Version 2.9.0-8.1.beta

Merge commit 'facc8b26b9461361bebc832e39e6e3036f2d191b' into beta
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index af00b66..7f75303 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": "2020-03-11T09:16:09.767708",
+  "generated": "2020-04-27T16:42:25.459210",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -66,19 +66,18 @@
       "name": "args",
       "rootUri": "../third_party/pkg/args",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.3"
     },
     {
       "name": "async",
       "rootUri": "../third_party/pkg/async",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.2"
     },
     {
       "name": "async_helper",
       "rootUri": "../pkg/async_helper",
-      "packageUri": "lib/",
-      "languageVersion": "2.7"
+      "packageUri": "lib/"
     },
     {
       "name": "bazel_worker",
@@ -96,7 +95,7 @@
       "name": "boolean_selector",
       "rootUri": "../third_party/pkg/boolean_selector",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.4"
     },
     {
       "name": "build_integration",
@@ -108,7 +107,7 @@
       "name": "charcode",
       "rootUri": "../third_party/pkg/charcode",
       "packageUri": "lib/",
-      "languageVersion": "1.0"
+      "languageVersion": "2.0"
     },
     {
       "name": "cli_util",
@@ -117,16 +116,10 @@
       "languageVersion": "2.0"
     },
     {
-      "name": "code_transformers",
-      "rootUri": "../third_party/pkg/code_transformers",
-      "packageUri": "lib/",
-      "languageVersion": "1.0"
-    },
-    {
       "name": "collection",
       "rootUri": "../third_party/pkg/collection",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.3"
     },
     {
       "name": "compiler",
@@ -138,7 +131,7 @@
       "name": "convert",
       "rootUri": "../third_party/pkg/convert",
       "packageUri": "lib/",
-      "languageVersion": "1.17"
+      "languageVersion": "2.0"
     },
     {
       "name": "crypto",
@@ -150,7 +143,7 @@
       "name": "csslib",
       "rootUri": "../third_party/pkg/csslib",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.2"
     },
     {
       "name": "dart2js_info",
@@ -180,7 +173,7 @@
       "name": "dart_style",
       "rootUri": "../third_party/pkg_tested/dart_style",
       "packageUri": "lib/",
-      "languageVersion": "2.3"
+      "languageVersion": "2.7"
     },
     {
       "name": "dartdev",
@@ -192,7 +185,7 @@
       "name": "dartdoc",
       "rootUri": "../third_party/pkg/dartdoc",
       "packageUri": "lib/",
-      "languageVersion": "2.6"
+      "languageVersion": "2.7"
     },
     {
       "name": "dartfix",
@@ -204,7 +197,7 @@
       "name": "dds",
       "rootUri": "../pkg/dds",
       "packageUri": "lib/",
-      "languageVersion": "2.3"
+      "languageVersion": "2.6"
     },
     {
       "name": "dev_compiler",
@@ -221,8 +214,7 @@
     {
       "name": "expect",
       "rootUri": "../pkg/expect",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "packageUri": "lib/"
     },
     {
       "name": "ffi",
@@ -234,7 +226,7 @@
       "name": "fixnum",
       "rootUri": "../third_party/pkg/fixnum",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.1"
     },
     {
       "name": "front_end",
@@ -263,18 +255,17 @@
       "packageUri": ".nonexisting/"
     },
     {
+      "name": "front_end_nonfunction_type_aliases",
+      "rootUri": "../pkg/front_end/testcases/nonfunction_type_aliases",
+      "packageUri": ".nonexisting/"
+    },
+    {
       "name": "frontend_server",
       "rootUri": "../pkg/frontend_server",
       "packageUri": "lib/",
       "languageVersion": "2.7"
     },
     {
-      "name": "func",
-      "rootUri": "../third_party/pkg/func",
-      "packageUri": "lib/",
-      "languageVersion": "1.9"
-    },
-    {
       "name": "gardening",
       "rootUri": "../tools/gardening",
       "packageUri": "lib/",
@@ -284,19 +275,19 @@
       "name": "glob",
       "rootUri": "../third_party/pkg/glob",
       "packageUri": "lib/",
-      "languageVersion": "1.23"
+      "languageVersion": "2.2"
     },
     {
       "name": "html",
       "rootUri": "../third_party/pkg/html",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.3"
     },
     {
       "name": "http",
       "rootUri": "../third_party/pkg/http",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.4"
     },
     {
       "name": "http_io",
@@ -329,16 +320,10 @@
       "languageVersion": "2.0"
     },
     {
-      "name": "initialize",
-      "rootUri": "../third_party/pkg/initialize",
-      "packageUri": "lib/",
-      "languageVersion": "1.9"
-    },
-    {
       "name": "intl",
       "rootUri": "../third_party/pkg/intl",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.5"
     },
     {
       "name": "js",
@@ -362,7 +347,7 @@
       "name": "json_rpc_2",
       "rootUri": "../third_party/pkg/json_rpc_2",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.2"
     },
     {
       "name": "kernel",
@@ -374,37 +359,30 @@
       "name": "linter",
       "rootUri": "../third_party/pkg/linter",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.6"
     },
     {
       "name": "logging",
       "rootUri": "../third_party/pkg/logging",
       "packageUri": "lib/",
-      "languageVersion": "1.5"
+      "languageVersion": "2.0"
     },
     {
       "name": "markdown",
       "rootUri": "../third_party/pkg/markdown",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.2"
     },
     {
       "name": "matcher",
       "rootUri": "../third_party/pkg/matcher",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.4"
     },
     {
       "name": "meta",
       "rootUri": "../pkg/meta",
-      "packageUri": "lib/",
-      "languageVersion": "1.12"
-    },
-    {
-      "name": "metatest",
-      "rootUri": "../third_party/pkg/metatest",
-      "packageUri": "lib/",
-      "languageVersion": "1.8"
+      "packageUri": "lib/"
     },
     {
       "name": "mime",
@@ -449,12 +427,6 @@
       "languageVersion": "2.0"
     },
     {
-      "name": "observable",
-      "rootUri": "../third_party/pkg/observable",
-      "packageUri": "lib/",
-      "languageVersion": "1.19"
-    },
-    {
       "name": "observatory",
       "rootUri": "../runtime/observatory",
       "packageUri": "lib/",
@@ -466,12 +438,6 @@
       "languageVersion": "2.7"
     },
     {
-      "name": "observe",
-      "rootUri": "../third_party/pkg/observe",
-      "packageUri": "lib/",
-      "languageVersion": "1.9"
-    },
-    {
       "name": "package_config",
       "rootUri": "../third_party/pkg_tested/package_config",
       "packageUri": "lib/",
@@ -490,30 +456,12 @@
       "languageVersion": "2.1"
     },
     {
-      "name": "platform",
-      "rootUri": "../third_party/pkg/platform",
-      "packageUri": "lib/",
-      "languageVersion": "1.24"
-    },
-    {
-      "name": "plugin",
-      "rootUri": "../third_party/pkg/plugin",
-      "packageUri": "lib/",
-      "languageVersion": "1.0"
-    },
-    {
       "name": "pool",
       "rootUri": "../third_party/pkg/pool",
       "packageUri": "lib/",
       "languageVersion": "2.0"
     },
     {
-      "name": "process",
-      "rootUri": "../third_party/pkg/process",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
-    },
-    {
       "name": "protobuf",
       "rootUri": "../third_party/pkg/protobuf/protobuf",
       "packageUri": "lib/",
@@ -529,7 +477,7 @@
       "name": "pub_semver",
       "rootUri": "../third_party/pkg/pub_semver",
       "packageUri": "lib/",
-      "languageVersion": "1.0"
+      "languageVersion": "2.0"
     },
     {
       "name": "quiver",
@@ -544,12 +492,6 @@
       "languageVersion": "2.0"
     },
     {
-      "name": "scheduled_test",
-      "rootUri": "../third_party/pkg/scheduled_test",
-      "packageUri": "lib/",
-      "languageVersion": "1.22"
-    },
-    {
       "name": "sdk_library_metadata",
       "rootUri": "../sdk/lib/_internal/sdk_library_metadata",
       "packageUri": "lib/",
@@ -565,13 +507,13 @@
       "name": "shelf_packages_handler",
       "rootUri": "../third_party/pkg/shelf_packages_handler",
       "packageUri": "lib/",
-      "languageVersion": "1.22"
+      "languageVersion": "2.0"
     },
     {
       "name": "shelf_proxy",
       "rootUri": "../third_party/pkg/shelf_proxy",
       "packageUri": "lib/",
-      "languageVersion": "2.3"
+      "languageVersion": "2.0"
     },
     {
       "name": "shelf_static",
@@ -592,16 +534,10 @@
       "languageVersion": "2.3"
     },
     {
-      "name": "smoke",
-      "rootUri": "../third_party/pkg/smoke",
-      "packageUri": "lib/",
-      "languageVersion": "1.12"
-    },
-    {
       "name": "source_map_stack_trace",
       "rootUri": "../third_party/pkg/source_map_stack_trace",
       "packageUri": "lib/",
-      "languageVersion": "1.8"
+      "languageVersion": "2.7"
     },
     {
       "name": "source_maps",
@@ -667,19 +603,19 @@
       "name": "test",
       "rootUri": "../third_party/pkg/test/pkgs/test",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.7"
     },
     {
       "name": "test_api",
       "rootUri": "../third_party/pkg/test/pkgs/test_api",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.7"
     },
     {
       "name": "test_core",
       "rootUri": "../third_party/pkg/test/pkgs/test_core",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.7"
     },
     {
       "name": "test_descriptor",
@@ -718,12 +654,6 @@
       "languageVersion": "2.6"
     },
     {
-      "name": "tuple",
-      "rootUri": "../third_party/pkg/tuple",
-      "packageUri": "lib/",
-      "languageVersion": "1.6"
-    },
-    {
       "name": "typed_data",
       "rootUri": "../third_party/pkg/typed_data",
       "packageUri": "lib/",
@@ -736,12 +666,6 @@
       "languageVersion": "2.0"
     },
     {
-      "name": "utf",
-      "rootUri": "../third_party/pkg/utf",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
-    },
-    {
       "name": "vm",
       "rootUri": "../pkg/vm",
       "packageUri": "lib/",
@@ -757,7 +681,7 @@
       "name": "watcher",
       "rootUri": "../third_party/pkg/watcher",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.2"
     },
     {
       "name": "web_components",
@@ -775,7 +699,7 @@
       "name": "yaml",
       "rootUri": "../third_party/pkg/yaml",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.4"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40ba119..4ccf379 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,63 @@
-## 2.8.0
+## 2.9.0
+
+### Language
+
+### Core libraries
+
+#### `dart:convert`
+
+*   **Breaking Change** [#41100][]: When encoding a string containing unpaired
+    surrogates as UTF-8, the unpaired surrogates will be encoded as replacement
+    characters (`U+FFFD`). When decoding UTF-8, encoded surrogates will be
+    treated as malformed input. When decoding UTF-8 with `allowMalformed: true`,
+    the number of replacement characters emitted for malformed input sequences
+    has been changed to match the [WHATWG encoding standard][].
+
+[#41100]: https://github.com/dart-lang/sdk/issues/41100
+[WHATWG encoding standard]: https://encoding.spec.whatwg.org/#utf-8-decoder
+
+#### `dart:html`
+
+*   **Breaking Change**: `CssClassSet.add()` previously returned `null` if the
+    `CssClassSet` corresponded to multiple elements. In order to align with the
+    null-safe changes in the `Set` interface, it will now return `false`
+    instead. The same applies for `CssClassSet.toggle`.
+
+#### `dart:io`
+
+*   Class `OSError` now implements `Exception`. This change means `OSError` will
+    now be caught in catch clauses catching `Exception`s.
+*   Added `InternetAddress.tryParse`.
+
+### Tools
+
+#### dartfmt
+
+* Add `--fix-single-cascade-statements`.
+* Correctly handle `var` in `--fix-function-typedefs`.
+* Preserve leading indentation in fixed doc comments.
+* Split outer nested control flow elements.
+* Always place a blank line after script tags.
+* Don't add unneeded splits on if elements near comments.
+* Indent blocks in initializers of multiple-variable declarations.
+* Update the null-aware subscript syntax from `?.[]` to `?[]`.
+
+#### Linter
+
+Updated the Linter to `0.1.115`, which includes:
+
+* Updated `avoid_types_as_parameter_names` to check catch-clauses.
+* Fixed `unsafe_html` to check attributes and methods on extensions.
+* Extended `unsafe_html` to include `Window.open`, `Element.html` and
+  `DocumentFragment.html` in unsafe API checks.
+* Improved docs for `sort_child_properties_last`.
+* (internal) `package:analyzer` API updates.
+* New lint: `sized_box_for_whitespace`.
+
+### Dart VM
+
+
+## 2.8.1 - 2020-05-06
 
 Much of the changes in this release are in preparation for non-nullable types,
 which will arrive in a future version. In anticipation of that, we have made a
@@ -674,6 +733,13 @@
 * new lint: `avoid_web_libraries_in_flutter` (experimental)
 * (internal) prepare `unnecessary_lambdas` for coming `MethodInvocation` vs. `FunctionExpressionInvocation` changes
 
+## 2.5.2 - 2019-10-08
+
+This is a patch release with properly signed binaries required for macOS
+Catalina (Issue [38765][]).
+
+[38765]: https://github.com/dart-lang/sdk/issues/38765
+
 ## 2.5.1 - 2019-09-27
 
 This is a patch release that prevents type inference failures in the analyzer
@@ -2877,7 +2943,7 @@
 
 * `dart:web_audio`
 
-  * new method on `AudioContext` – `createIirFilter` returns a new class
+  * new method on `AudioContext` - `createIirFilter` returns a new class
     `IirFilterNode`.
 
 * `dart:web_gl`
@@ -4029,8 +4095,8 @@
 ### Tool changes
 
 * Dartium and content shell
-  * The Chrome-based tools that ship as part of the Dart SDK – Dartium and
-    content shell – are now based on Chrome version 45 (instead of Chrome 39).
+  * The Chrome-based tools that ship as part of the Dart SDK - Dartium and
+    content shell - are now based on Chrome version 45 (instead of Chrome 39).
   * Dart browser libraries (`dart:html`, `dart:svg`, etc) *have not* been
     updated.
     * These are still based on Chrome 39.
@@ -4574,7 +4640,7 @@
   dart2dart (aka `dart2js --output-type=dart`) utility as part
   of dart2js
 
-## 1.10.0 – 2015-04-29
+## 1.10.0 - 2015-04-29
 
 ### Core library changes
 
@@ -4613,7 +4679,7 @@
   * On Mac and Linux, signals sent to `pub run` and forwarded to the child
     command.
 
-## 1.9.3 – 2015-04-14
+## 1.9.3 - 2015-04-14
 
 This is a bug fix release which merges a number of commits from `bleeding_edge`.
 
@@ -4638,7 +4704,7 @@
   Pub can fail to load transformers necessary for local development -
   [r44876](https://code.google.com/p/dart/source/detail?r=44876)
 
-## 1.9.1 – 2015-03-25
+## 1.9.1 - 2015-03-25
 
 ### Language changes
 
@@ -4752,7 +4818,7 @@
   * Isolates spawned via `Isolate.spawn` now allow most objects, including
     top-level and static functions, to be sent between them.
 
-## 1.8.5 – 2015-01-21
+## 1.8.5 - 2015-01-21
 
 * Code generation for SIMD on ARM and ARM64 is fixed.
 
@@ -4762,7 +4828,7 @@
 
 [issue 21795]: https://code.google.com/p/dart/issues/detail?id=21795
 
-## 1.8.3 – 2014-12-10
+## 1.8.3 - 2014-12-10
 
 * Breakpoints can be set in the Editor using file suffixes ([issue 21280][]).
 
@@ -4779,7 +4845,7 @@
 [issue 21280]: https://code.google.com/p/dart/issues/detail?id=21280
 [issue 21698]: https://code.google.com/p/dart/issues/detail?id=21698
 
-## 1.8.0 – 2014-11-28
+## 1.8.0 - 2014-11-28
 
 * `dart:collection`: `SplayTree` added the `toSet` function.
 
@@ -4820,7 +4886,7 @@
 
 [alpn]: https://tools.ietf.org/html/rfc7301
 
-## 1.7.0 – 2014-10-15
+## 1.7.0 - 2014-10-15
 
 ### Tool changes
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5669836..101dfb2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,14 +11,14 @@
       click that icon to report a bug on the page.
     * To report an API doc bug,
       [create an SDK issue](https://github.com/dart-lang/sdk/issues/new?title=API%20doc%20issue:).
-  * Contribute to the Dart developer websites such as [www.dartlang.org](https://www.dartlang.org) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)) and [webdev.dartlang.org](https://webdev.dartlang.org) (repo: [dart-lang/site-webdev](https://github.com/dart-lang/site-webdev)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/wiki/Writing-for-Dart-and-Flutter-websites).
-  * Improve the API reference docs at [api.dartlang.org](https://api.dartlang.org) by editing doc comments in the [Dart SDK repo](https://github.com/dart-lang/sdk/tree/master/sdk/lib). For more information on how to write API docs, see [Effective Dart: Documentation](https://www.dartlang.org/guides/language/effective-dart/documentation).
+  * Contribute to the Dart developer websites such as [dart.dev](https://dart.dev) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)) and [dart.dev/web](https://dart.dev/web) (repo: [dart-lang/site-webdev](https://github.com/dart-lang/site-webdev)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/wiki/Writing-for-Dart-and-Flutter-websites).
+  * Improve the API reference docs at [api.dart.dev](https://api.dart.dev) by editing doc comments in the [Dart SDK repo](https://github.com/dart-lang/sdk/tree/master/sdk/lib). For more information on how to write API docs, see [Effective Dart: Documentation](https://dart.dev/guides/language/effective-dart/documentation).
 
 ## Before you contribute
 
 Before we can use your code, you must sign the [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual) (CLA), which you can do online.  The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code.  We also need to be sure of various other things—for instance that you'll tell us if you know that your code infringes on other people's patents.  You don't have to sign the CLA until after you've submitted your code for review and a member has approved it, but you must do it before we can put your code into our codebase.
 
-Before you start working on a larger contribution, you should get in touch with us first through the  [Dart Issue Tracker](http://dartbug.com) with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on.
+Before you start working on a larger contribution, you should get in touch with us first through the  [Dart Issue Tracker](https://dartbug.com) with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on.
 
 All submissions, including submissions by project members, require review.  We use the same code-review tools and process as the chromium project.  In order to submit a patch, you need to get the [depot\_tools](http://dev.chromium.org/developers/how-tos/depottools).
 
diff --git a/DEPS b/DEPS
index 40774ba..f29c6914 100644
--- a/DEPS
+++ b/DEPS
@@ -36,10 +36,14 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
+  # 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.9.0-4.0.dev",
+
   # 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": "9934d8540d097366287267519413e888a7f6a482",
+  "co19_rev": "306b15d60048bee617b7d5ede9b49ebafb7d1c42",
   "co19_2_rev": "368bfa9e877a2df003547f64bb17e30596af10c7",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -60,16 +64,16 @@
   "async_tag": "2.4.1",
   "bazel_worker_tag": "v0.1.22",
   "benchmark_harness_tag": "81641290dea44c34138a109a37e215482f405f81",
-  "boolean_selector_tag" : "1.0.4",
+  "boolean_selector_tag": "1309eabed510cc3b7536fd4367d39b97ebee3d69",
   "boringssl_gen_rev": "b9e27cff1ff0803e97ab1f88764a83be4aa94a6d",
   "boringssl_rev" : "4dfd5af70191b068aebe567b8e29ce108cee85ce",
-  "charcode_tag": "v1.1.2",
+  "charcode_tag": "9085e6b6127f084d66c0a94810a808121459012a",
   "chrome_rev" : "19997",
   "cli_util_rev" : "4ad7ccbe3195fd2583b30f86a86697ef61e80f41",
-  "collection_tag": "1.14.11",
-  "convert_tag": "2.0.2",
+  "collection_tag": "7be42e03d427cc19571cd7f9fc628a5913a6b757",
+  "convert_tag": "49bde5b371eb5c2c8e721557cf762f17c75e49fc",
   "crypto_tag" : "2.0.6",
-  "csslib_tag" : "0.15.0",
+  "csslib_tag": "bf372d4fdc6dfa232ad93f77a0a3de0891edd04c",
   "dart2js_info_tag" : "0.6.0",
 
   # Note: Updates to dart_style have to be coordinated with the infrastructure
@@ -84,39 +88,38 @@
   #     and land the review.
   #
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
-  "dart_style_tag": "1.3.2",  # Please see the note above before updating.
+  "dart_style_tag": "1.3.6",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "v0.30.3",
-  "ffi_tag": "ea88d71b043ee14b268c3aedff14e9eb32e20959",
-  "fixnum_tag": "0.10.9",
-  "glob_tag": "1.1.7",
-  "html_tag" : "0.14.0+1",
+  "dartdoc_tag" : "v0.31.0",
+  "ffi_tag": "4cc14129e81f8804e73321f0ccf5484397a5ddce",
+  "fixnum_tag": "eb3748663dc979271ff6a3d014fbe522543b1d91",
+  "glob_tag": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
+  "html_tag": "083a36cd801a4b787ba156b7c6e4c8b2e2daed4a",
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
   "http_multi_server_rev" : "ea269f79321d659208402088f3297e8920a88ee6",
   "http_parser_tag" : "3.1.3",
   "http_retry_tag": "0.1.1",
-  "http_tag" : "0.12.0+2",
+  "http_tag": "a131e563c09349f624d5421237183a06fb10552d",
   "http_throttle_tag" : "1.0.2",
-  "icu_rev" : "c56c671998902fcc4fc9ace88c83daa99f980793",
+  "icu_rev" : "5005010d694e16571b8dfbf07d70817841f80a69",
   "idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
   "intl_tag": "0.16.1",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
-  "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.114",
-  "logging_tag": "0.11.3+2",
+  "json_rpc_2_tag": "eec10819a40e7bf2e401f2b97368776a90cc5550",
+  "linter_tag": "0.1.115",
+  "logging_tag": "9561ba016ae607747ae69b846c0e10958ca58ed4",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
-  "markdown_tag": "2.1.1",
-  "matcher_tag": "0.12.5",
-  "mime_tag": "0.9.6+2",
+  "markdown_tag": "dd150bb64c5f3b41d31f20f399ae2a855f7f8c00",
+  "matcher_tag": "af4fe7daf8e94a46981e4f072872be550a6969e9",
+  "mime_tag": "179b5e6a88f4b63f36dc1b8fcbc1e83e5e0cd3a7",
   "mockito_tag": "d39ac507483b9891165e422ec98d9fb480037c8b",
-  "mustache_tag" : "5e81b12215566dbe2473b2afd01a8a8aedd56ad9",
-  "oauth2_tag": "1.2.1",
-  "observatory_pub_packages_rev": "0894122173b0f98eb08863a7712e78407d4477bc",
+  "mustache_tag": "664737ecad027e6b96d0d1e627257efa0e46fcb1",
+  "oauth2_tag": "1.6.0",
   "package_config_tag": "v1.9.2",
-  "path_tag": "1.6.2",
-  "pedantic_tag": "v1.8.0",
+  "path_tag": "1.7.0",
+  "pedantic_tag": "v1.9.0",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
-  "pool_tag": "1.3.6",
+  "pool_tag": "86fbb2cde9bbc66c8d159909d2f65a5981ea5b50",
   "protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
   "pub_rev": "3606265962da4248d34d352aa3d170aae4496a90",
   "pub_semver_tag": "v1.4.4",
@@ -131,7 +134,7 @@
   "shelf_web_socket_tag": "0.2.2+3",
   "source_map_stack_trace_tag": "2.0.0",
   "source_maps-0.9.4_rev": "38524",
-  "source_maps_tag": "8af7cc1a1c3a193c1fba5993ce22a546a319c40e",
+  "source_maps_tag": "87b4fd9027378bbd51b02e9d7df794eee8a82b7a",
   "source_span_tag": "1.7.0",
   "stack_trace_tag": "1.9.3",
   "stagehand_tag": "v3.3.7",
@@ -139,17 +142,17 @@
   "string_scanner_tag": "1.0.3",
   "test_descriptor_tag": "1.1.1",
   "test_process_tag": "1.0.3",
-  "term_glyph_tag": "1.0.1",
+  "term_glyph_tag": "b3da31e9684a99cfe5f192b89914492018b44da7",
   "test_reflective_loader_tag": "0.1.9",
-  "test_tag": "test_core-v0.3.2",
+  "test_tag": "988e38ff3051f24607ad0aaf4e780835785f2ab5",
   "tflite_native_rev": "3c777c40608a2a9f1427bfe0028ab48e7116b4c1",
   "typed_data_tag": "1.1.6",
   "usage_tag": "3.4.0",
-  "watcher_rev": "0.9.7+14",
+  "watcher_rev": "fc3c9aae5d31d707b3013b42634dde8d8a1161b4",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
-  "web_socket_channel_tag": "1.0.15",
+  "web_socket_channel_tag": "490061ef0e22d3c8460ad2802f9948219365ad6b",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
-  "yaml_tag": "2.2.0",
+  "yaml_tag": "62e9f6b3a933b1f76dd3007d1a5ce0be8e429b2d",
   "zlib_rev": "c44fb7248079cc3d5563b14b3f758aee60d6b415",
   "crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
   "minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
@@ -177,7 +180,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.8.0-dev.18.0",
+          "version": Var("sdk_tag"),
       }],
       "dep_type": "cipd",
   },
@@ -332,9 +335,6 @@
       + "@" + Var("mustache_tag"),
   Var("dart_root") + "/third_party/pkg/oauth2":
       Var("dart_git") + "oauth2.git" + "@" + Var("oauth2_tag"),
-  Var("dart_root") + "/third_party/observatory_pub_packages":
-      Var("dart_git") + "observatory_pub_packages.git"
-      + "@" + Var("observatory_pub_packages_rev"),
   Var("dart_root") + "/third_party/pkg_tested/package_config":
       Var("dart_git") + "package_config.git" +
       "@" + Var("package_config_tag"),
@@ -469,7 +469,7 @@
     "packages": [
       {
         "package": "dart/cfe/dart2js_dills",
-        "version": "binary_version:40",
+        "version": "binary_version:42",
       }
     ],
     "dep_type": "cipd",
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 99a82f2..60c449a 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -38,6 +38,30 @@
     return []
 
 
+def _CheckSdkDdcRuntimeSync(input_api, output_api):
+    files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()]
+    unsynchronized_files = []
+    runtime_lib = 'lib/_internal/js_dev_runtime/private/ddc_runtime/'
+    for nnbd_file in files:
+        if nnbd_file.startswith('sdk_nnbd/' + runtime_lib):
+            file = 'sdk/' + nnbd_file[9:]
+            if not file in files:
+                unsynchronized_files.append(file)
+    if unsynchronized_files:
+        return [
+            output_api.PresubmitPromptWarning(
+                'Changes were made to '
+                'sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/ '
+                'that were not made to '
+                'sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/ '
+                'Please copy those changes (without Null Safety syntax) to '
+                'these files as well:\n'
+                '\n'
+                '%s' % ('\n'.join(unsynchronized_files)))
+        ]
+    return []
+
+
 def _CheckNnbdTestSync(input_api, output_api):
     """Make sure that any forked SDK tests are kept in sync. If a CL touches
     a test, the test's counterpart (if it exists at all) should be in the CL
@@ -316,6 +340,7 @@
 def _CommonChecks(input_api, output_api):
     results = []
     results.extend(_CheckNnbdSdkSync(input_api, output_api))
+    results.extend(_CheckSdkDdcRuntimeSync(input_api, output_api))
     results.extend(_CheckNnbdTestSync(input_api, output_api))
     results.extend(_CheckValidHostsInDEPS(input_api, output_api))
     results.extend(_CheckDartFormat(input_api, output_api))
diff --git a/WATCHLISTS b/WATCHLISTS
index 3e5b2ab..e587f14 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -33,7 +33,7 @@
       )
     },
     'package_vm': {
-      'filepath': '^pkg/vm',
+      'filepath': '^pkg/vm/',
     },
     'messages_review': {
       'filepath': (
diff --git a/benchmarks/IsolateJson/dart/IsolateJson.dart b/benchmarks/IsolateJson/dart/IsolateJson.dart
index bdc7988..1fa4919 100644
--- a/benchmarks/IsolateJson/dart/IsolateJson.dart
+++ b/benchmarks/IsolateJson/dart/IsolateJson.dart
@@ -11,17 +11,24 @@
 import 'package:benchmark_harness/benchmark_harness.dart' show BenchmarkBase;
 import 'package:meta/meta.dart';
 
+import 'runtime/tests/vm/dart/export_sendAndExit_helper.dart' show sendAndExit;
+
 class JsonDecodingBenchmark {
   JsonDecodingBenchmark(this.name,
-      {@required this.sample, @required this.numTasks});
+      {@required this.sample,
+      @required this.numTasks,
+      @required this.useSendAndExit});
 
   Future<void> report() async {
     final stopwatch = Stopwatch()..start();
-    final decodedFutures = <Future>[];
-    for (int i = 0; i < numTasks; i++) {
-      decodedFutures.add(decodeJson(sample));
+    // Benchmark harness counts 10 iterations as one.
+    for (int i = 0; i < 10; i++) {
+      final decodedFutures = <Future>[];
+      for (int i = 0; i < numTasks; i++) {
+        decodedFutures.add(decodeJson(useSendAndExit, sample));
+      }
+      await Future.wait(decodedFutures);
     }
-    await Future.wait(decodedFutures);
 
     print("$name(RunTime): ${stopwatch.elapsedMicroseconds} us.");
   }
@@ -29,6 +36,7 @@
   final String name;
   final Uint8List sample;
   final int numTasks;
+  final bool useSendAndExit;
 }
 
 Uint8List createSampleJson(final size) {
@@ -41,27 +49,42 @@
 }
 
 class JsonDecodeRequest {
+  final bool useSendAndExit;
   final SendPort sendPort;
   final Uint8List encodedJson;
-  const JsonDecodeRequest(this.sendPort, this.encodedJson);
+  const JsonDecodeRequest(this.useSendAndExit, this.sendPort, this.encodedJson);
 }
 
-Future<Map> decodeJson(Uint8List encodedJson) async {
+Future<Map> decodeJson(bool useSendAndExit, Uint8List encodedJson) async {
   final port = ReceivePort();
   final inbox = StreamIterator<dynamic>(port);
-  final workerExitedPort = ReceivePort();
-  await Isolate.spawn(
-      jsonDecodingIsolate, JsonDecodeRequest(port.sendPort, encodedJson),
-      onExit: workerExitedPort.sendPort);
+  final completer = Completer<bool>();
+  final workerExitedPort = RawReceivePort((v) {
+    completer.complete(true);
+  });
+  final workerErroredPort = RawReceivePort((v) {
+    stderr.writeln('worker errored out $v');
+    completer.completeError(true);
+  });
+  await Isolate.spawn(jsonDecodingIsolate,
+      JsonDecodeRequest(useSendAndExit, port.sendPort, encodedJson),
+      onError: workerErroredPort.sendPort, onExit: workerExitedPort.sendPort);
+  await completer.future;
+  workerExitedPort.close();
+  workerErroredPort.close();
   await inbox.moveNext();
   final decodedJson = inbox.current;
-  await workerExitedPort.first;
   port.close();
   return decodedJson;
 }
 
 Future<void> jsonDecodingIsolate(JsonDecodeRequest request) async {
-  request.sendPort.send(json.decode(utf8.decode(request.encodedJson)));
+  final result = json.decode(utf8.decode(request.encodedJson));
+  if (request.useSendAndExit) {
+    sendAndExit(request.sendPort, result);
+  } else {
+    request.sendPort.send(result);
+  }
 }
 
 class SyncJsonDecodingBenchmark extends BenchmarkBase {
@@ -118,6 +141,13 @@
     for (final iterations in <int>[1, 4]) {
       await JsonDecodingBenchmark(
               "IsolateJson.Decode${config.suffix}x$iterations",
+              useSendAndExit: false,
+              sample: config.sample,
+              numTasks: iterations)
+          .report();
+      await JsonDecodingBenchmark(
+              "IsolateJson.SendAndExit_Decode${config.suffix}x$iterations",
+              useSendAndExit: true,
               sample: config.sample,
               numTasks: iterations)
           .report();
diff --git a/benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart b/benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart
new file mode 100644
index 0000000..75628d6
--- /dev/null
+++ b/benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart
@@ -0,0 +1 @@
+export 'dart:_internal' show sendAndExit;
diff --git a/benchmarks/RuntimeType/dart/RuntimeType.dart b/benchmarks/RuntimeType/dart/RuntimeType.dart
new file mode 100644
index 0000000..fe21b30
--- /dev/null
+++ b/benchmarks/RuntimeType/dart/RuntimeType.dart
@@ -0,0 +1,176 @@
+// 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.
+//
+// Benchmark for runtimeType patterns as used in Flutter.
+
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: avoid_function_literals_in_foreach_calls
+
+import 'dart:typed_data';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+abstract class Key {
+  const factory Key(String value) = ValueKey<String>;
+  const Key.empty();
+}
+
+abstract class LocalKey extends Key {
+  const LocalKey() : super.empty();
+}
+
+class ValueKey<T> extends LocalKey {
+  const ValueKey(this.value);
+  final T value;
+  @override
+  bool operator ==(Object other) {
+    if (other.runtimeType != runtimeType) return false;
+    return other is ValueKey<T> && other.value == value;
+  }
+
+  @override
+  int get hashCode => value.hashCode;
+}
+
+abstract class Widget {
+  const Widget({this.key});
+  final Key key;
+
+  @pragma('dart2js:noInline')
+  static bool canUpdate(Widget oldWidget, Widget newWidget) {
+    return oldWidget.runtimeType == newWidget.runtimeType &&
+        oldWidget.key == newWidget.key;
+  }
+}
+
+class AWidget extends Widget {
+  const AWidget({Key key}) : super(key: key);
+}
+
+class BWidget extends Widget {
+  const BWidget({Key key}) : super(key: key);
+}
+
+class CWidget extends Widget {
+  const CWidget({Key key}) : super(key: key);
+}
+
+class DWidget extends Widget {
+  const DWidget({Key key}) : super(key: key);
+}
+
+class EWidget extends Widget {
+  const EWidget({Key key}) : super(key: key);
+}
+
+class FWidget extends Widget {
+  const FWidget({Key key}) : super(key: key);
+}
+
+class WWidget<W extends Widget> extends Widget {
+  final W /*?*/ ref;
+  const WWidget({this.ref, Key key}) : super(key: key);
+}
+
+class WidgetCanUpdateBenchmark extends BenchmarkBase {
+  WidgetCanUpdateBenchmark() : super('RuntimeType.Widget.canUpdate.byType');
+
+  // All widgets have different types.
+  static List<Widget> _widgets() => [
+        AWidget(),
+        BWidget(),
+        CWidget(),
+        DWidget(),
+        EWidget(),
+        FWidget(),
+        WWidget<AWidget>(),
+        WWidget<BWidget>(ref: const BWidget()),
+        WWidget<CWidget>(ref: CWidget()),
+        const WWidget<DWidget>(ref: DWidget()),
+      ];
+  // Bulk up list to reduce loop overheads.
+  final List<Widget> widgets = _widgets() + _widgets() + _widgets();
+
+  @override
+  void exercise() => run();
+
+  @override
+  void run() {
+    for (var w1 in widgets) {
+      for (var w2 in widgets) {
+        if (Widget.canUpdate(w1, w2) != Widget.canUpdate(w2, w1)) {
+          throw 'Hmm $w1 $w2';
+        }
+      }
+    }
+  }
+
+  // Normalize by number of calls to [Widgets.canUpdate].
+  @override
+  double measure() => super.measure() / (widgets.length * widgets.length * 2);
+}
+
+class ValueKeyEqualBenchmark extends BenchmarkBase {
+  ValueKeyEqualBenchmark() : super('RuntimeType.Widget.canUpdate.byKey');
+
+  // All widgets the same class but distinguished on keys.
+  static List<Widget> _widgets() => [
+        AWidget(),
+        AWidget(key: ValueKey(1)),
+        AWidget(key: ValueKey(1)),
+        AWidget(key: ValueKey(2)),
+        AWidget(key: ValueKey(2)),
+        AWidget(key: ValueKey(3)),
+        AWidget(key: ValueKey('one')),
+        AWidget(key: ValueKey('two')),
+        AWidget(key: ValueKey('three')),
+        AWidget(key: ValueKey(Duration(seconds: 5))),
+      ];
+  // Bulk up list to reduce loop overheads.
+  final List<Widget> widgets = _widgets() + _widgets() + _widgets();
+
+  @override
+  void exercise() => run();
+
+  @override
+  void run() {
+    for (var w1 in widgets) {
+      for (var w2 in widgets) {
+        if (Widget.canUpdate(w1, w2) != Widget.canUpdate(w2, w1)) {
+          throw 'Hmm $w1 $w2';
+        }
+      }
+    }
+  }
+
+  // Normalize by number of calls to [Widgets.canUpdate].
+  @override
+  double measure() => super.measure() / (widgets.length * widgets.length * 2);
+}
+
+void pollute() {
+  // Various bits of code to make environment less unrealistic.
+  void check(dynamic a, dynamic b) {
+    if (a.runtimeType != b.runtimeType) throw 'mismatch $a $b';
+  }
+
+  check(Uint8List(1), Uint8List(2)); // dart2js needs native interceptors.
+  check(Int16List(1), Int16List(2));
+  check([], []);
+  check(<bool>{}, <bool>{});
+}
+
+void main() {
+  pollute();
+
+  final benchmarks = [
+    WidgetCanUpdateBenchmark(),
+    ValueKeyEqualBenchmark(),
+  ];
+
+  // Warm up all benchmarks before running any.
+  benchmarks.forEach((bm) => bm.run());
+
+  benchmarks.forEach((bm) => bm.report());
+}
diff --git a/benchmarks/Utf8Decode/dart/Utf8Decode.dart b/benchmarks/Utf8Decode/dart/Utf8Decode.dart
index 23762d6..a1b423d 100644
--- a/benchmarks/Utf8Decode/dart/Utf8Decode.dart
+++ b/benchmarks/Utf8Decode/dart/Utf8Decode.dart
@@ -21,9 +21,7 @@
   final String text;
   final int size;
   final bool allowMalformed;
-  final Utf8Decoder decoder;
-  Uint8List data;
-  List<int> chunks;
+  List<Uint8List> chunks;
   int totalInputSize;
   int totalOutputSize;
 
@@ -37,27 +35,27 @@
   }
 
   Utf8Decode(this.language, this.text, this.size, this.allowMalformed)
-      : decoder = Utf8Decoder(allowMalformed: allowMalformed),
-        super(_makeName(language, size, allowMalformed));
+      : super(_makeName(language, size, allowMalformed));
 
   @override
   void setup() {
-    data = utf8.encode(text) as Uint8List;
+    Uint8List data = utf8.encode(text) as Uint8List;
     if (data.length != 10000) {
       throw "Expected input data of exactly 10000 bytes.";
     }
     if (size < data.length) {
       // Split into chunks.
-      chunks = <int>[];
-      chunks.add(0);
+      chunks = <Uint8List>[];
+      int startPos = 0;
       for (int pos = size; pos < data.length; pos += size) {
-        int chunkPos = pos;
-        while ((data[chunkPos] & 0xc0) == 0x80) {
-          chunkPos--;
+        int endPos = pos;
+        while ((data[endPos] & 0xc0) == 0x80) {
+          endPos--;
         }
-        chunks.add(chunkPos);
+        chunks.add(Uint8List.fromList(data.sublist(startPos, endPos)));
+        startPos = endPos;
       }
-      chunks.add(data.length);
+      chunks.add(Uint8List.fromList(data.sublist(startPos, data.length)));
       totalInputSize = data.length;
       totalOutputSize = text.length;
     } else if (size > data.length) {
@@ -66,13 +64,12 @@
       for (int i = 0; i < size; i++) {
         expanded[i] = data[i % data.length];
       }
-      chunks = <int>[0, size];
+      chunks = <Uint8List>[expanded];
       totalInputSize = size;
       totalOutputSize = text.length * size ~/ data.length;
-      data = expanded;
     } else {
       // Use data as is.
-      chunks = <int>[0, data.length];
+      chunks = <Uint8List>[data];
       totalInputSize = data.length;
       totalOutputSize = text.length;
     }
@@ -81,9 +78,8 @@
   @override
   void run() {
     int lengthSum = 0;
-    final int numChunks = chunks.length - 1;
-    for (int i = 0; i < numChunks; i++) {
-      final String s = decoder.convert(data, chunks[i], chunks[i + 1]);
+    for (int i = 0; i < chunks.length; i++) {
+      final String s = utf8.decode(chunks[i], allowMalformed: allowMalformed);
       lengthSum += s.length;
     }
     if (lengthSum != totalOutputSize) {
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index b3dec5b..b5a49ba 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -118,10 +118,7 @@
       ldflags += [ "-fsanitize=thread" ]
     }
     if (is_ubsan) {
-      cflags += [
-        "-fsanitize=undefined",
-        "-fno-sanitize=null,alignment",
-      ]
+      cflags += [ "-fsanitize=undefined" ]
       ldflags += [ "-fsanitize=undefined" ]
     }
   }
@@ -541,6 +538,9 @@
 
   if (is_clang) {
     default_warning_flags += [ "-Wno-tautological-constant-compare" ]
+  } else {
+    default_warning_flags +=
+        [ "-Wno-ignored-qualifiers" ]  # Warnings in BoringSSL headers
   }
 
   if (is_mac) {
diff --git a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
index 0ba9195..583344a 100644
--- a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
+++ b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
@@ -7,6 +7,7 @@
     # Allow having TODOs in the code
     todo: ignore
   exclude:
+    - test/constants/data/**
     - test/flow_analysis/assigned_variables/data/**
     - test/flow_analysis/definite_assignment/data/**
     - test/flow_analysis/definite_unassignment/data/**
diff --git a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
index feda572..02e8bdc 100644
--- a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
@@ -62,6 +62,10 @@
    */
   ErrorSeverity get errorSeverity;
 
+  /// Whether a finding of this error is ignorable via comments such as
+  /// `// ignore:` or `// ignore_for_file:`.
+  bool get isIgnorable => errorSeverity != ErrorSeverity.ERROR;
+
   /**
    * The type of the error.
    */
@@ -225,7 +229,7 @@
     STATIC_WARNING,
     STATIC_TYPE_WARNING,
     SYNTACTIC_ERROR,
-    LINT
+    LINT,
   ];
 
   /**
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart
new file mode 100644
index 0000000..1980d46
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart
@@ -0,0 +1,120 @@
+// 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.
+
+abstract class FactorTypeTestMixin<Type> {
+  Type futureNone(Type type);
+  Type futureOrNone(Type type);
+
+  Type get dynamicType;
+  Type get intNone;
+  Type get intQuestion;
+  Type get intStar;
+  Type get numNone;
+  Type get numQuestion;
+  Type get numStar;
+  Type get objectNone;
+  Type get objectQuestion;
+  Type get objectStar;
+  Type get stringNone;
+  Type get stringQuestion;
+  Type get stringStar;
+  Type get nullNone;
+  Type get voidType;
+
+  void test_dynamic() {
+    check(dynamicType, intNone, 'dynamic');
+  }
+
+  void test_futureOr() {
+    check(futureOrNone(intNone), intNone, 'Future<int>');
+    check(futureOrNone(intNone), futureNone(intNone), 'int');
+
+    check(futureOrNone(intQuestion), intNone, 'FutureOr<int?>');
+    check(futureOrNone(intQuestion), futureNone(intNone), 'FutureOr<int?>');
+    check(futureOrNone(intQuestion), intQuestion, 'Future<int?>');
+    check(futureOrNone(intQuestion), futureNone(intQuestion), 'int?');
+    check(futureOrNone(intQuestion), intStar, 'Future<int?>');
+    check(futureOrNone(intQuestion), futureNone(intStar), 'int?');
+
+    check(futureOrNone(intNone), numNone, 'Future<int>');
+    check(futureOrNone(intNone), futureNone(numNone), 'int');
+  }
+
+  void test_object() {
+    check(objectNone, objectNone, 'Never');
+    check(objectNone, objectQuestion, 'Never');
+    check(objectNone, objectStar, 'Never');
+
+    check(objectNone, intNone, 'Object');
+    check(objectNone, intQuestion, 'Object');
+    check(objectNone, intStar, 'Object');
+
+    check(objectQuestion, objectNone, 'Never?');
+    check(objectQuestion, objectQuestion, 'Never');
+    check(objectQuestion, objectStar, 'Never');
+
+    check(objectQuestion, intNone, 'Object?');
+    check(objectQuestion, intQuestion, 'Object');
+    check(objectQuestion, intStar, 'Object');
+  }
+
+  test_subtype() {
+    check(intNone, intNone, 'Never');
+    check(intNone, intQuestion, 'Never');
+    check(intNone, intStar, 'Never');
+
+    check(intQuestion, intNone, 'Never?');
+    check(intQuestion, intQuestion, 'Never');
+    check(intQuestion, intStar, 'Never');
+
+    check(intStar, intNone, 'Never');
+    check(intStar, intQuestion, 'Never');
+    check(intStar, intStar, 'Never');
+
+    check(intNone, numNone, 'Never');
+    check(intNone, numQuestion, 'Never');
+    check(intNone, numStar, 'Never');
+
+    check(intQuestion, numNone, 'Never?');
+    check(intQuestion, numQuestion, 'Never');
+    check(intQuestion, numStar, 'Never');
+
+    check(intStar, numNone, 'Never');
+    check(intStar, numQuestion, 'Never');
+    check(intStar, numStar, 'Never');
+
+    check(intNone, nullNone, 'int');
+    check(intQuestion, nullNone, 'int');
+    check(intStar, nullNone, 'int');
+
+    check(intNone, stringNone, 'int');
+    check(intQuestion, stringNone, 'int?');
+    check(intStar, stringNone, 'int*');
+
+    check(intNone, stringQuestion, 'int');
+    check(intQuestion, stringQuestion, 'int');
+    check(intStar, stringQuestion, 'int');
+
+    check(intNone, stringStar, 'int');
+    check(intQuestion, stringStar, 'int');
+    check(intStar, stringStar, 'int');
+  }
+
+  void test_void() {
+    check(voidType, intNone, 'void');
+  }
+
+  Type factor(Type T, Type S);
+
+  void expect(Type T, Type S, String actualResult, String expectedResult);
+
+  void check(Type T, Type S, String expectedStr) {
+    var result = factor(T, S);
+    var resultStr = typeString(result);
+
+    expect(T, S, resultStr, expectedStr);
+  }
+
+  String typeString(Type type);
+}
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 739dd20..3eb33ac 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
@@ -517,6 +517,13 @@
   /// state.
   bool isUnassigned(Variable variable);
 
+  /// Call this method before visiting a labeled statement.
+  /// Call [labeledStatement_end] after visiting the statement.
+  void labeledStatement_begin(Node node);
+
+  /// Call this method after visiting a labeled statement.
+  void labeledStatement_end();
+
   /// Call this method after visiting the RHS of a logical binary operation
   /// ("||" or "&&").
   /// [wholeExpression] should be the whole logical binary expression.
@@ -938,6 +945,18 @@
   }
 
   @override
+  void labeledStatement_begin(Node node) {
+    return _wrap('labeledStatement_begin($node)',
+        () => _wrapped.labeledStatement_begin(node));
+  }
+
+  @override
+  void labeledStatement_end() {
+    return _wrap(
+        'labeledStatement_end()', () => _wrapped.labeledStatement_end());
+  }
+
+  @override
   void logicalBinaryOp_end(Expression wholeExpression, Expression rightOperand,
       {@required bool isAnd}) {
     _wrap(
@@ -1142,10 +1161,13 @@
   /// variable is not in scope anymore.  This should not have any effect on
   /// analysis results for error-free code, because it is an error to refer to a
   /// variable that is no longer in scope.
-  final Map<Variable, VariableModel<Type> /*!*/ > variableInfo;
+  final Map<Variable, VariableModel<Variable, Type> /*!*/ > variableInfo;
 
   /// Variable model for variables that have never been seen before.
-  final VariableModel<Type> _freshVariableInfo;
+  final VariableModel<Variable, Type> _freshVariableInfo;
+
+  /// The empty map, used to [join] variables.
+  final Map<Variable, VariableModel<Variable, Type>> _emptyVariableMap = {};
 
   /// Creates a state object with the given [reachable] status.  All variables
   /// are assumed to be unpromoted and already assigned, so joining another
@@ -1159,7 +1181,7 @@
   FlowModel._(this.reachable, this.variableInfo)
       : _freshVariableInfo = new VariableModel.fresh() {
     assert(() {
-      for (VariableModel<Type> value in variableInfo.values) {
+      for (VariableModel<Variable, Type> value in variableInfo.values) {
         assert(value != null);
       }
       return true;
@@ -1172,7 +1194,7 @@
   /// A local variable is [initialized] if its declaration has an initializer.
   /// A function parameter is always initialized, so [initialized] is `true`.
   FlowModel<Variable, Type> declare(Variable variable, bool initialized) {
-    VariableModel<Type> newInfoForVar = _freshVariableInfo;
+    VariableModel<Variable, Type> newInfoForVar = _freshVariableInfo;
     if (initialized) {
       newInfoForVar = newInfoForVar.initialize();
     }
@@ -1181,7 +1203,7 @@
   }
 
   /// Gets the info for the given [variable], creating it if it doesn't exist.
-  VariableModel<Type> infoFor(Variable variable) =>
+  VariableModel<Variable, Type> infoFor(Variable variable) =>
       variableInfo[variable] ?? _freshVariableInfo;
 
   /// Updates the state to indicate that variables that are not definitely
@@ -1191,22 +1213,23 @@
     FlowModel<Variable, Type> other,
     Iterable<Variable> written,
   }) {
-    Map<Variable, VariableModel<Type>> newVariableInfo;
+    Map<Variable, VariableModel<Variable, Type>> newVariableInfo;
 
     void markNotUnassigned(Variable variable) {
-      VariableModel<Type> info = variableInfo[variable];
+      VariableModel<Variable, Type> info = variableInfo[variable];
       if (info == null) return;
 
-      VariableModel<Type> newInfo = info.markNotUnassigned();
+      VariableModel<Variable, Type> newInfo = info.markNotUnassigned();
       if (identical(newInfo, info)) return;
 
-      (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
-          variableInfo))[variable] = newInfo;
+      (newVariableInfo ??=
+          new Map<Variable, VariableModel<Variable, Type>>.from(
+              variableInfo))[variable] = newInfo;
     }
 
     if (other != null) {
       for (Variable variable in other.variableInfo.keys) {
-        VariableModel<Type> otherInfo = other.variableInfo[variable];
+        VariableModel<Variable, Type> otherInfo = other.variableInfo[variable];
         if (!otherInfo.unassigned) {
           markNotUnassigned(variable);
         }
@@ -1246,23 +1269,26 @@
   FlowModel<Variable, Type> removePromotedAll(
       Iterable<Variable> writtenVariables,
       Iterable<Variable> capturedVariables) {
-    Map<Variable, VariableModel<Type>> newVariableInfo;
+    Map<Variable, VariableModel<Variable, Type>> newVariableInfo;
     for (Variable variable in writtenVariables) {
-      VariableModel<Type> info = infoFor(variable);
+      VariableModel<Variable, Type> info = infoFor(variable);
       if (info.promotedTypes != null) {
-        (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
-            variableInfo))[variable] = info.discardPromotions();
+        (newVariableInfo ??=
+            new Map<Variable, VariableModel<Variable, Type>>.from(
+                variableInfo))[variable] = info.discardPromotions();
       }
     }
     for (Variable variable in capturedVariables) {
-      VariableModel<Type> info = variableInfo[variable];
+      VariableModel<Variable, Type> info = variableInfo[variable];
       if (info == null) {
-        (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
-                variableInfo))[variable] =
-            new VariableModel<Type>(null, const [], false, false, true);
+        (newVariableInfo ??=
+            new Map<Variable, VariableModel<Variable, Type>>.from(
+                variableInfo))[variable] = new VariableModel<Variable, Type>(
+            null, const [], false, false, true);
       } else if (!info.writeCaptured) {
-        (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
-            variableInfo))[variable] = info.writeCapture();
+        (newVariableInfo ??=
+            new Map<Variable, VariableModel<Variable, Type>>.from(
+                variableInfo))[variable] = info.writeCapture();
       }
     }
     if (newVariableInfo == null) return this;
@@ -1295,20 +1321,20 @@
       Set<Variable> unsafe) {
     bool newReachable = reachable && other.reachable;
 
-    Map<Variable, VariableModel<Type>> newVariableInfo =
-        <Variable, VariableModel<Type>>{};
+    Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+        <Variable, VariableModel<Variable, Type>>{};
     bool variableInfoMatchesThis = true;
     bool variableInfoMatchesOther = true;
-    for (MapEntry<Variable, VariableModel<Type>> entry
+    for (MapEntry<Variable, VariableModel<Variable, Type>> entry
         in variableInfo.entries) {
       Variable variable = entry.key;
-      VariableModel<Type> thisModel = entry.value;
-      VariableModel<Type> otherModel = other.variableInfo[variable];
+      VariableModel<Variable, Type> thisModel = entry.value;
+      VariableModel<Variable, Type> otherModel = other.variableInfo[variable];
       if (otherModel == null) {
         variableInfoMatchesThis = false;
         continue;
       }
-      VariableModel<Type> restricted = thisModel.restrict(
+      VariableModel<Variable, Type> restricted = thisModel.restrict(
           typeOperations, otherModel, unsafe.contains(variable));
       newVariableInfo[variable] = restricted;
       if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
@@ -1353,47 +1379,99 @@
   /// potentially nullable.
   ExpressionInfo<Variable, Type> tryMarkNonNullable(
       TypeOperations<Variable, Type> typeOperations, Variable variable) {
-    VariableModel<Type> info = infoFor(variable);
+    VariableModel<Variable, Type> info = infoFor(variable);
     if (info.writeCaptured) {
       return new ExpressionInfo<Variable, Type>(this, this, this);
     }
+
     Type previousType = info.promotedTypes?.last;
     previousType ??= typeOperations.variableType(variable);
-    Type type = typeOperations.promoteToNonNull(previousType);
-    if (typeOperations.isSameType(type, previousType)) {
+
+    Type newType = typeOperations.promoteToNonNull(previousType);
+    if (typeOperations.isSameType(newType, previousType)) {
       return new ExpressionInfo<Variable, Type>(this, this, this);
     }
-    assert(typeOperations.isSubtypeOf(type, previousType));
-    return _finishTypeTest(typeOperations, variable, info, type);
+    assert(typeOperations.isSubtypeOf(newType, previousType));
+
+    FlowModel<Variable, Type> modelIfSuccessful =
+        _finishTypeTest(typeOperations, variable, info, null, newType);
+
+    FlowModel<Variable, Type> modelIfFailed = this;
+
+    return new ExpressionInfo<Variable, Type>(
+        this, modelIfSuccessful, modelIfFailed);
   }
 
-  /// Returns an [ExpressionInfo] indicating the result of checking whether the
-  /// given [variable] satisfies the given [type], e.g. as a consequence of an
-  /// `is` expression as the condition of an `if` statement.
+  /// Returns an [ExpressionInfo] indicating the result of casting the given
+  /// [variable] to the given [type], as a consequence of an `as` expression.
   ///
   /// Note that the state is only changed if [type] is a subtype of the
   /// variable's previous (possibly promoted) type.
   ///
   /// TODO(paulberry): if the type is non-nullable, should this method mark the
   /// variable as definitely assigned?  Does it matter?
-  ExpressionInfo<Variable, Type> tryPromote(
+  FlowModel<Variable, Type> tryPromoteForTypeCast(
       TypeOperations<Variable, Type> typeOperations,
       Variable variable,
       Type type) {
-    VariableModel<Type> info = infoFor(variable);
+    VariableModel<Variable, Type> info = infoFor(variable);
     if (info.writeCaptured) {
-      return new ExpressionInfo<Variable, Type>(this, this, this);
+      return this;
     }
+
     Type previousType = info.promotedTypes?.last;
     previousType ??= typeOperations.variableType(variable);
 
     Type newType = typeOperations.tryPromoteToType(type, previousType);
     if (newType == null || typeOperations.isSameType(newType, previousType)) {
-      return new ExpressionInfo<Variable, Type>(this, this, this);
+      return this;
     }
+
     assert(typeOperations.isSubtypeOf(newType, previousType),
         "Expected $newType to be a subtype of $previousType.");
-    return _finishTypeTest(typeOperations, variable, info, newType);
+    return _finishTypeTest(typeOperations, variable, info, type, newType);
+  }
+
+  /// Returns an [ExpressionInfo] indicating the result of checking whether the
+  /// given [variable] satisfies the given [type], e.g. as a consequence of an
+  /// `is` expression as the condition of an `if` statement.
+  ///
+  /// Note that the "ifTrue" state is only changed if [type] is a subtype of
+  /// the variable's previous (possibly promoted) type.
+  ///
+  /// TODO(paulberry): if the type is non-nullable, should this method mark the
+  /// variable as definitely assigned?  Does it matter?
+  ExpressionInfo<Variable, Type> tryPromoteForTypeCheck(
+      TypeOperations<Variable, Type> typeOperations,
+      Variable variable,
+      Type type) {
+    VariableModel<Variable, Type> info = infoFor(variable);
+    if (info.writeCaptured) {
+      return new ExpressionInfo<Variable, Type>(this, this, this);
+    }
+
+    Type previousType = info.promotedTypes?.last;
+    previousType ??= typeOperations.variableType(variable);
+
+    FlowModel<Variable, Type> modelIfSuccessful = this;
+    Type typeIfSuccess = typeOperations.tryPromoteToType(type, previousType);
+    if (typeIfSuccess != null &&
+        !typeOperations.isSameType(typeIfSuccess, previousType)) {
+      assert(typeOperations.isSubtypeOf(typeIfSuccess, previousType),
+          "Expected $typeIfSuccess to be a subtype of $previousType.");
+      modelIfSuccessful =
+          _finishTypeTest(typeOperations, variable, info, type, typeIfSuccess);
+    }
+
+    Type factoredType = typeOperations.factor(previousType, type);
+    Type typeIfFailed = typeOperations.isSameType(factoredType, previousType)
+        ? null
+        : factoredType;
+    FlowModel<Variable, Type> modelIfFailed =
+        _finishTypeTest(typeOperations, variable, info, type, typeIfFailed);
+
+    return new ExpressionInfo<Variable, Type>(
+        this, modelIfSuccessful, modelIfFailed);
   }
 
   /// Updates the state to indicate that an assignment was made to the given
@@ -1401,56 +1479,61 @@
   /// previous type promotion is removed.
   FlowModel<Variable, Type> write(Variable variable, Type writtenType,
       TypeOperations<Variable, Type> typeOperations) {
-    VariableModel<Type> infoForVar = variableInfo[variable];
+    VariableModel<Variable, Type> infoForVar = variableInfo[variable];
     if (infoForVar == null) return this;
 
-    VariableModel<Type> newInfoForVar =
-        infoForVar.write(writtenType, typeOperations);
+    VariableModel<Variable, Type> newInfoForVar =
+        infoForVar.write(variable, writtenType, typeOperations);
     if (identical(newInfoForVar, infoForVar)) return this;
 
     return _updateVariableInfo(variable, newInfoForVar);
   }
 
-  /// Common algorithm for [tryMarkNonNullable] and [tryPromote].  Builds an
-  /// [ExpressionInfo] object describing the effect of trying to promote
-  /// [variable] to [testedType], under the following preconditions:
+  /// Common algorithm for [tryMarkNonNullable], [tryPromoteForTypeCast],
+  /// and [tryPromoteForTypeCheck].  Builds a [FlowModel] object describing the
+  /// effect of updating the [variable] by adding the [testedType] to the
+  /// list of tested types (if not `null`, and not there already), adding the
+  /// [promotedType] to the chain of promoted types.
+  ///
+  /// Preconditions:
   /// - [info] should be the result of calling `infoFor(variable)`
-  /// - [testedType] should be a subtype of the currently-promoted type (i.e.
+  /// - [promotedType] should be a subtype of the currently-promoted type (i.e.
   ///   no redundant or side-promotions)
   /// - The variable should not be write-captured.
-  ExpressionInfo<Variable, Type> _finishTypeTest(
-      TypeOperations<Variable, Type> typeOperations,
-      Variable variable,
-      VariableModel<Type> info,
-      Type testedType) {
-    List<Type> newPromotedTypes =
-        VariableModel._addToPromotedTypes(info.promotedTypes, testedType);
-    List<Type> newTested = VariableModel._addTypeToUniqueList(
-        info.tested, testedType, typeOperations);
-    FlowModel<Variable, Type> modelIfFailed = identical(newTested, info.tested)
+  FlowModel<Variable, Type> _finishTypeTest(
+    TypeOperations<Variable, Type> typeOperations,
+    Variable variable,
+    VariableModel<Variable, Type> info,
+    Type testedType,
+    Type promotedType,
+  ) {
+    List<Type> newTested = info.tested;
+    if (testedType != null) {
+      newTested = VariableModel._addTypeToUniqueList(
+          info.tested, testedType, typeOperations);
+    }
+
+    List<Type> newPromotedTypes = info.promotedTypes;
+    if (promotedType != null) {
+      newPromotedTypes =
+          VariableModel._addToPromotedTypes(info.promotedTypes, promotedType);
+    }
+
+    return identical(newTested, info.tested) &&
+            identical(newPromotedTypes, info.promotedTypes)
         ? this
         : _updateVariableInfo(
             variable,
-            new VariableModel<Type>(info.promotedTypes, newTested,
+            new VariableModel<Variable, Type>(newPromotedTypes, newTested,
                 info.assigned, info.unassigned, info.writeCaptured));
-    FlowModel<Variable, Type> modelIfSuccessful =
-        identical(newPromotedTypes, info.promotedTypes) &&
-                identical(newTested, info.tested)
-            ? this
-            : _updateVariableInfo(
-                variable,
-                new VariableModel<Type>(newPromotedTypes, newTested,
-                    info.assigned, info.unassigned, info.writeCaptured));
-    return new ExpressionInfo<Variable, Type>(
-        this, modelIfSuccessful, modelIfFailed);
   }
 
   /// Returns a new [FlowModel] where the information for [variable] is replaced
   /// with [model].
   FlowModel<Variable, Type> _updateVariableInfo(
-      Variable variable, VariableModel<Type> model) {
-    Map<Variable, VariableModel<Type>> newVariableInfo =
-        new Map<Variable, VariableModel<Type>>.from(variableInfo);
+      Variable variable, VariableModel<Variable, Type> model) {
+    Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+        new Map<Variable, VariableModel<Variable, Type>>.from(variableInfo);
     newVariableInfo[variable] = model;
     return new FlowModel<Variable, Type>._(reachable, newVariableInfo);
   }
@@ -1468,6 +1551,7 @@
     TypeOperations<Variable, Type> typeOperations,
     FlowModel<Variable, Type> first,
     FlowModel<Variable, Type> second,
+    Map<Variable, VariableModel<Variable, Type>> emptyVariableMap,
   ) {
     if (first == null) return second;
     if (second == null) return first;
@@ -1476,9 +1560,9 @@
     if (!first.reachable && second.reachable) return second;
 
     bool newReachable = first.reachable || second.reachable;
-    Map<Variable, VariableModel<Type>> newVariableInfo =
-        FlowModel.joinVariableInfo(
-            typeOperations, first.variableInfo, second.variableInfo);
+    Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+        FlowModel.joinVariableInfo(typeOperations, first.variableInfo,
+            second.variableInfo, emptyVariableMap);
 
     return FlowModel._identicalOrNew(
         first, second, newReachable, newVariableInfo);
@@ -1486,26 +1570,32 @@
 
   /// Joins two "variable info" maps.  See [join] for details.
   @visibleForTesting
-  static Map<Variable, VariableModel<Type>> joinVariableInfo<Variable, Type>(
+  static Map<Variable, VariableModel<Variable, Type>>
+      joinVariableInfo<Variable, Type>(
     TypeOperations<Variable, Type> typeOperations,
-    Map<Variable, VariableModel<Type>> first,
-    Map<Variable, VariableModel<Type>> second,
+    Map<Variable, VariableModel<Variable, Type>> first,
+    Map<Variable, VariableModel<Variable, Type>> second,
+    Map<Variable, VariableModel<Variable, Type>> emptyMap,
   ) {
     if (identical(first, second)) return first;
-    if (first.isEmpty || second.isEmpty) return const {};
+    if (first.isEmpty || second.isEmpty) {
+      return emptyMap;
+    }
 
-    Map<Variable, VariableModel<Type>> result =
-        <Variable, VariableModel<Type>>{};
+    Map<Variable, VariableModel<Variable, Type>> result =
+        <Variable, VariableModel<Variable, Type>>{};
     bool alwaysFirst = true;
     bool alwaysSecond = true;
-    for (MapEntry<Variable, VariableModel<Type>> entry in first.entries) {
+    for (MapEntry<Variable, VariableModel<Variable, Type>> entry
+        in first.entries) {
       Variable variable = entry.key;
-      VariableModel<Type> secondModel = second[variable];
+      VariableModel<Variable, Type> secondModel = second[variable];
       if (secondModel == null) {
         alwaysFirst = false;
       } else {
-        VariableModel<Type> joined =
-            VariableModel.join<Type>(typeOperations, entry.value, secondModel);
+        VariableModel<Variable, Type> joined =
+            VariableModel.join<Variable, Type>(
+                typeOperations, entry.value, secondModel);
         result[variable] = joined;
         if (!identical(joined, entry.value)) alwaysFirst = false;
         if (!identical(joined, secondModel)) alwaysSecond = false;
@@ -1514,7 +1604,7 @@
 
     if (alwaysFirst) return first;
     if (alwaysSecond && result.length == second.length) return second;
-    if (result.isEmpty) return const {};
+    if (result.isEmpty) return emptyMap;
     return result;
   }
 
@@ -1524,7 +1614,7 @@
       FlowModel<Variable, Type> first,
       FlowModel<Variable, Type> second,
       bool newReachable,
-      Map<Variable, VariableModel<Type>> newVariableInfo) {
+      Map<Variable, VariableModel<Variable, Type>> newVariableInfo) {
     if (first.reachable == newReachable &&
         identical(first.variableInfo, newVariableInfo)) {
       return first;
@@ -1542,13 +1632,14 @@
   /// The equivalence check is shallow; if two variables' models are not
   /// identical, we return `false`.
   static bool _variableInfosEqual<Variable, Type>(
-      Map<Variable, VariableModel<Type>> p1,
-      Map<Variable, VariableModel<Type>> p2) {
+      Map<Variable, VariableModel<Variable, Type>> p1,
+      Map<Variable, VariableModel<Variable, Type>> p2) {
     if (p1.length != p2.length) return false;
     if (!p1.keys.toSet().containsAll(p2.keys)) return false;
-    for (MapEntry<Variable, VariableModel<Type>> entry in p1.entries) {
-      VariableModel<Type> p1Value = entry.value;
-      VariableModel<Type> p2Value = p2[entry.key];
+    for (MapEntry<Variable, VariableModel<Variable, Type>> entry
+        in p1.entries) {
+      VariableModel<Variable, Type> p1Value = entry.value;
+      VariableModel<Variable, Type> p2Value = p2[entry.key];
       if (!identical(p1Value, p2Value)) {
         return false;
       }
@@ -1559,6 +1650,15 @@
 
 /// Operations on types, abstracted from concrete type interfaces.
 abstract class TypeOperations<Variable, Type> {
+  /// Returns the "remainder" of [from] when [what] has been removed from
+  /// consideration by an instance check.
+  Type factor(Type from, Type what);
+
+  /// Return `true` if the [variable] is a local variable (not a formal
+  /// parameter), and it has no declared type (no explicit type, and not
+  /// initializer).
+  bool isLocalVariableWithoutDeclaredType(Variable variable);
+
   /// Returns `true` if [type1] and [type2] are the same type.
   bool isSameType(Type type1, Type type2);
 
@@ -1586,7 +1686,7 @@
 /// Instances of this class are immutable, so the methods below that "update"
 /// the state actually leave `this` unchanged and return a new state object.
 @visibleForTesting
-class VariableModel<Type> {
+class VariableModel<Variable, Type> {
   /// Sequence of types that the variable has been promoted to, where each
   /// element of the sequence is a subtype of the previous.  Null if the
   /// variable hasn't been promoted.
@@ -1628,39 +1728,61 @@
 
   /// Returns a new [VariableModel] in which any promotions present have been
   /// dropped.
-  VariableModel<Type> discardPromotions() {
+  VariableModel<Variable, Type> discardPromotions() {
     assert(promotedTypes != null, 'No promotions to discard');
-    return new VariableModel<Type>(
+    return new VariableModel<Variable, Type>(
         null, tested, assigned, unassigned, writeCaptured);
   }
 
   /// Returns a new [VariableModel] reflecting the fact that the variable was
   /// just initialized.
-  VariableModel<Type> initialize() {
+  VariableModel<Variable, Type> initialize() {
     if (promotedTypes == null && tested.isEmpty && assigned && !unassigned) {
       return this;
     }
-    return new VariableModel<Type>(null, const [], true, false, writeCaptured);
+    return new VariableModel<Variable, Type>(
+        null, const [], true, false, writeCaptured);
   }
 
   /// Returns a new [VariableModel] reflecting the fact that the variable is
   /// not definitely unassigned.
-  VariableModel<Type> markNotUnassigned() {
+  VariableModel<Variable, Type> markNotUnassigned() {
     if (!unassigned) return this;
 
-    return new VariableModel<Type>(
+    return new VariableModel<Variable, Type>(
         promotedTypes, tested, assigned, false, writeCaptured);
   }
 
   /// Returns an updated model reflect a control path that is known to have
   /// previously passed through some [other] state.  See [FlowModel.restrict]
   /// for details.
-  VariableModel<Type> restrict(TypeOperations<Object, Type> typeOperations,
-      VariableModel<Type> otherModel, bool unsafe) {
+  VariableModel<Variable, Type> restrict(
+      TypeOperations<Variable, Type> typeOperations,
+      VariableModel<Variable, Type> otherModel,
+      bool unsafe) {
     List<Type> thisPromotedTypes = promotedTypes;
     List<Type> otherPromotedTypes = otherModel.promotedTypes;
     bool newAssigned = assigned || otherModel.assigned;
-    bool newUnassigned = unassigned;
+    // The variable can only be unassigned in this state if it was also
+    // unassigned in the other state or if the other state didn't complete
+    // normally. For the latter case the resulting state is unreachable but to
+    // avoid creating a variable model that is both assigned and unassigned we
+    // take the intersection below.
+    //
+    // This situation can occur in try-finally like:
+    //
+    //   method() {
+    //     var local;
+    //     try {
+    //       local = 0;
+    //       return; // assigned
+    //     } finally {
+    //       local; // unassigned
+    //     }
+    //     local; // unreachable state
+    //   }
+    //
+    bool newUnassigned = unassigned && otherModel.unassigned;
     bool newWriteCaptured = writeCaptured || otherModel.writeCaptured;
     List<Type> newPromotedTypes;
     if (unsafe) {
@@ -1718,45 +1840,87 @@
 
   /// Returns a new [VariableModel] reflecting the fact that the variable was
   /// just written to.
-  VariableModel<Type> write(
-      Type writtenType, TypeOperations<Object, Type> typeOperations) {
-    List<Type> newPromotedTypes;
-    if (promotedTypes == null) {
-      newPromotedTypes = null;
-    } else if (typeOperations.isSubtypeOf(writtenType, promotedTypes.last)) {
-      newPromotedTypes = promotedTypes;
-    } else {
-      int numChainElementsToKeep = promotedTypes.length - 1;
-      while (true) {
-        if (numChainElementsToKeep == 0) {
-          newPromotedTypes = null;
-          break;
-        } else if (typeOperations.isSubtypeOf(
-            writtenType, promotedTypes[numChainElementsToKeep - 1])) {
-          newPromotedTypes = promotedTypes.sublist(0, numChainElementsToKeep);
-          break;
-        } else {
-          numChainElementsToKeep--;
-        }
-      }
+  VariableModel<Variable, Type> write(Variable variable, Type writtenType,
+      TypeOperations<Variable, Type> typeOperations) {
+    if (writeCaptured) {
+      return new VariableModel<Variable, Type>(
+          promotedTypes, tested, true, false, writeCaptured);
     }
+
+    if (_isPromotableViaInitialization(typeOperations, variable)) {
+      return new VariableModel<Variable, Type>(
+          [writtenType], tested, true, false, writeCaptured);
+    }
+
+    List<Type> newPromotedTypes = _demoteViaAssignment(
+      writtenType,
+      typeOperations,
+    );
+
+    Type declaredType = typeOperations.variableType(variable);
     newPromotedTypes = _tryPromoteToTypeOfInterest(
-        typeOperations, newPromotedTypes, writtenType);
+        typeOperations, declaredType, newPromotedTypes, writtenType);
     if (identical(promotedTypes, newPromotedTypes) && assigned) return this;
+
     List<Type> newTested;
     if (newPromotedTypes == null && promotedTypes != null) {
       newTested = const [];
     } else {
       newTested = tested;
     }
-    return new VariableModel<Type>(
+
+    return new VariableModel<Variable, Type>(
         newPromotedTypes, newTested, true, false, writeCaptured);
   }
 
   /// Returns a new [VariableModel] reflecting the fact that the variable has
   /// been write-captured.
-  VariableModel<Type> writeCapture() {
-    return new VariableModel<Type>(null, const [], assigned, false, true);
+  VariableModel<Variable, Type> writeCapture() {
+    return new VariableModel<Variable, Type>(
+        null, const [], assigned, false, true);
+  }
+
+  List<Type> _demoteViaAssignment(
+    Type writtenType,
+    TypeOperations<Variable, Type> typeOperations,
+  ) {
+    if (promotedTypes == null) {
+      return null;
+    }
+
+    int numElementsToKeep = promotedTypes.length;
+    for (;; numElementsToKeep--) {
+      if (numElementsToKeep == 0) {
+        return null;
+      }
+      Type promoted = promotedTypes[numElementsToKeep - 1];
+      if (typeOperations.isSubtypeOf(writtenType, promoted)) {
+        if (numElementsToKeep == promotedTypes.length) {
+          return promotedTypes;
+        }
+        return promotedTypes.sublist(0, numElementsToKeep);
+      }
+    }
+  }
+
+  /// We say that a variable `x` is promotable via initialization given
+  /// variable model `VM` if `x` is a local variable (not a formal parameter)
+  /// and:
+  /// * VM = VariableModel(declared, promoted, tested,
+  ///                      assigned, unassigned, captured)
+  /// * and `captured` is false
+  /// * and `promoted` is empty
+  /// * and `x` is declared with no explicit type and no initializer
+  /// * and `assigned` is false and `unassigned` is true
+  bool _isPromotableViaInitialization<Variable>(
+    TypeOperations<Variable, Type> typeOperations,
+    Variable variable,
+  ) {
+    return !writeCaptured &&
+        !assigned &&
+        unassigned &&
+        promotedTypes == null &&
+        typeOperations.isLocalVariableWithoutDeclaredType(variable);
   }
 
   /// Determines whether a variable with the given [promotedTypes] should be
@@ -1767,34 +1931,80 @@
   /// Note that since promotions chains are considered immutable, if promotion
   /// is required, a new promotion chain will be created and returned.
   List<Type> _tryPromoteToTypeOfInterest(
-      TypeOperations<Object, Type> typeOperations,
+      TypeOperations<Variable, Type> typeOperations,
+      Type declaredType,
       List<Type> promotedTypes,
       Type writtenType) {
+    assert(!writeCaptured);
+
     // Figure out if we have any promotion candidates (types that are a
     // supertype of writtenType and a proper subtype of the currently-promoted
     // type).  If at any point we find an exact match, we take it immediately.
     Type currentlyPromotedType = promotedTypes?.last;
+
+    List<Type> result;
     List<Type> candidates = null;
-    for (int i = 0; i < tested.length; i++) {
-      Type type = tested[i];
+
+    void handleTypeOfInterest(Type type) {
+      // The written type must be a subtype of the type.
       if (!typeOperations.isSubtypeOf(writtenType, type)) {
-        // Can't promote to this type; the type written is not a subtype of
-        // it.
-      } else if (currentlyPromotedType != null &&
-          !typeOperations.isSubtypeOf(type, currentlyPromotedType)) {
-        // Can't promote to this type; it's less specific than the currently
-        // promoted type.
-      } else if (currentlyPromotedType != null &&
-          typeOperations.isSameType(type, currentlyPromotedType)) {
-        // Can't promote to this type; it's the same as the currently
-        // promoted type.
-      } else if (typeOperations.isSameType(type, writtenType)) {
-        // This is precisely the type we want to promote to; take it.
-        return _addToPromotedTypes(promotedTypes, writtenType);
-      } else {
-        (candidates ??= []).add(type);
+        return;
+      }
+
+      // Must be more specific that the currently promoted type.
+      if (currentlyPromotedType != null) {
+        if (typeOperations.isSameType(type, currentlyPromotedType)) {
+          return;
+        }
+        if (!typeOperations.isSubtypeOf(type, currentlyPromotedType)) {
+          return;
+        }
+      }
+
+      // This is precisely the type we want to promote to; take it.
+      if (typeOperations.isSameType(type, writtenType)) {
+        result = _addToPromotedTypes(promotedTypes, writtenType);
+      }
+
+      if (candidates == null) {
+        candidates = [type];
+        return;
+      }
+
+      // Add only unique candidates.
+      if (!_typeListContains(typeOperations, candidates, type)) {
+        candidates.add(type);
+        return;
       }
     }
+
+    // The declared type is always a type of interest, but we never promote
+    // to the declared type. So, try NonNull of it.
+    Type declaredTypeNonNull = typeOperations.promoteToNonNull(declaredType);
+    if (!typeOperations.isSameType(declaredTypeNonNull, declaredType)) {
+      handleTypeOfInterest(declaredTypeNonNull);
+      if (result != null) {
+        return result;
+      }
+    }
+
+    for (int i = 0; i < tested.length; i++) {
+      Type type = tested[i];
+
+      handleTypeOfInterest(type);
+      if (result != null) {
+        return result;
+      }
+
+      Type typeNonNull = typeOperations.promoteToNonNull(type);
+      if (!typeOperations.isSameType(typeNonNull, type)) {
+        handleTypeOfInterest(typeNonNull);
+        if (result != null) {
+          return result;
+        }
+      }
+    }
+
     if (candidates != null) {
       // Figure out if we have a unique promotion candidate that's a subtype
       // of all the others.
@@ -1824,10 +2034,10 @@
   }
 
   /// Joins two variable models.  See [FlowModel.join] for details.
-  static VariableModel<Type> join<Type>(
-      TypeOperations<Object, Type> typeOperations,
-      VariableModel<Type> first,
-      VariableModel<Type> second) {
+  static VariableModel<Variable, Type> join<Variable, Type>(
+      TypeOperations<Variable, Type> typeOperations,
+      VariableModel<Variable, Type> first,
+      VariableModel<Variable, Type> second) {
     List<Type> newPromotedTypes = joinPromotedTypes(
         first.promotedTypes, second.promotedTypes, typeOperations);
     bool newAssigned = first.assigned && second.assigned;
@@ -1844,8 +2054,8 @@
   /// chains.  Briefly, we intersect given chains.  The chains are totally
   /// ordered subsets of a global partial order.  Their intersection is a
   /// subset of each, and as such is also totally ordered.
-  static List<Type> joinPromotedTypes<Type>(List<Type> chain1,
-      List<Type> chain2, TypeOperations<Object, Type> typeOperations) {
+  static List<Type> joinPromotedTypes<Variable, Type>(List<Type> chain1,
+      List<Type> chain2, TypeOperations<Variable, Type> typeOperations) {
     if (chain1 == null) return chain1;
     if (chain2 == null) return chain2;
 
@@ -1888,8 +2098,8 @@
   /// - The sense of equality for the union operation is determined by
   ///   [TypeOperations.isSameType].
   /// - The types of interests lists are considered immutable.
-  static List<Type> joinTested<Type>(List<Type> types1, List<Type> types2,
-      TypeOperations<Object, Type> typeOperations) {
+  static List<Type> joinTested<Variable, Type>(List<Type> types1,
+      List<Type> types2, TypeOperations<Variable, Type> typeOperations) {
     // Ensure that types1 is the shorter list.
     if (types1.length > types2.length) {
       List<Type> tmp = types1;
@@ -1924,17 +2134,17 @@
           ? [promoted]
           : (promotedTypes.toList()..add(promoted));
 
-  static List<Type> _addTypeToUniqueList<Type>(List<Type> types, Type newType,
-      TypeOperations<Object, Type> typeOperations) {
+  static List<Type> _addTypeToUniqueList<Variable, Type>(List<Type> types,
+      Type newType, TypeOperations<Variable, Type> typeOperations) {
     if (_typeListContains(typeOperations, types, newType)) return types;
     return new List<Type>.from(types)..add(newType);
   }
 
   /// Creates a new [VariableModel] object, unless it is equivalent to either
   /// [first] or [second], in which case one of those objects is re-used.
-  static VariableModel<Type> _identicalOrNew<Type>(
-      VariableModel<Type> first,
-      VariableModel<Type> second,
+  static VariableModel<Variable, Type> _identicalOrNew<Variable, Type>(
+      VariableModel<Variable, Type> first,
+      VariableModel<Variable, Type> second,
       List<Type> newPromotedTypes,
       List<Type> newTested,
       bool newAssigned,
@@ -1953,13 +2163,13 @@
         second.writeCaptured == newWriteCaptured) {
       return second;
     } else {
-      return new VariableModel<Type>(newPromotedTypes, newTested, newAssigned,
-          newUnassigned, newWriteCaptured);
+      return new VariableModel<Variable, Type>(newPromotedTypes, newTested,
+          newAssigned, newUnassigned, newWriteCaptured);
     }
   }
 
-  static bool _typeListContains<Type>(
-      TypeOperations<Object, Type> typeOperations,
+  static bool _typeListContains<Variable, Type>(
+      TypeOperations<Variable, Type> typeOperations,
       List<Type> list,
       Type searchType) {
     for (Type type in list) {
@@ -2072,7 +2282,7 @@
     } else {
       return;
     }
-    _current = _current.tryPromote(typeOperations, variable, type).ifTrue;
+    _current = _current.tryPromoteForTypeCast(typeOperations, variable, type);
   }
 
   @override
@@ -2380,7 +2590,7 @@
       return;
     }
     ExpressionInfo<Variable, Type> expressionInfo =
-        _current.tryPromote(typeOperations, variable, type);
+        _current.tryPromoteForTypeCheck(typeOperations, variable, type);
     _storeExpressionInfo(isExpression,
         isNot ? ExpressionInfo.invert(expressionInfo) : expressionInfo);
   }
@@ -2391,6 +2601,21 @@
   }
 
   @override
+  void labeledStatement_begin(Node node) {
+    _BranchTargetContext<Variable, Type> context =
+        new _BranchTargetContext<Variable, Type>();
+    _stack.add(context);
+    _statementToContext[node] = context;
+  }
+
+  @override
+  void labeledStatement_end() {
+    _BranchTargetContext<Variable, Type> context =
+        _stack.removeLast() as _BranchTargetContext<Variable, Type>;
+    _current = _join(_current, context._breakModel);
+  }
+
+  @override
   void logicalBinaryOp_end(Expression wholeExpression, Expression rightOperand,
       {@required bool isAnd}) {
     _BranchContext<Variable, Type> context =
@@ -2661,7 +2886,7 @@
 
   FlowModel<Variable, Type> _join(
           FlowModel<Variable, Type> first, FlowModel<Variable, Type> second) =>
-      FlowModel.join(typeOperations, first, second);
+      FlowModel.join(typeOperations, first, second, _current._emptyVariableMap);
 
   /// Associates [expression], which should be the most recently visited
   /// expression, with the given [expressionInfo] object, and updates the
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 94553cd..4c34d93 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -1290,6 +1290,35 @@
     message: r"""Constant evaluation error:""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        String
+            string2)> templateConstEvalTruncateError = const Template<
+        Message Function(String string, String string2)>(
+    messageTemplate:
+        r"""Binary operator '#string ~/ #string2' results is Infinity or NaN.""",
+    withArguments: _withArgumentsConstEvalTruncateError);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, String string2)>
+    codeConstEvalTruncateError =
+    const Code<Message Function(String string, String string2)>(
+  "ConstEvalTruncateError",
+  templateConstEvalTruncateError,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalTruncateError(String string, String string2) {
+  if (string.isEmpty) throw 'No string provided';
+  if (string2.isEmpty) throw 'No string provided';
+  return new Message(codeConstEvalTruncateError,
+      message:
+          """Binary operator '${string} ~/ ${string2}' results is Infinity or NaN.""",
+      arguments: {'string': string, 'string2': string2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeConstEvalUnevaluated = messageConstEvalUnevaluated;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2879,29 +2908,33 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
+        String string,
         String
-            string)> templateExperimentNotEnabled = const Template<
-        Message Function(String string)>(
+            string2)> templateExperimentNotEnabled = const Template<
+        Message Function(String string, String string2)>(
     messageTemplate:
-        r"""This requires the '#string' experiment to be enabled.""",
+        r"""This requires the '#string' language feature to be enabled.""",
     tipTemplate:
-        r"""Try enabling this experiment by adding it to the command line when compiling and running.""",
+        r"""Try updating your pubspec.yaml to set the minimum SDK constraint to #string2 or higher, and running 'pub get'.""",
     withArguments: _withArgumentsExperimentNotEnabled);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String string)> codeExperimentNotEnabled =
-    const Code<Message Function(String string)>(
+const Code<Message Function(String string, String string2)>
+    codeExperimentNotEnabled =
+    const Code<Message Function(String string, String string2)>(
         "ExperimentNotEnabled", templateExperimentNotEnabled,
         index: 48);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsExperimentNotEnabled(String string) {
+Message _withArgumentsExperimentNotEnabled(String string, String string2) {
   if (string.isEmpty) throw 'No string provided';
+  if (string2.isEmpty) throw 'No string provided';
   return new Message(codeExperimentNotEnabled,
-      message: """This requires the '${string}' experiment to be enabled.""",
+      message:
+          """This requires the '${string}' language feature to be enabled.""",
       tip:
-          """Try enabling this experiment by adding it to the command line when compiling and running.""",
-      arguments: {'string': string});
+          """Try updating your pubspec.yaml to set the minimum SDK constraint to ${string2} or higher, and running 'pub get'.""",
+      arguments: {'string': string, 'string2': string2});
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3406,9 +3439,6 @@
     Location of the SDK sources for use when compiling additional platform
     libraries.
 
-  --supermixin
-    Ignored for now.
-
   --single-root-scheme=String
   --single-root-base=<dir>
     Specify a custom URI scheme and a location on disk where such URIs are
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 253b762..a241b0f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -629,8 +629,8 @@
 
   @override
   void endExtensionDeclaration(
-      Token extensionKeyword, Token onKeyword, Token token) {
-    listener?.endExtensionDeclaration(extensionKeyword, onKeyword, token);
+      Token extensionKeyword, Token onKeyword, Token endToken) {
+    listener?.endExtensionDeclaration(extensionKeyword, onKeyword, endToken);
   }
 
   @override
@@ -1037,6 +1037,16 @@
   }
 
   @override
+  void beginAsOperatorType(Token operator) {
+    listener?.beginAsOperatorType(operator);
+  }
+
+  @override
+  void endAsOperatorType(Token operator) {
+    listener?.endAsOperatorType(operator);
+  }
+
+  @override
   void handleAsOperator(Token operator) {
     listener?.handleAsOperator(operator);
   }
@@ -1276,6 +1286,16 @@
   }
 
   @override
+  void beginIsOperatorType(Token operator) {
+    listener?.beginIsOperatorType(operator);
+  }
+
+  @override
+  void endIsOperatorType(Token operator) {
+    listener?.endIsOperatorType(operator);
+  }
+
+  @override
   void handleIsOperator(Token isOperator, Token not) {
     listener?.handleIsOperator(isOperator, not);
   }
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 112bfe6..d284d8a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -225,7 +225,7 @@
   /// - on type
   /// - body
   void endExtensionDeclaration(
-      Token extensionKeyword, Token onKeyword, Token token) {
+      Token extensionKeyword, Token onKeyword, Token endToken) {
     logEvent('ExtensionDeclaration');
   }
 
@@ -1213,7 +1213,7 @@
   void reportVarianceModifierNotEnabled(Token variance) {
     if (variance != null) {
       handleRecoverableError(
-          templateExperimentNotEnabled.withArguments('variance'),
+          templateExperimentNotEnabled.withArguments('variance', '2.9'),
           variance,
           variance);
     }
@@ -1247,6 +1247,12 @@
     logEvent("WhileStatement");
   }
 
+  void beginAsOperatorType(Token operator) {}
+
+  void endAsOperatorType(Token operator) {
+    logEvent("AsOperatorType");
+  }
+
   void handleAsOperator(Token operator) {
     logEvent("AsOperator");
   }
@@ -1358,6 +1364,12 @@
     logEvent("IndexedExpression");
   }
 
+  void beginIsOperatorType(Token operator) {}
+
+  void endIsOperatorType(Token operator) {
+    logEvent("IsOperatorType");
+  }
+
   void handleIsOperator(Token isOperator, Token not) {
     logEvent("IsOperator");
   }
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 8a75f87..13ab757 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -1151,6 +1151,7 @@
   }
 
   Token parseWithClauseOpt(Token token) {
+    // <mixins> ::= with <typeNotVoidList>
     Token withKeyword = token.next;
     if (optional('with', withKeyword)) {
       token = parseTypeList(withKeyword);
@@ -1936,6 +1937,7 @@
   }
 
   Token parseClassExtendsOpt(Token token) {
+    // extends <typeNotVoid>
     Token next = token.next;
     if (optional('extends', next)) {
       Token extendsKeyword = next;
@@ -2480,7 +2482,7 @@
         reportRecoverableError(
             beforeType.next,
             codes.templateExperimentNotEnabled
-                .withArguments('extension-methods'));
+                .withArguments('extension-methods', '2.6'));
         token = rewriter.insertSyntheticToken(token, TokenType.SEMICOLON);
       } else {
         token = ensureSemicolon(token);
@@ -5468,8 +5470,10 @@
     if (optional('!', token.next)) {
       not = token = token.next;
     }
+    listener.beginIsOperatorType(operator);
     TypeInfo typeInfo = computeTypeAfterIsOrAs(token);
     token = typeInfo.ensureTypeNotVoid(token, this);
+    listener.endIsOperatorType(operator);
     listener.handleIsOperator(operator, not);
     return skipChainedAsIsOperators(token);
   }
@@ -5497,8 +5501,10 @@
   Token parseAsOperatorRest(Token token) {
     Token operator = token = token.next;
     assert(optional('as', operator));
+    listener.beginAsOperatorType(operator);
     TypeInfo typeInfo = computeTypeAfterIsOrAs(token);
     token = typeInfo.ensureTypeNotVoid(token, this);
+    listener.endAsOperatorType(operator);
     listener.handleAsOperator(operator);
     return skipChainedAsIsOperators(token);
   }
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
index b56e507..75be976 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
@@ -630,7 +630,7 @@
       if (atEndOfFile()) {
         appendEofToken();
       } else {
-        unexpected($EOF);
+        unexpectedEof();
       }
     }
 
@@ -1778,6 +1778,11 @@
     }
   }
 
+  void unexpectedEof() {
+    ErrorToken errorToken = buildUnexpectedCharacterToken($EOF, tokenStart);
+    prependErrorToken(errorToken);
+  }
+
   void unterminatedString(int quoteChar, int quoteStart, int start,
       {bool asciiOnly, bool isMultiLine, bool isRaw}) {
     String suffix = new String.fromCharCodes(
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/features.dart b/pkg/_fe_analyzer_shared/lib/src/testing/features.dart
index 36e32d7..7725a34 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/features.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/features.dart
@@ -59,31 +59,74 @@
 
   /// Returns a string containing all features in a comma-separated list sorted
   /// by feature names.
-  String getText() {
-    StringBuffer sb = new StringBuffer();
-    bool needsComma = false;
-    for (String name in _features.keys.toList()..sort()) {
-      dynamic value = _features[name];
-      if (value != null) {
-        if (needsComma) {
-          sb.write(',');
+  String getText([String indent]) {
+    if (indent == null) {
+      StringBuffer sb = new StringBuffer();
+      bool needsComma = false;
+      for (String name in _features.keys.toList()..sort()) {
+        dynamic value = _features[name];
+        if (value != null) {
+          if (needsComma) {
+            sb.write(',');
+          }
+          sb.write(name);
+          if (value is List<String>) {
+            if (_unsorted.contains(name)) {
+              value = '[${value.join(',')}]';
+            } else {
+              value = '[${(value..sort()).join(',')}]';
+            }
+          }
+          if (value != '') {
+            sb.write('=');
+            sb.write(value);
+          }
+          needsComma = true;
         }
+      }
+      return sb.toString();
+    } else {
+      StringBuffer sb = new StringBuffer();
+      Map<String, dynamic> values = {};
+      for (String name in _features.keys.toList()..sort()) {
+        dynamic value = _features[name];
+        if (value != null) {
+          values[name] = value;
+        }
+      }
+      String comma = '';
+      if (values.length > 1) {
+        comma = '\n$indent ';
+      }
+      values.forEach((String name, dynamic value) {
+        sb.write(comma);
         sb.write(name);
         if (value is List<String>) {
-          if (_unsorted.contains(name)) {
-            value = '[${value.join(',')}]';
+          if (value.length > 1) {
+            if (_unsorted.contains(name)) {
+              value = '[\n$indent  ${value.join(',\n$indent  ')}]';
+            } else {
+              value = '[\n$indent  ${(value..sort()).join(',\n$indent  ')}]';
+            }
           } else {
-            value = '[${(value..sort()).join(',')}]';
+            if (_unsorted.contains(name)) {
+              value = '[${value.join(',')}]';
+            } else {
+              value = '[${(value..sort()).join(',')}]';
+            }
           }
         }
         if (value != '') {
           sb.write('=');
           sb.write(value);
         }
-        needsComma = true;
+        comma = ',\n$indent ';
+      });
+      if (values.length > 1) {
+        sb.write('\n$indent');
       }
+      return sb.toString();
     }
-    return sb.toString();
   }
 
   @override
@@ -182,11 +225,13 @@
 }
 
 class FeaturesDataInterpreter implements DataInterpreter<Features> {
-  const FeaturesDataInterpreter();
+  final String wildcard;
+
+  const FeaturesDataInterpreter({this.wildcard: null});
 
   @override
   String isAsExpected(Features actualFeatures, String expectedData) {
-    if (expectedData == '*') {
+    if (wildcard != null && expectedData == wildcard) {
       return null;
     } else if (expectedData == '') {
       return actualFeatures.isNotEmpty ? "Expected empty data." : null;
@@ -212,7 +257,7 @@
           if (actualValue != '') {
             errorsFound.add('Non-empty data found for $key');
           }
-        } else if (expectedValue == '*') {
+        } else if (wildcard != null && expectedValue == wildcard) {
           return;
         } else if (expectedValue is List) {
           if (actualValue is List) {
@@ -220,10 +265,10 @@
             for (Object expectedObject in expectedValue) {
               String expectedText = '$expectedObject';
               bool matchFound = false;
-              if (expectedText.endsWith('*')) {
+              if (wildcard != null && expectedText.endsWith(wildcard)) {
                 // Wildcard matcher.
                 String prefix =
-                    expectedText.substring(0, expectedText.indexOf('*'));
+                    expectedText.substring(0, expectedText.indexOf(wildcard));
                 List matches = [];
                 for (Object actualObject in actualList) {
                   if ('$actualObject'.startsWith(prefix)) {
@@ -274,8 +319,8 @@
   }
 
   @override
-  String getText(Features actualData) {
-    return actualData.getText();
+  String getText(Features actualData, [String indentation]) {
+    return actualData.getText(indentation);
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
index 6800762..dd3fdb7e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
@@ -12,7 +12,8 @@
     Uri mainUri,
     Map<String, Map<Uri, Map<Id, ActualData<T>>>> actualData,
     DataInterpreter<T> dataInterpreter,
-    {Annotation Function(Annotation expected, Annotation actual) createDiff}) {
+    {Annotation Function(Annotation expected, Annotation actual) createDiff,
+    bool forceUpdate: false}) {
   Set<Uri> uriSet = {};
   Set<String> actualMarkers = actualData.keys.toSet();
   Map<Uri, Map<Id, Map<String, IdValue>>> idValuePerUri = {};
@@ -68,7 +69,7 @@
         code != null, "No annotated code for ${uri} in ${annotatedCode.keys}");
     result[uri] = _computeAnnotations(code, expectedMaps.keys, actualMarkers,
         idValuePerId, actualDataPerId, dataInterpreter,
-        sortMarkers: false, createDiff: createDiff);
+        sortMarkers: false, createDiff: createDiff, forceUpdate: forceUpdate);
   }
   return result;
 }
@@ -83,31 +84,42 @@
     {String defaultPrefix: '/*',
     String defaultSuffix: '*/',
     bool sortMarkers: true,
-    Annotation Function(Annotation expected, Annotation actual) createDiff}) {
+    Annotation Function(Annotation expected, Annotation actual) createDiff,
+    bool forceUpdate: false}) {
   assert(annotatedCode != null);
 
   Annotation createAnnotationFromData(
       ActualData<T> actualData, Annotation annotation) {
+    String getIndentationFromOffset(int offset) {
+      int lineIndex = annotatedCode.getLineIndex(offset);
+      String line = annotatedCode.getLine(lineIndex);
+      String trimmed = line.trimLeft();
+      return line.substring(0, line.length - trimmed.length);
+    }
+
     int offset;
     String prefix;
     String suffix;
+    String indentation;
     if (annotation != null) {
       offset = annotation.offset;
       prefix = annotation.prefix;
       suffix = annotation.suffix;
+      indentation = getIndentationFromOffset(offset);
     } else {
       Id id = actualData.id;
       if (id is NodeId) {
         offset = id.value;
         prefix = defaultPrefix;
         suffix = defaultSuffix;
+        indentation = getIndentationFromOffset(offset);
       } else if (id is ClassId || id is MemberId) {
         // Place the annotation at the line above at the indentation level of
         // the class/member.
         int lineIndex = annotatedCode.getLineIndex(actualData.offset);
         String line = annotatedCode.getLine(lineIndex);
         String trimmed = line.trimLeft();
-        String indentation = line.substring(0, line.length - trimmed.length);
+        indentation = line.substring(0, line.length - trimmed.length);
         offset = annotatedCode.getLineStart(lineIndex);
         prefix = '$indentation$defaultPrefix';
         suffix = '$defaultSuffix\n';
@@ -124,6 +136,7 @@
         offset = annotatedCode.getLineStart(lineIndex);
         prefix = '\n$defaultPrefix';
         suffix = '$defaultSuffix\n';
+        indentation = '';
       } else {
         throw 'Unexpected id $id (${id.runtimeType})';
       }
@@ -135,8 +148,8 @@
         annotation?.columnNo ?? -1,
         offset,
         prefix,
-        IdValue.idToString(
-            actualData.id, dataInterpreter.getText(actualData.value)),
+        IdValue.idToString(actualData.id,
+            dataInterpreter.getText(actualData.value, indentation)),
         suffix);
   }
 
@@ -154,7 +167,8 @@
       Annotation actualAnnotation;
       if (idValue != null && actualData != null) {
         if (dataInterpreter.isAsExpected(actualData.value, idValue.value) ==
-            null) {
+                null &&
+            !forceUpdate) {
           // Use existing annotation.
           expectedAnnotation = actualAnnotation = idValue.annotation;
         } else {
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 7b64c73..f210251 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
@@ -11,12 +11,14 @@
 const String cfeMarker = 'cfe';
 const String cfeWithNnbdMarker = '$cfeMarker:nnbd';
 const String dart2jsMarker = 'dart2js';
+const String dart2jsWithNnbdSdkMarker = '$dart2jsMarker:nnbd-sdk';
 const String analyzerMarker = 'analyzer';
 
 /// Markers used in annotated tests shared by CFE, analyzer and dart2js.
 const List<String> sharedMarkers = [
   cfeMarker,
   dart2jsMarker,
+  dart2jsWithNnbdSdkMarker,
   analyzerMarker,
 ];
 
@@ -31,6 +33,7 @@
   cfeMarker,
   cfeWithNnbdMarker,
   dart2jsMarker,
+  dart2jsWithNnbdSdkMarker,
   analyzerMarker,
 ];
 
@@ -434,7 +437,10 @@
   bool isEmpty(T actualData);
 
   /// Returns a textual representation of [actualData].
-  String getText(T actualData);
+  ///
+  /// If [indentation] is provided a multiline pretty printing can be returned
+  /// using [indentation] for additional lines.
+  String getText(T actualData, [String indentation]);
 }
 
 /// Default data interpreter for string data.
@@ -457,7 +463,7 @@
   }
 
   @override
-  String getText(String actualData) {
+  String getText(String actualData, [String indentation]) {
     return actualData;
   }
 }
@@ -725,6 +731,7 @@
   bool continued = false;
   bool hasFailures = false;
   bool generateAnnotations = args.remove('-g');
+  bool forceUpdate = args.remove('-f');
 
   String relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
   print('Data dir: ${relativeDir}');
@@ -791,7 +798,7 @@
     if (hasErrors) {
       // Cannot generate annotations for erroneous tests.
       hasFailures = true;
-    } else if (hasMismatches) {
+    } else if (hasMismatches || (forceUpdate && generateAnnotations)) {
       if (generateAnnotations) {
         DataInterpreter dataInterpreter;
         Map<String, Map<Uri, Map<Id, ActualData<T>>>> actualData = {};
@@ -823,7 +830,8 @@
             testData.expectedMaps,
             testData.entryPoint,
             actualData,
-            dataInterpreter);
+            dataInterpreter,
+            forceUpdate: forceUpdate);
         annotations.forEach((Uri uri, List<Annotation> annotations) {
           assert(uri != null, "Annotations without uri: $annotations");
           AnnotatedCode code = testData.code[uri];
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 2efa38e..8870c1c 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 1.0.3
+version: 3.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/constants/data/basic.dart b/pkg/_fe_analyzer_shared/test/constants/data/basic.dart
index ec98279..138949b 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/basic.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/basic.dart
@@ -20,10 +20,10 @@
   print(/*Double(0.5)*/ double0);
   print(
       /*cfe|analyzer.Symbol(foo)*/
-      /*dart2js.Instance(Symbol,{_name:String(foo))*/
+      /*dart2js|dart2js:nnbd-sdk.Instance(Symbol,{_name:String(foo))*/
       symbol0);
   print(
       /*cfe|analyzer.Symbol(foo)*/
-      /*dart2js.Instance(Symbol,{_name:String(foo))*/
+      /*dart2js|dart2js:nnbd-sdk.Instance(Symbol,{_name:String(foo))*/
       symbol1);
 }
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/errors.dart b/pkg/_fe_analyzer_shared/test/constants/data/errors.dart
index c25cead..a1c0f01 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/errors.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/errors.dart
@@ -2,14 +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.
 
-// ignore_for_file: const_initialized_with_non_constant_value
-
-// TODO(paulberry): Support testing errors in analyzer id testing.
-
 String method() => 'foo';
 
 const String string0 =
-    /*cfe|dart2js.error: Method invocation is not a constant expression.*/
+    /*cfe|dart2js|dart2js:nnbd-sdk.error: Method invocation is not a constant expression.*/
     method();
 
 main() {
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/function.dart b/pkg/_fe_analyzer_shared/test/constants/data/function.dart
index 987b64c5..d8cf2b6 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/function.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/function.dart
@@ -15,15 +15,15 @@
 
 main() {
   print(
-      /*cfe|dart2js.Function(method1)*/
+      /*cfe|dart2js|dart2js:nnbd-sdk.Function(method1)*/
       /*analyzer.Function(method1,type=T Function<T>(T))*/
       function0);
   print(
       /*cfe|dart2js.Instantiation(method1<int>)*/
       /*analyzer.Function(method1,type=int Function(int))*/
-      instantiation0);
+      /*dart2js:nnbd-sdk.Instantiation(method1<int*>)*/ instantiation0);
   print(
       /*cfe|dart2js.Instantiation(method2<String,int>)*/
       /*analyzer.Function(method2,type=Map<String, int> Function(String, int))*/
-      instantiation1);
+      /*dart2js:nnbd-sdk.Instantiation(method2<String*,int*>)*/ instantiation1);
 }
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/list.dart b/pkg/_fe_analyzer_shared/test/constants/data/list.dart
index 446475d..c18686c 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/list.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/list.dart
@@ -16,8 +16,12 @@
 
 main() {
   print(/*List<dynamic>()*/ list0);
-  print(/*List<int>()*/ list1);
-  print(/*List<int>()*/ list2);
-  print(/*List<int>(Int(42))*/ list3);
-  print(/*List<int>(Int(42),Int(87))*/ list4);
+  print(
+      /*cfe|analyzer|dart2js.List<int>()*/ /*dart2js:nnbd-sdk.List<int*>()*/ list1);
+  print(
+      /*cfe|analyzer|dart2js.List<int>()*/ /*dart2js:nnbd-sdk.List<int*>()*/ list2);
+  print(
+      /*cfe|analyzer|dart2js.List<int>(Int(42))*/ /*dart2js:nnbd-sdk.List<int*>(Int(42))*/ list3);
+  print(
+      /*cfe|analyzer|dart2js.List<int>(Int(42),Int(87))*/ /*dart2js:nnbd-sdk.List<int*>(Int(42),Int(87))*/ list4);
 }
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/map.dart b/pkg/_fe_analyzer_shared/test/constants/data/map.dart
index 88cf275..bb783c2 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/map.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/map.dart
@@ -17,8 +17,12 @@
 
 main() {
   print(/*Map<dynamic,dynamic>()*/ map0);
-  print(/*Map<String,int>()*/ map1);
-  print(/*Map<String,int>()*/ map2);
-  print(/*Map<String,int>(String(foo):Int(42))*/ map3);
-  print(/*Map<String,int>(String(foo):Int(42),String(bar):Int(87))*/ map4);
+  print(
+      /*cfe|analyzer|dart2js.Map<String,int>()*/ /*dart2js:nnbd-sdk.Map<String*,int*>()*/ map1);
+  print(
+      /*cfe|analyzer|dart2js.Map<String,int>()*/ /*dart2js:nnbd-sdk.Map<String*,int*>()*/ map2);
+  print(
+      /*cfe|analyzer|dart2js.Map<String,int>(String(foo):Int(42))*/ /*dart2js:nnbd-sdk.Map<String*,int*>(String(foo):Int(42))*/ map3);
+  print(
+      /*cfe|analyzer|dart2js.Map<String,int>(String(foo):Int(42),String(bar):Int(87))*/ /*dart2js:nnbd-sdk.Map<String*,int*>(String(foo):Int(42),String(bar):Int(87))*/ map4);
 }
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/marker.options b/pkg/_fe_analyzer_shared/test/constants/data/marker.options
index f713e63..98b58d7 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/marker.options
+++ b/pkg/_fe_analyzer_shared/test/constants/data/marker.options
@@ -1,3 +1,4 @@
 cfe=pkg/front_end/test/id_tests/constant_test.dart
 analyzer=pkg/analyzer/test/id_tests/constant_test.dart
-dart2js=tests/compiler/dart2js/model/cfe_constant_test.dart
\ No newline at end of file
+dart2js=tests/compiler/dart2js/model/cfe_constant_test.dart
+dart2js:nnbd-sdk=tests/compiler/dart2js/model/cfe_constant_test.dart
\ No newline at end of file
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/set.dart b/pkg/_fe_analyzer_shared/test/constants/data/set.dart
index 26ca6c3..bf567fe 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/set.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/set.dart
@@ -21,8 +21,12 @@
 
 main() {
   print(/*Set<dynamic>()*/ set0);
-  print(/*Set<int>()*/ set1);
-  print(/*Set<int>()*/ set2);
-  print(/*Set<int>(Int(42))*/ set3);
-  print(/*Set<int>(Int(42),Int(87))*/ set4);
+  print(
+      /*cfe|analyzer|dart2js.Set<int>()*/ /*dart2js:nnbd-sdk.Set<int*>()*/ set1);
+  print(
+      /*cfe|analyzer|dart2js.Set<int>()*/ /*dart2js:nnbd-sdk.Set<int*>()*/ set2);
+  print(
+      /*cfe|analyzer|dart2js.Set<int>(Int(42))*/ /*dart2js:nnbd-sdk.Set<int*>(Int(42))*/ set3);
+  print(
+      /*cfe|analyzer|dart2js.Set<int>(Int(42),Int(87))*/ /*dart2js:nnbd-sdk.Set<int*>(Int(42),Int(87))*/ set4);
 }
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart b/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart
index f729673..49a9d8f 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart
@@ -22,27 +22,27 @@
 main() {
   print(
       /*cfe|analyzer.TypeLiteral(dynamic Function())*/
-      /*dart2js.TypeLiteral(()->dynamic)*/
+      /*dart2js|dart2js:nnbd-sdk.TypeLiteral(()->dynamic)*/
       typedef);
 
   print(
       /*cfe|analyzer.TypeLiteral(void Function(dynamic))*/
-      /*dart2js.TypeLiteral((dynamic)->void)*/
+      /*dart2js|dart2js:nnbd-sdk.TypeLiteral((dynamic)->void)*/
       genericTypedef);
 
   print(
       /*cfe|analyzer.TypeLiteral(void Function<T>(T))*/
-      /*dart2js.TypeLiteral((0)->void)*/
+      /*dart2js|dart2js:nnbd-sdk.TypeLiteral((0)->void)*/
       genericFunctionTypedef);
 
   print(
       /*cfe|analyzer.TypeLiteral(void Function<T>(FutureOr<T>))*/
-      /*dart2js.TypeLiteral((FutureOr<0>)->void)*/
+      /*dart2js|dart2js:nnbd-sdk.TypeLiteral((FutureOr<0>)->void)*/
       typedefWithFutureOr);
 
   print(
       /*cfe|analyzer.TypeLiteral(FutureOr<dynamic>)*/
-      /*dart2js.TypeLiteral(dynamic)*/
+      /*dart2js|dart2js:nnbd-sdk.TypeLiteral(dynamic)*/
       futureOr);
 
   print(
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/assignment.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/assignment.dart
index f4f7394..2d2050f 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/assignment.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/assignment.dart
@@ -41,6 +41,6 @@
 questionEq_rhs_not_guaranteed_to_execute() {
   late int v;
   int? i;
-  /*cfe.unassigned*/ i ??= (v = 0);
+  /*unassigned*/ i ??= (v = 0);
   /*unassigned*/ v;
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/issue41284.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/issue41284.dart
new file mode 100644
index 0000000..95c0e7d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/data/issue41284.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void method1() {
+  var local;
+  try {
+    local = 0;
+    return;
+  } finally {
+    print(/*unassigned*/ local);
+  }
+  local;
+}
+
+void method2() {
+  var local;
+  try {
+    local = 0;
+    return;
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    print(/*unassigned*/ local);
+  }
+  local;
+}
+
+void method3() {
+  var local;
+  try {
+    local = 0;
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    print(/*unassigned*/ local);
+  }
+  local;
+}
+
+void method4() {
+  var local;
+  try {
+    print(/*unassigned*/ local);
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    local = 0;
+  }
+  local;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/issue41284.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/issue41284.dart
new file mode 100644
index 0000000..59f4591
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/issue41284.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void method1() {
+  var local;
+  try {
+    local = 0;
+    return;
+  } finally {
+    print(/*unassigned*/ local);
+  }
+  local;
+}
+
+void method2() {
+  var local;
+  try {
+    local = 0;
+    return;
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    print(/*unassigned*/ local);
+  }
+  local;
+}
+
+void method3() {
+  var local;
+  try {
+    local = 0;
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    print(local);
+  }
+  local;
+}
+
+void method4() {
+  var local;
+  try {
+    print(/*unassigned*/ local);
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    local = 0;
+  }
+  local;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/labeled_statement.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/labeled_statement.dart
new file mode 100644
index 0000000..3417f11
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/labeled_statement.dart
@@ -0,0 +1,42 @@
+// 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.
+
+block_break(bool c) {
+  late int v;
+  label:
+  {
+    if (c) {
+      break label;
+    }
+    v = 0;
+    return;
+  }
+  /*unassigned*/ v;
+}
+
+if_break(bool c) {
+  late int v;
+  label:
+  if (c) {
+    if (c) {
+      break label;
+    }
+    v = 0;
+    return;
+  }
+  /*unassigned*/ v;
+}
+
+try_break(bool c) {
+  late int v;
+  label:
+  try {
+    if (c) {
+      break label;
+    }
+    v = 0;
+    return;
+  } finally {}
+  /*unassigned*/ v;
+}
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 f28c2e9..b03b714 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
@@ -789,10 +789,14 @@
       });
     });
 
-    void _checkIs(String declaredType, String tryPromoteType,
-        String expectedPromotedType) {
+    void _checkIs(
+      String declaredType,
+      String tryPromoteType,
+      String expectedPromotedTypeThen,
+      String expectedPromotedTypeElse,
+    ) {
       var h = _Harness();
-      var x = h.addVar('x', 'int?');
+      var x = h.addVar('x', declaredType);
       h.run((flow) {
         h.declare(x, initialized: true);
         var read = _Expression();
@@ -800,27 +804,31 @@
         var expr = _Expression();
         flow.isExpression_end(expr, read, false, _Type(tryPromoteType));
         flow.ifStatement_thenBegin(expr);
-        if (expectedPromotedType == null) {
+        if (expectedPromotedTypeThen == null) {
           expect(flow.promotedType(x), isNull);
         } else {
-          expect(flow.promotedType(x).type, expectedPromotedType);
+          expect(flow.promotedType(x).type, expectedPromotedTypeThen);
         }
         flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
+        if (expectedPromotedTypeElse == null) {
+          expect(flow.promotedType(x), isNull);
+        } else {
+          expect(flow.promotedType(x).type, expectedPromotedTypeElse);
+        }
         flow.ifStatement_end(true);
       });
     }
 
     test('isExpression_end promotes to a subtype', () {
-      _checkIs('int?', 'int', 'int');
+      _checkIs('int?', 'int', 'int', 'Never?');
     });
 
     test('isExpression_end does not promote to a supertype', () {
-      _checkIs('int', 'int?', null);
+      _checkIs('int', 'int?', null, 'Never');
     });
 
     test('isExpression_end does not promote to an unrelated type', () {
-      _checkIs('int', 'String', null);
+      _checkIs('int', 'String', null, null);
     });
 
     test('isExpression_end() does not promote write-captured vars', () {
@@ -856,6 +864,41 @@
       });
     });
 
+    test('labeledBlock without break', () {
+      var h = _Harness();
+      var x = h.addVar('x', 'int?');
+      var block = _Statement();
+      h.run((flow) {
+        h.declare(x, initialized: true);
+
+        h.ifIsNotType(x, 'int', () {
+          h.labeledBlock(block, () {
+            flow.handleExit();
+          });
+        });
+        expect(flow.promotedType(x).type, 'int');
+      });
+    });
+
+    test('labeledBlock with break joins', () {
+      var h = _Harness();
+      var x = h.addVar('x', 'int?');
+      var block = _Statement();
+      h.run((flow) {
+        h.declare(x, initialized: true);
+
+        h.ifIsNotType(x, 'int', () {
+          h.labeledBlock(block, () {
+            h.if_(h.expr, () {
+              flow.handleBreak(block);
+            });
+            flow.handleExit();
+          });
+        });
+        expect(flow.promotedType(x), isNull);
+      });
+    });
+
     test('logicalBinaryOp_rightBegin(isAnd: true) promotes in RHS', () {
       var h = _Harness();
       var x = h.addVar('x', 'int?');
@@ -1713,32 +1756,32 @@
       });
     });
 
-    group('promote', () {
+    group('tryPromoteForTypeCheck', () {
       test('unpromoted -> unchanged (same)', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.tryPromote(h, intVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('int')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (supertype)', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.tryPromote(h, intVar, _Type('Object')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('Object')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (unrelated)', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.tryPromote(h, intVar, _Type('String')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('String')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> subtype', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.tryPromote(h, intQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, intQVar, _Type('int')).ifTrue;
         expect(s2.reachable, true);
         expect(s2.variableInfo, {
           intQVar: _matchVariableModel(chain: ['int'], ofInterest: ['int'])
@@ -1748,36 +1791,38 @@
       test('promoted -> unchanged (same)', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
-        var s2 = s1.tryPromote(h, objectQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (supertype)', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
-        var s2 = s1.tryPromote(h, objectQVar, _Type('Object')).ifTrue;
+        var s2 =
+            s1.tryPromoteForTypeCheck(h, objectQVar, _Type('Object')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (unrelated)', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
-        var s2 = s1.tryPromote(h, objectQVar, _Type('String')).ifTrue;
+        var s2 =
+            s1.tryPromoteForTypeCheck(h, objectQVar, _Type('String')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> subtype', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int?'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
             .ifTrue;
-        var s2 = s1.tryPromote(h, objectQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
         expect(s2.reachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -1799,9 +1844,7 @@
 
       test('unchanged', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h);
+        var s1 = FlowModel<_Var, _Type>(true).declare(objectQVar, true);
         var s2 = s1.write(objectQVar, _Type('Object?'), h);
         expect(s2, same(s1));
       });
@@ -1823,9 +1866,8 @@
       test('un-promotes fully', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
         expect(s1.variableInfo, contains(objectQVar));
         var s2 = s1.write(objectQVar, _Type('int?'), h);
@@ -1842,11 +1884,10 @@
       test('un-promotes partially, when no exact match', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
             .ifTrue
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -1859,7 +1900,7 @@
         expect(s2.reachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
-              chain: ['num?'],
+              chain: ['num?', 'num'],
               ofInterest: ['num?', 'int'],
               assigned: true,
               unassigned: false)
@@ -1869,13 +1910,12 @@
       test('un-promotes partially, when exact match', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
             .ifTrue
-            .tryPromote(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
             .ifTrue
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -1898,11 +1938,10 @@
       test('leaves promoted, when exact match', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
             .ifTrue
-            .tryPromote(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -1919,11 +1958,10 @@
       test('leaves promoted, when writing a subtype', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
             .ifTrue
-            .tryPromote(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -1937,124 +1975,339 @@
         expect(s2.variableInfo, same(s1.variableInfo));
       });
 
+      group('Promotes to NonNull of a type of interest', () {
+        test('when declared type', () {
+          var h = _Harness();
+          var x = _Var('x', _Type('int?'));
+
+          var s1 = FlowModel<_Var, _Type>(true).declare(x, true);
+          expect(s1.variableInfo, {
+            x: _matchVariableModel(chain: null),
+          });
+
+          var s2 = s1.write(x, _Type('int'), h);
+          expect(s2.variableInfo, {
+            x: _matchVariableModel(chain: ['int']),
+          });
+        });
+
+        test('when declared type, if write-captured', () {
+          var h = _Harness();
+          var x = h.addVar('x', 'int?');
+
+          var s1 = FlowModel<_Var, _Type>(true).declare(x, true);
+          expect(s1.variableInfo, {
+            x: _matchVariableModel(chain: null),
+          });
+
+          var s2 = s1.removePromotedAll([], [x]);
+          expect(s2.variableInfo, {
+            x: _matchVariableModel(chain: null, writeCaptured: true),
+          });
+
+          // 'x' is write-captured, so not promoted
+          var s3 = s2.write(x, _Type('int'), h);
+          expect(s3.variableInfo, {
+            x: _matchVariableModel(chain: null, writeCaptured: true),
+          });
+        });
+
+        test('when promoted', () {
+          var h = _Harness();
+          var s1 = FlowModel<_Var, _Type>(true)
+              .declare(objectQVar, true)
+              .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+              .ifTrue;
+          expect(s1.variableInfo, {
+            objectQVar: _matchVariableModel(
+              chain: ['int?'],
+              ofInterest: ['int?'],
+            ),
+          });
+          var s2 = s1.write(objectQVar, _Type('int'), h);
+          expect(s2.variableInfo, {
+            objectQVar: _matchVariableModel(
+              chain: ['int?', 'int'],
+              ofInterest: ['int?'],
+            ),
+          });
+        });
+
+        test('when not promoted', () {
+          var h = _Harness();
+          var s1 = FlowModel<_Var, _Type>(true)
+              .declare(objectQVar, true)
+              .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+              .ifFalse;
+          expect(s1.variableInfo, {
+            objectQVar: _matchVariableModel(
+              chain: ['Object'],
+              ofInterest: ['int?'],
+            ),
+          });
+          var s2 = s1.write(objectQVar, _Type('int'), h);
+          expect(s2.variableInfo, {
+            objectQVar: _matchVariableModel(
+              chain: ['Object', 'int'],
+              ofInterest: ['int?'],
+            ),
+          });
+        });
+      });
+
       test('Promotes to type of interest when not previously promoted', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
             .ifFalse;
         expect(s1.variableInfo, {
-          objectQVar: _matchVariableModel(chain: null, ofInterest: ['num?'])
+          objectQVar: _matchVariableModel(
+            chain: ['Object'],
+            ofInterest: ['num?'],
+          ),
         });
         var s2 = s1.write(objectQVar, _Type('num?'), h);
         expect(s2.variableInfo, {
-          objectQVar: _matchVariableModel(chain: ['num?'], ofInterest: ['num?'])
+          objectQVar: _matchVariableModel(
+            chain: ['num?'],
+            ofInterest: ['num?'],
+          ),
         });
       });
 
       test('Promotes to type of interest when previously promoted', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
+            .declare(objectQVar, true)
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
             .ifTrue
-            .tryPromote(h, objectQVar, _Type('int?'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
             .ifFalse;
         expect(s1.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: ['num?'], ofInterest: ['num?', 'int?'])
+          objectQVar: _matchVariableModel(
+            chain: ['num?', 'num'],
+            ofInterest: ['num?', 'int?'],
+          ),
         });
         var s2 = s1.write(objectQVar, _Type('int?'), h);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
-              chain: ['num?', 'int?'], ofInterest: ['num?', 'int?'])
+            chain: ['num?', 'int?'],
+            ofInterest: ['num?', 'int?'],
+          ),
         });
       });
 
-      test('Multiple candidate types of interest; choose most specific (first)',
-          () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('int?'))
-            .ifFalse
-            .tryPromote(h, objectQVar, _Type('num?'))
-            .ifFalse;
-        expect(s1.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: null, ofInterest: ['num?', 'int?'])
+      group('Multiple candidate types of interest', () {
+        group('; choose most specific', () {
+          _Harness h;
+
+          setUp(() {
+            h = _Harness();
+
+            // class A {}
+            // class B extends A {}
+            // class C extends B {}
+            h.addSubtype(_Type('Object'), _Type('A'), false);
+            h.addSubtype(_Type('Object'), _Type('A?'), false);
+            h.addSubtype(_Type('Object'), _Type('B?'), false);
+            h.addSubtype(_Type('A'), _Type('Object'), true);
+            h.addSubtype(_Type('A'), _Type('Object?'), true);
+            h.addSubtype(_Type('A'), _Type('A?'), true);
+            h.addSubtype(_Type('A'), _Type('B'), false);
+            h.addSubtype(_Type('A'), _Type('B?'), false);
+            h.addSubtype(_Type('A?'), _Type('Object'), false);
+            h.addSubtype(_Type('A?'), _Type('Object?'), true);
+            h.addSubtype(_Type('A?'), _Type('A'), false);
+            h.addSubtype(_Type('A?'), _Type('B?'), false);
+            h.addSubtype(_Type('B'), _Type('Object'), true);
+            h.addSubtype(_Type('B'), _Type('A'), true);
+            h.addSubtype(_Type('B'), _Type('A?'), true);
+            h.addSubtype(_Type('B'), _Type('B?'), true);
+            h.addSubtype(_Type('B?'), _Type('Object'), false);
+            h.addSubtype(_Type('B?'), _Type('Object?'), true);
+            h.addSubtype(_Type('B?'), _Type('A'), false);
+            h.addSubtype(_Type('B?'), _Type('A?'), true);
+            h.addSubtype(_Type('B?'), _Type('B'), false);
+            h.addSubtype(_Type('C'), _Type('Object'), true);
+            h.addSubtype(_Type('C'), _Type('A'), true);
+            h.addSubtype(_Type('C'), _Type('A?'), true);
+            h.addSubtype(_Type('C'), _Type('B'), true);
+            h.addSubtype(_Type('C'), _Type('B?'), true);
+
+            h.addFactor(_Type('Object'), _Type('A?'), _Type('Object'));
+            h.addFactor(_Type('Object'), _Type('B?'), _Type('Object'));
+            h.addFactor(_Type('Object?'), _Type('A'), _Type('Object?'));
+            h.addFactor(_Type('Object?'), _Type('A?'), _Type('Object'));
+            h.addFactor(_Type('Object?'), _Type('B?'), _Type('Object'));
+          });
+
+          test('; first', () {
+            var x = _Var('x', _Type('Object?'));
+
+            var s1 = FlowModel<_Var, _Type>(true)
+                .declare(x, true)
+                .tryPromoteForTypeCheck(h, x, _Type('B?'))
+                .ifFalse
+                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .ifFalse;
+            expect(s1.variableInfo, {
+              x: _matchVariableModel(
+                chain: ['Object'],
+                ofInterest: ['A?', 'B?'],
+              ),
+            });
+
+            var s2 = s1.write(x, _Type('C'), h);
+            expect(s2.variableInfo, {
+              x: _matchVariableModel(
+                chain: ['Object', 'B'],
+                ofInterest: ['A?', 'B?'],
+              ),
+            });
+          });
+
+          test('; second', () {
+            var x = _Var('x', _Type('Object?'));
+
+            var s1 = FlowModel<_Var, _Type>(true)
+                .declare(x, true)
+                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .ifFalse
+                .tryPromoteForTypeCheck(h, x, _Type('B?'))
+                .ifFalse;
+            expect(s1.variableInfo, {
+              x: _matchVariableModel(
+                chain: ['Object'],
+                ofInterest: ['A?', 'B?'],
+              ),
+            });
+
+            var s2 = s1.write(x, _Type('C'), h);
+            expect(s2.variableInfo, {
+              x: _matchVariableModel(
+                chain: ['Object', 'B'],
+                ofInterest: ['A?', 'B?'],
+              ),
+            });
+          });
+
+          test('; nullable and non-nullable', () {
+            var x = _Var('x', _Type('Object?'));
+
+            var s1 = FlowModel<_Var, _Type>(true)
+                .declare(x, true)
+                .tryPromoteForTypeCheck(h, x, _Type('A'))
+                .ifFalse
+                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .ifFalse;
+            expect(s1.variableInfo, {
+              x: _matchVariableModel(
+                chain: ['Object'],
+                ofInterest: ['A', 'A?'],
+              ),
+            });
+
+            var s2 = s1.write(x, _Type('B'), h);
+            expect(s2.variableInfo, {
+              x: _matchVariableModel(
+                chain: ['Object', 'A'],
+                ofInterest: ['A', 'A?'],
+              ),
+            });
+          });
         });
-        var s2 = s1.write(objectQVar, _Type('int'), h);
+
+        group('; ambiguous', () {
+          test('; no promotion', () {
+            var h = _Harness();
+            var s1 = FlowModel<_Var, _Type>(true)
+                .declare(objectQVar, true)
+                .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+                .ifFalse
+                .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+                .ifFalse;
+            expect(s1.variableInfo, {
+              objectQVar: _matchVariableModel(
+                chain: ['Object'],
+                ofInterest: ['num?', 'num*'],
+              ),
+            });
+            var s2 = s1.write(objectQVar, _Type('int'), h);
+            // It's ambiguous whether to promote to num? or num*, so we don't
+            // promote.
+            expect(s2, same(s1));
+          });
+        });
+
+        test('exact match', () {
+          var h = _Harness();
+          var s1 = FlowModel<_Var, _Type>(true)
+              .declare(objectQVar, true)
+              .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+              .ifFalse
+              .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+              .ifFalse;
+          expect(s1.variableInfo, {
+            objectQVar: _matchVariableModel(
+              chain: ['Object'],
+              ofInterest: ['num?', 'num*'],
+            ),
+          });
+          var s2 = s1.write(objectQVar, _Type('num?'), h);
+          // It's ambiguous whether to promote to num? or num*, but since the
+          // written type is exactly num?, we use that.
+          expect(s2.variableInfo, {
+            objectQVar: _matchVariableModel(
+              chain: ['num?'],
+              ofInterest: ['num?', 'num*'],
+            ),
+          });
+        });
+      });
+
+      test('promote via initialization', () {
+        var h = _Harness();
+        var x = _Var('x', null, isLocalVariableWithoutDeclaredType: true);
+
+        var s1 = FlowModel<_Var, _Type>(true).declare(x, false);
+        expect(s1.variableInfo, {
+          x: _matchVariableModel(chain: null),
+        });
+
+        var s2 = s1.write(x, _Type('int'), h);
         expect(s2.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: ['int?'], ofInterest: ['num?', 'int?'])
+          x: _matchVariableModel(chain: ['int']),
         });
       });
+    });
 
-      test(
-          'Multiple candidate types of interest; choose most specific (second)',
-          () {
+    group('demotion, to NonNull', () {
+      test('when promoted via test', () {
+        var x = _Var('x', _Type('Object?'));
+
         var h = _Harness();
+
         var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
-            .ifFalse
-            .tryPromote(h, objectQVar, _Type('int?'))
-            .ifFalse;
+            .declare(x, true)
+            .tryPromoteForTypeCheck(h, x, _Type('num?'))
+            .ifTrue
+            .tryPromoteForTypeCheck(h, x, _Type('int?'))
+            .ifTrue;
         expect(s1.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: null, ofInterest: ['num?', 'int?'])
+          x: _matchVariableModel(
+            chain: ['num?', 'int?'],
+            ofInterest: ['num?', 'int?'],
+          ),
         });
-        var s2 = s1.write(objectQVar, _Type('int'), h);
+
+        var s2 = s1.write(x, _Type('double'), h);
         expect(s2.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: ['int?'], ofInterest: ['num?', 'int?'])
-        });
-      });
-
-      test('Multiple candidate types of interest; ambiguous', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
-            .ifFalse
-            .tryPromote(h, objectQVar, _Type('num*'))
-            .ifFalse;
-        expect(s1.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: null, ofInterest: ['num?', 'num*'])
-        });
-        var s2 = s1.write(objectQVar, _Type('int'), h);
-        // It's ambiguous whether to promote to num? or num*, so we don't
-        // promote.
-        expect(s2, same(s1));
-      });
-
-      test('Multiple candidate types of interest; ambiguous but exact match',
-          () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .declare(objectQVar, false)
-            .write(objectQVar, _Type('Object?'), h)
-            .tryPromote(h, objectQVar, _Type('num?'))
-            .ifFalse
-            .tryPromote(h, objectQVar, _Type('num*'))
-            .ifFalse;
-        expect(s1.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: null, ofInterest: ['num?', 'num*'])
-        });
-        var s2 = s1.write(objectQVar, _Type('num?'), h);
-        // It's ambiguous whether to promote to num? or num*, but since the
-        // written type is exactly num?, we use that.
-        expect(s2.variableInfo, {
-          objectQVar:
-              _matchVariableModel(chain: ['num?'], ofInterest: ['num?', 'num*'])
+          x: _matchVariableModel(
+            chain: ['num?', 'num'],
+            ofInterest: ['num?', 'int?'],
+          ),
         });
       });
     });
@@ -2091,13 +2344,13 @@
         var s2 = s1.tryMarkNonNullable(h, intQVar).ifTrue;
         expect(s2.reachable, true);
         expect(s2.infoFor(intQVar),
-            _matchVariableModel(chain: ['int'], ofInterest: ['int']));
+            _matchVariableModel(chain: ['int'], ofInterest: []));
       });
 
       test('promoted -> unchanged', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
         var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
         expect(s2, same(s1));
@@ -2106,13 +2359,13 @@
       test('promoted -> re-promoted', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int?'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
             .ifTrue;
         var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
         expect(s2.reachable, true);
         expect(s2.variableInfo, {
-          objectQVar: _matchVariableModel(
-              chain: ['int?', 'int'], ofInterest: ['int?', 'int'])
+          objectQVar:
+              _matchVariableModel(chain: ['int?', 'int'], ofInterest: ['int?'])
         });
       });
     });
@@ -2230,7 +2483,7 @@
       test('unchanged', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue;
         var s2 = s1.removePromotedAll([intQVar], []);
         expect(s2, same(s1));
@@ -2239,9 +2492,9 @@
       test('written', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue
-            .tryPromote(h, intQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
             .ifTrue;
         var s2 = s1.removePromotedAll([intQVar], []);
         expect(s2.reachable, true);
@@ -2254,9 +2507,9 @@
       test('write captured', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .tryPromote(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
             .ifTrue
-            .tryPromote(h, intQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
             .ifTrue;
         var s2 = s1.removePromotedAll([], [intQVar]);
         expect(s2.reachable, true);
@@ -2337,15 +2590,13 @@
             List<String> expectedChain) {
           var h = _Harness();
           var x = _Var('x', _Type('Object?'));
-          var s0 = FlowModel<_Var, _Type>(true)
-              .declare(x, false)
-              .write(x, _Type('Object?'), h);
+          var s0 = FlowModel<_Var, _Type>(true).declare(x, true);
           var s1 = thisType == null
               ? s0
-              : s0.tryPromote(h, x, _Type(thisType)).ifTrue;
+              : s0.tryPromoteForTypeCheck(h, x, _Type(thisType)).ifTrue;
           var s2 = otherType == null
               ? s0
-              : s0.tryPromote(h, x, _Type(otherType)).ifTrue;
+              : s0.tryPromoteForTypeCheck(h, x, _Type(otherType)).ifTrue;
           var result = s1.restrict(h, s2, unsafe ? [x].toSet() : Set());
           if (expectedChain == null) {
             expect(result.variableInfo, contains(x));
@@ -2391,22 +2642,22 @@
             List<String> inFinally, List<String> expectedResult) {
           var h = _Harness();
           var x = _Var('x', _Type('Object?'));
-          var initialModel = FlowModel<_Var, _Type>(true)
-              .declare(x, false)
-              .write(x, _Type('Object?'), h);
+          var initialModel = FlowModel<_Var, _Type>(true).declare(x, true);
           for (var t in before) {
-            initialModel = initialModel.tryPromote(h, x, _Type(t)).ifTrue;
+            initialModel =
+                initialModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
           }
           _checkChain(initialModel.infoFor(x).promotedTypes, before);
           var tryModel = initialModel;
           for (var t in inTry) {
-            tryModel = tryModel.tryPromote(h, x, _Type(t)).ifTrue;
+            tryModel = tryModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
           }
           var expectedTryChain = before.toList()..addAll(inTry);
           _checkChain(tryModel.infoFor(x).promotedTypes, expectedTryChain);
           var finallyModel = initialModel;
           for (var t in inFinally) {
-            finallyModel = finallyModel.tryPromote(h, x, _Type(t)).ifTrue;
+            finallyModel =
+                finallyModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
           }
           var expectedFinallyChain = before.toList()..addAll(inFinally);
           _checkChain(
@@ -2445,7 +2696,7 @@
         var h = _Harness();
         var x = _Var('x', _Type('Object?'));
         var s0 = FlowModel<_Var, _Type>(true);
-        var s1 = s0.declare(x, false).write(x, _Type('Object?'), h);
+        var s1 = s0.declare(x, true);
         expect(s0.restrict(h, s1, {}), same(s0));
         expect(s0.restrict(h, s1, {x}), same(s0));
         expect(s1.restrict(h, s0, {}), same(s0));
@@ -2622,12 +2873,17 @@
     var intType = _Type('int');
     var intQType = _Type('int?');
     var stringType = _Type('String');
-    const emptyMap = <Null, VariableModel<Null>>{};
+    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
 
-    VariableModel<_Type> model(List<_Type> promotionChain,
-            [List<_Type> typesOfInterest]) =>
-        VariableModel<_Type>(promotionChain,
-            typesOfInterest ?? promotionChain ?? [], false, true, false);
+    VariableModel<_Var, _Type> model(List<_Type> promotionChain,
+            {List<_Type> typesOfInterest, bool assigned = false}) =>
+        VariableModel<_Var, _Type>(
+          promotionChain,
+          typesOfInterest ?? promotionChain ?? [],
+          assigned,
+          !assigned,
+          false,
+        );
 
     group('without input reuse', () {
       test('promoted with unpromoted', () {
@@ -2640,7 +2896,7 @@
           x: model(null),
           y: model([intType])
         };
-        expect(FlowModel.joinVariableInfo(h, p1, p2), {
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), {
           x: _matchVariableModel(chain: null, ofInterest: ['int']),
           y: _matchVariableModel(chain: null, ofInterest: ['int'])
         });
@@ -2653,7 +2909,7 @@
           x: model([intType]),
           y: model([stringType])
         };
-        expect(FlowModel.joinVariableInfo(h, p, p), same(p));
+        expect(FlowModel.joinVariableInfo(h, p, p, emptyMap), same(p));
       });
 
       test('one input empty', () {
@@ -2662,9 +2918,9 @@
           x: model([intType]),
           y: model([stringType])
         };
-        var p2 = <_Var, VariableModel<_Type>>{};
-        expect(FlowModel.joinVariableInfo(h, p1, p2), same(emptyMap));
-        expect(FlowModel.joinVariableInfo(h, p2, p1), same(emptyMap));
+        var p2 = <_Var, VariableModel<_Var, _Type>>{};
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(emptyMap));
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(emptyMap));
       });
 
       test('promoted with unpromoted', () {
@@ -2676,8 +2932,8 @@
         var expected = {
           x: _matchVariableModel(chain: null, ofInterest: ['int'])
         };
-        expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
-        expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
       });
 
       test('related type chains', () {
@@ -2691,8 +2947,8 @@
         var expected = {
           x: _matchVariableModel(chain: ['int?'], ofInterest: ['int?', 'int'])
         };
-        expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
-        expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
       });
 
       test('unrelated type chains', () {
@@ -2706,8 +2962,8 @@
         var expected = {
           x: _matchVariableModel(chain: null, ofInterest: ['String', 'int'])
         };
-        expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
-        expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
       });
 
       test('sub-map', () {
@@ -2718,8 +2974,8 @@
           y: model([stringType])
         };
         var p2 = {x: xModel};
-        expect(FlowModel.joinVariableInfo(h, p1, p2), same(p2));
-        expect(FlowModel.joinVariableInfo(h, p2, p1), same(p2));
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(p2));
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(p2));
       });
 
       test('sub-map with matched subtype', () {
@@ -2734,8 +2990,8 @@
         var expected = {
           x: _matchVariableModel(chain: ['int?'], ofInterest: ['int?', 'int'])
         };
-        expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
-        expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
       });
 
       test('sub-map with mismatched subtype', () {
@@ -2750,24 +3006,24 @@
         var expected = {
           x: _matchVariableModel(chain: ['int?'], ofInterest: ['int?', 'int'])
         };
-        expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
-        expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+        expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+        expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
       });
 
       test('assigned', () {
         var h = _Harness();
-        var intQModel = model([intQType]);
-        var writtenModel = intQModel.write(_Type('Object?'), h);
-        var p1 = {x: writtenModel, y: writtenModel, z: intQModel, w: intQModel};
-        var p2 = {x: writtenModel, y: intQModel, z: writtenModel, w: intQModel};
-        var joined = FlowModel.joinVariableInfo(h, p1, p2);
+        var unassigned = model(null, assigned: false);
+        var assigned = model(null, assigned: true);
+        var p1 = {x: assigned, y: assigned, z: unassigned, w: unassigned};
+        var p2 = {x: assigned, y: unassigned, z: assigned, w: unassigned};
+        var joined = FlowModel.joinVariableInfo(h, p1, p2, emptyMap);
         expect(joined, {
-          x: same(writtenModel),
+          x: same(assigned),
           y: _matchVariableModel(
               chain: null, assigned: false, unassigned: false),
           z: _matchVariableModel(
               chain: null, assigned: false, unassigned: false),
-          w: same(intQModel)
+          w: same(unassigned)
         });
       });
 
@@ -2787,7 +3043,7 @@
           z: writeCapturedModel,
           w: intQModel
         };
-        var joined = FlowModel.joinVariableInfo(h, p1, p2);
+        var joined = FlowModel.joinVariableInfo(h, p1, p2, emptyMap);
         expect(joined, {
           x: same(writeCapturedModel),
           y: same(writeCapturedModel),
@@ -2846,7 +3102,7 @@
   Matcher assignedMatcher = wrapMatcher(assigned);
   Matcher unassignedMatcher = wrapMatcher(unassigned);
   Matcher writeCapturedMatcher = wrapMatcher(writeCaptured);
-  return predicate((VariableModel<_Type> model) {
+  return predicate((VariableModel<_Var, _Type> model) {
     if (!chainMatcher.matches(model.promotedTypes, {})) return false;
     if (!ofInterestMatcher.matches(model.tested, {})) return false;
     if (!assignedMatcher.matches(model.assigned, {})) return false;
@@ -2904,7 +3160,11 @@
 
 class _Harness implements TypeOperations<_Var, _Type> {
   static const Map<String, bool> _coreSubtypes = const {
+    'double <: Object': true,
+    'double <: num': true,
+    'double <: num?': true,
     'double <: int': false,
+    'double <: int?': false,
     'int <: double': false,
     'int <: int?': true,
     'int <: Iterable': false,
@@ -2912,23 +3172,30 @@
     '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? <: num': false,
     'int? <: num?': true,
+    'int? <: Object': false,
     'int? <: 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,
@@ -2937,19 +3204,63 @@
     'List <: int': false,
     'List <: Iterable': true,
     'List <: Object': true,
+    'Never <: int': true,
+    'Never <: int?': true,
+    'Never? <: int': false,
+    'Never? <: int?': true,
+    'Never? <: num?': true,
+    'Never? <: Object?': true,
     'Object <: int': false,
+    'Object <: int?': false,
     'Object <: List': false,
     'Object <: num': false,
+    'Object <: num?': false,
     'Object <: Object?': true,
+    'Object? <: Object': false,
     'Object? <: int': false,
     'Object? <: int?': false,
     'String <: int': false,
     'String <: int?': false,
+    'String <: num?': false,
     'String <: Object?': true,
   };
 
+  static final Map<String, _Type> _coreFactors = {
+    'Object? - int': _Type('Object?'),
+    'Object? - int?': _Type('Object'),
+    'Object? - num?': _Type('Object'),
+    'Object? - Object?': _Type('Never?'),
+    'Object? - String': _Type('Object?'),
+    'Object - int': _Type('Object'),
+    'int - Object': _Type('Never'),
+    'int - String': _Type('int'),
+    'int - int': _Type('Never'),
+    'int - int?': _Type('Never'),
+    'int? - int': _Type('Never?'),
+    'int? - int?': _Type('Never'),
+    'int? - String': _Type('int?'),
+    'num - int': _Type('num'),
+    'num? - num': _Type('Never?'),
+    'num? - int': _Type('num?'),
+    'num? - int?': _Type('num'),
+    'num? - Object': _Type('Never?'),
+    'num? - String': _Type('num?'),
+    'Object - int?': _Type('Object'),
+    'Object - num': _Type('Object'),
+    'Object - num?': _Type('Object'),
+    'Object - num*': _Type('Object'),
+    'Object - Iterable': _Type('Object'),
+    'Object? - Object': _Type('Never?'),
+    'Object? - Iterable': _Type('Object?'),
+    'Object? - num': _Type('Object?'),
+    'Iterable - List': _Type('Iterable'),
+    'num* - Object': _Type('Never'),
+  };
+
   final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
 
+  final Map<String, _Type> _factorResults = Map.of(_coreFactors);
+
   FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> _flow;
 
   final _assignedVariables = AssignedVariables<_Node, _Var>();
@@ -2964,6 +3275,11 @@
         return expr;
       };
 
+  void addFactor(_Type from, _Type what, _Type result) {
+    var query = '$from - $what';
+    _factorResults[query] = result;
+  }
+
   void addSubtype(_Type leftType, _Type rightType, bool isSubtype) {
     var query = '$leftType <: $rightType';
     _subtypes[query] = isSubtype;
@@ -3025,6 +3341,12 @@
     };
   }
 
+  @override
+  _Type factor(_Type from, _Type what) {
+    var query = '$from - $what';
+    return _factorResults[query] ?? fail('Unknown factor query: $query');
+  }
+
   /// Invokes flow analysis of a nested function.
   void function(_Node node, void body()) {
     _flow.functionExpression_begin(node);
@@ -3048,6 +3370,16 @@
     _flow.ifStatement_end(true);
   }
 
+  /// Equivalent for `if (variable is! type) { ifTrue; }`
+  void ifIsNotType(_Var variable, String type, void ifTrue()) {
+    if_(isNotType(variableRead(variable), type), ifTrue);
+  }
+
+  @override
+  bool isLocalVariableWithoutDeclaredType(_Var variable) {
+    return variable.isLocalVariableWithoutDeclaredType;
+  }
+
   /// Creates a [LazyExpression] representing an `is!` check, checking whether
   /// [subExpression] has the given [type].
   LazyExpression isNotType(LazyExpression subExpression, String type) {
@@ -3080,6 +3412,13 @@
     };
   }
 
+  /// Invokes flow analysis of a labeled block.
+  void labeledBlock(_Statement node, void body()) {
+    _flow.labeledStatement_begin(node);
+    body();
+    _flow.labeledStatement_end();
+  }
+
   /// Creates a [LazyExpression] representing an equality check between two
   /// other expressions.
   LazyExpression notEqual(LazyExpression lhs, LazyExpression rhs) {
@@ -3128,7 +3467,7 @@
 
   /// Causes [variable] to be promoted to [type].
   void promote(_Var variable, String type) {
-    if_(isNotType(variableRead(variable), type), _flow.handleExit);
+    ifIsNotType(variable, type, _flow.handleExit);
   }
 
   @override
@@ -3194,10 +3533,14 @@
 
 class _Var {
   final String name;
-
   final _Type type;
+  final bool isLocalVariableWithoutDeclaredType;
 
-  _Var(this.name, this.type);
+  _Var(
+    this.name,
+    this.type, {
+    this.isLocalVariableWithoutDeclaredType = false,
+  });
 
   @override
   String toString() => '$type $name';
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/labeled_statement.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/labeled_statement.dart
new file mode 100644
index 0000000..a8faf57
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/labeled_statement.dart
@@ -0,0 +1,42 @@
+// 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.
+
+block_break(int? x, bool c) {
+  label:
+  {
+    if (x == null) {
+      if (c) {
+        break label;
+      }
+      return;
+    }
+  }
+  x;
+}
+
+if_break(int? x, bool c) {
+  label:
+  if (true) {
+    if (x == null) {
+      if (c) {
+        break label;
+      }
+      return;
+    }
+  }
+  x;
+}
+
+try_break(int? x, bool c) {
+  label:
+  try {
+    if (x == null) {
+      if (c) {
+        break label;
+      }
+      return;
+    }
+  } finally {}
+  x;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/issue41284.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/issue41284.dart
new file mode 100644
index 0000000..1a13beb
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/issue41284.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*member: method1:doesNotComplete*/
+void method1() {
+  var local;
+  try {
+    local = 0;
+    return;
+  } finally {
+    print(local);
+  }
+  /*stmt: unreachable*/ local;
+}
+
+/*member: method2:doesNotComplete*/
+void method2() {
+  var local;
+  try {
+    local = 0;
+    return;
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    print(local);
+  }
+  /*stmt: unreachable*/ local;
+}
+
+void method3() {
+  var local;
+  try {
+    local = 0;
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    print(local);
+  }
+  local;
+}
+
+void method4() {
+  var local;
+  try {
+    print(local);
+  } catch (e) {
+    local = 42;
+    rethrow;
+  } finally {
+    local = 0;
+  }
+  local;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/labeled_statement.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/labeled_statement.dart
new file mode 100644
index 0000000..c5eccbe
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/labeled_statement.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+block_break(bool b) {
+  label:
+  {
+    if (b) {
+      break label;
+    }
+    return;
+  }
+  1;
+}
+
+if_break(bool b) {
+  label:
+  if (true) {
+    if (b) {
+      break label;
+    }
+    return;
+  }
+  1;
+}
+
+try_break(bool b) {
+  label:
+  try {
+    if (b) {
+      break label;
+    }
+    return;
+  } finally {
+    1;
+  }
+  2;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment.dart
index 929536a..83ff29a 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment.dart
@@ -18,6 +18,17 @@
   }
 }
 
+assignmentDepromotes_partial_nonNull(Object? x) {
+  if (x is num?) {
+    /*num?*/ x;
+    if (/*num?*/ x is int?) {
+      /*int?*/ x;
+      x = 1.2;
+      /*num*/ x;
+    }
+  }
+}
+
 assignmentPreservesPromotion(Object x) {
   if (x is num) {
     x = 42;
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment_promoted.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment_promoted.dart
index 051be11..1a1a094 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment_promoted.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/assignment_promoted.dart
@@ -16,6 +16,15 @@
   /*int*/ x;
 }
 
+typeOfInterest_is_nullable(Object? x) {
+  if (x is int?) {
+  } else {
+    x = 1;
+    /*int*/ x;
+  }
+  x;
+}
+
 typeOfInterest_isNot(Object x) {
   if (x is! int) {
     x = 1;
@@ -24,11 +33,24 @@
   /*int*/ x;
 }
 
-notATypeOfInterest_nullability(Object? x) {
-  x = 1;
+typeOfInterest_isNot_nullable(Object? x) {
+  if (x is! int?) {
+    x = 1;
+    /*int*/ x;
+  }
   x;
 }
 
+typeOfInterest_declaredNullable_exact(int? x) {
+  x = 1;
+  /*int*/ x;
+}
+
+typeOfInterest_declaredNullable_subtype(Object? x) {
+  x = 1;
+  /*Object*/ x;
+}
+
 typeOfInterest_notEqualNull(Object? x) {
   if (x != null) {
   } else {
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart
index b71d9fb..9b8e497 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart
@@ -19,3 +19,13 @@
 
 int conditional_in_expression_function_body(Object o) =>
     o is int ? /*int*/ o : 0;
+
+void conditional_factor_Null(int? x) {
+  x is Null ? /*Null*/ x : /*int*/ x;
+  x;
+}
+
+void conditional_factor_nullable(num? x) {
+  x is int? ? /*int?*/ x : /*num*/ x;
+  x;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/declaration.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/declaration.dart
new file mode 100644
index 0000000..099a022
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/declaration.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The tests in this file exercise various kinds of constructs that initialize a
+// variable at its declaration site.  We verify that the variable is not
+// considered "written to" for purposes of defeating type promotions inside
+// closures.
+
+parameter(Object a) {
+  if (a is int) {
+    () {
+      /*int*/ a;
+    };
+  }
+}
+
+localParameter() {
+  localFunction(Object a) {
+    if (a is int) {
+      () {
+        /*int*/ a;
+      };
+    }
+  }
+
+  (Object b) {
+    if (b is int) {
+      () {
+        /*int*/ b;
+      };
+    }
+  };
+}
+
+localVariable() {
+  Object a = 1;
+  if (a is int) {
+    () {
+      /*int*/ a;
+    };
+  }
+}
+
+class MyStackTrace implements StackTrace {
+  noSuchMethod(invocation) => super.noSuchMethod(invocation);
+}
+
+catchParameters() {
+  try {} on Object catch (e, st) {
+    if (e is int) {
+      () {
+        /*int*/ e;
+      };
+    }
+    if (st is MyStackTrace) {
+      () {
+        /*MyStackTrace*/ st;
+      };
+    }
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart
index e150823..de0fa50 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart
@@ -2,6 +2,8 @@
 // for details. 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 A {}
 
 class B extends A {}
@@ -63,6 +65,60 @@
   v;
 }
 
+isType_factor_Null(int? v) {
+  if (v is Null) {
+    /*Null*/ v;
+  } else {
+    /*int*/ v;
+  }
+  v;
+}
+
+isType_factor_nullable(num? v) {
+  if (v is int?) {
+    /*int?*/ v;
+  } else {
+    /*num*/ v;
+  }
+  v;
+}
+
+isType_factor_declaredType(int? v) {
+  if (v is int?) {
+    v;
+  } else {
+    /*Never*/ v;
+  }
+  v;
+}
+
+isType_factor_supertype(int? v) {
+  if (v is num?) {
+    v;
+  } else {
+    /*Never*/ v;
+  }
+  v;
+}
+
+isType_factor_futureOr_future(FutureOr<int> v) {
+  if (v is Future<int>) {
+    /*Future<int>*/ v;
+  } else {
+    /*int*/ v;
+  }
+  v;
+}
+
+isType_factor_futureOr_type(FutureOr<int> v) {
+  if (v is int) {
+    /*int*/ v;
+  } else {
+    /*Future<int>*/ v;
+  }
+  v;
+}
+
 isType_thenNonBoolean(Object x) {
   if ((x is String) != 3) {
     x;
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart
index 099a022..6425744 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart
@@ -1,62 +1,95 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// 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.
 
-// The tests in this file exercise various kinds of constructs that initialize a
-// variable at its declaration site.  We verify that the variable is not
-// considered "written to" for purposes of defeating type promotions inside
-// closures.
-
-parameter(Object a) {
-  if (a is int) {
-    () {
-      /*int*/ a;
-    };
-  }
-}
-
-localParameter() {
-  localFunction(Object a) {
-    if (a is int) {
-      () {
-        /*int*/ a;
-      };
-    }
-  }
-
-  (Object b) {
-    if (b is int) {
-      () {
-        /*int*/ b;
-      };
-    }
-  };
-}
+// The tests in this file exercise "promotable via initialization" part of
+// the flow analysis specification.
 
 localVariable() {
-  Object a = 1;
-  if (a is int) {
-    () {
-      /*int*/ a;
-    };
-  }
+  var x;
+  x = 1;
+  /*int*/ x;
+  x = 2.3;
+  x;
 }
 
-class MyStackTrace implements StackTrace {
-  noSuchMethod(invocation) => super.noSuchMethod(invocation);
+localVariable_hasInitializer(num a) {
+  var x = a;
+  x = 1;
+  x;
 }
 
-catchParameters() {
-  try {} on Object catch (e, st) {
-    if (e is int) {
-      () {
-        /*int*/ e;
-      };
-    }
-    if (st is MyStackTrace) {
-      () {
-        /*MyStackTrace*/ st;
-      };
-    }
+localVariable_hasTypeAnnotation() {
+  num x;
+  x = 1;
+  x;
+}
+
+localVariable_hasTypeAnnotation_dynamic() {
+  dynamic x;
+  x = 1;
+  x;
+}
+
+localVariable_ifElse_differentTypes(bool a) {
+  var x;
+  if (a) {
+    x = 0;
+    /*int*/ x;
+  } else {
+    x = 1.2;
+    /*double*/ x;
   }
+  x;
+}
+
+localVariable_ifElse_sameTypes(bool a) {
+  var x;
+  if (a) {
+    x = 0;
+    /*int*/ x;
+  } else {
+    x = 1;
+    /*int*/ x;
+  }
+  /*int*/ x;
+}
+
+localVariable_notDefinitelyUnassigned(bool a) {
+  var x;
+  if (a) {
+    x = 1.2;
+  }
+  x = 1;
+  x;
+}
+
+localVariable_notDefinitelyUnassigned_hasLocalFunction() {
+  var x;
+
+  void f() {
+    // Note, no assignment to 'x', but because 'x' is assigned somewhere in
+    // the enclosing function, it is not definitely unassigned in 'f'.
+    // So, when we join after 'f' declaration, we make 'x' not definitely
+    // unassigned in the enclosing function as well.
+  }
+
+  f();
+
+  x = 1;
+  x;
+}
+
+parameter(x) {
+  x = 1;
+  x;
+}
+
+parameterLocal() {
+  void f(x) {
+    x = 1;
+    x;
+  }
+
+  f(0);
 }
diff --git a/pkg/_fe_analyzer_shared/test/id_generation_test.dart b/pkg/_fe_analyzer_shared/test/id_generation_test.dart
index 6010ed5..0f19b23 100644
--- a/pkg/_fe_analyzer_shared/test/id_generation_test.dart
+++ b/pkg/_fe_analyzer_shared/test/id_generation_test.dart
@@ -339,7 +339,13 @@
     }
   }, expectedResult: '''
 some code
-/*a.member: memberName:test1=b,test2=[c,d],test3=e*/
+/*a.member: memberName:
+ test1=b,
+ test2=[
+  c,
+  d],
+ test3=e
+*/
 /*b|c.member: memberName:
  test1=a,
  test2=[
@@ -349,6 +355,8 @@
 */
 some more code
 ''');
+  // TODO(johnniwinther): Should new data reuse an existing encoding when that
+  // differs from the pretty printed encoding?
   testFeatures('''
 some code
 /*a.member: memberName:test1=b,test2=[c,d],test3=e*/
@@ -366,7 +374,14 @@
     }
   }, expectedResult: '''
 some code
-/*a|b.member: memberName:test1=b,test2=[c,d],test3=e*/
+/*a.member: memberName:test1=b,test2=[c,d],test3=e*/
+/*b.member: memberName:
+ test1=b,
+ test2=[
+  c,
+  d],
+ test3=e
+*/
 /*c.member: memberName:
  test1=a,
  test2=[
@@ -378,7 +393,52 @@
 ''');
   testFeatures('''
 some code
-/*a|b.member: memberName:test1=b,test2=[c,d],test3=e*/
+/*a.member: memberName:
+ test1=b,
+ test2=[
+  c,
+  d],
+ test3=e
+*/
+/*b|c.member: memberName:
+ test1=a,
+ test2=[
+  b,
+  c],
+ test3=d
+*/
+some more code
+''', actualData: {
+    'b': {
+      new MemberId('memberName'): 'test1=b,test2=[c,d],test3=e',
+    }
+  }, expectedResult: '''
+some code
+/*a|b.member: memberName:
+ test1=b,
+ test2=[
+  c,
+  d],
+ test3=e
+*/
+/*c.member: memberName:
+ test1=a,
+ test2=[
+  b,
+  c],
+ test3=d
+*/
+some more code
+''');
+  testFeatures('''
+some code
+/*a|b.member: memberName:
+ test1=b,
+ test2=[
+  c,
+  d],
+ test3=e
+*/
 /*c.member: memberName:
  test1=a,
  test2=[
@@ -393,7 +453,13 @@
     }
   }, expectedResult: '''
 some code
-/*member: memberName:test1=b,test2=[c,d],test3=e*/
+/*member: memberName:
+ test1=b,
+ test2=[
+  c,
+  d],
+ test3=e
+*/
 some more code
 ''');
 }
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/main.dart
index aae2ae8..cdf272f 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/main.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/main.dart
@@ -17,32 +17,26 @@
   /*member: SubClass2.method:int? Function(int)*/
 }
 
-// TODO: Solve CFE / analyzer difference.
-// This an following examples end up with implementing `GenericInterface`
-// with `int` and `int?` type arguments, and their NNBD_TOP_MERGE does not
-// exist. it does not matter that some of these interfaces come through a
-// legacy library.
-
 /*class: GenericSubClass1a:GenericClass1,GenericInterface<int?>,GenericLegacyClass1a,GenericSubClass1a,Object*/
-/*analyzer.error: CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES*/ abstract class GenericSubClass1a
-    extends GenericLegacyClass1a implements GenericInterface<int?> {
+abstract class GenericSubClass1a extends GenericLegacyClass1a
+    implements GenericInterface<int?> {
   /*member: GenericSubClass1a.method:int? Function(int?)*/
 }
 
 /*class: GenericSubClass1b:GenericClass1,GenericInterface<int?>,GenericLegacyClass1b,GenericSubClass1b,Object*/
-/*analyzer.error: CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES*/ abstract class GenericSubClass1b
-    extends GenericLegacyClass1b implements GenericInterface<int?> {
+abstract class GenericSubClass1b extends GenericLegacyClass1b
+    implements GenericInterface<int?> {
   /*member: GenericSubClass1b.method:int? Function(int?)*/
 }
 
 /*class: GenericSubClass2a:GenericClass2,GenericInterface<int>,GenericLegacyClass2a,GenericSubClass2a,Object*/
-/*analyzer.error: CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES*/ abstract class GenericSubClass2a
-    extends GenericLegacyClass2a implements GenericInterface<int> {
+abstract class GenericSubClass2a extends GenericLegacyClass2a
+    implements GenericInterface<int> {
   /*member: GenericSubClass2a.method:int Function(int)*/
 }
 
 /*class: GenericSubClass2b:GenericClass2,GenericInterface<int>,GenericLegacyClass2b,GenericSubClass2b,Object*/
-/*analyzer.error: CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES*/ abstract class GenericSubClass2b
-    extends GenericLegacyClass2b implements GenericInterface<int> {
+abstract class GenericSubClass2b extends GenericLegacyClass2b
+    implements GenericInterface<int> {
   /*member: GenericSubClass2b.method:int Function(int)*/
 }
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/opt_out.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/opt_out.dart
index 1766444..09cfea2 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/opt_out.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/in_out_in/opt_out.dart
@@ -18,30 +18,24 @@
   /*member: LegacyClass2.method:int* Function(int*)**/
 }
 
-/// TODO: Solve CFE / analyzer difference.
-/// Classes in legacy libraries can only have members with legacy signatures.
 /*class: GenericLegacyClass1a:GenericClass1,GenericInterface<int*>,GenericLegacyClass1a,Object*/
 abstract class GenericLegacyClass1a extends GenericClass1 {
-  /*cfe|cfe:builder.member: GenericLegacyClass1a.method:int* Function(int*)*/
-  /*analyzer.member: GenericLegacyClass1a.method:int* Function(int*)**/
+  /*member: GenericLegacyClass1a.method:int* Function(int*)**/
 }
 
 /*class: GenericLegacyClass1b:GenericClass1,GenericInterface<int*>,GenericLegacyClass1b,Object*/
 abstract class GenericLegacyClass1b extends GenericClass1
     implements GenericInterface<int> {
-  /*cfe|cfe:builder.member: GenericLegacyClass1b.method:int* Function(int*)*/
-  /*analyzer.member: GenericLegacyClass1b.method:int* Function(int*)**/
+  /*member: GenericLegacyClass1b.method:int* Function(int*)**/
 }
 
 /*class: GenericLegacyClass2a:GenericClass2,GenericInterface<int*>,GenericLegacyClass2a,Object*/
 abstract class GenericLegacyClass2a extends GenericClass2 {
-  /*cfe|cfe:builder.member: GenericLegacyClass2a.method:int* Function(int*)*/
-  /*analyzer.member: GenericLegacyClass2a.method:int* Function(int*)**/
+  /*member: GenericLegacyClass2a.method:int* Function(int*)**/
 }
 
 /*class: GenericLegacyClass2b:GenericClass2,GenericInterface<int*>,GenericLegacyClass2b,Object*/
 abstract class GenericLegacyClass2b extends GenericClass2
     implements GenericInterface<int> {
-  /*cfe|cfe:builder.member: GenericLegacyClass2b.method:int* Function(int*)*/
-  /*analyzer.member: GenericLegacyClass2b.method:int* Function(int*)**/
+  /*member: GenericLegacyClass2b.method:int* Function(int*)**/
 }
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart
index 8b854b8..0ee78c7 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart
@@ -56,49 +56,49 @@
 
 /*class: F1:A,C,F1,Object*/
 class F1 extends A implements C {
-  /*member: F1.method:void Function(void, {void named})*/
+  /*member: F1.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: F2:A,C,F2,Object*/
 class F2 extends C implements A {
-  /*member: F2.method:void Function(void, {void named})*/
+  /*member: F2.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: F3:A,C,F3,Object*/
 class F3 implements A, C {
-  /*member: F3.method:void Function(void, {void named})*/
+  /*member: F3.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: F4:A,C,F4,Object*/
 class F4 implements C, A {
-  /*member: F4.method:void Function(void, {void named})*/
+  /*member: F4.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: G1:A,B,C,G1,Object*/
 class G1 extends B implements C {
-  /*member: G1.method:void Function(void, {void named})*/
+  /*member: G1.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: G2:A,B,C,G2,Object*/
 class G2 extends C implements B {
-  /*member: G2.method:void Function(void, {void named})*/
+  /*member: G2.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: G3:A,B,C,G3,Object*/
 class G3 implements B, C {
-  /*member: G3.method:void Function(void, {void named})*/
+  /*member: G3.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
 /*class: G4:A,B,C,G4,Object*/
 class G4 implements C, B {
-  /*member: G4.method:void Function(void, {void named})*/
+  /*member: G4.method:Object? Function(Object?, {Object? named})*/
   method(o, {named}) {}
 }
 
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40414/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40414/main.dart
index c416f58..6446c09 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40414/main.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40414/main.dart
@@ -12,12 +12,9 @@
   /*member: B.i=:int**/
 }
 
-/// TODO: Solve CFE / analyzer difference.
-/// I suspect that this is a bug in analyzer.
-/// We check `i` against separate signatures from `NULLABLE` and `NONNULLABLE`.
 /*class: C:A,C,NONNULLABLE,NULLABLE,Object*/
 class C extends A {
   /*member: C.i:int?*/
   /*member: C.i=:int?*/
-  int? /*analyzer.error: CompileTimeErrorCode.INVALID_OVERRIDE*/ i;
+  int? i;
 }
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart
index 9ef0a47..5b56249 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart
@@ -19,7 +19,7 @@
 /*class: B1:A<Object?>,A_Object,A_dynamic,B1,Object*/
 class B1 extends A_Object implements A_dynamic {}
 
-/*class: B2:A<void>,A_Object,A_void,B2,Object*/
+/*class: B2:A<Object?>,A_Object,A_void,B2,Object*/
 class B2 extends A_Object implements A_void {}
 
 main() {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart
index 4a6f1ad..6468993 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart
@@ -15,7 +15,7 @@
 /*class: B1:A<Object?>,A_Object,A_dynamic,B1,Object*/
 class B1 extends A_Object implements A_dynamic {}
 
-/*class: B2:A<void>,A_Object,A_void,B2,Object*/
+/*class: B2:A<Object?>,A_Object,A_void,B2,Object*/
 class B2 extends A_Object implements A_void {}
 
 main() {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/main.dart
index ff14c36..f05435c 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/main.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/main.dart
@@ -1,4 +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.
+
 /*library: nnbd=true*/
+
 import "opt_out.dart";
 import "dart:async";
 
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/opt_out.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/opt_out.dart
index 787499e..8647b27 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/opt_out.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40553/opt_out.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 // @dart=2.6
 
 /*library: nnbd=false*/
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/norm_supertypes.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/norm_supertypes.dart
index fb47fcd..12f8c82 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/norm_supertypes.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/norm_supertypes.dart
@@ -12,18 +12,19 @@
 /*class: Foo:A<FutureOr<T?>>,Foo<T, S>,Object*/
 class Foo<T extends S, S extends Never> implements A<FutureOr<T?>> {}
 
-/// TODO: Solve CFE / analyzer difference.
-/// It looks to me that is should be `A<FutureOr<Never?>>`, because this is
-/// what is written in the code. We don't do normalization because there is
-/// only one implementation of `A` in `Bar`.
-/*cfe|cfe:builder.class: Bar:A<FutureOr<Never>>,Bar,Object*/
-/*analyzer.class: Bar:A<FutureOr<Never?>>,Bar,Object*/
+/*class: Bar:A<FutureOr<Never?>>,Bar,Object*/
 class Bar implements A<FutureOr<Never?>> {}
 
 /*class: Baz:A<Future<Null>?>,Baz,Object*/
 class Baz implements A<Future<Null>?> {}
 
-/*class: Hest:A<Future<Null>?>,Bar,Foo<Never, Never>,Hest,Object*/
+/// TODO: Solve CFE / analyzer difference.
+/// Instantiation of [Foo] is `Foo<Never, Never>`, so it implements
+/// `A<FutureOr<Never?>>`, and `Bar` implements the same `A<FutureOr<Never?>>`.
+/// So, these two are syntactically equal, so NORM and TOP_MERGE should not
+/// be applied.
+/*cfe|cfe:builder.class: Hest:A<Future<Null>?>,Bar,Foo<Never, Never>,Hest,Object*/
+/*analyzer.class: Hest:A<FutureOr<Never?>>,Bar,Foo<Never, Never>,Hest,Object*/
 class Hest extends Foo implements Bar {}
 
 /*class: Fisk:A<Future<Null>?>,Bar,Baz,Fisk,Object*/
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_direct.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_direct.dart
new file mode 100644
index 0000000..bb1b4ab
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_direct.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: nnbd=true*/
+
+/*class: A:A<T>,Object*/
+class A<T> {
+  /*member: A.member:T Function()*/
+  T member() => throw "Unreachable";
+}
+
+/*class: B:A<T>,B<T>,Object*/
+/*member: B.member:T Function()*/
+class B<T> extends A<T> {}
+
+/*class: D0:A<Object?>,B<Object?>,D0,Object*/
+/*member: D0.member:Object? Function()*/
+class D0 extends A<dynamic> implements B<Object?> {}
+
+/*class: D1:A<Object?>,B<dynamic>,D1,Object*/
+/*member: D1.member:Object? Function()*/
+class D1 extends A<Object?> implements B<dynamic> {}
+
+/*class: D2:A<Object?>,B<Object?>,D2,Object*/
+/*member: D2.member:Object? Function()*/
+class D2 extends A<void> implements B<Object?> {}
+
+/*class: D3:A<Object?>,B<void>,D3,Object*/
+/*member: D3.member:Object? Function()*/
+class D3 extends A<Object?> implements B<void> {}
+
+/*class: D4:A<Object?>,B<dynamic>,D4,Object*/
+/*member: D4.member:Object? Function()*/
+class D4 extends A<void> implements B<dynamic> {}
+
+/*class: D5:A<Object?>,B<void>,D5,Object*/
+/*member: D5.member:Object? Function()*/
+class D5 extends A<dynamic> implements B<void> {}
+
+/*class: D6:A<void>,B<void>,D6,Object*/
+/*member: D6.member:void Function()*/
+class D6 extends A<void> implements B<void> {}
+
+/*class: D7:A<dynamic>,B<dynamic>,D7,Object*/
+/*member: D7.member:dynamic Function()*/
+class D7 extends A<dynamic> implements B<dynamic> {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_mixin.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_mixin.dart
new file mode 100644
index 0000000..597a802
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_mixin.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: nnbd=true*/
+
+/*class: A:A<T>,Object*/
+abstract class A<T> {
+  /*member: A.member:T Function()*/
+  T member();
+}
+
+/*cfe|cfe:builder.class: B:B<T>,Object*/
+/*cfe|cfe:builder.member: B.member:T Function()*/
+mixin B<T> {
+  T member();
+}
+
+/*class: D0:A<dynamic>,B<Object?>,D0,Object*/
+/*member: D0.member:Object? Function()*/
+abstract class D0 extends A<dynamic> with B<Object?> {}
+
+/*class: D1:A<Object?>,B<dynamic>,D1,Object*/
+/*member: D1.member:dynamic Function()*/
+abstract class D1 extends A<Object?> with B<dynamic> {}
+
+/*class: D2:A<void>,B<Object?>,D2,Object*/
+/*member: D2.member:Object? Function()*/
+abstract class D2 extends A<void> with B<Object?> {}
+
+/*class: D3:A<Object?>,B<void>,D3,Object*/
+/*member: D3.member:void Function()*/
+abstract class D3 extends A<Object?> with B<void> {}
+
+/*class: D4:A<void>,B<dynamic>,D4,Object*/
+/*member: D4.member:dynamic Function()*/
+abstract class D4 extends A<void> with B<dynamic> {}
+
+/*class: D5:A<dynamic>,B<void>,D5,Object*/
+/*member: D5.member:void Function()*/
+abstract class D5 extends A<dynamic> with B<void> {}
+
+/*class: D6:A<void>,B<void>,D6,Object*/
+/*member: D6.member:void Function()*/
+abstract class D6 extends A<void> with B<void> {}
+
+/*class: D7:A<dynamic>,B<dynamic>,D7,Object*/
+/*member: D7.member:dynamic Function()*/
+abstract class D7 extends A<dynamic> with B<dynamic> {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart
index d0865e2..3845f87 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart
@@ -32,7 +32,7 @@
 
 /*class: E1:A,B,C,D,E1,Object*/
 abstract class E1 implements A, B, C, D {
-  /*member: E1.method:void Function(void)*/
+  /*member: E1.method:Object? Function(Object?)*/
 }
 
 /*class: E2:A,B,E2,Object*/
@@ -42,12 +42,12 @@
 
 /*class: E3:B,C,E3,Object*/
 abstract class E3 implements B, C {
-  /*member: E3.method:void Function(void)*/
+  /*member: E3.method:Object? Function(Object?)*/
 }
 
 /*class: E4:A,C,E4,Object*/
 abstract class E4 implements A, C {
-  /*member: E4.method:void Function(void)*/
+  /*member: E4.method:Object? Function(Object?)*/
 }
 
 /*class: E5:A,D,E5,Object*/
@@ -68,20 +68,20 @@
 
 /*class: G1:A,C,F,G1,Object*/
 abstract class G1 implements A, C, F {
-  /*member: G1.method:void Function(void)*/
+  /*member: G1.method:Object? Function(Object?)*/
 }
 
 /*class: G2:A,C,F,G2,Object*/
 abstract class G2 implements A, F, C {
-  /*member: G2.method:void Function(void)*/
+  /*member: G2.method:Object? Function(Object?)*/
 }
 
 /*class: G3:A,C,F,G3,Object*/
 abstract class G3 implements C, A, F {
-  /*member: G3.method:void Function(void)*/
+  /*member: G3.method:Object? Function(Object?)*/
 }
 
 /*class: G4:A,C,F,G4,Object*/
 abstract class G4 implements C, F, A {
-  /*member: G4.method:void Function(void)*/
+  /*member: G4.method:Object? Function(Object?)*/
 }
diff --git a/pkg/analysis_server/.gitignore b/pkg/analysis_server/.gitignore
deleted file mode 100644
index ad1fe33..0000000
--- a/pkg/analysis_server/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-lib/src/edit/nnbd_migration/resources/*.js.deps
-lib/src/edit/nnbd_migration/resources/*.js.map
-lib/src/edit/nnbd_migration/resources/migration.js
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 75045dd..616ebe9 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -1101,6 +1101,41 @@
         <p>
           A list of the paths of the files that are being analyzed.
         </p>
+      </dd></dl></dd><dt class="notification"><a name="notification_analysis.closingLabels">analysis.closingLabels</a></dt><dd><div class="box"><pre>notification: {
+  "event": "analysis.closingLabels"
+  "params": {
+    "<b>file</b>": <a href="#type_FilePath">FilePath</a>
+    "<b>labels</b>": List&lt;<a href="#type_ClosingLabel">ClosingLabel</a>&gt;
+  }
+}</pre></div>
+    <p>
+      Reports closing labels relevant to a given file.
+    </p>
+    <p>
+      This notification is not subscribed to by default. Clients
+      can subscribe by including the value <tt>"CLOSING_LABELS"</tt>
+      in the list of services passed in an
+      analysis.setSubscriptions request.
+    </p>
+    
+  <h4>parameters:</h4><dl><dt class="field"><b>file: <a href="#type_FilePath">FilePath</a></b></dt><dd>
+        
+        <p>
+          The file the closing labels relate to.
+        </p>
+      </dd><dt class="field"><b>labels: List&lt;<a href="#type_ClosingLabel">ClosingLabel</a>&gt;</b></dt><dd>
+        
+        <p>
+          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.
+        </p>
       </dd></dl></dd><dt class="notification"><a name="notification_analysis.errors">analysis.errors</a></dt><dd><div class="box"><pre>notification: {
   "event": "analysis.errors"
   "params": {
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 6cddd5e..141ef76 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -76,7 +76,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is AnalyzerStatusParams) {
+    if (other is AnalyzerStatusParams &&
+        other.runtimeType == AnalyzerStatusParams) {
       return isAnalyzing == other.isAnalyzing && true;
     }
     return false;
@@ -166,7 +167,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ClosingLabel) {
+    if (other is ClosingLabel && other.runtimeType == ClosingLabel) {
       return range == other.range && label == other.label && true;
     }
     return false;
@@ -355,7 +356,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionItemResolutionInfo) {
+    if (other is CompletionItemResolutionInfo &&
+        other.runtimeType == CompletionItemResolutionInfo) {
       return file == other.file &&
           offset == other.offset &&
           libId == other.libId &&
@@ -433,7 +435,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DartDiagnosticServer) {
+    if (other is DartDiagnosticServer &&
+        other.runtimeType == DartDiagnosticServer) {
       return port == other.port && true;
     }
     return false;
@@ -580,7 +583,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Element) {
+    if (other is Element && other.runtimeType == Element) {
       return range == other.range &&
           name == other.name &&
           kind == other.kind &&
@@ -816,7 +819,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FlutterOutline) {
+    if (other is FlutterOutline && other.runtimeType == FlutterOutline) {
       return kind == other.kind &&
           label == other.label &&
           className == other.className &&
@@ -944,7 +947,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FlutterOutlineAttribute) {
+    if (other is FlutterOutlineAttribute &&
+        other.runtimeType == FlutterOutlineAttribute) {
       return name == other.name &&
           label == other.label &&
           valueRange == other.valueRange &&
@@ -1085,7 +1089,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Outline) {
+    if (other is Outline && other.runtimeType == Outline) {
       return element == other.element &&
           range == other.range &&
           codeRange == other.codeRange &&
@@ -1188,7 +1192,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is PublishClosingLabelsParams) {
+    if (other is PublishClosingLabelsParams &&
+        other.runtimeType == PublishClosingLabelsParams) {
       return uri == other.uri &&
           listEqual(labels, other.labels,
               (ClosingLabel a, ClosingLabel b) => a == b) &&
@@ -1286,7 +1291,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is PublishFlutterOutlineParams) {
+    if (other is PublishFlutterOutlineParams &&
+        other.runtimeType == PublishFlutterOutlineParams) {
       return uri == other.uri && outline == other.outline && true;
     }
     return false;
@@ -1379,7 +1385,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is PublishOutlineParams) {
+    if (other is PublishOutlineParams &&
+        other.runtimeType == PublishOutlineParams) {
       return uri == other.uri && outline == other.outline && true;
     }
     return false;
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index e4c0e70..fdafe89 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -94,7 +94,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ApplyWorkspaceEditParams) {
+    if (other is ApplyWorkspaceEditParams &&
+        other.runtimeType == ApplyWorkspaceEditParams) {
       return label == other.label && edit == other.edit && true;
     }
     return false;
@@ -182,7 +183,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ApplyWorkspaceEditResponse) {
+    if (other is ApplyWorkspaceEditResponse &&
+        other.runtimeType == ApplyWorkspaceEditResponse) {
       return applied == other.applied &&
           failureReason == other.failureReason &&
           true;
@@ -257,7 +259,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CancelParams) {
+    if (other is CancelParams && other.runtimeType == CancelParams) {
       return id == other.id && true;
     }
     return false;
@@ -356,7 +358,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ClientCapabilities) {
+    if (other is ClientCapabilities &&
+        other.runtimeType == ClientCapabilities) {
       return workspace == other.workspace &&
           textDocument == other.textDocument &&
           experimental == other.experimental &&
@@ -513,7 +516,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeAction) {
+    if (other is CodeAction && other.runtimeType == CodeAction) {
       return title == other.title &&
           kind == other.kind &&
           listEqual(diagnostics, other.diagnostics,
@@ -624,7 +627,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeActionContext) {
+    if (other is CodeActionContext && other.runtimeType == CodeActionContext) {
       return listEqual(diagnostics, other.diagnostics,
               (Diagnostic a, Diagnostic b) => a == b) &&
           listEqual(only, other.only,
@@ -772,7 +775,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeActionOptions) {
+    if (other is CodeActionOptions && other.runtimeType == CodeActionOptions) {
       return listEqual(codeActionKinds, other.codeActionKinds,
               (CodeActionKind a, CodeActionKind b) => a == b) &&
           true;
@@ -899,7 +902,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeActionParams) {
+    if (other is CodeActionParams && other.runtimeType == CodeActionParams) {
       return textDocument == other.textDocument &&
           range == other.range &&
           context == other.context &&
@@ -998,8 +1001,10 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeActionRegistrationOptions) {
-      return documentSelector == other.documentSelector &&
+    if (other is CodeActionRegistrationOptions &&
+        other.runtimeType == CodeActionRegistrationOptions) {
+      return listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           listEqual(codeActionKinds, other.codeActionKinds,
               (CodeActionKind a, CodeActionKind b) => a == b) &&
           true;
@@ -1112,7 +1117,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeLens) {
+    if (other is CodeLens && other.runtimeType == CodeLens) {
       return range == other.range &&
           command == other.command &&
           data == other.data &&
@@ -1177,7 +1182,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeLensOptions) {
+    if (other is CodeLensOptions && other.runtimeType == CodeLensOptions) {
       return resolveProvider == other.resolveProvider && true;
     }
     return false;
@@ -1248,7 +1253,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeLensParams) {
+    if (other is CodeLensParams && other.runtimeType == CodeLensParams) {
       return textDocument == other.textDocument && true;
     }
     return false;
@@ -1334,9 +1339,11 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CodeLensRegistrationOptions) {
+    if (other is CodeLensRegistrationOptions &&
+        other.runtimeType == CodeLensRegistrationOptions) {
       return resolveProvider == other.resolveProvider &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -1480,7 +1487,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Color) {
+    if (other is Color && other.runtimeType == Color) {
       return red == other.red &&
           green == other.green &&
           blue == other.blue &&
@@ -1580,7 +1587,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ColorInformation) {
+    if (other is ColorInformation && other.runtimeType == ColorInformation) {
       return range == other.range && color == other.color && true;
     }
     return false;
@@ -1695,7 +1702,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ColorPresentation) {
+    if (other is ColorPresentation && other.runtimeType == ColorPresentation) {
       return label == other.label &&
           textEdit == other.textEdit &&
           listEqual(additionalTextEdits, other.additionalTextEdits,
@@ -1822,7 +1829,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ColorPresentationParams) {
+    if (other is ColorPresentationParams &&
+        other.runtimeType == ColorPresentationParams) {
       return textDocument == other.textDocument &&
           color == other.color &&
           range == other.range &&
@@ -1869,7 +1877,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ColorProviderOptions) {
+    if (other is ColorProviderOptions &&
+        other.runtimeType == ColorProviderOptions) {
       return true;
     }
     return false;
@@ -1980,7 +1989,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Command) {
+    if (other is Command && other.runtimeType == Command) {
       return title == other.title &&
           command == other.command &&
           listEqual(
@@ -2077,7 +2086,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionContext) {
+    if (other is CompletionContext && other.runtimeType == CompletionContext) {
       return triggerKind == other.triggerKind &&
           triggerCharacter == other.triggerCharacter &&
           true;
@@ -2470,7 +2479,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionItem) {
+    if (other is CompletionItem && other.runtimeType == CompletionItem) {
       return label == other.label &&
           kind == other.kind &&
           detail == other.detail &&
@@ -2651,7 +2660,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionList) {
+    if (other is CompletionList && other.runtimeType == CompletionList) {
       return isIncomplete == other.isIncomplete &&
           listEqual(items, other.items,
               (CompletionItem a, CompletionItem b) => a == b) &&
@@ -2737,7 +2746,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionOptions) {
+    if (other is CompletionOptions && other.runtimeType == CompletionOptions) {
       return resolveProvider == other.resolveProvider &&
           listEqual(triggerCharacters, other.triggerCharacters,
               (String a, String b) => a == b) &&
@@ -2860,7 +2869,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionParams) {
+    if (other is CompletionParams && other.runtimeType == CompletionParams) {
       return context == other.context &&
           textDocument == other.textDocument &&
           position == other.position &&
@@ -3014,13 +3023,15 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionRegistrationOptions) {
+    if (other is CompletionRegistrationOptions &&
+        other.runtimeType == CompletionRegistrationOptions) {
       return listEqual(triggerCharacters, other.triggerCharacters,
               (String a, String b) => a == b) &&
           listEqual(allCommitCharacters, other.allCommitCharacters,
               (String a, String b) => a == b) &&
           resolveProvider == other.resolveProvider &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -3137,7 +3148,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ConfigurationItem) {
+    if (other is ConfigurationItem && other.runtimeType == ConfigurationItem) {
       return scopeUri == other.scopeUri && section == other.section && true;
     }
     return false;
@@ -3210,7 +3221,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ConfigurationParams) {
+    if (other is ConfigurationParams &&
+        other.runtimeType == ConfigurationParams) {
       return listEqual(items, other.items,
               (ConfigurationItem a, ConfigurationItem b) => a == b) &&
           true;
@@ -3325,7 +3337,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CreateFile) {
+    if (other is CreateFile && other.runtimeType == CreateFile) {
       return kind == other.kind &&
           uri == other.uri &&
           options == other.options &&
@@ -3405,7 +3417,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is CreateFileOptions) {
+    if (other is CreateFileOptions && other.runtimeType == CreateFileOptions) {
       return overwrite == other.overwrite &&
           ignoreIfExists == other.ignoreIfExists &&
           true;
@@ -3521,7 +3533,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DeleteFile) {
+    if (other is DeleteFile && other.runtimeType == DeleteFile) {
       return kind == other.kind &&
           uri == other.uri &&
           options == other.options &&
@@ -3602,7 +3614,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DeleteFileOptions) {
+    if (other is DeleteFileOptions && other.runtimeType == DeleteFileOptions) {
       return recursive == other.recursive &&
           ignoreIfNotExists == other.ignoreIfNotExists &&
           true;
@@ -3779,7 +3791,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Diagnostic) {
+    if (other is Diagnostic && other.runtimeType == Diagnostic) {
       return range == other.range &&
           severity == other.severity &&
           code == other.code &&
@@ -3895,7 +3907,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DiagnosticRelatedInformation) {
+    if (other is DiagnosticRelatedInformation &&
+        other.runtimeType == DiagnosticRelatedInformation) {
       return location == other.location && message == other.message && true;
     }
     return false;
@@ -3990,7 +4003,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidChangeConfigurationParams) {
+    if (other is DidChangeConfigurationParams &&
+        other.runtimeType == DidChangeConfigurationParams) {
       return settings == other.settings && true;
     }
     return false;
@@ -4100,7 +4114,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidChangeTextDocumentParams) {
+    if (other is DidChangeTextDocumentParams &&
+        other.runtimeType == DidChangeTextDocumentParams) {
       return textDocument == other.textDocument &&
           listEqual(
               contentChanges,
@@ -4183,7 +4198,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidChangeWatchedFilesParams) {
+    if (other is DidChangeWatchedFilesParams &&
+        other.runtimeType == DidChangeWatchedFilesParams) {
       return listEqual(
               changes, other.changes, (FileEvent a, FileEvent b) => a == b) &&
           true;
@@ -4263,7 +4279,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidChangeWatchedFilesRegistrationOptions) {
+    if (other is DidChangeWatchedFilesRegistrationOptions &&
+        other.runtimeType == DidChangeWatchedFilesRegistrationOptions) {
       return listEqual(watchers, other.watchers,
               (FileSystemWatcher a, FileSystemWatcher b) => a == b) &&
           true;
@@ -4336,7 +4353,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidChangeWorkspaceFoldersParams) {
+    if (other is DidChangeWorkspaceFoldersParams &&
+        other.runtimeType == DidChangeWorkspaceFoldersParams) {
       return event == other.event && true;
     }
     return false;
@@ -4407,7 +4425,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidCloseTextDocumentParams) {
+    if (other is DidCloseTextDocumentParams &&
+        other.runtimeType == DidCloseTextDocumentParams) {
       return textDocument == other.textDocument && true;
     }
     return false;
@@ -4478,7 +4497,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidOpenTextDocumentParams) {
+    if (other is DidOpenTextDocumentParams &&
+        other.runtimeType == DidOpenTextDocumentParams) {
       return textDocument == other.textDocument && true;
     }
     return false;
@@ -4566,7 +4586,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DidSaveTextDocumentParams) {
+    if (other is DidSaveTextDocumentParams &&
+        other.runtimeType == DidSaveTextDocumentParams) {
       return textDocument == other.textDocument && text == other.text && true;
     }
     return false;
@@ -4669,7 +4690,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentFilter) {
+    if (other is DocumentFilter && other.runtimeType == DocumentFilter) {
       return language == other.language &&
           scheme == other.scheme &&
           pattern == other.pattern &&
@@ -4773,7 +4794,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentFormattingParams) {
+    if (other is DocumentFormattingParams &&
+        other.runtimeType == DocumentFormattingParams) {
       return textDocument == other.textDocument &&
           options == other.options &&
           true;
@@ -4866,7 +4888,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentHighlight) {
+    if (other is DocumentHighlight && other.runtimeType == DocumentHighlight) {
       return range == other.range && kind == other.kind && true;
     }
     return false;
@@ -5002,7 +5024,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentLink) {
+    if (other is DocumentLink && other.runtimeType == DocumentLink) {
       return range == other.range &&
           target == other.target &&
           data == other.data &&
@@ -5067,7 +5089,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentLinkOptions) {
+    if (other is DocumentLinkOptions &&
+        other.runtimeType == DocumentLinkOptions) {
       return resolveProvider == other.resolveProvider && true;
     }
     return false;
@@ -5138,7 +5161,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentLinkParams) {
+    if (other is DocumentLinkParams &&
+        other.runtimeType == DocumentLinkParams) {
       return textDocument == other.textDocument && true;
     }
     return false;
@@ -5224,9 +5248,11 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentLinkRegistrationOptions) {
+    if (other is DocumentLinkRegistrationOptions &&
+        other.runtimeType == DocumentLinkRegistrationOptions) {
       return resolveProvider == other.resolveProvider &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -5322,7 +5348,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentOnTypeFormattingOptions) {
+    if (other is DocumentOnTypeFormattingOptions &&
+        other.runtimeType == DocumentOnTypeFormattingOptions) {
       return firstTriggerCharacter == other.firstTriggerCharacter &&
           listEqual(moreTriggerCharacter, other.moreTriggerCharacter,
               (String a, String b) => a == b) &&
@@ -5479,7 +5506,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentOnTypeFormattingParams) {
+    if (other is DocumentOnTypeFormattingParams &&
+        other.runtimeType == DocumentOnTypeFormattingParams) {
       return textDocument == other.textDocument &&
           position == other.position &&
           ch == other.ch &&
@@ -5608,11 +5636,13 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentOnTypeFormattingRegistrationOptions) {
+    if (other is DocumentOnTypeFormattingRegistrationOptions &&
+        other.runtimeType == DocumentOnTypeFormattingRegistrationOptions) {
       return firstTriggerCharacter == other.firstTriggerCharacter &&
           listEqual(moreTriggerCharacter, other.moreTriggerCharacter,
               (String a, String b) => a == b) &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -5739,7 +5769,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentRangeFormattingParams) {
+    if (other is DocumentRangeFormattingParams &&
+        other.runtimeType == DocumentRangeFormattingParams) {
       return textDocument == other.textDocument &&
           range == other.range &&
           options == other.options &&
@@ -5957,7 +5988,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentSymbol) {
+    if (other is DocumentSymbol && other.runtimeType == DocumentSymbol) {
       return name == other.name &&
           detail == other.detail &&
           kind == other.kind &&
@@ -6042,7 +6073,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is DocumentSymbolParams) {
+    if (other is DocumentSymbolParams &&
+        other.runtimeType == DocumentSymbolParams) {
       return textDocument == other.textDocument && true;
     }
     return false;
@@ -6150,7 +6182,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ExecuteCommandOptions) {
+    if (other is ExecuteCommandOptions &&
+        other.runtimeType == ExecuteCommandOptions) {
       return listEqual(
               commands, other.commands, (String a, String b) => a == b) &&
           true;
@@ -6240,7 +6273,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ExecuteCommandParams) {
+    if (other is ExecuteCommandParams &&
+        other.runtimeType == ExecuteCommandParams) {
       return command == other.command &&
           listEqual(
               arguments, other.arguments, (dynamic a, dynamic b) => a == b) &&
@@ -6317,7 +6351,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ExecuteCommandRegistrationOptions) {
+    if (other is ExecuteCommandRegistrationOptions &&
+        other.runtimeType == ExecuteCommandRegistrationOptions) {
       return listEqual(
               commands, other.commands, (String a, String b) => a == b) &&
           true;
@@ -6491,7 +6526,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FileEvent) {
+    if (other is FileEvent && other.runtimeType == FileEvent) {
       return uri == other.uri && type == other.type && true;
     }
     return false;
@@ -6591,7 +6626,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FileSystemWatcher) {
+    if (other is FileSystemWatcher && other.runtimeType == FileSystemWatcher) {
       return globPattern == other.globPattern && kind == other.kind && true;
     }
     return false;
@@ -6744,7 +6779,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FoldingRange) {
+    if (other is FoldingRange && other.runtimeType == FoldingRange) {
       return startLine == other.startLine &&
           startCharacter == other.startCharacter &&
           endLine == other.endLine &&
@@ -6855,7 +6890,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FoldingRangeParams) {
+    if (other is FoldingRangeParams &&
+        other.runtimeType == FoldingRangeParams) {
       return textDocument == other.textDocument && true;
     }
     return false;
@@ -6898,7 +6934,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FoldingRangeProviderOptions) {
+    if (other is FoldingRangeProviderOptions &&
+        other.runtimeType == FoldingRangeProviderOptions) {
       return true;
     }
     return false;
@@ -6993,7 +7030,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is FormattingOptions) {
+    if (other is FormattingOptions && other.runtimeType == FormattingOptions) {
       return tabSize == other.tabSize &&
           insertSpaces == other.insertSpaces &&
           true;
@@ -7090,7 +7127,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Hover) {
+    if (other is Hover && other.runtimeType == Hover) {
       return contents == other.contents && range == other.range && true;
     }
     return false;
@@ -7287,7 +7324,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is InitializeParams) {
+    if (other is InitializeParams && other.runtimeType == InitializeParams) {
       return processId == other.processId &&
           rootPath == other.rootPath &&
           rootUri == other.rootUri &&
@@ -7372,7 +7409,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is InitializeResult) {
+    if (other is InitializeResult && other.runtimeType == InitializeResult) {
       return capabilities == other.capabilities && true;
     }
     return false;
@@ -7413,7 +7450,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is InitializedParams) {
+    if (other is InitializedParams && other.runtimeType == InitializedParams) {
       return true;
     }
     return false;
@@ -7541,7 +7578,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Location) {
+    if (other is Location && other.runtimeType == Location) {
       return uri == other.uri && range == other.range && true;
     }
     return false;
@@ -7696,7 +7733,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is LocationLink) {
+    if (other is LocationLink && other.runtimeType == LocationLink) {
       return originSelectionRange == other.originSelectionRange &&
           targetUri == other.targetUri &&
           targetRange == other.targetRange &&
@@ -7798,7 +7835,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is LogMessageParams) {
+    if (other is LogMessageParams && other.runtimeType == LogMessageParams) {
       return type == other.type && message == other.message && true;
     }
     return false;
@@ -7915,7 +7952,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is MarkupContent) {
+    if (other is MarkupContent && other.runtimeType == MarkupContent) {
       return kind == other.kind && value == other.value && true;
     }
     return false;
@@ -8029,7 +8066,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Message) {
+    if (other is Message && other.runtimeType == Message) {
       return jsonrpc == other.jsonrpc && true;
     }
     return false;
@@ -8097,7 +8134,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is MessageActionItem) {
+    if (other is MessageActionItem && other.runtimeType == MessageActionItem) {
       return title == other.title && true;
     }
     return false;
@@ -8418,7 +8455,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is NotificationMessage) {
+    if (other is NotificationMessage &&
+        other.runtimeType == NotificationMessage) {
       return method == other.method &&
           params == other.params &&
           jsonrpc == other.jsonrpc &&
@@ -8530,7 +8568,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ParameterInformation) {
+    if (other is ParameterInformation &&
+        other.runtimeType == ParameterInformation) {
       return label == other.label &&
           documentation == other.documentation &&
           true;
@@ -8632,7 +8671,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Position) {
+    if (other is Position && other.runtimeType == Position) {
       return line == other.line && character == other.character && true;
     }
     return false;
@@ -8732,7 +8771,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is PublishDiagnosticsParams) {
+    if (other is PublishDiagnosticsParams &&
+        other.runtimeType == PublishDiagnosticsParams) {
       return uri == other.uri &&
           listEqual(diagnostics, other.diagnostics,
               (Diagnostic a, Diagnostic b) => a == b) &&
@@ -8829,7 +8869,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Range) {
+    if (other is Range && other.runtimeType == Range) {
       return start == other.start && end == other.end && true;
     }
     return false;
@@ -8921,7 +8961,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RangeAndPlaceholder) {
+    if (other is RangeAndPlaceholder &&
+        other.runtimeType == RangeAndPlaceholder) {
       return range == other.range && placeholder == other.placeholder && true;
     }
     return false;
@@ -8991,7 +9032,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ReferenceContext) {
+    if (other is ReferenceContext && other.runtimeType == ReferenceContext) {
       return includeDeclaration == other.includeDeclaration && true;
     }
     return false;
@@ -9116,7 +9157,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ReferenceParams) {
+    if (other is ReferenceParams && other.runtimeType == ReferenceParams) {
       return context == other.context &&
           textDocument == other.textDocument &&
           position == other.position &&
@@ -9232,7 +9273,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Registration) {
+    if (other is Registration && other.runtimeType == Registration) {
       return id == other.id &&
           method == other.method &&
           registerOptions == other.registerOptions &&
@@ -9310,7 +9351,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RegistrationParams) {
+    if (other is RegistrationParams &&
+        other.runtimeType == RegistrationParams) {
       return listEqual(registrations, other.registrations,
               (Registration a, Registration b) => a == b) &&
           true;
@@ -9450,7 +9492,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RenameFile) {
+    if (other is RenameFile && other.runtimeType == RenameFile) {
       return kind == other.kind &&
           oldUri == other.oldUri &&
           newUri == other.newUri &&
@@ -9532,7 +9574,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RenameFileOptions) {
+    if (other is RenameFileOptions && other.runtimeType == RenameFileOptions) {
       return overwrite == other.overwrite &&
           ignoreIfExists == other.ignoreIfExists &&
           true;
@@ -9595,7 +9637,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RenameOptions) {
+    if (other is RenameOptions && other.runtimeType == RenameOptions) {
       return prepareProvider == other.prepareProvider && true;
     }
     return false;
@@ -9720,7 +9762,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RenameParams) {
+    if (other is RenameParams && other.runtimeType == RenameParams) {
       return textDocument == other.textDocument &&
           position == other.position &&
           newName == other.newName &&
@@ -9810,9 +9852,11 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RenameRegistrationOptions) {
+    if (other is RenameRegistrationOptions &&
+        other.runtimeType == RenameRegistrationOptions) {
       return prepareProvider == other.prepareProvider &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -9951,7 +9995,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is RequestMessage) {
+    if (other is RequestMessage && other.runtimeType == RequestMessage) {
       return id == other.id &&
           method == other.method &&
           params == other.params &&
@@ -10107,7 +10151,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ResponseError) {
+    if (other is ResponseError && other.runtimeType == ResponseError) {
       return code == other.code &&
           message == other.message &&
           data == other.data &&
@@ -10240,7 +10284,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ResponseMessage) {
+    if (other is ResponseMessage && other.runtimeType == ResponseMessage) {
       return id == other.id &&
           result == other.result &&
           error == other.error &&
@@ -10306,7 +10350,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is SaveOptions) {
+    if (other is SaveOptions && other.runtimeType == SaveOptions) {
       return includeText == other.includeText && true;
     }
     return false;
@@ -10875,7 +10919,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ServerCapabilities) {
+    if (other is ServerCapabilities &&
+        other.runtimeType == ServerCapabilities) {
       return textDocumentSync == other.textDocumentSync &&
           hoverProvider == other.hoverProvider &&
           completionProvider == other.completionProvider &&
@@ -10992,7 +11037,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ServerCapabilitiesWorkspace) {
+    if (other is ServerCapabilitiesWorkspace &&
+        other.runtimeType == ServerCapabilitiesWorkspace) {
       return workspaceFolders == other.workspaceFolders && true;
     }
     return false;
@@ -11075,7 +11121,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ServerCapabilitiesWorkspaceFolders) {
+    if (other is ServerCapabilitiesWorkspaceFolders &&
+        other.runtimeType == ServerCapabilitiesWorkspaceFolders) {
       return supported == other.supported &&
           changeNotifications == other.changeNotifications &&
           true;
@@ -11173,7 +11220,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ShowMessageParams) {
+    if (other is ShowMessageParams && other.runtimeType == ShowMessageParams) {
       return type == other.type && message == other.message && true;
     }
     return false;
@@ -11291,7 +11338,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is ShowMessageRequestParams) {
+    if (other is ShowMessageRequestParams &&
+        other.runtimeType == ShowMessageRequestParams) {
       return type == other.type &&
           message == other.message &&
           listEqual(actions, other.actions,
@@ -11418,7 +11466,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is SignatureHelp) {
+    if (other is SignatureHelp && other.runtimeType == SignatureHelp) {
       return listEqual(signatures, other.signatures,
               (SignatureInformation a, SignatureInformation b) => a == b) &&
           activeSignature == other.activeSignature &&
@@ -11488,7 +11536,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is SignatureHelpOptions) {
+    if (other is SignatureHelpOptions &&
+        other.runtimeType == SignatureHelpOptions) {
       return listEqual(triggerCharacters, other.triggerCharacters,
               (String a, String b) => a == b) &&
           true;
@@ -11582,10 +11631,12 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is SignatureHelpRegistrationOptions) {
+    if (other is SignatureHelpRegistrationOptions &&
+        other.runtimeType == SignatureHelpRegistrationOptions) {
       return listEqual(triggerCharacters, other.triggerCharacters,
               (String a, String b) => a == b) &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -11707,7 +11758,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is SignatureInformation) {
+    if (other is SignatureInformation &&
+        other.runtimeType == SignatureInformation) {
       return label == other.label &&
           documentation == other.documentation &&
           listEqual(parameters, other.parameters,
@@ -11773,7 +11825,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is StaticRegistrationOptions) {
+    if (other is StaticRegistrationOptions &&
+        other.runtimeType == StaticRegistrationOptions) {
       return id == other.id && true;
     }
     return false;
@@ -11940,7 +11993,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is SymbolInformation) {
+    if (other is SymbolInformation && other.runtimeType == SymbolInformation) {
       return name == other.name &&
           kind == other.kind &&
           deprecated == other.deprecated &&
@@ -12101,9 +12154,11 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentChangeRegistrationOptions) {
+    if (other is TextDocumentChangeRegistrationOptions &&
+        other.runtimeType == TextDocumentChangeRegistrationOptions) {
       return syncKind == other.syncKind &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -12653,7 +12708,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilities) {
+    if (other is TextDocumentClientCapabilities &&
+        other.runtimeType == TextDocumentClientCapabilities) {
       return synchronization == other.synchronization &&
           completion == other.completion &&
           hover == other.hover &&
@@ -12784,7 +12840,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCodeAction) {
+    if (other is TextDocumentClientCapabilitiesCodeAction &&
+        other.runtimeType == TextDocumentClientCapabilitiesCodeAction) {
       return dynamicRegistration == other.dynamicRegistration &&
           codeActionLiteralSupport == other.codeActionLiteralSupport &&
           true;
@@ -12866,7 +12923,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCodeActionKind) {
+    if (other is TextDocumentClientCapabilitiesCodeActionKind &&
+        other.runtimeType == TextDocumentClientCapabilitiesCodeActionKind) {
       return listEqual(valueSet, other.valueSet,
               (CodeActionKind a, CodeActionKind b) => a == b) &&
           true;
@@ -12947,7 +13005,9 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCodeActionLiteralSupport) {
+    if (other is TextDocumentClientCapabilitiesCodeActionLiteralSupport &&
+        other.runtimeType ==
+            TextDocumentClientCapabilitiesCodeActionLiteralSupport) {
       return codeActionKind == other.codeActionKind && true;
     }
     return false;
@@ -13009,7 +13069,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCodeLens) {
+    if (other is TextDocumentClientCapabilitiesCodeLens &&
+        other.runtimeType == TextDocumentClientCapabilitiesCodeLens) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -13074,7 +13135,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesColorProvider) {
+    if (other is TextDocumentClientCapabilitiesColorProvider &&
+        other.runtimeType == TextDocumentClientCapabilitiesColorProvider) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -13197,7 +13259,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCompletion) {
+    if (other is TextDocumentClientCapabilitiesCompletion &&
+        other.runtimeType == TextDocumentClientCapabilitiesCompletion) {
       return dynamicRegistration == other.dynamicRegistration &&
           completionItem == other.completionItem &&
           completionItemKind == other.completionItemKind &&
@@ -13354,7 +13417,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCompletionItem) {
+    if (other is TextDocumentClientCapabilitiesCompletionItem &&
+        other.runtimeType == TextDocumentClientCapabilitiesCompletionItem) {
       return snippetSupport == other.snippetSupport &&
           commitCharactersSupport == other.commitCharactersSupport &&
           listEqual(documentationFormat, other.documentationFormat,
@@ -13437,7 +13501,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesCompletionItemKind) {
+    if (other is TextDocumentClientCapabilitiesCompletionItemKind &&
+        other.runtimeType == TextDocumentClientCapabilitiesCompletionItemKind) {
       return listEqual(valueSet, other.valueSet,
               (CompletionItemKind a, CompletionItemKind b) => a == b) &&
           true;
@@ -13524,7 +13589,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesDeclaration) {
+    if (other is TextDocumentClientCapabilitiesDeclaration &&
+        other.runtimeType == TextDocumentClientCapabilitiesDeclaration) {
       return dynamicRegistration == other.dynamicRegistration &&
           linkSupport == other.linkSupport &&
           true;
@@ -13607,7 +13673,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesDefinition) {
+    if (other is TextDocumentClientCapabilitiesDefinition &&
+        other.runtimeType == TextDocumentClientCapabilitiesDefinition) {
       return dynamicRegistration == other.dynamicRegistration &&
           linkSupport == other.linkSupport &&
           true;
@@ -13672,7 +13739,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesDocumentHighlight) {
+    if (other is TextDocumentClientCapabilitiesDocumentHighlight &&
+        other.runtimeType == TextDocumentClientCapabilitiesDocumentHighlight) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -13734,7 +13802,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesDocumentLink) {
+    if (other is TextDocumentClientCapabilitiesDocumentLink &&
+        other.runtimeType == TextDocumentClientCapabilitiesDocumentLink) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -13838,7 +13907,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesDocumentSymbol) {
+    if (other is TextDocumentClientCapabilitiesDocumentSymbol &&
+        other.runtimeType == TextDocumentClientCapabilitiesDocumentSymbol) {
       return dynamicRegistration == other.dynamicRegistration &&
           symbolKind == other.symbolKind &&
           hierarchicalDocumentSymbolSupport ==
@@ -13950,7 +14020,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesFoldingRange) {
+    if (other is TextDocumentClientCapabilitiesFoldingRange &&
+        other.runtimeType == TextDocumentClientCapabilitiesFoldingRange) {
       return dynamicRegistration == other.dynamicRegistration &&
           rangeLimit == other.rangeLimit &&
           lineFoldingOnly == other.lineFoldingOnly &&
@@ -14017,7 +14088,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesFormatting) {
+    if (other is TextDocumentClientCapabilitiesFormatting &&
+        other.runtimeType == TextDocumentClientCapabilitiesFormatting) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -14104,7 +14176,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesHover) {
+    if (other is TextDocumentClientCapabilitiesHover &&
+        other.runtimeType == TextDocumentClientCapabilitiesHover) {
       return dynamicRegistration == other.dynamicRegistration &&
           listEqual(contentFormat, other.contentFormat,
               (MarkupKind a, MarkupKind b) => a == b) &&
@@ -14193,7 +14266,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesImplementation) {
+    if (other is TextDocumentClientCapabilitiesImplementation &&
+        other.runtimeType == TextDocumentClientCapabilitiesImplementation) {
       return dynamicRegistration == other.dynamicRegistration &&
           linkSupport == other.linkSupport &&
           true;
@@ -14258,7 +14332,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesOnTypeFormatting) {
+    if (other is TextDocumentClientCapabilitiesOnTypeFormatting &&
+        other.runtimeType == TextDocumentClientCapabilitiesOnTypeFormatting) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -14324,7 +14399,9 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesParameterInformation) {
+    if (other is TextDocumentClientCapabilitiesParameterInformation &&
+        other.runtimeType ==
+            TextDocumentClientCapabilitiesParameterInformation) {
       return labelOffsetSupport == other.labelOffsetSupport && true;
     }
     return false;
@@ -14386,7 +14463,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesPublishDiagnostics) {
+    if (other is TextDocumentClientCapabilitiesPublishDiagnostics &&
+        other.runtimeType == TextDocumentClientCapabilitiesPublishDiagnostics) {
       return relatedInformation == other.relatedInformation && true;
     }
     return false;
@@ -14448,7 +14526,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesRangeFormatting) {
+    if (other is TextDocumentClientCapabilitiesRangeFormatting &&
+        other.runtimeType == TextDocumentClientCapabilitiesRangeFormatting) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -14510,7 +14589,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesReferences) {
+    if (other is TextDocumentClientCapabilitiesReferences &&
+        other.runtimeType == TextDocumentClientCapabilitiesReferences) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -14591,7 +14671,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesRename) {
+    if (other is TextDocumentClientCapabilitiesRename &&
+        other.runtimeType == TextDocumentClientCapabilitiesRename) {
       return dynamicRegistration == other.dynamicRegistration &&
           prepareSupport == other.prepareSupport &&
           true;
@@ -14681,7 +14762,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesSignatureHelp) {
+    if (other is TextDocumentClientCapabilitiesSignatureHelp &&
+        other.runtimeType == TextDocumentClientCapabilitiesSignatureHelp) {
       return dynamicRegistration == other.dynamicRegistration &&
           signatureInformation == other.signatureInformation &&
           true;
@@ -14776,7 +14858,9 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesSignatureInformation) {
+    if (other is TextDocumentClientCapabilitiesSignatureInformation &&
+        other.runtimeType ==
+            TextDocumentClientCapabilitiesSignatureInformation) {
       return listEqual(documentationFormat, other.documentationFormat,
               (MarkupKind a, MarkupKind b) => a == b) &&
           parameterInformation == other.parameterInformation &&
@@ -14852,7 +14936,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesSymbolKind) {
+    if (other is TextDocumentClientCapabilitiesSymbolKind &&
+        other.runtimeType == TextDocumentClientCapabilitiesSymbolKind) {
       return listEqual(valueSet, other.valueSet,
               (SymbolKind a, SymbolKind b) => a == b) &&
           true;
@@ -14969,7 +15054,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesSynchronization) {
+    if (other is TextDocumentClientCapabilitiesSynchronization &&
+        other.runtimeType == TextDocumentClientCapabilitiesSynchronization) {
       return dynamicRegistration == other.dynamicRegistration &&
           willSave == other.willSave &&
           willSaveWaitUntil == other.willSaveWaitUntil &&
@@ -15061,7 +15147,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentClientCapabilitiesTypeDefinition) {
+    if (other is TextDocumentClientCapabilitiesTypeDefinition &&
+        other.runtimeType == TextDocumentClientCapabilitiesTypeDefinition) {
       return dynamicRegistration == other.dynamicRegistration &&
           linkSupport == other.linkSupport &&
           true;
@@ -15168,7 +15255,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentContentChangeEvent) {
+    if (other is TextDocumentContentChangeEvent &&
+        other.runtimeType == TextDocumentContentChangeEvent) {
       return range == other.range &&
           rangeLength == other.rangeLength &&
           text == other.text &&
@@ -15276,7 +15364,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentEdit) {
+    if (other is TextDocumentEdit && other.runtimeType == TextDocumentEdit) {
       return textDocument == other.textDocument &&
           listEqual(edits, other.edits, (TextEdit a, TextEdit b) => a == b) &&
           true;
@@ -15350,7 +15438,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentIdentifier) {
+    if (other is TextDocumentIdentifier &&
+        other.runtimeType == TextDocumentIdentifier) {
       return uri == other.uri && true;
     }
     return false;
@@ -15496,7 +15585,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentItem) {
+    if (other is TextDocumentItem && other.runtimeType == TextDocumentItem) {
       return uri == other.uri &&
           languageId == other.languageId &&
           version == other.version &&
@@ -15607,7 +15696,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentPositionParams) {
+    if (other is TextDocumentPositionParams &&
+        other.runtimeType == TextDocumentPositionParams) {
       return textDocument == other.textDocument &&
           position == other.position &&
           true;
@@ -15708,8 +15798,11 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentRegistrationOptions) {
-      return documentSelector == other.documentSelector && true;
+    if (other is TextDocumentRegistrationOptions &&
+        other.runtimeType == TextDocumentRegistrationOptions) {
+      return listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
+          true;
     }
     return false;
   }
@@ -15828,9 +15921,11 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentSaveRegistrationOptions) {
+    if (other is TextDocumentSaveRegistrationOptions &&
+        other.runtimeType == TextDocumentSaveRegistrationOptions) {
       return includeText == other.includeText &&
-          documentSelector == other.documentSelector &&
+          listEqual(documentSelector, other.documentSelector,
+              (DocumentFilter a, DocumentFilter b) => a == b) &&
           true;
     }
     return false;
@@ -16001,7 +16096,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextDocumentSyncOptions) {
+    if (other is TextDocumentSyncOptions &&
+        other.runtimeType == TextDocumentSyncOptions) {
       return openClose == other.openClose &&
           change == other.change &&
           willSave == other.willSave &&
@@ -16105,7 +16201,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TextEdit) {
+    if (other is TextEdit && other.runtimeType == TextEdit) {
       return range == other.range && newText == other.newText && true;
     }
     return false;
@@ -16201,7 +16297,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is Unregistration) {
+    if (other is Unregistration && other.runtimeType == Unregistration) {
       return id == other.id && method == other.method && true;
     }
     return false;
@@ -16275,7 +16371,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is UnregistrationParams) {
+    if (other is UnregistrationParams &&
+        other.runtimeType == UnregistrationParams) {
       return listEqual(unregisterations, other.unregisterations,
               (Unregistration a, Unregistration b) => a == b) &&
           true;
@@ -16372,7 +16469,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is VersionedTextDocumentIdentifier) {
+    if (other is VersionedTextDocumentIdentifier &&
+        other.runtimeType == VersionedTextDocumentIdentifier) {
       return version == other.version && uri == other.uri && true;
     }
     return false;
@@ -16500,7 +16598,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WillSaveTextDocumentParams) {
+    if (other is WillSaveTextDocumentParams &&
+        other.runtimeType == WillSaveTextDocumentParams) {
       return textDocument == other.textDocument &&
           reason == other.reason &&
           true;
@@ -16729,7 +16828,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilities) {
+    if (other is WorkspaceClientCapabilities &&
+        other.runtimeType == WorkspaceClientCapabilities) {
       return applyEdit == other.applyEdit &&
           workspaceEdit == other.workspaceEdit &&
           didChangeConfiguration == other.didChangeConfiguration &&
@@ -16807,7 +16907,9 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilitiesDidChangeConfiguration) {
+    if (other is WorkspaceClientCapabilitiesDidChangeConfiguration &&
+        other.runtimeType ==
+            WorkspaceClientCapabilitiesDidChangeConfiguration) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -16872,7 +16974,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilitiesDidChangeWatchedFiles) {
+    if (other is WorkspaceClientCapabilitiesDidChangeWatchedFiles &&
+        other.runtimeType == WorkspaceClientCapabilitiesDidChangeWatchedFiles) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -16934,7 +17037,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilitiesExecuteCommand) {
+    if (other is WorkspaceClientCapabilitiesExecuteCommand &&
+        other.runtimeType == WorkspaceClientCapabilitiesExecuteCommand) {
       return dynamicRegistration == other.dynamicRegistration && true;
     }
     return false;
@@ -17016,7 +17120,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilitiesSymbol) {
+    if (other is WorkspaceClientCapabilitiesSymbol &&
+        other.runtimeType == WorkspaceClientCapabilitiesSymbol) {
       return dynamicRegistration == other.dynamicRegistration &&
           symbolKind == other.symbolKind &&
           true;
@@ -17091,7 +17196,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilitiesSymbolKind) {
+    if (other is WorkspaceClientCapabilitiesSymbolKind &&
+        other.runtimeType == WorkspaceClientCapabilitiesSymbolKind) {
       return listEqual(valueSet, other.valueSet,
               (SymbolKind a, SymbolKind b) => a == b) &&
           true;
@@ -17201,7 +17307,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceClientCapabilitiesWorkspaceEdit) {
+    if (other is WorkspaceClientCapabilitiesWorkspaceEdit &&
+        other.runtimeType == WorkspaceClientCapabilitiesWorkspaceEdit) {
       return documentChanges == other.documentChanges &&
           listEqual(resourceOperations, other.resourceOperations,
               (ResourceOperationKind a, ResourceOperationKind b) => a == b) &&
@@ -17335,9 +17442,12 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceEdit) {
-      return mapEqual(changes, other.changes,
-              (List<TextEdit> a, List<TextEdit> b) => a == b) &&
+    if (other is WorkspaceEdit && other.runtimeType == WorkspaceEdit) {
+      return mapEqual(
+              changes,
+              other.changes,
+              (List<TextEdit> a, List<TextEdit> b) =>
+                  listEqual(a, b, (TextEdit a, TextEdit b) => a == b)) &&
           documentChanges == other.documentChanges &&
           true;
     }
@@ -17433,7 +17543,7 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceFolder) {
+    if (other is WorkspaceFolder && other.runtimeType == WorkspaceFolder) {
       return uri == other.uri && name == other.name && true;
     }
     return false;
@@ -17540,7 +17650,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceFoldersChangeEvent) {
+    if (other is WorkspaceFoldersChangeEvent &&
+        other.runtimeType == WorkspaceFoldersChangeEvent) {
       return listEqual(added, other.added,
               (WorkspaceFolder a, WorkspaceFolder b) => a == b) &&
           listEqual(removed, other.removed,
@@ -17614,7 +17725,8 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is WorkspaceSymbolParams) {
+    if (other is WorkspaceSymbolParams &&
+        other.runtimeType == WorkspaceSymbolParams) {
       return query == other.query && true;
     }
     return false;
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 61ffb29..916bcf7 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -102,8 +102,7 @@
   if (element is engine.ClassElement) {
     if (element.isEnum) {
       return ElementKind.ENUM;
-    }
-    if (element.isMixin) {
+    } else if (element.isMixin) {
       return ElementKind.MIXIN;
     }
   }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index ffb863f7..bcc76e2 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -26,17 +26,13 @@
 import 'package:analysis_server/src/domain_execution.dart';
 import 'package:analysis_server/src/domain_kythe.dart';
 import 'package:analysis_server/src/domain_server.dart';
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
-import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analysis_server/src/flutter/flutter_domain.dart';
 import 'package:analysis_server/src/flutter/flutter_notifications.dart';
 import 'package:analysis_server/src/operation/operation_analysis.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
-import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analysis_server/src/plugin/plugin_watcher.dart';
 import 'package:analysis_server/src/protocol_server.dart' as server;
 import 'package:analysis_server/src/search/search_domain.dart';
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
@@ -46,32 +42,23 @@
 import 'package:analysis_server/src/server/features.dart';
 import 'package:analysis_server/src/server/sdk_configuration.dart';
 import 'package:analysis_server/src/services/flutter/widget_descriptions.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analysis_server/src/utilities/file_string_sink.dart';
-import 'package:analysis_server/src/utilities/null_string_sink.dart';
 import 'package:analysis_server/src/utilities/request_statistics.dart';
-import 'package:analysis_server/src/utilities/tee_string_sink.dart';
-import 'package:analyzer/dart/analysis/features.dart' as analyzer_features;
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/overlay_file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 import 'package:telemetry/crash_reporting.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
 import 'package:watcher/watcher.dart';
@@ -85,17 +72,6 @@
   /// be sent.
   final ServerCommunicationChannel channel;
 
-  /// The object used to manage sending a subset of notifications to the client.
-  /// The subset of notifications are those to which plugins may contribute.
-  /// This field is `null` when the new plugin support is disabled.
-  NotificationManager notificationManager;
-
-  /// The object used to manage the execution of plugins.
-  PluginManager pluginManager;
-
-  /// The [SearchEngine] for this server, may be `null` if indexing is disabled.
-  SearchEngine searchEngine;
-
   /// A flag indicating the value of the 'analyzing' parameter sent in the last
   /// status message to the client.
   bool statusAnalyzing = false;
@@ -104,15 +80,6 @@
   /// server.
   List<RequestHandler> handlers;
 
-  /// The object used to manage the SDK's known to this server.
-  final DartSdkManager sdkManager;
-
-  /// The instrumentation service that is to be used by this analysis server.
-  final InstrumentationService instrumentationService;
-
-  /// The helper for tracking request / response statistics.
-  final RequestStatisticsHelper requestStatistics;
-
   /// A set of the [ServerService]s to send notifications for.
   Set<ServerService> serverServices = HashSet<ServerService>();
 
@@ -145,12 +112,6 @@
   /// `null`.
   Set<String> prevAnalyzedFiles;
 
-  /// The default options used to create new analysis contexts. This object is
-  /// also referenced by the ContextManager.
-  final AnalysisOptionsImpl defaultContextOptions = AnalysisOptionsImpl();
-
-  PerformanceLog _analysisPerformanceLogger;
-
   /// The controller for [onAnalysisSetChanged].
   final StreamController _onAnalysisSetChangedController =
       StreamController.broadcast(sync: true);
@@ -168,67 +129,29 @@
     this.channel,
     ResourceProvider baseResourceProvider,
     AnalysisServerOptions options,
-    this.sdkManager,
+    DartSdkManager sdkManager,
     CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
-    this.instrumentationService, {
-    this.requestStatistics,
+    InstrumentationService instrumentationService, {
+    RequestStatisticsHelper requestStatistics,
     DiagnosticServer diagnosticServer,
     this.detachableFileSystemManager,
-  }) : super(options, diagnosticServer, crashReportingAttachmentsBuilder,
-            baseResourceProvider) {
-    notificationManager = NotificationManager(channel, resourceProvider);
-
-    pluginManager = PluginManager(
-        resourceProvider,
-        _getByteStorePath(),
-        sdkManager.defaultSdkDirectory,
-        notificationManager,
-        instrumentationService);
-    var pluginWatcher = PluginWatcher(resourceProvider, pluginManager);
-
-    defaultContextOptions.contextFeatures =
-        analyzer_features.FeatureSet.fromEnableFlags(
-            options.enabledExperiments);
-    defaultContextOptions.generateImplicitErrors = false;
-    defaultContextOptions.useFastaParser = options.useFastaParser;
-
-    {
-      var name = options.newAnalysisDriverLog;
-      StringSink sink = NullStringSink();
-      if (name != null) {
-        if (name == 'stdout') {
-          sink = io.stdout;
-        } else if (name.startsWith('file:')) {
-          var path = name.substring('file:'.length);
-          sink = FileStringSink(path);
-        }
-      }
-      if (requestStatistics != null) {
-        sink = TeeStringSink(sink, requestStatistics.perfLoggerStringSink);
-      }
-      _analysisPerformanceLogger = PerformanceLog(sink);
-    }
-
-    byteStore = createByteStore(resourceProvider);
-
-    analysisDriverScheduler = nd.AnalysisDriverScheduler(
-        _analysisPerformanceLogger,
-        driverWatcher: pluginWatcher);
-    analysisDriverScheduler.status.listen(sendStatusNotificationNew);
-    analysisDriverScheduler.start();
-
-    if (options.featureSet.completion) {
-      declarationsTracker = DeclarationsTracker(byteStore, resourceProvider);
-      declarationsTrackerData = DeclarationsTrackerData(declarationsTracker);
-      analysisDriverScheduler.outOfBandWorker =
-          CompletionLibrariesWorker(declarationsTracker);
-    }
-
-    contextManager = ContextManagerImpl(resourceProvider, sdkManager,
-        analyzedFilesGlobs, instrumentationService, defaultContextOptions);
+  }) : super(
+          options,
+          sdkManager,
+          diagnosticServer,
+          crashReportingAttachmentsBuilder,
+          baseResourceProvider,
+          instrumentationService,
+          NotificationManager(channel, baseResourceProvider.pathContext),
+          requestStatistics: requestStatistics,
+        ) {
     var contextManagerCallbacks =
         ServerContextManagerCallbacks(this, resourceProvider);
     contextManager.callbacks = contextManagerCallbacks;
+
+    analysisDriverScheduler.status.listen(sendStatusNotificationNew);
+    analysisDriverScheduler.start();
+
     _onAnalysisStartedController = StreamController.broadcast();
     onAnalysisStarted.first.then((_) {
       onAnalysisComplete.then((_) {
@@ -236,7 +159,6 @@
         performance = performanceAfterStartup;
       });
     });
-    searchEngine = SearchEngineImpl(driverMap.values);
     var notification =
         ServerConnectedParams(PROTOCOL_VERSION, io.pid).toNotification();
     channel.sendNotification(notification);
@@ -664,22 +586,6 @@
 //    });
   }
 
-  /// Return the path to the location of the byte store on disk, or `null` if
-  /// there is no on-disk byte store.
-  String _getByteStorePath() {
-    ResourceProvider provider = resourceProvider;
-    if (provider is OverlayResourceProvider) {
-      provider = (provider as OverlayResourceProvider).baseProvider;
-    }
-    if (provider is PhysicalResourceProvider) {
-      var stateLocation = provider.getStateLocation('.analysis-driver');
-      if (stateLocation != null) {
-        return stateLocation.path;
-      }
-    }
-    return null;
-  }
-
   /// Returns `true` if there is a subscription for the given [service] and
   /// [file].
   bool _hasAnalysisServiceSubscription(AnalysisService service, String file) {
@@ -691,8 +597,6 @@
   }
 
   Future<void> _scheduleAnalysisImplementedNotification() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var files = analysisServices[AnalysisService.IMPLEMENTED];
     if (files != null) {
       scheduleImplementedNotification(this, files);
@@ -941,7 +845,7 @@
         resourceProvider, analysisServer.sdkManager, null,
         options: builderOptions);
     builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler;
-    builder.performanceLog = analysisServer._analysisPerformanceLogger;
+    builder.performanceLog = analysisServer.analysisPerformanceLogger;
     builder.byteStore = analysisServer.byteStore;
     builder.enableIndex = true;
     return builder;
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 93975bf..c7a9f65 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -4,15 +4,26 @@
 
 import 'dart:async';
 import 'dart:core';
+import 'dart:io' as io;
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/plugin/notification_manager.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analysis_server/src/plugin/plugin_watcher.dart';
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
 import 'package:analysis_server/src/server/diagnostic_server.dart';
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analysis_server/src/utilities/file_string_sink.dart';
+import 'package:analysis_server/src/utilities/null_string_sink.dart';
+import 'package:analysis_server/src/utilities/request_statistics.dart';
+import 'package:analysis_server/src/utilities/tee_string_sink.dart';
+import 'package:analyzer/dart/analysis/features.dart' as analyzer_features;
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -21,22 +32,26 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/file_byte_store.dart'
     show EvictingFileByteStore;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/util/glob.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
 
 /// Implementations of [AbstractAnalysisServer] implement a server that listens
 /// on a [CommunicationChannel] for analysis messages and process them.
-abstract class AbstractAnalysisServer {
+abstract class AbstractAnalysisServer implements DriverProvider {
   /// The options of this server instance.
   AnalysisServerOptions options;
 
@@ -47,6 +62,24 @@
   /// context directories.
   ContextManager contextManager;
 
+  /// The default options used to create new analysis contexts. This object is
+  /// also referenced by the ContextManager.
+  final AnalysisOptionsImpl defaultContextOptions = AnalysisOptionsImpl();
+
+  /// The object used to manage sending a subset of notifications to the client.
+  /// The subset of notifications are those to which plugins may contribute.
+  /// This field is `null` when the new plugin support is disabled.
+  NotificationManager notificationManager;
+
+  /// The object used to manage the execution of plugins.
+  PluginManager pluginManager;
+
+  /// The object used to manage the SDK's known to this server.
+  final DartSdkManager sdkManager;
+
+  /// The [SearchEngine] for this server, may be `null` if indexing is disabled.
+  SearchEngine searchEngine;
+
   ByteStore byteStore;
 
   nd.AnalysisDriverScheduler analysisDriverScheduler;
@@ -63,6 +96,9 @@
   /// server.
   final RecentBuffer<ServerException> exceptions = RecentBuffer(10);
 
+  /// The instrumentation service that is to be used by this analysis server.
+  InstrumentationService instrumentationService;
+
   /// Performance information after initial analysis is complete
   /// or `null` if the initial analysis is not yet complete
   ServerPerformance performanceAfterStartup;
@@ -75,6 +111,10 @@
   /// Performance information before initial analysis is complete.
   final ServerPerformance performanceDuringStartup = ServerPerformance();
 
+  RequestStatisticsHelper requestStatistics;
+
+  PerformanceLog analysisPerformanceLogger;
+
   /// The set of the files that are currently priority.
   final Set<String> priorityFiles = <String>{};
 
@@ -88,6 +128,7 @@
   ];
 
   /// The [ResourceProvider] using which paths are converted into [Resource]s.
+  @override
   final OverlayResourceProvider resourceProvider;
 
   /// The next modification stamp for a changed file in the [resourceProvider].
@@ -98,12 +139,63 @@
   List<Glob> _analyzedFilesGlobs;
 
   AbstractAnalysisServer(
-      this.options,
-      this.diagnosticServer,
-      this.crashReportingAttachmentsBuilder,
-      ResourceProvider baseResourceProvider)
-      : resourceProvider = OverlayResourceProvider(baseResourceProvider) {
+    this.options,
+    this.sdkManager,
+    this.diagnosticServer,
+    this.crashReportingAttachmentsBuilder,
+    ResourceProvider baseResourceProvider,
+    this.instrumentationService,
+    this.notificationManager, {
+    this.requestStatistics,
+  }) : resourceProvider = OverlayResourceProvider(baseResourceProvider) {
     performance = performanceDuringStartup;
+
+    pluginManager = PluginManager(
+        resourceProvider,
+        _getByteStorePath(),
+        sdkManager.defaultSdkDirectory,
+        notificationManager,
+        instrumentationService);
+    var pluginWatcher = PluginWatcher(resourceProvider, pluginManager);
+
+    defaultContextOptions.contextFeatures =
+        analyzer_features.FeatureSet.fromEnableFlags(
+            options.enabledExperiments);
+    defaultContextOptions.useFastaParser = options.useFastaParser;
+
+    {
+      var name = options.newAnalysisDriverLog;
+      StringSink sink = NullStringSink();
+      if (name != null) {
+        if (name == 'stdout') {
+          sink = io.stdout;
+        } else if (name.startsWith('file:')) {
+          var path = name.substring('file:'.length);
+          sink = FileStringSink(path);
+        }
+      }
+      if (requestStatistics != null) {
+        sink = TeeStringSink(sink, requestStatistics.perfLoggerStringSink);
+      }
+      analysisPerformanceLogger = PerformanceLog(sink);
+    }
+
+    byteStore = createByteStore(resourceProvider);
+
+    analysisDriverScheduler = nd.AnalysisDriverScheduler(
+        analysisPerformanceLogger,
+        driverWatcher: pluginWatcher);
+
+    if (options.featureSet.completion) {
+      declarationsTracker = DeclarationsTracker(byteStore, resourceProvider);
+      declarationsTrackerData = DeclarationsTrackerData(declarationsTracker);
+      analysisDriverScheduler.outOfBandWorker =
+          CompletionLibrariesWorker(declarationsTracker);
+    }
+
+    contextManager = ContextManagerImpl(resourceProvider, sdkManager,
+        analyzedFilesGlobs, instrumentationService, defaultContextOptions);
+    searchEngine = SearchEngineImpl(driverMap.values);
   }
 
   /// Return a list of the globs used to determine which files should be
@@ -192,6 +284,10 @@
     return null;
   }
 
+  @override
+  AnalysisSession getAnalysisSession(String path) =>
+      getAnalysisDriver(path).currentSession;
+
   DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
     return declarationsTracker
             ?.getContext(result.session.analysisContext)
@@ -203,8 +299,6 @@
   /// [offset] of the given [file], or with `null` if there is no node at the
   /// [offset] or the node does not have an element.
   Future<Element> getElementAtOffset(String file, int offset) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (!priorityFiles.contains(file)) {
       var driver = getAnalysisDriver(file);
       if (driver == null) {
@@ -252,8 +346,6 @@
   /// given [offset] of the given [file], or with `null` if there is no node as
   /// the [offset].
   Future<AstNode> getNodeAtOffset(String file, int offset) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = await getResolvedUnit(file);
     var unit = result?.unit;
     if (unit != null) {
@@ -333,4 +425,20 @@
     declarationsTracker?.discardContext(driver.analysisContext);
     declarationsTracker?.addContext(driver.analysisContext);
   }
+
+  /// Return the path to the location of the byte store on disk, or `null` if
+  /// there is no on-disk byte store.
+  String _getByteStorePath() {
+    ResourceProvider provider = resourceProvider;
+    if (provider is OverlayResourceProvider) {
+      provider = (provider as OverlayResourceProvider).baseProvider;
+    }
+    if (provider is PhysicalResourceProvider) {
+      var stateLocation = provider.getStateLocation('.analysis-driver');
+      if (stateLocation != null) {
+        return stateLocation.path;
+      }
+    }
+    return null;
+  }
 }
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 1684533..beb2d8e 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -49,8 +49,6 @@
 
   @override
   Future<Response> sendRequest(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var id = request.id;
     output.write(json.encode(request.toJson()) + '\n');
     return await responseStream
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
new file mode 100644
index 0000000..d44effd
--- /dev/null
+++ b/pkg/analysis_server/lib/src/cider/completion.dart
@@ -0,0 +1,288 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+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';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart' show LibraryElement;
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
+import 'package:analyzer/src/test_utilities/function_ast_visitor.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:meta/meta.dart';
+
+/// The cache that can be reuse for across multiple completion request.
+///
+/// It contains data that is relatively small, and does not include for
+/// example types and elements.
+class CiderCompletionCache {
+  final Map<String, _CiderImportedLibrarySuggestions> _importedLibraries = {};
+  _LastCompletionResult _lastResult;
+}
+
+class CiderCompletionComputer {
+  final PerformanceLog _logger;
+  final CiderCompletionCache _cache;
+  final FileResolver _fileResolver;
+
+  DartCompletionRequestImpl _dartCompletionRequest;
+
+  /// Paths of imported libraries for which suggestions were (re)computed
+  /// during processing of this request. Does not include libraries that were
+  /// processed during previous requests, and reused from the cache now.
+  @visibleForTesting
+  final List<String> computedImportedLibraries = [];
+
+  CiderCompletionComputer(this._logger, this._cache, this._fileResolver);
+
+  @deprecated
+  Future<List<CompletionSuggestion>> compute(String path, int offset) async {
+    var fileContext = _fileResolver.getFileContext(path);
+    var file = fileContext.file;
+
+    var location = file.lineInfo.getLocation(offset);
+
+    var result = await compute2(
+      path: path,
+      line: location.lineNumber - 1,
+      column: location.columnNumber - 1,
+    );
+
+    return result.suggestions;
+  }
+
+  /// Return completion suggestions for the file and position.
+  ///
+  /// The [path] must be the absolute and normalized path of the file.
+  ///
+  /// The content of the file has already been updated.
+  ///
+  /// The [line] and [column] are zero based.
+  Future<CiderCompletionResult> compute2({
+    @required String path,
+    @required int line,
+    @required int column,
+  }) async {
+    var fileContext = _logger.run('Get file $path', () {
+      return _fileResolver.getFileContext(path);
+    });
+
+    var file = fileContext.file;
+
+    var resolvedSignature = _logger.run('Get signature', () {
+      return file.resolvedSignature;
+    });
+
+    var lineInfo = file.lineInfo;
+    var offset = lineInfo.getOffsetOfLine(line) + column;
+
+    // If the same file, in the same state as the last time, reuse the result.
+    var lastResult = _cache._lastResult;
+    if (lastResult != null &&
+        lastResult.path == path &&
+        lastResult.signature == resolvedSignature &&
+        lastResult.offset == offset) {
+      _logger.writeln('Use the last completion result.');
+      return lastResult.result;
+    }
+
+    var resolvedUnit = _fileResolver.resolve(path);
+
+    var completionRequest = CompletionRequestImpl(
+      resolvedUnit,
+      offset,
+      false,
+      CompletionPerformance(),
+    );
+    var dartdocDirectiveInfo = DartdocDirectiveInfo();
+
+    var suggestions = await _logger.runAsync('Compute suggestions', () async {
+      var includedElementKinds = <ElementKind>{};
+      var includedElementNames = <String>{};
+      var includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+
+      var manager = DartCompletionManager(
+        dartdocDirectiveInfo: dartdocDirectiveInfo,
+        includedElementKinds: includedElementKinds,
+        includedElementNames: includedElementNames,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+      );
+
+      return await manager.computeSuggestions(completionRequest);
+    });
+
+    _dartCompletionRequest = await DartCompletionRequestImpl.from(
+      completionRequest,
+      dartdocDirectiveInfo,
+    );
+
+    if (_dartCompletionRequest.includeIdentifiers) {
+      _logger.run('Add imported suggestions', () {
+        suggestions.addAll(
+          _importedLibrariesSuggestions(
+            resolvedUnit.libraryElement,
+          ),
+        );
+      });
+    }
+
+    _logger.run('Filter suggestions', () {
+      suggestions = _FilterSort(
+        _dartCompletionRequest,
+        suggestions,
+      ).perform();
+    });
+
+    var result = CiderCompletionResult._(suggestions);
+
+    _cache._lastResult =
+        _LastCompletionResult(path, resolvedSignature, offset, result);
+
+    return result;
+  }
+
+  /// Return suggestions from libraries imported into the [target].
+  ///
+  /// TODO(scheglov) Implement show / hide combinators.
+  /// TODO(scheglov) Implement prefixes.
+  List<CompletionSuggestion> _importedLibrariesSuggestions(
+    LibraryElement target,
+  ) {
+    var suggestions = <CompletionSuggestion>[];
+    for (var importedLibrary in target.importedLibraries) {
+      var importedSuggestions = _importedLibrarySuggestions(importedLibrary);
+      suggestions.addAll(importedSuggestions);
+    }
+    return suggestions;
+  }
+
+  /// Return cached, or compute unprefixed suggestions for all elements
+  /// exported from the library.
+  List<CompletionSuggestion> _importedLibrarySuggestions(
+    LibraryElement element,
+  ) {
+    var path = element.source.fullName;
+    var signature = _fileResolver.getLibraryLinkedSignature(path);
+
+    var cacheEntry = _cache._importedLibraries[path];
+    if (cacheEntry == null || cacheEntry.signature != signature) {
+      computedImportedLibraries.add(path);
+      var suggestions = _librarySuggestions(element);
+      cacheEntry = _CiderImportedLibrarySuggestions(
+        signature,
+        suggestions,
+      );
+      _cache._importedLibraries[path] = cacheEntry;
+    }
+    return cacheEntry.suggestions;
+  }
+
+  /// Compute all unprefixed suggestions for all elements exported from
+  /// the library.
+  List<CompletionSuggestion> _librarySuggestions(LibraryElement element) {
+    var visitor = LibraryElementSuggestionBuilder(_dartCompletionRequest, '');
+    var exportMap = element.exportNamespace.definedNames;
+    for (var definedElement in exportMap.values) {
+      definedElement.accept(visitor);
+    }
+    return visitor.suggestions;
+  }
+}
+
+class CiderCompletionResult {
+  final List<CompletionSuggestion> suggestions;
+
+  CiderCompletionResult._(this.suggestions);
+}
+
+class _CiderImportedLibrarySuggestions {
+  final String signature;
+  final List<CompletionSuggestion> suggestions;
+
+  _CiderImportedLibrarySuggestions(this.signature, this.suggestions);
+}
+
+class _FilterSort {
+  final DartCompletionRequestImpl _request;
+  final List<CompletionSuggestion> _suggestions;
+
+  FuzzyMatcher _matcher;
+
+  _FilterSort(this._request, this._suggestions);
+
+  List<CompletionSuggestion> perform() {
+    var pattern = _matchingPattern();
+    _matcher = FuzzyMatcher(pattern, matchStyle: MatchStyle.SYMBOL);
+
+    var scored = _suggestions
+        .map((e) => _FuzzyScoredSuggestion(e, _score(e)))
+        .where((e) => e.score > 0)
+        .toList();
+
+    scored.sort((a, b) {
+      // Prefer what the user requested by typing.
+      if (a.score > b.score) {
+        return -1;
+      } else if (a.score < b.score) {
+        return 1;
+      }
+
+      // Then prefer what is more relevant in the context.
+      if (a.suggestion.relevance != b.suggestion.relevance) {
+        return -(a.suggestion.relevance - b.suggestion.relevance);
+      }
+
+      // Other things being equal, sort by name.
+      return a.suggestion.completion.compareTo(b.suggestion.completion);
+    });
+
+    return scored.map((e) => e.suggestion).toList();
+  }
+
+  /// Return the pattern to match suggestions against, from the identifier
+  /// to the left of the caret. Return the empty string if cannot find the
+  /// identifier.
+  String _matchingPattern() {
+    SimpleIdentifier patternNode;
+    _request.target.containingNode.accept(
+      FunctionAstVisitor(simpleIdentifier: (node) {
+        if (node.end == _request.offset) {
+          patternNode = node;
+        }
+      }),
+    );
+
+    if (patternNode != null) {
+      return patternNode.name;
+    }
+
+    return '';
+  }
+
+  double _score(CompletionSuggestion e) => _matcher.score(e.completion);
+}
+
+/// [CompletionSuggestion] scored using [FuzzyMatcher].
+class _FuzzyScoredSuggestion {
+  final CompletionSuggestion suggestion;
+  final double score;
+
+  _FuzzyScoredSuggestion(this.suggestion, this.score);
+}
+
+class _LastCompletionResult {
+  final String path;
+  final String signature;
+  final int offset;
+  final CiderCompletionResult result;
+
+  _LastCompletionResult(this.path, this.signature, this.offset, this.result);
+}
diff --git a/pkg/analysis_server/lib/src/cider/fixes.dart b/pkg/analysis_server/lib/src/cider/fixes.dart
new file mode 100644
index 0000000..5a19221
--- /dev/null
+++ b/pkg/analysis_server/lib/src/cider/fixes.dart
@@ -0,0 +1,66 @@
+// 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/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';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:meta/meta.dart';
+
+class CiderErrorFixes {
+  final AnalysisError error;
+
+  /// The fixes for the [error], might be empty.
+  final List<Fix> fixes;
+
+  CiderErrorFixes({
+    @required this.error,
+    @required this.fixes,
+  });
+}
+
+class CiderFixesComputer {
+  final PerformanceLog _logger;
+  final FileResolver _fileResolver;
+
+  CiderFixesComputer(this._logger, this._fileResolver);
+
+  /// Compute quick fixes for errors on the line with the [offset].
+  Future<List<CiderErrorFixes>> compute(String path, int offset) async {
+    var result = <CiderErrorFixes>[];
+    var resolvedUnit = _fileResolver.resolve(path);
+
+    var lineInfo = resolvedUnit.lineInfo;
+    var requestLine = lineInfo.getLocation(offset).lineNumber;
+
+    await _logger.runAsync('Compute fixes', () async {
+      for (var error in resolvedUnit.errors) {
+        var errorLine = lineInfo.getLocation(error.offset).lineNumber;
+        if (errorLine == requestLine) {
+          var workspace = DartChangeWorkspace([resolvedUnit.session]);
+          var context = DartFixContextImpl(
+            workspace,
+            resolvedUnit,
+            error,
+            (name) => const [],
+          );
+
+          var fixes = await DartFixContributor().computeFixes(context);
+          fixes.sort(Fix.SORT_BY_RELEVANCE);
+
+          result.add(
+            CiderErrorFixes(error: error, fixes: fixes),
+          );
+        }
+      }
+    });
+
+    return result;
+  }
+}
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 0bab64a..6383a22 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -38,8 +38,6 @@
   /// imported into the library at the given [path].
   Future<SourceChange> createEdits(
       List<ImportedElements> importedElementsList) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var filteredImportedElements =
         _filterImportedElements(importedElementsList);
     var libraryElement = libraryResult.libraryElement;
diff --git a/pkg/analysis_server/lib/src/computer/new_notifications.dart b/pkg/analysis_server/lib/src/computer/new_notifications.dart
index 31f80848..e44abed 100644
--- a/pkg/analysis_server/lib/src/computer/new_notifications.dart
+++ b/pkg/analysis_server/lib/src/computer/new_notifications.dart
@@ -4,12 +4,12 @@
 
 import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
 import 'package:analysis_server/src/analysis_server.dart' show AnalysisServer;
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 
 void new_sendDartNotificationNavigation(
     AnalysisServer analysisServer, ResolvedUnitResult result) {
diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/domain_abstract.dart
index 1bf5c678..a2c28e2 100644
--- a/pkg/analysis_server/lib/src/domain_abstract.dart
+++ b/pkg/analysis_server/lib/src/domain_abstract.dart
@@ -7,6 +7,7 @@
 import 'dart:math' as math;
 
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/analysis_server_abstract.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
@@ -15,13 +16,21 @@
 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
 
 /// An abstract implementation of a request handler.
-abstract class AbstractRequestHandler implements RequestHandler {
+abstract class AbstractRequestHandler
+    with RequestHandlerMixin<AnalysisServer>
+    implements RequestHandler {
   /// The analysis server that is using this handler to process requests.
+  @override
   final AnalysisServer server;
 
   /// Initialize a newly created request handler to be associated with the given
   /// analysis [server].
   AbstractRequestHandler(this.server);
+}
+
+mixin RequestHandlerMixin<T extends AbstractAnalysisServer> {
+  /// The analysis server that is using this handler to process requests.
+  T get server;
 
   /// Given a mapping from plugins to futures that will complete when the plugin
   /// has responded to a request, wait for a finite amount of time for each of
@@ -34,8 +43,6 @@
       Map<PluginInfo, Future<plugin.Response>> futures,
       {plugin.RequestParams requestParameters,
       int timeout = 500}) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // TODO(brianwilkerson) requestParameters might need to be required.
     var endTime = DateTime.now().millisecondsSinceEpoch + timeout;
     var responses = <plugin.Response>[];
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 6351adc..f6b02a4 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -11,7 +11,6 @@
 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/domains/analysis/navigation_dart.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';
@@ -24,6 +23,7 @@
 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 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;
@@ -57,8 +57,6 @@
 
   /// Implement the `analysis.getHover` request.
   Future<void> getHover(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = AnalysisGetHoverParams.fromRequest(request);
     var file = params.file;
 
@@ -87,8 +85,6 @@
 
   /// Implement the `analysis.getImportedElements` request.
   Future<void> getImportedElements(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = AnalysisGetImportedElementsParams.fromRequest(request);
     var file = params.file;
 
@@ -147,8 +143,6 @@
 
   /// Implement the `analysis.getNavigation` request.
   Future<void> getNavigation(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = AnalysisGetNavigationParams.fromRequest(request);
     var file = params.file;
     var offset = params.offset;
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 5eff309..d9ffaca 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -69,8 +69,6 @@
     Set<String> includedElementNames,
     List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
   ) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     //
     // Allow plugins to start computing fixes.
     //
@@ -93,6 +91,7 @@
       performance.logStartTime(COMPUTE_SUGGESTIONS_TAG);
 
       var manager = DartCompletionManager(
+        dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(request.result),
         includedElementKinds: includedElementKinds,
         includedElementNames: includedElementNames,
         includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
index a7faff3..f095fba 100644
--- a/pkg/analysis_server/lib/src/domain_diagnostic.dart
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.dart
@@ -37,8 +37,6 @@
 
   /// Answer the `diagnostic.getServerPort` request.
   Future handleGetServerPort(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     try {
       // Open a port (or return the existing one).
       var port = await server.diagnosticServer.getServerPort();
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index c22eec5..2e75ddd 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -46,8 +46,6 @@
 
   /// Implement the 'execution.getSuggestions' request.
   void getSuggestions(Request request) async {
-//    // TODO(brianwilkerson) Determine whether this await is necessary.
-//    await null;
 //    var params = new ExecutionGetSuggestionsParams.fromRequest(request);
 //    var computer = new RuntimeCompletionComputer(
 //        server.resourceProvider,
diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart
index 357e1ae..2937a4d 100644
--- a/pkg/analysis_server/lib/src/domain_kythe.dart
+++ b/pkg/analysis_server/lib/src/domain_kythe.dart
@@ -28,8 +28,6 @@
 
   /// Implement the `kythe.getKytheEntries` request.
   Future<void> getKytheEntries(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var file = KytheGetKytheEntriesParams.fromRequest(request).file;
     var driver = server.getAnalysisDriver(file);
     if (driver == null) {
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
deleted file mode 100644
index d9b9a3b..0000000
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
-
-NavigationCollector computeDartNavigation(
-    ResourceProvider resourceProvider,
-    NavigationCollector collector,
-    CompilationUnit unit,
-    int offset,
-    int length) {
-  var dartCollector = _DartNavigationCollector(collector);
-  var visitor = _DartNavigationComputerVisitor(resourceProvider, dartCollector);
-  if (offset == null || length == null) {
-    unit.accept(visitor);
-  } else {
-    var node = _getNodeForRange(unit, offset, length);
-    node?.accept(visitor);
-  }
-  return collector;
-}
-
-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) {
-      return n;
-    }
-  }
-  return node;
-}
-
-/// A Dart specific wrapper around [NavigationCollector].
-class _DartNavigationCollector {
-  final NavigationCollector collector;
-
-  _DartNavigationCollector(this.collector);
-
-  void _addRegion(int offset, int length, Element element) {
-    if (element is FieldFormalParameterElement) {
-      element = (element as FieldFormalParameterElement).field;
-    }
-    if (element == null || element == DynamicElementImpl.instance) {
-      return;
-    }
-    if (element.location == null) {
-      return;
-    }
-    var kind = protocol.convertElementKind(element.kind);
-    var location = protocol.newLocation_fromElement(element);
-    if (location == null) {
-      return;
-    }
-    collector.addRegion(offset, length, kind, location);
-  }
-
-  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) {
-    if (node == null) {
-      return;
-    }
-    var offset = node.offset;
-    var length = node.length;
-    _addRegion(offset, length, element);
-  }
-
-  void _addRegionForToken(Token token, Element element) {
-    var offset = token.offset;
-    var length = token.length;
-    _addRegion(offset, length, element);
-  }
-}
-
-class _DartNavigationComputerVisitor extends RecursiveAstVisitor<void> {
-  final ResourceProvider resourceProvider;
-  final _DartNavigationCollector computer;
-
-  _DartNavigationComputerVisitor(this.resourceProvider, this.computer);
-
-  @override
-  void visitAnnotation(Annotation node) {
-    var element = node.element;
-    if (element is ConstructorElement && element.isSynthetic) {
-      element = element.enclosingElement;
-    }
-    var name = node.name;
-    if (name is PrefixedIdentifier) {
-      // use constructor in: @PrefixClass.constructorName
-      var prefixElement = name.prefix.staticElement;
-      if (prefixElement is ClassElement) {
-        prefixElement = element;
-      }
-      computer._addRegionForNode(name.prefix, prefixElement);
-      // always constructor
-      computer._addRegionForNode(name.identifier, element);
-    } else {
-      computer._addRegionForNode(name, element);
-    }
-    computer._addRegionForNode(node.constructorName, element);
-    // arguments
-    node.arguments?.accept(this);
-  }
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    node.leftHandSide?.accept(this);
-    computer._addRegionForToken(node.operator, node.staticElement);
-    node.rightHandSide?.accept(this);
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    node.leftOperand?.accept(this);
-    computer._addRegionForToken(node.operator, node.staticElement);
-    node.rightOperand?.accept(this);
-  }
-
-  @override
-  void visitCompilationUnit(CompilationUnit unit) {
-    // prepare top-level nodes sorted by their offsets
-    var nodes = <AstNode>[];
-    nodes.addAll(unit.directives);
-    nodes.addAll(unit.declarations);
-    nodes.sort((a, b) {
-      return a.offset - b.offset;
-    });
-    // visit sorted nodes
-    for (var node in nodes) {
-      node.accept(this);
-    }
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    // associate constructor with "T" or "T.name"
-    {
-      AstNode firstNode = node.returnType;
-      AstNode lastNode = node.name;
-      lastNode ??= firstNode;
-      if (firstNode != null && lastNode != null) {
-        computer._addRegion_nodeStart_nodeEnd(
-            firstNode, lastNode, node.declaredElement);
-      }
-    }
-    super.visitConstructorDeclaration(node);
-  }
-
-  @override
-  void visitConstructorName(ConstructorName node) {
-    var parent = node.parent;
-    if (parent is InstanceCreationExpression &&
-        parent.constructorName == node) {
-      _addConstructorName(parent, node);
-    } else if (parent is ConstructorDeclaration &&
-        parent.redirectedConstructor == node) {
-      _addConstructorName(node, node);
-    }
-  }
-
-  @override
-  void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    if (node.type == null) {
-      var token = node.keyword;
-      if (token?.keyword == Keyword.VAR) {
-        var inferredType = node.declaredElement?.type;
-        var element = inferredType?.element;
-        if (element != null) {
-          computer._addRegionForToken(token, element);
-        }
-      }
-    }
-    super.visitDeclaredIdentifier(node);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    ExportElement exportElement = node.element;
-    if (exportElement != null) {
-      Element libraryElement = exportElement.exportedLibrary;
-      _addUriDirectiveRegion(node, libraryElement);
-    }
-    super.visitExportDirective(node);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    ImportElement importElement = node.element;
-    if (importElement != null) {
-      Element libraryElement = importElement.importedLibrary;
-      _addUriDirectiveRegion(node, libraryElement);
-    }
-    super.visitImportDirective(node);
-  }
-
-  @override
-  void visitIndexExpression(IndexExpression node) {
-    super.visitIndexExpression(node);
-    var element = node.staticElement;
-    computer._addRegionForToken(node.leftBracket, element);
-    computer._addRegionForToken(node.rightBracket, element);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    computer._addRegionForNode(node.name, node.element);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    _addUriDirectiveRegion(node, node.element);
-    super.visitPartDirective(node);
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    computer._addRegionForNode(node.libraryName, node.element);
-    super.visitPartOfDirective(node);
-  }
-
-  @override
-  void visitPostfixExpression(PostfixExpression node) {
-    super.visitPostfixExpression(node);
-    computer._addRegionForToken(node.operator, node.staticElement);
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    computer._addRegionForToken(node.operator, node.staticElement);
-    super.visitPrefixExpression(node);
-  }
-
-  @override
-  void visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    Element element = node.staticElement;
-    if (element != null && element.isSynthetic) {
-      element = element.enclosingElement;
-    }
-    // add region
-    computer._addRegionForToken(node.thisKeyword, element);
-    computer._addRegionForNode(node.constructorName, element);
-    // process arguments
-    node.argumentList?.accept(this);
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (node.parent is ConstructorDeclaration) {
-      return;
-    }
-    var element = node.staticElement;
-    computer._addRegionForNode(node, element);
-  }
-
-  @override
-  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    Element element = node.staticElement;
-    if (element != null && element.isSynthetic) {
-      element = element.enclosingElement;
-    }
-    // add region
-    computer._addRegionForToken(node.superKeyword, element);
-    computer._addRegionForNode(node.constructorName, element);
-    // process arguments
-    node.argumentList?.accept(this);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    /// 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;
-      if (firstElement == null) {
-        return null;
-      }
-      for (var i = 1; i < variables.length; i++) {
-        var element = variables[1].declaredElement.type?.element;
-        if (element != firstElement) {
-          return null;
-        }
-      }
-      return firstElement;
-    }
-
-    if (node.type == null) {
-      var token = node.keyword;
-      if (token?.keyword == Keyword.VAR) {
-        var element = getCommonElement(node.variables);
-        if (element != null) {
-          computer._addRegionForToken(token, element);
-        }
-      }
-    }
-    super.visitVariableDeclarationList(node);
-  }
-
-  void _addConstructorName(AstNode parent, ConstructorName node) {
-    Element element = node.staticElement;
-    if (element == null) {
-      return;
-    }
-    // if a synthetic constructor, navigate to the class
-    if (element.isSynthetic) {
-      element = element.enclosingElement;
-    }
-    // add regions
-    var typeName = node.type;
-    // [prefix].ClassName
-    {
-      var name = typeName.name;
-      var className = name;
-      if (name is PrefixedIdentifier) {
-        name.prefix.accept(this);
-        className = name.identifier;
-      }
-      computer._addRegionForNode(className, element);
-    }
-    // <TypeA, TypeB>
-    var typeArguments = typeName.typeArguments;
-    if (typeArguments != null) {
-      typeArguments.accept(this);
-    }
-    // optional "name"
-    if (node.name != null) {
-      computer._addRegionForNode(node.name, element);
-    }
-  }
-
-  /// 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) {
-    var source = element?.source;
-    if (source != null) {
-      if (resourceProvider.getResource(source.fullName).exists) {
-        computer._addRegionForNode(node.uri, element);
-      }
-    }
-  }
-}
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 1b62c51..79e549c 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -71,18 +71,24 @@
   }
 }
 
+protocol.CompletionAvailableSuggestionsParams
+    createCompletionAvailableSuggestions(
+  List<Library> changed,
+  List<int> removed,
+) =>
+        protocol.CompletionAvailableSuggestionsParams(
+          changedLibraries: changed.map((library) {
+            return _protocolAvailableSuggestionSet(library);
+          }).toList(),
+          removedLibraries: removed,
+        );
+
 /// Convert the [LibraryChange] into the corresponding protocol notification.
 protocol.Notification createCompletionAvailableSuggestionsNotification(
   List<Library> changed,
   List<int> removed,
-) {
-  return protocol.CompletionAvailableSuggestionsParams(
-    changedLibraries: changed.map((library) {
-      return _protocolAvailableSuggestionSet(library);
-    }).toList(),
-    removedLibraries: removed,
-  ).toNotification();
-}
+) =>
+    createCompletionAvailableSuggestions(changed, removed).toNotification();
 
 /// Compute existing imports and elements that they provide.
 protocol.Notification createExistingImportsNotification(
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index 5839530..35b320a 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -44,8 +44,6 @@
       this.expressions);
 
   Future<RuntimeCompletionResult> compute() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var contextResult = await analysisDriver.getResult(contextPath);
     var session = contextResult.session;
 
@@ -84,7 +82,9 @@
       targetResult = await analysisDriver.getResult(contextPath);
     });
 
-    CompletionContributor contributor = DartCompletionManager();
+    CompletionContributor contributor = DartCompletionManager(
+        // dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(targetResult)
+        );
     var request = CompletionRequestImpl(
       targetResult,
       targetOffset,
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index d063871..82bb849 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -251,6 +251,7 @@
   }
 
   Future<bool> rerunTasks([List<String> changedPaths]) async {
+    listener.reset();
     if (changedPaths == null) {
       final drivers = <AnalysisDriver>{};
       for (var path in getPathsToProcess()) {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 316164d..862fd83 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -165,8 +165,6 @@
   }
 
   Future getAssists(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = EditGetAssistsParams.fromRequest(request);
     var file = params.file;
     var offset = params.offset;
@@ -287,8 +285,6 @@
   }
 
   Future getPostfixCompletion(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     server.options.analytics?.sendEvent('edit', 'getPostfixCompletion');
 
     var params = EditGetPostfixCompletionParams.fromRequest(request);
@@ -319,9 +315,6 @@
   }
 
   Future getStatementCompletion(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     var params = EditGetStatementCompletionParams.fromRequest(request);
     var file = params.file;
 
@@ -396,9 +389,6 @@
 
   /// Implement the `edit.importElements` request.
   Future<void> importElements(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     var params = EditImportElementsParams.fromRequest(request);
     var file = params.file;
 
@@ -437,8 +427,6 @@
   }
 
   Future isPostfixCompletionApplicable(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = EditGetPostfixCompletionParams.fromRequest(request);
     var file = params.file;
 
@@ -475,8 +463,6 @@
   }
 
   Future<void> organizeDirectives(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     server.options.analytics?.sendEvent('edit', 'organizeDirectives');
 
     var params = EditOrganizeDirectivesParams.fromRequest(request);
@@ -516,8 +502,6 @@
   }
 
   Future<void> sortMembers(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = EditSortMembersParams.fromRequest(request);
     var file = params.file;
 
@@ -922,8 +906,6 @@
     }
 
     runZonedGuarded(() async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       await _init(params.kind, file, params.offset, params.length);
       if (initStatus.hasFatalError) {
         feedback = null;
@@ -1013,8 +995,6 @@
   /// parameters. The existing [Refactoring] is reused or created as needed.
   Future _init(
       RefactoringKind kind, String file, int offset, int length) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // check if we can continue with the existing Refactoring instance
     if (this.kind == kind &&
         this.file == file &&
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 23ca3f4..80f3f5a 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -63,6 +63,9 @@
   LintFixInfo.preferAdjacentStringConcatenation,
   LintFixInfo.preferCollectionLiterals,
   LintFixInfo.preferConditionalAssignment,
+  LintFixInfo.preferConstConstructors,
+  LintFixInfo.preferConstConstructorsInImmutables,
+  LintFixInfo.preferConstDeclarations,
   LintFixInfo.preferContains,
   LintFixInfo.preferEqualForDefaultValues,
   LintFixInfo.preferFinalFields,
@@ -322,6 +325,24 @@
     isPedantic: true,
   );
 
+  static final preferConstConstructors = LintFixInfo(
+    'prefer_const_constructors',
+    DartFixKind.ADD_CONST,
+    'Make the instantiation const.',
+  );
+
+  static final preferConstConstructorsInImmutables = LintFixInfo(
+    'prefer_const_constructors_in_immutables',
+    DartFixKind.ADD_CONST,
+    'Make the constructor const.',
+  );
+
+  static final preferConstDeclarations = LintFixInfo(
+    'prefer_const_declarations',
+    DartFixKind.REPLACE_FINAL_WITH_CONST,
+    'Make the declaration const.',
+  );
+
   static final preferContains = LintFixInfo(
     'prefer_contains',
     DartFixKind.CONVERT_TO_CONTAINS,
@@ -423,7 +444,7 @@
   static final preferSingleQuotes = LintFixInfo(
     'prefer_single_quotes',
     DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING,
-    'Convert strings using a dobule quote to use a single quote.',
+    'Convert strings using a double quote to use a single quote.',
     isPedantic: true,
   );
 
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 aad1d10..ca028f7 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
@@ -8,13 +8,17 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show Location, SourceChange, SourceEdit, SourceFileEdit;
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
 
 /// Tasks use this API to report results.
-class DartFixListener {
+class DartFixListener implements DartFixListenerInterface {
+  @override
   final AnalysisServer server;
 
   final List<DartFixSuggestion> suggestions = <DartFixSuggestion>[];
   final List<DartFixSuggestion> otherSuggestions = <DartFixSuggestion>[];
+
+  @override
   final SourceChange sourceChange = SourceChange('dartfix');
 
   /// The details to be returned to the client.
@@ -24,6 +28,7 @@
 
   /// Add the given [detail] to the list of details to be returned to the
   /// client.
+  @override
   void addDetail(String detail) {
     if (details.length < 200) {
       details.add(detail);
@@ -34,11 +39,13 @@
   ///
   /// The associated suggestion should be separately added by calling
   /// [addSuggestion].
+  @override
   void addEditWithoutSuggestion(Source source, SourceEdit edit) {
     sourceChange.addEdit(source.fullName, -1, edit);
   }
 
   /// Record a recommendation to be sent to the client.
+  @override
   void addRecommendation(String description, [Location location]) {
     otherSuggestions.add(DartFixSuggestion(description, location: location));
   }
@@ -64,6 +71,7 @@
   }
 
   /// Record a source change to be sent to the client.
+  @override
   void addSourceFileEdit(
       String description, Location location, SourceFileEdit fileEdit) {
     suggestions.add(DartFixSuggestion(description, location: location));
@@ -76,6 +84,7 @@
   ///
   /// The associated edits should be separately added by calling
   /// [addEditWithoutRecommendation].
+  @override
   void addSuggestion(String description, Location location) {
     suggestions.add(DartFixSuggestion(description, location: location));
   }
@@ -88,4 +97,15 @@
         result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
     return location;
   }
+
+  /// Reset this listener so that it can accrue a new set of changes.
+  void reset() {
+    suggestions.clear();
+    otherSuggestions.clear();
+    sourceChange
+      ..edits.clear()
+      ..linkedEditGroups.clear()
+      ..selection = null
+      ..id = null;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index 4d3b523..2b2f011 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -6,17 +6,19 @@
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/preview/http_preview_server.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:charcode/charcode.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/api_for_analysis_server/http_preview_server.dart';
+import 'package:nnbd_migration/api_for_analysis_server/instrumentation_listener.dart';
+import 'package:nnbd_migration/api_for_analysis_server/migration_state.dart';
+import 'package:nnbd_migration/api_for_analysis_server/nnbd_migration.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
 
@@ -28,7 +30,18 @@
   /// mature enough.
   static const bool _usePermissiveMode = true;
 
-  final DartFixListener listener;
+  // TODO(srawlins): Refactor to use
+  //  `Feature.non_nullable.firstSupportedVersion` when this becomes non-null.
+  static const String _intendedMinimumSdkVersion = '2.9.0';
+
+  static const String _intendedSdkVersionConstraint =
+      '>=$_intendedMinimumSdkVersion <2.10.0';
+
+  static final List<HttpPreviewServer> _allServers = [];
+
+  final int preferredPort;
+
+  final DartFixListenerInterface listener;
 
   /// The root of the included paths.
   ///
@@ -37,8 +50,11 @@
   /// which all included paths share.
   final String includedRoot;
 
+  /// Indicates whether the web preview of migration results should be launched.
+  final bool enablePreview;
+
   /// The HTTP server that serves the preview tool.
-  HttpPreviewServer server;
+  HttpPreviewServer _server;
 
   /// The port on which preview pages should be served, or `null` if no preview
   /// server should be started.
@@ -59,7 +75,13 @@
 
   Future<void> Function([List<String>]) rerunFunction;
 
-  NonNullableFix(this.listener, {List<String> included = const []})
+  /// A list of the URLs corresponding to the included roots.
+  List<String> previewUrls;
+
+  NonNullableFix(this.listener,
+      {List<String> included = const [],
+      this.preferredPort,
+      this.enablePreview = true})
       : includedRoot =
             _getIncludedRoot(included, listener.server.resourceProvider) {
     reset();
@@ -68,125 +90,127 @@
   @override
   int get numPhases => 3;
 
-  /// Return a list of the URLs corresponding to the included roots.
-  List<String> get previewUrls => [
+  @override
+  Future<void> finish() async {
+    final state = MigrationState(
+        migration, includedRoot, listener, instrumentationListener);
+    await state.refresh();
+
+    if (enablePreview && _server == null) {
+      _server = HttpPreviewServer(state, rerun, preferredPort);
+      _server.serveHttp();
+      _allServers.add(_server);
+      port = await _server.boundPort;
+      authToken = await _server.authToken;
+
+      previewUrls = [
+        // TODO(jcollins-g): Change protocol to only return a single string.
         Uri(
             scheme: 'http',
             host: 'localhost',
             port: port,
-            path: includedRoot,
+            path: state.pathMapper.map(includedRoot),
             queryParameters: {'authToken': authToken}).toString()
       ];
-
-  @override
-  Future<void> finish() async {
-    final state = MigrationState(
-        migration, includedRoot, listener, instrumentationListener, adapter);
-    await state.refresh();
-
-    if (server == null) {
-      server = HttpPreviewServer(state, rerun);
-      server.serveHttp();
-      port = await server.boundPort;
-      authToken = await server.authToken;
     }
   }
 
-  /// If the package contains an analysis_options.yaml file, then update the
-  /// file to enabled NNBD. If that file does not exist, but the package
-  /// contains a pubspec.yaml, then create the analysis_options.yaml file.
+  /// Update the pubspec.yaml file to specify a minimum Dart SDK version which
+  /// enables the Null Safety feature.
   @override
   Future<void> processPackage(Folder pkgFolder) async {
     if (!_packageIsNNBD) {
       return;
     }
 
-    // TODO(danrubel): Update pubspec.yaml to enable NNBD
-
-    var optionsFile = pkgFolder.getChildAssumingFile('analysis_options.yaml');
-    String optionsContent;
-    YamlNode optionsMap;
-    if (optionsFile.exists) {
-      try {
-        optionsContent = optionsFile.readAsStringSync();
-      } on FileSystemException catch (e) {
-        processYamlException('read', optionsFile.path, e);
-        return;
-      }
-      try {
-        optionsMap = loadYaml(optionsContent);
-      } on YamlException catch (e) {
-        processYamlException('parse', optionsFile.path, e);
-        return;
-      }
+    var pubspecFile = pkgFolder.getChildAssumingFile('pubspec.yaml');
+    String pubspecContent;
+    YamlNode pubspecMap;
+    if (!pubspecFile.exists) {
+      // TODO(srawlins): Handle other package types, such as Bazel.
+      return;
     }
 
-    SourceSpan parentSpan;
-    String content;
-    YamlNode analyzerOptions;
-    if (optionsMap is YamlMap) {
-      analyzerOptions = optionsMap.nodes[AnalyzerOptions.analyzer];
+    try {
+      pubspecContent = pubspecFile.readAsStringSync();
+    } on FileSystemException catch (e) {
+      processYamlException('read', pubspecFile.path, e);
+      return;
     }
-    if (analyzerOptions == null) {
-      var start = SourceLocation(0, line: 0, column: 0);
-      parentSpan = SourceSpan(start, start, '');
-      content = '''
-analyzer:
-  enable-experiment:
-    - non-nullable
-
-''';
-    } else if (analyzerOptions is YamlMap) {
-      var experiments = analyzerOptions.nodes[AnalyzerOptions.enableExperiment];
-      if (experiments == null) {
-        parentSpan = analyzerOptions.span;
-        content = '''
-
-  enable-experiment:
-    - non-nullable''';
-      } else if (experiments is YamlList) {
-        experiments.nodes.firstWhere(
-          (node) => node.span.text == EnableString.non_nullable,
-          orElse: () {
-            parentSpan = experiments.span;
-            content = '''
-
-    - non-nullable''';
-            return null;
-          },
-        );
-      }
+    try {
+      pubspecMap = loadYaml(pubspecContent);
+    } on YamlException catch (e) {
+      processYamlException('parse', pubspecFile.path, e);
+      return;
     }
 
-    if (parentSpan != null) {
-      final space = ' '.codeUnitAt(0);
-      final cr = '\r'.codeUnitAt(0);
-      final lf = '\n'.codeUnitAt(0);
-
+    /// Inserts [content] into [pubspecFile], immediately after [parentSpan].
+    void insertAfterParent(SourceSpan parentSpan, String content) {
       var line = parentSpan.end.line;
       var offset = parentSpan.end.offset;
+      // Walk [offset] and [line] back to the first non-whitespace character
+      // before [offset].
       while (offset > 0) {
-        var ch = optionsContent.codeUnitAt(offset - 1);
-        if (ch == space || ch == cr) {
+        var ch = pubspecContent.codeUnitAt(offset - 1);
+        if (ch == $space || ch == $cr) {
           --offset;
-        } else if (ch == lf) {
+        } else if (ch == $lf) {
           --offset;
           --line;
         } else {
           break;
         }
       }
+      var edit = SourceEdit(offset, 0, content);
       listener.addSourceFileEdit(
-          'enable non-nullable analysis',
-          Location(
-            optionsFile.path,
-            offset,
-            content.length,
-            line,
-            0,
-          ),
-          SourceFileEdit(optionsFile.path, 0,
-              edits: [SourceEdit(offset, 0, content)]));
+          'enable Null Safety language feature',
+          Location(pubspecFile.path, offset, content.length, line, 0),
+          SourceFileEdit(pubspecFile.path, 0, edits: [edit]));
+    }
+
+    void replaceSpan(SourceSpan span, String content) {
+      var line = span.start.line;
+      var offset = span.start.offset;
+      var edit = SourceEdit(offset, span.length, content);
+      listener.addSourceFileEdit(
+          'enable Null Safety language feature',
+          Location(pubspecFile.path, offset, content.length, line, 0),
+          SourceFileEdit(pubspecFile.path, 0, edits: [edit]));
+    }
+
+    YamlNode environmentOptions;
+    if (pubspecMap is YamlMap) {
+      environmentOptions = pubspecMap.nodes['environment'];
+    }
+    if (environmentOptions == null) {
+      var start = SourceLocation(0, line: 0, column: 0);
+      var content = '''
+environment:
+  sdk: '$_intendedSdkVersionConstraint'
+
+''';
+      insertAfterParent(SourceSpan(start, start, ''), content);
+    } else if (environmentOptions is YamlMap) {
+      var sdk = environmentOptions.nodes['sdk'];
+      if (sdk == null) {
+        var content = """
+
+  sdk: '$_intendedSdkVersionConstraint'""";
+        insertAfterParent(environmentOptions.span, content);
+      } else if (sdk is YamlScalar) {
+        var currentConstraint = VersionConstraint.parse(sdk.value);
+        var minimumVersion = Version.parse(_intendedMinimumSdkVersion);
+        if (currentConstraint is VersionRange &&
+            currentConstraint.min >= minimumVersion) {
+          // The current SDK version constraint already enables Null Safety.
+          return;
+        } else {
+          // TODO(srawlins): This overwrites the current maximum version. In
+          // the uncommon situation that the maximum is not '<3.0.0', it should
+          // not.
+          replaceSpan(sdk.span, "'$_intendedSdkVersionConstraint'");
+        }
+      }
     }
   }
 
@@ -215,11 +239,11 @@
   $optionsFilePath
   $error
 
-  Manually update this file to enable non-nullable by adding:
+  Manually update this file to enable the Null Safety language feature by
+  adding:
 
-    analyzer:
-      enable-experiment:
-        - non-nullable
+    environment:
+      sdk: '$_intendedSdkVersionConstraint';
 ''');
     _packageIsNNBD = false;
   }
@@ -228,7 +252,7 @@
     reset();
     await rerunFunction(changedPaths);
     final state = MigrationState(
-        migration, includedRoot, listener, instrumentationListener, adapter);
+        migration, includedRoot, listener, instrumentationListener);
     await state.refresh();
     return state;
   }
@@ -241,10 +265,26 @@
         instrumentation: instrumentationListener);
   }
 
+  void shutdownServer() {
+    _server?.close();
+  }
+
+  /// Allows unit tests to shut down any rogue servers that have been started,
+  /// so that unit testing can complete.
+  @visibleForTesting
+  static void shutdownAllServers() {
+    for (var server in _allServers) {
+      try {
+        server.close();
+      } catch (_) {}
+    }
+    _allServers.clear();
+  }
+
   static void task(DartFixRegistrar registrar, DartFixListener listener,
       EditDartfixParams params) {
-    registrar
-        .registerCodeTask(NonNullableFix(listener, included: params.included));
+    registrar.registerCodeTask(NonNullableFix(listener,
+        included: params.included, preferredPort: params.port));
   }
 
   /// Get the "root" of all [included] paths. See [includedRoot] for its
@@ -278,7 +318,7 @@
 }
 
 class NullabilityMigrationAdapter implements NullabilityMigrationListener {
-  final DartFixListener listener;
+  final DartFixListenerInterface listener;
 
   NullabilityMigrationAdapter(this.listener);
 
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
deleted file mode 100644
index a4a89b4..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ /dev/null
@@ -1,864 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
-import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
-import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/syntactic_entity.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart'
-    show SourceFileEdit;
-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
-import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
-import 'package:meta/meta.dart';
-import 'package:nnbd_migration/instrumentation.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
-import 'package:nnbd_migration/src/edit_plan.dart';
-
-/// A builder used to build the migration information for a library.
-class InfoBuilder {
-  /// The resource provider used to access the file system.
-  ResourceProvider provider;
-
-  String includedPath;
-
-  /// The instrumentation information gathered while the migration engine was
-  /// running.
-  final InstrumentationInformation info;
-
-  /// The listener used to gather the changes to be applied.
-  final DartFixListener listener;
-
-  /// The dartfix adapter, which can be used to report exceptions that occur.
-  final NullabilityMigrationAdapter adapter;
-
-  /// The [NullabilityMigration] instance for this migration.
-  final NullabilityMigration migration;
-
-  /// A map from the path of a compilation unit to the information about that
-  /// unit.
-  final Map<String, UnitInfo> unitMap = {};
-
-  /// Initialize a newly created builder.
-  InfoBuilder(this.provider, this.includedPath, this.info, this.listener,
-      this.adapter, this.migration);
-
-  /// The analysis server used to get information about libraries.
-  AnalysisServer get server => listener.server;
-
-  /// Return the migration information for all of the libraries that were
-  /// migrated.
-  Future<Set<UnitInfo>> explainMigration() async {
-    var sourceInfoMap = info.sourceInformation;
-    Set<UnitInfo> units =
-        SplayTreeSet<UnitInfo>((u1, u2) => u1.path.compareTo(u2.path));
-    for (var source in sourceInfoMap.keys) {
-      var filePath = source.fullName;
-      var session = server.getAnalysisDriver(filePath).currentSession;
-      if (!session.getFile(filePath).isPart) {
-        var result = await session.getResolvedLibrary(filePath);
-        for (var unitResult in result.units) {
-          var sourceInfo =
-              sourceInfoMap[unitResult.unit.declaredElement.source];
-          // Note: there might have been no information for this unit in
-          // sourceInfoMap.  That can happen if there's an already-migrated
-          // library being referenced by the code being migrated, but not all
-          // parts of that library are referenced.  To avoid exceptions later
-          // on, we just create an empty SourceInformation object.
-          // TODO(paulberry): we don't do a good job of the case where the
-          // already-migrated library's defining compilation unit isn't
-          // referenced (we'll just skip the entire library because we'll only
-          // ever see its parts).
-          sourceInfo ??= SourceInformation();
-          var edit = listener.sourceChange.getFileEdit(unitResult.path);
-          var unit = _explainUnit(sourceInfo, unitResult, edit);
-          if (provider.pathContext.isWithin(includedPath, unitResult.path)) {
-            units.add(unit);
-          }
-        }
-      }
-    }
-    return units;
-  }
-
-  Iterable<EdgeInfo> upstreamTriggeredEdges(NullabilityNodeInfo node,
-      {bool skipExactNullable = true}) {
-    var edges = <EdgeInfo>[];
-    for (var edge in node.upstreamEdges) {
-      if (skipExactNullable &&
-          node.isExactNullable &&
-          edge.sourceNode.isExactNullable) {
-        // When an exact nullable points here, the nullability propagated
-        // in the other direction.
-        continue;
-      }
-      if (edge.isTriggered) {
-        edges.add(edge);
-      }
-    }
-    for (final containerNode in node.outerCompoundNodes) {
-      // We must include the exact nullable edges in the upstream triggered
-      // edges of the container node. If this node is in a substitution node,
-      // then it's possible it was marked exact nullable because it's container
-      // was marked nullable. It's container could have been marked nullable by
-      // another exact nullable node. We cannot tell. Err on the side of
-      // surfacing too many reasons.
-      edges.addAll(
-          upstreamTriggeredEdges(containerNode, skipExactNullable: false));
-    }
-
-    return edges;
-  }
-
-  void _addSimpleTrace(SimpleFixReasonInfo info, List<TraceInfo> traces) {
-    traces.add(TraceInfo(
-        'Reason', [_makeTraceEntry(info.description, info.codeReference)]));
-  }
-
-  /// Return detail text for a fix built from an edge with origin info [origin]
-  /// and [fixKind].
-  ///
-  /// Text is meant to be used as the beginning of a sentence. It is written in
-  /// present tense, beginning with a capital letter, not ending in a period.
-  String _baseDescriptionForOrigin(
-      EdgeOriginInfo origin, NullabilityFixKind fixKind) {
-    var node = origin.node;
-    var parent = node.parent;
-
-    String aNullableDefault(DefaultFormalParameter node) {
-      var defaultValue = node.defaultValue;
-      if (defaultValue == null) {
-        return "an implicit default value of 'null'";
-      } else if (defaultValue is NullLiteral) {
-        return "an explicit default value of 'null'";
-      }
-      return 'a nullable default value';
-    }
-
-    if (node is DefaultFormalParameter) {
-      if (fixKind == NullabilityFixKind.addRequired) {
-        return 'This parameter is non-nullable, so cannot have '
-            '${aNullableDefault(node)}';
-      } else {
-        return 'This parameter has ${aNullableDefault(node)}';
-      }
-    } else if (node is FieldFormalParameter) {
-      if (parent is DefaultFormalParameter) {
-        return 'This field is initialized by an optional field formal '
-            'parameter that has ${aNullableDefault(parent)}';
-      }
-      return 'This field is initialized by a field formal parameter and a '
-          'nullable value is passed as an argument';
-    } else if (parent is DefaultFormalParameter) {
-      return 'This parameter has ${aNullableDefault(parent)}';
-    } else if (parent is AsExpression) {
-      return 'The value of the expression is nullable';
-    }
-
-    if (origin.kind == EdgeOriginKind.listLengthConstructor) {
-      return 'A length is specified in the "List()" constructor and the list '
-          'items are initialized to null';
-    }
-    if (origin.kind == EdgeOriginKind.typeParameterInstantiation) {
-      return 'This type parameter is instantiated with a nullable type';
-    }
-    if (origin.kind == EdgeOriginKind.inferredTypeParameterInstantiation) {
-      return 'This type parameter is instantiated with an inferred nullable '
-          'type';
-    }
-
-    var unit = node.thisOrAncestorOfType<CompilationUnit>();
-    var lineNumber = unit.lineInfo.getLocation(node.offset).lineNumber;
-
-    if (origin.kind == EdgeOriginKind.uninitializedRead) {
-      return 'Used on line $lineNumber, when it is possibly uninitialized';
-    } else if (origin.kind == EdgeOriginKind.implicitNullReturn) {
-      return 'This function contains a return statement with no value on line '
-          '$lineNumber, which implicitly returns null.';
-    }
-
-    // Text indicating the type of nullable value found.
-    String nullableValue;
-    if (node is NullLiteral) {
-      nullableValue = "an explicit 'null'";
-    } else if (origin.kind == EdgeOriginKind.dynamicAssignment) {
-      nullableValue = 'a dynamic value, which is nullable';
-    } else {
-      nullableValue = 'a nullable value';
-    }
-
-    /// If the [node] is inside the return expression for a function body,
-    /// return the function body. Otherwise return `null`.
-    FunctionBody findFunctionBody() {
-      if (parent is ExpressionFunctionBody) {
-        return parent;
-      } else {
-        var returnNode = parent.thisOrAncestorOfType<ReturnStatement>();
-        var bodyNode = returnNode?.thisOrAncestorOfType<BlockFunctionBody>();
-        return bodyNode;
-      }
-    }
-
-    /// If the [node] is inside a collection literal, return it. Otherwise
-    /// return `null`.
-    TypedLiteral findCollectionLiteral() {
-      var ancestor = parent;
-      // Walk up collection elements, except for collection literals.
-      while (ancestor is CollectionElement && ancestor is! TypedLiteral) {
-        ancestor = ancestor.parent;
-      }
-      return (ancestor is TypedLiteral) ? ancestor : null;
-    }
-
-    var functionBody = findFunctionBody();
-    if (functionBody != null) {
-      var function = functionBody.parent;
-      if (function is MethodDeclaration) {
-        if (function.isGetter) {
-          return 'This getter returns $nullableValue on line $lineNumber';
-        }
-        return 'This method returns $nullableValue on line $lineNumber';
-      }
-      return 'This function returns $nullableValue on line $lineNumber';
-    }
-
-    var collectionLiteral = findCollectionLiteral();
-    if (collectionLiteral != null) {
-      if (collectionLiteral is ListLiteral) {
-        return 'This list is initialized with $nullableValue on line '
-            '$lineNumber';
-      } else if (collectionLiteral is SetOrMapLiteral) {
-        var mapOrSet = collectionLiteral.isMap ? 'map' : 'set';
-        return 'This $mapOrSet is initialized with $nullableValue on line '
-            '$lineNumber';
-      }
-    } else if (node is InvocationExpression &&
-        origin.kind == EdgeOriginKind.namedParameterNotSupplied) {
-      return 'This named parameter is omitted in a call to this function';
-    } else if (parent is ArgumentList) {
-      return capitalize('$nullableValue is passed as an argument');
-    } else if (parent is VariableDeclaration) {
-      var grandparent = parent.parent?.parent;
-      if (grandparent is FieldDeclaration) {
-        return 'This field is initialized to $nullableValue';
-      }
-      return 'This variable is initialized to $nullableValue';
-    } else if (origin.kind == EdgeOriginKind.fieldNotInitialized) {
-      if (node is ConstructorDeclaration) {
-        var constructorName = node.declaredElement.enclosingElement.displayName;
-        if (node.declaredElement.displayName.isNotEmpty) {
-          constructorName =
-              '$constructorName.${node.declaredElement.displayName}';
-        }
-        return "The constructor '$constructorName' does not initialize this "
-            'field in its initializer list';
-      } else {
-        return 'This field is not initialized';
-      }
-    }
-
-    var enclosingMemberDescription = buildEnclosingMemberDescription(node);
-    if (enclosingMemberDescription != null) {
-      return capitalize(
-          '$nullableValue is assigned in $enclosingMemberDescription');
-    } else {
-      assert(false, 'no enclosing member description');
-      return capitalize('$nullableValue is assigned');
-    }
-  }
-
-  /// Return a description of the given [origin].
-  String _buildDescriptionForOrigin(
-      EdgeOriginInfo origin, NullabilityFixKind fixKind) {
-    var description = _baseDescriptionForOrigin(origin, fixKind);
-    if (_inTestCode(origin.node)) {
-      // TODO(brianwilkerson) Don't add this if the graph node with which the
-      //  origin is associated is also in test code.
-      description += ' in test code';
-    }
-    return description;
-  }
-
-  /// Return a description of the given [origin] associated with the [edge].
-  RegionDetail _buildDetailForOrigin(
-      EdgeOriginInfo origin, EdgeInfo edge, NullabilityFixKind fixKind) {
-    var node = origin.node;
-    NavigationTarget target;
-    var type = info.typeAnnotationForNode(edge.sourceNode);
-    var typeParent = type?.parent;
-
-    if (typeParent is GenericFunctionType && type == typeParent.returnType) {
-      var description =
-          'A function-typed value with a nullable return type is assigned';
-      target = _proximateTargetForNode(origin.source.fullName, node);
-      return RegionDetail(description, target);
-    }
-    if (typeParent is FormalParameter) {
-      FormalParameterList parameterList =
-          typeParent.parent is DefaultFormalParameter
-              ? typeParent.parent.parent
-              : typeParent.parent;
-      if (parameterList.parent is GenericFunctionType) {
-        var description =
-            'The function-typed element in which this parameter is declared is '
-            'assigned to a function whose matching parameter is nullable';
-        target = _proximateTargetForNode(origin.source.fullName, node);
-        return RegionDetail(description, target);
-      }
-    }
-
-    // Some nodes don't need a target; default formal parameters
-    // without explicit default values, for example.
-    if (node is DefaultFormalParameter && node.defaultValue == null) {
-      target = null;
-    } else {
-      if (origin.kind == EdgeOriginKind.parameterInheritance ||
-          origin.kind == EdgeOriginKind.returnTypeInheritance) {
-        // The node is the method declaration in the subclass and we want to
-        // link to the either the corresponding parameter in the declaration in
-        // the superclass, or the return type in the declaration in that
-        // subclass.
-        if (type != null) {
-          var unit = type.thisOrAncestorOfType<CompilationUnit>();
-          target = _proximateTargetForNode(
-              unit.declaredElement.source.fullName, type);
-        }
-        var description = _buildInheritanceDescriptionForOrigin(origin, type);
-        return RegionDetail(description, target);
-      } else {
-        target = _proximateTargetForNode(origin.source.fullName, node);
-      }
-    }
-    return RegionDetail(_buildDescriptionForOrigin(origin, fixKind), target);
-  }
-
-  String _buildInheritanceDescriptionForOrigin(
-      EdgeOriginInfo origin, TypeAnnotation type) {
-    if (origin.kind == EdgeOriginKind.parameterInheritance) {
-      var overriddenName = 'the overridden method';
-      if (type != null && type.parent is FormalParameter) {
-        FormalParameter parameter = type.parent;
-        if (parameter.parent is DefaultFormalParameter) {
-          parameter = parameter.parent;
-        }
-        if (parameter.parent is FormalParameterList &&
-            parameter.parent.parent is MethodDeclaration) {
-          MethodDeclaration method = parameter.parent.parent;
-          var methodName = method.name.name;
-          ClassOrMixinDeclaration cls = method.parent;
-          var className = cls.name.name;
-          overriddenName += ', $className.$methodName,';
-        }
-      }
-      return 'The corresponding parameter in $overriddenName is nullable';
-    } else {
-      return 'An overridding method has a nullable return value';
-    }
-  }
-
-  /// Compute the details for the fix with the given [edit].
-  List<RegionDetail> _computeDetails(AtomicEdit edit) {
-    var details = <RegionDetail>[];
-    var fixInfo = edit.info;
-    for (var reason in fixInfo?.fixReasons ?? []) {
-      if (reason == null) {
-        // Sometimes reasons are null, so just ignore them (see for example the
-        // test case InfoBuilderTest.test_discardCondition.  If only we had
-        // NNBD, we could have prevented this!
-        // TODO(paulberry): fix this so that it will never happen.
-      } else if (reason is NullabilityNodeInfo) {
-        if (reason.isExactNullable) {
-          // When the node is exact nullable, that nullability propagated from
-          // downstream.
-          for (var edge in reason.downstreamEdges) {
-            final exactNullableDownstream = edge.destinationNode;
-            if (!exactNullableDownstream.isExactNullable) {
-              // This wasn't the source of the nullability.
-              continue;
-            }
-
-            var nodeInfo = info.nodeInfoFor(exactNullableDownstream);
-            if (nodeInfo != null) {
-              // TODO(mfairhurst): Give a better text description.
-              details.add(RegionDetail(
-                  'This is later required to accept null.',
-                  _proximateTargetForNode(
-                      nodeInfo.filePath, nodeInfo.astNode)));
-            } else {
-              final description =
-                  'exact nullable node with no info ($exactNullableDownstream)';
-              assert(false, description);
-              details.add(RegionDetail(description, null));
-            }
-          }
-        }
-
-        for (var edge in upstreamTriggeredEdges(reason)) {
-          var origin = info.edgeOrigin[edge];
-          if (origin != null) {
-            details.add(
-                _buildDetailForOrigin(origin, edge, fixInfo.description.kind));
-          } else {
-            final description = 'upstream edge with no origin ($edge)';
-            assert(false, description);
-            details.add(RegionDetail(description, null));
-          }
-        }
-      } else if (reason is EdgeInfo) {
-        var destination = reason.destinationNode;
-        var nodeInfo = info.nodeInfoFor(destination);
-        var edge = info.edgeOrigin[reason];
-        if (destination == info.never) {
-          details.add(RegionDetail(_describeNonNullEdge(edge), null));
-        } else if (nodeInfo != null && nodeInfo.astNode != null) {
-          NavigationTarget target;
-          if (destination != info.always) {
-            target =
-                _proximateTargetForNode(nodeInfo.filePath, nodeInfo.astNode);
-          }
-          details.add(RegionDetail(_describeNonNullEdge(edge), target));
-        } else {
-          // Likely an assignment to a migrated type.
-          final description = 'node with no info ($destination)';
-          assert(false, description);
-          details.add(RegionDetail(description, null));
-        }
-      } else if (reason is SimpleFixReasonInfo) {
-        details.add(RegionDetail(reason.description, null));
-      } else {
-        throw UnimplementedError(
-            'Unexpected class of reason: ${reason.runtimeType}');
-      }
-    }
-    return details;
-  }
-
-  /// Return an edit that can be applied.
-  List<EditDetail> _computeEdits(AtomicEditInfo fixInfo, int offset) {
-    var edits = <EditDetail>[];
-    var fixKind = fixInfo.description.kind;
-    switch (fixKind) {
-      case NullabilityFixKind.addRequired:
-        // TODO(brianwilkerson) This doesn't verify that the meta package has
-        //  been imported.
-        edits
-            .add(EditDetail("Mark with '@required'.", offset, 0, '@required '));
-        break;
-      case NullabilityFixKind.checkExpression:
-        // TODO(brianwilkerson) Determine whether we can know that the fix is
-        //  associated with a parameter and insert an assert if it is.
-        edits.add(EditDetail('Force null check.', offset, 0, '/*!*/'));
-        break;
-      case NullabilityFixKind.discardCondition:
-      case NullabilityFixKind.discardElse:
-      case NullabilityFixKind.discardIf:
-      case NullabilityFixKind.discardThen:
-      case NullabilityFixKind.removeAs:
-      case NullabilityFixKind.removeNullAwareness:
-      case NullabilityFixKind.removeLanguageVersionComment:
-        // There's no need for hints around code that is being removed.
-        break;
-      case NullabilityFixKind.makeTypeNullable:
-      case NullabilityFixKind.typeNotMadeNullable:
-        edits.add(
-            EditDetail('Force type to be non-nullable.', offset, 0, '/*!*/'));
-        edits.add(EditDetail('Force type to be nullable.', offset, 0, '/*?*/'));
-        break;
-    }
-    return edits;
-  }
-
-  /// Return the navigation sources for the unit associated with the [result].
-  List<NavigationSource> _computeNavigationSources(ResolvedUnitResult result) {
-    var collector = NavigationCollectorImpl();
-    computeDartNavigation(
-        result.session.resourceProvider, collector, result.unit, null, null);
-    collector.createRegions();
-    var files = collector.files;
-    var regions = collector.regions;
-    var rawTargets = collector.targets;
-    var convertedTargets = List<NavigationTarget>(rawTargets.length);
-    return regions.map((region) {
-      var targets = region.targets;
-      if (targets.isEmpty) {
-        throw StateError('Targets is empty');
-      }
-      var target = convertedTargets[targets[0]];
-      if (target == null) {
-        var rawTarget = rawTargets[targets[0]];
-        target = _targetForRawTarget(files[rawTarget.fileIndex], rawTarget);
-        convertedTargets[targets[0]] = target;
-      }
-      return NavigationSource(
-          region.offset, null /* line */, region.length, target);
-    }).toList();
-  }
-
-  void _computeTraceNonNullableInfo(
-      NullabilityNodeInfo node, List<TraceInfo> traces) {
-    var entries = <TraceEntryInfo>[];
-    var step = node.whyNotNullable;
-    if (step == null) {
-      return;
-    }
-    assert(identical(step.node, node));
-    while (step != null) {
-      entries.add(_nodeToTraceEntry(step.node));
-      if (step.codeReference != null) {
-        entries.add(_stepToTraceEntry(step));
-      }
-      step = step.principalCause;
-    }
-    var description = 'Non-nullability reason';
-    traces.add(TraceInfo(description, entries));
-  }
-
-  void _computeTraceNullableInfo(
-      NullabilityNodeInfo node, List<TraceInfo> traces) {
-    var entries = <TraceEntryInfo>[];
-    var step = node.whyNullable;
-    if (step == null) {
-      return;
-    }
-    assert(identical(step.targetNode, node));
-    while (step != null) {
-      entries.add(_nodeToTraceEntry(step.targetNode));
-      if (step.codeReference != null) {
-        entries.add(_stepToTraceEntry(step));
-      }
-      step = step.principalCause;
-    }
-    var description = 'Nullability reason';
-    traces.add(TraceInfo(description, entries));
-  }
-
-  List<TraceInfo> _computeTraces(List<FixReasonInfo> fixReasons) {
-    var traces = <TraceInfo>[];
-    for (var reason in fixReasons) {
-      if (reason is NullabilityNodeInfo) {
-        if (reason.isNullable) {
-          _computeTraceNullableInfo(reason, traces);
-        } else {
-          _computeTraceNonNullableInfo(reason, traces);
-        }
-      } else if (reason is EdgeInfo) {
-        assert(reason.sourceNode.isNullable);
-        assert(!reason.destinationNode.isNullable);
-        _computeTraceNullableInfo(reason.sourceNode, traces);
-        _computeTraceNonNullableInfo(reason.destinationNode, traces);
-      } else if (reason is SimpleFixReasonInfo) {
-        _addSimpleTrace(reason, traces);
-      } else {
-        assert(false, 'Unrecognized reason type: ${reason.runtimeType}');
-      }
-    }
-    return traces;
-  }
-
-  /// Describe why an edge may have gotten a '!'.
-  String _describeNonNullEdge(EdgeOriginInfo edge) {
-    // TODO(mfairhurst/paulberry): Do NOT use astNode/parent to create this
-    // description, as we are just duplicating work if we do so.
-    final astNode = edge.node;
-    final parent = astNode.parent;
-    if (parent is PropertyAccess && parent.target == astNode ||
-        parent is PrefixedIdentifier && parent.prefix == astNode) {
-      return 'This value must be null-checked before accessing its properties.';
-    }
-    if (parent is MethodInvocation && parent.target == astNode) {
-      return 'This value must be null-checked before calling its methods.';
-    }
-
-    return 'This value must be null-checked before use here.';
-  }
-
-  /// Return the migration information for the unit associated with the
-  /// [result].
-  UnitInfo _explainUnit(SourceInformation sourceInfo, ResolvedUnitResult result,
-      SourceFileEdit fileEdit) {
-    var unitInfo = _unitForPath(result.path);
-    unitInfo.sources ??= _computeNavigationSources(result);
-    var content = result.content;
-    var regions = unitInfo.regions;
-    var lineInfo = result.unit.lineInfo;
-    var insertions = <int, List<AtomicEdit>>{};
-
-    // Apply edits and build the regions.
-    var changes = sourceInfo.changes ?? {};
-    var sourceOffsets = changes.keys.toList();
-    sourceOffsets.sort();
-    var offset = 0;
-    var lastSourceOffset = 0;
-    for (var sourceOffset in sourceOffsets) {
-      offset += sourceOffset - lastSourceOffset;
-      lastSourceOffset = sourceOffset;
-      var changesForSourceOffset = changes[sourceOffset];
-      for (var edit in changesForSourceOffset) {
-        var length = edit.length;
-        var replacement = edit.replacement;
-        var end = offset + length;
-        // Insert the replacement text without deleting the replaced text.
-        if (replacement.isNotEmpty) {
-          content = content.replaceRange(end, end, replacement);
-          (insertions[sourceOffset] ??= []).add(AtomicEdit.insert(replacement));
-        }
-        var info = edit.info;
-        var explanation = info?.description?.appliedMessage;
-        var edits = info != null ? _computeEdits(info, sourceOffset) : [];
-        List<RegionDetail> details;
-        try {
-          details = _computeDetails(edit);
-        } catch (e, st) {
-          // TODO(mfairhurst): get the correct Source, and an AstNode.
-          if (migration.isPermissive) {
-            adapter.reportException(result.libraryElement.source, null, e, st);
-            details = [];
-          } else {
-            rethrow;
-          }
-        }
-        var lineNumber = lineInfo.getLocation(sourceOffset).lineNumber;
-        var traces = info == null ? const [] : _computeTraces(info.fixReasons);
-        if (explanation != null) {
-          if (length > 0) {
-            regions.add(RegionInfo(RegionType.remove, offset, length,
-                lineNumber, explanation, details,
-                edits: edits, traces: traces));
-          } else {
-            if (edit.isInformative) {
-              regions.add(RegionInfo(RegionType.informative, offset,
-                  replacement.length, lineNumber, explanation, const [],
-                  edits: edits, traces: traces));
-            } else {
-              regions.add(RegionInfo(RegionType.add, offset, replacement.length,
-                  lineNumber, explanation, details,
-                  edits: edits, traces: traces));
-            }
-          }
-        }
-        offset += replacement.length;
-      }
-    }
-
-    // Build the map from source file offset to offset in the modified text.
-    // We only account for insertions because in the code above, we don't delete
-    // the modified text.
-    var edits = insertions.toSourceEdits();
-    edits.sort((first, second) => first.offset.compareTo(second.offset));
-    var mapper = OffsetMapper.forEdits(edits);
-    regions.sort((first, second) => first.offset.compareTo(second.offset));
-    unitInfo.offsetMapper = mapper;
-    unitInfo.content = content;
-    return unitInfo;
-  }
-
-  /// Return `true` if the given [node] is from a compilation unit within the
-  /// 'test' directory of the package.
-  bool _inTestCode(AstNode node) {
-    // TODO(brianwilkerson) Generalize this.
-    var unit = node.thisOrAncestorOfType<CompilationUnit>();
-    var unitElement = unit?.declaredElement;
-    if (unitElement == null) {
-      return false;
-    }
-    var filePath = unitElement.source.fullName;
-    var resourceProvider = unitElement.session.resourceProvider;
-    return resourceProvider.pathContext.split(filePath).contains('test');
-  }
-
-  TraceEntryInfo _makeTraceEntry(
-      String description, CodeReference codeReference) {
-    var length = 1; // TODO(paulberry): figure out the correct value.
-    return TraceEntryInfo(
-        description,
-        codeReference?.function,
-        codeReference == null
-            ? null
-            : NavigationTarget(codeReference.path, codeReference.column,
-                codeReference.line, length));
-  }
-
-  TraceEntryInfo _nodeToTraceEntry(NullabilityNodeInfo node) {
-    var description = node.toString(); // TODO(paulberry): improve this message
-    return _makeTraceEntry(description, node.codeReference);
-  }
-
-  /// Return the navigation target corresponding to the given [node] in the file
-  /// with the given [filePath].
-  ///
-  /// Rather than a NavigationTarget targeting exactly [node], heuristics are
-  /// made to point to a narrower target, for example the name of a
-  /// method declaration, rather the the entire declaration.
-  NavigationTarget _proximateTargetForNode(String filePath, AstNode node) {
-    if (node == null) {
-      return null;
-    }
-    var parent = node.parent;
-    var unit = node.thisOrAncestorOfType<CompilationUnit>();
-    if (node is ConstructorDeclaration) {
-      if (node.name != null) {
-        return _targetForNode(filePath, node.name, unit);
-      } else {
-        return _targetForNode(filePath, node.returnType, unit);
-      }
-    } else if (node is MethodDeclaration) {
-      // Rather than create a NavigationTarget for an entire method declaration
-      // (starting at its doc comment, ending at `}`, return a target pointing
-      // to the method's name.
-      return _targetForNode(filePath, node.name, unit);
-    } else if (parent is ReturnStatement) {
-      // Rather than create a NavigationTarget for an entire expression, return
-      // a target pointing to the `return` token.
-      return _targetForNode(filePath, parent.returnKeyword, unit);
-    } else if (parent is ExpressionFunctionBody) {
-      // Rather than create a NavigationTarget for an entire expression function
-      // body, return a target pointing to the `=>` token.
-      return _targetForNode(filePath, parent.functionDefinition, unit);
-    } else {
-      return _targetForNode(filePath, node, unit);
-    }
-  }
-
-  TraceEntryInfo _stepToTraceEntry(PropagationStepInfo step) {
-    var description = step.edge?.description;
-    description ??= step.toString(); // TODO(paulberry): improve this message.
-    return _makeTraceEntry(description, step.codeReference);
-  }
-
-  /// Return the navigation target in the file with the given [filePath] at the
-  /// given [offset] ans with the given [length].
-  NavigationTarget _targetForNode(
-      String filePath, SyntacticEntity node, CompilationUnit unit) {
-    var unitInfo = _unitForPath(filePath);
-    var offset = node.offset;
-    var length = node.length;
-
-    var line = unit.lineInfo.getLocation(node.offset).lineNumber;
-    var target = NavigationTarget(filePath, offset, line, length);
-    unitInfo.targets.add(target);
-    return target;
-  }
-
-  /// Return the navigation target in the file with the given [filePath] at the
-  /// given [offset] ans with the given [length].
-  NavigationTarget _targetForRawTarget(
-      String filePath, protocol.NavigationTarget rawTarget) {
-    var unitInfo = _unitForPath(filePath);
-    var offset = rawTarget.offset;
-    var length = rawTarget.length;
-    var target = NavigationTarget(filePath, offset, null /* line */, length);
-    unitInfo.targets.add(target);
-    return target;
-  }
-
-  /// Return the unit info for the file at the given [path].
-  UnitInfo _unitForPath(String path) {
-    return unitMap.putIfAbsent(path, () => UnitInfo(path));
-  }
-
-  /// Builds a description for [node]'s enclosing member(s).
-  ///
-  /// This may include a class and method name, for example, or the name of the
-  /// enclosing top-level member.
-  @visibleForTesting
-  static String buildEnclosingMemberDescription(AstNode node) {
-    for (var enclosingNode = node;
-        enclosingNode != null;
-        enclosingNode = enclosingNode.parent) {
-      if (enclosingNode is ConstructorDeclaration) {
-        if (enclosingNode.name == null) {
-          return _describeClassOrExtensionMember(
-              enclosingNode.parent, 'the default constructor of', '');
-        } else {
-          return _describeClassOrExtensionMember(
-              enclosingNode.parent, 'the constructor', enclosingNode.name.name);
-        }
-      } else if (enclosingNode is MethodDeclaration) {
-        var functionName = enclosingNode.name.name;
-        String baseDescription;
-        if (enclosingNode.isGetter) {
-          baseDescription = 'the getter';
-        } else if (enclosingNode.isOperator) {
-          baseDescription = 'the operator';
-        } else if (enclosingNode.isSetter) {
-          baseDescription = 'the setter';
-          functionName += '=';
-        } else {
-          baseDescription = 'the method';
-        }
-        return _describeClassOrExtensionMember(
-            enclosingNode.parent, baseDescription, functionName);
-      } else if (enclosingNode is FunctionDeclaration &&
-          enclosingNode.parent is CompilationUnit) {
-        var functionName = enclosingNode.name.name;
-        String baseDescription;
-        if (enclosingNode.isGetter) {
-          baseDescription = 'the getter';
-        } else if (enclosingNode.isSetter) {
-          baseDescription = 'the setter';
-          functionName += '=';
-        } else {
-          baseDescription = 'the function';
-        }
-        return "$baseDescription '$functionName'";
-      } else if (enclosingNode is VariableDeclaration) {
-        var description = _describeVariableDeclaration(enclosingNode);
-        if (description != null) return description;
-      } else if (enclosingNode is VariableDeclarationList) {
-        var description =
-            _describeVariableDeclaration(enclosingNode.variables[0]);
-        if (description != null) return description;
-      }
-    }
-    throw ArgumentError(
-        "Can't describe enclosing member of ${node.runtimeType}");
-  }
-
-  static String _describeClassOrExtensionMember(CompilationUnitMember parent,
-      String baseDescription, String functionName) {
-    if (parent is NamedCompilationUnitMember) {
-      var parentName = parent.name.name;
-      if (functionName.isEmpty) {
-        return "$baseDescription '$parentName'";
-      } else {
-        return "$baseDescription '$parentName.$functionName'";
-      }
-    } else if (parent is ExtensionDeclaration) {
-      if (parent.name == null) {
-        var extendedTypeString = parent.extendedType.type.getDisplayString(
-          withNullability: false,
-        );
-        return "$baseDescription '$functionName' in unnamed extension on $extendedTypeString";
-      } else {
-        return "$baseDescription '${parent.name.name}.$functionName'";
-      }
-    } else {
-      throw ArgumentError(
-          'Unexpected class or extension type ${parent.runtimeType}');
-    }
-  }
-
-  static String _describeVariableDeclaration(VariableDeclaration node) {
-    var variableName = node.name.name;
-    var parent = node.parent;
-    var grandParent = parent.parent;
-    if (grandParent is FieldDeclaration) {
-      return _describeClassOrExtensionMember(
-          grandParent.parent, 'the field', variableName);
-    } else if (grandParent is TopLevelVariableDeclaration) {
-      return "the variable '$variableName'";
-    } else {
-      return null;
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
deleted file mode 100644
index 933b7b5..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:nnbd_migration/instrumentation.dart';
-import 'package:nnbd_migration/src/edit_plan.dart';
-
-/// A listener used to gather instrumentation information from the migration
-/// engine.
-class InstrumentationListener implements NullabilityMigrationInstrumentation {
-  /// The instrumentation information being gathered.
-  InstrumentationInformation data = InstrumentationInformation();
-
-  /// Initialize a newly created listener.
-  InstrumentationListener();
-
-  @override
-  void changes(Source source, Map<int, List<AtomicEdit>> changes) {
-    assert(_sourceInfo(source).changes == null);
-    _sourceInfo(source).changes = changes;
-  }
-
-  @override
-  void explicitTypeNullability(
-      Source source, TypeAnnotation typeAnnotation, NullabilityNodeInfo node) {
-    data.nodeInformation[node] =
-        NodeInformation(_filePathForSource(source), typeAnnotation, null);
-    _sourceInfo(source).explicitTypeNullability[typeAnnotation] = node;
-  }
-
-  @override
-  void externalDecoratedType(Element element, DecoratedTypeInfo decoratedType) {
-    _storeNodeInformation(decoratedType, element.source, null, element);
-  }
-
-  @override
-  void externalDecoratedTypeParameterBound(
-      TypeParameterElement typeParameter, DecoratedTypeInfo decoratedType) {
-    _storeNodeInformation(
-        decoratedType, typeParameter.source, null, typeParameter);
-  }
-
-  @override
-  void graphEdge(EdgeInfo edge, EdgeOriginInfo originInfo) {
-    data.edgeOrigin[edge] = originInfo;
-  }
-
-  @override
-  void immutableNodes(NullabilityNodeInfo never, NullabilityNodeInfo always) {
-    data.never = never;
-    data.always = always;
-  }
-
-  @override
-  void implicitReturnType(
-      Source source, AstNode node, DecoratedTypeInfo decoratedReturnType) {
-    _storeNodeInformation(decoratedReturnType, source, node, null);
-  }
-
-  @override
-  void implicitType(
-      Source source, AstNode node, DecoratedTypeInfo decoratedType) {
-    _storeNodeInformation(decoratedType, source, node, null);
-  }
-
-  @override
-  void implicitTypeArguments(
-      Source source, AstNode node, Iterable<DecoratedTypeInfo> types) {
-    for (var type in types) {
-      _storeNodeInformation(type, source, node, null);
-    }
-  }
-
-  @override
-  void prepareForUpdate() {
-    for (var source in data.sourceInformation.keys) {
-      _sourceInfo(source).changes = null;
-    }
-  }
-
-  String _filePathForSource(Source source) {
-    return source.fullName;
-  }
-
-  /// Return the source information associated with the given [source], creating
-  /// it if there has been no previous information for that source.
-  SourceInformation _sourceInfo(Source source) =>
-      data.sourceInformation.putIfAbsent(source, () => SourceInformation());
-
-  // TODO(srawlins): This code is completely untested.
-  void _storeNodeInformation(DecoratedTypeInfo decoratedType, Source source,
-      AstNode astNode, Element element) {
-    // Make sure source info exists for the given source.
-    _sourceInfo(source);
-    data.nodeInformation[decoratedType.node] =
-        NodeInformation(_filePathForSource(source), astNode, element);
-    var dartType = decoratedType.type;
-    if (dartType is InterfaceType) {
-      for (var i = 0; i < dartType.typeArguments.length; i++) {
-        _storeNodeInformation(
-            decoratedType.typeArgument(i), source, astNode, element);
-      }
-    } else if (dartType is FunctionType) {
-      _storeNodeInformation(
-        decoratedType.returnType,
-        source,
-        astNode,
-        element,
-      );
-      var i = 0;
-      for (var parameter in dartType.parameters) {
-        if (parameter.isNamed) {
-          var name = parameter.name;
-          _storeNodeInformation(
-              decoratedType.namedParameter(name), source, astNode, element);
-        } else {
-          _storeNodeInformation(
-              decoratedType.positionalParameter(i), source, astNode, element);
-          i++;
-        }
-      }
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
deleted file mode 100644
index 272b98e..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/resources/resources.g.dart'
-    as resources;
-import 'package:path/path.dart' as path;
-
-String get _dartSdkVersion {
-  var version = Platform.version;
-
-  // Remove the build date and OS.
-  if (version.contains(' ')) {
-    version = version.substring(0, version.indexOf(' '));
-  }
-
-  // Convert a git hash to 8 chars.
-  // '2.8.0-edge.fd992e423ef69ece9f44bd3ac58fa2355b563212'
-  var versionRegExp = RegExp(r'^.*\.([0123456789abcdef]+)$');
-  var match = versionRegExp.firstMatch(version);
-  if (match != null && match.group(1).length == 40) {
-    var commit = match.group(1);
-    version = version.replaceAll(commit, commit.substring(0, 10));
-  }
-
-  return version;
-}
-
-String substituteVariables(String content, Map<String, String> variables) {
-  for (var variable in variables.keys) {
-    var value = variables[variable];
-    content = content.replaceAll('{{ $variable }}', value);
-  }
-
-  return content;
-}
-
-/// Instrumentation display output for a library that was migrated to use
-/// non-nullable types.
-class InstrumentationRenderer {
-  /// Information for a whole migration, so that libraries can reference each
-  /// other.
-  final MigrationInfo migrationInfo;
-
-  /// Whether the migration has been applied already or not.
-  final bool hasBeenApplied;
-
-  /// An object used to map the file paths of analyzed files to the file paths
-  /// of the HTML files used to view the content of those files.
-  final PathMapper pathMapper;
-
-  /// Creates an output object for the given library info.
-  InstrumentationRenderer(
-      this.migrationInfo, this.pathMapper, this.hasBeenApplied);
-
-  /// Returns the path context used to manipulate paths.
-  path.Context get pathContext => migrationInfo.pathContext;
-
-  /// Builds an HTML view of the instrumentation information.
-  String render() {
-    var variables = <String, String>{
-      'root': migrationInfo.includedRoot,
-      'dartPageScript': resources.migration_js,
-      'dartPageStyle': resources.migration_css,
-      'highlightJsPath': migrationInfo.highlightJsPath,
-      'highlightStylePath': migrationInfo.highlightStylePath,
-      'sdkVersion': _dartSdkVersion,
-      'migrationAppliedStyle': hasBeenApplied ? 'applied' : 'proposed',
-    };
-
-    return substituteVariables(resources.index_html, variables);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
deleted file mode 100644
index f190d0d..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_link.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as path;
-
-/// A description of an edit that can be applied before rerunning the migration
-/// in order to improve the migration results.
-class EditDetail {
-  /// A description of the edit that will be performed.
-  final String description;
-
-  /// The offset of the range to be replaced.
-  final int offset;
-
-  /// The length of the range to be replaced.
-  final int length;
-
-  /// The string with which the range will be replaced.
-  final String replacement;
-
-  /// Initialize a newly created detail.
-  EditDetail(this.description, this.offset, this.length, this.replacement);
-}
-
-/// A class storing rendering information for an entire migration report.
-///
-/// This generally provides one [InstrumentationRenderer] (for one library)
-/// with information about the rest of the libraries represented in the
-/// instrumentation output.
-class MigrationInfo {
-  /// The information about the compilation units that are are migrated.
-  final Set<UnitInfo> units;
-
-  /// A map from file paths to the unit infos created for those files. The units
-  /// in this map is a strict superset of the [units] that were migrated.
-  final Map<String, UnitInfo> unitMap;
-
-  /// The resource provider's path context.
-  final path.Context pathContext;
-
-  /// The filesystem root used to create relative paths for each unit.
-  final String includedRoot;
-
-  MigrationInfo(this.units, this.unitMap, this.pathContext, this.includedRoot);
-
-  /// The path to the highlight.pack.js script, relative to [unitInfo].
-  String get highlightJsPath => PreviewSite.highlightJsPath;
-
-  /// The path to the highlight.pack.js stylesheet, relative to [unitInfo].
-  String get highlightStylePath => PreviewSite.highlightCssPath;
-
-  /// Return the path to [unit] from [includedRoot], to be used as a display
-  /// name for a library.
-  String computeName(UnitInfo unit) =>
-      pathContext.relative(unit.path, from: includedRoot);
-
-  List<UnitLink> unitLinks() {
-    var links = <UnitLink>[];
-    for (var unit in units) {
-      var count = unit.fixRegions.length;
-      links.add(UnitLink(
-          _pathTo(target: unit), pathContext.split(computeName(unit)), count));
-    }
-    return links;
-  }
-
-  /// The path to [target], as an HTTP URI path, using forward slash separators.
-  String _pathTo({@required UnitInfo target}) =>
-      '/' + pathContext.split(target.path).skip(1).join('/');
-}
-
-/// A location from or to which a user might want to navigate.
-abstract class NavigationRegion {
-  /// The offset of the region.
-  final int offset;
-
-  /// The line number of the region.
-  final int line;
-
-  /// The length of the region.
-  final int length;
-
-  /// Initialize a newly created link.
-  NavigationRegion(int offset, this.line, this.length)
-      : assert(offset >= 0),
-        offset = offset < 0 ? 0 : offset;
-}
-
-/// A location from which a user might want to navigate.
-class NavigationSource extends NavigationRegion {
-  /// The target to which the user should be navigated.
-  final NavigationTarget target;
-
-  /// Initialize a newly created link.
-  NavigationSource(int offset, int line, int length, this.target)
-      : super(offset, line, length);
-}
-
-/// A location to which a user might want to navigate.
-class NavigationTarget extends NavigationRegion {
-  /// The file containing the anchor.
-  final String filePath;
-
-  /// Initialize a newly created anchor.
-  NavigationTarget(this.filePath, int offset, int line, int length)
-      : super(offset, line, length);
-
-  @override
-  int get hashCode => JenkinsSmiHash.hash3(filePath.hashCode, offset, length);
-
-  @override
-  bool operator ==(other) {
-    return other is NavigationTarget &&
-        other.filePath == filePath &&
-        other.offset == offset &&
-        other.length == length;
-  }
-
-  @override
-  String toString() => 'NavigationTarget["$filePath", $line, $offset, $length]';
-}
-
-/// An additional detail related to a region.
-class RegionDetail {
-  /// A textual description of the detail.
-  final String description;
-
-  /// The location associated with the detail, such as the location of an
-  /// argument that's assigned to a parameter.
-  final NavigationTarget target;
-
-  /// Initialize a newly created detail.
-  RegionDetail(this.description, this.target);
-}
-
-/// A description of an explanation associated with a region of code that was
-/// modified.
-class RegionInfo {
-  /// Type type of region.
-  final RegionType regionType;
-
-  /// The offset to the beginning of the region.
-  final int offset;
-
-  /// The length of the region.
-  final int length;
-
-  /// The line number of the beginning of the region.
-  final int lineNumber;
-
-  /// The explanation to be displayed for the region.
-  final String explanation;
-
-  /// Details that further explain why a change was made.
-  final List<RegionDetail> details;
-
-  /// A list of the edits that are related to this range.
-  List<EditDetail> edits;
-
-  /// A list of the nullability propagation traces that are related to this
-  /// range.
-  List<TraceInfo> traces;
-
-  /// Initialize a newly created region.
-  RegionInfo(this.regionType, this.offset, this.length, this.lineNumber,
-      this.explanation, this.details,
-      {this.edits = const [], this.traces = const []});
-}
-
-/// Different types of regions that are called out.
-enum RegionType {
-  /// This is a region of code that was added in migration.
-  add,
-
-  /// This is a region of code that was removed in migration.
-  remove,
-
-  /// This is a region of code that wasn't changed by migration, but is being
-  /// shown to give the user more information about the migration.
-  informative,
-}
-
-/// Information about a single entry in a nullability trace.
-class TraceEntryInfo {
-  /// Text description of the entry.
-  final String description;
-
-  /// Name of the enclosing function, or `null` if not known.
-  String function;
-
-  /// Source code location associated with the entry, or `null` if no source
-  /// code location is known.
-  final NavigationTarget target;
-
-  TraceEntryInfo(this.description, this.function, this.target);
-}
-
-/// Information about a nullability trace.
-class TraceInfo {
-  /// Text description of the trace.
-  final String description;
-
-  /// List of trace entries.
-  final List<TraceEntryInfo> entries;
-
-  TraceInfo(this.description, this.entries);
-}
-
-/// The migration information associated with a single compilation unit.
-class UnitInfo {
-  /// The absolute and normalized path of the unit.
-  final String path;
-
-  /// The content of unit.
-  String content;
-
-  /// The information about the regions that have an explanation associated with
-  /// them. The offsets in these regions are offsets into the post-edit content.
-  final List<RegionInfo> regions = [];
-
-  /// The navigation sources that are located in this file. The offsets in these
-  /// sources are offsets into the pre-edit content.
-  List<NavigationSource> sources;
-
-  /// The navigation targets that are located in this file. The offsets in these
-  /// targets are offsets into the pre-edit content.
-  final Set<NavigationTarget> targets = {};
-
-  /// The object used to map the pre-edit offsets in the navigation targets to
-  /// the post-edit offsets in the [content].
-  OffsetMapper offsetMapper = OffsetMapper.identity;
-
-  /// Initialize a newly created unit.
-  UnitInfo(this.path);
-
-  /// Returns the [regions] that represent a fixed (changed) region of code.
-  List<RegionInfo> get fixRegions => regions
-      .where((region) => region.regionType != RegionType.informative)
-      .toList();
-
-  /// Returns the [regions] that are informative.
-  List<RegionInfo> get informativeRegions => regions
-      .where((region) => region.regionType == RegionType.informative)
-      .toList();
-
-  /// Returns the [RegionInfo] at offset [offset].
-  // TODO(srawlins): This is O(n), used each time the user clicks on a region.
-  //  Consider changing the type of [regions] to facilitate O(1) searching.
-  RegionInfo regionAt(int offset) =>
-      regions.firstWhere((region) => region.offset == offset);
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
deleted file mode 100644
index 41ab440..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
-
-/// The state of an NNBD migration.
-class MigrationState {
-  bool _hasBeenApplied = false;
-
-  /// The migration associated with the state.
-  final NullabilityMigration migration;
-
-  /// The adapter to dartfix for this migration.
-  final NullabilityMigrationAdapter adapter;
-
-  /// The root directory that contains all of the files that were migrated.
-  final String includedRoot;
-
-  /// The listener used to collect fixes.
-  final DartFixListener listener;
-
-  /// The listener that collected information during the migration.
-  final InstrumentationListener instrumentationListener;
-
-  /// The information that was built from the rest of the migration state.
-  MigrationInfo migrationInfo;
-
-  /// The object used to map paths.
-  PathMapper pathMapper;
-
-  /// Initialize a newly created migration state with the given values.
-  MigrationState(this.migration, this.includedRoot, this.listener,
-      this.instrumentationListener, this.adapter);
-
-  /// If the migration has been applied to disk.
-  bool get hasBeenApplied => _hasBeenApplied;
-
-  /// Mark that the migration has been applied to disk.
-  void markApplied() {
-    assert(!hasBeenApplied);
-    _hasBeenApplied = true;
-  }
-
-  /// Refresh the state of the migration after the migration has been updated.
-  Future<void> refresh() async {
-    assert(!hasBeenApplied);
-    var provider = listener.server.resourceProvider;
-    var infoBuilder = InfoBuilder(provider, includedRoot,
-        instrumentationListener.data, listener, adapter, migration);
-    var unitInfos = await infoBuilder.explainMigration();
-    var pathContext = provider.pathContext;
-    migrationInfo = MigrationInfo(
-        unitInfos, infoBuilder.unitMap, pathContext, includedRoot);
-    pathMapper = PathMapper(provider);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/navigation_tree_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/navigation_tree_renderer.dart
deleted file mode 100644
index 124a631..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/navigation_tree_renderer.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_link.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
-import 'package:path/path.dart' as path;
-
-/// Groups the items in [iterable] by the result of applying [groupFn] to each
-/// item.
-Map<K, List<T>> _groupBy<K, T>(
-    Iterable<T> iterable, K Function(T item) groupFn) {
-  var result = <K, List<T>>{};
-  for (var item in iterable) {
-    var key = groupFn(item);
-    result.putIfAbsent(key, () => <T>[]).add(item);
-  }
-  return result;
-}
-
-/// The HTML that is displayed for a region of code.
-class NavigationTreeRenderer {
-  final MigrationInfo migrationInfo;
-
-  /// An object used to map the file paths of analyzed files to the file paths
-  /// of the HTML files used to view the content of those files.
-  final PathMapper pathMapper;
-
-  /// Initializes a newly created region page within the given [site]. The
-  /// [unitInfo] provides the information needed to render the page.
-  NavigationTreeRenderer(this.migrationInfo, this.pathMapper);
-
-  /// Returns the path context used to manipulate paths.
-  path.Context get pathContext => migrationInfo.pathContext;
-
-  /// Renders the navigation link tree.
-  List<NavigationTreeNode> render() {
-    var linkData = migrationInfo.unitLinks();
-    return _renderNavigationSubtree(linkData, 0);
-  }
-
-  /// Renders the navigation link subtree at [depth].
-  List<NavigationTreeNode> _renderNavigationSubtree(
-      List<UnitLink> links, int depth) {
-    var linksGroupedByDirectory = _groupBy(
-        links.where((link) => link.depth > depth),
-        (UnitLink link) => link.pathParts[depth]);
-    return [
-      for (var entry in linksGroupedByDirectory.entries)
-        NavigationTreeNode.directory(
-          name: entry.key,
-          subtree: _renderNavigationSubtree(entry.value, depth + 1),
-        ),
-      for (var link in links.where((link) => link.depth == depth))
-        NavigationTreeNode.file(
-          name: link.fileName,
-          path: pathContext.joinAll(link.pathParts),
-          href: link.url,
-          editCount: link.editCount,
-        ),
-    ];
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart
deleted file mode 100644
index 45218d8..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-
-/// An object that can map the offsets before a sequence of edits to the offsets
-/// after applying the edits.
-abstract class OffsetMapper {
-  /// A mapper used for files that were not modified.
-  static OffsetMapper identity = _IdentityMapper();
-
-  /// Return a mapper representing the file modified by the given [edits].
-  factory OffsetMapper.forEdits(List<SourceEdit> edits) => _EditMapper(edits);
-
-  /// Return the post-edit offset that corresponds to the given pre-edit
-  /// [offset].
-  int map(int offset);
-}
-
-/// A mapper used for files that were modified by a set of edits.
-class _EditMapper implements OffsetMapper {
-  /// A list whose elements are the highest pre-edit offset for which the
-  /// corresponding element of [_deltas] should be applied.
-  final List<int> _offsets = [];
-
-  /// A list whose elements are the deltas to be applied for all pre-edit
-  /// offsets that are less than or equal to the corresponding element of
-  /// [_offsets].
-  final List<int> _deltas = [];
-
-  /// Initialize a newly created mapper based on the given set of [edits].
-  _EditMapper(List<SourceEdit> edits) {
-    _initializeDeltas(edits);
-  }
-
-  @override
-  int map(int offset) => offset + _deltaFor(offset);
-
-  /// Return the delta to be added to the pre-edit [offset] to produce the
-  /// post-edit offset.
-  int _deltaFor(int offset) {
-    for (var i = 0; i < _offsets.length; i++) {
-      var currentOffset = _offsets[i];
-      if (currentOffset >= offset || currentOffset < 0) {
-        return _deltas[i];
-      }
-    }
-    // We should never get here because [_initializeDeltas] always adds an
-    // offset/delta pair at the end of the list whose offset is less than zero.
-    return 0;
-  }
-
-  /// Initialize the list of old offsets and deltas used by [_deltaFor].
-  void _initializeDeltas(List<SourceEdit> edits) {
-    var previousDelta = 0;
-    for (var edit in edits) {
-      var offset = edit.offset;
-      var length = edit.length;
-      _offsets.add(offset);
-      _deltas.add(previousDelta);
-      previousDelta += (edit.replacement.length - length);
-    }
-    _offsets.add(-1);
-    _deltas.add(previousDelta);
-  }
-}
-
-/// A mapper used for files that were not modified.
-class _IdentityMapper implements OffsetMapper {
-  @override
-  int map(int offset) => offset;
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
deleted file mode 100644
index 9205c30..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/file_system/file_system.dart';
-
-/// An object that can map the file paths of analyzed files to the file paths of
-/// the HTML files used to view the content of those files.
-class PathMapper {
-  /// The resource provider used to map paths.
-  ResourceProvider provider;
-
-  /// The index to be used when creating the next synthetic file name.
-  int nextIndex = 1;
-
-  /// Initialize a newly created path mapper.
-  PathMapper(this.provider);
-
-  /// Return the path of the HTML file used to view the content of the analyzed
-  /// file with the given [path].
-  String map(String path) {
-    return Uri.file(path).path;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
deleted file mode 100644
index f1aea6c..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/edit_details.dart';
-import 'package:path/path.dart' as path;
-
-/// The HTML that is displayed for a region of code.
-class RegionRenderer {
-  /// A flag indicating whether the incremental workflow is currently supported.
-  static const bool supportsIncrementalWorkflow = true;
-
-  /// The region to render.
-  final RegionInfo region;
-
-  /// The compilation unit information containing the region.
-  final UnitInfo unitInfo;
-
-  final MigrationInfo migrationInfo;
-
-  /// An object used to map the file paths of analyzed files to the file paths
-  /// of the HTML files used to view the content of those files.
-  final PathMapper pathMapper;
-
-  /// Initializes a newly created region page within the given [site]. The
-  /// [unitInfo] provides the information needed to render the page.
-  RegionRenderer(
-      this.region, this.unitInfo, this.migrationInfo, this.pathMapper);
-
-  /// Returns the path context used to manipulate paths.
-  path.Context get pathContext => migrationInfo.pathContext;
-
-  EditDetails render() {
-    var unitDir = pathContext.dirname(pathMapper.map(unitInfo.path));
-
-    TargetLink linkForTarget(NavigationTarget target) {
-      var relativePath = _relativePathToTarget(target, unitDir);
-      var targetUri = _uriForRelativePath(relativePath, target);
-      return TargetLink(
-        path: relativePath,
-        href: targetUri,
-        line: target.line,
-      );
-    }
-
-    EditLink linkForEdit(EditDetail edit) => EditLink(
-        description: edit.description,
-        href: Uri(
-            scheme: 'http',
-            path: pathContext.basename(unitInfo.path),
-            queryParameters: {
-              'offset': edit.offset.toString(),
-              'end': (edit.offset + edit.length).toString(),
-              'replacement': edit.replacement
-            }).toString());
-
-    var response = EditDetails(
-      path: unitInfo.path,
-      line: region.lineNumber,
-      explanation: region.explanation,
-      details: [
-        for (var detail in region.details)
-          EditRationale(
-              description: detail.description,
-              link:
-                  detail.target == null ? null : linkForTarget(detail.target)),
-      ],
-      edits: supportsIncrementalWorkflow
-          ? [
-              for (var edit in region.edits) linkForEdit(edit),
-            ]
-          : null,
-      traces: [
-        for (var trace in region.traces)
-          Trace(description: trace.description, entries: [
-            for (var entry in trace.entries)
-              TraceEntry(
-                  description: entry.description,
-                  function: entry.function,
-                  link:
-                      entry.target == null ? null : linkForTarget(entry.target))
-          ])
-      ],
-    );
-    return response;
-  }
-
-  /// Returns the URL that will navigate to the given [target].
-  String _relativePathToTarget(NavigationTarget target, String unitDir) {
-    if (target == null) {
-      // TODO(brianwilkerson) This is temporary support until we can get targets
-      //  for all nodes.
-      return '';
-    }
-    return pathContext.relative(pathMapper.map(target.filePath), from: unitDir);
-  }
-
-  /// Return the URL that will navigate to the given [target] in the file at the
-  /// given [relativePath].
-  String _uriForRelativePath(String relativePath, NavigationTarget target) {
-    var queryParams = {
-      'offset': target.offset,
-      if (target.line != null) 'line': target.line,
-    }.entries.map((entry) => '${entry.key}=${entry.value}').join('&');
-    return '$relativePath?$queryParams';
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
deleted file mode 100644
index 96f80c9..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<html>
-<head>
-    <title>Null Safety Preview</title>
-    <script src="{{ highlightJsPath }}"></script>
-    <script>{{ dartPageScript }}</script>
-    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap">
-    <link rel="stylesheet" href="{{ highlightStylePath }}">
-    <style>{{ dartPageStyle }}</style>
-</head>
-<body class="{{ migrationAppliedStyle }}">
-<div class="rerunning-pane">
-  <h1>Rerunning...</h1>
-</div>
-<p class="root">{{ root }}</p>
-<header class="elevation-z4">
-    <h1 class="before-apply">Proposed null safety changes</h1>
-    <h1 class="after-apply">&#10003; Null safety migration applied</h1>
-    <h2 id="unit-name">&nbsp;</h2>
-    <button class="apply-migration before-apply">&#9998; Apply Migration</button>
-    <button class="apply-migration after-apply" disabled>&#9998; Apply Migration</button>
-    <button class="rerun-migration before-apply">&#8635; Rerun From Sources</button>
-</header>
-<div class="panels horizontal">
-    <div class="nav-panel">
-        <div class="nav-inner">
-            <div class="panel-heading">Project Files</div>
-            <div class="nav-tree"></div>
-        </div><!-- /nav-inner -->
-    </div><!-- /nav -->
-    <div class="content">
-        <div class="regions">
-            <!-- The regions overlay code copy of the content to provide -->
-            <!-- tooltips for modified regions. -->
-        </div><!-- /regions -->
-        <div class="code">
-            <!-- Compilation unit content is written here. -->
-            <p class="welcome">
-                Select a source file on the left to preview the proposed edits.
-            </p>
-        </div>
-    </div><!-- /content -->
-    <div class="info-panel">
-        <div class="edit-list">
-            <div class="panel-heading">Proposed Edits</div>
-            <div class="panel-content"></div>
-        </div><!-- /edit-list -->
-        <div class="edit-panel">
-            <div class="panel-heading">Edit Details</div>
-            <div class="panel-content">
-                <p class="placeholder">See details about a proposed edit.</p>
-            </div><!-- /panel-content -->
-        </div><!-- /edit-panel -->
-    </div><!-- /info-panel -->
-</div><!-- /panels -->
-<footer>
-    <a target="_blank"
-       href="https://github.com/dart-lang/sdk/blob/master/pkg/nnbd_migration/README.md">Null
-        safety migration help</a>
-    <span class="wide"> </span>
-    <div>Based on {{ sdkVersion }}</div>
-</footer>
-</body>
-</html>
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
deleted file mode 100644
index 76ae137..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
+++ /dev/null
@@ -1,455 +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.                   */
-
-body {
-  background-color: #12202f;
-  color: #ccc;
-  font-family: "Roboto", sans-serif;
-  font-size: 14px;
-  display: flex;
-  flex-direction: column;
-  position: absolute;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  margin: 0;
-  padding: 0;
-  overflow: hidden;
-}
-
-.proposed .after-apply {
-  display: none;
-}
-
-.applied .before-apply {
-  display: none;
-}
-
-header {
-  background-color: #1c2834;
-  height: 48px;
-  padding-left: 24px;
-  align-items: center;
-  z-index: 4;
-}
-
-header h1,
-header h2 {
-  display: inline-block;
-  font-family: "Google Sans","Roboto",sans-serif;
-  font-weight: 400;
-  margin-right: 24px;
-}
-
-h1 {
-  font-size: 1.5em;
-}
-
-header h2 {
-  font-size: 1.2em;
-}
-
-header .apply-migration, .rerun-migration {
-  right: 0px;
-  float: right;
-  margin: 10px;
-}
-
-footer {
-  color: #ccc;
-  background-color: #27323a;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  padding: 8px 24px;
-}
-
-footer .wide {
-  flex: 1;
-}
-
-.horizontal {
-  display: flex;
-}
-
-.panels {
-  background-color: #121a25;
-  flex: 1;
-  overflow: hidden;
-}
-
-.panel-heading {
-  color: gray;
-  margin: 8px;
-}
-
-.nav-link,
-.region {
-  cursor: pointer;
-}
-
-.nav-panel {
-  background-color: #282b2e;
-  flex: 1 200px;
-  margin: 0;
-  overflow: scroll;
-}
-
-.nav-inner {
-  padding: 0 0 7px 7px;
-}
-
-.fixed {
-  position: fixed;
-  top: 0;
-}
-
-.root {
-  margin: 0;
-  display: none;
-}
-
-.nav-tree > ul {
-  padding-left: 6px;
-}
-
-.nav-inner ul {
-  padding-left: 12px;
-  margin: 0;
-}
-
-.nav-inner li {
-  list-style-type: none;
-}
-
-.nav-inner li:not(.dir) {
-  margin-left: 20px;
-  margin-bottom: 3px;
-}
-
-.nav-inner li.dir .arrow {
-  cursor: pointer;
-  display: inline-block;
-  font-size: 10px;
-  margin-right: 4px;
-  transition: transform 0.5s ease-out;
-}
-
-.nav-inner li.dir .arrow.collapsed {
-  transform: rotate(-90deg);
-}
-
-.nav-inner ul {
-  max-height: 2000px;
-  transition: max-height 0.5s ease-out;
-}
-
-.nav-inner ul.collapsed {
-  max-height: 0 !important;
-  overflow: hidden;
-}
-
-.nav-inner .selected-file {
-  color: white;
-  cursor: inherit;
-  font-weight: 600;
-  text-decoration: none;
-}
-
-.edit-count {
-  background-color: #37aedc;
-  border-radius: 10px;
-  color: #000000;
-  display: inline-block;
-  font-size: 11px;
-  font-weight: 600;
-  margin-left: 5px;
-  min-width: 25px;
-  padding: 4px 0 2px 0;
-  text-align: center;
-  line-height: 1em;
-}
-
-.content {
-  flex: 4 300px;
-  background: #282b2e;
-  font-family: monospace;
-  margin: 0 6px;
-  position: relative;
-  white-space: pre;
-  overflow: scroll;
-}
-
-.code {
-  padding: 0.5em;
-  position: absolute;
-  left: 0;
-  top: 0;
-  margin-left: 56px;
-}
-
-.hljs {
-  background-color: #282b2e;
-  display: block;
-  overflow-x: auto;
-  padding: 0.5em;
-}
-
-.code .welcome {
-  font-family: "Google Sans","Roboto",sans-serif;
-  font-size: 18px;
-  margin-right: 62px;
-  color: #777;
-}
-
-.code .nav-link {
-  color: inherit;
-  text-decoration-line: none;
-}
-
-.code .nav-link:visited {
-  color: inherit;
-  text-decoration-line: none;
-}
-
-.code .nav-link:hover {
-  text-decoration-line: underline;
-  font-weight: 600;
-}
-
-.regions {
-  padding: 0.5em;
-  position: absolute;
-  left: 0;
-  top: 0;
-}
-
-.regions table {
-  border-spacing: 0;
-  font-size: inherit;
-}
-
-.regions td {
-  border: none;
-  /* The content of the regions is not visible; the user instead will see the
-   * highlighted copy of the content. */
-  color: rgba(255, 255, 255, 0);
-  padding: 0;
-  white-space: pre;
-}
-
-.regions td:empty:after {
-  content: "\00a0";
-}
-
-.regions tr.highlight td:last-child {
-  background-color: #444444;
-  color: white;
-}
-
-.regions td.line-no {
-  border-right: solid #282b2e 2px;
-  color: #999999;
-  padding-right: 4px;
-  text-align: right;
-  visibility: visible;
-  width: 50px;
-  display: inline-block;
-}
-
-.regions tr.highlight td.line-no {
-  border-right: solid #ccc 2px;
-}
-
-.region {
-  display: inline-block;
-  position: relative;
-  visibility: visible;
-  z-index: 200;
-}
-
-.region.added-region {
-  background-color: #ccffcc;
-  color: #003300;
-}
-
-.region.removed-region {
-  background-color: #ff6666;
-  color: #001100;
-}
-
-.region.informative-region {
-  background-color: #888888;
-  color: #000000;
-}
-
-.target {
-  background-color: #444;
-  position: relative;
-  visibility: visible;
-  font-weight: 600;
-}
-
-.info-panel {
-  flex: 1 200px;
-  margin: 0;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-}
-
-.info-panel .edit-panel {
-  background-color: #282b2e;
-  overflow: auto;
-}
-
-.info-panel .panel-content {
-  padding: 7px;
-}
-
-.info-panel .panel-content> :first-child {
-  margin-top: 0;
-}
-
-.info-panel .nowrap {
-  white-space: nowrap;
-}
-
-.info-panel ul,
-.info-panel ol {
-  padding-left: 20px;
-}
-
-.info-panel li {
-  margin: 0 0 5px 0;
-}
-
-.info-panel a {
-  color: #33ccff;
-}
-
-.info-panel .edit-list {
-  background-color: #282b2e;
-  overflow: auto;
-}
-
-.edit-panel {
-  margin-top: 6px;
-  flex: 1 100px;
-}
-
-.edit-list {
-  flex: 2 100px;
-}
-
-.edit-list .edit {
-  margin: 3px 0;
-}
-
-.edit-list .edit-link {
-  cursor: pointer;
-}
-
-.rerunning-pane {
-  display: none;
-}
-
-body.rerunning .rerunning-pane {
-  display: block;
-  position: fixed;
-  top: 0px;
-  bottom: 0px;
-  left: 0px;
-  right: 0px;
-  background-color: #000000AA; /* translucent black */
-  z-index: 400;
-}
-
-.rerunning-pane h1 {
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
-}
-
-p.trace .type-description {
-  /* From HLJS's .hljs-keyword, .hljs-selector-tag, .hljs-deletion */
-  color: #cc7832;
-  font-family: monospace;
-}
-
-ul.trace {
-  font-size: 13px;
-  list-style-type: none;
-  padding-left: 0px;
-}
-
-ul.trace li {
-  color: white;
-  margin-left: 14px;
-  text-indent: -14px;
-}
-
-ul.trace li .function {
-  /* From HLJS's .hljs-section, .hljs-title, .hljs-type */
-  color: #ffc66d;
-  font-family: monospace;
-  font-weight: 600;
-}
-
-.elevation-z4 {
-  box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
-      0px 4px 5px 0px rgba(0, 0, 0, 0.14),
-      0px 1px 10px 0px rgba(0, 0, 0, .12);
-}
-
-a {
-  color: #ccc;
-  fill: #ccc;
-  text-decoration: none;
-}
-
-a:hover {
-  color: #fff;
-  fill: #fff;
-}
-
-button {
-  background-color: #33ccff;
-  border: 2px solid #37aedc;
-  border-radius: 3px;
-  padding: 6px 10px;
-  font-weight: bold;
-  color: #282828;
-}
-
-button:hover {
-  background-color: #80dfff;
-  border: 2px solid #52b8e0;
-  cursor: pointer;
-}
-
-button[disabled] {
-  background-color: #7aa8b8;
-  color: #507177;
-  border: 2px solid #507177;
-  cursor: not-allowed;
-}
-
-.placeholder {
-  color: #777;
-  text-align: center;
-  margin-top: 3em !important;
-}
-
-/**
- * HLJS Overrides
- */
-.hljs {
-  /**
-   * This allows the per-line highlights to show.
-   */
-  background: none;
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
deleted file mode 100644
index a1b30c5..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
+++ /dev/null
@@ -1,4094 +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 is generated; don't edit it directly.
-//
-// See pkg/analysis_server/tool/nnbd_migration/generate_resources.dart for how
-// to edit the source content and for re-generation instructions.
-
-import 'dart:convert' as convert;
-
-String get highlight_css {
-  return _highlight_css ??= _decode(_highlight_css_base64);
-}
-
-String get highlight_pack_js {
-  return _highlight_pack_js ??= _decode(_highlight_pack_js_base64);
-}
-
-String get index_html {
-  return _index_html ??= _decode(_index_html_base64);
-}
-
-String get migration_css {
-  return _migration_css ??= _decode(_migration_css_base64);
-}
-
-String get migration_js {
-  return _migration_js ??= _decode(_migration_js_base64);
-}
-
-String _decode(String data) {
-  data = data.replaceAll('\n', '').trim();
-  return String.fromCharCodes(convert.base64Decode(data));
-}
-
-String _highlight_css;
-// highlight_css md5 is 'fb012626bafd286510d32da815dae448'
-String _highlight_css_base64 = '''
-LyoKRGF0ZTogMjQgRmV2IDIwMTUKQXV0aG9yOiBQZWRybyBPbGl2ZWlyYSA8a2FueXR1QGdtYWlsIC4g
-Y29tPgoqLwoKLmhsanMgewogIGNvbG9yOiAjYTliN2M2OwogIGJhY2tncm91bmQ6ICMyODJiMmU7CiAg
-ZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKfQoKLmhs
-anMtbnVtYmVyLAouaGxqcy1saXRlcmFsLAouaGxqcy1zeW1ib2wsCi5obGpzLWJ1bGxldCB7CiAgY29s
-b3I6ICM2ODk3QkI7Cn0KCi5obGpzLWtleXdvcmQsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhsanMtZGVs
-ZXRpb24gewogIGNvbG9yOiAjY2M3ODMyOwp9CgouaGxqcy12YXJpYWJsZSwKLmhsanMtdGVtcGxhdGUt
-dmFyaWFibGUsCi5obGpzLWxpbmsgewogIGNvbG9yOiAjNjI5NzU1Owp9CgouaGxqcy1jb21tZW50LAou
-aGxqcy1xdW90ZSB7CiAgY29sb3I6ICM4MDgwODA7Cn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjYmJi
-NTI5Owp9CgouaGxqcy1zdHJpbmcsCi5obGpzLWF0dHJpYnV0ZSwKLmhsanMtYWRkaXRpb24gewogIGNv
-bG9yOiAjNkE4NzU5Owp9CgouaGxqcy1zZWN0aW9uLAouaGxqcy10aXRsZSwKLmhsanMtdHlwZSB7CiAg
-Y29sb3I6ICNmZmM2NmQ7Cn0KCi5obGpzLW5hbWUsCi5obGpzLXNlbGVjdG9yLWlkLAouaGxqcy1zZWxl
-Y3Rvci1jbGFzcyB7CiAgY29sb3I6ICNlOGJmNmE7Cn0KCi5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0
-eWxlOiBpdGFsaWM7Cn0KCi5obGpzLXN0cm9uZyB7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7Cn0K
-''';
-
-String _highlight_pack_js;
-// highlight_pack_js md5 is '9104bfe8b056f8e00da50b0ea3d6e6d4'
-String _highlight_pack_js_base64 = '''
-LyohIGhpZ2hsaWdodC5qcyB2OS4xNS4xMCB8IEJTRDMgTGljZW5zZSB8IGdpdC5pby9obGpzbGljZW5z
-ZSAqLwohZnVuY3Rpb24oZSl7dmFyIG49Im9iamVjdCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvd3x8Im9i
-amVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmOyJ1bmRlZmluZWQiPT10eXBlb2YgZXhwb3J0c3x8ZXhwb3J0
-cy5ub2RlVHlwZT9uJiYobi5obGpzPWUoe30pLCJmdW5jdGlvbiI9PXR5cGVvZiBkZWZpbmUmJmRlZmlu
-ZS5hbWQmJmRlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiBuLmhsanN9KSk6ZShleHBvcnRzKX0oZnVu
-Y3Rpb24oYSl7dmFyIGY9W10sdT1PYmplY3Qua2V5cyxOPXt9LGM9e30sbj0vXihuby0/aGlnaGxpZ2h0
-fHBsYWlufHRleHQpJC9pLHM9L1xibGFuZyg/OnVhZ2UpPy0oW1x3LV0rKVxiL2ksdD0vKCheKDxbXj5d
-Kz58XHR8KSt8KD86XG4pKSkvZ20scj17Y2FzZV9pbnNlbnNpdGl2ZToiY0kiLGxleGVtZXM6ImwiLGNv
-bnRhaW5zOiJjIixrZXl3b3JkczoiayIsc3ViTGFuZ3VhZ2U6InNMIixjbGFzc05hbWU6ImNOIixiZWdp
-bjoiYiIsYmVnaW5LZXl3b3JkczoiYksiLGVuZDoiZSIsZW5kc1dpdGhQYXJlbnQ6ImVXIixpbGxlZ2Fs
-OiJpIixleGNsdWRlQmVnaW46ImVCIixleGNsdWRlRW5kOiJlRSIscmV0dXJuQmVnaW46InJCIixyZXR1
-cm5FbmQ6InJFIixyZWxldmFuY2U6InIiLHZhcmlhbnRzOiJ2IixJREVOVF9SRToiSVIiLFVOREVSU0NP
-UkVfSURFTlRfUkU6IlVJUiIsTlVNQkVSX1JFOiJOUiIsQ19OVU1CRVJfUkU6IkNOUiIsQklOQVJZX05V
-TUJFUl9SRToiQk5SIixSRV9TVEFSVEVSU19SRToiUlNSIixCQUNLU0xBU0hfRVNDQVBFOiJCRSIsQVBP
-U19TVFJJTkdfTU9ERToiQVNNIixRVU9URV9TVFJJTkdfTU9ERToiUVNNIixQSFJBU0FMX1dPUkRTX01P
-REU6IlBXTSIsQ19MSU5FX0NPTU1FTlRfTU9ERToiQ0xDTSIsQ19CTE9DS19DT01NRU5UX01PREU6IkNC
-Q00iLEhBU0hfQ09NTUVOVF9NT0RFOiJIQ00iLE5VTUJFUl9NT0RFOiJOTSIsQ19OVU1CRVJfTU9ERToi
-Q05NIixCSU5BUllfTlVNQkVSX01PREU6IkJOTSIsQ1NTX05VTUJFUl9NT0RFOiJDU1NOTSIsUkVHRVhQ
-X01PREU6IlJNIixUSVRMRV9NT0RFOiJUTSIsVU5ERVJTQ09SRV9USVRMRV9NT0RFOiJVVE0iLENPTU1F
-TlQ6IkMiLGJlZ2luUmU6ImJSIixlbmRSZToiZVIiLGlsbGVnYWxSZToiaVIiLGxleGVtZXNSZToibFIi
-LHRlcm1pbmF0b3JzOiJ0Iix0ZXJtaW5hdG9yX2VuZDoidEUifSxiPSI8L3NwYW4+IixoPXtjbGFzc1By
-ZWZpeDoiaGxqcy0iLHRhYlJlcGxhY2U6bnVsbCx1c2VCUjohMSxsYW5ndWFnZXM6dm9pZCAwfTtmdW5j
-dGlvbiBfKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsi
-KS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiBFKGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93
-ZXJDYXNlKCl9ZnVuY3Rpb24gdihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQu
-aW5kZXh9ZnVuY3Rpb24gbChlKXtyZXR1cm4gbi50ZXN0KGUpfWZ1bmN0aW9uIGcoZSl7dmFyIG4sdD17
-fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09
-ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1m
-dW5jdGlvbiBSKGUpe3ZhciBhPVtdO3JldHVybiBmdW5jdGlvbiBlKG4sdCl7Zm9yKHZhciByPW4uZmly
-c3RDaGlsZDtyO3I9ci5uZXh0U2libGluZykzPT09ci5ub2RlVHlwZT90Kz1yLm5vZGVWYWx1ZS5sZW5n
-dGg6MT09PXIubm9kZVR5cGUmJihhLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnQsbm9kZTpyfSks
-dD1lKHIsdCksRShyKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fGEucHVzaCh7ZXZlbnQ6InN0b3Ai
-LG9mZnNldDp0LG5vZGU6cn0pKTtyZXR1cm4gdH0oZSwwKSxhfWZ1bmN0aW9uIGkoZSl7aWYociYmIWUu
-bGFuZ0FwaVJlc3RvcmVkKXtmb3IodmFyIG4gaW4gZS5sYW5nQXBpUmVzdG9yZWQ9ITAscillW25dJiYo
-ZVtyW25dXT1lW25dKTsoZS5jfHxbXSkuY29uY2F0KGUudnx8W10pLmZvckVhY2goaSl9fWZ1bmN0aW9u
-IG0obyl7ZnVuY3Rpb24gcyhlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gYyhlLG4pe3Jl
-dHVybiBuZXcgUmVnRXhwKHMoZSksIm0iKyhvLmNJPyJpIjoiIikrKG4/ImciOiIiKSl9IWZ1bmN0aW9u
-IG4odCxlKXtpZighdC5jb21waWxlZCl7aWYodC5jb21waWxlZD0hMCx0Lms9dC5rfHx0LmJLLHQuayl7
-ZnVuY3Rpb24gcih0LGUpe28uY0kmJihlPWUudG9Mb3dlckNhc2UoKSksZS5zcGxpdCgiICIpLmZvckVh
-Y2goZnVuY3Rpb24oZSl7dmFyIG49ZS5zcGxpdCgifCIpO2FbblswXV09W3QsblsxXT9OdW1iZXIoblsx
-XSk6MV19KX12YXIgYT17fTsic3RyaW5nIj09dHlwZW9mIHQuaz9yKCJrZXl3b3JkIix0LmspOnUodC5r
-KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3IoZSx0LmtbZV0pfSksdC5rPWF9dC5sUj1jKHQubHx8L1x3Ky8s
-ITApLGUmJih0LmJLJiYodC5iPSJcXGIoIit0LmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiks
-dC5ifHwodC5iPS9cQnxcYi8pLHQuYlI9Yyh0LmIpLHQuZW5kU2FtZUFzQmVnaW4mJih0LmU9dC5iKSx0
-LmV8fHQuZVd8fCh0LmU9L1xCfFxiLyksdC5lJiYodC5lUj1jKHQuZSkpLHQudEU9cyh0LmUpfHwiIix0
-LmVXJiZlLnRFJiYodC50RSs9KHQuZT8ifCI6IiIpK2UudEUpKSx0LmkmJih0LmlSPWModC5pKSksbnVs
-bD09dC5yJiYodC5yPTEpLHQuY3x8KHQuYz1bXSksdC5jPUFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBw
-bHkoW10sdC5jLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4udiYmIW4u
-Y2FjaGVkX3ZhcmlhbnRzJiYobi5jYWNoZWRfdmFyaWFudHM9bi52Lm1hcChmdW5jdGlvbihlKXtyZXR1
-cm4gZyhuLHt2Om51bGx9LGUpfSkpLG4uY2FjaGVkX3ZhcmlhbnRzfHxuLmVXJiZbZyhuKV18fFtuXX0o
-InNlbGYiPT09ZT90OmUpfSkpLHQuYy5mb3JFYWNoKGZ1bmN0aW9uKGUpe24oZSx0KX0pLHQuc3RhcnRz
-JiZuKHQuc3RhcnRzLGUpO3ZhciBpPXQuYy5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGUuYks/IlxcLj8o
-PzoiK2UuYisiKVxcLj8iOmUuYn0pLmNvbmNhdChbdC50RSx0LmldKS5tYXAocykuZmlsdGVyKEJvb2xl
-YW4pO3QudD1pLmxlbmd0aD9jKGZ1bmN0aW9uKGUsbil7Zm9yKHZhciB0PS9cWyg/OlteXFxcXV18XFwu
-KSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixpPTA7aTxlLmxlbmd0aDtpKysp
-e3ZhciBvPXIsYz1zKGVbaV0pO2ZvcigwPGkmJihhKz1uKTswPGMubGVuZ3RoOyl7dmFyIHU9dC5leGVj
-KGMpO2lmKG51bGw9PXUpe2ErPWM7YnJlYWt9YSs9Yy5zdWJzdHJpbmcoMCx1LmluZGV4KSxjPWMuc3Vi
-c3RyaW5nKHUuaW5kZXgrdVswXS5sZW5ndGgpLCJcXCI9PXVbMF1bMF0mJnVbMV0/YSs9IlxcIitTdHJp
-bmcoTnVtYmVyKHVbMV0pK28pOihhKz11WzBdLCIoIj09dVswXSYmcisrKX19cmV0dXJuIGF9KGksInwi
-KSwhMCk6e2V4ZWM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH19fX0obyl9ZnVuY3Rpb24gQyhlLG4saSx0
-KXtmdW5jdGlvbiBjKGUsbix0LHIpe3ZhciBhPSc8c3BhbiBjbGFzcz0iJysocj8iIjpoLmNsYXNzUHJl
-Zml4KTtyZXR1cm4gZT8oYSs9ZSsnIj4nKStuKyh0PyIiOmIpOm59ZnVuY3Rpb24gbygpe0UrPW51bGwh
-PWwuc0w/ZnVuY3Rpb24oKXt2YXIgZT0ic3RyaW5nIj09dHlwZW9mIGwuc0w7aWYoZSYmIU5bbC5zTF0p
-cmV0dXJuIF8oZyk7dmFyIG49ZT9DKGwuc0wsZywhMCxmW2wuc0xdKTpPKGcsbC5zTC5sZW5ndGg/bC5z
-TDp2b2lkIDApO3JldHVybiAwPGwuciYmKFIrPW4uciksZSYmKGZbbC5zTF09bi50b3ApLGMobi5sYW5n
-dWFnZSxuLnZhbHVlLCExLCEwKX0oKTpmdW5jdGlvbigpe3ZhciBlLG4sdCxyLGEsaSxvO2lmKCFsLmsp
-cmV0dXJuIF8oZyk7Zm9yKHI9IiIsbj0wLGwubFIubGFzdEluZGV4PTAsdD1sLmxSLmV4ZWMoZyk7dDsp
-cis9XyhnLnN1YnN0cmluZyhuLHQuaW5kZXgpKSxhPWwsaT10LHZvaWQgMCxvPXMuY0k/aVswXS50b0xv
-d2VyQ2FzZSgpOmlbMF0sKGU9YS5rLmhhc093blByb3BlcnR5KG8pJiZhLmtbb10pPyhSKz1lWzFdLHIr
-PWMoZVswXSxfKHRbMF0pKSk6cis9Xyh0WzBdKSxuPWwubFIubGFzdEluZGV4LHQ9bC5sUi5leGVjKGcp
-O3JldHVybiByK18oZy5zdWJzdHIobikpfSgpLGc9IiJ9ZnVuY3Rpb24gdShlKXtFKz1lLmNOP2MoZS5j
-TiwiIiwhMCk6IiIsbD1PYmplY3QuY3JlYXRlKGUse3BhcmVudDp7dmFsdWU6bH19KX1mdW5jdGlvbiBy
-KGUsbil7aWYoZys9ZSxudWxsPT1uKXJldHVybiBvKCksMDt2YXIgdD1mdW5jdGlvbihlLG4pe3ZhciB0
-LHIsYTtmb3IodD0wLHI9bi5jLmxlbmd0aDt0PHI7dCsrKWlmKHYobi5jW3RdLmJSLGUpKXJldHVybiBu
-LmNbdF0uZW5kU2FtZUFzQmVnaW4mJihuLmNbdF0uZVI9KGE9bi5jW3RdLmJSLmV4ZWMoZSlbMF0sbmV3
-IFJlZ0V4cChhLnJlcGxhY2UoL1stXC9cXF4kKis/LigpfFtcXXt9XS9nLCJcXCQmIiksIm0iKSkpLG4u
-Y1t0XX0obixsKTtpZih0KXJldHVybiB0LnNraXA/Zys9bjoodC5lQiYmKGcrPW4pLG8oKSx0LnJCfHx0
-LmVCfHwoZz1uKSksdSh0KSx0LnJCPzA6bi5sZW5ndGg7dmFyIHI9ZnVuY3Rpb24gZShuLHQpe2lmKHYo
-bi5lUix0KSl7Zm9yKDtuLmVuZHNQYXJlbnQmJm4ucGFyZW50OyluPW4ucGFyZW50O3JldHVybiBufWlm
-KG4uZVcpcmV0dXJuIGUobi5wYXJlbnQsdCl9KGwsbik7aWYocil7dmFyIGE9bDtmb3IoYS5za2lwP2cr
-PW46KGEuckV8fGEuZUV8fChnKz1uKSxvKCksYS5lRSYmKGc9bikpO2wuY04mJihFKz1iKSxsLnNraXB8
-fGwuc0x8fChSKz1sLnIpLChsPWwucGFyZW50KSE9PXIucGFyZW50Oyk7cmV0dXJuIHIuc3RhcnRzJiYo
-ci5lbmRTYW1lQXNCZWdpbiYmKHIuc3RhcnRzLmVSPXIuZVIpLHUoci5zdGFydHMpKSxhLnJFPzA6bi5s
-ZW5ndGh9aWYoZnVuY3Rpb24oZSxuKXtyZXR1cm4haSYmdihuLmlSLGUpfShuLGwpKXRocm93IG5ldyBF
-cnJvcignSWxsZWdhbCBsZXhlbWUgIicrbisnIiBmb3IgbW9kZSAiJysobC5jTnx8Ijx1bm5hbWVkPiIp
-KyciJyk7cmV0dXJuIGcrPW4sbi5sZW5ndGh8fDF9dmFyIHM9QihlKTtpZighcyl0aHJvdyBuZXcgRXJy
-b3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTttKHMpO3ZhciBhLGw9dHx8cyxmPXt9LEU9IiI7
-Zm9yKGE9bDthIT09czthPWEucGFyZW50KWEuY04mJihFPWMoYS5jTiwiIiwhMCkrRSk7dmFyIGc9IiIs
-Uj0wO3RyeXtmb3IodmFyIGQscCxNPTA7bC50Lmxhc3RJbmRleD1NLGQ9bC50LmV4ZWMobik7KXA9cihu
-LnN1YnN0cmluZyhNLGQuaW5kZXgpLGRbMF0pLE09ZC5pbmRleCtwO2ZvcihyKG4uc3Vic3RyKE0pKSxh
-PWw7YS5wYXJlbnQ7YT1hLnBhcmVudClhLmNOJiYoRSs9Yik7cmV0dXJue3I6Uix2YWx1ZTpFLGxhbmd1
-YWdlOmUsdG9wOmx9fWNhdGNoKGUpe2lmKGUubWVzc2FnZSYmLTEhPT1lLm1lc3NhZ2UuaW5kZXhPZigi
-SWxsZWdhbCIpKXJldHVybntyOjAsdmFsdWU6XyhuKX07dGhyb3cgZX19ZnVuY3Rpb24gTyh0LGUpe2U9
-ZXx8aC5sYW5ndWFnZXN8fHUoTik7dmFyIHI9e3I6MCx2YWx1ZTpfKHQpfSxhPXI7cmV0dXJuIGUuZmls
-dGVyKEIpLmZpbHRlcihNKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBuPUMoZSx0LCExKTtuLmxhbmd1
-YWdlPWUsbi5yPmEuciYmKGE9biksbi5yPnIuciYmKGE9cixyPW4pfSksYS5sYW5ndWFnZSYmKHIuc2Vj
-b25kX2Jlc3Q9YSkscn1mdW5jdGlvbiBkKGUpe3JldHVybiBoLnRhYlJlcGxhY2V8fGgudXNlQlI/ZS5y
-ZXBsYWNlKHQsZnVuY3Rpb24oZSxuKXtyZXR1cm4gaC51c2VCUiYmIlxuIj09PWU/Ijxicj4iOmgudGFi
-UmVwbGFjZT9uLnJlcGxhY2UoL1x0L2csaC50YWJSZXBsYWNlKToiIn0pOmV9ZnVuY3Rpb24gbyhlKXt2
-YXIgbix0LHIsYSxpLG89ZnVuY3Rpb24oZSl7dmFyIG4sdCxyLGEsaT1lLmNsYXNzTmFtZSsiICI7aWYo
-aSs9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1zLmV4ZWMoaSkpcmV0dXJu
-IEIodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobj0wLHI9KGk9aS5zcGxpdCgvXHMrLykpLmxl
-bmd0aDtuPHI7bisrKWlmKGwoYT1pW25dKXx8QihhKSlyZXR1cm4gYX0oZSk7bChvKXx8KGgudXNlQlI/
-KG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwi
-ZGl2IikpLmlubmVySFRNTD1lLmlubmVySFRNTC5yZXBsYWNlKC9cbi9nLCIiKS5yZXBsYWNlKC88YnJb
-IFwvXSo+L2csIlxuIik6bj1lLGk9bi50ZXh0Q29udGVudCxyPW8/QyhvLGksITApOk8oaSksKHQ9Uihu
-KSkubGVuZ3RoJiYoKGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8x
-OTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1yLnZhbHVlLHIudmFsdWU9ZnVuY3Rpb24oZSxuLHQp
-e3ZhciByPTAsYT0iIixpPVtdO2Z1bmN0aW9uIG8oKXtyZXR1cm4gZS5sZW5ndGgmJm4ubGVuZ3RoP2Vb
-MF0ub2Zmc2V0IT09blswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8blswXS5vZmZzZXQ/ZTpuOiJzdGFydCI9
-PT1uWzBdLmV2ZW50P2U6bjplLmxlbmd0aD9lOm59ZnVuY3Rpb24gYyhlKXthKz0iPCIrRShlKStmLm1h
-cC5jYWxsKGUuYXR0cmlidXRlcyxmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsnPSInK18o
-ZS52YWx1ZSkucmVwbGFjZSgnIicsIiZxdW90OyIpKyciJ30pLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1
-KGUpe2ErPSI8LyIrRShlKSsiPiJ9ZnVuY3Rpb24gcyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShl
-Lm5vZGUpfWZvcig7ZS5sZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGw9bygpO2lmKGErPV8odC5zdWJzdHJp
-bmcocixsWzBdLm9mZnNldCkpLHI9bFswXS5vZmZzZXQsbD09PWUpe2ZvcihpLnJldmVyc2UoKS5mb3JF
-YWNoKHUpO3MobC5zcGxpY2UoMCwxKVswXSksKGw9bygpKT09PWUmJmwubGVuZ3RoJiZsWzBdLm9mZnNl
-dD09PXI7KTtpLnJldmVyc2UoKS5mb3JFYWNoKGMpfWVsc2Uic3RhcnQiPT09bFswXS5ldmVudD9pLnB1
-c2gobFswXS5ub2RlKTppLnBvcCgpLHMobC5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIGErXyh0LnN1YnN0
-cihyKSl9KHQsUihhKSxpKSksci52YWx1ZT1kKHIudmFsdWUpLGUuaW5uZXJIVE1MPXIudmFsdWUsZS5j
-bGFzc05hbWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPW4/Y1tuXTp0LGE9W2UudHJpbSgpXTtyZXR1cm4g
-ZS5tYXRjaCgvXGJobGpzXGIvKXx8YS5wdXNoKCJobGpzIiksLTE9PT1lLmluZGV4T2YocikmJmEucHVz
-aChyKSxhLmpvaW4oIiAiKS50cmltKCl9KGUuY2xhc3NOYW1lLG8sci5sYW5ndWFnZSksZS5yZXN1bHQ9
-e2xhbmd1YWdlOnIubGFuZ3VhZ2UscmU6ci5yfSxyLnNlY29uZF9iZXN0JiYoZS5zZWNvbmRfYmVzdD17
-bGFuZ3VhZ2U6ci5zZWNvbmRfYmVzdC5sYW5ndWFnZSxyZTpyLnNlY29uZF9iZXN0LnJ9KSl9ZnVuY3Rp
-b24gcCgpe2lmKCFwLmNhbGxlZCl7cC5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlTZWxlY3Rv
-ckFsbCgicHJlIGNvZGUiKTtmLmZvckVhY2guY2FsbChlLG8pfX1mdW5jdGlvbiBCKGUpe3JldHVybiBl
-PShlfHwiIikudG9Mb3dlckNhc2UoKSxOW2VdfHxOW2NbZV1dfWZ1bmN0aW9uIE0oZSl7dmFyIG49Qihl
-KTtyZXR1cm4gbiYmIW4uZGlzYWJsZUF1dG9kZXRlY3R9cmV0dXJuIGEuaGlnaGxpZ2h0PUMsYS5oaWdo
-bGlnaHRBdXRvPU8sYS5maXhNYXJrdXA9ZCxhLmhpZ2hsaWdodEJsb2NrPW8sYS5jb25maWd1cmU9ZnVu
-Y3Rpb24oZSl7aD1nKGgsZSl9LGEuaW5pdEhpZ2hsaWdodGluZz1wLGEuaW5pdEhpZ2hsaWdodGluZ09u
-TG9hZD1mdW5jdGlvbigpe2FkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLHAsITEpLGFk
-ZEV2ZW50TGlzdGVuZXIoImxvYWQiLHAsITEpfSxhLnJlZ2lzdGVyTGFuZ3VhZ2U9ZnVuY3Rpb24obixl
-KXt2YXIgdD1OW25dPWUoYSk7aSh0KSx0LmFsaWFzZXMmJnQuYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9u
-KGUpe2NbZV09bn0pfSxhLmxpc3RMYW5ndWFnZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdShOKX0sYS5nZXRM
-YW5ndWFnZT1CLGEuYXV0b0RldGVjdGlvbj1NLGEuaW5oZXJpdD1nLGEuSVI9YS5JREVOVF9SRT0iW2Et
-ekEtWl1cXHcqIixhLlVJUj1hLlVOREVSU0NPUkVfSURFTlRfUkU9IlthLXpBLVpfXVxcdyoiLGEuTlI9
-YS5OVU1CRVJfUkU9IlxcYlxcZCsoXFwuXFxkKyk/IixhLkNOUj1hLkNfTlVNQkVSX1JFPSIoLT8pKFxc
-YjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQr
-KT8pIixhLkJOUj1hLkJJTkFSWV9OVU1CRVJfUkU9IlxcYigwYlswMV0rKSIsYS5SU1I9YS5SRV9TVEFS
-VEVSU19SRT0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8LXwtPXwvPXwv
-fDp8O3w8PHw8PD18PD18PHw9PT18PT18PXw+Pj49fD4+PXw+PXw+Pj58Pj58PnxcXD98XFxbfFxce3xc
-XCh8XFxefFxcXj18XFx8fFxcfD18XFx8XFx8fH4iLGEuQkU9YS5CQUNLU0xBU0hfRVNDQVBFPXtiOiJc
-XFxcW1xcc1xcU10iLHI6MH0sYS5BU009YS5BUE9TX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiIn
-IixlOiInIixpOiJcXG4iLGM6W2EuQkVdfSxhLlFTTT1hLlFVT1RFX1NUUklOR19NT0RFPXtjTjoic3Ry
-aW5nIixiOiciJyxlOiciJyxpOiJcXG4iLGM6W2EuQkVdfSxhLlBXTT1hLlBIUkFTQUxfV09SRFNfTU9E
-RT17YjovXGIoYXxhbnx0aGV8YXJlfEknbXxpc24ndHxkb24ndHxkb2Vzbid0fHdvbid0fGJ1dHxqdXN0
-fHNob3VsZHxwcmV0dHl8c2ltcGx5fGVub3VnaHxnb25uYXxnb2luZ3x3dGZ8c298c3VjaHx3aWxsfHlv
-dXx5b3VyfHRoZXl8bGlrZXxtb3JlKVxiL30sYS5DPWEuQ09NTUVOVD1mdW5jdGlvbihlLG4sdCl7dmFy
-IHI9YS5pbmhlcml0KHtjTjoiY29tbWVudCIsYjplLGU6bixjOltdfSx0fHx7fSk7cmV0dXJuIHIuYy5w
-dXNoKGEuUFdNKSxyLmMucHVzaCh7Y046ImRvY3RhZyIsYjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xY
-WFgpOiIscjowfSkscn0sYS5DTENNPWEuQ19MSU5FX0NPTU1FTlRfTU9ERT1hLkMoIi8vIiwiJCIpLGEu
-Q0JDTT1hLkNfQkxPQ0tfQ09NTUVOVF9NT0RFPWEuQygiL1xcKiIsIlxcKi8iKSxhLkhDTT1hLkhBU0hf
-Q09NTUVOVF9NT0RFPWEuQygiIyIsIiQiKSxhLk5NPWEuTlVNQkVSX01PREU9e2NOOiJudW1iZXIiLGI6
-YS5OUixyOjB9LGEuQ05NPWEuQ19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLkNOUixyOjB9LGEu
-Qk5NPWEuQklOQVJZX05VTUJFUl9NT0RFPXtjTjoibnVtYmVyIixiOmEuQk5SLHI6MH0sYS5DU1NOTT1h
-LkNTU19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLk5SKyIoJXxlbXxleHxjaHxyZW18dnd8dmh8
-dm1pbnx2bWF4fGNtfG1tfGlufHB0fHBjfHB4fGRlZ3xncmFkfHJhZHx0dXJufHN8bXN8SHp8a0h6fGRw
-aXxkcGNtfGRwcHgpPyIscjowfSxhLlJNPWEuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxl
-Oi9cL1tnaW11eV0qLyxpOi9cbi8sYzpbYS5CRSx7YjovXFsvLGU6L1xdLyxyOjAsYzpbYS5CRV19XX0s
-YS5UTT1hLlRJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLklSLHI6MH0sYS5VVE09YS5VTkRFUlNDT1JF
-X1RJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLlVJUixyOjB9LGEuTUVUSE9EX0dVQVJEPXtiOiJcXC5c
-XHMqIithLlVJUixyOjB9LGF9KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24ocyl7
-dmFyIGU9e2VXOiEwLGk6LzwvLHI6MCxjOlt7Y046ImF0dHIiLGI6IltBLVphLXowLTlcXC5fOi1dKyIs
-cjowfSx7YjovPVxzKi8scjowLGM6W3tjTjoic3RyaW5nIixlbmRzUGFyZW50OiEwLHY6W3tiOi8iLyxl
-Oi8iL30se2I6LycvLGU6LycvfSx7YjovW15ccyInPTw+YF0rL31dfV19XX07cmV0dXJue2FsaWFzZXM6
-WyJodG1sIiwieGh0bWwiLCJyc3MiLCJhdG9tIiwieGpiIiwieHNkIiwieHNsIiwicGxpc3QiLCJ3c2Yi
-XSxjSTohMCxjOlt7Y046Im1ldGEiLGI6IjwhRE9DVFlQRSIsZToiPiIscjoxMCxjOlt7YjoiXFxbIixl
-OiJcXF0ifV19LHMuQygiXHgzYyEtLSIsIi0tXHgzZSIse3I6MTB9KSx7YjoiPFxcIVxcW0NEQVRBXFxb
-IixlOiJcXF1cXF0+IixyOjEwfSx7Y046Im1ldGEiLGI6LzxcP3htbC8sZTovXD8+LyxyOjEwfSx7Yjov
-PFw/KHBocCk/LyxlOi9cPz4vLHNMOiJwaHAiLGM6W3tiOiIvXFwqIixlOiJcXCovIixza2lwOiEwfSx7
-YjonYiInLGU6JyInLHNraXA6ITB9LHtiOiJiJyIsZToiJyIsc2tpcDohMH0scy5pbmhlcml0KHMuQVNN
-LHtpOm51bGwsY046bnVsbCxjOm51bGwsc2tpcDohMH0pLHMuaW5oZXJpdChzLlFTTSx7aTpudWxsLGNO
-Om51bGwsYzpudWxsLHNraXA6ITB9KV19LHtjTjoidGFnIixiOiI8c3R5bGUoPz1cXHN8PnwkKSIsZToi
-PiIsazp7bmFtZToic3R5bGUifSxjOltlXSxzdGFydHM6e2U6Ijwvc3R5bGU+IixyRTohMCxzTDpbImNz
-cyIsInhtbCJdfX0se2NOOiJ0YWciLGI6IjxzY3JpcHQoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToi
-c2NyaXB0In0sYzpbZV0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTohMCxzTDpbImFjdGlvbnNjcmlw
-dCIsImphdmFzY3JpcHQiLCJoYW5kbGViYXJzIiwieG1sIiwidmJzY3JpcHQiXX19LHtjTjoidGFnIixi
-OiI8Lz8iLGU6Ii8/PiIsYzpbe2NOOiJuYW1lIixiOi9bXlwvPjxcc10rLyxyOjB9LGVdfV19fSk7aGxq
-cy5yZWdpc3Rlckxhbmd1YWdlKCJtYXJrZG93biIsZnVuY3Rpb24oZSl7cmV0dXJue2FsaWFzZXM6WyJt
-ZCIsIm1rZG93biIsIm1rZCJdLGM6W3tjTjoic2VjdGlvbiIsdjpbe2I6Il4jezEsNn0iLGU6IiQifSx7
-YjoiXi4rP1xcbls9LV17Mix9JCJ9XX0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxs
-ZXQiLGI6Il5cXHMqKFsqKy1dfChcXGQrXFwuKSlcXHMrIn0se2NOOiJzdHJvbmciLGI6IlsqX117Mn0u
-Kz9bKl9dezJ9In0se2NOOiJlbXBoYXNpcyIsdjpbe2I6IlxcKi4rP1xcKiJ9LHtiOiJfLis/XyIscjow
-fV19LHtjTjoicXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsdjpbe2I6Il5gYGB3KnMq
-JCIsZToiXmBgYHMqJCJ9LHtiOiJgLis/YCJ9LHtiOiJeKCB7NH18XHQpIixlOiIkIixyOjB9XX0se2I6
-Il5bLVxcKl17Myx9IixlOiIkIn0se2I6IlxcWy4rP1xcXVtcXChcXFtdLio/W1xcKVxcXV0iLHJCOiEw
-LGM6W3tjTjoic3RyaW5nIixiOiJcXFsiLGU6IlxcXSIsZUI6ITAsckU6ITAscjowfSx7Y046Imxpbmsi
-LGI6IlxcXVxcKCIsZToiXFwpIixlQjohMCxlRTohMH0se2NOOiJzeW1ib2wiLGI6IlxcXVxcWyIsZToi
-XFxdIixlQjohMCxlRTohMH1dLHI6MTB9LHtiOi9eXFtbXlxuXStcXTovLHJCOiEwLGM6W3tjTjoic3lt
-Ym9sIixiOi9cWy8sZTovXF0vLGVCOiEwLGVFOiEwfSx7Y046ImxpbmsiLGI6LzpccyovLGU6LyQvLGVC
-OiEwfV19XX19KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoImRhcnQiLGZ1bmN0aW9uKGUpe3ZhciB0PXtj
-Tjoic3Vic3QiLHY6W3tiOiJcXCRbQS1aYS16MC05X10rIn1dfSxyPXtjTjoic3Vic3QiLHY6W3tiOiJc
-XCR7IixlOiJ9In1dLGs6InRydWUgZmFsc2UgbnVsbCB0aGlzIGlzIG5ldyBzdXBlciJ9LG49e2NOOiJz
-dHJpbmciLHY6W3tiOiJyJycnIixlOiInJycifSx7YjonciIiIicsZTonIiIiJ30se2I6InInIixlOiIn
-IixpOiJcXG4ifSx7YjonciInLGU6JyInLGk6IlxcbiJ9LHtiOiInJyciLGU6IicnJyIsYzpbZS5CRSx0
-LHJdfSx7YjonIiIiJyxlOiciIiInLGM6W2UuQkUsdCxyXX0se2I6IiciLGU6IiciLGk6IlxcbiIsYzpb
-ZS5CRSx0LHJdfSx7YjonIicsZTonIicsaToiXFxuIixjOltlLkJFLHQscl19XX07ci5jPVtlLkNOTSxu
-XTtyZXR1cm57azp7a2V5d29yZDoiYXNzZXJ0IGFzeW5jIGF3YWl0IGJyZWFrIGNhc2UgY2F0Y2ggY2xh
-c3MgY29uc3QgY29udGludWUgZGVmYXVsdCBkbyBlbHNlIGVudW0gZXh0ZW5kcyBmYWxzZSBmaW5hbCBm
-aW5hbGx5IGZvciBpZiBpbiBpcyBuZXcgbnVsbCByZXRocm93IHJldHVybiBzdXBlciBzd2l0Y2ggc3lu
-YyB0aGlzIHRocm93IHRydWUgdHJ5IHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQgYWJzdHJhY3QgYXMg
-ZHluYW1pYyBleHBvcnQgZXh0ZXJuYWwgZmFjdG9yeSBnZXQgaW1wbGVtZW50cyBpbXBvcnQgbGlicmFy
-eSBvcGVyYXRvciBwYXJ0IHNldCBzdGF0aWMgdHlwZWRlZiIsYnVpbHRfaW46InByaW50IENvbXBhcmFi
-bGUgRGF0ZVRpbWUgRHVyYXRpb24gRnVuY3Rpb24gSXRlcmFibGUgSXRlcmF0b3IgTGlzdCBNYXAgTWF0
-Y2ggTnVsbCBPYmplY3QgUGF0dGVybiBSZWdFeHAgU2V0IFN0b3B3YXRjaCBTdHJpbmcgU3RyaW5nQnVm
-ZmVyIFN0cmluZ1NpbmsgU3ltYm9sIFR5cGUgVXJpIGJvb2wgZG91YmxlIGludCBudW0gZG9jdW1lbnQg
-d2luZG93IHF1ZXJ5U2VsZWN0b3IgcXVlcnlTZWxlY3RvckFsbCBFbGVtZW50IEVsZW1lbnRMaXN0In0s
-YzpbbixlLkMoIi9cXCpcXCoiLCJcXCovIix7c0w6Im1hcmtkb3duIn0pLGUuQygiLy8vIiwiJCIse3NM
-OiJtYXJrZG93biJ9KSxlLkNMQ00sZS5DQkNNLHtjTjoiY2xhc3MiLGJLOiJjbGFzcyBpbnRlcmZhY2Ui
-LGU6InsiLGVFOiEwLGM6W3tiSzoiZXh0ZW5kcyBpbXBsZW1lbnRzIn0sZS5VVE1dfSxlLkNOTSx7Y046
-Im1ldGEiLGI6IkBbQS1aYS16XSsifSx7YjoiPT4ifV19fSk7Cg==
-''';
-
-String _index_html;
-// index_html md5 is '41fa7069b77fe104e2d78f9fd1d8d99b'
-String _index_html_base64 = '''
-PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
-cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
-cnRQYWdlU2NyaXB0IH19PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0
-dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1PcGVuK1NhbnM6NDAwLDYwMCZkaXNw
-bGF5PXN3YXAiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJ7eyBoaWdobGlnaHRTdHls
-ZVBhdGggfX0iPgogICAgPHN0eWxlPnt7IGRhcnRQYWdlU3R5bGUgfX08L3N0eWxlPgo8L2hlYWQ+Cjxi
-b2R5IGNsYXNzPSJ7eyBtaWdyYXRpb25BcHBsaWVkU3R5bGUgfX0iPgo8ZGl2IGNsYXNzPSJyZXJ1bm5p
-bmctcGFuZSI+CiAgPGgxPlJlcnVubmluZy4uLjwvaDE+CjwvZGl2Pgo8cCBjbGFzcz0icm9vdCI+e3sg
-cm9vdCB9fTwvcD4KPGhlYWRlciBjbGFzcz0iZWxldmF0aW9uLXo0Ij4KICAgIDxoMSBjbGFzcz0iYmVm
-b3JlLWFwcGx5Ij5Qcm9wb3NlZCBudWxsIHNhZmV0eSBjaGFuZ2VzPC9oMT4KICAgIDxoMSBjbGFzcz0i
-YWZ0ZXItYXBwbHkiPiYjMTAwMDM7IE51bGwgc2FmZXR5IG1pZ3JhdGlvbiBhcHBsaWVkPC9oMT4KICAg
-IDxoMiBpZD0idW5pdC1uYW1lIj4mbmJzcDs8L2gyPgogICAgPGJ1dHRvbiBjbGFzcz0iYXBwbHktbWln
-cmF0aW9uIGJlZm9yZS1hcHBseSI+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxi
-dXR0b24gY2xhc3M9ImFwcGx5LW1pZ3JhdGlvbiBhZnRlci1hcHBseSIgZGlzYWJsZWQ+JiM5OTk4OyBB
-cHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxidXR0b24gY2xhc3M9InJlcnVuLW1pZ3JhdGlvbiBi
-ZWZvcmUtYXBwbHkiPiYjODYzNTsgUmVydW4gRnJvbSBTb3VyY2VzPC9idXR0b24+CjwvaGVhZGVyPgo8
-ZGl2IGNsYXNzPSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2IGNsYXNzPSJuYXYtcGFuZWwiPgog
-ICAgICAgIDxkaXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InBhbmVs
-LWhlYWRpbmciPlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0ibmF2LXRy
-ZWUiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5lciAtLT4KICAgIDwvZGl2PjwhLS0g
-L25hdiAtLT4KICAgIDxkaXYgY2xhc3M9ImNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9InJlZ2lv
-bnMiPgogICAgICAgICAgICA8IS0tIFRoZSByZWdpb25zIG92ZXJsYXkgY29kZSBjb3B5IG9mIHRoZSBj
-b250ZW50IHRvIHByb3ZpZGUgLS0+CiAgICAgICAgICAgIDwhLS0gdG9vbHRpcHMgZm9yIG1vZGlmaWVk
-IHJlZ2lvbnMuIC0tPgogICAgICAgIDwvZGl2PjwhLS0gL3JlZ2lvbnMgLS0+CiAgICAgICAgPGRpdiBj
-bGFzcz0iY29kZSI+CiAgICAgICAgICAgIDwhLS0gQ29tcGlsYXRpb24gdW5pdCBjb250ZW50IGlzIHdy
-aXR0ZW4gaGVyZS4gLS0+CiAgICAgICAgICAgIDxwIGNsYXNzPSJ3ZWxjb21lIj4KICAgICAgICAgICAg
-ICAgIFNlbGVjdCBhIHNvdXJjZSBmaWxlIG9uIHRoZSBsZWZ0IHRvIHByZXZpZXcgdGhlIHByb3Bvc2Vk
-IGVkaXRzLgogICAgICAgICAgICA8L3A+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj48IS0tIC9jb250
-ZW50IC0tPgogICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAgICAgICAgPGRpdiBjbGFzcz0iZWRp
-dC1saXN0Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+UHJvcG9zZWQgRWRp
-dHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+PC9kaXY+CiAgICAg
-ICAgPC9kaXY+PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxkaXYgY2xhc3M9ImVkaXQtcGFuZWwi
-PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5FZGl0IERldGFpbHM8L2Rpdj4K
-ICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+CiAgICAgICAgICAgICAgICA8cCBj
-bGFzcz0icGxhY2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC48L3A+CiAg
-ICAgICAgICAgIDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+CiAgICAgICAgPC9kaXY+PCEtLSAv
-ZWRpdC1wYW5lbCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFuZWwgLS0+CjwvZGl2PjwhLS0gL3Bh
-bmVscyAtLT4KPGZvb3Rlcj4KICAgIDxhIHRhcmdldD0iX2JsYW5rIgogICAgICAgaHJlZj0iaHR0cHM6
-Ly9naXRodWIuY29tL2RhcnQtbGFuZy9zZGsvYmxvYi9tYXN0ZXIvcGtnL25uYmRfbWlncmF0aW9uL1JF
-QURNRS5tZCI+TnVsbAogICAgICAgIHNhZmV0eSBtaWdyYXRpb24gaGVscDwvYT4KICAgIDxzcGFuIGNs
-YXNzPSJ3aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBvbiB7eyBzZGtWZXJzaW9uIH19PC9kaXY+
-CjwvZm9vdGVyPgo8L2JvZHk+CjwvaHRtbD4K
-''';
-
-String _migration_css;
-// migration_css md5 is 'eab70bd06e8c1bfe25644337e63495b9'
-String _migration_css_base64 = '''
-LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
-dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
-ZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgKi8KLyogQlNELXN0eWxlIGxpY2Vu
-c2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4gICAgICAgICAgICAgICAgICAg
-Ki8KCmJvZHkgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgY29sb3I6ICNjY2M7CiAgZm9u
-dC1mYW1pbHk6ICJSb2JvdG8iLCBzYW5zLXNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKICBkaXNwbGF5
-OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRv
-cDogMDsKICByaWdodDogMDsKICBib3R0b206IDA7CiAgbGVmdDogMDsKICBtYXJnaW46IDA7CiAgcGFk
-ZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucHJvcG9zZWQgLmFmdGVyLWFwcGx5IHsKICBk
-aXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYmVmb3JlLWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9
-CgpoZWFkZXIgewogIGJhY2tncm91bmQtY29sb3I6ICMxYzI4MzQ7CiAgaGVpZ2h0OiA0OHB4OwogIHBh
-ZGRpbmctbGVmdDogMjRweDsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIHotaW5kZXg6IDQ7Cn0KCmhl
-YWRlciBoMSwKaGVhZGVyIGgyIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1mYW1pbHk6
-ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXdlaWdodDogNDAwOwogIG1h
-cmdpbi1yaWdodDogMjRweDsKfQoKaDEgewogIGZvbnQtc2l6ZTogMS41ZW07Cn0KCmhlYWRlciBoMiB7
-CiAgZm9udC1zaXplOiAxLjJlbTsKfQoKaGVhZGVyIC5hcHBseS1taWdyYXRpb24sIC5yZXJ1bi1taWdy
-YXRpb24gewogIHJpZ2h0OiAwcHg7CiAgZmxvYXQ6IHJpZ2h0OwogIG1hcmdpbjogMTBweDsKfQoKZm9v
-dGVyIHsKICBjb2xvcjogI2NjYzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjczMjNhOwogIGRpc3BsYXk6
-IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IHJvdzsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIHBhZGRp
-bmc6IDhweCAyNHB4Owp9Cgpmb290ZXIgLndpZGUgewogIGZsZXg6IDE7Cn0KCi5ob3Jpem9udGFsIHsK
-ICBkaXNwbGF5OiBmbGV4Owp9CgoucGFuZWxzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIxYTI1Owog
-IGZsZXg6IDE7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLnBhbmVsLWhlYWRpbmcgewogIGNvbG9yOiBn
-cmF5OwogIG1hcmdpbjogOHB4Owp9CgoubmF2LWxpbmssCi5yZWdpb24gewogIGN1cnNvcjogcG9pbnRl
-cjsKfQoKLm5hdi1wYW5lbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBmbGV4OiAxIDIw
-MHB4OwogIG1hcmdpbjogMDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgoubmF2LWlubmVyIHsKICBwYWRk
-aW5nOiAwIDAgN3B4IDdweDsKfQoKLmZpeGVkIHsKICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwOwp9
-Cgoucm9vdCB7CiAgbWFyZ2luOiAwOwogIGRpc3BsYXk6IG5vbmU7Cn0KCi5uYXYtdHJlZSA+IHVsIHsK
-ICBwYWRkaW5nLWxlZnQ6IDZweDsKfQoKLm5hdi1pbm5lciB1bCB7CiAgcGFkZGluZy1sZWZ0OiAxMnB4
-OwogIG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwp9
-CgoubmF2LWlubmVyIGxpOm5vdCguZGlyKSB7CiAgbWFyZ2luLWxlZnQ6IDIwcHg7CiAgbWFyZ2luLWJv
-dHRvbTogM3B4Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cgewogIGN1cnNvcjogcG9pbnRlcjsK
-ICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1zaXplOiAxMHB4OwogIG1hcmdpbi1yaWdodDog
-NHB4OwogIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjVzIGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIGxp
-LmRpciAuYXJyb3cuY29sbGFwc2VkIHsKICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpOwp9CgoubmF2
-LWlubmVyIHVsIHsKICBtYXgtaGVpZ2h0OiAyMDAwcHg7CiAgdHJhbnNpdGlvbjogbWF4LWhlaWdodCAw
-LjVzIGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIHVsLmNvbGxhcHNlZCB7CiAgbWF4LWhlaWdodDogMCAh
-aW1wb3J0YW50OwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5uYXYtaW5uZXIgLnNlbGVjdGVkLWZpbGUg
-ewogIGNvbG9yOiB3aGl0ZTsKICBjdXJzb3I6IGluaGVyaXQ7CiAgZm9udC13ZWlnaHQ6IDYwMDsKICB0
-ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCi5lZGl0LWNvdW50IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
-MzdhZWRjOwogIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgY29sb3I6ICMwMDAwMDA7CiAgZGlzcGxheTog
-aW5saW5lLWJsb2NrOwogIGZvbnQtc2l6ZTogMTFweDsKICBmb250LXdlaWdodDogNjAwOwogIG1hcmdp
-bi1sZWZ0OiA1cHg7CiAgbWluLXdpZHRoOiAyNXB4OwogIHBhZGRpbmc6IDRweCAwIDJweCAwOwogIHRl
-eHQtYWxpZ246IGNlbnRlcjsKICBsaW5lLWhlaWdodDogMWVtOwp9CgouY29udGVudCB7CiAgZmxleDog
-NCAzMDBweDsKICBiYWNrZ3JvdW5kOiAjMjgyYjJlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAg
-bWFyZ2luOiAwIDZweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgd2hpdGUtc3BhY2U6IHByZTsKICBv
-dmVyZmxvdzogc2Nyb2xsOwp9CgouY29kZSB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFi
-c29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwogIG1hcmdpbi1sZWZ0OiA1NnB4Owp9CgouaGxqcyB7
-CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14
-OiBhdXRvOwogIHBhZGRpbmc6IDAuNWVtOwp9CgouY29kZSAud2VsY29tZSB7CiAgZm9udC1mYW1pbHk6
-ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDE4cHg7CiAgbWFy
-Z2luLXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29kZSAubmF2LWxpbmsgewogIGNvbG9y
-OiBpbmhlcml0OwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAubmF2LWxpbms6
-dmlzaXRlZCB7CiAgY29sb3I6IGluaGVyaXQ7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0K
-Ci5jb2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IHVuZGVybGluZTsK
-ICBmb250LXdlaWdodDogNjAwOwp9CgoucmVnaW9ucyB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRp
-b246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwp9CgoucmVnaW9ucyB0YWJsZSB7CiAgYm9y
-ZGVyLXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBpbmhlcml0Owp9CgoucmVnaW9ucyB0ZCB7CiAgYm9y
-ZGVyOiBub25lOwogIC8qIFRoZSBjb250ZW50IG9mIHRoZSByZWdpb25zIGlzIG5vdCB2aXNpYmxlOyB0
-aGUgdXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQogICAqIGhpZ2hsaWdodGVkIGNvcHkgb2YgdGhlIGNv
-bnRlbnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMCk7CiAgcGFkZGluZzogMDsKICB3
-aGl0ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0ZDplbXB0eTphZnRlciB7CiAgY29udGVudDogIlww
-MGEwIjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkOmxhc3QtY2hpbGQgewogIGJhY2tncm91bmQt
-Y29sb3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRlOwp9CgoucmVnaW9ucyB0ZC5saW5lLW5vIHsKICBi
-b3JkZXItcmlnaHQ6IHNvbGlkICMyODJiMmUgMnB4OwogIGNvbG9yOiAjOTk5OTk5OwogIHBhZGRpbmct
-cmlnaHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdodDsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHdp
-ZHRoOiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0
-IHRkLmxpbmUtbm8gewogIGJvcmRlci1yaWdodDogc29saWQgI2NjYyAycHg7Cn0KCi5yZWdpb24gewog
-IGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTog
-dmlzaWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5yZWdpb24uYWRkZWQtcmVnaW9uIHsKICBiYWNrZ3Jv
-dW5kLWNvbG9yOiAjY2NmZmNjOwogIGNvbG9yOiAjMDAzMzAwOwp9CgoucmVnaW9uLnJlbW92ZWQtcmVn
-aW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmY2NjY2OwogIGNvbG9yOiAjMDAxMTAwOwp9CgoucmVn
-aW9uLmluZm9ybWF0aXZlLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzg4ODg4ODsKICBjb2xv
-cjogIzAwMDAwMDsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDsKICBwb3NpdGlv
-bjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICBmb250LXdlaWdodDogNjAwOwp9Cgou
-aW5mby1wYW5lbCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46IDA7CiAgaGVpZ2h0OiAxMDAlOwog
-IGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKfQoKLmluZm8tcGFuZWwgLmVk
-aXQtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMyODJiMmU7CiAgb3ZlcmZsb3c6IGF1dG87Cn0K
-Ci5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRkaW5nOiA3cHg7Cn0KCi5pbmZvLXBhbmVs
-IC5wYW5lbC1jb250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1hcmdpbi10b3A6IDA7Cn0KCi5pbmZvLXBh
-bmVsIC5ub3dyYXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5pbmZvLXBhbmVsIHVsLAouaW5m
-by1wYW5lbCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9CgouaW5mby1wYW5lbCBsaSB7CiAgbWFy
-Z2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewogIGNvbG9yOiAjMzNjY2ZmOwp9CgouaW5m
-by1wYW5lbCAuZWRpdC1saXN0IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjgyYjJlOwogIG92ZXJmbG93
-OiBhdXRvOwp9CgouZWRpdC1wYW5lbCB7CiAgbWFyZ2luLXRvcDogNnB4OwogIGZsZXg6IDEgMTAwcHg7
-Cn0KCi5lZGl0LWxpc3QgewogIGZsZXg6IDIgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgLmVkaXQgewogIG1h
-cmdpbjogM3B4IDA7Cn0KCi5lZGl0LWxpc3QgLmVkaXQtbGluayB7CiAgY3Vyc29yOiBwb2ludGVyOwp9
-CgoucmVydW5uaW5nLXBhbmUgewogIGRpc3BsYXk6IG5vbmU7Cn0KCmJvZHkucmVydW5uaW5nIC5yZXJ1
-bm5pbmctcGFuZSB7CiAgZGlzcGxheTogYmxvY2s7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMHB4
-OwogIGJvdHRvbTogMHB4OwogIGxlZnQ6IDBweDsKICByaWdodDogMHB4OwogIGJhY2tncm91bmQtY29s
-b3I6ICMwMDAwMDBBQTsgLyogdHJhbnNsdWNlbnQgYmxhY2sgKi8KICB6LWluZGV4OiA0MDA7Cn0KCi5y
-ZXJ1bm5pbmctcGFuZSBoMSB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRvcDogNTAlOwogIGxlZnQ6
-IDUwJTsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTsKfQoKcC50cmFjZSAudHlwZS1k
-ZXNjcmlwdGlvbiB7CiAgLyogRnJvbSBITEpTJ3MgLmhsanMta2V5d29yZCwgLmhsanMtc2VsZWN0b3It
-dGFnLCAuaGxqcy1kZWxldGlvbiAqLwogIGNvbG9yOiAjY2M3ODMyOwogIGZvbnQtZmFtaWx5OiBtb25v
-c3BhY2U7Cn0KCnVsLnRyYWNlIHsKICBmb250LXNpemU6IDEzcHg7CiAgbGlzdC1zdHlsZS10eXBlOiBu
-b25lOwogIHBhZGRpbmctbGVmdDogMHB4Owp9Cgp1bC50cmFjZSBsaSB7CiAgY29sb3I6IHdoaXRlOwog
-IG1hcmdpbi1sZWZ0OiAxNHB4OwogIHRleHQtaW5kZW50OiAtMTRweDsKfQoKdWwudHJhY2UgbGkgLmZ1
-bmN0aW9uIHsKICAvKiBGcm9tIEhMSlMncyAuaGxqcy1zZWN0aW9uLCAuaGxqcy10aXRsZSwgLmhsanMt
-dHlwZSAqLwogIGNvbG9yOiAjZmZjNjZkOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgZm9udC13
-ZWlnaHQ6IDYwMDsKfQoKLmVsZXZhdGlvbi16NCB7CiAgYm94LXNoYWRvdzogMHB4IDJweCA0cHggLTFw
-eCByZ2JhKDAsIDAsIDAsIDAuMiksCiAgICAgIDBweCA0cHggNXB4IDBweCByZ2JhKDAsIDAsIDAsIDAu
-MTQpLAogICAgICAwcHggMXB4IDEwcHggMHB4IHJnYmEoMCwgMCwgMCwgLjEyKTsKfQoKYSB7CiAgY29s
-b3I6ICNjY2M7CiAgZmlsbDogI2NjYzsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCmE6aG92ZXIg
-ewogIGNvbG9yOiAjZmZmOwogIGZpbGw6ICNmZmY7Cn0KCmJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xv
-cjogIzMzY2NmZjsKICBib3JkZXI6IDJweCBzb2xpZCAjMzdhZWRjOwogIGJvcmRlci1yYWRpdXM6IDNw
-eDsKICBwYWRkaW5nOiA2cHggMTBweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogIzI4Mjgy
-ODsKfQoKYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjODBkZmZmOwogIGJvcmRlcjog
-MnB4IHNvbGlkICM1MmI4ZTA7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgpidXR0b25bZGlzYWJsZWRdIHsK
-ICBiYWNrZ3JvdW5kLWNvbG9yOiAjN2FhOGI4OwogIGNvbG9yOiAjNTA3MTc3OwogIGJvcmRlcjogMnB4
-IHNvbGlkICM1MDcxNzc7CiAgY3Vyc29yOiBub3QtYWxsb3dlZDsKfQoKLnBsYWNlaG9sZGVyIHsKICBj
-b2xvcjogIzc3NzsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWFyZ2luLXRvcDogM2VtICFpbXBvcnRh
-bnQ7Cn0KCi8qKgogKiBITEpTIE92ZXJyaWRlcwogKi8KLmhsanMgewogIC8qKgogICAqIFRoaXMgYWxs
-b3dzIHRoZSBwZXItbGluZSBoaWdobGlnaHRzIHRvIHNob3cuCiAgICovCiAgYmFja2dyb3VuZDogbm9u
-ZTsKfQo=
-''';
-
-String _migration_js;
-// migration_dart md5 is '46d77ad01f8c88bd4174b5dfbb872e82'
-String _migration_js_base64 = '''
-KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
-YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
-cl19fXZhciB6PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oKXt9CnQucHJvdG90eXBlPXtwOnt9fQp2
-YXIgcz1uZXcgdCgpCmlmKCEocy5fX3Byb3RvX18mJnMuX19wcm90b19fLnA9PT10LnByb3RvdHlwZS5w
-KSlyZXR1cm4gZmFsc2UKdHJ5e2lmKHR5cGVvZiBuYXZpZ2F0b3IhPSJ1bmRlZmluZWQiJiZ0eXBlb2Yg
-bmF2aWdhdG9yLnVzZXJBZ2VudD09InN0cmluZyImJm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigi
-Q2hyb21lLyIpPj0wKXJldHVybiB0cnVlCmlmKHR5cGVvZiB2ZXJzaW9uPT0iZnVuY3Rpb24iJiZ2ZXJz
-aW9uLmxlbmd0aD09MCl7dmFyIHI9dmVyc2lvbigpCmlmKC9eXGQrXC5cZCtcLlxkK1wuXGQrJC8udGVz
-dChyKSlyZXR1cm4gdHJ1ZX19Y2F0Y2gocSl7fXJldHVybiBmYWxzZX0oKQpmdW5jdGlvbiBzZXRGdW5j
-dGlvbk5hbWVzSWZOZWNlc3NhcnkoYSl7ZnVuY3Rpb24gdCgpe307aWYodHlwZW9mIHQubmFtZT09InN0
-cmluZyIpcmV0dXJuCmZvcih2YXIgdD0wO3Q8YS5sZW5ndGg7dCsrKXt2YXIgcz1hW3RdCnZhciByPU9i
-amVjdC5rZXlzKHMpCmZvcih2YXIgcT0wO3E8ci5sZW5ndGg7cSsrKXt2YXIgcD1yW3FdCnZhciBvPXNb
-cF0KaWYodHlwZW9mIG89PSdmdW5jdGlvbicpby5uYW1lPXB9fX1mdW5jdGlvbiBpbmhlcml0KGEsYil7
-YS5wcm90b3R5cGUuY29uc3RydWN0b3I9YQphLnByb3RvdHlwZVsiJGkiK2EubmFtZV09YQppZihiIT1u
-dWxsKXtpZih6KXthLnByb3RvdHlwZS5fX3Byb3RvX189Yi5wcm90b3R5cGUKcmV0dXJufXZhciB0PU9i
-amVjdC5jcmVhdGUoYi5wcm90b3R5cGUpCmNvcHlQcm9wZXJ0aWVzKGEucHJvdG90eXBlLHQpCmEucHJv
-dG90eXBlPXR9fWZ1bmN0aW9uIGluaGVyaXRNYW55KGEsYil7Zm9yKHZhciB0PTA7dDxiLmxlbmd0aDt0
-KyspaW5oZXJpdChiW3RdLGEpfWZ1bmN0aW9uIG1peGluKGEsYil7Y29weVByb3BlcnRpZXMoYi5wcm90
-b3R5cGUsYS5wcm90b3R5cGUpCmEucHJvdG90eXBlLmNvbnN0cnVjdG9yPWF9ZnVuY3Rpb24gbGF6eShh
-LGIsYyxkKXt2YXIgdD1hCmFbYl09dAphW2NdPWZ1bmN0aW9uKCl7YVtjXT1mdW5jdGlvbigpe0guYWco
-Yil9CnZhciBzCnZhciByPWQKdHJ5e2lmKGFbYl09PT10KXtzPWFbYl09cgpzPWFbYl09ZCgpfWVsc2Ug
-cz1hW2JdfWZpbmFsbHl7aWYocz09PXIpYVtiXT1udWxsCmFbY109ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-c1tiXX19cmV0dXJuIHN9fWZ1bmN0aW9uIG1ha2VDb25zdExpc3QoYSl7YS5pbW11dGFibGUkbGlzdD1B
-cnJheQphLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX1mdW5jdGlvbiBjb252ZXJ0VG9GYXN0T2Jq
-ZWN0KGEpe2Z1bmN0aW9uIHQoKXt9dC5wcm90b3R5cGU9YQpuZXcgdCgpCnJldHVybiBhfWZ1bmN0aW9u
-IGNvbnZlcnRBbGxUb0Zhc3RPYmplY3QoYSl7Zm9yKHZhciB0PTA7dDxhLmxlbmd0aDsrK3QpY29udmVy
-dFRvRmFzdE9iamVjdChhW3RdKX12YXIgeT0wCmZ1bmN0aW9uIHRlYXJPZmZHZXR0ZXIoYSxiLGMsZCxl
-KXtyZXR1cm4gZT9uZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
-ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
-IihyZWNlaXZlcikgeyIrImlmIChjID09PSBudWxsKSBjID0gIisiSC5LcSIrIigiKyJ0aGlzLCBmdW5j
-cywgYXBwbHlUcmFtcG9saW5lSW5kZXgsIHJlZmxlY3Rpb25JbmZvLCBmYWxzZSwgdHJ1ZSwgbmFtZSk7
-IisicmV0dXJuIG5ldyBjKHRoaXMsIGZ1bmNzWzBdLCByZWNlaXZlciwgbmFtZSk7IisifSIpKGEsYixj
-LGQsSCxudWxsKTpuZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
-ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
-IigpIHsiKyJpZiAoYyA9PT0gbnVsbCkgYyA9ICIrIkguS3EiKyIoIisidGhpcywgZnVuY3MsIGFwcGx5
-VHJhbXBvbGluZUluZGV4LCByZWZsZWN0aW9uSW5mbywgZmFsc2UsIGZhbHNlLCBuYW1lKTsiKyJyZXR1
-cm4gbmV3IGModGhpcywgZnVuY3NbMF0sIG51bGwsIG5hbWUpOyIrIn0iKShhLGIsYyxkLEgsbnVsbCl9
-ZnVuY3Rpb24gdGVhck9mZihhLGIsYyxkLGUsZil7dmFyIHQ9bnVsbApyZXR1cm4gZD9mdW5jdGlvbigp
-e2lmKHQ9PT1udWxsKXQ9SC5LcSh0aGlzLGEsYixjLHRydWUsZmFsc2UsZSkucHJvdG90eXBlCnJldHVy
-biB0fTp0ZWFyT2ZmR2V0dGVyKGEsYixjLGUsZil9dmFyIHg9MApmdW5jdGlvbiBpbnN0YWxsVGVhck9m
-ZihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdD1bXQpmb3IodmFyIHM9MDtzPGgubGVuZ3RoO3MrKyl7
-dmFyIHI9aFtzXQppZih0eXBlb2Ygcj09J3N0cmluZycpcj1hW3JdCnIuJGNhbGxOYW1lPWdbc10KdC5w
-dXNoKHIpfXZhciByPXRbMF0Kci4kUj1lCnIuJEQ9Zgp2YXIgcT1pCmlmKHR5cGVvZiBxPT0ibnVtYmVy
-IilxKz14CnZhciBwPWhbMF0Kci4kc3R1Yk5hbWU9cAp2YXIgbz10ZWFyT2ZmKHQsanx8MCxxLGMscCxk
-KQphW2JdPW8KaWYoYylyLiR0ZWFyT2ZmPW99ZnVuY3Rpb24gaW5zdGFsbFN0YXRpY1RlYXJPZmYoYSxi
-LGMsZCxlLGYsZyxoKXtyZXR1cm4gaW5zdGFsbFRlYXJPZmYoYSxiLHRydWUsZmFsc2UsYyxkLGUsZixn
-LGgpfWZ1bmN0aW9uIGluc3RhbGxJbnN0YW5jZVRlYXJPZmYoYSxiLGMsZCxlLGYsZyxoLGkpe3JldHVy
-biBpbnN0YWxsVGVhck9mZihhLGIsZmFsc2UsYyxkLGUsZixnLGgsaSl9ZnVuY3Rpb24gc2V0T3JVcGRh
-dGVJbnRlcmNlcHRvcnNCeVRhZyhhKXt2YXIgdD12LmludGVyY2VwdG9yc0J5VGFnCmlmKCF0KXt2Lmlu
-dGVyY2VwdG9yc0J5VGFnPWEKcmV0dXJufWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gc2V0T3JV
-cGRhdGVMZWFmVGFncyhhKXt2YXIgdD12LmxlYWZUYWdzCmlmKCF0KXt2LmxlYWZUYWdzPWEKcmV0dXJu
-fWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gdXBkYXRlVHlwZXMoYSl7dmFyIHQ9di50eXBlcwp2
-YXIgcz10Lmxlbmd0aAp0LnB1c2guYXBwbHkodCxhKQpyZXR1cm4gc31mdW5jdGlvbiB1cGRhdGVIb2xk
-ZXIoYSxiKXtjb3B5UHJvcGVydGllcyhiLGEpCnJldHVybiBhfXZhciBodW5rSGVscGVycz1mdW5jdGlv
-bigpe3ZhciB0PWZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIGZ1bmN0aW9uKGYsZyxoLGkpe3JldHVy
-biBpbnN0YWxsSW5zdGFuY2VUZWFyT2ZmKGYsZyxhLGIsYyxkLFtoXSxpLGUpfX0scz1mdW5jdGlvbihh
-LGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oZSxmLGcsaCl7cmV0dXJuIGluc3RhbGxTdGF0aWNUZWFyT2Zm
-KGUsZixhLGIsYyxbZ10saCxkKX19CnJldHVybntpbmhlcml0OmluaGVyaXQsaW5oZXJpdE1hbnk6aW5o
-ZXJpdE1hbnksbWl4aW46bWl4aW4saW5zdGFsbFN0YXRpY1RlYXJPZmY6aW5zdGFsbFN0YXRpY1RlYXJP
-ZmYsaW5zdGFsbEluc3RhbmNlVGVhck9mZjppbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLF9pbnN0YW5jZV8w
-dTp0KDAsMCxudWxsLFsiJDAiXSwwKSxfaW5zdGFuY2VfMXU6dCgwLDEsbnVsbCxbIiQxIl0sMCksX2lu
-c3RhbmNlXzJ1OnQoMCwyLG51bGwsWyIkMiJdLDApLF9pbnN0YW5jZV8waTp0KDEsMCxudWxsLFsiJDAi
-XSwwKSxfaW5zdGFuY2VfMWk6dCgxLDEsbnVsbCxbIiQxIl0sMCksX2luc3RhbmNlXzJpOnQoMSwyLG51
-bGwsWyIkMiJdLDApLF9zdGF0aWNfMDpzKDAsbnVsbCxbIiQwIl0sMCksX3N0YXRpY18xOnMoMSxudWxs
-LFsiJDEiXSwwKSxfc3RhdGljXzI6cygyLG51bGwsWyIkMiJdLDApLG1ha2VDb25zdExpc3Q6bWFrZUNv
-bnN0TGlzdCxsYXp5OmxhenksdXBkYXRlSG9sZGVyOnVwZGF0ZUhvbGRlcixjb252ZXJ0VG9GYXN0T2Jq
-ZWN0OmNvbnZlcnRUb0Zhc3RPYmplY3Qsc2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5OnNldEZ1bmN0
-aW9uTmFtZXNJZk5lY2Vzc2FyeSx1cGRhdGVUeXBlczp1cGRhdGVUeXBlcyxzZXRPclVwZGF0ZUludGVy
-Y2VwdG9yc0J5VGFnOnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcsc2V0T3JVcGRhdGVMZWFmVGFn
-czpzZXRPclVwZGF0ZUxlYWZUYWdzfX0oKQpmdW5jdGlvbiBpbml0aWFsaXplRGVmZXJyZWRIdW5rKGEp
-e3g9di50eXBlcy5sZW5ndGgKYShodW5rSGVscGVycyx2LHcsJCl9ZnVuY3Rpb24gZ2V0R2xvYmFsRnJv
-bU5hbWUoYSl7Zm9yKHZhciB0PTA7dDx3Lmxlbmd0aDt0Kyspe2lmKHdbdF09PUMpY29udGludWUKaWYo
-d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17Rks6ZnVuY3Rpb24gRksoKXt9LApvbzpm
-dW5jdGlvbihhKXt2YXIgdCxzPWFeNDgKaWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8
-PTEwMilyZXR1cm4gdC04NwpyZXR1cm4tMX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3Rh
-cnQiKQppZihjIT1udWxsKXtQLmsxKGMsImVuZCIpCmlmKGI+YylILnZoKFAuVEUoYiwwLGMsInN0YXJ0
-IixudWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihh
-LGIsYyxkKXtpZih1Lmd3LmIoYSkpcmV0dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5D
-KCJ4eTwxLDI+IikpCnJldHVybiBuZXcgSC5pMShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygiaTE8MSwy
-PiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJObyBlbGVtZW50Iil9LApkVTpmdW5j
-dGlvbigpe3JldHVybiBuZXcgUC5saigiVG9vIG1hbnkgZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7
-cmV0dXJuIG5ldyBQLmxqKCJUb28gZmV3IGVsZW1lbnRzIil9LApxajpmdW5jdGlvbiBxaihhKXt0aGlz
-LmE9YX0sCmJROmZ1bmN0aW9uIGJRKCl7fSwKYUw6ZnVuY3Rpb24gYUwoKXt9LApuSDpmdW5jdGlvbiBu
-SChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAphNzpmdW5jdGlv
-biBhNyhhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwK
-aTE6ZnVuY3Rpb24gaTEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp4eTpmdW5j
-dGlvbiB4eShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCk1IOmZ1bmN0aW9uIE1I
-KGEsYixjKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uJHRpPWN9LApsSjpmdW5jdGlv
-biBsSihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClU1OmZ1bmN0aW9uIFU1KGEs
-YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKdkc6ZnVuY3Rpb24gdkcoYSxiLGMpe3Ro
-aXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApTVTpmdW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9u
-IFJlKCl7fSwKdzI6ZnVuY3Rpb24gdzIoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sCmRj
-OmZ1bmN0aW9uKCl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIE1hcCIp
-KX0sCk5ROmZ1bmN0aW9uKGEpe3ZhciB0LHM9SC5KZyhhKQppZih0eXBlb2Ygcz09InN0cmluZyIpcmV0
-dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihi
-IT1udWxsKXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmIoYSl9LApkOmZ1bmN0
-aW9uKGEpe3ZhciB0CmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2YgYT09Im51
-bWJlciIpe2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUiCmVsc2Ug
-aWYoITE9PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouQWMo
-YSkKaWYodHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILkkoYSkpCnJldHVybiB0fSwKZVE6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9YS4kaWRlbnRpdHlIYXNoCmlmKHQ9PW51bGwpe3Q9TWF0aC5yYW5kb20oKSow
-eDNmZmZmZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXR9cmV0dXJuIHR9LApIcDpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC5JKGEpKQp0PS9e
-XHMqWystXT8oKDB4W2EtZjAtOV0rKXwoXGQrKXwoW2EtejAtOV0rKSlccyokL2kuZXhlYyhhKQppZih0
-PT1udWxsKXJldHVybiBuCmlmKDM+PXQubGVuZ3RoKXJldHVybiBILmsodCwzKQpzPUguYyh0WzNdKQpp
-ZihiPT1udWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJl
-dHVybiBwYXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwy
-LDM2LCJyYWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYo
-YjwxMHx8cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtv
-PHA7KytvKWlmKChDLnhCLlcocSxvKXwzMik+cilyZXR1cm4gbn1yZXR1cm4gcGFyc2VJbnQoYSxiKX0s
-CmxoOmZ1bmN0aW9uKGEpe3ZhciB0PUguSDUoYSkKcmV0dXJuIHR9LApINTpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIKaWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIEguSihILnEoYSksbnVsbCkKaWYoSi5pYShh
-KT09PUMuT2t8fHUuYWsuYihhKSl7dD1DLndiKGEpCmlmKEguQmUodCkpcmV0dXJuIHQKcz1hLmNvbnN0
-cnVjdG9yCmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmlu
-ZyImJkguQmUocikpcmV0dXJuIHJ9fXJldHVybiBILkooSC5xKGEpLG51bGwpfSwKQmU6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YSE9PSJPYmplY3QiJiZhIT09IiIKcmV0dXJuIHR9LApNMDpmdW5jdGlvbigpe2lmKCEh
-c2VsZi5sb2NhdGlvbilyZXR1cm4gc2VsZi5sb2NhdGlvbi5ocmVmCnJldHVybiBudWxsfSwKVks6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPD01MDApcmV0dXJuIFN0cmluZy5mcm9t
-Q2hhckNvZGUuYXBwbHkobnVsbCxhKQpmb3IodD0iIixzPTA7czxwO3M9cil7cj1zKzUwMApxPXI8cD9y
-OnAKdCs9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc2xpY2UocyxxKSl9cmV0dXJuIHR9
-LApDcTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1ILlZNKFtdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz0w
-O3M8YS5sZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpe3I9YVtzXQppZighSC5vayhy
-KSl0aHJvdyBILmIoSC5JKHIpKQppZihyPD02NTUzNSlDLk5tLmkocSxyKQplbHNlIGlmKHI8PTExMTQx
-MTEpe0MuTm0uaShxLDU1Mjk2KyhDLmpuLndHKHItNjU1MzYsMTApJjEwMjMpKQpDLk5tLmkocSw1NjMy
-MCsociYxMDIzKSl9ZWxzZSB0aHJvdyBILmIoSC5JKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFILm9r
-KHIpKXRocm93IEguYihILkkocikpCmlmKHI8MCl0aHJvdyBILmIoSC5JKHIpKQppZihyPjY1NTM1KXJl
-dHVybiBILkNxKGEpfXJldHVybiBILlZLKGEpfSwKZnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixx
-CmlmKGM8PTUwMCYmYj09PTAmJmM9PT1hLmxlbmd0aClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5h
-cHBseShudWxsLGEpCmZvcih0PWIscz0iIjt0PGM7dD1yKXtyPXQrNTAwCnE9cjxjP3I6YwpzKz1TdHJp
-bmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zdWJhcnJheSh0LHEpKX1yZXR1cm4gc30sCkx3OmZ1
-bmN0aW9uKGEpe3ZhciB0CmlmKDA8PWEpe2lmKGE8PTY1NTM1KXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
-b2RlKGEpCmlmKGE8PTExMTQxMTEpe3Q9YS02NTUzNgpyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgo
-NTUyOTZ8Qy5qbi53Ryh0LDEwKSk+Pj4wLDU2MzIwfHQmMTAyMyl9fXRocm93IEguYihQLlRFKGEsMCwx
-MTE0MTExLG51bGwsbnVsbCkpfSwKbzI6ZnVuY3Rpb24oYSl7aWYoYS5kYXRlPT09dm9pZCAwKWEuZGF0
-ZT1uZXcgRGF0ZShhLmEpCnJldHVybiBhLmRhdGV9LAp0SjpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEp
-LmdldEZ1bGxZZWFyKCkrMApyZXR1cm4gdH0sCk5TOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0
-TW9udGgoKSsxCnJldHVybiB0fSwKakE6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXREYXRlKCkr
-MApyZXR1cm4gdH0sCktMOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0SG91cnMoKSswCnJldHVy
-biB0fSwKY2g6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRNaW51dGVzKCkrMApyZXR1cm4gdH0s
-CkpkOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0U2Vjb25kcygpKzAKcmV0dXJuIHR9LApWYTpm
-dW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbGxpc2Vjb25kcygpKzAKcmV0dXJuIHR9LAp6bzpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPXt9CnIuYT0wCnQ9W10Kcz1bXQpyLmE9Yi5sZW5ndGgKQy5O
-bS5GVih0LGIpCnIuYj0iIgppZihjIT1udWxsJiZjLmEhPT0wKWMuSygwLG5ldyBILkNqKHIscyx0KSkK
-IiIrci5hCnJldHVybiBKLkp5KGEsbmV3IEguTEkoQy5UZSwwLHQscywwKSl9LApFazpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQscyxyLHEKaWYoYiBpbnN0YW5jZW9mIEFycmF5KXQ9Yz09bnVsbHx8Yy5hPT09MApl
-bHNlIHQ9ITEKaWYodCl7cz1iCnI9cy5sZW5ndGgKaWYocj09PTApe2lmKCEhYS4kMClyZXR1cm4gYS4k
-MCgpfWVsc2UgaWYocj09PTEpe2lmKCEhYS4kMSlyZXR1cm4gYS4kMShzWzBdKX1lbHNlIGlmKHI9PT0y
-KXtpZighIWEuJDIpcmV0dXJuIGEuJDIoc1swXSxzWzFdKX1lbHNlIGlmKHI9PT0zKXtpZighIWEuJDMp
-cmV0dXJuIGEuJDMoc1swXSxzWzFdLHNbMl0pfWVsc2UgaWYocj09PTQpe2lmKCEhYS4kNClyZXR1cm4g
-YS4kNChzWzBdLHNbMV0sc1syXSxzWzNdKX1lbHNlIGlmKHI9PT01KWlmKCEhYS4kNSlyZXR1cm4gYS4k
-NShzWzBdLHNbMV0sc1syXSxzWzNdLHNbNF0pCnE9YVsiIisiJCIrcl0KaWYocSE9bnVsbClyZXR1cm4g
-cS5hcHBseShhLHMpfXJldHVybiBILkV3KGEsYixjKX0sCkV3OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
-LHIscSxwLG8sbixtLGwsaz1iIGluc3RhbmNlb2YgQXJyYXk/YjpQLkNIKGIsITAsdS56KSxqPWsubGVu
-Z3RoLGk9YS4kUgppZihqPGkpcmV0dXJuIEguem8oYSxrLGMpCnQ9YS4kRApzPXQ9PW51bGwKcj0hcz90
-KCk6bnVsbApxPUouaWEoYSkKcD1xLiRDCmlmKHR5cGVvZiBwPT0ic3RyaW5nIilwPXFbcF0KaWYocyl7
-aWYoYyE9bnVsbCYmYy5hIT09MClyZXR1cm4gSC56byhhLGssYykKaWYoaj09PWkpcmV0dXJuIHAuYXBw
-bHkoYSxrKQpyZXR1cm4gSC56byhhLGssYyl9aWYociBpbnN0YW5jZW9mIEFycmF5KXtpZihjIT1udWxs
-JiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPmkrci5sZW5ndGgpcmV0dXJuIEguem8oYSxr
-LG51bGwpCkMuTm0uRlYoayxyLnNsaWNlKGotaSkpCnJldHVybiBwLmFwcGx5KGEsayl9ZWxzZXtpZihq
-PmkpcmV0dXJuIEguem8oYSxrLGMpCm89T2JqZWN0LmtleXMocikKaWYoYz09bnVsbClmb3Iocz1vLmxl
-bmd0aCxuPTA7bjxvLmxlbmd0aDtvLmxlbmd0aD09PXN8fCgwLEgubGspKG8pLCsrbilDLk5tLmkoayxy
-W0guYyhvW25dKV0pCmVsc2V7Zm9yKHM9by5sZW5ndGgsbT0wLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3Ro
-PT09c3x8KDAsSC5saykobyksKytuKXtsPUguYyhvW25dKQppZihjLng0KGwpKXsrK20KQy5ObS5pKGss
-Yy5xKDAsbCkpfWVsc2UgQy5ObS5pKGsscltsXSl9aWYobSE9PWMuYSlyZXR1cm4gSC56byhhLGssYyl9
-cmV0dXJuIHAuYXBwbHkoYSxrKX19LApwWTpmdW5jdGlvbihhKXt0aHJvdyBILmIoSC5JKGEpKX0sCms6
-ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKUouSChhKQp0aHJvdyBILmIoSC5IWShhLGIpKX0sCkhZOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscyxyPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLkFUKCEw
-LGIscixudWxsKQp0PUguV1koSi5IKGEpKQppZighKGI8MCkpe2lmKHR5cGVvZiB0IT09Im51bWJlciIp
-cmV0dXJuIEgucFkodCkKcz1iPj10fWVsc2Ugcz0hMAppZihzKXJldHVybiBQLnQoYixhLHIsbnVsbCx0
-KQpyZXR1cm4gUC5PNyhiLHIpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSJJbnZhbGlkIHZhbHVl
-IgppZihhPmMpcmV0dXJuIG5ldyBQLmJKKDAsYywhMCxhLCJzdGFydCIsdCkKaWYoYiE9bnVsbCl7aWYo
-IUgub2soYikpcmV0dXJuIG5ldyBQLkFUKCEwLGIsImVuZCIsbnVsbCkKaWYoYjxhfHxiPmMpcmV0dXJu
-IG5ldyBQLmJKKGEsYywhMCxiLCJlbmQiLHQpfXJldHVybiBuZXcgUC5BVCghMCxiLCJlbmQiLG51bGwp
-fSwKSTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuQVQoITAsYSxudWxsLG51bGwpfSwKYjpmdW5jdGlv
-bihhKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAuTEsoKQp0PW5ldyBFcnJvcigpCnQuZGFydEV4Y2Vw
-dGlvbj1hCmlmKCJkZWZpbmVQcm9wZXJ0eSIgaW4gT2JqZWN0KXtPYmplY3QuZGVmaW5lUHJvcGVydHko
-dCwibWVzc2FnZSIse2dldDpILkp1fSkKdC5uYW1lPSIifWVsc2UgdC50b1N0cmluZz1ILkp1CnJldHVy
-biB0fSwKSnU6ZnVuY3Rpb24oKXtyZXR1cm4gSi5BYyh0aGlzLmRhcnRFeGNlcHRpb24pfSwKdmg6ZnVu
-Y3Rpb24oYSl7dGhyb3cgSC5iKGEpfSwKbGs6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKFAuYTQoYSkpfSwK
-Y006ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvCmE9SC5lQShhLnJlcGxhY2UoU3RyaW5nKHt9KSwn
-JHJlY2VpdmVyJCcpKQp0PWEubWF0Y2goL1xcXCRbYS16QS1aXStcXFwkL2cpCmlmKHQ9PW51bGwpdD1I
-LlZNKFtdLHUucykKcz10LmluZGV4T2YoIlxcJGFyZ3VtZW50c1xcJCIpCnI9dC5pbmRleE9mKCJcXCRh
-cmd1bWVudHNFeHByXFwkIikKcT10LmluZGV4T2YoIlxcJGV4cHJcXCQiKQpwPXQuaW5kZXhPZigiXFwk
-bWV0aG9kXFwkIikKbz10LmluZGV4T2YoIlxcJHJlY2VpdmVyXFwkIikKcmV0dXJuIG5ldyBILmY5KGEu
-cmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkYXJndW1lbnRzXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154
-XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGFyZ3VtZW50c0V4cHJcXFxcXFwkJywnZycp
-LCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkZXhwclxcXFxcXCQnLCdn
-JyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRtZXRob2RcXFxcXFwk
-JywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkcmVjZWl2ZXJc
-XFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykscyxyLHEscCxvKX0sClM3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBmdW5jdGlvbigkZXhwciQpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7
-JGV4cHIkLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2godCl7cmV0dXJuIHQubWVzc2FnZX19
-KGEpfSwKTWo6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRleHByJCl7dHJ5eyRleHByJC4kbWV0
-aG9kJH1jYXRjaCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApJajpmdW5jdGlvbihhLGIpe3JldHVy
-biBuZXcgSC5XMChhLGI9PW51bGw/bnVsbDpiLm1ldGhvZCl9LApUMzpmdW5jdGlvbihhLGIpe3ZhciB0
-PWI9PW51bGwscz10P251bGw6Yi5tZXRob2QKcmV0dXJuIG5ldyBILmF6KGEscyx0P251bGw6Yi5yZWNl
-aXZlcil9LApSdTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGY9bnVs
-bCxlPW5ldyBILkFtKGEpCmlmKGE9PW51bGwpcmV0dXJuIGYKaWYoYSBpbnN0YW5jZW9mIEguYnEpcmV0
-dXJuIGUuJDEoYS5hKQppZih0eXBlb2YgYSE9PSJvYmplY3QiKXJldHVybiBhCmlmKCJkYXJ0RXhjZXB0
-aW9uIiBpbiBhKXJldHVybiBlLiQxKGEuZGFydEV4Y2VwdGlvbikKZWxzZSBpZighKCJtZXNzYWdlIiBp
-biBhKSlyZXR1cm4gYQp0PWEubWVzc2FnZQppZigibnVtYmVyIiBpbiBhJiZ0eXBlb2YgYS5udW1iZXI9
-PSJudW1iZXIiKXtzPWEubnVtYmVyCnI9cyY2NTUzNQppZigoQy5qbi53RyhzLDE2KSY4MTkxKT09PTEw
-KXN3aXRjaChyKXtjYXNlIDQzODpyZXR1cm4gZS4kMShILlQzKEguZCh0KSsiIChFcnJvciAiK3IrIiki
-LGYpKQpjYXNlIDQ0NTpjYXNlIDUwMDc6cmV0dXJuIGUuJDEoSC5JaihILmQodCkrIiAoRXJyb3IgIity
-KyIpIixmKSl9fWlmKGEgaW5zdGFuY2VvZiBUeXBlRXJyb3Ipe3E9JC5TbigpCnA9JC5scSgpCm89JC5O
-OSgpCm49JC5pSSgpCm09JC5VTigpCmw9JC5aaCgpCms9JC5yTigpCiQuYzMoKQpqPSQuSEsoKQppPSQu
-cjEoKQpoPXEucVModCkKaWYoaCE9bnVsbClyZXR1cm4gZS4kMShILlQzKEguYyh0KSxoKSkKZWxzZXto
-PXAucVModCkKaWYoaCE9bnVsbCl7aC5tZXRob2Q9ImNhbGwiCnJldHVybiBlLiQxKEguVDMoSC5jKHQp
-LGgpKX1lbHNle2g9by5xUyh0KQppZihoPT1udWxsKXtoPW4ucVModCkKaWYoaD09bnVsbCl7aD1tLnFT
-KHQpCmlmKGg9PW51bGwpe2g9bC5xUyh0KQppZihoPT1udWxsKXtoPWsucVModCkKaWYoaD09bnVsbCl7
-aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9ai5xUyh0KQppZihoPT1udWxsKXtoPWkucVModCkKZz1oIT1u
-dWxsfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBn
-PSEwfWVsc2UgZz0hMAppZihnKXJldHVybiBlLiQxKEguSWooSC5jKHQpLGgpKX19cmV0dXJuIGUuJDEo
-bmV3IEgudlYodHlwZW9mIHQ9PSJzdHJpbmciP3Q6IiIpKX1pZihhIGluc3RhbmNlb2YgUmFuZ2VFcnJv
-cil7aWYodHlwZW9mIHQ9PSJzdHJpbmciJiZ0LmluZGV4T2YoImNhbGwgc3RhY2siKSE9PS0xKXJldHVy
-biBuZXcgUC5LWSgpCnQ9ZnVuY3Rpb24oYil7dHJ5e3JldHVybiBTdHJpbmcoYil9Y2F0Y2goZCl7fXJl
-dHVybiBudWxsfShhKQpyZXR1cm4gZS4kMShuZXcgUC5BVCghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmci
-P3QucmVwbGFjZSgvXlJhbmdlRXJyb3I6XHMqLywiIik6dCkpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9y
-PT0iZnVuY3Rpb24iJiZhIGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2YgdD09InN0cmlu
-ZyImJnQ9PT0idG9vIG11Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRz
-OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVs
-bClyZXR1cm4gbmV3IEguWE8oYSkKdD1hLiRjYWNoZWRUcmFjZQppZih0IT1udWxsKXJldHVybiB0CnJl
-dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
-LHE9YS5sZW5ndGgKZm9yKHQ9MDt0PHE7dD1yKXtzPXQrMQpyPXMrMQpiLlkoMCxhW3RdLGFbc10pfXJl
-dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3UuWi5hKGEpCnN3aXRjaChILldZKGIpKXtj
-YXNlIDA6cmV0dXJuIGEuJDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQy
-KGMsZCkKY2FzZSAzOnJldHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9
-dGhyb3cgSC5iKG5ldyBQLkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFw
-cGVkIGNsb3N1cmUiKSl9LAp0UjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51
-bGwKdD1hLiRpZGVudGl0eQppZighIXQpcmV0dXJuIHQKdD1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1
-bmN0aW9uKGYsZyxoLGkpe3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0
-eT10CnJldHVybiB0fSwKaUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsPW51bGwsaz1iWzBdLGo9ay4kY2FsbE5hbWUsaT1lP09iamVjdC5jcmVhdGUobmV3IEguengoKS5j
-b25zdHJ1Y3Rvci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguankobCxsLGwsbCkuY29uc3Ry
-dWN0b3IucHJvdG90eXBlKQppLiRpbml0aWFsaXplPWkuY29uc3RydWN0b3IKaWYoZSl0PWZ1bmN0aW9u
-IHN0YXRpY190ZWFyX29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtzPSQueWoKaWYodHlwZW9m
-IHMhPT0ibnVtYmVyIilyZXR1cm4gcy5oKCkKJC55aj1zKzEKcz1uZXcgRnVuY3Rpb24oImEsYixjLGQi
-K3MsInRoaXMuJGluaXRpYWxpemUoYSxiLGMsZCIrcysiKSIpCnQ9c31pLmNvbnN0cnVjdG9yPXQKdC5w
-cm90b3R5cGU9aQppZighZSl7cj1ILmJ4KGEsayxmKQpyLiRyZWZsZWN0aW9uSW5mbz1kfWVsc2V7aS4k
-c3RhdGljX25hbWU9ZwpyPWt9cT1ILmltKGQsZSxmKQppLiRTPXEKaVtqXT1yCmZvcihwPXIsbz0xO288
-Yi5sZW5ndGg7KytvKXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEs
-bixmKQppW21dPW59aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1pLiRDPXAKaS4kUj1r
-LiRSCmkuJEQ9ay4kRApyZXR1cm4gdH0sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2Yg
-YT09Im51bWJlciIpcmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQo
-ZSl9fShILkJwLGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBj
-b21wdXRlIHNpZ25hdHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKdD1jP0guUFc6SC5UbgpyZXR1cm4g
-ZnVuY3Rpb24oZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSx0KX10aHJv
-dyBILmIoIkVycm9yIGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgdD1ILkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXty
-ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyx0KQpjYXNlIDE6cmV0dXJuIGZ1
-bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyx0KQpj
-YXNlIDI6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhp
-cylbZV0oZyxoKX19KGMsdCkKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlv
-bihnLGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyx0KQpjYXNlIDQ6cmV0dXJuIGZ1bmN0
-aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGop
-fX0oYyx0KQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGos
-ayl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGksaixrKX19KGMsdCkKZGVmYXVsdDpyZXR1cm4gZnVuY3Rp
-b24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9
-fShkLHQpfX0sCmJ4OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbgppZihjKXJldHVybiBI
-LkhmKGEsYikKdD1iLiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09bnVsbDpi
-PT09cgpwPSFxfHxzPj0yNwppZihwKXJldHVybiBILnZxKHMsIXEsdCxiKQppZihzPT09MCl7cT0kLnlq
-CmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIHEuaCgpCiQueWo9cSsxCm89InNlbGYiK3EKcT0i
-cmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbysiID0gdGhpcy4iCnA9JC5tSgpyZXR1cm4gbmV3IEZ1bmN0
-aW9uKHErSC5kKHA9PW51bGw/JC5tSj1ILkUyKCJzZWxmIik6cCkrIjtyZXR1cm4gIitvKyIuIitILmQo
-dCkrIigpO30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNl
-KDAscykuam9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLmgoKQok
-LnlqPXErMQpuKz1xCnE9InJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIgpwPSQubUoK
-cmV0dXJuIG5ldyBGdW5jdGlvbihxK0guZChwPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnApKyIuIitI
-LmQodCkrIigiK24rIik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILkRWLHM9SC55
-Uwpzd2l0Y2goYj8tMTphKXtjYXNlIDA6dGhyb3cgSC5iKEguRWYoIkludGVyY2VwdGVkIGZ1bmN0aW9u
-IHdpdGggbm8gYXJndW1lbnRzLiIpKQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4g
-ZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpKX19KGMsdCxzKQpjYXNlIDI6cmV0dXJu
-IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlz
-KSxoKX19KGMsdCxzKQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24o
-aCxpKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSl9fShjLHQscykKY2FzZSA0OnJldHVybiBm
-dW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
-aXMpLGgsaSxqKX19KGMsdCxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVu
-Y3Rpb24oaCxpLGosayl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrKX19KGMsdCxzKQpj
-YXNlIDY6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGosayxsKXtyZXR1
-cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGssbCl9fShjLHQscykKZGVmYXVsdDpyZXR1cm4gZnVu
-Y3Rpb24oZSxmLGcsaCl7cmV0dXJuIGZ1bmN0aW9uKCl7aD1bZyh0aGlzKV0KQXJyYXkucHJvdG90eXBl
-LnB1c2guYXBwbHkoaCxhcmd1bWVudHMpCnJldHVybiBlLmFwcGx5KGYodGhpcyksaCl9fShkLHQscyl9
-fSwKSGY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPSQubUoKaWYobT09bnVsbCltPSQu
-bUo9SC5FMigic2VsZiIpCnQ9JC5QNAppZih0PT1udWxsKXQ9JC5QND1ILkUyKCJyZWNlaXZlciIpCnM9
-Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51bGw6Yj09PXEKbz0hcHx8
-cj49MjgKaWYobylyZXR1cm4gSC5aNChyLCFwLHMsYikKaWYocj09PTEpe209InJldHVybiBmdW5jdGlv
-bigpe3JldHVybiB0aGlzLiIrSC5kKG0pKyIuIitILmQocykrIih0aGlzLiIrSC5kKHQpKyIpOyIKdD0k
-LnlqCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcg
-RnVuY3Rpb24obSt0KyJ9IikoKX1uPSJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIp
-LnNwbGljZSgwLHItMSkuam9pbigiLCIpCm09InJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRo
-aXMuIitILmQobSkrIi4iK0guZChzKSsiKHRoaXMuIitILmQodCkrIiwgIituKyIpOyIKdD0kLnlqCmlm
-KHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcgRnVuY3Rp
-b24obSt0KyJ9IikoKX0sCktxOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3JldHVybiBILmlBKGEsYixj
-LGQsISFlLCEhZixnKX0sClRuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2Us
-SC5xKGEuYSksYil9LApQVzpmdW5jdGlvbihhLGIpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgu
-cShhLmMpLGIpfSwKRFY6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuYX0sCnlTOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmN9LApFMjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1uZXcgSC5qeSgic2VsZiIsInRhcmdldCIs
-InJlY2VpdmVyIiwibmFtZSIpLHA9Si5FcChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhxKSkKZm9y
-KHQ9cC5sZW5ndGgscz0wO3M8dDsrK3Mpe3I9cFtzXQppZihxW3JdPT09YSlyZXR1cm4gcn19LApvVDpm
-dW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8oImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBiZSBu
-dWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwKYWc6
-ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQLnQ3KGEpKX0sCkVmOmZ1bmN0aW9uKGEpe3JldHVybiBu
-ZXcgSC5FcShhKX0sCllnOmZ1bmN0aW9uKGEpe3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApWTTpm
-dW5jdGlvbihhLGIpe2Fbdi5hcnJheVJ0aV09YgpyZXR1cm4gYX0sCm9YOmZ1bmN0aW9uKGEpe2lmKGE9
-PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIGEuJHRpfSwKSU06ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBI
-Llk5KGFbIiRhIitILmQoYyldLEgub1goYikpfSwKWTk6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJl
-dHVybiBiCmE9YS5hcHBseShudWxsLGIpCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoQXJyYXkuaXNB
-cnJheShhKSlyZXR1cm4gYQppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gYS5hcHBseShudWxs
-LGIpCnJldHVybiBifSwKSUc6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBhLmFwcGx5KGIsSC5ZOShKLmlh
-KGIpWyIkYSIrSC5kKGMpXSxILm9YKGIpKSl9LAppdzpmdW5jdGlvbihhLGIsYyl7T2JqZWN0LmRlZmlu
-ZVByb3BlcnR5KGEsYix7dmFsdWU6YyxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmln
-dXJhYmxlOnRydWV9KX0sCkc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1ILmMoJC55LiQxKGEpKSxv
-PSQualtwXQppZihvIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVy
-dHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6
-dHJ1ZX0pCnJldHVybiBvLml9dD0kLnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0
-b3JzQnlUYWdbcF0KaWYocz09bnVsbCl7cD1ILmMoJC51LiQyKGEscCkpCmlmKHAhPW51bGwpe289JC5q
-W3BdCmlmKG8hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5h
-bWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVl
-fSkKcmV0dXJuIG8uaX10PSQudltwXQppZih0IT1udWxsKXJldHVybiB0CnM9di5pbnRlcmNlcHRvcnNC
-eVRhZ1twXX19aWYocz09bnVsbClyZXR1cm4gbnVsbAp0PXMucHJvdG90eXBlCnI9cFswXQppZihyPT09
-IiEiKXtvPUgubCh0KQokLmpbcF09bwpPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJv
-cGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFi
-bGU6dHJ1ZX0pCnJldHVybiBvLml9aWYocj09PSJ+Iil7JC52W3BdPXQKcmV0dXJuIHR9aWYocj09PSIt
-Iil7cT1ILmwodCkKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSx2
-LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpxLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1
-ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBxLml9aWYocj09PSIrIilyZXR1cm4gSC5MYyhhLHQp
-CmlmKHI9PT0iKiIpdGhyb3cgSC5iKFAubihwKSkKaWYodi5sZWFmVGFnc1twXT09PXRydWUpe3E9SC5s
-KHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5kaXNwYXRj
-aFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmln
-dXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWVsc2UgcmV0dXJuIEguTGMoYSx0KX0sCkxjOmZ1bmN0aW9u
-KGEsYil7dmFyIHQ9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0
-LHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYix0LG51bGwsbnVsbCksZW51bWVyYWJs
-ZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApsOmZ1bmN0
-aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlYail9LApWRjpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQ9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09PXRydWUpcmV0dXJuIEgubCh0KQplbHNl
-IHJldHVybiBKLlF1KHQsYyxudWxsLG51bGwpfSwKTTpmdW5jdGlvbigpe2lmKCEwPT09JC5LKXJldHVy
-bgokLks9ITAKSC5EKCl9LApEOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbQokLmo9T2JqZWN0
-LmNyZWF0ZShudWxsKQokLnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmEoKQp0PXYuaW50ZXJjZXB0b3Jz
-QnlUYWcKcz1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0KQppZih0eXBlb2Ygd2luZG93IT0idW5k
-ZWZpbmVkIil7d2luZG93CnI9ZnVuY3Rpb24oKXt9CmZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1tx
-XQpvPSQueDcuJDEocCkKaWYobyE9bnVsbCl7bj1ILlZGKHAsdFtwXSxvKQppZihuIT1udWxsKXtPYmpl
-Y3QuZGVmaW5lUHJvcGVydHkobyx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpuLGVudW1lcmFi
-bGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnIucHJvdG90eXBlPW99fX19
-Zm9yKHE9MDtxPHMubGVuZ3RoOysrcSl7cD1zW3FdCmlmKC9eW0EtWmEtel9dLy50ZXN0KHApKXttPXRb
-cF0KdFsiISIrcF09bQp0WyJ+IitwXT1tCnRbIi0iK3BdPW0KdFsiKyIrcF09bQp0WyIqIitwXT1tfX19
-LAphOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49Qy5PNCgpCm49SC5GKEMuWXEsSC5GKEMuS1Us
-SC5GKEMuZlEsSC5GKEMuZlEsSC5GKEMuaTcsSC5GKEMueGksSC5GKEMuZGsoQy53YiksbikpKSkpKSkK
-aWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIhPSJ1bmRlZmluZWQiKXt0
-PWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIKaWYodHlwZW9mIHQ9PSJmdW5jdGlvbiIp
-dD1bdF0KaWYodC5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHM9MDtzPHQubGVuZ3RoOysrcyl7cj10W3Nd
-CmlmKHR5cGVvZiByPT0iZnVuY3Rpb24iKW49cihuKXx8bn19cT1uLmdldFRhZwpwPW4uZ2V0VW5rbm93
-blRhZwpvPW4ucHJvdG90eXBlRm9yVGFnCiQueT1uZXcgSC5yKHEpCiQudT1uZXcgSC5kQyhwKQokLng3
-PW5ldyBILndOKG8pfSwKRjpmdW5jdGlvbihhLGIpe3JldHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24o
-YSxiLGMsZCxlLGYpe3ZhciB0PWI/Im0iOiIiLHM9Yz8iIjoiaSIscj1kPyJ1IjoiIixxPWU/InMiOiIi
-LHA9Zj8iZyI6IiIsbz1mdW5jdGlvbihnLGgpe3RyeXtyZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNo
-KG4pe3JldHVybiBufX0oYSx0K3MrcitxK3ApCmlmKG8gaW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG8K
-dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgUmVnRXhwIHBhdHRlcm4gKCIrU3RyaW5nKG8pKyIpIixhLG51
-bGwpKX0sCm0yOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJu
-IGEuaW5kZXhPZihiLGMpPj0wCmVsc2UgaWYoYiBpbnN0YW5jZW9mIEguVlIpe3Q9Qy54Qi5HKGEsYykK
-cmV0dXJuIGIuYi50ZXN0KHQpfWVsc2V7dD1KLkZMKGIsQy54Qi5HKGEsYykpCnJldHVybiF0LmdsMCh0
-KX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2Uo
-L1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4k
-fF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgvW1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpy
-ZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILm5NKGEsYixjKQpyZXR1cm4gdH0sCm5N
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwp0
-PWEubGVuZ3RoCmZvcihzPWMscj0wO3I8dDsrK3Ipcz1zK2Fbcl0rYwpyZXR1cm4gcy5jaGFyQ29kZUF0
-KDApPT0wP3M6c31xPWEuaW5kZXhPZihiLDApCmlmKHE8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8
-fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEuc3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBs
-YWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEguQTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0
-aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rpb24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIs
-YyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihh
-LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpmdW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRo
-aXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5mPWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhp
-cy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpmdW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89
-dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5jdGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
-PWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2VihhKXt0aGlzLmE9YX0sCmJxOmZ1bmN0aW9uIGJxKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBbTpmdW5jdGlvbiBBbShhKXt0aGlzLmE9YX0sClhPOmZ1bmN0
-aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwKVHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5j
-dGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7fSwKank6ZnVuY3Rpb24gankoYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1h
-fSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9LApONTpmdW5jdGlvbiBONShhKXt2YXIgXz10aGlz
-Cl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKZGI6ZnVuY3Rpb24g
-ZGIoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbH0sCmk1OmZ1bmN0aW9uIGk1
-KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCk42OmZ1bmN0aW9uIE42KGEsYixjKXt2YXIgXz10aGlz
-Cl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbApfLiR0aT1jfSwKcjpmdW5jdGlvbiByKGEpe3RoaXMuYT1h
-fSwKZEM6ZnVuY3Rpb24gZEMoYSl7dGhpcy5hPWF9LAp3TjpmdW5jdGlvbiB3TihhKXt0aGlzLmE9YX0s
-ClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApF
-SzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktXOmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0
-aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9uIFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8u
-Yj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rpb24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0s
-Ck5GOmZ1bmN0aW9uIE5GKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0
-aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEludDhBcnJheShhKX0s
-Cm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9PWF8fGE+PWMpdGhyb3cgSC5iKEguSFkoYixhKSl9
-LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1ifHxhPmJ8
-fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoSC5hdShhLGIsYykpCnJldHVybiBifSwKcEY6ZnVu
-Y3Rpb24gcEYoKXt9LApiMDpmdW5jdGlvbiBiMCgpe30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVu
-Y3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigpe30sCmRFOmZ1bmN0aW9uIGRFKCl7fSwKWkE6ZnVu
-Y3Rpb24gWkEoKXt9LAp3ZjpmdW5jdGlvbiB3Zigpe30sClBxOmZ1bmN0aW9uIFBxKCl7fSwKZUU6ZnVu
-Y3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigpe30sClJHOmZ1bmN0aW9uIFJHKCl7fSwKVlA6ZnVu
-Y3Rpb24gVlAoKXt9LApXQjpmdW5jdGlvbiBXQigpe30sClpHOmZ1bmN0aW9uIFpHKCl7fSwKY3o6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdD1iLmMKcmV0dXJuIHQ9PW51bGw/Yi5jPUguQmMoYSxiLnosITApOnR9LAp4
-WjpmdW5jdGlvbihhLGIpe3ZhciB0PWIuYwpyZXR1cm4gdD09bnVsbD9iLmM9SC5RMihhLCJiOCIsW2Iu
-el0pOnR9LApRMTpmdW5jdGlvbihhKXt2YXIgdD1hLnkKaWYodD09PTZ8fHQ9PT03fHx0PT09OClyZXR1
-cm4gSC5RMShhLnopCnJldHVybiB0PT09MTF8fHQ9PT0xMn0sCm1EOmZ1bmN0aW9uKGEpe3JldHVybiBh
-LmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCExKX0sClBMOmZ1
-bmN0aW9uKGEsYixjLGEwKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPWIueQpz
-d2l0Y2goZCl7Y2FzZSA1OmNhc2UgMTpjYXNlIDI6Y2FzZSAzOmNhc2UgNDpyZXR1cm4gYgpjYXNlIDY6
-dD1iLnoKcz1ILlBMKGEsdCxjLGEwKQppZihzPT09dClyZXR1cm4gYgpyZXR1cm4gSC5TTyhhLHMsITAp
-CmNhc2UgNzp0PWIuegpzPUguUEwoYSx0LGMsYTApCmlmKHM9PT10KXJldHVybiBiCnJldHVybiBILkJj
-KGEscywhMCkKY2FzZSA4OnQ9Yi56CnM9SC5QTChhLHQsYyxhMCkKaWYocz09PXQpcmV0dXJuIGIKcmV0
-dXJuIEguTE4oYSxzLCEwKQpjYXNlIDk6cj1iLlEKcT1ILmJaKGEscixjLGEwKQppZihxPT09cilyZXR1
-cm4gYgpyZXR1cm4gSC5RMihhLGIueixxKQpjYXNlIDEwOnA9Yi56Cm89SC5QTChhLHAsYyxhMCkKbj1i
-LlEKbT1ILmJaKGEsbixjLGEwKQppZihvPT09cCYmbT09PW4pcmV0dXJuIGIKcmV0dXJuIEguYXAoYSxv
-LG0pCmNhc2UgMTE6bD1iLnoKaz1ILlBMKGEsbCxjLGEwKQpqPWIuUQppPUgucVQoYSxqLGMsYTApCmlm
-KGs9PT1sJiZpPT09ailyZXR1cm4gYgpyZXR1cm4gSC5OZihhLGssaSkKY2FzZSAxMjpoPWIuUQphMCs9
-aC5sZW5ndGgKZz1ILmJaKGEsaCxjLGEwKQpwPWIuegpvPUguUEwoYSxwLGMsYTApCmlmKGc9PT1oJiZv
-PT09cClyZXR1cm4gYgpyZXR1cm4gSC5EUyhhLG8sZywhMCkKY2FzZSAxMzpmPWIuegppZihmPGEwKXJl
-dHVybiBiCmU9Y1tmLWEwXQppZihlPT1udWxsKXJldHVybiBiCnJldHVybiBlCmRlZmF1bHQ6dGhyb3cg
-SC5iKFAuaFYoIkF0dGVtcHRlZCB0byBzdWJzdGl0dXRlIHVuZXhwZWN0ZWQgUlRJIGtpbmQgIitkKSl9
-fSwKYlo6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscD1iLmxlbmd0aCxvPVtdCmZvcih0PSEx
-LHM9MDtzPHA7KytzKXtyPWJbc10KcT1ILlBMKGEscixjLGQpCmlmKHEhPT1yKXQ9ITAKby5wdXNoKHEp
-fXJldHVybiB0P286Yn0sCnZPOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbz1iLmxlbmd0
-aCxuPVtdCmZvcih0PSExLHM9MDtzPG87cys9Mil7cj1iW3NdCnE9YltzKzFdCnA9SC5QTChhLHEsYyxk
-KQppZihwIT09cSl0PSEwCm4ucHVzaChyKQpuLnB1c2gocCl9cmV0dXJuIHQ/bjpifSwKcVQ6ZnVuY3Rp
-b24oYSxiLGMsZCl7dmFyIHQscz1iLmEscj1ILmJaKGEscyxjLGQpLHE9Yi5iLHA9SC5iWihhLHEsYyxk
-KSxvPWIuYyxuPUgudk8oYSxvLGMsZCkKaWYocj09PXMmJnA9PT1xJiZuPT09bylyZXR1cm4gYgp0PW5l
-dyBILkVUKCkKdC5hPXIKdC5iPXAKdC5jPW4KcmV0dXJuIHR9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1h
-LiRTCmlmKHQhPW51bGwpe2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4g
-YS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEg
-aW5zdGFuY2VvZiBILlRwKXt0PUguSlMoYSkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gSC5xKGEp
-fSwKcTpmdW5jdGlvbihhKXt2YXIgdAppZihhIGluc3RhbmNlb2YgUC5NaCl7dD1hLiR0aQpyZXR1cm4g
-dCE9bnVsbD90OkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4g
-SC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciB0PWFbdi5hcnJheVJ0aV0scz11Lm0KaWYo
-dD09bnVsbClyZXR1cm4gcwppZih0LmNvbnN0cnVjdG9yIT09cy5jb25zdHJ1Y3RvcilyZXR1cm4gcwpy
-ZXR1cm4gdH0sCkxoOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShh
-KX0sClZVOmZ1bmN0aW9uKGEpe3ZhciB0PWEuY29uc3RydWN0b3Iscz10LiRjY2FjaGUKaWYocyE9bnVs
-bClyZXR1cm4gcwpyZXR1cm4gSC5yOShhLHQpfSwKcjk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hIGluc3Rh
-bmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0b3I6YixzPUguYWkodi50eXBl
-VW5pdmVyc2UsdC5uYW1lKQpiLiRjY2FjaGU9cwpyZXR1cm4gc30sCkJwOmZ1bmN0aW9uKGEpe3ZhciB0
-LHM9YSxyPXYudHlwZXMscT1yW3NdCmlmKHR5cGVvZiBxPT0ic3RyaW5nIil7dD1ILkUodi50eXBlVW5p
-dmVyc2UscSwhMSkKcltzXT10CnJldHVybiB0fXJldHVybiBxfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcyxzPUguWU8scj11LksKaWYodD09PXIpe3M9SC5rZQp0LmE9SC5UaX1lbHNlIGlmKEguQTgodCl8
-fHQ9PT1yKXtzPUguSXcKdC5hPUguaG59ZWxzZSBpZih0PT09dS5TKXM9SC5vawplbHNlIGlmKHQ9PT11
-LmdSKXM9SC5LSAplbHNlIGlmKHQ9PT11LmRpKXM9SC5LSAplbHNlIGlmKHQ9PT11Lk4pcz1ILk1NCmVs
-c2UgaWYodD09PXUueSlzPUguclEKZWxzZSBpZih0Lnk9PT05KXtyPXQuegppZih0LlEuZXZlcnkoSC5j
-Yykpe3Qucj0iJGkiK3IKcz1ILnQ0fX10LmI9cwpyZXR1cm4gdC5iKGEpfSwKWU86ZnVuY3Rpb24oYSl7
-dmFyIHQ9dGhpcwpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEsdCksbnVsbCx0LG51bGwp
-fSwKdDQ6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPXQucgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1
-cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwppZihh
-PT1udWxsKXJldHVybiBhCmVsc2UgaWYodC5iKGEpKXJldHVybiBhCnRocm93IEguYihILlpjKEgucChh
-LEguVWUoYSx0KSxILkoodCxudWxsKSkpKX0sCkRoOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PW51bGwK
-aWYoSC5XZSh2LnR5cGVVbml2ZXJzZSxhLHQsYix0KSlyZXR1cm4gYQp0aHJvdyBILmIoSC5aYygiVGhl
-IHR5cGUgYXJndW1lbnQgJyIrSC5kKEguSihhLHQpKSsiJyBpcyBub3QgYSBzdWJ0eXBlIG9mIHRoZSB0
-eXBlIHZhcmlhYmxlIGJvdW5kICciK0guZChILkooYix0KSkrIicgb2YgdHlwZSB2YXJpYWJsZSAnIitj
-KyInIGluICciK0guZChkKSsiJy4iKSl9LApwOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1QLmgoYSkscz1I
-LkooYj09bnVsbD9ILnEoYSk6YixudWxsKQpyZXR1cm4gdCsiOiB0eXBlICciK0guZChzKSsiJyBpcyBu
-b3QgYSBzdWJ0eXBlIG9mIHR5cGUgJyIrSC5kKGMpKyInIn0sClpjOmZ1bmN0aW9uKGEpe3JldHVybiBu
-ZXcgSC54KCJUeXBlRXJyb3I6ICIrYSl9LApCOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILngoIlR5
-cGVFcnJvcjogIitILnAoYSxudWxsLGIpKX0sCmtlOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKVGk6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGF9LApJdzpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmhuOmZ1bmN0aW9uKGEp
-e3JldHVybiBhfSwKclE6ZnVuY3Rpb24oYSl7cmV0dXJuITA9PT1hfHwhMT09PWF9LApFOTpmdW5jdGlv
-bihhKXtpZighMD09PWF8fCExPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEgu
-YihILkIoYSwiYm9vbCIpKX0sCmRqOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1
-cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILkIoYSwiZG91YmxlIikpfSwKb2s6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWF9LApXWTpm
-dW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBh
-CmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguQihhLCJpbnQiKSl9LApLSDpmdW5jdGlvbihh
-KXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKdVU6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJu
-dW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguQihhLCJudW0iKSl9
-LApNTTpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKYzpmdW5jdGlvbihhKXtp
-Zih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIo
-SC5CKGEsIlN0cmluZyIpKX0sCnc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKZm9yKHQ9IiIscz0iIixy
-PTA7cjxhLmxlbmd0aDsrK3Iscz0iLCAiKXQrPUMueEIuaChzLEguSihhW3JdLGIpKQpyZXR1cm4gdH0s
-CmY6ZnVuY3Rpb24oYTEsYTIsYTMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQs
-YyxiLGEsYTA9IiwgIgppZihhMyE9bnVsbCl7dD1hMy5sZW5ndGgKaWYoYTI9PW51bGwpe2EyPUguVk0o
-W10sdS5zKQpzPW51bGx9ZWxzZSBzPWEyLmxlbmd0aApyPWEyLmxlbmd0aApmb3IocT10O3E+MDstLXEp
-Qy5ObS5pKGEyLCJUIisocitxKSkKZm9yKHA9dS5LLG89IjwiLG49IiIscT0wO3E8dDsrK3Esbj1hMCl7
-bys9bgptPWEyLmxlbmd0aApsPW0tMS1xCmlmKGw8MClyZXR1cm4gSC5rKGEyLGwpCm89Qy54Qi5oKG8s
-YTJbbF0pCms9YTNbcV0KaWYoIShILkE4KGspfHxrPT09cCkpbT0hKGs9PT1wKQplbHNlIG09ITEKaWYo
-bSlvKz1DLnhCLmgoIiBleHRlbmRzICIsSC5KKGssYTIpKX1vKz0iPiJ9ZWxzZXtvPSIiCnM9bnVsbH1w
-PWExLnoKaj1hMS5RCmk9ai5hCmg9aS5sZW5ndGgKZz1qLmIKZj1nLmxlbmd0aAplPWouYwpkPWUubGVu
-Z3RoCmM9SC5KKHAsYTIpCmZvcihiPSIiLGE9IiIscT0wO3E8aDsrK3EsYT1hMCliKz1DLnhCLmgoYSxI
-LkooaVtxXSxhMikpCmlmKGY+MCl7Yis9YSsiWyIKZm9yKGE9IiIscT0wO3E8ZjsrK3EsYT1hMCliKz1D
-LnhCLmgoYSxILkooZ1txXSxhMikpCmIrPSJdIn1pZihkPjApe2IrPWErInsiCmZvcihhPSIiLHE9MDtx
-PGQ7cSs9MixhPWEwKWIrPUMueEIuaChhLEguSihlW3ErMV0sYTIpKSsiICIrZVtxXQpiKz0ifSJ9aWYo
-cyE9bnVsbClhMi5sZW5ndGg9cwpyZXR1cm4gbysiKCIrYisiKSA9PiAiK0guZChjKX0sCko6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEueQppZihtPT09NSlyZXR1cm4iZXJhc2VkIgppZiht
-PT09MilyZXR1cm4iZHluYW1pYyIKaWYobT09PTMpcmV0dXJuInZvaWQiCmlmKG09PT0xKXJldHVybiJO
-ZXZlciIKaWYobT09PTQpcmV0dXJuImFueSIKaWYobT09PTYpe3Q9SC5KKGEueixiKQpyZXR1cm4gdH1p
-ZihtPT09Nyl7cz1hLnoKdD1ILkoocyxiKQpyPXMueQpyZXR1cm4gSi5tKHI9PT0xMXx8cj09PTEyP0Mu
-eEIuaCgiKCIsdCkrIikiOnQsIj8iKX1pZihtPT09OClyZXR1cm4iRnV0dXJlT3I8IitILmQoSC5KKGEu
-eixiKSkrIj4iCmlmKG09PT05KXtxPUguQyhhLnopCnA9YS5RCnJldHVybiBwLmxlbmd0aCE9PTA/cSso
-IjwiK0gudyhwLGIpKyI+Iik6cX1pZihtPT09MTEpcmV0dXJuIEguZihhLGIsbnVsbCkKaWYobT09PTEy
-KXJldHVybiBILmYoYS56LGIsYS5RKQppZihtPT09MTMpe289YS56Cm49Yi5sZW5ndGgKbz1uLTEtbwpp
-ZihvPDB8fG8+PW4pcmV0dXJuIEguayhiLG8pCnJldHVybiBiW29dfXJldHVybiI/In0sCkM6ZnVuY3Rp
-b24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0ibWluaWZpZWQ6IithCnJl
-dHVybiB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7dHlwZW9mIHQ9PSJzdHJp
-bmciOyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1h
-LmVULG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiLCExKQplbHNlIGlmKHR5cGVvZiBuPT0i
-bnVtYmVyIil7dD1uCnM9SC5tWihhLDUsIiMiKQpyPVtdCmZvcihxPTA7cTx0OysrcSlyLnB1c2gocykK
-cD1ILlEyKGEsYixyKQpvW2JdPXAKcmV0dXJuIHB9ZWxzZSByZXR1cm4gbn0sCnhiOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIEguSXgoYS50UixiKX0sCkZGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguSXgoYS5lVCxi
-KX0sCkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9YS5lQyxyPXMuZ2V0KGIpCmlmKHIhPW51bGwpcmV0
-dXJuIHIKdD1ILnooYSxudWxsLGIsYykKcy5zZXQoYix0KQpyZXR1cm4gdH0sCmNFOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdCxzLHI9Yi5jaAppZihyPT1udWxsKXI9Yi5jaD1uZXcgTWFwKCkKdD1yLmdldChjKQpp
-Zih0IT1udWxsKXJldHVybiB0CnM9SC56KGEsYixjLCEwKQpyLnNldChjLHMpCnJldHVybiBzfSwKdjU6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIuY3gKaWYocT09bnVsbClxPWIuY3g9bmV3IE1hcCgp
-CnQ9Yy5jeQpzPXEuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmFwKGEsYixjLnk9PT0xMD9j
-LlE6W2NdKQpxLnNldCh0LHIpCnJldHVybiByfSwKejpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILmko
-SC5vKGEsYixjLGQpKQppZih0IT1udWxsKXJldHVybiB0CnRocm93IEguYihQLm4oJ19Vbml2ZXJzZS5f
-cGFyc2VSZWNpcGUoIicrSC5kKGMpKyciKScpKX0sCkJEOmZ1bmN0aW9uKGEsYil7Yi5hPUguT3oKYi5i
-PUguSkoKcmV0dXJuIGJ9LAptWjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPWEuZUMuZ2V0KGMpCmlm
-KHIhPW51bGwpcmV0dXJuIHIKdD1uZXcgSC5KYyhudWxsLG51bGwpCnQueT1iCnQuY3k9YwpzPUguQkQo
-YSx0KQphLmVDLnNldChjLHMpCnJldHVybiBzfSwKU086ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5j
-eSsiKiIscj1hLmVDLmdldChzKQppZihyIT1udWxsKXJldHVybiByCnQ9SC5aNyhhLGIscyxjKQphLmVD
-LnNldChzLHQpCnJldHVybiB0fSwKWjc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihkKXt0PWIu
-eQppZihILkE4KGIpfHxiPT09dS5LfHxiPT09dS5QfHx0PT09N3x8dD09PTYpcmV0dXJuIGJ9cz1uZXcg
-SC5KYyhudWxsLG51bGwpCnMueT02CnMuej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKQmM6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5jeSsiPyIscj1hLmVDLmdldChzKQppZihyIT1udWxsKXJldHVy
-biByCnQ9SC5sbChhLGIscyxjKQphLmVDLnNldChzLHQpCnJldHVybiB0fSwKbGw6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscyxyLHEscAppZihkKXt0PWIueQppZighSC5BOChiKSlpZighKGI9PT11LlApKWlm
-KHQhPT03KXM9dD09PTgmJkgubFIoYi56KQplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMAppZihz
-KXJldHVybiBiCmVsc2UgaWYodD09PTEpcmV0dXJuIHUuUAplbHNlIGlmKHQ9PT02KXtyPWIuegpxPXIu
-eQppZihxPT09MSlyZXR1cm4gdS5QCmVsc2UgaWYocT09PTgmJkgubFIoci56KSlyZXR1cm4gcgplbHNl
-IHJldHVybiBILmN6KGEsYil9fXA9bmV3IEguSmMobnVsbCxudWxsKQpwLnk9NwpwLno9YgpwLmN5PWMK
-cmV0dXJuIEguQkQoYSxwKX0sCkxOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWIuY3krIi8iLHI9YS5l
-Qy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PUguZVYoYSxiLHMsYykKYS5lQy5zZXQocyx0KQpy
-ZXR1cm4gdH0sCmVWOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKaWYoZCl7dD1iLnkKaWYoSC5BOChi
-KXx8Yj09PXUuS3x8Yj09PXUuSylyZXR1cm4gYgplbHNlIGlmKHQ9PT0xKXJldHVybiBILlEyKGEsImI4
-IixbYl0pCmVsc2UgaWYoYj09PXUuUClyZXR1cm4gdS5hUX1zPW5ldyBILkpjKG51bGwsbnVsbCkKcy55
-PTgKcy56PWIKcy5jeT1jCnJldHVybiBILkJEKGEscyl9LApIYzpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cj0iIitiKyJeIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKdD1uZXcgSC5KYyhudWxs
-LG51bGwpCnQueT0xMwp0Lno9Ygp0LmN5PXIKcz1ILkJEKGEsdCkKYS5lQy5zZXQocixzKQpyZXR1cm4g
-c30sClV4OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8
-cTsrK3Iscz0iLCIpdCs9cythW3JdLmN5CnJldHVybiB0fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvPWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8bztyKz0yLHM9IiwiKXtxPWFbcl0KcD1h
-W3IrMV0uY3kKdCs9cytxKyI6IitwfXJldHVybiB0fSwKUTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cixxPWIKaWYoYy5sZW5ndGghPT0wKXErPSI8IitILlV4KGMpKyI+Igp0PWEuZUMuZ2V0KHEpCmlmKHQh
-PW51bGwpcmV0dXJuIHQKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT05CnMuej1iCnMuUT1jCmlmKGMu
-bGVuZ3RoPjApcy5jPWNbMF0Kcy5jeT1xCnI9SC5CRChhLHMpCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9
-LAphcDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvCmlmKGIueT09PTEwKXt0PWIuegpzPWIu
-US5jb25jYXQoYyl9ZWxzZXtzPWMKdD1ifXI9dC5jeSsiOyIrKCI8IitILlV4KHMpKyI+IikKcT1hLmVD
-LmdldChyKQppZihxIT1udWxsKXJldHVybiBxCnA9bmV3IEguSmMobnVsbCxudWxsKQpwLnk9MTAKcC56
-PXQKcC5RPXMKcC5jeT1yCm89SC5CRChhLHApCmEuZUMuc2V0KHIsbykKcmV0dXJuIG99LApOZjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1iLmN5LG89Yy5hLG49by5sZW5ndGgsbT1jLmIsbD1tLmxl
-bmd0aCxrPWMuYyxqPWsubGVuZ3RoLGk9IigiK0guVXgobykKaWYobD4wKWkrPShuPjA/IiwiOiIiKSsi
-WyIrSC5VeChtKSsiXSIKaWYoaj4wKWkrPShuPjA/IiwiOiIiKSsieyIrSC5TNChrKSsifSIKdD1wKyhp
-KyIpIikKcz1hLmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9bmV3IEguSmMobnVsbCxudWxs
-KQpyLnk9MTEKci56PWIKci5RPWMKci5jeT10CnE9SC5CRChhLHIpCmEuZUMuc2V0KHQscSkKcmV0dXJu
-IHF9LApEUzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzPWIuY3krIjwiK0guVXgoYykrIj4iLHI9YS5l
-Qy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PUguaHcoYSxiLGMscyxkKQphLmVDLnNldChzLHQp
-CnJldHVybiB0fSwKaHc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG8sbixtCmlmKGUp
-e3Q9Yy5sZW5ndGgKcz1uZXcgQXJyYXkodCkKZm9yKHI9MCxxPTA7cTx0OysrcSl7cD1jW3FdCmlmKHAu
-eT09PTEpe3NbcV09cDsrK3J9fWlmKHI+MCl7bz1ILlBMKGEsYixzLDApCm49SC5iWihhLGMscywwKQpy
-ZXR1cm4gSC5EUyhhLG8sbixjIT09bil9fW09bmV3IEguSmMobnVsbCxudWxsKQptLnk9MTIKbS56PWIK
-bS5RPWMKbS5jeT1kCnJldHVybiBILkJEKGEsbSl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1
-OmEsZTpiLHI6YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqLGksaD1hLnIsZz1hLnMKZm9yKHQ9aC5sZW5ndGgscz0wO3M8dDspe3I9aC5jaGFyQ29kZUF0
-KHMpCmlmKHI+PTQ4JiZyPD01NylzPUguQWwocysxLHIsaCxnKQplbHNlIGlmKCgoKHJ8MzIpPj4+MCkt
-OTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNilzPUguUjgoYSxzLGgsZywhMSkKZWxzZSBpZihyPT09
-NDYpcz1ILlI4KGEscyxoLGcsITApCmVsc2V7KytzCnN3aXRjaChyKXtjYXNlIDQ0OmJyZWFrCmNhc2Ug
-NTg6YnJlYWsKY2FzZSA1OTpnLnB1c2goSC5LUShhLnUsYS5lLGcucG9wKCkpKQpicmVhawpjYXNlIDk0
-OmcucHVzaChILkhjKGEudSxnLnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpnLnB1c2goSC5tWihhLnUsNSwi
-IyIpKQpicmVhawpjYXNlIDY0OmcucHVzaChILm1aKGEudSwyLCJAIikpCmJyZWFrCmNhc2UgMTI2Omcu
-cHVzaChILm1aKGEudSwzLCJ+IikpCmJyZWFrCmNhc2UgNjA6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3Ro
-CmJyZWFrCmNhc2UgNjI6cT1hLnUKcD1nLnNwbGljZShhLnApCkguclQoYS51LGEuZSxwKQphLnA9Zy5w
-b3AoKQpvPWcucG9wKCkKaWYodHlwZW9mIG89PSJzdHJpbmciKWcucHVzaChILlEyKHEsbyxwKSkKZWxz
-ZXtuPUguS1EocSxhLmUsbykKc3dpdGNoKG4ueSl7Y2FzZSAxMTpnLnB1c2goSC5EUyhxLG4scCxhLm4p
-KQpicmVhawpkZWZhdWx0OmcucHVzaChILmFwKHEsbixwKSkKYnJlYWt9fWJyZWFrCmNhc2UgMzg6SC5J
-MyhhLGcpCmJyZWFrCmNhc2UgNDI6bT1hLnUKZy5wdXNoKEguU08obSxILktRKG0sYS5lLGcucG9wKCkp
-LGEubikpCmJyZWFrCmNhc2UgNjM6bT1hLnUKZy5wdXNoKEguQmMobSxILktRKG0sYS5lLGcucG9wKCkp
-LGEubikpCmJyZWFrCmNhc2UgNDc6bT1hLnUKZy5wdXNoKEguTE4obSxILktRKG0sYS5lLGcucG9wKCkp
-LGEubikpCmJyZWFrCmNhc2UgNDA6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3RoCmJyZWFrCmNhc2UgNDE6
-cT1hLnUKbD1uZXcgSC5FVCgpCms9cS5zRUEKaj1xLnNFQQpvPWcucG9wKCkKaWYodHlwZW9mIG89PSJu
-dW1iZXIiKXN3aXRjaChvKXtjYXNlLTE6az1nLnBvcCgpCmJyZWFrCmNhc2UtMjpqPWcucG9wKCkKYnJl
-YWsKZGVmYXVsdDpnLnB1c2gobykKYnJlYWt9ZWxzZSBnLnB1c2gobykKcD1nLnNwbGljZShhLnApCkgu
-clQoYS51LGEuZSxwKQphLnA9Zy5wb3AoKQpsLmE9cApsLmI9awpsLmM9agpnLnB1c2goSC5OZihxLEgu
-S1EocSxhLmUsZy5wb3AoKSksbCkpCmJyZWFrCmNhc2UgOTE6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3Ro
-CmJyZWFrCmNhc2UgOTM6cD1nLnNwbGljZShhLnApCkguclQoYS51LGEuZSxwKQphLnA9Zy5wb3AoKQpn
-LnB1c2gocCkKZy5wdXNoKC0xKQpicmVhawpjYXNlIDEyMzpnLnB1c2goYS5wKQphLnA9Zy5sZW5ndGgK
-YnJlYWsKY2FzZSAxMjU6cD1nLnNwbGljZShhLnApCkguV1MoYS51LGEuZSxwKQphLnA9Zy5wb3AoKQpn
-LnB1c2gocCkKZy5wdXNoKC0yKQpicmVhawpkZWZhdWx0OnRocm93IkJhZCBjaGFyYWN0ZXIgIityfX19
-aT1nLnBvcCgpCnJldHVybiBILktRKGEudSxhLmUsaSl9LApBbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
-dCxzLHI9Yi00OApmb3IodD1jLmxlbmd0aDthPHQ7KythKXtzPWMuY2hhckNvZGVBdChhKQppZighKHM+
-PTQ4JiZzPD01NykpYnJlYWsKcj1yKjEwKyhzLTQ4KX1kLnB1c2gocikKcmV0dXJuIGF9LApSODpmdW5j
-dGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuPWIrMQpmb3IodD1jLmxlbmd0aDtuPHQ7Kytu
-KXtzPWMuY2hhckNvZGVBdChuKQppZihzPT09NDYpe2lmKGUpYnJlYWsKZT0hMH1lbHNle2lmKCEoKCgo
-c3wzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHM9PT05NXx8cz09PTM2KSlyPXM+PTQ4JiZzPD01NwplbHNl
-IHI9ITAKaWYoIXIpYnJlYWt9fXE9Yy5zdWJzdHJpbmcoYixuKQppZihlKXt0PWEudQpwPWEuZQppZihw
-Lnk9PT0xMClwPXAuegpvPUguUW8odCxwLnopW3FdCmlmKG89PW51bGwpSC52aCgnTm8gIicrcSsnIiBp
-biAiJytILm1EKHApKyciJykKZC5wdXNoKEguY0UodCxwLG8pKX1lbHNlIGQucHVzaChxKQpyZXR1cm4g
-bn0sCkkzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5wb3AoKQppZigwPT09dCl7Yi5wdXNoKEgubVooYS51
-LDEsIjAmIikpCnJldHVybn1pZigxPT09dCl7Yi5wdXNoKEgubVooYS51LDQsIjEmIikpCnJldHVybn10
-aHJvdyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILmQodCkpKX0sCktR
-OmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguUTIoYSxjLGEuc0VB
-KQplbHNlIGlmKHR5cGVvZiBjPT0ibnVtYmVyIilyZXR1cm4gSC5UVihhLGIsYykKZWxzZSByZXR1cm4g
-Y30sCnJUOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWMubGVuZ3RoCmZvcih0PTA7dDxzOysrdCljW3Rd
-PUguS1EoYSxiLGNbdF0pfSwKV1M6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9
-MTt0PHM7dCs9MiljW3RdPUguS1EoYSxiLGNbdF0pfSwKVFY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cj1iLnkKaWYocj09PTEwKXtpZihjPT09MClyZXR1cm4gYi56CnQ9Yi5RCnM9dC5sZW5ndGgKaWYoYzw9
-cylyZXR1cm4gdFtjLTFdCmMtPXMKYj1iLnoKcj1iLnl9ZWxzZSBpZihjPT09MClyZXR1cm4gYgppZihy
-IT09OSl0aHJvdyBILmIoUC5oVigiSW5kZXhlZCBiYXNlIG11c3QgYmUgYW4gaW50ZXJmYWNlIHR5cGUi
-KSkKdD1iLlEKaWYoYzw9dC5sZW5ndGgpcmV0dXJuIHRbYy0xXQp0aHJvdyBILmIoUC5oVigiQmFkIGlu
-ZGV4ICIrYysiIGZvciAiK2IuWigwKSkpfSwKV2U6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIs
-cSxwLG8sbixtLGwsawppZihiPT09ZClyZXR1cm4hMAppZihILkE4KGQpfHxkPT09dS5LKXJldHVybiEw
-CnQ9Yi55CmlmKHQ9PT00KXJldHVybiEwCmlmKEguQTgoYikpcmV0dXJuITEKaWYoYj09PXUuUClyZXR1
-cm4hMApzPXQ9PT0xMwppZihzKWlmKEguV2UoYSxjW2Iuel0sYyxkLGUpKXJldHVybiEwCnI9ZC55Cmlm
-KHQ9PT02KXJldHVybiBILldlKGEsYi56LGMsZCxlKQppZihyPT09Nil7cT1kLnoKcmV0dXJuIEguV2Uo
-YSxiLGMscSxlKX1pZih0PT09OCl7aWYoIUguV2UoYSxiLnosYyxkLGUpKXJldHVybiExCnJldHVybiBI
-LldlKGEsSC54WihhLGIpLGMsZCxlKX1pZih0PT09Nyl7cT1ILldlKGEsYi56LGMsZCxlKQpyZXR1cm4g
-cX1pZihyPT09OCl7aWYoSC5XZShhLGIsYyxkLnosZSkpcmV0dXJuITAKcmV0dXJuIEguV2UoYSxiLGMs
-SC54WihhLGQpLGUpfWlmKHI9PT03KXtxPUguV2UoYSxiLGMsZC56LGUpCnJldHVybiBxfWlmKHMpcmV0
-dXJuITEKcT10IT09MTEKaWYoKCFxfHx0PT09MTIpJiZkPT09dS5aKXJldHVybiEwCmlmKHI9PT0xMil7
-aWYoYj09PXUuZylyZXR1cm4hMAppZih0IT09MTIpcmV0dXJuITEKcD1iLlEKbz1kLlEKbj1wLmxlbmd0
-aAppZihuIT09by5sZW5ndGgpcmV0dXJuITEKYz1jPT1udWxsP3A6cC5jb25jYXQoYykKZT1lPT1udWxs
-P286by5jb25jYXQoZSkKZm9yKHE9dS5hdixtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQpxLmEobCkK
-cS5hKGspCmlmKCFILldlKGEsbCxjLGssZSl8fCFILldlKGEsayxlLGwsYykpcmV0dXJuITF9cmV0dXJu
-IEguYk8oYSxiLnosYyxkLnosZSl9aWYocj09PTExKXtpZihiPT09dS5nKXJldHVybiEwCmlmKHEpcmV0
-dXJuITEKcmV0dXJuIEguYk8oYSxiLGMsZCxlKX1pZih0PT09OSl7aWYociE9PTkpcmV0dXJuITEKcmV0
-dXJuIEgucEcoYSxiLGMsZCxlKX1yZXR1cm4hMX0sCmJPOmZ1bmN0aW9uKGEwLGExLGEyLGEzLGE0KXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYixhCmlmKCFILldlKGEwLGExLnos
-YTIsYTMueixhNCkpcmV0dXJuITEKdD1hMS5RCnM9YTMuUQpyPXQuYQpxPXMuYQpwPXIubGVuZ3RoCm89
-cS5sZW5ndGgKaWYocD5vKXJldHVybiExCm49by1wCm09dC5iCmw9cy5iCms9bS5sZW5ndGgKaj1sLmxl
-bmd0aAppZihwK2s8bytqKXJldHVybiExCmZvcihpPTA7aTxwOysraSl7aD1yW2ldCmlmKCFILldlKGEw
-LHFbaV0sYTQsaCxhMikpcmV0dXJuITF9Zm9yKGk9MDtpPG47KytpKXtoPW1baV0KaWYoIUguV2UoYTAs
-cVtwK2ldLGE0LGgsYTIpKXJldHVybiExfWZvcihpPTA7aTxqOysraSl7aD1tW24raV0KaWYoIUguV2Uo
-YTAsbFtpXSxhNCxoLGEyKSlyZXR1cm4hMX1nPXQuYwpmPXMuYwplPWcubGVuZ3RoCmQ9Zi5sZW5ndGgK
-Zm9yKGk9MCxjPTA7YzxkO2MrPTIpe2I9ZltjXQpkb3tpZihpPj1lKXJldHVybiExCmE9Z1tpXQppKz0y
-fXdoaWxlKGE8YikKaWYoYjxhKXJldHVybiExCmg9Z1tpLTFdCmlmKCFILldlKGEwLGZbYysxXSxhNCxo
-LGEyKSlyZXR1cm4hMX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEs
-cCxvLG4sbSxsPWIueixrPWQuegppZihsPT09ayl7dD1iLlEKcz1kLlEKcj10Lmxlbmd0aApmb3IocT0w
-O3E8cjsrK3Epe3A9dFtxXQpvPXNbcV0KaWYoIUguV2UoYSxwLGMsbyxlKSlyZXR1cm4hMX1yZXR1cm4h
-MH1pZihkPT09dS5LKXJldHVybiEwCm49SC5RbyhhLGwpCmlmKG49PW51bGwpcmV0dXJuITEKbT1uW2td
-CmlmKG09PW51bGwpcmV0dXJuITEKcj1tLmxlbmd0aApzPWQuUQpmb3IocT0wO3E8cjsrK3EpaWYoIUgu
-V2UoYSxILmNFKGEsYixtW3FdKSxjLHNbcV0sZSkpcmV0dXJuITEKcmV0dXJuITB9LApsUjpmdW5jdGlv
-bihhKXt2YXIgdCxzPWEueQppZighKGE9PT11LlApKWlmKCFILkE4KGEpKWlmKHMhPT03KWlmKCEocz09
-PTYmJkgubFIoYS56KSkpdD1zPT09OCYmSC5sUihhLnopCmVsc2UgdD0hMAplbHNlIHQ9ITAKZWxzZSB0
-PSEwCmVsc2UgdD0hMApyZXR1cm4gdH0sCmNjOmZ1bmN0aW9uKGEpe3JldHVybiBILkE4KGEpfHxhPT09
-dS5LfSwKQTg6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLnkscj1zCmlmKHIhPT0yKWlmKHIhPT0zKWlmKHIh
-PT00KWlmKHIhPT01KXt0PXUuSwppZighKGE9PT10KSlzPXM9PT03JiZhLno9PT10CmVsc2Ugcz0hMH1l
-bHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMAplbHNlIHM9ITAKcmV0dXJuIHN9LApJeDpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMscj1PYmplY3Qua2V5cyhiKSxxPXIubGVuZ3RoCmZvcih0PTA7dDxxOysrdCl7
-cz1yW3RdCmFbc109YltzXX19LApKYzpmdW5jdGlvbiBKYyhhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
-PWIKXy54PV8ucj1fLmM9bnVsbApfLnk9MApfLmN5PV8uY3g9Xy5jaD1fLlE9Xy56PW51bGx9LApFVDpm
-dW5jdGlvbiBFVCgpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlvbiB1OSgpe30s
-Cng6ZnVuY3Rpb24geChhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB1LmQuYihhKXx8
-dS5CLmIoYSl8fHUuZHouYihhKXx8dS5JLmIoYSl8fHUuQS5iKGEpfHx1Lmc0LmIoYSl8fHUuZzIuYihh
-KX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9ewpRdTpm
-dW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHA9YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihwPT1udWxsKWlmKCQuSz09bnVs
-bCl7SC5NKCkKcD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCEx
-PT09dClyZXR1cm4gcC5pCmlmKCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihh
-KQppZih0PT09cylyZXR1cm4gcC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAubigiUmV0dXJuIGludGVy
-Y2VwdG9yIGZvciAiK0guZCh0KGEscCkpKSl9cj1hLmNvbnN0cnVjdG9yCnE9cj09bnVsbD9udWxsOnJb
-JC5BKCldCmlmKHEhPW51bGwpcmV0dXJuIHEKcT1ILkcoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0
-eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQpp
-Zih0PT1udWxsKXJldHVybiBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlm
-KHR5cGVvZiByPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLkEoKSx7dmFsdWU6
-Qy52QixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1
-cm4gQy52Qn1yZXR1cm4gQy52Qn0sClFpOmZ1bmN0aW9uKGEsYil7aWYoYTwwfHxhPjQyOTQ5NjcyOTUp
-dGhyb3cgSC5iKFAuVEUoYSwwLDQyOTQ5NjcyOTUsImxlbmd0aCIsbnVsbCkpCnJldHVybiBKLnB5KG5l
-dyBBcnJheShhKSxiKX0sCnB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouRXAoSC5WTShhLGIuQygiamQ8
-MD4iKSkpfSwKRXA6ZnVuY3Rpb24oYSl7YS5maXhlZCRsZW5ndGg9QXJyYXkKcmV0dXJuIGF9LAp1bjpm
-dW5jdGlvbihhKXthLmZpeGVkJGxlbmd0aD1BcnJheQphLmltbXV0YWJsZSRsaXN0PUFycmF5CnJldHVy
-biBhfSwKR2E6ZnVuY3Rpb24oYSl7aWYoYTwyNTYpc3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDEwOmNhc2Ug
-MTE6Y2FzZSAxMjpjYXNlIDEzOmNhc2UgMzI6Y2FzZSAxMzM6Y2FzZSAxNjA6cmV0dXJuITAKZGVmYXVs
-dDpyZXR1cm4hMX1zd2l0Y2goYSl7Y2FzZSA1NzYwOmNhc2UgODE5MjpjYXNlIDgxOTM6Y2FzZSA4MTk0
-OmNhc2UgODE5NTpjYXNlIDgxOTY6Y2FzZSA4MTk3OmNhc2UgODE5ODpjYXNlIDgxOTk6Y2FzZSA4MjAw
-OmNhc2UgODIwMTpjYXNlIDgyMDI6Y2FzZSA4MjMyOmNhc2UgODIzMzpjYXNlIDgyMzk6Y2FzZSA4Mjg3
-OmNhc2UgMTIyODg6Y2FzZSA2NTI3OTpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfX0sCm1tOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscwpmb3IodD1hLmxlbmd0aDtiPHQ7KXtzPUMueEIuVyhhLGIpCmlmKHMhPT0z
-MiYmcyE9PTEzJiYhSi5HYShzKSlicmVhazsrK2J9cmV0dXJuIGJ9LApjMTpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMKZm9yKDtiPjA7Yj10KXt0PWItMQpzPUMueEIubShhLHQpCmlmKHMhPT0zMiYmcyE9PTEzJiYh
-Si5HYShzKSlicmVha31yZXR1cm4gYn0sClJFOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEK
-aWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5w
-cm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3Mo
-YSl9LApUSjpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJvdG90
-eXBlCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbCly
-ZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlw
-ZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5
-cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApV
-NjpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlm
-KGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90
-eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEou
-YzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBK
-LmtzKGEpfSwKaWE6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29y
-KGEpPT1hKXJldHVybiBKLnVyLnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9m
-IGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLllFLnBy
-b3RvdHlwZQppZih0eXBlb2YgYT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNv
-bnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3Qi
-KXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYo
-YSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtp
-Zih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJu
-IGEKaWYoIShhIGluc3RhbmNlb2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwK
-dzE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSly
-ZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1
-bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgp
-cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApBYzpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5aKGEp
-fSwKQ006ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouUkUoYSkuZHUoYSxiLGMsZCl9LApGTDpmdW5j
-dGlvbihhLGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVybiBK
-LncxKGEpLkUoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdtVyhhKX0sCkg6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIEouVTYoYSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShh
-KS5na3ooYSl9LApKeTpmdW5jdGlvbihhLGIpe3JldHVybiBKLmlhKGEpLmU3KGEsYil9LApLVjpmdW5j
-dGlvbihhLGIpe3JldHVybiBKLnJZKGEpLkcoYSxiKX0sCkx0OmZ1bmN0aW9uKGEpe3JldHVybiBKLlJF
-KGEpLndnKGEpfSwKTTE6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLkUyKGEsYixjKX0sClF6
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVyhhLGIpfSwKUk06ZnVuY3Rpb24oYSxiKXtpZihh
-PT1udWxsKXJldHVybiBiPT1udWxsCmlmKHR5cGVvZiBhIT0ib2JqZWN0IilyZXR1cm4gYiE9bnVsbCYm
-YT09PWIKcmV0dXJuIEouaWEoYSkuRE4oYSxiKX0sClQwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnJZKGEp
-LmJTKGEpfSwKYTY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5tKGEsYil9LApiVDpmdW5jdGlv
-bihhKXtyZXR1cm4gSi5SRShhKS5ENChhKX0sCmNIOmZ1bmN0aW9uKGEpe3JldHVybiBKLnJZKGEpLmhj
-KGEpfSwKZFI6ZnVuY3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuZ0QoYSl9LApkWjpmdW5jdGlvbihhLGIs
-YyxkKXtyZXR1cm4gSi5SRShhKS5PbihhLGIsYyxkKX0sCmRnOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVy
-biBKLnJZKGEpLmk3KGEsYixjLGQpfSwKZGg6ZnVuY3Rpb24oYSl7cmV0dXJuIEouUkUoYSkudG4oYSl9
-LApoZjpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9LAppZzpmdW5jdGlvbihhKXtyZXR1
-cm4gSi5SRShhKS5nUWcoYSl9LApsNTpmdW5jdGlvbihhLGIpe3JldHVybiBKLlJFKGEpLnNoZihhLGIp
-fSwKbGQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnJZKGEpLncoYSxiLGMpfSwKbTpmdW5jdGlvbihh
-LGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmdHlwZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0
-dXJuIEouVEooYSkuaChhLGIpfSwKcDQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5UYyhhLGIp
-fSwKcTA6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnJZKGEpLlFpKGEsYixjKX0sCnFGOmZ1bmN0aW9u
-KGEpe3JldHVybiBKLlJFKGEpLmdWbChhKX0sCnRIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5SRShh
-KS5wayhhLGIsYyl9LAp4OTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiPT09Im51bWJlciIpaWYoYS5j
-b25zdHJ1Y3Rvcj09QXJyYXl8fHR5cGVvZiBhPT0ic3RyaW5nInx8SC53VihhLGFbdi5kaXNwYXRjaFBy
-b3BlcnR5TmFtZV0pKWlmKGI+Pj4wPT09YiYmYjxhLmxlbmd0aClyZXR1cm4gYVtiXQpyZXR1cm4gSi5V
-NihhKS5xKGEsYil9LAp6bDpmdW5jdGlvbihhLGIpe3JldHVybiBKLlU2KGEpLnRnKGEsYil9LAp2Qjpm
-dW5jdGlvbiB2Qigpe30sCnlFOmZ1bmN0aW9uIHlFKCl7fSwKWUU6ZnVuY3Rpb24gWUUoKXt9LApNRjpm
-dW5jdGlvbiBNRigpe30sCmlDOmZ1bmN0aW9uIGlDKCl7fSwKa2Q6ZnVuY3Rpb24ga2QoKXt9LApjNTpm
-dW5jdGlvbiBjNSgpe30sCmpkOmZ1bmN0aW9uIGpkKGEpe3RoaXMuJHRpPWF9LApQbzpmdW5jdGlvbiBQ
-byhhKXt0aGlzLiR0aT1hfSwKbTE6ZnVuY3Rpb24gbTEoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
-PWIKXy5jPTAKXy5kPW51bGwKXy4kdGk9Y30sCnFJOmZ1bmN0aW9uIHFJKCl7fSwKdXI6ZnVuY3Rpb24g
-dXIoKXt9LApWQTpmdW5jdGlvbiBWQSgpe30sCkRyOmZ1bmN0aW9uIERyKCl7fX0sUD17Ck9qOmZ1bmN0
-aW9uKCl7dmFyIHQscyxyPXt9CmlmKHNlbGYuc2NoZWR1bGVJbW1lZGlhdGUhPW51bGwpcmV0dXJuIFAu
-RVgoKQppZihzZWxmLk11dGF0aW9uT2JzZXJ2ZXIhPW51bGwmJnNlbGYuZG9jdW1lbnQhPW51bGwpe3Q9
-c2VsZi5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKQpzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxl
-bWVudCgic3BhbiIpCnIuYT1udWxsCm5ldyBzZWxmLk11dGF0aW9uT2JzZXJ2ZXIoSC50UihuZXcgUC50
-aChyKSwxKSkub2JzZXJ2ZSh0LHtjaGlsZExpc3Q6dHJ1ZX0pCnJldHVybiBuZXcgUC5oYShyLHQscyl9
-ZWxzZSBpZihzZWxmLnNldEltbWVkaWF0ZSE9bnVsbClyZXR1cm4gUC55dCgpCnJldHVybiBQLnFXKCl9
-LApaVjpmdW5jdGlvbihhKXtzZWxmLnNjaGVkdWxlSW1tZWRpYXRlKEgudFIobmV3IFAuVnModS5NLmEo
-YSkpLDApKX0sCm9BOmZ1bmN0aW9uKGEpe3NlbGYuc2V0SW1tZWRpYXRlKEgudFIobmV3IFAuRnQodS5N
-LmEoYSkpLDApKX0sCkJ6OmZ1bmN0aW9uKGEpe3UuTS5hKGEpClAuUU4oMCxhKX0sClFOOmZ1bmN0aW9u
-KGEsYil7dmFyIHQ9bmV3IFAuVzMoKQp0LkNZKGEsYikKcmV0dXJuIHR9LApGWDpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IFAuaWgobmV3IFAudnMoJC5YMyxhLkMoInZzPDA+IikpLGEuQygiaWg8MD4iKSl9LApE
-STpmdW5jdGlvbihhLGIpe2EuJDIoMCxudWxsKQpiLmI9ITAKcmV0dXJuIGIuYX0sCmpROmZ1bmN0aW9u
-KGEsYil7UC5KZShhLGIpfSwKeUM6ZnVuY3Rpb24oYSxiKXtiLmFNKDAsYSl9LApmMzpmdW5jdGlvbihh
-LGIpe2IudzAoSC5SdShhKSxILnRzKGEpKX0sCkplOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPW5ldyBQ
-LldNKGIpLHE9bmV3IFAuU1goYikKaWYoYSBpbnN0YW5jZW9mIFAudnMpYS5RZChyLHEsdS56KQplbHNl
-e3Q9dS56CmlmKHUuYy5iKGEpKWEuU3EocixxLHQpCmVsc2V7cz1uZXcgUC52cygkLlgzLHUuXykKcy5h
-PTQKcy5jPWEKcy5RZChyLHEsdCl9fX0sCmx6OmZ1bmN0aW9uKGEpe3ZhciB0PWZ1bmN0aW9uKGIsYyl7
-cmV0dXJuIGZ1bmN0aW9uKGQsZSl7d2hpbGUodHJ1ZSl0cnl7YihkLGUpCmJyZWFrfWNhdGNoKHMpe2U9
-cwpkPWN9fX0oYSwxKQpyZXR1cm4gJC5YMy5MaihuZXcgUC5Hcyh0KSx1LlAsdS5TLHUueil9LApHUTpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRnkoYSwxKX0sClRoOmZ1bmN0aW9uKCl7cmV0dXJuIEMud1F9
-LApZbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRnkoYSwzKX0sCmwwOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIG5ldyBQLnE0KGEsYi5DKCJxNDwwPiIpKX0sCmszOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmIu
-YT0xCnRyeXthLlNxKG5ldyBQLnBWKGIpLG5ldyBQLlU3KGIpLHUuUCl9Y2F0Y2gocil7dD1ILlJ1KHIp
-CnM9SC50cyhyKQpQLnJiKG5ldyBQLnZyKGIsdCxzKSl9fSwKQTk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-LHIKZm9yKHQ9dS5fO3M9YS5hLHM9PT0yOylhPXQuYShhLmMpCmlmKHM+PTQpe3I9Yi5haCgpCmIuYT1h
-LmEKYi5jPWEuYwpQLkhaKGIscil9ZWxzZXtyPXUueC5hKGIuYykKYi5hPTIKYi5jPWEKYS5qUShyKX19
-LApIWjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPW51bGws
-ZD17fSxjPWQuYT1hCmZvcih0PXUubixzPXUueCxyPXUuYzshMDspe3E9e30KcD1jLmE9PT04CmlmKGI9
-PW51bGwpe2lmKHApe289dC5hKGMuYykKUC5MMihlLGUsYy5iLG8uYSxvLmIpfXJldHVybn1mb3IoO249
-Yi5hLG4hPW51bGw7Yj1uKXtiLmE9bnVsbApQLkhaKGQuYSxiKX1jPWQuYQptPWMuYwpxLmE9cApxLmI9
-bQpsPSFwCmlmKGwpe2s9Yi5jCms9KGsmMSkhPT0wfHwoayYxNSk9PT04fWVsc2Ugaz0hMAppZihrKXtr
-PWIuYgpqPWsuYgppZihwKXtpPWMuYj09PWoKaT0hKGl8fGkpfWVsc2UgaT0hMQppZihpKXt0LmEobSkK
-UC5MMihlLGUsYy5iLG0uYSxtLmIpCnJldHVybn1oPSQuWDMKaWYoaCE9PWopJC5YMz1qCmVsc2UgaD1l
-CmM9Yi5jCmlmKChjJjE1KT09PTgpbmV3IFAuUlQoZCxxLGIscCkuJDAoKQplbHNlIGlmKGwpe2lmKChj
-JjEpIT09MCluZXcgUC5ycShxLGIsbSkuJDAoKX1lbHNlIGlmKChjJjIpIT09MCluZXcgUC5SVyhkLHEs
-YikuJDAoKQppZihoIT1udWxsKSQuWDM9aApjPXEuYgppZihyLmIoYykpe2lmKGMuYT49NCl7Zz1zLmEo
-ay5jKQprLmM9bnVsbApiPWsuTjgoZykKay5hPWMuYQprLmM9Yy5jCmQuYT1jCmNvbnRpbnVlfWVsc2Ug
-UC5BOShjLGspCnJldHVybn19Zj1iLmIKZz1zLmEoZi5jKQpmLmM9bnVsbApiPWYuTjgoZykKYz1xLmEK
-bD1xLmIKaWYoIWMpe2YuJHRpLmMuYShsKQpmLmE9NApmLmM9bH1lbHNle3QuYShsKQpmLmE9OApmLmM9
-bH1kLmE9ZgpjPWZ9fSwKVkg6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZih1LmFnLmIoYSkpcmV0dXJuIGIu
-TGooYSx1LnosdS5LLHUubCkKdD11LkYKaWYodC5iKGEpKXJldHVybiB0LmEoYSkKdGhyb3cgSC5iKFAu
-TDMoYSwib25FcnJvciIsIkVycm9yIGhhbmRsZXIgbXVzdCBhY2NlcHQgb25lIE9iamVjdCBvciBvbmUg
-T2JqZWN0IGFuZCBhIFN0YWNrVHJhY2UgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJuIGEgYSB2YWxpZCBy
-ZXN1bHQiKSl9LApwdTpmdW5jdGlvbigpe3ZhciB0LHMKZm9yKDt0PSQuUzYsdCE9bnVsbDspeyQubWc9
-bnVsbApzPXQuYgokLlM2PXMKaWYocz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rp
-b24oKXskLlVEPSEwCnRyeXtQLnB1KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1u
-dWxsKSQudXQoKS4kMShQLlY5KCkpfX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpCmlm
-KCQuUzY9PW51bGwpeyQuUzY9JC5rOD10CmlmKCEkLlVEKSQudXQoKS4kMShQLlY5KCkpfWVsc2UgJC5r
-OD0kLms4LmI9dH0sCnJSOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj0kLlM2CmlmKHI9PW51bGwpe1AuZVco
-YSkKJC5tZz0kLms4CnJldHVybn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cgok
-LlM2PSQubWc9dH1lbHNle3QuYj1zLmIKJC5tZz1zLmI9dAppZih0LmI9PW51bGwpJC5rOD10fX0sCnJi
-OmZ1bmN0aW9uKGEpe3ZhciB0PW51bGwscz0kLlgzCmlmKEMuTlU9PT1zKXtQLlRrKHQsdCxDLk5VLGEp
-CnJldHVybn1QLlRrKHQsdCxzLHUuTS5hKHMuR1koYSkpKX0sClF3OmZ1bmN0aW9uKGEsYil7aWYoYT09
-bnVsbClILnZoKFAuRWUoInN0cmVhbSIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sClRs
-OmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yj09bnVsbD9QLnYwKGEpOmIKUC5VSShhLCJlcnJvciIsdS5LKQpy
-ZXR1cm4gbmV3IFAuT0goYSx0KX0sCnYwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuVy5iKGEpKXt0PWEu
-Z0lJKCkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQs
-ZSl7dmFyIHQ9e30KdC5hPWQKdC5iPWUKaWYoZD09bnVsbCl7dC5hPW5ldyBQLkFUKCExLG51bGwsImVy
-cm9yIiwiTXVzdCBub3QgYmUgbnVsbCIpCnQuYj1QLlpiKCl9UC5yUihuZXcgUC5wSyh0KSl9LApUODpm
-dW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHM9JC5YMwppZihzPT09YylyZXR1cm4gZC4kMCgpCiQuWDM9
-Ywp0PXMKdHJ5e3M9ZC4kMCgpCnJldHVybiBzfWZpbmFsbHl7JC5YMz10fX0sCnl2OmZ1bmN0aW9uKGEs
-YixjLGQsZSxmLGcpe3ZhciB0LHM9JC5YMwppZihzPT09YylyZXR1cm4gZC4kMShlKQokLlgzPWMKdD1z
-CnRyeXtzPWQuJDEoZSkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKUXg6ZnVuY3Rpb24oYSxiLGMs
-ZCxlLGYsZyxoLGkpe3ZhciB0LHM9JC5YMwppZihzPT09YylyZXR1cm4gZC4kMihlLGYpCiQuWDM9Ywp0
-PXMKdHJ5e3M9ZC4kMihlLGYpCnJldHVybiBzfWZpbmFsbHl7JC5YMz10fX0sClRrOmZ1bmN0aW9uKGEs
-YixjLGQpe3ZhciB0CnUuTS5hKGQpCnQ9Qy5OVSE9PWMKaWYodClkPSEoIXR8fCExKT9jLkdZKGQpOmMu
-UlQoZCx1LkgpClAuZVcoZCl9LAp0aDpmdW5jdGlvbiB0aChhKXt0aGlzLmE9YX0sCmhhOmZ1bmN0aW9u
-IGhhKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClZzOmZ1bmN0aW9uIFZzKGEpe3Ro
-aXMuYT1hfSwKRnQ6ZnVuY3Rpb24gRnQoYSl7dGhpcy5hPWF9LApXMzpmdW5jdGlvbiBXMygpe30sCnlI
-OmZ1bmN0aW9uIHlIKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAppaDpmdW5jdGlvbiBpaChhLGIpe3Ro
-aXMuYT1hCnRoaXMuYj0hMQp0aGlzLiR0aT1ifSwKV006ZnVuY3Rpb24gV00oYSl7dGhpcy5hPWF9LApT
-WDpmdW5jdGlvbiBTWChhKXt0aGlzLmE9YX0sCkdzOmZ1bmN0aW9uIEdzKGEpe3RoaXMuYT1hfSwKRnk6
-ZnVuY3Rpb24gRnkoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkdWOmZ1bmN0aW9uIEdWKGEsYil7dmFy
-IF89dGhpcwpfLmE9YQpfLmQ9Xy5jPV8uYj1udWxsCl8uJHRpPWJ9LApxNDpmdW5jdGlvbiBxNChhLGIp
-e3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApiODpmdW5jdGlvbiBiOCgpe30sClBmOmZ1bmN0aW9uIFBmKCl7
-fSwKWmY6ZnVuY3Rpb24gWmYoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKRmU6ZnVuY3Rpb24gRmUo
-YSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRp
-PWV9LAp2czpmdW5jdGlvbiB2cyhhLGIpe3ZhciBfPXRoaXMKXy5hPTAKXy5iPWEKXy5jPW51bGwKXy4k
-dGk9Yn0sCmRhOmZ1bmN0aW9uIGRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApvUTpmdW5jdGlvbiBv
-UShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKcFY6ZnVuY3Rpb24gcFYoYSl7dGhpcy5hPWF9LApVNzpm
-dW5jdGlvbiBVNyhhKXt0aGlzLmE9YX0sCnZyOmZ1bmN0aW9uIHZyKGEsYixjKXt0aGlzLmE9YQp0aGlz
-LmI9Ygp0aGlzLmM9Y30sCnJIOmZ1bmN0aW9uIHJIKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLRjpm
-dW5jdGlvbiBLRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWkw6ZnVuY3Rpb24gWkwoYSxiLGMpe3Ro
-aXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUlQ6ZnVuY3Rpb24gUlQoYSxiLGMsZCl7dmFyIF89dGhp
-cwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmpaOmZ1bmN0aW9uIGpaKGEpe3RoaXMuYT1hfSwKcnE6
-ZnVuY3Rpb24gcnEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUlc6ZnVuY3Rpb24g
-UlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKT006ZnVuY3Rpb24gT00oYSl7dGhp
-cy5hPWEKdGhpcy5iPW51bGx9LApxaDpmdW5jdGlvbiBxaCgpe30sCkI1OmZ1bmN0aW9uIEI1KGEsYil7
-dGhpcy5hPWEKdGhpcy5iPWJ9LApQSTpmdW5jdGlvbiBQSShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-TU86ZnVuY3Rpb24gTU8oKXt9LAprVDpmdW5jdGlvbiBrVCgpe30sCnhJOmZ1bmN0aW9uIHhJKGEpe3Ro
-aXMuJHRpPWF9LApPSDpmdW5jdGlvbiBPSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKbTA6ZnVuY3Rp
-b24gbTAoKXt9LApwSzpmdW5jdGlvbiBwSyhhKXt0aGlzLmE9YX0sCkppOmZ1bmN0aW9uIEppKCl7fSwK
-aGo6ZnVuY3Rpb24gaGooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnA6ZnVuY3Rp
-b24gVnAoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9SOmZ1bmN0aW9uIE9SKGEsYixjKXt0aGlzLmE9
-YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVGOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gYi5DKCJAPDA+Iiku
-S3EoYykuQygiRm88MSwyPiIpLmEoSC5CNyhhLG5ldyBILk41KGIuQygiQDwwPiIpLktxKGMpLkMoIk41
-PDEsMj4iKSkpKX0sCkZsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILk41KGEuQygiQDwwPiIpLktx
-KGIpLkMoIk41PDEsMj4iKSl9LApMczpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuYjYoYS5DKCJiNjww
-PiIpKX0sClQyOmZ1bmN0aW9uKCl7dmFyIHQ9T2JqZWN0LmNyZWF0ZShudWxsKQp0WyI8bm9uLWlkZW50
-aWZpZXIta2V5PiJdPXQKZGVsZXRlIHRbIjxub24taWRlbnRpZmllci1rZXk+Il0KcmV0dXJuIHR9LApy
-ajpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9bmV3IFAubG0oYSxiLGMuQygibG08MD4iKSkKdC5jPWEuZQpy
-ZXR1cm4gdH0sCkVQOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKFAuaEIoYSkpe2lmKGI9PT0iKCIm
-JmM9PT0iKSIpcmV0dXJuIiguLi4pIgpyZXR1cm4gYisiLi4uIitjfXQ9SC5WTShbXSx1LnMpCkMuTm0u
-aSgkLnhnLGEpCnRyeXtQLlZyKGEsdCl9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5r
-KCQueGcsLTEpCiQueGcucG9wKCl9cz1QLnZnKGIsdS5SLmEodCksIiwgIikrYwpyZXR1cm4gcy5jaGFy
-Q29kZUF0KDApPT0wP3M6c30sCldFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKFAuaEIoYSkpcmV0
-dXJuIGIrIi4uLiIrYwp0PW5ldyBQLlJuKGIpCkMuTm0uaSgkLnhnLGEpCnRyeXtzPXQKcy5hPVAudmco
-cy5hLGEsIiwgIil9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5rKCQueGcsLTEpCiQu
-eGcucG9wKCl9dC5hKz1jCnM9dC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKaEI6ZnVu
-Y3Rpb24oYSl7dmFyIHQscwpmb3IodD0kLnhnLmxlbmd0aCxzPTA7czx0OysrcylpZihhPT09JC54Z1tz
-XSlyZXR1cm4hMApyZXR1cm4hMX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbT1h
-LmdreihhKSxsPTAsaz0wCndoaWxlKCEwKXtpZighKGw8ODB8fGs8MykpYnJlYWsKaWYoIW0uRigpKXJl
-dHVybgp0PUguZChtLmdsKCkpCkMuTm0uaShiLHQpCmwrPXQubGVuZ3RoKzI7KytrfWlmKCFtLkYoKSl7
-aWYoazw9NSlyZXR1cm4KaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguayhiLC0xKQpzPWIucG9wKCkKaWYo
-MD49Yi5sZW5ndGgpcmV0dXJuIEguayhiLC0xKQpyPWIucG9wKCl9ZWxzZXtxPW0uZ2woKTsrK2sKaWYo
-IW0uRigpKXtpZihrPD00KXtDLk5tLmkoYixILmQocSkpCnJldHVybn1zPUguZChxKQppZigwPj1iLmxl
-bmd0aClyZXR1cm4gSC5rKGIsLTEpCnI9Yi5wb3AoKQpsKz1zLmxlbmd0aCsyfWVsc2V7cD1tLmdsKCk7
-KytrCmZvcig7bS5GKCk7cT1wLHA9byl7bz1tLmdsKCk7KytrCmlmKGs+MTAwKXt3aGlsZSghMCl7aWYo
-IShsPjc1JiZrPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILmsoYiwtMSkKbC09Yi5wb3Ao
-KS5sZW5ndGgrMjstLWt9Qy5ObS5pKGIsIi4uLiIpCnJldHVybn19cj1ILmQocSkKcz1ILmQocCkKbCs9
-cy5sZW5ndGgrci5sZW5ndGgrNH19aWYoaz5iLmxlbmd0aCsyKXtsKz01Cm49Ii4uLiJ9ZWxzZSBuPW51
-bGwKd2hpbGUoITApe2lmKCEobD44MCYmYi5sZW5ndGg+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0
-dXJuIEguayhiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyCmlmKG49PW51bGwpe2wrPTUKbj0iLi4uIn19
-aWYobiE9bnVsbClDLk5tLmkoYixuKQpDLk5tLmkoYixyKQpDLk5tLmkoYixzKX0sCnRNOmZ1bmN0aW9u
-KGEsYil7dmFyIHQscyxyPVAuTHMoYikKZm9yKHQ9YS5sZW5ndGgscz0wO3M8YS5sZW5ndGg7YS5sZW5n
-dGg9PT10fHwoMCxILmxrKShhKSwrK3Mpci5pKDAsYi5hKGFbc10pKQpyZXR1cm4gcn0sCm5POmZ1bmN0
-aW9uKGEpe3ZhciB0LHM9e30KaWYoUC5oQihhKSlyZXR1cm4iey4uLn0iCnQ9bmV3IFAuUm4oIiIpCnRy
-eXtDLk5tLmkoJC54ZyxhKQp0LmErPSJ7IgpzLmE9ITAKYS5LKDAsbmV3IFAucmEocyx0KSkKdC5hKz0i
-fSJ9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5rKCQueGcsLTEpCiQueGcucG9wKCl9
-cz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApiNjpmdW5jdGlvbiBiNihhKXt2YXIg
-Xz10aGlzCl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKYm46ZnVu
-Y3Rpb24gYm4oYSl7dGhpcy5hPWEKdGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24gbG0oYSxi
-LGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpmdW5jdGlv
-biBtVygpe30sCkxVOmZ1bmN0aW9uIExVKCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpmdW5jdGlv
-biBpbCgpe30sCnJhOmZ1bmN0aW9uIHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpmdW5jdGlv
-biBZaygpe30sCnlROmZ1bmN0aW9uIHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1AoKXt9LApQ
-bjpmdW5jdGlvbiBQbigpe30sCkdqOmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0s
-Ck1hOmZ1bmN0aW9uIE1hKCl7fSwKVmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBYdigpe30s
-Cm5ZOmZ1bmN0aW9uIG5ZKCl7fSwKVEM6ZnVuY3Rpb24gVEMoKXt9LApSVTpmdW5jdGlvbiBSVSgpe30s
-CkJTOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRocm93IEgu
-YihILkkoYSkpCnQ9bnVsbAp0cnl7dD1KU09OLnBhcnNlKGEpfWNhdGNoKHIpe3M9SC5SdShyKQpxPVAu
-cnIoU3RyaW5nKHMpLG51bGwsbnVsbCkKdGhyb3cgSC5iKHEpfXE9UC5RZSh0KQpyZXR1cm4gcX0sClFl
-OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYodHlwZW9mIGEhPSJvYmpl
-Y3QiKXJldHVybiBhCmlmKE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSE9PUFycmF5LnByb3RvdHlwZSly
-ZXR1cm4gbmV3IFAudXcoYSxPYmplY3QuY3JlYXRlKG51bGwpKQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0
-KWFbdF09UC5RZShhW3RdKQpyZXR1cm4gYX0sCmt5OmZ1bmN0aW9uKGEsYixjLGQpe2lmKGIgaW5zdGFu
-Y2VvZiBVaW50OEFycmF5KXJldHVybiBQLlJQKCExLGIsYyxkKQpyZXR1cm4gbnVsbH0sClJQOmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciB0LHMscj0kLnRMKCkKaWYocj09bnVsbClyZXR1cm4gbnVsbAp0PTA9PT1j
-CmlmKHQmJiEwKXJldHVybiBQLk9RKHIsYikKcz1iLmxlbmd0aApkPVAuakIoYyxkLHMpCmlmKHQmJmQ9
-PT1zKXJldHVybiBQLk9RKHIsYikKcmV0dXJuIFAuT1EocixiLnN1YmFycmF5KGMsZCkpfSwKT1E6ZnVu
-Y3Rpb24oYSxiKXtpZihQLkFqKGIpKXJldHVybiBudWxsCnJldHVybiBQLkpoKGEsYil9LApKaDpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMKdHJ5e3Q9YS5kZWNvZGUoYikKcmV0dXJuIHR9Y2F0Y2gocyl7SC5SdShz
-KX1yZXR1cm4gbnVsbH0sCkFqOmZ1bmN0aW9uKGEpe3ZhciB0LHM9YS5sZW5ndGgtMgpmb3IodD0wO3Q8
-czsrK3QpaWYoYVt0XT09PTIzNylpZigoYVt0KzFdJjIyNCk9PT0xNjApcmV0dXJuITAKcmV0dXJuITF9
-LApXSTpmdW5jdGlvbigpe3ZhciB0LHMKdHJ5e3Q9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFs
-OnRydWV9KQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVybiBudWxsfSwKY1A6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0LHMscgpmb3IodD1KLlU2KGEpLHM9YjtzPGM7KytzKXtyPXQucShhLHMpCmlmKHR5
-cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuek0oKQppZigociYxMjcpIT09cilyZXR1cm4gcy1ifXJl
-dHVybiBjLWJ9LAp4TTpmdW5jdGlvbihhLGIsYyxkLGUsZil7aWYoQy5qbi56WShmLDQpIT09MCl0aHJv
-dyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgcGFkZGVkIGxlbmd0aCBtdXN0IGJlIG11
-bHRpcGxlIG9mIGZvdXIsIGlzICIrZixhLGMpKQppZihkK2UhPT1mKXRocm93IEguYihQLnJyKCJJbnZh
-bGlkIGJhc2U2NCBwYWRkaW5nLCAnPScgbm90IGF0IHRoZSBlbmQiLGEsYikpCmlmKGU+Mil0aHJvdyBI
-LmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgbW9yZSB0aGFuIHR3byAnPScgY2hhcmFjdGVy
-cyIsYSxiKSl9LAp1dzpmdW5jdGlvbiB1dyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1udWxs
-fSwKaTg6ZnVuY3Rpb24gaTgoYSl7dGhpcy5hPWF9LApDVjpmdW5jdGlvbiBDVigpe30sClU4OmZ1bmN0
-aW9uIFU4KCl7fSwKVWs6ZnVuY3Rpb24gVWsoKXt9LAp3STpmdW5jdGlvbiB3SSgpe30sClppOmZ1bmN0
-aW9uIFppKCl7fSwKYnk6ZnVuY3Rpb24gYnkoKXt9LApNeDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0s
-CnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlvbiBSdyhhKXt0
-aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6ZnVuY3Rpb24g
-YnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0hMApfLmY9Xy5lPV8uZD0wfSwKUUE6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0PUguSHAoYSxjKQppZih0IT1udWxsKXJldHVybiB0CmlmKGIhPW51bGwp
-cmV0dXJuIGIuJDEoYSkKdGhyb3cgSC5iKFAucnIoYSxudWxsLG51bGwpKX0sCm9zOmZ1bmN0aW9uKGEp
-e2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLlooMCkKcmV0dXJuIkluc3RhbmNlIG9mICciK0gu
-ZChILmxoKGEpKSsiJyJ9LApPODpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1KLlFpKGEsYykKaWYoYSE9
-PTAmJiEwKWZvcih0PTA7dDxzLmxlbmd0aDsrK3QpQy5ObS5ZKHMsdCxiKQpyZXR1cm4gc30sCkNIOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJqZDwwPiIpKQpmb3IodD1KLklUKGEpO3Qu
-RigpOylDLk5tLmkocyxjLmEodC5nbCgpKSkKaWYoYilyZXR1cm4gcwpyZXR1cm4gYy5DKCJ6TTwwPiIp
-LmEoSi5FcChzKSl9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBiLkMoInpNPDA+IikuYShKLnVuKFAu
-Q0goYSwhMSxiKSkpfSwKSE06ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKEFycmF5LmlzQXJyYXkoYSkp
-e3UudC5hKGEpCnQ9YS5sZW5ndGgKYz1QLmpCKGIsYyx0KQpyZXR1cm4gSC5lVChiPjB8fGM8dD9DLk5t
-LkQ2KGEsYixjKTphKX1pZih1LmJtLmIoYSkpcmV0dXJuIEguZncoYSxiLFAuakIoYixjLGEubGVuZ3Ro
-KSkKcmV0dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24oYSl7cmV0dXJuIEguTHcoYSl9LApidzpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1udWxsCmlmKGI8MCl0aHJvdyBILmIoUC5URShiLDAs
-Si5IKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixKLkgoYSks
-cCxwKSkKcz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYiww
-LHIscCxwKSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVzaChzLmdsKCkpCmVsc2UgZm9yKHI9Yjty
-PGM7KytyKXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHIscCxwKSkKcS5wdXNoKHMuZ2woKSl9
-cmV0dXJuIEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEs
-ITAsITEsITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1KLklUKGIpCmlmKCF0LkYoKSly
-ZXR1cm4gYQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0LmdsKCkpCndoaWxlKHQuRigpKX1lbHNl
-e2ErPUguZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guZCh0LmdsKCkpfXJldHVybiBhfSwKbHI6
-ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2
-YXIgdD1ILk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5i
-YXNlJyBpcyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEs
-cCxvLG49IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXt0PSQuejQoKS5iCmlmKHR5cGVvZiBi
-IT0ic3RyaW5nIilILnZoKEguSShiKSkKdD10LnRlc3QoYil9ZWxzZSB0PSExCmlmKHQpcmV0dXJuIGIK
-SC5MaChjKS5DKCJVay5TIikuYShiKQpzPWMuZ1pFKCkuV0ooYikKZm9yKHQ9cy5sZW5ndGgscj0wLHE9
-IiI7cjx0Oysrcil7cD1zW3JdCmlmKHA8MTI4KXtvPXA+Pj40CmlmKG8+PTgpcmV0dXJuIEguayhhLG8p
-Cm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQplbHNlIHE9ZCYm
-cD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hhckNvZGVBdCgw
-KT09MD9xOnF9LApaYjpmdW5jdGlvbigpe3ZhciB0LHMKaWYoSC5vVCgkLnA2KCkpKXJldHVybiBILnRz
-KG5ldyBFcnJvcigpKQp0cnl7dGhyb3cgSC5iKCIiKX1jYXRjaChzKXtILlJ1KHMpCnQ9SC50cyhzKQpy
-ZXR1cm4gdH19LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8iLSI6IiIKaWYo
-dD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0xMClyZXR1cm4g
-cysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMClyZXR1cm4i
-IithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEpe2lmKGE+
-PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApoOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVt
-YmVyInx8SC5yUShhKXx8bnVsbD09YSlyZXR1cm4gSi5BYyhhKQppZih0eXBlb2YgYT09InN0cmluZyIp
-cmV0dXJuIEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLm9zKGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0
-dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsbnVs
-bCxhKX0sCkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuQVQoITAsYSxiLGMpfSwKRWU6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsYSwiTXVzdCBub3QgYmUgbnVsbCIpfSwKVUk6
-ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5iKFAuRWUoYikpCnJldHVybiBhfSwKTzc6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxudWxsLCEwLGEsYiwiVmFsdWUgbm90IGlu
-IHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBuZXcgUC5iSihiLGMsITAsYSxk
-LCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIsYyxkKXtpZihhPGJ8fGE+Yyl0aHJvdyBI
-LmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpCOmZ1bmN0aW9uKGEsYixjKXtpZigwPmF8
-fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51bGwpKQppZihiIT1udWxsKXtpZihhPmJ8
-fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxsKSkKcmV0dXJuIGJ9cmV0dXJuIGN9LApr
-MTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhIT09Im51bWJlciIpcmV0dXJuIGEuSigpCmlmKGE8MCl0
-aHJvdyBILmIoUC5URShhLDAsbnVsbCxiLG51bGwpKQpyZXR1cm4gYX0sCnQ6ZnVuY3Rpb24oYSxiLGMs
-ZCxlKXt2YXIgdD1ILldZKGU9PW51bGw/Si5IKGIpOmUpCnJldHVybiBuZXcgUC5lWSh0LCEwLGEsYywi
-SW5kZXggb3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIoYSl9LApu
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5kcyhhKX0sClBWOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
-UC5saihhKX0sCmE0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEs
-YixjKXtyZXR1cm4gbmV3IFAuYUUoYSxiLGMpfSwKZEg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscz1I
-LlZNKFtdLGQuQygiamQ8MD4iKSkKQy5ObS5zQShzLGEpCmZvcih0PTA7dDxhOysrdClDLk5tLlkocyx0
-LGIuJDEodCkpCnJldHVybiBzfSwKaEs6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGss
-aixpLGgsZyxmLGU9bnVsbCxkPWEubGVuZ3RoCmlmKGQ+PTUpe3Q9KChKLlF6KGEsNCleNTgpKjN8Qy54
-Qi5XKGEsMCleMTAwfEMueEIuVyhhLDEpXjk3fEMueEIuVyhhLDIpXjExNnxDLnhCLlcoYSwzKV45Nyk+
-Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGQ8ZD9DLnhCLncoYSwwLGQpOmEsNSxlKS5nbFIoKQplbHNl
-IGlmKHQ9PT0zMilyZXR1cm4gUC5LRChDLnhCLncoYSw1LGQpLDAsZSkuZ2xSKCl9cz1uZXcgQXJyYXko
-OCkKcy5maXhlZCRsZW5ndGg9QXJyYXkKcj1ILlZNKHMsdS50KQpDLk5tLlkociwwLDApCkMuTm0uWShy
-LDEsLTEpCkMuTm0uWShyLDIsLTEpCkMuTm0uWShyLDcsLTEpCkMuTm0uWShyLDMsMCkKQy5ObS5ZKHIs
-NCwwKQpDLk5tLlkociw1LGQpCkMuTm0uWShyLDYsZCkKaWYoUC5VQihhLDAsZCwwLHIpPj0xNClDLk5t
-Llkociw3LGQpCnE9clsxXQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLnRCKCkKaWYocT49
-MClpZihQLlVCKGEsMCxxLDIwLHIpPT09MjApcls3XT1xCnM9clsyXQppZih0eXBlb2YgcyE9PSJudW1i
-ZXIiKXJldHVybiBzLmgoKQpwPXMrMQpvPXJbM10Kbj1yWzRdCm09cls1XQpsPXJbNl0KaWYodHlwZW9m
-IGwhPT0ibnVtYmVyIilyZXR1cm4gbC5KKCkKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5w
-WShtKQppZihsPG0pbT1sCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uSigpCmlmKG48cClu
-PW0KZWxzZSBpZihuPD1xKW49cSsxCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8uSigpCmlm
-KG88cClvPW4Kcz1yWzddCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSigpCms9czwwCmlm
-KGspaWYocD5xKzMpe2o9ZQprPSExfWVsc2V7cz1vPjAKaWYocyYmbysxPT09bil7aj1lCms9ITF9ZWxz
-ZXtpZighKG08ZCYmbT09PW4rMiYmSi5xMChhLCIuLiIsbikpKWk9bT5uKzImJkoucTAoYSwiLy4uIixt
-LTMpCmVsc2UgaT0hMAppZihpKXtqPWUKaz0hMX1lbHNle2lmKHE9PT00KWlmKEoucTAoYSwiZmlsZSIs
-MCkpe2lmKHA8PTApe2lmKCFDLnhCLlFpKGEsIi8iLG4pKXtoPSJmaWxlOi8vLyIKdD0zfWVsc2V7aD0i
-ZmlsZTovLyIKdD0yfWE9aCtDLnhCLncoYSxuLGQpCnEtPTAKcz10LTAKbSs9cwpsKz1zCmQ9YS5sZW5n
-dGgKcD03Cm89NwpuPTd9ZWxzZSBpZihuPT09bSl7Zz1tKzE7KytsCmE9Qy54Qi5pNyhhLG4sbSwiLyIp
-OysrZAptPWd9aj0iZmlsZSJ9ZWxzZSBpZihDLnhCLlFpKGEsImh0dHAiLDApKXtpZihzJiZvKzM9PT1u
-JiZDLnhCLlFpKGEsIjgwIixvKzEpKXtmPW4tMwptLT0zCmwtPTMKYT1DLnhCLmk3KGEsbyxuLCIiKQpk
-LT0zCm49Zn1qPSJodHRwIn1lbHNlIGo9ZQplbHNlIGlmKHE9PT01JiZKLnEwKGEsImh0dHBzIiwwKSl7
-aWYocyYmbys0PT09biYmSi5xMChhLCI0NDMiLG8rMSkpe2Y9bi00Cm0tPTQKbC09NAphPUouZGcoYSxv
-LG4sIiIpCmQtPTMKbj1mfWo9Imh0dHBzIn1lbHNlIGo9ZQprPSEwfX19ZWxzZSBqPWUKaWYoayl7cz1h
-Lmxlbmd0aAppZihkPHMpe2E9Si5sZChhLDAsZCkKcS09MApwLT0wCm8tPTAKbi09MAptLT0wCmwtPTB9
-cmV0dXJuIG5ldyBQLlVmKGEscSxwLG8sbixtLGwsail9cmV0dXJuIFAuanYoYSwwLGQscSxwLG8sbixt
-LGwsail9LApNdDpmdW5jdGlvbihhKXtILmMoYSkKcmV0dXJuIFAua3UoYSwwLGEubGVuZ3RoLEMueE0s
-ITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dS5OCnJldHVybiBDLk5tLk4wKEguVk0oYS5zcGxpdCgi
-JiIpLHUucyksUC5GbCh0LHQpLG5ldyBQLm4xKEMueE0pLHUuZil9LApIaDpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQscyxyLHEscCxvLG4sbT1udWxsLGw9IklQdjQgYWRkcmVzcyBzaG91bGQgY29udGFpbiBleGFj
-dGx5IDQgcGFydHMiLGs9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAwLi4yNTUiLGo9bmV3
-IFAuY1MoYSksaT1uZXcgVWludDhBcnJheSg0KQpmb3IodD1pLmxlbmd0aCxzPWIscj1zLHE9MDtzPGM7
-KytzKXtwPUMueEIubShhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpai4kMigiaW52YWxpZCBjaGFy
-YWN0ZXIiLHMpfWVsc2V7aWYocT09PTMpai4kMihsLHMpCm89UC5RQShDLnhCLncoYSxyLHMpLG0sbSkK
-aWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1cm4gby5vcygpCmlmKG8+MjU1KWouJDIoayxyKQpuPXEr
-MQppZihxPj10KXJldHVybiBILmsoaSxxKQppW3FdPW8Kcj1zKzEKcT1ufX1pZihxIT09MylqLiQyKGws
-YykKbz1QLlFBKEMueEIudyhhLHIsYyksbSxtKQppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBv
-Lm9zKCkKaWYobz4yNTUpai4kMihrLHIpCmlmKHE+PXQpcmV0dXJuIEguayhpLHEpCmlbcV09bwpyZXR1
-cm4gaX0sCmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
-LGUsZD1uZXcgUC5WQyhhKSxjPW5ldyBQLkpUKGQsYSkKaWYoYS5sZW5ndGg8MilkLiQxKCJhZGRyZXNz
-IGlzIHRvbyBzaG9ydCIpCnQ9SC5WTShbXSx1LnQpCmZvcihzPWIscj1zLHE9ITEscD0hMTtzPGEwOysr
-cyl7bz1DLnhCLm0oYSxzKQppZihvPT09NTgpe2lmKHM9PT1iKXsrK3MKaWYoQy54Qi5tKGEscykhPT01
-OClkLiQyKCJpbnZhbGlkIHN0YXJ0IGNvbG9uLiIscykKcj1zfWlmKHM9PT1yKXtpZihxKWQuJDIoIm9u
-bHkgb25lIHdpbGRjYXJkIGA6OmAgaXMgYWxsb3dlZCIscykKQy5ObS5pKHQsLTEpCnE9ITB9ZWxzZSBD
-Lk5tLmkodCxjLiQyKHIscykpCnI9cysxfWVsc2UgaWYobz09PTQ2KXA9ITB9aWYodC5sZW5ndGg9PT0w
-KWQuJDEoInRvbyBmZXcgcGFydHMiKQpuPXI9PT1hMAptPUMuTm0uZ3JaKHQpCmlmKG4mJm0hPT0tMSlk
-LiQyKCJleHBlY3RlZCBhIHBhcnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbilpZighcClDLk5tLmko
-dCxjLiQyKHIsYTApKQplbHNle2w9UC5IaChhLHIsYTApCkMuTm0uaSh0LChsWzBdPDw4fGxbMV0pPj4+
-MCkKQy5ObS5pKHQsKGxbMl08PDh8bFszXSk+Pj4wKX1pZihxKXtpZih0Lmxlbmd0aD43KWQuJDEoImFu
-IGFkZHJlc3Mgd2l0aCBhIHdpbGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2Ug
-aWYodC5sZW5ndGghPT04KWQuJDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29u
-dGFpbiBleGFjdGx5IDggcGFydHMiKQprPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobT10Lmxlbmd0aCxq
-PWsubGVuZ3RoLGk9OS1tLHM9MCxoPTA7czxtOysrcyl7Zz10W3NdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8
-aTsrK2Ype2lmKGg8MHx8aD49ailyZXR1cm4gSC5rKGssaCkKa1toXT0wCmU9aCsxCmlmKGU+PWopcmV0
-dXJuIEguayhrLGUpCmtbZV09MApoKz0yfWVsc2V7ZT1DLmpuLndHKGcsOCkKaWYoaDwwfHxoPj1qKXJl
-dHVybiBILmsoayxoKQprW2hdPWUKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5rKGssZSkKa1tlXT1nJjI1
-NQpoKz0yfX1yZXR1cm4ga30sCmp2OmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcsaCxpLGope3ZhciB0LHMs
-cixxLHAsbyxuLG09bnVsbAppZihqPT1udWxsKWlmKGQ+YilqPVAuUGkoYSxiLGQpCmVsc2V7aWYoZD09
-PWIpUC5SMyhhLGIsIkludmFsaWQgZW1wdHkgc2NoZW1lIikKaj0iIn1pZihlPmIpe3Q9ZCszCnM9dDxl
-P1AuelIoYSx0LGUtMSk6IiIKcj1QLk9lKGEsZSxmLCExKQppZih0eXBlb2YgZiE9PSJudW1iZXIiKXJl
-dHVybiBmLmgoKQpxPWYrMQppZih0eXBlb2YgZyE9PSJudW1iZXIiKXJldHVybiBILnBZKGcpCnA9cTxn
-P1Aud0IoUC5RQShKLmxkKGEscSxnKSxuZXcgUC5lMShhLGYpLG0pLGopOm19ZWxzZXtwPW0Kcj1wCnM9
-IiJ9bz1QLmthKGEsZyxoLG0saixyIT1udWxsKQppZih0eXBlb2YgaCE9PSJudW1iZXIiKXJldHVybiBo
-LkooKQpuPWg8aT9QLmxlKGEsaCsxLGksbSk6bQpyZXR1cm4gbmV3IFAuRG4oaixzLHIscCxvLG4saTxj
-P1AudEcoYSxpKzEsYyk6bSl9LAp3SzpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiA4MApp
-ZihhPT09Imh0dHBzIilyZXR1cm4gNDQzCnJldHVybiAwfSwKUjM6ZnVuY3Rpb24oYSxiLGMpe3Rocm93
-IEguYihQLnJyKGMsYSxiKSl9LAprRTpmdW5jdGlvbihhLGIpe0MuTm0uSyhhLG5ldyBQLk5ZKCExKSl9
-LApITjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyCmZvcih0PUgucUMoYSxjLG51bGwsSC50NihhKS5j
-KSx0PW5ldyBILmE3KHQsdC5nQSh0KSx0LiR0aS5DKCJhNzxhTC5FPiIpKTt0LkYoKTspe3M9dC5kCnI9
-UC5udSgnWyIqLzo8Pj9cXFxcfF0nKQpzLnRvU3RyaW5nCmlmKEgubTIocyxyLDApKXt0PVAuTDQoIkls
-bGVnYWwgY2hhcmFjdGVyIGluIHBhdGg6ICIrcykKdGhyb3cgSC5iKHQpfX19LApyZzpmdW5jdGlvbihh
-LGIpe3ZhciB0CmlmKCEoNjU8PWEmJmE8PTkwKSl0PTk3PD1hJiZhPD0xMjIKZWxzZSB0PSEwCmlmKHQp
-cmV0dXJuCnQ9UC5MNCgiSWxsZWdhbCBkcml2ZSBsZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIodCl9
-LAp3QjpmdW5jdGlvbihhLGIpe2lmKGEhPW51bGwmJmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJldHVy
-biBhfSwKT2U6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGE9PW51bGwpcmV0dXJu
-IG51bGwKaWYoYj09PWMpcmV0dXJuIiIKaWYoQy54Qi5tKGEsYik9PT05MSl7aWYodHlwZW9mIGMhPT0i
-bnVtYmVyIilyZXR1cm4gYy5ITigpCnQ9Yy0xCmlmKEMueEIubShhLHQpIT09OTMpUC5SMyhhLGIsIk1p
-c3NpbmcgZW5kIGBdYCB0byBtYXRjaCBgW2AgaW4gaG9zdCIpCnM9YisxCnI9UC50byhhLHMsdCkKaWYo
-dHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5KKCkKaWYocjx0KXtxPXIrMQpwPVAuT0EoYSxDLnhC
-LlFpKGEsIjI1IixxKT9yKzM6cSx0LCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLHMscikKcmV0dXJuIEMu
-eEIudyhhLGIscikudG9Mb3dlckNhc2UoKStwKyJdIn1pZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVy
-biBILnBZKGMpCm89Ygpmb3IoO288YzsrK28paWYoQy54Qi5tKGEsbyk9PT01OCl7cj1DLnhCLlhVKGEs
-IiUiLGIpCmlmKCEocj49YiYmcjxjKSlyPWMKaWYocjxjKXtxPXIrMQpwPVAuT0EoYSxDLnhCLlFpKGEs
-IjI1IixxKT9yKzM6cSxjLCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLGIscikKcmV0dXJuIlsiK0MueEIu
-dyhhLGIscikrcCsiXSJ9cmV0dXJuIFAuT0woYSxiLGMpfSwKdG86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHM9Qy54Qi5YVShhLCIlIixiKQppZihzPj1iKXtpZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBI
-LnBZKGMpCnQ9czxjfWVsc2UgdD0hMQpyZXR1cm4gdD9zOmN9LApPQTpmdW5jdGlvbihhLGIsYyxkKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwsaz1kIT09IiI/bmV3IFAuUm4oZCk6bnVsbAppZih0eXBlb2YgYyE9
-PSJudW1iZXIiKXJldHVybiBILnBZKGMpCnQ9YgpzPXQKcj0hMApmb3IoO3Q8Yzspe3E9Qy54Qi5tKGEs
-dCkKaWYocT09PTM3KXtwPVAucnYoYSx0LCEwKQpvPXA9PW51bGwKaWYobyYmcil7dCs9Mwpjb250aW51
-ZX1pZihrPT1udWxsKWs9bmV3IFAuUm4oIiIpCm49ay5hKz1DLnhCLncoYSxzLHQpCmlmKG8pcD1DLnhC
-LncoYSx0LHQrMykKZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJab25lSUQgc2hvdWxkIG5vdCBjb250
-YWluICUgYW55bW9yZSIpCmsuYT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNle2lmKHE8MTI3KXtvPXE+Pj40
-CmlmKG8+PTgpcmV0dXJuIEguayhDLkYzLG8pCm89KEMuRjNbb10mMTw8KHEmMTUpKSE9PTB9ZWxzZSBv
-PSExCmlmKG8pe2lmKHImJjY1PD1xJiY5MD49cSl7aWYoaz09bnVsbClrPW5ldyBQLlJuKCIiKQppZihz
-PHQpe2suYSs9Qy54Qi53KGEscyx0KQpzPXR9cj0hMX0rK3R9ZWxzZXtpZigocSY2NDUxMik9PT01NTI5
-NiYmdCsxPGMpe209Qy54Qi5tKGEsdCsxKQppZigobSY2NDUxMik9PT01NjMyMCl7cT02NTUzNnwocSYx
-MDIzKTw8MTB8bSYxMDIzCmw9Mn1lbHNlIGw9MX1lbHNlIGw9MQppZihrPT1udWxsKWs9bmV3IFAuUm4o
-IiIpCmsuYSs9Qy54Qi53KGEscyx0KQprLmErPVAuSEgocSkKdCs9bApzPXR9fX1pZihrPT1udWxsKXJl
-dHVybiBDLnhCLncoYSxiLGMpCmlmKHM8YylrLmErPUMueEIudyhhLHMsYykKbz1rLmEKcmV0dXJuIG8u
-Y2hhckNvZGVBdCgwKT09MD9vOm99LApPTDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsLGssagppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBILnBZKGMpCnQ9YgpzPXQKcj1udWxs
-CnE9ITAKZm9yKDt0PGM7KXtwPUMueEIubShhLHQpCmlmKHA9PT0zNyl7bz1QLnJ2KGEsdCwhMCkKbj1v
-PT1udWxsCmlmKG4mJnEpe3QrPTMKY29udGludWV9aWYocj09bnVsbClyPW5ldyBQLlJuKCIiKQptPUMu
-eEIudyhhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNhc2UoKTptCmlmKG4pe289Qy54Qi53KGEsdCx0
-KzMpCms9M31lbHNlIGlmKG89PT0iJSIpe289IiUyNSIKaz0xfWVsc2Ugaz0zCnIuYT1sK28KdCs9awpz
-PXQKcT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguayhDLmVhLG4pCm49
-KEMuZWFbbl0mMTw8KHAmMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pe2lmKHEmJjY1PD1wJiY5MD49cCl7
-aWYocj09bnVsbClyPW5ldyBQLlJuKCIiKQppZihzPHQpe3IuYSs9Qy54Qi53KGEscyx0KQpzPXR9cT0h
-MX0rK3R9ZWxzZXtpZihwPD05Myl7bj1wPj4+NAppZihuPj04KXJldHVybiBILmsoQy5hayxuKQpuPShD
-LmFrW25dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKVAuUjMoYSx0LCJJbnZhbGlkIGNoYXJh
-Y3RlciIpCmVsc2V7aWYoKHAmNjQ1MTIpPT09NTUyOTYmJnQrMTxjKXtqPUMueEIubShhLHQrMSkKaWYo
-KGomNjQ1MTIpPT09NTYzMjApe3A9NjU1MzZ8KHAmMTAyMyk8PDEwfGomMTAyMwprPTJ9ZWxzZSBrPTF9
-ZWxzZSBrPTEKaWYocj09bnVsbClyPW5ldyBQLlJuKCIiKQptPUMueEIudyhhLHMsdCkKci5hKz0hcT9t
-LnRvTG93ZXJDYXNlKCk6bQpyLmErPVAuSEgocCkKdCs9awpzPXR9fX19aWYocj09bnVsbClyZXR1cm4g
-Qy54Qi53KGEsYixjKQppZihzPGMpe209Qy54Qi53KGEscyxjKQpyLmErPSFxP20udG9Mb3dlckNhc2Uo
-KTptfW49ci5hCnJldHVybiBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKUGk6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHMscixxCmlmKGI9PT1jKXJldHVybiIiCmlmKCFQLkV0KEouclkoYSkuVyhhLGIpKSlQLlIz
-KGEsYiwiU2NoZW1lIG5vdCBzdGFydGluZyB3aXRoIGFscGhhYmV0aWMgY2hhcmFjdGVyIikKZm9yKHQ9
-YixzPSExO3Q8YzsrK3Qpe3I9Qy54Qi5XKGEsdCkKaWYocjwxMjgpe3E9cj4+PjQKaWYocT49OClyZXR1
-cm4gSC5rKEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpIT09MH1lbHNlIHE9ITEKaWYoIXEpUC5S
-MyhhLHQsIklsbGVnYWwgc2NoZW1lIGNoYXJhY3RlciIpCmlmKDY1PD1yJiZyPD05MClzPSEwfWE9Qy54
-Qi53KGEsYixjKQpyZXR1cm4gUC5ZYShzP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEp
-e2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9
-PT0iaHR0cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0
-dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC51Tyhh
-LGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdCxzPWU9PT0iZmlsZSIs
-cj1zfHxmLHE9YT09bnVsbAppZihxJiYhMClyZXR1cm4gcz8iLyI6IiIKdD0hcT9QLnVPKGEsYixjLEMu
-V2QsITApOkMuak4uRTIoZCxuZXcgUC5SWigpLHUuTikuelYoMCwiLyIpCmlmKHQubGVuZ3RoPT09MCl7
-aWYocylyZXR1cm4iLyJ9ZWxzZSBpZihyJiYhQy54Qi5uKHQsIi8iKSl0PSIvIit0CnJldHVybiBQLkpy
-KHQsZSxmKX0sCkpyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1iLmxlbmd0aD09PTAKaWYodCYmIWMmJiFD
-LnhCLm4oYSwiLyIpKXJldHVybiBQLndGKGEsIXR8fGMpCnJldHVybiBQLnhlKGEpfSwKbGU6ZnVuY3Rp
-b24oYSxiLGMsZCl7dmFyIHQscz17fQppZihhIT1udWxsKXtpZihkIT1udWxsKXRocm93IEguYihQLnhZ
-KCJCb3RoIHF1ZXJ5IGFuZCBxdWVyeVBhcmFtZXRlcnMgc3BlY2lmaWVkIikpCnJldHVybiBQLnVPKGEs
-YixjLEMuVkMsITApfWlmKGQ9PW51bGwpcmV0dXJuIG51bGwKdD1uZXcgUC5SbigiIikKcy5hPSIiCmQu
-SygwLG5ldyBQLnk1KG5ldyBQLk1FKHMsdCkpKQpzPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0w
-P3M6c30sCnRHOmZ1bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXJldHVybiBudWxsCnJldHVybiBQLnVP
-KGEsYixjLEMuVkMsITApfSwKcnY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbz1iKzIKaWYo
-bz49YS5sZW5ndGgpcmV0dXJuIiUiCnQ9Qy54Qi5tKGEsYisxKQpzPUMueEIubShhLG8pCnI9SC5vbyh0
-KQpxPUgub28ocykKaWYocjwwfHxxPDApcmV0dXJuIiUiCnA9cioxNitxCmlmKHA8MTI3KXtvPUMuam4u
-d0cocCw0KQppZihvPj04KXJldHVybiBILmsoQy5GMyxvKQpvPShDLkYzW29dJjE8PChwJjE1KSkhPT0w
-fWVsc2Ugbz0hMQppZihvKXJldHVybiBILkx3KGMmJjY1PD1wJiY5MD49cD8ocHwzMik+Pj4wOnApCmlm
-KHQ+PTk3fHxzPj05NylyZXR1cm4gQy54Qi53KGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51
-bGx9LApISDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbj0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYo
-YTwxMjgpe3Q9bmV3IEFycmF5KDMpCnQuZml4ZWQkbGVuZ3RoPUFycmF5CnM9SC5WTSh0LHUudCkKQy5O
-bS5ZKHMsMCwzNykKQy5ObS5ZKHMsMSxDLnhCLlcobixhPj4+NCkpCkMuTm0uWShzLDIsQy54Qi5XKG4s
-YSYxNSkpfWVsc2V7aWYoYT4yMDQ3KWlmKGE+NjU1MzUpe3I9MjQwCnE9NH1lbHNle3I9MjI0CnE9M31l
-bHNle3I9MTkyCnE9Mn10PW5ldyBBcnJheSgzKnEpCnQuZml4ZWQkbGVuZ3RoPUFycmF5CnM9SC5WTSh0
-LHUudCkKZm9yKHA9MDstLXEscT49MDtyPTEyOCl7bz1DLmpuLmJmKGEsNipxKSY2M3xyCkMuTm0uWShz
-LHAsMzcpCkMuTm0uWShzLHArMSxDLnhCLlcobixvPj4+NCkpCkMuTm0uWShzLHArMixDLnhCLlcobixv
-JjE1KSkKcCs9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKdU86ZnVuY3Rpb24oYSxiLGMsZCxlKXt2
-YXIgdD1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHQ9PW51bGw/Qy54Qi53KGEsYixjKTp0fSwKVWw6ZnVu
-Y3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG89bnVsbCxuPSFlLG09YixsPW0saz1vCndoaWxl
-KCEwKXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLkooKQppZih0eXBlb2YgYyE9PSJudW1i
-ZXIiKXJldHVybiBILnBZKGMpCmlmKCEobTxjKSlicmVhawpjJDA6e3Q9Qy54Qi5tKGEsbSkKaWYodDwx
-Mjcpe3M9dD4+PjQKaWYocz49OClyZXR1cm4gSC5rKGQscykKcz0oZFtzXSYxPDwodCYxNSkpIT09MH1l
-bHNlIHM9ITEKaWYocykrK20KZWxzZXtpZih0PT09Mzcpe3I9UC5ydihhLG0sITEpCmlmKHI9PW51bGwp
-e20rPTMKYnJlYWsgYyQwfWlmKCIlIj09PXIpe3I9IiUyNSIKcT0xfWVsc2UgcT0zfWVsc2V7aWYobilp
-Zih0PD05Myl7cz10Pj4+NAppZihzPj04KXJldHVybiBILmsoQy5hayxzKQpzPShDLmFrW3NdJjE8PCh0
-JjE1KSkhPT0wfWVsc2Ugcz0hMQplbHNlIHM9ITEKaWYocyl7UC5SMyhhLG0sIkludmFsaWQgY2hhcmFj
-dGVyIikKcT1vCnI9cX1lbHNle2lmKCh0JjY0NTEyKT09PTU1Mjk2KXtzPW0rMQppZihzPGMpe3A9Qy54
-Qi5tKGEscykKaWYoKHAmNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzZ8KHQmMTAyMyk8PDEwfHAmMTAyMwpx
-PTJ9ZWxzZSBxPTF9ZWxzZSBxPTF9ZWxzZSBxPTEKcj1QLkhIKHQpfX1pZihrPT1udWxsKWs9bmV3IFAu
-Um4oIiIpCmsuYSs9Qy54Qi53KGEsbCxtKQprLmErPUguZChyKQppZih0eXBlb2YgcSE9PSJudW1iZXIi
-KXJldHVybiBILnBZKHEpCm0rPXEKbD1tfX19aWYoaz09bnVsbClyZXR1cm4gbwppZih0eXBlb2YgbCE9
-PSJudW1iZXIiKXJldHVybiBsLkooKQppZihsPGMpay5hKz1DLnhCLncoYSxsLGMpCm49ay5hCnJldHVy
-biBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKeUI6ZnVuY3Rpb24oYSl7aWYoQy54Qi5uKGEsIi4iKSly
-ZXR1cm4hMApyZXR1cm4gQy54Qi5PWShhLCIvLiIpIT09LTF9LAp4ZTpmdW5jdGlvbihhKXt2YXIgdCxz
-LHIscSxwLG8sbgppZighUC55QihhKSlyZXR1cm4gYQp0PUguVk0oW10sdS5zKQpmb3Iocz1hLnNwbGl0
-KCIvIikscj1zLmxlbmd0aCxxPSExLHA9MDtwPHI7KytwKXtvPXNbcF0KaWYoSi5STShvLCIuLiIpKXtu
-PXQubGVuZ3RoCmlmKG4hPT0wKXtpZigwPj1uKXJldHVybiBILmsodCwtMSkKdC5wb3AoKQppZih0Lmxl
-bmd0aD09PTApQy5ObS5pKHQsIiIpfXE9ITB9ZWxzZSBpZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5tLmko
-dCxvKQpxPSExfX1pZihxKUMuTm0uaSh0LCIiKQpyZXR1cm4gQy5ObS56Vih0LCIvIil9LAp3RjpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwppZighUC55QihhKSlyZXR1cm4hYj9QLkMxKGEpOmEKdD1I
-LlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7
-bz1zW3BdCmlmKCIuLiI9PT1vKWlmKHQubGVuZ3RoIT09MCYmQy5ObS5ncloodCkhPT0iLi4iKXtpZigw
-Pj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkKcT0hMH1lbHNle0MuTm0uaSh0LCIuLiIp
-CnE9ITF9ZWxzZSBpZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5tLmkodCxvKQpxPSExfX1zPXQubGVuZ3Ro
-CmlmKHMhPT0wKWlmKHM9PT0xKXtpZigwPj1zKXJldHVybiBILmsodCwwKQpzPXRbMF0ubGVuZ3RoPT09
-MH1lbHNlIHM9ITEKZWxzZSBzPSEwCmlmKHMpcmV0dXJuIi4vIgppZihxfHxDLk5tLmdyWih0KT09PSIu
-LiIpQy5ObS5pKHQsIiIpCmlmKCFiKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsMCkKQy5ObS5Z
-KHQsMCxQLkMxKHRbMF0pKX1yZXR1cm4gQy5ObS56Vih0LCIvIil9LApDMTpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIscT1hLmxlbmd0aAppZihxPj0yJiZQLkV0KEouUXooYSwwKSkpZm9yKHQ9MTt0PHE7Kyt0KXtz
-PUMueEIuVyhhLHQpCmlmKHM9PT01OClyZXR1cm4gQy54Qi53KGEsMCx0KSsiJTNBIitDLnhCLkcoYSx0
-KzEpCmlmKHM8PTEyNyl7cj1zPj4+NAppZihyPj04KXJldHVybiBILmsoQy5tSyxyKQpyPShDLm1LW3Jd
-JjE8PChzJjE1KSk9PT0wfWVsc2Ugcj0hMAppZihyKWJyZWFrfXJldHVybiBhfSwKbW46ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyLHE9YS5nRmooKSxwPXEubGVuZ3RoCmlmKHA+MCYmSi5IKHFbMF0pPT09MiYmSi5h
-NihxWzBdLDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguayhxLDApClAucmcoSi5hNihxWzBdLDApLCEx
-KQpQLkhOKHEsITEsMSkKdD0hMH1lbHNle1AuSE4ocSwhMSwwKQp0PSExfXM9YS5ndFQoKSYmIXQ/Ilxc
-IjoiIgppZihhLmdjaigpKXtyPWEuZ0pmKGEpCmlmKHIubGVuZ3RoIT09MClzPXMrIlxcIityKyJcXCJ9
-cz1QLnZnKHMscSwiXFwiKQpwPXQmJnA9PT0xP3MrIlxcIjpzCnJldHVybiBwLmNoYXJDb2RlQXQoMCk9
-PTA/cDpwfSwKSWg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKZm9yKHQ9MCxzPTA7czwyOysrcyl7cj1D
-LnhCLlcoYSxiK3MpCmlmKDQ4PD1yJiZyPD01Nyl0PXQqMTYrci00OAplbHNle3J8PTMyCmlmKDk3PD1y
-JiZyPD0xMDIpdD10KjE2K3ItODcKZWxzZSB0aHJvdyBILmIoUC54WSgiSW52YWxpZCBVUkwgZW5jb2Rp
-bmciKSl9fXJldHVybiB0fSwKa3U6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwPUouclko
-YSksbz1iCndoaWxlKCEwKXtpZighKG88Yykpe3Q9ITAKYnJlYWt9cz1wLlcoYSxvKQppZihzPD0xMjcp
-aWYocyE9PTM3KXI9ZSYmcz09PTQzCmVsc2Ugcj0hMAplbHNlIHI9ITAKaWYocil7dD0hMQpicmVha30r
-K299aWYodCl7aWYoQy54TSE9PWQpcj0hMQplbHNlIHI9ITAKaWYocilyZXR1cm4gcC53KGEsYixjKQpl
-bHNlIHE9bmV3IEgucWoocC53KGEsYixjKSl9ZWxzZXtxPUguVk0oW10sdS50KQpmb3Iobz1iO288Yzsr
-K28pe3M9cC5XKGEsbykKaWYocz4xMjcpdGhyb3cgSC5iKFAueFkoIklsbGVnYWwgcGVyY2VudCBlbmNv
-ZGluZyBpbiBVUkkiKSkKaWYocz09PTM3KXtpZihvKzM+YS5sZW5ndGgpdGhyb3cgSC5iKFAueFkoIlRy
-dW5jYXRlZCBVUkkiKSkKQy5ObS5pKHEsUC5JaChhLG8rMSkpCm8rPTJ9ZWxzZSBpZihlJiZzPT09NDMp
-Qy5ObS5pKHEsMzIpCmVsc2UgQy5ObS5pKHEscyl9fXUuTC5hKHEpCnJldHVybiBuZXcgUC5HWSghMSku
-V0oocSl9LApFdDpmdW5jdGlvbihhKXt2YXIgdD1hfDMyCnJldHVybiA5Nzw9dCYmdDw9MTIyfSwKS0Q6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbD0iSW52YWxpZCBNSU1FIHR5cGUiLGs9
-SC5WTShbYi0xXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9YixyPS0xLHE9bnVsbDtzPHQ7KytzKXtxPUMu
-eEIuVyhhLHMpCmlmKHE9PT00NHx8cT09PTU5KWJyZWFrCmlmKHE9PT00Nyl7aWYocjwwKXtyPXMKY29u
-dGludWV9dGhyb3cgSC5iKFAucnIobCxhLHMpKX19aWYocjwwJiZzPmIpdGhyb3cgSC5iKFAucnIobCxh
-LHMpKQpmb3IoO3EhPT00NDspe0MuTm0uaShrLHMpOysrcwpmb3IocD0tMTtzPHQ7KytzKXtxPUMueEIu
-VyhhLHMpCmlmKHE9PT02MSl7aWYocDwwKXA9c31lbHNlIGlmKHE9PT01OXx8cT09PTQ0KWJyZWFrfWlm
-KHA+PTApQy5ObS5pKGsscCkKZWxzZXtvPUMuTm0uZ3JaKGspCmlmKHEhPT00NHx8cyE9PW8rN3x8IUMu
-eEIuUWkoYSwiYmFzZTY0IixvKzEpKXRocm93IEguYihQLnJyKCJFeHBlY3RpbmcgJz0nIixhLHMpKQpi
-cmVha319Qy5ObS5pKGsscykKbj1zKzEKaWYoKGsubGVuZ3RoJjEpPT09MSlhPUMuaDkueXIoYSxuLHQp
-CmVsc2V7bT1QLlVsKGEsbix0LEMuVkMsITApCmlmKG0hPW51bGwpYT1DLnhCLmk3KGEsbix0LG0pfXJl
-dHVybiBuZXcgUC5QRShhLGssYyl9LApLTjpmdW5jdGlvbigpe3ZhciB0PSIwMTIzNDU2Nzg5QUJDREVG
-R0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0uX34hJCYnKCkqKyw7
-PSIscz0iLiIscj0iOiIscT0iLyIscD0iPyIsbz0iIyIsbj11LmdjLG09UC5kSCgyMixuZXcgUC5xMygp
-LCEwLG4pLGw9bmV3IFAueUkobSksaz1uZXcgUC5jNigpLGo9bmV3IFAucWQoKSxpPW4uYShsLiQyKDAs
-MjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLHMsMTQpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwzKQprLiQz
-KGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxNCwyMjUpKQprLiQzKGksdCwxKQprLiQz
-KGkscywxNSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywy
-MDUpCmk9bi5hKGwuJDIoMTUsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLCIlIiwyMjUpCmsuJDMoaSxy
-LDM0KQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxLDIy
-NSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwxMCkKay4kMyhpLHAsMTcyKQprLiQz
-KGksbywyMDUpCmk9bi5hKGwuJDIoMiwyMzUpKQprLiQzKGksdCwxMzkpCmsuJDMoaSxxLDEzMSkKay4k
-MyhpLHMsMTQ2KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigzLDIzNSkpCmsu
-JDMoaSx0LDExKQprLiQzKGkscSw2OCkKay4kMyhpLHMsMTgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8s
-MjA1KQppPW4uYShsLiQyKDQsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIsMjI5KQprLiQzKGks
-ciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSwiWyIsMjMyKQprLiQzKGkscSwxMzgpCmsuJDMoaSxw
-LDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDUsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJB
-WiIsMjI5KQprLiQzKGksciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAs
-MTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNiwyMzEpKQpqLiQzKGksIjE5Iiw3KQprLiQzKGks
-IkAiLDY4KQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQy
-KDcsMjMxKSkKai4kMyhpLCIwOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGks
-cCwxNzIpCmsuJDMoaSxvLDIwNSkKay4kMyhuLmEobC4kMig4LDgpKSwiXSIsNSkKaT1uLmEobC4kMig5
-LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxNikKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIp
-CmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxNiwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTcp
-CmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTcsMjM1
-KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4u
-YShsLiQyKDEwLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxOCkKay4kMyhpLHEsMjM0KQprLiQz
-KGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxOCwyMzUpKQprLiQzKGksdCwxMSkKay4k
-MyhpLHMsMTkpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwu
-JDIoMTksMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGks
-bywyMDUpCmk9bi5hKGwuJDIoMTEsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDEwKQprLiQzKGks
-cCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMiwyMzYpKQprLiQzKGksdCwxMikKay4kMyhp
-LHAsMTIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMywyMzcpKQprLiQzKGksdCwxMykKay4kMyhp
-LHAsMTMpCmouJDMobi5hKGwuJDIoMjAsMjQ1KSksImF6IiwyMSkKbD1uLmEobC4kMigyMSwyNDUpKQpq
-LiQzKGwsImF6IiwyMSkKai4kMyhsLCIwOSIsMjEpCmsuJDMobCwiKy0uIiwyMSkKcmV0dXJuIG19LApV
-QjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbz0kLnZaKCkKZm9yKHQ9Si5yWShhKSxz
-PWI7czxjOysrcyl7aWYoZDwwfHxkPj1vLmxlbmd0aClyZXR1cm4gSC5rKG8sZCkKcj1vW2RdCnE9dC5X
-KGEscyleOTYKaWYocT45NSlxPTMxCmlmKHE+PXIubGVuZ3RoKXJldHVybiBILmsocixxKQpwPXJbcV0K
-ZD1wJjMxCkMuTm0uWShlLHA+Pj41LHMpfXJldHVybiBkfSwKV0Y6ZnVuY3Rpb24gV0YoYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCmEyOmZ1bmN0aW9uIGEyKCl7fSwKaVA6ZnVuY3Rpb24gaVAoYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCkNQOmZ1bmN0aW9uIENQKCl7fSwKWFM6ZnVuY3Rpb24gWFMoKXt9LApDNjpm
-dW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCkxLOmZ1bmN0aW9uIExLKCl7fSwKQVQ6ZnVuY3Rpb24gQVQo
-YSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmJKOmZ1bmN0aW9uIGJK
-KGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uZT1hCl8uZj1iCl8uYT1jCl8uYj1kCl8uYz1lCl8uZD1m
-fSwKZVk6ZnVuY3Rpb24gZVkoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZj1hCl8uYT1iCl8uYj1jCl8u
-Yz1kCl8uZD1lfSwKbXA6ZnVuY3Rpb24gbXAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9Ygpf
-LmM9YwpfLmQ9ZH0sCnViOmZ1bmN0aW9uIHViKGEpe3RoaXMuYT1hfSwKZHM6ZnVuY3Rpb24gZHMoYSl7
-dGhpcy5hPWF9LApsajpmdW5jdGlvbiBsaihhKXt0aGlzLmE9YX0sClVWOmZ1bmN0aW9uIFVWKGEpe3Ro
-aXMuYT1hfSwKazU6ZnVuY3Rpb24gazUoKXt9LApLWTpmdW5jdGlvbiBLWSgpe30sCnQ3OmZ1bmN0aW9u
-IHQ3KGEpe3RoaXMuYT1hfSwKQ0Q6ZnVuY3Rpb24gQ0QoYSl7dGhpcy5hPWF9LAphRTpmdW5jdGlvbiBh
-RShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApFSDpmdW5jdGlvbiBFSCgpe30sCklm
-OmZ1bmN0aW9uIElmKCl7fSwKY1g6ZnVuY3Rpb24gY1goKXt9LApBbjpmdW5jdGlvbiBBbigpe30sCnpN
-OmZ1bmN0aW9uIHpNKCl7fSwKWjA6ZnVuY3Rpb24gWjAoKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKbGY6ZnVuY3Rp
-b24gbGYoKXt9LApNaDpmdW5jdGlvbiBNaCgpe30sCk9kOmZ1bmN0aW9uIE9kKCl7fSwKaWI6ZnVuY3Rp
-b24gaWIoKXt9LAp4dTpmdW5jdGlvbiB4dSgpe30sCkd6OmZ1bmN0aW9uIEd6KCl7fSwKWmQ6ZnVuY3Rp
-b24gWmQoKXt9LApxVTpmdW5jdGlvbiBxVSgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwK
-R0Q6ZnVuY3Rpb24gR0QoKXt9LApuMTpmdW5jdGlvbiBuMShhKXt0aGlzLmE9YX0sCmNTOmZ1bmN0aW9u
-IGNTKGEpe3RoaXMuYT1hfSwKVkM6ZnVuY3Rpb24gVkMoYSl7dGhpcy5hPWF9LApKVDpmdW5jdGlvbiBK
-VChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKRG46ZnVuY3Rpb24gRG4oYSxiLGMsZCxlLGYsZyl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8u
-eT1fLng9bnVsbH0sCmUxOmZ1bmN0aW9uIGUxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApOWTpmdW5j
-dGlvbiBOWShhKXt0aGlzLmE9YX0sClJaOmZ1bmN0aW9uIFJaKCl7fSwKTUU6ZnVuY3Rpb24gTUUoYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3RoaXMuYT1hfSwKUEU6ZnVuY3Rp
-b24gUEUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcTM6ZnVuY3Rpb24gcTMoKXt9
-LAp5STpmdW5jdGlvbiB5SShhKXt0aGlzLmE9YX0sCmM2OmZ1bmN0aW9uIGM2KCl7fSwKcWQ6ZnVuY3Rp
-b24gcWQoKXt9LApVZjpmdW5jdGlvbiBVZihhLGIsYyxkLGUsZixnLGgpe3ZhciBfPXRoaXMKXy5hPWEK
-Xy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PWgKXy55PW51bGx9LApxZTpmdW5j
-dGlvbiBxZShhLGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8u
-ZT1lCl8uZj1mCl8ucj1nCl8uUT1fLno9Xy55PV8ueD1udWxsfSwKaUo6ZnVuY3Rpb24gaUooKXt9LApq
-ZzpmdW5jdGlvbiBqZyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVGE6ZnVuY3Rpb24gVGEoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sCkJmOmZ1bmN0aW9uIEJmKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApB
-czpmdW5jdGlvbiBBcygpe30sCkdFOmZ1bmN0aW9uIEdFKGEpe3RoaXMuYT1hfSwKTjc6ZnVuY3Rpb24g
-TjcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnVROmZ1bmN0aW9uIHVRKCl7fSwKaEY6ZnVuY3Rpb24g
-aEYoKXt9LApSNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKSC5FOShiKQp1LmouYShkKQppZihI
-Lm9UKGIpKXt0PVtjXQpDLk5tLkZWKHQsZCkKZD10fXM9dS56CnI9UC5DSChKLk0xKGQsUC53MCgpLHMp
-LCEwLHMpCnUuWi5hKGEpCnJldHVybiBQLndZKEguRWsoYSxyLG51bGwpKX0sCkRtOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdAp0cnl7aWYoT2JqZWN0LmlzRXh0ZW5zaWJsZShhKSYmIU9iamVjdC5wcm90b3R5cGUu
-aGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxiLHt2YWx1ZTpj
-fSkKcmV0dXJuITB9fWNhdGNoKHQpe0guUnUodCl9cmV0dXJuITF9LApPbTpmdW5jdGlvbihhLGIpe2lm
-KE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXJldHVybiBhW2JdCnJldHVy
-biBudWxsfSwKd1k6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBl
-b2YgYT09Im51bWJlciJ8fEguclEoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuRTQpcmV0dXJu
-IGEuYQppZihILlI5KGEpKXJldHVybiBhCmlmKHUudy5iKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2Vv
-ZiBQLmlQKXJldHVybiBILm8yKGEpCmlmKHUuWi5iKGEpKXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVu
-Y3Rpb24iLG5ldyBQLlBDKCkpCnJldHVybiBQLmhFKGEsIl8kZGFydF9qc09iamVjdCIsbmV3IFAubXQo
-JC5rSSgpKSl9LApoRTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9UC5PbShhLGIpCmlmKHQ9PW51bGwpe3Q9
-Yy4kMShhKQpQLkRtKGEsYix0KX1yZXR1cm4gdH0sCkw3OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYoYT09
-bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9v
-bGVhbiIpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBh
-CmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9iamVjdCYmdS53LmIoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGlu
-c3RhbmNlb2YgRGF0ZSl7dD1ILldZKGEuZ2V0VGltZSgpKQppZihNYXRoLmFicyh0KTw9ODY0ZTEzKXM9
-ITEKZWxzZSBzPSEwCmlmKHMpSC52aChQLnhZKCJEYXRlVGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdl
-OiAiK3QpKQpQLlVJKCExLCJpc1V0YyIsdS55KQpyZXR1cm4gbmV3IFAuaVAodCwhMSl9ZWxzZSBpZihh
-LmNvbnN0cnVjdG9yPT09JC5rSSgpKXJldHVybiBhLm8KZWxzZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1
-bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBQLmlRKGEsJC53USgpLG5ldyBQ
-Lk56KCkpCmlmKGEgaW5zdGFuY2VvZiBBcnJheSlyZXR1cm4gUC5pUShhLCQuQ3IoKSxuZXcgUC5ucCgp
-KQpyZXR1cm4gUC5pUShhLCQuQ3IoKSxuZXcgUC5VdCgpKX0sCmlROmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dD1QLk9tKGEsYikKaWYodD09bnVsbHx8IShhIGluc3RhbmNlb2YgT2JqZWN0KSl7dD1jLiQxKGEpClAu
-RG0oYSxiLHQpfXJldHVybiB0fSwKUEM6ZnVuY3Rpb24gUEMoKXt9LAptdDpmdW5jdGlvbiBtdChhKXt0
-aGlzLmE9YX0sCk56OmZ1bmN0aW9uIE56KCl7fSwKbnA6ZnVuY3Rpb24gbnAoKXt9LApVdDpmdW5jdGlv
-biBVdCgpe30sCkU0OmZ1bmN0aW9uIEU0KGEpe3RoaXMuYT1hfSwKcjc6ZnVuY3Rpb24gcjcoYSl7dGhp
-cy5hPWF9LApUejpmdW5jdGlvbiBUeihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApjbzpmdW5jdGlv
-biBjbygpe30sCm5kOmZ1bmN0aW9uIG5kKCl7fSwKS2U6ZnVuY3Rpb24gS2UoYSl7dGhpcy5hPWF9LApk
-NTpmdW5jdGlvbiBkNSgpe30sCm42OmZ1bmN0aW9uIG42KCl7fX0sVz17CngzOmZ1bmN0aW9uKCl7cmV0
-dXJuIHdpbmRvd30sClpyOmZ1bmN0aW9uKCl7cmV0dXJuIGRvY3VtZW50fSwKVTk6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0PWRvY3VtZW50LmJvZHkscz0odCYmQy5SWSkucjYodCxhLGIsYykKcy50b1N0cmluZwp0
-PXUuYWMKdD1uZXcgSC5VNShuZXcgVy5lNyhzKSx0LkMoImEyKGxELkUpIikuYShuZXcgVy5DdigpKSx0
-LkMoIlU1PGxELkU+IikpCnJldHVybiB1LmguYSh0LmdyOCh0KSl9LApyUzpmdW5jdGlvbihhKXt2YXIg
-dCxzLHI9ImVsZW1lbnQgdGFnIHVuYXZhaWxhYmxlIgp0cnl7dD1KLlJFKGEpCmlmKHR5cGVvZiB0Lmdu
-cyhhKT09InN0cmluZyIpcj10LmducyhhKX1jYXRjaChzKXtILlJ1KHMpfXJldHVybiByfSwKcUQ6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPW5ldyBQLnZzKCQuWDMsdS5hbykscD1uZXcgUC5aZihxLHUu
-YmopLG89bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5EdC5lbyhvLGI9PW51bGw/IkdFVCI6YixhLCEwKQpj
-LksoMCxuZXcgVy5iVShvKSkKdD11LmFuCnM9dC5hKG5ldyBXLmhIKG8scCkpCnUuTS5hKG51bGwpCnI9
-dS5wClcuSkUobywibG9hZCIscywhMSxyKQpXLkpFKG8sImVycm9yIix0LmEocC5nWUooKSksITEscikK
-by5zZW5kKCkKcmV0dXJuIHF9LApDMDpmdW5jdGlvbihhLGIpe2E9NTM2ODcwOTExJmErYgphPTUzNjg3
-MDkxMSZhKygoNTI0Mjg3JmEpPDwxMCkKcmV0dXJuIGFeYT4+PjZ9LApyRTpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgdD1XLkMwKFcuQzAoVy5DMChXLkMwKDAsYSksYiksYyksZCkscz01MzY4NzA5MTEmdCsoKDY3
-MTA4ODYzJnQpPDwzKQpzXj1zPj4+MTEKcmV0dXJuIDUzNjg3MDkxMSZzKygoMTYzODMmcyk8PDE1KX0s
-ClROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPWEuY2xhc3NMaXN0CmZvcih0PWIubGVuZ3RoLHM9MDtz
-PGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytzKXIuYWRkKGJbc10pfSwKSkU6ZnVu
-Y3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1XLmFGKG5ldyBXLnZOKGMpLHUuQikKaWYodCE9bnVsbCYmITAp
-Si5kWihhLGIsdCwhMSkKcmV0dXJuIG5ldyBXLnhDKGEsYix0LCExLGUuQygieEM8MD4iKSl9LApUdzpm
-dW5jdGlvbihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikscz1uZXcgVy5tayh0LHdp
-bmRvdy5sb2NhdGlvbikKcz1uZXcgVy5KUShzKQpzLkNZKGEpCnJldHVybiBzfSwKeVc6ZnVuY3Rpb24o
-YSxiLGMsZCl7dS5oLmEoYSkKSC5jKGIpCkguYyhjKQp1Lk8uYShkKQpyZXR1cm4hMH0sClFXOmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciB0LHMscgp1LmguYShhKQpILmMoYikKSC5jKGMpCnQ9dS5PLmEoZCkuYQpz
-PXQuYQpzLmhyZWY9YwpyPXMuaG9zdG5hbWUKdD10LmIKaWYoIShyPT10Lmhvc3RuYW1lJiZzLnBvcnQ9
-PXQucG9ydCYmcy5wcm90b2NvbD09dC5wcm90b2NvbCkpaWYocj09PSIiKWlmKHMucG9ydD09PSIiKXt0
-PXMucHJvdG9jb2wKdD10PT09IjoifHx0PT09IiJ9ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITAK
-cmV0dXJuIHR9LApCbDpmdW5jdGlvbigpe3ZhciB0PXUuTixzPVAudE0oQy5ReCx0KSxyPXUuZEcuYShu
-ZXcgVy5JQSgpKSxxPUguVk0oWyJURU1QTEFURSJdLHUucykKdD1uZXcgVy5jdChzLFAuTHModCksUC5M
-cyh0KSxQLkxzKHQpLG51bGwpCnQuQ1kobnVsbCxuZXcgSC5sSihDLlF4LHIsdS5kdikscSxudWxsKQpy
-ZXR1cm4gdH0sClB2OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFcuUDEo
-YSl9LApxYzpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0TWVz
-c2FnZSIgaW4gYSl7dD1XLlAxKGEpCnJldHVybiB0fWVsc2UgcmV0dXJuIHUuYVMuYShhKX0sClAxOmZ1
-bmN0aW9uKGEpe2lmKGE9PT13aW5kb3cpcmV0dXJuIHUuY2kuYShhKQplbHNlIHJldHVybiBuZXcgVy5k
-VyhhKX0sCnpYOmZ1bmN0aW9uKGEpe2lmKGE9PT13aW5kb3cubG9jYXRpb24pcmV0dXJuIGEKZWxzZSBy
-ZXR1cm4gbmV3IFcuRmIoKX0sCmFGOmZ1bmN0aW9uKGEsYil7dmFyIHQ9JC5YMwppZih0PT09Qy5OVSly
-ZXR1cm4gYQpyZXR1cm4gdC5QeShhLGIpfSwKcUU6ZnVuY3Rpb24gcUUoKXt9LApHaDpmdW5jdGlvbiBH
-aCgpe30sCmZZOmZ1bmN0aW9uIGZZKCl7fSwKbkI6ZnVuY3Rpb24gbkIoKXt9LApBejpmdW5jdGlvbiBB
-eigpe30sClFQOmZ1bmN0aW9uIFFQKCl7fSwKbng6ZnVuY3Rpb24gbngoKXt9LApvSjpmdW5jdGlvbiBv
-Sigpe30sCmlkOmZ1bmN0aW9uIGlkKCl7fSwKUUY6ZnVuY3Rpb24gUUYoKXt9LApOaDpmdW5jdGlvbiBO
-aCgpe30sCklCOmZ1bmN0aW9uIElCKCl7fSwKbjc6ZnVuY3Rpb24gbjcoKXt9LAp3ejpmdW5jdGlvbiB3
-eihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApjdjpmdW5jdGlvbiBjdigpe30sCkN2OmZ1bmN0aW9u
-IEN2KCl7fSwKZWE6ZnVuY3Rpb24gZWEoKXt9LApEMDpmdW5jdGlvbiBEMCgpe30sClQ1OmZ1bmN0aW9u
-IFQ1KCl7fSwKaDQ6ZnVuY3Rpb24gaDQoKXt9LApicjpmdW5jdGlvbiBicigpe30sClZiOmZ1bmN0aW9u
-IFZiKCl7fSwKZko6ZnVuY3Rpb24gZkooKXt9LApiVTpmdW5jdGlvbiBiVShhKXt0aGlzLmE9YX0sCmhI
-OmZ1bmN0aW9uIGhIKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YTpmdW5jdGlvbiB3YSgpe30sClNn
-OmZ1bmN0aW9uIFNnKCl7fSwKdTg6ZnVuY3Rpb24gdTgoKXt9LApPSzpmdW5jdGlvbiBPSygpe30sCmU3
-OmZ1bmN0aW9uIGU3KGEpe3RoaXMuYT1hfSwKdUg6ZnVuY3Rpb24gdUgoKXt9LApCSDpmdW5jdGlvbiBC
-SCgpe30sClNOOmZ1bmN0aW9uIFNOKCl7fSwKZXc6ZnVuY3Rpb24gZXcoKXt9LApscDpmdW5jdGlvbiBs
-cCgpe30sClRiOmZ1bmN0aW9uIFRiKCl7fSwKSXY6ZnVuY3Rpb24gSXYoKXt9LApCVDpmdW5jdGlvbiBC
-VCgpe30sCnlZOmZ1bmN0aW9uIHlZKCl7fSwKdzY6ZnVuY3Rpb24gdzYoKXt9LApLNTpmdW5jdGlvbiBL
-NSgpe30sCkNtOmZ1bmN0aW9uIENtKCl7fSwKQ1E6ZnVuY3Rpb24gQ1EoKXt9LAp3NDpmdW5jdGlvbiB3
-NCgpe30sCnJoOmZ1bmN0aW9uIHJoKCl7fSwKY2Y6ZnVuY3Rpb24gY2YoKXt9LAppNzpmdW5jdGlvbiBp
-NyhhKXt0aGlzLmE9YX0sClN5OmZ1bmN0aW9uIFN5KGEpe3RoaXMuYT1hfSwKS1M6ZnVuY3Rpb24gS1Mo
-YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkEzOmZ1bmN0aW9uIEEzKGEsYil7dGhpcy5hPWEKdGhpcy5i
-PWJ9LApJNDpmdW5jdGlvbiBJNChhKXt0aGlzLmE9YX0sCkZrOmZ1bmN0aW9uIEZrKGEsYil7dGhpcy5h
-PWEKdGhpcy4kdGk9Yn0sClJPOmZ1bmN0aW9uIFJPKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
-PWIKXy5jPWMKXy4kdGk9ZH0sCmV1OmZ1bmN0aW9uIGV1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEK
-Xy5iPWIKXy5jPWMKXy4kdGk9ZH0sCnhDOmZ1bmN0aW9uIHhDKGEsYixjLGQsZSl7dmFyIF89dGhpcwpf
-LmI9YQpfLmM9YgpfLmQ9YwpfLmU9ZApfLiR0aT1lfSwKdk46ZnVuY3Rpb24gdk4oYSl7dGhpcy5hPWF9
-LApKUTpmdW5jdGlvbiBKUShhKXt0aGlzLmE9YX0sCkdtOmZ1bmN0aW9uIEdtKCl7fSwKdkQ6ZnVuY3Rp
-b24gdkQoYSl7dGhpcy5hPWF9LApVdjpmdW5jdGlvbiBVdihhKXt0aGlzLmE9YX0sCkVnOmZ1bmN0aW9u
-IEVnKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCm02OmZ1bmN0aW9uIG02KCl7fSwK
-RW86ZnVuY3Rpb24gRW8oKXt9LApXazpmdW5jdGlvbiBXaygpe30sCmN0OmZ1bmN0aW9uIGN0KGEsYixj
-LGQsZSl7dmFyIF89dGhpcwpfLmU9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCklBOmZ1bmN0aW9u
-IElBKCl7fSwKT3c6ZnVuY3Rpb24gT3coKXt9LApXOTpmdW5jdGlvbiBXOShhLGIsYyl7dmFyIF89dGhp
-cwpfLmE9YQpfLmI9YgpfLmM9LTEKXy5kPW51bGwKXy4kdGk9Y30sCmRXOmZ1bmN0aW9uIGRXKGEpe3Ro
-aXMuYT1hfSwKRmI6ZnVuY3Rpb24gRmIoKXt9LAprRjpmdW5jdGlvbiBrRigpe30sCm1rOmZ1bmN0aW9u
-IG1rKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLbzpmdW5jdGlvbiBLbyhhKXt0aGlzLmE9YQp0aGlz
-LmI9ITF9LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6
-ZnVuY3Rpb24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6
-ZnVuY3Rpb24gb2EoKXt9fSxVPXsKeXU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49SC5WTShb
-XSx1LmJQKQpmb3IodD1KLlU2KGEpLHM9Si5JVCh1LlIuYSh0LnEoYSwiZGV0YWlscyIpKSk7cy5GKCk7
-KXtyPXMuZ2woKQpxPUouVTYocikKcD1ILmMocS5xKHIsImRlc2NyaXB0aW9uIikpCnE9cS5xKHIsImxp
-bmsiKQppZihxPT1udWxsKXE9bnVsbAplbHNle289Si5VNihxKQpxPW5ldyBVLk1sKEguYyhvLnEocSwi
-aHJlZiIpKSxILldZKG8ucShxLCJsaW5lIikpLEguYyhvLnEocSwicGF0aCIpKSl9Qy5ObS5pKG4sbmV3
-IFUudUYocCxxKSl9cmV0dXJuIG5ldyBVLmQyKG4sVS5qZih0LnEoYSwiZWRpdHMiKSksSC5jKHQucShh
-LCJleHBsYW5hdGlvbiIpKSxILldZKHQucShhLCJsaW5lIikpLEguYyh0LnEoYSwicGF0aCIpKSxVLk5k
-KHQucShhLCJ0cmFjZXMiKSkpfSwKamY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0
-PW51bGwKZWxzZXt0PUguVk0oW10sdS5mQSkKZm9yKHM9Si5JVCh1LlIuYShhKSk7cy5GKCk7KXtyPXMu
-Z2woKQpxPUouVTYocikKQy5ObS5pKHQsbmV3IFUuU2UoSC5jKHEucShyLCJkZXNjcmlwdGlvbiIpKSxI
-LmMocS5xKHIsImhyZWYiKSkpKX19cmV0dXJuIHR9LApOZDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9
-PW51bGwpdD1udWxsCmVsc2V7dD1ILlZNKFtdLHUuaGgpCmZvcihzPUouSVQodS5SLmEoYSkpO3MuRigp
-OylDLk5tLmkodCxVLkpqKHMuZ2woKSkpfXJldHVybiB0fSwKSmo6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvPSJkZXNjcmlwdGlvbiIsbj1KLlU2KGEpLG09SC5jKG4ucShhLG8pKSxsPUguVk0oW10sdS5h
-SikKZm9yKG49Si5JVCh1LlIuYShuLnEoYSwiZW50cmllcyIpKSk7bi5GKCk7KXt0PW4uZ2woKQpzPUou
-VTYodCkKcj1ILmMocy5xKHQsbykpCnE9SC5jKHMucSh0LCJmdW5jdGlvbiIpKQpzPXMucSh0LCJsaW5r
-IikKaWYocz09bnVsbClzPW51bGwKZWxzZXtwPUouVTYocykKcz1uZXcgVS5NbChILmMocC5xKHMsImhy
-ZWYiKSksSC5XWShwLnEocywibGluZSIpKSxILmMocC5xKHMsInBhdGgiKSkpfUMuTm0uaShsLG5ldyBV
-LndiKHIscSxzKSl9cmV0dXJuIG5ldyBVLnlEKG0sbCl9LApkMjpmdW5jdGlvbiBkMihhLGIsYyxkLGUs
-Zil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sClNlOmZ1bmN0
-aW9uIFNlKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1RjpmdW5jdGlvbiB1RihhLGIpe3RoaXMuYT1h
-CnRoaXMuYj1ifSwKTWw6ZnVuY3Rpb24gTWwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1j
-fSwKeUQ6ZnVuY3Rpb24geUQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndiOmZ1bmN0aW9uIHdiKGEs
-YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y319LEI9ewpZZjpmdW5jdGlvbihhKXt2YXIgdCxz
-LHIscT1ILmMoYS5xKDAsInJlZ2lvbnMiKSkscD1ILmMoYS5xKDAsIm5hdmlnYXRpb25Db250ZW50Iikp
-LG89SC5jKGEucSgwLCJzb3VyY2VDb2RlIikpLG49SC5WTShbXSx1LnUpCmZvcih0PUouSVQodS5SLmEo
-YS5xKDAsImVkaXRzIikpKTt0LkYoKTspe3M9dC5nbCgpCnI9Si5VNihzKQpDLk5tLmkobixuZXcgQi5q
-OChILldZKHIucShzLCJsaW5lIikpLEguYyhyLnEocywiZXhwbGFuYXRpb24iKSksSC5XWShyLnEocywi
-b2Zmc2V0IikpKSl9cmV0dXJuIG5ldyBCLnFwKHEscCxvLG4pfSwKajg6ZnVuY3Rpb24gajgoYSxiLGMp
-e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFyIF89
-dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCkx1OmZ1bmN0aW9uIEx1KCl7fSwKT1M6ZnVuY3Rp
-b24oYSl7dmFyIHQKaWYoIShhPj02NSYmYTw9OTApKXQ9YT49OTcmJmE8PTEyMgplbHNlIHQ9ITAKcmV0
-dXJuIHR9LApZdTpmdW5jdGlvbihhLGIpe3ZhciB0PWEubGVuZ3RoLHM9YisyCmlmKHQ8cylyZXR1cm4h
-MQppZighQi5PUyhDLnhCLm0oYSxiKSkpcmV0dXJuITEKaWYoQy54Qi5tKGEsYisxKSE9PTU4KXJldHVy
-biExCmlmKHQ9PT1zKXJldHVybiEwCnJldHVybiBDLnhCLm0oYSxzKT09PTQ3fX0sVD17bVE6ZnVuY3Rp
-b24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRlbnRMb2Fk
-ZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwoKSl9LAprejpmdW5j
-dGlvbihhKXt2YXIgdCxzPXUuaC5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNjb3BlID4g
-dWwiKSxyPXMuc3R5bGUscT0iIitDLkNELnpRKHMub2Zmc2V0SGVpZ2h0KSoyKyJweCIKci5tYXhIZWln
-aHQ9cQpyPUoucUYoYSkKcT1yLiR0aQp0PXEuQygifigxKSIpLmEobmV3IEwuV3gocyxhKSkKdS5NLmEo
-bnVsbCkKVy5KRShyLmEsci5iLHQsITEscS5jKX0sCnlYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEs
-cCxvPSJxdWVyeVNlbGVjdG9yQWxsIixuPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSksbT11LmgKbi50
-b1N0cmluZwpILkRoKG0sbSwiVCIsbykKdD11LlQKcz1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwo
-Ii5uYXYtbGluayIpLHQpCnMuSyhzLG5ldyBMLkFPKGIpKQpILkRoKG0sbSwiVCIsbykKcj1uZXcgVy53
-eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSx0KQppZihyLmdBKHIpIT09MCl7cT1uLnF1ZXJ5
-U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpxLnRvU3RyaW5nCnIuSyhyLG5ldyBMLkhvKHEuZ2V0
-QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocSkpLk8oInBhdGgiKSkpKX1ILkRoKG0s
-bSwiVCIsbykKcD1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5wb3N0LWxpbmsiKSx0KQpwLkso
-cCxuZXcgTC5JQygpKX0sClE2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dS5OCnJldHVybiBXLnFEKEwuUTQo
-YSxiKSxudWxsLFAuRUYoWyJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVU
-Ri04Il0sdCx0KSl9LAp0eTpmdW5jdGlvbihhKXt2YXIgdD11Lk4KcmV0dXJuIFcucUQoTC5RNChhLFAu
-RmwodCx0KSksIlBPU1QiLFAuRUYoWyJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFy
-c2V0PVVURi04Il0sdCx0KSkuVzcobmV3IEwuTDEoKSx1LnIpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9
-UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0s
-Ckc2OmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09
-bnVsbD9udWxsOkguSHAodCxudWxsKX0sCnQyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8s
-bj17fSxtPXUuaC5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnQ9bi5h
-PW0uZ2V0QXR0cmlidXRlKCJocmVmIikKaWYoSi56bCh0LCI/Iikpe3M9Qy54Qi53KHQsMCxDLnhCLk9Z
-KHQsIj8iKSkKbi5hPXMKcj1zfWVsc2Ugcj10CmlmKGMhPW51bGwpe3E9JC5uVSgpCnI9bi5hPXEubzUo
-RC5ucihxLnRNKGMpLHIpKX1wPUwuRzYodCkKbz1MLmFLKHQpCmlmKHAhPW51bGwpTC5hZihyLHAsbyxi
-LG5ldyBMLm5UKG4scCxvKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuQloobikpfSwKdW06
-ZnVuY3Rpb24oYSl7cmV0dXJuIEwuUVModS5WLmEoYSkpfSwKUVM6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxz
-PVAuRlgodS56KSxyPTEscSxwPVtdLG8sbixtLGwsayxqCnZhciAkYXN5bmMkdW09UC5seihmdW5jdGlv
-bihiLGMpe2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDprPXUuaC5h
-KFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVs
-dCgpCm09ZG9jdW1lbnQKbS5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVubmluZyIpCnI9Mwp0PTYKcmV0
-dXJuIFAualEoTC50eShrKSwkYXN5bmMkdW0pCmNhc2UgNjp1LmFfLmEoSi5HcihXLlB2KG0uZGVmYXVs
-dFZpZXcpKSkucmVsb2FkKCkKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmo9cQpvPUguUnUo
-aikKbj1ILnRzKGopCkwucUooImhhbmRsZVBvc3RMaW5rQ2xpY2s6ICIrSC5kKG8pLG4pCndpbmRvdy5h
-bGVydCgiQ291bGQgbm90IGxvYWQgIitILmQoaykrIiAoIitILmQobykrIikuIikKcC5wdXNoKDUpCnQ9
-NApicmVhawpjYXNlIDI6cD1bMV0KY2FzZSA0OnI9MQptLmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgicmVy
-dW5uaW5nIikKdD1wLnBvcCgpCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpy
-ZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyR1bSxzKX0sCnZVOmZ1bmN0aW9uKCl7
-dmFyIHQ9ZG9jdW1lbnQscz11LmgKSC5EaChzLHMsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikKdD1uZXcg
-Vy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5jb2RlIiksdS5UKQp0LksodCxuZXcgTC5HSCgpKX0sCmhY
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD11Lk4KTC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdpb24iLCJv
-ZmZzZXQiLEguZChiKV0sdCx0KSkuVzcobmV3IEwuRFQoYSxiLGMpLHUuUCkuT0EobmV3IEwuZUgoYSkp
-fSwKRzc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdAppZighSi5wNChhLCIuZGFydCIpKXtMLkJFKGEs
-bmV3IEIucXAoIiIsIiIsIiIsQy54RCksZCkKTC5CWChhLG51bGwpCmlmKGUhPW51bGwpZS4kMCgpCnJl
-dHVybn10PXUuTgpMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSx0LHQpKS5XNyhuZXcgTC56RChh
-LGQsYixjLGUpLHUuUCkuT0EobmV3IEwuT0UoYSkpfSwKR2U6ZnVuY3Rpb24oKXt2YXIgdD0iL19wcmV2
-aWV3L25hdmlnYXRpb25UcmVlLmpzb24iCkwuUTYodCxDLkNNKS5XNyhuZXcgTC5UVygpLHUuUCkuT0Eo
-bmV3IEwueHIodCkpfSwKcUo6ZnVuY3Rpb24oYSxiKXt2YXIgdAp3aW5kb3cKaWYodHlwZW9mIGNvbnNv
-bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKGEpCndpbmRvdwp0PUguZChiKQppZih0
-eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IodCl9LApxTzpmdW5j
-dGlvbihhKXt2YXIgdCxzPWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkscj1DLkNELnpRKCQuZmkoKS5v
-ZmZzZXRIZWlnaHQpLHE9d2luZG93LmlubmVySGVpZ2h0LHA9Qy5DRC56USgkLkRXKCkub2Zmc2V0SGVp
-Z2h0KQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLkhOKCkKdD1zLmJvdHRvbQppZih0eXBl
-b2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lm9zKCkKaWYodD5xLShwKzE0KSlKLmRoKGEpCmVsc2V7cT1z
-LnRvcAppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLkooKQppZihxPHIrMTQpSi5kaChhKX19
-LApmRzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgppZihhIT1udWxsKXt0PWRvY3VtZW50CnM9dC5nZXRF
-bGVtZW50QnlJZCgibyIrSC5kKGEpKQpyPXQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILmQoYikpCmlm
-KHMhPW51bGwpe0wucU8ocykKSi5kUihzKS5pKDAsInRhcmdldCIpfWVsc2UgaWYociE9bnVsbClMLnFP
-KHIucGFyZW50RWxlbWVudCkKaWYociE9bnVsbClKLmRSKHUuaC5hKHIucGFyZW50Tm9kZSkpLmkoMCwi
-aGlnaGxpZ2h0Iil9ZWxzZSBMLnFPKCQuRDkoKSl9LAphZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
-LHMscj1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxxPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYp
-CmlmKHIhPW51bGwpe3Q9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChyKSkKaWYodCE9bnVs
-bClKLmRSKHQpLlIoMCwidGFyZ2V0Iil9aWYocSE9bnVsbCl7cz1kb2N1bWVudC5xdWVyeVNlbGVjdG9y
-KCIubGluZS0iK0guZChxKSkKaWYocyE9bnVsbClKLmRSKHMucGFyZW50RWxlbWVudCkuUigwLCJoaWdo
-bGlnaHQiKX1pZihhPT13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpe0wuZkcoYixjKQplLiQwKCl9ZWxz
-ZSBMLkc3KGEsYixjLGQsZSl9LApRNDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1QLmhLKGEpLHE9dS5O
-CnE9UC5GbChxLHEpCmZvcih0PXIuZ2hZKCksdD10LmdQdSh0KSx0PXQuZ2t6KHQpO3QuRigpOyl7cz10
-LmdsKCkKcS5ZKDAscy5hLHMuYil9Zm9yKHQ9Yi5nUHUoYiksdD10Lmdreih0KTt0LkYoKTspe3M9dC5n
-bCgpCnEuWSgwLHMuYSxzLmIpfXEuWSgwLCJhdXRoVG9rZW4iLCQuVUUoKSkKcmV0dXJuIHIubm0oMCxx
-KS5aKDApfSwKTHg6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT09MSl0PWIKZWxzZSB0PWIrInMiCnJl
-dHVybiB0fSwKVDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPSQuaEwoKQpKLmw1KGws
-IiIpCmlmKGE9PW51bGwpe3Q9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpCnQudGV4dENvbnRlbnQ9
-IlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC4iCkMuTHQuc0QodCxILlZNKFsicGxhY2Vo
-b2xkZXIiXSx1LnMpKQpKLmRoKHUuaC5hKGwuYXBwZW5kQ2hpbGQodCkpKQpyZXR1cm59cz1hLmUKdD0k
-Lm5VKCkKcj10LnRNKHMpCnE9YS5jCnA9ZG9jdW1lbnQKbz10LkhQKHMsSi5UMChwLnF1ZXJ5U2VsZWN0
-b3IoIi5yb290IikudGV4dENvbnRlbnQpKQpuPWEuZAp0PXAuY3JlYXRlRWxlbWVudCgicCIpCm09dS5o
-LmEobC5hcHBlbmRDaGlsZCh0KSkKbS5hcHBlbmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKEguZChxKSsi
-IGF0ICIrSC5kKG8pKyI6IitILmQobikrIi4iKSkKSi5kaChtKQpMLkNDKGEsbCxyKQpMLkZ6KGEsbCkK
-TC5ORyhhLGwscil9LApMSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixp
-LGgsZyxmLGUsZD0kLnlQKCkKSi5sNShkLCIiKQp0PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJw
-IikKcj11LmgKcT1yLmEoZC5hcHBlbmRDaGlsZChzKSkKcD1iLmxlbmd0aAppZihwPT09MClxLmFwcGVu
-ZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUoIk5vIHByb3Bvc2VkIGVkaXRzIikpCmVsc2UgcS5hcHBlbmRD
-aGlsZCh0LmNyZWF0ZVRleHROb2RlKCIiK3ArIiBwcm9wb3NlZCAiK0wuTHgocCwiZWRpdCIpKyI6Iikp
-CnM9dC5jcmVhdGVFbGVtZW50KCJ1bCIpCm89ci5hKGQuYXBwZW5kQ2hpbGQocykpCmZvcihkPWIubGVu
-Z3RoLHM9dS5pLG49dS5RLG09bi5DKCJ+KDEpIiksbD11Lk0sbj1uLmMsaz0wO2s8Yi5sZW5ndGg7Yi5s
-ZW5ndGg9PT1kfHwoMCxILmxrKShiKSwrK2spe2o9YltrXQppPXQuY3JlYXRlRWxlbWVudCgibGkiKQpo
-PXIuYShvLmFwcGVuZENoaWxkKGkpKQpKLmRSKGgpLmkoMCwiZWRpdCIpCmk9dC5jcmVhdGVFbGVtZW50
-KCJhIikKZz1zLmEoaC5hcHBlbmRDaGlsZChpKSkKZy5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsiKQpm
-PWouYwppPUguZChmKQpnLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGcpKS5P
-KCJvZmZzZXQiKSxpKQplPWouYQppPUguZChlKQpnLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5
-KG5ldyBXLmk3KGcpKS5PKCJsaW5lIiksaSkKZy5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCJs
-aW5lICIrSC5kKGUpKSkKaT1tLmEobmV3IEwuRUUoZixlLGEpKQpsLmEobnVsbCkKVy5KRShnLCJjbGlj
-ayIsaSwhMSxuKQpoLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUoIjogIitILmQoai5iKSkpfWlm
-KGMpTC5UMShudWxsKX0sCkZyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9d2luZG93LmxvY2F0aW9u
-LHE9UC5oSygociYmQy5FeCkuZ0RyKHIpK0guZChhKSkKcj11Lk4Kcj1QLkZsKHIscikKaWYoYiE9bnVs
-bClyLlkoMCwib2Zmc2V0IixILmQoYikpCmlmKGMhPW51bGwpci5ZKDAsImxpbmUiLEguZChjKSkKci5Z
-KDAsImF1dGhUb2tlbiIsJC5VRSgpKQpxPXEubm0oMCxyKQpyPXdpbmRvdy5oaXN0b3J5CnQ9dS56CnM9
-cS5aKDApCnIudG9TdHJpbmcKci5wdXNoU3RhdGUobmV3IFAuQmYoW10sW10pLlB2KFAuRmwodCx0KSks
-IiIscyl9LApFbjpmdW5jdGlvbihhKXt2YXIgdD1KLm0oZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJv
-b3QiKS50ZXh0Q29udGVudCwiLyIpCmlmKEMueEIubihhLHQpKXJldHVybiBDLnhCLkcoYSx0Lmxlbmd0
-aCkKZWxzZSByZXR1cm4gYX0sCkJYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXt9CnIuYT1hCmE9TC5F
-bihhKQpyLmE9YQokLkQ5KCkudGV4dENvbnRlbnQ9YQp0PWRvY3VtZW50CnM9dS5oCkguRGgocyxzLCJU
-IiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9bmV3IFcud3oodC5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LXBh
-bmVsIC5uYXYtbGluayIpLHUuVCkKdC5LKHQsbmV3IEwuVlMocikpfSwKQkU6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0PSIucmVnaW9ucyIscz1kb2N1bWVudCxyPXMucXVlcnlTZWxlY3Rvcih0KSxxPXMucXVlcnlT
-ZWxlY3RvcigiLmNvZGUiKQpKLnRIKHIsYi5hLCQuS0coKSkKSi50SChxLGIuYiwkLktHKCkpCkwuTEgo
-YSxiLmQsYykKTC52VSgpCkwueVgoIi5jb2RlIiwhMCkKTC55WCh0LCEwKX0sCnRYOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPWRvY3VtZW50LGg9aS5jcmVhdGVFbGVtZW50KCJ1
-bCIpLGc9dS5oLGY9Zy5hKGEuYXBwZW5kQ2hpbGQoaCkpCmZvcihoPWIubGVuZ3RoLHQ9dS5NLHM9MDtz
-PGIubGVuZ3RoO2IubGVuZ3RoPT09aHx8KDAsSC5saykoYiksKytzKXtyPWJbc10KcT1pLmNyZWF0ZUVs
-ZW1lbnQoImxpIikKcD1nLmEoZi5hcHBlbmRDaGlsZChxKSkKcT1KLlJFKHApCmlmKHIuYT09PUMuWTIp
-e3EuZ0QocCkuaSgwLCJkaXIiKQpxPWkuY3JlYXRlRWxlbWVudCgic3BhbiIpCm89Zy5hKHAuYXBwZW5k
-Q2hpbGQocSkpCnE9Si5SRShvKQpxLmdEKG8pLmkoMCwiYXJyb3ciKQpxLnNoZihvLCImI3gyNUJDOyIp
-CnE9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5sNShnLmEocC5hcHBlbmRDaGlsZChxKSksIiYjeDFG
-NEMxOyIpCnAuYXBwZW5kQ2hpbGQoaS5jcmVhdGVUZXh0Tm9kZShyLmIpKQpMLnRYKHAsci5jKQpMLmt6
-KG8pfWVsc2V7cS5zaGYocCwiJiN4MUY0QzQ7IikKcT1pLmNyZWF0ZUVsZW1lbnQoImEiKQpuPWcuYShw
-LmFwcGVuZENoaWxkKHEpKQpxPUouUkUobikKcS5nRChuKS5pKDAsIm5hdi1saW5rIikKbi5zZXRBdHRy
-aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhuKSkuTygibmFtZSIpLHIuZCkKbi5zZXRBdHRy
-aWJ1dGUoImhyZWYiLHIuZSkKbi5hcHBlbmRDaGlsZChpLmNyZWF0ZVRleHROb2RlKHIuYikpCnE9cS5n
-VmwobikKbT1xLiR0aQpsPW0uQygifigxKSIpLmEobmV3IEwuVEQoKSkKdC5hKG51bGwpClcuSkUocS5h
-LHEuYixsLCExLG0uYykKaz1yLmYKaWYodHlwZW9mIGshPT0ibnVtYmVyIilyZXR1cm4gay5vcygpCmlm
-KGs+MCl7cT1pLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpqPWcuYShwLmFwcGVuZENoaWxkKHEpKQpKLmRS
-KGopLmkoMCwiZWRpdC1jb3VudCIpCnE9IiIraysiICIKaWYoaz09PTEpbT0iZWRpdCIKZWxzZSBtPSJl
-ZGl0cyIKai5zZXRBdHRyaWJ1dGUoInRpdGxlIixxK20pCmouYXBwZW5kQ2hpbGQoaS5jcmVhdGVUZXh0
-Tm9kZShDLmpuLlooaykpKX19fX0sCmM0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9ZG9jdW1lbnQscz10LmNy
-ZWF0ZUVsZW1lbnQoImEiKQp1LmkuYShzKQpzLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUoSC5k
-KGEuYykrIjoiK0guZChhLmIpKSkKdD1ELm5yKGIsYS5hKQpzLnNldEF0dHJpYnV0ZSgiaHJlZiIsJC5u
-VSgpLm81KHQpKQpzLmNsYXNzTGlzdC5hZGQoIm5hdi1saW5rIikKcmV0dXJuIHN9LApGejpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaT1hLmIKaWYoaSE9bnVsbClmb3IodD1pLmxl
-bmd0aCxzPXUuaCxyPXUucyxxPXUuWCxwPTA7cDxpLmxlbmd0aDtpLmxlbmd0aD09PXR8fCgwLEgubGsp
-KGkpLCsrcCl7bz1pW3BdCm49ZG9jdW1lbnQKbT1uLmNyZWF0ZUVsZW1lbnQoInAiKQpsPXMuYShiLmFw
-cGVuZENoaWxkKG0pKQptPW4uY3JlYXRlRWxlbWVudCgiYSIpCms9cy5hKGwuYXBwZW5kQ2hpbGQobSkp
-CmsuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShvLmEpKQprLnNldEF0dHJpYnV0ZSgiaHJlZiIs
-by5iKQpuPXEuYShILlZNKFsicG9zdC1saW5rIiwiYmVmb3JlLWFwcGx5Il0scikpCmo9Si5kUihrKQpq
-LlYxKDApCmouRlYoMCxuKX19LApORzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxs
-PWEuYQppZihsLmxlbmd0aCE9PTApe3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpzLnRl
-eHRDb250ZW50PSJFZGl0IHJhdGlvbmFsZSAoZXhwZXJpbWVudGFsKToiCmIuYXBwZW5kQ2hpbGQocykK
-cz10LmNyZWF0ZUVsZW1lbnQoInVsIikKcj11LmguYShiLmFwcGVuZENoaWxkKHMpKQpmb3Iocz1sLmxl
-bmd0aCxxPTA7cTxsLmxlbmd0aDtsLmxlbmd0aD09PXN8fCgwLEgubGspKGwpLCsrcSl7cD1sW3FdCm89
-dC5jcmVhdGVFbGVtZW50KCJsaSIpCm49ci5hcHBlbmRDaGlsZChvKQpuLmFwcGVuZENoaWxkKHQuY3Jl
-YXRlVGV4dE5vZGUocC5hKSkKbT1wLmIKaWYobSE9bnVsbCl7bi5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRl
-eHROb2RlKCIgKCIpKQpuLmFwcGVuZENoaWxkKEwuYzQobSxjKSkKbi5hcHBlbmRDaGlsZCh0LmNyZWF0
-ZVRleHROb2RlKCIpIikpfX19fSwKQ0M6ZnVuY3Rpb24oYSxiLGEwKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqLGksaCxnLGYsZSxkLGMKZm9yKHQ9YS5mLHM9dC5sZW5ndGgscj11LnMscT11LlgscD0wO3A8
-dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Ape289dFtwXQpuPWRvY3VtZW50Cm09
-bi5jcmVhdGVFbGVtZW50KCJwIikKbD1xLmEoSC5WTShbInRyYWNlIl0scikpCms9Si5kUihtKQprLlYx
-KDApCmsuRlYoMCxsKQpqPWIuYXBwZW5kQ2hpbGQobSkKbT1uLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQps
-PXEuYShILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHIpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAs
-bCkKbS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKG8uYSkpCmouYXBwZW5kQ2hpbGQobSkKai5h
-cHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKCI6IikpCm09bi5jcmVhdGVFbGVtZW50KCJ1bCIpCmw9
-cS5hKEguVk0oWyJ0cmFjZSJdLHIpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCkKaT1qLmFwcGVu
-ZENoaWxkKG0pCmZvcihtPW8uYixsPW0ubGVuZ3RoLGg9MDtoPG0ubGVuZ3RoO20ubGVuZ3RoPT09bHx8
-KDAsSC5saykobSksKytoKXtnPW1baF0KZj1uLmNyZWF0ZUVsZW1lbnQoImxpIikKSi5sNShmLCImI3gy
-NzRGOyAiKQplPWkuYXBwZW5kQ2hpbGQoZikKZj1uLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpkPXEuYShI
-LlZNKFsiZnVuY3Rpb24iXSxyKSkKaz1KLmRSKGYpCmsuVjEoMCkKay5GVigwLGQpCmQ9Zy5iCmlmKGQ9
-PW51bGwpZD0idW5rbm93biIKZi5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKGQpKQplLmFwcGVu
-ZENoaWxkKGYpCmM9Zy5jCmlmKGMhPW51bGwpe2UuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZSgi
-ICgiKSkKZS5hcHBlbmRDaGlsZChMLmM0KGMsYTApKQplLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5v
-ZGUoIikiKSl9ZS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKCI6ICIpKQplLmFwcGVuZENoaWxk
-KG4uY3JlYXRlVGV4dE5vZGUoZy5hKSl9fX0sCmU6ZnVuY3Rpb24gZSgpe30sClZXOmZ1bmN0aW9uIFZX
-KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6
-ZnVuY3Rpb24ganIoKXt9LApxbDpmdW5jdGlvbiBxbCgpe30sCnk4OmZ1bmN0aW9uIHk4KCl7fSwKTDpm
-dW5jdGlvbiBMKCl7fSwKV3g6ZnVuY3Rpb24gV3goYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFPOmZ1
-bmN0aW9uIEFPKGEpe3RoaXMuYT1hfSwKZE46ZnVuY3Rpb24gZE4oYSl7dGhpcy5hPWF9LApIbzpmdW5j
-dGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6OmZ1bmN0aW9uIHh6KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
-LApJQzpmdW5jdGlvbiBJQygpe30sCkwxOmZ1bmN0aW9uIEwxKCl7fSwKblQ6ZnVuY3Rpb24gblQoYSxi
-LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKQlo6ZnVuY3Rpb24gQlooYSl7dGhpcy5hPWF9
-LApHSDpmdW5jdGlvbiBHSCgpe30sCkRUOmZ1bmN0aW9uIERUKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
-Ygp0aGlzLmM9Y30sCmVIOmZ1bmN0aW9uIGVIKGEpe3RoaXMuYT1hfSwKekQ6ZnVuY3Rpb24gekQoYSxi
-LGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKT0U6ZnVuY3Rp
-b24gT0UoYSl7dGhpcy5hPWF9LApUVzpmdW5jdGlvbiBUVygpe30sCnhyOmZ1bmN0aW9uIHhyKGEpe3Ro
-aXMuYT1hfSwKRUU6ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwK
-UUw6ZnVuY3Rpb24gUUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3Ro
-aXMuYT1hfSwKVEQ6ZnVuY3Rpb24gVEQoKXt9LApYQTpmdW5jdGlvbiBYQSgpe30sCm1LOmZ1bmN0aW9u
-KGEpe3ZhciB0LHMscixxLHAsbyxuPUguVk0oW10sdS5maCkKZm9yKHQ9Si5JVCh1LlIuYShhKSk7dC5G
-KCk7KXtzPXQuZ2woKQpyPUouVTYocykKcT1MLnAyKEguYyhyLnEocywidHlwZSIpKSkKcD1ILmMoci5x
-KHMsIm5hbWUiKSkKbz1yLnEocywic3VidHJlZSIpCm89bz09bnVsbD9udWxsOkwubUsobykKQy5ObS5p
-KG4sbmV3IEwuWloocSxwLG8sSC5jKHIucShzLCJwYXRoIikpLEguYyhyLnEocywiaHJlZiIpKSxILldZ
-KHIucShzLCJlZGl0Q291bnQiKSkpKX1yZXR1cm4gbn0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtj
-YXNlImRpcmVjdG9yeSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRo
-cm93IEguYihQLlBWKCJVbnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILmQo
-YSkpKX19LApaWjpmdW5jdGlvbiBaWihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9Ygpf
-LmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sCk85OmZ1bmN0aW9uIE85KGEpe3RoaXMuYj1hfSwKSVY6ZnVu
-Y3Rpb24gSVYoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LE09ewpZ
-RjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3RoLHM9MTtzPHQ7Kytz
-KXtpZihiW3NdPT1udWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0xO3Q9cil7cj10LTEK
-aWYoYltyXSE9bnVsbClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1wCm89SC5xQyhiLDAs
-dCxILnQ2KGIpLmMpCm49by4kdGkKbj1wK25ldyBILmxKKG8sbi5DKCJxVShhTC5FKSIpLmEobmV3IE0u
-Tm8oKSksbi5DKCJsSjxhTC5FLHFVPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAi
-KyhzLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFko
-cS5aKDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30s
-CnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxYPXsKQ0w6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzLHIscSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktWKGEsby5sZW5n
-dGgpCnQ9dS5zCnM9SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0IT09MCYmYi5y
-NChDLnhCLlcoYSwwKSkpe2lmKDA+PXQpcmV0dXJuIEguayhhLDApCkMuTm0uaShyLGFbMF0pCnE9MX1l
-bHNle0MuTm0uaShyLCIiKQpxPTB9Zm9yKHA9cTtwPHQ7KytwKWlmKGIucjQoQy54Qi5XKGEscCkpKXtD
-Lk5tLmkocyxDLnhCLncoYSxxLHApKQpDLk5tLmkocixhW3BdKQpxPXArMX1pZihxPHQpe0MuTm0uaShz
-LEMueEIuRyhhLHEpKQpDLk5tLmkociwiIil9cmV0dXJuIG5ldyBYLldEKGIsbyxzLHIpfSwKV0Q6ZnVu
-Y3Rpb24gV0QoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9YwpfLmU9ZH0sCnFSOmZ1
-bmN0aW9uIHFSKGEpe3RoaXMuYT1hfSwKSTc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwK
-ZHY6ZnVuY3Rpb24gZHYoYSl7dGhpcy5hPWF9fSxPPXsKUmg6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxw
-LG8sbixtLGwsayxqLGk9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0
-PVAudW8oKQppZighQy54Qi5UYyh0LmdJaSh0KSwiLyIpKXJldHVybiAkLkViKCkKcz1QLlBpKGksMCww
-KQpyPVAuelIoaSwwLDApCnE9UC5PZShpLDAsMCwhMSkKcD1QLmxlKGksMCwwLGkpCm89UC50RyhpLDAs
-MCkKbj1QLndCKGkscykKbT1zPT09ImZpbGUiCmlmKHE9PW51bGwpdD1yLmxlbmd0aCE9PTB8fG4hPW51
-bGx8fG0KZWxzZSB0PSExCmlmKHQpcT0iIgp0PXE9PW51bGwKbD0hdAprPVAua2EoImEvYiIsMCwzLGks
-cyxsKQpqPXMubGVuZ3RoPT09MAppZihqJiZ0JiYhQy54Qi5uKGssIi8iKSlrPVAud0Yoaywhanx8bCkK
-ZWxzZSBrPVAueGUoaykKaWYobmV3IFAuRG4ocyxyLHQmJkMueEIubihrLCIvLyIpPyIiOnEsbixrLHAs
-bykudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlvbiB6
-TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9Y319
-LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5y
-PWR9fSxEPXsKUlg6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9UC51bygpCmlmKEouUk0ociwkLkk2KSlyZXR1
-cm4gJC5GZgokLkk2PXIKaWYoJC5IaygpPT0kLkViKCkpcmV0dXJuICQuRmY9ci5aSSgiLiIpLlooMCkK
-ZWxzZXt0PXIudDQoKQpzPXQubGVuZ3RoLTEKcmV0dXJuICQuRmY9cz09PTA/dDpDLnhCLncodCwwLHMp
-fX0sCm5yOmZ1bmN0aW9uKGEsYil7dmFyIHQ9bnVsbApyZXR1cm4gJC5uVSgpLnE3KDAsYSxiLHQsdCx0
-LHQsdCx0KX19CnZhciB3PVtDLEgsSixQLFcsVSxCLFQsTCxNLFgsTyxFLEYsRF0KaHVua0hlbHBlcnMu
-c2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5KHcpCnZhciAkPXt9CkguRksucHJvdG90eXBlPXt9Ckou
-dkIucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09PWJ9LApnaU86ZnVuY3Rpb24o
-YSl7cmV0dXJuIEguZVEoYSl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILmQo
-SC5saChhKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYShiKQp0aHJvdyBILmIoUC5scihhLGIu
-Z1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
-dXJuIFN0cmluZyhhKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gYT81MTkwMTg6MjE4MTU5fSwKJGlh
-MjoxfQpKLllFLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGw9PWJ9LApaOmZ1
-bmN0aW9uKGEpe3JldHVybiJudWxsIn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCmU3OmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuU2ooYSx1Lm8uYShiKSl9LAokaWM4OjF9CkouTUYucHJvdG90eXBl
-PXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEp
-fSwKJGl2bToxfQpKLmlDLnByb3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17fQpKLmM1LnByb3RvdHlw
-ZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9YVskLndRKCldCmlmKHQ9PW51bGwpcmV0dXJuIHRoaXMudChh
-KQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILmQoSi5BYyh0KSl9LAokUzpmdW5jdGlv
-bigpe3JldHVybntmdW5jOjEsb3B0OlssLCwsLCwsLCwsLCwsLCwsXX19LAokaUVIOjF9CkouamQucHJv
-dG90eXBlPXsKaTpmdW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgp
-SC52aChQLkw0KCJhZGQiKSkKYS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZighIWEu
-Zml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgicmVtb3ZlQXQiKSkKdD1hLmxlbmd0aAppZihiPj10KXRocm93
-IEguYihQLk83KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3RoKUgu
-dmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMubGVu
-Z3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52Zyhh
-LGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1v
-dmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEucG9w
-KCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5hKGIpCmlmKCEhYS5m
-aXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0LkYoKTspYS5wdXNo
-KHQuZ2woKSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoIn4oMSkiKS5hKGIpCnQ9
-YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtiLiQxKGFbc10pCmlmKGEubGVuZ3RoIT09dCl0aHJvdyBI
-LmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgudDYoYSkKcmV0dXJuIG5ldyBI
-LmxKKGEsdC5LcShjKS5DKCIxKDIpIikuYShiKSx0LkMoIkA8MT4iKS5LcShjKS5DKCJsSjwxLDI+Iikp
-fSwKelY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPW5ldyBBcnJheShhLmxlbmd0aCkKcy5maXhlZCRsZW5n
-dGg9QXJyYXkKZm9yKHQ9MDt0PGEubGVuZ3RoOysrdCl0aGlzLlkocyx0LEguZChhW3RdKSkKcmV0dXJu
-IHMuam9pbihiKX0sCk4wOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgpkLmEoYikKSC50NihhKS5L
-cShkKS5DKCIxKDEsMikiKS5hKGMpCnQ9YS5sZW5ndGgKZm9yKHM9YixyPTA7cjx0Oysrcil7cz1jLiQy
-KHMsYVtyXSkKaWYoYS5sZW5ndGghPT10KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4gc30sCkU6ZnVu
-Y3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILmsoYSxiKQpyZXR1cm4gYVtiXX0s
-CkQ2OmZ1bmN0aW9uKGEsYixjKXtpZihiPDB8fGI+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYiwwLGEu
-bGVuZ3RoLCJzdGFydCIsbnVsbCkpCmlmKGM8Ynx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLGIs
-YS5sZW5ndGgsImVuZCIsbnVsbCkpCmlmKGI9PT1jKXJldHVybiBILlZNKFtdLEgudDYoYSkpCnJldHVy
-biBILlZNKGEuc2xpY2UoYixjKSxILnQ2KGEpKX0sCmdyWjpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0
-aAppZih0PjApcmV0dXJuIGFbdC0xXQp0aHJvdyBILmIoSC5XcCgpKX0sCllXOmZ1bmN0aW9uKGEsYixj
-LGQsZSl7dmFyIHQscyxyPUgudDYoYSkKci5DKCJjWDwxPiIpLmEoZCkKaWYoISFhLmltbXV0YWJsZSRs
-aXN0KUgudmgoUC5MNCgic2V0UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnQ9Yy1iCmlmKHQ9PT0w
-KXJldHVybgpQLmsxKGUsInNraXBDb3VudCIpCnIuQygiek08MT4iKS5hKGQpCnI9Si5VNihkKQppZihl
-K3Q+ci5nQShkKSl0aHJvdyBILmIoSC5hcigpKQppZihlPGIpZm9yKHM9dC0xO3M+PTA7LS1zKWFbYitz
-XT1yLnEoZCxlK3MpCmVsc2UgZm9yKHM9MDtzPHQ7KytzKWFbYitzXT1yLnEoZCxlK3MpfSwKdmc6ZnVu
-Y3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZyOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysrcyl7
-aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQo
-YSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0
-KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAu
-V0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0aCxI
-LnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQkbGVu
-Z3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLG51bGws
-Im5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQppZihi
-Pj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlv
-bihhLGIsYyl7SC50NihhKS5jLmEoYykKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgiaW5k
-ZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQphW2JdPWN9
-LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpKLlBvLnByb3RvdHlwZT17fQpKLm0xLnByb3RvdHlwZT17
-CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1z
-LmEscT1yLmxlbmd0aAppZihzLmIhPT1xKXRocm93IEguYihILmxrKHIpKQp0PXMuYwppZih0Pj1xKXtz
-LnNIKG51bGwpCnJldHVybiExfXMuc0goclt0XSk7KytzLmMKcmV0dXJuITB9LApzSDpmdW5jdGlvbihh
-KXt0aGlzLmQ9dGhpcy4kdGkuYy5hKGEpfSwKJGlBbjoxfQpKLnFJLnByb3RvdHlwZT17Cnl1OmZ1bmN0
-aW9uKGEpe3ZhciB0CmlmKGE+PS0yMTQ3NDgzNjQ4JiZhPD0yMTQ3NDgzNjQ3KXJldHVybiBhfDAKaWYo
-aXNGaW5pdGUoYSkpe3Q9YTwwP01hdGguY2VpbChhKTpNYXRoLmZsb29yKGEpCnJldHVybiB0KzB9dGhy
-b3cgSC5iKFAuTDQoIiIrYSsiLnRvSW50KCkiKSl9LAp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEh
-PT0xLzApcmV0dXJuIE1hdGgucm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3Vu
-ZCgwLWEpCnRocm93IEguYihQLkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKRDg6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscQppZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkp
-CnQ9YS50b1N0cmluZyhiKQppZihDLnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14o
-W1xkYS16XSspKD86XC4oW1xkYS16XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwp
-SC52aChQLkw0KCJVbmV4cGVjdGVkIHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigx
-Pj1yKXJldHVybiBILmsocywxKQp0PXNbMV0KaWYoMz49cilyZXR1cm4gSC5rKHMsMykKcT0rc1szXQpy
-PXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0s
-Clo6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9
-LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkx
-MSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgu
-cG93KDIscykKcT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTky
-fDApKyhxKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIp
-e3ZhciB0PWElYgppZih0PT09MClyZXR1cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0
-LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAz
-KGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxi
-KXtpZihiPDApdGhyb3cgSC5iKEguSShiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIGI+MzE/MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLnVyLnByb3RvdHlwZT17
-JGlJZjoxfQpKLlZBLnByb3RvdHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtp
-ZihiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJl
-dHVybiBhLmNoYXJDb2RlQXQoYil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cg
-SC5iKEguSFkoYSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIG5ldyBILk5GKGIsYSwwKX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIp
-dGhyb3cgSC5iKFAuTDMoYixudWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2
-YXIgdD1iLmxlbmd0aCxzPWEubGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhh
-LHMtdCl9LAppNzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzCmM9UC5qQihiLGMsYS5sZW5ndGgpCnQ9
-YS5zdWJzdHJpbmcoMCxiKQpzPWEuc3Vic3RyaW5nKGMpCnJldHVybiB0K2Qrc30sClFpOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdAppZighSC5vayhjKSlILnZoKEguSShjKSkKaWYodHlwZW9mIGMhPT0ibnVtYmVy
-IilyZXR1cm4gYy5KKCkKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0
-aCxudWxsLG51bGwpKQp0PWMrYi5sZW5ndGgKaWYodD5hLmxlbmd0aClyZXR1cm4hMQpyZXR1cm4gYj09
-PWEuc3Vic3RyaW5nKGMsdCl9LApuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUWkoYSxiLDApfSwK
-dzpmdW5jdGlvbihhLGIsYyl7aWYoIUgub2soYikpSC52aChILkkoYikpCmlmKGM9PW51bGwpYz1hLmxl
-bmd0aAppZih0eXBlb2YgYiE9PSJudW1iZXIiKXJldHVybiBiLkooKQppZihiPDApdGhyb3cgSC5iKFAu
-TzcoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGM+YS5sZW5ndGgpdGhy
-b3cgSC5iKFAuTzcoYyxudWxsKSkKcmV0dXJuIGEuc3Vic3RyaW5nKGIsYyl9LApHOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIHRoaXMudyhhLGIsbnVsbCl9LApoYzpmdW5jdGlvbihhKXtyZXR1cm4gYS50b0xvd2Vy
-Q2FzZSgpfSwKYlM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9YS50cmltKCkscD1xLmxlbmd0aAppZihw
-PT09MClyZXR1cm4gcQppZih0aGlzLlcocSwwKT09PTEzMyl7dD1KLm1tKHEsMSkKaWYodD09PXApcmV0
-dXJuIiJ9ZWxzZSB0PTAKcz1wLTEKcj10aGlzLm0ocSxzKT09PTEzMz9KLmMxKHEscyk6cAppZih0PT09
-MCYmcj09PXApcmV0dXJuIHEKcmV0dXJuIHEuc3Vic3RyaW5nKHQscil9LApJeDpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJldHVybiBhCmlm
-KGIhPT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHQ9YSxzPSIiOyEwOyl7aWYoKGImMSk9PT0xKXM9
-dCtzCmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKdCs9dH1yZXR1cm4gc30sClhVOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdAppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGws
-bnVsbCkpCnQ9YS5pbmRleE9mKGIsYykKcmV0dXJuIHR9LApPWTpmdW5jdGlvbihhLGIpe3JldHVybiB0
-aGlzLlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKGM9PW51bGwpYz1hLmxl
-bmd0aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVs
-bCxudWxsKSkKdD1iLmxlbmd0aApzPWEubGVuZ3RoCmlmKGMrdD5zKWM9cy10CnJldHVybiBhLmxhc3RJ
-bmRleE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixudWxsKX0sCklz
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1hLmxlbmd0aAppZihjPnQpdGhyb3cgSC5iKFAuVEUoYywwLHQs
-bnVsbCxudWxsKSkKcmV0dXJuIEgubTIoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
-cy5JcyhhLGIsMCl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0
-LHMscgpmb3IodD1hLmxlbmd0aCxzPTAscj0wO3I8dDsrK3Ipe3M9NTM2ODcwOTExJnMrYS5jaGFyQ29k
-ZUF0KHIpCnM9NTM2ODcwOTExJnMrKCg1MjQyODcmcyk8PDEwKQpzXj1zPj42fXM9NTM2ODcwOTExJnMr
-KCg2NzEwODg2MyZzKTw8MykKc149cz4+MTEKcmV0dXJuIDUzNjg3MDkxMSZzKygoMTYzODMmcyk8PDE1
-KX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILldZKGIp
-CmlmKGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sCiRpdlg6
-MSwKJGlxVToxfQpILnFqLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVu
-Z3RofSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBDLnhCLm0odGhpcy5hLEguV1koYikpfX0KSC5iUS5w
-cm90b3R5cGU9e30KSC5hTC5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwpyZXR1
-cm4gbmV3IEguYTcodCx0LmdBKHQpLEguTGgodCkuQygiYTc8YUwuRT4iKSl9LAp6VjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscixxPXRoaXMscD1xLmdBKHEpCmlmKGIubGVuZ3RoIT09MCl7aWYocD09PTApcmV0
-dXJuIiIKdD1ILmQocS5FKDAsMCkpCmlmKHAhPT1xLmdBKHEpKXRocm93IEguYihQLmE0KHEpKQpmb3Io
-cz10LHI9MTtyPHA7KytyKXtzPXMrYitILmQocS5FKDAscikpCmlmKHAhPT1xLmdBKHEpKXRocm93IEgu
-YihQLmE0KHEpKX1yZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c31lbHNle2ZvcihyPTAscz0iIjty
-PHA7KytyKXtzKz1ILmQocS5FKDAscikpCmlmKHAhPT1xLmdBKHEpKXRocm93IEguYihQLmE0KHEpKX1y
-ZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c319LApldjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
-LkdHKDAsSC5MaCh0aGlzKS5DKCJhMihhTC5FKSIpLmEoYikpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0PUguTGgodGhpcykKcmV0dXJuIG5ldyBILmxKKHRoaXMsdC5LcShjKS5DKCIxKGFMLkUpIikuYShi
-KSx0LkMoIkA8YUwuRT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfX0KSC5uSC5wcm90b3R5cGU9ewpnVUQ6
-ZnVuY3Rpb24oKXt2YXIgdD1KLkgodGhpcy5hKSxzPXRoaXMuYwppZihzPT1udWxsfHxzPnQpcmV0dXJu
-IHQKcmV0dXJuIHN9LApnQXM6ZnVuY3Rpb24oKXt2YXIgdD1KLkgodGhpcy5hKSxzPXRoaXMuYgppZihz
-PnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPUouSCh0aGlzLmEpLHI9
-dGhpcy5iCmlmKHI+PXMpcmV0dXJuIDAKdD10aGlzLmMKaWYodD09bnVsbHx8dD49cylyZXR1cm4gcy1y
-CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSE4oKQpyZXR1cm4gdC1yfSwKRTpmdW5jdGlv
-bihhLGIpe3ZhciB0LHM9dGhpcyxyPXMuZ0FzKCkrYgppZihiPj0wKXt0PXMuZ1VEKCkKaWYodHlwZW9m
-IHQhPT0ibnVtYmVyIilyZXR1cm4gSC5wWSh0KQp0PXI+PXR9ZWxzZSB0PSEwCmlmKHQpdGhyb3cgSC5i
-KFAudChiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQShzLmEscil9fQpILmE3LnByb3Rv
-dHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRo
-aXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQppZihzLmIhPT1wKXRocm93IEguYihQLmE0KHIpKQp0
-PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVybiExfXMuc0kocS5FKHIsdCkpOysrcy5jCnJldHVy
-biEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShhKX0sCiRpQW46MX0KSC5pMS5w
-cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguTUgo
-Si5JVCh0aGlzLmEpLHRoaXMuYix0LkMoIkA8MT4iKS5LcSh0LlFbMV0pLkMoIk1IPDEsMj4iKSl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuYSl9fQpILnh5LnByb3RvdHlwZT17JGliUToxfQpI
-Lk1ILnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5iCmlmKHMuRigpKXt0LnNJ
-KHQuYy4kMShzLmdsKCkpKQpyZXR1cm4hMH10LnNJKG51bGwpCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpcy5hfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5hPXRoaXMuJHRpLlFbMV0uYShhKX19
-CkgubEoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSCh0aGlzLmEpfSwKRTpmdW5j
-dGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90b3R5cGU9
-ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILnZHKEouSVQodGhpcy5hKSx0aGlzLmIsdGhpcy4k
-dGkuQygidkc8MT4iKSl9fQpILnZHLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzCmZvcih0
-PXRoaXMuYSxzPXRoaXMuYjt0LkYoKTspaWYoSC5vVChzLiQxKHQuZ2woKSkpKXJldHVybiEwCnJldHVy
-biExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLmdsKCl9fQpILlNVLnByb3RvdHlwZT17fQpI
-LlJlLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykK
-dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncy
-LnByb3RvdHlwZT17fQpILnd2LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLl9o
-YXNoQ29kZQppZih0IT1udWxsKXJldHVybiB0CnQ9NTM2ODcwOTExJjY2NDU5NypKLmhmKHRoaXMuYSkK
-dGhpcy5faGFzaENvZGU9dApyZXR1cm4gdH0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytI
-LmQodGhpcy5hKSsnIiknfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVy
-biBiIGluc3RhbmNlb2YgSC53diYmdGhpcy5hPT1iLmF9LAokaUdEOjF9CkguUEQucHJvdG90eXBlPXt9
-CkguV1UucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sClk6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5jLmEoYikKdC5RWzFdLmEoYykKcmV0dXJuIEguZGMo
-KX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5xNChhLEguTGgodGhpcykuQygiTjM8MSwyPiIp
-KX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpyZXR1cm4gUC5sMChmdW5jdGlvbigpe3ZhciBz
-PWEKdmFyIHI9MCxxPTEscCxvLG4sbQpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lmKGM9
-PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIpe2Nhc2UgMDpvPXQuZ1YoKSxvPW8uZ2t6KG8p
-LG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZigh
-by5GKCkpe3I9MwpicmVha31tPW8uZ2woKQpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sdC5xKDAsbSksbikK
-Y2FzZSA0OnI9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0ocCl9
-fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90
-b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rp
-b24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0sCnFQOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5jKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
-cSxwPUguTGgodGhpcykKcC5DKCJ+KDEsMikiKS5hKGIpCnQ9dGhpcy5jCmZvcihzPXQubGVuZ3RoLHA9
-cC5RWzFdLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLHAuYSh0aGlzLnFQKHEpKSl9fSwKZ1Y6ZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+IikpfX0KSC5YUi5w
-cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmMKcmV0dXJuIG5ldyBKLm0xKHQs
-dC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
-Yy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQpyZXR1
-cm4gdH0sCmduZDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLmM9PT0xKXJldHVybiBD
-LmhVCnQ9cC5kCnM9dC5sZW5ndGgtcC5lLmxlbmd0aC1wLmYKaWYocz09PTApcmV0dXJuIEMuaFUKcj1b
-XQpmb3IocT0wO3E8czsrK3Epe2lmKHE+PXQubGVuZ3RoKXJldHVybiBILmsodCxxKQpyLnB1c2godFtx
-XSl9cmV0dXJuIEoudW4ocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhp
-cwppZihsLmMhPT0wKXJldHVybiBDLldPCnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1z
-LWwuZgppZihzPT09MClyZXR1cm4gQy5XTwpwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7
-aWYobz49dC5sZW5ndGgpcmV0dXJuIEguayh0LG8pCm49dFtvXQptPXErbwppZihtPDB8fG0+PXIubGVu
-Z3RoKXJldHVybiBILmsocixtKQpwLlkoMCxuZXcgSC53dihuKSxyW21dKX1yZXR1cm4gbmV3IEguUEQo
-cCx1LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0Ckgu
-YyhhKQp0PXRoaXMuYQp0LmI9dC5iKyIkIitILmQoYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5tLmkodGhp
-cy5jLGIpOysrdC5hfSwKJFM6MTN9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyPXRoaXMscT1uZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxsKXJldHVybiBudWxsCnQ9
-T2JqZWN0LmNyZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVudHM9cVtzKzFdCnM9ci5j
-CmlmKHMhPT0tMSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtz
-KzFdCnM9ci5lCmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYocyE9PS0xKXQucmVjZWl2
-ZXI9cVtzKzFdCnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuYgppZih0PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQodGhpcy5hKQpyZXR1
-cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3QrIicgb24gbnVsbCJ9fQpI
-LmF6LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9Ik5vU3VjaE1ldGhvZEVy
-cm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihxPT1udWxsKXJldHVybiJOb1N1Y2hNZXRo
-b2RFcnJvcjogIitILmQocy5hKQp0PXMuYwppZih0PT1udWxsKXJldHVybiByK3ErIicgKCIrSC5kKHMu
-YSkrIikiCnJldHVybiByK3ErIicgb24gJyIrdCsiJyAoIitILmQocy5hKSsiKSJ9fQpILnZWLnByb3Rv
-dHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0Lmxlbmd0aD09PTA/IkVycm9y
-IjoiRXJyb3I6ICIrdH19CkguYnEucHJvdG90eXBlPXt9CkguQW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7aWYodS5XLmIoYSkpaWYoYS4kdGhyb3duSnNFcnJvcj09bnVsbClhLiR0aHJvd25Kc0Vycm9y
-PXRoaXMuYQpyZXR1cm4gYX0sCiRTOjN9CkguWE8ucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIg
-dCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhpcy5hCnQ9cyE9PW51bGwmJnR5cGVvZiBz
-PT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9dD09bnVsbD8iIjp0fSwKJGlHejox
-fQpILlRwLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jb25zdHJ1Y3RvcixzPXQ9
-PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1udWxsPyJ1bmtub3duIjpz
-KSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwKJEM6IiQxIiwKJFI6MSwK
-JEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1cmUgb2YgdW5rbm93biBz
-dGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19CkguankucHJvdG90eXBl
-PXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIp
-cmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5qeSkpcmV0dXJuITEKcmV0dXJuIHQuYT09PWIuYSYm
-dC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmMKaWYocz09
-bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0Ij9KLmhmKHMpOkguZVEo
-cykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpp
-Zih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guZCh0aGlzLmQpKyInIG9mICIrKCJJ
-bnN0YW5jZSBvZiAnIitILmQoSC5saCh0KSkrIiciKX19CkguRXEucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlzLmEpfX0KSC5rWS5wcm90b3R5cGU9ewpa
-OmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AuaCh0aGlzLmEpfX0KSC5ONS5w
-cm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1
-cm4gbmV3IEguaTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFy
-IHQscwppZih0eXBlb2YgYT09InN0cmluZyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0
-dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9dGhpcy5DWChhKQpyZXR1cm4gc319LApDWDpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHQs
-Si5oZihhKSYweDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhp
-cyxvPW51bGwKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PXAuYgppZih0PT1udWxsKXJldHVybiBvCnM9
-cC5qMih0LGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4gcn1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVy
-IiYmKGImMHgzZmZmZmZmKT09PWIpe3E9cC5jCmlmKHE9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHEsYikK
-cj1zPT1udWxsP286cy5iCnJldHVybiByfWVsc2UgcmV0dXJuIHAuYWEoYil9LAphYTpmdW5jdGlvbihh
-KXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD10aGlzLkJ0KHIsSi5oZihh
-KSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0LGEpCmlmKHM8MClyZXR1cm4gbnVsbApyZXR1cm4gdFtzXS5i
-fSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPUguTGgobikKbS5jLmEo
-YikKbS5RWzFdLmEoYykKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PW4uYgpuLkVIKHQ9PW51bGw/bi5i
-PW4ueksoKTp0LGIsYyl9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1i
-KXtzPW4uYwpuLkVIKHM9PW51bGw/bi5jPW4ueksoKTpzLGIsYyl9ZWxzZXtyPW4uZAppZihyPT1udWxs
-KXI9bi5kPW4ueksoKQpxPUouaGYoYikmMHgzZmZmZmZmCnA9bi5CdChyLHEpCmlmKHA9PW51bGwpbi5F
-SShyLHEsW24uSG4oYixjKV0pCmVsc2V7bz1uLkZoKHAsYikKaWYobz49MClwW29dLmI9YwplbHNlIHAu
-cHVzaChuLkhuKGIsYykpfX19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5D
-KCJ+KDEsMikiKS5hKGIpCnQ9ci5lCnM9ci5yCmZvcig7dCE9bnVsbDspe2IuJDIodC5hLHQuYikKaWYo
-cyE9PXIucil0aHJvdyBILmIoUC5hNChyKSkKdD10LmN9fSwKRUg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHM9dGhpcyxyPUguTGgocykKci5jLmEoYikKci5RWzFdLmEoYykKdD1zLmoyKGEsYikKaWYodD09bnVs
-bClzLkVJKGEsYixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlz
-LnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5l
-dyBILmRiKHIuYy5hKGEpLHIuUVsxXS5hKGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7dD1z
-LmYKcS5kPXQKcy5mPXQuYz1xfSsrcy5hCnMua3MoKQpyZXR1cm4gcX0sCkZoOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEou
-Uk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0
-aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19LApCdDpmdW5jdGlvbihhLGIpe3JldHVy
-biBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxiLGMpe2FbYl09Y30sCnJuOmZ1bmN0aW9uKGEsYil7ZGVsZXRl
-IGFbYl19LApYdTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmoyKGEsYikhPW51bGx9LAp6SzpmdW5j
-dGlvbigpe3ZhciB0PSI8bm9uLWlkZW50aWZpZXIta2V5PiIscz1PYmplY3QuY3JlYXRlKG51bGwpCnRo
-aXMuRUkocyx0LHMpCnRoaXMucm4ocyx0KQpyZXR1cm4gc30sCiRpRm86MX0KSC5kYi5wcm90b3R5cGU9
-e30KSC5pNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmF9LApna3o6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9bmV3IEguTjYodCx0LnIsdGhpcy4kdGkuQygiTjY8MT4iKSkK
-cy5jPXQuZQpyZXR1cm4gc319CkguTjYucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmEKaWYodC5iIT09cy5yKXRocm93IEguYihQ
-LmE0KHMpKQplbHNle3M9dC5jCmlmKHM9PW51bGwpe3Quc3FZKG51bGwpCnJldHVybiExfWVsc2V7dC5z
-cVkocy5hKQp0LmM9dC5jLmMKcmV0dXJuITB9fX0sCnNxWTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4k
-dGkuYy5hKGEpfSwKJGlBbjoxfQpILnIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYShhKX0sCiRTOjN9CkguZEMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
-cy5hKGEsYil9LAokUzozOH0KSC53Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5hKEguYyhhKSl9LAokUzozN30KSC5WUi5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJS
-ZWdFeHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMs
-cz10LmMKaWYocyE9bnVsbClyZXR1cm4gcwpzPXQuYgpyZXR1cm4gdC5jPUgudjQodC5hLHMubXVsdGls
-aW5lLCFzLmlnbm9yZUNhc2Uscy51bmljb2RlLHMuZG90QWxsLCEwKX0sCmRkOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmdI
-YygpCnMubGFzdEluZGV4PWIKdD1zLmV4ZWMoYSkKaWYodD09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4g
-bmV3IEguRUsodCl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQKSC5XWShiKQp0PXRoaXMuYgppZihiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKcmV0
-dXJuIHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguUGIucHJvdG90eXBlPXsKZ2w6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxv
-PXAuYgppZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8ubGVuZ3RoKXtzPXAuYQpyPXMuVVoo
-byx0KQppZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgKcT10K29bMF0ubGVuZ3RoCmlmKHQ9
-PT1xKXtpZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIKaWYodDxzLmxlbmd0aCl7bz1KLnJZ
-KHMpLm0ocyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54Qi5tKHMsdCkKbz1vPj01NjMyMCYm
-bzw9NTczNDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEKcT0obz9xKzE6cSkrMX1wLmM9cQpy
-ZXR1cm4hMH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnByb3RvdHlwZT17CnE6
-ZnVuY3Rpb24oYSxiKXtILldZKGIpCmlmKGIhPT0wKUgudmgoUC5PNyhiLG51bGwpKQpyZXR1cm4gdGhp
-cy5jfSwKJGlPZDoxfQpILk5GLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgu
-U2QodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5TZC5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFy
-IHQscyxyPXRoaXMscT1yLmMscD1yLmIsbz1wLmxlbmd0aCxuPXIuYSxtPW4ubGVuZ3RoCmlmKHErbz5t
-KXtyLmQ9bnVsbApyZXR1cm4hMX10PW4uaW5kZXhPZihwLHEpCmlmKHQ8MCl7ci5jPW0rMQpyLmQ9bnVs
-bApyZXR1cm4hMX1zPXQrbwpyLmQ9bmV3IEgudFEodCxwKQpyLmM9cz09PXIuYz9zKzE6cwpyZXR1cm4h
-MH0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCiRpQW46MX0KSC5wRi5wcm90b3R5cGU9eyRp
-cEY6MSwkaUFTOjF9CkguYjAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
-fSwKJGlYajoxfQpILkRnLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixh
-LGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0guZGooYykKSC5vZChiLGEs
-YS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsK
-WTpmdW5jdGlvbihhLGIsYyl7SC5XWShjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUTox
-LAokaWNYOjEsCiRpek06MX0KSC54ai5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpI
-Lm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmRFLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24o
-YSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguWkEucHJvdG90eXBl
-PXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0K
-SC53Zi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkK
-cmV0dXJuIGFbYl19fQpILlBxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2Qo
-YixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZUUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgp
-CnJldHVybiBhW2JdfX0KSC5WNi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
-dGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19
-LAokaVY2OjEsCiRpbjY6MX0KSC5SRy5wcm90b3R5cGU9e30KSC5WUC5wcm90b3R5cGU9e30KSC5XQi5w
-cm90b3R5cGU9e30KSC5aRy5wcm90b3R5cGU9e30KSC5KYy5wcm90b3R5cGU9ewpDOmZ1bmN0aW9uKGEp
-e3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9LApLcTpmdW5jdGlvbihhKXtyZXR1cm4g
-SC52NSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfX0KSC5FVC5wcm90b3R5cGU9e30KSC51OS5wcm90b3R5
-cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9fQpILngucHJvdG90eXBlPXt9ClAudGgucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9dC5hCnQuYT1udWxsCnMuJDAoKX0s
-CiRTOjEyfQpQLmhhLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdGhpcy5hLmE9dS5N
-LmEoYSkKdD10aGlzLmIKcz10aGlzLmMKdC5maXJzdENoaWxkP3QucmVtb3ZlQ2hpbGQocyk6dC5hcHBl
-bmRDaGlsZChzKX0sCiRTOjIwfQpQLlZzLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLiQw
-KCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLkZ0LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhp
-cy5hLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLlczLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9u
-KGEsYil7aWYoc2VsZi5zZXRUaW1lb3V0IT1udWxsKXNlbGYuc2V0VGltZW91dChILnRSKG5ldyBQLnlI
-KHRoaXMsYiksMCksYSkKZWxzZSB0aHJvdyBILmIoUC5MNCgiYHNldFRpbWVvdXQoKWAgbm90IGZvdW5k
-LiIpKX19ClAueUgucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmIuJDAoKX0sCiRDOiIkMCIs
-CiRSOjAsCiRTOjJ9ClAuaWgucHJvdG90eXBlPXsKYU06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhp
-cy4kdGkKci5DKCIxLyIpLmEoYikKdD0hdGhpcy5ifHxyLkMoImI4PDE+IikuYihiKQpzPXRoaXMuYQpp
-Zih0KXMuWGYoYikKZWxzZSBzLlgyKHIuYy5hKGIpKX0sCncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYo
-Yj09bnVsbCliPVAudjAoYSkKdD10aGlzLmEKaWYodGhpcy5iKXQuWkwoYSxiKQplbHNlIHQuTmsoYSxi
-KX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwK
-JFM6NDd9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5i
-cShhLHUubC5hKGIpKSl9LAokQzoiJDIiLAokUjoyLAokUzoyMX0KUC5Hcy5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe3RoaXMuYShILldZKGEpLGIpfSwKJFM6MjZ9ClAuRnkucHJvdG90eXBlPXsKWjpm
-dW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5kKHRoaXMuYSkr
-IikifX0KUC5HVi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYwppZih0PT1udWxs
-KXJldHVybiB0aGlzLmIKcmV0dXJuIHRoaXMuJHRpLmMuYSh0LmdsKCkpfSwKRjpmdW5jdGlvbigpe3Zh
-ciB0LHMscixxLHA9dGhpcwpmb3IoOyEwOyl7dD1wLmMKaWYodCE9bnVsbClpZih0LkYoKSlyZXR1cm4h
-MAplbHNlIHAuYz1udWxsCnM9ZnVuY3Rpb24oYSxiLGMpe3ZhciBvLG49Ygp3aGlsZSh0cnVlKXRyeXty
-ZXR1cm4gYShuLG8pfWNhdGNoKG0pe289bQpuPWN9fShwLmEsMCwxKQppZihzIGluc3RhbmNlb2YgUC5G
-eSl7cj1zLmIKaWYocj09PTIpe3Q9cC5kCmlmKHQ9PW51bGx8fHQubGVuZ3RoPT09MCl7cC5zRUMobnVs
-bCkKcmV0dXJuITF9aWYoMD49dC5sZW5ndGgpcmV0dXJuIEguayh0LC0xKQpwLmE9dC5wb3AoKQpjb250
-aW51ZX1lbHNle3Q9cy5hCmlmKHI9PT0zKXRocm93IHQKZWxzZXtxPUouSVQodCkKaWYocSBpbnN0YW5j
-ZW9mIFAuR1Ype3Q9cC5kCmlmKHQ9PW51bGwpdD1wLmQ9W10KQy5ObS5pKHQscC5hKQpwLmE9cS5hCmNv
-bnRpbnVlfWVsc2V7cC5jPXEKY29udGludWV9fX19ZWxzZXtwLnNFQyhzKQpyZXR1cm4hMH19cmV0dXJu
-ITF9LApzRUM6ZnVuY3Rpb24oYSl7dGhpcy5iPXRoaXMuJHRpLmMuYShhKX0sCiRpQW46MX0KUC5xNC5w
-cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkdWKHRoaXMuYSgpLHRoaXMuJHRp
-LkMoIkdWPDE+IikpfX0KUC5iOC5wcm90b3R5cGU9e30KUC5QZi5wcm90b3R5cGU9ewp3MDpmdW5jdGlv
-bihhLGIpe3ZhciB0ClAuVUkoYSwiZXJyb3IiLHUuSykKdD10aGlzLmEKaWYodC5hIT09MCl0aHJvdyBI
-LmIoUC5QVigiRnV0dXJlIGFscmVhZHkgY29tcGxldGVkIikpCnQuTmsoYSxiPT1udWxsP1AudjAoYSk6
-Yil9LApwbTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5cGU9
-ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0CnRoaXMuJHRpLkMoIjEvIikuYShiKQp0PXRoaXMuYQppZih0
-LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5YZihiKX19
-ClAuRmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYxNSkhPT02KXJldHVybiEw
-CnJldHVybiB0aGlzLmIuYi5idih1LmFsLmEodGhpcy5kKSxhLmEsdS55LHUuSyl9LApLdzpmdW5jdGlv
-bihhKXt2YXIgdD10aGlzLmUscz11Lnoscj11LksscT10aGlzLiR0aS5DKCIyLyIpLHA9dGhpcy5iLmIK
-aWYodS5hZy5iKHQpKXJldHVybiBxLmEocC5ycCh0LGEuYSxhLmIscyxyLHUubCkpCmVsc2UgcmV0dXJu
-IHEuYShwLmJ2KHUuRi5hKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5hKGEpCnQ9JC5YMwpp
-Zih0IT09Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHEuYykuQygiMSgyKSIpLmEoYSkKaWYoYiE9bnVsbCli
-PVAuVkgoYix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRoaXMu
-eGYobmV3IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4g
-c30sClc3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIpLmEoYSkKdD1uZXcgUC52cygk
-LlgzLGMuQygidnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LDE5LGEsYixzLkMoIkA8MT4iKS5LcShj
-KS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gdH0sCk9BOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmJmLmEo
-bnVsbCkKdD10aGlzLiR0aQpzPSQuWDMKcj1uZXcgUC52cyhzLHQpCmlmKHMhPT1DLk5VKWE9UC5WSChh
-LHMpCnRoaXMueGYobmV3IFAuRmUociwyLG51bGwsYSx0LkMoIkA8MT4iKS5LcSh0LmMpLkMoIkZlPDEs
-Mj4iKSkpCnJldHVybiByfSwKeGY6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9cy5hCmlmKHI8PTEp
-e2EuYT11LnguYShzLmMpCnMuYz1hfWVsc2V7aWYocj09PTIpe3Q9dS5fLmEocy5jKQpyPXQuYQppZihy
-PDQpe3QueGYoYSkKcmV0dXJufXMuYT1yCnMuYz10LmN9UC5UayhudWxsLG51bGwscy5iLHUuTS5hKG5l
-dyBQLmRhKHMsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89dGhpcyxuPXt9Cm4u
-YT1hCmlmKGE9PW51bGwpcmV0dXJuCnQ9by5hCmlmKHQ8PTEpe3M9dS54LmEoby5jKQpyPW8uYz1hCmlm
-KHMhPW51bGwpe2Zvcig7cT1yLmEscSE9bnVsbDtyPXEpO3IuYT1zfX1lbHNle2lmKHQ9PT0yKXtwPXUu
-Xy5hKG8uYykKdD1wLmEKaWYodDw0KXtwLmpRKGEpCnJldHVybn1vLmE9dApvLmM9cC5jfW4uYT1vLk44
-KGEpClAuVGsobnVsbCxudWxsLG8uYix1Lk0uYShuZXcgUC5vUShuLG8pKSl9fSwKYWg6ZnVuY3Rpb24o
-KXt2YXIgdD11LnguYSh0aGlzLmMpCnRoaXMuYz1udWxsCnJldHVybiB0aGlzLk44KHQpfSwKTjg6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEscz1udWxsO3QhPW51bGw7cz10LHQ9cil7cj10LmEKdC5h
-PXN9cmV0dXJuIHN9LApISDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLiR0aQpyLkMoIjEvIiku
-YShhKQppZihyLkMoImI4PDE+IikuYihhKSlpZihyLmIoYSkpUC5BOShhLHMpCmVsc2UgUC5rMyhhLHMp
-CmVsc2V7dD1zLmFoKCkKci5jLmEoYSkKcy5hPTQKcy5jPWEKUC5IWihzLHQpfX0sClgyOmZ1bmN0aW9u
-KGEpe3ZhciB0LHM9dGhpcwpzLiR0aS5jLmEoYSkKdD1zLmFoKCkKcy5hPTQKcy5jPWEKUC5IWihzLHQp
-fSwKWkw6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwp1LmwuYShiKQp0PXIuYWgoKQpzPVAuVGwo
-YSxiKQpyLmE9OApyLmM9cwpQLkhaKHIsdCl9LApYZjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9dC4k
-dGkKcy5DKCIxLyIpLmEoYSkKaWYocy5DKCJiODwxPiIpLmIoYSkpe3QuY1UoYSkKcmV0dXJufXQuYT0x
-ClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYShuZXcgUC5ySCh0LGEpKSl9LApjVTpmdW5jdGlvbihhKXt2
-YXIgdD10aGlzLHM9dC4kdGkKcy5DKCJiODwxPiIpLmEoYSkKaWYocy5iKGEpKXtpZihhLmE9PT04KXt0
-LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmEobmV3IFAuS0YodCxhKSkpfWVsc2UgUC5BOShhLHQp
-CnJldHVybn1QLmszKGEsdCl9LApOazpmdW5jdGlvbihhLGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxs
-LHRoaXMuYix1Lk0uYShuZXcgUC5aTCh0aGlzLGEsYikpKX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9
-ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5hLHRoaXMuYil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17
-CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIsdGhpcy5hLmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9
-ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKdC5hPTAKdC5ISChhKX0sCiRTOjEyfQpQLlU3LnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dS5sLmEoYikKdGhpcy5hLlpMKGEsYil9LAokMTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJEM6IiQyIiwKJEQ6ZnVuY3Rpb24oKXtyZXR1
-cm5bbnVsbF19LAokUzozMH0KUC52ci5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0
-aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuckgucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdD10
-aGlzLmEKdC5YMih0LiR0aS5jLmEodGhpcy5iKSl9LAokUzowfQpQLktGLnByb3RvdHlwZT17CiQwOmZ1
-bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwucHJvdG90eXBlPXsKJDA6ZnVu
-Y3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLlJULnByb3RvdHlwZT17CiQw
-OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPW51bGwKdHJ5e3I9bi5jCm09ci5iLmIu
-enoodS5mTy5hKHIuZCksdS56KX1jYXRjaChxKXt0PUguUnUocSkKcz1ILnRzKHEpCmlmKG4uZCl7cj11
-Lm4uYShuLmEuYS5jKS5hCnA9dApwPXI9PW51bGw/cD09bnVsbDpyPT09cApyPXB9ZWxzZSByPSExCnA9
-bi5iCmlmKHIpcC5iPXUubi5hKG4uYS5hLmMpCmVsc2UgcC5iPVAuVGwodCxzKQpwLmE9ITAKcmV0dXJu
-fWlmKHUuYy5iKG0pKXtpZihtIGluc3RhbmNlb2YgUC52cyYmbS5hPj00KXtpZihtLmE9PT04KXtyPW4u
-YgpyLmI9dS5uLmEobS5jKQpyLmE9ITB9cmV0dXJufW89bi5hLmEKcj1uLmIKci5iPW0uVzcobmV3IFAu
-aloobyksdS56KQpyLmE9ITF9fSwKJFM6Mn0KUC5qWi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hfSwKJFM6MzN9ClAucnEucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxz
-LHIscSxwLG8sbixtPXRoaXMKdHJ5e3I9bS5iCnE9ci4kdGkKcD1xLmMKbz1wLmEobS5jKQptLmEuYj1y
-LmIuYi5idihxLkMoIjIvKDEpIikuYShyLmQpLG8scS5DKCIyLyIpLHApfWNhdGNoKG4pe3Q9SC5SdShu
-KQpzPUgudHMobikKcj1tLmEKci5iPVAuVGwodCxzKQpyLmE9ITB9fSwKJFM6Mn0KUC5SVy5wcm90b3R5
-cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCnRyeXt0PXUubi5hKGwu
-YS5hLmMpCnE9bC5jCmlmKEgub1QocS5IUih0KSkmJnEuZSE9bnVsbCl7cD1sLmIKcC5iPXEuS3codCkK
-cC5hPSExfX1jYXRjaChvKXtzPUguUnUobykKcj1ILnRzKG8pCnE9dS5uLmEobC5hLmEuYykKcD1xLmEK
-bj1zCm09bC5iCmlmKHA9PW51bGw/bj09bnVsbDpwPT09biltLmI9cQplbHNlIG0uYj1QLlRsKHMscikK
-bS5hPSEwfX0sCiRTOjJ9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQLnZzKCQuWDMsdS5mSikKcS5hPTAKdD1ILkxo
-KHIpCnM9dC5DKCJ+KDEpIikuYShuZXcgUC5CNShxLHIpKQp1Lk0uYShuZXcgUC5QSShxLHApKQpXLkpF
-KHIuYSxyLmIscywhMSx0LmMpCnJldHVybiBwfX0KUC5CNS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXtILkxoKHRoaXMuYikuYy5hKGEpOysrdGhpcy5hLmF9LAokUzpmdW5jdGlvbigpe3JldHVybiBILkxo
-KHRoaXMuYikuQygiYzgoMSkiKX19ClAuUEkucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmIu
-SEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5rVC5wcm90b3R5cGU9e30KUC54
-SS5wcm90b3R5cGU9e30KUC5PSC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBILmQodGhp
-cy5hKX0sCiRpWFM6MSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYn19ClAubTAucHJvdG90eXBl
-PXskaUpCOjF9ClAucEsucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMuYSxyPXMu
-YgppZihyPT1udWxsKXRocm93IEguYihzLmEpCnQ9SC5iKHMuYSkKdC5zdGFjaz1yLlooMCkKdGhyb3cg
-dH0sCiRTOjB9ClAuSmkucHJvdG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9bnVsbAp1
-Lk0uYShhKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDAoKQpyZXR1cm59UC5UOChxLHEsdGhpcyxhLHUu
-SCl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0aGlzLHQsdS5sLmEocykpfX0s
-CkRsOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIp
-CnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMShiKQpyZXR1cm59UC55dihxLHEsdGhpcyxhLGIsdS5ILGMp
-fWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5MMihxLHEsdGhpcyx0LHUubC5hKHMpKX19LApS
-VDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5oaih0aGlzLGIuQygiMCgpIikuYShhKSxiKX0sCkdZ
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5WcCh0aGlzLHUuTS5hKGEpKX0sClB5OmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIG5ldyBQLk9SKHRoaXMsYi5DKCJ+KDApIikuYShhKSxiKX0sCnE6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbnVsbH0sCnp6OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5hKGEpCmlmKCQuWDM9PT1D
-Lk5VKXJldHVybiBhLiQwKCkKcmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0
-aW9uKGEsYixjLGQpe2MuQygiQDwwPiIpLktxKGQpLkMoIjEoMikiKS5hKGEpCmQuYShiKQppZigkLlgz
-PT09Qy5OVSlyZXR1cm4gYS4kMShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0s
-CnJwOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMyki
-KS5hKGEpCmUuYShiKQpmLmEoYykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4g
-UC5ReChudWxsLG51bGwsdGhpcyxhLGIsYyxkLGUsZil9LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1
-cm4gYi5DKCJAPDA+IikuS3EoYykuS3EoZCkuQygiMSgyLDMpIikuYShhKX19ClAuaGoucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5jLkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e3JldHVybiB0aGlzLmEuYkgodGhpcy5iKX0sCiRTOjJ9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHQuYShhKSx0KX0sCiRTOmZ1
-bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdrejpmdW5j
-dGlvbihhKXt2YXIgdD10aGlzLHM9bmV3IFAubG0odCx0LnIsSC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9
-dC5lCnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD10aGlzLmIK
-aWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5KLmEodFtiXSkhPW51bGx9ZWxzZXtzPXRoaXMuUFIo
-YikKcmV0dXJuIHN9fSwKUFI6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJu
-ITEKcmV0dXJuIHRoaXMuREYodFt0aGlzLk4oYSldLGEpPj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscj10aGlzCkguTGgocikuYy5hKGIpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3Rv
-X18iKXt0PXIuYgpyZXR1cm4gci5TKHQ9PW51bGw/ci5iPVAuVDIoKTp0LGIpfWVsc2UgaWYodHlwZW9m
-IGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3M9ci5jCnJldHVybiByLlMocz09bnVsbD9y
-LmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhiKX0sCkI3OmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cixxPXRoaXMKSC5MaChxKS5jLmEoYSkKdD1xLmQKaWYodD09bnVsbCl0PXEuZD1QLlQyKCkKcz1xLk4o
-YSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhhKV0KZWxzZXtpZihxLkRGKHIsYSk+PTApcmV0
-dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMK
-aWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpcmV0dXJuIHQuSDQodC5iLGIpCmVs
-c2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHQuSDQodC5j
-LGIpCmVsc2UgcmV0dXJuIHQucWcoYil9LApxZzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPXRoaXMs
-bz1wLmQKaWYobz09bnVsbClyZXR1cm4hMQp0PXAuTihhKQpzPW9bdF0Kcj1wLkRGKHMsYSkKaWYocjww
-KXJldHVybiExCnE9cy5zcGxpY2UociwxKVswXQppZigwPT09cy5sZW5ndGgpZGVsZXRlIG9bdF0KcC5H
-UyhxKQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih1LkouYShh
-W2JdKSE9bnVsbClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJuITB9LApINDpmdW5jdGlvbihh
-LGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuITEKdD11LkouYShhW2JdKQppZih0PT1udWxsKXJldHVy
-biExCnRoaXMuR1ModCkKZGVsZXRlIGFbYl0KcmV0dXJuITB9LApYOmZ1bmN0aW9uKCl7dGhpcy5yPTEw
-NzM3NDE4MjMmdGhpcy5yKzF9LAp5bzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1uZXcgUC5ibihI
-LkxoKHMpLmMuYShhKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cgplbHNle3Q9cy5mCnIuYz10CnMuZj10
-LmI9cn0rK3MuYQpzLlgoKQpyZXR1cm4gcn0sCkdTOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hLmMs
-cj1hLmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMuYj1yCmlmKHI9PW51bGwpdC5mPXMKZWxzZSByLmM9
-czstLXQuYQp0LlgoKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sCkRG
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9
-MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfX0KUC5ibi5wcm90b3R5
-cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0
-aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIpdGhyb3cgSC5iKFAuYTQocykpCmVsc2V7
-cz10LmMKaWYocz09bnVsbCl7dC5zaihudWxsKQpyZXR1cm4hMX1lbHNle3Quc2oodC4kdGkuYy5hKHMu
-YSkpCnQuYz10LmMuYgpyZXR1cm4hMH19fSwKc2o6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMu
-YShhKX0sCiRpQW46MX0KUC5tVy5wcm90b3R5cGU9e30KUC5MVS5wcm90b3R5cGU9eyRpYlE6MSwkaWNY
-OjEsJGl6TToxfQpQLmxELnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguYTco
-YSx0aGlzLmdBKGEpLEgucShhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-dGhpcy5xKGEsYil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnEoYSkuQygifihsRC5FKSIpLmEo
-YikKdD10aGlzLmdBKGEpCmZvcihzPTA7czx0Oysrcyl7Yi4kMSh0aGlzLnEoYSxzKSkKaWYodCE9PXRo
-aXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnEo
-YSkKcmV0dXJuIG5ldyBILmxKKGEsdC5LcShjKS5DKCIxKGxELkUpIikuYShiKSx0LkMoIkA8bEQuRT4i
-KS5LcShjKS5DKCJsSjwxLDI+IikpfSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKSC5xKGEpLkMo
-ImxELkUiKS5hKGQpClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcih0PWI7dDxjOysrdCl0aGlzLlkoYSx0
-LGQpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90b3R5cGU9
-e30KUC5yYS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5hCmlmKCFzLmEp
-dGhpcy5iLmErPSIsICIKcy5hPSExCnM9dGhpcy5iCnQ9cy5hKz1ILmQoYSkKcy5hPXQrIjogIgpzLmEr
-PUguZChiKX0sCiRTOjF9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC5M
-aCh0aGlzKS5DKCJ+KFlrLkssWWsuVikiKS5hKGIpCmZvcih0PUouSVQodGhpcy5nVigpKTt0LkYoKTsp
-e3M9dC5nbCgpCmIuJDIocyx0aGlzLnEoMCxzKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0x
-KHRoaXMuZ1YoKSxuZXcgUC55USh0aGlzKSxILkxoKHRoaXMpLkMoIk4zPFlrLkssWWsuVj4iKSl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuZ1YoKSl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBQ
-Lm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuYSxzPUguTGgodCkKcy5DKCJZay5LIikuYShhKQpyZXR1cm4gbmV3IFAuTjMoYSx0LnEoMCxhKSxz
-LkMoIkA8WWsuSz4iKS5LcShzLkMoIllrLlYiKSkuQygiTjM8MSwyPiIpKX0sCiRTOmZ1bmN0aW9uKCl7
-cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5LLFlrLlY+KFlrLkspIil9fQpQLktQLnByb3RvdHlw
-ZT17Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5jLmEoYikKdC5RWzFdLmEoYykK
-dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1hcCIpKX19ClAuUG4ucHJv
-dG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIpfSwKWTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHQuYy5hKGIpLHQuUVsxXS5hKGMpKX0sCks6
-ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYShiKSl9LApnQTpm
-dW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LApaOmZ1bmN0aW9uKGEpe3JldHVy
-biBKLkFjKHRoaXMuYSl9LApnUHU6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdQdSh0
-KX0sCiRpWjA6MX0KUC5Hai5wcm90b3R5cGU9e30KUC5NYS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEp
-e3JldHVybiBQLldFKHRoaXMsInsiLCJ9Iil9fQpQLlZqLnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwk
-aXh1OjF9ClAuWHYucHJvdG90eXBlPXsKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD1KLklUKEgu
-TGgodGhpcykuQygiY1g8MT4iKS5hKGIpKTt0LkYoKTspdGhpcy5pKDAsdC5nbCgpKX0sClo6ZnVuY3Rp
-b24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0iKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1Q
-LnJqKHRoaXMsdGhpcy5yLEguTGgodGhpcykuYykKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7
-dD0iIgpkbyB0Kz1ILmQocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7
-KXQ9dCtiK0guZChzLmQpfXJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNY
-OjEsCiRpeHU6MX0KUC5uWS5wcm90b3R5cGU9e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5
-cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09
-bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4g
-bnVsbAplbHNle3Q9c1tiXQpyZXR1cm4gdHlwZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19
-LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5n
-dGh9LApnVjpmdW5jdGlvbigpe2lmKHRoaXMuYj09bnVsbCl7dmFyIHQ9dGhpcy5jCnJldHVybiBuZXcg
-SC5pNSh0LEguTGgodCkuQygiaTU8MT4iKSl9cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyPXRoaXMKaWYoci5iPT1udWxsKXIuYy5ZKDAsYixjKQplbHNlIGlmKHIu
-eDQoYikpe3Q9ci5iCnRbYl09YwpzPXIuYQppZihzPT1udWxsP3QhPW51bGw6cyE9PXQpc1tiXT1udWxs
-fWVsc2Ugci5YSygpLlkoMCxiLGMpfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodGhpcy5iPT1udWxsKXJldHVy
-biB0aGlzLmMueDQoYSkKcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0
-aGlzLmEsYSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzCnUuY0EuYShiKQppZihw
-LmI9PW51bGwpcmV0dXJuIHAuYy5LKDAsYikKdD1wLkNmKCkKZm9yKHM9MDtzPHQubGVuZ3RoOysrcyl7
-cj10W3NdCnE9cC5iW3JdCmlmKHR5cGVvZiBxPT0idW5kZWZpbmVkIil7cT1QLlFlKHAuYVtyXSkKcC5i
-W3JdPXF9Yi4kMihyLHEpCmlmKHQhPT1wLmMpdGhyb3cgSC5iKFAuYTQocCkpfX0sCkNmOmZ1bmN0aW9u
-KCl7dmFyIHQ9dS5qLmEodGhpcy5jKQppZih0PT1udWxsKXQ9dGhpcy5jPUguVk0oT2JqZWN0LmtleXMo
-dGhpcy5hKSx1LnMpCnJldHVybiB0fSwKWEs6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG89dGhpcwpp
-ZihvLmI9PW51bGwpcmV0dXJuIG8uYwp0PVAuRmwodS5OLHUueikKcz1vLkNmKCkKZm9yKHI9MDtxPXMu
-bGVuZ3RoLHI8cTsrK3Ipe3A9c1tyXQp0LlkoMCxwLG8ucSgwLHApKX1pZihxPT09MClDLk5tLmkocyxu
-dWxsKQplbHNlIEMuTm0uc0EocywwKQpvLmE9by5iPW51bGwKcmV0dXJuIG8uYz10fSwKZmI6ZnVuY3Rp
-b24oYSl7dmFyIHQKaWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEs
-YSkpcmV0dXJuIG51bGwKdD1QLlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT10fX0KUC5pOC5w
-cm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LApFOmZ1
-bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hCmlmKHQuYj09bnVsbCl0PXQuZ1YoKS5FKDAsYikKZWxzZXt0
-PXQuQ2YoKQppZihiPDB8fGI+PXQubGVuZ3RoKXJldHVybiBILmsodCxiKQp0PXRbYl19cmV0dXJuIHR9
-LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQuYj09bnVsbCl7dD10LmdWKCkKdD10Lmdr
-eih0KX1lbHNle3Q9dC5DZigpCnQ9bmV3IEoubTEodCx0Lmxlbmd0aCxILnQ2KHQpLkMoIm0xPDE+Iikp
-fXJldHVybiB0fX0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlvbihhLGEwLGExKXt2YXIgdCxzLHIs
-cSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYj0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVu
-Z3RoICIKYTE9UC5qQihhMCxhMSxhLmxlbmd0aCkKdD0kLlY3KCkKZm9yKHM9YTAscj1zLHE9bnVsbCxw
-PS0xLG89LTEsbj0wO3M8YTE7cz1tKXttPXMrMQpsPUMueEIuVyhhLHMpCmlmKGw9PT0zNyl7az1tKzIK
-aWYoazw9YTEpe2o9SC5vbyhDLnhCLlcoYSxtKSkKaT1ILm9vKEMueEIuVyhhLG0rMSkpCmg9aioxNitp
-LShpJjI1NikKaWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1lbHNlIGg9bAppZigwPD1oJiZoPD0x
-Mjcpe2lmKGg8MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguayh0LGgpCmc9dFtoXQppZihnPj0wKXtoPUMu
-eEIubSgiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx
-MjM0NTY3ODkrLyIsZykKaWYoaD09PWwpY29udGludWUKbD1ofWVsc2V7aWYoZz09PS0xKXtpZihwPDAp
-e2Y9cT09bnVsbD9udWxsOnEuYS5sZW5ndGgKaWYoZj09bnVsbClmPTAKcD1mKyhzLXIpCm89c30rK24K
-aWYobD09PTYxKWNvbnRpbnVlfWw9aH1pZihnIT09LTIpe2lmKHE9PW51bGwpcT1uZXcgUC5SbigiIikK
-cS5hKz1DLnhCLncoYSxyLHMpCnEuYSs9SC5MdyhsKQpyPW0KY29udGludWV9fXRocm93IEguYihQLnJy
-KCJJbnZhbGlkIGJhc2U2NCBkYXRhIixhLHMpKX1pZihxIT1udWxsKXtmPXEuYSs9Qy54Qi53KGEscixh
-MSkKZT1mLmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEs
-NCkrMQppZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9
-ZjsrK2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9
-Yz1hMS1hMAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9
-PT0xKXRocm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8i
-PT0iOiI9Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJ
-LnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdAp1LmVwLmEoYykKdD1QLkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4gdH0sCmdI
-ZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90b3R5cGU9e30KUC51NS5wcm90b3R5cGU9
-ewpnWkU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxxPXItMAppZihxPT09MClyZXR1cm4gbmV3
-IFVpbnQ4QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMpCnM9bmV3IFAuUncodCkKaWYocy5HeChh
-LDAscikhPT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJuIG5ldyBVaW50OEFycmF5KHQuc3ViYXJy
-YXkoMCxILnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpPNjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxvPXIubGVuZ3RoCmlmKChiJjY0NTEyKT09
-PTU2MzIwKXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpzLmI9cAppZihxPj1vKXJldHVybiBI
-LmsocixxKQpyW3FdPTI0MHx0Pj4+MTgKcT1zLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguayhyLHApCnJb
-cF09MTI4fHQ+Pj4xMiY2MwpwPXMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0xMjh8
-dD4+PjYmNjMKcy5iPXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHx0JjYzCnJldHVy
-biEwfWVsc2V7cy5iPXAKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0yMjR8YT4+PjEyCnE9cy5i
-PXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHxhPj4+NiY2MwpzLmI9cSsxCmlmKHE+
-PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MTI4fGEmNjMKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcwppZihiIT09YyYmKEMueEIubShhLGMtMSkmNjQ1MTIp
-PT09NTUyOTYpLS1jCmZvcih0PW0uYyxzPXQubGVuZ3RoLHI9YjtyPGM7KytyKXtxPUMueEIuVyhhLHIp
-CmlmKHE8PTEyNyl7cD1tLmIKaWYocD49cylicmVhawptLmI9cCsxCnRbcF09cX1lbHNlIGlmKChxJjY0
-NTEyKT09PTU1Mjk2KXtpZihtLmIrMz49cylicmVhawpvPXIrMQppZihtLk82KHEsQy54Qi5XKGEsbykp
-KXI9b31lbHNlIGlmKHE8PTIwNDcpe3A9bS5iCm49cCsxCmlmKG4+PXMpYnJlYWsKbS5iPW4KaWYocD49
-cylyZXR1cm4gSC5rKHQscCkKdFtwXT0xOTJ8cT4+PjYKbS5iPW4rMQp0W25dPTEyOHxxJjYzfWVsc2V7
-cD1tLmIKaWYocCsyPj1zKWJyZWFrCm49bS5iPXArMQppZihwPj1zKXJldHVybiBILmsodCxwKQp0W3Bd
-PTIyNHxxPj4+MTIKcD1tLmI9bisxCmlmKG4+PXMpcmV0dXJuIEguayh0LG4pCnRbbl09MTI4fHE+Pj42
-JjYzCm0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5rKHQscCkKdFtwXT0xMjh8cSY2M319cmV0dXJuIHJ9
-fQpQLkdZLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbAp1Lkwu
-YShhKQp0PVAua3koITEsYSwwLG51bGwpCmlmKHQhPW51bGwpcmV0dXJuIHQKcz1QLmpCKDAsbnVsbCxK
-LkgoYSkpCnI9UC5jUChhLDAscykKaWYocj4wKXtxPVAuSE0oYSwwLHIpCmlmKHI9PT1zKXJldHVybiBx
-CnA9bmV3IFAuUm4ocSkKbz1yCm49ITF9ZWxzZXtvPTAKcD1udWxsCm49ITB9aWYocD09bnVsbClwPW5l
-dyBQLlJuKCIiKQptPW5ldyBQLmJ6KCExLHApCm0uYz1uCm0uTUUoYSxvLHMpCmlmKG0uZT4wKXtILnZo
-KFAucnIoIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2UiLGEscykpCnAuYSs9SC5Mdyg2NTUz
-MykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpyZXR1cm4gbC5jaGFyQ29kZUF0KDApPT0wP2w6bH19ClAuYnou
-cHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxo
-PXRoaXMsZz0iQmFkIFVURi04IGVuY29kaW5nIDB4Igp1LkwuYShhKQp0PWguZApzPWguZQpyPWguZgpo
-LmY9aC5lPWguZD0wCiRsYWJlbDAkMDpmb3IocT1KLlU2KGEpLHA9aC5iLG89YjshMDtvPWopeyRsYWJl
-bDEkMTppZihzPjApe2Rve2lmKG89PT1jKWJyZWFrICRsYWJlbDAkMApuPXEucShhLG8pCmlmKHR5cGVv
-ZiBuIT09Im51bWJlciIpcmV0dXJuIG4uek0oKQppZigobiYxOTIpIT09MTI4KXttPVAucnIoZytDLmpu
-LkQ4KG4sMTYpLGEsbykKdGhyb3cgSC5iKG0pfWVsc2V7dD0odDw8NnxuJjYzKT4+PjA7LS1zOysrb319
-d2hpbGUocz4wKQptPXItMQppZihtPDB8fG0+PTQpcmV0dXJuIEguayhDLkdiLG0pCmlmKHQ8PUMuR2Jb
-bV0pe209UC5ycigiT3ZlcmxvbmcgZW5jb2Rpbmcgb2YgMHgiK0Muam4uRDgodCwxNiksYSxvLXItMSkK
-dGhyb3cgSC5iKG0pfWlmKHQ+MTExNDExMSl7bT1QLnJyKCJDaGFyYWN0ZXIgb3V0c2lkZSB2YWxpZCBV
-bmljb2RlIHJhbmdlOiAweCIrQy5qbi5EOCh0LDE2KSxhLG8tci0xKQp0aHJvdyBILmIobSl9aWYoIWgu
-Y3x8dCE9PTY1Mjc5KXAuYSs9SC5Mdyh0KQpoLmM9ITF9Zm9yKG09bzxjO207KXtsPVAuY1AoYSxvLGMp
-CmlmKGw+MCl7aC5jPSExCms9bytsCnAuYSs9UC5ITShhLG8saykKaWYoaz09PWMpYnJlYWt9ZWxzZSBr
-PW8Kaj1rKzEKbj1xLnEoYSxrKQppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihu
-PDApe2k9UC5ycigiTmVnYXRpdmUgVVRGLTggY29kZSB1bml0OiAtMHgiK0Muam4uRDgoLW4sMTYpLGEs
-ai0xKQp0aHJvdyBILmIoaSl9ZWxzZXtpZigobiYyMjQpPT09MTkyKXt0PW4mMzEKcz0xCnI9MQpjb250
-aW51ZSAkbGFiZWwwJDB9aWYoKG4mMjQwKT09PTIyNCl7dD1uJjE1CnM9MgpyPTIKY29udGludWUgJGxh
-YmVsMCQwfWlmKChuJjI0OCk9PT0yNDAmJm48MjQ1KXt0PW4mNwpzPTMKcj0zCmNvbnRpbnVlICRsYWJl
-bDAkMH1pPVAucnIoZytDLmpuLkQ4KG4sMTYpLGEsai0xKQp0aHJvdyBILmIoaSl9fWJyZWFrICRsYWJl
-bDAkMH1pZihzPjApe2guZD10CmguZT1zCmguZj1yfX19ClAuV0YucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHIKdS5mby5hKGEpCnQ9dGhpcy5iCnM9dGhpcy5hCnQuYSs9cy5hCnI9dC5h
-Kz1ILmQoYS5hKQp0LmE9cisiOiAiCnQuYSs9UC5oKGIpCnMuYT0iLCAifSwKJFM6MTl9ClAuYTIucHJv
-dG90eXBlPXt9ClAuaVAucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVy
-biExCnJldHVybiBiIGluc3RhbmNlb2YgUC5pUCYmdGhpcy5hPT09Yi5hJiYhMH0sCmdpTzpmdW5jdGlv
-bihhKXt2YXIgdD10aGlzLmEKcmV0dXJuKHReQy5qbi53Ryh0LDMwKSkmMTA3Mzc0MTgyM30sClo6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9dGhpcyxzPVAuR3EoSC50Sih0KSkscj1QLmgwKEguTlModCkpLHE9UC5oMChI
-LmpBKHQpKSxwPVAuaDAoSC5LTCh0KSksbz1QLmgwKEguY2godCkpLG49UC5oMChILkpkKHQpKSxtPVAu
-VngoSC5WYSh0KSksbD1zKyItIityKyItIitxKyIgIitwKyI6IitvKyI6IituKyIuIittCnJldHVybiBs
-fX0KUC5DUC5wcm90b3R5cGU9e30KUC5YUy5wcm90b3R5cGU9ewpnSUk6ZnVuY3Rpb24oKXtyZXR1cm4g
-SC50cyh0aGlzLiR0aHJvd25Kc0Vycm9yKX19ClAuQzYucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2
-YXIgdD10aGlzLmEKaWYodCE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLmgodCkKcmV0
-dXJuIkFzc2VydGlvbiBmYWlsZWQifX0KUC5MSy5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVy
-biJUaHJvdyBvZiBudWxsLiJ9fQpQLkFULnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7cmV0dXJuIklu
-dmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0dXJuIiJ9
-LApaOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYyxuPW8hPW51bGw/IiAoIitvKyIp
-IjoiIgpvPXAuZAp0PW89PW51bGw/IiI6IjogIitILmQobykKcz1wLmdMKCkrbit0CmlmKCFwLmEpcmV0
-dXJuIHMKcj1wLmd1KCkKcT1QLmgocC5iKQpyZXR1cm4gcytyKyI6ICIrcX19ClAuYkoucHJvdG90eXBl
-PXsKZ0w6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciB0LHMs
-cj10aGlzLmUKaWYocj09bnVsbCl7cj10aGlzLmYKdD1yIT1udWxsPyI6IE5vdCBsZXNzIHRoYW4gb3Ig
-ZXF1YWwgdG8gIitILmQocik6IiJ9ZWxzZXtzPXRoaXMuZgppZihzPT1udWxsKXQ9IjogTm90IGdyZWF0
-ZXIgdGhhbiBvciBlcXVhbCB0byAiK0guZChyKQplbHNlIGlmKHM+cil0PSI6IE5vdCBpbiByYW5nZSAi
-K0guZChyKSsiLi4iK0guZChzKSsiLCBpbmNsdXNpdmUiCmVsc2UgdD1zPHI/IjogVmFsaWQgdmFsdWUg
-cmFuZ2UgaXMgZW1wdHkiOiI6IE9ubHkgdmFsaWQgdmFsdWUgaXMgIitILmQocil9cmV0dXJuIHR9fQpQ
-LmVZLnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rp
-b24oKXt2YXIgdCxzPUguV1kodGhpcy5iKQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkoo
-KQppZihzPDApcmV0dXJuIjogaW5kZXggbXVzdCBub3QgYmUgbmVnYXRpdmUiCnQ9dGhpcy5mCmlmKHQ9
-PT0wKXJldHVybiI6IG5vIGluZGljZXMgYXJlIHZhbGlkIgpyZXR1cm4iOiBpbmRleCBzaG91bGQgYmUg
-bGVzcyB0aGFuICIrSC5kKHQpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAucHJv
-dG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcyxrPXt9LGo9bmV3
-IFAuUm4oIiIpCmsuYT0iIgpmb3IodD1sLmMscz10Lmxlbmd0aCxyPTAscT0iIixwPSIiO3I8czsrK3Is
-cD0iLCAiKXtvPXRbcl0Kai5hPXErcApxPWouYSs9UC5oKG8pCmsuYT0iLCAifWwuZC5LKDAsbmV3IFAu
-V0YoayxqKSkKbj1QLmgobC5hKQptPWouWigwKQp0PSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5v
-dCBmb3VuZDogJyIrSC5kKGwuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbisiXG5Bcmd1bWVudHM6IFsiK20r
-Il0iCnJldHVybiB0fX0KUC51Yi5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJVbnN1cHBv
-cnRlZCBvcGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMuYQpyZXR1cm4gdCE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAiK3Q6IlVuaW1wbGVt
-ZW50ZWRFcnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIkJhZCBzdGF0
-ZTogIit0aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlm
-KHQ9PW51bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb24uIgpy
-ZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjogIitQLmgodCkrIi4i
-fX0KUC5rNS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJPdXQgb2YgTWVtb3J5In0sCmdJ
-STpmdW5jdGlvbigpe3JldHVybiBudWxsfSwKJGlYUzoxfQpQLktZLnByb3RvdHlwZT17Clo6ZnVuY3Rp
-b24oYSl7cmV0dXJuIlN0YWNrIE92ZXJmbG93In0sCmdJSTpmdW5jdGlvbigpe3JldHVybiBudWxsfSwK
-JGlYUzoxfQpQLnQ3LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0
-PT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9uIjoi
-UmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrdCsiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9uIn19
-ClAuQ0QucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMuYX19
-ClAuYUUucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGks
-aD10aGlzLmEsZz1oIT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILmQoaCk6IkZvcm1h
-dEV4Y2VwdGlvbiIsZj10aGlzLmMsZT10aGlzLmIKaWYodHlwZW9mIGU9PSJzdHJpbmciKXtpZihmIT1u
-dWxsKWg9ZjwwfHxmPmUubGVuZ3RoCmVsc2UgaD0hMQppZihoKWY9bnVsbAppZihmPT1udWxsKXt0PWUu
-bGVuZ3RoPjc4P0MueEIudyhlLDAsNzUpKyIuLi4iOmUKcmV0dXJuIGcrIlxuIit0fWZvcihzPTEscj0w
-LHE9ITEscD0wO3A8ZjsrK3Ape289Qy54Qi5XKGUscCkKaWYobz09PTEwKXtpZihyIT09cHx8IXEpKytz
-CnI9cCsxCnE9ITF9ZWxzZSBpZihvPT09MTMpeysrcwpyPXArMQpxPSEwfX1nPXM+MT9nKygiIChhdCBs
-aW5lICIrcysiLCBjaGFyYWN0ZXIgIisoZi1yKzEpKyIpXG4iKTpnKygiIChhdCBjaGFyYWN0ZXIgIiso
-ZisxKSsiKVxuIikKbj1lLmxlbmd0aApmb3IocD1mO3A8bjsrK3Ape289Qy54Qi5tKGUscCkKaWYobz09
-PTEwfHxvPT09MTMpe249cApicmVha319aWYobi1yPjc4KWlmKGYtcjw3NSl7bT1yKzc1Cmw9cgprPSIi
-Cmo9Ii4uLiJ9ZWxzZXtpZihuLWY8NzUpe2w9bi03NQptPW4Kaj0iIn1lbHNle2w9Zi0zNgptPWYrMzYK
-aj0iLi4uIn1rPSIuLi4ifWVsc2V7bT1uCmw9cgprPSIiCmo9IiJ9aT1DLnhCLncoZSxsLG0pCnJldHVy
-biBnK2sraStqKyJcbiIrQy54Qi5JeCgiICIsZi1sK2subGVuZ3RoKSsiXlxuIn1lbHNlIHJldHVybiBm
-IT1udWxsP2crKCIgKGF0IG9mZnNldCAiK0guZChmKSsiKSIpOmd9fQpQLkVILnByb3RvdHlwZT17fQpQ
-LklmLnByb3RvdHlwZT17fQpQLmNYLnByb3RvdHlwZT17CkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1I
-LkxoKHRoaXMpCnJldHVybiBILksxKHRoaXMsdC5LcShjKS5DKCIxKGNYLkUpIikuYShiKSx0LkMoImNY
-LkUiKSxjKX0sCmV2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUo
-dGhpcyx0LkMoImEyKGNYLkUpIikuYShiKSx0LkMoIlU1PGNYLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7
-dmFyIHQscz10aGlzLmdreih0aGlzKQpmb3IodD0wO3MuRigpOykrK3QKcmV0dXJuIHR9LApnbDA6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2t6KHRoaXMpLkYoKX0sCmdyODpmdW5jdGlvbihhKXt2YXIgdCxz
-PXRoaXMuZ2t6KHRoaXMpCmlmKCFzLkYoKSl0aHJvdyBILmIoSC5XcCgpKQp0PXMuZ2woKQppZihzLkYo
-KSl0aHJvdyBILmIoSC5kVSgpKQpyZXR1cm4gdH0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT0i
-aW5kZXgiClAuVUkoYixxLHUuUykKUC5rMShiLHEpCmZvcih0PXRoaXMuZ2t6KHRoaXMpLHM9MDt0LkYo
-KTspe3I9dC5nbCgpCmlmKGI9PT1zKXJldHVybiByOysrc310aHJvdyBILmIoUC50KGIsdGhpcyxxLG51
-bGwscykpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90
-b3R5cGU9e30KUC56TS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjF9ClAuWjAucHJvdG90eXBlPXt9ClAu
-TjMucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iTWFwRW50cnkoIitILmQodGhpcy5hKSsi
-OiAiK0guZCh0aGlzLmIpKyIpIn19ClAuYzgucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVy
-biBQLk1oLnByb3RvdHlwZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4i
-bnVsbCJ9fQpQLmxmLnByb3RvdHlwZT17fQpQLk1oLnByb3RvdHlwZT17Y29uc3RydWN0b3I6UC5NaCwk
-aU1oOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmVRKHRoaXMpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEgu
-bGgodGhpcykpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmEoYikKdGhyb3cgSC5iKFAubHIodGhp
-cyxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfSwKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5aKHRoaXMpfX0KUC5PZC5wcm90b3R5cGU9e30KUC5pYi5wcm90b3R5cGU9eyRpT2Q6MX0KUC54dS5w
-cm90b3R5cGU9e30KUC5Hei5wcm90b3R5cGU9e30KUC5aZC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEp
-e3JldHVybiIifSwKJGlHejoxfQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnByb3RvdHlwZT17
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKWjpmdW5jdGlvbihhKXt2YXIgdD10
-aGlzLmEKcmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0QucHJvdG90eXBl
-PXt9ClAubjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmYuYShhKQpI
-LmMoYikKdD1KLnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlkoMCxQLmt1KGIs
-MCxiLmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIudyhiLDAsdCkKcj1D
-LnhCLkcoYix0KzEpCnE9dGhpcy5hCmEuWSgwLFAua3UocywwLHMubGVuZ3RoLHEsITApLFAua3Uociww
-LHIubGVuZ3RoLHEsITApKX1yZXR1cm4gYX0sCiRTOjQxfQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0
-aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIp
-KX0sCiRTOjQzfQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIo
-IklsbGVnYWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLiQyKGEsbnVsbCl9LAokUzo0NX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
-e3ZhciB0CmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBt
-YXhpbXVtIG9mIDQgaGV4IGRpZ2l0cyIsYSkKdD1QLlFBKEMueEIudyh0aGlzLmIsYSxiKSxudWxsLDE2
-KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+NjU1MzUpdGhpcy5h
-LiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhGRkZGYCIsYSkKcmV0
-dXJuIHR9LAokUzo0Nn0KUC5Ebi5wcm90b3R5cGU9ewpna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
-fSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlmKEMueEIu
-bih0LCJbIikpcmV0dXJuIEMueEIudyh0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApndHA6ZnVuY3Rp
-b24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpyZXR1cm4gdH0s
-Cmd0UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0
-aW9uKCl7dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHAsbyxuLG0sbD10aGlzCnUuWC5hKG51bGwpCnUuYi5hKGIpCnQ9bC5hCnM9dD09PSJm
-aWxlIgpyPWwuYgpxPWwuZApwPWwuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxs
-fHxzPyIiOm51bGwKbz1sLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlm
-KG4mJiFDLnhCLm4obywiLyIpKW89Ii8iK28KbT1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcgUC5E
-bih0LHIscCxxLG8sbSxsLnIpfSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLngKaWYocyE9bnVs
-bClyZXR1cm4gcwp0PXRoaXMuZQppZih0Lmxlbmd0aCE9PTAmJkMueEIuVyh0LDApPT09NDcpdD1DLnhC
-LkcodCwxKQpzPXQ9PT0iIj9DLmRuOlAuQUYobmV3IEgubEooSC5WTSh0LnNwbGl0KCIvIiksdS5zKSx1
-LmRPLmEoUC5QSCgpKSx1LmRvKSx1Lk4pCnRoaXMuc282KHMpCnJldHVybiBzfSwKZ2hZOmZ1bmN0aW9u
-KCl7dmFyIHQscz10aGlzCmlmKHMuUT09bnVsbCl7dD1zLmYKcy5zUkgobmV3IFAuR2ooUC5XWCh0PT1u
-dWxsPyIiOnQpLHUuRCkpfXJldHVybiBzLlF9LApKaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAs
-bwpmb3IodD0wLHM9MDtDLnhCLlFpKGIsIi4uLyIscyk7KXtzKz0zOysrdH1yPUMueEIuY24oYSwiLyIp
-CndoaWxlKCEwKXtpZighKHI+MCYmdD4wKSlicmVhawpxPUMueEIuUGsoYSwiLyIsci0xKQppZihxPDAp
-YnJlYWsKcD1yLXEKbz1wIT09MgppZighb3x8cD09PTMpaWYoQy54Qi5tKGEscSsxKT09PTQ2KW89IW98
-fEMueEIubShhLHErMik9PT00NgplbHNlIG89ITEKZWxzZSBvPSExCmlmKG8pYnJlYWs7LS10CnI9cX1y
-ZXR1cm4gQy54Qi5pNyhhLHIrMSxudWxsLEMueEIuRyhiLHMtMyp0KSl9LApaSTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0s
-bCxrPXRoaXMsaj1udWxsCmlmKGEuZ0ZpKCkubGVuZ3RoIT09MCl7dD1hLmdGaSgpCmlmKGEuZ2NqKCkp
-e3M9YS5na3UoKQpyPWEuZ0pmKGEpCnE9YS5neEEoKT9hLmd0cChhKTpqfWVsc2V7cT1qCnI9cQpzPSIi
-fXA9UC54ZShhLmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3Q9ay5hCmlmKGEuZ2NqKCkp
-e3M9YS5na3UoKQpyPWEuZ0pmKGEpCnE9UC53QihhLmd4QSgpP2EuZ3RwKGEpOmosdCkKcD1QLnhlKGEu
-Z0lpKGEpKQpvPWEuZ1FEKCk/YS5ndFAoKTpqfWVsc2V7cz1rLmIKcj1rLmMKcT1rLmQKaWYoYS5nSWko
-YSk9PT0iIil7cD1rLmUKbz1hLmdRRCgpP2EuZ3RQKCk6ay5mfWVsc2V7aWYoYS5ndFQoKSlwPVAueGUo
-YS5nSWkoYSkpCmVsc2V7bj1rLmUKaWYobi5sZW5ndGg9PT0wKWlmKHI9PW51bGwpcD10Lmxlbmd0aD09
-PTA/YS5nSWkoYSk6UC54ZShhLmdJaShhKSkKZWxzZSBwPVAueGUoIi8iK2EuZ0lpKGEpKQplbHNle209
-ay5KaChuLGEuZ0lpKGEpKQpsPXQubGVuZ3RoPT09MAppZighbHx8ciE9bnVsbHx8Qy54Qi5uKG4sIi8i
-KSlwPVAueGUobSkKZWxzZSBwPVAud0YobSwhbHx8ciE9bnVsbCl9fW89YS5nUUQoKT9hLmd0UCgpOmp9
-fX1yZXR1cm4gbmV3IFAuRG4odCxzLHIscSxwLG8sYS5nWjgoKT9hLmdLYSgpOmopfSwKZ2NqOmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmQhPW51
-bGx9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9uKCl7cmV0
-dXJuIHRoaXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4odGhpcy5lLCIvIil9
-LAp0NDpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzLHE9ci5hCmlmKHEhPT0iIiYmcSE9PSJmaWxlIil0
-aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHEpKyIg
-VVJJIikpCnE9ci5mCmlmKChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBl
-eHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQpxPXIu
-cgppZigocT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZp
-bGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSkKdD0kLk94KCkKaWYo
-SC5vVCh0KSlxPVAubW4ocikKZWxzZXtpZihyLmMhPW51bGwmJnIuZ0pmKHIpIT09IiIpSC52aChQLkw0
-KCJDYW5ub3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0
-aCBhbiBhdXRob3JpdHkiKSkKcz1yLmdGaigpClAua0UocywhMSkKcT1QLnZnKEMueEIubihyLmUsIi8i
-KT8iLyI6IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0KDApPT0wP3E6cX1yZXR1cm4gcX0sClo6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyLHE9dGhpcyxwPXEueQppZihwPT1udWxsKXtwPXEuYQp0PXAubGVuZ3RoIT09
-MD9wKyI6IjoiIgpzPXEuYwpyPXM9PW51bGwKaWYoIXJ8fHA9PT0iZmlsZSIpe3A9dCsiLy8iCnQ9cS5i
-CmlmKHQubGVuZ3RoIT09MClwPXArdCsiQCIKaWYoIXIpcCs9cwp0PXEuZAppZih0IT1udWxsKXA9cCsi
-OiIrSC5kKHQpfWVsc2UgcD10CnArPXEuZQp0PXEuZgppZih0IT1udWxsKXA9cCsiPyIrdAp0PXEucgpp
-Zih0IT1udWxsKXA9cCsiIyIrdApwPXEueT1wLmNoYXJDb2RlQXQoMCk9PTA/cDpwfXJldHVybiBwfSwK
-RE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHI9PT1i
-KXJldHVybiEwCmlmKHUuRS5iKGIpKWlmKHIuYT09Yi5nRmkoKSlpZihyLmMhPW51bGw9PT1iLmdjaigp
-KWlmKHIuYj09Yi5na3UoKSlpZihyLmdKZihyKT09Yi5nSmYoYikpaWYoci5ndHAocik9PWIuZ3RwKGIp
-KWlmKHIuZT09PWIuZ0lpKGIpKXt0PXIuZgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdRRCgpKXtpZihzKXQ9
-IiIKaWYodD09PWIuZ3RQKCkpe3Q9ci5yCnM9dD09bnVsbAppZighcz09PWIuZ1o4KCkpe2lmKHMpdD0i
-Igp0PXQ9PT1iLmdLYSgpfWVsc2UgdD0hMX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMQplbHNl
-IHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQpyZXR1
-cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnoKcmV0dXJuIHQ9PW51bGw/dGhpcy56PUMu
-eEIuZ2lPKHRoaXMuWigwKSk6dH0sCnNvNjpmdW5jdGlvbihhKXt0aGlzLng9dS5hLmEoYSl9LApzUkg6
-ZnVuY3Rpb24oYSl7dGhpcy5RPXUuZi5hKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5hfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLmUxLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3Rocm93IEguYihQLnJyKCJJbnZhbGlkIHBvcnQiLHRoaXMuYSx0aGlzLmIrMSkp
-fSwKJFM6MTR9ClAuTlkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9IklsbGVnYWwgcGF0
-aCBjaGFyYWN0ZXIgIgpILmMoYSkKaWYoSi56bChhLCIvIikpaWYodGhpcy5hKXRocm93IEguYihQLnhZ
-KHQrYSkpCmVsc2UgdGhyb3cgSC5iKFAuTDQodCthKSl9LAokUzoxNH0KUC5SWi5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXtyZXR1cm4gUC5lUChDLlpKLGEsQy54TSwhMSl9LAokUzo0fQpQLk1FLnByb3Rv
-dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5iLHM9dGhpcy5hCnQuYSs9cy5hCnMuYT0i
-JiIKcz10LmErPUguZChQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5ndGghPT0w
-KXt0LmE9cysiPSIKdC5hKz1ILmQoUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQLnk1LnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmMoYSkKaWYoYj09bnVsbHx8dHlwZW9m
-IGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguYyhiKSkKZWxzZSBmb3IodD1KLklUKHUuUi5hKGIpKSxz
-PXRoaXMuYTt0LkYoKTspcy4kMihhLEguYyh0LmdsKCkpKX0sCiRTOjEzfQpQLlBFLnByb3RvdHlwZT17
-CmdsUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwsbj1wLmMKaWYobiE9bnVsbCly
-ZXR1cm4gbgpuPXAuYgppZigwPj1uLmxlbmd0aClyZXR1cm4gSC5rKG4sMCkKdD1wLmEKbj1uWzBdKzEK
-cz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLnVPKHQscysxLHIsQy5WQywh
-MSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxvLFAudU8odCxuLHIs
-Qy5XZCwhMSkscSxvKX0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5sZW5ndGgp
-cmV0dXJuIEguayhzLDApCnQ9dGhpcy5hCnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9fQpQLnEz
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9LAokUzoy
-M30KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihhPj10Lmxl
-bmd0aClyZXR1cm4gSC5rKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwKJFM6MjR9
-ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0PWIubGVu
-Z3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cylyZXR1cm4g
-SC5rKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1zOysrdCl7
-cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguayhhLHEpCmFbcV09Y319fQpQLlVmLnByb3RvdHlw
-ZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3ZhciB0LHMK
-aWYodGhpcy5jPjApe3Q9dGhpcy5kCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnM9
-dGhpcy5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIEgucFkocykKcz10KzE8cwp0PXN9ZWxz
-ZSB0PSExCnJldHVybiB0fSwKZ1FEOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVvZiB0IT09
-Im51bWJlciIpcmV0dXJuIHQuSigpCnJldHVybiB0PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVy
-biB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZD
-LnhCLm4odGhpcy5hLCJmaWxlIil9LApnV1o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54
-Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ1JlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUmJkMueEIu
-bih0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8i
-LHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj0icGFja2FnZSIscT1zLmIKaWYo
-cTw9MClyZXR1cm4iIgp0PXMueAppZih0IT1udWxsKXJldHVybiB0CmlmKHMuZ1daKCkpcT1zLng9Imh0
-dHAiCmVsc2UgaWYocy5nUmUoKSl7cy54PSJodHRwcyIKcT0iaHR0cHMifWVsc2UgaWYocy5nTncoKSl7
-cy54PSJmaWxlIgpxPSJmaWxlIn1lbHNlIGlmKHE9PT03JiZDLnhCLm4ocy5hLHIpKXtzLng9cgpxPXJ9
-ZWxzZXtxPUMueEIudyhzLmEsMCxxKQpzLng9cX1yZXR1cm4gcX0sCmdrdTpmdW5jdGlvbigpe3ZhciB0
-PXRoaXMuYyxzPXRoaXMuYiszCnJldHVybiB0PnM/Qy54Qi53KHRoaXMuYSxzLHQtMSk6IiJ9LApnSmY6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0PjA/Qy54Qi53KHRoaXMuYSx0LHRoaXMuZCk6
-IiJ9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCmlmKHMuZ3hBKCkpe3Q9cy5kCmlmKHR5cGVv
-ZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnJldHVybiBQLlFBKEMueEIudyhzLmEsdCsxLHMuZSks
-bnVsbCxudWxsKX1pZihzLmdXWigpKXJldHVybiA4MAppZihzLmdSZSgpKXJldHVybiA0NDMKcmV0dXJu
-IDB9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudyh0aGlzLmEsdGhpcy5lLHRoaXMuZil9LApn
-dFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYscz10aGlzLnIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIily
-ZXR1cm4gdC5KKCkKcmV0dXJuIHQ8cz9DLnhCLncodGhpcy5hLHQrMSxzKToiIn0sCmdLYTpmdW5jdGlv
-bigpe3ZhciB0PXRoaXMucixzPXRoaXMuYQpyZXR1cm4gdDxzLmxlbmd0aD9DLnhCLkcocyx0KzEpOiIi
-fSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMuZSxxPXRoaXMuZixwPXRoaXMuYQppZihDLnhC
-LlFpKHAsIi8iLHIpKXtpZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKTsrK3J9aWYocj09
-cSlyZXR1cm4gQy5kbgp0PUguVk0oW10sdS5zKQpzPXIKd2hpbGUoITApe2lmKHR5cGVvZiBzIT09Im51
-bWJlciIpcmV0dXJuIHMuSigpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIEgucFkocSkKaWYo
-IShzPHEpKWJyZWFrCmlmKEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIudyhwLHIscykpCnI9
-cysxfSsrc31DLk5tLmkodCxDLnhCLncocCxyLHEpKQpyZXR1cm4gUC5BRih0LHUuTil9LApnaFk6ZnVu
-Y3Rpb24oKXt2YXIgdD10aGlzLmYKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkKaWYo
-dD49dGhpcy5yKXJldHVybiBDLkNNCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMuZ3RQKCkpLHUuRCl9
-LAprWDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZAppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVy
-biBzLmgoKQp0PXMrMQpyZXR1cm4gdCthLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0
-KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQucixyPXQuYQppZihzPj1yLmxlbmd0aClyZXR1
-cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi53KHIsMCxzKSx0LmIsdC5jLHQuZCx0LmUsdC5mLHMsdC54
-KX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaj10aGlzLGk9bnVsbAp1
-LlguYShudWxsKQp1LmIuYShiKQp0PWouZ0ZpKCkKcz10PT09ImZpbGUiCnI9ai5jCnE9cj4wP0MueEIu
-dyhqLmEsai5iKzMscik6IiIKcD1qLmd4QSgpP2ouZ3RwKGopOmkKcj1qLmMKaWYocj4wKW89Qy54Qi53
-KGouYSxyLGouZCkKZWxzZSBvPXEubGVuZ3RoIT09MHx8cCE9bnVsbHx8cz8iIjppCnI9ai5hCm49Qy54
-Qi53KHIsai5lLGouZikKaWYoIXMpbT1vIT1udWxsJiZuLmxlbmd0aCE9PTAKZWxzZSBtPSEwCmlmKG0m
-JiFDLnhCLm4obiwiLyIpKW49Ii8iK24KbD1QLmxlKGksMCwwLGIpCm09ai5yCms9bTxyLmxlbmd0aD9D
-LnhCLkcocixtKzEpOmkKcmV0dXJuIG5ldyBQLkRuKHQscSxvLHAsbixsLGspfSwKWkk6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXtpZihhIGluc3RhbmNlb2Yg
-UC5VZilyZXR1cm4gdGhpcy51MSh0aGlzLGEpCnJldHVybiB0aGlzLnZzKCkubVMoYSl9LAp1MTpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPWIuYgppZihlPjApcmV0
-dXJuIGIKdD1iLmMKaWYodD4wKXtzPWEuYgppZihzPD0wKXJldHVybiBiCmlmKGEuZ053KCkpcj1iLmUh
-PWIuZgplbHNlIGlmKGEuZ1daKCkpcj0hYi5rWCgiODAiKQplbHNlIHI9IWEuZ1JlKCl8fCFiLmtYKCI0
-NDMiKQppZihyKXtxPXMrMQpwPUMueEIudyhhLmEsMCxxKStDLnhCLkcoYi5hLGUrMSkKZT1iLmQKaWYo
-dHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKbz1iLmUKaWYodHlwZW9mIG8hPT0ibnVtYmVy
-IilyZXR1cm4gby5oKCkKbj1iLmYKaWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5oKCkKcmV0
-dXJuIG5ldyBQLlVmKHAscyx0K3EsZStxLG8rcSxuK3EsYi5yK3EsYS54KX1lbHNlIHJldHVybiB0aGlz
-LnZzKCkubVMoYil9bT1iLmUKZT1iLmYKaWYobT09ZSl7dD1iLnIKaWYodHlwZW9mIGUhPT0ibnVtYmVy
-IilyZXR1cm4gZS5KKCkKaWYoZTx0KXtzPWEuZgppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBz
-LkhOKCkKcT1zLWUKcmV0dXJuIG5ldyBQLlVmKEMueEIudyhhLmEsMCxzKStDLnhCLkcoYi5hLGUpLGEu
-YixhLmMsYS5kLGEuZSxlK3EsdCtxLGEueCl9ZT1iLmEKaWYodDxlLmxlbmd0aCl7cz1hLnIKcmV0dXJu
-IG5ldyBQLlVmKEMueEIudyhhLmEsMCxzKStDLnhCLkcoZSx0KSxhLmIsYS5jLGEuZCxhLmUsYS5mLHQr
-KHMtdCksYS54KX1yZXR1cm4gYS5OOSgpfXQ9Yi5hCmlmKEMueEIuUWkodCwiLyIsbSkpe3M9YS5lCmlm
-KHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4oKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJl
-dHVybiBILnBZKG0pCnE9cy1tCnA9Qy54Qi53KGEuYSwwLHMpK0MueEIuRyh0LG0pCmlmKHR5cGVvZiBl
-IT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcgUC5VZihwLGEuYixhLmMsYS5kLHMsZStx
-LGIucitxLGEueCl9bD1hLmUKaz1hLmYKaWYobD09ayYmYS5jPjApe2Zvcig7Qy54Qi5RaSh0LCIuLi8i
-LG0pOyl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5oKCkKbSs9M31pZih0eXBlb2YgbCE9
-PSJudW1iZXIiKXJldHVybiBsLkhOKCkKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5wWSht
-KQpxPWwtbSsxCnA9Qy54Qi53KGEuYSwwLGwpKyIvIitDLnhCLkcodCxtKQppZih0eXBlb2YgZSE9PSJu
-dW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxhLmIsYS5jLGEuZCxsLGUrcSxiLnIr
-cSxhLngpfWo9YS5hCmZvcihpPWw7Qy54Qi5RaShqLCIuLi8iLGkpOyl7aWYodHlwZW9mIGkhPT0ibnVt
-YmVyIilyZXR1cm4gaS5oKCkKaSs9M31oPTAKd2hpbGUoITApe2lmKHR5cGVvZiBtIT09Im51bWJlciIp
-cmV0dXJuIG0uaCgpCmc9bSszCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIEgucFkoZSkKaWYo
-IShnPD1lJiZDLnhCLlFpKHQsIi4uLyIsbSkpKWJyZWFrOysraAptPWd9Zj0iIgp3aGlsZSghMCl7aWYo
-dHlwZW9mIGshPT0ibnVtYmVyIilyZXR1cm4gay5vcygpCmlmKHR5cGVvZiBpIT09Im51bWJlciIpcmV0
-dXJuIEgucFkoaSkKaWYoIShrPmkpKWJyZWFrOy0tawppZihDLnhCLm0oaixrKT09PTQ3KXtpZihoPT09
-MCl7Zj0iLyIKYnJlYWt9LS1oCmY9Ii8ifX1pZihrPT09aSYmYS5iPD0wJiYhQy54Qi5RaShqLCIvIixs
-KSl7bS09aCozCmY9IiJ9cT1rLW0rZi5sZW5ndGgKcmV0dXJuIG5ldyBQLlVmKEMueEIudyhqLDAsaykr
-ZitDLnhCLkcodCxtKSxhLmIsYS5jLGEuZCxsLGUrcSxiLnIrcSxhLngpfSwKdDQ6ZnVuY3Rpb24oKXt2
-YXIgdCxzLHIscSxwPXRoaXMKaWYocC5iPj0wJiYhcC5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90
-IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHAuZ0ZpKCkpKyIgVVJJIikpCnQ9cC5mCnM9
-cC5hCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8cy5sZW5ndGgpe2lmKHQ8
-cC5yKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdp
-dGggYSBxdWVyeSBjb21wb25lbnQiKSkKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmls
-ZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIpKX1yPSQuT3goKQppZihI
-Lm9UKHIpKXQ9UC5tbihwKQplbHNle3E9cC5kCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIEgu
-cFkocSkKaWYocC5jPHEpSC52aChQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUg
-cGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3JpdHkiKSkKdD1DLnhCLncocyxwLmUsdCl9
-cmV0dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy55CnJldHVybiB0PT1udWxsP3RoaXMu
-eT1DLnhCLmdpTyh0aGlzLmEpOnR9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEK
-aWYodGhpcz09PWIpcmV0dXJuITAKcmV0dXJuIHUuRS5iKGIpJiZ0aGlzLmE9PT1iLlooMCl9LAp2czpm
-dW5jdGlvbigpe3ZhciB0PXRoaXMscz1udWxsLHI9dC5nRmkoKSxxPXQuZ2t1KCkscD10LmM+MD90LmdK
-Zih0KTpzLG89dC5neEEoKT90Lmd0cCh0KTpzLG49dC5hLG09dC5mLGw9Qy54Qi53KG4sdC5lLG0pLGs9
-dC5yCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0uSigpCm09bTxrP3QuZ3RQKCk6cwpyZXR1
-cm4gbmV3IFAuRG4ocixxLHAsbyxsLG0sazxuLmxlbmd0aD90LmdLYSgpOnMpfSwKWjpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3RvdHlwZT17fQpXLnFFLnByb3RvdHlwZT17
-fQpXLkdoLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpR2g6MX0K
-Vy5mWS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLm5CLnByb3Rv
-dHlwZT17JGluQjoxfQpXLkF6LnByb3RvdHlwZT17JGlBejoxfQpXLlFQLnByb3RvdHlwZT17JGlRUDox
-fQpXLm54LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcub0oucHJv
-dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5pZC5wcm90b3R5cGU9e30K
-Vy5RRi5wcm90b3R5cGU9e30KVy5OaC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBTdHJp
-bmcoYSl9fQpXLklCLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlY3RhbmdsZSAoIitI
-LmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkrIiB4ICIrSC5kKGEuaGVp
-Z2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5xLmIoYikm
-JmEubGVmdD09Yi5sZWZ0JiZhLnRvcD09Yi50b3AmJmEud2lkdGg9PWIud2lkdGgmJmEuaGVpZ2h0PT1i
-LmhlaWdodH0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gVy5yRShKLmhmKGEubGVmdCksSi5oZihhLnRv
-cCksSi5oZihhLndpZHRoKSxKLmhmKGEuaGVpZ2h0KSl9LAokaXRuOjF9ClcubjcucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy53ei5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILldZKGIpCnQ9
-dGhpcy5hCmlmKGI8MHx8Yj49dC5sZW5ndGgpcmV0dXJuIEguayh0LGIpCnJldHVybiB0aGlzLiR0aS5j
-LmEodFtiXSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykKdGhyb3cgSC5iKFAuTDQo
-IkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgVy5pNyhhKX0sCmdEOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNEOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKdS5YLmEoYikKdD10aGlzLmdEKGEpCnQuVjEoMCkKdC5GVigwLGIpfSwK
-WjpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhbE5hbWV9LAp0bjpmdW5jdGlvbihhKXt2YXIgdD0hIWEu
-c2Nyb2xsSW50b1ZpZXdJZk5lZWRlZAppZih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2Ug
-YS5zY3JvbGxJbnRvVmlldygpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoYz09
-bnVsbCl7aWYoZD09bnVsbCl7dD0kLmx0CmlmKHQ9PW51bGwpe3Q9SC5WTShbXSx1LmspCnM9bmV3IFcu
-dkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgpKQokLmx0PXMKZD1zfWVsc2Ug
-ZD10fXQ9JC5FVQppZih0PT1udWxsKXt0PW5ldyBXLktvKGQpCiQuRVU9dApjPXR9ZWxzZXt0LmE9ZApj
-PXR9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9yIGNhbiBvbmx5IGJlIHBh
-c3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVsbCl7dD1kb2N1bWVudApz
-PXQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKQokLnhvPXMKJC5CTz1zLmNyZWF0
-ZVJhbmdlKCkKcz0kLnhvLmNyZWF0ZUVsZW1lbnQoImJhc2UiKQp1LmNSLmEocykKcy5ocmVmPXQuYmFz
-ZVVSSQokLnhvLmhlYWQuYXBwZW5kQ2hpbGQocyl9dD0kLnhvCmlmKHQuYm9keT09bnVsbCl7cz10LmNy
-ZWF0ZUVsZW1lbnQoImJvZHkiKQp0LmJvZHk9dS5ZLmEocyl9dD0kLnhvCmlmKHUuWS5iKGEpKXI9dC5i
-b2R5CmVsc2V7cj10LmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5kQ2hpbGQo
-cil9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSYm
-IUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhyKQpxPSQuQk8u
-Y3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGIpfWVsc2V7ci5pbm5lckhUTUw9YgpxPSQueG8uY3JlYXRl
-RG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hpbGQsdCE9bnVsbDspcS5hcHBlbmRDaGls
-ZCh0KX10PSQueG8uYm9keQppZihyPT1udWxsP3QhPW51bGw6ciE9PXQpSi5MdChyKQpjLlBuKHEpCmRv
-Y3VtZW50LmFkb3B0Tm9kZShxKQpyZXR1cm4gcX0sCkFIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdGhp
-cy5yNihhLGIsYyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnBrOmZ1bmN0
-aW9uKGEsYixjKXthLnRleHRDb250ZW50PW51bGwKYS5hcHBlbmRDaGlsZCh0aGlzLnI2KGEsYixudWxs
-LGMpKX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKZ25zOmZ1bmN0
-aW9uKGEpe3JldHVybiBhLnRhZ05hbWV9LApnVmw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmV1KGEs
-ImNsaWNrIiwhMSx1LlEpfSwKJGljdjoxfQpXLkN2LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Jl
-dHVybiB1LmguYih1LkEuYShhKSl9LAokUzoyNX0KVy5lYS5wcm90b3R5cGU9eyRpZWE6MX0KVy5EMC5w
-cm90b3R5cGU9ewpPbjpmdW5jdGlvbihhLGIsYyxkKXt1LlUuYShjKQppZihjIT1udWxsKXRoaXMudihh
-LGIsYyxkKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixjLG51bGwpfSwKdjpm
-dW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50Uih1LlUuYShjKSwx
-KSxkKX0sCiRpRDA6MX0KVy5UNS5wcm90b3R5cGU9eyRpVDU6MX0KVy5oNC5wcm90b3R5cGU9ewpnQTpm
-dW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmJyLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEp
-e3JldHVybiBhLmxlbmd0aH19ClcuVmIucHJvdG90eXBlPXt9ClcuZkoucHJvdG90eXBlPXsKZW86ZnVu
-Y3Rpb24oYSxiLGMsZCl7cmV0dXJuIGEub3BlbihiLGMsITApfSwKJGlmSjoxfQpXLmJVLnByb3RvdHlw
-ZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLnNldFJlcXVlc3RIZWFkZXIoSC5jKGEpLEguYyhiKSl9
-LAokUzo5fQpXLmhILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAKdS5wLmEo
-YSkKdD10aGlzLmEKcz10LnN0YXR1cwppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLnRCKCkK
-cj1zPj0yMDAmJnM8MzAwCnE9cz4zMDcmJnM8NDAwCnM9cnx8cz09PTB8fHM9PT0zMDR8fHEKcD10aGlz
-LmIKaWYocylwLmFNKDAsdCkKZWxzZSBwLnBtKGEpfSwKJFM6Mjd9Clcud2EucHJvdG90eXBlPXt9Clcu
-U2cucHJvdG90eXBlPXskaVNnOjF9ClcudTgucHJvdG90eXBlPXsKZ0RyOmZ1bmN0aW9uKGEpe2lmKCJv
-cmlnaW4iIGluIGEpcmV0dXJuIGEub3JpZ2luCnJldHVybiBILmQoYS5wcm90b2NvbCkrIi8vIitILmQo
-YS5ob3N0KX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdTg6MX0KVy5PSy5wcm90
-b3R5cGU9eyRpT0s6MX0KVy5lNy5wcm90b3R5cGU9ewpncjg6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5h
-LHM9dC5jaGlsZE5vZGVzLmxlbmd0aAppZihzPT09MCl0aHJvdyBILmIoUC5QVigiTm8gZWxlbWVudHMi
-KSkKaWYocz4xKXRocm93IEguYihQLlBWKCJNb3JlIHRoYW4gb25lIGVsZW1lbnQiKSkKcmV0dXJuIHQu
-Zmlyc3RDaGlsZH0sCkZWOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5laC5hKGIpCnQ9Yi5hCnM9
-dGhpcy5hCmlmKHQhPT1zKWZvcihyPXQuY2hpbGROb2Rlcy5sZW5ndGgscT0wO3E8cjsrK3Epcy5hcHBl
-bmRDaGlsZCh0LmZpcnN0Q2hpbGQpCnJldHVybn0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKdS5B
-LmEoYykKdD10aGlzLmEKcz10LmNoaWxkTm9kZXMKaWYoYjwwfHxiPj1zLmxlbmd0aClyZXR1cm4gSC5r
-KHMsYikKdC5yZXBsYWNlQ2hpbGQoYyxzW2JdKX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEu
-Y2hpbGROb2RlcwpyZXR1cm4gbmV3IFcuVzkodCx0Lmxlbmd0aCxILnEodCkuQygiVzk8R20uRT4iKSl9
-LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNoaWxkTm9kZXMubGVuZ3RofSwKcTpmdW5jdGlv
-bihhLGIpe3ZhciB0CkguV1koYikKdD10aGlzLmEuY2hpbGROb2RlcwppZihiPDB8fGI+PXQubGVuZ3Ro
-KXJldHVybiBILmsodCxiKQpyZXR1cm4gdFtiXX19ClcudUgucHJvdG90eXBlPXsKd2c6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YS5wYXJlbnROb2RlCmlmKHQhPW51bGwpdC5yZW1vdmVDaGlsZChhKX0sCkQ0OmZ1bmN0
-aW9uKGEpe3ZhciB0CmZvcig7dD1hLmZpcnN0Q2hpbGQsdCE9bnVsbDspYS5yZW1vdmVDaGlsZCh0KX0s
-Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5ub2RlVmFsdWUKcmV0dXJuIHQ9PW51bGw/dGhpcy5VKGEpOnR9
-LAokaXVIOjF9ClcuQkgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwK
-cTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIo
-UC50KGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dS5B
-LmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlz
-dC4iKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5rKGEsYikK
-cmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBl
-PXt9ClcuZXcucHJvdG90eXBlPXskaWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofX0KVy5UYi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
-dCxzCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUp
-cmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1XLlU5KCI8dGFibGU+IitILmQoYikrIjwvdGFibGU+Iixj
-LGQpCnM9ZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnMudG9TdHJpbmcKdC50b1N0cmlu
-ZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHQpKQpyZXR1cm4gc319ClcuSXYucHJvdG90eXBlPXsK
-cjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVu
-dCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PWRvY3Vt
-ZW50CnM9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKdD1DLkllLnI2KHQuY3JlYXRlRWxlbWVudCgi
-dGFibGUiKSxiLGMsZCkKdC50b1N0cmluZwp0PW5ldyBXLmU3KHQpCnI9dC5ncjgodCkKci50b1N0cmlu
-Zwp0PW5ldyBXLmU3KHIpCnE9dC5ncjgodCkKcy50b1N0cmluZwpxLnRvU3RyaW5nCm5ldyBXLmU3KHMp
-LkZWKDAsbmV3IFcuZTcocSkpCnJldHVybiBzfX0KVy5CVC5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihh
-LGIsYyxkKXt2YXIgdCxzLHIKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJh
-bmdlLnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PWRvY3VtZW50CnM9dC5jcmVhdGVE
-b2N1bWVudEZyYWdtZW50KCkKdD1DLkllLnI2KHQuY3JlYXRlRWxlbWVudCgidGFibGUiKSxiLGMsZCkK
-dC50b1N0cmluZwp0PW5ldyBXLmU3KHQpCnI9dC5ncjgodCkKcy50b1N0cmluZwpyLnRvU3RyaW5nCm5l
-dyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcocikpCnJldHVybiBzfX0KVy55WS5wcm90b3R5cGU9ewpwazpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQscwphLnRleHRDb250ZW50PW51bGwKdD1hLmNvbnRlbnQKdC50b1N0
-cmluZwpKLmJUKHQpCnM9dGhpcy5yNihhLGIsbnVsbCxjKQphLmNvbnRlbnQuYXBwZW5kQ2hpbGQocyl9
-LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCiRpeVk6MX0KVy53Ni5w
-cm90b3R5cGU9e30KVy5LNS5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9jYXRp
-b259LAokaUs1OjEsCiRpdjY6MX0KVy5DbS5wcm90b3R5cGU9eyRpQ206MX0KVy5DUS5wcm90b3R5cGU9
-eyRpQ1E6MX0KVy53NC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJSZWN0YW5nbGUgKCIr
-SC5kKGEubGVmdCkrIiwgIitILmQoYS50b3ApKyIpICIrSC5kKGEud2lkdGgpKyIgeCAiK0guZChhLmhl
-aWdodCl9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUucS5iKGIp
-JiZhLmxlZnQ9PWIubGVmdCYmYS50b3A9PWIudG9wJiZhLndpZHRoPT1iLndpZHRoJiZhLmhlaWdodD09
-Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoSi5oZihhLmxlZnQpLEouaGYoYS50
-b3ApLEouaGYoYS53aWR0aCksSi5oZihhLmhlaWdodCkpfX0KVy5yaC5wcm90b3R5cGU9ewpnQTpmdW5j
-dGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQppZihiPj4+MCE9
-PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLnQoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFb
-Yl19LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2ln
-biBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+
-PWEubGVuZ3RoKXJldHVybiBILmsoYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNY
-OjEsCiRpek06MX0KVy5jZi5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscAp1
-LmVBLmEoYikKZm9yKHQ9dGhpcy5nVigpLHM9dC5sZW5ndGgscj10aGlzLmEscT0wO3E8dC5sZW5ndGg7
-dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9dFtxXQpiLiQyKHAsci5nZXRBdHRyaWJ1dGUo
-cCkpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLmEuYXR0cmlidXRlcyxvPUguVk0o
-W10sdS5zKQpmb3IodD1wLmxlbmd0aCxzPXUuaDkscj0wO3I8dDsrK3Ipe2lmKHI+PXAubGVuZ3RoKXJl
-dHVybiBILmsocCxyKQpxPXMuYShwW3JdKQppZihxLm5hbWVzcGFjZVVSST09bnVsbClDLk5tLmkobyxx
-Lm5hbWUpfXJldHVybiBvfX0KVy5pNy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
-aXMuYS5nZXRBdHRyaWJ1dGUoSC5jKGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5zZXRBdHRy
-aWJ1dGUoYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RofX0KVy5TeS5w
-cm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0
-YS0iK3RoaXMuTyhILmMoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0
-ZSgiZGF0YS0iK3RoaXMuTyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktT
-KHRoaXMsdS5lQS5hKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEu
-SygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-Z1YoKS5sZW5ndGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMp
-CmZvcih0PTE7dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQppZihzLmxlbmd0aD4wKUMuTm0uWShyLHQsc1sw
-XS50b1VwcGVyQ2FzZSgpK0ouS1YocywxKSl9cmV0dXJuIEMuTm0uelYociwiIil9LApPOmZ1bmN0aW9u
-KGEpe3ZhciB0LHMscixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7czx0Oysrcyl7cT1hW3NdCnA9
-cS50b0xvd2VyQ2FzZSgpCnI9KHEhPT1wJiZzPjA/cisiLSI6cikrcH1yZXR1cm4gci5jaGFyQ29kZUF0
-KDApPT0wP3I6cn19ClcuS1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4o
-YSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLmsoQy54Qi5HKGEsNSkpLGIpfSwKJFM6OX0KVy5BMy5w
-cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0
-aGlzLmIsdGhpcy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRTOjl9ClcuSTQucHJvdG90eXBlPXsKUDpmdW5j
-dGlvbigpe3ZhciB0LHMscixxLHA9UC5Mcyh1Lk4pCmZvcih0PXRoaXMuYS5jbGFzc05hbWUuc3BsaXQo
-IiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkKaWYocS5sZW5ndGghPT0wKXAu
-aSgwLHEpfXJldHVybiBwfSwKcDpmdW5jdGlvbihhKXt0aGlzLmEuY2xhc3NOYW1lPXUuQy5hKGEpLnpW
-KDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aH0sClYx
-OmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9IiJ9LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciB0PXRo
-aXMuYS5jbGFzc0xpc3QuY29udGFpbnMoYikKcmV0dXJuIHR9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQ9
-dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikKdC5hZGQoYikKcmV0dXJuIXN9LApSOmZ1bmN0
-aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikKdC5yZW1vdmUoYikK
-cmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe1cuVE4odGhpcy5hLHUuWC5hKGIpKX19ClcuRmsucHJv
-dG90eXBlPXt9ClcuUk8ucHJvdG90eXBlPXt9ClcuZXUucHJvdG90eXBlPXt9ClcueEMucHJvdG90eXBl
-PXt9Clcudk4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMSh1LkIuYShh
-KSl9LAokUzoyOH0KVy5KUS5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhKXt2YXIgdAppZigkLm9yLmE9
-PT0wKXtmb3IodD0wO3Q8MjYyOysrdCkkLm9yLlkoMCxDLmNtW3RdLFcucFMoKSkKZm9yKHQ9MDt0PDEy
-OysrdCkkLm9yLlkoMCxDLkJJW3RdLFcuVjQoKSl9fSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuICQuQU4o
-KS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSQub3IucSgwLEguZChXLnJT
-KGEpKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEoMCwiKjo6IitiKQppZih0PT1udWxsKXJldHVy
-biExCnJldHVybiBILkU5KHQuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpXLkdtLnByb3RvdHlwZT17
-CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgucShhKS5DKCJXOTxH
-bS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0uVnIodGhp
-cy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQy5ObS5Wcih0aGlzLmEs
-bmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
-ZXR1cm4gdS5lLmEoYSkuaTAodGhpcy5hKX0sCiRTOjE1fQpXLkVnLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3JldHVybiB1LmUuYShhKS5FYih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoxNX0KVy5t
-Ni5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKdGhpcy5hLkZWKDAsYykK
-dD1iLmV2KDAsbmV3IFcuRW8oKSkKcz1iLmV2KDAsbmV3IFcuV2soKSkKdGhpcy5iLkZWKDAsdCkKcj10
-aGlzLmMKci5GVigwLEMuZG4pCnIuRlYoMCxzKX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
-dGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD10aGlzLHM9Vy5yUyhhKSxyPXQu
-YwppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNlIGlmKHIudGcoMCwi
-Kjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2V7cj10LmIKaWYoci50ZygwLEguZChzKSsiOjoiK2Ip
-KXJldHVybiEwCmVsc2UgaWYoci50ZygwLCIqOjoiK2IpKXJldHVybiEwCmVsc2UgaWYoci50ZygwLEgu
-ZChzKSsiOjoqIikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsIio6OioiKSlyZXR1cm4hMH1yZXR1cm4h
-MX0sCiRpa0Y6MX0KVy5Fby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4hQy5ObS50ZyhD
-LkJJLEguYyhhKSl9LAokUzo4fQpXLldrLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBD
-Lk5tLnRnKEMuQkksSC5jKGEpKX0sCiRTOjh9ClcuY3QucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxi
-LGMpe2lmKHRoaXMuakYoYSxiLGMpKXJldHVybiEwCmlmKGI9PT0idGVtcGxhdGUiJiZjPT09IiIpcmV0
-dXJuITAKaWYoYS5nZXRBdHRyaWJ1dGUoInRlbXBsYXRlIik9PT0iIilyZXR1cm4gdGhpcy5lLnRnKDAs
-YikKcmV0dXJuITF9fQpXLklBLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiJURU1QTEFU
-RTo6IitILmQoSC5jKGEpKX0sCiRTOjR9ClcuT3cucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7dmFy
-IHQKaWYodS5ldy5iKGEpKXJldHVybiExCnQ9dS5nNy5iKGEpCmlmKHQmJlcuclMoYSk9PT0iZm9yZWln
-bk9iamVjdCIpcmV0dXJuITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkViOmZ1bmN0aW9uKGEsYixj
-KXtpZihiPT09ImlzInx8Qy54Qi5uKGIsIm9uIikpcmV0dXJuITEKcmV0dXJuIHRoaXMuaTAoYSl9LAok
-aWtGOjF9ClcuVzkucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMrMSxyPXQu
-YgppZihzPHIpe3Quc00oSi54OSh0LmEscykpCnQuYz1zCnJldHVybiEwfXQuc00obnVsbCkKdC5jPXIK
-cmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApzTTpmdW5jdGlvbihhKXt0aGlz
-LmQ9dGhpcy4kdGkuYy5hKGEpfSwKJGlBbjoxfQpXLmRXLnByb3RvdHlwZT17CmdtVzpmdW5jdGlvbihh
-KXtyZXR1cm4gVy56WCh0aGlzLmEubG9jYXRpb24pfSwKJGlEMDoxLAokaXY2OjF9ClcuRmIucHJvdG90
-eXBlPXt9Clcua0YucHJvdG90eXBlPXt9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90
-eXBlPXsKUG46ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPW5ldyBXLmZtKHQpCnQuYj0hMQpzLiQyKGEs
-bnVsbCkKZm9yKDt0LmI7KXt0LmI9ITEKcy4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFy
-IHQ9dGhpcy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTp0KUouTHQoYSkKZWxzZSBiLnJl
-bW92ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89ITAsbj1udWxsLG09
-bnVsbAp0cnl7bj1KLmlnKGEpCm09bi5hLmdldEF0dHJpYnV0ZSgiaXMiKQp1LmguYShhKQp0PWZ1bmN0
-aW9uKGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1
-ZQppZihjLmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3Vz
-U2libGluZyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFt
-ZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgbD1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQm
-JmMubGFzdENoaWxkIT09bFtsLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEo
-Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2Yg
-Tm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBrPTAKaWYoYy5jaGlsZHJlbilrPWMuY2hpbGRyZW4ubGVu
-Z3RoCmZvcih2YXIgaj0wO2o8aztqKyspe3ZhciBpPWMuY2hpbGRyZW5bal0KaWYoaS5pZD09J2F0dHJp
-YnV0ZXMnfHxpLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aS5pZD09J2xhc3RDaGlsZCd8fGkubmFtZT09J2xh
-c3RDaGlsZCd8fGkuaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxpLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcn
-fHxpLmlkPT0nY2hpbGRyZW4nfHxpLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZh
-bHNlfShhKQpvPUgub1QodCk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXAp
-fWNhdGNoKHEpe0guUnUocSl9cz0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3M9Si5BYyhhKX1jYXRj
-aChxKXtILlJ1KHEpfXRyeXtyPVcuclMoYSkKdGhpcy5rUih1LmguYShhKSxiLG8scyxyLHUuRy5hKG4p
-LEguYyhtKSl9Y2F0Y2gocSl7aWYoSC5SdShxKSBpbnN0YW5jZW9mIFAuQVQpdGhyb3cgcQplbHNle3Ro
-aXMuRVAoYSxiKQp3aW5kb3cKcD0iUmVtb3ZpbmcgY29ycnVwdGVkIGVsZW1lbnQgIitILmQocykKaWYo
-dHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCl9fX0sCmtSOmZ1
-bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMKaWYoYyl7bi5FUChhLGIp
-CndpbmRvdwp0PSJSZW1vdmluZyBlbGVtZW50IGR1ZSB0byBjb3JydXB0ZWQgYXR0cmlidXRlcyBvbiA8
-IitkKyI+IgppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2Fybih0
-KQpyZXR1cm59aWYoIW4uYS5pMChhKSl7bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBkaXNhbGxv
-d2VkIGVsZW1lbnQgPCIrSC5kKGUpKyI+IGZyb20gIitILmQoYikKaWYodHlwZW9mIGNvbnNvbGUhPSJ1
-bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKGchPW51bGwpaWYoIW4uYS5F
-YihhLCJpcyIsZykpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCB0eXBlIGV4
-dGVuc2lvbiA8IitILmQoZSkrJyBpcz0iJytnKyciPicKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
-ZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufXQ9Zi5nVigpCnM9SC5WTSh0LnNsaWNlKDAp
-LEgudDYodCkuQygiamQ8MT4iKSkKZm9yKHI9Zi5nVigpLmxlbmd0aC0xLHQ9Zi5hO3I+PTA7LS1yKXtp
-ZihyPj1zLmxlbmd0aClyZXR1cm4gSC5rKHMscikKcT1zW3JdCnA9bi5hCm89Si5jSChxKQpILmMocSkK
-aWYoIXAuRWIoYSxvLHQuZ2V0QXR0cmlidXRlKHEpKSl7d2luZG93CnA9IlJlbW92aW5nIGRpc2FsbG93
-ZWQgYXR0cmlidXRlIDwiK0guZChlKSsiICIrcSsnPSInK0guZCh0LmdldEF0dHJpYnV0ZShxKSkrJyI+
-JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKQp0LnJl
-bW92ZUF0dHJpYnV0ZShxKX19aWYodS5hVy5iKGEpKW4uUG4oYS5jb250ZW50KX0sCiRpb246MX0KVy5m
-bS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMuYQpzd2l0
-Y2goYS5ub2RlVHlwZSl7Y2FzZSAxOm4uSTQoYSxiKQpicmVhawpjYXNlIDg6Y2FzZSAxMTpjYXNlIDM6
-Y2FzZSA0OmJyZWFrCmRlZmF1bHQ6bi5FUChhLGIpfXQ9YS5sYXN0Q2hpbGQKZm9yKHI9dS5BO251bGwh
-PXQ7KXtzPW51bGwKdHJ5e3M9dC5wcmV2aW91c1NpYmxpbmcKaWYocyE9bnVsbCl7cT1zLm5leHRTaWJs
-aW5nCnA9dApwPXE9PW51bGw/cCE9bnVsbDpxIT09cApxPXB9ZWxzZSBxPSExCmlmKHEpe3E9UC5QVigi
-Q29ycnVwdCBIVE1MIikKdGhyb3cgSC5iKHEpfX1jYXRjaChvKXtILlJ1KG8pCnE9ci5hKHQpCm4uYj0h
-MApwPXEucGFyZW50Tm9kZQpwPWE9PW51bGw/cCE9bnVsbDphIT09cAppZihwKXtwPXEucGFyZW50Tm9k
-ZQppZihwIT1udWxsKXAucmVtb3ZlQ2hpbGQocSl9ZWxzZSBhLnJlbW92ZUNoaWxkKHEpCnQ9bnVsbApz
-PWEubGFzdENoaWxkfWlmKHQhPW51bGwpdGhpcy4kMih0LGEpCnQ9c319LAokUzozOX0KVy5MZS5wcm90
-b3R5cGU9e30KVy5LNy5wcm90b3R5cGU9e30KVy5yQi5wcm90b3R5cGU9e30KVy5YVy5wcm90b3R5cGU9
-e30KVy5vYS5wcm90b3R5cGU9e30KUC5pSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihhKXt2YXIgdCxz
-PXRoaXMuYSxyPXMubGVuZ3RoCmZvcih0PTA7dDxyOysrdClpZihzW3RdPT09YSlyZXR1cm4gdApDLk5t
-LmkocyxhKQpDLk5tLmkodGhpcy5iLG51bGwpCnJldHVybiByfSwKUHY6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyLHE9dGhpcyxwPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5yUShhKSlyZXR1cm4gYQppZih0
-eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCmlm
-KGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHUuZnYuYihhKSl0aHJvdyBI
-LmIoUC5uKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIFJlZ0V4cCIpKQppZih1LmM4LmIoYSkpcmV0dXJuIGEK
-aWYodS5kLmIoYSkpcmV0dXJuIGEKaWYodS5JLmIoYSkpcmV0dXJuIGEKdD11LmRELmIoYSl8fCExCmlm
-KHQpcmV0dXJuIGEKaWYodS5HLmIoYSkpe3M9cS5WSChhKQp0PXEuYgppZihzPj10Lmxlbmd0aClyZXR1
-cm4gSC5rKHQscykKcj1wLmE9dFtzXQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5hPXIKQy5ObS5Z
-KHQscyxyKQphLksoMCxuZXcgUC5qZyhwLHEpKQpyZXR1cm4gcC5hfWlmKHUuai5iKGEpKXtzPXEuVkgo
-YSkKcD1xLmIKaWYocz49cC5sZW5ndGgpcmV0dXJuIEguayhwLHMpCnI9cFtzXQppZihyIT1udWxsKXJl
-dHVybiByCnJldHVybiBxLmVrKGEscyl9aWYodS5lSC5iKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49
-dC5sZW5ndGgpcmV0dXJuIEguayh0LHMpCnI9cC5iPXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9
-CnAuYj1yCkMuTm0uWSh0LHMscikKcS5pbShhLG5ldyBQLlRhKHAscSkpCnJldHVybiBwLmJ9dGhyb3cg
-SC5iKFAubigic3RydWN0dXJlZCBjbG9uZSBvZiBvdGhlciB0eXBlIikpfSwKZWs6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzPUouVTYoYSkscj1zLmdBKGEpLHE9bmV3IEFycmF5KHIpCkMuTm0uWSh0aGlzLmIsYixx
-KQpmb3IodD0wO3Q8cjsrK3QpQy5ObS5ZKHEsdCx0aGlzLlB2KHMucShhLHQpKSkKcmV0dXJuIHF9fQpQ
-LmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmFbYV09dGhpcy5iLlB2KGIpfSwK
-JFM6MX0KUC5UYS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5iW2FdPXRoaXMuYi5Q
-dihiKX0sCiRTOjF9ClAuQmYucHJvdG90eXBlPXsKaW06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1
-LmI4LmEoYikKZm9yKHQ9T2JqZWN0LmtleXMoYSkscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT10W3Jd
-CmIuJDIocSxhW3FdKX19fQpQLkFzLnByb3RvdHlwZT17ClQ6ZnVuY3Rpb24oYSl7dmFyIHQKSC5jKGEp
-CnQ9JC5oRygpLmIKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC5JKGEpKQppZih0LnRlc3QoYSkp
-cmV0dXJuIGEKdGhyb3cgSC5iKFAuTDMoYSwidmFsdWUiLCJOb3QgYSB2YWxpZCBjbGFzcyB0b2tlbiIp
-KX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLnpWKDAsIiAiKX0sCmdrejpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLlAoKQpyZXR1cm4gUC5yaih0LHQucixILkxoKHQpLmMpfSwKZ0E6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuUCgpLmF9LAp0ZzpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gdGhp
-cy5QKCkudGcoMCxiKX0sCmk6ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIEguRTkodGhpcy5P
-UyhuZXcgUC5HRShiKSkpfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKdGhpcy5UKGIpCnQ9dGhpcy5Q
-KCkKcz10LlIoMCxiKQp0aGlzLnAodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1Mo
-bmV3IFAuTjcodGhpcyx1LlguYShiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgp
-KX0sCk9TOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5iVS5hKGEpCnQ9dGhpcy5QKCkKcz1hLiQxKHQpCnRo
-aXMucCh0KQpyZXR1cm4gc319ClAuR0UucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUu
-Qy5hKGEpLmkoMCx0aGlzLmEpfSwKJFM6MzJ9ClAuTjcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
-dmFyIHQ9dGhpcy5iLHM9SC50Nih0KQpyZXR1cm4gdS5DLmEoYSkuRlYoMCxuZXcgSC5sSih0LHMuQygi
-cVUoMSkiKS5hKHRoaXMuYS5ndU0oKSkscy5DKCJsSjwxLHFVPiIpKSl9LAokUzoxNn0KUC51US5wcm90
-b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LkMuYShhKQppZihhLmE+MCl7YS5iPWEuYz1hLmQ9YS5lPWEu
-Zj1udWxsCmEuYT0wCmEuWCgpfXJldHVybiBudWxsfSwKJFM6MTZ9ClAuaEYucHJvdG90eXBlPXskaWhG
-OjF9ClAuUEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5aLmEoYSkKdD1mdW5jdGlv
-bihiLGMsZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGIoYyxkLHRoaXMsQXJyYXkucHJvdG90eXBl
-LnNsaWNlLmFwcGx5KGFyZ3VtZW50cykpfX0oUC5SNCxhLCExKQpQLkRtKHQsJC53USgpLGEpCnJldHVy
-biB0fSwKJFM6M30KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMu
-YShhKX0sCiRTOjN9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3
-KGEpfSwKJFM6MzR9ClAubnAucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6
-KGEsdS5hbSl9LAokUzozNX0KUC5VdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
-IFAuRTQoYSl9LAokUzozNn0KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9m
-IGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlz
-IG5vdCBhIFN0cmluZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24o
-YSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQ
-LnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwK
-RE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5F
-NCYmdGhpcy5hPT09Yi5hfSwKWjpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEp
-CnJldHVybiB0fWNhdGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0
-aW9uKGEsYil7dmFyIHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1Q
-LkNIKG5ldyBILmxKKGIsdC5DKCJAKDEpIikuYShQLmlHKCkpLHQuQygibEo8MSxAPiIpKSwhMCx1Lnop
-fXJldHVybiBQLkw3KHNbYV0uYXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQ
-LnI3LnByb3RvdHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMs
-cz1hPDB8fGE+PXQuZ0EodCkKaWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwp
-KX0sCnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYj09Im51bWJlciImJmI9PT1DLmpuLnl1KGIpKXRo
-aXMuY1AoSC5XWShiKSkKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQKdGhpcy4kdGkuYy5hKGMpCnQ9Qy5qbi55dShiKQppZihiPT09dCl0aGlzLmNQ
-KGIpCnRoaXMuZTQoMCxiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0
-eXBlb2YgdD09PSJudW1iZXIiJiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBK
-c0FycmF5IGxlbmd0aCIpKX0sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9
-ClAubmQucHJvdG90eXBlPXskaW5kOjF9ClAuS2UucHJvdG90eXBlPXsKUDpmdW5jdGlvbigpe3ZhciB0
-LHMscixxLHA9dGhpcy5hLmdldEF0dHJpYnV0ZSgiY2xhc3MiKSxvPVAuTHModS5OKQppZihwPT1udWxs
-KXJldHVybiBvCmZvcih0PXAuc3BsaXQoIiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAo
-dFtyXSkKaWYocS5sZW5ndGghPT0wKW8uaSgwLHEpfXJldHVybiBvfSwKcDpmdW5jdGlvbihhKXt0aGlz
-LmEuc2V0QXR0cmlidXRlKCJjbGFzcyIsYS56VigwLCIgIikpfX0KUC5kNS5wcm90b3R5cGU9ewpnRDpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuS2UoYSl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEs
-Yil9LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYoZD09bnVsbCl7dD1ILlZN
-KFtdLHUuaykKZD1uZXcgVy52RCh0KQpDLk5tLmkodCxXLlR3KG51bGwpKQpDLk5tLmkodCxXLkJsKCkp
-CkMuTm0uaSh0LG5ldyBXLk93KCkpfWM9bmV3IFcuS28oZCkKcz0nPHN2ZyB2ZXJzaW9uPSIxLjEiPicr
-SC5kKGIpKyI8L3N2Zz4iCnQ9ZG9jdW1lbnQKcj10LmJvZHkKcT0ociYmQy5SWSkuQUgocixzLGMpCnA9
-dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKcS50b1N0cmluZwp0PW5ldyBXLmU3KHEpCm89dC5ncjgo
-dCkKZm9yKDt0PW8uZmlyc3RDaGlsZCx0IT1udWxsOylwLmFwcGVuZENoaWxkKHQpCnJldHVybiBwfSwK
-Z1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRpZDU6MX0K
-UC5uNi5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxLCRpQVM6MX0KVS5kMi5wcm90b3R5cGU9
-e30KVS5TZS5wcm90b3R5cGU9e30KVS51Ri5wcm90b3R5cGU9e30KVS5NbC5wcm90b3R5cGU9e30KVS55
-RC5wcm90b3R5cGU9e30KVS53Yi5wcm90b3R5cGU9e30KQi5qOC5wcm90b3R5cGU9e30KQi5xcC5wcm90
-b3R5cGU9e30KVC5tUS5wcm90b3R5cGU9e30KTC5lLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHAsbyxuCnUuQi5hKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3
-aW5kb3cubG9jYXRpb24uaHJlZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYo
-dCE9PSIvIiYmdCE9PUouVDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVu
-dCkpTC5HNyh0LHMsciwhMCxuZXcgTC5WVyh0LHMscikpCnE9ZG9jdW1lbnQKcD1KLnFGKHEucXVlcnlT
-ZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpvPXAuJHRpCm49by5DKCJ+KDEpIikuYShuZXcgTC5v
-WigpKQp1Lk0uYShudWxsKQpXLkpFKHAuYSxwLmIsbiwhMSxvLmMpCnE9Si5xRihxLnF1ZXJ5U2VsZWN0
-b3IoIi5yZXJ1bi1taWdyYXRpb24iKSkKbz1xLiR0aQpXLkpFKHEuYSxxLmIsby5DKCJ+KDEpIikuYShu
-ZXcgTC55OCgpKSwhMSxvLmMpfSwKJFM6MTd9CkwuVlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtM
-LkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7dS5WLmEoYSkKaWYoSC5vVCh3aW5kb3cuY29uZmlybSgiVGhpcyB3aWxsIGFwcGx5IHRoZSBj
-aGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVj
-b21tZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4i
-KSkpTC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIpLlc3KG5ldyBMLmpyKCksdS5QKS5PQShuZXcgTC5xbCgp
-KX0sCiRTOjV9CkwuanIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5yLmEoYSkKdD1k
-b2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQp0LmNsYXNzTGlzdC5hZGQo
-ImFwcGxpZWQiKX0sCiRTOjd9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJh
-cHBseSBtaWdyYXRpb24gZXJyb3I6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGFw
-cGx5IG1pZ3JhdGlvbiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLnk4LnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnhuKHUuVi5hKGEpKX0sCnhuOmZ1bmN0
-aW9uKGEpe3ZhciB0PTAscz1QLkZYKHUuUCkscj0xLHEscD1bXSxvLG4sbSxsCnZhciAkYXN5bmMkJDE9
-UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nh
-c2UgMDpyPTMKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCJyZXJ1bm5pbmciKQp0PTYKcmV0dXJu
-IFAualEoTC50eSgiL3JlcnVuLW1pZ3JhdGlvbiIpLCRhc3luYyQkMSkKY2FzZSA2OndpbmRvdy5sb2Nh
-dGlvbi5yZWxvYWQoKQpwLnB1c2goNSkKdD00CmJyZWFrCmNhc2UgMzpyPTIKbD1xCm89SC5SdShsKQpu
-PUgudHMobCkKTC5xSigicmVydW4gbWlncmF0aW9uOiAiK0guZChvKSxuKQp3aW5kb3cuYWxlcnQoIkZh
-aWxlZCB0byByZXJ1biBtaWdyYXRpb246ICIrSC5kKG8pKyIuIikKcC5wdXNoKDUpCnQ9NApicmVhawpj
-YXNlIDI6cD1bMV0KY2FzZSA0OnI9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoInJlcnVu
-bmluZyIpCnQ9cC5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNlIDE6cmV0
-dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzo0MH0KTC5MLnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LkIuYShhKQp0PXdpbmRvdy5sb2NhdGlvbi5w
-YXRobmFtZQpzPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24u
-aHJlZikKaWYodC5sZW5ndGg+MSlMLkc3KHQscyxyLCExLG51bGwpCmVsc2V7TC5CRSh0LG5ldyBCLnFw
-KCIiLCIiLCIiLEMueEQpLCEwKQpMLkJYKCImbmJzcDsiLG51bGwpfX0sCiRTOjE3fQpMLld4LnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPSJjb2xsYXBzZWQiCnUuVi5hKGEpCnQ9dGhp
-cy5hCnM9Si5SRSh0KQpyPXRoaXMuYgppZighcy5nRCh0KS50ZygwLHEpKXtzLmdEKHQpLmkoMCxxKQpK
-LmRSKHIpLmkoMCxxKX1lbHNle3MuZ0QodCkuUigwLHEpCkouZFIocikuUigwLHEpfX0sCiRTOjV9Ckwu
-QU8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYShhKSkscz10LiR0aSxy
-PXMuQygifigxKSIpLmEobmV3IEwuZE4odGhpcy5hKSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLHIs
-ITEscy5jKX0sCiRTOjZ9CkwuZE4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmEo
-YSkKdD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKdC50b1N0cmluZwpM
-LnQyKGEsdGhpcy5hLHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8o
-InBhdGgiKSkpfSwKJFM6NX0KTC5Iby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIK
-dS5oLmEoYSkKdD1KLnFGKGEpCnM9dC4kdGkKcj1zLkMoIn4oMSkiKS5hKG5ldyBMLnh6KGEsdGhpcy5h
-KSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLHIsITEscy5jKX0sCiRTOjZ9CkwueHoucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscz1udWxsCnUuVi5hKGEpCnQ9dGhpcy5hCkwuaFgodGhpcy5i
-LFAuUUEodC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygib2Zmc2V0
-IikpLHMscyksUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5P
-KCJsaW5lIikpLHMscykpfSwKJFM6NX0KTC5JQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
-dD1KLnFGKHUuaC5hKGEpKSxzPXQuJHRpCnMuQygifigxKSIpLmEoTC5IMCgpKQp1Lk0uYShudWxsKQpX
-LkpFKHQuYSx0LmIsTC5IMCgpLCExLHMuYyl9LAokUzo2fQpMLkwxLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciB0CnUuci5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMClyZXR1cm4gYQplbHNlIHRo
-cm93IEguYigiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo0Mn0KTC5uVC5w
-cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhpcy5hLmEsdGhpcy5iLHRoaXMuYyl9LAokUzow
-fQpMLkJaLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSxudWxsLG51bGwpfSwK
-JFM6MH0KTC5HSC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LmguYShhKQokLnpCKCkudG9TdHJp
-bmcKdS52LmEoJC5vdygpLnEoMCwiaGxqcyIpKS5WNygiaGlnaGxpZ2h0QmxvY2siLFthXSl9LAokUzo2
-fQpMLkRULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuci5hKGEpCnQ9YS5zdGF0dXMK
-aWYodD09PTIwMCl7TC5UMShVLnl1KEMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKSkpCkwuRnIo
-dGhpcy5hLHRoaXMuYix0aGlzLmMpCkwueVgoIi5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50IiwhMSl9
-ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6
-N30KTC5lSC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxvYWRSZWdpb25FeHBsYW5h
-dGlvbjogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK0guZCh0aGlzLmEp
-KyIgKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC56RC5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcwp1LnIuYShhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDAp
-e3M9ci5hCkwuQkUocyxCLllmKHUuYi5hKEMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKSkpLHIu
-YikKdD1yLmMKTC5mRyh0LHIuZCkKTC5CWChDLnhCLnRnKHMsIj8iKT9DLnhCLncocywwLEMueEIuT1ko
-cywiPyIpKTpzLHQpCnQ9ci5lCmlmKHQhPW51bGwpdC4kMCgpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1
-ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIrSC5kKHQpKX0sCiRTOjd9CkwuT0UucHJvdG90eXBlPXsKJDI6
-ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkRmlsZTogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3Vs
-ZCBub3QgbG9hZCAiK3RoaXMuYSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9
-CkwuVFcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuci5hKGEpCnQ9YS5zdGF0
-dXMKaWYodD09PTIwMCl7cz1DLkN0LnBXKDAsYS5yZXNwb25zZVRleHQsbnVsbCkKcj1kb2N1bWVudC5x
-dWVyeVNlbGVjdG9yKCIubmF2LXRyZWUiKQpKLmw1KHIsIiIpCkwudFgocixMLm1LKHMpKX1lbHNlIHdp
-bmRvdy5hbGVydCgiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo3fQpMLnhy
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5xSigibG9hZE5hdmlnYXRpb25UcmVlOiAiK0gu
-ZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5vdCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEpKyIp
-LiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
-YXIgdCxzCnUuVi5hKGEpCnQ9dGhpcy5hCnM9dGhpcy5iCkwuYWYod2luZG93LmxvY2F0aW9uLnBhdGhu
-YW1lLHQscywhMCxuZXcgTC5RTCh0LHMpKQpMLmhYKHRoaXMuYyx0LHMpfSwKJFM6NX0KTC5RTC5wcm90
-b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0
-aGlzLmIpfSwKJFM6MH0KTC5WUy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxl
-Y3RlZC1maWxlIgp1LmguYShhKQphLnRvU3RyaW5nCnQ9Si5SRShhKQppZihhLmdldEF0dHJpYnV0ZSgi
-ZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEpKS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nRChhKS5p
-KDAscykKZWxzZSB0LmdEKGEpLlIoMCxzKX0sCiRTOjZ9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEwudDIodS5WLmEoYSksITAsbnVsbCl9LAokUzoxOH0KTC5YQS5wcm90b3R5cGU9
-ewpFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRp
-a0Y6MX0KTC5aWi5wcm90b3R5cGU9e30KTC5POS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmJ9fQpNLmxJLnByb3RvdHlwZT17CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0u
-WUYoImFic29sdXRlIixILlZNKFtiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LnMpKQp0
-PXRoaXMuYQp0PXQuWXIoYik+MCYmIXQuaEsoYikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4g
-dGhpcy5xNygwLHQsYixzLHMscyxzLHMscyl9LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChh
-LHRoaXMuYSkKci5JVigpCnQ9ci5kCnM9dC5sZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1u
-dWxsPyIuIjp0fWlmKHM9PT0xKXt0PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVy
-biBILmsodCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSkKci5JVigpCnJldHVybiByLlooMCl9LApxNzpm
-dW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQ9SC5WTShbYixjLGQsZSxmLGcsaCxpXSx1LnMp
-Ck0uWUYoImpvaW4iLHQpCnJldHVybiB0aGlzLklQKG5ldyBILlU1KHQsdS5iQi5hKG5ldyBNLk1pKCkp
-LHUuY2MpKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbAp1LlguYShhKQpmb3Io
-dD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5hKG5ldyBNLnE3KCkpLHI9YS5na3ooYSksdD1uZXcgSC52
-RyhyLHMsdC5DKCJ2RzxjWC5FPiIpKSxzPXRoaXMuYSxxPSExLHA9ITEsbz0iIjt0LkYoKTspe249ci5n
-bCgpCmlmKHMuaEsobikmJnApe209WC5DTChuLHMpCmw9by5jaGFyQ29kZUF0KDApPT0wP286bwpvPUMu
-eEIudyhsLDAscy5TcChsLCEwKSkKbS5iPW8KaWYocy5kcyhvKSlDLk5tLlkobS5lLDAscy5nbUkoKSkK
-bz1tLlooMCl9ZWxzZSBpZihzLllyKG4pPjApe3A9IXMuaEsobikKbz1ILmQobil9ZWxzZXtpZighKG4u
-bGVuZ3RoPjAmJnMuVWQoblswXSkpKWlmKHEpbys9cy5nbUkoKQpvKz1ILmQobil9cT1zLmRzKG4pfXJl
-dHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKbzU6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoIXRoaXMu
-eTMoYSkpcmV0dXJuIGEKdD1YLkNMKGEsdGhpcy5hKQp0LnJSKCkKcmV0dXJuIHQuWigwKX0sCnkzOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrCmEudG9TdHJpbmcKdD10aGlzLmEKcz10Llly
-KGEpCmlmKHMhPT0wKXtpZih0PT09JC5LaygpKWZvcihyPTA7cjxzOysrcilpZihDLnhCLlcoYSxyKT09
-PTQ3KXJldHVybiEwCnE9cwpwPTQ3fWVsc2V7cT0wCnA9bnVsbH1mb3Iobz1uZXcgSC5xaihhKS5hLG49
-by5sZW5ndGgscj1xLG09bnVsbDtyPG47KytyLG09cCxwPWwpe2w9Qy54Qi5tKG8scikKaWYodC5yNChs
-KSl7aWYodD09PSQuS2soKSYmbD09PTQ3KXJldHVybiEwCmlmKHAhPW51bGwmJnQucjQocCkpcmV0dXJu
-ITAKaWYocD09PTQ2KWs9bT09bnVsbHx8bT09PTQ2fHx0LnI0KG0pCmVsc2Ugaz0hMQppZihrKXJldHVy
-biEwfX1pZihwPT1udWxsKXJldHVybiEwCmlmKHQucjQocCkpcmV0dXJuITAKaWYocD09PTQ2KXQ9bT09
-bnVsbHx8dC5yNChtKXx8bT09PTQ2CmVsc2UgdD0hMQppZih0KXJldHVybiEwCnJldHVybiExfSwKSFA6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89dGhpcyxuPSdVbmFibGUgdG8gZmluZCBhIHBhdGgg
-dG8gIicKYj1vLldPKDAsYikKdD1vLmEKaWYodC5ZcihiKTw9MCYmdC5ZcihhKT4wKXJldHVybiBvLm81
-KGEpCmlmKHQuWXIoYSk8PTB8fHQuaEsoYSkpYT1vLldPKDAsYSkKaWYodC5ZcihhKTw9MCYmdC5Zcihi
-KT4wKXRocm93IEguYihYLkk3KG4rSC5kKGEpKyciIGZyb20gIicrSC5kKGIpKyciLicpKQpzPVguQ0wo
-Yix0KQpzLnJSKCkKcj1YLkNMKGEsdCkKci5yUigpCnE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVsw
-XSwiLiIpKXJldHVybiByLlooMCkKcT1zLmIKcD1yLmIKaWYocSE9cClxPXE9PW51bGx8fHA9PW51bGx8
-fCF0Lk5jKHEscCkKZWxzZSBxPSExCmlmKHEpcmV0dXJuIHIuWigwKQp3aGlsZSghMCl7cT1zLmQKaWYo
-cS5sZW5ndGg+MCl7cD1yLmQKcT1wLmxlbmd0aD4wJiZ0Lk5jKHFbMF0scFswXSl9ZWxzZSBxPSExCmlm
-KCFxKWJyZWFrCkMuTm0uVzQocy5kLDApCkMuTm0uVzQocy5lLDEpCkMuTm0uVzQoci5kLDApCkMuTm0u
-VzQoci5lLDEpfXE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVswXSwiLi4iKSl0aHJvdyBILmIoWC5J
-NyhuK0guZChhKSsnIiBmcm9tICInK0guZChiKSsnIi4nKSkKcT11Lk4KQy5ObS5VRyhyLmQsMCxQLk84
-KHMuZC5sZW5ndGgsIi4uIixxKSkKQy5ObS5ZKHIuZSwwLCIiKQpDLk5tLlVHKHIuZSwxLFAuTzgocy5k
-Lmxlbmd0aCx0LmdtSSgpLHEpKQp0PXIuZApxPXQubGVuZ3RoCmlmKHE9PT0wKXJldHVybiIuIgppZihx
-PjEmJkouUk0oQy5ObS5ncloodCksIi4iKSl7dD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJuIEguayh0
-LC0xKQp0LnBvcCgpCnQ9ci5lCkMuTm0ubXYodCkKQy5ObS5tdih0KQpDLk5tLmkodCwiIil9ci5iPSIi
-CnIuSVYoKQpyZXR1cm4gci5aKDApfX0KTS5NaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
-cm4gSC5jKGEpIT1udWxsfSwKJFM6OH0KTS5xNy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
-cm4gSC5jKGEpIT09IiJ9LAokUzo4fQpNLk5vLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guYyhh
-KQpyZXR1cm4gYT09bnVsbD8ibnVsbCI6JyInK2ErJyInfSwKJFM6NH0KQi5MdS5wcm90b3R5cGU9ewp4
-WjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuWXIoYSkKaWYocz4wKXJldHVybiBKLmxkKGEsMCxzKQpp
-Zih0aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aClyZXR1cm4gSC5rKGEsMCkKdD1hWzBdfWVsc2UgdD1u
-dWxsCnJldHVybiB0fSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn19ClguV0QucHJvdG90eXBl
-PXsKSVY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcwp3aGlsZSghMCl7dD1yLmQKaWYoISh0Lmxlbmd0
-aCE9PTAmJkouUk0oQy5ObS5ncloodCksIiIpKSlicmVhawp0PXIuZAppZigwPj10Lmxlbmd0aClyZXR1
-cm4gSC5rKHQsLTEpCnQucG9wKCkKQy5ObS5tdihyLmUpfXQ9ci5lCnM9dC5sZW5ndGgKaWYocz4wKUMu
-Tm0uWSh0LHMtMSwiIil9LApyUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcyxsPUgu
-Vk0oW10sdS5zKQpmb3IodD1tLmQscz10Lmxlbmd0aCxyPTAscT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9
-PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9dFtxXQpvPUouaWEocCkKaWYoIShvLkROKHAsIi4iKXx8by5E
-TihwLCIiKSkpaWYoby5ETihwLCIuLiIpKWlmKGwubGVuZ3RoPjApbC5wb3AoKQplbHNlICsrcgplbHNl
-IEMuTm0uaShsLHApfWlmKG0uYj09bnVsbClDLk5tLlVHKGwsMCxQLk84KHIsIi4uIix1Lk4pKQppZihs
-Lmxlbmd0aD09PTAmJm0uYj09bnVsbClDLk5tLmkobCwiLiIpCm49UC5kSChsLmxlbmd0aCxuZXcgWC5x
-UihtKSwhMCx1Lk4pCnQ9bS5iCnQ9dCE9bnVsbCYmbC5sZW5ndGg+MCYmbS5hLmRzKHQpP20uYS5nbUko
-KToiIgpILnQ2KG4pLmMuYSh0KQppZighIW4uZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0Iikp
-Cm4uc3BsaWNlKDAsMCx0KQptLnNuSihsKQptLnNQaChuKQp0PW0uYgppZih0IT1udWxsJiZtLmE9PT0k
-LktrKCkpe3QudG9TdHJpbmcKbS5iPUgueXModCwiLyIsIlxcIil9bS5JVigpfSwKWjpmdW5jdGlvbihh
-KXt2YXIgdCxzLHI9dGhpcyxxPXIuYgpxPXEhPW51bGw/cToiIgpmb3IodD0wO3Q8ci5kLmxlbmd0aDsr
-K3Qpe3M9ci5lCmlmKHQ+PXMubGVuZ3RoKXJldHVybiBILmsocyx0KQpzPXErSC5kKHNbdF0pCnE9ci5k
-CmlmKHQ+PXEubGVuZ3RoKXJldHVybiBILmsocSx0KQpxPXMrSC5kKHFbdF0pfXErPUguZChDLk5tLmdy
-WihyLmUpKQpyZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0wP3E6cX0sCnNuSjpmdW5jdGlvbihhKXt0aGlz
-LmQ9dS5hLmEoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhpcy5lPXUuYS5hKGEpfX0KWC5xUi5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmEuZ21JKCl9LAokUzo0NH0KWC5kdi5wcm90
-b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhjZXB0aW9uOiAiK3RoaXMuYX19Ck8uekwu
-cHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nb2ModGhpcyl9fQpFLk9GLnByb3Rv
-dHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEp
-e3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aApyZXR1cm4gdCE9PTAm
-JkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYoYS5sZW5ndGghPT0wJiZDLnhC
-LlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-U3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJw
-b3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0
-aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9
-LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4hMQppZihDLnhCLm0o
-YSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIuVGMoYSwiOi8vIikmJnRoaXMuWXIoYSk9PT10
-fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiAw
-CmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9yKHQ9MDt0PHA7Kyt0KXtzPUMueEIuVyhhLHQp
-CmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lmKHQ9PT0wKXJldHVybiAwCnI9Qy54Qi5YVShh
-LCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQppZihyPD0wKXJldHVybiBwCmlmKCFifHxwPHIr
-MylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8iKSlyZXR1cm4gcgppZighQi5ZdShhLHIrMSkp
-cmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0fX1yZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEp
-e3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RoIT09MCYm
-Qy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ1cmwifSwKZ21JOmZ1bmN0aW9u
-KCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi50
-ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fHxhPT09OTJ9LApkczpmdW5jdGlv
-bihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4hMQp0PUMueEIubShhLHQtMSkKcmV0dXJu
-ISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1hLmxlbmd0aAppZihy
-PT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9PT00NylyZXR1cm4gMQppZih0PT09OTIpe2lm
-KHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpzPUMueEIuWFUoYSwiXFwiLDIpCmlmKHM+MCl7
-cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1cm4gc31yZXR1cm4gcn1pZihyPDMpcmV0dXJu
-IDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5XKGEsMSkhPT01OClyZXR1cm4gMApyPUMueEIu
-VyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVybiAwCnJldHVybiAzfSwKWXI6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ZcihhKT09
-PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PT1iKXJldHVybiEwCmlmKGE9PT00NylyZXR1
-cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3CmlmKChhXmIpIT09MzIpcmV0dXJuITEKdD1h
-fDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKaWYoYT09
-YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxlbmd0aClyZXR1cm4hMQpmb3Iocz1KLnJZKGIp
-LHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhhLHIpLHMuVyhiLHIpKSlyZXR1cm4hMQpyZXR1
-cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5kb3dzIn0sCmdtSTpmdW5jdGlvbigpe3JldHVy
-biJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0PUoudkIucHJvdG90eXBlCnQuVT10LloKdC5T
-aj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQuWgp0PVAuY1gucHJvdG90eXBlCnQuR0c9dC5ldgp0
-PVAuTWgucHJvdG90eXBlCnQueGI9dC5aCnQ9Vy5jdi5wcm90b3R5cGUKdC5EVz10LnI2CnQ9Vy5tNi5w
-cm90b3R5cGUKdC5qRj10LkViCnQ9UC5FNC5wcm90b3R5cGUKdC5Vcj10LnEKdC5lND10Lll9KSgpOyhm
-dW5jdGlvbiBpbnN0YWxsVGVhck9mZnMoKXt2YXIgdD1odW5rSGVscGVycy5fc3RhdGljXzEscz1odW5r
-SGVscGVycy5fc3RhdGljXzAscj1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHE9aHVu
-a0hlbHBlcnMuaW5zdGFsbFN0YXRpY1RlYXJPZmYscD1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKdChQ
-LCJFWCIsIlpWIiwxMCkKdChQLCJ5dCIsIm9BIiwxMCkKdChQLCJxVyIsIkJ6IiwxMCkKcyhQLCJWOSIs
-ImVOIiwyKQpyKFAuUGYucHJvdG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJw
-bSJdLDI5LDApCnQoUCwiUEgiLCJNdCIsNCkKcShXLCJwUyIsNCxudWxsLFsiJDQiXSxbInlXIl0sMTEs
-MCkKcShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sMTEsMCkKcChQLkFzLnByb3RvdHlwZSwiZ3VN
-IiwiVCIsNCkKdChQLCJpRyIsIndZIiwzKQp0KFAsIncwIiwiTDciLDMxKQp0KEwsIkgwIiwidW0iLDE4
-KX0pKCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFyIHQ9aHVua0hlbHBlcnMubWl4aW4scz1odW5r
-SGVscGVycy5pbmhlcml0LHI9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcyhQLk1oLG51bGwpCnIoUC5N
-aCxbSC5GSyxKLnZCLEoubTEsUC5uWSxQLmNYLEguYTcsUC5BbixILlNVLEguUmUsSC53dixQLlBuLEgu
-V1UsSC5MSSxILlRwLEguZjksUC5YUyxILmJxLEguWE8sUC5ZayxILmRiLEguTjYsSC5WUixILkVLLEgu
-UGIsSC50USxILlNkLEguSmMsSC5FVCxQLlczLFAuaWgsUC5GeSxQLkdWLFAuYjgsUC5QZixQLkZlLFAu
-dnMsUC5PTSxQLnFoLFAuTU8sUC5rVCxQLnhJLFAuT0gsUC5tMCxQLlh2LFAuYm4sUC5sbSxQLmxELFAu
-S1AsUC5NYSxQLlRDLFAuVWssUC5SdyxQLmJ6LFAuYTIsUC5pUCxQLmxmLFAuazUsUC5LWSxQLkNELFAu
-YUUsUC5FSCxQLnpNLFAuWjAsUC5OMyxQLmM4LFAuT2QsUC5pYixQLkd6LFAuWmQsUC5xVSxQLlJuLFAu
-R0QsUC5EbixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZELFcubTYsVy5PdyxXLlc5LFcu
-ZFcsVy5GYixXLmtGLFcubWssVy5LbyxQLmlKLFAuRTQsUC5uNixVLmQyLFUuU2UsVS51RixVLk1sLFUu
-eUQsVS53YixCLmo4LEIucXAsVC5tUSxMLlhBLEwuWlosTC5POSxNLmxJLE8uekwsWC5XRCxYLmR2XSkK
-cihKLnZCLFtKLnlFLEouWUUsSi5NRixKLmpkLEoucUksSi5EcixILnBGLFcuRDAsVy5BeixXLkxlLFcu
-TmgsVy5JQixXLm43LFcuZWEsVy5icixXLlNnLFcudTgsVy5LNyxXLlhXLFAuaEZdKQpyKEouTUYsW0ou
-aUMsSi5rZCxKLmM1XSkKcyhKLlBvLEouamQpCnIoSi5xSSxbSi51cixKLlZBXSkKcyhQLkxVLFAublkp
-CnIoUC5MVSxbSC53MixXLnd6LFcuZTddKQpzKEgucWosSC53MikKcihQLmNYLFtILmJRLEguaTEsSC5V
-NSxILlhSLFAubVcsSC5ORl0pCnIoSC5iUSxbSC5hTCxILmk1LFAueHVdKQpyKEguYUwsW0gubkgsSC5s
-SixQLmk4XSkKcyhILnh5LEguaTEpCnIoUC5BbixbSC5NSCxILnZHXSkKcyhQLlJVLFAuUG4pCnMoUC5H
-aixQLlJVKQpzKEguUEQsUC5HaikKcyhILkxQLEguV1UpCnIoSC5UcCxbSC5DaixILkFtLEgubGMsSC5y
-LEguZEMsSC53TixQLnRoLFAuaGEsUC5WcyxQLkZ0LFAueUgsUC5XTSxQLlNYLFAuR3MsUC5kYSxQLm9R
-LFAucFYsUC5VNyxQLnZyLFAuckgsUC5LRixQLlpMLFAuUlQsUC5qWixQLnJxLFAuUlcsUC5CNSxQLlBJ
-LFAucEssUC5oaixQLlZwLFAuT1IsUC5yYSxQLnlRLFAuV0YsUC5uMSxQLmNTLFAuVkMsUC5KVCxQLmUx
-LFAuTlksUC5SWixQLk1FLFAueTUsUC5xMyxQLnlJLFAuYzYsUC5xZCxXLkN2LFcuYlUsVy5oSCxXLktT
-LFcuQTMsVy52TixXLlV2LFcuRWcsVy5FbyxXLldrLFcuSUEsVy5mbSxQLmpnLFAuVGEsUC5HRSxQLk43
-LFAudVEsUC5QQyxQLm10LFAuTnosUC5ucCxQLlV0LEwuZSxMLlZXLEwub1osTC5qcixMLnFsLEwueTgs
-TC5MLEwuV3gsTC5BTyxMLmROLEwuSG8sTC54eixMLklDLEwuTDEsTC5uVCxMLkJaLEwuR0gsTC5EVCxM
-LmVILEwuekQsTC5PRSxMLlRXLEwueHIsTC5FRSxMLlFMLEwuVlMsTC5URCxNLk1pLE0ucTcsTS5ObyxY
-LnFSXSkKcihQLlhTLFtILlcwLEguYXosSC52VixILkVxLFAuQzYsSC51OSxQLkxLLFAuQVQsUC5tcCxQ
-LnViLFAuZHMsUC5saixQLlVWLFAudDddKQpyKEgubGMsW0guengsSC5qeV0pCnMoSC5rWSxQLkM2KQpz
-KFAuaWwsUC5ZaykKcihQLmlsLFtILk41LFAudXcsVy5jZixXLlN5XSkKcihQLm1XLFtILktXLFAucTRd
-KQpzKEguYjAsSC5wRikKcihILmIwLFtILlJHLEguV0JdKQpzKEguVlAsSC5SRykKcyhILkRnLEguVlAp
-CnMoSC5aRyxILldCKQpzKEguUGcsSC5aRykKcihILlBnLFtILnhqLEguZEUsSC5aQSxILndmLEguUHEs
-SC5lRSxILlY2XSkKcyhILngsSC51OSkKcyhQLlpmLFAuUGYpCnMoUC5KaSxQLm0wKQpzKFAuYjYsUC5Y
-dikKcyhQLlZqLFAuVEMpCnIoUC5VayxbUC5DVixQLlppLFAuYnldKQpzKFAud0ksUC5rVCkKcihQLndJ
-LFtQLlU4LFAuTXgsUC5FMyxQLkdZXSkKcyhQLnU1LFAuWmkpCnIoUC5sZixbUC5DUCxQLklmXSkKcihQ
-LkFULFtQLmJKLFAuZVldKQpzKFAucWUsUC5EbikKcihXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkK
-cihXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcihXLmN2LFtXLnFFLFAuZDVdKQpyKFcucUUsW1cu
-R2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuQlQsVy55WV0pCnMoVy5v
-SixXLkxlKQpzKFcuVDUsVy5BeikKcyhXLlZiLFcuUUYpCnMoVy5mSixXLndhKQpyKFcuZWEsW1cudzYs
-Vy5ld10pCnMoVy5PSyxXLnc2KQpzKFcuckIsVy5LNykKcyhXLkJILFcuckIpCnMoVy53NCxXLklCKQpz
-KFcub2EsVy5YVykKcyhXLnJoLFcub2EpCnMoVy5pNyxXLmNmKQpzKFAuQXMsUC5WaikKcihQLkFzLFtX
-Lkk0LFAuS2VdKQpzKFcuUk8sUC5xaCkKcyhXLmV1LFcuUk8pCnMoVy54QyxQLk1PKQpzKFcuY3QsVy5t
-NikKcyhQLkJmLFAuaUopCnIoUC5FNCxbUC5yNyxQLmNvXSkKcyhQLlR6LFAuY28pCnMoUC5uZCxQLmQ1
-KQpzKEIuTHUsTy56TCkKcihCLkx1LFtFLk9GLEYucnUsTC5JVl0pCnQoSC53MixILlJlKQp0KEguUkcs
-UC5sRCkKdChILlZQLEguU1UpCnQoSC5XQixQLmxEKQp0KEguWkcsSC5TVSkKdChQLm5ZLFAubEQpCnQo
-UC5UQyxQLk1hKQp0KFAuUlUsUC5LUCkKdChXLkxlLFcuaWQpCnQoVy5LNyxQLmxEKQp0KFcuckIsVy5H
-bSkKdChXLlhXLFAubEQpCnQoVy5vYSxXLkdtKQp0KFAuY28sUC5sRCl9KSgpCnZhciB2PXt0eXBlVW5p
-dmVyc2U6e2VDOm5ldyBNYXAoKSx0Ujp7fSxlVDp7fSx0UFY6e30sc0VBOltdfSxtYW5nbGVkR2xvYmFs
-TmFtZXM6e0lmOiJpbnQiLENQOiJkb3VibGUiLGxmOiJudW0iLHFVOiJTdHJpbmciLGEyOiJib29sIixj
-ODoiTnVsbCIsek06Ikxpc3QifSxtYW5nbGVkTmFtZXM6e30sZ2V0VHlwZUZyb21OYW1lOmdldEdsb2Jh
-bEZyb21OYW1lLG1ldGFkYXRhOltdLHR5cGVzOlsiYzgoKSIsImM4KEAsQCkiLCJ+KCkiLCJAKEApIiwi
-cVUocVUpIiwiYzgoT0spIiwiYzgoY3YpIiwiYzgoZkopIiwiYTIocVUpIiwiYzgocVUscVUpIiwifih+
-KCkpIiwiYTIoY3YscVUscVUsSlEpIiwiYzgoQCkiLCJjOChxVSxAKSIsImM4KHFVKSIsImEyKGtGKSIs
-In4oeHU8cVU+KSIsImM4KGVhKSIsIn4oT0spIiwiYzgoR0QsQCkiLCJjOCh+KCkpIiwiYzgoQCxHeiki
-LCJ+KHFVLHFVKSIsIm42KElmKSIsIm42KEAsQCkiLCJhMih1SCkiLCJjOChJZixAKSIsImM4KGV3KSIs
-IkAoZWEpIiwifihNaFtHel0pIiwiYzgoQFtHel0pIiwiTWgoQCkiLCJhMih4dTxxVT4pIiwidnM8QD4o
-QCkiLCJyNyhAKSIsIlR6PEA+KEApIiwiRTQoQCkiLCJAKHFVKSIsIkAoQCxxVSkiLCJ+KHVILHVIKSIs
-ImI4PGM4PihPSykiLCJaMDxxVSxxVT4oWjA8cVUscVU+LHFVKSIsImZKKGZKKSIsIn4ocVUsSWYpIiwi
-cVUoSWYpIiwifihxVVtAXSkiLCJJZihJZixJZikiLCJ+KEApIl0saW50ZXJjZXB0b3JzQnlUYWc6bnVs
-bCxsZWFmVGFnczpudWxsLGFycmF5UnRpOnR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJnR5cGVvZiBT
-eW1ib2woKT09InN5bWJvbCI/U3ltYm9sKCIkdGkiKToiJHRpIn0KSC54Yih2LnR5cGVVbml2ZXJzZSxK
-U09OLnBhcnNlKCd7ImM1IjoiTUYiLCJpQyI6Ik1GIiwia2QiOiJNRiIsInJ4IjoiZWEiLCJlNSI6ImVh
-IiwiWTAiOiJkNSIsInRwIjoiZDUiLCJHOCI6ImV3IiwiTXIiOiJxRSIsImVMIjoicUUiLCJJMCI6InVI
-IiwiaHMiOiJ1SCIsIlhnIjoiUUYiLCJ5YyI6Ik9LIiwieTQiOiJ3NiIsImFQIjoiQ20iLCJ4YyI6Im54
-Iiwia0oiOiJueCIsInpVIjoiRGciLCJkZiI6InBGIiwieUUiOnsiYTIiOltdfSwiWUUiOnsiYzgiOltd
-fSwiTUYiOnsidm0iOltdLCJFSCI6W119LCJqZCI6eyJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsi
-MSJdfSwiUG8iOnsiamQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibTEi
-OnsiQW4iOlsiMSJdfSwicUkiOnsiQ1AiOltdLCJsZiI6W119LCJ1ciI6eyJJZiI6W10sIkNQIjpbXSwi
-bGYiOltdfSwiVkEiOnsiQ1AiOltdLCJsZiI6W119LCJEciI6eyJxVSI6W10sInZYIjpbXX0sInFqIjp7
-IlJlIjpbIklmIl0sImxEIjpbIklmIl0sInpNIjpbIklmIl0sImJRIjpbIklmIl0sImNYIjpbIklmIl0s
-ImxELkUiOiJJZiIsIlJlLkUiOiJJZiJ9LCJiUSI6eyJjWCI6WyIxIl19LCJhTCI6eyJiUSI6WyIxIl0s
-ImNYIjpbIjEiXX0sIm5IIjp7ImFMIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImFMLkUiOiIx
-IiwiY1guRSI6IjEifSwiYTciOnsiQW4iOlsiMSJdfSwiaTEiOnsiY1giOlsiMiJdLCJjWC5FIjoiMiJ9
-LCJ4eSI6eyJpMSI6WyIxIiwiMiJdLCJiUSI6WyIyIl0sImNYIjpbIjIiXSwiY1guRSI6IjIifSwiTUgi
-OnsiQW4iOlsiMiJdfSwibEoiOnsiYUwiOlsiMiJdLCJiUSI6WyIyIl0sImNYIjpbIjIiXSwiYUwuRSI6
-IjIiLCJjWC5FIjoiMiJ9LCJVNSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sInZHIjp7IkFuIjpbIjEi
-XX0sIncyIjp7IlJlIjpbIjEiXSwibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsi
-MSJdfSwid3YiOnsiR0QiOltdfSwiUEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwiUG4i
-OlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEiLCIy
-Il19LCJMUCI6eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJdLCJj
-WC5FIjoiMSJ9LCJMSSI6eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6
-eyJYUyI6W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119LCJ6eCI6
-eyJFSCI6W119LCJqeSI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119LCJONSI6
-eyJGbyI6WyIxIiwiMiJdLCJZayI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoiMSIsIllr
-LlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJBbiI6
-WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ciOnsi
-Y1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119LCJO
-RiI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sInBGIjp7IkFTIjpb
-XX0sImIwIjp7IlhqIjpbIkAiXSwicEYiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJYaiI6
-WyJAIl0sInpNIjpbIkNQIl0sInBGIjpbXSwiYlEiOlsiQ1AiXSwiU1UiOlsiQ1AiXSwiQVMiOltdLCJj
-WCI6WyJDUCJdLCJsRC5FIjoiQ1AifSwiUGciOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsi
-QCJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXX0sInhq
-Ijp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJT
-VSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJsRCI6WyJJZiJd
-LCJ6TSI6WyJJZiJdLCJYaiI6WyJAIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMi
-OltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiWkEiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwi
-WGoiOlsiQCJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYi
-XSwibEQuRSI6IklmIn0sIndmIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwicEYi
-OltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9
-LCJQcSI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJAIl0sInBGIjpbXSwiYlEiOlsiSWYi
-XSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZUUiOnsibEQiOlsi
-SWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0s
-IkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlY2Ijp7Im42IjpbXSwibEQiOlsiSWYiXSwi
-ek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpb
-XSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sInU5Ijp7IlhTIjpbXX0sIngiOnsiWFMiOltdfSwiR1Yi
-OnsiQW4iOlsiMSJdfSwicTQiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJaZiI6eyJQZiI6WyIxIl19
-LCJ2cyI6eyJiOCI6WyIxIl19LCJPSCI6eyJYUyI6W119LCJtMCI6eyJKQiI6W119LCJKaSI6eyJKQiI6
-W119LCJiNiI6eyJYdiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJsbSI6
-eyJBbiI6WyIxIl19LCJtVyI6eyJjWCI6WyIxIl19LCJMVSI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwi
-YlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpbCI6eyJZayI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwi
-WWsiOnsiWjAiOlsiMSIsIjIiXX0sIlBuIjp7IlowIjpbIjEiLCIyIl19LCJHaiI6eyJSVSI6WyIxIiwi
-MiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiVmoiOnsiTWEi
-OlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiWHYiOnsieHUiOlsiMSJdLCJi
-USI6WyIxIl0sImNYIjpbIjEiXX0sInV3Ijp7IllrIjpbInFVIiwiQCJdLCJaMCI6WyJxVSIsIkAiXSwi
-WWsuSyI6InFVIiwiWWsuViI6IkAifSwiaTgiOnsiYUwiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsi
-cVUiXSwiYUwuRSI6InFVIiwiY1guRSI6InFVIn0sIkNWIjp7IlVrIjpbInpNPElmPiIsInFVIl0sIlVr
-LlMiOiJ6TTxJZj4ifSwiVTgiOnsid0kiOlsiek08SWY+IiwicVUiXX0sIlppIjp7IlVrIjpbInFVIiwi
-ek08SWY+Il19LCJieSI6eyJVayI6WyJNaCIsInFVIl0sIlVrLlMiOiJNaCJ9LCJNeCI6eyJ3SSI6WyJx
-VSIsIk1oIl19LCJ1NSI6eyJVayI6WyJxVSIsInpNPElmPiJdLCJVay5TIjoicVUifSwiRTMiOnsid0ki
-OlsicVUiLCJ6TTxJZj4iXX0sIkdZIjp7IndJIjpbInpNPElmPiIsInFVIl19LCJDUCI6eyJsZiI6W119
-LCJDNiI6eyJYUyI6W119LCJMSyI6eyJYUyI6W119LCJBVCI6eyJYUyI6W119LCJiSiI6eyJYUyI6W119
-LCJlWSI6eyJYUyI6W119LCJtcCI6eyJYUyI6W119LCJ1YiI6eyJYUyI6W119LCJkcyI6eyJYUyI6W119
-LCJsaiI6eyJYUyI6W119LCJVViI6eyJYUyI6W119LCJrNSI6eyJYUyI6W119LCJLWSI6eyJYUyI6W119
-LCJ0NyI6eyJYUyI6W119LCJJZiI6eyJsZiI6W119LCJ6TSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXX0s
-ImliIjp7Ik9kIjpbXX0sInh1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiWmQiOnsiR3oiOltdfSwi
-cVUiOnsidlgiOltdfSwiUm4iOnsiQkwiOltdfSwiRG4iOnsiaUQiOltdfSwiVWYiOnsiaUQiOltdfSwi
-cWUiOnsiaUQiOltdfSwicUUiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkdoIjp7ImN2IjpbXSwi
-dUgiOltdLCJEMCI6W119LCJmWSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibkIiOnsiY3YiOltd
-LCJ1SCI6W10sIkQwIjpbXX0sIlFQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJueCI6eyJ1SCI6
-W10sIkQwIjpbXX0sIlFGIjp7InVIIjpbXSwiRDAiOltdfSwiSUIiOnsidG4iOlsibGYiXX0sInd6Ijp7
-ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXSwibEQuRSI6IjEifSwiY3Yi
-OnsidUgiOltdLCJEMCI6W119LCJUNSI6eyJBeiI6W119LCJoNCI6eyJjdiI6W10sInVIIjpbXSwiRDAi
-OltdfSwiVmIiOnsidUgiOltdLCJEMCI6W119LCJmSiI6eyJEMCI6W119LCJ3YSI6eyJEMCI6W119LCJP
-SyI6eyJlYSI6W119LCJlNyI6eyJsRCI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6
-WyJ1SCJdLCJsRC5FIjoidUgifSwidUgiOnsiRDAiOltdfSwiQkgiOnsiR20iOlsidUgiXSwibEQiOlsi
-dUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwiR20uRSI6
-InVIIiwibEQuRSI6InVIIn0sIlNOIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJldyI6eyJlYSI6
-W119LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVGIiOnsiY3YiOltdLCJ1SCI6W10sIkQw
-IjpbXX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJCVCI6eyJjdiI6W10sInVIIjpbXSwi
-RDAiOltdfSwieVkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInc2Ijp7ImVhIjpbXX0sIks1Ijp7
-InY2IjpbXSwiRDAiOltdfSwiQ20iOnsiRDAiOltdfSwiQ1EiOnsidUgiOltdLCJEMCI6W119LCJ3NCI6
-eyJ0biI6WyJsZiJdfSwicmgiOnsiR20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwiWGoi
-OlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwiR20uRSI6InVIIiwibEQuRSI6InVIIn0sImNm
-Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdfSwiaTciOnsiWWsiOlsicVUiLCJxVSJd
-LCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJTeSI6eyJZayI6WyJxVSIs
-InFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIkk0Ijp7Ik1hIjpb
-InFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl19LCJSTyI6eyJxaCI6WyIxIl19
-LCJldSI6eyJSTyI6WyIxIl0sInFoIjpbIjEiXX0sInhDIjp7Ik1PIjpbIjEiXX0sIkpRIjp7ImtGIjpb
-XX0sInZEIjp7ImtGIjpbXX0sIm02Ijp7ImtGIjpbXX0sImN0Ijp7ImtGIjpbXX0sIk93Ijp7ImtGIjpb
-XX0sIlc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7InY2IjpbXSwiRDAiOltdfSwibWsiOnsieTAiOltdfSwi
-S28iOnsib24iOltdfSwiQXMiOnsiTWEiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1gi
-OlsicVUiXX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIx
-Il0sIkU0IjpbXSwiY1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJuZCI6eyJkNSI6W10sImN2IjpbXSwidUgi
-OltdLCJEMCI6W119LCJLZSI6eyJNYSI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6
-WyJxVSJdfSwiZDUiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm42Ijp7InpNIjpbIklmIl0sImJR
-IjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXX0sIlhBIjp7ImtGIjpbXX0sIk9GIjp7Ikx1IjpbXX0s
-InJ1Ijp7Ikx1IjpbXX0sIklWIjp7Ikx1IjpbXX19JykpCkguRkYodi50eXBlVW5pdmVyc2UsSlNPTi5w
-YXJzZSgneyJiUSI6MSwidzIiOjEsIk1PIjoxLCJrVCI6MiwibVciOjEsIkxVIjoxLCJpbCI6MiwiVmoi
-OjEsIm5ZIjoxLCJUQyI6MSwiY28iOjF9JykpCnZhciB1PShmdW5jdGlvbiBydGlpKCl7dmFyIHQ9SC5O
-MApyZXR1cm57aTp0KCJHaCIpLG46dCgiT0giKSxjUjp0KCJuQiIpLGQ6dCgiQXoiKSxZOnQoIlFQIiks
-Z0Y6dCgiUEQ8R0QsQD4iKSxndzp0KCJiUTxAPiIpLGg6dCgiY3YiKSxXOnQoIlhTIiksQjp0KCJlYSIp
-LGFTOnQoIkQwIiksYzg6dCgiVDUiKSxaOnQoIkVIIiksYVE6dCgiYjg8Yzg+IiksYzp0KCJiODxAPiIp
-LHI6dCgiZkoiKSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVIPiIpLFg6dCgiY1g8cVU+Iiks
-Ujp0KCJjWDxAPiIpLGZBOnQoImpkPFNlPiIpLHU6dCgiamQ8ajg+IiksYlA6dCgiamQ8dUY+IiksZmg6
-dCgiamQ8Wlo+Iiksazp0KCJqZDxrRj4iKSxzOnQoImpkPHFVPiIpLGhoOnQoImpkPHlEPiIpLGFKOnQo
-ImpkPHdiPiIpLG06dCgiamQ8QD4iKSx0OnQoImpkPElmPiIpLGVIOnQoInZtIiksZzp0KCJjNSIpLGFV
-OnQoIlhqPEA+IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxHRCxAPiIpLHY6dCgiRTQiKSxkejp0KCJo
-RiIpLGE6dCgiek08cVU+Iiksajp0KCJ6TTxAPiIpLEw6dCgiek08SWY+IiksYV86dCgidTgiKSxmOnQo
-IlowPHFVLHFVPiIpLGI6dCgiWjA8cVUsQD4iKSxHOnQoIlowPEAsQD4iKSxkdjp0KCJsSjxxVSxxVT4i
-KSxkbzp0KCJsSjxxVSxAPiIpLFY6dCgiT0siKSxkRDp0KCJwRiIpLGJtOnQoIlY2IiksQTp0KCJ1SCIp
-LGU6dCgia0YiKSxQOnQoImM4IiksSzp0KCJNaCIpLHA6dCgiZXciKSxxOnQoInRuPGxmPiIpLGZ2OnQo
-IndMIiksYXY6dCgiSmMiKSxldzp0KCJuZCIpLEM6dCgieHU8cVU+IiksbDp0KCJHeiIpLE46dCgicVUi
-KSxkRzp0KCJxVShxVSkiKSxnNzp0KCJkNSIpLGZvOnQoIkdEIiksYVc6dCgieVkiKSx3OnQoIkFTIiks
-Z2M6dCgibjYiKSxhazp0KCJrZCIpLEQ6dCgiR2o8cVUscVU+IiksRTp0KCJpRCIpLGNjOnQoIlU1PHFV
-PiIpLGc0OnQoIks1IiksY2k6dCgidjYiKSxnMjp0KCJDbSIpLGJqOnQoIlpmPGZKPiIpLGg5OnQoIkNR
-IiksYWM6dCgiZTciKSxROnQoImV1PE9LPiIpLFQ6dCgid3o8Y3Y+IikseDp0KCJGZTxALEA+IiksYW86
-dCgidnM8Zko+IiksXzp0KCJ2czxAPiIpLGZKOnQoInZzPElmPiIpLE86dCgiSlEiKSxKOnQoImJuIiks
-eTp0KCJhMiIpLGFsOnQoImEyKE1oKSIpLGJCOnQoImEyKHFVKSIpLGJmOnQoImEyKEApIiksZ1I6dCgi
-Q1AiKSx6OnQoIkAiKSxmTzp0KCJAKCkiKSxVOnQoIkAoZWEpIiksRjp0KCJAKE1oKSIpLGVwOnQoIkAo
-TWgsTWgpIiksYWc6dCgiQChNaCxHeikiKSxiVTp0KCJAKHh1PHFVPikiKSxkTzp0KCJAKHFVKSIpLGI4
-OnQoIkAoQCxAKSIpLFM6dCgiSWYiKSxkaTp0KCJsZiIpLEg6dCgifiIpLE06dCgifigpIiksYW46dCgi
-fihldykiKSxlQTp0KCJ+KHFVLHFVKSIpLGNBOnQoIn4ocVUsQCkiKX19KSgpOyhmdW5jdGlvbiBjb25z
-dGFudHMoKXt2YXIgdD1odW5rSGVscGVycy5tYWtlQ29uc3RMaXN0CkMuUlk9Vy5RUC5wcm90b3R5cGUK
-Qy5CWj1XLlZiLnByb3RvdHlwZQpDLkR0PVcuZkoucHJvdG90eXBlCkMuT2s9Si52Qi5wcm90b3R5cGUK
-Qy5ObT1KLmpkLnByb3RvdHlwZQpDLmpuPUoudXIucHJvdG90eXBlCkMuak49Si5ZRS5wcm90b3R5cGUK
-Qy5DRD1KLnFJLnByb3RvdHlwZQpDLnhCPUouRHIucHJvdG90eXBlCkMuREc9Si5jNS5wcm90b3R5cGUK
-Qy5FeD1XLnU4LnByb3RvdHlwZQpDLkx0PVcuU04ucHJvdG90eXBlCkMuWlE9Si5pQy5wcm90b3R5cGUK
-Qy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJvdG90eXBlCkMub2w9Vy5LNS5wcm90b3R5cGUK
-Qy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpDLndiPWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNr
-KG8pIHsKICB2YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4g
-cy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLk80PWZ1bmN0aW9uKCkgewogIHZhciB0b1N0
-cmluZ0Z1bmN0aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWco
-bykgewogICAgdmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJz
-dHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3Qs
-IHRhZykgewogICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZh
-ciBuYW1lID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09ICJb
-b2JqZWN0IE9iamVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAg
-ICB9CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykg
-ewogICAgaWYgKHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQp
-IHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcp
-OwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRv
-dyA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09
-ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWdd
-OwogICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAg
-IHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3Io
-dGFnKSB7IHJldHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0g
-Im9iamVjdCI7CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzog
-aXNCcm93c2VyID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywKICAg
-IHByb3RvdHlwZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlzY3Jp
-bWluYXRvciB9Owp9CkMuZGs9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rp
-b24oaG9va3MpIHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9v
-a3M7CiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1
-bXBSZW5kZXJUcmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9t
-ZSIpID49IDApIHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVv
-ZiB3aW5kb3cgPT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAg
-ICAgIH0KICAgICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50Iikp
-IHJldHVybiBob29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07
-Cn0KQy5ZcT1mdW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVw
-R2V0VGFnICE9ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhw
-ZXJpbWVudGFsRml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLktVPWZ1bmN0aW9uKGhvb2tzKSB7
-CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3Mu
-cHJvdG90eXBlRm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBn
-ZXRUYWcobyk7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJz
-aW9uKSByZXR1cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9
-CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsK
-ICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBl
-Rm9yVGFnKHRhZyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3Rv
-dHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMueGk9ZnVuY3Rpb24oaG9va3MpIHsK
-ICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51
-c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0
-dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewog
-ICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJv
-YXJkIiwKICAgICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAi
-IUxvY2F0aW9uIiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJY
-TUxEb2N1bWVudCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAg
-IHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQog
-IGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgewogIHZh
-ciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJB
-Z2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJu
-IGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAg
-IkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJk
-IiwKICAgICJIVE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50Ijog
-IkhUTUxFbGVtZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAi
-UG9zaXRpb24iOiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2
-YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAo
-bmV3VGFnKSByZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAo
-d2luZG93LkRhdGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJE
-YXRhVmlldyI7CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JU
-YWdJRSh0YWcpIHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0
-cnVjdG9yID09IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlw
-ZTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0g
-cHJvdG90eXBlRm9yVGFnSUU7Cn0KQy5mUT1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7IH0K
-CkMuQ3Q9bmV3IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAu
-RTMoKQpDLk5VPW5ldyBQLkppKCkKQy5wZD1uZXcgUC5aZCgpCkMuQTM9bmV3IFAuTXgobnVsbCkKQy5H
-Yj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5WTSh0KFswLDAsMzI3
-NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xhc3MiLCIqOjpkaXIi
-LCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3Ai
-LCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0
-aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5n
-IiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwi
-QVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwi
-QVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9s
-cyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6
-cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGlu
-ayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5
-IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRU
-T046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwi
-Q0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09M
-OjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JP
-VVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZh
-bGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5k
-IiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAi
-LCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3Bl
-biIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNh
-YmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQi
-LCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6
-bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjph
-bGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2Ojph
-bGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1M
-Ojp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6Omhl
-aWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6
-d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0Iiwi
-SU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZz
-cGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVU
-OjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1
-cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklO
-UFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJ
-TlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xk
-ZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVU
-OjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5Q
-VVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5
-cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6
-YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6
-ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwi
-TUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6
-dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIs
-Ik9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVs
-IiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BU
-SU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6Ondp
-ZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxF
-Q1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VM
-RUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5k
-ZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpi
-b3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJh
-bWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjph
-bGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFi
-YnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hh
-cm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIs
-IlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVB
-OjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhU
-QVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhU
-QVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQi
-LCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZP
-T1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJU
-SDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRI
-OjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93
-cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhF
-QUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJU
-Ujo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWdu
-IiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNs
-YW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpoZWln
-aHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklERU86
-OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCwwLDY1NDkwLDQ1MDU1
-LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCwwLDI2NjI0LDEwMjMs
-NjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQiLCJBUkVBIiwiQkFT
-RSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNF
-VCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFN
-IiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMueEQ9SC5WTSh0KFtdKSx1LnUp
-CkMuZG49SC5WTSh0KFtdKSx1LnMpCkMuaFU9SC5WTSh0KFtdKSx1Lm0pCkMudG89SC5WTSh0KFswLDAs
-MzI3MjIsMTIyODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0KFswLDAs
-MjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAsMCwz
-Mjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAsMCwz
-MjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2
-NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJiaW5k
-IiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6OmhyZWYi
-LCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01NQU5E
-OjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwi
-SU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLkNNPW5ldyBILkxQKDAs
-e30sQy5kbixILk4wKCJMUDxxVSxxVT4iKSkKQy5pSD1ILlZNKHQoW10pLEguTjAoImpkPEdEPiIpKQpD
-LldPPW5ldyBILkxQKDAse30sQy5pSCxILk4wKCJMUDxHRCxAPiIpKQpDLlkyPW5ldyBMLk85KCJOYXZp
-Z2F0aW9uVHJlZU5vZGVUeXBlLmRpcmVjdG9yeSIpCkMucmY9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVl
-Tm9kZVR5cGUuZmlsZSIpCkMuVGU9bmV3IEgud3YoImNhbGwiKQpDLndRPW5ldyBQLkZ5KG51bGwsMil9
-KSgpOyhmdW5jdGlvbiBzdGF0aWNGaWVsZHMoKXskLnlqPTAKJC5tSj1udWxsCiQuUDQ9bnVsbAokLnk9
-bnVsbAokLnU9bnVsbAokLng3PW51bGwKJC5qPW51bGwKJC52PW51bGwKJC5LPW51bGwKJC5TNj1udWxs
-CiQuazg9bnVsbAokLm1nPW51bGwKJC5VRD0hMQokLlgzPUMuTlUKJC54Zz1bXQokLnhvPW51bGwKJC5C
-Tz1udWxsCiQubHQ9bnVsbAokLkVVPW51bGwKJC5vcj1QLkZsKHUuTix1LlopCiQuSTY9bnVsbAokLkZm
-PW51bGx9KSgpOyhmdW5jdGlvbiBsYXp5SW5pdGlhbGl6ZXJzKCl7dmFyIHQ9aHVua0hlbHBlcnMubGF6
-eQp0KCQsImZhIiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0Q2xvc3VyZSIp
-fSkKdCgkLCJZMiIsIkEiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9qcyIpfSkKdCgkLCJV
-MiIsIlNuIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoewp0b1N0cmluZzpmdW5jdGlvbigpe3Jl
-dHVybiIkcmVjZWl2ZXIkIn19KSl9KQp0KCQsInhxIiwibHEiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00o
-SC5TNyh7JG1ldGhvZCQ6bnVsbCwKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9
-fSkpfSkKdCgkLCJSMSIsIk45IixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcobnVsbCkpfSkKdCgk
-LCJmTiIsImlJIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNF
-eHByJD0nJGFyZ3VtZW50cyQnCnRyeXtudWxsLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2go
-cyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJxaSIsIlVOIixmdW5jdGlvbigpe3JldHVybiBI
-LmNNKEguUzcodm9pZCAwKSl9KQp0KCQsInJaIiwiWmgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVu
-Y3Rpb24oKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5eyh2b2lkIDApLiRtZXRo
-b2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJr
-cSIsInJOIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguTWoobnVsbCkpfSkKdCgkLCJ0dCIsImMzIixm
-dW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5e251bGwuJG1ldGhvZCR9Y2F0Y2gocyl7
-cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJkdCIsIkhLIixmdW5jdGlvbigpe3JldHVybiBILmNN
-KEguTWoodm9pZCAwKSl9KQp0KCQsIkE3IiwicjEiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rp
-b24oKXt0cnl7KHZvaWQgMCkuJG1ldGhvZCR9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkK
-dCgkLCJXYyIsInV0IixmdW5jdGlvbigpe3JldHVybiBQLk9qKCl9KQp0KCQsImtoIiwidEwiLGZ1bmN0
-aW9uKCl7cmV0dXJuIFAuV0koKX0pCnQoJCwiYnQiLCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5EUShI
-LlhGKEguVk0oWy0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0xLC0yLC0yLC0yLC0yLC0yLDYyLC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYw
-LDYxLC0yLC0yLC0yLC0xLC0yLC0yLC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQs
-MTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgs
-MjksMzAsMzEsMzIsMzMsMzQsMzUsMzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgs
-NDksNTAsNTEsLTIsLTIsLTIsLTIsLTJdLHUudCkpKX0pCnQoJCwiTTUiLCJPeCIsZnVuY3Rpb24oKXty
-ZXR1cm4gdHlwZW9mIHByb2Nlc3MhPSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5n
-LmNhbGwocHJvY2Vzcyk9PSJbb2JqZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMy
-In0pCnQoJCwibWYiLCJ6NCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpfYS16
-fl0qJCIpfSkKdCgkLCJBdiIsInA2IixmdW5jdGlvbigpe3JldHVybiBuZXcgRXJyb3IoKS5zdGFjayE9
-dm9pZCAwfSkKdCgkLCJKRyIsInZaIixmdW5jdGlvbigpe3JldHVybiBQLktOKCl9KQp0KCQsIlNDIiwi
-QU4iLGZ1bmN0aW9uKCl7cmV0dXJuIFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNTIiwi
-QVJFQSIsIkFSVElDTEUiLCJBU0lERSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJMT0NL
-UVVPVEUiLCJCUiIsIkJVVFRPTiIsIkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwiQ09E
-RSIsIkNPTCIsIkNPTEdST1VQIiwiQ09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVMIiwi
-REVUQUlMUyIsIkRGTiIsIkRJUiIsIkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQ
-VElPTiIsIkZJR1VSRSIsIkZPTlQiLCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJI
-NSIsIkg2IiwiSEVBREVSIiwiSEdST1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJ
-TlMiLCJLQkQiLCJMQUJFTCIsIkxFR0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIs
-Ik5BViIsIk5PQlIiLCJPTCIsIk9QVEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBS
-T0dSRVNTIiwiUSIsIlMiLCJTQU1QIiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNFIiwi
-U1BBTiIsIlNUUklLRSIsIlNUUk9ORyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZ
-IiwiVEQiLCJURVhUQVJFQSIsIlRGT09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwi
-VFQiLCJVIiwiVUwiLCJWQVIiLCJWSURFTyIsIldCUiJdLHUuTil9KQp0KCQsIlg0IiwiaEciLGZ1bmN0
-aW9uKCl7cmV0dXJuIFAubnUoIl5cXFMrJCIpfSkKdCgkLCJ3TyIsIm93IixmdW5jdGlvbigpe3JldHVy
-biB1LnYuYShQLk5EKHNlbGYpKX0pCnQoJCwia3QiLCJDciIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygi
-XyRkYXJ0X2RhcnRPYmplY3QiKX0pCnQoJCwiZksiLCJrSSIsZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rp
-b24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQp0KCQsInF0IiwiekIiLGZ1bmN0aW9uKCl7cmV0dXJu
-IG5ldyBULm1RKCl9KQp0KCQsIk9sIiwiVUUiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuaEsoQy5vbC5nbVco
-Vy54MygpKS5ocmVmKS5naFkoKS5xKDAsImF1dGhUb2tlbiIpfSkKdCgkLCJoVCIsInlQIixmdW5jdGlv
-bigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVkaXQtbGlzdCAucGFuZWwtY29udGVudCIp
-fSkKdCgkLCJXNiIsImhMIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVk
-aXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX0pCnQoJCwiVFIiLCJEVyIsZnVuY3Rpb24oKXtyZXR1cm4g
-Vy5acigpLnF1ZXJ5U2VsZWN0b3IoImZvb3RlciIpfSkKdCgkLCJFWSIsImZpIixmdW5jdGlvbigpe3Jl
-dHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQp0KCQsImF2IiwiRDkiLGZ1bmN0aW9u
-KCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIil9KQp0KCQsImZlIiwiS0ci
-LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQp0KCQsImVvIiwiblUiLGZ1bmN0aW9uKCl7cmV0
-dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQp0KCQsInlyIiwiYkQiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBF
-Lk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkKdCgkLCJNayIsIktrIixmdW5j
-dGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5udSgiW14vXFxcXF0kIiksUC5u
-dSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1aXTpbL1xcXFxdKSIpLFAubnUo
-Il5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQp0KCQsImFrIiwiRWIiLGZ1bmN0aW9uKCl7cmV0dXJuIG5l
-dyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vfFteL10pJCIp
-LFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQLm51KCJeLyIpKX0pCnQoJCwi
-bHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhmdW5jdGlvbiBuYXRpdmVTdXBw
-b3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oYSl7dmFyIG49e30KblthXT0xCnJldHVybiBP
-YmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0KG4pKVswXX0Kdi5nZXRJc29s
-YXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB0KCJfX19kYXJ0XyIrYSt2Lmlzb2xhdGVUYWcpfQp2YXIg
-cz0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcj1PYmplY3Rbc118fChPYmplY3Rbc109T2JqZWN0
-LmNyZWF0ZShudWxsKSkKdmFyIHE9Il9aeFl4WCIKZm9yKHZhciBwPTA7O3ArKyl7dmFyIG89dChxKyJf
-IitwKyJfIikKaWYoIShvIGluIHIpKXtyW29dPTEKdi5pc29sYXRlVGFnPW8KYnJlYWt9fXYuZGlzcGF0
-Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9yZWNvcmQiKX0oKQpodW5rSGVs
-cGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJvcjpKLnZCLERPTUltcGxlbWVu
-dGF0aW9uOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRvcjpKLnZCLE5hdmlnYXRvckNvbmN1cnJl
-bnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkoudkIsT3ZlcmNvbnN0cmFpbmVk
-RXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6Si52QixTUUxFcnJvcjpKLnZCLERhdGFW
-aWV3OkgucEYsQXJyYXlCdWZmZXJWaWV3OkgucEYsRmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2NEFycmF5
-OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZB
-cnJheTpILndmLFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQaXhl
-bEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVt
-ZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxD
-b250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5x
-RSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50OlcucUUsSFRNTERpYWxv
-Z0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1M
-RmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFkRWxlbWVudDpXLnFF
-LEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhUTUxJRnJhbWVFbGVt
-ZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElF
-bGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRFbGVtZW50OlcucUUsSFRN
-TExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50OlcucUUs
-SFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRNTE1ldGVyRWxlbWVudDpX
-LnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxPYmplY3RFbGVt
-ZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25FbGVtZW50OlcucUUsSFRN
-TE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50
-OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1b3Rl
-RWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxI
-VE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpX
-LnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxU
-YWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxl
-SGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRleHRBcmVh
-RWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1M
-VHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxVbmtub3duRWxlbWVudDpX
-LnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxGb250
-RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50OlcucUUs
-SFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpX
-LkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5BeixIVE1M
-Qm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVu
-dDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0
-aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVydGllczpXLm9KLFhNTERv
-Y3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxET01SZWN0UmVhZE9ubHk6
-Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQYXltZW50RXZlbnQ6Vy5lYSxB
-bmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6Vy5lYSxBcHBsaWNhdGlvbkNh
-Y2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5k
-RmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpXLmVhLEJhY2tncm91bmRGZXRj
-aGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5lYSxCZWZvcmVVbmxvYWRFdmVu
-dDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6Vy5lYSxDbGlwYm9hcmRFdmVu
-dDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERldmljZU1vdGlvbkV2ZW50Olcu
-ZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlRXZl
-bnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hFdmVudDpXLmVhLEZvbnRGYWNl
-U2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxHYW1lcGFkRXZlbnQ6Vy5lYSxI
-YXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRpYUVuY3J5cHRlZEV2ZW50Olcu
-ZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OlcuZWEsTWVkaWFT
-dHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVhLE1lc3NhZ2VFdmVudDpXLmVh
-LE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50OlcuZWEsTXV0YXRpb25FdmVu
-dDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRpb25FdmVudDpXLmVhLFBheW1l
-bnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OlcuZWEsUG9wU3RhdGVF
-dmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDpXLmVhLFByZXNlbnRh
-dGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVjdGlvbkV2ZW50OlcuZWEsUHVz
-aEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6
-Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJhY2tFdmVudDpXLmVhLFNlY3Vy
-aXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2ZW50OlcuZWEsU3BlZWNoUmVj
-b2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6Vy5lYSxTcGVlY2hTeW50aGVz
-aXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpXLmVhLFRyYWNrRXZlbnQ6Vy5l
-YSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxWUkRldmljZUV2
-ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVudDpXLmVhLE1vam9JbnRlcmZh
-Y2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5lYSxJREJWZXJzaW9uQ2hhbmdl
-RXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25F
-dmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2ZW50OlcuZWEs
-RXZlbnRUYXJnZXQ6Vy5EMCxGaWxlOlcuVDUsSFRNTEZvcm1FbGVtZW50OlcuaDQsSGlzdG9yeTpXLmJy
-LEhUTUxEb2N1bWVudDpXLlZiLFhNTEh0dHBSZXF1ZXN0OlcuZkosWE1MSHR0cFJlcXVlc3RFdmVudFRh
-cmdldDpXLndhLEltYWdlRGF0YTpXLlNnLExvY2F0aW9uOlcudTgsTW91c2VFdmVudDpXLk9LLERyYWdF
-dmVudDpXLk9LLFBvaW50ZXJFdmVudDpXLk9LLFdoZWVsRXZlbnQ6Vy5PSyxEb2N1bWVudEZyYWdtZW50
-OlcudUgsU2hhZG93Um9vdDpXLnVILERvY3VtZW50VHlwZTpXLnVILE5vZGU6Vy51SCxOb2RlTGlzdDpX
-LkJILFJhZGlvTm9kZUxpc3Q6Vy5CSCxIVE1MUGFyYWdyYXBoRWxlbWVudDpXLlNOLFByb2dyZXNzRXZl
-bnQ6Vy5ldyxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6Vy5ldyxIVE1MU2VsZWN0RWxlbWVudDpXLmxwLEhU
-TUxUYWJsZUVsZW1lbnQ6Vy5UYixIVE1MVGFibGVSb3dFbGVtZW50OlcuSXYsSFRNTFRhYmxlU2VjdGlv
-bkVsZW1lbnQ6Vy5CVCxIVE1MVGVtcGxhdGVFbGVtZW50OlcueVksQ29tcG9zaXRpb25FdmVudDpXLnc2
-LEZvY3VzRXZlbnQ6Vy53NixLZXlib2FyZEV2ZW50OlcudzYsVGV4dEV2ZW50OlcudzYsVG91Y2hFdmVu
-dDpXLnc2LFVJRXZlbnQ6Vy53NixXaW5kb3c6Vy5LNSxET01XaW5kb3c6Vy5LNSxEZWRpY2F0ZWRXb3Jr
-ZXJHbG9iYWxTY29wZTpXLkNtLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFNoYXJlZFdvcmtl
-ckdsb2JhbFNjb3BlOlcuQ20sV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxBdHRyOlcuQ1EsQ2xpZW50UmVj
-dDpXLnc0LERPTVJlY3Q6Vy53NCxOYW1lZE5vZGVNYXA6Vy5yaCxNb3pOYW1lZEF0dHJNYXA6Vy5yaCxJ
-REJLZXlSYW5nZTpQLmhGLFNWR1NjcmlwdEVsZW1lbnQ6UC5uZCxTVkdBRWxlbWVudDpQLmQ1LFNWR0Fu
-aW1hdGVFbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlVHJh
-bnNmb3JtRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGlvbkVsZW1lbnQ6UC5kNSxTVkdDaXJjbGVFbGVtZW50
-OlAuZDUsU1ZHQ2xpcFBhdGhFbGVtZW50OlAuZDUsU1ZHRGVmc0VsZW1lbnQ6UC5kNSxTVkdEZXNjRWxl
-bWVudDpQLmQ1LFNWR0Rpc2NhcmRFbGVtZW50OlAuZDUsU1ZHRWxsaXBzZUVsZW1lbnQ6UC5kNSxTVkdG
-RUJsZW5kRWxlbWVudDpQLmQ1LFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVDb21wb25l
-bnRUcmFuc2ZlckVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6UC5kNSxTVkdGRUNvbnZv
-bHZlTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDpQLmQ1LFNWR0ZF
-RGlzcGxhY2VtZW50TWFwRWxlbWVudDpQLmQ1LFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDpQLmQ1LFNW
-R0ZFRmxvb2RFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQUVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNCRWxlbWVu
-dDpQLmQ1LFNWR0ZFRnVuY0dFbGVtZW50OlAuZDUsU1ZHRkVGdW5jUkVsZW1lbnQ6UC5kNSxTVkdGRUdh
-dXNzaWFuQmx1ckVsZW1lbnQ6UC5kNSxTVkdGRUltYWdlRWxlbWVudDpQLmQ1LFNWR0ZFTWVyZ2VFbGVt
-ZW50OlAuZDUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OlAuZDUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDpQ
-LmQ1LFNWR0ZFT2Zmc2V0RWxlbWVudDpQLmQ1LFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdG
-RVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OlAuZDUsU1ZH
-RkVUaWxlRWxlbWVudDpQLmQ1LFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6UC5kNSxTVkdGaWx0ZXJFbGVt
-ZW50OlAuZDUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6UC5kNSxTVkdHRWxlbWVudDpQLmQ1LFNWR0dl
-b21ldHJ5RWxlbWVudDpQLmQ1LFNWR0dyYXBoaWNzRWxlbWVudDpQLmQ1LFNWR0ltYWdlRWxlbWVudDpQ
-LmQ1LFNWR0xpbmVFbGVtZW50OlAuZDUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHTWFy
-a2VyRWxlbWVudDpQLmQ1LFNWR01hc2tFbGVtZW50OlAuZDUsU1ZHTWV0YWRhdGFFbGVtZW50OlAuZDUs
-U1ZHUGF0aEVsZW1lbnQ6UC5kNSxTVkdQYXR0ZXJuRWxlbWVudDpQLmQ1LFNWR1BvbHlnb25FbGVtZW50
-OlAuZDUsU1ZHUG9seWxpbmVFbGVtZW50OlAuZDUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OlAuZDUs
-U1ZHUmVjdEVsZW1lbnQ6UC5kNSxTVkdTZXRFbGVtZW50OlAuZDUsU1ZHU3RvcEVsZW1lbnQ6UC5kNSxT
-VkdTdHlsZUVsZW1lbnQ6UC5kNSxTVkdTVkdFbGVtZW50OlAuZDUsU1ZHU3dpdGNoRWxlbWVudDpQLmQ1
-LFNWR1N5bWJvbEVsZW1lbnQ6UC5kNSxTVkdUU3BhbkVsZW1lbnQ6UC5kNSxTVkdUZXh0Q29udGVudEVs
-ZW1lbnQ6UC5kNSxTVkdUZXh0RWxlbWVudDpQLmQ1LFNWR1RleHRQYXRoRWxlbWVudDpQLmQ1LFNWR1Rl
-eHRQb3NpdGlvbmluZ0VsZW1lbnQ6UC5kNSxTVkdUaXRsZUVsZW1lbnQ6UC5kNSxTVkdVc2VFbGVtZW50
-OlAuZDUsU1ZHVmlld0VsZW1lbnQ6UC5kNSxTVkdHcmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdDb21wb25l
-bnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDpQLmQ1LFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6UC5kNSxT
-VkdNUGF0aEVsZW1lbnQ6UC5kNSxTVkdFbGVtZW50OlAuZDV9KQpodW5rSGVscGVycy5zZXRPclVwZGF0
-ZUxlYWZUYWdzKHtET01FcnJvcjp0cnVlLERPTUltcGxlbWVudGF0aW9uOnRydWUsTWVkaWFFcnJvcjp0
-cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTp0cnVlLE5hdmlnYXRv
-clVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6dHJ1ZSxQb3NpdGlvbkVycm9y
-OnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRydWUsQXJyYXlCdWZmZXJWaWV3
-OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVlLEludDE2QXJyYXk6dHJ1ZSxJ
-bnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6dHJ1ZSxVaW50MzJBcnJheTp0
-cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJheTp0cnVlLFVpbnQ4QXJyYXk6
-ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9uRWxl
-bWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRlbnRFbGVtZW50OnRydWUsSFRN
-TERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhUTUxEYXRhTGlzdEVsZW1lbnQ6
-dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxlbWVudDp0cnVlLEhUTUxEaXZF
-bGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVsZFNldEVsZW1lbnQ6dHJ1ZSxI
-VE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRNTEhlYWRpbmdFbGVtZW50OnRy
-dWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VFbGVt
-ZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1lbnQ6dHJ1ZSxIVE1MTGFiZWxF
-bGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxIVE1M
-TWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1ZSxI
-VE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUsSFRNTE1vZEVsZW1lbnQ6dHJ1
-ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0R3JvdXBF
-bGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0cHV0RWxlbWVudDp0cnVlLEhU
-TUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxlbWVudDp0
-cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVtZW50OnRydWUsSFRNTFNjcmlw
-dEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxTbG90RWxlbWVudDp0cnVlLEhU
-TUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUsSFRNTFN0eWxlRWxlbWVudDp0
-cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1ZSxI
-VE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDp0cnVl
-LEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVtZW50OnRydWUsSFRNTFRpbWVF
-bGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFja0VsZW1lbnQ6dHJ1ZSxIVE1M
-VUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUsSFRNTFZpZGVvRWxlbWVudDp0
-cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVtZW50OnRydWUsSFRNTEZyYW1l
-RWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1MTWFycXVlZUVsZW1lbnQ6dHJ1
-ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVlLEhUTUxBcmVhRWxlbWVudDp0
-cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJvZHlFbGVtZW50OnRydWUsQ0RB
-VEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6dHJ1ZSxQcm9jZXNzaW5nSW5z
-dHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlvbjp0cnVlLE1TU3R5bGVDU1NQ
-cm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1bWVudDp0cnVlLERvY3VtZW50
-OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTVJlY3RSZWFkT25seTpmYWxzZSxET01Ub2tlbkxpc3Q6
-dHJ1ZSxFbGVtZW50OmZhbHNlLEFib3J0UGF5bWVudEV2ZW50OnRydWUsQW5pbWF0aW9uRXZlbnQ6dHJ1
-ZSxBbmltYXRpb25QbGF5YmFja0V2ZW50OnRydWUsQXBwbGljYXRpb25DYWNoZUVycm9yRXZlbnQ6dHJ1
-ZSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoRXZlbnQ6dHJ1ZSxC
-YWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hlZEV2ZW50OnRydWUsQmVm
-b3JlSW5zdGFsbFByb21wdEV2ZW50OnRydWUsQmVmb3JlVW5sb2FkRXZlbnQ6dHJ1ZSxCbG9iRXZlbnQ6
-dHJ1ZSxDYW5NYWtlUGF5bWVudEV2ZW50OnRydWUsQ2xpcGJvYXJkRXZlbnQ6dHJ1ZSxDbG9zZUV2ZW50
-OnRydWUsQ3VzdG9tRXZlbnQ6dHJ1ZSxEZXZpY2VNb3Rpb25FdmVudDp0cnVlLERldmljZU9yaWVudGF0
-aW9uRXZlbnQ6dHJ1ZSxFcnJvckV2ZW50OnRydWUsRXh0ZW5kYWJsZUV2ZW50OnRydWUsRXh0ZW5kYWJs
-ZU1lc3NhZ2VFdmVudDp0cnVlLEZldGNoRXZlbnQ6dHJ1ZSxGb250RmFjZVNldExvYWRFdmVudDp0cnVl
-LEZvcmVpZ25GZXRjaEV2ZW50OnRydWUsR2FtZXBhZEV2ZW50OnRydWUsSGFzaENoYW5nZUV2ZW50OnRy
-dWUsSW5zdGFsbEV2ZW50OnRydWUsTWVkaWFFbmNyeXB0ZWRFdmVudDp0cnVlLE1lZGlhS2V5TWVzc2Fn
-ZUV2ZW50OnRydWUsTWVkaWFRdWVyeUxpc3RFdmVudDp0cnVlLE1lZGlhU3RyZWFtRXZlbnQ6dHJ1ZSxN
-ZWRpYVN0cmVhbVRyYWNrRXZlbnQ6dHJ1ZSxNZXNzYWdlRXZlbnQ6dHJ1ZSxNSURJQ29ubmVjdGlvbkV2
-ZW50OnRydWUsTUlESU1lc3NhZ2VFdmVudDp0cnVlLE11dGF0aW9uRXZlbnQ6dHJ1ZSxOb3RpZmljYXRp
-b25FdmVudDp0cnVlLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdEV2ZW50OnRy
-dWUsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDp0cnVlLFBvcFN0YXRlRXZlbnQ6dHJ1ZSxQcmVzZW50
-YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xv
-c2VFdmVudDp0cnVlLFByb21pc2VSZWplY3Rpb25FdmVudDp0cnVlLFB1c2hFdmVudDp0cnVlLFJUQ0Rh
-dGFDaGFubmVsRXZlbnQ6dHJ1ZSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50OnRydWUsUlRDUGVlckNvbm5l
-Y3Rpb25JY2VFdmVudDp0cnVlLFJUQ1RyYWNrRXZlbnQ6dHJ1ZSxTZWN1cml0eVBvbGljeVZpb2xhdGlv
-bkV2ZW50OnRydWUsU2Vuc29yRXJyb3JFdmVudDp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXJyb3I6dHJ1
-ZSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OnRydWUsU3BlZWNoU3ludGhlc2lzRXZlbnQ6dHJ1ZSxTdG9y
-YWdlRXZlbnQ6dHJ1ZSxTeW5jRXZlbnQ6dHJ1ZSxUcmFja0V2ZW50OnRydWUsVHJhbnNpdGlvbkV2ZW50
-OnRydWUsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OnRydWUsVlJEZXZpY2VFdmVudDp0cnVlLFZSRGlzcGxh
-eUV2ZW50OnRydWUsVlJTZXNzaW9uRXZlbnQ6dHJ1ZSxNb2pvSW50ZXJmYWNlUmVxdWVzdEV2ZW50OnRy
-dWUsVVNCQ29ubmVjdGlvbkV2ZW50OnRydWUsSURCVmVyc2lvbkNoYW5nZUV2ZW50OnRydWUsQXVkaW9Q
-cm9jZXNzaW5nRXZlbnQ6dHJ1ZSxPZmZsaW5lQXVkaW9Db21wbGV0aW9uRXZlbnQ6dHJ1ZSxXZWJHTENv
-bnRleHRFdmVudDp0cnVlLEV2ZW50OmZhbHNlLElucHV0RXZlbnQ6ZmFsc2UsRXZlbnRUYXJnZXQ6ZmFs
-c2UsRmlsZTp0cnVlLEhUTUxGb3JtRWxlbWVudDp0cnVlLEhpc3Rvcnk6dHJ1ZSxIVE1MRG9jdW1lbnQ6
-dHJ1ZSxYTUxIdHRwUmVxdWVzdDp0cnVlLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6ZmFsc2UsSW1h
-Z2VEYXRhOnRydWUsTG9jYXRpb246dHJ1ZSxNb3VzZUV2ZW50OnRydWUsRHJhZ0V2ZW50OnRydWUsUG9p
-bnRlckV2ZW50OnRydWUsV2hlZWxFdmVudDp0cnVlLERvY3VtZW50RnJhZ21lbnQ6dHJ1ZSxTaGFkb3dS
-b290OnRydWUsRG9jdW1lbnRUeXBlOnRydWUsTm9kZTpmYWxzZSxOb2RlTGlzdDp0cnVlLFJhZGlvTm9k
-ZUxpc3Q6dHJ1ZSxIVE1MUGFyYWdyYXBoRWxlbWVudDp0cnVlLFByb2dyZXNzRXZlbnQ6dHJ1ZSxSZXNv
-dXJjZVByb2dyZXNzRXZlbnQ6dHJ1ZSxIVE1MU2VsZWN0RWxlbWVudDp0cnVlLEhUTUxUYWJsZUVsZW1l
-bnQ6dHJ1ZSxIVE1MVGFibGVSb3dFbGVtZW50OnRydWUsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6dHJ1
-ZSxIVE1MVGVtcGxhdGVFbGVtZW50OnRydWUsQ29tcG9zaXRpb25FdmVudDp0cnVlLEZvY3VzRXZlbnQ6
-dHJ1ZSxLZXlib2FyZEV2ZW50OnRydWUsVGV4dEV2ZW50OnRydWUsVG91Y2hFdmVudDp0cnVlLFVJRXZl
-bnQ6ZmFsc2UsV2luZG93OnRydWUsRE9NV2luZG93OnRydWUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2Nv
-cGU6dHJ1ZSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTaGFyZWRXb3JrZXJHbG9iYWxTY29w
-ZTp0cnVlLFdvcmtlckdsb2JhbFNjb3BlOnRydWUsQXR0cjp0cnVlLENsaWVudFJlY3Q6dHJ1ZSxET01S
-ZWN0OnRydWUsTmFtZWROb2RlTWFwOnRydWUsTW96TmFtZWRBdHRyTWFwOnRydWUsSURCS2V5UmFuZ2U6
-dHJ1ZSxTVkdTY3JpcHRFbGVtZW50OnRydWUsU1ZHQUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlRWxlbWVu
-dDp0cnVlLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OnRydWUsU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1l
-bnQ6dHJ1ZSxTVkdBbmltYXRpb25FbGVtZW50OnRydWUsU1ZHQ2lyY2xlRWxlbWVudDp0cnVlLFNWR0Ns
-aXBQYXRoRWxlbWVudDp0cnVlLFNWR0RlZnNFbGVtZW50OnRydWUsU1ZHRGVzY0VsZW1lbnQ6dHJ1ZSxT
-VkdEaXNjYXJkRWxlbWVudDp0cnVlLFNWR0VsbGlwc2VFbGVtZW50OnRydWUsU1ZHRkVCbGVuZEVsZW1l
-bnQ6dHJ1ZSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJF
-bGVtZW50OnRydWUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OnRydWUsU1ZHRkVDb252b2x2ZU1hdHJpeEVs
-ZW1lbnQ6dHJ1ZSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRURpc3BsYWNlbWVu
-dE1hcEVsZW1lbnQ6dHJ1ZSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRUZsb29kRWxl
-bWVudDp0cnVlLFNWR0ZFRnVuY0FFbGVtZW50OnRydWUsU1ZHRkVGdW5jQkVsZW1lbnQ6dHJ1ZSxTVkdG
-RUZ1bmNHRWxlbWVudDp0cnVlLFNWR0ZFRnVuY1JFbGVtZW50OnRydWUsU1ZHRkVHYXVzc2lhbkJsdXJF
-bGVtZW50OnRydWUsU1ZHRkVJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlRWxlbWVudDp0cnVlLFNW
-R0ZFTWVyZ2VOb2RlRWxlbWVudDp0cnVlLFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6dHJ1ZSxTVkdGRU9m
-ZnNldEVsZW1lbnQ6dHJ1ZSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVTcGVjdWxhckxp
-Z2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFVGlsZUVsZW1l
-bnQ6dHJ1ZSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OnRydWUsU1ZHRmlsdGVyRWxlbWVudDp0cnVlLFNW
-R0ZvcmVpZ25PYmplY3RFbGVtZW50OnRydWUsU1ZHR0VsZW1lbnQ6dHJ1ZSxTVkdHZW9tZXRyeUVsZW1l
-bnQ6dHJ1ZSxTVkdHcmFwaGljc0VsZW1lbnQ6dHJ1ZSxTVkdJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5l
-RWxlbWVudDp0cnVlLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDp0cnVlLFNWR01hcmtlckVsZW1lbnQ6
-dHJ1ZSxTVkdNYXNrRWxlbWVudDp0cnVlLFNWR01ldGFkYXRhRWxlbWVudDp0cnVlLFNWR1BhdGhFbGVt
-ZW50OnRydWUsU1ZHUGF0dGVybkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5Z29uRWxlbWVudDp0cnVlLFNWR1Bv
-bHlsaW5lRWxlbWVudDp0cnVlLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDp0cnVlLFNWR1JlY3RFbGVt
-ZW50OnRydWUsU1ZHU2V0RWxlbWVudDp0cnVlLFNWR1N0b3BFbGVtZW50OnRydWUsU1ZHU3R5bGVFbGVt
-ZW50OnRydWUsU1ZHU1ZHRWxlbWVudDp0cnVlLFNWR1N3aXRjaEVsZW1lbnQ6dHJ1ZSxTVkdTeW1ib2xF
-bGVtZW50OnRydWUsU1ZHVFNwYW5FbGVtZW50OnRydWUsU1ZHVGV4dENvbnRlbnRFbGVtZW50OnRydWUs
-U1ZHVGV4dEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UGF0aEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UG9zaXRpb25p
-bmdFbGVtZW50OnRydWUsU1ZHVGl0bGVFbGVtZW50OnRydWUsU1ZHVXNlRWxlbWVudDp0cnVlLFNWR1Zp
-ZXdFbGVtZW50OnRydWUsU1ZHR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHQ29tcG9uZW50VHJhbnNmZXJG
-dW5jdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OnRydWUsU1ZHTVBhdGhFbGVt
-ZW50OnRydWUsU1ZHRWxlbWVudDpmYWxzZX0pCkguYjAuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5
-QnVmZmVyVmlldyIKSC5SRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlZQ
-LiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguRGcuJG5hdGl2ZVN1cGVyY2xh
-c3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5XQi4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZm
-ZXJWaWV3IgpILlpHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUGcuJG5h
-dGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyJ9KSgpCmNvbnZlcnRBbGxUb0Zhc3RPYmpl
-Y3QodykKY29udmVydFRvRmFzdE9iamVjdCgkKTsoZnVuY3Rpb24oYSl7aWYodHlwZW9mIGRvY3VtZW50
-PT09InVuZGVmaW5lZCIpe2EobnVsbCkKcmV0dXJufWlmKHR5cGVvZiBkb2N1bWVudC5jdXJyZW50U2Ny
-aXB0IT0ndW5kZWZpbmVkJyl7YShkb2N1bWVudC5jdXJyZW50U2NyaXB0KQpyZXR1cm59dmFyIHQ9ZG9j
-dW1lbnQuc2NyaXB0cwpmdW5jdGlvbiBvbkxvYWQoYil7Zm9yKHZhciByPTA7cjx0Lmxlbmd0aDsrK3Ip
-dFtyXS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFsc2UpCmEoYi50YXJnZXQpfWZv
-cih2YXIgcz0wO3M8dC5sZW5ndGg7KytzKXRbc10uYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2Fk
-LGZhbHNlKX0pKGZ1bmN0aW9uKGEpe3YuY3VycmVudFNjcmlwdD1hCmlmKHR5cGVvZiBkYXJ0TWFpblJ1
-bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5uZXIoTC5JcSxbXSkKZWxzZSBMLklxKFtdKX0pfSko
-KQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMubWFwCg==
-''';
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
deleted file mode 100644
index b85ff1d..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert' show HtmlEscape, HtmlEscapeMode, LineSplitter;
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/file_details.dart';
-import 'package:path/path.dart' as path;
-
-/// Instrumentation display output for a library that was migrated to use
-/// non-nullable types.
-class UnitRenderer {
-  /// A converter which only escapes "&", "<", and ">". Safe for use in HTML
-  /// text, between HTML elements.
-  static const HtmlEscape _htmlEscape =
-      HtmlEscape(HtmlEscapeMode(escapeLtGt: true));
-
-  /// Displays information for a compilation unit.
-  final UnitInfo unitInfo;
-
-  /// Information for a whole migration, so that libraries can reference each
-  /// other.
-  final MigrationInfo migrationInfo;
-
-  /// An object used to map the file paths of analyzed files to the file paths
-  /// of the HTML files used to view the content of those files.
-  final PathMapper pathMapper;
-
-  /// Creates an output object for the given library info.
-  UnitRenderer(this.unitInfo, this.migrationInfo, this.pathMapper);
-
-  /// Return the path context used to manipulate paths.
-  path.Context get pathContext => migrationInfo.pathContext;
-
-  /// Builds a JSON view of the instrumentation information in [unitInfo].
-  FileDetails render() {
-    return FileDetails(
-        regions: _computeRegionContent(unitInfo),
-        navigationContent: _computeNavigationContent(),
-        sourceCode: unitInfo.content,
-        edits: _computeEditList());
-  }
-
-  /// Returns the list of edits, as JSON.
-  List<EditListItem> _computeEditList() {
-    return unitInfo.fixRegions.map((RegionInfo region) {
-      return EditListItem(
-          line: region.lineNumber,
-          explanation: region.explanation,
-          offset: region.offset);
-    }).toList();
-  }
-
-  /// Returns the content of the file with navigation links and anchors added.
-  ///
-  /// The content of the file (not including added links and anchors) will be
-  /// HTML-escaped.
-  String _computeNavigationContent() {
-    var unitDir = pathContext.dirname(pathMapper.map(unitInfo.path));
-    var content = unitInfo.content;
-    var mapper = unitInfo.offsetMapper;
-    var openInsertions = <int, String>{};
-    var closeInsertions = <int, String>{};
-    //
-    // Compute insertions for navigation targets.
-    //
-    for (var region in unitInfo.targets) {
-      if (region.length > 0) {
-        var openOffset = mapper.map(region.offset);
-        var openInsertion = openInsertions[openOffset] ?? '';
-        openInsertion = '<span id="o${region.offset}">$openInsertion';
-        openInsertions[openOffset] = openInsertion;
-
-        var closeOffset = openOffset + region.length;
-        var closeInsertion = closeInsertions[closeOffset] ?? '';
-        closeInsertion = '$closeInsertion</span>';
-        closeInsertions[closeOffset] = closeInsertion;
-      }
-    }
-    //
-    // Compute insertions for navigation sources, but skip the sources that
-    // point at themselves.
-    //
-    for (var region in unitInfo.sources ?? <NavigationSource>[]) {
-      if (region.length > 0) {
-        var openOffset = mapper.map(region.offset);
-        var target = region.target;
-        if (target.filePath != unitInfo.path ||
-            region.offset != target.offset) {
-          var openInsertion = openInsertions[openOffset] ?? '';
-          var unitPath = pathContext.relative(pathMapper.map(target.filePath),
-              from: unitDir);
-          var targetUri = _uriForRelativePath(unitPath, target);
-          openInsertion =
-              '<a href="$targetUri" class="nav-link">$openInsertion';
-          openInsertions[openOffset] = openInsertion;
-
-          var closeOffset = openOffset + region.length;
-          var closeInsertion = closeInsertions[closeOffset] ?? '';
-          closeInsertion = '$closeInsertion</a>';
-          closeInsertions[closeOffset] = closeInsertion;
-        }
-      }
-    }
-    //
-    // Apply the insertions that have been computed.
-    //
-    var offsets = <int>[...openInsertions.keys, ...closeInsertions.keys];
-    offsets.sort();
-    var navContent2 = StringBuffer();
-    var previousOffset = 0;
-    for (var offset in offsets) {
-      navContent2.write(
-          _htmlEscape.convert(content.substring(previousOffset, offset)));
-      navContent2.write(closeInsertions[offset] ?? '');
-      navContent2.write(openInsertions[offset] ?? '');
-      previousOffset = offset;
-    }
-    if (previousOffset < content.length) {
-      navContent2.write(_htmlEscape.convert(content.substring(previousOffset)));
-    }
-    return navContent2.toString();
-  }
-
-  /// Returns the content of regions, based on the [unitInfo] for both
-  /// unmodified and modified regions.
-  ///
-  /// The content of the file (not including added links and anchors) will be
-  /// HTML-escaped.
-  String _computeRegionContent(UnitInfo unit) {
-    var content = unitInfo.content;
-    var regions = StringBuffer();
-    var lineNumber = 1;
-
-    void writeSplitLines(
-      String lines, {
-      String perLineOpeningTag = '',
-      String perLineClosingTag = '',
-    }) {
-      var lineIterator = LineSplitter.split(lines).iterator;
-      lineIterator.moveNext();
-
-      while (true) {
-        regions.write(perLineOpeningTag);
-        regions.write(_htmlEscape.convert(lineIterator.current));
-        regions.write(perLineClosingTag);
-        if (lineIterator.moveNext()) {
-          // If we're not on the last element, end this table row, and start a
-          // new table row.
-          lineNumber++;
-          regions.write('</td></tr>'
-              '<tr><td class="line-no">$lineNumber</td>'
-              '<td class="line-$lineNumber">');
-        } else {
-          break;
-        }
-      }
-
-      if (lines.endsWith('\n')) {
-        lineNumber++;
-        regions.write('</td></tr>'
-            '<tr><td class="line-no">$lineNumber</td>'
-            '<td class="line-$lineNumber">');
-      }
-    }
-
-    /// Returns the CSS class for a region with a given [RegionType].
-    String classForRegion(RegionType type) {
-      switch (type) {
-        case RegionType.add:
-          return 'added-region';
-        case RegionType.remove:
-          return 'removed-region';
-        case RegionType.informative:
-          return 'informative-region';
-      }
-      throw StateError('Unexpected RegionType $type');
-    }
-
-    var previousOffset = 0;
-    regions.write('<table data-path="${unit.path}"><tbody>');
-    regions.write('<tr><td class="line-no">$lineNumber</td><td>');
-    for (var region in unitInfo.regions) {
-      var offset = region.offset;
-      var length = region.length;
-      if (offset > previousOffset) {
-        // Display a region of unmodified content.
-        writeSplitLines(content.substring(previousOffset, offset));
-        previousOffset = offset + length;
-      }
-      var regionClass = classForRegion(region.regionType);
-      var regionSpanTag = '<span class="region $regionClass" '
-          'data-offset="$offset" data-line="$lineNumber">';
-      writeSplitLines(content.substring(offset, offset + length),
-          perLineOpeningTag: regionSpanTag, perLineClosingTag: '</span>');
-    }
-    if (previousOffset < content.length) {
-      // Last region of unmodified content.
-      writeSplitLines(content.substring(previousOffset));
-    }
-    regions.write('</td></tr></tbody></table>');
-    return regions.toString();
-  }
-
-  /// Returns the URL that will navigate to the given [target] in the file at
-  /// the given [relativePath].
-  String _uriForRelativePath(String relativePath, NavigationTarget target) {
-    var queryParams = {
-      'offset': target.offset,
-      if (target.line != null) 'line': target.line,
-    }.entries.map((entry) => '${entry.key}=${entry.value}').join('&');
-    return '$relativePath?$queryParams';
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
deleted file mode 100644
index 6c7afbd..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:meta/meta.dart';
-
-/// Information about what should be populated into the "Edit Details" view of
-/// the migration preview tool.
-class EditDetails {
-  /// A list of the bulleted items that should be displayed as rationale for the
-  /// edit.
-  final List<EditRationale> details;
-
-  /// A list of edits that can be offered to the user related to this source
-  /// location (e.g. adding/removing hints).  `null` if this feature is
-  /// disabled.
-  final List<EditLink> edits;
-
-  /// A string explanation of the edit.
-  final String explanation;
-
-  /// The line number of the edit.
-  final int line;
-
-  /// The path of the file that was edited.
-  final String path;
-
-  /// A list of traces representing stacktrace-like views of why the change was
-  /// made, or the empty list if there are no traces for this change.
-  final List<Trace> traces;
-
-  EditDetails(
-      {@required this.details,
-      this.edits,
-      @required this.explanation,
-      @required this.line,
-      @required this.path,
-      this.traces = const []});
-
-  EditDetails.fromJson(dynamic json)
-      : details = [
-          for (var detail in json['details']) EditRationale.fromJson(detail)
-        ],
-        edits = _decodeEdits(json['edits']),
-        explanation = json['explanation'],
-        line = json['line'],
-        path = json['path'],
-        traces = _decodeTraces(json['traces']);
-
-  Map<String, Object> toJson() => {
-        'details': [for (var detail in details) detail.toJson()],
-        if (edits != null) 'edits': [for (var edit in edits) edit.toJson()],
-        'explanation': explanation,
-        'line': line,
-        'path': path,
-        if (traces != null)
-          'traces': [for (var trace in traces) trace.toJson()],
-      };
-
-  static List<EditLink> _decodeEdits(dynamic json) =>
-      json == null ? null : [for (var edit in json) EditLink.fromJson(edit)];
-
-  static List<Trace> _decodeTraces(dynamic json) =>
-      json == null ? null : [for (var trace in json) Trace.fromJson(trace)];
-}
-
-/// Information about a single link that should be included in the
-/// "Edit Details" view of the migration preview tool, where the purpose of the
-/// link is to allow the user to make a change to the source file (e.g. to add
-/// or remove a hint).
-class EditLink {
-  /// Description of the change to be performed.
-  final String description;
-
-  /// The href to link to.
-  final String href;
-
-  EditLink({@required this.description, @required this.href});
-
-  EditLink.fromJson(dynamic json)
-      : description = json['description'],
-        href = json['href'];
-
-  Map<String, Object> toJson() => {
-        'description': description,
-        'href': href,
-      };
-}
-
-/// Information about what should be populated into a single "rational" bullet
-/// item in the "Edit Details" view of the migration preview tool.
-class EditRationale {
-  /// Description of the rationale.
-  final String description;
-
-  /// Link the user may click to see the source code in question.  May be null.
-  final TargetLink link;
-
-  EditRationale({@required this.description, this.link});
-
-  EditRationale.fromJson(dynamic json)
-      : description = json['description'],
-        link = _decodeLink(json['link']);
-
-  Map<String, Object> toJson() => {
-        'description': description,
-        if (link != null) 'link': link.toJson(),
-      };
-
-  static TargetLink _decodeLink(dynamic json) =>
-      json == null ? null : TargetLink.fromJson(json);
-}
-
-/// Information about a single link that should be included in the
-/// "Edit Details" view of the migration preview tool, where the purpose of the
-/// link is to allow the user to navigate to a source file containing
-/// information about the rationale for a change.
-class TargetLink {
-  /// The href to link to.
-  final String href;
-
-  /// The line number of the link.
-  final int line;
-
-  /// Relative path to the source file (intended for display).
-  final String path;
-
-  TargetLink({@required this.href, @required this.line, @required this.path});
-
-  TargetLink.fromJson(dynamic json)
-      : href = json['href'],
-        line = json['line'],
-        path = json['path'];
-
-  Map<String, Object> toJson() => {
-        'href': href,
-        'line': line,
-        'path': path,
-      };
-}
-
-/// A trace of why a nullability decision was made.
-class Trace {
-  /// Text description of the trace.
-  final String description;
-
-  /// List of trace entries.
-  final List<TraceEntry> entries;
-
-  Trace({@required this.description, @required this.entries});
-
-  Trace.fromJson(dynamic json)
-      : description = json['description'],
-        entries = [
-          for (var entry in json['entries']) TraceEntry.fromJson(entry)
-        ];
-
-  Map<String, Object> toJson() => {
-        'description': description,
-        'entries': [for (var entry in entries) entry.toJson()]
-      };
-}
-
-/// Information about a single entry in a nullability trace.
-class TraceEntry {
-  /// Text description of the entry.
-  final String description;
-
-  /// The function associated with the entry.  We display this before the link
-  /// so that the trace has the familiar appearance of a stacktrace.
-  ///
-  /// Null if not known.
-  final String function;
-
-  /// Source code location associated with the entry, or `null` if no source
-  /// code location is known.
-  final TargetLink link;
-
-  TraceEntry({@required this.description, this.function, this.link});
-
-  TraceEntry.fromJson(dynamic json)
-      : description = json['description'],
-        function = json['function'],
-        link = _decodeLink(json['link']);
-
-  Map<String, Object> toJson() => {
-        'description': description,
-        if (function != null) 'function': function,
-        if (link != null) 'link': link.toJson()
-      };
-
-  static TargetLink _decodeLink(dynamic json) =>
-      json == null ? null : TargetLink.fromJson(json);
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/file_details.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/file_details.dart
deleted file mode 100644
index 7d0276f..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/file_details.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:meta/meta.dart';
-
-/// Information about an item that should show up in the "proposed edits" panel.
-class EditListItem {
-  /// Line number of this edit.
-  final int line;
-
-  /// Human-readable explanation of this edit.
-  final String explanation;
-
-  /// File offset of this edit
-  final int offset;
-
-  EditListItem(
-      {@required this.line, @required this.explanation, @required this.offset});
-
-  EditListItem.fromJson(dynamic json)
-      : line = json['line'],
-        explanation = json['explanation'],
-        offset = json['offset'];
-
-  Map<String, Object> toJson() =>
-      {'line': line, 'explanation': explanation, 'offset': offset};
-}
-
-/// Information about how a single file should be migrated.
-class FileDetails {
-  /// HTML representation of the source file with spans added to represent
-  /// added, removed, and unchanged file regions.
-  ///
-  /// TODO(paulberry): this should be replaced by a more neutral data structure.
-  final String regions;
-
-  /// HTML representation of the source file with links added to allow
-  /// navigation through source files.
-  ///
-  /// TODO(paulberry): this should be replaced by a more neutral data structure.
-  final String navigationContent;
-
-  /// Textual representation of the source file, including both added and
-  /// removed text.
-  final String sourceCode;
-
-  /// Items that should show up in the "proposed edits" panel for the file.
-  final List<EditListItem> edits;
-
-  FileDetails(
-      {@required this.regions,
-      @required this.navigationContent,
-      @required this.sourceCode,
-      @required this.edits});
-
-  FileDetails.empty()
-      : regions = '',
-        navigationContent = '',
-        sourceCode = '',
-        edits = const [];
-
-  FileDetails.fromJson(dynamic json)
-      : regions = json['regions'],
-        navigationContent = json['navigationContent'],
-        sourceCode = json['sourceCode'],
-        edits = [for (var edit in json['edits']) EditListItem.fromJson(edit)];
-
-  Map<String, Object> toJson() => {
-        'regions': regions,
-        'navigationContent': navigationContent,
-        'sourceCode': sourceCode,
-        'edits': [for (var edit in edits) edit.toJson()]
-      };
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/highlight_js.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/highlight_js.dart
deleted file mode 100644
index 7e9901e..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/highlight_js.dart
+++ /dev/null
@@ -1,19 +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:html';
-import 'dart:js';
-
-final HighlightJs hljs = HighlightJs._();
-
-/// A small wrapper around the JavaScript highlight.js APIs.
-class HighlightJs {
-  static JsObject get _hljs => context['hljs'];
-
-  HighlightJs._();
-
-  void highlightBlock(Element block) {
-    _hljs.callMethod('highlightBlock', [block]);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
deleted file mode 100644
index 4dc2537..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
+++ /dev/null
@@ -1,690 +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 'dart:convert';
-import 'dart:html';
-
-import 'package:analysis_server/src/edit/nnbd_migration/web/edit_details.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/file_details.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
-import 'package:path/path.dart' as _p;
-
-import 'highlight_js.dart';
-
-// TODO(devoncarew): Fix the issue where we can't load source maps.
-
-// TODO(devoncarew): Include a favicon.
-
-void main() {
-  document.addEventListener('DOMContentLoaded', (event) {
-    var path = window.location.pathname;
-    var offset = getOffset(window.location.href);
-    var lineNumber = getLine(window.location.href);
-    loadNavigationTree();
-    if (path != '/' && path != rootPath) {
-      // TODO(srawlins): replaceState?
-      loadFile(path, offset, lineNumber, true, callback: () {
-        pushState(path, offset, lineNumber);
-      });
-    }
-
-    final applyMigrationButton = document.querySelector('.apply-migration');
-    applyMigrationButton.onClick.listen((event) {
-      if (window.confirm(
-          "This will apply the changes you've previewed to your working "
-          'directory. It is recommended you commit any changes you made before '
-          'doing this.')) {
-        doPost('/apply-migration').then((xhr) {
-          document.body.classes
-            ..remove('proposed')
-            ..add('applied');
-        }).catchError((e, st) {
-          logError('apply migration error: $e', st);
-
-          window.alert('Could not apply migration ($e).');
-        });
-      }
-    });
-
-    final rerunMigrationButton = document.querySelector('.rerun-migration');
-    rerunMigrationButton.onClick.listen((event) async {
-      try {
-        document.body.classes..add('rerunning');
-        await doPost('/rerun-migration');
-        window.location.reload();
-      } catch (e, st) {
-        logError('rerun migration: $e', st);
-
-        window.alert('Failed to rerun migration: $e.');
-      } finally {
-        document.body.classes.remove('rerunning');
-      }
-    });
-  });
-
-  window.addEventListener('popstate', (event) {
-    var path = window.location.pathname;
-    var offset = getOffset(window.location.href);
-    var lineNumber = getLine(window.location.href);
-    if (path.length > 1) {
-      loadFile(path, offset, lineNumber, false);
-    } else {
-      // Blank out the page, for the index screen.
-      writeCodeAndRegions(path, FileDetails.empty(), true);
-      updatePage('&nbsp;', null);
-    }
-  });
-}
-
-/// Returns the "authToken" query parameter value of the current location.
-// TODO(srawlins): This feels a little fragile, as the user can accidentally
-//  change/remove this text, and break their session. Normally auth tokens are
-//  stored in cookies, but there is no authentication step during which the
-//  server would attach such a token to cookies. We could do a little step where
-//  the first request to the server with the token is considered
-//  "authentication", and we subsequently store the token in cookies thereafter.
-final String authToken =
-    Uri.parse(window.location.href).queryParameters['authToken'];
-
-final Element editListElement =
-    document.querySelector('.edit-list .panel-content');
-
-final Element editPanel = document.querySelector('.edit-panel .panel-content');
-
-final Element footerPanel = document.querySelector('footer');
-
-final Element headerPanel = document.querySelector('header');
-
-final Element unitName = document.querySelector('#unit-name');
-
-String get rootPath => querySelector('.root').text.trim();
-
-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
-  // have are hacks. The `* 2` allows for events in which the list grows in
-  // height when resized, with additional text wrapping.
-  // [1] https://css-tricks.com/using-css-transitions-auto-dimensions/
-  childList.style.maxHeight = '${childList.offsetHeight * 2}px';
-  arrow.onClick.listen((MouseEvent event) {
-    if (!childList.classes.contains('collapsed')) {
-      childList.classes.add('collapsed');
-      arrow.classes.add('collapsed');
-    } else {
-      childList.classes.remove('collapsed');
-      arrow.classes.remove('collapsed');
-    }
-  });
-}
-
-void addClickHandlers(String selector, bool clearEditDetails) {
-  var parentElement = document.querySelector(selector);
-
-  // Add navigation handlers for navigation links in the source code.
-  List<Element> navLinks = parentElement.querySelectorAll('.nav-link');
-  navLinks.forEach((link) {
-    link.onClick.listen((event) {
-      var tableElement = document.querySelector('table[data-path]');
-      var parentPath = tableElement.dataset['path'];
-      handleNavLinkClick(event, clearEditDetails, relativeTo: parentPath);
-    });
-  });
-
-  List<Element> regions = parentElement.querySelectorAll('.region');
-  if (regions.isNotEmpty) {
-    var table = parentElement.querySelector('table[data-path]');
-    var path = table.dataset['path'];
-    regions.forEach((Element anchor) {
-      anchor.onClick.listen((event) {
-        var offset = int.parse(anchor.dataset['offset']);
-        var line = int.parse(anchor.dataset['line']);
-        loadAndPopulateEditDetails(path, offset, line);
-      });
-    });
-  }
-
-  List<Element> postLinks = parentElement.querySelectorAll('.post-link');
-  postLinks.forEach((link) {
-    link.onClick.listen(handlePostLinkClick);
-  });
-}
-
-Future<HttpRequest> doGet(String path,
-        {Map<String, String> queryParameters = const {}}) =>
-    HttpRequest.request(pathWithQueryParameters(path, queryParameters),
-        requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'});
-
-Future<HttpRequest> doPost(String path) => HttpRequest.request(
-      pathWithQueryParameters(path, {}),
-      method: 'POST',
-      requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'},
-    ).then((HttpRequest xhr) {
-      if (xhr.status == 200) {
-        // Request OK.
-        return xhr;
-      } else {
-        throw 'Request failed; status of ${xhr.status}';
-      }
-    });
-
-int getLine(String location) {
-  var str = Uri.parse(location).queryParameters['line'];
-  return str == null ? null : int.tryParse(str);
-}
-
-int getOffset(String location) {
-  var str = Uri.parse(location).queryParameters['offset'];
-  return str == null ? null : int.tryParse(str);
-}
-
-void handleNavLinkClick(
-  MouseEvent event,
-  bool clearEditDetails, {
-  String relativeTo,
-}) {
-  Element target = event.currentTarget;
-  event.preventDefault();
-
-  var location = target.getAttribute('href');
-  var path = location;
-  if (path.contains('?')) {
-    path = path.substring(0, path.indexOf('?'));
-  }
-  // Fix-up the path - it might be relative.
-  if (relativeTo != null) {
-    path = _p.normalize(_p.join(_p.dirname(relativeTo), path));
-  }
-
-  var offset = getOffset(location);
-  var lineNumber = getLine(location);
-
-  if (offset != null) {
-    navigate(path, offset, lineNumber, clearEditDetails, callback: () {
-      pushState(path, offset, lineNumber);
-    });
-  } else {
-    navigate(path, null, null, clearEditDetails, callback: () {
-      pushState(path, null, null);
-    });
-  }
-}
-
-void handlePostLinkClick(MouseEvent event) async {
-  var path = (event.currentTarget as Element).getAttribute('href');
-
-  // Don't navigate on link click.
-  event.preventDefault();
-
-  document.body.classes.add('rerunning');
-
-  try {
-    // Directing the server to produce an edit; request it, then do work with the
-    // response.
-    await doPost(path);
-    (document.window.location as Location).reload();
-  } catch (e, st) {
-    logError('handlePostLinkClick: $e', st);
-
-    window.alert('Could not load $path ($e).');
-  } finally {
-    document.body.classes.remove('rerunning');
-  }
-}
-
-void highlightAllCode() {
-  document.querySelectorAll('.code').forEach((Element block) {
-    hljs.highlightBlock(block);
-  });
-}
-
-/// Loads the explanation for [region], into the ".panel-content" div.
-void loadAndPopulateEditDetails(String path, int offset, int line) {
-  // Request the region, then do work with the response.
-  doGet(path, queryParameters: {'region': 'region', 'offset': '$offset'})
-      .then((HttpRequest xhr) {
-    if (xhr.status == 200) {
-      var response = EditDetails.fromJson(jsonDecode(xhr.responseText));
-      populateEditDetails(response);
-      pushState(path, offset, line);
-      addClickHandlers('.edit-panel .panel-content', false);
-    } else {
-      window.alert('Request failed; status of ${xhr.status}');
-    }
-  }).catchError((e, st) {
-    logError('loadRegionExplanation: $e', st);
-
-    window.alert('Could not load $path ($e).');
-  });
-}
-
-/// Load the file at [path] from the server, optionally scrolling [offset] into
-/// view.
-void loadFile(
-  String path,
-  int offset,
-  int line,
-  bool clearEditDetails, {
-  VoidCallback callback,
-}) {
-  // Handle the case where we're requesting a directory.
-  if (!path.endsWith('.dart')) {
-    writeCodeAndRegions(path, FileDetails.empty(), clearEditDetails);
-    updatePage(path);
-    if (callback != null) {
-      callback();
-    }
-
-    return;
-  }
-
-  // Navigating to another file; request it, then do work with the response.
-  doGet(path, queryParameters: {'inline': 'true'}).then((HttpRequest xhr) {
-    if (xhr.status == 200) {
-      Map<String, dynamic> response = jsonDecode(xhr.responseText);
-      writeCodeAndRegions(
-          path, FileDetails.fromJson(response), clearEditDetails);
-      maybeScrollToAndHighlight(offset, line);
-      var filePathPart =
-          path.contains('?') ? path.substring(0, path.indexOf('?')) : path;
-      updatePage(filePathPart, offset);
-      if (callback != null) {
-        callback();
-      }
-    } else {
-      window.alert('Request failed; status of ${xhr.status}');
-    }
-  }).catchError((e, st) {
-    logError('loadFile: $e', st);
-
-    window.alert('Could not load $path ($e).');
-  });
-}
-
-/// Load the navigation tree into the ".nav-tree" div.
-void loadNavigationTree() {
-  var path = '/_preview/navigationTree.json';
-
-  // Request the navigation tree, then do work with the response.
-  doGet(path).then((HttpRequest xhr) {
-    if (xhr.status == 200) {
-      dynamic response = jsonDecode(xhr.responseText);
-      var navTree = document.querySelector('.nav-tree');
-      navTree.innerHtml = '';
-      writeNavigationSubtree(
-          navTree, NavigationTreeNode.listFromJson(response));
-    } else {
-      window.alert('Request failed; status of ${xhr.status}');
-    }
-  }).catchError((e, st) {
-    logError('loadNavigationTree: $e', st);
-
-    window.alert('Could not load $path ($e).');
-  });
-}
-
-void logError(e, st) {
-  window.console.error('$e');
-  window.console.error('$st');
-}
-
-/// Scroll an element into view if it is not visible.
-void maybeScrollIntoView(Element element) {
-  var rect = element.getBoundingClientRect();
-  // A line of text in the code view is 14px high. Including it here means we
-  // only choose to _not_ scroll a line of code into view if the entire line is
-  // visible.
-  var lineHeight = 14;
-  var visibleCeiling = headerPanel.offsetHeight + lineHeight;
-  var visibleFloor =
-      window.innerHeight - (footerPanel.offsetHeight + lineHeight);
-  if (rect.bottom > visibleFloor) {
-    element.scrollIntoView();
-  } else if (rect.top < visibleCeiling) {
-    element.scrollIntoView();
-  }
-}
-
-/// Scroll target with id [offset] into view if it is not currently in view.
-///
-/// If [offset] is null, instead scroll the "unit-name" header, at the top of
-/// the page, into view.
-///
-/// Also add the "target" class, highlighting the target. Also add the
-/// "highlight" class to the entire line on which the target lies.
-void maybeScrollToAndHighlight(int offset, int lineNumber) {
-  Element target;
-  Element line;
-
-  if (offset != null) {
-    target = document.getElementById('o$offset');
-    line = document.querySelector('.line-$lineNumber');
-    if (target != null) {
-      maybeScrollIntoView(target);
-      target.classes.add('target');
-    } else if (line != null) {
-      // If the target doesn't exist, but the line does, scroll that into view
-      // instead.
-      maybeScrollIntoView(line.parent);
-    }
-    if (line != null) {
-      (line.parentNode as Element).classes.add('highlight');
-    }
-  } else {
-    // If no offset is given, this is likely a navigation link, and we need to
-    // scroll back to the top of the page.
-    maybeScrollIntoView(unitName);
-  }
-}
-
-/// Navigate to [path] and optionally scroll [offset] into view.
-///
-/// If [callback] is present, it will be called after the server response has
-/// been processed, and the content has been updated on the page.
-void navigate(
-  String path,
-  int offset,
-  int lineNumber,
-  bool clearEditDetails, {
-  VoidCallback callback,
-}) {
-  var currentOffset = getOffset(window.location.href);
-  var currentLineNumber = getLine(window.location.href);
-  removeHighlight(currentOffset, currentLineNumber);
-  if (path == window.location.pathname) {
-    // Navigating to same file; just scroll into view.
-    maybeScrollToAndHighlight(offset, lineNumber);
-    if (callback != null) {
-      callback();
-    }
-  } else {
-    loadFile(path, offset, lineNumber, clearEditDetails, callback: callback);
-  }
-}
-
-/// Returns [path], which may include query parameters, with a new path which
-/// adds (or replaces) parameters from [queryParameters].
-///
-/// Additionally, the "authToken" parameter will be added with the authToken
-/// found in the current location.
-String pathWithQueryParameters(
-    String path, Map<String, String> queryParameters) {
-  var uri = Uri.parse(path);
-  var mergedQueryParameters = {
-    ...uri.queryParameters,
-    ...queryParameters,
-    'authToken': authToken
-  };
-  return uri.replace(queryParameters: mergedQueryParameters).toString();
-}
-
-String pluralize(int count, String single, {String multiple}) {
-  return count == 1 ? single : (multiple ?? '${single}s');
-}
-
-void populateEditDetails([EditDetails response]) {
-  // Clear out any current edit details.
-  editPanel.innerHtml = '';
-  if (response == null) {
-    Element p = editPanel.append(ParagraphElement()
-      ..text = 'See details about a proposed edit.'
-      ..classes = ['placeholder']);
-    p.scrollIntoView();
-    return;
-  }
-
-  var filePath = response.path;
-  var parentDirectory = _p.dirname(filePath);
-
-  // 'Changed ... at foo.dart:12.'
-  var explanationMessage = response.explanation;
-  var relPath = _p.relative(filePath, from: rootPath);
-  var line = response.line;
-  Element explanation = editPanel.append(document.createElement('p'));
-  explanation.append(Text('$explanationMessage at $relPath:$line.'));
-  explanation.scrollIntoView();
-  _populateEditTraces(response, editPanel, parentDirectory);
-  _populateEditLinks(response, editPanel);
-  _populateEditRationale(response, editPanel, parentDirectory);
-}
-
-/// Write the contents of the Edit List, from JSON data [editListData].
-void populateProposedEdits(
-    String path, List<EditListItem> edits, bool clearEditDetails) {
-  editListElement.innerHtml = '';
-
-  Element p = editListElement.append(document.createElement('p'));
-  var editCount = edits.length;
-  if (editCount == 0) {
-    p.append(Text('No proposed edits'));
-  } else {
-    p.append(Text('$editCount proposed ${pluralize(editCount, 'edit')}:'));
-  }
-
-  Element list = editListElement.append(document.createElement('ul'));
-  for (var edit in edits) {
-    Element item = list.append(document.createElement('li'));
-    item.classes.add('edit');
-    AnchorElement anchor = item.append(document.createElement('a'));
-    anchor.classes.add('edit-link');
-    var offset = edit.offset;
-    anchor.dataset['offset'] = '$offset';
-    var line = edit.line;
-    anchor.dataset['line'] = '$line';
-    anchor.append(Text('line $line'));
-    anchor.onClick.listen((MouseEvent event) {
-      navigate(window.location.pathname, offset, line, true, callback: () {
-        pushState(window.location.pathname, offset, line);
-      });
-      loadAndPopulateEditDetails(path, offset, line);
-    });
-    item.append(Text(': ${edit.explanation}'));
-  }
-
-  if (clearEditDetails) {
-    populateEditDetails();
-  }
-}
-
-void pushState(String path, int offset, int line) {
-  var uri = Uri.parse('${window.location.origin}$path');
-
-  var params = {
-    if (offset != null) 'offset': '$offset',
-    if (line != null) 'line': '$line',
-    'authToken': authToken,
-  };
-
-  uri = uri.replace(queryParameters: params);
-  window.history.pushState({}, '', uri.toString());
-}
-
-/// If [path] lies within [root], return the relative path of [path] from [root].
-/// Otherwise, return [path].
-String relativePath(String path) {
-  var root = querySelector('.root').text + '/';
-  if (path.startsWith(root)) {
-    return path.substring(root.length);
-  } else {
-    return path;
-  }
-}
-
-/// Remove highlighting from [offset].
-void removeHighlight(int offset, int lineNumber) {
-  if (offset != null) {
-    var anchor = document.getElementById('o$offset');
-    if (anchor != null) {
-      anchor.classes.remove('target');
-    }
-  }
-  if (lineNumber != null) {
-    var line = document.querySelector('.line-$lineNumber');
-    if (line != null) {
-      line.parent.classes.remove('highlight');
-    }
-  }
-}
-
-/// Update the heading and navigation links.
-///
-/// Call this after updating page content on a navigation.
-void updatePage(String path, [int offset]) {
-  path = relativePath(path);
-  // Update page heading.
-  unitName.text = path;
-  // Update navigation styles.
-  document.querySelectorAll('.nav-panel .nav-link').forEach((Element link) {
-    var name = link.dataset['name'];
-    if (name == path) {
-      link.classes.add('selected-file');
-    } else {
-      link.classes.remove('selected-file');
-    }
-  });
-}
-
-/// Load data from [data] into the .code and the .regions divs.
-void writeCodeAndRegions(String path, FileDetails data, bool clearEditDetails) {
-  var regionsElement = document.querySelector('.regions');
-  var codeElement = document.querySelector('.code');
-
-  _PermissiveNodeValidator.setInnerHtml(regionsElement, data.regions);
-  _PermissiveNodeValidator.setInnerHtml(codeElement, data.navigationContent);
-  populateProposedEdits(path, data.edits, clearEditDetails);
-
-  highlightAllCode();
-  addClickHandlers('.code', true);
-  addClickHandlers('.regions', true);
-}
-
-void writeNavigationSubtree(
-    Element parentElement, List<NavigationTreeNode> tree) {
-  Element ul = parentElement.append(document.createElement('ul'));
-  for (var entity in tree) {
-    Element li = ul.append(document.createElement('li'));
-    if (entity.type == NavigationTreeNodeType.directory) {
-      li.classes.add('dir');
-      Element arrow = li.append(document.createElement('span'));
-      arrow.classes.add('arrow');
-      arrow.innerHtml = '&#x25BC;';
-      Element icon = li.append(document.createElement('span'));
-      icon.innerHtml = '&#x1F4C1;';
-      li.append(Text(entity.name));
-      writeNavigationSubtree(li, entity.subtree);
-      addArrowClickHandler(arrow);
-    } else {
-      li.innerHtml = '&#x1F4C4;';
-      Element a = li.append(document.createElement('a'));
-      a.classes.add('nav-link');
-      a.dataset['name'] = entity.path;
-      a.setAttribute('href', entity.href);
-      a.append(Text(entity.name));
-      a.onClick.listen((MouseEvent event) => handleNavLinkClick(event, true));
-      var editCount = entity.editCount;
-      if (editCount > 0) {
-        Element editsBadge = li.append(document.createElement('span'));
-        editsBadge.classes.add('edit-count');
-        editsBadge.setAttribute(
-            'title', '$editCount ${pluralize(editCount, 'edit')}');
-        editsBadge.append(Text(editCount.toString()));
-      }
-    }
-  }
-}
-
-AnchorElement _aElementForLink(TargetLink link, String parentDirectory) {
-  var targetLine = link.line;
-  AnchorElement a = document.createElement('a');
-  a.append(Text('${link.path}:$targetLine'));
-
-  var relLink = link.href;
-  var fullPath = _p.normalize(_p.join(parentDirectory, relLink));
-
-  a.setAttribute('href', fullPath);
-  a.classes.add('nav-link');
-  return a;
-}
-
-void _populateEditLinks(EditDetails response, Element editPanel) {
-  if (response.edits != null) {
-    for (var edit in response.edits) {
-      Element editParagraph = editPanel.append(document.createElement('p'));
-      Element a = editParagraph.append(document.createElement('a'));
-      a.append(Text(edit.description));
-      a.setAttribute('href', edit.href);
-      a.classes = ['post-link', 'before-apply'];
-    }
-  }
-}
-
-void _populateEditRationale(
-    EditDetails response, Element editPanel, String parentDirectory) {
-  var detailCount = response.details.length;
-  if (detailCount == 0) {
-    // Having 0 details is not necessarily an expected possibility, but handling
-    // the possibility prevents awkward text, "for 0 reasons:".
-  } else {
-    editPanel
-        .append(ParagraphElement()..text = 'Edit rationale (experimental):');
-
-    Element detailList = editPanel.append(document.createElement('ul'));
-    for (var detail in response.details) {
-      var detailItem = detailList.append(document.createElement('li'));
-      detailItem.append(Text(detail.description));
-      var link = detail.link;
-      if (link != null) {
-        detailItem.append(Text(' ('));
-        detailItem.append(_aElementForLink(link, parentDirectory));
-        detailItem.append(Text(')'));
-      }
-    }
-  }
-}
-
-void _populateEditTraces(
-    EditDetails response, Element editPanel, String parentDirectory) {
-  for (var trace in response.traces) {
-    var traceParagraph =
-        editPanel.append(document.createElement('p')..classes = ['trace']);
-    traceParagraph.append(document.createElement('span')
-      ..classes = ['type-description']
-      ..append(Text(trace.description)));
-    traceParagraph.append(Text(':'));
-    var ul = traceParagraph
-        .append(document.createElement('ul')..classes = ['trace']);
-    for (var entry in trace.entries) {
-      var li = ul.append(document.createElement('li')..innerHtml = '&#x274F; ');
-      li.append(document.createElement('span')
-        ..classes = ['function']
-        ..append(Text(entry.function ?? 'unknown')));
-      var link = entry.link;
-      if (link != null) {
-        li.append(Text(' ('));
-        li.append(_aElementForLink(link, parentDirectory));
-        li.append(Text(')'));
-      }
-      li.append(Text(': '));
-      li.append(Text(entry.description));
-    }
-  }
-}
-
-class _PermissiveNodeValidator implements NodeValidator {
-  static _PermissiveNodeValidator instance = _PermissiveNodeValidator();
-
-  @override
-  bool allowsAttribute(Element element, String attributeName, String value) {
-    return true;
-  }
-
-  @override
-  bool allowsElement(Element element) {
-    return true;
-  }
-
-  static void setInnerHtml(Element element, String html) {
-    element.setInnerHtml(html, validator: instance);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/navigation_tree.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/navigation_tree.dart
deleted file mode 100644
index 096574d..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/navigation_tree.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:meta/meta.dart';
-
-/// Information about a node in the migration tool's navigation tree.
-class NavigationTreeNode {
-  /// Type of the node.
-  final NavigationTreeNodeType type;
-
-  /// Name of the node.
-  final String name;
-
-  /// If this is a directory node, list of nodes nested under this one.
-  /// Otherwise `null`.
-  final List<NavigationTreeNode> subtree;
-
-  /// If this is a file node, full path to the file.  Otherwise `null`.
-  final String path;
-
-  /// If this is a file node, href that should be used if the file is clicked
-  /// on, otherwise `null`.
-  final String href;
-
-  /// If this is a file node, number of edits that were made in the file,
-  /// otherwise `null`.
-  final int editCount;
-
-  /// Creates a navigation tree node representing a directory.
-  NavigationTreeNode.directory({@required this.name, @required this.subtree})
-      : type = NavigationTreeNodeType.directory,
-        path = null,
-        href = null,
-        editCount = null;
-
-  /// Creates a navigation tree node representing a file.
-  NavigationTreeNode.file(
-      {@required this.name,
-      @required this.path,
-      @required this.href,
-      @required this.editCount})
-      : type = NavigationTreeNodeType.file,
-        subtree = null;
-
-  NavigationTreeNode.fromJson(dynamic json)
-      : type = _decodeType(json['type']),
-        name = json['name'],
-        subtree = listFromJsonOrNull(json['subtree']),
-        path = json['path'],
-        href = json['href'],
-        editCount = json['editCount'];
-
-  Map<String, Object> toJson() => {
-        'type': _encodeType(type),
-        'name': name,
-        if (subtree != null) 'subtree': listToJson(subtree),
-        if (path != null) 'path': path,
-        if (href != null) 'href': href,
-        if (editCount != null) 'editCount': editCount
-      };
-
-  /// Deserializes a list of navigation tree nodes from a JSON list.
-  static List<NavigationTreeNode> listFromJson(dynamic json) =>
-      [for (var node in json) NavigationTreeNode.fromJson(node)];
-
-  /// Deserializes a list of navigation tree nodes from a possibly null JSON
-  /// list.  If the argument is `null`, `null` is returned.
-  static List<NavigationTreeNode> listFromJsonOrNull(dynamic json) =>
-      json == null ? null : listFromJson(json);
-
-  /// Serializes a list of navigation tree nodes into JSON.
-  static List<Map<String, Object>> listToJson(List<NavigationTreeNode> nodes) =>
-      [for (var node in nodes) node.toJson()];
-
-  static NavigationTreeNodeType _decodeType(String json) {
-    switch (json) {
-      case 'directory':
-        return NavigationTreeNodeType.directory;
-      case 'file':
-        return NavigationTreeNodeType.file;
-      default:
-        throw StateError('Unrecognized navigation tree node type: $json');
-    }
-  }
-
-  static String _encodeType(NavigationTreeNodeType type) {
-    switch (type) {
-      case NavigationTreeNodeType.directory:
-        return 'directory';
-      case NavigationTreeNodeType.file:
-        return 'file';
-    }
-    throw StateError('Unrecognized navigation tree node type: $type');
-  }
-}
-
-/// Enum representing the different types of [NavigationTreeNode]s.
-enum NavigationTreeNodeType {
-  directory,
-  file,
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/dart_file_page.dart b/pkg/analysis_server/lib/src/edit/preview/dart_file_page.dart
deleted file mode 100644
index 7f7da1f..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/dart_file_page.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_renderer.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that is displayed when a preview of a valid Dart file is requested.
-class DartFilePage extends PreviewPage {
-  /// The information about the file being previewed.
-  final UnitInfo unitInfo;
-
-  /// Initialize a newly created Dart file page within the given [site]. The
-  /// [unitInfo] provides the information needed to render the page.
-  DartFilePage(PreviewSite site, this.unitInfo)
-      // TODO(brianwilkerson) The path needs to be converted to use '/' if that
-      //  isn't already done as part of building the unitInfo.
-      : super(site, unitInfo.path.substring(1));
-
-  @override
-  bool get requiresAuth => true;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    throw UnsupportedError('generateBody');
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    var renderer = UnitRenderer(unitInfo, site.migrationInfo, site.pathMapper);
-    buf.write(jsonEncode(renderer.render().toJson()));
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/exception_page.dart b/pkg/analysis_server/lib/src/edit/preview/exception_page.dart
deleted file mode 100644
index bb18409..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/exception_page.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that is displayed when an exception is encountered in the process
-/// of composing the content of a different page.
-class ExceptionPage extends PreviewPage {
-  /// The message from the exception that caused this page to be displayed.
-  final String message;
-
-  /// The stack trace of the exception that caused this page to be displayed.
-  final StackTrace stackTrace;
-
-  /// Initialize a newly created exception page within the given [site]. The
-  /// [message] and [stackTrace] are used to describe the exception to the user.
-  ExceptionPage(PreviewSite site, String path, this.message, this.stackTrace)
-      : super(site, path.substring(1));
-
-  @override
-  bool get requiresAuth => false;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    buf.write('''
-<h1>500 Exception in preview</h1>
-<p>
-We're sorry, but you've encountered a bug in the preview tool. Please visit
-<a href='https://github.com/dart-lang/sdk/issues/new'>
-github.com/dart-lang/sdk/issues/new</a> to report the issue and include the
-stack trace below.
-</p>
-<h2>$message</h2>
-<p style="white-space: pre">
-${htmlEscape.convert(stackTrace.toString())}
-</p>
-''');
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/highlight_css_page.dart b/pkg/analysis_server/lib/src/edit/preview/highlight_css_page.dart
deleted file mode 100644
index 0104a69..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/highlight_css_page.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/src/edit/nnbd_migration/resources/resources.g.dart'
-    as resources;
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that contains the CSS used to style the semantic highlighting
-/// within a Dart file.
-class HighlightCssPage extends PreviewPage {
-  /// Initialize a newly created CSS page within the given [site].
-  HighlightCssPage(PreviewSite site)
-      : super(site, PreviewSite.highlightCssPath.substring(1));
-
-  @override
-  bool get requiresAuth => false;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    throw UnimplementedError();
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    buf.write(resources.highlight_css);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/highlight_js_page.dart b/pkg/analysis_server/lib/src/edit/preview/highlight_js_page.dart
deleted file mode 100644
index 6fb15b0..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/highlight_js_page.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/src/edit/nnbd_migration/resources/resources.g.dart'
-    as resources;
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that contains the JavaScript used to apply semantic highlighting
-/// styles to a Dart file.
-class HighlightJSPage extends PreviewPage {
-  /// Initialize a newly created JS page within the given [site].
-  HighlightJSPage(PreviewSite site)
-      : super(site, PreviewSite.highlightJsPath.substring(1));
-
-  @override
-  bool get requiresAuth => false;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    throw UnimplementedError();
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    buf.write(resources.highlight_pack_js);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart b/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
deleted file mode 100644
index caf4d48..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// Instances of the class [AbstractGetHandler] handle GET requests.
-abstract class AbstractGetHandler {
-  /// Handle a GET request received by the HTTP server.
-  Future<void> handleGetRequest(HttpRequest request);
-}
-
-/// Instances of the class [AbstractPostHandler] handle POST requests.
-abstract class AbstractPostHandler {
-  /// Handle a POST request received by the HTTP server.
-  Future<void> handlePostRequest(HttpRequest request);
-}
-
-/// Instances of the class [HttpPreviewServer] implement a simple HTTP server
-/// that serves up dartfix preview pages.
-class HttpPreviewServer {
-  /// The state of the migration being previewed.
-  final MigrationState migrationState;
-
-  /// The [PreviewSite] that can handle GET and POST requests.
-  PreviewSite previewSite;
-
-  /// Future that is completed with the HTTP server once it is running.
-  Future<HttpServer> _serverFuture;
-
-  // A function which allows the migration to be rerun, taking changed paths.
-  final Future<MigrationState> Function([List<String>]) rerunFunction;
-
-  /// Initialize a newly created HTTP server.
-  HttpPreviewServer(this.migrationState, this.rerunFunction);
-
-  Future<String> get authToken async {
-    await _serverFuture;
-    previewSite ??= PreviewSite(migrationState, rerunFunction);
-    return previewSite.serviceAuthToken;
-  }
-
-  /// Return the port this server is bound to.
-  Future<int> get boundPort async {
-    return (await _serverFuture)?.port;
-  }
-
-  void close() {
-    _serverFuture?.then((HttpServer server) {
-      server.close();
-    });
-  }
-
-  /// Begin serving HTTP requests over the given port.
-  Future<int> serveHttp([int initialPort]) async {
-    if (_serverFuture != null) {
-      return boundPort;
-    }
-
-    try {
-      _serverFuture =
-          HttpServer.bind(InternetAddress.loopbackIPv4, initialPort ?? 0);
-
-      var server = await _serverFuture;
-      _handleServer(server);
-      return server.port;
-    } catch (ignore) {
-      // If we can't bind to the specified port, don't remember the broken
-      // server.
-      _serverFuture = null;
-
-      return null;
-    }
-  }
-
-  /// Handle a GET request received by the HTTP server.
-  Future<void> _handleGetRequest(HttpRequest request) async {
-    previewSite ??= PreviewSite(migrationState, rerunFunction);
-    await previewSite.handleGetRequest(request);
-  }
-
-  /// Handle a POST request received by the HTTP server.
-  Future<void> _handlePostRequest(HttpRequest request) async {
-    previewSite ??= PreviewSite(migrationState, rerunFunction);
-    await previewSite.handlePostRequest(request);
-  }
-
-  /// Attach a listener to a newly created HTTP server.
-  void _handleServer(HttpServer httpServer) {
-    httpServer.listen((HttpRequest request) async {
-      var updateValues = request.headers[HttpHeaders.upgradeHeader];
-      if (request.method == 'GET') {
-        await _handleGetRequest(request);
-      } else if (request.method == 'POST') {
-        await _handlePostRequest(request);
-      } else if (updateValues != null && updateValues.contains('websocket')) {
-        // We do not support serving analysis server communications over
-        // WebSocket connections.
-        var response = request.response;
-        response.statusCode = HttpStatus.notFound;
-        response.headers.contentType = ContentType.text;
-        response.write(
-            'WebSocket connections not supported (${request.uri.path}).');
-        response.close();
-      } else {
-        _returnUnknownRequest(request);
-      }
-    });
-  }
-
-  /// Return an error in response to an unrecognized request received by the HTTP
-  /// server.
-  void _returnUnknownRequest(HttpRequest request) {
-    var response = request.response;
-    response.statusCode = HttpStatus.notFound;
-    response.headers.contentType = ContentType.text;
-    response.write('Not found');
-    response.close();
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart b/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
deleted file mode 100644
index d3e5fa5..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that is displayed when the root of the included path is requested.
-class IndexFilePage extends PreviewPage {
-  /// Initialize a newly created index file page within the given [site].
-  IndexFilePage(PreviewSite site)
-      : super(site, site.migrationInfo.includedRoot);
-
-  @override
-  bool get requiresAuth => true;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    throw UnsupportedError('generateBody');
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    var renderer = InstrumentationRenderer(site.migrationInfo, site.pathMapper,
-        site.migrationState.hasBeenApplied);
-    buf.write(renderer.render());
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/navigation_tree_page.dart b/pkg/analysis_server/lib/src/edit/preview/navigation_tree_page.dart
deleted file mode 100644
index 415d6f6..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/navigation_tree_page.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:analysis_server/src/edit/nnbd_migration/navigation_tree_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The JSON that is displayed for the navigation tree.
-class NavigationTreePage extends PreviewPage {
-  /// Initialize a newly created navigation tree page within the given [site].
-  NavigationTreePage(PreviewSite site)
-      : super(site, site.migrationInfo.includedRoot);
-
-  @override
-  bool get requiresAuth => true;
-
-  @override
-  // TODO(srawlins): Refactor JSON-returning pages like this to not inherit all
-  //  of the HTML logic from [PreviewPage].
-  void generateBody(Map<String, String> params) {
-    throw UnsupportedError('generateBody');
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    var renderer = NavigationTreeRenderer(site.migrationInfo, site.pathMapper);
-    buf.write(jsonEncode(NavigationTreeNode.listToJson(renderer.render())));
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/not_found_page.dart b/pkg/analysis_server/lib/src/edit/preview/not_found_page.dart
deleted file mode 100644
index 5865b5f..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/not_found_page.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.
-
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that is displayed when an invalid URL is requested.
-class NotFoundPage extends PreviewPage {
-  /// Initialize a newly created file-not-found page within the given [site].
-  /// The [id] is the portion of the path to the page that follows the initial
-  /// slash ('/').
-  NotFoundPage(PreviewSite site, String id) : super(site, id);
-
-  @override
-  bool get requiresAuth => false;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    buf.write('''
-<h1>404 Not found</h1>
-<p>
-'$path' not found.
-</p>
-''');
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/preview_page.dart b/pkg/analysis_server/lib/src/edit/preview/preview_page.dart
deleted file mode 100644
index b82a4ef..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/preview_page.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-import 'package:analysis_server/src/status/pages.dart';
-
-/// A page displayed on the preview site.
-abstract class PreviewPage extends Page {
-  /// The site containing the page.
-  final PreviewSite site;
-
-  /// Initialize a newly created page within the given [site]. The [id] is the
-  /// portion of the path to the page that follows the initial slash ('/').
-  PreviewPage(this.site, String id) : super(id, '', description: '');
-
-  /// Whether pages of this type require authorization.
-  bool get requiresAuth;
-
-  /// Generate the content of the body tag.
-  void generateBody(Map<String, String> params);
-
-  /// Generate the content of the head tag.
-  void generateHead() {
-    buf.writeln('<meta charset="utf-8">');
-    buf.writeln('<meta name="viewport" content="width=device-width, '
-        'initial-scale=1.0">');
-    buf.writeln('<title>${site.title}</title>');
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    buf.writeln('<!DOCTYPE html><html lang="en">');
-    buf.writeln('<head>');
-    buf.writeln('</head>');
-    generateHead();
-    buf.writeln('<body>');
-    generateBody(params);
-    buf.writeln('</body>');
-    buf.writeln('</html>');
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart b/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
deleted file mode 100644
index cdbb8fb..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math';
-import 'dart:typed_data';
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/preview/dart_file_page.dart';
-import 'package:analysis_server/src/edit/preview/exception_page.dart';
-import 'package:analysis_server/src/edit/preview/highlight_css_page.dart';
-import 'package:analysis_server/src/edit/preview/highlight_js_page.dart';
-import 'package:analysis_server/src/edit/preview/http_preview_server.dart';
-import 'package:analysis_server/src/edit/preview/index_file_page.dart';
-import 'package:analysis_server/src/edit/preview/navigation_tree_page.dart';
-import 'package:analysis_server/src/edit/preview/not_found_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/region_page.dart';
-import 'package:analysis_server/src/edit/preview/unauthorized_page.dart';
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analysis_server/src/status/pages.dart';
-
-// The randomly generated auth token used to access the preview site.
-String _makeAuthToken() {
-  final kTokenByteSize = 8;
-  var bytes = Uint8List(kTokenByteSize);
-  var random = Random.secure();
-  for (var i = 0; i < kTokenByteSize; i++) {
-    bytes[i] = random.nextInt(256);
-  }
-  return base64Url.encode(bytes);
-}
-
-/// The site used to serve pages for the preview tool.
-class PreviewSite extends Site
-    implements AbstractGetHandler, AbstractPostHandler {
-  /// The path of the CSS page used to style the semantic highlighting within a
-  /// Dart file.
-  static const highlightCssPath = '/highlight.css';
-
-  /// The path of the JS page used to associate highlighting within a Dart file.
-  static const highlightJsPath = '/highlight.pack.js';
-
-  static const navigationTreePath = '/_preview/navigationTree.json';
-
-  static const applyMigrationPath = '/apply-migration';
-
-  static const rerunMigrationPath = '/rerun-migration';
-
-  /// The state of the migration being previewed.
-  MigrationState migrationState;
-
-  /// A table mapping the paths of files to the information about the
-  /// compilation units at those paths.
-  final Map<String, UnitInfo> unitInfoMap = {};
-
-  // A function provided by DartFix to rerun the migration.
-  final Future<MigrationState> Function([List<String>]) rerunFunction;
-
-  final String serviceAuthToken = _makeAuthToken();
-
-  /// Initialize a newly created site to serve a preview of the results of an
-  /// NNBD migration.
-  PreviewSite(this.migrationState, this.rerunFunction)
-      : super('NNBD Migration Preview') {
-    reset();
-  }
-
-  /// Return the information about the migration that will be used to serve up
-  /// pages.
-  MigrationInfo get migrationInfo => migrationState.migrationInfo;
-
-  /// Return the path mapper used to map paths from the unit infos to the paths
-  /// being served.
-  PathMapper get pathMapper => migrationState.pathMapper;
-
-  @override
-  Page createExceptionPage(String message, StackTrace trace) {
-    // Use createExceptionPageWithPath instead.
-    throw UnimplementedError();
-  }
-
-  /// Return a page used to display an exception that occurred while attempting
-  /// to render another page. The [path] is the path to the page that was being
-  /// rendered when the exception was thrown. The [message] and [stackTrace] are
-  /// those from the exception.
-  Page createExceptionPageWithPath(
-      String path, String message, StackTrace stackTrace) {
-    return ExceptionPage(this, path, message, stackTrace);
-  }
-
-  Page createUnauthorizedPage(String unauthorizedPath) {
-    return UnauthorizedPage(this, unauthorizedPath.substring(1));
-  }
-
-  @override
-  Page createUnknownPage(String unknownPath) {
-    return NotFoundPage(this, unknownPath.substring(1));
-  }
-
-  @override
-  Future<void> handleGetRequest(HttpRequest request) async {
-    var uri = request.uri;
-    var path = uri.path;
-    try {
-      if (path == highlightCssPath) {
-        // Note: `return await` needed due to
-        // https://github.com/dart-lang/sdk/issues/39204
-        return await respond(request, HighlightCssPage(this));
-      } else if (path == highlightJsPath) {
-        // Note: `return await` needed due to
-        // https://github.com/dart-lang/sdk/issues/39204
-        return await respond(request, HighlightJSPage(this));
-      } else if (path == navigationTreePath) {
-        // Note: `return await` needed due to
-        // https://github.com/dart-lang/sdk/issues/39204
-        return await respond(request, NavigationTreePage(this));
-      } else if (path == '/' ||
-          path == migrationInfo.includedRoot ||
-          path == '${migrationInfo.includedRoot}/') {
-        // Note: `return await` needed due to
-        // https://github.com/dart-lang/sdk/issues/39204
-        return await respond(request, IndexFilePage(this));
-      }
-
-      var unitInfo = unitInfoMap[path];
-      if (unitInfo != null) {
-        if (uri.queryParameters.containsKey('inline')) {
-          // TODO(devoncarew): Ensure that we don't serve content outside of our
-          //  project.
-
-          // Note: `return await` needed due to
-          // https://github.com/dart-lang/sdk/issues/39204
-          return await respond(request, DartFilePage(this, unitInfo));
-        } else if (uri.queryParameters.containsKey('region')) {
-          // TODO(devoncarew): Ensure that we don't serve content outside of our
-          //  project.
-
-          // Note: `return await` needed due to
-          // https://github.com/dart-lang/sdk/issues/39204
-          return await respond(request, RegionPage(this, unitInfo));
-        } else {
-          // Note: `return await` needed due to
-          // https://github.com/dart-lang/sdk/issues/39204
-          return await respond(request, IndexFilePage(this));
-        }
-      }
-      // Note: `return await` needed due to
-      // https://github.com/dart-lang/sdk/issues/39204
-      return await respond(
-          request, createUnknownPage(path), HttpStatus.notFound);
-    } catch (exception, stackTrace) {
-      _respondInternalError(request, path, exception, stackTrace);
-    }
-  }
-
-  @override
-  Future<void> handlePostRequest(HttpRequest request) async {
-    var uri = request.uri;
-    var path = uri.path;
-    try {
-      // All POST requests must be authorized.
-      if (!_isAuthorized(request)) {
-        return _respondUnauthorized(request);
-      }
-      if (path == applyMigrationPath) {
-        performApply();
-
-        respondOk(request);
-        return;
-      } else if (path == rerunMigrationPath) {
-        await rerunMigration();
-
-        respondOk(request);
-        return;
-      } else if (uri.queryParameters.containsKey('replacement')) {
-        await performEdit(uri);
-
-        respondOk(request);
-        return;
-      }
-    } catch (exception, stackTrace) {
-      _respondInternalError(request, path, exception, stackTrace);
-    }
-  }
-
-  /// Perform the migration.
-  void performApply() {
-    if (migrationState.hasBeenApplied) {
-      throw StateError('Cannot reapply migration.');
-    }
-
-    final edits = migrationState.listener.sourceChange.edits;
-
-    // Eagerly mark the migration applied. If this throws, we cannot go back.
-    migrationState.markApplied();
-    for (final fileEdit in edits) {
-      final file = pathMapper.provider.getFile(fileEdit.file);
-      var code = file.exists ? file.readAsStringSync() : '';
-      code = SourceEdit.applySequence(code, fileEdit.edits);
-      file.writeAsStringSync(code);
-    }
-  }
-
-  /// Perform the edit indicated by the [uri].
-  Future<void> performEdit(Uri uri) async {
-    //
-    // Update the code on disk.
-    //
-    var params = uri.queryParameters;
-    var path = uri.path;
-    var offset = int.parse(params['offset']);
-    var end = int.parse(params['end']);
-    var replacement = params['replacement'];
-    var file = pathMapper.provider.getFile(path);
-    var oldContent = file.readAsStringSync();
-    var newContent = oldContent.replaceRange(offset, end, replacement);
-    file.writeAsStringSync(newContent);
-    await rerunMigration([path]);
-  }
-
-  Future<void> rerunMigration([List<String> changedPaths]) async {
-    migrationState = await rerunFunction(changedPaths);
-    reset();
-  }
-
-  void reset() {
-    unitInfoMap.clear();
-    var unitInfos = migrationInfo.units;
-    var provider = pathMapper.provider;
-    for (var unit in unitInfos) {
-      unitInfoMap[unit.path] = unit;
-    }
-    for (var unit in migrationInfo.unitMap.values) {
-      if (!unitInfos.contains(unit)) {
-        if (unit.content == null) {
-          try {
-            unit.content = provider.getFile(unit.path).readAsStringSync();
-          } catch (_) {
-            // If we can't read the content of the file, then skip it.
-            continue;
-          }
-        }
-        unitInfoMap[unit.path] = unit;
-      }
-    }
-  }
-
-  @override
-  Future<void> respond(HttpRequest request, Page page,
-      [int code = HttpStatus.ok]) async {
-    if (page is PreviewPage && page.requiresAuth) {
-      if (!_isAuthorized(request)) {
-        return _respondUnauthorized(request);
-      }
-    }
-    var response = request.response;
-    response.statusCode = code;
-    if (page is HighlightCssPage) {
-      response.headers.contentType =
-          ContentType('text', 'css', charset: 'utf-8');
-    } else if (page is HighlightJSPage) {
-      response.headers.contentType =
-          ContentType('application', 'javascript', charset: 'utf-8');
-    } else {
-      response.headers.contentType = ContentType.html;
-    }
-    response.write(await page.generate(request.uri.queryParameters));
-    response.close();
-  }
-
-  /// Returns whether [request] is an authorized request.
-  bool _isAuthorized(HttpRequest request) {
-    var authToken = request.uri.queryParameters['authToken'];
-    return authToken == serviceAuthToken;
-  }
-
-  Future<void> _respondInternalError(HttpRequest request, String path,
-      dynamic exception, StackTrace stackTrace) async {
-    try {
-      await respond(
-          request,
-          createExceptionPageWithPath(path, '$exception', stackTrace),
-          HttpStatus.internalServerError);
-    } catch (exception, stackTrace) {
-      var response = request.response;
-      response.statusCode = HttpStatus.internalServerError;
-      response.headers.contentType = ContentType.text;
-      response.write('$exception\n\n$stackTrace');
-      response.close();
-    }
-  }
-
-  /// Responds with a 401 Unauthorized response.
-  Future<void> _respondUnauthorized(HttpRequest request) async {
-    var page = createUnauthorizedPage(request.uri.path);
-    var response = request.response;
-    response
-      ..statusCode = HttpStatus.unauthorized
-      ..headers.contentType = ContentType.html
-      ..write(await page.generate(request.uri.queryParameters))
-      ..close();
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/region_page.dart b/pkg/analysis_server/lib/src/edit/preview/region_page.dart
deleted file mode 100644
index 89b67f0..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/region_page.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert' show jsonEncode;
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/region_renderer.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The HTML that is displayed for a region of code.
-class RegionPage extends PreviewPage {
-  /// The compilation unit information containing the region.
-  final UnitInfo unitInfo;
-
-  /// Initialize a newly created region page within the given [site]. The
-  /// [unitInfo] provides the information needed to render the page.
-  RegionPage(PreviewSite site, this.unitInfo)
-      : super(site, unitInfo.path.substring(1));
-
-  @override
-  bool get requiresAuth => true;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    throw UnsupportedError('generateBody');
-  }
-
-  @override
-  Future<void> generatePage(Map<String, String> params) async {
-    var region = unitInfo.regionAt(int.parse(params['offset']));
-    var renderer =
-        RegionRenderer(region, unitInfo, site.migrationInfo, site.pathMapper);
-    buf.write(jsonEncode(renderer.render().toJson()));
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/preview/unauthorized_page.dart b/pkg/analysis_server/lib/src/edit/preview/unauthorized_page.dart
deleted file mode 100644
index e93f426..0000000
--- a/pkg/analysis_server/lib/src/edit/preview/unauthorized_page.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-
-/// The page that is displayed when a request could not be authenticated.
-class UnauthorizedPage extends PreviewPage {
-  /// Initialize a newly created unauthorized page within the given [site].
-  /// The [id] is the portion of the path to the page that follows the initial
-  /// slash ('/').
-  UnauthorizedPage(PreviewSite site, String id) : super(site, id);
-
-  @override
-  bool get requiresAuth => false;
-
-  @override
-  void generateBody(Map<String, String> params) {
-    buf.write('''
-<h1>401 Unauthorized</h1>
-<p>
-Request for '$path' is unauthorized.
-</p>
-''');
-  }
-}
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 4b12674..3af7d6f 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
@@ -99,7 +99,7 @@
   Either2<Command, CodeAction> _createAssistAction(Assist assist) {
     return Either2<Command, CodeAction>.t2(CodeAction(
       assist.change.message,
-      CodeActionKind.Refactor,
+      toCodeActionKind(assist.change.id, CodeActionKind.Refactor),
       const [],
       createWorkspaceEdit(server, assist.change.edits),
       null,
@@ -114,7 +114,7 @@
       Fix fix, Diagnostic diagnostic) {
     return Either2<Command, CodeAction>.t2(CodeAction(
       fix.change.message,
-      CodeActionKind.QuickFix,
+      toCodeActionKind(fix.change.id, CodeActionKind.QuickFix),
       [diagnostic],
       createWorkspaceEdit(server, fix.change.edits),
       null,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index bee5664..04f7092 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -148,6 +148,8 @@
 
     try {
       CompletionContributor contributor = DartCompletionManager(
+        dartdocDirectiveInfo:
+            server.getDartdocDirectiveInfoFor(completionRequest.result),
         includedElementKinds: includedElementKinds,
         includedElementNames: includedElementNames,
         includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
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 dfa4dba..e9009a3 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -6,12 +6,17 @@
 
 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/navigation_dart.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart'
+    hide AnalysisGetNavigationParams;
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/plugin/result_merger.dart';
 import 'package:analysis_server/src/protocol_server.dart' show NavigationTarget;
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 
 class DefinitionHandler
     extends MessageHandler<TextDocumentPositionParams, List<Location>> {
@@ -23,30 +28,77 @@
   LspJsonHandler<TextDocumentPositionParams> get jsonHandler =>
       TextDocumentPositionParams.jsonHandler;
 
+  Future<List<AnalysisNavigationParams>> getPluginResults(
+    String path,
+    int offset,
+  ) async {
+    // LSP requests must be converted to DAS-protocol requests for compatibility
+    // with plugins.
+    final requestParams = plugin.AnalysisGetNavigationParams(path, offset, 0);
+
+    final driver = server.getAnalysisDriver(path);
+    final pluginFutures = server.pluginManager
+        .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
+
+    final responses =
+        await waitForResponses(pluginFutures, requestParameters: requestParams);
+
+    return responses
+        .map((response) =>
+            plugin.AnalysisGetNavigationResult.fromResponse(response))
+        .map((result) => AnalysisNavigationParams(
+            path, result.regions, result.targets, result.files))
+        .toList();
+  }
+
+  Future<AnalysisNavigationParams> getServerResult(
+      String path, int offset) async {
+    final collector = NavigationCollectorImpl();
+
+    final result = await server.getResolvedUnit(path);
+    if (result?.state == ResultState.VALID) {
+      computeDartNavigation(
+          server.resourceProvider, collector, result.unit, offset, 0);
+    }
+
+    return AnalysisNavigationParams(
+        path, collector.regions, collector.targets, collector.files);
+  }
+
   @override
   Future<ErrorOr<List<Location>>> handle(
       TextDocumentPositionParams params, CancellationToken token) async {
-    if (!isDartDocument(params.textDocument)) {
-      return success(const []);
-    }
-
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireResolvedUnit);
-    final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
-    return offset.mapResult((offset) {
-      var collector = NavigationCollectorImpl();
-      computeDartNavigation(
-          server.resourceProvider, collector, unit.result.unit, offset, 0);
-
-      Location toLocation(NavigationTarget target) {
-        final targetFilePath = collector.files[target.fileIndex];
-        final lineInfo = server.getLineInfo(targetFilePath);
-        return navigationTargetToLocation(targetFilePath, target, lineInfo);
+    return path.mapResult((path) async {
+      final lineInfo = server.getLineInfo(path);
+      // If there is no lineInfo, the request canot be translated from LSP line/col
+      // to server offset/length.
+      if (lineInfo == null) {
+        return success(const []);
       }
 
-      return success(convert(collector.targets, toLocation).toList());
+      final offset = toOffset(lineInfo, pos);
+
+      return offset.mapResult((offset) async {
+        final allResults = [
+          await getServerResult(path, offset),
+          ...await getPluginResults(path, offset),
+        ];
+
+        final merger = ResultMerger();
+        final mergedResults = merger.mergeNavigation(allResults);
+        final mergedTargets = mergedResults?.targets ?? [];
+
+        Location toLocation(NavigationTarget target) {
+          final targetFilePath = mergedResults.files[target.fileIndex];
+          final lineInfo = server.getLineInfo(targetFilePath);
+          return navigationTargetToLocation(targetFilePath, target, lineInfo);
+        }
+
+        return success(convert(mergedTargets, toLocation).toList());
+      });
     });
   }
 }
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 bb721de..418e84d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
@@ -10,6 +10,9 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/source/line_info.dart';
 
 class FoldingHandler
     extends MessageHandler<FoldingRangeParams, List<FoldingRange>> {
@@ -24,16 +27,36 @@
   @override
   Future<ErrorOr<List<FoldingRange>>> handle(
       FoldingRangeParams params, CancellationToken token) async {
-    if (!isDartDocument(params.textDocument)) {
-      return success(const []);
-    }
-
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnresolvedUnit);
 
-    return unit.mapResult((unit) {
-      final lineInfo = unit.lineInfo;
-      final regions = DartUnitFoldingComputer(lineInfo, unit.unit).compute();
+    return path.mapResult((path) async {
+      final partialResults = <List<FoldingRegion>>[];
+      LineInfo lineInfo;
+
+      final unit = server.getParsedUnit(path);
+      if (unit?.state == ResultState.VALID) {
+        lineInfo = unit.lineInfo;
+
+        final regions = DartUnitFoldingComputer(lineInfo, unit.unit).compute();
+        partialResults.insert(0, regions);
+      }
+
+      // Still try to obtain line info for invalid or non-Dart files, as plugins
+      // could contribute to those.
+      lineInfo ??= server.getLineInfo(path);
+
+      if (lineInfo == null) {
+        // Line information would be required to translate folding results to
+        // LSP.
+        return success(const []);
+      }
+
+      final notificationManager = server.notificationManager;
+      final pluginResults = notificationManager.folding.getResults(path);
+      partialResults.addAll(pluginResults);
+
+      final regions =
+          notificationManager.merger.mergeFoldingRegions(partialResults);
 
       return success(
         regions.map((region) => toFoldingRange(lineInfo, region)).toList(),
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 eeee66f..7df227a 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -4,88 +4,10 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 
-/// Helper for reading client dynamic registrations which may be ommitted by the
-/// client.
-class ClientDynamicRegistrations {
-  /// All dynamic registrations supported by the Dart LSP server.
-  ///
-  /// Anything listed here and supported by the client will not send a static
-  /// registration but intead dynamically register (usually only for a subset of
-  /// files such as for .dart/pubspec.yaml/etc).
-  ///
-  /// When adding new capabilities that will be registered dynamically, the
-  /// test_dynamicRegistration_XXX tests in `lsp/initialization_test.dart` should
-  /// also be updated to ensure no double-registrations.
-  static const supported = [
-    Method.textDocument_didOpen,
-    Method.textDocument_didChange,
-    Method.textDocument_didClose,
-    Method.textDocument_completion,
-    Method.textDocument_hover,
-    Method.textDocument_signatureHelp,
-    Method.textDocument_references,
-    Method.textDocument_documentHighlight,
-    Method.textDocument_formatting,
-    Method.textDocument_onTypeFormatting,
-    Method.textDocument_definition,
-    Method.textDocument_codeAction,
-    Method.textDocument_rename,
-    Method.textDocument_foldingRange,
-  ];
-  final ClientCapabilities _capabilities;
-
-  ClientDynamicRegistrations(this._capabilities);
-
-  bool get codeActions =>
-      _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
-
-  bool get completion =>
-      _capabilities.textDocument?.completion?.dynamicRegistration ?? false;
-
-  bool get definition =>
-      _capabilities.textDocument?.definition?.dynamicRegistration ?? false;
-
-  bool get documentHighlights =>
-      _capabilities.textDocument?.documentHighlight?.dynamicRegistration ??
-      false;
-
-  bool get documentSymbol =>
-      _capabilities.textDocument?.documentSymbol?.dynamicRegistration ?? false;
-
-  bool get folding =>
-      _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
-
-  bool get formatting =>
-      _capabilities.textDocument?.formatting?.dynamicRegistration ?? false;
-
-  bool get hover =>
-      _capabilities.textDocument?.hover?.dynamicRegistration ?? false;
-
-  bool get implementation =>
-      _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
-
-  bool get references =>
-      _capabilities.textDocument?.references?.dynamicRegistration ?? false;
-
-  bool get rename =>
-      _capabilities.textDocument?.rename?.dynamicRegistration ?? false;
-
-  bool get signatureHelp =>
-      _capabilities.textDocument?.signatureHelp?.dynamicRegistration ?? false;
-
-  bool get textSync =>
-      _capabilities.textDocument?.synchronization?.dynamicRegistration ?? false;
-
-  bool get typeFormatting =>
-      _capabilities.textDocument?.onTypeFormatting?.dynamicRegistration ??
-      false;
-}
-
 class InitializeMessageHandler
     extends MessageHandler<InitializeParams, InitializeResult> {
   InitializeMessageHandler(LspAnalysisServer server) : super(server);
@@ -131,92 +53,8 @@
       openWorkspacePaths,
     );
 
-    final codeActionLiteralSupport =
-        params.capabilities.textDocument?.codeAction?.codeActionLiteralSupport;
-
-    final renameOptionsSupport =
-        params.capabilities.textDocument?.rename?.prepareSupport ?? false;
-
-    final dynamicRegistrations =
-        ClientDynamicRegistrations(params.capabilities);
-
-    // When adding new capabilities to the server that may apply to specific file
-    // types, it's important to update
-    // [IntializedMessageHandler._performDynamicRegistration()] to notify
-    // supporting clients of this. This avoids clients needing to hard-code the
-    // list of what files types we support (and allows them to avoid sending
-    // requests where we have only partial support for some types).
-    server.capabilities = ServerCapabilities(
-        dynamicRegistrations.textSync
-            ? null
-            : Either2<TextDocumentSyncOptions, num>.t1(TextDocumentSyncOptions(
-                // The open/close and sync kind flags are registered dynamically if the
-                // client supports them, so these static registrations are based on whether
-                // the client supports dynamic registration.
-                true,
-                TextDocumentSyncKind.Incremental,
-                false,
-                false,
-                null,
-              )),
-        dynamicRegistrations.hover ? null : true, // hoverProvider
-        dynamicRegistrations.completion
-            ? null
-            : CompletionOptions(
-                true, // resolveProvider
-                dartCompletionTriggerCharacters,
-              ),
-        dynamicRegistrations.signatureHelp
-            ? null
-            : SignatureHelpOptions(
-                dartSignatureHelpTriggerCharacters,
-              ),
-        dynamicRegistrations.definition ? null : true, // definitionProvider
-        null,
-        dynamicRegistrations.implementation
-            ? null
-            : true, // implementationProvider
-        dynamicRegistrations.references ? null : true, // referencesProvider
-        dynamicRegistrations.documentHighlights
-            ? null
-            : true, // documentHighlightProvider
-        dynamicRegistrations.documentSymbol
-            ? null
-            : true, // documentSymbolProvider
-        true, // workspaceSymbolProvider
-        // "The `CodeActionOptions` return type is only valid if the client
-        // signals code action literal support via the property
-        // `textDocument.codeAction.codeActionLiteralSupport`."
-        dynamicRegistrations.codeActions
-            ? null
-            : codeActionLiteralSupport != null
-                ? Either2<bool, CodeActionOptions>.t2(
-                    CodeActionOptions(DartCodeActionKind.serverSupportedKinds))
-                : Either2<bool, CodeActionOptions>.t1(true),
-        null,
-        dynamicRegistrations.formatting
-            ? null
-            : true, // documentFormattingProvider
-        false, // documentRangeFormattingProvider
-        dynamicRegistrations.typeFormatting
-            ? null
-            : DocumentOnTypeFormattingOptions(
-                dartTypeFormattingCharacters.first,
-                dartTypeFormattingCharacters.skip(1).toList()),
-        dynamicRegistrations.rename
-            ? null
-            : renameOptionsSupport
-                ? Either2<bool, RenameOptions>.t2(RenameOptions(true))
-                : Either2<bool, RenameOptions>.t1(true),
-        null,
-        null,
-        dynamicRegistrations.folding ? null : true, // foldingRangeProvider
-        null, // declarationProvider
-        ExecuteCommandOptions(Commands.serverSupportedCommands),
-        ServerCapabilitiesWorkspace(
-            ServerCapabilitiesWorkspaceFolders(true, true)),
-        null);
-
+    server.capabilities = server.capabilitiesComputer
+        .computeServerCapabilities(params.capabilities);
     return success(InitializeResult(server.capabilities));
   }
 }
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 854eaf5..f1cbeba 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
@@ -28,7 +27,7 @@
       server,
     );
 
-    _performDynamicRegistration();
+    server.capabilitiesComputer.performDynamicRegistration();
 
     if (!server.initializationOptions.onlyAnalyzeProjectsWithOpenFiles) {
       server.setAnalysisRoots(openWorkspacePaths);
@@ -36,146 +35,4 @@
 
     return success();
   }
-
-  /// If the client supports dynamic registrations we can tell it what methods
-  /// we support for which documents. For example, this allows us to ask for
-  /// file edits for .dart as well as pubspec.yaml but only get hover/completion
-  /// calls for .dart. This functionality may not be supported by the client, in
-  /// which case they will use the ServerCapabilities to know which methods we
-  /// support and it will be up to them to decide which file types they will
-  /// send requests for.
-  Future<void> _performDynamicRegistration() async {
-    final dartFiles = DocumentFilter('dart', 'file', null);
-    final pubspecFile = DocumentFilter('yaml', 'file', '**/pubspec.yaml');
-    final analysisOptionsFile =
-        DocumentFilter('yaml', 'file', '**/analysis_options.yaml');
-    final allTypes = [dartFiles, pubspecFile, analysisOptionsFile];
-
-    // TODO(dantup): When we support plugins, we will need to collect their
-    // requirements too. For example, the Angular plugin might wish to add HTML
-    // `DocumentFilter('html', 'file', null)` to many of these requests.
-
-    var _lastRegistrationId = 1;
-    final registrations = <Registration>[];
-
-    /// Helper for creating registrations with IDs.
-    void register(bool condition, Method method, [ToJsonable options]) {
-      if (condition == true) {
-        registrations.add(Registration(
-            (_lastRegistrationId++).toString(), method.toJson(), options));
-      }
-    }
-
-    final textCapabilities = server.clientCapabilities?.textDocument;
-
-    register(
-      textCapabilities?.synchronization?.dynamicRegistration,
-      Method.textDocument_didOpen,
-      TextDocumentRegistrationOptions(allTypes),
-    );
-    register(
-      textCapabilities?.synchronization?.dynamicRegistration,
-      Method.textDocument_didClose,
-      TextDocumentRegistrationOptions(allTypes),
-    );
-    register(
-      textCapabilities?.synchronization?.dynamicRegistration,
-      Method.textDocument_didChange,
-      TextDocumentChangeRegistrationOptions(
-          TextDocumentSyncKind.Incremental, allTypes),
-    );
-    register(
-      server.clientCapabilities?.textDocument?.completion?.dynamicRegistration,
-      Method.textDocument_completion,
-      CompletionRegistrationOptions(
-        dartCompletionTriggerCharacters,
-        null,
-        true,
-        [dartFiles],
-      ),
-    );
-    register(
-      textCapabilities?.hover?.dynamicRegistration,
-      Method.textDocument_hover,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      textCapabilities?.signatureHelp?.dynamicRegistration,
-      Method.textDocument_signatureHelp,
-      SignatureHelpRegistrationOptions(
-          dartSignatureHelpTriggerCharacters, [dartFiles]),
-    );
-    register(
-      server.clientCapabilities?.textDocument?.references?.dynamicRegistration,
-      Method.textDocument_references,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      textCapabilities?.documentHighlight?.dynamicRegistration,
-      Method.textDocument_documentHighlight,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      textCapabilities?.documentSymbol?.dynamicRegistration,
-      Method.textDocument_documentSymbol,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      server.clientCapabilities?.textDocument?.formatting?.dynamicRegistration,
-      Method.textDocument_formatting,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      textCapabilities?.onTypeFormatting?.dynamicRegistration,
-      Method.textDocument_onTypeFormatting,
-      DocumentOnTypeFormattingRegistrationOptions(
-        dartTypeFormattingCharacters.first,
-        dartTypeFormattingCharacters.skip(1).toList(),
-        [dartFiles],
-      ),
-    );
-    register(
-      server.clientCapabilities?.textDocument?.definition?.dynamicRegistration,
-      Method.textDocument_definition,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      textCapabilities?.implementation?.dynamicRegistration,
-      Method.textDocument_implementation,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-    register(
-      server.clientCapabilities?.textDocument?.codeAction?.dynamicRegistration,
-      Method.textDocument_codeAction,
-      CodeActionRegistrationOptions(
-          [dartFiles], DartCodeActionKind.serverSupportedKinds),
-    );
-    register(
-      textCapabilities?.rename?.dynamicRegistration,
-      Method.textDocument_rename,
-      RenameRegistrationOptions(true, [dartFiles]),
-    );
-    register(
-      textCapabilities?.foldingRange?.dynamicRegistration,
-      Method.textDocument_foldingRange,
-      TextDocumentRegistrationOptions([dartFiles]),
-    );
-
-    // Only send the registration request if we have at least one (since
-    // otherwise we don't know that the client supports registerCapability).
-    if (registrations.isNotEmpty) {
-      final registrationResponse = await server.sendRequest(
-        Method.client_registerCapability,
-        RegistrationParams(registrations),
-      );
-
-      if (registrationResponse.error != null) {
-        server.logErrorToClient(
-          'Failed to register capabilities with client: '
-          '(${registrationResponse.error.code}) '
-          '${registrationResponse.error.message}',
-        );
-      }
-    }
-  }
 }
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 be37eac..bf4094e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -6,7 +6,6 @@
 
 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/navigation_dart.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
@@ -17,6 +16,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 
 class ReferencesHandler
     extends MessageHandler<ReferenceParams, List<Location>> {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index b25a5d8..4d36a7e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_cancel_request.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_reject.dart';
@@ -68,7 +69,8 @@
 /// An object that can handle messages and produce responses for requests.
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class MessageHandler<P, R> with Handler<P, R> {
+abstract class MessageHandler<P, R>
+    with Handler<P, R>, RequestHandlerMixin<LspAnalysisServer> {
   MessageHandler(LspAnalysisServer server) {
     this.server = server;
   }
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 0145248..cecd4f4 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:io' as io;
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
@@ -12,29 +11,28 @@
 import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/analysis_server_abstract.dart';
+import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/computer/computer_closingLabels.dart';
 import 'package:analysis_server/src/computer/computer_outline.dart';
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/domain_completion.dart'
     show CompletionDomainHandler;
-import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/flutter/flutter_outline_computer.dart';
 import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/server_capabilities_computer.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
 import 'package:analysis_server/src/server/diagnostic_server.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart'
     show CompletionPerformance;
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analysis_server/src/utilities/null_string_sink.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -44,11 +42,10 @@
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:watcher/watcher.dart';
 
 /// Instances of the class [LspAnalysisServer] implement an LSP-based server
@@ -66,21 +63,6 @@
   /// be sent.
   final LspServerCommunicationChannel channel;
 
-  /// The [SearchEngine] for this server, may be `null` if indexing is disabled.
-  SearchEngine searchEngine;
-
-  final NotificationManager notificationManager = NullNotificationManager();
-
-  /// The object used to manage the SDK's known to this server.
-  final DartSdkManager sdkManager;
-
-  /// The instrumentation service that is to be used by this analysis server.
-  final InstrumentationService instrumentationService;
-
-  /// The default options used to create new analysis contexts. This object is
-  /// also referenced by the ContextManager.
-  final AnalysisOptionsImpl defaultContextOptions = AnalysisOptionsImpl();
-
   /// The workspace for rename refactorings. Should be accessed through the
   /// refactoringWorkspace getter to be automatically created (lazily).
   RefactoringWorkspace _refactoringWorkspace;
@@ -94,8 +76,6 @@
   /// not known.
   final Map<String, VersionedTextDocumentIdentifier> documentVersions = {};
 
-  PerformanceLog _analysisPerformanceLogger;
-
   ServerStateMessageHandler messageHandler;
 
   int nextRequestId = 1;
@@ -105,6 +85,7 @@
   /// Capabilities of the server. Will be null prior to initialization as
   /// the server capabilities depend on the client capabilities.
   ServerCapabilities capabilities;
+  ServerCapabilitiesComputer capabilitiesComputer;
 
   LspPerformance performanceStats = LspPerformance();
 
@@ -112,58 +93,43 @@
   /// automatically.
   bool willExit = false;
 
+  StreamSubscription _pluginChangeSubscription;
+
   /// Initialize a newly created server to send and receive messages to the
   /// given [channel].
   LspAnalysisServer(
     this.channel,
     ResourceProvider baseResourceProvider,
     AnalysisServerOptions options,
-    this.sdkManager,
+    DartSdkManager sdkManager,
     CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
-    this.instrumentationService, {
+    InstrumentationService instrumentationService, {
     DiagnosticServer diagnosticServer,
-  }) : super(options, diagnosticServer, crashReportingAttachmentsBuilder,
-            baseResourceProvider) {
+  }) : super(
+          options,
+          sdkManager,
+          diagnosticServer,
+          crashReportingAttachmentsBuilder,
+          baseResourceProvider,
+          instrumentationService,
+          NotificationManager(
+            const NoOpServerCommunicationChannel(),
+            baseResourceProvider.pathContext,
+          ),
+        ) {
     messageHandler = UninitializedStateMessageHandler(this);
-    // TODO(dantup): This code is almost identical to AnalysisServer, consider
-    // moving it the base class that already holds many of these fields.
-    defaultContextOptions.generateImplicitErrors = false;
-    defaultContextOptions.useFastaParser = options.useFastaParser;
+    capabilitiesComputer = ServerCapabilitiesComputer(this);
 
-    {
-      var name = options.newAnalysisDriverLog;
-      StringSink sink = NullStringSink();
-      if (name != null) {
-        if (name == 'stdout') {
-          sink = io.stdout;
-        } else if (name.startsWith('file:')) {
-          var path = name.substring('file:'.length);
-          sink = io.File(path).openWrite(mode: io.FileMode.append);
-        }
-      }
-      _analysisPerformanceLogger = PerformanceLog(sink);
-    }
-    byteStore = createByteStore(resourceProvider);
-    analysisDriverScheduler =
-        nd.AnalysisDriverScheduler(_analysisPerformanceLogger);
-    analysisDriverScheduler.status.listen(sendStatusNotification);
-    analysisDriverScheduler.start();
-
-    if (options.featureSet.completion) {
-      declarationsTracker = DeclarationsTracker(byteStore, resourceProvider);
-      declarationsTrackerData = DeclarationsTrackerData(declarationsTracker);
-      analysisDriverScheduler.outOfBandWorker =
-          CompletionLibrariesWorker(declarationsTracker);
-    }
-
-    contextManager = ContextManagerImpl(resourceProvider, sdkManager,
-        analyzedFilesGlobs, instrumentationService, defaultContextOptions);
     final contextManagerCallbacks =
         LspServerContextManagerCallbacks(this, resourceProvider);
     contextManager.callbacks = contextManagerCallbacks;
-    searchEngine = SearchEngineImpl(driverMap.values);
+
+    analysisDriverScheduler.status.listen(sendStatusNotification);
+    analysisDriverScheduler.start();
 
     channel.listen(handleMessage, onDone: done, onError: socketError);
+    _pluginChangeSubscription =
+        pluginManager.pluginsChanged.listen((_) => _onPluginsChanged());
   }
 
   /// The capabilities of the LSP client. Will be null prior to initialization.
@@ -175,6 +141,16 @@
   /// specific server functionality. Will be null prior to initialization.
   LspInitializationOptions get initializationOptions => _initializationOptions;
 
+  @override
+  set pluginManager(PluginManager value) {
+    // we exchange the plugin manager in tests
+    super.pluginManager = value;
+    _pluginChangeSubscription?.cancel();
+
+    _pluginChangeSubscription =
+        pluginManager.pluginsChanged.listen((_) => _onPluginsChanged());
+  }
+
   RefactoringWorkspace get refactoringWorkspace => _refactoringWorkspace ??=
       RefactoringWorkspace(driverMap.values, searchEngine);
 
@@ -182,7 +158,7 @@
     final didAdd = priorityFiles.add(path);
     assert(didAdd);
     if (didAdd) {
-      _updateDriversPriorityFiles();
+      _updateDriversAndPluginsPriorityFiles();
     }
   }
 
@@ -193,10 +169,6 @@
   /// analyzed in one of the analysis drivers to which the file was added,
   /// otherwise in the first driver, otherwise `null` is returned.
   LineInfo getLineInfo(String path) {
-    if (!AnalysisEngine.isDartFileName(path)) {
-      return null;
-    }
-
     return getAnalysisDriver(path)?.getFileSync(path)?.lineInfo;
   }
 
@@ -367,7 +339,7 @@
     final didRemove = priorityFiles.remove(path);
     assert(didRemove);
     if (didRemove) {
-      _updateDriversPriorityFiles();
+      _updateDriversAndPluginsPriorityFiles();
     }
   }
 
@@ -450,6 +422,7 @@
     declarationsTracker?.discardContexts();
     final uniquePaths = HashSet<String>.of(includedPaths ?? const []);
     contextManager.setRoots(uniquePaths.toList(), [], {});
+    notificationManager.setAnalysisRoots(includedPaths, []);
     addContextsToDeclarationsTracker();
   }
 
@@ -509,6 +482,7 @@
     Future(() {
       channel.close();
     });
+    _pluginChangeSubscription?.cancel();
 
     return Future.value();
   }
@@ -543,9 +517,32 @@
     notifyFlutterWidgetDescriptions(path);
   }
 
-  void _updateDriversPriorityFiles() {
+  void _onPluginsChanged() {
+    capabilitiesComputer.performDynamicRegistration();
+  }
+
+  void _updateDriversAndPluginsPriorityFiles() {
+    final priorityFilesList = priorityFiles.toList();
     driverMap.values.forEach((driver) {
-      driver.priorityFiles = priorityFiles.toList();
+      driver.priorityFiles = priorityFilesList;
+    });
+
+    final pluginPriorities =
+        plugin.AnalysisSetPriorityFilesParams(priorityFilesList);
+    pluginManager.setAnalysisSetPriorityFilesParams(pluginPriorities);
+
+    // Plugins send most of their analysis results via notifications, but with
+    // LSP we're supposed to have them available per request. Assume that we'll
+    // only receive requests for files that are currently open.
+    final pluginSubscriptions = plugin.AnalysisSetSubscriptionsParams({
+      for (final service in plugin.AnalysisService.VALUES)
+        service: priorityFilesList,
+    });
+    pluginManager.setAnalysisSetSubscriptionsParams(pluginSubscriptions);
+
+    notificationManager.setSubscriptions({
+      for (final service in protocol.AnalysisService.VALUES)
+        service: priorityFiles
     });
   }
 }
@@ -673,7 +670,7 @@
   void broadcastWatchEvent(WatchEvent event) {
     analysisServer.notifyDeclarationsTracker(event.path);
     analysisServer.notifyFlutterWidgetDescriptions(event.path);
-    // TODO: implement plugin broadcastWatchEvent
+    analysisServer.pluginManager.broadcastWatchEvent(event);
   }
 
   @override
@@ -701,7 +698,7 @@
         resourceProvider, analysisServer.sdkManager, null,
         options: builderOptions);
     builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler;
-    builder.performanceLog = analysisServer._analysisPerformanceLogger;
+    builder.performanceLog = analysisServer.analysisPerformanceLogger;
     builder.byteStore = analysisServer.byteStore;
     builder.enableIndex = true;
     return builder;
@@ -717,7 +714,19 @@
   }
 }
 
-class NullNotificationManager implements NotificationManager {
+class NoOpServerCommunicationChannel implements ServerCommunicationChannel {
+  const NoOpServerCommunicationChannel();
+
   @override
-  dynamic noSuchMethod(Invocation invocation) {}
+  void close() {}
+
+  @override
+  void listen(void Function(protocol.Request request) onRequest,
+      {Function onError, void Function() onDone}) {}
+
+  @override
+  void sendNotification(protocol.Notification notification) {}
+
+  @override
+  void sendResponse(protocol.Response response) {}
 }
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index ab35b3f..00efe02 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -605,6 +605,20 @@
     lsp.ClosingLabel(
         toRange(lineInfo, label.offset, label.length), label.label);
 
+CodeActionKind toCodeActionKind(String id, lsp.CodeActionKind fallback) {
+  if (id == null) {
+    return fallback;
+  }
+  // Dart fixes and assists start with "dart.assist." and "dart.fix." but in LSP
+  // we want to use the predefined prefixes for CodeActions.
+  final newId = id
+      .replaceAll('dart.assist', CodeActionKind.Refactor.toString())
+      .replaceAll('dart.fix', CodeActionKind.QuickFix.toString())
+      .replaceAll('analysisOptions.assist', CodeActionKind.Refactor.toString())
+      .replaceAll('analysisOptions.fix', CodeActionKind.QuickFix.toString());
+  return CodeActionKind(newId);
+}
+
 lsp.CompletionItem toCompletionItem(
   lsp.TextDocumentClientCapabilitiesCompletion completionCapabilities,
   HashSet<lsp.CompletionItemKind> supportedCompletionItemKinds,
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
new file mode 100644
index 0000000..a359d36
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -0,0 +1,371 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+/// Helper for reading client dynamic registrations which may be ommitted by the
+/// client.
+class ClientDynamicRegistrations {
+  /// All dynamic registrations supported by the Dart LSP server.
+  ///
+  /// Anything listed here and supported by the client will not send a static
+  /// registration but intead dynamically register (usually only for a subset of
+  /// files such as for .dart/pubspec.yaml/etc).
+  ///
+  /// When adding new capabilities that will be registered dynamically, the
+  /// test_dynamicRegistration_XXX tests in `lsp/initialization_test.dart` should
+  /// also be updated to ensure no double-registrations.
+  static const supported = [
+    Method.textDocument_didOpen,
+    Method.textDocument_didChange,
+    Method.textDocument_didClose,
+    Method.textDocument_completion,
+    Method.textDocument_hover,
+    Method.textDocument_signatureHelp,
+    Method.textDocument_references,
+    Method.textDocument_documentHighlight,
+    Method.textDocument_formatting,
+    Method.textDocument_onTypeFormatting,
+    Method.textDocument_definition,
+    Method.textDocument_codeAction,
+    Method.textDocument_rename,
+    Method.textDocument_foldingRange,
+  ];
+  final ClientCapabilities _capabilities;
+
+  ClientDynamicRegistrations(this._capabilities);
+
+  bool get codeActions =>
+      _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
+
+  bool get completion =>
+      _capabilities.textDocument?.completion?.dynamicRegistration ?? false;
+
+  bool get definition =>
+      _capabilities.textDocument?.definition?.dynamicRegistration ?? false;
+
+  bool get documentHighlights =>
+      _capabilities.textDocument?.documentHighlight?.dynamicRegistration ??
+      false;
+
+  bool get documentSymbol =>
+      _capabilities.textDocument?.documentSymbol?.dynamicRegistration ?? false;
+
+  bool get folding =>
+      _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
+
+  bool get formatting =>
+      _capabilities.textDocument?.formatting?.dynamicRegistration ?? false;
+
+  bool get hover =>
+      _capabilities.textDocument?.hover?.dynamicRegistration ?? false;
+
+  bool get implementation =>
+      _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
+
+  bool get references =>
+      _capabilities.textDocument?.references?.dynamicRegistration ?? false;
+
+  bool get rename =>
+      _capabilities.textDocument?.rename?.dynamicRegistration ?? false;
+
+  bool get signatureHelp =>
+      _capabilities.textDocument?.signatureHelp?.dynamicRegistration ?? false;
+
+  bool get textSync =>
+      _capabilities.textDocument?.synchronization?.dynamicRegistration ?? false;
+
+  bool get typeFormatting =>
+      _capabilities.textDocument?.onTypeFormatting?.dynamicRegistration ??
+      false;
+}
+
+class ServerCapabilitiesComputer {
+  final LspAnalysisServer _server;
+
+  /// Map from method name to current registration data.
+  Map<String, Registration> _currentRegistrations = {};
+  var _lastRegistrationId = 0;
+
+  ServerCapabilitiesComputer(this._server);
+
+  ServerCapabilities computeServerCapabilities(
+      ClientCapabilities clientCapabilities) {
+    final codeActionLiteralSupport =
+        clientCapabilities.textDocument?.codeAction?.codeActionLiteralSupport;
+
+    final renameOptionsSupport =
+        clientCapabilities.textDocument?.rename?.prepareSupport ?? false;
+
+    final dynamicRegistrations = ClientDynamicRegistrations(clientCapabilities);
+
+    // When adding new capabilities to the server that may apply to specific file
+    // types, it's important to update
+    // [IntializedMessageHandler._performDynamicRegistration()] to notify
+    // supporting clients of this. This avoids clients needing to hard-code the
+    // list of what files types we support (and allows them to avoid sending
+    // requests where we have only partial support for some types).
+    return ServerCapabilities(
+        dynamicRegistrations.textSync
+            ? null
+            : Either2<TextDocumentSyncOptions, num>.t1(TextDocumentSyncOptions(
+                // The open/close and sync kind flags are registered dynamically if the
+                // client supports them, so these static registrations are based on whether
+                // the client supports dynamic registration.
+                true,
+                TextDocumentSyncKind.Incremental,
+                false,
+                false,
+                null,
+              )),
+        dynamicRegistrations.hover ? null : true, // hoverProvider
+        dynamicRegistrations.completion
+            ? null
+            : CompletionOptions(
+                true, // resolveProvider
+                dartCompletionTriggerCharacters,
+              ),
+        dynamicRegistrations.signatureHelp
+            ? null
+            : SignatureHelpOptions(
+                dartSignatureHelpTriggerCharacters,
+              ),
+        dynamicRegistrations.definition ? null : true, // definitionProvider
+        null,
+        dynamicRegistrations.implementation
+            ? null
+            : true, // implementationProvider
+        dynamicRegistrations.references ? null : true, // referencesProvider
+        dynamicRegistrations.documentHighlights
+            ? null
+            : true, // documentHighlightProvider
+        dynamicRegistrations.documentSymbol
+            ? null
+            : true, // documentSymbolProvider
+        true, // workspaceSymbolProvider
+        // "The `CodeActionOptions` return type is only valid if the client
+        // signals code action literal support via the property
+        // `textDocument.codeAction.codeActionLiteralSupport`."
+        dynamicRegistrations.codeActions
+            ? null
+            : codeActionLiteralSupport != null
+                ? Either2<bool, CodeActionOptions>.t2(
+                    CodeActionOptions(DartCodeActionKind.serverSupportedKinds))
+                : Either2<bool, CodeActionOptions>.t1(true),
+        null,
+        dynamicRegistrations.formatting
+            ? null
+            : true, // documentFormattingProvider
+        false, // documentRangeFormattingProvider
+        dynamicRegistrations.typeFormatting
+            ? null
+            : DocumentOnTypeFormattingOptions(
+                dartTypeFormattingCharacters.first,
+                dartTypeFormattingCharacters.skip(1).toList()),
+        dynamicRegistrations.rename
+            ? null
+            : renameOptionsSupport
+                ? Either2<bool, RenameOptions>.t2(RenameOptions(true))
+                : Either2<bool, RenameOptions>.t1(true),
+        null,
+        null,
+        dynamicRegistrations.folding ? null : true, // foldingRangeProvider
+        null, // declarationProvider
+        ExecuteCommandOptions(Commands.serverSupportedCommands),
+        ServerCapabilitiesWorkspace(
+            ServerCapabilitiesWorkspaceFolders(true, true)),
+        null);
+  }
+
+  /// If the client supports dynamic registrations we can tell it what methods
+  /// we support for which documents. For example, this allows us to ask for
+  /// file edits for .dart as well as pubspec.yaml but only get hover/completion
+  /// calls for .dart. This functionality may not be supported by the client, in
+  /// which case they will use the ServerCapabilities to know which methods we
+  /// support and it will be up to them to decide which file types they will
+  /// send requests for.
+  Future<void> performDynamicRegistration() async {
+    final dartFiles = DocumentFilter('dart', 'file', null);
+    final pubspecFile = DocumentFilter('yaml', 'file', '**/pubspec.yaml');
+    final analysisOptionsFile =
+        DocumentFilter('yaml', 'file', '**/analysis_options.yaml');
+
+    final pluginTypes = _server.pluginManager.plugins
+        .expand((plugin) => plugin.currentSession?.interestingFiles ?? const [])
+        // All published plugins use something like `*.extension` as
+        // interestingFiles. Prefix a `**/` so that the glob matches nested
+        // folders as well.
+        .map((glob) => DocumentFilter(null, 'file', '**/$glob'));
+
+    final allTypes = [
+      dartFiles,
+      pubspecFile,
+      analysisOptionsFile,
+      ...pluginTypes
+    ];
+
+    final registrations = <Registration>[];
+
+    /// Helper for creating registrations with IDs.
+    void register(bool condition, Method method, [ToJsonable options]) {
+      if (condition == true) {
+        registrations.add(Registration(
+            (_lastRegistrationId++).toString(), method.toJson(), options));
+      }
+    }
+
+    final textCapabilities = _server.clientCapabilities?.textDocument;
+
+    register(
+      textCapabilities?.synchronization?.dynamicRegistration,
+      Method.textDocument_didOpen,
+      TextDocumentRegistrationOptions(allTypes),
+    );
+    register(
+      textCapabilities?.synchronization?.dynamicRegistration,
+      Method.textDocument_didClose,
+      TextDocumentRegistrationOptions(allTypes),
+    );
+    register(
+      textCapabilities?.synchronization?.dynamicRegistration,
+      Method.textDocument_didChange,
+      TextDocumentChangeRegistrationOptions(
+          TextDocumentSyncKind.Incremental, allTypes),
+    );
+    register(
+      _server.clientCapabilities?.textDocument?.completion?.dynamicRegistration,
+      Method.textDocument_completion,
+      CompletionRegistrationOptions(
+        dartCompletionTriggerCharacters,
+        null,
+        true,
+        [dartFiles],
+      ),
+    );
+    register(
+      textCapabilities?.hover?.dynamicRegistration,
+      Method.textDocument_hover,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      textCapabilities?.signatureHelp?.dynamicRegistration,
+      Method.textDocument_signatureHelp,
+      SignatureHelpRegistrationOptions(
+          dartSignatureHelpTriggerCharacters, [dartFiles]),
+    );
+    register(
+      _server.clientCapabilities?.textDocument?.references?.dynamicRegistration,
+      Method.textDocument_references,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      textCapabilities?.documentHighlight?.dynamicRegistration,
+      Method.textDocument_documentHighlight,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      textCapabilities?.documentSymbol?.dynamicRegistration,
+      Method.textDocument_documentSymbol,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      _server.clientCapabilities?.textDocument?.formatting?.dynamicRegistration,
+      Method.textDocument_formatting,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      textCapabilities?.onTypeFormatting?.dynamicRegistration,
+      Method.textDocument_onTypeFormatting,
+      DocumentOnTypeFormattingRegistrationOptions(
+        dartTypeFormattingCharacters.first,
+        dartTypeFormattingCharacters.skip(1).toList(),
+        [dartFiles],
+      ),
+    );
+    register(
+      _server.clientCapabilities?.textDocument?.definition?.dynamicRegistration,
+      Method.textDocument_definition,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      textCapabilities?.implementation?.dynamicRegistration,
+      Method.textDocument_implementation,
+      TextDocumentRegistrationOptions([dartFiles]),
+    );
+    register(
+      _server.clientCapabilities?.textDocument?.codeAction?.dynamicRegistration,
+      Method.textDocument_codeAction,
+      CodeActionRegistrationOptions(
+          [dartFiles], DartCodeActionKind.serverSupportedKinds),
+    );
+    register(
+      textCapabilities?.rename?.dynamicRegistration,
+      Method.textDocument_rename,
+      RenameRegistrationOptions(true, [dartFiles]),
+    );
+    register(
+      textCapabilities?.foldingRange?.dynamicRegistration,
+      Method.textDocument_foldingRange,
+      TextDocumentRegistrationOptions(allTypes),
+    );
+
+    await _applyRegistrations(registrations);
+  }
+
+  Future<void> _applyRegistrations(List<Registration> registrations) async {
+    final newRegistrationsByMethod = {
+      for (final registration in registrations)
+        registration.method: registration
+    };
+
+    final additionalRegistrations = List.of(registrations);
+    final removedRegistrations = <Unregistration>[];
+
+    // compute a diff of old and new registrations to send the unregister or
+    // another register request. We assume that we'll only ever have one
+    // registration per LSP method name.
+    for (final entry in _currentRegistrations.entries) {
+      final method = entry.key;
+      final registration = entry.value;
+
+      final newRegistrationForMethod = newRegistrationsByMethod[method];
+      final entryRemovedOrChanged = newRegistrationForMethod?.registerOptions !=
+          registration.registerOptions;
+
+      if (entryRemovedOrChanged) {
+        removedRegistrations
+            .add(Unregistration(registration.id, registration.method));
+      } else {
+        additionalRegistrations.remove(newRegistrationForMethod);
+      }
+    }
+
+    _currentRegistrations = newRegistrationsByMethod;
+
+    if (removedRegistrations.isNotEmpty) {
+      await _server.sendRequest(Method.client_unregisterCapability,
+          UnregistrationParams(removedRegistrations));
+    }
+
+    // Only send the registration request if we have at least one (since
+    // otherwise we don't know that the client supports registerCapability).
+    if (additionalRegistrations.isNotEmpty) {
+      final registrationResponse = await _server.sendRequest(
+        Method.client_registerCapability,
+        RegistrationParams(additionalRegistrations),
+      );
+
+      if (registrationResponse.error != null) {
+        _server.logErrorToClient(
+          'Failed to register capabilities with client: '
+          '(${registrationResponse.error.code}) '
+          '${registrationResponse.error.message}',
+        );
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 9a0fadc..7890009 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -21,8 +21,6 @@
 
 Future<void> scheduleImplementedNotification(
     AnalysisServer server, Iterable<String> files) async {
-  // TODO(brianwilkerson) Determine whether this await is necessary.
-  await null;
   var searchEngine = server.searchEngine;
   if (searchEngine == null) {
     return;
diff --git a/pkg/analysis_server/lib/src/plugin/notification_manager.dart b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
index b1a4b44..c7987a2 100644
--- a/pkg/analysis_server/lib/src/plugin/notification_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
@@ -9,11 +9,11 @@
 import 'package:analysis_server/src/plugin/result_collector.dart';
 import 'package:analysis_server/src/plugin/result_converter.dart';
 import 'package:analysis_server/src/plugin/result_merger.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:path/path.dart';
 
 /// The object used to coordinate the results of notifications from the analysis
 /// server and multiple plugins.
@@ -24,8 +24,8 @@
   /// The channel used to send notifications to the client.
   final ServerCommunicationChannel channel;
 
-  /// The resource provider used to get the path context.
-  final ResourceProvider provider;
+  /// The path context.
+  final Context pathContext;
 
   /// A list of the paths of files and directories that are included for
   /// analysis.
@@ -66,7 +66,7 @@
   final ResultMerger merger = ResultMerger();
 
   /// Initialize a newly created notification manager.
-  NotificationManager(this.channel, this.provider) {
+  NotificationManager(this.channel, this.pathContext) {
     errors =
         ResultCollector<List<AnalysisError>>(serverId, predicate: _isIncluded);
     folding = ResultCollector<List<FoldingRegion>>(serverId);
@@ -277,8 +277,8 @@
   bool _isIncluded(String path) {
     bool isIncluded() {
       for (var includedPath in includedPaths) {
-        if (provider.pathContext.isWithin(includedPath, path) ||
-            provider.pathContext.equals(includedPath, path)) {
+        if (pathContext.isWithin(includedPath, path) ||
+            pathContext.equals(includedPath, path)) {
           return true;
         }
       }
@@ -287,7 +287,7 @@
 
     bool isExcluded() {
       for (var excludedPath in excludedPaths) {
-        if (provider.pathContext.isWithin(excludedPath, path)) {
+        if (pathContext.isWithin(excludedPath, path)) {
           return true;
         }
       }
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index de68843..785e77b 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -195,8 +195,6 @@
   /// used to interact with the plugin, or `null` if the plugin could not be
   /// run.
   Future<PluginSession> start(String byteStorePath, String sdkPath) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (currentSession != null) {
       throw StateError('Cannot start a plugin that is already running.');
     }
@@ -281,6 +279,8 @@
   /// plugin has been started.
   final Map<String, dynamic> _overlayState = <String, dynamic>{};
 
+  final StreamController<void> _pluginsChanged = StreamController.broadcast();
+
   /// Initialize a newly created plugin manager. The notifications from the
   /// running plugins will be handled by the given [notificationManager].
   PluginManager(this.resourceProvider, this.byteStorePath, this.sdkPath,
@@ -289,13 +289,14 @@
   /// Return a list of all of the plugins that are currently known.
   List<PluginInfo> get plugins => _pluginMap.values.toList();
 
+  /// Stream emitting an event when known [plugins] change.
+  Stream<void> get pluginsChanged => _pluginsChanged.stream;
+
   /// Add the plugin with the given [path] to the list of plugins that should be
   /// used when analyzing code for the given [contextRoot]. If the plugin had
   /// not yet been started, then it will be started by this method.
   Future<void> addPluginToContextRoot(
       analyzer.ContextRoot contextRoot, String path) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var plugin = _pluginMap[path];
     var isNew = plugin == null;
     if (isNew) {
@@ -317,6 +318,7 @@
           var session = await plugin.start(byteStorePath, sdkPath);
           session?.onDone?.then((_) {
             _pluginMap.remove(path);
+            _notifyPluginsChanged();
           });
         } catch (exception, stackTrace) {
           // Record the exception (for debugging purposes) and record the fact
@@ -325,6 +327,8 @@
           isNew = false;
         }
       }
+
+      _notifyPluginsChanged();
     }
     plugin.addContextRoot(contextRoot);
     if (isNew) {
@@ -364,8 +368,6 @@
   /// response.
   Future<List<Future<Response>>> broadcastWatchEvent(
       watcher.WatchEvent watchEvent) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var filePath = watchEvent.path;
 
     /// Return `true` if the given glob [pattern] matches the file being
@@ -469,6 +471,7 @@
       plugin.removeContextRoot(contextRoot);
       if (plugin is DiscoveredPluginInfo && plugin.contextRoots.isEmpty) {
         _pluginMap.remove(plugin.path);
+        _notifyPluginsChanged();
         try {
           plugin.stop();
         } catch (e, st) {
@@ -481,8 +484,6 @@
 
   /// Restart all currently running plugins.
   Future<void> restartPlugins() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     for (var plugin in _pluginMap.values.toList()) {
       if (plugin.currentSession != null) {
         //
@@ -708,6 +709,8 @@
     return packagesFile;
   }
 
+  void _notifyPluginsChanged() => _pluginsChanged.add(null);
+
   /// Return the names of packages that are listed as dependencies in the given
   /// [pubspecFile].
   Iterable<String> _readDependecies(File pubspecFile) {
@@ -893,8 +896,6 @@
   /// the given [byteStorePath]. Return `true` if the plugin is compatible and
   /// running.
   Future<bool> start(String byteStorePath, String sdkPath) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (channel != null) {
       throw StateError('Cannot start a plugin that is already running.');
     }
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 5e20c2b..cf04772 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
@@ -6,10 +6,12 @@
 
 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';
 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/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -22,8 +24,10 @@
 abstract class DartCompletionContributor {
   /// Return a [Future] that completes with a list of suggestions
   /// for the given completion [request].
+  // TODO(brianwilkerson) When all of the suggestions are being built using the
+  //  builder, change the return type to `Future<void>`.
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request);
+      DartCompletionRequest request, SuggestionBuilder builder);
 }
 
 /// The information about a requested list of completions within a Dart file.
@@ -34,6 +38,9 @@
   /// context, or `null` if the context does not impose any type.
   DartType get contextType;
 
+  /// Return the object used to resolve macros in Dartdoc comments.
+  DartdocDirectiveInfo get dartdocDirectiveInfo;
+
   /// Return the expression to the right of the "dot" or "dot dot",
   /// or `null` if this is not a "dot" completion (e.g. `foo.b`).
   Expression get dotTarget;
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 4b34793..ba332d9 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -19,8 +19,6 @@
   /// Computes [SearchResult]s for [element] references.
   Future<List<SearchResult>> compute(
       Element element, bool withPotential) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var results = <SearchResult>[];
 
     // Add element references.
@@ -40,8 +38,6 @@
   /// Returns a [Future] completing with a [List] of references to [element] or
   /// to the corresponding hierarchy [Element]s.
   Future<List<SearchResult>> _findElementsReferences(Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allResults = <SearchResult>[];
     var refElements = await _getRefElements(element);
     for (var refElement in refElements) {
@@ -54,8 +50,6 @@
   /// Returns a [Future] completing with a [List] of references to [element].
   Future<List<SearchResult>> _findSingleElementReferences(
       Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var matches = await searchEngine.searchReferences(element);
     matches = SearchMatch.withNotNullElement(matches);
     return matches.map(toResult).toList();
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 5ddaa75..e3ad323 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -32,8 +32,6 @@
         searchEngine = server.searchEngine;
 
   Future findElementReferences(protocol.Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params =
         protocol.SearchFindElementReferencesParams.fromRequest(request);
     var file = params.file;
@@ -65,8 +63,6 @@
   }
 
   Future findMemberDeclarations(protocol.Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params =
         protocol.SearchFindMemberDeclarationsParams.fromRequest(request);
     await server.onAnalysisComplete;
@@ -81,8 +77,6 @@
   }
 
   Future findMemberReferences(protocol.Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = protocol.SearchFindMemberReferencesParams.fromRequest(request);
     await server.onAnalysisComplete;
     // respond
@@ -96,8 +90,6 @@
   }
 
   Future findTopLevelDeclarations(protocol.Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params =
         protocol.SearchFindTopLevelDeclarationsParams.fromRequest(request);
     try {
@@ -122,8 +114,6 @@
 
   /// Implement the `search.getDeclarations` request.
   Future getDeclarations(protocol.Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params =
         protocol.SearchGetElementDeclarationsParams.fromRequest(request);
 
@@ -203,8 +193,6 @@
 
   /// Implement the `search.getTypeHierarchy` request.
   Future getTypeHierarchy(protocol.Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var params = protocol.SearchGetTypeHierarchyParams.fromRequest(request);
     var file = params.file;
     // prepare element
diff --git a/pkg/analysis_server/lib/src/server/crash_reporting.dart b/pkg/analysis_server/lib/src/server/crash_reporting.dart
index 879adbc..866b9ff 100644
--- a/pkg/analysis_server/lib/src/server/crash_reporting.dart
+++ b/pkg/analysis_server/lib/src/server/crash_reporting.dart
@@ -8,10 +8,20 @@
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:telemetry/crash_reporting.dart';
 
-class CrashReportingInstrumentation extends NoopInstrumentationService {
-  final CrashReportSender reporter;
+const _angularPluginName = 'Angular Analysis Plugin';
 
-  CrashReportingInstrumentation(this.reporter);
+class CrashReportingInstrumentation extends NoopInstrumentationService {
+  // A staging reporter, that we are in the process of phasing out.
+  final CrashReportSender stagingReporter;
+
+  // A prod reporter, that we are in the process of phasing in.
+  final CrashReportSender prodReporter;
+
+  // The angular plugin crash reporter.
+  final CrashReportSender angularReporter;
+
+  CrashReportingInstrumentation(
+      this.stagingReporter, this.prodReporter, this.angularReporter);
 
   @override
   void logException(dynamic exception,
@@ -28,19 +38,11 @@
       // Get the root CaughtException, which matters most for debugging.
       var root = exception.rootCaughtException;
 
-      reporter
-          .sendReport(root.exception, root.stackTrace,
-              attachments: crashReportAttachments, comment: root.message)
-          .catchError((error) {
-        // We silently ignore errors sending crash reports (network issues, ...).
-      });
+      _sendServerReport(root.exception, root.stackTrace,
+          attachments: crashReportAttachments, comment: root.message);
     } else {
-      reporter
-          .sendReport(exception, stackTrace ?? StackTrace.current,
-              attachments: crashReportAttachments)
-          .catchError((error) {
-        // We silently ignore errors sending crash reports (network issues, ...).
-      });
+      _sendServerReport(exception, stackTrace ?? StackTrace.current,
+          attachments: crashReportAttachments);
     }
   }
 
@@ -50,15 +52,27 @@
     dynamic exception,
     StackTrace stackTrace,
   ) {
-    // TODO(devoncarew): Temporarily disabled; re-enable after deciding on a
-    // plan of action for the AngularDart analysis plugin.
-    const angularPluginName = 'Angular Analysis Plugin';
-    if (plugin.name == angularPluginName) {
-      return;
+    if (plugin.name == _angularPluginName) {
+      angularReporter.sendReport(exception, stackTrace).catchError((error) {
+        // We silently ignore errors sending crash reports (network issues, ...).
+      });
+    } else {
+      _sendServerReport(exception, stackTrace,
+          comment: 'plugin: ${plugin.name}');
     }
+  }
 
-    reporter
-        .sendReport(exception, stackTrace, comment: 'plugin: ${plugin.name}')
+  void _sendServerReport(Object exception, Object stackTrace,
+      {String comment, List<CrashReportAttachment> attachments}) {
+    stagingReporter
+        .sendReport(exception, stackTrace,
+            attachments: attachments, comment: comment)
+        .catchError((error) {
+      // We silently ignore errors sending crash reports (network issues, ...).
+    });
+    prodReporter
+        .sendReport(exception, stackTrace,
+            attachments: attachments, comment: comment)
         .catchError((error) {
       // We silently ignore errors sending crash reports (network issues, ...).
     });
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 3d14a00..54245c7 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -403,8 +403,13 @@
 
     // Use sdkConfig to optionally override analytics settings.
     final crashProductId = sdkConfig.crashReportingId ?? 'Dart_analysis_server';
-    final crashReportSender =
-        CrashReportSender(crashProductId, shouldSendCallback);
+    final crashReportSenderStaging =
+        CrashReportSender.staging(crashProductId, shouldSendCallback);
+    final crashReportSenderProd =
+        CrashReportSender.prod(crashProductId, shouldSendCallback);
+    // TODO(mfairhurst): send these to prod or disable.
+    final crashReportSenderAngular = CrashReportSender.staging(
+        'Dart_angular_analysis_plugin', shouldSendCallback);
 
     if (telemetry.SHOW_ANALYTICS_UI) {
       if (results.wasParsed(ANALYTICS_FLAG)) {
@@ -455,8 +460,10 @@
     }
 
     var errorNotifier = ErrorNotifier();
-    allInstrumentationServices
-        .add(CrashReportingInstrumentation(crashReportSender));
+    allInstrumentationServices.add(CrashReportingInstrumentation(
+        crashReportSenderStaging,
+        crashReportSenderProd,
+        crashReportSenderAngular));
     instrumentationService =
         MulticastInstrumentationService(allInstrumentationServices);
 
@@ -613,9 +620,6 @@
           serveResult = isolateAnalysisServer.serveIsolate(sendPort);
         }
         serveResult.then((_) async {
-          // TODO(brianwilkerson) Determine whether this await is necessary.
-          await null;
-
           if (serve_http) {
             httpServer.close();
           }
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index b1d8d36..394cb9a 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -41,8 +41,6 @@
 
   /// Return the port this server is bound to.
   Future<int> get boundPort async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return (await _serverFuture)?.port;
   }
 
@@ -63,8 +61,6 @@
 
   /// Begin serving HTTP requests over the given port.
   Future<int> serveHttp([int initialPort]) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (_serverFuture != null) {
       return boundPort;
     }
@@ -87,8 +83,6 @@
 
   /// Handle a GET request received by the HTTP server.
   Future<void> _handleGetRequest(HttpRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     getHandler ??= DiagnosticsSite(socketServer, _printBuffer);
     // TODO(brianwilkerson) Determine if await is necessary, if so, change the
     // return type of [AbstractGetHandler.handleGetRequest] to `Future<void>`.
@@ -98,8 +92,6 @@
   /// Attach a listener to a newly created HTTP server.
   void _handleServer(HttpServer httpServer) {
     httpServer.listen((HttpRequest request) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       var updateValues = request.headers[HttpHeaders.upgradeHeader];
       if (request.method == 'GET') {
         await _handleGetRequest(request);
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 23e8240..29c8cda 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
@@ -4,9 +4,11 @@
 
 import 'dart:async';
 
+import 'package:analysis_server/src/computer/computer_hover.dart';
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
 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/completion/dart/utilities.dart';
 import 'package:analysis_server/src/utilities/flutter.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -32,7 +34,7 @@
 
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var executable = request.target.executableElement;
     if (executable == null) {
       return const <CompletionSuggestion>[];
@@ -72,6 +74,7 @@
       var selectionOffset = completion.length;
 
       // Optionally add Flutter child widget details.
+      // todo (pq): revisit this special casing; likely it can be generalized away
       var element = parameter.enclosingElement;
       if (element is ConstructorElement) {
         var flutter = Flutter.of(request.result);
@@ -79,7 +82,7 @@
           var defaultValue = getDefaultStringParameterValue(parameter);
           // TODO(devoncarew): Should we remove the check here? We would then
           // suggest values for param types like closures.
-          if (defaultValue != null && defaultValue.text == '<Widget>[]') {
+          if (defaultValue != null && defaultValue.text == '[]') {
             var completionLength = completion.length;
             completion += defaultValue.text;
             if (defaultValue.cursorPosition != null) {
@@ -115,7 +118,7 @@
           parameterName: name,
           parameterType: type);
       if (parameter is FieldFormalParameterElement) {
-        _setDocumentation(suggestion, parameter.field?.documentationComment);
+        _setDocumentation(suggestion, parameter);
         suggestion.element = convertElement(parameter);
       }
 
@@ -333,10 +336,10 @@
 
   /// If the given [comment] is not `null`, fill the [suggestion] documentation
   /// fields.
-  static void _setDocumentation(
-      CompletionSuggestion suggestion, String comment) {
-    if (comment != null) {
-      var doc = getDartDocPlainText(comment);
+  void _setDocumentation(CompletionSuggestion suggestion, Element element) {
+    var doc = DartUnitHoverComputer.computeDocumentation(
+        request.dartdocDirectiveInfo, element);
+    if (doc != null) {
       suggestion.docComplete = doc;
       suggestion.docSummary = getDartDocSummary(doc);
     }
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 6220845..b559a08 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
@@ -16,7 +16,7 @@
 class CombinatorContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var node = request.target.containingNode;
     if (node is! Combinator) {
       return const <CompletionSuggestion>[];
@@ -26,14 +26,35 @@
     if (directive is NamespaceDirective) {
       var library = directive.uriElement as LibraryElement;
       if (library != null) {
-        var builder = LibraryElementSuggestionBuilder(
-            request, CompletionSuggestionKind.IDENTIFIER, false, false);
+        var existingNames = _getCombinatorNames(directive);
         for (var element in library.exportNamespace.definedNames.values) {
-          element.accept(builder);
+          if (!existingNames.contains(element.name)) {
+            builder.suggestElement(element,
+                kind: CompletionSuggestionKind.IDENTIFIER);
+          }
         }
-        return builder.suggestions;
       }
     }
     return const <CompletionSuggestion>[];
   }
+
+  List<String> _getCombinatorNames(NamespaceDirective directive) {
+    var combinatorNameList = <String>[];
+    for (var combinator in directive.combinators) {
+      if (combinator is ShowCombinator) {
+        for (var simpleId in combinator.shownNames) {
+          if (!simpleId.isSynthetic) {
+            combinatorNameList.add(simpleId.name);
+          }
+        }
+      } else if (combinator is HideCombinator) {
+        for (var simpleId in combinator.hiddenNames) {
+          if (!simpleId.isSynthetic) {
+            combinatorNameList.add(simpleId.name);
+          }
+        }
+      }
+    }
+    return combinatorNameList;
+  }
 }
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 e2544fe..8a72ce7 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
@@ -30,6 +30,7 @@
 import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
@@ -43,6 +44,7 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -57,6 +59,9 @@
   /// to maintain state between calls to [DartContributionSorter#sort(...)].
   static DartContributionSorter contributionSorter = CommonUsageSorter();
 
+  /// The object used to resolve macros in Dartdoc comments.
+  final DartdocDirectiveInfo dartdocDirectiveInfo;
+
   /// If not `null`, then instead of using [ImportedReferenceContributor],
   /// fill this set with kinds of elements that are applicable at the
   /// completion location, so should be suggested from available suggestion
@@ -78,6 +83,7 @@
   /// [includedSuggestionRelevanceTags] must either all be `null` or must all be
   /// non-`null`.
   DartCompletionManager({
+    this.dartdocDirectiveInfo,
     this.includedElementKinds,
     this.includedElementNames,
     this.includedSuggestionRelevanceTags,
@@ -98,7 +104,7 @@
 
     var performance = (request as CompletionRequestImpl).performance;
     DartCompletionRequestImpl dartRequest =
-        await DartCompletionRequestImpl.from(request);
+        await DartCompletionRequestImpl.from(request, dartdocDirectiveInfo);
 
     // Don't suggest in comments.
     if (dartRequest.target.isCommentText) {
@@ -117,6 +123,7 @@
     // Request Dart specific completions from each contributor
     var suggestionMap = <String, CompletionSuggestion>{};
     var constructorMap = <String, List<String>>{};
+    var builder = SuggestionBuilder(dartRequest);
     var contributors = <DartCompletionContributor>[
       ArgListContributor(),
       CombinatorContributor(),
@@ -145,39 +152,48 @@
       contributors.add(ImportedReferenceContributor());
     }
 
+    void addSuggestionToMap(CompletionSuggestion newSuggestion) {
+      // TODO(brianwilkerson) After all contributors are using SuggestionBuilder
+      //  move this logic into SuggestionBuilder.
+      var key = newSuggestion.completion;
+
+      // Append parenthesis for constructors to disambiguate from classes.
+      if (_isConstructor(newSuggestion)) {
+        key += '()';
+        var className = _getConstructorClassName(newSuggestion);
+        _ensureList(constructorMap, className).add(key);
+      }
+
+      // Local declarations hide both the class and its constructors.
+      if (!_isClass(newSuggestion)) {
+        var constructorKeys = constructorMap[key];
+        constructorKeys?.forEach(suggestionMap.remove);
+      }
+
+      var oldSuggestion = suggestionMap[key];
+      if (oldSuggestion == null ||
+          oldSuggestion.relevance < newSuggestion.relevance) {
+        suggestionMap[key] = newSuggestion;
+      }
+    }
+
     try {
       for (var contributor in contributors) {
         var contributorTag =
             'DartCompletionManager - ${contributor.runtimeType}';
         performance.logStartTime(contributorTag);
         var contributorSuggestions =
-            await contributor.computeSuggestions(dartRequest);
+            await contributor.computeSuggestions(dartRequest, builder);
         performance.logElapseTime(contributorTag);
         request.checkAborted();
 
         for (var newSuggestion in contributorSuggestions) {
-          var key = newSuggestion.completion;
-
-          // Append parenthesis for constructors to disambiguate from classes.
-          if (_isConstructor(newSuggestion)) {
-            key += '()';
-            var className = _getConstructorClassName(newSuggestion);
-            _ensureList(constructorMap, className).add(key);
-          }
-
-          // Local declarations hide both the class and its constructors.
-          if (!_isClass(newSuggestion)) {
-            var constructorKeys = constructorMap[key];
-            constructorKeys?.forEach(suggestionMap.remove);
-          }
-
-          var oldSuggestion = suggestionMap[key];
-          if (oldSuggestion == null ||
-              oldSuggestion.relevance < newSuggestion.relevance) {
-            suggestionMap[key] = newSuggestion;
-          }
+          addSuggestionToMap(newSuggestion);
         }
       }
+      for (var newSuggestion in builder.suggestions) {
+        addSuggestionToMap(newSuggestion);
+      }
     } on InconsistentAnalysisException {
       // The state of the code being analyzed has changed, so results are likely
       // to be inconsistent. Just abort the operation.
@@ -372,6 +388,9 @@
   @override
   final FeatureComputer featureComputer;
 
+  @override
+  final DartdocDirectiveInfo dartdocDirectiveInfo;
+
   /// A flag indicating whether the [_contextType] has been computed.
   bool _hasComputedContextType = false;
 
@@ -390,6 +409,7 @@
       this.source,
       this.offset,
       CompilationUnit unit,
+      this.dartdocDirectiveInfo,
       this._originalRequest,
       this.performance)
       : featureComputer =
@@ -482,7 +502,8 @@
   /// Return a [Future] that completes with a newly created completion request
   /// based on the given [request]. This method will throw [AbortCompletion]
   /// if the completion request has been aborted.
-  static Future<DartCompletionRequest> from(CompletionRequest request) async {
+  static Future<DartCompletionRequest> from(CompletionRequest request,
+      DartdocDirectiveInfo dartdocDirectiveInfo) async {
     request.checkAborted();
     var performance = (request as CompletionRequestImpl).performance;
     const BUILD_REQUEST_TAG = 'build DartCompletionRequest';
@@ -500,6 +521,7 @@
         request.source,
         request.offset,
         unit,
+        dartdocDirectiveInfo,
         request,
         performance);
 
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 524ebf7..7f16627 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
@@ -12,20 +12,19 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/generic_inferrer.dart'
+    show GenericInferrer;
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/generated/resolver.dart'
-    show GenericInferrer, LibraryScope;
-import 'package:analyzer/src/generated/type_system.dart' show GenericInferrer;
 
 /// A contributor that produces suggestions based on the members of an
 /// extension.
 class ExtensionMemberContributor extends DartCompletionContributor {
-  MemberSuggestionBuilder builder;
+  MemberSuggestionBuilder memberBuilder;
 
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var containingLibrary = request.libraryElement;
     // Gracefully degrade if the library could not be determined, such as with a
     // detached part file or source change.
@@ -33,7 +32,7 @@
       return const <CompletionSuggestion>[];
     }
 
-    builder = MemberSuggestionBuilder(request);
+    memberBuilder = MemberSuggestionBuilder(request, builder);
 
     // Recompute the target because resolution might have changed it.
     var expression = request.dotTarget;
@@ -55,7 +54,7 @@
             for (var type in types) {
               double inheritanceDistance;
               if (request.useNewRelevance) {
-                inheritanceDistance = builder.request.featureComputer
+                inheritanceDistance = memberBuilder.request.featureComputer
                     .inheritanceDistanceFeature(
                         extendedType.element, type.element);
               }
@@ -65,7 +64,7 @@
         }
       }
 
-      return builder.suggestions.toList();
+      return const <CompletionSuggestion>[];
     }
 
     if (expression.isSynthetic) {
@@ -98,7 +97,7 @@
       _addExtensionMembers(containingLibrary, type);
       expression.staticType;
     }
-    return builder.suggestions.toList();
+    return const <CompletionSuggestion>[];
   }
 
   void _addExtensionMembers(LibraryElement containingLibrary, DartType type) {
@@ -109,8 +108,8 @@
           _resolveExtendedType(containingLibrary, extension, type);
       if (extendedType != null && typeSystem.isSubtypeOf(type, extendedType)) {
         double inheritanceDistance;
-        if (builder.request.useNewRelevance) {
-          inheritanceDistance = builder.request.featureComputer
+        if (memberBuilder.request.useNewRelevance) {
+          inheritanceDistance = memberBuilder.request.featureComputer
               .inheritanceDistanceFeature(type.element, extendedType.element);
         }
         // TODO(brianwilkerson) We might want to apply the substitution to the
@@ -124,13 +123,13 @@
       ExtensionElement extension, double inheritanceDistance) {
     for (var method in extension.methods) {
       if (!method.isStatic) {
-        builder.addSuggestionForMethod(
+        memberBuilder.addSuggestionForMethod(
             method: method, inheritanceDistance: inheritanceDistance);
       }
     }
     for (var accessor in extension.accessors) {
       if (!accessor.isStatic) {
-        builder.addSuggestionForAccessor(
+        memberBuilder.addSuggestionForAccessor(
             accessor: accessor, inheritanceDistance: inheritanceDistance);
       }
     }
@@ -138,11 +137,11 @@
 
   void _addTypeMembers(InterfaceType type, double inheritanceDistance) {
     for (var method in type.methods) {
-      builder.addSuggestionForMethod(
+      memberBuilder.addSuggestionForMethod(
           method: method, inheritanceDistance: inheritanceDistance);
     }
     for (var accessor in type.accessors) {
-      builder.addSuggestionForAccessor(
+      memberBuilder.addSuggestionForAccessor(
           accessor: accessor, inheritanceDistance: inheritanceDistance);
     }
   }
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 10c24e1..d81478d 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
@@ -4,10 +4,15 @@
 
 /// Utility methods to compute the value of the features used for code
 /// completion.
+import 'dart:math' as math;
+
+import 'package:analysis_server/src/protocol_server.dart'
+    show convertElementToElementKind;
+import 'package:analysis_server/src/services/completion/dart/relevance_tables.g.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart'
-    show ClassElement, Element, FieldElement;
+    show ClassElement, CompilationUnitElement, Element, FieldElement;
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart';
@@ -89,9 +94,32 @@
     }
   }
 
+  /// Return the value of the _element kind_ feature for the [element] when
+  /// 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}) {
+    if (completionLocation == null) {
+      return -1.0;
+    }
+    var locationTable = elementKindRelevance[completionLocation];
+    if (locationTable == null) {
+      return -1.0;
+    }
+    var kind = convertElementToElementKind(element);
+    var range = locationTable[kind];
+    if (range == null) {
+      return 0.0;
+    }
+    if (distance == null) {
+      return range.upper;
+    }
+    return range.conditionalProbability(_distanceToPercent(distance));
+  }
+
   /// Return the value of the _has deprecated_ feature for the given [element].
   double hasDeprecatedFeature(Element element) {
-    return element.hasDeprecated ? 0.0 : 1.0;
+    return element.hasOrInheritsDeprecated ? 0.0 : 1.0;
   }
 
   /// Return the inheritance distance between the [subclass] and the
@@ -115,7 +143,7 @@
     if (distance < 0) {
       return 0.0;
     }
-    return 1.0 / (distance + 1);
+    return _distanceToPercent(distance);
   }
 
   /// Return the value of the _starts with dollar_ feature.
@@ -129,6 +157,9 @@
           ? -1.0
           : (proposedMemberName == containingMethodName ? 1.0 : 0.0);
 
+  /// Convert a [distance] to a percentage value and return the percentage.
+  double _distanceToPercent(int distance) => math.pow(0.95, distance);
+
   /// Return the inheritance distance between the [subclass] and the
   /// [superclass]. The set of [visited] elements is used to guard against
   /// cycles in the type graph.
@@ -508,3 +539,23 @@
     return null;
   }
 }
+
+/// Additional behavior for elements related to the computation of features.
+extension ElementExtension on Element {
+  /// Return `true` if this element, or any enclosing element, has been
+  /// annotated with the `@deprecated` annotation.
+  bool get hasOrInheritsDeprecated {
+    if (hasDeprecated) {
+      return true;
+    }
+    var element = enclosingElement;
+    if (element is ClassElement) {
+      if (element.hasDeprecated) {
+        return true;
+      }
+      element = element.enclosingElement;
+    }
+    return element is CompilationUnitElement &&
+        element.enclosingElement.hasDeprecated;
+  }
+}
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 6b47032..2b7bae3 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
@@ -17,8 +17,11 @@
 class FieldFormalContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var node = request.target.containingNode;
+    // TODO(brianwilkerson) We should suggest field formal parameters even if
+    //  the user hasn't already typed the `this.` prefix, by including the
+    //  prefix in the completion.
     if (node is! FieldFormalParameter) {
       return const <CompletionSuggestion>[];
     }
@@ -29,10 +32,11 @@
     }
 
     // Compute the list of fields already referenced in the constructor.
+    // TODO(brianwilkerson) This doesn't include fields in initializers, which
+    //  shouldn't be suggested.
     var referencedFields = <String>[];
     for (var param in constructor.parameters.parameters) {
-      if (param is DefaultFormalParameter &&
-          param.parameter is FieldFormalParameter) {
+      if (param is DefaultFormalParameter) {
         param = (param as DefaultFormalParameter).parameter;
       }
       if (param is FieldFormalParameter) {
@@ -52,29 +56,21 @@
     }
 
     // Add suggestions for fields that are not already referenced.
-    var relevance = request.useNewRelevance
-        ? Relevance.fieldFormalParameter
-        : DART_RELEVANCE_LOCAL_FIELD;
-    var suggestions = <CompletionSuggestion>[];
     for (var member in enclosingClass.members) {
       if (member is FieldDeclaration && !member.isStatic) {
         for (var variable in member.fields.variables) {
-          var fieldId = variable.name;
-          if (fieldId != null) {
-            var fieldName = fieldId.name;
+          var field = variable.name.staticElement;
+          if (field != null) {
+            var fieldName = field.name;
             if (fieldName != null && fieldName.isNotEmpty) {
               if (!referencedFields.contains(fieldName)) {
-                var suggestion = createSuggestion(fieldId.staticElement,
-                    relevance: relevance);
-                if (suggestion != null) {
-                  suggestions.add(suggestion);
-                }
+                builder.suggestFieldFormalParameter(field);
               }
             }
           }
         }
       }
     }
-    return suggestions;
+    return const <CompletionSuggestion>[];
   }
 }
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 972878a..15aad2a 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
@@ -6,6 +6,8 @@
 
 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'
+    show SuggestionBuilder;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 
@@ -15,7 +17,7 @@
 class ImportedReferenceContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
       return const <CompletionSuggestion>[];
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
index 248b44f..f1f1db2 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -8,8 +8,6 @@
     show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/dart/utilities.dart';
-import 'package:analysis_server/src/utilities/flutter.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -21,14 +19,14 @@
 /// via an implicit target of `this`.
 class InheritedReferenceContributor extends DartCompletionContributor {
   /// The builder used to build the suggestions.
-  MemberSuggestionBuilder builder;
+  MemberSuggestionBuilder memberBuilder;
 
   /// The kind of suggestion to make.
   CompletionSuggestionKind kind;
 
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
       return const <CompletionSuggestion>[];
     }
@@ -40,8 +38,8 @@
     var classOrMixin = member.parent;
     if (classOrMixin is ClassOrMixinDeclaration &&
         classOrMixin.declaredElement != null) {
-      builder = MemberSuggestionBuilder(request);
-      return _computeSuggestionsForClass(classOrMixin.declaredElement, request);
+      memberBuilder = MemberSuggestionBuilder(request, builder);
+      _computeSuggestionsForClass(classOrMixin.declaredElement, request);
     }
     return const <CompletionSuggestion>[];
   }
@@ -54,12 +52,12 @@
       for (var accessor in type.accessors) {
         if (accessor.isGetter) {
           if (opType.includeReturnValueSuggestions) {
-            builder.addSuggestionForAccessor(
+            memberBuilder.addSuggestionForAccessor(
                 accessor: accessor, inheritanceDistance: inheritanceDistance);
           }
         } else {
           if (opType.includeVoidReturnSuggestions) {
-            builder.addSuggestionForAccessor(
+            memberBuilder.addSuggestionForAccessor(
                 accessor: accessor, inheritanceDistance: inheritanceDistance);
           }
         }
@@ -67,30 +65,29 @@
     }
     for (var method in type.methods) {
       if (method.returnType == null) {
-        builder.addSuggestionForMethod(
+        memberBuilder.addSuggestionForMethod(
             method: method,
             inheritanceDistance: inheritanceDistance,
             kind: kind);
       } else if (!method.returnType.isVoid) {
         if (opType.includeReturnValueSuggestions) {
-          builder.addSuggestionForMethod(
+          memberBuilder.addSuggestionForMethod(
               method: method,
               inheritanceDistance: inheritanceDistance,
               kind: kind);
         }
       } else {
         if (opType.includeVoidReturnSuggestions) {
-          var suggestion = builder.addSuggestionForMethod(
+          memberBuilder.addSuggestionForMethod(
               method: method,
               inheritanceDistance: inheritanceDistance,
               kind: kind);
-          _updateFlutterSuggestions(request, method, suggestion);
         }
       }
     }
   }
 
-  List<CompletionSuggestion> _computeSuggestionsForClass(
+  void _computeSuggestionsForClass(
       ClassElement classElement, DartCompletionRequest request) {
     var isFunctionalArgument = request.target.isFunctionalArgument();
     kind = isFunctionalArgument
@@ -105,7 +102,6 @@
       _addSuggestionsForType(type, request, inheritanceDistance,
           isFunctionalArgument: isFunctionalArgument);
     }
-    return builder.suggestions.toList();
   }
 
   /// Return the class member containing the target or `null` if the target is
@@ -121,40 +117,11 @@
         if (!node.isStatic) {
           return node;
         }
+      } else if (node is ConstructorDeclaration) {
+        return node;
       }
       node = node.parent;
     }
     return null;
   }
-
-  void _updateFlutterSuggestions(DartCompletionRequest request, Element element,
-      CompletionSuggestion suggestion) {
-    if (suggestion == null) {
-      return;
-    }
-    if (element is MethodElement &&
-        element.name == 'setState' &&
-        Flutter.of(request.result).isExactState(element.enclosingElement)) {
-      // Find the line indentation.
-      var indent = getRequestLineIndent(request);
-
-      // Let the user know that we are going to insert a complete statement.
-      suggestion.displayText = 'setState(() {});';
-
-      // Build the completion and the selection offset.
-      var buffer = StringBuffer();
-      buffer.writeln('setState(() {');
-      buffer.write('$indent  ');
-      suggestion.selectionOffset = buffer.length;
-      buffer.writeln();
-      buffer.write('$indent});');
-      suggestion.completion = buffer.toString();
-
-      // There are no arguments to fill.
-      suggestion.parameterNames = null;
-      suggestion.parameterTypes = null;
-      suggestion.requiredParameterCount = null;
-      suggestion.hasNamedParameters = null;
-    }
-  }
 }
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 3e25727..6d08f63 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
@@ -6,6 +6,8 @@
 
 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';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -28,7 +30,7 @@
 class KeywordContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var suggestions = <CompletionSuggestion>[];
 
     // Don't suggest anything right after double or integer literals.
@@ -62,10 +64,6 @@
   int get lowKeyword =>
       request.useNewRelevance ? 400 : DART_RELEVANCE_KEYWORD - 1;
 
-  bool isEmptyBody(FunctionBody body) =>
-      body is EmptyFunctionBody ||
-      (body is BlockFunctionBody && body.beginToken.isSynthetic);
-
   @override
   void visitArgumentList(ArgumentList node) {
     if (request is DartCompletionRequestImpl) {
@@ -150,7 +148,7 @@
       }
     }
     _addStatementKeywords(node);
-    if (_inCatchClause(node)) {
+    if (node.inCatchClause) {
       _addSuggestion(Keyword.RETHROW, relevance: lowKeyword);
     }
   }
@@ -167,7 +165,7 @@
       _addClassBodyKeywords();
       var index = node.members.indexOf(entity);
       var previous = index > 0 ? node.members[index - 1] : null;
-      if (previous is MethodDeclaration && isEmptyBody(previous.body)) {
+      if (previous is MethodDeclaration && previous.body.isEmpty) {
         _addSuggestion(Keyword.ASYNC);
         _addSuggestion2(ASYNC_STAR);
         _addSuggestion2(SYNC_STAR);
@@ -234,7 +232,7 @@
     if (entity == null || entity is Declaration) {
       if (previousMember is FunctionDeclaration &&
           previousMember.functionExpression is FunctionExpression &&
-          isEmptyBody(previousMember.functionExpression.body)) {
+          previousMember.functionExpression.body.isEmpty) {
         _addSuggestion(Keyword.ASYNC, relevance: highKeyword);
         _addSuggestion2(ASYNC_STAR, relevance: highKeyword);
         _addSuggestion2(SYNC_STAR, relevance: highKeyword);
@@ -360,11 +358,12 @@
     var constructorDeclaration =
         node.thisOrAncestorOfType<ConstructorDeclaration>();
     if (constructorDeclaration != null) {
-      _addSuggestions([Keyword.THIS]);
+      _addSuggestion(Keyword.THIS);
     }
     if (entity is Token && (entity as Token).type == TokenType.CLOSE_PAREN) {
       _addSuggestion(Keyword.COVARIANT);
       _addSuggestion(Keyword.DYNAMIC);
+      _addSuggestion(Keyword.VOID);
       if (request.featureSet.isEnabled(Feature.non_nullable)) {
         _addSuggestion(Keyword.REQUIRED);
       }
@@ -373,6 +372,14 @@
       if (beginToken != null && request.target.offset == beginToken.end) {
         _addSuggestion(Keyword.COVARIANT);
         _addSuggestion(Keyword.DYNAMIC);
+        _addSuggestion(Keyword.VOID);
+        if (request.featureSet.isEnabled(Feature.non_nullable)) {
+          _addSuggestion(Keyword.REQUIRED);
+        }
+      } else if (entity is FunctionTypedFormalParameter) {
+        _addSuggestion(Keyword.COVARIANT);
+        _addSuggestion(Keyword.DYNAMIC);
+        _addSuggestion(Keyword.VOID);
         if (request.featureSet.isEnabled(Feature.non_nullable)) {
           _addSuggestion(Keyword.REQUIRED);
         }
@@ -511,7 +518,7 @@
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
     if (entity == node.body) {
-      if (isEmptyBody(node.body)) {
+      if (node.body.isEmpty) {
         _addClassBodyKeywords();
         _addSuggestion(Keyword.ASYNC);
         _addSuggestion2(ASYNC_STAR);
@@ -559,7 +566,7 @@
       _addClassBodyKeywords();
       var index = node.members.indexOf(entity);
       var previous = index > 0 ? node.members[index - 1] : null;
-      if (previous is MethodDeclaration && isEmptyBody(previous.body)) {
+      if (previous is MethodDeclaration && previous.body.isEmpty) {
         _addSuggestion(Keyword.ASYNC);
         _addSuggestion2(ASYNC_STAR);
         _addSuggestion2(SYNC_STAR);
@@ -762,10 +769,10 @@
       Keyword.NULL,
       Keyword.TRUE,
     ]);
-    if (_inClassMemberBody(node)) {
+    if (node.inClassMemberBody) {
       _addSuggestions([Keyword.SUPER, Keyword.THIS]);
     }
-    if (_inAsyncMethodOrFunction(node)) {
+    if (node.inAsyncMethodOrFunction) {
       _addSuggestion(Keyword.AWAIT);
     }
   }
@@ -826,20 +833,20 @@
   }
 
   void _addStatementKeywords(AstNode node) {
-    if (_inClassMemberBody(node)) {
+    if (node.inClassMemberBody) {
       _addSuggestions([Keyword.SUPER, Keyword.THIS]);
     }
-    if (_inAsyncMethodOrFunction(node)) {
+    if (node.inAsyncMethodOrFunction) {
       _addSuggestion(Keyword.AWAIT);
-    } else if (_inAsyncStarOrSyncStarMethodOrFunction(node)) {
+    } else if (node.inAsyncStarOrSyncStarMethodOrFunction) {
       _addSuggestion(Keyword.AWAIT);
       _addSuggestion(Keyword.YIELD);
       _addSuggestion2(YIELD_STAR);
     }
-    if (_inLoop(node)) {
+    if (node.inLoop) {
       _addSuggestions([Keyword.BREAK, Keyword.CONTINUE]);
     }
-    if (_inSwitch(node)) {
+    if (node.inSwitch) {
       _addSuggestions([Keyword.BREAK]);
     }
     if (_isEntityAfterIfWithoutElse(node)) {
@@ -882,48 +889,6 @@
     });
   }
 
-  bool _inAsyncMethodOrFunction(AstNode node) {
-    var body = node.thisOrAncestorOfType<FunctionBody>();
-    return body != null && body.isAsynchronous && body.star == null;
-  }
-
-  bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) {
-    var body = node.thisOrAncestorOfType<FunctionBody>();
-    return body != null && body.keyword != null && body.star != null;
-  }
-
-  bool _inCatchClause(Block node) =>
-      node.thisOrAncestorOfType<CatchClause>() != null;
-
-  bool _inClassMemberBody(AstNode node) {
-    while (true) {
-      var body = node.thisOrAncestorOfType<FunctionBody>();
-      if (body == null) {
-        return false;
-      }
-      var parent = body.parent;
-      if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
-        return true;
-      }
-      node = parent;
-    }
-  }
-
-  bool _inDoLoop(AstNode node) =>
-      node.thisOrAncestorOfType<DoStatement>() != null;
-
-  bool _inForLoop(AstNode node) =>
-      node.thisOrAncestorMatching((p) => p is ForStatement) != null;
-
-  bool _inLoop(AstNode node) =>
-      _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
-
-  bool _inSwitch(AstNode node) =>
-      node.thisOrAncestorOfType<SwitchStatement>() != null;
-
-  bool _inWhileLoop(AstNode node) =>
-      node.thisOrAncestorOfType<WhileStatement>() != null;
-
   bool _isEntityAfterIfWithoutElse(AstNode node) {
     var block = node?.thisOrAncestorOfType<Block>();
     if (block == null) {
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 4d4940e..fb3b718 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
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
@@ -22,7 +23,7 @@
 class LabelContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var optype = (request as DartCompletionRequestImpl).opType;
 
     // Collect suggestions from the specific child [AstNode] that contains
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 181c43c..f011a42 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
@@ -19,7 +19,7 @@
 class LibraryMemberContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     // Determine if the target looks like a library prefix.
     var targetId = request.dotTarget;
     if (targetId is SimpleIdentifier && !request.target.isCascade) {
@@ -31,7 +31,7 @@
         if (containingLibrary != null) {
           var imports = containingLibrary.imports;
           if (imports != null) {
-            return _buildSuggestions(request, elem, imports);
+            return _buildSuggestions(request, builder, elem, imports);
           }
         }
       }
@@ -39,35 +39,50 @@
     return const <CompletionSuggestion>[];
   }
 
-  List<CompletionSuggestion> _buildSuggestions(DartCompletionRequest request,
-      PrefixElement elem, List<ImportElement> imports) {
+  List<CompletionSuggestion> _buildSuggestions(
+      DartCompletionRequest request,
+      SuggestionBuilder builder,
+      PrefixElement elem,
+      List<ImportElement> imports) {
     var parent = request.target.containingNode.parent;
-    var isConstructor = parent.parent is ConstructorName;
     var typesOnly = parent is TypeName;
-    var instCreation = typesOnly && isConstructor;
-    var builder = LibraryElementSuggestionBuilder(
-        request, CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
+    var isConstructor = parent.parent is ConstructorName;
     for (var importElem in imports) {
       if (importElem.prefix?.name == elem.name) {
         var library = importElem.importedLibrary;
         if (library != null) {
-          // Suggest elements from the imported library.
           for (var element in importElem.namespace.definedNames.values) {
-            element.accept(builder);
+            if (typesOnly && isConstructor) {
+              // Suggest constructors from the imported libraries.
+              if (element is ClassElement) {
+                for (var constructor in element.constructors) {
+                  if (!constructor.isPrivate) {
+                    builder.suggestConstructor(constructor,
+                        kind: CompletionSuggestionKind.INVOCATION);
+                  }
+                }
+              }
+            } else {
+              if (element is ClassElement ||
+                  element is ExtensionElement ||
+                  element is FunctionTypeAliasElement) {
+                builder.suggestElement(element,
+                    kind: CompletionSuggestionKind.INVOCATION);
+              } else if (!typesOnly &&
+                  (element is FunctionElement ||
+                      element is PropertyAccessorElement)) {
+                builder.suggestElement(element,
+                    kind: CompletionSuggestionKind.INVOCATION);
+              }
+            }
           }
-          // If the import is 'deferred' then suggest 'loadLibrary'.
-          if (importElem.isDeferred) {
-            var function = library.loadLibraryFunction;
-            var useNewRelevance = request.useNewRelevance;
-            var relevance = useNewRelevance
-                ? Relevance.loadLibrary
-                : DART_RELEVANCE_DEFAULT;
-            builder.suggestions.add(createSuggestion(function,
-                relevance: relevance, useNewRelevance: useNewRelevance));
+          // If the import is `deferred` then suggest `loadLibrary`.
+          if (!typesOnly && importElem.isDeferred) {
+            builder.suggestLoadLibraryFunction(library.loadLibraryFunction);
           }
         }
       }
     }
-    return builder.suggestions;
+    return const <CompletionSuggestion>[];
   }
 }
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 3ed0ef1..c9e4d19 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
@@ -15,7 +15,7 @@
 class LibraryPrefixContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
       return const <CompletionSuggestion>[];
     }
@@ -36,13 +36,15 @@
       if (completion != null && completion.isNotEmpty) {
         var libraryElement = element.importedLibrary;
         if (libraryElement != null) {
-          var relevance =
-              useNewRelevance ? Relevance.prefix : DART_RELEVANCE_DEFAULT;
-          var suggestion = createSuggestion(libraryElement,
+          var relevance = useNewRelevance
+              ? Relevance.prefix
+              : (libraryElement.hasDeprecated
+                  ? DART_RELEVANCE_LOW
+                  : DART_RELEVANCE_DEFAULT);
+          var suggestion = createSuggestion(request, libraryElement,
               completion: completion,
               kind: CompletionSuggestionKind.IDENTIFIER,
-              relevance: relevance,
-              useNewRelevance: useNewRelevance);
+              relevance: relevance);
           if (suggestion != null) {
             suggestions.add(suggestion);
           }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index db6852f..007b8df 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -28,7 +28,7 @@
 class LocalConstructorContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var optype = (request as DartCompletionRequestImpl).opType;
 
     // Collect suggestions from the specific child [AstNode] that contains
@@ -136,11 +136,12 @@
       if (name != null && name.isNotEmpty) {
         completion = '$completion.$name';
       }
+      if (!useNewRelevance && element.hasDeprecated) {
+        relevance = DART_RELEVANCE_LOW;
+      }
 
-      var suggestion = createSuggestion(element,
-          completion: completion,
-          relevance: relevance,
-          useNewRelevance: useNewRelevance);
+      var suggestion = createSuggestion(request, element,
+          completion: completion, relevance: relevance);
       if (suggestion != null) {
         suggestions.add(suggestion);
       }
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 8ed08d6..8f8e024 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
@@ -7,7 +7,7 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
-    show createSuggestion, ElementSuggestionBuilder;
+    show createSuggestion, ElementSuggestionBuilder, SuggestionBuilder;
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -23,6 +23,7 @@
 /// the source in which the completions are being requested.
 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
     with ElementSuggestionBuilder {
+  @override
   final DartCompletionRequest request;
 
   final OpType optype;
@@ -53,39 +54,39 @@
   void visitClassElement(ClassElement element) {
     if (optype.includeTypeNameSuggestions) {
       // if includeTypeNameSuggestions, then use the filter
-      var useNewRelevance = request.useNewRelevance;
       int relevance;
-      if (useNewRelevance) {
+      if (request.useNewRelevance) {
         relevance = _relevanceForType(element.thisType);
+      } else if (element.hasDeprecated) {
+        relevance = DART_RELEVANCE_LOW;
       } else {
         relevance = optype.typeNameSuggestionsFilter(
             _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
       }
       if (relevance != null) {
-        addSuggestion(element,
-            prefix: prefix,
-            relevance: relevance,
-            useNewRelevance: useNewRelevance);
+        addSuggestion(element, prefix: prefix, relevance: relevance);
       }
     }
     if (optype.includeConstructorSuggestions) {
-      var useNewRelevance = request.useNewRelevance;
       int relevance;
-      if (useNewRelevance) {
+      if (request.useNewRelevance) {
         relevance = _relevanceForType(element.thisType);
+      } else if (element.hasDeprecated) {
+        relevance = DART_RELEVANCE_LOW;
       } else {
         relevance = optype.returnValueSuggestionsFilter(
             _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
       }
-      _addConstructorSuggestions(element, relevance, useNewRelevance);
+      _addConstructorSuggestions(element, relevance);
     }
     if (optype.includeReturnValueSuggestions) {
       if (element.isEnum) {
         var enumName = element.displayName;
-        var useNewRelevance = request.useNewRelevance;
         int relevance;
-        if (useNewRelevance) {
+        if (request.useNewRelevance) {
           relevance = _relevanceForType(element.thisType);
+        } else if (element.hasDeprecated) {
+          relevance = DART_RELEVANCE_LOW;
         } else {
           relevance = optype.returnValueSuggestionsFilter(
               _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
@@ -95,8 +96,7 @@
             addSuggestion(field,
                 prefix: prefix,
                 relevance: relevance,
-                elementCompletion: '$enumName.${field.name}',
-                useNewRelevance: useNewRelevance);
+                elementCompletion: '$enumName.${field.name}');
           }
         }
       }
@@ -116,17 +116,14 @@
   @override
   void visitExtensionElement(ExtensionElement element) {
     if (optype.includeReturnValueSuggestions) {
-      var useNewRelevance = request.useNewRelevance;
       int relevance;
-      if (useNewRelevance) {
+      if (request.useNewRelevance) {
         relevance = _relevanceForType(element.extendedType);
       } else {
-        relevance = DART_RELEVANCE_DEFAULT;
+        relevance =
+            element.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
       }
-      addSuggestion(element,
-          prefix: prefix,
-          relevance: relevance,
-          useNewRelevance: useNewRelevance);
+      addSuggestion(element, prefix: prefix, relevance: relevance);
     }
     element.visitChildren(this);
   }
@@ -141,28 +138,23 @@
       return;
     }
     var returnType = element.returnType;
-    var useNewRelevance = request.useNewRelevance;
     int relevance;
-    if (useNewRelevance) {
+    if (request.useNewRelevance) {
       relevance = _relevanceForType(returnType);
     } else {
-      relevance = element.library == containingLibrary
-          ? DART_RELEVANCE_LOCAL_FUNCTION
-          : DART_RELEVANCE_DEFAULT;
+      relevance = element.hasDeprecated
+          ? DART_RELEVANCE_LOW
+          : (element.library == containingLibrary
+              ? DART_RELEVANCE_LOCAL_FUNCTION
+              : DART_RELEVANCE_DEFAULT);
     }
     if (returnType != null && returnType.isVoid) {
       if (optype.includeVoidReturnSuggestions) {
-        addSuggestion(element,
-            prefix: prefix,
-            relevance: relevance,
-            useNewRelevance: useNewRelevance);
+        addSuggestion(element, prefix: prefix, relevance: relevance);
       }
     } else {
       if (optype.includeReturnValueSuggestions) {
-        addSuggestion(element,
-            prefix: prefix,
-            relevance: relevance,
-            useNewRelevance: useNewRelevance);
+        addSuggestion(element, prefix: prefix, relevance: relevance);
       }
     }
   }
@@ -170,21 +162,19 @@
   @override
   void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
     if (optype.includeTypeNameSuggestions) {
-      var useNewRelevance = request.useNewRelevance;
       int relevance;
-      if (useNewRelevance) {
+      if (request.useNewRelevance) {
         // TODO(brianwilkerson) Figure out whether there are any features that
         //  ought to be used here and what the right default value is.
         relevance = 400;
       } else {
-        relevance = element.library == containingLibrary
-            ? DART_RELEVANCE_LOCAL_FUNCTION
-            : DART_RELEVANCE_DEFAULT;
+        relevance = element.hasDeprecated
+            ? DART_RELEVANCE_LOW
+            : (element.library == containingLibrary
+                ? DART_RELEVANCE_LOCAL_FUNCTION
+                : DART_RELEVANCE_DEFAULT);
       }
-      addSuggestion(element,
-          prefix: prefix,
-          relevance: relevance,
-          useNewRelevance: useNewRelevance);
+      addSuggestion(element, prefix: prefix, relevance: relevance);
     }
   }
 
@@ -198,10 +188,11 @@
   @override
   void visitPropertyAccessorElement(PropertyAccessorElement element) {
     if (optype.includeReturnValueSuggestions) {
-      var useNewRelevance = request.useNewRelevance;
       int relevance;
-      if (useNewRelevance) {
+      if (request.useNewRelevance) {
         relevance = _relevanceForType(element.returnType);
+      } else if (element.hasDeprecated) {
+        relevance = DART_RELEVANCE_LOW;
       } else {
         if (element.library == containingLibrary) {
           if (element.enclosingElement is ClassElement) {
@@ -213,35 +204,29 @@
           relevance = DART_RELEVANCE_DEFAULT;
         }
       }
-      addSuggestion(element,
-          prefix: prefix,
-          relevance: relevance,
-          useNewRelevance: useNewRelevance);
+      addSuggestion(element, prefix: prefix, relevance: relevance);
     }
   }
 
   @override
   void visitTopLevelVariableElement(TopLevelVariableElement element) {
     if (optype.includeReturnValueSuggestions) {
-      var useNewRelevance = request.useNewRelevance;
       int relevance;
-      if (useNewRelevance) {
+      if (request.useNewRelevance) {
         relevance = _relevanceForType(element.type);
       } else {
-        relevance = element.library == containingLibrary
-            ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
-            : DART_RELEVANCE_DEFAULT;
+        relevance = element.hasDeprecated
+            ? DART_RELEVANCE_LOW
+            : (element.library == containingLibrary
+                ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+                : DART_RELEVANCE_DEFAULT);
       }
-      addSuggestion(element,
-          prefix: prefix,
-          relevance: relevance,
-          useNewRelevance: useNewRelevance);
+      addSuggestion(element, prefix: prefix, relevance: relevance);
     }
   }
 
   /// Add constructor suggestions for the given class.
-  void _addConstructorSuggestions(
-      ClassElement classElem, int relevance, bool useNewRelevance) {
+  void _addConstructorSuggestions(ClassElement classElem, int relevance) {
     var className = classElem.name;
     for (var constructor in classElem.constructors) {
       if (constructor.isPrivate) {
@@ -251,15 +236,14 @@
         continue;
       }
 
-      var suggestion = createSuggestion(constructor,
-          relevance: relevance, useNewRelevance: useNewRelevance);
+      var completion = constructor.displayName;
+      completion = completion.isNotEmpty ? '$className.$completion' : className;
+      if (prefix != null && prefix.isNotEmpty) {
+        completion = '$prefix.$completion';
+      }
+      var suggestion = createSuggestion(request, constructor,
+          completion: completion, relevance: relevance);
       if (suggestion != null) {
-        var name = suggestion.completion;
-        name = name.isNotEmpty ? '$className.$name' : className;
-        if (prefix != null && prefix.isNotEmpty) {
-          name = '$prefix.$name';
-        }
-        suggestion.completion = name;
         suggestion.selectionOffset = suggestion.completion.length;
         suggestions.add(suggestion);
       }
@@ -301,7 +285,7 @@
 class LocalLibraryContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
       return const <CompletionSuggestion>[];
     }
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 2c27a26..1164992 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
@@ -5,21 +5,14 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind, Location;
+    show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
-import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/util/comment.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
-    show Element, ElementKind;
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart'
     show LocalDeclarationVisitor;
@@ -30,7 +23,7 @@
 class LocalReferenceContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var opType = request.opType;
     var node = request.target.containingNode;
 
@@ -58,9 +51,14 @@
           node = node.parent.parent;
         }
 
-        var visitor =
-            _LocalVisitor(request, suggestLocalFields: suggestLocalFields);
-        visitor.visit(node);
+        var visitor = _LocalVisitor(request, builder,
+            suggestLocalFields: suggestLocalFields);
+        try {
+          builder.laterReplacesEarlier = false;
+          visitor.visit(node);
+        } finally {
+          builder.laterReplacesEarlier = true;
+        }
         return visitor.suggestions;
       }
     }
@@ -74,6 +72,9 @@
   /// The request for which suggestions are being computed.
   final DartCompletionRequest request;
 
+  /// The builder used to build the suggestions.
+  final SuggestionBuilder builder;
+
   /// The op type associated with the request.
   final OpType opType;
 
@@ -98,7 +99,7 @@
   /// Only used when [useNewRelevance] is `false`.
   int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
 
-  _LocalVisitor(this.request, {@required this.suggestLocalFields})
+  _LocalVisitor(this.request, this.builder, {@required this.suggestLocalFields})
       : opType = request.opType,
         useNewRelevance = request.useNewRelevance,
         targetIsFunctionalArgument = request.target.isFunctionalArgument(),
@@ -138,54 +139,31 @@
 
   TypeProvider get typeProvider => request.libraryElement.typeProvider;
 
+  CompletionSuggestionKind get _defaultKind => targetIsFunctionalArgument
+      ? CompletionSuggestionKind.IDENTIFIER
+      : opType.suggestKind;
+
   @override
   void declaredClass(ClassDeclaration declaration) {
     if (opType.includeTypeNameSuggestions) {
-      _addLocalSuggestion_includeTypeNameSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        NO_RETURN_TYPE,
-        protocol.ElementKind.CLASS,
-        isAbstract: declaration.isAbstract,
-        isDeprecated: isDeprecated(declaration),
-        type: _instantiateClassElement(declaration.declaredElement),
-      );
+      builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
     }
   }
 
   @override
   void declaredClassTypeAlias(ClassTypeAlias declaration) {
     if (opType.includeTypeNameSuggestions) {
-      _addLocalSuggestion_includeTypeNameSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        NO_RETURN_TYPE,
-        protocol.ElementKind.CLASS_TYPE_ALIAS,
-        isAbstract: true,
-        isDeprecated: isDeprecated(declaration),
-        type: _instantiateClassElement(declaration.declaredElement),
-      );
+      builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
     }
   }
 
   @override
   void declaredEnum(EnumDeclaration declaration) {
     if (opType.includeTypeNameSuggestions) {
-      _addLocalSuggestion_includeTypeNameSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        NO_RETURN_TYPE,
-        protocol.ElementKind.ENUM,
-        isDeprecated: isDeprecated(declaration),
-        type: _instantiateClassElement(declaration.declaredElement),
-      );
+      builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
       for (var enumConstant in declaration.constants) {
         if (!enumConstant.isSynthetic) {
-          _addLocalSuggestion_includeReturnValueSuggestions_enumConstant(
-            enumConstant,
-            declaration,
-            isDeprecated: isDeprecated(declaration),
-          );
+          builder.suggestEnumConstant(enumConstant.declaredElement);
         }
       }
     }
@@ -194,14 +172,7 @@
   @override
   void declaredExtension(ExtensionDeclaration declaration) {
     if (opType.includeReturnValueSuggestions && declaration.name != null) {
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        NO_RETURN_TYPE,
-        protocol.ElementKind.EXTENSION,
-        isDeprecated: isDeprecated(declaration),
-        type: null,
-      );
+      builder.suggestExtension(declaration.declaredElement, kind: _defaultKind);
     }
   }
 
@@ -210,25 +181,16 @@
     if ((opType.includeReturnValueSuggestions &&
             (!opType.inStaticMethodBody || fieldDecl.isStatic)) ||
         suggestLocalFields) {
-      var deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
-      var fieldType = varDecl.declaredElement.type;
-      var typeName = fieldDecl.fields.type;
-      int relevance;
-      if (useNewRelevance) {
-        relevance = _relevanceForType(fieldType);
-      } else {
-        relevance = DART_RELEVANCE_LOCAL_FIELD;
+      var field = varDecl.declaredElement;
+      var inheritanceDistance = -1.0;
+      var enclosingClass = request.target.containingNode
+          .thisOrAncestorOfType<ClassDeclaration>();
+      if (enclosingClass != null) {
+        inheritanceDistance = request.featureComputer
+            .inheritanceDistanceFeature(
+                enclosingClass.declaredElement, field.enclosingElement);
       }
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        fieldDecl.documentationComment,
-        varDecl.name,
-        typeName,
-        protocol.ElementKind.FIELD,
-        isDeprecated: deprecated,
-        relevance: relevance,
-        classDecl: fieldDecl.parent,
-        type: fieldType,
-      );
+      builder.suggestField(field, inheritanceDistance: inheritanceDistance);
     }
   }
 
@@ -236,71 +198,39 @@
   void declaredFunction(FunctionDeclaration declaration) {
     if (opType.includeReturnValueSuggestions ||
         opType.includeVoidReturnSuggestions) {
-      var typeName = declaration.returnType;
-      protocol.ElementKind elemKind;
-      var relevance = DART_RELEVANCE_DEFAULT;
-      if (declaration.isGetter) {
-        elemKind = protocol.ElementKind.GETTER;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (declaration.isSetter) {
+      if (declaration.isSetter) {
         if (!opType.includeVoidReturnSuggestions) {
           return;
         }
-        elemKind = protocol.ElementKind.SETTER;
-        typeName = NO_RETURN_TYPE;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else {
-        if (!opType.includeVoidReturnSuggestions && _isVoid(typeName)) {
+      } else if (!declaration.isGetter) {
+        if (!opType.includeVoidReturnSuggestions &&
+            _isVoid(declaration.returnType)) {
           return;
         }
-        elemKind = protocol.ElementKind.FUNCTION;
-        relevance = DART_RELEVANCE_LOCAL_FUNCTION;
       }
-      if (useNewRelevance) {
-        relevance = _relevanceForType(declaration.declaredElement.returnType);
+      var declaredElement = declaration.declaredElement;
+      if (declaredElement is FunctionElement) {
+        builder.suggestTopLevelFunction(declaredElement, kind: _defaultKind);
+      } else if (declaredElement is PropertyAccessorElement) {
+        builder.suggestTopLevelPropertyAccessor(declaredElement,
+            kind: _defaultKind);
       }
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        typeName,
-        elemKind,
-        isDeprecated: isDeprecated(declaration),
-        param: declaration.functionExpression.parameters,
-        relevance: relevance,
-        type: declaration.declaredElement.type,
-      );
     }
   }
 
   @override
   void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
     if (opType.includeTypeNameSuggestions) {
-      // TODO (danrubel) determine parameters and return type
-      _addLocalSuggestion_includeTypeNameSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        declaration.returnType,
-        protocol.ElementKind.FUNCTION_TYPE_ALIAS,
-        isAbstract: true,
-        isDeprecated: isDeprecated(declaration),
-        type: _instantiateFunctionTypeAlias(declaration.declaredElement),
-      );
+      builder.suggestFunctionTypeAlias(declaration.declaredElement,
+          kind: _defaultKind);
     }
   }
 
   @override
   void declaredGenericTypeAlias(GenericTypeAlias declaration) {
     if (opType.includeTypeNameSuggestions) {
-      // TODO (danrubel) determine parameters and return type
-      _addLocalSuggestion_includeTypeNameSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        declaration.functionType?.returnType,
-        protocol.ElementKind.FUNCTION_TYPE_ALIAS,
-        isAbstract: true,
-        isDeprecated: isDeprecated(declaration),
-        type: _instantiateFunctionTypeAlias(declaration.declaredElement),
-      );
+      builder.suggestFunctionTypeAlias(declaration.declaredElement,
+          kind: _defaultKind);
     }
   }
 
@@ -312,23 +242,7 @@
   @override
   void declaredLocalVar(SimpleIdentifier id, TypeAnnotation typeName) {
     if (opType.includeReturnValueSuggestions) {
-      var variableType = (id.staticElement as LocalVariableElement)?.type;
-      int relevance;
-      if (useNewRelevance) {
-        // TODO(brianwilkerson) Use the distance to the local variable as
-        //  another feature.
-        relevance = _relevanceForType(variableType);
-      } else {
-        relevance = DART_RELEVANCE_LOCAL_VARIABLE;
-      }
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        null,
-        id,
-        typeName,
-        protocol.ElementKind.LOCAL_VARIABLE,
-        relevance: relevance,
-        type: variableType ?? typeProvider.dynamicType,
-      );
+      builder.suggestLocalVariable(id.staticElement as LocalVariableElement);
     }
   }
 
@@ -337,80 +251,44 @@
     if ((opType.includeReturnValueSuggestions ||
             opType.includeVoidReturnSuggestions) &&
         (!opType.inStaticMethodBody || declaration.isStatic)) {
-      protocol.ElementKind elemKind;
-      FormalParameterList param;
-      var typeName = declaration.returnType;
-      var relevance = DART_RELEVANCE_DEFAULT;
-      if (declaration.isGetter) {
-        elemKind = protocol.ElementKind.GETTER;
-        param = null;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (declaration.isSetter) {
-        if (!opType.includeVoidReturnSuggestions) {
-          return;
-        }
-        elemKind = protocol.ElementKind.SETTER;
-        typeName = NO_RETURN_TYPE;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else {
-        if (!opType.includeVoidReturnSuggestions && _isVoid(typeName)) {
-          return;
-        }
-        elemKind = protocol.ElementKind.METHOD;
-        param = declaration.parameters;
-        relevance = DART_RELEVANCE_LOCAL_METHOD;
+      var element = declaration.declaredElement;
+      var inheritanceDistance = -1.0;
+      var enclosingClass = request.target.containingNode
+          .thisOrAncestorOfType<ClassDeclaration>();
+      if (enclosingClass != null) {
+        inheritanceDistance = request.featureComputer
+            .inheritanceDistanceFeature(
+                enclosingClass.declaredElement, element.enclosingElement);
       }
-      if (useNewRelevance) {
-        relevance = _relevanceForType(declaration.declaredElement.returnType);
+      if (element is MethodElement) {
+        builder.suggestMethod(element,
+            inheritanceDistance: inheritanceDistance, kind: _defaultKind);
+      } else if (element is PropertyAccessorElement) {
+        builder.suggestAccessor(element,
+            inheritanceDistance: inheritanceDistance);
       }
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        typeName,
-        elemKind,
-        isAbstract: declaration.isAbstract,
-        isDeprecated: isDeprecated(declaration),
-        classDecl: declaration.parent,
-        param: param,
-        relevance: relevance,
-        type: declaration.declaredElement.type,
-      );
     }
   }
 
   @override
   void declaredMixin(MixinDeclaration declaration) {
     if (opType.includeTypeNameSuggestions) {
-      _addLocalSuggestion_includeTypeNameSuggestions(
-        declaration.documentationComment,
-        declaration.name,
-        NO_RETURN_TYPE,
-        protocol.ElementKind.MIXIN,
-        isAbstract: true,
-        isDeprecated: isDeprecated(declaration),
-        type: _instantiateClassElement(declaration.declaredElement),
-      );
+      builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
     }
   }
 
   @override
   void declaredParam(SimpleIdentifier id, TypeAnnotation typeName) {
     if (opType.includeReturnValueSuggestions) {
-      var parameterType = (id.staticElement as VariableElement).type;
-      int relevance;
-      if (useNewRelevance) {
-        relevance = _relevanceForType(parameterType);
-      } else {
-        relevance = DART_RELEVANCE_PARAMETER;
+      if (_isUnused(id.name)) {
+        return;
       }
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        null,
-        id,
-        typeName,
-        protocol.ElementKind.PARAMETER,
-        relevance: relevance,
-        type: parameterType,
-      );
+      var element = id.staticElement;
+      if (element is ParameterElement) {
+        builder.suggestParameter(element);
+      } else if (element is LocalVariableElement) {
+        builder.suggestCatchParameter(element);
+      }
     }
   }
 
@@ -418,283 +296,22 @@
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl) {
     if (opType.includeReturnValueSuggestions) {
-      var variableType = varDecl.declaredElement.type;
-      int relevance;
-      if (useNewRelevance) {
-        relevance = _relevanceForType(variableType);
-      } else {
-        relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
-      }
-      _addLocalSuggestion_includeReturnValueSuggestions(
-        varDecl.documentationComment,
-        varDecl.name,
-        varList.type,
-        protocol.ElementKind.TOP_LEVEL_VARIABLE,
-        isDeprecated: isDeprecated(varList) || isDeprecated(varDecl),
-        relevance: relevance,
-        type: variableType,
-      );
+      var variableElement = varDecl.declaredElement;
+      builder.suggestTopLevelPropertyAccessor(
+          (variableElement as TopLevelVariableElement).getter);
     }
   }
 
   @override
   void declaredTypeParameter(TypeParameter node) {
     if (opType.includeTypeNameSuggestions) {
-      int relevance;
-      if (useNewRelevance) {
-        relevance = Relevance.typeParameter;
-      } else {
-        relevance = DART_RELEVANCE_TYPE_PARAMETER;
-      }
-      _addLocalSuggestion(
-        null,
-        node.name,
-        null,
-        protocol.ElementKind.TYPE_PARAMETER,
-        isDeprecated: isDeprecated(node),
-        kind: CompletionSuggestionKind.IDENTIFIER,
-        relevance: relevance,
-      );
+      builder.suggestTypeParameter(node.declaredElement);
     }
   }
 
-  void _addLocalSuggestion(Comment documentationComment, SimpleIdentifier id,
-      TypeAnnotation typeName, protocol.ElementKind elemKind,
-      {bool isAbstract = false,
-      bool isDeprecated = false,
-      ClassOrMixinDeclaration classDecl,
-      CompletionSuggestionKind kind,
-      FormalParameterList param,
-      int relevance = DART_RELEVANCE_DEFAULT}) {
-    if (id == null) {
-      return null;
-    }
-    kind ??= targetIsFunctionalArgument
-        ? CompletionSuggestionKind.IDENTIFIER
-        : opType.suggestKind;
-    var suggestion = _createLocalSuggestion(
-        id, isDeprecated, relevance, typeName,
-        classDecl: classDecl, kind: kind);
-    if (suggestion != null) {
-      _setDocumentation(suggestion, documentationComment);
-      if (!useNewRelevance &&
-          privateMemberRelevance != null &&
-          suggestion.completion.startsWith('_')) {
-        suggestion.relevance = privateMemberRelevance;
-      }
-      suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
-      suggestion.element = createLocalElement(request.source, elemKind, id,
-          isAbstract: isAbstract,
-          isDeprecated: isDeprecated,
-          parameters: param?.toSource(),
-          returnType: typeName);
-      if ((elemKind == protocol.ElementKind.METHOD ||
-              elemKind == protocol.ElementKind.FUNCTION) &&
-          param != null) {
-        _addParameterInfo(suggestion, param);
-      }
-    }
-  }
-
-  void _addLocalSuggestion_enumConstant(
-      EnumConstantDeclaration constantDeclaration,
-      EnumDeclaration enumDeclaration,
-      {bool isDeprecated = false,
-      int relevance = DART_RELEVANCE_DEFAULT}) {
-    var constantNameNode = constantDeclaration.name;
-    var constantName = constantNameNode.name;
-    var enumName = enumDeclaration.name.name;
-    var completion = '$enumName.$constantName';
-    if (!useNewRelevance) {
-      relevance = isDeprecated ? DART_RELEVANCE_LOW : relevance;
-    }
-    var suggestion = CompletionSuggestion(CompletionSuggestionKind.INVOCATION,
-        relevance, completion, completion.length, 0, isDeprecated, false,
-        returnType: enumName);
-
-    suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
-    var flags = protocol.Element.makeFlags(
-        isDeprecated: isDeprecated,
-        isPrivate: Identifier.isPrivateName(constantName));
-    suggestion.element = protocol.Element(
-        protocol.ElementKind.ENUM_CONSTANT, constantName, flags,
-        location: Location(request.source.fullName, constantNameNode.offset,
-            constantNameNode.length, 0, 0));
-  }
-
-  void _addLocalSuggestion_includeReturnValueSuggestions(
-      Comment documentationComment,
-      SimpleIdentifier id,
-      TypeAnnotation typeName,
-      protocol.ElementKind elemKind,
-      {bool isAbstract = false,
-      bool isDeprecated = false,
-      ClassOrMixinDeclaration classDecl,
-      FormalParameterList param,
-      int relevance = DART_RELEVANCE_DEFAULT,
-      @required DartType type}) {
-    if (!useNewRelevance) {
-      relevance = opType.returnValueSuggestionsFilter(type, relevance);
-    }
-    if (relevance != null) {
-      _addLocalSuggestion(documentationComment, id, typeName, elemKind,
-          isAbstract: isAbstract,
-          isDeprecated: isDeprecated,
-          classDecl: classDecl,
-          param: param,
-          relevance: relevance);
-    }
-  }
-
-  void _addLocalSuggestion_includeReturnValueSuggestions_enumConstant(
-      EnumConstantDeclaration constantDeclaration,
-      EnumDeclaration enumDeclaration,
-      {@required bool isDeprecated}) {
-    var enumElement = enumDeclaration.declaredElement;
-    int relevance;
-    if (useNewRelevance) {
-      relevance = _relevanceForType(enumElement.thisType);
-    } else {
-      relevance = opType.returnValueSuggestionsFilter(
-          _instantiateClassElement(enumElement), DART_RELEVANCE_DEFAULT);
-    }
-    if (relevance != null) {
-      _addLocalSuggestion_enumConstant(constantDeclaration, enumDeclaration,
-          isDeprecated: isDeprecated, relevance: relevance);
-    }
-  }
-
-  void _addLocalSuggestion_includeTypeNameSuggestions(
-      Comment documentationComment,
-      SimpleIdentifier id,
-      TypeAnnotation typeName,
-      protocol.ElementKind elemKind,
-      {bool isAbstract = false,
-      bool isDeprecated = false,
-      @required DartType type}) {
-    int relevance;
-    if (useNewRelevance) {
-      relevance = _relevanceForType(type);
-    } else {
-      relevance =
-          opType.typeNameSuggestionsFilter(type, DART_RELEVANCE_DEFAULT);
-    }
-    if (relevance != null) {
-      _addLocalSuggestion(documentationComment, id, typeName, elemKind,
-          isAbstract: isAbstract,
-          isDeprecated: isDeprecated,
-          relevance: relevance);
-    }
-  }
-
-  void _addParameterInfo(
-      CompletionSuggestion suggestion, FormalParameterList parameters) {
-    var paramList = parameters.parameters;
-    suggestion.parameterNames = paramList
-        .map((FormalParameter param) => param.identifier.name)
-        .toList();
-    suggestion.parameterTypes = paramList.map((FormalParameter param) {
-      TypeAnnotation type;
-      if (param is DefaultFormalParameter) {
-        var child = param.parameter;
-        if (child is SimpleFormalParameter) {
-          type = child.type;
-        } else if (child is FieldFormalParameter) {
-          type = child.type;
-        }
-      }
-      if (param is SimpleFormalParameter) {
-        type = param.type;
-      } else if (param is FieldFormalParameter) {
-        type = param.type;
-      }
-      if (type == null) {
-        return 'dynamic';
-      }
-      if (type is TypeName) {
-        var typeId = type.name;
-        if (typeId == null) {
-          return 'dynamic';
-        }
-        return typeId.name;
-      }
-      // TODO(brianwilkerson) Support function types.
-      return 'dynamic';
-    }).toList();
-
-    var requiredParameters = paramList
-        .where((FormalParameter param) => param.isRequiredPositional)
-        .map((p) => p.declaredElement);
-    suggestion.requiredParameterCount = requiredParameters.length;
-
-    var namedParameters = paramList
-        .where((FormalParameter param) => param.isNamed)
-        .map((p) => p.declaredElement);
-    suggestion.hasNamedParameters = namedParameters.isNotEmpty;
-
-    addDefaultArgDetails(suggestion, null, requiredParameters, namedParameters);
-  }
-
-  /// Create a new suggestion based upon the given information. Return the new
-  /// suggestion or `null` if it could not be created.
-  CompletionSuggestion _createLocalSuggestion(SimpleIdentifier id,
-      bool isDeprecated, int relevance, TypeAnnotation returnType,
-      {ClassOrMixinDeclaration classDecl,
-      @required CompletionSuggestionKind kind}) {
-    var completion = id.name;
-    if (completion == null || completion.isEmpty || completion == '_') {
-      return null;
-    }
-    if (!useNewRelevance) {
-      relevance = isDeprecated ? DART_RELEVANCE_LOW : relevance;
-    }
-    var suggestion = CompletionSuggestion(
-        kind, relevance, completion, completion.length, 0, isDeprecated, false,
-        returnType: nameForType(id, returnType));
-    var className = classDecl?.name?.name;
-    if (className != null && className.isNotEmpty) {
-      suggestion.declaringType = className;
-    }
-    return suggestion;
-  }
-
-  InterfaceType _instantiateClassElement(ClassElement element) {
-    var typeParameters = element.typeParameters;
-    var typeArguments = const <DartType>[];
-    if (typeParameters.isNotEmpty) {
-      typeArguments = typeParameters.map((t) {
-        return typeProvider.dynamicType;
-      }).toList();
-    }
-
-    var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
-        ? NullabilitySuffix.none
-        : NullabilitySuffix.star;
-
-    return element.instantiate(
-      typeArguments: typeArguments,
-      nullabilitySuffix: nullabilitySuffix,
-    );
-  }
-
-  FunctionType _instantiateFunctionTypeAlias(FunctionTypeAliasElement element) {
-    var typeParameters = element.typeParameters;
-    var typeArguments = const <DartType>[];
-    if (typeParameters.isNotEmpty) {
-      typeArguments = typeParameters.map((t) {
-        return typeProvider.dynamicType;
-      }).toList();
-    }
-
-    var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
-        ? NullabilitySuffix.none
-        : NullabilitySuffix.star;
-
-    return element.instantiate(
-      typeArguments: typeArguments,
-      nullabilitySuffix: nullabilitySuffix,
-    );
-  }
+  /// Return `true` if the [identifier] is composed of one or more underscore
+  /// characters and nothing else.
+  bool _isUnused(String identifier) => RegExp(r'^_+$').hasMatch(identifier);
 
   bool _isVoid(TypeAnnotation returnType) {
     if (returnType is TypeName) {
@@ -705,29 +322,4 @@
     }
     return false;
   }
-
-  /// Return the relevance for an element with the given [elementType].
-  int _relevanceForType(DartType elementType) {
-    var contextTypeFeature =
-        request.featureComputer.contextTypeFeature(contextType, elementType);
-    // TODO(brianwilkerson) Figure out whether there are other features that
-    //  ought to be used here and what the right default value is. It's possible
-    //  that the right default value depends on where this is called from.
-    return toRelevance(contextTypeFeature, 800);
-  }
-
-  /// If the given [documentationComment] is not `null`, fill the [suggestion]
-  /// documentation fields.
-  static void _setDocumentation(
-      CompletionSuggestion suggestion, Comment documentationComment) {
-    if (documentationComment != null) {
-      var text = documentationComment.tokens
-          .map((Token t) => t.toString())
-          .join('\n')
-          .replaceAll('\r\n', '\n');
-      var doc = getDartDocPlainText(text);
-      suggestion.docComplete = doc;
-      suggestion.docSummary = getDartDocSummary(doc);
-    }
-  }
 }
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 5a0c30d..c8d6130 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
@@ -17,7 +17,7 @@
 class NamedConstructorContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var node = request.target.containingNode;
     var libraryElement = request.libraryElement;
     if (libraryElement == null) {
@@ -32,8 +32,7 @@
         if (type != null) {
           var element = type.element;
           if (element is ClassElement) {
-            return _buildSuggestions(
-                libraryElement, element, request.useNewRelevance);
+            _buildSuggestions(request, builder, libraryElement, element);
           }
         }
       }
@@ -41,27 +40,19 @@
     return const <CompletionSuggestion>[];
   }
 
-  List<CompletionSuggestion> _buildSuggestions(
-      LibraryElement libElem, ClassElement classElem, bool useNewRelevance) {
+  void _buildSuggestions(
+      DartCompletionRequest request,
+      SuggestionBuilder builder,
+      LibraryElement libElem,
+      ClassElement classElem) {
     var isLocalClassDecl = classElem.library == libElem;
-    var suggestions = <CompletionSuggestion>[];
     for (var constructor in classElem.constructors) {
       if (isLocalClassDecl || !constructor.isPrivate) {
         var name = constructor.name;
         if (name != null) {
-          var relevance = useNewRelevance
-              ? Relevance.namedConstructor
-              : DART_RELEVANCE_DEFAULT;
-          var suggestion = createSuggestion(constructor,
-              completion: name,
-              relevance: relevance,
-              useNewRelevance: useNewRelevance);
-          if (suggestion != null) {
-            suggestions.add(suggestion);
-          }
+          builder.suggestConstructor(constructor, hasClassName: true);
         }
       }
     }
-    return suggestions;
   }
 }
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 bfecf44..28c0d6f 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
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/protocol_server.dart' as protocol
     hide CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -24,7 +25,7 @@
 class OverrideContributor implements DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var targetId = _getTargetId(request.target);
     if (targetId == null) {
       return const <CompletionSuggestion>[];
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
new file mode 100644
index 0000000..2b4be44
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/probability_range.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A range of probabilities that a given event has occurred.
+class ProbabilityRange {
+  /// The lower bound of the range.
+  final double lower;
+
+  /// The upper bound of the range.
+  final double upper;
+
+  /// Initialize a newly created probability range to have the given [lower] and
+  /// [upper] bounds.
+  const ProbabilityRange({this.lower, this.upper});
+
+  /// 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);
+  }
+}
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
new file mode 100644
index 0000000..ab6d997
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
@@ -0,0 +1,873 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart",
+// passing it the location of a corpus of code that is large enough for the
+// computed values to be statistically meaningful.
+
+import 'package:analysis_server/src/services/completion/dart/probability_range.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+
+/// A table keyed by completion location and element kind whose values are the
+/// ranges of the relevance of those element kinds in those locations.
+const elementKindRelevance = {
+  'Annotation_name': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.029),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.029, upper: 1.000),
+  },
+  'ArgumentList_annotation_named': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.979),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.979, upper: 0.984),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.984, upper: 1.000),
+  },
+  'ArgumentList_annotation_unnamed': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'ArgumentList_constructorRedirect_named': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.027),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.027, upper: 0.029),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.029, upper: 0.031),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.031, upper: 0.034),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.034, upper: 0.044),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.044, upper: 1.000),
+  },
+  'ArgumentList_constructorRedirect_unnamed': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.199),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.199, upper: 0.201),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.201, upper: 0.206),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.206, upper: 0.212),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.212, upper: 0.230),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.230, upper: 0.279),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.279, upper: 1.000),
+  },
+  'ArgumentList_constructor_named': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.485),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.485, upper: 0.487),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.487, upper: 0.489),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.489, upper: 0.501),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.501, upper: 0.539),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.539, upper: 0.579),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.579, upper: 0.646),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.646, upper: 0.735),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.735, upper: 1.000),
+  },
+  'ArgumentList_constructor_unnamed': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.617),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.617, upper: 0.621),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.621, upper: 0.629),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.629, upper: 0.645),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.645, upper: 0.683),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.683, upper: 0.733),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.733, upper: 0.811),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.811, upper: 0.905),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.905, upper: 1.000),
+  },
+  'ArgumentList_function_named': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.616),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.616, upper: 0.648),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.648, upper: 0.792),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.792, upper: 1.000),
+  },
+  'ArgumentList_function_unnamed': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.220),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.220, upper: 0.227),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.227, upper: 0.237),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.237, upper: 0.255),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.255, upper: 0.280),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.280, upper: 0.347),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.347, upper: 0.583),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.583, upper: 1.000),
+  },
+  'ArgumentList_method_named': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.548),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.548, upper: 0.551),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.551, upper: 0.555),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.555, upper: 0.568),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.568, upper: 0.626),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.626, upper: 0.686),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.686, upper: 0.764),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.764, upper: 0.854),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.854, upper: 1.000),
+  },
+  'ArgumentList_method_unnamed': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.387),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.387, upper: 0.387),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.387, upper: 0.387),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.387, upper: 0.388),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.388, upper: 0.394),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.394, upper: 0.402),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.402, upper: 0.425),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.425, upper: 0.452),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.452, upper: 0.510),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.510, upper: 0.624),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.624, upper: 0.746),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.746, upper: 1.000),
+  },
+  'ArgumentList_widgetConstructor_named': {
+    ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.351),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.351, upper: 0.352),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.352, upper: 0.355),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.355, upper: 0.368),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.368, upper: 0.387),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.387, upper: 0.422),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.422, upper: 0.482),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.482, upper: 0.552),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.552, upper: 0.636),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.636, upper: 1.000),
+  },
+  'ArgumentList_widgetConstructor_unnamed': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.461),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.461, upper: 0.463),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.463, upper: 0.469),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.469, upper: 0.475),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.475, upper: 0.491),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.491, upper: 0.541),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.541, upper: 0.612),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.612, upper: 0.757),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.757, upper: 1.000),
+  },
+  'AsExpression_type': {
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.000, upper: 0.000),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.001),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.001, upper: 0.002),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.002, upper: 0.012),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.012, upper: 1.000),
+  },
+  'AssertInitializer_condition': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'AssertInitializer_message': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'AssertStatement_condition': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.142),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.142, upper: 0.176),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.176, upper: 0.226),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.226, upper: 0.332),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.332, upper: 0.662),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.662, upper: 1.000),
+  },
+  'AssertStatement_message': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'AssignmentExpression_rightHandSide': {
+    ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.305),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.305, upper: 0.306),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.306, upper: 0.318),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.318, upper: 0.329),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.329, upper: 0.350),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.350, upper: 0.395),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.395, upper: 0.490),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.490, upper: 0.601),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.601, upper: 0.740),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.740, upper: 1.000),
+  },
+  'AwaitExpression_expression': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.022),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.022, upper: 0.049),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.049, upper: 0.144),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.144, upper: 0.291),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.291, upper: 0.448),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.448, upper: 0.606),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.606, upper: 0.773),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.773, upper: 1.000),
+  },
+  'BinaryExpression_!=_rightOperand': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.874),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.874, upper: 0.874),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.874, upper: 0.875),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.875, upper: 0.886),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.886, upper: 0.903),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.903, upper: 0.921),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.921, upper: 0.958),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.958, upper: 1.000),
+  },
+  'BinaryExpression_%_rightOperand': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.719),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.719, upper: 0.725),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.725, upper: 0.752),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.752, upper: 0.784),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.784, upper: 0.853),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.853, upper: 1.000),
+  },
+  'BinaryExpression_&&_rightOperand': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.108),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.108, upper: 0.113),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.113, upper: 0.123),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.123, upper: 0.138),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.138, upper: 0.260),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.260, upper: 0.442),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.442, upper: 1.000),
+  },
+  'BinaryExpression_&_rightOperand': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.266),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.266, upper: 0.364),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.364, upper: 0.462),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.462, upper: 0.723),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.723, upper: 1.000),
+  },
+  'BinaryExpression_*_rightOperand': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.611),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.611, upper: 0.613),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.613, upper: 0.616),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.616, upper: 0.625),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.625, upper: 0.640),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.640, upper: 0.663),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.663, upper: 0.714),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.714, upper: 0.850),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.850, upper: 1.000),
+  },
+  'BinaryExpression_+_rightOperand': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.500),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.500, upper: 0.505),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.505, upper: 0.511),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.511, upper: 0.526),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.526, upper: 0.549),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.549, upper: 0.668),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.668, upper: 0.825),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.825, upper: 1.000),
+  },
+  'BinaryExpression_-_rightOperand': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.473),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.473, upper: 0.477),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.477, upper: 0.483),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.483, upper: 0.491),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.491, upper: 0.506),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.506, upper: 0.597),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.597, upper: 0.793),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.793, upper: 1.000),
+  },
+  'BinaryExpression_/_rightOperand': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.762),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.762, upper: 0.763),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.763, upper: 0.765),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.765, upper: 0.771),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.771, upper: 0.779),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.779, upper: 0.818),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.818, upper: 0.907),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.907, upper: 1.000),
+  },
+  'BinaryExpression_<<_rightOperand': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.756),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.756, upper: 0.854),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.854, upper: 1.000),
+  },
+  'BinaryExpression_<=_rightOperand': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.607),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.607, upper: 0.717),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.717, upper: 0.848),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.848, upper: 1.000),
+  },
+  'BinaryExpression_<_rightOperand': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.424),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.424, upper: 0.425),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.425, upper: 0.426),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.426, upper: 0.438),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.438, upper: 0.557),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.557, upper: 0.773),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.773, upper: 1.000),
+  },
+  'BinaryExpression_==_rightOperand': {
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.567),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.567, upper: 0.567),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.567, upper: 0.567),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.567, upper: 0.567),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.567, upper: 0.568),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.568, upper: 0.591),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.591, upper: 0.629),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.629, upper: 0.679),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.679, upper: 0.807),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.807, upper: 1.000),
+  },
+  'BinaryExpression_>=_rightOperand': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.714),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.714, upper: 0.731),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.731, upper: 0.791),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.791, upper: 0.854),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.854, upper: 1.000),
+  },
+  'BinaryExpression_>>_rightOperand': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'BinaryExpression_>_rightOperand': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.813),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.813, upper: 0.814),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.814, upper: 0.815),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.815, upper: 0.818),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.818, upper: 0.826),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.826, upper: 0.867),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.867, upper: 0.928),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.928, upper: 1.000),
+  },
+  'BinaryExpression_??_rightOperand': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.665),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.665, upper: 0.668),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.668, upper: 0.673),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.673, upper: 0.684),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.684, upper: 0.726),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.726, upper: 0.768),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.768, upper: 0.816),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.816, upper: 0.871),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.871, upper: 1.000),
+  },
+  'BinaryExpression_^_rightOperand': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.118),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.118, upper: 1.000),
+  },
+  'BinaryExpression_|_rightOperand': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.143),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.143, upper: 0.429),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.429, upper: 1.000),
+  },
+  'BinaryExpression_||_rightOperand': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.144),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.144, upper: 0.148),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.148, upper: 0.168),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.168, upper: 0.378),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.378, upper: 0.663),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.663, upper: 1.000),
+  },
+  'BinaryExpression_~/_rightOperand': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.627),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.627, upper: 0.640),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.640, upper: 0.677),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.677, upper: 0.795),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.795, upper: 1.000),
+  },
+  'Block_statement': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.537),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.537, upper: 0.537),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.537, upper: 0.538),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.538, upper: 0.538),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.538, upper: 0.539),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.539, upper: 0.540),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.540, upper: 0.563),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.563, upper: 0.614),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.614, upper: 0.674),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.674, upper: 0.743),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.743, upper: 0.825),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.825, upper: 0.911),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.911, upper: 1.000),
+  },
+  'CatchClause_exceptionType': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'ClassDeclaration_member': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.390),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.390, upper: 0.390),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.390, upper: 0.391),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.391, upper: 0.392),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.392, upper: 0.393),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.393, upper: 0.399),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.399, upper: 1.000),
+  },
+  'ClassTypeAlias_superclass': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'CommentReference_identifier': {
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.001),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.001, upper: 0.001),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.001, upper: 0.002),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.002, upper: 0.004),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.004, upper: 0.008),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.008, upper: 0.021),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.021, upper: 0.054),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.054, upper: 0.106),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.106, upper: 0.167),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.167, upper: 0.425),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.425, upper: 1.000),
+  },
+  'CompilationUnit_declaration': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.820),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.820, upper: 0.820),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.820, upper: 0.821),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.821, upper: 0.823),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.823, upper: 0.837),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.837, upper: 1.000),
+  },
+  'ConditionalExpression_elseExpression': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.370),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.370, upper: 0.375),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.375, upper: 0.383),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.383, upper: 0.403),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.403, upper: 0.427),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.427, upper: 0.482),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.482, upper: 0.549),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.549, upper: 0.655),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.655, upper: 0.790),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.790, upper: 1.000),
+  },
+  'ConditionalExpression_thenExpression': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.390),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.390, upper: 0.395),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.395, upper: 0.402),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.402, upper: 0.424),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.424, upper: 0.450),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.450, upper: 0.500),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.500, upper: 0.556),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.556, upper: 0.634),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.634, upper: 0.777),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.777, upper: 1.000),
+  },
+  'ConstructorDeclaration_initializer': {
+    ElementKind.FIELD: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'ConstructorDeclaration_returnType': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'ConstructorFieldInitializer_expression': {
+    ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.183),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.183, upper: 0.187),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.187, upper: 0.195),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.195, upper: 0.220),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.220, upper: 0.272),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.272, upper: 0.396),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.396, upper: 1.000),
+  },
+  'DefaultFormalParameter_defaultValue': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.716),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.716, upper: 0.716),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.716, upper: 0.717),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.717, upper: 0.733),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.733, upper: 0.776),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.776, upper: 0.838),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.838, upper: 1.000),
+  },
+  'DoStatement_condition': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.333),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.333, upper: 1.000),
+  },
+  'Expression': {
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.386),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.386, upper: 0.386),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.386, upper: 0.386),
+    ElementKind.TOP_LEVEL_VARIABLE:
+        ProbabilityRange(lower: 0.386, upper: 0.386),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.386, upper: 0.386),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.386, upper: 0.388),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.388, upper: 0.402),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.402, upper: 0.418),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.418, upper: 0.434),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.434, upper: 0.450),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.450, upper: 0.522),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.522, upper: 0.607),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.607, upper: 0.701),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.701, upper: 0.839),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.839, upper: 1.000),
+  },
+  'ExpressionFunctionBody_expression': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.352),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.352, upper: 0.352),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.352, upper: 0.358),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.358, upper: 0.363),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.363, upper: 0.373),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.373, upper: 0.394),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.394, upper: 0.419),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.419, upper: 0.452),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.452, upper: 0.487),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.487, upper: 0.613),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.613, upper: 0.794),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.794, upper: 1.000),
+  },
+  'ExpressionStatement_expression': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.132),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.132, upper: 0.134),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.134, upper: 0.136),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.136, upper: 0.139),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.139, upper: 0.190),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.190, upper: 0.255),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.255, upper: 0.361),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.361, upper: 0.482),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.482, upper: 0.625),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.625, upper: 0.801),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.801, upper: 1.000),
+  },
+  'ExtendsClause_superclass': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.000),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'ExtensionDeclaration_extendedType': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.053),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.053, upper: 0.105),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.105, upper: 1.000),
+  },
+  'ExtensionDeclaration_member': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.120),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.120, upper: 1.000),
+  },
+  'ForEachPartsWithDeclaration_iterable': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.016),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.016, upper: 0.018),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.018, upper: 0.022),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.022, upper: 0.029),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.029, upper: 0.036),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.036, upper: 0.288),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.288, upper: 0.607),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.607, upper: 1.000),
+  },
+  'ForEachPartsWithDeclaration_loopVariable': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.703),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.703, upper: 0.704),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.704, upper: 0.706),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.706, upper: 0.708),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.708, upper: 0.712),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.712, upper: 1.000),
+  },
+  'ForElement_body': {
+    ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.900),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.900, upper: 0.904),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.904, upper: 0.908),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.908, upper: 0.918),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.918, upper: 0.937),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.937, upper: 1.000),
+  },
+  'ForParts_condition': {
+    ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.023),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.023, upper: 1.000),
+  },
+  'ForParts_updater': {
+    ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.067),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.067, upper: 1.000),
+  },
+  'FormalParameterList_parameter': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.245),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.245, upper: 0.247),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.247, upper: 0.255),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.255, upper: 0.267),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.267, upper: 0.284),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.284, upper: 0.311),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.311, upper: 1.000),
+  },
+  'GenericTypeAlias_functionType': {
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.000, upper: 0.590),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.590, upper: 0.610),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.610, upper: 0.660),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.660, upper: 1.000),
+  },
+  'HideCombinator_hiddenName': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.059),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.059, upper: 1.000),
+  },
+  'IfElement_condition': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.157),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.157, upper: 0.172),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.172, upper: 0.338),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.338, upper: 0.633),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.633, upper: 1.000),
+  },
+  'IfElement_elseElement': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.333),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.333, upper: 1.000),
+  },
+  'IfElement_thenElement': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.212),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.212, upper: 0.219),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.219, upper: 0.228),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.228, upper: 0.239),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.239, upper: 0.254),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.254, upper: 0.281),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.281, upper: 1.000),
+  },
+  'IfStatement_condition': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.117),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.117, upper: 0.118),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.118, upper: 0.118),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.118, upper: 0.118),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.118, upper: 0.119),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.119, upper: 0.129),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.129, upper: 0.145),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.145, upper: 0.167),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.167, upper: 0.388),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.388, upper: 0.688),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.688, upper: 1.000),
+  },
+  'IfStatement_else': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.968),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.968, upper: 0.969),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.969, upper: 0.972),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.972, upper: 0.976),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.976, upper: 0.981),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.981, upper: 0.990),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.990, upper: 1.000),
+  },
+  'IfStatement_then': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.934),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.934, upper: 0.935),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.935, upper: 0.937),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.937, upper: 0.942),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.942, upper: 0.952),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.952, upper: 0.964),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.964, upper: 0.981),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.981, upper: 1.000),
+  },
+  'ImplementsClause_interface': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.003),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.003, upper: 1.000),
+  },
+  'IndexExpression_index': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.655),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.655, upper: 0.655),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.655, upper: 0.656),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.656, upper: 0.656),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.656, upper: 0.657),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.657, upper: 0.659),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.659, upper: 0.664),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.664, upper: 0.760),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.760, upper: 0.863),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.863, upper: 1.000),
+  },
+  'InterpolationExpression_expression': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.035),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.035, upper: 0.035),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.035, upper: 0.036),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.036, upper: 0.036),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.036, upper: 0.044),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.044, upper: 0.074),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.074, upper: 0.198),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.198, upper: 0.388),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.388, upper: 0.633),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.633, upper: 1.000),
+  },
+  'IsExpression_type': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.002),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.002, upper: 0.005),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.005, upper: 0.008),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.008, upper: 0.013),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.013, upper: 1.000),
+  },
+  'ListLiteral_element': {
+    ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.324),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.324, upper: 0.325),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.325, upper: 0.327),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.327, upper: 0.331),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.331, upper: 0.338),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.338, upper: 0.349),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.349, upper: 0.362),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.362, upper: 0.379),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.379, upper: 0.407),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.407, upper: 1.000),
+  },
+  'MapLiteralEntry_value': {
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.814),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.814, upper: 0.814),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.814, upper: 0.816),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.816, upper: 0.818),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.818, upper: 0.823),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.823, upper: 0.829),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.829, upper: 0.849),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.849, upper: 0.884),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.884, upper: 1.000),
+  },
+  'MixinDeclaration_member': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.116),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.116, upper: 0.121),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.121, upper: 0.128),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.128, upper: 1.000),
+  },
+  'OnClause_superclassConstraint': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.392),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.392, upper: 1.000),
+  },
+  'ParenthesizedExpression_expression': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.217),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.217, upper: 0.218),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.218, upper: 0.220),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.220, upper: 0.223),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.223, upper: 0.225),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.225, upper: 0.230),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.230, upper: 0.276),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.276, upper: 0.333),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.333, upper: 0.516),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.516, upper: 0.730),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.730, upper: 1.000),
+  },
+  'PrefixExpression_!_operand': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.063),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.063, upper: 0.094),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.094, upper: 0.142),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.142, upper: 0.330),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.330, upper: 0.584),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.584, upper: 1.000),
+  },
+  'PrefixExpression_++_operand': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.035),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.035, upper: 0.123),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.123, upper: 0.351),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.351, upper: 1.000),
+  },
+  'PrefixExpression_--_operand': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.063),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.063, upper: 0.313),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.313, upper: 0.625),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.625, upper: 1.000),
+  },
+  'PrefixExpression_-_operand': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.810),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.810, upper: 0.813),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.813, upper: 0.820),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.820, upper: 0.841),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.841, upper: 0.866),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.866, upper: 0.925),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.925, upper: 1.000),
+  },
+  'PrefixExpression_~_operand': {
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.000, upper: 1.000),
+  },
+  'PropertyAccess_propertyName': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.002),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.002, upper: 0.104),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.104, upper: 1.000),
+  },
+  'ReturnStatement_expression': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.242),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.242, upper: 0.242),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.242, upper: 0.245),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.245, upper: 0.252),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.252, upper: 0.269),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.269, upper: 0.294),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.294, upper: 0.346),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.346, upper: 0.403),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.403, upper: 0.464),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.464, upper: 0.561),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.561, upper: 1.000),
+  },
+  'SetOrMapLiteral_element': {
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.974),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.974, upper: 0.974),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.974, upper: 0.974),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.974, upper: 0.974),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.974, upper: 0.974),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.974, upper: 0.978),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.978, upper: 0.983),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.983, upper: 0.991),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.991, upper: 1.000),
+  },
+  'ShowCombinator_shownName': {
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.000, upper: 0.005),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.005, upper: 0.032),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.032, upper: 0.212),
+    ElementKind.TOP_LEVEL_VARIABLE:
+        ProbabilityRange(lower: 0.212, upper: 0.561),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.561, upper: 1.000),
+  },
+  'SpreadElement_expression': {
+    ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.332),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.332, upper: 0.347),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.347, upper: 0.376),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.376, upper: 0.443),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.443, upper: 0.531),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.531, upper: 0.631),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.631, upper: 0.734),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.734, upper: 1.000),
+  },
+  'Statement': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.600),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.600, upper: 0.600),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.600, upper: 0.600),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.600, upper: 0.601),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.601, upper: 0.601),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.601, upper: 0.603),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.603, upper: 0.623),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.623, upper: 0.666),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.666, upper: 0.716),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.716, upper: 0.774),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.774, upper: 0.846),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.846, upper: 0.919),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.919, upper: 1.000),
+  },
+  'SwitchCase_expression': {
+    ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.541),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.541, upper: 0.677),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.677, upper: 1.000),
+  },
+  'SwitchMember_statement': {
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.691),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.691, upper: 0.691),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.691, upper: 0.697),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.697, upper: 0.708),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.708, upper: 0.719),
+    ElementKind.SETTER: ProbabilityRange(lower: 0.719, upper: 0.733),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.733, upper: 0.748),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.748, upper: 0.765),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.765, upper: 1.000),
+  },
+  'SwitchStatement_expression': {
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.009),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.009, upper: 0.011),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.011, upper: 0.015),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.015, upper: 0.030),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.030, upper: 0.211),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.211, upper: 0.504),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.504, upper: 1.000),
+  },
+  'ThrowExpression_expression': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.833),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.833, upper: 0.834),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.834, upper: 0.836),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.836, upper: 1.000),
+  },
+  'TypeArgumentList_argument': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.021),
+    ElementKind.FUNCTION_TYPE_ALIAS:
+        ProbabilityRange(lower: 0.021, upper: 0.024),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.024, upper: 0.031),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.031, upper: 0.039),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.039, upper: 0.053),
+    ElementKind.UNKNOWN: ProbabilityRange(lower: 0.053, upper: 0.163),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.163, upper: 1.000),
+  },
+  'TypeParameter_bound': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.016),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.016, upper: 0.039),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.039, upper: 1.000),
+  },
+  'VariableDeclaration_initializer': {
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.452),
+    ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.452, upper: 0.452),
+    ElementKind.PREFIX: ProbabilityRange(lower: 0.452, upper: 0.456),
+    ElementKind.ENUM: ProbabilityRange(lower: 0.456, upper: 0.460),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.460, upper: 0.472),
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.472, upper: 0.497),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.497, upper: 0.561),
+    ElementKind.CLASS: ProbabilityRange(lower: 0.561, upper: 0.630),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.630, upper: 0.712),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.712, upper: 0.794),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.794, upper: 1.000),
+  },
+  'WhileStatement_body': {
+    ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.985),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.985, upper: 1.000),
+  },
+  'WhileStatement_condition': {
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.083),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.083, upper: 0.109),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.109, upper: 1.000),
+  },
+  'WithClause_mixinType': {
+    ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.280),
+    ElementKind.MIXIN: ProbabilityRange(lower: 0.280, upper: 1.000),
+  },
+  'YieldStatement_expression': {
+    ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.065),
+    ElementKind.GETTER: ProbabilityRange(lower: 0.065, upper: 0.086),
+    ElementKind.PARAMETER: ProbabilityRange(lower: 0.086, upper: 0.122),
+    ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.122, upper: 0.161),
+    ElementKind.METHOD: ProbabilityRange(lower: 0.161, upper: 0.309),
+    ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.309, upper: 1.000),
+  },
+};
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 2ef8b70..c836fb5 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
@@ -7,13 +7,9 @@
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/visitor.dart';
-import 'package:meta/meta.dart';
 
 /// A contributor that produces suggestions based on the static members of a
 /// given class, enum, or extension. More concretely, this class produces
@@ -22,132 +18,54 @@
 class StaticMemberContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
+    if (request.libraryElement == null) {
+      // Gracefully degrade if the library could not be determined, such as a
+      // detached part file or source change.
+      // TODO(brianwilkerson) Consider testing for this before invoking _any_ of
+      //  the contributors.
+      return const <CompletionSuggestion>[];
+    }
     var targetId = request.dotTarget;
     if (targetId is Identifier && !request.target.isCascade) {
-      var elem = targetId.staticElement;
-      if (elem is ClassElement || elem is ExtensionElement) {
-        if (request.libraryElement == null) {
-          // Gracefully degrade if the library could not be determined, such as
-          // a detached part file or source change.
-          return const <CompletionSuggestion>[];
+      var element = targetId.staticElement;
+      if (element is ClassElement) {
+        for (var accessor in element.accessors) {
+          if (accessor.isStatic) {
+            builder.suggestAccessor(accessor, inheritanceDistance: -1.0);
+          }
         }
-        var builder = _SuggestionBuilder(request);
-        elem.accept(builder);
-        return builder.suggestions;
+        for (var constructor in element.constructors) {
+          builder.suggestConstructor(constructor, hasClassName: true);
+        }
+        for (var field in element.fields) {
+          if (field.isStatic && (!field.isSynthetic || element.isEnum)) {
+            builder.suggestField(field, inheritanceDistance: -1.0);
+          }
+        }
+        for (var method in element.methods) {
+          if (method.isStatic) {
+            builder.suggestMethod(method, inheritanceDistance: -1.0);
+          }
+        }
+      } else if (element is ExtensionElement) {
+        for (var accessor in element.accessors) {
+          if (accessor.isStatic) {
+            builder.suggestAccessor(accessor, inheritanceDistance: -1.0);
+          }
+        }
+        for (var field in element.fields) {
+          if (field.isStatic) {
+            builder.suggestField(field, inheritanceDistance: -1.0);
+          }
+        }
+        for (var method in element.methods) {
+          if (method.isStatic) {
+            builder.suggestMethod(method, inheritanceDistance: -1.0);
+          }
+        }
       }
     }
     return const <CompletionSuggestion>[];
   }
 }
-
-/// This class visits elements in a class or extension and provides suggestions
-/// based on the visible static members in that class.
-class _SuggestionBuilder extends SimpleElementVisitor<void> {
-  /// Information about the completion being requested.
-  final DartCompletionRequest request;
-
-  /// A collection of completion suggestions.
-  final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-
-  /// Initialize a newly created suggestion builder.
-  _SuggestionBuilder(this.request);
-
-  @override
-  void visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  void visitConstructorElement(ConstructorElement element) {
-    _addSuggestion(element, element.returnType);
-  }
-
-  @override
-  void visitExtensionElement(ExtensionElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  void visitFieldElement(FieldElement element) {
-    if (element.isStatic) {
-      _addSuggestion(element, element.type);
-    }
-  }
-
-  @override
-  void visitMethodElement(MethodElement element) {
-    if (element.isStatic && !element.isOperator) {
-      _addSuggestion(element, element.returnType);
-    }
-  }
-
-  @override
-  void visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (element.isStatic) {
-      _addSuggestion(element, element.returnType);
-    }
-  }
-
-  /// Add a suggestion based on the given [element].
-  void _addSuggestion(Element element, DartType elementType) {
-    if (element.isPrivate) {
-      if (element.library != request.libraryElement) {
-        // Don't suggest private members for imported libraries.
-        return;
-      }
-    }
-    if (element.isSynthetic) {
-      if (element is PropertyAccessorElement ||
-          element is FieldElement && !_isSpecialEnumField(element)) {
-        return;
-      }
-    }
-    var completion = element.displayName;
-    if (completion == null || completion.isEmpty) {
-      return;
-    }
-    var relevance = DART_RELEVANCE_DEFAULT;
-    var useNewRelevance = request.useNewRelevance;
-    if (useNewRelevance) {
-      var contextType = request.featureComputer
-          .contextTypeFeature(request.contextType, elementType);
-      var hasDeprecated = request.featureComputer.hasDeprecatedFeature(element);
-      relevance = _computeRelevance(
-          contextType: contextType, hasDeprecated: hasDeprecated);
-    }
-    var suggestion = createSuggestion(element,
-        completion: completion,
-        relevance: relevance,
-        useNewRelevance: useNewRelevance);
-    if (suggestion != null) {
-      suggestions.add(suggestion);
-    }
-  }
-
-  /// Compute a relevance value from the given feature scores:
-  /// - [contextType] is higher if the type of the element matches the context
-  ///   type,
-  /// - [hasDeprecated] is higher if the element is not deprecated,
-  /// - [inheritanceDistance] is higher if the element is defined closer to the
-  ///   target type,
-  /// - [startsWithDollar] is higher if the element's name doe _not_ start with
-  ///   a dollar sign, and
-  /// - [superMatches] is higher if the element is being invoked through `super`
-  ///   and the element's name matches the name of the enclosing method.
-  int _computeRelevance(
-      {@required double contextType, @required double hasDeprecated}) {
-    var score = weightedAverage([contextType, hasDeprecated], [1.0, 0.5]);
-    return toRelevance(score, Relevance.member);
-  }
-
-  /// Determine whether the [element] is one of the synthetic enum accessors
-  /// for which we should generate a suggestion.
-  bool _isSpecialEnumField(FieldElement element) {
-    var parent = element.enclosingElement;
-    if (parent is ClassElement && parent.isEnum) {
-      return element.name == 'values';
-    }
-    return false;
-  }
-}
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 0831608..e8eb817 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
@@ -4,6 +4,7 @@
 
 import 'dart:collection';
 
+import 'package:analysis_server/src/computer/computer_hover.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
@@ -12,18 +13,23 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analysis_server/src/utilities/flutter.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/visitor.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/util/comment.dart';
 import 'package:meta/meta.dart';
 
-/// Return a suggestion based upon the given element or `null` if a suggestion
+/// Return a suggestion based on the given [element], or `null` if a suggestion
 /// is not appropriate for the given element.
-CompletionSuggestion createSuggestion(Element element,
+CompletionSuggestion createSuggestion(
+    DartCompletionRequest request, Element element,
     {String completion,
+    protocol.ElementKind elementKind,
     CompletionSuggestionKind kind,
-    int relevance = DART_RELEVANCE_DEFAULT,
-    bool useNewRelevance = false}) {
+    int relevance = DART_RELEVANCE_DEFAULT}) {
   if (element == null) {
     return null;
   }
@@ -32,20 +38,25 @@
     return null;
   }
   completion ??= element.displayName;
-  kind ??= CompletionSuggestionKind.INVOCATION;
-  var isDeprecated = element.hasDeprecated;
-  if (!useNewRelevance && isDeprecated) {
-    relevance = DART_RELEVANCE_LOW;
+  if (completion == null || completion.isEmpty) {
+    return null;
   }
-  var suggestion = CompletionSuggestion(
-      kind, relevance, completion, completion.length, 0, isDeprecated, false);
+  kind ??= CompletionSuggestionKind.INVOCATION;
+  var suggestion = CompletionSuggestion(kind, relevance, completion,
+      completion.length, 0, element.hasOrInheritsDeprecated, false);
 
   // Attach docs.
-  var doc = getDartDocPlainText(element.documentationComment);
-  suggestion.docComplete = doc;
-  suggestion.docSummary = getDartDocSummary(doc);
+  var doc = DartUnitHoverComputer.computeDocumentation(
+      request.dartdocDirectiveInfo, element);
+  if (doc != null) {
+    suggestion.docComplete = doc;
+    suggestion.docSummary = getDartDocSummary(doc);
+  }
 
   suggestion.element = protocol.convertElement(element);
+  if (elementKind != null) {
+    suggestion.element.kind = elementKind;
+  }
   var enclosingElement = element.enclosingElement;
   if (enclosingElement is ClassElement) {
     suggestion.declaringType = enclosingElement.displayName;
@@ -96,11 +107,13 @@
   /// Return the kind of suggestions that should be built.
   CompletionSuggestionKind get kind;
 
+  /// Return the completion request for which suggestions are being built.
+  DartCompletionRequest get request;
+
   /// Add a suggestion based upon the given element.
   CompletionSuggestion addSuggestion(Element element,
       {String prefix,
       int relevance = DART_RELEVANCE_DEFAULT,
-      bool useNewRelevance = false,
       String elementCompletion}) {
     if (element.isPrivate) {
       if (element.library != containingLibrary) {
@@ -118,11 +131,8 @@
     if (completion == null || completion.isEmpty) {
       return null;
     }
-    var suggestion = createSuggestion(element,
-        completion: completion,
-        kind: kind,
-        relevance: relevance,
-        useNewRelevance: useNewRelevance);
+    var suggestion = createSuggestion(request, element,
+        completion: completion, kind: kind, relevance: relevance);
     if (suggestion != null) {
       if (element.isSynthetic && element is PropertyAccessorElement) {
         String cacheKey;
@@ -165,121 +175,6 @@
   }
 }
 
-/// This class creates suggestions based on top-level elements.
-class LibraryElementSuggestionBuilder extends SimpleElementVisitor<void>
-    with ElementSuggestionBuilder {
-  /// The completion request for which suggestions are being built.
-  final DartCompletionRequest request;
-
-  @override
-  final CompletionSuggestionKind kind;
-
-  final bool typesOnly;
-
-  final bool instCreation;
-
-  /// Return `true` if the new relevance scores should be produced.
-  final bool useNewRelevance;
-
-  LibraryElementSuggestionBuilder(
-      this.request, this.kind, this.typesOnly, this.instCreation)
-      : useNewRelevance = request.useNewRelevance;
-
-  @override
-  LibraryElement get containingLibrary => request.libraryElement;
-
-  @override
-  void visitClassElement(ClassElement element) {
-    if (instCreation) {
-      element.visitChildren(this);
-    } else {
-      // TODO(brianwilkerson) Determine whether this should be based on features
-      //  (such as the kind of the element) or a constant.
-      var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
-      addSuggestion(element,
-          relevance: relevance, useNewRelevance: useNewRelevance);
-    }
-  }
-
-  @override
-  void visitConstructorElement(ConstructorElement element) {
-    if (instCreation) {
-      var classElem = element.enclosingElement;
-      if (classElem != null) {
-        var prefix = classElem.name;
-        if (prefix != null && prefix.isNotEmpty) {
-          // TODO(brianwilkerson) Determine whether this should be based on features
-          //  (such as the kind of the element) or a constant.
-          var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
-          addSuggestion(element,
-              prefix: prefix,
-              relevance: relevance,
-              useNewRelevance: useNewRelevance);
-        }
-      }
-    }
-  }
-
-  @override
-  void visitExtensionElement(ExtensionElement element) {
-    if (!instCreation) {
-      // TODO(brianwilkerson) Determine whether this should be based on features
-      //  (such as the kind of the element) or a constant.
-      var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
-      addSuggestion(element,
-          relevance: relevance, useNewRelevance: useNewRelevance);
-    }
-  }
-
-  @override
-  void visitFunctionElement(FunctionElement element) {
-    if (!typesOnly) {
-      int relevance;
-      if (useNewRelevance) {
-        // TODO(brianwilkerson) Determine whether this should be based on
-        //  features (such as the kind of the element) or a constant.
-        relevance = element.library == containingLibrary ? 800 : 750;
-      } else {
-        relevance = element.library == containingLibrary
-            ? DART_RELEVANCE_LOCAL_FUNCTION
-            : DART_RELEVANCE_DEFAULT;
-      }
-      addSuggestion(element,
-          relevance: relevance, useNewRelevance: useNewRelevance);
-    }
-  }
-
-  @override
-  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    if (!instCreation) {
-      // TODO(brianwilkerson) Determine whether this should be based on features
-      //  (such as the kind of the element) or a constant.
-      var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
-      addSuggestion(element,
-          relevance: relevance, useNewRelevance: useNewRelevance);
-    }
-  }
-
-  @override
-  void visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (!typesOnly) {
-      var variable = element.variable;
-      int relevance;
-      if (useNewRelevance) {
-        // TODO(brianwilkerson) Determine whether this should be based on
-        //  features (such as the kind of the element) or a constant.
-        relevance = variable.library == containingLibrary ? 800 : 750;
-      } else {
-        relevance = variable.library == containingLibrary
-            ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
-            : DART_RELEVANCE_DEFAULT;
-      }
-      addSuggestion(variable,
-          relevance: relevance, useNewRelevance: useNewRelevance);
-    }
-  }
-}
-
 /// This class provides suggestions based upon the visible instance members in
 /// an interface type.
 class MemberSuggestionBuilder {
@@ -302,6 +197,9 @@
   /// The request for which suggestions are being built.
   final DartCompletionRequest request;
 
+  /// The builder used to build the suggestions.
+  final SuggestionBuilder builder;
+
   /// Map indicating, for each possible completion identifier, whether we have
   /// already generated completions for a getter, setter, or both.  The "both"
   /// case also handles the case where have generated a completion for a method
@@ -311,152 +209,36 @@
   /// compared.
   final Map<String, int> _completionTypesGenerated = HashMap<String, int>();
 
-  /// A map from a completion identifier to a completion suggestion.
-  final Map<String, CompletionSuggestion> _suggestionMap =
-      <String, CompletionSuggestion>{};
+  MemberSuggestionBuilder(this.request, this.builder);
 
-  MemberSuggestionBuilder(this.request);
-
-  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
-
-  /// Add the given completion [suggestion].
-  void addCompletionSuggestion(CompletionSuggestion suggestion) {
-    _suggestionMap[suggestion.completion] = suggestion;
-  }
-
-  /// Add a suggestion for the given [method].
-  CompletionSuggestion addSuggestionForAccessor(
+  /// Add a suggestion for the given [accessor].
+  void addSuggestionForAccessor(
       {@required PropertyAccessorElement accessor,
-      String containingMethodName,
       @required double inheritanceDistance}) {
-    int oldRelevance() {
-      if (accessor.hasDeprecated) {
-        return DART_RELEVANCE_LOW;
+    if (accessor.isAccessibleIn(request.libraryElement)) {
+      var member = accessor.isSynthetic ? accessor.variable : accessor;
+      if (_shouldAddSuggestion(member)) {
+        builder.suggestAccessor(accessor,
+            inheritanceDistance: inheritanceDistance);
       }
-      var identifier = accessor.displayName;
-      if (identifier != null && identifier.startsWith(r'$')) {
-        // Decrease relevance of suggestions starting with $
-        // https://github.com/dart-lang/sdk/issues/27303
-        return DART_RELEVANCE_LOW;
-      }
-      return DART_RELEVANCE_DEFAULT;
     }
-
-    if (!accessor.isAccessibleIn(request.libraryElement)) {
-      // Don't suggest private members from imported libraries.
-      return null;
-    }
-    if (accessor.isSynthetic) {
-      // Avoid visiting a field twice. All fields induce a getter, but only
-      // non-final fields induce a setter, so we don't add a suggestion for a
-      // synthetic setter.
-      if (accessor.isGetter) {
-        var variable = accessor.variable;
-        int relevance;
-        var useNewRelevance = request.useNewRelevance;
-        if (useNewRelevance) {
-          var featureComputer = request.featureComputer;
-          var contextType = featureComputer.contextTypeFeature(
-              request.contextType, variable.type);
-          var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
-          var startsWithDollar =
-              featureComputer.startsWithDollarFeature(accessor.name);
-          var superMatches = featureComputer.superMatchesFeature(
-              containingMethodName, accessor.name);
-          relevance = _computeRelevance(
-              contextType: contextType,
-              hasDeprecated: hasDeprecated,
-              inheritanceDistance: inheritanceDistance,
-              startsWithDollar: startsWithDollar,
-              superMatches: superMatches);
-        } else {
-          relevance = oldRelevance();
-        }
-        return _addSuggestion(variable, relevance, useNewRelevance);
-      }
-    } else {
-      var type =
-          accessor.isGetter ? accessor.returnType : accessor.parameters[0].type;
-      int relevance;
-      var useNewRelevance = request.useNewRelevance;
-      if (useNewRelevance) {
-        var featureComputer = request.featureComputer;
-        var contextType =
-            featureComputer.contextTypeFeature(request.contextType, type);
-        var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
-        var startsWithDollar =
-            featureComputer.startsWithDollarFeature(accessor.name);
-        var superMatches = featureComputer.superMatchesFeature(
-            containingMethodName, accessor.name);
-        relevance = _computeRelevance(
-            contextType: contextType,
-            hasDeprecated: hasDeprecated,
-            inheritanceDistance: inheritanceDistance,
-            startsWithDollar: startsWithDollar,
-            superMatches: superMatches);
-      } else {
-        relevance = oldRelevance();
-      }
-      return _addSuggestion(accessor, relevance, useNewRelevance);
-    }
-    return null;
   }
 
   /// Add a suggestion for the given [method].
-  CompletionSuggestion addSuggestionForMethod(
+  void addSuggestionForMethod(
       {@required MethodElement method,
-      String containingMethodName,
       CompletionSuggestionKind kind,
       @required double inheritanceDistance}) {
-    int oldRelevance() {
-      if (method.hasDeprecated) {
-        return DART_RELEVANCE_LOW;
-      } else if (method.name == containingMethodName) {
-        // Boost the relevance of a super expression calling a method of the
-        // same name as the containing method.
-        return DART_RELEVANCE_HIGH;
-      }
-      var identifier = method.displayName;
-      if (identifier != null && identifier.startsWith(r'$')) {
-        // Decrease relevance of suggestions starting with $
-        // https://github.com/dart-lang/sdk/issues/27303
-        return DART_RELEVANCE_LOW;
-      }
-      return DART_RELEVANCE_DEFAULT;
+    if (method.isAccessibleIn(request.libraryElement) &&
+        _shouldAddSuggestion(method)) {
+      builder.suggestMethod(method,
+          kind: kind, inheritanceDistance: inheritanceDistance);
     }
-
-    if (!method.isAccessibleIn(request.libraryElement)) {
-      // Don't suggest private members from imported libraries.
-      return null;
-    }
-    int relevance;
-    var useNewRelevance = request.useNewRelevance;
-    if (useNewRelevance) {
-      var featureComputer = request.featureComputer;
-      var contextType = featureComputer.contextTypeFeature(
-          request.contextType, method.returnType);
-      var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
-      var startsWithDollar =
-          featureComputer.startsWithDollarFeature(method.name);
-      var superMatches = featureComputer.superMatchesFeature(
-          containingMethodName, method.name);
-      relevance = _computeRelevance(
-          contextType: contextType,
-          hasDeprecated: hasDeprecated,
-          inheritanceDistance: inheritanceDistance,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
-    } else {
-      relevance = oldRelevance();
-    }
-    return _addSuggestion(method, relevance, useNewRelevance, kind: kind);
   }
 
-  /// Add a suggestion for the given [element] with the given [relevance],
-  /// provided that it is not shadowed by a previously added suggestion.
-  CompletionSuggestion _addSuggestion(
-      Element element, int relevance, bool useNewRelevance,
-      {CompletionSuggestionKind kind}) {
+  /// Return `true` if a suggestion for the given [element] should be created.
+  bool _shouldAddSuggestion(Element element) {
+    // TODO(brianwilkerson) Consider moving this into SuggestionBuilder.
     var identifier = element.displayName;
 
     var alreadyGenerated = _completionTypesGenerated.putIfAbsent(
@@ -464,7 +246,7 @@
     if (element is MethodElement) {
       // Anything shadows a method.
       if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
-        return null;
+        return false;
       }
       _completionTypesGenerated[identifier] =
           _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
@@ -472,13 +254,13 @@
       if (element.isGetter) {
         // Getters, fields, and methods shadow a getter.
         if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
-          return null;
+          return false;
         }
         _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
       } else {
         // Setters, fields, and methods shadow a setter.
         if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
-          return null;
+          return false;
         }
         _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
       }
@@ -486,21 +268,655 @@
       // Fields and methods shadow a field.  A getter/setter pair shadows a
       // field, but a getter or setter by itself doesn't.
       if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
-        return null;
+        return false;
       }
       _completionTypesGenerated[identifier] =
           _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
     } else {
       // Unexpected element type; skip it.
       assert(false);
+      return false;
+    }
+    return true;
+  }
+}
+
+/// An object used to build a list of suggestions in response to a single
+/// completion request.
+class SuggestionBuilder {
+  /// The completion request for which suggestions are being built.
+  final DartCompletionRequest request;
+
+  /// A map from a completion identifier to a completion suggestion.
+  final Map<String, CompletionSuggestion> _suggestionMap =
+      <String, CompletionSuggestion>{};
+
+  /// A flag indicating whether a suggestion should replace any earlier
+  /// suggestions for the same completion (`true`) or whether earlier
+  /// suggestions should take priority over more recent suggestions.
+  // TODO(brianwilkerson) Attempt to convert the contributors so that a single
+  //  approach is followed.
+  bool laterReplacesEarlier = true;
+
+  /// A flag indicating whether the [_cachedContainingMemberName] has been
+  /// computed.
+  bool _hasContainingMemberName = false;
+
+  /// The name of the member containing the completion location, or `null` if
+  /// either the completion location isn't within a member, the target of the
+  /// completion isn't `super`, or the name of the member hasn't yet been
+  /// computed. In the latter case, [_hasContainingMemberName] will be `false`.
+  String _cachedContainingMemberName;
+
+  /// A flag indicating whether the [_cachedContextType] has been computed.
+  bool _hasContextType = false;
+
+  /// The context type associated with the completion location, or `null` if
+  /// either the location doesn't have a context type, or the context type
+  /// hasn't yet been computed. In the latter case, [_hasContextType] will be
+  /// `false`.
+  DartType _cachedContextType;
+
+  /// The cached instance of the flutter utilities, or `null` if it hasn't been
+  /// created yet.
+  Flutter _flutter;
+
+  /// Initialize a newly created suggestion builder to build suggestions for the
+  /// given [request].
+  SuggestionBuilder(this.request);
+
+  /// Return an object that can answer questions about Flutter code based on the
+  /// flavor of Flutter being used.
+  Flutter get flutter => _flutter ??= Flutter.of(request.result);
+
+  /// Return an iterable that can be used to access the completion suggestions
+  /// that have been built.
+  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
+  /// Return the name of the member containing the completion location, or
+  /// `null` if the completion location isn't within a member or if the target
+  /// of the completion isn't `super`.
+  String get _containingMemberName {
+    if (!_hasContainingMemberName) {
+      _hasContainingMemberName = true;
+      if (request.dotTarget is SuperExpression) {
+        var containingMethod = request.target.containingNode
+            .thisOrAncestorOfType<MethodDeclaration>();
+        if (containingMethod != null) {
+          var id = containingMethod.name;
+          if (id != null) {
+            _cachedContainingMemberName = id.name;
+          }
+        }
+      }
+    }
+    return _cachedContainingMemberName;
+  }
+
+  /// Return the context type associated with the completion location, or `null`
+  /// if the location doesn't have a context type.
+  DartType get _contextType {
+    if (!_hasContextType) {
+      _hasContextType = true;
+      _cachedContextType = request.featureComputer
+          .computeContextType(request.target.containingNode);
+    }
+    return _cachedContextType;
+  }
+
+  /// Add a suggestion for an [accessor] declared within a class or extension.
+  /// If the accessor is being invoked with a target of `super`, then the
+  /// [containingMemberName] should be the name of the member containing the
+  /// invocation. The [inheritanceDistance] is the value of the inheritance
+  /// distance feature computed for the accessor (or `-1.0` if the accessor is a
+  /// static accessor).
+  void suggestAccessor(PropertyAccessorElement accessor,
+      {@required double inheritanceDistance}) {
+    assert(accessor.enclosingElement is ClassElement ||
+        accessor.enclosingElement is ExtensionElement);
+    if (accessor.isSynthetic) {
+      // Avoid visiting a field twice. All fields induce a getter, but only
+      // non-final fields induce a setter, so we don't add a suggestion for a
+      // synthetic setter.
+      if (accessor.isGetter) {
+        var variable = accessor.variable;
+        if (variable is FieldElement) {
+          suggestField(variable, inheritanceDistance: inheritanceDistance);
+        }
+      }
+    } else {
+      var type =
+          accessor.isGetter ? accessor.returnType : accessor.parameters[0].type;
+      int relevance;
+      if (request.useNewRelevance) {
+        var featureComputer = request.featureComputer;
+        var contextType =
+            featureComputer.contextTypeFeature(request.contextType, type);
+        var elementKind = featureComputer.elementKindFeature(
+            accessor, request.opType.completionLocation);
+        var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+        var startsWithDollar =
+            featureComputer.startsWithDollarFeature(accessor.name);
+        var superMatches = featureComputer.superMatchesFeature(
+            _containingMemberName, accessor.name);
+        relevance = _computeMemberRelevance(
+            contextType: contextType,
+            elementKind: elementKind,
+            hasDeprecated: hasDeprecated,
+            inheritanceDistance: inheritanceDistance,
+            startsWithDollar: startsWithDollar,
+            superMatches: superMatches);
+      } else {
+        relevance = _computeOldMemberRelevance(accessor);
+        if (request.opType.includeReturnValueSuggestions) {
+          relevance =
+              request.opType.returnValueSuggestionsFilter(type, relevance);
+        }
+        if (relevance == null) {
+          return;
+        }
+      }
+      _add(createSuggestion(request, accessor, relevance: relevance));
+    }
+  }
+
+  /// Add a suggestion for a catch [parameter].
+  void suggestCatchParameter(LocalVariableElement parameter) {
+    var variableType = parameter.type;
+    int relevance;
+    if (request.useNewRelevance) {
+      var contextTypeFeature = request.featureComputer
+          .contextTypeFeature(_contextType, variableType);
+      relevance = toRelevance(contextTypeFeature, 800);
+    } else {
+      relevance = _computeOldMemberRelevance(parameter);
+      relevance =
+          request.opType.returnValueSuggestionsFilter(variableType, relevance);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, parameter,
+        elementKind: protocol.ElementKind.PARAMETER, relevance: relevance));
+  }
+
+  /// Add a suggestion for a [classElement]. If a [kind] is provided it will
+  /// be used as the kind for the suggestion.
+  void suggestClass(ClassElement classElement,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance = _computeTopLevelRelevance(classElement,
+          elementType: _instantiateClassElement(classElement));
+    } else if (classElement.hasOrInheritsDeprecated) {
+      relevance = DART_RELEVANCE_LOW;
+    } else {
+      relevance = request.opType.typeNameSuggestionsFilter(
+          _instantiateClassElement(classElement), DART_RELEVANCE_DEFAULT);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, classElement,
+        kind: kind, relevance: relevance));
+  }
+
+  /// Add a suggestion for a [constructor]. If a [kind] is provided it will be
+  /// used as the kind for the suggestion. The flag [hasClassName] should be
+  /// `true` if the completion is occurring after the name of the class and a
+  /// period, and hence should not include the name of the class.
+  void suggestConstructor(ConstructorElement constructor,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+      bool hasClassName = false}) {
+    var classElement = constructor.enclosingElement;
+    if (classElement == null) {
+      return;
+    }
+    var prefix = classElement.name;
+    // TODO(brianwilkerson) It shouldn't be necessary to test for an empty
+    //  prefix.
+    if (prefix == null || prefix.isEmpty) {
+      return;
+    }
+
+    var completion = constructor.displayName;
+    if (!hasClassName && prefix != null && prefix.isNotEmpty) {
+      if (completion == null || completion.isEmpty) {
+        completion = prefix;
+      } else {
+        completion = '$prefix.$completion';
+      }
+    }
+    if (completion == null || completion.isEmpty) {
       return null;
     }
-    var suggestion = createSuggestion(element,
-        kind: kind, relevance: relevance, useNewRelevance: useNewRelevance);
-    if (suggestion != null) {
-      addCompletionSuggestion(suggestion);
+
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance = _computeTopLevelRelevance(constructor);
+    } else {
+      relevance = constructor.hasOrInheritsDeprecated
+          ? DART_RELEVANCE_LOW
+          : DART_RELEVANCE_DEFAULT;
     }
-    return suggestion;
+
+    _add(createSuggestion(request, constructor,
+        completion: completion, kind: kind, relevance: relevance));
+  }
+
+  /// Add a suggestion for a top-level [element]. If a [kind] is provided it
+  /// will be used as the kind for the suggestion.
+  void suggestElement(Element element,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    if (element is ClassElement) {
+      suggestClass(element, kind: kind);
+    } else if (element is ConstructorElement) {
+      suggestConstructor(element, kind: kind);
+    } else if (element is ExtensionElement) {
+      suggestExtension(element, kind: kind);
+    } else if (element is FunctionElement &&
+        element.enclosingElement is CompilationUnitElement) {
+      suggestTopLevelFunction(element, kind: kind);
+    } else if (element is FunctionTypeAliasElement) {
+      suggestFunctionTypeAlias(element, kind: kind);
+    } else if (element is PropertyAccessorElement &&
+        element.enclosingElement is CompilationUnitElement) {
+      suggestTopLevelPropertyAccessor(element, kind: kind);
+    } else {
+      throw ArgumentError('Cannot suggest a ${element.runtimeType}');
+    }
+  }
+
+  /// Add a suggestion for an enum [constant].
+  void suggestEnumConstant(FieldElement constant) {
+    var constantName = constant.name;
+    var enumElement = constant.enclosingElement;
+    var enumName = enumElement.name;
+    var completion = '$enumName.$constantName';
+
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance =
+          _computeTopLevelRelevance(constant, elementType: constant.type);
+    } else if (constant.hasOrInheritsDeprecated) {
+      relevance = DART_RELEVANCE_LOW;
+    } else {
+      relevance = request.opType.returnValueSuggestionsFilter(
+          _instantiateClassElement(enumElement), DART_RELEVANCE_DEFAULT);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, constant,
+        completion: completion, relevance: relevance));
+  }
+
+  /// Add a suggestion for an [extension]. If a [kind] is provided it will be
+  /// used as the kind for the suggestion.
+  void suggestExtension(ExtensionElement extension,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance = _computeTopLevelRelevance(extension,
+          elementType: extension.extendedType);
+    } else {
+      relevance = extension.hasOrInheritsDeprecated
+          ? DART_RELEVANCE_LOW
+          : DART_RELEVANCE_DEFAULT;
+    }
+
+    _add(
+        createSuggestion(request, extension, kind: kind, relevance: relevance));
+  }
+
+  /// Add a suggestion for a [field]. If the field is being referenced with a
+  /// target of `super`, then the [containingMemberName] should be the name of
+  /// the member containing the reference. The [inheritanceDistance] is the
+  /// value of the inheritance distance feature computed for the field (or
+  /// `-1.0` if the field is a static field).
+  void suggestField(FieldElement field,
+      {@required double inheritanceDistance}) {
+    int relevance;
+    if (request.useNewRelevance) {
+      var featureComputer = request.featureComputer;
+      var contextType =
+          featureComputer.contextTypeFeature(request.contextType, field.type);
+      var elementKind = featureComputer.elementKindFeature(
+          field, request.opType.completionLocation);
+      var hasDeprecated = featureComputer.hasDeprecatedFeature(field);
+      var startsWithDollar =
+          featureComputer.startsWithDollarFeature(field.name);
+      var superMatches = featureComputer.superMatchesFeature(
+          _containingMemberName, field.name);
+      relevance = _computeMemberRelevance(
+          contextType: contextType,
+          elementKind: elementKind,
+          hasDeprecated: hasDeprecated,
+          inheritanceDistance: inheritanceDistance,
+          startsWithDollar: startsWithDollar,
+          superMatches: superMatches);
+    } else {
+      relevance = _computeOldMemberRelevance(field);
+      if (request.opType.includeReturnValueSuggestions) {
+        relevance =
+            request.opType.returnValueSuggestionsFilter(field.type, relevance);
+      }
+      if (relevance == null) {
+        return;
+      }
+    }
+    _add(createSuggestion(request, field, relevance: relevance));
+  }
+
+  /// Add a suggestion to reference a [field] in a field formal parameter.
+  void suggestFieldFormalParameter(FieldElement field) {
+    // TODO(brianwilkerson) Add a parameter (`bool includePrefix`) indicating
+    //  whether to include the `this.` prefix in the completion.
+    var relevance = request.useNewRelevance
+        ? Relevance.fieldFormalParameter
+        : DART_RELEVANCE_LOCAL_FIELD;
+
+    _add(createSuggestion(request, field, relevance: relevance));
+  }
+
+  /// Add a suggestion for the `call` method defined on functions.
+  void suggestFunctionCall() {
+    const callString = 'call()';
+    final element = protocol.Element(
+        protocol.ElementKind.METHOD, callString, protocol.Element.makeFlags(),
+        location: null,
+        typeParameters: null,
+        parameters: null,
+        returnType: 'void');
+    _add(CompletionSuggestion(
+      CompletionSuggestionKind.INVOCATION,
+      request.useNewRelevance ? Relevance.callFunction : DART_RELEVANCE_HIGH,
+      callString,
+      callString.length,
+      0,
+      false,
+      false,
+      displayText: callString,
+      element: element,
+      returnType: 'void',
+    ));
+  }
+
+  /// Add a suggestion for a [functionTypeAlias]. If a [kind] is provided it
+  /// will be used as the kind for the suggestion.
+  void suggestFunctionTypeAlias(FunctionTypeAliasElement functionTypeAlias,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance = _computeTopLevelRelevance(functionTypeAlias,
+          defaultRelevance: 750,
+          elementType: _instantiateFunctionTypeAlias(functionTypeAlias));
+    } else if (functionTypeAlias.hasOrInheritsDeprecated) {
+      relevance = DART_RELEVANCE_LOW;
+    } else {
+      relevance = functionTypeAlias.library == request.libraryElement
+          ? DART_RELEVANCE_LOCAL_FUNCTION
+          : DART_RELEVANCE_DEFAULT;
+    }
+    _add(createSuggestion(request, functionTypeAlias,
+        kind: kind, relevance: relevance));
+  }
+
+  /// Add a suggestion for the `loadLibrary` [function] associated with a
+  /// prefix.
+  void suggestLoadLibraryFunction(FunctionElement function) {
+    int relevance;
+    if (request.useNewRelevance) {
+      // TODO(brianwilkerson) This might want to use the context type rather
+      //  than a fixed value.
+      relevance = Relevance.loadLibrary;
+    } else {
+      relevance = function.hasOrInheritsDeprecated
+          ? DART_RELEVANCE_LOW
+          : DART_RELEVANCE_DEFAULT;
+    }
+
+    _add(createSuggestion(request, function, relevance: relevance));
+  }
+
+  /// Add a suggestion for a local [variable].
+  void suggestLocalVariable(LocalVariableElement variable) {
+    var variableType = variable.type;
+    int relevance;
+    if (request.useNewRelevance) {
+      // TODO(brianwilkerson) Use the distance to the local variable as
+      //  another feature.
+      var contextTypeFeature = request.featureComputer
+          .contextTypeFeature(_contextType, variableType);
+      relevance = toRelevance(contextTypeFeature, 800);
+    } else {
+      relevance = _computeOldMemberRelevance(variable);
+      relevance =
+          request.opType.returnValueSuggestionsFilter(variableType, relevance);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, variable, relevance: relevance));
+  }
+
+  /// Add a suggestion for a [method]. If the method is being invoked with a
+  /// target of `super`, then the [containingMemberName] should be the name of
+  /// the member containing the invocation. If a [kind] is provided it will be
+  /// used as the kind for the suggestion. The [inheritanceDistance] is the
+  /// value of the inheritance distance feature computed for the method.
+  void suggestMethod(MethodElement method,
+      {CompletionSuggestionKind kind, @required double inheritanceDistance}) {
+    // TODO(brianwilkerson) Refactor callers so that we're passing in the type
+    //  of the target (assuming we don't already have that type available via
+    //  the [request]) and compute the [inheritanceDistance] in this method.
+    int relevance;
+    if (request.useNewRelevance) {
+      var featureComputer = request.featureComputer;
+      var contextType = featureComputer.contextTypeFeature(
+          request.contextType, method.returnType);
+      var elementKind = featureComputer.elementKindFeature(
+          method, request.opType.completionLocation);
+      var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
+      var startsWithDollar =
+          featureComputer.startsWithDollarFeature(method.name);
+      var superMatches = featureComputer.superMatchesFeature(
+          _containingMemberName, method.name);
+      relevance = _computeMemberRelevance(
+          contextType: contextType,
+          elementKind: elementKind,
+          hasDeprecated: hasDeprecated,
+          inheritanceDistance: inheritanceDistance,
+          startsWithDollar: startsWithDollar,
+          superMatches: superMatches);
+    } else {
+      relevance = _computeOldMemberRelevance(method);
+      if (request.opType.includeReturnValueSuggestions) {
+        relevance = request.opType
+            .returnValueSuggestionsFilter(method.returnType, relevance);
+      }
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    var suggestion =
+        createSuggestion(request, method, kind: kind, relevance: relevance);
+    if (suggestion != null) {
+      if (method.name == 'setState' &&
+          flutter.isExactState(method.enclosingElement)) {
+        // TODO(brianwilkerson) Make this more efficient by creating the correct
+        //  suggestion in the first place.
+        // Find the line indentation.
+        var indent = getRequestLineIndent(request);
+
+        // Let the user know that we are going to insert a complete statement.
+        suggestion.displayText = 'setState(() {});';
+
+        // Build the completion and the selection offset.
+        var buffer = StringBuffer();
+        buffer.writeln('setState(() {');
+        buffer.write('$indent  ');
+        suggestion.selectionOffset = buffer.length;
+        buffer.writeln();
+        buffer.write('$indent});');
+        suggestion.completion = buffer.toString();
+
+        // There are no arguments to fill.
+        suggestion.parameterNames = null;
+        suggestion.parameterTypes = null;
+        suggestion.requiredParameterCount = null;
+        suggestion.hasNamedParameters = null;
+      }
+      _add(suggestion);
+    }
+  }
+
+  /// Add a suggestion for a [parameter].
+  void suggestParameter(ParameterElement parameter) {
+    var variableType = parameter.type;
+    int relevance;
+    if (request.useNewRelevance) {
+      // TODO(brianwilkerson) Use the distance to the declaring function as
+      //  another feature.
+      var contextTypeFeature = request.featureComputer
+          .contextTypeFeature(_contextType, variableType);
+      relevance = toRelevance(contextTypeFeature, 800);
+    } else {
+      relevance = _computeOldMemberRelevance(parameter);
+      relevance =
+          request.opType.returnValueSuggestionsFilter(variableType, relevance);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, parameter, relevance: relevance));
+  }
+
+  /// Add a suggestion for a top-level [function]. If a [kind] is provided it
+  /// will be used as the kind for the suggestion.
+  void suggestTopLevelFunction(FunctionElement function,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance =
+          _computeTopLevelRelevance(function, elementType: function.returnType);
+    } else if (function.hasOrInheritsDeprecated) {
+      relevance = DART_RELEVANCE_LOW;
+    } else {
+      relevance = function.library == request.libraryElement
+          ? DART_RELEVANCE_LOCAL_FUNCTION
+          : DART_RELEVANCE_DEFAULT;
+      relevance =
+          request.opType.returnValueSuggestionsFilter(function.type, relevance);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, function, kind: kind, relevance: relevance));
+  }
+
+  /// Add a suggestion for a top-level property [accessor]. If a [kind] is
+  /// provided it will be used as the kind for the suggestion.
+  void suggestTopLevelPropertyAccessor(PropertyAccessorElement accessor,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    assert(accessor.enclosingElement is CompilationUnitElement);
+    if (accessor.isSynthetic) {
+      // Avoid visiting a field twice. All fields induce a getter, but only
+      // non-final fields induce a setter, so we don't add a suggestion for a
+      // synthetic setter.
+      if (accessor.isGetter) {
+        var variable = accessor.variable;
+        if (variable is TopLevelVariableElement) {
+          suggestTopLevelVariable(variable, kind: kind);
+        }
+      }
+    } else {
+      var type =
+          accessor.isGetter ? accessor.returnType : accessor.parameters[0].type;
+      int relevance;
+      if (request.useNewRelevance) {
+        var featureComputer = request.featureComputer;
+        var contextType =
+            featureComputer.contextTypeFeature(request.contextType, type);
+        var elementKind = featureComputer.elementKindFeature(
+            accessor, request.opType.completionLocation);
+        var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+        var startsWithDollar =
+            featureComputer.startsWithDollarFeature(accessor.name);
+        relevance = _computeMemberRelevance(
+            contextType: contextType,
+            elementKind: elementKind,
+            hasDeprecated: hasDeprecated,
+            inheritanceDistance: -1.0,
+            startsWithDollar: startsWithDollar,
+            superMatches: -1.0);
+      } else {
+        relevance = _computeOldMemberRelevance(accessor);
+        if (request.opType.includeReturnValueSuggestions) {
+          relevance =
+              request.opType.returnValueSuggestionsFilter(type, relevance);
+        }
+        if (relevance == null) {
+          return;
+        }
+      }
+      _add(createSuggestion(request, accessor, relevance: relevance));
+    }
+  }
+
+  /// Add a suggestion for a top-level [variable]. If a [kind] is provided it
+  /// will be used as the kind for the suggestion.
+  void suggestTopLevelVariable(TopLevelVariableElement variable,
+      {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+    assert(variable.enclosingElement is CompilationUnitElement);
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance =
+          _computeTopLevelRelevance(variable, elementType: variable.type);
+    } else if (variable.hasOrInheritsDeprecated) {
+      relevance = DART_RELEVANCE_LOW;
+    } else {
+      var type = variable.type;
+      relevance = _computeOldMemberRelevance(variable);
+      relevance = request.opType.returnValueSuggestionsFilter(type, relevance);
+      if (relevance == null) {
+        return;
+      }
+    }
+
+    _add(createSuggestion(request, variable, kind: kind, relevance: relevance));
+  }
+
+  /// Add a suggestion for a type [parameter].
+  void suggestTypeParameter(TypeParameterElement parameter) {
+    int relevance;
+    if (request.useNewRelevance) {
+      relevance = Relevance.typeParameter;
+    } else {
+      relevance = _computeOldMemberRelevance(parameter);
+    }
+
+    _add(createSuggestion(request, parameter,
+        kind: CompletionSuggestionKind.IDENTIFIER, relevance: relevance));
+  }
+
+  /// Add the given [suggestion] if it isn't `null` and if it isn't shadowed by
+  /// a previously added suggestion.
+  void _add(protocol.CompletionSuggestion suggestion) {
+    if (suggestion != null) {
+      if (laterReplacesEarlier) {
+        _suggestionMap[suggestion.completion] = suggestion;
+      } else {
+        _suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
+      }
+    }
   }
 
   /// Compute a relevance value from the given feature scores:
@@ -513,20 +929,23 @@
   ///   a dollar sign, and
   /// - [superMatches] is higher if the element is being invoked through `super`
   ///   and the element's name matches the name of the enclosing method.
-  int _computeRelevance(
+  int _computeMemberRelevance(
       {@required double contextType,
+      @required double elementKind,
       @required double hasDeprecated,
       @required double inheritanceDistance,
       @required double startsWithDollar,
       @required double superMatches}) {
     var score = weightedAverage([
       contextType,
+      elementKind,
       hasDeprecated,
       inheritanceDistance,
       startsWithDollar,
       superMatches
     ], [
       1.0,
+      0.75,
       0.5,
       1.0,
       0.5,
@@ -534,4 +953,99 @@
     ]);
     return toRelevance(score, Relevance.member);
   }
+
+  /// Compute the old relevance score for a member.
+  int _computeOldMemberRelevance(Element member) {
+    if (member.hasOrInheritsDeprecated) {
+      return DART_RELEVANCE_LOW;
+    } else if (member.name == _containingMemberName) {
+      // Boost the relevance of a super expression calling a method of the
+      // same name as the containing method.
+      return DART_RELEVANCE_HIGH;
+    }
+    var identifier = member.displayName;
+    if (identifier != null && identifier.startsWith(r'$')) {
+      // Decrease relevance of suggestions starting with $
+      // https://github.com/dart-lang/sdk/issues/27303
+      return DART_RELEVANCE_LOW;
+    }
+    if (member is LocalVariableElement) {
+      return DART_RELEVANCE_LOCAL_VARIABLE;
+    }
+    if (!member.name.startsWith('_') &&
+        member.library == request.libraryElement) {
+      // Locally declared elements sometimes have a special relevance.
+      if (member is PropertyAccessorElement) {
+        return DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else if (member is FieldElement) {
+        return DART_RELEVANCE_LOCAL_FIELD;
+      } else if (member is FunctionElement) {
+        return DART_RELEVANCE_LOCAL_FUNCTION;
+      } else if (member is MethodElement) {
+        return DART_RELEVANCE_LOCAL_METHOD;
+      } else if (member is ParameterElement) {
+        return DART_RELEVANCE_PARAMETER;
+      } else if (member is TopLevelVariableElement) {
+        return DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+      } else if (member is TypeParameterElement) {
+        return DART_RELEVANCE_TYPE_PARAMETER;
+      }
+    }
+    return DART_RELEVANCE_DEFAULT;
+  }
+
+  /// Return the relevance score for a top-level [element].
+  int _computeTopLevelRelevance(Element element,
+      {int defaultRelevance = 800, DartType elementType}) {
+    // TODO(brianwilkerson) The old relevance computation used a signal based
+    //  on whether the element being suggested was from the same library in
+    //  which completion is being performed. Explore whether that's a useful
+    //  signal.
+    var featureComputer = request.featureComputer;
+    var contextTypeFeature =
+        featureComputer.contextTypeFeature(_contextType, elementType);
+    var elementKind = featureComputer.elementKindFeature(
+        element, request.opType.completionLocation);
+    var hasDeprecated = featureComputer.hasDeprecatedFeature(element);
+    return toRelevance(
+        weightedAverage(
+            [contextTypeFeature, elementKind, hasDeprecated], [1.0, 0.75, 0.2]),
+        defaultRelevance);
+  }
+
+  InterfaceType _instantiateClassElement(ClassElement element) {
+    var typeParameters = element.typeParameters;
+    var typeArguments = const <DartType>[];
+    if (typeParameters.isNotEmpty) {
+      var neverType = request.libraryElement.typeProvider.neverType;
+      typeArguments = List.filled(typeParameters.length, neverType);
+    }
+
+    var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+        ? NullabilitySuffix.none
+        : NullabilitySuffix.star;
+
+    return element.instantiate(
+      typeArguments: typeArguments,
+      nullabilitySuffix: nullabilitySuffix,
+    );
+  }
+
+  FunctionType _instantiateFunctionTypeAlias(FunctionTypeAliasElement element) {
+    var typeParameters = element.typeParameters;
+    var typeArguments = const <DartType>[];
+    if (typeParameters.isNotEmpty) {
+      var neverType = request.libraryElement.typeProvider.neverType;
+      typeArguments = List.filled(typeParameters.length, neverType);
+    }
+
+    var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+        ? NullabilitySuffix.none
+        : NullabilitySuffix.star;
+
+    return element.instantiate(
+      typeArguments: typeArguments,
+      nullabilitySuffix: nullabilitySuffix,
+    );
+  }
 }
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 e43b3bf..1be5e6e 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
@@ -6,13 +6,12 @@
 import 'dart:collection';
 
 import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
+    show CompletionSuggestion;
 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';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart';
 
 /// A contributor that produces suggestions based on the instance members of a
@@ -23,7 +22,7 @@
 class TypeMemberContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var containingLibrary = request.libraryElement;
     // Gracefully degrade if the library could not be determined, such as with a
     // detached part file or source change.
@@ -75,7 +74,6 @@
         }
       }
     }
-    String containingMethodName;
     List<InterfaceType> mixins;
     List<InterfaceType> superclassConstraints;
     if (expression is SuperExpression && type is InterfaceType) {
@@ -83,16 +81,6 @@
       mixins = (type as InterfaceType).mixins;
       superclassConstraints = (type as InterfaceType).superclassConstraints;
       type = (type as InterfaceType).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;
-        }
-      }
     }
     if (type == null || type.isDynamic) {
       // Suggest members from object if target is "dynamic".
@@ -101,14 +89,11 @@
 
     // Build the suggestions.
     if (type is InterfaceType) {
-      var builder = _SuggestionBuilder(request);
-      builder.buildSuggestions(type, containingMethodName,
+      var memberBuilder = _SuggestionBuilder(request, builder);
+      memberBuilder.buildSuggestions(type,
           mixins: mixins, superclassConstraints: superclassConstraints);
-      return builder.suggestions.toList();
-    }
-    if (type is FunctionType) {
-      var builder = _SuggestionBuilder(request);
-      return [builder._createFunctionCallSuggestion()];
+    } else if (type is FunctionType) {
+      builder.suggestFunctionCall();
     }
 
     return const <CompletionSuggestion>[];
@@ -238,12 +223,13 @@
 /// an interface type.
 class _SuggestionBuilder extends MemberSuggestionBuilder {
   /// Initialize a newly created suggestion builder.
-  _SuggestionBuilder(DartCompletionRequest request) : super(request);
+  _SuggestionBuilder(DartCompletionRequest request, SuggestionBuilder builder)
+      : super(request, builder);
 
   /// Return 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,
       {List<InterfaceType> mixins, List<InterfaceType> superclassConstraints}) {
     // Visit all of the types in the class hierarchy, collecting possible
     // completions.  If multiple elements are found that complete to the same
@@ -266,47 +252,21 @@
         // Exclude static methods when completion on an instance.
         if (!method.isStatic) {
           addSuggestionForMethod(
-              method: method,
-              containingMethodName: containingMethodName,
-              inheritanceDistance: inheritanceDistance);
+              method: method, inheritanceDistance: inheritanceDistance);
         }
       }
       for (var accessor in targetType.accessors) {
         if (!accessor.isStatic) {
           addSuggestionForAccessor(
-              accessor: accessor,
-              containingMethodName: containingMethodName,
-              inheritanceDistance: inheritanceDistance);
+              accessor: accessor, inheritanceDistance: inheritanceDistance);
         }
       }
       if (targetType.isDartCoreFunction) {
-        addCompletionSuggestion(_createFunctionCallSuggestion());
+        builder.suggestFunctionCall();
       }
     }
   }
 
-  CompletionSuggestion _createFunctionCallSuggestion() {
-    const callString = 'call()';
-    final element = protocol.Element(
-        protocol.ElementKind.METHOD, callString, protocol.Element.makeFlags(),
-        location: null,
-        typeParameters: null,
-        parameters: null,
-        returnType: 'void');
-    return CompletionSuggestion(
-      CompletionSuggestionKind.INVOCATION,
-      request.useNewRelevance ? Relevance.callFunction : DART_RELEVANCE_HIGH,
-      callString,
-      callString.length,
-      0,
-      false,
-      false,
-      displayText: callString,
-      element: element,
-      returnType: 'void',
-    );
-  }
-
   /// Get a list of [InterfaceType]s that should be searched to find the
   /// possible completions for an object having type [type].
   List<InterfaceType> _getTypeOrdering(InterfaceType type) {
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 245e9d6..cc6bad1 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
@@ -8,6 +8,7 @@
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -25,7 +26,7 @@
 
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var builder = _UriSuggestionBuilder(request);
     request.target.containingNode.accept(builder);
     return builder.suggestions;
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 d6da442..deea96b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -172,21 +172,7 @@
   if (param != null) {
     var type = param.type;
     if (type is InterfaceType && type.isDartCoreList) {
-      String getTypeArgumentsStr() {
-        var elementType = type.typeArguments.single;
-        if (elementType.isDynamic) {
-          return '';
-        } else {
-          var typeArgStr = elementType.getDisplayString(
-            withNullability: false,
-          );
-          return '<$typeArgStr>';
-        }
-      }
-
-      var typeArgumentStr = getTypeArgumentsStr();
-      var text = '$typeArgumentStr[]';
-      return DefaultArgument(text, cursorPosition: text.length - 1);
+      return DefaultArgument('[]', cursorPosition: 1);
     } else if (type is FunctionType) {
       var params = type.parameters
           .map((p) => '${getTypeString(p.type)}${p.name}')
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 a0ee964..b40435c 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
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -16,7 +17,7 @@
 class VariableNameContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
+      DartCompletionRequest request, SuggestionBuilder builder) async {
     var opType = request.opType;
 
     // Collect suggestions from the specific child [AstNode] that contains
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
new file mode 100644
index 0000000..7868f80
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/filtering/fuzzy_matcher.dart
@@ -0,0 +1,507 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:math' as math;
+
+/// Character role in a candidate string.
+enum CharRole {
+  NONE,
+  SEPARATOR,
+  TAIL,
+  UC_TAIL,
+  HEAD,
+}
+
+/// A fuzzy matcher that takes a pattern at construction time, and then can
+/// evaluate how well various strings match this pattern. Together with a score,
+/// it computes a corresponding mapping of pattern characters on the candidate
+/// string, which can be retrieved later by calling `getMatchedRanges`.
+///
+/// A string matches the pattern if every character of the pattern occurs in
+/// the string in the same order as in the pattern, and first letters of
+/// separate words in pattern are aligned with words in the string. Characters
+/// matching the beginning of a word, case-sensitive and just longer matches get
+/// higher scores.
+///
+/// The algorithm takes inspiration from Sublime, VS Code, and IntelliJ and is
+/// tuned to produce visually good results for code completion, navigation, and
+/// all other kinds of element filtering in the UI.
+///
+/// Note: if constructed in filename or symbol matching mode, the matcher
+/// requires that there is at least some match in the last segment of the path
+/// or in the symbol name. In this case, we also prefer reporting sub-matches in
+/// the last segment.
+///
+/// Similar implementations (for reference):
+/// - github.com/Microsoft/vscode/blob/master/src/vs/base/common/filters.ts#L439
+///
+/// Typical usage:
+/// ```dart
+/// var topN = TopN(100);
+/// var matcher = FuzzyMatcher(pattern, FuzzyInput.SYMBOL);
+/// for (var item of completionItems) {
+///   var score = matcher.score(item.title);
+///   if (score > -1) {
+///     var matchRanges = matcher.getMatchedRanges();
+///     topN.push({item, matchRanges}, score);
+///   }
+/// }
+/// // ... use topN.getTopElements();
+/// ```
+class FuzzyMatcher {
+  /// The maximum size of the input scored against the fuzzy matcher. Longer
+  /// inputs will be truncated to this size.
+  static const int maxInputSize = 127;
+
+  /// The maximum size of the pattern used to construct the fuzzy matcher.
+  /// Longer patterns are truncated to this size.
+  static const int maxPatternSize = 63;
+
+  /// The minimum integer score (before normalization).
+  static const int minScore = -10000;
+
+  /// Character types for the first 127 ASCII symbols encoded as a string.
+  ///
+  /// This is:
+  ///   [a-z0-9]  LOWER
+  ///   [A-Z]     UPPER
+  ///   [:./ ]    PUNCT
+  ///   otherwise NONE
+  static const String TYPES =
+      '0000000000000000000000000000000010000000000000112222222222100000'
+      '0333333333333333333333333330000002222222222222222222222222200000';
+
+  /// TODO(brianwilkerson) Use package:charcode.
+  static final int $a = 'a'.codeUnitAt(0);
+  static final int $z = 'z'.codeUnitAt(0);
+
+  /// The (potentially truncated) pattern to be matched.
+  String pattern;
+
+  /// The style of match to be performed.
+  MatchStyle matchStyle;
+
+  /// The lowercase version of the pattern.
+  String patternLower;
+
+  /// The first three characters of the lowercase version of the pattern.
+  String patternShort;
+
+  /// The length of the last matched candidate.
+  int lastCandidateLen = 0;
+
+  /// A flag indicating whether the last matched candidate matched the pattern.
+  bool lastCandidateMatched = false;
+
+  /// MatchStyle.FILENAME only: For the last matched candidate, the length of
+  /// text that was trimmed from the start of the string.
+  int lastCandidatePrefixTrimmedLen = 0;
+
+  /// Dynamic programming table.
+  ///
+  /// We use a 3-dimensional dynamic programming table, with the 3-rd dimension
+  /// telling us whether the last character matched (true or false). The table
+  /// for matched characters is stored adjacent to the table for unmatched
+  /// characters to avoid too nested arrays.
+  ///
+  /// 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;
+
+  /// The offset of the "previous symbol matched" table on the pattern axis.
+  int matchesLayerOffset;
+
+  /// 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;
+
+  /// A flag indicating whether scoring should be case-sensitive. Mix-case
+  /// patterns turn on case-sensitive scoring.
+  bool caseSensitive;
+
+  /// Normalizes scores for the pattern length.
+  double scoreScale;
+
+  /// Initialize a newly created matcher to match the [pattern] using the given
+  /// [matchStyle].
+  FuzzyMatcher(this.pattern, {this.matchStyle = MatchStyle.TEXT}) {
+    if (pattern.length > maxPatternSize) {
+      pattern = pattern.substring(0, maxPatternSize);
+    }
+    patternLower = pattern.toLowerCase();
+    caseSensitive = pattern != patternLower;
+    if (patternLower.length > 3) {
+      patternShort = patternLower.substring(0, 3);
+    } else {
+      patternShort = patternLower;
+    }
+    matchesLayerOffset = pattern.length + 1;
+
+    table = [];
+    for (var i = 0; i <= maxInputSize; i++) {
+      table.add(List.filled(2 * matchesLayerOffset, 0));
+    }
+
+    patternRoles = List.filled(pattern.length, CharRole.NONE);
+    fuzzyMap(pattern, patternRoles);
+    var maxCharScore = matchStyle == MatchStyle.TEXT ? 6 : 4;
+    scoreScale =
+        pattern.isNotEmpty ? 1.0 / (maxCharScore * pattern.length) : 0.0;
+  }
+
+  /// This function picks the matches layer with the best score.
+  int bestLayerIndexAt(int i, int j) {
+    return scoreAt(i, j, 0) < scoreAt(i, j, 1) ? 1 : 0;
+  }
+
+  /// Scores the candidate string.
+  ///
+  /// Return a non-negative value in case of success, or a negative value if the
+  /// candidate does not match or matches poorly.
+  int computeScore(String candidate, String candidateLower) {
+    for (var j = 0; j <= pattern.length; j++) {
+      var mj = matchesLayerOffset + j;
+      // We start with zero but only in the layer where the previous character
+      // didn't match.
+      table[0][j] = j == 0 ? 0 : minScore << 1;
+      table[0][mj] = minScore << 1;
+    }
+
+    var segmentsLeft = 1;
+    var lastSegmentStart = 0;
+    for (var i = 0; i < candidate.length; i++) {
+      if (candidateRoles[i] == CharRole.SEPARATOR) {
+        segmentsLeft++;
+        lastSegmentStart = i + 1;
+      }
+    }
+
+    for (var i = 1; i <= candidate.length; i++) {
+      var isHead = candidateRoles[i - 1] == CharRole.HEAD;
+      if (candidateRoles[i - 1] == CharRole.SEPARATOR && segmentsLeft > 1) {
+        segmentsLeft--;
+      }
+
+      // Boost the very last segment.
+      var segmentScore = segmentsLeft > 1 ? 0 : 1;
+
+      var skipPenalty = 0;
+      // Penalize missing words.
+      if (segmentsLeft == 1 && isHead && matchStyle != MatchStyle.TEXT) {
+        skipPenalty += 1;
+      }
+      // Penalize skipping the first letter of a last segment.
+      if (i - 1 == lastSegmentStart) {
+        skipPenalty += 3;
+      }
+
+      for (var j = 0; j <= pattern.length; j++) {
+        var mj = matchesLayerOffset + j;
+
+        // By default, we don't have a match. Fill in the skip data.
+        table[i][mj] = minScore << 1;
+        if (segmentsLeft > 1 && j == pattern.length) {
+          // The very last pattern character can only be matched in the last
+          // segment.
+          table[i][j] = minScore << 1;
+          continue;
+        }
+
+        // Keep track where we came from.
+        var k = bestLayerIndexAt(i - 1, j);
+        var skipScore = scoreAt(i - 1, j, k);
+        // Do not penalize missing characters after the last matched segment.
+        if (j != pattern.length) {
+          skipScore -= skipPenalty;
+        }
+
+        table[i][j] = (skipScore << 1) + k;
+
+        if (j == 0 ||
+            !(candidateLower.codeUnitAt(i - 1) ==
+                patternLower.codeUnitAt(j - 1))) {
+          // Not a match.
+          continue;
+        }
+
+        // Score the match.
+        var charScore = segmentScore;
+        if (candidateRoles[i - 1] == CharRole.TAIL &&
+            patternRoles[j - 1] == CharRole.HEAD) {
+          if (j > 1) {
+            // Not a match: a Head in the pattern matches some tail character.
+            continue;
+          }
+          // Special treatment for the first character of the pattern. We allow
+          // matches in the middle of a word if they are long enough, at least
+          // min(3, pattern.length) characters.
+          if (patternShort !=
+              candidateLower.substring(
+                  i - 1,
+                  math.min(
+                      candidateLower.length, i - 1 + patternShort.length))) {
+            continue;
+          }
+          charScore -= 4;
+        }
+
+        if ((candidate.codeUnitAt(i - 1) == pattern.codeUnitAt(j - 1)) ||
+            (isHead &&
+                (!caseSensitive || patternRoles[j - 1] == CharRole.HEAD))) {
+          // Case match, or a Head in the pattern aligns with one in the word.
+          // Single-case patterns lack segmentation signals and we assume any
+          // character can be a head of a segment.
+          charScore++;
+        }
+
+        // The third dimension tells us if there is a gap between the previous
+        // match and the current one.
+        for (var k = 0; k < 2; k++) {
+          var score = scoreAt(i - 1, j - 1, k) + charScore;
+          var prevMatches = k == 1;
+
+          var isConsecutive =
+              prevMatches || i - 1 == 0 || i - 1 == lastSegmentStart;
+          if (isConsecutive || (matchStyle == MatchStyle.TEXT && j - 1 == 0)) {
+            // Bonus for a consecutive match. First character match also gets a
+            // bonus to ensure prefix final match score normalizes to 1.0.
+            // Logically, this is a part of charScore, but we have to compute it
+            // here because it only applies for consecutive matches (k == 1).
+            score += matchStyle == MatchStyle.TEXT ? 4 : 2;
+          }
+
+          if (!prevMatches &&
+              (candidateRoles[i - 1] == CharRole.TAIL ||
+                  candidateRoles[i - 1] == CharRole.UC_TAIL)) {
+            // Match starts in the middle of a word. Penalize for the lack of
+            // alignment.
+            score -= 3;
+          }
+          if (score > (table[i][mj] >> 1)) {
+            table[i][mj] = (score << 1) + k;
+          }
+        }
+      }
+    }
+
+    return scoreAt(candidate.length, pattern.length,
+        bestLayerIndexAt(candidate.length, pattern.length));
+  }
+
+  /// Identify the role of each character in the given [string] for fuzzy
+  /// matching. The roles are stored in the list of [roles].
+  void fuzzyMap(String string, List<CharRole> roles) {
+    assert(roles.length >= string.length);
+    var prev = _CharType.NONE;
+    for (var i = 0; i < string.length; i++) {
+      var ch = string.codeUnitAt(i);
+      var type = ch < 128
+          ? _CharType.values[TYPES.codeUnitAt(ch) - 48]
+          : _CharType.LOWER;
+      var role = CharRole.NONE;
+      if (type == _CharType.LOWER) {
+        role = (prev.index <= _CharType.PUNCT.index)
+            ? CharRole.HEAD
+            : CharRole.TAIL;
+      } else if (type == _CharType.UPPER) {
+        role = CharRole.HEAD;
+        // Note: this treats RPCTest as two words.
+        if (prev == _CharType.UPPER &&
+            !(i + 1 < string.length &&
+                string.codeUnitAt(i + 1) >= $a &&
+                string.codeUnitAt(i + 1) <= $z)) {
+          role = CharRole.UC_TAIL;
+        }
+      } else if (type == _CharType.PUNCT) {
+        if (matchStyle == MatchStyle.FILENAME && string[i] == '/' ||
+            matchStyle == MatchStyle.SYMBOL &&
+                (string[i] == '.' || string[i] == ':' || string[i] == ' ')) {
+          role = CharRole.SEPARATOR;
+        }
+      }
+      roles[i] = role;
+      prev = type;
+    }
+    for (var i = string.length - 1;
+        i >= 0 && roles[i] == CharRole.SEPARATOR;
+        i--) {
+      roles[i] = CharRole.NONE;
+    }
+  }
+
+  /// Returns matched ranges for the last scored string as a flattened array of
+  /// [begin, end) pairs, where the start and end of each range aer consecutive
+  /// elements in the list.
+  List<int> getMatchedRanges() {
+    if (pattern.isEmpty || !lastCandidateMatched) {
+      return [];
+    }
+    var i = lastCandidateLen;
+    var j = pattern.length;
+    if (scoreAt(i, j, 0) < minScore / 2 && scoreAt(i, j, 1) < minScore / 2) {
+      return [];
+    }
+
+    var result = <int>[];
+    var k = bestLayerIndexAt(i, j); // bestK in go
+    while (i > 0) {
+      var take = k == 1;
+      k = prevK(i, j, k);
+      if (take) {
+        if (result.isEmpty || result[result.length - 1] != i) {
+          result.add(lastCandidatePrefixTrimmedLen + i);
+          result.add(lastCandidatePrefixTrimmedLen + i - 1);
+        } else {
+          result[result.length - 1] = lastCandidatePrefixTrimmedLen + i - 1;
+        }
+        j--;
+      }
+      i--;
+    }
+    return result.reversed.toList();
+  }
+
+  /// A match is poor if it has more than one short sub-match that is not
+  /// aligned at a word boundary.
+  bool isPoorMatch() {
+    if (pattern.length < 2) {
+      return false;
+    }
+    var i = lastCandidateLen;
+    var j = pattern.length;
+    var k = bestLayerIndexAt(i, j);
+    var counter = 0;
+    var len = 0;
+    while (i > 0) {
+      var take = k == 1;
+      k = prevK(i, j, k);
+      if (take) {
+        len++;
+        if (k == 0 && len < 3 && candidateRoles[i - 1] == CharRole.TAIL) {
+          // Short match in the middle of a word.
+          counter++;
+          if (counter > 1) {
+            return true;
+          }
+        }
+        j--;
+      } else {
+        len = 0;
+      }
+      i--;
+    }
+    return false;
+  }
+
+  /// Return `true` if the [candidate] matches the pattern at all.
+  bool match(String candidate, String candidateLower) {
+    var i = 0;
+    var j = 0;
+    for (; i < candidateLower.length && j < patternLower.length; i++) {
+      if (candidateLower.codeUnitAt(i) == patternLower.codeUnitAt(j)) {
+        j++;
+      }
+    }
+    if (j != patternLower.length) {
+      return false;
+    }
+
+    // The input passes the simple test against pattern, so it is time to
+    // classify its characters. Character roles are used below to find the last
+    // segment.
+    fuzzyMap(candidate, candidateRoles);
+    if (matchStyle != MatchStyle.TEXT) {
+      var sep = candidateLower.length - 1;
+      while (sep >= i && candidateRoles[sep] != CharRole.SEPARATOR) {
+        sep--;
+      }
+      if (sep >= i) {
+        // We are not in the last segment, check that we have at least one
+        // character match in the last segment of the candidate.
+        return candidateLower.contains(
+            patternLower.substring(patternLower.length - 1), sep);
+      }
+    }
+    return true;
+  }
+
+  /// Returns the previous value for the third dimension.
+  int prevK(int i, int j, int k) {
+    return table[i][j + k * matchesLayerOffset] & 1;
+  }
+
+  /// Computes the fuzzy score of how well the [candidate] matches the pattern,
+  /// and returns a value in the range of [0, 1] for matching strings, and -1
+  /// for non-matching ones.
+  double score(String candidate) {
+    lastCandidatePrefixTrimmedLen = 0;
+    if (candidate.length > maxInputSize) {
+      if (matchStyle == MatchStyle.FILENAME) {
+        lastCandidatePrefixTrimmedLen = candidate.length - maxInputSize;
+        candidate = candidate.substring(lastCandidatePrefixTrimmedLen);
+      } else {
+        candidate = candidate.substring(0, maxInputSize);
+      }
+    }
+    if (pattern.isEmpty) {
+      // Empty patterns perfectly match candidates.
+      return 1.0;
+    }
+    lastCandidateLen = candidate.length;
+    var candidateLower = candidate.toLowerCase();
+    if (match(candidate, candidateLower)) {
+      var score = computeScore(candidate, candidateLower);
+      if (score > minScore / 2 && !isPoorMatch()) {
+        lastCandidateMatched = true;
+        if (pattern.length == candidate.length) {
+          // Exact matches are always perfect.
+          return 1.0;
+        }
+        if (score < 0) {
+          score = 0;
+        }
+        var normalizedScore = score * scoreScale;
+        if (normalizedScore > 1) {
+          return 1.0;
+        }
+        return normalizedScore;
+      }
+    }
+
+    // Make sure subsequent calls to getMatchedRanges() return an empty list.
+    lastCandidateMatched = false;
+    return -1.0;
+  }
+
+  /// Returns the pre-computed score for a given cell.
+  int scoreAt(int i, int j, int k) {
+    return table[i][j + k * matchesLayerOffset] >> 1;
+  }
+
+  void setInput(MatchStyle style) {
+    if (matchStyle == style) {
+      return;
+    }
+    matchStyle = style;
+    fuzzyMap(pattern, patternRoles);
+  }
+}
+
+/// The type of strings to match against. For files and symbols, FuzzyMatcher
+/// ensures that the match touches the last segment of the candidate string.
+enum MatchStyle {
+  /// An arbitrary string such as a menu title.
+  TEXT,
+
+  /// A path that uses forward slashes for segment separation.
+  FILENAME,
+
+  /// A qualified symbol name.
+  SYMBOL,
+}
+
+enum _CharType { NONE, PUNCT, LOWER, UPPER }
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 95ddfce..4d2409c 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
@@ -67,8 +67,6 @@
 
   static Future<PostfixCompletion> expandAssert(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findAssertExpression, (expr) {
       return 'assert(${processor.utils.getNodeText(expr)});';
     }, withBraces: false);
@@ -76,16 +74,12 @@
 
   static Future<PostfixCompletion> expandElse(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findBoolExpression,
         (expr) => 'if (${processor.makeNegatedBoolExpr(expr)})');
   }
 
   static Future<PostfixCompletion> expandFor(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findIterableExpression, (expr) {
       var value = processor.newVariable('value');
       return 'for (var $value in ${processor.utils.getNodeText(expr)})';
@@ -94,8 +88,6 @@
 
   static Future<PostfixCompletion> expandFori(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findIntExpression, (expr) {
       var index = processor.newVariable('i');
       return 'for (int $index = 0; $index < ${processor.utils.getNodeText(expr)}; $index++)';
@@ -104,16 +96,12 @@
 
   static Future<PostfixCompletion> expandIf(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findBoolExpression,
         (expr) => 'if (${processor.utils.getNodeText(expr)})');
   }
 
   static Future<PostfixCompletion> expandNegate(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findBoolExpression,
         (expr) => processor.makeNegatedBoolExpr(expr),
         withBraces: false);
@@ -121,8 +109,6 @@
 
   static Future<PostfixCompletion> expandNotNull(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findObjectExpression, (expr) {
       return expr is NullLiteral
           ? 'if (false)'
@@ -132,8 +118,6 @@
 
   static Future<PostfixCompletion> expandNull(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findObjectExpression, (expr) {
       return expr is NullLiteral
           ? 'if (true)'
@@ -143,8 +127,6 @@
 
   static Future<PostfixCompletion> expandParen(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findObjectExpression,
         (expr) => '(${processor.utils.getNodeText(expr)})',
         withBraces: false);
@@ -152,8 +134,6 @@
 
   static Future<PostfixCompletion> expandReturn(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findObjectExpression,
         (expr) => 'return ${processor.utils.getNodeText(expr)};',
         withBraces: false);
@@ -161,30 +141,22 @@
 
   static Future<PostfixCompletion> expandSwitch(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findObjectExpression,
         (expr) => 'switch (${processor.utils.getNodeText(expr)})');
   }
 
   static Future<PostfixCompletion> expandTry(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expandTry(kind, processor.findStatement, withOn: false);
   }
 
   static Future<PostfixCompletion> expandTryon(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expandTry(kind, processor.findStatement, withOn: true);
   }
 
   static Future<PostfixCompletion> expandWhile(
       PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return processor.expand(kind, processor.findBoolExpression,
         (expr) => 'while (${processor.utils.getNodeText(expr)})');
   }
@@ -300,8 +272,6 @@
   TypeSystem get typeSystem => completionContext.resolveResult.typeSystem;
 
   Future<PostfixCompletion> compute() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     node = _selectedNode();
     if (node == null) {
       return NO_COMPLETION;
@@ -313,8 +283,6 @@
   Future<PostfixCompletion> expand(
       PostfixCompletionKind kind, Function contexter, Function sourcer,
       {bool withBraces = true}) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     AstNode expr = contexter();
     if (expr == null) {
       return null;
@@ -350,8 +318,6 @@
   Future<PostfixCompletion> expandTry(
       PostfixCompletionKind kind, Function contexter,
       {bool withOn = false}) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     AstNode stmt = contexter();
     if (stmt == null) {
       return null;
@@ -455,8 +421,6 @@
   }
 
   Future<bool> isApplicable() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     node = _selectedNode();
     if (node == null) {
       return false;
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 9b025cd..6b19e69 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
@@ -132,8 +132,6 @@
       statementContext.resolveResult.unit.declaredElement;
 
   Future<StatementCompletion> compute() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     node = _selectedNode();
     if (node == null) {
       return NO_COMPLETION;
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 54a3100..88f78e0 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -28,15 +28,15 @@
 /// An enumeration of possible assist kinds.
 class DartAssistKind {
   static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE = AssistKind(
-      'ADD_DIAGNOSTIC_PROPERTY_REFERENCE',
+      'dart.assist.add.diagnosticPropertyReference',
       30,
       'Add a debug reference to this property');
   static const ADD_NOT_NULL_ASSERT = AssistKind(
-      'dart.assist.addNotNullAssert', 30, 'Add a not-null assertion');
+      'dart.assist.add.notNullAssert', 30, 'Add a not-null assertion');
   static const ADD_RETURN_TYPE =
-      AssistKind('dart.assist.addReturnType', 30, 'Add return type');
+      AssistKind('dart.assist.add.returnType', 30, 'Add return type');
   static const ADD_TYPE_ANNOTATION =
-      AssistKind('dart.assist.addTypeAnnotation', 30, 'Add type annotation');
+      AssistKind('dart.assist.add.typeAnnotation', 30, 'Add type annotation');
   static const ASSIGN_TO_LOCAL_VARIABLE = AssistKind(
       'dart.assist.assignToVariable', 30, 'Assign value to new local variable');
   static const CONVERT_CLASS_TO_MIXIN = AssistKind(
@@ -82,9 +82,9 @@
       30,
       'Convert to field formal parameter');
   static const CONVERT_TO_FOR_ELEMENT = AssistKind(
-      'dart.assist.convertToForElement', 30, "Convert to a 'for' element");
+      'dart.assist.convert.toForElement', 30, "Convert to a 'for' element");
   static const CONVERT_TO_IF_ELEMENT = AssistKind(
-      'dart.assist.convertToIfElement', 30, "Convert to an 'if' element");
+      'dart.assist.convert.toIfElement', 30, "Convert to an 'if' element");
   static const CONVERT_TO_INT_LITERAL = AssistKind(
       'dart.assist.convert.toIntLiteral', 30, 'Convert to an int literal');
   static const CONVERT_TO_LIST_LITERAL = AssistKind(
@@ -107,6 +107,10 @@
       'dart.assist.convert.relativeToPackageImport',
       30,
       "Convert to 'package:' import");
+  static const CONVERT_TO_RELATIVE_IMPORT = AssistKind(
+      'dart.assist.convert.packageToRelativeImport',
+      30,
+      'Convert to a relative import');
   static const CONVERT_TO_SET_LITERAL = AssistKind(
       'dart.assist.convert.toSetLiteral', 30, 'Convert to set literal',
       associatedErrorCodes: <String>['prefer_collection_literals']);
@@ -115,7 +119,7 @@
       30,
       'Convert to single quoted string');
   static const CONVERT_TO_SPREAD =
-      AssistKind('dart.assist.convertToSpread', 30, 'Convert to a spread');
+      AssistKind('dart.assist.convert.toSpread', 30, 'Convert to a spread');
   static const ENCAPSULATE_FIELD =
       AssistKind('dart.assist.encapsulateField', 30, 'Encapsulate field');
   static const EXCHANGE_OPERANDS =
@@ -163,7 +167,7 @@
       AssistKind('dart.assist.flutter.removeWidget', 35, 'Remove this widget');
 
   static const IMPORT_ADD_SHOW = AssistKind(
-      'dart.assist.addShowCombinator', 30, "Add explicit 'show' combinator");
+      'dart.assist.add.showCombinator', 30, "Add explicit 'show' combinator");
   static const INLINE_INVOCATION =
       AssistKind('dart.assist.inline', 30, "Inline invocation of '{0}'");
   static const INTRODUCE_LOCAL_CAST_TYPE = AssistKind(
@@ -180,7 +184,7 @@
       'dart.assist.joinVariableDeclaration', 30, 'Join variable declaration');
   static const REMOVE_TYPE_ANNOTATION = AssistKind(
       // todo (pq): unify w/ fix
-      'dart.assist.removeTypeAnnotation',
+      'dart.assist.remove.typeAnnotation',
       29,
       'Remove type annotation');
   static const REPLACE_CONDITIONAL_WITH_IF_ELSE = AssistKind(
@@ -192,9 +196,7 @@
       30,
       "Replace 'if-else' with conditional ('c ? x : y')");
   static const REPLACE_WITH_VAR = AssistKind(
-      'dart.assist.convert.replaceWithVar',
-      30,
-      "Replace type annotation with 'var'");
+      'dart.assist.replace.withVar', 30, "Replace type annotation with 'var'");
   static const SHADOW_FIELD = AssistKind('dart.assist.shadowField', 30,
       'Create a local variable that shadows the field');
   static const SORT_CHILD_PROPERTY_LAST = AssistKind(
@@ -224,5 +226,5 @@
   static const SURROUND_WITH_WHILE =
       AssistKind('dart.assist.surround.while', 24, "Surround with 'while'");
   static const USE_CURLY_BRACES =
-      AssistKind('USE_CURLY_BRACES', 30, 'Use curly braces');
+      AssistKind('dart.assist.surround.curlyBraces', 30, 'Use curly braces');
 }
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 56190d1..1b83baf 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -11,14 +11,31 @@
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/base_processor.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
 import 'package:analysis_server/src/services/correction/dart/add_return_type.dart';
+import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_expression_function_body.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_list_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/exchange_operands.dart';
+import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
 import 'package:analysis_server/src/services/correction/dart/shadow_field.dart';
+import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
 import 'package:analysis_server/src/services/correction/dart/split_and_condition.dart';
+import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
 import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
 import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
@@ -33,7 +50,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -64,56 +80,22 @@
     if (!setupCompute()) {
       return assists;
     }
-    if (!_containsErrorCode(
-      {LintNames.always_specify_types, LintNames.type_annotate_public_apis},
-    )) {
-      await _addProposals_addTypeAnnotation();
-    }
     await _addProposal_addNotNullAssert();
     await _addProposal_assignToLocalVariable();
     await _addProposal_convertClassToMixin();
     await _addProposal_convertDocumentationIntoBlock();
-    if (!_containsErrorCode(
-      {LintNames.slash_for_doc_comments},
-    )) {
-      await _addProposal_convertDocumentationIntoLine();
-    }
     await _addProposal_convertIntoFinalField();
     await _addProposal_convertIntoGetter();
     await _addProposal_convertPartOfToUri();
     await _addProposal_convertToAsyncFunctionBody();
     await _addProposal_convertToBlockFunctionBody();
-    await _addProposal_convertToDoubleQuotedString();
-    if (!_containsErrorCode(
-      {LintNames.prefer_expression_function_bodies},
-    )) {
-      await _addProposal_convertToExpressionFunctionBody();
-    }
     await _addProposal_convertToFieldParameter();
     await _addProposal_convertToForIndexLoop();
-    if (!_containsErrorCode({LintNames.prefer_generic_function_type_aliases})) {
-      await _addProposal_convertToGenericFunctionSyntax();
-    }
-    if (!_containsErrorCode(
-      {LintNames.prefer_int_literals},
-    )) {
-      await _addProposal_convertToIntLiteral();
-    }
     await _addProposal_convertToIsNot_onIs();
     await _addProposal_convertToIsNot_onNot();
     await _addProposal_convertToIsNotEmpty();
     await _addProposal_convertToMultilineString();
     await _addProposal_convertToNormalParameter();
-    if (!_containsErrorCode(
-      {LintNames.avoid_relative_lib_imports},
-    )) {
-      await _addProposal_convertToPackageImport();
-    }
-    if (!_containsErrorCode(
-      {LintNames.prefer_single_quotes},
-    )) {
-      await _addProposal_convertToSingleQuotedString();
-    }
     await _addProposal_encapsulateField();
     await _addProposal_flutterConvertToChildren();
     await _addProposal_flutterConvertToStatefulWidget();
@@ -127,66 +109,17 @@
     await _addProposal_flutterWrapWidget();
     await _addProposal_flutterWrapWidgets();
     await _addProposal_importAddShow();
-    if (!_containsErrorCode(
-      {LintNames.prefer_inlined_adds},
-    )) {
-      await _addProposal_inlineAdd();
-    }
     await _addProposal_introduceLocalTestedType();
     await _addProposal_invertIf();
     await _addProposal_joinIfStatementInner();
     await _addProposal_joinIfStatementOuter();
     await _addProposal_joinVariableDeclaration_onAssignment();
     await _addProposal_joinVariableDeclaration_onDeclaration();
-    await _addProposal_removeTypeAnnotation();
     await _addProposal_reparentFlutterList();
     await _addProposal_replaceConditionalWithIfElse();
     await _addProposal_replaceIfElseWithConditional();
-    if (!_containsErrorCode({LintNames.omit_local_variable_types})) {
-      await _addProposal_replaceWithVar();
-    }
-    if (!_containsErrorCode(
-      {LintNames.sort_child_properties_last},
-    )) {
-      await _addProposal_sortChildPropertyLast();
-    }
     await _addProposal_splitVariableDeclaration();
     await _addProposal_surroundWith();
-    if (!_containsErrorCode(
-      {LintNames.curly_braces_in_flow_control_structures},
-    )) {
-      await _addProposal_useCurlyBraces();
-    }
-    if (!_containsErrorCode(
-      {LintNames.diagnostic_describe_all_properties},
-    )) {
-      await _addProposal_addDiagnosticPropertyReference();
-    }
-    if (experimentStatus.control_flow_collections) {
-      if (!_containsErrorCode(
-        {LintNames.prefer_if_elements_to_conditional_expressions},
-      )) {
-        await _addProposal_convertConditionalExpressionToIfElement();
-      }
-      if (!_containsErrorCode(
-        {LintNames.prefer_for_elements_to_map_fromIterable},
-      )) {
-        await _addProposal_convertMapFromIterableToForLiteral();
-      }
-    }
-    if (experimentStatus.spread_collections) {
-      final preferSpreadsLintFound =
-          _containsErrorCode({LintNames.prefer_spread_collections});
-      final preferInlinedAddsLintFound =
-          _containsErrorCode({LintNames.prefer_inlined_adds});
-      if (!_containsErrorCode(
-        {LintNames.prefer_spread_collections},
-      )) {
-        await _addProposal_convertAddAllToSpread(
-            preferInlinedAdds: !preferInlinedAddsLintFound,
-            convertToSpreads: !preferSpreadsLintFound);
-      }
-    }
 
     await _addFromProducers();
 
@@ -198,23 +131,39 @@
       return assists;
     }
 
+    var context = CorrectionProducerContext(
+      selectionOffset: selectionOffset,
+      selectionLength: selectionLength,
+      resolvedResult: resolvedResult,
+      workspace: workspace,
+    );
+
+    var setupSuccess = context.setupCompute();
+    if (!setupSuccess) {
+      return assists;
+    }
+
+    Future<void> compute(CorrectionProducer producer) async {
+      producer.configure(context);
+
+      var builder = _newDartChangeBuilder();
+      await producer.compute(builder);
+
+      _addAssistFromBuilder(builder, producer.assistKind,
+          args: producer.assistArguments);
+    }
+
     // Calculate only specific assists for edit.dartFix
     if (assistKind == DartAssistKind.CONVERT_CLASS_TO_MIXIN) {
       await _addProposal_convertClassToMixin();
     } else if (assistKind == DartAssistKind.CONVERT_TO_INT_LITERAL) {
-      await _addProposal_convertToIntLiteral();
+      await compute(ConvertToIntLiteral());
     } else if (assistKind == DartAssistKind.CONVERT_TO_SPREAD) {
-      if (experimentStatus.spread_collections) {
-        await _addProposal_convertAddAllToSpread();
-      }
+      await compute(ConvertAddAllToSpread());
     } else if (assistKind == DartAssistKind.CONVERT_TO_FOR_ELEMENT) {
-      if (experimentStatus.control_flow_collections) {
-        await _addProposal_convertMapFromIterableToForLiteral();
-      }
+      await compute(ConvertMapFromIterableToForLiteral());
     } else if (assistKind == DartAssistKind.CONVERT_TO_IF_ELEMENT) {
-      if (experimentStatus.control_flow_collections) {
-        await _addProposal_convertConditionalExpressionToIfElement();
-      }
+      await compute(ConvertConditionalExpressionToIfElement());
     }
     return assists;
   }
@@ -226,7 +175,6 @@
     }
     var change = builder.sourceChange;
     if (change.edits.isEmpty) {
-      _coverageMarker();
       return;
     }
     change.id = kind.id;
@@ -271,6 +219,43 @@
       {LintNames.always_declare_return_types},
     );
     await computeIfNotErrorCode(
+      AddDiagnosticPropertyReference(),
+      {LintNames.diagnostic_describe_all_properties},
+    );
+    await computeIfNotErrorCode(
+      AddTypeAnnotation(),
+      {LintNames.always_specify_types, LintNames.type_annotate_public_apis},
+    );
+    await computeIfNotErrorCode(
+      ConvertConditionalExpressionToIfElement(),
+      {LintNames.prefer_if_elements_to_conditional_expressions},
+    );
+    await computeIfNotErrorCode(
+      ConvertDocumentationIntoLine(),
+      {LintNames.slash_for_doc_comments},
+    );
+    await computeIfNotErrorCode(
+      ConvertMapFromIterableToForLiteral(),
+      {LintNames.prefer_for_elements_to_map_fromIterable},
+    );
+    await compute(ConvertToDoubleQuotes());
+    await computeIfNotErrorCode(
+      ConvertToSingleQuotes(),
+      {LintNames.prefer_single_quotes},
+    );
+    await computeIfNotErrorCode(
+      ConvertToExpressionFunctionBody(),
+      {LintNames.prefer_expression_function_bodies},
+    );
+    await computeIfNotErrorCode(
+      ConvertToGenericFunctionSyntax(),
+      {LintNames.prefer_generic_function_type_aliases},
+    );
+    await computeIfNotErrorCode(
+      ConvertToIntLiteral(),
+      {LintNames.prefer_int_literals},
+    );
+    await computeIfNotErrorCode(
       ConvertToListLiteral(),
       {LintNames.prefer_collection_literals},
     );
@@ -283,18 +268,41 @@
       {LintNames.prefer_null_aware_operators},
     );
     await computeIfNotErrorCode(
+      ConvertToPackageImport(),
+      {LintNames.avoid_relative_lib_imports},
+    );
+    await computeIfNotErrorCode(
+      ConvertToRelativeImport(),
+      {LintNames.prefer_relative_imports},
+    );
+    await computeIfNotErrorCode(
       ConvertToSetLiteral(),
       {LintNames.prefer_collection_literals},
     );
     await compute(ExchangeOperands());
+    await computeIfNotErrorCode(
+      InlineInvocation(),
+      {LintNames.prefer_inlined_adds},
+    );
+    await compute(RemoveTypeAnnotation());
+    await computeIfNotErrorCode(
+      ReplaceWithVar(),
+      {LintNames.omit_local_variable_types},
+    );
     await compute(ShadowField());
+    await computeIfNotErrorCode(
+      SortChildPropertyLast(),
+      {LintNames.sort_child_properties_last},
+    );
     await compute(SplitAndCondition());
-  }
-
-  Future<void> _addProposal_addDiagnosticPropertyReference() async {
-    final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
-    _addAssistFromBuilder(
-        changeBuilder, DartAssistKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
+    await computeIfNotErrorCode(
+      UseCurlyBraces(),
+      {LintNames.curly_braces_in_flow_control_structures},
+    );
+    await computeIfNotErrorCode(
+      ConvertAddAllToSpread(),
+      {LintNames.prefer_inlined_adds, LintNames.prefer_spread_collections},
+    );
   }
 
   Future<void> _addProposal_addNotNullAssert() async {
@@ -365,12 +373,10 @@
           node is AssignmentExpression ||
           node is Statement ||
           node is ThrowExpression) {
-        _coverageMarker();
         return;
       }
     }
     if (expressionStatement == null) {
-      _coverageMarker();
       return;
     }
     // prepare expression
@@ -379,7 +385,6 @@
     // prepare expression type
     var type = expression.staticType;
     if (type.isVoid) {
-      _coverageMarker();
       return;
     }
     // prepare excluded names
@@ -406,20 +411,6 @@
     }
   }
 
-  Future<void> _addProposal_convertAddAllToSpread(
-      {bool preferInlinedAdds = true, bool convertToSpreads = true}) async {
-    final change = await createBuilder_convertAddAllToSpread();
-    if (change != null) {
-      if (change.isLineInvocation && !preferInlinedAdds || !convertToSpreads) {
-        return;
-      }
-      final kind = change.isLineInvocation
-          ? DartAssistKind.INLINE_INVOCATION
-          : DartAssistKind.CONVERT_TO_SPREAD;
-      _addAssistFromBuilder(change.builder, kind, args: change.args);
-    }
-  }
-
   Future<void> _addProposal_convertClassToMixin() async {
     var classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
     if (classDeclaration == null) {
@@ -475,12 +466,6 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_CLASS_TO_MIXIN);
   }
 
-  Future<void> _addProposal_convertConditionalExpressionToIfElement() async {
-    final changeBuilder =
-        await createBuilder_convertConditionalExpressionToIfElement();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT);
-  }
-
   Future<void> _addProposal_convertDocumentationIntoBlock() async {
     var comment = node.thisOrAncestorOfType<Comment>();
     if (comment == null || !comment.isDocumentation) {
@@ -512,12 +497,6 @@
         changeBuilder, DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
   }
 
-  Future<void> _addProposal_convertDocumentationIntoLine() async {
-    final changeBuilder = await createBuilder_convertDocumentationIntoLine();
-    _addAssistFromBuilder(
-        changeBuilder, DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE);
-  }
-
   Future<void> _addProposal_convertIntoFinalField() async {
     // Find the enclosing getter.
     MethodDeclaration getter;
@@ -635,12 +614,6 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_GETTER);
   }
 
-  Future<void> _addProposal_convertMapFromIterableToForLiteral() async {
-    final changeBuilder =
-        await createBuilder_convertMapFromIterableToForLiteral();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_FOR_ELEMENT);
-  }
-
   Future<void> _addProposal_convertPartOfToUri() async {
     var directive = node.thisOrAncestorOfType<PartOfDirective>();
     if (directive == null || directive.libraryName == null) {
@@ -659,12 +632,11 @@
   }
 
   Future<void> _addProposal_convertToAsyncFunctionBody() async {
-    var body = getEnclosingFunctionBody();
+    var body = _getEnclosingFunctionBody();
     if (body == null ||
         body is EmptyFunctionBody ||
         body.isAsynchronous ||
         body.isGenerator) {
-      _coverageMarker();
       return;
     }
 
@@ -693,10 +665,9 @@
   }
 
   Future<void> _addProposal_convertToBlockFunctionBody() async {
-    var body = getEnclosingFunctionBody();
+    var body = _getEnclosingFunctionBody();
     // prepare expression body
     if (body is! ExpressionFunctionBody || body.isGenerator) {
-      _coverageMarker();
       return;
     }
 
@@ -705,7 +676,6 @@
     // Return expressions can be quite large, e.g. Flutter build() methods.
     // It is surprising to see this Quick Assist deep in the function body.
     if (selectionOffset >= returnValue.offset) {
-      _coverageMarker();
       return;
     }
 
@@ -735,16 +705,6 @@
         changeBuilder, DartAssistKind.CONVERT_INTO_BLOCK_BODY);
   }
 
-  Future<void> _addProposal_convertToDoubleQuotedString() async {
-    await _convertQuotes(false, DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING);
-  }
-
-  Future<void> _addProposal_convertToExpressionFunctionBody() async {
-    final changeBuilder = await createBuilder_convertToExpressionFunctionBody();
-    _addAssistFromBuilder(
-        changeBuilder, DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
   Future<void> _addProposal_convertToFieldParameter() async {
     if (node == null) {
       return;
@@ -842,13 +802,11 @@
             (node) => node is ForStatement && node.forLoopParts is ForEachParts)
         as ForStatement;
     if (forEachStatement == null) {
-      _coverageMarker();
       return;
     }
     ForEachParts forEachParts = forEachStatement.forLoopParts;
     if (selectionOffset < forEachStatement.offset ||
         forEachStatement.rightParenthesis.end < selectionOffset) {
-      _coverageMarker();
       return;
     }
     // loop should declare variable
@@ -856,7 +814,6 @@
         ? forEachParts.loopVariable
         : null;
     if (loopVariable == null) {
-      _coverageMarker();
       return;
     }
     // iterable should be VariableElement
@@ -866,7 +823,6 @@
         iterable.staticElement is VariableElement) {
       listName = iterable.name;
     } else {
-      _coverageMarker();
       return;
     }
     // iterable should be List
@@ -874,13 +830,11 @@
       var iterableType = iterable.staticType;
       if (iterableType is! InterfaceType ||
           iterableType.element != typeProvider.listElement) {
-        _coverageMarker();
         return;
       }
     }
     // body should be Block
     if (forEachStatement.body is! Block) {
-      _coverageMarker();
       return;
     }
     Block body = forEachStatement.body;
@@ -896,7 +850,6 @@
       } else if (!conflicts.contains('k')) {
         indexName = 'k';
       } else {
-        _coverageMarker();
         return;
       }
     }
@@ -917,17 +870,6 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_FOR_INDEX);
   }
 
-  Future<void> _addProposal_convertToGenericFunctionSyntax() async {
-    var changeBuilder = await createBuilder_convertToGenericFunctionSyntax();
-    _addAssistFromBuilder(
-        changeBuilder, DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX);
-  }
-
-  Future<void> _addProposal_convertToIntLiteral() async {
-    final changeBuilder = await createBuilder_convertToIntLiteral();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_INT_LITERAL);
-  }
-
   Future<void> _addProposal_convertToIsNot_onIs() async {
     // may be child of "is"
     var node = this.node;
@@ -936,30 +878,25 @@
     }
     // prepare "is"
     if (node is! IsExpression) {
-      _coverageMarker();
       return;
     }
     var isExpression = node as IsExpression;
     if (isExpression.notOperator != null) {
-      _coverageMarker();
       return;
     }
     // prepare enclosing ()
     var parent = isExpression.parent;
     if (parent is! ParenthesizedExpression) {
-      _coverageMarker();
       return;
     }
     var parExpression = parent as ParenthesizedExpression;
     // prepare enclosing !()
     var parent2 = parent.parent;
     if (parent2 is! PrefixExpression) {
-      _coverageMarker();
       return;
     }
     var prefExpression = parent2 as PrefixExpression;
     if (prefExpression.operator.type != TokenType.BANG) {
-      _coverageMarker();
       return;
     }
 
@@ -987,31 +924,26 @@
     }
     // prepare !()
     if (node is! PrefixExpression) {
-      _coverageMarker();
       return;
     }
     var prefExpression = node as PrefixExpression;
     // should be ! operator
     if (prefExpression.operator.type != TokenType.BANG) {
-      _coverageMarker();
       return;
     }
     // prepare !()
     var operand = prefExpression.operand;
     if (operand is! ParenthesizedExpression) {
-      _coverageMarker();
       return;
     }
     var parExpression = operand as ParenthesizedExpression;
     operand = parExpression.expression;
     // prepare "is"
     if (operand is! IsExpression) {
-      _coverageMarker();
       return;
     }
     var isExpression = operand as IsExpression;
     if (isExpression.notOperator != null) {
-      _coverageMarker();
       return;
     }
 
@@ -1051,31 +983,26 @@
       }
     }
     if (isEmptyIdentifier == null) {
-      _coverageMarker();
       return;
     }
     // should be "isEmpty"
     var propertyElement = isEmptyIdentifier.staticElement;
     if (propertyElement == null || 'isEmpty' != propertyElement.name) {
-      _coverageMarker();
       return;
     }
     // should have "isNotEmpty"
     var propertyTarget = propertyElement.enclosingElement;
     if (propertyTarget == null ||
         getChildren(propertyTarget, 'isNotEmpty').isEmpty) {
-      _coverageMarker();
       return;
     }
     // should be in PrefixExpression
     if (isEmptyAccess.parent is! PrefixExpression) {
-      _coverageMarker();
       return;
     }
     var prefixExpression = isEmptyAccess.parent as PrefixExpression;
     // should be !
     if (prefixExpression.operator.type != TokenType.BANG) {
-      _coverageMarker();
       return;
     }
 
@@ -1158,43 +1085,28 @@
     }
   }
 
-  Future<void> _addProposal_convertToPackageImport() async {
-    final changeBuilder = await createBuilder_convertToPackageImport();
-    _addAssistFromBuilder(
-        changeBuilder, DartAssistKind.CONVERT_TO_PACKAGE_IMPORT);
-  }
-
-  Future<void> _addProposal_convertToSingleQuotedString() async {
-    await _convertQuotes(true, DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING);
-  }
-
   Future<void> _addProposal_encapsulateField() async {
     // find FieldDeclaration
     var fieldDeclaration = node.thisOrAncestorOfType<FieldDeclaration>();
     if (fieldDeclaration == null) {
-      _coverageMarker();
       return;
     }
     // not interesting for static
     if (fieldDeclaration.isStatic) {
-      _coverageMarker();
       return;
     }
     // has a parse error
     var variableList = fieldDeclaration.fields;
     if (variableList.keyword == null && variableList.type == null) {
-      _coverageMarker();
       return;
     }
     // not interesting for final
     if (variableList.isFinal) {
-      _coverageMarker();
       return;
     }
     // should have exactly one field
     List<VariableDeclaration> fields = variableList.variables;
     if (fields.length != 1) {
-      _coverageMarker();
       return;
     }
     var field = fields.first;
@@ -1203,12 +1115,10 @@
     // should have a public name
     var name = nameNode.name;
     if (Identifier.isPrivateName(name)) {
-      _coverageMarker();
       return;
     }
     // should be on the name
     if (nameNode != node) {
-      _coverageMarker();
       return;
     }
     var changeBuilder = _newDartChangeBuilder();
@@ -1281,7 +1191,6 @@
           flutter.isWidgetExpression(parent2.expression)) {
         namedExp = parent2;
       } else {
-        _coverageMarker();
         return;
       }
     }
@@ -1299,14 +1208,12 @@
     var widgetClass = node.thisOrAncestorOfType<ClassDeclaration>();
     var superclass = widgetClass?.extendsClause?.superclass;
     if (widgetClass == null || superclass == null) {
-      _coverageMarker();
       return;
     }
 
     // Don't spam, activate only from the `class` keyword to the class body.
     if (selectionOffset < widgetClass.classKeyword.offset ||
         selectionOffset > widgetClass.leftBracket.end) {
-      _coverageMarker();
       return;
     }
 
@@ -1322,14 +1229,12 @@
       }
     }
     if (buildMethod == null) {
-      _coverageMarker();
       return;
     }
 
     // Must be a StatelessWidget subclasses.
     var widgetClassElement = widgetClass.declaredElement;
     if (!flutter.isExactlyStatelessWidgetType(widgetClassElement.supertype)) {
-      _coverageMarker();
       return;
     }
 
@@ -1686,14 +1591,12 @@
   Future<void> _addProposal_flutterSwapWithChild() async {
     var parent = flutter.identifyNewExpression(node);
     if (!flutter.isWidgetCreation(parent)) {
-      _coverageMarker();
       return;
     }
 
     var childArgument = flutter.findChildArgument(parent);
     if (childArgument?.expression is! InstanceCreationExpression ||
         !flutter.isWidgetCreation(childArgument.expression)) {
-      _coverageMarker();
       return;
     }
     InstanceCreationExpression child = childArgument.expression;
@@ -1705,14 +1608,12 @@
   Future<void> _addProposal_flutterSwapWithParent() async {
     var child = flutter.identifyNewExpression(node);
     if (!flutter.isWidgetCreation(child)) {
-      _coverageMarker();
       return;
     }
 
     // NamedExpression (child:), ArgumentList, InstanceCreationExpression
     var expr = child.parent?.parent?.parent;
     if (expr is! InstanceCreationExpression) {
-      _coverageMarker();
       return;
     }
     InstanceCreationExpression parent = expr;
@@ -1813,11 +1714,9 @@
       List<String> leadingLines = const []}) async {
     var widgetExpr = flutter.identifyWidgetExpression(node);
     if (widgetExpr == null) {
-      _coverageMarker();
       return;
     }
     if (widgetValidator != null && !widgetValidator(widgetExpr)) {
-      _coverageMarker();
       return;
     }
     var widgetSrc = utils.getNodeText(widgetExpr);
@@ -1922,9 +1821,7 @@
 
           builder.write(eol);
           builder.write(indentNew1);
-          builder.write('children: <');
-          builder.writeReference(widgetClassElement);
-          builder.write('>[');
+          builder.write('children: [');
           builder.write(eol);
 
           var newSrc = _replaceSourceIndent(src, indentOld, indentNew2);
@@ -1959,18 +1856,15 @@
     // prepare ImportDirective
     var importDirective = node.thisOrAncestorOfType<ImportDirective>();
     if (importDirective == null) {
-      _coverageMarker();
       return;
     }
     // there should be no existing combinators
     if (importDirective.combinators.isNotEmpty) {
-      _coverageMarker();
       return;
     }
     // prepare whole import namespace
     ImportElement importElement = importDirective.element;
     if (importElement == null) {
-      _coverageMarker();
       return;
     }
     var namespace = getImportNamespace(importElement);
@@ -1988,7 +1882,6 @@
     context.resolveResult.unit.accept(visitor);
     // ignore if unused
     if (referencedNames.isEmpty) {
-      _coverageMarker();
       return;
     }
     var changeBuilder = _newDartChangeBuilder();
@@ -1999,12 +1892,6 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.IMPORT_ADD_SHOW);
   }
 
-  Future<void> _addProposal_inlineAdd() async {
-    final changeBuilder = await createBuilder_inlineAdd();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.INLINE_INVOCATION,
-        args: ['add']);
-  }
-
   Future<void> _addProposal_introduceLocalTestedType() async {
     var node = this.node;
     if (node is IfStatement) {
@@ -2014,7 +1901,6 @@
     }
     // prepare IsExpression
     if (node is! IsExpression) {
-      _coverageMarker();
       return;
     }
     IsExpression isExpression = node;
@@ -2031,7 +1917,6 @@
       } else if (statement is WhileStatement && statement.body is Block) {
         targetBlock = statement.body;
       } else {
-        _coverageMarker();
         return;
       }
       prefix = utils.getNodePrefix(statement);
@@ -2110,24 +1995,20 @@
     }
     // prepare target "if" statement
     if (node is! IfStatement) {
-      _coverageMarker();
       return;
     }
     var targetIfStatement = node as IfStatement;
     if (targetIfStatement.elseStatement != null) {
-      _coverageMarker();
       return;
     }
     // prepare inner "if" statement
     var targetThenStatement = targetIfStatement.thenStatement;
     var innerStatement = getSingleStatement(targetThenStatement);
     if (innerStatement is! IfStatement) {
-      _coverageMarker();
       return;
     }
     var innerIfStatement = innerStatement as IfStatement;
     if (innerIfStatement.elseStatement != null) {
-      _coverageMarker();
       return;
     }
     // prepare environment
@@ -2170,30 +2051,25 @@
     }
     // prepare target "if" statement
     if (node is! IfStatement) {
-      _coverageMarker();
       return;
     }
     var targetIfStatement = node as IfStatement;
     if (targetIfStatement.elseStatement != null) {
-      _coverageMarker();
       return;
     }
     // prepare outer "if" statement
     var parent = targetIfStatement.parent;
     if (parent is Block) {
       if ((parent as Block).statements.length != 1) {
-        _coverageMarker();
         return;
       }
       parent = parent.parent;
     }
     if (parent is! IfStatement) {
-      _coverageMarker();
       return;
     }
     var outerIfStatement = parent as IfStatement;
     if (outerIfStatement.elseStatement != null) {
-      _coverageMarker();
       return;
     }
     // prepare environment
@@ -2232,19 +2108,16 @@
         (node.parent as AssignmentExpression).leftHandSide == node &&
         node.parent.parent is ExpressionStatement) {
     } else {
-      _coverageMarker();
       return;
     }
     var assignExpression = node.parent as AssignmentExpression;
     // check that binary expression is assignment
     if (assignExpression.operator.type != TokenType.EQ) {
-      _coverageMarker();
       return;
     }
     // prepare "declaration" statement
     var element = (node as SimpleIdentifier).staticElement;
     if (element == null) {
-      _coverageMarker();
       return;
     }
     var declOffset = element.nameOffset;
@@ -2256,19 +2129,16 @@
         declNode.parent.parent is VariableDeclarationList &&
         declNode.parent.parent.parent is VariableDeclarationStatement) {
     } else {
-      _coverageMarker();
       return;
     }
     var decl = declNode.parent as VariableDeclaration;
     var declStatement = decl.parent.parent as VariableDeclarationStatement;
     // may be has initializer
     if (decl.initializer != null) {
-      _coverageMarker();
       return;
     }
     // check that "declaration" statement declared only one variable
     if (declStatement.variables.variables.length != 1) {
-      _coverageMarker();
       return;
     }
     // check that the "declaration" and "assignment" statements are
@@ -2277,7 +2147,6 @@
     if (assignStatement.parent is Block &&
         assignStatement.parent == declStatement.parent) {
     } else {
-      _coverageMarker();
       return;
     }
     var block = assignStatement.parent as Block;
@@ -2286,7 +2155,6 @@
     if (statements.indexOf(assignStatement) ==
         statements.indexOf(declStatement) + 1) {
     } else {
-      _coverageMarker();
       return;
     }
 
@@ -2304,20 +2172,17 @@
     var declList = node.thisOrAncestorOfType<VariableDeclarationList>();
     if (declList != null && declList.variables.length == 1) {
     } else {
-      _coverageMarker();
       return;
     }
     var decl = declList.variables[0];
     // already initialized
     if (decl.initializer != null) {
-      _coverageMarker();
       return;
     }
     // prepare VariableDeclarationStatement in Block
     if (declList.parent is VariableDeclarationStatement &&
         declList.parent.parent is Block) {
     } else {
-      _coverageMarker();
       return;
     }
     var declStatement = declList.parent as VariableDeclarationStatement;
@@ -2330,28 +2195,24 @@
       var declIndex = statements.indexOf(declStatement);
       if (declIndex < statements.length - 1) {
       } else {
-        _coverageMarker();
         return;
       }
       // next Statement should be assignment
       var assignStatement = statements[declIndex + 1];
       if (assignStatement is ExpressionStatement) {
       } else {
-        _coverageMarker();
         return;
       }
       var expressionStatement = assignStatement as ExpressionStatement;
       // expression should be assignment
       if (expressionStatement.expression is AssignmentExpression) {
       } else {
-        _coverageMarker();
         return;
       }
       assignExpression = expressionStatement.expression as AssignmentExpression;
     }
     // check that pure assignment
     if (assignExpression.operator.type != TokenType.EQ) {
-      _coverageMarker();
       return;
     }
 
@@ -2364,13 +2225,6 @@
         changeBuilder, DartAssistKind.JOIN_VARIABLE_DECLARATION);
   }
 
-  Future<void> _addProposal_removeTypeAnnotation() async {
-    // todo (pq): unify w/ fix (and then add a guard to not assist on lints:
-    // avoid_return_types_on_setters, type_init_formals)
-    final changeBuilder = await createBuilder_removeTypeAnnotation();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.REMOVE_TYPE_ANNOTATION);
-  }
-
   Future<void> _addProposal_reparentFlutterList() async {
     if (node is! ListLiteral) {
       return;
@@ -2378,13 +2232,11 @@
     if ((node as ListLiteral).elements.any((CollectionElement exp) =>
         !(exp is InstanceCreationExpression &&
             flutter.isWidgetCreation(exp)))) {
-      _coverageMarker();
       return;
     }
     var literalSrc = utils.getNodeText(node);
     var newlineIdx = literalSrc.lastIndexOf(eol);
     if (newlineIdx < 0 || newlineIdx == literalSrc.length - 1) {
-      _coverageMarker();
       return; // Lists need to be in multi-line format already.
     }
     var indentOld = utils.getLinePrefix(node.offset + 1 + newlineIdx);
@@ -2422,7 +2274,6 @@
     // may be on Statement with Conditional
     var statement = node.thisOrAncestorOfType<Statement>();
     if (statement == null) {
-      _coverageMarker();
       return;
     }
     // variable declaration
@@ -2520,7 +2371,6 @@
   Future<void> _addProposal_replaceIfElseWithConditional() async {
     // should be "if"
     if (node is! IfStatement) {
-      _coverageMarker();
       return;
     }
     var ifStatement = node as IfStatement;
@@ -2528,7 +2378,6 @@
     var thenStatement = getSingleStatement(ifStatement.thenStatement);
     var elseStatement = getSingleStatement(ifStatement.elseStatement);
     if (thenStatement == null || elseStatement == null) {
-      _coverageMarker();
       return;
     }
     Expression thenExpression;
@@ -2583,63 +2432,6 @@
     }
   }
 
-  Future<void> _addProposal_replaceWithVar() async {
-    /// Return `true` if the type in the [node] can be replaced with `var`.
-    bool canConvertVariableDeclarationList(VariableDeclarationList node) {
-      final staticType = node?.type?.type;
-      if (staticType == null || staticType.isDynamic) {
-        return false;
-      }
-      for (final child in node.variables) {
-        var initializer = child.initializer;
-        if (initializer == null || initializer.staticType != staticType) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /// Return `true` if the given node can be replaced with `var`.
-    bool canReplaceWithVar() {
-      var parent = node.parent;
-      while (parent != null) {
-        if (parent is VariableDeclarationStatement) {
-          return canConvertVariableDeclarationList(parent.variables);
-        } else if (parent is ForPartsWithDeclarations) {
-          return canConvertVariableDeclarationList(parent.variables);
-        } else if (parent is ForEachPartsWithDeclaration) {
-          var loopVariableType = parent.loopVariable.type;
-          var staticType = loopVariableType?.type;
-          if (staticType == null || staticType.isDynamic) {
-            return false;
-          }
-          final iterableType = parent.iterable.staticType;
-          if (iterableType is InterfaceTypeImpl) {
-            var instantiatedType =
-                iterableType.asInstanceOf(typeProvider.iterableElement);
-            if (instantiatedType?.typeArguments?.first == staticType) {
-              return true;
-            }
-          }
-          return false;
-        }
-        parent = parent.parent;
-      }
-      return false;
-    }
-
-    if (canReplaceWithVar()) {
-      var changeBuilder = await createBuilder_replaceWithVar();
-      _addAssistFromBuilder(changeBuilder, DartAssistKind.REPLACE_WITH_VAR);
-    }
-  }
-
-  Future<void> _addProposal_sortChildPropertyLast() async {
-    final changeBuilder = await createBuilder_sortChildPropertyLast();
-    _addAssistFromBuilder(
-        changeBuilder, DartAssistKind.SORT_CHILD_PROPERTY_LAST);
-  }
-
   Future<void> _addProposal_splitVariableDeclaration() async {
     var variableList = node?.thisOrAncestorOfType<VariableDeclarationList>();
 
@@ -2924,24 +2716,6 @@
     }
   }
 
-  Future<void> _addProposal_useCurlyBraces() async {
-    final changeBuilder = await createBuilder_useCurlyBraces();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
-  }
-
-  Future<void> _addProposals_addTypeAnnotation() async {
-    var changeBuilder =
-        await createBuilder_addTypeAnnotation_DeclaredIdentifier();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
-
-    changeBuilder =
-        await createBuilder_addTypeAnnotation_SimpleFormalParameter();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
-
-    changeBuilder = await createBuilder_addTypeAnnotation_VariableDeclaration();
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
   bool _containsErrorCode(Set<String> errorCodes) {
     final fileOffset = node.offset;
     for (var error in context.resolveResult.errors) {
@@ -3000,9 +2774,27 @@
     }
   }
 
-  Future<void> _convertQuotes(bool fromDouble, AssistKind kind) async {
-    final changeBuilder = await createBuilder_convertQuotes(fromDouble);
-    _addAssistFromBuilder(changeBuilder, kind);
+  FunctionBody _getEnclosingFunctionBody() {
+    // This is duplicated from [CorrectionProducer] and should be replaced by
+    // that method when the assists that reference it are converted to be
+    // producers.
+    var closure = node.thisOrAncestorOfType<FunctionExpression>();
+    if (closure != null) {
+      return closure.body;
+    }
+    var function = node.thisOrAncestorOfType<FunctionDeclaration>();
+    if (function != null) {
+      return function.functionExpression.body;
+    }
+    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+    if (constructor != null) {
+      return constructor.body;
+    }
+    var method = node.thisOrAncestorOfType<MethodDeclaration>();
+    if (method != null) {
+      return method.body;
+    }
+    return null;
   }
 
   /// Returns the text of the given node in the unit.
@@ -3023,7 +2815,6 @@
       InstanceCreationExpression child, AssistKind kind) async {
     // The child must have its own child.
     if (flutter.findChildArgument(child) == null) {
-      _coverageMarker();
       return;
     }
 
@@ -3099,13 +2890,6 @@
     _addAssistFromBuilder(changeBuilder, kind);
   }
 
-  /// This method does nothing, but we invoke it in places where Dart VM
-  /// coverage agent fails to provide coverage information - such as almost
-  /// all "return" statements.
-  ///
-  /// https://code.google.com/p/dart/issues/detail?id=19912
-  static void _coverageMarker() {}
-
   static String _replaceSourceIndent(
       String source, String indentOld, String indentNew) {
     return source.replaceAll(RegExp('^$indentOld', multiLine: true), indentNew);
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 ecaaa94..2e797a5 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -7,24 +7,13 @@
 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/ast/visitor.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/source/source_range.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.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:meta/meta.dart';
-import 'package:path/path.dart' as path;
 
 /// Base class for common processor functionality.
 abstract class BaseProcessor {
@@ -66,1464 +55,10 @@
       (session.analysisContext.analysisOptions as AnalysisOptionsImpl)
           .experimentStatus;
 
-  Future<ChangeBuilder> createBuilder_addDiagnosticPropertyReference() async {
-    final node = this.node;
-    if (node is! SimpleIdentifier) {
-      _coverageMarker();
-      return null;
-    }
-    SimpleIdentifier name = node;
-    final parent = node.parent;
-
-    DartType type;
-
-    // Getter.
-    if (parent is MethodDeclaration) {
-      var methodDeclaration = parent;
-      var element = methodDeclaration.declaredElement;
-      if (element is PropertyAccessorElement) {
-        var propertyAccessor = element;
-        type = propertyAccessor.returnType;
-      }
-      // Field.
-    } else if (parent is VariableDeclaration) {
-      var variableDeclaration = parent;
-      final element = variableDeclaration.declaredElement;
-      if (element is FieldElement) {
-        var fieldElement = element;
-        type = fieldElement.type;
-      }
-    }
-
-    if (type == null) {
-      return null;
-    }
-
-    var constructorId;
-    var typeArgs;
-    var constructorName = '';
-
-    if (type.element is FunctionTypedElement) {
-      constructorId = 'ObjectFlagProperty';
-      typeArgs = [type];
-      constructorName = '.has';
-    } else if (type.isDartCoreInt) {
-      constructorId = 'IntProperty';
-    } else if (type.isDartCoreDouble) {
-      constructorId = 'DoubleProperty';
-    } else if (type.isDartCoreString) {
-      constructorId = 'StringProperty';
-    } else if (isEnum(type)) {
-      constructorId = 'EnumProperty';
-      typeArgs = [type];
-    } else if (isIterable(type)) {
-      constructorId = 'IterableProperty';
-      typeArgs = (type as InterfaceType).typeArguments;
-    } else if (flutter.isColor(type)) {
-      constructorId = 'ColorProperty';
-    } else if (flutter.isMatrix4(type)) {
-      constructorId = 'TransformProperty';
-    } else {
-      constructorId = 'DiagnosticsProperty';
-      if (!type.isDynamic) {
-        typeArgs = [type];
-      }
-    }
-
-    void writePropertyReference(
-      DartEditBuilder builder, {
-      @required String prefix,
-      @required String builderName,
-    }) {
-      builder.write('$prefix$builderName.add($constructorId');
-      if (typeArgs != null) {
-        builder.write('<');
-        builder.writeTypes(typeArgs);
-        builder.write('>');
-      } else if (type.isDynamic) {
-        TypeAnnotation declType;
-        final decl = node.thisOrAncestorOfType<VariableDeclarationList>();
-        if (decl != null) {
-          declType = decl.type;
-          // getter
-        } else if (parent is MethodDeclaration) {
-          declType = parent.returnType;
-        }
-
-        if (declType != null) {
-          final typeText = utils.getNodeText(declType);
-          if (typeText != 'dynamic') {
-            builder.write('<');
-            builder.write(utils.getNodeText(declType));
-            builder.write('>');
-          }
-        }
-      }
-      builder.writeln("$constructorName('${name.name}', ${name.name}));");
-    }
-
-    final classDeclaration = parent.thisOrAncestorOfType<ClassDeclaration>();
-    final debugFillProperties =
-        classDeclaration.getMethod('debugFillProperties');
-    if (debugFillProperties == null) {
-      final insertOffset =
-          utils.prepareNewMethodLocation(classDeclaration).offset;
-      final changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addInsertion(utils.getLineNext(insertOffset),
-            (DartEditBuilder builder) {
-          final declPrefix =
-              utils.getLinePrefix(classDeclaration.offset) + utils.getIndent(1);
-          final bodyPrefix = declPrefix + utils.getIndent(1);
-
-          builder.writeln('$declPrefix@override');
-          builder.writeln(
-              '${declPrefix}void debugFillProperties(DiagnosticPropertiesBuilder properties) {');
-          builder
-              .writeln('${bodyPrefix}super.debugFillProperties(properties);');
-          writePropertyReference(builder,
-              prefix: bodyPrefix, builderName: 'properties');
-          builder.writeln('$declPrefix}');
-        });
-      });
-      return changeBuilder;
-    }
-
-    final body = debugFillProperties.body;
-    if (body is BlockFunctionBody) {
-      var functionBody = body;
-
-      var offset;
-      var prefix;
-      if (functionBody.block.statements.isEmpty) {
-        offset = functionBody.block.leftBracket.offset;
-        prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
-      } else {
-        offset = functionBody.block.statements.last.endToken.offset;
-        prefix = utils.getLinePrefix(offset);
-      }
-
-      var parameters = debugFillProperties.parameters.parameters;
-      var propertiesBuilderName;
-      for (var parameter in parameters) {
-        if (parameter is SimpleFormalParameter) {
-          final type = parameter.type;
-          if (type is TypeName) {
-            if (type.name.name == 'DiagnosticPropertiesBuilder') {
-              propertiesBuilderName = parameter.identifier.name;
-              break;
-            }
-          }
-        }
-      }
-      if (propertiesBuilderName == null) {
-        return null;
-      }
-
-      final changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addInsertion(utils.getLineNext(offset),
-            (DartEditBuilder builder) {
-          writePropertyReference(builder,
-              prefix: prefix, builderName: propertiesBuilderName);
-        });
-      });
-      return changeBuilder;
-    }
-
-    return null;
-  }
-
-  Future<ChangeBuilder>
-      createBuilder_addTypeAnnotation_DeclaredIdentifier() async {
-    var declaredIdentifier = node.thisOrAncestorOfType<DeclaredIdentifier>();
-    if (declaredIdentifier == null) {
-      var forEach = node.thisOrAncestorMatching((node) =>
-              node is ForStatement && node.forLoopParts is ForEachParts)
-          as ForStatement;
-      ForEachParts forEachParts = forEach?.forLoopParts;
-      var offset = node.offset;
-      if (forEach != null &&
-          forEachParts.iterable != null &&
-          offset < forEachParts.iterable.offset) {
-        declaredIdentifier = forEachParts is ForEachPartsWithDeclaration
-            ? forEachParts.loopVariable
-            : null;
-      }
-    }
-    if (declaredIdentifier == null) {
-      _coverageMarker();
-      return null;
-    }
-    // Ensure that there isn't already a type annotation.
-    if (declaredIdentifier.type != null) {
-      _coverageMarker();
-      return null;
-    }
-    var type = declaredIdentifier.declaredElement.type;
-    if (type is! InterfaceType && type is! FunctionType) {
-      _coverageMarker();
-      return null;
-    }
-    _configureTargetLocation(node);
-
-    var changeBuilder = _newDartChangeBuilder();
-    var validChange = true;
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      var keyword = declaredIdentifier.keyword;
-      if (keyword.keyword == Keyword.VAR) {
-        builder.addReplacement(range.token(keyword), (DartEditBuilder builder) {
-          validChange = builder.writeType(type);
-        });
-      } else {
-        builder.addInsertion(declaredIdentifier.identifier.offset,
-            (DartEditBuilder builder) {
-          validChange = builder.writeType(type);
-          builder.write(' ');
-        });
-      }
-    });
-    return validChange ? changeBuilder : null;
-  }
-
-  Future<ChangeBuilder>
-      createBuilder_addTypeAnnotation_SimpleFormalParameter() async {
-    var node = this.node;
-    // should be the name of a simple parameter
-    if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) {
-      _coverageMarker();
-      return null;
-    }
-    SimpleIdentifier name = node;
-    SimpleFormalParameter parameter = node.parent;
-    // the parameter should not have a type
-    if (parameter.type != null) {
-      _coverageMarker();
-      return null;
-    }
-    // prepare the type
-    var type = parameter.declaredElement.type;
-    // TODO(scheglov) If the parameter is in a method declaration, and if the
-    // method overrides a method that has a type for the corresponding
-    // parameter, it would be nice to copy down the type from the overridden
-    // method.
-    if (type is! InterfaceType) {
-      _coverageMarker();
-      return null;
-    }
-    // prepare type source
-    _configureTargetLocation(node);
-
-    var changeBuilder = _newDartChangeBuilder();
-    var validChange = true;
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addInsertion(name.offset, (DartEditBuilder builder) {
-        validChange = builder.writeType(type);
-        builder.write(' ');
-      });
-    });
-    return validChange ? changeBuilder : null;
-  }
-
-  Future<ChangeBuilder>
-      createBuilder_addTypeAnnotation_VariableDeclaration() async {
-    var node = this.node;
-    // prepare VariableDeclarationList
-    var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
-    if (declarationList == null) {
-      _coverageMarker();
-      return null;
-    }
-    // may be has type annotation already
-    if (declarationList.type != null) {
-      _coverageMarker();
-      return null;
-    }
-    // prepare single VariableDeclaration
-    List<VariableDeclaration> variables = declarationList.variables;
-    if (variables.length != 1) {
-      _coverageMarker();
-      return null;
-    }
-    var variable = variables[0];
-    // must be not after the name of the variable
-    if (selectionOffset > variable.name.end) {
-      _coverageMarker();
-      return null;
-    }
-    // we need an initializer to get the type from
-    var initializer = variable.initializer;
-    if (initializer == null) {
-      _coverageMarker();
-      return null;
-    }
-    var type = initializer.staticType;
-    // prepare type source
-    if ((type is! InterfaceType || type.isDartCoreNull) &&
-        type is! FunctionType) {
-      _coverageMarker();
-      return null;
-    }
-    _configureTargetLocation(node);
-
-    var changeBuilder = _newDartChangeBuilder();
-    var validChange = true;
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      var keyword = declarationList.keyword;
-      if (keyword?.keyword == Keyword.VAR) {
-        builder.addReplacement(range.token(keyword), (DartEditBuilder builder) {
-          validChange = builder.writeType(type);
-        });
-      } else {
-        builder.addInsertion(variable.offset, (DartEditBuilder builder) {
-          validChange = builder.writeType(type);
-          builder.write(' ');
-        });
-      }
-    });
-    return validChange ? changeBuilder : null;
-  }
-
-  Future<ConvertToSpreadCollectionsChange>
-      createBuilder_convertAddAllToSpread() async {
-    var node = this.node;
-    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
-      _coverageMarker();
-      return null;
-    }
-    SimpleIdentifier name = node;
-    MethodInvocation invocation = node.parent;
-    if (name != invocation.methodName ||
-        name.name != 'addAll' ||
-        !invocation.isCascaded ||
-        invocation.argumentList.arguments.length != 1) {
-      _coverageMarker();
-      return null;
-    }
-    var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
-    var sections = cascade.cascadeSections;
-    var target = cascade.target;
-    if (target is! ListLiteral || sections[0] != invocation) {
-      // TODO(brianwilkerson) Consider extending this to handle set literals.
-      _coverageMarker();
-      return null;
-    }
-
-    bool isEmptyListLiteral(Expression expression) =>
-        expression is ListLiteral && expression.elements.isEmpty;
-
-    ListLiteral list = target;
-    var argument = invocation.argumentList.arguments[0];
-    String elementText;
-    var change = ConvertToSpreadCollectionsChange();
-    List<String> args;
-    if (argument is BinaryExpression &&
-        argument.operator.type == TokenType.QUESTION_QUESTION) {
-      var right = argument.rightOperand;
-      if (isEmptyListLiteral(right)) {
-        // ..addAll(things ?? const [])
-        // ..addAll(things ?? [])
-        elementText = '...?${utils.getNodeText(argument.leftOperand)}';
-      }
-    } else if (experimentStatus.control_flow_collections &&
-        argument is ConditionalExpression) {
-      var elseExpression = argument.elseExpression;
-      if (isEmptyListLiteral(elseExpression)) {
-        // ..addAll(condition ? things : const [])
-        // ..addAll(condition ? things : [])
-        var conditionText = utils.getNodeText(argument.condition);
-        var thenText = utils.getNodeText(argument.thenExpression);
-        elementText = 'if ($conditionText) ...$thenText';
-      }
-    } else if (argument is ListLiteral) {
-      // ..addAll([ ... ])
-      var elements = argument.elements;
-      if (elements.isEmpty) {
-        // TODO(brianwilkerson) Consider adding a cleanup for the empty list
-        //  case. We can essentially remove the whole invocation because it does
-        //  nothing.
-        return null;
-      }
-      var startOffset = elements.first.offset;
-      var endOffset = elements.last.end;
-      elementText = utils.getText(startOffset, endOffset - startOffset);
-      change.isLineInvocation = true;
-      args = ['addAll'];
-    }
-    elementText ??= '...${utils.getNodeText(argument)}';
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      if (list.elements.isNotEmpty) {
-        // ['a']..addAll(['b', 'c']);
-        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
-      } else {
-        // []..addAll(['b', 'c']);
-        builder.addSimpleInsertion(list.leftBracket.end, elementText);
-      }
-      builder.addDeletion(range.node(invocation));
-    });
-    change.args = args;
-    change.builder = changeBuilder;
-    return change;
-  }
-
-  Future<ChangeBuilder>
-      createBuilder_convertConditionalExpressionToIfElement() async {
-    AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
-    if (node == null) {
-      _coverageMarker();
-      return null;
-    }
-    var nodeToReplace = node;
-    var parent = node.parent;
-    while (parent is ParenthesizedExpression) {
-      nodeToReplace = parent;
-      parent = parent.parent;
-    }
-    if (parent is ListLiteral || (parent is SetOrMapLiteral && parent.isSet)) {
-      ConditionalExpression conditional = node;
-      var condition = conditional.condition.unParenthesized;
-      var thenExpression = conditional.thenExpression.unParenthesized;
-      var elseExpression = conditional.elseExpression.unParenthesized;
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addReplacement(range.node(nodeToReplace),
-            (DartEditBuilder builder) {
-          builder.write('if (');
-          builder.write(utils.getNodeText(condition));
-          builder.write(') ');
-          builder.write(utils.getNodeText(thenExpression));
-          builder.write(' else ');
-          builder.write(utils.getNodeText(elseExpression));
-        });
-      });
-      return changeBuilder;
-    }
-
-    return null;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertDocumentationIntoLine() async {
-    var comment = node.thisOrAncestorOfType<Comment>();
-    if (comment == null ||
-        !comment.isDocumentation ||
-        comment.tokens.length != 1) {
-      _coverageMarker();
-      return null;
-    }
-    var token = comment.tokens.first;
-    if (token.type != TokenType.MULTI_LINE_COMMENT) {
-      _coverageMarker();
-      return null;
-    }
-    var text = token.lexeme;
-    var lines = text.split('\n');
-    var prefix = utils.getNodePrefix(comment);
-    var newLines = <String>[];
-    var firstLine = true;
-    var linePrefix = '';
-    for (var line in lines) {
-      if (firstLine) {
-        firstLine = false;
-        var expectedPrefix = '/**';
-        if (!line.startsWith(expectedPrefix)) {
-          _coverageMarker();
-          return null;
-        }
-        line = line.substring(expectedPrefix.length).trim();
-        if (line.isNotEmpty) {
-          newLines.add('/// $line');
-          linePrefix = eol + prefix;
-        }
-      } else {
-        if (line.startsWith(prefix + ' */')) {
-          break;
-        }
-        var expectedPrefix = prefix + ' *';
-        if (!line.startsWith(expectedPrefix)) {
-          _coverageMarker();
-          return null;
-        }
-        line = line.substring(expectedPrefix.length);
-        if (line.isEmpty) {
-          newLines.add('$linePrefix///');
-        } else {
-          newLines.add('$linePrefix///$line');
-        }
-        linePrefix = eol + prefix;
-      }
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(comment), (DartEditBuilder builder) {
-        for (var newLine in newLines) {
-          builder.write(newLine);
-        }
-      });
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder>
-      createBuilder_convertMapFromIterableToForLiteral() async {
-    //
-    // Ensure that the selection is inside an invocation of Map.fromIterable.
-    //
-    var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
-    if (creation == null) {
-      _coverageMarker();
-      return null;
-    }
-    var element = creation.staticElement;
-    if (element == null ||
-        element.name != 'fromIterable' ||
-        element.enclosingElement != typeProvider.mapElement) {
-      _coverageMarker();
-      return null;
-    }
-    //
-    // Ensure that the arguments have the right form.
-    //
-    var arguments = creation.argumentList.arguments;
-    if (arguments.length != 3) {
-      _coverageMarker();
-      return null;
-    }
-    var iterator = arguments[0].unParenthesized;
-    var secondArg = arguments[1];
-    var thirdArg = arguments[2];
-
-    Expression extractBody(FunctionExpression expression) {
-      var body = expression.body;
-      if (body is ExpressionFunctionBody) {
-        return body.expression;
-      } else if (body is BlockFunctionBody) {
-        var statements = body.block.statements;
-        if (statements.length == 1) {
-          var statement = statements[0];
-          if (statement is ReturnStatement) {
-            return statement.expression;
-          }
-        }
-      }
-      return null;
-    }
-
-    FunctionExpression extractClosure(String name, Expression argument) {
-      if (argument is NamedExpression && argument.name.label.name == name) {
-        var expression = argument.expression.unParenthesized;
-        if (expression is FunctionExpression) {
-          var parameters = expression.parameters.parameters;
-          if (parameters.length == 1 && parameters[0].isRequiredPositional) {
-            if (extractBody(expression) != null) {
-              return expression;
-            }
-          }
-        }
-      }
-      return null;
-    }
-
-    var keyClosure =
-        extractClosure('key', secondArg) ?? extractClosure('key', thirdArg);
-    var valueClosure =
-        extractClosure('value', thirdArg) ?? extractClosure('value', secondArg);
-    if (keyClosure == null || valueClosure == null) {
-      _coverageMarker();
-      return null;
-    }
-    //
-    // Compute the loop variable name and convert the key and value closures if
-    // necessary.
-    //
-    SimpleFormalParameter keyParameter = keyClosure.parameters.parameters[0];
-    var keyParameterName = keyParameter.identifier.name;
-    SimpleFormalParameter valueParameter =
-        valueClosure.parameters.parameters[0];
-    var valueParameterName = valueParameter.identifier.name;
-    var keyBody = extractBody(keyClosure);
-    var keyExpressionText = utils.getNodeText(keyBody);
-    var valueBody = extractBody(valueClosure);
-    var valueExpressionText = utils.getNodeText(valueBody);
-
-    String loopVariableName;
-    if (keyParameterName == valueParameterName) {
-      loopVariableName = keyParameterName;
-    } else {
-      var keyFinder = _ParameterReferenceFinder(keyParameter.declaredElement);
-      keyBody.accept(keyFinder);
-
-      var valueFinder =
-          _ParameterReferenceFinder(valueParameter.declaredElement);
-      valueBody.accept(valueFinder);
-
-      String computeUnusedVariableName() {
-        var candidate = 'e';
-        var index = 1;
-        while (keyFinder.referencesName(candidate) ||
-            valueFinder.referencesName(candidate)) {
-          candidate = 'e${index++}';
-        }
-        return candidate;
-      }
-
-      if (valueFinder.isParameterUnreferenced) {
-        if (valueFinder.referencesName(keyParameterName)) {
-          // The name of the value parameter is not used, but we can't use the
-          // name of the key parameter because doing so would hide a variable
-          // referenced in the value expression.
-          loopVariableName = computeUnusedVariableName();
-          keyExpressionText = keyFinder.replaceName(
-              keyExpressionText, loopVariableName, keyBody.offset);
-        } else {
-          loopVariableName = keyParameterName;
-        }
-      } else if (keyFinder.isParameterUnreferenced) {
-        if (keyFinder.referencesName(valueParameterName)) {
-          // The name of the key parameter is not used, but we can't use the
-          // name of the value parameter because doing so would hide a variable
-          // referenced in the key expression.
-          loopVariableName = computeUnusedVariableName();
-          valueExpressionText = valueFinder.replaceName(
-              valueExpressionText, loopVariableName, valueBody.offset);
-        } else {
-          loopVariableName = valueParameterName;
-        }
-      } else {
-        // The names are different and both are used. We need to find a name
-        // that would not change the resolution of any other identifiers in
-        // either the key or value expressions.
-        loopVariableName = computeUnusedVariableName();
-        keyExpressionText = keyFinder.replaceName(
-            keyExpressionText, loopVariableName, keyBody.offset);
-        valueExpressionText = valueFinder.replaceName(
-            valueExpressionText, loopVariableName, valueBody.offset);
-      }
-    }
-    //
-    // Construct the edit.
-    //
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
-        builder.write('{ for (var ');
-        builder.write(loopVariableName);
-        builder.write(' in ');
-        builder.write(utils.getNodeText(iterator));
-        builder.write(') ');
-        builder.write(keyExpressionText);
-        builder.write(' : ');
-        builder.write(valueExpressionText);
-        builder.write(' }');
-      });
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertQuotes(bool fromDouble) async {
-    if (node is SimpleStringLiteral) {
-      SimpleStringLiteral literal = node;
-      if (fromDouble ? !literal.isSingleQuoted : literal.isSingleQuoted) {
-        var newQuote = literal.isMultiline
-            ? (fromDouble ? "'''" : '"""')
-            : (fromDouble ? "'" : '"');
-        var quoteLength = literal.isMultiline ? 3 : 1;
-        var lexeme = literal.literal.lexeme;
-        if (!lexeme.contains(newQuote)) {
-          var changeBuilder = _newDartChangeBuilder();
-          await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-            builder.addSimpleReplacement(
-                SourceRange(
-                    literal.offset + (literal.isRaw ? 1 : 0), quoteLength),
-                newQuote);
-            builder.addSimpleReplacement(
-                SourceRange(literal.end - quoteLength, quoteLength), newQuote);
-          });
-          return changeBuilder;
-        }
-      }
-    } else if (node is InterpolationString) {
-      StringInterpolation parent = node.parent;
-      if (fromDouble ? !parent.isSingleQuoted : parent.isSingleQuoted) {
-        var newQuote = parent.isMultiline
-            ? (fromDouble ? "'''" : '"""')
-            : (fromDouble ? "'" : '"');
-        var quoteLength = parent.isMultiline ? 3 : 1;
-        var elements = parent.elements;
-        for (var i = 0; i < elements.length; i++) {
-          var element = elements[i];
-          if (element is InterpolationString) {
-            var lexeme = element.contents.lexeme;
-            if (lexeme.contains(newQuote)) {
-              return null;
-            }
-          }
-        }
-        var changeBuilder = _newDartChangeBuilder();
-        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-          builder.addSimpleReplacement(
-              SourceRange(parent.offset + (parent.isRaw ? 1 : 0), quoteLength),
-              newQuote);
-          builder.addSimpleReplacement(
-              SourceRange(parent.end - quoteLength, quoteLength), newQuote);
-        });
-        return changeBuilder;
-      }
-    }
-    return null;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertToExpressionFunctionBody() async {
-    // prepare current body
-    var body = getEnclosingFunctionBody();
-    if (body is! BlockFunctionBody || body.isGenerator) {
-      _coverageMarker();
-      return null;
-    }
-    // prepare return statement
-    List<Statement> statements = (body as BlockFunctionBody).block.statements;
-    if (statements.length != 1) {
-      _coverageMarker();
-      return null;
-    }
-    var onlyStatement = statements.first;
-    // prepare returned expression
-    Expression returnExpression;
-    if (onlyStatement is ReturnStatement) {
-      returnExpression = onlyStatement.expression;
-    } else if (onlyStatement is ExpressionStatement) {
-      returnExpression = onlyStatement.expression;
-    }
-    if (returnExpression == null) {
-      _coverageMarker();
-      return null;
-    }
-
-    // Return expressions can be quite large, e.g. Flutter build() methods.
-    // It is surprising to see this Quick Assist deep in the function body.
-    if (selectionOffset >= returnExpression.offset) {
-      _coverageMarker();
-      return null;
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(body), (DartEditBuilder builder) {
-        if (body.isAsynchronous) {
-          builder.write('async ');
-        }
-        builder.write('=> ');
-        builder.write(_getNodeText(returnExpression));
-        if (body.parent is! FunctionExpression ||
-            body.parent.parent is FunctionDeclaration) {
-          builder.write(';');
-        }
-      });
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertToGenericFunctionSyntax() async {
-    var node = this.node;
-    while (node != null) {
-      if (node is FunctionTypeAlias) {
-        return _createBuilder_convertFunctionTypeAliasToGenericTypeAlias(node);
-      } else if (node is FunctionTypedFormalParameter) {
-        return _createBuilder_convertFunctionTypedFormalParameterToGenericTypeAlias(
-            node);
-      } else if (node is FormalParameterList) {
-        // It would be confusing for this assist to alter a surrounding context
-        // when the selection is inside a parameter list.
-        return null;
-      }
-      node = node.parent;
-    }
-    return null;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertToIntLiteral() async {
-    if (node is! DoubleLiteral) {
-      _coverageMarker();
-      return null;
-    }
-    DoubleLiteral literal = node;
-    int intValue;
-    try {
-      intValue = literal.value?.truncate();
-    } catch (e) {
-      // Double cannot be converted to int
-    }
-    if (intValue == null || intValue != literal.value) {
-      _coverageMarker();
-      return null;
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(SourceRange(literal.offset, literal.length),
-          (DartEditBuilder builder) {
-        builder.write('$intValue');
-      });
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertToPackageImport() async {
-    var node = this.node;
-    if (node is StringLiteral) {
-      node = node.parent;
-    }
-    if (node is ImportDirective) {
-      var importDirective = node;
-      var uriSource = importDirective.uriSource;
-
-      // Ignore if invalid URI.
-      if (uriSource == null) {
-        return null;
-      }
-
-      var importUri = uriSource.uri;
-      if (importUri.scheme != 'package') {
-        return null;
-      }
-
-      // Don't offer to convert a 'package:' URI to itself.
-      try {
-        if (Uri.parse(importDirective.uriContent).scheme == 'package') {
-          return null;
-        }
-      } on FormatException {
-        return null;
-      }
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        builder.addSimpleReplacement(
-          range.node(importDirective.uri),
-          "'$importUri'",
-        );
-      });
-      return changeBuilder;
-    }
-    return null;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertToRelativeImport() async {
-    var node = this.node;
-    if (node is StringLiteral) {
-      node = node.parent;
-    }
-    if (node is! ImportDirective) {
-      return null;
-    }
-
-    ImportDirective importDirective = node;
-
-    // Ignore if invalid URI.
-    if (importDirective.uriSource == null) {
-      return null;
-    }
-
-    // Ignore if the uri is not a package: uri.
-    var sourceUri = resolvedResult.uri;
-    if (sourceUri.scheme != 'package') {
-      return null;
-    }
-
-    Uri importUri;
-    try {
-      importUri = Uri.parse(importDirective.uriContent);
-    } on FormatException {
-      return null;
-    }
-
-    // Ignore if import uri is not a package: uri.
-    if (importUri.scheme != 'package') {
-      return null;
-    }
-
-    // Verify that the source's uri and the import uri have the same package
-    // name.
-    var sourceSegments = sourceUri.pathSegments;
-    var importSegments = importUri.pathSegments;
-    if (sourceSegments.isEmpty ||
-        importSegments.isEmpty ||
-        sourceSegments.first != importSegments.first) {
-      return null;
-    }
-
-    // We only write posix style paths in import directives.
-    var relativePath = path.posix.relative(
-      importUri.path,
-      from: path.dirname(sourceUri.path),
-    );
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (builder) {
-      builder.addSimpleReplacement(
-        range.node(importDirective.uri).getExpanded(-1),
-        relativePath,
-      );
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder> createBuilder_inlineAdd() async {
-    var node = this.node;
-    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
-      _coverageMarker();
-      return null;
-    }
-    SimpleIdentifier name = node;
-    MethodInvocation invocation = node.parent;
-    if (name != invocation.methodName ||
-        name.name != 'add' ||
-        !invocation.isCascaded ||
-        invocation.argumentList.arguments.length != 1) {
-      _coverageMarker();
-      return null;
-    }
-    var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
-    var sections = cascade.cascadeSections;
-    var target = cascade.target;
-    if (target is! ListLiteral || sections[0] != invocation) {
-      // TODO(brianwilkerson) Consider extending this to handle set literals.
-      _coverageMarker();
-      return null;
-    }
-    ListLiteral list = target;
-    var argument = invocation.argumentList.arguments[0];
-    var elementText = utils.getNodeText(argument);
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      if (list.elements.isNotEmpty) {
-        // ['a']..add(e);
-        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
-      } else {
-        // []..add(e);
-        builder.addSimpleInsertion(list.leftBracket.end, elementText);
-      }
-      builder.addDeletion(range.node(invocation));
-    });
-    return changeBuilder;
-  }
-
-  /// todo (pq): unify with similar behavior in fix.
-  Future<ChangeBuilder> createBuilder_removeTypeAnnotation() async {
-    var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
-    if (declarationList == null) {
-      var declaration = node.thisOrAncestorOfType<DeclaredIdentifier>();
-      if (declaration == null) {
-        _coverageMarker();
-        return null;
-      }
-      var typeNode = declaration.type;
-      if (typeNode == null) {
-        _coverageMarker();
-        return null;
-      }
-      var keyword = declaration.keyword;
-      var variableName = declaration.identifier;
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        var typeRange = range.startStart(typeNode, variableName);
-        if (keyword != null && keyword.lexeme != 'var') {
-          builder.addSimpleReplacement(typeRange, '');
-        } else {
-          builder.addSimpleReplacement(typeRange, 'var ');
-        }
-      });
-      return changeBuilder;
-    }
-    // we need a type
-    var typeNode = declarationList.type;
-    if (typeNode == null) {
-      _coverageMarker();
-      return null;
-    }
-    // ignore if an incomplete variable declaration
-    if (declarationList.variables.length == 1 &&
-        declarationList.variables[0].name.isSynthetic) {
-      _coverageMarker();
-      return null;
-    }
-    // must be not after the name of the variable
-    var firstVariable = declarationList.variables[0];
-    if (selectionOffset > firstVariable.name.end) {
-      _coverageMarker();
-      return null;
-    }
-    // The variable must have an initializer, otherwise there is no other
-    // source for its type.
-    if (firstVariable.initializer == null) {
-      _coverageMarker();
-      return null;
-    }
-    var keyword = declarationList.keyword;
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      var typeRange = range.startStart(typeNode, firstVariable);
-      if (keyword != null && keyword.lexeme != 'var') {
-        builder.addSimpleReplacement(typeRange, '');
-      } else {
-        builder.addSimpleReplacement(typeRange, 'var ');
-      }
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder> createBuilder_replaceWithVar() async {
-    var type = node.thisOrAncestorOfType<TypeAnnotation>();
-    if (type == null) {
-      return null;
-    }
-    var parent = type.parent;
-    var grandparent = parent?.parent;
-    if (parent is VariableDeclarationList &&
-        (grandparent is VariableDeclarationStatement ||
-            grandparent is ForPartsWithDeclarations)) {
-      var variables = parent.variables;
-      if (variables.length != 1) {
-        return null;
-      }
-      var initializer = variables[0].initializer;
-      String typeArgumentsText;
-      int typeArgumentsOffset;
-      if (type is NamedType && type.typeArguments != null) {
-        if (initializer is TypedLiteral) {
-          if (initializer.typeArguments == null) {
-            typeArgumentsText = utils.getNodeText(type.typeArguments);
-            typeArgumentsOffset = initializer.offset;
-          }
-        } else if (initializer is InstanceCreationExpression) {
-          if (initializer.constructorName.type.typeArguments == null) {
-            typeArgumentsText = utils.getNodeText(type.typeArguments);
-            typeArgumentsOffset = initializer.constructorName.type.end;
-          }
-        }
-      }
-      if (initializer is SetOrMapLiteral &&
-          initializer.typeArguments == null &&
-          typeArgumentsText == null) {
-        // TODO(brianwilkerson) This is to prevent the fix from converting a
-        //  valid map or set literal into an ambiguous literal. We could apply
-        //  this in more places by examining the elements of the collection.
-        return null;
-      }
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addSimpleReplacement(range.node(type), 'var');
-        if (typeArgumentsText != null) {
-          builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
-        }
-      });
-      return changeBuilder;
-    } else if (parent is DeclaredIdentifier &&
-        grandparent is ForEachPartsWithDeclaration) {
-      String typeArgumentsText;
-      int typeArgumentsOffset;
-      if (type is NamedType && type.typeArguments != null) {
-        var iterable = grandparent.iterable;
-        if (iterable is TypedLiteral && iterable.typeArguments == null) {
-          typeArgumentsText = utils.getNodeText(type.typeArguments);
-          typeArgumentsOffset = iterable.offset;
-        }
-      }
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addSimpleReplacement(range.node(type), 'var');
-        if (typeArgumentsText != null) {
-          builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
-        }
-      });
-      return changeBuilder;
-    }
-    return null;
-  }
-
-  Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
-    var childProp = flutter.findNamedExpression(node, 'child');
-    childProp ??= flutter.findNamedExpression(node, 'children');
-    if (childProp == null) {
-      return null;
-    }
-
-    var parent = childProp.parent?.parent;
-    if (parent is! InstanceCreationExpression ||
-        !flutter.isWidgetCreation(parent)) {
-      return null;
-    }
-
-    InstanceCreationExpression creationExpression = parent;
-    var args = creationExpression.argumentList;
-
-    var last = args.arguments.last;
-    if (last == childProp) {
-      // Already sorted.
-      return null;
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      var start = childProp.beginToken.previous.end;
-      var end = childProp.endToken.next.end;
-      var childRange = range.startOffsetEndOffset(start, end);
-
-      var childText = utils.getRangeText(childRange);
-      builder.addSimpleReplacement(childRange, '');
-      builder.addSimpleInsertion(last.end + 1, childText);
-
-      changeBuilder.setSelection(Position(file, last.end + 1));
-    });
-
-    return changeBuilder;
-  }
-
-  @protected
-  Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
-    Future<ChangeBuilder> doStatement(DoStatement node) async {
-      var body = node.body;
-      if (body is Block) return null;
-
-      var prefix = utils.getLinePrefix(node.offset);
-      var indent = prefix + utils.getIndent(1);
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        builder.addSimpleReplacement(
-          range.endStart(node.doKeyword, body),
-          ' {$eol$indent',
-        );
-        builder.addSimpleReplacement(
-          range.endStart(body, node.whileKeyword),
-          '$eol$prefix} ',
-        );
-      });
-      return changeBuilder;
-    }
-
-    Future<ChangeBuilder> forStatement(ForStatement node) async {
-      var body = node.body;
-      if (body is Block) return null;
-
-      var prefix = utils.getLinePrefix(node.offset);
-      var indent = prefix + utils.getIndent(1);
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        builder.addSimpleReplacement(
-          range.endStart(node.rightParenthesis, body),
-          ' {$eol$indent',
-        );
-        builder.addSimpleInsertion(body.end, '$eol$prefix}');
-      });
-
-      return changeBuilder;
-    }
-
-    Future<ChangeBuilder> ifStatement(
-        IfStatement node, Statement thenOrElse) async {
-      var prefix = utils.getLinePrefix(node.offset);
-      var indent = prefix + utils.getIndent(1);
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        var thenStatement = node.thenStatement;
-        if (thenStatement is! Block &&
-            (thenOrElse == null || thenOrElse == thenStatement)) {
-          builder.addSimpleReplacement(
-            range.endStart(node.rightParenthesis, thenStatement),
-            ' {$eol$indent',
-          );
-          if (node.elseKeyword != null) {
-            builder.addSimpleReplacement(
-              range.endStart(thenStatement, node.elseKeyword),
-              '$eol$prefix} ',
-            );
-          } else {
-            builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
-          }
-        }
-
-        var elseStatement = node.elseStatement;
-        if (elseStatement != null &&
-            elseStatement is! Block &&
-            (thenOrElse == null || thenOrElse == elseStatement)) {
-          builder.addSimpleReplacement(
-            range.endStart(node.elseKeyword, elseStatement),
-            ' {$eol$indent',
-          );
-          builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
-        }
-      });
-
-      return changeBuilder;
-    }
-
-    Future<ChangeBuilder> whileStatement(WhileStatement node) async {
-      var body = node.body;
-      if (body is Block) return null;
-
-      var prefix = utils.getLinePrefix(node.offset);
-      var indent = prefix + utils.getIndent(1);
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        builder.addSimpleReplacement(
-          range.endStart(node.rightParenthesis, body),
-          ' {$eol$indent',
-        );
-        builder.addSimpleInsertion(body.end, '$eol$prefix}');
-      });
-      return changeBuilder;
-    }
-
-    var statement = node.thisOrAncestorOfType<Statement>();
-    var parent = statement?.parent;
-
-    if (statement is DoStatement) {
-      return doStatement(statement);
-    } else if (parent is DoStatement) {
-      return doStatement(parent);
-    } else if (statement is ForStatement) {
-      return forStatement(statement);
-    } else if (parent is ForStatement) {
-      return forStatement(parent);
-    } else if (statement is IfStatement) {
-      if (statement.elseKeyword != null &&
-          range.token(statement.elseKeyword).contains(selectionOffset)) {
-        return ifStatement(statement, statement.elseStatement);
-      } else {
-        return ifStatement(statement, null);
-      }
-    } else if (parent is IfStatement) {
-      return ifStatement(parent, statement);
-    } else if (statement is WhileStatement) {
-      return whileStatement(statement);
-    } else if (parent is WhileStatement) {
-      return whileStatement(parent);
-    }
-    return null;
-  }
-
-  FunctionBody getEnclosingFunctionBody() {
-    // TODO(brianwilkerson) Determine whether there is a reason why this method
-    // isn't just "return node.getAncestor((node) => node is FunctionBody);"
-    {
-      var function = node.thisOrAncestorOfType<FunctionExpression>();
-      if (function != null) {
-        return function.body;
-      }
-    }
-    {
-      var function = node.thisOrAncestorOfType<FunctionDeclaration>();
-      if (function != null) {
-        return function.functionExpression.body;
-      }
-    }
-    {
-      var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
-      if (constructor != null) {
-        return constructor.body;
-      }
-    }
-    {
-      var method = node.thisOrAncestorOfType<MethodDeclaration>();
-      if (method != null) {
-        return method.body;
-      }
-    }
-    return null;
-  }
-
-  bool isEnum(DartType type) {
-    final element = type.element;
-    return element is ClassElement && element.isEnum;
-  }
-
-  bool isIterable(DartType type) {
-    if (type is! InterfaceType) {
-      return false;
-    }
-
-    ClassElement element = type.element;
-
-    bool isExactIterable(ClassElement element) {
-      return element?.name == 'Iterable' && element.library.isDartCore;
-    }
-
-    if (isExactIterable(element)) {
-      return true;
-    }
-    for (var type in element.allSupertypes) {
-      if (isExactIterable(type.element)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @protected
   bool setupCompute() {
     final locator = NodeLocator(selectionOffset, selectionEnd);
     node = locator.searchWithin(resolvedResult.unit);
     return node != null;
   }
-
-  /// Return `true` if all of the parameters in the given list of [parameters]
-  /// have an explicit type annotation.
-  bool _allParametersHaveTypes(FormalParameterList parameters) {
-    for (var parameter in parameters.parameters) {
-      if (parameter is DefaultFormalParameter) {
-        parameter = (parameter as DefaultFormalParameter).parameter;
-      }
-      if (parameter is SimpleFormalParameter) {
-        if (parameter.type == null) {
-          return false;
-        }
-      } else if (parameter is! FunctionTypedFormalParameter) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /// Configures [utils] using given [target].
-  void _configureTargetLocation(Object target) {
-    utils.targetClassElement = null;
-    if (target is AstNode) {
-      var targetClassDeclaration =
-          target.thisOrAncestorOfType<ClassDeclaration>();
-      if (targetClassDeclaration != null) {
-        utils.targetClassElement = targetClassDeclaration.declaredElement;
-      }
-    }
-  }
-
-  Future<ChangeBuilder>
-      _createBuilder_convertFunctionTypeAliasToGenericTypeAlias(
-          FunctionTypeAlias node) async {
-    if (!_allParametersHaveTypes(node.parameters)) {
-      return null;
-    }
-    String returnType;
-    if (node.returnType != null) {
-      returnType = utils.getNodeText(node.returnType);
-    }
-    var functionName = utils.getRangeText(
-        range.startEnd(node.name, node.typeParameters ?? node.name));
-    var parameters = utils.getNodeText(node.parameters);
-    String replacement;
-    if (returnType == null) {
-      replacement = '$functionName = Function$parameters';
-    } else {
-      replacement = '$functionName = $returnType Function$parameters';
-    }
-    // add change
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addSimpleReplacement(
-          range.startStart(node.typedefKeyword.next, node.semicolon),
-          replacement);
-    });
-    return changeBuilder;
-  }
-
-  Future<ChangeBuilder>
-      _createBuilder_convertFunctionTypedFormalParameterToGenericTypeAlias(
-          FunctionTypedFormalParameter node) async {
-    if (!_allParametersHaveTypes(node.parameters)) {
-      return null;
-    }
-    String returnType;
-    if (node.returnType != null) {
-      returnType = utils.getNodeText(node.returnType);
-    }
-    var functionName = utils.getRangeText(range.startEnd(
-        node.identifier, node.typeParameters ?? node.identifier));
-    var parameters = utils.getNodeText(node.parameters);
-    String replacement;
-    if (returnType == null) {
-      replacement = 'Function$parameters $functionName';
-    } else {
-      replacement = '$returnType Function$parameters $functionName';
-    }
-    // add change
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addSimpleReplacement(range.node(node), replacement);
-    });
-    return changeBuilder;
-  }
-
-  /// Returns the text of the given node in the unit.
-  String /* TODO (pq): make visible */ _getNodeText(AstNode node) =>
-      utils.getNodeText(node);
-
-  DartChangeBuilder _newDartChangeBuilder() =>
-      DartChangeBuilderImpl.forWorkspace(workspace);
-
-  /// This method does nothing, but we invoke it in places where Dart VM
-  /// coverage agent fails to provide coverage information - such as almost
-  /// all "return" statements.
-  ///
-  /// https://code.google.com/p/dart/issues/detail?id=19912
-  static void _coverageMarker() {}
-}
-
-class ConvertToSpreadCollectionsChange {
-  ChangeBuilder builder;
-  List<String> args;
-  bool isLineInvocation = false;
-}
-
-/// A visitor that can be used to find references to a parameter.
-class _ParameterReferenceFinder extends RecursiveAstVisitor<void> {
-  /// The parameter for which references are being sought, or `null` if we are
-  /// just accumulating a list of referenced names.
-  final ParameterElement parameter;
-
-  /// A list of the simple identifiers that reference the [parameter].
-  final List<SimpleIdentifier> references = <SimpleIdentifier>[];
-
-  /// A collection of the names of other simple identifiers that were found. We
-  /// need to know these in order to ensure that the selected loop variable does
-  /// not hide a name from an enclosing scope that is already being referenced.
-  final Set<String> otherNames = <String>{};
-
-  /// Initialize a newly created finder to find references to the [parameter].
-  _ParameterReferenceFinder(this.parameter) : assert(parameter != null);
-
-  /// Return `true` if the parameter is unreferenced in the nodes that have been
-  /// visited.
-  bool get isParameterUnreferenced => references.isEmpty;
-
-  /// Return `true` is the given name (assumed to be different than the name of
-  /// the parameter) is references in the nodes that have been visited.
-  bool referencesName(String name) => otherNames.contains(name);
-
-  /// Replace all of the references to the parameter in the given [source] with
-  /// the [newName]. The [offset] is the offset of the first character of the
-  /// [source] relative to the start of the file.
-  String replaceName(String source, String newName, int offset) {
-    var oldLength = parameter.name.length;
-    for (var i = references.length - 1; i >= 0; i--) {
-      var oldOffset = references[i].offset - offset;
-      source = source.replaceRange(oldOffset, oldOffset + oldLength, newName);
-    }
-    return source;
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (node.staticElement == parameter) {
-      references.add(node);
-    } else if (!node.isQualified) {
-      // Only non-prefixed identifiers can be hidden.
-      otherNames.add(node.name);
-    }
-  }
 }
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 9f7282e..e624242 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
@@ -65,6 +65,28 @@
     _context = context;
   }
 
+  /// Return the function body of the most deeply nested method or function that
+  /// encloses the [node], or `null` if the node is not in a method or function.
+  FunctionBody getEnclosingFunctionBody() {
+    var closure = node.thisOrAncestorOfType<FunctionExpression>();
+    if (closure != null) {
+      return closure.body;
+    }
+    var function = node.thisOrAncestorOfType<FunctionDeclaration>();
+    if (function != null) {
+      return function.functionExpression.body;
+    }
+    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+    if (constructor != null) {
+      return constructor.body;
+    }
+    var method = node.thisOrAncestorOfType<MethodDeclaration>();
+    if (method != null) {
+      return method.body;
+    }
+    return null;
+  }
+
   /// Return the text of the given [range] in the unit.
   String getRangeText(SourceRange range) {
     return utils.getRangeText(range);
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
new file mode 100644
index 0000000..2451a7c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
@@ -0,0 +1,215 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:meta/meta.dart';
+
+class AddDiagnosticPropertyReference extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+  @override
+  FixKind get fixKind => DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    final node = this.node;
+    if (node is! SimpleIdentifier) {
+      return;
+    }
+    SimpleIdentifier name = node;
+    final parent = node.parent;
+
+    var type = _getReturnType(parent);
+    if (type == null) {
+      return;
+    }
+
+    var constructorId;
+    var typeArgs;
+    var constructorName = '';
+
+    if (type.element is FunctionTypedElement) {
+      constructorId = 'ObjectFlagProperty';
+      typeArgs = [type];
+      constructorName = '.has';
+    } else if (type.isDartCoreInt) {
+      constructorId = 'IntProperty';
+    } else if (type.isDartCoreDouble) {
+      constructorId = 'DoubleProperty';
+    } else if (type.isDartCoreString) {
+      constructorId = 'StringProperty';
+    } else if (_isEnum(type)) {
+      constructorId = 'EnumProperty';
+      typeArgs = [type];
+    } else if (_isIterable(type)) {
+      constructorId = 'IterableProperty';
+      typeArgs = (type as InterfaceType).typeArguments;
+    } else if (flutter.isColor(type)) {
+      constructorId = 'ColorProperty';
+    } else if (flutter.isMatrix4(type)) {
+      constructorId = 'TransformProperty';
+    } else {
+      constructorId = 'DiagnosticsProperty';
+      if (!type.isDynamic) {
+        typeArgs = [type];
+      }
+    }
+
+    void writePropertyReference(
+      DartEditBuilder builder, {
+      @required String prefix,
+      @required String builderName,
+    }) {
+      builder.write('$prefix$builderName.add($constructorId');
+      if (typeArgs != null) {
+        builder.write('<');
+        builder.writeTypes(typeArgs);
+        builder.write('>');
+      } else if (type.isDynamic) {
+        TypeAnnotation declType;
+        final decl = node.thisOrAncestorOfType<VariableDeclarationList>();
+        if (decl != null) {
+          declType = decl.type;
+          // getter
+        } else if (parent is MethodDeclaration) {
+          declType = parent.returnType;
+        }
+
+        if (declType != null) {
+          final typeText = utils.getNodeText(declType);
+          if (typeText != 'dynamic') {
+            builder.write('<');
+            builder.write(utils.getNodeText(declType));
+            builder.write('>');
+          }
+        }
+      }
+      builder.writeln("$constructorName('${name.name}', ${name.name}));");
+    }
+
+    final classDeclaration = parent.thisOrAncestorOfType<ClassDeclaration>();
+    final debugFillProperties =
+        classDeclaration.getMethod('debugFillProperties');
+    if (debugFillProperties == null) {
+      final insertOffset =
+          utils.prepareNewMethodLocation(classDeclaration).offset;
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addInsertion(utils.getLineNext(insertOffset),
+            (DartEditBuilder builder) {
+          final declPrefix =
+              utils.getLinePrefix(classDeclaration.offset) + utils.getIndent(1);
+          final bodyPrefix = declPrefix + utils.getIndent(1);
+
+          builder.writeln('$declPrefix@override');
+          builder.writeln(
+              '${declPrefix}void debugFillProperties(DiagnosticPropertiesBuilder properties) {');
+          builder
+              .writeln('${bodyPrefix}super.debugFillProperties(properties);');
+          writePropertyReference(builder,
+              prefix: bodyPrefix, builderName: 'properties');
+          builder.writeln('$declPrefix}');
+        });
+      });
+      return;
+    }
+
+    final body = debugFillProperties.body;
+    if (body is BlockFunctionBody) {
+      var functionBody = body;
+
+      var offset;
+      var prefix;
+      if (functionBody.block.statements.isEmpty) {
+        offset = functionBody.block.leftBracket.offset;
+        prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
+      } else {
+        offset = functionBody.block.statements.last.endToken.offset;
+        prefix = utils.getLinePrefix(offset);
+      }
+
+      var parameters = debugFillProperties.parameters.parameters;
+      var propertiesBuilderName;
+      for (var parameter in parameters) {
+        if (parameter is SimpleFormalParameter) {
+          final type = parameter.type;
+          if (type is TypeName) {
+            if (type.name.name == 'DiagnosticPropertiesBuilder') {
+              propertiesBuilderName = parameter.identifier.name;
+              break;
+            }
+          }
+        }
+      }
+      if (propertiesBuilderName == null) {
+        return null;
+      }
+
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addInsertion(utils.getLineNext(offset),
+            (DartEditBuilder builder) {
+          writePropertyReference(builder,
+              prefix: prefix, builderName: propertiesBuilderName);
+        });
+      });
+    }
+  }
+
+  /// Return the return type of the given [node].
+  DartType _getReturnType(AstNode node) {
+    if (node is MethodDeclaration) {
+      // Getter.
+      var element = node.declaredElement;
+      if (element is PropertyAccessorElement) {
+        return element.returnType;
+      }
+    } else if (node is VariableDeclaration) {
+      // Field.
+      var element = node.declaredElement;
+      if (element is FieldElement) {
+        return element.type;
+      }
+    }
+    return null;
+  }
+
+  bool _isEnum(DartType type) {
+    final element = type.element;
+    return element is ClassElement && element.isEnum;
+  }
+
+  bool _isIterable(DartType type) {
+    if (type is! InterfaceType) {
+      return false;
+    }
+
+    ClassElement element = type.element;
+
+    bool isExactIterable(ClassElement element) {
+      return element?.name == 'Iterable' && element.library.isDartCore;
+    }
+
+    if (isExactIterable(element)) {
+      return true;
+    }
+    for (var type in element.allSupertypes) {
+      if (isExactIterable(type.element)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddDiagnosticPropertyReference newInstance() =>
+      AddDiagnosticPropertyReference();
+}
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 2d5018e..133873f 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
@@ -71,4 +71,7 @@
       }
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddFieldFormalParameters newInstance() => AddFieldFormalParameters();
 }
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
new file mode 100644
index 0000000..ca26be2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package: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_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddRequiredKeyword extends CorrectionProducer {
+  @override
+  FixKind get fixKind => DartFixKind.ADD_REQUIRED2;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleInsertion(node.parent.offset, 'required ');
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddRequiredKeyword newInstance() => AddRequiredKeyword();
+}
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 c1f61c6..7ff6f15 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
@@ -111,6 +111,9 @@
     }
     return baseType;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddReturnType newInstance() => AddReturnType();
 }
 
 /// Copied from lib/src/services/refactoring/extract_method.dart", but
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
new file mode 100644
index 0000000..5361b82
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
@@ -0,0 +1,201 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_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';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class AddTypeAnnotation extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.ADD_TYPE_ANNOTATION;
+
+  @override
+  FixKind get fixKind => DartFixKind.ADD_TYPE_ANNOTATION;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var node = this.node;
+    if (node is SimpleIdentifier) {
+      var parent = node.parent;
+      if (parent is SimpleFormalParameter) {
+        await _forSimpleFormalParameter(builder, node, parent);
+        return;
+      }
+    }
+    while (node != null) {
+      if (node is VariableDeclarationList) {
+        await _forVariableDeclaration(builder, node);
+        return;
+      } else if (node is DeclaredIdentifier) {
+        await _forDeclaredIdentifier(builder, node);
+        return;
+      } else if (node is ForStatement) {
+        var forLoopParts = node.forLoopParts;
+        if (forLoopParts is ForEachParts) {
+          var offset = this.node.offset;
+          if (forLoopParts.iterable != null &&
+              offset < forLoopParts.iterable.offset) {
+            if (forLoopParts is ForEachPartsWithDeclaration) {
+              await _forDeclaredIdentifier(builder, forLoopParts.loopVariable);
+            }
+          }
+        }
+        return;
+      }
+      node = node.parent;
+    }
+  }
+
+  /// Configure the [utils] using the given [target].
+  void _configureTargetLocation(Object target) {
+    utils.targetClassElement = null;
+    if (target is AstNode) {
+      var targetClassDeclaration =
+          target.thisOrAncestorOfType<ClassDeclaration>();
+      if (targetClassDeclaration != null) {
+        utils.targetClassElement = targetClassDeclaration.declaredElement;
+      }
+    }
+  }
+
+  Future<void> _forDeclaredIdentifier(
+      DartChangeBuilder builder, DeclaredIdentifier declaredIdentifier) async {
+    // Ensure that there isn't already a type annotation.
+    if (declaredIdentifier.type != null) {
+      return;
+    }
+    var type = declaredIdentifier.declaredElement.type;
+    if (type is! InterfaceType && type is! FunctionType) {
+      return;
+    }
+    _configureTargetLocation(node);
+
+    Future<bool> applyChange(DartChangeBuilder builder) async {
+      var validChange = true;
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        var keyword = declaredIdentifier.keyword;
+        if (keyword.keyword == Keyword.VAR) {
+          builder.addReplacement(range.token(keyword),
+              (DartEditBuilder builder) {
+            validChange = builder.writeType(type);
+          });
+        } else {
+          builder.addInsertion(declaredIdentifier.identifier.offset,
+              (DartEditBuilder builder) {
+            validChange = builder.writeType(type);
+            builder.write(' ');
+          });
+        }
+      });
+      return validChange;
+    }
+
+    if (await applyChange(_temporaryBuilder(builder))) {
+      await applyChange(builder);
+    }
+  }
+
+  Future<void> _forSimpleFormalParameter(DartChangeBuilder builder,
+      SimpleIdentifier name, SimpleFormalParameter parameter) async {
+    // Ensure that there isn't already a type annotation.
+    if (parameter.type != null) {
+      return;
+    }
+    // Prepare the type.
+    var type = parameter.declaredElement.type;
+    // TODO(scheglov) If the parameter is in a method declaration, and if the
+    // method overrides a method that has a type for the corresponding
+    // parameter, it would be nice to copy down the type from the overridden
+    // method.
+    if (type is! InterfaceType) {
+      return;
+    }
+    _configureTargetLocation(node);
+
+    Future<bool> applyChange(DartChangeBuilder builder) async {
+      var validChange = true;
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addInsertion(name.offset, (DartEditBuilder builder) {
+          validChange = builder.writeType(type);
+          if (validChange) {
+            builder.write(' ');
+          }
+        });
+      });
+      return validChange;
+    }
+
+    if (await applyChange(_temporaryBuilder(builder))) {
+      await applyChange(builder);
+    }
+  }
+
+  Future<void> _forVariableDeclaration(DartChangeBuilder builder,
+      VariableDeclarationList declarationList) async {
+    // Ensure that there isn't already a type annotation.
+    if (declarationList.type != null) {
+      return;
+    }
+    // Ensure that there is a single VariableDeclaration.
+    List<VariableDeclaration> variables = declarationList.variables;
+    if (variables.length != 1) {
+      return;
+    }
+    var variable = variables[0];
+    // Ensure that the selection is not after the name of the variable.
+    if (selectionOffset > variable.name.end) {
+      return;
+    }
+    // Ensure that there is an initializer to get the type from.
+    var initializer = variable.initializer;
+    if (initializer == null) {
+      return;
+    }
+    var type = initializer.staticType;
+    // prepare type source
+    if ((type is! InterfaceType || type.isDartCoreNull) &&
+        type is! FunctionType) {
+      return;
+    }
+    _configureTargetLocation(node);
+
+    Future<bool> applyChange(DartChangeBuilder builder) async {
+      var validChange = true;
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        var keyword = declarationList.keyword;
+        if (keyword?.keyword == Keyword.VAR) {
+          builder.addReplacement(range.token(keyword),
+              (DartEditBuilder builder) {
+            validChange = builder.writeType(type);
+          });
+        } else {
+          builder.addInsertion(variable.offset, (DartEditBuilder builder) {
+            validChange = builder.writeType(type);
+            builder.write(' ');
+          });
+        }
+      });
+      return validChange;
+    }
+
+    if (await applyChange(_temporaryBuilder(builder))) {
+      await applyChange(builder);
+    }
+  }
+
+  DartChangeBuilder _temporaryBuilder(DartChangeBuilder builder) =>
+      DartChangeBuilderImpl.forWorkspace(
+          (builder as DartChangeBuilderImpl).workspace);
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddTypeAnnotation newInstance() => AddTypeAnnotation();
+}
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
new file mode 100644
index 0000000..a6fc1e4
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertAddAllToSpread extends CorrectionProducer {
+  /// The arguments used to compose the message.
+  List<String> args;
+
+  /// A flag indicating whether the change that was built is one that inlines
+  /// the elements of another list into the target list.
+  bool isInlineInvocation = false;
+
+  @override
+  List<Object> get assistArguments => args;
+
+  @override
+  AssistKind get assistKind => isInlineInvocation
+      ? DartAssistKind.INLINE_INVOCATION
+      : DartAssistKind.CONVERT_TO_SPREAD;
+
+  @override
+  List<Object> get fixArguments => args;
+
+  @override
+  FixKind get fixKind => isInlineInvocation
+      ? DartFixKind.INLINE_INVOCATION
+      : DartFixKind.CONVERT_TO_SPREAD;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var node = this.node;
+    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+      return;
+    }
+    SimpleIdentifier name = node;
+    MethodInvocation invocation = node.parent;
+    if (name != invocation.methodName ||
+        name.name != 'addAll' ||
+        !invocation.isCascaded ||
+        invocation.argumentList.arguments.length != 1) {
+      return;
+    }
+    var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
+    var sections = cascade.cascadeSections;
+    var target = cascade.target;
+    if (target is! ListLiteral || sections[0] != invocation) {
+      // TODO(brianwilkerson) Consider extending this to handle set literals.
+      return;
+    }
+
+    bool isEmptyListLiteral(Expression expression) =>
+        expression is ListLiteral && expression.elements.isEmpty;
+
+    ListLiteral list = target;
+    var argument = invocation.argumentList.arguments[0];
+    String elementText;
+    if (argument is BinaryExpression &&
+        argument.operator.type == TokenType.QUESTION_QUESTION) {
+      var right = argument.rightOperand;
+      if (isEmptyListLiteral(right)) {
+        // ..addAll(things ?? const [])
+        // ..addAll(things ?? [])
+        elementText = '...?${utils.getNodeText(argument.leftOperand)}';
+      }
+    } else if (argument is ConditionalExpression) {
+      var elseExpression = argument.elseExpression;
+      if (isEmptyListLiteral(elseExpression)) {
+        // ..addAll(condition ? things : const [])
+        // ..addAll(condition ? things : [])
+        var conditionText = utils.getNodeText(argument.condition);
+        var thenText = utils.getNodeText(argument.thenExpression);
+        elementText = 'if ($conditionText) ...$thenText';
+      }
+    } else if (argument is ListLiteral) {
+      // ..addAll([ ... ])
+      var elements = argument.elements;
+      if (elements.isEmpty) {
+        // TODO(brianwilkerson) Consider adding a cleanup for the empty list
+        //  case. We can essentially remove the whole invocation because it does
+        //  nothing.
+        return null;
+      }
+      var startOffset = elements.first.offset;
+      var endOffset = elements.last.end;
+      elementText = utils.getText(startOffset, endOffset - startOffset);
+      args = ['addAll'];
+      isInlineInvocation = true;
+    }
+    elementText ??= '...${utils.getNodeText(argument)}';
+
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      if (list.elements.isNotEmpty) {
+        // ['a']..addAll(['b', 'c']);
+        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      } else {
+        // []..addAll(['b', 'c']);
+        builder.addSimpleInsertion(list.leftBracket.end, elementText);
+      }
+      builder.addDeletion(range.node(invocation));
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertAddAllToSpread newInstance() => ConvertAddAllToSpread();
+}
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
new file mode 100644
index 0000000..b545497
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package: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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertConditionalExpressionToIfElement extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_IF_ELEMENT;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_IF_ELEMENT;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
+    if (node == null) {
+      return null;
+    }
+    var nodeToReplace = node;
+    var parent = node.parent;
+    while (parent is ParenthesizedExpression) {
+      nodeToReplace = parent;
+      parent = parent.parent;
+    }
+    if (parent is ListLiteral || (parent is SetOrMapLiteral && parent.isSet)) {
+      ConditionalExpression conditional = node;
+      var condition = conditional.condition.unParenthesized;
+      var thenExpression = conditional.thenExpression.unParenthesized;
+      var elseExpression = conditional.elseExpression.unParenthesized;
+
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addReplacement(range.node(nodeToReplace),
+            (DartEditBuilder builder) {
+          builder.write('if (');
+          builder.write(utils.getNodeText(condition));
+          builder.write(') ');
+          builder.write(utils.getNodeText(thenExpression));
+          builder.write(' else ');
+          builder.write(utils.getNodeText(elseExpression));
+        });
+      });
+    }
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertConditionalExpressionToIfElement newInstance() =>
+      ConvertConditionalExpressionToIfElement();
+}
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
new file mode 100644
index 0000000..3288b0c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_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';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertDocumentationIntoLine extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_LINE_COMMENT;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var comment = node.thisOrAncestorOfType<Comment>();
+    if (comment == null ||
+        !comment.isDocumentation ||
+        comment.tokens.length != 1) {
+      return null;
+    }
+    var token = comment.tokens.first;
+    if (token.type != TokenType.MULTI_LINE_COMMENT) {
+      return null;
+    }
+    var text = token.lexeme;
+    var lines = text.split('\n');
+    var prefix = utils.getNodePrefix(comment);
+    var newLines = <String>[];
+    var firstLine = true;
+    var linePrefix = '';
+    for (var line in lines) {
+      if (firstLine) {
+        firstLine = false;
+        var expectedPrefix = '/**';
+        if (!line.startsWith(expectedPrefix)) {
+          return null;
+        }
+        line = line.substring(expectedPrefix.length).trim();
+        if (line.isNotEmpty) {
+          newLines.add('/// $line');
+          linePrefix = eol + prefix;
+        }
+      } else {
+        if (line.startsWith(prefix + ' */')) {
+          break;
+        }
+        var expectedPrefix = prefix + ' *';
+        if (!line.startsWith(expectedPrefix)) {
+          return null;
+        }
+        line = line.substring(expectedPrefix.length);
+        if (line.isEmpty) {
+          newLines.add('$linePrefix///');
+        } else {
+          newLines.add('$linePrefix///$line');
+        }
+        linePrefix = eol + prefix;
+      }
+    }
+
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(comment), (DartEditBuilder builder) {
+        for (var newLine in newLines) {
+          builder.write(newLine);
+        }
+      });
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertDocumentationIntoLine newInstance() =>
+      ConvertDocumentationIntoLine();
+}
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
new file mode 100644
index 0000000..522a60a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertMapFromIterableToForLiteral extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_FOR_ELEMENT;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_FOR_ELEMENT;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    //
+    // Ensure that the selection is inside an invocation of Map.fromIterable.
+    //
+    var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
+    if (creation == null) {
+      return null;
+    }
+    var element = creation.staticElement;
+    if (element == null ||
+        element.name != 'fromIterable' ||
+        element.enclosingElement != typeProvider.mapElement) {
+      return null;
+    }
+    //
+    // Ensure that the arguments have the right form.
+    //
+    var arguments = creation.argumentList.arguments;
+    if (arguments.length != 3) {
+      return null;
+    }
+    var iterator = arguments[0].unParenthesized;
+    var secondArg = arguments[1];
+    var thirdArg = arguments[2];
+
+    Expression extractBody(FunctionExpression expression) {
+      var body = expression.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else if (body is BlockFunctionBody) {
+        var statements = body.block.statements;
+        if (statements.length == 1) {
+          var statement = statements[0];
+          if (statement is ReturnStatement) {
+            return statement.expression;
+          }
+        }
+      }
+      return null;
+    }
+
+    FunctionExpression extractClosure(String name, Expression argument) {
+      if (argument is NamedExpression && argument.name.label.name == name) {
+        var expression = argument.expression.unParenthesized;
+        if (expression is FunctionExpression) {
+          var parameters = expression.parameters.parameters;
+          if (parameters.length == 1 && parameters[0].isRequiredPositional) {
+            if (extractBody(expression) != null) {
+              return expression;
+            }
+          }
+        }
+      }
+      return null;
+    }
+
+    var keyClosure =
+        extractClosure('key', secondArg) ?? extractClosure('key', thirdArg);
+    var valueClosure =
+        extractClosure('value', thirdArg) ?? extractClosure('value', secondArg);
+    if (keyClosure == null || valueClosure == null) {
+      return null;
+    }
+    //
+    // Compute the loop variable name and convert the key and value closures if
+    // necessary.
+    //
+    SimpleFormalParameter keyParameter = keyClosure.parameters.parameters[0];
+    var keyParameterName = keyParameter.identifier.name;
+    SimpleFormalParameter valueParameter =
+        valueClosure.parameters.parameters[0];
+    var valueParameterName = valueParameter.identifier.name;
+    var keyBody = extractBody(keyClosure);
+    var keyExpressionText = utils.getNodeText(keyBody);
+    var valueBody = extractBody(valueClosure);
+    var valueExpressionText = utils.getNodeText(valueBody);
+
+    String loopVariableName;
+    if (keyParameterName == valueParameterName) {
+      loopVariableName = keyParameterName;
+    } else {
+      var keyFinder = _ParameterReferenceFinder(keyParameter.declaredElement);
+      keyBody.accept(keyFinder);
+
+      var valueFinder =
+          _ParameterReferenceFinder(valueParameter.declaredElement);
+      valueBody.accept(valueFinder);
+
+      String computeUnusedVariableName() {
+        var candidate = 'e';
+        var index = 1;
+        while (keyFinder.referencesName(candidate) ||
+            valueFinder.referencesName(candidate)) {
+          candidate = 'e${index++}';
+        }
+        return candidate;
+      }
+
+      if (valueFinder.isParameterUnreferenced) {
+        if (valueFinder.referencesName(keyParameterName)) {
+          // The name of the value parameter is not used, but we can't use the
+          // name of the key parameter because doing so would hide a variable
+          // referenced in the value expression.
+          loopVariableName = computeUnusedVariableName();
+          keyExpressionText = keyFinder.replaceName(
+              keyExpressionText, loopVariableName, keyBody.offset);
+        } else {
+          loopVariableName = keyParameterName;
+        }
+      } else if (keyFinder.isParameterUnreferenced) {
+        if (keyFinder.referencesName(valueParameterName)) {
+          // The name of the key parameter is not used, but we can't use the
+          // name of the value parameter because doing so would hide a variable
+          // referenced in the key expression.
+          loopVariableName = computeUnusedVariableName();
+          valueExpressionText = valueFinder.replaceName(
+              valueExpressionText, loopVariableName, valueBody.offset);
+        } else {
+          loopVariableName = valueParameterName;
+        }
+      } else {
+        // The names are different and both are used. We need to find a name
+        // that would not change the resolution of any other identifiers in
+        // either the key or value expressions.
+        loopVariableName = computeUnusedVariableName();
+        keyExpressionText = keyFinder.replaceName(
+            keyExpressionText, loopVariableName, keyBody.offset);
+        valueExpressionText = valueFinder.replaceName(
+            valueExpressionText, loopVariableName, valueBody.offset);
+      }
+    }
+    //
+    // Construct the edit.
+    //
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
+        builder.write('{ for (var ');
+        builder.write(loopVariableName);
+        builder.write(' in ');
+        builder.write(utils.getNodeText(iterator));
+        builder.write(') ');
+        builder.write(keyExpressionText);
+        builder.write(' : ');
+        builder.write(valueExpressionText);
+        builder.write(' }');
+      });
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertMapFromIterableToForLiteral newInstance() =>
+      ConvertMapFromIterableToForLiteral();
+}
+
+/// A visitor that can be used to find references to a parameter.
+class _ParameterReferenceFinder extends RecursiveAstVisitor<void> {
+  /// The parameter for which references are being sought, or `null` if we are
+  /// just accumulating a list of referenced names.
+  final ParameterElement parameter;
+
+  /// A list of the simple identifiers that reference the [parameter].
+  final List<SimpleIdentifier> references = <SimpleIdentifier>[];
+
+  /// A collection of the names of other simple identifiers that were found. We
+  /// need to know these in order to ensure that the selected loop variable does
+  /// not hide a name from an enclosing scope that is already being referenced.
+  final Set<String> otherNames = <String>{};
+
+  /// Initialize a newly created finder to find references to the [parameter].
+  _ParameterReferenceFinder(this.parameter) : assert(parameter != null);
+
+  /// Return `true` if the parameter is unreferenced in the nodes that have been
+  /// visited.
+  bool get isParameterUnreferenced => references.isEmpty;
+
+  /// Return `true` is the given name (assumed to be different than the name of
+  /// the parameter) is references in the nodes that have been visited.
+  bool referencesName(String name) => otherNames.contains(name);
+
+  /// Replace all of the references to the parameter in the given [source] with
+  /// the [newName]. The [offset] is the offset of the first character of the
+  /// [source] relative to the start of the file.
+  String replaceName(String source, String newName, int offset) {
+    var oldLength = parameter.name.length;
+    for (var i = references.length - 1; i >= 0; i--) {
+      var oldOffset = references[i].offset - offset;
+      source = source.replaceRange(oldOffset, oldOffset + oldLength, newName);
+    }
+    return source;
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.staticElement == parameter) {
+      references.add(node);
+    } else if (!node.isQualified) {
+      // Only non-prefixed identifiers can be hidden.
+      otherNames.add(node.name);
+    }
+  }
+}
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
new file mode 100644
index 0000000..52e7880
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+abstract class ConvertQuotes extends CorrectionProducer {
+  ConvertQuotes();
+
+  /// Return `true` if this producer is converting from double quotes to single
+  /// quotes, or `false` if it's converting from single quotes to double quotes.
+  bool get fromDouble;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    if (node is SimpleStringLiteral) {
+      SimpleStringLiteral literal = node;
+      if (fromDouble ? !literal.isSingleQuoted : literal.isSingleQuoted) {
+        var newQuote = literal.isMultiline
+            ? (fromDouble ? "'''" : '"""')
+            : (fromDouble ? "'" : '"');
+        var quoteLength = literal.isMultiline ? 3 : 1;
+        var lexeme = literal.literal.lexeme;
+        if (!lexeme.contains(newQuote)) {
+          await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+            builder.addSimpleReplacement(
+                SourceRange(
+                    literal.offset + (literal.isRaw ? 1 : 0), quoteLength),
+                newQuote);
+            builder.addSimpleReplacement(
+                SourceRange(literal.end - quoteLength, quoteLength), newQuote);
+          });
+        }
+      }
+    } else if (node is InterpolationString) {
+      StringInterpolation parent = node.parent;
+      if (fromDouble ? !parent.isSingleQuoted : parent.isSingleQuoted) {
+        var newQuote = parent.isMultiline
+            ? (fromDouble ? "'''" : '"""')
+            : (fromDouble ? "'" : '"');
+        var quoteLength = parent.isMultiline ? 3 : 1;
+        var elements = parent.elements;
+        for (var i = 0; i < elements.length; i++) {
+          var element = elements[i];
+          if (element is InterpolationString) {
+            var lexeme = element.contents.lexeme;
+            if (lexeme.contains(newQuote)) {
+              return null;
+            }
+          }
+        }
+        await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+          builder.addSimpleReplacement(
+              SourceRange(parent.offset + (parent.isRaw ? 1 : 0), quoteLength),
+              newQuote);
+          builder.addSimpleReplacement(
+              SourceRange(parent.end - quoteLength, quoteLength), newQuote);
+        });
+      }
+    }
+  }
+}
+
+class ConvertToDoubleQuotes extends ConvertQuotes {
+  ConvertToDoubleQuotes();
+
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING;
+
+  @override
+  bool get fromDouble => false;
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToDoubleQuotes newInstance() => ConvertToDoubleQuotes();
+}
+
+class ConvertToSingleQuotes extends ConvertQuotes {
+  ConvertToSingleQuotes();
+
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING;
+
+  @override
+  bool get fromDouble => true;
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToSingleQuotes newInstance() => ConvertToSingleQuotes();
+}
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 f80ac75..8be4d1b 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
@@ -138,6 +138,9 @@
     // so we should never reach this point.
     return NegationStyle.none;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToContains newInstance() => ConvertToContains();
 }
 
 /// An indication of whether the `contains` test should be negated, not negated,
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
new file mode 100644
index 0000000..0e4b2c9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToExpressionFunctionBody extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_INTO_EXPRESSION_BODY;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_INTO_EXPRESSION_BODY;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    // prepare current body
+    var body = getEnclosingFunctionBody();
+    if (body is! BlockFunctionBody || body.isGenerator) {
+      return;
+    }
+    // prepare return statement
+    List<Statement> statements = (body as BlockFunctionBody).block.statements;
+    if (statements.length != 1) {
+      return;
+    }
+    var onlyStatement = statements.first;
+    // prepare returned expression
+    Expression returnExpression;
+    if (onlyStatement is ReturnStatement) {
+      returnExpression = onlyStatement.expression;
+    } else if (onlyStatement is ExpressionStatement) {
+      returnExpression = onlyStatement.expression;
+    }
+    if (returnExpression == null) {
+      return;
+    }
+
+    // Return expressions can be quite large, e.g. Flutter build() methods.
+    // It is surprising to see this Quick Assist deep in the function body.
+    if (selectionOffset >= returnExpression.offset) {
+      return;
+    }
+
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(body), (DartEditBuilder builder) {
+        if (body.isAsynchronous) {
+          builder.write('async ');
+        }
+        builder.write('=> ');
+        builder.write(utils.getNodeText(returnExpression));
+        if (body.parent is! FunctionExpression ||
+            body.parent.parent is FunctionDeclaration) {
+          builder.write(';');
+        }
+      });
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToExpressionFunctionBody newInstance() =>
+      ConvertToExpressionFunctionBody();
+}
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
new file mode 100644
index 0000000..d62d9eb
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToGenericFunctionSyntax extends CorrectionProducer {
+  @override
+  AssistKind get assistKind =>
+      DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var node = this.node;
+    while (node != null) {
+      if (node is FunctionTypeAlias) {
+        return _convertFunctionTypeAlias(builder, node);
+      } else if (node is FunctionTypedFormalParameter) {
+        return _convertFunctionTypedFormalParameter(builder, node);
+      } else if (node is FormalParameterList) {
+        // It would be confusing for this assist to alter a surrounding context
+        // when the selection is inside a parameter list.
+        return null;
+      }
+      node = node.parent;
+    }
+  }
+
+  /// Return `true` if all of the parameters in the given list of [parameters]
+  /// have an explicit type annotation.
+  bool _allParametersHaveTypes(FormalParameterList parameters) {
+    for (var parameter in parameters.parameters) {
+      if (parameter is DefaultFormalParameter) {
+        parameter = (parameter as DefaultFormalParameter).parameter;
+      }
+      if (parameter is SimpleFormalParameter) {
+        if (parameter.type == null) {
+          return false;
+        }
+      } else if (parameter is! FunctionTypedFormalParameter) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  Future<void> _convertFunctionTypeAlias(
+      DartChangeBuilder builder, FunctionTypeAlias node) async {
+    if (!_allParametersHaveTypes(node.parameters)) {
+      return;
+    }
+    String returnType;
+    if (node.returnType != null) {
+      returnType = utils.getNodeText(node.returnType);
+    }
+    var functionName = utils.getRangeText(
+        range.startEnd(node.name, node.typeParameters ?? node.name));
+    var parameters = utils.getNodeText(node.parameters);
+    String replacement;
+    if (returnType == null) {
+      replacement = '$functionName = Function$parameters';
+    } else {
+      replacement = '$functionName = $returnType Function$parameters';
+    }
+    // add change
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleReplacement(
+          range.startStart(node.typedefKeyword.next, node.semicolon),
+          replacement);
+    });
+  }
+
+  Future<void> _convertFunctionTypedFormalParameter(
+      DartChangeBuilder builder, FunctionTypedFormalParameter node) async {
+    if (!_allParametersHaveTypes(node.parameters)) {
+      return;
+    }
+    String returnType;
+    if (node.returnType != null) {
+      returnType = utils.getNodeText(node.returnType);
+    }
+    var functionName = utils.getRangeText(range.startEnd(
+        node.identifier, node.typeParameters ?? node.identifier));
+    var parameters = utils.getNodeText(node.parameters);
+    String replacement;
+    if (returnType == null) {
+      replacement = 'Function$parameters $functionName';
+    } else {
+      replacement = '$returnType Function$parameters $functionName';
+    }
+    // add change
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleReplacement(range.node(node), replacement);
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToGenericFunctionSyntax newInstance() =>
+      ConvertToGenericFunctionSyntax();
+}
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
new file mode 100644
index 0000000..72d1338
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToIntLiteral extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_INT_LITERAL;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_INT_LITERAL;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    if (node is! DoubleLiteral) {
+      return;
+    }
+    DoubleLiteral literal = node;
+    int intValue;
+    try {
+      intValue = literal.value?.truncate();
+    } catch (e) {
+      // Double cannot be converted to int
+    }
+    if (intValue == null || intValue != literal.value) {
+      return;
+    }
+
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(SourceRange(literal.offset, literal.length),
+          (DartEditBuilder builder) {
+        builder.write('$intValue');
+      });
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToIntLiteral newInstance() => ConvertToIntLiteral();
+}
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 1c4dda0..c3ecab5 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
@@ -47,4 +47,7 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToListLiteral newInstance() => ConvertToListLiteral();
 }
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 b8098ce..daccb53 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
@@ -57,4 +57,7 @@
       (element == typeProvider.mapElement ||
           (element.name == 'LinkedHashMap' &&
               element.library.name == 'dart.collection'));
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToMapLiteral newInstance() => ConvertToMapLiteral();
 }
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 adace32..18604d3 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
@@ -102,4 +102,7 @@
       });
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToNullAware newInstance() => ConvertToNullAware();
 }
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
new file mode 100644
index 0000000..2df2ee0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToOnType extends CorrectionProducer {
+  @override
+  final List<Object> fixArguments = [];
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_ON_TYPE;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var exceptionParameter = node;
+    if (exceptionParameter is SimpleIdentifier) {
+      var catchClause = exceptionParameter.parent;
+      if (catchClause is CatchClause &&
+          catchClause.exceptionType == null &&
+          catchClause.exceptionParameter == exceptionParameter) {
+        var exceptionTypeName = exceptionParameter.name;
+        fixArguments.add(exceptionTypeName);
+        await builder.addFileEdit(file, (builder) {
+          if (catchClause.stackTraceParameter != null) {
+            builder.addSimpleReplacement(
+              range.startStart(
+                catchClause.catchKeyword,
+                catchClause.stackTraceParameter,
+              ),
+              'on $exceptionTypeName catch (_, ',
+            );
+          } else {
+            builder.addSimpleReplacement(
+              range.startEnd(
+                catchClause.catchKeyword,
+                catchClause.rightParenthesis,
+              ),
+              'on $exceptionTypeName',
+            );
+          }
+        });
+      }
+    }
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToOnType newInstance() => ConvertToOnType();
+}
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
new file mode 100644
index 0000000..7856391
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToPackageImport extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_PACKAGE_IMPORT;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_PACKAGE_IMPORT;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var node = this.node;
+    if (node is StringLiteral) {
+      node = node.parent;
+    }
+    if (node is ImportDirective) {
+      var importDirective = node;
+      var uriSource = importDirective.uriSource;
+
+      // Ignore if invalid URI.
+      if (uriSource == null) {
+        return;
+      }
+
+      var importUri = uriSource.uri;
+      if (importUri.scheme != 'package') {
+        return;
+      }
+
+      // Don't offer to convert a 'package:' URI to itself.
+      try {
+        if (Uri.parse(importDirective.uriContent).scheme == 'package') {
+          return;
+        }
+      } on FormatException {
+        return;
+      }
+
+      await builder.addFileEdit(file, (builder) {
+        builder.addSimpleReplacement(
+          range.node(importDirective.uri),
+          "'$importUri'",
+        );
+      });
+    }
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToPackageImport newInstance() => ConvertToPackageImport();
+}
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
new file mode 100644
index 0000000..eea6658
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+import 'package:path/path.dart' as path;
+
+class ConvertToRelativeImport extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.CONVERT_TO_RELATIVE_IMPORT;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_RELATIVE_IMPORT;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var node = this.node;
+    if (node is StringLiteral) {
+      node = node.parent;
+    }
+    if (node is! ImportDirective) {
+      return;
+    }
+
+    ImportDirective importDirective = node;
+
+    // Ignore if invalid URI.
+    if (importDirective.uriSource == null) {
+      return;
+    }
+
+    // Ignore if the uri is not a package: uri.
+    var sourceUri = resolvedResult.uri;
+    if (sourceUri.scheme != 'package') {
+      return;
+    }
+
+    Uri importUri;
+    try {
+      importUri = Uri.parse(importDirective.uriContent);
+    } on FormatException {
+      return;
+    }
+
+    // Ignore if import uri is not a package: uri.
+    if (importUri.scheme != 'package') {
+      return;
+    }
+
+    // Verify that the source's uri and the import uri have the same package
+    // name.
+    var sourceSegments = sourceUri.pathSegments;
+    var importSegments = importUri.pathSegments;
+    if (sourceSegments.isEmpty ||
+        importSegments.isEmpty ||
+        sourceSegments.first != importSegments.first) {
+      return;
+    }
+
+    // We only write posix style paths in import directives.
+    var relativePath = path.posix.relative(
+      importUri.path,
+      from: path.dirname(sourceUri.path),
+    );
+
+    await builder.addFileEdit(file, (builder) {
+      builder.addSimpleReplacement(
+        range.node(importDirective.uri).getExpanded(-1),
+        relativePath,
+      );
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToRelativeImport newInstance() => ConvertToRelativeImport();
+}
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 bf39226..dde8458 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
@@ -181,4 +181,7 @@
     }
     return _hasUnambiguousElement(creation);
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToSetLiteral newInstance() => ConvertToSetLiteral();
 }
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 fd1a83d..7d66b0e 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
@@ -55,4 +55,7 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToWhereType newInstance() => ConvertToWhereType();
 }
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
new file mode 100644
index 0000000..1788e09
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class InlineInvocation extends CorrectionProducer {
+  @override
+  List<Object> get assistArguments => ['add'];
+
+  @override
+  AssistKind get assistKind => DartAssistKind.INLINE_INVOCATION;
+
+  @override
+  List<Object> get fixArguments => ['add'];
+
+  @override
+  FixKind get fixKind => DartFixKind.INLINE_INVOCATION;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var node = this.node;
+    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+      return;
+    }
+    SimpleIdentifier name = node;
+    MethodInvocation invocation = node.parent;
+    if (name != invocation.methodName ||
+        name.name != 'add' ||
+        !invocation.isCascaded ||
+        invocation.argumentList.arguments.length != 1) {
+      return;
+    }
+    var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
+    var sections = cascade.cascadeSections;
+    var target = cascade.target;
+    if (target is! ListLiteral || sections[0] != invocation) {
+      // TODO(brianwilkerson) Consider extending this to handle set literals.
+      return;
+    }
+    ListLiteral list = target;
+    var argument = invocation.argumentList.arguments[0];
+    var elementText = utils.getNodeText(argument);
+
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      if (list.elements.isNotEmpty) {
+        // ['a']..add(e);
+        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      } else {
+        // []..add(e);
+        builder.addSimpleInsertion(list.leftBracket.end, elementText);
+      }
+      builder.addDeletion(range.node(invocation));
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static InlineInvocation newInstance() => InlineInvocation();
+}
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 82832ec..6235f74 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
@@ -123,6 +123,9 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static InlineTypedef newInstance() => InlineTypedef();
 }
 
 class _ReferenceFinder extends RecursiveAstVisitor {
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 fc64406..830007a 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
@@ -50,4 +50,7 @@
       builder.addDeletion(sourceRange);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveDeadIfNull newInstance() => RemoveDeadIfNull();
 }
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 aee06f8..4491682 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
@@ -34,4 +34,7 @@
       builder.addDeletion(sourceRange);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveIfNullOperator newInstance() => RemoveIfNullOperator();
 }
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
new file mode 100644
index 0000000..ae50eb6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
@@ -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 file.
+
+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_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveQuestionMark extends CorrectionProducer {
+  @override
+  FixKind get fixKind => DartFixKind.REMOVE_QUESTION_MARK;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    if (node is! SimpleIdentifier || node.parent is! TypeName) {
+      return;
+    }
+    var typeName = node.parent as TypeName;
+    var questionMark = typeName.question;
+    if (questionMark == null) {
+      return;
+    }
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addDeletion(range.token(questionMark));
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveQuestionMark newInstance() => RemoveQuestionMark();
+}
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
new file mode 100644
index 0000000..023a9cf
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveTypeAnnotation extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.REMOVE_TYPE_ANNOTATION;
+
+  @override
+  FixKind get fixKind => DartFixKind.REMOVE_TYPE_ANNOTATION;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    // todo (pq): unify w/ fix (and then add a guard to not assist on lints:
+    //  avoid_return_types_on_setters, type_init_formals)
+    var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
+    if (declarationList == null) {
+      await _removeFromDeclaredIdentifier(builder);
+    } else {
+      await _removeFromDeclarationList(builder, declarationList);
+    }
+  }
+
+  Future<void> _removeFromDeclarationList(DartChangeBuilder builder,
+      VariableDeclarationList declarationList) async {
+    // we need a type
+    var typeNode = declarationList.type;
+    if (typeNode == null) {
+      return;
+    }
+    // ignore if an incomplete variable declaration
+    if (declarationList.variables.length == 1 &&
+        declarationList.variables[0].name.isSynthetic) {
+      return;
+    }
+    // must be not after the name of the variable
+    var firstVariable = declarationList.variables[0];
+    if (selectionOffset > firstVariable.name.end) {
+      return;
+    }
+    // The variable must have an initializer, otherwise there is no other
+    // source for its type.
+    if (firstVariable.initializer == null) {
+      return;
+    }
+    var keyword = declarationList.keyword;
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      var typeRange = range.startStart(typeNode, firstVariable);
+      if (keyword != null && keyword.lexeme != 'var') {
+        builder.addSimpleReplacement(typeRange, '');
+      } else {
+        builder.addSimpleReplacement(typeRange, 'var ');
+      }
+    });
+  }
+
+  Future<void> _removeFromDeclaredIdentifier(DartChangeBuilder builder) async {
+    var declaration = node.thisOrAncestorOfType<DeclaredIdentifier>();
+    if (declaration == null) {
+      return;
+    }
+    var typeNode = declaration.type;
+    if (typeNode == null) {
+      return;
+    }
+    var keyword = declaration.keyword;
+    var variableName = declaration.identifier;
+    await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+      var typeRange = range.startStart(typeNode, variableName);
+      if (keyword != null && keyword.lexeme != 'var') {
+        builder.addSimpleReplacement(typeRange, '');
+      } else {
+        builder.addSimpleReplacement(typeRange, 'var ');
+      }
+    });
+  }
+}
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 525a4ed..9559f6d 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
@@ -54,6 +54,9 @@
       }
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveUnusedElement newInstance() => RemoveUnusedElement();
 }
 
 class RemoveUnusedField extends _RemoveUnused {
@@ -161,6 +164,9 @@
       return range.nodeInList(parent.variables, node);
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveUnusedField newInstance() => RemoveUnusedField();
 }
 
 class _ElementReferenceCollector extends RecursiveAstVisitor<void> {
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 366a7c1..c6b654c 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
@@ -84,4 +84,7 @@
       return null;
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveUnusedLocalVariable newInstance() => RemoveUnusedLocalVariable();
 }
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 3353fe8..ad91c45 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
@@ -36,4 +36,7 @@
       builder.addSimpleReplacement(range.node(node), replacement);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithEightDigitHex newInstance() => ReplaceWithEightDigitHex();
 }
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 bdced61..2c36432 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
@@ -143,6 +143,9 @@
     }
     return false;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithInterpolation newInstance() => ReplaceWithInterpolation();
 }
 
 class _StringStyle {
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
new file mode 100644
index 0000000..2f8f19a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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/src/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ReplaceWithVar extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.REPLACE_WITH_VAR;
+
+  @override
+  FixKind get fixKind => DartFixKind.REPLACE_WITH_VAR;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var type = node.thisOrAncestorOfType<TypeAnnotation>();
+    if (type == null) {
+      return;
+    }
+    // TODO(brianwilkerson) Optimize this by removing the duplication between
+    //  [_canReplaceWithVar] and the rest of this method.
+    if (!_canReplaceWithVar()) {
+      return;
+    }
+    var parent = type.parent;
+    var grandparent = parent?.parent;
+    if (parent is VariableDeclarationList &&
+        (grandparent is VariableDeclarationStatement ||
+            grandparent is ForPartsWithDeclarations)) {
+      var variables = parent.variables;
+      if (variables.length != 1) {
+        return;
+      }
+      var initializer = variables[0].initializer;
+      String typeArgumentsText;
+      int typeArgumentsOffset;
+      if (type is NamedType && type.typeArguments != null) {
+        if (initializer is TypedLiteral) {
+          if (initializer.typeArguments == null) {
+            typeArgumentsText = utils.getNodeText(type.typeArguments);
+            typeArgumentsOffset = initializer.offset;
+          }
+        } else if (initializer is InstanceCreationExpression) {
+          if (initializer.constructorName.type.typeArguments == null) {
+            typeArgumentsText = utils.getNodeText(type.typeArguments);
+            typeArgumentsOffset = initializer.constructorName.type.end;
+          }
+        }
+      }
+      if (initializer is SetOrMapLiteral &&
+          initializer.typeArguments == null &&
+          typeArgumentsText == null) {
+        // TODO(brianwilkerson) This is to prevent the fix from converting a
+        //  valid map or set literal into an ambiguous literal. We could apply
+        //  this in more places by examining the elements of the collection.
+        return;
+      }
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addSimpleReplacement(range.node(type), 'var');
+        if (typeArgumentsText != null) {
+          builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
+        }
+      });
+    } else if (parent is DeclaredIdentifier &&
+        grandparent is ForEachPartsWithDeclaration) {
+      String typeArgumentsText;
+      int typeArgumentsOffset;
+      if (type is NamedType && type.typeArguments != null) {
+        var iterable = grandparent.iterable;
+        if (iterable is TypedLiteral && iterable.typeArguments == null) {
+          typeArgumentsText = utils.getNodeText(type.typeArguments);
+          typeArgumentsOffset = iterable.offset;
+        }
+      }
+      await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addSimpleReplacement(range.node(type), 'var');
+        if (typeArgumentsText != null) {
+          builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
+        }
+      });
+    }
+  }
+
+  /// Return `true` if the type in the [node] can be replaced with `var`.
+  bool _canConvertVariableDeclarationList(VariableDeclarationList node) {
+    final staticType = node?.type?.type;
+    if (staticType == null || staticType.isDynamic) {
+      return false;
+    }
+    for (final child in node.variables) {
+      var initializer = child.initializer;
+      if (initializer == null || initializer.staticType != staticType) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// Return `true` if the [node] can be replaced with `var`.
+  bool _canReplaceWithVar() {
+    var parent = node.parent;
+    while (parent != null) {
+      if (parent is VariableDeclarationStatement) {
+        return _canConvertVariableDeclarationList(parent.variables);
+      } else if (parent is ForPartsWithDeclarations) {
+        return _canConvertVariableDeclarationList(parent.variables);
+      } else if (parent is ForEachPartsWithDeclaration) {
+        var loopVariableType = parent.loopVariable.type;
+        var staticType = loopVariableType?.type;
+        if (staticType == null || staticType.isDynamic) {
+          return false;
+        }
+        final iterableType = parent.iterable.staticType;
+        if (iterableType is InterfaceTypeImpl) {
+          var instantiatedType =
+              iterableType.asInstanceOf(typeProvider.iterableElement);
+          if (instantiatedType?.typeArguments?.first == staticType) {
+            return true;
+          }
+        }
+        return false;
+      }
+      parent = parent.parent;
+    }
+    return false;
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithVar newInstance() => ReplaceWithVar();
+}
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
new file mode 100644
index 0000000..c4a0c23
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class SortChildPropertyLast extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.SORT_CHILD_PROPERTY_LAST;
+
+  @override
+  FixKind get fixKind => DartFixKind.SORT_CHILD_PROPERTY_LAST;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var childProp = flutter.findNamedExpression(node, 'child');
+    childProp ??= flutter.findNamedExpression(node, 'children');
+    if (childProp == null) {
+      return;
+    }
+
+    var parent = childProp.parent?.parent;
+    if (parent is! InstanceCreationExpression ||
+        !flutter.isWidgetCreation(parent)) {
+      return;
+    }
+
+    InstanceCreationExpression creationExpression = parent;
+    var args = creationExpression.argumentList;
+
+    var last = args.arguments.last;
+    if (last == childProp) {
+      // Already sorted.
+      return;
+    }
+
+    await builder.addFileEdit(file, (DartFileEditBuilder fileEditBuilder) {
+      var start = childProp.beginToken.previous.end;
+      var end = childProp.endToken.next.end;
+      var childRange = range.startOffsetEndOffset(start, end);
+
+      var childText = utils.getRangeText(childRange);
+      fileEditBuilder.addSimpleReplacement(childRange, '');
+      fileEditBuilder.addSimpleInsertion(last.end + 1, childText);
+
+      builder.setSelection(Position(file, last.end + 1));
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static SortChildPropertyLast newInstance() => SortChildPropertyLast();
+}
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
new file mode 100644
index 0000000..620e21e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
@@ -0,0 +1,141 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/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_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class UseCurlyBraces extends CorrectionProducer {
+  @override
+  AssistKind get assistKind => DartAssistKind.USE_CURLY_BRACES;
+
+  @override
+  FixKind get fixKind => DartFixKind.ADD_CURLY_BRACES;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var statement = node.thisOrAncestorOfType<Statement>();
+    var parent = statement?.parent;
+
+    if (statement is DoStatement) {
+      return _doStatement(builder, statement);
+    } else if (parent is DoStatement) {
+      return _doStatement(builder, parent);
+    } else if (statement is ForStatement) {
+      return _forStatement(builder, statement);
+    } else if (parent is ForStatement) {
+      return _forStatement(builder, parent);
+    } else if (statement is IfStatement) {
+      if (statement.elseKeyword != null &&
+          range.token(statement.elseKeyword).contains(selectionOffset)) {
+        return _ifStatement(builder, statement, statement.elseStatement);
+      } else {
+        return _ifStatement(builder, statement, null);
+      }
+    } else if (parent is IfStatement) {
+      return _ifStatement(builder, parent, statement);
+    } else if (statement is WhileStatement) {
+      return _whileStatement(builder, statement);
+    } else if (parent is WhileStatement) {
+      return _whileStatement(builder, parent);
+    }
+  }
+
+  Future<void> _doStatement(DartChangeBuilder builder, DoStatement node) async {
+    var body = node.body;
+    if (body is Block) return null;
+
+    var prefix = utils.getLinePrefix(node.offset);
+    var indent = prefix + utils.getIndent(1);
+
+    await builder.addFileEdit(file, (builder) {
+      builder.addSimpleReplacement(
+        range.endStart(node.doKeyword, body),
+        ' {$eol$indent',
+      );
+      builder.addSimpleReplacement(
+        range.endStart(body, node.whileKeyword),
+        '$eol$prefix} ',
+      );
+    });
+  }
+
+  Future<void> _forStatement(
+      DartChangeBuilder builder, ForStatement node) async {
+    var body = node.body;
+    if (body is Block) return null;
+
+    var prefix = utils.getLinePrefix(node.offset);
+    var indent = prefix + utils.getIndent(1);
+
+    await builder.addFileEdit(file, (builder) {
+      builder.addSimpleReplacement(
+        range.endStart(node.rightParenthesis, body),
+        ' {$eol$indent',
+      );
+      builder.addSimpleInsertion(body.end, '$eol$prefix}');
+    });
+  }
+
+  Future<void> _ifStatement(
+      DartChangeBuilder builder, IfStatement node, Statement thenOrElse) async {
+    var prefix = utils.getLinePrefix(node.offset);
+    var indent = prefix + utils.getIndent(1);
+
+    await builder.addFileEdit(file, (builder) {
+      var thenStatement = node.thenStatement;
+      if (thenStatement is! Block &&
+          (thenOrElse == null || thenOrElse == thenStatement)) {
+        builder.addSimpleReplacement(
+          range.endStart(node.rightParenthesis, thenStatement),
+          ' {$eol$indent',
+        );
+        if (node.elseKeyword != null) {
+          builder.addSimpleReplacement(
+            range.endStart(thenStatement, node.elseKeyword),
+            '$eol$prefix} ',
+          );
+        } else {
+          builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
+        }
+      }
+
+      var elseStatement = node.elseStatement;
+      if (elseStatement != null &&
+          elseStatement is! Block &&
+          (thenOrElse == null || thenOrElse == elseStatement)) {
+        builder.addSimpleReplacement(
+          range.endStart(node.elseKeyword, elseStatement),
+          ' {$eol$indent',
+        );
+        builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
+      }
+    });
+  }
+
+  Future<void> _whileStatement(
+      DartChangeBuilder builder, WhileStatement node) async {
+    var body = node.body;
+    if (body is Block) return null;
+
+    var prefix = utils.getLinePrefix(node.offset);
+    var indent = prefix + utils.getIndent(1);
+
+    await builder.addFileEdit(file, (builder) {
+      builder.addSimpleReplacement(
+        range.endStart(node.rightParenthesis, body),
+        ' {$eol$indent',
+      );
+      builder.addSimpleInsertion(body.end, '$eol$prefix}');
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static UseCurlyBraces newInstance() => UseCurlyBraces();
+}
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 bba9db5..62da5e5 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
@@ -35,4 +35,7 @@
           range.node(expression), 'Future.value($value)');
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static WrapInFuture newInstance() => WrapInFuture();
 }
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 e391f54..e45c057 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
@@ -64,4 +64,7 @@
       }
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static WrapInText newInstance() => WrapInText();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 35e0a65..8411deb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -85,6 +85,9 @@
             errorCode.name == LintNames.null_closures ||
             errorCode.name == LintNames.prefer_collection_literals ||
             errorCode.name == LintNames.prefer_conditional_assignment ||
+            errorCode.name == LintNames.prefer_const_constructors ||
+            errorCode.name ==
+                LintNames.prefer_const_constructors_in_immutables ||
             errorCode.name == LintNames.prefer_const_declarations ||
             errorCode.name == LintNames.prefer_equal_for_default_values ||
             errorCode.name == LintNames.prefer_final_fields ||
@@ -103,7 +106,8 @@
 /// An enumeration of quick fix kinds for the errors found in an analysis
 /// options file.
 class AnalysisOptionsFixKind {
-  static const REMOVE_SETTING = FixKind('REMOVE_SETTING', 50, "Remove '{0}'");
+  static const REMOVE_SETTING =
+      FixKind('analysisOptions.fix.removeSetting', 50, "Remove '{0}'");
 }
 
 /// The implementation of [DartFixContext].
@@ -131,293 +135,338 @@
 
 /// An enumeration of quick fix kinds found in a Dart file.
 class DartFixKind {
-  static const ADD_ASYNC = FixKind('ADD_ASYNC', 50, "Add 'async' modifier");
-  static const ADD_AWAIT = FixKind('ADD_AWAIT', 50, "Add 'await' keyword");
-  static const ADD_EXPLICIT_CAST = FixKind('ADD_EXPLICIT_CAST', 50, 'Add cast',
+  static const ADD_ASYNC =
+      FixKind('dart.fix.add.async', 50, "Add 'async' modifier");
+  static const ADD_AWAIT =
+      FixKind('dart.fix.add.await', 50, "Add 'await' keyword");
+  static const ADD_EXPLICIT_CAST = FixKind(
+      'dart.fix.add.explicitCast', 50, 'Add cast',
       appliedTogetherMessage: 'Add all casts in file');
-  static const ADD_CONST = FixKind('ADD_CONST', 50, "Add 'const' modifier");
+  static const ADD_CONST =
+      FixKind('dart.fix.add.const', 50, "Add 'const' modifier");
   static const ADD_CURLY_BRACES =
-      FixKind('ADD_CURLY_BRACES', 50, 'Add curly braces');
+      FixKind('dart.fix.add.curlyBraces', 50, 'Add curly braces');
   static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE = FixKind(
-      'ADD_DIAGNOSTIC_PROPERTY_REFERENCE',
+      'dart.fix.add.diagnosticPropertyReference',
       50,
       'Add a debug reference to this property');
   static const ADD_FIELD_FORMAL_PARAMETERS = FixKind(
-      'ADD_FIELD_FORMAL_PARAMETERS', 70, 'Add final field formal parameters');
-  static const ADD_MISSING_ENUM_CASE_CLAUSES =
-      FixKind('ADD_MISSING_ENUM_CASE_CLAUSES', 50, 'Add missing case clauses');
-  static const ADD_MISSING_PARAMETER_NAMED =
-      FixKind('ADD_MISSING_PARAMETER_NAMED', 70, "Add named parameter '{0}'");
+      'dart.fix.add.fieldFormalParameters',
+      70,
+      'Add final field formal parameters');
+  static const ADD_MISSING_ENUM_CASE_CLAUSES = FixKind(
+      'dart.fix.add.missingEnumCaseClauses', 50, 'Add missing case clauses');
+  static const ADD_MISSING_PARAMETER_NAMED = FixKind(
+      'dart.fix.add.missingParameterNamed', 70, "Add named parameter '{0}'");
   static const ADD_MISSING_PARAMETER_POSITIONAL = FixKind(
-      'ADD_MISSING_PARAMETER_POSITIONAL',
+      'dart.fix.add.missingParameterPositional',
       69,
       'Add optional positional parameter');
-  static const ADD_MISSING_PARAMETER_REQUIRED =
-      FixKind('ADD_MISSING_PARAMETER_REQUIRED', 70, 'Add required parameter');
+  static const ADD_MISSING_PARAMETER_REQUIRED = FixKind(
+      'dart.fix.add.missingParameterRequired', 70, 'Add required parameter');
   static const ADD_MISSING_REQUIRED_ARGUMENT = FixKind(
-      'ADD_MISSING_REQUIRED_ARGUMENT', 70, "Add required argument '{0}'");
-  static const ADD_NE_NULL = FixKind('ADD_NE_NULL', 50, 'Add != null',
+      'dart.fix.add.missingRequiredArgument',
+      70,
+      "Add required argument '{0}'");
+  static const ADD_NE_NULL = FixKind('dart.fix.add.neNull', 50, 'Add != null',
       appliedTogetherMessage: 'Add != null everywhere in file');
   static const ADD_OVERRIDE =
-      FixKind('ADD_OVERRIDE', 50, "Add '@override' annotation");
+      FixKind('dart.fix.add.override', 50, "Add '@override' annotation");
   static const ADD_REQUIRED =
-      FixKind('ADD_REQUIRED', 50, "Add '@required' annotation");
+      FixKind('dart.fix.add.required', 50, "Add '@required' annotation");
+  static const ADD_REQUIRED2 =
+      FixKind('dart.fix.add.required', 50, "Add 'required' keyword");
   static const ADD_RETURN_TYPE =
-      FixKind('ADD_RETURN_TYPE', 50, 'Add return type');
-  static const ADD_STATIC = FixKind('ADD_STATIC', 50, "Add 'static' modifier");
+      FixKind('dart.fix.add.returnType', 50, 'Add return type');
+  static const ADD_STATIC =
+      FixKind('dart.fix.add.static', 50, "Add 'static' modifier");
   static const ADD_SUPER_CONSTRUCTOR_INVOCATION = FixKind(
-      'ADD_SUPER_CONSTRUCTOR_INVOCATION',
+      'dart.fix.add.superConstructorInvocation',
       50,
       'Add super constructor {0} invocation');
   static const ADD_TYPE_ANNOTATION =
-      FixKind('ADD_TYPE_ANNOTATION', 50, 'Add type annotation');
+      FixKind('dart.fix.add.typeAnnotation', 50, 'Add type annotation');
   static const CHANGE_ARGUMENT_NAME =
-      FixKind('CHANGE_ARGUMENT_NAME', 60, "Change to '{0}'");
-  static const CHANGE_TO = FixKind('CHANGE_TO', 51, "Change to '{0}'");
+      FixKind('dart.fix.change.argumentName', 60, "Change to '{0}'");
+  static const CHANGE_TO = FixKind('dart.fix.change.to', 51, "Change to '{0}'");
   static const CHANGE_TO_NEAREST_PRECISE_VALUE = FixKind(
-      'CHANGE_TO_NEAREST_PRECISE_VALUE',
+      'dart.fix.change.toNearestPreciseValue',
       50,
       'Change to nearest precise int-as-double value: {0}');
   static const CHANGE_TO_STATIC_ACCESS = FixKind(
-      'CHANGE_TO_STATIC_ACCESS', 50, "Change access to static using '{0}'");
+      'dart.fix.change.toStaticAccess',
+      50,
+      "Change access to static using '{0}'");
   static const CHANGE_TYPE_ANNOTATION = FixKind(
-      'CHANGE_TYPE_ANNOTATION', 50, "Change '{0}' to '{1}' type annotation");
-  static const CONVERT_FLUTTER_CHILD =
-      FixKind('CONVERT_FLUTTER_CHILD', 50, 'Convert to children:');
-  static const CONVERT_FLUTTER_CHILDREN =
-      FixKind('CONVERT_FLUTTER_CHILDREN', 50, 'Convert to child:');
-  static const CONVERT_INTO_EXPRESSION_BODY =
-      FixKind('CONVERT_INTO_EXPRESSION_BODY', 50, 'Convert to expression body');
+      'dart.fix.change.typeAnnotation',
+      50,
+      "Change '{0}' to '{1}' type annotation");
+  static const CONVERT_FLUTTER_CHILD = FixKind(
+      'dart.fix.flutter.convert.childToChildren', 50, 'Convert to children:');
+  static const CONVERT_FLUTTER_CHILDREN = FixKind(
+      'dart.fix.flutter.convert.childrenToChild', 50, 'Convert to child:');
+  static const CONVERT_INTO_EXPRESSION_BODY = FixKind(
+      'dart.fix.convert.toExpressionBody', 50, 'Convert to expression body');
   static const CONVERT_TO_CONTAINS =
-      FixKind('CONVERT_TO_CONTAINS', 50, "Convert to using 'contains'");
-  static const CONVERT_TO_FOR_ELEMENT =
-      FixKind('CONVERT_TO_FOR_ELEMENT', 50, "Convert to a 'for' element");
+      FixKind('dart.fix.convert.toContains', 50, "Convert to using 'contains'");
+  static const CONVERT_TO_FOR_ELEMENT = FixKind(
+      'dart.fix.convert.toForElement', 50, "Convert to a 'for' element");
   static const CONVERT_TO_GENERIC_FUNCTION_SYNTAX = FixKind(
-      'CONVERT_TO_GENERIC_FUNCTION_SYNTAX',
+      'dart.fix.convert.toGenericFunctionSyntax',
       50,
       "Convert into 'Function' syntax");
   static const CONVERT_TO_IF_ELEMENT =
-      FixKind('CONVERT_TO_IF_ELEMENT', 50, "Convert to an 'if' element");
+      FixKind('dart.fix.convert.toIfElement', 50, "Convert to an 'if' element");
   static const CONVERT_TO_IF_NULL =
-      FixKind('CONVERT_TO_IF_NULL', 50, "Convert to use '??'");
+      FixKind('dart.fix.convert.toIfNull', 50, "Convert to use '??'");
   static const CONVERT_TO_INT_LITERAL =
-      FixKind('CONVERT_TO_INT_LITERAL', 50, 'Convert to an int literal');
+      FixKind('dart.fix.convert.toIntLiteral', 50, 'Convert to an int literal');
   static const CONVERT_TO_LINE_COMMENT = FixKind(
-      'CONVERT_TO_LINE_COMMENT', 50, 'Convert to line documentation comment');
+      'dart.fix.convert.toLineComment',
+      50,
+      'Convert to line documentation comment');
   static const CONVERT_TO_LIST_LITERAL =
-      FixKind('CONVERT_TO_LIST_LITERAL', 50, 'Convert to list literal');
+      FixKind('dart.fix.convert.toListLiteral', 50, 'Convert to list literal');
   static const CONVERT_TO_MAP_LITERAL =
-      FixKind('CONVERT_TO_MAP_LITERAL', 50, 'Convert to map literal');
-  static const CONVERT_TO_NAMED_ARGUMENTS =
-      FixKind('CONVERT_TO_NAMED_ARGUMENTS', 50, 'Convert to named arguments');
+      FixKind('dart.fix.convert.toMapLiteral', 50, 'Convert to map literal');
+  static const CONVERT_TO_NAMED_ARGUMENTS = FixKind(
+      'dart.fix.convert.toNamedArguments', 50, 'Convert to named arguments');
   static const CONVERT_TO_NULL_AWARE =
-      FixKind('CONVERT_TO_NULL_AWARE', 50, "Convert to use '?.'");
-  static const CONVERT_TO_PACKAGE_IMPORT =
-      FixKind('CONVERT_TO_PACKAGE_IMPORT', 50, "Convert to 'package:' import");
-  static const CONVERT_TO_RELATIVE_IMPORT =
-      FixKind('CONVERT_TO_RELATIVE_IMPORT', 50, 'Convert to relative import');
+      FixKind('dart.fix.convert.toNullAware', 50, "Convert to use '?.'");
+  static const CONVERT_TO_ON_TYPE =
+      FixKind('dart.fix.convert.toOnType', 50, "Convert to 'on {0}'");
+  static const CONVERT_TO_PACKAGE_IMPORT = FixKind(
+      'dart.fix.convert.toPackageImport', 50, "Convert to 'package:' import");
+  static const CONVERT_TO_RELATIVE_IMPORT = FixKind(
+      'dart.fix.convert.toRelativeImport', 50, 'Convert to relative import');
   static const CONVERT_TO_SET_LITERAL =
-      FixKind('CONVERT_TO_SET_LITERAL', 50, 'Convert to set literal');
+      FixKind('dart.fix.convert.toSetLiteral', 50, 'Convert to set literal');
   static const CONVERT_TO_SINGLE_QUOTED_STRING = FixKind(
-      'CONVERT_TO_SINGLE_QUOTED_STRING', 50, 'Convert to single quoted string');
+      'dart.fix.convert.toSingleQuotedString',
+      50,
+      'Convert to single quoted string');
   static const CONVERT_TO_SPREAD =
-      FixKind('CONVERT_TO_SPREAD', 50, 'Convert to a spread');
-  static const CONVERT_TO_WHERE_TYPE =
-      FixKind('CONVERT_TO_WHERE_TYPE', 50, "Convert to a use 'whereType'");
-  static const CREATE_CLASS = FixKind('CREATE_CLASS', 50, "Create class '{0}'");
+      FixKind('dart.fix.convert.toSpread', 50, 'Convert to a spread');
+  static const CONVERT_TO_WHERE_TYPE = FixKind(
+      'dart.fix.convert.toWhereType', 50, "Convert to a use 'whereType'");
+  static const CREATE_CLASS =
+      FixKind('dart.fix.create.class', 50, "Create class '{0}'");
   static const CREATE_CONSTRUCTOR =
-      FixKind('CREATE_CONSTRUCTOR', 50, "Create constructor '{0}'");
+      FixKind('dart.fix.create.constructor', 50, "Create constructor '{0}'");
   static const CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS = FixKind(
-      'CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS',
+      'dart.fix.create.constructorForFinalFields',
       50,
       'Create constructor for final fields');
-  static const CREATE_CONSTRUCTOR_SUPER =
-      FixKind('CREATE_CONSTRUCTOR_SUPER', 50, 'Create constructor to call {0}');
-  static const CREATE_FIELD = FixKind('CREATE_FIELD', 49, "Create field '{0}'");
-  static const CREATE_FILE = FixKind('CREATE_FILE', 50, "Create file '{0}'");
+  static const CREATE_CONSTRUCTOR_SUPER = FixKind(
+      'dart.fix.create.constructorSuper', 50, 'Create constructor to call {0}');
+  static const CREATE_FIELD =
+      FixKind('dart.fix.create.field', 49, "Create field '{0}'");
+  static const CREATE_FILE =
+      FixKind('dart.fix.create.file', 50, "Create file '{0}'");
   static const CREATE_FUNCTION =
-      FixKind('CREATE_FUNCTION', 49, "Create function '{0}'");
+      FixKind('dart.fix.create.function', 49, "Create function '{0}'");
   static const CREATE_GETTER =
-      FixKind('CREATE_GETTER', 50, "Create getter '{0}'");
-  static const CREATE_LOCAL_VARIABLE =
-      FixKind('CREATE_LOCAL_VARIABLE', 50, "Create local variable '{0}'");
+      FixKind('dart.fix.create.getter', 50, "Create getter '{0}'");
+  static const CREATE_LOCAL_VARIABLE = FixKind(
+      'dart.fix.create.localVariable', 50, "Create local variable '{0}'");
   static const CREATE_METHOD =
-      FixKind('CREATE_METHOD', 50, "Create method '{0}'");
-  static const CREATE_MISSING_OVERRIDES =
-      FixKind('CREATE_MISSING_OVERRIDES', 51, 'Create {0} missing override(s)');
-  static const CREATE_MIXIN = FixKind('CREATE_MIXIN', 50, "Create mixin '{0}'");
-  static const CREATE_NO_SUCH_METHOD =
-      FixKind('CREATE_NO_SUCH_METHOD', 49, "Create 'noSuchMethod' method");
+      FixKind('dart.fix.create.method', 50, "Create method '{0}'");
+  static const CREATE_MISSING_OVERRIDES = FixKind(
+      'dart.fix.create.missingOverrides', 51, 'Create {0} missing override(s)');
+  static const CREATE_MIXIN =
+      FixKind('dart.fix.create.mixin', 50, "Create mixin '{0}'");
+  static const CREATE_NO_SUCH_METHOD = FixKind(
+      'dart.fix.create.noSuchMethod', 49, "Create 'noSuchMethod' method");
   static const CREATE_SETTER =
-      FixKind('CREATE_SETTER', 50, "Create setter '{0}'");
+      FixKind('dart.fix.create.setter', 50, "Create setter '{0}'");
   static const EXTEND_CLASS_FOR_MIXIN =
-      FixKind('EXTEND_CLASS_FOR_MIXIN', 50, "Extend the class '{0}'");
+      FixKind('dart.fix.extendClassForMixin', 50, "Extend the class '{0}'");
   static const IMPORT_ASYNC =
-      FixKind('IMPORT_ASYNC', 49, "Import 'dart:async'");
-  static const IMPORT_LIBRARY_PREFIX = FixKind('IMPORT_LIBRARY_PREFIX', 49,
-      "Use imported library '{0}' with prefix '{1}'");
+      FixKind('dart.fix.import.async', 49, "Import 'dart:async'");
+  static const IMPORT_LIBRARY_PREFIX = FixKind('dart.fix.import.libraryPrefix',
+      49, "Use imported library '{0}' with prefix '{1}'");
   static const IMPORT_LIBRARY_PROJECT1 =
-      FixKind('IMPORT_LIBRARY_PROJECT1', 53, "Import library '{0}'");
+      FixKind('dart.fix.import.libraryProject1', 53, "Import library '{0}'");
   static const IMPORT_LIBRARY_PROJECT2 =
-      FixKind('IMPORT_LIBRARY_PROJECT2', 52, "Import library '{0}'");
+      FixKind('dart.fix.import.libraryProject2', 52, "Import library '{0}'");
   static const IMPORT_LIBRARY_PROJECT3 =
-      FixKind('IMPORT_LIBRARY_PROJECT3', 51, "Import library '{0}'");
+      FixKind('dart.fix.import.libraryProject3', 51, "Import library '{0}'");
   static const IMPORT_LIBRARY_SDK =
-      FixKind('IMPORT_LIBRARY_SDK', 54, "Import library '{0}'");
+      FixKind('dart.fix.import.librarySdk', 54, "Import library '{0}'");
   static const IMPORT_LIBRARY_SHOW =
-      FixKind('IMPORT_LIBRARY_SHOW', 55, "Update library '{0}' import");
+      FixKind('dart.fix.import.libraryShow', 55, "Update library '{0}' import");
   static const INLINE_INVOCATION =
-      FixKind('INLINE_INVOCATION', 30, "Inline invocation of '{0}'");
+      FixKind('dart.fix.inlineInvocation', 30, "Inline invocation of '{0}'");
   static const INLINE_TYPEDEF =
-      FixKind('INLINE_TYPEDEF', 30, "Inline the definition of '{0}'");
-  static const INSERT_SEMICOLON = FixKind('INSERT_SEMICOLON', 50, "Insert ';'");
+      FixKind('dart.fix.inlineTypedef', 30, "Inline the definition of '{0}'");
+  static const INSERT_SEMICOLON =
+      FixKind('dart.fix.insertSemicolon', 50, "Insert ';'");
   static const MAKE_CLASS_ABSTRACT =
-      FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract");
+      FixKind('dart.fix.makeClassAbstract', 50, "Make class '{0}' abstract");
   static const MAKE_FIELD_NOT_FINAL =
-      FixKind('MAKE_FIELD_NOT_FINAL', 50, "Make field '{0}' not final");
-  static const MAKE_FINAL = FixKind('MAKE_FINAL', 50, 'Make final');
+      FixKind('dart.fix.makeFieldNotFinal', 50, "Make field '{0}' not final");
+  static const MAKE_FINAL = FixKind('dart.fix.makeFinal', 50, 'Make final');
   static const MOVE_TYPE_ARGUMENTS_TO_CLASS = FixKind(
-      'MOVE_TYPE_ARGUMENTS_TO_CLASS',
+      'dart.fix.moveTypeArgumentsToClass',
       50,
       'Move type arguments to after class name');
-  static const MAKE_VARIABLE_NOT_FINAL =
-      FixKind('MAKE_VARIABLE_NOT_FINAL', 50, "Make variable '{0}' not final");
+  static const MAKE_VARIABLE_NOT_FINAL = FixKind(
+      'dart.fix.makeVariableNotFinal', 50, "Make variable '{0}' not final");
   static const QUALIFY_REFERENCE =
-      FixKind('QUALIFY_REFERENCE', 50, "Use '{0}'");
+      FixKind('dart.fix.qualifyReference', 50, "Use '{0}'");
   static const REMOVE_ANNOTATION =
-      FixKind('REMOVE_ANNOTATION', 50, "Remove the '{0}' annotation");
+      FixKind('dart.fix.remove.annotation', 50, "Remove the '{0}' annotation");
   static const REMOVE_ARGUMENT =
-      FixKind('REMOVE_ARGUMENT', 50, 'Remove argument');
-  static const REMOVE_AWAIT = FixKind('REMOVE_AWAIT', 50, 'Remove await');
-  static const REMOVE_CONST = FixKind('REMOVE_CONST', 50, 'Remove const');
+      FixKind('dart.fix.remove.argument', 50, 'Remove argument');
+  static const REMOVE_AWAIT =
+      FixKind('dart.fix.remove.await', 50, 'Remove await');
+  static const REMOVE_CONST =
+      FixKind('dart.fix.remove.const', 50, 'Remove const');
   static const REMOVE_DEAD_CODE =
-      FixKind('REMOVE_DEAD_CODE', 50, 'Remove dead code');
-  static const REMOVE_DUPLICATE_CASE =
-      FixKind('REMOVE_DUPLICATE_CASE', 50, 'Remove duplicate case statement');
+      FixKind('dart.fix.remove.deadCode', 50, 'Remove dead code');
+  static const REMOVE_DUPLICATE_CASE = FixKind(
+      'dart.fix.remove.duplicateCase', 50, 'Remove duplicate case statement');
   static const REMOVE_EMPTY_CATCH =
-      FixKind('REMOVE_EMPTY_CATCH', 50, 'Remove empty catch clause');
+      FixKind('dart.fix.remove.emptyCatch', 50, 'Remove empty catch clause');
   static const REMOVE_EMPTY_CONSTRUCTOR_BODY = FixKind(
-      'REMOVE_EMPTY_CONSTRUCTOR_BODY', 50, 'Remove empty constructor body');
+      'dart.fix.remove.emptyConstructorBody',
+      50,
+      'Remove empty constructor body');
   static const REMOVE_EMPTY_ELSE =
-      FixKind('REMOVE_EMPTY_ELSE', 50, 'Remove empty else clause');
+      FixKind('dart.fix.remove.emptyElse', 50, 'Remove empty else clause');
   static const REMOVE_EMPTY_STATEMENT =
-      FixKind('REMOVE_EMPTY_STATEMENT', 50, 'Remove empty statement');
+      FixKind('dart.fix.remove.emptyStatement', 50, 'Remove empty statement');
   static const REMOVE_IF_NULL_OPERATOR =
-      FixKind('REMOVE_IF_NULL_OPERATOR', 50, "Remove the '??' operator");
+      FixKind('dart.fix.remove.ifNullOperator', 50, "Remove the '??' operator");
   static const REMOVE_INITIALIZER =
-      FixKind('REMOVE_INITIALIZER', 50, 'Remove initializer');
+      FixKind('dart.fix.remove.initializer', 50, 'Remove initializer');
   static const REMOVE_INTERPOLATION_BRACES = FixKind(
-      'REMOVE_INTERPOLATION_BRACES',
+      'dart.fix.remove.interpolationBraces',
       50,
       'Remove unnecessary interpolation braces');
-  static const REMOVE_METHOD_DECLARATION =
-      FixKind('REMOVE_METHOD_DECLARATION', 50, 'Remove method declaration');
-  static const REMOVE_NAME_FROM_COMBINATOR =
-      FixKind('REMOVE_NAME_FROM_COMBINATOR', 50, "Remove name from '{0}'");
+  static const REMOVE_METHOD_DECLARATION = FixKind(
+      'dart.fix.remove.methodDeclaration', 50, 'Remove method declaration');
+  static const REMOVE_NAME_FROM_COMBINATOR = FixKind(
+      'dart.fix.remove.nameFromCombinator', 50, "Remove name from '{0}'");
   static const REMOVE_OPERATOR =
-      FixKind('REMOVE_OPERATOR', 50, 'Remove the operator');
+      FixKind('dart.fix.remove.operator', 50, 'Remove the operator');
   static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = FixKind(
-      'REMOVE_PARAMETERS_IN_GETTER_DECLARATION',
+      'dart.fix.remove.parametersInGetterDeclaration',
       50,
       'Remove parameters in getter declaration');
   static const REMOVE_PARENTHESIS_IN_GETTER_INVOCATION = FixKind(
-      'REMOVE_PARENTHESIS_IN_GETTER_INVOCATION',
+      'dart.fix.remove.parenthesisInGetterInvocation',
       50,
       'Remove parentheses in getter invocation');
+  static const REMOVE_QUESTION_MARK =
+      FixKind('dart.fix.remove.questionMark', 50, "Remove the '?'");
   static const REMOVE_THIS_EXPRESSION =
-      FixKind('REMOVE_THIS_EXPRESSION', 50, 'Remove this expression');
+      FixKind('dart.fix.remove.thisExpression', 50, 'Remove this expression');
   static const REMOVE_TYPE_ANNOTATION =
-      FixKind('REMOVE_TYPE_ANNOTATION', 50, 'Remove type annotation');
+      FixKind('dart.fix.remove.typeAnnotation', 50, 'Remove type annotation');
   static const REMOVE_TYPE_ARGUMENTS =
-      FixKind('REMOVE_TYPE_ARGUMENTS', 49, 'Remove type arguments');
+      FixKind('dart.fix.remove.typeArguments', 49, 'Remove type arguments');
   static const REMOVE_UNNECESSARY_CAST = FixKind(
-      'REMOVE_UNNECESSARY_CAST', 50, 'Remove unnecessary cast',
+      'dart.fix.remove.unnecessaryCast', 50, 'Remove unnecessary cast',
       appliedTogetherMessage: 'Remove all unnecessary casts in file');
   static const REMOVE_UNNECESSARY_CONST = FixKind(
-      'REMOVE_UNNECESSARY_CONST', 50, 'Remove unnecessary const keyword');
-  static const REMOVE_UNNECESSARY_NEW =
-      FixKind('REMOVE_UNNECESSARY_NEW', 50, 'Remove unnecessary new keyword');
-  static const REMOVE_UNUSED_CATCH_CLAUSE =
-      FixKind('REMOVE_UNUSED_CATCH_CLAUSE', 50, "Remove unused 'catch' clause");
+      'dart.fix.remove.unnecessaryConst',
+      50,
+      'Remove unnecessary const keyword');
+  static const REMOVE_UNNECESSARY_NEW = FixKind(
+      'dart.fix.remove.unnecessaryNew', 50, 'Remove unnecessary new keyword');
+  static const REMOVE_UNUSED_CATCH_CLAUSE = FixKind(
+      'dart.fix.remove.unusedCatchClause', 50, "Remove unused 'catch' clause");
   static const REMOVE_UNUSED_CATCH_STACK = FixKind(
-      'REMOVE_UNUSED_CATCH_STACK', 50, 'Remove unused stack trace variable');
+      'dart.fix.remove.unusedCatchStack',
+      50,
+      'Remove unused stack trace variable');
   static const REMOVE_UNUSED_ELEMENT =
-      FixKind('REMOVE_UNUSED_ELEMENT', 50, 'Remove unused element');
+      FixKind('dart.fix.remove.unusedElement', 50, 'Remove unused element');
   static const REMOVE_UNUSED_FIELD =
-      FixKind('REMOVE_UNUSED_FIELD', 50, 'Remove unused field');
+      FixKind('dart.fix.remove.unusedField', 50, 'Remove unused field');
   static const REMOVE_UNUSED_IMPORT = FixKind(
-      'REMOVE_UNUSED_IMPORT', 50, 'Remove unused import',
+      'dart.fix.remove.unusedImport', 50, 'Remove unused import',
       appliedTogetherMessage: 'Remove all unused imports in this file');
   static const REMOVE_UNUSED_LABEL =
-      FixKind('REMOVE_UNUSED_LABEL', 50, 'Remove unused label');
+      FixKind('dart.fix.remove.unusedLabel', 50, 'Remove unused label');
   static const REMOVE_UNUSED_LOCAL_VARIABLE = FixKind(
-      'REMOVE_UNUSED_LOCAL_VARIABLE', 50, 'Remove unused local variable');
+      'dart.fix.remove.unusedLocalVariable',
+      50,
+      'Remove unused local variable');
   static const RENAME_TO_CAMEL_CASE =
-      FixKind('RENAME_TO_CAMEL_CASE', 50, "Rename to '{0}'");
+      FixKind('dart.fix.rename.toCamelCase', 50, "Rename to '{0}'");
   static const REPLACE_BOOLEAN_WITH_BOOL = FixKind(
-      'REPLACE_BOOLEAN_WITH_BOOL', 50, "Replace 'boolean' with 'bool'",
+      'dart.fix.replace.booleanWithBool', 50, "Replace 'boolean' with 'bool'",
       appliedTogetherMessage: "Replace all 'boolean' with 'bool' in file");
   static const REPLACE_COLON_WITH_EQUALS =
-      FixKind('REPLACE_COLON_WITH_EQUALS', 50, "Replace ':' with '='");
-  static const REPLACE_FINAL_WITH_CONST =
-      FixKind('REPLACE_FINAL_WITH_CONST', 50, "Replace 'final' with 'const'");
-  static const REPLACE_NEW_WITH_CONST =
-      FixKind('REPLACE_NEW_WITH_CONST', 50, "Replace 'new' with 'const'");
-  static const REPLACE_NULL_WITH_CLOSURE =
-      FixKind('REPLACE_NULL_WITH_CLOSURE', 50, "Replace 'null' with a closure");
+      FixKind('dart.fix.replace.colonWithEquals', 50, "Replace ':' with '='");
+  static const REPLACE_FINAL_WITH_CONST = FixKind(
+      'dart.fix.replace.finalWithConst', 50, "Replace 'final' with 'const'");
+  static const REPLACE_NEW_WITH_CONST = FixKind(
+      'dart.fix.replace.newWithConst', 50, "Replace 'new' with 'const'");
+  static const REPLACE_NULL_WITH_CLOSURE = FixKind(
+      'dart.fix.replace.nullWithClosure', 50, "Replace 'null' with a closure");
   static const REPLACE_RETURN_TYPE_FUTURE = FixKind(
-      'REPLACE_RETURN_TYPE_FUTURE',
+      'dart.fix.replace.returnTypeFuture',
       50,
       "Return 'Future' from 'async' function");
-  static const REPLACE_VAR_WITH_DYNAMIC =
-      FixKind('REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'");
+  static const REPLACE_VAR_WITH_DYNAMIC = FixKind(
+      'dart.fix.replace.varWithDynamic', 50, "Replace 'var' with 'dynamic'");
   static const REPLACE_WITH_EIGHT_DIGIT_HEX =
-      FixKind('REPLACE_WITH_EIGHT_DIGIT_HEX', 50, "Replace with '{0}'");
+      FixKind('dart.fix.replace.withEightDigitHex', 50, "Replace with '{0}'");
   static const REPLACE_WITH_BRACKETS =
-      FixKind('REPLACE_WITH_BRACKETS', 50, 'Replace with { }');
-  static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT =
-      FixKind('REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, 'Replace with ??=');
+      FixKind('dart.fix.replace.withBrackets', 50, 'Replace with { }');
+  static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = FixKind(
+      'dart.fix.replace.withConditionalAssignment', 50, 'Replace with ??=');
   static const REPLACE_WITH_EXTENSION_NAME =
-      FixKind('REPLACE_WITH_EXTENSION_NAME', 50, "Replace with '{0}'");
+      FixKind('dart.fix.replace.withExtensionName', 50, "Replace with '{0}'");
   static const REPLACE_WITH_IDENTIFIER =
-      FixKind('REPLACE_WITH_IDENTIFIER', 50, 'Replace with identifier');
-  static const REPLACE_WITH_INTERPOLATION =
-      FixKind('REPLACE_WITH_INTERPOLATION', 50, 'Replace with interpolation');
+      FixKind('dart.fix.replace.withIdentifier', 50, 'Replace with identifier');
+  static const REPLACE_WITH_INTERPOLATION = FixKind(
+      'dart.fix.replace.withInterpolation', 50, 'Replace with interpolation');
   static const REPLACE_WITH_IS_EMPTY =
-      FixKind('REPLACE_WITH_IS_EMPTY', 50, "Replace with 'isEmpty'");
-  static const REPLACE_WITH_IS_NOT_EMPTY =
-      FixKind('REPLACE_WITH_IS_NOT_EMPTY', 50, "Replace with 'isNotEmpty'");
-  static const REPLACE_WITH_NULL_AWARE = FixKind('REPLACE_WITH_NULL_AWARE', 50,
+      FixKind('dart.fix.replace.withIsEmpty', 50, "Replace with 'isEmpty'");
+  static const REPLACE_WITH_IS_NOT_EMPTY = FixKind(
+      'dart.fix.replace.withIsNotEmpty', 50, "Replace with 'isNotEmpty'");
+  static const REPLACE_WITH_NULL_AWARE = FixKind(
+      'dart.fix.replace.withNullAware',
+      50,
       "Replace the '.' with a '?.' in the invocation");
-  static const REPLACE_WITH_TEAR_OFF = FixKind(
-      'REPLACE_WITH_TEAR_OFF', 50, 'Replace function literal with tear-off');
-  static const REPLACE_WITH_VAR =
-      FixKind('REPLACE_WITH_VAR', 50, "Replace type annotation with 'var'");
-  static const SORT_CHILD_PROPERTY_LAST = FixKind('SORT_CHILD_PROPERTY_LAST',
-      50, 'Move child property to end of arguments');
-  static const UPDATE_SDK_CONSTRAINTS =
-      FixKind('UPDATE_SDK_CONSTRAINTS', 50, 'Update the SDK constraints');
-  static const USE_CONST = FixKind('USE_CONST', 50, 'Change to constant');
+  static const REPLACE_WITH_TEAR_OFF = FixKind('dart.fix.replace.withTearOff',
+      50, 'Replace function literal with tear-off');
+  static const REPLACE_WITH_VAR = FixKind(
+      'dart.fix.replace.withVar', 50, "Replace type annotation with 'var'");
+  static const SORT_CHILD_PROPERTY_LAST = FixKind(
+      'dart.fix.sort.childPropertyLast',
+      50,
+      'Move child property to end of arguments');
+  static const SORT_DIRECTIVES =
+      FixKind('dart.fix.sort.directives', 50, 'Sort directives');
+  static const UPDATE_SDK_CONSTRAINTS = FixKind(
+      'dart.fix.updateSdkConstraints', 50, 'Update the SDK constraints');
+  static const USE_CONST =
+      FixKind('dart.fix.use.const', 50, 'Change to constant');
   static const USE_EFFECTIVE_INTEGER_DIVISION = FixKind(
-      'USE_EFFECTIVE_INTEGER_DIVISION',
+      'dart.fix.use.effectiveIntegerDivision',
       50,
       'Use effective integer division ~/');
   static const USE_EQ_EQ_NULL = FixKind(
-      'USE_EQ_EQ_NULL', 50, "Use == null instead of 'is Null'",
+      'dart.fix.use.eqEqNull', 50, "Use == null instead of 'is Null'",
       appliedTogetherMessage:
           "Use == null instead of 'is Null' everywhere in file");
-  static const USE_IS_NOT_EMPTY = FixKind(
-      'USE_IS_NOT_EMPTY', 50, "Use x.isNotEmpty instead of '!x.isEmpty'");
+  static const USE_IS_NOT_EMPTY = FixKind('dart.fix.use.isNotEmpty', 50,
+      "Use x.isNotEmpty instead of '!x.isEmpty'");
   static const USE_NOT_EQ_NULL = FixKind(
-      'USE_NOT_EQ_NULL', 50, "Use != null instead of 'is! Null'",
+      'dart.fix.use.notEqNull', 50, "Use != null instead of 'is! Null'",
       appliedTogetherMessage:
           "Use != null instead of 'is! Null' everywhere in file");
   static const USE_RETHROW =
-      FixKind('USE_RETHROW', 50, 'Replace throw with rethrow');
+      FixKind('dart.fix.use.rethrow', 50, 'Replace throw with rethrow');
   static const WRAP_IN_FUTURE =
-      FixKind('WRAP_IN_FUTURE', 50, "Wrap in 'Future.value'");
+      FixKind('dart.fix.wrap.future', 50, "Wrap in 'Future.value'");
   static const WRAP_IN_TEXT =
-      FixKind('WRAP_IN_TEXT', 50, "Wrap in a 'Text' widget");
+      FixKind('dart.fix.flutter.wrap.text', 50, "Wrap in a 'Text' widget");
 }
 
 /// An enumeration of quick fix kinds for the errors found in an Android
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 11f111b..f0fd8b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -12,27 +12,47 @@
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analysis_server/src/services/correction/base_processor.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
 import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
+import 'package:analysis_server/src/services/correction/dart/add_required_keyword.dart';
 import 'package:analysis_server/src/services/correction/dart/add_return_type.dart';
+import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_contains.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_expression_function_body.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_list_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_on_type.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_where_type.dart';
+import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
 import 'package:analysis_server/src/services/correction/dart/inline_typedef.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_dead_if_null.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_if_null_operator.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_question_mark.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_unused.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_unused_local_variable.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_interpolation.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
+import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
+import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
 import 'package:analysis_server/src/services/correction/dart/wrap_in_future.dart';
 import 'package:analysis_server/src/services/correction/dart/wrap_in_text.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/correction/levenshtein.dart';
 import 'package:analysis_server/src/services/correction/namespace.dart';
+import 'package:analysis_server/src/services/correction/organize_directives.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
@@ -72,6 +92,9 @@
 /// A predicate is a one-argument function that returns a boolean value.
 typedef ElementPredicate = bool Function(Element argument);
 
+/// A function that can be executed to create a correction producer.
+typedef ProducerGenerator = CorrectionProducer Function();
+
 /// A fix contributor that provides the default set of fixes for Dart files.
 class DartFixContributor implements FixContributor {
   @override
@@ -174,15 +197,163 @@
 class FixProcessor extends BaseProcessor {
   static const int MAX_LEVENSHTEIN_DISTANCE = 3;
 
+  /// 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_specify_types: [
+      AddTypeAnnotation.newInstance,
+    ],
+    LintNames.avoid_private_typedef_functions: [
+      InlineTypedef.newInstance,
+    ],
+    LintNames.avoid_relative_lib_imports: [
+      ConvertToPackageImport.newInstance,
+    ],
+    LintNames.avoid_returning_null_for_future: [
+      WrapInFuture.newInstance,
+    ],
+    LintNames.avoid_types_as_parameter_names: [
+      ConvertToOnType.newInstance,
+    ],
+    LintNames.curly_braces_in_flow_control_structures: [
+      UseCurlyBraces.newInstance,
+    ],
+    LintNames.diagnostic_describe_all_properties: [
+      AddDiagnosticPropertyReference.newInstance,
+    ],
+    LintNames.omit_local_variable_types: [
+      ReplaceWithVar.newInstance,
+    ],
+    LintNames.prefer_collection_literals: [
+      ConvertToListLiteral.newInstance,
+      ConvertToMapLiteral.newInstance,
+      ConvertToSetLiteral.newInstance,
+    ],
+    LintNames.prefer_contains: [
+      ConvertToContains.newInstance,
+    ],
+    LintNames.prefer_expression_function_bodies: [
+      ConvertToExpressionFunctionBody.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_inlined_adds: [
+      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.unnecessary_null_in_if_null_operators: [
+      RemoveIfNullOperator.newInstance,
+    ],
+    LintNames.use_full_hex_values_for_flutter_colors: [
+      ReplaceWithEightDigitHex.newInstance,
+    ],
+    LintNames.use_function_type_syntax_for_parameters: [
+      ConvertToGenericFunctionSyntax.newInstance,
+    ],
+  };
+
+  /// A map from error codes to a list of generators used to create the
+  /// correction producers used to build fixes for those diagnostics. The
+  /// generators used for lint rules are in the [lintProducerMap].
+  static const Map<ErrorCode, List<ProducerGenerator>> nonLintProducerMap = {
+    CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER: [
+      AddRequiredKeyword.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    HintCode.UNUSED_ELEMENT: [
+      RemoveUnusedElement.newInstance,
+    ],
+    HintCode.UNUSED_FIELD: [
+      RemoveUnusedField.newInstance,
+    ],
+    HintCode.UNUSED_LOCAL_VARIABLE: [
+      RemoveUnusedLocalVariable.newInstance,
+    ],
+    ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE: [
+      AddTypeAnnotation.newInstance,
+    ],
+    StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE: [
+      WrapInText.newInstance,
+    ],
+    StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION: [
+      RemoveDeadIfNull.newInstance,
+    ],
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1: [
+      AddFieldFormalParameters.newInstance,
+    ],
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2: [
+      AddFieldFormalParameters.newInstance,
+    ],
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS: [
+      AddFieldFormalParameters.newInstance,
+    ],
+  };
+
   final DartFixContext context;
+
   final ResourceProvider resourceProvider;
   final TypeSystem typeSystem;
 
   final LibraryElement unitLibraryElement;
   final CompilationUnit unit;
-
   final AnalysisError error;
+
   final int errorOffset;
+
   final int errorLength;
 
   final List<Fix> fixes = <Fix>[];
@@ -394,9 +565,6 @@
     if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) {
       await _addFix_replaceVarWithDynamic();
     }
-    if (errorCode == ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE) {
-      await _addFix_addTypeAnnotation();
-    }
     if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) {
       await _addFix_makeFieldNotFinal();
     }
@@ -590,10 +758,6 @@
     // lints
     if (errorCode is LintCode) {
       var name = errorCode.name;
-      if (name == LintNames.always_specify_types ||
-          name == LintNames.type_annotate_public_apis) {
-        await _addFix_addTypeAnnotation();
-      }
       if (name == LintNames.always_require_non_null_named_parameters) {
         await _addFix_addRequiredAnnotation();
       }
@@ -612,9 +776,6 @@
       if (name == LintNames.avoid_redundant_argument_values) {
         await _addFix_removeArgument();
       }
-      if (name == LintNames.avoid_relative_lib_imports) {
-        await _addFix_convertToPackageImport();
-      }
       if (name == LintNames.avoid_return_types_on_setters) {
         await _addFix_removeTypeAnnotation();
       }
@@ -627,11 +788,8 @@
       if (name == LintNames.await_only_futures) {
         await _addFix_removeAwait();
       }
-      if (name == LintNames.curly_braces_in_flow_control_structures) {
-        await _addFix_addCurlyBraces();
-      }
-      if (name == LintNames.diagnostic_describe_all_properties) {
-        await _addFix_addDiagnosticPropertyReference();
+      if (name == LintNames.directives_ordering) {
+        await _addFix_sortDirectives();
       }
       if (name == LintNames.empty_catches) {
         await _addFix_removeEmptyCatch();
@@ -654,9 +812,6 @@
       if (name == LintNames.null_closures) {
         await _addFix_replaceNullWithClosure();
       }
-      if (name == LintNames.omit_local_variable_types) {
-        await _addFix_replaceWithVar();
-      }
       if (name == LintNames.prefer_adjacent_string_concatenation) {
         await _addFix_removeOperator();
       }
@@ -666,12 +821,6 @@
       if (errorCode.name == LintNames.prefer_const_declarations) {
         await _addFix_replaceFinalWithConst();
       }
-      if (errorCode.name == LintNames.prefer_expression_function_bodies) {
-        await _addFix_convertToExpressionBody();
-      }
-      if (errorCode.name == LintNames.prefer_for_elements_to_map_fromIterable) {
-        await _addFix_convertMapFromIterableToForLiteral();
-      }
       if (errorCode.name == LintNames.prefer_equal_for_default_values) {
         await _addFix_replaceColonWithEquals();
       }
@@ -681,19 +830,6 @@
       if (name == LintNames.prefer_final_locals) {
         await _addFix_makeVariableFinal();
       }
-      if (name == LintNames.prefer_generic_function_type_aliases) {
-        await _addFix_convertToGenericFunctionSyntax();
-      }
-      if (errorCode.name ==
-          LintNames.prefer_if_elements_to_conditional_expressions) {
-        await _addFix_convertConditionalToIfElement();
-      }
-      if (name == LintNames.prefer_inlined_adds) {
-        await _addFix_convertToInlineAdd();
-      }
-      if (name == LintNames.prefer_int_literals) {
-        await _addFix_convertToIntLiteral();
-      }
       if (name == LintNames.prefer_is_empty) {
         await _addFix_replaceWithIsEmpty();
       }
@@ -710,21 +846,6 @@
       if (errorCode.name == LintNames.prefer_if_null_operators) {
         await _addFix_convertToIfNullOperator();
       }
-      if (name == LintNames.prefer_relative_imports) {
-        await _addFix_convertToRelativeImport();
-      }
-      if (name == LintNames.prefer_single_quotes) {
-        await _addFix_convertSingleQuotes();
-      }
-      if (errorCode.name == LintNames.slash_for_doc_comments) {
-        await _addFix_convertDocumentationIntoLine();
-      }
-      if (name == LintNames.prefer_spread_collections) {
-        await _addFix_convertAddAllToSpread();
-      }
-      if (name == LintNames.sort_child_properties_last) {
-        await _addFix_sortChildPropertiesLast();
-      }
       if (name == LintNames.type_init_formals) {
         await _addFix_removeTypeAnnotation();
       }
@@ -749,9 +870,6 @@
       if (name == LintNames.unnecessary_this) {
         await _addFix_removeThisExpression();
       }
-      if (name == LintNames.use_function_type_syntax_for_parameters) {
-        await _addFix_convertToGenericFunctionSyntax();
-      }
       if (name == LintNames.use_rethrow_when_possible) {
         await _addFix_replaceWithRethrow();
       }
@@ -822,17 +940,6 @@
     }
   }
 
-  Future<void> _addFix_addCurlyBraces() async {
-    final changeBuilder = await createBuilder_useCurlyBraces();
-    _addFixFromBuilder(changeBuilder, DartFixKind.ADD_CURLY_BRACES);
-  }
-
-  Future<void> _addFix_addDiagnosticPropertyReference() async {
-    final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
-    _addFixFromBuilder(
-        changeBuilder, DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
-  }
-
   Future<void> _addFix_addExplicitCast() async {
     if (coveredNode is! Expression) {
       return;
@@ -1298,19 +1405,6 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.ADD_STATIC);
   }
 
-  Future<void> _addFix_addTypeAnnotation() async {
-    var changeBuilder =
-        await createBuilder_addTypeAnnotation_DeclaredIdentifier();
-    _addFixFromBuilder(changeBuilder, DartFixKind.ADD_TYPE_ANNOTATION);
-
-    changeBuilder =
-        await createBuilder_addTypeAnnotation_SimpleFormalParameter();
-    _addFixFromBuilder(changeBuilder, DartFixKind.ADD_TYPE_ANNOTATION);
-
-    changeBuilder = await createBuilder_addTypeAnnotation_VariableDeclaration();
-    _addFixFromBuilder(changeBuilder, DartFixKind.ADD_TYPE_ANNOTATION);
-  }
-
   Future<void> _addFix_boolInsteadOfBoolean() async {
     var changeBuilder = _newDartChangeBuilder();
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -1442,27 +1536,6 @@
     }
   }
 
-  Future<void> _addFix_convertAddAllToSpread() async {
-    final change = await createBuilder_convertAddAllToSpread();
-    if (change != null) {
-      final kind = change.isLineInvocation
-          ? DartFixKind.INLINE_INVOCATION
-          : DartFixKind.CONVERT_TO_SPREAD;
-      _addFixFromBuilder(change.builder, kind, args: change.args);
-    }
-  }
-
-  Future<void> _addFix_convertConditionalToIfElement() async {
-    final changeBuilder =
-        await createBuilder_convertConditionalExpressionToIfElement();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_IF_ELEMENT);
-  }
-
-  Future<void> _addFix_convertDocumentationIntoLine() async {
-    final changeBuilder = await createBuilder_convertDocumentationIntoLine();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_LINE_COMMENT);
-  }
-
   Future<void> _addFix_convertFlutterChild() async {
     var named = flutter.findNamedExpression(node, 'child');
     if (named == null) {
@@ -1528,29 +1601,6 @@
     }
   }
 
-  Future<void> _addFix_convertMapFromIterableToForLiteral() async {
-    final changeBuilder =
-        await createBuilder_convertMapFromIterableToForLiteral();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_FOR_ELEMENT);
-  }
-
-  Future<void> _addFix_convertSingleQuotes() async {
-    final changeBuilder = await createBuilder_convertQuotes(true);
-    _addFixFromBuilder(
-        changeBuilder, DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING);
-  }
-
-  Future<void> _addFix_convertToExpressionBody() async {
-    final changeBuilder = await createBuilder_convertToExpressionFunctionBody();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
-  Future<void> _addFix_convertToGenericFunctionSyntax() async {
-    var changeBuilder = await createBuilder_convertToGenericFunctionSyntax();
-    _addFixFromBuilder(
-        changeBuilder, DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX);
-  }
-
   Future<void> _addFix_convertToIfNullOperator() async {
     var conditional = node.thisOrAncestorOfType<ConditionalExpression>();
     if (conditional == null) {
@@ -1577,17 +1627,6 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_IF_NULL);
   }
 
-  Future<void> _addFix_convertToInlineAdd() async {
-    final changeBuilder = await createBuilder_inlineAdd();
-    _addFixFromBuilder(changeBuilder, DartFixKind.INLINE_INVOCATION,
-        args: ['add']);
-  }
-
-  Future<void> _addFix_convertToIntLiteral() async {
-    final changeBuilder = await createBuilder_convertToIntLiteral();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_INT_LITERAL);
-  }
-
   Future<void> _addFix_convertToNamedArgument() async {
     var argumentList = node;
     if (argumentList is ArgumentList) {
@@ -1664,16 +1703,6 @@
     }
   }
 
-  Future<void> _addFix_convertToPackageImport() async {
-    final changeBuilder = await createBuilder_convertToPackageImport();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_PACKAGE_IMPORT);
-  }
-
-  Future<void> _addFix_convertToRelativeImport() async {
-    final changeBuilder = await createBuilder_convertToRelativeImport();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_RELATIVE_IMPORT);
-  }
-
   Future<void> _addFix_createClass() async {
     Element prefixElement;
     String name;
@@ -4110,14 +4139,19 @@
     }
   }
 
-  Future<void> _addFix_replaceWithVar() async {
-    var changeBuilder = await createBuilder_replaceWithVar();
-    _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_VAR);
-  }
+  Future<void> _addFix_sortDirectives() async {
+    var organizer =
+        DirectiveOrganizer(resolvedResult.content, unit, resolvedResult.errors);
 
-  Future<void> _addFix_sortChildPropertiesLast() async {
-    final changeBuilder = await createBuilder_sortChildPropertyLast();
-    _addFixFromBuilder(changeBuilder, DartFixKind.SORT_CHILD_PROPERTY_LAST);
+    var changeBuilder = _newDartChangeBuilder();
+    // todo (pq): consider restructuring organizer to allow a passed-in change builder
+    for (var edit in organizer.organize()) {
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addSimpleReplacement(
+            SourceRange(edit.offset, edit.length), edit.replacement);
+      });
+    }
+    _addFixFromBuilder(changeBuilder, DartFixKind.SORT_DIRECTIVES);
   }
 
   Future<void> _addFix_undefinedClass_useSimilar() async {
@@ -4451,6 +4485,7 @@
     if (change.edits.isEmpty && !importsOnly) {
       return;
     }
+    change.id = kind.id;
     change.message = formatList(kind.message, args);
     fixes.add(Fix(kind, change));
   }
@@ -4479,46 +4514,19 @@
     }
 
     var errorCode = error.errorCode;
-    if (errorCode == HintCode.UNUSED_ELEMENT) {
-      await compute(RemoveUnusedElement());
-    } else if (errorCode == HintCode.UNUSED_FIELD) {
-      await compute(RemoveUnusedField());
-    } else if (errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
-      await compute(RemoveUnusedLocalVariable());
-    } else if (errorCode == StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE) {
-      await compute(WrapInText());
-    } else if (errorCode == StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION) {
-      await compute(RemoveDeadIfNull());
-    } else if (errorCode ==
-            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 ||
-        errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 ||
-        errorCode ==
-            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) {
-      await compute(AddFieldFormalParameters());
-    } else if (errorCode is LintCode) {
-      var name = errorCode.name;
-      if (name == LintNames.always_declare_return_types) {
-        await compute(AddReturnType());
-      } else if (name == LintNames.avoid_private_typedef_functions) {
-        await compute(InlineTypedef());
-      } else if (name == LintNames.avoid_returning_null_for_future) {
-        await compute(WrapInFuture());
-      } else if (name == LintNames.prefer_collection_literals) {
-        await compute(ConvertToListLiteral());
-        await compute(ConvertToMapLiteral());
-        await compute(ConvertToSetLiteral());
-      } else if (name == LintNames.prefer_contains) {
-        await compute(ConvertToContains());
-      } else if (name == LintNames.prefer_interpolation_to_compose_strings) {
-        await compute(ReplaceWithInterpolation());
-      } else if (name == LintNames.prefer_iterable_whereType) {
-        await compute(ConvertToWhereType());
-      } else if (name == LintNames.prefer_null_aware_operators) {
-        await compute(ConvertToNullAware());
-      } else if (name == LintNames.unnecessary_null_in_if_null_operators) {
-        await compute(RemoveIfNullOperator());
-      } else if (name == LintNames.use_full_hex_values_for_flutter_colors) {
-        await compute(ReplaceWithEightDigitHex());
+    if (errorCode is LintCode) {
+      var generators = lintProducerMap[errorCode.name];
+      if (generators != null) {
+        for (var generator in generators) {
+          await compute(generator());
+        }
+      }
+    } else {
+      var generators = nonLintProducerMap[errorCode];
+      if (generators != null) {
+        for (var generator in generators) {
+          await compute(generator());
+        }
       }
     }
   }
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 6a91795..187c91b 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -23,6 +23,8 @@
       'avoid_return_types_on_setters';
   static const String avoid_returning_null_for_future =
       'avoid_returning_null_for_future';
+  static const String avoid_types_as_parameter_names =
+      'avoid_types_as_parameter_names';
   static const String avoid_types_on_closure_parameters =
       'avoid_types_on_closure_parameters';
   static const String await_only_futures = 'await_only_futures';
@@ -30,6 +32,7 @@
       'curly_braces_in_flow_control_structures';
   static const String diagnostic_describe_all_properties =
       'diagnostic_describe_all_properties';
+  static const String directives_ordering = 'directives_ordering';
   static const String empty_catches = 'empty_catches';
   static const String empty_constructor_bodies = 'empty_constructor_bodies';
   static const String empty_statements = 'empty_statements';
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 9253e3b..d1436b8 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
@@ -46,8 +46,6 @@
 
   @override
   Future<SourceChange> createChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     change = SourceChange(refactoringName);
     // function
     if (element.enclosingElement is CompilationUnitElement) {
@@ -59,8 +57,6 @@
       FieldElement field = element.variable;
       var elements = await getHierarchyMembers(searchEngine, field);
       await Future.forEach(elements, (ClassMemberElement member) async {
-        // TODO(brianwilkerson) Determine whether this await is necessary.
-        await null;
         if (member is FieldElement) {
           var getter = member.getter;
           if (!getter.isSynthetic) {
@@ -84,8 +80,6 @@
 
   Future<void> _updateElementDeclaration(
       PropertyAccessorElement element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // prepare "get" keyword
     Token getKeyword;
     {
@@ -115,8 +109,6 @@
   }
 
   Future _updateElementReferences(Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var matches = await searchEngine.searchReferences(element);
     var references = getSourceReferences(matches);
     for (var reference in references) {
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 6744118..416e5f2 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
@@ -39,8 +39,6 @@
 
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // check Element type
     if (element is FunctionElement) {
       if (element.enclosingElement is! CompilationUnitElement) {
@@ -67,8 +65,6 @@
 
   @override
   Future<SourceChange> createChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     change = SourceChange(refactoringName);
     // FunctionElement
     if (element is FunctionElement) {
@@ -80,8 +76,6 @@
       MethodElement method = element;
       var elements = await getHierarchyMembers(searchEngine, method);
       await Future.forEach(elements, (Element element) async {
-        // TODO(brianwilkerson) Determine whether this await is necessary.
-        await null;
         await _updateElementDeclaration(element);
         return _updateElementReferences(element);
       });
@@ -91,8 +85,6 @@
   }
 
   Future<void> _updateElementDeclaration(Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // prepare parameters
     FormalParameterList parameters;
     {
@@ -119,8 +111,6 @@
   }
 
   Future<void> _updateElementReferences(Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var matches = await searchEngine.searchReferences(element);
     var references = getSourceReferences(matches);
     for (var reference in references) {
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 7818889..8aa4a78 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -179,8 +179,6 @@
 
   @override
   Future<RefactoringStatus> checkFinalConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     result.addStatus(validateMethodName(name));
     result.addStatus(_checkParameterNames());
@@ -191,8 +189,6 @@
 
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     // selection
     result.addStatus(_checkSelection());
@@ -231,8 +227,6 @@
 
   @override
   Future<SourceChange> createChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var change = SourceChange(refactoringName);
     // replace occurrences with method invocation
     for (var occurrence in _occurrences) {
@@ -431,8 +425,6 @@
   /// Checks if created method will shadow or will be shadowed by other
   /// elements.
   Future<RefactoringStatus> _checkPossibleConflicts() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     var parent = _parentMember.parent;
     // top-level function
@@ -701,8 +693,6 @@
   /// Prepares information about used variables, which should be turned into
   /// parameters.
   Future<RefactoringStatus> _initializeParameters() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _parameters.clear();
     _parametersMap.clear();
     _parameterReferencesMap.clear();
@@ -766,8 +756,6 @@
   }
 
   Future<void> _initializeReturnType() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var typeProvider = await resolveResult.typeProvider;
     if (_selectionFunctionExpression != null) {
       variableType = '';
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 843a254..6726707 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -94,8 +94,6 @@
 
   @override
   Future<RefactoringStatus> checkFinalConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     result.addStatus(validateClassName(name));
     return result;
@@ -103,8 +101,6 @@
 
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
 
     result.addStatus(_checkSelection());
@@ -146,8 +142,6 @@
 
   @override
   Future<SourceChange> createChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var changeBuilder = DartChangeBuilder(sessionHelper.session);
     await changeBuilder.addFileEdit(resolveResult.path, (builder) {
       if (_expression != null) {
@@ -241,13 +235,9 @@
   }
 
   Future<RefactoringStatus> _initializeClasses() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
 
     Future<ClassElement> getClass(String name) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       var element = await sessionHelper.getClass(flutter.widgetsUri, name);
       if (element == null) {
         result.addFatalError(
@@ -258,8 +248,6 @@
     }
 
     Future<PropertyAccessorElement> getAccessor(String uri, String name) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       var element = await sessionHelper.getTopLevelPropertyAccessor(uri, name);
       if (element == null) {
         result.addFatalError("Unable to find 'required' in $uri");
@@ -280,8 +268,6 @@
   /// Prepare referenced local variables and fields, that should be turned
   /// into the widget class fields and constructor parameters.
   Future<RefactoringStatus> _initializeParameters() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _ParametersCollector collector;
     if (_expression != null) {
       var localRange = range.node(_expression);
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 f5e2e3f..1ad6b64 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -63,8 +63,6 @@
 
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     // prepare variable
     {
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 a35aa2a..00e267f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -263,8 +263,6 @@
 
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     // prepare method information
     result.addStatus(await _prepareMethod());
@@ -311,8 +309,6 @@
 
   /// Initializes [_methodElement] and related fields.
   Future<RefactoringStatus> _prepareMethod() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _methodElement = null;
     _methodParameters = null;
     _methodBody = null;
@@ -423,8 +419,6 @@
   _ReferenceProcessor(this.ref, this.reference);
 
   Future<void> init() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     refElement = reference.element;
 
     // prepare CorrectionUtils
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 b32654d..bb06cec 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
@@ -40,8 +40,6 @@
 
   @override
   Future<RefactoringStatus> checkAllConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = RefactoringStatus();
     result.addStatus(await checkInitialConditions());
     if (result.hasFatalError) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index 371f720..4e4caef 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -104,8 +104,6 @@
 
   @override
   Future<SourceChange> createChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var changeName = "$refactoringName '$oldName' to '$newName'";
     change = SourceChange(changeName);
     await fillChange();
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 38fc012..75d6ce5 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
@@ -66,8 +66,6 @@
 
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var result = await super.checkInitialConditions();
     if (element is MethodElement && (element as MethodElement).isOperator) {
       result.addFatalError('Cannot rename operator.');
@@ -160,8 +158,6 @@
         elementKind = element.kind;
 
   Future<RefactoringStatus> validate() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // check if there is a member with "newName" in the same ClassElement
     for (var newNameMember in getChildren(elementClass, name)) {
       result.addError(
@@ -292,8 +288,6 @@
 
   /// Fills [elements] with [Element]s to rename.
   Future _prepareElements() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (element is ClassMemberElement) {
       elements = await getHierarchyMembers(searchEngine, element);
     } else {
@@ -303,15 +297,11 @@
 
   /// Fills [references] with all references to [elements].
   Future _prepareReferences() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (!isRename) {
       return Future.value();
     }
     await _prepareElements();
     await Future.forEach(elements, (Element element) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       var elementReferences = await searchEngine.searchReferences(element);
       references.addAll(elementReferences);
     });
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 9376f8a..1ea0e0d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -56,8 +56,6 @@
 
   @override
   Future<void> fillChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // prepare references
     var matches = await searchEngine.searchReferences(element);
     var references = getSourceReferences(matches);
@@ -110,8 +108,6 @@
   }
 
   Future<void> _replaceSynthetic() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var classElement = element.enclosingElement;
 
     var result = await AnalysisSessionHelper(session)
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 0876e3a..1183fcc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
@@ -48,8 +48,6 @@
 
   @override
   Future<void> fillChange() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // update declaration
     {
       var prefix = element.prefix;
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 e6306ba..b3c18ef 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
@@ -186,8 +186,6 @@
   }
 
   Future<RefactoringStatus> validate() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _validateWillConflict();
     if (isRename) {
       references = await searchEngine.searchReferences(element);
@@ -271,8 +269,6 @@
 
   /// Validates if renamed [element] will shadow any [Element] named [name].
   Future _validateWillShadow() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var declarations = await searchEngine.searchMemberDeclarations(name);
     for (var declaration in declarations) {
       var member = declaration.element;
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 59cccd8..9f600f3 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -51,8 +51,6 @@
 /// Returns a [Set] with direct subclasses of [seed].
 Future<Set<ClassElement>> getDirectSubClasses(
     SearchEngine searchEngine, ClassElement seed) async {
-  // TODO(brianwilkerson) Determine whether this await is necessary.
-  await null;
   var matches = await searchEngine.searchSubtypes(seed);
   return matches.map((match) => match.element).cast<ClassElement>().toSet();
 }
@@ -83,8 +81,6 @@
 /// their subclasses.
 Future<Set<ClassMemberElement>> getHierarchyMembers(
     SearchEngine searchEngine, ClassMemberElement member) async {
-  // TODO(brianwilkerson) Determine whether this await is necessary.
-  await null;
   Set<ClassMemberElement> result = HashSet<ClassMemberElement>();
   // extension member
   if (member.enclosingElement is ExtensionElement) {
@@ -125,8 +121,6 @@
 /// corresponding named parameters in the method hierarchy.
 Future<List<ParameterElement>> getHierarchyNamedParameters(
     SearchEngine searchEngine, ParameterElement element) async {
-  // TODO(brianwilkerson) Determine whether this await is necessary.
-  await null;
   if (element.isNamed) {
     var method = element.enclosingElement;
     if (method is MethodElement) {
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 968e7a1..b680a98 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
@@ -18,8 +18,6 @@
 
   @override
   Future<Set<String>> membersOfSubtypes(ClassElement type) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var drivers = _drivers.toList();
     var searchedFiles = _createSearchedFiles(drivers);
 
@@ -29,8 +27,6 @@
     var members = <String>{};
 
     Future<void> addMembers(ClassElement type, SubtypeResult subtype) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       if (subtype != null && !visitedIds.add(subtype.id)) {
         return;
       }
@@ -57,13 +53,9 @@
 
   @override
   Future<Set<ClassElement>> searchAllSubtypes(ClassElement type) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allSubtypes = <ClassElement>{};
 
     Future<void> addSubtypes(ClassElement type) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       var directResults = await _searchDirectSubtypes(type);
       for (var directResult in directResults) {
         var directSubtype = directResult.enclosingElement as ClassElement;
@@ -79,8 +71,6 @@
 
   @override
   Future<List<SearchMatch>> searchMemberDeclarations(String name) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allDeclarations = <SearchMatch>[];
     var drivers = _drivers.toList();
     for (var driver in drivers) {
@@ -92,8 +82,6 @@
 
   @override
   Future<List<SearchMatch>> searchMemberReferences(String name) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allResults = <SearchResult>[];
     var drivers = _drivers.toList();
     var searchedFiles = _createSearchedFiles(drivers);
@@ -107,8 +95,6 @@
 
   @override
   Future<List<SearchMatch>> searchReferences(Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allResults = <SearchResult>[];
     var drivers = _drivers.toList();
     var searchedFiles = _createSearchedFiles(drivers);
@@ -121,16 +107,12 @@
 
   @override
   Future<List<SearchMatch>> searchSubtypes(ClassElement type) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var results = await _searchDirectSubtypes(type);
     return results.map(SearchMatchImpl.forSearchResult).toList();
   }
 
   @override
   Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allElements = <Element>{};
     var regExp = RegExp(pattern);
     var drivers = _drivers.toList();
@@ -152,8 +134,6 @@
   }
 
   Future<List<SearchResult>> _searchDirectSubtypes(ClassElement type) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var allResults = <SearchResult>[];
     var drivers = _drivers.toList();
     var searchedFiles = _createSearchedFiles(drivers);
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 3814029..c633e59 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -447,15 +447,8 @@
     b.write(writeOption('Feature set', options.contextFeatures.toString()));
     b.write('<br>');
 
-    b.write(
-        writeOption('Analyze function bodies', options.analyzeFunctionBodies));
     b.write(writeOption('Generate dart2js hints', options.dart2jsHint));
-    b.write(writeOption(
-        'Generate errors in implicit files', options.generateImplicitErrors));
-    b.write(
-        writeOption('Generate errors in SDK files', options.generateSdkErrors));
     b.write(writeOption('Generate hints', options.hint));
-    b.write(writeOption('Preserve comments', options.preserveComments));
 
     return b.toString();
   }
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index 929313a..71f5835 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -145,7 +145,6 @@
       properties['typeParameters'] = element.typeParameters;
     }
     if (element is VariableElement) {
-      properties['constantValue'] = element.constantValue;
       properties['hasImplicitType'] = element.hasImplicitType;
       properties['isConst'] = element.isConst;
       properties['isFinal'] = element.isFinal;
diff --git a/pkg/analysis_server/lib/src/status/pages.dart b/pkg/analysis_server/lib/src/status/pages.dart
index 2a83d87..795b8c9 100644
--- a/pkg/analysis_server/lib/src/status/pages.dart
+++ b/pkg/analysis_server/lib/src/status/pages.dart
@@ -32,8 +32,6 @@
   String get path => '/$id';
 
   Future<void> asyncDiv(void Function() gen, {String classes}) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (classes != null) {
       buf.writeln('<div class="$classes">');
     } else {
@@ -60,8 +58,6 @@
   }
 
   Future<String> generate(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.clear();
     // TODO(brianwilkerson) Determine if await is necessary, if so, change the
     // return type of [generatePage] to `Future<void>`.
@@ -155,8 +151,6 @@
   Page createUnknownPage(String unknownPath);
 
   Future<void> handleGetRequest(HttpRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     try {
       var path = request.uri.path;
 
@@ -195,8 +189,6 @@
     Page page, [
     int code = HttpStatus.ok,
   ]) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var response = request.response;
     response.statusCode = code;
     response.headers.contentType = ContentType.html;
@@ -204,10 +196,26 @@
     await response.close();
   }
 
+  Future<void> respondJson(
+    HttpRequest request,
+    Map<String, Object> json, [
+    int code = HttpStatus.ok,
+  ]) async {
+    var response = request.response;
+    response.statusCode = code;
+    response.headers.contentType = ContentType.json;
+    response.write(jsonEncode(json));
+    await response.close();
+  }
+
   Future<void> respondOk(
     HttpRequest request, {
     int code = HttpStatus.ok,
   }) async {
+    if (request.headers.contentType.subType == 'json') {
+      return respondJson(request, {'success': true}, code);
+    }
+
     var response = request.response;
     response.statusCode = code;
     await response.close();
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
new file mode 100644
index 0000000..20a9324
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+
+/// Extensions for [AstNode]s
+extension AstNodeExtensions on AstNode {
+  bool get inAsyncMethodOrFunction {
+    var body = thisOrAncestorOfType<FunctionBody>();
+    return body != null && body.isAsynchronous && body.star == null;
+  }
+
+  bool get inAsyncStarOrSyncStarMethodOrFunction {
+    var body = thisOrAncestorOfType<FunctionBody>();
+    return body != null && body.keyword != null && body.star != null;
+  }
+
+  bool get inCatchClause => thisOrAncestorOfType<CatchClause>() != null;
+
+  bool get inClassMemberBody {
+    var node = this;
+    while (true) {
+      var body = node.thisOrAncestorOfType<FunctionBody>();
+      if (body == null) {
+        return false;
+      }
+      var parent = body.parent;
+      if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
+        return true;
+      }
+      node = parent;
+    }
+  }
+
+  bool get inDoLoop => thisOrAncestorOfType<DoStatement>() != null;
+
+  bool get inForLoop =>
+      thisOrAncestorMatching((p) => p is ForStatement) != null;
+
+  bool get inLoop => inDoLoop || inForLoop || inWhileLoop;
+
+  bool get inSwitch => thisOrAncestorOfType<SwitchStatement>() != null;
+
+  bool get inWhileLoop => thisOrAncestorOfType<WhileStatement>() != null;
+}
+
+/// Extensions for [FunctionBody]s
+extension FunctionBodyExtensions on FunctionBody {
+  bool get isEmpty =>
+      this is EmptyFunctionBody ||
+      (this is BlockFunctionBody && beginToken.isSynthetic);
+}
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart
index 1552225..1602ed4 100644
--- a/pkg/analysis_server/lib/src/utilities/mocks.dart
+++ b/pkg/analysis_server/lib/src/utilities/mocks.dart
@@ -148,6 +148,12 @@
   Map<PluginInfo, Future<plugin.Response>> broadcastResults;
 
   @override
+  List<PluginInfo> plugins = [];
+
+  StreamController<void> pluginsChangedController =
+      StreamController.broadcast();
+
+  @override
   String get byteStorePath {
     fail('Unexpected invocation of byteStorePath');
   }
@@ -163,9 +169,7 @@
   }
 
   @override
-  List<PluginInfo> get plugins {
-    fail('Unexpected invocation of plugins');
-  }
+  Stream<void> get pluginsChanged => pluginsChangedController.stream;
 
   @override
   ResourceProvider get resourceProvider {
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 2ea56a3..b33c8d0 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -8,6 +8,7 @@
   analyzer: any
   analyzer_plugin: any
   args: any
+  charcode: any
   convert: any
   crypto: any
   dart_style: any
@@ -16,6 +17,7 @@
   logging: any
   meta: any
   nnbd_migration: any
+  pub_semver: any
   source_span: any
   stream_channel: any
   package_config: any
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index a7c48cf..72c03d1 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -103,8 +103,15 @@
 class F {var x = !1false;}''', <String>['1+true']);
 
     buildTests('testCommentSnippets018', '''
-class Map{}class Arrays{}class C{ m(!1){} n(!2 x, q)''',
-        <String>['1+Map', '1-void', '1-null', '2+Arrays', '2-void', '2-null']);
+class Map{}class Arrays{}class C{ m(!1){} n(!2 x, q)''', <String>[
+      '1+Map',
+      '1+dynamic',
+      '1+void',
+      '1-null',
+      '2+Arrays',
+      '2-void',
+      '2-null'
+    ]);
 
     buildTests('testCommentSnippets019', '''
 class A{m(){Object x;x.!1/**/clear()''', <String>['1+toString']);
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 0d7f152..3f0d69d 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -540,7 +540,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
     });
   }
 
@@ -569,7 +570,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
     });
   }
 
@@ -601,7 +603,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
     });
   }
 
@@ -611,7 +614,7 @@
 main(A p) { var v1 = p.is^; }''');
     await getSuggestions();
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'isVisible',
-        relevance: DART_RELEVANCE_DEFAULT);
+        relevance: DART_RELEVANCE_LOCAL_FIELD);
   }
 
   Future<void> test_keyword() {
@@ -674,8 +677,7 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
     });
   }
 
@@ -741,8 +743,7 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
     });
   }
 
@@ -828,14 +829,14 @@
     });
   }
 
-  Future<void> test_static() {
+  Future<void> test_static() async {
     addTestFile('class A {static b() {} c() {}} main() {A.^}');
-    return getSuggestions().then((_) {
-      expect(replacementOffset, equals(completionOffset));
-      expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
-      assertNoResult('c');
-    });
+    await getSuggestions();
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
+        relevance: DART_RELEVANCE_INHERITED_METHOD);
+    assertNoResult('c');
   }
 
   Future<void> test_topLevel() {
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index c493bf4..69a64aa 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -68,7 +68,7 @@
 
     var fix = EditDartFix(server, request);
     final response = await fix.compute();
-    fix.nonNullableFixTask?.server?.close();
+    fix.nonNullableFixTask?.shutdownServer();
     expect(response.id, id);
     return response;
   }
@@ -175,72 +175,74 @@
         throwsA(TypeMatcher<StateError>()));
   }
 
-  Future<void> test_nonNullable_analysisOptions_created() async {
-    // Add pubspec for nnbd migration to detect
-    newFile('/project/pubspec.yaml', content: '''
-name: testnnbd
-''');
+  Future<void> test_nonNullable_pubspec_environmentAdded() async {
+    var originalContent = '''
+name: foo
+''';
+    newFile('/project/pubspec.yaml', content: originalContent);
     createProject();
     var result = await performFix(includedFixes: ['non-nullable']);
     expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.hasErrors, isFalse);
     expect(result.edits, hasLength(1));
-    expectFileEdits('', result.edits[0], '''
-analyzer:
-  enable-experiment:
-    - non-nullable
+    expectFileEdits(originalContent, result.edits[0], '''
+environment:
+  sdk: '>=2.9.0 <2.10.0'
 
+name: foo
 ''');
   }
 
-  Future<void> test_nonNullable_analysisOptions_experimentsAdded() async {
-    var originalOptions = '''
-analyzer:
-  something:
-    - other
-
-linter:
-  - boo
+  Future<void> test_nonNullable_pubspec_sdkAdded() async {
+    var originalContent = '''
+name: foo
+environment:
+  x: y
 ''';
-    newFile('/project/analysis_options.yaml', content: originalOptions);
+    newFile('/project/pubspec.yaml', content: originalContent);
     createProject();
     var result = await performFix(includedFixes: ['non-nullable']);
     expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.hasErrors, isFalse);
     expect(result.edits, hasLength(1));
-    expectFileEdits(originalOptions, result.edits[0], '''
-analyzer:
-  something:
-    - other
-  enable-experiment:
-    - non-nullable
-
-linter:
-  - boo
+    expectFileEdits(originalContent, result.edits[0], '''
+name: foo
+environment:
+  x: y
+  sdk: '>=2.9.0 <2.10.0'
 ''');
   }
 
-  Future<void> test_nonNullable_analysisOptions_nnbdAdded() async {
-    var originalOptions = '''
-analyzer:
-  enable-experiment:
-    - other
-linter:
-  - boo
+  Future<void> test_nonNullable_pubspec_sdkNotUpdated() async {
+    var originalContent = '''
+name: foo
+environment:
+  sdk: '>=2.9.0 <2.10.0'
 ''';
-    newFile('/project/analysis_options.yaml', content: originalOptions);
+    newFile('/project/pubspec.yaml', content: originalContent);
+    createProject();
+    var result = await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions, isEmpty);
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, isEmpty);
+  }
+
+  Future<void> test_nonNullable_pubspec_sdkUpdated() async {
+    var originalContent = '''
+name: foo
+environment:
+  sdk: '>=2.7.0 <3.0.0'
+''';
+    newFile('/project/pubspec.yaml', content: originalContent);
     createProject();
     var result = await performFix(includedFixes: ['non-nullable']);
     expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.hasErrors, isFalse);
     expect(result.edits, hasLength(1));
-    expectFileEdits(originalOptions, result.edits[0], '''
-analyzer:
-  enable-experiment:
-    - other
-    - non-nullable
-linter:
-  - boo
+    expectFileEdits(originalContent, result.edits[0], '''
+name: foo
+environment:
+  sdk: '>=2.9.0 <2.10.0'
 ''');
   }
 
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 88ab0fd..0ed0c88 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -40,7 +40,9 @@
     final codeActions = await getCodeActions(mainFileUri.toString(),
         range: rangeFromMarkers(content));
     final assist = findEditAction(
-        codeActions, CodeActionKind.Refactor, "Add explicit 'show' combinator");
+        codeActions,
+        CodeActionKind('refactor.add.showCombinator'),
+        "Add explicit 'show' combinator");
 
     // Ensure the edit came back, and using documentChanges.
     expect(assist, isNotNull);
@@ -77,7 +79,9 @@
     final codeActions = await getCodeActions(mainFileUri.toString(),
         range: rangeFromMarkers(content));
     final assistAction = findEditAction(
-        codeActions, CodeActionKind.Refactor, "Add explicit 'show' combinator");
+        codeActions,
+        CodeActionKind('refactor.add.showCombinator'),
+        "Add explicit 'show' combinator");
 
     // Ensure the edit came back, and using changes.
     expect(assistAction, isNotNull);
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 fa93a77..f2485a1 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -40,8 +40,8 @@
 
     final codeActions = await getCodeActions(mainFileUri.toString(),
         range: rangeFromMarkers(content));
-    final fixAction = findEditAction(
-        codeActions, CodeActionKind.QuickFix, 'Remove unused import');
+    final fixAction = findEditAction(codeActions,
+        CodeActionKind('quickfix.remove.unusedImport'), 'Remove unused import');
 
     // Ensure the edit came back, and using documentChanges.
     expect(fixAction, isNotNull);
@@ -78,8 +78,8 @@
 
     final codeActions = await getCodeActions(mainFileUri.toString(),
         range: rangeFromMarkers(content));
-    final fixAction = findEditAction(
-        codeActions, CodeActionKind.QuickFix, 'Remove unused import');
+    final fixAction = findEditAction(codeActions,
+        CodeActionKind('quickfix.remove.unusedImport'), 'Remove unused import');
 
     // Ensure the edit came back, and using changes.
     expect(fixAction, isNotNull);
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index 2d5c444..5c5fd36 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/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;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -52,6 +55,29 @@
     expect(loc.uri, equals(referencedFileUri.toString()));
   }
 
+  Future<void> test_fromPlugins() async {
+    final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.foo');
+    final pluginAnalyzedFileUri = Uri.file(pluginAnalyzedFilePath);
+    final pluginResult = plugin.AnalysisGetNavigationResult(
+      [pluginAnalyzedFilePath],
+      [NavigationTarget(ElementKind.CLASS, 0, 0, 5, 0, 0)],
+      [
+        NavigationRegion(0, 5, [0])
+      ],
+    );
+    configureTestPlugin(respondWith: pluginResult);
+
+    newFile(pluginAnalyzedFilePath);
+    await initialize();
+    final res = await getDefinition(pluginAnalyzedFileUri, lsp.Position(0, 0));
+
+    expect(res, hasLength(1));
+    var loc = res.single;
+    expect(
+        loc.range, equals(lsp.Range(lsp.Position(0, 0), lsp.Position(0, 5))));
+    expect(loc.uri, equals(pluginAnalyzedFileUri.toString()));
+  }
+
   Future<void> test_nonDartFile() async {
     newFile(pubspecFilePath, content: simplePubspecContent);
     await initialize();
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
index b27ea0b..49dc5ce 100644
--- a/pkg/analysis_server/test/lsp/folding_test.dart
+++ b/pkg/analysis_server/test/lsp/folding_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 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;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -66,6 +68,65 @@
     expect(regions, unorderedEquals(expectedRegions));
   }
 
+  Future<void> test_fromPlugins_dartFile() async {
+    final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.dart');
+    final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath);
+
+    const content = '''
+    // [[contributed by fake plugin]]
+
+    class AnnotatedDartClass {[[
+      // content of dart class, contributed by server
+    ]]}
+    ''';
+    final ranges = rangesFromMarkers(content);
+    final withoutMarkers = withoutRangeMarkers(content);
+    newFile(pluginAnalyzedFilePath);
+
+    await initialize();
+    await openFile(pluginAnalyzedUri, withoutMarkers);
+
+    final pluginResult = plugin.AnalysisFoldingParams(
+      pluginAnalyzedFilePath,
+      [plugin.FoldingRegion(plugin.FoldingKind.DIRECTIVES, 7, 26)],
+    );
+    configureTestPlugin(notification: pluginResult.toNotification());
+
+    final res = await getFoldingRegions(pluginAnalyzedUri);
+    expect(
+      res,
+      unorderedEquals([
+        _toFoldingRange(ranges[0], FoldingRangeKind.Imports),
+        _toFoldingRange(ranges[1], null),
+      ]),
+    );
+  }
+
+  Future<void> test_fromPlugins_nonDartFile() async {
+    final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.sql');
+    final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath);
+    const content = '''
+      CREATE TABLE foo(
+         [[-- some columns]]
+      );
+    ''';
+    final withoutMarkers = withoutRangeMarkers(content);
+    newFile(pluginAnalyzedFilePath, content: withoutMarkers);
+
+    await initialize();
+    await openFile(pluginAnalyzedUri, withoutMarkers);
+
+    final pluginResult = plugin.AnalysisFoldingParams(
+      pluginAnalyzedFilePath,
+      [plugin.FoldingRegion(plugin.FoldingKind.CLASS_BODY, 33, 15)],
+    );
+    configureTestPlugin(notification: pluginResult.toNotification());
+
+    final res = await getFoldingRegions(pluginAnalyzedUri);
+    final expectedRange = rangeFromMarkers(content);
+    expect(res, [_toFoldingRange(expectedRange, null)]);
+  }
+
   Future<void> test_headersImportsComments() async {
     // TODO(dantup): Review why the file header and the method comment ranges
     // are different... one spans only the range to collapse, but the other
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 0d0421f..2d132bb 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -5,7 +5,8 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
-import 'package:analysis_server/src/lsp/handlers/handler_initialize.dart';
+import 'package:analysis_server/src/lsp/server_capabilities_computer.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -185,6 +186,95 @@
     }
   }
 
+  Future<void> test_dynamicRegistration_unregistersOutdatedAfterChange() async {
+    // Initialize by supporting dynamic registrations everywhere
+    List<Registration> registrations;
+    await handleExpectedRequest<ResponseMessage, RegistrationParams, void>(
+      Method.client_registerCapability,
+      () => initialize(
+          textDocumentCapabilities: withAllSupportedDynamicRegistrations(
+              emptyTextDocumentClientCapabilities)),
+      handler: (registrationParams) =>
+          registrations = registrationParams.registrations,
+    );
+
+    final unregisterRequest =
+        await expectRequest(Method.client_unregisterCapability, () {
+      final plugin = configureTestPlugin();
+      plugin.currentSession = PluginSession(plugin)
+        ..interestingFiles = ['*.foo'];
+      pluginManager.pluginsChangedController.add(null);
+    });
+    final unregistrations =
+        (unregisterRequest.params as UnregistrationParams).unregisterations;
+
+    // folding method should have been unregistered as the server now supports
+    // *.foo files for it as well.
+    final registrationIdForFolding = registrations
+        .singleWhere((r) => r.method == 'textDocument/foldingRange')
+        .id;
+    expect(
+      unregistrations,
+      contains(isA<Unregistration>()
+          .having((r) => r.method, 'method', 'textDocument/foldingRange')
+          .having((r) => r.id, 'id', registrationIdForFolding)),
+    );
+
+    // Renaming documents is a Dart-specific service that should not have been
+    // affected by the plugin change.
+    final registrationIdForRename =
+        registrations.singleWhere((r) => r.method == 'textDocument/rename').id;
+    expect(
+        unregistrations,
+        isNot(contains(isA<Unregistration>()
+            .having((r) => r.id, 'id', registrationIdForRename))));
+  }
+
+  Future<void> test_dynamicRegistration_updatesWithPlugins() async {
+    await initialize(
+      textDocumentCapabilities:
+          extendTextDocumentCapabilities(emptyTextDocumentClientCapabilities, {
+        'foldingRange': {'dynamicRegistration': true},
+      }),
+    );
+
+    // The server will send an unregister request followed by another register
+    // request to change document filter on folding. We need to respond to the
+    // unregister request as the server awaits that.
+    requestsFromServer
+        .firstWhere((r) => r.method == Method.client_unregisterCapability)
+        .then((request) {
+      respondTo(request, null);
+      return (request.params as UnregistrationParams).unregisterations;
+    });
+
+    final request = await expectRequest(Method.client_registerCapability, () {
+      final plugin = configureTestPlugin();
+      plugin.currentSession = PluginSession(plugin)
+        ..interestingFiles = ['*.sql'];
+      pluginManager.pluginsChangedController.add(null);
+    });
+
+    final registrations = (request.params as RegistrationParams).registrations;
+
+    final documentFilterSql = DocumentFilter(null, 'file', '**/*.sql');
+    final documentFilterDart = DocumentFilter('dart', 'file', null);
+    final expectedFoldingRegistration =
+        isA<TextDocumentRegistrationOptions>().having(
+      (o) => o.documentSelector,
+      'documentSelector',
+      containsAll([documentFilterSql, documentFilterDart]),
+    );
+
+    expect(
+      registrations,
+      contains(isA<Registration>()
+          .having((r) => r.method, 'method', 'textDocument/foldingRange')
+          .having((r) => r.registerOptions, 'registerOptions',
+              expectedFoldingRegistration)),
+    );
+  }
+
   Future<void> test_initialize() async {
     final response = await initialize();
     expect(response, isNotNull);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index d393fb4..b009198 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -12,12 +12,17 @@
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
+import 'package:analysis_server/src/utilities/mocks.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
@@ -38,11 +43,33 @@
         ClientCapabilitiesHelperMixin,
         LspAnalysisServerTestMixin {
   MockLspServerChannel channel;
+  TestPluginManager pluginManager;
   LspAnalysisServer server;
 
   @override
   Stream<Message> get serverToClient => channel.serverToClient;
 
+  DiscoveredPluginInfo configureTestPlugin({
+    plugin.ResponseResult respondWith,
+    plugin.Notification notification,
+  }) {
+    final info = DiscoveredPluginInfo('a', 'b', 'c', null, null);
+    pluginManager.plugins.add(info);
+
+    if (respondWith != null) {
+      pluginManager.broadcastResults = <PluginInfo, Future<plugin.Response>>{
+        info: Future.value(respondWith.toResponse('-', 1))
+      };
+    }
+
+    if (notification != null) {
+      server.notificationManager
+          .handlePluginNotification(info.pluginId, notification);
+    }
+
+    return info;
+  }
+
   /// Sends a request to the server and unwraps the result. Throws if the
   /// response was not successful or returned an error.
   @override
@@ -75,6 +102,7 @@
     channel = MockLspServerChannel(debugPrintCommunication);
     // Create an SDK in the mock file system.
     MockSdk(resourceProvider: resourceProvider);
+    pluginManager = TestPluginManager();
     server = LspAnalysisServer(
         channel,
         resourceProvider,
@@ -82,6 +110,7 @@
         DartSdkManager(convertPath('/sdk'), false),
         CrashReportingAttachmentsBuilder.empty,
         InstrumentationService.NULL_SERVICE);
+    server.pluginManager = pluginManager;
 
     projectFolderPath = convertPath('/home/test');
     projectFolderUri = Uri.file(projectFolderPath);
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 5267658..0ce5609 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -360,6 +360,9 @@
   bool get hasPublishedDocs => false;
 
   @override
+  bool get isIgnorable => true;
+
+  @override
   bool get isUnresolvedIdentifier => false;
 
   @override
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 33834f2..203a14c 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
@@ -400,11 +400,11 @@
 
     await computeSuggestions();
 
-    assertSuggest('children: <Widget>[],',
+    assertSuggest('children: [],',
         csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
         relevance: DART_RELEVANCE_NAMED_PARAMETER,
         defaultArgListString: null,
-        selectionOffset: 19,
+        selectionOffset: 11,
         defaultArgumentListTextRanges: null);
   }
 
@@ -444,11 +444,11 @@
 
     await computeSuggestions();
 
-    assertSuggest('children: <Widget>[],',
+    assertSuggest('children: [],',
         csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
         relevance: DART_RELEVANCE_NAMED_PARAMETER,
         defaultArgListString: null,
-        selectionOffset: 19,
+        selectionOffset: 11,
         defaultArgumentListTextRanges: null);
   }
 
@@ -466,11 +466,11 @@
 
     await computeSuggestions();
 
-    assertSuggest('children: <Widget>[],',
+    assertSuggest('children: [],',
         csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
         relevance: DART_RELEVANCE_NAMED_PARAMETER,
         defaultArgListString: null,
-        selectionOffset: 19,
+        selectionOffset: 11,
         defaultArgumentListTextRanges: null);
   }
 
@@ -494,11 +494,11 @@
 
     await computeSuggestions();
 
-    assertSuggest('children: ,',
+    assertSuggest('children: [],',
         csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
         relevance: DART_RELEVANCE_NAMED_PARAMETER,
         defaultArgListString: null,
-        selectionOffset: 10,
+        selectionOffset: 11,
         defaultArgumentListTextRanges: null);
   }
 
@@ -546,11 +546,11 @@
 
     await computeSuggestions();
 
-    assertSuggest('slivers: <Widget>[],',
+    assertSuggest('slivers: [],',
         csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
         relevance: DART_RELEVANCE_NAMED_PARAMETER,
         defaultArgListString: null,
-        selectionOffset: 18,
+        selectionOffset: 10,
         defaultArgumentListTextRanges: null);
   }
 
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 04a362b..ec3822e 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
@@ -74,6 +74,12 @@
     assertNotSuggested('Object');
   }
 
+  Future<void> test_Combinator_hide_duplicate() async {
+    addTestSource('import "dart:math" hide PI, ^;');
+    await computeSuggestions();
+    assertNotSuggested('PI');
+  }
+
   Future<void> test_Combinator_show() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
     addSource('/home/test/lib/ab.dart', '''
@@ -123,6 +129,12 @@
     assertNotSuggested('Object');
   }
 
+  Future<void> test_Combinator_show_duplicate() async {
+    addTestSource('import "dart:math" show PI, ^;');
+    await computeSuggestions();
+    assertNotSuggested('PI');
+  }
+
   Future<void> test_Combinator_show_export_withShow() async {
     addSource('/home/test/lib/a.dart', r'''
 class A {}
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index be5ab67..2edf873 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -74,7 +74,8 @@
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1',
+        relevance: DART_RELEVANCE_INHERITED_FIELD);
     assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
         relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
@@ -108,7 +109,8 @@
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1',
+        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'g2',
         relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
@@ -124,7 +126,8 @@
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1',
+        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
     assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
         relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
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 c4521dc..cd6b0a1 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
@@ -9,7 +9,9 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionManager, DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/parser.dart' as analyzer;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:meta/meta.dart';
@@ -52,7 +54,9 @@
   @override
   Future<List<CompletionSuggestion>> computeContributedSuggestions(
       DartCompletionRequest request) async {
-    return contributor.computeSuggestions(request);
+    var builder = SuggestionBuilder(request);
+    var suggestions = await contributor.computeSuggestions(request, builder);
+    return [...suggestions, ...builder.suggestions];
   }
 
   DartCompletionContributor createContributor();
@@ -100,6 +104,9 @@
   int replacementOffset;
   int replacementLength;
 
+  /// The Dartdoc information passed to requests.
+  final DartdocDirectiveInfo dartdocInfo = DartdocDirectiveInfo();
+
   DartCompletionRequest request;
 
   List<CompletionSuggestion> suggestions;
@@ -132,6 +139,33 @@
     addSource(testFile, content);
   }
 
+  void assertCoreTypeSuggestions() {
+    assertSuggest('Comparable');
+    assertSuggest('Comparator');
+    assertSuggest('DateTime');
+    assertSuggest('Deprecated');
+    assertSuggest('Duration');
+    assertSuggest('Error');
+    assertSuggest('Exception');
+    assertSuggest('FormatException');
+    assertSuggest('Function');
+    assertSuggest('Future');
+    assertSuggest('Invocation');
+    assertSuggest('Iterable');
+    assertSuggest('Iterator');
+    assertSuggest('List');
+    assertSuggest('Map');
+    assertSuggest('MapEntry');
+    assertSuggest('Null');
+    assertSuggest('Object');
+    assertSuggest('Pattern');
+    assertSuggest('RegExp');
+    assertSuggest('Set');
+    assertSuggest('StackTrace');
+    assertSuggest('Stream');
+    assertSuggest('String');
+  }
+
   void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
     expect(suggestion.parameterNames, isNull);
     expect(suggestion.parameterTypes, isNull);
@@ -544,7 +578,8 @@
         useNewRelevance, CompletionPerformance());
 
     // Build the request
-    var request = await DartCompletionRequestImpl.from(baseRequest);
+    var request =
+        await DartCompletionRequestImpl.from(baseRequest, dartdocInfo);
 
     var range = request.target.computeReplacementRange(request.offset);
     replacementOffset = range.offset;
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 86d3b20..ed776f5 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
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -51,7 +52,7 @@
         false,
         CompletionPerformance());
     var requestCompleter = Completer<DartCompletionRequest>();
-    DartCompletionRequestImpl.from(baseRequest)
+    DartCompletionRequestImpl.from(baseRequest, DartdocDirectiveInfo())
         .then((DartCompletionRequest request) {
       requestCompleter.complete(request);
     });
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 70752af..b043bd3 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
@@ -1924,7 +1924,7 @@
     assertNoSuggestions();
   }
 
-  Future<void> test_extendsClause() async {
+  Future<void> test_ExtendsClause() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     addTestSource('''
 import 'a.dart';
@@ -1935,6 +1935,41 @@
     assertSuggestClass('A');
   }
 
+  Future<void> test_ExtensionDeclaration_extendedType() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    addTestSource('''
+import 'a.dart';
+
+extension E on ^
+''');
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertNotSuggested('E');
+  }
+
+  Future<void> test_ExtensionDeclaration_extendedType2() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    addTestSource('''
+import 'a.dart';
+
+extension E on ^ {}
+''');
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertNotSuggested('E');
+  }
+
+  Future<void> test_ExtensionDeclaration_member() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    addTestSource('''
+import 'a.dart';
+
+extension E on A { ^ }
+''');
+    await computeSuggestions();
+    assertSuggestClass('A');
+  }
+
   Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
@@ -1959,6 +1994,80 @@
     assertNoSuggestions();
   }
 
+  Future<void> test_FieldDeclaration_type() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        class C {^ foo;) ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_FieldDeclaration_type_after_comment1() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        class C {
+          // comment
+          ^ foo;
+        } ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_FieldDeclaration_type_after_comment2() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        class C {
+          /* comment */
+          ^ foo;
+        } ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_FieldDeclaration_type_after_comment3() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        class C {
+          /// some dartdoc
+          ^ foo;
+        } ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_FieldDeclaration_type_without_semicolon() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        class C {^ foo} ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
   Future<void> test_FieldFormalParameter_in_non_constructor() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('class A {B(this.^foo) {}}');
@@ -4330,6 +4439,74 @@
     assertNotSuggested('==');
   }
 
+  Future<void> test_TopLevelVariableDeclaration_type() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        ^ foo; ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_TopLevelVariableDeclaration_type_after_comment1() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        // comment
+        ^ foo; ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_TopLevelVariableDeclaration_type_after_comment2() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        /* comment */
+        ^ foo; ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_TopLevelVariableDeclaration_type_after_comment3() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        /// some dartdoc
+        ^ foo; ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
+  Future<void> test_TopLevelVariableDeclaration_type_without_semicolon() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addSource('/home/test/lib/a.dart', 'class A { }');
+    addTestSource('''
+        import 'a.dart';
+        ^ foo ''');
+
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertCoreTypeSuggestions();
+  }
+
   Future<void> test_TopLevelVariableDeclaration_typed_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
index 8f3172c..420da3c 100644
--- a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
@@ -75,7 +75,34 @@
     assertSuggestMethod('y', 'A', 'Future<dynamic>');
   }
 
-  Future<void> test_Block_inherited_imported() async {
+  Future<void> test_Block_inherited_imported_from_constructor() async {
+    // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
+    resolveSource('/home/test/lib/b.dart', '''
+      lib B;
+      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }''');
+    addTestSource('''
+      import "b.dart";
+      class A extends E implements I with M {const A() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+    assertNotSuggested('==');
+  }
+
+  Future<void> test_Block_inherited_imported_from_method() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     resolveSource('/home/test/lib/b.dart', '''
       lib B;
@@ -102,7 +129,31 @@
     assertNotSuggested('==');
   }
 
-  Future<void> test_Block_inherited_local() async {
+  Future<void> test_Block_inherited_local_from_constructor() async {
+    // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {const A() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+  }
+
+  Future<void> test_Block_inherited_local_from_method() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     addTestSource('''
 class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
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 4272bdc..0df9309 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
@@ -71,7 +71,13 @@
   }
 
   List<Keyword> get constructorParameter {
-    var keywords = <Keyword>[Keyword.COVARIANT, Keyword.DYNAMIC, Keyword.THIS];
+    var keywords = <Keyword>[
+      Keyword.COVARIANT,
+      Keyword.DYNAMIC,
+      Keyword.THIS,
+      Keyword.DYNAMIC,
+      Keyword.VOID
+    ];
     if (isEnabled(ExperimentalFeatures.non_nullable)) {
       keywords.add(Keyword.REQUIRED);
     }
@@ -156,7 +162,7 @@
   }
 
   List<Keyword> get methodParameter {
-    var keywords = <Keyword>[Keyword.COVARIANT, Keyword.DYNAMIC];
+    var keywords = <Keyword>[Keyword.COVARIANT, Keyword.DYNAMIC, Keyword.VOID];
     if (isEnabled(ExperimentalFeatures.non_nullable)) {
       keywords.add(Keyword.REQUIRED);
     }
@@ -1028,12 +1034,26 @@
     assertSuggestKeywords(constructorParameter);
   }
 
+  Future<void> test_constructor_param_noPrefix_func_parameter() async {
+    addTestSource('class A { A(^ Function(){}) {}}');
+    await computeSuggestions();
+    expect(suggestions, isNotEmpty);
+    assertSuggestKeywords(constructorParameter);
+  }
+
   Future<void> test_constructor_param_prefix() async {
     addTestSource('class A { A(t^) {}}');
     await computeSuggestions();
     assertSuggestKeywords(constructorParameter);
   }
 
+  Future<void> test_constructor_param_prefix_func_parameter() async {
+    addTestSource('class A { A(v^ Function(){}) {}}');
+    await computeSuggestions();
+    expect(suggestions, isNotEmpty);
+    assertSuggestKeywords(constructorParameter);
+  }
+
   Future<void> test_do_break_continue_insideClass() async {
     addTestSource('class A {foo() {do {^} while (true);}}');
     await computeSuggestions();
@@ -1971,6 +1991,13 @@
     assertSuggestKeywords(methodParameter);
   }
 
+  Future<void> test_method_param_noPrefix_func_parameter() async {
+    addTestSource('class A { foo(^ Function(){}) {}}');
+    await computeSuggestions();
+    expect(suggestions, isNotEmpty);
+    assertSuggestKeywords(methodParameter);
+  }
+
   Future<void> test_method_param_positional_init() async {
     addTestSource('class A { foo([bool bar = ^]) {}}');
     await computeSuggestions();
@@ -1992,6 +2019,13 @@
     assertSuggestKeywords(methodParameter);
   }
 
+  Future<void> test_method_param_prefix_func_parameter() async {
+    addTestSource('class A { foo(v^ Function(){}) {}}');
+    await computeSuggestions();
+    expect(suggestions, isNotEmpty);
+    assertSuggestKeywords(methodParameter);
+  }
+
   Future<void> test_mixin() async {
     addTestSource('mixin M o^ { }');
     await computeSuggestions();
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 8bf8c19..6827874 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
@@ -1552,7 +1552,18 @@
 
   Future<void> test_CatchClause_typed() async {
     // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    addTestSource('''
+class A {
+  a() {
+    try {
+      var x;
+    } on E catch (e) {
+      ^
+    }
+  }
+}
+class E {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -2150,6 +2161,30 @@
     }
   }
 
+  Future<void> test_doc_macro() async {
+    dartdocInfo.addTemplateNamesAndValues([
+      'template_name'
+    ], [
+      '''
+Macro contents on
+multiple lines.
+'''
+    ]);
+    addTestSource('''
+/// {@macro template_name}
+///
+/// With an additional line.
+int x = 0;
+
+void main() {^}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestTopLevelVar('x', 'int');
+    expect(suggestion.docSummary, 'Macro contents on\nmultiple lines.');
+    expect(suggestion.docComplete,
+        'Macro contents on\nmultiple lines.\n\n\nWith an additional line.');
+  }
+
   Future<void> test_doc_topLevel() async {
     var docLines = r'''
 /// My documentation.
@@ -2168,7 +2203,7 @@
 class MyClass {}
 
 $docLines
-class MyClassTypeAlias = Object with MyClass;
+class MyMixinApplication = Object with MyClass;
 
 $docLines
 enum MyEnum {A, B, C}
@@ -2187,7 +2222,7 @@
       assertDoc(suggestion);
     }
     {
-      var suggestion = assertSuggestClassTypeAlias('MyClassTypeAlias');
+      var suggestion = assertSuggestClass('MyMixinApplication');
       assertDoc(suggestion);
     }
     {
@@ -2470,7 +2505,7 @@
     assertSuggestMethod('bar', 'C', 'void',
         relevance: DART_RELEVANCE_LOCAL_METHOD);
     assertSuggestFunctionTypeAlias('F2', 'int');
-    assertSuggestClassTypeAlias('Clz');
+    assertSuggestClass('Clz');
     assertSuggestClass('C');
     assertNotSuggested('x');
     assertNotSuggested('_B');
@@ -2489,7 +2524,7 @@
     assertNoSuggestions();
   }
 
-  Future<void> test_extendsClause() async {
+  Future<void> test_ExtendsClause() async {
     addTestSource('''
 class A {}
 mixin M {}
@@ -2500,6 +2535,35 @@
     assertNotSuggested('M');
   }
 
+  Future<void> test_ExtensionDeclaration_extendedType() async {
+    addTestSource('''
+class A {}
+extension E on ^
+''');
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertNotSuggested('E');
+  }
+
+  Future<void> test_ExtensionDeclaration_extendedType2() async {
+    addTestSource('''
+class A {}
+extension E on ^ {}
+''');
+    await computeSuggestions();
+    assertSuggestClass('A');
+    assertNotSuggested('E');
+  }
+
+  Future<void> test_ExtensionDeclaration_member() async {
+    addTestSource('''
+class A {}
+extension E on A { ^ }
+''');
+    await computeSuggestions();
+    assertSuggestClass('A');
+  }
+
   Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
@@ -2963,8 +3027,12 @@
   Future<void> test_FunctionExpression_body_function() async {
     // Block  BlockFunctionBody  FunctionExpression
     addTestSource('''
-        void bar() { }
-        String foo(List args) {x.then((R b) {^});}''');
+void bar() { }
+String foo(List args) {
+  x.then((R b) {^});
+}
+class R {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -3017,7 +3085,15 @@
   Future<void> test_IfStatement() async {
     // SimpleIdentifier  IfStatement
     addTestSource('''
-        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+class A {
+  var b;
+  X _c;
+  foo() {
+    A a; if (true) ^
+  }
+}
+class X {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -3048,7 +3124,16 @@
   Future<void> test_IfStatement_empty() async {
     // SimpleIdentifier  IfStatement
     addTestSource('''
-        class A {var b; X _c; foo() {A a; if (^) something}}''');
+class A {
+  var b;
+  X _c;
+  foo() {
+    A a;
+    if (^) something
+  }
+}
+class X {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -3063,13 +3148,22 @@
   Future<void> test_IfStatement_empty_private() async {
     // SimpleIdentifier  IfStatement
     addTestSource('''
-        class A {var b; X _c; foo() {A a; if (_^) something}}''');
+class A {
+  var b;
+  X _c;
+  foo() {
+    A a;
+    if (_^) something
+  }
+}
+class X {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset - 1);
     expect(replacementLength, 1);
     assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
-    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT);
     assertNotSuggested('Object');
     assertSuggestClass('A');
     assertNotSuggested('==');
@@ -3686,7 +3780,16 @@
 
   Future<void> test_MethodDeclaration_body_getters() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    addTestSource('''
+class A {
+  @deprecated
+  X get f => 0;
+  Z a() {^}
+  get _g => 1;
+}
+class X {}
+class Z {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -3751,7 +3854,15 @@
 
   Future<void> test_MethodDeclaration_members() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    addTestSource('''
+class A {
+  @deprecated X f;
+  Z _a() {^}
+  var _g;
+}
+class X {}
+class Z {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -3782,13 +3893,22 @@
 
   Future<void> test_MethodDeclaration_members_private() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X f; Z _a() {_^} var _g;}');
+    addTestSource('''
+class A {
+  @deprecated
+  X f;
+  Z _a() {_^}
+  var _g;
+}
+class X {}
+class Z {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset - 1);
     expect(replacementLength, 1);
-    var methodA = assertSuggestMethod('_a', 'A', 'Z',
-        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    var methodA =
+        assertSuggestMethod('_a', 'A', 'Z', relevance: DART_RELEVANCE_DEFAULT);
     if (methodA != null) {
       expect(methodA.element.isDeprecated, isFalse);
       expect(methodA.element.isPrivate, isTrue);
@@ -3803,7 +3923,7 @@
     // If user prefixed completion with '_' then suggestion of private members
     // should be the same as public members
     var getterG =
-        assertSuggestField('_g', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+        assertSuggestField('_g', null, relevance: DART_RELEVANCE_DEFAULT);
     if (getterG != null) {
       expect(getterG.element.isDeprecated, isFalse);
       expect(getterG.element.isPrivate, isTrue);
@@ -3814,7 +3934,14 @@
 
   Future<void> test_MethodDeclaration_parameters_named() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    addTestSource('''
+class A {
+  @deprecated
+  Z a(X x, _, b, {y: boo}) {^}
+}
+class X {}
+class Z {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -3837,7 +3964,12 @@
     addTestSource('''
 foo() { }
 void bar() { }
-class A {Z a(X x, [int y=1]) {^}}''');
+class A {
+  Z a(X x, [int y=1]) {^}
+}
+class X {}
+class Z {}
+''');
     await computeSuggestions();
 
     expect(replacementOffset, completionOffset);
@@ -4530,7 +4662,7 @@
     addTestSource('main() {var ab; var _ab; ^}');
     await computeSuggestions();
     assertSuggestLocalVariable('ab', null);
-    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
+    assertSuggestLocalVariable('_ab', null);
   }
 
   Future<void> test_prioritization_private() async {
@@ -4544,7 +4676,7 @@
     addTestSource('main() {var ab; var _ab; a^}');
     await computeSuggestions();
     assertSuggestLocalVariable('ab', null);
-    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
+    assertSuggestLocalVariable('_ab', null);
   }
 
   Future<void> test_PropertyAccess_expression() async {
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 ff816cc..d0df1f8 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
@@ -225,6 +225,110 @@
   }''', displayText: 'foo() { … }', selectionOffset: 51, selectionLength: 0);
   }
 
+  Future<void> test_inComment() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  // comment^
+  void m() {}
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
+  Future<void> test_inComment_dartdoc() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  /// dartdoc^
+  void m() {}
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
+  Future<void> test_inComment_reference() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  /// Asdf [St^]
+  void m() {}
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
+  Future<void> test_inConstructor() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  var one;
+  B(this.^);
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
+  Future<void> test_inConstructor2() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  var one;
+  var two;
+  B(this.one, {this.^});
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
+  Future<void> test_inFieldDeclaration_name() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  final String ^type;
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
+  Future<void> test_inFieldDeclaration_value() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  final String type = '^';
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
   Future<void> test_inMixin_of_interface() async {
     addTestSource('''
 class A {
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 15e904c..c46ba90 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
@@ -28,7 +28,19 @@
     var previous = suggestions[0];
     for (var i = 1; i < length; i++) {
       var current = suggestions[i];
-      expect(current.relevance, lessThan(previous.relevance));
+      if (current.relevance >= previous.relevance) {
+        suggestions.sort(
+            (first, second) => second.relevance.compareTo(first.relevance));
+        var buffer = StringBuffer();
+        buffer.write('Suggestions are not in the expected order. ');
+        buffer.writeln('To accept the current state, use');
+        buffer.writeln();
+        for (var suggestion in suggestions) {
+          var completion = suggestion.completion;
+          buffer.writeln("  suggestionWith(completion: '$completion'),");
+        }
+        fail(buffer.toString());
+      }
       previous = current;
     }
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
index a456ad4..cb7fff9 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
@@ -30,12 +30,29 @@
     var length = suggestions.length;
     expect(length, greaterThan(1),
         reason: 'Test must specify more than one suggestion');
+    var inOrder = true;
     var previous = suggestions[0];
     for (var i = 1; i < length; i++) {
       var current = suggestions[i];
-      expect(current.relevance, lessThan(previous.relevance));
+      if (current.relevance >= previous.relevance) {
+        inOrder = false;
+      }
       previous = current;
     }
+    if (!inOrder) {
+      suggestions.sort((first, second) => second.relevance - first.relevance);
+      var buffer = StringBuffer();
+      buffer.writeln('Actual sort order does not match expected order.');
+      buffer.writeln('To accept the actual sort order, use:');
+      buffer.writeln();
+      buffer.writeln('    assertOrder([');
+      for (var suggestion in suggestions) {
+        var completion = suggestion.completion;
+        buffer.writeln("      suggestionWith(completion: '$completion'),");
+      }
+      buffer.writeln('    ]);');
+      fail(buffer.toString());
+    }
   }
 
   Future<void> test_contextType() async {
@@ -65,6 +82,27 @@
     ]);
   }
 
+  Future<void> test_elementKind() async {
+    await addTestFile('''
+class A {
+  int get g => 0;
+  void m() { }
+  set s(int x) {}
+}
+
+void f(A a) {
+  a.^
+}
+''');
+    // The order below is dependent on generated data, so it can validly change
+    // when the data is re-generated.
+    assertOrder([
+      suggestionWith(completion: 'g'),
+      suggestionWith(completion: 's'),
+      suggestionWith(completion: 'm'),
+    ]);
+  }
+
   Future<void> test_hasDeprecated() async {
     await addTestFile('''
 class C {
@@ -100,7 +138,7 @@
     assertOrder([
       suggestionWith(completion: 'b'),
       suggestionWith(completion: 'a'),
-      suggestionWith(completion: 'hashCode'),
+      suggestionWith(completion: 'toString'),
     ]);
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart
index e16d539..d3a952e 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart
@@ -41,6 +41,27 @@
     ]);
   }
 
+  Future<void> test_elementKind() async {
+    await addTestFile('''
+class C {
+  static int f = 0;
+  static void get g {}
+  static set s(int x) {}
+  static void m() {}
+}
+
+void g() {
+  C.^
+}
+''');
+    assertOrder([
+      suggestionWith(completion: 'g'),
+      suggestionWith(completion: 's'),
+      suggestionWith(completion: 'm'),
+      suggestionWith(completion: 'f'),
+    ]);
+  }
+
   Future<void> test_hasDeprecated() async {
     await addTestFile('''
 class C {
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 c3c7033..dae0842 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
@@ -28,8 +28,8 @@
     addTestSource('enum E { one, two } main() {E.^}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -38,8 +38,8 @@
     addTestSource('enum E { one, two } main() {E.o^}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -48,8 +48,8 @@
     addTestSource('enum E { one, two } main() {E.^ int g;}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -64,8 +64,8 @@
     addTestSource('enum E { one, two } main() {E.^.}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -80,19 +80,16 @@
     addTestSource('enum E { one, two } main() {E.^.o}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
 
-  @failingTest
   Future<void> test_enumConst_deprecated() async {
     addTestSource('@deprecated enum E { one, two } main() {E.^}');
     await computeSuggestions();
     assertNotSuggested('E');
-    // TODO(danrubel) Investigate why enum suggestion is not marked
-    // as deprecated if enum ast element is deprecated
     assertSuggestEnumConst('one', isDeprecated: true);
     assertSuggestEnumConst('two', isDeprecated: true);
     assertNotSuggested('index');
diff --git a/pkg/analysis_server/test/src/cider/cider_service.dart b/pkg/analysis_server/test/src/cider/cider_service.dart
new file mode 100644
index 0000000..b08f2f2
--- /dev/null
+++ b/pkg/analysis_server/test/src/cider/cider_service.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+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';
+
+class CiderServiceTest with ResourceProviderMixin {
+  static final String _testPath = '/workspace/dart/test/lib/test.dart';
+
+  final ByteStore byteStore = MemoryByteStore();
+
+  final StringBuffer logBuffer = StringBuffer();
+  PerformanceLog logger;
+  MockSdk sdk;
+
+  FileResolver fileResolver;
+
+  String get testPath => _testPath;
+
+  /// Create a new [FileResolver] into [fileResolver].
+  ///
+  /// We do this the first time, and to test reusing results from [byteStore].
+  void createFileResolver() {
+    var workspace = BazelWorkspace.find(
+      resourceProvider,
+      convertPath(_testPath),
+    );
+
+    fileResolver = FileResolver(
+      logger,
+      resourceProvider,
+      byteStore,
+      workspace.createSourceFactory(sdk, null),
+      (String path) => _getDigest(path),
+      null,
+      workspace: workspace,
+      libraryContextResetTimeout: null,
+    );
+    fileResolver.testView = FileResolverTestView();
+  }
+
+  void setUp() {
+    registerLintRules();
+
+    logger = PerformanceLog(logBuffer);
+    sdk = MockSdk(resourceProvider: resourceProvider);
+
+    newFile('/workspace/WORKSPACE', content: '');
+    createFileResolver();
+  }
+
+  String _getDigest(String path) {
+    try {
+      var content = resourceProvider.getFile(path).readAsStringSync();
+      var contentBytes = utf8.encode(content);
+      return md5.convert(contentBytes).toString();
+    } catch (_) {
+      return '';
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/src/cider/completion_test.dart b/pkg/analysis_server/test/src/cider/completion_test.dart
new file mode 100644
index 0000000..9aedd3f
--- /dev/null
+++ b/pkg/analysis_server/test/src/cider/completion_test.dart
@@ -0,0 +1,407 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/cider/completion.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show CompletionSuggestion, ElementKind;
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'cider_service.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(CiderCompletionComputerTest);
+  });
+}
+
+@reflectiveTest
+class CiderCompletionComputerTest extends CiderServiceTest {
+  final CiderCompletionCache _completionCache = CiderCompletionCache();
+
+  CiderCompletionComputer _computer;
+  CiderCompletionResult _completionResult;
+  List<CompletionSuggestion> _suggestions;
+
+  @override
+  void setUp() {
+    super.setUp();
+  }
+
+  Future<void> test_compute() async {
+    var context = _updateFile(r'''
+class A {}
+
+int a = 0;
+
+main(int b) {
+  int c = 0;
+  ^
+}
+''');
+
+    // ignore: deprecated_member_use_from_same_package
+    _suggestions = await _newComputer().compute(
+      convertPath(testPath),
+      context.offset,
+    );
+
+    _assertHasCompletion(text: 'a');
+    _assertHasCompletion(text: 'b');
+    _assertHasCompletion(text: 'c');
+    _assertHasClass(text: 'A');
+    _assertHasClass(text: 'String');
+
+    _assertNoClass(text: 'Random');
+  }
+
+  Future<void> test_compute2() async {
+    await _compute2(r'''
+class A {}
+
+int a = 0;
+
+main(int b) {
+  int c = 0;
+  ^
+}
+''');
+
+    _assertHasCompletion(text: 'a');
+    _assertHasCompletion(text: 'b');
+    _assertHasCompletion(text: 'c');
+    _assertHasClass(text: 'A');
+    _assertHasClass(text: 'String');
+
+    _assertNoClass(text: 'Random');
+  }
+
+  Future<void> test_compute2_sameSignature_sameResult() async {
+    _createFileResolver();
+    await _compute2(r'''
+var a = ^;
+''');
+    var lastResult = _completionResult;
+
+    // Ask for completion using new resolver and computer.
+    // But the file signature is the same, so the same result.
+    _createFileResolver();
+    await _compute2(r'''
+var a = ^;
+''');
+    expect(_completionResult, same(lastResult));
+  }
+
+  Future<void> test_compute2_updateImportedLibrary() async {
+    var corePath = convertPath('/sdk/lib/core/core.dart');
+
+    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
+    newFile(aPath, content: r'''
+class A {}
+''');
+
+    var content = r'''
+import 'a.dart';
+^
+''';
+
+    _createFileResolver();
+    await _compute2(content);
+    _assertComputedImportedLibraries([corePath, aPath]);
+    _assertHasClass(text: 'A');
+
+    // Repeat the query, still has 'A'.
+    _createFileResolver();
+    await _compute2(content);
+    _assertComputedImportedLibraries([]);
+    _assertHasClass(text: 'A');
+
+    // Update the imported library, has 'B', but not 'A'.
+    newFile(aPath, content: r'''
+class B {}
+''');
+    _createFileResolver();
+    await _compute2(content);
+    _assertComputedImportedLibraries([aPath]);
+    _assertHasClass(text: 'B');
+    _assertNoClass(text: 'A');
+  }
+
+  Future<void> test_compute2_updateImports() async {
+    var corePath = convertPath('/sdk/lib/core/core.dart');
+
+    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
+    newFile(aPath, content: r'''
+class A {}
+''');
+
+    _createFileResolver();
+    await _compute2(r'''
+var a = ^;
+''');
+    _assertComputedImportedLibraries([corePath]);
+    _assertHasClass(text: 'String');
+
+    // Repeat the query, still has 'A'.
+    _createFileResolver();
+    await _compute2(r'''
+import 'a.dart';
+var a = ^;
+''');
+    _assertComputedImportedLibraries([aPath]);
+    _assertHasClass(text: 'A');
+    _assertHasClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_excludeNotMatching() async {
+    await _compute2(r'''
+var a = F^;
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertNoClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_location_beforeMethod() async {
+    await _compute2(r'''
+class A {
+  F^
+  void foo() {}
+}
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertNoClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_location_functionReturnType() async {
+    await _compute2(r'''
+F^ foo() {}
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertNoClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_location_methodReturnType() async {
+    await _compute2(r'''
+class A {
+  F^ foo() {}
+}
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertNoClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_location_parameterType() async {
+    await _compute2(r'''
+void foo(F^ a) {}
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertNoClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_location_parameterType2() async {
+    await _compute2(r'''
+void foo(^a) {}
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertHasClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_location_statement() async {
+    await _compute2(r'''
+main() {
+  F^
+  0;
+}
+''');
+
+    _assertHasClass(text: 'Future');
+    _assertNoClass(text: 'String');
+  }
+
+  Future<void> test_filterSort_byPattern_preferPrefix() async {
+    await _compute2(r'''
+class Foobar {}
+class Falcon {}
+var a = Fo^;
+''');
+
+    _assertOrder([
+      _assertHasClass(text: 'Foobar'),
+      _assertHasClass(text: 'Falcon'),
+    ]);
+  }
+
+  Future<void> test_filterSort_preferLocal() async {
+    await _compute2(r'''
+var a = 0;
+main() {
+  var b = 0;
+  var v = ^;
+}
+''');
+
+    _assertOrder([
+      _assertHasLocalVariable(text: 'b'),
+      _assertHasTopLevelVariable(text: 'a'),
+    ]);
+  }
+
+  Future<void> test_filterSort_sortByName() async {
+    await _compute2(r'''
+main() {
+  var a = 0;
+  var b = 0;
+  var v = ^;
+}
+''');
+
+    _assertOrder([
+      _assertHasLocalVariable(text: 'a'),
+      _assertHasLocalVariable(text: 'b'),
+    ]);
+  }
+
+  void _assertComputedImportedLibraries(List<String> expected) {
+    expected = expected.map(convertPath).toList();
+    expect(
+      _computer.computedImportedLibraries,
+      unorderedEquals(expected),
+    );
+  }
+
+  CompletionSuggestion _assertHasClass({@required String text}) {
+    var matching = _matchingCompletions(
+      text: text,
+      elementKind: ElementKind.CLASS,
+    );
+    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
+    return matching.single;
+  }
+
+  void _assertHasCompletion({@required String text}) {
+    var matching = _matchingCompletions(text: text);
+    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
+  }
+
+  CompletionSuggestion _assertHasLocalVariable({@required String text}) {
+    var matching = _matchingCompletions(
+      text: text,
+      elementKind: ElementKind.LOCAL_VARIABLE,
+    );
+    expect(
+      matching,
+      hasLength(1),
+      reason: 'Expected exactly one completion in $_suggestions',
+    );
+    return matching.single;
+  }
+
+  CompletionSuggestion _assertHasTopLevelVariable({@required String text}) {
+    var matching = _matchingCompletions(
+      text: text,
+      elementKind: ElementKind.TOP_LEVEL_VARIABLE,
+    );
+    expect(
+      matching,
+      hasLength(1),
+      reason: 'Expected exactly one completion in $_suggestions',
+    );
+    return matching.single;
+  }
+
+  void _assertNoClass({@required String text}) {
+    var matching = _matchingCompletions(
+      text: text,
+      elementKind: ElementKind.CLASS,
+    );
+    expect(matching, isEmpty, reason: 'Expected zero completions');
+  }
+
+  void _assertOrder(List<CompletionSuggestion> suggestions) {
+    var lastIndex = -2;
+    for (var suggestion in suggestions) {
+      var index = _suggestions.indexOf(suggestion);
+      expect(index, isNonNegative, reason: '$suggestion');
+      expect(index, greaterThan(lastIndex), reason: '$suggestion');
+      lastIndex = index;
+    }
+  }
+
+  Future _compute2(String content) async {
+    var context = _updateFile(content);
+
+    _completionResult = await _newComputer().compute2(
+      path: convertPath(testPath),
+      line: context.line,
+      column: context.character,
+    );
+    _suggestions = _completionResult.suggestions;
+  }
+
+  /// TODO(scheglov) Implement incremental updating
+  void _createFileResolver() {
+    createFileResolver();
+  }
+
+  List<CompletionSuggestion> _matchingCompletions({
+    @required String text,
+    ElementKind elementKind,
+  }) {
+    return _suggestions.where((e) {
+      if (e.completion != text) {
+        return false;
+      }
+
+      if (elementKind != null && e.element.kind != elementKind) {
+        return false;
+      }
+
+      return true;
+    }).toList();
+  }
+
+  CiderCompletionComputer _newComputer() {
+    return _computer = CiderCompletionComputer(
+      logger,
+      _completionCache,
+      fileResolver,
+    );
+  }
+
+  _CompletionContext _updateFile(String content) {
+    var offset = content.indexOf('^');
+    expect(offset, isPositive, reason: 'Expected to find ^');
+    expect(content.indexOf('^', offset + 1), -1, reason: 'Expected only one ^');
+
+    var lineInfo = LineInfo.fromContent(content);
+    var location = lineInfo.getLocation(offset);
+
+    content = content.substring(0, offset) + content.substring(offset + 1);
+    newFile(testPath, content: content);
+
+    return _CompletionContext(
+      content,
+      offset,
+      location.lineNumber - 1,
+      location.columnNumber - 1,
+    );
+  }
+}
+
+class _CompletionContext {
+  final String content;
+  final int offset;
+  final int line;
+  final int character;
+
+  _CompletionContext(this.content, this.offset, this.line, this.character);
+}
diff --git a/pkg/analysis_server/test/src/cider/fixes_test.dart b/pkg/analysis_server/test/src/cider/fixes_test.dart
new file mode 100644
index 0000000..b9157d5
--- /dev/null
+++ b/pkg/analysis_server/test/src/cider/fixes_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'cider_service.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(CiderFixesComputerTest);
+  });
+}
+
+@reflectiveTest
+class CiderFixesComputerTest extends CiderServiceTest {
+  _CorrectionContext _correctionContext;
+  List<CiderErrorFixes> _errorsFixes;
+
+  void assertHasFix(FixKind kind, String expected) {
+    var fix = _getFix(kind);
+
+    var fileEdits = fix.change.edits;
+    expect(fileEdits, hasLength(1));
+
+    var resultContent = SourceEdit.applySequence(
+      _correctionContext.content,
+      fileEdits.single.edits,
+    );
+    expect(resultContent, expected);
+  }
+
+  Future<void> test_createMethod() async {
+    await _compute(r'''
+class A {
+}
+
+void f(A a) {
+  a.foo(0);^
+}
+''');
+
+    assertHasFix(DartFixKind.CREATE_METHOD, r'''
+class A {
+  void foo(int i) {}
+}
+
+void f(A a) {
+  a.foo(0);
+}
+''');
+  }
+
+  Future<void> test_insertSemicolon() async {
+    await _compute(r'''
+var v = 0^
+''');
+
+    assertHasFix(DartFixKind.INSERT_SEMICOLON, r'''
+var v = 0;
+''');
+  }
+
+  Future<void> _compute(String content) async {
+    _updateFile(content);
+
+    _errorsFixes = await CiderFixesComputer(
+      logger,
+      fileResolver,
+    ).compute(
+      convertPath(testPath),
+      _correctionContext.offset,
+    );
+  }
+
+  Fix _getFix(FixKind kind) {
+    for (var errorFixes in _errorsFixes) {
+      for (var fix in errorFixes.fixes) {
+        if (fix.kind == kind) {
+          return fix;
+        }
+      }
+    }
+    fail('No fix $kind');
+  }
+
+  void _updateFile(String content) {
+    var offset = content.indexOf('^');
+    expect(offset, isPositive, reason: 'Expected to find ^');
+    expect(content.indexOf('^', offset + 1), -1, reason: 'Expected only one ^');
+
+    var lineInfo = LineInfo.fromContent(content);
+    var location = lineInfo.getLocation(offset);
+
+    content = content.substring(0, offset) + content.substring(offset + 1);
+    newFile(testPath, content: content);
+
+    _correctionContext = _CorrectionContext(
+      content,
+      offset,
+      location.lineNumber - 1,
+      location.columnNumber - 1,
+    );
+  }
+}
+
+class _CorrectionContext {
+  final String content;
+  final int offset;
+  final int line;
+  final int character;
+
+  _CorrectionContext(this.content, this.offset, this.line, this.character);
+}
diff --git a/pkg/analysis_server/test/src/cider/test_all.dart b/pkg/analysis_server/test/src/cider/test_all.dart
new file mode 100644
index 0000000..9aea1f0
--- /dev/null
+++ b/pkg/analysis_server/test/src/cider/test_all.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_test.dart' as completion;
+import 'fixes_test.dart' as fixes;
+
+void main() {
+  defineReflectiveSuite(() {
+    completion.main();
+    fixes.main();
+  });
+}
diff --git a/pkg/analysis_server/test/src/edit/fix/dartfix_listener_test.dart b/pkg/analysis_server/test/src/edit/fix/dartfix_listener_test.dart
new file mode 100644
index 0000000..a904622
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/fix/dartfix_listener_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DartFixListenerTest);
+  });
+}
+
+@reflectiveTest
+class DartFixListenerTest {
+  DartFixListener listener;
+
+  void setUp() {
+    listener = DartFixListener(null);
+  }
+
+  void test_clear_clears_edits() {
+    listener.addSourceChange(
+        'Example',
+        null,
+        SourceChange('foo')
+          ..edits = [
+            SourceFileEdit('foo', 2, edits: [SourceEdit(0, 0, 'foo')])
+          ]);
+    expect(listener.sourceChange.edits, hasLength(1));
+    listener.reset();
+    expect(listener.sourceChange.edits, isEmpty);
+  }
+}
diff --git a/pkg/analysis_server/test/src/edit/fix/test_all.dart b/pkg/analysis_server/test/src/edit/fix/test_all.dart
index 3d33c83..d503cd9 100644
--- a/pkg/analysis_server/test/src/edit/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/edit/fix/test_all.dart
@@ -4,10 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'dartfix_listener_test.dart' as dartfix_listener;
 import 'non_nullable_fix_test.dart' as non_nullable_fix;
 
 void main() {
   defineReflectiveSuite(() {
+    dartfix_listener.main();
     non_nullable_fix.main();
   }, name: 'fix');
 }
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
deleted file mode 100644
index 59e080b..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ /dev/null
@@ -1,2070 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/source/line_info.dart';
-import 'package:meta/meta.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../../analysis_abstract.dart';
-import 'nnbd_migration_test_base.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(BuildEnclosingMemberDescriptionTest);
-    defineReflectiveTests(InfoBuilderTest);
-  });
-}
-
-@reflectiveTest
-class BuildEnclosingMemberDescriptionTest extends AbstractAnalysisTest {
-  Future<ResolvedUnitResult> resolveTestFile() async {
-    var includedRoot = resourceProvider.pathContext.dirname(testFile);
-    server.setAnalysisRoots('0', [includedRoot], [], {});
-    return await server
-        .getAnalysisDriver(testFile)
-        .currentSession
-        .getResolvedUnit(testFile);
-  }
-
-  Future<void> test_classConstructor_named() async {
-    addTestFile(r'''
-class C {
-  C.aaa();
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    var constructor = class_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(constructor),
-        equals("the constructor 'C.aaa'"));
-  }
-
-  Future<void> test_classConstructor_unnamed() async {
-    addTestFile(r'''
-class C {
-  C();
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    var constructor = class_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(constructor),
-        equals("the default constructor of 'C'"));
-  }
-
-  Future<void> test_classField() async {
-    addTestFile(r'''
-class C {
-  int i;
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    FieldDeclaration fieldDeclaration = class_.members.single;
-    var field = fieldDeclaration.fields.variables[0];
-    expect(InfoBuilder.buildEnclosingMemberDescription(field),
-        equals("the field 'C.i'"));
-  }
-
-  Future<void> test_classField_from_type() async {
-    addTestFile(r'''
-class C {
-  int i;
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    FieldDeclaration fieldDeclaration = class_.members.single;
-    var type = fieldDeclaration.fields.type;
-    expect(InfoBuilder.buildEnclosingMemberDescription(type),
-        equals("the field 'C.i'"));
-  }
-
-  Future<void> test_classGetter() async {
-    addTestFile(r'''
-class C {
-  int get aaa => 7;
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    var getter = class_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(getter),
-        equals("the getter 'C.aaa'"));
-  }
-
-  Future<void> test_classMethod() async {
-    addTestFile(r'''
-class C {
-  int aaa() => 7;
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    var method = class_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(method),
-        equals("the method 'C.aaa'"));
-  }
-
-  Future<void> test_classOperator() async {
-    addTestFile(r'''
-class C {
-  bool operator ==(Object other) => false;
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    var operator = class_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(operator),
-        equals("the operator 'C.=='"));
-  }
-
-  Future<void> test_classSetter() async {
-    addTestFile(r'''
-class C {
-  void set aaa(value) {}
-}
-''');
-    var result = await resolveTestFile();
-    ClassDeclaration class_ = result.unit.declarations.single;
-    var setter = class_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(setter),
-        equals("the setter 'C.aaa='"));
-  }
-
-  Future<void> test_extensionMethod() async {
-    addTestFile(r'''
-extension E on List {
-  int aaa() => 7;
-}
-''');
-    var result = await resolveTestFile();
-    ExtensionDeclaration extension_ = result.unit.declarations.single;
-    var method = extension_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(method),
-        equals("the method 'E.aaa'"));
-  }
-
-  Future<void> test_extensionMethod_unnamed() async {
-    addTestFile(r'''
-extension on List {
-  int aaa() => 7;
-}
-''');
-    var result = await resolveTestFile();
-    ExtensionDeclaration extension_ = result.unit.declarations.single;
-    var method = extension_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(method),
-        equals("the method 'aaa' in unnamed extension on List<dynamic>"));
-  }
-
-  Future<void> test_mixinMethod() async {
-    addTestFile(r'''
-mixin C {
-  int aaa() => 7;
-}
-''');
-    var result = await resolveTestFile();
-    MixinDeclaration mixin_ = result.unit.declarations.single;
-    var method = mixin_.members.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(method),
-        equals("the method 'C.aaa'"));
-  }
-
-  Future<void> test_topLevelFunction() async {
-    addTestFile(r'''
-void aaa(value) {}
-''');
-    var result = await resolveTestFile();
-    var function = result.unit.declarations.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(function),
-        equals("the function 'aaa'"));
-  }
-
-  Future<void> test_topLevelGetter() async {
-    addTestFile(r'''
-int get aaa => 7;
-''');
-    var result = await resolveTestFile();
-    var getter = result.unit.declarations.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(getter),
-        equals("the getter 'aaa'"));
-  }
-
-  Future<void> test_topLevelSetter() async {
-    addTestFile(r'''
-void set aaa(value) {}
-''');
-    var result = await resolveTestFile();
-    var setter = result.unit.declarations.single;
-    expect(InfoBuilder.buildEnclosingMemberDescription(setter),
-        equals("the setter 'aaa='"));
-  }
-
-  Future<void> test_topLevelVariable() async {
-    addTestFile(r'''
-int i;
-''');
-    var result = await resolveTestFile();
-    TopLevelVariableDeclaration topLevelVariableDeclaration =
-        result.unit.declarations.single;
-    var variable = topLevelVariableDeclaration.variables.variables[0];
-    expect(InfoBuilder.buildEnclosingMemberDescription(variable),
-        equals("the variable 'i'"));
-  }
-
-  Future<void> test_topLevelVariable_from_type() async {
-    addTestFile(r'''
-int i;
-''');
-    var result = await resolveTestFile();
-    TopLevelVariableDeclaration topLevelVariableDeclaration =
-        result.unit.declarations.single;
-    var type = topLevelVariableDeclaration.variables.type;
-    expect(InfoBuilder.buildEnclosingMemberDescription(type),
-        equals("the variable 'i'"));
-  }
-}
-
-@reflectiveTest
-class InfoBuilderTest extends NnbdMigrationTestBase {
-  /// Assert various properties of the given [detail].
-  void assertDetail({@required RegionDetail detail, int offset, int length}) {
-    if (offset != null) {
-      expect(detail.target.offset, offset);
-    }
-    if (length != null) {
-      expect(detail.target.length, length);
-    }
-  }
-
-  /// Assert various properties of the given [edit].
-  void assertEdit(
-      {@required EditDetail edit, int offset, int length, String replacement}) {
-    expect(edit, isNotNull);
-    if (offset != null) {
-      expect(edit.offset, offset);
-    }
-    if (length != null) {
-      expect(edit.length, length);
-    }
-    if (replacement != null) {
-      expect(edit.replacement, replacement);
-    }
-  }
-
-  /// Assert that some target in [targets] has various properties.
-  void assertInTargets(
-      {@required Iterable<NavigationTarget> targets, int offset, int length}) {
-    var failureReasons = [
-      if (offset != null) 'offset: $offset',
-      if (length != null) 'length: $length',
-    ].join(' and ');
-    expect(targets.any((t) {
-      return (offset == null || offset == t.offset) &&
-          (length == null || length == t.length);
-    }), isTrue, reason: 'Expected one of $targets to contain $failureReasons');
-  }
-
-  /// Assert various properties of the given [region]. If an [offset] is
-  /// provided but no [length] is provided, a default length of `1` will be
-  /// used.
-  void assertRegion(
-      {@required RegionInfo region,
-      int offset,
-      int length,
-      List<String> details}) {
-    if (offset != null) {
-      expect(region.offset, offset);
-      expect(region.length, length ?? 1);
-    }
-    if (details != null) {
-      expect(region.details.map((detail) => detail.description),
-          unorderedEquals(details));
-    }
-  }
-
-  void assertTraceEntry(UnitInfo unit, TraceEntryInfo entryInfo,
-      String function, int offset, Object descriptionMatcher) {
-    assert(offset >= 0);
-    var lineInfo = LineInfo.fromContent(unit.content);
-    var expectedLocation = lineInfo.getLocation(offset);
-    expect(entryInfo.target.filePath, unit.path);
-    expect(entryInfo.target.line, expectedLocation.lineNumber);
-    expect(entryInfo.target.offset, expectedLocation.columnNumber);
-    expect(entryInfo.function, function);
-    expect(entryInfo.description, descriptionMatcher);
-  }
-
-  Future<void> test_asExpression() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f([num a]) {
-  int b = a as int;
-}
-''', migratedContent: '''
-void f([num? a]) {
-  int? b = a as int?;
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(3));
-    // regions[0] is `num? a`.
-    assertRegion(
-        region: regions[1],
-        offset: 24,
-        details: ['This variable is initialized to a nullable value']);
-    assertRegion(
-        region: regions[2],
-        offset: 38,
-        details: ['The value of the expression is nullable']);
-  }
-
-  Future<void> test_asExpression_insideReturn() async {
-    var unit = await buildInfoForSingleTestFile('''
-int f([num a]) {
-  return a as int;
-}
-''', migratedContent: '''
-int? f([num? a]) {
-  return a as int?;
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(3));
-    // regions[0] is `inf? f`.
-    // regions[1] is `num? a`.
-    assertRegion(
-        region: regions[2],
-        offset: 36,
-        details: ['The value of the expression is nullable']);
-  }
-
-  Future<void> test_bound() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C<T extends Object> {}
-
-void f() {
-  C<int/*?*/> c = null;
-}
-''', migratedContent: '''
-class C<T extends Object?> {}
-
-void f() {
-  C<int?/*?*/>? c = null;
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(3));
-    assertRegion(
-        region: regions[0],
-        offset: 24,
-        details: ['This type parameter is instantiated with a nullable type']);
-  }
-
-  Future<void> test_bound_instantiation_explicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C<T extends Object> {}
-
-void main() {
-  C<int/*?*/>();
-}
-''', migratedContent: '''
-class C<T extends Object?> {}
-
-void main() {
-  C<int?/*?*/>();
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 24,
-        details: ['This type parameter is instantiated with a nullable type']);
-  }
-
-  Future<void> test_bound_instantiation_implicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C<T extends Object> {
-  C(T/*!*/ t);
-}
-
-void main() {
-  C(null);
-}
-''', migratedContent: '''
-class C<T extends Object?> {
-  C(T /*!*/ t);
-}
-
-void main() {
-  C(null);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(region: regions[0], offset: 24, details: [
-      'This type parameter is instantiated with an inferred nullable type'
-    ]);
-  }
-
-  Future<void> test_bound_method_explicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-f<T extends Object> {}
-
-void main() {
-  f<int/*?*/>();
-}
-''', migratedContent: '''
-f<T extends Object?> {}
-
-void main() {
-  f<int?/*?*/>();
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 18,
-        details: ['This type parameter is instantiated with a nullable type']);
-  }
-
-  Future<void> test_bound_method_implicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-f<T extends Object>(T/*!*/ t) {}
-
-void main() {
-  f(null);
-}
-''', migratedContent: '''
-f<T extends Object?>(T /*!*/ t) {}
-
-void main() {
-  f(null);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(region: regions[0], offset: 18, details: [
-      'This type parameter is instantiated with an inferred nullable type'
-    ]);
-  }
-
-  Future<void> test_discardCondition() async {
-    var unit = await buildInfoForSingleTestFile('''
-void g(int i) {
-  print(i.isEven);
-  if (i != null) print('NULL');
-}
-''', migratedContent: '''
-void g(int  i) {
-  print(i.isEven);
-  /* if (i != null) */ print('NULL');
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(region: regions[0], offset: 38, length: 3);
-    assertRegion(region: regions[1], offset: 56, length: 3);
-  }
-
-  Future<void> test_discardElse() async {
-    var unit = await buildInfoForSingleTestFile('''
-void g(int i) {
-  print(i.isEven);
-  if (i != null) print('NULL');
-  else print('NOT NULL');
-}
-''', migratedContent: '''
-void g(int  i) {
-  print(i.isEven);
-  /* if (i != null) */ print('NULL'); /*
-  else print('NOT NULL'); */
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(4));
-    assertRegion(region: regions[0], offset: 38, length: 3);
-    assertRegion(region: regions[1], offset: 56, length: 3);
-    assertRegion(region: regions[2], offset: 73, length: 3);
-    assertRegion(region: regions[3], offset: 102, length: 3);
-  }
-
-  Future<void> test_dynamicValueIsUsed() async {
-    var unit = await buildInfoForSingleTestFile('''
-bool f(int i) {
-  if (i == null) return true;
-  else return false;
-}
-void g() {
-  dynamic i = null;
-  f(i);
-}
-''', migratedContent: '''
-bool  f(int? i) {
-  if (i == null) return true;
-  else return false;
-}
-void g() {
-  dynamic i = null;
-  f(i);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    var region = regions[0];
-    var edits = region.edits;
-    assertRegion(region: region, offset: 11, details: [
-      'A dynamic value, which is nullable is passed as an argument'
-    ]);
-    assertDetail(detail: region.details[0], offset: 104, length: 1);
-    assertEdit(edit: edits[0], offset: 10, replacement: '/*!*/');
-    assertEdit(edit: edits[1], offset: 10, replacement: '/*?*/');
-  }
-
-  Future<void> test_exactNullable() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(List<int> list) {
-  list[0] = null;
-}
-
-void g() {
-  f(<int>[]);
-}
-''', migratedContent: '''
-void f(List<int?>  list) {
-  list[0] = null;
-}
-
-void g() {
-  f(<int?>[]);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(3));
-    assertRegion(region: regions[0], offset: 15, details: [
-      "An explicit 'null' is assigned in the function 'f'",
-    ]);
-    // regions[1] is the hard edge that f's parameter is non-nullable.
-    assertRegion(
-        region: regions[2],
-        offset: 67,
-        details: ['This is later required to accept null.']);
-  }
-
-  @FailingTest(issue: 'https://dartbug.com/40587')
-  Future<void> test_exactNullable_exactNullable() async {
-    var unit = await buildInfoForSingleTestFile('''
-void g(List<int> list1, List<int> list2) {
-  list1[0] = null;
-  list2[0] = list1[0];
-}
-''', migratedContent: '''
-void g(List<int?> list1, List<int?> list2) {
-  list1[0] = null;
-  list2[0] = list1[0];
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(4));
-    // regions[0] is the hard edge that list1 is unconditionally indexed
-    assertRegion(region: regions[1], offset: 15, details: [
-      "An explicit 'null' is assigned in the function 'g'",
-    ]);
-    // regions[2] is the hard edge that list2 is unconditionally indexed
-    assertRegion(
-        region: regions[3],
-        offset: 33,
-        details: ["A nullable value is assigned in the function 'g'"]);
-  }
-
-  Future<void> test_expressionFunctionReturnTarget() async {
-    var unit = await buildInfoForSingleTestFile('''
-String g() => 1 == 2 ? "Hello" : null;
-''', migratedContent: '''
-String? g() => 1 == 2 ? "Hello" : null;
-''');
-    assertInTargets(targets: unit.targets, offset: 7, length: 1); // "g"
-    assertInTargets(targets: unit.targets, offset: 11, length: 2); // "=>"
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 6,
-        details: ['This function returns a nullable value on line 1']);
-    assertDetail(detail: regions[0].details[0], offset: 11, length: 2);
-  }
-
-  Future<void> test_field_fieldFormalInitializer_optional() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int _f;
-  A([this._f]);
-}
-''', migratedContent: '''
-class A {
-  int? _f;
-  A([this._f]);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 15, details: [
-      'This field is initialized by an optional field formal parameter that '
-          "has an implicit default value of 'null'"
-    ]);
-  }
-
-  Future<void> test_field_fieldFormalInitializer_optional_defaultNull() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int _f;
-  A([this._f = null]);
-}
-''', migratedContent: '''
-class A {
-  int? _f;
-  A([this._f = null]);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 15, details: [
-      'This field is initialized by an optional field formal parameter that '
-          "has an explicit default value of 'null'"
-    ]);
-  }
-
-  Future<void> test_field_fieldFormalInitializer_required() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int _f;
-  A(this._f);
-}
-void g() {
-  A(null);
-}
-''', migratedContent: '''
-class A {
-  int? _f;
-  A(this._f);
-}
-void g() {
-  A(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    // TODO(brianwilkerson) It would be nice if the target for the region could
-    //  be the argument rather than the field formal parameter.
-    assertRegion(region: regions[0], offset: 15, details: [
-      'This field is initialized by a field formal parameter and a nullable '
-          'value is passed as an argument'
-    ]);
-  }
-
-  Future<void> test_field_initializer() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int _f = null;
-  int _f2 = _f;
-}
-''', migratedContent: '''
-class A {
-  int? _f = null;
-  int? _f2 = _f;
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 15,
-        details: ["This field is initialized to an explicit 'null'"]);
-    assertRegion(
-        region: regions[1],
-        offset: 33,
-        details: ['This field is initialized to a nullable value']);
-  }
-
-  Future<void> test_fieldLaterAssignedNullable() async {
-    var unit = await buildInfoForSingleTestFile('''
-class Foo {
-  int value = 7;
-  void bar() {
-    value = null;
-  }
-}
-''', migratedContent: '''
-class Foo {
-  int? value = 7;
-  void bar() {
-    value = null;
-  }
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    var region = regions.single;
-    assertRegion(region: region, offset: 17, details: [
-      "An explicit 'null' is assigned in the method 'Foo.bar'",
-    ]);
-
-    assertDetail(detail: region.details[0], offset: 56, length: 4);
-  }
-
-  Future<void> test_functionType_nullable_asArgument() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  f(void Function(int) cb1) {}
-  g(void Function(int) cb2) {
-    f(cb2);
-  }
-  h() => f(null);
-}
-''', migratedContent: '''
-class C {
-  f(void Function(int )? cb1) {}
-  g(void Function(int )  cb2) {
-    f(cb2);
-  }
-  h() => f(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 33,
-        details: ["An explicit 'null' is passed as an argument"]);
-    assertDetail(detail: regions[0].details[0], offset: 98, length: 4);
-  }
-
-  Future<void> test_functionType_nullableParameter_asArgument() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  f(void Function(int) cb1) {
-    cb1(null);
-  }
-  g(void Function(int) cb2) {
-    f(cb2);
-  }
-}
-''', migratedContent: '''
-class C {
-  f(void Function(int?)  cb1) {
-    cb1(null);
-  }
-  g(void Function(int?)  cb2) {
-    f(cb2);
-  }
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 31,
-        details: ["An explicit 'null' is passed as an argument"]);
-    assertRegion(region: regions[1], offset: 82, details: [
-      'The function-typed element in which this parameter is declared is '
-          'assigned to a function whose matching parameter is nullable'
-    ]);
-    assertDetail(detail: regions[1].details[0], offset: 95, length: 3);
-  }
-
-  Future<void> test_functionType_nullableParameter_assignment() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  void Function(int) _cb = (x) {};
-  f(void Function(int) cb) {
-    _cb = cb;
-  }
-  g() => _cb(null);
-}
-''', migratedContent: '''
-class C {
-  void Function(int?)  _cb = (x) {};
-  f(void Function(int?)  cb) {
-    _cb = cb;
-  }
-  g() => _cb(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is `void Function(int?) _cb`.
-    assertRegion(region: regions[1], offset: 68, details: [
-      'The function-typed element in which this parameter is declared is '
-          'assigned to a function whose matching parameter is nullable'
-    ]);
-    assertDetail(detail: regions[1].details[0], offset: 84, length: 2);
-  }
-
-  Future<void> test_functionType_nullableParameter_fieldInitializer() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  void Function(int) _cb;
-  C(void Function(int) cb): _cb = cb;
-  f() => _cb(null);
-}
-''', migratedContent: '''
-class C {
-  void Function(int?)  _cb;
-  C(void Function(int?)  cb): _cb = cb;
-  f() => _cb(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 29,
-        details: ["An explicit 'null' is passed as an argument"]);
-    assertRegion(region: regions[1], offset: 59, details: [
-      'The function-typed element in which this parameter is declared is '
-          'assigned to a function whose matching parameter is nullable'
-    ]);
-    assertDetail(detail: regions[1].details[0], offset: 70, length: 2);
-  }
-
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40034')
-  Future<void> test_functionType_nullableParameter_typedef() async {
-    var unit = await buildInfoForSingleTestFile('''
-typedef Cb = void Function(int);
-class C {
-  Cb _cb;
-  C(void Function(int) cb): _cb = cb;
-  f() => _cb(null);
-}
-''', migratedContent: '''
-typedef Cb = void Function(int?);
-class C {
-  Cb _cb;
-  C(void Function(int?) cb): _cb = cb;
-  f() => _cb(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is `typedef Cb = void Function(int?);`.
-    assertRegion(region: regions[1], offset: 75, details: [
-      'The function-typed element in which this parameter is declared is '
-          'assigned to a function whose matching parameter is nullable'
-    ]);
-    assertDetail(detail: regions[1].details[0], offset: 70, length: 2);
-  }
-
-  Future<void> test_functionType_nullableReturn() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int Function() _cb = () => 7;
-  f(int Function() cb) {
-    _cb = cb;
-  }
-  g() {
-    f(() => null);
-  }
-}
-''', migratedContent: '''
-class C {
-  int? Function()  _cb = () => 7;
-  f(int? Function()  cb) {
-    _cb = cb;
-  }
-  g() {
-    f(() => null);
-  }
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(region: regions[0], offset: 15, details: [
-      'A function-typed value with a nullable return type is assigned'
-    ]);
-    assertDetail(detail: regions[0].details[0], offset: 77, length: 2);
-  }
-
-  Future<void> test_insertedRequired_fieldFormal() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int level;
-  int level2;
-  C({this.level}) : this.level2 = level + 1;
-}
-''', migratedContent: '''
-class C {
-  int  level;
-  int  level2;
-  C({required this.level}) : this.level2 = level + 1;
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    var region = regions[0];
-    var edits = region.edits;
-    assertRegion(region: region, offset: 44, length: 9, details: [
-      'This parameter is non-nullable, so cannot have an implicit default '
-          "value of 'null'"
-    ]);
-    assertEdit(
-        edit: edits[0], offset: 42, length: 0, replacement: '@required ');
-  }
-
-  Future<void> test_insertedRequired_parameter() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int level = 0;
-  bool f({int lvl}) => lvl >= level;
-}
-''', migratedContent: '''
-class C {
-  int  level = 0;
-  bool  f({required int  lvl}) => lvl >= level;
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    var region = regions[0];
-    var edits = region.edits;
-    assertRegion(region: region, offset: 39, length: 9, details: [
-      'This parameter is non-nullable, so cannot have an implicit default '
-          "value of 'null'"
-    ]);
-    assertEdit(
-        edit: edits[0], offset: 37, length: 0, replacement: '@required ');
-  }
-
-  Future<void> test_insertParens() async {
-    var originalContent = '''
-class C {
-  C operator+(C c) => null;
-}
-C/*!*/ _f(C c) => c + c;
-''';
-    var migratedContent = '''
-class C {
-  C? operator+(C  c) => null;
-}
-C /*!*/ _f(C  c) => (c + c)!;
-''';
-    var unit = await buildInfoForSingleTestFile(originalContent,
-        migratedContent: migratedContent);
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: migratedContent.indexOf('? operator'),
-        length: 1,
-        details: ["This method returns an explicit 'null' on line 2"]);
-    assertRegion(
-        region: regions[1],
-        offset: migratedContent.indexOf('!;'),
-        length: 1,
-        details: ['This value must be null-checked before use here.']);
-  }
-
-  Future<void> test_listAndSetLiteralTypeArgument() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  String s = null;
-  var x = <String>["hello", s];
-  var y = <String>{"hello", s};
-}
-''', migratedContent: '''
-void f() {
-  String? s = null;
-  var x = <String?>["hello", s];
-  var y = <String?>{"hello", s};
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(3));
-    // regions[0] is the `String? s` fix.
-    assertRegion(
-        region: regions[1],
-        offset: 48,
-        details: ['This list is initialized with a nullable value on line 3']);
-    assertDetail(detail: regions[1].details[0], offset: 58, length: 1);
-    assertRegion(
-        region: regions[2],
-        offset: 81,
-        details: ['This set is initialized with a nullable value on line 4']);
-    assertDetail(detail: regions[2].details[0], offset: 90, length: 1);
-  }
-
-  Future<void> test_listConstructor_length() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  List<int> list = List<int>(10);
-}
-''', migratedContent: '''
-void f() {
-  List<int?>  list = List<int?>(10);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is `num? a`.
-    assertRegion(region: regions[1], offset: 40, details: [
-      'A length is specified in the "List()" constructor and the list items '
-          'are initialized to null'
-    ]);
-  }
-
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40064')
-  Future<void> test_listConstructor_length_implicitType() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  List<int> list = List(10);
-}
-''', migratedContent: '''
-void f() {
-  List<int?> list = List(10);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    // regions[0] is `num? a`.
-    assertRegion(region: regions[1], offset: 40, details: [
-      'List value type must be nullable because a length is specified,'
-          ' and the list items are initialized as null.'
-    ]);
-  }
-
-  Future<void> test_listLiteralTypeArgument_collectionIf() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  String s = null;
-  var x = <String>[
-    "hello",
-    if (1 == 2) s
-  ];
-}
-''', migratedContent: '''
-void f() {
-  String? s = null;
-  var x = <String?>[
-    "hello",
-    if (1 == 2) s
-  ];
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is the `String? s` fix.
-    assertRegion(
-        region: regions[1],
-        offset: 48,
-        details: ['This list is initialized with a nullable value on line 5']);
-    assertDetail(detail: regions[1].details[0], offset: 79, length: 1);
-  }
-
-  Future<void> test_localVariable() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  int v1 = null;
-  int v2 = v1;
-}
-''', migratedContent: '''
-void f() {
-  int? v1 = null;
-  int? v2 = v1;
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 16,
-        details: ["This variable is initialized to an explicit 'null'"]);
-    assertRegion(
-        region: regions[1],
-        offset: 34,
-        details: ['This variable is initialized to a nullable value']);
-  }
-
-  Future<void> test_mapLiteralTypeArgument() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  String s = null;
-  var x = <String, bool>{"hello": false, s: true};
-  var y = <bool, String>{false: "hello", true: s};
-}
-''', migratedContent: '''
-void f() {
-  String? s = null;
-  var x = <String?, bool >{"hello": false, s: true};
-  var y = <bool , String?>{false: "hello", true: s};
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(3));
-    // regions[0] is the `String? s` fix.
-    assertRegion(
-        region: regions[1],
-        offset: 48,
-        details: ['This map is initialized with a nullable value on line 3']);
-    assertDetail(detail: regions[1].details[0], offset: 71, length: 1);
-    assertRegion(
-        region: regions[2],
-        offset: 108,
-        details: ['This map is initialized with a nullable value on line 4']);
-    assertDetail(detail: regions[2].details[0], offset: 128, length: 1);
-  }
-
-  Future<void> test_namedParameterWithDefault_fromOverridden_explicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  void m({int p = 0}) {}
-}
-class B extends A {
-  void m({num p = 0}) {}
-}
-void f(A a) {
-  a.m(p: null);
-}
-''', migratedContent: '''
-class A {
-  void m({int? p = 0}) {}
-}
-class B extends A {
-  void m({num? p = 0}) {}
-}
-void f(A  a) {
-  a.m(p: null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is "an explicit null is passed..."
-    assertRegion(region: regions[1], offset: 71, details: [
-      'The corresponding parameter in the overridden method, A.m, is nullable'
-    ]);
-    assertDetail(detail: regions[1].details[0], offset: 20, length: 3);
-  }
-
-  Future<void> test_nonNullableType_assert() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(String s) {
-  assert(s != null);
-}
-''', migratedContent: '''
-void f(String  s) {
-  assert(s != null);
-}
-''');
-    var regions = unit.informativeRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 13, length: 1, details: []);
-  }
-
-  Future<void> test_nonNullableType_exclamationComment() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(String /*!*/ s) {}
-''', migratedContent: '''
-void f(String  /*!*/ s) {}
-''');
-    var regions = unit.informativeRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 13, length: 1, details: []);
-  }
-
-  Future<void> test_nonNullableType_unconditionalFieldAccess() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(String s) {
-  print(s.length);
-}
-''', migratedContent: '''
-void f(String  s) {
-  print(s.length);
-}
-''');
-    var regions = unit.informativeRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 13, length: 1, details: []);
-  }
-
-  Future<void> test_nullCheck_onMemberAccess() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int value;
-  C([this.value]);
-  void f() {
-    value.sign;
-  }
-}
-''', migratedContent: '''
-class C {
-  int? value;
-  C([this.value]);
-  void f() {
-    value!.sign;
-  }
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    // regions[0] is `int?`.
-    var region = regions[1];
-    var edits = region.edits;
-    assertRegion(region: regions[1], offset: 65, details: [
-      'This value must be null-checked before accessing its properties.'
-    ]);
-    assertEdit(edit: edits[0], offset: 64, length: 0, replacement: '/*!*/');
-  }
-
-  Future<void> test_nullCheck_onMethodCall() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int value;
-  C([this.value]);
-  void f() {
-    value.abs();
-  }
-}
-''', migratedContent: '''
-class C {
-  int? value;
-  C([this.value]);
-  void f() {
-    value!.abs();
-  }
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    // regions[0] is `int?`.
-    assertRegion(region: regions[1], offset: 65, details: [
-      'This value must be null-checked before calling its methods.'
-    ]);
-  }
-
-  Future<void> test_parameter_fromInvocation_explicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(String s) {}
-void g() {
-  f(null);
-}
-''', migratedContent: '''
-void f(String? s) {}
-void g() {
-  f(null);
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 13,
-        details: ["An explicit 'null' is passed as an argument"]);
-  }
-
-  Future<void> test_parameter_fromInvocation_implicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(String s) {}
-void g(p) {
-  f(p);
-}
-void h() => g(null);
-''', migratedContent: '''
-void f(String? s) {}
-void g(p) {
-  f(p);
-}
-void h() => g(null);
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 13, details: [
-      'A dynamic value, which is nullable is passed as an argument'
-    ]);
-  }
-
-  Future<void> test_parameter_fromMultipleOverridden_explicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  void m(int p) {}
-}
-class B extends A {
-  void m(num p) {}
-}
-class C extends B {
-  void m(Object p) {}
-}
-void f(A a) {
-  a.m(null);
-}
-''', migratedContent: '''
-class A {
-  void m(int? p) {}
-}
-class B extends A {
-  void m(num? p) {}
-}
-class C extends B {
-  void m(Object? p) {}
-}
-void f(A  a) {
-  a.m(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(3));
-    // regions[0] is "an explicit null is passed..."
-    assertRegion(region: regions[1], offset: 64, details: [
-      'The corresponding parameter in the overridden method, A.m, is nullable'
-    ]);
-    assertRegion(region: regions[2], offset: 109, details: [
-      'The corresponding parameter in the overridden method, B.m, is nullable'
-    ]);
-    assertDetail(detail: regions[1].details[0], offset: 19, length: 3);
-    assertDetail(detail: regions[2].details[0], offset: 60, length: 3);
-  }
-
-  Future<void> test_parameter_fromMultipleOverridden_implicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  void m(int p) {}
-}
-class B extends A {
-  void m(p) {}
-}
-class C extends B {
-  void m(Object p) {}
-}
-void f(A a) {
-  a.m(null);
-}
-''', migratedContent: '''
-class A {
-  void m(int? p) {}
-}
-class B extends A {
-  void m(p) {}
-}
-class C extends B {
-  void m(Object? p) {}
-}
-void f(A  a) {
-  a.m(null);
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is "an explicit null is passed..."
-    assertRegion(region: regions[1], offset: 104, details: [
-      'The corresponding parameter in the overridden method is nullable'
-    ]);
-  }
-
-  Future<void> test_parameter_fromOverridden_implicitDynamic() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  void m(p) {}
-}
-class B extends A {
-  void m(Object p) {}
-}
-''', migratedContent: '''
-class A {
-  void m(p) {}
-}
-class B extends A {
-  void m(Object  p) {}
-}
-''');
-    var regions = unit.informativeRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 62, details: []);
-  }
-
-  Future<void> test_parameter_fromOverriddenField_explicit() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int m;
-}
-class B extends A {
-  void set m(Object p) {}
-}
-void f(A a) => a.m = null;
-''', migratedContent: '''
-class A {
-  int? m;
-}
-class B extends A {
-  void set m(Object? p) {}
-}
-void f(A  a) => a.m = null;
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(region: regions[0], offset: 15, details: [
-      'This field is not initialized',
-      "An explicit 'null' is assigned in the function 'f'",
-    ]);
-    assertRegion(region: regions[1], offset: 61, details: [
-      // TODO(srawlins): Improve this message to include "B.m".
-      'The corresponding parameter in the overridden method is nullable'
-    ]);
-    assertDetail(detail: regions[0].details[1], offset: 90, length: 4);
-    assertDetail(detail: regions[1].details[0], offset: 12, length: 3);
-
-    expect(regions[0].traces, hasLength(1));
-    var trace = regions[0].traces.first;
-    expect(trace.description, 'Nullability reason');
-    var entries = trace.entries;
-    expect(entries, hasLength(2));
-    // Entry 0 is the nullability of the type of A.m.
-    // TODO(srawlins): "A" is probably incorrect here. Should be "A.m".
-    assertTraceEntry(unit, entries[0], 'A', unit.content.indexOf('int?'),
-        contains('explicit type'));
-  }
-
-  Future<void> test_parameter_named_omittedInCall() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() { g(); }
-
-void g({int i}) {}
-''', migratedContent: '''
-void f() { g(); }
-
-void g({int? i}) {}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 30, details: [
-      'This named parameter is omitted in a call to this function',
-      "This parameter has an implicit default value of 'null'",
-    ]);
-    assertDetail(detail: regions[0].details[0], offset: 11, length: 3);
-  }
-
-  Future<void> test_parameter_named_omittedInCall_inArgumentList() async {
-    var unit = await buildInfoForSingleTestFile('''
-int f({int compare}) => 7
-void g() {
-  h(f());
-}
-void h(int x) {}
-''', migratedContent: '''
-int  f({int? compare}) => 7
-void g() {
-  h(f());
-}
-void h(int  x) {}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 11, details: [
-      "This parameter has an implicit default value of 'null'",
-      'This named parameter is omitted in a call to this function'
-    ]);
-  }
-
-  Future<void> test_parameter_optional_explicitDefault_null() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f({String s = null}) {}
-''', migratedContent: '''
-void f({String? s = null}) {}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 14,
-        details: ["This parameter has an explicit default value of 'null'"]);
-  }
-
-  Future<void> test_parameter_optional_explicitDefault_nullable() async {
-    var unit = await buildInfoForSingleTestFile('''
-String sd = null;
-void f({String s = sd}) {}
-''', migratedContent: '''
-String? sd = null;
-void f({String? s = sd}) {}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[1],
-        offset: 33,
-        details: ['This parameter has a nullable default value']);
-  }
-
-  Future<void> test_parameter_optional_implicitDefault_named() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f({String s}) {}
-''', migratedContent: '''
-void f({String? s}) {}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 14,
-        details: ["This parameter has an implicit default value of 'null'"]);
-  }
-
-  Future<void> test_parameter_optional_implicitDefault_positional() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f([String s]) {}
-''', migratedContent: '''
-void f([String? s]) {}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 14,
-        details: ["This parameter has an implicit default value of 'null'"]);
-  }
-
-  Future<void> test_removal_handles_offsets_correctly() async {
-    var originalContent = '''
-void f(num n, int/*?*/ i) {
-  if (n is! int) return;
-  print((n as int).isEven);
-  print(i + 1);
-}
-''';
-    // Note: even though `as int` is removed, it still shows up in the
-    // preview, since we show deleted text.
-    var migratedContent = '''
-void f(num  n, int?/*?*/ i) {
-  if (n is! int ) return;
-  print((n as int).isEven);
-  print(i! + 1);
-}
-''';
-    var unit = await buildInfoForSingleTestFile(originalContent,
-        migratedContent: migratedContent, removeViaComments: false);
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(3));
-    // regions[0] is the addition of `?` to the type of `i`.
-    assertRegion(
-        region: regions[1],
-        offset: migratedContent.indexOf(' as int'),
-        length: ' as int'.length,
-        details: []);
-    assertRegion(
-        region: regions[2],
-        offset: migratedContent.indexOf('! + 1'),
-        details: ['This value must be null-checked before use here.']);
-  }
-
-  Future<void> test_return_fromOverriden() async {
-    var unit = await buildInfoForSingleTestFile('''
-abstract class A {
-  String m();
-}
-class B implements A {
-  String m() => 1 == 2 ? "Hello" : null;
-}
-''', migratedContent: '''
-abstract class A {
-  String? m();
-}
-class B implements A {
-  String? m() => 1 == 2 ? "Hello" : null;
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 27,
-        details: ['An overridding method has a nullable return value']);
-    assertDetail(detail: regions[0].details[0], offset: 60, length: 6);
-  }
-
-  Future<void> test_return_multipleReturns() async {
-    var unit = await buildInfoForSingleTestFile('''
-String g() {
-  int x = 1;
-  if (x == 2) return x == 3 ? "Hello" : null;
-  return "Hello";
-}
-''', migratedContent: '''
-String? g() {
-  int  x = 1;
-  if (x == 2) return x == 3 ? "Hello" : null;
-  return "Hello";
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 6,
-        details: ['This function returns a nullable value on line 3']);
-    assertInTargets(targets: unit.targets, offset: 40, length: 6); // "return"
-  }
-
-  Future<void> test_returnDetailTarget() async {
-    var unit = await buildInfoForSingleTestFile('''
-String g() {
-  return 1 == 2 ? "Hello" : null;
-}
-''', migratedContent: '''
-String? g() {
-  return 1 == 2 ? "Hello" : null;
-}
-''');
-    assertInTargets(targets: unit.targets, offset: 7, length: 1); // "g"
-    assertInTargets(targets: unit.targets, offset: 15, length: 6); // "return"
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    assertRegion(
-        region: regions[0],
-        offset: 6,
-        details: ['This function returns a nullable value on line 2']);
-    assertDetail(detail: regions[0].details[0], offset: 15, length: 6);
-  }
-
-  Future<void> test_returnNoValue() async {
-    var unit = await buildInfoForSingleTestFile('''
-int f() {
-  return;
-}
-''', migratedContent: '''
-int? f() {
-  return;
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    assertRegion(region: regions[0], offset: 3, details: [
-      'This function contains a return statement with no value on line 2,'
-          ' which implicitly returns null.'
-    ]);
-  }
-
-  Future<void> test_returnType_function_expression() async {
-    var unit = await buildInfoForSingleTestFile('''
-int _f = null;
-int f() => _f;
-''', migratedContent: '''
-int? _f = null;
-int? f() => _f;
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 3,
-        details: ["This variable is initialized to an explicit 'null'"]);
-    assertRegion(
-        region: regions[1],
-        offset: 19,
-        details: ['This function returns a nullable value on line 2']);
-  }
-
-  Future<void> test_returnType_getter_block() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int _f = null;
-  int get f {
-    return _f;
-  }
-}
-''', migratedContent: '''
-class A {
-  int? _f = null;
-  int? get f {
-    return _f;
-  }
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 15,
-        details: ["This field is initialized to an explicit 'null'"]);
-    assertRegion(
-        region: regions[1],
-        offset: 33,
-        details: ['This getter returns a nullable value on line 4']);
-  }
-
-  Future<void> test_returnType_getter_expression() async {
-    var unit = await buildInfoForSingleTestFile('''
-class A {
-  int _f = null;
-  int get f => _f;
-}
-''', migratedContent: '''
-class A {
-  int? _f = null;
-  int? get f => _f;
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 15,
-        details: ["This field is initialized to an explicit 'null'"]);
-    assertRegion(
-        region: regions[1],
-        offset: 33,
-        details: ['This getter returns a nullable value on line 3']);
-  }
-
-  Future<void> test_setLiteralTypeArgument_nestedList() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  String s = null;
-  var x = <List<String>>{
-    ["hello"],
-    if (1 == 2) [s]
-  };
-}
-''', migratedContent: '''
-void f() {
-  String? s = null;
-  var x = <List<String?> >{
-    ["hello"],
-    if (1 == 2) [s]
-  };
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    // regions[0] is the `String? s` fix.
-    assertRegion(
-        region: regions[1],
-        offset: 53,
-        details: ['This set is initialized with a nullable value on line 5']);
-    // TODO(srawlins): Actually, this is marking the `[s]`, but I think only
-    //  `s` should be marked. Minor bug for now.
-    assertDetail(detail: regions[1].details[0], offset: 87, length: 3);
-  }
-
-  Future<void> test_topLevelVariable() async {
-    var unit = await buildInfoForSingleTestFile('''
-int _f = null;
-int _f2 = _f;
-''', migratedContent: '''
-int? _f = null;
-int? _f2 = _f;
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 3,
-        details: ["This variable is initialized to an explicit 'null'"]);
-    assertRegion(
-        region: regions[1],
-        offset: 19,
-        details: ['This variable is initialized to a nullable value']);
-  }
-
-  Future<void> test_trace_deadCode() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(int/*!*/ i) {
-  if (i == null) return;
-}
-''', migratedContent: '''
-void f(int /*!*/ i) {
-  /* if (i == null) return; */
-}
-''');
-    var region = unit.regions
-        .where(
-            (regionInfo) => regionInfo.offset == unit.content.indexOf('/* if'))
-        .single;
-    expect(region.traces, hasLength(1));
-    var trace = region.traces.single;
-    expect(trace.description, 'Non-nullability reason');
-    var entries = trace.entries;
-    expect(entries, hasLength(3));
-    // Entry 0 is the nullability of f's argument
-    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int'),
-        contains('parameter 0 of f'));
-    // Entry 1 is the edge from f's argument to never, due to the `/*!*/` hint.
-    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int'),
-        'explicitly hinted to be non-nullable');
-    // Entry 2 is the "never" node.
-    // TODO(paulberry): this node provides no additional useful information and
-    // shouldn't be included in the trace.
-    expect(entries[2].description, 'never');
-    expect(entries[2].function, null);
-    expect(entries[2].target, null);
-  }
-
-  Future<void> test_trace_nullableType() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(int i) {} // f
-void g(int i) { // g
-  f(i);
-}
-void h() {
-  g(null);
-}
-''', migratedContent: '''
-void f(int? i) {} // f
-void g(int? i) { // g
-  f(i);
-}
-void h() {
-  g(null);
-}
-''');
-    var region = unit.regions
-        .where((regionInfo) =>
-            regionInfo.offset == unit.content.indexOf('? i) {} // f'))
-        .single;
-    expect(region.traces, hasLength(1));
-    var trace = region.traces.single;
-    expect(trace.description, 'Nullability reason');
-    var entries = trace.entries;
-    expect(entries, hasLength(6));
-    // Entry 0 is the nullability of f's argument
-    assertTraceEntry(unit, entries[0], 'f',
-        unit.content.indexOf('int? i) {} // f'), contains('parameter 0 of f'));
-    // Entry 1 is the edge from g's argument to f's argument, due to g's call to
-    // f.
-    assertTraceEntry(
-        unit, entries[1], 'g', unit.content.indexOf('i);'), 'data flow');
-    // Entry 2 is the nullability of g's argument
-    assertTraceEntry(unit, entries[2], 'g',
-        unit.content.indexOf('int? i) { // g'), contains('parameter 0 of g'));
-    // Entry 3 is the edge from null to g's argument, due to h's call to g.
-    assertTraceEntry(
-        unit, entries[3], 'h', unit.content.indexOf('null'), 'data flow');
-    // Entry 4 is the nullability of the null literal.
-    assertTraceEntry(unit, entries[4], 'h', unit.content.indexOf('null'),
-        contains('null literal'));
-    // Entry 5 is the edge from always to null.
-    // TODO(paulberry): this edge provides no additional useful information and
-    // shouldn't be included in the trace.
-    assertTraceEntry(unit, entries[5], 'h', unit.content.indexOf('null'),
-        'literal expression');
-  }
-
-  Future<void> test_trace_nullCheck() async {
-    var unit = await buildInfoForSingleTestFile('int f(int/*?*/ i) => i + 1;',
-        migratedContent: 'int  f(int?/*?*/ i) => i! + 1;');
-    var region = unit.regions
-        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('! +'))
-        .single;
-    expect(region.traces, hasLength(1));
-    var trace = region.traces.single;
-    expect(trace.description, 'Nullability reason');
-    var entries = trace.entries;
-    expect(entries, hasLength(2));
-    // Entry 0 is the nullability of the type of i.
-    // TODO(paulberry): -1 is a bug.
-    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int?') - 1,
-        contains('parameter 0 of f'));
-    // Entry 1 is the edge from always to the type of i.
-    // TODO(paulberry): this edge provides no additional useful information and
-    // shouldn't be included in the trace.
-    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int?') - 1,
-        'explicitly hinted to be nullable');
-  }
-
-  Future<void> test_trace_nullCheck_notNullableReason() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f(int i) { // f
-  assert(i != null);
-}
-void g(int i) { // g
-  f(i); // call f
-}
-void h(int/*?*/ i) {
-  g(i);
-}
-''', migratedContent: '''
-void f(int  i) { // f
-  assert(i != null);
-}
-void g(int  i) { // g
-  f(i); // call f
-}
-void h(int?/*?*/ i) {
-  g(i!);
-}
-''');
-    var region = unit.regions
-        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('!)'))
-        .single;
-    expect(region.traces, hasLength(2));
-    // Trace 0 is the nullability reason; we don't care about that right now.
-    // Trace 1 is the non-nullability reason.
-    var trace = region.traces[1];
-    expect(trace.description, 'Non-nullability reason');
-    var entries = trace.entries;
-    expect(entries, hasLength(5));
-    // Entry 0 is the nullability of g's argument
-    assertTraceEntry(unit, entries[0], 'g',
-        unit.content.indexOf('int  i) { // g'), contains('parameter 0 of g'));
-    // Entry 1 is the edge from g's argument to f's argument, due to g's call to
-    // f.
-    assertTraceEntry(unit, entries[1], 'g',
-        unit.content.indexOf('i); // call f'), 'data flow');
-    // Entry 2 is the nullability of f's argument
-    assertTraceEntry(unit, entries[2], 'f',
-        unit.content.indexOf('int  i) { // f'), contains('parameter 0 of f'));
-    // Entry 3 is the edge f's argument to never, due to the assert.
-    assertTraceEntry(unit, entries[3], 'f', unit.content.indexOf('assert'),
-        'value asserted to be non-null');
-    // Entry 4 is the "never" node.
-    // TODO(paulberry): this node provides no additional useful information and
-    // shouldn't be included in the trace.
-    expect(entries[4].description, 'never');
-    expect(entries[4].function, null);
-    expect(entries[4].target, null);
-  }
-
-  Future<void> test_trace_nullCheckHint() async {
-    UnitInfo unit = await buildInfoForSingleTestFile(
-        'int f(int/*?*/ i) => i/*!*/;',
-        migratedContent: 'int  f(int?/*?*/ i) => i!/*!*/;');
-    var region = unit.regions
-        .where(
-            (regionInfo) => regionInfo.offset == unit.content.indexOf('!/*!*/'))
-        .single;
-    expect(region.traces, hasLength(1));
-    var trace = region.traces.single;
-    expect(trace.description, 'Reason');
-    expect(trace.entries, hasLength(1));
-    // TODO(paulberry): -2 is a bug.
-    assertTraceEntry(unit, trace.entries.single, 'f',
-        unit.content.indexOf('i!/*!*/') - 2, 'Null check hint');
-  }
-
-  Future<void> test_trace_substitutionNode() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C<T extends Object/*!*/> {}
-
-C<int /*?*/ > c;
-
-Map<int, String> x = {};
-String/*!*/ y = x[0];
-''', migratedContent: '''
-class C<T extends Object /*!*/> {}
-
-C<int? /*?*/ >? c;
-
-Map<int , String >  x = {};
-String /*!*/ y = x[0]!;
-''');
-    var region = unit.regions
-        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('!;'))
-        .single;
-    // The "why nullable" node associated with adding the `!` is a substitution
-    // node, and we don't currently generate a trace for a substitution node.
-    // TODO(paulberry): fix this.
-    // We do, however, generate a trace for "why not nullable".
-    expect(region.traces, hasLength(1));
-    expect(region.traces[0].description, 'Non-nullability reason');
-  }
-
-  Future<void> test_type_not_made_nullable() async {
-    var unit = await buildInfoForSingleTestFile('int i = 0;',
-        migratedContent: 'int  i = 0;');
-    var region = unit.regions
-        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('  i'))
-        .single;
-    expect(region.length, 1);
-    expect(region.lineNumber, 1);
-    expect(region.explanation, "Type 'int' was not made nullable");
-    expect(region.details, isEmpty);
-    expect(region.edits.map((edit) => edit.description).toSet(),
-        {'Force type to be non-nullable.', 'Force type to be nullable.'});
-    expect(region.traces, isEmpty);
-  }
-
-  Future<void> test_uninitializedField() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int value;
-  C();
-  C.one() {
-    this.value = 7;
-  }
-  C.two() {}
-}
-''', migratedContent: '''
-class C {
-  int? value;
-  C();
-  C.one() {
-    this.value = 7;
-  }
-  C.two() {}
-}
-''');
-    var regions = unit.regions;
-    expect(regions, hasLength(1));
-    var region = regions.single;
-    assertRegion(region: region, offset: 15, details: [
-      "The constructor 'C' does not initialize this field in its initializer "
-          'list',
-      "The constructor 'C.one' does not initialize this field in its "
-          'initializer list',
-      "The constructor 'C.two' does not initialize this field in its "
-          'initializer list',
-    ]);
-
-    assertDetail(detail: region.details[0], offset: 25, length: 1);
-    assertDetail(detail: region.details[1], offset: 34, length: 3);
-    assertDetail(detail: region.details[2], offset: 70, length: 3);
-  }
-
-  Future<void> test_uninitializedMember() async {
-    var unit = await buildInfoForSingleTestFile('''
-class C {
-  int level;
-}
-''', migratedContent: '''
-class C {
-  int? level;
-}
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(1));
-    expect(regions[0].details, isNotEmpty);
-    assertRegion(
-        region: regions[0],
-        offset: 15,
-        length: 1,
-        details: ['This field is not initialized']);
-  }
-
-  Future<void> test_uninitializedVariable_notLate_uninitializedUse() async {
-    var unit = await buildInfoForSingleTestFile('''
-void f() {
-  int v1;
-  if (1 == 2) v1 = 7;
-  g(v1);
-}
-void g(int i) => print(i.isEven);
-''', migratedContent: '''
-void f() {
-  int? v1;
-  if (1 == 2) v1 = 7;
-  g(v1!);
-}
-void g(int  i) => print(i.isEven);
-''');
-    var regions = unit.fixRegions;
-    expect(regions, hasLength(2));
-    assertRegion(
-        region: regions[0],
-        offset: 16,
-        details: ['Used on line 4, when it is possibly uninitialized']);
-    // regions[1] is the `v1!` fix.
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
deleted file mode 100644
index a680df94..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'nnbd_migration_test_base.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(InstrumentationRendererTest);
-  });
-}
-
-@reflectiveTest
-class InstrumentationRendererTest extends NnbdMigrationTestBase {
-  /// Render the instrumentation view for [files].
-  Future<String> renderViewForTestFiles(Map<String, String> files,
-      {bool applied = false}) async {
-    var packageRoot = convertPath('/project');
-    await buildInfoForTestFiles(files, includedRoot: packageRoot);
-    var migrationInfo =
-        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
-    var instrumentationRenderer = InstrumentationRenderer(
-        migrationInfo, PathMapper(resourceProvider), applied);
-    return instrumentationRenderer.render();
-  }
-
-  Future<void> test_appliedStyle() async {
-    var renderedView = await renderViewForTestFiles(
-        {convertPath('/project/lib/a.dart'): 'int a = null;'},
-        applied: true);
-    expect(renderedView, contains('<body class="applied">'));
-  }
-
-  Future<void> test_navigation_containsRoot() async {
-    var renderedView = await renderViewForTestFiles(
-        {convertPath('/project/lib/a.dart'): 'int a = null;'});
-    var expectedPath = convertPath('/project');
-    expect(renderedView, contains('<p class="root">$expectedPath</p>'));
-  }
-
-  Future<void> test_notAppliedStyle() async {
-    var renderedView = await renderViewForTestFiles(
-        {convertPath('/project/lib/a.dart'): 'int a = null;'},
-        applied: false);
-    expect(renderedView, contains('<body class="proposed">'));
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/navigation_tree_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/navigation_tree_renderer_test.dart
deleted file mode 100644
index 6a8451f..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/navigation_tree_renderer_test.dart
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/navigation_tree_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'nnbd_migration_test_base.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(NavigationTreeRendererTest);
-  });
-}
-
-const isNavigationTreeNode = TypeMatcher<NavigationTreeNode>();
-
-@reflectiveTest
-class NavigationTreeRendererTest extends NnbdMigrationTestBase {
-  /// Render the navigation tree view for [files].
-  Future<List<NavigationTreeNode>> renderNavigationTree(
-      Map<String, String> files) async {
-    var packageRoot = convertPath('/project');
-    await buildInfoForTestFiles(files, includedRoot: packageRoot);
-    var migrationInfo =
-        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
-    return NavigationTreeRenderer(migrationInfo, PathMapper(resourceProvider))
-        .render();
-  }
-
-  Future<void> test_containsEditCounts() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/lib/a.dart'): 'int a = 1;',
-      convertPath('/project/lib/b.dart'): 'int b = null;',
-      convertPath('/project/lib/c.dart'): 'int c = null;\nint d = null;',
-    });
-
-    var libNode = response[0];
-    expect(
-        libNode,
-        isNavigationTreeNode.havingSubtree([
-          isNavigationTreeNode.havingEditCount(0),
-          isNavigationTreeNode.havingEditCount(1),
-          isNavigationTreeNode.havingEditCount(2)
-        ]));
-  }
-
-  Future<void> test_containsHrefs() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/lib/a.dart'): 'int a = null;',
-      convertPath('/project/lib/src/b.dart'): 'int b = null;',
-      convertPath('/project/tool.dart'): 'int c = null;',
-    });
-
-    var libNode = response[0];
-    expect(
-        libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode.named('src').havingSubtree(
-              [isNavigationTreeNode.havingHref('/project/lib/src/b.dart')]),
-          isNavigationTreeNode.havingHref('/project/lib/a.dart')
-        ]));
-
-    var toolNode = response[1];
-    expect(toolNode.href, '/project/tool.dart');
-  }
-
-  Future<void> test_containsMultipleLinks_multipleDepths() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/lib/a.dart'): 'int a = null;',
-      convertPath('/project/lib/src/b.dart'): 'int b = null;',
-      convertPath('/project/tool.dart'): 'int c = null;',
-    });
-    expect(response, hasLength(2));
-
-    var libNode = response[0];
-    expect(
-        libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode
-              .named('src')
-              .havingSubtree([isNavigationTreeNode.named('b.dart')]),
-          isNavigationTreeNode.named('a.dart')
-        ]));
-
-    var toolNode = response[1];
-    expect(toolNode.name, 'tool.dart');
-  }
-
-  Future<void> test_containsMultipleLinks_multipleRoots() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/bin/bin.dart'): 'int c = null;',
-      convertPath('/project/lib/a.dart'): 'int a = null;',
-    });
-    expect(response, hasLength(2));
-
-    var binNode = response[0];
-    expect(binNode.type, equals(NavigationTreeNodeType.directory));
-    expect(binNode.name, equals('bin'));
-    expect(binNode.subtree, hasLength(1));
-
-    var libNode = response[1];
-    expect(libNode.type, equals(NavigationTreeNodeType.directory));
-    expect(libNode.name, equals('lib'));
-    expect(libNode.subtree, hasLength(1));
-  }
-
-  Future<void> test_containsMultipleLinks_sameDepth() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/lib/a.dart'): 'int a = null;',
-      convertPath('/project/lib/b.dart'): 'int b = null;',
-    });
-    expect(response, hasLength(1));
-
-    var libNode = response[0];
-    expect(
-        libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode
-              .named('a.dart')
-              .havingPath(convertPath('lib/a.dart'))
-              .havingHref('/project/lib/a.dart'),
-          isNavigationTreeNode
-              .named('b.dart')
-              .havingPath(convertPath('lib/b.dart'))
-              .havingHref('/project/lib/b.dart')
-        ]));
-  }
-
-  Future<void> test_containsPaths() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/lib/a.dart'): 'int a = null;',
-      convertPath('/project/lib/src/b.dart'): 'int b = null;',
-      convertPath('/project/tool.dart'): 'int c = null;',
-    });
-
-    var libNode = response[0];
-    expect(
-        libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode.named('src').havingSubtree(
-              [isNavigationTreeNode.havingPath(convertPath('lib/src/b.dart'))]),
-          isNavigationTreeNode.havingPath(convertPath('lib/a.dart'))
-        ]));
-
-    var toolNode = response[1];
-    expect(toolNode.path, 'tool.dart');
-  }
-
-  Future<void> test_containsSingleLink_deep() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/lib/src/a.dart'): 'int a = null;',
-    });
-    expect(response, hasLength(1));
-
-    var libNode = response[0];
-    expect(
-        libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode.named('src').havingSubtree([
-            isNavigationTreeNode
-                .named('a.dart')
-                .havingPath(convertPath('lib/src/a.dart'))
-                .havingHref('/project/lib/src/a.dart')
-          ])
-        ]));
-  }
-
-  Future<void> test_containsSingleLink_shallow() async {
-    var response = await renderNavigationTree({
-      convertPath('/project/a.dart'): 'int a = null;',
-    });
-    expect(response, hasLength(1));
-
-    var aNode = response[0];
-    expect(aNode.name, 'a.dart');
-    expect(aNode.path, 'a.dart');
-    expect(aNode.href, '/project/a.dart');
-  }
-}
-
-extension on TypeMatcher<NavigationTreeNode> {
-  TypeMatcher<NavigationTreeNode> havingSubtree(dynamic matcher) =>
-      having((node) => node.subtree, 'subtree', matcher);
-
-  TypeMatcher<NavigationTreeNode> havingEditCount(dynamic matcher) =>
-      having((node) => node.editCount, 'editCount', matcher);
-
-  TypeMatcher<NavigationTreeNode> named(dynamic matcher) =>
-      having((node) => node.name, 'name', matcher);
-
-  TypeMatcher<NavigationTreeNode> havingHref(dynamic matcher) =>
-      having((node) => node.href, 'href', matcher);
-
-  TypeMatcher<NavigationTreeNode> havingPath(dynamic matcher) =>
-      having((node) => node.path, 'path', matcher);
-}
-
-extension _E<T, U> on TypeMatcher<Map<T, U>> {
-  TypeMatcher<Map<T, U>> containing(Map<T, dynamic> matchers) {
-    var result = this;
-    for (var entry in matchers.entries) {
-      result = result.having(
-          (map) => map[entry.key], entry.key.toString(), entry.value);
-    }
-    return result;
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
deleted file mode 100644
index e5bd693..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:meta/meta.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../../analysis_abstract.dart';
-
-@reflectiveTest
-class NnbdMigrationTestBase extends AbstractAnalysisTest {
-  /// The information produced by the InfoBuilder, or `null` if [buildInfo] has
-  /// not yet completed.
-  Set<UnitInfo> infos;
-
-  /// Uses the InfoBuilder to build information for [testFile].
-  ///
-  /// The information is stored in [infos].
-  Future<void> buildInfo({bool removeViaComments = true}) async {
-    var includedRoot = resourceProvider.pathContext.dirname(testFile);
-    await _buildMigrationInfo([testFile],
-        includedRoot: includedRoot, removeViaComments: removeViaComments);
-  }
-
-  /// Uses the InfoBuilder to build information for a single test file.
-  ///
-  /// Asserts that [originalContent] is migrated to [migratedContent]. Returns
-  /// the singular UnitInfo which was built.
-  Future<UnitInfo> buildInfoForSingleTestFile(String originalContent,
-      {@required String migratedContent, bool removeViaComments = true}) async {
-    addTestFile(originalContent);
-    await buildInfo(removeViaComments: removeViaComments);
-    // Ignore info for dart:core.
-    var filteredInfos = [
-      for (var info in infos) if (!info.path.contains('core.dart')) info
-    ];
-    expect(filteredInfos, hasLength(1));
-    var unit = filteredInfos[0];
-    expect(unit.path, testFile);
-    expect(unit.content, migratedContent);
-    return unit;
-  }
-
-  /// Uses the InfoBuilder to build information for test files.
-  ///
-  /// Returns
-  /// the singular UnitInfo which was built.
-  Future<List<UnitInfo>> buildInfoForTestFiles(Map<String, String> files,
-      {String includedRoot}) async {
-    var testPaths = <String>[];
-    files.forEach((String path, String content) {
-      newFile(path, content: content);
-      testPaths.add(path);
-    });
-    await _buildMigrationInfo(testPaths, includedRoot: includedRoot);
-    // Ignore info for dart:core.
-    var filteredInfos = [
-      for (var info in infos) if (!info.path.contains('core.dart')) info
-    ];
-    return filteredInfos;
-  }
-
-  /// Uses the InfoBuilder to build information for files at [testPaths], which
-  /// should all share a common parent directory, [includedRoot].
-  Future<void> _buildMigrationInfo(List<String> testPaths,
-      {String includedRoot, bool removeViaComments = true}) async {
-    // Compute the analysis results.
-    server.setAnalysisRoots('0', [includedRoot], [], {});
-    // Run the migration engine.
-    var listener = DartFixListener(server);
-    var instrumentationListener = InstrumentationListener();
-    var adapter = NullabilityMigrationAdapter(listener);
-    var migration = NullabilityMigration(adapter,
-        permissive: false,
-        instrumentation: instrumentationListener,
-        removeViaComments: removeViaComments);
-    Future<void> _forEachPath(
-        void Function(ResolvedUnitResult) callback) async {
-      for (var testPath in testPaths) {
-        var result = await server
-            .getAnalysisDriver(testPath)
-            .currentSession
-            .getResolvedUnit(testPath);
-        callback(result);
-      }
-    }
-
-    await _forEachPath(migration.prepareInput);
-    await _forEachPath(migration.processInput);
-    await _forEachPath(migration.finalizeInput);
-    migration.finish();
-    // Build the migration info.
-    var info = instrumentationListener.data;
-    var builder = InfoBuilder(
-        resourceProvider, includedRoot, info, listener, adapter, migration);
-    infos = await builder.explainMigration();
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart
deleted file mode 100644
index 87597b3..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../../analysis_abstract.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(OffsetMapperTest);
-  });
-}
-
-@reflectiveTest
-class OffsetMapperTest extends AbstractAnalysisTest {
-  void test_identity() {
-    var mapper = OffsetMapper.identity;
-    expect(mapper.map(0), 0);
-    expect(mapper.map(20), 20);
-    expect(mapper.map(0xFFFFFF), 0xFFFFFF);
-  }
-
-  void test_multipleEdits() {
-    var mapper = OffsetMapper.forEdits([
-      SourceEdit(13, 0, '?'),
-      SourceEdit(21, 0, '!'),
-      SourceEdit(32, 0, '?'),
-    ]);
-    expect(mapper.map(0), 0);
-    expect(mapper.map(13), 13);
-    expect(mapper.map(14), 15);
-    expect(mapper.map(21), 22);
-    expect(mapper.map(22), 24);
-    expect(mapper.map(32), 34);
-    expect(mapper.map(33), 36);
-    expect(mapper.map(55), 58);
-  }
-
-  void test_singleEdit() {
-    var mapper = OffsetMapper.forEdits([
-      SourceEdit(13, 0, '?'),
-    ]);
-    expect(mapper.map(0), 0);
-    expect(mapper.map(13), 13);
-    expect(mapper.map(14), 15);
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
deleted file mode 100644
index e6380b1..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/region_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/edit_details.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'nnbd_migration_test_base.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(RegionRendererTest);
-  });
-}
-
-@reflectiveTest
-class RegionRendererTest extends NnbdMigrationTestBase {
-  /// Render the region at [offset], using a [MigrationInfo] which knows only
-  /// about the library at `infos.single`.
-  EditDetails renderRegion(int offset) {
-    var packageRoot = convertPath('/package');
-    var migrationInfo =
-        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
-    var unitInfo = infos.single;
-    var region = unitInfo.regionAt(offset);
-    return RegionRenderer(
-            region, unitInfo, migrationInfo, PathMapper(resourceProvider))
-        .render();
-  }
-
-  Future<void> test_modifiedOutput_containsDetail() async {
-    await buildInfoForSingleTestFile('int a = null;',
-        migratedContent: 'int? a = null;');
-    var response = renderRegion(3);
-    expect(response.details, hasLength(1));
-    var detail = response.details.single;
-    expect(detail.description,
-        equals("This variable is initialized to an explicit 'null'"));
-    expect(detail.link.path, equals('test.dart'));
-    expect(detail.link.href, equals('test.dart?offset=8&line=1'));
-  }
-
-  Future<void> test_modifiedOutput_containsExplanation() async {
-    await buildInfoForSingleTestFile('int a = null;',
-        migratedContent: 'int? a = null;');
-    var response = renderRegion(3);
-    expect(response.explanation, equals("Changed type 'int' to be nullable"));
-  }
-
-  Future<void> test_modifiedOutput_containsPath() async {
-    await buildInfoForSingleTestFile('int a = null;',
-        migratedContent: 'int? a = null;');
-    var response = renderRegion(3);
-    expect(response.path, equals(convertPath('/project/bin/test.dart')));
-    expect(response.line, equals(1));
-  }
-
-  @FailingTest(reason: "Unmodified output reason doesn't contain detail")
-  Future<void> test_unmodifiedOutput_containsDetail() async {
-    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
-        migratedContent: 'f(int  a) => a.isEven;');
-    var response = renderRegion(5);
-    expect(response.details, isNotEmpty);
-    // TODO(paulberry): fix and re-enable.
-//    expect(response.details, hasLength(1));
-//    var detail = response.details.single;
-//    expect(
-//        detail.description,
-//        equals('This value is unconditionally used in a '
-//            'non-nullable context'));
-//    expect(detail.link.path, equals('test.dart'));
-//    expect(detail.link.href, equals('test.dart?offset=12&line=1'));
-  }
-
-  Future<void> test_unmodifiedOutput_containsExplanation() async {
-    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
-        migratedContent: 'f(int  a) => a.isEven;');
-    var response = renderRegion(5);
-    expect(response.explanation, equals("Type 'int' was not made nullable"));
-  }
-
-  Future<void> test_unmodifiedOutput_containsPath() async {
-    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
-        migratedContent: 'f(int  a) => a.isEven;');
-    var response = renderRegion(5);
-    expect(response.path, equals(convertPath('/project/bin/test.dart')));
-    expect(response.line, equals(1));
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
deleted file mode 100644
index f2277ef..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
+++ /dev/null
@@ -1,23 +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:test_reflective_loader/test_reflective_loader.dart';
-
-import 'info_builder_test.dart' as info_builder;
-import 'instrumentation_renderer_test.dart' as instrumentation_renderer;
-import 'navigation_tree_renderer_test.dart' as navigation_tree_renderer;
-import 'offset_mapper_test.dart' as offset_mapper;
-import 'region_renderer_test.dart' as region_renderer;
-import 'unit_renderer_test.dart' as unit_renderer;
-
-void main() {
-  defineReflectiveSuite(() {
-    info_builder.main();
-    instrumentation_renderer.main();
-    navigation_tree_renderer.main();
-    offset_mapper.main();
-    region_renderer.main();
-    unit_renderer.main();
-  }, name: 'nnbd_migration');
-}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
deleted file mode 100644
index 5c26be5..0000000
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/file_details.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'nnbd_migration_test_base.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(UnitRendererTest);
-  });
-}
-
-@reflectiveTest
-class UnitRendererTest extends NnbdMigrationTestBase {
-  /// Render [libraryInfo], using a [MigrationInfo] which knows only about this
-  /// library.
-  List<FileDetails> renderUnits() {
-    var packageRoot = convertPath('/package');
-    var migrationInfo =
-        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
-
-    var contents = <FileDetails>[];
-    for (var unitInfo in infos) {
-      contents.add(
-          UnitRenderer(unitInfo, migrationInfo, PathMapper(resourceProvider))
-              .render());
-    }
-    return contents;
-  }
-
-  Future<void> test_editList_containsCount() async {
-    await buildInfoForSingleTestFile('''
-int a = null;
-bool b = a.isEven;
-''', migratedContent: '''
-int? a = null;
-bool  b = a!.isEven;
-''');
-    var output = renderUnits()[0];
-    var editList = output.edits;
-    expect(editList, hasLength(2));
-  }
-
-  Future<void> test_editList_containsEdits() async {
-    await buildInfoForSingleTestFile('''
-int a = null;
-bool b = a.isEven;
-''', migratedContent: '''
-int? a = null;
-bool  b = a!.isEven;
-''');
-    var output = renderUnits()[0];
-    expect(output.edits, hasLength(2));
-    expect(output.edits[0].line, equals(1));
-    expect(output.edits[0].offset, equals(3));
-    expect(output.edits[0].explanation,
-        equals("Changed type 'int' to be nullable"));
-    expect(output.edits[1].line, equals(2));
-    expect(output.edits[1].offset, equals(26));
-    expect(output.edits[1].explanation,
-        equals('Added a non-null assertion to nullable expression'));
-  }
-
-  Future<void> test_handle_large_deleted_region_near_top_of_file() async {
-    await buildInfoForSingleTestFile('''
-class C {
-  int hash(Iterable<int> elements) {
-    if (elements == null) {
-      return null.hashCode;
-    }
-    return 0;
-  }
-}
-
-List<int> x = [null];
-''', migratedContent: '''
-class C {
-  int  hash(Iterable<int >  elements) {
-    if (elements == null) {
-      return null.hashCode;
-    }
-    return 0;
-  }
-}
-
-List<int?>  x = [null];
-''', removeViaComments: false);
-    renderUnits();
-    // No assertions necessary; we are checking to make sure there is no crash.
-  }
-
-  Future<void> test_info_within_deleted_code() async {
-    await buildInfoForSingleTestFile('''
-class C {
-  int hash(Iterable<int> elements) {
-    if (elements == null) {
-      return null.hashCode;
-    }
-    return 0;
-  }
-}
-
-List<int> x = [null];
-''', migratedContent: '''
-class C {
-  int  hash(Iterable<int >  elements) {
-    if (elements == null) {
-      return null.hashCode;
-    }
-    return 0;
-  }
-}
-
-List<int?>  x = [null];
-''', removeViaComments: false);
-    var output = renderUnits()[0];
-    // Strip out URLs and span IDs; they're not being tested here.
-    var navContent = output.navigationContent
-        .replaceAll(RegExp('href="[^"]*"'), 'href="..."')
-        .replaceAll(RegExp('id="[^"]*"'), 'id="..."');
-    expect(navContent, '''
-class <span id="...">C</span> {
-  <a href="..." class="nav-link">int</a>  <span id="...">hash</span>(<a href="..." class="nav-link">Iterable</a>&lt;<a href="..." class="nav-link">int</a> &gt;  <span id="...">elements</span>) {
-    if (<a href="..." class="nav-link">elements</a> <a href="..." class="nav-link">==</a> null) {
-      return null.<a href="..." class="nav-link">hashCode</a>;
-    }
-    return 0;
-  }
-}
-
-<a href="..." class="nav-link">List</a>&lt;<a href="..." class="nav-link">int</a>?&gt;  <span id="...">x</span> = <span id="...">[null]</span>;
-''');
-  }
-
-  Future<void> test_navContentContainsEscapedHtml() async {
-    await buildInfoForSingleTestFile('List<String> a = null;',
-        migratedContent: 'List<String >? a = null;');
-    var output = renderUnits()[0];
-    // Strip out URLs which will change; not being tested here.
-    var navContent =
-        output.navigationContent.replaceAll(RegExp('href=".*?"'), 'href="..."');
-    expect(
-        navContent,
-        contains(r'<a href="..." class="nav-link">List</a>'
-            r'&lt;<a href="..." class="nav-link">String</a> &gt;? '
-            r'<span id="o13">a</span> = <span id="o17">null</span>;'));
-  }
-
-  Future<void> test_outputContainsModifiedAndUnmodifiedRegions() async {
-    await buildInfoForSingleTestFile('int a = null;',
-        migratedContent: 'int? a = null;');
-    var output = renderUnits()[0];
-    var regions = _stripDataAttributes(output.regions);
-    expect(regions,
-        contains('int<span class="region added-region">?</span> a = null;'));
-  }
-
-  Future<void> test_project_with_parts() async {
-    // In this test, we migrate a library and its part file.  Both files require
-    // addition of a `?`, but at different offsets.  We make sure the `?`s get
-    // added at the correct locations in each file.
-    var files = {
-      convertPath('/project/lib/a.dart'): '''
-part 'b.dart';
-
-int f() => null;
-''',
-      convertPath('/project/lib/b.dart'): '''
-part of 'a.dart';
-
-int g() => null;
-''',
-    };
-    var packageRoot = convertPath('/project');
-    await buildInfoForTestFiles(files, includedRoot: packageRoot);
-    var output = renderUnits();
-    expect(output[0].sourceCode, contains('int?'));
-    expect(output[1].sourceCode, contains('int?'));
-  }
-
-  Future<void> test_reference_to_sdk_file_with_parts() async {
-    await buildInfoForSingleTestFile('''
-import 'dart:async';
-Future<int> f(Future<int> x) {
-  return x.whenComplete(() {});
-}
-''', migratedContent: '''
-import 'dart:async';
-Future<int >  f(Future<int >  x) {
-  return x.whenComplete(() {});
-}
-''');
-    renderUnits();
-    // No assertions; we're just making sure there's no crash.
-  }
-
-  Future<void> test_regionsContainsEscapedHtml_ampersand() async {
-    await buildInfoForSingleTestFile('bool a = true && false;',
-        migratedContent: 'bool  a = true && false;');
-    var output = renderUnits()[0];
-    expect(
-        output.regions,
-        contains('bool<span class="region informative-region" data-offset="4" '
-            'data-line="1"> </span> a = true &amp;&amp; false;'));
-  }
-
-  Future<void> test_regionsContainsEscapedHtml_betweenRegions() async {
-    await buildInfoForSingleTestFile('List<String> a = null;',
-        migratedContent: 'List<String >? a = null;');
-    var output = renderUnits()[0];
-    var regions = _stripDataAttributes(output.regions);
-    expect(
-        regions,
-        contains(
-            'List&lt;String<span class="region informative-region"> </span>&gt;'
-            '<span class="region added-region">?</span> a = null;'));
-  }
-
-  Future<void> test_regionsContainsEscapedHtml_region() async {
-    await buildInfoForSingleTestFile('f(List<String> a) => a.join(",");',
-        migratedContent: 'f(List<String >  a) => a.join(",");');
-    var output = renderUnits()[0];
-    var regions = _stripDataAttributes(output.regions);
-    expect(
-        regions,
-        contains(
-            'List&lt;String<span class="region informative-region"> </span>'
-            '&gt;<span class="region informative-region"> </span>'));
-  }
-
-  UnitInfo unit(String path, String content, {List<RegionInfo> regions}) {
-    return UnitInfo(convertPath(path))
-      ..content = content
-      ..regions.addAll(regions);
-  }
-
-  /// Strip out data attributes which are not being tested here.
-  String _stripDataAttributes(String html) =>
-      html.replaceAll(RegExp(' data-[^=]+="[^"]+"'), '');
-}
diff --git a/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart b/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart
deleted file mode 100644
index 52b74d1..0000000
--- a/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
-import 'package:analyzer/file_system/memory_file_system.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:test_reflective_loader/test_reflective_loader.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(PreviewSiteTest);
-  });
-}
-
-@reflectiveTest
-class PreviewSiteTest with ResourceProviderMixin {
-  PreviewSite site;
-  DartFixListener dartfixListener;
-  MigrationState state;
-
-  void setUp() {
-    dartfixListener = DartFixListener(null);
-    resourceProvider = MemoryResourceProvider();
-    final migrationInfo = MigrationInfo({}, {}, null, null);
-    state = MigrationState(null, null, dartfixListener, null, null);
-    state.pathMapper = PathMapper(resourceProvider);
-    state.migrationInfo = migrationInfo;
-    site = PreviewSite(state, ([_]) => null);
-  }
-
-  void test_applyChangesEmpty() {
-    final file = getFile('/test.dart');
-    file.writeAsStringSync('void main() {}');
-    site.performApply();
-    expect(file.readAsStringSync(), 'void main() {}');
-    expect(state.hasBeenApplied, true);
-  }
-
-  void test_applyChangesTwiceThrows() {
-    site.performApply();
-    expect(site.performApply, throwsA(isA<StateError>()));
-  }
-
-  void test_applyMultipleChanges() {
-    final path = convertPath('/test.dart');
-    final file = getFile(path);
-    file.writeAsStringSync('void main() {}');
-    dartfixListener.addSourceChange(
-        'test change',
-        Location(path, 10, 0, 1, 10),
-        SourceChange('test change', edits: [
-          SourceFileEdit(path, 0, edits: [
-            SourceEdit(10, 0, 'List args'),
-            SourceEdit(13, 0, '\n  print(args);\n')
-          ])
-        ]));
-    site.performApply();
-    expect(file.readAsStringSync(), '''
-void main(List args) {
-  print(args);
-}''');
-    expect(state.hasBeenApplied, true);
-  }
-
-  void test_applySingleChange() {
-    final path = convertPath('/test.dart');
-    final file = getFile(path);
-    file.writeAsStringSync('void main() {}');
-    dartfixListener.addSourceChange(
-        'test change',
-        Location(path, 10, 0, 1, 10),
-        SourceChange('test change', edits: [
-          SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')])
-        ]));
-    site.performApply();
-    expect(file.readAsStringSync(), 'void main(List args) {}');
-    expect(state.hasBeenApplied, true);
-  }
-}
diff --git a/pkg/analysis_server/test/src/edit/test_all.dart b/pkg/analysis_server/test/src/edit/test_all.dart
index f63fe71..b91a43d 100644
--- a/pkg/analysis_server/test/src/edit/test_all.dart
+++ b/pkg/analysis_server/test/src/edit/test_all.dart
@@ -5,13 +5,9 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'fix/test_all.dart' as fix;
-import 'nnbd_migration/test_all.dart' as nnbd_migration;
-import 'preview/test_all.dart' as preview;
 
 void main() {
   defineReflectiveSuite(() {
     fix.main();
-    nnbd_migration.main();
-    preview.main();
   }, name: 'edit');
 }
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 891e189..88fd799 100644
--- a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
@@ -47,7 +47,7 @@
     fileA = provider.convertPath('/test/a.dart');
     fileB = provider.convertPath('/test/b.dart');
     channel = TestChannel();
-    manager = NotificationManager(channel, provider);
+    manager = NotificationManager(channel, provider.pathContext);
   }
 
   void test_handlePluginNotification_errors() {
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
new file mode 100644
index 0000000..3bc5d7a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/filtering/fuzzy_matcher_test.dart
@@ -0,0 +1,345 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FuzzyMapTest);
+    defineReflectiveTests(FuzzyMatcherTest);
+    defineReflectiveTests(FuzzyScorerTest);
+    defineReflectiveTests(ScoringFunctionTest);
+  });
+}
+
+/// Surrounds all matching ranges with brackets.
+String highlightMatches(String str, FuzzyMatcher matcher) {
+  var matches = matcher.getMatchedRanges();
+  expect(matches.length % 2, 0);
+  for (var i = 1; i < matches.length; i++) {
+    expect(matches[i], isNot(lessThan(matches[i - 1])));
+  }
+
+  var index = 0;
+  var result = '';
+  for (var i = 0; i < matches.length - 1; i += 2) {
+    result += str.substring(index, matches[i]) +
+        '[' +
+        str.substring(matches[i], matches[i + 1]) +
+        ']';
+    index = matches[i + 1];
+  }
+  return result + str.substring(index);
+}
+
+@reflectiveTest
+class FuzzyMapTest {
+  static MatchStyle FILE = MatchStyle.FILENAME;
+  static MatchStyle SYM = MatchStyle.SYMBOL;
+
+  void map(
+      {@required String str,
+      @required String want,
+      MatchStyle matchStyle = MatchStyle.TEXT}) {
+//    test('maps characters of $str', () {
+    var out = List<CharRole>.filled(str.length, CharRole.NONE);
+    var matcher = FuzzyMatcher('', matchStyle: matchStyle);
+    matcher.fuzzyMap(str, out);
+    var result = '';
+    var map = ' /cuC';
+    for (var i = 0; i < str.length; i++) {
+      result += map[out[i].index];
+    }
+    expect(result, want);
+//    });
+  }
+
+  void test_map() {
+    // Text
+    map(str: 'abc', want: 'Ccc');
+    map(str: '.abc', want: ' Ccc');
+    map(str: 'abc def', want: 'Ccc Ccc');
+    map(str: 'SWT MyID', want: 'Cuu CcCu');
+    map(str: 'ID', want: 'Cu');
+    map(str: ' ID ', want: ' Cu ');
+    map(str: 'IDSome', want: 'CuCccc');
+    map(str: '0123456789', want: 'Cccccccccc');
+    map(str: 'abcdefghigklmnopqrstuvwxyz', want: 'Cccccccccccccccccccccccccc');
+    map(str: 'ABCDEFGHIGKLMNOPQRSTUVWXYZ', want: 'Cuuuuuuuuuuuuuuuuuuuuuuuuu');
+    map(str: 'こんにちは', want: 'Ccccc');
+    map(str: ':/.', want: '   ');
+
+    // File names
+    map(str: 'abc/def', want: 'Ccc/Ccc', matchStyle: FILE);
+    map(str: ' abc_def', want: ' Ccc Ccc', matchStyle: FILE);
+    map(str: ' abc_DDf', want: ' Ccc CCc', matchStyle: FILE);
+    map(str: ':.', want: '  ', matchStyle: FILE);
+
+    // Symbols
+    map(str: 'abc::def::goo', want: 'Ccc//Ccc//Ccc', matchStyle: SYM);
+    map(str: 'proto::Message', want: 'Ccccc//Ccccccc', matchStyle: SYM);
+    map(str: 'AbstractSWTFactory', want: 'CcccccccCuuCcccccc', matchStyle: SYM);
+    map(str: 'Abs012', want: 'Cccccc', matchStyle: SYM);
+    map(str: 'public setFoo', want: 'Cccccc/CccCcc', matchStyle: SYM);
+    map(str: '/', want: ' ', matchStyle: SYM);
+  }
+}
+
+@reflectiveTest
+class FuzzyMatcherTest {
+  void expectMatch(FuzzyMatcher matcher, String str, String expected) {
+    expect(matcher.score(str), greaterThan(0));
+    expect(highlightMatches(str, matcher), expected);
+  }
+
+  void test_considersTheEmptyStringToMatchAll() {
+    var matcher = FuzzyMatcher('');
+    expect(matcher.score('def'), greaterThan(0));
+    expect(matcher.getMatchedRanges(), []);
+    expect(matcher.score('Ab stuff c'), greaterThan(0));
+    expect(matcher.getMatchedRanges(), []);
+  }
+
+  void test_ranksActions() {
+    var matcher = FuzzyMatcher('jade', matchStyle: MatchStyle.TEXT);
+    // Full word matches score higher than subsequence matches.
+    expect(
+        matcher.score('jump to a directory in tree'),
+        lessThan(matcher
+            .score('fix imports and dependencies using jade (java only)')));
+
+    matcher = FuzzyMatcher('unedit', matchStyle: MatchStyle.TEXT);
+    expect(matcher.score('Undo an edit'),
+        lessThan(matcher.score('Close unedited tabs')));
+
+    matcher = FuzzyMatcher('fix', matchStyle: MatchStyle.TEXT);
+    expect(
+        matcher.score('find next match'),
+        lessThan(
+            matcher.score('format edited lines in workspace files (g4 fix)')));
+  }
+
+  void test_ranksFileNames() {
+    var matcher = FuzzyMatcher('aa', matchStyle: MatchStyle.FILENAME);
+    // Full word matches scores higher than subsequence matches.
+    expect(matcher.score('a/a/a'), lessThan(matcher.score('b/aa')));
+    // Matches starting at the word boundary score higher.
+    expect(matcher.score('baab'), lessThan(matcher.score('aabb')));
+    // First word scores higher than later ones.
+    expect(matcher.score('bb_aa'), lessThan(matcher.score('aa_bb')));
+    // Tails don't matter.
+    expect(matcher.score('aa_b'), matcher.score('aab'));
+  }
+
+  void test_ranksSymbols() {
+    var matcher = FuzzyMatcher('Foo', matchStyle: MatchStyle.SYMBOL);
+    // Prefix and complete matches are the same.
+    expect(matcher.score('FooA'), matcher.score('Foo'));
+    // First word scores higher than later ones.
+    expect(matcher.score('BarFoo'), lessThan(matcher.score('FooBar')));
+    // Aligned matches score higher.
+    expect(matcher.score('Barfoo'), lessThan(matcher.score('BarFoo')));
+    expect(matcher.score('F__oo'), matcher.score('F_oo'));
+    expect(matcher.score('F_o_o'), lessThan(matcher.score('F_oo')));
+    // Missed word vs a match in the middle.
+    expect(matcher.score('BarFaoo'), lessThan(matcher.score('BarFaoFooa')));
+
+    matcher = FuzzyMatcher('FooBar', matchStyle: MatchStyle.SYMBOL);
+    // Ignores incomplete matches
+    expect(matcher.score('FooaBar'), lessThan(matcher.score('FooBar')));
+    expect(matcher.score('FooBara'), matcher.score('FooBar'));
+    // Less words in the middle is better.
+    expect(matcher.score('FooAtBaBar'), lessThan(matcher.score('FooAtBar')));
+    expectMatch(matcher, 'FooAtBaBar', '[Foo]AtBa[Bar]');
+  }
+
+  void test_respectsTheBasename() {
+    var matcher = FuzzyMatcher('subs', matchStyle: MatchStyle.FILENAME);
+    expect(matcher.score('sub/seq'), greaterThanOrEqualTo(0));
+    expect(matcher.score('sub/seq/end'), -1);
+    expect(matcher.score('sub/seq'), greaterThanOrEqualTo(0));
+    expect(matcher.score('sub/seq/base'), greaterThanOrEqualTo(0));
+  }
+
+  void test_worksWithDepotPaths() {
+    var matcher = FuzzyMatcher('subs', matchStyle: MatchStyle.FILENAME);
+    expect(matcher.score('//sub/seq'), greaterThanOrEqualTo(0));
+    expect(matcher.score('//sub/seq/end'), -1);
+    expect(matcher.score('//sub/seq'), greaterThanOrEqualTo(0));
+    expect(matcher.score('//sub/seq/base'), greaterThanOrEqualTo(0));
+  }
+
+  void test_worksWithSimpleCases() {
+    var matcher = FuzzyMatcher('abc');
+    expect(matcher.score('def'), -1);
+    expect(matcher.score('abd'), -1);
+    expect(matcher.score('abc'), greaterThan(0));
+    expect(matcher.score('Abc'), greaterThan(0));
+    expect(matcher.score('Ab stuff c'), greaterThan(0));
+  }
+
+  void test_worksWithUpperCasePatterns() {
+    var matcher = FuzzyMatcher('Abc');
+    expect(matcher.score('def'), -1);
+    expect(matcher.score('abd'), -1);
+    expect(matcher.score('abc'), greaterThan(0));
+    expect(matcher.score('Abc'), greaterThan(0));
+    expect(matcher.score('Ab stuff c'), greaterThan(0));
+  }
+}
+
+@reflectiveTest
+class FuzzyScorerTest {
+  static MatchStyle FILE = MatchStyle.FILENAME;
+
+  static MatchStyle SYM = MatchStyle.SYMBOL;
+
+  void score(
+      {@required String p,
+      @required String str,
+      String want,
+      MatchStyle input = MatchStyle.TEXT}) {
+//    test('scores $str against $p', () {
+    var matcher = FuzzyMatcher(p, matchStyle: input);
+    if (want != null) {
+      expect(matcher.score(str), greaterThanOrEqualTo(0));
+      expect(highlightMatches(str, matcher), want);
+    } else {
+      expect(matcher.score(str), -1);
+    }
+//    });
+  }
+
+  void test_scorer() {
+    // Text
+    score(p: 'a', str: 'abc', want: '[a]bc');
+    score(p: 'aaa', str: 'aaa', want: '[aaa]');
+    score(p: 'aaa', str: 'abab');
+    score(p: 'aaba', str: 'abababa', want: '[a]b[aba]ba');
+    score(p: 'cabaa', str: 'c_babababa', want: '[c]_b[aba]b[a]ba');
+    score(p: 'caaa', str: 'c_babababaaa', want: '[c]_bababab[aaa]');
+    score(p: 'aaa', str: 'aaababababaaa', want: '[aaa]babababaaa');
+    score(
+        p: 'unedit', str: 'Close unedited tabs', want: 'Close [unedit]ed tabs');
+    // Forward slashes are ignored in the non-filename mode.
+    score(p: 'aaa', str: 'aaabab/ababaaa', want: '[aaa]bab/ababaaa');
+    score(p: 'aaa', str: 'baaabab/abab_aaa', want: 'baaabab/abab_[aaa]');
+
+    // Filenames.
+    score(p: 'aa', str: 'a_a/a_a', want: '[a]_a/[a]_a', input: FILE);
+    score(p: 'aaaa', str: 'a_a/a_a', want: '[a]_[a]/[a]_[a]', input: FILE);
+    score(p: 'aaaa', str: 'aaaa', want: '[aaaa]', input: FILE);
+    score(p: 'aaaa', str: 'a_a/a_aaaa', want: 'a_a/[a]_[aaa]a', input: FILE);
+    score(p: 'aaaa', str: 'a_a/aaaaa', want: 'a_a/[aaaa]a', input: FILE);
+    score(p: 'aaaa', str: 'aabaaa', want: '[aa]b[aa]a', input: FILE);
+    score(p: 'aaaa', str: 'a/baaa', want: '[a]/b[aaa]', input: FILE);
+    score(p: 'aaaa', str: 'a/baaa/', want: '[a]/b[aaa]/', input: FILE);
+    score(
+        p: 'abcxz',
+        str: 'd/abc/abcd/oxz',
+        want: 'd/[abc]/abcd/o[xz]',
+        input: FILE);
+    score(
+        p: 'abcxz',
+        str: 'd/abcd/abc/oxz',
+        want: 'd/[abc]d/abc/o[xz]',
+        input: FILE);
+
+    // Symbols
+    score(p: 'foo', str: 'abc::foo', want: 'abc::[foo]', input: SYM);
+    score(p: 'foo', str: 'abc::foo::', want: 'abc::[foo]::', input: SYM);
+    score(p: 'foo', str: 'foo.foo', want: 'foo.[foo]', input: SYM);
+    score(p: 'foo', str: 'fo_oo.oo_oo', want: '[f]o_oo.[oo]_oo', input: SYM);
+    score(p: 'foo', str: 'fo_oo.fo_oo', want: 'fo_oo.[fo]_[o]o', input: SYM);
+    score(p: 'fo_o', str: 'fo_oo.o_oo', want: '[f]o_oo.[o_o]o', input: SYM);
+    score(p: 'fOO', str: 'fo_oo.o_oo', want: '[f]o_oo.[o]_[o]o', input: SYM);
+    score(
+        p: 'tedit', str: 'foo.TextEdit', want: 'foo.[T]ext[Edit]', input: SYM);
+    score(
+        p: 'tedit',
+        str: '*foo.TextEdit',
+        want: '*foo.[T]ext[Edit]',
+        input: SYM);
+    score(
+        p: 'TEdit', str: 'foo.TextEdit', want: 'foo.[T]ext[Edit]', input: SYM);
+    score(
+        p: 'Tedit', str: 'foo.TextEdit', want: 'foo.[T]ext[Edit]', input: SYM);
+    score(
+        p: 'Tedit', str: 'foo.Textedit', want: 'foo.[Te]xte[dit]', input: SYM);
+    score(p: 'TEdit', str: 'foo.Textedit', input: SYM);
+    score(p: 'te', str: 'foo.Textedit', want: 'foo.[Te]xtedit', input: SYM);
+    score(p: 'ee', str: 'foo.Textedit', input: SYM);
+    score(p: 'ex', str: 'foo.Textedit', want: 'foo.T[ex]tedit', input: SYM);
+    score(p: 'exdi', str: 'foo.Textedit', input: SYM);
+    score(p: 'exdit', str: 'foo.Textedit', input: SYM);
+    score(
+        p: 'extdit', str: 'foo.Textedit', want: 'foo.T[ext]e[dit]', input: SYM);
+    score(p: 'e', str: 'foo.Textedit', want: 'foo.T[e]xtedit', input: SYM);
+    score(p: 'ed', str: 'foo.Textedit', want: 'foo.Text[ed]it', input: SYM);
+    score(p: 'edt', str: 'foo.Textedit', input: SYM);
+    score(p: 'edit', str: 'foo.Textedit', want: 'foo.Text[edit]', input: SYM);
+    score(
+        p: 'pub', str: 'public setPubl', want: 'public set[Pub]l', input: SYM);
+    score(
+        p: 'mod',
+        str: 'public List<AbstractModule> getMods',
+        want: 'public List<AbstractModule> get[Mod]s',
+        input: SYM);
+    score(
+        p: 'm',
+        str: 'public List<AbstractModule> getMods',
+        want: 'public List<AbstractModule> get[M]ods',
+        input: SYM);
+    score(p: 'f', str: '[]foo.Foo', want: '[]foo.[F]oo', input: SYM);
+    score(
+        p: 'edin',
+        str: 'foo.TexteditNum',
+        want: 'foo.Text[edi]t[N]um',
+        input: SYM);
+  }
+}
+
+@reflectiveTest
+class ScoringFunctionTest {
+  ///
+  void score({@required String p, @required String str, double want}) {
+//    test('scores $str against $p', () {
+    var matcher = FuzzyMatcher(p, matchStyle: MatchStyle.SYMBOL);
+    expect(
+        matcher
+            .score(str)
+            .toStringAsFixed(4)
+            .startsWith(want.toStringAsFixed(4)),
+        true);
+//    });
+  }
+
+  void test_score() {
+    // This is a regression test. Feel free to update numbers below if the new
+    // ones are reasonable. Use 5 digits after the period.
+    score(p: 'abc', str: 'abc', want: 1); // perfect
+    score(p: 'abc', str: 'Abc', want: 1); // almost perfect
+    score(p: 'abc', str: 'Abcdef', want: 1);
+    score(p: 'strc', str: 'StrCat', want: 1);
+    score(p: 'abc_def', str: 'abc_def_xyz', want: 1);
+    score(p: 'abcdef', str: 'abc_def_xyz', want: 0.91667);
+    score(p: 'abcxyz', str: 'abc_def_xyz', want: 0.875);
+    score(p: 'sc', str: 'StrCat', want: 0.75);
+    score(p: 'abc', str: 'AbstrBasicCtor', want: 0.75);
+    // Qualified symbols.
+    score(p: 'foo', str: 'abc::foo', want: 1);
+    score(p: 'afoo', str: 'abc::foo', want: 0.9375);
+    score(p: 'abr', str: 'abc::bar', want: 0.5);
+    score(p: 'br', str: 'abc::bar', want: 0.375);
+    score(p: 'aar', str: 'abc::bar', want: 0.16667);
+    score(p: 'edin', str: 'foo.TexteditNum', want: 0.0625); // poor match
+    score(p: 'ediu', str: 'foo.TexteditNum', want: 0); // poor match
+    // We want the next two items to have roughly similar scores.
+    score(p: 'up', str: 'unique_ptr', want: 0.75);
+    score(p: 'up', str: 'upper_bound', want: 1);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/filtering/test_all.dart b/pkg/analysis_server/test/src/services/completion/filtering/test_all.dart
new file mode 100644
index 0000000..ffc9b80
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/filtering/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fuzzy_matcher_test.dart' as fuzzy_matcher;
+
+void main() {
+  defineReflectiveSuite(() {
+    fuzzy_matcher.main();
+  }, name: 'filtering');
+}
diff --git a/pkg/analysis_server/test/src/services/completion/test_all.dart b/pkg/analysis_server/test/src/services/completion/test_all.dart
new file mode 100644
index 0000000..1d82ee2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'filtering/test_all.dart' as filtering;
+
+void main() {
+  defineReflectiveSuite(() {
+    filtering.main();
+  }, name: 'completion');
+}
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 3dfe23e..6a2da91 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
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -12,22 +11,15 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ConvertToIfElementTest);
+    defineReflectiveTests(ConvertToForElementTest);
   });
 }
 
 @reflectiveTest
-class ConvertToIfElementTest extends AssistProcessorTest {
+class ConvertToForElementTest extends AssistProcessorTest {
   @override
   AssistKind get kind => DartAssistKind.CONVERT_TO_FOR_ELEMENT;
 
-  @override
-  void setUp() {
-    createAnalysisOptionsFile(
-        experiments: [EnableString.control_flow_collections]);
-    super.setUp();
-  }
-
   Future<void> test_mapFromIterable_complexKey() async {
     await resolveTestUnit('''
 f(Iterable<int> i) {
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 fb81386..fce863a 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
@@ -25,7 +25,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
-    children: <Widget>[
+    children: [
       Center(
         child: /*caret*/Padding(
           padding: const EdgeInsets.all(8.0),
@@ -43,7 +43,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
-    children: <Widget>[
+    children: [
       Center(
         child: Center(
           heightFactor: 0.5,
@@ -87,7 +87,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
-    children: <Widget>[
+    children: [
       Text('foo'),
       /*caret*/Center(
         heightFactor: 0.5,
@@ -105,7 +105,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
-    children: <Widget>[
+    children: [
       Text('foo'),
       Padding(
         padding: const EdgeInsets.all(8.0),
@@ -186,7 +186,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
-    children: <Widget>[
+    children: [
       Text('aaa'),
       /*caret*/Column(
         children: [
@@ -213,7 +213,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
-    children: <Widget>[
+    children: [
       Text('aaa'),
       Row(
         children: [
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 629ebde..ce2a3ba 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
@@ -42,7 +42,7 @@
     children: [
       Text('aaa'),
       if (b) Column(
-        children: <Widget>[
+        children: [
           Text('bbb'),
         ],
       ),
@@ -73,7 +73,7 @@
   main() {
     return Container(
       child: Column(
-        children: <Widget>[
+        children: [
           Text('aaa'),
         ],
       ),
@@ -109,7 +109,7 @@
     return Row(children: [
       Text('aaa'),
       Column(
-        children: <Widget>[
+        children: [
           Text('bbb'),
           Text('ccc'),
         ],
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 6905f54..794cc11 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
@@ -94,7 +94,7 @@
     return Container(
       child: /*caret*/DefaultTextStyle(
         child: Row(
-          children: <Widget>[
+          children: [
             Container(
             ),
           ],
@@ -112,7 +112,7 @@
       child: widget(
         child: DefaultTextStyle(
           child: Row(
-            children: <Widget>[
+            children: [
               Container(
               ),
             ],
@@ -134,7 +134,7 @@
     return Container(\r
       child: /*caret*/DefaultTextStyle(\r
         child: Row(\r
-          children: <Widget>[\r
+          children: [\r
             Container(\r
             ),\r
           ],\r
@@ -152,7 +152,7 @@
       child: widget(\r
         child: DefaultTextStyle(\r
           child: Row(\r
-            children: <Widget>[\r
+            children: [\r
               Container(\r
               ),\r
             ],\r
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 fe71efc..2325c8c 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
@@ -45,7 +45,7 @@
     return Column(children: [
       Text('aaa'),
       Row(
-        children: <Widget>[
+        children: [
           Text('bbb'),
           Text('ccc'),
         ],
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 b471caa..49a5dcf 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
@@ -43,7 +43,7 @@
 }
 
 build() {
-  return new MyWidget(children: <Widget>[],);
+  return new MyWidget(children: [],);
 }
 ''');
   }
@@ -241,7 +241,7 @@
 import 'package:test/a.dart';
 
 main() {
-  A a = new A(names: <String>[]);
+  A a = new A(names: []);
   print(a);
 }
 ''');
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 b9ecdf2..14fdb0d 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
@@ -12,6 +12,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AddRequiredTest);
+    defineReflectiveTests(AddRequiredWithNNBDTest);
   });
 }
 
@@ -36,3 +37,21 @@
 ''');
   }
 }
+
+@reflectiveTest
+class AddRequiredWithNNBDTest extends FixProcessorTest {
+  @override
+  List<String> get experiments => ['non-nullable'];
+
+  @override
+  FixKind get kind => DartFixKind.ADD_REQUIRED2;
+
+  Future<void> test_withAssert() async {
+    await resolveTestUnit('''
+void function({String param}) {}
+''');
+    await assertHasFix('''
+void function({required String param}) {}
+''');
+  }
+}
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
new file mode 100644
index 0000000..41d23a3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/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 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToOnTypeTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToOnTypeTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_ON_TYPE;
+
+  @override
+  String get lintCode => LintNames.avoid_types_as_parameter_names;
+
+  Future<void> test_withOnType() async {
+    await resolveTestUnit('''
+void f() {
+  try {
+  } on ArgumentError catch (Object) {
+  }
+}
+''');
+    await assertNoFix(
+      errorFilter: lintNameFilter(
+        LintNames.avoid_types_as_parameter_names,
+      ),
+    );
+  }
+
+  Future<void> test_withoutStackTrace() async {
+    await resolveTestUnit('''
+void f() {
+  try {
+  } catch (ArgumentError) {
+  }
+}
+''');
+    await assertHasFix('''
+void f() {
+  try {
+  } on ArgumentError {
+  }
+}
+''');
+  }
+
+  Future<void> test_withStackTrace() async {
+    await resolveTestUnit('''
+void f() {
+  try {
+  } catch (ArgumentError, st) {
+    st;
+  }
+}
+''');
+    await assertHasFix('''
+void f() {
+  try {
+  } on ArgumentError catch (_, st) {
+    st;
+  }
+}
+''');
+  }
+}
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 d806718..4808f8b 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
@@ -27,16 +27,17 @@
   /// The offset of the lint marker in the code being analyzed.
   int lintOffset = -1;
 
-  /// Return a list of the experiments that are to be enabled for tests in this
-  /// class, or `null` if there are no experiments that should be enabled.
-  List<String> get experiments => null;
-
   /// Return the lint code being tested.
   String get lintCode;
 
+  bool Function(AnalysisError) lintNameFilter(String name) {
+    return (e) {
+      return e.errorCode is LintCode && e.errorCode.name == name;
+    };
+  }
+
   @override
-  void setUp() {
-    super.setUp();
+  void _createAnalysisOptionsFile() {
     createAnalysisOptionsFile(experiments: experiments, lints: [lintCode]);
   }
 
@@ -69,6 +70,10 @@
   /// neither [assertHasFix] nor [assertHasFixAllFix] has been invoked.
   String resultCode;
 
+  /// Return a list of the experiments that are to be enabled for tests in this
+  /// class, or `null` if there are no experiments that should be enabled.
+  List<String> get experiments => null;
+
   /// Return the kind of fixes being tested by this test class.
   FixKind get kind;
 
@@ -166,6 +171,7 @@
   void setUp() {
     super.setUp();
     verifyNoTestUnitErrors = false;
+    _createAnalysisOptionsFile();
   }
 
   /// Computes fixes and verifies that there is a fix for the given [error] of the appropriate kind.
@@ -287,6 +293,12 @@
     return await DartFixContributor().computeFixes(context);
   }
 
+  /// Create the analysis options file needed in order to correctly analyze the
+  /// test file.
+  void _createAnalysisOptionsFile() {
+    createAnalysisOptionsFile(experiments: experiments);
+  }
+
   /// Find the error that is to be fixed by computing the errors in the file,
   /// using the [errorFilter] to filter out errors that should be ignored, and
   /// expecting that there is a single remaining error. The error filter should
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
new file mode 100644
index 0000000..428f1d6
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveQuestionMarkTest);
+  });
+}
+
+@reflectiveTest
+class RemoveQuestionMarkTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_QUESTION_MARK;
+
+  @override
+  void setUp() {
+    super.setUp();
+    createAnalysisOptionsFile(experiments: ['non-nullable']);
+  }
+
+  Future<void> test_catchClause() async {
+    await resolveTestUnit('''
+class A {}
+void f() {
+  try {
+  } on A? {
+  }
+}
+''');
+    await assertHasFix('''
+class A {}
+void f() {
+  try {
+  } on A {
+  }
+}
+''');
+  }
+
+  Future<void> test_extendsClause() async {
+    await resolveTestUnit('''
+class A {}
+class B extends A? {}
+''');
+    await assertHasFix('''
+class A {}
+class B extends A {}
+''');
+  }
+
+  Future<void> test_implementsClause() async {
+    await resolveTestUnit('''
+class A {}
+class B implements A? {}
+''');
+    await assertHasFix('''
+class A {}
+class B implements A {}
+''');
+  }
+
+  Future<void> test_onClause_class() async {
+    await resolveTestUnit('''
+class A {}
+mixin B on A? {}
+''');
+    await assertHasFix('''
+class A {}
+mixin B on A {}
+''');
+  }
+
+  Future<void> test_withClause_class() async {
+    await resolveTestUnit('''
+class A {}
+class B with A? {}
+''');
+    await assertHasFix('''
+class A {}
+class B with A {}
+''');
+  }
+
+  Future<void> test_withClause_mixin() async {
+    await resolveTestUnit('''
+mixin A {}
+class B with A? {}
+''');
+    await assertHasFix('''
+mixin A {}
+class B with A {}
+''');
+  }
+}
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 c7f6976..c6c1814 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
@@ -39,9 +39,7 @@
 ''');
     await assertHasFix('''
 var v;Future<int> main() async => 0;
-''', errorFilter: (error) {
-      return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
-    });
+''');
   }
 
   Future<void> test_complexTypeName_withImport() async {
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 8da5969..48d2b28 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
@@ -11,12 +11,12 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(SortChildPropertiesLastTest);
+    defineReflectiveTests(SortChildPropertyLastTest);
   });
 }
 
 @reflectiveTest
-class SortChildPropertiesLastTest extends FixProcessorLintTest {
+class SortChildPropertyLastTest extends FixProcessorLintTest {
   @override
   FixKind get kind => DartFixKind.SORT_CHILD_PROPERTY_LAST;
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_directives_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_directives_test.dart
new file mode 100644
index 0000000..903e00e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/sort_directives_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SortDirectivesTest);
+  });
+}
+
+@reflectiveTest
+class SortDirectivesTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.SORT_DIRECTIVES;
+
+  @override
+  String get lintCode => LintNames.directives_ordering;
+
+  Future<void> test_sortDirectives() async {
+    await resolveTestUnit('''
+//ignore_for_file: unused_import
+import 'dart:io';
+
+import 'dart:async';
+
+void main(Stream<String> args) { }
+''');
+    await assertHasFix('''
+//ignore_for_file: unused_import
+import 'dart:async';
+import 'dart:io';
+
+void main(Stream<String> args) { }
+''');
+  }
+}
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 9fdf630..2c18bb7 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
@@ -52,6 +52,7 @@
 import 'convert_to_map_literal_test.dart' as convert_to_map_literal;
 import 'convert_to_named_arguments_test.dart' as convert_to_named_arguments;
 import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
+import 'convert_to_on_type_test.dart' as convert_to_on_type;
 import 'convert_to_package_import_test.dart' as convert_to_package_import;
 import 'convert_to_relative_import_test.dart' as convert_to_relative_import;
 import 'convert_to_set_literal_test.dart' as convert_to_set_literal;
@@ -111,6 +112,7 @@
     as remove_parameters_in_getter_declaration;
 import 'remove_parentheses_in_getter_invocation_test.dart'
     as remove_parentheses_in_getter_invocation;
+import 'remove_question_mark_test.dart' as remove_question_mark;
 import 'remove_this_expression_test.dart' as remove_this_expression;
 import 'remove_type_annotation_test.dart' as remove_type_annotation;
 import 'remove_type_arguments_test.dart' as remove_type_arguments;
@@ -145,6 +147,7 @@
 import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
 import 'replace_with_var_test.dart' as replace_with_var;
 import 'sort_child_property_last_test.dart' as sort_properties_last;
+import 'sort_directives_test.dart' as sort_directives;
 import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
 import 'use_const_test.dart' as use_const;
 import 'use_effective_integer_division_test.dart'
@@ -197,6 +200,7 @@
     convert_to_map_literal.main();
     convert_to_named_arguments.main();
     convert_to_null_aware.main();
+    convert_to_on_type.main();
     convert_to_package_import.main();
     convert_to_relative_import.main();
     convert_to_set_literal.main();
@@ -251,6 +255,7 @@
     remove_operator.main();
     remove_parameters_in_getter_declaration.main();
     remove_parentheses_in_getter_invocation.main();
+    remove_question_mark.main();
     remove_this_expression.main();
     remove_type_annotation.main();
     remove_type_arguments.main();
@@ -283,6 +288,7 @@
     replace_with_null_aware.main();
     replace_with_tear_off.main();
     replace_with_var.main();
+    sort_directives.main();
     sort_properties_last.main();
     update_sdk_constraints.main();
     use_const.main();
diff --git a/pkg/analysis_server/test/src/services/test_all.dart b/pkg/analysis_server/test/src/services/test_all.dart
index a2c9b81..e5d8aa0 100644
--- a/pkg/analysis_server/test/src/services/test_all.dart
+++ b/pkg/analysis_server/test/src/services/test_all.dart
@@ -4,12 +4,14 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'correction/test_all.dart' as correction_all;
-import 'flutter/test_all.dart' as flutter_all;
+import 'completion/test_all.dart' as completion;
+import 'correction/test_all.dart' as correction;
+import 'flutter/test_all.dart' as flutter;
 
 void main() {
   defineReflectiveSuite(() {
-    correction_all.main();
-    flutter_all.main();
+    completion.main();
+    correction.main();
+    flutter.main();
   }, name: 'services');
 }
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index 2f1638e..1681ecc 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -4,6 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'cider/test_all.dart' as cider;
 import 'computer/test_all.dart' as computer;
 import 'domain_abstract_test.dart' as domain_abstract;
 import 'domains/test_all.dart' as domains;
@@ -17,6 +18,7 @@
 
 void main() {
   defineReflectiveSuite(() {
+    cider.main();
     computer.main();
     domain_abstract.main();
     domains.main();
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
new file mode 100644
index 0000000..ca011cc
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('generated classes', () {
+    test('can be checked for equality', () {
+      final a = TextDocumentIdentifier('/a');
+      final b = TextDocumentIdentifier('/a');
+
+      expect(a, equals(b));
+    });
+
+    test('with list fields can be checked for equality', () {
+      final a = TextDocumentClientCapabilitiesCodeActionKind(
+          [CodeActionKind.QuickFix]);
+      final b = TextDocumentClientCapabilitiesCodeActionKind(
+          [CodeActionKind.QuickFix]);
+
+      expect(a, equals(b));
+    });
+
+    test('with aliased list fields can be checked for equality', () {
+      final a = TextDocumentRegistrationOptions(
+          [DocumentFilter('dart', 'file', null)]);
+      final b = TextDocumentRegistrationOptions(
+          [DocumentFilter('dart', 'file', null)]);
+
+      expect(a, equals(b));
+    });
+
+    test('with map fields can be checked for equality', () {
+      final a = WorkspaceEdit({
+        'a': [TextEdit(Range(Position(0, 0), Position(0, 0)), 'a')]
+      }, null);
+      final b = WorkspaceEdit({
+        'a': [TextEdit(Range(Position(0, 0), Position(0, 0)), 'a')]
+      }, null);
+
+      expect(a, equals(b));
+    });
+
+    test('with union fields can be checked for equality', () {
+      final a =
+          SignatureInformation('a', Either2<String, MarkupContent>.t1('a'), []);
+      final b =
+          SignatureInformation('a', Either2<String, MarkupContent>.t1('a'), []);
+
+      expect(a, equals(b));
+    });
+
+    test('consider subclasses when checking for equality', () {
+      final a = TextDocumentRegistrationOptions(
+          [DocumentFilter('dart', 'file', null)]);
+      final b = TextDocumentSaveRegistrationOptions(
+          true, [DocumentFilter('dart', 'file', null)]);
+
+      expect(a, isNot(equals(b)));
+      expect(b, isNot(equals(a)));
+    });
+  });
+}
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 1717817..07a4247 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'dart_test.dart' as dart_test;
+import 'generated_classes_test.dart' as generated_classes_test;
 import 'json_test.dart' as json_test;
 import 'markdown_test.dart' as markdown_test;
 import 'typescript_test.dart' as typescript_test;
@@ -12,6 +13,7 @@
 void main() {
   defineReflectiveSuite(() {
     dart_test.main();
+    generated_classes_test.main();
     json_test.main();
     markdown_test.main();
     typescript_test.main();
diff --git a/pkg/analysis_server/tool/completion_metrics/code_metrics.dart b/pkg/analysis_server/tool/completion_metrics/code_metrics.dart
index 47af3b7..cd29795 100644
--- a/pkg/analysis_server/tool/completion_metrics/code_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/code_metrics.dart
@@ -6,6 +6,7 @@
 import 'dart:io' as io;
 
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -321,6 +322,8 @@
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
     _visitChildren(node, {
+      'documentationComment': node.documentationComment,
+      'metadata': node.metadata,
       'abstractKeyword': node.abstractKeyword,
       'name': node.name,
       'typeParameters': node.typeParameters,
@@ -694,7 +697,10 @@
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     _visitChildren(node, {
+      'documentationComment': node.documentationComment,
+      'metadata': node.metadata,
       'returnType': node.returnType,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'parameters': node.parameters,
     });
@@ -929,6 +935,7 @@
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
       'name': node.name,
+      'typeParameters': node.typeParameters,
       'onClause': node.onClause,
       'implementsClause': node.implementsClause,
       'members': node.members,
@@ -1138,6 +1145,7 @@
   @override
   void visitSwitchCase(SwitchCase node) {
     _visitChildren(node, {
+      'labels': node.labels,
       'expression': node.expression,
       'statements': node.statements,
     });
@@ -1352,36 +1360,8 @@
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
     final collector = CodeShapeDataCollector(data);
-
     for (var context in collection.contexts) {
-      for (var filePath in context.contextRoot.analyzedFiles()) {
-        if (AnalysisEngine.isDartFileName(filePath)) {
-          try {
-            var resolvedUnitResult =
-                await context.currentSession.getResolvedUnit(filePath);
-            //
-            // Check for errors that cause the file to be skipped.
-            //
-            if (resolvedUnitResult.state != ResultState.VALID) {
-              print('File $filePath skipped because it could not be analyzed.');
-              print('');
-              continue;
-            } else if (hasError(resolvedUnitResult)) {
-              print('File $filePath skipped due to errors:');
-              for (var error in resolvedUnitResult.errors) {
-                print('  ${error.toString()}');
-              }
-              print('');
-              continue;
-            }
-
-            resolvedUnitResult.unit.accept(collector);
-          } catch (exception) {
-            print('Exception caught analyzing: "$filePath"');
-            print(exception.toString());
-          }
-        }
-      }
+      await _computeInContext(context.contextRoot, collector);
     }
   }
 
@@ -1394,6 +1374,49 @@
     _writeChildData(sink);
   }
 
+  /// Compute the metrics for the files in the context [root], creating a
+  /// separate context collection to prevent accumulating memory. The metrics
+  /// should be captured in the [collector]. Include additional details in the
+  /// output if [verbose] is `true`.
+  void _computeInContext(
+      ContextRoot root, CodeShapeDataCollector collector) async {
+    // Create a new collection to avoid consuming large quantities of memory.
+    final collection = AnalysisContextCollection(
+      includedPaths: root.includedPaths.toList(),
+      excludedPaths: root.excludedPaths.toList(),
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
+    );
+    var context = collection.contexts[0];
+    for (var filePath in context.contextRoot.analyzedFiles()) {
+      if (AnalysisEngine.isDartFileName(filePath)) {
+        try {
+          var resolvedUnitResult =
+              await context.currentSession.getResolvedUnit(filePath);
+          //
+          // Check for errors that cause the file to be skipped.
+          //
+          if (resolvedUnitResult.state != ResultState.VALID) {
+            print('File $filePath skipped because it could not be analyzed.');
+            print('');
+            continue;
+          } else if (hasError(resolvedUnitResult)) {
+            print('File $filePath skipped due to errors:');
+            for (var error in resolvedUnitResult.errors) {
+              print('  ${error.toString()}');
+            }
+            print('');
+            continue;
+          }
+
+          resolvedUnitResult.unit.accept(collector);
+        } catch (exception) {
+          print('Exception caught analyzing: "$filePath"');
+          print(exception.toString());
+        }
+      }
+    }
+  }
+
   /// Convert the contents of a single [map] into the values for each row in the
   /// column occupied by the map.
   List<String> _convertMap<T extends Object>(String context, Map<T, int> map) {
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
index be513c6..38dcbeb 100644
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:io' as io;
 
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 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';
@@ -15,8 +16,13 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart' as err;
+import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:args/args.dart';
 
 import 'metrics_util.dart';
@@ -30,10 +36,14 @@
   if (!validArguments(parser, result)) {
     return io.exit(1);
   }
+
   var root = result.rest[0];
   print('Analyzing root: "$root"');
   var stopwatch = Stopwatch()..start();
-  var code = await CompletionMetricsComputer(root, verbose: result['verbose'])
+  var code = await CompletionMetricsComputer(root,
+          verbose: result['verbose'],
+          availableSuggestions: result[AVAILABLE_SUGGESTIONS],
+          overlay: result[OVERLAY])
       .compute();
   stopwatch.stop();
 
@@ -43,21 +53,51 @@
   return io.exit(code);
 }
 
+const String AVAILABLE_SUGGESTIONS = 'available-suggestions';
+
+const String OVERLAY = 'overlay';
+
+const String OVERLAY_NONE = 'none';
+
+const String OVERLAY_REMOVE_REST_OF_FILE = 'remove-rest-of-file';
+
+const String OVERLAY_REMOVE_TOKEN = 'remove-token';
+
 /// Create a parser that can be used to parse the command-line arguments.
 ArgParser createArgParser() {
-  var parser = ArgParser();
-  parser.addOption(
-    'help',
-    abbr: 'h',
-    help: 'Print this help message.',
-  );
-  parser.addFlag(
-    'verbose',
-    abbr: 'v',
-    help: 'Print additional information about the analysis',
-    negatable: false,
-  );
-  return parser;
+  return ArgParser()
+    ..addOption(
+      'help',
+      abbr: 'h',
+      help: 'Print this help message.',
+    )
+    ..addFlag(
+      'verbose',
+      abbr: 'v',
+      help: 'Print additional information about the analysis',
+      negatable: false,
+    )
+    ..addFlag(AVAILABLE_SUGGESTIONS,
+        abbr: 'a',
+        help: 'Use the available suggestions feature in the Analysis Server '
+            'when computing the set of code completions. With this feature '
+            'enabled, completion will match the support in the Dart Plugin for '
+            'IntelliJ, without this enabled the completion support matches '
+            'the support in LSP.',
+        defaultsTo: false,
+        negatable: false)
+    ..addOption(OVERLAY,
+        allowed: [
+          OVERLAY_NONE,
+          OVERLAY_REMOVE_TOKEN,
+          OVERLAY_REMOVE_REST_OF_FILE
+        ],
+        defaultsTo: OVERLAY_NONE,
+        help:
+            'Before attempting a completion at the location of each token, the '
+            'token can be removed, or the rest of the file can be removed to test '
+            'code completion with diverse methods. The default mode is to '
+            'complete at the start of the token without modifying the file.');
 }
 
 /// Print usage information for this tool.
@@ -94,6 +134,12 @@
 /// A wrapper for the collection of [Counter] and [MeanReciprocalRankComputer]
 /// objects for a run of [CompletionMetricsComputer].
 class CompletionMetrics {
+  /// The maximum number of longest results to collect.
+  static const maxLongestResults = 10;
+
+  /// The maximum number of worst results to collect.
+  static const maxWorstResults = 10;
+
   /// The name associated with this set of metrics.
   final String name;
 
@@ -126,7 +172,52 @@
   MeanReciprocalRankComputer nonTypeMemberMrrComputer =
       MeanReciprocalRankComputer('non-type member completions');
 
+  ArithmeticMeanComputer charsBeforeTop =
+      ArithmeticMeanComputer('chars_before_top');
+
+  ArithmeticMeanComputer charsBeforeTopFive =
+      ArithmeticMeanComputer('chars_before_top_five');
+
+  ArithmeticMeanComputer insertionLengthTheoretical =
+      ArithmeticMeanComputer('insertion_length_theoretical');
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks.
+  List<CompletionResult> worstResults = [];
+
+  /// A list of the top [maxLongestResults] completion results with the highest
+  /// (worst) ranks.
+  List<CompletionResult> longestResults = [];
+
   CompletionMetrics(this.name);
+
+  /// Record this completion result, this method handles the worst ranked items
+  /// as well as the longest sets of results to compute.
+  void recordCompletionResult(CompletionResult result) {
+    // If the [result] is worse than any previously recorded results, record it.
+    if (worstResults.length >= maxWorstResults) {
+      if (result.place.rank <= worstResults.last.place.rank) {
+        return;
+      }
+      worstResults.removeLast();
+    }
+    worstResults.add(result);
+    worstResults.sort((first, second) => second.place.rank - first.place.rank);
+
+    // Record this elapsed ms count for the average ms count.
+    meanCompletionMS.addValue(result.elapsedMS);
+
+    // If the [result] is took longer than any previously recorded results,
+    // record it.
+    if (longestResults.length >= maxLongestResults) {
+      if (result.elapsedMS <= longestResults.last.elapsedMS) {
+        return;
+      }
+      longestResults.removeLast();
+    }
+    longestResults.add(result);
+    longestResults.sort((first, second) => second.elapsedMS - first.elapsedMS);
+  }
 }
 
 /// This is the main metrics computer class for code completions. After the
@@ -137,7 +228,9 @@
 
   final bool verbose;
 
-  String _currentFilePath;
+  final bool availableSuggestions;
+
+  final String overlay;
 
   ResolvedUnitResult _resolvedUnitResult;
 
@@ -148,10 +241,16 @@
 
   CompletionMetrics metricsNewMode;
 
-  CompletionMetricsComputer(this.rootPath, {this.verbose});
+  final OverlayResourceProvider _provider =
+      OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
 
-  /// The path to the current file.
-  String get currentFilePath => _currentFilePath;
+  int overlayModificationStamp = 0;
+
+  CompletionMetricsComputer(this.rootPath,
+      {this.verbose, this.availableSuggestions, this.overlay})
+      : assert(overlay == OVERLAY_NONE ||
+            overlay == OVERLAY_REMOVE_TOKEN ||
+            overlay == OVERLAY_REMOVE_REST_OF_FILE);
 
   Future<int> compute() async {
     resultCode = 0;
@@ -166,21 +265,36 @@
     }
     printMetrics(metricsOldMode);
     printMetrics(metricsNewMode);
+    if (verbose) {
+      printWorstResults(metricsNewMode);
+      printLongestResults(metricsNewMode);
+    }
     return resultCode;
   }
 
-  void forEachExpectedCompletion(ExpectedCompletion expectedCompletion,
-      List<CompletionSuggestion> suggestions, CompletionMetrics metrics) {
+  bool forEachExpectedCompletion(
+      ExpectedCompletion expectedCompletion,
+      List<CompletionSuggestion> suggestions,
+      CompletionMetrics metrics,
+      int elapsedMS,
+      bool doPrintMissedCompletions) {
     assert(suggestions != null);
 
+    var successfulCompletion;
+
     var place = placementInSuggestionList(suggestions, expectedCompletion);
 
     metrics.mrrComputer.addRank(place.rank);
 
     if (place.denominator != 0) {
+      successfulCompletion = true;
+
       metrics.successfulMrrComputer.addRank(place.rank);
       metrics.completionCounter.count('successful');
 
+      metrics.recordCompletionResult(
+          CompletionResult(place, suggestions, expectedCompletion, elapsedMS));
+
       var element = getElement(expectedCompletion.syntacticEntity);
       if (isInstanceMember(element)) {
         metrics.instanceMemberMrrComputer.addRank(place.rank);
@@ -189,7 +303,17 @@
       } else {
         metrics.nonTypeMemberMrrComputer.addRank(place.rank);
       }
+
+      var charsBeforeTop =
+          _computeCharsBeforeTop(expectedCompletion, suggestions);
+      metrics.charsBeforeTop.addValue(charsBeforeTop);
+      metrics.charsBeforeTopFive.addValue(
+          _computeCharsBeforeTop(expectedCompletion, suggestions, minRank: 5));
+      metrics.insertionLengthTheoretical
+          .addValue(expectedCompletion.completion.length - charsBeforeTop);
     } else {
+      successfulCompletion = false;
+
       metrics.completionCounter.count('unsuccessful');
 
       metrics.completionMissedTokenCounter.count(expectedCompletion.completion);
@@ -197,18 +321,40 @@
       metrics.completionElementKindCounter
           .count(expectedCompletion.elementKind.toString());
 
-      if (verbose) {
-        // The format "/file/path/foo.dart:3:4" makes for easier input
-        // with the Files dialog in IntelliJ.
-        var lineNumber = expectedCompletion.lineNumber;
-        var columnNumber = expectedCompletion.columnNumber;
-        print('$currentFilePath:$lineNumber:$columnNumber');
-        print('  missing completion: "${expectedCompletion.completion}"');
-        print('  completion kind: ${expectedCompletion.kind}');
-        print('  element kind: ${expectedCompletion.elementKind}');
+      if (doPrintMissedCompletions) {
+        var closeMatchSuggestion;
+        for (var suggestion in suggestions) {
+          if (suggestion.completion == expectedCompletion.completion) {
+            closeMatchSuggestion = suggestion;
+          }
+        }
+
+        print('missing completion (`useNewRelevance = true`):');
+        print('$expectedCompletion');
+        if (closeMatchSuggestion != null) {
+          print('    close matching completion that was in the list:');
+          print('    $closeMatchSuggestion');
+        }
         print('');
       }
     }
+    return successfulCompletion;
+  }
+
+  void printLongestResults(CompletionMetrics metrics) {
+    print('');
+    print('====================');
+    print('The longest completion results to compute:');
+    for (var result in metrics.longestResults) {
+      var elapsedMS = result.elapsedMS;
+      var expected = result.expectedCompletion;
+      print('');
+      print('Elapsed ms: $elapsedMS');
+      print('Completion: ${expected.completion}');
+      print('Completion kind: ${expected.kind}');
+      print('Element kind: ${expected.elementKind}');
+      print('Location: ${expected.location}');
+    }
   }
 
   void printMetrics(CompletionMetrics metrics) {
@@ -242,54 +388,143 @@
     metrics.nonTypeMemberMrrComputer.printMean();
     print('');
 
+    metrics.charsBeforeTop.printMean();
+    metrics.charsBeforeTopFive.printMean();
+    metrics.insertionLengthTheoretical.printMean();
+    print('');
+
     print('Summary for $rootPath:');
     metrics.meanCompletionMS.printMean();
     metrics.completionCounter.printCounterValues();
     print('====================');
   }
 
+  void printWorstResults(CompletionMetrics metrics) {
+    print('');
+    print('====================');
+    print('The worst completion results:');
+    for (var result in metrics.worstResults) {
+      var rank = result.place.rank;
+      var expected = result.expectedCompletion;
+      var suggestions = result.suggestions;
+      var preceeding = StringBuffer();
+      for (var i = 0; i < rank - 1; i++) {
+        if (i > 0) {
+          preceeding.write(', ');
+        }
+        preceeding.write(suggestions[i].relevance);
+      }
+      print('');
+      print('Rank: $rank');
+      print('Completion: ${expected.completion}');
+      print('Completion kind: ${expected.kind}');
+      print('Element kind: ${expected.elementKind}');
+      print('Location: ${expected.location}');
+      print('Preceeding: $preceeding');
+      print('Suggestion: ${suggestions[rank - 1]}');
+    }
+  }
+
+  int _computeCharsBeforeTop(
+      ExpectedCompletion target, List<CompletionSuggestion> suggestions,
+      {int minRank = 1}) {
+    var rank = placementInSuggestionList(suggestions, target).rank;
+    if (rank <= minRank) {
+      return 0;
+    }
+    var expected = target.completion;
+    for (var i = 1; i < expected.length + 1; i++) {
+      var prefix = expected.substring(0, i);
+      var filteredSuggestions = _filterSuggestions(prefix, suggestions);
+      rank = placementInSuggestionList(filteredSuggestions, target).rank;
+      if (rank <= minRank) {
+        return i;
+      }
+    }
+    return expected.length;
+  }
+
   Future<List<CompletionSuggestion>> _computeCompletionSuggestions(
       ResolvedUnitResult resolvedUnitResult,
       int offset,
       CompletionMetrics metrics,
-      [bool useNewRelevance = false]) async {
-    var completionRequestImpl = CompletionRequestImpl(
+      [bool useNewRelevance = false,
+      DeclarationsTracker declarationsTracker,
+      CompletionAvailableSuggestionsParams availableSuggestionsParams]) async {
+    var completionRequest = CompletionRequestImpl(
       resolvedUnitResult,
       offset,
       useNewRelevance,
       CompletionPerformance(),
     );
 
-    var stopwatch = Stopwatch()..start();
+    var suggestions;
 
-    // This gets all of the suggestions with relevances.
-    var suggestions =
-        await DartCompletionManager().computeSuggestions(completionRequestImpl);
+    if (declarationsTracker == null) {
+      // available suggestions == false
+      suggestions = await DartCompletionManager(
+              dartdocDirectiveInfo: DartdocDirectiveInfo())
+          .computeSuggestions(completionRequest);
+    } else {
+      // available suggestions == true
+      var includedElementKinds = <ElementKind>{};
+      var includedElementNames = <String>{};
+      var includedSuggestionRelevanceTagList =
+          <IncludedSuggestionRelevanceTag>[];
+      var includedSuggestionSetList = <IncludedSuggestionSet>[];
+      suggestions = await DartCompletionManager(
+              dartdocDirectiveInfo: DartdocDirectiveInfo(),
+              includedElementKinds: includedElementKinds,
+              includedElementNames: includedElementNames,
+              includedSuggestionRelevanceTags:
+                  includedSuggestionRelevanceTagList)
+          .computeSuggestions(completionRequest);
 
-//    // If a non-null declarationsTracker was passed, use it to call
-//    // computeIncludedSetList, this current implementation just adds the set of
-//    // included element names with relevance 0, future implementations should
-//    // compute out the relevance that clients will set to each value.
-//    if (declarationsTracker != null) {
-//      var includedSuggestionSets = <IncludedSuggestionSet>[];
-//      var includedElementNames = <String>{};
-//
-//      computeIncludedSetList(declarationsTracker, resolvedUnitResult,
-//          includedSuggestionSets, includedElementNames);
-//
-//      for (var eltName in includedElementNames) {
-//        suggestions.add(CompletionSuggestion(
-//            CompletionSuggestionKind.INVOCATION,
-//            0,
-//            eltName,
-//            0,
-//            eltName.length,
-//            false,
-//            false));
-//      }
-//    }
-    stopwatch.stop();
-    metrics.meanCompletionMS.addValue(stopwatch.elapsedMilliseconds);
+      computeIncludedSetList(declarationsTracker, resolvedUnitResult,
+          includedSuggestionSetList, includedElementNames);
+
+      var includedSuggestionSetMap = {
+        for (var includedSuggestionSet in includedSuggestionSetList)
+          includedSuggestionSet.id: includedSuggestionSet,
+      };
+
+      var includedSuggestionRelevanceTagMap = {
+        for (var includedSuggestionRelevanceTag
+            in includedSuggestionRelevanceTagList)
+          includedSuggestionRelevanceTag.tag:
+              includedSuggestionRelevanceTag.relevanceBoost,
+      };
+
+      for (var availableSuggestionSet
+          in availableSuggestionsParams.changedLibraries) {
+        var id = availableSuggestionSet.id;
+        for (var availableSuggestion in availableSuggestionSet.items) {
+          // Exclude available suggestions where this element kind doesn't match
+          // an element kind in includedElementKinds.
+          var elementKind = availableSuggestion.element?.kind;
+          if (elementKind != null &&
+              includedElementKinds.contains(elementKind)) {
+            if (includedSuggestionSetMap.containsKey(id)) {
+              var relevance = includedSuggestionSetMap[id].relevance;
+
+              // Search for any matching relevance tags to apply any boosts
+              if (includedSuggestionRelevanceTagList.isNotEmpty &&
+                  availableSuggestion.relevanceTags != null &&
+                  availableSuggestion.relevanceTags.isNotEmpty) {
+                for (var tag in availableSuggestion.relevanceTags) {
+                  if (includedSuggestionRelevanceTagMap.containsKey(tag)) {
+                    // apply the boost
+                    relevance += includedSuggestionRelevanceTagMap[tag];
+                  }
+                }
+              }
+              suggestions
+                  .add(availableSuggestion.toCompletionSuggestion(relevance));
+            }
+          }
+        }
+      }
+    }
 
     suggestions.sort(completionComparator);
     return suggestions;
@@ -300,30 +535,40 @@
   /// should be captured in the [collector].
   Future<void> _computeInContext(ContextRoot root) async {
     // Create a new collection to avoid consuming large quantities of memory.
-    // TODO(brianwilkerson) Create an OverlayResourceProvider to allow the
-    //  content of the files to be modified before computing suggestions.
     final collection = AnalysisContextCollection(
       includedPaths: root.includedPaths.toList(),
       excludedPaths: root.excludedPaths.toList(),
-      resourceProvider: PhysicalResourceProvider.INSTANCE,
+      resourceProvider: _provider,
     );
+
     var context = collection.contexts[0];
-//    // Set the DeclarationsTracker, only call doWork to build up the available
-//    // suggestions if doComputeCompletionsFromAnalysisServer is true.
-//    // TODO(brianwilkerson) Add a flag to control whether available suggestions
-//    //  are to be used.
-//    var declarationsTracker = DeclarationsTracker(
-//        MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
-//    declarationsTracker.addContext(context);
-//    while (declarationsTracker.hasWork) {
-//      declarationsTracker.doWork();
-//    }
+
+    // Set the DeclarationsTracker, only call doWork to build up the available
+    // suggestions if doComputeCompletionsFromAnalysisServer is true.
+    var declarationsTracker;
+    var availableSuggestionsParams;
+    if (availableSuggestions) {
+      declarationsTracker = DeclarationsTracker(
+          MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
+      declarationsTracker.addContext(context);
+      while (declarationsTracker.hasWork) {
+        declarationsTracker.doWork();
+      }
+
+      // Have the AvailableDeclarationsSet computed to use later.
+      availableSuggestionsParams = createCompletionAvailableSuggestions(
+          declarationsTracker.allLibraries.toList(), []);
+
+      // assert that this object is not null, throw if it is.
+      if (availableSuggestionsParams == null) {
+        throw Exception('availableSuggestionsParam not computable.');
+      }
+    }
 
     // Loop through each file, resolve the file and call
     // forEachExpectedCompletion
     for (var filePath in context.contextRoot.analyzedFiles()) {
       if (AnalysisEngine.isDartFileName(filePath)) {
-        _currentFilePath = filePath;
         try {
           _resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
@@ -339,34 +584,95 @@
 
           // Use the ExpectedCompletionsVisitor to compute the set of expected
           // completions for this CompilationUnit.
-          final visitor = ExpectedCompletionsVisitor();
+          final visitor = ExpectedCompletionsVisitor(filePath);
           _resolvedUnitResult.unit.accept(visitor);
 
           for (var expectedCompletion in visitor.expectedCompletions) {
+            var resolvedUnitResultWithOverlay = _resolvedUnitResult;
+
+            // If an overlay option is being used, compute the overlay file, and
+            // have the context reanalyze the file
+            if (overlay != OVERLAY_NONE) {
+              var overlayContents = _getOverlayContents(
+                  _resolvedUnitResult.content, expectedCompletion, overlay);
+
+              _provider.setOverlay(filePath,
+                  content: overlayContents,
+                  modificationStamp: overlayModificationStamp++);
+              (context as DriverBasedAnalysisContext)
+                  .driver
+                  .changeFile(filePath);
+              resolvedUnitResultWithOverlay =
+                  await context.currentSession.getResolvedUnit(filePath);
+            }
+
             // As this point the completion suggestions are computed,
             // and results are collected with varying settings for
             // comparison:
 
             // First we compute the completions useNewRelevance set to
             // false:
+            var stopwatch = Stopwatch()..start();
             var suggestions = await _computeCompletionSuggestions(
-                _resolvedUnitResult,
+                resolvedUnitResultWithOverlay,
                 expectedCompletion.offset,
                 metricsOldMode,
+                false,
+                declarationsTracker,
+                availableSuggestionsParams);
+            stopwatch.stop();
+
+            var successfulnessUseOldRelevance = forEachExpectedCompletion(
+                expectedCompletion,
+                suggestions,
+                metricsOldMode,
+                stopwatch.elapsedMilliseconds,
                 false);
 
-            forEachExpectedCompletion(
-                expectedCompletion, suggestions, metricsOldMode);
-
             // And again here with useNewRelevance set to true:
+            stopwatch = Stopwatch()..start();
             suggestions = await _computeCompletionSuggestions(
-                _resolvedUnitResult,
+                resolvedUnitResultWithOverlay,
                 expectedCompletion.offset,
                 metricsNewMode,
-                true);
+                true,
+                declarationsTracker,
+                availableSuggestionsParams);
+            stopwatch.stop();
 
-            forEachExpectedCompletion(
-                expectedCompletion, suggestions, metricsNewMode);
+            var successfulnessUseNewRelevance = forEachExpectedCompletion(
+                expectedCompletion,
+                suggestions,
+                metricsNewMode,
+                stopwatch.elapsedMilliseconds,
+                verbose);
+
+            if (verbose &&
+                successfulnessUseOldRelevance !=
+                    successfulnessUseNewRelevance) {
+              if (successfulnessUseNewRelevance &&
+                  !successfulnessUseOldRelevance) {
+                print('    ===========');
+                print(
+                    '    The `useNewRelevance = true` generated a completion that `useNewRelevance = false` did not:');
+                print('    $expectedCompletion');
+                print('    ===========');
+                print('');
+              } else {
+                print('    ===========');
+                print(
+                    '    The `useNewRelevance = false` generated a completion that `useNewRelevance = true` did not:');
+                print('    $expectedCompletion');
+                print('    ===========');
+                print('');
+              }
+            }
+
+            // If an overlay option is being used, remove the overlay applied
+            // earlier
+            if (overlay != OVERLAY_NONE) {
+              _provider.removeOverlay(filePath);
+            }
           }
         } catch (e) {
           print('Exception caught analyzing: $filePath');
@@ -377,6 +683,32 @@
     }
   }
 
+  List<CompletionSuggestion> _filterSuggestions(
+      String prefix, List<CompletionSuggestion> suggestions) {
+    // TODO(brianwilkerson) Replace this with a more realistic filtering algorithm.
+    return suggestions
+        .where((suggestion) => suggestion.completion.startsWith(prefix))
+        .toList();
+  }
+
+  String _getOverlayContents(String contents,
+      ExpectedCompletion expectedCompletion, String overlayMode) {
+    assert(contents.isNotEmpty);
+    var offset = expectedCompletion.offset;
+    var length = expectedCompletion.syntacticEntity.length;
+    assert(offset >= 0);
+    assert(length > 0);
+    if (overlayMode == OVERLAY_REMOVE_TOKEN) {
+      return contents.substring(0, offset) +
+          contents.substring(offset + length);
+    } else if (overlayMode == OVERLAY_REMOVE_REST_OF_FILE) {
+      return contents.substring(0, offset);
+    } else {
+      throw Exception('\'_getOverlayContents\' called with option other than'
+          '$OVERLAY_REMOVE_TOKEN and $OVERLAY_REMOVE_REST_OF_FILE: $overlayMode');
+    }
+  }
+
   /// Given some [ResolvedUnitResult] return the first error of high severity
   /// if such an error exists, `null` otherwise.
   static err.AnalysisError getFirstErrorOrNull(
@@ -401,3 +733,26 @@
     return Place.none();
   }
 }
+
+/// The result of a single completion.
+class CompletionResult {
+  final Place place;
+
+  final List<CompletionSuggestion> suggestions;
+
+  final ExpectedCompletion expectedCompletion;
+
+  final int elapsedMS;
+
+  CompletionResult(
+      this.place, this.suggestions, this.expectedCompletion, this.elapsedMS);
+}
+
+extension AvailableSuggestionsExtension on AvailableSuggestion {
+  // TODO(jwren) I am not sure if we want CompletionSuggestionKind.INVOCATION in
+  // call cases here, to iterate I need to figure out why this algorithm is
+  // taking so much time.
+  CompletionSuggestion toCompletionSuggestion(int relevance) =>
+      CompletionSuggestion(CompletionSuggestionKind.INVOCATION, relevance,
+          label, label.length, 0, element.isDeprecated, false);
+}
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
index 7c0157d..21ff025 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
@@ -138,6 +138,10 @@
   /// A table mapping counter names to counts.
   Map<String, int> simpleCounts = {};
 
+  /// A table mapping the length of identifiers to the number of identifiers
+  /// found of that length.
+  Map<int, int> identifierLengths = {};
+
   /// A table mapping distances from an identifier to the nearest previous token
   /// with the same lexeme to the number of times that distance was found.
   Map<int, int> tokenDistances = {};
@@ -189,6 +193,11 @@
     contextMap[key] = (contextMap[key] ?? 0) + 1;
   }
 
+  /// Record that an identifier of the given [length] was found.
+  void recordIdentifierOfLength(int length) {
+    identifierLengths[length] = (identifierLengths[length] ?? 0) + 1;
+  }
+
   /// Record information about the distance between recurring tokens.
   void recordTokenStream(int distance) {
     tokenDistances[distance] = (tokenDistances[distance] ?? 0) + 1;
@@ -1243,6 +1252,12 @@
   }
 
   @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    data.recordIdentifierOfLength(node.name.length);
+    super.visitSimpleIdentifier(node);
+  }
+
+  @override
   void visitSimpleStringLiteral(SimpleStringLiteral node) {
     // There are no completions.
     super.visitSimpleStringLiteral(node);
@@ -2013,21 +2028,22 @@
       }
     }
 
-    sink.writeln('');
+    sink.writeln();
     _writeCounts(sink, data.simpleCounts);
-    sink.writeln('');
+    sink.writeln();
     _writeSideBySide(sink, [data.byTokenType, data.byElementKind],
         ['Token Types', 'Element Kinds']);
-    sink.writeln('');
+    sink.writeln();
     sink.writeln('Type relationships');
     _writeSideBySide(sink, [first, whole], ['First Token', 'Whole Expression']);
     _writeContextMap(sink, rest);
-    sink.writeln('');
+    sink.writeln();
     sink.writeln('Structural indicators');
     _writeContextMap(sink, data.byDistance);
-    sink.writeln('');
+    sink.writeln();
     sink.writeln('Distance to member (left) by depth of target class (top)');
     _writeMatrix(sink, data.distanceByDepthMap);
+    _writeIdentifierLengths(sink, data.identifierLengths);
     _writeTokenData(sink, data.tokenDistances);
   }
 
@@ -2218,6 +2234,14 @@
     }
   }
 
+  /// Write information about the [lengths] of identifiers to the given [sink].
+  void _writeIdentifierLengths(StringSink sink, Map<int, int> lengths) {
+    sink.writeln();
+    var column = _convertMap('identifier lengths', lengths);
+    var table = _convertColumnsToRows([column]).toList();
+    _writeTable(sink, table);
+  }
+
   /// Write the given [matrix] to the [sink]. The keys of the outer map will be
   /// the row titles; the keys of the inner map will be the column titles.
   void _writeMatrix(StringSink sink, Map<int, Map<int, int>> matrix) {
@@ -2310,7 +2334,7 @@
       secondColumn.add('  $percent%: $i');
     }
 
-    sink.writeln('');
+    sink.writeln();
     sink.writeln('Token stream analysis');
     var table = _convertColumnsToRows([firstColumn, secondColumn]).toList();
     _writeTable(sink, table);
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
new file mode 100644
index 0000000..9d4e2bb
--- /dev/null
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
@@ -0,0 +1,1562 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io' as io;
+
+import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
+import 'package:analysis_server/src/protocol_server.dart'
+    show convertElementToElementKind, ElementKind;
+import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
+import 'package:analysis_server/src/utilities/flutter.dart';
+import 'package:analysis_tool/tools.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart'
+    show ClassElement, Element, LibraryElement;
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:args/args.dart';
+import 'package:meta/meta.dart';
+
+import '../../test/utils/package_root.dart' as package_root;
+
+/// Compute metrics to determine whether they should be used to compute a
+/// relevance score for completion suggestions.
+Future<void> main(List<String> args) async {
+  var parser = createArgParser();
+  var result = parser.parse(args);
+
+  if (validArguments(parser, result)) {
+    var rootPath = result.rest[0];
+    print('Analyzing root: "$rootPath"');
+
+    var provider = PhysicalResourceProvider.INSTANCE;
+    var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
+    var generatedFilePath = provider.pathContext.join(
+        packageRoot,
+        'analysis_server',
+        'lib',
+        'src',
+        'services',
+        'completion',
+        'dart',
+        'relevance_tables.g.dart');
+    var generatedFile = provider.getFile(generatedFilePath);
+
+    var computer = RelevanceMetricsComputer();
+    var stopwatch = Stopwatch();
+    stopwatch.start();
+    await computer.compute(rootPath, verbose: result['verbose']);
+    var buffer = StringBuffer();
+    var writer = RelevanceTableWriter(buffer);
+    writer.write(computer.data);
+    generatedFile.writeAsStringSync(buffer.toString());
+    DartFormat.formatFile(io.File(generatedFile.path));
+    stopwatch.stop();
+
+    var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
+    print('Tables generated in $duration');
+  }
+}
+
+/// Create a parser that can be used to parse the command-line arguments.
+ArgParser createArgParser() {
+  var parser = ArgParser();
+  parser.addFlag(
+    'help',
+    abbr: 'h',
+    help: 'Print this help message.',
+  );
+  parser.addFlag(
+    'verbose',
+    abbr: 'v',
+    help: 'Print additional information about the analysis',
+    negatable: false,
+  );
+  return parser;
+}
+
+/// Print usage information for this tool.
+void printUsage(ArgParser parser, {String error}) {
+  if (error != null) {
+    print(error);
+    print('');
+  }
+  print('usage: dart relevance_table_generator.dart [options] packagePath');
+  print('');
+  print('Generate the tables used to compute the values of certain features.');
+  print('');
+  print(parser.usage);
+}
+
+/// Return `true` if the command-line arguments (represented by the [result] and
+/// parsed by the [parser]) are valid.
+bool validArguments(ArgParser parser, ArgResults result) {
+  if (result.wasParsed('help')) {
+    printUsage(parser);
+    return false;
+  } else if (result.rest.length != 1) {
+    printUsage(parser, error: 'No package path specified.');
+    return false;
+  }
+  var rootPath = result.rest[0];
+  if (!PhysicalResourceProvider.INSTANCE.pathContext.isAbsolute(rootPath)) {
+    printUsage(parser, error: 'The package path must be an absolute path.');
+    return false;
+  }
+  if (!io.Directory(rootPath).existsSync()) {
+    printUsage(parser, error: 'The directory "$rootPath" does not exist.');
+    return false;
+  }
+  return true;
+}
+
+/// An object that records the data used to compute the tables.
+class RelevanceData {
+  /// A table mapping element kinds to counts by context.
+  Map<String, Map<String, int>> byElementKind = {};
+
+  /// A table mapping token types to counts by context.
+  Map<String, Map<String, int>> byTokenType = {};
+
+  /// Initialize a newly created set of relevance data to be empty.
+  RelevanceData();
+
+  /// Add the data from the given relevance [data] to this set of data.
+  void addDataFrom(RelevanceData data) {
+    _addToMap(byElementKind, data.byElementKind);
+    _addToMap(byTokenType, data.byTokenType);
+  }
+
+  /// Record that an element of the given [kind] was found in the given
+  /// [context].
+  void recordElementKind(String context, ElementKind kind) {
+    var contextMap = byElementKind.putIfAbsent(context, () => {});
+    var key = kind.name;
+    contextMap[key] = (contextMap[key] ?? 0) + 1;
+  }
+
+  /// Record that a token of the given [type] was found in the given [context].
+  void recordTokenType(String context, TokenType type) {
+    var contextMap = byTokenType.putIfAbsent(context, () => {});
+    var key = type.name;
+    contextMap[key] = (contextMap[key] ?? 0) + 1;
+  }
+
+  /// Add the data in the [source] map to the [target] map.
+  void _addToMap<K>(Map<K, Map<K, int>> target, Map<K, Map<K, int>> source) {
+    for (var outerEntry in source.entries) {
+      var innerTarget = target.putIfAbsent(outerEntry.key, () => {});
+      for (var innerEntry in outerEntry.value.entries) {
+        var innerKey = innerEntry.key;
+        innerTarget[innerKey] = (innerTarget[innerKey] ?? 0) + innerEntry.value;
+      }
+    }
+  }
+}
+
+/// An object that visits a compilation unit in order to record the data used to
+/// compute the metrics.
+class RelevanceDataCollector extends RecursiveAstVisitor<void> {
+  static const List<Keyword> declarationKeywords = [
+    Keyword.MIXIN,
+    Keyword.TYPEDEF
+  ];
+
+  static const List<Keyword> directiveKeywords = [
+    Keyword.EXPORT,
+    Keyword.IMPORT,
+    Keyword.LIBRARY,
+    Keyword.PART
+  ];
+
+  static const List<Keyword> exportKeywords = [
+    Keyword.AS,
+    Keyword.HIDE,
+    Keyword.SHOW
+  ];
+
+  static const List<Keyword> expressionKeywords = [
+    Keyword.AWAIT,
+    Keyword.SUPER
+  ];
+
+  static const List<Keyword> functionBodyKeywords = [
+    Keyword.ASYNC,
+    Keyword.SYNC
+  ];
+
+  static const List<Keyword> importKeywords = [
+    Keyword.AS,
+    Keyword.HIDE,
+    Keyword.SHOW
+  ];
+
+  static const List<Keyword> memberKeywords = [
+    Keyword.FACTORY,
+    Keyword.GET,
+    Keyword.OPERATOR,
+    Keyword.SET,
+    Keyword.STATIC
+  ];
+
+  static const List<Keyword> noKeywords = [];
+
+  static const List<Keyword> statementKeywords = [Keyword.AWAIT, Keyword.YIELD];
+
+  /// The relevance data being collected.
+  final RelevanceData data;
+
+  /// The compilation unit in which data is currently being collected.
+  CompilationUnit unit;
+
+  /// The object used to determine Flutter-specific features.
+  Flutter flutter;
+
+  InheritanceManager3 inheritanceManager = InheritanceManager3();
+
+  /// The library containing the compilation unit being visited.
+  LibraryElement enclosingLibrary;
+
+  /// The type provider associated with the current compilation unit.
+  TypeProvider typeProvider;
+
+  /// The type system associated with the current compilation unit.
+  TypeSystem typeSystem;
+
+  /// The object used to compute the values of features.
+  FeatureComputer featureComputer;
+
+  /// Initialize a newly created collector to add data points to the given
+  /// [data].
+  RelevanceDataCollector(this.data);
+
+  /// Initialize this collector prior to visiting the unit in the [result].
+  void initializeFrom(ResolvedUnitResult result) {
+    unit = result.unit;
+    flutter = Flutter.of(result);
+  }
+
+  @override
+  void visitAdjacentStrings(AdjacentStrings node) {
+    // There are no completions.
+    super.visitAdjacentStrings(node);
+  }
+
+  @override
+  void visitAnnotation(Annotation node) {
+    _recordDataForNode('Annotation_name', node.name);
+    super.visitAnnotation(node);
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    var context = _argumentListContext(node);
+    for (var argument in node.arguments) {
+      var realArgument = argument;
+      var argumentKind = 'unnamed';
+      if (argument is NamedExpression) {
+        realArgument = argument.expression;
+        argumentKind = 'named';
+      }
+      _recordDataForNode('ArgumentList_${context}_$argumentKind', realArgument,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitArgumentList(node);
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    _recordDataForNode('AsExpression_type', node.type);
+    super.visitAsExpression(node);
+  }
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {
+    _recordDataForNode('AssertInitializer_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('AssertInitializer_message', node.message,
+        allowedKeywords: expressionKeywords);
+    super.visitAssertInitializer(node);
+  }
+
+  @override
+  void visitAssertStatement(AssertStatement node) {
+    _recordDataForNode('AssertStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('AssertStatement_message', node.message,
+        allowedKeywords: expressionKeywords);
+    super.visitAssertStatement(node);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    _recordDataForNode('AssignmentExpression_rightHandSide', node.rightHandSide,
+        allowedKeywords: expressionKeywords);
+    super.visitAssignmentExpression(node);
+  }
+
+  @override
+  void visitAwaitExpression(AwaitExpression node) {
+    _recordDataForNode('AwaitExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitAwaitExpression(node);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    _recordDataForNode(
+        'BinaryExpression_${node.operator}_rightOperand', node.rightOperand,
+        allowedKeywords: expressionKeywords);
+    super.visitBinaryExpression(node);
+  }
+
+  @override
+  void visitBlock(Block node) {
+    for (var statement in node.statements) {
+      // Function declaration statements that have no return type begin with an
+      // identifier but don't have an element kind associated with the
+      // identifier.
+      _recordDataForNode('Block_statement', statement,
+          allowedKeywords: statementKeywords);
+    }
+    super.visitBlock(node);
+  }
+
+  @override
+  void visitBlockFunctionBody(BlockFunctionBody node) {
+    _recordTokenType('BlockFunctionBody_start', node,
+        allowedKeywords: functionBodyKeywords);
+    super.visitBlockFunctionBody(node);
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    _recordTokenType('BooleanLiteral_start', node);
+    super.visitBooleanLiteral(node);
+  }
+
+  @override
+  void visitBreakStatement(BreakStatement node) {
+    // The token following the `break` (if there is one) is always a label.
+    super.visitBreakStatement(node);
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    for (var cascade in node.cascadeSections) {
+      _recordDataForNode('CascadeExpression_cascadeSection', cascade);
+    }
+    super.visitCascadeExpression(node);
+  }
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    _recordDataForNode('CatchClause_exceptionType', node.exceptionType);
+    super.visitCatchClause(node);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    var context = 'name';
+    if (node.extendsClause != null) {
+      _recordTokenType('ClassDeclaration_$context', node.extendsClause,
+          allowedKeywords: [Keyword.EXTENDS]);
+      context = 'extends';
+    }
+    if (node.withClause != null) {
+      _recordTokenType('ClassDeclaration_$context', node.withClause);
+      context = 'with';
+    }
+    _recordTokenType('ClassDeclaration_$context', node.implementsClause,
+        allowedKeywords: [Keyword.IMPLEMENTS]);
+
+    for (var member in node.members) {
+      _recordDataForNode('ClassDeclaration_member', member,
+          allowedKeywords: memberKeywords);
+    }
+    super.visitClassDeclaration(node);
+  }
+
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    _recordDataForNode('ClassTypeAlias_superclass', node.superclass);
+    var context = 'superclass';
+    if (node.withClause != null) {
+      _recordTokenType('ClassTypeAlias_$context', node.withClause);
+      context = 'with';
+    }
+    _recordTokenType('ClassTypeAlias_$context', node.implementsClause);
+    super.visitClassTypeAlias(node);
+  }
+
+  @override
+  void visitComment(Comment node) {
+    // There are no completions.
+    super.visitComment(node);
+  }
+
+  @override
+  void visitCommentReference(CommentReference node) {
+    void recordDataForCommentReference(String context, AstNode node) {
+      _recordElementKind(context, node);
+      _recordTokenType(context, node);
+    }
+
+    recordDataForCommentReference(
+        'CommentReference_identifier', node.identifier);
+    super.visitCommentReference(node);
+  }
+
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    enclosingLibrary = node.declaredElement.library;
+    typeProvider = enclosingLibrary.typeProvider;
+    typeSystem = enclosingLibrary.typeSystem;
+    inheritanceManager = InheritanceManager3();
+    featureComputer = FeatureComputer(typeSystem, typeProvider);
+
+    for (var directive in node.directives) {
+      _recordTokenType('CompilationUnit_directive', directive,
+          allowedKeywords: directiveKeywords);
+    }
+    for (var declaration in node.declarations) {
+      _recordDataForNode('CompilationUnit_declaration', declaration,
+          allowedKeywords: declarationKeywords);
+    }
+    super.visitCompilationUnit(node);
+
+    featureComputer = null;
+    inheritanceManager = null;
+    typeSystem = null;
+    typeProvider = null;
+    enclosingLibrary = null;
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    _recordDataForNode(
+        'ConditionalExpression_thenExpression', node.thenExpression,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode(
+        'ConditionalExpression_elseExpression', node.elseExpression,
+        allowedKeywords: expressionKeywords);
+    super.visitConditionalExpression(node);
+  }
+
+  @override
+  void visitConfiguration(Configuration node) {
+    // There are no completions.
+    super.visitConfiguration(node);
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    _recordDataForNode('ConstructorDeclaration_returnType', node.returnType);
+    for (var initializer in node.initializers) {
+      _recordDataForNode('ConstructorDeclaration_initializer', initializer);
+    }
+    super.visitConstructorDeclaration(node);
+  }
+
+  @override
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    _recordDataForNode(
+        'ConstructorFieldInitializer_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitConstructorFieldInitializer(node);
+  }
+
+  @override
+  void visitConstructorName(ConstructorName node) {
+    // The token following the `.` is always the name of a constructor.
+    super.visitConstructorName(node);
+  }
+
+  @override
+  void visitContinueStatement(ContinueStatement node) {
+    // The token following the `continue` (if there is one) is always a label.
+    super.visitContinueStatement(node);
+  }
+
+  @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    // There are no completions.
+    super.visitDeclaredIdentifier(node);
+  }
+
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _recordDataForNode('DefaultFormalParameter_defaultValue', node.defaultValue,
+        allowedKeywords: expressionKeywords);
+    super.visitDefaultFormalParameter(node);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    _recordDataForNode('DoStatement_body', node.body,
+        allowedKeywords: statementKeywords);
+    _recordDataForNode('DoStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    super.visitDoStatement(node);
+  }
+
+  @override
+  void visitDottedName(DottedName node) {
+    // The components are always identifiers.
+    super.visitDottedName(node);
+  }
+
+  @override
+  void visitDoubleLiteral(DoubleLiteral node) {
+    // There are no completions.
+    super.visitDoubleLiteral(node);
+  }
+
+  @override
+  void visitEmptyFunctionBody(EmptyFunctionBody node) {
+    // There are no completions.
+    super.visitEmptyFunctionBody(node);
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {
+    // There are no completions.
+    super.visitEmptyStatement(node);
+  }
+
+  @override
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    // There are no completions.
+    super.visitEnumConstantDeclaration(node);
+  }
+
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {
+    // There are no completions.
+    super.visitEnumDeclaration(node);
+  }
+
+  @override
+  void visitExportDirective(ExportDirective node) {
+    var context = 'uri';
+    if (node.configurations.isNotEmpty) {
+      _recordTokenType('ImportDirective_$context', node.configurations[0],
+          allowedKeywords: exportKeywords);
+      context = 'configurations';
+    }
+    if (node.combinators.isNotEmpty) {
+      _recordTokenType('ImportDirective_$context', node.combinators[0],
+          allowedKeywords: exportKeywords);
+    }
+    for (var combinator in node.combinators) {
+      _recordTokenType('ImportDirective_combinator', combinator,
+          allowedKeywords: exportKeywords);
+    }
+    super.visitExportDirective(node);
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _recordTokenType('ExpressionFunctionBody_start', node,
+        allowedKeywords: functionBodyKeywords);
+    _recordDataForNode('ExpressionFunctionBody_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitExpressionFunctionBody(node);
+  }
+
+  @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    _recordDataForNode('ExpressionStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitExpressionStatement(node);
+  }
+
+  @override
+  void visitExtendsClause(ExtendsClause node) {
+    _recordDataForNode('ExtendsClause_superclass', node.superclass);
+    super.visitExtendsClause(node);
+  }
+
+  @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    _recordDataForNode('ExtensionDeclaration_extendedType', node.extendedType);
+    for (var member in node.members) {
+      _recordDataForNode('ExtensionDeclaration_member', member,
+          allowedKeywords: memberKeywords);
+    }
+    super.visitExtensionDeclaration(node);
+  }
+
+  @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    // There are no completions.
+    super.visitExtensionOverride(node);
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    // There are no completions.
+    super.visitFieldDeclaration(node);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    // The completions after `this.` are always existing fields.
+    super.visitFieldFormalParameter(node);
+  }
+
+  @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _recordDataForNode(
+        'ForEachPartsWithDeclaration_loopVariable', node.loopVariable);
+    _recordDataForNode('ForEachPartsWithDeclaration_iterable', node.iterable,
+        allowedKeywords: expressionKeywords);
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    _recordDataForNode(
+        'ForEachPartsWithIdentifier_identifier', node.identifier);
+    _recordDataForNode('ForEachPartsWithIdentifier_iterable', node.iterable,
+        allowedKeywords: expressionKeywords);
+    super.visitForEachPartsWithIdentifier(node);
+  }
+
+  @override
+  void visitForElement(ForElement node) {
+    _recordTokenType('ForElement_parts', node.forLoopParts);
+    _recordDataForNode('ForElement_body', node.body);
+    super.visitForElement(node);
+  }
+
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    for (var parameter in node.parameters) {
+      _recordDataForNode('FormalParameterList_parameter', parameter,
+          allowedKeywords: [Keyword.COVARIANT]);
+    }
+    super.visitFormalParameterList(node);
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _recordDataForNode('ForParts_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    for (var updater in node.updaters) {
+      _recordDataForNode('ForParts_updater', updater,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitForPartsWithDeclarations(node);
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    _recordDataForNode('ForParts_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    for (var updater in node.updaters) {
+      _recordDataForNode('ForParts_updater', updater,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitForPartsWithExpression(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    _recordTokenType('ForElement_parts', node.forLoopParts);
+    _recordDataForNode('ForElement_body', node.body,
+        allowedKeywords: statementKeywords);
+    super.visitForStatement(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    // There are no completions.
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    // There are no completions.
+    super.visitFunctionDeclarationStatement(node);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // There are no completions.
+    super.visitFunctionExpression(node);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    // There are no completions.
+    super.visitFunctionExpressionInvocation(node);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    // There are no completions.
+    super.visitFunctionTypeAlias(node);
+  }
+
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    // There are no completions.
+    super.visitFunctionTypedFormalParameter(node);
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    // There are no completions.
+    super.visitGenericFunctionType(node);
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    _recordDataForNode('GenericTypeAlias_functionType', node.functionType,
+        allowedKeywords: [Keyword.FUNCTION]);
+    super.visitGenericTypeAlias(node);
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    for (var hiddenName in node.hiddenNames) {
+      _recordDataForNode('HideCombinator_hiddenName', hiddenName);
+    }
+    super.visitHideCombinator(node);
+  }
+
+  @override
+  void visitIfElement(IfElement node) {
+    _recordDataForNode('IfElement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('IfElement_thenElement', node.thenElement);
+    _recordDataForNode('IfElement_elseElement', node.elseElement);
+    super.visitIfElement(node);
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    _recordDataForNode('IfStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('IfStatement_then', node.thenStatement,
+        allowedKeywords: statementKeywords);
+    _recordDataForNode('IfStatement_else', node.elseStatement,
+        allowedKeywords: statementKeywords);
+    super.visitIfStatement(node);
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    // At the start of each type name.
+    for (var typeName in node.interfaces) {
+      _recordDataForNode('ImplementsClause_interface', typeName);
+    }
+    super.visitImplementsClause(node);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    var context = 'uri';
+    if (node.deferredKeyword != null) {
+      data.recordTokenType(
+          'ImportDirective_$context', node.deferredKeyword.type);
+      context = 'deferred';
+    }
+    if (node.asKeyword != null) {
+      data.recordTokenType('ImportDirective_$context', node.asKeyword.type);
+      context = 'prefix';
+    }
+    if (node.configurations.isNotEmpty) {
+      _recordTokenType('ImportDirective_$context', node.configurations[0],
+          allowedKeywords: importKeywords);
+      context = 'configurations';
+    }
+    if (node.combinators.isNotEmpty) {
+      _recordTokenType('ImportDirective_$context', node.combinators[0],
+          allowedKeywords: importKeywords);
+    }
+    for (var combinator in node.combinators) {
+      _recordTokenType('ImportDirective_combinator', combinator,
+          allowedKeywords: importKeywords);
+    }
+    super.visitImportDirective(node);
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    _recordDataForNode('IndexExpression_index', node.index,
+        allowedKeywords: expressionKeywords);
+    super.visitIndexExpression(node);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    // There are no completions.
+    super.visitInstanceCreationExpression(node);
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    // There are no completions.
+    super.visitIntegerLiteral(node);
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    // TODO(brianwilkerson) Consider splitting this based on whether the
+    //  expression is a simple identifier ('$') or a full expression ('${').
+    _recordDataForNode('InterpolationExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitInterpolationExpression(node);
+  }
+
+  @override
+  void visitInterpolationString(InterpolationString node) {
+    // There are no completions.
+    super.visitInterpolationString(node);
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    _recordDataForNode('IsExpression_type', node.type);
+    super.visitIsExpression(node);
+  }
+
+  @override
+  void visitLabel(Label node) {
+    // There are no completions.
+    super.visitLabel(node);
+  }
+
+  @override
+  void visitLabeledStatement(LabeledStatement node) {
+    _recordDataForNode('LabeledStatement_statement', node.statement,
+        allowedKeywords: statementKeywords);
+    super.visitLabeledStatement(node);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    // There are no completions.
+    super.visitLibraryDirective(node);
+  }
+
+  @override
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    // There are no completions.
+    super.visitLibraryIdentifier(node);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    for (var element in node.elements) {
+      _recordDataForNode('ListLiteral_element', element,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitListLiteral(node);
+  }
+
+  @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    _recordDataForNode('MapLiteralEntry_value', node.value,
+        allowedKeywords: expressionKeywords);
+    super.visitMapLiteralEntry(node);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    // There are no completions.
+    super.visitMethodDeclaration(node);
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    // There are no completions.
+    super.visitMethodInvocation(node);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    var context = 'name';
+    if (node.onClause != null) {
+      _recordTokenType('MixinDeclaration_$context', node.onClause,
+          allowedKeywords: [Keyword.ON]);
+      context = 'on';
+    }
+    _recordTokenType('MixinDeclaration_$context', node.implementsClause,
+        allowedKeywords: [Keyword.IMPLEMENTS]);
+
+    for (var member in node.members) {
+      _recordDataForNode('MixinDeclaration_member', member,
+          allowedKeywords: memberKeywords);
+    }
+    super.visitMixinDeclaration(node);
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression node) {
+    // Named expressions only occur in argument lists and are handled there.
+    super.visitNamedExpression(node);
+  }
+
+  @override
+  void visitNativeClause(NativeClause node) {
+    // There are no completions.
+    super.visitNativeClause(node);
+  }
+
+  @override
+  void visitNativeFunctionBody(NativeFunctionBody node) {
+    // There are no completions.
+    super.visitNativeFunctionBody(node);
+  }
+
+  @override
+  void visitNullLiteral(NullLiteral node) {
+    // There are no completions.
+    super.visitNullLiteral(node);
+  }
+
+  @override
+  void visitOnClause(OnClause node) {
+    for (var constraint in node.superclassConstraints) {
+      _recordDataForNode('OnClause_superclassConstraint', constraint);
+    }
+    super.visitOnClause(node);
+  }
+
+  @override
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    _recordDataForNode('ParenthesizedExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitParenthesizedExpression(node);
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    // There are no completions.
+    super.visitPartDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    // There are no completions.
+    super.visitPartOfDirective(node);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    // There are no completions.
+    super.visitPostfixExpression(node);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    // There are no completions.
+    super.visitPrefixedIdentifier(node);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    _recordDataForNode(
+        'PrefixExpression_${node.operator}_operand', node.operand,
+        allowedKeywords: expressionKeywords);
+    super.visitPrefixExpression(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    _recordDataForNode('PropertyAccess_propertyName', node.propertyName);
+    super.visitPropertyAccess(node);
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    // There are no completions.
+    super.visitRedirectingConstructorInvocation(node);
+  }
+
+  @override
+  void visitRethrowExpression(RethrowExpression node) {
+    // There are no completions.
+    super.visitRethrowExpression(node);
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    _recordDataForNode('ReturnStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    if (node.expression == null) {
+      data.recordTokenType('ReturnStatement_expression', node.semicolon.type);
+    }
+    super.visitReturnStatement(node);
+  }
+
+  @override
+  void visitScriptTag(ScriptTag node) {
+    // There are no completions.
+    super.visitScriptTag(node);
+  }
+
+  @override
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    for (var element in node.elements) {
+      _recordDataForNode('SetOrMapLiteral_element', element,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitSetOrMapLiteral(node);
+  }
+
+  @override
+  void visitShowCombinator(ShowCombinator node) {
+    for (var name in node.shownNames) {
+      _recordDataForNode('ShowCombinator_shownName', name);
+    }
+    super.visitShowCombinator(node);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    // There are no completions.
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    // There are no completions.
+    super.visitSimpleStringLiteral(node);
+  }
+
+  @override
+  void visitSpreadElement(SpreadElement node) {
+    _recordDataForNode('SpreadElement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitSpreadElement(node);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    // There are no completions.
+    super.visitStringInterpolation(node);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    // There are no completions.
+    super.visitSuperConstructorInvocation(node);
+  }
+
+  @override
+  void visitSuperExpression(SuperExpression node) {
+    // There are no completions.
+    super.visitSuperExpression(node);
+  }
+
+  @override
+  void visitSwitchCase(SwitchCase node) {
+    _recordDataForNode('SwitchCase_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    for (var statement in node.statements) {
+      _recordDataForNode('SwitchMember_statement', statement,
+          allowedKeywords: statementKeywords);
+    }
+    super.visitSwitchCase(node);
+  }
+
+  @override
+  void visitSwitchDefault(SwitchDefault node) {
+    for (var statement in node.statements) {
+      _recordDataForNode('SwitchMember_statement', statement,
+          allowedKeywords: statementKeywords);
+    }
+    super.visitSwitchDefault(node);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    _recordDataForNode('SwitchStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitSwitchStatement(node);
+  }
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    // There are no completions.
+    super.visitSymbolLiteral(node);
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    // There are no completions.
+    super.visitThisExpression(node);
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    _recordDataForNode('ThrowExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitThrowExpression(node);
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    // There are no completions.
+    super.visitTopLevelVariableDeclaration(node);
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    var context = 'try';
+    for (var clause in node.catchClauses) {
+      _recordTokenType('TryStatement_$context', clause,
+          allowedKeywords: [Keyword.ON]);
+      context = 'catch';
+    }
+    if (node.finallyKeyword != null) {
+      data.recordTokenType('TryStatement_$context', node.finallyKeyword.type);
+    }
+    super.visitTryStatement(node);
+  }
+
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    for (var typeArgument in node.arguments) {
+      _recordDataForNode('TypeArgumentList_argument', typeArgument);
+    }
+    super.visitTypeArgumentList(node);
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    // There are no completions.
+    super.visitTypeName(node);
+  }
+
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    if (node.bound != null) {
+      _recordDataForNode('TypeParameter_bound', node.bound);
+    }
+    super.visitTypeParameter(node);
+  }
+
+  @override
+  void visitTypeParameterList(TypeParameterList node) {
+    // There are no completions.
+    super.visitTypeParameterList(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    var keywords = node.parent.parent is FieldDeclaration
+        ? [Keyword.COVARIANT, ...expressionKeywords]
+        : expressionKeywords;
+    _recordDataForNode('VariableDeclaration_initializer', node.initializer,
+        allowedKeywords: keywords);
+    super.visitVariableDeclaration(node);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    // There are no completions.
+    super.visitVariableDeclarationList(node);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    // There are no completions.
+    super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    _recordDataForNode('WhileStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('WhileStatement_body', node.body,
+        allowedKeywords: statementKeywords);
+    super.visitWhileStatement(node);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    for (var typeName in node.mixinTypes) {
+      _recordDataForNode('WithClause_mixinType', typeName);
+    }
+    super.visitWithClause(node);
+  }
+
+  @override
+  void visitYieldStatement(YieldStatement node) {
+    _recordDataForNode('YieldStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitYieldStatement(node);
+  }
+
+  /// Return the context in which the [node] occurs. The [node] is expected to
+  /// be the parent of the argument expression.
+  String _argumentListContext(AstNode node) {
+    if (node is ArgumentList) {
+      var parent = node.parent;
+      if (parent is Annotation) {
+        return 'annotation';
+      } else if (parent is ExtensionOverride) {
+        return 'extensionOverride';
+      } else if (parent is FunctionExpressionInvocation) {
+        return 'function';
+      } else if (parent is InstanceCreationExpression) {
+        if (flutter.isWidgetType(parent.staticType)) {
+          return 'widgetConstructor';
+        }
+        return 'constructor';
+      } else if (parent is MethodInvocation) {
+        return 'method';
+      } else if (parent is RedirectingConstructorInvocation) {
+        return 'constructorRedirect';
+      } else if (parent is SuperConstructorInvocation) {
+        return 'constructorRedirect';
+      }
+    } else if (node is AssignmentExpression ||
+        node is BinaryExpression ||
+        node is PrefixExpression ||
+        node is PostfixExpression) {
+      return 'operator';
+    } else if (node is IndexExpression) {
+      return 'index';
+    }
+    throw ArgumentError(
+        'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
+  }
+
+  /// Return the first child of the [node] that is neither a comment nor an
+  /// annotation.
+  SyntacticEntity _firstChild(AstNode node) {
+    var children = node.childEntities.toList();
+    for (var i = 0; i < children.length; i++) {
+      var child = children[i];
+      if (child is! Comment && child is! Annotation) {
+        return child;
+      }
+    }
+    return null;
+  }
+
+  /// Return the element associated with the left-most identifier that is a
+  /// child of the [node].
+  Element _leftMostElement(AstNode node) =>
+      _leftMostIdentifier(node)?.staticElement;
+
+  /// Return the left-most child of the [node] if it is a simple identifier, or
+  /// `null` if the left-most child is not a simple identifier. Comments and
+  /// annotations are ignored for this purpose.
+  SimpleIdentifier _leftMostIdentifier(AstNode node) {
+    var currentNode = node;
+    while (currentNode != null && currentNode is! SimpleIdentifier) {
+      var firstChild = _firstChild(currentNode);
+      if (firstChild is AstNode) {
+        currentNode = firstChild;
+      } else {
+        currentNode = null;
+      }
+    }
+    if (currentNode is SimpleIdentifier && currentNode.inDeclarationContext()) {
+      return null;
+    }
+    return currentNode;
+  }
+
+  /// Return the element kind of the element associated with the left-most
+  /// identifier that is a child of the [node].
+  ElementKind _leftMostKind(AstNode node) {
+    if (node is InstanceCreationExpression) {
+      return convertElementToElementKind(node.staticElement);
+    }
+    var element = _leftMostElement(node);
+    if (element == null) {
+      return null;
+    }
+    if (element is ClassElement) {
+      var parent = node.parent;
+      if (parent is Annotation && parent.arguments != null) {
+        element = parent.element;
+      }
+    }
+    return convertElementToElementKind(element);
+  }
+
+  /// Return the left-most token that is a child of the [node].
+  Token _leftMostToken(AstNode node) {
+    SyntacticEntity entity = node;
+    while (entity is AstNode) {
+      entity = _firstChild(entity as AstNode);
+    }
+    if (entity is Token) {
+      return entity;
+    }
+    return null;
+  }
+
+  /// Record information about the given [node] occurring in the given
+  /// [context].
+  void _recordDataForNode(String context, AstNode node,
+      {List<Keyword> allowedKeywords = noKeywords}) {
+    _recordElementKind(context, node);
+    _recordTokenType(context, node, allowedKeywords: allowedKeywords);
+  }
+
+  /// Record the element kind of the element associated with the left-most
+  /// identifier that is a child of the [node] in the given [context].
+  void _recordElementKind(String context, AstNode node) {
+    if (node != null) {
+      var kind = _leftMostKind(node);
+      if (kind != null) {
+        data.recordElementKind(context, kind);
+        if (node is Expression) {
+          data.recordElementKind('Expression', kind);
+        } else if (node is Statement) {
+          data.recordElementKind('Statement', kind);
+        }
+      }
+    }
+  }
+
+  /// Record the token type of the left-most token that is a child of the
+  /// [node] in the given [context].
+  void _recordTokenType(String context, AstNode node,
+      {List<Keyword> allowedKeywords = noKeywords}) {
+    if (node != null) {
+      var token = _leftMostToken(node);
+      if (token != null) {
+        var type = token.type;
+        if (token.isKeyword && token.keyword.isBuiltInOrPseudo) {
+          // These keywords can be used as identifiers, so determine whether it
+          // is being used as a keyword or an identifier.
+          if (!allowedKeywords.contains(token.keyword)) {
+            type = TokenType.IDENTIFIER;
+          }
+        }
+        data.recordTokenType(context, type);
+        if (node is Expression) {
+          data.recordTokenType('Expression', type);
+        } else if (node is Statement) {
+          data.recordTokenType('Statement', type);
+        }
+      }
+    }
+  }
+}
+
+/// An object used to compute metrics for a single file or directory.
+class RelevanceMetricsComputer {
+  /// The metrics data that was computed.
+  final RelevanceData data = RelevanceData();
+
+  /// Initialize a newly created metrics computer that can compute the metrics
+  /// in one or more files and directories.
+  RelevanceMetricsComputer();
+
+  /// Compute the metrics for the file(s) in the [rootPath].
+  /// If [corpus] is true, treat rootPath as a container of packages, creating
+  /// a new context collection for each subdirectory.
+  void compute(String rootPath, {@required bool verbose}) async {
+    final collection = AnalysisContextCollection(
+      includedPaths: [rootPath],
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
+    );
+    final collector = RelevanceDataCollector(data);
+    for (var context in collection.contexts) {
+      await _computeInContext(context.contextRoot, collector, verbose: verbose);
+    }
+  }
+
+  /// Compute the metrics for the files in the context [root], creating a
+  /// separate context collection to prevent accumulating memory. The metrics
+  /// should be captured in the [collector]. Include additional details in the
+  /// output if [verbose] is `true`.
+  void _computeInContext(ContextRoot root, RelevanceDataCollector collector,
+      {@required bool verbose}) async {
+    // Create a new collection to avoid consuming large quantities of memory.
+    final collection = AnalysisContextCollection(
+      includedPaths: root.includedPaths.toList(),
+      excludedPaths: root.excludedPaths.toList(),
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
+    );
+    var context = collection.contexts[0];
+    for (var filePath in context.contextRoot.analyzedFiles()) {
+      if (AnalysisEngine.isDartFileName(filePath)) {
+        try {
+          var resolvedUnitResult =
+              await context.currentSession.getResolvedUnit(filePath);
+          //
+          // Check for errors that cause the file to be skipped.
+          //
+          if (resolvedUnitResult == null) {
+            print('File $filePath skipped because resolved unit was null.');
+            if (verbose) {
+              print('');
+            }
+            continue;
+          } else if (resolvedUnitResult.state != ResultState.VALID) {
+            print('File $filePath skipped because it could not be analyzed.');
+            if (verbose) {
+              print('');
+            }
+            continue;
+          } else if (hasError(resolvedUnitResult)) {
+            if (verbose) {
+              print('File $filePath skipped due to errors:');
+              for (var error in resolvedUnitResult.errors
+                  .where((e) => e.severity == Severity.error)) {
+                print('  ${error.toString()}');
+              }
+              print('');
+            } else {
+              print('File $filePath skipped due to analysis errors.');
+            }
+            continue;
+          }
+
+          collector.initializeFrom(resolvedUnitResult);
+          resolvedUnitResult.unit.accept(collector);
+        } catch (exception, stacktrace) {
+          print('Exception caught analyzing: "$filePath"');
+          print(exception);
+          print(stacktrace);
+        }
+      }
+    }
+  }
+
+  /// Return `true` if the [result] contains an error.
+  static bool hasError(ResolvedUnitResult result) {
+    for (var error in result.errors) {
+      if (error.severity == Severity.error) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/// A class used to write relevance data as a set of tables in a generated Dart
+/// file.
+class RelevanceTableWriter {
+  final StringSink sink;
+
+  RelevanceTableWriter(this.sink);
+
+  int totalCount(Map<String, int> counts) {
+    return counts.values
+        .fold(0, (previousValue, value) => previousValue + value);
+  }
+
+  void write(RelevanceData data) {
+    writeFileHeader();
+    writeElementKindTable(data);
+  }
+
+  void writeElementKindTable(RelevanceData data) {
+    var byTokenType = data.byTokenType;
+    var byElementKind = data.byElementKind;
+
+    sink.writeln();
+    sink.write('''
+/// A table keyed by completion location and element kind whose values are the
+/// ranges of the relevance of those element kinds in those locations.
+const elementKindRelevance = {
+''');
+
+    var completionLocations = byElementKind.keys.toList()..sort();
+    for (var completionLocation in completionLocations) {
+      var elementCounts = byElementKind[completionLocation];
+      var identifierPercent = 1.0;
+      var tokenCounts = byTokenType[completionLocation];
+      if (tokenCounts != null) {
+        var identifierCount = tokenCounts['IDENTIFIER'];
+        if (identifierCount != null) {
+          var totalTokenCount = totalCount(tokenCounts);
+          identifierPercent = identifierCount / totalTokenCount;
+        }
+      }
+      // TODO(brianwilkerson) This incorrectly assumes that identifiers are
+      //  always the most common first token in a completion location.
+      var startOfBand = 1.0 - identifierPercent;
+      sink.write("  '");
+      sink.write(completionLocation);
+      sink.writeln("': {");
+      var totalElementCount = totalCount(elementCounts);
+      var cumulativeCount = 0;
+      // TODO(brianwilkerson) If two element kinds have the same count they
+      //  ought to have the same probability. This doesn't correctly do that.
+      var entries = elementCounts.entries.toList()
+        ..sort((first, second) => first.value.compareTo(second.value));
+      var lowerBound = 0.0;
+      for (var entry in entries) {
+        var elementKind = entry.key;
+        cumulativeCount += entry.value;
+        var percentInBand = cumulativeCount / totalElementCount;
+        var upperBound = (percentInBand * identifierPercent) + startOfBand;
+        sink.write('    ElementKind.');
+        sink.write(elementKind);
+        sink.write(': ProbabilityRange(lower: ');
+        sink.write(lowerBound.toStringAsFixed(3));
+        sink.write(', upper: ');
+        sink.write(upperBound.toStringAsFixed(3));
+        sink.writeln('),');
+        lowerBound = upperBound;
+      }
+      sink.writeln('  },');
+    }
+    sink.writeln('};');
+  }
+
+  void writeFileHeader() {
+    sink.write('''
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart",
+// passing it the location of a corpus of code that is large enough for the
+// computed values to be statistically meaningful.
+
+import 'package:analysis_server/src/services/completion/dart/probability_range.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+''');
+  }
+}
+
+class Timer {
+  Stopwatch stopwatch = Stopwatch();
+
+  int count = 0;
+
+  Timer();
+
+  double get averageTime => count == 0 ? 0 : totalTime / count;
+
+  int get totalTime => stopwatch.elapsedMilliseconds;
+
+  void start() {
+    stopwatch.start();
+  }
+
+  void stop() {
+    stopwatch.stop();
+    count++;
+  }
+}
diff --git a/pkg/analysis_server/tool/completion_metrics/visitors.dart b/pkg/analysis_server/tool/completion_metrics/visitors.dart
index dcb21a8..f154a6d 100644
--- a/pkg/analysis_server/tool/completion_metrics/visitors.dart
+++ b/pkg/analysis_server/tool/completion_metrics/visitors.dart
@@ -11,6 +11,8 @@
 import 'package:analyzer/dart/element/element.dart' as element;
 
 class ExpectedCompletion {
+  final String _filePath;
+
   final SyntacticEntity _entity;
 
   /// Some completions are special cased from the DAS "import" for instance is
@@ -26,11 +28,12 @@
 
   final protocol.ElementKind _elementKind;
 
-  ExpectedCompletion(this._entity, this._lineNumber, this._columnNumber,
-      this._kind, this._elementKind)
+  ExpectedCompletion(this._filePath, this._entity, this._lineNumber,
+      this._columnNumber, this._kind, this._elementKind)
       : _completionString = null;
 
   ExpectedCompletion.specialCompletionString(
+      this._filePath,
       this._entity,
       this._lineNumber,
       this._columnNumber,
@@ -44,10 +47,14 @@
 
   protocol.ElementKind get elementKind => _elementKind;
 
+  String get filePath => _filePath;
+
   protocol.CompletionSuggestionKind get kind => _kind;
 
   int get lineNumber => _lineNumber;
 
+  String get location => '$filePath:$lineNumber:$columnNumber';
+
   int get offset => _entity.offset;
 
   SyntacticEntity get syntacticEntity => _entity;
@@ -68,11 +75,17 @@
     }
     return false;
   }
+
+  @override
+  String toString() =>
+      "'$completion', kind = $kind, elementKind = $elementKind, $location";
 }
 
 class ExpectedCompletionsVisitor extends RecursiveAstVisitor<void> {
   final List<ExpectedCompletion> expectedCompletions;
 
+  final String filePath;
+
   CompilationUnit _enclosingCompilationUnit;
 
   /// This boolean is set to enable whether or not we should assert that some
@@ -88,7 +101,9 @@
   /// comment don't yield an error like Dart syntax mistakes would yield.
   final bool _doExpectCommentRefs = false;
 
-  ExpectedCompletionsVisitor() : expectedCompletions = <ExpectedCompletion>[];
+  ExpectedCompletionsVisitor(this.filePath)
+      : expectedCompletions = <ExpectedCompletion>[],
+        assert(filePath != null);
 
   void safelyRecordEntity(SyntacticEntity entity,
       {protocol.CompletionSuggestionKind kind,
@@ -108,9 +123,16 @@
       // DAS is "import '';" which we want to be sure to match.
       if (entity.toString() == 'async') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
-            entity, lineNumber, columnNumber, ASYNC_STAR, kind, elementKind));
+            filePath,
+            entity,
+            lineNumber,
+            columnNumber,
+            ASYNC_STAR,
+            kind,
+            elementKind));
       } else if (entity.toString() == 'default') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
+            filePath,
             entity,
             lineNumber,
             columnNumber,
@@ -119,9 +141,16 @@
             elementKind));
       } else if (entity.toString() == 'deferred') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
-            entity, lineNumber, columnNumber, DEFERRED_AS, kind, elementKind));
+            filePath,
+            entity,
+            lineNumber,
+            columnNumber,
+            DEFERRED_AS,
+            kind,
+            elementKind));
       } else if (entity.toString() == 'export') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
+            filePath,
             entity,
             lineNumber,
             columnNumber,
@@ -130,6 +159,7 @@
             elementKind));
       } else if (entity.toString() == 'import') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
+            filePath,
             entity,
             lineNumber,
             columnNumber,
@@ -138,6 +168,7 @@
             elementKind));
       } else if (entity.toString() == 'part') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
+            filePath,
             entity,
             lineNumber,
             columnNumber,
@@ -146,13 +177,25 @@
             elementKind));
       } else if (entity.toString() == 'sync') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
-            entity, lineNumber, columnNumber, SYNC_STAR, kind, elementKind));
+            filePath,
+            entity,
+            lineNumber,
+            columnNumber,
+            SYNC_STAR,
+            kind,
+            elementKind));
       } else if (entity.toString() == 'yield') {
         expectedCompletions.add(ExpectedCompletion.specialCompletionString(
-            entity, lineNumber, columnNumber, YIELD_STAR, kind, elementKind));
+            filePath,
+            entity,
+            lineNumber,
+            columnNumber,
+            YIELD_STAR,
+            kind,
+            elementKind));
       } else {
         expectedCompletions.add(ExpectedCompletion(
-            entity, lineNumber, columnNumber, kind, elementKind));
+            filePath, entity, lineNumber, columnNumber, kind, elementKind));
       }
     }
   }
@@ -528,7 +571,7 @@
     if (_doIncludeSimpleIdentifier(node)) {
       var elementKind;
       if (node.staticElement?.kind != null) {
-        elementKind = protocol.convertElementKind(node.staticElement?.kind);
+        elementKind = protocol.convertElementKind(node.staticElement.kind);
 
         // If the completed element kind is a getter or setter set the element
         // kind to null as the exact kind from the DAS is unknown at this
@@ -551,6 +594,27 @@
         if (node.parent is FieldFormalParameter) {
           elementKind = protocol.ElementKind.FIELD;
         }
+
+        // Class references that are constructor calls are constructor kinds,
+        // unless either:
+        //   1) the constructor is a named constructor, i.e. some "Foo.bar()",
+        //      the "Foo" in this case is a class,
+        //   2) or, there is an explicit const or new keyword before the
+        //      constructor invocation in which case the "Foo" above is
+        //      considered a constructor still
+        if (elementKind == protocol.ElementKind.CLASS) {
+          if (node.parent?.parent is ConstructorName) {
+            var constructorName = node.parent.parent as ConstructorName;
+            var instanceCreationExpression = constructorName.parent;
+            if (instanceCreationExpression is InstanceCreationExpression &&
+                constructorName.type.name == node) {
+              if (instanceCreationExpression.keyword != null ||
+                  constructorName.name == null) {
+                elementKind = protocol.ElementKind.CONSTRUCTOR;
+              }
+            }
+          }
+        }
       }
       safelyRecordEntity(node, elementKind: elementKind);
     }
@@ -644,6 +708,12 @@
     if (node == null || node.isSynthetic || node.inDeclarationContext()) {
       return false;
     }
+
+    // If the type of the SimpleIdentifier is dynamic, don't include.
+    if (node.staticType != null && node.staticType.isDynamic) {
+      return false;
+    }
+
     // If we are in a comment reference context, return if we should include
     // such identifiers.
     if (node.thisOrAncestorOfType<CommentReference>() != null) {
@@ -661,16 +731,17 @@
     // Named arguments, i.e. the 'foo' in 'method_call(foo: 1)' should not be
     // included, by design, the completion engine won't suggest named arguments
     // already it the source.
-    if (node.staticElement?.kind == element.ElementKind.PARAMETER &&
+    //
+    // The null check, node.staticElement == null, handles the cases where the
+    // invocation is unknown, i.e. the 'arg' in 'foo.bar(arg: 1)', where foo is
+    // dynamic.
+    if ((node.staticElement == null ||
+            node.staticElement?.kind == element.ElementKind.PARAMETER) &&
         node.parent is Label &&
         node.thisOrAncestorOfType<ArgumentList>() != null) {
       return false;
     }
 
-    // If the type of the SimpleIdentifier is dynamic, don't include.
-    if (node.staticType != null && node.staticType.isDynamic) {
-      return false;
-    }
     return true;
   }
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index da5c60f..3208c04 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -46,7 +46,7 @@
 | window/logMessage | ✅ | | | |
 | telemetry/event | | | | |
 | client/registerCapability | ✅ | ✅ | ✅ | ✅ |
-| client/unregisterCapability | | | | | (unused, capabilities don't change currently)
+| client/unregisterCapability | ✅ | ✅ | ✅ | | Capabilities only change when using analyzer plugins
 | workspace/workspaceFolders | | | | |
 | workspace/didChangeWorkspaceFolders | ✅ | ✅ | ✅ | ✅ |
 | workspace/configuration | | | | |
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 4533588..23df9cc 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -348,24 +348,16 @@
     ..writeIndentedln('@override')
     ..writeIndentedln('bool operator ==(Object other) {')
     ..indent()
-    ..writeIndentedln('if (other is ${interface.name}) {')
+    // We want an exact type match, but also need `is` to have the analyzer
+    // promote the type to allow access to the fields on `other`.
+    ..writeIndentedln(
+        'if (other is ${interface.name} && other.runtimeType == ${interface.name}) {')
     ..indent()
     ..writeIndented('return ');
   for (var field in _getAllFields(interface)) {
-    final type = field.type;
-    if (type is ArrayType) {
-      final elementType = type.elementType;
-      final elementDartType = elementType.dartTypeWithTypeArgs;
-      buffer.write(
-          'listEqual(${field.name}, other.${field.name}, ($elementDartType a, $elementDartType b) => a == b) && ');
-    } else if (type is MapType) {
-      final valueType = type.valueType;
-      final valueDartType = valueType.dartTypeWithTypeArgs;
-      buffer.write(
-          'mapEqual(${field.name}, other.${field.name}, ($valueDartType a, $valueDartType b) => a == b) && ');
-    } else {
-      buffer.write('${field.name} == other.${field.name} && ');
-    }
+    final type = resolveTypeAlias(field.type);
+    _writeEqualsExpression(buffer, type, field.name, 'other.${field.name}');
+    buffer.write(' && ');
   }
   buffer
     ..writeln('true;')
@@ -376,6 +368,27 @@
     ..writeIndentedln('}');
 }
 
+void _writeEqualsExpression(IndentableStringBuffer buffer, TypeBase type,
+    String thisName, String otherName) {
+  if (type is ArrayType) {
+    final elementType = type.elementType;
+    final elementDartType = elementType.dartTypeWithTypeArgs;
+    buffer.write(
+        'listEqual($thisName, $otherName, ($elementDartType a, $elementDartType b) => ');
+    _writeEqualsExpression(buffer, elementType, 'a', 'b');
+    buffer.write(')');
+  } else if (type is MapType) {
+    final valueType = type.valueType;
+    final valueDartType = valueType.dartTypeWithTypeArgs;
+    buffer.write(
+        'mapEqual($thisName, $otherName, ($valueDartType a, $valueDartType b) => ');
+    _writeEqualsExpression(buffer, valueType, 'a', 'b');
+    buffer.write(')');
+  } else {
+    buffer.write('$thisName == $otherName');
+  }
+}
+
 void _writeField(IndentableStringBuffer buffer, Field field) {
   _writeDocCommentsAndAnnotations(buffer, field);
   buffer
diff --git a/pkg/analysis_server/tool/nnbd_migration/check_generated_test.dart b/pkg/analysis_server/tool/nnbd_migration/check_generated_test.dart
deleted file mode 100644
index 8c0f118..0000000
--- a/pkg/analysis_server/tool/nnbd_migration/check_generated_test.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-
-import 'generate_resources.dart' as generate_resources;
-
-/// Validate that the
-/// pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
-/// file was regenerated after changing upstream dependencies.
-void main() async {
-  test('description', () {
-    generate_resources.verifyResourcesGDartGenerated(failVerification: fail);
-  });
-}
diff --git a/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart b/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
deleted file mode 100644
index cdc22c5..0000000
--- a/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
+++ /dev/null
@@ -1,263 +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 script generates the
-// lib/src/edit/nnbd_migration/resources/resources.g.dart file from the contents
-// of the lib/src/edit/nnbd_migration/resources directory.
-
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math' as math;
-
-import 'package:args/args.dart';
-import 'package:crypto/crypto.dart';
-import 'package:path/path.dart' as path;
-
-void main(List<String> args) async {
-  var argParser = ArgParser()
-    ..addFlag('verify', negatable: false)
-    ..addFlag('dev', negatable: false)
-    ..addFlag('help', negatable: false);
-  var argResults = argParser.parse(args);
-  if (argResults['help'] == true) {
-    fail('''
-usage: dart pkg/analysis_server/tool/nnbd_migration/generate_resources.dart [--verify]
-
-Run with no args to generate web resources for the NNBD migration preview tool.
-Run with '--verify' to validate that the web resource have been regenerated.
-''');
-  }
-
-  if (FileSystemEntity.isFileSync(
-      path.join('tool', 'nnbd_migration', 'generate_resources.dart'))) {
-    // We're running from the project root - cd up two directories.
-    Directory.current = Directory.current.parent.parent;
-  } else if (!FileSystemEntity.isDirectorySync(
-      path.join('pkg', 'analysis_server'))) {
-    fail('Please run this tool from the root of the sdk repo.');
-  }
-
-  bool verify = argResults['verify'];
-  bool dev = argResults['dev'];
-
-  if (verify) {
-    verifyResourcesGDartGenerated();
-  } else {
-    await compileWebFrontEnd(devMode: dev);
-
-    print('');
-
-    createResourcesGDart();
-  }
-}
-
-final File dartSources = File(path.join('pkg', 'analysis_server', 'lib', 'src',
-    'edit', 'nnbd_migration', 'web', 'migration.dart'));
-
-final javascriptOutput = File(path.join('pkg', 'analysis_server', 'lib', 'src',
-    'edit', 'nnbd_migration', 'resources', 'migration.js'));
-
-final Directory resourceDir = Directory(path.join('pkg', 'analysis_server',
-    'lib', 'src', 'edit', 'nnbd_migration', 'resources'));
-
-final File resourcesFile = File(path.join('pkg', 'analysis_server', 'lib',
-    'src', 'edit', 'nnbd_migration', 'resources', 'resources.g.dart'));
-
-final List<String> resourceTypes = [
-  '.css',
-  '.html',
-  '.js',
-];
-
-String base64Encode(List<int> bytes) {
-  var encoded = base64.encode(bytes);
-
-  // Logic to cut lines into 80-character chunks.
-  var lines = <String>[];
-  var index = 0;
-
-  while (index < encoded.length) {
-    var line = encoded.substring(index, math.min(index + 80, encoded.length));
-    lines.add(line);
-    index += line.length;
-  }
-
-  return lines.join('\n');
-}
-
-void compileWebFrontEnd({bool devMode = false}) async {
-  var sdkBinDir = path.dirname(Platform.resolvedExecutable);
-  var dart2jsPath = path.join(sdkBinDir, 'dart2js');
-
-  // dart2js -m -o output source
-  var process = await Process.start(dart2jsPath, [
-    devMode ? '-O1' : '-m',
-    '--no-frequency-based-minification',
-    '-o',
-    javascriptOutput.path,
-    dartSources.path,
-  ]);
-  process.stdout.listen((List<int> data) => stdout.add(data));
-  process.stderr.listen((List<int> data) => stderr.add(data));
-  var exitCode = await process.exitCode;
-
-  if (exitCode != 0) {
-    fail('Failed compiling ${dartSources.path}.');
-  }
-}
-
-void createResourcesGDart() {
-  var content =
-      generateResourceFile(sortDir(resourceDir.listSync()).where((entity) {
-    var name = path.basename(entity.path);
-    return entity is File && resourceTypes.contains(path.extension(name));
-  }).cast<File>());
-
-  // write the content
-  resourcesFile.writeAsStringSync(content);
-}
-
-void fail(String message) {
-  stderr.writeln(message);
-  exit(1);
-}
-
-/// Fail the script, and print out a message indicating how to regenerate the
-/// resources file.
-void failGenerate(String message) {
-  stderr.writeln('$message.');
-  stderr.writeln();
-  stderr.writeln('''
-To re-generate lib/src/edit/nnbd_migration/resources/resources.g.dart, run:
-
-  dart pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
-''');
-  exit(1);
-}
-
-String generateResourceFile(Iterable<File> resources) {
-  var filePath = path.relative(Platform.script.toFilePath());
-  var buf = StringBuffer('''
-// 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 is generated; don't edit it directly.
-//
-// See $filePath for how
-// to edit the source content and for re-generation instructions.
-
-import 'dart:convert' as convert;
-''');
-
-  for (var resource in resources) {
-    var name = path.basename(resource.path).replaceAll('.', '_');
-    print('adding $name...');
-
-    buf.writeln();
-    buf.writeln('String get $name {');
-    buf.writeln('  return _$name ??= _decode(_${name}_base64);');
-    buf.writeln('}');
-  }
-
-  buf.writeln(r'''
-
-String _decode(String data) {
-  data = data.replaceAll('\n', '').trim();
-  return String.fromCharCodes(convert.base64Decode(data));
-}''');
-
-  for (var resource in resources) {
-    var name = path.basename(resource.path).replaceAll('.', '_');
-    var source = resource.readAsStringSync();
-
-    var delimiter = "'''";
-
-    buf.writeln();
-    buf.writeln('String _$name;');
-    if (name == path.basename(javascriptOutput.path).replaceAll('.', '_')) {
-      // Write out the crc for the dart code.
-      var sourceCode = StringBuffer();
-      // collect the dart source code
-      for (var entity in sortDir(dartSources.parent.listSync())) {
-        if (entity.path.endsWith('.dart')) {
-          sourceCode.write((entity as File).readAsStringSync());
-        }
-      }
-      buf.writeln(
-          "// migration_dart md5 is '${md5String(sourceCode.toString())}'");
-    } else {
-      // highlight_css md5 is 'fb012626bafd286510d32da815dae448'
-      buf.writeln("// $name md5 is '${md5String(source)}'");
-    }
-    buf.writeln('String _${name}_base64 = $delimiter');
-    buf.writeln(base64Encode(source.codeUnits));
-    buf.writeln('$delimiter;');
-  }
-
-  return buf.toString();
-}
-
-String md5String(String str) {
-  return md5.convert(str.codeUnits).toString();
-}
-
-List<FileSystemEntity> sortDir(Iterable<FileSystemEntity> entities) {
-  var result = entities.toList();
-  result.sort((a, b) => a.path.compareTo(b.path));
-  return result;
-}
-
-void verifyResourcesGDartGenerated({
-  VerificationFunction failVerification = failGenerate,
-}) {
-  print('Verifying that ${path.basename(resourcesFile.path)} is up-to-date...');
-
-  // Find the hashes for the last generated version of resources.g.dart.
-  var resourceHashes = <String, String>{};
-  // highlight_css md5 is 'fb012626bafd286510d32da815dae448'
-  var hashPattern = RegExp(r"// (\S+) md5 is '(\S+)'");
-  for (var match in hashPattern.allMatches(resourcesFile.readAsStringSync())) {
-    resourceHashes[match.group(1)] = match.group(2);
-  }
-
-  // For all resources (modulo compiled JS ones), verify the hash.
-  for (var entity in sortDir(resourceDir.listSync())) {
-    var name = path.basename(entity.path);
-    if (!resourceTypes.contains(path.extension(name))) {
-      continue;
-    }
-
-    if (name == 'migration.js') {
-      // skip the compiled js
-      continue;
-    }
-
-    var key = name.replaceAll('.', '_');
-    if (!resourceHashes.containsKey(key)) {
-      failVerification('No entry on resources.g.dart for $name');
-    } else {
-      var hash = md5String((entity as File).readAsStringSync());
-      if (hash != resourceHashes[key]) {
-        failVerification('$name not up to date in resources.g.dart');
-      }
-    }
-  }
-
-  // verify the compiled dart code
-  var sourceCode = StringBuffer();
-  for (var entity in sortDir(dartSources.parent.listSync())) {
-    if (entity.path.endsWith('.dart')) {
-      sourceCode.write((entity as File).readAsStringSync());
-    }
-  }
-  var hash = md5String(sourceCode.toString());
-  if (hash != resourceHashes['migration_dart']) {
-    failVerification('Compiled javascript not up to date in resources.g.dart');
-  }
-
-  print('Generated resources up to date.');
-}
-
-typedef VerificationFunction = void Function(String);
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 59f2af9..058ac50 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1002,7 +1002,7 @@
       </field>
     </params>
   </notification>
-  <notification event="closingLabels" experimental="true">
+  <notification event="closingLabels">
     <p>
       Reports closing labels relevant to a given file.
     </p>
diff --git a/pkg/analysis_server_client/CHANGELOG.md b/pkg/analysis_server_client/CHANGELOG.md
index 144b255..43563a1 100644
--- a/pkg/analysis_server_client/CHANGELOG.md
+++ b/pkg/analysis_server_client/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 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. 
+
 # 1.1.2
  * Update the dartfix protocol to include `--pedantic`
  * Supports changes made to Analysis Server protocol through Dart 2.6.0
diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml
index e661389..bc8b89f 100644
--- a/pkg/analysis_server_client/pubspec.yaml
+++ b/pkg/analysis_server_client/pubspec.yaml
@@ -6,9 +6,9 @@
   and facilitate communication to and from the server.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server_client
 environment:
-  sdk: '>=2.1.0-dev.9.0 <3.0.0'
+  sdk: '>=2.8.0 <3.0.0'
 dependencies:
-  path: ^1.6.2
-  pub_semver: ^1.4.2
+  path: ^1.7.0
+  pub_semver: ^1.4.4
 dev_dependencies:
-  test: ^1.3.4
+  test: ^1.14.2
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 743a14a..0680d6b 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,12 +1,77 @@
-## 0.39.5-dev
+## 0.39.8
+* Deprecated `VariableElement.constantValue`, it does not guarantee that
+  the value has been computed. Use `computeConstantValue()` instead.
+* Deprecated the following members of `AnalysisOptions`:
+  `analyzeFunctionBodiesPredicate`, `disableCacheFlushing`,
+  `enableLazyAssignmentOperators`, `generateImplicitErrors`,
+  `generateSdkErrors`, `patchPaths`, `preserveComments`,
+  `trackCacheDependencies`, and `resetToDefaults`.
+* Bug fixes: #35716, #37048, #40014, #40957, #41479, #41521, #41551, #41555,
+  #41557, #41593, #41603, #41630, #41632, #41645.
+
+## 0.39.7
+* Added new error codes: ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING and
+  THROW_OF_INVALID_TYPE.
+* Changed error code NULLABLE_TYPE_IN_CATCH_CLAUSE to a hint.
+* Bug fixes: #40554, #41378, #41399, #41412, and, #41470.
+
+## 0.39.6
+* Added Window and DocumentFragment to analyzer's mock SDK.  These are required
+  for upcoming changes to the unsafe_html lint.
+
+## 0.39.5
 * Deprecated `ClassElement.instantiateToBounds()` and
   `FunctionTypeAliasElement.instantiateToBounds()`. With the null-safety
   feature, type arguments derived from type parameter bounds cannot be used as
   is, and might require erasing nullability, when the element is instantiated
   from a legacy library. Use `TypeSystem.instantiateToBounds2()` instead.
-* Deprecated `DeclaredVariables.getBool/getInt/getString()`. These methods
-  are used internally for constants computation, and should not be used by
-  clients.
+* Deprecated `DeclaredVariables.getBool/getInt/getString()` and
+  `TypeProvider.nullObject`. These methods are used internally for constants
+  computation, and should not be used by clients.
+* Deprecated `AstFactory.indexExpressionForCascade()`.  Please use
+  `indexExpressionForCascade2` instead.
+* Deprecated `AstFactory.indexExpressionForTarget()`.  Please use
+  `indexExpressionForTarget2` instead.
+* Deprecated `ClassElement.isOrInheritsProxy` and `ClassElement.isProxy`.  The
+  `@proxy` annotation is deprecated in the langauge, and will be removed.
+* Added new error codes: BODY_MIGHT_COMPLETE_NORMALLY,
+  CASE_EXPRESSION_TYPE_IS_NOT_SWITCH_EXPRESSION_SUBTYPE,
+  DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, LATE_FINAL_LOCAL_ALREADY_ASSIGNED,
+  SWITCH_CASE_COMPLETES_NORMALLY, EXTERNAL_CONSTRUCTOR_WITH_INITIALIZER,
+  FINAL_AND_COVARIANT_LATE_WITH_INITIALIZER, GETTER_CONSTRUCTOR,
+  MEMBER_WITH_CLASS_NAME, SETTER_CONSTRUCTOR, TYPE_PARAMETER_ON_OPERATOR, and
+  VOID_WITH_TYPE_ARGUMENTS.
+* Renamed error code DEFAULT_LIST_CONSTRUCTOR_MISMATCH to
+  DEFAULT_LIST_CONSTRUCTOR.  This reflects a spec change: after null safety is
+  enabled, it will be an error to call the default `List` constructor under all
+  circumstances.
+* Added new warning code: INVALID_NULL_AWARE_OPERATOR.
+* Renamed warning code DEAD_NULL_COALESCE to DEAD_NULL_AWARE_EXPRESSION, to
+  reflect the fact that it applies both to if-null expressions (`??`) and
+  if-null compound assignment expressions (`??=`).
+* Split warning code MISMATCHED_GETTER_AND_SETTER_TYPES into two codes:
+  GETTER_NOT_ASSIGNABLE_SETTER_TYPES and GETTER_NOT_SUBTYPE_SETTER_TYPES.
+* Coalesced warning codes UNNECESSARY_NULL_AWARE_CALL and
+  UNNECESSARY_NULL_AWARE_SPREAD into one warning code:
+  INVALID_NULL_AWARE_OPERATOR.
+* Added new hint codes: EQUAL_ELEMENTS_IN_SET, EQUAL_KEYS_IN_MAP,
+  INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION, UNNECESSARY_NULL_COMPARISON_FALSE,
+  and UNNECESSARY_NULL_COMPARISON_TRUE.
+* Downgraded warning INVALID_USE_OF_NEVER_VALUE to hint RECEIVER_OF_TYPE_NEVER.
+* Re-introduced strong mode codes: DYNAMIC_INVOKE, IMPLICIT_DYNAMIC_FIELD,
+  IMPLICIT_DYNAMIC_FUNCTION, IMPLICIT_DYNAMIC_INVOKE,
+  IMPLICIT_DYNAMIC_LIST_LITERAL, IMPLICIT_DYNAMIC_MAP_LITERAL,
+  IMPLICIT_DYNAMIC_METHOD, IMPLICIT_DYNAMIC_PARAMETER, IMPLICIT_DYNAMIC_RETURN,
+  IMPLICIT_DYNAMIC_TYPE, and IMPLICIT_DYNAMIC_VARIABLE.  These were removed in
+  version 0.39.3, but it turns out they are actually needed (see
+  https://github.com/dart-lang/sdk/issues/40129).
+* Fixed bugs 35940, 37122, 38554, 38666, 38791, 38990, 39059, 39597, 39694,
+  39762, 39791, 39833, 39875, 39876, 39917, 39939, 39976, 40033, 40055, 40057,
+  40110, 40129, 40221, 40279, 40283, 40287, 40299, 40304, 40316, 40333, 40392,
+  40394, 40396, 40398, 40413, 40414, 40460, 40482, 40500, 40538, 40546, 40547,
+  40572, 40578, 40603, 40609, 40677, 40689, 40701, 40704, 40734, 40764, 40837,
+  40865, 40915, 40931, 40941, 40955, 40956, 40958, 40959, 41019, 41036, 41050,
+  41095, 41130, and 41180.
 
 ## 0.39.4
 * Deprecated `DartType.name`, use `element` or `getDisplayString()` instead.
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index 561a4db..1d46e72 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -70,8 +70,8 @@
   /// Queries whether the given [feature] is contained in this feature set.
   bool isEnabled(Feature feature);
 
-  /// Computes a subset of this FeatureSet by removing any features that weren't
-  /// available in the given Dart SDK version.
+  /// Computes a subset of this FeatureSet by removing any features that are
+  /// not available in the given language version.
   FeatureSet restrictToVersion(Version version);
 }
 
@@ -82,7 +82,7 @@
   future,
 
   /// The language feature has not yet shipped, but we are testing the effect of
-  /// enabling it by default.  It may be used in any library with an appopriate
+  /// enabling it by default.  It may be used in any library with an appropriate
   /// version constraint, unless an experimental flag is used to disable it.
   provisional,
 
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 4841b13..308face 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1735,6 +1735,7 @@
   /// Return `null` if either this variable was not declared with the 'const'
   /// modifier or if the value of this variable could not be computed because of
   /// errors.
+  @Deprecated('Use computeConstantValue() instead')
   DartObject get constantValue;
 
   @override
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index bbcdc16..1ecfb41 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -137,6 +137,7 @@
   CompileTimeErrorCode.DUPLICATE_DEFINITION,
   CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
   CompileTimeErrorCode.DUPLICATE_PART,
+  CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
   CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET,
   CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP,
   CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
@@ -269,7 +270,6 @@
   CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
   CompileTimeErrorCode.NOT_MAP_SPREAD,
   CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
-  CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
   CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE,
   CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE,
   CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE,
@@ -293,6 +293,7 @@
   CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH,
   CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
   CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+  CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
   CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
   CompileTimeErrorCode.REDIRECT_TO_NON_CLASS,
   CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
@@ -308,6 +309,7 @@
   CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
   CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
   CompileTimeErrorCode.SWITCH_CASE_COMPLETES_NORMALLY,
+  CompileTimeErrorCode.THROW_OF_INVALID_TYPE,
   CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
   CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
   // ignore: deprecated_member_use_from_same_package
@@ -420,6 +422,7 @@
   HintCode.NULL_AWARE_BEFORE_OPERATOR,
   HintCode.NULL_AWARE_IN_CONDITION,
   HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR,
+  HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
   HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
   HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD,
   HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index 8d313c8..5d5bf1a 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -57,11 +57,9 @@
 }
 
 /**
- * Use the given [resourceProvider], [contentCache] and command-line [args] to
- * create a context builder.
+ * Use the command-line [args] to create a context builder.
  */
-ContextBuilderOptions createContextBuilderOptions(ArgResults args,
-    {bool trackCacheDependencies}) {
+ContextBuilderOptions createContextBuilderOptions(ArgResults args) {
   ContextBuilderOptions builderOptions = ContextBuilderOptions();
   builderOptions.argResults = args;
   //
@@ -77,9 +75,6 @@
   //
   AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
   applyAnalysisOptionFlags(defaultOptions, args);
-  if (trackCacheDependencies != null) {
-    defaultOptions.trackCacheDependencies = trackCacheDependencies;
-  }
   builderOptions.defaultOptions = defaultOptions;
   //
   // Declared variables.
diff --git a/pkg/analyzer/lib/src/context/packages.dart b/pkg/analyzer/lib/src/context/packages.dart
index 8d79d78..8ea6b3b 100644
--- a/pkg/analyzer/lib/src/context/packages.dart
+++ b/pkg/analyzer/lib/src/context/packages.dart
@@ -158,4 +158,20 @@
 
   /// Return the [Package] with the given [name], or `null`.
   Package operator [](String name) => _map[name];
+
+  /// Return the inner-most [Package] that contains  the [path], `null` if none.
+  Package packageForPath(String path) {
+    Package result;
+    int resultPathLength;
+    for (var package in packages) {
+      if (package.rootFolder.contains(path)) {
+        var packagePathLength = package.rootFolder.path.length;
+        if (result == null || resultPathLength < packagePathLength) {
+          result = package;
+          resultPathLength = packagePathLength;
+        }
+      }
+    }
+    return result;
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 1066383..0ece485 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -91,7 +91,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 = 100;
+  static const int DATA_VERSION = 101;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
@@ -445,7 +445,7 @@
         _unitElementRequestedParts.isNotEmpty) {
       return AnalysisDriverPriority.general;
     }
-    _libraryContext = null;
+    _clearLibraryContext();
     return AnalysisDriverPriority.nothing;
   }
 
@@ -1173,7 +1173,7 @@
     _throwIfNotAbsolutePath(path);
     _throwIfChangesAreNotAllowed();
     _fileTracker.removeFile(path);
-    _libraryContext = null;
+    _clearLibraryContext();
     _priorityResults.clear();
   }
 
@@ -1188,7 +1188,7 @@
   /// Implementation for [changeFile].
   void _changeFile(String path) {
     _fileTracker.changeFile(path);
-    _libraryContext = null;
+    _clearLibraryContext();
     _priorityResults.clear();
   }
 
@@ -1196,17 +1196,27 @@
   /// of state.
   void _changeHook(String path) {
     _createNewSession(path);
-    _libraryContext = null;
+    _clearLibraryContext();
     _priorityResults.clear();
     _scheduler.notify(this);
   }
 
+  /// Clear the library context and any related data structures. Mostly we do
+  /// this to reduce memory consumption. The library context holds to every
+  /// library that was resynthesized, but after some initial analysis we might
+  /// not get again to many of these libraries. So, we should clear the context
+  /// periodically.
+  void _clearLibraryContext() {
+    _libraryContext = null;
+    _currentSession.clearHierarchies();
+  }
+
   /// There was an exception during a file analysis, we don't know why.
   /// But it might have been caused by an inconsistency of files state, and
   /// the library context state. Reset the library context, and hope that
   /// we will solve the inconsistency while loading / building summaries.
   void _clearLibraryContextAfterException() {
-    _libraryContext = null;
+    _clearLibraryContext();
   }
 
   /// Return the cached or newly computed analysis result of the file with the
@@ -1497,7 +1507,7 @@
   LibraryContext _createLibraryContext(FileState library) {
     if (_libraryContext != null) {
       if (_libraryContext.pack()) {
-        _libraryContext = null;
+        _clearLibraryContext();
       }
     }
 
@@ -1588,35 +1598,9 @@
       FileState file, List<AnalysisDriverUnitError> serialized) {
     List<AnalysisError> errors = <AnalysisError>[];
     for (AnalysisDriverUnitError error in serialized) {
-      String errorName = error.uniqueName;
-      ErrorCode errorCode =
-          errorCodeByUniqueName(errorName) ?? _lintCodeByUniqueName(errorName);
-      if (errorCode == null) {
-        // This could fail because the error code is no longer defined, or, in
-        // the case of a lint rule, if the lint rule has been disabled since the
-        // errors were written.
-        AnalysisEngine.instance.instrumentationService
-            .logError('No error code for "$error" in "$file"');
-      } else {
-        List<DiagnosticMessageImpl> contextMessages;
-        if (error.contextMessages.isNotEmpty) {
-          contextMessages = <DiagnosticMessageImpl>[];
-          for (var message in error.contextMessages) {
-            contextMessages.add(DiagnosticMessageImpl(
-                filePath: message.filePath,
-                length: message.length,
-                message: message.message,
-                offset: message.offset));
-          }
-        }
-        errors.add(AnalysisError.forValues(
-            file.source,
-            error.offset,
-            error.length,
-            errorCode,
-            error.message,
-            error.correction.isEmpty ? null : error.correction,
-            contextMessages: contextMessages ?? const []));
+      var analysisError = ErrorEncoding.decode(file.source, error);
+      if (analysisError != null) {
+        errors.add(analysisError);
       }
     }
     return errors;
@@ -1637,24 +1621,6 @@
     return signature.toHex();
   }
 
-  /// Return the lint code with the given [errorName], or `null` if there is no
-  /// lint registered with that name.
-  ErrorCode _lintCodeByUniqueName(String errorName) {
-    const String lintPrefix = 'LintCode.';
-    if (errorName.startsWith(lintPrefix)) {
-      String lintName = errorName.substring(lintPrefix.length);
-      return linter.Registry.ruleRegistry.getRule(lintName)?.lintCode;
-    }
-
-    const String lintPrefixOld = '_LintCode.';
-    if (errorName.startsWith(lintPrefixOld)) {
-      String lintName = errorName.substring(lintPrefixOld.length);
-      return linter.Registry.ruleRegistry.getRule(lintName)?.lintCode;
-    }
-
-    return null;
-  }
-
   /// We detected that one of the required `dart` libraries is missing.
   /// Return the empty analysis result with the error.
   AnalysisResult _newMissingDartLibraryResult(
@@ -1705,24 +1671,7 @@
         : AnalysisDriverUnitIndexBuilder();
     return AnalysisDriverResolvedUnitBuilder(
             errors: errors.map((error) {
-              List<DiagnosticMessageBuilder> contextMessages;
-              if (error.contextMessages != null) {
-                contextMessages = <DiagnosticMessageBuilder>[];
-                for (var message in error.contextMessages) {
-                  contextMessages.add(DiagnosticMessageBuilder(
-                      filePath: message.filePath,
-                      length: message.length,
-                      message: message.message,
-                      offset: message.offset));
-                }
-              }
-              return AnalysisDriverUnitErrorBuilder(
-                  offset: error.offset,
-                  length: error.length,
-                  uniqueName: error.errorCode.uniqueName,
-                  message: error.message,
-                  correction: error.correction,
-                  contextMessages: contextMessages);
+              return ErrorEncoding.encode(error);
             }).toList(),
             index: index)
         .toBuffer();
@@ -2117,6 +2066,94 @@
   void removedDriver(AnalysisDriver driver);
 }
 
+class ErrorEncoding {
+  static AnalysisError decode(
+    Source source,
+    AnalysisDriverUnitError error,
+  ) {
+    String errorName = error.uniqueName;
+    ErrorCode errorCode =
+        errorCodeByUniqueName(errorName) ?? _lintCodeByUniqueName(errorName);
+    if (errorCode == null) {
+      // This could fail because the error code is no longer defined, or, in
+      // the case of a lint rule, if the lint rule has been disabled since the
+      // errors were written.
+      AnalysisEngine.instance.instrumentationService
+          .logError('No error code for "$error" in "$source"');
+      return null;
+    }
+
+    List<DiagnosticMessageImpl> contextMessages;
+    if (error.contextMessages.isNotEmpty) {
+      contextMessages = <DiagnosticMessageImpl>[];
+      for (var message in error.contextMessages) {
+        contextMessages.add(
+          DiagnosticMessageImpl(
+            filePath: message.filePath,
+            length: message.length,
+            message: message.message,
+            offset: message.offset,
+          ),
+        );
+      }
+    }
+
+    return AnalysisError.forValues(
+      source,
+      error.offset,
+      error.length,
+      errorCode,
+      error.message,
+      error.correction.isEmpty ? null : error.correction,
+      contextMessages: contextMessages ?? const [],
+    );
+  }
+
+  static AnalysisDriverUnitErrorBuilder encode(AnalysisError error) {
+    List<DiagnosticMessageBuilder> contextMessages;
+    if (error.contextMessages != null) {
+      contextMessages = <DiagnosticMessageBuilder>[];
+      for (var message in error.contextMessages) {
+        contextMessages.add(
+          DiagnosticMessageBuilder(
+            filePath: message.filePath,
+            length: message.length,
+            message: message.message,
+            offset: message.offset,
+          ),
+        );
+      }
+    }
+
+    return AnalysisDriverUnitErrorBuilder(
+      offset: error.offset,
+      length: error.length,
+      uniqueName: error.errorCode.uniqueName,
+      message: error.message,
+      correction: error.correction,
+      contextMessages: contextMessages,
+    );
+  }
+
+  /// Return the lint code with the given [errorName], or `null` if there is no
+  /// lint registered with that name.
+  static ErrorCode _lintCodeByUniqueName(String errorName) {
+    const String lintPrefix = 'LintCode.';
+    if (errorName.startsWith(lintPrefix)) {
+      String lintName = errorName.substring(lintPrefix.length);
+      return linter.Registry.ruleRegistry.getRule(lintName)?.lintCode;
+    }
+
+    const String lintPrefixOld = '_LintCode.';
+    if (errorName.startsWith(lintPrefixOld)) {
+      String lintName = errorName.substring(lintPrefixOld.length);
+      return linter.Registry.ruleRegistry.getRule(lintName)?.lintCode;
+    }
+
+    return null;
+  }
+}
+
 /// Exception that happened during analysis.
 class ExceptionResult {
   /// The path of the file being analyzed when the [exception] happened.
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 55646c1..aad02df 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -8,7 +8,7 @@
 
 /// The current version of the Dart language (or, for non-stable releases, the
 /// version of the language currently in the process of being developed).
-const _currentVersion = '2.8.0';
+const _currentVersion = '2.9.0';
 
 /// A map containing information about all known experimental flags.
 const _knownFeatures = <String, ExperimentalFeature>{
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart b/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart
index 88c6582..ca5b993 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart
@@ -90,12 +90,16 @@
 }
 
 /// Computes a new set of enable flags based on [flags], but with any features
-/// that were not present in [version] set to `false`.
+/// that are not present in the language [version] set to `false`.
 List<bool> restrictEnableFlagsToVersion(List<bool> flags, Version version) {
+  if (version == ExperimentStatus.currentVersion) {
+    return flags;
+  }
+
   flags = List.from(flags);
   for (var feature in _knownFeatures.values) {
-    if (!feature.isEnabledByDefault ||
-        feature.firstSupportedVersion > version) {
+    var firstSupportedVersion = feature.firstSupportedVersion;
+    if (firstSupportedVersion == null || firstSupportedVersion > version) {
       flags[feature.index] = false;
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
index f062dd9..b02965c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -35,16 +35,11 @@
       return _sdkFeatureSet;
     }
 
-    for (var package in _packages.packages) {
-      if (package.rootFolder.contains(path)) {
-        var languageVersion = package.languageVersion;
-        if (languageVersion == null ||
-            languageVersion == ExperimentStatus.currentVersion) {
-          return _packageDefaultFeatureSet;
-        } else {
-          return _packageDefaultFeatureSet.restrictToVersion(languageVersion);
-        }
-      }
+    var package = _packages.packageForPath(path);
+    if (package != null) {
+      var languageVersion = package.languageVersion;
+      languageVersion ??= ExperimentStatus.currentVersion;
+      return _packageDefaultFeatureSet.restrictToVersion(languageVersion);
     }
 
     return _nonPackageDefaultFeatureSet;
@@ -52,13 +47,11 @@
 
   /// Return the language version configured for the file.
   Version getLanguageVersion(String path, Uri uri) {
-    for (var package in _packages.packages) {
-      if (package.rootFolder.contains(path)) {
-        var languageVersion = package.languageVersion;
-        if (languageVersion != null) {
-          return languageVersion;
-        }
-        break;
+    var package = _packages.packageForPath(path);
+    if (package != null) {
+      var languageVersion = package.languageVersion;
+      if (languageVersion != null) {
+        return languageVersion;
       }
     }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
index 1456849..a5652ec 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
@@ -106,12 +106,17 @@
   }
 
   static void _cleanUpFolder(String cachePath, int maxSizeBytes) {
+    List<FileSystemEntity> resources;
+    try {
+      resources = Directory(cachePath).listSync(recursive: true);
+    } catch (_) {
+      return;
+    }
+
     // Prepare the list of files and their statistics.
     List<File> files = <File>[];
     Map<File, FileStat> fileStatMap = {};
     int currentSizeBytes = 0;
-    List<FileSystemEntity> resources =
-        Directory(cachePath).listSync(recursive: true);
     for (FileSystemEntity resource in resources) {
       if (resource is File) {
         try {
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 0cb5728..89a1393 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -445,7 +445,9 @@
       element = element.enclosingElement;
     }
     if (element?.enclosingElement is CompilationUnitElement) {
-      nameIdUnitMember = _getStringInfo(element.name);
+      // Unnamed extensions have a null `name`, but _StringInfo instances must
+      // have non-null values.
+      nameIdUnitMember = _getStringInfo(element.name ?? '');
     }
     return _ElementInfo(unitId, nameIdUnitMember, nameIdClassMember,
         nameIdParameter, info.kind);
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 4ab24f0..818e0b0 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -231,20 +231,30 @@
     AnalysisErrorListener errorListener = _getErrorListener(file);
     ErrorReporter errorReporter = _getErrorReporter(file);
 
-    unit.accept(DeadCodeVerifier(errorReporter, unit.featureSet,
-        typeSystem: _typeSystem));
+    if (!_libraryElement.isNonNullableByDefault) {
+      unit.accept(DeadCodeVerifier(errorReporter, unit.featureSet,
+          typeSystem: _typeSystem));
+    }
 
     // Dart2js analysis.
     if (_analysisOptions.dart2jsHint) {
       unit.accept(Dart2JSVerifier(errorReporter));
     }
 
-    unit.accept(BestPracticesVerifier(
-        errorReporter, _typeProvider, _libraryElement, unit, file.content,
+    unit.accept(
+      BestPracticesVerifier(
+        errorReporter,
+        _typeProvider,
+        _libraryElement,
+        unit,
+        file.content,
+        declaredVariables: _declaredVariables,
         typeSystem: _typeSystem,
         inheritanceManager: _inheritance,
         resourceProvider: _resourceProvider,
-        analysisOptions: _context.analysisOptions));
+        analysisOptions: _context.analysisOptions,
+      ),
+    );
 
     unit.accept(OverrideVerifier(
       _inheritance,
@@ -403,12 +413,46 @@
     LineInfo lineInfo = _fileToLineInfo[file];
 
     bool isIgnored(AnalysisError error) {
+      var code = error.errorCode;
+      // Don't allow error severity issues to be ignored.
+      if (!code.isIgnorable) {
+        // 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.
+        bool privileged = false;
+
+        if (code == StaticTypeWarningCode.UNDEFINED_FUNCTION ||
+            code == StaticTypeWarningCode.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 (file.path.contains('flutter')) {
+            privileged = true;
+          }
+        }
+
+        if (code == CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY &&
+            file.path.contains('tests/compiler/dart2js')) {
+          // Special case the dart2js language tests. Some of these import
+          // various internal libraries.
+          privileged = true;
+        }
+
+        if (!privileged) return false;
+      }
+
       int errorLine = lineInfo.getLocation(error.offset).lineNumber;
-      String name = error.errorCode.name.toLowerCase();
+      String name = code.name.toLowerCase();
       if (ignoreInfo.ignoredAt(name, errorLine)) {
         return true;
       }
-      String uniqueName = error.errorCode.uniqueName;
+      String uniqueName = code.uniqueName;
       int period = uniqueName.indexOf('.');
       if (period >= 0) {
         uniqueName = uniqueName.substring(period + 1);
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index ec2e3e9..559c900 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/element/element.dart'
     show CompilationUnitElement, LibraryElement;
 import 'package:analyzer/exception/exception.dart';
@@ -44,7 +43,7 @@
 
   final PerformanceLog logger;
   final ByteStore byteStore;
-  final AnalysisSession analysisSession;
+  final AnalysisSessionImpl analysisSession;
   final SummaryDataStore externalSummaries;
   final SummaryDataStore store = SummaryDataStore([]);
 
@@ -60,7 +59,7 @@
   var loadedBundles = Set<LibraryCycle>.identity();
 
   LibraryContext({
-    @required AnalysisSession session,
+    @required AnalysisSessionImpl session,
     @required PerformanceLog logger,
     @required ByteStore byteStore,
     @required FileSystemState fsState,
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 066e416..e0a5320 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -39,8 +39,8 @@
   /// The cache of libraries for URIs.
   final Map<String, LibraryElement> _uriToLibraryCache = {};
 
-  final ClassHierarchy classHierarchy = ClassHierarchy();
-  final InheritanceManager3 inheritanceManager = InheritanceManager3();
+  ClassHierarchy classHierarchy = ClassHierarchy();
+  InheritanceManager3 inheritanceManager = InheritanceManager3();
 
   /// Initialize a newly created analysis session.
   AnalysisSessionImpl(this._driver);
@@ -94,6 +94,12 @@
     return _uriConverter ??= DriverBasedUriConverter(_driver);
   }
 
+  /// Clear hierarchies, to reduce memory consumption.
+  void clearHierarchies() {
+    classHierarchy = ClassHierarchy();
+    inheritanceManager = InheritanceManager3();
+  }
+
   @deprecated
   driver.AnalysisDriver getDriver() => _driver;
 
@@ -210,7 +216,7 @@
 /// Data structure containing information about the analysis session that is
 /// available synchronously.
 class SynchronousSession {
-  final AnalysisOptionsImpl analysisOptions;
+  AnalysisOptionsImpl _analysisOptions;
 
   final DeclaredVariables declaredVariables;
 
@@ -222,7 +228,23 @@
 
   InheritanceManager3 _inheritanceManager;
 
-  SynchronousSession(this.analysisOptions, this.declaredVariables);
+  SynchronousSession(this._analysisOptions, this.declaredVariables);
+
+  AnalysisOptionsImpl get analysisOptions => _analysisOptions;
+
+  set analysisOptions(AnalysisOptionsImpl analysisOptions) {
+    this._analysisOptions = analysisOptions;
+
+    _typeSystemLegacy?.updateOptions(
+      implicitCasts: analysisOptions.implicitCasts,
+      strictInference: analysisOptions.strictInference,
+    );
+
+    _typeSystemNonNullableByDefault?.updateOptions(
+      implicitCasts: analysisOptions.implicitCasts,
+      strictInference: analysisOptions.strictInference,
+    );
+  }
 
   InheritanceManager3 get inheritanceManager {
     return _inheritanceManager ??= InheritanceManager3();
@@ -275,16 +297,16 @@
     _typeProviderNonNullableByDefault = nonNullableByDefault;
 
     _typeSystemLegacy = TypeSystemImpl(
-      implicitCasts: analysisOptions.implicitCasts,
+      implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: false,
-      strictInference: analysisOptions.strictInference,
+      strictInference: _analysisOptions.strictInference,
       typeProvider: _typeProviderLegacy,
     );
 
     _typeSystemNonNullableByDefault = TypeSystemImpl(
-      implicitCasts: analysisOptions.implicitCasts,
+      implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: true,
-      strictInference: analysisOptions.strictInference,
+      strictInference: _analysisOptions.strictInference,
       typeProvider: _typeProviderNonNullableByDefault,
     );
   }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 8c31220..8bac535 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2031,18 +2031,6 @@
   int languageVersionMinor;
 
   @override
-  LanguageVersionToken get languageVersionToken {
-    CommentToken comment = beginToken.precedingComments;
-    while (comment != null) {
-      if (comment is LanguageVersionToken) {
-        return comment;
-      }
-      comment = comment.next;
-    }
-    return null;
-  }
-
-  @override
   final FeatureSet featureSet;
 
   /// Initialize a newly created compilation unit to have the given directives
@@ -2085,6 +2073,18 @@
   }
 
   @override
+  LanguageVersionToken get languageVersionToken {
+    CommentToken comment = beginToken.precedingComments;
+    while (comment != null) {
+      if (comment is LanguageVersionToken) {
+        return comment;
+      }
+      comment = comment.next;
+    }
+    return null;
+  }
+
+  @override
   int get length {
     Token endToken = this.endToken;
     if (endToken == null) {
@@ -2385,6 +2385,10 @@
         case CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL:
         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_KEY:
+        case CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE:
+        case CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT:
           hasConstError = true;
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index f5af931..189fe9f 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -380,7 +380,10 @@
   }
 
   void _reportNotPotentialConstants(AstNode node) {
-    var notPotentiallyConstants = getNotPotentiallyConstants(node);
+    var notPotentiallyConstants = getNotPotentiallyConstants(
+      node,
+      isNonNullableByDefault: _isNonNullableByDefault,
+    );
     if (notPotentiallyConstants.isEmpty) return;
 
     for (var notConst in notPotentiallyConstants) {
@@ -750,7 +753,10 @@
 
   /// Return `true` if the [node] is a potential constant.
   bool _reportNotPotentialConstants(AstNode node) {
-    var notPotentiallyConstants = getNotPotentiallyConstants(node);
+    var notPotentiallyConstants = getNotPotentiallyConstants(
+      node,
+      isNonNullableByDefault: verifier._isNonNullableByDefault,
+    );
     if (notPotentiallyConstants.isEmpty) return true;
 
     for (var notConst in notPotentiallyConstants) {
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 3c58f20..7d7607e 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -19,12 +19,12 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/constant/from_environment_evaluator.dart';
+import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart';
 import 'package:analyzer/src/dart/constant/potentially_constant.dart';
 import 'package:analyzer/src/dart/constant/utilities.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type_visitor.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -251,11 +251,11 @@
       Annotation constNode = constant.annotationAst;
       Element element = constant.element;
       if (element is PropertyAccessorElement &&
-          element.variable is VariableElementImpl) {
+          element.variable is VariableElement) {
         // The annotation is a reference to a compile-time constant variable.
         // Just copy the evaluation result.
         VariableElementImpl variableElement =
-            element.variable as VariableElementImpl;
+            element.variable.declaration as VariableElementImpl;
         if (variableElement.evaluationResult != null) {
           constant.evaluationResult = variableElement.evaluationResult;
         } else {
@@ -381,14 +381,14 @@
       Annotation constNode = constant.annotationAst;
       Element element = constant.element;
       if (element is PropertyAccessorElement &&
-          element.variable is VariableElementImpl) {
+          element.variable is VariableElement) {
         // The annotation is a reference to a compile-time constant variable,
         // so it depends on the variable.
-        callback(element.variable);
-      } else if (element is ConstructorElementImpl) {
+        callback(element.variable.declaration);
+      } else if (element is ConstructorElement) {
         // The annotation is a constructor invocation, so it depends on the
         // constructor.
-        callback(element);
+        callback(element.declaration);
       } else {
         // This could happen in the event of invalid code.  The error will be
         // reported at constant evaluation time.
@@ -981,6 +981,8 @@
   /// Convenience getter to gain access to the [evaluationEngine]'s type system.
   TypeSystemImpl get typeSystem => evaluationEngine.typeSystem;
 
+  bool get _isNonNullableByDefault => typeSystem.isNonNullableByDefault;
+
   /// Convenience getter to gain access to the [evaluationEngine]'s type
   /// provider.
   TypeProvider get _typeProvider => evaluationEngine.typeProvider;
@@ -1468,7 +1470,7 @@
   @override
   DartObjectImpl visitTypeName(TypeName node) {
     var type = node.type;
-    if (_hasTypeParameterReference(type)) {
+    if (!_isNonNullableByDefault && hasTypeParameterReference(type)) {
       return super.visitTypeName(node);
     }
     return DartObjectImpl(
@@ -1637,7 +1639,7 @@
         element is PropertyAccessorElement ? element.variable : element;
 
     if (node is SimpleIdentifier &&
-        (node.tearOffTypeArgumentTypes?.any(_hasAppliedTypeParameters) ??
+        (node.tearOffTypeArgumentTypes?.any(hasTypeParameterReference) ??
             false)) {
       _error(node, null);
     }
@@ -1707,13 +1709,6 @@
     return null;
   }
 
-  /// Check if any type parameters are referenced by [type], which is an error.
-  bool _hasAppliedTypeParameters(DartType type) {
-    final visitor = _ReferencesTypeParameterVisitor();
-    DartTypeVisitor.visit(type, visitor);
-    return visitor.result;
-  }
-
   /// Return `true` if the given [targetResult] represents a string and the
   /// [identifier] is "length".
   bool _isStringLength(
@@ -1726,7 +1721,10 @@
   }
 
   void _reportNotPotentialConstants(AstNode node) {
-    var notPotentiallyConstants = getNotPotentiallyConstants(node);
+    var notPotentiallyConstants = getNotPotentiallyConstants(
+      node,
+      isNonNullableByDefault: _isNonNullableByDefault,
+    );
     if (notPotentiallyConstants.isEmpty) return;
 
     for (var notConst in notPotentiallyConstants) {
@@ -1746,18 +1744,6 @@
     }
     return evaluationEngine._nullObject;
   }
-
-  /// Return `true` if the [type] has a type parameter reference, so is not
-  /// valid in a constant context.
-  static bool _hasTypeParameterReference(DartType type) {
-    if (type is TypeParameterType) {
-      return true;
-    }
-    if (type is ParameterizedType) {
-      return type.typeArguments.any(_hasTypeParameterReference);
-    }
-    return false;
-  }
 }
 
 /// A utility class that contains methods for manipulating instances of a Dart
@@ -2255,24 +2241,3 @@
     return value.toString();
   }
 }
-
-/// A visitor to find if a type contains any [TypeParameterType]s.
-///
-/// To find the result, check [result] on this instance after visiting the tree.
-/// The actual value returned by the visit methods is merely used so that
-/// [RecursiveTypeVisitor] stops visiting the type once the first type parameter
-/// type is found.
-class _ReferencesTypeParameterVisitor extends RecursiveTypeVisitor {
-  /// The result of whether any type parameters were found.
-  bool result = false;
-
-  @override
-  bool defaultDartType(_) => true;
-
-  @override
-  bool visitTypeParameterType(_) {
-    result = true;
-    // Stop visiting at this point.
-    return false;
-  } // Continue visiting in this case.
-}
diff --git a/pkg/analyzer/lib/src/dart/constant/has_type_parameter_reference.dart b/pkg/analyzer/lib/src/dart/constant/has_type_parameter_reference.dart
new file mode 100644
index 0000000..0aa6243
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/constant/has_type_parameter_reference.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_visitor.dart';
+
+/// Return `true` if the [type] has a type parameter reference.
+bool hasTypeParameterReference(DartType type) {
+  var visitor = _ReferencesTypeParameterVisitor();
+  DartTypeVisitor.visit(type, visitor);
+  return visitor.result;
+}
+
+/// A visitor to find if a type contains any [TypeParameterType]s.
+///
+/// To find the result, check [result] on this instance after visiting the tree.
+///
+/// The actual value returned by the visit methods is merely used so that
+/// [RecursiveTypeVisitor] stops visiting the type once the first type parameter
+/// type is found.
+class _ReferencesTypeParameterVisitor extends RecursiveTypeVisitor {
+  /// The result of whether any type parameters were found.
+  bool result = false;
+
+  @override
+  bool defaultDartType(_) => true;
+
+  @override
+  bool visitTypeParameterType(_) {
+    result = true;
+    // Stop visiting at this point.
+    return false;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index ba05758..82bbe07 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:meta/meta.dart';
 
 /// Some [ConstructorElement]s can be temporary marked as "const" to check
 /// if doing this is valid.
@@ -14,8 +15,13 @@
 /// Check if the [node] and all its sub-nodes are potentially constant.
 ///
 /// Return the list of nodes that are not potentially constant.
-List<AstNode> getNotPotentiallyConstants(AstNode node) {
-  var collector = _Collector();
+List<AstNode> getNotPotentiallyConstants(
+  AstNode node, {
+  @required bool isNonNullableByDefault,
+}) {
+  var collector = _Collector(
+    isNonNullableByDefault: isNonNullableByDefault,
+  );
   collector.collect(node);
   return collector.nodes;
 }
@@ -78,6 +84,18 @@
   return false;
 }
 
+/// Return `true` if the [node] is a potentially constant type expression.
+bool isPotentiallyConstantTypeExpression(TypeAnnotation node) {
+  if (node is TypeName) {
+    var element = node.name.staticElement;
+    if (element is TypeParameterElement) {
+      return true;
+    }
+  }
+
+  return isConstantTypeExpression(node);
+}
+
 bool _isConstantTypeName(Identifier name) {
   var element = name.staticElement;
   if (element is ClassElement || element is GenericTypeAliasElement) {
@@ -92,8 +110,11 @@
 }
 
 class _Collector {
+  final bool isNonNullableByDefault;
   final List<AstNode> nodes = [];
 
+  _Collector({@required this.isNonNullableByDefault});
+
   void collect(AstNode node) {
     if (node is BooleanLiteral ||
         node is DoubleLiteral ||
@@ -178,16 +199,28 @@
     }
 
     if (node is AsExpression) {
-      if (!isConstantTypeExpression(node.type)) {
-        nodes.add(node.type);
+      if (isNonNullableByDefault) {
+        if (!isPotentiallyConstantTypeExpression(node.type)) {
+          nodes.add(node.type);
+        }
+      } else {
+        if (!isConstantTypeExpression(node.type)) {
+          nodes.add(node.type);
+        }
       }
       collect(node.expression);
       return;
     }
 
     if (node is IsExpression) {
-      if (!isConstantTypeExpression(node.type)) {
-        nodes.add(node.type);
+      if (isNonNullableByDefault) {
+        if (!isPotentiallyConstantTypeExpression(node.type)) {
+          nodes.add(node.type);
+        }
+      } else {
+        if (!isConstantTypeExpression(node.type)) {
+          nodes.add(node.type);
+        }
       }
       collect(node.expression);
       return;
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index fcaf659..2e000e5 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
@@ -262,7 +263,16 @@
     if (isNull) {
       return this;
     }
-    if (!typeSystem.isSubtypeOf2(type, (castType._state as TypeState)._type)) {
+
+    var resultType = (castType._state as TypeState)._type;
+
+    // We don't know the actual value of a type parameter.
+    // So, the object type might be a subtype of the result type.
+    if (hasTypeParameterReference(resultType)) {
+      return this;
+    }
+
+    if (!typeSystem.isSubtypeOf2(type, resultType)) {
       throw EvaluationException(
           CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
     }
diff --git a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
index a02599d..f14f835 100644
--- a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
+++ b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
@@ -7,18 +7,41 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:meta/meta.dart';
 
 class ClassHierarchy {
   final Map<ClassElement, _Hierarchy> _map = {};
 
+  List<ClassHierarchyError> errors(ClassElement element) {
+    return _getHierarchy(element).errors;
+  }
+
   List<InterfaceType> implementedInterfaces(ClassElement element) {
+    return _getHierarchy(element).interfaces;
+  }
+
+  void remove(ClassElement element) {
+    _map.remove(element);
+  }
+
+  /// Remove hierarchies for classes defined in specified libraries.
+  void removeOfLibraries(Iterable<String> uriStrIterable) {
+    var uriStrSet = uriStrIterable.toSet();
+    _map.removeWhere((element, _) {
+      var uriStr = '${element.librarySource.uri}';
+      return uriStrSet.contains(uriStr);
+    });
+  }
+
+  _Hierarchy _getHierarchy(ClassElement element) {
     var hierarchy = _map[element];
 
     if (hierarchy != null) {
-      return hierarchy.interfaces;
+      return hierarchy;
     }
 
     hierarchy = _Hierarchy(
+      errors: const <ClassHierarchyError>[],
       interfaces: const <InterfaceType>[],
     );
     _map[element] = hierarchy;
@@ -29,16 +52,12 @@
 
     void appendOne(InterfaceType type) {
       var element = type.element;
-      if (library.isNonNullableByDefault) {
-        var classResult = map[element];
-        if (classResult == null) {
-          classResult = _ClassInterfaceType(typeSystem);
-          map[element] = classResult;
-        }
-        classResult.update(type);
-      } else {
-        map[element] ??= _ClassInterfaceType(typeSystem)..update(type);
+      var classResult = map[element];
+      if (classResult == null) {
+        classResult = _ClassInterfaceType(typeSystem);
+        map[element] = classResult;
       }
+      classResult.update(type);
     }
 
     void append(InterfaceType type) {
@@ -68,43 +87,101 @@
       append(type);
     }
 
-    var result = map.values.map((e) => e.type).toList(growable: false);
-    hierarchy.interfaces = result;
-    return result;
+    var errors = <ClassHierarchyError>[];
+    var interfaces = <InterfaceType>[];
+    for (var collector in map.values) {
+      if (collector._error != null) {
+        errors.add(collector._error);
+      }
+      interfaces.add(collector.type);
+    }
+
+    hierarchy.errors = errors;
+    hierarchy.interfaces = interfaces;
+
+    return hierarchy;
   }
 }
 
+abstract class ClassHierarchyError {}
+
+/// This error is recorded when the same generic class is found in the
+/// hierarchy of a class, and the type arguments are not compatible. What it
+/// means to be compatible depends on whether the class is declared in a
+/// legacy, or an opted-in library.
+///
+/// In legacy libraries LEGACY_ERASURE of the interfaces must be syntactically
+/// equal.
+///
+/// In opted-in libraries NNBD_TOP_MERGE of NORM of the interfaces must be
+/// successful.
+class IncompatibleInterfacesClassHierarchyError extends ClassHierarchyError {
+  final InterfaceType first;
+  final InterfaceType second;
+
+  IncompatibleInterfacesClassHierarchyError(this.first, this.second);
+}
+
 class _ClassInterfaceType {
   final TypeSystemImpl _typeSystem;
 
-  InterfaceType _notNormalized;
-  InterfaceType _currentMerge;
+  ClassHierarchyError _error;
+
+  InterfaceType _singleType;
+  InterfaceType _currentResult;
 
   _ClassInterfaceType(this._typeSystem);
 
-  InterfaceType get type => _currentMerge ?? _notNormalized;
+  InterfaceType get type => _currentResult ?? _singleType;
 
   void update(InterfaceType type) {
-    if (_currentMerge == null) {
-      if (_notNormalized == null) {
-        _notNormalized = type;
-        return;
-      } else {
-        _currentMerge = _typeSystem.normalize(_notNormalized);
-      }
+    if (_error != null) {
+      return;
     }
 
-    var normType = _typeSystem.normalize(type);
-    try {
-      _currentMerge = _typeSystem.topMerge(_currentMerge, normType);
-    } catch (e) {
-      // ignored
+    if (_typeSystem.isNonNullableByDefault) {
+      if (_currentResult == null) {
+        if (_singleType == null) {
+          _singleType = type;
+          return;
+        } else if (type == _singleType) {
+          return;
+        } else {
+          _currentResult = _typeSystem.normalize(_singleType);
+        }
+      }
+
+      var normType = _typeSystem.normalize(type);
+      try {
+        _currentResult = _typeSystem.topMerge(_currentResult, normType);
+      } catch (e) {
+        _error = IncompatibleInterfacesClassHierarchyError(
+          _currentResult,
+          type,
+        );
+      }
+    } else {
+      var legacyType = _typeSystem.toLegacyType(type);
+      if (_currentResult == null) {
+        _currentResult = legacyType;
+      } else {
+        if (legacyType != _currentResult) {
+          _error = IncompatibleInterfacesClassHierarchyError(
+            _currentResult,
+            legacyType,
+          );
+        }
+      }
     }
   }
 }
 
 class _Hierarchy {
+  List<ClassHierarchyError> errors;
   List<InterfaceType> interfaces;
 
-  _Hierarchy({this.interfaces});
+  _Hierarchy({
+    @required this.errors,
+    @required this.interfaces,
+  });
 }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 5422092..5234c13 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4072,7 +4072,7 @@
   @override
   String get name {
     if (linkedNode != null) {
-      return (linkedNode as ExtensionDeclaration).name?.name ?? '';
+      return (linkedNode as ExtensionDeclaration).name?.name;
     }
     return super.name;
   }
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
new file mode 100644
index 0000000..076a6f4
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -0,0 +1,990 @@
+// 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:collection';
+import 'dart:math' as math;
+
+import 'package:analyzer/dart/ast/ast.dart' show AstNode, ConstructorName;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/error/listener.dart' show ErrorReporter;
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/nullability_eliminator.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_schema.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/error/codes.dart' show HintCode, StrongModeCode;
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:meta/meta.dart';
+
+bool _isBottom(DartType t) {
+  return (t.isBottom && t.nullabilitySuffix != NullabilitySuffix.question) ||
+      identical(t, UnknownInferredType.instance);
+}
+
+/// Is [t] the bottom of the legacy type hierarchy.
+bool _isLegacyBottom(DartType t, {@required bool orTrueBottom}) {
+  return (t.isBottom && t.nullabilitySuffix == NullabilitySuffix.question) ||
+      t.isDartCoreNull ||
+      (orTrueBottom ? _isBottom(t) : false);
+}
+
+/// Is [t] the top of the legacy type hierarch.
+bool _isLegacyTop(DartType t, {@required bool orTrueTop}) {
+  if (t.isDartAsyncFutureOr) {
+    return _isLegacyTop((t as InterfaceType).typeArguments[0],
+        orTrueTop: orTrueTop);
+  }
+  if (t.isObject && t.nullabilitySuffix == NullabilitySuffix.none) {
+    return true;
+  }
+  return orTrueTop ? _isTop(t) : false;
+}
+
+bool _isTop(DartType t) {
+  if (t.isDartAsyncFutureOr) {
+    return _isTop((t as InterfaceType).typeArguments[0]);
+  }
+  return t.isDynamic ||
+      (t.isObject && t.nullabilitySuffix != NullabilitySuffix.none) ||
+      t.isVoid ||
+      identical(t, UnknownInferredType.instance);
+}
+
+/// Tracks upper and lower type bounds for a set of type parameters.
+///
+/// This class is used by calling [isSubtypeOf]. When it encounters one of
+/// the type parameters it is inferring, it will record the constraint, and
+/// optimistically assume the constraint will be satisfied.
+///
+/// For example if we are inferring type parameter A, and we ask if
+/// `A <: num`, this will record that A must be a subytpe of `num`. It also
+/// handles cases when A appears as part of the structure of another type, for
+/// example `Iterable<A> <: Iterable<num>` would infer the same constraint
+/// (due to covariant generic types) as would `() -> A <: () -> num`. In
+/// contrast `(A) -> void <: (num) -> void`.
+///
+/// Once the lower/upper bounds are determined, [infer] should be called to
+/// finish the inference. It will instantiate a generic function type with the
+/// inferred types for each type parameter.
+///
+/// It can also optionally compute a partial solution, in case some of the type
+/// parameters could not be inferred (because the constraints cannot be
+/// satisfied), or bail on the inference when this happens.
+///
+/// As currently designed, an instance of this class should only be used to
+/// infer a single call and discarded immediately afterwards.
+class GenericInferrer {
+  final TypeSystemImpl _typeSystem;
+  final Map<TypeParameterElement, List<_TypeConstraint>> constraints = {};
+
+  /// Buffer recording constraints recorded while performing a recursive call to
+  /// [_matchSubtypeOf] that might fail, so that any constraints recorded during
+  /// the failed match can be rewound.
+  final _undoBuffer = <_TypeConstraint>[];
+
+  GenericInferrer(
+    this._typeSystem,
+    Iterable<TypeParameterElement> typeFormals,
+  ) {
+    for (var formal in typeFormals) {
+      constraints[formal] = [];
+    }
+  }
+
+  bool get isNonNullableByDefault => _typeSystem.isNonNullableByDefault;
+
+  TypeProvider get typeProvider => _typeSystem.typeProvider;
+
+  /// Apply an argument constraint, which asserts that the [argument] staticType
+  /// is a subtype of the [parameterType].
+  void constrainArgument(
+      DartType argumentType, DartType parameterType, String parameterName,
+      {ClassElement genericClass}) {
+    var origin = _TypeConstraintFromArgument(
+      argumentType,
+      parameterType,
+      parameterName,
+      genericClass: genericClass,
+      isNonNullableByDefault: isNonNullableByDefault,
+    );
+    tryMatchSubtypeOf(argumentType, parameterType, origin, covariant: false);
+  }
+
+  /// Constrain a universal function type [fnType] used in a context
+  /// [contextType].
+  void constrainGenericFunctionInContext(
+      FunctionType fnType, DartType contextType) {
+    var origin = _TypeConstraintFromFunctionContext(
+      fnType,
+      contextType,
+      isNonNullableByDefault: isNonNullableByDefault,
+    );
+
+    // Since we're trying to infer the instantiation, we want to ignore type
+    // formals as we check the parameters and return type.
+    var inferFnType = FunctionTypeImpl(
+      typeFormals: const [],
+      parameters: fnType.parameters,
+      returnType: fnType.returnType,
+      nullabilitySuffix: fnType.nullabilitySuffix,
+    );
+    tryMatchSubtypeOf(inferFnType, contextType, origin, covariant: true);
+  }
+
+  /// Apply a return type constraint, which asserts that the [declaredType]
+  /// is a subtype of the [contextType].
+  void constrainReturnType(DartType declaredType, DartType contextType) {
+    var origin = _TypeConstraintFromReturnType(
+      declaredType,
+      contextType,
+      isNonNullableByDefault: isNonNullableByDefault,
+    );
+    tryMatchSubtypeOf(declaredType, contextType, origin, covariant: true);
+  }
+
+  /// Given the constraints that were given by calling [constrainArgument] and
+  /// [constrainReturnType], find the type arguments for the [typeFormals] that
+  /// satisfies these constraints.
+  ///
+  /// If [downwardsInferPhase] is set, we are in the first pass of inference,
+  /// pushing context types down. At that point we are allowed to push down
+  /// `?` 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}) {
+    // Initialize the inferred type array.
+    //
+    // In the downwards phase, they all start as `?` to offer reasonable
+    // degradation for f-bounded type parameters.
+    var inferredTypes =
+        List<DartType>.filled(typeFormals.length, UnknownInferredType.instance);
+
+    for (int i = 0; i < typeFormals.length; i++) {
+      // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
+      // variance is added to the interface.
+      TypeParameterElementImpl typeParam = typeFormals[i];
+      _TypeConstraint extendsClause;
+      if (considerExtendsClause && typeParam.bound != null) {
+        extendsClause = _TypeConstraint.fromExtends(
+          typeParam,
+          Substitution.fromPairs(typeFormals, inferredTypes)
+              .substituteType(typeParam.bound),
+          isNonNullableByDefault: isNonNullableByDefault,
+        );
+      }
+
+      inferredTypes[i] = downwardsInferPhase
+          ? _inferTypeParameterFromContext(
+              constraints[typeParam], extendsClause,
+              isContravariant: typeParam.variance.isContravariant)
+          : _inferTypeParameterFromAll(constraints[typeParam], extendsClause,
+              isContravariant: typeParam.variance.isContravariant,
+              preferUpwardsInference: !typeParam.isLegacyCovariant);
+    }
+
+    // If the downwards infer phase has failed, we'll catch this in the upwards
+    // phase later on.
+    if (downwardsInferPhase) {
+      return inferredTypes;
+    }
+
+    // Check the inferred types against all of the constraints.
+    var knownTypes = <TypeParameterElement, DartType>{};
+    for (int i = 0; i < typeFormals.length; i++) {
+      TypeParameterElement typeParam = typeFormals[i];
+      var constraints = this.constraints[typeParam];
+      var typeParamBound = typeParam.bound != null
+          ? Substitution.fromPairs(typeFormals, inferredTypes)
+              .substituteType(typeParam.bound)
+          : typeProvider.dynamicType;
+
+      var inferred = inferredTypes[i];
+      bool success =
+          constraints.every((c) => c.isSatisifedBy(_typeSystem, inferred));
+      if (success && !typeParamBound.isDynamic) {
+        // If everything else succeeded, check the `extends` constraint.
+        var extendsConstraint = _TypeConstraint.fromExtends(
+          typeParam,
+          typeParamBound,
+          isNonNullableByDefault: isNonNullableByDefault,
+        );
+        constraints.add(extendsConstraint);
+        success = extendsConstraint.isSatisifedBy(_typeSystem, inferred);
+      }
+
+      if (!success) {
+        if (failAtError) return null;
+        errorReporter?.reportErrorForNode(
+            StrongModeCode.COULD_NOT_INFER,
+            errorNode,
+            [typeParam.name, _formatError(typeParam, inferred, constraints)]);
+
+        // Heuristic: even if we failed, keep the erroneous type.
+        // It should satisfy at least some of the constraints (e.g. the return
+        // context). If we fall back to instantiateToBounds, we'll typically get
+        // more errors (e.g. because `dynamic` is the most common bound).
+      }
+
+      if (inferred is FunctionType && inferred.typeFormals.isNotEmpty) {
+        if (failAtError) return null;
+        var typeFormals = (inferred as FunctionType).typeFormals;
+        var typeFormalsStr = typeFormals.map(_elementStr).join(', ');
+        errorReporter
+            ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
+          typeParam.name,
+          ' Inferred candidate type ${_typeStr(inferred)} has type parameters'
+              ' [$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)) {
+        knownTypes[typeParam] = inferred;
+      } else if (_typeSystem.strictInference) {
+        // [typeParam] could not be inferred. A result will still be returned
+        // by [infer], with [typeParam] filled in as its bounds. This is
+        // considered a failure of inference, under the "strict-inference"
+        // mode.
+        if (errorNode is ConstructorName) {
+          String constructorName = '${errorNode.type}.${errorNode.name}';
+          errorReporter?.reportErrorForNode(
+              HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION,
+              errorNode,
+              [constructorName]);
+        }
+        // TODO(srawlins): More inference failure cases, like functions, and
+        // function expressions.
+      }
+    }
+
+    // Use instantiate to bounds to finish things off.
+    var hasError = List<bool>.filled(typeFormals.length, false);
+    var result = _typeSystem.instantiateTypeFormalsToBounds(typeFormals,
+        hasError: hasError, knownTypes: knownTypes);
+
+    // Report any errors from instantiateToBounds.
+    for (int i = 0; i < hasError.length; i++) {
+      if (hasError[i]) {
+        if (failAtError) return null;
+        TypeParameterElement typeParam = typeFormals[i];
+        var typeParamBound = Substitution.fromPairs(typeFormals, inferredTypes)
+            .substituteType(typeParam.bound ?? typeProvider.objectType);
+        // TODO(jmesserly): improve this error message.
+        errorReporter
+            ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
+          typeParam.name,
+          "\nRecursive bound cannot be instantiated: '$typeParamBound'."
+              "\nConsider passing explicit type argument(s) "
+              "to the generic.\n\n'"
+        ]);
+      }
+    }
+
+    return result;
+  }
+
+  /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
+  ///
+  /// The return value indicates whether the match was successful.  If it was
+  /// unsuccessful, any constraints that were accumulated during the match
+  /// attempt have been rewound (see [_rewindConstraints]).
+  bool tryMatchSubtypeOf(DartType t1, DartType t2, _TypeConstraintOrigin origin,
+      {@required bool covariant}) {
+    int previousRewindBufferLength = _undoBuffer.length;
+    bool success = _matchSubtypeOf(t1, t2, null, origin, covariant: covariant);
+    if (!success) {
+      _rewindConstraints(previousRewindBufferLength);
+    }
+    return success;
+  }
+
+  /// Choose the bound that was implied by the return type, if any.
+  ///
+  /// Which bound this is depends on what positions the type parameter
+  /// appears in. If the type only appears only in a contravariant position,
+  /// we will choose the lower bound instead.
+  ///
+  /// For example given:
+  ///
+  ///     Func1<T, bool> makeComparer<T>(T x) => (T y) => x() == y;
+  ///
+  ///     main() {
+  ///       Func1<num, bool> t = makeComparer/* infer <num> */(42);
+  ///       print(t(42.0)); /// false, no error.
+  ///     }
+  ///
+  /// The constraints we collect are:
+  ///
+  /// * `num <: T`
+  /// * `int <: T`
+  ///
+  /// ... and no upper bound. Therefore the lower bound is the best choice.
+  ///
+  /// If [isContravariant] is `true`, then we are solving for a contravariant
+  /// type parameter which means we choose the upper bound rather than the
+  /// lower bound for normally covariant type parameters.
+  DartType _chooseTypeFromConstraints(Iterable<_TypeConstraint> constraints,
+      {bool toKnownType = false, @required bool isContravariant}) {
+    DartType lower = UnknownInferredType.instance;
+    DartType upper = UnknownInferredType.instance;
+    for (var constraint in constraints) {
+      // Given constraints:
+      //
+      //     L1 <: T <: U1
+      //     L2 <: T <: U2
+      //
+      // These can be combined to produce:
+      //
+      //     LUB(L1, L2) <: T <: GLB(U1, U2).
+      //
+      // This can then be done for all constraints in sequence.
+      //
+      // This resulting constraint may be unsatisfiable; in that case inference
+      // will fail.
+      upper = _typeSystem.getGreatestLowerBound(upper, constraint.upperBound);
+      lower = _typeSystem.getLeastUpperBound(lower, constraint.lowerBound);
+      upper = _toLegacyType(upper);
+      lower = _toLegacyType(lower);
+    }
+
+    // Prefer the known bound, if any.
+    // Otherwise take whatever bound has partial information, e.g. `Iterable<?>`
+    //
+    // For both of those, prefer the lower bound (arbitrary heuristic) or upper
+    // bound if [isContravariant] is `true`
+    if (isContravariant) {
+      if (UnknownInferredType.isKnown(upper)) {
+        return upper;
+      }
+      if (UnknownInferredType.isKnown(lower)) {
+        return lower;
+      }
+      if (!identical(UnknownInferredType.instance, upper)) {
+        return toKnownType ? _typeSystem.greatestClosure(upper) : upper;
+      }
+      if (!identical(UnknownInferredType.instance, lower)) {
+        return toKnownType ? _typeSystem.leastClosure(lower) : lower;
+      }
+      return upper;
+    } else {
+      if (UnknownInferredType.isKnown(lower)) {
+        return lower;
+      }
+      if (UnknownInferredType.isKnown(upper)) {
+        return upper;
+      }
+      if (!identical(UnknownInferredType.instance, lower)) {
+        return toKnownType ? _typeSystem.leastClosure(lower) : lower;
+      }
+      if (!identical(UnknownInferredType.instance, upper)) {
+        return toKnownType ? _typeSystem.greatestClosure(upper) : upper;
+      }
+      return lower;
+    }
+  }
+
+  String _elementStr(Element element) {
+    return element.getDisplayString(withNullability: isNonNullableByDefault);
+  }
+
+  String _formatError(TypeParameterElement typeParam, DartType inferred,
+      Iterable<_TypeConstraint> constraints) {
+    var inferredStr = inferred.getDisplayString(
+      withNullability: isNonNullableByDefault,
+    );
+    var intro = "Tried to infer '$inferredStr' for '${typeParam.name}'"
+        " which doesn't work:";
+
+    var constraintsByOrigin = <_TypeConstraintOrigin, List<_TypeConstraint>>{};
+    for (var c in constraints) {
+      constraintsByOrigin.putIfAbsent(c.origin, () => []).add(c);
+    }
+
+    // Only report unique constraint origins.
+    Iterable<_TypeConstraint> isSatisified(bool expected) => constraintsByOrigin
+        .values
+        .where((l) =>
+            l.every((c) => c.isSatisifedBy(_typeSystem, inferred)) == expected)
+        .expand((i) => i);
+
+    String unsatisified = _formatConstraints(isSatisified(false));
+    String satisified = _formatConstraints(isSatisified(true));
+
+    assert(unsatisified.isNotEmpty);
+    if (satisified.isNotEmpty) {
+      satisified = "\nThe type '$inferredStr' was inferred from:\n$satisified";
+    }
+
+    return '\n\n$intro\n$unsatisified$satisified\n\n'
+        'Consider passing explicit type argument(s) to the generic.\n\n';
+  }
+
+  DartType _inferTypeParameterFromAll(
+      List<_TypeConstraint> constraints, _TypeConstraint extendsClause,
+      {@required bool isContravariant, @required bool preferUpwardsInference}) {
+    // See if we already fixed this type from downwards inference.
+    // If so, then we aren't allowed to change it based on argument types unless
+    // [preferUpwardsInference] is true.
+    DartType t = _inferTypeParameterFromContext(
+        constraints.where((c) => c.isDownwards), extendsClause,
+        isContravariant: isContravariant);
+    if (!preferUpwardsInference && UnknownInferredType.isKnown(t)) {
+      // Remove constraints that aren't downward ones; we'll ignore these for
+      // error reporting, because inference already succeeded.
+      constraints.removeWhere((c) => !c.isDownwards);
+      return t;
+    }
+
+    if (extendsClause != null) {
+      constraints = constraints.toList()..add(extendsClause);
+    }
+
+    var choice = _chooseTypeFromConstraints(constraints,
+        toKnownType: true, isContravariant: isContravariant);
+    return choice;
+  }
+
+  DartType _inferTypeParameterFromContext(
+      Iterable<_TypeConstraint> constraints, _TypeConstraint extendsClause,
+      {@required bool isContravariant}) {
+    DartType t = _chooseTypeFromConstraints(constraints,
+        isContravariant: isContravariant);
+    if (UnknownInferredType.isUnknown(t)) {
+      return t;
+    }
+
+    // If we're about to make our final choice, apply the extends clause.
+    // This gives us a chance to refine the choice, in case it would violate
+    // the `extends` clause. For example:
+    //
+    //     Object obj = math.min/*<infer Object, error>*/(1, 2);
+    //
+    // If we consider the `T extends num` we conclude `<num>`, which works.
+    if (extendsClause != null) {
+      constraints = constraints.toList()..add(extendsClause);
+      return _chooseTypeFromConstraints(constraints,
+          isContravariant: isContravariant);
+    }
+    return t;
+  }
+
+  /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
+  ///
+  /// The return value indicates whether the match was successful.  If it was
+  /// unsuccessful, the caller is responsible for ignoring any constraints that
+  /// were accumulated (see [_rewindConstraints]).
+  bool _matchInterfaceSubtypeOf(InterfaceType i1, InterfaceType i2,
+      Set<Element> visited, _TypeConstraintOrigin origin,
+      {@required bool covariant}) {
+    if (identical(i1, i2)) {
+      return true;
+    }
+
+    if (i1.element == i2.element) {
+      return _matchInterfaceSubtypeOf2(i1, i2, origin, covariant);
+    }
+
+    for (var interface in i1.element.allSupertypes) {
+      if (interface.element == i2.element) {
+        var substitution = Substitution.fromInterfaceType(i1);
+        var substitutedInterface = substitution.substituteType(interface);
+        return _matchInterfaceSubtypeOf2(
+            substitutedInterface, i2, origin, covariant);
+      }
+    }
+    return false;
+  }
+
+  /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
+  ///
+  /// The return value indicates whether the match was successful.  If it was
+  /// unsuccessful, the caller is responsible for ignoring any constraints that
+  /// were accumulated (see [_rewindConstraints]).
+  ///
+  /// Interfaces [i1] and [i2] are instantiations of the same class element.
+  bool _matchInterfaceSubtypeOf2(InterfaceType i1, InterfaceType i2,
+      _TypeConstraintOrigin origin, bool covariant) {
+    List<DartType> tArgs1 = i1.typeArguments;
+    List<DartType> tArgs2 = i2.typeArguments;
+    List<TypeParameterElement> tParams = i1.element.typeParameters;
+    assert(tArgs1.length == tArgs2.length);
+    assert(tArgs1.length == tParams.length);
+    for (int i = 0; i < tArgs1.length; i++) {
+      TypeParameterElement typeParameterElement = tParams[i];
+
+      // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
+      // variance is added to the interface.
+      Variance parameterVariance =
+          (typeParameterElement as TypeParameterElementImpl).variance;
+      if (parameterVariance.isCovariant) {
+        if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], HashSet<Element>(), origin,
+            covariant: covariant)) {
+          return false;
+        }
+      } else if (parameterVariance.isContravariant) {
+        if (!_matchSubtypeOf(tArgs2[i], tArgs1[i], HashSet<Element>(), origin,
+            covariant: !covariant)) {
+          return false;
+        }
+      } else if (parameterVariance.isInvariant) {
+        if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], HashSet<Element>(), origin,
+                covariant: covariant) ||
+            !_matchSubtypeOf(tArgs2[i], tArgs1[i], HashSet<Element>(), origin,
+                covariant: !covariant)) {
+          return false;
+        }
+      } else {
+        throw StateError("Type parameter ${tParams[i]} has unknown "
+            "variance $parameterVariance for inference.");
+      }
+    }
+    return true;
+  }
+
+  /// Assert that [t1] will be a subtype of [t2], and returns if the constraint
+  /// can be satisfied.
+  ///
+  /// [covariant] must be true if [t1] is a declared type of the generic
+  /// function and [t2] is the context type, or false if the reverse. For
+  /// example [covariant] is used when [t1] is the declared return type
+  /// and [t2] is the context type. Contravariant would be used if [t1] is the
+  /// argument type (i.e. passed in to the generic function) and [t2] is the
+  /// declared parameter type.
+  ///
+  /// [origin] indicates where the constraint came from, for example an argument
+  /// or return type.
+  bool _matchSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
+      _TypeConstraintOrigin origin,
+      {@required bool covariant}) {
+    if (covariant && t1 is TypeParameterType) {
+      var constraints = this.constraints[t1.element];
+      if (constraints != null) {
+        if (!identical(t2, UnknownInferredType.instance)) {
+          if (t1.nullabilitySuffix == NullabilitySuffix.question) {
+            t2 = _typeSystem.promoteToNonNull(t2);
+          }
+          var constraint = _TypeConstraint(origin, t1.element, upper: t2);
+          constraints.add(constraint);
+          _undoBuffer.add(constraint);
+        }
+        return true;
+      }
+    }
+    if (!covariant && t2 is TypeParameterType) {
+      var constraints = this.constraints[t2.element];
+      if (constraints != null) {
+        if (!identical(t1, UnknownInferredType.instance)) {
+          if (t2.nullabilitySuffix == NullabilitySuffix.question) {
+            t1 = _typeSystem.promoteToNonNull(t1);
+          }
+          var constraint = _TypeConstraint(origin, t2.element, lower: t1);
+          constraints.add(constraint);
+          _undoBuffer.add(constraint);
+        }
+        return true;
+      }
+    }
+
+    if (identical(t1, t2)) {
+      return true;
+    }
+
+    // TODO(jmesserly): this logic is taken from subtype.
+    bool matchSubtype(DartType t1, DartType t2) {
+      return _matchSubtypeOf(t1, t2, null, origin, covariant: covariant);
+    }
+
+    // Handle FutureOr<T> union type.
+    if (t1 is InterfaceType && t1.isDartAsyncFutureOr) {
+      var t1TypeArg = t1.typeArguments[0];
+      if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
+        var t2TypeArg = t2.typeArguments[0];
+        // FutureOr<A> <: FutureOr<B> iff A <: B
+        return matchSubtype(t1TypeArg, t2TypeArg);
+      }
+
+      // given t1 is Future<A> | A, then:
+      // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
+      var t1Future = typeProvider.futureType2(t1TypeArg);
+      return matchSubtype(t1Future, t2) && matchSubtype(t1TypeArg, t2);
+    }
+
+    if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
+      // given t2 is Future<A> | A, then:
+      // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
+      var t2TypeArg = t2.typeArguments[0];
+      var t2Future = typeProvider.futureType2(t2TypeArg);
+
+      // First we try matching `t1 <: Future<A>`.  If that succeeds *and*
+      // records at least one constraint, then we proceed using that constraint.
+      var previousRewindBufferLength = _undoBuffer.length;
+      var success =
+          tryMatchSubtypeOf(t1, t2Future, origin, covariant: covariant);
+
+      if (_undoBuffer.length != previousRewindBufferLength) {
+        // Trying to match `t1 <: Future<A>` succeeded and recorded constraints,
+        // so those are the constraints we want.
+        return true;
+      } else {
+        // Either `t1 <: Future<A>` failed to match, or it matched trivially
+        // without recording any constraints (e.g. because t1 is `Null`).  We
+        // want constraints, because they let us do more precise inference, so
+        // go ahead and try matching `t1 <: A` to see if it records any
+        // constraints.
+        if (tryMatchSubtypeOf(t1, t2TypeArg, origin, covariant: covariant)) {
+          // Trying to match `t1 <: A` succeeded.  If it recorded constraints,
+          // those are the constraints we want.  If it didn't, then there's no
+          // way we're going to get any constraints.  So either way, we want to
+          // return `true` since the match suceeded and the constraints we want
+          // (if any) have been recorded.
+          return true;
+        } else {
+          // Trying to match `t1 <: A` failed.  So there's no way we are going
+          // to get any constraints.  Just return `success` to indicate whether
+          // the match succeeded.
+          return success;
+        }
+      }
+    }
+
+    // S <: T where S is a type variable
+    //  T is not dynamic or object (handled above)
+    //  True if T == S
+    //  Or true if bound of S is S' and S' <: T
+
+    if (t1 is TypeParameterType) {
+      // Guard against recursive type parameters
+      //
+      // TODO(jmesserly): this function isn't guarding against anything (it's
+      // not passsing down `visitedSet`, so adding the element has no effect).
+      bool guardedSubtype(DartType t1, DartType t2) {
+        var visitedSet = visited ?? HashSet<Element>();
+        if (visitedSet.add(t1.element)) {
+          bool matched = matchSubtype(t1, t2);
+          visitedSet.remove(t1.element);
+          return matched;
+        } else {
+          // In the case of a recursive type parameter, consider the subtype
+          // match to have failed.
+          return false;
+        }
+      }
+
+      if (t2 is TypeParameterType && t1.definition == t2.definition) {
+        return guardedSubtype(t1.bound, t2.bound);
+      }
+      return guardedSubtype(t1.bound, t2);
+    }
+    if (t2 is TypeParameterType) {
+      return false;
+    }
+
+    // TODO(mfairhurst): switch legacy Bottom checks to true Bottom checks
+    // TODO(mfairhurst): switch legacy Top checks to true Top checks
+    if (_isLegacyBottom(t1, orTrueBottom: true) ||
+        _isLegacyTop(t2, orTrueTop: true)) return true;
+
+    if (t1 is InterfaceType && t2 is InterfaceType) {
+      return _matchInterfaceSubtypeOf(t1, t2, visited, origin,
+          covariant: covariant);
+    }
+
+    if (t1 is FunctionType && t2 is FunctionType) {
+      return FunctionTypeImpl.relate(t1, t2, matchSubtype,
+          parameterRelation: (p1, p2) {
+            return _matchSubtypeOf(p2.type, p1.type, null, origin,
+                covariant: !covariant);
+          },
+          // Type parameter bounds are invariant.
+          boundsRelation: (t1, t2, p1, p2) =>
+              matchSubtype(t1, t2) && matchSubtype(t2, t1));
+    }
+
+    if (t1 is FunctionType && t2 == typeProvider.functionType) {
+      return true;
+    }
+
+    return false;
+  }
+
+  /// Un-does constraints that were gathered by a failed match attempt, until
+  /// [_undoBuffer] has length [previousRewindBufferLength].
+  ///
+  /// The intended usage is that the caller should record the length of
+  /// [_undoBuffer] before attempting to make a match.  Then, if the match
+  /// fails, pass the recorded length to this method to erase any constraints
+  /// that were recorded during the failed match.
+  void _rewindConstraints(int previousRewindBufferLength) {
+    while (_undoBuffer.length > previousRewindBufferLength) {
+      var constraint = _undoBuffer.removeLast();
+      var element = constraint.typeParameter;
+      assert(identical(constraints[element].last, constraint));
+      constraints[element].removeLast();
+    }
+  }
+
+  /// If in a legacy library, return the legacy version of the [type].
+  /// Otherwise, return the original type.
+  DartType _toLegacyType(DartType type) {
+    if (isNonNullableByDefault) return type;
+    return NullabilityEliminator.perform(typeProvider, type);
+  }
+
+  String _typeStr(DartType type) {
+    return type.getDisplayString(withNullability: isNonNullableByDefault);
+  }
+
+  static String _formatConstraints(Iterable<_TypeConstraint> constraints) {
+    List<List<String>> lineParts =
+        Set<_TypeConstraintOrigin>.from(constraints.map((c) => c.origin))
+            .map((o) => o.formatError())
+            .toList();
+
+    int prefixMax = lineParts.map((p) => p[0].length).fold(0, math.max);
+
+    // Use a set to prevent identical message lines.
+    // (It's not uncommon for the same constraint to show up in a few places.)
+    var messageLines = Set<String>.from(lineParts.map((parts) {
+      var prefix = parts[0];
+      var middle = parts[1];
+      var prefixPad = ' ' * (prefixMax - prefix.length);
+      var middlePad = ' ' * (prefixMax);
+      var end = "";
+      if (parts.length > 2) {
+        end = '\n  $middlePad ${parts[2]}';
+      }
+      return '  $prefix$prefixPad $middle$end';
+    }));
+
+    return messageLines.join('\n');
+  }
+}
+
+/// A constraint on a type parameter that we're inferring.
+class _TypeConstraint extends _TypeRange {
+  /// The type parameter that is constrained by [lowerBound] or [upperBound].
+  final TypeParameterElement typeParameter;
+
+  /// Where this constraint comes from, used for error messages.
+  ///
+  /// See [toString].
+  final _TypeConstraintOrigin origin;
+
+  _TypeConstraint(this.origin, this.typeParameter,
+      {DartType upper, DartType lower})
+      : super(upper: upper, lower: lower);
+
+  _TypeConstraint.fromExtends(
+      TypeParameterElement element, DartType extendsType,
+      {@required bool isNonNullableByDefault})
+      : this(
+            _TypeConstraintFromExtendsClause(
+              element,
+              extendsType,
+              isNonNullableByDefault: isNonNullableByDefault,
+            ),
+            element,
+            upper: extendsType);
+
+  bool get isDownwards => origin is! _TypeConstraintFromArgument;
+
+  bool isSatisifedBy(TypeSystemImpl ts, DartType type) =>
+      ts.isSubtypeOf2(lowerBound, type) && ts.isSubtypeOf2(type, upperBound);
+
+  /// Converts this constraint to a message suitable for a type inference error.
+  @override
+  String toString() => !identical(upperBound, UnknownInferredType.instance)
+      ? "'$typeParameter' must extend '$upperBound'"
+      : "'$lowerBound' must extend '$typeParameter'";
+}
+
+class _TypeConstraintFromArgument extends _TypeConstraintOrigin {
+  final DartType argumentType;
+  final DartType parameterType;
+  final String parameterName;
+  final ClassElement genericClass;
+
+  _TypeConstraintFromArgument(
+      this.argumentType, this.parameterType, this.parameterName,
+      {this.genericClass, @required bool isNonNullableByDefault})
+      : super(isNonNullableByDefault: isNonNullableByDefault);
+
+  @override
+  formatError() {
+    // TODO(jmesserly): we should highlight the span. That would be more useful.
+    // However in summary code it doesn't look like the AST node with span is
+    // available.
+    String prefix;
+    if (genericClass != null &&
+        (genericClass.name == "List" || genericClass.name == "Map") &&
+        genericClass.library.isDartCore == true) {
+      // This will become:
+      //     "List element"
+      //     "Map key"
+      //     "Map value"
+      prefix = "${genericClass.name} $parameterName";
+    } else {
+      prefix = "Parameter '$parameterName'";
+    }
+
+    return [
+      prefix,
+      "declared as     '${_typeStr(parameterType)}'",
+      "but argument is '${_typeStr(argumentType)}'."
+    ];
+  }
+}
+
+class _TypeConstraintFromExtendsClause extends _TypeConstraintOrigin {
+  final TypeParameterElement typeParam;
+  final DartType extendsType;
+
+  _TypeConstraintFromExtendsClause(this.typeParam, this.extendsType,
+      {@required bool isNonNullableByDefault})
+      : super(isNonNullableByDefault: isNonNullableByDefault);
+
+  @override
+  formatError() {
+    return [
+      "Type parameter '${typeParam.name}'",
+      "declared to extend '${_typeStr(extendsType)}'."
+    ];
+  }
+}
+
+class _TypeConstraintFromFunctionContext extends _TypeConstraintOrigin {
+  final DartType contextType;
+  final DartType functionType;
+
+  _TypeConstraintFromFunctionContext(this.functionType, this.contextType,
+      {@required bool isNonNullableByDefault})
+      : super(isNonNullableByDefault: isNonNullableByDefault);
+
+  @override
+  formatError() {
+    return [
+      "Function type",
+      "declared as '${_typeStr(functionType)}'",
+      "used where  '${_typeStr(contextType)}' is required."
+    ];
+  }
+}
+
+class _TypeConstraintFromReturnType extends _TypeConstraintOrigin {
+  final DartType contextType;
+  final DartType declaredType;
+
+  _TypeConstraintFromReturnType(this.declaredType, this.contextType,
+      {@required bool isNonNullableByDefault})
+      : super(isNonNullableByDefault: isNonNullableByDefault);
+
+  @override
+  formatError() {
+    return [
+      "Return type",
+      "declared as '${_typeStr(declaredType)}'",
+      "used where  '${_typeStr(contextType)}' is required."
+    ];
+  }
+}
+
+/// The origin of a type constraint, for the purposes of producing a human
+/// readable error message during type inference as well as determining whether
+/// the constraint was used to fix the type parameter or not.
+abstract class _TypeConstraintOrigin {
+  final bool isNonNullableByDefault;
+
+  _TypeConstraintOrigin({@required this.isNonNullableByDefault});
+
+  List<String> formatError();
+
+  String _typeStr(DartType type) {
+    return type.getDisplayString(withNullability: isNonNullableByDefault);
+  }
+}
+
+class _TypeRange {
+  /// The upper bound of the type parameter. In other words, T <: upperBound.
+  ///
+  /// In Dart this can be written as `<T extends UpperBoundType>`.
+  ///
+  /// In inference, this can happen as a result of parameters of function type.
+  /// For example, consider a signature like:
+  ///
+  ///     T reduce<T>(List<T> values, T f(T x, T y));
+  ///
+  /// and a call to it like:
+  ///
+  ///     reduce(values, (num x, num y) => ...);
+  ///
+  /// From the function expression's parameters, we conclude `T <: num`. We may
+  /// still be able to conclude a different [lower] based on `values` or
+  /// the type of the elided `=> ...` body. For example:
+  ///
+  ///      reduce(['x'], (num x, num y) => 'hi');
+  ///
+  /// Here the [lower] will be `String` and the upper bound will be `num`,
+  /// which cannot be satisfied, so this is ill typed.
+  final DartType upperBound;
+
+  /// The lower bound of the type parameter. In other words, lowerBound <: T.
+  ///
+  /// This kind of constraint cannot be expressed in Dart, but it applies when
+  /// we're doing inference. For example, consider a signature like:
+  ///
+  ///     T pickAtRandom<T>(T x, T y);
+  ///
+  /// and a call to it like:
+  ///
+  ///     pickAtRandom(1, 2.0)
+  ///
+  /// when we see the first parameter is an `int`, we know that `int <: T`.
+  /// When we see `double` this implies `double <: T`.
+  /// Combining these constraints results in a lower bound of `num`.
+  ///
+  /// In general, we choose the lower bound as our inferred type, so we can
+  /// offer the most constrained (strongest) result type.
+  final DartType lowerBound;
+
+  _TypeRange({DartType lower, DartType upper})
+      : lowerBound = lower ?? UnknownInferredType.instance,
+        upperBound = upper ?? UnknownInferredType.instance;
+
+  /// Formats the typeRange as a string suitable for unit testing.
+  ///
+  /// For example, if [typeName] is 'T' and the range has bounds int and Object
+  /// respectively, the returned string will be 'int <: T <: Object'.
+  @visibleForTesting
+  String format(String typeName, {@required bool withNullability}) {
+    String typeStr(DartType type) {
+      return type.getDisplayString(withNullability: withNullability);
+    }
+
+    var lowerString = identical(lowerBound, UnknownInferredType.instance)
+        ? ''
+        : '${typeStr(lowerBound)} <: ';
+    var upperString = identical(upperBound, UnknownInferredType.instance)
+        ? ''
+        : ' <: ${typeStr(upperBound)}';
+    return '$lowerString$typeName$upperString';
+  }
+
+  @override
+  String toString() => format('(type)', withNullability: true);
+}
diff --git a/pkg/analyzer/lib/src/dart/element/greatest_lower_bound.dart b/pkg/analyzer/lib/src/dart/element/greatest_lower_bound.dart
new file mode 100644
index 0000000..1085211
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/greatest_lower_bound.dart
@@ -0,0 +1,411 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+class GreatestLowerBoundHelper {
+  final TypeSystemImpl _typeSystem;
+
+  GreatestLowerBoundHelper(this._typeSystem);
+
+  InterfaceTypeImpl get _nullNone => _typeSystem.nullNone;
+
+  TypeProviderImpl get _typeProvider => _typeSystem.typeProvider;
+
+  /// Computes the greatest lower bound of [T1] and [T2].
+  ///
+  /// https://github.com/dart-lang/language
+  /// See `resources/type-system/upper-lower-bounds.md`
+  DartType getGreatestLowerBound(DartType T1, DartType T2) {
+    // DOWN(T, T) = T
+    if (identical(T1, T2)) {
+      return T1;
+    }
+
+    // For any type T, DOWN(?, T) == T.
+    if (identical(T1, UnknownInferredType.instance)) {
+      return T2;
+    }
+    if (identical(T2, UnknownInferredType.instance)) {
+      return T1;
+    }
+
+    var T1_isTop = _typeSystem.isTop(T1);
+    var T2_isTop = _typeSystem.isTop(T2);
+
+    // DOWN(T1, T2) where TOP(T1) and TOP(T2)
+    if (T1_isTop && T2_isTop) {
+      // * T1 if MORETOP(T2, T1)
+      // * T2 otherwise
+      if (_typeSystem.isMoreTop(T2, T1)) {
+        return T1;
+      } else {
+        return T2;
+      }
+    }
+
+    // DOWN(T1, T2) = T2 if TOP(T1)
+    if (T1_isTop) {
+      return T2;
+    }
+
+    // DOWN(T1, T2) = T1 if TOP(T2)
+    if (T2_isTop) {
+      return T1;
+    }
+
+    var T1_isBottom = _typeSystem.isBottom(T1);
+    var T2_isBottom = _typeSystem.isBottom(T2);
+
+    // DOWN(T1, T2) where BOTTOM(T1) and BOTTOM(T2)
+    if (T1_isBottom && T2_isBottom) {
+      // * T1 if MOREBOTTOM(T1, T2)
+      // * T2 otherwise
+      if (_typeSystem.isMoreBottom(T1, T2)) {
+        return T1;
+      } else {
+        return T2;
+      }
+    }
+
+    // DOWN(T1, T2) = T1 if BOTTOM(T1)
+    if (T1_isBottom) {
+      return T1;
+    }
+
+    // DOWN(T1, T2) = T2 if BOTTOM(T2)
+    if (T2_isBottom) {
+      return T2;
+    }
+
+    var T1_isNull = _typeSystem.isNull(T1);
+    var T2_isNull = _typeSystem.isNull(T2);
+
+    // DOWN(T1, T2) where NULL(T1) and NULL(T2)
+    if (T1_isNull && T2_isNull) {
+      // * T1 if MOREBOTTOM(T1, T2)
+      // * T2 otherwise
+      if (_typeSystem.isMoreBottom(T1, T2)) {
+        return T1;
+      } else {
+        return T2;
+      }
+    }
+
+    var T1_impl = T1 as TypeImpl;
+    var T2_impl = T2 as TypeImpl;
+
+    var T1_nullability = T1_impl.nullabilitySuffix;
+    var T2_nullability = T2_impl.nullabilitySuffix;
+
+    // DOWN(Null, T2)
+    if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreNull) {
+      // * Null if Null <: T2
+      // * Never otherwise
+      if (_typeSystem.isSubtypeOf2(_nullNone, T2)) {
+        return _nullNone;
+      } else {
+        return NeverTypeImpl.instance;
+      }
+    }
+
+    // DOWN(T1, Null)
+    if (T2_nullability == NullabilitySuffix.none && T2.isDartCoreNull) {
+      // * Null if Null <: T1
+      // * Never otherwise
+      if (_typeSystem.isSubtypeOf2(_nullNone, T1)) {
+        return _nullNone;
+      } else {
+        return NeverTypeImpl.instance;
+      }
+    }
+
+    var T1_isObject = _typeSystem.isObject(T1);
+    var T2_isObject = _typeSystem.isObject(T2);
+
+    // DOWN(T1, T2) where OBJECT(T1) and OBJECT(T2)
+    if (T1_isObject && T2_isObject) {
+      // * T1 if MORETOP(T2, T1)
+      // * T2 otherwise
+      if (_typeSystem.isMoreTop(T2, T1)) {
+        return T1;
+      } else {
+        return T2;
+      }
+    }
+
+    // DOWN(T1, T2) where OBJECT(T1)
+    if (T1_isObject) {
+      // * T2 if T2 is non-nullable
+      if (_typeSystem.isNonNullable(T2)) {
+        return T2;
+      }
+
+      // * NonNull(T2) if NonNull(T2) is non-nullable
+      var T2_nonNull = _typeSystem.promoteToNonNull(T2_impl);
+      if (_typeSystem.isNonNullable(T2_nonNull)) {
+        return T2_nonNull;
+      }
+
+      // * Never otherwise
+      return NeverTypeImpl.instance;
+    }
+
+    // DOWN(T1, T2) where OBJECT(T2)
+    if (T2_isObject) {
+      // * T1 if T1 is non-nullable
+      if (_typeSystem.isNonNullable(T1)) {
+        return T1;
+      }
+
+      // * NonNull(T1) if NonNull(T1) is non-nullable
+      var T1_nonNull = _typeSystem.promoteToNonNull(T1_impl);
+      if (_typeSystem.isNonNullable(T1_nonNull)) {
+        return T1_nonNull;
+      }
+
+      // * Never otherwise
+      return NeverTypeImpl.instance;
+    }
+
+    // DOWN(T1*, T2*) = S* where S is DOWN(T1, T2)
+    // DOWN(T1*, T2?) = S* where S is DOWN(T1, T2)
+    // DOWN(T1?, T2*) = S* where S is DOWN(T1, T2)
+    // DOWN(T1*, T2) = S where S is DOWN(T1, T2)
+    // DOWN(T1, T2*) = S where S is DOWN(T1, T2)
+    // DOWN(T1?, T2?) = S? where S is DOWN(T1, T2)
+    // DOWN(T1?, T2) = S where S is DOWN(T1, T2)
+    // DOWN(T1, T2?) = S where S is DOWN(T1, T2)
+    if (T1_nullability != NullabilitySuffix.none ||
+        T2_nullability != NullabilitySuffix.none) {
+      var resultNullability = NullabilitySuffix.question;
+      if (T1_nullability == NullabilitySuffix.none ||
+          T2_nullability == NullabilitySuffix.none) {
+        resultNullability = NullabilitySuffix.none;
+      } else if (T1_nullability == NullabilitySuffix.star ||
+          T2_nullability == NullabilitySuffix.star) {
+        resultNullability = NullabilitySuffix.star;
+      }
+      var T1_none = T1_impl.withNullability(NullabilitySuffix.none);
+      var T2_none = T2_impl.withNullability(NullabilitySuffix.none);
+      var S = getGreatestLowerBound(T1_none, T2_none);
+      return (S as TypeImpl).withNullability(resultNullability);
+    }
+
+    assert(T1_nullability == NullabilitySuffix.none);
+    assert(T2_nullability == NullabilitySuffix.none);
+
+    if (T1 is FunctionType && T2 is FunctionType) {
+      return _functionType(T1, T2);
+    }
+
+    // DOWN(T1, T2) = T1 if T1 <: T2
+    if (_typeSystem.isSubtypeOf2(T1, T2)) {
+      return T1;
+    }
+
+    // DOWN(T1, T2) = T2 if T2 <: T1
+    if (_typeSystem.isSubtypeOf2(T2, T1)) {
+      return T2;
+    }
+
+    // FutureOr<S1>
+    if (T1 is InterfaceType && T1.isDartAsyncFutureOr) {
+      var S1 = T1.typeArguments[0];
+      // DOWN(FutureOr<S1>, FutureOr<S2>) = FutureOr(S)
+      //   S = DOWN(S1, S2)
+      if (T2 is InterfaceType && T2.isDartAsyncFutureOr) {
+        var S2 = T2.typeArguments[0];
+        var S = getGreatestLowerBound(S1, S2);
+        return _typeProvider.futureOrType2(S);
+      }
+      // DOWN(FutureOr<S1>, Future<S2>) = Future(S)
+      //   S = DOWN(S1, S2)
+      if (T2 is InterfaceType && T2.isDartAsyncFuture) {
+        var S2 = T2.typeArguments[0];
+        var S = getGreatestLowerBound(S1, S2);
+        return _typeProvider.futureType2(S);
+      }
+      // DOWN(FutureOr<S1>, T2) = DOWN(S1, T2)
+      return getGreatestLowerBound(S1, T2);
+    }
+
+    // FutureOr<S2>
+    if (T2 is InterfaceType && T2.isDartAsyncFutureOr) {
+      var S2 = T2.typeArguments[0];
+      // DOWN(Future<S1>, FutureOr<S2>) = Future<S>
+      //   S = DOWN(S1, S2)
+      if (T1 is InterfaceType && T1.isDartAsyncFuture) {
+        var S1 = T1.typeArguments[0];
+        var S = getGreatestLowerBound(S1, S2);
+        return _typeProvider.futureType2(S);
+      }
+      // DOWN(T1, FutureOr<S2>) = DOWN(T1, S2)
+      return getGreatestLowerBound(T1, S2);
+    }
+
+    // DOWN(T1, T2) = Never otherwise
+    return NeverTypeImpl.instance;
+  }
+
+  /**
+   * Compute the greatest lower bound of function types [f] and [g].
+   *
+   * https://github.com/dart-lang/language
+   * See `resources/type-system/upper-lower-bounds.md`
+   */
+  DartType _functionType(FunctionType f, FunctionType g) {
+    var fTypeFormals = f.typeFormals;
+    var gTypeFormals = g.typeFormals;
+
+    // The number of type parameters must be the same.
+    // Otherwise the result is `Never`.
+    if (fTypeFormals.length != gTypeFormals.length) {
+      return NeverTypeImpl.instance;
+    }
+
+    // The bounds of type parameters must be equal.
+    // Otherwise the result is `Never`.
+    var freshTypeFormalTypes =
+        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
+    if (freshTypeFormalTypes == null) {
+      return NeverTypeImpl.instance;
+    }
+
+    var typeFormals = freshTypeFormalTypes
+        .map<TypeParameterElement>((t) => t.element)
+        .toList();
+
+    f = f.instantiate(freshTypeFormalTypes);
+    g = g.instantiate(freshTypeFormalTypes);
+
+    var fParameters = f.parameters;
+    var gParameters = g.parameters;
+
+    var parameters = <ParameterElement>[];
+    var fIndex = 0;
+    var gIndex = 0;
+    while (fIndex < fParameters.length && gIndex < gParameters.length) {
+      var fParameter = fParameters[fIndex];
+      var gParameter = gParameters[gIndex];
+      if (fParameter.isPositional) {
+        if (gParameter.isPositional) {
+          fIndex++;
+          gIndex++;
+          parameters.add(
+            ParameterElementImpl.synthetic(
+              fParameter.name,
+              _typeSystem.getLeastUpperBound(fParameter.type, gParameter.type),
+              fParameter.isOptional || gParameter.isOptional
+                  ? ParameterKind.POSITIONAL
+                  : ParameterKind.REQUIRED,
+            ),
+          );
+        } else {
+          return NeverTypeImpl.instance;
+        }
+      } else if (fParameter.isNamed) {
+        if (gParameter.isNamed) {
+          var compareNames = fParameter.name.compareTo(gParameter.name);
+          if (compareNames == 0) {
+            fIndex++;
+            gIndex++;
+            parameters.add(
+              ParameterElementImpl.synthetic(
+                fParameter.name,
+                _typeSystem.getLeastUpperBound(
+                    fParameter.type, gParameter.type),
+                fParameter.isRequiredNamed && gParameter.isRequiredNamed
+                    ? ParameterKind.NAMED_REQUIRED
+                    : ParameterKind.NAMED,
+              ),
+            );
+          } else if (compareNames < 0) {
+            fIndex++;
+            parameters.add(
+              ParameterElementImpl.synthetic(
+                fParameter.name,
+                fParameter.type,
+                ParameterKind.NAMED,
+              ),
+            );
+          } else {
+            assert(compareNames > 0);
+            gIndex++;
+            parameters.add(
+              ParameterElementImpl.synthetic(
+                gParameter.name,
+                gParameter.type,
+                ParameterKind.NAMED,
+              ),
+            );
+          }
+        } else {
+          return NeverTypeImpl.instance;
+        }
+      }
+    }
+
+    while (fIndex < fParameters.length) {
+      var fParameter = fParameters[fIndex++];
+      if (fParameter.isPositional) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            fParameter.name,
+            fParameter.type,
+            ParameterKind.POSITIONAL,
+          ),
+        );
+      } else {
+        assert(fParameter.isNamed);
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            fParameter.name,
+            fParameter.type,
+            ParameterKind.NAMED,
+          ),
+        );
+      }
+    }
+
+    while (gIndex < gParameters.length) {
+      var gParameter = gParameters[gIndex++];
+      if (gParameter.isPositional) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            gParameter.name,
+            gParameter.type,
+            ParameterKind.POSITIONAL,
+          ),
+        );
+      } else {
+        assert(gParameter.isNamed);
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            gParameter.name,
+            gParameter.type,
+            ParameterKind.NAMED,
+          ),
+        );
+      }
+    }
+
+    var returnType = getGreatestLowerBound(f.returnType, g.returnType);
+
+    return FunctionTypeImpl(
+      typeFormals: typeFormals,
+      parameters: parameters,
+      returnType: returnType,
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index bf23dce..6f4e1f1 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -75,6 +75,7 @@
         type.element,
         interface._inheritedMap,
         interface._overridden,
+        doTopMerge: false,
       );
     }
     return interface._inheritedMap;
@@ -106,20 +107,12 @@
     Map<Name, ExecutableElement> declared;
     Interface superInterface;
     Map<Name, ExecutableElement> implemented;
+    List<List<Conflict>> mixinsConflicts = [];
     try {
       // If a class declaration has a member declaration, the signature of that
       // member declaration becomes the signature in the interface.
       declared = _getTypeMembers(type);
 
-      for (var interface in type.interfaces.reversed) {
-        var interfaceObj = getInterface(interface);
-        _addCandidates(
-          namedCandidates,
-          interfaceObj,
-          isNonNullableByDefault: isNonNullableByDefault,
-        );
-      }
-
       if (classElement.isMixin) {
         var superClassCandidates = <Name, List<ExecutableElement>>{};
         for (var constraint in type.superclassConstraints) {
@@ -145,6 +138,7 @@
           classElement,
           superClass,
           superClassCandidates,
+          doTopMerge: true,
         );
         superImplemented.add(superClass);
       } else {
@@ -156,35 +150,109 @@
             isNonNullableByDefault: isNonNullableByDefault,
           );
 
-          implemented = superInterface.implemented;
+          if (isNonNullableByDefault) {
+            implemented = superInterface.implemented;
+          } else {
+            implemented = {};
+            for (var entry in superInterface.implemented.entries) {
+              implemented[entry.key] = Member.legacy(entry.value);
+            }
+          }
+
           superImplemented.add(implemented);
         } else {
           implemented = {};
         }
 
+        // TODO(scheglov) Handling of members for super and mixins is not
+        // optimal. We always have just one member for each name in super,
+        // multiple candidates happen only when we merge super and multiple
+        // interfaces. Consider using `Map<Name, ExecutableElement>` here.
         for (var mixin in type.mixins) {
+          var mixinElement = mixin.element;
           var interfaceObj = getInterface(mixin);
-          _addCandidates(
-            namedCandidates,
-            interfaceObj,
-            isNonNullableByDefault: isNonNullableByDefault,
-          );
+          // `class X extends S with M1, M2 {}` is semantically a sequence of:
+          //     class S&M1 extends S implements M1 {
+          //       // declared M1 members
+          //     }
+          //     class S&M2 extends S&M1 implements M2 {
+          //       // declared M2 members
+          //     }
+          //     class X extends S&M2 {
+          //       // declared X members
+          //     }
+          // So, each mixin always replaces members in the interface.
+          // And there are individual override conflicts for each mixin.
+          var candidatesFromSuperAndMixin = <Name, List<ExecutableElement>>{};
+          var mixinConflicts = <Conflict>[];
+          for (var name in interfaceObj.map.keys) {
+            var candidate = interfaceObj.map[name];
+
+            var currentList = namedCandidates[name];
+            if (currentList == null) {
+              namedCandidates[name] = [
+                isNonNullableByDefault ? candidate : Member.legacy(candidate),
+              ];
+              continue;
+            }
+
+            var current = currentList.single;
+            if (candidate.enclosingElement == mixinElement) {
+              namedCandidates[name] = [
+                isNonNullableByDefault ? candidate : Member.legacy(candidate),
+              ];
+              if (current.kind != candidate.kind) {
+                var currentIsGetter = current.kind == ElementKind.GETTER;
+                mixinConflicts.add(
+                  Conflict(
+                    name,
+                    [current, candidate],
+                    currentIsGetter ? current : candidate,
+                    currentIsGetter ? candidate : current,
+                  ),
+                );
+              }
+            } else {
+              candidatesFromSuperAndMixin[name] = [current, candidate];
+            }
+          }
+
+          // Merge members from the superclass and the mixin interface.
+          {
+            var map = <Name, ExecutableElement>{};
+            _findMostSpecificFromNamedCandidates(
+              classElement,
+              map,
+              candidatesFromSuperAndMixin,
+              doTopMerge: true,
+            );
+            for (var entry in map.entries) {
+              namedCandidates[entry.key] = [
+                isNonNullableByDefault
+                    ? entry.value
+                    : Member.legacy(entry.value),
+              ];
+            }
+          }
+
+          mixinsConflicts.add(mixinConflicts);
 
           implemented = <Name, ExecutableElement>{}..addAll(implemented);
-          implemented.addEntries(
-            interfaceObj.implemented.entries.where((entry) {
-              var executable = entry.value;
-              if (executable.isAbstract) {
-                return false;
-              }
-              var class_ = executable.enclosingElement;
-              return class_ is ClassElement && !class_.isDartCoreObject;
-            }),
-          );
+          _addMixinMembers(implemented, interfaceObj,
+              isNonNullableByDefault: isNonNullableByDefault);
 
           superImplemented.add(implemented);
         }
       }
+
+      for (var interface in type.interfaces) {
+        var interfaceObj = getInterface(interface);
+        _addCandidates(
+          namedCandidates,
+          interfaceObj,
+          isNonNullableByDefault: isNonNullableByDefault,
+        );
+      }
     } finally {
       _processingClasses.remove(classElement);
     }
@@ -203,6 +271,7 @@
       classElement,
       map,
       namedCandidates,
+      doTopMerge: true,
     );
 
     var noSuchMethodForwarders = <Name>{};
@@ -224,6 +293,15 @@
       }
     }
 
+    /// TODO(scheglov) Instead of merging conflicts we could report them on
+    /// the corresponding mixins applied in the class.
+    for (var mixinConflicts in mixinsConflicts) {
+      if (mixinConflicts.isNotEmpty) {
+        conflicts ??= [];
+        conflicts.addAll(mixinConflicts);
+      }
+    }
+
     var interface = Interface._(
       map,
       declared,
@@ -237,6 +315,30 @@
     return interface;
   }
 
+  void _addMixinMembers(
+    Map<Name, ExecutableElement> implemented,
+    Interface mixin, {
+    @required bool isNonNullableByDefault,
+  }) {
+    for (var entry in mixin.implemented.entries) {
+      var executable = entry.value;
+      if (executable.isAbstract) {
+        continue;
+      }
+
+      var class_ = executable.enclosingElement;
+      if (class_ is ClassElement && class_.isDartCoreObject) {
+        continue;
+      }
+
+      if (!isNonNullableByDefault) {
+        executable = Member.legacy(executable);
+      }
+
+      implemented[entry.key] = executable;
+    }
+  }
+
   /// Return the member with the given [name].
   ///
   /// If [concrete] is `true`, the the concrete implementation is returned,
@@ -380,9 +482,11 @@
   /// such single most specific signature (i.e. no valid override), then add a
   /// new conflict description.
   List<Conflict> _findMostSpecificFromNamedCandidates(
-      ClassElement targetClass,
-      Map<Name, ExecutableElement> map,
-      Map<Name, List<ExecutableElement>> namedCandidates) {
+    ClassElement targetClass,
+    Map<Name, ExecutableElement> map,
+    Map<Name, List<ExecutableElement>> namedCandidates, {
+    @required bool doTopMerge,
+  }) {
     TypeSystemImpl typeSystem = targetClass.library.typeSystem;
 
     List<Conflict> conflicts;
@@ -407,13 +511,8 @@
         conflicts.add(conflict);
       }
 
-      // Candidates are recorded in forward order, so
-      // `class X extends S with M1, M2 implements I1, I2 {}` will record
-      // candidates from [I1, I2, S, M1, M2]. But during method lookup
-      // candidates should be considered in backward order, i.e. from `M2`,
-      // then from `M1`, then from `S`.
       var validOverrides = <ExecutableElement>[];
-      for (var i = candidates.length - 1; i >= 0; i--) {
+      for (var i = 0; i < candidates.length; i++) {
         var validOverride = candidates[i];
         var overrideHelper = CorrectOverrideHelper(
           library: targetClass.library,
@@ -437,7 +536,11 @@
         continue;
       }
 
-      map[name] = _topMerge(typeSystem, targetClass, validOverrides);
+      if (doTopMerge) {
+        map[name] = _topMerge(typeSystem, targetClass, validOverrides);
+      } else {
+        map[name] = validOverrides.first;
+      }
     }
 
     return conflicts;
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
new file mode 100644
index 0000000..21fe0b0
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -0,0 +1,818 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:meta/meta.dart';
+
+/// The instantiation of a [ClassElement] with type arguments.
+///
+/// It is not a [DartType] itself, because it does not have nullability.
+/// But it should be used where nullability does not make sense - to specify
+/// superclasses, mixins, and implemented interfaces.
+class InstantiatedClass {
+  final ClassElement element;
+  final List<DartType> arguments;
+
+  final Substitution _substitution;
+
+  InstantiatedClass(this.element, this.arguments)
+      : _substitution = Substitution.fromPairs(
+          element.typeParameters,
+          arguments,
+        );
+
+  /// Return the [InstantiatedClass] that corresponds to the [type] - with the
+  /// same element and type arguments, ignoring its nullability suffix.
+  factory InstantiatedClass.of(InterfaceType type) {
+    return InstantiatedClass(type.element, type.typeArguments);
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0x3fffffff & element.hashCode;
+    for (var i = 0; i < arguments.length; i++) {
+      hash = 0x3fffffff & (hash * 31 + (hash ^ arguments[i].hashCode));
+    }
+    return hash;
+  }
+
+  /// Return the interfaces that are directly implemented by this class.
+  List<InstantiatedClass> get interfaces {
+    var interfaces = element.interfaces;
+
+    var result = List<InstantiatedClass>(interfaces.length);
+    for (var i = 0; i < interfaces.length; i++) {
+      var interface = interfaces[i];
+      var substituted = _substitution.substituteType(interface);
+      result[i] = InstantiatedClass.of(substituted);
+    }
+
+    return result;
+  }
+
+  /// Return `true` if this type represents the type 'Function' defined in the
+  /// dart:core library.
+  bool get isDartCoreFunction {
+    return element.name == 'Function' && element.library.isDartCore;
+  }
+
+  /// Return the superclass of this type, or `null` if this type represents
+  /// the class 'Object'.
+  InstantiatedClass get superclass {
+    var supertype = element.supertype;
+    if (supertype == null) return null;
+
+    supertype = _substitution.substituteType(supertype);
+    return InstantiatedClass.of(supertype);
+  }
+
+  /// Return a list containing all of the superclass constraints defined for
+  /// this class. The list will be empty if this class does not represent a
+  /// mixin declaration. If this class _does_ represent a mixin declaration but
+  /// the declaration does not have an `on` clause, then the list will contain
+  /// the type for the class `Object`.
+  List<InstantiatedClass> get superclassConstraints {
+    var constraints = element.superclassConstraints;
+
+    var result = List<InstantiatedClass>(constraints.length);
+    for (var i = 0; i < constraints.length; i++) {
+      var constraint = constraints[i];
+      var substituted = _substitution.substituteType(constraint);
+      result[i] = InstantiatedClass.of(substituted);
+    }
+
+    return result;
+  }
+
+  @visibleForTesting
+  InterfaceType get withNullabilitySuffixNone {
+    return withNullability(NullabilitySuffix.none);
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+
+    if (other is InstantiatedClass) {
+      if (element != other.element) return false;
+      if (arguments.length != other.arguments.length) return false;
+      for (var i = 0; i < arguments.length; i++) {
+        if (arguments[i] != other.arguments[i]) return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  String toString() {
+    var buffer = StringBuffer();
+    buffer.write(element.name);
+    if (arguments.isNotEmpty) {
+      buffer.write('<');
+      buffer.write(arguments.join(', '));
+      buffer.write('>');
+    }
+    return buffer.toString();
+  }
+
+  InterfaceType withNullability(NullabilitySuffix nullability) {
+    return InterfaceTypeImpl(
+      element: element,
+      typeArguments: arguments,
+      nullabilitySuffix: nullability,
+    );
+  }
+}
+
+class InterfaceLeastUpperBoundHelper {
+  final TypeSystemImpl typeSystem;
+
+  InterfaceLeastUpperBoundHelper(this.typeSystem);
+
+  /// This currently does not implement a very complete least upper bound
+  /// algorithm, but handles a couple of the very common cases that are
+  /// causing pain in real code.  The current algorithm is:
+  /// 1. If either of the types is a supertype of the other, return it.
+  ///    This is in fact the best result in this case.
+  /// 2. If the two types have the same class element and are implicitly or
+  ///    explicitly covariant, then take the pointwise least upper bound of
+  ///    the type arguments. This is again the best result, except that the
+  ///    recursive calls may not return the true least upper bounds. The
+  ///    result is guaranteed to be a well-formed type under the assumption
+  ///    that the input types were well-formed (and assuming that the
+  ///    recursive calls return well-formed types).
+  ///    If the variance of the type parameter is contravariant, we take the
+  ///    greatest lower bound of the type arguments. If the variance of the
+  ///    type parameter is invariant, we verify if the type arguments satisfy
+  ///    subtyping in both directions, then choose a bound.
+  /// 3. Otherwise return the spec-defined least upper bound.  This will
+  ///    be an upper bound, might (or might not) be least, and might
+  ///    (or might not) be a well-formed type.
+  ///
+  /// TODO(leafp): Use matchTypes or something similar here to handle the
+  ///  case where one of the types is a superclass (but not supertype) of
+  ///  the other, e.g. LUB(Iterable<double>, List<int>) = Iterable<num>
+  /// TODO(leafp): Figure out the right final algorithm and implement it.
+  InterfaceTypeImpl compute(InterfaceTypeImpl type1, InterfaceTypeImpl type2) {
+    var nullability = _chooseNullability(type1, type2);
+
+    // Strip off nullability.
+    type1 = type1.withNullability(NullabilitySuffix.none);
+    type2 = type2.withNullability(NullabilitySuffix.none);
+
+    if (typeSystem.isSubtypeOf2(type1, type2)) {
+      return type2.withNullability(nullability);
+    }
+    if (typeSystem.isSubtypeOf2(type2, type1)) {
+      return type1.withNullability(nullability);
+    }
+
+    if (type1.element == type2.element) {
+      var args1 = type1.typeArguments;
+      var args2 = type2.typeArguments;
+      var params = type1.element.typeParameters;
+      assert(args1.length == args2.length);
+      assert(args1.length == params.length);
+
+      var args = List<DartType>(args1.length);
+      for (int i = 0; i < args1.length; i++) {
+        // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
+        // variance is added to the interface.
+        Variance parameterVariance =
+            (params[i] as TypeParameterElementImpl).variance;
+        if (parameterVariance.isCovariant) {
+          args[i] = typeSystem.getLeastUpperBound(args1[i], args2[i]);
+        } else if (parameterVariance.isContravariant) {
+          if (typeSystem is TypeSystemImpl) {
+            args[i] = typeSystem.getGreatestLowerBound(args1[i], args2[i]);
+          } else {
+            args[i] = typeSystem.getLeastUpperBound(args1[i], args2[i]);
+          }
+        } else if (parameterVariance.isInvariant) {
+          if (!typeSystem.isSubtypeOf2(args1[i], args2[i]) ||
+              !typeSystem.isSubtypeOf2(args2[i], args1[i])) {
+            // No bound will be valid, find bound at the interface level.
+            return _computeLeastUpperBound(
+              InstantiatedClass.of(type1),
+              InstantiatedClass.of(type2),
+            ).withNullability(nullability);
+          }
+          // TODO (kallentu) : Fix asymmetric bounds behavior for invariant type
+          //  parameters.
+          args[i] = args1[i];
+        } else {
+          throw StateError('Type parameter ${params[i]} has unknown '
+              'variance $parameterVariance for bounds calculation.');
+        }
+      }
+
+      return InterfaceTypeImpl(
+        element: type1.element,
+        typeArguments: args,
+        nullabilitySuffix: nullability,
+      );
+    }
+
+    var result = _computeLeastUpperBound(
+      InstantiatedClass.of(type1),
+      InstantiatedClass.of(type2),
+    );
+    return result.withNullability(nullability);
+  }
+
+  /// Compute the least upper bound of types [i] and [j], both of which are
+  /// known to be interface types.
+  ///
+  /// In the event that the algorithm fails (which might occur due to a bug in
+  /// the analyzer), `null` is returned.
+  InstantiatedClass _computeLeastUpperBound(
+    InstantiatedClass i,
+    InstantiatedClass j,
+  ) {
+    // compute set of supertypes
+    var si = computeSuperinterfaceSet(i);
+    var sj = computeSuperinterfaceSet(j);
+
+    // union si with i and sj with j
+    si.add(i);
+    sj.add(j);
+
+    // compute intersection, reference as set 's'
+    var s = _intersection(si, sj);
+    return _computeTypeAtMaxUniqueDepth(s);
+  }
+
+  /**
+   * Return the length of the longest inheritance path from the [element] to
+   * Object.
+   */
+  @visibleForTesting
+  static int computeLongestInheritancePathToObject(ClassElement element) {
+    return _computeLongestInheritancePathToObject(
+      element,
+      0,
+      <ClassElement>{},
+    );
+  }
+
+  /// Return all of the superinterfaces of the given [type].
+  @visibleForTesting
+  static Set<InstantiatedClass> computeSuperinterfaceSet(
+      InstantiatedClass type) {
+    var result = <InstantiatedClass>{};
+    _addSuperinterfaces(result, type);
+    return result;
+  }
+
+  /// Add all of the superinterfaces of the given [type] to the given [set].
+  static void _addSuperinterfaces(
+      Set<InstantiatedClass> set, InstantiatedClass type) {
+    for (var interface in type.interfaces) {
+      if (!interface.isDartCoreFunction) {
+        if (set.add(interface)) {
+          _addSuperinterfaces(set, interface);
+        }
+      }
+    }
+
+    for (var constraint in type.superclassConstraints) {
+      if (!constraint.isDartCoreFunction) {
+        if (set.add(constraint)) {
+          _addSuperinterfaces(set, constraint);
+        }
+      }
+    }
+
+    var supertype = type.superclass;
+    if (supertype != null && !supertype.isDartCoreFunction) {
+      if (set.add(supertype)) {
+        _addSuperinterfaces(set, supertype);
+      }
+    }
+  }
+
+  static NullabilitySuffix _chooseNullability(
+    InterfaceTypeImpl type1,
+    InterfaceTypeImpl type2,
+  ) {
+    var nullability1 = type1.nullabilitySuffix;
+    var nullability2 = type2.nullabilitySuffix;
+    if (nullability1 == NullabilitySuffix.question ||
+        nullability2 == NullabilitySuffix.question) {
+      return NullabilitySuffix.question;
+    } else if (nullability1 == NullabilitySuffix.star ||
+        nullability2 == NullabilitySuffix.star) {
+      return NullabilitySuffix.star;
+    }
+    return NullabilitySuffix.none;
+  }
+
+  /// Return the length of the longest inheritance path from a subtype of the
+  /// given [element] to Object, where the given [depth] is the length of the
+  /// longest path from the subtype to this type. The set of [visitedElements]
+  /// is used to prevent infinite recursion in the case of a cyclic type
+  /// structure.
+  static int _computeLongestInheritancePathToObject(
+      ClassElement element, int depth, Set<ClassElement> visitedElements) {
+    // Object case
+    if (element.isDartCoreObject || visitedElements.contains(element)) {
+      return depth;
+    }
+    int longestPath = 1;
+    try {
+      visitedElements.add(element);
+      int pathLength;
+
+      // loop through each of the superinterfaces recursively calling this
+      // method and keeping track of the longest path to return
+      for (InterfaceType interface in element.superclassConstraints) {
+        pathLength = _computeLongestInheritancePathToObject(
+            interface.element, depth + 1, visitedElements);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
+        }
+      }
+
+      // loop through each of the superinterfaces recursively calling this
+      // method and keeping track of the longest path to return
+      for (InterfaceType interface in element.interfaces) {
+        pathLength = _computeLongestInheritancePathToObject(
+            interface.element, depth + 1, visitedElements);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
+        }
+      }
+
+      // finally, perform this same check on the super type
+      // TODO(brianwilkerson) Does this also need to add in the number of mixin
+      // classes?
+      InterfaceType supertype = element.supertype;
+      if (supertype != null) {
+        pathLength = _computeLongestInheritancePathToObject(
+            supertype.element, depth + 1, visitedElements);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
+        }
+      }
+    } finally {
+      visitedElements.remove(element);
+    }
+    return longestPath;
+  }
+
+  /// Return the type from the [types] list that has the longest inheritance
+  /// path to Object of unique length.
+  static InstantiatedClass _computeTypeAtMaxUniqueDepth(
+    List<InstantiatedClass> types,
+  ) {
+    // for each element in Set s, compute the largest inheritance path to Object
+    List<int> depths = List<int>.filled(types.length, 0);
+    int maxDepth = 0;
+    for (int i = 0; i < types.length; i++) {
+      depths[i] = computeLongestInheritancePathToObject(types[i].element);
+      if (depths[i] > maxDepth) {
+        maxDepth = depths[i];
+      }
+    }
+    // ensure that the currently computed maxDepth is unique,
+    // otherwise, decrement and test for uniqueness again
+    for (; maxDepth >= 0; maxDepth--) {
+      int indexOfLeastUpperBound = -1;
+      int numberOfTypesAtMaxDepth = 0;
+      for (int m = 0; m < depths.length; m++) {
+        if (depths[m] == maxDepth) {
+          numberOfTypesAtMaxDepth++;
+          indexOfLeastUpperBound = m;
+        }
+      }
+      if (numberOfTypesAtMaxDepth == 1) {
+        return types[indexOfLeastUpperBound];
+      }
+    }
+    // Should be impossible--there should always be exactly one type with the
+    // maximum depth.
+    assert(false);
+    return null;
+  }
+
+  /**
+   * Return the intersection of the [first] and [second] sets of types, where
+   * intersection is based on the equality of the types themselves.
+   */
+  static List<InstantiatedClass> _intersection(
+    Set<InstantiatedClass> first,
+    Set<InstantiatedClass> second,
+  ) {
+    var result = first.toSet();
+    result.retainAll(second);
+    return result.toList();
+  }
+}
+
+class LeastUpperBoundHelper {
+  final TypeSystemImpl _typeSystem;
+
+  LeastUpperBoundHelper(this._typeSystem);
+
+  InterfaceType get _interfaceTypeFunctionNone {
+    return _typeSystem.typeProvider.functionType.element.instantiate(
+      typeArguments: const [],
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  InterfaceType get _objectType => _typeSystem.typeProvider.objectType;
+
+  /**
+   * Compute the least upper bound of two types.
+   *
+   * https://github.com/dart-lang/language
+   * See `resources/type-system/upper-lower-bounds.md`
+   */
+  DartType getLeastUpperBound(DartType T1, DartType T2) {
+    // UP(T, T) = T
+    if (identical(T1, T2)) {
+      return T1;
+    }
+
+    // For any type T, UP(?, T) == T.
+    if (identical(T1, UnknownInferredType.instance)) {
+      return T2;
+    }
+    if (identical(T2, UnknownInferredType.instance)) {
+      return T1;
+    }
+
+    var T1_isTop = _typeSystem.isTop(T1);
+    var T2_isTop = _typeSystem.isTop(T2);
+
+    // UP(T1, T2) where TOP(T1) and TOP(T2)
+    if (T1_isTop && T2_isTop) {
+      // * T1 if MORETOP(T1, T2)
+      // * T2 otherwise
+      if (_typeSystem.isMoreTop(T1, T2)) {
+        return T1;
+      } else {
+        return T2;
+      }
+    }
+
+    // UP(T1, T2) = T1 if TOP(T1)
+    if (T1_isTop) {
+      return T1;
+    }
+
+    // UP(T1, T2) = T2 if TOP(T2)
+    if (T2_isTop) {
+      return T2;
+    }
+
+    var T1_isBottom = _typeSystem.isBottom(T1);
+    var T2_isBottom = _typeSystem.isBottom(T2);
+
+    // UP(T1, T2) where BOTTOM(T1) and BOTTOM(T2)
+    if (T1_isBottom && T2_isBottom) {
+      // * T2 if MOREBOTTOM(T1, T2)
+      // * T1 otherwise
+      if (_typeSystem.isMoreBottom(T1, T2)) {
+        return T2;
+      } else {
+        return T1;
+      }
+    }
+
+    // UP(T1, T2) = T2 if BOTTOM(T1)
+    if (T1_isBottom) {
+      return T2;
+    }
+
+    // UP(T1, T2) = T1 if BOTTOM(T2)
+    if (T2_isBottom) {
+      return T1;
+    }
+
+    var T1_isNull = _typeSystem.isNull(T1);
+    var T2_isNull = _typeSystem.isNull(T2);
+
+    // UP(T1, T2) where NULL(T1) and NULL(T2)
+    if (T1_isNull && T2_isNull) {
+      // * T2 if MOREBOTTOM(T1, T2)
+      // * T1 otherwise
+      if (_typeSystem.isMoreBottom(T1, T2)) {
+        return T2;
+      } else {
+        return T1;
+      }
+    }
+
+    var T1_impl = T1 as TypeImpl;
+    var T2_impl = T2 as TypeImpl;
+
+    var T1_nullability = T1_impl.nullabilitySuffix;
+    var T2_nullability = T2_impl.nullabilitySuffix;
+
+    // UP(T1, T2) where NULL(T1)
+    if (T1_isNull) {
+      // * T2 if T2 is nullable
+      // * T2* if Null <: T2 or T1 <: Object (that is, T1 or T2 is legacy)
+      // * T2? otherwise
+      if (_typeSystem.isNullable(T2)) {
+        return T2;
+      } else if (T1_nullability == NullabilitySuffix.star ||
+          T2_nullability == NullabilitySuffix.star) {
+        return T2_impl.withNullability(NullabilitySuffix.star);
+      } else {
+        return _typeSystem.makeNullable(T2);
+      }
+    }
+
+    // UP(T1, T2) where NULL(T2)
+    if (T2_isNull) {
+      // * T1 if T1 is nullable
+      // * T1* if Null <: T1 or T2 <: Object (that is, T1 or T2 is legacy)
+      // * T1? otherwise
+      if (_typeSystem.isNullable(T1)) {
+        return T1;
+      } else if (T1_nullability == NullabilitySuffix.star ||
+          T2_nullability == NullabilitySuffix.star) {
+        return T1_impl.withNullability(NullabilitySuffix.star);
+      } else {
+        return _typeSystem.makeNullable(T1);
+      }
+    }
+
+    var T1_isObject = _typeSystem.isObject(T1);
+    var T2_isObject = _typeSystem.isObject(T2);
+
+    // UP(T1, T2) where OBJECT(T1) and OBJECT(T2)
+    if (T1_isObject && T2_isObject) {
+      // * T1 if MORETOP(T1, T2)
+      // * T2 otherwise
+      if (_typeSystem.isMoreTop(T1, T2)) {
+        return T1;
+      } else {
+        return T2;
+      }
+    }
+
+    // UP(T1, T2) where OBJECT(T1)
+    if (T1_isObject) {
+      // * T1 if T2 is non-nullable
+      // * T1? otherwise
+      if (_typeSystem.isNonNullable(T2)) {
+        return T1;
+      } else {
+        return _typeSystem.makeNullable(T1);
+      }
+    }
+
+    // UP(T1, T2) where OBJECT(T2)
+    if (T2_isObject) {
+      // * T2 if T1 is non-nullable
+      // * T2? otherwise
+      if (_typeSystem.isNonNullable(T1)) {
+        return T2;
+      } else {
+        return _typeSystem.makeNullable(T2);
+      }
+    }
+
+    // UP(T1*, T2*) = S* where S is UP(T1, T2)
+    // UP(T1*, T2?) = S? where S is UP(T1, T2)
+    // UP(T1?, T2*) = S? where S is UP(T1, T2)
+    // UP(T1*, T2) = S* where S is UP(T1, T2)
+    // UP(T1, T2*) = S* where S is UP(T1, T2)
+    // UP(T1?, T2?) = S? where S is UP(T1, T2)
+    // UP(T1?, T2) = S? where S is UP(T1, T2)
+    // UP(T1, T2?) = S? where S is UP(T1, T2)
+    if (T1_nullability != NullabilitySuffix.none ||
+        T2_nullability != NullabilitySuffix.none) {
+      var resultNullability = NullabilitySuffix.none;
+      if (T1_nullability == NullabilitySuffix.question ||
+          T2_nullability == NullabilitySuffix.question) {
+        resultNullability = NullabilitySuffix.question;
+      } else if (T1_nullability == NullabilitySuffix.star ||
+          T2_nullability == NullabilitySuffix.star) {
+        resultNullability = NullabilitySuffix.star;
+      }
+      var T1_none = T1_impl.withNullability(NullabilitySuffix.none);
+      var T2_none = T2_impl.withNullability(NullabilitySuffix.none);
+      var S = getLeastUpperBound(T1_none, T2_none);
+      return (S as TypeImpl).withNullability(resultNullability);
+    }
+
+    assert(T1_nullability == NullabilitySuffix.none);
+    assert(T2_nullability == NullabilitySuffix.none);
+
+    // UP(X1 extends B1, T2)
+    // UP(X1 & B1, T2)
+    if (T1 is TypeParameterType) {
+      // T2 if X1 <: T2
+      if (_typeSystem.isSubtypeOf2(T1, T2)) {
+        return T2;
+      }
+      // otherwise X1 if T2 <: X1
+      if (_typeSystem.isSubtypeOf2(T2, T1)) {
+        return T1;
+      }
+      // otherwise UP(B1[Object/X1], T2)
+      var T1_toObject = _typeParameterResolveToObjectBounds(T1);
+      return getLeastUpperBound(T1_toObject, T2);
+    }
+
+    // UP(T1, X2 extends B2)
+    // UP(T1, X2 & B2)
+    if (T2 is TypeParameterType) {
+      // X2 if T1 <: X2
+      if (_typeSystem.isSubtypeOf2(T1, T2)) {
+        // TODO(scheglov) How to get here?
+        return T2;
+      }
+      // otherwise T1 if X2 <: T1
+      if (_typeSystem.isSubtypeOf2(T2, T1)) {
+        return T1;
+      }
+      // otherwise UP(T1, B2[Object/X2])
+      var T2_toObject = _typeParameterResolveToObjectBounds(T2);
+      return getLeastUpperBound(T1, T2_toObject);
+    }
+
+    // UP(T Function<...>(...), Function) = Function
+    if (T1 is FunctionType && T2.isDartCoreFunction) {
+      return T2;
+    }
+
+    // UP(Function, T Function<...>(...)) = Function
+    if (T1.isDartCoreFunction && T2 is FunctionType) {
+      return T1;
+    }
+
+    // UP(T Function<...>(...), S Function<...>(...)) = Function
+    // And other, more interesting variants.
+    if (T1 is FunctionType && T2 is FunctionType) {
+      return _functionType(T1, T2);
+    }
+
+    // UP(T Function<...>(...), T2) = Object
+    // UP(T1, T Function<...>(...)) = Object
+    if (T1 is FunctionType || T2 is FunctionType) {
+      return _typeSystem.objectNone;
+    }
+
+    // UP(T1, T2) = T2 if T1 <: T2
+    // UP(T1, T2) = T1 if T2 <: T1
+    // And other, more complex variants of interface types.
+    var helper = InterfaceLeastUpperBoundHelper(_typeSystem);
+    return helper.compute(T1, T2);
+  }
+
+  /**
+   * Compute the least upper bound of function types [f] and [g].
+   *
+   * https://github.com/dart-lang/language
+   * See `resources/type-system/upper-lower-bounds.md`
+   */
+  DartType _functionType(FunctionType f, FunctionType g) {
+    var fTypeFormals = f.typeFormals;
+    var gTypeFormals = g.typeFormals;
+
+    // The number of type parameters must be the same.
+    // Otherwise the result is `Function`.
+    if (fTypeFormals.length != gTypeFormals.length) {
+      return _interfaceTypeFunctionNone;
+    }
+
+    // The bounds of type parameters must be equal.
+    // Otherwise the result is `Function`.
+    var freshTypeFormalTypes =
+        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
+    if (freshTypeFormalTypes == null) {
+      return _interfaceTypeFunctionNone;
+    }
+
+    var typeFormals = freshTypeFormalTypes
+        .map<TypeParameterElement>((t) => t.element)
+        .toList();
+
+    f = f.instantiate(freshTypeFormalTypes);
+    g = g.instantiate(freshTypeFormalTypes);
+
+    var fParameters = f.parameters;
+    var gParameters = g.parameters;
+
+    var parameters = <ParameterElement>[];
+    var fIndex = 0;
+    var gIndex = 0;
+    while (fIndex < fParameters.length && gIndex < gParameters.length) {
+      var fParameter = fParameters[fIndex];
+      var gParameter = gParameters[gIndex];
+      if (fParameter.isRequiredPositional) {
+        if (gParameter.isRequiredPositional) {
+          fIndex++;
+          gIndex++;
+          parameters.add(
+            ParameterElementImpl.synthetic(
+              fParameter.name,
+              _parameterType(fParameter, gParameter),
+              ParameterKind.REQUIRED,
+            ),
+          );
+        } else {
+          break;
+        }
+      } else if (fParameter.isOptionalPositional) {
+        if (gParameter.isOptionalPositional) {
+          fIndex++;
+          gIndex++;
+          parameters.add(
+            ParameterElementImpl.synthetic(
+              fParameter.name,
+              _parameterType(fParameter, gParameter),
+              ParameterKind.POSITIONAL,
+            ),
+          );
+        } else {
+          break;
+        }
+      } else if (fParameter.isNamed) {
+        if (gParameter.isNamed) {
+          var compareNames = fParameter.name.compareTo(gParameter.name);
+          if (compareNames == 0) {
+            fIndex++;
+            gIndex++;
+            parameters.add(
+              ParameterElementImpl.synthetic(
+                fParameter.name,
+                _parameterType(fParameter, gParameter),
+                fParameter.isRequiredNamed || gParameter.isRequiredNamed
+                    ? ParameterKind.NAMED_REQUIRED
+                    : ParameterKind.NAMED,
+              ),
+            );
+          } else if (compareNames < 0) {
+            if (fParameter.isRequiredNamed) {
+              // We cannot skip required named.
+              return _interfaceTypeFunctionNone;
+            } else {
+              fIndex++;
+            }
+          } else {
+            assert(compareNames > 0);
+            if (gParameter.isRequiredNamed) {
+              // We cannot skip required named.
+              return _interfaceTypeFunctionNone;
+            } else {
+              gIndex++;
+            }
+          }
+        } else {
+          break;
+        }
+      }
+    }
+
+    while (fIndex < fParameters.length) {
+      var fParameter = fParameters[fIndex++];
+      if (fParameter.isNotOptional) {
+        return _interfaceTypeFunctionNone;
+      }
+    }
+
+    while (gIndex < gParameters.length) {
+      var gParameter = gParameters[gIndex++];
+      if (gParameter.isNotOptional) {
+        return _interfaceTypeFunctionNone;
+      }
+    }
+
+    var returnType = getLeastUpperBound(f.returnType, g.returnType);
+
+    return FunctionTypeImpl(
+      typeFormals: typeFormals,
+      parameters: parameters,
+      returnType: returnType,
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  DartType _parameterType(ParameterElement a, ParameterElement b) {
+    return _typeSystem.getGreatestLowerBound(a.type, b.type);
+  }
+
+  DartType _typeParameterResolveToObjectBounds(DartType type) {
+    var element = type.element;
+    type = type.resolveToBound(_objectType);
+    return Substitution.fromMap({element: _objectType}).substituteType(type);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index eda8b3d..2fc7443 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -388,29 +388,13 @@
 }
 
 class FunctionMember extends ExecutableMember implements FunctionElement {
-  factory FunctionMember(
-    FunctionElement declaration,
-    MapSubstitution substitution,
-    bool isLegacy,
-  ) {
-    var freshTypeParameters = _SubstitutedTypeParameters(
-      declaration.typeParameters,
-      substitution,
-    );
-    return FunctionMember._(
-      declaration,
-      freshTypeParameters.substitution,
-      isLegacy,
-      freshTypeParameters.elements,
-    );
-  }
-
-  FunctionMember._(
-    FunctionElement declaration,
-    MapSubstitution substitution,
-    bool isLegacy,
-    List<TypeParameterElement> typeParameters,
-  ) : super(declaration, substitution, isLegacy, typeParameters);
+  FunctionMember(FunctionElement declaration, bool isLegacy)
+      : super(
+          declaration,
+          Substitution.empty,
+          isLegacy,
+          declaration.typeParameters,
+        );
 
   @override
   FunctionElement get declaration => super.declaration;
@@ -658,15 +642,8 @@
     } else if (element is FunctionElement) {
       if (!element.library.isNonNullableByDefault) {
         return element;
-      } else if (element is Member) {
-        var member = element as Member;
-        return FunctionMember(
-          member._declaration,
-          member._substitution,
-          true,
-        );
       } else {
-        return FunctionMember(element, Substitution.empty, true);
+        return FunctionMember(element.declaration, true);
       }
     } else if (element is MethodElement) {
       if (!element.library.isNonNullableByDefault) {
@@ -1044,6 +1021,7 @@
   @override
   VariableElement get baseElement => declaration;
 
+  @Deprecated('Use computeConstantValue() instead')
   @override
   DartObject get constantValue => declaration.constantValue;
 
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index 25887d8..83c3c78 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -8,9 +8,8 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
diff --git a/pkg/analyzer/lib/src/dart/element/subtype.dart b/pkg/analyzer/lib/src/dart/element/subtype.dart
new file mode 100644
index 0000000..77eef3a
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/subtype.dart
@@ -0,0 +1,508 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/// Helper for checking the subtype relation.
+///
+/// https://github.com/dart-lang/language
+/// See `resources/type-system/subtyping.md`
+class SubtypeHelper {
+  final TypeProviderImpl _typeProvider;
+  final InterfaceTypeImpl _nullNone;
+  final InterfaceTypeImpl _objectNone;
+  final InterfaceTypeImpl _objectQuestion;
+
+  SubtypeHelper(TypeSystemImpl typeSystem)
+      : _typeProvider = typeSystem.typeProvider,
+        _nullNone = typeSystem.nullNone,
+        _objectNone = typeSystem.objectNone,
+        _objectQuestion = typeSystem.objectQuestion;
+
+  /// Return `true` if [_T0] is a subtype of [_T1].
+  bool isSubtypeOf(DartType _T0, DartType _T1) {
+    // Reflexivity: if `T0` and `T1` are the same type then `T0 <: T1`.
+    if (identical(_T0, _T1)) {
+      return true;
+    }
+
+    // `?` is treated as a top and a bottom type during inference.
+    if (identical(_T0, UnknownInferredType.instance) ||
+        identical(_T1, UnknownInferredType.instance)) {
+      return true;
+    }
+
+    var T0 = _T0 as TypeImpl;
+    var T1 = _T1 as TypeImpl;
+
+    var T1_nullability = T1.nullabilitySuffix;
+    var T0_nullability = T0.nullabilitySuffix;
+
+    // Right Top: if `T1` is a top type (i.e. `dynamic`, or `void`, or
+    // `Object?`) then `T0 <: T1`.
+    if (identical(T1, DynamicTypeImpl.instance) ||
+        identical(T1, VoidTypeImpl.instance) ||
+        T1_nullability == NullabilitySuffix.question && T1.isDartCoreObject) {
+      return true;
+    }
+
+    // Left Top: if `T0` is `dynamic` or `void`,
+    //   then `T0 <: T1` if `Object? <: T1`.
+    if (identical(T0, DynamicTypeImpl.instance) ||
+        identical(T0, VoidTypeImpl.instance)) {
+      if (isSubtypeOf(_objectQuestion, T1)) {
+        return true;
+      }
+    }
+
+    // Left Bottom: if `T0` is `Never`, then `T0 <: T1`.
+    if (identical(T0, NeverTypeImpl.instance)) {
+      return true;
+    }
+
+    // Right Object: if `T1` is `Object` then:
+    if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreObject) {
+      // * if `T0` is an unpromoted type variable with bound `B`,
+      //   then `T0 <: T1` iff `B <: Object`.
+      // * if `T0` is a promoted type variable `X & S`,
+      //   then `T0 <: T1` iff `S <: Object`.
+      if (T0_nullability == NullabilitySuffix.none &&
+          T0 is TypeParameterTypeImpl) {
+        var S = T0.promotedBound;
+        var B = T0.element.bound;
+        if (S == null && B != null) {
+          return isSubtypeOf(B, _objectNone);
+        }
+        if (S != null) {
+          return isSubtypeOf(S, _objectNone);
+        }
+      }
+      // * if `T0` is `FutureOr<S>` for some `S`,
+      //   then `T0 <: T1` iff `S <: Object`
+      if (T0_nullability == NullabilitySuffix.none &&
+          T0 is InterfaceTypeImpl &&
+          T0.isDartAsyncFutureOr) {
+        return isSubtypeOf(T0.typeArguments[0], T1);
+      }
+      // * if `T0` is `S*` for any `S`, then `T0 <: T1` iff `S <: T1`
+      if (T0_nullability == NullabilitySuffix.star) {
+        return isSubtypeOf(
+          T0.withNullability(NullabilitySuffix.none),
+          T1,
+        );
+      }
+      // * if `T0` is `Null`, `dynamic`, `void`, or `S?` for any `S`,
+      //   then the subtyping does not hold, the result is false.
+      if (T0_nullability == NullabilitySuffix.none && T0.isDartCoreNull ||
+          identical(T0, DynamicTypeImpl.instance) ||
+          identical(T0, VoidTypeImpl.instance) ||
+          T0_nullability == NullabilitySuffix.question) {
+        return false;
+      }
+      // Otherwise `T0 <: T1` is true.
+      return true;
+    }
+
+    // Left Null: if `T0` is `Null` then:
+    if (T0_nullability == NullabilitySuffix.none && T0.isDartCoreNull) {
+      // * If `T1` is `FutureOr<S>` for some `S`, then the query is true iff
+      // `Null <: S`.
+      if (T1_nullability == NullabilitySuffix.none &&
+          T1 is InterfaceTypeImpl &&
+          T1.isDartAsyncFutureOr) {
+        var S = T1.typeArguments[0];
+        return isSubtypeOf(_nullNone, S);
+      }
+      // If `T1` is `Null`, `S?` or `S*` for some `S`, then the query is true.
+      if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreNull ||
+          T1_nullability == NullabilitySuffix.question ||
+          T1_nullability == NullabilitySuffix.star) {
+        return true;
+      }
+      // * if `T1` is a type variable (promoted or not) the query is false
+      if (T1 is TypeParameterTypeImpl) {
+        return false;
+      }
+      // Otherwise, the query is false.
+      return false;
+    }
+
+    // Left Legacy if `T0` is `S0*` then:
+    if (T0_nullability == NullabilitySuffix.star) {
+      // * `T0 <: T1` iff `S0 <: T1`.
+      var S0 = T0.withNullability(NullabilitySuffix.none);
+      return isSubtypeOf(S0, T1);
+    }
+
+    // Right Legacy `T1` is `S1*` then:
+    //   * `T0 <: T1` iff `T0 <: S1?`.
+    if (T1_nullability == NullabilitySuffix.star) {
+      if (T1 is FunctionType && _isFunctionTypeWithNamedRequired(T0)) {
+        T1 = _functionTypeWithNamedRequired(T1 as FunctionType);
+      }
+      var S1 = T1.withNullability(NullabilitySuffix.question);
+      return isSubtypeOf(T0, S1);
+    }
+
+    // Left FutureOr: if `T0` is `FutureOr<S0>` then:
+    if (T0_nullability == NullabilitySuffix.none &&
+        T0 is InterfaceTypeImpl &&
+        T0.isDartAsyncFutureOr) {
+      var S0 = T0.typeArguments[0];
+      // * `T0 <: T1` iff `Future<S0> <: T1` and `S0 <: T1`
+      if (isSubtypeOf(S0, T1)) {
+        var FutureS0 = _typeProvider.futureElement.instantiate(
+          typeArguments: [S0],
+          nullabilitySuffix: NullabilitySuffix.none,
+        );
+        return isSubtypeOf(FutureS0, T1);
+      }
+      return false;
+    }
+
+    // Left Nullable: if `T0` is `S0?` then:
+    //   * `T0 <: T1` iff `S0 <: T1` and `Null <: T1`.
+    if (T0_nullability == NullabilitySuffix.question) {
+      var S0 = T0.withNullability(NullabilitySuffix.none);
+      return isSubtypeOf(S0, T1) && isSubtypeOf(_nullNone, T1);
+    }
+
+    // Type Variable Reflexivity 1: if T0 is a type variable X0 or a promoted
+    // type variables X0 & S0 and T1 is X0 then:
+    //   * T0 <: T1
+    if (T0 is TypeParameterTypeImpl &&
+        T1 is TypeParameterTypeImpl &&
+        T1.promotedBound == null &&
+        T0.element == T1.element) {
+      return true;
+    }
+
+    // Right Promoted Variable: if `T1` is a promoted type variable `X1 & S1`:
+    //   * `T0 <: T1` iff `T0 <: X1` and `T0 <: S1`
+    if (T1 is TypeParameterTypeImpl && T1.promotedBound != null) {
+      var X1 = TypeParameterTypeImpl(
+        element: T1.element,
+        nullabilitySuffix: T1.nullabilitySuffix,
+      );
+      return isSubtypeOf(T0, X1) && isSubtypeOf(T0, T1.promotedBound);
+    }
+
+    // Right FutureOr: if `T1` is `FutureOr<S1>` then:
+    if (T1_nullability == NullabilitySuffix.none &&
+        T1 is InterfaceTypeImpl &&
+        T1.isDartAsyncFutureOr) {
+      var S1 = T1.typeArguments[0];
+      // `T0 <: T1` iff any of the following hold:
+      // * either `T0 <: Future<S1>`
+      var FutureS1 = _typeProvider.futureElement.instantiate(
+        typeArguments: [S1],
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+      if (isSubtypeOf(T0, FutureS1)) {
+        return true;
+      }
+      // * or `T0 <: S1`
+      if (isSubtypeOf(T0, S1)) {
+        return true;
+      }
+      // * or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
+      // * or `T0` is `X0 & S0` and `S0 <: T1`
+      if (T0 is TypeParameterTypeImpl) {
+        var S0 = T0.promotedBound;
+        if (S0 != null && isSubtypeOf(S0, T1)) {
+          return true;
+        }
+        var B0 = T0.element.bound;
+        if (B0 != null && isSubtypeOf(B0, T1)) {
+          return true;
+        }
+      }
+      // iff
+      return false;
+    }
+
+    // Right Nullable: if `T1` is `S1?` then:
+    if (T1_nullability == NullabilitySuffix.question) {
+      var S1 = T1.withNullability(NullabilitySuffix.none);
+      // `T0 <: T1` iff any of the following hold:
+      // * either `T0 <: S1`
+      if (isSubtypeOf(T0, S1)) {
+        return true;
+      }
+      // * or `T0 <: Null`
+      if (isSubtypeOf(T0, _nullNone)) {
+        return true;
+      }
+      // or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
+      // or `T0` is `X0 & S0` and `S0 <: T1`
+      if (T0 is TypeParameterTypeImpl) {
+        var S0 = T0.promotedBound;
+        if (S0 != null && isSubtypeOf(S0, T1)) {
+          return true;
+        }
+        var B0 = T0.element.bound;
+        if (B0 != null && isSubtypeOf(B0, T1)) {
+          return true;
+        }
+      }
+      // iff
+      return false;
+    }
+
+    // Super-Interface: `T0` is an interface type with super-interfaces
+    // `S0,...Sn`:
+    //   * and `Si <: T1` for some `i`.
+    if (T0 is InterfaceTypeImpl && T1 is InterfaceTypeImpl) {
+      return _isInterfaceSubtypeOf(T0, T1);
+    }
+
+    // Left Promoted Variable: `T0` is a promoted type variable `X0 & S0`
+    //   * and `S0 <: T1`
+    // Left Type Variable Bound: `T0` is a type variable `X0` with bound `B0`
+    //   * and `B0 <: T1`
+    if (T0 is TypeParameterTypeImpl) {
+      var S0 = T0.promotedBound;
+      if (S0 != null && isSubtypeOf(S0, T1)) {
+        return true;
+      }
+
+      var B0 = T0.element.bound;
+      if (B0 != null && isSubtypeOf(B0, T1)) {
+        return true;
+      }
+    }
+
+    if (T0 is FunctionTypeImpl) {
+      // Function Type/Function: `T0` is a function type and `T1` is `Function`.
+      if (T1.isDartCoreFunction) {
+        return true;
+      }
+      if (T1 is FunctionTypeImpl) {
+        return _isFunctionSubtypeOf(T0, T1);
+      }
+    }
+
+    return false;
+  }
+
+  bool _interfaceArguments(
+    ClassElement element,
+    InterfaceType subType,
+    InterfaceType superType,
+  ) {
+    List<TypeParameterElement> parameters = element.typeParameters;
+    List<DartType> subArguments = subType.typeArguments;
+    List<DartType> superArguments = superType.typeArguments;
+
+    assert(subArguments.length == superArguments.length);
+    assert(parameters.length == subArguments.length);
+
+    for (int i = 0; i < subArguments.length; i++) {
+      var parameter = parameters[i] as TypeParameterElementImpl;
+      var subArgument = subArguments[i];
+      var superArgument = superArguments[i];
+
+      Variance variance = parameter.variance;
+      if (variance.isCovariant) {
+        if (!isSubtypeOf(subArgument, superArgument)) {
+          return false;
+        }
+      } else if (variance.isContravariant) {
+        if (!isSubtypeOf(superArgument, subArgument)) {
+          return false;
+        }
+      } else if (variance.isInvariant) {
+        if (!isSubtypeOf(subArgument, superArgument) ||
+            !isSubtypeOf(superArgument, subArgument)) {
+          return false;
+        }
+      } else {
+        throw StateError(
+          'Type parameter $parameter has unknown '
+          'variance $variance for subtype checking.',
+        );
+      }
+    }
+    return true;
+  }
+
+  /// Check that [f] is a subtype of [g].
+  bool _isFunctionSubtypeOf(FunctionType f, FunctionType g) {
+    var fTypeFormals = f.typeFormals;
+    var gTypeFormals = g.typeFormals;
+
+    // The number of type parameters must be the same.
+    if (fTypeFormals.length != gTypeFormals.length) {
+      return false;
+    }
+
+    // The bounds of type parameters must be equal.
+    var freshTypeFormalTypes =
+        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) {
+      return isSubtypeOf(t, s) && isSubtypeOf(s, t);
+    });
+    if (freshTypeFormalTypes == null) {
+      return false;
+    }
+
+    f = f.instantiate(freshTypeFormalTypes);
+    g = g.instantiate(freshTypeFormalTypes);
+
+    if (!isSubtypeOf(f.returnType, g.returnType)) {
+      return false;
+    }
+
+    var fParameters = f.parameters;
+    var gParameters = g.parameters;
+
+    var fIndex = 0;
+    var gIndex = 0;
+    while (fIndex < fParameters.length && gIndex < gParameters.length) {
+      var fParameter = fParameters[fIndex];
+      var gParameter = gParameters[gIndex];
+      if (fParameter.isRequiredPositional) {
+        if (gParameter.isRequiredPositional) {
+          if (isSubtypeOf(gParameter.type, fParameter.type)) {
+            fIndex++;
+            gIndex++;
+          } else {
+            return false;
+          }
+        } else {
+          return false;
+        }
+      } else if (fParameter.isOptionalPositional) {
+        if (gParameter.isPositional) {
+          if (isSubtypeOf(gParameter.type, fParameter.type)) {
+            fIndex++;
+            gIndex++;
+          } else {
+            return false;
+          }
+        } else {
+          return false;
+        }
+      } else if (fParameter.isNamed) {
+        if (gParameter.isNamed) {
+          var compareNames = fParameter.name.compareTo(gParameter.name);
+          if (compareNames == 0) {
+            var gIsRequiredOrLegacy = gParameter.isRequiredNamed ||
+                g.nullabilitySuffix == NullabilitySuffix.star;
+            if (fParameter.isRequiredNamed && !gIsRequiredOrLegacy) {
+              return false;
+            } else if (isSubtypeOf(gParameter.type, fParameter.type)) {
+              fIndex++;
+              gIndex++;
+            } else {
+              return false;
+            }
+          } else if (compareNames < 0) {
+            if (fParameter.isRequiredNamed) {
+              return false;
+            } else {
+              fIndex++;
+            }
+          } else {
+            assert(compareNames > 0);
+            // The subtype must accept all parameters of the supertype.
+            return false;
+          }
+        } else {
+          break;
+        }
+      }
+    }
+
+    // The supertype must provide all required parameters to the subtype.
+    while (fIndex < fParameters.length) {
+      var fParameter = fParameters[fIndex++];
+      if (fParameter.isNotOptional) {
+        return false;
+      }
+    }
+
+    // The subtype must accept all parameters of the supertype.
+    assert(fIndex == fParameters.length);
+    if (gIndex < gParameters.length) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool _isInterfaceSubtypeOf(InterfaceType subType, InterfaceType superType) {
+    // Note: we should never reach `_isInterfaceSubtypeOf` with `i2 == Object`,
+    // because top types are eliminated before `isSubtypeOf` calls this.
+    // TODO(scheglov) Replace with assert().
+    if (identical(subType, superType) || superType.isObject) {
+      return true;
+    }
+
+    // Object cannot subtype anything but itself (handled above).
+    if (subType.isObject) {
+      return false;
+    }
+
+    var subElement = subType.element;
+    var superElement = superType.element;
+    if (subElement == superElement) {
+      return _interfaceArguments(superElement, subType, superType);
+    }
+
+    // Classes types cannot subtype `Function` or vice versa.
+    if (subType.isDartCoreFunction || superType.isDartCoreFunction) {
+      return false;
+    }
+
+    for (var interface in subElement.allSupertypes) {
+      if (interface.element == superElement) {
+        var substitution = Substitution.fromInterfaceType(subType);
+        var substitutedInterface = substitution.substituteType(interface);
+        return _interfaceArguments(
+          superElement,
+          substitutedInterface,
+          superType,
+        );
+      }
+    }
+
+    return false;
+  }
+
+  static FunctionTypeImpl _functionTypeWithNamedRequired(FunctionType type) {
+    return FunctionTypeImpl(
+      typeFormals: type.typeFormals,
+      parameters: type.parameters.map((e) {
+        if (e.isNamed) {
+          return ParameterElementImpl.synthetic(
+            e.name,
+            e.type,
+            ParameterKind.NAMED_REQUIRED,
+          );
+        } else {
+          return e;
+        }
+      }).toList(growable: false),
+      returnType: type.returnType,
+      nullabilitySuffix: type.nullabilitySuffix,
+    );
+  }
+
+  static bool _isFunctionTypeWithNamedRequired(DartType type) {
+    if (type is FunctionType) {
+      return type.parameters.any((e) => e.isRequiredNamed);
+    }
+    return false;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/top_merge.dart b/pkg/analyzer/lib/src/dart/element/top_merge.dart
index 2db7d00..974ad2e 100644
--- a/pkg/analyzer/lib/src/dart/element/top_merge.dart
+++ b/pkg/analyzer/lib/src/dart/element/top_merge.dart
@@ -44,6 +44,11 @@
       return DynamicTypeImpl.instance;
     }
 
+    if (identical(T, NeverTypeImpl.instance) &&
+        identical(S, NeverTypeImpl.instance)) {
+      return NeverTypeImpl.instance;
+    }
+
     // NNBD_TOP_MERGE(void, void) = void
     var T_isVoid = identical(T, VoidTypeImpl.instance);
     var S_isVoid = identical(S, VoidTypeImpl.instance);
@@ -51,26 +56,26 @@
       return VoidTypeImpl.instance;
     }
 
-    // NNBD_TOP_MERGE(void, Object?) = void
     // NNBD_TOP_MERGE(Object?, void) = void
-    if (T_isVoid && S_isObjectQuestion || T_isObjectQuestion && S_isVoid) {
-      return VoidTypeImpl.instance;
+    // NNBD_TOP_MERGE(void, Object?) = void
+    if (T_isObjectQuestion && S_isVoid || T_isVoid && S_isObjectQuestion) {
+      return typeSystem.objectQuestion;
     }
 
-    // NNBD_TOP_MERGE(void, Object*) = void
     // NNBD_TOP_MERGE(Object*, void) = void
+    // NNBD_TOP_MERGE(void, Object*) = void
     var T_isObjectStar =
         T_nullability == NullabilitySuffix.star && T.isDartCoreObject;
     var S_isObjectStar =
         S_nullability == NullabilitySuffix.star && S.isDartCoreObject;
-    if (T_isVoid && S_isObjectStar || T_isObjectStar && S_isVoid) {
-      return VoidTypeImpl.instance;
+    if (T_isObjectStar && S_isVoid || T_isVoid && S_isObjectStar) {
+      return typeSystem.objectQuestion;
     }
 
-    // NNBD_TOP_MERGE(void, dynamic) = void
     // NNBD_TOP_MERGE(dynamic, void) = void
-    if (T_isVoid && S_isDynamic || T_isDynamic && S_isVoid) {
-      return VoidTypeImpl.instance;
+    // NNBD_TOP_MERGE(void, dynamic) = void
+    if (T_isDynamic && S_isVoid || T_isVoid && S_isDynamic) {
+      return typeSystem.objectQuestion;
     }
 
     // NNBD_TOP_MERGE(Object?, dynamic) = Object?
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 0b61689..9c209a2 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -977,7 +977,18 @@
    * return the type `A<String>`.
    */
   InterfaceType asInstanceOf(ClassElement targetElement) {
-    return _asInstanceOf(targetElement, <ClassElement>{});
+    if (element == targetElement) {
+      return this;
+    }
+
+    for (var rawInterface in element.allSupertypes) {
+      if (rawInterface.element == targetElement) {
+        var substitution = Substitution.fromInterfaceType(this);
+        return substitution.substituteType(rawInterface);
+      }
+    }
+
+    return null;
   }
 
   @override
@@ -1499,43 +1510,6 @@
     );
   }
 
-  /**
-   * Return  either this type or a supertype of this type that is defined by the
-   * [targetElement], or `null` if such a type does not exist. The set of
-   * [visitedClasses] is used to prevent infinite recursion.
-   */
-  InterfaceType _asInstanceOf(
-      ClassElement targetElement, Set<ClassElement> visitedClasses) {
-    ClassElement thisElement = element;
-    if (thisElement == targetElement) {
-      return this;
-    } else if (visitedClasses.add(thisElement)) {
-      InterfaceType type;
-      for (InterfaceType mixin in mixins) {
-        type = (mixin as InterfaceTypeImpl)
-            ._asInstanceOf(targetElement, visitedClasses);
-        if (type != null) {
-          return type;
-        }
-      }
-      if (superclass != null) {
-        type = (superclass as InterfaceTypeImpl)
-            ._asInstanceOf(targetElement, visitedClasses);
-        if (type != null) {
-          return type;
-        }
-      }
-      for (InterfaceType interface in interfaces) {
-        type = (interface as InterfaceTypeImpl)
-            ._asInstanceOf(targetElement, visitedClasses);
-        if (type != null) {
-          return type;
-        }
-      }
-    }
-    return null;
-  }
-
   List<InterfaceType> _instantiateSuperTypes(List<InterfaceType> defined) {
     if (defined.isEmpty) return defined;
 
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index d6635c0..4197381 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -7,8 +7,8 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 
diff --git a/pkg/analyzer/lib/src/dart/element/type_schema.dart b/pkg/analyzer/lib/src/dart/element/type_schema.dart
new file mode 100644
index 0000000..05469d8
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type_schema.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/token.dart' show Keyword;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/display_string_builder.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+
+/// A type that is being inferred but is not currently known.
+///
+/// This type will only appear in a downward inference context for type
+/// parameters that we do not know yet. Notationally it is written `?`, for
+/// example `List<?>`. This is distinct from `List<dynamic>`. These types will
+/// never appear in the final resolved AST.
+class UnknownInferredType extends TypeImpl {
+  static final UnknownInferredType instance = UnknownInferredType._();
+
+  UnknownInferredType._() : super(UnknownInferredTypeElement.instance);
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool get isDynamic => true;
+
+  @Deprecated('Check element, or use getDisplayString()')
+  @override
+  String get name => Keyword.DYNAMIC.lexeme;
+
+  @override
+  NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.star;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeUnknownInferredType();
+  }
+
+  @override
+  DartType replaceTopAndBottom(TypeProvider typeProvider,
+      {bool isCovariant = true}) {
+    // In theory this should never happen, since we only need to do this
+    // replacement when checking super-boundedness of explicitly-specified
+    // types, or types produced by mixin inference or instantiate-to-bounds, and
+    // the unknown type can't occur in any of those cases.
+    assert(
+        false, 'Attempted to check super-boundedness of a type including "?"');
+    // But just in case it does, behave similar to `dynamic`.
+    if (isCovariant) {
+      return typeProvider.nullType;
+    } else {
+      return this;
+    }
+  }
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+
+  @override
+  TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
+
+  /// Given a [type] T, return true if it does not have an unknown type `?`.
+  static bool isKnown(DartType type) => !isUnknown(type);
+
+  /// Given a [type] T, return true if it has an unknown type `?`.
+  static bool isUnknown(DartType type) {
+    if (identical(type, UnknownInferredType.instance)) {
+      return true;
+    }
+    if (type is InterfaceTypeImpl) {
+      return type.typeArguments.any(isUnknown);
+    }
+    if (type is FunctionType) {
+      return isUnknown(type.returnType) ||
+          type.parameters.any((p) => isUnknown(p.type));
+    }
+    return false;
+  }
+}
+
+/// The synthetic element for [UnknownInferredType].
+class UnknownInferredTypeElement extends ElementImpl
+    implements TypeDefiningElement {
+  static final UnknownInferredTypeElement instance =
+      UnknownInferredTypeElement._();
+
+  UnknownInferredTypeElement._() : super(Keyword.DYNAMIC.lexeme, -1) {
+    setModifier(Modifier.SYNTHETIC, true);
+  }
+
+  @override
+  ElementKind get kind => ElementKind.DYNAMIC;
+
+  @override
+  UnknownInferredType get type => UnknownInferredType.instance;
+
+  @override
+  T accept<T>(ElementVisitor visitor) => null;
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart b/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart
index 2727d95..3fff1c1 100644
--- a/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart
@@ -4,7 +4,7 @@
 
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/replacement_visitor.dart';
-import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:meta/meta.dart';
 
 /// Visitor that computes least and greatest closures of a type schema.
diff --git a/pkg/analyzer/lib/src/dart/element/type_visitor.dart b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
index 11ef758..714fac0 100644
--- a/pkg/analyzer/lib/src/dart/element/type_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
@@ -4,7 +4,7 @@
 
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 84df830..0890f77 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -1306,6 +1306,50 @@
           "as an operand of a logical operator.");
 
   /**
+   * No parameters.
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the type following `on` in a
+  // catch clause is a nullable type. It isn't valid to specify a nullable type
+  // because it isn't possible to catch `null` (because it's a runtime error to
+  // throw `null`).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the exception type is
+  // specified to allow `null` when `null` can't be thrown:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f() {
+  //   try {
+  //     // ...
+  //   } on [!FormatException?!] {
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the question mark from the type:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f() {
+  //   try {
+  //     // ...
+  //   } on FormatException {
+  //   }
+  // }
+  // ```
+  static const HintCode NULLABLE_TYPE_IN_CATCH_CLAUSE = HintCode(
+      'NULLABLE_TYPE_IN_CATCH_CLAUSE',
+      "A potentially nullable type can't be used in an 'on' clause because it "
+          "isn't valid to throw a nullable expression.",
+      correction: "Try using a non-nullable type.");
+
+  /**
    * Hint for classes that override equals, but not hashCode.
    *
    * Parameters:
@@ -2228,6 +2272,61 @@
   /**
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when it finds an equality comparison
+  // (either `==` or `!=`) with one operand of `null` and the other operand
+  // can't be `null`. Such comparisons are always either `true` or `false`, so
+  // they serve no purpose.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` can never be
+  // `null`, so the comparison always evaluates to `true`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int x) {
+  //   if (x [!!= null!]) {
+  //     print(x);
+  //   }
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because `x` can never be
+  // `null`, so the comparison always evaluates to `false`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int x) {
+  //   if (x [!== null!]) {
+  //     throw ArgumentError("x can't be null");
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the other operand should be able to be `null`, then change the type of
+  // the operand:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int? x) {
+  //   if (x != null) {
+  //     print(x);
+  //   }
+  // }
+  // ```
+  //
+  // If the other operand really can't be `null`, then remove the condition:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int x) {
+  //   print(x);
+  // }
+  // ```
   static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE =
       HintCodeWithUniqueName(
           'UNNECESSARY_NULL_COMPARISON',
diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
index 0a3659c..22c0965 100644
--- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
@@ -4,13 +4,11 @@
 
 import 'package:analyzer/error/error.dart';
 
-/**
- * Defines style and best practice recommendations.
- *
- * Unlike [HintCode]s, which are akin to traditional static warnings from a
- * compiler, lint recommendations focus on matters of style and practices that
- * might aggregated to define a project's style guide.
- */
+/// Defines style and best practice recommendations.
+///
+/// Unlike [HintCode]s, which are akin to traditional static warnings from a
+/// compiler, lint recommendations focus on matters of style and practices that
+/// might aggregated to define a project's style guide.
 class LintCode extends ErrorCode {
   const LintCode(String name, String message, {String correction})
       : super.temporary(name, message, correction: correction);
@@ -27,14 +25,24 @@
   @override
   ErrorType get type => ErrorType.LINT;
 
-  /**
-   * Overridden so that [LintCode] and its subclasses share the same uniqueName
-   * pattern (we know how to identify a lint even if we don't know the specific
-   * subclass the lint's code is defined in.
-   */
+  /// Overridden so that [LintCode] and its subclasses share the same uniqueName
+  /// pattern (we know how to identify a lint even if we don't know the specific
+  /// subclass the lint's code is defined in.
   @override
   String get uniqueName => "LintCode.$name";
 
   @override
   String get url => 'https://dart-lang.github.io/linter/lints/$name.html';
 }
+
+/// Defines security-related best practice recommendations.
+///
+/// The primary difference from [LintCode]s is that these codes cannot be
+/// suppressed with `// ignore:` or `// ignore_for_file:` comments.
+class SecurityLintCode extends LintCode {
+  const SecurityLintCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
+
+  @override
+  bool get isIgnorable => false;
+}
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 85aeefe..ad33ec7 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -246,9 +246,9 @@
 
 const ParserErrorCode _EXPERIMENT_NOT_ENABLED = ParserErrorCode(
     'EXPERIMENT_NOT_ENABLED',
-    r"This requires the '#string' experiment to be enabled.",
+    r"This requires the '#string' language feature to be enabled.",
     correction:
-        "Try enabling this experiment by adding it to the command line when compiling and running.");
+        "Try updating your pubspec.yaml to set the minimum SDK constraint to #string2 or higher, and running 'pub get'.");
 
 const ParserErrorCode _EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = ParserErrorCode(
     'EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index a9d7cf3..82a6e42 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -5,53 +5,125 @@
 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/session.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/uri_converter.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
-import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart';
 import 'package:analyzer/src/dart/analysis/results.dart';
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
+import 'package:meta/meta.dart';
 
-class MicroAnalysisContextImpl implements AnalysisContext {
+MicroContextObjects createMicroContextObjects({
+  @required FileResolver fileResolver,
+  @required AnalysisOptionsImpl analysisOptions,
+  @required SourceFactory sourceFactory,
+  @required ContextRootImpl root,
+  @required ResourceProvider resourceProvider,
+  @required Workspace workspace,
+}) {
+  var declaredVariables = DeclaredVariables();
+  var synchronousSession = SynchronousSession(
+    analysisOptions,
+    declaredVariables,
+  );
+
+  var analysisContext = AnalysisContextImpl(
+    synchronousSession,
+    sourceFactory,
+  );
+
+  var analysisSession = _MicroAnalysisSessionImpl(
+    declaredVariables,
+    sourceFactory,
+  );
+
+  var analysisContext2 = _MicroAnalysisContextImpl(
+    fileResolver,
+    synchronousSession,
+    root,
+    declaredVariables,
+    sourceFactory,
+    resourceProvider,
+    workspace: workspace,
+  );
+
+  analysisContext2.currentSession = analysisSession;
+  analysisSession.analysisContext = analysisContext2;
+
+  return MicroContextObjects(
+    declaredVariables: declaredVariables,
+    synchronousSession: synchronousSession,
+    analysisSession: analysisSession,
+    analysisContext: analysisContext,
+    analysisContext2: analysisContext2,
+  );
+}
+
+class MicroContextObjects {
+  final DeclaredVariables declaredVariables;
+  final SynchronousSession synchronousSession;
+  final _MicroAnalysisSessionImpl analysisSession;
+  final AnalysisContextImpl analysisContext;
+  final _MicroAnalysisContextImpl analysisContext2;
+
+  MicroContextObjects({
+    @required this.declaredVariables,
+    @required this.synchronousSession,
+    @required this.analysisSession,
+    @required this.analysisContext,
+    @required this.analysisContext2,
+  });
+
+  set analysisOptions(AnalysisOptionsImpl analysisOptions) {
+    synchronousSession.analysisOptions = analysisOptions;
+  }
+}
+
+class _MicroAnalysisContextImpl implements AnalysisContext {
   final FileResolver fileResolver;
-
-  @override
-  final AnalysisOptions analysisOptions;
+  final SynchronousSession synchronousSession;
 
   final ResourceProvider resourceProvider;
 
   @override
   final ContextRoot contextRoot;
 
+  @override
+  _MicroAnalysisSessionImpl currentSession;
+
   final DeclaredVariables declaredVariables;
   final SourceFactory sourceFactory;
 
   Workspace _workspace;
 
+  _MicroAnalysisContextImpl(
+    this.fileResolver,
+    this.synchronousSession,
+    this.contextRoot,
+    this.declaredVariables,
+    this.sourceFactory,
+    this.resourceProvider, {
+    Workspace workspace,
+  }) : this._workspace = workspace;
+
+  @override
+  AnalysisOptionsImpl get analysisOptions {
+    return synchronousSession.analysisOptions;
+  }
+
   @override
   Workspace get workspace {
     return _workspace ??= _buildWorkspace();
   }
 
-  MicroAnalysisContextImpl(
-      this.fileResolver,
-      this.contextRoot,
-      this.analysisOptions,
-      this.declaredVariables,
-      this.sourceFactory,
-      this.resourceProvider,
-      {Workspace workspace})
-      : this._workspace = workspace;
-
   @override
-  AnalysisSession get currentSession {
-    return _AnalysisSessionImpl(this, declaredVariables, sourceFactory);
-  }
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   Workspace _buildWorkspace() {
     String path = contextRoot.root.path;
@@ -59,14 +131,11 @@
         resourceProvider, null /* sdkManager */, null /* contentCache */);
     return ContextBuilder.createWorkspace(resourceProvider, path, builder);
   }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class _AnalysisSessionImpl extends AnalysisSessionImpl {
+class _MicroAnalysisSessionImpl extends AnalysisSessionImpl {
   @override
-  final MicroAnalysisContextImpl analysisContext;
+  _MicroAnalysisContextImpl analysisContext;
 
   @override
   final DeclaredVariables declaredVariables;
@@ -74,16 +143,24 @@
   @override
   SourceFactory sourceFactory;
 
-  _AnalysisSessionImpl(
-    this.analysisContext,
+  _MicroAnalysisSessionImpl(
     this.declaredVariables,
     this.sourceFactory,
   ) : super(null);
+
   @override
   ResourceProvider get resourceProvider =>
       analysisContext.contextRoot.resourceProvider;
 
   @override
+  UriConverter get uriConverter {
+    return _UriConverterImpl(
+      analysisContext.contextRoot.resourceProvider,
+      sourceFactory,
+    );
+  }
+
+  @override
   FileResult getFile(String path) {
     return FileResultImpl(
       this,
@@ -95,16 +172,20 @@
   }
 
   @override
-  Future<ResolvedUnitResult> getResolvedUnit(String path) async {
-    return analysisContext.fileResolver.resolve(path);
+  Future<ResolvedLibraryResult> getResolvedLibrary(String path) async {
+    var resolvedUnit = await getResolvedUnit(path);
+    return ResolvedLibraryResultImpl(
+      this,
+      path,
+      resolvedUnit.uri,
+      resolvedUnit.libraryElement,
+      [resolvedUnit],
+    );
   }
 
   @override
-  UriConverter get uriConverter {
-    return _UriConverterImpl(
-      analysisContext.contextRoot.resourceProvider,
-      sourceFactory,
-    );
+  Future<ResolvedUnitResult> getResolvedUnit(String path) async {
+    return analysisContext.fileResolver.resolve(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 6dda3a4..3accea6 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -269,12 +269,20 @@
     }
 
     var content = _getFileContent(file.path);
-    unit.accept(BestPracticesVerifier(
-        errorReporter, _typeProvider, _libraryElement, unit, content,
+    unit.accept(
+      BestPracticesVerifier(
+        errorReporter,
+        _typeProvider,
+        _libraryElement,
+        unit,
+        content,
+        declaredVariables: _declaredVariables,
         typeSystem: _typeSystem,
         inheritanceManager: _inheritance,
         resourceProvider: _resourceProvider,
-        analysisOptions: _context.analysisOptions));
+        analysisOptions: _context.analysisOptions,
+      ),
+    );
 
     unit.accept(OverrideVerifier(
       _inheritance,
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 0409d1a..c392e42 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -28,6 +28,7 @@
     show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:collection/collection.dart';
+import 'package:convert/convert.dart';
 
 /// Ensure that the [FileState.libraryCycle] for the [file] and anything it
 /// depends on is computed.
@@ -54,6 +55,9 @@
    */
   final Source source;
 
+  /// Files that reference this file.
+  final List<FileState> referencingFiles = [];
+
   final List<FileState> importedFiles = [];
   final List<FileState> exportedFiles = [];
   final List<FileState> partedFiles = [];
@@ -61,6 +65,7 @@
   final Set<FileState> directReferencedLibraries = Set();
   final List<FileState> libraryFiles = [];
 
+  List<int> _digest;
   bool _exists;
   List<int> _apiSignature;
   UnlinkedUnit2 unlinked2;
@@ -70,6 +75,8 @@
 
   List<int> get apiSignature => _apiSignature;
 
+  List<int> get digest => _digest;
+
   bool get exists => _exists;
 
   /// Return the [LibraryCycle] this file belongs to, even if it consists of
@@ -81,9 +88,34 @@
     return _libraryCycle;
   }
 
+  LineInfo get lineInfo => LineInfo(unlinked2.lineStarts);
+
+  /// The resolved signature of the file, that depends on the [libraryCycle]
+  /// signature, and the content of the file.
+  String get resolvedSignature {
+    var signatureBuilder = ApiSignature();
+    signatureBuilder.addString(path);
+    signatureBuilder.addBytes(libraryCycle.signature);
+
+    var content = getContent();
+    signatureBuilder.addString(content);
+
+    return signatureBuilder.toHex();
+  }
+
   /// Return the [uri] string.
   String get uriStr => uri.toString();
 
+  /// Return the content of the file, the empty string if cannot be read.
+  String getContent() {
+    try {
+      var resource = _fsState._resourceProvider.getFile(path);
+      return resource.readAsStringSync();
+    } catch (_) {
+      return '';
+    }
+  }
+
   void internal_setLibraryCycle(LibraryCycle cycle, String signature) {
     _libraryCycle = cycle;
   }
@@ -123,8 +155,13 @@
   }
 
   void refresh() {
-    var digest = utf8.encode(_fsState.getFileDigest(path));
-    _exists = digest.isNotEmpty;
+    _fsState.testView.refreshedFiles.add(path);
+
+    _fsState.timers.digest.run(() {
+      _digest = utf8.encode(_fsState.getFileDigest(path));
+      _exists = _digest.isNotEmpty;
+    });
+
     String unlinkedKey = path;
 
     // Prepare bytes of the unlinked bundle - existing or new.
@@ -136,27 +173,28 @@
       if (bytes != null) {
         var ciderUnlinkedUnit = CiderUnlinkedUnit.fromBuffer(bytes);
         if (!const ListEquality()
-            .equals(ciderUnlinkedUnit.contentDigest, digest)) {
+            .equals(ciderUnlinkedUnit.contentDigest, _digest)) {
           bytes = null;
         }
       }
 
       if (bytes == null || bytes.isEmpty) {
-        String content;
-        try {
-          content = _fsState._resourceProvider.getFile(path).readAsStringSync();
-        } catch (_) {
-          content = '';
-        }
-        var unit = parse(AnalysisErrorListener.NULL_LISTENER, content);
-        _fsState._logger.run('Create unlinked for $path', () {
-          var unlinkedBuilder = serializeAstCiderUnlinked(digest, unit);
+        var content = _fsState.timers.read.run(() {
+          return getContent();
+        });
+        var unit = _fsState.timers.parse.run(() {
+          return parse(AnalysisErrorListener.NULL_LISTENER, content);
+        });
+        _fsState.timers.unlinked.run(() {
+          var unlinkedBuilder = serializeAstCiderUnlinked(_digest, unit);
           bytes = unlinkedBuilder.toBuffer();
           _fsState._byteStore.put(unlinkedKey, bytes);
         });
 
-        unlinked2 = CiderUnlinkedUnit.fromBuffer(bytes).unlinkedUnit;
-        _prefetchDirectReferences(unlinked2);
+        _fsState.timers.prefetch.run(() {
+          unlinked2 = CiderUnlinkedUnit.fromBuffer(bytes).unlinkedUnit;
+          _prefetchDirectReferences(unlinked2);
+        });
       }
     }
 
@@ -188,6 +226,11 @@
     directReferencedLibraries..addAll(importedFiles)..addAll(exportedFiles);
   }
 
+  @override
+  String toString() {
+    return path;
+  }
+
   FileState _fileForRelativeUri(String relativeUri) {
     if (relativeUri.isEmpty) {
       return _fsState.unresolvedFile;
@@ -200,7 +243,10 @@
       return _fsState.unresolvedFile;
     }
 
-    return _fsState.getFileForUri(absoluteUri);
+    var file = _fsState.getFileForUri(absoluteUri);
+    file.referencingFiles.add(this);
+
+    return file;
   }
 
   void _prefetchDirectReferences(UnlinkedUnit2 unlinkedUnit2) {
@@ -335,6 +381,10 @@
    */
   FileState _unresolvedFile;
 
+  final FileSystemStateTimers timers = FileSystemStateTimers();
+
+  final FileSystemStateTestView testView = FileSystemStateTestView();
+
   FileSystemState(
     this._logger,
     this._resourceProvider,
@@ -358,6 +408,29 @@
     return _unresolvedFile;
   }
 
+  /// Update the state to reflect the fact that the file with the given [path]
+  /// was changed. Specifically this means that we evict this file and every
+  /// file that referenced it.
+  void changeFile(String path, List<FileState> removedFiles) {
+    var file = _pathToFile.remove(path);
+    if (file == null) {
+      return;
+    }
+
+    removedFiles.add(file);
+    _uriToFile.remove(file.uri);
+
+    // The removed file does not reference other file anymore.
+    for (var referencedFile in file.directReferencedFiles) {
+      referencedFile.referencingFiles.remove(file);
+    }
+
+    // Recursively remove files that reference the removed file.
+    for (var reference in file.referencingFiles.toList()) {
+      changeFile(reference.path, removedFiles);
+    }
+  }
+
   FileState getFileForPath(String path) {
     var file = _pathToFile[path];
     if (file == null) {
@@ -402,6 +475,60 @@
     }
     return source.fullName;
   }
+
+  void logStatistics() {
+    _logger.writeln(
+      '[files: ${_pathToFile.length}]'
+      '[digest: ${timers.digest.timer.elapsedMilliseconds} ms]'
+      '[read: ${timers.read.timer.elapsedMilliseconds} ms]'
+      '[parse: ${timers.parse.timer.elapsedMilliseconds} ms]'
+      '[unlinked: ${timers.unlinked.timer.elapsedMilliseconds} ms]'
+      '[prefetch: ${timers.prefetch.timer.elapsedMilliseconds} ms]',
+    );
+    timers.reset();
+  }
+}
+
+class FileSystemStateTestView {
+  final List<String> refreshedFiles = [];
+}
+
+class FileSystemStateTimer {
+  final Stopwatch timer = Stopwatch();
+
+  T run<T>(T Function() f) {
+    timer.start();
+    try {
+      return f();
+    } finally {
+      timer.stop();
+    }
+  }
+
+  Future<T> runAsync<T>(T Function() f) async {
+    timer.start();
+    try {
+      return f();
+    } finally {
+      timer.stop();
+    }
+  }
+}
+
+class FileSystemStateTimers {
+  final FileSystemStateTimer digest = FileSystemStateTimer();
+  final FileSystemStateTimer read = FileSystemStateTimer();
+  final FileSystemStateTimer parse = FileSystemStateTimer();
+  final FileSystemStateTimer unlinked = FileSystemStateTimer();
+  final FileSystemStateTimer prefetch = FileSystemStateTimer();
+
+  void reset() {
+    digest.timer.reset();
+    read.timer.reset();
+    parse.timer.reset();
+    unlinked.timer.reset();
+    prefetch.timer.reset();
+  }
 }
 
 /// Information about libraries that reference each other, so form a cycle.
@@ -420,11 +547,15 @@
   /// files that [libraries] reference (but we don't compute these files).
   List<int> signature;
 
-  // The hash for all the paths of the files in this cycle.
+  /// The hash of all the paths of the files in this cycle.
   String cyclePathsHash;
 
   LibraryCycle();
 
+  String get signatureStr {
+    return hex.encode(signature);
+  }
+
   @override
   String toString() {
     return '[' + libraries.join(', ') + ']';
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 401bbe7..c173f89 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -2,40 +2,49 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:typed_data';
 
-import 'package:analyzer/dart/analysis/context_locator.dart';
-import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart' show ErrorEncoding;
 import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/results.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/micro/analysis_context.dart';
 import 'package:analyzer/src/dart/micro/library_analyzer.dart';
 import 'package:analyzer/src/dart/micro/library_graph.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/link.dart' as link2;
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
+import 'package:meta/meta.dart';
+import 'package:yaml/yaml.dart';
 
-/*
- * Resolves a single file.
- */
+class FileContext {
+  final AnalysisOptionsImpl analysisOptions;
+  final FileState file;
+
+  FileContext(this.analysisOptions, this.file);
+}
+
 class FileResolver {
   final PerformanceLog logger;
   final ResourceProvider resourceProvider;
@@ -55,125 +64,306 @@
    */
   final void Function(List<String> paths) prefetchFiles;
 
-  Workspace workspace;
+  final Workspace workspace;
 
-  MicroAnalysisContextImpl analysisContext;
+  _LibraryContextReset _libraryContextReset;
 
-  FileResolver(this.logger, this.resourceProvider, this.byteStore,
-      this.sourceFactory, this.getFileDigest, this.prefetchFiles,
-      {Workspace workspace})
-      : this.workspace = workspace;
+  /// This field gets value only during testing.
+  FileResolverTestView testView;
+
+  FileSystemState fsState;
+
+  MicroContextObjects contextObjects;
+
+  _LibraryContext libraryContext;
+
+  FileResolver(
+    this.logger,
+    this.resourceProvider,
+    this.byteStore,
+    this.sourceFactory,
+    this.getFileDigest,
+    this.prefetchFiles, {
+    @required Workspace workspace,
+    Duration libraryContextResetTimeout = const Duration(seconds: 60),
+  }) : this.workspace = workspace {
+    _libraryContextReset = _LibraryContextReset(
+      fileResolver: this,
+      resetTimeout: libraryContextResetTimeout,
+    );
+  }
 
   FeatureSet get defaultFeatureSet => FeatureSet.fromEnableFlags([]);
 
+  /// Update the resolver to reflect the fact that the file with the given
+  /// [path] was changed. We need to make sure that when this file, of any file
+  /// that directly or indirectly referenced it, is resolved, we used the new
+  /// state of the file.
+  void changeFile(String path) {
+    if (fsState == null) {
+      return;
+    }
+
+    // Remove this file and all files that transitively depend on it.
+    var removedFiles = <FileState>[];
+    fsState.changeFile(path, removedFiles);
+
+    // Remove libraries represented by removed files.
+    // If we need these libraries later, we will relink and reattach them.
+    if (libraryContext != null) {
+      libraryContext.elementFactory.removeLibraries(
+        removedFiles.map((e) => e.uriStr).toList(),
+      );
+    }
+  }
+
+  void dispose() {
+    _libraryContextReset.dispose();
+  }
+
+  ErrorsResult getErrors(String path) {
+    _throwIfNotAbsoluteNormalizedPath(path);
+
+    return _withLibraryContextReset(() {
+      return logger.run('Get errors for $path', () {
+        var fileContext = getFileContext(path);
+        var file = fileContext.file;
+
+        var errorsSignatureBuilder = ApiSignature();
+        errorsSignatureBuilder.addBytes(file.libraryCycle.signature);
+        errorsSignatureBuilder.addBytes(file.digest);
+        var errorsSignature = errorsSignatureBuilder.toByteList();
+
+        var errorsKey = file.path + '.errors';
+        var bytes = byteStore.get(errorsKey);
+
+        List<AnalysisError> errors;
+        if (bytes != null) {
+          var data = CiderUnitErrors.fromBuffer(bytes);
+          if (const ListEquality().equals(data.signature, errorsSignature)) {
+            errors = data.errors.map((error) {
+              return ErrorEncoding.decode(file.source, error);
+            }).toList();
+          }
+        }
+
+        if (errors == null) {
+          var unitResult = resolve(path);
+          errors = unitResult.errors;
+
+          bytes = CiderUnitErrorsBuilder(
+            signature: errorsSignature,
+            errors: errors.map((ErrorEncoding.encode)).toList(),
+          ).toBuffer();
+          byteStore.put(errorsKey, bytes);
+        }
+
+        return ErrorsResultImpl(
+          contextObjects.analysisSession,
+          path,
+          file.uri,
+          file.lineInfo,
+          false, // isPart
+          errors,
+        );
+      });
+    });
+  }
+
+  FileContext getFileContext(String path) {
+    var analysisOptions = _getAnalysisOptions(path);
+    _createContext(path, analysisOptions);
+
+    var file = fsState.getFileForPath(path);
+    return FileContext(analysisOptions, file);
+  }
+
+  String getLibraryLinkedSignature(String path) {
+    _throwIfNotAbsoluteNormalizedPath(path);
+
+    var file = fsState.getFileForPath(path);
+    return file.libraryCycle.signatureStr;
+  }
+
   ResolvedUnitResult resolve(String path) {
     _throwIfNotAbsoluteNormalizedPath(path);
 
-    return logger.run('Resolve $path', () {
-      logger.run('Create AnalysisContext', () {
-        var contextLocator = ContextLocator(
-          resourceProvider: this.resourceProvider,
-        );
+    return _withLibraryContextReset(() {
+      return logger.run('Resolve $path', () {
+        var fileContext = getFileContext(path);
+        var file = fileContext.file;
 
-        var roots = contextLocator.locateRoots(
-          includedPaths: [path],
-          excludedPaths: [],
-        );
-        if (roots.length != 1) {
-          throw StateError('Exactly one root expected: $roots');
-        }
-        var root = roots[0];
+        libraryContext.load2(file);
 
-        var analysisOptions = AnalysisOptionsImpl();
-        var declaredVariables = DeclaredVariables();
+        testView?.addResolvedFile(path);
 
-        analysisContext = MicroAnalysisContextImpl(
-          this,
-          root,
-          analysisOptions,
-          declaredVariables,
-          sourceFactory,
-          resourceProvider,
-          workspace: workspace,
+        var errorListener = RecordingErrorListener();
+        var content = resourceProvider.getFile(path).readAsStringSync();
+        var unit = file.parse(errorListener, content);
+
+        Map<FileState, UnitAnalysisResult> results;
+        logger.run('Compute analysis results', () {
+          var libraryAnalyzer = LibraryAnalyzer(
+            fileContext.analysisOptions,
+            contextObjects.declaredVariables,
+            sourceFactory,
+            (_) => true, // _isLibraryUri
+            contextObjects.analysisContext,
+            libraryContext.elementFactory,
+            libraryContext.inheritanceManager,
+            file,
+            resourceProvider,
+            (String path) => resourceProvider.getFile(path).readAsStringSync(),
+          );
+
+          results = libraryAnalyzer.analyzeSync();
+        });
+        UnitAnalysisResult fileResult = results[file];
+
+        return ResolvedUnitResultImpl(
+          contextObjects.analysisSession,
+          path,
+          file.uri,
+          file.exists,
+          content,
+          unit.lineInfo,
+          false, // isPart
+          fileResult.unit,
+          fileResult.errors,
         );
       });
-
-      return _resolve(path);
     });
   }
 
-  ResolvedUnitResultImpl _resolve(String path) {
-    var options = analysisContext.analysisOptions;
-    var featureSetProvider = FeatureSetProvider.build(
-      resourceProvider: resourceProvider,
-      packages: Packages.empty,
-      packageDefaultFeatureSet: analysisContext.analysisOptions.contextFeatures,
-      nonPackageDefaultFeatureSet:
-          (options as AnalysisOptionsImpl).nonPackageFeatureSet,
-    );
+  /// Make sure that [fsState], [contextObjects], and [libraryContext] are
+  /// created and configured with the given [fileAnalysisOptions].
+  ///
+  /// The [fsState] is not affected by [fileAnalysisOptions].
+  ///
+  /// The [fileAnalysisOptions] only affect reported diagnostics, but not
+  /// elements and types. So, we really need to reconfigure only when we are
+  /// going to resolve some files using these new options.
+  ///
+  /// Specifically, "implicit casts" and "strict inference" affect the type
+  /// system. And there are lints that are enabled for one package, but not
+  /// for another.
+  void _createContext(String path, AnalysisOptionsImpl fileAnalysisOptions) {
+    if (contextObjects != null) {
+      contextObjects.analysisOptions = fileAnalysisOptions;
+      return;
+    }
 
-    var fsState = FileSystemState(
-      logger,
-      resourceProvider,
-      byteStore,
-      analysisContext.sourceFactory,
-      analysisContext.analysisOptions,
-      Uint32List(0), // linkedSalt
-      featureSetProvider,
-      getFileDigest,
-      prefetchFiles,
-    );
+    var analysisOptions = AnalysisOptionsImpl()
+      ..implicitCasts = fileAnalysisOptions.implicitCasts
+      ..strictInference = fileAnalysisOptions.strictInference;
 
-    FileState file;
-    logger.run('Get file $path', () {
-      file = fsState.getFileForPath(path);
-    });
-
-    var errorListener = RecordingErrorListener();
-    var content = resourceProvider.getFile(path).readAsStringSync();
-    var unit = file.parse(errorListener, content);
-
-    _LibraryContext libraryContext = _LibraryContext(
-      logger,
-      resourceProvider,
-      byteStore,
-      analysisContext.currentSession,
-      analysisContext.analysisOptions,
-      analysisContext.sourceFactory,
-      analysisContext.declaredVariables,
-    );
-    libraryContext.load2(file);
-
-    Map<FileState, UnitAnalysisResult> results;
-    logger.run('Compute analysis results', () {
-      var libraryAnalyzer = LibraryAnalyzer(
-        analysisContext.analysisOptions,
-        analysisContext.declaredVariables,
-        analysisContext.sourceFactory,
-        (_) => true, // _isLibraryUri
-        libraryContext.analysisContext,
-        libraryContext.elementFactory,
-        libraryContext.inheritanceManager,
-        file,
-        resourceProvider,
-        (String path) => resourceProvider.getFile(path).readAsStringSync(),
+    if (fsState == null) {
+      var featureSetProvider = FeatureSetProvider.build(
+        resourceProvider: resourceProvider,
+        packages: Packages.empty,
+        packageDefaultFeatureSet: analysisOptions.contextFeatures,
+        nonPackageDefaultFeatureSet: analysisOptions.nonPackageFeatureSet,
       );
 
-      results = libraryAnalyzer.analyzeSync();
-    });
-    UnitAnalysisResult fileResult = results[file];
+      fsState = FileSystemState(
+        logger,
+        resourceProvider,
+        byteStore,
+        sourceFactory,
+        analysisOptions,
+        Uint32List(0),
+        // linkedSalt
+        featureSetProvider,
+        getFileDigest,
+        prefetchFiles,
+      );
+    }
 
-    return ResolvedUnitResultImpl(
-      analysisContext.currentSession,
-      path,
-      file.uri,
-      file.exists,
-      content,
-      unit.lineInfo,
-      false, // isPart
-      fileResult.unit,
-      fileResult.errors,
-    );
+    if (contextObjects == null) {
+      var rootFolder = resourceProvider.getFolder(workspace.root);
+      var root = ContextRootImpl(resourceProvider, rootFolder);
+      root.included.add(rootFolder);
+
+      contextObjects = createMicroContextObjects(
+        fileResolver: this,
+        analysisOptions: analysisOptions,
+        sourceFactory: sourceFactory,
+        root: root,
+        resourceProvider: resourceProvider,
+        workspace: workspace,
+      );
+
+      libraryContext = _LibraryContext(
+        logger,
+        resourceProvider,
+        byteStore,
+        contextObjects,
+      );
+    }
+  }
+
+  File _findOptionsFile(Folder folder) {
+    while (folder != null) {
+      File packagesFile =
+          _getFile(folder, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+      if (packagesFile != null) {
+        return packagesFile;
+      }
+      folder = folder.parent;
+    }
+    return null;
+  }
+
+  /// Return the analysis options.
+  ///
+  /// If the [path] is not `null`, read it.
+  ///
+  /// If the [workspace] is a [WorkspaceWithDefaultAnalysisOptions], get the
+  /// default options, if the file exists.
+  ///
+  /// Otherwise, return the default options.
+  AnalysisOptionsImpl _getAnalysisOptions(String path) {
+    YamlMap optionMap;
+    var folder = resourceProvider.getFile(path).parent;
+    var optionsFile = _findOptionsFile(folder);
+    if (optionsFile != null) {
+      try {
+        var optionsProvider = AnalysisOptionsProvider(sourceFactory);
+        optionMap = optionsProvider.getOptionsFromFile(optionsFile);
+      } catch (e) {
+        // ignored
+      }
+    } else {
+      Source source;
+      if (workspace is WorkspaceWithDefaultAnalysisOptions) {
+        var separator = resourceProvider.pathContext.separator;
+        if (path
+            .contains('${separator}third_party${separator}dart${separator}')) {
+          source = sourceFactory
+              .forUri(WorkspaceWithDefaultAnalysisOptions.thirdPartyUri);
+        } else {
+          source =
+              sourceFactory.forUri(WorkspaceWithDefaultAnalysisOptions.uri);
+        }
+      }
+
+      if (source != null && source.exists()) {
+        try {
+          var optionsProvider = AnalysisOptionsProvider(sourceFactory);
+          optionMap = optionsProvider.getOptionsFromSource(source);
+        } catch (e) {
+          // ignored
+        }
+      }
+    }
+
+    var options = AnalysisOptionsImpl();
+
+    if (optionMap != null) {
+      applyToAnalysisOptions(options, optionMap);
+    }
+
+    return options;
   }
 
   void _throwIfNotAbsoluteNormalizedPath(String path) {
@@ -184,15 +374,46 @@
       );
     }
   }
+
+  /// Run the [operation] that uses the library context, by locking it first,
+  /// so that it is not reset while the operating is still running, and
+  /// unlocking after the operation is done, so that the library context
+  /// will be reset after some timeout.
+  T _withLibraryContextReset<T>(T Function() operation) {
+    _libraryContextReset.lock();
+    try {
+      return operation();
+    } finally {
+      _libraryContextReset.unlock();
+    }
+  }
+
+  static File _getFile(Folder directory, String name) {
+    Resource resource = directory.getChild(name);
+    if (resource is File && resource.exists) {
+      return resource;
+    }
+    return null;
+  }
+}
+
+class FileResolverTestView {
+  /// The paths of files which were resolved.
+  ///
+  /// The file path is added every time when it is resolved.
+  final List<String> resolvedFiles = [];
+
+  void addResolvedFile(String path) {
+    resolvedFiles.add(path);
+  }
 }
 
 class _LibraryContext {
   final PerformanceLog logger;
   final ResourceProvider resourceProvider;
   final MemoryByteStore byteStore;
-  final AnalysisSession analysisSession;
+  final MicroContextObjects contextObjects;
 
-  AnalysisContextImpl analysisContext;
   LinkedElementFactory elementFactory;
   InheritanceManager3 inheritanceManager;
 
@@ -202,18 +423,9 @@
     this.logger,
     this.resourceProvider,
     this.byteStore,
-    this.analysisSession,
-    AnalysisOptionsImpl analysisOptions,
-    SourceFactory sourceFactory,
-    DeclaredVariables declaredVariables,
+    this.contextObjects,
   ) {
-    var synchronousSession =
-        SynchronousSession(analysisOptions, declaredVariables);
-    analysisContext = AnalysisContextImpl(
-      synchronousSession,
-      sourceFactory,
-    );
-
+    // TODO(scheglov) remove it?
     _createElementFactory();
   }
 
@@ -312,7 +524,7 @@
       // linker might have set the type provider. So, clear it, and recreate
       // the element factory - it is empty anyway.
       if (!elementFactory.hasDartCore) {
-        analysisContext.clearTypeProvider();
+        contextObjects.analysisContext.clearTypeProvider();
         _createElementFactory();
       }
       var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
@@ -354,6 +566,24 @@
     inheritanceManager = InheritanceManager3();
   }
 
+  void _createElementFactory() {
+    elementFactory = LinkedElementFactory(
+      contextObjects.analysisContext,
+      contextObjects.analysisSession,
+      Reference.root(),
+    );
+  }
+
+  /// Ensure that type provider is created.
+  void _createElementFactoryTypeProvider() {
+    var analysisContext = contextObjects.analysisContext;
+    if (analysisContext.typeProviderNonNullableByDefault == null) {
+      var dartCore = elementFactory.libraryOfUri('dart:core');
+      var dartAsync = elementFactory.libraryOfUri('dart:async');
+      elementFactory.createTypeProviders(dartCore, dartAsync);
+    }
+  }
+
   static CiderLinkedLibraryCycleBuilder serializeBundle(
       List<int> signature, link2.LinkResult linkResult) {
     return CiderLinkedLibraryCycleBuilder(
@@ -361,21 +591,62 @@
       bundle: linkResult.bundle,
     );
   }
+}
 
-  void _createElementFactory() {
-    elementFactory = LinkedElementFactory(
-      analysisContext,
-      analysisSession,
-      Reference.root(),
-    );
+/// The helper to reset the library context will be reset after the specified
+/// interval of inactivity. Keeping library context with loaded elements
+/// significantly improves performance of resolution, because we don't have
+/// to resynthesize elements, build export scopes for libraries, etc.
+/// However keeping elements that we don't need anymore, or when the user
+/// does not work with files, is wasteful.
+class _LibraryContextReset {
+  final FileResolver fileResolver;
+  final Duration resetTimeout;
+
+  /// The lock level, incremented by [lock], and decremented by [unlock].
+  /// The timeout timer is started when the level reaches zero.
+  int _lockLevel = 0;
+  Timer _timer;
+
+  _LibraryContextReset({
+    @required this.fileResolver,
+    @required this.resetTimeout,
+  });
+
+  void dispose() {
+    _stop();
   }
 
-  /// Ensure that type provider is created.
-  void _createElementFactoryTypeProvider() {
-    if (analysisContext.typeProviderNonNullableByDefault == null) {
-      var dartCore = elementFactory.libraryOfUri('dart:core');
-      var dartAsync = elementFactory.libraryOfUri('dart:async');
-      elementFactory.createTypeProviders(dartCore, dartAsync);
+  /// Stop the timeout timer, and increment the lock level. The library context
+  /// will be not reset until [unlock] will bring the lock level back to zero.
+  void lock() {
+    _stop();
+    _lockLevel++;
+  }
+
+  /// Unlock the timer, the library context will be reset after the timeout.
+  void unlock() {
+    assert(_lockLevel > 0);
+    _lockLevel--;
+
+    if (_lockLevel == 0) {
+      _stop();
+      if (resetTimeout != null) {
+        _timer = Timer(resetTimeout, () {
+          _timer = null;
+          if (fileResolver.libraryContext != null) {
+            fileResolver.contextObjects = null;
+            fileResolver.libraryContext = null;
+          }
+        });
+      }
+    }
+  }
+
+  void _stop() {
+    if (_timer != null) {
+      _timer.cancel();
+      _timer = null;
     }
   }
 }
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 a0db802..c0c8df6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -70,7 +70,12 @@
       return;
     }
 
-    _resolveOtherOperator(node);
+    if (operator.isUserDefinableOperator) {
+      _resolveUserDefinable(node);
+      return;
+    }
+
+    _resolveUnsupportedOperator(node);
   }
 
   /// Set the static type of [node] to be the least upper bound of the static
@@ -129,100 +134,26 @@
     return _resolveTypeParameter(type);
   }
 
-  void _resolve1(BinaryExpressionImpl node) {
-    Token operator = node.operator;
-    if (operator.isUserDefinableOperator) {
-      _resolveBinaryExpression(node, operator.lexeme);
-    } else if (operator.type == TokenType.BANG_EQ) {
-      _resolveBinaryExpression(node, TokenType.EQ_EQ.lexeme);
-    }
-  }
-
-  void _resolve2(BinaryExpressionImpl node) {
-    if (identical(node.leftOperand.staticType, NeverTypeImpl.instance)) {
-      _inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
-      return;
-    }
-
-    DartType staticType =
-        node.staticInvokeType?.returnType ?? DynamicTypeImpl.instance;
-    if (node.leftOperand is! ExtensionOverride) {
-      staticType = _typeSystem.refineBinaryExpressionType(
-        _getStaticType(node.leftOperand),
-        node.operator.type,
-        node.rightOperand.staticType,
-        staticType,
-      );
-    }
-    _inferenceHelper.recordStaticType(node, staticType);
-  }
-
-  void _resolveBinaryExpression(BinaryExpression node, String methodName) {
-    Expression leftOperand = node.leftOperand;
-
-    if (leftOperand is ExtensionOverride) {
-      ExtensionElement extension = leftOperand.extensionName.staticElement;
-      MethodElement member = extension.getMethod(methodName);
-      if (member == null) {
-        _errorReporter.reportErrorForToken(
-          CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR,
-          node.operator,
-          [methodName, extension.name],
-        );
-      }
-      node.staticElement = member;
-      return;
-    }
-
-    var leftType = _getStaticType(leftOperand);
-
-    if (identical(leftType, NeverTypeImpl.instance)) {
-      _resolver.errorReporter.reportErrorForNode(
-        HintCode.RECEIVER_OF_TYPE_NEVER,
-        leftOperand,
-      );
-      return;
-    }
-
-    ResolutionResult result = _typePropertyResolver.resolve(
-      receiver: leftOperand,
-      receiverType: leftType,
-      name: methodName,
-      receiverErrorNode: leftOperand,
-      nameErrorNode: node,
-    );
-
-    node.staticElement = result.getter;
-    node.staticInvokeType = result.getter?.type;
-    if (_shouldReportInvalidMember(leftType, result)) {
-      if (leftOperand is SuperExpression) {
-        _errorReporter.reportErrorForToken(
-          StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
-          node.operator,
-          [methodName, leftType],
-        );
-      } else {
-        _errorReporter.reportErrorForToken(
-          StaticTypeWarningCode.UNDEFINED_OPERATOR,
-          node.operator,
-          [methodName, leftType],
-        );
-      }
-    }
-  }
-
   void _resolveEqual(BinaryExpressionImpl node, {@required bool notEqual}) {
     var left = node.leftOperand;
-    var right = node.rightOperand;
-    var flow = _flowAnalysis?.flow;
-
     left.accept(_resolver);
+    left = node.leftOperand;
+
+    var flow = _flowAnalysis?.flow;
     flow?.equalityOp_rightBegin(left);
+
+    var right = node.rightOperand;
     right.accept(_resolver);
-    _resolve1(node);
+    right = node.rightOperand;
+
     flow?.equalityOp_end(node, right, notEqual: notEqual);
 
-    _resolve2(node);
+    _resolveUserDefinableElement(
+      node,
+      TokenType.EQ_EQ.lexeme,
+      promoteLeftTypeToNonNull: true,
+    );
+    _resolveUserDefinableType(node);
   }
 
   void _resolveIfNull(BinaryExpressionImpl node) {
@@ -270,17 +201,17 @@
     InferenceContext.setType(left, _typeProvider.boolType);
     InferenceContext.setType(right, _typeProvider.boolType);
 
-    // TODO(scheglov) Do we need these checks for null?
-    left?.accept(_resolver);
+    left.accept(_resolver);
     left = node.leftOperand;
 
     if (_flowAnalysis != null) {
       flow?.logicalBinaryOp_rightBegin(left, isAnd: true);
-      _flowAnalysis.checkUnreachableNode(right);
+      _resolver.checkUnreachableNode(right);
 
       right.accept(_resolver);
       right = node.rightOperand;
 
+      _resolver.nullSafetyDeadCodeVerifier?.flowEnd(right);
       flow?.logicalBinaryOp_end(node, right, isAnd: true);
     } else {
       _promoteManager.visitBinaryExpression_and_rhs(
@@ -296,47 +227,54 @@
     _checkNonBoolOperand(left, '&&');
     _checkNonBoolOperand(right, '&&');
 
-    _resolve1(node);
-    _resolve2(node);
+    _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
 
   void _resolveLogicalOr(BinaryExpressionImpl node) {
     var left = node.leftOperand;
-    Expression right = node.rightOperand;
+    var right = node.rightOperand;
     var flow = _flowAnalysis?.flow;
 
     InferenceContext.setType(left, _typeProvider.boolType);
     InferenceContext.setType(right, _typeProvider.boolType);
 
-    // TODO(scheglov) Do we need these checks for null?
-    left?.accept(_resolver);
+    left.accept(_resolver);
     left = node.leftOperand;
 
     flow?.logicalBinaryOp_rightBegin(left, isAnd: false);
-    _flowAnalysis?.checkUnreachableNode(right);
+    _resolver.checkUnreachableNode(right);
 
     right.accept(_resolver);
     right = node.rightOperand;
 
+    _resolver.nullSafetyDeadCodeVerifier?.flowEnd(right);
     flow?.logicalBinaryOp_end(node, right, isAnd: false);
 
     _checkNonBoolOperand(left, '||');
     _checkNonBoolOperand(right, '||');
 
-    _resolve1(node);
-    _resolve2(node);
+    _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
 
-  void _resolveOtherOperator(BinaryExpressionImpl node) {
-    Expression left = node.leftOperand;
-    Expression right = node.rightOperand;
+  /// If the given [type] is a type parameter, resolve it to the type that should
+  /// be used when looking up members. Otherwise, return the original type.
+  ///
+  /// TODO(scheglov) this is duplicate
+  DartType _resolveTypeParameter(DartType type) =>
+      type?.resolveToBound(_typeProvider.objectType);
 
-    // TODO(scheglov) Do we need these checks for null?
-    left?.accept(_resolver);
+  void _resolveUnsupportedOperator(BinaryExpressionImpl node) {
+    _inferenceHelper.recordStaticType(node, DynamicTypeImpl.instance);
+  }
 
-    // Call ElementResolver.visitBinaryExpression to resolve the user-defined
-    // operator method, if applicable.
-    _resolve1(node);
+  void _resolveUserDefinable(BinaryExpressionImpl node) {
+    var left = node.leftOperand;
+    var right = node.rightOperand;
+
+    left.accept(_resolver);
+
+    var operator = node.operator;
+    _resolveUserDefinableElement(node, operator.lexeme);
 
     var invokeType = node.staticInvokeType;
     if (invokeType != null && invokeType.parameters.isNotEmpty) {
@@ -346,18 +284,91 @@
       InferenceContext.setType(right, rightParam.type);
     }
 
-    // TODO(scheglov) Do we need these checks for null?
-    right?.accept(_resolver);
+    right.accept(_resolver);
 
-    _resolve2(node);
+    _resolveUserDefinableType(node);
   }
 
-  /// If the given [type] is a type parameter, resolve it to the type that should
-  /// be used when looking up members. Otherwise, return the original type.
-  ///
-  /// TODO(scheglov) this is duplicate
-  DartType _resolveTypeParameter(DartType type) =>
-      type?.resolveToBound(_typeProvider.objectType);
+  void _resolveUserDefinableElement(
+    BinaryExpression node,
+    String methodName, {
+    bool promoteLeftTypeToNonNull = false,
+  }) {
+    Expression leftOperand = node.leftOperand;
+
+    if (leftOperand is ExtensionOverride) {
+      ExtensionElement extension = leftOperand.extensionName.staticElement;
+      MethodElement member = extension.getMethod(methodName);
+      if (member == null) {
+        _errorReporter.reportErrorForToken(
+          CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR,
+          node.operator,
+          [methodName, extension.name],
+        );
+      }
+      node.staticElement = member;
+      return;
+    }
+
+    var leftType = _getStaticType(leftOperand);
+
+    if (identical(leftType, NeverTypeImpl.instance)) {
+      _resolver.errorReporter.reportErrorForNode(
+        HintCode.RECEIVER_OF_TYPE_NEVER,
+        leftOperand,
+      );
+      return;
+    }
+
+    if (promoteLeftTypeToNonNull) {
+      leftType = _typeSystem.promoteToNonNull(leftType);
+    }
+
+    ResolutionResult result = _typePropertyResolver.resolve(
+      receiver: leftOperand,
+      receiverType: leftType,
+      name: methodName,
+      receiverErrorNode: leftOperand,
+      nameErrorNode: node,
+    );
+
+    node.staticElement = result.getter;
+    node.staticInvokeType = result.getter?.type;
+    if (_shouldReportInvalidMember(leftType, result)) {
+      if (leftOperand is SuperExpression) {
+        _errorReporter.reportErrorForToken(
+          StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
+          node.operator,
+          [methodName, leftType],
+        );
+      } else {
+        _errorReporter.reportErrorForToken(
+          StaticTypeWarningCode.UNDEFINED_OPERATOR,
+          node.operator,
+          [methodName, leftType],
+        );
+      }
+    }
+  }
+
+  void _resolveUserDefinableType(BinaryExpressionImpl node) {
+    if (identical(node.leftOperand.staticType, NeverTypeImpl.instance)) {
+      _inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
+      return;
+    }
+
+    DartType staticType =
+        node.staticInvokeType?.returnType ?? DynamicTypeImpl.instance;
+    if (node.leftOperand is! ExtensionOverride) {
+      staticType = _typeSystem.refineBinaryExpressionType(
+        _getStaticType(node.leftOperand),
+        node.operator.type,
+        node.rightOperand.staticType,
+        staticType,
+      );
+    }
+    _inferenceHelper.recordStaticType(node, staticType);
+  }
 
   /// Return `true` if we should report an error for the lookup [result] on
   /// the [type].
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 fd27511..f668b54 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -8,8 +8,10 @@
 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/element/generic_inferrer.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
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 81ce4ed..fad0ca3 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -26,7 +26,7 @@
 
   /// The list of [Expression]s representing variable accesses that occur before
   /// the corresponding variable has been definitely assigned.
-  final List<AstNode> unassignedNodes = [];
+  final List<AstNode> potentiallyUnassignedNodes = [];
 
   /// The list of [SimpleIdentifier]s representing variable accesses that occur
   /// when the corresponding variable has been definitely unassigned.
@@ -181,12 +181,11 @@
     var element = node.staticElement;
     if (element is LocalVariableElement) {
       var typeSystem = _typeOperations.typeSystem;
+      var isUnassigned = !flow.isAssigned(element);
+      if (isUnassigned) {
+        dataForTesting?.potentiallyUnassignedNodes?.add(node);
+      }
       if (typeSystem.isPotentiallyNonNullable(element.type)) {
-        var isUnassigned = !flow.isAssigned(element);
-        if (isUnassigned) {
-          dataForTesting?.unassignedNodes?.add(node);
-        }
-
         // Note: in principle we could make this slightly more performant by
         // checking element.isLate earlier, but we would lose the ability to
         // test the flow analysis mechanism using late variables.  And it seems
@@ -219,6 +218,14 @@
     return false;
   }
 
+  void labeledStatement_enter(LabeledStatement node) {
+    flow.labeledStatement_begin(node);
+  }
+
+  void labeledStatement_exit(LabeledStatement node) {
+    flow.labeledStatement_end();
+  }
+
   void topLevelDeclaration_enter(
       Declaration node, FormalParameterList parameters, FunctionBody body) {
     assert(node != null);
@@ -273,26 +280,28 @@
   /// not specify a label), so the default enclosing target is returned.
   static Statement getLabelTarget(AstNode node, LabelElement element) {
     for (; node != null; node = node.parent) {
-      if (node is DoStatement ||
-          node is ForStatement ||
-          node is SwitchStatement ||
-          node is WhileStatement) {
-        if (element == null) {
+      if (element == null) {
+        if (node is DoStatement ||
+            node is ForStatement ||
+            node is SwitchStatement ||
+            node is WhileStatement) {
           return node;
         }
-        var parent = node.parent;
-        if (parent is LabeledStatement) {
-          for (var nodeLabel in parent.labels) {
-            if (identical(nodeLabel.label.staticElement, element)) {
+      } else {
+        if (node is LabeledStatement) {
+          if (_hasLabel(node.labels, element)) {
+            var statement = node.statement;
+            if (statement is Block ||
+                statement is IfStatement ||
+                statement is TryStatement) {
               return node;
             }
+            return statement;
           }
         }
-      }
-      if (element != null && node is SwitchStatement) {
-        for (var member in node.members) {
-          for (var nodeLabel in member.labels) {
-            if (identical(nodeLabel.label.staticElement, element)) {
+        if (node is SwitchStatement) {
+          for (var member in node.members) {
+            if (_hasLabel(member.labels, element)) {
               return node;
             }
           }
@@ -301,6 +310,15 @@
     }
     return null;
   }
+
+  static bool _hasLabel(List<Label> labels, LabelElement element) {
+    for (var nodeLabel in labels) {
+      if (identical(nodeLabel.label.staticElement, element)) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
 
 /// Override of [FlowAnalysisHelper] that invokes methods of
@@ -333,6 +351,18 @@
   TypeSystemTypeOperations(this.typeSystem);
 
   @override
+  DartType factor(DartType from, DartType what) {
+    return typeSystem.factor(from, what);
+  }
+
+  @override
+  bool isLocalVariableWithoutDeclaredType(PromotableElement variable) {
+    return variable is LocalVariableElement &&
+        variable.hasImplicitType &&
+        variable.initializer == null;
+  }
+
+  @override
   bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
     return type1 == type2;
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
index efb83e0..7844f5b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
@@ -8,9 +8,9 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/type_system.dart';
 import 'package:meta/meta.dart';
 
 /// Helper for resolving [ForStatement]s and [ForElement]s.
@@ -34,7 +34,7 @@
   }
 
   void resolveStatement(ForStatementImpl node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    _resolver.checkUnreachableNode(node);
 
     var forLoopParts = node.forLoopParts;
     if (forLoopParts is ForParts) {
@@ -63,7 +63,9 @@
         : null;
 
     if (iteratedType != null) {
-      return iteratedType.typeArguments.single;
+      var elementType = iteratedType.typeArguments.single;
+      elementType = _resolver.toLegacyTypeIfOptOut(elementType);
+      return elementType;
     } else {
       return null;
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index dd3dbcd1..4340e9d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -178,10 +178,13 @@
 
         exceptionNode.staticElement = element;
 
+        element.isFinal = true;
         if (exceptionTypeNode == null) {
           element.hasImplicitType = true;
-          element.type = _dynamicType;
-          exceptionNode.staticType = _dynamicType;
+          var type =
+              _isNonNullableByDefault ? _typeProvider.objectType : _dynamicType;
+          element.type = type;
+          exceptionNode.staticType = type;
         } else {
           element.type = exceptionTypeNode.type;
           exceptionNode.staticType = exceptionTypeNode.type;
@@ -201,6 +204,7 @@
 
         stackTraceNode.staticElement = element;
 
+        element.isFinal = true;
         element.type = _typeProvider.stackTraceType;
         stackTraceNode.staticType = _typeProvider.stackTraceType;
 
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 238602d..b955c20 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 6c5f405..71bcb62 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -4,7 +4,6 @@
 
 import 'dart:collection';
 
-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/ast/token.dart';
@@ -85,21 +84,14 @@
     this._currentLibrary,
     CompilationUnit unit,
     String content, {
-    TypeSystemImpl typeSystem,
+    @required TypeSystemImpl typeSystem,
     @required InheritanceManager3 inheritanceManager,
-    ResourceProvider resourceProvider,
-    DeclaredVariables declaredVariables,
-    AnalysisOptions analysisOptions,
+    @required ResourceProvider resourceProvider,
+    @required DeclaredVariables declaredVariables,
+    @required AnalysisOptions analysisOptions,
   })  : _nullType = typeProvider.nullType,
-        _typeSystem = typeSystem ??
-            TypeSystemImpl(
-              implicitCasts: true,
-              isNonNullableByDefault: false,
-              strictInference: false,
-              typeProvider: typeProvider,
-            ),
-        _isNonNullableByDefault =
-            unit.featureSet.isEnabled(Feature.non_nullable),
+        _typeSystem = typeSystem,
+        _isNonNullableByDefault = typeSystem.isNonNullableByDefault,
         _strictInference =
             (analysisOptions as AnalysisOptionsImpl).strictInference,
         _inheritanceManager = inheritanceManager,
@@ -242,6 +234,12 @@
   }
 
   @override
+  void visitCatchClause(CatchClause node) {
+    super.visitCatchClause(node);
+    _checkForNullableTypeInCatchClause(node);
+  }
+
+  @override
   void visitClassDeclaration(ClassDeclaration node) {
     ClassElementImpl element = node.declaredElement;
     _enclosingClass = element;
@@ -1163,6 +1161,24 @@
     }
   }
 
+  void _checkForNullableTypeInCatchClause(CatchClause node) {
+    if (!_isNonNullableByDefault) {
+      return;
+    }
+
+    var type = node.exceptionType;
+    if (type == null) {
+      return;
+    }
+
+    if (_typeSystem.isPotentiallyNullable(type.type)) {
+      _errorReporter.reportErrorForNode(
+        HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
+        type,
+      );
+    }
+  }
+
   /// Produce several null-aware related hints.
   void _checkForNullAwareHints(Expression node, Token operator) {
     if (_isNonNullableByDefault) {
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 9ab905c..3a45736 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -483,16 +483,88 @@
               "Try marking the function body with either 'async' or 'async*'.");
 
   /**
-   * It is an error if the body of a method, function, getter, or function
-   * expression with a potentially non-nullable return type may completely
-   * normally.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a method or function has a
+  // return type that's <a href=”#potentially-non-nullable”>potentially
+  // non-nullable</a> but would implicitly return `null` if control reached the
+  // end of the function.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the method `m` has an
+  // implicit return of `null` inserted at the end of the method, but the method
+  // is declared to not return `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int [!m!](int t) {
+  //     print(t);
+  //   }
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the method `m` has an
+  // implicit return of `null` inserted at the end of the method, but because
+  // the class `C` can be instantiated with a non-nullable type argument, the
+  // method is effectively declared to not return `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C<T> {
+  //   T [!m!](T t) {
+  //     print(t);
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If there's a reasonable value that can be returned, then add a return
+  // statement at the end of the method:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C<T> {
+  //   T m(T t) {
+  //     print(t);
+  //     return t;
+  //   }
+  // }
+  // ```
+  //
+  // If the method won't reach the implicit return, then add a throw at the end
+  // of the method:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C<T> {
+  //   T m(T t) {
+  //     print(t);
+  //     throw '';
+  //   }
+  // }
+  // ```
+  //
+  // If the method intentionally returns `null` at the end, then change the
+  // return type so that it's valid to return `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C<T> {
+  //   T? m(T t) {
+  //     print(t);
+  //   }
+  // }
+  // ```
   static const CompileTimeErrorCode BODY_MIGHT_COMPLETE_NORMALLY =
       CompileTimeErrorCode(
           'BODY_MIGHT_COMPLETE_NORMALLY',
-          "The body might complete normally, which would cause 'null' to be "
-              "returned, but the return type is a potentially "
-              "non-nullable type.",
+          "The body might complete normally, causing 'null' to be returned, "
+              "but the return type is a potentially non-nullable type.",
           correction:
               "Try adding either a return or a throw statement at the end.");
 
@@ -625,11 +697,59 @@
           "The switch case expression type '{0}' can't override the == "
               "operator.");
 
-  /// Given a switch statement which switches over an expression `e` of type
-  /// `T`, where the cases are dispatched based on expressions `e0` ... `ek`:
-  ///
-  /// It is an error if any of the `ei` evaluate to a value whose static type
-  /// is not a subtype of `T`.
+  /**
+   * Parameters:
+   * 0: the type of the case expression
+   * 1: the type of the switch expression
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the expression following `case`
+  // in a switch statement has a static type that isn't a subtype of the static
+  // type of the expression following `switch`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `1` is an `int`, which
+  // isn't a subtype of `String` (the type of `s`):
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String s) {
+  //   switch (s) {
+  //     case [!1!]:
+  //       break;
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the value of the case expression is wrong, then change the case
+  // expression so that it has the required type:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String s) {
+  //   switch (s) {
+  //     case '1':
+  //       break;
+  //   }
+  // }
+  // ```
+  //
+  // If the value of the case expression is correct, then change the switch
+  // expression to have the required type:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int s) {
+  //   switch (s) {
+  //     case 1:
+  //       break;
+  //   }
+  // }
+  // ```
   static const CompileTimeErrorCode
       CASE_EXPRESSION_TYPE_IS_NOT_SWITCH_EXPRESSION_SUBTYPE =
       CompileTimeErrorCode(
@@ -1348,12 +1468,53 @@
           "A continue label resolves to switch, must be loop or switch member");
 
   /**
-   * It is an error to call the default `List` constructor.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when it finds a use of the default
+  // constructor for the class `List` in code that has opted in to null safety.
+  //
+  // #### Example
+  //
+  // Assuming the following code is opted in to null safety, it produces this
+  // diagnostic because it uses the default `List` constructor:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // var l = [!List<int>!]();
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If no initial size is provided, then convert the code to use a list
+  // literal:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // var l = <int>[];
+  // ```
+  //
+  // If an initial size needs to be provided and there is a single reasonable
+  // initial value for the elements, then use `List.filled`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // var l = List.filled(3, 0);
+  // ```
+  //
+  // If an initial size needs to be provided but each element needs to be
+  // computed, then use `List.generate`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // var l = List.generate(3, (i) => i);
+  // ```
   static const CompileTimeErrorCode DEFAULT_LIST_CONSTRUCTOR =
       CompileTimeErrorCode('DEFAULT_LIST_CONSTRUCTOR',
-          "It is an error to call the default List constructor.",
-          correction: "Try using 'List.filled' or 'List.generate'.");
+          "Calling the default 'List' constructor causes an error.",
+          correction: "Try using a list literal, 'List.filled' or "
+              "'List.generate'.");
 
   /**
    * 6.2.1 Required Formals: By means of a function signature that names the
@@ -1427,17 +1588,46 @@
               "extensions.");
 
   /**
-   * It is a compile time error to read a local variable marked `late` when the
-   * variable is definitely unassigned. This includes all forms of reads,
-   * including implicit reads via the composite assignment operators as well
-   * as pre and post-fix operators.
-   *
    * Parameters:
    * 0: the name of the variable that is invalid
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when
+  // [definite assignment](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md)
+  // analysis shows that a local variable that's marked as `late` is read before
+  // being assigned.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` was not assigned a
+  // value before being read:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(bool b) {
+  //   late int x;
+  //   print([!x!]);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Assign a value to the variable before reading from it:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(bool b) {
+  //   late int x;
+  //   x = b ? 1 : 0;
+  //   print(x);
+  // }
+  // ```
   static const CompileTimeErrorCode DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE =
-      CompileTimeErrorCode('DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE',
-          "The late local variable '{0}' is definitely unassigned.",
+      CompileTimeErrorCode(
+          'DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE',
+          "The late local variable '{0}' is definitely unassigned at this "
+              "point.",
           correction:
               "Ensure that it is assigned on necessary execution paths.");
 
@@ -1566,19 +1756,6 @@
       hasPublishedDocs: true);
 
   /**
-   * 18.3 Parts: It's a compile-time error if the same library contains two part
-   * directives with the same URI.
-   *
-   * Parameters:
-   * 0: the URI of the duplicate part
-   */
-  static const CompileTimeErrorCode DUPLICATE_PART = CompileTimeErrorCode(
-      'DUPLICATE_PART',
-      "The library already contains a part with the uri '{0}'.",
-      correction:
-          "Try removing all but one of the duplicated part directives.");
-
-  /**
    * Parameters:
    * 0: the name of the parameter that was duplicated
    */
@@ -1636,6 +1813,24 @@
           hasPublishedDocs: true);
 
   /**
+   * 18.3 Parts: It's a compile-time error if the same library contains two part
+   * directives with the same URI.
+   *
+   * Parameters:
+   * 0: the URI of the duplicate part
+   */
+  static const CompileTimeErrorCode DUPLICATE_PART = CompileTimeErrorCode(
+      'DUPLICATE_PART',
+      "The library already contains a part with the uri '{0}'.",
+      correction:
+          "Try removing all but one of the duplicated part directives.");
+
+  static const CompileTimeErrorCode ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING =
+      CompileTimeErrorCode('ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING',
+          "The name of the enum constant can't be the same as the enum's name.",
+          correction: "Try renaming the constant.");
+
+  /**
    * No parameters.
    */
   // #### Description
@@ -1725,18 +1920,61 @@
           "The library '{0}' is internal and can't be exported.");
 
   /**
-   * It is an error for an opted-in library to re-export symbols which are
-   * defined in a legacy library.
-   *
    * Parameters:
    * 0: the name of a symbol defined in a legacy library
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a library that was opted in to
+  // null safety exports another library, and the exported library is opted out
+  // of null safety.
+  //
+  // #### Example
+  //
+  // Given a library that is opted out of null safety:
+  //
+  // ```dart
+  // %uri="lib/optedOut.dart"
+  // // @dart = 2.8
+  // String s;
+  // ```
+  //
+  // The following code produces this diagnostic because it's exporting symbols
+  // from an opted-out library:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // export [!'optedOut.dart'!];
+  //
+  // class C {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you're able to do so, migrate the exported library so that it doesn't
+  // need to opt out:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // String? s;
+  // ```
+  //
+  // If you can't migrate the library, then remove the export:
+  //
+  // ```dart
+  // class C {}
+  // ```
+  //
+  // If the exported library (the one that is opted out) itself exports an
+  // opted-in library, then it's valid for your library to indirectly export the
+  // symbols from the opted-in library. You can do so by adding a hide
+  // combinator to the export directive in your library that hides all of the
+  // names declared in the opted-out library.
   static const CompileTimeErrorCode EXPORT_LEGACY_SYMBOL = CompileTimeErrorCode(
       'EXPORT_LEGACY_SYMBOL',
       "The symbol '{0}' is defined in a legacy library, and can't be "
           "re-exported from a non-nullable by default library.",
-      correction: "Use show / hide combinators to avoid exporting these"
-          "symbols, or migrate the legacy library.");
+      correction: "Try removing the export or migrating the legacy library.");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at
@@ -3544,63 +3782,104 @@
   /**
    * No parameters.
    */
-  /* #### Description
+  // #### Description
   //
-  // The analyzer produces this diagnostic when an optional parameter doesn't
-  // have a default value, but has a
-  // <a href=”#potentially-non-nullable”>potentially non-nullable</a> type.
-  // Optional parameters that have no explicit default value have an implicit
-  // default value of `null`. If the type of the parameter doesn't allow the
-  // parameter to have a value of null, then the implicit default value is not
-  // valid.
+  // The analyzer produces this diagnostic when an optional parameter, whether
+  // positional or named, has a <a href=”#potentially-non-nullable”>potentially
+  // non-nullable</a> type and doesn't specify a default value. Optional
+  // parameters that have no explicit default value have an implicit default
+  // value of `null`. If the type of the parameter doesn't allow the parameter
+  // to have a value of `null`, then the implicit default value isn't valid.
   //
-  // #### Examples
+  // #### Example
   //
-  // The following code generates this diagnostic:
+  // The following code produces this diagnostic because `x` can't be `null`,
+  // and no non-`null` default value is specified:
   //
   // ```dart
-  // void log({String [!message!]}) {}
+  // %experiments=non-nullable
+  // void f([int [!x!]]) {}
+  // ```
+  //
+  // As does this:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void g({int [!x!]}) {}
   // ```
   //
   // #### Common fixes
   //
-  // If the parameter can have the value `null`, then add a question mark after
-  // the type annotation:
+  // If you want to use `null` to indicate that no value was provided, then you
+  // need to make the type nullable:
   //
   // ```dart
-  // void log({String? message}) {}
+  // %experiments=non-nullable
+  // void f([int? x]) {}
+  // void g({int? x}) {}
   // ```
   //
   // If the parameter can't be null, then either provide a default value:
   //
   // ```dart
-  // void log({String message = ''}) {}
+  // %experiments=non-nullable
+  // void f([int x = 1]) {}
+  // void g({int x = 2}) {}
   // ```
   //
-  // or add the `required` modifier to the parameter:
+  // or make the parameter a required parameter:
   //
   // ```dart
-  // void log({required String message}) {}
-  // ``` */
+  // %experiments=non-nullable
+  // void f(int x) {}
+  // void g({required int x}) {}
+  // ```
   static const CompileTimeErrorCode MISSING_DEFAULT_VALUE_FOR_PARAMETER =
       CompileTimeErrorCode(
           'MISSING_DEFAULT_VALUE_FOR_PARAMETER',
           "The parameter '{0}' can't have a value of 'null' because of its "
-              "type, so it must either be a required parameter or have a "
-              "default value.",
+              "type, and no non-null default value is provided.",
           correction:
               "Try adding either a default value or the 'required' modifier.");
 
   /**
-   * It is an error if a named parameter that is marked as being required is
-   * not bound to an argument at a call site.
-   *
    * Parameters:
    * 0: the name of the parameter
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an invocation of a function is
+  // missing a required named parameter.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the invocation of `f`
+  // doesn't include a value for the required named parameter `end`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int start, {required int end}) {}
+  // void g() {
+  //   [!f!](3);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Add a named argument corresponding to the missing required parameter:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(int start, {required int end}) {}
+  // void g() {
+  //   f(3, end: 5);
+  // }
+  // ```
   static const CompileTimeErrorCode MISSING_REQUIRED_ARGUMENT =
-      CompileTimeErrorCode('MISSING_REQUIRED_ARGUMENT',
-          "The named parameter '{0}' is required but was not provided.",
+      CompileTimeErrorCode(
+          'MISSING_REQUIRED_ARGUMENT',
+          "The named parameter '{0}' is required, but there's no corresponding "
+              "argument.",
           correction: "Try adding the required argument.");
 
   /**
@@ -4373,22 +4652,135 @@
       "Factory bodies can't use 'async', 'async*', or 'sync*'.");
 
   /**
-   * It is an error if a potentially non-nullable local variable which has no
-   * initializer expression and is not marked `late` is used before it is
-   * definitely assigned.
-   *
    * Parameters:
    * 0: the name of the variable that is invalid
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a local variable is referenced
+  // and has all these characteristics:
+  // - Has a type that's <a href=”#potentially-non-nullable”>potentially
+  //   non-nullable</a>.
+  // - Doesn't have an initializer.
+  // - Isn't marked as `late`.
+  // - The analyzer can't prove that the local variable will be assigned before
+  //   the reference based on the specification of
+  //   [definite assignment](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` can't have a value
+  // of `null`, but is referenced before a value was assigned to it:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // String f() {
+  //   int x;
+  //   return [!x!].toString();
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the assignment to `x`
+  // might not be executed, so it might have a value of `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int g(bool b) {
+  //   int x;
+  //   if (b) {
+  //     x = 1;
+  //   }
+  //   return [!x!] * 2;
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the analyzer can't
+  // prove, based on definite assignment analysis, that `x` won't be referenced
+  // without having a value assigned to it:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int h(bool b) {
+  //   int x;
+  //   if (b) {
+  //     x = 1;
+  //   }
+  //   if (b) {
+  //     return [!x!] * 2;
+  //   }
+  //   return 0;
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If `null` is a valid value, then make the variable nullable:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // String f() {
+  //   int? x;
+  //   return x!.toString();
+  // }
+  // ```
+  //
+  // If `null` isn’t a valid value, and there's a reasonable default value, then
+  // add an initializer:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int g(bool b) {
+  //   int x = 2;
+  //   if (b) {
+  //     x = 1;
+  //   }
+  //   return x * 2;
+  // }
+  // ```
+  //
+  // Otherwise, ensure that a value was assigned on every possible code path
+  // before the value is accessed:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int g(bool b) {
+  //   int x;
+  //   if (b) {
+  //     x = 1;
+  //   } else {
+  //     x = 2;
+  //   }
+  //   return x * 2;
+  // }
+  // ```
+  //
+  // You can also mark the variable as `late`, which removes the diagnostic, but
+  // if the variable isn't assigned a value before it's accessed, then it
+  // results in an exception being thrown at runtime. This approach should only
+  // be used if you're sure that the variable will always be assigned, even
+  // though the analyzer can't prove it based on definite assignment analysis.
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int h(bool b) {
+  //   late int x;
+  //   if (b) {
+  //     x = 1;
+  //   }
+  //   if (b) {
+  //     return x * 2;
+  //   }
+  //   return 0;
+  // }
+  // ```
   static const CompileTimeErrorCode
       NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
       CompileTimeErrorCode(
           'NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
           "The non-nullable local variable '{0}' must be assigned before it "
               "can be used.",
-          correction: "Try giving it an initializer expression, "
-              "or ensure that it is assigned on every execution path, "
-              "or mark it 'late'.");
+          correction: "Try giving it an initializer expression, or ensure that "
+              "it's assigned on every execution path.");
 
   /**
    * Parameters:
@@ -4434,14 +4826,82 @@
       NOT_ENOUGH_POSITIONAL_ARGUMENTS;
 
   /**
-   * It is an error if an instance field with potentially non-nullable type has
-   * no initializer expression and is not initialized in a constructor via an
-   * initializing formal or an initializer list entry, unless the field is
-   * marked with the `late` modifier.
-   *
    * Parameters:
    * 0: the name of the field that is not initialized
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a field is declared and has all
+  // these characteristics:
+  // - Has a type that's <a href=”#potentially-non-nullable”>potentially
+  //   non-nullable</a>
+  // - Doesn't have an initializer
+  // - Isn't marked as `late`
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` is implicitly
+  // initialized to `null` when it isn't allowed to be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int [!x!];
+  // }
+  // ```
+  //
+  // Similarly, the following code produces this diagnostic because `x` is
+  // implicitly initialized to `null`, when it isn't allowed to be `null`, by
+  // one of the constructors, even though it's initialized by other
+  // constructors:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int x;
+  //
+  //   C(this.x);
+  //
+  //   [!C!].n();
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If there's a reasonable default value for the field that’s the same for all
+  // instances, then add an initializer expression:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int x = 0;
+  // }
+  // ```
+  //
+  // If the value of the field should be provided when an instance is created,
+  // then add a constructor that sets the value of the field or update an
+  // existing constructor:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int x;
+  //
+  //   C(this.x);
+  // }
+  // ```
+  //
+  // You can also mark the field as `late`, which removes the diagnostic, but if
+  // the field isn't assigned a value before it's accessed, then it results in
+  // an exception being thrown at runtime. This approach should only be used if
+  // you're sure that the field will always be assigned before it's referenced.
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   late int x;
+  // }
+  // ```
   static const CompileTimeErrorCode
       NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD = CompileTimeErrorCode(
           'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
@@ -4451,11 +4911,6 @@
               "or mark it 'late'.");
 
   /**
-   * It is an error if an instance field with potentially non-nullable type has
-   * no initializer expression and is not initialized in a constructor via an
-   * initializing formal or an initializer list entry, unless the field is
-   * marked with the `late` modifier.
-   *
    * Parameters:
    * 0: the name of the field that is not initialized
    */
@@ -4470,12 +4925,66 @@
               "or mark it 'late'.");
 
   /**
-   * It is an error if a static field or top-level variable with potentially
-   * non-nullable type has no initializer expression.
-   *
    * Parameters:
    * 0: the name of the variable that is invalid
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a static field or top-level
+  // variable has a type that's non-nullable and doesn't have an initializer.
+  // Fields and variables that don't have an initializer are normally
+  // initialized to `null`, but the type of the field or variable doesn't allow
+  // it to be set to `null`, so an explicit initializer must be provided.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the field `f` can't be
+  // initialized to `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   static int [!f!];
+  // }
+  // ```
+  //
+  // Similarly, the following code produces this diagnostic because the
+  // top-level variable `v` can't be initialized to `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int [!v!];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the field or variable can't be initialized to `null`, then add an
+  // initializer that sets it to a non-null value:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   static int f = 0;
+  // }
+  // ```
+  //
+  // If the field or variable should be initialized to `null`, then change the
+  // type to be nullable:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int? v;
+  // ```
+  //
+  // If the field or variable can't be initialized in the declaration but will
+  // always be initialized before it's referenced, then mark it as being `late`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   static late int f;
+  // }
+  // ```
   static const CompileTimeErrorCode NOT_INITIALIZED_NON_NULLABLE_VARIABLE =
       CompileTimeErrorCode('NOT_INITIALIZED_NON_NULLABLE_VARIABLE',
           "The non-nullable variable '{0}' must be initialized.",
@@ -4544,6 +5053,9 @@
       'NOT_MAP_SPREAD', "Spread elements in map literals must implement 'Map'.",
       hasPublishedDocs: true);
 
+  /**
+   * No parameters.
+   */
   static const CompileTimeErrorCode NOT_NULL_AWARE_NULL_SPREAD =
       CompileTimeErrorCode(
           'NOT_NULL_AWARE_NULL_SPREAD',
@@ -4551,74 +5063,164 @@
               "spread.");
 
   /**
-   * It is an error if the type `T` in the on-catch clause `on T catch` is
-   * potentially nullable.
-   */
-  static const CompileTimeErrorCode NULLABLE_TYPE_IN_CATCH_CLAUSE =
-      CompileTimeErrorCode(
-          'NULLABLE_TYPE_IN_CATCH_CLAUSE',
-          "A nullable type can't be used in an 'on' clause because it isn't "
-              "valid to throw 'null'.",
-          correction: "Try removing the question mark.");
-
-  /**
    * No parameters.
    */
-  /* #### Description
+  // #### Description
   //
   // The analyzer produces this diagnostic when a class declaration uses an
-  // extends clause to specify a superclass, and the type that's specified is a
-  // nullable type.
+  // extends clause to specify a superclass, and the superclass is followed by a
+  // `?`.
   //
-  // The reason the supertype is a _type_ rather than a class name is to allow
-  // you to control the signatures of the members to be inherited from the
-  // supertype, such as by specifying type arguments. However, the nullability
-  // of a type doesn't change the signatures of any members, so there isn't any
-  // reason to allow the nullability to be specified when used in the extends
-  // clause.
+  // It isn't valid to specify a nullable superclass because doing so would have
+  // no meaning; it wouldn't change either the interface or implementation being
+  // inherited by the class containing the extends clause.
   //
-  // #### Examples
+  // Note, however, that it _is_ valid to use a nullable type as a type argument
+  // to the superclass, such as `class A extends B<C?> {}`.
   //
-  // The following code generates this diagnostic:
+  // #### Example
+  //
+  // The following code produces this diagnostic because `A?` is a nullable
+  // type, and nullable types can't be used in an extends clause:
   //
   // ```dart
-  // class Invalid extends [!Duration?!] {}
+  // %experiments=non-nullable
+  // class A {}
+  // class B extends [!A?!] {}
   // ```
   //
   // #### Common fixes
   //
-  // The most common fix is to remove the question mark:
+  // Remove the question mark from the type:
   //
   // ```dart
-  // class Invalid extends Duration {}
-  // ``` */
+  // %experiments=non-nullable
+  // class A {}
+  // class B extends A {}
+  // ```
   static const CompileTimeErrorCode NULLABLE_TYPE_IN_EXTENDS_CLAUSE =
       CompileTimeErrorCode('NULLABLE_TYPE_IN_EXTENDS_CLAUSE',
           "A class can't extend a nullable type.",
           correction: "Try removing the question mark.");
 
   /**
-   * It is a compile-time error for a class to extend, implement, or mixin a
-   * type of the form T? for any T.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a class or mixin declaration has
+  // an implements clause, and an interface is followed by a `?`.
+  //
+  // It isn't valid to specify a nullable interface because doing so would have
+  // no meaning; it wouldn't change the interface being inherited by the class
+  // containing the implements clause.
+  //
+  // Note, however, that it _is_ valid to use a nullable type as a type argument
+  // to the interface, such as `class A implements B<C?> {}`.
+  //
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `A?` is a nullable
+  // type, and nullable types can't be used in an implements clause:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class A {}
+  // class B implements [!A?!] {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the question mark from the type:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class A {}
+  // class B implements A {}
+  // ```
   static const CompileTimeErrorCode NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE =
       CompileTimeErrorCode('NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE',
           "A class or mixin can't implement a nullable type.",
           correction: "Try removing the question mark.");
 
   /**
-   * It is a compile-time error for a class to extend, implement, or mixin a
-   * type of the form T? for any T.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a mixin declaration uses an on
+  // clause to specify a superclass constraint, and the class that's specified
+  // is followed by a `?`.
+  //
+  // It isn't valid to specify a nullable superclass constraint because doing so
+  // would have no meaning; it wouldn't change the interface being depended on
+  // by the mixin containing the on clause.
+  //
+  // Note, however, that it _is_ valid to use a nullable type as a type argument
+  // to the superclass constraint, such as `mixin A on B<C?> {}`.
+  //
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `A?` is a nullable type
+  // and nullable types can't be used in an on clause:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {}
+  // mixin M on [!C?!] {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the question mark from the type:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {}
+  // mixin M on C {}
+  // ```
   static const CompileTimeErrorCode NULLABLE_TYPE_IN_ON_CLAUSE =
       CompileTimeErrorCode('NULLABLE_TYPE_IN_ON_CLAUSE',
           "A mixin can't have a nullable type as a superclass constraint.",
           correction: "Try removing the question mark.");
 
   /**
-   * It is a compile-time error for a class to extend, implement, or mixin a
-   * type of the form T? for any T.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a class or mixin declaration has
+  // a with clause, and a mixin is followed by a `?`.
+  //
+  // It isn't valid to specify a nullable mixin because doing so would have no
+  // meaning; it wouldn't change either the interface or implementation being
+  // inherited by the class containing the with clause.
+  //
+  // Note, however, that it _is_ valid to use a nullable type as a type argument
+  // to the mixin, such as `class A with B<C?> {}`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `A?` is a nullable
+  // type, and nullable types can't be used in a with clause:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // mixin M {}
+  // class C with [!M?!] {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the question mark from the type:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // mixin M {}
+  // class C with M {}
+  // ```
   static const CompileTimeErrorCode NULLABLE_TYPE_IN_WITH_CLAUSE =
       CompileTimeErrorCode('NULLABLE_TYPE_IN_WITH_CLAUSE',
           "A class or mixin can't mix in a nullable type.",
@@ -4892,6 +5494,17 @@
           correction: "Try redirecting to a different constructor.");
 
   /**
+   * A factory constructor can't redirect to a non-generative constructor of an
+   * abstract class.
+   */
+  static const CompileTimeErrorCode REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR =
+      CompileTimeErrorCode(
+          'REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR',
+          "The redirecting constructor '{0}' can't redirect to a constructor "
+              "of the abstract class '{1}'.",
+          correction: "Try redirecting to a constructor of a different class.");
+
+  /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with
    * the const modifier but <i>k'</i> is not a constant constructor.
    */
@@ -5165,6 +5778,42 @@
 
   /**
    * Parameters:
+   * 0: the type that can't be thrown
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the type of the expression in a
+  // throw expression is not assignable to `Object`. It’s not valid to throw
+  // `null`, so it isn't valid to use an expression that might evaluate to
+  // `null`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `s` might be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String? s) {
+  //   throw [!s!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Add an explicit null check to the expression:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String? s) {
+  //   throw s!;
+  // }
+  // ```
+  static const CompileTimeErrorCode THROW_OF_INVALID_TYPE = CompileTimeErrorCode(
+      'THROW_OF_INVALID_TYPE',
+      "The type '{0}' of the thrown expression must be assignable to 'Object'.");
+
+  /**
+   * Parameters:
    * 0: the name of the type used in the instance creation that should be
    *    limited by the bound as specified in the class declaration
    * 1: the name of the bounding type
@@ -7756,15 +8405,90 @@
       INSTANTIATE_ABSTRACT_CLASS;
 
   /**
-   * It is a warning to use null aware operators '??' or '??=' on an
-   * expression of type `T` if `T` is strictly non-nullable.
-   *
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic in two cases.
+  //
+  // The first is when the left operand of an `??` operator can't be `null`.
+  // The right operand is only evaluated if the left operand has the value
+  // `null`, and because the left operand can't be `null`, the right operand is
+  // never evaluated.
+  //
+  // The second is when the left-hand side of an assignment using the `??=`
+  // operator can't be `null`. The right-hand side is only evaluated if the
+  // left-hand side has the value `null`, and because the left-hand side can't
+  // be `null`, the right-hand side is never evaluated.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` can't be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int f(int x) {
+  //   return x ?? [!0!];
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because `f` can't be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int f = -1;
+  //
+  //   void m(int x) {
+  //     f ??= [!x!];
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the diagnostic is reported for an `??` operator, then remove the `??`
+  // operator and the right operand:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int f(int x) {
+  //   return x;
+  // }
+  // ```
+  //
+  // If the diagnostic is reported for an assignment, and the assignment isn't
+  // needed, then remove the assignment:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int f = -1;
+  //
+  //   void m(int x) {
+  //   }
+  // }
+  // ```
+  //
+  // If the assignment is needed, but should be based on a different condition,
+  // then rewrite the code to use `=` and the different condition:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // class C {
+  //   int f = -1;
+  //
+  //   void m(int x) {
+  //     if (f < 0) {
+  //       f = x;
+  //     }
+  //   }
+  // }
+  // ```
   static const StaticWarningCode DEAD_NULL_AWARE_EXPRESSION = StaticWarningCode(
       'DEAD_NULL_AWARE_EXPRESSION',
       "The left operand can't be null, so the right operand is never executed.",
-      correction: "Try removing the right operand.",
+      correction: "Try removing the operator and the right operand.",
       errorSeverity: ErrorSeverity.WARNING);
 
   /**
@@ -8128,6 +8852,45 @@
    * 0: The null-aware operator that is invalid
    * 1: The non-null-aware operator that can replace the invalid operator
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a null-aware operator (`?.`,
+  // `?..`, `?[`, `?..[`, or `...?`) is used on a target that's known to be
+  // non-nullable.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `s` can't be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int? getLength(String s) {
+  //   return s[!?.!]length;
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because `a` can't be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // var a = [];
+  // var b = [[!...?!]a];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Replace the null-aware operator with a non-null-aware equivalent, such as
+  // replacing '?.' with  '.':
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int getLength(String s) {
+  //   return s.length;
+  // }
+  // ```
+  //
+  // (Note that the return type was also changed to be non-nullable, which might
+  // not be appropriate in some cases.)
   static const StaticWarningCode INVALID_NULL_AWARE_OPERATOR =
       StaticWarningCode(
           'INVALID_NULL_AWARE_OPERATOR',
@@ -8168,24 +8931,40 @@
           errorSeverity: ErrorSeverity.WARNING);
 
   /**
-   * For the purposes of experimenting with potential non-null type semantics.
-   *
-   * Whereas [UNCHECKED_USE_OF_NULLABLE] refers to using a value of type T? as
-   * if it were a T, this refers to using a value of type [Null] itself. These
-   * occur at many of the same times ([Null] is a potentially nullable type) but
-   * it indicates a different type of programmer error and has different
-   * corrections.
-   *
    * No parameters.
    */
-  static const StaticWarningCode INVALID_USE_OF_NULL_VALUE =
-      StaticWarningCodeWithUniqueName(
-          'USE_OF_NULLABLE_VALUE',
-          'INVALID_USE_OF_NULL_VALUE',
-          "This expression is invalid as it will always be null.",
-          correction:
-              "Try changing the type, or casting, to a more useful type like "
-              "dynamic.");
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an expression whose value will
+  // always be `null` is dererenced.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` will always be
+  // `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int f(Null x) {
+  //   return [!x!].length;
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the value is allowed to be something other than `null`, then change the
+  // type of the expression:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int f(String? x) {
+  //   return x!.length;
+  // }
+  // ```
+  static const StaticWarningCode INVALID_USE_OF_NULL_VALUE = StaticWarningCode(
+      'INVALID_USE_OF_NULL_VALUE',
+      "An expression whose value is always 'null' can't be dereferenced.",
+      correction: "Try changing the type of the expression.");
 
   /**
    * Parameters:
@@ -8864,7 +9643,7 @@
       StaticWarningCode(
           'REDIRECT_TO_INVALID_RETURN_TYPE',
           "The return type '{0}' of the redirected constructor isn't "
-              "assignable to '{1}'.",
+              "a subtype of '{1}'.",
           correction: "Try redirecting to a different constructor.",
           hasPublishedDocs: true);
 
@@ -9131,29 +9910,111 @@
       CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER;
 
   /**
-   * For the purposes of experimenting with potential non-null type semantics.
-   *
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an expression whose type is
+  // <a href=”#potentially-non-nullable”>potentially non-nullable</a> is
+  // dereferenced without first verifying that the value isn't `null`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `s` can be `null` at
+  // the point where it's referenced:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String? s) {
+  //   if ([!s!].length > 3) {
+  //     // ...
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the value really can be `null`, then add a test to ensure that members
+  // are only accessed when the value isn't `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String? s) {
+  //   if (s != null && s.length > 3) {
+  //     // ...
+  //   }
+  // }
+  // ```
+  //
+  // If the expression is a variable and the value should never be `null`, then
+  // change the type of the variable to be non-nullable:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String s) {
+  //   if (s.length > 3) {
+  //     // ...
+  //   }
+  // }
+  // ```
+  //
+  // If you believe that the value of the expression should never be `null`, but
+  // you can't change the type of the variable, and you're willing to risk
+  // having an exception thrown at runtime if you're wrong, then you can assert
+  // that the value isn't null:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // void f(String? s) {
+  //   if (s!.length > 3) {
+  //     // ...
+  //   }
+  // }
+  // ```
   static const StaticWarningCode UNCHECKED_USE_OF_NULLABLE_VALUE =
-      StaticWarningCodeWithUniqueName(
-          'USE_OF_NULLABLE_VALUE',
+      StaticWarningCode(
           'UNCHECKED_USE_OF_NULLABLE_VALUE',
-          "The expression is nullable and must be null-checked before it can "
-              "be used.",
+          "An expression whose value can be 'null' must be null-checked before "
+              "it can be dereferenced.",
           correction:
-              "Try checking that the value isn't null before using it.");
+              "Try checking that the value isn't 'null' before dereferencing "
+              "it.");
 
   /**
-   * When the '!' operator is used on a value that we know to be non-null,
-   * it is unnecessary.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the operand of the `!` operator
+  // can't be `null`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `x` can't be `null`:
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int f(int x) {
+  //   return x[!!!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the null check operator (`!`):
+  //
+  // ```dart
+  // %experiments=non-nullable
+  // int f(int x) {
+  //   return x;
+  // }
+  // ```
   static const StaticWarningCode UNNECESSARY_NON_NULL_ASSERTION =
       StaticWarningCode(
           'UNNECESSARY_NON_NULL_ASSERTION',
-          "The '!' will have no effect because the target expression cannot be"
+          "The '!' will have no effect because the target expression can't be"
               " null.",
-          correction: "Try removing the '!' operator here.",
+          correction: "Try removing the '!' operator.",
           errorSeverity: ErrorSeverity.WARNING);
 
   /**
diff --git a/pkg/analyzer/lib/src/error/correct_override.dart b/pkg/analyzer/lib/src/error/correct_override.dart
index e513da0..7d67e40 100644
--- a/pkg/analyzer/lib/src/error/correct_override.dart
+++ b/pkg/analyzer/lib/src/error/correct_override.dart
@@ -7,6 +7,7 @@
 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/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
@@ -16,16 +17,12 @@
 import 'package:meta/meta.dart';
 
 class CorrectOverrideHelper {
-  final LibraryElement _library;
+  final LibraryElementImpl _library;
   final TypeSystemImpl _typeSystem;
 
   final ExecutableElement _thisMember;
   FunctionType _thisTypeForSubtype;
 
-  bool _hasCovariant = false;
-  Substitution _thisSubstitution;
-  Substitution _superSubstitution;
-
   CorrectOverrideHelper({
     @required LibraryElement library,
     @required ExecutableElement thisMember,
@@ -42,50 +39,7 @@
     superMember = _library.toLegacyElementIfOptOut(superMember);
 
     var superType = superMember.type;
-    if (!_typeSystem.isSubtypeOf2(_thisTypeForSubtype, superType)) {
-      return false;
-    }
-
-    // If no covariant parameters, then the subtype checking above is enough.
-    if (!_hasCovariant) {
-      return true;
-    }
-
-    _initSubstitutions(superType);
-
-    var thisParameters = _thisMember.parameters;
-    for (var i = 0; i < thisParameters.length; i++) {
-      var thisParameter = thisParameters[i];
-      if (thisParameter.isCovariant) {
-        var superParameter = _correspondingParameter(
-          superType.parameters,
-          thisParameter,
-          i,
-        );
-        if (superParameter != null) {
-          var thisParameterType = thisParameter.type;
-          var superParameterType = superParameter.type;
-
-          if (_thisSubstitution != null) {
-            thisParameterType = _thisSubstitution.substituteType(
-              thisParameterType,
-            );
-            superParameterType = _superSubstitution.substituteType(
-              superParameterType,
-            );
-          }
-
-          if (!_typeSystem.isSubtypeOf2(
-                  superParameterType, thisParameterType) &&
-              !_typeSystem.isSubtypeOf2(
-                  thisParameterType, superParameterType)) {
-            return false;
-          }
-        }
-      }
-    }
-
-    return true;
+    return _typeSystem.isSubtypeOf2(_thisTypeForSubtype, superType);
   }
 
   /// If [_thisMember] is not a correct override of [superMember], report the
@@ -120,7 +74,6 @@
     for (var i = 0; i < parameters.length; i++) {
       var parameter = parameters[i];
       if (parameter.isCovariant) {
-        _hasCovariant = true;
         newParameters ??= parameters.toList(growable: false);
         newParameters[i] = ParameterElementImpl.synthetic(
           parameter.name,
@@ -145,35 +98,138 @@
       _thisTypeForSubtype = type;
     }
   }
+}
 
-  /// We know that [_thisMember] has a covariant parameter, which we need
-  /// to check against the corresponding parameters in [superType]. their types
-  /// should be compatible. If [_thisMember] (and correspondingly [superType])
-  /// has type parameters, we need to convert types of formal parameters in
-  /// both to the same type parameters.
-  void _initSubstitutions(FunctionType superType) {
-    var thisParameters = _thisMember.typeParameters;
-    var superParameters = superType.typeFormals;
-    if (thisParameters.isEmpty) {
-      return;
+class CovariantParametersVerifier {
+  final AnalysisSessionImpl _session;
+  final TypeSystemImpl _typeSystem;
+
+  final ExecutableElement _thisMember;
+
+  CovariantParametersVerifier({
+    @required ExecutableElement thisMember,
+  })  : _session = thisMember.library.session,
+        _typeSystem = thisMember.library.typeSystem,
+        _thisMember = thisMember;
+
+  void verify({
+    @required ErrorReporter errorReporter,
+    @required AstNode errorNode,
+  }) {
+    var superParameters = _superParameters();
+    for (var entry in superParameters.entries) {
+      var parameter = entry.key;
+      for (var superParameter in entry.value) {
+        var thisType = parameter.type;
+        var superType = superParameter.type;
+        if (!_typeSystem.isSubtypeOf2(superType, thisType) &&
+            !_typeSystem.isSubtypeOf2(thisType, superType)) {
+          var superMember = superParameter.member;
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.INVALID_OVERRIDE,
+            errorNode,
+            [
+              _thisMember.name,
+              _thisMember.enclosingElement.name,
+              _thisMember.type,
+              superMember.enclosingElement.name,
+              superMember.type,
+            ],
+          );
+        }
+      }
+    }
+  }
+
+  List<_SuperMember> _superMembers() {
+    var classHierarchy = _session.classHierarchy;
+    var classElement = _thisMember.enclosingElement;
+    var interfaces = classHierarchy.implementedInterfaces(classElement);
+
+    var superMembers = <_SuperMember>[];
+    for (var interface in interfaces) {
+      var superMember = _correspondingMember(interface.element, _thisMember);
+      if (superMember != null) {
+        superMembers.add(
+          _SuperMember(interface, superMember),
+        );
+      }
     }
 
-    var newParameters = <TypeParameterElement>[];
-    var newTypes = <TypeParameterType>[];
-    for (var i = 0; i < thisParameters.length; i++) {
-      var newParameter = TypeParameterElementImpl.synthetic(
-        thisParameters[i].name,
-      );
-      newParameters.add(newParameter);
+    return superMembers;
+  }
 
-      var newType = newParameter.instantiate(
-        nullabilitySuffix: NullabilitySuffix.none,
-      );
-      newTypes.add(newType);
+  Map<ParameterElement, List<_SuperParameter>> _superParameters() {
+    var result = <ParameterElement, List<_SuperParameter>>{};
+
+    List<_SuperMember> superMembers;
+    var parameters = _thisMember.parameters;
+    for (var i = 0; i < parameters.length; i++) {
+      var parameter = parameters[i];
+      if (parameter.isCovariant) {
+        superMembers ??= _superMembers();
+        for (var superMember in superMembers) {
+          var superParameter = _correspondingParameter(
+            superMember.rawElement.parameters,
+            parameter,
+            i,
+          );
+          if (superParameter != null) {
+            var parameterSuperList = (result[parameter] ??= []);
+            var superType = _superSubstitution(superMember)
+                .substituteType(superParameter.type);
+            parameterSuperList.add(
+              _SuperParameter(superParameter, superType),
+            );
+          }
+        }
+      }
     }
 
-    _thisSubstitution = Substitution.fromPairs(thisParameters, newTypes);
-    _superSubstitution = Substitution.fromPairs(superParameters, newTypes);
+    return result;
+  }
+
+  /// Return the [Substitution] to convert types of [superMember] to types of
+  /// [_thisMember].
+  Substitution _superSubstitution(_SuperMember superMember) {
+    var result = Substitution.fromInterfaceType(superMember.interface);
+
+    // If the executable has type parameters, ensure that super uses the same.
+    var thisTypeParameters = _thisMember.typeParameters;
+    if (thisTypeParameters.isNotEmpty) {
+      var superTypeParameters = superMember.rawElement.typeParameters;
+      if (thisTypeParameters.length == superTypeParameters.length) {
+        var typeParametersSubstitution = Substitution.fromPairs(
+          superTypeParameters,
+          thisTypeParameters.map((e) {
+            return e.instantiate(
+              nullabilitySuffix: NullabilitySuffix.none,
+            );
+          }).toList(),
+        );
+        result = Substitution.combine(result, typeParametersSubstitution);
+      }
+    }
+
+    return result;
+  }
+
+  /// Return a member from [classElement] that corresponds to the [proto],
+  /// or `null` if no such member exist.
+  static ExecutableElement _correspondingMember(
+    ClassElement classElement,
+    ExecutableElement proto,
+  ) {
+    if (proto is MethodElement) {
+      return classElement.getMethod(proto.displayName);
+    }
+    if (proto is PropertyAccessorElement) {
+      if (proto.isGetter) {
+        return classElement.getGetter(proto.displayName);
+      }
+      return classElement.getSetter(proto.displayName);
+    }
+    return null;
   }
 
   /// Return an element of [parameters] that corresponds for the [proto],
@@ -201,3 +257,19 @@
     return null;
   }
 }
+
+class _SuperMember {
+  final InterfaceType interface;
+  final ExecutableElement rawElement;
+
+  _SuperMember(this.interface, this.rawElement);
+}
+
+class _SuperParameter {
+  final ParameterElement element;
+  final DartType type;
+
+  _SuperParameter(this.element, this.type);
+
+  ExecutableElement get member => element.enclosingElement;
+}
diff --git a/pkg/analyzer/lib/src/error/dead_code_verifier.dart b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
index 0edeacd..780f770 100644
--- a/pkg/analyzer/lib/src/error/dead_code_verifier.dart
+++ b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
@@ -10,13 +10,22 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer/src/dart/resolver/exit_detector.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 
+typedef _CatchClausesVerifierReporter = void Function(
+  CatchClause first,
+  CatchClause last,
+  ErrorCode,
+  List<Object> arguments,
+);
+
 /// A visitor that finds dead code and unused labels.
 class DeadCodeVerifier extends RecursiveAstVisitor<void> {
   /// The error reporter by which errors will be reported.
@@ -265,67 +274,27 @@
   void visitTryStatement(TryStatement node) {
     node.body?.accept(this);
     node.finallyBlock?.accept(this);
-    NodeList<CatchClause> catchClauses = node.catchClauses;
-    int numOfCatchClauses = catchClauses.length;
-    List<DartType> visitedTypes = <DartType>[];
-    for (int i = 0; i < numOfCatchClauses; i++) {
-      CatchClause catchClause = catchClauses[i];
-      if (catchClause.onKeyword != null) {
-        // An on-catch clause was found; verify that the exception type is not a
-        // subtype of a previous on-catch exception type.
-        DartType currentType = catchClause.exceptionType?.type;
-        if (currentType != null) {
-          if (currentType.isObject) {
-            // Found catch clause clause that has Object as an exception type,
-            // this is equivalent to having a catch clause that doesn't have an
-            // exception type, visit the block, but generate an error on any
-            // following catch clauses (and don't visit them).
-            catchClause?.accept(this);
-            if (i + 1 != numOfCatchClauses) {
-              // This catch clause is not the last in the try statement.
-              CatchClause nextCatchClause = catchClauses[i + 1];
-              CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
-              int offset = nextCatchClause.offset;
-              int length = lastCatchClause.end - offset;
-              _errorReporter.reportErrorForOffset(
-                  HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length);
-              return;
-            }
-          }
-          int length = visitedTypes.length;
-          for (int j = 0; j < length; j++) {
-            DartType type = visitedTypes[j];
-            if (_typeSystem.isSubtypeOf2(currentType, type)) {
-              CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
-              int offset = catchClause.offset;
-              int length = lastCatchClause.end - offset;
-              _errorReporter.reportErrorForOffset(
-                  HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
-                  offset,
-                  length,
-                  [currentType, type]);
-              return;
-            }
-          }
-          visitedTypes.add(currentType);
-        }
-        catchClause?.accept(this);
-      } else {
-        // Found catch clause clause that doesn't have an exception type,
-        // visit the block, but generate an error on any following catch clauses
-        // (and don't visit them).
-        catchClause?.accept(this);
-        if (i + 1 != numOfCatchClauses) {
-          // This catch clause is not the last in the try statement.
-          CatchClause nextCatchClause = catchClauses[i + 1];
-          CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
-          int offset = nextCatchClause.offset;
-          int length = lastCatchClause.end - offset;
-          _errorReporter.reportErrorForOffset(
-              HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length);
-          return;
-        }
+
+    var verifier = _CatchClausesVerifier(
+      _typeSystem,
+      (first, last, errorCode, arguments) {
+        var offset = first.offset;
+        var length = last.end - offset;
+        _errorReporter.reportErrorForOffset(
+          errorCode,
+          offset,
+          length,
+          arguments,
+        );
+      },
+      node.catchClauses,
+    );
+    for (var catchClause in node.catchClauses) {
+      verifier.nextCatchClause(catchClause);
+      if (verifier._done) {
+        break;
       }
+      catchClause.accept(this);
     }
   }
 
@@ -472,6 +441,195 @@
   }
 }
 
+/// Helper for tracking dead code - [CatchClause]s and unreachable code.
+///
+/// [CatchClause]s are checked separately, as we visit AST we may make some
+/// of them as dead, and record [_deadCatchClauseRanges].
+///
+/// When an unreachable node is found, and [_firstDeadNode] is `null`, we
+/// set [_firstDeadNode], so start a new dead nodes interval. The dead code
+/// interval ends when [flowEnd] is invoked with a node that is the start
+/// node, or contains it. So, we end the the end of the covering control flow.
+class NullSafetyDeadCodeVerifier {
+  final TypeSystemImpl _typeSystem;
+  final ErrorReporter _errorReporter;
+  final FlowAnalysisHelper _flowAnalysis;
+
+  /// The stack of verifiers of (potentially nested) try statements.
+  final List<_CatchClausesVerifier> _catchClausesVerifiers = [];
+
+  /// When a sequence [CatchClause]s is found to be dead, we don't want to
+  /// report additional dead code inside of already dead code.
+  final List<SourceRange> _deadCatchClauseRanges = [];
+
+  /// When this field is `null`, we are in reachable code.
+  /// Once we find the first unreachable node, we store it here.
+  ///
+  /// When this field is not `null`, and we see an unreachable node, this new
+  /// node is ignored, because it continues the same dead code range.
+  AstNode _firstDeadNode;
+
+  NullSafetyDeadCodeVerifier(
+    this._typeSystem,
+    this._errorReporter,
+    this._flowAnalysis,
+  );
+
+  /// The [node] ends a basic block in the control flow. If [_firstDeadNode] is
+  /// not `null`, and is covered by the [node], then we reached the end of
+  /// the current dead code interval.
+  void flowEnd(AstNode node) {
+    if (_firstDeadNode != null) {
+      if (!_containsFirstDeadNode(node)) {
+        return;
+      }
+
+      // We know that [node] is the first dead node, or contains it.
+      // So, technically the code code interval ends at the end of [node].
+      // But we trim it to the last statement for presentation purposes.
+      if (node != _firstDeadNode) {
+        if (node is FunctionDeclaration) {
+          node = (node as FunctionDeclaration).functionExpression.body;
+        }
+        if (node is FunctionExpression) {
+          node = (node as FunctionExpression).body;
+        }
+        if (node is MethodDeclaration) {
+          node = (node as MethodDeclaration).body;
+        }
+        if (node is BlockFunctionBody) {
+          node = (node as BlockFunctionBody).block;
+        }
+        if (node is Block && node.statements.isNotEmpty) {
+          node = (node as Block).statements.last;
+        }
+        if (node is SwitchMember && node.statements.isNotEmpty) {
+          node = (node as SwitchMember).statements.last;
+        }
+      }
+
+      var offset = _firstDeadNode.offset;
+      var length = node.end - offset;
+      _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE, offset, length);
+
+      _firstDeadNode = null;
+    }
+  }
+
+  void tryStatementEnter(TryStatement node) {
+    var verifier = _CatchClausesVerifier(
+      _typeSystem,
+      (first, last, errorCode, arguments) {
+        var offset = first.offset;
+        var length = last.end - offset;
+        _errorReporter.reportErrorForOffset(
+          errorCode,
+          offset,
+          length,
+          arguments,
+        );
+        _deadCatchClauseRanges.add(SourceRange(offset, length));
+      },
+      node.catchClauses,
+    );
+    _catchClausesVerifiers.add(verifier);
+  }
+
+  void tryStatementExit(TryStatement node) {
+    _catchClausesVerifiers.removeLast();
+  }
+
+  void verifyCatchClause(CatchClause node) {
+    var verifier = _catchClausesVerifiers.last;
+    if (verifier._done) return;
+
+    verifier.nextCatchClause(node);
+  }
+
+  void visitNode(AstNode node) {
+    // Comments are visited after bodies of functions.
+    // So, they look unreachable, but this does not make sense.
+    if (node is Comment) return;
+
+    if (_flowAnalysis == null) return;
+    _flowAnalysis.checkUnreachableNode(node);
+
+    var flow = _flowAnalysis.flow;
+    if (flow == null) return;
+
+    if (flow.isReachable) return;
+
+    // If in a dead `CatchClause`, no need to report dead code.
+    for (var range in _deadCatchClauseRanges) {
+      if (range.contains(node.offset)) {
+        return;
+      }
+    }
+
+    if (_firstDeadNode != null) return;
+    _firstDeadNode = node;
+  }
+
+  bool _containsFirstDeadNode(AstNode parent) {
+    for (var node = _firstDeadNode; node != null; node = node.parent) {
+      if (node == parent) return true;
+    }
+    return false;
+  }
+}
+
+class _CatchClausesVerifier {
+  final TypeSystemImpl _typeSystem;
+  final _CatchClausesVerifierReporter _errorReporter;
+  final List<CatchClause> catchClauses;
+
+  bool _done = false;
+  List<DartType> _visitedTypes = <DartType>[];
+
+  _CatchClausesVerifier(
+    this._typeSystem,
+    this._errorReporter,
+    this.catchClauses,
+  );
+
+  void nextCatchClause(CatchClause catchClause) {
+    var currentType = catchClause.exceptionType?.type;
+
+    // Found catch clause that doesn't have an exception type.
+    // Generate an error on any following catch clauses.
+    if (currentType == null || currentType.isDartCoreObject) {
+      if (catchClause != catchClauses.last) {
+        var index = catchClauses.indexOf(catchClause);
+        _errorReporter(
+          catchClauses[index + 1],
+          catchClauses.last,
+          HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
+          const [],
+        );
+        _done = true;
+      }
+      return;
+    }
+
+    // An on-catch clause was found; verify that the exception type is not a
+    // subtype of a previous on-catch exception type.
+    for (var type in _visitedTypes) {
+      if (_typeSystem.isSubtypeOf2(currentType, type)) {
+        _errorReporter(
+          catchClause,
+          catchClauses.last,
+          HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
+          [currentType, type],
+        );
+        _done = true;
+        return;
+      }
+    }
+
+    _visitedTypes.add(currentType);
+  }
+}
+
 /// An object used to track the usage of labels within a single label scope.
 class _LabelTracker {
   /// The tracker for the outer label scope.
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 8c8837f..dea3b72 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -42,24 +42,29 @@
     Map<String, Element> instanceGetters = HashMap<String, Element>();
     Map<String, Element> staticGetters = HashMap<String, Element>();
 
-    String indexName = 'index';
-    String valuesName = 'values';
-    instanceGetters[indexName] = element.getGetter(indexName);
-    staticGetters[valuesName] = element.getGetter(valuesName);
+    instanceGetters['index'] = element.getGetter('index');
+    instanceGetters['toString'] = element.getMethod('toString');
+    staticGetters['values'] = element.getGetter('values');
 
     for (EnumConstantDeclaration constant in node.constants) {
       _checkDuplicateIdentifier(staticGetters, constant.name);
     }
 
+    String enumName = element.name;
     for (EnumConstantDeclaration constant in node.constants) {
       SimpleIdentifier identifier = constant.name;
       String name = identifier.name;
-      if (instanceGetters.containsKey(name)) {
-        String enumName = element.displayName;
+      if (name == enumName) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-            identifier,
-            [enumName, name, enumName]);
+          CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
+          identifier,
+        );
+      } else if (instanceGetters.containsKey(name)) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+          identifier,
+          [enumName, name, enumName],
+        );
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 4596a57..7d6fc78 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -18,6 +18,7 @@
 import 'package:analyzer/src/error/getter_setter_types_verifier.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
 import 'package:analyzer/src/generated/type_system.dart';
+import 'package:meta/meta.dart';
 
 class InheritanceOverrideVerifier {
   static const _missingOverridesKey = 'missingOverrides';
@@ -103,12 +104,7 @@
   final TypeName superclass;
   final WithClause withClause;
 
-  /// The set of unique supertypes of the current class.
-  /// It is used to decide when to add a new element to [allSuperinterfaces].
-  final Set<InterfaceType> allSupertypes = <InterfaceType>{};
-
-  /// The list of all superinterfaces, collected so far.
-  final List<Interface> allSuperinterfaces = [];
+  final List<InterfaceType> directSuperInterfaces = [];
 
   _ClassVerifier({
     this.typeSystem,
@@ -126,6 +122,8 @@
   })  : libraryUri = library.source.uri,
         classElement = classNameNode.staticElement;
 
+  bool get _isNonNullableByDefault => typeSystem.isNonNullableByDefault;
+
   void verify() {
     if (_checkDirectSuperTypes()) {
       return;
@@ -137,9 +135,16 @@
 
     InterfaceTypeImpl type = classElement.thisType;
 
-    // Add all superinterfaces of the direct supertype.
-    if (type.superclass != null) {
-      _addSuperinterfaces(type.superclass);
+    // Compute the interface of the class.
+    var interface = inheritance.getInterface(type);
+
+    // Report conflicts between direct superinterfaces of the class.
+    for (var conflict in interface.conflicts) {
+      _reportInconsistentInheritance(classNameNode, conflict);
+    }
+
+    if (classElement.supertype != null) {
+      directSuperInterfaces.add(classElement.supertype);
     }
 
     // Each mixin in `class C extends S with M0, M1, M2 {}` is equivalent to:
@@ -153,14 +158,11 @@
     var mixinTypes = type.mixins;
     for (var i = 0; i < mixinTypes.length; i++) {
       var mixinType = mixinTypes[i];
-      _checkDeclaredMembers(mixinNodes[i], mixinType);
-      _addSuperinterfaces(mixinType);
+      _checkDeclaredMembers(mixinNodes[i], mixinType, mixinIndex: i);
+      directSuperInterfaces.add(mixinType);
     }
 
-    // Add all superinterfaces of the direct class interfaces.
-    for (var interface in type.interfaces) {
-      _addSuperinterfaces(interface);
-    }
+    directSuperInterfaces.addAll(classElement.interfaces);
 
     // Check the members if the class itself, against all the previously
     // collected superinterfaces of the supertype, mixins, and interfaces.
@@ -178,14 +180,6 @@
       }
     }
 
-    // Compute the interface of the class.
-    var interface = inheritance.getInterface(type);
-
-    // Report conflicts between direct superinterfaces of the class.
-    for (var conflict in interface.conflicts) {
-      _reportInconsistentInheritance(classNameNode, conflict);
-    }
-
     GetterSetterTypesVerifier(
       typeSystem: typeSystem,
       errorReporter: reporter,
@@ -246,26 +240,15 @@
     }
   }
 
-  void _addSuperinterfaces(InterfaceType startingType) {
-    var supertypes = <InterfaceType>[];
-    ClassElementImpl.collectAllSupertypes(supertypes, startingType, null);
-    for (int i = 0; i < supertypes.length; i++) {
-      var supertype = supertypes[i];
-      if (allSupertypes.add(supertype)) {
-        var interface = inheritance.getInterface(supertype);
-        allSuperinterfaces.add(interface);
-      }
-    }
-  }
-
   /// Check that the given [member] is a valid override of the corresponding
-  /// instance members in each of [allSuperinterfaces].  The [libraryUri] is
+  /// instance members in each of [directSuperInterfaces].  The [libraryUri] is
   /// the URI of the library containing the [member].
   void _checkDeclaredMember(
     AstNode node,
     Uri libraryUri,
     ExecutableElement member, {
     List<FormalParameter> methodParameterNodes,
+    int mixinIndex = -1,
   }) {
     if (member == null) return;
     if (member.isStatic) return;
@@ -276,8 +259,12 @@
       thisMember: member,
     );
 
-    for (var superInterface in allSuperinterfaces) {
-      var superMember = superInterface.declared[name];
+    for (var superType in directSuperInterfaces) {
+      var superMember = inheritance.getMember(
+        superType,
+        name,
+        forMixinIndex: mixinIndex,
+      );
       if (superMember == null) {
         continue;
       }
@@ -304,17 +291,25 @@
         );
       }
     }
+
+    if (mixinIndex == -1) {
+      CovariantParametersVerifier(thisMember: member).verify(
+        errorReporter: reporter,
+        errorNode: node,
+      );
+    }
   }
 
   /// Check that instance members of [type] are valid overrides of the
   /// corresponding instance members in each of [allSuperinterfaces].
-  void _checkDeclaredMembers(AstNode node, InterfaceTypeImpl type) {
+  void _checkDeclaredMembers(AstNode node, InterfaceTypeImpl type,
+      {@required int mixinIndex}) {
     var libraryUri = type.element.library.source.uri;
     for (var method in type.methods) {
-      _checkDeclaredMember(node, libraryUri, method);
+      _checkDeclaredMember(node, libraryUri, method, mixinIndex: mixinIndex);
     }
     for (var accessor in type.accessors) {
-      _checkDeclaredMember(node, libraryUri, accessor);
+      _checkDeclaredMember(node, libraryUri, accessor, mixinIndex: mixinIndex);
     }
   }
 
@@ -630,8 +625,6 @@
     }
   }
 
-  bool get _isNonNullableByDefault => typeSystem.isNonNullableByDefault;
-
   void _reportInheritedAbstractMembers(List<ExecutableElement> elements) {
     if (elements == null) {
       return;
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index 98e1df1..ac089e4 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/error/listener.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_schema.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/resolver.dart';
diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
index 1b84b71..94bd973 100644
--- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
+++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
@@ -108,12 +108,21 @@
       }
     } else {
       _useIdentifierElement(node);
+      var enclosingElement = element?.enclosingElement;
       if (element == null) {
         if (isIdentifierRead) {
           usedElements.unresolvedReadMembers.add(node.name);
         }
-      } else if ((element.enclosingElement is ClassElement ||
-              element.enclosingElement is ExtensionElement) &&
+      } else if (enclosingElement is ClassElement &&
+          enclosingElement.isEnum &&
+          element.name == 'values') {
+        // If the 'values' static accessor of the enum is accessed, then all of
+        // the enum values have been read.
+        for (var value in enclosingElement.fields) {
+          usedElements.readMembers.add(value.getter);
+        }
+      } else if ((enclosingElement is ClassElement ||
+              enclosingElement is ExtensionElement) &&
           !identical(element, _enclosingExec)) {
         usedElements.members.add(element);
         if (isIdentifierRead) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 7828dae..efc8d42 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -62,6 +62,7 @@
         TypeParameterImpl;
 import 'package:analyzer/src/fasta/error_converter.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:pub_semver/pub_semver.dart';
 
 const _invalidCollectionElement = _InvalidCollectionElement._();
 
@@ -603,11 +604,15 @@
       reportErrorIfSuper(right);
       push(ast.binaryExpression(left, operatorToken, right));
       if (!enableTripleShift && operatorToken.type == TokenType.GT_GT_GT) {
+        var feature = ExperimentalFeatures.triple_shift;
         handleRecoverableError(
-            templateExperimentNotEnabled
-                .withArguments(EnableString.triple_shift),
-            operatorToken,
-            operatorToken);
+          templateExperimentNotEnabled.withArguments(
+            feature.enableString,
+            _versionAsString(ExperimentStatus.currentVersion),
+          ),
+          operatorToken,
+          operatorToken,
+        );
       }
     }
   }
@@ -699,6 +704,8 @@
       prefixOrName = name.prefix;
       period = name.period;
       nameOrNull = name.identifier;
+    } else if (name is _OperatorName) {
+      prefixOrName = name.name;
     } else {
       throw UnimplementedError(
           'name is an instance of ${name.runtimeType} in endClassConstructor');
@@ -2259,6 +2266,14 @@
   }
 
   @override
+  void beginAsOperatorType(Token asOperator) {}
+
+  @override
+  void endAsOperatorType(Token asOperator) {
+    debugEvent("AsOperatorType");
+  }
+
+  @override
   void handleAsOperator(Token asOperator) {
     assert(optional('as', asOperator));
     debugEvent("AsOperator");
@@ -2282,10 +2297,15 @@
     }
     push(ast.assignmentExpression(lhs, token, rhs));
     if (!enableTripleShift && token.type == TokenType.GT_GT_GT_EQ) {
+      var feature = ExperimentalFeatures.triple_shift;
       handleRecoverableError(
-          templateExperimentNotEnabled.withArguments(EnableString.triple_shift),
-          token,
-          token);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        token,
+        token,
+      );
     }
   }
 
@@ -2817,6 +2837,14 @@
   }
 
   @override
+  void beginIsOperatorType(Token asOperator) {}
+
+  @override
+  void endIsOperatorType(Token asOperator) {
+    debugEvent("IsOperatorType");
+  }
+
+  @override
   void handleIsOperator(Token isOperator, Token not) {
     assert(optional('is', isOperator));
     assert(optionalOrNull('!', not));
@@ -3310,11 +3338,15 @@
       push(ast.spreadElement(
           spreadOperator: spreadToken, expression: expression));
     } else {
+      var feature = Feature.spread_collections;
       handleRecoverableError(
-          templateExperimentNotEnabled
-              .withArguments(EnableString.spread_collections),
-          spreadToken,
-          spreadToken);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(feature.firstSupportedVersion),
+        ),
+        spreadToken,
+        spreadToken,
+      );
       push(_invalidCollectionElement);
     }
   }
@@ -3529,11 +3561,15 @@
         body: entry as CollectionElement,
       ));
     } else {
+      var feature = Feature.control_flow_collections;
       handleRecoverableError(
-          templateExperimentNotEnabled
-              .withArguments(EnableString.control_flow_collections),
-          forToken,
-          forToken);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(feature.firstSupportedVersion),
+        ),
+        forToken,
+        forToken,
+      );
       push(_invalidCollectionElement);
     }
   }
@@ -3558,11 +3594,15 @@
         elseElement: elseElement,
       ));
     } else {
+      var feature = ExperimentalFeatures.control_flow_collections;
       handleRecoverableError(
-          templateExperimentNotEnabled
-              .withArguments(EnableString.control_flow_collections),
-          ifToken,
-          ifToken);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(feature.firstSupportedVersion),
+        ),
+        ifToken,
+        ifToken,
+      );
       push(_invalidCollectionElement);
     }
   }
@@ -3570,10 +3610,15 @@
   void reportErrorIfNullableType(Token questionMark) {
     if (questionMark != null) {
       assert(optional('?', questionMark));
+      var feature = ExperimentalFeatures.non_nullable;
       handleRecoverableError(
-          templateExperimentNotEnabled.withArguments('non-nullable'),
-          questionMark,
-          questionMark);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        questionMark,
+        questionMark,
+      );
     }
   }
 
@@ -3587,16 +3632,28 @@
 
   void reportNonNullableModifierError(Token modifierToken) {
     if (modifierToken != null) {
+      var feature = ExperimentalFeatures.non_nullable;
       handleRecoverableError(
-          templateExperimentNotEnabled.withArguments('non-nullable'),
-          modifierToken,
-          modifierToken);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        modifierToken,
+        modifierToken,
+      );
     }
   }
 
   void reportNonNullAssertExpressionNotEnabled(Token bang) {
+    var feature = ExperimentalFeatures.non_nullable;
     handleRecoverableError(
-        templateExperimentNotEnabled.withArguments('non-nullable'), bang, bang);
+      templateExperimentNotEnabled.withArguments(
+        feature.enableString,
+        _versionAsString(ExperimentStatus.currentVersion),
+      ),
+      bang,
+      bang,
+    );
   }
 
   Comment _findComment(List<Annotation> metadata, Token tokenAfterMetadata) {
@@ -3668,6 +3725,10 @@
       return ParameterKind.REQUIRED;
     }
   }
+
+  static String _versionAsString(Version version) {
+    return '${version.major}.${version.minor}.${version.patch}';
+  }
 }
 
 class _ConstructorNameWithInvalidTypeArgs {
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index cc87d16..22e20e2 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -703,15 +703,6 @@
       return;
     }
     //
-    // The name dynamic denotes a Type object even though dynamic is not a
-    // class.
-    //
-    if (node.name == 'dynamic') {
-      node.staticElement = _dynamicType.element;
-      node.staticType = _typeType;
-      return;
-    }
-    //
     // Otherwise, the node should be resolved.
     //
     Element element = _resolveSimpleIdentifier(node);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index aa2c4e3..785ccbd 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -221,6 +221,7 @@
 
   /// Function that returns `true` if analysis is to parse and analyze function
   /// bodies for a given source.
+  @deprecated
   AnalyzeFunctionBodiesPredicate get analyzeFunctionBodiesPredicate;
 
   /// Return the maximum number of sources for which AST structures should be
@@ -247,6 +248,7 @@
   /// This option should not be used when the analyzer is part of a long running
   /// process (such as the analysis server) because it has the potential to
   /// prevent memory from being reclaimed.
+  @deprecated
   bool get disableCacheFlushing;
 
   /// Return `true` if the parser is to parse asserts in the initializer list of
@@ -281,6 +283,7 @@
 
   /// Return `true` to enable the lazy compound assignment operators '&&=' and
   /// '||='.
+  @deprecated
   bool get enableLazyAssignmentOperators;
 
   /// Return `true` if mixins are allowed to inherit from types other than
@@ -305,10 +308,12 @@
 
   /// Return `true` if errors, warnings and hints should be generated for sources
   /// that are implicitly being analyzed. The default value is `true`.
+  @deprecated
   bool get generateImplicitErrors;
 
   /// Return `true` if errors, warnings and hints should be generated for sources
   /// in the SDK. The default value is `false`.
+  @deprecated
   bool get generateSdkErrors;
 
   /// Return `true` if analysis is to generate hint results (e.g. type inference
@@ -324,9 +329,11 @@
 
   /// A mapping from Dart SDK library name (e.g. "dart:core") to a list of paths
   /// to patch files that should be applied to the library.
+  @deprecated
   Map<String, List<String>> get patchPaths;
 
   /// Return `true` if analysis is to parse comments.
+  @deprecated
   bool get preserveComments;
 
   /// Return `true` if analyzer should enable the use of Dart 2.0 features.
@@ -356,6 +363,7 @@
   /// by analysis cache.  This option should only be set to `false` if analysis
   /// is performed in such a way that none of the inputs is ever changed
   /// during the life time of the context.
+  @deprecated
   bool get trackCacheDependencies;
 
   /// Return `true` if analyzer should use the Dart 2.0 Front End parser.
@@ -365,6 +373,7 @@
   bool isLintEnabled(String name);
 
   /// Reset the state of this set of analysis options to its original state.
+  @deprecated
   void resetToDefaults();
 
   /// Set the values of the cross-context options to match those in the given set
@@ -403,6 +412,7 @@
 
   /// A predicate indicating whether analysis is to parse and analyze function
   /// bodies.
+  @deprecated
   AnalyzeFunctionBodiesPredicate _analyzeFunctionBodiesPredicate =
       _analyzeAllFunctionBodies;
 
@@ -434,6 +444,7 @@
   @override
   List<String> enabledPluginNames = const <String>[];
 
+  @deprecated
   @override
   bool enableLazyAssignmentOperators = false;
 
@@ -447,9 +458,11 @@
   /// A list of exclude patterns used to exclude some sources from analysis.
   List<String> _excludePatterns;
 
+  @deprecated
   @override
   bool generateImplicitErrors = true;
 
+  @deprecated
   @override
   bool generateSdkErrors = false;
 
@@ -463,18 +476,22 @@
   /// `true`.
   List<Linter> _lintRules;
 
+  @deprecated
   @override
   Map<String, List<String>> patchPaths = {};
 
+  @deprecated
   @override
   bool preserveComments = true;
 
+  @deprecated
   @override
   bool trackCacheDependencies = true;
 
   @override
   bool useFastaParser = true;
 
+  @deprecated
   @override
   bool disableCacheFlushing = false;
 
@@ -516,19 +533,24 @@
   /// Initialize a newly created set of analysis options to have the same values
   /// as those in the given set of analysis [options].
   AnalysisOptionsImpl.from(AnalysisOptions options) {
+    // ignore: deprecated_member_use_from_same_package
     analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
     dart2jsHint = options.dart2jsHint;
     contextFeatures = options.contextFeatures;
     enabledPluginNames = options.enabledPluginNames;
+    // ignore: deprecated_member_use_from_same_package
     enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
     enableTiming = options.enableTiming;
     errorProcessors = options.errorProcessors;
     excludePatterns = options.excludePatterns;
+    // ignore: deprecated_member_use_from_same_package
     generateImplicitErrors = options.generateImplicitErrors;
+    // ignore: deprecated_member_use_from_same_package
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
     lint = options.lint;
     lintRules = options.lintRules;
+    // ignore: deprecated_member_use_from_same_package
     preserveComments = options.preserveComments;
     useFastaParser = options.useFastaParser;
     if (options is AnalysisOptionsImpl) {
@@ -537,12 +559,16 @@
       strictInference = options.strictInference;
       strictRawTypes = options.strictRawTypes;
     }
+    // ignore: deprecated_member_use_from_same_package
     trackCacheDependencies = options.trackCacheDependencies;
+    // ignore: deprecated_member_use_from_same_package
     disableCacheFlushing = options.disableCacheFlushing;
+    // ignore: deprecated_member_use_from_same_package
     patchPaths = options.patchPaths;
     sdkVersionConstraint = options.sdkVersionConstraint;
   }
 
+  @deprecated
   bool get analyzeFunctionBodies {
     if (identical(analyzeFunctionBodiesPredicate, _analyzeAllFunctionBodies)) {
       return true;
@@ -554,6 +580,7 @@
     }
   }
 
+  @deprecated
   set analyzeFunctionBodies(bool value) {
     if (value) {
       analyzeFunctionBodiesPredicate = _analyzeAllFunctionBodies;
@@ -562,10 +589,12 @@
     }
   }
 
+  @deprecated
   @override
   AnalyzeFunctionBodiesPredicate get analyzeFunctionBodiesPredicate =>
       _analyzeFunctionBodiesPredicate;
 
+  @deprecated
   set analyzeFunctionBodiesPredicate(AnalyzeFunctionBodiesPredicate value) {
     if (value == null) {
       throw ArgumentError.notNull('analyzeFunctionBodiesPredicate');
@@ -701,6 +730,7 @@
       }
 
       // Append boolean flags.
+      // ignore: deprecated_member_use_from_same_package
       buffer.addBool(enableLazyAssignmentOperators);
       buffer.addBool(implicitCasts);
       buffer.addBool(implicitDynamic);
@@ -755,6 +785,7 @@
       ApiSignature buffer = ApiSignature();
 
       // Append boolean flags.
+      // ignore: deprecated_member_use_from_same_package
       buffer.addBool(enableLazyAssignmentOperators);
       buffer.addBool(useFastaParser);
 
@@ -780,6 +811,7 @@
     return lintRules.any((rule) => rule.name == name);
   }
 
+  @deprecated
   @override
   void resetToDefaults() {
     contextFeatures = ExperimentStatus();
@@ -826,10 +858,12 @@
 
   /// Predicate used for [analyzeFunctionBodiesPredicate] when
   /// [analyzeFunctionBodies] is set to `true`.
+  @deprecated
   static bool _analyzeAllFunctionBodies(Source _) => true;
 
   /// Predicate used for [analyzeFunctionBodiesPredicate] when
   /// [analyzeFunctionBodies] is set to `false`.
+  @deprecated
   static bool _analyzeNoFunctionBodies(Source _) => false;
 }
 
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 3336cd5..dc1011c 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -15,10 +15,11 @@
 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/analysis/session.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/class_hierarchy.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
@@ -38,6 +39,39 @@
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
 import 'package:analyzer/src/task/strong/checker.dart';
 
+class EnclosingExecutableContext {
+  final ExecutableElement element;
+  final bool isAsynchronous;
+  final bool isConstConstructor;
+  final bool isFactoryConstructor;
+  final bool isGenerator;
+  final bool isStaticMethod;
+
+  /// The return statements that have a value.
+  final List<ReturnStatement> _returnsWith = [];
+
+  /// The return statements that do not have a value.
+  final List<ReturnStatement> _returnsWithout = [];
+
+  EnclosingExecutableContext(this.element)
+      : isAsynchronous = element != null && element.isAsynchronous,
+        isConstConstructor = element is ConstructorElement && element.isConst,
+        isFactoryConstructor =
+            element is ConstructorElement && element.isFactory,
+        isGenerator = element != null && element.isGenerator,
+        isStaticMethod = _isStaticMethod(element);
+
+  EnclosingExecutableContext.empty() : this(null);
+
+  static bool _isStaticMethod(ExecutableElement element) {
+    var enclosing = element?.enclosingElement;
+    if (enclosing is ClassElement) {
+      return element.isStatic;
+    }
+    return false;
+  }
+}
+
 /**
  * A visitor used to traverse an AST structure looking for additional errors and
  * warnings not covered by the parser and resolver.
@@ -79,26 +113,6 @@
   final InheritanceManager3 _inheritanceManager;
 
   /**
-   * A flag indicating whether the visitor is currently within a constructor
-   * declaration that is 'const'.
-   *
-   * See [visitConstructorDeclaration].
-   */
-  bool _isEnclosingConstructorConst = false;
-
-  /**
-   * A flag indicating whether we are currently within a function body marked as
-   * being asynchronous.
-   */
-  bool _inAsync = false;
-
-  /**
-   * A flag indicating whether we are currently within a function body marked a
-   *  being a generator.
-   */
-  bool _inGenerator = false;
-
-  /**
    * A flag indicating whether the visitor is currently within a catch clause.
    *
    * See [visitCatchClause].
@@ -110,12 +124,6 @@
    */
   bool _isInComment = false;
 
-  /**
-   * A flag indicating whether the visitor is currently within an instance
-   * creation expression.
-   */
-  bool _isInConstInstanceCreation = false;
-
   /// The stack of flags, where `true` at the top (last) of the stack indicates
   /// that the visitor is in the initializer of a lazy local variable. When the
   /// top is `false`, we might be not in a local variable, or it is not `lazy`,
@@ -153,20 +161,6 @@
   bool _isInFunctionTypedFormalParameter = false;
 
   /**
-   * A flag indicating whether the visitor is currently within a static method.
-   * By "method" here getter, setter and operator declarations are also implied
-   * since they are all represented with a [MethodDeclaration] in the AST
-   * structure.
-   */
-  bool _isInStaticMethod = false;
-
-  /**
-   * A flag indicating whether the visitor is currently within a factory
-   * constructor.
-   */
-  bool _isInFactory = false;
-
-  /**
    * A flag indicating whether the visitor is currently within code in the SDK.
    */
   bool _isInSystemLibrary = false;
@@ -196,22 +190,11 @@
   ExtensionElement _enclosingExtension;
 
   /**
-   * The method or function that we are currently visiting, or `null` if we are
-   * not inside a method or function.
+   * The context of the method or function that we are currently visiting, or
+   * `null` if we are not inside a method or function.
    */
-  ExecutableElement _enclosingFunction;
-
-  /**
-   * The return statements found in the method or function that we are currently
-   * visiting that have a return value.
-   */
-  List<ReturnStatement> _returnsWith = <ReturnStatement>[];
-
-  /**
-   * The return statements found in the method or function that we are currently
-   * visiting that do not have a return value.
-   */
-  List<ReturnStatement> _returnsWithout = <ReturnStatement>[];
+  EnclosingExecutableContext _enclosingExecutable =
+      EnclosingExecutableContext.empty();
 
   /// A table mapping name of the library to the export directive which export
   /// this library.
@@ -238,14 +221,6 @@
 
   final _UninstantiatedBoundChecker _uninstantiatedBoundChecker;
 
-  /// Setting this flag to `true` disables the check for conflicting generics.
-  /// This is used when running with the old task model to work around
-  /// dartbug.com/32421.
-  ///
-  /// TODO(paulberry): remove this flag once dartbug.com/32421 is properly
-  /// fixed.
-  final bool disableConflictingGenericsCheck;
-
   /// The features enabled in the unit currently being checked for errors.
   FeatureSet _featureSet;
 
@@ -258,8 +233,7 @@
    * Initialize a newly created error verifier.
    */
   ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
-      this._typeProvider, this._inheritanceManager, bool enableSuperMixins,
-      {this.disableConflictingGenericsCheck = false})
+      this._typeProvider, this._inheritanceManager, bool enableSuperMixins)
       : _errorReporter = errorReporter,
         _uninstantiatedBoundChecker =
             _UninstantiatedBoundChecker(errorReporter),
@@ -268,11 +242,9 @@
             DuplicateDefinitionVerifier(_currentLibrary, errorReporter) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
-    _isEnclosingConstructorConst = false;
     _isInCatchClause = false;
     _isInStaticVariableDeclaration = false;
     _isInConstructorInitializer = false;
-    _isInStaticMethod = false;
     _intType = _typeProvider.intType;
     _typeSystem = _currentLibrary.typeSystem;
     _options = _currentLibrary.context.analysisOptions;
@@ -305,7 +277,7 @@
     assert(classElement is ClassElementImpl);
     assert(_enclosingClass == null);
     assert(_enclosingEnum == null);
-    assert(_enclosingFunction == null);
+    assert(_enclosingExecutable.element == null);
     _enclosingClass = classElement;
   }
 
@@ -354,10 +326,13 @@
 
   @override
   void visitAwaitExpression(AwaitExpression node) {
-    if (!_inAsync) {
+    if (!_enclosingExecutable.isAsynchronous) {
       _errorReporter.reportErrorForToken(
           CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
     }
+    if (_isNonNullableByDefault) {
+      _checkForUseOfVoidResult(node.expression);
+    }
     _checkForAwaitInLateLocalVariableInitializer(node);
     super.visitAwaitExpression(node);
   }
@@ -399,26 +374,6 @@
   }
 
   @override
-  void visitBlockFunctionBody(BlockFunctionBody node) {
-    bool wasInAsync = _inAsync;
-    bool wasInGenerator = _inGenerator;
-    List<ReturnStatement> previousReturnsWith = _returnsWith;
-    List<ReturnStatement> previousReturnsWithout = _returnsWithout;
-    try {
-      _inAsync = node.isAsynchronous;
-      _inGenerator = node.isGenerator;
-      _returnsWith = <ReturnStatement>[];
-      _returnsWithout = <ReturnStatement>[];
-      super.visitBlockFunctionBody(node);
-    } finally {
-      _inAsync = wasInAsync;
-      _inGenerator = wasInGenerator;
-      _returnsWith = previousReturnsWith;
-      _returnsWithout = previousReturnsWithout;
-    }
-  }
-
-  @override
   void visitBreakStatement(BreakStatement node) {
     SimpleIdentifier labelNode = node.label;
     if (labelNode != null) {
@@ -437,7 +392,6 @@
     try {
       _isInCatchClause = true;
       _checkForTypeAnnotationDeferredClass(node.exceptionType);
-      _checkForNullableTypeInCatchClause(node.exceptionType);
       super.visitCatchClause(node);
     } finally {
       _isInCatchClause = previousIsInCatchClause;
@@ -517,31 +471,23 @@
 
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    ExecutableElement outerFunction = _enclosingFunction;
-    try {
-      ConstructorElement constructorElement = node.declaredElement;
-      _enclosingFunction = constructorElement;
-      _isEnclosingConstructorConst = node.constKeyword != null;
-      _isInFactory = node.factoryKeyword != null;
+    ConstructorElement element = node.declaredElement;
+    _withEnclosingExecutable(element, () {
       _checkForInvalidModifierOnBody(
           node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR);
-      _checkForConstConstructorWithNonFinalField(node, constructorElement);
+      _checkForConstConstructorWithNonFinalField(node, element);
       _checkForConstConstructorWithNonConstSuper(node);
       _constructorFieldsVerifier.verify(node);
       _checkForRedirectingConstructorErrorCodes(node);
       _checkForMultipleSuperInitializers(node);
-      _checkForRecursiveConstructorRedirect(node, constructorElement);
-      if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) {
+      _checkForRecursiveConstructorRedirect(node, element);
+      if (!_checkForRecursiveFactoryRedirect(node, element)) {
         _checkForAllRedirectConstructorErrorCodes(node);
       }
       _checkForUndefinedConstructorInInitializerImplicit(node);
       _checkForReturnInGenerativeConstructor(node);
       super.visitConstructorDeclaration(node);
-    } finally {
-      _isEnclosingConstructorConst = false;
-      _isInFactory = false;
-      _enclosingFunction = outerFunction;
-    }
+    });
   }
 
   @override
@@ -607,28 +553,19 @@
 
   @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    bool wasInAsync = _inAsync;
-    bool wasInGenerator = _inGenerator;
-    try {
-      _inAsync = node.isAsynchronous;
-      _inGenerator = node.isGenerator;
-      FunctionType functionType = _enclosingFunction?.type;
-      DartType expectedReturnType = functionType == null
-          ? DynamicTypeImpl.instance
-          : functionType.returnType;
-      ExecutableElement function = _enclosingFunction;
-      bool isSetterWithImplicitReturn = function.hasImplicitReturnType &&
-          function is PropertyAccessorElement &&
-          function.isSetter;
-      if (!isSetterWithImplicitReturn) {
-        _checkForReturnOfInvalidType(node.expression, expectedReturnType,
-            isArrowFunction: true);
-      }
-      super.visitExpressionFunctionBody(node);
-    } finally {
-      _inAsync = wasInAsync;
-      _inGenerator = wasInGenerator;
+    ExecutableElement function = _enclosingExecutable.element;
+    FunctionType functionType = function?.type;
+    DartType expectedReturnType = functionType == null
+        ? DynamicTypeImpl.instance
+        : functionType.returnType;
+    bool isSetterWithImplicitReturn = function.hasImplicitReturnType &&
+        function is PropertyAccessorElement &&
+        function.isSetter;
+    if (!isSetterWithImplicitReturn) {
+      _checkForReturnOfInvalidType(node.expression, expectedReturnType,
+          isArrowFunction: true);
     }
+    super.visitExpressionFunctionBody(node);
   }
 
   @override
@@ -736,10 +673,9 @@
         functionElement.enclosingElement is! CompilationUnitElement) {
       _hiddenElements.declare(functionElement);
     }
-    ExecutableElement outerFunction = _enclosingFunction;
-    try {
+
+    _withEnclosingExecutable(functionElement, () {
       SimpleIdentifier identifier = node.name;
-      _enclosingFunction = functionElement;
       TypeAnnotation returnType = node.returnType;
       if (node.isGetter) {
         GetterSetterTypesVerifier(
@@ -761,27 +697,21 @@
       _checkForIllegalReturnType(returnType);
       _checkForImplicitDynamicReturn(node.name, node.declaredElement);
       super.visitFunctionDeclaration(node);
-    } finally {
-      _enclosingFunction = outerFunction;
-    }
+    });
   }
 
   @override
   void visitFunctionExpression(FunctionExpression node) {
     _isInLateLocalVariable.add(false);
-    // If this function expression is wrapped in a function declaration, don't
-    // change the enclosingFunction field.
+
     if (node.parent is! FunctionDeclaration) {
-      ExecutableElement outerFunction = _enclosingFunction;
-      try {
-        _enclosingFunction = node.declaredElement;
+      _withEnclosingExecutable(node.declaredElement, () {
         super.visitFunctionExpression(node);
-      } finally {
-        _enclosingFunction = outerFunction;
-      }
+      });
     } else {
       super.visitFunctionExpression(node);
     }
+
     _isInLateLocalVariable.removeLast();
   }
 
@@ -886,32 +816,25 @@
 
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    bool wasInConstInstanceCreation = _isInConstInstanceCreation;
-    _isInConstInstanceCreation = node.isConst;
-    try {
-      ConstructorName constructorName = node.constructorName;
-      TypeName typeName = constructorName.type;
-      DartType type = typeName.type;
-      if (type is InterfaceType) {
-        _checkForConstOrNewWithAbstractClass(node, typeName, type);
-        _checkForConstOrNewWithEnum(node, typeName, type);
-        _checkForConstOrNewWithMixin(node, typeName, type);
-        _requiredParametersVerifier.visitInstanceCreationExpression(node);
-        if (_isInConstInstanceCreation) {
-          _checkForConstWithNonConst(node);
-          _checkForConstWithUndefinedConstructor(
-              node, constructorName, typeName);
-          _checkForConstDeferredClass(node, constructorName, typeName);
-        } else {
-          _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
-        }
-        _checkForListConstructor(node, type);
+    ConstructorName constructorName = node.constructorName;
+    TypeName typeName = constructorName.type;
+    DartType type = typeName.type;
+    if (type is InterfaceType) {
+      _checkForConstOrNewWithAbstractClass(node, typeName, type);
+      _checkForConstOrNewWithEnum(node, typeName, type);
+      _checkForConstOrNewWithMixin(node, typeName, type);
+      _requiredParametersVerifier.visitInstanceCreationExpression(node);
+      if (node.isConst) {
+        _checkForConstWithNonConst(node);
+        _checkForConstWithUndefinedConstructor(node, constructorName, typeName);
+        _checkForConstDeferredClass(node, constructorName, typeName);
+      } else {
+        _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
       }
-      _checkForImplicitDynamicType(typeName);
-      super.visitInstanceCreationExpression(node);
-    } finally {
-      _isInConstInstanceCreation = wasInConstInstanceCreation;
+      _checkForListConstructor(node, type);
     }
+    _checkForImplicitDynamicType(typeName);
+    super.visitInstanceCreationExpression(node);
   }
 
   @override
@@ -943,10 +866,7 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    ExecutableElement previousFunction = _enclosingFunction;
-    try {
-      _isInStaticMethod = node.isStatic;
-      _enclosingFunction = node.declaredElement;
+    _withEnclosingExecutable(node.declaredElement, () {
       TypeAnnotation returnType = node.returnType;
       if (node.isStatic && node.isGetter) {
         GetterSetterTypesVerifier(
@@ -971,10 +891,7 @@
       _checkForMustCallSuper(node);
       _checkForWrongTypeParameterVarianceInMethod(node);
       super.visitMethodDeclaration(node);
-    } finally {
-      _enclosingFunction = previousFunction;
-      _isInStaticMethod = false;
-    }
+    });
   }
 
   @override
@@ -1113,9 +1030,9 @@
   @override
   void visitReturnStatement(ReturnStatement node) {
     if (node.expression == null) {
-      _returnsWithout.add(node);
+      _enclosingExecutable._returnsWithout.add(node);
     } else {
-      _returnsWith.add(node);
+      _enclosingExecutable._returnsWith.add(node);
     }
     _checkForAllReturnStatementErrorCodes(node);
     super.visitReturnStatement(node);
@@ -1212,6 +1129,7 @@
   void visitThrowExpression(ThrowExpression node) {
     _checkForConstEvalThrowsException(node);
     _checkForUseOfVoidResult(node.expression);
+    _checkForThrowOfInvalidType(node);
     super.visitThrowExpression(node);
   }
 
@@ -1332,9 +1250,7 @@
       _checkImplementsSuperClass(implementsClause);
       _checkMixinInference(node, withClause);
       _checkForMixinWithConflictingPrivateMember(withClause, superclass);
-      if (!disableConflictingGenericsCheck) {
-        _checkForConflictingGenerics(node);
-      }
+      _checkForConflictingGenerics(node);
     }
   }
 
@@ -1365,11 +1281,12 @@
    */
   void _checkForAllEmptyReturnStatementErrorCodes(
       ReturnStatement statement, DartType expectedReturnType) {
-    if (_inGenerator) {
+    if (_enclosingExecutable.isGenerator) {
       return;
     }
-    var returnType =
-        _inAsync ? _typeSystem.flatten(expectedReturnType) : expectedReturnType;
+    var returnType = _enclosingExecutable.isAsynchronous
+        ? _typeSystem.flatten(expectedReturnType)
+        : expectedReturnType;
     if (returnType.isDynamic ||
         returnType.isDartCoreNull ||
         returnType.isVoid) {
@@ -1504,7 +1421,7 @@
    * the enclosing method or function.
    */
   void _checkForAllReturnStatementErrorCodes(ReturnStatement statement) {
-    FunctionType functionType = _enclosingFunction?.type;
+    FunctionType functionType = _enclosingExecutable.element.type;
     DartType expectedReturnType = functionType == null
         ? DynamicTypeImpl.instance
         : functionType.returnType;
@@ -1513,7 +1430,7 @@
     // RETURN_IN_GENERATIVE_CONSTRUCTOR
     bool isGenerativeConstructor(ExecutableElement element) =>
         element is ConstructorElement && !element.isFactory;
-    if (isGenerativeConstructor(_enclosingFunction)) {
+    if (isGenerativeConstructor(_enclosingExecutable.element)) {
       if (returnExpression == null) {
         return;
       }
@@ -1526,12 +1443,12 @@
     if (returnExpression == null) {
       _checkForAllEmptyReturnStatementErrorCodes(statement, expectedReturnType);
       return;
-    } else if (_inGenerator) {
+    } else if (_enclosingExecutable.isGenerator) {
       // RETURN_IN_GENERATOR
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.RETURN_IN_GENERATOR,
           statement,
-          [_inAsync ? "async*" : "sync*"]);
+          [_enclosingExecutable.isAsynchronous ? "async*" : "sync*"]);
       return;
     }
 
@@ -1957,58 +1874,26 @@
   }
 
   void _checkForConflictingGenerics(NamedCompilationUnitMember node) {
-    var visitedClasses = <ClassElement>[];
-    var interfaces = <ClassElement, InterfaceType>{};
+    var element = node.declaredElement as ClassElement;
 
-    void visit(InterfaceType type) {
-      if (type == null) return;
+    var analysisSession = _currentLibrary.session as AnalysisSessionImpl;
+    var errors = analysisSession.classHierarchy.errors(element);
 
-      var element = type.element;
-      if (visitedClasses.contains(element)) return;
-      visitedClasses.add(element);
-
-      if (element.typeParameters.isNotEmpty) {
-        if (_typeSystem.isNonNullableByDefault) {
-          type = _typeSystem.normalize(type);
-          var oldType = interfaces[element];
-          if (oldType == null) {
-            interfaces[element] = type;
-          } else {
-            try {
-              var result = _typeSystem.topMerge(oldType, type);
-              interfaces[element] = result;
-            } catch (_) {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
-                node,
-                [_enclosingClass.name, oldType, type],
-              );
-            }
-          }
-        } else {
-          type = _toLegacyType(type);
-          var oldType = interfaces[element];
-          if (oldType == null) {
-            interfaces[element] = type;
-          } else if (type != oldType) {
-            _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
-              node,
-              [_enclosingClass.name, oldType, type],
-            );
-          }
-        }
+    for (var error in errors) {
+      if (error is IncompatibleInterfacesClassHierarchyError) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
+          node,
+          [
+            _enclosingClass.name,
+            error.first.getDisplayString(withNullability: true),
+            error.second.getDisplayString(withNullability: true),
+          ],
+        );
+      } else {
+        throw UnimplementedError('${error.runtimeType}');
       }
-
-      visit(type.superclass);
-      type.mixins.forEach(visit);
-      type.superclassConstraints.forEach(visit);
-      type.interfaces.forEach(visit);
-
-      visitedClasses.removeLast();
     }
-
-    visit(_enclosingClass.thisType);
   }
 
   /**
@@ -2048,7 +1933,7 @@
    */
   void _checkForConstConstructorWithNonConstSuper(
       ConstructorDeclaration constructor) {
-    if (!_isEnclosingConstructorConst) {
+    if (!_enclosingExecutable.isConstConstructor) {
       return;
     }
     // OK, const factory, checked elsewhere
@@ -2118,7 +2003,7 @@
   void _checkForConstConstructorWithNonFinalField(
       ConstructorDeclaration constructor,
       ConstructorElement constructorElement) {
-    if (!_isEnclosingConstructorConst) {
+    if (!_enclosingExecutable.isConstConstructor) {
       return;
     }
     // check if there is non-final field
@@ -2160,7 +2045,7 @@
    * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION].
    */
   void _checkForConstEvalThrowsException(ThrowExpression expression) {
-    if (_isEnclosingConstructorConst) {
+    if (_enclosingExecutable.isConstConstructor) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression);
     }
@@ -2554,6 +2439,10 @@
         NamespaceBuilder().createExportNamespaceForDirective(element);
 
     for (var element in namespace.definedNames.values) {
+      if (element == DynamicElementImpl.instance ||
+          element == NeverElementImpl.instance) {
+        continue;
+      }
       if (!element.library.isNonNullableByDefault) {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.EXPORT_LEGACY_SYMBOL,
@@ -2683,7 +2572,7 @@
       return;
     }
     // report problem
-    if (_isEnclosingConstructorConst) {
+    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(
@@ -2845,8 +2734,8 @@
       // assignable to everything.
       return;
     }
-    if (_enclosingFunction.isAsynchronous) {
-      if (_enclosingFunction.isGenerator) {
+    if (_enclosingExecutable.isAsynchronous) {
+      if (_enclosingExecutable.isGenerator) {
         _checkForIllegalReturnTypeCode(
           returnType,
           _typeProvider.streamElement,
@@ -2859,7 +2748,7 @@
           StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
         );
       }
-    } else if (_enclosingFunction.isGenerator) {
+    } else if (_enclosingExecutable.isGenerator) {
       _checkForIllegalReturnTypeCode(
         returnType,
         _typeProvider.iterableElement,
@@ -2872,35 +2761,12 @@
    * If the current function is async, async*, or sync*, verify that its
    * declared return type is assignable to Future, Stream, or Iterable,
    * respectively. This is called by [_checkForIllegalReturnType] to check if
-   * the declared [returnTypeName] is assignable to the required [expectedType]
-   * and if not report [errorCode].
+   * a value with the type of the declared [returnTypeName] is assignable to
+   * [expectedElement] and if not report [errorCode].
    */
   void _checkForIllegalReturnTypeCode(TypeAnnotation returnTypeName,
       ClassElement expectedElement, StaticTypeWarningCode errorCode) {
-    DartType returnType = _enclosingFunction.returnType;
-    //
-    // When checking an async/sync*/async* method, we know the exact type
-    // that will be returned (e.g. Future, Iterable, or Stream).
-    //
-    // For example an `async` function body will return a `Future<T>` for
-    // some `T` (possibly `dynamic`).
-    //
-    // We allow the declared return type to be a supertype of that
-    // (e.g. `dynamic`, `Object`), or Future<S> for some S.
-    // (We assume the T <: S relation is checked elsewhere.)
-    //
-    // We do not allow user-defined subtypes of Future, because an `async`
-    // method will never return those.
-    //
-    // To check for this, we ensure that `Future<bottom> <: returnType`.
-    //
-    // Similar logic applies for sync* and async*.
-    //
-    var lowerBound = expectedElement.instantiate(
-      typeArguments: [NeverTypeImpl.instance],
-      nullabilitySuffix: NullabilitySuffix.star,
-    );
-    if (!_typeSystem.isSubtypeOf2(lowerBound, returnType)) {
+    if (!_isLegalReturnType(expectedElement)) {
       _errorReporter.reportErrorForNode(errorCode, returnTypeName);
     }
   }
@@ -2994,8 +2860,8 @@
       return;
     }
     if (!_isInConstructorInitializer &&
-        !_isInStaticMethod &&
-        !_isInFactory &&
+        !_enclosingExecutable.isStaticMethod &&
+        !_enclosingExecutable.isFactoryConstructor &&
         !_isInInstanceNotLateVariableDeclaration &&
         !_isInStaticVariableDeclaration) {
       return;
@@ -3036,10 +2902,10 @@
       }
     }
 
-    if (_isInStaticMethod) {
+    if (_enclosingExecutable.isStaticMethod) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
-    } else if (_isInFactory) {
+    } else if (_enclosingExecutable.isFactoryConstructor) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
     } else {
@@ -3204,7 +3070,12 @@
       return;
     }
 
-    if (identical(lhs.staticType, NeverTypeImpl.instance)) {
+    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;
     }
 
@@ -3939,23 +3810,6 @@
     }
   }
 
-  void _checkForNullableTypeInCatchClause(TypeAnnotation type) {
-    if (!_isNonNullableByDefault) {
-      return;
-    }
-
-    if (type == null) {
-      return;
-    }
-
-    if (_typeSystem.isPotentiallyNullable(type.type)) {
-      _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
-        type,
-      );
-    }
-  }
-
   /**
    * Verify that all classes of the given [onClause] are valid.
    *
@@ -4163,6 +4017,21 @@
         redirectedConstructor.staticElement,
         redirectedConstructor,
       );
+      var redirectedClass =
+          redirectedConstructor.staticElement?.enclosingElement;
+      if (redirectedClass is ClassElement &&
+          redirectedClass.isAbstract &&
+          !redirectedConstructor.staticElement.isFactory) {
+        String enclosingTypeName = _enclosingClass.displayName;
+        String constructorStrName = enclosingTypeName;
+        if (declaration.name != null) {
+          constructorStrName += ".${declaration.name.name}";
+        }
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
+            redirectedConstructor,
+            [constructorStrName, redirectedClass.name]);
+      }
     }
     // check if there are redirected invocations
     int numRedirections = 0;
@@ -4329,10 +4198,10 @@
   void _checkForReturnOfInvalidType(
       Expression returnExpression, DartType expectedType,
       {bool isArrowFunction = false}) {
-    if (_enclosingFunction == null) {
+    if (_enclosingExecutable == null) {
       return;
     }
-    if (_inGenerator) {
+    if (_enclosingExecutable.isGenerator) {
       // "return expression;" is disallowed in generators, but this is checked
       // elsewhere.  Bare "return" is always allowed in generators regardless
       // of the return type.  So no need to do any further checking.
@@ -4346,20 +4215,27 @@
 
     var toType = expectedType;
     var fromType = expressionType;
-    if (_inAsync) {
+    if (_enclosingExecutable.isAsynchronous) {
       toType = _typeSystem.flatten(toType);
       fromType = _typeSystem.flatten(fromType);
+      if (!_isLegalReturnType(_typeProvider.futureElement)) {
+        // ILLEGAL_ASYNC_RETURN_TYPE has already been reported, meaning the
+        // _declared_ return type is illegal; don't confuse by also reporting
+        // that the type being returned here does not match that illegal return
+        // type.
+        return;
+      }
     }
 
     void reportTypeError() {
-      String displayName = _enclosingFunction.displayName;
+      String displayName = _enclosingExecutable.element.displayName;
 
       if (displayName.isEmpty) {
         _errorReporter.reportErrorForNode(
             StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_CLOSURE,
             returnExpression,
             [fromType, toType]);
-      } else if (_enclosingFunction is MethodElement) {
+      } else if (_enclosingExecutable.element is MethodElement) {
         _errorReporter.reportErrorForNode(
             StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_METHOD,
             returnExpression,
@@ -4391,8 +4267,9 @@
       }
     }
     if (!expectedType.isVoid && !fromType.isVoid) {
-      var checkWithType =
-          !_inAsync ? fromType : _typeProvider.futureType2(fromType);
+      var checkWithType = !_enclosingExecutable.isAsynchronous
+          ? fromType
+          : _typeProvider.futureType2(fromType);
       if (_typeSystem.isAssignableTo2(checkWithType, expectedType)) {
         return;
       }
@@ -4511,6 +4388,21 @@
     }
   }
 
+  void _checkForThrowOfInvalidType(ThrowExpression node) {
+    if (!_isNonNullableByDefault) return;
+
+    var expression = node.expression;
+    var type = node.expression.staticType;
+
+    if (!_typeSystem.isAssignableTo2(type, _typeSystem.objectNone)) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.THROW_OF_INVALID_TYPE,
+        expression,
+        [type],
+      );
+    }
+  }
+
   /**
    * Verify that the given [element] does not reference itself directly.
    * If it does, report the error on the [node].
@@ -4580,7 +4472,7 @@
   }
 
   void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
-    if (_isInStaticMethod || _isInStaticVariableDeclaration) {
+    if (_enclosingExecutable.isStaticMethod || _isInStaticVariableDeclaration) {
       var element = identifier.staticElement;
       if (element is TypeParameterElement &&
           element.enclosingElement is ClassElement) {
@@ -5190,9 +5082,7 @@
         implementsClause?.interfaces,
         CompileTimeErrorCode.IMPLEMENTS_REPEATED,
       );
-      if (!disableConflictingGenericsCheck) {
-        _checkForConflictingGenerics(node);
-      }
+      _checkForConflictingGenerics(node);
     }
   }
 
@@ -5229,12 +5119,13 @@
     if (!_isNonNullableByDefault) return;
 
     var parent = node.parent;
-    var defaultValuesAreExpected = parent is ConstructorDeclaration ||
-        parent is FunctionExpression ||
-        parent is MethodDeclaration &&
-            !parent.isAbstract &&
-            parent.externalKeyword == null &&
-            parent.body is! NativeFunctionBody;
+    var defaultValuesAreExpected =
+        parent is ConstructorDeclaration && parent.externalKeyword == null ||
+            parent is FunctionExpression ||
+            parent is MethodDeclaration &&
+                !parent.isAbstract &&
+                parent.externalKeyword == null &&
+                parent.body is! NativeFunctionBody;
 
     for (var parameter in node.parameters) {
       if (parameter is DefaultFormalParameter) {
@@ -5482,6 +5373,35 @@
     return false;
   }
 
+  /// Returns whether a value with the type of the the enclosing function's
+  /// declared return type is assignable to [expectedElement].
+  bool _isLegalReturnType(ClassElement expectedElement) {
+    DartType returnType = _enclosingExecutable.element.returnType;
+    //
+    // When checking an async/sync*/async* method, we know the exact type
+    // that will be returned (e.g. Future, Iterable, or Stream).
+    //
+    // For example an `async` function body will return a `Future<T>` for
+    // some `T` (possibly `dynamic`).
+    //
+    // We allow the declared return type to be a supertype of that
+    // (e.g. `dynamic`, `Object`), or Future<S> for some S.
+    // (We assume the T <: S relation is checked elsewhere.)
+    //
+    // We do not allow user-defined subtypes of Future, because an `async`
+    // method will never return those.
+    //
+    // To check for this, we ensure that `Future<bottom> <: returnType`.
+    //
+    // Similar logic applies for sync* and async*.
+    //
+    var lowerBound = expectedElement.instantiate(
+      typeArguments: [NeverTypeImpl.instance],
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+    return _typeSystem.isSubtypeOf2(lowerBound, returnType);
+  }
+
   /**
    * Return `true` if the given 'this' [expression] is in a valid context.
    */
@@ -5552,11 +5472,17 @@
     return null;
   }
 
-  /// If in a legacy library, return the legacy version of the [type].
-  /// Otherwise, return the original type.
-  DartType _toLegacyType(DartType type) {
-    if (_isNonNullableByDefault) return type;
-    return NullabilityEliminator.perform(_typeProvider, type);
+  void _withEnclosingExecutable(
+    ExecutableElement element,
+    void Function() operation,
+  ) {
+    var current = _enclosingExecutable;
+    try {
+      _enclosingExecutable = EnclosingExecutableContext(element);
+      operation();
+    } finally {
+      _enclosingExecutable = current;
+    }
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3c731ff..ea4d2dd 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -38,6 +38,7 @@
 import 'package:analyzer/src/dart/resolver/yield_statement_resolver.dart';
 import 'package:analyzer/src/error/bool_expression_verifier.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/error/dead_code_verifier.dart';
 import 'package:analyzer/src/error/nullable_dereference_verifier.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
@@ -126,13 +127,15 @@
     if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) {
       // If NNBD, and the function body end is reachable, infer nullable.
       // If legacy, we consider the end as always reachable, and return Null.
-      if (_resolver._isNonNullableByDefault) {
-        var flow = _resolver._flowAnalysis?.flow;
-        if (flow != null && flow.isReachable) {
+      if (!node.isGenerator) {
+        if (_resolver._isNonNullableByDefault) {
+          var flow = _resolver._flowAnalysis?.flow;
+          if (flow != null && flow.isReachable) {
+            addReturnOrYieldType(_typeProvider.nullType);
+          }
+        } else {
           addReturnOrYieldType(_typeProvider.nullType);
         }
-      } else {
-        addReturnOrYieldType(_typeProvider.nullType);
       }
 
       DartType context = _returnStack.removeLast();
@@ -220,6 +223,8 @@
   PrefixExpressionResolver _prefixExpressionResolver;
   YieldStatementResolver _yieldStatementResolver;
 
+  NullSafetyDeadCodeVerifier nullSafetyDeadCodeVerifier;
+
   InvocationInferenceHelper inferenceHelper;
 
   /// The object used to resolve the element associated with the current node.
@@ -386,6 +391,11 @@
     this._yieldStatementResolver = YieldStatementResolver(
       resolver: this,
     );
+    this.nullSafetyDeadCodeVerifier = NullSafetyDeadCodeVerifier(
+      typeSystem,
+      errorReporter,
+      _flowAnalysis,
+    );
     this.elementResolver = ElementResolver(this,
         reportConstEvaluationErrors: reportConstEvaluationErrors,
         migratableAstInfoProvider: _migratableAstInfoProvider);
@@ -429,6 +439,10 @@
   bool get _isNonNullableByDefault =>
       _featureSet.isEnabled(Feature.non_nullable);
 
+  void checkUnreachableNode(AstNode node) {
+    nullSafetyDeadCodeVerifier.visitNode(node);
+  }
+
   /// Return the static element associated with the given expression whose type
   /// can be overridden, or `null` if there is no element whose type can be
   /// overridden.
@@ -503,7 +517,9 @@
         _unfinishedNullShorts.removeLast();
         _flowAnalysis.flow.nullAwareAccess_end();
       } while (identical(_unfinishedNullShorts.last, node));
-      node.staticType = typeSystem.makeNullable(node.staticType);
+      if (node is! CascadeExpression) {
+        node.staticType = typeSystem.makeNullable(node.staticType);
+      }
     }
   }
 
@@ -817,9 +833,10 @@
     if (_flowAnalysis != null) {
       if (flow != null) {
         flow.conditional_thenBegin(condition);
-        _flowAnalysis.checkUnreachableNode(thenExpression);
+        checkUnreachableNode(thenExpression);
       }
       thenExpression.accept(this);
+      nullSafetyDeadCodeVerifier?.flowEnd(thenExpression);
     } else {
       _promoteManager.visitConditionalExpression_then(
         condition,
@@ -835,9 +852,10 @@
 
     if (flow != null) {
       flow.conditional_elseBegin(thenExpression);
-      _flowAnalysis.checkUnreachableNode(elseExpression);
+      checkUnreachableNode(elseExpression);
       elseExpression.accept(this);
       flow.conditional_end(node, elseExpression);
+      nullSafetyDeadCodeVerifier?.flowEnd(elseExpression);
     } else {
       elseExpression.accept(this);
     }
@@ -937,7 +955,7 @@
 
   @override
   void visitDoStatementInScope(DoStatement node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
 
     var body = node.body;
     var condition = node.condition;
@@ -1059,6 +1077,7 @@
   @override
   void visitForStatementInScope(ForStatement node) {
     _forResolver.resolveStatement(node);
+    nullSafetyDeadCodeVerifier?.flowEnd(node.body);
   }
 
   @override
@@ -1108,6 +1127,7 @@
       } else {
         _flowAnalysis.topLevelDeclaration_exit();
       }
+      nullSafetyDeadCodeVerifier?.flowEnd(node);
     } else {
       _promoteManager.exitFunctionBody();
     }
@@ -1161,6 +1181,7 @@
           errorNode: body,
         );
         _flowAnalysis.flow?.functionExpression_end();
+        nullSafetyDeadCodeVerifier?.flowEnd(node);
       }
     } else {
       _promoteManager.exitFunctionBody();
@@ -1243,7 +1264,7 @@
 
   @override
   void visitIfStatement(IfStatement node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
 
     Expression condition = node.condition;
 
@@ -1258,6 +1279,7 @@
     if (_flowAnalysis != null) {
       _flowAnalysis.flow.ifStatement_thenBegin(condition);
       visitStatementInScope(thenStatement);
+      nullSafetyDeadCodeVerifier?.flowEnd(thenStatement);
     } else {
       _promoteManager.visitIfStatement_thenStatement(
         condition,
@@ -1272,6 +1294,7 @@
     if (elseStatement != null) {
       _flowAnalysis?.flow?.ifStatement_elseBegin();
       visitStatementInScope(elseStatement);
+      nullSafetyDeadCodeVerifier?.flowEnd(elseStatement);
     }
 
     _flowAnalysis?.flow?.ifStatement_end(elseStatement != null);
@@ -1320,11 +1343,18 @@
   void visitLabel(Label node) {}
 
   @override
+  void visitLabeledStatement(LabeledStatement node) {
+    _flowAnalysis?.labeledStatement_enter(node);
+    super.visitLabeledStatement(node);
+    _flowAnalysis?.labeledStatement_exit(node);
+  }
+
+  @override
   void visitLibraryIdentifier(LibraryIdentifier node) {}
 
   @override
   void visitListLiteral(ListLiteral node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
     _typedLiteralResolver.resolveListLiteral(node);
   }
 
@@ -1355,6 +1385,7 @@
       );
       _flowAnalysis.executableDeclaration_exit(node.body, false);
       _flowAnalysis.topLevelDeclaration_exit();
+      nullSafetyDeadCodeVerifier?.flowEnd(node);
     } else {
       _promoteManager.exitFunctionBody();
     }
@@ -1419,7 +1450,7 @@
 
   @override
   void visitNode(AstNode node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
     node.visitChildren(this);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -1513,7 +1544,7 @@
 
   @override
   void visitSetOrMapLiteral(SetOrMapLiteral node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
     _typedLiteralResolver.resolveSetOrMapLiteral(node);
   }
 
@@ -1571,7 +1602,7 @@
 
   @override
   void visitSwitchCase(SwitchCase node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
 
     InferenceContext.setType(
         node.expression, _enclosingSwitchStatementExpressionType);
@@ -1587,11 +1618,19 @@
         );
       }
     }
+
+    nullSafetyDeadCodeVerifier?.flowEnd(node);
+  }
+
+  @override
+  void visitSwitchDefault(SwitchDefault node) {
+    super.visitSwitchDefault(node);
+    nullSafetyDeadCodeVerifier?.flowEnd(node);
   }
 
   @override
   void visitSwitchStatementInScope(SwitchStatement node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
 
     var previousExpressionType = _enclosingSwitchStatementExpressionType;
     try {
@@ -1628,7 +1667,6 @@
   @override
   void visitThrowExpression(ThrowExpression node) {
     super.visitThrowExpression(node);
-    nullableDereferenceVerifier.expression(node.expression);
     _flowAnalysis?.flow?.handleExit();
   }
 
@@ -1638,7 +1676,7 @@
       return super.visitTryStatement(node);
     }
 
-    _flowAnalysis.checkUnreachableNode(node);
+    checkUnreachableNode(node);
     var flow = _flowAnalysis.flow;
 
     var body = node.body;
@@ -1655,18 +1693,24 @@
     body.accept(this);
     if (catchClauses.isNotEmpty) {
       flow.tryCatchStatement_bodyEnd(body);
+      nullSafetyDeadCodeVerifier?.flowEnd(node.body);
+      nullSafetyDeadCodeVerifier.tryStatementEnter(node);
 
       var catchLength = catchClauses.length;
       for (var i = 0; i < catchLength; ++i) {
         var catchClause = catchClauses[i];
+        nullSafetyDeadCodeVerifier.verifyCatchClause(catchClause);
         flow.tryCatchStatement_catchBegin(
-            catchClause.exceptionParameter?.staticElement,
-            catchClause.stackTraceParameter?.staticElement);
+          catchClause.exceptionParameter?.staticElement,
+          catchClause.stackTraceParameter?.staticElement,
+        );
         catchClause.accept(this);
         flow.tryCatchStatement_catchEnd();
+        nullSafetyDeadCodeVerifier?.flowEnd(catchClause.body);
       }
 
       flow.tryCatchStatement_end();
+      nullSafetyDeadCodeVerifier.tryStatementExit(node);
     }
 
     if (finallyBlock != null) {
@@ -1720,7 +1764,7 @@
 
   @override
   void visitWhileStatement(WhileStatement node) {
-    _flowAnalysis?.checkUnreachableNode(node);
+    checkUnreachableNode(node);
 
     // Note: since we don't call the base class, we have to maintain
     // _implicitLabelScope ourselves.
@@ -1741,6 +1785,7 @@
         _flowAnalysis?.flow?.whileStatement_bodyBegin(node, condition);
         visitStatementInScope(body);
         _flowAnalysis?.flow?.whileStatement_end();
+        nullSafetyDeadCodeVerifier?.flowEnd(node.body);
       }
     } finally {
       _implicitLabelScope = outerImplicitScope;
@@ -2048,6 +2093,21 @@
             migrationResolutionHooks);
 
   @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    var conditionalKnownValue =
+        _migrationResolutionHooks.getConditionalKnownValue(node);
+    if (conditionalKnownValue == null) {
+      super.visitConditionalExpression(node);
+      return;
+    } else {
+      var subexpressionToKeep =
+          conditionalKnownValue ? node.thenExpression : node.elseExpression;
+      subexpressionToKeep.accept(this);
+      typeAnalyzer.recordStaticType(node, subexpressionToKeep.staticType);
+    }
+  }
+
+  @override
   void visitIfElement(IfElement node) {
     var conditionalKnownValue =
         _migrationResolutionHooks.getConditionalKnownValue(node);
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index b47e5e3..71e150d 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -174,12 +174,34 @@
   }
 
   /**
+   * Record that the static type of the given node is the given type.
+   *
+   * @param expression the node whose type is to be recorded
+   * @param type the static type of the node
+   */
+  void recordStaticType(Expression expression, DartType type) {
+    if (_migrationResolutionHooks != null) {
+      type = _migrationResolutionHooks.modifyExpressionType(
+          expression, type ?? _dynamicType);
+    }
+
+    if (type == null) {
+      expression.staticType = _dynamicType;
+    } else {
+      expression.staticType = type;
+      if (identical(type, NeverTypeImpl.instance)) {
+        _flowAnalysis?.flow?.handleExit();
+      }
+    }
+  }
+
+  /**
    * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
    * `String`.</blockquote>
    */
   @override
   void visitAdjacentStrings(AdjacentStrings node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.stringType));
+    recordStaticType(node, _nonNullable(_typeProvider.stringType));
   }
 
   /**
@@ -192,7 +214,7 @@
    */
   @override
   void visitAsExpression(AsExpression node) {
-    _recordStaticType(node, _getType(node.type));
+    recordStaticType(node, _getType(node.type));
   }
 
   /**
@@ -205,7 +227,7 @@
   void visitAwaitExpression(AwaitExpression node) {
     DartType resultType = _getStaticType(node.expression);
     if (resultType != null) resultType = _typeSystem.flatten(resultType);
-    _recordStaticType(node, resultType);
+    recordStaticType(node, resultType);
   }
 
   /**
@@ -214,7 +236,7 @@
    */
   @override
   void visitBooleanLiteral(BooleanLiteral node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.boolType));
+    recordStaticType(node, _nonNullable(_typeProvider.boolType));
   }
 
   /**
@@ -224,7 +246,7 @@
    */
   @override
   void visitCascadeExpression(CascadeExpression node) {
-    _recordStaticType(node, _getStaticType(node.target));
+    recordStaticType(node, _getStaticType(node.target));
   }
 
   /**
@@ -247,7 +269,7 @@
    */
   @override
   void visitDoubleLiteral(DoubleLiteral node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.doubleType));
+    recordStaticType(node, _nonNullable(_typeProvider.doubleType));
   }
 
   @override
@@ -270,7 +292,7 @@
       functionElement.returnType =
           _computeStaticReturnTypeOfFunctionDeclaration(node);
     }
-    _recordStaticType(function, functionElement.type);
+    recordStaticType(function, functionElement.type);
   }
 
   /**
@@ -321,7 +343,7 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     if (identical(node.realTarget.staticType, NeverTypeImpl.instance)) {
-      _recordStaticType(node, NeverTypeImpl.instance);
+      recordStaticType(node, NeverTypeImpl.instance);
     } else {
       DartType type;
       if (node.inSetterContext()) {
@@ -335,7 +357,7 @@
 
       type ??= _dynamicType;
 
-      _recordStaticType(node, type);
+      recordStaticType(node, type);
     }
 
     _resolver.nullShortingTermination(node);
@@ -353,7 +375,7 @@
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
     _inferInstanceCreationExpression(node);
-    _recordStaticType(node, node.constructorName.type.type);
+    recordStaticType(node, node.constructorName.type.type);
   }
 
   /**
@@ -381,9 +403,9 @@
     if (context == null ||
         _typeSystem.isAssignableTo2(_typeProvider.intType, context) ||
         !_typeSystem.isAssignableTo2(_typeProvider.doubleType, context)) {
-      _recordStaticType(node, _nonNullable(_typeProvider.intType));
+      recordStaticType(node, _nonNullable(_typeProvider.intType));
     } else {
-      _recordStaticType(node, _nonNullable(_typeProvider.doubleType));
+      recordStaticType(node, _nonNullable(_typeProvider.doubleType));
     }
   }
 
@@ -395,7 +417,7 @@
    */
   @override
   void visitIsExpression(IsExpression node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.boolType));
+    recordStaticType(node, _nonNullable(_typeProvider.boolType));
   }
 
   @override
@@ -406,7 +428,7 @@
   @override
   void visitNamedExpression(NamedExpression node) {
     Expression expression = node.expression;
-    _recordStaticType(node, _getStaticType(expression));
+    recordStaticType(node, _getStaticType(expression));
   }
 
   /**
@@ -415,13 +437,13 @@
    */
   @override
   void visitNullLiteral(NullLiteral node) {
-    _recordStaticType(node, _typeProvider.nullType);
+    recordStaticType(node, _typeProvider.nullType);
   }
 
   @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     Expression expression = node.expression;
-    _recordStaticType(node, _getStaticType(expression));
+    recordStaticType(node, _getStaticType(expression));
   }
 
   /**
@@ -438,8 +460,8 @@
     }
 
     if (identical(node.prefix.staticType, NeverTypeImpl.instance)) {
-      _recordStaticType(prefixedIdentifier, NeverTypeImpl.instance);
-      _recordStaticType(node, NeverTypeImpl.instance);
+      recordStaticType(prefixedIdentifier, NeverTypeImpl.instance);
+      recordStaticType(node, NeverTypeImpl.instance);
       return;
     }
 
@@ -451,6 +473,11 @@
         node.identifier.staticType = type;
       }
       return;
+    } else if (staticElement is DynamicElementImpl) {
+      var type = _nonNullable(_typeProvider.typeType);
+      node.staticType = type;
+      node.identifier.staticType = type;
+      return;
     } else if (staticElement is FunctionTypeAliasElement) {
       if (node.parent is TypeName) {
         // no type
@@ -472,8 +499,8 @@
 
     staticType = _inferTearOff(node, node.identifier, staticType);
     if (!_inferObjectAccess(node, staticType, prefixedIdentifier)) {
-      _recordStaticType(prefixedIdentifier, staticType);
-      _recordStaticType(node, staticType);
+      recordStaticType(prefixedIdentifier, staticType);
+      recordStaticType(node, staticType);
     }
   }
 
@@ -534,8 +561,8 @@
     staticType = _inferTearOff(node, node.propertyName, staticType);
 
     if (!_inferObjectAccess(node, staticType, propertyName)) {
-      _recordStaticType(propertyName, staticType);
-      _recordStaticType(node, staticType);
+      recordStaticType(propertyName, staticType);
+      recordStaticType(node, staticType);
       _resolver.nullShortingTermination(node);
     }
   }
@@ -546,7 +573,7 @@
    */
   @override
   void visitRethrowExpression(RethrowExpression node) {
-    _recordStaticType(node, _typeProvider.bottomType);
+    recordStaticType(node, _typeProvider.bottomType);
   }
 
   /**
@@ -632,7 +659,7 @@
       staticType = _dynamicType;
     }
     staticType = _inferTearOff(node, node, staticType);
-    _recordStaticType(node, staticType);
+    recordStaticType(node, staticType);
   }
 
   /**
@@ -641,7 +668,7 @@
    */
   @override
   void visitSimpleStringLiteral(SimpleStringLiteral node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.stringType));
+    recordStaticType(node, _nonNullable(_typeProvider.stringType));
   }
 
   /**
@@ -650,7 +677,7 @@
    */
   @override
   void visitStringInterpolation(StringInterpolation node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.stringType));
+    recordStaticType(node, _nonNullable(_typeProvider.stringType));
   }
 
   @override
@@ -659,15 +686,15 @@
         node.thisOrAncestorOfType<ExtensionDeclaration>() != null) {
       // TODO(brianwilkerson) Report this error if it hasn't already been
       // reported.
-      _recordStaticType(node, _dynamicType);
+      recordStaticType(node, _dynamicType);
     } else {
-      _recordStaticType(node, _resolver.thisType);
+      recordStaticType(node, _resolver.thisType);
     }
   }
 
   @override
   void visitSymbolLiteral(SymbolLiteral node) {
-    _recordStaticType(node, _nonNullable(_typeProvider.symbolType));
+    recordStaticType(node, _nonNullable(_typeProvider.symbolType));
   }
 
   /**
@@ -679,9 +706,9 @@
     if (_resolver.thisType == null) {
       // TODO(brianwilkerson) Report this error if it hasn't already been
       // reported.
-      _recordStaticType(node, _dynamicType);
+      recordStaticType(node, _dynamicType);
     } else {
-      _recordStaticType(node, _resolver.thisType);
+      recordStaticType(node, _resolver.thisType);
     }
   }
 
@@ -691,7 +718,7 @@
    */
   @override
   void visitThrowExpression(ThrowExpression node) {
-    _recordStaticType(node, _typeProvider.bottomType);
+    recordStaticType(node, _typeProvider.bottomType);
   }
 
   @override
@@ -734,7 +761,7 @@
 
     staticType = _resolver.toLegacyTypeIfOptOut(staticType);
 
-    _recordStaticType(node, staticType);
+    recordStaticType(node, staticType);
   }
 
   /**
@@ -937,7 +964,7 @@
 
     computedType = _computeReturnTypeOfFunction(body, computedType);
     functionElement.returnType = computedType;
-    _recordStaticType(node, functionElement.type);
+    recordStaticType(node, functionElement.type);
   }
 
   /**
@@ -1002,8 +1029,8 @@
         nodeType.isDynamic &&
         inferredType is InterfaceType &&
         _typeProvider.nonSubtypableClasses.contains(inferredType.element)) {
-      _recordStaticType(id, inferredType);
-      _recordStaticType(node, inferredType);
+      recordStaticType(id, inferredType);
+      recordStaticType(node, inferredType);
       return true;
     }
     return false;
@@ -1070,28 +1097,6 @@
     return type;
   }
 
-  /**
-   * Record that the static type of the given node is the given type.
-   *
-   * @param expression the node whose type is to be recorded
-   * @param type the static type of the node
-   */
-  void _recordStaticType(Expression expression, DartType type) {
-    if (_migrationResolutionHooks != null) {
-      type = _migrationResolutionHooks.modifyExpressionType(
-          expression, type ?? _dynamicType);
-    }
-
-    if (type == null) {
-      expression.staticType = _dynamicType;
-    } else {
-      expression.staticType = type;
-      if (identical(type, NeverTypeImpl.instance)) {
-        _flowAnalysis?.flow?.handleExit();
-      }
-    }
-  }
-
   void _setExtensionIdentifierType(Identifier node) {
     if (node is SimpleIdentifier && node.inDeclarationContext()) {
       return;
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 1d5a001..4ad4eae 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -3,7 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
+import 'package:analyzer/src/dart/element/class_hierarchy.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/source.dart' show Source;
@@ -18,11 +19,9 @@
   factory TestTypeProvider({
     bool isNonNullableByDefault = false,
   }) {
-    var context = _MockAnalysisContext();
-    var sdkElements = MockSdkElements(
-      context,
-      isNonNullableByDefault ? NullabilitySuffix.none : NullabilitySuffix.star,
-    );
+    var analysisContext = _MockAnalysisContext();
+    var analysisSession = _MockAnalysisSession();
+    var sdkElements = MockSdkElements(analysisContext, analysisSession);
     return TestTypeProvider._(
       sdkElements.coreLibrary,
       sdkElements.asyncLibrary,
@@ -37,7 +36,7 @@
   ) : super(
           coreLibrary: coreLibrary,
           asyncLibrary: asyncLibrary,
-          isNonNullableByDefault: isNonNullableByDefault,
+          isNonNullableByDefault: true,
         );
 }
 
@@ -49,6 +48,14 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
+class _MockAnalysisSession implements AnalysisSessionImpl {
+  @override
+  final ClassHierarchy classHierarchy = ClassHierarchy();
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
 class _MockSource implements Source {
   @override
   final Uri uri;
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 3a57819..c58545b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -3,10 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:collection';
-import 'dart:math' as math;
 
-import 'package:analyzer/dart/ast/ast.dart' show AstNode, ConstructorName;
-import 'package:analyzer/dart/ast/token.dart' show Keyword, TokenType;
+import 'package:analyzer/dart/ast/ast.dart' show AstNode;
+import 'package:analyzer/dart/ast/token.dart' show TokenType;
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -14,1256 +13,21 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart' as public;
 import 'package:analyzer/error/listener.dart' show ErrorReporter;
-import 'package:analyzer/src/dart/element/display_string_builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/generic_inferrer.dart';
+import 'package:analyzer/src/dart/element/greatest_lower_bound.dart';
+import 'package:analyzer/src/dart/element/least_upper_bound.dart';
 import 'package:analyzer/src/dart/element/normalize.dart';
 import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
 import 'package:analyzer/src/dart/element/runtime_type_equality.dart';
+import 'package:analyzer/src/dart/element/subtype.dart';
 import 'package:analyzer/src/dart/element/top_merge.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_schema_elimination.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/error/codes.dart' show HintCode, StrongModeCode;
-import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
 import 'package:meta/meta.dart';
 
-bool _isBottom(DartType t) {
-  return (t.isBottom && t.nullabilitySuffix != NullabilitySuffix.question) ||
-      identical(t, UnknownInferredType.instance);
-}
-
-/// Is [t] the bottom of the legacy type hierarchy.
-bool _isLegacyBottom(DartType t, {@required bool orTrueBottom}) {
-  return (t.isBottom && t.nullabilitySuffix == NullabilitySuffix.question) ||
-      t.isDartCoreNull ||
-      (orTrueBottom ? _isBottom(t) : false);
-}
-
-/// Is [t] the top of the legacy type hierarch.
-bool _isLegacyTop(DartType t, {@required bool orTrueTop}) {
-  if (t.isDartAsyncFutureOr) {
-    return _isLegacyTop((t as InterfaceType).typeArguments[0],
-        orTrueTop: orTrueTop);
-  }
-  if (t.isObject && t.nullabilitySuffix == NullabilitySuffix.none) {
-    return true;
-  }
-  return orTrueTop ? _isTop(t) : false;
-}
-
-bool _isTop(DartType t) {
-  if (t.isDartAsyncFutureOr) {
-    return _isTop((t as InterfaceType).typeArguments[0]);
-  }
-  return t.isDynamic ||
-      (t.isObject && t.nullabilitySuffix != NullabilitySuffix.none) ||
-      t.isVoid ||
-      identical(t, UnknownInferredType.instance);
-}
-
-/// Tracks upper and lower type bounds for a set of type parameters.
-///
-/// This class is used by calling [isSubtypeOf]. When it encounters one of
-/// the type parameters it is inferring, it will record the constraint, and
-/// optimistically assume the constraint will be satisfied.
-///
-/// For example if we are inferring type parameter A, and we ask if
-/// `A <: num`, this will record that A must be a subytpe of `num`. It also
-/// handles cases when A appears as part of the structure of another type, for
-/// example `Iterable<A> <: Iterable<num>` would infer the same constraint
-/// (due to covariant generic types) as would `() -> A <: () -> num`. In
-/// contrast `(A) -> void <: (num) -> void`.
-///
-/// Once the lower/upper bounds are determined, [infer] should be called to
-/// finish the inference. It will instantiate a generic function type with the
-/// inferred types for each type parameter.
-///
-/// It can also optionally compute a partial solution, in case some of the type
-/// parameters could not be inferred (because the constraints cannot be
-/// satisfied), or bail on the inference when this happens.
-///
-/// As currently designed, an instance of this class should only be used to
-/// infer a single call and discarded immediately afterwards.
-class GenericInferrer {
-  final TypeSystemImpl _typeSystem;
-  final Map<TypeParameterElement, List<_TypeConstraint>> constraints = {};
-
-  /// Buffer recording constraints recorded while performing a recursive call to
-  /// [_matchSubtypeOf] that might fail, so that any constraints recorded during
-  /// the failed match can be rewound.
-  final _undoBuffer = <_TypeConstraint>[];
-
-  GenericInferrer(
-    this._typeSystem,
-    Iterable<TypeParameterElement> typeFormals,
-  ) {
-    for (var formal in typeFormals) {
-      constraints[formal] = [];
-    }
-  }
-
-  bool get isNonNullableByDefault => _typeSystem.isNonNullableByDefault;
-
-  TypeProvider get typeProvider => _typeSystem.typeProvider;
-
-  /// Apply an argument constraint, which asserts that the [argument] staticType
-  /// is a subtype of the [parameterType].
-  void constrainArgument(
-      DartType argumentType, DartType parameterType, String parameterName,
-      {ClassElement genericClass}) {
-    var origin = _TypeConstraintFromArgument(
-      argumentType,
-      parameterType,
-      parameterName,
-      genericClass: genericClass,
-      isNonNullableByDefault: isNonNullableByDefault,
-    );
-    tryMatchSubtypeOf(argumentType, parameterType, origin, covariant: false);
-  }
-
-  /// Constrain a universal function type [fnType] used in a context
-  /// [contextType].
-  void constrainGenericFunctionInContext(
-      FunctionType fnType, DartType contextType) {
-    var origin = _TypeConstraintFromFunctionContext(
-      fnType,
-      contextType,
-      isNonNullableByDefault: isNonNullableByDefault,
-    );
-
-    // Since we're trying to infer the instantiation, we want to ignore type
-    // formals as we check the parameters and return type.
-    var inferFnType = FunctionTypeImpl(
-      typeFormals: const [],
-      parameters: fnType.parameters,
-      returnType: fnType.returnType,
-      nullabilitySuffix: fnType.nullabilitySuffix,
-    );
-    tryMatchSubtypeOf(inferFnType, contextType, origin, covariant: true);
-  }
-
-  /// Apply a return type constraint, which asserts that the [declaredType]
-  /// is a subtype of the [contextType].
-  void constrainReturnType(DartType declaredType, DartType contextType) {
-    var origin = _TypeConstraintFromReturnType(
-      declaredType,
-      contextType,
-      isNonNullableByDefault: isNonNullableByDefault,
-    );
-    tryMatchSubtypeOf(declaredType, contextType, origin, covariant: true);
-  }
-
-  /// Given the constraints that were given by calling [constrainArgument] and
-  /// [constrainReturnType], find the type arguments for the [typeFormals] that
-  /// satisfies these constraints.
-  ///
-  /// If [downwardsInferPhase] is set, we are in the first pass of inference,
-  /// pushing context types down. At that point we are allowed to push down
-  /// `?` 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}) {
-    // Initialize the inferred type array.
-    //
-    // In the downwards phase, they all start as `?` to offer reasonable
-    // degradation for f-bounded type parameters.
-    var inferredTypes =
-        List<DartType>.filled(typeFormals.length, UnknownInferredType.instance);
-
-    for (int i = 0; i < typeFormals.length; i++) {
-      // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
-      // variance is added to the interface.
-      TypeParameterElementImpl typeParam = typeFormals[i];
-      _TypeConstraint extendsClause;
-      if (considerExtendsClause && typeParam.bound != null) {
-        extendsClause = _TypeConstraint.fromExtends(
-          typeParam,
-          Substitution.fromPairs(typeFormals, inferredTypes)
-              .substituteType(typeParam.bound),
-          isNonNullableByDefault: isNonNullableByDefault,
-        );
-      }
-
-      inferredTypes[i] = downwardsInferPhase
-          ? _inferTypeParameterFromContext(
-              constraints[typeParam], extendsClause,
-              isContravariant: typeParam.variance.isContravariant)
-          : _inferTypeParameterFromAll(constraints[typeParam], extendsClause,
-              isContravariant: typeParam.variance.isContravariant,
-              preferUpwardsInference: !typeParam.isLegacyCovariant);
-    }
-
-    // If the downwards infer phase has failed, we'll catch this in the upwards
-    // phase later on.
-    if (downwardsInferPhase) {
-      return inferredTypes;
-    }
-
-    // Check the inferred types against all of the constraints.
-    var knownTypes = <TypeParameterElement, DartType>{};
-    for (int i = 0; i < typeFormals.length; i++) {
-      TypeParameterElement typeParam = typeFormals[i];
-      var constraints = this.constraints[typeParam];
-      var typeParamBound = typeParam.bound != null
-          ? Substitution.fromPairs(typeFormals, inferredTypes)
-              .substituteType(typeParam.bound)
-          : typeProvider.dynamicType;
-
-      var inferred = inferredTypes[i];
-      bool success =
-          constraints.every((c) => c.isSatisifedBy(_typeSystem, inferred));
-      if (success && !typeParamBound.isDynamic) {
-        // If everything else succeeded, check the `extends` constraint.
-        var extendsConstraint = _TypeConstraint.fromExtends(
-          typeParam,
-          typeParamBound,
-          isNonNullableByDefault: isNonNullableByDefault,
-        );
-        constraints.add(extendsConstraint);
-        success = extendsConstraint.isSatisifedBy(_typeSystem, inferred);
-      }
-
-      if (!success) {
-        if (failAtError) return null;
-        errorReporter?.reportErrorForNode(
-            StrongModeCode.COULD_NOT_INFER,
-            errorNode,
-            [typeParam.name, _formatError(typeParam, inferred, constraints)]);
-
-        // Heuristic: even if we failed, keep the erroneous type.
-        // It should satisfy at least some of the constraints (e.g. the return
-        // context). If we fall back to instantiateToBounds, we'll typically get
-        // more errors (e.g. because `dynamic` is the most common bound).
-      }
-
-      if (inferred is FunctionType && inferred.typeFormals.isNotEmpty) {
-        if (failAtError) return null;
-        var typeFormals = (inferred as FunctionType).typeFormals;
-        var typeFormalsStr = typeFormals.map(_elementStr).join(', ');
-        errorReporter
-            ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
-          typeParam.name,
-          ' Inferred candidate type ${_typeStr(inferred)} has type parameters'
-              ' [$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)) {
-        knownTypes[typeParam] = inferred;
-      } else if (_typeSystem.strictInference) {
-        // [typeParam] could not be inferred. A result will still be returned
-        // by [infer], with [typeParam] filled in as its bounds. This is
-        // considered a failure of inference, under the "strict-inference"
-        // mode.
-        if (errorNode is ConstructorName) {
-          String constructorName = '${errorNode.type}.${errorNode.name}';
-          errorReporter?.reportErrorForNode(
-              HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION,
-              errorNode,
-              [constructorName]);
-        }
-        // TODO(srawlins): More inference failure cases, like functions, and
-        // function expressions.
-      }
-    }
-
-    // Use instantiate to bounds to finish things off.
-    var hasError = List<bool>.filled(typeFormals.length, false);
-    var result = _typeSystem.instantiateTypeFormalsToBounds(typeFormals,
-        hasError: hasError, knownTypes: knownTypes);
-
-    // Report any errors from instantiateToBounds.
-    for (int i = 0; i < hasError.length; i++) {
-      if (hasError[i]) {
-        if (failAtError) return null;
-        TypeParameterElement typeParam = typeFormals[i];
-        var typeParamBound = Substitution.fromPairs(typeFormals, inferredTypes)
-            .substituteType(typeParam.bound ?? typeProvider.objectType);
-        // TODO(jmesserly): improve this error message.
-        errorReporter
-            ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
-          typeParam.name,
-          "\nRecursive bound cannot be instantiated: '$typeParamBound'."
-              "\nConsider passing explicit type argument(s) "
-              "to the generic.\n\n'"
-        ]);
-      }
-    }
-
-    return result;
-  }
-
-  /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
-  ///
-  /// The return value indicates whether the match was successful.  If it was
-  /// unsuccessful, any constraints that were accumulated during the match
-  /// attempt have been rewound (see [_rewindConstraints]).
-  bool tryMatchSubtypeOf(DartType t1, DartType t2, _TypeConstraintOrigin origin,
-      {bool covariant}) {
-    int previousRewindBufferLength = _undoBuffer.length;
-    bool success = _matchSubtypeOf(t1, t2, null, origin, covariant: covariant);
-    if (!success) {
-      _rewindConstraints(previousRewindBufferLength);
-    }
-    return success;
-  }
-
-  /// Choose the bound that was implied by the return type, if any.
-  ///
-  /// Which bound this is depends on what positions the type parameter
-  /// appears in. If the type only appears only in a contravariant position,
-  /// we will choose the lower bound instead.
-  ///
-  /// For example given:
-  ///
-  ///     Func1<T, bool> makeComparer<T>(T x) => (T y) => x() == y;
-  ///
-  ///     main() {
-  ///       Func1<num, bool> t = makeComparer/* infer <num> */(42);
-  ///       print(t(42.0)); /// false, no error.
-  ///     }
-  ///
-  /// The constraints we collect are:
-  ///
-  /// * `num <: T`
-  /// * `int <: T`
-  ///
-  /// ... and no upper bound. Therefore the lower bound is the best choice.
-  ///
-  /// If [isContravariant] is `true`, then we are solving for a contravariant
-  /// type parameter which means we choose the upper bound rather than the
-  /// lower bound for normally covariant type parameters.
-  DartType _chooseTypeFromConstraints(Iterable<_TypeConstraint> constraints,
-      {bool toKnownType = false, @required bool isContravariant}) {
-    DartType lower = UnknownInferredType.instance;
-    DartType upper = UnknownInferredType.instance;
-    for (var constraint in constraints) {
-      // Given constraints:
-      //
-      //     L1 <: T <: U1
-      //     L2 <: T <: U2
-      //
-      // These can be combined to produce:
-      //
-      //     LUB(L1, L2) <: T <: GLB(U1, U2).
-      //
-      // This can then be done for all constraints in sequence.
-      //
-      // This resulting constraint may be unsatisfiable; in that case inference
-      // will fail.
-      upper = _getGreatestLowerBound(upper, constraint.upperBound);
-      lower = _typeSystem.getLeastUpperBound(lower, constraint.lowerBound);
-      upper = _toLegacyType(upper);
-      lower = _toLegacyType(lower);
-    }
-
-    // Prefer the known bound, if any.
-    // Otherwise take whatever bound has partial information, e.g. `Iterable<?>`
-    //
-    // For both of those, prefer the lower bound (arbitrary heuristic) or upper
-    // bound if [isContravariant] is `true`
-    if (isContravariant) {
-      if (UnknownInferredType.isKnown(upper)) {
-        return upper;
-      }
-      if (UnknownInferredType.isKnown(lower)) {
-        return lower;
-      }
-      if (!identical(UnknownInferredType.instance, upper)) {
-        return toKnownType ? _typeSystem.greatestClosure(upper) : upper;
-      }
-      if (!identical(UnknownInferredType.instance, lower)) {
-        return toKnownType ? _typeSystem.leastClosure(lower) : lower;
-      }
-      return upper;
-    } else {
-      if (UnknownInferredType.isKnown(lower)) {
-        return lower;
-      }
-      if (UnknownInferredType.isKnown(upper)) {
-        return upper;
-      }
-      if (!identical(UnknownInferredType.instance, lower)) {
-        return toKnownType ? _typeSystem.leastClosure(lower) : lower;
-      }
-      if (!identical(UnknownInferredType.instance, upper)) {
-        return toKnownType ? _typeSystem.greatestClosure(upper) : upper;
-      }
-      return lower;
-    }
-  }
-
-  String _elementStr(Element element) {
-    return element.getDisplayString(withNullability: isNonNullableByDefault);
-  }
-
-  String _formatError(TypeParameterElement typeParam, DartType inferred,
-      Iterable<_TypeConstraint> constraints) {
-    var inferredStr = inferred.getDisplayString(
-      withNullability: isNonNullableByDefault,
-    );
-    var intro = "Tried to infer '$inferredStr' for '${typeParam.name}'"
-        " which doesn't work:";
-
-    var constraintsByOrigin = <_TypeConstraintOrigin, List<_TypeConstraint>>{};
-    for (var c in constraints) {
-      constraintsByOrigin.putIfAbsent(c.origin, () => []).add(c);
-    }
-
-    // Only report unique constraint origins.
-    Iterable<_TypeConstraint> isSatisified(bool expected) => constraintsByOrigin
-        .values
-        .where((l) =>
-            l.every((c) => c.isSatisifedBy(_typeSystem, inferred)) == expected)
-        .expand((i) => i);
-
-    String unsatisified = _formatConstraints(isSatisified(false));
-    String satisified = _formatConstraints(isSatisified(true));
-
-    assert(unsatisified.isNotEmpty);
-    if (satisified.isNotEmpty) {
-      satisified = "\nThe type '$inferredStr' was inferred from:\n$satisified";
-    }
-
-    return '\n\n$intro\n$unsatisified$satisified\n\n'
-        'Consider passing explicit type argument(s) to the generic.\n\n';
-  }
-
-  /// This is first calls strong mode's GLB, but if it fails to find anything
-  /// (i.e. returns the bottom type), we kick in a few additional rules:
-  ///
-  /// - `GLB(FutureOr<A>, B)` is defined as:
-  ///   - `GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>`
-  ///   - `GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>`
-  ///   - else `GLB(FutureOr<A>, B) == GLB(A, B)`
-  /// - `GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)` (defined above),
-  /// - else `GLB(A, B) == Null`
-  DartType _getGreatestLowerBound(DartType t1, DartType t2) {
-    var result = _typeSystem.getGreatestLowerBound(t1, t2);
-    if (result.isBottom) {
-      // See if we can do better by considering FutureOr rules.
-      if (t1 is InterfaceType && t1.isDartAsyncFutureOr) {
-        var t1TypeArg = t1.typeArguments[0];
-        if (t2 is InterfaceType) {
-          //  GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>
-          if (t2.isDartAsyncFutureOr) {
-            var t2TypeArg = t2.typeArguments[0];
-            return typeProvider
-                .futureOrType2(_getGreatestLowerBound(t1TypeArg, t2TypeArg));
-          }
-          // GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>
-          if (t2.isDartAsyncFuture) {
-            var t2TypeArg = t2.typeArguments[0];
-            return typeProvider
-                .futureType2(_getGreatestLowerBound(t1TypeArg, t2TypeArg));
-          }
-        }
-        // GLB(FutureOr<A>, B) == GLB(A, B)
-        return _getGreatestLowerBound(t1TypeArg, t2);
-      }
-      if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
-        // GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)
-        return _getGreatestLowerBound(t2, t1);
-      }
-    }
-    return result;
-  }
-
-  DartType _inferTypeParameterFromAll(
-      List<_TypeConstraint> constraints, _TypeConstraint extendsClause,
-      {@required bool isContravariant, @required bool preferUpwardsInference}) {
-    // See if we already fixed this type from downwards inference.
-    // If so, then we aren't allowed to change it based on argument types unless
-    // [preferUpwardsInference] is true.
-    DartType t = _inferTypeParameterFromContext(
-        constraints.where((c) => c.isDownwards), extendsClause,
-        isContravariant: isContravariant);
-    if (!preferUpwardsInference && UnknownInferredType.isKnown(t)) {
-      // Remove constraints that aren't downward ones; we'll ignore these for
-      // error reporting, because inference already succeeded.
-      constraints.removeWhere((c) => !c.isDownwards);
-      return t;
-    }
-
-    if (extendsClause != null) {
-      constraints = constraints.toList()..add(extendsClause);
-    }
-
-    var choice = _chooseTypeFromConstraints(constraints,
-        toKnownType: true, isContravariant: isContravariant);
-    return choice;
-  }
-
-  DartType _inferTypeParameterFromContext(
-      Iterable<_TypeConstraint> constraints, _TypeConstraint extendsClause,
-      {@required bool isContravariant}) {
-    DartType t = _chooseTypeFromConstraints(constraints,
-        isContravariant: isContravariant);
-    if (UnknownInferredType.isUnknown(t)) {
-      return t;
-    }
-
-    // If we're about to make our final choice, apply the extends clause.
-    // This gives us a chance to refine the choice, in case it would violate
-    // the `extends` clause. For example:
-    //
-    //     Object obj = math.min/*<infer Object, error>*/(1, 2);
-    //
-    // If we consider the `T extends num` we conclude `<num>`, which works.
-    if (extendsClause != null) {
-      constraints = constraints.toList()..add(extendsClause);
-      return _chooseTypeFromConstraints(constraints,
-          isContravariant: isContravariant);
-    }
-    return t;
-  }
-
-  /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
-  ///
-  /// The return value indicates whether the match was successful.  If it was
-  /// unsuccessful, the caller is responsible for ignoring any constraints that
-  /// were accumulated (see [_rewindConstraints]).
-  bool _matchInterfaceSubtypeOf(InterfaceType i1, InterfaceType i2,
-      Set<Element> visited, _TypeConstraintOrigin origin,
-      {bool covariant}) {
-    if (identical(i1, i2)) {
-      return true;
-    }
-
-    if (i1.element == i2.element) {
-      List<DartType> tArgs1 = i1.typeArguments;
-      List<DartType> tArgs2 = i2.typeArguments;
-      List<TypeParameterElement> tParams = i1.element.typeParameters;
-      assert(tArgs1.length == tArgs2.length);
-      assert(tArgs1.length == tParams.length);
-      for (int i = 0; i < tArgs1.length; i++) {
-        TypeParameterElement typeParameterElement = tParams[i];
-
-        // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
-        // variance is added to the interface.
-        Variance parameterVariance =
-            (typeParameterElement as TypeParameterElementImpl).variance;
-        if (parameterVariance.isCovariant) {
-          if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], HashSet<Element>(), origin,
-              covariant: covariant)) {
-            return false;
-          }
-        } else if (parameterVariance.isContravariant) {
-          if (!_matchSubtypeOf(tArgs2[i], tArgs1[i], HashSet<Element>(), origin,
-              covariant: !covariant)) {
-            return false;
-          }
-        } else if (parameterVariance.isInvariant) {
-          if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], HashSet<Element>(), origin,
-                  covariant: covariant) ||
-              !_matchSubtypeOf(tArgs2[i], tArgs1[i], HashSet<Element>(), origin,
-                  covariant: !covariant)) {
-            return false;
-          }
-        } else {
-          throw StateError("Type parameter ${tParams[i]} has unknown "
-              "variance $parameterVariance for inference.");
-        }
-      }
-      return true;
-    }
-    if (i1.isObject) {
-      return false;
-    }
-
-    // Guard against loops in the class hierarchy
-    bool guardedInterfaceSubtype(InterfaceType t1) {
-      visited ??= HashSet<Element>();
-      if (visited.add(t1.element)) {
-        bool matched = _matchInterfaceSubtypeOf(t1, i2, visited, origin,
-            covariant: covariant);
-        visited.remove(t1.element);
-        return matched;
-      } else {
-        // In the case of a recursive type parameter, consider the subtype
-        // match to have failed.
-        return false;
-      }
-    }
-
-    // We don't need to search the entire class hierarchy, since a given
-    // subclass can't appear multiple times with different generic parameters.
-    // So shortcut to the first match found.
-    //
-    // We don't need undo logic here because if the classes don't match, nothing
-    // is added to the constraint set.
-    var superclass = i1.superclass;
-    if (superclass != null && guardedInterfaceSubtype(superclass)) return true;
-    for (final parent in i1.interfaces) {
-      if (guardedInterfaceSubtype(parent)) return true;
-    }
-    for (final parent in i1.mixins) {
-      if (guardedInterfaceSubtype(parent)) return true;
-    }
-    for (final parent in i1.superclassConstraints) {
-      if (guardedInterfaceSubtype(parent)) return true;
-    }
-    return false;
-  }
-
-  /// Assert that [t1] will be a subtype of [t2], and returns if the constraint
-  /// can be satisfied.
-  ///
-  /// [covariant] must be true if [t1] is a declared type of the generic
-  /// function and [t2] is the context type, or false if the reverse. For
-  /// example [covariant] is used when [t1] is the declared return type
-  /// and [t2] is the context type. Contravariant would be used if [t1] is the
-  /// argument type (i.e. passed in to the generic function) and [t2] is the
-  /// declared parameter type.
-  ///
-  /// [origin] indicates where the constraint came from, for example an argument
-  /// or return type.
-  bool _matchSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
-      _TypeConstraintOrigin origin,
-      {bool covariant}) {
-    if (covariant && t1 is TypeParameterType) {
-      var constraints = this.constraints[t1.element];
-      if (constraints != null) {
-        if (!identical(t2, UnknownInferredType.instance)) {
-          var constraint = _TypeConstraint(origin, t1.element, upper: t2);
-          constraints.add(constraint);
-          _undoBuffer.add(constraint);
-        }
-        return true;
-      }
-    }
-    if (!covariant && t2 is TypeParameterType) {
-      var constraints = this.constraints[t2.element];
-      if (constraints != null) {
-        if (!identical(t1, UnknownInferredType.instance)) {
-          if (t2.nullabilitySuffix == NullabilitySuffix.question) {
-            t1 = _typeSystem.promoteToNonNull(t1);
-          }
-          var constraint = _TypeConstraint(origin, t2.element, lower: t1);
-          constraints.add(constraint);
-          _undoBuffer.add(constraint);
-        }
-        return true;
-      }
-    }
-
-    if (identical(t1, t2)) {
-      return true;
-    }
-
-    // TODO(jmesserly): this logic is taken from subtype.
-    bool matchSubtype(DartType t1, DartType t2) {
-      return _matchSubtypeOf(t1, t2, null, origin, covariant: covariant);
-    }
-
-    // Handle FutureOr<T> union type.
-    if (t1 is InterfaceType && t1.isDartAsyncFutureOr) {
-      var t1TypeArg = t1.typeArguments[0];
-      if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
-        var t2TypeArg = t2.typeArguments[0];
-        // FutureOr<A> <: FutureOr<B> iff A <: B
-        return matchSubtype(t1TypeArg, t2TypeArg);
-      }
-
-      // given t1 is Future<A> | A, then:
-      // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
-      var t1Future = typeProvider.futureType2(t1TypeArg);
-      return matchSubtype(t1Future, t2) && matchSubtype(t1TypeArg, t2);
-    }
-
-    if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
-      // given t2 is Future<A> | A, then:
-      // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
-      var t2TypeArg = t2.typeArguments[0];
-      var t2Future = typeProvider.futureType2(t2TypeArg);
-
-      // First we try matching `t1 <: Future<A>`.  If that succeeds *and*
-      // records at least one constraint, then we proceed using that constraint.
-      var previousRewindBufferLength = _undoBuffer.length;
-      var success =
-          tryMatchSubtypeOf(t1, t2Future, origin, covariant: covariant);
-
-      if (_undoBuffer.length != previousRewindBufferLength) {
-        // Trying to match `t1 <: Future<A>` succeeded and recorded constraints,
-        // so those are the constraints we want.
-        return true;
-      } else {
-        // Either `t1 <: Future<A>` failed to match, or it matched trivially
-        // without recording any constraints (e.g. because t1 is `Null`).  We
-        // want constraints, because they let us do more precise inference, so
-        // go ahead and try matching `t1 <: A` to see if it records any
-        // constraints.
-        if (tryMatchSubtypeOf(t1, t2TypeArg, origin, covariant: covariant)) {
-          // Trying to match `t1 <: A` succeeded.  If it recorded constraints,
-          // those are the constraints we want.  If it didn't, then there's no
-          // way we're going to get any constraints.  So either way, we want to
-          // return `true` since the match suceeded and the constraints we want
-          // (if any) have been recorded.
-          return true;
-        } else {
-          // Trying to match `t1 <: A` failed.  So there's no way we are going
-          // to get any constraints.  Just return `success` to indicate whether
-          // the match succeeded.
-          return success;
-        }
-      }
-    }
-
-    // S <: T where S is a type variable
-    //  T is not dynamic or object (handled above)
-    //  True if T == S
-    //  Or true if bound of S is S' and S' <: T
-
-    if (t1 is TypeParameterType) {
-      // Guard against recursive type parameters
-      //
-      // TODO(jmesserly): this function isn't guarding against anything (it's
-      // not passsing down `visitedSet`, so adding the element has no effect).
-      bool guardedSubtype(DartType t1, DartType t2) {
-        var visitedSet = visited ?? HashSet<Element>();
-        if (visitedSet.add(t1.element)) {
-          bool matched = matchSubtype(t1, t2);
-          visitedSet.remove(t1.element);
-          return matched;
-        } else {
-          // In the case of a recursive type parameter, consider the subtype
-          // match to have failed.
-          return false;
-        }
-      }
-
-      if (t2 is TypeParameterType && t1.definition == t2.definition) {
-        return guardedSubtype(t1.bound, t2.bound);
-      }
-      return guardedSubtype(t1.bound, t2);
-    }
-    if (t2 is TypeParameterType) {
-      return false;
-    }
-
-    // TODO(mfairhurst): switch legacy Bottom checks to true Bottom checks
-    // TODO(mfairhurst): switch legacy Top checks to true Top checks
-    if (_isLegacyBottom(t1, orTrueBottom: true) ||
-        _isLegacyTop(t2, orTrueTop: true)) return true;
-
-    if (t1 is InterfaceType && t2 is InterfaceType) {
-      return _matchInterfaceSubtypeOf(t1, t2, visited, origin,
-          covariant: covariant);
-    }
-
-    if (t1 is FunctionType && t2 is FunctionType) {
-      return FunctionTypeImpl.relate(t1, t2, matchSubtype,
-          parameterRelation: (p1, p2) {
-            return _matchSubtypeOf(p2.type, p1.type, null, origin,
-                covariant: !covariant);
-          },
-          // Type parameter bounds are invariant.
-          boundsRelation: (t1, t2, p1, p2) =>
-              matchSubtype(t1, t2) && matchSubtype(t2, t1));
-    }
-
-    if (t1 is FunctionType && t2 == typeProvider.functionType) {
-      return true;
-    }
-
-    return false;
-  }
-
-  /// Un-does constraints that were gathered by a failed match attempt, until
-  /// [_undoBuffer] has length [previousRewindBufferLength].
-  ///
-  /// The intended usage is that the caller should record the length of
-  /// [_undoBuffer] before attempting to make a match.  Then, if the match
-  /// fails, pass the recorded length to this method to erase any constraints
-  /// that were recorded during the failed match.
-  void _rewindConstraints(int previousRewindBufferLength) {
-    while (_undoBuffer.length > previousRewindBufferLength) {
-      var constraint = _undoBuffer.removeLast();
-      var element = constraint.typeParameter;
-      assert(identical(constraints[element].last, constraint));
-      constraints[element].removeLast();
-    }
-  }
-
-  /// If in a legacy library, return the legacy version of the [type].
-  /// Otherwise, return the original type.
-  DartType _toLegacyType(DartType type) {
-    if (isNonNullableByDefault) return type;
-    return NullabilityEliminator.perform(typeProvider, type);
-  }
-
-  String _typeStr(DartType type) {
-    return type.getDisplayString(withNullability: isNonNullableByDefault);
-  }
-
-  static String _formatConstraints(Iterable<_TypeConstraint> constraints) {
-    List<List<String>> lineParts =
-        Set<_TypeConstraintOrigin>.from(constraints.map((c) => c.origin))
-            .map((o) => o.formatError())
-            .toList();
-
-    int prefixMax = lineParts.map((p) => p[0].length).fold(0, math.max);
-
-    // Use a set to prevent identical message lines.
-    // (It's not uncommon for the same constraint to show up in a few places.)
-    var messageLines = Set<String>.from(lineParts.map((parts) {
-      var prefix = parts[0];
-      var middle = parts[1];
-      var prefixPad = ' ' * (prefixMax - prefix.length);
-      var middlePad = ' ' * (prefixMax);
-      var end = "";
-      if (parts.length > 2) {
-        end = '\n  $middlePad ${parts[2]}';
-      }
-      return '  $prefix$prefixPad $middle$end';
-    }));
-
-    return messageLines.join('\n');
-  }
-}
-
-/// The instantiation of a [ClassElement] with type arguments.
-///
-/// It is not a [DartType] itself, because it does not have nullability.
-/// But it should be used where nullability does not make sense - to specify
-/// superclasses, mixins, and implemented interfaces.
-class InstantiatedClass {
-  final ClassElement element;
-  final List<DartType> arguments;
-
-  final Substitution _substitution;
-
-  InstantiatedClass(this.element, this.arguments)
-      : _substitution = Substitution.fromPairs(
-          element.typeParameters,
-          arguments,
-        );
-
-  /// Return the [InstantiatedClass] that corresponds to the [type] - with the
-  /// same element and type arguments, ignoring its nullability suffix.
-  factory InstantiatedClass.of(InterfaceType type) {
-    return InstantiatedClass(type.element, type.typeArguments);
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0x3fffffff & element.hashCode;
-    for (var i = 0; i < arguments.length; i++) {
-      hash = 0x3fffffff & (hash * 31 + (hash ^ arguments[i].hashCode));
-    }
-    return hash;
-  }
-
-  /// Return the interfaces that are directly implemented by this class.
-  List<InstantiatedClass> get interfaces {
-    var interfaces = element.interfaces;
-
-    var result = List<InstantiatedClass>(interfaces.length);
-    for (var i = 0; i < interfaces.length; i++) {
-      var interface = interfaces[i];
-      var substituted = _substitution.substituteType(interface);
-      result[i] = InstantiatedClass.of(substituted);
-    }
-
-    return result;
-  }
-
-  /// Return `true` if this type represents the type 'Function' defined in the
-  /// dart:core library.
-  bool get isDartCoreFunction {
-    return element.name == 'Function' && element.library.isDartCore;
-  }
-
-  /// Return the superclass of this type, or `null` if this type represents
-  /// the class 'Object'.
-  InstantiatedClass get superclass {
-    var supertype = element.supertype;
-    if (supertype == null) return null;
-
-    supertype = _substitution.substituteType(supertype);
-    return InstantiatedClass.of(supertype);
-  }
-
-  /// Return a list containing all of the superclass constraints defined for
-  /// this class. The list will be empty if this class does not represent a
-  /// mixin declaration. If this class _does_ represent a mixin declaration but
-  /// the declaration does not have an `on` clause, then the list will contain
-  /// the type for the class `Object`.
-  List<InstantiatedClass> get superclassConstraints {
-    var constraints = element.superclassConstraints;
-
-    var result = List<InstantiatedClass>(constraints.length);
-    for (var i = 0; i < constraints.length; i++) {
-      var constraint = constraints[i];
-      var substituted = _substitution.substituteType(constraint);
-      result[i] = InstantiatedClass.of(substituted);
-    }
-
-    return result;
-  }
-
-  @visibleForTesting
-  InterfaceType get withNullabilitySuffixNone {
-    return withNullability(NullabilitySuffix.none);
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-
-    if (other is InstantiatedClass) {
-      if (element != other.element) return false;
-      if (arguments.length != other.arguments.length) return false;
-      for (var i = 0; i < arguments.length; i++) {
-        if (arguments[i] != other.arguments[i]) return false;
-      }
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  String toString() {
-    var buffer = StringBuffer();
-    buffer.write(element.name);
-    if (arguments.isNotEmpty) {
-      buffer.write('<');
-      buffer.write(arguments.join(', '));
-      buffer.write('>');
-    }
-    return buffer.toString();
-  }
-
-  InterfaceType withNullability(NullabilitySuffix nullability) {
-    return InterfaceTypeImpl(
-      element: element,
-      typeArguments: arguments,
-      nullabilitySuffix: nullability,
-    );
-  }
-}
-
-class InterfaceLeastUpperBoundHelper {
-  final TypeSystemImpl typeSystem;
-
-  InterfaceLeastUpperBoundHelper(this.typeSystem);
-
-  /// This currently does not implement a very complete least upper bound
-  /// algorithm, but handles a couple of the very common cases that are
-  /// causing pain in real code.  The current algorithm is:
-  /// 1. If either of the types is a supertype of the other, return it.
-  ///    This is in fact the best result in this case.
-  /// 2. If the two types have the same class element and are implicitly or
-  ///    explicitly covariant, then take the pointwise least upper bound of
-  ///    the type arguments. This is again the best result, except that the
-  ///    recursive calls may not return the true least upper bounds. The
-  ///    result is guaranteed to be a well-formed type under the assumption
-  ///    that the input types were well-formed (and assuming that the
-  ///    recursive calls return well-formed types).
-  ///    If the variance of the type parameter is contravariant, we take the
-  ///    greatest lower bound of the type arguments. If the variance of the
-  ///    type parameter is invariant, we verify if the type arguments satisfy
-  ///    subtyping in both directions, then choose a bound.
-  /// 3. Otherwise return the spec-defined least upper bound.  This will
-  ///    be an upper bound, might (or might not) be least, and might
-  ///    (or might not) be a well-formed type.
-  ///
-  /// TODO(leafp): Use matchTypes or something similar here to handle the
-  ///  case where one of the types is a superclass (but not supertype) of
-  ///  the other, e.g. LUB(Iterable<double>, List<int>) = Iterable<num>
-  /// TODO(leafp): Figure out the right final algorithm and implement it.
-  InterfaceTypeImpl compute(InterfaceTypeImpl type1, InterfaceTypeImpl type2) {
-    var nullability = _chooseNullability(type1, type2);
-
-    // Strip off nullability.
-    type1 = type1.withNullability(NullabilitySuffix.none);
-    type2 = type2.withNullability(NullabilitySuffix.none);
-
-    if (typeSystem.isSubtypeOf2(type1, type2)) {
-      return type2.withNullability(nullability);
-    }
-    if (typeSystem.isSubtypeOf2(type2, type1)) {
-      return type1.withNullability(nullability);
-    }
-
-    if (type1.element == type2.element) {
-      var args1 = type1.typeArguments;
-      var args2 = type2.typeArguments;
-      var params = type1.element.typeParameters;
-      assert(args1.length == args2.length);
-      assert(args1.length == params.length);
-
-      var args = List<DartType>(args1.length);
-      for (int i = 0; i < args1.length; i++) {
-        // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
-        // variance is added to the interface.
-        Variance parameterVariance =
-            (params[i] as TypeParameterElementImpl).variance;
-        if (parameterVariance.isCovariant) {
-          args[i] = typeSystem.getLeastUpperBound(args1[i], args2[i]);
-        } else if (parameterVariance.isContravariant) {
-          if (typeSystem is TypeSystemImpl) {
-            args[i] = typeSystem.getGreatestLowerBound(args1[i], args2[i]);
-          } else {
-            args[i] = typeSystem.getLeastUpperBound(args1[i], args2[i]);
-          }
-        } else if (parameterVariance.isInvariant) {
-          if (!typeSystem.isSubtypeOf2(args1[i], args2[i]) ||
-              !typeSystem.isSubtypeOf2(args2[i], args1[i])) {
-            // No bound will be valid, find bound at the interface level.
-            return _computeLeastUpperBound(
-              InstantiatedClass.of(type1),
-              InstantiatedClass.of(type2),
-            ).withNullability(nullability);
-          }
-          // TODO (kallentu) : Fix asymmetric bounds behavior for invariant type
-          //  parameters.
-          args[i] = args1[i];
-        } else {
-          throw StateError('Type parameter ${params[i]} has unknown '
-              'variance $parameterVariance for bounds calculation.');
-        }
-      }
-
-      return InterfaceTypeImpl(
-        element: type1.element,
-        typeArguments: args,
-        nullabilitySuffix: nullability,
-      );
-    }
-
-    var result = _computeLeastUpperBound(
-      InstantiatedClass.of(type1),
-      InstantiatedClass.of(type2),
-    );
-    return result.withNullability(nullability);
-  }
-
-  /// Compute the least upper bound of types [i] and [j], both of which are
-  /// known to be interface types.
-  ///
-  /// In the event that the algorithm fails (which might occur due to a bug in
-  /// the analyzer), `null` is returned.
-  InstantiatedClass _computeLeastUpperBound(
-    InstantiatedClass i,
-    InstantiatedClass j,
-  ) {
-    // compute set of supertypes
-    var si = computeSuperinterfaceSet(i);
-    var sj = computeSuperinterfaceSet(j);
-
-    // union si with i and sj with j
-    si.add(i);
-    sj.add(j);
-
-    // compute intersection, reference as set 's'
-    var s = _intersection(si, sj);
-    return _computeTypeAtMaxUniqueDepth(s);
-  }
-
-  /**
-   * Return the length of the longest inheritance path from the [element] to
-   * Object.
-   */
-  @visibleForTesting
-  static int computeLongestInheritancePathToObject(ClassElement element) {
-    return _computeLongestInheritancePathToObject(
-      element,
-      0,
-      <ClassElement>{},
-    );
-  }
-
-  /// Return all of the superinterfaces of the given [type].
-  @visibleForTesting
-  static Set<InstantiatedClass> computeSuperinterfaceSet(
-      InstantiatedClass type) {
-    var result = <InstantiatedClass>{};
-    _addSuperinterfaces(result, type);
-    return result;
-  }
-
-  /// Add all of the superinterfaces of the given [type] to the given [set].
-  static void _addSuperinterfaces(
-      Set<InstantiatedClass> set, InstantiatedClass type) {
-    for (var interface in type.interfaces) {
-      if (!interface.isDartCoreFunction) {
-        if (set.add(interface)) {
-          _addSuperinterfaces(set, interface);
-        }
-      }
-    }
-
-    for (var constraint in type.superclassConstraints) {
-      if (!constraint.isDartCoreFunction) {
-        if (set.add(constraint)) {
-          _addSuperinterfaces(set, constraint);
-        }
-      }
-    }
-
-    var supertype = type.superclass;
-    if (supertype != null && !supertype.isDartCoreFunction) {
-      if (set.add(supertype)) {
-        _addSuperinterfaces(set, supertype);
-      }
-    }
-  }
-
-  static NullabilitySuffix _chooseNullability(
-    InterfaceTypeImpl type1,
-    InterfaceTypeImpl type2,
-  ) {
-    var nullability1 = type1.nullabilitySuffix;
-    var nullability2 = type2.nullabilitySuffix;
-    if (nullability1 == NullabilitySuffix.question ||
-        nullability2 == NullabilitySuffix.question) {
-      return NullabilitySuffix.question;
-    } else if (nullability1 == NullabilitySuffix.star ||
-        nullability2 == NullabilitySuffix.star) {
-      return NullabilitySuffix.star;
-    }
-    return NullabilitySuffix.none;
-  }
-
-  /// Return the length of the longest inheritance path from a subtype of the
-  /// given [element] to Object, where the given [depth] is the length of the
-  /// longest path from the subtype to this type. The set of [visitedElements]
-  /// is used to prevent infinite recursion in the case of a cyclic type
-  /// structure.
-  static int _computeLongestInheritancePathToObject(
-      ClassElement element, int depth, Set<ClassElement> visitedElements) {
-    // Object case
-    if (element.isDartCoreObject || visitedElements.contains(element)) {
-      return depth;
-    }
-    int longestPath = 1;
-    try {
-      visitedElements.add(element);
-      int pathLength;
-
-      // loop through each of the superinterfaces recursively calling this
-      // method and keeping track of the longest path to return
-      for (InterfaceType interface in element.superclassConstraints) {
-        pathLength = _computeLongestInheritancePathToObject(
-            interface.element, depth + 1, visitedElements);
-        if (pathLength > longestPath) {
-          longestPath = pathLength;
-        }
-      }
-
-      // loop through each of the superinterfaces recursively calling this
-      // method and keeping track of the longest path to return
-      for (InterfaceType interface in element.interfaces) {
-        pathLength = _computeLongestInheritancePathToObject(
-            interface.element, depth + 1, visitedElements);
-        if (pathLength > longestPath) {
-          longestPath = pathLength;
-        }
-      }
-
-      // finally, perform this same check on the super type
-      // TODO(brianwilkerson) Does this also need to add in the number of mixin
-      // classes?
-      InterfaceType supertype = element.supertype;
-      if (supertype != null) {
-        pathLength = _computeLongestInheritancePathToObject(
-            supertype.element, depth + 1, visitedElements);
-        if (pathLength > longestPath) {
-          longestPath = pathLength;
-        }
-      }
-    } finally {
-      visitedElements.remove(element);
-    }
-    return longestPath;
-  }
-
-  /// Return the type from the [types] list that has the longest inheritance
-  /// path to Object of unique length.
-  static InstantiatedClass _computeTypeAtMaxUniqueDepth(
-    List<InstantiatedClass> types,
-  ) {
-    // for each element in Set s, compute the largest inheritance path to Object
-    List<int> depths = List<int>.filled(types.length, 0);
-    int maxDepth = 0;
-    for (int i = 0; i < types.length; i++) {
-      depths[i] = computeLongestInheritancePathToObject(types[i].element);
-      if (depths[i] > maxDepth) {
-        maxDepth = depths[i];
-      }
-    }
-    // ensure that the currently computed maxDepth is unique,
-    // otherwise, decrement and test for uniqueness again
-    for (; maxDepth >= 0; maxDepth--) {
-      int indexOfLeastUpperBound = -1;
-      int numberOfTypesAtMaxDepth = 0;
-      for (int m = 0; m < depths.length; m++) {
-        if (depths[m] == maxDepth) {
-          numberOfTypesAtMaxDepth++;
-          indexOfLeastUpperBound = m;
-        }
-      }
-      if (numberOfTypesAtMaxDepth == 1) {
-        return types[indexOfLeastUpperBound];
-      }
-    }
-    // Should be impossible--there should always be exactly one type with the
-    // maximum depth.
-    assert(false);
-    return null;
-  }
-
-  /**
-   * Return the intersection of the [first] and [second] sets of types, where
-   * intersection is based on the equality of the types themselves.
-   */
-  static List<InstantiatedClass> _intersection(
-    Set<InstantiatedClass> first,
-    Set<InstantiatedClass> second,
-  ) {
-    var result = first.toSet();
-    result.retainAll(second);
-    return result.toList();
-  }
-}
-
-/// Used to check for infinite loops, if we repeat the same type comparison.
-class TypeComparison {
-  final DartType lhs;
-  final DartType rhs;
-
-  TypeComparison(this.lhs, this.rhs);
-
-  @override
-  int get hashCode => lhs.hashCode * 11 + rhs.hashCode;
-
-  @override
-  bool operator ==(Object other) {
-    if (other is TypeComparison) {
-      return lhs == other.lhs && rhs == other.rhs;
-    }
-
-    return false;
-  }
-
-  @override
-  String toString() => "$lhs vs $rhs";
-}
-
 /**
  * The interface `TypeSystem` defines the behavior of an object representing
  * the type system.  This provides a common location to put methods that act on
@@ -1610,7 +374,9 @@
           operator == TokenType.PERCENT_EQ ||
           operator == TokenType.PLUS_EQ ||
           operator == TokenType.STAR_EQ ||
-          operator == TokenType.TILDE_SLASH_EQ) {
+          operator == TokenType.TILDE_SLASH_EQ ||
+          operator == TokenType.PLUS_PLUS ||
+          operator == TokenType.MINUS_MINUS) {
         if (rightType.isDartCoreInt) {
           InterfaceTypeImpl intType = typeProvider.intType;
           if (isNonNullableByDefault) {
@@ -1712,58 +478,61 @@
    *
    * This affects the behavior of [isAssignableTo].
    */
-  final bool implicitCasts;
+  bool implicitCasts;
 
   /// A flag indicating whether inference failures are allowed, off by default.
   ///
   /// This option is experimental and subject to change.
-  final bool strictInference;
+  bool strictInference;
 
   @override
   final TypeProvider typeProvider;
 
   /// The cached instance of `Object?`.
-  InterfaceTypeImpl _objectQuestionCached;
+  InterfaceTypeImpl _objectQuestion;
 
   /// The cached instance of `Object*`.
-  InterfaceTypeImpl _objectStarCached;
+  InterfaceTypeImpl _objectStar;
 
   /// The cached instance of `Object!`.
-  InterfaceTypeImpl _objectNoneCached;
+  InterfaceTypeImpl _objectNone;
 
   /// The cached instance of `Null!`.
-  InterfaceTypeImpl _nullNoneCached;
+  InterfaceTypeImpl _nullNone;
+
+  GreatestLowerBoundHelper _greatestLowerBoundHelper;
+  LeastUpperBoundHelper _leastUpperBoundHelper;
+
+  /// The implementation of the subtyping relation.
+  SubtypeHelper _subtypeHelper;
 
   TypeSystemImpl({
     @required this.implicitCasts,
     @required bool isNonNullableByDefault,
     @required this.strictInference,
     @required this.typeProvider,
-  }) : super(isNonNullableByDefault: isNonNullableByDefault);
+  }) : super(isNonNullableByDefault: isNonNullableByDefault) {
+    _greatestLowerBoundHelper = GreatestLowerBoundHelper(this);
+    _leastUpperBoundHelper = LeastUpperBoundHelper(this);
+    _subtypeHelper = SubtypeHelper(this);
+  }
 
   InterfaceTypeImpl get nullNone =>
-      _nullNoneCached ??= (typeProvider.nullType as TypeImpl)
+      _nullNone ??= (typeProvider.nullType as TypeImpl)
           .withNullability(NullabilitySuffix.none);
 
   InterfaceTypeImpl get objectNone =>
-      _objectNoneCached ??= (typeProvider.objectType as TypeImpl)
+      _objectNone ??= (typeProvider.objectType as TypeImpl)
           .withNullability(NullabilitySuffix.none);
 
   InterfaceTypeImpl get objectQuestion =>
-      _objectQuestionCached ??= (typeProvider.objectType as TypeImpl)
+      _objectQuestion ??= (typeProvider.objectType as TypeImpl)
           .withNullability(NullabilitySuffix.question);
 
   InterfaceTypeImpl get objectStar =>
-      _objectStarCached ??= (typeProvider.objectType as TypeImpl)
+      _objectStar ??= (typeProvider.objectType as TypeImpl)
           .withNullability(NullabilitySuffix.star);
 
-  InterfaceType get _interfaceTypeFunctionNone {
-    return typeProvider.functionType.element.instantiate(
-      typeArguments: const [],
-      nullabilitySuffix: NullabilitySuffix.none,
-    );
-  }
-
   /// Returns true iff the type [t] accepts function types, and requires an
   /// implicit coercion if interface types with a `call` method are passed in.
   ///
@@ -1877,201 +646,7 @@
 
   /// Computes the greatest lower bound of [T1] and [T2].
   DartType getGreatestLowerBound(DartType T1, DartType T2) {
-    // DOWN(T, T) = T
-    if (identical(T1, T2)) {
-      return T1;
-    }
-
-    // For any type T, DOWN(?, T) == T.
-    if (identical(T1, UnknownInferredType.instance)) {
-      return T2;
-    }
-    if (identical(T2, UnknownInferredType.instance)) {
-      return T1;
-    }
-
-    var T1_isTop = isTop(T1);
-    var T2_isTop = isTop(T2);
-
-    // DOWN(T1, T2) where TOP(T1) and TOP(T2)
-    if (T1_isTop && T2_isTop) {
-      // * T1 if MORETOP(T2, T1)
-      // * T2 otherwise
-      if (isMoreTop(T2, T1)) {
-        return T1;
-      } else {
-        return T2;
-      }
-    }
-
-    // DOWN(T1, T2) = T2 if TOP(T1)
-    if (T1_isTop) {
-      return T2;
-    }
-
-    // DOWN(T1, T2) = T1 if TOP(T2)
-    if (T2_isTop) {
-      return T1;
-    }
-
-    var T1_isBottom = isBottom(T1);
-    var T2_isBottom = isBottom(T2);
-
-    // DOWN(T1, T2) where BOTTOM(T1) and BOTTOM(T2)
-    if (T1_isBottom && T2_isBottom) {
-      // * T1 if MOREBOTTOM(T1, T2)
-      // * T2 otherwise
-      if (isMoreBottom(T1, T2)) {
-        return T1;
-      } else {
-        return T2;
-      }
-    }
-
-    // DOWN(T1, T2) = T1 if BOTTOM(T1)
-    if (T1_isBottom) {
-      return T1;
-    }
-
-    // DOWN(T1, T2) = T2 if BOTTOM(T2)
-    if (T2_isBottom) {
-      return T2;
-    }
-
-    var T1_isNull = isNull(T1);
-    var T2_isNull = isNull(T2);
-
-    // DOWN(T1, T2) where NULL(T1) and NULL(T2)
-    if (T1_isNull && T2_isNull) {
-      // * T1 if MOREBOTTOM(T1, T2)
-      // * T2 otherwise
-      if (isMoreBottom(T1, T2)) {
-        return T1;
-      } else {
-        return T2;
-      }
-    }
-
-    var T1_impl = T1 as TypeImpl;
-    var T2_impl = T2 as TypeImpl;
-
-    var T1_nullability = T1_impl.nullabilitySuffix;
-    var T2_nullability = T2_impl.nullabilitySuffix;
-
-    // DOWN(Null, T2)
-    if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreNull) {
-      // * Null if Null <: T2
-      // * Never otherwise
-      if (isSubtypeOf2(nullNone, T2)) {
-        return nullNone;
-      } else {
-        return NeverTypeImpl.instance;
-      }
-    }
-
-    // DOWN(T1, Null)
-    if (T2_nullability == NullabilitySuffix.none && T2.isDartCoreNull) {
-      // * Null if Null <: T1
-      // * Never otherwise
-      if (isSubtypeOf2(nullNone, T1)) {
-        return nullNone;
-      } else {
-        return NeverTypeImpl.instance;
-      }
-    }
-
-    var T1_isObject = isObject(T1);
-    var T2_isObject = isObject(T2);
-
-    // DOWN(T1, T2) where OBJECT(T1) and OBJECT(T2)
-    if (T1_isObject && T2_isObject) {
-      // * T1 if MORETOP(T2, T1)
-      // * T2 otherwise
-      if (isMoreTop(T2, T1)) {
-        return T1;
-      } else {
-        return T2;
-      }
-    }
-
-    // DOWN(T1, T2) where OBJECT(T1)
-    if (T1_isObject) {
-      // * T2 if T2 is non-nullable
-      if (isNonNullable(T2)) {
-        return T2;
-      }
-
-      // * NonNull(T2) if NonNull(T2) is non-nullable
-      var T2_nonNull = promoteToNonNull(T2_impl);
-      if (isNonNullable(T2_nonNull)) {
-        return T2_nonNull;
-      }
-
-      // * Never otherwise
-      return NeverTypeImpl.instance;
-    }
-
-    // DOWN(T1, T2) where OBJECT(T2)
-    if (T2_isObject) {
-      // * T1 if T1 is non-nullable
-      if (isNonNullable(T1)) {
-        return T1;
-      }
-
-      // * NonNull(T1) if NonNull(T1) is non-nullable
-      var T1_nonNull = promoteToNonNull(T1_impl);
-      if (isNonNullable(T1_nonNull)) {
-        return T1_nonNull;
-      }
-
-      // * Never otherwise
-      return NeverTypeImpl.instance;
-    }
-
-    // DOWN(T1*, T2*) = S* where S is DOWN(T1, T2)
-    // DOWN(T1*, T2?) = S* where S is DOWN(T1, T2)
-    // DOWN(T1?, T2*) = S* where S is DOWN(T1, T2)
-    // DOWN(T1*, T2) = S where S is DOWN(T1, T2)
-    // DOWN(T1, T2*) = S where S is DOWN(T1, T2)
-    // DOWN(T1?, T2?) = S? where S is DOWN(T1, T2)
-    // DOWN(T1?, T2) = S where S is DOWN(T1, T2)
-    // DOWN(T1, T2?) = S where S is DOWN(T1, T2)
-    if (T1_nullability != NullabilitySuffix.none ||
-        T2_nullability != NullabilitySuffix.none) {
-      var resultNullability = NullabilitySuffix.question;
-      if (T1_nullability == NullabilitySuffix.none ||
-          T2_nullability == NullabilitySuffix.none) {
-        resultNullability = NullabilitySuffix.none;
-      } else if (T1_nullability == NullabilitySuffix.star ||
-          T2_nullability == NullabilitySuffix.star) {
-        resultNullability = NullabilitySuffix.star;
-      }
-      var T1_none = T1_impl.withNullability(NullabilitySuffix.none);
-      var T2_none = T2_impl.withNullability(NullabilitySuffix.none);
-      var S = getGreatestLowerBound(T1_none, T2_none);
-      return (S as TypeImpl).withNullability(resultNullability);
-    }
-
-    assert(T1_nullability == NullabilitySuffix.none);
-    assert(T2_nullability == NullabilitySuffix.none);
-
-    // TODO(scheglov) incomplete
-    if (T1 is FunctionType && T2 is FunctionType) {
-      return _functionGreatestLowerBound(T1, T2);
-    }
-
-    // DOWN(T1, T2) = T1 if T1 <: T2
-    if (isSubtypeOf2(T1, T2)) {
-      return T1;
-    }
-
-    // DOWN(T1, T2) = T2 if T2 <: T1
-    if (isSubtypeOf2(T2, T1)) {
-      return T2;
-    }
-
-    // DOWN(T1, T2) = Never otherwise
-    return NeverTypeImpl.instance;
+    return _greatestLowerBoundHelper.getGreatestLowerBound(T1, T2);
   }
 
   /**
@@ -2082,240 +657,7 @@
    */
   @override
   DartType getLeastUpperBound(DartType T1, DartType T2) {
-    // UP(T, T) = T
-    if (identical(T1, T2)) {
-      return T1;
-    }
-
-    // For any type T, UP(?, T) == T.
-    if (identical(T1, UnknownInferredType.instance)) {
-      return T2;
-    }
-    if (identical(T2, UnknownInferredType.instance)) {
-      return T1;
-    }
-
-    var T1_isTop = isTop(T1);
-    var T2_isTop = isTop(T2);
-
-    // UP(T1, T2) where TOP(T1) and TOP(T2)
-    if (T1_isTop && T2_isTop) {
-      // * T1 if MORETOP(T1, T2)
-      // * T2 otherwise
-      if (isMoreTop(T1, T2)) {
-        return T1;
-      } else {
-        return T2;
-      }
-    }
-
-    // UP(T1, T2) = T1 if TOP(T1)
-    if (T1_isTop) {
-      return T1;
-    }
-
-    // UP(T1, T2) = T2 if TOP(T2)
-    if (T2_isTop) {
-      return T2;
-    }
-
-    var T1_isBottom = isBottom(T1);
-    var T2_isBottom = isBottom(T2);
-
-    // UP(T1, T2) where BOTTOM(T1) and BOTTOM(T2)
-    if (T1_isBottom && T2_isBottom) {
-      // * T2 if MOREBOTTOM(T1, T2)
-      // * T1 otherwise
-      if (isMoreBottom(T1, T2)) {
-        return T2;
-      } else {
-        return T1;
-      }
-    }
-
-    // UP(T1, T2) = T2 if BOTTOM(T1)
-    if (T1_isBottom) {
-      return T2;
-    }
-
-    // UP(T1, T2) = T1 if BOTTOM(T2)
-    if (T2_isBottom) {
-      return T1;
-    }
-
-    var T1_isNull = isNull(T1);
-    var T2_isNull = isNull(T2);
-
-    // UP(T1, T2) where NULL(T1) and NULL(T2)
-    if (T1_isNull && T2_isNull) {
-      // * T2 if MOREBOTTOM(T1, T2)
-      // * T1 otherwise
-      if (isMoreBottom(T1, T2)) {
-        return T2;
-      } else {
-        return T1;
-      }
-    }
-
-    var T1_impl = T1 as TypeImpl;
-    var T2_impl = T2 as TypeImpl;
-
-    var T1_nullability = T1_impl.nullabilitySuffix;
-    var T2_nullability = T2_impl.nullabilitySuffix;
-
-    // UP(T1, T2) where NULL(T1)
-    if (T1_isNull) {
-      // * T2 if T2 is nullable
-      // * T2* if Null <: T2 or T1 <: Object (that is, T1 or T2 is legacy)
-      // * T2? otherwise
-      if (isNullable(T2)) {
-        return T2;
-      } else if (T1_nullability == NullabilitySuffix.star ||
-          T2_nullability == NullabilitySuffix.star) {
-        return T2_impl.withNullability(NullabilitySuffix.star);
-      } else {
-        return makeNullable(T2);
-      }
-    }
-
-    // UP(T1, T2) where NULL(T2)
-    if (T2_isNull) {
-      // * T1 if T1 is nullable
-      // * T1* if Null <: T1 or T2 <: Object (that is, T1 or T2 is legacy)
-      // * T1? otherwise
-      if (isNullable(T1)) {
-        return T1;
-      } else if (T1_nullability == NullabilitySuffix.star ||
-          T2_nullability == NullabilitySuffix.star) {
-        return T1_impl.withNullability(NullabilitySuffix.star);
-      } else {
-        return makeNullable(T1);
-      }
-    }
-
-    var T1_isObject = isObject(T1);
-    var T2_isObject = isObject(T2);
-
-    // UP(T1, T2) where OBJECT(T1) and OBJECT(T2)
-    if (T1_isObject && T2_isObject) {
-      // * T1 if MORETOP(T1, T2)
-      // * T2 otherwise
-      if (isMoreTop(T1, T2)) {
-        return T1;
-      } else {
-        return T2;
-      }
-    }
-
-    // UP(T1, T2) where OBJECT(T1)
-    if (T1_isObject) {
-      // * T1 if T2 is non-nullable
-      // * T1? otherwise
-      if (isNonNullable(T2)) {
-        return T1;
-      } else {
-        return makeNullable(T1);
-      }
-    }
-
-    // UP(T1, T2) where OBJECT(T2)
-    if (T2_isObject) {
-      // * T2 if T1 is non-nullable
-      // * T2? otherwise
-      if (isNonNullable(T1)) {
-        return T2;
-      } else {
-        return makeNullable(T2);
-      }
-    }
-
-    // UP(T1*, T2*) = S* where S is UP(T1, T2)
-    // UP(T1*, T2?) = S? where S is UP(T1, T2)
-    // UP(T1?, T2*) = S? where S is UP(T1, T2)
-    // UP(T1*, T2) = S* where S is UP(T1, T2)
-    // UP(T1, T2*) = S* where S is UP(T1, T2)
-    // UP(T1?, T2?) = S? where S is UP(T1, T2)
-    // UP(T1?, T2) = S? where S is UP(T1, T2)
-    // UP(T1, T2?) = S? where S is UP(T1, T2)
-    if (T1_nullability != NullabilitySuffix.none ||
-        T2_nullability != NullabilitySuffix.none) {
-      var resultNullability = NullabilitySuffix.none;
-      if (T1_nullability == NullabilitySuffix.question ||
-          T2_nullability == NullabilitySuffix.question) {
-        resultNullability = NullabilitySuffix.question;
-      } else if (T1_nullability == NullabilitySuffix.star ||
-          T2_nullability == NullabilitySuffix.star) {
-        resultNullability = NullabilitySuffix.star;
-      }
-      var T1_none = T1_impl.withNullability(NullabilitySuffix.none);
-      var T2_none = T2_impl.withNullability(NullabilitySuffix.none);
-      var S = getLeastUpperBound(T1_none, T2_none);
-      return (S as TypeImpl).withNullability(resultNullability);
-    }
-
-    assert(T1_nullability == NullabilitySuffix.none);
-    assert(T2_nullability == NullabilitySuffix.none);
-
-    // UP(X1 extends B1, T2)
-    // UP(X1 & B1, T2)
-    if (T1 is TypeParameterType) {
-      // T2 if X1 <: T2
-      if (isSubtypeOf2(T1, T2)) {
-        return T2;
-      }
-      // otherwise X1 if T2 <: X1
-      if (isSubtypeOf2(T2, T1)) {
-        return T1;
-      }
-      // otherwise UP(B1[Object/X1], T2)
-      var T1_toObject = _typeParameterResolveToObjectBounds(T1);
-      return getLeastUpperBound(T1_toObject, T2);
-    }
-
-    // UP(T1, X2 extends B2)
-    // UP(T1, X2 & B2)
-    if (T2 is TypeParameterType) {
-      // X2 if T1 <: X2
-      if (isSubtypeOf2(T1, T2)) {
-        // TODO(scheglov) How to get here?
-        return T2;
-      }
-      // otherwise T1 if X2 <: T1
-      if (isSubtypeOf2(T2, T1)) {
-        return T1;
-      }
-      // otherwise UP(T1, B2[Object/X2])
-      var T2_toObject = _typeParameterResolveToObjectBounds(T2);
-      return getLeastUpperBound(T1, T2_toObject);
-    }
-
-    // UP(T Function<...>(...), Function) = Function
-    if (T1 is FunctionType && T2.isDartCoreFunction) {
-      return T2;
-    }
-
-    // UP(Function, T Function<...>(...)) = Function
-    if (T1.isDartCoreFunction && T2 is FunctionType) {
-      return T1;
-    }
-
-    // UP(T Function<...>(...), S Function<...>(...)) = Function
-    // And other, more interesting variants.
-    if (T1 is FunctionType && T2 is FunctionType) {
-      return _functionLeastUpperBound(T1, T2);
-    }
-
-    // UP(T Function<...>(...), T2) = Object
-    // UP(T1, T Function<...>(...)) = Object
-    if (T1 is FunctionType || T2 is FunctionType) {
-      return objectNone;
-    }
-
-    // UP(T1, T2) = T2 if T1 <: T2
-    // UP(T1, T2) = T1 if T2 <: T1
-    // And other, more complex variants of interface types.
-    var helper = InterfaceLeastUpperBoundHelper(this);
-    return helper.compute(T1, T2);
+    return _leastUpperBoundHelper.getLeastUpperBound(T1, T2);
   }
 
   /// Returns the greatest closure of the given type [schema] with respect to `?`.
@@ -2954,282 +1296,22 @@
     return false;
   }
 
-  /// Check if [_T0] is a subtype of [_T1].
+  /// Check if [leftType] is a subtype of [rightType].
   ///
   /// Implements:
-  /// https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md#rules
+  /// https://github.com/dart-lang/language
+  /// See `resources/type-system/subtyping.md`
   @override
-  bool isSubtypeOf(DartType _T0, DartType _T1) {
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
     if (!NullSafetyUnderstandingFlag.isEnabled) {
-      _T0 = NullabilityEliminator.perform(typeProvider, _T0);
-      _T1 = NullabilityEliminator.perform(typeProvider, _T1);
+      leftType = NullabilityEliminator.perform(typeProvider, leftType);
+      rightType = NullabilityEliminator.perform(typeProvider, rightType);
     }
-    return isSubtypeOf2(_T0, _T1);
+    return isSubtypeOf2(leftType, rightType);
   }
 
-  bool isSubtypeOf2(DartType _T0, DartType _T1) {
-    // Reflexivity: if `T0` and `T1` are the same type then `T0 <: T1`.
-    if (identical(_T0, _T1)) {
-      return true;
-    }
-
-    // `?` is treated as a top and a bottom type during inference.
-    if (identical(_T0, UnknownInferredType.instance) ||
-        identical(_T1, UnknownInferredType.instance)) {
-      return true;
-    }
-
-    var T0 = _T0 as TypeImpl;
-    var T1 = _T1 as TypeImpl;
-
-    var T1_nullability = T1.nullabilitySuffix;
-    var T0_nullability = T0.nullabilitySuffix;
-
-    // Right Top: if `T1` is a top type (i.e. `dynamic`, or `void`, or
-    // `Object?`) then `T0 <: T1`.
-    if (identical(T1, DynamicTypeImpl.instance) ||
-        identical(T1, VoidTypeImpl.instance) ||
-        T1_nullability == NullabilitySuffix.question && T1.isDartCoreObject) {
-      return true;
-    }
-
-    // Left Top: if `T0` is `dynamic` or `void`,
-    //   then `T0 <: T1` if `Object? <: T1`.
-    if (identical(T0, DynamicTypeImpl.instance) ||
-        identical(T0, VoidTypeImpl.instance)) {
-      if (isSubtypeOf2(objectQuestion, T1)) {
-        return true;
-      }
-    }
-
-    // Left Bottom: if `T0` is `Never`, then `T0 <: T1`.
-    if (identical(T0, NeverTypeImpl.instance)) {
-      return true;
-    }
-
-    // Right Object: if `T1` is `Object` then:
-    if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreObject) {
-      // * if `T0` is an unpromoted type variable with bound `B`,
-      //   then `T0 <: T1` iff `B <: Object`.
-      // * if `T0` is a promoted type variable `X & S`,
-      //   then `T0 <: T1` iff `S <: Object`.
-      if (T0_nullability == NullabilitySuffix.none &&
-          T0 is TypeParameterTypeImpl) {
-        var S = T0.promotedBound;
-        var B = T0.element.bound;
-        if (S == null && B != null) {
-          return isSubtypeOf2(B, objectNone);
-        }
-        if (S != null) {
-          return isSubtypeOf2(S, objectNone);
-        }
-      }
-      // * if `T0` is `FutureOr<S>` for some `S`,
-      //   then `T0 <: T1` iff `S <: Object`
-      if (T0_nullability == NullabilitySuffix.none &&
-          T0 is InterfaceTypeImpl &&
-          T0.isDartAsyncFutureOr) {
-        return isSubtypeOf2(T0.typeArguments[0], T1);
-      }
-      // * if `T0` is `S*` for any `S`, then `T0 <: T1` iff `S <: T1`
-      if (T0_nullability == NullabilitySuffix.star) {
-        return isSubtypeOf2(
-          T0.withNullability(NullabilitySuffix.none),
-          T1,
-        );
-      }
-      // * if `T0` is `Null`, `dynamic`, `void`, or `S?` for any `S`,
-      //   then the subtyping does not hold, the result is false.
-      if (T0_nullability == NullabilitySuffix.none && T0.isDartCoreNull ||
-          identical(T0, DynamicTypeImpl.instance) ||
-          identical(T0, VoidTypeImpl.instance) ||
-          T0_nullability == NullabilitySuffix.question) {
-        return false;
-      }
-      // Otherwise `T0 <: T1` is true.
-      return true;
-    }
-
-    // Left Null: if `T0` is `Null` then:
-    if (T0_nullability == NullabilitySuffix.none && T0.isDartCoreNull) {
-      // * If `T1` is `FutureOr<S>` for some `S`, then the query is true iff
-      // `Null <: S`.
-      if (T1_nullability == NullabilitySuffix.none &&
-          T1 is InterfaceTypeImpl &&
-          T1.isDartAsyncFutureOr) {
-        var S = T1.typeArguments[0];
-        return isSubtypeOf2(nullNone, S);
-      }
-      // If `T1` is `Null`, `S?` or `S*` for some `S`, then the query is true.
-      if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreNull ||
-          T1_nullability == NullabilitySuffix.question ||
-          T1_nullability == NullabilitySuffix.star) {
-        return true;
-      }
-      // * if `T1` is a type variable (promoted or not) the query is false
-      if (T1 is TypeParameterTypeImpl) {
-        return false;
-      }
-      // Otherwise, the query is false.
-      return false;
-    }
-
-    // Left Legacy if `T0` is `S0*` then:
-    if (T0_nullability == NullabilitySuffix.star) {
-      // * `T0 <: T1` iff `S0 <: T1`.
-      var S0 = T0.withNullability(NullabilitySuffix.none);
-      return isSubtypeOf2(S0, T1);
-    }
-
-    // Right Legacy `T1` is `S1*` then:
-    //   * `T0 <: T1` iff `T0 <: S1?`.
-    if (T1_nullability == NullabilitySuffix.star) {
-      if (T1 is FunctionType && _isFunctionTypeWithNamedRequired(T0)) {
-        T1 = _functionTypeWithNamedRequired(T1 as FunctionType);
-      }
-      var S1 = T1.withNullability(NullabilitySuffix.question);
-      return isSubtypeOf2(T0, S1);
-    }
-
-    // Left FutureOr: if `T0` is `FutureOr<S0>` then:
-    if (T0_nullability == NullabilitySuffix.none &&
-        T0 is InterfaceTypeImpl &&
-        T0.isDartAsyncFutureOr) {
-      var S0 = T0.typeArguments[0];
-      // * `T0 <: T1` iff `Future<S0> <: T1` and `S0 <: T1`
-      if (isSubtypeOf2(S0, T1)) {
-        var FutureS0 = typeProvider.futureElement.instantiate(
-          typeArguments: [S0],
-          nullabilitySuffix: NullabilitySuffix.none,
-        );
-        return isSubtypeOf2(FutureS0, T1);
-      }
-      return false;
-    }
-
-    // Left Nullable: if `T0` is `S0?` then:
-    //   * `T0 <: T1` iff `S0 <: T1` and `Null <: T1`.
-    if (T0_nullability == NullabilitySuffix.question) {
-      var S0 = T0.withNullability(NullabilitySuffix.none);
-      return isSubtypeOf2(S0, T1) && isSubtypeOf2(nullNone, T1);
-    }
-
-    // Type Variable Reflexivity 1: if T0 is a type variable X0 or a promoted
-    // type variables X0 & S0 and T1 is X0 then:
-    //   * T0 <: T1
-    if (T0 is TypeParameterTypeImpl &&
-        T1 is TypeParameterTypeImpl &&
-        T1.promotedBound == null &&
-        T0.element == T1.element) {
-      return true;
-    }
-
-    // Right Promoted Variable: if `T1` is a promoted type variable `X1 & S1`:
-    //   * `T0 <: T1` iff `T0 <: X1` and `T0 <: S1`
-    if (T1 is TypeParameterTypeImpl && T1.promotedBound != null) {
-      var X1 = TypeParameterTypeImpl(
-        element: T1.element,
-        nullabilitySuffix: T1.nullabilitySuffix,
-      );
-      return isSubtypeOf2(T0, X1) && isSubtypeOf2(T0, T1.promotedBound);
-    }
-
-    // Right FutureOr: if `T1` is `FutureOr<S1>` then:
-    if (T1_nullability == NullabilitySuffix.none &&
-        T1 is InterfaceTypeImpl &&
-        T1.isDartAsyncFutureOr) {
-      var S1 = T1.typeArguments[0];
-      // `T0 <: T1` iff any of the following hold:
-      // * either `T0 <: Future<S1>`
-      var FutureS1 = typeProvider.futureElement.instantiate(
-        typeArguments: [S1],
-        nullabilitySuffix: NullabilitySuffix.none,
-      );
-      if (isSubtypeOf2(T0, FutureS1)) {
-        return true;
-      }
-      // * or `T0 <: S1`
-      if (isSubtypeOf2(T0, S1)) {
-        return true;
-      }
-      // * or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
-      // * or `T0` is `X0 & S0` and `S0 <: T1`
-      if (T0 is TypeParameterTypeImpl) {
-        var S0 = T0.promotedBound;
-        if (S0 != null && isSubtypeOf2(S0, T1)) {
-          return true;
-        }
-        var B0 = T0.element.bound;
-        if (B0 != null && isSubtypeOf2(B0, T1)) {
-          return true;
-        }
-      }
-      // iff
-      return false;
-    }
-
-    // Right Nullable: if `T1` is `S1?` then:
-    if (T1_nullability == NullabilitySuffix.question) {
-      var S1 = T1.withNullability(NullabilitySuffix.none);
-      // `T0 <: T1` iff any of the following hold:
-      // * either `T0 <: S1`
-      if (isSubtypeOf2(T0, S1)) {
-        return true;
-      }
-      // * or `T0 <: Null`
-      if (isSubtypeOf2(T0, nullNone)) {
-        return true;
-      }
-      // or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
-      // or `T0` is `X0 & S0` and `S0 <: T1`
-      if (T0 is TypeParameterTypeImpl) {
-        var S0 = T0.promotedBound;
-        if (S0 != null && isSubtypeOf2(S0, T1)) {
-          return true;
-        }
-        var B0 = T0.element.bound;
-        if (B0 != null && isSubtypeOf2(B0, T1)) {
-          return true;
-        }
-      }
-      // iff
-      return false;
-    }
-
-    // Super-Interface: `T0` is an interface type with super-interfaces
-    // `S0,...Sn`:
-    //   * and `Si <: T1` for some `i`.
-    if (T0 is InterfaceTypeImpl && T1 is InterfaceTypeImpl) {
-      return _isInterfaceSubtypeOf(T0, T1, null);
-    }
-
-    // Left Promoted Variable: `T0` is a promoted type variable `X0 & S0`
-    //   * and `S0 <: T1`
-    // Left Type Variable Bound: `T0` is a type variable `X0` with bound `B0`
-    //   * and `B0 <: T1`
-    if (T0 is TypeParameterTypeImpl) {
-      var S0 = T0.promotedBound;
-      if (S0 != null && isSubtypeOf2(S0, T1)) {
-        return true;
-      }
-
-      var B0 = T0.element.bound;
-      if (B0 != null && isSubtypeOf2(B0, T1)) {
-        return true;
-      }
-    }
-
-    if (T0 is FunctionTypeImpl) {
-      // Function Type/Function: `T0` is a function type and `T1` is `Function`.
-      if (T1.isDartCoreFunction) {
-        return true;
-      }
-      if (T1 is FunctionTypeImpl) {
-        return _isFunctionSubtypeOf(T0, T1);
-      }
-    }
-
-    return false;
+  bool isSubtypeOf2(DartType leftType, DartType rightType) {
+    return _subtypeHelper.isSubtypeOf(leftType, rightType);
   }
 
   /// Return `true` for any type which is in the equivalence class of top types.
@@ -3322,7 +1404,9 @@
             operator == TokenType.STAR ||
             operator == TokenType.PLUS_EQ ||
             operator == TokenType.MINUS_EQ ||
-            operator == TokenType.STAR_EQ) {
+            operator == TokenType.STAR_EQ ||
+            operator == TokenType.PLUS_PLUS ||
+            operator == TokenType.MINUS_MINUS) {
           if (isNonNullableByDefault) {
             return promoteToNonNull(leftType as TypeImpl);
           }
@@ -3402,6 +1486,14 @@
     return null;
   }
 
+  void updateOptions({
+    @required bool implicitCasts,
+    @required bool strictInference,
+  }) {
+    this.implicitCasts = implicitCasts;
+    this.strictInference = strictInference;
+  }
+
   List<DartType> _defaultTypeArguments(
     List<TypeParameterElement> typeParameters,
   ) {
@@ -3410,830 +1502,6 @@
       return typeParameterImpl.defaultType;
     }).toList();
   }
-
-  /**
-   * Compute the greatest lower bound of function types [f] and [g].
-   *
-   * https://github.com/dart-lang/language
-   * See `resources/type-system/upper-lower-bounds.md`
-   */
-  DartType _functionGreatestLowerBound(FunctionType f, FunctionType g) {
-    var fTypeFormals = f.typeFormals;
-    var gTypeFormals = g.typeFormals;
-
-    // The number of type parameters must be the same.
-    // Otherwise the result is `Never`.
-    if (fTypeFormals.length != gTypeFormals.length) {
-      return NeverTypeImpl.instance;
-    }
-
-    // The bounds of type parameters must be equal.
-    // Otherwise the result is `Never`.
-    var freshTypeFormalTypes =
-        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
-    if (freshTypeFormalTypes == null) {
-      return NeverTypeImpl.instance;
-    }
-
-    var typeFormals = freshTypeFormalTypes
-        .map<TypeParameterElement>((t) => t.element)
-        .toList();
-
-    f = f.instantiate(freshTypeFormalTypes);
-    g = g.instantiate(freshTypeFormalTypes);
-
-    var fParameters = f.parameters;
-    var gParameters = g.parameters;
-
-    var parameters = <ParameterElement>[];
-    var fIndex = 0;
-    var gIndex = 0;
-    while (fIndex < fParameters.length && gIndex < gParameters.length) {
-      var fParameter = fParameters[fIndex];
-      var gParameter = gParameters[gIndex];
-      if (fParameter.isPositional) {
-        if (gParameter.isPositional) {
-          fIndex++;
-          gIndex++;
-          parameters.add(
-            ParameterElementImpl.synthetic(
-              fParameter.name,
-              getLeastUpperBound(fParameter.type, gParameter.type),
-              fParameter.isOptional || gParameter.isOptional
-                  ? ParameterKind.POSITIONAL
-                  : ParameterKind.REQUIRED,
-            ),
-          );
-        } else {
-          return NeverTypeImpl.instance;
-        }
-      } else if (fParameter.isNamed) {
-        if (gParameter.isNamed) {
-          var compareNames = fParameter.name.compareTo(gParameter.name);
-          if (compareNames == 0) {
-            fIndex++;
-            gIndex++;
-            parameters.add(
-              ParameterElementImpl.synthetic(
-                fParameter.name,
-                getLeastUpperBound(fParameter.type, gParameter.type),
-                fParameter.isRequiredNamed && gParameter.isRequiredNamed
-                    ? ParameterKind.NAMED_REQUIRED
-                    : ParameterKind.NAMED,
-              ),
-            );
-          } else if (compareNames < 0) {
-            fIndex++;
-            parameters.add(
-              ParameterElementImpl.synthetic(
-                fParameter.name,
-                fParameter.type,
-                ParameterKind.NAMED,
-              ),
-            );
-          } else {
-            assert(compareNames > 0);
-            gIndex++;
-            parameters.add(
-              ParameterElementImpl.synthetic(
-                gParameter.name,
-                gParameter.type,
-                ParameterKind.NAMED,
-              ),
-            );
-          }
-        } else {
-          return NeverTypeImpl.instance;
-        }
-      }
-    }
-
-    while (fIndex < fParameters.length) {
-      var fParameter = fParameters[fIndex++];
-      if (fParameter.isPositional) {
-        parameters.add(
-          ParameterElementImpl.synthetic(
-            fParameter.name,
-            fParameter.type,
-            ParameterKind.POSITIONAL,
-          ),
-        );
-      } else {
-        assert(fParameter.isNamed);
-        parameters.add(
-          ParameterElementImpl.synthetic(
-            fParameter.name,
-            fParameter.type,
-            ParameterKind.NAMED,
-          ),
-        );
-      }
-    }
-
-    while (gIndex < gParameters.length) {
-      var gParameter = gParameters[gIndex++];
-      if (gParameter.isPositional) {
-        parameters.add(
-          ParameterElementImpl.synthetic(
-            gParameter.name,
-            gParameter.type,
-            ParameterKind.POSITIONAL,
-          ),
-        );
-      } else {
-        assert(gParameter.isNamed);
-        parameters.add(
-          ParameterElementImpl.synthetic(
-            gParameter.name,
-            gParameter.type,
-            ParameterKind.NAMED,
-          ),
-        );
-      }
-    }
-
-    var returnType = getGreatestLowerBound(f.returnType, g.returnType);
-
-    return FunctionTypeImpl(
-      typeFormals: typeFormals,
-      parameters: parameters,
-      returnType: returnType,
-      nullabilitySuffix: NullabilitySuffix.none,
-    );
-  }
-
-  /**
-   * Compute the least upper bound of function types [f] and [g].
-   *
-   * https://github.com/dart-lang/language
-   * See `resources/type-system/upper-lower-bounds.md`
-   */
-  DartType _functionLeastUpperBound(FunctionType f, FunctionType g) {
-    var fTypeFormals = f.typeFormals;
-    var gTypeFormals = g.typeFormals;
-
-    // The number of type parameters must be the same.
-    // Otherwise the result is `Function`.
-    if (fTypeFormals.length != gTypeFormals.length) {
-      return _interfaceTypeFunctionNone;
-    }
-
-    // The bounds of type parameters must be equal.
-    // Otherwise the result is `Function`.
-    var freshTypeFormalTypes =
-        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
-    if (freshTypeFormalTypes == null) {
-      return _interfaceTypeFunctionNone;
-    }
-
-    var typeFormals = freshTypeFormalTypes
-        .map<TypeParameterElement>((t) => t.element)
-        .toList();
-
-    f = f.instantiate(freshTypeFormalTypes);
-    g = g.instantiate(freshTypeFormalTypes);
-
-    var fParameters = f.parameters;
-    var gParameters = g.parameters;
-
-    var parameters = <ParameterElement>[];
-    var fIndex = 0;
-    var gIndex = 0;
-    while (fIndex < fParameters.length && gIndex < gParameters.length) {
-      var fParameter = fParameters[fIndex];
-      var gParameter = gParameters[gIndex];
-      if (fParameter.isRequiredPositional) {
-        if (gParameter.isRequiredPositional) {
-          fIndex++;
-          gIndex++;
-          parameters.add(
-            ParameterElementImpl.synthetic(
-              fParameter.name,
-              getGreatestLowerBound(fParameter.type, gParameter.type),
-              ParameterKind.REQUIRED,
-            ),
-          );
-        } else {
-          break;
-        }
-      } else if (fParameter.isOptionalPositional) {
-        if (gParameter.isOptionalPositional) {
-          fIndex++;
-          gIndex++;
-          parameters.add(
-            ParameterElementImpl.synthetic(
-              fParameter.name,
-              getGreatestLowerBound(fParameter.type, gParameter.type),
-              ParameterKind.POSITIONAL,
-            ),
-          );
-        } else {
-          break;
-        }
-      } else if (fParameter.isNamed) {
-        if (gParameter.isNamed) {
-          var compareNames = fParameter.name.compareTo(gParameter.name);
-          if (compareNames == 0) {
-            fIndex++;
-            gIndex++;
-            parameters.add(
-              ParameterElementImpl.synthetic(
-                fParameter.name,
-                getGreatestLowerBound(fParameter.type, gParameter.type),
-                fParameter.isRequiredNamed || gParameter.isRequiredNamed
-                    ? ParameterKind.NAMED_REQUIRED
-                    : ParameterKind.NAMED,
-              ),
-            );
-          } else if (compareNames < 0) {
-            if (fParameter.isRequiredNamed) {
-              // We cannot skip required named.
-              return _interfaceTypeFunctionNone;
-            } else {
-              fIndex++;
-            }
-          } else {
-            assert(compareNames > 0);
-            if (gParameter.isRequiredNamed) {
-              // We cannot skip required named.
-              return _interfaceTypeFunctionNone;
-            } else {
-              gIndex++;
-            }
-          }
-        } else {
-          break;
-        }
-      }
-    }
-
-    while (fIndex < fParameters.length) {
-      var fParameter = fParameters[fIndex++];
-      if (fParameter.isNotOptional) {
-        return _interfaceTypeFunctionNone;
-      }
-    }
-
-    while (gIndex < gParameters.length) {
-      var gParameter = gParameters[gIndex++];
-      if (gParameter.isNotOptional) {
-        return _interfaceTypeFunctionNone;
-      }
-    }
-
-    var returnType = getLeastUpperBound(f.returnType, g.returnType);
-
-    return FunctionTypeImpl(
-      typeFormals: typeFormals,
-      parameters: parameters,
-      returnType: returnType,
-      nullabilitySuffix: NullabilitySuffix.none,
-    );
-  }
-
-  /// Check that [f] is a subtype of [g].
-  bool _isFunctionSubtypeOf(FunctionType f, FunctionType g) {
-    var fTypeFormals = f.typeFormals;
-    var gTypeFormals = g.typeFormals;
-
-    // The number of type parameters must be the same.
-    if (fTypeFormals.length != gTypeFormals.length) {
-      return false;
-    }
-
-    // The bounds of type parameters must be equal.
-    var freshTypeFormalTypes =
-        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) {
-      return isSubtypeOf2(t, s) && isSubtypeOf2(s, t);
-    });
-    if (freshTypeFormalTypes == null) {
-      return false;
-    }
-
-    f = f.instantiate(freshTypeFormalTypes);
-    g = g.instantiate(freshTypeFormalTypes);
-
-    if (!isSubtypeOf2(f.returnType, g.returnType)) {
-      return false;
-    }
-
-    var fParameters = f.parameters;
-    var gParameters = g.parameters;
-
-    var fIndex = 0;
-    var gIndex = 0;
-    while (fIndex < fParameters.length && gIndex < gParameters.length) {
-      var fParameter = fParameters[fIndex];
-      var gParameter = gParameters[gIndex];
-      if (fParameter.isRequiredPositional) {
-        if (gParameter.isRequiredPositional) {
-          if (isSubtypeOf2(gParameter.type, fParameter.type)) {
-            fIndex++;
-            gIndex++;
-          } else {
-            return false;
-          }
-        } else {
-          return false;
-        }
-      } else if (fParameter.isOptionalPositional) {
-        if (gParameter.isPositional) {
-          if (isSubtypeOf2(gParameter.type, fParameter.type)) {
-            fIndex++;
-            gIndex++;
-          } else {
-            return false;
-          }
-        } else {
-          return false;
-        }
-      } else if (fParameter.isNamed) {
-        if (gParameter.isNamed) {
-          var compareNames = fParameter.name.compareTo(gParameter.name);
-          if (compareNames == 0) {
-            var gIsRequiredOrLegacy = gParameter.isRequiredNamed ||
-                g.nullabilitySuffix == NullabilitySuffix.star;
-            if (fParameter.isRequiredNamed && !gIsRequiredOrLegacy) {
-              return false;
-            } else if (isSubtypeOf2(gParameter.type, fParameter.type)) {
-              fIndex++;
-              gIndex++;
-            } else {
-              return false;
-            }
-          } else if (compareNames < 0) {
-            if (fParameter.isRequiredNamed) {
-              return false;
-            } else {
-              fIndex++;
-            }
-          } else {
-            assert(compareNames > 0);
-            // The subtype must accept all parameters of the supertype.
-            return false;
-          }
-        } else {
-          break;
-        }
-      }
-    }
-
-    // The supertype must provide all required parameters to the subtype.
-    while (fIndex < fParameters.length) {
-      var fParameter = fParameters[fIndex++];
-      if (fParameter.isNotOptional) {
-        return false;
-      }
-    }
-
-    // The subtype must accept all parameters of the supertype.
-    assert(fIndex == fParameters.length);
-    if (gIndex < gParameters.length) {
-      return false;
-    }
-
-    return true;
-  }
-
-  bool _isInterfaceSubtypeOf(
-      InterfaceType i1, InterfaceType i2, Set<ClassElement> visitedTypes) {
-    // Note: we should never reach `_isInterfaceSubtypeOf` with `i2 == Object`,
-    // because top types are eliminated before `isSubtypeOf` calls this.
-    if (identical(i1, i2) || i2.isObject) {
-      return true;
-    }
-
-    // Object cannot subtype anything but itself (handled above).
-    if (i1.isObject) {
-      return false;
-    }
-
-    ClassElement i1Element = i1.element;
-    if (i1Element == i2.element) {
-      List<DartType> tArgs1 = i1.typeArguments;
-      List<DartType> tArgs2 = i2.typeArguments;
-      List<TypeParameterElement> tParams = i1Element.typeParameters;
-
-      assert(tArgs1.length == tArgs2.length);
-      assert(tParams.length == tArgs1.length);
-
-      for (int i = 0; i < tArgs1.length; i++) {
-        DartType t1 = tArgs1[i];
-        DartType t2 = tArgs2[i];
-
-        // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
-        // variance is added to the interface.
-        Variance variance = (tParams[i] as TypeParameterElementImpl).variance;
-        if (variance.isCovariant) {
-          if (!isSubtypeOf2(t1, t2)) {
-            return false;
-          }
-        } else if (variance.isContravariant) {
-          if (!isSubtypeOf2(t2, t1)) {
-            return false;
-          }
-        } else if (variance.isInvariant) {
-          if (!isSubtypeOf2(t1, t2) || !isSubtypeOf2(t2, t1)) {
-            return false;
-          }
-        } else {
-          throw StateError('Type parameter ${tParams[i]} has unknown '
-              'variance $variance for subtype checking.');
-        }
-      }
-      return true;
-    }
-
-    // Classes types cannot subtype `Function` or vice versa.
-    if (i1.isDartCoreFunction || i2.isDartCoreFunction) {
-      return false;
-    }
-
-    // Guard against loops in the class hierarchy.
-    //
-    // Dart 2 does not allow multiple implementations of the same generic type
-    // with different type arguments. So we can track just the class element
-    // to find cycles, rather than tracking the full interface type.
-    visitedTypes ??= HashSet<ClassElement>();
-    if (!visitedTypes.add(i1Element)) return false;
-
-    InterfaceType superclass = i1.superclass;
-    if (superclass != null &&
-        _isInterfaceSubtypeOf(superclass, i2, visitedTypes)) {
-      return true;
-    }
-
-    for (final parent in i1.interfaces) {
-      if (_isInterfaceSubtypeOf(parent, i2, visitedTypes)) {
-        return true;
-      }
-    }
-
-    for (final parent in i1.mixins) {
-      if (_isInterfaceSubtypeOf(parent, i2, visitedTypes)) {
-        return true;
-      }
-    }
-
-    if (i1Element.isMixin) {
-      for (final parent in i1.superclassConstraints) {
-        if (_isInterfaceSubtypeOf(parent, i2, visitedTypes)) {
-          return true;
-        }
-      }
-    }
-
-    return false;
-  }
-
-  DartType _typeParameterResolveToObjectBounds(DartType type) {
-    var element = type.element;
-    type = type.resolveToBound(typeProvider.objectType);
-    return Substitution.fromMap({element: typeProvider.objectType})
-        .substituteType(type);
-  }
-
-  static FunctionTypeImpl _functionTypeWithNamedRequired(FunctionType type) {
-    return FunctionTypeImpl(
-      typeFormals: type.typeFormals,
-      parameters: type.parameters.map((e) {
-        if (e.isNamed) {
-          return ParameterElementImpl.synthetic(
-            e.name,
-            e.type,
-            ParameterKind.NAMED_REQUIRED,
-          );
-        } else {
-          return e;
-        }
-      }).toList(growable: false),
-      returnType: type.returnType,
-      nullabilitySuffix: type.nullabilitySuffix,
-    );
-  }
-
-  static bool _isFunctionTypeWithNamedRequired(DartType type) {
-    if (type is FunctionType) {
-      return type.parameters.any((e) => e.isRequiredNamed);
-    }
-    return false;
-  }
-}
-
-/// A type that is being inferred but is not currently known.
-///
-/// This type will only appear in a downward inference context for type
-/// parameters that we do not know yet. Notationally it is written `?`, for
-/// example `List<?>`. This is distinct from `List<dynamic>`. These types will
-/// never appear in the final resolved AST.
-class UnknownInferredType extends TypeImpl {
-  static final UnknownInferredType instance = UnknownInferredType._();
-
-  UnknownInferredType._() : super(UnknownInferredTypeElement.instance);
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool get isDynamic => true;
-
-  @Deprecated('Check element, or use getDisplayString()')
-  @override
-  String get name => Keyword.DYNAMIC.lexeme;
-
-  @override
-  NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.star;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeUnknownInferredType();
-  }
-
-  @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    // In theory this should never happen, since we only need to do this
-    // replacement when checking super-boundedness of explicitly-specified
-    // types, or types produced by mixin inference or instantiate-to-bounds, and
-    // the unknown type can't occur in any of those cases.
-    assert(
-        false, 'Attempted to check super-boundedness of a type including "?"');
-    // But just in case it does, behave similar to `dynamic`.
-    if (isCovariant) {
-      return typeProvider.nullType;
-    } else {
-      return this;
-    }
-  }
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-
-  @override
-  TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
-
-  /// Given a [type] T, return true if it does not have an unknown type `?`.
-  static bool isKnown(DartType type) => !isUnknown(type);
-
-  /// Given a [type] T, return true if it has an unknown type `?`.
-  static bool isUnknown(DartType type) {
-    if (identical(type, UnknownInferredType.instance)) {
-      return true;
-    }
-    if (type is InterfaceTypeImpl) {
-      return type.typeArguments.any(isUnknown);
-    }
-    if (type is FunctionType) {
-      return isUnknown(type.returnType) ||
-          type.parameters.any((p) => isUnknown(p.type));
-    }
-    return false;
-  }
-}
-
-/// The synthetic element for [UnknownInferredType].
-class UnknownInferredTypeElement extends ElementImpl
-    implements TypeDefiningElement {
-  static final UnknownInferredTypeElement instance =
-      UnknownInferredTypeElement._();
-
-  UnknownInferredTypeElement._() : super(Keyword.DYNAMIC.lexeme, -1) {
-    setModifier(Modifier.SYNTHETIC, true);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.DYNAMIC;
-
-  @override
-  UnknownInferredType get type => UnknownInferredType.instance;
-
-  @override
-  T accept<T>(ElementVisitor visitor) => null;
-}
-
-/// A constraint on a type parameter that we're inferring.
-class _TypeConstraint extends _TypeRange {
-  /// The type parameter that is constrained by [lowerBound] or [upperBound].
-  final TypeParameterElement typeParameter;
-
-  /// Where this constraint comes from, used for error messages.
-  ///
-  /// See [toString].
-  final _TypeConstraintOrigin origin;
-
-  _TypeConstraint(this.origin, this.typeParameter,
-      {DartType upper, DartType lower})
-      : super(upper: upper, lower: lower);
-
-  _TypeConstraint.fromExtends(
-      TypeParameterElement element, DartType extendsType,
-      {@required bool isNonNullableByDefault})
-      : this(
-            _TypeConstraintFromExtendsClause(
-              element,
-              extendsType,
-              isNonNullableByDefault: isNonNullableByDefault,
-            ),
-            element,
-            upper: extendsType);
-
-  bool get isDownwards => origin is! _TypeConstraintFromArgument;
-
-  bool isSatisifedBy(TypeSystemImpl ts, DartType type) =>
-      ts.isSubtypeOf2(lowerBound, type) && ts.isSubtypeOf2(type, upperBound);
-
-  /// Converts this constraint to a message suitable for a type inference error.
-  @override
-  String toString() => !identical(upperBound, UnknownInferredType.instance)
-      ? "'$typeParameter' must extend '$upperBound'"
-      : "'$lowerBound' must extend '$typeParameter'";
-}
-
-class _TypeConstraintFromArgument extends _TypeConstraintOrigin {
-  final DartType argumentType;
-  final DartType parameterType;
-  final String parameterName;
-  final ClassElement genericClass;
-
-  _TypeConstraintFromArgument(
-      this.argumentType, this.parameterType, this.parameterName,
-      {this.genericClass, @required bool isNonNullableByDefault})
-      : super(isNonNullableByDefault: isNonNullableByDefault);
-
-  @override
-  formatError() {
-    // TODO(jmesserly): we should highlight the span. That would be more useful.
-    // However in summary code it doesn't look like the AST node with span is
-    // available.
-    String prefix;
-    if (genericClass != null &&
-        (genericClass.name == "List" || genericClass.name == "Map") &&
-        genericClass.library.isDartCore == true) {
-      // This will become:
-      //     "List element"
-      //     "Map key"
-      //     "Map value"
-      prefix = "${genericClass.name} $parameterName";
-    } else {
-      prefix = "Parameter '$parameterName'";
-    }
-
-    return [
-      prefix,
-      "declared as     '${_typeStr(parameterType)}'",
-      "but argument is '${_typeStr(argumentType)}'."
-    ];
-  }
-}
-
-class _TypeConstraintFromExtendsClause extends _TypeConstraintOrigin {
-  final TypeParameterElement typeParam;
-  final DartType extendsType;
-
-  _TypeConstraintFromExtendsClause(this.typeParam, this.extendsType,
-      {@required bool isNonNullableByDefault})
-      : super(isNonNullableByDefault: isNonNullableByDefault);
-
-  @override
-  formatError() {
-    return [
-      "Type parameter '${typeParam.name}'",
-      "declared to extend '${_typeStr(extendsType)}'."
-    ];
-  }
-}
-
-class _TypeConstraintFromFunctionContext extends _TypeConstraintOrigin {
-  final DartType contextType;
-  final DartType functionType;
-
-  _TypeConstraintFromFunctionContext(this.functionType, this.contextType,
-      {@required bool isNonNullableByDefault})
-      : super(isNonNullableByDefault: isNonNullableByDefault);
-
-  @override
-  formatError() {
-    return [
-      "Function type",
-      "declared as '${_typeStr(functionType)}'",
-      "used where  '${_typeStr(contextType)}' is required."
-    ];
-  }
-}
-
-class _TypeConstraintFromReturnType extends _TypeConstraintOrigin {
-  final DartType contextType;
-  final DartType declaredType;
-
-  _TypeConstraintFromReturnType(this.declaredType, this.contextType,
-      {@required bool isNonNullableByDefault})
-      : super(isNonNullableByDefault: isNonNullableByDefault);
-
-  @override
-  formatError() {
-    return [
-      "Return type",
-      "declared as '${_typeStr(declaredType)}'",
-      "used where  '${_typeStr(contextType)}' is required."
-    ];
-  }
-}
-
-/// The origin of a type constraint, for the purposes of producing a human
-/// readable error message during type inference as well as determining whether
-/// the constraint was used to fix the type parameter or not.
-abstract class _TypeConstraintOrigin {
-  final bool isNonNullableByDefault;
-
-  _TypeConstraintOrigin({@required this.isNonNullableByDefault});
-
-  List<String> formatError();
-
-  String _typeStr(DartType type) {
-    return type.getDisplayString(withNullability: isNonNullableByDefault);
-  }
-}
-
-class _TypeRange {
-  /// The upper bound of the type parameter. In other words, T <: upperBound.
-  ///
-  /// In Dart this can be written as `<T extends UpperBoundType>`.
-  ///
-  /// In inference, this can happen as a result of parameters of function type.
-  /// For example, consider a signature like:
-  ///
-  ///     T reduce<T>(List<T> values, T f(T x, T y));
-  ///
-  /// and a call to it like:
-  ///
-  ///     reduce(values, (num x, num y) => ...);
-  ///
-  /// From the function expression's parameters, we conclude `T <: num`. We may
-  /// still be able to conclude a different [lower] based on `values` or
-  /// the type of the elided `=> ...` body. For example:
-  ///
-  ///      reduce(['x'], (num x, num y) => 'hi');
-  ///
-  /// Here the [lower] will be `String` and the upper bound will be `num`,
-  /// which cannot be satisfied, so this is ill typed.
-  final DartType upperBound;
-
-  /// The lower bound of the type parameter. In other words, lowerBound <: T.
-  ///
-  /// This kind of constraint cannot be expressed in Dart, but it applies when
-  /// we're doing inference. For example, consider a signature like:
-  ///
-  ///     T pickAtRandom<T>(T x, T y);
-  ///
-  /// and a call to it like:
-  ///
-  ///     pickAtRandom(1, 2.0)
-  ///
-  /// when we see the first parameter is an `int`, we know that `int <: T`.
-  /// When we see `double` this implies `double <: T`.
-  /// Combining these constraints results in a lower bound of `num`.
-  ///
-  /// In general, we choose the lower bound as our inferred type, so we can
-  /// offer the most constrained (strongest) result type.
-  final DartType lowerBound;
-
-  _TypeRange({DartType lower, DartType upper})
-      : lowerBound = lower ?? UnknownInferredType.instance,
-        upperBound = upper ?? UnknownInferredType.instance;
-
-  /// Formats the typeRange as a string suitable for unit testing.
-  ///
-  /// For example, if [typeName] is 'T' and the range has bounds int and Object
-  /// respectively, the returned string will be 'int <: T <: Object'.
-  @visibleForTesting
-  String format(String typeName, {@required bool withNullability}) {
-    String typeStr(DartType type) {
-      return type.getDisplayString(withNullability: withNullability);
-    }
-
-    var lowerString = identical(lowerBound, UnknownInferredType.instance)
-        ? ''
-        : '${typeStr(lowerBound)} <: ';
-    var upperString = identical(upperBound, UnknownInferredType.instance)
-        ? ''
-        : ' <: ${typeStr(upperBound)}';
-    return '$lowerString$typeName$upperString';
-  }
-
-  @override
-  String toString() => format('(type)', withNullability: true);
 }
 
 class _TypeVariableEliminator extends Substitution {
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index b0e1884..7ea5feb 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -59,7 +59,6 @@
 
   analysisOptions.hint = false;
   analysisOptions.lint = options.enableLints;
-  analysisOptions.generateSdkErrors = options.showSdkWarnings;
   analysisOptions.enableTiming = options.enableTiming;
   analysisOptions.lintRules = options.enabledLints?.toList(growable: false);
   return analysisOptions;
@@ -85,9 +84,6 @@
   /// The path to the package root.
   String packageRootPath;
 
-  /// Whether to show SDK warnings.
-  bool showSdkWarnings = false;
-
   /// Whether to use Dart's Strong Mode analyzer.
   bool strongMode = true;
 
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 93ca7de..783cf74 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -17,14 +17,20 @@
 import 'package:analyzer/file_system/file_system.dart' as file_system;
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/constant/compute.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/constant/potentially_constant.dart';
+import 'package:analyzer/src/dart/constant/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/error/lint_codes.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisErrorInfo, AnalysisErrorInfoImpl, AnalysisOptions;
+    show
+        AnalysisErrorInfo,
+        AnalysisErrorInfoImpl,
+        AnalysisOptions,
+        AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/resolver.dart'
     show ConstantVerifier, ScopedVisitor;
 import 'package:analyzer/src/generated/source.dart' show LineInfo;
@@ -239,15 +245,15 @@
 
   TypeSystem get typeSystem;
 
-  /// Return `true` if it would be valid for the given instance creation
-  /// [expression] to have a keyword of `const`.
+  /// Return `true` if it would be valid for the given [expression] to have
+  /// a keyword of `const`.
   ///
   /// The [expression] is expected to be a node within one of the compilation
   /// units in [allUnits].
   ///
   /// Note that this method can cause constant evaluation to occur, which can be
   /// computationally expensive.
-  bool canBeConst(InstanceCreationExpression expression);
+  bool canBeConst(Expression expression);
 
   /// Return `true` if it would be valid for the given constructor declaration
   /// [node] to have a keyword of `const`.
@@ -307,30 +313,14 @@
   );
 
   @override
-  bool canBeConst(InstanceCreationExpression expression) {
-    //
-    // Verify that the invoked constructor is a const constructor.
-    //
-    ConstructorElement element = expression.staticElement;
-    if (element == null || !element.isConst) {
+  bool canBeConst(Expression expression) {
+    if (expression is InstanceCreationExpression) {
+      return _canBeConstInstanceCreation(expression);
+    } else if (expression is TypedLiteral) {
+      return _canBeConstTypedLiteral(expression);
+    } else {
       return false;
     }
-
-    // Ensure that dependencies (e.g. default parameter values) are computed.
-    ConstructorElementImpl implElement = element.declaration;
-    implElement.computeConstantDependencies();
-
-    //
-    // Verify that the evaluation of the constructor would not produce an
-    // exception.
-    //
-    Token oldKeyword = expression.keyword;
-    try {
-      expression.keyword = KeywordToken(Keyword.CONST, expression.offset);
-      return !_hasConstantVerifierError(expression);
-    } finally {
-      expression.keyword = oldKeyword;
-    }
   }
 
   @override
@@ -423,11 +413,57 @@
     return const LinterNameInScopeResolutionResult._none();
   }
 
+  bool _canBeConstInstanceCreation(InstanceCreationExpression node) {
+    //
+    // Verify that the invoked constructor is a const constructor.
+    //
+    ConstructorElement element = node.staticElement;
+    if (element == null || !element.isConst) {
+      return false;
+    }
+
+    // Ensure that dependencies (e.g. default parameter values) are computed.
+    ConstructorElementImpl implElement = element.declaration;
+    implElement.computeConstantDependencies();
+
+    //
+    // Verify that the evaluation of the constructor would not produce an
+    // exception.
+    //
+    Token oldKeyword = node.keyword;
+    try {
+      node.keyword = KeywordToken(Keyword.CONST, node.offset);
+      return !_hasConstantVerifierError(node);
+    } finally {
+      node.keyword = oldKeyword;
+    }
+  }
+
+  bool _canBeConstTypedLiteral(TypedLiteral node) {
+    Token oldKeyword = node.constKeyword;
+    try {
+      node.constKeyword = KeywordToken(Keyword.CONST, node.offset);
+      return !_hasConstantVerifierError(node);
+    } finally {
+      node.constKeyword = oldKeyword;
+    }
+  }
+
   /// Return `true` if [ConstantVerifier] reports an error for the [node].
   bool _hasConstantVerifierError(AstNode node) {
     var unitElement = currentUnit.unit.declaredElement;
     var libraryElement = unitElement.library;
 
+    var dependenciesFinder = ConstantExpressionsDependenciesFinder();
+    node.accept(dependenciesFinder);
+    computeConstants(
+      typeProvider,
+      typeSystem,
+      declaredVariables,
+      dependenciesFinder.dependencies.toList(),
+      (analysisOptions as AnalysisOptionsImpl).experimentStatus,
+    );
+
     var listener = ConstantAnalysisErrorListener();
     var errorReporter = ErrorReporter(
       listener,
@@ -592,6 +628,12 @@
     }
   }
 
+  void reportLintForOffset(int offset, int length,
+      {List<Object> arguments = const [], ErrorCode errorCode}) {
+    reporter.reportErrorForOffset(
+        errorCode ?? lintCode, offset, length, arguments);
+  }
+
   void reportLintForToken(Token token,
       {List<Object> arguments = const [],
       ErrorCode errorCode,
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 2294207..a97325c 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -3645,6 +3645,148 @@
   String toString() => convert.json.encode(toJson());
 }
 
+class CiderUnitErrorsBuilder extends Object
+    with _CiderUnitErrorsMixin
+    implements idl.CiderUnitErrors {
+  List<AnalysisDriverUnitErrorBuilder> _errors;
+  List<int> _signature;
+
+  @override
+  List<AnalysisDriverUnitErrorBuilder> get errors =>
+      _errors ??= <AnalysisDriverUnitErrorBuilder>[];
+
+  set errors(List<AnalysisDriverUnitErrorBuilder> value) {
+    this._errors = value;
+  }
+
+  @override
+  List<int> get signature => _signature ??= <int>[];
+
+  /// The hash signature of this data.
+  set signature(List<int> value) {
+    assert(value == null || value.every((e) => e >= 0));
+    this._signature = value;
+  }
+
+  CiderUnitErrorsBuilder(
+      {List<AnalysisDriverUnitErrorBuilder> errors, List<int> signature})
+      : _errors = errors,
+        _signature = signature;
+
+  /// Flush [informative] data recursively.
+  void flushInformative() {
+    _errors?.forEach((b) => b.flushInformative());
+  }
+
+  /// Accumulate non-[informative] data into [signature].
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._signature == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._signature.length);
+      for (var x in this._signature) {
+        signature.addInt(x);
+      }
+    }
+    if (this._errors == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._errors.length);
+      for (var x in this._errors) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder), "CUEr");
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_errors;
+    fb.Offset offset_signature;
+    if (!(_errors == null || _errors.isEmpty)) {
+      offset_errors =
+          fbBuilder.writeList(_errors.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_signature == null || _signature.isEmpty)) {
+      offset_signature = fbBuilder.writeListUint32(_signature);
+    }
+    fbBuilder.startTable();
+    if (offset_errors != null) {
+      fbBuilder.addOffset(1, offset_errors);
+    }
+    if (offset_signature != null) {
+      fbBuilder.addOffset(0, offset_signature);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+idl.CiderUnitErrors readCiderUnitErrors(List<int> buffer) {
+  fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
+  return const _CiderUnitErrorsReader().read(rootRef, 0);
+}
+
+class _CiderUnitErrorsReader extends fb.TableReader<_CiderUnitErrorsImpl> {
+  const _CiderUnitErrorsReader();
+
+  @override
+  _CiderUnitErrorsImpl createObject(fb.BufferContext bc, int offset) =>
+      _CiderUnitErrorsImpl(bc, offset);
+}
+
+class _CiderUnitErrorsImpl extends Object
+    with _CiderUnitErrorsMixin
+    implements idl.CiderUnitErrors {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _CiderUnitErrorsImpl(this._bc, this._bcOffset);
+
+  List<idl.AnalysisDriverUnitError> _errors;
+  List<int> _signature;
+
+  @override
+  List<idl.AnalysisDriverUnitError> get errors {
+    _errors ??= const fb.ListReader<idl.AnalysisDriverUnitError>(
+            _AnalysisDriverUnitErrorReader())
+        .vTableGet(_bc, _bcOffset, 1, const <idl.AnalysisDriverUnitError>[]);
+    return _errors;
+  }
+
+  @override
+  List<int> get signature {
+    _signature ??=
+        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
+    return _signature;
+  }
+}
+
+abstract class _CiderUnitErrorsMixin implements idl.CiderUnitErrors {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (errors.isNotEmpty) {
+      _result["errors"] = errors.map((_value) => _value.toJson()).toList();
+    }
+    if (signature.isNotEmpty) {
+      _result["signature"] = signature;
+    }
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "errors": errors,
+        "signature": signature,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
 class CiderUnlinkedUnitBuilder extends Object
     with _CiderUnlinkedUnitMixin
     implements idl.CiderUnlinkedUnit {
@@ -16831,10 +16973,18 @@
 class LinkedNodeTypeSubstitutionBuilder extends Object
     with _LinkedNodeTypeSubstitutionMixin
     implements idl.LinkedNodeTypeSubstitution {
+  bool _isLegacy;
   List<LinkedNodeTypeBuilder> _typeArguments;
   List<int> _typeParameters;
 
   @override
+  bool get isLegacy => _isLegacy ??= false;
+
+  set isLegacy(bool value) {
+    this._isLegacy = value;
+  }
+
+  @override
   List<LinkedNodeTypeBuilder> get typeArguments =>
       _typeArguments ??= <LinkedNodeTypeBuilder>[];
 
@@ -16851,8 +17001,11 @@
   }
 
   LinkedNodeTypeSubstitutionBuilder(
-      {List<LinkedNodeTypeBuilder> typeArguments, List<int> typeParameters})
-      : _typeArguments = typeArguments,
+      {bool isLegacy,
+      List<LinkedNodeTypeBuilder> typeArguments,
+      List<int> typeParameters})
+      : _isLegacy = isLegacy,
+        _typeArguments = typeArguments,
         _typeParameters = typeParameters;
 
   /// Flush [informative] data recursively.
@@ -16878,6 +17031,7 @@
         x?.collectApiSignature(signature);
       }
     }
+    signature.addBool(this._isLegacy == true);
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
@@ -16891,6 +17045,9 @@
       offset_typeParameters = fbBuilder.writeListUint32(_typeParameters);
     }
     fbBuilder.startTable();
+    if (_isLegacy == true) {
+      fbBuilder.addBool(2, true);
+    }
     if (offset_typeArguments != null) {
       fbBuilder.addOffset(1, offset_typeArguments);
     }
@@ -16919,10 +17076,17 @@
 
   _LinkedNodeTypeSubstitutionImpl(this._bc, this._bcOffset);
 
+  bool _isLegacy;
   List<idl.LinkedNodeType> _typeArguments;
   List<int> _typeParameters;
 
   @override
+  bool get isLegacy {
+    _isLegacy ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
+    return _isLegacy;
+  }
+
+  @override
   List<idl.LinkedNodeType> get typeArguments {
     _typeArguments ??=
         const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
@@ -16943,6 +17107,9 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (isLegacy != false) {
+      _result["isLegacy"] = isLegacy;
+    }
     if (typeArguments.isNotEmpty) {
       _result["typeArguments"] =
           typeArguments.map((_value) => _value.toJson()).toList();
@@ -16955,6 +17122,7 @@
 
   @override
   Map<String, Object> toMap() => {
+        "isLegacy": isLegacy,
         "typeArguments": typeArguments,
         "typeParameters": typeParameters,
       };
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 073c2c3..cfd13d9 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1023,6 +1023,14 @@
   signature:[uint] (id: 0);
 }
 
+/// Errors for a single unit.
+table CiderUnitErrors {
+  errors:[AnalysisDriverUnitError] (id: 1);
+
+  /// The hash signature of this data.
+  signature:[uint] (id: 0);
+}
+
 /// Information about a compilation unit, contains the content hash
 /// and unlinked summary.
 table CiderUnlinkedUnit {
@@ -1211,6 +1219,8 @@
 
 /// Information about a type substitution.
 table LinkedNodeTypeSubstitution {
+  isLegacy:bool (id: 2);
+
   typeArguments:[LinkedNodeType] (id: 1);
 
   typeParameters:[uint] (id: 0);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 6c505f2..6e182ec 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -465,6 +465,20 @@
   List<int> get signature;
 }
 
+/// Errors for a single unit.
+@TopLevel('CUEr')
+abstract class CiderUnitErrors extends base.SummaryClass {
+  factory CiderUnitErrors.fromBuffer(List<int> buffer) =>
+      generated.readCiderUnitErrors(buffer);
+
+  @Id(1)
+  List<AnalysisDriverUnitError> get errors;
+
+  /// The hash signature of this data.
+  @Id(0)
+  List<int> get signature;
+}
+
 /// Information about a compilation unit, contains the content hash
 /// and unlinked summary.
 @TopLevel('CUUN')
@@ -1825,6 +1839,9 @@
 
 /// Information about a type substitution.
 abstract class LinkedNodeTypeSubstitution extends base.SummaryClass {
+  @Id(2)
+  bool get isLegacy;
+
   @Id(1)
   List<LinkedNodeType> get typeArguments;
 
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 4380c3d..461f6d3 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -131,10 +131,22 @@
   }
 
   CompilationUnit _parse(Source source) {
-    return parseString(
+    var result = parseString(
       content: source.contents.data,
       featureSet: featureSet,
       throwIfDiagnostics: false,
-    ).unit;
+    );
+
+    if (result.errors.isNotEmpty) {
+      var errorsStr = result.errors.map((e) {
+        var location = result.lineInfo.getLocation(e.offset);
+        return '${source.fullName}:$location - ${e.message}';
+      }).join('\n');
+      throw StateError(
+        'Unexpected diagnostics:\n$errorsStr',
+      );
+    }
+
+    return result.unit;
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 09fd0b0..c36c2ed 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -107,7 +107,12 @@
     var typeArguments = substitutionNode.typeArguments.map(_readType).toList();
     var substitution = Substitution.fromPairs(typeParameters, typeArguments);
 
-    return ExecutableMember.from2(element, substitution);
+    var member = ExecutableMember.from2(element, substitution);
+    if (substitutionNode.isLegacy) {
+      member = Member.legacy(member);
+    }
+
+    return member;
   }
 
   T _getElement<T extends Element>(int index) {
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 4d0c8bf..497e564 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -1478,6 +1478,7 @@
       var elementIndex = _indexOfElement(element.declaration);
       var substitution = element.substitution.map;
       var substitutionBuilder = LinkedNodeTypeSubstitutionBuilder(
+        isLegacy: element.isLegacy,
         typeParameters: substitution.keys.map(_indexOfElement).toList(),
         typeArguments: substitution.values.map(_writeType).toList(),
       );
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 4d4d3a1..374cfb3 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
@@ -18,7 +18,7 @@
 
 class LinkedElementFactory {
   final AnalysisContextImpl analysisContext;
-  final AnalysisSession analysisSession;
+  final AnalysisSessionImpl analysisSession;
   final Reference rootReference;
   final Map<String, LinkedLibraryContext> libraryMap = {};
 
@@ -150,10 +150,26 @@
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
   void removeBundle(LinkedBundleContext context) {
+    // TODO(scheglov) Use removeLibraries()
     for (var uriStr in context.libraryMap.keys) {
       libraryMap.remove(uriStr);
       rootReference.removeChild(uriStr);
     }
+
+    var classHierarchy = analysisSession.classHierarchy;
+    classHierarchy.removeOfLibraries(context.libraryMap.keys);
+  }
+
+  /// Remove libraries with the specified URIs from the reference tree, and
+  /// any session level caches.
+  void removeLibraries(List<String> uriStrList) {
+    for (var uriStr in uriStrList) {
+      libraryMap.remove(uriStr);
+      rootReference.removeChild(uriStr);
+    }
+
+    var classHierarchy = analysisSession.classHierarchy;
+    classHierarchy.removeOfLibraries(uriStrList);
   }
 
   /// Set optional informative data for the unit.
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 3682824..16af95c 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/type_system.dart';
@@ -351,6 +352,8 @@
     for (var declaration in declarations) {
       _inferDeclaration(declaration);
     }
+
+    _resetHierarchies(declarations);
   }
 
   /// This method is invoked when mixins are asked from the [element], and
@@ -388,6 +391,20 @@
     }
   }
 
+  /// When a loop is detected during mixin inference, we pretend that the list
+  /// of mixins of the class is empty. But if this happens during building a
+  /// class hierarchy, we cache such incomplete hierarchy. So, here we reset
+  /// hierarchies for all classes being linked, indiscriminately.
+  void _resetHierarchies(List<AstNode> declarations) {
+    for (var declaration in declarations) {
+      if (declaration is ClassOrMixinDeclaration) {
+        var element = declaration.declaredElement;
+        var sessionImpl = element.library.session as AnalysisSessionImpl;
+        sessionImpl.classHierarchy.remove(element);
+      }
+    }
+  }
+
   static FeatureSet _unitFeatureSet(ClassElementImpl element) {
     var unit = element.linkedNode.parent as CompilationUnit;
     return unit.featureSet;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index e1a6501..7f5b2d4 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -271,7 +271,8 @@
           checkBoolean(node.rightOperand);
           break;
         case TokenType.BANG_EQ:
-          break;
+        case TokenType.BANG_EQ_EQ:
+        case TokenType.EQ_EQ_EQ:
         case TokenType.QUESTION_QUESTION:
           break;
         default:
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 1b70ef0..65daa02 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -55,6 +55,10 @@
     return _node(search, (n) => n is CascadeExpression);
   }
 
+  CatchClause catchClause(String search) {
+    return _node(search, (n) => n is CatchClause);
+  }
+
   ClassDeclaration classDeclaration(String search) {
     return _node(search, (n) => n is ClassDeclaration);
   }
@@ -304,6 +308,10 @@
     return _node(search, (n) => n is TypeAnnotation);
   }
 
+  TypedLiteral typedLiteral(String search) {
+    return _node(search, (n) => n is TypedLiteral);
+  }
+
   TypeName typeName(String search) {
     return _node(search, (n) => n is TypeName);
   }
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 4566120..126e28a 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -27,11 +27,11 @@
 part 'stream.dart';
 
 abstract class Future<T> {
-  factory Future(computation()) {
+  factory Future(FutureOr<T> computation()) {
     throw 0;
   }
 
-  factory Future.delayed(Duration duration, [T computation()?]) {
+  factory Future.delayed(Duration duration, [FutureOr<T> computation()?]) {
     throw 0;
   }
 
@@ -175,12 +175,11 @@
     throw 0;
   }
 
-    factory LinkedHashMap.fromIterable(Iterable iterable,
+  factory LinkedHashMap.fromIterable(Iterable iterable,
       {K Function(dynamic element)? key, V Function(dynamic element)? value}) {
     throw 0;
   }
 
-
   factory LinkedHashMap.fromIterables(Iterable<K> keys, Iterable<V> values) {
     throw 0;
   }
@@ -252,6 +251,12 @@
 
 void print(Object? object) {}
 
+class ArgumentError extends Error {
+  ArgumentError([message]);
+  
+  static T checkNotNull<T>(T argument, [String, name]) => argument;
+}
+
 abstract class bool extends Object {
   external const factory bool.fromEnvironment(String name,
       {bool defaultValue: false});
@@ -521,7 +526,7 @@
   external factory String.fromCharCode(int charCode);
 
   external const factory String.fromEnvironment(String name,
-    {String defaultValue = ""});
+      {String defaultValue = ""});
 
   List<int> get codeUnits;
   bool get isEmpty => false;
@@ -579,52 +584,68 @@
     '$sdkRoot/lib/ffi/ffi.dart',
     '''
 library dart.ffi;
+
 class NativeType {
   const NativeType();
 }
+
 class Void extends NativeType {}
+
 class Int8 extends NativeType {
   const Int8();
 }
+
 class Uint8 extends NativeType {
   const Uint8();
 }
+
 class Int16 extends NativeType {
   const Int16();
 }
+
 class Uint16 extends NativeType {
   const Uint16();
 }
+
 class Int32 extends NativeType {
   const Int32();
 }
+
 class Uint32 extends NativeType {
   const Uint32();
 }
+
 class Int64 extends NativeType {
   const Int64();
 }
+
 class Uint64 extends NativeType {
   const Uint64();
 }
+
 class Float extends NativeType {
   const Float();
 }
+
 class Double extends NativeType {
   const Double();
 }
+
 class Pointer<T extends NativeType> extends NativeType {
   static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
       @DartRepresentationOf("T") Function f,
-      [Object exceptionalReturn]);
+      [Object exceptionalReturn]) {}
 }
+
 extension NativeFunctionPointer<NF extends Function>
     on Pointer<NativeFunction<NF>> {
   external DF asFunction<DF extends Function>();
 }
+
 class Struct extends NativeType {}
 
 abstract class DynamicLibrary {}
+
 extension DynamicLibraryExtension on DynamicLibrary {
   external F lookupFunction<T extends Function, F extends Function>(
       String symbolName);
@@ -646,22 +667,36 @@
       '$sdkRoot/lib/html/dart2js/html_dart2js.dart',
       '''
 library dart.dom.html;
+
 import 'dart:async';
 
 class Event {}
+
 class MouseEvent extends Event {}
+
 class FocusEvent extends Event {}
+
 class KeyEvent extends Event {}
 
 abstract class ElementStream<T extends Event> implements Stream<T> {}
 
 abstract class Element {
+  factory Element.html(String html,
+          {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) =>
+      new HtmlElement();
+
   /// Stream of `cut` events handled by this [Element].
   ElementStream<Event> get onCut => throw 0;
 
   String get id => throw 0;
 
   set id(String value) => throw 0;
+
+  DocumentFragment createFragment(String html,
+          {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) => null;
+
+  void setInnerHtml(String html,
+          {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {}
 }
 
 class HtmlElement extends Element {
@@ -682,6 +717,7 @@
   String get innerHtml {
     throw 'not the real implementation';
   }
+
   set innerHtml(String value) {
     // stuff
   }
@@ -706,7 +742,9 @@
 }
 
 class ButtonElement extends HtmlElement {
-  factory ButtonElement._() { throw new UnsupportedError("Not supported"); }
+  factory ButtonElement._() {
+    throw new UnsupportedError("Not supported");
+  }
   factory ButtonElement() => document.createElement("button");
 
   bool autofocus;
@@ -717,14 +755,22 @@
 }
 
 class HeadingElement extends HtmlElement {
-  factory HeadingElement._() { throw new UnsupportedError("Not supported"); }
+  factory HeadingElement._() {
+    throw new UnsupportedError("Not supported");
+  }
   factory HeadingElement.h1() => document.createElement("h1");
   factory HeadingElement.h2() => document.createElement("h2");
   factory HeadingElement.h3() => document.createElement("h3");
 }
 
+class ImageElement extends HtmlEment {
+  String src;
+}
+
 class InputElement extends HtmlElement {
-  factory InputElement._() { throw new UnsupportedError("Not supported"); }
+  factory InputElement._() {
+    throw new UnsupportedError("Not supported");
+  }
   factory InputElement() => document.createElement("input");
 
   String value;
@@ -732,7 +778,9 @@
 }
 
 class IFrameElement extends HtmlElement {
-  factory IFrameElement._() { throw new UnsupportedError("Not supported"); }
+  factory IFrameElement._() {
+    throw new UnsupportedError("Not supported");
+  }
   factory IFrameElement() => JS(
       'returns:IFrameElement;creates:IFrameElement;new:true',
       '#.createElement(#)',
@@ -742,16 +790,12 @@
   String src;
 }
 
-class ImageElement extends HtmlEment {
-  String src;
-}
-
 class OptionElement extends HtmlElement {
-  factory OptionElement({String data: '', String value : '', bool selected: false}) {
-  }
+  factory OptionElement(
+      {String data: '', String value: '', bool selected: false}) {}
 
-  factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
-  }
+  factory OptionElement._(
+      [String data, String value, bool defaultSelected, bool selected]) {}
 }
 
 class ScriptElement extends HtmlElement {
@@ -760,15 +804,15 @@
 }
 
 class TableSectionElement extends HtmlElement {
-
   List<TableRowElement> get rows => throw 0;
 
-  TableRowElement addRow() {
-  }
+  TableRowElement addRow() {}
 
   TableRowElement insertRow(int index) => throw 0;
 
-  factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+  factory TableSectionElement._() {
+    throw new UnsupportedError("Not supported");
+  }
 
   @Deprecated("Internal Use Only")
   external static Type get instanceRuntimeType;
@@ -778,7 +822,9 @@
 }
 
 class TemplateElement extends HtmlElement {
-  factory TemplateElement._() { throw new UnsupportedError("Not supported"); }
+  factory TemplateElement._() {
+    throw new UnsupportedError("Not supported");
+  }
   factory TemplateElement() => document.createElement("template");
 }
 
@@ -799,6 +845,21 @@
 
 class MediaElement extends Element {}
 
+class WindowBase {}
+
+class Window extends WindowBase {
+  WindowBase open(String url, String name, [String options]) => null;
+}
+
+class NodeValidator {}
+
+class NodeTreeSanitizer {}
+
+class DocumentFragment {
+  DocumentFragment.html(String html,
+          {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {}
+}
+
 dynamic JS(a, b, c, d) {}
 ''',
     )
@@ -824,7 +885,9 @@
       '$sdkRoot/lib/_internal/internal.dart',
       '''
 library dart._internal;
+
 class Symbol {}
+
 class ExternalName {
   final String name;
   const ExternalName(this.name);
@@ -881,10 +944,11 @@
   static Future<bool> isLink(String path) async => true;
   static bool isLinkSync(String path) => true;
 
-  static Future<FileSystemEntityType> type(
-    String path, {bool followLinks: true}) => throw 0;
-  static FileSystemEntityType typeSync(
-    String path, {bool followLinks: true}) => throw 0;
+  static Future<FileSystemEntityType> type(String path,
+          {bool followLinks: true}) =>
+      throw 0;
+  static FileSystemEntityType typeSync(String path, {bool followLinks: true}) =>
+      throw 0;
 }
 
 enum ProcessStartMode {
@@ -958,7 +1022,7 @@
 
 const double E = 2.718281828459045;
 const double PI = 3.1415926535897932;
-const double LN10 =  2.302585092994046;
+const double LN10 = 2.302585092994046;
 
 T min<T extends num>(T a, T b) => throw 0;
 T max<T extends num>(T a, T b) => throw 0;
@@ -1014,17 +1078,13 @@
 
   final AnalysisOptionsImpl _analysisOptions;
 
-  /**
-   * The [AnalysisContextImpl] which is used for all of the sources.
-   */
+  /// The [AnalysisContextImpl] which is used for all of the sources.
   AnalysisContextImpl _analysisContext;
 
   @override
   final List<SdkLibrary> sdkLibraries = [];
 
-  /**
-   * The cached linked bundle of the SDK.
-   */
+  /// The cached linked bundle of the SDK.
   PackageBundle _bundle;
 
   /// Optional [additionalLibraries] should have unique URIs, and paths in
@@ -1176,14 +1236,12 @@
     return null;
   }
 
-  /**
-   * Compute the bytes of the linked bundle associated with this SDK.
-   */
+  /// Compute the bytes of the linked bundle associated with this SDK.
   List<int> _computeLinkedBundleBytes() {
     List<Source> librarySources = sdkLibraries
         .map((SdkLibrary library) => mapDartUri(library.shortName))
         .toList();
-    var featureSet = FeatureSet.fromEnableFlags([]);
+    var featureSet = FeatureSet.fromEnableFlags(['non-nullable']);
     return SummaryBuilder(librarySources, context).build(
       featureSet: featureSet,
     );
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index 2699efb..894e924 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
@@ -18,9 +19,9 @@
 
   factory MockSdkElements(
     engine.AnalysisContext analysisContext,
-    NullabilitySuffix nullabilitySuffix,
+    AnalysisSessionImpl analysisSession,
   ) {
-    var builder = _MockSdkElementsBuilder(analysisContext, nullabilitySuffix);
+    var builder = _MockSdkElementsBuilder(analysisContext, analysisSession);
     var coreLibrary = builder._buildCore();
     var asyncLibrary = builder._buildAsync();
     return MockSdkElements._(coreLibrary, asyncLibrary);
@@ -31,7 +32,7 @@
 
 class _MockSdkElementsBuilder {
   final engine.AnalysisContext analysisContext;
-  final NullabilitySuffix nullabilitySuffix;
+  final AnalysisSessionImpl analysisSession;
 
   ClassElementImpl _boolElement;
   ClassElementImpl _comparableElement;
@@ -67,7 +68,10 @@
   InterfaceType _stringType;
   InterfaceType _typeType;
 
-  _MockSdkElementsBuilder(this.analysisContext, this.nullabilitySuffix);
+  _MockSdkElementsBuilder(
+    this.analysisContext,
+    this.analysisSession,
+  );
 
   ClassElementImpl get boolElement {
     if (_boolElement != null) return _boolElement;
@@ -815,11 +819,11 @@
   LibraryElementImpl _buildAsync() {
     var asyncLibrary = LibraryElementImpl(
       analysisContext,
-      null,
+      analysisSession,
       'dart.async',
       0,
       0,
-      nullabilitySuffix == NullabilitySuffix.none,
+      true,
     );
 
     var asyncUnit = CompilationUnitElementImpl();
@@ -908,11 +912,11 @@
 
     var coreLibrary = LibraryElementImpl(
       analysisContext,
-      null,
+      analysisSession,
       'dart.core',
       0,
       0,
-      nullabilitySuffix == NullabilitySuffix.none,
+      true,
     );
     coreLibrary.definingCompilationUnit = coreUnit;
 
@@ -976,7 +980,7 @@
       typeFormals: typeFormals,
       parameters: parameters,
       returnType: returnType,
-      nullabilitySuffix: nullabilitySuffix,
+      nullabilitySuffix: NullabilitySuffix.none,
     );
   }
 
@@ -1009,7 +1013,7 @@
     return InterfaceTypeImpl(
       element: element,
       typeArguments: typeArguments,
-      nullabilitySuffix: nullabilitySuffix,
+      nullabilitySuffix: NullabilitySuffix.none,
     );
   }
 
@@ -1077,7 +1081,7 @@
   TypeParameterType _typeParameterType(TypeParameterElement element) {
     return TypeParameterTypeImpl(
       element: element,
-      nullabilitySuffix: nullabilitySuffix,
+      nullabilitySuffix: NullabilitySuffix.none,
     );
   }
 }
diff --git a/pkg/analyzer/lib/src/workspace/workspace.dart b/pkg/analyzer/lib/src/workspace/workspace.dart
index 3681cdf..51b67b3 100644
--- a/pkg/analyzer/lib/src/workspace/workspace.dart
+++ b/pkg/analyzer/lib/src/workspace/workspace.dart
@@ -79,7 +79,13 @@
  */
 class WorkspaceWithDefaultAnalysisOptions {
   /**
-   * The uri for the analysis options file.
+   * The uri for the default analysis options file.
    */
   static const String uri = 'package:dart.analysis_options/default.yaml';
+
+  /**
+   *  The uri for third_party analysis options file.
+   */
+  static const String thirdPartyUri =
+      'package:dart.analysis_options/third_party.yaml';
 }
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 0c72327..a6c70c1 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.39.4
+version: 0.39.8
 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,7 +7,7 @@
   sdk: '>=2.6.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^1.0.3
+  _fe_analyzer_shared: ^3.0.0
   args: ^1.0.0
   charcode: ^1.1.0
   collection: ^1.10.1
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 9b6b82f..558b322 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1485,43 +1485,6 @@
     ]);
   }
 
-  test_isInConstInstanceCreation_restored() async {
-    // If ErrorVerifier._isInConstInstanceCreation is not properly restored on
-    // exit from visitInstanceCreationExpression, the error at (1) will be
-    // treated as a warning rather than an error.
-    await assertErrorsInCode(r'''
-class Foo<T extends num> {
-  const Foo(x, y);
-}
-const x = const Foo<int>(const Foo<int>(0, 1),
-    const <Foo<String>>[]); // (1)
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 110, 6),
-    ]);
-  }
-
-  test_isInInstanceVariableInitializer_restored() async {
-    // If ErrorVerifier._isInInstanceVariableInitializer is not properly
-    // restored on exit from visitVariableDeclaration, the error at (1)
-    // won't be detected.
-    await assertErrorsInCode(r'''
-class Foo {
-  var bar;
-  Map foo = {
-    'bar': () {
-        var _bar;
-    },
-    'bop': _foo // (1)
-  };
-  _foo() {
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 65, 4),
-      error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 89, 4),
-    ]);
-  }
-
   test_length_of_erroneous_constant() async {
     // Attempting to compute the length of constant that couldn't be evaluated
     // (due to an error) should not crash the analyzer (see dartbug.com/23383)
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index ad07280..c4efa4a 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -699,7 +699,7 @@
     MethodInvocation invocation =
         AstTestFactory.methodInvocation(left, methodName);
     _resolveNode(invocation);
-    expect(invocation.methodName.staticElement,
+    expect(invocation.methodName.staticElement.declaration,
         same(numType.getMethod(methodName)));
     _listener.assertNoErrors();
   }
@@ -883,14 +883,6 @@
     _listener.assertNoErrors();
   }
 
-  test_visitSimpleIdentifier_dynamic() async {
-    SimpleIdentifier node = AstTestFactory.identifier3("dynamic");
-    _resolveIdentifier(node);
-    expect(node.staticElement, same(_typeProvider.dynamicType.element));
-    expect(node.staticType, same(_typeProvider.typeType));
-    _listener.assertNoErrors();
-  }
-
   test_visitSimpleIdentifier_lexicalScope() async {
     SimpleIdentifier node = AstTestFactory.identifier3("i");
     VariableElementImpl element = ElementFactory.localVariableElement(node);
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 27375f7..9d932a3 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -6,13 +6,19 @@
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:meta/meta.dart';
 
 mixin ElementsTypesMixin {
+  LibraryElementImpl get testLibrary => null;
+
   InterfaceType get boolNone {
     var element = typeProvider.boolElement;
     return interfaceTypeNone(element);
@@ -157,6 +163,7 @@
     List<MethodElement> methods = const [],
   }) {
     var element = ClassElementImpl(name, 0);
+    element.enclosingElement = testLibrary;
     element.typeParameters = typeParameters;
     element.supertype = superType ?? typeProvider.objectType;
     element.interfaces = interfaces;
@@ -387,6 +394,30 @@
     );
   }
 
+  LibraryElementImpl library_({
+    @required String uriStr,
+    @required TypeSystemImpl typeSystem,
+    AnalysisContext analysisContext,
+    AnalysisSessionImpl analysisSession,
+  }) {
+    var library = LibraryElementImpl(analysisContext, analysisSession, uriStr,
+        -1, 0, typeSystem.isNonNullableByDefault);
+    library.typeSystem = typeSystem;
+    library.typeProvider = typeSystem.typeProvider;
+
+    var uri = Uri.parse(uriStr);
+    var source = _MockSource(uri);
+
+    var definingUnit = CompilationUnitElementImpl();
+    definingUnit.source = source;
+    definingUnit.librarySource = source;
+
+    definingUnit.enclosingElement = library;
+    library.definingCompilationUnit = definingUnit;
+
+    return library;
+  }
+
   InterfaceType listNone(DartType type) {
     return typeProvider.listElement.instantiate(
       typeArguments: [type],
@@ -408,6 +439,27 @@
     );
   }
 
+  InterfaceType mapNone(DartType key, DartType value) {
+    return typeProvider.mapElement.instantiate(
+      typeArguments: [key, value],
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  InterfaceType mapQuestion(DartType key, DartType value) {
+    return typeProvider.mapElement.instantiate(
+      typeArguments: [key, value],
+      nullabilitySuffix: NullabilitySuffix.question,
+    );
+  }
+
+  InterfaceType mapStar(DartType key, DartType value) {
+    return typeProvider.mapElement.instantiate(
+      typeArguments: [key, value],
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+  }
+
   MethodElement method(
     String name,
     DartType returnType, {
@@ -429,6 +481,7 @@
     List<InterfaceType> interfaces = const [],
   }) {
     var element = MixinElementImpl(name, 0);
+    element.enclosingElement = testLibrary;
     element.typeParameters = typeParameters;
     element.superclassConstraints = constraints ?? [typeProvider.objectType];
     element.interfaces = interfaces;
@@ -537,16 +590,6 @@
     return element;
   }
 
-  TypeParameterTypeImpl typeParameterType(
-    TypeParameterElement element, {
-    NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
-  }) {
-    return TypeParameterTypeImpl(
-      element: element,
-      nullabilitySuffix: nullabilitySuffix,
-    );
-  }
-
   TypeParameterTypeImpl typeParameterTypeNone(TypeParameterElement element) {
     return element.instantiate(nullabilitySuffix: NullabilitySuffix.none);
   }
@@ -560,3 +603,13 @@
     return element.instantiate(nullabilitySuffix: NullabilitySuffix.star);
   }
 }
+
+class _MockSource implements Source {
+  @override
+  final Uri uri;
+
+  _MockSource(this.uri);
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
deleted file mode 100644
index 71a877f..0000000
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisOptionsImplTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisOptionsImplTest {
-  test_resetToDefaults() {
-    // Note that this only tests options visible from the interface.
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    AnalysisOptionsImpl modifiedOptions = AnalysisOptionsImpl();
-    modifiedOptions.dart2jsHint = true;
-    modifiedOptions.disableCacheFlushing = true;
-    modifiedOptions.enabledPluginNames = ['somePackage'];
-    modifiedOptions.enableLazyAssignmentOperators = true;
-    modifiedOptions.enableTiming = true;
-    modifiedOptions.errorProcessors = [null];
-    modifiedOptions.excludePatterns = ['a'];
-    modifiedOptions.generateImplicitErrors = false;
-    modifiedOptions.generateSdkErrors = true;
-    modifiedOptions.hint = false;
-    modifiedOptions.lint = true;
-    modifiedOptions.lintRules = [null];
-    modifiedOptions.patchPaths = {
-      'dart:core': ['/dart_core.patch.dart']
-    };
-    modifiedOptions.preserveComments = false;
-    modifiedOptions.trackCacheDependencies = false;
-
-    modifiedOptions.resetToDefaults();
-
-    expect(modifiedOptions.dart2jsHint, defaultOptions.dart2jsHint);
-    expect(modifiedOptions.disableCacheFlushing,
-        defaultOptions.disableCacheFlushing);
-    expect(modifiedOptions.enabledPluginNames, isEmpty);
-    expect(modifiedOptions.enableLazyAssignmentOperators,
-        defaultOptions.enableLazyAssignmentOperators);
-    expect(modifiedOptions.enableTiming, defaultOptions.enableTiming);
-    expect(modifiedOptions.errorProcessors, defaultOptions.errorProcessors);
-    expect(modifiedOptions.excludePatterns, defaultOptions.excludePatterns);
-    expect(modifiedOptions.generateImplicitErrors,
-        defaultOptions.generateImplicitErrors);
-    expect(modifiedOptions.generateSdkErrors, defaultOptions.generateSdkErrors);
-    expect(modifiedOptions.hint, defaultOptions.hint);
-    expect(modifiedOptions.lint, defaultOptions.lint);
-    expect(modifiedOptions.lintRules, defaultOptions.lintRules);
-    expect(modifiedOptions.patchPaths, defaultOptions.patchPaths);
-    expect(modifiedOptions.preserveComments, defaultOptions.preserveComments);
-    expect(modifiedOptions.trackCacheDependencies,
-        defaultOptions.trackCacheDependencies);
-  }
-}
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 003c3b0..877c713 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -16,86 +16,102 @@
 
 @reflectiveTest
 class ErrorSuppressionTest extends DriverResolutionTest with PackageMixin {
-  String get ignoredCode => 'const_initialized_with_non_constant_value';
+  String get ignoredCode => 'unused_element';
+
+  test_does_not_ignore_errors() async {
+    await assertErrorsInCode('''
+int x = ''; // ignore: invalid_assignment
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+    ]);
+  }
+
+  test_error_cannot_be_ignored() async {
+    await assertErrorsInCode('''
+// ignore: unused_import, undefined_function
+f() => g();
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_FUNCTION, 52, 1),
+    ]);
+  }
 
   test_error_code_mismatch() async {
     await assertErrorsInCode('''
 // ignore: $ignoredCode
 int x = '';
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int _y = 0; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''', [
-      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 61, 2),
-      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 75,
-          1),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 34, 2),
+      error(HintCode.UNUSED_ELEMENT, 42, 2),
     ]);
   }
 
   test_ignore_first() async {
     await assertErrorsInCode('''
-// ignore: invalid_assignment
-int x = '';
+// ignore: unnecessary_cast
+int x = (0 as int);
 // ... but no ignore here ...
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''', [
-      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 88,
           1),
     ]);
   }
 
   test_ignore_first_trailing() async {
     await assertErrorsInCode('''
-int x = ''; // ignore: invalid_assignment
+int x = (0 as int); // ignore: unnecessary_cast
 // ... but no ignore here ...
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''', [
-      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 88,
           1),
     ]);
   }
 
   test_ignore_for_file() async {
     await assertErrorsInCode('''
-int x = '';  //INVALID_ASSIGNMENT
+int x = (0 as int); //UNNECESSARY_CAST
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-// ignore_for_file: invalid_assignment
+// ignore_for_file: unnecessary_cast
 ''', [
-      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 49,
           1),
     ]);
   }
 
   test_ignore_for_file_whitespace_variant() async {
     await assertNoErrorsInCode('''
-//ignore_for_file:   $ignoredCode , invalid_assignment
-int x = '';  //INVALID_ASSIGNMENT
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+//ignore_for_file:   $ignoredCode , unnecessary_cast
+int x = (0 as int);  //UNNECESSARY_CAST
+String _foo; //UNUSED_ELEMENT
 ''');
   }
 
   test_ignore_only_trailing() async {
     await assertNoErrorsInCode('''
-int x = ''; // ignore: invalid_assignment
+int x = (0 as int); // ignore: unnecessary_cast
 ''');
   }
 
   test_ignore_second() async {
     await assertErrorsInCode('''
-//INVALID_ASSIGNMENT
-int x = '';
+//UNNECESSARY_CAST
+int x = (0 as int);
 // ignore: $ignoredCode
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+String _foo; //UNUSED_ELEMENT
 ''', [
-      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+      error(HintCode.UNNECESSARY_CAST, 28, 8),
     ]);
   }
 
   test_ignore_second_trailing() async {
     await assertErrorsInCode('''
-//INVALID_ASSIGNMENT
-int x = '';
-const y = x; // ignore: $ignoredCode
+//UNNECESSARY_CAST
+int x = (0 as int);
+String _foo; // ignore: $ignoredCode
 ''', [
-      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+      error(HintCode.UNNECESSARY_CAST, 28, 8),
     ]);
   }
 
@@ -113,7 +129,7 @@
 
   test_ignore_upper_case() async {
     await assertNoErrorsInCode('''
-int x = ''; // ignore: INVALID_ASSIGNMENT
+int x = (0 as int); // ignore: UNNECESSARY_CAST
 ''');
   }
 
@@ -152,78 +168,111 @@
 
   test_multiple_comments() async {
     await assertErrorsInCode('''
-int x = ''; //This is the first comment...
+int x = (0 as int); //This is the first comment...
 // ignore: $ignoredCode
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+String _foo; //UNUSED_ELEMENT
 ''', [
-      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+      error(HintCode.UNNECESSARY_CAST, 9, 8),
     ]);
   }
 
   test_multiple_ignore_for_files() async {
     await assertNoErrorsInCode('''
-int x = '';  //INVALID_ASSIGNMENT
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-// ignore_for_file: invalid_assignment,$ignoredCode
+int x = (0 as int); //UNNECESSARY_CAST
+String _foo; //UNUSED_ELEMENT
+// ignore_for_file: unnecessary_cast,$ignoredCode
 ''');
   }
 
   test_multiple_ignores() async {
     await assertNoErrorsInCode('''
 int x = 3;
-// ignore: invalid_assignment, $ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// ignore: unnecessary_cast, $ignoredCode
+int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
 ''');
   }
 
   test_multiple_ignores_trailing() async {
     await assertNoErrorsInCode('''
 int x = 3;
-const String y = x; // ignore: invalid_assignment, $ignoredCode
+int _y = x as int; // ignore: unnecessary_cast, $ignoredCode
 ''');
   }
 
   test_multiple_ignores_whitespace_variant_1() async {
     await assertNoErrorsInCode('''
 int x = 3;
-//ignore:invalid_assignment,$ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+//ignore:unnecessary_cast,$ignoredCode
+int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
 ''');
   }
 
   test_multiple_ignores_whitespace_variant_2() async {
     await assertNoErrorsInCode('''
 int x = 3;
-//ignore: invalid_assignment,$ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+//ignore: unnecessary_cast,$ignoredCode
+int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
 ''');
   }
 
   test_multiple_ignores_whitespace_variant_3() async {
     await assertNoErrorsInCode('''
 int x = 3;
-// ignore: invalid_assignment,$ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// ignore: unnecessary_cast,$ignoredCode
+int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
 ''');
   }
 
   test_no_ignores() async {
     await assertErrorsInCode('''
-int x = '';  //INVALID_ASSIGNMENT
+int x = ''; //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''', [
       error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
-      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 43,
           1),
     ]);
   }
 
   test_trailing_not_above() async {
     await assertErrorsInCode('''
-int x = ''; // ignore: invalid_assignment
-int y = '';
+int x = (0 as int); // ignore: unnecessary_cast
+int y = (0 as int);
 ''', [
-      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 50, 2),
+      error(HintCode.UNNECESSARY_CAST, 57, 8),
     ]);
   }
+
+  test_undefined_function_within_flutter_can_be_ignored() async {
+    await assertErrorsInFile(
+      '/workspace/flutterlib/flutter.dart',
+      '''
+// ignore: undefined_function
+f() => g();
+''',
+      [],
+    );
+  }
+
+  test_undefined_function_within_flutter_without_ignore() async {
+    await assertErrorsInFile(
+      '/workspace/flutterlib/flutter.dart',
+      '''
+f() => g();
+''',
+      [error(StaticTypeWarningCode.UNDEFINED_FUNCTION, 7, 1)],
+    );
+  }
+
+  test_undefined_prefixed_name_within_flutter_can_be_ignored() async {
+    await assertErrorsInFile(
+      '/workspace/flutterlib/flutter.dart',
+      '''
+import 'dart:collection' as c;
+// ignore: undefined_prefixed_name
+f() => c.g;
+''',
+      [],
+    );
+  }
 }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index ba70d51..575463a 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -163,6 +163,17 @@
     expect(invocation.argumentList.arguments, hasLength(0));
   }
 
+  void test_parseConstructor_operator_name() {
+    var unit = parseCompilationUnit('class A { operator/() : super(); }',
+        errors: [
+          expectedError(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 10, 8)
+        ]);
+    var classDeclaration = unit.declarations[0] as ClassDeclaration;
+    var constructor = classDeclaration.members[0] as ConstructorDeclaration;
+    var invocation = constructor.initializers[0] as SuperConstructorInvocation;
+    expect(invocation.argumentList.arguments, hasLength(0));
+  }
+
   void test_parseField_const_late() {
     createParser('const late T f = 0;', featureSet: nonNullable);
     ClassMember member = parser.parseClassMember('C');
@@ -2714,6 +2725,28 @@
     parseCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x; }');
   }
 
+  void test_bangQuestionIndex() {
+    // http://dartbug.com/41177
+    CompilationUnit unit = parseCompilationUnit('f(dynamic a) { a!?[0]; }');
+    FunctionDeclaration funct = unit.declarations[0];
+    BlockFunctionBody body = funct.functionExpression.body;
+
+    ExpressionStatement statement = body.block.statements[0];
+    IndexExpression expression = statement.expression;
+
+    IntegerLiteral index = expression.index;
+    expect(index.value, 0);
+
+    Token question = expression.question;
+    expect(question, isNotNull);
+    expect(question.lexeme, "?");
+
+    PostfixExpression target = expression.target;
+    SimpleIdentifier identifier = target.operand;
+    expect(identifier.name, 'a');
+    expect(target.operator.lexeme, '!');
+  }
+
   void test_bangBeforeFuctionCall1() {
     // https://github.com/dart-lang/sdk/issues/39776
     var unit = parseCompilationUnit('f() { Function? f1; f1!(42); }');
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 5936dbd..fac087f 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -263,7 +263,7 @@
     ClassElementImpl derivedClass =
         ElementFactory.classElement2('Derived', ['T']);
     derivedClass.supertype =
-        futureType(typeParameterType(derivedClass.typeParameters[0]));
+        futureType(typeParameterTypeStar(derivedClass.typeParameters[0]));
     InterfaceType intType = _typeProvider.intType;
     DartType dynamicType = _typeProvider.dynamicType;
     InterfaceType derivedIntType =
@@ -307,7 +307,7 @@
     ClassElementImpl derivedClass =
         ElementFactory.classElement2('Derived', ['T']);
     derivedClass.supertype =
-        futureType(typeParameterType(derivedClass.typeParameters[0]));
+        futureType(typeParameterTypeStar(derivedClass.typeParameters[0]));
     // class A extends Derived<int> implements Derived<num> { ... }
     ClassElementImpl classA = ElementFactory.classElement(
         'A', interfaceTypeStar(derivedClass, typeArguments: [intType]));
@@ -908,16 +908,6 @@
     _listener.assertNoErrors();
   }
 
-  void test_visitSimpleIdentifier_dynamic() {
-    // "dynamic"
-    SimpleIdentifier identifier = AstTestFactory.identifier3('dynamic');
-    DynamicElementImpl element = DynamicElementImpl.instance;
-    identifier.staticElement = element;
-    identifier.staticType = _typeProvider.typeType;
-    expect(_analyze(identifier), same(_typeProvider.typeType));
-    _listener.assertNoErrors();
-  }
-
   void test_visitSimpleStringLiteral() {
     // "a"
     Expression node = _resolvedString("a");
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index f3db5e9..12c45df 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -11,7 +11,6 @@
 // ignore: deprecated_member_use_from_same_package
 import 'constant_test.dart' as constant_test;
 import 'element_resolver_test.dart' as element_resolver_test;
-import 'engine_test.dart' as engine_test;
 import 'error_suppression_test.dart' as error_suppression;
 import 'invalid_code_test.dart' as invalid_code;
 import 'issues_test.dart' as issues;
@@ -41,7 +40,6 @@
     compile_time_error_code.main();
     constant_test.main();
     element_resolver_test.main();
-    engine_test.main();
     error_suppression.main();
     invalid_code.main();
     issues.main();
diff --git a/pkg/analyzer/test/generated/test_analysis_context.dart b/pkg/analyzer/test/generated/test_analysis_context.dart
index 8d2ff9b1c..35ea5c4 100644
--- a/pkg/analyzer/test/generated/test_analysis_context.dart
+++ b/pkg/analyzer/test/generated/test_analysis_context.dart
@@ -3,9 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
+import 'package:analyzer/src/dart/element/class_hierarchy.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
@@ -16,6 +18,7 @@
   @override
   final SourceFactory sourceFactory = _MockSourceFactory();
 
+  _MockAnalysisSession _analysisSession = _MockAnalysisSession();
   AnalysisOptionsImpl _analysisOptions;
 
   TypeProvider _typeProviderLegacy;
@@ -28,12 +31,7 @@
     _analysisOptions = AnalysisOptionsImpl()
       ..contextFeatures = featureSet ?? FeatureSet.forTesting();
 
-    var sdkElements = MockSdkElements(
-      this,
-      analysisOptions.contextFeatures.isEnabled(Feature.non_nullable)
-          ? NullabilitySuffix.none
-          : NullabilitySuffix.star,
-    );
+    var sdkElements = MockSdkElements(this, _analysisSession);
 
     _typeProviderLegacy = TypeProviderImpl(
       coreLibrary: sdkElements.coreLibrary,
@@ -68,6 +66,8 @@
   @override
   AnalysisOptions get analysisOptions => _analysisOptions;
 
+  AnalysisSessionImpl get analysisSession => _analysisSession;
+
   @Deprecated('Use LibraryElement.typeProvider')
   @override
   TypeProvider get typeProvider => typeProviderLegacy;
@@ -96,11 +96,22 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   void _setLibraryTypeSystem(LibraryElementImpl libraryElement) {
-    libraryElement.typeProvider = _typeProviderLegacy;
-    libraryElement.typeSystem = _typeSystemLegacy;
+    libraryElement.typeProvider = _typeProviderNonNullableByDefault;
+    libraryElement.typeSystem = _typeSystemNonNullableByDefault;
   }
 }
 
+class _MockAnalysisSession implements AnalysisSessionImpl {
+  @override
+  final ClassHierarchy classHierarchy = ClassHierarchy();
+
+  @override
+  final InheritanceManager3 inheritanceManager = InheritanceManager3();
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
 class _MockSource implements Source {
   @override
   final Uri uri;
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index caef5dfa..8561e3c 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -3,24 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart' show astFactory;
-import 'package:analyzer/dart/ast/token.dart' show Keyword;
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
-import 'package:analyzer/src/dart/ast/token.dart' show KeywordToken;
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/least_upper_bound.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart'
-    show NonExistingSource, Source, UriKind;
-import 'package:path/path.dart' show toUri;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -30,19 +21,51 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AssignabilityTest);
-    defineReflectiveTests(ConstraintMatchingTest);
-    defineReflectiveTests(GenericFunctionInferenceTest);
-    defineReflectiveTests(GreatestLowerBoundTest);
     defineReflectiveTests(LeastUpperBoundFunctionsTest);
     defineReflectiveTests(LeastUpperBoundTest);
     defineReflectiveTests(TryPromoteToTest);
   });
 }
 
+abstract class AbstractTypeSystemNullSafetyTest with ElementsTypesMixin {
+  TestAnalysisContext analysisContext;
+
+  @override
+  LibraryElementImpl testLibrary;
+
+  @override
+  TypeProvider typeProvider;
+
+  TypeSystemImpl typeSystem;
+
+  FeatureSet get testFeatureSet {
+    return FeatureSet.forTesting(
+      additionalFeatures: [Feature.non_nullable],
+    );
+  }
+
+  void setUp() {
+    analysisContext = TestAnalysisContext(
+      featureSet: testFeatureSet,
+    );
+    typeProvider = analysisContext.typeProviderNonNullableByDefault;
+    typeSystem = analysisContext.typeSystemNonNullableByDefault;
+
+    testLibrary = library_(
+      uriStr: 'package:test/test.dart',
+      analysisSession: analysisContext.analysisSession,
+      typeSystem: typeSystem,
+    );
+  }
+}
+
 abstract class AbstractTypeSystemTest with ElementsTypesMixin {
   TestAnalysisContext analysisContext;
 
   @override
+  LibraryElementImpl testLibrary;
+
+  @override
   TypeProvider typeProvider;
 
   TypeSystemImpl typeSystem;
@@ -57,6 +80,12 @@
     );
     typeProvider = analysisContext.typeProviderLegacy;
     typeSystem = analysisContext.typeSystemLegacy;
+
+    testLibrary = library_(
+      uriStr: 'package:test/test.dart',
+      analysisSession: analysisContext.analysisSession,
+      typeSystem: typeSystem,
+    );
   }
 
   String _typeString(TypeImpl type) {
@@ -92,7 +121,6 @@
       ],
     );
 
-    var testLibrary = _testLibrary();
     B.enclosingElement = testLibrary.definingCompilationUnit;
 
     _checkIsStrictAssignableTo(
@@ -411,39 +439,12 @@
     _checkIsNotAssignableTo(type1, type2);
     _checkIsNotAssignableTo(type2, type1);
   }
-
-  /// Return a test library, in `/test.dart` file.
-  LibraryElementImpl _testLibrary() {
-    var source = _MockSource(toUri('/test.dart'));
-
-    var definingUnit = CompilationUnitElementImpl();
-    definingUnit.source = definingUnit.librarySource = source;
-
-    var testLibrary = LibraryElementImpl(
-        analysisContext, AnalysisSessionImpl(null), '', -1, 0, false);
-    testLibrary.definingCompilationUnit = definingUnit;
-    return testLibrary;
-  }
 }
 
 /**
  * Base class for testing LUB and GLB in spec and strong mode.
  */
 abstract class BoundTestBase extends AbstractTypeSystemTest {
-  void _checkGreatestLowerBound(
-      DartType type1, DartType type2, DartType expectedResult) {
-    var glb = typeSystem.getGreatestLowerBound(type1, type2);
-    expect(glb, expectedResult);
-
-    // Check that the result is a lower bound.
-    expect(typeSystem.isSubtypeOf(glb, type1), true);
-    expect(typeSystem.isSubtypeOf(glb, type2), true);
-
-    // Check for symmetry while we're at it.
-    glb = typeSystem.getGreatestLowerBound(type2, type1);
-    expect(glb, expectedResult);
-  }
-
   void _checkLeastUpperBound(DartType T1, DartType T2, DartType expected) {
     var expectedStr = _typeString(expected);
 
@@ -469,1623 +470,6 @@
 }
 
 @reflectiveTest
-class ConstraintMatchingTest extends AbstractTypeSystemTest {
-  TypeParameterType T;
-
-  @override
-  void setUp() {
-    super.setUp();
-    T = typeParameterTypeStar(
-      typeParameter('T'),
-    );
-  }
-
-  void test_function_coreFunction() {
-    _checkOrdinarySubtypeMatch(
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: stringStar,
-      ),
-      typeProvider.functionType,
-      [T],
-      covariant: true,
-    );
-  }
-
-  void test_function_parameter_types() {
-    _checkIsSubtypeMatchOf(
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: T),
-        ],
-        returnType: intStar,
-      ),
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: stringStar),
-        ],
-        returnType: intStar,
-      ),
-      [T],
-      ['String <: T'],
-      covariant: true,
-    );
-  }
-
-  void test_function_return_types() {
-    _checkIsSubtypeMatchOf(
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: T,
-      ),
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: stringStar,
-      ),
-      [T],
-      ['T <: String'],
-      covariant: true,
-    );
-  }
-
-  void test_futureOr_futureOr() {
-    _checkIsSubtypeMatchOf(
-        futureOrStar(T), futureOrStar(stringStar), [T], ['T <: String'],
-        covariant: true);
-  }
-
-  void test_futureOr_x_fail_future_branch() {
-    // FutureOr<List<T>> <: List<String> can't be satisfied because
-    // Future<List<T>> <: List<String> can't be satisfied
-    _checkIsNotSubtypeMatchOf(
-        futureOrStar(listStar(T)), listStar(stringStar), [T],
-        covariant: true);
-  }
-
-  void test_futureOr_x_fail_nonFuture_branch() {
-    // FutureOr<List<T>> <: Future<List<String>> can't be satisfied because
-    // List<T> <: Future<List<String>> can't be satisfied
-    _checkIsNotSubtypeMatchOf(
-        futureOrStar(listStar(T)), futureStar(listStar(stringStar)), [T],
-        covariant: true);
-  }
-
-  void test_futureOr_x_success() {
-    // FutureOr<T> <: Future<T> can be satisfied by T=Null.  At this point in
-    // the type inference algorithm all we figure out is that T must be a
-    // subtype of both String and Future<String>.
-    _checkIsSubtypeMatchOf(futureOrStar(T), futureStar(stringStar), [T],
-        ['T <: String', 'T <: Future<String>'],
-        covariant: true);
-  }
-
-  void test_lhs_null() {
-    // Null <: T is trivially satisfied by the constraint Null <: T.
-    _checkIsSubtypeMatchOf(nullStar, T, [T], ['Null <: T'], covariant: false);
-    // For any other type X, Null <: X is satisfied without the need for any
-    // constraints.
-    _checkOrdinarySubtypeMatch(nullStar, listStar(T), [T], covariant: false);
-    _checkOrdinarySubtypeMatch(nullStar, stringStar, [T], covariant: false);
-    _checkOrdinarySubtypeMatch(nullStar, voidNone, [T], covariant: false);
-    _checkOrdinarySubtypeMatch(nullStar, dynamicType, [T], covariant: false);
-    _checkOrdinarySubtypeMatch(nullStar, objectStar, [T], covariant: false);
-    _checkOrdinarySubtypeMatch(nullStar, nullStar, [T], covariant: false);
-    _checkOrdinarySubtypeMatch(
-      nullStar,
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: stringStar,
-      ),
-      [T],
-      covariant: false,
-    );
-  }
-
-  void test_param_on_lhs_contravariant_direct() {
-    // When doing a contravariant match, the type parameters we're trying to
-    // find types for are on the right hand side.  Is a type parameter also
-    // appears on the left hand side, there is a condition in which the
-    // constraint can be satisfied without consulting the bound of the LHS type
-    // parameter: the condition where both parameters appear at corresponding
-    // locations in the type tree.
-    //
-    // In other words, List<S> <: List<T> is satisfied provided that
-    // S <: T.
-    var S = typeParameterTypeStar(typeParameter('S'));
-    _checkIsSubtypeMatchOf(listStar(S), listStar(T), [T], ['S <: T'],
-        covariant: false);
-  }
-
-  void test_param_on_lhs_contravariant_via_bound() {
-    // When doing a contravariant match, the type parameters we're trying to
-    // find types for are on the right hand side.  Is a type parameter also
-    // appears on the left hand side, we may have to constrain the RHS type
-    // parameter using the bounds of the LHS type parameter.
-    //
-    // In other words, S <: List<T> is satisfied provided that
-    // bound(S) <: List<T>.
-    var S = typeParameterTypeStar(typeParameter(
-      'S',
-      bound: listStar(stringStar),
-    ));
-    _checkIsSubtypeMatchOf(S, listStar(T), [T], ['String <: T'],
-        covariant: false);
-  }
-
-  void test_param_on_lhs_covariant() {
-    // When doing a covariant match, the type parameters we're trying to find
-    // types for are on the left hand side.
-    _checkIsSubtypeMatchOf(T, stringStar, [T], ['T <: String'],
-        covariant: true);
-  }
-
-  void test_param_on_rhs_contravariant() {
-    // When doing a contravariant match, the type parameters we're trying to
-    // find types for are on the right hand side.
-    _checkIsSubtypeMatchOf(stringStar, T, [T], ['String <: T'],
-        covariant: false);
-  }
-
-  void test_param_on_rhs_covariant_match() {
-    // When doing a covariant match, the type parameters we're trying to find
-    // types for are on the left hand side.  If a type parameter appears on the
-    // right hand side, there is a condition in which the constraint can be
-    // satisfied: where both parameters appear at corresponding locations in the
-    // type tree.
-    //
-    // In other words, T <: S can be satisfied trivially by the constraint
-    // T <: S.
-    var S = typeParameterTypeStar(typeParameter('S'));
-    _checkIsSubtypeMatchOf(T, S, [T], ['T <: S'], covariant: true);
-  }
-
-  void test_param_on_rhs_covariant_no_match() {
-    // When doing a covariant match, the type parameters we're trying to find
-    // types for are on the left hand side.  If a type parameter appears on the
-    // right hand side, it's probable that the constraint can't be satisfied,
-    // because there is no possible type for the LHS (other than bottom)
-    // that's guaranteed to satisfy the relation for all possible assignments of
-    // the RHS type parameter.
-    //
-    // In other words, no match can be found for List<T> <: S because regardless
-    // of T, we can't guarantee that List<T> <: S for all S.
-    var S = typeParameterTypeStar(typeParameter('S'));
-    _checkIsNotSubtypeMatchOf(listStar(T), S, [T], covariant: true);
-  }
-
-  void test_related_interface_types_failure() {
-    _checkIsNotSubtypeMatchOf(iterableStar(T), listStar(stringStar), [T],
-        covariant: true);
-  }
-
-  void test_related_interface_types_success() {
-    _checkIsSubtypeMatchOf(
-        listStar(T), iterableStar(stringStar), [T], ['T <: String'],
-        covariant: true);
-  }
-
-  void test_rhs_dynamic() {
-    // T <: dynamic is trivially satisfied by the constraint T <: dynamic.
-    _checkIsSubtypeMatchOf(T, dynamicType, [T], ['T <: dynamic'],
-        covariant: true);
-    // For any other type X, X <: dynamic is satisfied without the need for any
-    // constraints.
-    _checkOrdinarySubtypeMatch(listStar(T), dynamicType, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(stringStar, dynamicType, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(voidNone, dynamicType, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(dynamicType, dynamicType, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(objectStar, dynamicType, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(nullStar, dynamicType, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: stringStar,
-      ),
-      dynamicType,
-      [T],
-      covariant: true,
-    );
-  }
-
-  void test_rhs_object() {
-    // T <: Object is trivially satisfied by the constraint T <: Object.
-    _checkIsSubtypeMatchOf(T, objectStar, [T], ['T <: Object'],
-        covariant: true);
-    // For any other type X, X <: Object is satisfied without the need for any
-    // constraints.
-    _checkOrdinarySubtypeMatch(listStar(T), objectStar, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(stringStar, objectStar, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(voidNone, objectStar, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(dynamicType, objectStar, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(objectStar, objectStar, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(nullStar, objectStar, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: stringStar,
-      ),
-      objectStar,
-      [T],
-      covariant: true,
-    );
-  }
-
-  void test_rhs_void() {
-    // T <: void is trivially satisfied by the constraint T <: void.
-    _checkIsSubtypeMatchOf(T, voidNone, [T], ['T <: void'], covariant: true);
-    // For any other type X, X <: void is satisfied without the need for any
-    // constraints.
-    _checkOrdinarySubtypeMatch(listStar(T), voidNone, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(stringStar, voidNone, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(voidNone, voidNone, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(dynamicType, voidNone, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(objectStar, voidNone, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(nullStar, voidNone, [T], covariant: true);
-    _checkOrdinarySubtypeMatch(
-      functionTypeStar(
-        parameters: [
-          requiredParameter(type: intStar),
-        ],
-        returnType: stringStar,
-      ),
-      voidNone,
-      [T],
-      covariant: true,
-    );
-  }
-
-  void test_same_interface_types() {
-    _checkIsSubtypeMatchOf(
-        listStar(T), listStar(stringStar), [T], ['T <: String'],
-        covariant: true);
-  }
-
-  void test_variance_contravariant() {
-    // class A<in T>
-    var tContravariant = typeParameter('T', variance: Variance.contravariant);
-    var tType = typeParameterType(tContravariant);
-    var A = class_(name: 'A', typeParameters: [tContravariant]);
-
-    // A<num>
-    // A<T>
-    var aNum = interfaceType(A,
-        typeArguments: [numStar], nullabilitySuffix: NullabilitySuffix.none);
-    var aT = interfaceType(A,
-        typeArguments: [tType], nullabilitySuffix: NullabilitySuffix.none);
-
-    _checkIsSubtypeMatchOf(aT, aNum, [tType], ['num <: in T'], covariant: true);
-  }
-
-  void test_variance_covariant() {
-    // class A<out T>
-    var tCovariant = typeParameter('T', variance: Variance.covariant);
-    var tType = typeParameterType(tCovariant);
-    var A = class_(name: 'A', typeParameters: [tCovariant]);
-
-    // A<num>
-    // A<T>
-    var aNum = interfaceType(A,
-        typeArguments: [numStar], nullabilitySuffix: NullabilitySuffix.none);
-    var aT = interfaceType(A,
-        typeArguments: [tType], nullabilitySuffix: NullabilitySuffix.none);
-
-    _checkIsSubtypeMatchOf(aT, aNum, [tType], ['out T <: num'],
-        covariant: true);
-  }
-
-  void test_variance_invariant() {
-    // class A<inout T>
-    var tInvariant = typeParameter('T', variance: Variance.invariant);
-    var tType = typeParameterType(tInvariant);
-    var A = class_(name: 'A', typeParameters: [tInvariant]);
-
-    // A<num>
-    // A<T>
-    var aNum = interfaceType(A,
-        typeArguments: [numStar], nullabilitySuffix: NullabilitySuffix.none);
-    var aT = interfaceType(A,
-        typeArguments: [tType], nullabilitySuffix: NullabilitySuffix.none);
-
-    _checkIsSubtypeMatchOf(
-        aT, aNum, [tType], ['inout T <: num', 'num <: inout T'],
-        covariant: true);
-  }
-
-  void test_x_futureOr_fail_both_branches() {
-    // List<T> <: FutureOr<String> can't be satisfied because neither
-    // List<T> <: Future<String> nor List<T> <: int can be satisfied
-    _checkIsNotSubtypeMatchOf(listStar(T), futureOrStar(stringStar), [T],
-        covariant: true);
-  }
-
-  void test_x_futureOr_pass_both_branches_constraints_from_both_branches() {
-    // Future<String> <: FutureOr<T> can be satisfied because both
-    // Future<String> <: Future<T> and Future<String> <: T can be satisfied.
-    // Trying to match Future<String> <: Future<T> generates the constraint
-    // String <: T, whereas trying to match Future<String> <: T generates the
-    // constraint Future<String> <: T.  We keep the constraint based on trying
-    // to match Future<String> <: Future<T>, so String <: T.
-    _checkIsSubtypeMatchOf(
-        futureStar(stringStar), futureOrStar(T), [T], ['String <: T'],
-        covariant: false);
-  }
-
-  void test_x_futureOr_pass_both_branches_constraints_from_future_branch() {
-    // Future<T> <: FutureOr<Object> can be satisfied because both
-    // Future<T> <: Future<Object> and Future<T> <: Object can be satisfied.
-    // Trying to match Future<T> <: Future<Object> generates the constraint
-    // T <: Object, whereas trying to match Future<T> <: Object generates no
-    // constraints, so we keep the constraint T <: Object.
-    _checkIsSubtypeMatchOf(
-        futureStar(T), futureOrStar(objectStar), [T], ['T <: Object'],
-        covariant: true);
-  }
-
-  void test_x_futureOr_pass_both_branches_constraints_from_nonFuture_branch() {
-    // Null <: FutureOr<T> can be satisfied because both
-    // Null <: Future<T> and Null <: T can be satisfied.
-    // Trying to match Null <: FutureOr<T> generates no constraints, whereas
-    // trying to match Null <: T generates the constraint Null <: T,
-    // so we keep the constraint Null <: T.
-    _checkIsSubtypeMatchOf(nullStar, futureOrStar(T), [T], ['Null <: T'],
-        covariant: false);
-  }
-
-  void test_x_futureOr_pass_both_branches_no_constraints() {
-    // Future<String> <: FutureOr<Object> is satisfied because both
-    // Future<String> <: Future<Object> and Future<String> <: Object.
-    // No constraints are recorded.
-    _checkIsSubtypeMatchOf(
-        futureStar(stringStar), futureOrStar(objectStar), [T], [],
-        covariant: true);
-  }
-
-  void test_x_futureOr_pass_future_branch() {
-    // Future<T> <: FutureOr<String> can be satisfied because
-    // Future<T> <: Future<String> can be satisfied
-    _checkIsSubtypeMatchOf(
-        futureStar(T), futureOrStar(stringStar), [T], ['T <: String'],
-        covariant: true);
-  }
-
-  void test_x_futureOr_pass_nonFuture_branch() {
-    // List<T> <: FutureOr<List<String>> can be satisfied because
-    // List<T> <: List<String> can be satisfied
-    _checkIsSubtypeMatchOf(
-        listStar(T), futureOrStar(listStar(stringStar)), [T], ['T <: String'],
-        covariant: true);
-  }
-
-  void _checkIsNotSubtypeMatchOf(
-      DartType t1, DartType t2, Iterable<TypeParameterType> typeFormals,
-      {bool covariant}) {
-    var inferrer = GenericInferrer(
-      typeSystem,
-      typeFormals.map((t) => t.element),
-    );
-    var success =
-        inferrer.tryMatchSubtypeOf(t1, t2, null, covariant: covariant);
-    expect(success, isFalse);
-    inferrer.constraints.forEach((typeParameter, constraintsForTypeParameter) {
-      expect(constraintsForTypeParameter, isEmpty);
-    });
-  }
-
-  void _checkIsSubtypeMatchOf(
-      DartType t1,
-      DartType t2,
-      Iterable<TypeParameterType> typeFormals,
-      Iterable<String> expectedConstraints,
-      {bool covariant}) {
-    var inferrer = GenericInferrer(
-      typeSystem,
-      typeFormals.map((t) => t.element),
-    );
-    var success =
-        inferrer.tryMatchSubtypeOf(t1, t2, null, covariant: covariant);
-    expect(success, isTrue);
-    var formattedConstraints = <String>[];
-    inferrer.constraints.forEach((typeParameter, constraintsForTypeParameter) {
-      for (var constraint in constraintsForTypeParameter) {
-        formattedConstraints.add(
-          constraint.format(
-            typeParameter.getDisplayString(
-              withNullability: typeSystem.isNonNullableByDefault,
-            ),
-            withNullability: false,
-          ),
-        );
-      }
-    });
-    expect(formattedConstraints, unorderedEquals(expectedConstraints));
-  }
-
-  void _checkOrdinarySubtypeMatch(
-      DartType t1, DartType t2, Iterable<TypeParameterType> typeFormals,
-      {bool covariant}) {
-    bool expectSuccess = typeSystem.isSubtypeOf(t1, t2);
-    if (expectSuccess) {
-      _checkIsSubtypeMatchOf(t1, t2, typeFormals, [], covariant: covariant);
-    } else {
-      _checkIsNotSubtypeMatchOf(t1, t2, typeFormals);
-    }
-  }
-}
-
-@reflectiveTest
-class GenericFunctionInferenceTest extends AbstractTypeSystemTest {
-  void test_boundedByAnotherTypeParameter() {
-    // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
-    var tFrom = typeParameter('TFrom');
-    var tTo =
-        typeParameter('TTo', bound: iterableStar(typeParameterTypeStar(tFrom)));
-    var cast = functionTypeStar(
-      typeFormals: [tFrom, tTo],
-      parameters: [
-        requiredParameter(
-          type: typeParameterTypeStar(tFrom),
-        ),
-      ],
-      returnType: typeParameterTypeStar(tTo),
-    );
-    expect(_inferCall(cast, [stringStar]),
-        [stringStar, (iterableStar(stringStar))]);
-  }
-
-  void test_boundedByOuterClass() {
-    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
-
-    // class A {}
-    var A = class_(name: 'A', superType: objectStar);
-    var typeA = interfaceTypeStar(A);
-
-    // class B extends A {}
-    var B = class_(name: 'B', superType: typeA);
-    var typeB = interfaceTypeStar(B);
-
-    // class C<T extends A> {
-    var CT = typeParameter('T', bound: typeA);
-    var C = class_(
-      name: 'C',
-      superType: objectStar,
-      typeParameters: [CT],
-    );
-    //   S m<S extends T>(S);
-    var S = typeParameter('S', bound: typeParameterTypeStar(CT));
-    var m = method(
-      'm',
-      typeParameterTypeStar(S),
-      typeFormals: [S],
-      parameters: [
-        requiredParameter(
-          name: '_',
-          type: typeParameterTypeStar(S),
-        ),
-      ],
-    );
-    C.methods = [m];
-    // }
-
-    // C<Object> cOfObject;
-    var cOfObject = interfaceTypeStar(C, typeArguments: [objectStar]);
-    // C<A> cOfA;
-    var cOfA = interfaceTypeStar(C, typeArguments: [typeA]);
-    // C<B> cOfB;
-    var cOfB = interfaceTypeStar(C, typeArguments: [typeB]);
-    // B b;
-    // cOfB.m(b); // infer <B>
-    _assertType(
-        _inferCall2(cOfB.getMethod('m').type, [typeB]), 'B Function(B)');
-    // cOfA.m(b); // infer <B>
-    _assertType(
-        _inferCall2(cOfA.getMethod('m').type, [typeB]), 'B Function(B)');
-    // cOfObject.m(b); // infer <B>
-    _assertType(
-        _inferCall2(cOfObject.getMethod('m').type, [typeB]), 'B Function(B)');
-  }
-
-  void test_boundedByOuterClassSubstituted() {
-    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
-
-    // class A {}
-    var A = class_(name: 'A', superType: objectStar);
-    var typeA = interfaceTypeStar(A);
-
-    // class B extends A {}
-    var B = class_(name: 'B', superType: typeA);
-    var typeB = interfaceTypeStar(B);
-
-    // class C<T extends A> {
-    var CT = typeParameter('T', bound: typeA);
-    var C = class_(
-      name: 'C',
-      superType: objectStar,
-      typeParameters: [CT],
-    );
-    //   S m<S extends Iterable<T>>(S);
-    var iterableOfT = iterableStar(typeParameterTypeStar(CT));
-    var S = typeParameter('S', bound: iterableOfT);
-    var m = method(
-      'm',
-      typeParameterTypeStar(S),
-      typeFormals: [S],
-      parameters: [
-        requiredParameter(
-          name: '_',
-          type: typeParameterTypeStar(S),
-        ),
-      ],
-    );
-    C.methods = [m];
-    // }
-
-    // C<Object> cOfObject;
-    var cOfObject = interfaceTypeStar(C, typeArguments: [objectStar]);
-    // C<A> cOfA;
-    var cOfA = interfaceTypeStar(C, typeArguments: [typeA]);
-    // C<B> cOfB;
-    var cOfB = interfaceTypeStar(C, typeArguments: [typeB]);
-    // List<B> b;
-    var listOfB = listStar(typeB);
-    // cOfB.m(b); // infer <B>
-    _assertType(_inferCall2(cOfB.getMethod('m').type, [listOfB]),
-        'List<B> Function(List<B>)');
-    // cOfA.m(b); // infer <B>
-    _assertType(_inferCall2(cOfA.getMethod('m').type, [listOfB]),
-        'List<B> Function(List<B>)');
-    // cOfObject.m(b); // infer <B>
-    _assertType(_inferCall2(cOfObject.getMethod('m').type, [listOfB]),
-        'List<B> Function(List<B>)');
-  }
-
-  void test_boundedRecursively() {
-    // class A<T extends A<T>>
-    var T = typeParameter('T');
-    var A = class_(
-      name: 'Cloneable',
-      superType: objectStar,
-      typeParameters: [T],
-    );
-    T.bound = interfaceTypeStar(
-      A,
-      typeArguments: [typeParameterTypeStar(T)],
-    );
-
-    // class B extends A<B> {}
-    var B = class_(name: 'B', superType: null);
-    B.supertype = interfaceTypeStar(A, typeArguments: [interfaceTypeStar(B)]);
-    var typeB = interfaceTypeStar(B);
-
-    // <S extends A<S>>
-    var S = typeParameter('S');
-    var typeS = typeParameterTypeStar(S);
-    S.bound = interfaceTypeStar(A, typeArguments: [typeS]);
-
-    // (S, S) -> S
-    var clone = functionTypeStar(
-      typeFormals: [S],
-      parameters: [
-        requiredParameter(type: typeS),
-        requiredParameter(type: typeS),
-      ],
-      returnType: typeS,
-    );
-    expect(_inferCall(clone, [typeB, typeB]), [typeB]);
-
-    // Something invalid...
-    expect(
-      _inferCall(clone, [stringStar, numStar], expectError: true),
-      [objectStar],
-    );
-  }
-
-  void test_genericCastFunction() {
-    // <TFrom, TTo>(TFrom) -> TTo
-    var tFrom = typeParameter('TFrom');
-    var tTo = typeParameter('TTo');
-    var cast = functionTypeStar(
-      typeFormals: [tFrom, tTo],
-      parameters: [
-        requiredParameter(
-          type: typeParameterTypeStar(tFrom),
-        ),
-      ],
-      returnType: typeParameterTypeStar(tTo),
-    );
-    expect(_inferCall(cast, [intStar]), [intStar, dynamicType]);
-  }
-
-  void test_genericCastFunctionWithUpperBound() {
-    // <TFrom, TTo extends TFrom>(TFrom) -> TTo
-    var tFrom = typeParameter('TFrom');
-    var tTo = typeParameter(
-      'TTo',
-      bound: typeParameterTypeStar(tFrom),
-    );
-    var cast = functionTypeStar(
-      typeFormals: [tFrom, tTo],
-      parameters: [
-        requiredParameter(
-          type: typeParameterTypeStar(tFrom),
-        ),
-      ],
-      returnType: typeParameterTypeStar(tTo),
-    );
-    expect(_inferCall(cast, [intStar]), [intStar, intStar]);
-  }
-
-  void test_parameter_contravariantUseUpperBound() {
-    // <T>(T x, void Function(T) y) -> T
-    // Generates constraints int <: T <: num.
-    // Since T is contravariant, choose num.
-    var T = typeParameter('T', variance: Variance.contravariant);
-    var tFunction = functionTypeStar(
-        parameters: [requiredParameter(type: typeParameterTypeStar(T))],
-        returnType: voidNone);
-    var numFunction = functionTypeStar(
-        parameters: [requiredParameter(type: numStar)], returnType: voidNone);
-    var function = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(type: typeParameterTypeStar(T)),
-        requiredParameter(type: tFunction)
-      ],
-      returnType: typeParameterTypeStar(T),
-    );
-
-    expect(_inferCall(function, [intStar, numFunction]), [numStar]);
-  }
-
-  void test_parameter_covariantUseLowerBound() {
-    // <T>(T x, void Function(T) y) -> T
-    // Generates constraints int <: T <: num.
-    // Since T is covariant, choose int.
-    var T = typeParameter('T', variance: Variance.covariant);
-    var tFunction = functionTypeStar(
-        parameters: [requiredParameter(type: typeParameterTypeStar(T))],
-        returnType: voidNone);
-    var numFunction = functionTypeStar(
-        parameters: [requiredParameter(type: numStar)], returnType: voidNone);
-    var function = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(type: typeParameterTypeStar(T)),
-        requiredParameter(type: tFunction)
-      ],
-      returnType: typeParameterTypeStar(T),
-    );
-
-    expect(_inferCall(function, [intStar, numFunction]), [intStar]);
-  }
-
-  void test_parametersToFunctionParam() {
-    // <T>(f(T t)) -> T
-    var T = typeParameter('T');
-    var cast = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(
-                type: typeParameterTypeStar(T),
-              ),
-            ],
-            returnType: dynamicType,
-          ),
-        ),
-      ],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(
-      _inferCall(cast, [
-        functionTypeStar(
-          parameters: [
-            requiredParameter(type: numStar),
-          ],
-          returnType: dynamicType,
-        )
-      ]),
-      [numStar],
-    );
-  }
-
-  void test_parametersUseLeastUpperBound() {
-    // <T>(T x, T y) -> T
-    var T = typeParameter('T');
-    var cast = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(type: typeParameterTypeStar(T)),
-        requiredParameter(type: typeParameterTypeStar(T)),
-      ],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(_inferCall(cast, [intStar, doubleStar]), [numStar]);
-  }
-
-  void test_parameterTypeUsesUpperBound() {
-    // <T extends num>(T) -> dynamic
-    var T = typeParameter('T', bound: numStar);
-    var f = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(type: typeParameterTypeStar(T)),
-      ],
-      returnType: dynamicType,
-    );
-    expect(_inferCall(f, [intStar]), [intStar]);
-  }
-
-  void test_returnFunctionWithGenericParameter() {
-    // <T>(T -> T) -> (T -> void)
-    var T = typeParameter('T');
-    var f = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(type: typeParameterTypeStar(T)),
-            ],
-            returnType: typeParameterTypeStar(T),
-          ),
-        ),
-      ],
-      returnType: functionTypeStar(
-        parameters: [
-          requiredParameter(type: typeParameterTypeStar(T)),
-        ],
-        returnType: voidNone,
-      ),
-    );
-    expect(
-      _inferCall(f, [
-        functionTypeStar(
-          parameters: [
-            requiredParameter(type: numStar),
-          ],
-          returnType: intStar,
-        ),
-      ]),
-      [intStar],
-    );
-  }
-
-  void test_returnFunctionWithGenericParameterAndContext() {
-    // <T>(T -> T) -> (T -> Null)
-    var T = typeParameter('T');
-    var f = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(type: typeParameterTypeStar(T)),
-            ],
-            returnType: typeParameterTypeStar(T),
-          ),
-        ),
-      ],
-      returnType: functionTypeStar(
-        parameters: [
-          requiredParameter(type: typeParameterTypeStar(T)),
-        ],
-        returnType: nullStar,
-      ),
-    );
-    expect(
-      _inferCall(
-        f,
-        [],
-        returnType: functionTypeStar(
-          parameters: [
-            requiredParameter(type: numStar),
-          ],
-          returnType: intStar,
-        ),
-      ),
-      [numStar],
-    );
-  }
-
-  void test_returnFunctionWithGenericParameterAndReturn() {
-    // <T>(T -> T) -> (T -> T)
-    var T = typeParameter('T');
-    var f = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(type: typeParameterTypeStar(T)),
-            ],
-            returnType: typeParameterTypeStar(T),
-          ),
-        ),
-      ],
-      returnType: functionTypeStar(
-        parameters: [
-          requiredParameter(type: typeParameterTypeStar(T)),
-        ],
-        returnType: typeParameterTypeStar(T),
-      ),
-    );
-    expect(
-      _inferCall(f, [
-        functionTypeStar(
-          parameters: [
-            requiredParameter(type: numStar),
-          ],
-          returnType: intStar,
-        )
-      ]),
-      [intStar],
-    );
-  }
-
-  void test_returnFunctionWithGenericReturn() {
-    // <T>(T -> T) -> (() -> T)
-    var T = typeParameter('T');
-    var f = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(type: typeParameterTypeStar(T)),
-            ],
-            returnType: typeParameterTypeStar(T),
-          ),
-        ),
-      ],
-      returnType: functionTypeStar(
-        returnType: typeParameterTypeStar(T),
-      ),
-    );
-    expect(
-      _inferCall(f, [
-        functionTypeStar(
-          parameters: [
-            requiredParameter(type: numStar),
-          ],
-          returnType: intStar,
-        )
-      ]),
-      [intStar],
-    );
-  }
-
-  void test_returnTypeFromContext() {
-    // <T>() -> T
-    var T = typeParameter('T');
-    var f = functionTypeStar(
-      typeFormals: [T],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(_inferCall(f, [], returnType: stringStar), [stringStar]);
-  }
-
-  void test_returnTypeWithBoundFromContext() {
-    // <T extends num>() -> T
-    var T = typeParameter('T', bound: numStar);
-    var f = functionTypeStar(
-      typeFormals: [T],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(_inferCall(f, [], returnType: doubleStar), [doubleStar]);
-  }
-
-  void test_returnTypeWithBoundFromInvalidContext() {
-    // <T extends num>() -> T
-    var T = typeParameter('T', bound: numStar);
-    var f = functionTypeStar(
-      typeFormals: [T],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(_inferCall(f, [], returnType: stringStar), [nullStar]);
-  }
-
-  void test_unifyParametersToFunctionParam() {
-    // <T>(f(T t), g(T t)) -> T
-    var T = typeParameter('T');
-    var cast = functionTypeStar(
-      typeFormals: [T],
-      parameters: [
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(
-                type: typeParameterTypeStar(T),
-              ),
-            ],
-            returnType: dynamicType,
-          ),
-        ),
-        requiredParameter(
-          type: functionTypeStar(
-            parameters: [
-              requiredParameter(
-                type: typeParameterTypeStar(T),
-              ),
-            ],
-            returnType: dynamicType,
-          ),
-        ),
-      ],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(
-      _inferCall(cast, [
-        functionTypeStar(
-          parameters: [
-            requiredParameter(type: intStar),
-          ],
-          returnType: dynamicType,
-        ),
-        functionTypeStar(
-          parameters: [
-            requiredParameter(type: doubleStar),
-          ],
-          returnType: dynamicType,
-        )
-      ]),
-      [nullStar],
-    );
-  }
-
-  void test_unusedReturnTypeIsDynamic() {
-    // <T>() -> T
-    var T = typeParameter('T');
-    var f = functionTypeStar(
-      typeFormals: [T],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(_inferCall(f, []), [dynamicType]);
-  }
-
-  void test_unusedReturnTypeWithUpperBound() {
-    // <T extends num>() -> T
-    var T = typeParameter('T', bound: numStar);
-    var f = functionTypeStar(
-      typeFormals: [T],
-      returnType: typeParameterTypeStar(T),
-    );
-    expect(_inferCall(f, []), [numStar]);
-  }
-
-  void _assertType(DartType type, String expected) {
-    var typeStr = type.getDisplayString(withNullability: false);
-    expect(typeStr, expected);
-  }
-
-  List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
-      {DartType returnType, bool expectError = false}) {
-    var listener = RecordingErrorListener();
-
-    var reporter = ErrorReporter(
-      listener,
-      NonExistingSource('/test.dart', toUri('/test.dart'), UriKind.FILE_URI),
-      isNonNullableByDefault: false,
-    );
-
-    var typeArguments = typeSystem.inferGenericFunctionOrType(
-      typeParameters: ft.typeFormals,
-      parameters: ft.parameters,
-      declaredReturnType: ft.returnType,
-      argumentTypes: arguments,
-      contextReturnType: returnType,
-      errorReporter: reporter,
-      errorNode: astFactory.nullLiteral(KeywordToken(Keyword.NULL, 0)),
-    );
-
-    if (expectError) {
-      expect(listener.errors.map((e) => e.errorCode).toList(),
-          [StrongModeCode.COULD_NOT_INFER],
-          reason: 'expected exactly 1 could not infer error.');
-    } else {
-      expect(listener.errors, isEmpty, reason: 'did not expect any errors.');
-    }
-    return typeArguments;
-  }
-
-  FunctionType _inferCall2(FunctionTypeImpl ft, List<DartType> arguments,
-      {DartType returnType, bool expectError = false}) {
-    var typeArguments = _inferCall(
-      ft,
-      arguments,
-      returnType: returnType,
-      expectError: expectError,
-    );
-    return ft.instantiate(typeArguments);
-  }
-}
-
-@reflectiveTest
-class GreatestLowerBoundTest extends BoundTestBase {
-  void test_bottom_function() {
-    _checkGreatestLowerBound(
-        neverStar, functionTypeStar(returnType: voidNone), neverStar);
-  }
-
-  void test_bottom_interface() {
-    var A = class_(name: 'A');
-    _checkGreatestLowerBound(neverStar, interfaceTypeStar(A), neverStar);
-  }
-
-  void test_bottom_typeParam() {
-    var T = typeParameter('T');
-    _checkGreatestLowerBound(neverStar, typeParameterTypeStar(T), neverStar);
-  }
-
-  void test_bounds_of_top_types_complete() {
-    // Test every combination of a subset of Tops programatically.
-    var futureOrDynamicType = futureOrStar(dynamicType);
-    var futureOrObjectType = futureOrStar(objectStar);
-    var futureOrVoidType = futureOrStar(voidNone);
-    final futureOrFutureOrDynamicType = futureOrStar(futureOrDynamicType);
-    final futureOrFutureOrObjectType = futureOrStar(futureOrObjectType);
-    final futureOrFutureOrVoidType = futureOrStar(futureOrVoidType);
-
-    var orderedTops = [
-      // Lower index, so lower Top
-      voidNone,
-      dynamicType,
-      objectStar,
-      futureOrVoidType,
-      futureOrDynamicType,
-      futureOrObjectType,
-      futureOrFutureOrVoidType,
-      futureOrFutureOrDynamicType,
-      futureOrFutureOrObjectType,
-      // Higher index, higher Top
-    ];
-
-    // We could sort and check the sort result is correct in O(n log n), but a
-    // good sorting algorithm would only run n tests here (that each value is
-    // correct relative to its nearest neighbors). But O(n^2) for n=6 is stupid
-    // fast, in this case, so just do the brute force check because we can.
-    for (var i = 0; i < orderedTops.length; ++i) {
-      for (var lower = 0; lower <= i; ++lower) {
-        _checkGreatestLowerBound(
-            orderedTops[i], orderedTops[lower], orderedTops[i]);
-        _checkLeastUpperBound(
-            orderedTops[i], orderedTops[lower], orderedTops[lower]);
-      }
-      for (var greater = i; greater < orderedTops.length; ++greater) {
-        _checkGreatestLowerBound(
-            orderedTops[i], orderedTops[greater], orderedTops[greater]);
-        _checkLeastUpperBound(
-            orderedTops[i], orderedTops[greater], orderedTops[i]);
-      }
-    }
-  }
-
-  void test_bounds_of_top_types_sanity() {
-    var futureOrDynamicType = futureOrStar(dynamicType);
-    final futureOrFutureOrDynamicType = futureOrStar(futureOrDynamicType);
-
-    // Sanity check specific cases of top for GLB/LUB.
-    _checkLeastUpperBound(objectStar, dynamicType, dynamicType);
-    _checkGreatestLowerBound(objectStar, dynamicType, objectStar);
-    _checkLeastUpperBound(objectStar, voidNone, voidNone);
-    _checkLeastUpperBound(futureOrDynamicType, dynamicType, dynamicType);
-    _checkGreatestLowerBound(
-        futureOrDynamicType, objectStar, futureOrDynamicType);
-    _checkGreatestLowerBound(futureOrDynamicType, futureOrFutureOrDynamicType,
-        futureOrFutureOrDynamicType);
-  }
-
-  void test_classAndSuperclass() {
-    // class A
-    // class B extends A
-    // class C extends B
-    var A = class_(name: 'A');
-    var B = class_(name: 'B', superType: interfaceTypeStar(A));
-    var C = class_(name: 'C', superType: interfaceTypeStar(B));
-    _checkGreatestLowerBound(
-      interfaceTypeStar(A),
-      interfaceTypeStar(C),
-      interfaceTypeStar(C),
-    );
-  }
-
-  void test_classAndSuperinterface() {
-    // class A
-    // class B implements A
-    // class C implements B
-    var A = class_(name: 'A');
-    var B = class_(name: 'B', interfaces: [interfaceTypeStar(A)]);
-    var C = class_(name: 'C', interfaces: [interfaceTypeStar(B)]);
-    _checkGreatestLowerBound(
-      interfaceTypeStar(A),
-      interfaceTypeStar(C),
-      interfaceTypeStar(C),
-    );
-  }
-
-  void test_dynamic_bottom() {
-    _checkGreatestLowerBound(dynamicType, neverStar, neverStar);
-  }
-
-  void test_dynamic_function() {
-    _checkGreatestLowerBound(
-        dynamicType,
-        functionTypeStar(returnType: voidNone),
-        functionTypeStar(returnType: voidNone));
-  }
-
-  void test_dynamic_interface() {
-    var A = class_(name: 'A');
-    var typeA = interfaceTypeStar(A);
-    _checkGreatestLowerBound(dynamicType, typeA, typeA);
-  }
-
-  void test_dynamic_typeParam() {
-    var T = typeParameter('T');
-    var typeT = typeParameterTypeStar(T);
-    _checkGreatestLowerBound(dynamicType, typeT, typeT);
-  }
-
-  void test_dynamic_void() {
-    // Note: _checkGreatestLowerBound tests `GLB(x, y)` as well as `GLB(y, x)`
-    _checkGreatestLowerBound(dynamicType, voidNone, dynamicType);
-  }
-
-  void test_functionsDifferentNamedTakeUnion() {
-    var type1 = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'a', type: intStar),
-        namedParameter(name: 'b', type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'b', type: doubleStar),
-        namedParameter(name: 'c', type: stringStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'a', type: intStar),
-        namedParameter(name: 'b', type: numStar),
-        namedParameter(name: 'c', type: stringStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsDifferentOptionalArityTakeMax() {
-    var type1 = functionTypeStar(
-      parameters: [
-        positionalParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        positionalParameter(type: doubleStar),
-        positionalParameter(type: stringStar),
-        positionalParameter(type: objectStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        positionalParameter(type: numStar),
-        positionalParameter(type: stringStar),
-        positionalParameter(type: objectStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsDifferentRequiredArityBecomeOptional() {
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsFromDynamic() {
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: dynamicType),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        requiredParameter(type: dynamicType),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsGlbReturnType() {
-    var type1 = functionTypeStar(
-      returnType: intStar,
-    );
-    var type2 = functionTypeStar(
-      returnType: numStar,
-    );
-    var expected = functionTypeStar(
-      returnType: intStar,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsLubNamedParams() {
-    var type1 = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'a', type: stringStar),
-        namedParameter(name: 'b', type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'a', type: intStar),
-        namedParameter(name: 'b', type: numStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'a', type: objectStar),
-        namedParameter(name: 'b', type: numStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsLubPositionalParams() {
-    var type1 = functionTypeStar(
-      parameters: [
-        positionalParameter(type: stringStar),
-        positionalParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        positionalParameter(type: intStar),
-        positionalParameter(type: numStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        positionalParameter(type: objectStar),
-        positionalParameter(type: numStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsLubRequiredParams() {
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        requiredParameter(type: doubleStar),
-        requiredParameter(type: numStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        requiredParameter(type: objectStar),
-        requiredParameter(type: numStar),
-        requiredParameter(type: numStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsMixedOptionalAndRequiredBecomeOptional() {
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        requiredParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var expected = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-        positionalParameter(type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsReturnBottomIfMixOptionalAndNamed() {
-    // Dart doesn't allow a function to have both optional and named parameters,
-    // so if we would have synthethized that, pick bottom instead.
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: intStar),
-        namedParameter(name: 'a', type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    var type2 = functionTypeStar(
-      parameters: [
-        namedParameter(name: 'a', type: intStar),
-      ],
-      returnType: voidNone,
-    );
-    _checkGreatestLowerBound(type1, type2, neverStar);
-  }
-
-  void test_functionsSameType_withNamed() {
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: numStar),
-        namedParameter(name: 'n', type: numStar),
-      ],
-      returnType: intStar,
-    );
-
-    var type2 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: numStar),
-        namedParameter(name: 'n', type: numStar),
-      ],
-      returnType: intStar,
-    );
-
-    var expected = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: numStar),
-        namedParameter(name: 'n', type: numStar),
-      ],
-      returnType: intStar,
-    );
-
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_functionsSameType_withOptional() {
-    var type1 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: numStar),
-        positionalParameter(type: doubleStar),
-      ],
-      returnType: intStar,
-    );
-
-    var type2 = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: numStar),
-        positionalParameter(type: doubleStar),
-      ],
-      returnType: intStar,
-    );
-
-    var expected = functionTypeStar(
-      parameters: [
-        requiredParameter(type: stringStar),
-        requiredParameter(type: intStar),
-        requiredParameter(type: numStar),
-        positionalParameter(type: doubleStar),
-      ],
-      returnType: intStar,
-    );
-
-    _checkGreatestLowerBound(type1, type2, expected);
-  }
-
-  void test_interface_function() {
-    var A = class_(name: 'A');
-    var typeA = interfaceTypeStar(A);
-    _checkGreatestLowerBound(
-      typeA,
-      functionTypeStar(returnType: voidNone),
-      neverStar,
-    );
-  }
-
-  void test_mixin() {
-    // class A
-    // class B
-    // class C
-    // class D extends A with B, C
-    var A = class_(name: 'A');
-    var typeA = interfaceTypeStar(A);
-
-    var B = class_(name: 'B');
-    var typeB = interfaceTypeStar(B);
-
-    var C = class_(name: 'C');
-    var typeC = interfaceTypeStar(C);
-
-    var D = class_(
-      name: 'D',
-      superType: interfaceTypeStar(A),
-      mixins: [typeB, typeC],
-    );
-    var typeD = interfaceTypeStar(D);
-
-    _checkGreatestLowerBound(typeA, typeD, typeD);
-    _checkGreatestLowerBound(typeB, typeD, typeD);
-    _checkGreatestLowerBound(typeC, typeD, typeD);
-  }
-
-  void test_self() {
-    var T = typeParameter('T');
-    var A = class_(name: 'A');
-
-    List<DartType> types = [
-      dynamicType,
-      voidNone,
-      neverStar,
-      typeParameterTypeStar(T),
-      interfaceTypeStar(A),
-      functionTypeStar(returnType: voidNone),
-    ];
-
-    for (DartType type in types) {
-      _checkGreatestLowerBound(type, type, type);
-    }
-  }
-
-  void test_typeParam_function_noBound() {
-    var T = typeParameter('T');
-    _checkGreatestLowerBound(
-      typeParameterTypeStar(T),
-      functionTypeStar(returnType: voidNone),
-      neverStar,
-    );
-  }
-
-  void test_typeParam_interface_bounded() {
-    var A = class_(name: 'A');
-    var typeA = interfaceTypeStar(A);
-
-    var B = class_(name: 'B', superType: typeA);
-    var typeB = interfaceTypeStar(B);
-
-    var C = class_(name: 'C', superType: typeB);
-    var typeC = interfaceTypeStar(C);
-
-    var T = typeParameter('T', bound: typeB);
-    _checkGreatestLowerBound(typeParameterTypeStar(T), typeC, neverStar);
-  }
-
-  void test_typeParam_interface_noBound() {
-    // GLB(T, A) = ⊥
-    var T = typeParameter('T');
-    var A = class_(name: 'A');
-    _checkGreatestLowerBound(
-      typeParameterTypeStar(T),
-      interfaceTypeStar(A),
-      neverStar,
-    );
-  }
-
-  void test_typeParameters_different() {
-    // GLB(List<int>, List<double>) = ⊥
-    var listOfIntType = listStar(intStar);
-    var listOfDoubleType = listStar(doubleStar);
-    // TODO(rnystrom): Can we do something better here?
-    _checkGreatestLowerBound(listOfIntType, listOfDoubleType, neverStar);
-  }
-
-  void test_typeParameters_same() {
-    // GLB(List<int>, List<int>) = List<int>
-    var listOfIntType = listStar(intStar);
-    _checkGreatestLowerBound(listOfIntType, listOfIntType, listOfIntType);
-  }
-
-  void test_unrelatedClasses() {
-    // class A
-    // class B
-    // class C
-    var A = class_(name: 'A');
-    var B = class_(name: 'B');
-    _checkGreatestLowerBound(
-        interfaceTypeStar(A), interfaceTypeStar(B), neverStar);
-  }
-
-  void test_void() {
-    var A = class_(name: 'A');
-    var T = typeParameter('T');
-    List<DartType> types = [
-      neverStar,
-      functionTypeStar(returnType: voidNone),
-      interfaceTypeStar(A),
-      typeParameterTypeStar(T),
-    ];
-    for (DartType type in types) {
-      _checkGreatestLowerBound(
-        functionTypeStar(returnType: voidNone),
-        functionTypeStar(returnType: type),
-        functionTypeStar(returnType: type),
-      );
-    }
-  }
-}
-
-@reflectiveTest
 class LeastUpperBoundFunctionsTest extends BoundTestBase {
   void test_differentRequiredArity() {
     var type1 = functionTypeStar(
@@ -3343,16 +1727,3 @@
     check(T2, T, intNone);
   }
 }
-
-class _MockSource implements Source {
-  @override
-  final Uri uri;
-
-  _MockSource(this.uri);
-
-  @override
-  String get encoding => '$uri';
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/test/id_tests/assigned_variables_test.dart b/pkg/analyzer/test/id_tests/assigned_variables_test.dart
index 9ac842c..f674c7c 100644
--- a/pkg/analyzer/test/id_tests/assigned_variables_test.dart
+++ b/pkg/analyzer/test/id_tests/assigned_variables_test.dart
@@ -118,7 +118,7 @@
   const _AssignedVariablesDataInterpreter();
 
   @override
-  String getText(_Data actualData) {
+  String getText(_Data actualData, [String indentation]) {
     var parts = <String>[];
     if (actualData.declared.isNotEmpty) {
       parts.add('declared=${_setToString(actualData.declared)}');
diff --git a/pkg/analyzer/test/id_tests/constant_test.dart b/pkg/analyzer/test/id_tests/constant_test.dart
index e249afe2..9a78106 100644
--- a/pkg/analyzer/test/id_tests/constant_test.dart
+++ b/pkg/analyzer/test/id_tests/constant_test.dart
@@ -11,7 +11,9 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/analysis/testing_data.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/util/ast_data_extractor.dart';
 
 import '../util/id_testing_helper.dart';
@@ -36,6 +38,18 @@
   DataInterpreter<String> get dataValidator => const StringDataInterpreter();
 
   @override
+  bool get supportsErrors => true;
+
+  @override
+  String computeErrorData(TestConfig config, TestingData testingData, Id id,
+      List<AnalysisError> errors) {
+    var errorCodes = errors.map((e) => e.errorCode).where((errorCode) =>
+        errorCode !=
+        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
+    return errorCodes.isNotEmpty ? errorCodes.join(',') : null;
+  }
+
+  @override
   void computeUnitData(TestingData testingData, CompilationUnit unit,
       Map<Id, ActualData<String>> actualMap) {
     ConstantsDataExtractor(unit.declaredElement.source.uri, actualMap)
@@ -54,7 +68,7 @@
       if (element is PropertyAccessorElement && element.isSynthetic) {
         var variable = element.variable;
         if (!variable.isSynthetic && variable.isConst) {
-          var value = variable.constantValue;
+          var value = variable.computeConstantValue();
           if (value != null) return _stringify(value);
         }
       }
diff --git a/pkg/analyzer/test/id_tests/definite_assignment_test.dart b/pkg/analyzer/test/id_tests/definite_assignment_test.dart
index 732c27a..0581c64 100644
--- a/pkg/analyzer/test/id_tests/definite_assignment_test.dart
+++ b/pkg/analyzer/test/id_tests/definite_assignment_test.dart
@@ -73,7 +73,7 @@
     if (node is SimpleIdentifier && node.inGetterContext()) {
       var element = node.staticElement;
       if (element is LocalVariableElement || element is ParameterElement) {
-        if (_flowResult.unassignedNodes.contains(node)) {
+        if (_flowResult.potentiallyUnassignedNodes.contains(node)) {
           return 'unassigned';
         }
       }
@@ -86,7 +86,7 @@
   const _DefiniteAssignmentDataInterpreter();
 
   @override
-  String getText(String actualData) => actualData;
+  String getText(String actualData, [String indentation]) => actualData;
 
   @override
   String isAsExpected(String actualData, String expectedData) {
diff --git a/pkg/analyzer/test/id_tests/definite_unassignment_test.dart b/pkg/analyzer/test/id_tests/definite_unassignment_test.dart
index 1e2b9c5..359b481 100644
--- a/pkg/analyzer/test/id_tests/definite_unassignment_test.dart
+++ b/pkg/analyzer/test/id_tests/definite_unassignment_test.dart
@@ -86,7 +86,7 @@
   const _DefiniteUnassignmentDataInterpreter();
 
   @override
-  String getText(String actualData) => actualData;
+  String getText(String actualData, [String indentation]) => actualData;
 
   @override
   String isAsExpected(String actualData, String expectedData) {
diff --git a/pkg/analyzer/test/id_tests/nullability_test.dart b/pkg/analyzer/test/id_tests/nullability_test.dart
index 4d9128a..1490e2e 100644
--- a/pkg/analyzer/test/id_tests/nullability_test.dart
+++ b/pkg/analyzer/test/id_tests/nullability_test.dart
@@ -96,7 +96,7 @@
   const _NullabilityDataInterpreter();
 
   @override
-  String getText(String actualData) => actualData;
+  String getText(String actualData, [String indentation]) => actualData;
 
   @override
   String isAsExpected(String actualData, String expectedData) {
diff --git a/pkg/analyzer/test/id_tests/reachability_test.dart b/pkg/analyzer/test/id_tests/reachability_test.dart
index 093d824..833f131 100644
--- a/pkg/analyzer/test/id_tests/reachability_test.dart
+++ b/pkg/analyzer/test/id_tests/reachability_test.dart
@@ -116,7 +116,7 @@
   const _ReachabilityDataInterpreter();
 
   @override
-  String getText(Set<_ReachabilityAssertion> actualData) =>
+  String getText(Set<_ReachabilityAssertion> actualData, [String indentation]) =>
       _sortedRepresentation(_toStrings(actualData));
 
   @override
diff --git a/pkg/analyzer/test/id_tests/type_promotion_test.dart b/pkg/analyzer/test/id_tests/type_promotion_test.dart
index 4e7705a..067dc95 100644
--- a/pkg/analyzer/test/id_tests/type_promotion_test.dart
+++ b/pkg/analyzer/test/id_tests/type_promotion_test.dart
@@ -70,7 +70,7 @@
   const _TypePromotionDataInterpreter();
 
   @override
-  String getText(DartType actualData) {
+  String getText(DartType actualData, [String indentation]) {
     if (actualData is TypeParameterTypeImpl) {
       var element = actualData.element;
       var promotedBound = actualData.promotedBound;
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 28a121a..7ebbad5 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -234,8 +234,6 @@
     // being returned.
     AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
     defaultOptions.dart2jsHint = !defaultOptions.dart2jsHint;
-    defaultOptions.enableLazyAssignmentOperators =
-        !defaultOptions.enableLazyAssignmentOperators;
     builderOptions.defaultOptions = defaultOptions;
     AnalysisOptions options = builder.createDefaultOptions();
     _expectEqualOptions(options, defaultOptions);
@@ -614,10 +612,8 @@
 
   void test_getAnalysisOptions_default_noOverrides() {
     AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    defaultOptions.enableLazyAssignmentOperators = true;
     builderOptions.defaultOptions = defaultOptions;
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.enableLazyAssignmentOperators = true;
     String path = convertPath('/some/directory/path');
     String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
     newFile(filePath, content: '''
@@ -830,28 +826,19 @@
   void _expectEqualOptions(
       AnalysisOptionsImpl actual, AnalysisOptionsImpl expected) {
     // TODO(brianwilkerson) Consider moving this to AnalysisOptionsImpl.==.
-    expect(actual.analyzeFunctionBodiesPredicate,
-        same(expected.analyzeFunctionBodiesPredicate));
     expect(actual.dart2jsHint, expected.dart2jsHint);
-    expect(actual.enableLazyAssignmentOperators,
-        expected.enableLazyAssignmentOperators);
     expect(actual.enableTiming, expected.enableTiming);
-    expect(actual.generateImplicitErrors, expected.generateImplicitErrors);
-    expect(actual.generateSdkErrors, expected.generateSdkErrors);
     expect(actual.hint, expected.hint);
     expect(actual.lint, expected.lint);
     expect(
       actual.lintRules.map((l) => l.name),
       unorderedEquals(expected.lintRules.map((l) => l.name)),
     );
-    expect(actual.preserveComments, expected.preserveComments);
     expect(actual.strongMode, expected.strongMode);
     expect(actual.implicitCasts, expected.implicitCasts);
     expect(actual.implicitDynamic, expected.implicitDynamic);
     expect(actual.strictInference, expected.strictInference);
     expect(actual.strictRawTypes, expected.strictRawTypes);
-    expect(actual.trackCacheDependencies, expected.trackCacheDependencies);
-    expect(actual.disableCacheFlushing, expected.disableCacheFlushing);
   }
 
   Uri _relativeUri(String path, {String from}) {
diff --git a/pkg/analyzer/test/src/context/packages_test.dart b/pkg/analyzer/test/src/context/packages_test.dart
index 2868970..0313bbc 100644
--- a/pkg/analyzer/test/src/context/packages_test.dart
+++ b/pkg/analyzer/test/src/context/packages_test.dart
@@ -102,6 +102,42 @@
     );
   }
 
+  test_packageForPath() {
+    var packages = Packages(
+      {
+        'aaa': Package(
+          name: 'aaa',
+          rootFolder: getFolder('/home/aaa'),
+          libFolder: getFolder('/home/aaa/lib'),
+          languageVersion: Version.parse('2.7.0'),
+        ),
+        'bbb': Package(
+          name: 'bbb',
+          rootFolder: getFolder('/home/aaa/bbb'),
+          libFolder: getFolder('/home/aaa/bbb/lib'),
+          languageVersion: Version.parse('2.7.0'),
+        ),
+        'ccc': Package(
+          name: 'ccc',
+          rootFolder: getFolder('/home/ccc'),
+          libFolder: getFolder('/home/ccc/lib'),
+          languageVersion: Version.parse('2.7.0'),
+        ),
+      },
+    );
+
+    void check(String posixPath, String expectedPackageName) {
+      var path = convertPath(posixPath);
+      var package = packages.packageForPath(path);
+      expect(package?.name, expectedPackageName);
+    }
+
+    check('/home/aaa/lib/a.dart', 'aaa');
+    check('/home/aaa/bbb/lib/b.dart', 'bbb');
+    check('/home/ccc/lib/c.dart', 'ccc');
+    check('/home/ddd/lib/c.dart', null);
+  }
+
   test_parseDotPackagesFile() {
     var file = newFile('/test/.packages', content: '''
 # Generated by pub
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 4a26ff6..7f8d145 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -1344,7 +1344,7 @@
 
     ClassDeclaration bNode = result.unit.declarations[1];
     TypeParameterType uType =
-        typeParameterType(bNode.declaredElement.typeParameters[0]);
+        typeParameterTypeStar(bNode.declaredElement.typeParameters[0]);
     InterfaceType auType = aElement.instantiate(
       typeArguments: [uType],
       nullabilitySuffix: NullabilitySuffix.star,
@@ -1720,7 +1720,8 @@
     FieldDeclaration fDeclaration = cNode.members[0];
     VariableDeclaration fNode = fDeclaration.fields.variables[0];
     FieldElement fElement = fNode.declaredElement;
-    expect(fElement.type, typeProvider.listType2(typeParameterType(tElement)));
+    expect(
+        fElement.type, typeProvider.listType2(typeParameterTypeStar(tElement)));
   }
 
   test_field_generic() async {
@@ -4010,7 +4011,7 @@
 
     TypeName fReturnTypeNode = fNode.returnType;
     expect(fReturnTypeNode.name.staticElement, same(tElement));
-    expect(fReturnTypeNode.type, typeParameterType(tElement));
+    expect(fReturnTypeNode.type, typeParameterTypeStar(tElement));
 
     expect(fExpression.declaredElement, same(fElement));
 
@@ -4025,13 +4026,13 @@
           name: 'a',
           offset: 28,
           kind: ParameterKind.REQUIRED,
-          type: typeParameterType(tElement));
+          type: typeParameterTypeStar(tElement));
 
       _assertSimpleParameter(nodes[1], parameters[1],
           name: 'b',
           offset: 33,
           kind: ParameterKind.REQUIRED,
-          type: typeParameterType(uElement));
+          type: typeParameterTypeStar(uElement));
 
       var aRef = findNode.simple('a;');
       assertElement(aRef, parameters[0]);
@@ -7266,7 +7267,7 @@
 
       VariableDeclaration bNode = bDeclaration.fields.variables[0];
       expect(bNode.declaredElement, same(bElement));
-      expect(bElement.type, typeParameterType(tElement));
+      expect(bElement.type, typeParameterTypeStar(tElement));
       expect(bNode.name.staticElement, same(bElement));
       expect(bNode.name.staticType, isNull);
     }
@@ -7504,7 +7505,7 @@
         name: 'b',
         offset: 27,
         kind: ParameterKind.REQUIRED,
-        type: typeParameterType(aliasElement.typeParameters[0]));
+        type: typeParameterTypeStar(aliasElement.typeParameters[0]));
   }
 
   test_top_typeParameter() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 45376fd..c9d26a4 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -885,8 +885,8 @@
     var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
     var y = AstFinder.getTopLevelVariableElement(result.unit, 'y');
-    expect(x.constantValue.toIntValue(), 2);
-    expect(y.constantValue.toIntValue(), 1);
+    expect(x.computeConstantValue().toIntValue(), 2);
+    expect(y.computeConstantValue().toIntValue(), 1);
   }
 
   test_const_externalConstFactory() async {
@@ -901,7 +901,7 @@
 ''');
     var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
-    expect(x.constantValue, isNotNull);
+    expect(x.computeConstantValue(), isNotNull);
   }
 
   test_const_implicitCreation() async {
@@ -967,7 +967,7 @@
 ''');
     var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
-    expect(x.constantValue, isNotNull);
+    expect(x.computeConstantValue(), isNotNull);
   }
 
   test_const_simple_topLevelVariable() async {
@@ -976,7 +976,7 @@
 ''');
     var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
-    expect(x.constantValue.toIntValue(), 1);
+    expect(x.computeConstantValue().toIntValue(), 1);
   }
 
   test_currentSession() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
index 901f3b1..9de6844 100644
--- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/context/source.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -35,6 +36,52 @@
     _createSourceFactory();
   }
 
+  test_nested() {
+    var packages = Packages(
+      {
+        'aaa': Package(
+          name: 'aaa',
+          rootFolder: getFolder('/packages/aaa'),
+          libFolder: getFolder('/packages/aaa/lib'),
+          languageVersion: Version.parse('2.5.0'),
+        ),
+        'bbb': Package(
+          name: 'bbb',
+          rootFolder: getFolder('/packages/aaa/bbb'),
+          libFolder: getFolder('/packages/aaa/bbb/lib'),
+          languageVersion: Version.parse('2.6.0'),
+        ),
+        'ccc': Package(
+          name: 'ccc',
+          rootFolder: getFolder('/packages/ccc'),
+          libFolder: getFolder('/packages/ccc/lib'),
+          languageVersion: Version.parse('2.7.0'),
+        ),
+      },
+    );
+
+    provider = FeatureSetProvider.build(
+      resourceProvider: resourceProvider,
+      packages: packages,
+      packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+      nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+    );
+
+    void check(String posixPath, Version expected) {
+      var path = convertPath(posixPath);
+      var uri = Uri.parse('package:aaa/a.dart');
+      expect(
+        provider.getLanguageVersion(path, uri),
+        expected,
+      );
+    }
+
+    check('/packages/aaa/a.dart', Version.parse('2.5.0'));
+    check('/packages/aaa/bbb/b.dart', Version.parse('2.6.0'));
+    check('/packages/ccc/c.dart', Version.parse('2.7.0'));
+    check('/packages/ddd/d.dart', ExperimentStatus.currentVersion);
+  }
+
   test_packages() {
     var packages = Packages(
       {
@@ -104,7 +151,7 @@
           name: 'ccc',
           rootFolder: newFolder('/packages/ccc'),
           libFolder: newFolder('/packages/ccc/lib'),
-          languageVersion: Version(2, 8, 0),
+          languageVersion: Version(2, 9, 0),
         ),
       },
     );
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 0c8d536..056f1c4 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -15,6 +15,7 @@
 
 import '../../../generated/test_support.dart';
 import '../resolution/driver_resolution.dart';
+import 'potentially_constant_test.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -22,6 +23,7 @@
     defineReflectiveTests(ConstantVisitorWithConstantUpdate2018Test);
     defineReflectiveTests(
         ConstantVisitorWithFlowControlAndSpreadCollectionsTest);
+    defineReflectiveTests(ConstantVisitorWithNullSafetyTest);
   });
 }
 
@@ -1152,3 +1154,22 @@
     expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3, 4]);
   }
 }
+
+@reflectiveTest
+class ConstantVisitorWithNullSafetyTest extends ConstantVisitorTestSupport
+    with WithNullSafetyMixin {
+  test_visitAsExpression_potentialConstType() async {
+    await assertNoErrorsInCode('''
+const num three = 3;
+
+class C<T extends num> {
+  final T w;
+  const C() : w = three as T;
+}
+
+void main() {
+  const C<int>().w;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart b/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart
new file mode 100644
index 0000000..bc0be60
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/type_system_test.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(HasTypeParameterReferenceTest);
+  });
+}
+
+@reflectiveTest
+class HasTypeParameterReferenceTest extends AbstractTypeSystemNullSafetyTest {
+  test_dynamic() {
+    _checkFalse(dynamicNone);
+  }
+
+  test_functionType() {
+    _checkFalse(functionTypeNone(returnType: voidNone));
+
+    var T = typeParameter('T');
+    var T_none = typeParameterTypeNone(T);
+
+    _checkTrue(
+      functionTypeNone(returnType: T_none),
+    );
+
+    _checkTrue(
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [requiredParameter(type: T_none)],
+      ),
+    );
+
+    _checkTrue(
+      functionTypeNone(
+        returnType: voidNone,
+        typeFormals: [typeParameter('S', bound: T_none)],
+      ),
+    );
+  }
+
+  test_interfaceType() {
+    _checkFalse(intNone);
+    _checkFalse(intQuestion);
+    _checkFalse(intStar);
+
+    var T = typeParameter('T');
+    var T_none = typeParameterTypeNone(T);
+    _checkTrue(listNone(T_none));
+    _checkTrue(mapNone(T_none, intNone));
+    _checkTrue(mapNone(intNone, T_none));
+  }
+
+  test_typeParameter() {
+    var T = typeParameter('T');
+    _checkTrue(typeParameterTypeNone(T));
+    _checkTrue(typeParameterTypeQuestion(T));
+    _checkTrue(typeParameterTypeStar(T));
+  }
+
+  test_void() {
+    _checkFalse(voidNone);
+  }
+
+  void _checkFalse(DartType type) {
+    expect(hasTypeParameterReference(type), isFalse);
+  }
+
+  void _checkTrue(DartType type) {
+    expect(hasTypeParameterReference(type), isTrue);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index b2431e5..44d4dd4 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -2,8 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/constant/potentially_constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -12,7 +15,9 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(IsConstantTypeExpressionTest);
+    defineReflectiveTests(IsPotentiallyConstantTypeExpressionTest);
     defineReflectiveTests(PotentiallyConstantTest);
+    defineReflectiveTests(PotentiallyConstantWithNullSafetyTest);
   });
 }
 
@@ -132,6 +137,35 @@
 }
 
 @reflectiveTest
+class IsPotentiallyConstantTypeExpressionTest
+    extends IsConstantTypeExpressionTest {
+  @override
+  test_typeParameter() async {
+    await _assertConst(r'''
+class A<T> {
+  m() {
+    T x;
+  }
+}
+''');
+  }
+
+  @override
+  Future<void> _assertConst(String code) async {
+    await resolveTestCode(code);
+    var type = findNode.variableDeclarationList('x;').type;
+    expect(isPotentiallyConstantTypeExpression(type), isTrue);
+  }
+
+  @override
+  Future<void> _assertNotConst(String code) async {
+    await resolveTestCode(code);
+    var type = findNode.variableDeclarationList('x;').type;
+    expect(isPotentiallyConstantTypeExpression(type), isFalse);
+  }
+}
+
+@reflectiveTest
 class PotentiallyConstantTest extends DriverResolutionTest {
   test_adjacentStrings() async {
     await _assertConst(r'''
@@ -153,7 +187,7 @@
 ''', () => _xInitializer(), () => [findNode.simple('a as')]);
   }
 
-  test_asExpression_notConstType() async {
+  test_asExpression_typeParameter() async {
     await _assertNotConst(r'''
 const a = 0;
 class A<T> {
@@ -249,7 +283,7 @@
 ''', () => _xInitializer(), () => [findNode.simple('a is')]);
   }
 
-  test_isExpression_notConstType() async {
+  test_isExpression_typeParameter() async {
     await _assertNotConst(r'''
 const a = 0;
 class A<T> {
@@ -845,7 +879,10 @@
   _assertConst(String code, AstNode Function() getNode) async {
     await resolveTestCode(code);
     var node = getNode();
-    var notConstList = getNotPotentiallyConstants(node);
+    var notConstList = getNotPotentiallyConstants(
+      node,
+      isNonNullableByDefault: typeSystem.isNonNullableByDefault,
+    );
     expect(notConstList, isEmpty);
   }
 
@@ -853,7 +890,10 @@
       List<AstNode> Function() getNotConstList) async {
     await resolveTestCode(code);
     var node = getNode();
-    var notConstList = getNotPotentiallyConstants(node);
+    var notConstList = getNotPotentiallyConstants(
+      node,
+      isNonNullableByDefault: typeSystem.isNonNullableByDefault,
+    );
 
     var expectedNotConst = getNotConstList();
     expect(notConstList, unorderedEquals(expectedNotConst));
@@ -863,3 +903,42 @@
     return findNode.variableDeclaration('x = ').initializer;
   }
 }
+
+@reflectiveTest
+class PotentiallyConstantWithNullSafetyTest extends PotentiallyConstantTest
+    with WithNullSafetyMixin {
+  @override
+  test_asExpression_typeParameter() async {
+    await _assertConst(r'''
+const a = 0;
+class A<T> {
+  m() {
+    var x = a as T;
+  }
+}
+''', () => _xInitializer());
+  }
+
+  @override
+  test_isExpression_typeParameter() async {
+    await _assertConst(r'''
+const a = 0;
+class A<T> {
+  m() {
+    var x = a is T;
+  }
+}
+''', () => _xInitializer());
+  }
+}
+
+mixin WithNullSafetyMixin on DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.fromEnableFlags(
+      [EnableString.non_nullable],
+    );
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
diff --git a/pkg/analyzer/test/src/dart/constant/test_all.dart b/pkg/analyzer/test/src/dart/constant/test_all.dart
index 95c1b2e..977b74c 100644
--- a/pkg/analyzer/test/src/dart/constant/test_all.dart
+++ b/pkg/analyzer/test/src/dart/constant/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'evaluation_test.dart' as evaluation;
+import 'has_type_parameter_reference_test.dart' as has_type_parameter_reference;
 import 'potentially_constant_test.dart' as potentially_constant;
 import 'utilities_test.dart' as utilities;
 import 'value_test.dart' as value;
@@ -12,6 +13,7 @@
 main() {
   defineReflectiveSuite(() {
     evaluation.main();
+    has_type_parameter_reference.main();
     potentially_constant.main();
     utilities.main();
     value.main();
diff --git a/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart b/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
new file mode 100644
index 0000000..08ec4f4
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/class_hierarchy.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/elements_types_mixin.dart';
+import '../../../generated/type_system_test.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ClassHierarchyLegacyTest);
+    defineReflectiveTests(ClassHierarchyNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class ClassHierarchyLegacyTest extends AbstractTypeSystemTest
+    with _AbstractClassHierarchyMixin {
+  @override
+  void setUp() {
+    super.setUp();
+    _createSharedElements();
+  }
+
+  test_invalid() {
+    _checkA(
+      typeArguments: [intNone, doubleNone],
+      interfaces: ['A<int*>'],
+      errors: ['A<int*> vs. A<double*>'],
+    );
+  }
+
+  test_valid() {
+    _checkA(
+      typeArguments: [intNone, intQuestion],
+      interfaces: ['A<int*>'],
+    );
+  }
+}
+
+@reflectiveTest
+class ClassHierarchyNullSafetyTest extends AbstractTypeSystemNullSafetyTest
+    with _AbstractClassHierarchyMixin {
+  @override
+  void setUp() {
+    super.setUp();
+    _createSharedElements();
+  }
+
+  test_invalid() {
+    _checkA(
+      typeArguments: [intNone, doubleNone],
+      interfaces: ['A<int>'],
+      errors: ['A<int> vs. A<double>'],
+    );
+  }
+
+  test_valid_equal() {
+    _checkA(
+      typeArguments: [intNone, intNone],
+      interfaces: ['A<int>'],
+    );
+  }
+
+  test_valid_equal_neverNone() {
+    _checkA(
+      typeArguments: [neverNone, neverNone],
+      interfaces: ['A<Never>'],
+    );
+  }
+
+  test_valid_merge() {
+    _checkA(
+      typeArguments: [objectQuestion, dynamicNone],
+      interfaces: ['A<Object?>'],
+    );
+  }
+}
+
+mixin _AbstractClassHierarchyMixin on ElementsTypesMixin {
+  ClassElementImpl A;
+
+  void _assertErrors(List<ClassHierarchyError> errors, List<String> expected) {
+    expect(
+      errors.map((e) {
+        if (e is IncompatibleInterfacesClassHierarchyError) {
+          var firstStr = _interfaceString(e.first);
+          var secondStr = _interfaceString(e.second);
+          return '$firstStr vs. $secondStr';
+        } else {
+          throw UnimplementedError('${e.runtimeType}');
+        }
+      }).toList(),
+      unorderedEquals(expected),
+    );
+  }
+
+  void _assertInterfaces(
+    List<InterfaceType> interfaces,
+    List<String> expected,
+  ) {
+    var interfacesStr = interfaces.map(_interfaceString).toList();
+    expect(interfacesStr, unorderedEquals(['Object', ...expected]));
+  }
+
+  void _checkA({
+    @required List<DartType> typeArguments,
+    @required List<String> interfaces,
+    List<String> errors = const [],
+  }) {
+    var specifiedInterfaces = typeArguments
+        .map((e) => interfaceTypeNone(A, typeArguments: [e]))
+        .toList();
+    var X = class_(name: 'X', interfaces: specifiedInterfaces);
+
+    var classHierarchy = ClassHierarchy();
+
+    var actualInterfaces = classHierarchy.implementedInterfaces(X);
+    _assertInterfaces(actualInterfaces, interfaces);
+
+    var actualErrors = classHierarchy.errors(X);
+    _assertErrors(actualErrors, errors);
+  }
+
+  void _createSharedElements() {
+    var T = typeParameter('T');
+    A = class_(name: 'A', typeParameters: [T]);
+  }
+
+  String _interfaceString(InterfaceType interface) {
+    return (interface as InterfaceTypeImpl)
+        .withNullability(NullabilitySuffix.none)
+        .getDisplayString(withNullability: true);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 2e0b1b2..06e4bb6 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -39,14 +40,25 @@
 
 class AbstractTypeTest with ElementsTypesMixin {
   TestAnalysisContext _analysisContext;
-  TypeProvider _typeProvider;
 
   @override
-  TypeProvider get typeProvider => _typeProvider;
+  LibraryElementImpl testLibrary;
+
+  @override
+  TypeProvider typeProvider;
+
+  TypeSystemImpl typeSystem;
 
   void setUp() {
     _analysisContext = TestAnalysisContext();
-    _typeProvider = _analysisContext.typeProviderLegacy;
+    typeProvider = _analysisContext.typeProviderLegacy;
+    typeSystem = _analysisContext.typeSystemLegacy;
+
+    testLibrary = library_(
+      uriStr: 'package:test/test.dart',
+      analysisSession: _analysisContext.analysisSession,
+      typeSystem: typeSystem,
+    );
   }
 }
 
@@ -1184,7 +1196,7 @@
   void test_substitute2_equal() {
     ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
     TypeParameterType parameterType =
-        typeParameterType(definingClass.typeParameters[0]);
+        typeParameterTypeStar(definingClass.typeParameters[0]);
     MethodElementImpl functionElement = MethodElementImpl('m', -1);
     String namedParameterName = "c";
     functionElement.parameters = <ParameterElement>[
@@ -1309,7 +1321,7 @@
       typeParameters: [BE],
       interfaces: [
         A.instantiate(
-          typeArguments: [typeParameterType(BE)],
+          typeArguments: [typeParameterTypeStar(BE)],
           nullabilitySuffix: NullabilitySuffix.star,
         ),
       ],
@@ -1399,7 +1411,7 @@
     var AE = typeParameter('E');
     var A = class_(name: 'A', typeParameters: [AE]);
 
-    DartType typeAE = typeParameterType(AE);
+    DartType typeAE = typeParameterTypeStar(AE);
     String getterName = "g";
     PropertyAccessorElementImpl getterG =
         ElementFactory.getterElement(getterName, false, typeAE);
@@ -1461,7 +1473,7 @@
       typeParameters: [F],
       interfaces: [
         A.instantiate(
-          typeArguments: [typeParameterType(F)],
+          typeArguments: [typeParameterTypeStar(F)],
           nullabilitySuffix: NullabilitySuffix.star,
         )
       ],
@@ -1520,7 +1532,7 @@
     //
     var E = typeParameter('E');
     var A = class_(name: 'A', typeParameters: [E]);
-    DartType typeE = typeParameterType(E);
+    DartType typeE = typeParameterTypeStar(E);
     String methodName = "m";
     MethodElementImpl methodM =
         ElementFactory.methodElement(methodName, typeE, [typeE]);
@@ -1599,7 +1611,7 @@
       typeParameters: [F],
       mixins: [
         interfaceTypeStar(A, typeArguments: [
-          typeParameterType(F),
+          typeParameterTypeStar(F),
         ]),
       ],
     );
@@ -1635,7 +1647,7 @@
     //
     var E = typeParameter('E');
     var A = class_(name: 'A', typeParameters: [E]);
-    DartType typeE = typeParameterType(E);
+    DartType typeE = typeParameterTypeStar(E);
     String setterName = "s";
     PropertyAccessorElementImpl setterS =
         ElementFactory.setterElement(setterName, false, typeE);
@@ -1683,7 +1695,7 @@
     var A = class_(name: 'A', typeParameters: [E]);
 
     var F = typeParameter('F');
-    var typeF = typeParameterType(F);
+    var typeF = typeParameterTypeStar(F);
 
     var B = class_(
       name: 'B',
@@ -1894,7 +1906,7 @@
     //
     var E = typeParameter('E');
     var A = class_(name: 'A', typeParameters: [E]);
-    DartType typeE = typeParameterType(E);
+    DartType typeE = typeParameterTypeStar(E);
     String methodName = "m";
     MethodElementImpl methodM =
         ElementFactory.methodElement(methodName, typeE, [typeE]);
@@ -1905,7 +1917,7 @@
       name: 'B',
       typeParameters: [F],
       superType: interfaceTypeStar(A, typeArguments: [
-        typeParameterType(F),
+        typeParameterTypeStar(F),
       ]),
     );
     LibraryElementImpl library =
@@ -2200,12 +2212,10 @@
     SimpleIdentifier argument = findNode.simple('C);');
     PropertyAccessorElementImpl getter = argument.staticElement;
     TopLevelVariableElement constant = getter.variable;
-    expect(constant.constantValue, isNull);
 
     DartObject value = constant.computeConstantValue();
     expect(value, isNotNull);
     expect(value.toIntValue(), 42);
-    expect(constant.constantValue, value);
   }
 }
 
diff --git a/pkg/analyzer/test/src/dart/element/factor_type_test.dart b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
index 111da27..f3ad7cc 100644
--- a/pkg/analyzer/test/src/dart/element/factor_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
@@ -2,12 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/factory_type_test_helper.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
-import 'package:test/test.dart';
+import 'package:test/test.dart' as test;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../generated/elements_types_mixin.dart';
@@ -20,7 +21,7 @@
 }
 
 @reflectiveTest
-class FactorTypeTest with ElementsTypesMixin {
+class FactorTypeTest with FactorTypeTestMixin<DartType>, ElementsTypesMixin {
   @override
   TypeProvider typeProvider;
 
@@ -32,6 +33,20 @@
     );
   }
 
+  @override
+  DartType get voidType => typeProvider.voidType;
+
+  @override
+  void expect(
+      DartType T, DartType S, String actualResult, String expectedResult) {
+    test.expect(actualResult, expectedResult);
+  }
+
+  @override
+  DartType factor(DartType T, DartType S) {
+    return typeSystem.factor(T, S);
+  }
+
   void setUp() {
     var analysisContext = TestAnalysisContext(
       featureSet: testFeatureSet,
@@ -40,89 +55,8 @@
     typeSystem = analysisContext.typeSystemNonNullableByDefault;
   }
 
-  void test_futureOr() {
-    _check(futureOrNone(intNone), intNone, 'Future<int>');
-    _check(futureOrNone(intNone), futureNone(intNone), 'int');
-
-    _check(futureOrNone(intQuestion), intNone, 'FutureOr<int?>');
-    _check(futureOrNone(intQuestion), futureNone(intNone), 'FutureOr<int?>');
-    _check(futureOrNone(intQuestion), intQuestion, 'Future<int?>');
-    _check(futureOrNone(intQuestion), futureNone(intQuestion), 'int?');
-    _check(futureOrNone(intQuestion), intStar, 'Future<int?>');
-    _check(futureOrNone(intQuestion), futureNone(intStar), 'int?');
-
-    _check(futureOrNone(intNone), numNone, 'Future<int>');
-    _check(futureOrNone(intNone), futureNone(numNone), 'int');
-  }
-
-  void test_object() {
-    _check(objectNone, objectNone, 'Never');
-    _check(objectNone, objectQuestion, 'Never');
-    _check(objectNone, objectStar, 'Never');
-
-    _check(objectNone, intNone, 'Object');
-    _check(objectNone, intQuestion, 'Object');
-    _check(objectNone, intStar, 'Object');
-
-    _check(objectQuestion, objectNone, 'Never?');
-    _check(objectQuestion, objectQuestion, 'Never');
-    _check(objectQuestion, objectStar, 'Never');
-
-    _check(objectQuestion, intNone, 'Object?');
-    _check(objectQuestion, intQuestion, 'Object');
-    _check(objectQuestion, intStar, 'Object');
-  }
-
-  test_subtype() {
-    _check(intNone, intNone, 'Never');
-    _check(intNone, intQuestion, 'Never');
-    _check(intNone, intStar, 'Never');
-
-    _check(intQuestion, intNone, 'Never?');
-    _check(intQuestion, intQuestion, 'Never');
-    _check(intQuestion, intStar, 'Never');
-
-    _check(intStar, intNone, 'Never');
-    _check(intStar, intQuestion, 'Never');
-    _check(intStar, intStar, 'Never');
-
-    _check(intNone, numNone, 'Never');
-    _check(intNone, numQuestion, 'Never');
-    _check(intNone, numStar, 'Never');
-
-    _check(intQuestion, numNone, 'Never?');
-    _check(intQuestion, numQuestion, 'Never');
-    _check(intQuestion, numStar, 'Never');
-
-    _check(intStar, numNone, 'Never');
-    _check(intStar, numQuestion, 'Never');
-    _check(intStar, numStar, 'Never');
-
-    _check(intNone, nullNone, 'int');
-    _check(intQuestion, nullNone, 'int');
-    _check(intStar, nullNone, 'int');
-
-    _check(intNone, stringNone, 'int');
-    _check(intQuestion, stringNone, 'int?');
-    _check(intStar, stringNone, 'int*');
-
-    _check(intNone, stringQuestion, 'int');
-    _check(intQuestion, stringQuestion, 'int');
-    _check(intStar, stringQuestion, 'int');
-
-    _check(intNone, stringStar, 'int');
-    _check(intQuestion, stringStar, 'int');
-    _check(intStar, stringStar, 'int');
-  }
-
-  void _check(DartType T, DartType S, String expectedStr) {
-    var result = typeSystem.factor(T, S);
-    var resultStr = _typeString(result);
-
-    expect(resultStr, expectedStr);
-  }
-
-  String _typeString(TypeImpl type) {
+  @override
+  String typeString(covariant TypeImpl type) {
     return type.getDisplayString(withNullability: true);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/element/flatten_type_test.dart b/pkg/analyzer/test/src/dart/element/flatten_type_test.dart
index a27da75..685c771 100644
--- a/pkg/analyzer/test/src/dart/element/flatten_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/flatten_type_test.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index 12a11bf..c17d008 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -300,11 +300,11 @@
   test_synthetic_instantiate() {
     // T Function<T>(T x)
     var t = typeParameter('T');
-    var x = requiredParameter(name: 'x', type: typeParameterType(t));
+    var x = requiredParameter(name: 'x', type: typeParameterTypeNone(t));
     FunctionType f = FunctionTypeImpl(
       typeFormals: [t],
       parameters: [x],
-      returnType: typeParameterType(t),
+      returnType: typeParameterTypeNone(t),
       nullabilitySuffix: NullabilitySuffix.star,
     );
     FunctionType instantiated = f.instantiate([objectType]);
@@ -346,7 +346,7 @@
     FunctionType f = FunctionTypeImpl(
       typeFormals: [t],
       parameters: [x],
-      returnType: typeParameterType(t),
+      returnType: typeParameterTypeNone(t),
       nullabilitySuffix: NullabilitySuffix.star,
     );
     FunctionType instantiated = f.instantiate([objectType]);
@@ -432,24 +432,24 @@
   test_synthetic_substitute() {
     // Map<T, U> Function<U extends T>(T x, U y)
     var t = typeParameter('T');
-    var u = typeParameter('U', bound: typeParameterType(t));
-    var x = requiredParameter(name: 'x', type: typeParameterType(t));
-    var y = requiredParameter(name: 'y', type: typeParameterType(u));
+    var u = typeParameter('U', bound: typeParameterTypeNone(t));
+    var x = requiredParameter(name: 'x', type: typeParameterTypeNone(t));
+    var y = requiredParameter(name: 'y', type: typeParameterTypeNone(u));
     FunctionType f = FunctionTypeImpl.synthetic(
-        mapOf(typeParameterType(t), typeParameterType(u)), [u], [x, y],
+        mapOf(typeParameterTypeNone(t), typeParameterTypeNone(u)), [u], [x, y],
         nullabilitySuffix: NullabilitySuffix.star);
     FunctionType substituted =
-        f.substitute2([objectType], [typeParameterType(t)]);
+        f.substitute2([objectType], [typeParameterTypeNone(t)]);
     var uSubstituted = substituted.typeFormals[0];
     basicChecks(substituted,
         element: isNull,
         displayName: 'Map<Object, U> Function<U extends Object>(Object, U)',
-        returnType: mapOf(objectType, typeParameterType(uSubstituted)),
+        returnType: mapOf(objectType, typeParameterTypeNone(uSubstituted)),
         typeFormals: [uSubstituted],
         normalParameterNames: ['x', 'y'],
         normalParameterTypes: [
           same(objectType),
-          typeParameterType(uSubstituted)
+          typeParameterTypeNone(uSubstituted)
         ],
         parameters: hasLength(2));
   }
@@ -460,7 +460,7 @@
     var t = typeParameter('T');
     FunctionType f = FunctionTypeImpl.synthetic(dynamicType, [], [],
         nullabilitySuffix: NullabilitySuffix.star);
-    expect(() => f.substitute2([], [typeParameterType(t)]),
+    expect(() => f.substitute2([], [typeParameterTypeStar(t)]),
         throwsA(TypeMatcher<ArgumentError>()));
   }
 
@@ -469,11 +469,11 @@
     // dynamic Function<U>(U x)
     var t = typeParameter('T');
     var u = typeParameter('U');
-    var x = requiredParameter(name: 'x', type: typeParameterType(u));
+    var x = requiredParameter(name: 'x', type: typeParameterTypeStar(u));
     FunctionType f = FunctionTypeImpl.synthetic(dynamicType, [u], [x],
         nullabilitySuffix: NullabilitySuffix.star);
     FunctionType substituted =
-        f.substitute2([objectType], [typeParameterType(t)]);
+        f.substitute2([objectType], [typeParameterTypeStar(t)]);
     expect(substituted, same(f));
   }
 
@@ -482,13 +482,13 @@
     FunctionType f = FunctionTypeImpl(
       typeFormals: [t],
       parameters: const [],
-      returnType: typeParameterType(t),
+      returnType: typeParameterTypeStar(t),
       nullabilitySuffix: NullabilitySuffix.star,
     );
     basicChecks(f,
         element: isNull,
         displayName: 'T Function<T>()',
-        returnType: typeParameterType(t),
+        returnType: typeParameterTypeStar(t),
         typeFormals: [same(t)]);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
new file mode 100644
index 0000000..4354565
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -0,0 +1,1214 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/element/generic_inferrer.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' show toUri;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/type_system_test.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstraintMatchingTest);
+    defineReflectiveTests(GenericFunctionInferenceTest);
+  });
+}
+
+@reflectiveTest
+class ConstraintMatchingTest extends AbstractTypeSystemNullSafetyTest {
+  TypeParameterElement T;
+  TypeParameterType T_none;
+  TypeParameterType T_question;
+
+  @override
+  void setUp() {
+    super.setUp();
+    T = typeParameter('T');
+    T_none = typeParameterTypeNone(T);
+    T_question = typeParameterTypeQuestion(T);
+  }
+
+  void test_function_coreFunction() {
+    _checkOrdinarySubtypeMatch(
+      functionTypeNone(
+        returnType: voidNone,
+      ),
+      typeProvider.functionType,
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_function_parameters_requiredPositional() {
+    _checkIsSubtypeMatchOf(
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: T_none),
+        ],
+        returnType: intNone,
+      ),
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: stringNone),
+        ],
+        returnType: intNone,
+      ),
+      [T],
+      ['String <: T'],
+      covariant: true,
+    );
+  }
+
+  void test_function_returnType() {
+    _checkIsSubtypeMatchOf(
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: intNone),
+        ],
+        returnType: T_none,
+      ),
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: intNone),
+        ],
+        returnType: stringNone,
+      ),
+      [T],
+      ['T <: String'],
+      covariant: true,
+    );
+  }
+
+  /// Left FutureOr: if `T0` is `FutureOr<S0>` then:
+  /// * `T0 <: T1` iff `Future<S0> <: T1` and `S0 <: T1`
+  void test_futureOr_left() {
+    _checkIsSubtypeMatchOf(
+      futureOrNone(T_none),
+      futureOrNone(stringNone),
+      [T],
+      ['T <: String'],
+      covariant: true,
+    );
+
+    _checkIsSubtypeMatchOf(
+      futureOrNone(T_none),
+      futureNone(stringNone),
+      [T],
+      ['T <: String', 'T <: Future<String>'],
+      covariant: true,
+    );
+
+    // Future<List<T>> <: List<String> can't be satisfied
+    _checkIsNotSubtypeMatchOf(
+      futureOrNone(listNone(T_none)),
+      listNone(stringNone),
+      [T],
+      covariant: true,
+    );
+
+    // List<T> <: Future<List<String>> can't be satisfied
+    _checkIsNotSubtypeMatchOf(
+      futureOrNone(listNone(T_none)),
+      futureNone(listNone(stringNone)),
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_futureOr_right_both_noConstraints() {
+    // `Future<String> <: Future<Object>` can be satisfied:
+    //    * no constraints
+    //
+    // `Future<String> <: Object` can be satisfied:
+    //    * no constraints
+    _checkIsSubtypeMatchOf(
+      futureNone(stringNone),
+      futureOrNone(objectNone),
+      [T],
+      [],
+      covariant: true,
+    );
+  }
+
+  void test_futureOr_right_both_prefer_future() {
+    // `Future<String> <: Future<T>` can be satisfied:
+    //    * `String <: T`
+    //
+    // `Future<String> <: T` can be satisfied:
+    //    * `Future<String> <: T`
+    //
+    // We prefer `String <: T`.
+    _checkIsSubtypeMatchOf(
+      futureNone(stringNone),
+      futureOrNone(T_none),
+      [T],
+      ['String <: T'],
+      covariant: false,
+    );
+
+    // `Future<T> <: Future<Object>` can be satisfied:
+    //   * `T <: Object`
+    //
+    // `Future<T> <: Object` can be satisfied:
+    //   * no constraints
+    //
+    // We prefer `T <: Object`.
+    _checkIsSubtypeMatchOf(
+      futureNone(T_none),
+      futureOrNone(objectNone),
+      [T],
+      ['T <: Object'],
+      covariant: true,
+    );
+  }
+
+  /// Right FutureOr: if `T1` is `FutureOr<S1>` then:
+  /// `T0 <: T1` iff any of the following hold:
+  /// * either `T0 <: Future<S1>`
+  /// * or `T0 <: S1`
+  void test_futureOr_right_none() {
+    // `List<T> <: Future<String>` cannot be satisfied.
+    // `List<T> <: int` cannot be satisfied.
+    _checkIsNotSubtypeMatchOf(
+      listNone(T_none),
+      futureOrNone(stringNone),
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_futureOr_right_single_future() {
+    // `Future<T> <: Future<String>` can be satisfied:
+    //    * `T <: String`
+    //
+    // `Future<T> <: String` cannot be satisfied.
+    _checkIsSubtypeMatchOf(
+      futureNone(T_none),
+      futureOrNone(stringNone),
+      [T],
+      ['T <: String'],
+      covariant: true,
+    );
+  }
+
+  void test_futureOr_right_single_nonFuture() {
+    // `List<T> <: Future<List<String>>` cannot be satisfied.
+    //
+    // `List<T> <: List<String>` can be satisfied:
+    //    * `T <: String`
+    _checkIsSubtypeMatchOf(
+      listNone(T_none),
+      futureOrNone(listNone(stringNone)),
+      [T],
+      ['T <: String'],
+      covariant: true,
+    );
+  }
+
+  void test_futureOr_right_single_nonFuture_null() {
+    // `Null <: Future<T>` can be satisfied:
+    //    * no constraints
+    //
+    // `Null <: T` can be satisfied:
+    //    * `Null <: T`
+    //
+    // We prefer `Null <: T`.
+    _checkIsSubtypeMatchOf(
+      nullNone,
+      futureOrNone(T_none),
+      [T],
+      ['Null <: T'],
+      covariant: false,
+    );
+  }
+
+  void test_interfaceType_interface_left() {
+    _checkIsNotSubtypeMatchOf(
+      iterableNone(T_none),
+      listNone(stringNone),
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_interfaceType_interface_right() {
+    _checkIsSubtypeMatchOf(
+      listNone(T_none),
+      iterableNone(stringNone),
+      [T],
+      ['T <: String'],
+      covariant: true,
+    );
+  }
+
+  void test_interfaceType_sameClass() {
+    _checkIsSubtypeMatchOf(
+      listNone(T_none),
+      listNone(stringNone),
+      [T],
+      ['T <: String'],
+      covariant: true,
+    );
+  }
+
+  void test_interfaceType_topMerge() {
+    var testClassIndex = 0;
+
+    void check1(
+      DartType extendsTypeArgument,
+      DartType implementsTypeArgument,
+      String expectedConstraint,
+    ) {
+      var library = library_(
+        uriStr: 'package:test/test.dart',
+        analysisSession: analysisContext.analysisSession,
+        typeSystem: typeSystem,
+      );
+
+      // class A<T> {}
+      var A = class_(name: 'A', typeParameters: [
+        typeParameter('T'),
+      ]);
+      A.enclosingElement = library.definingCompilationUnit;
+
+      // class B<T> extends A<T> {}
+      var B_T = typeParameter('T');
+      var B_T_none = typeParameterTypeNone(B_T);
+      var B = class_(
+        name: 'B',
+        typeParameters: [B_T],
+        superType: interfaceTypeNone(A, typeArguments: [B_T_none]),
+      );
+      B.enclosingElement = library.definingCompilationUnit;
+
+      // class Cx extends A<> implements B<> {}
+      var C = class_(
+        name: 'C${testClassIndex++}',
+        superType: interfaceTypeNone(
+          A,
+          typeArguments: [extendsTypeArgument],
+        ),
+        interfaces: [
+          interfaceTypeNone(
+            B,
+            typeArguments: [implementsTypeArgument],
+          )
+        ],
+      );
+      C.enclosingElement = library.definingCompilationUnit;
+
+      _checkIsSubtypeMatchOf(
+        interfaceTypeNone(C),
+        interfaceTypeNone(A, typeArguments: [T_none]),
+        [T],
+        [expectedConstraint],
+        covariant: false,
+      );
+    }
+
+    void check(
+      DartType typeArgument1,
+      DartType typeArgument2,
+      String expectedConstraint,
+    ) {
+      check1(typeArgument1, typeArgument2, expectedConstraint);
+      check1(typeArgument2, typeArgument1, expectedConstraint);
+    }
+
+    check(objectQuestion, dynamicNone, 'Object? <: T');
+    check(objectStar, dynamicNone, 'Object? <: T');
+    check(voidNone, objectQuestion, 'Object? <: T');
+    check(voidNone, objectStar, 'Object? <: T');
+  }
+
+  void test_left_null() {
+    // Null <: T is trivially satisfied by the constraint Null <: T.
+    _checkIsSubtypeMatchOf(nullNone, T_none, [T], ['Null <: T'],
+        covariant: false);
+
+    // For any other type X, Null <: X is satisfied without the need for any
+    // constraints.
+    _checkOrdinarySubtypeMatch(nullNone, listQuestion(T_none), [T],
+        covariant: false);
+    _checkOrdinarySubtypeMatch(nullNone, stringQuestion, [T], covariant: false);
+    _checkOrdinarySubtypeMatch(nullNone, voidNone, [T], covariant: false);
+    _checkOrdinarySubtypeMatch(nullNone, dynamicNone, [T], covariant: false);
+    _checkOrdinarySubtypeMatch(nullNone, objectQuestion, [T], covariant: false);
+    _checkOrdinarySubtypeMatch(nullNone, nullNone, [T], covariant: false);
+    _checkOrdinarySubtypeMatch(
+      nullNone,
+      functionTypeQuestion(returnType: voidNone),
+      [T],
+      covariant: false,
+    );
+  }
+
+  void test_right_dynamic() {
+    // T <: dynamic is trivially satisfied by the constraint T <: dynamic.
+    _checkIsSubtypeMatchOf(T_none, dynamicNone, [T], ['T <: dynamic'],
+        covariant: true);
+
+    // For any other type X, X <: dynamic is satisfied without the need for any
+    // constraints.
+    _checkOrdinarySubtypeMatch(listNone(T_none), dynamicNone, [T],
+        covariant: true);
+    _checkOrdinarySubtypeMatch(stringNone, dynamicNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(voidNone, dynamicNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(dynamicNone, dynamicNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(objectNone, dynamicNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(nullNone, dynamicNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: intNone),
+        ],
+        returnType: stringNone,
+      ),
+      dynamicNone,
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_right_object() {
+    // T <: Object is trivially satisfied by the constraint T <: Object.
+    _checkIsSubtypeMatchOf(T_none, objectNone, [T], ['T <: Object'],
+        covariant: true);
+
+    // For any other type X, X <: Object is satisfied without the need for any
+    // constraints.
+    _checkOrdinarySubtypeMatch(listNone(T_none), objectNone, [T],
+        covariant: true);
+    _checkOrdinarySubtypeMatch(stringNone, objectNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(voidNone, objectNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(dynamicNone, objectNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(objectNone, objectNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(nullNone, objectNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: intNone),
+        ],
+        returnType: stringNone,
+      ),
+      objectNone,
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_right_void() {
+    // T <: void is trivially satisfied by the constraint T <: void.
+    _checkIsSubtypeMatchOf(T_none, voidNone, [T], ['T <: void'],
+        covariant: true);
+
+    // For any other type X, X <: void is satisfied without the need for any
+    // constraints.
+    _checkOrdinarySubtypeMatch(listNone(T_none), voidNone, [T],
+        covariant: true);
+    _checkOrdinarySubtypeMatch(stringNone, voidNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(voidNone, voidNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(dynamicNone, voidNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(objectNone, voidNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(nullNone, voidNone, [T], covariant: true);
+    _checkOrdinarySubtypeMatch(
+      functionTypeNone(
+        parameters: [
+          requiredParameter(type: intNone),
+        ],
+        returnType: stringNone,
+      ),
+      voidNone,
+      [T],
+      covariant: true,
+    );
+  }
+
+  void test_typeParameter_left_covariant() {
+    // When doing a covariant match, the type parameters we're trying to find
+    // types for are on the left hand side.
+    _checkIsSubtypeMatchOf(T_none, stringNone, [T], ['T <: String'],
+        covariant: true);
+  }
+
+  void test_typeParameter_left_covariant_match() {
+    // When doing a covariant match, the type parameters we're trying to find
+    // types for are on the left hand side.  If a type parameter appears on the
+    // right hand side, there is a condition in which the constraint can be
+    // satisfied: where both parameters appear at corresponding locations in the
+    // type tree.
+    //
+    // In other words, T <: S can be satisfied trivially by the constraint
+    // T <: S.
+    var S = typeParameter('S');
+    var S_none = typeParameterTypeNone(S);
+    _checkIsSubtypeMatchOf(T_none, S_none, [T], ['T <: S'], covariant: true);
+  }
+
+  void test_typeParameter_left_covariant_no_match() {
+    // When doing a covariant match, the type parameters we're trying to find
+    // types for are on the left hand side.  If a type parameter appears on the
+    // right hand side, it's probable that the constraint can't be satisfied,
+    // because there is no possible type for the LHS (other than bottom)
+    // that's guaranteed to satisfy the relation for all possible assignments of
+    // the RHS type parameter.
+    //
+    // In other words, no match can be found for List<T> <: S because regardless
+    // of T, we can't guarantee that List<T> <: S for all S.
+    var S = typeParameter('S');
+    var S_none = typeParameterTypeNone(S);
+    _checkIsNotSubtypeMatchOf(listNone(T_none), S_none, [T], covariant: true);
+  }
+
+  void test_typeParameter_nullable() {
+    _checkIsSubtypeMatchOf(T_question, stringQuestion, [T], ['T <: String'],
+        covariant: true);
+
+    _checkIsSubtypeMatchOf(stringQuestion, T_question, [T], ['String <: T'],
+        covariant: false);
+  }
+
+  void test_typeParameter_right_contravariant() {
+    // When doing a contravariant match, the type parameters we're trying to
+    // find types for are on the right hand side.
+    _checkIsSubtypeMatchOf(stringNone, T_none, [T], ['String <: T'],
+        covariant: false);
+  }
+
+  void test_typeParameter_right_contravariant_direct() {
+    // When doing a contravariant match, the type parameters we're trying to
+    // find types for are on the right hand side.  If a type parameter also
+    // appears on the left hand side, there is a condition in which the
+    // constraint can be satisfied without consulting the bound of the LHS type
+    // parameter: the condition where both parameters appear at corresponding
+    // locations in the type tree.
+    //
+    // In other words, List<S> <: List<T> is satisfied provided that
+    // S <: T.
+    var S = typeParameter('S');
+    var S_none = typeParameterTypeNone(S);
+    _checkIsSubtypeMatchOf(listNone(S_none), listNone(T_none), [T], ['S <: T'],
+        covariant: false);
+  }
+
+  void test_typeParameter_right_contravariant_via_bound() {
+    // When doing a contravariant match, the type parameters we're trying to
+    // find types for are on the right hand side.  If a type parameter also
+    // appears on the left hand side, we may have to constrain the RHS type
+    // parameter using the bounds of the LHS type parameter.
+    //
+    // In other words, S <: List<T> is satisfied provided that
+    // bound(S) <: List<T>.
+    var S = typeParameter('S', bound: listNone(stringNone));
+    var S_none = typeParameterTypeNone(S);
+    _checkIsSubtypeMatchOf(S_none, listNone(T_none), [T], ['String <: T'],
+        covariant: false);
+  }
+
+  void test_variance_contravariant() {
+    // class A<in T>
+    var T = typeParameter('T', variance: Variance.contravariant);
+    var T_none = typeParameterTypeNone(T);
+    var A = class_(name: 'A', typeParameters: [T]);
+
+    _checkIsSubtypeMatchOf(
+      interfaceTypeNone(A, typeArguments: [T_none]),
+      interfaceTypeNone(A, typeArguments: [numNone]),
+      [T],
+      ['num <: in T'],
+      covariant: true,
+    );
+  }
+
+  void test_variance_covariant() {
+    // class A<out T>
+    var T = typeParameter('T', variance: Variance.covariant);
+    var T_none = typeParameterTypeNone(T);
+    var A = class_(name: 'A', typeParameters: [T]);
+
+    _checkIsSubtypeMatchOf(
+      interfaceTypeNone(A, typeArguments: [T_none]),
+      interfaceTypeNone(A, typeArguments: [numNone]),
+      [T],
+      ['out T <: num'],
+      covariant: true,
+    );
+  }
+
+  void test_variance_invariant() {
+    // class A<inout T>
+    var T = typeParameter('T', variance: Variance.invariant);
+    var T_none = typeParameterTypeNone(T);
+    var A = class_(name: 'A', typeParameters: [T]);
+
+    _checkIsSubtypeMatchOf(
+      interfaceTypeNone(A, typeArguments: [T_none]),
+      interfaceTypeNone(A, typeArguments: [numNone]),
+      [T],
+      ['inout T <: num', 'num <: inout T'],
+      covariant: true,
+    );
+  }
+
+  void _checkIsNotSubtypeMatchOf(
+    DartType subtype,
+    DartType supertype,
+    List<TypeParameterElement> typeFormals, {
+    @required bool covariant,
+  }) {
+    var inferrer = GenericInferrer(typeSystem, typeFormals);
+
+    var success = inferrer.tryMatchSubtypeOf(subtype, supertype, null,
+        covariant: covariant);
+    expect(success, isFalse);
+
+    inferrer.constraints.forEach((typeParameter, constraints) {
+      expect(constraints, isEmpty);
+    });
+  }
+
+  void _checkIsSubtypeMatchOf(
+    DartType subtype,
+    DartType supertype,
+    List<TypeParameterElement> typeFormals,
+    Iterable<String> expectedConstraints, {
+    @required bool covariant,
+  }) {
+    var inferrer = GenericInferrer(typeSystem, typeFormals);
+
+    var success = inferrer.tryMatchSubtypeOf(subtype, supertype, null,
+        covariant: covariant);
+    expect(success, isTrue);
+
+    var formattedConstraints = <String>[];
+    inferrer.constraints.forEach((typeParameter, constraints) {
+      for (var constraint in constraints) {
+        formattedConstraints.add(
+          constraint.format(
+            typeParameter.getDisplayString(withNullability: true),
+            withNullability: true,
+          ),
+        );
+      }
+    });
+    expect(formattedConstraints, unorderedEquals(expectedConstraints));
+  }
+
+  void _checkOrdinarySubtypeMatch(
+    DartType subtype,
+    DartType supertype,
+    List<TypeParameterElement> typeFormals, {
+    @required bool covariant,
+  }) {
+    var expectSuccess = typeSystem.isSubtypeOf(subtype, supertype);
+    if (expectSuccess) {
+      _checkIsSubtypeMatchOf(subtype, supertype, typeFormals, [],
+          covariant: covariant);
+    } else {
+      _checkIsNotSubtypeMatchOf(subtype, supertype, typeFormals,
+          covariant: covariant);
+    }
+  }
+}
+
+@reflectiveTest
+class GenericFunctionInferenceTest extends AbstractTypeSystemNullSafetyTest {
+  void test_boundedByAnotherTypeParameter() {
+    // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
+    var tFrom = typeParameter('TFrom');
+    var tTo =
+        typeParameter('TTo', bound: iterableNone(typeParameterTypeNone(tFrom)));
+    var cast = functionTypeNone(
+      typeFormals: [tFrom, tTo],
+      parameters: [
+        requiredParameter(
+          type: typeParameterTypeNone(tFrom),
+        ),
+      ],
+      returnType: typeParameterTypeNone(tTo),
+    );
+    expect(_inferCall(cast, [stringNone]),
+        [stringNone, (iterableNone(stringNone))]);
+  }
+
+  void test_boundedByOuterClass() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
+
+    // class A {}
+    var A = class_(name: 'A', superType: objectNone);
+    var typeA = interfaceTypeNone(A);
+
+    // class B extends A {}
+    var B = class_(name: 'B', superType: typeA);
+    var typeB = interfaceTypeNone(B);
+
+    // class C<T extends A> {
+    var CT = typeParameter('T', bound: typeA);
+    var C = class_(
+      name: 'C',
+      superType: objectNone,
+      typeParameters: [CT],
+    );
+    //   S m<S extends T>(S);
+    var S = typeParameter('S', bound: typeParameterTypeNone(CT));
+    var m = method(
+      'm',
+      typeParameterTypeNone(S),
+      typeFormals: [S],
+      parameters: [
+        requiredParameter(
+          name: '_',
+          type: typeParameterTypeNone(S),
+        ),
+      ],
+    );
+    C.methods = [m];
+    // }
+
+    // C<Object> cOfObject;
+    var cOfObject = interfaceTypeNone(C, typeArguments: [objectNone]);
+    // C<A> cOfA;
+    var cOfA = interfaceTypeNone(C, typeArguments: [typeA]);
+    // C<B> cOfB;
+    var cOfB = interfaceTypeNone(C, typeArguments: [typeB]);
+    // B b;
+    // cOfB.m(b); // infer <B>
+    _assertType(
+        _inferCall2(cOfB.getMethod('m').type, [typeB]), 'B Function(B)');
+    // cOfA.m(b); // infer <B>
+    _assertType(
+        _inferCall2(cOfA.getMethod('m').type, [typeB]), 'B Function(B)');
+    // cOfObject.m(b); // infer <B>
+    _assertType(
+        _inferCall2(cOfObject.getMethod('m').type, [typeB]), 'B Function(B)');
+  }
+
+  void test_boundedByOuterClassSubstituted() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
+
+    // class A {}
+    var A = class_(name: 'A', superType: objectNone);
+    var typeA = interfaceTypeNone(A);
+
+    // class B extends A {}
+    var B = class_(name: 'B', superType: typeA);
+    var typeB = interfaceTypeNone(B);
+
+    // class C<T extends A> {
+    var CT = typeParameter('T', bound: typeA);
+    var C = class_(
+      name: 'C',
+      superType: objectNone,
+      typeParameters: [CT],
+    );
+    //   S m<S extends Iterable<T>>(S);
+    var iterableOfT = iterableNone(typeParameterTypeNone(CT));
+    var S = typeParameter('S', bound: iterableOfT);
+    var m = method(
+      'm',
+      typeParameterTypeNone(S),
+      typeFormals: [S],
+      parameters: [
+        requiredParameter(
+          name: '_',
+          type: typeParameterTypeNone(S),
+        ),
+      ],
+    );
+    C.methods = [m];
+    // }
+
+    // C<Object> cOfObject;
+    var cOfObject = interfaceTypeNone(C, typeArguments: [objectNone]);
+    // C<A> cOfA;
+    var cOfA = interfaceTypeNone(C, typeArguments: [typeA]);
+    // C<B> cOfB;
+    var cOfB = interfaceTypeNone(C, typeArguments: [typeB]);
+    // List<B> b;
+    var listOfB = listNone(typeB);
+    // cOfB.m(b); // infer <B>
+    _assertType(_inferCall2(cOfB.getMethod('m').type, [listOfB]),
+        'List<B> Function(List<B>)');
+    // cOfA.m(b); // infer <B>
+    _assertType(_inferCall2(cOfA.getMethod('m').type, [listOfB]),
+        'List<B> Function(List<B>)');
+    // cOfObject.m(b); // infer <B>
+    _assertType(_inferCall2(cOfObject.getMethod('m').type, [listOfB]),
+        'List<B> Function(List<B>)');
+  }
+
+  void test_boundedRecursively() {
+    // class A<T extends A<T>>
+    var T = typeParameter('T');
+    var A = class_(
+      name: 'Cloneable',
+      superType: objectNone,
+      typeParameters: [T],
+    );
+    T.bound = interfaceTypeNone(
+      A,
+      typeArguments: [typeParameterTypeNone(T)],
+    );
+
+    // class B extends A<B> {}
+    var B = class_(name: 'B', superType: null);
+    B.supertype = interfaceTypeNone(A, typeArguments: [interfaceTypeNone(B)]);
+    var typeB = interfaceTypeNone(B);
+
+    // <S extends A<S>>
+    var S = typeParameter('S');
+    var typeS = typeParameterTypeNone(S);
+    S.bound = interfaceTypeNone(A, typeArguments: [typeS]);
+
+    // (S, S) -> S
+    var clone = functionTypeNone(
+      typeFormals: [S],
+      parameters: [
+        requiredParameter(type: typeS),
+        requiredParameter(type: typeS),
+      ],
+      returnType: typeS,
+    );
+    expect(_inferCall(clone, [typeB, typeB]), [typeB]);
+
+    // Something invalid...
+    expect(
+      _inferCall(clone, [stringNone, numNone], expectError: true),
+      [objectNone],
+    );
+  }
+
+  void test_genericCastFunction() {
+    // <TFrom, TTo>(TFrom) -> TTo
+    var tFrom = typeParameter('TFrom');
+    var tTo = typeParameter('TTo');
+    var cast = functionTypeNone(
+      typeFormals: [tFrom, tTo],
+      parameters: [
+        requiredParameter(
+          type: typeParameterTypeNone(tFrom),
+        ),
+      ],
+      returnType: typeParameterTypeNone(tTo),
+    );
+    expect(_inferCall(cast, [intNone]), [intNone, dynamicNone]);
+  }
+
+  void test_genericCastFunctionWithUpperBound() {
+    // <TFrom, TTo extends TFrom>(TFrom) -> TTo
+    var tFrom = typeParameter('TFrom');
+    var tTo = typeParameter(
+      'TTo',
+      bound: typeParameterTypeNone(tFrom),
+    );
+    var cast = functionTypeNone(
+      typeFormals: [tFrom, tTo],
+      parameters: [
+        requiredParameter(
+          type: typeParameterTypeNone(tFrom),
+        ),
+      ],
+      returnType: typeParameterTypeNone(tTo),
+    );
+    expect(_inferCall(cast, [intNone]), [intNone, intNone]);
+  }
+
+  void test_parameter_contravariantUseUpperBound() {
+    // <T>(T x, void Function(T) y) -> T
+    // Generates constraints int <: T <: num.
+    // Since T is contravariant, choose num.
+    var T = typeParameter('T', variance: Variance.contravariant);
+    var tFunction = functionTypeNone(
+        parameters: [requiredParameter(type: typeParameterTypeNone(T))],
+        returnType: voidNone);
+    var numFunction = functionTypeNone(
+        parameters: [requiredParameter(type: numNone)], returnType: voidNone);
+    var function = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(type: typeParameterTypeNone(T)),
+        requiredParameter(type: tFunction)
+      ],
+      returnType: typeParameterTypeNone(T),
+    );
+
+    expect(_inferCall(function, [intNone, numFunction]), [numNone]);
+  }
+
+  void test_parameter_covariantUseLowerBound() {
+    // <T>(T x, void Function(T) y) -> T
+    // Generates constraints int <: T <: num.
+    // Since T is covariant, choose int.
+    var T = typeParameter('T', variance: Variance.covariant);
+    var tFunction = functionTypeNone(
+        parameters: [requiredParameter(type: typeParameterTypeNone(T))],
+        returnType: voidNone);
+    var numFunction = functionTypeNone(
+        parameters: [requiredParameter(type: numNone)], returnType: voidNone);
+    var function = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(type: typeParameterTypeNone(T)),
+        requiredParameter(type: tFunction)
+      ],
+      returnType: typeParameterTypeNone(T),
+    );
+
+    expect(_inferCall(function, [intNone, numFunction]), [intNone]);
+  }
+
+  void test_parametersToFunctionParam() {
+    // <T>(f(T t)) -> T
+    var T = typeParameter('T');
+    var cast = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(
+                type: typeParameterTypeNone(T),
+              ),
+            ],
+            returnType: dynamicNone,
+          ),
+        ),
+      ],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(
+      _inferCall(cast, [
+        functionTypeNone(
+          parameters: [
+            requiredParameter(type: numNone),
+          ],
+          returnType: dynamicNone,
+        )
+      ]),
+      [numNone],
+    );
+  }
+
+  void test_parametersUseLeastUpperBound() {
+    // <T>(T x, T y) -> T
+    var T = typeParameter('T');
+    var cast = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(type: typeParameterTypeNone(T)),
+        requiredParameter(type: typeParameterTypeNone(T)),
+      ],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(_inferCall(cast, [intNone, doubleNone]), [numNone]);
+  }
+
+  void test_parameterTypeUsesUpperBound() {
+    // <T extends num>(T) -> dynamic
+    var T = typeParameter('T', bound: numNone);
+    var f = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(type: typeParameterTypeNone(T)),
+      ],
+      returnType: dynamicNone,
+    );
+    expect(_inferCall(f, [intNone]), [intNone]);
+  }
+
+  void test_returnFunctionWithGenericParameter() {
+    // <T>(T -> T) -> (T -> void)
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(type: typeParameterTypeNone(T)),
+            ],
+            returnType: typeParameterTypeNone(T),
+          ),
+        ),
+      ],
+      returnType: functionTypeNone(
+        parameters: [
+          requiredParameter(type: typeParameterTypeNone(T)),
+        ],
+        returnType: voidNone,
+      ),
+    );
+    expect(
+      _inferCall(f, [
+        functionTypeNone(
+          parameters: [
+            requiredParameter(type: numNone),
+          ],
+          returnType: intNone,
+        ),
+      ]),
+      [intNone],
+    );
+  }
+
+  void test_returnFunctionWithGenericParameterAndContext() {
+    // <T>(T -> T) -> (T -> Null)
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(type: typeParameterTypeNone(T)),
+            ],
+            returnType: typeParameterTypeNone(T),
+          ),
+        ),
+      ],
+      returnType: functionTypeNone(
+        parameters: [
+          requiredParameter(type: typeParameterTypeNone(T)),
+        ],
+        returnType: nullNone,
+      ),
+    );
+    expect(
+      _inferCall(
+        f,
+        [],
+        returnType: functionTypeNone(
+          parameters: [
+            requiredParameter(type: numNone),
+          ],
+          returnType: intNone,
+        ),
+      ),
+      [numNone],
+    );
+  }
+
+  void test_returnFunctionWithGenericParameterAndReturn() {
+    // <T>(T -> T) -> (T -> T)
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(type: typeParameterTypeNone(T)),
+            ],
+            returnType: typeParameterTypeNone(T),
+          ),
+        ),
+      ],
+      returnType: functionTypeNone(
+        parameters: [
+          requiredParameter(type: typeParameterTypeNone(T)),
+        ],
+        returnType: typeParameterTypeNone(T),
+      ),
+    );
+    expect(
+      _inferCall(f, [
+        functionTypeNone(
+          parameters: [
+            requiredParameter(type: numNone),
+          ],
+          returnType: intNone,
+        )
+      ]),
+      [intNone],
+    );
+  }
+
+  void test_returnFunctionWithGenericReturn() {
+    // <T>(T -> T) -> (() -> T)
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(type: typeParameterTypeNone(T)),
+            ],
+            returnType: typeParameterTypeNone(T),
+          ),
+        ),
+      ],
+      returnType: functionTypeNone(
+        returnType: typeParameterTypeNone(T),
+      ),
+    );
+    expect(
+      _inferCall(f, [
+        functionTypeNone(
+          parameters: [
+            requiredParameter(type: numNone),
+          ],
+          returnType: intNone,
+        )
+      ]),
+      [intNone],
+    );
+  }
+
+  void test_returnTypeFromContext() {
+    // <T>() -> T
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(_inferCall(f, [], returnType: stringNone), [stringNone]);
+  }
+
+  void test_returnTypeWithBoundFromContext() {
+    // <T extends num>() -> T
+    var T = typeParameter('T', bound: numNone);
+    var f = functionTypeNone(
+      typeFormals: [T],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(_inferCall(f, [], returnType: doubleNone), [doubleNone]);
+  }
+
+  void test_returnTypeWithBoundFromInvalidContext() {
+    // <T extends num>() -> T
+    var T = typeParameter('T', bound: numNone);
+    var f = functionTypeNone(
+      typeFormals: [T],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(_inferCall(f, [], returnType: stringNone), [neverNone]);
+  }
+
+  void test_unifyParametersToFunctionParam() {
+    // <T>(f(T t), g(T t)) -> T
+    var T = typeParameter('T');
+    var cast = functionTypeNone(
+      typeFormals: [T],
+      parameters: [
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(
+                type: typeParameterTypeNone(T),
+              ),
+            ],
+            returnType: dynamicNone,
+          ),
+        ),
+        requiredParameter(
+          type: functionTypeNone(
+            parameters: [
+              requiredParameter(
+                type: typeParameterTypeNone(T),
+              ),
+            ],
+            returnType: dynamicNone,
+          ),
+        ),
+      ],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(
+      _inferCall(cast, [
+        functionTypeNone(
+          parameters: [
+            requiredParameter(type: intNone),
+          ],
+          returnType: dynamicNone,
+        ),
+        functionTypeNone(
+          parameters: [
+            requiredParameter(type: doubleNone),
+          ],
+          returnType: dynamicNone,
+        )
+      ]),
+      [neverNone],
+    );
+  }
+
+  void test_unusedReturnTypeIsDynamic() {
+    // <T>() -> T
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(_inferCall(f, []), [dynamicNone]);
+  }
+
+  void test_unusedReturnTypeWithUpperBound() {
+    // <T extends num>() -> T
+    var T = typeParameter('T', bound: numNone);
+    var f = functionTypeNone(
+      typeFormals: [T],
+      returnType: typeParameterTypeNone(T),
+    );
+    expect(_inferCall(f, []), [numNone]);
+  }
+
+  void _assertType(DartType type, String expected) {
+    var typeStr = type.getDisplayString(withNullability: false);
+    expect(typeStr, expected);
+  }
+
+  List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
+      {DartType returnType, bool expectError = false}) {
+    var listener = RecordingErrorListener();
+
+    var reporter = ErrorReporter(
+      listener,
+      NonExistingSource('/test.dart', toUri('/test.dart'), UriKind.FILE_URI),
+      isNonNullableByDefault: false,
+    );
+
+    var typeArguments = typeSystem.inferGenericFunctionOrType(
+      typeParameters: ft.typeFormals,
+      parameters: ft.parameters,
+      declaredReturnType: ft.returnType,
+      argumentTypes: arguments,
+      contextReturnType: returnType,
+      errorReporter: reporter,
+      errorNode: astFactory.nullLiteral(KeywordToken(Keyword.NULL, 0)),
+    );
+
+    if (expectError) {
+      expect(listener.errors.map((e) => e.errorCode).toList(),
+          [StrongModeCode.COULD_NOT_INFER],
+          reason: 'expected exactly 1 could not infer error.');
+    } else {
+      expect(listener.errors, isEmpty, reason: 'did not expect any errors.');
+    }
+    return typeArguments;
+  }
+
+  FunctionType _inferCall2(FunctionTypeImpl ft, List<DartType> arguments,
+      {DartType returnType, bool expectError = false}) {
+    var typeArguments = _inferCall(
+      ft,
+      arguments,
+      returnType: returnType,
+      expectError: expectError,
+    );
+    return ft.instantiate(typeArguments);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
index dc308ff..e7b9cbae 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
@@ -1075,10 +1075,35 @@
 ''');
 
     _assertInheritedMap('C', r'''
-B.foo: void Function({required int a})
+A.foo: void Function({int a})
 ''');
   }
 
+  test_getMember_mixin_notMerge_replace() async {
+    await resolveTestCode('''
+class A<T> {
+  T foo() => throw 0;
+}
+
+mixin M<T> {
+  T foo() => throw 1;
+}
+
+class X extends A<dynamic> with M<Object?> {}
+class Y extends A<Object?> with M<dynamic> {}
+''');
+    _assertGetMember2(
+      className: 'X',
+      name: 'foo',
+      expected: 'M.foo: Object? Function()',
+    );
+    _assertGetMember2(
+      className: 'Y',
+      name: 'foo',
+      expected: 'M.foo: dynamic Function()',
+    );
+  }
+
   test_getMember_optIn_inheritsOptIn() async {
     newFile('/test/lib/a.dart', content: r'''
 class A {
@@ -1201,12 +1226,38 @@
   int bar(int a) => 0;
 }
 ''');
-    _assertGetMember(
+    _assertGetMember2(
       className: 'B',
       name: 'foo',
       expected: 'A.foo: int* Function(int*, int*)*',
     );
-    _assertGetMember(
+
+    _assertGetMember2(
+      className: 'B',
+      name: 'bar',
+      expected: 'B.bar: int* Function(int*)*',
+    );
+  }
+
+  test_getMember_optOut_mixesOptIn() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  int foo(int a, int? b) => 0;
+}
+''');
+    await resolveTestCode('''
+// @dart = 2.6
+import 'a.dart';
+class B with A {
+  int bar(int a) => 0;
+}
+''');
+    _assertGetMember2(
+      className: 'B',
+      name: 'foo',
+      expected: 'A.foo: int* Function(int*, int*)*',
+    );
+    _assertGetMember2(
       className: 'B',
       name: 'bar',
       expected: 'B.bar: int* Function(int*)*',
@@ -1303,6 +1354,26 @@
     _assertExecutable(member, expected);
   }
 
+  void _assertGetMember2({
+    @required String className,
+    @required String name,
+    String expected,
+  }) {
+    _assertGetMember(
+      className: className,
+      name: name,
+      expected: expected,
+      concrete: false,
+    );
+
+    _assertGetMember(
+      className: className,
+      name: name,
+      expected: expected,
+      concrete: true,
+    );
+  }
+
   void _assertInheritedConcreteMap(String className, String expected) {
     var type = _classInterfaceType(className);
     var map = manager.getInheritedConcreteMap(type);
diff --git a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
index 9cb8284..3e95b6c 100644
--- a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
@@ -5,9 +5,9 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/least_upper_bound.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/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -166,7 +166,7 @@
       interfaces: [
         InstantiatedClass(
           classB,
-          [typeParameterType(CT)],
+          [typeParameterTypeStar(CT)],
         ).withNullabilitySuffixNone,
       ],
     );
@@ -228,7 +228,7 @@
       typeParameters: typeParametersC,
       supertype: InstantiatedClass(
         classB,
-        [typeParameterType(typeParametersC[0])],
+        [typeParameterTypeStar(typeParametersC[0])],
       ).withNullabilitySuffixNone,
     );
 
diff --git a/pkg/analyzer/test/src/dart/element/subtype_test.dart b/pkg/analyzer/test/src/dart/element/subtype_test.dart
index 66d8fb5..e7c1853 100644
--- a/pkg/analyzer/test/src/dart/element/subtype_test.dart
+++ b/pkg/analyzer/test/src/dart/element/subtype_test.dart
@@ -6,16 +6,13 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/elements_types_mixin.dart';
-import '../../../generated/test_analysis_context.dart';
+import '../../../generated/type_system_test.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -5965,28 +5962,9 @@
   }
 }
 
-@reflectiveTest
-class _SubtypingTestBase with ElementsTypesMixin {
-  @override
-  TypeProvider typeProvider;
-
-  TypeSystemImpl typeSystem;
-
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting();
-  }
-
-  void setUp() {
-    var analysisContext = TestAnalysisContext(
-      featureSet: testFeatureSet,
-    );
-    typeProvider = analysisContext.typeProviderNonNullableByDefault;
-    typeSystem = analysisContext.typeSystemNonNullableByDefault;
-  }
-}
+class _SubtypingTestBase extends AbstractTypeSystemNullSafetyTest {}
 
 class _TypeParameterCollector extends DartTypeVisitor<void> {
-//  final Set<TypeParameterElement> typeParameters = {};
   final Set<String> typeParameters = {};
 
   /// We don't need to print bounds for these type parameters, because
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 43eab7c..ef6a0df 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -4,10 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'class_hierarchy_test.dart' as class_hierarchy;
 import 'element_test.dart' as element;
 import 'factor_type_test.dart' as factor_type;
 import 'flatten_type_test.dart' as flatten_type;
 import 'function_type_test.dart' as function_type;
+import 'generic_inferrer_test.dart' as generic_inferrer;
 import 'inheritance_manager3_test.dart' as inheritance_manager3;
 import 'least_upper_bound_helper_test.dart' as least_upper_bound_helper;
 import 'normalize_type_test.dart' as normalize_type;
@@ -24,10 +26,12 @@
 /// Utility for manually running all tests.
 main() {
   defineReflectiveSuite(() {
+    class_hierarchy.main();
     element.main();
     factor_type.main();
     flatten_type.main();
     function_type.main();
+    generic_inferrer.main();
     inheritance_manager3.main();
     least_upper_bound_helper.main();
     normalize_type.main();
diff --git a/pkg/analyzer/test/src/dart/element/top_merge_test.dart b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
index 6f77a5f..008ed17 100644
--- a/pkg/analyzer/test/src/dart/element/top_merge_test.dart
+++ b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
@@ -46,7 +46,7 @@
     _check(
       functionTypeNone(returnType: voidNone),
       functionTypeNone(returnType: objectQuestion),
-      functionTypeNone(returnType: voidNone),
+      functionTypeNone(returnType: objectQuestion),
     );
 
     _check(
@@ -213,7 +213,7 @@
     _check(
       listNone(voidNone),
       listNone(objectQuestion),
-      listNone(voidNone),
+      listNone(objectQuestion),
     );
 
     _check(
@@ -233,6 +233,10 @@
     );
   }
 
+  test_never() {
+    _check(neverNone, neverNone, neverNone);
+  }
+
   test_null() {
     // NNBD_TOP_MERGE(Never*, Null) = Null
     // NNBD_TOP_MERGE(Null, Never*) = Null
@@ -263,16 +267,19 @@
     // NNBD_TOP_MERGE(Object?, Object?) = Object?
     _check(objectQuestion, objectQuestion, objectQuestion);
 
+    // NNBD_TOP_MERGE(Object?, void) = Object?
+    // NNBD_TOP_MERGE(void, Object?) = Object?
+    _check(objectQuestion, voidNone, objectQuestion);
+
     // NNBD_TOP_MERGE(Object?, dynamic) = Object?
     // NNBD_TOP_MERGE(dynamic, Object?) = Object?
     _check(objectQuestion, dynamicNone, objectQuestion);
-    _check(dynamicNone, objectQuestion, objectQuestion);
   }
 
   test_objectStar() {
-    // NNBD_TOP_MERGE(Object*, void) = void
-    // NNBD_TOP_MERGE(void, Object*) = void
-    _check(objectStar, voidNone, voidNone);
+    // NNBD_TOP_MERGE(Object*, void) = Object?
+    // NNBD_TOP_MERGE(void, Object*) = Object?
+    _check(objectStar, voidNone, objectQuestion);
 
     // NNBD_TOP_MERGE(Object*, dynamic) = Object?
     // NNBD_TOP_MERGE(dynamic, Object*) = Object?
@@ -303,15 +310,9 @@
     // NNBD_TOP_MERGE(void, void) = void
     _check(voidNone, voidNone, voidNone);
 
-    // NNBD_TOP_MERGE(void, Object?) = void
-    // NNBD_TOP_MERGE(Object?, void) = void
-    _check(voidNone, objectQuestion, voidNone);
-    _check(objectQuestion, voidNone, voidNone);
-
-    // NNBD_TOP_MERGE(void, dynamic) = void
-    // NNBD_TOP_MERGE(dynamic, void) = void
-    _check(voidNone, dynamicNone, voidNone);
-    _check(dynamicNone, voidNone, voidNone);
+    // NNBD_TOP_MERGE(void, dynamic) = Object?
+    // NNBD_TOP_MERGE(dynamic, void) = Object?
+    _check(voidNone, dynamicNone, objectQuestion);
   }
 
   void _check(DartType T, DartType S, DartType expected) {
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
index 3de9097..75efd3f 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -7,8 +7,8 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:analyzer/src/generated/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -54,7 +54,7 @@
     var substitution = Substitution.fromInterfaceType(BofInt);
 
     // A<U>
-    var type = interfaceTypeStar(A, typeArguments: [typeParameterType(U)]);
+    var type = interfaceTypeStar(A, typeArguments: [typeParameterTypeStar(U)]);
     assertType(type, 'A<U>');
 
     var result = substitution.substituteType(type);
@@ -73,8 +73,8 @@
     var type = interfaceTypeStar(
       A,
       typeArguments: [
-        typeParameterType(T),
-        typeParameterType(U),
+        typeParameterTypeStar(T),
+        typeParameterTypeStar(U),
       ],
     );
 
@@ -93,9 +93,9 @@
     var T = typeParameter('T');
     var type = functionTypeStar(
       parameters: [
-        requiredParameter(type: typeParameterType(T)),
+        requiredParameter(type: typeParameterTypeStar(T)),
       ],
-      returnType: typeParameterType(T),
+      returnType: typeParameterTypeStar(T),
     );
 
     var result = Substitution.fromUpperAndLowerBounds(
@@ -136,10 +136,10 @@
     var U = typeParameter('U');
     var type = functionTypeStar(
       parameters: [
-        requiredParameter(type: typeParameterType(U)),
+        requiredParameter(type: typeParameterTypeStar(U)),
         requiredParameter(type: boolType),
       ],
-      returnType: typeParameterType(T),
+      returnType: typeParameterTypeStar(T),
     );
 
     assertType(type, 'T Function(U, bool)');
@@ -158,13 +158,13 @@
   test_function_typeFormals() async {
     // typedef F<T> = T Function<U extends T>(U);
     var T = typeParameter('T');
-    var U = typeParameter('U', bound: typeParameterType(T));
+    var U = typeParameter('U', bound: typeParameterTypeStar(T));
     var type = functionTypeStar(
       typeFormals: [U],
       parameters: [
-        requiredParameter(type: typeParameterType(U)),
+        requiredParameter(type: typeParameterTypeStar(U)),
       ],
-      returnType: typeParameterType(T),
+      returnType: typeParameterTypeStar(T),
     );
 
     assertType(type, 'T Function<U extends T>(U)');
@@ -188,9 +188,9 @@
     var U = typeParameter('U');
     var V = typeParameter('V');
     T.bound = interfaceTypeStar(classTriplet, typeArguments: [
-      typeParameterType(T),
-      typeParameterType(U),
-      typeParameterType(V),
+      typeParameterTypeStar(T),
+      typeParameterTypeStar(U),
+      typeParameterTypeStar(V),
     ]);
     var type = functionTypeStar(
       typeFormals: [T, U],
@@ -221,7 +221,7 @@
 
     var U = typeParameter('U');
     var type = interfaceTypeStar(A, typeArguments: [
-      typeParameterType(U),
+      typeParameterTypeStar(U),
     ]);
 
     assertType(type, 'A<U>');
@@ -237,7 +237,7 @@
       interfaceTypeStar(
         typeProvider.listElement,
         typeArguments: [
-          typeParameterType(U),
+          typeParameterTypeStar(U),
         ],
       )
     ]);
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index 8e159b5..c41a840 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -6,16 +6,15 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/elements_types_mixin.dart';
-import '../../../generated/test_analysis_context.dart';
+import '../../../generated/type_system_test.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -924,6 +923,56 @@
     );
   }
 
+  test_futureOr() {
+    InterfaceType futureOrFunction(DartType T, String str) {
+      var result = futureOrNone(
+        functionTypeNone(returnType: voidNone, parameters: [
+          requiredParameter(type: T),
+        ]),
+      );
+      expect(result.getDisplayString(withNullability: true), str);
+      return result;
+    }
+
+    // DOWN(FutureOr<T1>, FutureOr<T2>) = FutureOr<S>, S = DOWN(T1, T2)
+    _checkGreatestLowerBound(
+      futureOrNone(intNone),
+      futureOrNone(numNone),
+      futureOrNone(intNone),
+    );
+    _checkGreatestLowerBound(
+      futureOrFunction(intNone, 'FutureOr<void Function(int)>'),
+      futureOrFunction(doubleNone, 'FutureOr<void Function(double)>'),
+      futureOrFunction(numNone, 'FutureOr<void Function(num)>'),
+    );
+
+    // DOWN(FutureOr<T1>, Future<T2>) = Future<S>, S = DOWN(T1, T2)
+    // DOWN(Future<T1>, FutureOr<T2>) = Future<S>, S = DOWN(T1, T2)
+    _checkGreatestLowerBound(
+      futureOrNone(numNone),
+      futureNone(intNone),
+      futureNone(intNone),
+    );
+    _checkGreatestLowerBound(
+      futureOrNone(intNone),
+      futureNone(numNone),
+      futureNone(intNone),
+    );
+
+    // DOWN(FutureOr<T1>, T2) = S, S = DOWN(T1, T2)
+    // DOWN(T1, FutureOr<T2>) = S, S = DOWN(T1, T2)
+    _checkGreatestLowerBound(
+      futureOrNone(numNone),
+      intNone,
+      intNone,
+    );
+    _checkGreatestLowerBound(
+      futureOrNone(intNone),
+      numNone,
+      intNone,
+    );
+  }
+
   test_identical() {
     void check(DartType type) {
       _checkGreatestLowerBound(type, type, type);
@@ -943,8 +992,67 @@
       _checkGreatestLowerBound(T1, T2, expected);
     }
 
+    check(intNone, intNone, intNone);
     check(numNone, intNone, intNone);
     check(doubleNone, intNone, neverNone);
+
+    check(listNone(intNone), listNone(intNone), listNone(intNone));
+    check(listNone(numNone), listNone(intNone), listNone(intNone));
+    check(listNone(doubleNone), listNone(intNone), neverNone);
+  }
+
+  void test_interfaceType2_interfaces() {
+    // class A
+    // class B implements A
+    // class C implements B
+    var A = class_(name: 'A');
+    var B = class_(name: 'B', interfaces: [interfaceTypeNone(A)]);
+    var C = class_(name: 'C', interfaces: [interfaceTypeNone(B)]);
+    _checkGreatestLowerBound(
+      interfaceTypeNone(A),
+      interfaceTypeNone(C),
+      interfaceTypeNone(C),
+    );
+  }
+
+  void test_interfaceType2_mixins() {
+    // class A
+    // class B
+    // class C
+    // class D extends A with B, C
+    var A = class_(name: 'A');
+    var typeA = interfaceTypeNone(A);
+
+    var B = class_(name: 'B');
+    var typeB = interfaceTypeNone(B);
+
+    var C = class_(name: 'C');
+    var typeC = interfaceTypeNone(C);
+
+    var D = class_(
+      name: 'D',
+      superType: interfaceTypeNone(A),
+      mixins: [typeB, typeC],
+    );
+    var typeD = interfaceTypeNone(D);
+
+    _checkGreatestLowerBound(typeA, typeD, typeD);
+    _checkGreatestLowerBound(typeB, typeD, typeD);
+    _checkGreatestLowerBound(typeC, typeD, typeD);
+  }
+
+  void test_interfaceType2_superType() {
+    // class A
+    // class B extends A
+    // class C extends B
+    var A = class_(name: 'A');
+    var B = class_(name: 'B', superType: interfaceTypeNone(A));
+    var C = class_(name: 'C', superType: interfaceTypeNone(B));
+    _checkGreatestLowerBound(
+      interfaceTypeNone(A),
+      interfaceTypeNone(C),
+      interfaceTypeNone(C),
+    );
   }
 
   test_none_question() {
@@ -1147,6 +1255,23 @@
     check(intQuestion, doubleQuestion, neverQuestion);
   }
 
+  test_self() {
+    var T = typeParameter('T');
+
+    List<DartType> types = [
+      dynamicType,
+      voidNone,
+      neverNone,
+      typeParameterTypeStar(T),
+      intNone,
+      functionTypeNone(returnType: voidNone),
+    ];
+
+    for (var type in types) {
+      _checkGreatestLowerBound(type, type, type);
+    }
+  }
+
   test_star_question() {
     void check(DartType T1, DartType T2, DartType expected) {
       _assertNullabilityQuestion(T1);
@@ -1195,6 +1320,8 @@
     check(voidNone, intStar);
     check(voidNone, listNone(intNone));
     check(voidNone, futureOrNone(intNone));
+    check(voidNone, neverNone);
+    check(voidNone, functionTypeNone(returnType: voidNone));
 
     check(dynamicNone, objectNone);
     check(dynamicNone, intNone);
@@ -1202,6 +1329,8 @@
     check(dynamicNone, intStar);
     check(dynamicNone, listNone(intNone));
     check(dynamicNone, futureOrNone(intNone));
+    check(dynamicNone, neverNone);
+    check(dynamicNone, functionTypeNone(returnType: voidNone));
 
     check(objectQuestion, objectNone);
     check(objectQuestion, intNone);
@@ -1209,6 +1338,8 @@
     check(objectQuestion, intStar);
     check(objectQuestion, listNone(intNone));
     check(objectQuestion, futureOrNone(intNone));
+    check(objectQuestion, neverNone);
+    check(objectQuestion, functionTypeNone(returnType: voidNone));
 
     check(objectStar, objectNone);
     check(objectStar, intNone);
@@ -1216,6 +1347,8 @@
     check(objectStar, intStar);
     check(objectStar, listNone(intNone));
     check(objectStar, futureOrNone(intNone));
+    check(objectStar, neverNone);
+    check(objectStar, functionTypeNone(returnType: voidNone));
 
     check(futureOrNone(voidNone), intNone);
     check(futureOrQuestion(voidNone), intNone);
@@ -1278,6 +1411,22 @@
     check(futureOrNone(dynamicNone), futureOrNone(objectStar));
   }
 
+  test_typeParameter() {
+    void check({DartType bound, DartType T2}) {
+      var T1 = typeParameterTypeNone(
+        typeParameter('T', bound: bound),
+      );
+      _checkGreatestLowerBound(T1, T2, neverNone);
+    }
+
+    check(
+      bound: null,
+      T2: functionTypeNone(returnType: voidNone),
+    );
+    check(bound: null, T2: intNone);
+    check(bound: numNone, T2: intNone);
+  }
+
   void _checkGreatestLowerBound(DartType T1, DartType T2, DartType expected,
       {bool checkSubtype = true}) {
     var expectedStr = _typeString(expected);
@@ -2064,24 +2213,7 @@
 }
 
 @reflectiveTest
-class _BoundsTestBase with ElementsTypesMixin {
-  @override
-  TypeProvider typeProvider;
-
-  TypeSystemImpl typeSystem;
-
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting();
-  }
-
-  void setUp() {
-    var analysisContext = TestAnalysisContext(
-      featureSet: testFeatureSet,
-    );
-    typeProvider = analysisContext.typeProviderNonNullableByDefault;
-    typeSystem = analysisContext.typeSystemNonNullableByDefault;
-  }
-
+class _BoundsTestBase extends AbstractTypeSystemNullSafetyTest {
   void _assertNotBottom(DartType type) {
     if (typeSystem.isBottom(type)) {
       fail('isBottom must be false: ' + _typeString(type));
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index 22f938e..ef3df6c 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -5,78 +5,93 @@
 import 'dart:convert';
 
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.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/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 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 '../resolution/resolution.dart';
 
 /// [FileResolver] based implementation of [ResolutionTest].
 class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
+  static final String _testFile = '/workspace/dart/test/lib/test.dart';
+
   final ByteStore byteStore = MemoryByteStore();
 
   final StringBuffer logBuffer = StringBuffer();
   PerformanceLog logger;
+  MockSdk sdk;
 
-  DartSdk sdk;
-  Map<String, List<Folder>> packageMap;
   FileResolver fileResolver;
 
-  List<MockSdkLibrary> get additionalMockSdkLibraries => [];
+  @override
+  void addTestFile(String content) {
+    newFile(_testFile, content: content);
+  }
 
-  /// Override this to change the analysis options for a given set of tests.
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl();
+  /// Create a new [FileResolver] into [fileResolver].
+  ///
+  /// We do this the first time, and to test reusing results from [byteStore].
+  void createFileResolver() {
+    var workspace = BazelWorkspace.find(
+      resourceProvider,
+      convertPath(_testFile),
+    );
+
+    fileResolver = FileResolver(
+      logger,
+      resourceProvider,
+      byteStore,
+      workspace.createSourceFactory(sdk, null),
+      (String path) => _getDigest(path),
+      null,
+      workspace: workspace,
+      libraryContextResetTimeout: null,
+    );
+    fileResolver.testView = FileResolverTestView();
+  }
+
+  ErrorsResult getTestErrors() {
+    var path = convertPath(_testFile);
+    return fileResolver.getErrors(path);
+  }
 
   @override
   Future<ResolvedUnitResult> resolveFile(String path) async {
     return fileResolver.resolve(path);
   }
 
-  String _getDigest(String path) {
-    var content;
-    try {
-      content = resourceProvider.getFile(path).readAsStringSync();
-    } catch (_) {
-      return '';
-    }
-    var contentBytes = utf8.encode(content);
-    return md5.convert(contentBytes).toString();
+  @override
+  Future<void> resolveTestFile() async {
+    var path = convertPath(_testFile);
+    result = await resolveFile(path);
+    findNode = FindNode(result.content, result.unit);
+    findElement = FindElement(result.unit);
   }
 
   void setUp() {
-    sdk = MockSdk(
-      resourceProvider: resourceProvider,
-      additionalLibraries: additionalMockSdkLibraries,
-    );
+    registerLintRules();
+
     logger = PerformanceLog(logBuffer);
+    sdk = MockSdk(resourceProvider: resourceProvider);
 
-    // TODO(brianwilkerson) Create an empty package map by default and only add
-    //  packages in the tests that need them.
-    packageMap = <String, List<Folder>>{
-      'test': [getFolder('/test/lib')],
-      'aaa': [getFolder('/aaa/lib')],
-      'bbb': [getFolder('/bbb/lib')],
-      'meta': [getFolder('/.pub-cache/meta/lib')],
-    };
+    newFile('/workspace/WORKSPACE', content: '');
+    createFileResolver();
+  }
 
-    fileResolver = FileResolver(
-        logger,
-        resourceProvider,
-        byteStore,
-        SourceFactory([
-          DartUriResolver(sdk),
-          PackageMapUriResolver(resourceProvider, packageMap),
-          ResourceUriResolver(resourceProvider)
-        ]),
-        (String path) => _getDigest(path),
-        null);
+  String _getDigest(String path) {
+    try {
+      var content = resourceProvider.getFile(path).readAsStringSync();
+      var contentBytes = utf8.encode(content);
+      return md5.convert(contentBytes).toString();
+    } catch (_) {
+      return '';
+    }
   }
 }
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 d4155ce..28ed93b 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
@@ -2,1301 +2,352 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/lint/registry.dart';
+import 'package:matcher/matcher.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'file_resolution.dart';
-import '../../../generated/resolver_test_case.dart';
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(SimpleFileResolverTest);
+    defineReflectiveTests(FileResolver_changeFile_Test);
+    defineReflectiveTests(FileResolverTest);
   });
 }
 
 @reflectiveTest
-class SimpleFileResolverTest extends FileResolutionTest {
-  test_argumentResolution_required_matching() async {
-    await resolveTestCode(r'''
-class A {
-  void f() {
-    g(1, 2, 3);
-  }
-  void g(a, b, c) {}
-}''');
-    await _validateArgumentResolution([0, 1, 2]);
+class FileResolver_changeFile_Test extends FileResolutionTest {
+  String aPath;
+  String bPath;
+  String cPath;
+
+  @override
+  void setUp() {
+    super.setUp();
+    aPath = convertPath('/workspace/dart/test/lib/a.dart');
+    bPath = convertPath('/workspace/dart/test/lib/b.dart');
+    cPath = convertPath('/workspace/dart/test/lib/c.dart');
   }
 
-  test_argumentResolution_required_tooFew() async {
-    await resolveTestCode(r'''
-class A {
-  void f() {
-    g(1, 2);
-  }
-  void g(a, b, c) {}
-}''');
-    await _validateArgumentResolution([0, 1]);
-  }
-
-  test_argumentResolution_required_tooMany() async {
-    await resolveTestCode(r'''
-class A {
-  void f() {
-    g(1, 2, 3);
-  }
-  void g(a, b) {}
-}''');
-    await _validateArgumentResolution([0, 1, -1]);
-  }
-
-  test_argumentResolution_requiredAndNamed_extra() async {
-    await resolveTestCode('''
-class A {
-  void f() {
-    g(1, 2, c: 3, d: 4);
-  }
-  void g(a, b, {c}) {}
-}''');
-    await _validateArgumentResolution([0, 1, 2, -1]);
-  }
-
-  test_argumentResolution_requiredAndNamed_matching() async {
-    await resolveTestCode(r'''
-class A {
-  void f() {
-    g(1, 2, c: 3);
-  }
-  void g(a, b, {c}) {}
-}''');
-    await _validateArgumentResolution([0, 1, 2]);
-  }
-
-  test_argumentResolution_requiredAndNamed_missing() async {
-    await resolveTestCode('''
-class A {
-  void f() {
-    g(1, 2, d: 3);
-  }
-  void g(a, b, {c, d}) {}
-}''');
-    await _validateArgumentResolution([0, 1, 3]);
-  }
-
-  test_argumentResolution_requiredAndPositional_fewer() async {
-    await resolveTestCode('''
-class A {
-  void f() {
-    g(1, 2, 3);
-  }
-  void g(a, b, [c, d]) {}
-}''');
-    await _validateArgumentResolution([0, 1, 2]);
-  }
-
-  test_argumentResolution_requiredAndPositional_matching() async {
-    await resolveTestCode(r'''
-class A {
-  void f() {
-    g(1, 2, 3, 4);
-  }
-  void g(a, b, [c, d]) {}
-}''');
-    await _validateArgumentResolution([0, 1, 2, 3]);
-  }
-
-  test_argumentResolution_requiredAndPositional_more() async {
-    await resolveTestCode(r'''
-class A {
-  void f() {
-    g(1, 2, 3, 4);
-  }
-  void g(a, b, [c]) {}
-}''');
-    await _validateArgumentResolution([0, 1, 2, -1]);
-  }
-
-  test_argumentResolution_setter_propagated() async {
-    await resolveTestCode(r'''
-main() {
-  var a = new A();
-  a.sss = 0;
-}
-class A {
-  set sss(x) {}
-}''');
-    var rhs = findNode.assignment(' = 0;').rightHandSide;
-    expect(
-      rhs.staticParameterElement,
-      findElement.parameter('x'),
-    );
-  }
-
-  test_argumentResolution_setter_propagated_propertyAccess() async {
-    await resolveTestCode(r'''
-main() {
-  var a = new A();
-  a.b.sss = 0;
-}
-class A {
-  B b = new B();
-}
-class B {
-  set sss(x) {}
-}''');
-    var rhs = findNode.assignment(' = 0;').rightHandSide;
-    expect(
-      rhs.staticParameterElement,
-      findElement.parameter('x'),
-    );
-  }
-
-  test_argumentResolution_setter_static() async {
-    await resolveTestCode(r'''
-main() {
-  A a = new A();
-  a.sss = 0;
-}
-class A {
-  set sss(x) {}
-}''');
-    var rhs = findNode.assignment(' = 0;').rightHandSide;
-    expect(
-      rhs.staticParameterElement,
-      findElement.parameter('x'),
-    );
-  }
-
-  test_argumentResolution_setter_static_propertyAccess() async {
-    await resolveTestCode(r'''
-main() {
-  A a = new A();
-  a.b.sss = 0;
-}
-class A {
-  B b = new B();
-}
-class B {
-  set sss(x) {}
-}''');
-    var rhs = findNode.assignment(' = 0;').rightHandSide;
-    expect(
-      rhs.staticParameterElement,
-      findElement.parameter('x'),
-    );
-  }
-
-  test_breakTarget_labeled() async {
-    // Verify that the target of the label is correctly found and is recorded
-    // as the unlabeled portion of the statement.
-    await resolveTestCode(r'''
-void f() {
-  loop1: while (true) {
-    loop2: for (int i = 0; i < 10; i++) {
-      break loop1;
-      break loop2;
-    }
-  }
-}
+  test_changeFile_refreshedFiles() async {
+    newFile(aPath, content: r'''
+class A {}
 ''');
-    var break1 = findNode.breakStatement('break loop1;');
-    var whileStatement = findNode.whileStatement('while (');
-    expect(break1.target, same(whileStatement));
 
-    var break2 = findNode.breakStatement('break loop2;');
-    var forStatement = findNode.forStatement('for (');
-    expect(break2.target, same(forStatement));
-  }
-
-  test_breakTarget_unlabeledBreakFromDo() async {
-    await resolveTestCode('''
-void f() {
-  do {
-    break;
-  } while (true);
-}
-''');
-    var doStatement = findNode.doStatement('do {');
-    var breakStatement = findNode.breakStatement('break;');
-    expect(breakStatement.target, same(doStatement));
-  }
-
-  test_breakTarget_unlabeledBreakFromFor() async {
-    await resolveTestCode(r'''
-void f() {
-  for (int i = 0; i < 10; i++) {
-    break;
-  }
-}
-''');
-    var forStatement = findNode.forStatement('for (');
-    var breakStatement = findNode.breakStatement('break;');
-    expect(breakStatement.target, same(forStatement));
-  }
-
-  test_breakTarget_unlabeledBreakFromForEach() async {
-    await resolveTestCode('''
-void f() {
-  for (x in []) {
-    break;
-  }
-}
-''');
-    var forStatement = findNode.forStatement('for (');
-    var breakStatement = findNode.breakStatement('break;');
-    expect(breakStatement.target, same(forStatement));
-  }
-
-  test_breakTarget_unlabeledBreakFromSwitch() async {
-    await resolveTestCode(r'''
-void f() {
-  while (true) {
-    switch (0) {
-      case 0:
-        break;
-    }
-  }
-}
-''');
-    var switchStatement = findNode.switchStatement('switch (');
-    var breakStatement = findNode.breakStatement('break;');
-    expect(breakStatement.target, same(switchStatement));
-  }
-
-  test_breakTarget_unlabeledBreakFromWhile() async {
-    await resolveTestCode(r'''
-void f() {
-  while (true) {
-    break;
-  }
-}
-''');
-    var whileStatement = findNode.whileStatement('while (');
-    var breakStatement = findNode.breakStatement('break;');
-    expect(breakStatement.target, same(whileStatement));
-  }
-
-  test_breakTarget_unlabeledBreakToOuterFunction() async {
-    // Verify that unlabeled break statements can't resolve to loops in an
-    // outer function.
-    await resolveTestCode(r'''
-void f() {
-  while (true) {
-    void g() {
-      break;
-    }
-  }
-}
-''');
-    var breakStatement = findNode.breakStatement('break;');
-    expect(breakStatement.target, isNull);
-  }
-
-  test_class_definesCall() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  int call(int x) { return x; }
-}
-int f(A a) {
-  return a(0);
-}''');
-  }
-
-  test_class_extends_implements() async {
-    await assertNoErrorsInCode(r'''
-class A extends B implements C {}
+    newFile(bPath, content: r'''
 class B {}
-class C {}''');
-  }
-
-  test_continueTarget_labeled() async {
-    // Verify that the target of the label is correctly found and is recorded
-    // as the unlabeled portion of the statement.
-    await resolveTestCode('''
-void f() {
-  loop1: while (true) {
-    loop2: for (int i = 0; i < 10; i++) {
-      continue loop1;
-      continue loop2;
-    }
-  }
-}
-''');
-    var continue1 = findNode.continueStatement('continue loop1');
-    var whileStatement = findNode.whileStatement('while (');
-    expect(continue1.target, same(whileStatement));
-
-    var continue2 = findNode.continueStatement('continue loop2');
-    var forStatement = findNode.forStatement('for (');
-    expect(continue2.target, same(forStatement));
-  }
-
-  test_continueTarget_unlabeledContinueFromDo() async {
-    await resolveTestCode('''
-void f() {
-  do {
-    continue;
-  } while (true);
-}
-''');
-    var doStatement = findNode.doStatement('do {');
-    var continueStatement = findNode.continueStatement('continue;');
-    expect(continueStatement.target, same(doStatement));
-  }
-
-  test_continueTarget_unlabeledContinueFromFor() async {
-    await resolveTestCode('''
-void f() {
-  for (int i = 0; i < 10; i++) {
-    continue;
-  }
-}
-''');
-    var forStatement = findNode.forStatement('for (');
-    var continueStatement = findNode.continueStatement('continue;');
-    expect(continueStatement.target, same(forStatement));
-  }
-
-  test_continueTarget_unlabeledContinueFromForEach() async {
-    await resolveTestCode(r'''
-void f() {
-  for (x in []) {
-    continue;
-  }
-}
-''');
-    var forStatement = findNode.forStatement('for (');
-    var continueStatement = findNode.continueStatement('continue;');
-    expect(continueStatement.target, same(forStatement));
-  }
-
-  test_continueTarget_unlabeledContinueFromWhile() async {
-    await resolveTestCode(r'''
-void f() {
-  while (true) {
-    continue;
-  }
-}
-''');
-    var whileStatement = findNode.whileStatement('while (');
-    var continueStatement = findNode.continueStatement('continue;');
-    expect(continueStatement.target, same(whileStatement));
-  }
-
-  test_continueTarget_unlabeledContinueSkipsSwitch() async {
-    await resolveTestCode(r'''
-void f() {
-  while (true) {
-    switch (0) {
-      case 0:
-        continue;
-    }
-  }
-}
-''');
-    var whileStatement = findNode.whileStatement('while (');
-    var continueStatement = findNode.continueStatement('continue;');
-    expect(continueStatement.target, same(whileStatement));
-  }
-
-  test_continueTarget_unlabeledContinueToOuterFunction() async {
-    // Verify that unlabeled continue statements can't resolve to loops in an
-    // outer function.
-    await resolveTestCode(r'''
-void f() {
-  while (true) {
-    void g() {
-      continue;
-    }
-  }
-}
-''');
-    var continueStatement = findNode.continueStatement('continue;');
-    expect(continueStatement.target, isNull);
-  }
-
-  test_empty() async {
-    await assertNoErrorsInCode('');
-  }
-
-  test_entryPoint_exported() async {
-    newFile('/test/lib/a.dart', content: r'''
-main() {}
 ''');
 
-    await assertNoErrorsInCode(r'''
-export 'a.dart';
-''');
-
-    var library = result.libraryElement;
-    var main = library.entryPoint;
-
-    expect(main, isNotNull);
-    expect(main.library, isNot(same(library)));
-  }
-
-  test_entryPoint_local() async {
-    await assertNoErrorsInCode(r'''
-main() {}
-''');
-
-    var library = result.libraryElement;
-    var main = library.entryPoint;
-
-    expect(main, isNotNull);
-    expect(main.library, same(library));
-  }
-
-  test_entryPoint_none() async {
-    await assertNoErrorsInCode('');
-
-    var library = result.libraryElement;
-    expect(library.entryPoint, isNull);
-  }
-
-  test_enum_externalLibrary() async {
-    newFile('/test/lib/a.dart', content: r'''
-enum EEE {A, B, C}
-''');
-    await assertNoErrorsInCode(r'''
+    newFile(cPath, content: r'''
 import 'a.dart';
-
-void f(EEE e) {}
+import 'b.dart';
 ''');
-    verifyTestResolved();
+
+    // First time we refresh everything.
+    await fileResolver.resolve(cPath);
+    _assertRefreshedFiles([aPath, bPath, cPath], withSdk: true);
+
+    // Without changes we refresh nothing.
+    await fileResolver.resolve(cPath);
+    _assertRefreshedFiles([]);
+
+    // We already know a.dart, refresh nothing.
+    await fileResolver.resolve(aPath);
+    _assertRefreshedFiles([]);
+
+    // Change a.dart, refresh a.dart and c.dart, but not b.dart
+    fileResolver.changeFile(aPath);
+    await fileResolver.resolve(cPath);
+    _assertRefreshedFiles([aPath, cPath]);
   }
 
-  test_extractedMethodAsConstant() async {
-    await assertNoErrorsInCode(r'''
-abstract class Comparable<T> {
-  int compareTo(T other);
-  static int compare(Comparable a, Comparable b) => a.compareTo(b);
-}
-class A {
-  void sort([compare = Comparable.compare]) {}
-}''');
-    verifyTestResolved();
-  }
-
-  test_fieldFormalParameter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  int x;
-  int y;
-  A(this.x) : y = x {}
-}''');
-    verifyTestResolved();
-
-    var xParameter = findNode.fieldFormalParameter('this.x');
-
-    var xParameterElement =
-        xParameter.declaredElement as FieldFormalParameterElement;
-    expect(xParameterElement.field, findElement.field('x'));
-
-    assertElement(
-      findNode.simple('x {}'),
-      xParameterElement,
-    );
-  }
-
-  test_forEachLoops_nonConflicting() async {
-    await assertErrorsInCode(r'''
-f() {
-  List list = [1,2,3];
-  for (int x in list) {}
-  for (int x in list) {}
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 40, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 65, 1),
-    ]);
-    verifyTestResolved();
-  }
-
-  test_forLoops_nonConflicting() async {
-    await assertNoErrorsInCode(r'''
-f() {
-  for (int i = 0; i < 3; i++) {
-  }
-  for (int i = 0; i < 3; i++) {
-  }
-}''');
-    verifyTestResolved();
-  }
-
-  test_functionTypeAlias() async {
-    await assertNoErrorsInCode(r'''
-typedef bool P(e);
-class A {
-  P p;
-  m(e) {
-    if (p(e)) {}
-  }
-}''');
-    verifyTestResolved();
-  }
-
-  test_getter_and_setter_fromMixins_bare_identifier() async {
-    await assertNoErrorsInCode('''
-class B {}
-class M1 {
-  get x => null;
-  set x(value) {}
-}
-class M2 {
-  get x => null;
-  set x(value) {}
-}
-class C extends B with M1, M2 {
-  void f() {
-    x += 1;
-  }
-}
-''');
-    verifyTestResolved();
-
-    // Verify that both the getter and setter for "x" in C.f() refer to the
-    // accessors defined in M2.
-    var leftHandSide = findNode.simple('x +=');
-    expect(
-      leftHandSide.staticElement,
-      findElement.setter('x', of: 'M2'),
-    );
-    expect(
-      leftHandSide.auxiliaryElements.staticElement,
-      findElement.getter('x', of: 'M2'),
-    );
-  }
-
-  test_getter_and_setter_fromMixins_property_access() async {
-    await assertNoErrorsInCode(r'''
-class B {}
-class M1 {
-  get x => null;
-  set x(value) {}
-}
-class M2 {
-  get x => null;
-  set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
-  new C().x += 1;
-}
-''');
-    verifyTestResolved();
-
-    // Verify that both the getter and setter for "x" in "new C().x" refer to
-    // the accessors defined in M2.
-    var leftHandSide = findNode.simple('x +=');
-    expect(
-      leftHandSide.staticElement,
-      findElement.setter('x', of: 'M2'),
-    );
-    expect(
-      leftHandSide.auxiliaryElements.staticElement,
-      findElement.getter('x', of: 'M2'),
-    );
-  }
-
-  test_getter_fromMixins_bare_identifier() async {
-    await assertNoErrorsInCode('''
-class B {}
-class M1 {
-  get x => null;
-}
-class M2 {
-  get x => null;
-}
-class C extends B with M1, M2 {
-  f() {
-    return x;
-  }
-}
-''');
-    verifyTestResolved();
-
-    // Verify that the getter for "x" in C.f() refers to the getter defined in
-    // M2.
-    expect(
-      findNode.simple('x;').staticElement,
-      findElement.getter('x', of: 'M2'),
-    );
-  }
-
-  test_getter_fromMixins_property_access() async {
-    await assertErrorsInCode('''
-class B {}
-class M1 {
-  get x => null;
-}
-class M2 {
-  get x => null;
-}
-class C extends B with M1, M2 {}
-void main() {
-  var y = new C().x;
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 124, 1),
-    ]);
-    verifyTestResolved();
-
-    // Verify that the getter for "x" in "new C().x" refers to the getter
-    // defined in M2.
-    expect(
-      findNode.simple('x;').staticElement,
-      findElement.getter('x', of: 'M2'),
-    );
-  }
-
-  test_hasReferenceToSuper() async {
-    await assertNoErrorsInCode(r'''
+  test_changeFile_resolution() async {
+    newFile(aPath, content: r'''
 class A {}
-class B {toString() => super.toString();}''');
-    verifyTestResolved();
+''');
 
-    var a = findElement.class_('A');
-    expect(a.hasReferenceToSuper, isFalse);
+    newFile(bPath, content: r'''
+import 'a.dart';
+A a;
+B b;
+''');
 
-    var b = findElement.class_('B');
-    expect(b.hasReferenceToSuper, isTrue);
-  }
-
-  test_import_hide() async {
-    newFile('/test/lib/lib1.dart', content: r'''
-set foo(value) {}
-class A {}''');
-
-    newFile('/test/lib/lib2.dart', content: r'''
-set foo(value) {}''');
-
-    await assertNoErrorsInCode(r'''
-import 'lib1.dart' hide foo;
-import 'lib2.dart';
-
-main() {
-  foo = 0;
-}
-A a;''');
-    verifyTestResolved();
-  }
-
-  test_import_prefix() async {
-    newFile('/test/lib/a.dart', content: r'''
-f(int x) {
-  return x * x;
-}''');
-
-    await assertNoErrorsInCode(r'''
-import 'a.dart' as _a;
-main() {
-  _a.f(0);
-}''');
-    verifyTestResolved();
-  }
-
-  test_import_prefix_doesNotExist() async {
-    //
-    // The primary purpose of this test is to ensure that we are only getting a
-    // single error generated when the only problem is that an imported file
-    // does not exist.
-    //
-    await assertErrorsInCode('''
-import 'missing.dart' as p;
-int a = p.q + p.r.s;
-String b = p.t(a) + p.u(v: 0);
-p.T c = new p.T();
-class D<E> extends p.T {
-  D(int i) : super(i);
-  p.U f = new p.V();
-}
-class F implements p.T {
-  p.T m(p.U u) => null;
-}
-class G extends Object with p.V {}
-class H extends D<p.W> {
-  H(int i) : super(i);
-}
-''', [
-      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 14),
+    result = fileResolver.resolve(bPath);
+    assertErrorsInResolvedUnit(result, [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 22, 1),
     ]);
-    verifyTestResolved();
-  }
 
-  test_import_show_doesNotExist() async {
-    //
-    // The primary purpose of this test is to ensure that we are only getting a
-    // single error generated when the only problem is that an imported file
-    // does not exist.
-    //
-    await assertErrorsInCode('''
-import 'missing.dart' show q, r, t, u, T, U, V, W;
-int a = q + r.s;
-String b = t(a) + u(v: 0);
-T c = new T();
-class D<E> extends T {
-  D(int i) : super(i);
-  U f = new V();
-}
-class F implements T {
-  T m(U u) => null;
-}
-class G extends Object with V {}
-class H extends D<W> {
-  H(int i) : super(i);
-}
-''', [
-      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 14),
-    ]);
-  }
-
-  @failingTest
-  test_import_spaceInUri() async {
-    // TODO(scheglov) Fix this. The problem is in `package` URI resolver.
-    newFile('/test/lib/sub folder/a.dart', content: r'''
-foo() {}''');
-
-    await assertNoErrorsInCode(r'''
-import 'sub folder/a.dart';
-
-main() {
-  foo();
-}''');
-    verifyTestResolved();
-  }
-
-  test_indexExpression_typeParameters() async {
-    await assertNoErrorsInCode(r'''
-f() {
-  List<int> a;
-  a[0];
-  List<List<int>> b;
-  b[0][0];
-  List<List<List<int>>> c;
-  c[0][0][0];
-}''');
-    verifyTestResolved();
-  }
-
-  test_indexExpression_typeParameters_invalidAssignmentWarning() async {
-    await assertErrorsInCode(r'''
-f() {
-  List<List<int>> b;
-  b[0][0] = 'hi';
-}''', [
-      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 39, 4),
-    ]);
-    verifyTestResolved();
-  }
-
-  test_indirectOperatorThroughCall() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  B call() { return new B(); }
-}
-
-class B {
-  int operator [](int i) { return i; }
-}
-
-A f = new A();
-
-g(int x) {}
-
-main() {
-  g(f()[0]);
-}''');
-    verifyTestResolved();
-  }
-
-  test_invoke_dynamicThroughGetter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  List get X => [() => 0];
-  m(A a) {
-    X.last;
-  }
-}''');
-    verifyTestResolved();
-  }
-
-  test_isValidMixin_badSuperclass() async {
-    await assertErrorsInCode(r'''
-class A extends B {}
-class B {}
-class C = Object with A;''', [
-      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 54, 1),
-    ]);
-    verifyTestResolved();
-
-    var a = findElement.class_('A');
-    expect(a.isValidMixin, isFalse);
-  }
-
-  test_isValidMixin_constructor() async {
-    await assertErrorsInCode(r'''
-class A {
-  A() {}
-}
-class C = Object with A;''', [
-      error(CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR, 43, 1),
-    ]);
-    verifyTestResolved();
-
-    var a = findElement.class_('A');
-    expect(a.isValidMixin, isFalse);
-  }
-
-  test_isValidMixin_factoryConstructor() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  factory A() => throw 0;
-}
-class C = Object with A;''');
-    verifyTestResolved();
-
-    var a = findElement.class_('A');
-    expect(a.isValidMixin, isTrue);
-  }
-
-  test_isValidMixin_super() async {
-    await assertErrorsInCode(r'''
-class A {
-  toString() {
-    return super.toString();
-  }
-}
-class C = Object with A;''', [
-      error(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, 82, 1),
-    ]);
-    verifyTestResolved();
-
-    var a = findElement.class_('A');
-    expect(a.isValidMixin, isFalse);
-  }
-
-  test_isValidMixin_valid() async {
-    await assertNoErrorsInCode('''
+    newFile(aPath, content: r'''
 class A {}
-class C = Object with A;''');
-    verifyTestResolved();
-
-    var a = findElement.class_('A');
-    expect(a.isValidMixin, isTrue);
-  }
-
-  test_labels_switch() async {
-    await assertNoErrorsInCode(r'''
-void doSwitch(int target) {
-  switch (target) {
-    l0: case 0:
-      continue l1;
-    l1: case 1:
-      continue l0;
-    default:
-      continue l1;
-  }
-}''');
-    verifyTestResolved();
-  }
-
-  test_localVariable_types_invoked() async {
-    await resolveTestCode(r'''
-const A = null;
-main() {
-  var myVar = (int p) => 'foo';
-  myVar(42);
-}''');
-    var node = findNode.simple('myVar(42)');
-    assertType(node, 'String Function(int)');
-  }
-
-  test_metadata_class() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-@A class C<A> {}''');
-    verifyTestResolved();
-
-    var annotations = findElement.class_('C').metadata;
-    expect(annotations, hasLength(1));
-
-    var cDeclaration = findNode.classDeclaration('C<A>');
-    assertElement(
-      cDeclaration.metadata[0].name,
-      findElement.topGet('A'),
-    );
-  }
-
-  test_metadata_field() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-class C {
-  @A int f;
-}''');
-    verifyTestResolved();
-
-    var metadata = findElement.field('f').metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_fieldFormalParameter() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-class C {
-  int f;
-  C(@A this.f);
-}''');
-    verifyTestResolved();
-
-    var metadata = findElement.fieldFormalParameter('f').metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_function() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-@A f() {}''');
-    verifyTestResolved();
-
-    var annotations = findElement.topFunction('f').metadata;
-    expect(annotations, hasLength(1));
-  }
-
-  test_metadata_functionTypedParameter() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-f(@A int p(int x)) {}''');
-    verifyTestResolved();
-
-    var metadata = findElement.parameter('p').metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_libraryDirective() async {
-    await assertNoErrorsInCode(r'''
-@A library lib;
-const A = null;''');
-    verifyTestResolved();
-
-    var metadata = result.libraryElement.metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_method() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-class C {
-  @A void m() {}
-}''');
-    verifyTestResolved();
-
-    var metadata = findElement.method('m').metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_namedParameter() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-f({@A int p : 0}) {}''');
-    verifyTestResolved();
-
-    var metadata = findElement.parameter('p').metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_positionalParameter() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-f([@A int p = 0]) {}''');
-    verifyTestResolved();
-
-    var metadata = findElement.parameter('p').metadata;
-    expect(metadata, hasLength(1));
-  }
-
-  test_metadata_simpleParameter() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-f(@A p1, @A int p2) {}''');
-    verifyTestResolved();
-
-    expect(findElement.parameter('p1').metadata, hasLength(1));
-    expect(findElement.parameter('p2').metadata, hasLength(1));
-  }
-
-  test_metadata_typedef() async {
-    await assertNoErrorsInCode(r'''
-const A = null;
-@A typedef F<A>();''');
-    verifyTestResolved();
-
-    expect(
-      findElement.functionTypeAlias('F').metadata,
-      hasLength(1),
-    );
-
-    var actualElement = findNode.annotation('@A').name.staticElement;
-    expect(actualElement, findElement.topGet('A'));
-  }
-
-  test_method_fromMixin() async {
-    await assertNoErrorsInCode(r'''
-class B {
-  bar() => 1;
-}
-class A {
-  foo() => 2;
-}
-
-class C extends B with A {
-  bar() => super.bar();
-  foo() => super.foo();
-}''');
-    verifyTestResolved();
-  }
-
-  test_method_fromMixins() async {
-    await assertNoErrorsInCode('''
 class B {}
-class M1 {
-  void f() {}
-}
-class M2 {
-  void f() {}
-}
-class C extends B with M1, M2 {}
-void main() {
-  new C().f();
-}
 ''');
-    verifyTestResolved();
+    fileResolver.changeFile(aPath);
 
-    expect(
-      findNode.simple('f();').staticElement,
-      findElement.method('f', of: 'M2'),
-    );
+    result = fileResolver.resolve(bPath);
+    assertErrorsInResolvedUnit(result, []);
   }
 
-  test_method_fromMixins_bare_identifier() async {
-    await assertNoErrorsInCode('''
-class B {}
-class M1 {
-  void f() {}
-}
-class M2 {
-  void f() {}
-}
-class C extends B with M1, M2 {
-  void g() {
-    f();
-  }
-}
-''');
-    verifyTestResolved();
+  void _assertRefreshedFiles(List<String> expected, {bool withSdk = false}) {
+    var expectedPlusSdk = expected.toSet();
 
-    expect(
-      findNode.simple('f();').staticElement,
-      findElement.method('f', of: 'M2'),
-    );
-  }
-
-  test_method_fromMixins_invoked_from_outside_class() async {
-    await assertNoErrorsInCode('''
-class B {}
-class M1 {
-  void f() {}
-}
-class M2 {
-  void f() {}
-}
-class C extends B with M1, M2 {}
-void main() {
-  new C().f();
-}
-''');
-    verifyTestResolved();
-
-    expect(
-      findNode.simple('f();').staticElement,
-      findElement.method('f', of: 'M2'),
-    );
-  }
-
-  test_method_fromSuperclassMixin() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  void m1() {}
-}
-class B extends Object with A {
-}
-class C extends B {
-}
-f(C c) {
-  c.m1();
-}''');
-    verifyTestResolved();
-  }
-
-  test_methodCascades() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  void m1() {}
-  void m2() {}
-  void m() {
-    A a = new A();
-    a..m1()
-     ..m2();
-  }
-}''');
-    verifyTestResolved();
-  }
-
-  test_methodCascades_withSetter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  String name;
-  void m1() {}
-  void m2() {}
-  void m() {
-    A a = new A();
-    a..m1()
-     ..name = 'name'
-     ..m2();
-  }
-}''');
-    verifyTestResolved();
-  }
-
-  test_resolveAgainstNull() async {
-    await assertNoErrorsInCode(r'''
-f(var p) {
-  return null == p;
-}''');
-    verifyTestResolved();
-  }
-
-  test_setter_fromMixins_bare_identifier() async {
-    await resolveTestCode('''
-class B {}assertNoErrorsInCode
-class M1 {
-  set x(value) {}
-}
-class M2 {
-  set x(value) {}
-}
-class C extends B with M1, M2 {
-  void f() {
-    x = 1;
-  }
-}
-''');
-    verifyTestResolved();
-
-    expect(
-      findNode.simple('x = ').staticElement,
-      findElement.setter('x', of: 'M2'),
-    );
-  }
-
-  test_setter_fromMixins_property_access() async {
-    await assertNoErrorsInCode('''
-class B {}
-class M1 {
-  set x(value) {}
-}
-class M2 {
-  set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
-  new C().x = 1;
-}
-''');
-    verifyTestResolved();
-
-    expect(
-      findNode.simple('x = ').staticElement,
-      findElement.setter('x', of: 'M2'),
-    );
-  }
-
-  test_setter_inherited() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  int get x => 0;
-  set x(int p) {}
-}
-class B extends A {
-  int get x => super.x == null ? 0 : super.x;
-  int f() => x = 1;
-}''');
-    verifyTestResolved();
-  }
-
-  test_setter_static() async {
-    await assertNoErrorsInCode(r'''
-set s(x) {
-}
-
-main() {
-  s = 123;
-}''');
-    verifyTestResolved();
-  }
-
-  /**
-   * Verify that all of the identifiers in the [result] have been resolved.
-   */
-  void verifyTestResolved() {
-    var verifier = ResolutionVerifier();
-    result.unit.accept(verifier);
-    verifier.assertResolved();
-  }
-
-  /**
-   * Resolve the test file and verify that the arguments in a specific method
-   * invocation were correctly resolved.
-   *
-   * The file is expected to define a method named `g`, and has exactly one
-   * [MethodInvocation] in a statement ending with `);`. It is the arguments to
-   * that method invocation that are tested. The method invocation can contain
-   * errors.
-   *
-   * The arguments were resolved correctly if the number of expressions in the list matches the
-   * length of the array of indices and if, for each index in the array of indices, the parameter to
-   * which the argument expression was resolved is the parameter in the invoked method's list of
-   * parameters at that index. Arguments that should not be resolved to a parameter because of an
-   * error can be denoted by including a negative index in the array of indices.
-   *
-   * @param indices the array of indices used to associate arguments with parameters
-   * @throws Exception if the source could not be resolved or if the structure of the source is not
-   *           valid
-   */
-  Future<void> _validateArgumentResolution(List<int> indices) async {
-    var g = findElement.method('g');
-    var parameters = g.parameters;
-
-    var invocation = findNode.methodInvocation(');');
-
-    var arguments = invocation.argumentList.arguments;
-
-    var argumentCount = arguments.length;
-    expect(argumentCount, indices.length);
-
-    for (var i = 0; i < argumentCount; i++) {
-      var argument = arguments[i];
-      var actualParameter = argument.staticParameterElement;
-
-      var index = indices[i];
-      if (index < 0) {
-        expect(actualParameter, isNull);
-      } else {
-        var expectedParameter = parameters[index];
-        expect(actualParameter, same(expectedParameter));
-      }
+    if (withSdk) {
+      expectedPlusSdk
+        ..add(convertPath('/sdk/lib/async/async.dart'))
+        ..add(convertPath('/sdk/lib/async/stream.dart'))
+        ..add(convertPath('/sdk/lib/core/core.dart'))
+        ..add(convertPath('/sdk/lib/math/math.dart'));
     }
+
+    var refreshedFiles = fileResolver.fsState.testView.refreshedFiles;
+    expect(refreshedFiles, unorderedEquals(expectedPlusSdk));
+
+    refreshedFiles.clear();
+  }
+}
+
+@reflectiveTest
+class FileResolverTest extends FileResolutionTest {
+  test_analysisOptions_default_fromPackageUri() async {
+    newFile('/workspace/dart/analysis_options/lib/default.yaml', content: r'''
+analyzer:
+  strong-mode:
+    implicit-casts: false
+''');
+
+    await assertErrorsInCode(r'''
+num a = 0;
+int b = a;
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
+  }
+
+  test_analysisOptions_file_inPackage() async {
+    newFile('/workspace/dart/test/analysis_options.yaml', content: r'''
+analyzer:
+  strong-mode:
+    implicit-casts: false
+''');
+
+    await assertErrorsInCode(r'''
+num a = 0;
+int b = a;
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
+  }
+
+  test_analysisOptions_file_inThirdParty() async {
+    newFile('/workspace/dart/analysis_options/lib/third_party.yaml',
+        content: r'''
+analyzer:
+  strong-mode:
+    implicit-casts: false
+''');
+
+    var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
+    await assertErrorsInFile(aPath, r'''
+num a = 0;
+int b = a;
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
+  }
+
+  test_analysisOptions_lints() async {
+    newFile('/workspace/dart/analysis_options/lib/default.yaml', content: r'''
+linter:
+  rules:
+    - omit_local_variable_types
+''');
+
+    var rule = Registry.ruleRegistry.getRule('omit_local_variable_types');
+
+    await assertErrorsInCode(r'''
+main() {
+  int a = 0;
+  a;
+}
+''', [
+      error(rule.lintCode, 11, 9),
+    ]);
+  }
+
+  test_analysisOptions_no() async {
+    await assertNoErrorsInCode(r'''
+num a = 0;
+int b = a;
+''');
+  }
+
+  test_basic() async {
+    await assertNoErrorsInCode(r'''
+int a = 0;
+var b = 1 + 2;
+''');
+    assertType(findElement.topVar('a').type, 'int');
+    assertElement(findNode.simple('int a'), intElement);
+
+    assertType(findElement.topVar('b').type, 'int');
+  }
+
+  test_getErrors() {
+    addTestFile(r'''
+var a = b;
+var foo = 0;
+''');
+
+    var result = getTestErrors();
+    expect(result.path, convertPath('/workspace/dart/test/lib/test.dart'));
+    expect(result.uri.toString(), 'package:dart.test/test.dart');
+    assertErrorsInList(result.errors, [
+      error(StaticWarningCode.UNDEFINED_IDENTIFIER, 8, 1),
+    ]);
+    expect(result.lineInfo.lineStarts, [0, 11, 24]);
+  }
+
+  test_getErrors_reuse() {
+    addTestFile('var a = b;');
+
+    var path = convertPath('/workspace/dart/test/lib/test.dart');
+
+    // No resolved files yet.
+    expect(fileResolver.testView.resolvedFiles, isEmpty);
+
+    // No cached, will resolve once.
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, [path]);
+
+    // Has cached, will be not resolved again.
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, [path]);
+
+    // New resolver.
+    // Still has cached, will be not resolved.
+    createFileResolver();
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, []);
+
+    // Change the file, new resolver.
+    // With changed file the previously cached result cannot be used.
+    addTestFile('var a = c;');
+    createFileResolver();
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, [path]);
+
+    // New resolver.
+    // Still has cached, will be not resolved.
+    createFileResolver();
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, []);
+  }
+
+  test_getErrors_reuse_changeDependency() {
+    newFile('/workspace/dart/test/lib/a.dart', content: r'''
+var a = 0;
+''');
+
+    addTestFile(r'''
+import 'a.dart';
+var b = a.foo;
+''');
+
+    var path = convertPath('/workspace/dart/test/lib/test.dart');
+
+    // No resolved files yet.
+    expect(fileResolver.testView.resolvedFiles, isEmpty);
+
+    // No cached, will resolve once.
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, [path]);
+
+    // Has cached, will be not resolved again.
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, [path]);
+
+    // Change the dependency, new resolver.
+    // The signature of the result is different.
+    // The previously cached result cannot be used.
+    newFile('/workspace/dart/test/lib/a.dart', content: r'''
+var a = 4.2;
+''');
+    createFileResolver();
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, [path]);
+
+    // New resolver.
+    // Still has cached, will be not resolved.
+    createFileResolver();
+    expect(getTestErrors().errors, hasLength(1));
+    expect(fileResolver.testView.resolvedFiles, []);
+  }
+
+  test_hint() async {
+    await assertErrorsInCode(r'''
+import 'dart:math';
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 11),
+    ]);
+  }
+
+  test_reuse_compatibleOptions() async {
+    var aPath = '/workspace/dart/aaa/lib/a.dart';
+    var aResult = await assertErrorsInFile(aPath, r'''
+num a = 0;
+int b = a;
+''', []);
+
+    var bPath = '/workspace/dart/bbb/lib/a.dart';
+    var bResult = await assertErrorsInFile(bPath, r'''
+num a = 0;
+int b = a;
+''', []);
+
+    // Both files use the same (default) analysis options.
+    // So, when we resolve 'bbb', we can reuse the context after 'aaa'.
+    expect(
+      aResult.libraryElement.context,
+      same(bResult.libraryElement.context),
+    );
+  }
+
+  test_reuse_incompatibleOptions_implicitCasts() async {
+    newFile('/workspace/dart/aaa/analysis_options.yaml', content: r'''
+analyzer:
+  strong-mode:
+    implicit-casts: false
+''');
+
+    newFile('/workspace/dart/bbb/analysis_options.yaml', content: r'''
+analyzer:
+  strong-mode:
+    implicit-casts: true
+''');
+
+    // Implicit casts are disabled in 'aaa'.
+    var aPath = '/workspace/dart/aaa/lib/a.dart';
+    await assertErrorsInFile(aPath, r'''
+num a = 0;
+int b = a;
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
+
+    // Implicit casts are enabled in 'bbb'.
+    var bPath = '/workspace/dart/bbb/lib/a.dart';
+    await assertErrorsInFile(bPath, r'''
+num a = 0;
+int b = a;
+''', []);
+
+    // Implicit casts are still disabled in 'aaa'.
+    await assertErrorsInFile(aPath, r'''
+num a = 0;
+int b = a;
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
index f387181a2..27f64b1 100644
--- a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -52,6 +53,22 @@
     );
   }
 
+  test_eqEqEq() async {
+    await assertErrorsInCode(r'''
+f(int a, int b) {
+  a === b;
+}
+''', [
+      error(ScannerErrorCode.UNSUPPORTED_OPERATOR, 22, 1),
+    ]);
+
+    assertBinaryExpression(
+      findNode.binary('a === b'),
+      element: null,
+      type: 'dynamic',
+    );
+  }
+
   test_ifNull() async {
     await assertNoErrorsInCode(r'''
 f(int a, double b) {
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index a74c799..4ff5920 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -456,16 +456,6 @@
     ]);
   }
 
-  test_error_memberWithClassName_getter() async {
-    await assertErrorsInCode(r'''
-class C {
-  int get C => null;
-}
-''', [
-      error(ParserErrorCode.MEMBER_WITH_CLASS_NAME, 20, 1),
-    ]);
-  }
-
   test_error_memberWithClassName_field() async {
     await assertErrorsInCode(r'''
 class C {
@@ -476,6 +466,16 @@
     ]);
   }
 
+  test_error_memberWithClassName_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  int get C => null;
+}
+''', [
+      error(ParserErrorCode.MEMBER_WITH_CLASS_NAME, 20, 1),
+    ]);
+  }
+
   test_error_memberWithClassName_getter_static() async {
     await assertErrorsInCode(r'''
 class C {
@@ -587,6 +587,46 @@
     ]);
   }
 
+  test_inconsistentInheritanceGetterAndMethod_mixinApp() async {
+    await assertErrorsInCode('''
+class S {
+  bool get m => false;
+}
+
+class M {
+  int m() => 1;
+}
+
+class C = S with M;
+''', [
+      error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, 71,
+          1),
+    ]);
+  }
+
+  test_inconsistentInheritanceGetterAndMethod_mixinApp2() async {
+    await assertErrorsInCode('''
+class S {
+  bool get m => false;
+}
+
+class M1 {
+  int m() => 1;
+}
+
+class M2 {
+  bool get m => false;
+}
+
+class C = S with M1, M2;
+''', [
+      error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
+          109, 1),
+      error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
+          109, 1),
+    ]);
+  }
+
   test_issue32815() async {
     await assertErrorsInCode(r'''
 class A<T> extends B<T> {}
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 2ad2114..9d51f53 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -328,7 +328,25 @@
     _assertIntValue(c, 42);
   }
 
+  test_topLevelVariable_optOut3() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+const a = int.fromEnvironment('a', defaultValue: 42);
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+const b = a;
+''');
+
+    var c = findElement.topVar('b');
+    assertType(c.type, 'int*');
+    _assertIntValue(c, 42);
+  }
+
   void _assertIntValue(VariableElement element, int value) {
-    expect(element.constantValue.toIntValue(), value);
+    expect(element.computeConstantValue().toIntValue(), value);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/for_element_test.dart b/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
index 4de68fb..7dc6aef 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
@@ -56,10 +56,45 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..contextFeatures = FeatureSet.forTesting(
         sdkVersion: '2.6.0', additionalFeatures: [Feature.non_nullable]);
+
+  test_optIn_fromOptOut() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A implements Iterable<int> {
+  Iterator<int> iterator => throw 0;
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+main(A a) {
+  for (var v in a) {
+    v;
+  }
+}
+''');
+  }
 }
 
 @reflectiveTest
 class ForLoopElementTest extends DriverResolutionTest {
+  test_condition_rewrite() async {
+    await assertNoErrorsInCode(r'''
+main(bool Function() b) {
+  <int>[for (; b(); ) 0];
+}
+''');
+
+    assertFunctionExpressionInvocation(
+      findNode.functionExpressionInvocation('b()'),
+      element: null,
+      typeArgumentTypes: [],
+      invokeType: 'bool Function()',
+      type: 'bool',
+    );
+  }
+
   test_declaredVariableScope() async {
     await assertNoErrorsInCode(r'''
 main() {
@@ -77,20 +112,4 @@
       findNode.simple('i = 1.1;').staticElement,
     );
   }
-
-  test_condition_rewrite() async {
-    await assertNoErrorsInCode(r'''
-main(bool Function() b) {
-  <int>[for (; b(); ) 0];
-}
-''');
-
-    assertFunctionExpressionInvocation(
-      findNode.functionExpressionInvocation('b()'),
-      element: null,
-      typeArgumentTypes: [],
-      invokeType: 'bool Function()',
-      type: 'bool',
-    );
-  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index f764905..487f00f 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -4,8 +4,11 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 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/generated/engine.dart';
 import 'package:analyzer/src/test_utilities/find_element.dart';
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -223,7 +226,8 @@
   test_optIn_fromOptOut_class_constructor() async {
     newFile('/test/lib/a.dart', content: r'''
 class A {
-  const A.named(int a);
+  final int a;
+  const A.named(this.a);
 }
 ''');
 
@@ -231,7 +235,7 @@
 // @dart = 2.7
 import 'a.dart';
 
-@A.named(0)
+@A.named(42)
 void f() {}
 ''');
 
@@ -245,12 +249,52 @@
       declaration: import_a.constructor('named', of: 'A'),
       isLegacy: true,
     );
+
+    _assertConstantValue(
+      findElement.function('f').metadata[0].computeConstantValue(),
+      type: 'A*',
+      fieldMap: {'a': 42},
+    );
+  }
+
+  test_optIn_fromOptOut_class_constructor_withDefault() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  final int a;
+  const A.named({this.a = 42});
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+@A.named()
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A.named('),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@A'),
+      declaration: import_a.constructor('named', of: 'A'),
+      isLegacy: true,
+    );
+
+    _assertConstantValue(
+      findElement.function('f').metadata[0].computeConstantValue(),
+      type: 'A*',
+      fieldMap: {'a': 42},
+    );
   }
 
   test_optIn_fromOptOut_class_getter() async {
     newFile('/test/lib/a.dart', content: r'''
 class A {
-  const foo = 0;
+  static const foo = 42;
 }
 ''');
 
@@ -272,11 +316,13 @@
       declaration: import_a.getter('foo'),
       isLegacy: true,
     );
+
+    _assertIntValue(findElement.function('f').metadata[0], 42);
   }
 
   test_optIn_fromOptOut_getter() async {
     newFile('/test/lib/a.dart', content: r'''
-const foo = 0;
+const foo = 42;
 ''');
 
     await assertNoErrorsInCode(r'''
@@ -292,6 +338,8 @@
       declaration: import_a.topGet('foo'),
       isLegacy: true,
     );
+
+    _assertIntValue(findElement.function('f').metadata[0], 42);
   }
 
   test_optIn_fromOptOut_prefix_class() async {
@@ -351,7 +399,7 @@
   test_optIn_fromOptOut_prefix_class_getter() async {
     newFile('/test/lib/a.dart', content: r'''
 class A {
-  const foo = 0;
+  static const foo = 0;
 }
 ''');
 
@@ -394,4 +442,36 @@
       isLegacy: true,
     );
   }
+
+  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.');
+    }
+  }
+
+  void _assertIntValue(ElementAnnotation annotation, int intValue) {
+    _assertConstantValue(
+      annotation.computeConstantValue(),
+      type: 'int*',
+      intValue: intValue,
+    );
+  }
 }
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 c6ce42f..096e13c 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -2042,4 +2042,35 @@
 
     assertType(findNode.cascade('a?'), 'A?');
   }
+
+  test_nullShorting_cascade_nullAwareInside() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  int? foo() => 0;
+}
+
+main() {
+  A a = A()..foo()?.abs();
+  a;
+}
+''');
+
+    assertMethodInvocation2(
+      findNode.methodInvocation('..foo()'),
+      element: findElement.method('foo'),
+      typeArgumentTypes: [],
+      invokeType: 'int? Function()',
+      type: 'int?',
+    );
+
+    assertMethodInvocation2(
+      findNode.methodInvocation('.abs()'),
+      element: intElement.getMethod('abs'),
+      typeArgumentTypes: [],
+      invokeType: 'int Function()',
+      type: 'int',
+    );
+
+    assertType(findNode.cascade('A()'), 'A');
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
index a47b170..8998675 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
@@ -18,6 +18,22 @@
 
 @reflectiveTest
 class PrefixedIdentifierResolutionTest extends DriverResolutionTest {
+  test_dynamic_explicitCore_withPrefix() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:core' as mycore;
+
+main() {
+  mycore.dynamic;
+}
+''');
+
+    assertPrefixedIdentifier(
+      findNode.prefixed('mycore.dynamic'),
+      element: dynamicElement,
+      type: 'Type',
+    );
+  }
+
   test_implicitCall_tearOff() async {
     newFile('/test/lib/a.dart', content: r'''
 class A {
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 9bceab5..41e7bea 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -94,4 +94,108 @@
 
     assertType(findNode.cascade('a?'), 'A?');
   }
+
+  test_nullShorting_cascade2() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  int? get foo => 0;
+}
+
+main() {
+  A a = A()..foo?.isEven;
+  a;
+}
+''');
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('..foo?'),
+      element: findElement.getter('foo'),
+      type: 'int?',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.isEven'),
+      element: intElement.getGetter('isEven'),
+      type: 'bool',
+    );
+
+    assertType(findNode.cascade('A()'), 'A');
+  }
+
+  test_nullShorting_cascade3() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  A? get foo => this;
+  A? get bar => this;
+  A? get baz => this;
+}
+
+main() {
+  A a = A()..foo?.bar?.baz;
+  a;
+}
+''');
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.foo'),
+      element: findElement.getter('foo'),
+      type: 'A?',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.bar'),
+      element: findElement.getter('bar'),
+      type: 'A?',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.baz'),
+      element: findElement.getter('baz'),
+      type: 'A?',
+    );
+
+    assertType(findNode.cascade('A()'), 'A');
+  }
+
+  test_nullShorting_cascade4() async {
+    await assertNoErrorsInCode(r'''
+A? get foo => A();
+
+class A {
+  A get bar => this;
+  A? get baz => this;
+  A get baq => this;
+}
+
+main() {
+  foo?.bar?..baz?.baq;
+}
+''');
+
+    assertSimpleIdentifier(
+      findNode.simple('foo?'),
+      element: findElement.topGet('foo'),
+      type: 'A?',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.bar'),
+      element: findElement.getter('bar'),
+      type: 'A?',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.baz'),
+      element: findElement.getter('baz'),
+      type: 'A?',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('.baq'),
+      element: findElement.getter('baq'),
+      type: 'A',
+    );
+
+    assertType(findNode.cascade('foo?'), 'A?');
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index d851422..b052e2e 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -243,7 +243,7 @@
     assertErrorsInResolvedUnit(result, expectedErrors);
   }
 
-  Future<void> assertErrorsInFile(
+  Future<ResolvedUnitResult> assertErrorsInFile(
     String path,
     String content,
     List<ExpectedError> expectedErrors,
@@ -253,15 +253,24 @@
 
     var result = await resolveFile(path);
     assertErrorsInResolvedUnit(result, expectedErrors);
+
+    return result;
+  }
+
+  void assertErrorsInList(
+    List<AnalysisError> errors,
+    List<ExpectedError> expectedErrors,
+  ) {
+    GatheringErrorListener errorListener = GatheringErrorListener();
+    errorListener.addAll(errors);
+    errorListener.assertErrors(expectedErrors);
   }
 
   void assertErrorsInResolvedUnit(
     ResolvedUnitResult result,
     List<ExpectedError> expectedErrors,
   ) {
-    GatheringErrorListener errorListener = GatheringErrorListener();
-    errorListener.addAll(result.errors);
-    errorListener.assertErrors(expectedErrors);
+    assertErrorsInList(result.errors, expectedErrors);
   }
 
   void assertFunctionExpressionInvocation(
diff --git a/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
index fab2d68..a79a25e 100644
--- a/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
@@ -18,6 +18,54 @@
 
 @reflectiveTest
 class SimpleIdentifierResolutionTest extends DriverResolutionTest {
+  test_dynamic_explicitCore() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:core';
+
+main() {
+  dynamic;
+}
+''');
+
+    assertSimpleIdentifier(
+      findNode.simple('dynamic;'),
+      element: dynamicElement,
+      type: 'Type',
+    );
+  }
+
+  test_dynamic_explicitCore_withPrefix_referenceWithout() async {
+    await assertErrorsInCode(r'''
+import 'dart:core' as mycore;
+
+main() {
+  dynamic;
+}
+''', [
+      error(StaticWarningCode.UNDEFINED_IDENTIFIER, 42, 7),
+    ]);
+
+    assertSimpleIdentifier(
+      findNode.simple('dynamic;'),
+      element: null,
+      type: 'dynamic',
+    );
+  }
+
+  test_dynamic_implicitCore() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  dynamic;
+}
+''');
+
+    assertSimpleIdentifier(
+      findNode.simple('dynamic;'),
+      element: dynamicElement,
+      type: 'Type',
+    );
+  }
+
   test_implicitCall_tearOff() async {
     await assertNoErrorsInCode('''
 class A {
@@ -76,6 +124,32 @@
   @override
   bool get typeToStringWithNullability => true;
 
+  test_functionReference() async {
+    await assertErrorsInCode('''
+// @dart = 2.7
+import 'dart:math';
+
+class A {
+  const A(_);
+}
+
+@A([min])
+main() {}
+''', [
+      error(StrongModeCode.COULD_NOT_INFER, 66, 5),
+    ]);
+
+    var identifier = findNode.simple('min]');
+    assertElement(
+      identifier,
+      elementMatcher(
+        findElement.importFind('dart:math').topFunction('min'),
+        isLegacy: true,
+      ),
+    );
+    assertType(identifier, 'T* Function<T extends num*>(T*, T*)*');
+  }
+
   test_implicitCall_tearOff_nullable() async {
     await assertErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index d1251c4..2918265 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -50,6 +50,7 @@
 import 'property_access_test.dart' as property_access;
 import 'simple_identifier_test.dart' as simple_identifier;
 import 'top_type_inference_test.dart' as top_type_inference;
+import 'try_statement_test.dart' as try_statement;
 import 'type_inference/test_all.dart' as type_inference;
 import 'type_name_test.dart' as type_name;
 import 'yield_statement_test.dart' as yield_statement;
@@ -99,6 +100,7 @@
     property_access.main();
     simple_identifier.main();
     top_type_inference.main();
+    try_statement.main();
     type_name.main();
     type_inference.main();
     yield_statement.main();
diff --git a/pkg/analyzer/test/src/dart/resolution/try_statement_test.dart b/pkg/analyzer/test/src/dart/resolution/try_statement_test.dart
new file mode 100644
index 0000000..2b544e6
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/try_statement_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../constant/potentially_constant_test.dart';
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TryStatementTest);
+    defineReflectiveTests(TryStatementNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class TryStatementNullSafetyTest extends TryStatementTest
+    with WithNullSafetyMixin {}
+
+@reflectiveTest
+class TryStatementTest extends DriverResolutionTest {
+  test_catch_withoutType() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  try {} catch (e, st) {
+    st;
+  }
+}
+''');
+
+    var e = findElement.localVar('e');
+    expect(e.isFinal, isTrue);
+    assertType(
+      e.type,
+      typeStringByNullability(nullable: 'Object', legacy: 'dynamic'),
+    );
+
+    var st = findElement.localVar('st');
+    expect(st.isFinal, isTrue);
+    assertType(st.type, 'StackTrace');
+
+    var node = findNode.catchClause('catch');
+    expect(node.exceptionParameter.staticElement, e);
+    expect(node.stackTraceParameter.staticElement, st);
+  }
+
+  test_catch_withType() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  try {} on int catch (e, st) {
+    st;
+  }
+}
+''');
+
+    var e = findElement.localVar('e');
+    expect(e.isFinal, isTrue);
+    assertType(e.type, 'int');
+
+    var st = findElement.localVar('st');
+    expect(st.isFinal, isTrue);
+    assertType(st.type, 'StackTrace');
+
+    var node = findNode.catchClause('catch');
+    expect(node.exceptionParameter.staticElement, e);
+    expect(node.stackTraceParameter.staticElement, st);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
index 0ca414d..15bea04 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
@@ -54,18 +54,51 @@
     );
   }
 
-  test_returnType_blockBody_notNullable() async {
+  test_returnType_async_blockBody() async {
+    await resolveTestCode('''
+var v = () async {
+  return 0;
+};
+''');
+    _assertReturnType('() async {', 'Future<int>');
+  }
+
+  test_returnType_async_expressionBody() async {
+    await resolveTestCode('''
+var v = () async => 0;
+''');
+    _assertReturnType('() async =>', 'Future<int>');
+  }
+
+  test_returnType_asyncStar_blockBody() async {
+    await resolveTestCode('''
+var v = () async* {
+  yield 0;
+};
+''');
+    _assertReturnType('() async* {', 'Stream<int>');
+  }
+
+  test_returnType_sync_blockBody() async {
+    await resolveTestCode('''
+var v = () {
+  return 0;
+};
+''');
+    _assertReturnType('() {', 'int');
+  }
+
+  test_returnType_sync_blockBody_notNullable() async {
     await resolveTestCode('''
 var v = (bool b) {
   if (b) return 0;
   return 1.2;
 };
 ''');
-    var element = findNode.functionExpression('(bool').declaredElement;
-    assertType(element.returnType, 'num');
+    _assertReturnType('(bool b) {', 'num');
   }
 
-  test_returnType_blockBody_notNullable_switch_onEnum() async {
+  test_returnType_sync_blockBody_notNullable_switch_onEnum() async {
     var expectedErrors = expectedErrorsByNullability(
       nullable: [],
       legacy: [
@@ -86,11 +119,10 @@
   };
 }
 ''', expectedErrors);
-    var element = findNode.functionExpression('(E e)').declaredElement;
-    assertType(element.returnType, 'int');
+    _assertReturnType('(E e) {', 'int');
   }
 
-  test_returnType_blockBody_notNullable_switch_onEnum_imported() async {
+  test_returnType_sync_blockBody_notNullable_switch_onEnum_imported() async {
     newFile('/test/lib/a.dart', content: r'''
 enum E { a, b }
 ''');
@@ -115,42 +147,38 @@
   };
 }
 ''', expectedErrors);
-    var element = findNode.functionExpression('(p.E e)').declaredElement;
-    assertType(element.returnType, 'int');
+    _assertReturnType('(p.E e) {', 'int');
   }
 
-  test_returnType_blockBody_null_hasReturn() async {
+  test_returnType_sync_blockBody_null_hasReturn() async {
     await resolveTestCode('''
 var v = (bool b) {
   if (b) return;
 };
 ''');
-    var element = findNode.functionExpression('(bool').declaredElement;
-    assertType(element.returnType, 'Null');
+    _assertReturnType('(bool b) {', 'Null');
   }
 
-  test_returnType_blockBody_null_noReturn() async {
+  test_returnType_sync_blockBody_null_noReturn() async {
     await resolveTestCode('''
 var v = () {};
 ''');
-    var element = findNode.functionExpression('() {}').declaredElement;
-    assertType(element.returnType, 'Null');
+    _assertReturnType('() {}', 'Null');
   }
 
-  test_returnType_blockBody_nullable() async {
+  test_returnType_sync_blockBody_nullable() async {
     await resolveTestCode('''
 var v = (bool b) {
   if (b) return 0;
 };
 ''');
-    var element = findNode.functionExpression('(bool').declaredElement;
-    assertType(
-      element.returnType,
+    _assertReturnType(
+      '(bool b) {',
       typeStringByNullability(nullable: 'int?', legacy: 'int'),
     );
   }
 
-  test_returnType_blockBody_nullable_switch() async {
+  test_returnType_sync_blockBody_nullable_switch() async {
     var expectedErrors = expectedErrorsByNullability(
       nullable: [],
       legacy: [
@@ -167,38 +195,48 @@
   };
 }
 ''', expectedErrors);
-    var element = findNode.functionExpression('(int a)').declaredElement;
-    assertType(
-      element.returnType,
+    _assertReturnType(
+      '(int a) {',
       typeStringByNullability(nullable: 'int?', legacy: 'int'),
     );
   }
 
-  test_returnType_expressionBody_Never() async {
+  test_returnType_sync_expressionBody_Never() async {
     await resolveTestCode('''
 var v = () => throw 42;
 ''');
-    var element = findNode.functionExpression('() =>').declaredElement;
-    assertType(
-      element.returnType,
+    _assertReturnType(
+      '() =>',
       typeStringByNullability(nullable: 'Never', legacy: 'Null'),
     );
   }
 
-  test_returnType_expressionBody_notNullable() async {
+  test_returnType_sync_expressionBody_notNullable() async {
     await resolveTestCode('''
 var v = () => 42;
 ''');
-    var element = findNode.functionExpression('() =>').declaredElement;
-    assertType(element.returnType, 'int');
+    _assertReturnType('() =>', 'int');
   }
 
-  test_returnType_expressionBody_Null() async {
+  test_returnType_sync_expressionBody_Null() async {
     await resolveTestCode('''
 var v = () => null;
 ''');
-    var element = findNode.functionExpression('() =>').declaredElement;
-    assertType(element.returnType, 'Null');
+    _assertReturnType('() =>', 'Null');
+  }
+
+  test_returnType_syncStar_blockBody() async {
+    await resolveTestCode('''
+var v = () sync* {
+  yield 0;
+};
+''');
+    _assertReturnType('() sync* {', 'Iterable<int>');
+  }
+
+  void _assertReturnType(String search, String expected) {
+    var element = findNode.functionExpression(search).declaredElement;
+    assertType(element.returnType, expected);
   }
 }
 
@@ -224,7 +262,6 @@
   foo(() => null);
 }
 ''');
-    var element = findNode.functionExpression('() =>').declaredElement;
-    assertType(element.returnType, 'Null*');
+    _assertReturnType('() =>', 'Null*');
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
index 08ba80b..d287dbd 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
@@ -242,6 +242,17 @@
     assertType(findNode.listLiteral('[...'), 'List<Object>');
   }
 
+  test_noContext_noTypeArgs_spread_mixin() async {
+    await resolveTestCode(r'''
+mixin L on List<int> {}
+main() {
+  L l1;
+  var l2 = [...l1];
+}
+''');
+    assertType(findNode.listLiteral('[...'), 'List<int>');
+  }
+
   test_noContext_noTypeArgs_spread_nestedInIf_oneAmbiguous() async {
     await resolveTestCode('''
 List<int> c;
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
index 023d13e..6f441c5 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
@@ -254,6 +254,17 @@
     assertType(setOrMapLiteral('{...'), 'Map<Object, Object>');
   }
 
+  test_noContext_noTypeArgs_spread_mixin() async {
+    await resolveTestCode(r'''
+mixin M on Map<String, int> {}
+main() {
+  M m1;
+  var m2 = {...m1};
+}
+''');
+    assertType(setOrMapLiteral('{...'), 'Map<String, int>');
+  }
+
   test_noContext_noTypeArgs_spread_nestedInIf_oneAmbiguous() async {
     await resolveTestCode('''
 Map<String, int> c;
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
index dc673a4..0711c83 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
@@ -216,6 +216,17 @@
     assertType(setLiteral('{...'), 'Set<Object>');
   }
 
+  test_noContext_noTypeArgs_spread_mixin() async {
+    await resolveTestCode(r'''
+mixin S on Set<int> {}
+main() {
+  S s1;
+  var s2 = {...s1};
+}
+''');
+    assertType(setLiteral('{...'), 'Set<int>');
+  }
+
   test_noContext_noTypeArgs_spread_nestedInIf_oneAmbiguous() async {
     await resolveTestCode('''
 List<int> c;
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 6c54c0b..ed3d0fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
@@ -78,6 +78,63 @@
     );
   }
 
+  test_dynamic_explicitCore() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:core';
+
+dynamic a;
+''');
+
+    assertTypeName(
+      findNode.typeName('dynamic a;'),
+      dynamicElement,
+      'dynamic',
+    );
+  }
+
+  test_dynamic_explicitCore_withPrefix() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:core' as mycore;
+
+mycore.dynamic a;
+''');
+
+    assertTypeName(
+      findNode.typeName('mycore.dynamic a;'),
+      dynamicElement,
+      'dynamic',
+      expectedPrefix: findElement.import('dart:core').prefix,
+    );
+  }
+
+  test_dynamic_explicitCore_withPrefix_referenceWithout() async {
+    await assertErrorsInCode(r'''
+import 'dart:core' as mycore;
+
+dynamic a;
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 31, 7),
+    ]);
+
+    assertTypeName(
+      findNode.typeName('dynamic a;'),
+      null,
+      'dynamic',
+    );
+  }
+
+  test_dynamic_implicitCore() async {
+    await assertNoErrorsInCode(r'''
+dynamic a;
+''');
+
+    assertTypeName(
+      findNode.typeName('dynamic a;'),
+      dynamicElement,
+      'dynamic',
+    );
+  }
+
   test_functionTypeAlias() async {
     await assertNoErrorsInCode(r'''
 typedef F = int Function();
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 b471124..2cc6cb6 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
@@ -419,6 +419,24 @@
     ]);
   }
 
+  test_binary_eqEq_covariantParameterType() async {
+    await assertErrorsInCode(r'''
+class A {
+  bool operator==(covariant A other) => false;
+}
+
+main(A a, A? aq) {
+  a == 0;
+  aq == 1;
+  aq == aq;
+  aq == null;
+}
+''', [
+      error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 86, 1),
+      error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 97, 1),
+    ]);
+  }
+
   test_dynamicCast() async {
     await assertNoErrorsInCode(r'''
 m() {
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart
index f392af5..c12c914 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart
@@ -86,6 +86,15 @@
     ..contextFeatures = FeatureSet.forTesting(
         sdkVersion: '2.6.0', additionalFeatures: [Feature.non_nullable]);
 
+  test_class_extends_implements_never() async {
+    await assertNoErrorsInCode('''
+class I<T> {}
+class A implements I<Never> {}
+class B implements I<Never> {}
+class C extends A implements B {}
+''');
+  }
+
   test_class_extends_implements_nullability() async {
     await assertErrorsInCode('''
 class I<T> {}
@@ -125,6 +134,30 @@
 ''');
   }
 
+  test_class_mixed_viaLegacy() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {}
+
+class Bi implements A<int> {}
+
+class Biq implements A<int?> {}
+''');
+
+    // Both `Bi` and `Biq` implement `A<int*>` in legacy, so identical.
+    newFile('/test/lib/b.dart', content: r'''
+// @dart = 2.7
+import 'a.dart';
+
+class C extends Bi implements Biq {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'b.dart';
+
+abstract class D implements C {}
+''');
+  }
+
   test_class_topMerge() async {
     await assertNoErrorsInCode('''
 import 'dart:async';
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
index d7ac1a6..bde5cd0 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
@@ -434,12 +434,22 @@
   test_index() async {
     await assertErrorsInCode(r'''
 enum E {
-  a, index
+  a, index, b
 }
 ''', [
       error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 5),
     ]);
   }
+
+  test_toString() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, toString, b
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 8),
+    ]);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
index fbb109e..088a0a8 100644
--- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -6,11 +6,13 @@
 import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../dart/constant/potentially_constant_test.dart';
 import '../dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(DeadCodeTest);
+    defineReflectiveTests(DeadCodeWithNullSafetyTest);
   });
 }
 
@@ -18,11 +20,12 @@
 class DeadCodeTest extends DriverResolutionTest with PackageMixin {
   test_afterForEachWithBreakLabel() async {
     await assertNoErrorsInCode(r'''
-f() {
+f(List<Object> values) {
   named: {
-    for (var x in [1]) {
-      if (x == null)
+    for (var x in values) {
+      if (x == 42) {
         break named;
+      }
     }
     return;
   }
@@ -36,7 +39,7 @@
 f() {
   named: {
     for (int i = 0; i < 7; i++) {
-      if (i == null)
+      if (i == 42)
         break named;
     }
     return;
@@ -428,6 +431,82 @@
     ]);
   }
 
+  test_documentationComment() async {
+    await assertNoErrorsInCode(r'''
+/// text
+int f() => 0;
+''');
+  }
+
+  test_flowEnd_forStatement() async {
+    await assertErrorsInCode(r'''
+main() {
+  for (var v in [0, 1, 2]) {
+    v;
+    return;
+    1;
+  }
+  2;
+}
+''', [
+      error(HintCode.DEAD_CODE, 61, 2),
+    ]);
+  }
+
+  test_flowEnd_ifStatement() async {
+    await assertErrorsInCode(r'''
+main(bool a) {
+  if (a) {
+    return;
+    1;
+  }
+  2;
+}
+''', [
+      error(HintCode.DEAD_CODE, 42, 2),
+    ]);
+  }
+
+  test_flowEnd_tryStatement_catchClause() async {
+    await assertErrorsInCode(r'''
+main() {
+  try {
+    1;
+  } catch (_) {
+    return;
+    2;
+  }
+  3;
+}
+''', [
+      error(HintCode.DEAD_CODE, 56, 2),
+    ]);
+  }
+
+  test_flowEnd_tryStatement_finally() async {
+    var expectedErrors = expectedErrorsByNullability(
+      nullable: [
+        error(HintCode.DEAD_CODE, 61, 11),
+      ],
+      legacy: [
+        error(HintCode.DEAD_CODE, 61, 2),
+        error(HintCode.DEAD_CODE, 70, 2),
+      ],
+    );
+    await assertErrorsInCode(r'''
+main() {
+  try {
+    1;
+  } finally {
+    2;
+    return;
+    3;
+  }
+  4;
+}
+''', expectedErrors);
+  }
+
   test_statementAfterAlwaysThrowsFunction() async {
     addMetaPackage();
     await assertErrorsInCode(r'''
@@ -639,6 +718,33 @@
     ]);
   }
 
+  test_statementAfterReturn_function_local() async {
+    await assertErrorsInCode(r'''
+f() {
+  void g() {
+    print(1);
+    return;
+    print(2);
+  }
+  g();
+}''', [
+      error(HintCode.DEAD_CODE, 49, 9),
+    ]);
+  }
+
+  test_statementAfterReturn_functionExpression() async {
+    await assertErrorsInCode(r'''
+f() {
+  () {
+    print(1);
+    return;
+    print(2);
+  };
+}''', [
+      error(HintCode.DEAD_CODE, 43, 9),
+    ]);
+  }
+
   test_statementAfterReturn_ifStatement() async {
     await assertErrorsInCode(r'''
 f(bool b) {
@@ -700,3 +806,78 @@
     ]);
   }
 }
+
+@reflectiveTest
+class DeadCodeWithNullSafetyTest extends DeadCodeTest with WithNullSafetyMixin {
+  test_flowEnd_tryStatement_body() async {
+    await assertErrorsInCode(r'''
+Never foo() => throw 0;
+
+main() {
+  try {
+    foo();
+    1;
+  } catch (_) {
+    2;
+  }
+  3;
+}
+''', [
+      error(HintCode.DEAD_CODE, 57, 2),
+    ]);
+  }
+
+  test_returnTypeNever_function() async {
+    await assertErrorsInCode(r'''
+Never foo() => throw 0;
+
+main() {
+  foo();
+  1;
+}
+''', [
+      error(HintCode.DEAD_CODE, 45, 2),
+    ]);
+  }
+
+  test_returnTypeNever_getter() async {
+    await assertErrorsInCode(r'''
+Never get foo => throw 0;
+
+main() {
+  foo;
+  2;
+}
+''', [
+      error(HintCode.DEAD_CODE, 45, 2),
+    ]);
+  }
+
+  @FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
+  @override
+  test_statementAfterAlwaysThrowsFunction() async {
+    return super.test_statementAfterAlwaysThrowsFunction();
+  }
+
+  @FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
+  @override
+  test_statementAfterAlwaysThrowsMethod() async {
+    return super.test_statementAfterAlwaysThrowsMethod();
+  }
+
+  test_switchStatement_exhaustive() async {
+    await assertErrorsInCode(r'''
+enum Foo { a, b }
+
+int f(Foo foo) {
+  switch (foo) {
+    case Foo.a: return 0;
+    case Foo.b: return 1;
+  }
+  return -1;
+}
+''', [
+      error(HintCode.DEAD_CODE, 111, 10),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/enum_constant_same_name_as_enclosing.dart b/pkg/analyzer/test/src/diagnostics/enum_constant_same_name_as_enclosing.dart
new file mode 100644
index 0000000..e0b57f8
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/enum_constant_same_name_as_enclosing.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EnumConstantSameNameAsEnclosingTest);
+  });
+}
+
+@reflectiveTest
+class EnumConstantSameNameAsEnclosingTest extends DriverResolutionTest {
+  test_name() async {
+    await assertErrorsInCode(r'''
+enum E {
+  E
+}
+''', [
+      error(CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING, 11, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/export_legacy_symbol_test.dart b/pkg/analyzer/test/src/diagnostics/export_legacy_symbol_test.dart
index a95fada..364015d 100644
--- a/pkg/analyzer/test/src/diagnostics/export_legacy_symbol_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/export_legacy_symbol_test.dart
@@ -25,6 +25,18 @@
   @override
   bool get typeToStringWithNullability => true;
 
+  test_exportDartAsync() async {
+    await assertNoErrorsInCode(r'''
+export 'dart:async';
+''');
+  }
+
+  test_exportDartCore() async {
+    await assertNoErrorsInCode(r'''
+export 'dart:core';
+''');
+  }
+
   test_exportOptedIn() async {
     newFile('/test/lib/a.dart', content: r'''
 class A {}
diff --git a/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
index 0ff696e..7fe09d4 100644
--- a/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
@@ -71,25 +71,29 @@
         sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
 
   test_awaitForIn_never() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 f(Never e) async {
   await for (var id in e) {
     id;
   }
 }
-''');
+''', [
+      error(HintCode.DEAD_CODE, 32, 26),
+    ]);
     // TODO(scheglov) extract for-in resolution and implement
 //    assertType(findNode.simple('id;'), 'Never');
   }
 
   test_forIn_never() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 f(Never e) {
   for (var id in e) {
     id;
   }
 }
-''');
+''', [
+      error(HintCode.DEAD_CODE, 20, 26),
+    ]);
     // TODO(scheglov) extract for-in resolution and implement
 //    assertType(findNode.simple('id;'), 'Never');
   }
diff --git a/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart b/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart
index bc9db02..5a1293a 100644
--- a/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart
@@ -24,7 +24,6 @@
     ]);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38188')
   test_function_nonFuture_withReturn() async {
     await assertErrorsInCode('''
 int f() async {
diff --git a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
index 8d86a32..aa3745b 100644
--- a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
@@ -74,6 +74,25 @@
     ]);
   }
 
+  test_instanceVariableInitializer_nestedLocal() async {
+    // Test that (1) does not prevent reporting an error at (2).
+    await assertErrorsInCode(r'''
+class A {
+  Map foo = {
+    'a': () {
+      var v = 0; // (1)
+      v;
+    },
+    'b': _foo // (2)
+  };
+
+  void _foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 87, 4),
+    ]);
+  }
+
   test_invocation() async {
     await assertErrorsInCode(r'''
 class A {
@@ -97,28 +116,6 @@
     ]);
   }
 
-  test_isInInstanceVariableInitializer_restored() async {
-    // If ErrorVerifier._isInInstanceVariableInitializer is not properly
-    // restored on exit from visitVariableDeclaration, the error at (1)
-    // won't be detected.
-    await assertErrorsInCode(r'''
-class Foo {
-  var bar;
-  Map foo = {
-    'bar': () {
-        var _bar;
-    },
-    'bop': _foo // (1)
-  };
-  _foo() {
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 65, 4),
-      error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 89, 4),
-    ]);
-  }
-
   test_prefixedIdentifier() async {
     await assertNoErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
index d9209a9..312f892 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
@@ -44,6 +44,30 @@
 }
 ''');
   }
+
+  test_localLevelVariable_never_null() async {
+    await assertErrorsInCode('''
+void f(Never x) {
+  x = null;
+}
+''', [
+      error(HintCode.DEAD_CODE, 24, 5),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 24, 4),
+    ]);
+  }
+
+  test_topLevelVariable_never_null() async {
+    await assertErrorsInCode('''
+Never x = throw 0;
+
+void f() {
+  x = null;
+}
+''', [
+      error(HintCode.DEAD_CODE, 37, 5),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 37, 4),
+    ]);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
index afba36c..662a22b 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
@@ -61,7 +61,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.INVALID_OVERRIDE, 163, 6),
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 163, 6),
     ]);
   }
 
@@ -124,6 +123,24 @@
 ''');
   }
 
+  test_method_covariant_3() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo(num a) {}
+}
+
+class B extends A {
+  void foo(dynamic a) {}
+}
+
+class C extends B {
+  void foo(covariant String a) {}
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_OVERRIDE, 109, 3),
+    ]);
+  }
+
   test_method_named_fewerNamedParameters() async {
     await assertErrorsInCode('''
 class A {
@@ -220,7 +237,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 1),
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 1),
     ]);
   }
 
@@ -269,7 +285,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 1),
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 1),
     ]);
   }
 
@@ -408,7 +423,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.INVALID_OVERRIDE, 129, 1),
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 129, 1),
     ]);
   }
 
@@ -452,7 +466,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.INVALID_OVERRIDE, 173, 8),
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 173, 8),
     ]);
   }
 
@@ -471,7 +484,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.INVALID_OVERRIDE, 166, 8),
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 166, 8),
     ]);
   }
 
@@ -539,14 +551,81 @@
 ''');
   }
 
-  test_method_viaLegacy_returnType_notSubtype() async {
+  test_mixedInheritance_1() async {
     newFile('/test/lib/a.dart', content: r'''
-class Nullable {
-  int? foo() => 0;
+class B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
 }
 
-class NonNullable {
-  int foo() => 0;
+class Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+''');
+
+    newFile('/test/lib/b.dart', content: r'''
+// @dart = 2.7
+import 'a.dart';
+
+class C with B {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+import 'b.dart';
+
+class D extends C implements Bq {}
+''');
+  }
+
+  test_mixedInheritance_2() async {
+    newFile('/test/lib/a.dart', content: r'''
+class B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+''');
+
+    newFile('/test/lib/b.dart', content: r'''
+// @dart = 2.7
+import 'a.dart';
+
+class C extends B with Bq {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'b.dart';
+
+class D extends C {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+''');
+  }
+
+  test_viaLegacy_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A1 {
+  int m() => 0;
+  int get g => 0;
+  set s(int? _) {}
+}
+
+class A2 {
+  int? m() => 0;
+  int? get g => 0;
+  set s(int _) {}
 }
 ''');
 
@@ -554,19 +633,58 @@
 // @dart=2.6
 import 'a.dart';
 
-class A extends Nullable implements NonNullable {}
+class L extends A2 implements A1 {}
 ''');
 
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
+import 'a.dart';
 import 'b.dart';
 
-class B extends A {}
+class X1 extends L implements A1 {}
+class X2 extends L implements A2 {}
 
-class C extends A {   
-  int? foo() => 0;
+class Y extends L {
+  int? get g => 0;
+  int? m() => 0;
+  set s(int _) {}
 }
-''', [
-      error(CompileTimeErrorCode.INVALID_OVERRIDE, 70, 3),
-    ]);
+''');
+  }
+
+  test_viaLegacy_mixin() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A1 {
+  int m() => 0;
+  int get g => 0;
+  set s(int? _) {}
+}
+
+mixin A2 {
+  int? m() => 0;
+  int? get g => 0;
+  set s(int _) {}
+}
+''');
+
+    newFile('/test/lib/b.dart', content: r'''
+// @dart=2.6
+import 'a.dart';
+
+class L extends Object with A2 implements A1 {}
+''');
+
+    await assertNoErrorsInCode('''
+import 'a.dart';
+import 'b.dart';
+
+class X1 extends L implements A1 {}
+class X2 extends L implements A2 {}
+
+class Y extends L {
+  int? get g => 0;
+  int? m() => 0;
+  set s(int _) {}
+}
+''');
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
index 8bc17df..0236a09 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
@@ -23,7 +23,62 @@
     ..contextFeatures = FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
 
-  test_constructor_nonNullable_named_optional_noDefault() async {
+  test_constructor_externalFactory_nonNullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  external factory C({int a});
+}
+''');
+  }
+
+  test_constructor_externalFactory_nonNullable_positional_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  external factory C([int a]);
+}
+''');
+  }
+
+  test_constructor_externalFactory_nullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  external factory C({int? a});
+}
+''');
+  }
+
+  test_constructor_factory_nonNullable_named_optional_noDefault() async {
+    await assertErrorsInCode('''
+class C {
+  factory C({int a}) => C._();
+  C._();
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 27, 1),
+    ]);
+  }
+
+  test_constructor_factory_nonNullable_positional_optional_noDefault() async {
+    await assertErrorsInCode('''
+class C {
+  factory C([int a]) => C._();
+  C._();
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 27, 1),
+    ]);
+  }
+
+  test_constructor_factory_nullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  factory C({int? a}) => C._();
+  C._();
+}
+''');
+  }
+
+  test_constructor_generative_nonNullable_named_optional_noDefault() async {
     await assertErrorsInCode('''
 class C {
   C({int a});
@@ -33,7 +88,7 @@
     ]);
   }
 
-  test_constructor_nonNullable_positional_optional_noDefault() async {
+  test_constructor_generative_nonNullable_positional_optional_noDefault() async {
     await assertErrorsInCode('''
 class C {
   C([int a]);
@@ -43,7 +98,7 @@
     ]);
   }
 
-  test_constructor_nullable_named_optional_noDefault() async {
+  test_constructor_generative_nullable_named_optional_noDefault() async {
     await assertNoErrorsInCode('''
 class C {
   C({int? a});
@@ -51,7 +106,7 @@
 ''');
   }
 
-  test_constructor_nullable_named_optional_noDefault_fieldFormal() async {
+  test_constructor_generative_nullable_named_optional_noDefault_fieldFormal() async {
     await assertNoErrorsInCode('''
 class C {
   int? f;
diff --git a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
index 50e9132..480726c 100644
--- a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
@@ -812,7 +812,7 @@
   }
 
   test_if_condition_notTrue() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 void f() {
   int v;
   if (!true) {
@@ -822,7 +822,9 @@
   }
   v;
 }
-''');
+''', [
+      error(HintCode.DEAD_CODE, 33, 25),
+    ]);
   }
 
   test_if_condition_true() async {
@@ -1325,7 +1327,7 @@
   }
 
   test_while_true_break_if() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 void f(bool b) {
   int v;
   while (true) {
@@ -1340,7 +1342,9 @@
   }
   v;
 }
-''');
+''', [
+      error(HintCode.DEAD_CODE, 131, 2),
+    ]);
   }
 
   test_while_true_break_if2() async {
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.dart
index 195f47c..10b129c 100644
--- a/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.dart
@@ -1,13 +1,11 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../dart/constant/potentially_constant_test.dart';
 import '../dart/resolution/driver_resolution.dart';
 
 main() {
@@ -17,13 +15,8 @@
 }
 
 @reflectiveTest
-class NullableTypeInCatchClauseTest extends DriverResolutionTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = FeatureSet.fromEnableFlags(
-      [EnableString.non_nullable],
-    );
-
+class NullableTypeInCatchClauseTest extends DriverResolutionTest
+    with WithNullSafetyMixin {
   test_noOnClause() async {
     await assertNoErrorsInCode('''
 f() {
@@ -34,43 +27,60 @@
 ''');
   }
 
-  test_on_class_nonNullable() async {
+  test_on_dynamic() async {
     await assertErrorsInCode('''
 class A {}
 f() {
   try {
-  } on A catch (e) {
+  } on dynamic {
   }
 }
 ''', [
-      error(HintCode.UNUSED_CATCH_CLAUSE, 41, 1),
+      error(HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 32, 7),
     ]);
   }
 
-  test_on_class_nullable() async {
-    await assertErrorsInCode('''
-class A {}
+  test_on_functionType_nonNullable() async {
+    await assertNoErrorsInCode('''
 f() {
   try {
-  } on A? {
+  } on void Function() {
+  }
+}
+''');
+  }
+
+  test_on_functionType_nullable() async {
+    await assertErrorsInCode('''
+f() {
+  try {
+  } on void Function()? {
   }
 }
 ''', [
-      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 32, 2),
+      error(HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 21, 16),
     ]);
   }
 
-  test_on_typeParameter() async {
+  test_on_interfaceType_nonNullable() async {
+    await assertNoErrorsInCode('''
+f() {
+  try {
+  } on int {
+  }
+}
+''');
+  }
+
+  test_on_interfaceType_nullable() async {
     await assertErrorsInCode('''
-class A<B> {
-  m() {
-    try {
-    } on B {
-    }
+f() {
+  try {
+  } on int? {
   }
 }
 ''', [
-      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 40, 1),
+      error(HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 21, 4),
     ]);
   }
 
@@ -86,6 +96,20 @@
 ''');
   }
 
+  test_on_typeParameter_nullable() async {
+    await assertErrorsInCode('''
+class A<B> {
+  m() {
+    try {
+    } on B {
+    }
+  }
+}
+''', [
+      error(HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 40, 1),
+    ]);
+  }
+
   test_optOut() async {
     await assertNoErrorsInCode('''
 // @dart = 2.7
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 9e628cc..3c4b65e 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
@@ -35,6 +35,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 28, 6),
     ]);
 
     assertBinaryExpression(
@@ -53,6 +54,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 27, 8),
     ]);
 
     assertBinaryExpression(
@@ -141,6 +143,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 25, 3),
     ]);
 
     assertIndexExpression(
@@ -158,6 +161,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 25, 12),
     ]);
 
     assertIndexExpression(
@@ -177,6 +181,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 25, 11),
     ]);
 
     assertIndexExpression(
@@ -263,6 +268,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 28, 8),
     ]);
 
     assertMethodInvocation(
@@ -283,6 +289,7 @@
 }
 ''', [
       error(HintCode.RECEIVER_OF_TYPE_NEVER, 23, 1),
+      error(HintCode.DEAD_CODE, 33, 8),
     ]);
 
     assertMethodInvocation(
@@ -410,11 +417,13 @@
   }
 
   test_propertyAccess_never_readWrite() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 void main(Never x) {
   x.foo += 0;
 }
-''');
+''', [
+      error(HintCode.DEAD_CODE, 32, 2),
+    ]);
 
     assertSimpleIdentifier(
       findNode.simple('foo'),
@@ -444,11 +453,13 @@
   }
 
   test_propertyAccess_never_write() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 void main(Never x) {
   x.foo = 0;
 }
-''');
+''', [
+      error(HintCode.DEAD_CODE, 31, 2),
+    ]);
 
     assertSimpleIdentifier(
       findNode.simple('foo'),
diff --git a/pkg/analyzer/test/src/diagnostics/redirect_to_abstract_class_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/redirect_to_abstract_class_constructor_test.dart
new file mode 100644
index 0000000..a828062
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/redirect_to_abstract_class_constructor_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RedirectToAbstractClassConstructorTest);
+  });
+}
+
+@reflectiveTest
+class RedirectToAbstractClassConstructorTest extends DriverResolutionTest {
+  test_abstractRedirectsToSelf() async {
+    await assertErrorsInCode(r'''
+abstract class A {
+  factory A() = A._;
+  A._();
+}
+''', [
+      error(CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR, 35, 3),
+    ]);
+  }
+
+  test_redirectsToAbstractSubclass() async {
+    await assertErrorsInCode(r'''
+class A {
+  factory A.named() = B;
+  A();
+}
+
+abstract class B extends A {}
+''', [
+      error(CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR, 32, 1),
+    ]);
+  }
+
+  test_redirectsToSubclass() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  factory A.named() = B;
+  A();
+}
+
+class B extends A {}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
index 2946765..7f9667b 100644
--- a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
@@ -39,18 +39,12 @@
   }
 
   test_async_future_int_mismatches_int() async {
-    // TODO(brianwilkerson) Stop producing RETURN_OF_INVALID_TYPE_FROM_FUNCTION.
     await assertErrorsInCode('''
 int f() async {
   return 5;
 }
 ''', [
       error(StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, 0, 3),
-      error(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 25, 1,
-          contextMessages: [
-            message('/sdk/lib/core/core.dart', 2150, 3),
-            message('/sdk/lib/core/core.dart', 2150, 3)
-          ]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 67486e1..76664cc 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -82,6 +82,8 @@
 import 'duplicate_named_argument_test.dart' as duplicate_named_argument;
 import 'duplicate_part_test.dart' as duplicate_part;
 import 'duplicate_shown_name_test.dart' as duplicate_shown_name;
+import 'enum_constant_same_name_as_enclosing.dart'
+    as enum_constant_same_name_as_enclosing;
 import 'equal_elements_in_const_set_test.dart' as equal_elements_in_const_set;
 import 'equal_elements_in_set_test.dart' as equal_elements_in_set;
 import 'equal_keys_in_const_map_test.dart' as equal_keys_in_const_map;
@@ -374,6 +376,8 @@
     as redirect_generative_to_missing_constructor;
 import 'redirect_generative_to_non_generative_constructor_test.dart'
     as redirect_generative_to_non_generative_constructor;
+import 'redirect_to_abstract_class_constructor_test.dart'
+    as redirect_to_abstract_class_constructor;
 import 'redirect_to_invalid_function_type_test.dart'
     as redirect_to_invalid_function_type;
 import 'redirect_to_invalid_return_type_test.dart'
@@ -431,6 +435,7 @@
     as switch_case_completes_normally;
 import 'switch_expression_not_assignable_test.dart'
     as switch_expression_not_assignable;
+import 'throw_of_invalid_type_test.dart' as throw_of_invalid_type;
 import 'todo_test.dart' as todo_test;
 import 'top_level_instance_getter_test.dart' as top_level_instance_getter;
 import 'top_level_instance_method_test.dart' as top_level_instance_method;
@@ -560,6 +565,7 @@
     duplicate_named_argument.main();
     duplicate_part.main();
     duplicate_shown_name.main();
+    enum_constant_same_name_as_enclosing.main();
     equal_elements_in_const_set.main();
     equal_elements_in_set.main();
     equal_keys_in_const_map.main();
@@ -754,6 +760,7 @@
     recursive_factory_redirect.main();
     redirect_generative_to_missing_constructor.main();
     redirect_generative_to_non_generative_constructor.main();
+    redirect_to_abstract_class_constructor.main();
     redirect_to_invalid_function_type.main();
     redirect_to_invalid_return_type.main();
     redirect_to_missing_constructor.main();
@@ -791,6 +798,7 @@
     super_initializer_in_object.main();
     switch_case_completes_normally.main();
     switch_expression_not_assignable.main();
+    throw_of_invalid_type.main();
     todo_test.main();
     top_level_instance_getter.main();
     top_level_instance_method.main();
diff --git a/pkg/analyzer/test/src/diagnostics/throw_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/throw_of_invalid_type_test.dart
new file mode 100644
index 0000000..448719d
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/throw_of_invalid_type_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ThrowOfInvalidTypeTest);
+  });
+}
+
+@reflectiveTest
+class ThrowOfInvalidTypeTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.fromEnableFlags(
+      [EnableString.non_nullable],
+    );
+
+  test_dynamic() async {
+    await assertNoErrorsInCode('''
+f(dynamic a) {
+  throw a;
+}
+''');
+  }
+
+  test_legacy() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+int a = 0;
+''');
+    await assertNoErrorsInCode('''
+import 'a.dart';
+
+f() {
+  throw a;
+}
+''');
+  }
+
+  test_nonNullable() async {
+    await assertNoErrorsInCode('''
+f(int a) {
+  throw a;
+}
+''');
+  }
+
+  test_nullable() async {
+    await assertErrorsInCode('''
+f(int? a) {
+  throw a;
+}
+''', [
+      error(CompileTimeErrorCode.THROW_OF_INVALID_TYPE, 20, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
index cb92c0d..045edd4 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
@@ -95,6 +95,13 @@
 ''');
   }
 
+  test_isUsed_privateEnum_values() async {
+    await assertNoErrorsInCode(r'''
+enum _Foo {a}
+f() => _Foo.values;
+''');
+  }
+
   test_isUsed_publicEnum_privateValue() async {
     await assertNoErrorsInCode(r'''
 enum Foo {_a, _b}
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
index 2613cb9..b1cbafc 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
@@ -2,13 +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/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../generated/test_support.dart';
+import '../dart/constant/potentially_constant_test.dart';
 import '../dart/resolution/driver_resolution.dart';
 
 main() {
@@ -97,10 +95,10 @@
 
   test_await() async {
     await assertNoErrorsInCode('''
-main() async {
-  void x;
+main(void x) async {
   await x;
-}''');
+}
+''');
   }
 
   test_extensionApplication() async {
@@ -728,12 +726,17 @@
 }
 
 @reflectiveTest
-class UseOfVoidResultTest_NonNullable extends DriverResolutionTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = FeatureSet.fromEnableFlags(
-      [EnableString.non_nullable],
-    );
+class UseOfVoidResultTest_NonNullable extends DriverResolutionTest
+    with WithNullSafetyMixin {
+  test_await() async {
+    await assertErrorsInCode('''
+main(void x) async {
+  await x;
+}
+''', [
+      error(StaticWarningCode.USE_OF_VOID_RESULT, 29, 1),
+    ]);
+  }
 
   test_nullCheck() async {
     await assertErrorsInCode(r'''
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 94e0f48..2f12e46 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
@@ -16,7 +16,8 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CanBeConstConstructorTest);
-    defineReflectiveTests(CanBeConstTest);
+    defineReflectiveTests(CanBeConstInstanceCreationTest);
+    defineReflectiveTests(CanBeConstTypedLiteralTest);
     defineReflectiveTests(EvaluateExpressionTest);
     defineReflectiveTests(PubDependencyTest);
   });
@@ -149,7 +150,7 @@
 }
 
 @reflectiveTest
-class CanBeConstTest extends AbstractLinterContextTest {
+class CanBeConstInstanceCreationTest extends AbstractLinterContextTest {
   void assertCanBeConst(String snippet, bool expectedResult) {
     var node = findNode.instanceCreation(snippet);
     expect(context.canBeConst(node), expectedResult);
@@ -208,6 +209,23 @@
     assertCanBeConst("A<U>", false);
   }
 
+  void test_true_computeDependencies() async {
+    newFile('/test/lib/a.dart', content: r'''
+const a = 0;
+''');
+
+    await resolve('''
+import 'a.dart';
+
+class A {
+  const A(int a);
+}
+
+A f() => A(a);
+''');
+    assertCanBeConst('A(a)', true);
+  }
+
   void test_true_constConstructorArg() async {
     await resolve('''
 class A {
@@ -249,6 +267,102 @@
 }
 
 @reflectiveTest
+class CanBeConstTypedLiteralTest extends AbstractLinterContextTest {
+  void assertCanBeConst(String snippet, bool expectedResult) {
+    var node = findNode.typedLiteral(snippet);
+    expect(context.canBeConst(node), expectedResult);
+  }
+
+  void test_listLiteral_false_methodInvocation() async {
+    await resolve('''
+f() => [g()];
+int g() => 0;
+''');
+    assertCanBeConst('[', false);
+  }
+
+  void test_listLiteral_false_typeParameter() async {
+    await resolve('''
+class A<T> {
+  const A();
+}
+
+f<U>() => [A<U>()];
+''');
+    assertCanBeConst('[', false);
+  }
+
+  void test_listLiteral_true_computeDependencies() async {
+    newFile('/test/lib/a.dart', content: r'''
+const a = 0;
+''');
+
+    await resolve('''
+import 'a.dart';
+
+f() => [a];
+''');
+    assertCanBeConst('[', true);
+  }
+
+  void test_listLiteral_true_constConstructor() async {
+    await resolve('''
+class A {
+  const A();
+}
+
+f() => [A()];
+''');
+    assertCanBeConst('[', true);
+  }
+
+  void test_listLiteral_true_integerLiteral() async {
+    await resolve('''
+f() => [1, 2, 3];
+''');
+    assertCanBeConst('[', true);
+  }
+
+  void test_mapLiteral_false_methodInvocation_key() async {
+    await resolve('''
+f() => {g(): 0};
+int g() => 0;
+''');
+    assertCanBeConst('{', false);
+  }
+
+  void test_mapLiteral_false_methodInvocation_value() async {
+    await resolve('''
+f() => {0: g()};
+int g() => 0;
+''');
+    assertCanBeConst('{', false);
+  }
+
+  void test_mapLiteral_true_integerLiteral() async {
+    await resolve('''
+f() => {1: 2, 3: 4};
+''');
+    assertCanBeConst('{', true);
+  }
+
+  void test_setLiteral_false_methodInvocation() async {
+    await resolve('''
+f() => {g()};
+int g() => 0;
+''');
+    assertCanBeConst('{', false);
+  }
+
+  void test_setLiteral_true_integerLiteral() async {
+    await resolve('''
+f() => {1, 2, 3};
+''');
+    assertCanBeConst('{', true);
+  }
+}
+
+@reflectiveTest
 class EvaluateExpressionTest extends AbstractLinterContextTest {
   test_hasError_listLiteral_forElement() async {
     await resolve('''
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 340a034..5e594b8 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -3,10 +3,10 @@
 // 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/src/context/context.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
+import 'package:analyzer/src/dart/element/class_hierarchy.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -216,7 +216,10 @@
   }
 }
 
-class _AnalysisSessionForLinking implements AnalysisSession {
+class _AnalysisSessionForLinking implements AnalysisSessionImpl {
+  @override
+  final ClassHierarchy classHierarchy = ClassHierarchy();
+
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 2850837..edbcf0e 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2649,7 +2649,6 @@
 ''');
   }
 
-  @failingTest
   test_invalidOverrides_doubleOverride() async {
     await checkFile('''
 class A {}
@@ -2669,7 +2668,6 @@
 ''');
   }
 
-  @failingTest
   test_invalidOverrides_doubleOverride2() async {
     await checkFile('''
 class A {}
@@ -2747,20 +2745,13 @@
     int x;
 }
 
-class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base
-    with /*error:INVALID_OVERRIDE*/M1 {}
-class /*error:INCONSISTENT_INHERITANCE*/T2 extends Base
-    with /*error:INVALID_OVERRIDE*/M1, M2 {}
-class /*error:INCONSISTENT_INHERITANCE*/T3 extends Base
-    with M2, /*error:INVALID_OVERRIDE*/M1 {}
+class T1 extends Base with /*error:INVALID_OVERRIDE*/M1 {}
+class T2 extends Base with /*error:INVALID_OVERRIDE*/M1, M2 {}
+class T3 extends Base with M2, /*error:INVALID_OVERRIDE*/M1 {}
 
-
-class /*error:INCONSISTENT_INHERITANCE*/U1 = Base
-    with /*error:INVALID_OVERRIDE*/M1;
-class /*error:INCONSISTENT_INHERITANCE*/U2 = Base
-    with /*error:INVALID_OVERRIDE*/M1, M2;
-class /*error:INCONSISTENT_INHERITANCE*/U3 = Base
-    with M2, /*error:INVALID_OVERRIDE*/M1;
+class U1 = Base with /*error:INVALID_OVERRIDE*/M1;
+class U2 = Base with /*error:INVALID_OVERRIDE*/M1, M2;
+class U3 = Base with M2, /*error:INVALID_OVERRIDE*/M1;
 ''');
   }
 
@@ -2782,13 +2773,9 @@
     int x;
 }
 
-class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base
-    with M1,
-    /*error:INVALID_OVERRIDE*/M2 {}
+class T1 extends Base with M1, /*error:INVALID_OVERRIDE*/M2 {}
 
-class /*error:INCONSISTENT_INHERITANCE*/U1 = Base
-    with M1,
-    /*error:INVALID_OVERRIDE*/M2;
+class U1 = Base with M1, /*error:INVALID_OVERRIDE*/M2;
 ''');
   }
 
@@ -3410,11 +3397,9 @@
     m(B a) {}
 }
 
-class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base
-    with /*error:INVALID_OVERRIDE*/M {}
+class T1 extends Base with /*error:INVALID_OVERRIDE*/M {}
 
-class /*error:INCONSISTENT_INHERITANCE*/U1 = Base
-    with /*error:INVALID_OVERRIDE*/M;
+class U1 = Base with /*error:INVALID_OVERRIDE*/M;
 ''');
   }
 
@@ -3434,11 +3419,9 @@
     m(B a) {}
 }
 
-class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base
-    with /*error:INVALID_OVERRIDE*/M {}
+class T1 extends Base with /*error:INVALID_OVERRIDE*/M {}
 
-class /*error:INCONSISTENT_INHERITANCE*/U1 = Base
-    with /*error:INVALID_OVERRIDE*/M;
+class U1 = Base with /*error:INVALID_OVERRIDE*/M;
 ''');
   }
 
@@ -3647,7 +3630,6 @@
 ''');
   }
 
-  @failingTest
   test_noDuplicateReports_typeOverridesSomeMethodInMultipleInterfaces() async {
     await checkFile('''
 class A {}
@@ -4330,12 +4312,7 @@
 }
 
 class T1 extends Base {
-    // we consider the base class incomplete because it is
-    // abstract, so we report the error here too.
-    // TODO(sigmund): consider tracking overrides in a fine-grain
-    // manner, then this and the double-overrides would not be
-    // reported.
-    /*error:INVALID_OVERRIDE*/m(B a) {}
+    m(B a) {}
 }
 ''');
   }
@@ -4354,7 +4331,7 @@
 }
 
 class T1 extends Base {
-    /*error:INVALID_OVERRIDE*/m(B a) {}
+    m(B a) {}
 }
 ''');
   }
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 97dd440..5cd6fd9 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -49,8 +49,14 @@
     'HintCode.DEPRECATED_MEMBER_USE',
     // Needs to be able to specify two expected diagnostics.
     'StaticWarningCode.AMBIGUOUS_IMPORT',
+    // Produces two diagnostics when it should only produce one.
+    'StaticWarningCode.INVALID_USE_OF_NULL_VALUE',
   ];
 
+  /// The prefix used on directive lines to specify the experiments that should
+  /// be enabled for a snippet.
+  static const String experimentsPrefix = '%experiments=';
+
   /// The prefix used on directive lines to indicate the uri of an auxiliary
   /// file that is needed for testing purposes.
   static const String uriDirectivePrefix = '%uri="';
@@ -130,19 +136,19 @@
     return docs;
   }
 
-  _SnippetData _extractSnippetData(
-      String snippet, bool errorRequired, Map<String, String> auxiliaryFiles) {
+  _SnippetData _extractSnippetData(String snippet, bool errorRequired,
+      Map<String, String> auxiliaryFiles, List<String> experiments) {
     int rangeStart = snippet.indexOf(errorRangeStart);
     if (rangeStart < 0) {
       if (errorRequired) {
         _reportProblem('No error range in example');
       }
-      return _SnippetData(snippet, -1, 0, auxiliaryFiles);
+      return _SnippetData(snippet, -1, 0, auxiliaryFiles, experiments);
     }
     int rangeEnd = snippet.indexOf(errorRangeEnd, rangeStart + 1);
     if (rangeEnd < 0) {
       _reportProblem('No end of error range in example');
-      return _SnippetData(snippet, -1, 0, auxiliaryFiles);
+      return _SnippetData(snippet, -1, 0, auxiliaryFiles, experiments);
     } else if (snippet.indexOf(errorRangeStart, rangeEnd) > 0) {
       _reportProblem('More than one error range in example');
     }
@@ -152,33 +158,43 @@
             snippet.substring(rangeEnd + errorRangeEnd.length),
         rangeStart,
         rangeEnd - rangeStart - 2,
-        auxiliaryFiles);
+        auxiliaryFiles,
+        experiments);
   }
 
   /// Extract the snippets of Dart code between the start (inclusive) and end
   /// (exclusive) indexes.
   List<_SnippetData> _extractSnippets(
       List<String> lines, int start, int end, bool errorRequired) {
-    List<_SnippetData> snippets = [];
-    Map<String, String> auxiliaryFiles = <String, String>{};
-    int currentStart = -1;
-    for (int i = start; i < end; i++) {
-      String line = lines[i];
+    var snippets = <_SnippetData>[];
+    var auxiliaryFiles = <String, String>{};
+    List<String> experiments;
+    var currentStart = -1;
+    for (var i = start; i < end; i++) {
+      var line = lines[i];
       if (line == '```') {
         if (currentStart < 0) {
           _reportProblem('Snippet without file type on line $i.');
           return snippets;
         }
-        String secondLine = lines[currentStart + 1];
+        var secondLine = lines[currentStart + 1];
         if (secondLine.startsWith(uriDirectivePrefix)) {
-          String name = secondLine.substring(
+          var name = secondLine.substring(
               uriDirectivePrefix.length, secondLine.length - 1);
-          String content = lines.sublist(currentStart + 2, i).join('\n');
+          var content = lines.sublist(currentStart + 2, i).join('\n');
           auxiliaryFiles[name] = content;
         } else if (lines[currentStart] == '```dart') {
-          String content = lines.sublist(currentStart + 1, i).join('\n');
-          snippets
-              .add(_extractSnippetData(content, errorRequired, auxiliaryFiles));
+          if (secondLine.startsWith(experimentsPrefix)) {
+            experiments = secondLine
+                .substring(experimentsPrefix.length)
+                .split(',')
+                .map((e) => e.trim())
+                .toList();
+            currentStart++;
+          }
+          var content = lines.sublist(currentStart + 1, i).join('\n');
+          snippets.add(_extractSnippetData(
+              content, errorRequired, auxiliaryFiles, experiments));
           auxiliaryFiles = <String, String>{};
         }
         currentStart = -1;
@@ -246,6 +262,9 @@
             if (docs != null) {
               VariableDeclaration variable = member.fields.variables[0];
               codeName = _extractCodeName(variable);
+              if (codeName == 'NULLABLE_TYPE_IN_CATCH_CLAUSE') {
+                DateTime.now();
+              }
               variableName = '$className.${variable.name.name}';
               if (unverifiedDocs.contains(variableName)) {
                 continue;
@@ -366,8 +385,10 @@
   final int offset;
   final int length;
   final Map<String, String> auxiliaryFiles;
+  final List<String> experiments;
 
-  _SnippetData(this.content, this.offset, this.length, this.auxiliaryFiles);
+  _SnippetData(this.content, this.offset, this.length, this.auxiliaryFiles,
+      this.experiments);
 }
 
 /// A test class that creates an environment suitable for analyzing the
@@ -381,9 +402,8 @@
 
   /// Initialize a newly created test to test the given [snippet].
   _SnippetTest(this.snippet) {
-    analysisOptions.contextFeatures = FeatureSet.fromEnableFlags(
-      ['extension-methods'],
-    );
+    analysisOptions.contextFeatures =
+        FeatureSet.fromEnableFlags(snippet.experiments ?? []);
     String pubspecContent = snippet.auxiliaryFiles['pubspec.yaml'];
     if (pubspecContent != null) {
       for (String line in pubspecContent.split('\n')) {
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index bd24cb1..e4481c9 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -57,6 +57,22 @@
   }
   ```
 
+### Potentially non-nullable
+
+A type is _potentially non-nullable_ if it's either explicitly non-nullable or
+if it's a type parameter.
+
+A type is explicitly non-nullable if it is a type name that is not followed by a
+question mark. Note that there are a few types that are always nullable, such as
+`Null` and `dynamic`, and that `FutureOr` is only non-nullable if it is not
+followed by a question mark _and_ the type argument is non-nullable (such as
+`FutureOr<String>`).
+
+Type parameters are potentially non-nullable because the actual runtime type
+(the type specified as a type argument) might be non-nullable. For example,
+given a declaration of `class C<T> {}`, the type `C` could be used with a
+non-nullable type argument as in `C<int>`.
+
 ## Diagnostics
 
 The analyzer produces the following diagnostics for code that
@@ -557,6 +573,82 @@
 
 Rewrite the code so that there isn't an assignment to a method.
 
+### body_might_complete_normally
+
+_The body might complete normally, causing 'null' to be returned, but the return
+type is a potentially non-nullable type._
+
+#### Description
+
+The analyzer produces this diagnostic when a method or function has a
+return type that's <a href=”#potentially-non-nullable”>potentially
+non-nullable</a> but would implicitly return `null` if control reached the
+end of the function.
+
+#### Example
+
+The following code produces this diagnostic because the method `m` has an
+implicit return of `null` inserted at the end of the method, but the method
+is declared to not return `null`:
+
+{% prettify dart %}
+class C {
+  int [!m!](int t) {
+    print(t);
+  }
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the method `m` has an
+implicit return of `null` inserted at the end of the method, but because
+the class `C` can be instantiated with a non-nullable type argument, the
+method is effectively declared to not return `null`:
+
+{% prettify dart %}
+class C<T> {
+  T [!m!](T t) {
+    print(t);
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If there's a reasonable value that can be returned, then add a return
+statement at the end of the method:
+
+{% prettify dart %}
+class C<T> {
+  T m(T t) {
+    print(t);
+    return t;
+  }
+}
+{% endprettify %}
+
+If the method won't reach the implicit return, then add a throw at the end
+of the method:
+
+{% prettify dart %}
+class C<T> {
+  T m(T t) {
+    print(t);
+    throw '';
+  }
+}
+{% endprettify %}
+
+If the method intentionally returns `null` at the end, then change the
+return type so that it's valid to return `null`:
+
+{% prettify dart %}
+class C<T> {
+  T? m(T t) {
+    print(t);
+  }
+}
+{% endprettify %}
+
 ### built_in_identifier_as_extension_name
 
 _The built-in identifier '{0}' can't be used as an extension name._
@@ -648,6 +740,57 @@
 }
 {% endprettify %}
 
+### case_expression_type_is_not_switch_expression_subtype
+
+_The switch case expression type '{0}' must be a subtype of the switch
+expression type '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the expression following `case`
+in a switch statement has a static type that isn't a subtype of the static
+type of the expression following `switch`.
+
+#### Example
+
+The following code produces this diagnostic because `1` is an `int`, which
+isn't a subtype of `String` (the type of `s`):
+
+{% prettify dart %}
+void f(String s) {
+  switch (s) {
+    case [!1!]:
+      break;
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the value of the case expression is wrong, then change the case
+expression so that it has the required type:
+
+{% prettify dart %}
+void f(String s) {
+  switch (s) {
+    case '1':
+      break;
+  }
+}
+{% endprettify %}
+
+If the value of the case expression is correct, then change the switch
+expression to have the required type:
+
+{% prettify dart %}
+void f(int s) {
+  switch (s) {
+    case 1:
+      break;
+  }
+}
+{% endprettify %}
+
 ### cast_to_non_type
 
 _The name '{0}' isn't a type, so it can't be used in an 'as' expression._
@@ -1156,6 +1299,160 @@
 }
 {% endprettify %}
 
+### dead_null_aware_expression
+
+_The left operand can't be null, so the right operand is never executed._
+
+#### Description
+
+The analyzer produces this diagnostic in two cases.
+
+The first is when the left operand of an `??` operator can't be `null`.
+The right operand is only evaluated if the left operand has the value
+`null`, and because the left operand can't be `null`, the right operand is
+never evaluated.
+
+The second is when the left-hand side of an assignment using the `??=`
+operator can't be `null`. The right-hand side is only evaluated if the
+left-hand side has the value `null`, and because the left-hand side can't
+be `null`, the right-hand side is never evaluated.
+
+#### Example
+
+The following code produces this diagnostic because `x` can't be `null`:
+
+{% prettify dart %}
+int f(int x) {
+  return x ?? [!0!];
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `f` can't be `null`:
+
+{% prettify dart %}
+class C {
+  int f = -1;
+
+  void m(int x) {
+    f ??= [!x!];
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the diagnostic is reported for an `??` operator, then remove the `??`
+operator and the right operand:
+
+{% prettify dart %}
+int f(int x) {
+  return x;
+}
+{% endprettify %}
+
+If the diagnostic is reported for an assignment, and the assignment isn't
+needed, then remove the assignment:
+
+{% prettify dart %}
+class C {
+  int f = -1;
+
+  void m(int x) {
+  }
+}
+{% endprettify %}
+
+If the assignment is needed, but should be based on a different condition,
+then rewrite the code to use `=` and the different condition:
+
+{% prettify dart %}
+class C {
+  int f = -1;
+
+  void m(int x) {
+    if (f < 0) {
+      f = x;
+    }
+  }
+}
+{% endprettify %}
+
+### default_list_constructor
+
+_Calling the default 'List' constructor causes an error._
+
+#### Description
+
+The analyzer produces this diagnostic when it finds a use of the default
+constructor for the class `List` in code that has opted in to null safety.
+
+#### Example
+
+Assuming the following code is opted in to null safety, it produces this
+diagnostic because it uses the default `List` constructor:
+
+{% prettify dart %}
+var l = [!List<int>!]();
+{% endprettify %}
+
+#### Common fixes
+
+If no initial size is provided, then convert the code to use a list
+literal:
+
+{% prettify dart %}
+var l = <int>[];
+{% endprettify %}
+
+If an initial size needs to be provided and there is a single reasonable
+initial value for the elements, then use `List.filled`:
+
+{% prettify dart %}
+var l = List.filled(3, 0);
+{% endprettify %}
+
+If an initial size needs to be provided but each element needs to be
+computed, then use `List.generate`:
+
+{% prettify dart %}
+var l = List.generate(3, (i) => i);
+{% endprettify %}
+
+### definitely_unassigned_late_local_variable
+
+_The late local variable '{0}' is definitely unassigned at this point._
+
+#### Description
+
+The analyzer produces this diagnostic when
+[definite assignment](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md)
+analysis shows that a local variable that's marked as `late` is read before
+being assigned.
+
+#### Example
+
+The following code produces this diagnostic because `x` was not assigned a
+value before being read:
+
+{% prettify dart %}
+void f(bool b) {
+  late int x;
+  print([!x!]);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Assign a value to the variable before reading from it:
+
+{% prettify dart %}
+void f(bool b) {
+  late int x;
+  x = b ? 1 : 0;
+  print(x);
+}
+{% endprettify %}
+
 ### deprecated_member_use
 
 _'{0}' is deprecated and shouldn't be used._
@@ -1468,6 +1765,56 @@
 of which entry to remove might affect the order in which keys and values
 are returned by an iterator.
 
+### export_legacy_symbol
+
+_The symbol '{0}' is defined in a legacy library, and can't be re-exported from
+a non-nullable by default library._
+
+#### Description
+
+The analyzer produces this diagnostic when a library that was opted in to
+null safety exports another library, and the exported library is opted out
+of null safety.
+
+#### Example
+
+Given a library that is opted out of null safety:
+
+{% prettify dart %}
+// @dart = 2.8
+String s;
+{% endprettify %}
+
+The following code produces this diagnostic because it's exporting symbols
+from an opted-out library:
+
+{% prettify dart %}
+export [!'optedOut.dart'!];
+
+class C {}
+{% endprettify %}
+
+#### Common fixes
+
+If you're able to do so, migrate the exported library so that it doesn't
+need to opt out:
+
+{% prettify dart %}
+String? s;
+{% endprettify %}
+
+If you can't migrate the library, then remove the export:
+
+{% prettify dart %}
+class C {}
+{% endprettify %}
+
+If the exported library (the one that is opted out) itself exports an
+opted-in library, then it's valid for your library to indirectly export the
+symbols from the opted-in library. You can do so by adding a hide
+combinator to the export directive in your library that hides all of the
+names declared in the opted-out library.
+
 ### expression_in_map
 
 _Expressions can't be used in a map literal._
@@ -2749,6 +3096,48 @@
 var x;
 {% endprettify %}
 
+### invalid_null_aware_operator
+
+_The target expression can't be null, so the null-aware operator '{0}' can't be
+used._
+
+#### Description
+
+The analyzer produces this diagnostic when a null-aware operator (`?.`,
+`?..`, `?[`, `?..[`, or `...?`) is used on a target that's known to be
+non-nullable.
+
+#### Example
+
+The following code produces this diagnostic because `s` can't be `null`:
+
+{% prettify dart %}
+int? getLength(String s) {
+  return s[!?.!]length;
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `a` can't be `null`:
+
+{% prettify dart %}
+var a = [];
+var b = [[!...?!]a];
+{% endprettify %}
+
+#### Common fixes
+
+Replace the null-aware operator with a non-null-aware equivalent, such as
+replacing '?.' with  '.':
+
+{% prettify dart %}
+int getLength(String s) {
+  return s.length;
+}
+{% endprettify %}
+
+(Note that the return type was also changed to be non-nullable, which might
+not be appropriate in some cases.)
+
 ### invalid_override
 
 _'{1}.{0}' ('{2}') isn't a valid override of '{3}.{0}' ('{4}')._
@@ -2897,6 +3286,37 @@
 }
 {% endprettify %}
 
+### invalid_use_of_null_value
+
+_An expression whose value is always 'null' can't be dereferenced._
+
+#### Description
+
+The analyzer produces this diagnostic when an expression whose value will
+always be `null` is dererenced.
+
+#### Example
+
+The following code produces this diagnostic because `x` will always be
+`null`:
+
+{% prettify dart %}
+int f(Null x) {
+  return [!x!].length;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the value is allowed to be something other than `null`, then change the
+type of the expression:
+
+{% prettify dart %}
+int f(String? x) {
+  return x!.length;
+}
+{% endprettify %}
+
 ### invalid_visibility_annotation
 
 _The member '{0}' is annotated with '{1}', but this annotation is only
@@ -3205,6 +3625,59 @@
 var m = <String, int>{'a' : 2};
 {% endprettify %}
 
+### missing_default_value_for_parameter
+
+_The parameter '{0}' can't have a value of 'null' because of its type, and no
+non-null default value is provided._
+
+#### Description
+
+The analyzer produces this diagnostic when an optional parameter, whether
+positional or named, has a <a href=”#potentially-non-nullable”>potentially
+non-nullable</a> type and doesn't specify a default value. Optional
+parameters that have no explicit default value have an implicit default
+value of `null`. If the type of the parameter doesn't allow the parameter
+to have a value of `null`, then the implicit default value isn't valid.
+
+#### Example
+
+The following code produces this diagnostic because `x` can't be `null`,
+and no non-`null` default value is specified:
+
+{% prettify dart %}
+void f([int [!x!]]) {}
+{% endprettify %}
+
+As does this:
+
+{% prettify dart %}
+void g({int [!x!]}) {}
+{% endprettify %}
+
+#### Common fixes
+
+If you want to use `null` to indicate that no value was provided, then you
+need to make the type nullable:
+
+{% prettify dart %}
+void f([int? x]) {}
+void g({int? x}) {}
+{% endprettify %}
+
+If the parameter can't be null, then either provide a default value:
+
+{% prettify dart %}
+void f([int x = 1]) {}
+void g({int x = 2}) {}
+{% endprettify %}
+
+or make the parameter a required parameter:
+
+{% prettify dart %}
+void f(int x) {}
+void g({required int x}) {}
+{% endprettify %}
+
 ### missing_enum_constant_in_switch
 
 _Missing case clause for '{0}'._
@@ -3267,6 +3740,38 @@
 }
 {% endprettify %}
 
+### missing_required_argument
+
+_The named parameter '{0}' is required, but there's no corresponding argument._
+
+#### Description
+
+The analyzer produces this diagnostic when an invocation of a function is
+missing a required named parameter.
+
+#### Example
+
+The following code produces this diagnostic because the invocation of `f`
+doesn't include a value for the required named parameter `end`:
+
+{% prettify dart %}
+void f(int start, {required int end}) {}
+void g() {
+  [!f!](3);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Add a named argument corresponding to the missing required parameter:
+
+{% prettify dart %}
+void f(int start, {required int end}) {}
+void g() {
+  f(3, end: 5);
+}
+{% endprettify %}
+
 ### missing_required_param
 
 _The parameter '{0}' is required._
@@ -4159,6 +4664,122 @@
 }
 {% endprettify %}
 
+### not_assigned_potentially_non_nullable_local_variable
+
+_The non-nullable local variable '{0}' must be assigned before it can be used._
+
+#### Description
+
+The analyzer produces this diagnostic when a local variable is referenced
+and has all these characteristics:
+- Has a type that's <a href=”#potentially-non-nullable”>potentially
+  non-nullable</a>.
+- Doesn't have an initializer.
+- Isn't marked as `late`.
+- The analyzer can't prove that the local variable will be assigned before
+  the reference based on the specification of
+  [definite assignment](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md).
+
+#### Example
+
+The following code produces this diagnostic because `x` can't have a value
+of `null`, but is referenced before a value was assigned to it:
+
+{% prettify dart %}
+String f() {
+  int x;
+  return [!x!].toString();
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the assignment to `x`
+might not be executed, so it might have a value of `null`:
+
+{% prettify dart %}
+int g(bool b) {
+  int x;
+  if (b) {
+    x = 1;
+  }
+  return [!x!] * 2;
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the analyzer can't
+prove, based on definite assignment analysis, that `x` won't be referenced
+without having a value assigned to it:
+
+{% prettify dart %}
+int h(bool b) {
+  int x;
+  if (b) {
+    x = 1;
+  }
+  if (b) {
+    return [!x!] * 2;
+  }
+  return 0;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If `null` is a valid value, then make the variable nullable:
+
+{% prettify dart %}
+String f() {
+  int? x;
+  return x!.toString();
+}
+{% endprettify %}
+
+If `null` isn’t a valid value, and there's a reasonable default value, then
+add an initializer:
+
+{% prettify dart %}
+int g(bool b) {
+  int x = 2;
+  if (b) {
+    x = 1;
+  }
+  return x * 2;
+}
+{% endprettify %}
+
+Otherwise, ensure that a value was assigned on every possible code path
+before the value is accessed:
+
+{% prettify dart %}
+int g(bool b) {
+  int x;
+  if (b) {
+    x = 1;
+  } else {
+    x = 2;
+  }
+  return x * 2;
+}
+{% endprettify %}
+
+You can also mark the variable as `late`, which removes the diagnostic, but
+if the variable isn't assigned a value before it's accessed, then it
+results in an exception being thrown at runtime. This approach should only
+be used if you're sure that the variable will always be assigned, even
+though the analyzer can't prove it based on definite assignment analysis.
+
+{% prettify dart %}
+int h(bool b) {
+  late int x;
+  if (b) {
+    x = 1;
+  }
+  if (b) {
+    return x * 2;
+  }
+  return 0;
+}
+{% endprettify %}
+
 ### not_a_type
 
 _{0} isn't a type._
@@ -4214,6 +4835,138 @@
 }
 {% endprettify %}
 
+### not_initialized_non_nullable_instance_field
+
+_Non-nullable instance field '{0}' must be initialized._
+
+_Non-nullable instance field '{0}' must be initialized._
+
+#### Description
+
+The analyzer produces this diagnostic when a field is declared and has all
+these characteristics:
+- Has a type that's <a href=”#potentially-non-nullable”>potentially
+  non-nullable</a>
+- Doesn't have an initializer
+- Isn't marked as `late`
+
+#### Example
+
+The following code produces this diagnostic because `x` is implicitly
+initialized to `null` when it isn't allowed to be `null`:
+
+{% prettify dart %}
+class C {
+  int [!x!];
+}
+{% endprettify %}
+
+Similarly, the following code produces this diagnostic because `x` is
+implicitly initialized to `null`, when it isn't allowed to be `null`, by
+one of the constructors, even though it's initialized by other
+constructors:
+
+{% prettify dart %}
+class C {
+  int x;
+
+  C(this.x);
+
+  [!C!].n();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If there's a reasonable default value for the field that’s the same for all
+instances, then add an initializer expression:
+
+{% prettify dart %}
+class C {
+  int x = 0;
+}
+{% endprettify %}
+
+If the value of the field should be provided when an instance is created,
+then add a constructor that sets the value of the field or update an
+existing constructor:
+
+{% prettify dart %}
+class C {
+  int x;
+
+  C(this.x);
+}
+{% endprettify %}
+
+You can also mark the field as `late`, which removes the diagnostic, but if
+the field isn't assigned a value before it's accessed, then it results in
+an exception being thrown at runtime. This approach should only be used if
+you're sure that the field will always be assigned before it's referenced.
+
+{% prettify dart %}
+class C {
+  late int x;
+}
+{% endprettify %}
+
+### not_initialized_non_nullable_variable
+
+_The non-nullable variable '{0}' must be initialized._
+
+#### Description
+
+The analyzer produces this diagnostic when a static field or top-level
+variable has a type that's non-nullable and doesn't have an initializer.
+Fields and variables that don't have an initializer are normally
+initialized to `null`, but the type of the field or variable doesn't allow
+it to be set to `null`, so an explicit initializer must be provided.
+
+#### Example
+
+The following code produces this diagnostic because the field `f` can't be
+initialized to `null`:
+
+{% prettify dart %}
+class C {
+  static int [!f!];
+}
+{% endprettify %}
+
+Similarly, the following code produces this diagnostic because the
+top-level variable `v` can't be initialized to `null`:
+
+{% prettify dart %}
+int [!v!];
+{% endprettify %}
+
+#### Common fixes
+
+If the field or variable can't be initialized to `null`, then add an
+initializer that sets it to a non-null value:
+
+{% prettify dart %}
+class C {
+  static int f = 0;
+}
+{% endprettify %}
+
+If the field or variable should be initialized to `null`, then change the
+type to be nullable:
+
+{% prettify dart %}
+int? v;
+{% endprettify %}
+
+If the field or variable can't be initialized in the declaration but will
+always be initialized before it's referenced, then mark it as being `late`:
+
+{% prettify dart %}
+class C {
+  static late int f;
+}
+{% endprettify %}
+
 ### not_iterable_spread
 
 _Spread elements in list or set literals must implement 'Iterable'._
@@ -4311,6 +5064,189 @@
 var x;
 {% endprettify %}
 
+### nullable_type_in_catch_clause
+
+_A potentially nullable type can't be used in an 'on' clause because it isn't
+valid to throw a nullable expression._
+
+#### Description
+
+The analyzer produces this diagnostic when the type following `on` in a
+catch clause is a nullable type. It isn't valid to specify a nullable type
+because it isn't possible to catch `null` (because it's a runtime error to
+throw `null`).
+
+#### Example
+
+The following code produces this diagnostic because the exception type is
+specified to allow `null` when `null` can't be thrown:
+
+{% prettify dart %}
+void f() {
+  try {
+    // ...
+  } on [!FormatException?!] {
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the question mark from the type:
+
+{% prettify dart %}
+void f() {
+  try {
+    // ...
+  } on FormatException {
+  }
+}
+{% endprettify %}
+
+### nullable_type_in_extends_clause
+
+_A class can't extend a nullable type._
+
+#### Description
+
+The analyzer produces this diagnostic when a class declaration uses an
+extends clause to specify a superclass, and the superclass is followed by a
+`?`.
+
+It isn't valid to specify a nullable superclass because doing so would have
+no meaning; it wouldn't change either the interface or implementation being
+inherited by the class containing the extends clause.
+
+Note, however, that it _is_ valid to use a nullable type as a type argument
+to the superclass, such as `class A extends B<C?> {}`.
+
+#### Example
+
+The following code produces this diagnostic because `A?` is a nullable
+type, and nullable types can't be used in an extends clause:
+
+{% prettify dart %}
+class A {}
+class B extends [!A?!] {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the question mark from the type:
+
+{% prettify dart %}
+class A {}
+class B extends A {}
+{% endprettify %}
+
+### nullable_type_in_implements_clause
+
+_A class or mixin can't implement a nullable type._
+
+#### Description
+
+The analyzer produces this diagnostic when a class or mixin declaration has
+an implements clause, and an interface is followed by a `?`.
+
+It isn't valid to specify a nullable interface because doing so would have
+no meaning; it wouldn't change the interface being inherited by the class
+containing the implements clause.
+
+Note, however, that it _is_ valid to use a nullable type as a type argument
+to the interface, such as `class A implements B<C?> {}`.
+
+
+#### Example
+
+The following code produces this diagnostic because `A?` is a nullable
+type, and nullable types can't be used in an implements clause:
+
+{% prettify dart %}
+class A {}
+class B implements [!A?!] {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the question mark from the type:
+
+{% prettify dart %}
+class A {}
+class B implements A {}
+{% endprettify %}
+
+### nullable_type_in_on_clause
+
+_A mixin can't have a nullable type as a superclass constraint._
+
+#### Description
+
+The analyzer produces this diagnostic when a mixin declaration uses an on
+clause to specify a superclass constraint, and the class that's specified
+is followed by a `?`.
+
+It isn't valid to specify a nullable superclass constraint because doing so
+would have no meaning; it wouldn't change the interface being depended on
+by the mixin containing the on clause.
+
+Note, however, that it _is_ valid to use a nullable type as a type argument
+to the superclass constraint, such as `mixin A on B<C?> {}`.
+
+
+#### Example
+
+The following code produces this diagnostic because `A?` is a nullable type
+and nullable types can't be used in an on clause:
+
+{% prettify dart %}
+class C {}
+mixin M on [!C?!] {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the question mark from the type:
+
+{% prettify dart %}
+class C {}
+mixin M on C {}
+{% endprettify %}
+
+### nullable_type_in_with_clause
+
+_A class or mixin can't mix in a nullable type._
+
+#### Description
+
+The analyzer produces this diagnostic when a class or mixin declaration has
+a with clause, and a mixin is followed by a `?`.
+
+It isn't valid to specify a nullable mixin because doing so would have no
+meaning; it wouldn't change either the interface or implementation being
+inherited by the class containing the with clause.
+
+Note, however, that it _is_ valid to use a nullable type as a type argument
+to the mixin, such as `class A with B<C?> {}`.
+
+#### Example
+
+The following code produces this diagnostic because `A?` is a nullable
+type, and nullable types can't be used in a with clause:
+
+{% prettify dart %}
+mixin M {}
+class C with [!M?!] {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the question mark from the type:
+
+{% prettify dart %}
+mixin M {}
+class C with M {}
+{% endprettify %}
+
 ### override_on_non_overriding_member
 
 _The field doesn't override an inherited getter or setter._
@@ -4471,7 +5407,7 @@
 
 ### redirect_to_invalid_return_type
 
-_The return type '{0}' of the redirected constructor isn't assignable to '{1}'._
+_The return type '{0}' of the redirected constructor isn't a subtype of '{1}'._
 
 #### Description
 
@@ -5295,6 +6231,37 @@
 
 Rewrite the code to not use `super`.
 
+### throw_of_invalid_type
+
+_The type '{0}' of the thrown expression must be assignable to 'Object'._
+
+#### Description
+
+The analyzer produces this diagnostic when the type of the expression in a
+throw expression is not assignable to `Object`. It’s not valid to throw
+`null`, so it isn't valid to use an expression that might evaluate to
+`null`.
+
+#### Example
+
+The following code produces this diagnostic because `s` might be `null`:
+
+{% prettify dart %}
+void f(String? s) {
+  throw [!s!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Add an explicit null check to the expression:
+
+{% prettify dart %}
+void f(String? s) {
+  throw s!;
+}
+{% endprettify %}
+
 ### type_argument_not_matching_bounds
 
 _'{0}' doesn't extend '{1}'._
@@ -5359,6 +6326,67 @@
 }
 {% endprettify %}
 
+### unchecked_use_of_nullable_value
+
+_An expression whose value can be 'null' must be null-checked before it can be
+dereferenced._
+
+#### Description
+
+The analyzer produces this diagnostic when an expression whose type is
+<a href=”#potentially-non-nullable”>potentially non-nullable</a> is
+dereferenced without first verifying that the value isn't `null`.
+
+#### Example
+
+The following code produces this diagnostic because `s` can be `null` at
+the point where it's referenced:
+
+{% prettify dart %}
+void f(String? s) {
+  if ([!s!].length > 3) {
+    // ...
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the value really can be `null`, then add a test to ensure that members
+are only accessed when the value isn't `null`:
+
+{% prettify dart %}
+void f(String? s) {
+  if (s != null && s.length > 3) {
+    // ...
+  }
+}
+{% endprettify %}
+
+If the expression is a variable and the value should never be `null`, then
+change the type of the variable to be non-nullable:
+
+{% prettify dart %}
+void f(String s) {
+  if (s.length > 3) {
+    // ...
+  }
+}
+{% endprettify %}
+
+If you believe that the value of the expression should never be `null`, but
+you can't change the type of the variable, and you're willing to risk
+having an exception thrown at runtime if you're wrong, then you can assert
+that the value isn't null:
+
+{% prettify dart %}
+void f(String? s) {
+  if (s!.length > 3) {
+    // ...
+  }
+}
+{% endprettify %}
+
 ### undefined_annotation
 
 _Undefined name '{0}' used as an annotation._
@@ -6212,6 +7240,93 @@
 }
 {% endprettify %}
 
+### unnecessary_non_null_assertion
+
+_The '!' will have no effect because the target expression can't be null._
+
+#### Description
+
+The analyzer produces this diagnostic when the operand of the `!` operator
+can't be `null`.
+
+#### Example
+
+The following code produces this diagnostic because `x` can't be `null`:
+
+{% prettify dart %}
+int f(int x) {
+  return x[!!!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the null check operator (`!`):
+
+{% prettify dart %}
+int f(int x) {
+  return x;
+}
+{% endprettify %}
+
+### unnecessary_null_comparison
+
+_The operand can't be null, so the condition is always false._
+
+_The operand can't be null, so the condition is always true._
+
+#### Description
+
+The analyzer produces this diagnostic when it finds an equality comparison
+(either `==` or `!=`) with one operand of `null` and the other operand
+can't be `null`. Such comparisons are always either `true` or `false`, so
+they serve no purpose.
+
+#### Example
+
+The following code produces this diagnostic because `x` can never be
+`null`, so the comparison always evaluates to `true`:
+
+{% prettify dart %}
+void f(int x) {
+  if (x [!!= null!]) {
+    print(x);
+  }
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `x` can never be
+`null`, so the comparison always evaluates to `false`:
+
+{% prettify dart %}
+void f(int x) {
+  if (x [!== null!]) {
+    throw ArgumentError("x can't be null");
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the other operand should be able to be `null`, then change the type of
+the operand:
+
+{% prettify dart %}
+void f(int? x) {
+  if (x != null) {
+    print(x);
+  }
+}
+{% endprettify %}
+
+If the other operand really can't be `null`, then remove the condition:
+
+{% prettify dart %}
+void f(int x) {
+  print(x);
+}
+{% endprettify %}
+
 ### unqualified_reference_to_static_member_of_extended_type
 
 _Static members from the extended type or one of its superclasses must be
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index dbb0f84..61ea2d7 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -429,13 +429,23 @@
     }
   }
   ```
-''');
 
-//### Potentially non-nullable
-//
-//A type is _potentially non-nullable_ if it's either explicitly non-nullable or
-//if it's a type parameter. The latter case is included because the actual runtime
-//type might be non-nullable.
+### Potentially non-nullable
+
+A type is _potentially non-nullable_ if it's either explicitly non-nullable or
+if it's a type parameter.
+
+A type is explicitly non-nullable if it is a type name that is not followed by a
+question mark. Note that there are a few types that are always nullable, such as
+`Null` and `dynamic`, and that `FutureOr` is only non-nullable if it is not
+followed by a question mark _and_ the type argument is non-nullable (such as
+`FutureOr<String>`).
+
+Type parameters are potentially non-nullable because the actual runtime type
+(the type specified as a type argument) might be non-nullable. For example,
+given a declaration of `class C<T> {}`, the type `C` could be used with a
+non-nullable type argument as in `C<int>`.
+''');
   }
 
   /// Write the header of the file.
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index 144b1a3..7e92f7d 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -11,6 +11,8 @@
 import 'package:_fe_analyzer_shared/src/parser/parser.dart';
 import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart';
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:pub_semver/pub_semver.dart';
 
 /// "Mini AST" representation of a declaration which can accept annotations.
 class AnnotatedNode {
@@ -615,16 +617,32 @@
   void reportErrorIfNullableType(Token questionMark) {
     if (questionMark != null) {
       assert(optional('?', questionMark));
+      var feature = ExperimentalFeatures.non_nullable;
       handleRecoverableError(
-          templateExperimentNotEnabled.withArguments('non-nullable'),
-          questionMark,
-          questionMark);
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        questionMark,
+        questionMark,
+      );
     }
   }
 
   void reportNonNullAssertExpressionNotEnabled(Token bang) {
+    var feature = ExperimentalFeatures.non_nullable;
     handleRecoverableError(
-        templateExperimentNotEnabled.withArguments('non-nullable'), bang, bang);
+      templateExperimentNotEnabled.withArguments(
+        feature.enableString,
+        _versionAsString(ExperimentStatus.currentVersion),
+      ),
+      bang,
+      bang,
+    );
+  }
+
+  static String _versionAsString(Version version) {
+    return '${version.major}.${version.minor}.${version.patch}';
   }
 }
 
diff --git a/pkg/analyzer_cli/lib/src/context_cache.dart b/pkg/analyzer_cli/lib/src/context_cache.dart
index b3af37d..82e7f1e 100644
--- a/pkg/analyzer_cli/lib/src/context_cache.dart
+++ b/pkg/analyzer_cli/lib/src/context_cache.dart
@@ -106,12 +106,8 @@
             verbosePrint: clOptions.verbose ? verbosePrint : null)
         as AnalysisOptionsImpl;
 
-    contextOptions.trackCacheDependencies = false;
-    contextOptions.disableCacheFlushing = clOptions.disableCacheFlushing;
     _buildContextFeatureSet(contextOptions);
     contextOptions.hint = !clOptions.disableHints;
-    contextOptions.generateImplicitErrors = clOptions.showPackageWarnings;
-    contextOptions.generateSdkErrors = clOptions.showSdkWarnings;
     contextOptions.useFastaParser = clOptions.useFastaParser;
     return contextOptions;
   }
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index cf57798..295f5cf 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -1,6 +1,8 @@
 name: analyzer_cli
 description: Command line interface for the Dart Analyzer.
 publish_to: none
+environment:
+  sdk: "^2.7.0"
 dependencies:
   analyzer: ^0.37.0
   args: '>=0.13.0 <2.0.0'
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 592f09a..219b110 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -92,6 +92,9 @@
   bool get hasPublishedDocs => false;
 
   @override
+  bool get isIgnorable => true;
+
+  @override
   bool get isUnresolvedIdentifier => false;
 
   @override
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 4e80d11..6b93571 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -96,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 Object 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].
@@ -231,7 +232,7 @@
   /// Create a [CompletionTarget] holding the given [containingNode] and
   /// [entity].
   CompletionTarget._(this.unit, this.offset, AstNode containingNode,
-      Object entity, this.isCommentText)
+      SyntacticEntity entity, this.isCommentText)
       : containingNode = containingNode,
         entity = entity,
         argIndex = _computeArgIndex(containingNode, entity),
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 4ce976b..d138827 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -80,6 +81,9 @@
   /// The suggested completion kind.
   CompletionSuggestionKind suggestKind = CompletionSuggestionKind.INVOCATION;
 
+  /// An representation of the location at which completion was requested.
+  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;
@@ -226,9 +230,9 @@
 }
 
 class _OpTypeAstVisitor extends GeneralizingAstVisitor<void> {
-  /// The entity (AstNode or Token) which will be replaced or displaced by the
+  /// The entity (AstNode or Token) that will be replaced or displaced by the
   /// added text.
-  final Object entity;
+  final SyntacticEntity entity;
 
   /// The offset within the source at which the completion is requested.
   final int offset;
@@ -241,9 +245,16 @@
   @override
   void visitAnnotation(Annotation node) {
     if (identical(entity, node.name)) {
+      optype.completionLocation = 'Annotation_name';
       optype.includeTypeNameSuggestions = true;
       optype.includeReturnValueSuggestions = true;
     } else if (identical(entity, node.constructorName)) {
+      // There is no location for the constructor name because only named
+      // constructors are valid.
+      // TODO(brianwilkerson) The following looks wrong. I think we want to set
+      //  includeConstructorSuggestions = true, but not type names or return
+      //  values. On the other hand, I can't construct a test case that reaches
+      //  this point, so perhaps we should just remove this branch.
       optype.includeTypeNameSuggestions = true;
       optype.includeReturnValueSuggestions = true;
       optype.isPrefixed = true;
@@ -282,6 +293,18 @@
           optype.includeNamedArgumentSuggestions = true;
         }
       }
+    } else if (parent is SuperConstructorInvocation) {
+      parameters = parent.staticElement?.parameters;
+    } else if (parent is RedirectingConstructorInvocation) {
+      parameters = parent.staticElement?.parameters;
+    } else if (parent is Annotation) {
+      var constructor = parent.element;
+      if (constructor is ConstructorElement) {
+        parameters = constructor.parameters;
+      } else if (constructor == null) {
+        // If unresolved, then include named arguments
+        optype.includeNamedArgumentSuggestions = true;
+      }
     }
     // Based upon the insertion location and declared parameters
     // determine whether only named arguments should be suggested
@@ -303,11 +326,15 @@
       if (0 <= index && index < parameters.length) {
         var param = parameters[index];
         if (param?.isNamed == true) {
+          var context = _argumentListContext(node);
+          optype.completionLocation = 'ArgumentList_${context}_named';
           optype.includeNamedArgumentSuggestions = true;
           return;
         }
       }
     }
+    var context = _argumentListContext(node);
+    optype.completionLocation = 'ArgumentList_${context}_unnamed';
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
   }
@@ -315,6 +342,7 @@
   @override
   void visitAsExpression(AsExpression node) {
     if (identical(entity, node.type)) {
+      optype.completionLocation = 'AsExpression_type';
       optype.includeTypeNameSuggestions = true;
       optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
         var staticType = node.expression.staticType;
@@ -333,22 +361,33 @@
   @override
   void visitAssertInitializer(AssertInitializer node) {
     if (identical(entity, node.condition)) {
+      optype.completionLocation = 'AssertInitializer_condition';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
+    } else if (identical(entity, node.message)) {
+      optype.completionLocation = 'AssertInitializer_message';
+      // TODO(brianwilkerson) Consider including return value suggestions and
+      //  type name suggestions here.
     }
   }
 
   @override
   void visitAssertStatement(AssertStatement node) {
     if (identical(entity, node.condition)) {
+      optype.completionLocation = 'AssertStatement_condition';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
+    } else if (identical(entity, node.message)) {
+      optype.completionLocation = 'AssertStatement_message';
+      // TODO(brianwilkerson) Consider including return value suggestions and
+      //  type name suggestions here.
     }
   }
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
     if (identical(entity, node.rightHandSide)) {
+      optype.completionLocation = 'AssignmentExpression_rightHandSide';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -357,6 +396,7 @@
   @override
   void visitAwaitExpression(AwaitExpression node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'AwaitExpression_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -365,6 +405,8 @@
   @override
   void visitBinaryExpression(BinaryExpression node) {
     if (identical(entity, node.rightOperand)) {
+      optype.completionLocation =
+          'BinaryExpression_${node.operator}_rightOperand';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -372,6 +414,7 @@
 
   @override
   void visitBlock(Block node) {
+    optype.completionLocation = 'Block_statement';
     var prevStmt = OpType.getPreviousStatement(node, entity);
     if (prevStmt is TryStatement) {
       if (prevStmt.catchClauses.isEmpty && prevStmt.finallyBlock == null) {
@@ -393,6 +436,7 @@
   @override
   void visitCascadeExpression(CascadeExpression node) {
     if (node.cascadeSections.contains(entity)) {
+      optype.completionLocation = 'CascadeExpression_cascadeSection';
       optype.includeReturnValueSuggestions = true;
       optype.includeVoidReturnSuggestions = true;
       optype.isPrefixed = true;
@@ -402,6 +446,7 @@
   @override
   void visitCatchClause(CatchClause node) {
     if (identical(entity, node.exceptionType)) {
+      optype.completionLocation = 'CatchClause_exceptionType';
       optype.includeTypeNameSuggestions = true;
     }
   }
@@ -410,6 +455,7 @@
   void visitClassDeclaration(ClassDeclaration node) {
     // Make suggestions in the body of the class declaration
     if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.completionLocation = 'ClassDeclaration_member';
       optype.includeTypeNameSuggestions = true;
     }
   }
@@ -418,7 +464,16 @@
   void visitClassMember(ClassMember node) {}
 
   @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    if (identical(entity, node.superclass)) {
+      optype.completionLocation = 'ClassTypeAlias_superclass';
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
   void visitCommentReference(CommentReference node) {
+    optype.completionLocation = 'CommentReference_identifier';
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
     optype.includeVoidReturnSuggestions = true;
@@ -428,19 +483,54 @@
   @override
   void visitCompilationUnit(CompilationUnit node) {
     if (entity is! CommentToken) {
+      int declarationStart() {
+        var declarations = node.declarations;
+        if (declarations.isNotEmpty) {
+          return declarations[0].offset;
+        }
+        var directives = node.directives;
+        if (directives.isNotEmpty) {
+          return directives.last.end;
+        }
+        return node.end;
+      }
+
+      if (entity != null) {
+        if (entity.offset <= declarationStart()) {
+          optype.completionLocation = 'CompilationUnit_declaration';
+        } else {
+          optype.completionLocation = 'CompilationUnit_declaration';
+        }
+      }
       optype.includeTypeNameSuggestions = true;
     }
   }
 
   @override
   void visitConditionalExpression(ConditionalExpression node) {
+    if (identical(entity, node.thenExpression)) {
+      optype.completionLocation = 'ConditionalExpression_thenExpression';
+    } else if (identical(entity, node.elseExpression)) {
+      optype.completionLocation = 'ConditionalExpression_elseExpression';
+    }
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
   }
 
   @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    if (identical(entity, node.returnType)) {
+      optype.completionLocation = 'ConstructorDeclaration_returnType';
+      optype.includeTypeNameSuggestions = true;
+    } else if (node.initializers.contains(entity)) {
+      optype.completionLocation = 'ConstructorDeclaration_initializer';
+    }
+  }
+
+  @override
   void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'ConstructorFieldInitializer_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -473,6 +563,7 @@
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     if (identical(entity, node.defaultValue)) {
+      optype.completionLocation = 'DefaultFormalParameter_defaultValue';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -480,7 +571,10 @@
 
   @override
   void visitDoStatement(DoStatement node) {
-    if (identical(entity, node.condition)) {
+    if (identical(entity, node.body)) {
+      optype.completionLocation = 'DoStatement_body';
+    } else if (identical(entity, node.condition)) {
+      optype.completionLocation = 'DoStatement_condition';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -503,6 +597,7 @@
   @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'ExpressionFunctionBody_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -510,6 +605,7 @@
 
   @override
   void visitExpressionStatement(ExpressionStatement node) {
+    optype.completionLocation = 'ExpressionStatement_expression';
     // Given f[], the parser drops the [] from the expression statement
     // but the [] token is the CompletionTarget entity
     if (entity is Token) {
@@ -528,6 +624,7 @@
   @override
   void visitExtendsClause(ExtendsClause node) {
     if (identical(entity, node.superclass)) {
+      optype.completionLocation = 'ExtendsClause_superclass';
       optype.includeTypeNameSuggestions = true;
       optype.typeNameSuggestionsFilter = _nonMixinClasses;
     }
@@ -535,8 +632,13 @@
 
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
-    // Make suggestions in the body of the extension declaration
-    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+    if (identical(entity, node.extendedType)) {
+      optype.completionLocation = 'ExtensionDeclaration_extendedType';
+      optype.includeTypeNameSuggestions = true;
+    } else if (node.members.contains(entity) ||
+        identical(entity, node.rightBracket)) {
+      // Make suggestions in the body of the extension declaration
+      optype.completionLocation = 'ExtensionDeclaration_member';
       optype.includeTypeNameSuggestions = true;
     }
   }
@@ -546,6 +648,9 @@
     if (offset <= node.semicolon.offset) {
       optype.includeVarNameSuggestions = true;
     }
+    if (offset <= node.fields.offset) {
+      optype.includeTypeNameSuggestions = true;
+    }
   }
 
   @override
@@ -560,24 +665,38 @@
 
   @override
   void visitForEachParts(ForEachParts node) {
-    if (node is ForEachPartsWithIdentifier &&
-        identical(entity, node.identifier)) {
-      optype.includeTypeNameSuggestions = true;
-    }
-    if (node is ForEachPartsWithDeclaration &&
-        identical(entity, node.loopVariable)) {
-      optype.includeTypeNameSuggestions = true;
-    }
     if (identical(entity, node.inKeyword) && offset <= node.inKeyword.offset) {
       if (!(node is ForEachPartsWithIdentifier && node.identifier != null ||
           node is ForEachPartsWithDeclaration && node.loopVariable != null)) {
         optype.includeTypeNameSuggestions = true;
       }
     }
-    if (identical(entity, node.iterable)) {
+  }
+
+  @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    if (identical(entity, node.loopVariable)) {
+      optype.completionLocation = 'ForEachPartsWithDeclaration_loopVariable';
+      optype.includeTypeNameSuggestions = true;
+    } else if (identical(entity, node.iterable)) {
+      optype.completionLocation = 'ForEachPartsWithDeclaration_iterable';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
+    visitForEachParts(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    if (identical(entity, node.identifier)) {
+      optype.completionLocation = 'ForEachPartsWithIdentifier_identifier';
+      optype.includeTypeNameSuggestions = true;
+    } else if (identical(entity, node.iterable)) {
+      optype.completionLocation = 'ForEachPartsWithIdentifier_iterable';
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+    visitForEachParts(node);
   }
 
   @override
@@ -588,9 +707,8 @@
     // but for any practical use we need only types.
     if (entity == node.forLoopParts) {
       optype.includeTypeNameSuggestions = true;
-    }
-
-    if (entity == node.body) {
+    } else if (entity == node.body) {
+      optype.completionLocation = 'ForElement_body';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -598,7 +716,8 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    dynamic entity = this.entity;
+    optype.completionLocation = 'FormalParameterList_parameter';
+    var entity = this.entity;
     if (entity is Token) {
       var previous = node.findPrevious(entity);
       if (previous != null) {
@@ -646,13 +765,14 @@
       //                    ^
       optype.includeVarNameSuggestions = true;
     } else {
-      // for (; ^) {}
       if (entity == node.condition) {
+        // for (; ^) {}
+        optype.completionLocation = 'ForParts_condition';
         optype.includeTypeNameSuggestions = true;
         optype.includeReturnValueSuggestions = true;
-      }
-      // for (; ; ^) {}
-      if (node.updaters.contains(entity)) {
+      } else if (node.updaters.contains(entity)) {
+        // for (; ; ^) {}
+        optype.completionLocation = 'ForParts_updater';
         optype.includeTypeNameSuggestions = true;
         optype.includeReturnValueSuggestions = true;
         optype.includeVoidReturnSuggestions = true;
@@ -668,6 +788,8 @@
     // but for any practical use we need only types.
     if (entity == node.forLoopParts) {
       optype.includeTypeNameSuggestions = true;
+    } else if (entity == node.body) {
+      optype.completionLocation = 'ForElement_body';
     }
   }
 
@@ -694,12 +816,32 @@
   }
 
   @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    if (entity == node.functionType) {
+      optype.completionLocation = 'GenericTypeAlias_functionType';
+    }
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    if (node.hiddenNames.contains(entity)) {
+      optype.completionLocation = 'HideCombinator_hiddenName';
+    }
+  }
+
+  @override
   void visitIfElement(IfElement node) {
     if (identical(entity, node.condition)) {
+      optype.completionLocation = 'IfElement_condition';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
-    } else if (identical(entity, node.thenElement) ||
-        identical(entity, node.elseElement)) {
+    } else if (identical(entity, node.thenElement)) {
+      optype.completionLocation = 'IfElement_thenElement';
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    } else if (identical(entity, node.elseElement)) {
+      optype.completionLocation = 'IfElement_elseElement';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
       optype.includeVoidReturnSuggestions = true;
@@ -712,10 +854,16 @@
       // Actual: if (var v i^)
       // Parsed: if (v) i^;
     } else if (identical(entity, node.condition)) {
+      optype.completionLocation = 'IfStatement_condition';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
-    } else if (identical(entity, node.thenStatement) ||
-        identical(entity, node.elseStatement)) {
+    } else if (identical(entity, node.thenStatement)) {
+      optype.completionLocation = 'IfStatement_thenElement';
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    } else if (identical(entity, node.elseStatement)) {
+      optype.completionLocation = 'IfStatement_elseElement';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
       optype.includeVoidReturnSuggestions = true;
@@ -724,11 +872,13 @@
 
   @override
   void visitImplementsClause(ImplementsClause node) {
+    optype.completionLocation = 'ImplementsClause_interface';
     optype.includeTypeNameSuggestions = true;
   }
 
   @override
   void visitIndexExpression(IndexExpression node) {
+    optype.completionLocation = 'IndexExpression_index';
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
   }
@@ -743,6 +893,7 @@
   @override
   void visitInterpolationExpression(InterpolationExpression node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'InterpolationExpression_expression';
       optype.includeReturnValueSuggestions = true;
       // Only include type names in a ${ } expression
       optype.includeTypeNameSuggestions =
@@ -753,6 +904,7 @@
   @override
   void visitIsExpression(IsExpression node) {
     if (identical(entity, node.type)) {
+      optype.completionLocation = 'IsExpression_type';
       optype.includeTypeNameSuggestions = true;
       optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
         var staticType = node.expression.staticType;
@@ -769,12 +921,26 @@
   }
 
   @override
+  void visitLabeledStatement(LabeledStatement node) {
+    optype.completionLocation = 'LabeledStatement_statement';
+  }
+
+  @override
   void visitLibraryIdentifier(LibraryIdentifier node) {
     // No suggestions.
   }
 
   @override
+  void visitListLiteral(ListLiteral node) {
+    if (node.elements.contains(entity)) {
+      optype.completionLocation = 'ListLiteral_element';
+    }
+    visitTypedLiteral(node);
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
+    optype.completionLocation = 'MapLiteralEntry_value';
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
   }
@@ -811,6 +977,7 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     // Make suggestions in the body of the mixin declaration
     if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.completionLocation = 'MixinDeclaration_member';
       optype.includeTypeNameSuggestions = true;
     }
   }
@@ -818,6 +985,8 @@
   @override
   void visitNamedExpression(NamedExpression node) {
     if (identical(entity, node.expression)) {
+      var context = _argumentListContext(node.parent);
+      optype.completionLocation = 'ArgumentList_${context}_named';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
 
@@ -857,12 +1026,14 @@
 
   @override
   void visitOnClause(OnClause node) {
+    optype.completionLocation = 'OnClause_superclassConstraint';
     optype.includeTypeNameSuggestions = true;
   }
 
   @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'ParenthesizedExpression_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -891,7 +1062,10 @@
       optype.isPrefixed = true;
       if (node.parent is TypeName && node.parent.parent is ConstructorName) {
         optype.includeConstructorSuggestions = true;
+      } else if (node.parent is Annotation) {
+        optype.includeConstructorSuggestions = true;
       } else {
+        optype.completionLocation = 'PropertyAccess_propertyName';
         optype.includeReturnValueSuggestions = true;
         optype.includeTypeNameSuggestions = true;
         optype.includeVoidReturnSuggestions =
@@ -903,6 +1077,7 @@
   @override
   void visitPrefixExpression(PrefixExpression node) {
     if (identical(entity, node.operand)) {
+      optype.completionLocation = 'PrefixExpression_${node.operator}_operand';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -919,11 +1094,13 @@
     if (identical(entity, node.operator) && offset > node.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.completionLocation = 'PropertyAccess_propertyName';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = !isThis;
       optype.includeVoidReturnSuggestions = true;
       optype.isPrefixed = true;
     } else if (identical(entity, node.propertyName)) {
+      optype.completionLocation = 'PropertyAccess_propertyName';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions =
           !isThis && (node.parent is! CascadeExpression);
@@ -935,12 +1112,28 @@
   @override
   void visitReturnStatement(ReturnStatement node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'ReturnStatement_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
   }
 
   @override
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    if (node.elements.contains(entity)) {
+      optype.completionLocation = 'SetOrMapLiteral_element';
+    }
+    visitTypedLiteral(node);
+  }
+
+  @override
+  void visitShowCombinator(ShowCombinator node) {
+    if (node.shownNames.contains(entity)) {
+      optype.completionLocation = 'ShowCombinator_shownName';
+    }
+  }
+
+  @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     var type = node.type;
     var name = node.identifier;
@@ -1006,6 +1199,7 @@
   @override
   void visitSpreadElement(SpreadElement node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'SpreadElement_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -1019,9 +1213,11 @@
   @override
   void visitSwitchCase(SwitchCase node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'SwitchCase_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     } else if (node.statements.contains(entity)) {
+      optype.completionLocation = 'SwitchCase_statement';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
       optype.includeVoidReturnSuggestions = true;
@@ -1031,11 +1227,13 @@
   @override
   void visitSwitchStatement(SwitchStatement node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'SwitchStatement_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
     if (identical(entity, node.rightBracket)) {
       if (node.members.isNotEmpty) {
+        optype.completionLocation = 'SwitchMember_statement';
         optype.includeReturnValueSuggestions = true;
         optype.includeTypeNameSuggestions = true;
         optype.includeVoidReturnSuggestions = true;
@@ -1044,6 +1242,7 @@
     if (entity is SwitchMember && entity != node.members.first) {
       var member = entity as SwitchMember;
       if (offset <= member.offset) {
+        optype.completionLocation = 'SwitchMember_statement';
         optype.includeReturnValueSuggestions = true;
         optype.includeTypeNameSuggestions = true;
         optype.includeVoidReturnSuggestions = true;
@@ -1053,6 +1252,7 @@
 
   @override
   void visitThrowExpression(ThrowExpression node) {
+    optype.completionLocation = 'ThrowExpression_expression';
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
   }
@@ -1065,6 +1265,9 @@
         optype.includeVarNameSuggestions = true;
       }
     }
+    if (offset <= node.variables.offset) {
+      optype.includeTypeNameSuggestions = true;
+    }
   }
 
   @override
@@ -1072,6 +1275,7 @@
     var arguments = node.arguments;
     for (var type in arguments) {
       if (identical(entity, type)) {
+        optype.completionLocation = 'TypeArgumentList_argument';
         optype.includeTypeNameSuggestions = true;
         break;
       }
@@ -1096,6 +1300,9 @@
 
   @override
   void visitTypeParameter(TypeParameter node) {
+    if (entity == node.bound) {
+      optype.completionLocation = 'TypeParameter_bound';
+    }
     optype.includeTypeNameSuggestions = true;
   }
 
@@ -1103,6 +1310,7 @@
   void visitVariableDeclaration(VariableDeclaration node) {
     // Make suggestions for the RHS of a variable declaration
     if (identical(entity, node.initializer)) {
+      optype.completionLocation = 'VariableDeclaration_initializer';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -1125,24 +1333,67 @@
   @override
   void visitWhileStatement(WhileStatement node) {
     if (identical(entity, node.condition)) {
+      optype.completionLocation = 'WhileStatement_condition';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
+    } else if (identical(entity, node.body)) {
+      optype.completionLocation = 'WhileStatement_body';
     }
   }
 
   @override
   void visitWithClause(WithClause node) {
+    if (node.mixinTypes.contains(entity)) {
+      optype.completionLocation = 'WithClause_mixinType';
+    }
     optype.includeTypeNameSuggestions = true;
   }
 
   @override
   void visitYieldStatement(YieldStatement node) {
     if (identical(entity, node.expression)) {
+      optype.completionLocation = 'YieldStatement_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
   }
 
+  /// Return the context in which the [node] occurs. The [node] is expected to
+  /// be the parent of the argument expression.
+  String _argumentListContext(AstNode node) {
+    if (node is ArgumentList) {
+      var parent = node.parent;
+      if (parent is Annotation) {
+        return 'annotation';
+      } else if (parent is ExtensionOverride) {
+        return 'extensionOverride';
+      } else if (parent is FunctionExpressionInvocation) {
+        return 'function';
+      } else if (parent is InstanceCreationExpression) {
+        // TODO(brianwilkerson) Enable this case.
+//        if (flutter.isWidgetType(parent.staticType)) {
+//          return 'widgetConstructor';
+//        }
+        return 'constructor';
+      } else if (parent is MethodInvocation) {
+        return 'method';
+      } else if (parent is RedirectingConstructorInvocation) {
+        return 'constructorRedirect';
+      } else if (parent is SuperConstructorInvocation) {
+        return 'constructorRedirect';
+      }
+    } else if (node is AssignmentExpression ||
+        node is BinaryExpression ||
+        node is PrefixExpression ||
+        node is PostfixExpression) {
+      return 'operator';
+    } else if (node is IndexExpression) {
+      return 'index';
+    }
+    throw ArgumentError(
+        'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
+  }
+
   bool _isEntityPrevTokenSynthetic() {
     var entity = this.entity;
     if (entity is AstNode) {
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 00dedd3..d6fa2a4 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -65,7 +65,8 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AssistKind {
-  /// The unique identifier of this kind of assist.
+  /// The unique identifier of this kind of assist. May be used by client editors,
+  /// for example to allow key-binding specific fixes (or groups of).
   final String id;
 
   /// The priority of this kind of assist for the kind of error being addressed.
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
index ac3c5fe..46c3a7d 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
@@ -91,8 +91,9 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FixKind {
-  /// The name of this kind of fix, used for debugging.
-  final String name;
+  /// The unique identifier of this kind of assist. May be used by client editors,
+  /// for example to allow key-binding specific fixes (or groups of).
+  final String id;
 
   /// The priority of this kind of fix for the kind of error being addressed
   /// where a higher integer value indicates a higher priority and relevance.
@@ -108,21 +109,21 @@
   /// kind of 'applied together' fix.
   final String appliedTogetherMessage;
 
-  /// Initialize a newly created kind of fix to have the given [name],
+  /// Initialize a newly created kind of fix to have the given [id],
   /// [priority], [message], and optionally [canBeAppliedTogether] and
   /// [appliedTogetherMessage].
-  const FixKind(this.name, this.priority, this.message,
+  const FixKind(this.id, this.priority, this.message,
       {this.appliedTogetherMessage});
 
   @override
-  int get hashCode => name.hashCode;
+  int get hashCode => id.hashCode;
 
   @override
-  bool operator ==(o) => o is FixKind && o.name == name;
+  bool operator ==(o) => o is FixKind && o.id == id;
 
   /// The change can be made with other fixes of this [FixKind].
   bool canBeAppliedTogether() => appliedTogetherMessage != null;
 
   @override
-  String toString() => name;
+  String toString() => id;
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
new file mode 100644
index 0000000..f375d47
--- /dev/null
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -0,0 +1,355 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
+
+NavigationCollector computeDartNavigation(
+    ResourceProvider resourceProvider,
+    NavigationCollector collector,
+    CompilationUnit unit,
+    int offset,
+    int length) {
+  var dartCollector = _DartNavigationCollector(collector);
+  var visitor = _DartNavigationComputerVisitor(resourceProvider, dartCollector);
+  if (offset == null || length == null) {
+    unit.accept(visitor);
+  } else {
+    var node = _getNodeForRange(unit, offset, length);
+    node?.accept(visitor);
+  }
+  return collector;
+}
+
+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) {
+      return n;
+    }
+  }
+  return node;
+}
+
+/// A Dart specific wrapper around [NavigationCollector].
+class _DartNavigationCollector {
+  final NavigationCollector collector;
+
+  _DartNavigationCollector(this.collector);
+
+  void _addRegion(int offset, int length, Element element) {
+    if (element is FieldFormalParameterElement) {
+      element = (element as FieldFormalParameterElement).field;
+    }
+    if (element == null || element == DynamicElementImpl.instance) {
+      return;
+    }
+    if (element.location == null) {
+      return;
+    }
+    var kind = protocol.convertElementKind(element.kind);
+    var location = protocol.newLocation_fromElement(element);
+    if (location == null) {
+      return;
+    }
+    collector.addRegion(offset, length, kind, location);
+  }
+
+  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) {
+    if (node == null) {
+      return;
+    }
+    var offset = node.offset;
+    var length = node.length;
+    _addRegion(offset, length, element);
+  }
+
+  void _addRegionForToken(Token token, Element element) {
+    var offset = token.offset;
+    var length = token.length;
+    _addRegion(offset, length, element);
+  }
+}
+
+class _DartNavigationComputerVisitor extends RecursiveAstVisitor<void> {
+  final ResourceProvider resourceProvider;
+  final _DartNavigationCollector computer;
+
+  _DartNavigationComputerVisitor(this.resourceProvider, this.computer);
+
+  @override
+  void visitAnnotation(Annotation node) {
+    var element = node.element;
+    if (element is ConstructorElement && element.isSynthetic) {
+      element = element.enclosingElement;
+    }
+    var name = node.name;
+    if (name is PrefixedIdentifier) {
+      // use constructor in: @PrefixClass.constructorName
+      var prefixElement = name.prefix.staticElement;
+      if (prefixElement is ClassElement) {
+        prefixElement = element;
+      }
+      computer._addRegionForNode(name.prefix, prefixElement);
+      // always constructor
+      computer._addRegionForNode(name.identifier, element);
+    } else {
+      computer._addRegionForNode(name, element);
+    }
+    computer._addRegionForNode(node.constructorName, element);
+    // arguments
+    node.arguments?.accept(this);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    node.leftHandSide?.accept(this);
+    computer._addRegionForToken(node.operator, node.staticElement);
+    node.rightHandSide?.accept(this);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    node.leftOperand?.accept(this);
+    computer._addRegionForToken(node.operator, node.staticElement);
+    node.rightOperand?.accept(this);
+  }
+
+  @override
+  void visitCompilationUnit(CompilationUnit unit) {
+    // prepare top-level nodes sorted by their offsets
+    var nodes = <AstNode>[];
+    nodes.addAll(unit.directives);
+    nodes.addAll(unit.declarations);
+    nodes.sort((a, b) {
+      return a.offset - b.offset;
+    });
+    // visit sorted nodes
+    for (var node in nodes) {
+      node.accept(this);
+    }
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    // associate constructor with "T" or "T.name"
+    {
+      AstNode firstNode = node.returnType;
+      AstNode lastNode = node.name;
+      lastNode ??= firstNode;
+      if (firstNode != null && lastNode != null) {
+        computer._addRegion_nodeStart_nodeEnd(
+            firstNode, lastNode, node.declaredElement);
+      }
+    }
+    super.visitConstructorDeclaration(node);
+  }
+
+  @override
+  void visitConstructorName(ConstructorName node) {
+    var parent = node.parent;
+    if (parent is InstanceCreationExpression &&
+        parent.constructorName == node) {
+      _addConstructorName(parent, node);
+    } else if (parent is ConstructorDeclaration &&
+        parent.redirectedConstructor == node) {
+      _addConstructorName(node, node);
+    }
+  }
+
+  @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    if (node.type == null) {
+      var token = node.keyword;
+      if (token?.keyword == Keyword.VAR) {
+        var inferredType = node.declaredElement?.type;
+        var element = inferredType?.element;
+        if (element != null) {
+          computer._addRegionForToken(token, element);
+        }
+      }
+    }
+    super.visitDeclaredIdentifier(node);
+  }
+
+  @override
+  void visitExportDirective(ExportDirective node) {
+    var exportElement = node.element as ExportElement;
+    if (exportElement != null) {
+      Element libraryElement = exportElement.exportedLibrary;
+      _addUriDirectiveRegion(node, libraryElement);
+    }
+    super.visitExportDirective(node);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    var importElement = node.element as ImportElement;
+    if (importElement != null) {
+      Element libraryElement = importElement.importedLibrary;
+      _addUriDirectiveRegion(node, libraryElement);
+    }
+    super.visitImportDirective(node);
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    super.visitIndexExpression(node);
+    var element = node.staticElement;
+    computer._addRegionForToken(node.leftBracket, element);
+    computer._addRegionForToken(node.rightBracket, element);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    computer._addRegionForNode(node.name, node.element);
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    _addUriDirectiveRegion(node, node.element);
+    super.visitPartDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    computer._addRegionForNode(node.libraryName, node.element);
+    super.visitPartOfDirective(node);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    super.visitPostfixExpression(node);
+    computer._addRegionForToken(node.operator, node.staticElement);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    computer._addRegionForToken(node.operator, node.staticElement);
+    super.visitPrefixExpression(node);
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    Element element = node.staticElement;
+    if (element != null && element.isSynthetic) {
+      element = element.enclosingElement;
+    }
+    // add region
+    computer._addRegionForToken(node.thisKeyword, element);
+    computer._addRegionForNode(node.constructorName, element);
+    // process arguments
+    node.argumentList?.accept(this);
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.parent is ConstructorDeclaration) {
+      return;
+    }
+    var element = node.staticElement;
+    computer._addRegionForNode(node, element);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    Element element = node.staticElement;
+    if (element != null && element.isSynthetic) {
+      element = element.enclosingElement;
+    }
+    // add region
+    computer._addRegionForToken(node.superKeyword, element);
+    computer._addRegionForNode(node.constructorName, element);
+    // process arguments
+    node.argumentList?.accept(this);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    /// 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;
+      if (firstElement == null) {
+        return null;
+      }
+      for (var i = 1; i < variables.length; i++) {
+        var element = variables[1].declaredElement.type?.element;
+        if (element != firstElement) {
+          return null;
+        }
+      }
+      return firstElement;
+    }
+
+    if (node.type == null) {
+      var token = node.keyword;
+      if (token?.keyword == Keyword.VAR) {
+        var element = getCommonElement(node.variables);
+        if (element != null) {
+          computer._addRegionForToken(token, element);
+        }
+      }
+    }
+    super.visitVariableDeclarationList(node);
+  }
+
+  void _addConstructorName(AstNode parent, ConstructorName node) {
+    Element element = node.staticElement;
+    if (element == null) {
+      return;
+    }
+    // if a synthetic constructor, navigate to the class
+    if (element.isSynthetic) {
+      element = element.enclosingElement;
+    }
+    // add regions
+    var typeName = node.type;
+    // [prefix].ClassName
+    {
+      var name = typeName.name;
+      var className = name;
+      if (name is PrefixedIdentifier) {
+        name.prefix.accept(this);
+        className = name.identifier;
+      }
+      computer._addRegionForNode(className, element);
+    }
+    // <TypeA, TypeB>
+    var typeArguments = typeName.typeArguments;
+    if (typeArguments != null) {
+      typeArguments.accept(this);
+    }
+    // optional "name"
+    if (node.name != null) {
+      computer._addRegionForNode(node.name, element);
+    }
+  }
+
+  /// 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) {
+    var source = element?.source;
+    if (source != null) {
+      if (resourceProvider.getResource(source.fullName).exists) {
+        computer._addRegionForNode(node.uri, element);
+      }
+    }
+  }
+}
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 6223a2c..c9f6489 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -16,83 +15,357 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(OpTypeTest);
-    defineReflectiveTests(OpTypeDart1OnlyTest);
-    defineReflectiveTests(OpTypeTestWithExtensionMethods);
   });
 }
 
+/// Common test methods to Dart1/Dart2 versions of OpType tests.
+abstract class AbstractOpTypeTest extends AbstractContextTest {
+  String testPath;
+  int completionOffset;
+
+  void addTestSource(String content) {
+    completionOffset = content.indexOf('^');
+    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
+    var nextOffset = content.indexOf('^', completionOffset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    content = content.substring(0, completionOffset) +
+        content.substring(completionOffset + 1);
+    super.addSource(testPath, content);
+  }
+
+  Future<void> assertOpType(
+      {bool caseLabel = false,
+      String completionLocation,
+      bool constructors = false,
+      bool namedArgs = false,
+      bool prefixed = false,
+      bool returnValue = false,
+      bool statementLabel = false,
+      bool staticMethodBody = false,
+      bool typeNames = false,
+      bool varNames = false,
+      bool voidReturn = false,
+      CompletionSuggestionKind kind =
+          CompletionSuggestionKind.INVOCATION}) async {
+    //
+    // Compute the OpType.
+    //
+    var resolvedUnit = await driver.getResult(testPath);
+    var completionTarget =
+        CompletionTarget.forOffset(resolvedUnit.unit, completionOffset);
+    var opType = OpType.forCompletion(completionTarget, completionOffset);
+    //
+    // Validate the OpType.
+    //
+    var isValid = opType.includeCaseLabelSuggestions == caseLabel &&
+        opType.completionLocation == completionLocation &&
+        opType.includeConstructorSuggestions == constructors &&
+        opType.suggestKind == kind &&
+        opType.includeNamedArgumentSuggestions == namedArgs &&
+        opType.isPrefixed == prefixed &&
+        opType.includeReturnValueSuggestions == returnValue &&
+        opType.includeStatementLabelSuggestions == statementLabel &&
+        opType.inStaticMethodBody == staticMethodBody &&
+        opType.includeTypeNameSuggestions == typeNames &&
+        opType.includeVarNameSuggestions == varNames &&
+        opType.includeVoidReturnSuggestions == voidReturn;
+    //
+    // Fail with a useful message if the OpType doesn't match the expectations.
+    //
+    if (!isValid) {
+      var args = <String>[];
+      void addArg(bool shouldAdd, String argument) {
+        if (shouldAdd) {
+          args.add(argument);
+        }
+      }
+
+      addArg(opType.includeCaseLabelSuggestions, 'caseLabel: true');
+      addArg(opType.completionLocation != null,
+          "completionLocation: '${opType.completionLocation}'");
+      addArg(opType.includeConstructorSuggestions, 'constructors: true');
+      addArg(opType.suggestKind != CompletionSuggestionKind.INVOCATION,
+          'kind: ${opType.suggestKind}');
+      addArg(opType.includeNamedArgumentSuggestions, 'namedArgs: true');
+      addArg(opType.isPrefixed, 'prefixed: true');
+      addArg(opType.includeReturnValueSuggestions, 'returnValue: true');
+      addArg(opType.includeStatementLabelSuggestions, 'statementLabel: true');
+      addArg(opType.inStaticMethodBody, 'staticMethodBody: true');
+      addArg(opType.includeTypeNameSuggestions, 'typeNames: true');
+      addArg(opType.includeVarNameSuggestions, 'varNames: true');
+      addArg(opType.includeVoidReturnSuggestions, 'voidReturn: true');
+
+      fail('''
+Actual OpType does not match expected. Actual matches
+  await assertOpType(${args.join(', ')});''');
+    }
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    testPath = convertPath('/completionTest.dart');
+  }
+}
+
 @reflectiveTest
-class OpTypeDart1OnlyTest extends OpTypeTestCommon {
+class OpTypeTest extends AbstractOpTypeTest {
+  Future<void> test_annotation_constructorName_arguments() async {
+    // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class C { @A.n^() void m() {} }
+class A {
+  const A.named();
+}
+''');
+    await assertOpType(constructors: true, prefixed: true);
+  }
+
+  Future<void> test_annotation_constructorName_noArguments() async {
+    // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class C { @A.^ void m() {} }
+class A {
+  const A.m();
+}
+''');
+    await assertOpType(constructors: true, prefixed: true);
+  }
+
+  Future<void> test_annotation_name() async {
+    // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class C { @A^ void m() {} }
+class A {
+  const A();
+}
+''');
+    await assertOpType(
+        completionLocation: 'Annotation_name',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
   @failingTest
-  Future<void> test_Annotation() async {
+  Future<void> test_annotation_notBeforeDeclaration() async {
     // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
     addTestSource('class C { @A^ }');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        constructors: true,
+        completionLocation: 'Annotation_name',
+        returnValue: true,
+        typeNames: true);
     // TODO(danrubel): This test fails because the @A is dropped from the AST.
     // Ideally we generate a synthetic field and associate the annotation
     // with that field, but doing so breaks test_constructorAndMethodNameCollision.
     // See https://dart-review.googlesource.com/c/sdk/+/65760/3/pkg/analyzer/lib/src/fasta/ast_builder.dart#2395
   }
 
-  Future<void> test_ArgumentList() async {
+  Future<void> test_argumentList_constructor_named_resolved_1_0() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
+    addTestSource(
+      'main() { new A.b(^); }'
+      'class A{ A.b({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_constructor_named_resolved_1_1() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addTestSource(
+      'main() { new A.b(o^); }'
+      'class A { A.b({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_constructor_resolved_1_0() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
+    addTestSource(
+      'main() { new A(^); }'
+      'class A{ A({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_constructor_resolved_1_1() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addTestSource(
+      'main() { new A(o^); }'
+      'class A { A({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_factory_named_resolved_1_0() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
+    addTestSource(
+      'main() { new A.b(^); }'
+      'class A{ factory A.b({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_factory_named_resolved_1_1() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addTestSource(
+      'main() { new A.b(o^); }'
+      'class A { factory A.b({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_factory_resolved_1_0() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
+    addTestSource(
+      'main() { new A(^); }'
+      'class A{ factory A({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_factory_resolved_1_1() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addTestSource(
+      'main() { new A(o^); }'
+      'class A { factory A({one, two}) {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ArgumentList_constructor_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_method_resolved_1_0() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('main() { foo(^);} foo({one, two}) {}');
+    await assertOpType(
+        completionLocation: 'ArgumentList_method_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_method_resolved_1_1() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('main() { foo(o^);} foo({one, two}) {}');
+    await assertOpType(
+        completionLocation: 'ArgumentList_method_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addTestSource('void main() {expect(foo: ^)}');
+    await assertOpType(
+        completionLocation: 'ArgumentList_method_named',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_argumentList_prefixedIdentifier() async {
+    // SimpleIdentifier  PrefixedIdentifier  ArgumentList
+    addTestSource('void main() {expect(aa.^)}');
+    await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_argumentList_resolved() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('void main() {int.parse(^)}');
+    await assertOpType(
+        completionLocation: 'ArgumentList_method_unnamed',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_argumentList_resolved_2_0() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('void main() {int.parse("16", ^)}');
+    await assertOpType(
+        completionLocation: 'ArgumentList_method_named', namedArgs: true);
+  }
+
+  Future<void> test_argumentList_unresolved() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('void main() {expect(^)}');
     // If "expect()" were resolved, then either namedArgs would be true
     // or returnValue and typeNames would be true.
     await assertOpType(
+        completionLocation: 'ArgumentList_method_unnamed',
         constructors: true,
         namedArgs: true,
         returnValue: true,
         typeNames: true);
   }
 
-  Future<void> test_ArgumentList_namedParam() async {
-    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
-    // ExpressionStatement
-    addTestSource('void main() {expect(foo: ^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_ArgumentList_prefixedIdentifier() async {
-    // SimpleIdentifier  PrefixedIdentifier  ArgumentList
-    addTestSource('void main() {expect(aa.^)}');
+  Future<void> test_asExpression_rightHandSide() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
     await assertOpType(
-        constructors: true, returnValue: true, typeNames: true, prefixed: true);
+        completionLocation: 'AsExpression_type', typeNames: true);
   }
 
-  Future<void> test_ArgumentList_resolved() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('void main() {int.parse(^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_AsIdentifier() async {
-    addTestSource('class A {var asdf; foo() {as^}');
+  Future<void> test_assertInitializer_firstArgument() async {
+    addTestSource('class C { C() : assert(^); }');
     await assertOpType(
+        completionLocation: 'AssertInitializer_condition',
         constructors: true,
         returnValue: true,
-        typeNames: true,
-        voidReturn: true);
+        typeNames: true);
   }
 
-  Future<void> test_Assert() async {
+  Future<void> test_assertInitializer_secondArgument() async {
+    addTestSource('class C { C() : assert(true, ^); }');
+    // TODO(brianwilkerson) This should have a location of
+    //  'AssertInitializer_message'
+    await assertOpType();
+  }
+
+  Future<void> test_assertStatement_firstArgument() async {
     addTestSource('main() {assert(^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'AssertStatement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_AssertInitializer() async {
-    addTestSource('class C { C() : assert(^); }');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+  Future<void> test_assertStatement_secondArgument() async {
+    addTestSource('main() {assert(true, ^)}');
+    // TODO(brianwilkerson) This should have a location of
+    //  'AssertStatement_message'
+    await assertOpType();
   }
 
-  Future<void> test_AssignmentExpression_RHS() async {
+  Future<void> test_assignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await assertOpType(varNames: true);
+  }
+
+  Future<void> test_assignmentExpression_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('class A {} main() {int a; int b = ^}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'VariableDeclaration_initializer',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_AssignmentExpression_type() async {
+  Future<void> test_assignmentExpression_type() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -105,13 +378,14 @@
     // Consider suggesting only types
     // if only spaces separates the 1st and 2nd identifiers.
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_AssignmentExpression_type_newline() async {
+  Future<void> test_assignmentExpression_type_newline() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -123,13 +397,14 @@
     // if newline follows first identifier
     // because user is probably starting a new statement
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_AssignmentExpression_type_partial() async {
+  Future<void> test_assignmentExpression_type_partial() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -142,13 +417,14 @@
     // Consider suggesting only types
     // if only spaces separates the 1st and 2nd identifiers.
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_AssignmentExpression_type_partial_newline() async {
+  Future<void> test_assignmentExpression_type_partial_newline() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -160,69 +436,197 @@
     // if newline follows first identifier
     // because user is probably starting a new statement
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_AwaitExpression() async {
+  Future<void> test_awaitExpression_assignment() async {
+    addTestSource('main() async {A a; int x = await ^}');
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_awaitExpression_assignment2() async {
+    addTestSource('main() async {A a; int x = await ^ await foo;}');
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_awaitExpression_assignment3() async {
+    addTestSource('main() async {A a; int x = await v^ int y = await foo;}');
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_awaitExpression_statement() async {
     // SimpleIdentifier  AwaitExpression  ExpressionStatement
     addTestSource('main() async {A a; await ^}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_AwaitExpression2() async {
+  Future<void> test_awaitExpression_statement2() async {
     addTestSource('main() async {A a; await c^ await}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_AwaitExpression3() async {
+  Future<void> test_awaitExpression_statement3() async {
     addTestSource('main() async {A a; await ^ await foo;}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_AwaitExpression4() async {
+  Future<void> test_awaitExpression_statement4() async {
     addTestSource('main() async {A a; await ^ await bar();}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'AwaitExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_AwaitExpression_assignment() async {
-    addTestSource('main() async {A a; int x = await ^}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_AwaitExpression_assignment2() async {
-    addTestSource('main() async {A a; int x = await ^ await foo;}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_AwaitExpression_assignment3() async {
-    addTestSource('main() async {A a; int x = await v^ int y = await foo;}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_BinaryExpression_LHS() async {
+  Future<void> test_binaryExpression_LHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
     addTestSource('main() {int a = 1, b = ^ + 2;}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'VariableDeclaration_initializer',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_BinaryExpression_RHS() async {
+  Future<void> test_binaryExpression_RHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
     addTestSource('main() {int a = 1, b = 2 + ^;}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'BinaryExpression_+_rightOperand',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_BinaryExpression_RHS2() async {
+  Future<void> test_binaryExpression_RHS2() async {
     // SimpleIdentifier  BinaryExpression
     addTestSource('main() {if (c < ^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'BinaryExpression_<_rightOperand',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_Block() async {
+  Future<void> test_block_empty() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('class A extends E implements I with M {a() {^}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_block_final() async {
+    addTestSource('main() {final ^}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_block_final_final() async {
+    addTestSource('main() {final ^ final S x;}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_block_final_final2() async {
+    addTestSource('main() {final S^ final S x;}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_block_identifier_partial() async {
+    addTestSource('class X {a() {var f; {var x;} D^ var r;} void b() { }}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_block_inConstructor() async {
+    addTestSource('class A {A() {^}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_block_inFunction() async {
+    addTestSource('foo() {^}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_block_inMethod() async {
+    addTestSource('class A {foo() {^}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_block_keyword() async {
+    addTestSource('class C { static C get instance => null; } main() {C.in^}');
+    await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_block_startOfStatement() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('''
       class X {
@@ -234,141 +638,62 @@
         }
       }''');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_Block_catch_2a() async {
-    // '}'  Block  BlockFunctionBody  FunctionExpression
-    addTestSource('main() {try {} catch () {} ^}');
+  Future<void> test_block_static() async {
+    addTestSource('class A {static foo() {^}}');
     await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        staticMethodBody: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_break_afterLabel() async {
+    addTestSource('main() { foo: while (true) { break foo ^ ; } }');
+    await assertOpType(/* No valid completions */);
+  }
+
+  Future<void> test_break_beforeLabel() async {
+    addTestSource('main() { foo: while (true) { break ^ foo; } }');
+    await assertOpType(statementLabel: true);
+  }
+
+  Future<void> test_break_noLabel() async {
+    addTestSource('main() { foo: while (true) { break ^; } }');
+    await assertOpType(statementLabel: true);
+  }
+
+  Future<void> test_builtInIdentifier_as() async {
+    addTestSource('class A {var asdf; foo() {as^}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_Block_catch_2b() async {
-    // [ExpressionStatement 'c']  Block  BlockFunctionBody
-    addTestSource('main() {try {} catch () {} c^}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
+  Future<void> test_builtInIdentifier_as2() async {
+    addTestSource('class A {var asdf; foo() {A as^}');
+    await assertOpType();
   }
 
-  Future<void> test_Block_catch_2c() async {
-    // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
-    addTestSource('main() {try {} catch () {} ^;}');
+  Future<void> test_cascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addTestSource('''
+      // looks like a cascade to the parser
+      // but the user is trying to get completions for a non-cascade
+      main() {A a; a.^.z}''');
     await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_catch_2d() async {
-    // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
-    addTestSource('main() {try {} catch () {} ^ Foo foo;}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_catch_3a() async {
-    // '}'  Block  BlockFunctionBody  FunctionExpression
-    addTestSource('main() {try {} finally {} ^}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_catch_3b() async {
-    // [ExpressionStatement 'c']  Block  BlockFunctionBody
-    addTestSource('main() {try {} finally {} c^}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_catch_3c() async {
-    // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
-    addTestSource('main() {try {} finally {} ^;}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_catch_3d() async {
-    // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
-    addTestSource('main() {try {} finally {} ^ Foo foo;}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_empty() async {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addTestSource('class A extends E implements I with M {a() {^}}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_identifier_partial() async {
-    addTestSource('class X {a() {var f; {var x;} D^ var r;} void b() { }}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_in_constructor() async {
-    addTestSource('class A {A() {^}}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_in_function() async {
-    addTestSource('foo() {^}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_in_method() async {
-    addTestSource('class A {foo() {^}}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_Block_keyword() async {
-    addTestSource('class C { static C get instance => null; } main() {C.in^}');
-    await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
         constructors: true,
         prefixed: true,
         returnValue: true,
@@ -376,122 +701,201 @@
         voidReturn: true);
   }
 
-  Future<void> test_Block_static() async {
-    addTestSource('class A {static foo() {^}}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        staticMethodBody: true,
-        voidReturn: true);
-  }
-
-  Future<void> test_CascadeExpression_selector1() async {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addTestSource('''
-      // looks like a cascade to the parser
-      // but the user is trying to get completions for a non-cascade
-      main() {A a; a.^.z}''');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true,
-        prefixed: true);
-  }
-
-  Future<void> test_CascadeExpression_selector2() async {
+  Future<void> test_cascadeExpression_selector2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
     addTestSource('main() {A a; a..^z}');
     await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
         constructors: true,
+        prefixed: true,
         returnValue: true,
-        voidReturn: true,
-        prefixed: true);
+        voidReturn: true);
   }
 
-  Future<void> test_CascadeExpression_selector2_withTrailingReturn() async {
+  Future<void> test_cascadeExpression_selector2_withTrailingReturn() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
     addTestSource('main() {A a; a..^ return}');
     await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
         constructors: true,
+        prefixed: true,
         returnValue: true,
-        voidReturn: true,
-        prefixed: true);
+        voidReturn: true);
   }
 
-  Future<void> test_CascadeExpression_target() async {
+  Future<void> test_cascadeExpression_target() async {
     // SimpleIdentifier  CascadeExpression  ExpressionStatement
     addTestSource('main() {A a; a^..b}');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_CatchClause_typed() async {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+  Future<void> test_classDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('@deprecated class A {^}');
     await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
   }
 
-  Future<void> test_CatchClause_untyped() async {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+  Future<void> test_classDeclaration_body2() async {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('@deprecated class A {^mth() {}}');
     await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true);
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
   }
 
-  Future<void> test_CommentReference() async {
+  Future<void> test_commentReference() async {
     // SimpleIdentifier  CommentReference  Comment  MethodDeclaration
     addTestSource('class A {/** [^] */ mth() {}');
     await assertOpType(
+        completionLocation: 'CommentReference_identifier',
         constructors: true,
+        kind: CompletionSuggestionKind.IDENTIFIER,
         returnValue: true,
         typeNames: true,
-        voidReturn: true,
-        kind: CompletionSuggestionKind.IDENTIFIER);
+        voidReturn: true);
   }
 
-  Future<void> test_ConditionalExpression_elseExpression() async {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addTestSource('class C {foo(){var f; {var x;} return a ? T1 : T^}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_ConditionalExpression_elseExpression_empty() async {
+  Future<void> test_conditionalExpression_elseExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T1 : ^}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ConditionalExpression_elseExpression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ConditionalExpression_partial_thenExpression() async {
+  Future<void> test_conditionalExpression_elseExpression_nonEmpty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addTestSource('class C {foo(){var f; {var x;} return a ? T1 : T^}}');
+    await assertOpType(
+        completionLocation: 'ConditionalExpression_elseExpression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_conditionalExpression_partial_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T^}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ConditionalExpression_thenExpression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ConditionalExpression_partial_thenExpression_empty() async {
+  Future<void> test_conditionalExpression_partial_thenExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? ^}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ConditionalExpression_thenExpression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ConditionalExpression_thenExpression() async {
+  Future<void> test_conditionalExpression_thenExpression_nonEmpty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T^ : c}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ConditionalExpression_thenExpression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ConstructorFieldInitializer_name() async {
+  Future<void> test_constructorDeclaration_const_named() async {
+    // ConstructorDeclaration
+    // The additional syntax with assert is to ensure that the target node is
+    // a ConstructorDeclaration, instead of a MethodDeclaration.
+    addTestSource('''
+      class ABC {
+        int i;
+        const A^.b(this.i) : assert(i != 0);
+      }''');
+    await assertOpType(
+        completionLocation: 'ConstructorDeclaration_returnType',
+        typeNames: true);
+  }
+
+  Future<void> test_constructorDeclaration_const_named2() async {
+    // ConstructorDeclaration
+    // The additional syntax with assert is to ensure that the target node is
+    // a ConstructorDeclaration, instead of a MethodDeclaration.
+    // A negative test that type names aren't expected to be the name of a named
+    // constructor.
+    addTestSource('''
+      class ABC {
+        int i;
+        const A.^b(this.i) : assert(i != 0);
+      }''');
+    await assertOpType(typeNames: false);
+  }
+
+  Future<void> test_constructorDeclaration_const_unnamed() async {
+    // ConstructorDeclaration
+    // The additional syntax with assert is to ensure that the target node is
+    // a ConstructorDeclaration, instead of a MethodDeclaration.
+    addTestSource('''
+      class ABC {
+        int i;
+        const A^(this.i) : assert(i != 0);
+      }''');
+    await assertOpType(
+        completionLocation: 'ConstructorDeclaration_returnType',
+        typeNames: true);
+  }
+
+  Future<void> test_constructorDeclaration_factory_named() async {
+    // ConstructorDeclaration
+    addTestSource(
+      'class A { factory A^.b() {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ConstructorDeclaration_returnType',
+        typeNames: true);
+  }
+
+  Future<void> test_constructorDeclaration_factory_named2() async {
+    // ConstructorDeclaration
+    // A negative test that type names aren't expected to be the name of a named
+    // constructor.
+    addTestSource(
+      'class A { factory A.^b() {} }',
+    );
+    await assertOpType(typeNames: false);
+  }
+
+  Future<void> test_constructorDeclaration_factory_unnamed() async {
+    // ConstructorDeclaration
+    addTestSource(
+      'class A { factory A^() {} }',
+    );
+    await assertOpType(
+        completionLocation: 'ConstructorDeclaration_returnType',
+        typeNames: true);
+  }
+
+  Future<void> test_constructorDeclaration_generative_unnamed() async {
+    // ClassDeclaration
+    // This ConstructorDeclaration case is handled by the ClassDeclaration
+    // visitor.
+    addTestSource('''
+      class ABC {
+        int i;
+        A^(this.i) : assert(i != 0);
+      }''');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_constructorFieldInitializer_name() async {
     addTestSource(r'''
 class C {
   final int foo;
@@ -499,10 +903,11 @@
   C() : ^
 }
 ''');
-    await assertOpType();
+    await assertOpType(
+        completionLocation: 'ConstructorDeclaration_initializer');
   }
 
-  Future<void> test_ConstructorFieldInitializer_value() async {
+  Future<void> test_constructorFieldInitializer_value() async {
     addTestSource(r'''
 class C {
   final int foo;
@@ -511,303 +916,1093 @@
 }
 ''');
     await assertOpType(
-      constructors: true,
-      returnValue: true,
-      typeNames: true,
-    );
+        completionLocation: 'ConstructorFieldInitializer_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_DefaultFormalParameter_named_expression() async {
+  Future<void> test_constructorName_name() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new X.^}');
+    await assertOpType(constructors: true, prefixed: true);
+  }
+
+  Future<void> test_constructorName_name_resolved() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new Str^ing.fromCharCodes([]);}');
+    await assertOpType(constructors: true);
+  }
+
+  Future<void> test_constructorName_nameAndPrefix_resolved() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+import 'dart:core' as core;
+main() {new core.String.from^CharCodes([]);}
+''');
+    await assertOpType(constructors: true, prefixed: true);
+  }
+
+  Future<void> test_constructorName_resolved() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new String.fr^omCharCodes([]);}');
+    await assertOpType(constructors: true, prefixed: true);
+  }
+
+  Future<void> test_constructorName_unresolved() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new String.fr^omCharCodes([]);}');
+    await assertOpType(constructors: true, prefixed: true);
+  }
+
+  Future<void> test_continue_afterLabel() async {
+    addTestSource('main() { foo: while (true) { continue foo ^ ; } }');
+    await assertOpType(/* No valid completions */);
+  }
+
+  Future<void> test_continue_beforeLabel() async {
+    addTestSource('main() { foo: while (true) { continue ^ foo; } }');
+    await assertOpType(statementLabel: true, caseLabel: true);
+  }
+
+  Future<void> test_continue_noLabel() async {
+    addTestSource('main() { foo: while (true) { continue ^; } }');
+    await assertOpType(statementLabel: true, caseLabel: true);
+  }
+
+  Future<void> test_defaultFormalParameter_named_expression() async {
     // DefaultFormalParameter FormalParameterList MethodDeclaration
     addTestSource('class A {a(blat: ^) { }}');
     await assertOpType(
-      constructors: true,
-      returnValue: true,
-      typeNames: true,
-    );
+        completionLocation: 'DefaultFormalParameter_defaultValue',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_DoStatement() async {
+  Future<void> test_doStatement_inCondition() async {
     // SimpleIdentifier  DoStatement  Block
     addTestSource('main() {do{} while(^x);}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'DoStatement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ExpressionFunctionBody() async {
+  Future<void> test_doubleLiteral() async {
+    addTestSource('main() { print(1.2^); }');
+    await assertOpType();
+  }
+
+  Future<void> test_expressionFunctionBody_beginning() async {
     // SimpleIdentifier  ExpressionFunctionBody  FunctionExpression
     addTestSource('m(){[1].forEach((x)=>^x);}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ExpressionFunctionBody_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ExpressionStatement() async {
+  Future<void> test_expressionStatement_beginning() async {
     // ExpressionStatement  Block  BlockFunctionBody
     addTestSource('n(){f(3);^}');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_ForEachStatement() async {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main() {for(z in ^zs) {}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+  Future<void> test_expressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class C {a() {C ^}}');
+    await assertOpType(
+        completionLocation: 'ExpressionStatement_expression', varNames: true);
   }
 
-  Future<void> test_ForEachStatement_body_typed() async {
+  Future<void> test_expressionStatement_name_semicolon() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class C {a() {C ^;}}');
+    await assertOpType(
+        completionLocation: 'ExpressionStatement_expression', varNames: true);
+  }
+
+  Future<void> test_expressionStatement_prefixed_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class C {a() {x.Y ^}}');
+    await assertOpType(
+        completionLocation: 'ExpressionStatement_expression', varNames: true);
+  }
+
+  Future<void> test_expressionStatement_prefixed_name_semicolon() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class C {a() {x.Y ^;}}');
+    await assertOpType(
+        completionLocation: 'ExpressionStatement_expression', varNames: true);
+  }
+
+  Future<void> test_extendsClause_beginning() async {
+    // ExtendsClause  ClassDeclaration
+    addTestSource('class x extends ^\n{}');
+    await assertOpType(
+        completionLocation: 'ExtendsClause_superclass', typeNames: true);
+  }
+
+  Future<void> test_extensionDeclaration_body_atBeginning() async {
+    // SimpleIdentifier  MethodDeclaration  ExtensionDeclaration
+    addTestSource('extension E on int {^mth() {}}');
+    await assertOpType(
+        completionLocation: 'ExtensionDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_extensionDeclaration_body_atEnd() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('extension E on int {^}');
+    await assertOpType(
+        completionLocation: 'ExtensionDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_extensionDeclaration_extendedType() async {
+    // SimpleIdentifier  MethodDeclaration  ExtensionDeclaration
+    addTestSource('extension E on ^ {}');
+    await assertOpType(
+        completionLocation: 'ExtensionDeclaration_extendedType',
+        typeNames: true);
+  }
+
+  Future<void> test_extensionOverride_argumentList() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('''
+extension E on int {}
+int x = E(^);
+''');
+    await assertOpType(
+        completionLocation: 'ArgumentList_extensionOverride_unnamed',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_fieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {A ^}');
+    await assertOpType(varNames: true);
+  }
+
+  Future<void> test_fieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {var ^}');
+    await assertOpType();
+  }
+
+  Future<void> test_fieldDeclaration_type() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {^ foo; }');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_fieldDeclaration_type_noSemicolon() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {^ foo }');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_forEachStatement_body_typed() async {
     // Block  ForEachStatement
     addTestSource('main(args) {for (int foo in bar) {^}}');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_ForEachStatement_body_untyped() async {
+  Future<void> test_forEachStatement_body_untyped() async {
     // Block  ForEachStatement
     addTestSource('main(args) {for (foo in bar) {^}}');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_ForEachStatement_iterable() async {
+  Future<void> test_forEachStatement_iterable() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (int foo in ^) {}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ForEachPartsWithDeclaration_iterable',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ForElement_body() async {
+  Future<void> test_forEachStatement_iterator() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main() {for(z in ^zs) {}}');
+    await assertOpType(
+        completionLocation: 'ForEachPartsWithIdentifier_iterable',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_forEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_forEachStatement_loopVariable_name() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (String ^ in args) {}}');
+    await assertOpType();
+  }
+
+  Future<void> test_forEachStatement_loopVariable_name2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (String f^ in args) {}}');
+    await assertOpType();
+  }
+
+  Future<void> test_forEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_forEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_forElement_body() async {
     addTestSource('main(args) {[for (var foo in [0]) ^];}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ForElement_body',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ForElement_forEachParts_iterable() async {
+  Future<void> test_forElement_forEachParts_iterable() async {
     addTestSource('main(args) {[for (var foo in ^) foo];}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ForEachPartsWithDeclaration_iterable',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ForElement_forEachParts_type() async {
+  Future<void> test_forElement_forEachParts_type() async {
     addTestSource('main(args) {[for (i^ foo in [0]) foo];}');
     await assertOpType(typeNames: true);
   }
 
-  Future<void> test_FormalParameter_partialType() async {
+  Future<void> test_formalParameter_partialType() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(b.^ f) { }}');
     await assertOpType(
-      constructors: true,
-      returnValue: true,
-      typeNames: true,
-      prefixed: true,
-    );
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_FormalParameter_partialType2() async {
+  Future<void> test_formalParameter_partialType2() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(b.z^ f) { }}');
     await assertOpType(
-      constructors: true,
-      returnValue: true,
-      typeNames: true,
-      prefixed: true,
-    );
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_FormalParameter_partialType3() async {
+  Future<void> test_formalParameter_partialType3() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(b.^) { }}');
     await assertOpType(
-      constructors: true,
-      returnValue: true,
-      typeNames: true,
-      prefixed: true,
-    );
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ForStatement_condition() async {
+  Future<void> test_formalParameterList_empty() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('class A {a(^) { }}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_forStatement_condition() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; i^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ForParts_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ForStatement_updaters() async {
+  Future<void> test_forStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_forStatement_initializer_inKeyword() async {
+    addTestSource('main() { for (var v i^) }');
+    await assertOpType();
+  }
+
+//
+  Future<void> test_forStatement_initializer_type() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (i^ v = 0;)}');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void>
+      test_forStatement_initializer_variableNameEmpty_afterType() async {
+    addTestSource('main() { for (String ^) }');
+    await assertOpType(varNames: true);
+  }
+
+  Future<void> test_forStatement_updaters() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; i^)}');
-    // TODO (danrubel) may want to exclude methods/functions with void return
+    // TODO (danrubel) might want to exclude methods/functions with void return
     await assertOpType(
+        completionLocation: 'ForParts_updater',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_ForStatement_updaters_prefix_expression() async {
+  Future<void> test_forStatement_updaters_prefix_expression() async {
     // SimpleIdentifier  PrefixExpression  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; ++i^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'PrefixExpression_++_operand',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IfElement_condition() async {
+  Future<void> test_functionDeclaration_inLineComment() async {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal comment ^
+      zoo(z) { } String name;''');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inLineComment2() async {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal ^comment
+      zoo(z) { } String name;''');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inLineComment3() async {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal comment ^
+      // normal comment 2
+      zoo(z) { } String name;''');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inLineComment4() async {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal comment
+      // normal comment 2^
+      zoo(z) { } String name;''');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inLineDocComment() async {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      /// some dartdoc ^
+      zoo(z) { } String name;''');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inLineDocComment2() async {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      /// some ^dartdoc
+      zoo(z) { } String name;''');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inStarComment() async {
+    // Comment  CompilationUnit
+    addTestSource('/* ^ */ zoo(z) {} String name;');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inStarComment2() async {
+    // Comment  CompilationUnit
+    addTestSource('/*  *^/ zoo(z) {} String name;');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inStarDocComment() async {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('/** ^ */ zoo(z) { } String name; ');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_inStarDocComment2() async {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('/**  *^/ zoo(z) { } String name;');
+    await assertOpType();
+  }
+
+  Future<void> test_functionDeclaration_name1() async {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('const ^Fara();');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_name2() async {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('const F^ara();');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType() async {
+    // CompilationUnit
+    addTestSource('^ zoo(z) { } String name;');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType_afterLineComment() async {
+    // FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      // normal comment
+      ^ zoo(z) {} String name;''');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType_afterLineComment2() async {
+    // FunctionDeclaration  CompilationUnit
+    // TOD(danrubel) left align all test source
+    addTestSource('''
+// normal comment
+^ zoo(z) {} String name;''');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType_afterLineDocComment() async {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      /// some dartdoc
+      ^ zoo(z) { } String name;''');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void>
+      test_functionDeclaration_returnType_afterLineDocComment2() async {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+/// some dartdoc
+^ zoo(z) { } String name;''');
+    // TODO(brianwilkerson) This should have a location of
+    //  'CompilationUnit_declaration' (or 'CompilationUnit_directive')
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType_afterStarComment() async {
+    // CompilationUnit
+    addTestSource('/* */ ^ zoo(z) { } String name;');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType_afterStarComment2() async {
+    // CompilationUnit
+    addTestSource('/* */^ zoo(z) { } String name;');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_functionDeclaration_returnType_afterStarDocComment() async {
+    // FunctionDeclaration  CompilationUnit
+    addTestSource('/** */ ^ zoo(z) { } String name;');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void>
+      test_functionDeclaration_returnType_afterStarDocComment2() async {
+    // FunctionDeclaration  CompilationUnit
+    addTestSource('/** */^ zoo(z) { } String name;');
+    // TODO(brianwilkerson) This should have a location of
+    //  'CompilationUnit_declaration' (or 'CompilationUnit_directive')
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_functionExpression_beforeBody() async {
+    // BlockFunctionBody  FunctionExpression  FunctionDeclaration
+    addTestSource('main()^ { int b = 2; b++; b. }');
+    await assertOpType();
+  }
+
+  Future<void> test_functionExpressionInvocation_beforeArgumentList() async {
+    // ArgumentList  FunctionExpressionInvocation  ExpressionStatement
+    addTestSource('main() { ((x) => x + 7)^(2) }');
+    await assertOpType();
+  }
+
+  Future<void> test_functionTypeAlias_name() async {
+    // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
+    addTestSource('typedef n^ ;');
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_hideCombinator() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addTestSource('''
+import '/testAB.dart' hide ^;
+class X {}
+''');
+    await assertOpType(completionLocation: 'HideCombinator_hiddenName');
+  }
+
+  Future<void> test_ifElement_condition() async {
     addTestSource('''
 main() {
   [if (^)];
 }
 ''');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'IfElement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IfElement_else() async {
+  Future<void> test_ifElement_else() async {
     addTestSource('''
 main() {
   [if (true) 0 else ^];
 }
 ''');
     await assertOpType(
+        completionLocation: 'IfElement_elseElement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_IfElement_then() async {
+  Future<void> test_ifElement_then() async {
     addTestSource('''
 main() {
   [if (true) ^];
 }
 ''');
     await assertOpType(
+        completionLocation: 'IfElement_thenElement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_IfStatement() async {
+  Future<void> test_ifStatement_afterCondition() async {
     // EmptyStatement  IfStatement  Block  BlockFunctionBody
     addTestSource('main(){var a; if (true) ^}');
     await assertOpType(
+        completionLocation: 'IfStatement_thenElement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_IfStatement_condition() async {
+  Future<void> test_ifStatement_condition() async {
     // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
     addTestSource('main(){var a; if (^)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'IfStatement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IfStatement_empty() async {
+  Future<void> test_ifStatement_empty() async {
     // SimpleIdentifier  PrefixIdentifier  IfStatement
     addTestSource('class A {foo() {A a; if (^) something}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'IfStatement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IfStatement_invocation() async {
+  Future<void> test_ifStatement_invocation() async {
     // SimpleIdentifier  PrefixIdentifier  IfStatement
     addTestSource('main() {var a; if (a.^) something}');
     await assertOpType(
-        constructors: true, returnValue: true, typeNames: true, prefixed: true);
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IndexExpression() async {
+  Future<void> test_implementsClause_beginning() async {
+    // ImplementsClause  ClassDeclaration
+    addTestSource('class x implements ^\n{}');
+    await assertOpType(
+        completionLocation: 'ImplementsClause_interface', typeNames: true);
+  }
+
+  Future<void> test_importDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+      import "dart^";
+      main() {}''');
+    await assertOpType();
+  }
+
+  Future<void> test_indexExpression_emptyIndex() async {
     addTestSource('class C {foo(){var f; {var x;} f[^]}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'IndexExpression_index',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IndexExpression2() async {
+  Future<void> test_indexExpression_nonEmptyIndex() async {
     addTestSource('class C {foo(){var f; {var x;} f[T^]}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'IndexExpression_index',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_InstanceCreationExpression_keyword() async {
+  Future<void> test_instanceCreationExpression_afterNew() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addTestSource('class C {foo(){var f; {var x;} new ^}}');
+    await assertOpType(constructors: true);
+  }
+
+  Future<void> test_instanceCreationExpression_keyword() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     addTestSource('class C {foo(){var f; {var x;} new^ }}');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_InstanceCreationExpression_keyword2() async {
+  Future<void> test_instanceCreationExpression_keyword2() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     addTestSource('class C {foo(){var f; {var x;} new^ C();}}');
     await assertOpType(
+        completionLocation: 'Block_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_InterpolationExpression() async {
+  Future<void> test_instanceCreationExpression_trailingStmt() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addTestSource('class C {foo(){var f; {var x;} new ^ int x = 7;}}');
+    await assertOpType(constructors: true);
+  }
+
+  Future<void> test_integerLiteral_inArgumentList() async {
+    addTestSource('main() { print(1^); }');
+    await assertOpType();
+  }
+
+  Future<void> test_integerLiteral_inListLiteral() async {
+    addTestSource('main() { var items = [1^]; }');
+    await assertOpType();
+  }
+
+  Future<void> test_interpolationExpression_afterDollar() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addTestSource('main() {String name; print("hello \$^");}');
-    await assertOpType(constructors: true, returnValue: true);
+    await assertOpType(
+        completionLocation: 'InterpolationExpression_expression',
+        constructors: true,
+        returnValue: true);
   }
 
-  Future<void> test_InterpolationExpression_block() async {
+  Future<void> test_interpolationExpression_block() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addTestSource('main() {String name; print("hello \${n^}");}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'InterpolationExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_InterpolationExpression_prefix_selector() async {
+  Future<void> test_interpolationExpression_prefix_selector() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \${name.^}");}');
     await assertOpType(
-        constructors: true, returnValue: true, typeNames: true, prefixed: true);
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_InterpolationExpression_prefix_target() async {
+  Future<void> test_interpolationExpression_prefix_target() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \${nam^e.length}");}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'InterpolationExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_IsExpression_target() async {
+  Future<void> test_isExpression_target() async {
     // IfStatement  Block  BlockFunctionBody
     addTestSource('main(){var a; if (^ is A)}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'IfStatement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_Literal_list() async {
+  Future<void> test_isExpression_type_empty() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('main() {var x; if (x is ^) { }}');
+    await assertOpType(
+        completionLocation: 'IsExpression_type', typeNames: true);
+  }
+
+  Future<void> test_isExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('main(){var a; if (a is Obj^)}');
+    await assertOpType(
+        completionLocation: 'IsExpression_type', typeNames: true);
+  }
+
+  Future<void> test_literal_list() async {
     // ']'  ListLiteral  ArgumentList  MethodInvocation
     addTestSource('main() {var Some; print([^]);}');
+    // TODO(brianwilkerson) This should have a location of
+    //  'ListLiteral_element'
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  Future<void> test_Literal_list2() async {
+  Future<void> test_literal_list2() async {
     // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
     addTestSource('main() {var Some; print([S^]);}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ListLiteral_element',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_MapLiteralEntry() async {
+  Future<void> test_literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await assertOpType();
+  }
+
+  Future<void> test_mapLiteralEntry_emptyKey() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
     addTestSource('foo = {^');
+    // TODO(brianwilkerson) This should have a location of
+    //  'SetOrMapLiteral_element'
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  Future<void> test_MapLiteralEntry1() async {
+  Future<void> test_mapLiteralEntry_partialKey() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
     addTestSource('foo = {T^');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SetOrMapLiteral_element',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_MapLiteralEntry2() async {
+  Future<void> test_mapLiteralEntry_value() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
     addTestSource('foo = {7:T^};');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'MapLiteralEntry_value',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_MethodInvocation_no_semicolon() async {
+  Future<void> test_methodDeclaration_inClass1() async {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('class Bar {const ^Fara();}');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inClass2() async {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('class Bar {const F^ara();}');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inClass_inLineComment() async {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class C2 {
+  // normal comment ^
+  zoo(z) { } String name;
+}
+''');
+    // TODO(brianwilkerson) This should have a location of
+    //  'ClassDeclaration_member'
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inLineComment2() async {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal ^comment
+        zoo(z) { } String name; }''');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inLineComment3() async {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal comment ^
+        // normal comment 2
+        zoo(z) { } String name; }''');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inLineDocComment() async {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        /// some dartdoc ^
+        zoo(z) { } String name; }''');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inLineDocComment2() async {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        /// some ^dartdoc
+        zoo(z) { } String name; }''');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inStarComment() async {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inStarComment2() async {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inStarDocComment() async {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_inStarDocComment2() async {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
+    await assertOpType();
+  }
+
+  Future<void> test_methodDeclaration_inClass_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {^ zoo(z) { } String name; }');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterLineComment() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class C2 {
+  // normal comment
+  ^ zoo(z) {} String name;
+}
+''');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterLineComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class C2 {
+  // normal comment
+  ^ zoo(z) {} String name;
+}
+''');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterLineDocComment() async {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class C2 {
+  /// some dartdoc
+  ^ zoo(z) { } String name;
+}
+''');
+    // TODO(brianwilkerson) This should have a location of
+    //  'ClassDeclaration_member'
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterLineDocComment2() async {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class C2 {
+  /// some dartdoc
+^ zoo(z) { } String name;
+
+''');
+    // TODO(brianwilkerson) This should have a location of
+    //  'ClassDeclaration_member'
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterStarComment() async {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterStarComment2() async {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
+    await assertOpType(
+        completionLocation: 'ClassDeclaration_member', typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterStarDocComment() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
+    // TODO(brianwilkerson) This should have a location of
+    //  'ClassDeclaration_member'
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void>
+      test_methodDeclaration_inClass_returnType_afterStarDocComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
+    // TODO(brianwilkerson) This should have a location of
+    //  'ClassDeclaration_member'
+    await assertOpType(typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inExtension2_inName() async {
+    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
+    addTestSource('extension E on int {const F^ara();}');
+    await assertOpType(
+        completionLocation: 'ExtensionDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inExtension_beforeName() async {
+    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
+    addTestSource('extension E on int {const ^Fara();}');
+    await assertOpType(
+        completionLocation: 'ExtensionDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inExtension_returnType() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('extension E on int {^ zoo(z) { } String name; }');
+    await assertOpType(
+        completionLocation: 'ExtensionDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inMixin1() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {const ^Fara();}');
+    await assertOpType(
+        completionLocation: 'MixinDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inMixin2() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {const F^ara();}');
+    await assertOpType(
+        completionLocation: 'MixinDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodDeclaration_inMixin_returnType() async {
+    // MixinDeclaration  CompilationUnit
+    addTestSource('mixin M {^ zoo(z) { } String name; }');
+    await assertOpType(
+        completionLocation: 'MixinDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_methodInvocation_no_semicolon() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
       class A implements I {
@@ -822,45 +2017,80 @@
         prefixed: true);
   }
 
-  Future<void> test_PostfixExpression() async {
+  Future<void> test_mixinDeclaration_body() async {
+    // MixinDeclaration  CompilationUnit
+    addTestSource('mixin M {^}');
+    await assertOpType(
+        completionLocation: 'MixinDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_mixinDeclaration_body2() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {^mth() {}}');
+    await assertOpType(
+        completionLocation: 'MixinDeclaration_member', typeNames: true);
+  }
+
+  Future<void> test_namedExpression_beforeName() async {
+    addTestSource('''
+main() { f(3, ^); }
+void f(int a, {int b}) {}
+''');
+    await assertOpType(
+        completionLocation: 'ArgumentList_method_named', namedArgs: true);
+  }
+
+  Future<void> test_onClause_beginning() async {
+    // OnClause  MixinDeclaration
+    addTestSource('mixin M on ^\n{}');
+    await assertOpType(
+        completionLocation: 'OnClause_superclassConstraint', typeNames: true);
+  }
+
+  Future<void> test_postfixExpression_inOperator() async {
     // SimpleIdentifier  PostfixExpression  ForStatement
     addTestSource('int x = 0; main() {ax+^+;}');
+    // TODO(brianwilkerson) This should probably have a location of
+    //  'BinaryExpression_+_rightOperand'
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  Future<void> test_PrefixedIdentifier_class_const() async {
+  Future<void> test_prefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
     addTestSource('main() {A.^}');
     await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
         constructors: true,
+        prefixed: true,
         returnValue: true,
         typeNames: true,
-        voidReturn: true,
-        prefixed: true);
-  }
-
-  Future<void> test_PrefixedIdentifier_class_imported() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('main() {A a; a.^}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
-        voidReturn: true,
-        prefixed: true);
-  }
-
-  Future<void> test_PrefixedIdentifier_prefix() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class X {foo(){A^.bar}}');
-    await assertOpType(
-        constructors: true,
-        typeNames: true,
-        returnValue: true,
         voidReturn: true);
   }
 
-  Future<void> test_PropertyAccess_expression() async {
+  Future<void> test_prefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('main() {A a; a.^}');
+    await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
+        constructors: true,
+        prefixed: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_prefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class X {foo(){A^.bar}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_propertyAccess_expression() async {
     // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
     addTestSource('class A {a() {"hello".to^String().length}}');
     await assertOpType(
@@ -871,103 +2101,301 @@
         prefixed: true);
   }
 
-  Future<void> test_PropertyAccess_selector() async {
+  Future<void> test_propertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addTestSource('main() {.^}');
+    await assertOpType();
+  }
+
+  Future<void> test_propertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpressions
+    addTestSource('main() {.^.}');
+    await assertOpType();
+  }
+
+  Future<void> test_propertyAccess_noTarget3() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpressions
+    addTestSource('main() {..^}');
+    // TODO(brianwilkerson) This should have a location of
+    //  'PropertyAccess_propertyName' (as should several others before this).
+    await assertOpType();
+  }
+
+  Future<void> test_propertyAccess_selector() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
     addTestSource('class A {a() {"hello".length.^}}');
     await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
         constructors: true,
+        prefixed: true,
         returnValue: true,
         typeNames: true,
-        voidReturn: true,
-        prefixed: true);
+        voidReturn: true);
   }
 
-  Future<void> test_ReturnStatement() async {
+  Future<void> test_returnStatement_empty() async {
     // ReturnStatement  Block
     addTestSource('f() { var vvv = 42; return ^ }');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'ReturnStatement_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_SpreadElement() async {
+  Future<void> test_showCombinator() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addTestSource('''
+      import "/testAB.dart" show ^;
+      import "/testCD.dart";
+      class X {}''');
+    await assertOpType(completionLocation: 'ShowCombinator_shownName');
+  }
+
+  Future<void> test_simpleFormalParameter_closure() async {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('mth() { PNGS.sort((String a, Str^) => a.compareTo(b)); }');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_functionType_name() async {
+    addTestSource('void Function(int ^) v;');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_functionType_name_named() async {
+    addTestSource('void Function({int ^}) v;');
+    await assertOpType(typeNames: false, varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_functionType_name_optional() async {
+    addTestSource('void Function([int ^]) v;');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_functionType_type_withName() async {
+    addTestSource('void Function(Str^ name) v;');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_functionType_type_withName2() async {
+    addTestSource('void Function(^ name) v;');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_name_typed() async {
+    addTestSource('f(String ^, int b) {}');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_name_typed_hasName() async {
+    addTestSource('f(String n^, int b) {}');
+    await assertOpType(typeNames: false, varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_name_typed_last() async {
+    addTestSource('f(String ^) {}');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_name_typed_last_hasName() async {
+    addTestSource('f(String n^) {}');
+    await assertOpType(typeNames: false, varNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_named() async {
+    addTestSource('f(^ name) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_optionalNamed() async {
+    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
+    addTestSource('m({Str^}) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_optionalPositional() async {
+    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
+    addTestSource('m([Str^]) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_withName() async {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(Str^ name) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_withoutName1() async {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(Str^) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_withoutName2() async {
+    // FormalParameterList
+    addTestSource('m(^) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_type_withoutName3() async {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(int first, Str^) {}');
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
+  }
+
+  Future<void> test_simpleFormalParameter_untyped() async {
+    addTestSource('main(final ^) {}');
+    // TODO(brianwilkerson) This should have a location of
+    //  'FormalParameterList_parameter'
+    await assertOpType(typeNames: true, varNames: false);
+  }
+
+  Future<void> test_spreadElement_emptyExpression() async {
     addTestSource(r'''
 main() {
   [...^];
 }
 ''');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SpreadElement_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_SwitchCase_between() async {
+  Future<void> test_switchCase_before() async {
+    // SwitchCase  SwitchStatement  Block
+    addTestSource('main() {switch(k) {^case 1:}}');
+    await assertOpType();
+  }
+
+  Future<void> test_switchCase_between() async {
     // SwitchCase  SwitchStatement  Block
     addTestSource('main() {switch(k) {case 1: ^ case 2: return}}');
     await assertOpType(
+        completionLocation: 'SwitchMember_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_SwitchCase_expression1() async {
+  Future<void> test_switchCase_expression1() async {
     // SimpleIdentifier  SwitchCase  SwitchStatement
     addTestSource('''m() {switch (x) {case ^D: return;}}''');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SwitchCase_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_SwitchCase_expression2() async {
+  Future<void> test_switchCase_expression2() async {
     // SimpleIdentifier  SwitchCase  SwitchStatement
     addTestSource('''m() {switch (x) {case ^}}''');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SwitchCase_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_SwitchDefault_between() async {
+  Future<void> test_switchDefault_before() async {
+    // SwitchDefault  SwitchStatement  Block
+    addTestSource('main() {switch(k) { ^ default: return;}}');
+    await assertOpType();
+  }
+
+  Future<void> test_switchDefault_between() async {
     // SwitchDefault  SwitchStatement  Block
     addTestSource('main() {switch(k) {case 1: ^ default: return;}}');
     await assertOpType(
+        completionLocation: 'SwitchMember_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_SwitchStatement_body_end() async {
+  Future<void> test_switchStatement_body_empty() async {
+    // Token('}')  SwitchStatement  Block
+    addTestSource('main() {switch(k) {^}}');
+    await assertOpType();
+  }
+
+  Future<void> test_switchStatement_body_end() async {
     // Token('}')  SwitchStatement  Block
     addTestSource('main() {switch(k) {case 1:^}}');
     await assertOpType(
+        completionLocation: 'SwitchMember_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_SwitchStatement_body_end2() async {
+  Future<void> test_switchStatement_body_end2() async {
     addTestSource('main() {switch(k) {case 1:as^}}');
+    // TODO(brianwilkerson) This should have a location of
+    //  'SwitchMember_statement'
     await assertOpType(
+        completionLocation: 'SwitchCase_statement',
         constructors: true,
         returnValue: true,
         typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_SwitchStatement_expression1() async {
+  Future<void> test_switchStatement_expression1() async {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(^k) {case 1:{}}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SwitchStatement_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_SwitchStatement_expression2() async {
+  Future<void> test_switchStatement_expression2() async {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(k^) {case 1:{}}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SwitchStatement_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-//
-  Future<void> test_SwitchStatement_expression_empty() async {
+  Future<void> test_switchStatement_expression_empty() async {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(^) {case 1:{}}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
+    await assertOpType(
+        completionLocation: 'SwitchStatement_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_ThisExpression_block() async {
+  Future<void> test_thisExpression_block() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
       class A implements I {
@@ -982,1041 +2410,21 @@
         prefixed: true);
   }
 
-  Future<void> test_ThisExpression_constructor() async {
+  Future<void> test_thisExpression_constructor() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addTestSource('''
       class A implements I {
         A() {this.^}
       }''');
     await assertOpType(
+        completionLocation: 'PropertyAccess_propertyName',
         constructors: true,
+        prefixed: true,
         returnValue: true,
-        voidReturn: true,
-        prefixed: true);
-  }
-
-  Future<void> test_ThrowExpression() async {
-    // SimpleIdentifier  ThrowExpression  ExpressionStatement
-    addTestSource('main() {throw ^;}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_VariableDeclarationStatement_afterSemicolon() async {
-    // VariableDeclarationStatement  Block  BlockFunctionBody
-    addTestSource('class A {var a; x() {var b;^}}');
-    await assertOpType(
-        constructors: true,
-        returnValue: true,
-        typeNames: true,
         voidReturn: true);
   }
 
-  Future<void> test_VariableDeclarationStatement_RHS() async {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addTestSource('class C {bar(){var f; {var x;} var e = ^}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_VariableDeclarationStatement_RHS_missing_semicolon() async {
-    // VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addTestSource('class C {bar(){var f; {var x;} var e = ^ var g}}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  Future<void> test_WhileStatement() async {
-    // SimpleIdentifier  WhileStatement  Block
-    addTestSource('mth() { while (b^) {} }}');
-    await assertOpType(constructors: true, returnValue: true, typeNames: true);
-  }
-
-  @failingTest
-  Future<void> test_WithClause() async {
-    // WithClause  ClassDeclaration
-    addTestSource('class x extends Object with ^\n{}');
-    await assertOpType(constructors: true, typeNames: true);
-  }
-}
-
-@reflectiveTest
-class OpTypeTest extends OpTypeTestCommon {
-  Future<void> test_ArgumentList_constructor_named_resolved_1_0() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
-    addTestSource(
-      'main() { new A.b(^); }'
-      'class A{ A.b({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_constructor_named_resolved_1_1() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addTestSource(
-      'main() { new A.b(o^); }'
-      'class A { A.b({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_constructor_resolved_1_0() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
-    addTestSource(
-      'main() { new A(^); }'
-      'class A{ A({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_constructor_resolved_1_1() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addTestSource(
-      'main() { new A(o^); }'
-      'class A { A({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_factory_named_resolved_1_0() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
-    addTestSource(
-      'main() { new A.b(^); }'
-      'class A{ factory A.b({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_factory_named_resolved_1_1() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addTestSource(
-      'main() { new A.b(o^); }'
-      'class A { factory A.b({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_factory_resolved_1_0() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
-    addTestSource(
-      'main() { new A(^); }'
-      'class A{ factory A({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_factory_resolved_1_1() async {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addTestSource(
-      'main() { new A(o^); }'
-      'class A { factory A({one, two}) {} }',
-    );
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_method_resolved_1_0() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('main() { foo(^);} foo({one, two}) {}');
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_method_resolved_1_1() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('main() { foo(o^);} foo({one, two}) {}');
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_ArgumentList_resolved_2_0() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('void main() {int.parse("16", ^)}');
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_AsExpression() async {
-    // SimpleIdentifier  TypeName  AsExpression
-    addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_AsIdentifier2() async {
-    addTestSource('class A {var asdf; foo() {A as^}');
-    await assertOpType();
-  }
-
-  Future<void> test_AssignmentExpression_name() async {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int ^b = 1;}');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_Block_catch_1a() async {
-    // '}'  Block  BlockFunctionBody  FunctionExpression
-    addTestSource('main() {try {} ^}');
-    // Only return 'on', 'catch', and 'finally' keywords
-    await assertOpType();
-  }
-
-  Future<void> test_Block_catch_1b() async {
-    // [ExpressionStatement 'c']  Block  BlockFunctionBody
-    addTestSource('main() {try {} c^}');
-    // Only return 'on', 'catch', and 'finally' keywords
-    await assertOpType();
-  }
-
-  Future<void> test_Block_catch_1c() async {
-    // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
-    addTestSource('main() {try {} ^;}');
-    // Only return 'on', 'catch', and 'finally' keywords
-    await assertOpType();
-  }
-
-  Future<void> test_Block_catch_1d() async {
-    // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
-    addTestSource('main() {try {} ^ Foo foo;}');
-    // Only return 'on', 'catch', and 'finally' keywords
-    await assertOpType();
-  }
-
-  Future<void> test_Block_final() async {
-    addTestSource('main() {final ^}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Block_final2() async {
-    addTestSource('main() {final S^ v;}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Block_final3() async {
-    addTestSource('main() {final ^ v;}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Block_final_final() async {
-    addTestSource('main() {final ^ final S x;}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Block_final_final2() async {
-    addTestSource('main() {final S^ final S x;}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Break_after_label() async {
-    addTestSource('main() { foo: while (true) { break foo ^ ; } }');
-    await assertOpType(/* No valid completions */);
-  }
-
-  Future<void> test_Break_before_label() async {
-    addTestSource('main() { foo: while (true) { break ^ foo; } }');
-    await assertOpType(statementLabel: true);
-  }
-
-  Future<void> test_Break_no_label() async {
-    addTestSource('main() { foo: while (true) { break ^; } }');
-    await assertOpType(statementLabel: true);
-  }
-
-  Future<void> test_catch_4a1() async {
-    addTestSource('main() {try {} ^ on SomeException {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_catch_4a2() async {
-    addTestSource('main() {try {} c^ on SomeException {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_catch_4b1() async {
-    addTestSource('main() {try {} ^ catch (e) {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_catch_4b2() async {
-    addTestSource('main() {try {} c^ catch (e) {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_catch_4c1() async {
-    addTestSource('main() {try {} ^ finally {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_catch_4c2() async {
-    addTestSource('main() {try {} c^ finally {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_catch_5a() async {
-    addTestSource('main() {try {} on ^ finally {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_catch_5b() async {
-    addTestSource('main() {try {} on E^ finally {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_CatchClause_onType() async {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^ {}}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_CatchClause_onType_noBrackets() async {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ClassDeclaration_body() async {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('@deprecated class A {^}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ClassDeclaration_body2() async {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
-    addTestSource('@deprecated class A {^mth() {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Combinator_hide() async {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addTestSource('''
-      import "/testAB.dart" hide ^;
-      class X {}''');
-    await assertOpType();
-  }
-
-  Future<void> test_Combinator_show() async {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addTestSource('''
-      import "/testAB.dart" show ^;
-      import "/testCD.dart";
-      class X {}''');
-    await assertOpType();
-  }
-
-  Future<void> test_ConstructorName() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new X.^}');
-    await assertOpType(constructors: true, prefixed: true);
-  }
-
-  Future<void> test_ConstructorName_name_resolved() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new Str^ing.fromCharCodes([]);}');
-    await assertOpType(constructors: true);
-  }
-
-  Future<void> test_ConstructorName_nameAndPrefix_resolved() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-import 'dart:core' as core;
-main() {new core.String.from^CharCodes([]);}
-''');
-    await assertOpType(constructors: true, prefixed: true);
-  }
-
-  Future<void> test_ConstructorName_resolved() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new String.fr^omCharCodes([]);}');
-    await assertOpType(constructors: true, prefixed: true);
-  }
-
-  Future<void> test_ConstructorName_unresolved() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new String.fr^omCharCodes([]);}');
-    await assertOpType(constructors: true, prefixed: true);
-  }
-
-  Future<void> test_Continue_after_label() async {
-    addTestSource('main() { foo: while (true) { continue foo ^ ; } }');
-    await assertOpType(/* No valid completions */);
-  }
-
-  Future<void> test_Continue_before_label() async {
-    addTestSource('main() { foo: while (true) { continue ^ foo; } }');
-    await assertOpType(statementLabel: true, caseLabel: true);
-  }
-
-  Future<void> test_Continue_no_label() async {
-    addTestSource('main() { foo: while (true) { continue ^; } }');
-    await assertOpType(statementLabel: true, caseLabel: true);
-  }
-
-  Future<void> test_DoubleLiteral() async {
-    addTestSource('main() { print(1.2^); }');
-    await assertOpType();
-  }
-
-  Future<void> test_ExpressionStatement_name() async {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class C {a() {C ^}}');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_ExpressionStatement_name_semicolon() async {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class C {a() {C ^;}}');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_ExpressionStatement_prefixed_name() async {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class C {a() {x.Y ^}}');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_ExpressionStatement_prefixed_name_semicolon() async {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class C {a() {x.Y ^;}}');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_ExtendsClause() async {
-    // ExtendsClause  ClassDeclaration
-    addTestSource('class x extends ^\n{}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FieldDeclaration_name_typed() async {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addTestSource('class C {A ^}');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_FieldDeclaration_name_var() async {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addTestSource('class C {var ^}');
-    await assertOpType();
-  }
-
-  Future<void> test_ForEachStatement_loopVariable() async {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ in args) {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ForEachStatement_loopVariable_name() async {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (String ^ in args) {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_ForEachStatement_loopVariable_name2() async {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (String f^ in args) {}}');
-    await assertOpType();
-  }
-
-  Future<void> test_ForEachStatement_loopVariable_type() async {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ foo in args) {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ForEachStatement_loopVariable_type2() async {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (S^ foo in args) {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FormalParameterList() async {
-    // FormalParameterList MethodDeclaration
-    addTestSource('class A {a(^) { }}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ForStatement_initializer() async {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {List a; for (^)}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ForStatement_initializer_inKeyword() async {
-    addTestSource('main() { for (var v i^) }');
-    await assertOpType();
-  }
-
-  Future<void> test_ForStatement_initializer_type() async {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {List a; for (i^ v = 0;)}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_ForStatement_initializer_variableNameEmpty_afterType() async {
-    addTestSource('main() { for (String ^) }');
-    await assertOpType(varNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration1() async {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('const ^Fara();');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration2() async {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('const F^ara();');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_inLineComment() async {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal comment ^
-      zoo(z) { } String name;''');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inLineComment2() async {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal ^comment
-      zoo(z) { } String name;''');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inLineComment3() async {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal comment ^
-      // normal comment 2
-      zoo(z) { } String name;''');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inLineComment4() async {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal comment
-      // normal comment 2^
-      zoo(z) { } String name;''');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inLineDocComment() async {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      /// some dartdoc ^
-      zoo(z) { } String name;''');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inLineDocComment2() async {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      /// some ^dartdoc
-      zoo(z) { } String name;''');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inStarComment() async {
-    // Comment  CompilationUnit
-    addTestSource('/* ^ */ zoo(z) {} String name;');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inStarComment2() async {
-    // Comment  CompilationUnit
-    addTestSource('/*  *^/ zoo(z) {} String name;');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inStarDocComment() async {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('/** ^ */ zoo(z) { } String name; ');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_inStarDocComment2() async {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('/**  *^/ zoo(z) { } String name;');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionDeclaration_returnType() async {
-    // CompilationUnit
-    addTestSource('^ zoo(z) { } String name;');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_returnType_afterLineComment() async {
-    // FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      // normal comment
-      ^ zoo(z) {} String name;''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_returnType_afterLineComment2() async {
-    // FunctionDeclaration  CompilationUnit
-    // TOD(danrubel) left align all test source
-    addTestSource('''
-// normal comment
-^ zoo(z) {} String name;''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_returnType_afterLineDocComment() async {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      /// some dartdoc
-      ^ zoo(z) { } String name;''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_FunctionDeclaration_returnType_afterLineDocComment2() async {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-/// some dartdoc
-^ zoo(z) { } String name;''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_returnType_afterStarComment() async {
-    // CompilationUnit
-    addTestSource('/* */ ^ zoo(z) { } String name;');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_returnType_afterStarComment2() async {
-    // CompilationUnit
-    addTestSource('/* */^ zoo(z) { } String name;');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionDeclaration_returnType_afterStarDocComment() async {
-    // FunctionDeclaration  CompilationUnit
-    addTestSource('/** */ ^ zoo(z) { } String name;');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_FunctionDeclaration_returnType_afterStarDocComment2() async {
-    // FunctionDeclaration  CompilationUnit
-    addTestSource('/** */^ zoo(z) { } String name;');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_FunctionExpression() async {
-    // BlockFunctionBody  FunctionExpression  FunctionDeclaration
-    addTestSource('main()^ { int b = 2; b++; b. }');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionExpressionInvocation() async {
-    // ArgumentList  FunctionExpressionInvocation  ExpressionStatement
-    addTestSource('main() { ((x) => x + 7)^(2) }');
-    await assertOpType();
-  }
-
-  Future<void> test_FunctionTypeAlias() async {
-    // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
-    addTestSource('typedef n^ ;');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ImplementsClause() async {
-    // ImplementsClause  ClassDeclaration
-    addTestSource('class x implements ^\n{}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_ImportDirective_dart() async {
-    // SimpleStringLiteral  ImportDirective
-    addTestSource('''
-      import "dart^";
-      main() {}''');
-    await assertOpType();
-  }
-
-  Future<void> test_InstanceCreationExpression() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addTestSource('class C {foo(){var f; {var x;} new ^}}');
-    await assertOpType(constructors: true);
-  }
-
-  Future<void> test_InstanceCreationExpression_trailingStmt() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addTestSource('class C {foo(){var f; {var x;} new ^ int x = 7;}}');
-    await assertOpType(constructors: true);
-  }
-
-  Future<void> test_IntegerLiteral_inArgumentList() async {
-    addTestSource('main() { print(1^); }');
-    await assertOpType();
-  }
-
-  Future<void> test_IntegerLiteral_inListLiteral() async {
-    addTestSource('main() { var items = [1^]; }');
-    await assertOpType();
-  }
-
-  Future<void> test_IsExpression() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('main() {var x; if (x is ^) { }}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_IsExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('main(){var a; if (a is Obj^)}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_Literal_string() async {
-    // SimpleStringLiteral  ExpressionStatement  Block
-    addTestSource('class A {a() {"hel^lo"}}');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass1() async {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
-    addTestSource('class Bar {const ^Fara();}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_MethodDeclaration_inClass2() async {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
-    addTestSource('class Bar {const F^ara();}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inLineComment() async {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment ^
-        zoo(z) { } String name; }''');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inLineComment2() async {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal ^comment
-        zoo(z) { } String name; }''');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inLineComment3() async {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment ^
-        // normal comment 2
-        zoo(z) { } String name; }''');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inLineDocComment() async {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        /// some dartdoc ^
-        zoo(z) { } String name; }''');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inLineDocComment2() async {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        /// some ^dartdoc
-        zoo(z) { } String name; }''');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inStarComment() async {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inStarComment2() async {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inStarDocComment() async {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_inStarDocComment2() async {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
-    await assertOpType();
-  }
-
-  Future<void> test_MethodDeclaration_inClass_returnType() async {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterLineComment() async {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment
-        ^ zoo(z) {} String name;}''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterLineComment2() async {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    // TOD(danrubel) left align all test source
-    addTestSource('''
-class C2 {
-  // normal comment
-^ zoo(z) {} String name;}''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterLineDocComment() async {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        /// some dartdoc
-        ^ zoo(z) { } String name; }''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterLineDocComment2() async {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-class C2 {
-  /// some dartdoc
-^ zoo(z) { } String name; }''');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterStarComment() async {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterStarComment2() async {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterStarDocComment() async {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void>
-      test_MethodDeclaration_inClass_returnType_afterStarDocComment2() async {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_methodDeclaration_inMixin1() async {
-    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
-    addTestSource('mixin M {const ^Fara();}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_methodDeclaration_inMixin2() async {
-    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
-    addTestSource('mixin M {const F^ara();}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_methodDeclaration_inMixin_returnType() async {
-    // MixinDeclaration  CompilationUnit
-    addTestSource('mixin M {^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_mixinDeclaration_body() async {
-    // MixinDeclaration  CompilationUnit
-    addTestSource('mixin M {^}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_mixinDeclaration_body2() async {
-    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
-    addTestSource('mixin M {^mth() {}}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_NamedExpression() async {
-    addTestSource('''
-main() { f(3, ^); }
-void f(int a, {int b}) {}
-''');
-    await assertOpType(namedArgs: true);
-  }
-
-  Future<void> test_OnClause() async {
-    // OnClause  MixinDeclaration
-    addTestSource('mixin M on ^\n{}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_PropertyAccess_noTarget() async {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestSource('main() {.^}');
-    await assertOpType();
-  }
-
-  Future<void> test_PropertyAccess_noTarget2() async {
-    // SimpleIdentifier  PropertyAccess  CascadeExpressions
-    addTestSource('main() {.^.}');
-    await assertOpType();
-  }
-
-  Future<void> test_PropertyAccess_noTarget3() async {
-    // SimpleIdentifier  PropertyAccess  CascadeExpressions
-    addTestSource('main() {..^}');
-    await assertOpType();
-  }
-
-  Future<void> test_SimpleFormalParameter_closure() async {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('mth() { PNGS.sort((String a, Str^) => a.compareTo(b)); }');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_functionType_name() async {
-    addTestSource('void Function(int ^) v;');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_functionType_name_named() async {
-    addTestSource('void Function({int ^}) v;');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_functionType_name_optional() async {
-    addTestSource('void Function([int ^]) v;');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_functionType_type_withName() async {
-    addTestSource('void Function(Str^ name) v;');
-    await assertOpType(typeNames: true, varNames: false);
-  }
-
-  Future<void> test_SimpleFormalParameter_functionType_type_withName2() async {
-    addTestSource('void Function(^ name) v;');
-    await assertOpType(typeNames: true, varNames: false);
-  }
-
-  Future<void> test_SimpleFormalParameter_name_typed() async {
-    addTestSource('f(String ^, int b) {}');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_name_typed_hasName() async {
-    addTestSource('f(String n^, int b) {}');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_name_typed_last() async {
-    addTestSource('f(String ^) {}');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_name_typed_last_hasName() async {
-    addTestSource('f(String n^) {}');
-    await assertOpType(typeNames: false, varNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_named() async {
-    addTestSource('f(^ name) {}');
-    await assertOpType(typeNames: true, varNames: false);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_optionalNamed() async {
-    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
-    addTestSource('m({Str^}) {}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_optionalPositional() async {
-    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
-    addTestSource('m([Str^]) {}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_withName() async {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(Str^ name) {}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_withoutName1() async {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(Str^) {}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_withoutName2() async {
-    // FormalParameterList
-    addTestSource('m(^) {}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_type_withoutName3() async {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(int first, Str^) {}');
-    await assertOpType(typeNames: true);
-  }
-
-  Future<void> test_SimpleFormalParameter_untyped() async {
-    addTestSource('main(final ^) {}');
-    await assertOpType(typeNames: true, varNames: false);
-  }
-
-  Future<void> test_SwitchCase_before() async {
-    // SwitchCase  SwitchStatement  Block
-    addTestSource('main() {switch(k) {^case 1:}}');
-    await assertOpType();
-  }
-
-  Future<void> test_SwitchDefault_before() async {
-    // SwitchDefault  SwitchStatement  Block
-    addTestSource('main() {switch(k) { ^ default: return;}}');
-    await assertOpType();
-  }
-
-  Future<void> test_SwitchStatement_body_empty() async {
-    // Token('}')  SwitchStatement  Block
-    addTestSource('main() {switch(k) {^}}');
-    await assertOpType();
-  }
-
-  Future<void> test_ThisExpression_constructor_param() async {
+  Future<void> test_thisExpression_constructor_param() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
       class A implements I {
@@ -2025,7 +2433,7 @@
     await assertOpType(prefixed: true);
   }
 
-  Future<void> test_ThisExpression_constructor_param2() async {
+  Future<void> test_thisExpression_constructor_param2() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
       class A implements I {
@@ -2034,7 +2442,7 @@
     await assertOpType(prefixed: true);
   }
 
-  Future<void> test_ThisExpression_constructor_param3() async {
+  Future<void> test_thisExpression_constructor_param3() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
       class A implements I {
@@ -2043,192 +2451,365 @@
     await assertOpType(prefixed: true);
   }
 
-  Future<void> test_ThisExpression_constructor_param4() async {
+  Future<void> test_thisExpression_constructor_param4() async {
     // FieldFormalParameter  FormalParameterList  ConstructorDeclaration
     addTestSource('''
       class A implements I {
         A(Str^ this.foo) {}
       }''');
-    await assertOpType(typeNames: true);
+    await assertOpType(
+        completionLocation: 'FormalParameterList_parameter', typeNames: true);
   }
 
-  Future<void> test_TopLevelVariableDeclaration_typed_name() async {
+  Future<void> test_throwExpression_empty() async {
+    // SimpleIdentifier  ThrowExpression  ExpressionStatement
+    addTestSource('main() {throw ^;}');
+    await assertOpType(
+        completionLocation: 'ThrowExpression_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_topLevelVariableDeclaration_type() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('^ foo;');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_topLevelVariableDeclaration_type_no_semicolon() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('^ foo');
+    await assertOpType(
+        completionLocation: 'CompilationUnit_declaration', typeNames: true);
+  }
+
+  Future<void> test_topLevelVariableDeclaration_typed_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     // _OpTypeAstVisitor.visitVariableDeclarationList is executed with this
     // source, but _OpTypeAstVisitor.visitTopLevelVariableDeclaration is called
-    // for test_TopLevelVariableDeclaration_typed_name_semicolon
+    // for test_topLevelVariableDeclaration_typed_name_semicolon
     addTestSource('class A {} B ^');
     await assertOpType(varNames: true);
   }
 
-  Future<void> test_TopLevelVariableDeclaration_typed_name_semicolon() async {
+  Future<void> test_topLevelVariableDeclaration_typed_name_semicolon() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
-    // See comment in test_TopLevelVariableDeclaration_typed_name
+    // See comment in test_topLevelVariableDeclaration_typed_name
     addTestSource('class A {} B ^;');
     await assertOpType(varNames: true);
   }
 
-  Future<void> test_TopLevelVariableDeclaration_untyped_name() async {
+  Future<void> test_topLevelVariableDeclaration_untyped_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     addTestSource('class A {} var ^');
     await assertOpType();
   }
 
-  Future<void> test_TypeArgumentList() async {
+  Future<void> test_tryStatement_catch_1a() async {
+    // '}'  Block  BlockFunctionBody  FunctionExpression
+    addTestSource('main() {try {} ^}');
+    // Only return 'on', 'catch', and 'finally' keywords
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_1b() async {
+    // [ExpressionStatement 'c']  Block  BlockFunctionBody
+    addTestSource('main() {try {} c^}');
+    // Only return 'on', 'catch', and 'finally' keywords
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_1c() async {
+    // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
+    addTestSource('main() {try {} ^;}');
+    // Only return 'on', 'catch', and 'finally' keywords
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_1d() async {
+    // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
+    addTestSource('main() {try {} ^ Foo foo;}');
+    // Only return 'on', 'catch', and 'finally' keywords
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_2a() async {
+    // '}'  Block  BlockFunctionBody  FunctionExpression
+    addTestSource('main() {try {} catch () {} ^}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_2b() async {
+    // [ExpressionStatement 'c']  Block  BlockFunctionBody
+    addTestSource('main() {try {} catch () {} c^}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_2c() async {
+    // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
+    addTestSource('main() {try {} catch () {} ^;}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_2d() async {
+    // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
+    addTestSource('main() {try {} catch () {} ^ Foo foo;}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_3a() async {
+    // '}'  Block  BlockFunctionBody  FunctionExpression
+    addTestSource('main() {try {} finally {} ^}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_3b() async {
+    // [ExpressionStatement 'c']  Block  BlockFunctionBody
+    addTestSource('main() {try {} finally {} c^}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_3c() async {
+    // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
+    addTestSource('main() {try {} finally {} ^;}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_3d() async {
+    // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
+    addTestSource('main() {try {} finally {} ^ Foo foo;}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catch_4a1() async {
+    addTestSource('main() {try {} ^ on SomeException {}}');
+    await assertOpType();
+  }
+
+  Future<void> test_tryStatement_catch_4a2() async {
+    addTestSource('main() {try {} c^ on SomeException {}}');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_4b1() async {
+    addTestSource('main() {try {} ^ catch (e) {}}');
+    await assertOpType();
+  }
+
+  Future<void> test_tryStatement_catch_4b2() async {
+    addTestSource('main() {try {} c^ catch (e) {}}');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_4c1() async {
+    addTestSource('main() {try {} ^ finally {}}');
+    await assertOpType();
+  }
+
+  Future<void> test_tryStatement_catch_4c2() async {
+    addTestSource('main() {try {} c^ finally {}}');
+    // TODO(brianwilkerson) This should not have a location.
+    await assertOpType(completionLocation: 'Block_statement');
+  }
+
+  Future<void> test_tryStatement_catch_5a() async {
+    addTestSource('main() {try {} on ^ finally {}}');
+    await assertOpType(
+        completionLocation: 'CatchClause_exceptionType', typeNames: true);
+  }
+
+  Future<void> test_tryStatement_catch_5b() async {
+    addTestSource('main() {try {} on E^ finally {}}');
+    await assertOpType(
+        completionLocation: 'CatchClause_exceptionType', typeNames: true);
+  }
+
+  Future<void> test_tryStatement_catchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await assertOpType(
+        completionLocation: 'CatchClause_exceptionType', typeNames: true);
+  }
+
+  Future<void> test_tryStatement_catchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await assertOpType(
+        completionLocation: 'CatchClause_exceptionType', typeNames: true);
+  }
+
+  Future<void> test_tryStatement_catchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_tryStatement_catchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_typeArgumentList_empty() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
     addTestSource('main() { C<^> c; }');
-    await assertOpType(typeNames: true);
+    await assertOpType(
+        completionLocation: 'TypeArgumentList_argument', typeNames: true);
   }
 
-  Future<void> test_TypeArgumentList2() async {
+  Future<void> test_typeArgumentList_partial() async {
     // TypeName  TypeArgumentList  TypeName
     addTestSource('main() { C<C^> c; }');
-    await assertOpType(typeNames: true);
+    await assertOpType(
+        completionLocation: 'TypeArgumentList_argument', typeNames: true);
   }
 
-  Future<void> test_TypeParameter() async {
+  Future<void> test_typeParameter_beforeType() async {
     // SimpleIdentifier  TypeParameter  TypeParameterList
     addTestSource('class tezetst <String, ^List> {}');
     await assertOpType();
   }
 
-  Future<void> test_TypeParameterList_empty() async {
+  Future<void> test_typeParameterList_empty() async {
     // SimpleIdentifier  TypeParameter  TypeParameterList
     addTestSource('class tezetst <^> {}');
     await assertOpType();
   }
 
-  Future<void> test_VariableDeclaration_name() async {
+  Future<void> test_variableDeclaration_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('main() {var ^}');
     await assertOpType();
   }
 
-  Future<void> test_VariableDeclaration_name_hasSome_parameterizedType() async {
+  Future<void> test_variableDeclaration_name_hasSome_parameterizedType() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('main() {List<int> m^}');
     await assertOpType(varNames: true);
   }
 
-  Future<void> test_VariableDeclaration_name_hasSome_simpleType() async {
+  Future<void> test_variableDeclaration_name_hasSome_simpleType() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('main() {String m^}');
     await assertOpType(varNames: true);
   }
 
-  Future<void> test_VariableDeclarationList_final() async {
+  Future<void> test_variableDeclarationList_final() async {
     // VariableDeclarationList  VariableDeclarationStatement  Block
     addTestSource('main() {final ^}');
-    await assertOpType(typeNames: true);
-  }
-}
-
-/// Common test methods to Dart1/Dart2 versions of OpType tests.
-class OpTypeTestCommon extends AbstractContextTest {
-  String testPath;
-  int completionOffset;
-  OpType visitor;
-
-  void addTestSource(String content) {
-    completionOffset = content.indexOf('^');
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    var nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    content = content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1);
-    super.addSource(testPath, content);
-  }
-
-  Future<void> assertOpType(
-      {bool caseLabel = false,
-      bool constructors = false,
-      bool namedArgs = false,
-      bool prefixed = false,
-      bool returnValue = false,
-      bool statementLabel = false,
-      bool staticMethodBody = false,
-      bool typeNames = false,
-      bool varNames = false,
-      bool voidReturn = false,
-      CompletionSuggestionKind kind =
-          CompletionSuggestionKind.INVOCATION}) async {
-    var resolvedUnit = await driver.getResult(testPath);
-
-    var completionTarget =
-        CompletionTarget.forOffset(resolvedUnit.unit, completionOffset);
-    visitor = OpType.forCompletion(completionTarget, completionOffset);
-
-    expect(visitor.includeCaseLabelSuggestions, caseLabel, reason: 'caseLabel');
-    expect(visitor.includeConstructorSuggestions, constructors,
-        reason: 'constructors');
-    expect(visitor.includeNamedArgumentSuggestions, namedArgs,
-        reason: 'namedArgs');
-    expect(visitor.includeReturnValueSuggestions, returnValue,
-        reason: 'returnValue');
-    expect(visitor.includeStatementLabelSuggestions, statementLabel,
-        reason: 'statementLabel');
-    expect(visitor.includeTypeNameSuggestions, typeNames, reason: 'typeNames');
-    expect(visitor.includeVarNameSuggestions, varNames, reason: 'varNames');
-    expect(visitor.includeVoidReturnSuggestions, voidReturn,
-        reason: 'voidReturn');
-    expect(visitor.inStaticMethodBody, staticMethodBody,
-        reason: 'staticMethodBody');
-    expect(visitor.isPrefixed, prefixed, reason: 'prefixed');
-    expect(visitor.suggestKind, kind, reason: 'suggestion kind');
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    testPath = convertPath('/completionTest.dart');
-  }
-}
-
-@reflectiveTest
-class OpTypeTestWithExtensionMethods extends OpTypeTestCommon {
-  @override
-  void setUp() {
-    createAnalysisOptionsFile(
-      experiments: [
-        EnableString.extension_methods,
-      ],
-    );
-    super.setUp();
-  }
-
-  Future<void> test_extensionDeclaration_body() async {
-    // ExtensionDeclaration  CompilationUnit
-    addTestSource('extension E on int {^}');
+    // TODO(brianwilkerson) This should probably have a location.
     await assertOpType(typeNames: true);
   }
 
-  Future<void> test_extensionDeclaration_body2() async {
-    // SimpleIdentifier  MethodDeclaration  ExtensionDeclaration
-    addTestSource('extension E on int {^mth() {}}');
-    await assertOpType(typeNames: true);
+  Future<void> test_variableDeclarationStatement_afterSemicolon() async {
+    // VariableDeclarationStatement  Block  BlockFunctionBody
+    addTestSource('class A {var a; x() {var b;^}}');
+    await assertOpType(
+        completionLocation: 'Block_statement',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
   }
 
-  Future<void> test_methodDeclaration_inExtension1() async {
-    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
-    addTestSource('extension E on int {const ^Fara();}');
-    await assertOpType(typeNames: true);
+  Future<void> test_variableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addTestSource('class C {bar(){var f; {var x;} var e = ^}}');
+    await assertOpType(
+        completionLocation: 'VariableDeclaration_initializer',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_methodDeclaration_inExtension2() async {
-    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
-    addTestSource('extension E on int {const F^ara();}');
-    await assertOpType(typeNames: true);
+  Future<void> test_variableDeclarationStatement_RHS_missingSemicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addTestSource('class C {bar(){var f; {var x;} var e = ^ var g}}');
+    await assertOpType(
+        completionLocation: 'VariableDeclaration_initializer',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
   }
 
-  Future<void> test_methodDeclaration_inExtension_returnType() async {
-    // ExtensionDeclaration  CompilationUnit
-    addTestSource('extension E on int {^ zoo(z) { } String name; }');
-    await assertOpType(typeNames: true);
+  Future<void> test_whileStatement_expression() async {
+    // SimpleIdentifier  WhileStatement  Block
+    addTestSource('mth() { while (b^) {} }}');
+    await assertOpType(
+        completionLocation: 'WhileStatement_condition',
+        constructors: true,
+        returnValue: true,
+        typeNames: true);
+  }
+
+  Future<void> test_withClause_empty() async {
+    // WithClause  ClassDeclaration
+    addTestSource('class x extends Object with ^\n{}');
+    await assertOpType(
+        completionLocation: 'WithClause_mixinType', typeNames: true);
   }
 }
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index d5bcc08..1f3acb1 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -107,7 +107,10 @@
     [bool check(T error) = _pass, String reason = ""]) {
   var type = "";
   if (T != dynamic && T != Object) type = "<$T>";
-  var header = "asyncExpectThrows$type(${reason ?? ''}):";
+  // Handle null being passed in from legacy code while also avoiding producing
+  // an unnecessary null check warning here.
+  if ((reason as dynamic) == null) reason = "";
+  var header = "asyncExpectThrows$type(${reason}):";
 
   // TODO(rnystrom): It might useful to validate that T is not bound to
   // ExpectException since that won't work.
@@ -124,7 +127,7 @@
   }
 
   asyncStart();
-  result.then((_) {
+  result.then<Null>((_) {
     throw ExpectException("$header Did not throw.");
   }).catchError((error, stack) {
     // A test failure doesn't count as throwing.
diff --git a/pkg/async_helper/lib/async_minitest.dart b/pkg/async_helper/lib/async_minitest.dart
index cf60812..fa5d319 100644
--- a/pkg/async_helper/lib/async_minitest.dart
+++ b/pkg/async_helper/lib/async_minitest.dart
@@ -99,7 +99,7 @@
 
 dynamic expectAsync(Function f, {int count = 1}) {
   var f2 = f; // Avoid type-promoting f, we want dynamic invocations.
-  if (f2 is Function(Null, Null, Null, Null, Null)) {
+  if (f2 is Function(Never, Never, Never, Never, Never)) {
     asyncStart(count);
     return ([a, b, c, d, e]) {
       var result = f(a, b, c, d, e);
@@ -107,7 +107,7 @@
       return result;
     };
   }
-  if (f2 is Function(Null, Null, Null, Null)) {
+  if (f2 is Function(Never, Never, Never, Never)) {
     asyncStart(count);
     return ([a, b, c, d]) {
       var result = f(a, b, c, d);
@@ -115,7 +115,7 @@
       return result;
     };
   }
-  if (f2 is Function(Null, Null, Null)) {
+  if (f2 is Function(Never, Never, Never)) {
     asyncStart(count);
     return ([a, b, c]) {
       var result = f(a, b, c);
@@ -123,7 +123,7 @@
       return result;
     };
   }
-  if (f2 is Function(Null, Null)) {
+  if (f2 is Function(Never, Never)) {
     asyncStart(count);
     return ([a, b]) {
       var result = f(a, b);
@@ -131,7 +131,7 @@
       return result;
     };
   }
-  if (f2 is Function(Null)) {
+  if (f2 is Function(Never)) {
     asyncStart(count);
     return ([a]) {
       var result = f(a);
@@ -310,9 +310,7 @@
 bool _initializedTestNameCallback = false;
 
 /// The current combined name of the nesting [group] or [test].
-// TODO(rnystrom): Type this "String?" when this library does not need to be
-// NNBD agnostic.
-dynamic _currentName = null;
+String _currentName = "";
 
 String _pushName(String newName) {
   // Look up the current test name from the zone created for the test.
@@ -322,7 +320,7 @@
   }
 
   var oldName = _currentName;
-  if (oldName == null) {
+  if (oldName == "") {
     _currentName = newName;
   } else {
     _currentName = "$oldName $newName";
diff --git a/pkg/async_helper/pubspec.yaml b/pkg/async_helper/pubspec.yaml
index df92b53..9497752 100644
--- a/pkg/async_helper/pubspec.yaml
+++ b/pkg/async_helper/pubspec.yaml
@@ -7,6 +7,5 @@
  language tests.
  Third parties are discouraged from using this, and should use
  the facilities provided in package:test.
-
 dependencies:
   expect: any
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 80362a4..9d9f4d6 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -18,6 +18,7 @@
   static const String disableTypeInference = '--disable-type-inference';
   static const String disableRtiOptimization = '--disable-rti-optimization';
   static const String dumpInfo = '--dump-info';
+  static const String dumpSsa = '--dump-ssa';
   static const String enableAssertMessage = '--assert-message';
   static const String enableCheckedMode = '--enable-checked-mode';
   static const String enableAsserts = '--enable-asserts';
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 925f3d8..9bbfd02 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -353,6 +353,10 @@
 
   ClassEntity get jsInvocationMirrorClass;
 
+  ClassEntity get requiredSentinelClass;
+
+  InterfaceType get requiredSentinelType;
+
   MemberEntity get invocationTypeArgumentGetter;
 
   /// Interface used to determine if an object has the JavaScript
@@ -520,13 +524,23 @@
   FunctionEntity get specializedIsTop;
   FunctionEntity get specializedAsTop;
   FunctionEntity get specializedIsBool;
+  FunctionEntity get specializedAsBool;
+  FunctionEntity get specializedAsBoolLegacy;
   FunctionEntity get specializedAsBoolNullable;
+  FunctionEntity get specializedAsDouble;
+  FunctionEntity get specializedAsDoubleLegacy;
   FunctionEntity get specializedAsDoubleNullable;
   FunctionEntity get specializedIsInt;
+  FunctionEntity get specializedAsInt;
+  FunctionEntity get specializedAsIntLegacy;
   FunctionEntity get specializedAsIntNullable;
   FunctionEntity get specializedIsNum;
+  FunctionEntity get specializedAsNum;
+  FunctionEntity get specializedAsNumLegacy;
   FunctionEntity get specializedAsNumNullable;
   FunctionEntity get specializedIsString;
+  FunctionEntity get specializedAsString;
+  FunctionEntity get specializedAsStringLegacy;
   FunctionEntity get specializedAsStringNullable;
 
   FunctionEntity get instantiatedGenericFunctionTypeNewRti;
@@ -1546,6 +1560,13 @@
   ClassEntity get jsInvocationMirrorClass =>
       _jsInvocationMirrorClass ??= _findHelperClass('JSInvocationMirror');
 
+  ClassEntity _requiredSentinelClass;
+  @override
+  ClassEntity get requiredSentinelClass =>
+      _requiredSentinelClass ??= _findHelperClass('_Required');
+  @override
+  InterfaceType get requiredSentinelType => _getRawType(requiredSentinelClass);
+
   MemberEntity _invocationTypeArgumentGetter;
   @override
   MemberEntity get invocationTypeArgumentGetter =>
@@ -2004,33 +2025,62 @@
   FunctionEntity get specializedIsBool => _findRtiFunction('_isBool');
 
   @override
-  FunctionEntity get specializedAsBoolNullable =>
-      _findRtiFunction('_asBoolNullable');
+  FunctionEntity get specializedAsBool => _findRtiFunction('_asBool');
+
+  @override
+  FunctionEntity get specializedAsBoolLegacy => _findRtiFunction('_asBoolS');
+
+  @override
+  FunctionEntity get specializedAsBoolNullable => _findRtiFunction('_asBoolQ');
+
+  @override
+  FunctionEntity get specializedAsDouble => _findRtiFunction('_asDouble');
+
+  @override
+  FunctionEntity get specializedAsDoubleLegacy =>
+      _findRtiFunction('_asDoubleS');
 
   @override
   FunctionEntity get specializedAsDoubleNullable =>
-      _findRtiFunction('_asDoubleNullable');
+      _findRtiFunction('_asDoubleQ');
 
   @override
   FunctionEntity get specializedIsInt => _findRtiFunction('_isInt');
 
   @override
-  FunctionEntity get specializedAsIntNullable =>
-      _findRtiFunction('_asIntNullable');
+  FunctionEntity get specializedAsInt => _findRtiFunction('_asInt');
+
+  @override
+  FunctionEntity get specializedAsIntLegacy => _findRtiFunction('_asIntS');
+
+  @override
+  FunctionEntity get specializedAsIntNullable => _findRtiFunction('_asIntQ');
 
   @override
   FunctionEntity get specializedIsNum => _findRtiFunction('_isNum');
 
   @override
-  FunctionEntity get specializedAsNumNullable =>
-      _findRtiFunction('_asNumNullable');
+  FunctionEntity get specializedAsNum => _findRtiFunction('_asNum');
+
+  @override
+  FunctionEntity get specializedAsNumLegacy => _findRtiFunction('_asNumS');
+
+  @override
+  FunctionEntity get specializedAsNumNullable => _findRtiFunction('_asNumQ');
 
   @override
   FunctionEntity get specializedIsString => _findRtiFunction('_isString');
 
   @override
+  FunctionEntity get specializedAsString => _findRtiFunction('_asString');
+
+  @override
+  FunctionEntity get specializedAsStringLegacy =>
+      _findRtiFunction('_asStringS');
+
+  @override
   FunctionEntity get specializedAsStringNullable =>
-      _findRtiFunction('_asStringNullable');
+      _findRtiFunction('_asStringQ');
 
   @override
   FunctionEntity get instantiatedGenericFunctionTypeNewRti =>
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 276c347..37094a9 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -477,6 +477,7 @@
     new OptionHandler(Flags.useNewSourceInfo, passThrough),
     new OptionHandler(Flags.useOldRti, passThrough),
     new OptionHandler(Flags.testMode, passThrough),
+    new OptionHandler('${Flags.dumpSsa}=.+', passThrough),
 
     // Experimental features.
     // We don't provide documentation for these yet.
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 644e4cb..09f7fab 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -663,6 +663,7 @@
   final CompilerOptions _options;
   bool get terse => _options?.terseDiagnostics ?? false;
   bool get _printLegacyStars => _options?.printLegacyStars ?? false;
+  bool get _useLegacySubtyping => _options?.useLegacySubtyping ?? false;
   String message;
 
   Message(this.template, this.arguments, this._options) {
@@ -712,7 +713,9 @@
 
   String convertToString(value) {
     if (value is DartType) {
-      value = value.toStructuredText(printLegacyStars: _printLegacyStars);
+      value = value.toStructuredText(
+          printLegacyStars: _printLegacyStars,
+          useLegacySubtyping: _useLegacySubtyping);
     } else if (value is ConstantValue) {
       value = value.toDartText();
     } else {
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 646cdee..bc001f7 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -276,8 +276,10 @@
     });
     int parameterIndex = 0;
     closedWorld.elementEnvironment.forEachParameter(function, (type, name, _) {
-      parameters.add(new ParameterInfo(
-          name, inferredParameterTypes[parameterIndex++], '$type'));
+      // Synthesized parameters have no name. This can happen on parameters of
+      // setters derived from lowering late fields.
+      parameters.add(new ParameterInfo(name ?? '#t${parameterIndex}',
+          inferredParameterTypes[parameterIndex++], '$type'));
     });
 
     var functionType = environment.getFunctionType(function);
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index bad2d7c..e863b5b 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -264,58 +264,76 @@
   /// debugging data stream.
   static const String tag = 'parameter-structure';
 
-  /// The number of required (positional) parameters.
-  final int requiredParameters;
+  /// The number of required positional parameters.
+  final int requiredPositionalParameters;
 
   /// The number of positional parameters.
   final int positionalParameters;
 
-  /// The named parameters sorted alphabetically.
+  /// All named parameters sorted alphabetically.
   final List<String> namedParameters;
 
+  /// The required named parameters.
+  final Set<String> requiredNamedParameters;
+
   /// The number of type parameters.
   final int typeParameters;
 
-  const ParameterStructure(this.requiredParameters, this.positionalParameters,
-      this.namedParameters, this.typeParameters);
+  const ParameterStructure(
+      this.requiredPositionalParameters,
+      this.positionalParameters,
+      this.namedParameters,
+      this.requiredNamedParameters,
+      this.typeParameters);
 
-  const ParameterStructure.getter() : this(0, 0, const <String>[], 0);
+  const ParameterStructure.getter()
+      : this(0, 0, const <String>[], const <String>{}, 0);
 
-  const ParameterStructure.setter() : this(1, 1, const <String>[], 0);
+  const ParameterStructure.setter()
+      : this(1, 1, const <String>[], const <String>{}, 0);
 
   factory ParameterStructure.fromType(FunctionType type) {
     return new ParameterStructure(
         type.parameterTypes.length,
         type.parameterTypes.length + type.optionalParameterTypes.length,
         type.namedParameters,
+        type.requiredNamedParameters,
         type.typeVariables.length);
   }
 
   /// Deserializes a [ParameterStructure] object from [source].
   factory ParameterStructure.readFromDataSource(DataSource source) {
     source.begin(tag);
-    int requiredParameters = source.readInt();
+    int requiredPositionalParameters = source.readInt();
     int positionalParameters = source.readInt();
     List<String> namedParameters = source.readStrings();
+    Set<String> requiredNamedParameters =
+        source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
     int typeParameters = source.readInt();
     source.end(tag);
-    return new ParameterStructure(requiredParameters, positionalParameters,
-        namedParameters, typeParameters);
+    return new ParameterStructure(
+        requiredPositionalParameters,
+        positionalParameters,
+        namedParameters,
+        requiredNamedParameters,
+        typeParameters);
   }
 
   /// Serializes this [ParameterStructure] to [sink].
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
-    sink.writeInt(requiredParameters);
+    sink.writeInt(requiredPositionalParameters);
     sink.writeInt(positionalParameters);
     sink.writeStrings(namedParameters);
+    sink.writeStrings(requiredNamedParameters);
     sink.writeInt(typeParameters);
     sink.end(tag);
   }
 
   /// The number of optional parameters (positional or named).
   int get optionalParameters =>
-      positionalParameters - requiredParameters + namedParameters.length;
+      (positionalParameters - requiredPositionalParameters) +
+      (namedParameters.length - requiredNamedParameters.length);
 
   /// The total number of parameters (required or optional).
   int get totalParameters => positionalParameters + namedParameters.length;
@@ -323,26 +341,29 @@
   /// Returns the [CallStructure] corresponding to a call site passing all
   /// parameters both required and optional.
   CallStructure get callStructure {
-    return new CallStructure(positionalParameters + namedParameters.length,
-        namedParameters, typeParameters);
+    return new CallStructure(totalParameters, namedParameters, typeParameters);
   }
 
   @override
   int get hashCode => Hashing.listHash(
       namedParameters,
-      Hashing.objectHash(
-          positionalParameters,
+      Hashing.setHash(
+          requiredNamedParameters,
           Hashing.objectHash(
-              requiredParameters, Hashing.objectHash(typeParameters))));
+              positionalParameters,
+              Hashing.objectHash(requiredPositionalParameters,
+                  Hashing.objectHash(typeParameters)))));
 
   @override
   bool operator ==(other) {
     if (identical(this, other)) return true;
     if (other is! ParameterStructure) return false;
-    if (requiredParameters != other.requiredParameters ||
+    if (requiredPositionalParameters != other.requiredPositionalParameters ||
         positionalParameters != other.positionalParameters ||
         typeParameters != other.typeParameters ||
-        namedParameters.length != other.namedParameters.length) {
+        namedParameters.length != other.namedParameters.length ||
+        requiredNamedParameters.length !=
+            other.requiredNamedParameters.length) {
       return false;
     }
     for (int i = 0; i < namedParameters.length; i++) {
@@ -350,6 +371,9 @@
         return false;
       }
     }
+    for (String name in requiredNamedParameters) {
+      if (!other.requiredNamedParameters.contains(name)) return false;
+    }
     return true;
   }
 
@@ -363,9 +387,10 @@
     }
     sb.write('(');
     sb.write(positionalParameters);
-    if (namedParameters.length > 0) {
+    for (var name in namedParameters) {
       sb.write(',');
-      sb.write(namedParameters.join(','));
+      if (requiredNamedParameters.contains(name)) sb.write('req ');
+      sb.write(name);
     }
     sb.write(')');
     return sb.toString();
@@ -375,13 +400,13 @@
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('ParameterStructure(');
-    sb.write('requiredParameters=$requiredParameters,');
+    sb.write('requiredPositionalParameters=$requiredPositionalParameters,');
     sb.write('positionalParameters=$positionalParameters,');
     sb.write('namedParameters={${namedParameters.join(',')}},');
+    sb.write('requiredNamedParameters={${requiredNamedParameters.join(',')}},');
     sb.write('typeParameters=$typeParameters)');
     return sb.toString();
   }
 
-  int get size =>
-      positionalParameters + typeParameters + namedParameters.length;
+  int get size => totalParameters + typeParameters;
 }
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 9cf992b..96702e1 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -5,7 +5,7 @@
 import '../common/names.dart';
 import '../common_elements.dart';
 import '../serialization/serialization.dart';
-import '../util/util.dart' show equalElements, identicalElements;
+import '../util/util.dart' show equalElements, equalSets, identicalElements;
 import 'entities.dart';
 
 /// Hierarchy to describe types in Dart.
@@ -92,15 +92,15 @@
   DartType get withoutNullability => this;
 
   /// Is `true` if this type is a top type but not a legacy top type.
-  bool _isStrongTop(bool useNullSafety) => false;
+  bool _isStrongTop(bool useLegacySubtyping) => false;
 
   /// Is `true` if this type is a top type.
-  bool _isTop(bool useNullSafety) => _isStrongTop(useNullSafety);
+  bool _isTop(bool useLegacySubtyping) => _isStrongTop(useLegacySubtyping);
 
   /// Is `true` if every type argument of this type is a top type.
   // TODO(fishythefish): Should we instead check if each type argument is at its
   // bound?
-  bool _treatAsRaw(bool useNullSafety) => true;
+  bool _treatAsRaw(bool useLegacySubtyping) => true;
 
   /// Whether this type contains a type variable.
   bool get containsTypeVariables => false;
@@ -130,8 +130,9 @@
   @override
   String toString() => toStructuredText();
 
-  String toStructuredText({bool printLegacyStars = true}) =>
-      _DartTypeToStringVisitor(printLegacyStars).run(this);
+  String toStructuredText(
+          {bool printLegacyStars = true, bool useLegacySubtyping = false}) =>
+      _DartTypeToStringVisitor(printLegacyStars, useLegacySubtyping).run(this);
 }
 
 /// Pairs of [FunctionTypeVariable]s that are currently assumed to be
@@ -232,10 +233,11 @@
   DartType get withoutNullability => baseType;
 
   @override
-  bool _isTop(bool useNullSafety) => baseType.isObject;
+  bool _isTop(bool useLegacySubtyping) => baseType.isObject;
 
   @override
-  bool _treatAsRaw(bool useNullSafety) => baseType._treatAsRaw(useNullSafety);
+  bool _treatAsRaw(bool useLegacySubtyping) =>
+      baseType._treatAsRaw(useLegacySubtyping);
 
   @override
   bool get containsTypeVariables => baseType.containsTypeVariables;
@@ -293,10 +295,11 @@
   DartType get withoutNullability => baseType;
 
   @override
-  bool _isStrongTop(bool isLegacy) => baseType.isObject;
+  bool _isStrongTop(bool useLegacySubtyping) => baseType.isObject;
 
   @override
-  bool _treatAsRaw(bool useNullSafety) => baseType._treatAsRaw(useNullSafety);
+  bool _treatAsRaw(bool useLegacySubtyping) =>
+      baseType._treatAsRaw(useLegacySubtyping);
 
   @override
   bool get containsTypeVariables => baseType.containsTypeVariables;
@@ -354,7 +357,7 @@
   }
 
   @override
-  bool _isStrongTop(bool useNullSafety) => useNullSafety ? false : isObject;
+  bool _isTop(bool useLegacySubtyping) => useLegacySubtyping && isObject;
 
   @override
   bool get isObject =>
@@ -375,9 +378,9 @@
   }
 
   @override
-  bool _treatAsRaw(bool useNullSafety) {
+  bool _treatAsRaw(bool useLegacySubtyping) {
     for (DartType type in typeArguments) {
-      if (!type._isTop(useNullSafety)) return false;
+      if (!type._isTop(useLegacySubtyping)) return false;
     }
     return true;
   }
@@ -562,7 +565,7 @@
   }
 
   @override
-  bool _isStrongTop(bool useNullSafety) => true;
+  bool _isStrongTop(bool useLegacySubtyping) => true;
 
   @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -592,7 +595,7 @@
   }
 
   @override
-  bool _isStrongTop(bool useNullSafety) => true;
+  bool _isStrongTop(bool useLegacySubtyping) => true;
 
   @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -622,7 +625,7 @@
   }
 
   @override
-  bool _isStrongTop(bool useNullSafety) => true;
+  bool _isStrongTop(bool useLegacySubtyping) => true;
 
   @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -663,7 +666,7 @@
   }
 
   @override
-  bool _isStrongTop(bool useNullSafety) => true;
+  bool _isStrongTop(bool useLegacySubtyping) => true;
 
   @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -684,9 +687,12 @@
   final List<DartType> parameterTypes;
   final List<DartType> optionalParameterTypes;
 
-  /// The names of the named parameters ordered lexicographically.
+  /// The names of all named parameters ordered lexicographically.
   final List<String> namedParameters;
 
+  /// The names of the required named parameters.
+  final Set<String> requiredNamedParameters;
+
   /// The types of the named parameters in the order corresponding to the
   /// [namedParameters].
   final List<DartType> namedParameterTypes;
@@ -698,6 +704,7 @@
       this.parameterTypes,
       this.optionalParameterTypes,
       this.namedParameters,
+      this.requiredNamedParameters,
       this.namedParameterTypes,
       this.typeVariables) {
     assert(returnType != null, "Invalid return type in $this.");
@@ -706,6 +713,8 @@
         "Invalid optional parameter types in $this.");
     assert(
         !namedParameters.contains(null), "Invalid named parameters in $this.");
+    assert(!requiredNamedParameters.contains(null),
+        "Invalid required named parameters in $this.");
     assert(!namedParameterTypes.contains(null),
         "Invalid named parameter types in $this.");
     assert(!typeVariables.contains(null), "Invalid type variables in $this.");
@@ -732,11 +741,19 @@
     List<DartType> namedParameterTypes =
         source._readDartTypes(functionTypeVariables);
     List<String> namedParameters = List<String>(namedParameterTypes.length);
+    var requiredNamedParameters = <String>{};
     for (int i = 0; i < namedParameters.length; i++) {
       namedParameters[i] = source.readString();
+      if (source.readBool()) requiredNamedParameters.add(namedParameters[i]);
     }
-    return FunctionType._(returnType, parameterTypes, optionalParameterTypes,
-        namedParameters, namedParameterTypes, typeVariables);
+    return FunctionType._(
+        returnType,
+        parameterTypes,
+        optionalParameterTypes,
+        namedParameters,
+        requiredNamedParameters,
+        namedParameterTypes,
+        typeVariables);
   }
 
   @override
@@ -755,6 +772,7 @@
     sink._writeDartTypes(namedParameterTypes, functionTypeVariables);
     for (String namedParameter in namedParameters) {
       sink.writeString(namedParameter);
+      sink.writeBool(requiredNamedParameters.contains(namedParameter));
     }
   }
 
@@ -784,16 +802,19 @@
   int get hashCode {
     int hash = 3 * returnType.hashCode;
     for (DartType parameter in parameterTypes) {
-      hash = 17 * hash + 5 * parameter.hashCode;
+      hash = 19 * hash + 5 * parameter.hashCode;
     }
     for (DartType parameter in optionalParameterTypes) {
-      hash = 19 * hash + 7 * parameter.hashCode;
+      hash = 23 * hash + 7 * parameter.hashCode;
     }
     for (String name in namedParameters) {
-      hash = 23 * hash + 11 * name.hashCode;
+      hash = 29 * hash + 11 * name.hashCode;
     }
     for (DartType parameter in namedParameterTypes) {
-      hash = 29 * hash + 13 * parameter.hashCode;
+      hash = 31 * hash + 13 * parameter.hashCode;
+    }
+    for (String name in requiredNamedParameters) {
+      hash = 37 * hash + 17 * name.hashCode;
     }
     return hash;
   }
@@ -829,6 +850,7 @@
           _equalTypes(optionalParameterTypes, other.optionalParameterTypes,
               assumptions) &&
           equalElements(namedParameters, other.namedParameters) &&
+          equalSets(requiredNamedParameters, other.requiredNamedParameters) &&
           _equalTypes(
               namedParameterTypes, other.namedParameterTypes, assumptions);
     } finally {
@@ -1068,6 +1090,7 @@
             parameterTypes,
             optionalParameterTypes,
             type.namedParameters,
+            type.requiredNamedParameters,
             namedParameterTypes,
             typeVariables));
   }
@@ -1205,6 +1228,7 @@
             newParameterTypes,
             newOptionalParameterTypes,
             type.namedParameters,
+            type.requiredNamedParameters,
             newNamedParameterTypes,
             newTypeVariables));
   }
@@ -1502,13 +1526,14 @@
 
 class _DartTypeToStringVisitor extends DartTypeVisitor<void, void> {
   final bool _printLegacyStars;
+  final bool _useLegacySubtyping;
   final List _fragments = []; // Strings and _DeferredNames
   bool _lastIsIdentifier = false;
   List<FunctionTypeVariable> _boundVariables;
   Map<FunctionTypeVariable, _DeferredName> _variableToName;
   Set<FunctionType> _genericFunctions;
 
-  _DartTypeToStringVisitor(this._printLegacyStars);
+  _DartTypeToStringVisitor(this._printLegacyStars, this._useLegacySubtyping);
 
   String run(DartType type) {
     _visit(type);
@@ -1660,9 +1685,9 @@
         needsComma = _comma(needsComma);
         _visit(typeVariable);
         DartType bound = typeVariable.bound;
-        if (!bound.isObject) {
+        if (!bound._isTop(_useLegacySubtyping)) {
           _token(' extends ');
-          _visit(typeVariable.bound);
+          _visit(bound);
         }
       }
       _token('>');
@@ -1740,7 +1765,7 @@
 
   DartType legacyType(DartType baseType) {
     DartType result;
-    if (isTopType(baseType) ||
+    if (isStrongTopType(baseType) ||
         baseType.isNull ||
         baseType is LegacyType ||
         baseType is NullableType) {
@@ -1811,6 +1836,7 @@
       List<DartType> parameterTypes,
       List<DartType> optionalParameterTypes,
       List<String> namedParameters,
+      Set<String> requiredNamedParameters,
       List<DartType> namedParameterTypes,
       List<FunctionTypeVariable> typeVariables) {
     FunctionType type = FunctionType._(
@@ -1818,6 +1844,7 @@
         parameterTypes,
         optionalParameterTypes,
         namedParameters,
+        requiredNamedParameters,
         namedParameterTypes,
         typeVariables);
     List<FunctionTypeVariable> normalizableVariables = typeVariables
@@ -1877,19 +1904,24 @@
         t.optionalParameterTypes.map(_subst).toList();
     List<DartType> namedParameterTypes =
         t.namedParameterTypes.map(_subst).toList();
-    return functionType(returnType, parameterTypes, optionalParameterTypes,
-        t.namedParameters, namedParameterTypes, const []);
+    return functionType(
+        returnType,
+        parameterTypes,
+        optionalParameterTypes,
+        t.namedParameters,
+        t.requiredNamedParameters,
+        namedParameterTypes, const []);
   }
 
   /// Returns `true` if every type argument of [t] is a top type.
   // TODO(fishythefish): Should we instead check if each type argument is at its
   // bound?
-  bool treatAsRawType(DartType t) => t._treatAsRaw(useNullSafety);
+  bool treatAsRawType(DartType t) => t._treatAsRaw(useLegacySubtyping);
 
   /// Returns `true` if [t] is a top type, that is, a supertype of every type.
-  bool isTopType(DartType t) => t._isTop(useNullSafety);
+  bool isTopType(DartType t) => t._isTop(useLegacySubtyping);
 
-  bool isStrongTopType(DartType t) => t._isStrongTop(useNullSafety);
+  bool isStrongTopType(DartType t) => t._isStrongTop(useLegacySubtyping);
 
   /// Returns `true` if [s] is a subtype of [t].
   bool isSubtype(DartType s, DartType t) => _subtypeHelper(s, t);
@@ -2055,8 +2087,6 @@
 
             if (!_isSubtype(s.returnType, t.returnType, env)) return false;
 
-            // TODO(fishythefish): Support required named parameters.
-
             List<DartType> sRequiredPositional = s.parameterTypes;
             List<DartType> tRequiredPositional = t.parameterTypes;
             int sRequiredPositionalLength = sRequiredPositional.length;
@@ -2099,25 +2129,38 @@
               }
             }
 
-            List<String> sOptionalNamed = s.namedParameters;
-            List<String> tOptionalNamed = t.namedParameters;
-            List<DartType> sOptionalNamedTypes = s.namedParameterTypes;
-            List<DartType> tOptionalNamedTypes = t.namedParameterTypes;
-            int sOptionalNamedLength = sOptionalNamed.length;
-            int tOptionalNamedLength = tOptionalNamed.length;
-            for (int i = 0, j = 0; j < tOptionalNamedLength; j++) {
-              String sName;
-              String tName = tOptionalNamed[j];
-              int comparison;
-              do {
-                if (i >= sOptionalNamedLength) return false;
-                sName = sOptionalNamed[i++];
-                comparison = sName.compareTo(tName);
-              } while (comparison < 0);
-              if (comparison > 0) return false;
-              if (!_isSubtype(
-                  tOptionalNamedTypes[j], sOptionalNamedTypes[i - 1], env))
-                return false;
+            List<String> sNamed = s.namedParameters;
+            List<String> tNamed = t.namedParameters;
+            Set<String> sRequiredNamed = s.requiredNamedParameters;
+            Set<String> tRequiredNamed = t.requiredNamedParameters;
+            List<DartType> sNamedTypes = s.namedParameterTypes;
+            List<DartType> tNamedTypes = t.namedParameterTypes;
+            int sNamedLength = sNamed.length;
+            int tNamedLength = tNamed.length;
+
+            int sIndex = 0;
+            for (int tIndex = 0; tIndex < tNamedLength; tIndex++) {
+              String tName = tNamed[tIndex];
+              while (true) {
+                if (sIndex >= sNamedLength) return false;
+                String sName = sNamed[sIndex++];
+                int comparison = sName.compareTo(tName);
+                if (comparison > 0) return false;
+                bool sIsRequired = sRequiredNamed.contains(sName);
+                if (comparison < 0) {
+                  if (sIsRequired) return false;
+                  continue;
+                }
+                bool tIsRequired = tRequiredNamed.contains(tName);
+                if (sIsRequired && !tIsRequired) return false;
+                if (!_isSubtype(
+                    tNamedTypes[tIndex], sNamedTypes[sIndex - 1], env))
+                  return false;
+                break;
+              }
+            }
+            while (sIndex < sNamedLength) {
+              if (sRequiredNamed.contains(sNamed[sIndex++])) return false;
             }
             return true;
           } finally {
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index 6eed483..baa2c18 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -206,6 +206,10 @@
   /// the input's abstract type. The check can only be removed with additional
   /// reasoning, for example, that a dominating check uses the same type
   /// expression.
+  ///
+  /// [nullable] determines if the type in weak or legacy mode should be
+  /// interpreted as nullable. This is passed as `false` for is-tests and `true`
+  /// for as-checks and other contexts (e.g. parameter checks).
   AbstractValueWithPrecision createFromStaticType(DartType type,
       {ClassRelation classRelation = ClassRelation.subtype, bool nullable});
 
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 9916400..33d1bed 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -229,7 +229,7 @@
     ParameterStructure parameterStructure = function.parameterStructure;
 
     return arguments.positional.length <
-            parameterStructure.requiredParameters ||
+            parameterStructure.requiredPositionalParameters ||
         arguments.positional.length > parameterStructure.positionalParameters ||
         arguments.named.keys
             .any((name) => !parameterStructure.namedParameters.contains(name));
@@ -859,14 +859,17 @@
     if (mask != null) return mask;
     // TODO(sigmund): ensure that this is only called once per node.
     DartType staticType = _getStaticType(receiver);
-    // TODO(sigmund): this needs to be adjusted when we enable non-nullable
-    // types to handle legacy and nullable wrappers.
+    bool includeNull =
+        _dartTypes.useLegacySubtyping || staticType is NullableType;
+    staticType = staticType.withoutNullability;
     if (staticType is InterfaceType) {
       ClassEntity cls = staticType.element;
       if (receiver is ir.ThisExpression && !_closedWorld.isUsedAsMixin(cls)) {
         mask = _closedWorld.abstractValueDomain.createNonNullSubclass(cls);
-      } else {
+      } else if (includeNull) {
         mask = _closedWorld.abstractValueDomain.createNullableSubtype(cls);
+      } else {
+        mask = _closedWorld.abstractValueDomain.createNonNullSubtype(cls);
       }
       data.setReceiverTypeMask(node, mask);
       return mask;
@@ -1706,7 +1709,7 @@
     if (exception != null) {
       TypeInformation mask;
       DartType type = node.guard != null
-          ? _elementMap.getDartType(node.guard)
+          ? _elementMap.getDartType(node.guard).withoutNullability
           : _dartTypes.dynamicType();
       if (type is InterfaceType) {
         InterfaceType interfaceType = type;
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index a510d20..0820252 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -772,7 +772,7 @@
       int parameterIndex = 0;
       types.strategy.forEachParameter(callee, (Local parameter) {
         TypeInformation type;
-        if (parameterIndex < parameterStructure.requiredParameters) {
+        if (parameterIndex < parameterStructure.requiredPositionalParameters) {
           type = arguments.positional[parameterIndex];
         } else if (parameterStructure.namedParameters.isNotEmpty) {
           type = arguments.named[parameter.name];
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index c3683c5..61b0825 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -268,18 +268,51 @@
   AbstractValueWithPrecision createFromStaticType(DartType type,
       {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
     assert(nullable != null);
+
+    if ((classRelation == ClassRelation.subtype ||
+            classRelation == ClassRelation.thisExpression) &&
+        dartTypes.isTopType(type)) {
+      // A cone of a top type includes all values.
+      return AbstractValueWithPrecision(dynamicType, true);
+    }
+
+    if (type is NullableType) {
+      assert(dartTypes.useNullSafety);
+      return _createFromStaticType(type.baseType, classRelation, true);
+    }
+
+    if (type is LegacyType) {
+      assert(dartTypes.useNullSafety);
+      DartType baseType = type.baseType;
+      if (baseType is NeverType) {
+        // Never* is same as Null, for both 'is' and 'as'.
+        return AbstractValueWithPrecision(nullType, true);
+      }
+
+      // Object* is a top type for both 'is' and 'as'. This is handled in the
+      // 'cone of top type' case above.
+
+      return _createFromStaticType(baseType, classRelation, nullable);
+    }
+
+    if (dartTypes.useLegacySubtyping) {
+      // In legacy and weak mode, `String` is nullable depending on context.
+      return _createFromStaticType(type, classRelation, nullable);
+    } else {
+      // In strong mode nullability comes from explicit NullableType.
+      return _createFromStaticType(type, classRelation, false);
+    }
+  }
+
+  AbstractValueWithPrecision _createFromStaticType(
+      DartType type, ClassRelation classRelation, bool nullable) {
+    assert(nullable != null);
+
     AbstractValueWithPrecision finish(TypeMask value, bool isPrecise) {
       return AbstractValueWithPrecision(
           nullable ? value : value.nonNullable(), isPrecise);
     }
 
-    if (type is NullableType) {
-      return createFromStaticType(type.baseType,
-          classRelation: classRelation, nullable: true);
-    }
-
-    // TODO(sra): Handle LegacyType more precisely.
-
     bool isPrecise = true;
     while (type is TypeVariableType) {
       TypeVariableType typeVariable = type;
@@ -287,37 +320,71 @@
           .getTypeVariableBound(typeVariable.element);
       classRelation = ClassRelation.subtype;
       isPrecise = false;
+      if (type is NullableType) {
+        // <A extends B?, B extends num>  ...  null is A --> can be `true`.
+        // <A extends B, B extends num?>  ...  null is A --> can be `true`.
+        nullable = true;
+        type = type.withoutNullability;
+      }
+    }
+
+    if ((classRelation == ClassRelation.thisExpression ||
+            classRelation == ClassRelation.subtype) &&
+        dartTypes.isTopType(type)) {
+      // A cone of a top type includes all values. Since we already tested this
+      // in [createFromStaticType], we get here only for type parameter bounds.
+      return AbstractValueWithPrecision(dynamicType, isPrecise);
     }
 
     if (type is InterfaceType) {
-      if (isPrecise) {
-        // TODO(sra): Could be precise if instantiated-to-bounds.
-        for (DartType argument in type.typeArguments) {
-          if (argument is DynamicType) continue;
+      ClassEntity cls = type.element;
+      List<DartType> arguments = type.typeArguments;
+      if (isPrecise && arguments.isNotEmpty) {
+        // Can we ignore the type arguments?
+        //
+        // For legacy covariance, if the interface type is a generic interface
+        // type and is maximal (i.e. instantiated to bounds), the typemask,
+        // which is based on the class element, is still precise. We check
+        // against Top for the parameter arguments since we don't have a
+        // convenient check for instantation to bounds.
+        //
+        // TODO(sra): Check arguments against bounds.
+        // TODO(sra): Handle other variances.
+        List<Variance> variances = dartTypes.getTypeVariableVariances(cls);
+        for (int i = 0; i < arguments.length; i++) {
+          Variance variance = variances[i];
+          DartType argument = arguments[i];
+          if (variance == Variance.legacyCovariant &&
+              dartTypes.isTopType(argument)) {
+            continue;
+          }
           isPrecise = false;
         }
       }
       switch (classRelation) {
         case ClassRelation.exact:
-          return finish(TypeMask.exact(type.element, _closedWorld), isPrecise);
+          return finish(TypeMask.exact(cls, _closedWorld), isPrecise);
         case ClassRelation.thisExpression:
-          if (!_closedWorld.isUsedAsMixin(type.element)) {
-            return finish(
-                TypeMask.subclass(type.element, _closedWorld), isPrecise);
+          if (!_closedWorld.isUsedAsMixin(cls)) {
+            return finish(TypeMask.subclass(cls, _closedWorld), isPrecise);
           }
           break;
         case ClassRelation.subtype:
           break;
       }
-      return finish(TypeMask.subtype(type.element, _closedWorld), isPrecise);
-    } else if (type is FunctionType) {
+      return finish(TypeMask.subtype(cls, _closedWorld), isPrecise);
+    }
+
+    if (type is FunctionType) {
       return finish(
           TypeMask.subtype(commonElements.functionClass, _closedWorld), false);
-    } else if (type is DynamicType) {
-      return AbstractValueWithPrecision(dynamicType, true);
-    } else {
-      return finish(dynamicType, false);
     }
+
+    if (type is NeverType) {
+      return finish(nullType, isPrecise);
+    }
+
+    return AbstractValueWithPrecision(dynamicType, false);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 75ec907..b1eda7b 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -742,6 +742,8 @@
     assert(
         node.promotedType == null ||
             promotedType == typeEnvironment.nullType ||
+            promotedType is ir.InterfaceType &&
+                promotedType.classNode == typeEnvironment.futureOrClass ||
             typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
                 ir.SubtypeCheckMode.ignoringNullabilities),
         "Unexpected promotion of ${node.variable} in ${node.parent}. "
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index cd46b51..5a65825 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -130,6 +130,12 @@
             .skip(node.requiredParameterCount)
             .toList()),
         node.namedParameters.map((n) => n.name).toList(),
+        _options.useLegacySubtyping
+            ? const <String>{}
+            : node.namedParameters
+                .where((n) => n.isRequired)
+                .map((n) => n.name)
+                .toSet(),
         node.namedParameters.map((n) => visitType(n.type)).toList(),
         typeVariables ?? const <FunctionTypeVariable>[]);
     DartType type = _convertNullability(functionType, node.nullability);
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 7d50038..d22ce35 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -820,14 +820,24 @@
           ],
           // Specialized checks.
           _commonElements.specializedIsBool,
+          _commonElements.specializedAsBool,
+          _commonElements.specializedAsBoolLegacy,
           _commonElements.specializedAsBoolNullable,
           // no specializedIsDouble.
+          _commonElements.specializedAsDouble,
+          _commonElements.specializedAsDoubleLegacy,
           _commonElements.specializedAsDoubleNullable,
           _commonElements.specializedIsInt,
+          _commonElements.specializedAsInt,
+          _commonElements.specializedAsIntLegacy,
           _commonElements.specializedAsIntNullable,
           _commonElements.specializedIsNum,
+          _commonElements.specializedAsNum,
+          _commonElements.specializedAsNumLegacy,
           _commonElements.specializedAsNumNullable,
           _commonElements.specializedIsString,
+          _commonElements.specializedAsString,
+          _commonElements.specializedAsStringLegacy,
           _commonElements.specializedAsStringNullable,
           _commonElements.specializedIsTop,
           _commonElements.specializedAsTop,
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index 2a547ec..3642a24 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -231,7 +231,7 @@
         // function type.
         _elementEnvironment.getFunctionType(constructor);
         // Ignore constructors that cannot be called with zero arguments.
-        if (constructor.parameterStructure.requiredParameters == 0) {
+        if (constructor.parameterStructure.requiredPositionalParameters == 0) {
           result.add(constructor);
         }
       }
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 8699611..5137d62 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -49,6 +49,7 @@
       const <DartType>[],
       new List<DartType>.filled(16, dartTypes.dynamicType()),
       const <String>[],
+      const <String>{},
       const <DartType>[],
       const <FunctionTypeVariable>[]);
 }
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 1d7794a..3519633 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -339,6 +339,7 @@
       }
     });
     data.forEachJsInteropMember((ir.Member node, String name) {
+      if (memberIsIgnorable(node)) return;
       jsInteropMembers[map.getMember(node)] = name;
     });
 
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 4c371aa..edbbc71 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -359,7 +359,8 @@
       _emitCode(Recipe.endOptionalGroup);
     }
 
-    void emitNamedGroup(List<String> names, List<DartType> types) {
+    void emitNamedGroup(
+        List<String> names, Set<String> requiredNames, List<DartType> types) {
       assert(names.length == types.length);
       first = true;
       _emitCode(Recipe.startNamedGroup);
@@ -368,17 +369,18 @@
           _emitCode(Recipe.separator);
         }
         _emitStringUnescaped(names[i]);
-        _emitCode(Recipe.nameSeparator);
+        _emitCode(requiredNames.contains(names[i])
+            ? Recipe.requiredNameSeparator
+            : Recipe.nameSeparator);
         visit(types[i], _);
         first = false;
       }
       _emitCode(Recipe.endNamedGroup);
     }
 
-    // TODO(sra): These are optional named parameters. Handle required named
-    // parameters the same way when they are implemented.
     if (type.namedParameterTypes.isNotEmpty) {
-      emitNamedGroup(type.namedParameters, type.namedParameterTypes);
+      emitNamedGroup(type.namedParameters, type.requiredNamedParameters,
+          type.namedParameterTypes);
     }
 
     _emitCode(Recipe.endFunctionArguments);
diff --git a/pkg/compiler/lib/src/js_backend/specialized_checks.dart b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
index 9df9562..ca83fd1 100644
--- a/pkg/compiler/lib/src/js_backend/specialized_checks.dart
+++ b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
@@ -24,6 +24,20 @@
 class SpecializedChecks {
   static IsTestSpecialization findIsTestSpecialization(
       DartType dartType, HGraph graph, JClosedWorld closedWorld) {
+    if (dartType is LegacyType) {
+      DartType base = dartType.baseType;
+      // `Never*` accepts only `null`.
+      if (base is NeverType) return IsTestSpecialization.null_;
+      // TODO(sra): Handle strong checking 'x is Object' --> `x != null`.
+      // `Object*` is top and should be handled by constant folding.
+      if (base.isObject) return null;
+      return _findIsTestSpecialization(base, graph, closedWorld);
+    }
+    return _findIsTestSpecialization(dartType, graph, closedWorld);
+  }
+
+  static IsTestSpecialization _findIsTestSpecialization(
+      DartType dartType, HGraph graph, JClosedWorld closedWorld) {
     if (dartType is InterfaceType) {
       ClassEntity element = dartType.element;
       JCommonElements commonElements = closedWorld.commonElements;
@@ -84,48 +98,76 @@
     return null;
   }
 
-  static MemberEntity findAsCheck(
-      DartType dartType, JCommonElements commonElements) {
+  static MemberEntity findAsCheck(DartType dartType,
+      JCommonElements commonElements, bool useLegacySubtyping) {
     if (dartType is InterfaceType) {
       if (dartType.typeArguments.isNotEmpty) return null;
-      return _findAsCheck(dartType.element, commonElements, isNullable: true);
+      return _findAsCheck(dartType.element, commonElements,
+          nullable: false, legacy: useLegacySubtyping);
+    }
+    if (dartType is LegacyType) {
+      DartType baseType = dartType.baseType;
+      if (baseType is InterfaceType && baseType.typeArguments.isEmpty) {
+        return _findAsCheck(baseType.element, commonElements,
+            nullable: false, legacy: true);
+      }
+      return null;
+    }
+    if (dartType is NullableType) {
+      DartType baseType = dartType.baseType;
+      if (baseType is InterfaceType && baseType.typeArguments.isEmpty) {
+        return _findAsCheck(baseType.element, commonElements,
+            nullable: true, legacy: false);
+      }
+      return null;
     }
     return null;
   }
 
+  /// Finds the method that implements the specialized check for a simple type.
+  /// The specialized method will report a TypeError that includes a reported
+  /// type.
+  ///
+  /// [nullable]: Find specialization for `element?`.
+  /// [legacy]: Find specialization for non-nullable `element?` but with legacy
+  /// semantics (accepting null).
+  ///
+  ///     element   options                           reported  accepts
+  ///                                                 type      null
+  ///
+  ///     String    nullable: true   legacy: ---      String?   yes
+  ///     String    nullable: false  legacy: true     String    yes
+  ///     String    nullable: false  legacy: false    String    no
+  ///
   static MemberEntity _findAsCheck(
       ClassEntity element, JCommonElements commonElements,
-      {bool isNullable}) {
+      {bool nullable, bool legacy}) {
     if (element == commonElements.jsStringClass ||
         element == commonElements.stringClass) {
-      if (isNullable) {
-        return commonElements.specializedAsStringNullable;
-      }
-      return null;
+      if (legacy) return commonElements.specializedAsStringLegacy;
+      if (nullable) return commonElements.specializedAsStringNullable;
+      return commonElements.specializedAsString;
     }
 
     if (element == commonElements.jsBoolClass ||
         element == commonElements.boolClass) {
-      if (isNullable) {
-        return commonElements.specializedAsBoolNullable;
-      }
-      return null;
+      if (legacy) return commonElements.specializedAsBoolLegacy;
+      if (nullable) return commonElements.specializedAsBoolNullable;
+      return commonElements.specializedAsBool;
     }
 
     if (element == commonElements.jsDoubleClass ||
         element == commonElements.doubleClass) {
-      if (isNullable) {
-        return commonElements.specializedAsDoubleNullable;
-      }
-      return null;
+      if (legacy) return commonElements.specializedAsDoubleLegacy;
+      if (nullable) return commonElements.specializedAsDoubleNullable;
+      return commonElements.specializedAsDouble;
     }
 
     if (element == commonElements.jsNumberClass ||
         element == commonElements.numClass) {
-      if (isNullable) {
-        return commonElements.specializedAsNumNullable;
-      }
-      return null;
+      if (legacy) return commonElements.specializedAsNumLegacy;
+      if (nullable) return commonElements.specializedAsNumNullable;
+      return commonElements.specializedAsNum;
     }
 
     if (element == commonElements.jsIntClass ||
@@ -133,10 +175,9 @@
         element == commonElements.jsUInt32Class ||
         element == commonElements.jsUInt31Class ||
         element == commonElements.jsPositiveIntClass) {
-      if (isNullable) {
-        return commonElements.specializedAsIntNullable;
-      }
-      return null;
+      if (legacy) return commonElements.specializedAsIntLegacy;
+      if (nullable) return commonElements.specializedAsIntNullable;
+      return commonElements.specializedAsInt;
     }
 
     return null;
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index e6b39a4..de1a5f3 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -693,7 +693,7 @@
     var parameterTypes = type.parameterTypes;
     var optionalParameterTypes = type.optionalParameterTypes;
     var namedParameters = type.namedParameters;
-    // TODO(fishythefish): Handle required named parameters.
+    var requiredNamedParameters = type.requiredNamedParameters;
 
     if (optionalParameterTypes.isEmpty &&
         namedParameters.isEmpty &&
@@ -725,6 +725,9 @@
       bool needsNamedComma = false;
       for (int index = 0; index < namedParameters.length; index++) {
         needsNamedComma = _comma(needsNamedComma);
+        if (requiredNamedParameters.contains(namedParameters[index])) {
+          _add(r'$req');
+        }
         _identifier(namedParameters[index]);
         _visit(type.namedParameterTypes[index], type);
       }
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 7b73e7f..84ff8fe 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -281,6 +281,8 @@
     jsAst.Expression closureConverter;
     _elementEnvironment.forEachParameter(member,
         (DartType type, String name, _) {
+      type = type.withoutNullability;
+
       // If [name] is not in [stubParameters], then the parameter is an optional
       // parameter that was not provided for this stub.
       for (jsAst.Parameter stubParameter in stubParameters) {
@@ -291,8 +293,7 @@
 
             // The parameter type is a function type either directly or through
             // typedef(s).
-            FunctionType functionType = type;
-            int arity = functionType.parameterTypes.length;
+            int arity = type.parameterTypes.length;
             statements.add(js
                 .statement('# = #(#, $arity)', [name, closureConverter, name]));
             break;
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 dc51d54..a400318 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
@@ -894,7 +894,7 @@
       int index = 0;
       _elementEnvironment.forEachParameter(method,
           (DartType type, String name, ConstantValue defaultValue) {
-        if (index >= parameterStructure.requiredParameters) {
+        if (index >= parameterStructure.requiredPositionalParameters) {
           optionalParameterDefaultValues.add(defaultValue);
         }
         index++;
@@ -961,7 +961,8 @@
 
     FunctionEntity method = element;
     ParameterStructure parameterStructure = method.parameterStructure;
-    int requiredParameterCount = parameterStructure.requiredParameters;
+    int requiredParameterCount =
+        parameterStructure.requiredPositionalParameters;
     var /* List | Map */ optionalParameterDefaultValues;
     int applyIndex = 0;
     if (canBeApplied) {
@@ -1249,7 +1250,8 @@
 
     FunctionEntity method = element;
     ParameterStructure parameterStructure = method.parameterStructure;
-    int requiredParameterCount = parameterStructure.requiredParameters;
+    int requiredParameterCount =
+        parameterStructure.requiredPositionalParameters;
     var /* List | Map */ optionalParameterDefaultValues;
     int applyIndex = 0;
     if (canBeApplied) {
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 00cb033..10bb603 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -106,6 +106,13 @@
       ir.Member memberContext, ir.Expression expression,
       {bool requireConstant: true, bool implicitNull: false});
 
+  /// Returns the [ConstantValue] for the sentinel used to indicate that a
+  /// parameter is required.
+  ///
+  /// These should only appear within the defaultValues object attached to
+  /// closures and tearoffs when emitting Function.apply.
+  ConstantValue getRequiredSentinelConstantValue();
+
   /// Return the [ImportEntity] corresponding to [node].
   ImportEntity getImport(ir.LibraryDependency node);
 
@@ -529,7 +536,7 @@
       position++) {
     ir.VariableDeclaration variable = node.positionalParameters[position];
     f(variable,
-        isOptional: position >= parameterStructure.requiredParameters,
+        isOptional: position >= parameterStructure.requiredPositionalParameters,
         isElided: position >= parameterStructure.positionalParameters);
   }
 
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 78e93d5..90c7c44 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.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:front_end/src/api_unstable/dart2js.dart' show Link, LinkBuilder;
 import 'package:front_end/src/api_unstable/dart2js.dart' as ir;
 
 import 'package:kernel/ast.dart' as ir;
@@ -705,17 +704,41 @@
         data.isMixinApplication = false;
         data.interfaces = const <InterfaceType>[];
       } else {
-        InterfaceType processSupertype(ir.Supertype node) {
-          InterfaceType supertype = _typeConverter.visitSupertype(node);
+        // Set of canonical supertypes.
+        //
+        // This is necessary to support when a class implements the same
+        // supertype in multiple non-conflicting ways, like implementing A<int*>
+        // and A<int?> or B<Object?> and B<dynamic>.
+        Set<InterfaceType> canonicalSupertypes = <InterfaceType>{};
+
+        InterfaceType processSupertype(ir.Supertype supertypeNode) {
+          supertypeNode = classHierarchy.getClassAsInstanceOf(
+              node, supertypeNode.classNode);
+          InterfaceType supertype =
+              _typeConverter.visitSupertype(supertypeNode);
+          canonicalSupertypes.add(supertype);
           IndexedClass superclass = supertype.element;
           JClassData superdata = classes.getData(superclass);
           _ensureSupertypes(superclass, superdata);
+          for (InterfaceType supertype in superdata.orderedTypeSet.supertypes) {
+            ClassDefinition definition = getClassDefinition(supertype.element);
+            if (definition.kind == ClassKind.regular) {
+              ir.Supertype canonicalSupertype =
+                  classHierarchy.getClassAsInstanceOf(node, definition.node);
+              if (canonicalSupertype != null) {
+                supertype = _typeConverter.visitSupertype(canonicalSupertype);
+              } else {
+                assert(supertype.typeArguments.isEmpty,
+                    "Generic synthetic supertypes are not supported");
+              }
+            }
+            canonicalSupertypes.add(supertype);
+          }
           return supertype;
         }
 
         InterfaceType supertype;
-        LinkBuilder<InterfaceType> linkBuilder =
-            new LinkBuilder<InterfaceType>();
+        List<InterfaceType> interfaces = <InterfaceType>[];
         if (node.isMixinDeclaration) {
           // A mixin declaration
           //
@@ -733,7 +756,7 @@
           // so we need get the superclasses from the on-clause, A, B, and C,
           // through [superclassConstraints].
           for (ir.Supertype constraint in node.superclassConstraints()) {
-            linkBuilder.addLast(processSupertype(constraint));
+            interfaces.add(processSupertype(constraint));
           }
           // Set superclass to `Object`.
           supertype = _commonElements.objectType;
@@ -744,26 +767,26 @@
           ClassEntity defaultSuperclass =
               _commonElements.getDefaultSuperclass(cls, nativeData);
           data.supertype = _elementEnvironment.getRawType(defaultSuperclass);
+          assert(data.supertype.typeArguments.isEmpty,
+              "Generic default supertypes are not supported");
+          canonicalSupertypes.add(data.supertype);
         } else {
           data.supertype = supertype;
         }
         if (node.mixedInType != null) {
           data.isMixinApplication = true;
-          linkBuilder
-              .addLast(data.mixedInType = processSupertype(node.mixedInType));
+          interfaces.add(data.mixedInType = processSupertype(node.mixedInType));
         } else {
           data.isMixinApplication = false;
         }
         node.implementedTypes.forEach((ir.Supertype supertype) {
-          linkBuilder.addLast(processSupertype(supertype));
+          interfaces.add(processSupertype(supertype));
         });
-        Link<InterfaceType> interfaces =
-            linkBuilder.toLink(const Link<InterfaceType>());
         OrderedTypeSetBuilder setBuilder =
             new KernelOrderedTypeSetBuilder(this, cls);
-        data.orderedTypeSet = setBuilder.createOrderedTypeSet(
-            data.supertype, interfaces.reverse(const Link<InterfaceType>()));
-        data.interfaces = new List<InterfaceType>.from(interfaces.toList());
+        data.orderedTypeSet =
+            setBuilder.createOrderedTypeSet(canonicalSupertypes);
+        data.interfaces = interfaces;
       }
     }
   }
@@ -887,13 +910,17 @@
         parameterTypes.add(getParameterType(variable));
       }
     }
-    List<String> namedParameters = <String>[];
+    var namedParameters = <String>[];
+    var requiredNamedParameters = <String>{};
     List<DartType> namedParameterTypes = <DartType>[];
     List<ir.VariableDeclaration> sortedNamedParameters =
         node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
     for (ir.VariableDeclaration variable in sortedNamedParameters) {
       namedParameters.add(variable.name);
       namedParameterTypes.add(getParameterType(variable));
+      if (variable.isRequired && !options.useLegacySubtyping) {
+        requiredNamedParameters.add(variable.name);
+      }
     }
     List<FunctionTypeVariable> typeVariables;
     if (node.typeParameters.isNotEmpty) {
@@ -927,6 +954,7 @@
         parameterTypes,
         optionalParameterTypes,
         namedParameters,
+        requiredNamedParameters,
         namedParameterTypes,
         typeVariables);
   }
@@ -1487,6 +1515,12 @@
   }
 
   @override
+  ConstantValue getRequiredSentinelConstantValue() {
+    return new ConstructedConstantValue(
+        _commonElements.requiredSentinelType, <FieldEntity, ConstantValue>{});
+  }
+
+  @override
   FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
     while (cls != null) {
       cls = elementEnvironment.getSuperClass(cls);
@@ -1779,13 +1813,24 @@
 
   ParameterStructure _getParameterStructureFromFunctionNode(
       ir.FunctionNode node) {
-    int requiredParameters = node.requiredParameterCount;
+    int requiredPositionalParameters = node.requiredParameterCount;
     int positionalParameters = node.positionalParameters.length;
     int typeParameters = node.typeParameters.length;
-    List<String> namedParameters =
-        node.namedParameters.map((p) => p.name).toList()..sort();
-    return new ParameterStructure(requiredParameters, positionalParameters,
-        namedParameters, typeParameters);
+    var namedParameters = <String>[];
+    var requiredNamedParameters = <String>{};
+    for (var p in node.namedParameters.toList()
+      ..sort((a, b) => a.name.compareTo(b.name))) {
+      namedParameters.add(p.name);
+      if (p.isRequired && !options.useLegacySubtyping) {
+        requiredNamedParameters.add(p.name);
+      }
+    }
+    return new ParameterStructure(
+        requiredPositionalParameters,
+        positionalParameters,
+        namedParameters,
+        requiredNamedParameters,
+        typeParameters);
   }
 
   KernelClosureClassInfo constructClosureClass(
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 89b4467..4929d21 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -729,9 +729,15 @@
   static const String tag = 'signature-method';
 
   JSignatureMethod(ClassEntity enclosingClass)
-      : super(enclosingClass.library, enclosingClass, Names.signature,
-            const ParameterStructure(0, 0, const [], 0), AsyncMarker.SYNC,
-            isStatic: false, isExternal: false, isAbstract: false);
+      : super(
+            enclosingClass.library,
+            enclosingClass,
+            Names.signature,
+            const ParameterStructure(0, 0, const [], const {}, 0),
+            AsyncMarker.SYNC,
+            isStatic: false,
+            isExternal: false,
+            isAbstract: false);
 
   factory JSignatureMethod.readFromDataSource(DataSource source) {
     source.begin(tag);
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index 4187979..58716eb 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -647,7 +647,9 @@
       DartType type = elementMap.getDartType(parameter.type);
       String name = parameter.name;
       ConstantValue defaultValue;
-      if (isOptional) {
+      if (parameter.isRequired) {
+        defaultValue = elementMap.getRequiredSentinelConstantValue();
+      } else if (isOptional) {
         if (parameter.initializer != null) {
           defaultValue =
               elementMap.getConstantValue(memberContext, parameter.initializer);
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 3e31aa5e..06fc442 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -198,7 +198,8 @@
         ? const MinifiedFixedNames()
         : const FixedNames();
 
-    Tracer tracer = new Tracer(closedWorld, _compiler.outputProvider);
+    Tracer tracer =
+        new Tracer(closedWorld, _compiler.options, _compiler.outputProvider);
     RuntimeTypesEncoder rtiEncoder = new RuntimeTypesEncoderImpl(
         rtiTags,
         closedWorld.nativeData,
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index bb9a5ca..e510eff 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -259,21 +259,21 @@
   @override
   ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls) {
     if (nativeData.isJsInteropClass(cls)) {
-      return commonElements.jsJavaScriptObjectClass;
+      return getLubOfInstantiatedSubclasses(
+          commonElements.jsJavaScriptObjectClass);
     }
     ClassHierarchyNode hierarchy = classHierarchy.getClassHierarchyNode(cls);
-    return hierarchy != null
-        ? hierarchy.getLubOfInstantiatedSubclasses()
-        : null;
+    return hierarchy?.getLubOfInstantiatedSubclasses();
   }
 
   @override
   ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls) {
     if (nativeData.isJsInteropClass(cls)) {
-      return commonElements.jsJavaScriptObjectClass;
+      return getLubOfInstantiatedSubtypes(
+          commonElements.jsJavaScriptObjectClass);
     }
     ClassSet classSet = classHierarchy.getClassSet(cls);
-    return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null;
+    return classSet?.getLubOfInstantiatedSubtypes();
   }
 
   @override
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 f9dfd30..f5d5955 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -818,6 +818,7 @@
         parameterTypes,
         optionalParameterTypes,
         type.namedParameters,
+        type.requiredNamedParameters,
         namedParameterTypes,
         typeVariables);
   }
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 8fbb7d9..4b3917c8 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -185,3 +185,31 @@
   JS_INTERCEPTOR_CONSTANT,
   NONE,
 }
+
+// Members which dart2js ignores.
+bool memberIsIgnorable(ir.Member node, {ir.Class cls}) {
+  if (node is! ir.Procedure) return false;
+  ir.Procedure member = node;
+  if ((member.isMemberSignature || member.isForwardingStub) &&
+      member.isAbstract) {
+    // Skip abstract forwarding stubs. These are never emitted but they
+    // might shadow the inclusion of a mixed in method in code like:
+    //
+    //     class Super {}
+    //     class Mixin<T> {
+    //       void method(T t) {}
+    //     }
+    //     class Class extends Super with Mixin<int> {}
+    //     main() => new Class().method();
+    //
+    // Here a stub is created for `Super&Mixin.method` hiding that
+    // `Mixin.method` is inherited by `Class`.
+    return true;
+  }
+  if (cls != null &&
+      (member.isMemberSignature || member.isForwardingStub) &&
+      cls.isAnonymousMixin) {
+    return true;
+  }
+  return false;
+}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index b0c227b..8c34549 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -325,17 +325,38 @@
         data.isMixinApplication = false;
         data.interfaces = const <InterfaceType>[];
       } else {
-        InterfaceType processSupertype(ir.Supertype node) {
-          InterfaceType supertype = _typeConverter.visitSupertype(node);
+        // Set of canonical supertypes.
+        //
+        // This is necessary to support when a class implements the same
+        // supertype in multiple non-conflicting ways, like implementing A<int*>
+        // and A<int?> or B<Object?> and B<dynamic>.
+        Set<InterfaceType> canonicalSupertypes = <InterfaceType>{};
+
+        InterfaceType processSupertype(ir.Supertype supertypeNode) {
+          supertypeNode = classHierarchy.getClassAsInstanceOf(
+              node, supertypeNode.classNode);
+          InterfaceType supertype =
+              _typeConverter.visitSupertype(supertypeNode);
+          canonicalSupertypes.add(supertype);
           IndexedClass superclass = supertype.element;
           KClassData superdata = classes.getData(superclass);
           _ensureSupertypes(superclass, superdata);
+          for (InterfaceType supertype in superdata.orderedTypeSet.supertypes) {
+            ir.Supertype canonicalSupertype = classHierarchy
+                .getClassAsInstanceOf(node, getClassNode(supertype.element));
+            if (canonicalSupertype != null) {
+              supertype = _typeConverter.visitSupertype(canonicalSupertype);
+            } else {
+              assert(supertype.typeArguments.isEmpty,
+                  "Generic synthetic supertypes are not supported");
+            }
+            canonicalSupertypes.add(supertype);
+          }
           return supertype;
         }
 
         InterfaceType supertype;
-        ir.LinkBuilder<InterfaceType> linkBuilder =
-            new ir.LinkBuilder<InterfaceType>();
+        List<InterfaceType> interfaces = <InterfaceType>[];
         if (node.isMixinDeclaration) {
           // A mixin declaration
           //
@@ -353,7 +374,7 @@
           // so we need get the superclasses from the on-clause, A, B, and C,
           // through [superclassConstraints].
           for (ir.Supertype constraint in node.superclassConstraints()) {
-            linkBuilder.addLast(processSupertype(constraint));
+            interfaces.add(processSupertype(constraint));
           }
           // Set superclass to `Object`.
           supertype = _commonElements.objectType;
@@ -364,26 +385,26 @@
           ClassEntity defaultSuperclass =
               _commonElements.getDefaultSuperclass(cls, nativeBasicData);
           data.supertype = _elementEnvironment.getRawType(defaultSuperclass);
+          assert(data.supertype.typeArguments.isEmpty,
+              "Generic default supertypes are not supported");
+          canonicalSupertypes.add(data.supertype);
         } else {
           data.supertype = supertype;
         }
         if (node.mixedInType != null) {
           data.isMixinApplication = true;
-          linkBuilder
-              .addLast(data.mixedInType = processSupertype(node.mixedInType));
+          interfaces.add(data.mixedInType = processSupertype(node.mixedInType));
         } else {
           data.isMixinApplication = false;
         }
         node.implementedTypes.forEach((ir.Supertype supertype) {
-          linkBuilder.addLast(processSupertype(supertype));
+          interfaces.add(processSupertype(supertype));
         });
-        ir.Link<InterfaceType> interfaces =
-            linkBuilder.toLink(const ir.Link<InterfaceType>());
         OrderedTypeSetBuilder setBuilder =
             new KernelOrderedTypeSetBuilder(this, cls);
-        data.orderedTypeSet = setBuilder.createOrderedTypeSet(
-            data.supertype, interfaces.reverse(const ir.Link<InterfaceType>()));
-        data.interfaces = new List<InterfaceType>.from(interfaces.toList());
+        data.orderedTypeSet =
+            setBuilder.createOrderedTypeSet(canonicalSupertypes);
+        data.interfaces = interfaces;
       }
     }
   }
@@ -511,12 +532,16 @@
       }
     }
     List<String> namedParameters = <String>[];
+    Set<String> requiredNamedParameters = <String>{};
     List<DartType> namedParameterTypes = <DartType>[];
     List<ir.VariableDeclaration> sortedNamedParameters =
         node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
     for (ir.VariableDeclaration variable in sortedNamedParameters) {
       namedParameters.add(variable.name);
       namedParameterTypes.add(getParameterType(variable));
+      if (variable.isRequired && !options.useLegacySubtyping) {
+        requiredNamedParameters.add(variable.name);
+      }
     }
     List<FunctionTypeVariable> typeVariables;
     if (node.typeParameters.isNotEmpty) {
@@ -550,6 +575,7 @@
         parameterTypes,
         optionalParameterTypes,
         namedParameters,
+        requiredNamedParameters,
         namedParameterTypes,
         typeVariables);
   }
@@ -813,13 +839,25 @@
       // constructors like calling a generic method.
       {bool includeTypeParameters: true}) {
     // TODO(johnniwinther): Cache the computed function type.
-    int requiredParameters = node.requiredParameterCount;
+    int requiredPositionalParameters = node.requiredParameterCount;
     int positionalParameters = node.positionalParameters.length;
     int typeParameters = node.typeParameters.length;
-    List<String> namedParameters =
-        node.namedParameters.map((p) => p.name).toList()..sort();
-    return new ParameterStructure(requiredParameters, positionalParameters,
-        namedParameters, includeTypeParameters ? typeParameters : 0);
+    List<String> namedParameters = <String>[];
+    Set<String> requiredNamedParameters = <String>{};
+    List<ir.VariableDeclaration> sortedNamedParameters =
+        node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
+    for (var variable in sortedNamedParameters) {
+      namedParameters.add(variable.name);
+      if (variable.isRequired && !options.useLegacySubtyping) {
+        requiredNamedParameters.add(variable.name);
+      }
+    }
+    return new ParameterStructure(
+        requiredPositionalParameters,
+        positionalParameters,
+        namedParameters,
+        requiredNamedParameters,
+        includeTypeParameters ? typeParameters : 0);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 517787b..23a170d 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -25,6 +25,7 @@
 import '../ordered_typeset.dart';
 import '../ssa/type_builder.dart';
 import '../universe/member_usage.dart';
+import 'element_map.dart';
 import 'element_map_impl.dart';
 
 /// Environment for fast lookup of component libraries.
@@ -388,26 +389,7 @@
 
     void addProcedure(ir.Procedure member,
         {bool includeStatic, bool includeNoSuchMethodForwarders}) {
-      if ((member.isMemberSignature || member.isForwardingStub) &&
-          member.isAbstract) {
-        // Skip abstract forwarding stubs. These are never emitted but they
-        // might shadow the inclusion of a mixed in method in code like:
-        //
-        //     class Super {}
-        //     class Mixin<T> {
-        //       void method(T t) {}
-        //     }
-        //     class Class extends Super with Mixin<int> {}
-        //     main() => new Class().method();
-        //
-        // Here a stub is created for `Super&Mixin.method` hiding that
-        // `Mixin.method` is inherited by `Class`.
-        return;
-      }
-      if ((member.isMemberSignature || member.isForwardingStub) &&
-          cls.isAnonymousMixin) {
-        return;
-      }
+      if (memberIsIgnorable(member, cls: cls)) return;
       if (!includeStatic && member.isStatic) return;
       if (member.isNoSuchMethodForwarder) {
         // TODO(sigmund): remove once #33732 is fixed.
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index a218e6a..1f754e04 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -118,6 +118,13 @@
       }
       if (component == null) return null;
 
+      // TODO(sigmund): remove after we unfork the sdk, and force null-safety to
+      // always be considered to be true.
+      if (component.libraries.any((lib) =>
+          lib.isNonNullableByDefault && lib.importUri.scheme == 'dart')) {
+        _options.useNullSafety = true;
+      }
+
       if (_options.cfeOnly) {
         measureSubtask('serialize dill', () {
           _reporter.log('Writing dill to ${_options.outputUri}');
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 11f838f..2f6b7dc 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -199,6 +199,10 @@
   /// after a transitional period.
   bool useDumpInfoBinaryFormat = false;
 
+  /// If set, SSA intermediate form is dumped for methods with names matching
+  /// this RegExp pattern.
+  String dumpSsaPattern = null;
+
   /// Whether we allow passing an extra argument to `assert`, containing a
   /// reason for why an assertion fails. (experimental)
   ///
@@ -332,9 +336,12 @@
   /// Whether to use the new RTI representation (default).
   bool useNewRti = true;
 
-  /// Whether null-safety (non-nullable types) are enabled.
-  bool get useNullSafety =>
-      languageExperiments[fe.ExperimentalFlag.nonNullable];
+  /// Whether null-safety (non-nullable types) are enabled in the sdk.
+  ///
+  /// This may be true either when `--enable-experiment=non-nullable` is
+  /// provided on the command-line, or when the provided .dill file for the sdk
+  /// was built with null-safety enabled.
+  bool useNullSafety = false;
 
   /// When null-safety is enabled, whether the compiler should emit code with
   /// weak or strong semantics.
@@ -376,22 +383,11 @@
       void Function(String) onWarning}) {
     Map<fe.ExperimentalFlag, bool> languageExperiments =
         _extractExperiments(options, onError: onError, onWarning: onWarning);
-    if (equalMaps(languageExperiments, fe.defaultExperimentalFlags)) {
-      platformBinaries ??= fe.computePlatformBinariesLocation();
-    } else {
-      // TODO(sigmund): change these defaults before we unfork the sdk.
-      // To unfork the plan is to accept the same platform files regardless of
-      // the experiment flag (it will be enabled in the sdk regardless).
-      if (_hasOption(options, Flags.testMode) &&
-          languageExperiments[fe.ExperimentalFlag.nonNullable]) {
-        var experimentWithoutNullability = Map.of(languageExperiments);
-        experimentWithoutNullability[fe.ExperimentalFlag.nonNullable] = false;
-        if (equalMaps(
-            experimentWithoutNullability, fe.defaultExperimentalFlags)) {
-          platformBinaries ??= fe.computePlatformBinariesLocation();
-        }
-      }
-    }
+
+    // The null safety experiment can result in requiring different experiments
+    // for compiling user code vs. the sdk. To simplify things, we prebuild the
+    // sdk with the correct flags.
+    platformBinaries ??= fe.computePlatformBinariesLocation();
     return new CompilerOptions()
       ..librariesSpecificationUri = librariesSpecificationUri
       ..allowMockCompilation = _hasOption(options, Flags.allowMockCompilation)
@@ -423,6 +419,8 @@
       ..dumpInfo = _hasOption(options, Flags.dumpInfo)
       ..useDumpInfoBinaryFormat =
           _hasOption(options, "${Flags.dumpInfo}=binary")
+      ..dumpSsaPattern =
+          _extractStringOption(options, '${Flags.dumpSsa}=', null)
       ..enableMinification = _hasOption(options, Flags.minify)
       .._disableMinification = _hasOption(options, Flags.noMinify)
       ..enableNativeLiveTypeAnalysis =
@@ -441,8 +439,7 @@
       ..useNewRti = !_hasOption(options, Flags.useOldRti)
       ..generateSourceMap = !_hasOption(options, Flags.noSourceMaps)
       ..outputUri = _extractUriOption(options, '--out=')
-      ..platformBinaries =
-          platformBinaries ?? _extractUriOption(options, '--platform-binaries=')
+      ..platformBinaries = platformBinaries
       ..printLegacyStars = _hasOption(options, Flags.printLegacyStars)
       ..sourceMapUri = _extractUriOption(options, '--source-map=')
       ..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
@@ -513,6 +510,10 @@
     if (_noLegacyJavaScript) legacyJavaScript = false;
     if (_legacyJavaScript) legacyJavaScript = true;
 
+    if (languageExperiments[fe.ExperimentalFlag.nonNullable]) {
+      useNullSafety = true;
+    }
+
     if (optimizationLevel != null) {
       if (optimizationLevel == 0) {
         disableInlining = true;
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index d732744..dcbcf37 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -195,8 +195,7 @@
 ///     B: [B, Object]
 ///     C: [C, B, A, Object]
 abstract class OrderedTypeSetBuilder {
-  OrderedTypeSet createOrderedTypeSet(
-      InterfaceType supertype, Link<DartType> interfaces);
+  OrderedTypeSet createOrderedTypeSet(Set<InterfaceType> canonicalSupertypes);
 }
 
 abstract class OrderedTypeSetBuilderBase implements OrderedTypeSetBuilder {
@@ -215,41 +214,14 @@
   OrderedTypeSet getOrderedTypeSet(covariant ClassEntity cls);
 
   @override
-  OrderedTypeSet createOrderedTypeSet(
-      InterfaceType supertype, Link<DartType> interfaces) {
-    // TODO(15296): Collapse these iterations to one when the order is not
-    // needed.
-    add(supertype);
-    for (Link<DartType> link = interfaces; !link.isEmpty; link = link.tail) {
-      add(link.head);
-    }
-
-    _addAllSupertypes(supertype);
-    for (Link<DartType> link = interfaces; !link.isEmpty; link = link.tail) {
-      _addAllSupertypes(link.head);
+  OrderedTypeSet createOrderedTypeSet(Set<InterfaceType> canonicalSupertypes) {
+    for (InterfaceType supertype in canonicalSupertypes) {
+      add(supertype);
     }
     add(getThisType(cls));
     return toTypeSet();
   }
 
-  /// Adds [type] and all supertypes of [type] to [allSupertypes] while
-  /// substituting type variables.
-  void _addAllSupertypes(InterfaceType type) {
-    ClassEntity classElement = type.element;
-    Link<InterfaceType> supertypes = getOrderedTypeSet(classElement).supertypes;
-    assert(
-        supertypes != null,
-        failedAt(
-            cls,
-            "Supertypes not computed on $classElement "
-            "during resolution of $cls"));
-    while (!supertypes.isEmpty) {
-      InterfaceType supertype = supertypes.head;
-      add(substByContext(supertype, type));
-      supertypes = supertypes.tail;
-    }
-  }
-
   void add(InterfaceType type) {
     if (type.element == cls) {
       _addAtDepth(type, maxDepth + 1);
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index 27435a1..fb968a5 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -232,8 +232,10 @@
             new List<ir.NamedType>(namedParameterCount);
         for (int index = 0; index < namedParameterCount; index++) {
           String name = readString();
+          bool isRequired = readBool();
           ir.DartType type = _readDartTypeNode(functionTypeVariables);
-          namedParameters[index] = new ir.NamedType(name, type);
+          namedParameters[index] =
+              new ir.NamedType(name, type, isRequired: isRequired);
         }
         ir.TypedefType typedefType = _readDartTypeNode(functionTypeVariables);
         end(functionTypeNodeTag);
diff --git a/pkg/compiler/lib/src/serialization/helpers.dart b/pkg/compiler/lib/src/serialization/helpers.dart
index 61023e8..5232b87 100644
--- a/pkg/compiler/lib/src/serialization/helpers.dart
+++ b/pkg/compiler/lib/src/serialization/helpers.dart
@@ -215,6 +215,7 @@
     _sink.writeInt(node.namedParameters.length);
     for (ir.NamedType parameter in node.namedParameters) {
       _sink.writeString(parameter.name);
+      _sink.writeBool(parameter.isRequired);
       _sink._writeDartTypeNode(parameter.type, functionTypeVariables);
     }
     _sink._writeDartTypeNode(node.typedefType, functionTypeVariables,
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index de9a007..11272be 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -365,6 +365,9 @@
         }
         break;
       case OutputType.debug:
+        if (name == '') {
+          name = out.pathSegments.last;
+        }
         uri = out.resolve('$name.$extension');
         break;
       default:
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index bd8c171..ba9f5f6 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -705,22 +705,29 @@
     for (TypeVariableType typeVariable
         in _elementEnvironment.getFunctionTypeVariables(function)) {
       HInstruction param;
+      bool erased = false;
       if (elideTypeParameters) {
         // Add elided type parameters.
         param = _computeTypeArgumentDefaultValue(function, typeVariable);
+        erased = true;
       } else if (needsTypeArguments) {
         param = addParameter(
             typeVariable.element, _abstractValueDomain.nonNullType);
       } else {
-        // Unused, so bind to `dynamic`.
-        param = graph.addConstantNull(closedWorld);
+        // Unused, so bind to bound.
+        param = _computeTypeArgumentDefaultValue(function, typeVariable);
+        erased = true;
       }
       Local local = localsHandler.getTypeVariableAsLocal(typeVariable);
       localsHandler.directLocals[local] = param;
-      _functionTypeParameterLocals.add(local);
+      if (!erased) {
+        _functionTypeParameterLocals.add(local);
+      }
     }
   }
 
+  // Locals for function type parameters that can be forwarded, in argument
+  // position order.
   List<Local> _functionTypeParameterLocals = <Local>[];
 
   /// Builds a generative constructor.
@@ -1392,6 +1399,9 @@
     DartType elementType = _elementEnvironment.getAsyncOrSyncStarElementType(
         function.asyncMarker, _returnType);
 
+    // TODO(sra): [elementType] can contain free type variables that are erased
+    // due to no rtiNeed. We will get getter code if these type variables are
+    // substituted with an <any> or <erased> type.
     if (elementType.containsFreeTypeVariables) {
       // Type must be computed in the entry function, where the type variables
       // are in scope, and passed to the body function.
@@ -1494,7 +1504,8 @@
         newParameter = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
             targetElement, newParameter, type);
       } else {
-        newParameter = _typeBuilder.trustTypeOfParameter(newParameter, type);
+        newParameter = _typeBuilder.trustTypeOfParameter(
+            targetElement, newParameter, type);
       }
 
       localsHandler.directLocals[local] = newParameter;
@@ -6335,7 +6346,8 @@
       DartType type = localsMap.getLocalType(_elementMap, parameter);
       HInstruction checkedOrTrusted;
       if (trusted) {
-        checkedOrTrusted = _typeBuilder.trustTypeOfParameter(argument, type);
+        checkedOrTrusted =
+            _typeBuilder.trustTypeOfParameter(function, argument, type);
       } else {
         checkedOrTrusted = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
             function, argument, type);
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index b5848269..781976a 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -3518,7 +3518,13 @@
         break;
 
       case IsTestSpecialization.instanceof:
-        InterfaceType type = node.dartType;
+        DartType dartType = node.dartType;
+        // We don't generate instancof specializations for Never* and Object*.
+        assert(dartType is InterfaceType ||
+            (dartType is LegacyType &&
+                !dartType.baseType.isObject &&
+                dartType.baseType is! NeverType));
+        InterfaceType type = dartType.withoutNullability;
         _registry.registerTypeUse(TypeUse.instanceConstructor(type));
         test = handleNegative(js.js('# instanceof #',
             [value, _emitter.constructorAccess(type.element)]));
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 695aca3..414e7a3 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -4636,8 +4636,19 @@
   // is definitely false, so we reuse some of the case-by-case logic from the
   // old [HIs] optimization.
   if (closedWorld.dartTypes.isTopType(dartType)) return AbstractBool.True;
-  if (dartType is! InterfaceType) return AbstractBool.Maybe;
-  InterfaceType type = dartType;
+
+  InterfaceType type;
+  if (dartType is InterfaceType) {
+    type = dartType;
+  } else if (dartType is LegacyType) {
+    DartType base = dartType.baseType;
+    if (base is! InterfaceType) return AbstractBool.Maybe;
+    assert(!base.isObject); // Top type handled above;
+    type = base;
+  } else {
+    return AbstractBool.Maybe;
+  }
+
   ClassEntity element = type.element;
   if (type.typeArguments.isNotEmpty) return AbstractBool.Maybe;
   JCommonElements commonElements = closedWorld.commonElements;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 4f2dfa8..6b65f2a 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -903,7 +903,7 @@
       // @Native methods have conversion code for function arguments. Rather
       // than insert that code at the inlined call site, call the target on the
       // interceptor.
-      if (parameterType is FunctionType) return true;
+      if (parameterType.withoutNullability is FunctionType) return true;
     }
 
     if (!_closedWorld.annotationsData
@@ -2133,8 +2133,8 @@
     if (typeInput is HLoadType) {
       TypeExpressionRecipe recipe = typeInput.typeExpression;
       DartType dartType = recipe.type;
-      MemberEntity specializedCheck =
-          SpecializedChecks.findAsCheck(dartType, _closedWorld.commonElements);
+      MemberEntity specializedCheck = SpecializedChecks.findAsCheck(
+          dartType, _closedWorld.commonElements, _options.useLegacySubtyping);
       if (specializedCheck != null) {
         AbstractValueWithPrecision checkedType =
             _abstractValueDomain.createFromStaticType(dartType, nullable: true);
@@ -2185,11 +2185,8 @@
       }
 
       if (specialization != null) {
-        AbstractValueWithPrecision checkedType =
-            _abstractValueDomain.createFromStaticType(dartType,
-                nullable: _abstractValueDomain
-                    .isNull(node.checkedAbstractValue.abstractValue)
-                    .isPotentiallyTrue);
+        AbstractValueWithPrecision checkedType = _abstractValueDomain
+            .createFromStaticType(dartType, nullable: false);
         return HIsTestSimple(dartType, checkedType, specialization,
             node.checkedInput, _abstractValueDomain.boolType);
       }
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index f7269a3..36218f3 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -53,10 +53,15 @@
     if (type == null) return null;
     type = builder.localsHandler.substInContext(type);
     if (_closedWorld.dartTypes.isTopType(type)) return null;
+    bool includeNull =
+        _closedWorld.dartTypes.useLegacySubtyping || type is NullableType;
+    type = type.withoutNullability;
     if (type is! InterfaceType) return null;
     // The type element is either a class or the void element.
     ClassEntity element = (type as InterfaceType).element;
-    return _abstractValueDomain.createNullableSubtype(element);
+    return includeNull
+        ? _abstractValueDomain.createNullableSubtype(element)
+        : _abstractValueDomain.createNonNullSubtype(element);
   }
 
   /// Create an instruction to simply trust the provided type.
@@ -102,8 +107,17 @@
     return checkInstruction;
   }
 
-  HInstruction trustTypeOfParameter(HInstruction original, DartType type) {
+  HInstruction trustTypeOfParameter(
+      MemberEntity memberContext, HInstruction original, DartType type) {
     if (type == null) return original;
+
+    /// Dart semantics check against null outside the method definition,
+    /// however dart2js moves the null check to the callee for performance
+    /// reasons. As a result the body cannot trust or check that the type is not
+    /// nullable.
+    if (builder.options.useNullSafety && memberContext.name == '==') {
+      type = _closedWorld.dartTypes.nullableType(type);
+    }
     HInstruction trusted = _trustType(original, type);
     if (trusted == original) return original;
     if (trusted is HTypeKnown && trusted.isRedundant(builder.closedWorld)) {
@@ -119,6 +133,14 @@
     HInstruction checkedOrTrusted = original;
     CheckPolicy parameterCheckPolicy = builder.closedWorld.annotationsData
         .getParameterCheckPolicy(memberContext);
+
+    /// Dart semantics check against null outside the method definition,
+    /// however dart2js moves the null check to the callee for performance
+    /// reasons. As a result the body cannot trust or check that the type is not
+    /// nullable.
+    if (builder.options.useNullSafety && memberContext.name == '==') {
+      type = _closedWorld.dartTypes.nullableType(type);
+    }
     if (parameterCheckPolicy.isTrusted) {
       checkedOrTrusted = _trustType(original, type);
     } else if (parameterCheckPolicy.isEmitted) {
diff --git a/pkg/compiler/lib/src/tracer.dart b/pkg/compiler/lib/src/tracer.dart
index 66564af..a02c499 100644
--- a/pkg/compiler/lib/src/tracer.dart
+++ b/pkg/compiler/lib/src/tracer.dart
@@ -5,19 +5,12 @@
 library tracer;
 
 import '../compiler_new.dart' as api;
+import 'options.dart' show CompilerOptions;
 import 'ssa/nodes.dart' as ssa show HGraph;
 import 'ssa/ssa_tracer.dart' show HTracer;
 import 'util/util.dart' show Indentation;
 import 'world.dart' show JClosedWorld;
 
-/// If non-null, we only trace methods whose name match the regexp defined by
-/// the given pattern.
-String get TRACE_FILTER_PATTERN => TRACE_FILTER_PATTERN_FROM_ENVIRONMENT != ''
-    ? TRACE_FILTER_PATTERN_FROM_ENVIRONMENT
-    : TRACE_FILTER_PATTERN_FOR_TEST;
-
-const String TRACE_FILTER_PATTERN_FROM_ENVIRONMENT =
-    String.fromEnvironment("DUMP_IR", defaultValue: "");
 String TRACE_FILTER_PATTERN_FOR_TEST;
 
 /// Dumps the intermediate representation after each phase in a format
@@ -29,14 +22,17 @@
   final api.OutputSink output;
   final RegExp traceFilter;
 
-  Tracer(this.closedWorld, api.CompilerOutput compilerOutput)
-      : traceFilter = TRACE_FILTER_PATTERN == null
-            ? null
-            : new RegExp(TRACE_FILTER_PATTERN),
-        output = TRACE_FILTER_PATTERN != null
-            ? compilerOutput.createOutputSink(
-                'dart', 'cfg', api.OutputType.debug)
-            : null;
+  Tracer._(this.closedWorld, this.traceFilter, this.output);
+
+  factory Tracer(JClosedWorld closedWorld, CompilerOptions options,
+      api.CompilerOutput compilerOutput) {
+    String pattern = options.dumpSsaPattern ?? TRACE_FILTER_PATTERN_FOR_TEST;
+    if (pattern == null) return Tracer._(closedWorld, null, null);
+    var traceFilter = RegExp(pattern);
+    var output =
+        compilerOutput.createOutputSink('', 'cfg', api.OutputType.debug);
+    return Tracer._(closedWorld, traceFilter, output);
+  }
 
   bool get isEnabled => traceFilter != null;
 
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 5410034..45603b8 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -147,9 +147,9 @@
   }
 
   bool signatureApplies(ParameterStructure parameters) {
-    int requiredParameterCount = parameters.requiredParameters;
+    int requiredParameterCount = parameters.requiredPositionalParameters;
     int optionalParameterCount = parameters.optionalParameters;
-    int parameterCount = requiredParameterCount + optionalParameterCount;
+    int parameterCount = parameters.totalParameters;
     if (argumentCount > parameterCount) return false;
     if (positionalArgumentCount < requiredParameterCount) return false;
     if (typeArgumentCount != 0) {
@@ -166,15 +166,22 @@
     } else {
       if (positionalArgumentCount > requiredParameterCount) return false;
       assert(positionalArgumentCount == requiredParameterCount);
-      if (namedArgumentCount > optionalParameterCount) return false;
+      if (namedArgumentCount >
+          optionalParameterCount + parameters.requiredNamedParameters.length)
+        return false;
 
       int nameIndex = 0;
       List<String> namedParameters = parameters.namedParameters;
+      int seenRequiredNamedParameters = 0;
+
       for (String name in getOrderedNamedArguments()) {
         bool found = false;
         // Note: we start at the existing index because arguments are sorted.
         while (nameIndex < namedParameters.length) {
-          if (name == namedParameters[nameIndex]) {
+          String parameterName = namedParameters[nameIndex];
+          if (name == parameterName) {
+            if (parameters.requiredNamedParameters.contains(name))
+              seenRequiredNamedParameters++;
             found = true;
             break;
           }
@@ -182,7 +189,8 @@
         }
         if (!found) return false;
       }
-      return true;
+      return seenRequiredNamedParameters ==
+          parameters.requiredNamedParameters.length;
     }
   }
 
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index 92ded95..1cb6aff 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -218,7 +218,7 @@
       case RuntimeTypeUseKind.equals:
         sb.write('equals:');
         sb.write(receiverType);
-        sb.write('/');
+        sb.write('==');
         sb.write(argumentType);
         break;
       case RuntimeTypeUseKind.unknown:
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index 5fae2da..de26a23 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -707,7 +707,7 @@
     _hasInvoke = false;
     _areAllTypeParametersProvided = _parameterStructure.typeParameters == 0;
     _providedPositionalParameters = _parameterStructure.positionalParameters ==
-            _parameterStructure.requiredParameters
+            _parameterStructure.requiredPositionalParameters
         ? null
         : 0;
     if (!_parameterStructure.namedParameters.isEmpty) {
@@ -777,7 +777,7 @@
     if (!_hasInvoke) return null;
     if (isFullyUsed) return _parameterStructure;
     return new ParameterStructure(
-        _parameterStructure.requiredParameters,
+        _parameterStructure.requiredPositionalParameters,
         _providedPositionalParameters ??
             _parameterStructure.positionalParameters,
         _unprovidedNamedParameters == null
@@ -785,6 +785,7 @@
             : _parameterStructure.namedParameters
                 .where((n) => !_unprovidedNamedParameters.contains(n))
                 .toList(),
+        _parameterStructure.requiredNamedParameters,
         _areAllTypeParametersProvided ? _parameterStructure.typeParameters : 0);
   }
 
diff --git a/pkg/dart2native/pubspec.yaml b/pkg/dart2native/pubspec.yaml
index feca449..c89834f 100644
--- a/pkg/dart2native/pubspec.yaml
+++ b/pkg/dart2native/pubspec.yaml
@@ -1,6 +1,9 @@
 name: dart2native
 publish_to: none
 
+environment:
+  sdk: "^2.7.0"
+
 # Add the bin/dart2native.dart script to the scripts pub installs.
 executables:
   dart2native:
diff --git a/pkg/dart_internal/analysis_options.yaml b/pkg/dart_internal/analysis_options.yaml
index 1a46de2..edcd64e 100644
--- a/pkg/dart_internal/analysis_options.yaml
+++ b/pkg/dart_internal/analysis_options.yaml
@@ -1,3 +1,5 @@
 analyzer:
+  errors:
+    import_internal_library: ignore
   strong-mode:
     implicit-casts: false
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 0b34601..62180a8 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -24,6 +24,8 @@
 
     argParser.addFlag('verbose',
         abbr: 'v', negatable: false, help: 'Show verbose output.');
+    argParser.addFlag('version',
+        negatable: false, help: 'Print the Dart SDK version.');
 
     addCommand(AnalyzeCommand(verbose: verbose));
     addCommand(CreateCommand(verbose: verbose));
@@ -35,6 +37,10 @@
   }
 
   @override
+  String get invocation =>
+      'dart [<vm-flags>] <command|dart-file> [<arguments>]';
+
+  @override
   Future<int> runCommand(ArgResults results) async {
     isVerbose = results['verbose'];
 
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index c7089b1..5c6cd31 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -12,8 +12,8 @@
 
 class RunCommand extends DartdevCommand<int> {
   final ArgParser argParser = ArgParser.allowAnything();
-
-  RunCommand({bool verbose = false}) : super('run', '''
+  final bool verbose;
+  RunCommand({this.verbose = false}) : super('run', '''
 Run a Dart file.''');
 
   @override
@@ -25,7 +25,11 @@
     // execute [run] below.  Without this, the 'dart help run' reports the
     // command pub with no commands or flags.
     final command = sdk.dart;
-    final args = ['--help'];
+    final args = [
+      '--disable-dart-dev',
+      '--help',
+      if (verbose) '--verbose',
+    ];
 
     log.trace('$command ${args.first}');
 
@@ -49,7 +53,8 @@
 
     // Starting in ProcessStartMode.inheritStdio mode means the child process
     // can detect support for ansi chars.
-    var process = await Process.start(sdk.dart, args,
+    final process = await Process.start(
+        sdk.dart, ['--disable-dart-dev', ...args],
         mode: ProcessStartMode.inheritStdio);
     return process.exitCode;
   }
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index c8d5b3d..29c4d07 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -7,7 +7,7 @@
 import '../utils.dart';
 
 void main() {
-  group('analyze', defineAnalyze, timeout: defaultTimeout);
+  group('analyze', defineAnalyze, timeout: longTimeout);
 }
 
 const String _analyzeDescriptionText = "Analyze the project's Dart code.";
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 4eaee40..08ff9e3 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -12,7 +12,7 @@
 import '../utils.dart';
 
 void main() {
-  group('create', defineCreateTests);
+  group('create', defineCreateTests, timeout: longTimeout);
 }
 
 void defineCreateTests() {
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 67820a5..b18b6e5 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -9,8 +9,8 @@
 import '../utils.dart';
 
 void main() {
-  group('command', command);
-  group('flag', help);
+  group('command', command, timeout: longTimeout);
+  group('flag', help, timeout: longTimeout);
 }
 
 void command() {
@@ -47,7 +47,8 @@
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains(DartdevRunner.dartdevDescription));
-    expect(result.stdout, contains('Usage: dart <command> [arguments]'));
+    expect(result.stdout,
+        contains('Usage: dart [<vm-flags>] <command|dart-file> [<arguments>]'));
     expect(result.stdout, contains('Global options:'));
     expect(result.stdout, contains('Available commands:'));
     expect(result.stdout, contains('analyze '));
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
index 74c5c50..15dd356 100644
--- a/pkg/dartdev/test/commands/format_test.dart
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -9,7 +9,7 @@
 import '../utils.dart';
 
 void main() {
-  group('format', format);
+  group('format', format, timeout: longTimeout);
 }
 
 void format() {
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index 204e4a0..eef0589 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -9,7 +9,7 @@
 import '../utils.dart';
 
 void main() {
-  group('help', help);
+  group('help', help, timeout: longTimeout);
 }
 
 void help() {
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 1294f88..c3d2c97 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -8,7 +8,7 @@
 import '../utils.dart';
 
 void main() {
-  group('migrate', defineMigrateTests);
+  group('migrate', defineMigrateTests, timeout: longTimeout);
 }
 
 // TODO(jcollins-g): Set to true and/or remove when when NNBD is enabled in the
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index fa49271..b8a98ee 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -7,7 +7,7 @@
 import '../utils.dart';
 
 void main() {
-  group('pub', pub);
+  group('pub', pub, timeout: longTimeout);
 }
 
 void pub() {
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 3699c92..214207c 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -9,7 +9,7 @@
 import '../utils.dart';
 
 void main() {
-  group('run', run);
+  group('run', run, timeout: longTimeout);
 }
 
 void run() {
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index e1e9b5c..3f2ea70 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -7,7 +7,7 @@
 import '../utils.dart';
 
 void main() {
-  group('test', defineTest);
+  group('test', defineTest, timeout: longTimeout);
 }
 
 void defineTest() {
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 24db6fa..f191eaa 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -7,7 +7,10 @@
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
-Timeout defaultTimeout = Timeout(Duration(seconds: 15));
+/// A long [Timeout] is provided for tests that start a process on
+/// `bin/dartdev.dart` as the command is not compiled ahead of time, and each
+/// invocation requires the VM to compile the entire dependency graph.
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
 
 TestProject project({String mainSrc, String analysisOptions}) {
   return TestProject(mainSrc: mainSrc, analysisOptions: analysisOptions);
diff --git a/pkg/dartfix/CHANGELOG.md b/pkg/dartfix/CHANGELOG.md
index de84535..0b0c65d 100644
--- a/pkg/dartfix/CHANGELOG.md
+++ b/pkg/dartfix/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 0.1.7
+* Improve experimental non-nullable migration support.
+
 # 0.1.6
 * Improve experimental non-nullable migration support.
 
diff --git a/pkg/dartfix/lib/src/migrate/migrate.dart b/pkg/dartfix/lib/src/migrate/migrate.dart
index ceddcce..a7cb7a4 100644
--- a/pkg/dartfix/lib/src/migrate/migrate.dart
+++ b/pkg/dartfix/lib/src/migrate/migrate.dart
@@ -8,7 +8,7 @@
 import 'package:analysis_server_client/handler/notification_handler.dart';
 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:nnbd_migration/isolate_server.dart';
 import 'package:args/command_runner.dart';
 import 'package:cli_util/cli_logging.dart';
 import 'package:nnbd_migration/src/messages.dart';
@@ -88,18 +88,11 @@
 
     Map<String, List<AnalysisError>> fileErrors = {};
 
-    bool enableAsserts = false;
     String instrumentationLogFile;
-    bool profileServer = false;
-    String serverPath = options.serverPath;
-    int servicesPort;
     String sdkPath = options.sdkPath;
     bool stdioPassthrough = false;
 
     if (options.debug) {
-      enableAsserts = true;
-      profileServer = true;
-      servicesPort = 9500;
       stdioPassthrough = true;
       instrumentationLogFile = path.join(
           Directory.systemTemp.createTempSync('migration_debug').path,
@@ -116,11 +109,7 @@
       await server.start(
           clientId: 'dart $name',
           clientVersion: _dartSdkVersion,
-          enableAsserts: enableAsserts,
           instrumentationLogFile: instrumentationLogFile,
-          profileServer: profileServer,
-          serverPath: serverPath,
-          servicesPort: servicesPort,
           sdkPath: sdkPath);
       _ServerNotifications serverNotifications = _ServerNotifications(server);
       await serverNotifications.listenToServer(server);
@@ -200,6 +189,7 @@
       final EditDartfixParams params =
           EditDartfixParams([options.directoryAbsolute]);
       params.includedFixes = ['non-nullable'];
+      params.port = options.previewPort;
       json = await server.send(EDIT_REQUEST_DARTFIX, params.toJson());
       progress.finish(showTiming: true);
     } finally {
@@ -242,6 +232,8 @@
 
     if (options.webPreview) {
       String url = migrationResults.urls.first;
+      assert(migrationResults.urls.length <= 1,
+          'Got unexpected extra preview URLs from server');
 
       logger.stdout(ansi.emphasized('View migration results:'));
 
diff --git a/pkg/dartfix/lib/src/migrate/options.dart b/pkg/dartfix/lib/src/migrate/options.dart
index 20e2e67..f19908d 100644
--- a/pkg/dartfix/lib/src/migrate/options.dart
+++ b/pkg/dartfix/lib/src/migrate/options.dart
@@ -12,6 +12,7 @@
   static const applyChangesOption = 'apply-changes';
   static const debugOption = 'debug';
   static const ignoreErrorsOption = 'ignore-errors';
+  static const previewPortOption = 'preview-port';
   static const sdkPathOption = 'sdk-path';
   static const serverPathOption = 'server-path';
   static const webPreviewOption = 'web-preview';
@@ -20,6 +21,7 @@
   final bool debug;
   final String directory;
   final bool ignoreErrors;
+  final int previewPort;
   final String serverPath;
   final String sdkPath;
   final bool webPreview;
@@ -28,6 +30,8 @@
       : applyChanges = argResults[applyChangesOption] as bool,
         debug = argResults[debugOption] as bool,
         ignoreErrors = argResults[ignoreErrorsOption] as bool,
+        previewPort =
+            int.tryParse(argResults[previewPortOption] as String) ?? 0,
         sdkPath = argResults[sdkPathOption] as String,
         serverPath = argResults[serverPathOption] as String,
         webPreview = argResults['web-preview'] as bool;
@@ -67,6 +71,12 @@
       help: 'Override the SDK path used for migration.',
     );
     argParser.addOption(
+      previewPortOption,
+      defaultsTo: '0',
+      help: 'Run the preview server on the specified port.  If not specified '
+          'or invalid, dynamically allocate a port.',
+    );
+    argParser.addOption(
       serverPathOption,
       hide: true,
       help: 'Override the analysis server path used for migration.',
diff --git a/pkg/dartfix/pubspec.yaml b/pkg/dartfix/pubspec.yaml
index 628c71b..c8de0ad 100644
--- a/pkg/dartfix/pubspec.yaml
+++ b/pkg/dartfix/pubspec.yaml
@@ -1,11 +1,11 @@
 name: dartfix
-version: 0.1.6
+version: 0.1.7
 description:
   A tool for migrating Dart source to newer versions of the Dart SDK
   and fixing common issues.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dartfix
 environment:
-  sdk: '>=2.3.0 <3.0.0'
+  sdk: '>=2.8.0 <3.0.0'
 
 # Add the bin/dartfix.dart script to the scripts pub installs.
 executables:
@@ -17,10 +17,10 @@
   analysis_server_client: 1.1.3
   args: ^1.4.0
   cli_util: ^0.1.3
-  path: ^1.6.0
-  pub_semver: ^1.4.2
+  path: ^1.7.0
+  pub_semver: ^1.4.4
 
 dev_dependencies:
-  analyzer: ^0.37.0
+  analyzer: ^0.39.0
   pedantic: ^1.8.0
-  test: ^1.3.0
+  test: ^1.14.2
diff --git a/pkg/dds/dds_protocol.md b/pkg/dds/dds_protocol.md
index fb6fd82..c40b84d 100644
--- a/pkg/dds/dds_protocol.md
+++ b/pkg/dds/dds_protocol.md
@@ -8,14 +8,19 @@
 
 [JSON-RPC 2.0]: http://www.jsonrpc.org/specification
 
-
-**Table of Contents**
+## Table of Contents
 
 - [RPCs, Requests, and Responses](#rpcs-requests-and-responses)
 - [Events](#events)
 - [Types](#types)
 - [IDs and Names](#ids-and-names)
 - [Revision History](#revision-history)
+- [Public RPCs](#public-rpcs)
+  - [getClientName](#getclientname)
+  - [requirePermissionToResume](#requirepermissiontoresume)
+  - [setClientName](#setclientname)
+- [Public Types](#public-types)
+  - [ClientName](#clientname)
 
 ## RPCs, Requests, and Responses
 
@@ -41,16 +46,95 @@
 
 The DDS Protocol supports all [public RPCs defined in the VM Service protocol][service-protocol-public-rpcs].
 
+### getClientName
+
+```
+ClientName getClientName()
+```
+
+The _getClientName_ RPC is used to retrieve the name associated with the currently
+connected VM service client. If no name was previously set through the
+[setClientName](#setclientname) RPC, a default name will be returned.
+
+See [ClientName](#clientname)
+
+### requirePermissionToResume
+
+```
+Success requirePermissionToResume(bool onPauseStart [optional],
+                                  bool onPauseReload[optional],
+                                  bool onPauseExit [optional])
+```
+
+The _requirePermissionToResume_ RPC is used to change the pause/resume behavior
+of isolates by providing a way for the VM service to wait for approval to resume
+from some set of clients. This is useful for clients which want to perform some
+operation on an isolate after a pause without it being resumed by another client.
+
+If the _onPauseStart_ parameter is `true`, isolates will not resume after pausing
+on start until the client sends a `resume` request and all other clients which
+need to provide resume approval for this pause type have done so.
+
+If the _onPauseReload_ parameter is `true`, isolates will not resume after pausing
+after a reload until the client sends a `resume` request and all other clients
+which need to provide resume approval for this pause type have done so.
+
+If the _onPauseExit_ parameter is `true`, isolates will not resume after pausing
+on exit until the client sends a `resume` request and all other clients which
+need to provide resume approval for this pause type have done so.
+
+**Important Notes:**
+
+- All clients with the same client name share resume permissions. Only a
+  single client of a given name is required to provide resume approval.
+- When a client requiring approval disconnects from the service, a paused
+  isolate may resume if all other clients requiring resume approval have
+  already given approval. In the case that no other client requires resume
+  approval for the current pause event, the isolate will be resumed if at
+  least one other client has attempted to [resume](resume) the isolate.
+
+### setClientName
+
+```
+Success setClientName(string name)
+```
+
+The _setClientName_ RPC is used to set a name to be associated with the currently
+connected VM service client. If the _name_ parameter is a non-empty string, _name_
+will become the new name associated with the client. If _name_ is an empty string,
+the client's name will be reset to its default name.
+
+See [Success](#success).
+
+## Public Types
+
+The DDS Protocol supports all [public types defined in the VM Service protocol][service-protocol-public-types].
+
+### ClientName
+
+```
+class ClientName extends Response {
+  // The name of the currently connected VM service client.
+  string name;
+}
+```
+
+See [getClientName](#getclientname) and [setClientName](#setclientname).
+
 ## Revision History
 
 version | comments
 ------- | --------
 0.x | Initial revision
 
+[resume]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#resume
+[success]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#success
+
 [service-protocol]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md
 [service-protocol-rpcs-requests-and-responses]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses
 [service-protocol-events]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#events
 [service-protocol-binary-events]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#binary-events
 [service-protocol-types]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#types
 [service-protocol-ids-and-names]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#ids-and-names
-[service-protocol-public-rpcs]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#public-rpcs
\ No newline at end of file
+[service-protocol-public-rpcs]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#public-rpcs
+[service-protocol-public-types]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#public-types
\ No newline at end of file
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index d2bb5ea..4312c28 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -7,15 +7,31 @@
 library dds;
 
 import 'dart:async';
+import 'dart:collection';
+import 'dart:convert';
 import 'dart:io';
+import 'dart:typed_data';
 
+import 'package:async/async.dart';
+import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
+import 'package:meta/meta.dart';
+import 'package:pedantic/pedantic.dart';
 import 'package:shelf/shelf.dart';
 import 'package:shelf/shelf_io.dart' as io;
 import 'package:shelf_proxy/shelf_proxy.dart';
 import 'package:shelf_web_socket/shelf_web_socket.dart';
+import 'package:stream_channel/stream_channel.dart';
 import 'package:web_socket_channel/web_socket_channel.dart';
 
+part 'src/binary_compatible_peer.dart';
+part 'src/client.dart';
+part 'src/client_manager.dart';
+part 'src/constants.dart';
 part 'src/dds_impl.dart';
+part 'src/isolate_manager.dart';
+part 'src/named_lookup.dart';
+part 'src/rpc_error_codes.dart';
+part 'src/stream_manager.dart';
 
 /// An intermediary between a Dart VM service and its clients that offers
 /// additional functionality on top of the standard VM service protocol.
@@ -24,7 +40,8 @@
 /// for details.
 abstract class DartDevelopmentService {
   /// Creates a [DartDevelopmentService] instance which will communicate with a
-  /// VM service.
+  /// VM service. Requires the target VM service to have no other connected
+  /// clients.
   ///
   /// [remoteVmServiceUri] is the address of the VM service that this
   /// development service will communicate with.
@@ -85,3 +102,11 @@
   /// requests.
   bool get isRunning;
 }
+
+class DartDevelopmentServiceException implements Exception {
+  DartDevelopmentServiceException._(this.message);
+
+  String toString() => 'DartDevelopmentServiceException: $message';
+
+  final String message;
+}
diff --git a/pkg/dds/lib/src/binary_compatible_peer.dart b/pkg/dds/lib/src/binary_compatible_peer.dart
new file mode 100644
index 0000000..7c5b83b
--- /dev/null
+++ b/pkg/dds/lib/src/binary_compatible_peer.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dds;
+
+/// Adds support for binary events send from the VM service, which are not part
+/// of the official JSON RPC 2.0 specification.
+///
+/// A binary event from the VM service has the form:
+/// ```
+/// type BinaryEvent {
+///  dataOffset : uint32,
+///  metadata : uint8[dataOffset-4],
+///  data : uint8[],
+/// }
+/// ```
+/// where `metadata` is the JSON body of the event.
+///
+/// [_BinaryCompatiblePeer] assumes that only stream events can contain a
+/// binary payload (e.g., clients cannot send a `BinaryEvent` to the VM service).
+class _BinaryCompatiblePeer extends json_rpc.Peer {
+  _BinaryCompatiblePeer(WebSocketChannel ws, _StreamManager streamManager)
+      : super(
+          ws.transform<String>(
+            StreamChannelTransformer(
+              StreamTransformer<dynamic, String>.fromHandlers(
+                  handleData: (data, EventSink<String> sink) =>
+                      _transformStream(streamManager, data, sink)),
+              StreamSinkTransformer<String, dynamic>.fromHandlers(
+                handleData: (String data, EventSink<dynamic> sink) {
+                  sink.add(data);
+                },
+              ),
+            ),
+          ),
+        );
+
+  static void _transformStream(
+      _StreamManager streamManager, dynamic data, EventSink<String> sink) {
+    if (data is String) {
+      // Non-binary messages come in as Strings. Simply forward to the sink.
+      sink.add(data);
+    } else if (data is Uint8List) {
+      // Only binary events will result in `data` being of type Uint8List. We
+      // need to manually forward them here.
+      final bytesView =
+          ByteData.view(data.buffer, data.offsetInBytes, data.lengthInBytes);
+      const metadataOffset = 4;
+      final dataOffset = bytesView.getUint32(0, Endian.little);
+      final metadataLength = dataOffset - metadataOffset;
+      final metadata = Utf8Decoder().convert(new Uint8List.view(
+          bytesView.buffer,
+          bytesView.offsetInBytes + metadataOffset,
+          metadataLength));
+      final decodedMetadata = json.decode(metadata);
+      streamManager.streamNotify(decodedMetadata['params']['streamId'], data);
+    }
+  }
+}
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
new file mode 100644
index 0000000..2c19752
--- /dev/null
+++ b/pkg/dds/lib/src/client.dart
@@ -0,0 +1,167 @@
+// 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.
+
+part of dds;
+
+/// Representation of a single DDS client which manages the connection and
+/// DDS request intercepting / forwarding.
+class _DartDevelopmentServiceClient {
+  _DartDevelopmentServiceClient(
+    this.dds,
+    this.ws,
+    json_rpc.Peer vmServicePeer,
+  ) : _vmServicePeer = vmServicePeer {
+    _clientPeer = json_rpc.Peer(ws.cast<String>());
+    _registerJsonRpcMethods();
+  }
+
+  /// Start receiving JSON RPC requests from the client.
+  ///
+  /// Returned future completes when the peer is closed.
+  Future<void> listen() => _clientPeer.listen().then(
+        (_) => dds.streamManager.clientDisconnect(this),
+      );
+
+  /// Close the connection to the client.
+  Future<void> close() async {
+    // Cleanup the JSON RPC server for this connection if DDS has shutdown.
+    await _clientPeer.close();
+  }
+
+  /// Send a JSON RPC notification to the client.
+  void sendNotification(String method, [dynamic parameters]) {
+    if (_clientPeer.isClosed) {
+      return;
+    }
+    _clientPeer.sendNotification(method, parameters);
+  }
+
+  /// Send a JSON RPC request to the client.
+  Future<dynamic> sendRequest(String method, [dynamic parameters]) async {
+    if (_clientPeer.isClosed) {
+      return null;
+    }
+    return await _clientPeer.sendRequest(method, parameters);
+  }
+
+  /// Registers handlers for JSON RPC methods which need to be intercepted by
+  /// DDS as well as fallback request forwarder.
+  void _registerJsonRpcMethods() {
+    _clientPeer.registerMethod('streamListen', (parameters) async {
+      final streamId = parameters['streamId'].asString;
+      await dds.streamManager.streamListen(this, streamId);
+      return _RPCResponses.success;
+    });
+
+    _clientPeer.registerMethod('streamCancel', (parameters) async {
+      final streamId = parameters['streamId'].asString;
+      await dds.streamManager.streamCancel(this, streamId);
+      return _RPCResponses.success;
+    });
+
+    _clientPeer.registerMethod('registerService', (parameters) async {
+      final serviceId = parameters['service'].asString;
+      final alias = parameters['alias'].asString;
+      if (services.containsKey(serviceId)) {
+        throw _RpcErrorCodes.buildRpcException(
+          _RpcErrorCodes.kServiceAlreadyRegistered,
+        );
+      }
+      services[serviceId] = alias;
+      // Notify other clients that a new service extension is available.
+      dds.streamManager.sendServiceRegisteredEvent(
+        this,
+        serviceId,
+        alias,
+      );
+      return _RPCResponses.success;
+    });
+
+    _clientPeer.registerMethod(
+      'getClientName',
+      (parameters) => {'type': 'ClientName', 'name': name},
+    );
+
+    _clientPeer.registerMethod(
+      'setClientName',
+      (parameters) => dds.clientManager.setClientName(this, parameters),
+    );
+
+    _clientPeer.registerMethod(
+      'requirePermissionToResume',
+      (parameters) =>
+          dds.clientManager.requirePermissionToResume(this, parameters),
+    );
+
+    _clientPeer.registerMethod(
+      'resume',
+      (parameters) => dds.isolateManager.resumeIsolate(this, parameters),
+    );
+
+    // When invoked within a fallback, the next fallback will start executing.
+    // The final fallback forwards the request to the VM service directly.
+    @alwaysThrows
+    nextFallback() => throw json_rpc.RpcException.methodNotFound('');
+
+    // Handle service extension invocations.
+    _clientPeer.registerFallback((parameters) async {
+      hasNamespace(String method) => method.contains('.');
+      getMethod(String method) => method.split('.').last;
+      getNamespace(String method) => method.split('.').first;
+      if (!hasNamespace(parameters.method)) {
+        nextFallback();
+      }
+      // Lookup the client associated with the service extension's namespace.
+      // If the client exists and that client has registered the specified
+      // method, forward the request to that client.
+      final method = getMethod(parameters.method);
+      final namespace = getNamespace(parameters.method);
+      final serviceClient = dds.clientManager.clients[namespace];
+      if (serviceClient != null && serviceClient.services.containsKey(method)) {
+        return await Future.any(
+          [
+            // Forward the request to the service client or...
+            serviceClient.sendRequest(method, parameters.asMap),
+            // if the service client closes, return an error response.
+            serviceClient._clientPeer.done.then(
+              (_) => throw _RpcErrorCodes.buildRpcException(
+                _RpcErrorCodes.kServiceDisappeared,
+              ),
+            ),
+          ],
+        );
+      }
+      throw json_rpc.RpcException(
+        _RpcErrorCodes.kMethodNotFound,
+        'Unknown service: ${parameters.method}',
+      );
+    });
+
+    // Unless otherwise specified, the request is forwarded to the VM service.
+    // NOTE: This must be the last fallback registered.
+    _clientPeer.registerFallback((parameters) async =>
+        await _vmServicePeer.sendRequest(parameters.method, parameters.asMap));
+  }
+
+  static int _idCounter = 0;
+  final int _id = ++_idCounter;
+
+  /// The name given to the client upon its creation.
+  String get defaultClientName => 'client$_id';
+
+  /// The current name associated with this client.
+  String get name => _name;
+
+  // NOTE: this should not be called directly except from:
+  //   - `_ClientManager._clearClientName`
+  //   - `_ClientManager._setClientNameHelper`
+  set name(String n) => _name = n ?? defaultClientName;
+  String _name;
+
+  final _DartDevelopmentService dds;
+  final Map<String, String> services = {};
+  final json_rpc.Peer _vmServicePeer;
+  final WebSocketChannel ws;
+  json_rpc.Peer _clientPeer;
+}
diff --git a/pkg/dds/lib/src/client_manager.dart b/pkg/dds/lib/src/client_manager.dart
new file mode 100644
index 0000000..a7e066e
--- /dev/null
+++ b/pkg/dds/lib/src/client_manager.dart
@@ -0,0 +1,146 @@
+// 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.
+
+part of dds;
+
+/// [_ClientResumePermissions] associates a list of
+/// [_DartDevelopmentServiceClient]s, all of the same client name, with a
+/// permissions mask used to determine which pause event types require approval
+/// from one of the listed clients before resuming an isolate.
+class _ClientResumePermissions {
+  final List<_DartDevelopmentServiceClient> clients = [];
+  int permissionsMask = 0;
+}
+
+/// The [_ClientManager] has the responsibility of managing all state and
+/// requests related to client connections, including:
+///   - A list of all currently connected clients
+///   - Tracking client names and associated permissions for isolate resume
+///     synchronization
+///   - Handling RPC invocations which change client state
+class _ClientManager {
+  _ClientManager(this.dds);
+
+  /// Initialize state for a newly connected client.
+  void addClient(_DartDevelopmentServiceClient client) {
+    _setClientNameHelper(
+      client,
+      client.defaultClientName,
+    );
+    clients.add(client);
+    client.listen().then((_) => removeClient(client));
+  }
+
+  /// Cleanup state for a disconnected client.
+  void removeClient(_DartDevelopmentServiceClient client) {
+    _clearClientName(client);
+    clients.remove(client);
+  }
+
+  /// Cleanup clients on DDS shutdown.
+  Future<void> shutdown() async {
+    // Close all incoming websocket connections.
+    final futures = <Future>[];
+    for (final client in clients) {
+      futures.add(client.close());
+    }
+    await Future.wait(futures);
+  }
+
+  /// Associates a name with a given client.
+  ///
+  /// The provided client name is used to track isolate resume approvals.
+  Map<String, dynamic> setClientName(
+    _DartDevelopmentServiceClient client,
+    json_rpc.Parameters parameters,
+  ) {
+    _setClientNameHelper(client, parameters['name'].asString);
+    return _RPCResponses.success;
+  }
+
+  /// Require permission from this client before resuming an isolate.
+  Map<String, dynamic> requirePermissionToResume(
+    _DartDevelopmentServiceClient client,
+    json_rpc.Parameters parameters,
+  ) {
+    int pauseTypeMask = 0;
+    if (parameters['onPauseStart'].asBoolOr(false)) {
+      pauseTypeMask |= _PauseTypeMasks.pauseOnStartMask;
+    }
+    if (parameters['onPauseReload'].asBoolOr(false)) {
+      pauseTypeMask |= _PauseTypeMasks.pauseOnReloadMask;
+    }
+    if (parameters['onPauseExit'].asBoolOr(false)) {
+      pauseTypeMask |= _PauseTypeMasks.pauseOnExitMask;
+    }
+
+    clientResumePermissions[client.name].permissionsMask = pauseTypeMask;
+    return _RPCResponses.success;
+  }
+
+  /// Changes `client`'s name to `name` while also updating resume permissions
+  /// and approvals.
+  void _setClientNameHelper(
+    _DartDevelopmentServiceClient client,
+    String name,
+  ) {
+    _clearClientName(client);
+    client.name = name.isEmpty ? client.defaultClientName : name;
+    clientResumePermissions.putIfAbsent(
+      client.name,
+      () => _ClientResumePermissions(),
+    );
+    clientResumePermissions[client.name].clients.add(client);
+  }
+
+  /// Resets the client's name while also cleaning up resume permissions and
+  /// approvals.
+  void _clearClientName(
+    _DartDevelopmentServiceClient client,
+  ) {
+    final name = client.name;
+    client.name = null;
+    final clientsForName = clientResumePermissions[name];
+    if (clientsForName != null) {
+      clientsForName.clients.remove(client);
+      // If this was the last client with a given name, cleanup resume
+      // permissions.
+      if (clientsForName.clients.isEmpty) {
+        clientResumePermissions.remove(name);
+
+        // Check to see if we need to resume any isolates now that the last
+        // client of a given name has disconnected or changed names.
+        //
+        // An isolate will be resumed in this situation if:
+        //
+        // 1) This client required resume approvals for the current pause event
+        // associated with the isolate and all other required resume approvals
+        // have been provided by other clients.
+        //
+        // OR
+        //
+        // 2) This client required resume approvals for the current pause event
+        // associated with the isolate, no other clients require resume approvals
+        // for the current pause event, and at least one client has issued a resume
+        // request.
+        dds.isolateManager.isolates.forEach(
+          (_, isolate) async =>
+              await isolate.maybeResumeAfterClientChange(name),
+        );
+      }
+    }
+  }
+
+  // Handles namespace generation for service extensions.
+  static const _kServicePrologue = 's';
+  final NamedLookup<_DartDevelopmentServiceClient> clients = NamedLookup(
+    prologue: _kServicePrologue,
+  );
+
+  /// Mapping of client names to all clients of that name and their resume
+  /// permissions.
+  final Map<String, _ClientResumePermissions> clientResumePermissions = {};
+
+  final _DartDevelopmentService dds;
+}
diff --git a/pkg/dds/lib/src/constants.dart b/pkg/dds/lib/src/constants.dart
new file mode 100644
index 0000000..6a41e0b
--- /dev/null
+++ b/pkg/dds/lib/src/constants.dart
@@ -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 file.
+
+part of dds;
+
+abstract class _RPCResponses {
+  static const success = <String, dynamic>{
+    'type': 'Success',
+  };
+
+  static const collectedSentinel = <String, dynamic>{
+    'type': 'Sentinel',
+    'kind': 'Collected',
+    'valueAsString': '<collected>',
+  };
+}
+
+abstract class _PauseTypeMasks {
+  static const pauseOnStartMask = 1 << 0;
+  static const pauseOnReloadMask = 1 << 1;
+  static const pauseOnExitMask = 1 << 2;
+}
+
+abstract class _ServiceEvents {
+  static const isolateExit = 'IsolateExit';
+  static const isolateSpawn = 'IsolateSpawn';
+  static const isolateStart = 'IsolateStart';
+  static const pauseExit = 'PauseExit';
+  static const pausePostRequest = 'PausePostRequest';
+  static const pauseStart = 'PauseStart';
+  static const resume = 'Resume';
+}
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index 37f019a..f47d909f 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -5,12 +5,26 @@
 part of dds;
 
 class _DartDevelopmentService implements DartDevelopmentService {
-  _DartDevelopmentService(this._remoteVmServiceUri, this._uri);
+  _DartDevelopmentService(this._remoteVmServiceUri, this._uri) {
+    _clientManager = _ClientManager(this);
+    _isolateManager = _IsolateManager(this);
+    _streamManager = _StreamManager(this);
+  }
 
   Future<void> startService() async {
+    // TODO(bkonyi): throw if we've already shutdown.
     // Establish the connection to the VM service.
-    _vmServiceSocket = await WebSocket.connect(remoteVmServiceWsUri.toString());
-    _vmServiceStream = _vmServiceSocket.asBroadcastStream();
+    _vmServiceSocket = WebSocketChannel.connect(remoteVmServiceWsUri);
+    _vmServiceClient = _BinaryCompatiblePeer(_vmServiceSocket, _streamManager);
+    // Setup the JSON RPC client with the VM service.
+    unawaited(_vmServiceClient.listen().then((_) => shutdown()));
+
+    // Setup stream event handling.
+    await streamManager.listen();
+
+    // Populate initial isolate state.
+    await _isolateManager.initialize();
+
     // Once we have a connection to the VM service, we're ready to spawn the intermediary.
     await _startDDSServer();
   }
@@ -23,13 +37,42 @@
 
     // Start the DDS server.
     _server = await io.serve(_handlers().handler, host, port);
-    _uri = Uri(scheme: 'http', host: host, port: _server.port);
+
+    final tmpUri = Uri(scheme: 'http', host: host, port: _server.port);
+
+    // Notify the VM service that this client is DDS and that it should close
+    // and refuse connections from other clients. DDS is now acting in place of
+    // the VM service.
+    try {
+      await _vmServiceClient.sendRequest('_yieldControlToDDS', {
+        'uri': tmpUri.toString(),
+      });
+    } on json_rpc.RpcException catch (e) {
+      await _server.close(force: true);
+      // _yieldControlToDDS fails if DDS is not the only VM service client.
+      throw DartDevelopmentServiceException._(e.data['details']);
+    }
+
+    _uri = tmpUri;
   }
 
   /// Stop accepting requests after gracefully handling existing requests.
   Future<void> shutdown() async {
+    if (_done.isCompleted || _shuttingDown) {
+      // Already shutdown.
+      return;
+    }
+    _shuttingDown = true;
+    // Don't accept anymore HTTP requests.
     await _server.close();
-    await _vmServiceSocket.close();
+
+    // Close connections to clients.
+    await clientManager.shutdown();
+
+    // Close connection to VM service.
+    await _vmServiceSocket.sink.close();
+
+    _done.complete();
   }
 
   // Attempt to upgrade HTTP requests to a websocket before processing them as
@@ -38,16 +81,17 @@
   Cascade _handlers() => Cascade().add(_webSocketHandler()).add(_httpHandler());
 
   Handler _webSocketHandler() => webSocketHandler((WebSocketChannel ws) {
-        // TODO(bkonyi): actually process requests instead of blindly forwarding them.
-        _vmServiceStream.listen(
-          (event) => ws.sink.add(event),
-          onDone: () => ws.sink.close(),
+        final client = _DartDevelopmentServiceClient(
+          this,
+          ws,
+          _vmServiceClient,
         );
-        ws.stream.listen((event) => _vmServiceSocket.add(event));
+        clientManager.addClient(client);
       });
 
   Handler _httpHandler() {
-    // TODO(bkonyi): actually process requests instead of blindly forwarding them.
+    // DDS doesn't support any HTTP requests itself, so we just forward all of
+    // them to the VM service.
     final cascade = Cascade().add(proxyHandler(remoteVmServiceUri));
     return cascade.handler;
   }
@@ -69,6 +113,9 @@
     return uri.replace(scheme: 'ws', pathSegments: pathSegments);
   }
 
+  String _getNamespace(_DartDevelopmentServiceClient client) =>
+      clientManager.clients.keyOf(client);
+
   Uri get remoteVmServiceUri => _remoteVmServiceUri;
   Uri get remoteVmServiceWsUri => _toWebSocket(_remoteVmServiceUri);
   Uri _remoteVmServiceUri;
@@ -79,7 +126,20 @@
 
   bool get isRunning => _uri != null;
 
-  WebSocket _vmServiceSocket;
-  Stream _vmServiceStream;
+  Future<void> get done => _done.future;
+  Completer _done = Completer<void>();
+  bool _shuttingDown = false;
+
+  _ClientManager get clientManager => _clientManager;
+  _ClientManager _clientManager;
+
+  _IsolateManager get isolateManager => _isolateManager;
+  _IsolateManager _isolateManager;
+
+  _StreamManager get streamManager => _streamManager;
+  _StreamManager _streamManager;
+
+  json_rpc.Peer _vmServiceClient;
+  WebSocketChannel _vmServiceSocket;
   HttpServer _server;
 }
diff --git a/pkg/dds/lib/src/isolate_manager.dart b/pkg/dds/lib/src/isolate_manager.dart
new file mode 100644
index 0000000..1ebc9f7
--- /dev/null
+++ b/pkg/dds/lib/src/isolate_manager.dart
@@ -0,0 +1,237 @@
+// 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.
+
+part of dds;
+
+/// This file contains functionality used to track the running state of
+/// all isolates in a given Dart process.
+///
+/// [_RunningIsolate] is a representation of a single live isolate and contains
+/// running state information for that isolate. In addition, approvals from
+/// clients used to synchronize isolate resuming across multiple clients are
+/// tracked in this class.
+///
+/// The [_IsolateManager] keeps track of all the isolates in the
+/// target process and handles isolate lifecycle events including:
+///   - Startup
+///   - Shutdown
+///   - Pauses
+///
+/// The [_IsolateManager] also handles the `resume` RPC, which checks the
+/// resume approvals in the target [_RunningIsolate] to determine if the
+/// isolate should be resumed or wait for additional approvals to be granted.
+
+enum _IsolateState {
+  start,
+  running,
+  pauseStart,
+  pauseExit,
+  pausePostRequest,
+}
+
+class _RunningIsolate {
+  _RunningIsolate(this.isolateManager, this.portId, this.name);
+
+  // State setters.
+  void pausedOnExit() => _state = _IsolateState.pauseExit;
+  void pausedOnStart() => _state = _IsolateState.pauseStart;
+  void pausedPostRequest() => _state = _IsolateState.pausePostRequest;
+  void resumed() => running();
+  void running() => _state = _IsolateState.running;
+  void started() => _state = _IsolateState.start;
+
+  /// Resumes the isolate if all clients which need to approve a resume have
+  /// done so. Called when the last client of a given name disconnects or
+  /// changes name to ensure we don't deadlock waiting for approval to resume
+  /// from a disconnected client.
+  Future<void> maybeResumeAfterClientChange(String clientName) async {
+    // Remove approvals from the disconnected client.
+    _resumeApprovalsByName.remove(clientName);
+
+    if (shouldResume()) {
+      clearResumeApprovals();
+      await isolateManager.dds._vmServiceClient.sendRequest('resume', {
+        'isolateId': 'isolates/$portId',
+      });
+    }
+  }
+
+  /// Returns true if this isolate should resume given its client approvals
+  /// state.
+  ///
+  /// If `resumingClient` is provided, it will be added to the set of clients
+  /// which have provided approval to resume this isolate. If not provided,
+  /// the existing approvals state will be examined to see if the isolate
+  /// should resume due to a client disconnect or name change.
+  bool shouldResume({_DartDevelopmentServiceClient resumingClient}) {
+    if (resumingClient != null) {
+      // Mark approval by the client.
+      _resumeApprovalsByName.add(resumingClient.name);
+    }
+    final requiredClientApprovals = <String>{};
+    final permissions =
+        isolateManager.dds.clientManager.clientResumePermissions;
+
+    // Determine which clients require approval for this pause type.
+    permissions.forEach((name, clientNamePermissions) {
+      if (clientNamePermissions.permissionsMask & _isolateStateMask != 0) {
+        requiredClientApprovals.add(name);
+      }
+    });
+
+    // We require at least a single client to resume, even if that client
+    // doesn't require resume approval.
+    if (_resumeApprovalsByName.isEmpty) {
+      return false;
+    }
+
+    // If all the required approvals are present, we should resume.
+    return _resumeApprovalsByName.containsAll(requiredClientApprovals);
+  }
+
+  /// Resets the internal resume approvals state.
+  ///
+  /// Should always be called after an isolate is resumed.
+  void clearResumeApprovals() => _resumeApprovalsByName.clear();
+
+  int get _isolateStateMask => isolateStateToMaskMapping[_state] ?? 0;
+
+  static const isolateStateToMaskMapping = {
+    _IsolateState.pauseStart: _PauseTypeMasks.pauseOnStartMask,
+    _IsolateState.pausePostRequest: _PauseTypeMasks.pauseOnReloadMask,
+    _IsolateState.pauseExit: _PauseTypeMasks.pauseOnExitMask,
+  };
+
+  final _IsolateManager isolateManager;
+  final String name;
+  final String portId;
+  final Set<String> _resumeApprovalsByName = {};
+  _IsolateState _state;
+}
+
+class _IsolateManager {
+  _IsolateManager(this.dds);
+
+  /// Handles state changes for isolates.
+  void handleIsolateEvent(json_rpc.Parameters parameters) {
+    final event = parameters['event'];
+    final eventKind = event['kind'].asString;
+
+    // There's no interesting information about isolate state associated with
+    // and IsolateSpawn event.
+    if (eventKind == _ServiceEvents.isolateSpawn) {
+      return;
+    }
+
+    final isolateData = event['isolate'];
+    final id = isolateData['number'].asString;
+    final name = isolateData['name'].asString;
+    _updateIsolateState(id, name, eventKind);
+  }
+
+  void _updateIsolateState(String id, String name, String eventKind) {
+    switch (eventKind) {
+      case _ServiceEvents.isolateStart:
+        isolateStarted(id, name);
+        break;
+      case _ServiceEvents.isolateExit:
+        isolateExited(id);
+        break;
+      default:
+        final isolate = isolates[id];
+        switch (eventKind) {
+          case _ServiceEvents.pauseExit:
+            isolate.pausedOnExit();
+            break;
+          case _ServiceEvents.pausePostRequest:
+            isolate.pausedPostRequest();
+            break;
+          case _ServiceEvents.pauseStart:
+            isolate.pausedOnStart();
+            break;
+          case _ServiceEvents.resume:
+            isolate.resumed();
+            break;
+          default:
+            break;
+        }
+    }
+  }
+
+  /// Initializes the set of running isolates.
+  Future<void> initialize() async {
+    final vm = await dds._vmServiceClient.sendRequest('getVM');
+    final List<Map> isolateRefs = vm['isolates'].cast<Map<String, dynamic>>();
+    // Check the pause event for each isolate to determine whether or not the
+    // isolate is already paused.
+    for (final isolateRef in isolateRefs) {
+      final isolate = await dds._vmServiceClient.sendRequest('getIsolate', {
+        'isolateId': isolateRef['id'],
+      });
+      final portId = isolate['number'];
+      final name = isolate['name'];
+      final eventKind = isolate['pauseEvent']['kind'];
+      isolates[portId] = _RunningIsolate(this, portId, name);
+      _updateIsolateState(portId, name, eventKind);
+    }
+  }
+
+  /// Initializes state for a newly started isolate.
+  void isolateStarted(String portId, String name) {
+    final isolate = _RunningIsolate(this, portId, name);
+    isolate.running();
+    isolates[portId] = isolate;
+  }
+
+  /// Cleans up state for an isolate that has exited.
+  void isolateExited(String portId) {
+    isolates.remove(portId);
+  }
+
+  /// Handles `resume` RPC requests. If the client requires that approval be
+  /// given before resuming an isolate, this method will:
+  ///
+  ///   - Update the approval state for the isolate.
+  ///   - Resume the isolate if approval has been given by all clients which
+  ///     require approval.
+  ///
+  /// Returns a collected sentinel if the isolate no longer exists.
+  Future<Map<String, dynamic>> resumeIsolate(
+    _DartDevelopmentServiceClient client,
+    json_rpc.Parameters parameters,
+  ) async {
+    final isolateId = parameters['isolateId'].asString;
+    final portId = _isolateIdToPortId(isolateId);
+    final isolate = isolates[portId];
+    if (isolate == null) {
+      return _RPCResponses.collectedSentinel;
+    }
+    if (isolate.shouldResume(resumingClient: client)) {
+      isolate.clearResumeApprovals();
+      return await _sendResumeRequest(isolateId, parameters);
+    }
+    return _RPCResponses.success;
+  }
+
+  /// Forwards a `resume` request to the VM service.
+  Future<Map<String, dynamic>> _sendResumeRequest(
+    String isolateId,
+    json_rpc.Parameters parameters,
+  ) async {
+    final step = parameters['step'].asStringOr(null);
+    final frameIndex = parameters['frameIndex'].asIntOr(null);
+    final resumeResult = await dds._vmServiceClient.sendRequest('resume', {
+      'isolateId': isolateId,
+      if (step != null) 'step': step,
+      if (frameIndex != null) 'frameIndex': frameIndex,
+    });
+    return resumeResult;
+  }
+
+  static String _isolateIdToPortId(String isolateId) =>
+      isolateId.substring('isolates/'.length);
+
+  final _DartDevelopmentService dds;
+  final Map<String, _RunningIsolate> isolates = {};
+}
diff --git a/pkg/dds/lib/src/named_lookup.dart b/pkg/dds/lib/src/named_lookup.dart
new file mode 100644
index 0000000..4b89633
--- /dev/null
+++ b/pkg/dds/lib/src/named_lookup.dart
@@ -0,0 +1,72 @@
+// 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.
+
+// Originally pulled from dart:_vmservice.
+
+part of dds;
+
+/// [Set]-like containers which automatically generate [String] IDs for its
+/// items.
+class NamedLookup<E> with IterableMixin<E> {
+  final IdGenerator _generator;
+  final Map<String, E> _elements = {};
+  final Map<E, String> _ids = {};
+
+  NamedLookup({String prologue = ''})
+      : _generator = IdGenerator(prologue: prologue);
+
+  void add(E e) {
+    final id = _generator.newId();
+    _elements[id] = e;
+    _ids[e] = id;
+  }
+
+  void remove(E e) {
+    final id = _ids.remove(e);
+    _elements.remove(id);
+    _generator.release(id);
+  }
+
+  E operator [](String id) => _elements[id];
+  String keyOf(E e) => _ids[e];
+
+  Iterator<E> get iterator => _ids.keys.iterator;
+}
+
+/// Generator for unique IDs which recycles expired ones.
+class IdGenerator {
+  /// Fixed initial part of the ID
+  final String prologue;
+
+  // IDs in use.
+  final Set<String> _used = {};
+
+  /// IDs to be recycled (use these before generate new ones).
+  final Set<String> _free = {};
+
+  /// Next ID to generate when no recycled IDs are available.
+  int _next = 0;
+
+  IdGenerator({this.prologue = ''});
+
+  /// Returns a new ID (possibly recycled).
+  String newId() {
+    String id;
+    if (_free.isEmpty) {
+      id = prologue + (_next++).toString();
+    } else {
+      id = _free.first;
+    }
+    _free.remove(id);
+    _used.add(id);
+    return id;
+  }
+
+  /// Releases the ID and mark it for recycling.
+  void release(String id) {
+    if (_used.remove(id)) {
+      _free.add(id);
+    }
+  }
+}
diff --git a/pkg/dds/lib/src/rpc_error_codes.dart b/pkg/dds/lib/src/rpc_error_codes.dart
new file mode 100644
index 0000000..84b1f62
--- /dev/null
+++ b/pkg/dds/lib/src/rpc_error_codes.dart
@@ -0,0 +1,52 @@
+// 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.
+
+part of dds;
+
+abstract class _RpcErrorCodes {
+  static json_rpc.RpcException buildRpcException(int code) {
+    return json_rpc.RpcException(
+      code,
+      errorMessages[code],
+    );
+  }
+
+  // These error codes must be kept in sync with those in vm/json_stream.h and
+  // vmservice.dart.
+  // static const kParseError = -32700;
+  // static const kInvalidRequest = -32600;
+  static const kMethodNotFound = -32601;
+  // static const kInvalidParams = -32602;
+  // static const kInternalError = -32603;
+
+  // static const kExtensionError = -32000;
+
+  static const kFeatureDisabled = 100;
+  // static const kCannotAddBreakpoint = 102;
+  static const kStreamAlreadySubscribed = 103;
+  static const kStreamNotSubscribed = 104;
+  // static const kIsolateMustBeRunnable = 105;
+  // static const kIsolateMustBePaused = 106;
+  // static const kCannotResume = 107;
+  // static const kIsolateIsReloading = 108;
+  // static const kIsolateReloadBarred = 109;
+  // static const kIsolateMustHaveReloaded = 110;
+  static const kServiceAlreadyRegistered = 111;
+  static const kServiceDisappeared = 112;
+  // static const kExpressionCompilationError = 113;
+  // static const kInvalidTimelineRequest = 114;
+
+  // Experimental (used in private rpcs).
+  // static const kFileSystemAlreadyExists = 1001;
+  // static const kFileSystemDoesNotExist = 1002;
+  // static const kFileDoesNotExist = 1003;
+
+  static const errorMessages = {
+    kFeatureDisabled: 'Feature is disabled',
+    kStreamAlreadySubscribed: 'Stream already subscribed',
+    kStreamNotSubscribed: 'Stream not subscribed',
+    kServiceAlreadyRegistered: 'Service already registered',
+    kServiceDisappeared: 'Service has disappeared',
+  };
+}
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
new file mode 100644
index 0000000..217471f
--- /dev/null
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -0,0 +1,199 @@
+// 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.
+
+part of dds;
+
+class _StreamManager {
+  _StreamManager(this.dds);
+
+  /// Send `streamNotify` notifications to clients subscribed to `streamId`.
+  ///
+  /// If `data` is of type `Uint8List`, the notification is assumed to be a
+  /// binary event and is forwarded directly over the subscriber's websocket.
+  /// Otherwise, the event is sent via the JSON RPC client.
+  ///
+  /// If `excludedClient` is provided, the notification will be sent to all
+  /// clients subscribed to `streamId` except for `excludedClient`.
+  void streamNotify(
+    String streamId,
+    data, {
+    _DartDevelopmentServiceClient excludedClient,
+  }) {
+    if (streamListeners.containsKey(streamId)) {
+      final listeners = streamListeners[streamId];
+      final isBinaryData = data is Uint8List;
+      for (final listener in listeners) {
+        if (listener == excludedClient) {
+          continue;
+        }
+        if (isBinaryData) {
+          listener.ws.sink.add(data);
+        } else {
+          listener.sendNotification('streamNotify', data);
+        }
+      }
+    }
+  }
+
+  void sendServiceRegisteredEvent(
+    _DartDevelopmentServiceClient client,
+    String service,
+    String alias,
+  ) {
+    final namespace = dds._getNamespace(client);
+    streamNotify(
+      kServiceStream,
+      {
+        'streamId': kServiceStream,
+        'event': {
+          'type': 'Event',
+          'kind': 'ServiceRegistered',
+          'timestamp': DateTime.now().millisecondsSinceEpoch,
+          'service': service,
+          'method': namespace + '.' + service,
+          'alias': alias,
+        },
+      },
+      excludedClient: client,
+    );
+  }
+
+  void _sendServiceUnregisteredEvents(
+    _DartDevelopmentServiceClient client,
+  ) {
+    final namespace = dds._getNamespace(client);
+    for (final service in client.services.keys) {
+      streamNotify(
+        kServiceStream,
+        {
+          'streamId': kServiceStream,
+          'event': {
+            'type': 'Event',
+            'kind': 'ServiceUnregistered',
+            'timestamp': DateTime.now().millisecondsSinceEpoch,
+            'service': service,
+            'method': namespace + '.' + service,
+          },
+        },
+        excludedClient: client,
+      );
+    }
+  }
+
+  /// Start listening for `streamNotify` events from the VM service and forward
+  /// them to the clients which have subscribed to the stream.
+  Future<void> listen() async {
+    // The _IsolateManager requires information from both the Debug and
+    // Isolate streams, so they must always be subscribed to by DDS.
+    for (final stream in ddsCoreStreams) {
+      await streamListen(null, stream);
+    }
+    dds._vmServiceClient.registerMethod(
+      'streamNotify',
+      (parameters) {
+        final streamId = parameters['streamId'].asString;
+        // Forward events from the streams _IsolateManager subscribes to.
+        if (isolateManagerStreams.contains(streamId)) {
+          dds.isolateManager.handleIsolateEvent(parameters);
+        }
+        streamNotify(streamId, parameters.value);
+      },
+    );
+  }
+
+  /// Subscribes `client` to a stream.
+  ///
+  /// If `client` is the first client to listen to `stream`, DDS will send a
+  /// `streamListen` request for `stream` to the VM service.
+  Future<void> streamListen(
+    _DartDevelopmentServiceClient client,
+    String stream,
+  ) async {
+    assert(stream != null && stream.isNotEmpty);
+    if (!streamListeners.containsKey(stream)) {
+      // This will return an RPC exception if the stream doesn't exist. This
+      // will throw and the exception will be forwarded to the client.
+      final result = await dds._vmServiceClient.sendRequest('streamListen', {
+        'streamId': stream,
+      });
+      assert(result['type'] == 'Success');
+      streamListeners[stream] = <_DartDevelopmentServiceClient>[];
+    }
+    if (streamListeners[stream].contains(client)) {
+      throw kStreamAlreadySubscribedException;
+    }
+    if (client != null) {
+      streamListeners[stream].add(client);
+    }
+  }
+
+  /// Unsubscribes `client` from a stream.
+  ///
+  /// If `client` is the last client to unsubscribe from `stream`, DDS will
+  /// send a `streamCancel` request for `stream` to the VM service.
+  Future<void> streamCancel(
+    _DartDevelopmentServiceClient client,
+    String stream,
+  ) async {
+    assert(stream != null && stream.isNotEmpty);
+    final listeners = streamListeners[stream];
+    if (listeners == null || !listeners.contains(client)) {
+      throw kStreamNotSubscribedException;
+    }
+    listeners.remove(client);
+    // Don't cancel streams DDS needs to function.
+    if (listeners.isEmpty && !ddsCoreStreams.contains(stream)) {
+      streamListeners.remove(stream);
+      final result = await dds._vmServiceClient.sendRequest('streamCancel', {
+        'streamId': stream,
+      });
+      assert(result['type'] == 'Success');
+    } else {
+      streamListeners[stream] = listeners;
+    }
+  }
+
+  /// Cleanup stream subscriptions for `client` when it has disconnected.
+  void clientDisconnect(_DartDevelopmentServiceClient client) {
+    for (final streamId in streamListeners.keys.toList()) {
+      streamCancel(client, streamId).catchError(
+        (_) => null,
+        // Ignore 'stream not subscribed' errors.
+        test: (e) => e is json_rpc.RpcException,
+      );
+    }
+    // Notify other service clients of service extensions that are being
+    // unregistered.
+    _sendServiceUnregisteredEvents(client);
+  }
+
+  static const kServiceStream = 'Service';
+
+  static final kStreamAlreadySubscribedException =
+      _RpcErrorCodes.buildRpcException(
+    _RpcErrorCodes.kStreamAlreadySubscribed,
+  );
+
+  static final kStreamNotSubscribedException = _RpcErrorCodes.buildRpcException(
+    _RpcErrorCodes.kStreamNotSubscribed,
+  );
+
+  static const kDebugStream = 'Debug';
+  static const kIsolateStream = 'Isolate';
+
+  // Never cancel the Debug or Isolate stream as `_IsolateManager` requires
+  // them for isolate state notifications.
+  static const isolateManagerStreams = <String>{
+    kDebugStream,
+    kIsolateStream,
+  };
+
+  // The set of streams that DDS requires to function.
+  static final ddsCoreStreams = <String>{
+    ...isolateManagerStreams,
+  };
+
+  final _DartDevelopmentService dds;
+  final streamListeners = <String, List<_DartDevelopmentServiceClient>>{};
+}
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 8734df5..9dbb70e 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -11,13 +11,15 @@
   sdk: '>=2.6.0 <3.0.0'
 
 dependencies:
+  async: ^2.4.1
   json_rpc_2: ^2.1.0
+  pedantic: ^1.7.0
   shelf: ^0.7.5
   shelf_proxy: ^0.1.0+7
   shelf_web_socket: ^0.2.3
+  stream_channel: ^2.0.0
   web_socket_channel: ^1.1.0
 
 dev_dependencies:
-  pedantic: ^1.7.0
   test: ^1.0.0
   vm_service: ^4.0.0
diff --git a/pkg/dds/test/smoke_test.dart b/pkg/dds/test/smoke_test.dart
index 6e6c1ed..39468b0 100644
--- a/pkg/dds/test/smoke_test.dart
+++ b/pkg/dds/test/smoke_test.dart
@@ -41,35 +41,78 @@
 }
 
 void main() {
-  test('DDS Smoke Test', () async {
-    final process = await spawnDartProcess('smoke.dart');
-    final dds = await DartDevelopmentService.startDartDevelopmentService(
-      remoteVmServiceUri,
-    );
-    expect(dds.isRunning, true);
+  group('DDS', () {
+    Process process;
+    DartDevelopmentService dds;
 
-    // Ensure basic websocket requests are forwarded correctly to the VM service.
-    final service = await vmServiceConnectUri(dds.wsUri.toString());
-    final version = await service.getVersion();
-    expect(version.major > 0, true);
-    expect(version.minor > 0, true);
+    setUp(() async {
+      process = await spawnDartProcess('smoke.dart');
+    });
 
-    // Ensure we can still make requests of the VM service via HTTP.
-    HttpClient client = HttpClient();
-    final request = await client.getUrl(remoteVmServiceUri.replace(
-      pathSegments: [
-        remoteVmServiceUri.pathSegments.first,
-        'getVersion',
-      ],
-    ));
-    final response = await request.close();
-    final Map<String, dynamic> jsonResponse =
-        (await response.transform(utf8.decoder).transform(json.decoder).single);
-    expect(jsonResponse['result']['type'], 'Version');
-    expect(jsonResponse['result']['major'] > 0, true);
-    expect(jsonResponse['result']['minor'] > 0, true);
-    await dds.shutdown();
-    process.kill();
+    tearDown(() async {
+      await dds?.shutdown();
+      process?.kill();
+      dds = null;
+      process = null;
+    });
+
+    test('Smoke Test', () async {
+      dds = await DartDevelopmentService.startDartDevelopmentService(
+        remoteVmServiceUri,
+      );
+      expect(dds.isRunning, true);
+
+      // Ensure basic websocket requests are forwarded correctly to the VM service.
+      final service = await vmServiceConnectUri(dds.wsUri.toString());
+      final version = await service.getVersion();
+      expect(version.major > 0, true);
+      expect(version.minor > 0, true);
+
+      // Ensure we can still make requests of the VM service via HTTP.
+      HttpClient client = HttpClient();
+      final request = await client.getUrl(remoteVmServiceUri.replace(
+        pathSegments: [
+          if (remoteVmServiceUri.pathSegments.isNotEmpty)
+            remoteVmServiceUri.pathSegments.first,
+          'getVersion',
+        ],
+      ));
+      final response = await request.close();
+      final Map<String, dynamic> jsonResponse = (await response
+          .transform(utf8.decoder)
+          .transform(json.decoder)
+          .single);
+      expect(jsonResponse['result']['type'], 'Version');
+      expect(jsonResponse['result']['major'] > 0, true);
+      expect(jsonResponse['result']['minor'] > 0, true);
+    });
+
+    test('startup fails when VM service has existing clients', () async {
+      Uri httpToWebSocketUri(Uri httpUri) {
+        final segments = (httpUri.pathSegments.isNotEmpty)
+            ? (httpUri.pathSegments.toList()..removeLast())
+            : <String>[];
+        segments.add('ws');
+        return httpUri.replace(
+          scheme: 'ws',
+          pathSegments: segments,
+        );
+      }
+
+      final _ = await vmServiceConnectUri(
+        httpToWebSocketUri(remoteVmServiceUri).toString(),
+      );
+      try {
+        dds = await DartDevelopmentService.startDartDevelopmentService(
+          remoteVmServiceUri,
+        );
+        fail(
+            'DDS startup should fail if there are existing VM service clients.');
+      } on DartDevelopmentServiceException catch (e) {
+        expect(e.message,
+            'Existing VM service clients prevent DDS from taking control.');
+      }
+    });
   });
 
   test('Invalid args test', () async {
diff --git a/pkg/dev_compiler/lib/dev_compiler.dart b/pkg/dev_compiler/lib/dev_compiler.dart
index ff98a4d..dedfc72 100644
--- a/pkg/dev_compiler/lib/dev_compiler.dart
+++ b/pkg/dev_compiler/lib/dev_compiler.dart
@@ -4,7 +4,7 @@
 
 // The dev_compiler does not have a publishable public API, instead this is
 // intended for other consumers within the Dart SDK.
-export 'src/compiler/module_builder.dart' show ModuleFormat;
+export 'src/compiler/module_builder.dart' show ModuleFormat, parseModuleFormat;
 export 'src/compiler/shared_command.dart' show SharedCompilerOptions;
 export 'src/kernel/command.dart' show jsProgramToCode;
 export 'src/kernel/compiler.dart' show ProgramCompiler;
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 842287d..da8765a 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -25,15 +25,25 @@
 }
 
 /// Parses a string into a [ModuleFormat].
-ModuleFormat parseModuleFormat(String s) => {
-      'es6': ModuleFormat.es6,
-      'common': ModuleFormat.common,
-      'amd': ModuleFormat.amd,
-      'ddc': ModuleFormat.ddc,
-      // Deprecated:
-      'node': ModuleFormat.common,
-      'legacy': ModuleFormat.ddc
-    }[s];
+///
+/// Throws an [ArgumentError] if the module format is not recognized.
+ModuleFormat parseModuleFormat(String s) {
+  var formats = const {
+    'es6': ModuleFormat.es6,
+    'common': ModuleFormat.common,
+    'amd': ModuleFormat.amd,
+    'ddc': ModuleFormat.ddc,
+    // Deprecated:
+    'node': ModuleFormat.common,
+    'legacy': ModuleFormat.ddc
+  };
+  var selected = formats[s];
+  if (selected == null) {
+    throw ArgumentError('Invalid module format `$s`, allowed formats are: '
+        '`${formats.keys.join(', ')}`');
+  }
+  return selected;
+}
 
 /// Parse the module format option added by [addModuleFormatOptions].
 List<ModuleFormat> parseModuleFormatOption(ArgResults args) {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index b297574..39e6830 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1038,43 +1038,23 @@
       // * There isn't an obvious place in dart:_runtime were we could place a
       //   method that adds these type tests (similar to addTypeTests()) because
       //   in the bootstrap ordering the Future class hasn't been defined yet.
-      if (_options.enableNullSafety) {
-        var typeParam =
-            TypeParameterType(c.typeParameters[0], Nullability.undetermined);
-        var typeT = visitTypeParameterType(typeParam);
-        var futureOfT = visitInterfaceType(InterfaceType(
-            _coreTypes.futureClass, currentLibrary.nonNullable, [typeParam]));
-        body.add(js.statement('''
-            #.is = function is_FutureOr(o) {
-              return #.is(o) || #.is(o);
-            }
-            ''', [className, typeT, futureOfT]));
-        body.add(js.statement('''
-            #.as = function as_FutureOr(o) {
-              if (#.is(o) || #.is(o)) return o;
-              return #.as(o, this);
-            }
-            ''', [className, typeT, futureOfT, runtimeModule]));
-        return null;
-      } else {
-        var typeParam =
-            TypeParameterType(c.typeParameters[0], Nullability.legacy);
-        var typeT = visitTypeParameterType(typeParam);
-        var futureOfT = visitInterfaceType(InterfaceType(
-            _coreTypes.futureClass, Nullability.legacy, [typeParam]));
-        body.add(js.statement('''
-            #.is = function is_FutureOr(o) {
-              return #.is(o) || #.is(o);
-            }
-            ''', [className, typeT, futureOfT]));
-        body.add(js.statement('''
-            #.as = function as_FutureOr(o) {
-              if (o == null || #.is(o) || #.is(o)) return o;
-              #.castError(o, this);
-            }
-            ''', [className, typeT, futureOfT, runtimeModule]));
-        return null;
-      }
+      var typeParam =
+          TypeParameterType(c.typeParameters[0], Nullability.undetermined);
+      var typeT = visitTypeParameterType(typeParam);
+      var futureOfT = visitInterfaceType(InterfaceType(
+          _coreTypes.futureClass, currentLibrary.nonNullable, [typeParam]));
+      body.add(js.statement('''
+          #.is = function is_FutureOr(o) {
+            return #.is(o) || #.is(o);
+          }
+          ''', [className, typeT, futureOfT]));
+      body.add(js.statement('''
+          #.as = function as_FutureOr(o) {
+            if (#.is(o) || #.is(o)) return o;
+            return #.as(o, this);
+          }
+          ''', [className, typeT, futureOfT, runtimeModule]));
+      return null;
     }
 
     body.add(runtimeStatement('addTypeTests(#)', [className]));
@@ -2574,13 +2554,9 @@
           _coreTypes.futureClass, futureOr.nullability, [typeArgument]);
     } else if (typeArgument is InterfaceType &&
         typeArgument.classNode == _coreTypes.nullClass) {
-      // TODO(40266) Remove this workaround when we unfork dart:_runtime
-      var nullability = _options.enableNullSafety
-          ? Nullability.nullable
-          : currentLibrary.nullable;
       // FutureOr<Null> --> Future<Null>?
-      normalizedType =
-          InterfaceType(_coreTypes.futureClass, nullability, [typeArgument]);
+      normalizedType = InterfaceType(
+          _coreTypes.futureClass, Nullability.nullable, [typeArgument]);
     } else if (futureOr.nullability == Nullability.nullable &&
         typeArgument.nullability == Nullability.nullable) {
       // FutureOr<T?>? --> FutureOr<T?>
@@ -2655,27 +2631,38 @@
     //   * `class A extends B {...}` where B is the InterfaceType.
     //   * Emitting non-null constructor calls.
     // * The InterfaceType is the Null type.
-    if (!emitNullability || type == _coreTypes.nullType) return typeRep;
+    // * The types were written in JS context or as part of the dart:_runtime
+    //   library.
+    if (!emitNullability ||
+        type == _coreTypes.nullType ||
+        // TODO(38701) Remove these once the SDK has unforked and is running
+        // "opted-in"
+        !coreLibrary.isNonNullableByDefault &&
+            (_isInForeignJS || isSdkInternalRuntime(currentLibrary))) {
+      return typeRep;
+    }
 
     if (type.nullability == Nullability.undetermined) {
       throw UnsupportedError('Undetermined Nullability');
     }
-    return _emitNullabilityWrapper(typeRep, type.nullability);
+
+    // Emit non-nullable version directly.
+    typeRep = _emitNullabilityWrapper(typeRep, type.nullability);
+    if (!_cacheTypes || type.nullability == Nullability.nonNullable) {
+      return typeRep;
+    }
+
+    // Hoist the nullable or legacy versions of the type to the top level and
+    // use it everywhere it appears.
+    return _typeTable.nameType(type, typeRep);
   }
 
   /// Wraps [typeRep] in the appropriate wrapper for the given [nullability].
   ///
-  /// NOTE: This is currently a no-op if the null safety experiment is not
-  /// enabled.
-  ///
   /// Non-nullable and undetermined nullability will not cause any wrappers to
   /// be emitted.
   js_ast.Expression _emitNullabilityWrapper(
       js_ast.Expression typeRep, Nullability nullability) {
-    // TODO(nshahan) Cleanup this check once it is safe to always emit the
-    // legacy wrapper.
-    if (!_options.enableNullSafety) return typeRep;
-
     switch (nullability) {
       case Nullability.legacy:
         return runtimeCall('legacy(#)', [typeRep]);
@@ -2761,35 +2748,28 @@
 
       helperCall = 'gFnType(#)';
 
-      /// Whether the type parameter [t] has an explicit bound, like
-      /// `<T extends C>`, `<T extends Object>` or `<T extends dynamic>`.
+      /// Returns `true` when the type parameter [t] has a `Object*` bound
+      /// either implicit `<T>` or explicit `<T extends Object>` written in a
+      /// legacy library.
       ///
-      /// In contrast, a type parameter like `<T>` has an implicit bound.
-      /// Implicit bounds are a bit unusual, in that `Object` is used as the
-      /// bound for checking, but `dynamic` is filled in as the default value.
-      ///
-      /// Kernel represents `<T>` as `<T extends Object = dynamic>`. We can find
-      /// explicit bounds by looking for anything *except* that.
-      bool typeParameterHasExplicitBound(TypeParameter t) =>
-          t.bound != _types.coreTypes.objectLegacyRawType ||
-          t.defaultType != const DynamicType();
+      /// Note: Kernel represents these differently in the default values.
+      /// `<T extends Object* = dynamic>` vs `<T extends Object* = Object*>` but
+      /// at runtime we treat both as having a default value of dynamic as it is
+      /// correct for the cases that appear more frequently.
+      bool typeParameterHasLegacyTopBound(TypeParameter t) =>
+          t.bound == _types.coreTypes.objectLegacyRawType;
 
-      // If any explicit bounds were passed, emit them.
-      if (typeFormals.any(typeParameterHasExplicitBound)) {
+      // Avoid emitting these bounds when possible and interpret the empty
+      // bounds at runtime to mean all bounds are `Object*`.
+      // TODO(nshahan) Revisit this representation when more libraries have
+      // migrated to null safety.
+      if (!typeFormals.every(typeParameterHasLegacyTopBound)) {
         /// Emits the bound of the type parameter [t] for use in runtime
-        /// checking and the default value (e.g. for dynamic class).
+        /// checking.
         ///
-        /// For most type parameters we can use [TypeParameter.bound]. However,
-        /// for *implicit* bounds such as `<T>` (represented in Kernel as
-        /// `<T extends Object = dynamic>`) we need to emit `dynamic` so we use
-        /// the correct default value at runtime.
-        ///
-        /// Because `dynamic` and `Object` are both top types, they'll behave
-        /// identically for the purposes of type checks.
+        /// Default values e.g. dynamic get replaced at runtime.
         js_ast.Expression emitTypeParameterBound(TypeParameter t) =>
-            typeParameterHasExplicitBound(t)
-                ? _emitType(t.bound)
-                : visitDynamicType(const DynamicType());
+            _emitType(t.bound);
 
         var bounds = typeFormals.map(emitTypeParameterBound).toList();
         typeParts.add(addTypeFormalsAsParameters(bounds));
@@ -2798,13 +2778,22 @@
       helperCall = 'fnType(#)';
     }
     var typeRep = runtimeCall(helperCall, [typeParts]);
-    // Avoid caching the nullability of the function type itself so it can be
-    // shared by nullable, non-nullable, and legacy versions at the use site.
+    // First add the type to the type table in its non-nullable form. It can be
+    // reused by the nullable and legacy versions.
     typeRep = _cacheTypes
-        ? _typeTable.nameFunctionType(type, typeRep, lazy: lazy)
+        ? _typeTable.nameFunctionType(
+            type.withNullability(Nullability.nonNullable), typeRep,
+            lazy: lazy)
         : typeRep;
 
-    return _emitNullabilityWrapper(typeRep, type.nullability);
+    if (type.nullability == Nullability.nonNullable) return typeRep;
+
+    // Hoist the nullable or legacy versions of the type to the top level and
+    // use it everywhere it appears.
+    typeRep = _emitNullabilityWrapper(typeRep, type.nullability);
+    return _cacheTypes
+        ? _typeTable.nameFunctionType(type, typeRep, lazy: lazy)
+        : typeRep;
   }
 
   /// Emits an expression that lets you access statics on a [type] from code.
@@ -2846,9 +2835,17 @@
   js_ast.Expression _emitTypeParameterType(TypeParameterType type,
       {bool emitNullability = true}) {
     var typeParam = _emitTypeParameter(type.parameter);
-    if (!emitNullability) return typeParam;
+    if (!emitNullability ||
+        !_cacheTypes ||
+        // Emit non-nullable version directly.
+        type.isPotentiallyNonNullable) {
+      return typeParam;
+    }
 
-    return _emitNullabilityWrapper(typeParam, type.nullability);
+    // Hoist the wrapped version to the top level and use it everywhere this
+    // type appears.
+    return _typeTable.nameType(
+        type, _emitNullabilityWrapper(typeParam, type.nullability));
   }
 
   js_ast.Identifier _emitTypeParameter(TypeParameter t) =>
@@ -4746,8 +4743,16 @@
 
     // Optimize some internal SDK calls.
     if (isSdkInternalRuntime(target.enclosingLibrary)) {
-      if (node.arguments.positional.length == 1) {
-        var name = target.name.name;
+      var name = target.name.name;
+      if (node.arguments.positional.isEmpty) {
+        if (name == 'typeRep') {
+          return _emitType(node.arguments.types.single);
+        }
+        if (name == 'legacyTypeRep') {
+          return _emitType(
+              node.arguments.types.single.withNullability(Nullability.legacy));
+        }
+      } else if (node.arguments.positional.length == 1) {
         var firstArg = node.arguments.positional[0];
         if (name == 'getGenericClass' && firstArg is TypeLiteral) {
           var type = firstArg.type;
@@ -4762,17 +4767,20 @@
           return getExtensionSymbolInternal(firstArg.value);
         }
       } else if (node.arguments.positional.length == 2) {
-        var name = target.name.name;
         var firstArg = node.arguments.positional[0];
         var secondArg = node.arguments.positional[1];
         if (name == '_jsInstanceOf' && secondArg is TypeLiteral) {
-          return js.call('# instanceof #',
-              [_visitExpression(firstArg), _emitType(secondArg.type)]);
+          return js.call('# instanceof #', [
+            _visitExpression(firstArg),
+            _emitType(secondArg.type.withNullability(Nullability.nonNullable))
+          ]);
         }
 
         if (name == '_equalType' && secondArg is TypeLiteral) {
-          return js.call('# === #',
-              [_visitExpression(firstArg), _emitType(secondArg.type)]);
+          return js.call('# === #', [
+            _visitExpression(firstArg),
+            _emitType(secondArg.type.withNullability(Nullability.nonNullable))
+          ]);
         }
       }
     }
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index acf7573..cea0477 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -158,7 +158,7 @@
       {void Function(String msg) logger,
       ChangedStructureNotifier changedStructureNotifier}) {
     if (flags.trackWidgetCreation) {
-      _widgetTracker ??= WidgetCreatorTracker();
+      _widgetTracker ??= WidgetCreatorTracker(changedStructureNotifier);
       _widgetTracker.transform(component, libraries);
     }
   }
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 865cc53..573238d 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -26,7 +26,7 @@
       _options,
       IOPipeline([
         SourceToSummaryDillStep(),
-        DDKStep(),
+        DDCStep(),
         RunD8(),
       ], cacheSharedModules: true));
 }
@@ -120,7 +120,7 @@
   }
 }
 
-class DDKStep implements IOModularStep {
+class DDCStep implements IOModularStep {
   @override
   List<DataId> get resultData => const [jsId];
 
@@ -139,7 +139,7 @@
   @override
   Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
       List<String> flags) async {
-    if (_options.verbose) print('\nstep: ddk on $module');
+    if (_options.verbose) print('\nstep: ddc on $module');
 
     var transitiveDependencies = computeTransitiveDependencies(module);
     await _createPackagesFile(module, root, transitiveDependencies);
@@ -192,7 +192,7 @@
 
   @override
   void notifyCached(Module module) {
-    if (_options.verbose) print('\ncached step: ddk on $module');
+    if (_options.verbose) print('\ncached step: ddc on $module');
   }
 }
 
diff --git a/pkg/dev_compiler/test/modular_suite_nnbd.dart b/pkg/dev_compiler/test/modular_suite_nnbd.dart
index 4f1b317..9c52552 100644
--- a/pkg/dev_compiler/test/modular_suite_nnbd.dart
+++ b/pkg/dev_compiler/test/modular_suite_nnbd.dart
@@ -21,12 +21,12 @@
   _options = Options.parse(args);
   await _resolveScripts();
   await runSuite(
-      sdkRoot.resolve('tests/compiler/dartdevc/modular/'),
-      'tests/compiler/dartdevc/modular',
+      sdkRoot.resolve('tests/modular/'),
+      'tests/modular',
       _options,
       IOPipeline([
         SourceToSummaryDillStep(),
-        DDKStep(),
+        DDCStep(),
         RunD8(),
       ], cacheSharedModules: true));
 }
@@ -77,7 +77,7 @@
       sources = ['dart:core'];
       extraArgs = [
         '--libraries-file',
-        '$rootScheme:///sdk_nnbd/lib/libraries_nnbd_mix_hack.json'
+        '$rootScheme:///sdk_nnbd/lib/libraries.json',
       ];
       assert(transitiveDependencies.isEmpty);
     } else {
@@ -109,6 +109,10 @@
           .where((m) => !m.isSdk)
           .expand((m) => ['--input-summary', '${toUri(m, dillId)}'])),
       ...(sources.expand((String uri) => ['--source', uri])),
+      // TODO(40266) After unfork of dart:_runtime only need experiment when
+      // compiling SDK. For now always use the Null Safety experiment.
+      '--enable-experiment',
+      'non-nullable',
       ...(flags.expand((String flag) => ['--enable-experiment', flag])),
     ];
 
@@ -123,7 +127,7 @@
   }
 }
 
-class DDKStep implements IOModularStep {
+class DDCStep implements IOModularStep {
   @override
   List<DataId> get resultData => const [jsId];
 
@@ -142,7 +146,7 @@
   @override
   Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
       List<String> flags) async {
-    if (_options.verbose) print('\nstep: ddk on $module');
+    if (_options.verbose) print('\nstep: ddc on $module');
 
     var transitiveDependencies = computeTransitiveDependencies(module);
     await _createPackagesFile(module, root, transitiveDependencies);
@@ -152,11 +156,10 @@
     List<String> extraArgs;
     if (module.isSdk) {
       sources = ['dart:core'];
-      // extraArgs = [];
       extraArgs = [
         '--compile-sdk',
         '--libraries-file',
-        '$rootScheme:///sdk_nnbd/lib/libraries_nnbd_mix_hack.json'
+        '$rootScheme:///sdk_nnbd/lib/libraries.json',
       ];
       assert(transitiveDependencies.isEmpty);
     } else {
@@ -179,7 +182,6 @@
       '--packages=${sdkRoot.toFilePath()}/.packages',
       _dartdevcScript,
       '--kernel',
-      '--summarize-text',
       '--modules=es6',
       '--no-summarize',
       '--no-source-map',
@@ -187,6 +189,10 @@
       rootScheme,
       ...sources,
       ...extraArgs,
+      // TODO(40266) After unfork of dart:_runtime only need experiment when
+      // compiling SDK. For now always use the Null Safety experiment.
+      '--enable-experiment',
+      'non-nullable',
       for (String flag in flags) '--enable-experiment=$flag',
       ...(transitiveDependencies
           .where((m) => !m.isSdk)
@@ -201,7 +207,7 @@
 
   @override
   void notifyCached(Module module) {
-    if (_options.verbose) print('\ncached step: ddk on $module');
+    if (_options.verbose) print('\ncached step: ddc on $module');
   }
 }
 
@@ -238,6 +244,7 @@
     var runjs = '''
     import { dart, _isolate_helper } from 'dart_sdk.js';
     import { main } from 'main.js';
+    dart.nullSafety(false);
     _isolate_helper.startRootIsolate(() => {}, []);
     main.main();
     ''';
@@ -310,9 +317,11 @@
   if (module.isPackage) {
     packagesContents.write('${module.name}:${module.packageBase}\n');
   }
+  var unusedNum = 0;
   for (var dependency in transitiveDependencies) {
     if (dependency.isPackage) {
-      packagesContents.write('${dependency.name}:unused\n');
+      unusedNum++;
+      packagesContents.write('${dependency.name}:unused$unusedNum\n');
     }
   }
 
diff --git a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
index b091933..51310b9 100644
--- a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
@@ -1,10 +1,11 @@
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '&': int.& (int Function(int)), JSNumber.& (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '<<': int.<< (int Function(int)), JSNumber.<< (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '>>': int.>> (int Function(int)), JSNumber.>> (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '\|': int.\| (int Function(int)), JSNumber.\| (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '^': int.^ (int Function(int)), JSNumber.^ (num Function(num)).
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1648|28|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1650|27|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1653|17|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1658|18|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1658|44|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1634|7|5|Superinterfaces don't have a valid override for '&': JSNumber.& (num Function(num)), int.& (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1634|7|5|Superinterfaces don't have a valid override for '<<': JSNumber.<< (num Function(num)), int.<< (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1634|7|5|Superinterfaces don't have a valid override for '>>': JSNumber.>> (num Function(num)), int.>> (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1634|7|5|Superinterfaces don't have a valid override for '\|': JSNumber.\| (num Function(num)), int.\| (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1634|7|5|Superinterfaces don't have a valid override for '^': JSNumber.^ (num Function(num)), int.^ (int Function(int)).
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1651|28|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1653|27|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1656|17|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1661|18|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1661|44|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_WARNING|ARGUMENT_TYPE_NOT_ASSIGNABLE|lib/io/io.dart|6334|51|12|The argument type 'Object' can't be assigned to the parameter type 'String'.
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index 8b13789..1f1e98a 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1 +1,9 @@
-
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3719|5|94|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7908|5|97|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|940|5|95|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|973|5|94|Const constructors can't throw exceptions.
+ERROR|STATIC_WARNING|ARGUMENT_TYPE_NOT_ASSIGNABLE|lib/io/io.dart|6334|51|12|The argument type 'Object' can't be assigned to the parameter type 'String'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3717|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7906|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|938|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|971|3|5|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 9abb66c..8585dac 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -269,7 +269,7 @@
         function(sdk, app) {
     'use strict';
     if ($nnbd) {
-      sdk.dart.strictSubtypeChecks($isNnbdStrong);
+      sdk.dart.nullSafety($isNnbdStrong);
     }
     sdk._debugger.registerDevtoolsFormatter();
     app.$libname.main();
@@ -301,7 +301,7 @@
 let main = require(\"./$basename\").$libname.main;
 try {
   if ($nnbd) {
-    sdk.dart.strictSubtypeChecks($isNnbdStrong);
+    sdk.dart.nullSafety($isNnbdStrong);
   }
   sdk._isolate_helper.startRootIsolate(main, []);
 } catch(e) {
@@ -334,7 +334,7 @@
 let main = $libname.main;
 try {
   if ($nnbd) {
-    dart.strictSubtypeChecks($isNnbdStrong);
+    dart.nullSafety($isNnbdStrong);
   }
   _isolate_helper.startRootIsolate(() => {}, []);
   main();
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 0e993bc..4a177ab 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -490,7 +490,7 @@
    *
    * If the objects are iterables or maps, recurses into them.
    */
-  static void deepEquals(Object expected, Object actual) {
+  static void deepEquals(dynamic expected, dynamic actual) {
     // Early exit check for equality.
     if (expected == actual) return;
 
@@ -560,8 +560,10 @@
     // TODO(vsm): Make check and reason nullable or change call sites.
     // Existing tests pass null to set a reason and/or pass them through
     // via helpers.
-    check ??= _defaultCheck;
-    reason ??= "";
+    // TODO(rnystrom): Using the strange form below instead of "??=" to avoid
+    // warnings of unnecessary null checks when analyzed as NNBD code.
+    if ((check as dynamic) == null) check = _defaultCheck;
+    if ((reason as dynamic) == null) reason = "";
     String msg = reason.isEmpty ? "" : "($reason)";
     if (f is! Function()) {
       // Only throws from executing the function body should count as throwing.
@@ -570,7 +572,7 @@
     }
     try {
       f();
-    } on Object catch (e, s) {
+    } catch (e, s) {
       // A test failure doesn't count as throwing.
       if (e is ExpectException) rethrow;
       if (e is T && check(e as dynamic)) return;
diff --git a/pkg/expect/lib/minitest.dart b/pkg/expect/lib/minitest.dart
index 350b6aa..0021ada 100644
--- a/pkg/expect/lib/minitest.dart
+++ b/pkg/expect/lib/minitest.dart
@@ -26,7 +26,7 @@
 import 'package:expect/expect.dart';
 
 typedef dynamic _Action();
-typedef void _ExpectationFunction(Object actual);
+typedef void _ExpectationFunction(dynamic actual);
 
 final List<_Group> _groups = [new _Group()];
 
@@ -124,7 +124,7 @@
   _groups.last.tearDownFunction = body;
 }
 
-void expect(Object actual, Object expected, {String reason = ""}) {
+void expect(dynamic actual, dynamic expected, {String reason = ""}) {
   // TODO(rnystrom): Do something useful with reason.
   if (expected is! _Expectation) {
     expected = equals(expected);
@@ -138,19 +138,19 @@
   Expect.fail(message);
 }
 
-Object equals(Object value) => new _Expectation((actual) {
+Object equals(dynamic value) => new _Expectation((actual) {
       Expect.deepEquals(value, actual);
     });
 
-Object notEquals(Object value) => new _Expectation((actual) {
+Object notEquals(dynamic value) => new _Expectation((actual) {
       Expect.notEquals(value, actual);
     });
 
-Object unorderedEquals(Object value) => new _Expectation((actual) {
+Object unorderedEquals(dynamic value) => new _Expectation((actual) {
       Expect.setEquals(value as Iterable, actual as Iterable);
     });
 
-Object predicate(bool fn(Object value), [String description = ""]) =>
+Object predicate(bool fn(dynamic value), [String description = ""]) =>
     new _Expectation((actual) {
       Expect.isTrue(fn(actual), description);
     });
@@ -169,7 +169,7 @@
       }
     });
 
-Object same(Object value) => new _Expectation((actual) {
+Object same(dynamic value) => new _Expectation((actual) {
       Expect.identical(value, actual);
     });
 
diff --git a/pkg/expect/pubspec.yaml b/pkg/expect/pubspec.yaml
index 5e6beb6..595d26c 100644
--- a/pkg/expect/pubspec.yaml
+++ b/pkg/expect/pubspec.yaml
@@ -6,8 +6,5 @@
  Third parties are discouraged from using this, and should use
  the expect() function in the unit test library instead for
  test assertions.
-environment:
-  sdk: ">=2.0.0 <3.0.0"
-
 dependencies:
   meta: any
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 0ffeb41..602303d 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -8,7 +8,7 @@
     show DiagnosticMessageHandler;
 
 import 'package:kernel/default_language_version.dart' as kernel
-    show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
+    show defaultLanguageVersion;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -229,9 +229,9 @@
   /// The current sdk version string, e.g. "2.6.0-edge.sha1hash".
   /// For instance used for language versioning (specifying the maximum
   /// version).
-  String currentSdkVersion = "${kernel.defaultLanguageVersionMajor}"
+  String currentSdkVersion = "${kernel.defaultLanguageVersion.major}"
       "."
-      "${kernel.defaultLanguageVersionMinor}";
+      "${kernel.defaultLanguageVersion.minor}";
 
   bool equivalent(CompilerOptions other,
       {bool ignoreOnDiagnostic: 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 9945733..d5094b8 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -7,6 +7,8 @@
 // Instead modify 'tools/experimental_features.yaml' and run
 // 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
 
+import 'package:kernel/kernel.dart' show Version;
+
 enum ExperimentalFlag {
   constantUpdate2018,
   controlFlowCollections,
@@ -19,24 +21,15 @@
   variance,
 }
 
-const int enableConstantUpdate2018MajorVersion = 2;
-const int enableConstantUpdate2018MinorVersion = 4;
-const int enableControlFlowCollectionsMajorVersion = 2;
-const int enableControlFlowCollectionsMinorVersion = 2;
-const int enableExtensionMethodsMajorVersion = 2;
-const int enableExtensionMethodsMinorVersion = 6;
-const int enableNonNullableMajorVersion = 2;
-const int enableNonNullableMinorVersion = 8;
-const int enableNonfunctionTypeAliasesMajorVersion = 2;
-const int enableNonfunctionTypeAliasesMinorVersion = 8;
-const int enableSetLiteralsMajorVersion = 2;
-const int enableSetLiteralsMinorVersion = 2;
-const int enableSpreadCollectionsMajorVersion = 2;
-const int enableSpreadCollectionsMinorVersion = 2;
-const int enableTripleShiftMajorVersion = 2;
-const int enableTripleShiftMinorVersion = 8;
-const int enableVarianceMajorVersion = 2;
-const int enableVarianceMinorVersion = 8;
+const Version enableConstantUpdate2018Version = const Version(2, 4);
+const Version enableControlFlowCollectionsVersion = const Version(2, 2);
+const Version enableExtensionMethodsVersion = const Version(2, 6);
+const Version enableNonNullableVersion = const Version(2, 9);
+const Version enableNonfunctionTypeAliasesVersion = const Version(2, 9);
+const Version enableSetLiteralsVersion = const Version(2, 2);
+const Version enableSpreadCollectionsVersion = const Version(2, 2);
+const Version enableTripleShiftVersion = const Version(2, 9);
+const Version enableVarianceVersion = const Version(2, 9);
 
 ExperimentalFlag parseExperimentalFlag(String flag) {
   switch (flag) {
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 4b566d6..2ce4a67 100644
--- a/pkg/front_end/lib/src/api_prototype/language_version.dart
+++ b/pkg/front_end/lib/src/api_prototype/language_version.dart
@@ -7,6 +7,9 @@
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
     show LanguageVersionToken, Scanner, ScannerConfiguration, scan;
 
+import 'package:kernel/ast.dart' show Version, defaultLanguageVersion;
+export 'package:kernel/ast.dart' show Version;
+
 import 'package:package_config/package_config.dart'
     show InvalidLanguageVersion, Package;
 
@@ -14,6 +17,8 @@
 
 import '../fasta/compiler_context.dart' show CompilerContext;
 
+import '../fasta/source/source_library_builder.dart' show SourceLibraryBuilder;
+
 import '../fasta/uri_translator.dart' show UriTranslator;
 
 import 'compiler_options.dart' show CompilerOptions;
@@ -27,8 +32,7 @@
 /// specifies a language version that's too high).
 ///
 /// The language version returned is valid though.
-Future<LanguageVersionForUri> languageVersionForUri(
-    Uri uri, CompilerOptions options) async {
+Future<Version> languageVersionForUri(Uri uri, CompilerOptions options) async {
   return await CompilerContext.runWithOptions(
       new ProcessedOptions(options: options, inputs: [uri]), (context) async {
     // Get largest valid version / default version.
@@ -96,7 +100,7 @@
     }
     if (major != null && minor != null) {
       // The file decided. Return result.
-      return new LanguageVersionForUri(major, minor);
+      return new Version(major, minor);
     }
 
     // Check package.
@@ -113,18 +117,19 @@
     }
     if (major != null && minor != null) {
       // The package decided. Return result.
-      return new LanguageVersionForUri(major, minor);
+      return new Version(major, minor);
     }
 
     // Return default.
-    return new LanguageVersionForUri(
-        currentSdkVersionMajor, currentSdkVersionMinor);
+    return new Version(currentSdkVersionMajor, currentSdkVersionMinor);
   });
 }
 
-class LanguageVersionForUri {
-  final int major;
-  final int minor;
-
-  LanguageVersionForUri(this.major, this.minor);
+Future<bool> uriUsesLegacyLanguageVersion(
+    Uri uri, CompilerOptions options) async {
+  // This method is here in order to use the opt out hack here for test
+  // sources.
+  if (SourceLibraryBuilder.isOptOutTest(uri)) return true;
+  Version uriVersion = await languageVersionForUri(uri, options);
+  return (uriVersion < defaultLanguageVersion);
 }
diff --git a/pkg/front_end/lib/src/base/command_line_options.dart b/pkg/front_end/lib/src/base/command_line_options.dart
index c5bfc09..7ac70b7 100644
--- a/pkg/front_end/lib/src/base/command_line_options.dart
+++ b/pkg/front_end/lib/src/base/command_line_options.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.
 
-// TODO(johnniwinther): Move all option strings here.
 class Flags {
   // TODO(johnniwinther): What is the right name for this?
   static const String nnbdStrongMode = "--nnbd-strong";
@@ -13,4 +12,26 @@
       "--force-no-explicit-getter-calls";
 
   static const String target = "--target";
+
+  static const String linkDependencies = "--link-dependencies";
+
+  static const String bytecode = "--bytecode";
+  static const String compileSdk = "--compile-sdk";
+  static const String dumpIr = "--dump-ir";
+  static const String enableExperiment = "--enable-experiment";
+  static const String excludeSource = "--exclude-source";
+  static const String omitPlatform = "--omit-platform";
+  static const String fatal = "--fatal";
+  static const String fatalSkip = "--fatal-skip";
+  static const String help = "--help";
+  static const String librariesJson = "--libraries-json";
+  static const String noDefines = "--no-defines";
+  static const String output = "--output";
+  static const String packages = "--packages";
+  static const String platform = "--platform";
+  static const String sdk = "--sdk";
+  static const String singleRootBase = "--single-root-base";
+  static const String singleRootScheme = "--single-root-scheme";
+  static const String verbose = "--verbose";
+  static const String verify = "--verify";
 }
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index f199738..48303eb 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -132,13 +132,15 @@
   }
 
   List<int> _sdkSummaryBytes;
+  bool _triedLoadingSdkSummary = false;
 
   /// Get the bytes of the SDK outline, if any.
   Future<List<int>> loadSdkSummaryBytes() async {
-    if (_sdkSummaryBytes == null) {
+    if (_sdkSummaryBytes == null && !_triedLoadingSdkSummary) {
       if (sdkSummary == null) return null;
       FileSystemEntity entry = fileSystem.entityForUri(sdkSummary);
       _sdkSummaryBytes = await _readAsBytes(entry);
+      _triedLoadingSdkSummary = true;
     }
     return _sdkSummaryBytes;
   }
@@ -364,8 +366,10 @@
       // TODO(sigmund): throttle # of concurrent operations.
       List<List<int>> allBytes = await Future.wait(
           uris.map((uri) => _readAsBytes(fileSystem.entityForUri(uri))));
-      _additionalDillComponents =
-          allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
+      _additionalDillComponents = allBytes
+          .where((bytes) => bytes != null)
+          .map((bytes) => loadComponent(bytes, nameRoot))
+          .toList();
     }
     return _additionalDillComponents;
   }
@@ -726,7 +730,7 @@
               .withArguments(error.uri, error.message)
               .withoutLocation(),
           Severity.error);
-      return new Uint8List(0);
+      return null;
     }
   }
 }
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 cebb845..fd82ceb 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -21,18 +21,15 @@
         Member,
         MethodInvocation,
         Name,
-        NeverType,
         Nullability,
         Procedure,
         ProcedureKind,
-        RedirectingFactoryConstructor,
         ReturnStatement,
         Supertype,
         ThisExpression,
         TypeParameter,
         TypeParameterType,
         VariableDeclaration,
-        Variance,
         VoidType,
         getAsTypeArguments;
 
@@ -40,13 +37,6 @@
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'package:kernel/src/bounds_checks.dart'
-    show
-        TypeArgumentIssue,
-        computeVariance,
-        findTypeArgumentIssues,
-        getGenericTypeName;
-
 import 'package:kernel/src/legacy_erasure.dart';
 
 import 'package:kernel/text/text_serialization_verifier.dart';
@@ -56,6 +46,8 @@
 import 'package:kernel/type_environment.dart'
     show SubtypeCheckMode, TypeEnvironment;
 
+import 'package:kernel/src/types.dart' show Types;
+
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
 import '../fasta_codes.dart';
@@ -64,8 +56,6 @@
 
 import '../kernel/kernel_target.dart' show KernelTarget;
 
-import '../kernel/types.dart' show Types;
-
 import '../loader.dart';
 
 import '../modifier.dart';
@@ -202,11 +192,6 @@
 
   void checkSupertypes(CoreTypes coreTypes);
 
-  void checkBoundsInSupertype(
-      Supertype supertype, TypeEnvironment typeEnvironment);
-
-  void checkTypesInOutline(TypeEnvironment typeEnvironment);
-
   void handleSeenCovariant(
       Types types,
       Member declaredMember,
@@ -749,273 +734,6 @@
   }
 
   @override
-  void checkBoundsInSupertype(
-      Supertype supertype, TypeEnvironment typeEnvironment) {
-    SourceLibraryBuilder library = this.library;
-    final DartType bottomType = library.isNonNullableByDefault
-        ? const NeverType(Nullability.nonNullable)
-        : typeEnvironment.nullType;
-
-    Set<TypeArgumentIssue> issues = {};
-    issues.addAll(findTypeArgumentIssues(
-            new InterfaceType(supertype.classNode, library.nonNullable,
-                supertype.typeArguments),
-            typeEnvironment,
-            SubtypeCheckMode.ignoringNullabilities,
-            bottomType,
-            allowSuperBounded: false) ??
-        const []);
-    if (library.isNonNullableByDefault) {
-      issues.addAll(findTypeArgumentIssues(
-              new InterfaceType(supertype.classNode, library.nonNullable,
-                  supertype.typeArguments),
-              typeEnvironment,
-              SubtypeCheckMode.withNullabilities,
-              bottomType,
-              allowSuperBounded: false) ??
-          const []);
-    }
-    for (TypeArgumentIssue issue in issues) {
-      DartType argument = issue.argument;
-      TypeParameter typeParameter = issue.typeParameter;
-      bool inferred = library.inferredTypes.contains(argument);
-      if (argument is FunctionType && argument.typeParameters.length > 0) {
-        if (inferred) {
-          library.reportTypeArgumentIssue(
-              templateGenericFunctionTypeInferredAsActualTypeArgument
-                  .withArguments(argument, library.isNonNullableByDefault),
-              fileUri,
-              charOffset,
-              null);
-        } else {
-          library.reportTypeArgumentIssue(
-              messageGenericFunctionTypeUsedAsActualTypeArgument,
-              fileUri,
-              charOffset,
-              null);
-        }
-      } else {
-        void reportProblem(
-            Template<
-                    Message Function(DartType, DartType, String, String, String,
-                        String, bool)>
-                template) {
-          library.reportTypeArgumentIssue(
-              template.withArguments(
-                  argument,
-                  typeParameter.bound,
-                  typeParameter.name,
-                  getGenericTypeName(issue.enclosingType),
-                  supertype.classNode.name,
-                  name,
-                  library.isNonNullableByDefault),
-              fileUri,
-              charOffset,
-              typeParameter);
-        }
-
-        if (inferred) {
-          reportProblem(templateIncorrectTypeArgumentInSupertypeInferred);
-        } else {
-          reportProblem(templateIncorrectTypeArgumentInSupertype);
-        }
-      }
-    }
-  }
-
-  @override
-  void checkTypesInOutline(TypeEnvironment typeEnvironment) {
-    SourceLibraryBuilder library = this.library;
-    final DartType bottomType = library.isNonNullableByDefault
-        ? const NeverType(Nullability.nonNullable)
-        : typeEnvironment.nullType;
-
-    // Check in bounds of own type variables.
-    for (TypeParameter parameter in cls.typeParameters) {
-      Set<TypeArgumentIssue> issues = {};
-      issues.addAll(findTypeArgumentIssues(parameter.bound, typeEnvironment,
-              SubtypeCheckMode.ignoringNullabilities, bottomType,
-              allowSuperBounded: true) ??
-          const []);
-      if (library.isNonNullableByDefault) {
-        issues.addAll(findTypeArgumentIssues(parameter.bound, typeEnvironment,
-                SubtypeCheckMode.withNullabilities, bottomType,
-                allowSuperBounded: true) ??
-            const []);
-      }
-      for (TypeArgumentIssue issue in issues) {
-        DartType argument = issue.argument;
-        TypeParameter typeParameter = issue.typeParameter;
-        if (library.inferredTypes.contains(argument)) {
-          // Inference in type expressions in the supertypes boils down to
-          // instantiate-to-bound which shouldn't produce anything that breaks
-          // the bounds after the non-simplicity checks are done.  So, any
-          // violation here is the result of non-simple bounds, and the error
-          // is reported elsewhere.
-          continue;
-        }
-
-        if (argument is FunctionType && argument.typeParameters.length > 0) {
-          library.reportTypeArgumentIssue(
-              messageGenericFunctionTypeUsedAsActualTypeArgument,
-              fileUri,
-              parameter.fileOffset,
-              null);
-        } else {
-          library.reportTypeArgumentIssue(
-              templateIncorrectTypeArgument.withArguments(
-                  argument,
-                  typeParameter.bound,
-                  typeParameter.name,
-                  getGenericTypeName(issue.enclosingType),
-                  library.isNonNullableByDefault),
-              fileUri,
-              parameter.fileOffset,
-              typeParameter);
-        }
-      }
-    }
-
-    // Check in supers.
-    if (cls.supertype != null) {
-      checkBoundsInSupertype(cls.supertype, typeEnvironment);
-    }
-    if (cls.mixedInType != null) {
-      checkBoundsInSupertype(cls.mixedInType, typeEnvironment);
-    }
-    if (cls.implementedTypes != null) {
-      for (Supertype supertype in cls.implementedTypes) {
-        checkBoundsInSupertype(supertype, typeEnvironment);
-      }
-    }
-
-    // Check in members.
-    for (Procedure procedure in cls.procedures) {
-      checkVarianceInFunction(procedure, typeEnvironment, cls.typeParameters);
-      library.checkBoundsInFunctionNode(
-          procedure.function, typeEnvironment, fileUri);
-    }
-    for (Constructor constructor in cls.constructors) {
-      library.checkBoundsInFunctionNode(
-          constructor.function, typeEnvironment, fileUri);
-    }
-    for (RedirectingFactoryConstructor redirecting
-        in cls.redirectingFactoryConstructors) {
-      library.checkBoundsInFunctionNodeParts(
-          typeEnvironment, fileUri, redirecting.fileOffset,
-          typeParameters: redirecting.typeParameters,
-          positionalParameters: redirecting.positionalParameters,
-          namedParameters: redirecting.namedParameters);
-    }
-
-    forEach((String name, Builder builder) {
-      // Check fields.
-      if (builder is FieldBuilder) {
-        checkVarianceInField(
-            builder.field, typeEnvironment, cls.typeParameters);
-        library.checkTypesInField(builder, typeEnvironment);
-      }
-
-      // Check initializers.
-      if (builder is FunctionBuilder &&
-          !builder.isAbstract &&
-          builder.formals != null) {
-        library.checkInitializersInFormals(builder.formals, typeEnvironment);
-      }
-    });
-  }
-
-  void checkVarianceInField(Field field, TypeEnvironment typeEnvironment,
-      List<TypeParameter> typeParameters) {
-    for (TypeParameter typeParameter in typeParameters) {
-      int fieldVariance = computeVariance(typeParameter, field.type);
-      if (field.hasImplicitGetter) {
-        reportVariancePositionIfInvalid(
-            fieldVariance, typeParameter, field.fileUri, field.fileOffset);
-      }
-      if (field.hasImplicitSetter && !field.isCovariant) {
-        fieldVariance = Variance.combine(Variance.contravariant, fieldVariance);
-        reportVariancePositionIfInvalid(
-            fieldVariance, typeParameter, field.fileUri, field.fileOffset);
-      }
-    }
-  }
-
-  void checkVarianceInFunction(Procedure procedure,
-      TypeEnvironment typeEnvironment, List<TypeParameter> typeParameters) {
-    List<TypeParameter> functionTypeParameters =
-        procedure.function.typeParameters;
-    List<VariableDeclaration> positionalParameters =
-        procedure.function.positionalParameters;
-    List<VariableDeclaration> namedParameters =
-        procedure.function.namedParameters;
-    DartType returnType = procedure.function.returnType;
-
-    if (functionTypeParameters != null) {
-      for (TypeParameter functionParameter in functionTypeParameters) {
-        for (TypeParameter typeParameter in typeParameters) {
-          int typeVariance = Variance.combine(Variance.invariant,
-              computeVariance(typeParameter, functionParameter.bound));
-          reportVariancePositionIfInvalid(typeVariance, typeParameter, fileUri,
-              functionParameter.fileOffset);
-        }
-      }
-    }
-    if (positionalParameters != null) {
-      for (VariableDeclaration formal in positionalParameters) {
-        if (!formal.isCovariant) {
-          for (TypeParameter typeParameter in typeParameters) {
-            int formalVariance = Variance.combine(Variance.contravariant,
-                computeVariance(typeParameter, formal.type));
-            reportVariancePositionIfInvalid(
-                formalVariance, typeParameter, fileUri, formal.fileOffset);
-          }
-        }
-      }
-    }
-    if (namedParameters != null) {
-      for (VariableDeclaration named in namedParameters) {
-        for (TypeParameter typeParameter in typeParameters) {
-          int namedVariance = Variance.combine(Variance.contravariant,
-              computeVariance(typeParameter, named.type));
-          reportVariancePositionIfInvalid(
-              namedVariance, typeParameter, fileUri, named.fileOffset);
-        }
-      }
-    }
-    if (returnType != null) {
-      for (TypeParameter typeParameter in typeParameters) {
-        int returnTypeVariance = computeVariance(typeParameter, returnType);
-        reportVariancePositionIfInvalid(returnTypeVariance, typeParameter,
-            fileUri, procedure.function.fileOffset,
-            isReturnType: true);
-      }
-    }
-  }
-
-  void reportVariancePositionIfInvalid(
-      int variance, TypeParameter typeParameter, Uri fileUri, int fileOffset,
-      {bool isReturnType: false}) {
-    SourceLibraryBuilder library = this.library;
-    if (!typeParameter.isLegacyCovariant &&
-        !Variance.greaterThanOrEqual(variance, typeParameter.variance)) {
-      Message message;
-      if (isReturnType) {
-        message = templateInvalidTypeVariableVariancePositionInReturnType
-            .withArguments(Variance.keywordString(typeParameter.variance),
-                typeParameter.name, Variance.keywordString(variance));
-      } else {
-        message = templateInvalidTypeVariableVariancePosition.withArguments(
-            Variance.keywordString(typeParameter.variance),
-            typeParameter.name,
-            Variance.keywordString(variance));
-      }
-      library.reportTypeArgumentIssue(
-          message, fileUri, fileOffset, typeParameter);
-    }
-  }
-
-  @override
   void handleSeenCovariant(
       Types types,
       Member declaredMember,
@@ -1025,8 +743,9 @@
     // When a parameter is covariant we have to check that we also
     // override the same member in all parents.
     for (Supertype supertype in interfaceMember.enclosingClass.supers) {
-      Member m = types.hierarchy.getInterfaceMemberKernel(
-          supertype.classNode, interfaceMember.name, isSetter);
+      Member m = types.hierarchy.getInterfaceMember(
+          supertype.classNode, interfaceMember.name,
+          setter: isSetter);
       if (m != null) {
         callback(declaredMember, m, isSetter);
       }
@@ -1160,7 +879,7 @@
       interfaceSubstitution = Substitution.fromPairs(
           enclosingClass.typeParameters,
           types.hierarchy
-              .getKernelTypeArgumentsAsInstanceOf(thisType, enclosingClass));
+              .getTypeArgumentsAsInstanceOf(thisType, enclosingClass));
     }
 
     if (declaredFunction?.typeParameters?.length !=
@@ -1203,8 +922,13 @@
                 interfaceSubstitution.substituteType(interfaceBound);
           }
           DartType computedBound = substitution.substituteType(interfaceBound);
+          if (!library.isNonNullableByDefault) {
+            computedBound =
+                legacyErasure(types.hierarchy.coreTypes, computedBound);
+          }
           if (!types
-              .isSameTypeKernel(declaredBound, computedBound)
+              .performNullabilityAwareMutualSubtypesCheck(
+                  declaredBound, computedBound)
               .isSubtypeWhenUsingNullabilities()) {
             reportInvalidOverride(
                 isInterfaceCheck,
@@ -1243,7 +967,7 @@
       declaredSubstitution = Substitution.fromPairs(
           enclosingClass.typeParameters,
           types.hierarchy
-              .getKernelTypeArgumentsAsInstanceOf(thisType, enclosingClass));
+              .getTypeArgumentsAsInstanceOf(thisType, enclosingClass));
     }
     return declaredSubstitution;
   }
@@ -1276,11 +1000,11 @@
     DartType subtype = inParameter ? interfaceType : declaredType;
     DartType supertype = inParameter ? declaredType : interfaceType;
 
-    if (types.isSubtypeOfKernel(
+    if (types.isSubtypeOf(
         subtype, supertype, SubtypeCheckMode.withNullabilities)) {
       // No problem--the proper subtyping relation is satisfied.
     } else if (isCovariant &&
-        types.isSubtypeOfKernel(
+        types.isSubtypeOf(
             supertype, subtype, SubtypeCheckMode.withNullabilities)) {
       // No problem--the overriding parameter is marked "covariant" and has
       // a type which is a subtype of the parameter it overrides.
@@ -1289,10 +1013,10 @@
       // been reported.
     } else {
       // Report an error.
-      bool isErrorInNnbdOptedOutMode = !types.isSubtypeOfKernel(
+      bool isErrorInNnbdOptedOutMode = !types.isSubtypeOf(
               subtype, supertype, SubtypeCheckMode.ignoringNullabilities) &&
           (!isCovariant ||
-              !types.isSubtypeOfKernel(
+              !types.isSubtypeOf(
                   supertype, subtype, SubtypeCheckMode.ignoringNullabilities));
       if (isErrorInNnbdOptedOutMode || library.isNonNullableByDefault) {
         String declaredMemberName = '${declaredMember.enclosingClass.name}'
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 9a69677..5cb9fc0 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -674,12 +674,14 @@
         new Field(null, fileUri: fileUri, reference: referenceFrom?.reference)
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = true;
+          ..isNonNullableByDefault = true
+          ..isInternalImplementation = true;
     _lateIsSetField = new Field(null,
         fileUri: fileUri, reference: lateIsSetReferenceFrom?.reference)
       ..fileOffset = charOffset
       ..fileEndOffset = charEndOffset
-      ..isNonNullableByDefault = true;
+      ..isNonNullableByDefault = true
+      ..isInternalImplementation = true;
     _lateGetter = new Procedure(
         null, ProcedureKind.Getter, new FunctionNode(null),
         fileUri: fileUri, reference: getterReferenceFrom?.reference)
@@ -936,11 +938,14 @@
   @override
   List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) {
     List<ClassMember> list = <ClassMember>[
-      new _LateFieldClassMember(fieldBuilder, field),
-      new _LateFieldClassMember(fieldBuilder, _lateGetter)
+      new _LateFieldClassMember(fieldBuilder, field,
+          isInternalImplementation: true),
+      new _LateFieldClassMember(fieldBuilder, _lateGetter,
+          isInternalImplementation: false)
     ];
     if (_lateIsSetField != null) {
-      list.add(new _LateFieldClassMember(fieldBuilder, _lateIsSetField));
+      list.add(new _LateFieldClassMember(fieldBuilder, _lateIsSetField,
+          isInternalImplementation: true));
     }
     return list;
   }
@@ -950,11 +955,11 @@
     List<ClassMember> list = <ClassMember>[];
     if (_lateIsSetField != null) {
       list.add(new _LateFieldClassMember(fieldBuilder, _lateIsSetField,
-          forSetter: true));
+          forSetter: true, isInternalImplementation: true));
     }
     if (_lateSetter != null) {
       list.add(new _LateFieldClassMember(fieldBuilder, _lateSetter,
-          forSetter: true));
+          forSetter: true, isInternalImplementation: false));
     }
     return list;
   }
@@ -1106,8 +1111,12 @@
   @override
   final bool forSetter;
 
+  @override
+  final bool isInternalImplementation;
+
   _LateFieldClassMember(this.fieldBuilder, this._member,
-      {this.forSetter: false});
+      {this.forSetter: false, this.isInternalImplementation})
+      : assert(isInternalImplementation != null);
 
   Member getMember(ClassHierarchyBuilder hierarchy) {
     fieldBuilder._ensureType(hierarchy);
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 e176173..224ecbc 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -6,7 +6,7 @@
 
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Library, Nullability;
+import 'package:kernel/ast.dart' show Library, Nullability, Version;
 
 import '../combinator.dart' show Combinator;
 
@@ -53,7 +53,7 @@
 
   bool mayImplementRestrictedTypes;
 
-  /// Set the language version to a specific non-null major and minor version.
+  /// 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
@@ -67,7 +67,7 @@
   ///
   /// [offset] and [length] refers to the offset and length of the source code
   /// specifying the language version.
-  void setLanguageVersion(int major, int minor,
+  void setLanguageVersion(Version version,
       {int offset: 0, int length, bool explicit});
 
   bool get isPart;
@@ -222,6 +222,9 @@
 
   /// 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.
@@ -235,7 +238,7 @@
   /// [offset] and [length] refers to the offset and length of the source code
   /// specifying the language version.
   @override
-  void setLanguageVersion(int major, int minor,
+  void setLanguageVersion(Version version,
       {int offset: 0, int length, bool explicit});
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index edeb46b..2d827d5 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -249,6 +249,9 @@
   bool get isSynthesized => false;
 
   @override
+  bool get isInternalImplementation => false;
+
+  @override
   bool get isInheritableConflict => false;
 
   @override
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 a852f46..7b26757 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
@@ -79,7 +79,7 @@
   bool get fromDill => false;
 
   Typedef build(SourceLibraryBuilder libraryBuilder) {
-    typedef..type ??= buildThisType(libraryBuilder);
+    typedef..type ??= buildThisType();
 
     TypeBuilder type = this.type;
     if (type is FunctionTypeBuilder) {
@@ -146,7 +146,7 @@
     return result;
   }
 
-  DartType buildThisType(LibraryBuilder library) {
+  DartType buildThisType() {
     if (thisType != null) {
       if (identical(thisType, cyclicTypeAliasMarker)) {
         library.addProblem(templateCyclicTypedef.withArguments(name),
@@ -181,7 +181,7 @@
   /// [arguments] have already been built.
   DartType buildTypesWithBuiltArguments(LibraryBuilder library,
       Nullability nullability, List<DartType> arguments) {
-    DartType thisType = buildThisType(library);
+    DartType thisType = buildThisType();
     if (const DynamicType() == thisType) return thisType;
     Nullability adjustedNullability =
         isNullAlias ? Nullability.nullable : nullability;
@@ -248,26 +248,32 @@
   DartType buildType(LibraryBuilder library,
       NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments,
       [bool notInstanceContext]) {
-    DartType thisType = buildThisType(library);
+    DartType thisType = buildThisType();
     if (thisType is InvalidType) return thisType;
     // TODO(dmitryas): Remove the following comment when FutureOr has its own
     // encoding and isn't represented as an InterfaceType.
 
     // The following won't work if the right-hand side of the typedef is a
     // FutureOr.
-    Nullability rhsNullability = thisType.nullability;
+    Nullability nullability;
+    if (isNullAlias) {
+      // Null is always nullable.
+      nullability = Nullability.nullable;
+    } else if (!parent.isNonNullableByDefault ||
+        !library.isNonNullableByDefault) {
+      // The typedef is defined or used in an opt-out library so the nullability
+      // is based on the use site alone.
+      nullability = nullabilityBuilder.build(library);
+    } else {
+      nullability = uniteNullabilities(
+          thisType.nullability, nullabilityBuilder.build(library));
+    }
     if (typedef.typeParameters.isEmpty && arguments == null) {
-      Nullability nullability = isNullAlias
-          ? Nullability.nullable
-          : nullabilityBuilder.build(library);
-      return thisType
-          .withNullability(uniteNullabilities(rhsNullability, nullability));
+      return thisType.withNullability(nullability);
     }
     // Otherwise, substitute.
     return buildTypesWithBuiltArguments(
-        library,
-        uniteNullabilities(rhsNullability, nullabilityBuilder.build(library)),
-        buildTypeArguments(library, arguments));
+        library, nullability, buildTypeArguments(library, arguments));
   }
 
   TypeDeclarationBuilder _cachedUnaliasedDeclaration;
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 818480a..e9a2f1d 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
@@ -26,7 +26,8 @@
         StaticGet,
         StringConstant,
         StringLiteral,
-        Typedef;
+        Typedef,
+        Version;
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
@@ -137,7 +138,7 @@
   bool get isNonNullableByDefault => library.isNonNullableByDefault;
 
   @override
-  void setLanguageVersion(int major, int minor,
+  void setLanguageVersion(Version version,
       {int offset: 0, int length, bool explicit}) {}
 
   Uri get importUri => library.importUri;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
index 5e8589c..93becfc 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
@@ -156,6 +156,12 @@
   bool get isSourceDeclaration => false;
 
   @override
+  bool get isInternalImplementation {
+    Member member = memberBuilder.member;
+    return member is Field && member.isInternalImplementation;
+  }
+
+  @override
   bool get isProperty =>
       memberBuilder.kind == null ||
       memberBuilder.kind == ProcedureKind.Getter ||
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 f13acd1..6a06914 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
@@ -45,7 +45,7 @@
   }
 
   @override
-  DartType buildThisType(LibraryBuilder library) {
+  DartType buildThisType() {
     return thisType ??= typedef.type;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index e0a4b57..3da4fa2 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -11,6 +11,7 @@
         BinaryBuilderWithMetadata,
         CanonicalNameError,
         CanonicalNameSdkError,
+        CompilationModeError,
         InvalidKernelVersionError,
         SubComponentView;
 
@@ -30,6 +31,7 @@
         LibraryDependency,
         LibraryPart,
         Name,
+        NonNullableByDefaultCompiledMode,
         Procedure,
         ProcedureKind,
         ReturnStatement,
@@ -279,9 +281,14 @@
             await userCode.buildComponent(verify: c.options.verify);
       }
       hierarchy ??= userCode.loader.hierarchy;
-      if (hierarchy != null && userCode.classesChangedStructure != null) {
-        hierarchy.applyMemberChanges(userCode.classesChangedStructure,
-            findDescendants: true);
+      if (hierarchy != null) {
+        if (userCode.classHierarchyChanges != null) {
+          hierarchy.applyTreeChanges([], [], userCode.classHierarchyChanges);
+        }
+        if (userCode.classMemberChanges != null) {
+          hierarchy.applyMemberChanges(userCode.classMemberChanges,
+              findDescendants: true);
+        }
       }
       recordNonFullComponentForTesting(componentWithDill);
 
@@ -331,11 +338,14 @@
 
       // Output result.
       Procedure mainMethod = componentWithDill == null
-          ? data.userLoadedUriMain
+          ? data.component?.mainMethod
           : componentWithDill.mainMethod;
+      NonNullableByDefaultCompiledMode compiledMode = componentWithDill == null
+          ? data.component?.mode
+          : componentWithDill.mode;
       return context.options.target.configureComponent(
           new Component(libraries: outputLibraries, uriToSource: uriToSource))
-        ..mainMethod = mainMethod
+        ..setMainMethodAndMode(mainMethod?.reference, true, compiledMode)
         ..problemsAsJson = problemsAsJson;
     });
   }
@@ -784,7 +794,7 @@
         Library lib = builder.library;
         removedLibraries.add(lib);
       }
-      hierarchy.applyTreeChanges(removedLibraries, const []);
+      hierarchy.applyTreeChanges(removedLibraries, const [], const []);
     }
   }
 
@@ -1006,7 +1016,8 @@
 
             if (e is InvalidKernelVersionError ||
                 e is PackageChangedError ||
-                e is CanonicalNameSdkError) {
+                e is CanonicalNameSdkError ||
+                e is CompilationModeError) {
               // Don't report any warning.
             } else {
               Uri gzInitializedFrom;
@@ -1374,7 +1385,7 @@
         incrementalSerializer?.invalidate(builder.fileUri);
       }
     }
-    hierarchy?.applyTreeChanges(removedLibraries, const []);
+    hierarchy?.applyTreeChanges(removedLibraries, const [], const []);
     if (removedDillBuilders) {
       makeDillLoaderLibrariesUpToDateWithBuildersMap();
     }
@@ -1491,7 +1502,6 @@
 
         initializedFromDill = true;
         bytesLength += initializationBytes.length;
-        data.userLoadedUriMain = data.component.mainMethod;
         saveComponentProblems(data);
       }
     }
@@ -1522,8 +1532,8 @@
     data.component = new Component(
         libraries: componentToInitializeFrom.libraries,
         uriToSource: componentToInitializeFrom.uriToSource)
-      ..mainMethod = componentToInitializeFrom.mainMethod;
-    data.userLoadedUriMain = componentToInitializeFrom.mainMethod;
+      ..setMainMethodAndMode(componentToInitializeFrom.mainMethod?.reference,
+          true, componentToInitializeFrom.mode);
     saveComponentProblems(data);
 
     bool foundDartCore = false;
@@ -1592,9 +1602,7 @@
         scope: libraryBuilder.scope.createNestedScope("expression"),
         nameOrigin: libraryBuilder.library,
       );
-      debugLibrary.setLanguageVersion(
-          libraryBuilder.library.languageVersionMajor,
-          libraryBuilder.library.languageVersionMinor);
+      debugLibrary.setLanguageVersion(libraryBuilder.library.languageVersion);
 
       if (libraryBuilder is DillLibraryBuilder) {
         for (LibraryDependency dependency
@@ -1888,7 +1896,6 @@
 }
 
 class IncrementalCompilerData {
-  Procedure userLoadedUriMain = null;
   Component component = null;
   List<int> initializationBytes = null;
 }
@@ -1921,7 +1928,9 @@
 
 class IncrementalKernelTarget extends KernelTarget
     implements ChangedStructureNotifier {
-  Set<Class> classesChangedStructure;
+  Set<Class> classHierarchyChanges;
+  Set<Class> classMemberChanges;
+
   IncrementalKernelTarget(FileSystem fileSystem, bool includeComments,
       DillTarget dillTarget, UriTranslator uriTranslator)
       : super(fileSystem, includeComments, dillTarget, uriTranslator);
@@ -1929,8 +1938,14 @@
   ChangedStructureNotifier get changedStructureNotifier => this;
 
   @override
-  void forClass(Class c) {
-    classesChangedStructure ??= new Set<Class>();
-    classesChangedStructure.add(c);
+  void registerClassMemberChange(Class c) {
+    classMemberChanges ??= new Set<Class>();
+    classMemberChanges.add(c);
+  }
+
+  @override
+  void registerClassHierarchyChange(Class cls) {
+    classHierarchyChanges ??= <Class>{};
+    classHierarchyChanges.add(cls);
   }
 }
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 e32f0fc..f9dfb2b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -272,6 +272,11 @@
   ///
   bool get inLateLocalInitializer => _localInitializerState.head;
 
+  Link<bool> _isOrAsOperatorTypeState = const Link<bool>().prepend(false);
+
+  @override
+  bool get inIsOrAsOperatorType => _isOrAsOperatorTypeState.head;
+
   Link<bool> _localInitializerState = const Link<bool>().prepend(false);
 
   List<Initializer> _initializers;
@@ -848,8 +853,7 @@
 
     final ModifierBuilder member = this.member;
     if (!(member is ConstructorBuilder && !member.isExternal)) {
-      // Initializer not allowed. An error will (hopefully) have been created
-      // already.
+      // An error has been reported by the parser.
       initializers = <Initializer>[];
     } else if (node is Initializer) {
       initializers = <Initializer>[node];
@@ -1526,33 +1530,56 @@
     Arguments arguments = pop();
     List<UnresolvedType> typeArguments = pop();
     Object receiver = pop();
-    if (arguments != null && typeArguments != null) {
+    // Delay adding [typeArguments] to [forest] for type aliases: They
+    // must be unaliased to the type arguments of the denoted type.
+    bool isInForest = arguments != null &&
+        typeArguments != null &&
+        (receiver is! TypeUseGenerator ||
+            (receiver is TypeUseGenerator &&
+                receiver.declaration is! TypeAliasBuilder));
+    if (isInForest) {
       assert(forest.argumentsTypeArguments(arguments).isEmpty);
       forest.argumentsSetTypeArguments(
           arguments, buildDartTypeArguments(typeArguments));
     } else {
-      assert(typeArguments == null);
+      assert(typeArguments == null ||
+          (receiver is TypeUseGenerator &&
+              receiver.declaration is TypeAliasBuilder));
     }
     if (receiver is Identifier) {
       Name name = new Name(receiver.name, libraryBuilder.nameOrigin);
       if (arguments == null) {
         push(new IncompletePropertyAccessGenerator(this, beginToken, name));
       } else {
-        push(new SendAccessGenerator(this, beginToken, name, arguments));
+        push(new SendAccessGenerator(
+            this, beginToken, name, typeArguments, arguments,
+            isTypeArgumentsInForest: isInForest));
       }
+    } else if (receiver is ParserRecovery) {
+      push(new ParserErrorGenerator(this, null, fasta.messageSyntheticToken));
     } else if (arguments == null) {
       push(receiver);
     } else {
-      push(finishSend(receiver, arguments, beginToken.charOffset));
+      push(finishSend(receiver, typeArguments, arguments, beginToken.charOffset,
+          isTypeArgumentsInForest: isInForest));
     }
+    assert(checkState(beginToken, [
+      unionOfKinds([
+        ValueKinds.Expression,
+        ValueKinds.Generator,
+        ValueKinds.Initializer,
+        ValueKinds.ProblemBuilder
+      ])
+    ]));
   }
 
   @override
-  finishSend(Object receiver, Arguments arguments, int charOffset) {
+  finishSend(Object receiver, List<UnresolvedType> typeArguments,
+      Arguments arguments, int charOffset,
+      {bool isTypeArgumentsInForest = false}) {
     if (receiver is Generator) {
-      return receiver.doInvocation(charOffset, arguments);
-    } else if (receiver is ParserRecovery) {
-      return new ParserErrorGenerator(this, null, fasta.messageSyntheticToken);
+      return receiver.doInvocation(charOffset, typeArguments, arguments,
+          isTypeArgumentsInForest: isTypeArgumentsInForest);
     } else {
       return forest.createExpressionInvocation(
           charOffset, toValue(receiver), arguments);
@@ -3067,20 +3094,18 @@
   @override
   void handleNonNullAssertExpression(Token bang) {
     assert(checkState(bang, [
-      unionOfKinds([ValueKinds.Expression, ValueKinds.Generator])
+      unionOfKinds([
+        ValueKinds.Expression,
+        ValueKinds.Generator,
+        ValueKinds.Initializer,
+        ValueKinds.ProblemBuilder
+      ])
     ]));
     if (!libraryBuilder.isNonNullableByDefault) {
       reportNonNullAssertExpressionNotEnabled(bang);
     }
-    Object operand = pop();
-    Expression expression;
-    if (operand is Generator) {
-      expression = operand.buildSimpleRead();
-    } else {
-      assert(operand is Expression);
-      expression = operand;
-    }
-    push(forest.createNullCheck(offsetForToken(bang), expression));
+    Expression operand = popForValue();
+    push(forest.createNullCheck(offsetForToken(bang), operand));
   }
 
   @override
@@ -3220,9 +3245,20 @@
   }
 
   @override
+  void beginAsOperatorType(Token operator) {
+    _isOrAsOperatorTypeState = _isOrAsOperatorTypeState.prepend(true);
+  }
+
+  @override
+  void endAsOperatorType(Token operator) {
+    _isOrAsOperatorTypeState = _isOrAsOperatorTypeState.tail;
+  }
+
+  @override
   void handleAsOperator(Token operator) {
     debugEvent("AsOperator");
-    DartType type = buildDartType(pop());
+    DartType type = buildDartType(pop(),
+        allowPotentiallyConstantType: libraryBuilder.isNonNullableByDefault);
     libraryBuilder.checkBoundsInType(
         type, typeEnvironment, uri, operator.charOffset);
     Expression expression = popForValue();
@@ -3233,9 +3269,20 @@
   }
 
   @override
+  void beginIsOperatorType(Token operator) {
+    _isOrAsOperatorTypeState = _isOrAsOperatorTypeState.prepend(true);
+  }
+
+  @override
+  void endIsOperatorType(Token operator) {
+    _isOrAsOperatorTypeState = _isOrAsOperatorTypeState.tail;
+  }
+
+  @override
   void handleIsOperator(Token isOperator, Token not) {
     debugEvent("IsOperator");
-    DartType type = buildDartType(pop());
+    DartType type = buildDartType(pop(),
+        allowPotentiallyConstantType: libraryBuilder.isNonNullableByDefault);
     Expression operand = popForValue();
     bool isInverted = not != null;
     Expression isExpression = forest.createIsExpression(
@@ -3660,6 +3707,7 @@
       unionOfKinds(<ValueKind>[
         ValueKinds.Expression,
         ValueKinds.Generator,
+        ValueKinds.ProblemBuilder
       ]),
     ]));
     debugEvent("UnaryPrefixExpression");
@@ -4125,7 +4173,8 @@
       String name,
       List<UnresolvedType> typeArguments,
       int charOffset,
-      Constness constness) {
+      Constness constness,
+      {bool isTypeArgumentsInForest = false}) {
     if (arguments == null) {
       return buildProblem(fasta.messageMissingArgumentList,
           nameToken.charOffset, nameToken.length);
@@ -4136,28 +4185,15 @@
           nameToken.charOffset, nameToken.length);
     }
 
-    if (typeArguments != null) {
-      assert(forest.argumentsTypeArguments(arguments).isEmpty);
-      forest.argumentsSetTypeArguments(
-          arguments, buildDartTypeArguments(typeArguments));
-    }
-
     String errorName;
     LocatedMessage message;
 
     if (type is TypeAliasBuilder) {
       errorName = debugName(type.name, name);
       TypeAliasBuilder aliasBuilder = type;
-      List<TypeBuilder> typeArgumentBuilders = null;
-      if (typeArguments != null) {
-        typeArgumentBuilders = <TypeBuilder>[];
-        for (UnresolvedType unresolvedType in typeArguments) {
-          typeArgumentBuilders.add(unresolvedType?.builder);
-        }
-      }
       int numberOfTypeParameters = aliasBuilder.typeVariables?.length ?? 0;
-      int numberOfTypeArguments = typeArgumentBuilders?.length ?? 0;
-      if (typeArgumentBuilders != null &&
+      int numberOfTypeArguments = typeArguments?.length ?? 0;
+      if (typeArguments != null &&
           numberOfTypeParameters != numberOfTypeArguments) {
         // TODO(eernst): Use position of type arguments, not nameToken.
         return evaluateArgumentsBefore(
@@ -4165,13 +4201,20 @@
             buildProblem(
                 fasta.templateTypeArgumentMismatch
                     .withArguments(numberOfTypeParameters),
-                nameToken.charOffset,
-                nameToken.length));
+                charOffset,
+                noLength));
       }
-      if (typeArgumentBuilders == null) {
-        if (aliasBuilder.typeVariables?.isEmpty ?? true) {
-          typeArgumentBuilders = [];
-        } else {
+      type = aliasBuilder.unaliasDeclaration(null,
+          isInvocation: true,
+          invocationCharOffset: nameToken.charOffset,
+          invocationFileUri: uri);
+      List<TypeBuilder> typeArgumentBuilders = [];
+      if (typeArguments != null) {
+        for (UnresolvedType unresolvedType in typeArguments) {
+          typeArgumentBuilders.add(unresolvedType?.builder);
+        }
+      } else {
+        if (aliasBuilder.typeVariables?.isNotEmpty ?? false) {
           // No type arguments provided to alias, but it is generic.
           typeArgumentBuilders = new List<TypeBuilder>.filled(
               aliasBuilder.typeVariables.length, null,
@@ -4182,7 +4225,6 @@
           }
         }
       }
-      type = aliasBuilder.unaliasDeclaration(typeArgumentBuilders);
       if (type is ClassBuilder) {
         if (typeArguments != null) {
           int numberOfTypeParameters = aliasBuilder.typeVariables?.length ?? 0;
@@ -4210,20 +4252,15 @@
                     nameToken.length,
                     suppressMessage: true));
           }
-          if (unaliasedTypeArgumentBuilders.isEmpty) {
-            forest.argumentsSetTypeArguments(arguments, []);
-          } else {
-            List<DartType> dartTypeArguments = [];
-            if (typeArguments != null) {
-              for (UnresolvedType unresolvedType in typeArguments) {
-                dartTypeArguments
-                    .add(unresolvedType.builder?.build(libraryBuilder));
-              }
-            }
-            forest.argumentsSetTypeArguments(arguments, dartTypeArguments);
+          List<DartType> dartTypeArguments = [];
+          for (TypeBuilder typeBuilder in unaliasedTypeArgumentBuilders) {
+            dartTypeArguments.add(typeBuilder.build(libraryBuilder));
           }
+          assert(forest.argumentsTypeArguments(arguments).isEmpty);
+          forest.argumentsSetTypeArguments(arguments, dartTypeArguments);
         } else {
           if (type.typeVariables?.isEmpty ?? true) {
+            assert(forest.argumentsTypeArguments(arguments).isEmpty);
             forest.argumentsSetTypeArguments(arguments, []);
           } else {
             // No type arguments provided to unaliased class, use defaults.
@@ -4234,10 +4271,17 @@
               result[i] =
                   type.typeVariables[i].defaultType?.build(type.library);
             }
+            assert(forest.argumentsTypeArguments(arguments).isEmpty);
             forest.argumentsSetTypeArguments(arguments, result);
           }
         }
       }
+    } else {
+      if (typeArguments != null && !isTypeArgumentsInForest) {
+        assert(forest.argumentsTypeArguments(arguments).isEmpty);
+        forest.argumentsSetTypeArguments(
+            arguments, buildDartTypeArguments(typeArguments));
+      }
     }
     if (type is ClassBuilder) {
       if (type is EnumBuilder) {
@@ -5780,14 +5824,17 @@
   }
 
   @override
-  UnresolvedType validateTypeUse(
-      UnresolvedType unresolved, bool nonInstanceAccessIsError) {
+  UnresolvedType validateTypeUse(UnresolvedType unresolved,
+      {bool nonInstanceAccessIsError, bool allowPotentiallyConstantType}) {
+    assert(nonInstanceAccessIsError != null);
+    assert(allowPotentiallyConstantType != null);
     TypeBuilder builder = unresolved.builder;
     if (builder is NamedTypeBuilder && builder.declaration.isTypeVariable) {
       TypeVariableBuilder typeParameterBuilder = builder.declaration;
       TypeParameter typeParameter = typeParameterBuilder.parameter;
       LocatedMessage message = _validateTypeUseIsInternal(
-          builder, unresolved.fileUri, unresolved.charOffset);
+          builder, unresolved.fileUri, unresolved.charOffset,
+          allowPotentiallyConstantType: allowPotentiallyConstantType);
       if (message == null) return unresolved;
       return new UnresolvedType(
           new NamedTypeBuilder(
@@ -5798,7 +5845,8 @@
           unresolved.fileUri);
     } else if (builder is FunctionTypeBuilder) {
       LocatedMessage message = _validateTypeUseIsInternal(
-          builder, unresolved.fileUri, unresolved.charOffset);
+          builder, unresolved.fileUri, unresolved.charOffset,
+          allowPotentiallyConstantType: allowPotentiallyConstantType);
       if (message == null) return unresolved;
       // TODO(CFE Team): This should probably be some kind of InvalidType
       // instead of null.
@@ -5809,7 +5857,9 @@
   }
 
   LocatedMessage _validateTypeUseIsInternal(
-      TypeBuilder builder, Uri fileUri, int charOffset) {
+      TypeBuilder builder, Uri fileUri, int charOffset,
+      {bool allowPotentiallyConstantType}) {
+    assert(allowPotentiallyConstantType != null);
     if (builder is NamedTypeBuilder && builder.declaration.isTypeVariable) {
       TypeVariableBuilder typeParameterBuilder = builder.declaration;
       TypeParameter typeParameter = typeParameterBuilder.parameter;
@@ -5823,7 +5873,8 @@
             builder.fileUri ?? fileUri,
             builder.charOffset ?? charOffset,
             typeParameter.name.length);
-      } else if (constantContext == ConstantContext.inferred) {
+      } else if (constantContext == ConstantContext.inferred &&
+          !allowPotentiallyConstantType) {
         message = fasta.messageTypeVariableInConstantContext
             .withLocation(fileUri, charOffset, typeParameter.name.length);
       } else {
@@ -5832,15 +5883,17 @@
       addProblem(message.messageObject, message.charOffset, message.length);
       return message;
     } else if (builder is FunctionTypeBuilder) {
-      LocatedMessage result =
-          _validateTypeUseIsInternal(builder.returnType, fileUri, charOffset);
+      LocatedMessage result = _validateTypeUseIsInternal(
+          builder.returnType, fileUri, charOffset,
+          allowPotentiallyConstantType: allowPotentiallyConstantType);
       if (result != null) {
         return result;
       }
       if (builder.formals != null) {
         for (FormalParameterBuilder formalParameterBuilder in builder.formals) {
           result = _validateTypeUseIsInternal(
-              formalParameterBuilder.type, fileUri, charOffset);
+              formalParameterBuilder.type, fileUri, charOffset,
+              allowPotentiallyConstantType: allowPotentiallyConstantType);
           if (result != null) {
             return result;
           }
@@ -6011,9 +6064,12 @@
 
   @override
   DartType buildDartType(UnresolvedType unresolvedType,
-      {bool nonInstanceAccessIsError: false}) {
+      {bool nonInstanceAccessIsError: false,
+      bool allowPotentiallyConstantType: false}) {
     if (unresolvedType == null) return null;
-    return validateTypeUse(unresolvedType, nonInstanceAccessIsError)
+    return validateTypeUse(unresolvedType,
+            nonInstanceAccessIsError: nonInstanceAccessIsError,
+            allowPotentiallyConstantType: allowPotentiallyConstantType)
         .builder
         ?.build(libraryBuilder);
   }
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 c080b03..f0afbcc 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
@@ -6,7 +6,8 @@
 
 import 'package:kernel/ast.dart' hide MapEntry;
 
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/class_hierarchy.dart'
+    show ClassHierarchy, ClassHierarchyBase;
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
@@ -17,6 +18,7 @@
 import 'package:kernel/src/legacy_erasure.dart';
 import 'package:kernel/src/nnbd_top_merge.dart';
 import 'package:kernel/src/norm.dart';
+import 'package:kernel/src/types.dart' show Types;
 
 import '../../testing/id_testing_utils.dart' show typeToText;
 
@@ -81,8 +83,6 @@
 
 import 'kernel_builder.dart' show ImplicitFieldType;
 
-import 'types.dart' show Types;
-
 const bool useConsolidated = true;
 
 const DebugLogger debug =
@@ -222,6 +222,14 @@
 
   bool get needsComputation;
   bool get isSynthesized;
+
+  // If `true` this member is not part of the interface but only part of the
+  // class members.
+  //
+  // This is `true` for instance for synthesized fields added for the late
+  // lowering.
+  bool get isInternalImplementation;
+
   bool get isInheritableConflict;
   ClassMember withParent(ClassBuilder classBuilder);
   bool get hasDeclarations;
@@ -309,7 +317,7 @@
   return aReturnType == bReturnType;
 }
 
-class ClassHierarchyBuilder {
+class ClassHierarchyBuilder implements ClassHierarchyBase {
   final Map<Class, ClassHierarchyNode> nodes = <Class, ClassHierarchyNode>{};
 
   final Map<ClassBuilder, Map<Class, Substitution>> substitutions =
@@ -340,6 +348,9 @@
 
   Types types;
 
+  Map<ClassMember, Map<ClassMember, ClassMember>> inheritanceConflictCache =
+      new Map.identity();
+
   ClassHierarchyBuilder(this.objectClassBuilder, this.loader, this.coreTypes)
       : objectClass = objectClassBuilder.cls,
         futureClass = coreTypes.futureClass,
@@ -354,6 +365,7 @@
     substitutions.clear();
     _overrideChecks.clear();
     _delayedTypeComputations.clear();
+    inheritanceConflictCache.clear();
   }
 
   void registerDelayedTypeComputation(DelayedTypeComputation computation) {
@@ -469,8 +481,8 @@
     return null;
   }
 
-  InterfaceType getKernelTypeAsInstanceOf(
-      InterfaceType type, Class superclass, Library clientLibrary) {
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
+      Library clientLibrary, CoreTypes coreTypes) {
     Class kernelClass = type.classNode;
     if (kernelClass == superclass) return type;
     if (kernelClass == nullClass) {
@@ -491,7 +503,7 @@
         .withNullability(type.nullability);
   }
 
-  List<DartType> getKernelTypeArgumentsAsInstanceOf(
+  List<DartType> getTypeArgumentsAsInstanceOf(
       InterfaceType type, Class superclass) {
     Class kernelClass = type.classNode;
     if (kernelClass == superclass) return type.typeArguments;
@@ -530,10 +542,10 @@
       ClassHierarchyNode node = nodes2[i];
       if (node == null) continue;
       if (nodes1.contains(node)) {
-        DartType candidate1 = getKernelTypeAsInstanceOf(
-            type1, node.classBuilder.cls, clientLibrary);
-        DartType candidate2 = getKernelTypeAsInstanceOf(
-            type2, node.classBuilder.cls, clientLibrary);
+        DartType candidate1 = getTypeAsInstanceOf(
+            type1, node.classBuilder.cls, clientLibrary, coreTypes);
+        DartType candidate2 = getTypeAsInstanceOf(
+            type2, node.classBuilder.cls, clientLibrary, coreTypes);
         if (candidate1 == candidate2) {
           common.add(node);
         }
@@ -549,8 +561,8 @@
     for (int i = 0; i < common.length - 1; i++) {
       ClassHierarchyNode node = common[i];
       if (node.maxInheritancePath != common[i + 1].maxInheritancePath) {
-        return getKernelTypeAsInstanceOf(
-                type1, node.classBuilder.cls, clientLibrary)
+        return getTypeAsInstanceOf(
+                type1, node.classBuilder.cls, clientLibrary, coreTypes)
             .withNullability(
                 uniteNullabilities(type1.nullability, type2.nullability));
       } else {
@@ -563,9 +575,9 @@
         uniteNullabilities(type1.nullability, type2.nullability));
   }
 
-  Member getInterfaceMemberKernel(Class cls, Name name, bool isSetter) {
+  Member getInterfaceMember(Class cls, Name name, {bool setter: false}) {
     return getNodeFromClass(cls)
-        .getInterfaceMember(name, isSetter)
+        .getInterfaceMember(name, setter)
         ?.getMember(this);
   }
 
@@ -640,12 +652,18 @@
       classBuilder.library.loader == hierarchy.loader;
 
   ClassMember checkInheritanceConflict(ClassMember a, ClassMember b) {
+    hierarchy.inheritanceConflictCache[a] ??= new Map.identity();
+    if (hierarchy.inheritanceConflictCache[a].containsKey(b)) {
+      return hierarchy.inheritanceConflictCache[a][b];
+    }
+
     if (a.hasDeclarations) {
       ClassMember result;
       for (int i = 0; i < a.declarations.length; i++) {
         ClassMember d = checkInheritanceConflict(a.declarations[i], b);
         result ??= d;
       }
+      hierarchy.inheritanceConflictCache[a][b] = result;
       return result;
     }
     if (b.hasDeclarations) {
@@ -654,12 +672,15 @@
         ClassMember d = checkInheritanceConflict(a, b.declarations[i]);
         result ??= d;
       }
+      hierarchy.inheritanceConflictCache[a][b] = result;
       return result;
     }
     if (isInheritanceConflict(a, b)) {
       reportInheritanceConflict(a, b);
+      hierarchy.inheritanceConflictCache[a][b] = a;
       return a;
     }
+    hierarchy.inheritanceConflictCache[a][b] = null;
     return null;
   }
 
@@ -731,7 +752,8 @@
             DartType overriddenBound = methodSubstitution
                 .substituteType(overriddenTypeParameters[i].bound);
             if (!hierarchy.types
-                .isSameTypeKernel(declaredBound, overriddenBound)
+                .performNullabilityAwareMutualSubtypesCheck(
+                    declaredBound, overriddenBound)
                 .isSubtypeWhenUsingNullabilities()) {
               debug?.log("Giving up 3");
               continue;
@@ -1949,7 +1971,9 @@
               return result;
             } else {
               if (isNameVisibleIn(interfaceMember.name, classBuilder.library)) {
-                recordAbstractMember(interfaceMember);
+                if (!interfaceMember.isInternalImplementation) {
+                  recordAbstractMember(interfaceMember);
+                }
               }
               if (interfaceMember.isInheritableConflict) {
                 interfaceMember = interfaceMember.withParent(classBuilder);
@@ -2552,13 +2576,14 @@
   @override
   InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
       Library clientLibrary, CoreTypes coreTypes) {
-    return hierarchy.getKernelTypeAsInstanceOf(type, superclass, clientLibrary);
+    return hierarchy.getTypeAsInstanceOf(
+        type, superclass, clientLibrary, coreTypes);
   }
 
   @override
   List<DartType> getTypeArgumentsAsInstanceOf(
       InterfaceType type, Class superclass) {
-    return hierarchy.getKernelTypeArgumentsAsInstanceOf(type, superclass);
+    return hierarchy.getTypeArgumentsAsInstanceOf(type, superclass);
   }
 
   @override
@@ -2570,7 +2595,7 @@
   @override
   bool isSubtypeOf(
       DartType subtype, DartType supertype, SubtypeCheckMode mode) {
-    return hierarchy.types.isSubtypeOfKernel(subtype, supertype, mode);
+    return hierarchy.types.isSubtypeOf(subtype, supertype, mode);
   }
 
   @override
@@ -2676,6 +2701,9 @@
   bool get isSynthesized => true;
 
   @override
+  bool get isInternalImplementation => false;
+
+  @override
   bool get forSetter => isSetter;
 
   @override
@@ -2840,12 +2868,13 @@
     assert(concreteImplementation.isProperty == other.isProperty,
         "Unexpected member combination: $concreteImplementation vs $other");
     List<ClassMember> declarations = <ClassMember>[];
-    if (concreteImplementation.hasDeclarations) {
+    if (concreteImplementation.hasDeclarations &&
+        concreteImplementation.classBuilder == parent) {
       addAllDeclarationsTo(concreteImplementation, declarations);
     } else {
       declarations.add(concreteImplementation);
     }
-    if (other.hasDeclarations) {
+    if (other.hasDeclarations && other.classBuilder == parent) {
       addAllDeclarationsTo(other, declarations);
     } else {
       addDeclarationIfDifferent(other, declarations);
@@ -2932,8 +2961,11 @@
       unhandled("${member.runtimeType}", "$member", classBuilder.charOffset,
           classBuilder.fileUri);
     }
-    InterfaceType instance = hierarchy.getKernelTypeAsInstanceOf(
-        thisType, member.enclosingClass, classBuilder.library.library);
+    InterfaceType instance = hierarchy.getTypeAsInstanceOf(
+        thisType,
+        member.enclosingClass,
+        classBuilder.library.library,
+        hierarchy.coreTypes);
     assert(
         instance != null,
         "No instance of $thisType as ${member.enclosingClass} found for "
@@ -2944,10 +2976,10 @@
   bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
     if (isSetter) {
       return hierarchy.types
-          .isSubtypeOfKernel(b, a, SubtypeCheckMode.withNullabilities);
+          .isSubtypeOf(b, a, SubtypeCheckMode.withNullabilities);
     } else {
       return hierarchy.types
-          .isSubtypeOfKernel(a, b, SubtypeCheckMode.withNullabilities);
+          .isSubtypeOf(a, b, SubtypeCheckMode.withNullabilities);
     }
   }
 
@@ -3113,12 +3145,12 @@
     assert(a.isProperty == b.isProperty,
         "Unexpected member combination: $a vs $b");
     List<ClassMember> declarations = <ClassMember>[];
-    if (a.hasDeclarations) {
+    if (a.hasDeclarations && a.classBuilder == parent) {
       addAllDeclarationsTo(a, declarations);
     } else {
       declarations.add(a);
     }
-    if (b.hasDeclarations) {
+    if (b.hasDeclarations && b.classBuilder == parent) {
       addAllDeclarationsTo(b, declarations);
     } else {
       addDeclarationIfDifferent(b, declarations);
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 742cd7e..38e392f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2122,7 +2122,7 @@
             ..fileOffset = node.fileOffset
             ..flags = node.flags);
     }
-    if (constant is NullConstant) {
+    if (constant is NullConstant && !node.isForNonNullableByDefault) {
       DartType nodeType = node.type;
       return makeBoolConstant(nodeType == typeEnvironment.nullType ||
           nodeType is InterfaceType &&
@@ -2232,27 +2232,28 @@
 
   bool isSubtype(Constant constant, DartType type) {
     DartType constantType = constant.getType(_staticTypeContext);
-    if (targetingJavaScript) {
+    bool result = typeEnvironment.isSubtypeOf(
+        constantType, type, SubtypeCheckMode.withNullabilities);
+    if (targetingJavaScript && !result) {
       if (constantType is InterfaceType &&
-          constantType.classNode == typeEnvironment.coreTypes.intClass &&
-          type is InterfaceType &&
-          type.classNode == typeEnvironment.coreTypes.doubleClass) {
+          constantType.classNode == typeEnvironment.coreTypes.intClass) {
         // With JS semantics, an integer is also a double.
-        return true;
-      }
-
-      if (constantType is InterfaceType &&
-          constantType.classNode == typeEnvironment.coreTypes.doubleClass &&
-          type is InterfaceType &&
-          type.classNode == typeEnvironment.coreTypes.intClass) {
-        double value = (constant as DoubleConstant).value;
-        if (value.isFinite && value == value.truncateToDouble()) {
-          return true;
-        }
+        result = typeEnvironment.isSubtypeOf(
+            new InterfaceType(typeEnvironment.coreTypes.doubleClass,
+                constantType.nullability, const <DartType>[]),
+            type,
+            SubtypeCheckMode.withNullabilities);
+      } else if (intFolder.isInt(constant)) {
+        // With JS semantics, an integer valued double is also an int.
+        result = typeEnvironment.isSubtypeOf(
+            new InterfaceType(typeEnvironment.coreTypes.intClass,
+                constantType.nullability, const <DartType>[]),
+            type,
+            SubtypeCheckMode.withNullabilities);
       }
     }
-    return typeEnvironment.isSubtypeOf(
-        constantType, type, SubtypeCheckMode.withNullabilities);
+
+    return result;
   }
 
   Constant ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
@@ -2367,7 +2368,7 @@
           return report(
               node, templateConstEvalZeroDivisor.withArguments(op, '$a'));
         }
-        return intFolder.truncatingDivide(a, b);
+        return intFolder.truncatingDivide(node, a, b);
       case '%':
         return new DoubleConstant(a % b);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
index 9bd4a18..337d61e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
@@ -10,7 +10,10 @@
 import 'constant_evaluator.dart';
 
 import '../fasta_codes.dart'
-    show templateConstEvalNegativeShift, templateConstEvalZeroDivisor;
+    show
+        templateConstEvalNegativeShift,
+        templateConstEvalTruncateError,
+        templateConstEvalZeroDivisor;
 
 abstract class ConstantIntFolder {
   final ConstantEvaluator evaluator;
@@ -36,7 +39,7 @@
   Constant foldBinaryOperator(MethodInvocation node, String op,
       covariant Constant left, covariant Constant right);
 
-  Constant truncatingDivide(num left, num right);
+  Constant truncatingDivide(MethodInvocation node, num left, num right);
 
   void _checkOperands(MethodInvocation node, String op, num left, num right) {
     if ((op == '<<' || op == '>>' || op == '>>>') && right < 0) {
@@ -120,8 +123,13 @@
   }
 
   @override
-  Constant truncatingDivide(num left, num right) {
-    return new IntConstant(left ~/ right);
+  Constant truncatingDivide(MethodInvocation node, num left, num right) {
+    try {
+      return new IntConstant(left ~/ right);
+    } catch (e) {
+      return evaluator.report(node,
+          templateConstEvalTruncateError.withArguments('$left', '$right'));
+    }
   }
 }
 
@@ -184,7 +192,7 @@
       case '/':
         return new DoubleConstant(a / b);
       case '~/':
-        return truncatingDivide(a, b);
+        return truncatingDivide(node, a, b);
       case '%':
         return new DoubleConstant(a % b);
       case '|':
@@ -220,8 +228,13 @@
   }
 
   @override
-  Constant truncatingDivide(num left, num right) {
-    double result = (left / right).truncateToDouble();
+  Constant truncatingDivide(MethodInvocation node, num left, num right) {
+    double division = (left / right);
+    if (division.isNaN || division.isInfinite) {
+      return evaluator.report(node,
+          templateConstEvalTruncateError.withArguments('$left', '${right}'));
+    }
+    double result = division.truncateToDouble();
     return new DoubleConstant(result == 0.0 ? 0.0 : result);
   }
 }
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 19bcd1f..b392aab 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -211,7 +211,9 @@
   }
 
   /// Returns an expression, generator or initializer for an invocation of this
-  /// subexpression with [arguments] at [offset].
+  /// subexpression with [typeArguments] and [arguments] at [offset]. Callers
+  /// must pass `isInForest: true` iff [typeArguments] have already been added
+  /// to [forest].
   ///
   /// For instance:
   /// * If this is a [PropertyAccessGenerator] for `a.b`, this will create
@@ -224,7 +226,8 @@
   /// If the invocation has explicit type arguments
   /// [buildTypeWithResolvedArguments] called instead.
   /* Expression | Generator | Initializer */ doInvocation(
-      int offset, Arguments arguments);
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false});
 
   /* Expression | Generator */ buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
@@ -405,7 +408,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.forest.createExpressionInvocation(
         adjustForImplicitCall(_plainNameForRead, offset),
         buildSimpleRead(),
@@ -464,7 +469,9 @@
   String get _plainNameForRead => name.name;
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.buildMethodInvocation(receiver, name, arguments, offset);
   }
 
@@ -685,7 +692,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.buildMethodInvocation(
         _forest.createThisExpression(fileOffset), name, arguments, offset);
   }
@@ -787,7 +796,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return unsupported("doInvocation", offset, _uri);
   }
 
@@ -891,7 +902,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     if (_helper.constantContext != ConstantContext.none) {
       // TODO(brianwilkerson) Fix the length
       _helper.addProblem(messageNotAConstantExpression, offset, 1);
@@ -1061,7 +1074,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.forest.createExpressionInvocation(
         arguments.fileOffset, buildSimpleRead(), arguments);
   }
@@ -1162,7 +1177,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.forest
         .createExpressionInvocation(offset, buildSimpleRead(), arguments);
   }
@@ -1261,7 +1278,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.forest
         .createExpressionInvocation(offset, buildSimpleRead(), arguments);
   }
@@ -1426,7 +1445,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     if (_helper.constantContext != ConstantContext.none &&
         !_helper.isIdentical(readTarget)) {
       return _helper.buildProblem(
@@ -1695,7 +1716,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     if (invokeTarget != null) {
       return _helper.buildExtensionMethodInvocation(
           offset,
@@ -2103,7 +2126,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     VariableDeclaration receiverVariable;
     Expression receiverExpression = receiver;
     if (isNullAware) {
@@ -2425,7 +2450,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.forest
         .createExpressionInvocation(offset, buildSimpleRead(), arguments);
   }
@@ -2564,7 +2591,9 @@
     Generator generator =
         _createInstanceAccess(send.token, send.name, isNullAware: isNullAware);
     if (send.arguments != null) {
-      return generator.doInvocation(offsetForToken(send.token), send.arguments);
+      return generator.doInvocation(
+          offsetForToken(send.token), send.typeArguments, send.arguments,
+          isTypeArgumentsInForest: send.isTypeArgumentsInForest);
     } else {
       return generator;
     }
@@ -2574,8 +2603,8 @@
   buildBinaryOperation(Token token, Name binaryName, Expression right) {
     int fileOffset = offsetForToken(token);
     Generator generator = _createInstanceAccess(token, binaryName);
-    return generator.doInvocation(
-        fileOffset, _forest.createArguments(fileOffset, <Expression>[right]));
+    return generator.doInvocation(fileOffset, null,
+        _forest.createArguments(fileOffset, <Expression>[right]));
   }
 
   @override
@@ -2583,13 +2612,16 @@
     int fileOffset = offsetForToken(token);
     Generator generator = _createInstanceAccess(token, unaryName);
     return generator.doInvocation(
-        fileOffset, _forest.createArgumentsEmpty(fileOffset));
+        fileOffset, null, _forest.createArgumentsEmpty(fileOffset));
   }
 
   @override
-  doInvocation(int offset, Arguments arguments) {
+  doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     Generator generator = _createInstanceAccess(token, callName);
-    return generator.doInvocation(offset, arguments);
+    return generator.doInvocation(offset, typeArguments, arguments,
+        isTypeArgumentsInForest: isTypeArgumentsInForest);
   }
 
   @override
@@ -2696,7 +2728,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     if (_forest.argumentsPositional(arguments).length > 0 ||
         _forest.argumentsNamed(arguments).length > 0) {
       _helper.addProblemErrorIfConst(
@@ -2833,8 +2867,12 @@
   }
 
   @override
-  doInvocation(int offset, Arguments arguments) {
-    Object suffix = suffixGenerator.doInvocation(offset, arguments);
+  doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
+    Object suffix = suffixGenerator.doInvocation(
+        offset, typeArguments, arguments,
+        isTypeArgumentsInForest: isTypeArgumentsInForest);
     if (suffix is Expression) {
       return _helper.wrapInDeferredCheck(
           suffix, prefixGenerator.prefix, fileOffset);
@@ -2947,8 +2985,13 @@
     if (arguments != null) {
       argumentBuilders = new List<TypeBuilder>(arguments.length);
       for (int i = 0; i < argumentBuilders.length; i++) {
-        argumentBuilders[i] =
-            _helper.validateTypeUse(arguments[i], false).builder;
+        argumentBuilders[i] = _helper
+            .validateTypeUse(arguments[i],
+                nonInstanceAccessIsError: false,
+                allowPotentiallyConstantType:
+                    _helper.libraryBuilder.isNonNullableByDefault &&
+                        _helper.inIsOrAsOperatorType)
+            .builder;
       }
     }
     return new NamedTypeBuilder(
@@ -3040,9 +3083,10 @@
               send.token,
               arguments,
               name.name,
-              null,
+              send.typeArguments,
               token.charOffset,
-              Constness.implicit);
+              Constness.implicit,
+              isTypeArgumentsInForest: send.isTypeArgumentsInForest);
         }
       } else if (member is AmbiguousBuilder) {
         return _helper.buildProblem(
@@ -3076,14 +3120,18 @@
 
       return arguments == null
           ? generator
-          : generator.doInvocation(offsetForToken(send.token), arguments);
+          : generator.doInvocation(
+              offsetForToken(send.token), send.typeArguments, arguments,
+              isTypeArgumentsInForest: send.isTypeArgumentsInForest);
     } else {
       return super.buildPropertyAccess(send, operatorOffset, isNullAware);
     }
   }
 
   @override
-  doInvocation(int offset, Arguments arguments) {
+  doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     if (declaration.isExtension) {
       ExtensionBuilder extensionBuilder = declaration;
       if (arguments.positional.length != 1 || arguments.named.isNotEmpty) {
@@ -3107,7 +3155,8 @@
           arguments.positional.single, explicitTypeArguments);
     } else {
       return _helper.buildConstructorInvocation(declaration, token, token,
-          arguments, "", null, token.charOffset, Constness.implicit);
+          arguments, "", typeArguments, token.charOffset, Constness.implicit,
+          isTypeArgumentsInForest: isTypeArgumentsInForest);
     }
   }
 }
@@ -3237,7 +3286,9 @@
   }
 
   @override
-  doInvocation(int offset, Arguments arguments) {
+  doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.forest.createExpressionInvocation(
         adjustForImplicitCall(targetName, offset), _createRead(), arguments);
   }
@@ -3290,7 +3341,9 @@
   }
 
   @override
-  doInvocation(int offset, Arguments arguments) {
+  doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return buildError(arguments, offset: offset);
   }
 
@@ -3405,7 +3458,9 @@
   String get _debugName => "UnresolvedNameGenerator";
 
   @override
-  Expression doInvocation(int charOffset, Arguments arguments) {
+  Expression doInvocation(
+      int charOffset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return buildError(arguments, offset: charOffset);
   }
 
@@ -3477,7 +3532,9 @@
   }
 
   @override
-  Expression doInvocation(int charOffset, Arguments arguments) {
+  Expression doInvocation(
+      int charOffset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return unhandled("${runtimeType}", "doInvocation", charOffset, _uri);
   }
 
@@ -3721,7 +3778,8 @@
 
   @override
   /* Expression | Generator | Initializer */ doInvocation(
-      int offset, Arguments arguments) {
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.wrapInLocatedProblem(
         _helper.evaluateArgumentsBefore(
             arguments, _forest.createNullLiteral(fileOffset)),
@@ -3737,7 +3795,9 @@
           "'${send.name.name}' != ${send.token.lexeme}");
       Object result = qualifiedLookup(send.token);
       if (send is SendAccessGenerator) {
-        result = _helper.finishSend(result, send.arguments, fileOffset);
+        result = _helper.finishSend(
+            result, send.typeArguments, send.arguments, fileOffset,
+            isTypeArgumentsInForest: send.isTypeArgumentsInForest);
       }
       if (isNullAware) {
         result = _helper.wrapInLocatedProblem(
@@ -3823,7 +3883,9 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return _helper.throwNoSuchMethodError(_forest.createNullLiteral(offset),
         _plainNameForRead, arguments, fileOffset);
   }
@@ -3923,7 +3985,9 @@
     return <Initializer>[_helper.buildInvalidInitializer(buildProblem())];
   }
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return buildProblem();
   }
 
@@ -4112,7 +4176,9 @@
     }
   }
 
-  doInvocation(int offset, Arguments arguments) {
+  doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     if (isInitializer) {
       return buildConstructorInitializer(offset, new Name(""), arguments);
     } else if (isSuper) {
@@ -4274,6 +4340,10 @@
 
   withReceiver(Object receiver, int operatorOffset, {bool isNullAware});
 
+  List<UnresolvedType> get typeArguments => null;
+
+  bool get isTypeArgumentsInForest => true;
+
   Arguments get arguments => null;
 }
 
@@ -4303,7 +4373,10 @@
   }
 
   @override
-  doInvocation(int offset, Arguments arguments) => this;
+  doInvocation(
+          int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+          {bool isTypeArgumentsInForest = false}) =>
+      this;
 
   @override
   Expression buildSimpleRead() {
@@ -4324,13 +4397,19 @@
   final Name name;
 
   @override
+  final List<UnresolvedType> typeArguments;
+
+  @override
+  final bool isTypeArgumentsInForest;
+
+  @override
   final Arguments arguments;
 
   final bool isPotentiallyConstant;
 
-  SendAccessGenerator(
-      ExpressionGeneratorHelper helper, Token token, this.name, this.arguments,
-      {this.isPotentiallyConstant: false})
+  SendAccessGenerator(ExpressionGeneratorHelper helper, Token token, this.name,
+      this.typeArguments, this.arguments,
+      {this.isPotentiallyConstant = false, this.isTypeArgumentsInForest = true})
       : super(helper, token) {
     assert(arguments != null);
   }
@@ -4379,7 +4458,9 @@
     return unsupported("buildPostfixIncrement", offset ?? fileOffset, _uri);
   }
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return unsupported("doInvocation", offset, _uri);
   }
 
@@ -4455,7 +4536,9 @@
     return unsupported("buildPostfixIncrement", offset ?? fileOffset, _uri);
   }
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  Expression doInvocation(
+      int offset, List<UnresolvedType> typeArguments, Arguments arguments,
+      {bool isTypeArgumentsInForest = false}) {
     return unsupported("doInvocation", offset, _uri);
   }
 
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 1d4799e..1666a65 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
@@ -57,10 +57,15 @@
 
   Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
 
+  /// `true` if we are in the type of an as expression.
+  bool get inIsOrAsOperatorType;
+
   scopeLookup(Scope scope, String name, Token token,
       {bool isQualified: false, PrefixBuilder prefix});
 
-  finishSend(Object receiver, Arguments arguments, int offset);
+  finishSend(Object receiver, List<UnresolvedType> typeArguments,
+      Arguments arguments, int offset,
+      {bool isTypeArgumentsInForest = false});
 
   Initializer buildInvalidInitializer(Expression expression, [int offset]);
 
@@ -114,10 +119,11 @@
       String name,
       List<UnresolvedType> typeArguments,
       int charOffset,
-      Constness constness);
+      Constness constness,
+      {bool isTypeArgumentsInForest = false});
 
-  UnresolvedType validateTypeUse(
-      UnresolvedType unresolved, bool nonInstanceAccessIsError);
+  UnresolvedType validateTypeUse(UnresolvedType unresolved,
+      {bool nonInstanceAccessIsError, bool allowPotentiallyConstantType});
 
   void addProblemErrorIfConst(Message message, int charOffset, int length);
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 66897dc..734b8b4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -346,8 +346,15 @@
         parameterIndex < interfaceTypeParameters.length;
         parameterIndex++) {
       TypeParameter typeParameter = interfaceTypeParameters[parameterIndex];
-      bool isGenericCovariantImpl = typeParameter.isGenericCovariantImpl ||
-          needsCheck(typeParameter.bound);
+      DartType parameterBound =
+          substitution.substituteType(typeParameter.bound);
+      DartType bound = initialType(_combinedMemberIndex, parameterBound);
+      DartType parameterDefaultType =
+          substitution.substituteType(typeParameter.defaultType);
+      DartType defaultType =
+          initialType(_combinedMemberIndex, parameterDefaultType);
+      bool isGenericCovariantImpl =
+          typeParameter.isGenericCovariantImpl || needsCheck(parameterBound);
       TypeParameter superTypeParameter = typeParameter;
       for (int candidateIndex = 0;
           candidateIndex < _candidates.length;
@@ -374,6 +381,14 @@
               true;
         }
       }
+      if (bound != null && bound != parameterBound) {
+        createStubIfNeeded(forMemberSignature: true);
+        stub.function.typeParameters[parameterIndex].bound = bound;
+      }
+      if (defaultType != null && defaultType != parameterDefaultType) {
+        createStubIfNeeded(forMemberSignature: true);
+        stub.function.typeParameters[parameterIndex].defaultType = defaultType;
+      }
     }
     DartType returnType =
         substitution.substituteType(getReturnType(interfaceMember));
@@ -486,6 +501,8 @@
       for (int i = 0; i < typeParameters.length; i++) {
         typeParameters[i].bound =
             substitution.substituteType(targetTypeParameters[i].bound);
+        typeParameters[i].defaultType =
+            substitution.substituteType(targetTypeParameters[i].defaultType);
       }
     }
     List<VariableDeclaration> positionalParameters =
@@ -537,11 +554,12 @@
   Substitution _substitutionFor(
       List<TypeParameter> stubTypeParameters, Member candidate, Class class_) {
     Substitution substitution = Substitution.fromInterfaceType(
-        hierarchy.getKernelTypeAsInstanceOf(
+        hierarchy.getTypeAsInstanceOf(
             hierarchy.coreTypes
                 .thisInterfaceType(class_, class_.enclosingLibrary.nonNullable),
             candidate.enclosingClass,
-            class_.enclosingLibrary));
+            class_.enclosingLibrary,
+            hierarchy.coreTypes));
     if (stubTypeParameters != null) {
       // If the stub is generic ensure that type parameters are alpha renamed
       // to the [stubTypeParameters].
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 c237248..b174679 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5,13 +5,9 @@
 import 'dart:core' hide MapEntry;
 
 import 'package:_fe_analyzer_shared/src/util/link.dart';
-
 import 'package:kernel/ast.dart';
-
 import 'package:kernel/src/future_or.dart';
-
 import 'package:kernel/type_algebra.dart' show Substitution;
-
 import 'package:kernel/type_environment.dart';
 
 import '../../base/instrumentation.dart'
@@ -19,24 +15,14 @@
         InstrumentationValueForMember,
         InstrumentationValueForType,
         InstrumentationValueForTypeArgs;
-
 import '../fasta_codes.dart';
-
 import '../names.dart';
-
 import '../problems.dart' show unhandled;
-
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
 import '../type_inference/type_inference_engine.dart';
 import '../type_inference/type_inferrer.dart';
-
 import '../type_inference/type_schema.dart' show UnknownType;
-
-import '../type_inference/type_schema_elimination.dart' show greatestClosure;
-
 import 'body_builder.dart' show combineStatements;
-
 import 'collections.dart'
     show
         ForElement,
@@ -48,11 +34,8 @@
         SpreadElement,
         SpreadMapEntry,
         convertToElement;
-
 import 'implicit_type_argument.dart' show ImplicitTypeArgument;
-
 import 'internal_ast.dart';
-
 import 'late_lowering.dart' as late_lowering;
 
 class InferenceVisitor
@@ -1247,7 +1230,19 @@
 
   @override
   StatementInferenceResult visitLabeledStatement(LabeledStatement node) {
+    bool isSimpleBody = node.body is Block ||
+        node.body is IfStatement ||
+        node.body is TryStatement;
+    if (isSimpleBody) {
+      inferrer.flowAnalysis.labeledStatement_begin(node);
+    }
+
     StatementInferenceResult bodyResult = inferrer.inferStatement(node.body);
+
+    if (isSimpleBody) {
+      inferrer.flowAnalysis.labeledStatement_end();
+    }
+
     if (bodyResult.hasChanged) {
       node.body = bodyResult.statement..parent = node;
     }
@@ -2814,7 +2809,8 @@
   ExpressionInferenceResult visitSuperIndexSet(
       SuperIndexSet node, DartType typeContext) {
     ObjectAccessTarget indexSetTarget = node.setter != null
-        ? new ObjectAccessTarget.interfaceMember(node.setter)
+        ? new ObjectAccessTarget.interfaceMember(node.setter,
+            isPotentiallyNullable: false)
         : const ObjectAccessTarget.missing();
 
     DartType indexType =
@@ -3111,7 +3107,8 @@
   ExpressionInferenceResult visitIfNullSuperIndexSet(
       IfNullSuperIndexSet node, DartType typeContext) {
     ObjectAccessTarget readTarget = node.getter != null
-        ? new ObjectAccessTarget.interfaceMember(node.getter)
+        ? new ObjectAccessTarget.interfaceMember(node.getter,
+            isPotentiallyNullable: false)
         : const ObjectAccessTarget.missing();
 
     DartType readType = inferrer.getReturnType(readTarget, inferrer.thisType);
@@ -3125,7 +3122,8 @@
         .member;
 
     ObjectAccessTarget writeTarget = node.setter != null
-        ? new ObjectAccessTarget.interfaceMember(node.setter)
+        ? new ObjectAccessTarget.interfaceMember(node.setter,
+            isPotentiallyNullable: false)
         : const ObjectAccessTarget.missing();
 
     DartType writeIndexType =
@@ -3428,7 +3426,6 @@
     ExpressionInferenceResult rightResult = inferrer.inferExpression(
         right, const UnknownType(), typeNeeded,
         isVoidAllowed: false);
-    right = rightResult.expression;
 
     assert(equalsTarget.isInstanceMember);
     if (inferrer.instrumentation != null && leftType == const DynamicType()) {
@@ -3438,6 +3435,11 @@
           'target',
           new InstrumentationValueForMember(equalsTarget.member));
     }
+    DartType rightType =
+        inferrer.getPositionalParameterTypeForTarget(equalsTarget, leftType, 0);
+    right = inferrer.ensureAssignableResult(
+        rightType.withNullability(inferrer.library.nullable), rightResult,
+        errorTemplate: templateArgumentTypeNotAssignable);
 
     Expression equals = new MethodInvocation(
         left,
@@ -3513,6 +3515,7 @@
             extensionAccessCandidates: binaryTarget.candidates);
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         assert(binaryTarget.extensionMethodKind != ProcedureKind.Setter);
         binary = new StaticInvocation(
             binaryTarget.member,
@@ -3524,9 +3527,11 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
       case ObjectAccessTargetKind.invalid:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
         if (binaryTarget.isInstanceMember &&
@@ -3566,19 +3571,15 @@
         }
         break;
     }
-    if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
-      if (leftType is! InvalidType &&
-          leftType is! DynamicType &&
-          isPotentiallyNullable(leftType, inferrer.coreTypes.futureOrClass)) {
-        return new ExpressionInferenceResult(
-            binaryType,
-            inferrer.helper.wrapInProblem(
-                binary,
-                templateNullableOperatorCallError.withArguments(
-                    binaryName.name, leftType, inferrer.isNonNullableByDefault),
-                binary.fileOffset,
-                binaryName.name.length));
-      }
+    if (!inferrer.isTopLevel && binaryTarget.isNullable) {
+      return new ExpressionInferenceResult(
+          binaryType,
+          inferrer.helper.wrapInProblem(
+              binary,
+              templateNullableOperatorCallError.withArguments(
+                  binaryName.name, leftType, inferrer.isNonNullableByDefault),
+              binary.fileOffset,
+              binaryName.name.length));
     }
     return new ExpressionInferenceResult(binaryType, binary);
   }
@@ -3612,6 +3613,7 @@
             extensionAccessCandidates: unaryTarget.candidates);
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         assert(unaryTarget.extensionMethodKind != ProcedureKind.Setter);
         unary = new StaticInvocation(
             unaryTarget.member,
@@ -3622,9 +3624,11 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
       case ObjectAccessTargetKind.invalid:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
         if (unaryTarget.isInstanceMember &&
@@ -3660,22 +3664,17 @@
         }
         break;
     }
-    if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
-      if (expressionType is! InvalidType &&
-          expressionType is! DynamicType &&
-          isPotentiallyNullable(
-              expressionType, inferrer.coreTypes.futureOrClass)) {
-        // TODO(johnniwinther): Special case 'unary-' in messages. It should
-        // probably be referred to as "Unary operator '-' ...".
-        return new ExpressionInferenceResult(
-            unaryType,
-            inferrer.helper.wrapInProblem(
-                unary,
-                templateNullableOperatorCallError.withArguments(unaryName.name,
-                    expressionType, inferrer.isNonNullableByDefault),
-                unary.fileOffset,
-                unaryName == unaryMinusName ? 1 : unaryName.name.length));
-      }
+    if (!inferrer.isTopLevel && unaryTarget.isNullable) {
+      // TODO(johnniwinther): Special case 'unary-' in messages. It should
+      // probably be referred to as "Unary operator '-' ...".
+      return new ExpressionInferenceResult(
+          unaryType,
+          inferrer.helper.wrapInProblem(
+              unary,
+              templateNullableOperatorCallError.withArguments(unaryName.name,
+                  expressionType, inferrer.isNonNullableByDefault),
+              unary.fileOffset,
+              unaryName == unaryMinusName ? 1 : unaryName.name.length));
     }
     return new ExpressionInferenceResult(unaryType, unary);
   }
@@ -3706,6 +3705,7 @@
             extensionAccessCandidates: readTarget.candidates);
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         read = new StaticInvocation(
             readTarget.member,
             new Arguments(<Expression>[
@@ -3716,9 +3716,11 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
       case ObjectAccessTargetKind.invalid:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
         read = new MethodInvocation(
@@ -3746,22 +3748,15 @@
         }
         break;
     }
-    if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
-      if (receiverType is! DynamicType &&
-          receiverType is! InvalidType &&
-          isPotentiallyNullable(
-              receiverType, inferrer.coreTypes.futureOrClass)) {
-        return new ExpressionInferenceResult(
-            readType,
-            inferrer.helper.wrapInProblem(
-                read,
-                templateNullableOperatorCallError.withArguments(
-                    indexGetName.name,
-                    receiverType,
-                    inferrer.isNonNullableByDefault),
-                read.fileOffset,
-                noLength));
-      }
+    if (!inferrer.isTopLevel && readTarget.isNullable) {
+      return new ExpressionInferenceResult(
+          readType,
+          inferrer.helper.wrapInProblem(
+              read,
+              templateNullableOperatorCallError.withArguments(indexGetName.name,
+                  receiverType, inferrer.isNonNullableByDefault),
+              read.fileOffset,
+              noLength));
     }
     return new ExpressionInferenceResult(readType, read);
   }
@@ -3794,6 +3789,7 @@
             extensionAccessCandidates: writeTarget.candidates);
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         assert(writeTarget.extensionMethodKind != ProcedureKind.Setter);
         write = new StaticInvocation(
             writeTarget.member,
@@ -3803,9 +3799,11 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
       case ObjectAccessTargetKind.invalid:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
         write = new MethodInvocation(
@@ -3816,18 +3814,13 @@
           ..fileOffset = fileOffset;
         break;
     }
-    if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
-      if (receiverType is! InvalidType &&
-          receiverType is! DynamicType &&
-          isPotentiallyNullable(
-              receiverType, inferrer.coreTypes.futureOrClass)) {
-        return inferrer.helper.wrapInProblem(
-            write,
-            templateNullableOperatorCallError.withArguments(indexSetName.name,
-                receiverType, inferrer.isNonNullableByDefault),
-            write.fileOffset,
-            noLength);
-      }
+    if (!inferrer.isTopLevel && writeTarget.isNullable) {
+      return inferrer.helper.wrapInProblem(
+          write,
+          templateNullableOperatorCallError.withArguments(
+              indexSetName.name, receiverType, inferrer.isNonNullableByDefault),
+          write.fileOffset,
+          noLength);
     }
     return write;
   }
@@ -3856,6 +3849,7 @@
     DartType readType = inferrer.getGetterType(readTarget, receiverType);
 
     Expression read;
+    ExpressionInferenceResult readResult;
     switch (readTarget.kind) {
       case ObjectAccessTargetKind.missing:
         read = inferrer.createMissingPropertyGet(
@@ -3867,6 +3861,7 @@
             extensionAccessCandidates: readTarget.candidates);
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (readTarget.extensionMethodKind) {
           case ProcedureKind.Getter:
             read = new StaticInvocation(
@@ -3885,7 +3880,9 @@
                 ], types: readTarget.inferredExtensionTypeArguments)
                   ..fileOffset = fileOffset)
               ..fileOffset = fileOffset;
-            return inferrer.instantiateTearOff(readType, typeContext, read);
+            readResult =
+                inferrer.instantiateTearOff(readType, typeContext, read);
+            break;
           case ProcedureKind.Setter:
           case ProcedureKind.Factory:
           case ProcedureKind.Operator:
@@ -3894,9 +3891,11 @@
         }
         break;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
       case ObjectAccessTargetKind.invalid:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
         if (readTarget.isInstanceMember &&
@@ -3940,30 +3939,20 @@
         }
         Member member = readTarget.member;
         if (member is Procedure && member.kind == ProcedureKind.Method) {
-          return inferrer.instantiateTearOff(readType, typeContext, read);
+          readResult = inferrer.instantiateTearOff(readType, typeContext, read);
         }
         break;
     }
-    if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
-      if (receiverType is! DynamicType &&
-          receiverType is! InvalidType &&
-          isPotentiallyNullable(
-              receiverType, inferrer.coreTypes.futureOrClass) &&
-          !inferrer.matchesObjectMemberCall(
-              propertyName, const [], const [], const [])) {
-        return new ExpressionInferenceResult(
-            readType,
-            inferrer.helper.wrapInProblem(
-                read,
-                templateNullablePropertyAccessError.withArguments(
-                    propertyName.name,
-                    receiverType,
-                    inferrer.isNonNullableByDefault),
-                read.fileOffset,
-                propertyName.name.length));
-      }
+    readResult ??= new ExpressionInferenceResult(readType, read);
+    if (!inferrer.isTopLevel && readTarget.isNullable) {
+      readResult = inferrer.wrapExpressionInferenceResultInProblem(
+          readResult,
+          templateNullablePropertyAccessError.withArguments(
+              propertyName.name, receiverType, inferrer.isNonNullableByDefault),
+          read.fileOffset,
+          propertyName.name.length);
     }
-    return new ExpressionInferenceResult(readType, read);
+    return readResult;
   }
 
   /// Creates a property set operation of [writeTarget] on [receiver] using
@@ -4003,6 +3992,7 @@
             extensionAccessCandidates: writeTarget.candidates);
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         if (forEffect) {
           write = new StaticInvocation(
               writeTarget.member,
@@ -4027,9 +4017,11 @@
         }
         break;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
       case ObjectAccessTargetKind.invalid:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
         write =
@@ -4037,17 +4029,13 @@
               ..fileOffset = fileOffset;
         break;
     }
-    if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
-      if (receiverType is! DynamicType &&
-          isPotentiallyNullable(
-              receiverType, inferrer.coreTypes.futureOrClass)) {
-        return inferrer.helper.wrapInProblem(
-            write,
-            templateNullablePropertyAccessError.withArguments(propertyName.name,
-                receiverType, inferrer.isNonNullableByDefault),
-            write.fileOffset,
-            propertyName.name.length);
-      }
+    if (!inferrer.isTopLevel && writeTarget.isNullable) {
+      return inferrer.helper.wrapInProblem(
+          write,
+          templateNullablePropertyAccessError.withArguments(
+              propertyName.name, receiverType, inferrer.isNonNullableByDefault),
+          write.fileOffset,
+          propertyName.name.length);
     }
 
     return write;
@@ -4343,7 +4331,8 @@
   ExpressionInferenceResult visitCompoundSuperIndexSet(
       CompoundSuperIndexSet node, DartType typeContext) {
     ObjectAccessTarget readTarget = node.getter != null
-        ? new ObjectAccessTarget.interfaceMember(node.getter)
+        ? new ObjectAccessTarget.interfaceMember(node.getter,
+            isPotentiallyNullable: false)
         : const ObjectAccessTarget.missing();
 
     DartType readType = inferrer.getReturnType(readTarget, inferrer.thisType);
@@ -4395,7 +4384,8 @@
     DartType binaryType = binaryResult.inferredType;
 
     ObjectAccessTarget writeTarget = node.setter != null
-        ? new ObjectAccessTarget.interfaceMember(node.setter)
+        ? new ObjectAccessTarget.interfaceMember(node.setter,
+            isPotentiallyNullable: false)
         : const ObjectAccessTarget.missing();
 
     DartType writeIndexType =
@@ -5097,7 +5087,8 @@
         node,
         typeContext,
         node.interfaceTarget != null
-            ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget)
+            ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget,
+                isPotentiallyNullable: false)
             : const ObjectAccessTarget.unresolved());
   }
 
@@ -5115,7 +5106,8 @@
         node,
         typeContext,
         node.interfaceTarget != null
-            ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget)
+            ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget,
+                isPotentiallyNullable: false)
             : const ObjectAccessTarget.unresolved());
   }
 
@@ -5262,8 +5254,7 @@
     if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
       if (!inferrer.isAssignable(
           inferrer.typeSchemaEnvironment.objectNonNullableRawType,
-          expressionResult.inferredType,
-          isStrongNullabilityMode: true)) {
+          expressionResult.inferredType)) {
         return new ExpressionInferenceResult(
             const DynamicType(),
             inferrer.helper.buildProblem(
@@ -5600,7 +5591,8 @@
     if (!inferrer.isTopLevel) {
       bool isUnassigned = !inferrer.flowAnalysis.isAssigned(variable);
       if (isUnassigned) {
-        inferrer.dataForTesting?.flowAnalysisResult?.unassignedNodes?.add(node);
+        inferrer.dataForTesting?.flowAnalysisResult?.potentiallyUnassignedNodes
+            ?.add(node);
       }
       bool isDefinitelyUnassigned =
           inferrer.flowAnalysis.isUnassigned(variable);
@@ -5876,7 +5868,7 @@
 
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(variableSet.variable.type, inferrer.bottomType),
+        inferrer.computeGreatestClosure(variableSet.variable.type),
         rhsType,
         variableSet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
@@ -5936,7 +5928,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(_writeType, inferrer.bottomType), rhsType, _rhs,
+        inferrer.computeGreatestClosure(_writeType), rhsType, _rhs,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
         isVoidAllowed: true);
 
@@ -5970,7 +5962,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(_writeType, inferrer.bottomType),
+        inferrer.computeGreatestClosure(_writeType),
         rhsType,
         superPropertySet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
@@ -5995,7 +5987,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(staticSet.target.setterType, inferrer.bottomType),
+        inferrer.computeGreatestClosure(staticSet.target.setterType),
         rhsType,
         staticSet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
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 7b2b43a..fa7ea0c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -26,6 +26,7 @@
         Library,
         Name,
         NamedExpression,
+        NonNullableByDefaultCompiledMode,
         NullLiteral,
         Procedure,
         RedirectingInitializer,
@@ -395,11 +396,29 @@
         AmbiguousBuilder problem = declaration;
         declaration = problem.getFirstDeclaration();
       }
+      NonNullableByDefaultCompiledMode compiledMode = null;
+      if (enableNonNullable) {
+        switch (loader.nnbdMode) {
+          case NnbdMode.Weak:
+            compiledMode = NonNullableByDefaultCompiledMode.Weak;
+            break;
+          case NnbdMode.Strong:
+            compiledMode = NonNullableByDefaultCompiledMode.Strong;
+            break;
+          case NnbdMode.Agnostic:
+            compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
+            break;
+        }
+      } else {
+        compiledMode = NonNullableByDefaultCompiledMode.Disabled;
+      }
       if (declaration is ProcedureBuilder) {
-        component.mainMethod = declaration.actualProcedure;
+        component.setMainMethodAndMode(
+            declaration.actualProcedure?.reference, true, compiledMode);
       } else if (declaration is DillMemberBuilder) {
         if (declaration.member is Procedure) {
-          component.mainMethod = declaration.member;
+          component.setMainMethodAndMode(
+              declaration.member?.reference, true, compiledMode);
         }
       }
     }
@@ -1054,7 +1073,8 @@
         loader.coreTypes,
         loader.libraries,
         new KernelDiagnosticReporter(loader),
-        logger: (String msg) => ticker.logMs(msg));
+        logger: (String msg) => ticker.logMs(msg),
+        changedStructureNotifier: changedStructureNotifier);
 
     TypeEnvironment environment =
         new TypeEnvironment(loader.coreTypes, loader.hierarchy);
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 30af5bc..643e2e0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -59,8 +59,8 @@
 // variables.  For that case if the type has its declaration set to null and its
 // name matches that of the variable, it's interpreted as an occurrence of a
 // type variable.
-int computeVariance(TypeVariableBuilder variable, TypeBuilder type,
-    LibraryBuilder libraryBuilder) {
+int computeTypeVariableBuilderVariance(TypeVariableBuilder variable,
+    TypeBuilder type, LibraryBuilder libraryBuilder) {
   if (type is NamedTypeBuilder) {
     assert(type.declaration != null);
     TypeDeclarationBuilder declaration = type.declaration;
@@ -79,7 +79,7 @@
                 result,
                 Variance.combine(
                     declaration.cls.typeParameters[i].variance,
-                    computeVariance(
+                    computeTypeVariableBuilderVariance(
                         variable, type.arguments[i], libraryBuilder)));
           }
         }
@@ -97,7 +97,7 @@
               TypeVariableBuilder declarationTypeVariable =
                   declaration.typeVariables[i];
               declarationTypeVariable.variance = visitMarker;
-              int computedVariance = computeVariance(
+              int computedVariance = computeTypeVariableBuilderVariance(
                   declarationTypeVariable, declaration.type, libraryBuilder);
               declarationTypeVariableVariance =
                   declarationTypeVariable.variance = computedVariance;
@@ -120,7 +120,7 @@
             result = Variance.meet(
                 result,
                 Variance.combine(
-                    computeVariance(
+                    computeTypeVariableBuilderVariance(
                         variable, type.arguments[i], libraryBuilder),
                     declarationTypeVariableVariance));
           }
@@ -132,7 +132,9 @@
     int result = Variance.unrelated;
     if (type.returnType != null) {
       result = Variance.meet(
-          result, computeVariance(variable, type.returnType, libraryBuilder));
+          result,
+          computeTypeVariableBuilderVariance(
+              variable, type.returnType, libraryBuilder));
     }
     if (type.typeVariables != null) {
       for (TypeVariableBuilder typeVariable in type.typeVariables) {
@@ -141,7 +143,8 @@
         // of [computeVariance] below is made to simply figure out if [variable]
         // occurs in the bound.
         if (typeVariable.bound != null &&
-            computeVariance(variable, typeVariable.bound, libraryBuilder) !=
+            computeTypeVariableBuilderVariance(
+                    variable, typeVariable.bound, libraryBuilder) !=
                 Variance.unrelated) {
           result = Variance.invariant;
         }
@@ -151,8 +154,10 @@
       for (FormalParameterBuilder formal in type.formals) {
         result = Variance.meet(
             result,
-            Variance.combine(Variance.contravariant,
-                computeVariance(variable, formal.type, libraryBuilder)));
+            Variance.combine(
+                Variance.contravariant,
+                computeTypeVariableBuilderVariance(
+                    variable, formal.type, libraryBuilder)));
       }
     }
     return result;
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 69f2b57..6d3b442 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -255,6 +255,12 @@
       }
       result.add(">");
     }
+    if (classNode.name == 'Null' &&
+        classNode.enclosingLibrary.importUri.scheme == 'dart' &&
+        classNode.enclosingLibrary.importUri.path == 'core') {
+      // Don't print nullability on `Null`.
+      return;
+    }
     addNullability(node.nullability);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
deleted file mode 100644
index 8b87689..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/types.dart
+++ /dev/null
@@ -1,966 +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.
-
-library fasta.types;
-
-import 'package:kernel/ast.dart'
-    show
-        BottomType,
-        Class,
-        DartType,
-        DynamicType,
-        FunctionType,
-        InterfaceType,
-        InvalidType,
-        Library,
-        NamedType,
-        NeverType,
-        Nullability,
-        TypeParameter,
-        TypeParameterType,
-        TypedefType,
-        Variance,
-        VoidType;
-
-import 'package:kernel/core_types.dart';
-
-import 'package:kernel/type_algebra.dart'
-    show Substitution, combineNullabilitiesForSubstitution;
-
-import 'package:kernel/type_environment.dart';
-
-import 'package:kernel/src/future_or.dart';
-
-import 'kernel_builder.dart' show ClassHierarchyBuilder;
-
-class Types implements SubtypeTester {
-  final ClassHierarchyBuilder hierarchy;
-
-  Types(this.hierarchy);
-
-  /// Returns true if [s] is a subtype of [t].
-  bool isSubtypeOfKernel(DartType s, DartType t, SubtypeCheckMode mode) {
-    IsSubtypeOf result = performNullabilityAwareSubtypeCheck(s, t);
-    switch (mode) {
-      case SubtypeCheckMode.withNullabilities:
-        return result.isSubtypeWhenUsingNullabilities();
-      case SubtypeCheckMode.ignoringNullabilities:
-        return result.isSubtypeWhenIgnoringNullabilities();
-      default:
-        throw new StateError("Unhandled subtype checking mode '$mode'");
-    }
-  }
-
-  @override
-  IsSubtypeOf performNullabilityAwareSubtypeCheck(DartType s, DartType t) {
-    if (s is BottomType) {
-      return const IsSubtypeOf.always(); // Rule 3.
-    }
-    if (t is DynamicType) {
-      return const IsSubtypeOf.always(); // Rule 2.
-    }
-    if (t is VoidType) {
-      return const IsSubtypeOf.always(); // Rule 2.
-    }
-    if (t is BottomType) {
-      return const IsSubtypeOf.never();
-    }
-    if (s is NeverType) {
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          s, t, hierarchy.futureOrClass);
-    }
-
-    // TODO(dmitryas): Remove InvalidType from subtype relation.
-    if (s is InvalidType) {
-      // InvalidType is a bottom type.
-      return const IsSubtypeOf.always();
-    }
-    if (t is InvalidType) {
-      return const IsSubtypeOf.never();
-    }
-
-    if (t is InterfaceType) {
-      Class cls = t.classNode;
-      if (cls == hierarchy.objectClass &&
-          !(s is InterfaceType && s.classNode == hierarchy.futureOrClass)) {
-        return new IsSubtypeOf.basedSolelyOnNullabilities(
-            s, t, hierarchy.futureOrClass);
-      }
-      if (cls == hierarchy.futureOrClass) {
-        const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
-        if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
-        } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
-        } else if (s is InterfaceType) {
-          return s.classNode == hierarchy.futureOrClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
-        } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
-        } else if (s is TypeParameterType) {
-          return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
-        } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
-        }
-      } else {
-        const IsInterfaceSubtypeOf relation = const IsInterfaceSubtypeOf();
-        if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
-        } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
-        } else if (s is InterfaceType) {
-          return s.classNode == hierarchy.futureOrClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
-        } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
-        } else if (s is TypeParameterType) {
-          return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
-        } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
-        }
-      }
-    } else if (t is FunctionType) {
-      const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
-      if (s is DynamicType) {
-        return relation.isDynamicRelated(s, t, this);
-      } else if (s is VoidType) {
-        return relation.isVoidRelated(s, t, this);
-      } else if (s is InterfaceType) {
-        return s.classNode == hierarchy.futureOrClass
-            ? relation.isFutureOrRelated(s, t, this)
-            : relation.isInterfaceRelated(s, t, this);
-      } else if (s is FunctionType) {
-        return relation.isFunctionRelated(s, t, this);
-      } else if (s is TypeParameterType) {
-        return s.promotedBound == null
-            ? relation.isTypeParameterRelated(s, t, this)
-            : relation.isIntersectionRelated(s, t, this);
-      } else if (s is TypedefType) {
-        return relation.isTypedefRelated(s, t, this);
-      }
-    } else if (t is TypeParameterType) {
-      if (t.promotedBound == null) {
-        const IsTypeParameterSubtypeOf relation =
-            const IsTypeParameterSubtypeOf();
-        if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
-        } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
-        } else if (s is InterfaceType) {
-          return s.classNode == hierarchy.futureOrClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
-        } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
-        } else if (s is TypeParameterType) {
-          return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
-        } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
-        }
-      } else {
-        const IsIntersectionSubtypeOf relation =
-            const IsIntersectionSubtypeOf();
-        if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
-        } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
-        } else if (s is InterfaceType) {
-          return s.classNode == hierarchy.futureOrClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
-        } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
-        } else if (s is TypeParameterType) {
-          return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
-        } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
-        }
-      }
-    } else if (t is TypedefType) {
-      const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
-      if (s is DynamicType) {
-        return relation.isDynamicRelated(s, t, this);
-      } else if (s is VoidType) {
-        return relation.isVoidRelated(s, t, this);
-      } else if (s is InterfaceType) {
-        return s.classNode == hierarchy.futureOrClass
-            ? relation.isFutureOrRelated(s, t, this)
-            : relation.isInterfaceRelated(s, t, this);
-      } else if (s is FunctionType) {
-        return relation.isFunctionRelated(s, t, this);
-      } else if (s is TypeParameterType) {
-        return s.promotedBound == null
-            ? relation.isTypeParameterRelated(s, t, this)
-            : relation.isIntersectionRelated(s, t, this);
-      } else if (s is TypedefType) {
-        return relation.isTypedefRelated(s, t, this);
-      }
-    } else if (t is NeverType) {
-      const IsNeverTypeSubtypeOf relation = const IsNeverTypeSubtypeOf();
-      if (s is DynamicType) {
-        return relation.isDynamicRelated(s, t, this);
-      } else if (s is VoidType) {
-        return relation.isVoidRelated(s, t, this);
-      } else if (s is InterfaceType) {
-        return relation.isInterfaceRelated(s, t, this);
-      } else if (s is FunctionType) {
-        return relation.isFunctionRelated(s, t, this);
-      } else if (s is TypeParameterType) {
-        return s.promotedBound == null
-            ? relation.isTypeParameterRelated(s, t, this)
-            : relation.isIntersectionRelated(s, t, this);
-      } else if (s is TypedefType) {
-        return relation.isTypedefRelated(s, t, this);
-      }
-    } else {
-      throw "Unhandled type: ${t.runtimeType}";
-    }
-    throw "Unhandled type combination: ${t.runtimeType} ${s.runtimeType}";
-  }
-
-  /// Returns true if all type arguments in [s] and [t] pairwise are subtypes
-  /// with respect to the variance of the corresponding [p] type parameter.
-  IsSubtypeOf areTypeArgumentsOfSubtypeKernel(
-      List<DartType> s, List<DartType> t, List<TypeParameter> p) {
-    if (s.length != t.length || s.length != p.length) {
-      throw "Numbers of type arguments don't match $s $t with parameters $p.";
-    }
-    IsSubtypeOf result = const IsSubtypeOf.always();
-    for (int i = 0; i < s.length; i++) {
-      int variance = p[i].variance;
-      if (variance == Variance.contravariant) {
-        result = result.and(performNullabilityAwareSubtypeCheck(t[i], s[i]));
-        if (!result.isSubtypeWhenIgnoringNullabilities()) {
-          return const IsSubtypeOf.never();
-        }
-      } else if (variance == Variance.invariant) {
-        result = result.and(isSameTypeKernel(s[i], t[i]));
-        if (!result.isSubtypeWhenIgnoringNullabilities()) {
-          return const IsSubtypeOf.never();
-        }
-      } else {
-        result = result.and(performNullabilityAwareSubtypeCheck(s[i], t[i]));
-        if (!result.isSubtypeWhenIgnoringNullabilities()) {
-          return const IsSubtypeOf.never();
-        }
-      }
-    }
-    return result;
-  }
-
-  IsSubtypeOf isSameTypeKernel(DartType s, DartType t) {
-    return performNullabilityAwareSubtypeCheck(s, t)
-        .andSubtypeCheckFor(t, s, this);
-  }
-
-  @override
-  bool isSubtypeOf(
-      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
-    return isSubtypeOfKernel(subtype, supertype, mode);
-  }
-
-  @override
-  Class get futureOrClass => hierarchy.coreTypes.futureOrClass;
-
-  @override
-  Class get functionClass => hierarchy.coreTypes.functionClass;
-
-  @override
-  InterfaceType get functionLegacyRawType =>
-      hierarchy.coreTypes.functionLegacyRawType;
-
-  @override
-  InterfaceType futureType(DartType type, Nullability nullability) {
-    return new InterfaceType(
-        hierarchy.coreTypes.futureClass, nullability, <DartType>[type]);
-  }
-
-  @override
-  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
-      Library clientLibrary, CoreTypes coreTypes) {
-    return hierarchy.getKernelTypeAsInstanceOf(type, superclass, clientLibrary);
-  }
-
-  @override
-  List<DartType> getTypeArgumentsAsInstanceOf(
-      InterfaceType type, Class superclass) {
-    return hierarchy.getKernelTypeArgumentsAsInstanceOf(type, superclass);
-  }
-
-  @override
-  bool isTop(DartType type) {
-    return type is DynamicType ||
-        type is VoidType ||
-        type == objectLegacyRawType ||
-        type == objectNullableRawType;
-  }
-
-  @override
-  InterfaceType get nullType => hierarchy.coreTypes.nullType;
-
-  @override
-  Class get objectClass => hierarchy.coreTypes.objectClass;
-
-  @override
-  InterfaceType get objectLegacyRawType {
-    return hierarchy.coreTypes.objectLegacyRawType;
-  }
-
-  @override
-  InterfaceType get objectNullableRawType {
-    return hierarchy.coreTypes.objectNullableRawType;
-  }
-
-  @override
-  IsSubtypeOf performNullabilityAwareMutualSubtypesCheck(
-      DartType type1, DartType type2) {
-    return isSameTypeKernel(type1, type2);
-  }
-}
-
-abstract class TypeRelation<T extends DartType> {
-  const TypeRelation();
-
-  IsSubtypeOf isDynamicRelated(DynamicType s, T t, Types types);
-
-  IsSubtypeOf isVoidRelated(VoidType s, T t, Types types);
-
-  IsSubtypeOf isInterfaceRelated(InterfaceType s, T t, Types types);
-
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, T t, Types types);
-
-  IsSubtypeOf isFunctionRelated(FunctionType s, T t, Types types);
-
-  IsSubtypeOf isFutureOrRelated(InterfaceType futureOr, T t, Types types);
-
-  IsSubtypeOf isTypeParameterRelated(TypeParameterType s, T t, Types types);
-
-  IsSubtypeOf isTypedefRelated(TypedefType s, T t, Types types);
-}
-
-class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
-  const IsInterfaceSubtypeOf();
-
-  @override
-  IsSubtypeOf isInterfaceRelated(
-      InterfaceType s, InterfaceType t, Types types) {
-    if (s.classNode == types.hierarchy.nullClass) {
-      // This is an optimization, to avoid instantiating unnecessary type
-      // arguments in getKernelTypeAsInstanceOf.
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          s, t, types.futureOrClass);
-    }
-    List<DartType> asSupertypeArguments =
-        types.hierarchy.getKernelTypeArgumentsAsInstanceOf(s, t.classNode);
-    if (asSupertypeArguments == null) {
-      return const IsSubtypeOf.never();
-    }
-    return types
-        .areTypeArgumentsOfSubtypeKernel(
-            asSupertypeArguments, t.typeArguments, t.classNode.typeParameters)
-        .and(new IsSubtypeOf.basedSolelyOnNullabilities(
-            s, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, InterfaceType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s.parameter.bound, t).and(
-        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType futureOr, InterfaceType t, Types types) {
-    List<DartType> arguments = futureOr.typeArguments;
-    // Rules 7.1 and 7.2.
-    return types
-        .performNullabilityAwareSubtypeCheck(arguments.single, t)
-        .andSubtypeCheckFor(
-            new InterfaceType(types.hierarchy.futureClass,
-                Nullability.nonNullable, arguments),
-            t,
-            types)
-        .and(new IsSubtypeOf.basedSolelyOnNullabilities(
-            futureOr, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, InterfaceType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(
-        intersection.promotedBound, t); // Rule 12.
-  }
-
-  @override
-  IsSubtypeOf isDynamicRelated(DynamicType s, InterfaceType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isFunctionRelated(FunctionType s, InterfaceType t, Types types) {
-    return t.classNode == types.hierarchy.functionClass
-        ? new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass)
-        : const IsSubtypeOf.never(); // Rule 14.
-  }
-
-  @override
-  IsSubtypeOf isTypedefRelated(TypedefType s, InterfaceType t, Types types) {
-    // Rule 5.
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, t).and(
-        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isVoidRelated(VoidType s, InterfaceType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-}
-
-class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
-  const IsFunctionSubtypeOf();
-
-  @override
-  IsSubtypeOf isFunctionRelated(FunctionType s, FunctionType t, Types types) {
-    List<TypeParameter> sTypeVariables = s.typeParameters;
-    List<TypeParameter> tTypeVariables = t.typeParameters;
-    if (sTypeVariables.length != tTypeVariables.length) {
-      return const IsSubtypeOf.never();
-    }
-    IsSubtypeOf result = const IsSubtypeOf.always();
-    if (sTypeVariables.isNotEmpty) {
-      // If the function types have type variables, we alpha-rename the type
-      // variables of [s] to use those of [t].
-
-      // As an optimization, we first check if the bounds of the type variables
-      // of the two types on the same positions are mutual subtypes without
-      // alpha-renaming them.
-      List<DartType> typeVariableSubstitution = <DartType>[];
-      for (int i = 0; i < sTypeVariables.length; i++) {
-        TypeParameter sTypeVariable = sTypeVariables[i];
-        TypeParameter tTypeVariable = tTypeVariables[i];
-        result = result.and(
-            types.isSameTypeKernel(sTypeVariable.bound, tTypeVariable.bound));
-        typeVariableSubstitution.add(new TypeParameterType.forAlphaRenaming(
-            sTypeVariable, tTypeVariable));
-      }
-      Substitution substitution =
-          Substitution.fromPairs(sTypeVariables, typeVariableSubstitution);
-      // If the bounds aren't the same, we need to try again after computing the
-      // substitution of type variables.
-      if (!result.isSubtypeWhenIgnoringNullabilities()) {
-        result = const IsSubtypeOf.always();
-        for (int i = 0; i < sTypeVariables.length; i++) {
-          TypeParameter sTypeVariable = sTypeVariables[i];
-          TypeParameter tTypeVariable = tTypeVariables[i];
-          result = result.and(types.isSameTypeKernel(
-              substitution.substituteType(sTypeVariable.bound),
-              tTypeVariable.bound));
-          if (!result.isSubtypeWhenIgnoringNullabilities()) {
-            return const IsSubtypeOf.never();
-          }
-        }
-      }
-      s = substitution.substituteType(s.withoutTypeParameters);
-    }
-    result = result.and(
-        types.performNullabilityAwareSubtypeCheck(s.returnType, t.returnType));
-    if (!result.isSubtypeWhenIgnoringNullabilities()) {
-      return const IsSubtypeOf.never();
-    }
-    List<DartType> sPositional = s.positionalParameters;
-    List<DartType> tPositional = t.positionalParameters;
-    if (s.requiredParameterCount > t.requiredParameterCount) {
-      // Rule 15, n1 <= n2.
-      return const IsSubtypeOf.never();
-    }
-    if (sPositional.length < tPositional.length) {
-      // Rule 15, n1 + k1 >= n2 + k2.
-      return const IsSubtypeOf.never();
-    }
-    for (int i = 0; i < tPositional.length; i++) {
-      result = result.and(types.performNullabilityAwareSubtypeCheck(
-          tPositional[i], sPositional[i]));
-      if (!result.isSubtypeWhenIgnoringNullabilities()) {
-        // Rule 15, Tj <: Sj.
-        return const IsSubtypeOf.never();
-      }
-    }
-    List<NamedType> sNamed = s.namedParameters;
-    List<NamedType> tNamed = t.namedParameters;
-    if (sNamed.isNotEmpty || tNamed.isNotEmpty) {
-      // Rule 16, the number of positional parameters must be the same.
-      if (sPositional.length != tPositional.length) {
-        return const IsSubtypeOf.never();
-      }
-      if (s.requiredParameterCount != t.requiredParameterCount) {
-        return const IsSubtypeOf.never();
-      }
-
-      // Rule 16, the parameter names of [t] must be a subset of those of
-      // [s]. Also, for the intersection, the type of the parameter of [t] must
-      // be a subtype of the type of the parameter of [s].
-      int sCount = 0;
-      for (int tCount = 0; tCount < tNamed.length; tCount++) {
-        String name = tNamed[tCount].name;
-        for (; sCount < sNamed.length; sCount++) {
-          if (sNamed[sCount].name == name) break;
-        }
-        if (sCount == sNamed.length) return const IsSubtypeOf.never();
-        result = result.and(types.performNullabilityAwareSubtypeCheck(
-            tNamed[tCount].type, sNamed[sCount].type));
-        if (!result.isSubtypeWhenIgnoringNullabilities()) {
-          return const IsSubtypeOf.never();
-        }
-      }
-    }
-    return result.and(
-        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isInterfaceRelated(InterfaceType s, FunctionType t, Types types) {
-    if (s.classNode == types.hierarchy.nullClass) {
-      // Rule 4.
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          s, t, types.futureOrClass);
-    }
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isDynamicRelated(DynamicType s, FunctionType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType futureOr, FunctionType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, FunctionType t, Types types) {
-    // Rule 12.
-    return types.performNullabilityAwareSubtypeCheck(
-        intersection.promotedBound, t);
-  }
-
-  @override
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, FunctionType t, Types types) {
-    // Rule 13.
-    return types.performNullabilityAwareSubtypeCheck(s.parameter.bound, t).and(
-        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isTypedefRelated(TypedefType s, FunctionType t, Types types) {
-    // Rule 5.
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
-  }
-
-  @override
-  IsSubtypeOf isVoidRelated(VoidType s, FunctionType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-}
-
-class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
-  const IsTypeParameterSubtypeOf();
-
-  @override
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, TypeParameterType t, Types types) {
-    IsSubtypeOf result = const IsSubtypeOf.always();
-    if (s.parameter != t.parameter) {
-      result = types.performNullabilityAwareSubtypeCheck(s.bound, t);
-    }
-    if (s.nullability == Nullability.undetermined &&
-        t.nullability == Nullability.undetermined) {
-      // The two nullabilities are undetermined, but are connected via
-      // additional constraint, namely that they will be equal at run time.
-      return result;
-    }
-    return result.and(
-        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, TypeParameterType t, Types types) {
-    // Nullable types aren't promoted to intersection types.
-    // TODO(dmitryas): Uncomment the following when the inference is updated.
-    //assert(intersection.typeParameterTypeNullability != Nullability.nullable);
-
-    // Rule 8.
-    if (intersection.parameter == t.parameter) {
-      if (intersection.nullability == Nullability.undetermined &&
-          t.nullability == Nullability.undetermined) {
-        // The two nullabilities are undetermined, but are connected via
-        // additional constraint, namely that they will be equal at run time.
-        return const IsSubtypeOf.always();
-      }
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          intersection, t, types.futureOrClass);
-    }
-
-    // Rule 12.
-    return types.performNullabilityAwareSubtypeCheck(
-        intersection.promotedBound.withNullability(intersection.nullability),
-        t);
-  }
-
-  @override
-  IsSubtypeOf isInterfaceRelated(
-      InterfaceType s, TypeParameterType t, Types types) {
-    if (s.classNode == types.hierarchy.nullClass) {
-      // Rule 4.
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          s, t, types.futureOrClass);
-    }
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isDynamicRelated(
-      DynamicType s, TypeParameterType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isFunctionRelated(
-      FunctionType s, TypeParameterType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType futureOr, TypeParameterType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isTypedefRelated(
-      TypedefType s, TypeParameterType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
-  }
-
-  @override
-  IsSubtypeOf isVoidRelated(VoidType s, TypeParameterType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-}
-
-class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
-  const IsTypedefSubtypeOf();
-
-  @override
-  IsSubtypeOf isInterfaceRelated(InterfaceType s, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isDynamicRelated(DynamicType s, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isFunctionRelated(FunctionType s, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType futureOr, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(futureOr, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(intersection, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isTypedefRelated(TypedefType s, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, t.unalias);
-  }
-
-  @override
-  IsSubtypeOf isVoidRelated(VoidType s, TypedefType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
-  }
-}
-
-class IsFutureOrSubtypeOf extends TypeRelation<InterfaceType> {
-  const IsFutureOrSubtypeOf();
-
-  @override
-  IsSubtypeOf isInterfaceRelated(
-      InterfaceType s, InterfaceType futureOr, Types types) {
-    List<DartType> arguments = futureOr.typeArguments;
-
-    Nullability unitedNullability =
-        computeNullabilityOfFutureOr(futureOr, types.hierarchy.futureOrClass);
-
-    return types
-        // Rule 11.
-        .performNullabilityAwareSubtypeCheck(
-            s, arguments.single.withNullability(unitedNullability))
-        // Rule 10.
-        .orSubtypeCheckFor(
-            s,
-            new InterfaceType(
-                types.hierarchy.futureClass, unitedNullability, arguments),
-            types);
-  }
-
-  @override
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType sFutureOr, InterfaceType tFutureOr, Types types) {
-    // This follows from combining rules 7, 10, and 11.
-    DartType sArgument = sFutureOr.typeArguments.single;
-    DartType tArgument = tFutureOr.typeArguments.single;
-    DartType sFutureOfArgument = new InterfaceType(types.hierarchy.futureClass,
-        Nullability.nonNullable, sFutureOr.typeArguments);
-    DartType tFutureOfArgument = new InterfaceType(types.hierarchy.futureClass,
-        Nullability.nonNullable, tFutureOr.typeArguments);
-    Nullability sNullability =
-        computeNullabilityOfFutureOr(sFutureOr, types.hierarchy.futureOrClass);
-    Nullability tNullability =
-        computeNullabilityOfFutureOr(tFutureOr, types.hierarchy.futureOrClass);
-    // The following is an optimized is-subtype-of test for the case where
-    // both LHS and RHS are FutureOrs.  It's based on the following:
-    // FutureOr<X> <: FutureOr<Y> iff X <: Y OR (X <: Future<Y> AND
-    // Future<X> <: Y).
-    //
-    // The correctness of that can be shown as follows:
-    //   1. FutureOr<X> <: Y iff X <: Y AND Future<X> <: Y
-    //   2. X <: FutureOr<Y> iff X <: Y OR X <: Future<Y>
-    //   3. 1,2 => FutureOr<X> <: FutureOr<Y> iff
-    //          (X <: Y OR X <: Future<Y>) AND
-    //            (Future<X> <: Y OR Future<X> <: Future<Y>)
-    //   4. X <: Y iff Future<X> <: Future<Y>
-    //   5. 3,4 => FutureOr<X> <: FutureOr<Y> iff
-    //          (X <: Y OR X <: Future<Y>) AND
-    //            (X <: Y OR Future<X> <: Y) iff
-    //          X <: Y OR (X <: Future<Y> AND Future<X> <: Y)
-    return types
-        .performNullabilityAwareSubtypeCheck(sArgument, tArgument)
-        .or(types
-            .performNullabilityAwareSubtypeCheck(sArgument, tFutureOfArgument)
-            .andSubtypeCheckFor(sFutureOfArgument, tArgument, types))
-        .and(new IsSubtypeOf.basedSolelyOnNullabilities(
-            sFutureOr.withNullability(sNullability),
-            tFutureOr.withNullability(tNullability),
-            types.futureOrClass));
-  }
-
-  @override
-  IsSubtypeOf isDynamicRelated(
-      DynamicType s, InterfaceType futureOr, Types types) {
-    // Rule 11.
-    DartType argument = futureOr.typeArguments.single;
-    return types.performNullabilityAwareSubtypeCheck(
-        s,
-        argument.withNullability(computeNullabilityOfFutureOr(
-            futureOr, types.hierarchy.futureOrClass)));
-  }
-
-  @override
-  IsSubtypeOf isVoidRelated(VoidType s, InterfaceType futureOr, Types types) {
-    // Rule 11.
-    DartType argument = futureOr.typeArguments.single;
-    return types.performNullabilityAwareSubtypeCheck(
-        s,
-        argument.withNullability(computeNullabilityOfFutureOr(
-            futureOr, types.hierarchy.futureOrClass)));
-  }
-
-  @override
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, InterfaceType futureOr, Types types) {
-    List<DartType> arguments = futureOr.typeArguments;
-    Nullability unitedNullability =
-        computeNullabilityOfFutureOr(futureOr, types.hierarchy.futureOrClass);
-    // TODO(dmitryas): Revise the original optimization.
-    return types
-        // Rule 11.
-        .performNullabilityAwareSubtypeCheck(
-            s, arguments.single.withNullability(unitedNullability))
-        // Rule 13.
-        .orSubtypeCheckFor(
-            s.parameter.bound.withNullability(
-                combineNullabilitiesForSubstitution(
-                    s.parameter.bound.nullability, s.nullability)),
-            futureOr,
-            types)
-        // Rule 10.
-        .orSubtypeCheckFor(
-            s,
-            new InterfaceType(
-                types.hierarchy.futureClass, unitedNullability, arguments),
-            types);
-  }
-
-  @override
-  IsSubtypeOf isFunctionRelated(
-      FunctionType s, InterfaceType futureOr, Types types) {
-    // Rule 11.
-    DartType argument = futureOr.typeArguments.single;
-    return types.performNullabilityAwareSubtypeCheck(
-        s,
-        argument.withNullability(computeNullabilityOfFutureOr(
-            futureOr, types.hierarchy.futureOrClass)));
-  }
-
-  @override
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, InterfaceType futureOr, Types types) {
-    return isTypeParameterRelated(intersection, futureOr, types) // Rule 8.
-        .orSubtypeCheckFor(
-            intersection.promotedBound, futureOr, types); // Rule 12.
-  }
-
-  @override
-  IsSubtypeOf isTypedefRelated(
-      TypedefType s, InterfaceType futureOr, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, futureOr);
-  }
-}
-
-class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
-  const IsIntersectionSubtypeOf();
-
-  @override
-  IsSubtypeOf isIntersectionRelated(TypeParameterType sIntersection,
-      TypeParameterType tIntersection, Types types) {
-    // Rule 9.
-    return const IsTypeParameterSubtypeOf()
-        .isIntersectionRelated(sIntersection, tIntersection, types)
-        .andSubtypeCheckFor(sIntersection, tIntersection.promotedBound, types);
-  }
-
-  @override
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, TypeParameterType intersection, Types types) {
-    // Rule 9.
-    return const IsTypeParameterSubtypeOf()
-        .isTypeParameterRelated(s, intersection, types)
-        .andSubtypeCheckFor(s, intersection.promotedBound, types);
-  }
-
-  @override
-  IsSubtypeOf isInterfaceRelated(
-      InterfaceType s, TypeParameterType intersection, Types types) {
-    if (s.classNode == types.hierarchy.nullClass) {
-      // Rule 4.
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          s, intersection, types.futureOrClass);
-    }
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isDynamicRelated(
-      DynamicType s, TypeParameterType intersection, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isFunctionRelated(
-      FunctionType s, TypeParameterType intersection, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType futureOr, TypeParameterType intersection, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  @override
-  IsSubtypeOf isTypedefRelated(
-      TypedefType s, TypeParameterType intersection, Types types) {
-    // Rule 5.
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, intersection);
-  }
-
-  @override
-  IsSubtypeOf isVoidRelated(
-      VoidType s, TypeParameterType intersection, Types types) {
-    return const IsSubtypeOf.never();
-  }
-}
-
-class IsNeverTypeSubtypeOf implements TypeRelation<NeverType> {
-  const IsNeverTypeSubtypeOf();
-
-  IsSubtypeOf isDynamicRelated(DynamicType s, NeverType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  IsSubtypeOf isVoidRelated(VoidType s, NeverType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  IsSubtypeOf isInterfaceRelated(InterfaceType s, NeverType t, Types types) {
-    if (s.classNode == types.hierarchy.nullClass) {
-      if (t.nullability == Nullability.nullable ||
-          t.nullability == Nullability.legacy) {
-        return const IsSubtypeOf.always();
-      }
-      if (t.nullability == Nullability.nonNullable) {
-        return const IsSubtypeOf.never();
-      }
-      throw new StateError(
-          "Unexpected nullability '$t.nullability' of type Never");
-    }
-    return const IsSubtypeOf.never();
-  }
-
-  IsSubtypeOf isIntersectionRelated(
-      TypeParameterType intersection, NeverType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(
-        intersection.promotedBound, t);
-  }
-
-  IsSubtypeOf isFunctionRelated(FunctionType s, NeverType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  IsSubtypeOf isFutureOrRelated(
-      InterfaceType futureOr, NeverType t, Types types) {
-    return const IsSubtypeOf.never();
-  }
-
-  IsSubtypeOf isTypeParameterRelated(
-      TypeParameterType s, NeverType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s.bound, t).and(
-        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
-  }
-
-  IsSubtypeOf isTypedefRelated(TypedefType s, NeverType t, Types types) {
-    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 97a844a..ee062fb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -76,8 +76,10 @@
   Library realLibrary = procedure.enclosingLibrary;
 
   Library fakeLibrary = new Library(new Uri(scheme: 'evaluate', path: 'source'))
-    ..setLanguageVersion(
-        realLibrary.languageVersionMajor, realLibrary.languageVersionMinor);
+    ..setLanguageVersion(realLibrary.languageVersion)
+    ..isNonNullableByDefault = realLibrary.isNonNullableByDefault
+    ..nonNullableByDefaultCompiledMode =
+        realLibrary.nonNullableByDefaultCompiledMode;
 
   if (procedure.parent is Class) {
     Class realClass = procedure.parent;
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index 0ab9f32..a7de26a 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -10,7 +10,7 @@
 
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Class, DartType, Library;
+import 'package:kernel/ast.dart' show Class, DartType, Library, Version;
 import 'package:package_config/package_config.dart';
 
 import 'scope.dart';
@@ -145,17 +145,14 @@
             target.uriTranslator.packages.packageOf(fileUri);
       }
       bool hasPackageSpecifiedLanguageVersion = false;
-      int packageSpecifiedLanguageVersionMajor;
-      int packageSpecifiedLanguageVersionMinor;
+      Version version;
       if (packageForLanguageVersion != null &&
           packageForLanguageVersion.languageVersion != null) {
         hasPackageSpecifiedLanguageVersion = true;
         if (packageForLanguageVersion.languageVersion
             is! InvalidLanguageVersion) {
-          packageSpecifiedLanguageVersionMajor =
-              packageForLanguageVersion.languageVersion.major;
-          packageSpecifiedLanguageVersionMinor =
-              packageForLanguageVersion.languageVersion.minor;
+          version = new Version(packageForLanguageVersion.languageVersion.major,
+              packageForLanguageVersion.languageVersion.minor);
         }
       }
       LibraryBuilder library = target.createLibraryBuilder(
@@ -166,9 +163,7 @@
       }
 
       if (hasPackageSpecifiedLanguageVersion) {
-        library.setLanguageVersion(packageSpecifiedLanguageVersionMajor,
-            packageSpecifiedLanguageVersionMinor,
-            explicit: false);
+        library.setLanguageVersion(version, explicit: false);
       }
       if (uri.scheme == "dart" && uri.path == "core") {
         coreLibrary = library;
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 b5f17b8..635e249 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -653,6 +653,40 @@
   @override
   void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
+    _endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken, false);
+  }
+
+  @override
+  void endClassConstructor(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    _endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken, true);
+  }
+
+  @override
+  void endMixinMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    _endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken, false);
+  }
+
+  @override
+  void endExtensionMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    _endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken, false);
+  }
+
+  @override
+  void endMixinConstructor(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    _endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken, true);
+  }
+
+  void _endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken, bool isConstructor) {
     debugEvent("Method");
     // TODO(danrubel): Consider removing the beginParam parameter
     // and using bodyToken, but pushing a NullValue on the stack
@@ -663,8 +697,7 @@
     checkEmpty(beginToken.charOffset);
     if (name is ParserRecovery || currentClassIsParserRecovery) return;
     FunctionBuilder builder;
-    if (name is QualifiedName ||
-        (getOrSet == null && name == currentClass?.name)) {
+    if (isConstructor) {
       builder = lookupConstructor(beginToken, name);
     } else {
       builder = lookupBuilder(beginToken, getOrSet, name);
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 04a3998..05b1fac 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -515,8 +515,7 @@
   void handleClassOrMixinImplements(
       Token implementsKeyword, int interfacesCount) {
     debugEvent("ClassOrMixinImplements");
-    push(const FixedNullableList<NamedTypeBuilder>()
-            .pop(stack, interfacesCount) ??
+    push(const FixedNullableList<TypeBuilder>().pop(stack, interfacesCount) ??
         NullValue.TypeBuilderList);
   }
 
@@ -1327,7 +1326,7 @@
   @override
   void endTypeList(int count) {
     debugEvent("TypeList");
-    push(const FixedNullableList<NamedTypeBuilder>().pop(stack, count) ??
+    push(const FixedNullableList<TypeBuilder>().pop(stack, count) ??
         new ParserRecovery(-1));
   }
 
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 bc7ee5e..75eacd7 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
@@ -4,99 +4,43 @@
 
 library fasta.source_class_builder;
 
-import 'package:kernel/ast.dart'
-    show
-        Class,
-        Constructor,
-        Expression,
-        ListLiteral,
-        Member,
-        StaticGet,
-        Supertype,
-        TreeNode,
-        DartType,
-        DynamicType,
-        Field,
-        FunctionNode,
-        Name,
-        Procedure,
-        ProcedureKind,
-        TypeParameter,
-        VariableDeclaration,
-        Variance,
-        VoidType;
-
+import 'package:kernel/ast.dart' hide MapEntry;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
 import 'package:kernel/clone.dart' show CloneProcedureWithoutBody;
-
 import 'package:kernel/reference_from_index.dart' show IndexedClass;
-
+import 'package:kernel/src/bounds_checks.dart';
 import 'package:kernel/type_algebra.dart' show Substitution;
-
 import 'package:kernel/type_algebra.dart' as type_algebra
     show getSubstitutionMap;
-
 import 'package:kernel/type_environment.dart';
 
 import '../builder/builder.dart';
-
 import '../builder/class_builder.dart';
-
 import '../builder/constructor_reference_builder.dart';
-
+import '../builder/field_builder.dart';
 import '../builder/function_builder.dart';
-
 import '../builder/invalid_type_declaration_builder.dart';
-
 import '../builder/library_builder.dart';
-
 import '../builder/member_builder.dart';
-
 import '../builder/metadata_builder.dart';
-
 import '../builder/named_type_builder.dart';
-
 import '../builder/nullability_builder.dart';
-
 import '../builder/procedure_builder.dart';
-
 import '../builder/type_alias_builder.dart';
-
 import '../builder/type_builder.dart';
-
 import '../builder/type_declaration_builder.dart';
-
 import '../builder/type_variable_builder.dart';
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
-import '../fasta_codes.dart'
-    show
-        Message,
-        noLength,
-        messageExtendFunction,
-        messageImplementFunction,
-        messageMixinFunction,
-        templateConflictsWithConstructor,
-        templateConflictsWithFactory,
-        templateConflictsWithMember,
-        templateConflictsWithSetter,
-        templateDuplicatedDeclarationUse,
-        templateInvalidTypeVariableInSupertype,
-        templateInvalidTypeVariableInSupertypeWithVariance,
-        templateRedirectionTargetNotFound,
-        templateSupertypeIsIllegal;
+import '../fasta_codes.dart';
 
 import '../kernel/redirecting_factory_body.dart' show redirectingName;
-
 import '../kernel/kernel_builder.dart' show compareProcedures;
-
 import '../kernel/kernel_target.dart' show KernelTarget;
-
 import '../kernel/redirecting_factory_body.dart' show RedirectingFactoryBody;
-
-import '../kernel/type_algorithms.dart' show Variance, computeVariance;
+import '../kernel/type_algorithms.dart'
+    show Variance, computeTypeVariableBuilderVariance;
 
 import '../names.dart' show noSuchMethodName;
 
@@ -340,7 +284,8 @@
     if (typeVariables == null || supertype == null) return supertype;
     Message message;
     for (int i = 0; i < typeVariables.length; ++i) {
-      int variance = computeVariance(typeVariables[i], supertype, library);
+      int variance = computeTypeVariableBuilderVariance(
+          typeVariables[i], supertype, library);
       if (!Variance.greaterThanOrEqual(variance, typeVariables[i].variance)) {
         if (typeVariables[i].parameter.isLegacyCovariant) {
           message = templateInvalidTypeVariableInSupertype.withArguments(
@@ -367,6 +312,280 @@
     return supertype;
   }
 
+  void checkVarianceInField(Field field, TypeEnvironment typeEnvironment,
+      List<TypeParameter> typeParameters) {
+    for (TypeParameter typeParameter in typeParameters) {
+      int fieldVariance = computeVariance(typeParameter, field.type);
+      if (field.hasImplicitGetter) {
+        reportVariancePositionIfInvalid(
+            fieldVariance, typeParameter, field.fileUri, field.fileOffset);
+      }
+      if (field.hasImplicitSetter && !field.isCovariant) {
+        fieldVariance = Variance.combine(Variance.contravariant, fieldVariance);
+        reportVariancePositionIfInvalid(
+            fieldVariance, typeParameter, field.fileUri, field.fileOffset);
+      }
+    }
+  }
+
+  void checkVarianceInFunction(Procedure procedure,
+      TypeEnvironment typeEnvironment, List<TypeParameter> typeParameters) {
+    List<TypeParameter> functionTypeParameters =
+        procedure.function.typeParameters;
+    List<VariableDeclaration> positionalParameters =
+        procedure.function.positionalParameters;
+    List<VariableDeclaration> namedParameters =
+        procedure.function.namedParameters;
+    DartType returnType = procedure.function.returnType;
+
+    if (functionTypeParameters != null) {
+      for (TypeParameter functionParameter in functionTypeParameters) {
+        for (TypeParameter typeParameter in typeParameters) {
+          int typeVariance = Variance.combine(Variance.invariant,
+              computeVariance(typeParameter, functionParameter.bound));
+          reportVariancePositionIfInvalid(typeVariance, typeParameter, fileUri,
+              functionParameter.fileOffset);
+        }
+      }
+    }
+    if (positionalParameters != null) {
+      for (VariableDeclaration formal in positionalParameters) {
+        if (!formal.isCovariant) {
+          for (TypeParameter typeParameter in typeParameters) {
+            int formalVariance = Variance.combine(Variance.contravariant,
+                computeVariance(typeParameter, formal.type));
+            reportVariancePositionIfInvalid(
+                formalVariance, typeParameter, fileUri, formal.fileOffset);
+          }
+        }
+      }
+    }
+    if (namedParameters != null) {
+      for (VariableDeclaration named in namedParameters) {
+        for (TypeParameter typeParameter in typeParameters) {
+          int namedVariance = Variance.combine(Variance.contravariant,
+              computeVariance(typeParameter, named.type));
+          reportVariancePositionIfInvalid(
+              namedVariance, typeParameter, fileUri, named.fileOffset);
+        }
+      }
+    }
+    if (returnType != null) {
+      for (TypeParameter typeParameter in typeParameters) {
+        int returnTypeVariance = computeVariance(typeParameter, returnType);
+        reportVariancePositionIfInvalid(returnTypeVariance, typeParameter,
+            fileUri, procedure.function.fileOffset,
+            isReturnType: true);
+      }
+    }
+  }
+
+  void reportVariancePositionIfInvalid(
+      int variance, TypeParameter typeParameter, Uri fileUri, int fileOffset,
+      {bool isReturnType: false}) {
+    SourceLibraryBuilder library = this.library;
+    if (!typeParameter.isLegacyCovariant &&
+        !Variance.greaterThanOrEqual(variance, typeParameter.variance)) {
+      Message message;
+      if (isReturnType) {
+        message = templateInvalidTypeVariableVariancePositionInReturnType
+            .withArguments(Variance.keywordString(typeParameter.variance),
+                typeParameter.name, Variance.keywordString(variance));
+      } else {
+        message = templateInvalidTypeVariableVariancePosition.withArguments(
+            Variance.keywordString(typeParameter.variance),
+            typeParameter.name,
+            Variance.keywordString(variance));
+      }
+      library.reportTypeArgumentIssue(
+          message, fileUri, fileOffset, typeParameter);
+    }
+  }
+
+  void checkBoundsInSupertype(
+      Supertype supertype, TypeEnvironment typeEnvironment) {
+    SourceLibraryBuilder libraryBuilder = this.library;
+    Library library = libraryBuilder.library;
+    final DartType bottomType = library.isNonNullableByDefault
+        ? const NeverType(Nullability.nonNullable)
+        : typeEnvironment.nullType;
+
+    Set<TypeArgumentIssue> issues = {};
+    issues.addAll(findTypeArgumentIssues(
+            library,
+            new InterfaceType(supertype.classNode, library.nonNullable,
+                supertype.typeArguments),
+            typeEnvironment,
+            SubtypeCheckMode.ignoringNullabilities,
+            bottomType,
+            allowSuperBounded: false) ??
+        const []);
+    if (library.isNonNullableByDefault) {
+      issues.addAll(findTypeArgumentIssues(
+              library,
+              new InterfaceType(supertype.classNode, library.nonNullable,
+                  supertype.typeArguments),
+              typeEnvironment,
+              SubtypeCheckMode.withNullabilities,
+              bottomType,
+              allowSuperBounded: false) ??
+          const []);
+    }
+    for (TypeArgumentIssue issue in issues) {
+      DartType argument = issue.argument;
+      TypeParameter typeParameter = issue.typeParameter;
+      bool inferred = libraryBuilder.inferredTypes.contains(argument);
+      if (argument is FunctionType && argument.typeParameters.length > 0) {
+        if (inferred) {
+          libraryBuilder.reportTypeArgumentIssue(
+              templateGenericFunctionTypeInferredAsActualTypeArgument
+                  .withArguments(argument, library.isNonNullableByDefault),
+              fileUri,
+              charOffset,
+              null);
+        } else {
+          libraryBuilder.reportTypeArgumentIssue(
+              messageGenericFunctionTypeUsedAsActualTypeArgument,
+              fileUri,
+              charOffset,
+              null);
+        }
+      } else {
+        void reportProblem(
+            Template<
+                    Message Function(DartType, DartType, String, String, String,
+                        String, bool)>
+                template) {
+          libraryBuilder.reportTypeArgumentIssue(
+              template.withArguments(
+                  argument,
+                  typeParameter.bound,
+                  typeParameter.name,
+                  getGenericTypeName(issue.enclosingType),
+                  supertype.classNode.name,
+                  name,
+                  library.isNonNullableByDefault),
+              fileUri,
+              charOffset,
+              typeParameter);
+        }
+
+        if (inferred) {
+          reportProblem(templateIncorrectTypeArgumentInSupertypeInferred);
+        } else {
+          reportProblem(templateIncorrectTypeArgumentInSupertype);
+        }
+      }
+    }
+  }
+
+  void checkTypesInOutline(TypeEnvironment typeEnvironment) {
+    SourceLibraryBuilder libraryBuilder = this.library;
+    Library library = libraryBuilder.library;
+    final DartType bottomType = library.isNonNullableByDefault
+        ? const NeverType(Nullability.nonNullable)
+        : typeEnvironment.nullType;
+
+    // Check in bounds of own type variables.
+    for (TypeParameter parameter in cls.typeParameters) {
+      Set<TypeArgumentIssue> issues = {};
+      issues.addAll(findTypeArgumentIssues(
+              library,
+              parameter.bound,
+              typeEnvironment,
+              SubtypeCheckMode.ignoringNullabilities,
+              bottomType,
+              allowSuperBounded: true) ??
+          const []);
+      if (library.isNonNullableByDefault) {
+        issues.addAll(findTypeArgumentIssues(library, parameter.bound,
+                typeEnvironment, SubtypeCheckMode.withNullabilities, bottomType,
+                allowSuperBounded: true) ??
+            const []);
+      }
+      for (TypeArgumentIssue issue in issues) {
+        DartType argument = issue.argument;
+        TypeParameter typeParameter = issue.typeParameter;
+        if (libraryBuilder.inferredTypes.contains(argument)) {
+          // Inference in type expressions in the supertypes boils down to
+          // instantiate-to-bound which shouldn't produce anything that breaks
+          // the bounds after the non-simplicity checks are done.  So, any
+          // violation here is the result of non-simple bounds, and the error
+          // is reported elsewhere.
+          continue;
+        }
+
+        if (argument is FunctionType && argument.typeParameters.length > 0) {
+          libraryBuilder.reportTypeArgumentIssue(
+              messageGenericFunctionTypeUsedAsActualTypeArgument,
+              fileUri,
+              parameter.fileOffset,
+              null);
+        } else {
+          libraryBuilder.reportTypeArgumentIssue(
+              templateIncorrectTypeArgument.withArguments(
+                  argument,
+                  typeParameter.bound,
+                  typeParameter.name,
+                  getGenericTypeName(issue.enclosingType),
+                  library.isNonNullableByDefault),
+              fileUri,
+              parameter.fileOffset,
+              typeParameter);
+        }
+      }
+    }
+
+    // Check in supers.
+    if (cls.supertype != null) {
+      checkBoundsInSupertype(cls.supertype, typeEnvironment);
+    }
+    if (cls.mixedInType != null) {
+      checkBoundsInSupertype(cls.mixedInType, typeEnvironment);
+    }
+    if (cls.implementedTypes != null) {
+      for (Supertype supertype in cls.implementedTypes) {
+        checkBoundsInSupertype(supertype, typeEnvironment);
+      }
+    }
+
+    // Check in members.
+    for (Procedure procedure in cls.procedures) {
+      checkVarianceInFunction(procedure, typeEnvironment, cls.typeParameters);
+      libraryBuilder.checkBoundsInFunctionNode(
+          procedure.function, typeEnvironment, fileUri);
+    }
+    for (Constructor constructor in cls.constructors) {
+      libraryBuilder.checkBoundsInFunctionNode(
+          constructor.function, typeEnvironment, fileUri);
+    }
+    for (RedirectingFactoryConstructor redirecting
+        in cls.redirectingFactoryConstructors) {
+      libraryBuilder.checkBoundsInFunctionNodeParts(
+          typeEnvironment, fileUri, redirecting.fileOffset,
+          typeParameters: redirecting.typeParameters,
+          positionalParameters: redirecting.positionalParameters,
+          namedParameters: redirecting.namedParameters);
+    }
+
+    forEach((String name, Builder builder) {
+      // Check fields.
+      if (builder is FieldBuilder) {
+        checkVarianceInField(
+            builder.field, typeEnvironment, cls.typeParameters);
+        libraryBuilder.checkTypesInField(builder, typeEnvironment);
+      }
+
+      // Check initializers.
+      if (builder is FunctionBuilder &&
+          !builder.isAbstract &&
+          builder.formals != null) {
+        libraryBuilder.checkInitializersInFormals(
+            builder.formals, typeEnvironment);
+      }
+    });
+  }
+
   void addSyntheticConstructor(Constructor constructor) {
     String name = constructor.name.name;
     cls.constructors.add(constructor);
@@ -580,15 +799,25 @@
       Member bestSoFar = members.first;
       DartType bestSoFarType =
           forSetters ? bestSoFar.setterType : bestSoFar.getterType;
-      bestSoFarType = Substitution.fromSupertype(
-              hierarchy.getClassAsInstanceOf(cls, bestSoFar.enclosingClass))
-          .substituteType(bestSoFarType);
+      Supertype supertype =
+          hierarchy.getClassAsInstanceOf(cls, bestSoFar.enclosingClass);
+      assert(
+          supertype != null,
+          "No supertype of enclosing class ${bestSoFar.enclosingClass} for "
+          "$bestSoFar found for $cls.");
+      bestSoFarType =
+          Substitution.fromSupertype(supertype).substituteType(bestSoFarType);
       for (int i = 1; i < members.length; ++i) {
         Member candidate = members[i];
         DartType candidateType =
             forSetters ? candidate.setterType : candidate.getterType;
-        Substitution substitution = Substitution.fromSupertype(
-            hierarchy.getClassAsInstanceOf(cls, candidate.enclosingClass));
+        Supertype supertype =
+            hierarchy.getClassAsInstanceOf(cls, candidate.enclosingClass);
+        assert(
+            supertype != null,
+            "No supertype of enclosing class ${candidate.enclosingClass} for "
+            "$candidate found for $cls.");
+        Substitution substitution = Substitution.fromSupertype(supertype);
         candidateType = substitution.substituteType(candidateType);
         memberTypes.add(candidateType);
         bool isMoreSpecific = forSetters
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 923c081..6b0594b 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
@@ -49,11 +49,9 @@
         TypeParameterType,
         Typedef,
         VariableDeclaration,
+        Version,
         VoidType;
 
-import 'package:kernel/default_language_version.dart' as kernel
-    show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
-
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
 import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
@@ -133,7 +131,7 @@
 import '../kernel/type_algorithms.dart'
     show
         calculateBounds,
-        computeVariance,
+        computeTypeVariableBuilderVariance,
         findGenericFunctionTypes,
         getNonSimplicityIssuesForDeclaration,
         getNonSimplicityIssuesForTypeVariables,
@@ -169,7 +167,7 @@
 import 'source_loader.dart' show SourceLoader;
 
 import '../../api_prototype/experimental_flags.dart'
-    show enableNonNullableMajorVersion, enableNonNullableMinorVersion;
+    show enableNonNullableVersion;
 
 class SourceLibraryBuilder extends LibraryBuilderImpl {
   static const String MALFORMED_URI_SCHEME = "org-dartlang-malformed-uri";
@@ -272,7 +270,7 @@
 
   List<FieldBuilder> _implicitlyTypedFields;
 
-  LanguageVersion _languageVersion = const ImplicitLanguageVersion();
+  LanguageVersion _languageVersion;
 
   bool postponedProblemsIssued = false;
   List<PostponedProblem> postponedProblems;
@@ -312,7 +310,8 @@
       this.library,
       this._nameOrigin,
       this.referencesFrom)
-      : currentTypeParameterScopeBuilder = libraryDeclaration,
+      : _languageVersion = new ImplicitLanguageVersion(library.languageVersion),
+        currentTypeParameterScopeBuilder = libraryDeclaration,
         referencesFromIndexed =
             referencesFrom == null ? null : new IndexedLibrary(referencesFrom),
         super(
@@ -362,8 +361,7 @@
                         reference: referenceIsPartOwner == true
                             ? null
                             : referencesFrom?.reference)
-                  ..setLanguageVersion(loader.target.currentSdkVersionMajor,
-                      loader.target.currentSdkVersionMinor)),
+                  ..setLanguageVersion(loader.target.currentSdkVersion)),
             nameOrigin,
             referencesFrom,
             referenceIsPartOwner);
@@ -385,11 +383,10 @@
   @override
   bool get isNonNullableByDefault =>
       loader.target.enableNonNullable &&
-      languageVersion.major >= enableNonNullableMajorVersion &&
-      languageVersion.minor >= enableNonNullableMinorVersion &&
+      languageVersion.version >= enableNonNullableVersion &&
       !isOptOutTest(library.importUri);
 
-  bool isOptOutTest(Uri uri) {
+  static bool isOptOutTest(Uri uri) {
     String path = uri.path;
     for (String testDir in ['/tests/', '/generated_tests/']) {
       int start = path.indexOf(testDir);
@@ -410,61 +407,48 @@
     'language_2/',
     'lib_2/',
     'standalone_2/',
+    'vm/dart/', // in runtime/tests
   ];
 
   LanguageVersion get languageVersion => _languageVersion;
 
   @override
-  void setLanguageVersion(int major, int minor,
+  void setLanguageVersion(Version version,
       {int offset: 0, int length: noLength, bool explicit: false}) {
     if (languageVersion.isExplicit) return;
 
-    if (major == null || minor == null) {
+    if (version == null) {
       addPostponedProblem(
           messageLanguageVersionInvalidInDotPackages, offset, length, fileUri);
       if (_languageVersion is ImplicitLanguageVersion) {
         _languageVersion = new InvalidLanguageVersion(
-            fileUri,
-            offset,
-            length,
-            explicit,
-            loader.target.currentSdkVersionMajor,
-            loader.target.currentSdkVersionMinor);
-        library.setLanguageVersion(
-            _languageVersion.major, _languageVersion.minor);
+            fileUri, offset, length, explicit, loader.target.currentSdkVersion);
+        library.setLanguageVersion(_languageVersion.version);
       }
       return;
     }
 
     // If trying to set a language version that is higher than the current sdk
     // version it's an error.
-    if (major > loader.target.currentSdkVersionMajor ||
-        (major == loader.target.currentSdkVersionMajor &&
-            minor > loader.target.currentSdkVersionMinor)) {
+    if (version > loader.target.currentSdkVersion) {
       addPostponedProblem(
           templateLanguageVersionTooHigh.withArguments(
-              loader.target.currentSdkVersionMajor,
-              loader.target.currentSdkVersionMinor),
+              loader.target.currentSdkVersion.major,
+              loader.target.currentSdkVersion.minor),
           offset,
           length,
           fileUri);
       if (_languageVersion is ImplicitLanguageVersion) {
         _languageVersion = new InvalidLanguageVersion(
-            fileUri,
-            offset,
-            length,
-            explicit,
-            loader.target.currentSdkVersionMajor,
-            loader.target.currentSdkVersionMinor);
-        library.setLanguageVersion(
-            _languageVersion.major, _languageVersion.minor);
+            fileUri, offset, length, explicit, loader.target.currentSdkVersion);
+        library.setLanguageVersion(_languageVersion.version);
       }
       return;
     }
 
     _languageVersion =
-        new LanguageVersion(major, minor, fileUri, offset, length, explicit);
-    library.setLanguageVersion(major, minor);
+        new LanguageVersion(version, fileUri, offset, length, explicit);
+    library.setLanguageVersion(version);
   }
 
   ConstructorReferenceBuilder addConstructorReference(Object name,
@@ -2729,8 +2713,8 @@
       if (declaration is TypeAliasBuilder &&
           declaration.typeVariablesCount > 0) {
         for (TypeVariableBuilder typeParameter in declaration.typeVariables) {
-          typeParameter.variance =
-              computeVariance(typeParameter, declaration.type, this);
+          typeParameter.variance = computeTypeVariableBuilderVariance(
+              typeParameter, declaration.type, this);
           ++count;
         }
       }
@@ -3105,13 +3089,13 @@
           ? const NeverType(Nullability.nonNullable)
           : typeEnvironment.nullType;
       Set<TypeArgumentIssue> issues = {};
-      issues.addAll(findTypeArgumentIssues(returnType, typeEnvironment,
+      issues.addAll(findTypeArgumentIssues(library, returnType, typeEnvironment,
               SubtypeCheckMode.ignoringNullabilities, bottomType,
               allowSuperBounded: true) ??
           const []);
       if (isNonNullableByDefault) {
-        issues.addAll(findTypeArgumentIssues(returnType, typeEnvironment,
-                SubtypeCheckMode.withNullabilities, bottomType,
+        issues.addAll(findTypeArgumentIssues(library, returnType,
+                typeEnvironment, SubtypeCheckMode.withNullabilities, bottomType,
                 allowSuperBounded: true) ??
             const []);
       }
@@ -3187,12 +3171,12 @@
         ? const NeverType(Nullability.nonNullable)
         : typeEnvironment.nullType;
     Set<TypeArgumentIssue> issues = {};
-    issues.addAll(findTypeArgumentIssues(type, typeEnvironment,
+    issues.addAll(findTypeArgumentIssues(library, type, typeEnvironment,
             SubtypeCheckMode.ignoringNullabilities, bottomType,
             allowSuperBounded: allowSuperBounded) ??
         const []);
     if (isNonNullableByDefault) {
-      issues.addAll(findTypeArgumentIssues(type, typeEnvironment,
+      issues.addAll(findTypeArgumentIssues(library, type, typeEnvironment,
               SubtypeCheckMode.withNullabilities, bottomType,
               allowSuperBounded: allowSuperBounded) ??
           const []);
@@ -3255,6 +3239,7 @@
         : typeEnvironment.nullType;
     Set<TypeArgumentIssue> issues = {};
     issues.addAll(findTypeArgumentIssuesForInvocation(
+            library,
             parameters,
             arguments,
             typeEnvironment,
@@ -3263,6 +3248,7 @@
         const []);
     if (isNonNullableByDefault) {
       issues.addAll(findTypeArgumentIssuesForInvocation(
+              library,
               parameters,
               arguments,
               typeEnvironment,
@@ -3340,6 +3326,7 @@
         : typeEnvironment.nullType;
     Set<TypeArgumentIssue> issues = {};
     issues.addAll(findTypeArgumentIssuesForInvocation(
+            library,
             instantiatedMethodParameters,
             arguments.types,
             typeEnvironment,
@@ -3348,6 +3335,7 @@
         const []);
     if (isNonNullableByDefault) {
       issues.addAll(findTypeArgumentIssuesForInvocation(
+              library,
               instantiatedMethodParameters,
               arguments.types,
               typeEnvironment,
@@ -3373,7 +3361,7 @@
         if (declaration.formals != null) {
           checkInitializersInFormals(declaration.formals, typeEnvironment);
         }
-      } else if (declaration is ClassBuilder) {
+      } else if (declaration is SourceClassBuilder) {
         declaration.checkTypesInOutline(typeEnvironment);
       }
     }
@@ -3738,31 +3726,28 @@
 }
 
 class LanguageVersion {
-  final int major;
-  final int minor;
+  final Version version;
   final Uri fileUri;
   final int charOffset;
   final int charCount;
   final bool isExplicit;
 
-  LanguageVersion(this.major, this.minor, this.fileUri, this.charOffset,
-      this.charCount, this.isExplicit);
+  LanguageVersion(this.version, this.fileUri, this.charOffset, this.charCount,
+      this.isExplicit);
 
   bool get valid => true;
 
-  int get hashCode =>
-      major.hashCode * 13 + minor.hashCode * 17 + isExplicit.hashCode * 19;
+  int get hashCode => version.hashCode * 13 + isExplicit.hashCode * 19;
 
   bool operator ==(Object other) {
     if (identical(this, other)) return true;
     return other is LanguageVersion &&
-        major == other.major &&
-        minor == other.minor &&
+        version == other.version &&
         isExplicit == other.isExplicit;
   }
 
   String toString() {
-    return 'LanguageVersion(major=$major,minor=$minor,isExplicit=$isExplicit,'
+    return 'LanguageVersion(version=$version,isExplicit=$isExplicit,'
         'fileUri=$fileUri,charOffset=$charOffset,charCount=$charCount)';
   }
 }
@@ -3772,11 +3757,10 @@
   final int charOffset;
   final int charCount;
   final bool isExplicit;
-  final int major;
-  final int minor;
+  final Version version;
 
   InvalidLanguageVersion(this.fileUri, this.charOffset, this.charCount,
-      this.isExplicit, this.major, this.minor);
+      this.isExplicit, this.version);
 
   @override
   bool get valid => false;
@@ -3795,13 +3779,10 @@
 }
 
 class ImplicitLanguageVersion implements LanguageVersion {
-  const ImplicitLanguageVersion();
-
   @override
-  int get major => kernel.defaultLanguageVersionMajor;
+  final Version version;
 
-  @override
-  int get minor => kernel.defaultLanguageVersionMinor;
+  ImplicitLanguageVersion(this.version);
 
   @override
   bool get valid => true;
@@ -3818,6 +3799,13 @@
   @override
   bool get isExplicit => false;
 
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is ImplicitLanguageVersion && version == other.version;
+  }
+
   @override
-  String toString() => 'ImplicitLanguageVersion()';
+  String toString() {
+    return 'ImplicitLanguageVersion(version=$version)';
+  }
 }
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 776f399..92f6450 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -42,7 +42,8 @@
         ProcedureKind,
         Reference,
         Supertype,
-        TreeNode;
+        TreeNode,
+        Version;
 
 import 'package:kernel/class_hierarchy.dart'
     show ClassHierarchy, HandleAmbiguousSupertypes;
@@ -258,7 +259,7 @@
             enableNonNullable: library.isNonNullableByDefault),
         languageVersionChanged:
             (Scanner scanner, LanguageVersionToken version) {
-      library.setLanguageVersion(version.major, version.minor,
+      library.setLanguageVersion(new Version(version.major, version.minor),
           offset: version.offset, length: version.length, explicit: true);
       scanner.configuration = new ScannerConfiguration(
           enableTripleShift: target.enableTripleShift,
@@ -925,7 +926,7 @@
       hierarchy.onAmbiguousSupertypes = onAmbiguousSupertypes;
       Component component = computeFullComponent();
       hierarchy.coreTypes = coreTypes;
-      hierarchy.applyTreeChanges(const [], component.libraries,
+      hierarchy.applyTreeChanges(const [], component.libraries, const [],
           reissueAmbiguousSupertypesFor: component);
     }
     for (AmbiguousTypesRecord record in ambiguousTypesRecords) {
@@ -1238,33 +1239,76 @@
 
 print(object) {}
 
-class Iterator {}
+class Iterator<E> {
+  bool moveNext() => null;
+  E get current => null;
+}
 
-class Iterable {}
+class Iterable<E> {
+  Iterator<E> get iterator => null;
+}
 
-class List extends Iterable {
+class List<E> extends Iterable {
+  factory List() => null;
   factory List.unmodifiable(elements) => null;
+  factory List.filled(int length, E fill, {bool growable = false}) => null;
+  void add(E) {}
+  E operator [](int index) => null;
 }
 
-class Map extends Iterable {
-  factory Map.unmodifiable(other) => null;
+class _GrowableList<E> {
+  factory _GrowableList() => null;
 }
 
+class _List<E> {
+  factory _List() => null;
+}
+
+class MapEntry<K, V> {
+  K key;
+  V value;
+}
+
+abstract class Map<K, V> extends Iterable {
+  factory Map.unmodifiable(other) => null;
+  Iterable<MapEntry<K, V>> get entries;
+  void operator []=(K key, V value) {}
+}
+
+abstract class _ImmutableMap<K, V> implements Map<K, V> {
+  dynamic _kvPairs;
+}
+
+abstract class pragma {
+  String name;
+  Object options;
+}
+
+class AbstractClassInstantiationError {}
+
 class NoSuchMethodError {
   NoSuchMethodError.withInvocation(receiver, invocation);
 }
 
+class StackTrace {}
+
 class Null {}
 
 class Object {
+  const Object();
   noSuchMethod(invocation) => null;
+  bool operator==(dynamic) {}
 }
 
 class String {}
 
 class Symbol {}
 
-class Set {}
+class Set<E> {
+  factory Set() = Set<E>._fake;
+  external factory Set._fake();
+  void add(E) {}
+}
 
 class Type {}
 
@@ -1296,6 +1340,10 @@
 const String defaultDartAsyncSource = """
 _asyncErrorWrapperHelper(continuation) {}
 
+void _asyncStarListenHelper(var object, var awaiter) {}
+
+void _asyncStarMoveNextHelper(var stream) {}
+
 _asyncStackTraceHelper(async_op) {}
 
 _asyncThenWrapperHelper(continuation) {}
@@ -1316,7 +1364,7 @@
   get stream => null;
 }
 
-class Completer {
+abstract class Completer {
   factory Completer.sync() => null;
 
   get future;
@@ -1326,7 +1374,7 @@
   completeError(error, [stackTrace]);
 }
 
-class Future {
+class Future<T> {
   factory Future.microtask(computation) => null;
 }
 
@@ -1339,6 +1387,8 @@
   complete([value]) {}
 
   completeError(error, [stackTrace]) {}
+
+  void start(void Function() f) {}
 }
 
 class Stream {}
@@ -1367,6 +1417,8 @@
 class Symbol {
   const Symbol(String name);
 }
+
+T unsafeCast<T>(Object v) {}
 """;
 
 /// A minimal implementation of dart:typed_data that is sufficient to create an
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 5e3b43a..26baf64 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
@@ -81,8 +81,10 @@
         addProblem(messageNonNullableOptOut, token.charOffset, token.charCount);
       }
     } else {
-      addProblem(templateExperimentNotEnabled.withArguments('non-nullable'),
-          token.offset, noLength);
+      addProblem(
+          templateExperimentNotEnabled.withArguments('non-nullable', '2.9'),
+          token.offset,
+          noLength);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 00c4bef..26400d6 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -6,7 +6,7 @@
 
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Library, Source;
+import 'package:kernel/ast.dart' show Library, Source, Version;
 
 import 'package:kernel/target/targets.dart' as backend show Target;
 
@@ -169,36 +169,30 @@
     return rewriteSeverity(severity, message.code, fileUri);
   }
 
-  String get currentSdkVersion {
+  String get currentSdkVersionString {
     return CompilerContext.current.options.currentSdkVersion;
   }
 
-  int _currentSdkVersionMajor;
-  int _currentSdkVersionMinor;
-  int get currentSdkVersionMajor {
-    if (_currentSdkVersionMajor != null) return _currentSdkVersionMajor;
+  Version _currentSdkVersion;
+  Version get currentSdkVersion {
+    if (_currentSdkVersion != null) return _currentSdkVersion;
     _parseCurrentSdkVersion();
-    return _currentSdkVersionMajor;
-  }
-
-  int get currentSdkVersionMinor {
-    if (_currentSdkVersionMinor != null) return _currentSdkVersionMinor;
-    _parseCurrentSdkVersion();
-    return _currentSdkVersionMinor;
+    return _currentSdkVersion;
   }
 
   void _parseCurrentSdkVersion() {
     bool good = false;
-    if (currentSdkVersion != null) {
-      List<String> dotSeparatedParts = currentSdkVersion.split(".");
+    if (currentSdkVersionString != null) {
+      List<String> dotSeparatedParts = currentSdkVersionString.split(".");
       if (dotSeparatedParts.length >= 2) {
-        _currentSdkVersionMajor = int.tryParse(dotSeparatedParts[0]);
-        _currentSdkVersionMinor = int.tryParse(dotSeparatedParts[1]);
+        _currentSdkVersion = new Version(int.tryParse(dotSeparatedParts[0]),
+            int.tryParse(dotSeparatedParts[1]));
         good = true;
       }
     }
     if (!good) {
-      throw new StateError("Unparsable sdk version given: $currentSdkVersion");
+      throw new StateError(
+          "Unparsable sdk version given: $currentSdkVersionString");
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart b/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart
new file mode 100644
index 0000000..6f93a2b
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/type_environment.dart';
+
+/// Computes the "remainder" of [T] when [S] has been removed from consideration
+/// by an instance check.  This operation is used for type promotion during flow
+/// analysis.
+DartType factorType(TypeEnvironment typeEnvironment, DartType T, DartType S) {
+  // * If T <: S then Never
+  if (typeEnvironment.isSubtypeOf(T, S, SubtypeCheckMode.withNullabilities)) {
+    return const NeverType(Nullability.nonNullable);
+  }
+
+  // * Else if T is R? and Null <: S then factor(R, S)
+  // * Else if T is R? then factor(R, S)?
+  if (T.nullability == Nullability.nullable) {
+    DartType R = T.withNullability(Nullability.nonNullable);
+    if (identical(R, T)) {
+      return T;
+    }
+    DartType factor_RS = factorType(typeEnvironment, R, S);
+    if (typeEnvironment.isSubtypeOf(
+        typeEnvironment.nullType, S, SubtypeCheckMode.withNullabilities)) {
+      return factor_RS;
+    } else {
+      return factor_RS.withNullability(Nullability.nullable);
+    }
+  }
+
+  // * Else if T is R* and Null <: S then factor(R, S)
+  // * Else if T is R* then factor(R, S)*
+  if (T.nullability == Nullability.legacy) {
+    DartType R = T.withNullability(Nullability.nonNullable);
+    DartType factor_RS = factorType(typeEnvironment, R, S);
+    if (typeEnvironment.isSubtypeOf(
+        typeEnvironment.nullType, S, SubtypeCheckMode.withNullabilities)) {
+      return factor_RS;
+    } else {
+      return factor_RS.withNullability(Nullability.legacy);
+    }
+  }
+
+  // * Else if T is FutureOr<R> and Future<R> <: S then factor(R, S)
+  // * Else if T is FutureOr<R> and R <: S then factor(Future<R>, S)
+  if (T is InterfaceType && T.classNode == typeEnvironment.futureOrClass) {
+    DartType R = T.typeArguments[0];
+    DartType future_R = typeEnvironment.futureType(R, Nullability.nonNullable);
+    if (typeEnvironment.isSubtypeOf(
+        future_R, S, SubtypeCheckMode.withNullabilities)) {
+      return factorType(typeEnvironment, R, S);
+    }
+    if (typeEnvironment.isSubtypeOf(R, S, SubtypeCheckMode.withNullabilities)) {
+      return factorType(typeEnvironment, future_R, S);
+    }
+  }
+
+  return T;
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index 8e1c904..e2d8911 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -407,8 +407,14 @@
 
     // DOWN(T1, T2) = T1 if T1 <: T2.
     // DOWN(T1, T2) = T2 if T2 <: T1.
+
+    // We use the non-nullable variants of the two types to determine T1 <: T2
+    // without using the nullability of the outermost type. The result uses
+    // [intersectNullabilities] to compute the resulting type if the subtype
+    // relation is established.
     DartType nonNullableType1 = type1.withNullability(Nullability.nonNullable);
     DartType nonNullableType2 = type2.withNullability(Nullability.nonNullable);
+
     if (isSubtypeOf(nonNullableType1, nonNullableType2,
         SubtypeCheckMode.withNullabilities)) {
       return type1.withNullability(
@@ -755,14 +761,26 @@
         "Expected type1 to be an interface type, got '${type1.runtimeType}'.");
     assert(type2 is InterfaceType,
         "Expected type2 to be an interface type, got '${type2.runtimeType}'.");
-    if (isSubtypeOf(type1, type2, SubtypeCheckMode.withNullabilities)) {
+
+    // We use the non-nullable variants of the two interfaces types to determine
+    // T1 <: T2 without using the nullability of the outermost type. The result
+    // uses [uniteNullabilities] to compute the resulting type if the subtype
+    // relation is established.
+    InterfaceType nonNonNullableType1 =
+        type1.withNullability(Nullability.nonNullable);
+    InterfaceType nonNonNullableType2 =
+        type2.withNullability(Nullability.nonNullable);
+
+    if (isSubtypeOf(nonNonNullableType1, nonNonNullableType2,
+        SubtypeCheckMode.withNullabilities)) {
       return type2.withNullability(
           uniteNullabilities(type1.nullability, type2.nullability));
     }
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point.
-    if (isSubtypeOf(type2, type1, SubtypeCheckMode.withNullabilities)) {
+    if (isSubtypeOf(nonNonNullableType2, nonNonNullableType1,
+        SubtypeCheckMode.withNullabilities)) {
       return type1.withNullability(
           uniteNullabilities(type1.nullability, type2.nullability));
     }
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 7b57b07..bbaff28 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
@@ -16,6 +16,7 @@
         NamedType,
         NeverType,
         Nullability,
+        Statement,
         TreeNode,
         TypeParameter,
         TypeParameterType,
@@ -35,11 +36,15 @@
 
 import '../kernel/forest.dart';
 
+import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
+
 import '../kernel/kernel_builder.dart'
     show ClassHierarchyBuilder, ImplicitFieldType;
 
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 
+import 'factor_type.dart';
+
 import 'type_inferrer.dart';
 
 import 'type_schema_environment.dart' show TypeSchemaEnvironment;
@@ -236,7 +241,7 @@
 
   /// The list of [Expression]s representing variable accesses that occur before
   /// the corresponding variable has been definitely assigned.
-  final List<TreeNode> unassignedNodes = [];
+  final List<TreeNode> potentiallyUnassignedNodes = [];
 
   /// The list of [Expression]s representing variable accesses that occur when
   /// the corresponding variable has been definitely unassigned.
@@ -253,6 +258,19 @@
 
   TypeOperationsCfe(this.typeEnvironment);
 
+  @override
+  DartType factor(DartType from, DartType what) {
+    return factorType(typeEnvironment, from, what);
+  }
+
+  @override
+  bool isLocalVariableWithoutDeclaredType(VariableDeclaration variable) {
+    return variable is VariableDeclarationImpl &&
+        variable.parent is Statement &&
+        variable.isImplicitlyTyped &&
+        !variable.hasDeclaredInitializer;
+  }
+
   // TODO(dmitryas): Consider checking for mutual subtypes instead of ==.
   @override
   bool isSameType(DartType type1, DartType type2) => type1 == type2;
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 2010a5b..c28a357 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
@@ -157,7 +157,7 @@
       DartType returnContext, bool needToInferReturnType) {
     assert(returnContext != null);
     DartType declaredReturnType =
-        greatestClosure(returnContext, inferrer.bottomType);
+        inferrer.computeGreatestClosure(returnContext);
     bool isAsync = asyncMarker == AsyncMarker.Async ||
         asyncMarker == AsyncMarker.AsyncStar;
     bool isGenerator = asyncMarker == AsyncMarker.SyncStar ||
@@ -293,7 +293,7 @@
         if (!identical(statement.expression, expression)) {
           statement.expression = expression..parent = statement;
           // Not assignable, use the expectation.
-          type = greatestClosure(returnOrYieldContext, inferrer.bottomType);
+          type = inferrer.computeGreatestClosure(returnOrYieldContext);
         }
       }
       DartType unwrappedType = type;
@@ -306,8 +306,14 @@
         statement.expression != null) {
       // If we are not inferring a type we can immediately check that the return
       // is valid.
+      DartType wrappedType = type;
+      if (isAsync) {
+        wrappedType = inferrer.typeSchemaEnvironment.futureType(
+            inferrer.typeSchemaEnvironment.unfutureType(type),
+            Nullability.nonNullable);
+      }
       Expression expression = inferrer.ensureAssignable(
-          returnOrYieldContext, type, statement.expression,
+          returnOrYieldContext, wrappedType, statement.expression,
           fileOffset: statement.fileOffset,
           isReturnFromAsync: isAsync,
           isVoidAllowed: true);
@@ -331,7 +337,7 @@
     node.expression = expression..parent = node;
     DartType type = expressionResult.inferredType;
     if (!identical(expressionResult.expression, expression)) {
-      type = greatestClosure(expectedType, inferrer.bottomType);
+      type = inferrer.computeGreatestClosure(expectedType);
     }
     if (_needToInferReturnType) {
       DartType unwrappedType = type;
@@ -375,7 +381,7 @@
         returnOrYieldContext, SubtypeCheckMode.withNullabilities)) {
       // If the inferred return type isn't a subtype of the context, we use the
       // context.
-      inferredType = greatestClosure(declaredReturnType, inferrer.bottomType);
+      inferredType = inferrer.computeGreatestClosure2(declaredReturnType);
     }
 
     for (int i = 0; i < returnStatements.length; ++i) {
@@ -602,6 +608,19 @@
       ? const NeverType(Nullability.nonNullable)
       : engine.coreTypes.nullType;
 
+  DartType computeGreatestClosure(DartType type) {
+    return greatestClosure(type, const DynamicType(), bottomType);
+  }
+
+  DartType computeGreatestClosure2(DartType type) {
+    return greatestClosure(
+        type,
+        isNonNullableByDefault
+            ? coreTypes.objectNullableRawType
+            : const DynamicType(),
+        bottomType);
+  }
+
   DartType computeNullable(DartType type) {
     if (type == coreTypes.nullType || type is NeverType) {
       return coreTypes.nullType;
@@ -697,11 +716,8 @@
         typeContext.classNode == coreTypes.doubleClass;
   }
 
-  bool isAssignable(DartType contextType, DartType expressionType,
-      {bool isStrongNullabilityMode}) {
-    isStrongNullabilityMode ??=
-        isNonNullableByDefault && nnbdMode != NnbdMode.Weak;
-    if (isStrongNullabilityMode) {
+  bool isAssignable(DartType contextType, DartType expressionType) {
+    if (isNonNullableByDefault) {
       if (expressionType is DynamicType) return true;
       return typeSchemaEnvironment
           .performNullabilityAwareSubtypeCheck(expressionType, contextType)
@@ -717,12 +733,14 @@
       DartType expectedType, ExpressionInferenceResult result,
       {int fileOffset,
       bool isVoidAllowed: false,
-      bool isReturnFromAsync: false}) {
+      bool isReturnFromAsync: false,
+      Template<Message Function(DartType, DartType, bool)> errorTemplate}) {
     return ensureAssignable(
         expectedType, result.inferredType, result.expression,
         fileOffset: fileOffset,
         isVoidAllowed: isVoidAllowed,
-        isReturnFromAsync: isReturnFromAsync);
+        isReturnFromAsync: isReturnFromAsync,
+        errorTemplate: errorTemplate);
   }
 
   /// Ensures that [expressionType] is assignable to [contextType].
@@ -744,7 +762,7 @@
     if (isTopLevel) return expression;
 
     fileOffset ??= expression.fileOffset;
-    contextType = greatestClosure(contextType, bottomType);
+    contextType = computeGreatestClosure(contextType);
 
     DartType initialContextType = contextType;
     if (isReturnFromAsync &&
@@ -1012,6 +1030,153 @@
     return inferredTypes;
   }
 
+  /// Returns the extension member access by the given [name] for a receiver
+  /// with the static [receiverType].
+  ///
+  /// If none is found, [defaultTarget] is returned.
+  ///
+  /// If multiple are found, none more specific, an
+  /// [AmbiguousExtensionAccessTarget] is returned. This access kind results in
+  /// a compile-time error, but is used to provide a better message than just
+  /// reporting that the receiver does not have a member by the given name.
+  ///
+  /// If [isPotentiallyNullableAccess] is `true`, the returned extension member
+  /// is flagged as a nullable extension member access. This access kind results
+  /// in a compile-time error, but is used to provide a better message than just
+  /// reporting that the receiver does not have a member by the given name.
+  ObjectAccessTarget _findExtensionMember(
+      DartType receiverType, Class classNode, Name name, int fileOffset,
+      {bool setter: false,
+      ObjectAccessTarget defaultTarget,
+      bool isPotentiallyNullableAccess: false}) {
+    Name otherName = name;
+    bool otherIsSetter;
+    if (name == indexGetName) {
+      // [] must be checked against []=.
+      otherName = indexSetName;
+      otherIsSetter = false;
+    } else if (name == indexSetName) {
+      // []= must be checked against [].
+      otherName = indexGetName;
+      otherIsSetter = false;
+    } else {
+      otherName = name;
+      otherIsSetter = !setter;
+    }
+
+    Member otherMember =
+        _getInterfaceMember(classNode, otherName, otherIsSetter, fileOffset);
+    if (otherMember != null) {
+      // If we're looking for `foo` and `foo=` can be found or vice-versa then
+      // extension methods should not be found.
+      return defaultTarget;
+    }
+
+    ExtensionAccessCandidate bestSoFar;
+    List<ExtensionAccessCandidate> noneMoreSpecific = [];
+    library.forEachExtensionInScope((ExtensionBuilder extensionBuilder) {
+      MemberBuilder thisBuilder =
+          extensionBuilder.lookupLocalMemberByName(name, setter: setter);
+      MemberBuilder otherBuilder = extensionBuilder
+          .lookupLocalMemberByName(otherName, setter: otherIsSetter);
+      if ((thisBuilder != null && !thisBuilder.isStatic) ||
+          (otherBuilder != null && !otherBuilder.isStatic)) {
+        DartType onType;
+        DartType onTypeInstantiateToBounds;
+        List<DartType> inferredTypeArguments;
+        if (extensionBuilder.extension.typeParameters.isEmpty) {
+          onTypeInstantiateToBounds =
+              onType = extensionBuilder.extension.onType;
+          inferredTypeArguments = const <DartType>[];
+        } else {
+          List<TypeParameter> typeParameters =
+              extensionBuilder.extension.typeParameters;
+          inferredTypeArguments = inferExtensionTypeArguments(
+              extensionBuilder.extension, receiverType);
+          Substitution inferredSubstitution =
+              Substitution.fromPairs(typeParameters, inferredTypeArguments);
+
+          for (int index = 0; index < typeParameters.length; index++) {
+            TypeParameter typeParameter = typeParameters[index];
+            DartType typeArgument = inferredTypeArguments[index];
+            DartType bound =
+                inferredSubstitution.substituteType(typeParameter.bound);
+            if (!typeSchemaEnvironment.isSubtypeOf(
+                typeArgument, bound, SubtypeCheckMode.withNullabilities)) {
+              return;
+            }
+          }
+          onType = inferredSubstitution
+              .substituteType(extensionBuilder.extension.onType);
+          List<DartType> instantiateToBoundTypeArguments = calculateBounds(
+              typeParameters, coreTypes.objectClass, library.library);
+          Substitution instantiateToBoundsSubstitution = Substitution.fromPairs(
+              typeParameters, instantiateToBoundTypeArguments);
+          onTypeInstantiateToBounds = instantiateToBoundsSubstitution
+              .substituteType(extensionBuilder.extension.onType);
+        }
+
+        if (typeSchemaEnvironment.isSubtypeOf(
+            receiverType, onType, SubtypeCheckMode.withNullabilities)) {
+          ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
+              thisBuilder ?? otherBuilder,
+              onType,
+              onTypeInstantiateToBounds,
+              thisBuilder != null &&
+                      !thisBuilder.isField &&
+                      !thisBuilder.isStatic
+                  ? new ObjectAccessTarget.extensionMember(
+                      setter
+                          ? thisBuilder.writeTarget
+                          : thisBuilder.invokeTarget,
+                      thisBuilder.readTarget,
+                      thisBuilder.kind,
+                      inferredTypeArguments,
+                      isPotentiallyNullable: isPotentiallyNullableAccess)
+                  : const ObjectAccessTarget.missing(),
+              isPlatform: extensionBuilder.library.importUri.scheme == 'dart');
+          if (noneMoreSpecific.isNotEmpty) {
+            bool isMostSpecific = true;
+            for (ExtensionAccessCandidate other in noneMoreSpecific) {
+              bool isMoreSpecific =
+                  candidate.isMoreSpecificThan(typeSchemaEnvironment, other);
+              if (isMoreSpecific != true) {
+                isMostSpecific = false;
+                break;
+              }
+            }
+            if (isMostSpecific) {
+              bestSoFar = candidate;
+              noneMoreSpecific.clear();
+            } else {
+              noneMoreSpecific.add(candidate);
+            }
+          } else if (bestSoFar == null) {
+            bestSoFar = candidate;
+          } else {
+            bool isMoreSpecific =
+                candidate.isMoreSpecificThan(typeSchemaEnvironment, bestSoFar);
+            if (isMoreSpecific == true) {
+              bestSoFar = candidate;
+            } else if (isMoreSpecific == null) {
+              noneMoreSpecific.add(bestSoFar);
+              noneMoreSpecific.add(candidate);
+              bestSoFar = null;
+            }
+          }
+        }
+      }
+    });
+    if (bestSoFar != null) {
+      return bestSoFar.target;
+    } else {
+      if (noneMoreSpecific.isNotEmpty) {
+        return new AmbiguousExtensionAccessTarget(noneMoreSpecific);
+      }
+    }
+    return defaultTarget;
+  }
+
   /// Finds a member of [receiverType] called [name], and if it is found,
   /// reports it through instrumentation using [fileOffset].
   ///
@@ -1030,27 +1195,43 @@
       bool includeExtensionMethods: false}) {
     assert(receiverType != null && isKnown(receiverType));
 
-    receiverType = resolveTypeParameter(receiverType);
+    DartType receiverBound = resolveTypeParameter(receiverType);
 
-    if (receiverType is FunctionType && name == callName) {
-      return const ObjectAccessTarget.callFunction();
+    bool isReceiverTypePotentiallyNullable = isNonNullableByDefault &&
+        isPotentiallyNullable(receiverType, coreTypes.futureOrClass) &&
+        // Calls to `==` are always on a non-null receiver.
+        name != equalsName;
+
+    Class classNode = receiverBound is InterfaceType
+        ? receiverBound.classNode
+        : coreTypes.objectClass;
+
+    if (isReceiverTypePotentiallyNullable) {
+      Member member =
+          _getInterfaceMember(coreTypes.objectClass, name, setter, fileOffset);
+      if (member != null) {
+        return new ObjectAccessTarget.interfaceMember(member,
+            // Null implements all Object members so this is not considered a
+            // potentially nullable access.
+            isPotentiallyNullable: false);
+      }
+      if (includeExtensionMethods) {
+        ObjectAccessTarget target =
+            _findExtensionMember(receiverBound, classNode, name, fileOffset);
+        if (target != null) {
+          return target;
+        }
+      }
     }
 
-    Class classNode = receiverType is InterfaceType
-        ? receiverType.classNode
-        : coreTypes.objectClass;
-    Member interfaceMember =
-        _getInterfaceMember(classNode, name, setter, fileOffset);
-    ObjectAccessTarget target;
-    if (interfaceMember != null) {
-      target = new ObjectAccessTarget.interfaceMember(interfaceMember);
-    } else if (receiverType is DynamicType) {
-      target = const ObjectAccessTarget.dynamic();
-    } else if (receiverType is NeverType) {
-      switch (receiverType.nullability) {
+    if (receiverBound is FunctionType && name == callName) {
+      return isReceiverTypePotentiallyNullable
+          ? const ObjectAccessTarget.nullableCallFunction()
+          : const ObjectAccessTarget.callFunction();
+    } else if (receiverBound is NeverType) {
+      switch (receiverBound.nullability) {
         case Nullability.nonNullable:
-          target = const ObjectAccessTarget.never();
-          break;
+          return const ObjectAccessTarget.never();
         case Nullability.nullable:
         case Nullability.legacy:
           // Never? and Never* are equivalent to Null.
@@ -1058,273 +1239,65 @@
         case Nullability.undetermined:
           return internalProblem(
               templateInternalProblemUnsupportedNullability.withArguments(
-                  "${receiverType.nullability}",
-                  receiverType,
+                  "${receiverBound.nullability}",
+                  receiverBound,
                   isNonNullableByDefault),
               fileOffset,
               library.fileUri);
       }
-    } else if (receiverType is InvalidType) {
+    }
+
+    ObjectAccessTarget target;
+    Member interfaceMember =
+        _getInterfaceMember(classNode, name, setter, fileOffset);
+    if (interfaceMember != null) {
+      target = new ObjectAccessTarget.interfaceMember(interfaceMember,
+          isPotentiallyNullable: isReceiverTypePotentiallyNullable);
+    } else if (receiverBound is DynamicType) {
+      target = const ObjectAccessTarget.dynamic();
+    } else if (receiverBound is InvalidType) {
       target = const ObjectAccessTarget.invalid();
-    } else if (receiverType is InterfaceType &&
-        receiverType.classNode == coreTypes.functionClass &&
+    } else if (receiverBound is InterfaceType &&
+        receiverBound.classNode == coreTypes.functionClass &&
         name == callName) {
-      target = const ObjectAccessTarget.callFunction();
+      target = isReceiverTypePotentiallyNullable
+          ? const ObjectAccessTarget.nullableCallFunction()
+          : const ObjectAccessTarget.callFunction();
     } else {
       target = const ObjectAccessTarget.missing();
     }
     if (instrumented &&
-        receiverType != const DynamicType() &&
+        receiverBound != const DynamicType() &&
         target.isInstanceMember) {
       instrumentation?.record(uriForInstrumentation, fileOffset, 'target',
           new InstrumentationValueForMember(target.member));
     }
 
     if (target.isUnresolved &&
-        receiverType is! DynamicType &&
+        receiverBound is! DynamicType &&
         includeExtensionMethods) {
-      Name otherName = name;
-      bool otherIsSetter;
-      if (name == indexGetName) {
-        // [] must be checked against []=.
-        otherName = indexSetName;
-        otherIsSetter = false;
-      } else if (name == indexSetName) {
-        // []= must be checked against [].
-        otherName = indexGetName;
-        otherIsSetter = false;
+      if (isReceiverTypePotentiallyNullable) {
+        // When the receiver type is potentially nullable we would have found
+        // the extension member above, if available. Therefore we know that we
+        // are in an erroneous case and instead look up the extension member on
+        // the non-nullable receiver bound but flag the found target as a
+        // nullable extension member access. This is done to provide the better
+        // error message that the extension member exists but that the access is
+        // invalid.
+        target = _findExtensionMember(
+            computeNonNullable(receiverBound), classNode, name, fileOffset,
+            setter: setter,
+            defaultTarget: target,
+            isPotentiallyNullableAccess: true);
       } else {
-        otherName = name;
-        otherIsSetter = !setter;
-      }
-
-      Member otherMember =
-          _getInterfaceMember(classNode, otherName, otherIsSetter, fileOffset);
-      if (otherMember != null) {
-        // If we're looking for `foo` and `foo=` can be found or vice-versa then
-        // extension methods should not be found.
-        return target;
-      }
-
-      ExtensionAccessCandidate bestSoFar;
-      List<ExtensionAccessCandidate> noneMoreSpecific = [];
-      library.forEachExtensionInScope((ExtensionBuilder extensionBuilder) {
-        MemberBuilder thisBuilder =
-            extensionBuilder.lookupLocalMemberByName(name, setter: setter);
-        MemberBuilder otherBuilder = extensionBuilder
-            .lookupLocalMemberByName(otherName, setter: otherIsSetter);
-        if ((thisBuilder != null && !thisBuilder.isStatic) ||
-            (otherBuilder != null && !otherBuilder.isStatic)) {
-          DartType onType;
-          DartType onTypeInstantiateToBounds;
-          List<DartType> inferredTypeArguments;
-          if (extensionBuilder.extension.typeParameters.isEmpty) {
-            onTypeInstantiateToBounds =
-                onType = extensionBuilder.extension.onType;
-            inferredTypeArguments = const <DartType>[];
-          } else {
-            List<TypeParameter> typeParameters =
-                extensionBuilder.extension.typeParameters;
-            inferredTypeArguments = inferExtensionTypeArguments(
-                extensionBuilder.extension, receiverType);
-            Substitution inferredSubstitution =
-                Substitution.fromPairs(typeParameters, inferredTypeArguments);
-
-            for (int index = 0; index < typeParameters.length; index++) {
-              TypeParameter typeParameter = typeParameters[index];
-              DartType typeArgument = inferredTypeArguments[index];
-              DartType bound =
-                  inferredSubstitution.substituteType(typeParameter.bound);
-              if (!typeSchemaEnvironment.isSubtypeOf(
-                  typeArgument, bound, SubtypeCheckMode.withNullabilities)) {
-                return;
-              }
-            }
-            onType = inferredSubstitution
-                .substituteType(extensionBuilder.extension.onType);
-            List<DartType> instantiateToBoundTypeArguments = calculateBounds(
-                typeParameters, coreTypes.objectClass, library.library);
-            Substitution instantiateToBoundsSubstitution =
-                Substitution.fromPairs(
-                    typeParameters, instantiateToBoundTypeArguments);
-            onTypeInstantiateToBounds = instantiateToBoundsSubstitution
-                .substituteType(extensionBuilder.extension.onType);
-          }
-
-          if (typeSchemaEnvironment.isSubtypeOf(
-              receiverType, onType, SubtypeCheckMode.ignoringNullabilities)) {
-            ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
-                thisBuilder ?? otherBuilder,
-                onType,
-                onTypeInstantiateToBounds,
-                thisBuilder != null &&
-                        !thisBuilder.isField &&
-                        !thisBuilder.isStatic
-                    ? new ObjectAccessTarget.extensionMember(
-                        setter
-                            ? thisBuilder.writeTarget
-                            : thisBuilder.invokeTarget,
-                        thisBuilder.readTarget,
-                        thisBuilder.kind,
-                        inferredTypeArguments)
-                    : const ObjectAccessTarget.missing(),
-                isPlatform:
-                    extensionBuilder.library.importUri.scheme == 'dart');
-            if (noneMoreSpecific.isNotEmpty) {
-              bool isMostSpecific = true;
-              for (ExtensionAccessCandidate other in noneMoreSpecific) {
-                bool isMoreSpecific =
-                    candidate.isMoreSpecificThan(typeSchemaEnvironment, other);
-                if (isMoreSpecific != true) {
-                  isMostSpecific = false;
-                  break;
-                }
-              }
-              if (isMostSpecific) {
-                bestSoFar = candidate;
-                noneMoreSpecific.clear();
-              } else {
-                noneMoreSpecific.add(candidate);
-              }
-            } else if (bestSoFar == null) {
-              bestSoFar = candidate;
-            } else {
-              bool isMoreSpecific = candidate.isMoreSpecificThan(
-                  typeSchemaEnvironment, bestSoFar);
-              if (isMoreSpecific == true) {
-                bestSoFar = candidate;
-              } else if (isMoreSpecific == null) {
-                noneMoreSpecific.add(bestSoFar);
-                noneMoreSpecific.add(candidate);
-                bestSoFar = null;
-              }
-            }
-          }
-        }
-      });
-      if (bestSoFar != null) {
-        target = bestSoFar.target;
-      } else {
-        if (noneMoreSpecific.isNotEmpty) {
-          target = new AmbiguousExtensionAccessTarget(noneMoreSpecific);
-        }
+        target = _findExtensionMember(
+            receiverBound, classNode, name, fileOffset,
+            setter: setter, defaultTarget: target);
       }
     }
     return target;
   }
 
-  /// True if [Object]'s member called [name] can be called with the arguments.
-  ///
-  /// Checks for the arity and the types of the arguments and tells if an
-  /// invocation of a method [name] on the receiver with static type [Object]
-  /// doesn't lead to a compile-time error.
-  bool matchesObjectMemberCall(
-      Name name,
-      List<DartType> typeArguments,
-      List<DartType> positionalArgumentTypes,
-      List<NamedType> namedArgumentTypes) {
-    ObjectAccessTarget target = findInterfaceMember(
-        coreTypes.objectNonNullableRawType, name, -1,
-        instrumented: false);
-    if (target.isUnresolved) return false;
-    return matchesMemberCall(target.member, typeArguments ?? const [],
-        positionalArgumentTypes ?? const [], namedArgumentTypes ?? const []);
-  }
-
-  /// True if [member] can be called with the arguments.
-  ///
-  /// Checks for the arity and the types of the arguments and tells if an
-  /// invocation of [member] doesn't lead to a compile-time error.
-  bool matchesMemberCall(
-      Member member,
-      List<DartType> typeArguments,
-      List<DartType> positionalArgumentTypes,
-      List<NamedType> namedArgumentTypes) {
-    FunctionNode function = member.function;
-    List<TypeParameter> typeParameters = function.typeParameters;
-    List<VariableDeclaration> positionalParameters =
-        function.positionalParameters;
-    List<VariableDeclaration> namedParameters = function.namedParameters;
-    if (typeParameters.length != typeArguments.length ||
-        positionalParameters.length < positionalArgumentTypes.length ||
-        namedParameters.length < namedArgumentTypes.length) {
-      // The number of arguments isn't compatible.
-      return false;
-    }
-
-    // Assume that both named parameters and named arguments are sorted
-    // lexicographically.
-    assert(namedParameters.isEmpty ||
-        namedParameters.skip(1).fold(
-                namedParameters[0],
-                (p, n) =>
-                    p != null && p.name.compareTo(n.name) <= 0 ? n : null) !=
-            null);
-    assert(namedArgumentTypes.isEmpty ||
-        namedArgumentTypes.skip(1).fold(
-                namedArgumentTypes[0],
-                (p, n) =>
-                    p != null && p.name.compareTo(n.name) <= 0 ? n : null) !=
-            null);
-
-    Substitution substitution = typeParameters.isEmpty
-        ? Substitution.empty
-        : Substitution.fromPairs(typeParameters, typeArguments);
-
-    {
-      int parameterIndex = 0;
-      int argumentIndex = 0;
-      while (parameterIndex < namedParameters.length &&
-          argumentIndex < namedArgumentTypes.length) {
-        VariableDeclaration parameter = namedParameters[parameterIndex];
-        NamedType argument = namedArgumentTypes[argumentIndex];
-        int compareResult = parameter.name.compareTo(argument.name);
-        if (compareResult == 0) {
-          if (!isAssignable(
-              substitution.substituteType(parameter.type), argument.type)) {
-            // Types aren't compatible.
-            return false;
-          }
-          ++parameterIndex;
-          ++argumentIndex;
-        } else if (compareResult < 0) {
-          if (parameter.isRequired) {
-            // A required parameter is skipped.
-            return false;
-          }
-          ++parameterIndex;
-        } else {
-          assert(compareResult > 0);
-          // Extra argument.
-          return false;
-        }
-      }
-    }
-    for (int i = 0; i < positionalArgumentTypes.length; ++i) {
-      VariableDeclaration parameter = positionalParameters[i];
-      DartType argument = positionalArgumentTypes[i];
-      if (!isAssignable(
-          substitution.substituteType(parameter.type), argument)) {
-        // Types aren't compatible.
-        return false;
-      }
-    }
-    for (int i = 0; i < typeArguments.length; ++i) {
-      TypeParameter parameter = typeParameters[i];
-      DartType argument = typeArguments[i];
-      if (!typeSchemaEnvironment.isSubtypeOf(
-          argument,
-          substitution.substituteType(parameter.bound),
-          library.isNonNullableByDefault
-              ? SubtypeCheckMode.withNullabilities
-              : SubtypeCheckMode.ignoringNullabilities)) {
-        // The type argument doesn't conform to the bound.
-        return false;
-      }
-    }
-    return true;
-  }
-
   /// If target is missing on a non-dynamic receiver, an error is reported
   /// using [errorTemplate] and an invalid expression is returned.
   Expression reportMissingInterfaceMember(
@@ -1365,6 +1338,7 @@
   DartType getGetterType(ObjectAccessTarget target, DartType receiverType) {
     switch (target.kind) {
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
         return receiverType;
       case ObjectAccessTargetKind.invalid:
         return const InvalidType();
@@ -1376,8 +1350,10 @@
       case ObjectAccessTargetKind.never:
         return const NeverType(Nullability.nonNullable);
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         return getGetterTypeForMemberTarget(target.member, receiverType);
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (target.extensionMethodKind) {
           case ProcedureKind.Method:
           case ProcedureKind.Operator:
@@ -1472,6 +1448,7 @@
       ObjectAccessTarget target, DartType receiverType) {
     switch (target.kind) {
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
         return _getFunctionType(receiverType);
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.dynamic:
@@ -1481,9 +1458,11 @@
       case ObjectAccessTargetKind.ambiguous:
         return unknownFunction;
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         return _getFunctionType(
             getGetterTypeForMemberTarget(target.member, receiverType));
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (target.extensionMethodKind) {
           case ProcedureKind.Method:
           case ProcedureKind.Operator:
@@ -1519,11 +1498,13 @@
   DartType getReturnType(ObjectAccessTarget target, DartType receiverType) {
     switch (target.kind) {
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         FunctionType functionType = _getFunctionType(
             getGetterTypeForMemberTarget(target.member, receiverType));
         return functionType.returnType;
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (target.extensionMethodKind) {
           case ProcedureKind.Operator:
             FunctionType functionType =
@@ -1545,6 +1526,7 @@
       case ObjectAccessTargetKind.invalid:
         return const InvalidType();
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.missing:
@@ -1558,6 +1540,7 @@
       ObjectAccessTarget target, DartType receiverType, int index) {
     switch (target.kind) {
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         FunctionType functionType = _getFunctionType(
             getGetterTypeForMemberTarget(target.member, receiverType));
         if (functionType.positionalParameters.length > index) {
@@ -1565,6 +1548,7 @@
         }
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         FunctionType functionType =
             target.member.function.computeFunctionType(library.nonNullable);
         if (functionType.positionalParameters.length > index + 1) {
@@ -1581,6 +1565,7 @@
       case ObjectAccessTargetKind.invalid:
         return const InvalidType();
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
@@ -1613,6 +1598,7 @@
   DartType getIndexKeyType(ObjectAccessTarget target, DartType receiverType) {
     switch (target.kind) {
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         FunctionType functionType = _getFunctionType(
             getGetterTypeForMemberTarget(target.member, receiverType));
         if (functionType.positionalParameters.length >= 1) {
@@ -1620,6 +1606,7 @@
         }
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (target.extensionMethodKind) {
           case ProcedureKind.Operator:
             FunctionType functionType =
@@ -1642,6 +1629,7 @@
       case ObjectAccessTargetKind.invalid:
         return const InvalidType();
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
@@ -1671,6 +1659,7 @@
       ObjectAccessTarget target, DartType receiverType) {
     switch (target.kind) {
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         FunctionType functionType = _getFunctionType(
             getGetterTypeForMemberTarget(target.member, receiverType));
         if (functionType.positionalParameters.length >= 2) {
@@ -1678,6 +1667,7 @@
         }
         break;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (target.extensionMethodKind) {
           case ProcedureKind.Operator:
             FunctionType functionType =
@@ -1700,6 +1690,7 @@
       case ObjectAccessTargetKind.invalid:
         return const InvalidType();
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.unresolved:
       case ObjectAccessTargetKind.dynamic:
       case ObjectAccessTargetKind.never:
@@ -1764,6 +1755,7 @@
       case ObjectAccessTargetKind.invalid:
         return const InvalidType();
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         Member interfaceMember = target.member;
         Class memberClass = interfaceMember.enclosingClass;
         DartType setterType;
@@ -1792,6 +1784,7 @@
         }
         return setterType;
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         switch (target.extensionMethodKind) {
           case ProcedureKind.Setter:
             FunctionType functionType =
@@ -1813,6 +1806,7 @@
         // TODO(johnniwinther): Compute the right setter type.
         return const DynamicType();
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
         break;
     }
     throw unhandled(target.runtimeType.toString(), 'getSetterType', null, null);
@@ -1890,10 +1884,27 @@
     Member equalsMember =
         findInterfaceMember(variable.type, equalsName, variable.fileOffset)
             .member;
+    // Ensure operator == member even for `Never`.
+    equalsMember ??= findInterfaceMember(const DynamicType(), equalsName, -1,
+            instrumented: false)
+        .member;
     return new NullAwareGuard(
         variable, variable.fileOffset, equalsMember, this);
   }
 
+  ExpressionInferenceResult wrapExpressionInferenceResultInProblem(
+      ExpressionInferenceResult result,
+      Message message,
+      int fileOffset,
+      int length,
+      {List<LocatedMessage> context}) {
+    return createNullAwareExpressionInferenceResult(
+        result.inferredType,
+        helper.wrapInProblem(
+            result.nullAwareAction, message, fileOffset, length),
+        result.nullAwareGuards);
+  }
+
   ExpressionInferenceResult createNullAwareExpressionInferenceResult(
       DartType inferredType,
       Expression expression,
@@ -2388,32 +2399,6 @@
         "Inferred return type $inferredType contains free variables."
         "Inferred function type: $calleeType.");
 
-    if (!isTopLevel && isNonNullableByDefault) {
-      if (receiverType != null &&
-          receiverType is! DynamicType &&
-          isPotentiallyNullable(receiverType, coreTypes.futureOrClass) &&
-          !matchesObjectMemberCall(targetName, inferredTypes,
-              positionalArgumentTypes, namedArgumentTypes)) {
-        if (isImplicitCall) {
-          return new WrapInProblemInferenceResult(
-              inferredType,
-              templateNullableExpressionCallError.withArguments(
-                  receiverType, isNonNullableByDefault),
-              offset,
-              noLength,
-              helper);
-        } else {
-          return new WrapInProblemInferenceResult(
-              inferredType,
-              templateNullableMethodCallError.withArguments(
-                  targetName.name, receiverType, isNonNullableByDefault),
-              offset,
-              targetName.name.length,
-              helper);
-        }
-      }
-    }
-
     return new SuccessfulInferenceResult(inferredType);
   }
 
@@ -2511,12 +2496,14 @@
       VariableDeclarationImpl formal = formals[i];
       if (formal.isImplicitlyTyped) {
         DartType inferredType;
-        if (formalTypesFromContext[i] == coreTypes.nullType) {
-          inferredType = coreTypes.objectRawType(library.nullable);
-        } else if (formalTypesFromContext[i] != null) {
-          inferredType = greatestClosure(
-              substitution.substituteType(formalTypesFromContext[i]),
-              bottomType);
+        if (formalTypesFromContext[i] != null) {
+          if (coreTypes.isBottom(formalTypesFromContext[i]) ||
+              coreTypes.isNull(formalTypesFromContext[i])) {
+            inferredType = coreTypes.objectRawType(library.nullable);
+          } else {
+            inferredType = computeGreatestClosure2(
+                substitution.substituteType(formalTypesFromContext[i]));
+          }
         } else {
           inferredType = const DynamicType();
         }
@@ -2628,7 +2615,7 @@
 
   StaticInvocation transformExtensionMethodInvocation(int fileOffset,
       ObjectAccessTarget target, Expression receiver, Arguments arguments) {
-    assert(target.isExtensionMember);
+    assert(target.isExtensionMember || target.isNullableExtensionMember);
     Procedure procedure = target.member;
     return engine.forest.createStaticInvocation(
         fileOffset,
@@ -2686,7 +2673,7 @@
         isImplicitCall: isImplicitCall);
     assert(name != equalsName);
     return createNullAwareExpressionInferenceResult(
-        result.inferredType,
+        const NeverType(Nullability.nonNullable),
         result.applyResult(new MethodInvocation(receiver, name, arguments)
           ..fileOffset = fileOffset),
         nullAwareGuards);
@@ -2736,19 +2723,36 @@
       List<VariableDeclaration> hoistedExpressions,
       {bool isImplicitCall}) {
     assert(isImplicitCall != null);
-    assert(target.isExtensionMember);
+    assert(target.isExtensionMember || target.isNullableExtensionMember);
     DartType calleeType = getGetterType(target, receiverType);
     FunctionType functionType = getFunctionType(target, receiverType);
 
     if (target.extensionMethodKind == ProcedureKind.Getter) {
       StaticInvocation staticInvocation = transformExtensionMethodInvocation(
           fileOffset, target, receiver, new Arguments.empty());
-      return inferMethodInvocation(fileOffset, nullAwareGuards,
-          staticInvocation, calleeType, callName, arguments, typeContext,
+      ExpressionInferenceResult result = inferMethodInvocation(
+          fileOffset,
+          nullAwareGuards,
+          staticInvocation,
+          calleeType,
+          callName,
+          arguments,
+          typeContext,
           hoistedExpressions: hoistedExpressions,
           isExpressionInvocation: false,
           isImplicitCall: true,
           implicitInvocationPropertyName: name);
+
+      if (!isTopLevel && target.isNullable) {
+        result = wrapExpressionInferenceResultInProblem(
+            result,
+            templateNullableExpressionCallError.withArguments(
+                receiverType, isNonNullableByDefault),
+            fileOffset,
+            noLength);
+      }
+
+      return result;
     } else {
       StaticInvocation staticInvocation = transformExtensionMethodInvocation(
           fileOffset, target, receiver, arguments);
@@ -2762,8 +2766,27 @@
         library.checkBoundsInStaticInvocation(staticInvocation,
             typeSchemaEnvironment, helper.uri, getTypeArgumentsInfo(arguments));
       }
-      return createNullAwareExpressionInferenceResult(result.inferredType,
-          result.applyResult(staticInvocation), nullAwareGuards);
+
+      Expression replacement = result.applyResult(staticInvocation);
+      if (!isTopLevel && target.isNullable) {
+        if (isImplicitCall) {
+          replacement = helper.wrapInProblem(
+              replacement,
+              templateNullableExpressionCallError.withArguments(
+                  receiverType, isNonNullableByDefault),
+              fileOffset,
+              noLength);
+        } else {
+          replacement = helper.wrapInProblem(
+              replacement,
+              templateNullableMethodCallError.withArguments(
+                  name.name, receiverType, isNonNullableByDefault),
+              fileOffset,
+              name.name.length);
+        }
+      }
+      return createNullAwareExpressionInferenceResult(
+          result.inferredType, replacement, nullAwareGuards);
     }
   }
 
@@ -2778,19 +2801,36 @@
       List<VariableDeclaration> hoistedExpressions,
       {bool isImplicitCall}) {
     assert(isImplicitCall != null);
-    assert(target.isCallFunction);
+    assert(target.isCallFunction || target.isNullableCallFunction);
     FunctionType functionType = getFunctionType(target, receiverType);
     InvocationInferenceResult result = inferInvocation(
         typeContext, fileOffset, functionType, arguments, callName,
         hoistedExpressions: hoistedExpressions,
         receiverType: receiverType,
         isImplicitCall: isImplicitCall);
+    Expression replacement = result.applyResult(
+        new MethodInvocation(receiver, callName, arguments)
+          ..fileOffset = fileOffset);
+    if (!isTopLevel && target.isNullableCallFunction) {
+      if (isImplicitCall) {
+        replacement = helper.wrapInProblem(
+            replacement,
+            templateNullableExpressionCallError.withArguments(
+                receiverType, isNonNullableByDefault),
+            fileOffset,
+            noLength);
+      } else {
+        replacement = helper.wrapInProblem(
+            replacement,
+            templateNullableMethodCallError.withArguments(
+                callName.name, receiverType, isNonNullableByDefault),
+            fileOffset,
+            callName.name.length);
+      }
+    }
     // TODO(johnniwinther): Check that type arguments against the bounds.
     return createNullAwareExpressionInferenceResult(
-        result.inferredType,
-        result.applyResult(new MethodInvocation(receiver, callName, arguments)
-          ..fileOffset = fileOffset),
-        nullAwareGuards);
+        result.inferredType, replacement, nullAwareGuards);
   }
 
   ExpressionInferenceResult _inferInstanceMethodInvocation(
@@ -2804,7 +2844,7 @@
       List<VariableDeclaration> hoistedExpressions,
       {bool isImplicitCall}) {
     assert(isImplicitCall != null);
-    assert(target.isInstanceMember);
+    assert(target.isInstanceMember || target.isNullableInstanceMember);
     Procedure method = target.member;
     assert(method.kind == ProcedureKind.Method,
         "Unexpected instance method $method");
@@ -2872,8 +2912,27 @@
         new MethodInvocation(receiver, methodName, arguments, method)
           ..fileOffset = fileOffset;
 
+    replacement = result.applyResult(replacement);
+    if (!isTopLevel && target.isNullable) {
+      if (isImplicitCall) {
+        replacement = helper.wrapInProblem(
+            replacement,
+            templateNullableExpressionCallError.withArguments(
+                receiverType, isNonNullableByDefault),
+            fileOffset,
+            noLength);
+      } else {
+        replacement = helper.wrapInProblem(
+            replacement,
+            templateNullableMethodCallError.withArguments(
+                methodName.name, receiverType, isNonNullableByDefault),
+            fileOffset,
+            methodName.name.length);
+      }
+    }
+
     return createNullAwareExpressionInferenceResult(
-        result.inferredType, result.applyResult(replacement), nullAwareGuards);
+        result.inferredType, replacement, nullAwareGuards);
   }
 
   ExpressionInferenceResult _inferInstanceGetterInvocation(
@@ -2887,7 +2946,7 @@
       List<VariableDeclaration> hoistedExpressions,
       {bool isExpressionInvocation}) {
     assert(isExpressionInvocation != null);
-    assert(target.isInstanceMember);
+    assert(target.isInstanceMember || target.isNullableInstanceMember);
     Procedure getter = target.member;
     assert(getter.kind == ProcedureKind.Getter);
 
@@ -2915,7 +2974,8 @@
     FunctionType functionType = getFunctionTypeForImplicitCall(calleeType);
 
     List<VariableDeclaration> locallyHoistedExpressions;
-    if (hoistedExpressions == null) {
+    if (hoistedExpressions == null && !isTopLevel) {
+      // We don't hoist in top-level inference.
       hoistedExpressions = locallyHoistedExpressions = <VariableDeclaration>[];
     }
     if (arguments.positional.isNotEmpty || arguments.named.isNotEmpty) {
@@ -2954,7 +3014,7 @@
         isImplicitCall: true,
         implicitInvocationPropertyName: getter.name);
 
-    if (isExpressionInvocation) {
+    if (!isTopLevel && isExpressionInvocation) {
       Expression error = helper.buildProblem(
           templateImplicitCallOfNonMethod.withArguments(
               receiverType, isNonNullableByDefault),
@@ -2962,6 +3022,16 @@
           noLength);
       return new ExpressionInferenceResult(const DynamicType(), error);
     }
+
+    if (!isTopLevel && target.isNullable) {
+      invocationResult = wrapExpressionInferenceResultInProblem(
+          invocationResult,
+          templateNullableExpressionCallError.withArguments(
+              receiverType, isNonNullableByDefault),
+          fileOffset,
+          noLength);
+    }
+
     if (!library.loader.target.backendTarget.supportsExplicitGetterCalls) {
       // TODO(johnniwinther): Remove this when dart2js/ddc supports explicit
       //  getter calls.
@@ -3021,14 +3091,15 @@
       List<VariableDeclaration> hoistedExpressions,
       {bool isExpressionInvocation}) {
     assert(isExpressionInvocation != null);
-    assert(target.isInstanceMember);
+    assert(target.isInstanceMember || target.isNullableInstanceMember);
     Field field = target.member;
 
     DartType calleeType = getGetterType(target, receiverType);
     FunctionType functionType = getFunctionTypeForImplicitCall(calleeType);
 
     List<VariableDeclaration> locallyHoistedExpressions;
-    if (hoistedExpressions == null) {
+    if (hoistedExpressions == null && !isTopLevel) {
+      // We don't hoist in top-level inference.
       hoistedExpressions = locallyHoistedExpressions = <VariableDeclaration>[];
     }
     if (arguments.positional.isNotEmpty || arguments.named.isNotEmpty) {
@@ -3068,7 +3139,7 @@
         hoistedExpressions: hoistedExpressions,
         implicitInvocationPropertyName: field.name);
 
-    if (isExpressionInvocation) {
+    if (!isTopLevel && isExpressionInvocation) {
       Expression error = helper.buildProblem(
           templateImplicitCallOfNonMethod.withArguments(
               receiverType, isNonNullableByDefault),
@@ -3076,6 +3147,16 @@
           noLength);
       return new ExpressionInferenceResult(const DynamicType(), error);
     }
+
+    if (!isTopLevel && target.isNullable) {
+      invocationResult = wrapExpressionInferenceResultInProblem(
+          invocationResult,
+          templateNullableExpressionCallError.withArguments(
+              receiverType, isNonNullableByDefault),
+          fileOffset,
+          noLength);
+    }
+
     if (!library.loader.target.backendTarget.supportsExplicitGetterCalls) {
       // TODO(johnniwinther): Remove this when dart2js/ddc supports explicit
       //  getter calls.
@@ -3115,11 +3196,13 @@
       List<VariableDeclaration> hoistedExpressions}) {
     assert(isExpressionInvocation != null);
     assert(isImplicitCall != null);
+
     ObjectAccessTarget target = findInterfaceMember(
         receiverType, name, fileOffset,
         instrumented: true, includeExtensionMethods: true);
     switch (target.kind) {
       case ObjectAccessTargetKind.instanceMember:
+      case ObjectAccessTargetKind.nullableInstanceMember:
         Member member = target.member;
         if (member is Procedure) {
           if (member.kind == ProcedureKind.Getter) {
@@ -3159,10 +3242,12 @@
         }
         break;
       case ObjectAccessTargetKind.callFunction:
+      case ObjectAccessTargetKind.nullableCallFunction:
         return _inferFunctionInvocation(fileOffset, nullAwareGuards, receiver,
             receiverType, target, arguments, typeContext, hoistedExpressions,
             isImplicitCall: isImplicitCall);
       case ObjectAccessTargetKind.extensionMember:
+      case ObjectAccessTargetKind.nullableExtensionMember:
         return _inferExtensionInvocation(
             fileOffset,
             nullAwareGuards,
@@ -3250,7 +3335,7 @@
 
   bool isOverloadedArithmeticOperatorAndType(
       ObjectAccessTarget target, DartType receiverType) {
-    return target.isInstanceMember &&
+    return (target.isInstanceMember || target.isNullableInstanceMember) &&
         target.member is Procedure &&
         typeSchemaEnvironment.isOverloadedArithmeticOperatorAndType(
             target.member, receiverType);
@@ -4135,14 +4220,48 @@
 }
 
 enum ObjectAccessTargetKind {
+  /// A valid access to a statically known instance member. The access is
+  /// either non-nullable or potentially nullable on a `Object` member.
   instanceMember,
+
+  /// A potentially nullable access to a statically known instance member. This
+  /// is an erroneous case and a compile-time error is reported.
+  nullableInstanceMember,
+
+  /// A (non-nullable) access to the `.call` method of a function. This is used
+  /// for access on `Function` and on function types.
   callFunction,
+
+  /// A potentially nullable access to the `.call` method of a function. This is
+  /// an erroneous case and a compile-time error is reported.
+  nullableCallFunction,
+
+  /// A valid access to an extension member.
   extensionMember,
+
+  /// A potentially nullable access to an extension member on an extension of
+  /// a non-nullable type. This is an erroneous case and a compile-time error is
+  /// reported.
+  nullableExtensionMember,
+
+  /// An access on a receiver of type `dynamic`.
   dynamic,
+
+  /// An access on a receiver of type `Never`.
   never,
+
+  /// An access on a receiver of an invalid type. This case is the result of
+  /// a previously report error and no error is report this case.
   invalid,
+
+  /// An access to a statically unknown instance member. This is an erroneous
+  /// case and a compile-time error is reported.
   missing,
+
+  /// An access to multiple extension members, none of which are most specific.
+  /// This is an erroneous case and a compile-time error is reported.
   ambiguous,
+
   // TODO(johnniwinther): Remove this.
   unresolved,
 }
@@ -4156,10 +4275,15 @@
   const ObjectAccessTarget.internal(this.kind, this.member);
 
   /// Creates an access to the instance [member].
-  factory ObjectAccessTarget.interfaceMember(Member member) {
+  factory ObjectAccessTarget.interfaceMember(Member member,
+      {bool isPotentiallyNullable}) {
     assert(member != null);
+    assert(isPotentiallyNullable != null);
     return new ObjectAccessTarget.internal(
-        ObjectAccessTargetKind.instanceMember, member);
+        isPotentiallyNullable
+            ? ObjectAccessTargetKind.nullableInstanceMember
+            : ObjectAccessTargetKind.instanceMember,
+        member);
   }
 
   /// Creates an access to the extension [member].
@@ -4167,13 +4291,19 @@
       Member member,
       Member tearoffTarget,
       ProcedureKind kind,
-      List<DartType> inferredTypeArguments) = ExtensionAccessTarget;
+      List<DartType> inferredTypeArguments,
+      {bool isPotentiallyNullable}) = ExtensionAccessTarget;
 
   /// Creates an access to a 'call' method on a function, i.e. a function
   /// invocation.
   const ObjectAccessTarget.callFunction()
       : this.internal(ObjectAccessTargetKind.callFunction, null);
 
+  /// Creates an access to a 'call' method on a potentially nullable function,
+  /// i.e. a function invocation.
+  const ObjectAccessTarget.nullableCallFunction()
+      : this.internal(ObjectAccessTargetKind.nullableCallFunction, null);
+
   /// Creates an access with no known target.
   const ObjectAccessTarget.unresolved()
       : this.internal(ObjectAccessTargetKind.unresolved, null);
@@ -4207,6 +4337,11 @@
   /// Returns `true` if this is an access to the 'call' method on a function.
   bool get isCallFunction => kind == ObjectAccessTargetKind.callFunction;
 
+  /// Returns `true` if this is an access to the 'call' method on a potentially
+  /// nullable function.
+  bool get isNullableCallFunction =>
+      kind == ObjectAccessTargetKind.nullableCallFunction;
+
   /// Returns `true` if this is an access without a known target.
   bool get isUnresolved =>
       kind == ObjectAccessTargetKind.unresolved ||
@@ -4227,6 +4362,23 @@
   /// occurs when an implicit extension access is ambiguous.
   bool get isAmbiguous => kind == ObjectAccessTargetKind.ambiguous;
 
+  /// Returns `true` if this is an access to an instance member on a potentially
+  /// nullable receiver.
+  bool get isNullableInstanceMember =>
+      kind == ObjectAccessTargetKind.nullableInstanceMember;
+
+  /// Returns `true` if this is an access to an instance member on a potentially
+  /// nullable receiver.
+  bool get isNullableExtensionMember =>
+      kind == ObjectAccessTargetKind.nullableExtensionMember;
+
+  /// Returns `true` if this is an access to an instance member on a potentially
+  /// nullable receiver.
+  bool get isNullable =>
+      isNullableInstanceMember ||
+      isNullableCallFunction ||
+      isNullableExtensionMember;
+
   /// Returns the candidates for an ambiguous extension access.
   List<ExtensionAccessCandidate> get candidates =>
       throw new UnsupportedError('ObjectAccessTarget.candidates');
@@ -4264,8 +4416,13 @@
   final List<DartType> inferredExtensionTypeArguments;
 
   ExtensionAccessTarget(Member member, this.tearoffTarget,
-      this.extensionMethodKind, this.inferredExtensionTypeArguments)
-      : super.internal(ObjectAccessTargetKind.extensionMember, member);
+      this.extensionMethodKind, this.inferredExtensionTypeArguments,
+      {bool isPotentiallyNullable: false})
+      : super.internal(
+            isPotentiallyNullable
+                ? ObjectAccessTargetKind.nullableExtensionMember
+                : ObjectAccessTargetKind.extensionMember,
+            member);
 
   @override
   String toString() =>
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 94ac593..e05eba1 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
@@ -94,7 +94,7 @@
 
   @override
   String toStringInternal() {
-    return "";
+    return "<unknown-type>";
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
index 75e3d42..6401112 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
@@ -20,13 +20,9 @@
 ///
 /// Note that the greatest closure of a type schema is always a supertype of any
 /// type which matches the schema.
-DartType greatestClosure(DartType schema, DartType bottomType) {
-  assert(bottomType == const NeverType(Nullability.nonNullable) ||
-      bottomType is InterfaceType &&
-          bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
-          bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
-          bottomType.classNode.name == "Null");
-  return _TypeSchemaEliminationVisitor.run(false, schema, bottomType);
+DartType greatestClosure(
+    DartType schema, DartType topType, DartType bottomType) {
+  return _TypeSchemaEliminationVisitor.run(false, schema, topType, bottomType);
 }
 
 /// Returns the least closure of the given type [schema] with respect to `?`.
@@ -42,13 +38,8 @@
 ///
 /// Note that the least closure of a type schema is always a subtype of any type
 /// which matches the schema.
-DartType leastClosure(DartType schema, DartType bottomType) {
-  assert(bottomType == const NeverType(Nullability.nonNullable) ||
-      bottomType is InterfaceType &&
-          bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
-          bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
-          bottomType.classNode.name == "Null");
-  return _TypeSchemaEliminationVisitor.run(true, schema, bottomType);
+DartType leastClosure(DartType schema, DartType topType, DartType bottomType) {
+  return _TypeSchemaEliminationVisitor.run(true, schema, topType, bottomType);
 }
 
 /// Visitor that computes least and greatest closures of a type schema.
@@ -57,11 +48,13 @@
 /// type, otherwise it returns the result of substituting `?` with `Null` or
 /// `Object`, as appropriate.
 class _TypeSchemaEliminationVisitor extends ReplacementVisitor {
+  final DartType topType;
   final DartType bottomType;
 
   bool isLeastClosure;
 
-  _TypeSchemaEliminationVisitor(this.isLeastClosure, this.bottomType);
+  _TypeSchemaEliminationVisitor(
+      this.isLeastClosure, this.topType, this.bottomType);
 
   void changeVariance() {
     isLeastClosure = !isLeastClosure;
@@ -70,7 +63,7 @@
   @override
   DartType defaultDartType(DartType node) {
     if (node is UnknownType) {
-      return isLeastClosure ? bottomType : const DynamicType();
+      return isLeastClosure ? bottomType : topType;
     }
     return null;
   }
@@ -78,10 +71,21 @@
   /// Runs an instance of the visitor on the given [schema] and returns the
   /// resulting type.  If the schema contains no instances of `?`, the original
   /// schema object is returned to avoid unnecessary allocation.
-  static DartType run(
-      bool isLeastClosure, DartType schema, DartType bottomType) {
+  static DartType run(bool isLeastClosure, DartType schema, DartType topType,
+      DartType bottomType) {
+    assert(topType == const DynamicType() ||
+        topType is InterfaceType &&
+            topType.nullability == Nullability.nullable &&
+            topType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+            topType.classNode.enclosingLibrary.importUri.path == "core" &&
+            topType.classNode.name == "Object");
+    assert(bottomType == const NeverType(Nullability.nonNullable) ||
+        bottomType is InterfaceType &&
+            bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+            bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
+            bottomType.classNode.name == "Null");
     _TypeSchemaEliminationVisitor visitor =
-        new _TypeSchemaEliminationVisitor(isLeastClosure, bottomType);
+        new _TypeSchemaEliminationVisitor(isLeastClosure, topType, bottomType);
     DartType result = schema.accept(visitor);
     assert(visitor.isLeastClosure == isLeastClosure);
     return result ?? schema;
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 c0a489b..05199b3 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
@@ -102,7 +102,9 @@
 
 class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment
     with StandardBounds {
-  TypeSchemaEnvironment(CoreTypes coreTypes, ClassHierarchy hierarchy)
+  final ClassHierarchy hierarchy;
+
+  TypeSchemaEnvironment(CoreTypes coreTypes, this.hierarchy)
       : super(coreTypes, hierarchy);
 
   Class get functionClass => coreTypes.functionClass;
@@ -364,7 +366,7 @@
       unwrappedSupertype =
           (unwrappedSupertype as InterfaceType).typeArguments.single;
     }
-    if (subtype == coreTypes.nullType && unwrappedSupertype is UnknownType) {
+    if (unwrappedSupertype is UnknownType) {
       return const IsSubtypeOf.always();
     }
     return super.performNullabilityAwareSubtypeCheck(subtype, supertype);
@@ -432,11 +434,11 @@
       // e.g. `Iterable<?>`
       if (constraint.lower is! UnknownType) {
         return grounded
-            ? leastClosure(constraint.lower, bottomType)
+            ? leastClosure(constraint.lower, const DynamicType(), bottomType)
             : constraint.lower;
       } else {
         return grounded
-            ? greatestClosure(constraint.upper, bottomType)
+            ? greatestClosure(constraint.upper, const DynamicType(), bottomType)
             : constraint.upper;
       }
     } else {
@@ -448,11 +450,11 @@
       // e.g. `Iterable<?>`
       if (constraint.upper is! UnknownType) {
         return grounded
-            ? greatestClosure(constraint.upper, bottomType)
+            ? greatestClosure(constraint.upper, const DynamicType(), bottomType)
             : constraint.upper;
       } else {
         return grounded
-            ? leastClosure(constraint.lower, bottomType)
+            ? leastClosure(constraint.lower, const DynamicType(), bottomType)
             : constraint.lower;
       }
     }
diff --git a/pkg/front_end/lib/src/fasta/util/textual_outline.dart b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
index 5ff9bc4..4f705d0 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -9,9 +9,6 @@
 import 'package:_fe_analyzer_shared/src/parser/class_member_parser.dart'
     show ClassMemberParser;
 
-import 'package:_fe_analyzer_shared/src/parser/declaration_kind.dart'
-    show DeclarationKind;
-
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
     show ErrorToken, LanguageVersionToken, Scanner;
 
@@ -22,73 +19,335 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
 
-String textualOutline(List<int> rawBytes, {bool makeMoreReadable: false}) {
+// TODO: Sort imports.
+
+class _TextualOutlineState {
+  bool prevTokenKnown = false;
+  Token currentElementEnd;
+  List<String> currentChunk = new List<String>();
+  List<String> outputLines = new List<String>();
+
+  final bool performModelling;
+  String indent = "";
+  _TextualOutlineState(this.performModelling);
+}
+
+String textualOutline(List<int> rawBytes,
+    {bool throwOnUnexpected: false, bool performModelling: false}) {
   // TODO(jensj): We need to specify the scanner settings to match that of the
   // compiler!
   Uint8List bytes = new Uint8List(rawBytes.length + 1);
   bytes.setRange(0, rawBytes.length, rawBytes);
 
-  StringBuffer sb = new StringBuffer();
+  // Idea:
+  // * Chunks are entities, e.g. whole classes, whole procedures etc.
+  // * It could also be an "unknown" batch of tokens.
+  // * currentChunk is a temporary buffer where we add chunks in a "run".
+  // * Depending on whether we know what the previous token (and thus chunk) is
+  //   or not, and what the current token (and thus chunk) is, we either flush
+  //   the currentChunk buffer or not.
+  // * The idea being, that if we add 3 chunks we know and then are about to add
+  //   one we don't know, we can sort the 3 chunks we do know and output them.
+  //   But when we go from unknown to known, we don't sort before outputting.
+
+  _TextualOutlineState state = new _TextualOutlineState(performModelling);
+
+  TokenPrinter tokenPrinter = new TokenPrinter();
 
   Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: false,
       languageVersionChanged:
           (Scanner scanner, LanguageVersionToken languageVersion) {
-    sb.writeln("// @dart = ${languageVersion.major}.${languageVersion.minor}");
+    flush(state, isSortable: false);
+    state.prevTokenKnown = false;
+    state.outputLines
+        .add("// @dart = ${languageVersion.major}.${languageVersion.minor}");
   });
   Token firstToken = scanner.tokenize();
-  if (firstToken == null) return null;
-  Token token = firstToken;
+  if (firstToken == null) {
+    if (throwOnUnexpected) throw "firstToken is null";
+    return null;
+  }
 
-  EndOffsetListener listener = new EndOffsetListener();
+  TextualOutlineListener listener = new TextualOutlineListener();
   ClassMemberParser classMemberParser = new ClassMemberParser(listener);
   classMemberParser.parseUnit(firstToken);
 
-  bool printed = false;
-  int endOfLast = -1;
-  bool addLinebreak = false;
+  Token token = firstToken;
   while (token != null) {
     if (token is ErrorToken) {
       return null;
     }
-    if (addLinebreak) {
-      sb.write("\n");
-    } else if (printed && token.offset > endOfLast) {
-      sb.write(" ");
-    }
-    addLinebreak = false;
-
-    sb.write(token.lexeme);
-    printed = true;
-    endOfLast = token.end;
-    if (makeMoreReadable) {
-      if (token.lexeme == ";") {
-        addLinebreak = true;
-      } else if (token.endGroup != null &&
-          (listener.nonClassEndOffsets.contains(token.endGroup.offset) ||
-              listener.classEndOffsets.contains(token.endGroup.offset))) {
-        addLinebreak = true;
-      } else if (listener.nonClassEndOffsets.contains(token.offset) ||
-          listener.classEndOffsets.contains(token.offset)) {
-        addLinebreak = true;
-      }
-    }
-
     if (token.isEof) break;
 
-    if (token.endGroup != null &&
-        listener.nonClassEndOffsets.contains(token.endGroup.offset)) {
-      token = token.endGroup;
+    if (listener.classStartToFinish.containsKey(token)) {
+      if (state.prevTokenKnown) {
+        // TODO: Assert this instead.
+        if (!tokenPrinter.isEmpty) {
+          throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+        }
+      } else if (!tokenPrinter.isEmpty) {
+        // We're ending a streak of unknown: Output, and flush,
+        // but it's not sortable.
+        tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+        flush(state, isSortable: false);
+      }
+
+      Token currentClassEnd = listener.classStartToFinish[token];
+      String classContent = _textualizeClass(
+          listener, token, currentClassEnd, state,
+          throwOnUnexpected: throwOnUnexpected);
+      if (classContent == null) return null;
+      state.currentChunk.add(classContent);
+      token = currentClassEnd.next;
+      state.prevTokenKnown = true;
+      assert(tokenPrinter.isEmpty);
+      continue;
+    }
+
+    token = _textualizeNonClassEntriesInsideLoop(
+        listener, token, state, throwOnUnexpected, tokenPrinter);
+    if (token == null) return null;
+  }
+  _textualizeAfterLoop(state, tokenPrinter);
+  return state.outputLines.join("\n\n");
+}
+
+Token _textualizeNonClassEntriesInsideLoop(
+    TextualOutlineListener listener,
+    Token token,
+    _TextualOutlineState state,
+    bool throwOnUnexpected,
+    TokenPrinter tokenPrinter) {
+  if (listener.elementStartToFinish.containsKey(token)) {
+    if (state.currentElementEnd != null) {
+      if (throwOnUnexpected) throw "Element in element";
+      return null;
+    }
+    if (state.prevTokenKnown) {
+      if (!tokenPrinter.isEmpty) {
+        throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+      }
+    } else if (!tokenPrinter.isEmpty) {
+      // We're ending a streak of unknown: Output, and flush,
+      // but it's not sortable.
+      tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+      flush(state, isSortable: false);
+    }
+    state.currentElementEnd = listener.elementStartToFinish[token];
+    state.prevTokenKnown = true;
+  } else if (state.currentElementEnd == null &&
+      listener.metadataStartToFinish.containsKey(token)) {
+    if (state.prevTokenKnown) {
+      if (!tokenPrinter.isEmpty) {
+        throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+      }
+    } else if (!tokenPrinter.isEmpty) {
+      // We're ending a streak of unknown: Output, and flush,
+      // but it's not sortable.
+      tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+      flush(state, isSortable: false);
+    }
+    state.currentElementEnd = listener.metadataStartToFinish[token];
+    state.prevTokenKnown = true;
+  }
+
+  if (state.currentElementEnd == null && state.prevTokenKnown) {
+    // We're ending a streak of known stuff.
+    if (!tokenPrinter.isEmpty) {
+      throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+    }
+    flush(state, isSortable: true);
+    state.prevTokenKnown = false;
+  } else {
+    if (state.currentElementEnd == null) {
+      if (state.prevTokenKnown) {
+        // known -> unknown.
+        throw "This case was apparently not handled above.";
+      } else {
+        // OK: Streak of unknown.
+      }
     } else {
-      token = token.next;
+      if (state.prevTokenKnown) {
+        // OK: Streak of known.
+      } else {
+        // unknown -> known: This should have been flushed above.
+        if (!tokenPrinter.isEmpty) {
+          throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+        }
+      }
     }
   }
 
-  return sb.toString();
+  tokenPrinter.print(token);
+
+  if (token == state.currentElementEnd) {
+    state.currentElementEnd = null;
+    tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+  }
+
+  if (token.endGroup != null &&
+      listener.nonClassEndOffsets.contains(token.endGroup.offset)) {
+    token = token.endGroup;
+    tokenPrinter.nextTokenIsEndGroup = true;
+  } else {
+    token = token.next;
+  }
+  return token;
+}
+
+void _textualizeAfterLoop(
+    _TextualOutlineState state, TokenPrinter tokenPrinter) {
+  // We're done, so we're logically at an unknown token.
+  if (state.prevTokenKnown) {
+    // We're ending a streak of known stuff.
+    if (!tokenPrinter.isEmpty) {
+      throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+    }
+    flush(state, isSortable: true);
+    state.prevTokenKnown = false;
+  } else {
+    // Streak of unknown.
+    tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+    flush(state, isSortable: false);
+    state.prevTokenKnown = false;
+  }
+}
+
+void flush(_TextualOutlineState state, {bool isSortable}) {
+  assert(isSortable != null);
+  if (state.currentChunk.isEmpty) return;
+  if (isSortable) {
+    state.currentChunk = mergeAndSort(state.currentChunk, state.indent,
+        isModelling: state.performModelling);
+  }
+  if (state.indent == "") {
+    state.outputLines.addAll(state.currentChunk);
+  } else {
+    for (int i = 0; i < state.currentChunk.length; i++) {
+      state.outputLines.add("${state.indent}${state.currentChunk[i]}");
+    }
+  }
+  state.currentChunk.clear();
+}
+
+List<String> mergeAndSort(List<String> data, String indent,
+    {bool isModelling}) {
+  assert(isModelling != null);
+  // If not modelling, don't sort.
+  if (!isModelling) return data;
+
+  bool hasAnnotations = false;
+  for (int i = 0; i < data.length - 1; i++) {
+    String element = data[i];
+    if (element.startsWith("@")) {
+      hasAnnotations = true;
+      break;
+    }
+  }
+  if (!hasAnnotations) {
+    data.sort();
+    return data;
+  }
+
+  // There's annotations: Merge them with the owner.
+  List<String> merged = new List<String>();
+  StringBuffer sb = new StringBuffer();
+  for (int i = 0; i < data.length; i++) {
+    String element = data[i];
+    if (element.startsWith("@")) {
+      if (sb.length > 0) sb.write(indent);
+      sb.writeln(element);
+    } else {
+      if (sb.length > 0) sb.write(indent);
+      sb.write(element);
+      merged.add(sb.toString());
+      sb.clear();
+    }
+  }
+  if (sb.length > 0) {
+    merged.add(sb.toString());
+    sb.clear();
+  }
+
+  merged.sort();
+  return merged;
+}
+
+class TokenPrinter {
+  bool nextTokenIsEndGroup = false;
+  int _endOfLast = -1;
+  StringBuffer _sb = new StringBuffer();
+
+  String get content => _sb.toString();
+
+  bool get isEmpty => _sb.isEmpty;
+
+  void clear() {
+    _endOfLast = -1;
+    _sb.clear();
+  }
+
+  void addAndClearIfHasContent(List<String> list) {
+    if (_sb.length > 0) {
+      list.add(_sb.toString());
+      clear();
+    }
+  }
+
+  void print(Token token) {
+    if (_sb.isNotEmpty && (token.offset > _endOfLast || nextTokenIsEndGroup)) {
+      _sb.write(" ");
+    }
+
+    _sb.write(token.lexeme);
+    _endOfLast = token.end;
+    nextTokenIsEndGroup = false;
+  }
+
+  String toString() {
+    throw new UnsupportedError("toString");
+  }
+}
+
+String _textualizeClass(TextualOutlineListener listener, Token beginToken,
+    Token endToken, _TextualOutlineState originalState,
+    {bool throwOnUnexpected: false, bool model: false}) {
+  Token token = beginToken;
+  TokenPrinter tokenPrinter = new TokenPrinter();
+  // Class header.
+  while (token != endToken) {
+    tokenPrinter.print(token);
+    if (token.endGroup == endToken) {
+      token = token.next;
+      break;
+    }
+    token = token.next;
+  }
+  _TextualOutlineState state =
+      new _TextualOutlineState(originalState.performModelling);
+  tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+  flush(state, isSortable: false);
+
+  state.indent = "  ";
+  while (token != endToken) {
+    token = _textualizeNonClassEntriesInsideLoop(
+        listener, token, state, throwOnUnexpected, tokenPrinter);
+    if (token == null) return null;
+  }
+  _textualizeAfterLoop(state, tokenPrinter);
+
+  state.indent = "";
+  tokenPrinter.nextTokenIsEndGroup = true;
+  tokenPrinter.print(token);
+  tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+  flush(state, isSortable: false);
+  return state.outputLines.join("\n");
 }
 
 main(List<String> args) {
   File f = new File(args[0]);
-  String outline = textualOutline(f.readAsBytesSync(), makeMoreReadable: true);
+  String outline = textualOutline(f.readAsBytesSync(),
+      throwOnUnexpected: true, performModelling: true);
   if (args.length > 1 && args[1] == "--overwrite") {
     f.writeAsStringSync(outline);
   } else {
@@ -96,35 +355,88 @@
   }
 }
 
-class EndOffsetListener extends DirectiveListener {
+class TextualOutlineListener extends DirectiveListener {
   Set<int> nonClassEndOffsets = new Set<int>();
-  Set<int> classEndOffsets = new Set<int>();
+  Map<Token, Token> classStartToFinish = {};
+  Map<Token, Token> elementStartToFinish = {};
+  Map<Token, Token> metadataStartToFinish = {};
 
   @override
   void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
     nonClassEndOffsets.add(endToken.offset);
+    elementStartToFinish[beginToken] = endToken;
   }
 
   @override
   void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
     nonClassEndOffsets.add(endToken.offset);
+    elementStartToFinish[beginToken] = endToken;
   }
 
   @override
   void endClassFactoryMethod(
       Token beginToken, Token factoryKeyword, Token endToken) {
     nonClassEndOffsets.add(endToken.offset);
-  }
-
-  @override
-  void endClassOrMixinBody(
-      DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
-    classEndOffsets.add(endToken.offset);
+    elementStartToFinish[beginToken] = endToken;
   }
 
   @override
   void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
     // Allow native functions.
   }
+
+  @override
+  void endClassFields(Token staticToken, Token covariantToken, Token lateToken,
+      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
+    elementStartToFinish[beginToken] = endToken;
+  }
+
+  @override
+  void endTopLevelFields(
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    elementStartToFinish[beginToken] = endToken;
+  }
+
+  void endFunctionTypeAlias(
+      Token typedefKeyword, Token equals, Token endToken) {
+    elementStartToFinish[typedefKeyword] = endToken;
+  }
+
+  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+    elementStartToFinish[enumKeyword] = leftBrace.endGroup;
+  }
+
+  // @override
+  // void endLibraryName(Token libraryKeyword, Token semicolon) {
+  //   elementStartToFinish[libraryKeyword] = semicolon;
+  // }
+
+  @override
+  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
+    // Metadata's endToken is the one *after* the actual end of the metadata.
+    metadataStartToFinish[beginToken] = endToken.previous;
+  }
+
+  @override
+  void endClassDeclaration(Token beginToken, Token endToken) {
+    classStartToFinish[beginToken] = endToken;
+  }
+
+  @override
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
+    classStartToFinish[mixinKeyword] = endToken;
+  }
+
+  @override
+  void endExtensionDeclaration(
+      Token extensionKeyword, Token onKeyword, Token endToken) {
+    classStartToFinish[extensionKeyword] = endToken;
+  }
 }
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 09a048d..ff03fe7 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -462,6 +462,9 @@
 
   void visitNeverType(NeverType node) {
     sb.write('Never');
+    if (node.nullability != Nullability.nonNullable) {
+      sb.write(nullabilityToText(node.nullability, typeRepresentation));
+    }
   }
 
   void visitInterfaceType(InterfaceType node) {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 7f5e3f8..5558bde 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -122,6 +122,8 @@
 ConstEvalNullValue/example: Fail
 ConstEvalStartingPoint/analyzerCode: Fail # This is just used for displaying the starting point.
 ConstEvalStartingPoint/example: Fail # This is just used for displaying the starting point.
+ConstEvalTruncateError/analyzerCode: Fail
+ConstEvalTruncateError/example: Fail
 ConstEvalUnevaluated/analyzerCode: Fail
 ConstEvalUnevaluated/example: Fail
 ConstEvalZeroDivisor/example: Fail
@@ -163,8 +165,6 @@
 DirectiveAfterDeclaration/part_wrapped_script2: Fail
 DirectiveAfterDeclaration/script1: Fail
 DirectiveAfterDeclaration/script2: Fail
-DuplicateDeferred/example: Fail
-DuplicatePrefix/example: Fail
 DuplicatedDeclarationUse/analyzerCode: Fail # No corresponding analyzer code.
 DuplicatedDeclarationUse/part_wrapped_script1: Fail
 DuplicatedDeclarationUse/part_wrapped_script2: Fail
@@ -172,6 +172,7 @@
 DuplicatedDeclarationUse/script2: Fail # Wrong error.
 DuplicatedDefinition/analyzerCode: Fail
 DuplicatedDefinition/example: Fail
+DuplicateDeferred/example: Fail
 DuplicatedExport/part_wrapped_script: Fail # Exporting file in the (now) part.
 DuplicatedExportInType/analyzerCode: Fail
 DuplicatedExportInType/example: Fail
@@ -183,6 +184,7 @@
 DuplicatedName/example: Fail
 DuplicatedNamedArgument/example: Fail
 DuplicatedParameterName/example: Fail
+DuplicatePrefix/example: Fail
 Encoding/analyzerCode: Fail
 EnumConstantSameNameAsEnclosing/example: Fail
 EnumInstantiation/example: Fail
@@ -254,6 +256,7 @@
 ExternalFactoryRedirection/example: Fail
 ExternalFactoryWithBody/part_wrapped_script1: Fail
 ExternalFactoryWithBody/script1: Fail
+ExtraneousModifier/part_wrapped_script1: Fail
 ExtraneousModifier/part_wrapped_script10: Fail
 ExtraneousModifier/part_wrapped_script11: Fail
 ExtraneousModifier/part_wrapped_script12: Fail
@@ -262,15 +265,15 @@
 ExtraneousModifier/part_wrapped_script17: Fail
 ExtraneousModifier/part_wrapped_script18: Fail
 ExtraneousModifier/part_wrapped_script19: Fail
-ExtraneousModifier/part_wrapped_script1: Fail
-ExtraneousModifier/part_wrapped_script20: Fail
 ExtraneousModifier/part_wrapped_script2: Fail
+ExtraneousModifier/part_wrapped_script20: Fail
 ExtraneousModifier/part_wrapped_script3: Fail
 ExtraneousModifier/part_wrapped_script4: Fail
 ExtraneousModifier/part_wrapped_script5: Fail
 ExtraneousModifier/part_wrapped_script7: Fail
 ExtraneousModifier/part_wrapped_script8: Fail
 ExtraneousModifier/part_wrapped_script9: Fail
+ExtraneousModifier/script1: Fail
 ExtraneousModifier/script10: Fail
 ExtraneousModifier/script11: Fail
 ExtraneousModifier/script12: Fail
@@ -279,9 +282,8 @@
 ExtraneousModifier/script17: Fail
 ExtraneousModifier/script18: Fail
 ExtraneousModifier/script19: Fail
-ExtraneousModifier/script1: Fail
-ExtraneousModifier/script20: Fail
 ExtraneousModifier/script2: Fail
+ExtraneousModifier/script20: Fail
 ExtraneousModifier/script3: Fail
 ExtraneousModifier/script4: Fail
 ExtraneousModifier/script5: Fail
@@ -377,10 +379,10 @@
 IncompatibleRedirecteeFunctionType/part_wrapped_script6: Fail
 IncompatibleRedirecteeFunctionType/script6: Fail # Triggers multiple errors.
 IncompatibleRedirecteeFunctionTypeWarning/example: Fail
+IncorrectTypeArgumentInferredWarning/example: Fail
 IncorrectTypeArgumentInReturnTypeWarning/example: Fail
 IncorrectTypeArgumentInSupertypeInferredWarning/example: Fail
 IncorrectTypeArgumentInSupertypeWarning/example: Fail
-IncorrectTypeArgumentInferredWarning/example: Fail
 IncorrectTypeArgumentQualifiedInferredWarning/example: Fail
 IncorrectTypeArgumentQualifiedWarning/example: Fail
 IncorrectTypeArgumentWarning/example: Fail
@@ -481,9 +483,6 @@
 NamedMixinOverride/example: Fail
 NativeClauseShouldBeAnnotation/example: Fail
 NoFormals/example: Fail
-NoSuchNamedParameter/example: Fail
-NoUnnamedConstructorInObject/analyzerCode: Fail
-NoUnnamedConstructorInObject/example: Fail
 NonAgnosticConstant/analyzerCode: Fail
 NonAgnosticConstant/example: Fail
 NonAsciiIdentifier/expression: Fail
@@ -491,7 +490,6 @@
 NonConstConstructor/example: Fail
 NonConstFactory/example: Fail
 NonInstanceTypeVariableUse/example: Fail
-NonNullAwareSpreadIsNull/analyzerCode: Fail # There's no analyzer code for that error yet.
 NonNullableInNullAware/analyzerCode: Fail
 NonNullableInNullAware/example: Fail
 NonNullableLateDefinitelyAssignedError/analyzerCode: Fail
@@ -501,14 +499,17 @@
 NonNullableNotAssignedWarning/example: Fail
 NonNullableOptOut/analyzerCode: Fail
 NonNullableOptOut/example: Fail
+NonNullAwareSpreadIsNull/analyzerCode: Fail # There's no analyzer code for that error yet.
 NonPartOfDirectiveInPart/part_wrapped_script1: Fail
 NonPartOfDirectiveInPart/script1: Fail
+NoSuchNamedParameter/example: Fail
 NotAConstantExpression/example: Fail
-NotAType/example: Fail
 NotAnLvalue/example: Fail
+NotAType/example: Fail
 NotBinaryOperator/analyzerCode: Fail
 NotConstantExpression/example: Fail
-NullAwareCascadeOutOfOrder/example: Fail
+NoUnnamedConstructorInObject/analyzerCode: Fail
+NoUnnamedConstructorInObject/example: Fail
 NullableExpressionCallError/analyzerCode: Fail
 NullableExpressionCallError/example: Fail
 NullableExpressionCallWarning/analyzerCode: Fail
@@ -541,6 +542,7 @@
 NullableTearoffError/example: Fail
 NullableTearoffWarning/analyzerCode: Fail
 NullableTearoffWarning/example: Fail
+NullAwareCascadeOutOfOrder/example: Fail
 OperatorMinusParameterMismatch/example: Fail
 OperatorParameterMismatch0/analyzerCode: Fail
 OperatorParameterMismatch0/example: Fail
@@ -630,13 +632,13 @@
 StackOverflow/example: Fail
 SuperAsExpression/example: Fail
 SuperAsIdentifier/example: Fail
-SuperNullAware/example: Fail
 SuperclassHasNoDefaultConstructor/example: Fail
 SuperclassHasNoGetter/example: Fail
 SuperclassHasNoMethod/example: Fail
 SuperclassHasNoSetter/example: Fail
 SuperclassMethodArgumentMismatch/analyzerCode: Fail
 SuperclassMethodArgumentMismatch/example: Fail
+SuperNullAware/example: Fail
 SupertypeIsFunction/analyzerCode: Fail
 SupertypeIsFunction/example: Fail
 SupertypeIsIllegal/example: Fail
@@ -660,14 +662,14 @@
 TypeArgumentMismatch/example: Fail
 TypeArgumentsOnTypeVariable/part_wrapped_script1: Fail
 TypeArgumentsOnTypeVariable/script1: Fail
-TypeNotFound/example: Fail
-TypeVariableDuplicatedName/example: Fail
-TypeVariableSameNameAsEnclosing/example: Fail
 TypedefNotFunction/example: Fail
 TypedefNotType/example: Fail # Feature not yet enabled by default.
 TypedefNullableType/analyzerCode: Fail
 TypedefTypeVariableNotConstructor/analyzerCode: Fail # Feature not yet enabled by default.
 TypedefTypeVariableNotConstructor/example: Fail # Feature not yet enabled by default.
+TypeNotFound/example: Fail
+TypeVariableDuplicatedName/example: Fail
+TypeVariableSameNameAsEnclosing/example: Fail
 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 a8a30c3..bf8b9c1 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -129,6 +129,9 @@
 ConstEvalNegativeShift:
   template: "Binary operator '#string' on '#string2' requires non-negative operand, but was '#string3'."
 
+ConstEvalTruncateError:
+  template: "Binary operator '#string ~/ #string2' results is Infinity or NaN."
+
 ConstEvalInvalidMethodInvocation:
   template: "The method '#string' can't be invoked on '#constant' in a constant expression."
   analyzerCode: UNDEFINED_OPERATOR
@@ -233,8 +236,8 @@
 
 ExperimentNotEnabled:
   index: 48
-  template: "This requires the '#string' experiment to be enabled."
-  tip: "Try enabling this experiment by adding it to the command line when compiling and running."
+  template: "This requires the '#string' language feature to be enabled."
+  tip: "Try updating your pubspec.yaml to set the minimum SDK constraint to #string2 or higher, and running 'pub get'."
   analyzerCode: ParserErrorCode.EXPERIMENT_NOT_ENABLED
 
 EmptyNamedParameterList:
@@ -1610,9 +1613,6 @@
         Location of the SDK sources for use when compiling additional platform
         libraries.
 
-      --supermixin
-        Ignored for now.
-
       --single-root-scheme=String
       --single-root-base=<dir>
         Specify a custom URI scheme and a location on disk where such URIs are
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart
new file mode 100644
index 0000000..50f35ac
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+class A<T> {}
+
+mixin M<T> {}
+
+class DND1 extends Object with M<dynamic> Function()> {
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect
new file mode 100644
index 0000000..d5d26ac
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect
@@ -0,0 +1,89 @@
+Problems reported:
+
+parser/error_recovery/issue_41265.crash:9:53: Unexpected token '>'.
+class DND1 extends Object with M<dynamic> Function()> {
+                                                    ^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(A, classOrMixinDeclaration)
+    beginTypeVariables(<)
+      beginMetadataStar(T)
+      endMetadataStar(0)
+      handleIdentifier(T, typeVariableDeclaration)
+      beginTypeVariable(T)
+        handleTypeVariablesDefined(T, 1)
+        handleNoType(T)
+      endTypeVariable(>, 0, null, null)
+    endTypeVariables(<, >)
+    beginClassDeclaration(class, null, A)
+      handleNoType(>)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+      endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(mixin)
+  beginMetadataStar(mixin)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(mixin)
+    handleIdentifier(M, classOrMixinDeclaration)
+    beginTypeVariables(<)
+      beginMetadataStar(T)
+      endMetadataStar(0)
+      handleIdentifier(T, typeVariableDeclaration)
+      beginTypeVariable(T)
+        handleTypeVariablesDefined(T, 1)
+        handleNoType(T)
+      endTypeVariable(>, 0, null, null)
+    endTypeVariables(<, >)
+    beginMixinDeclaration(mixin, M)
+      handleMixinOn(null, 0)
+      handleClassOrMixinImplements(null, 0)
+      handleMixinHeader(mixin)
+      beginClassOrMixinBody(DeclarationKind.Mixin, {)
+      endClassOrMixinBody(DeclarationKind.Mixin, 0, {, })
+    endMixinDeclaration(mixin, })
+  endTopLevelDeclaration(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(DND1, classOrMixinDeclaration)
+    handleNoTypeVariables(extends)
+    beginClassDeclaration(class, null, DND1)
+      handleIdentifier(Object, typeReference)
+      handleNoTypeArguments(with)
+      handleType(Object, null)
+      handleClassExtends(extends)
+      beginTypeList(M)
+        handleNoTypeVariables(()
+        beginFunctionType(M)
+          handleIdentifier(M, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(dynamic, typeReference)
+            handleNoTypeArguments(>)
+            handleType(dynamic, null)
+          endTypeArguments(1, <, >)
+          handleType(M, null)
+          beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          endFormalParameters(0, (, ), MemberKind.GeneralizedFunctionType)
+        endFunctionType(Function, null)
+      endTypeList(1)
+      handleClassWithClause(with)
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token '>'., null, {token: >}], >, >)
+      handleNoType(>)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleRecoverClassHeader()
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+      endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(3, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect
new file mode 100644
index 0000000..52766bc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect
@@ -0,0 +1,143 @@
+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(A, 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, A)
+        parseClass(>, class, class, A)
+          parseClassHeaderOpt(>, class, class)
+            parseClassExtendsOpt(>)
+              listener: handleNoType(>)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(>)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(>)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(>, DeclarationKind.Class, A)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(mixin)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(mixin)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, mixin, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(}, mixin)
+      parseMixin(mixin)
+        listener: beginClassOrNamedMixinApplicationPrelude(mixin)
+        ensureIdentifier(mixin, classOrMixinDeclaration)
+          listener: handleIdentifier(M, 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: beginMixinDeclaration(mixin, M)
+        parseMixinHeaderOpt(>, mixin)
+          parseMixinOnOpt(>)
+            listener: handleMixinOn(null, 0)
+          parseClassOrMixinImplementsOpt(>)
+            listener: handleClassOrMixinImplements(null, 0)
+          listener: handleMixinHeader(mixin)
+        parseClassOrMixinOrExtensionBody(>, DeclarationKind.Mixin, M)
+          listener: beginClassOrMixinBody(DeclarationKind.Mixin, {)
+          notEofOrValue(}, })
+          listener: endClassOrMixinBody(DeclarationKind.Mixin, 0, {, })
+        listener: endMixinDeclaration(mixin, })
+  listener: endTopLevelDeclaration(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(DND1, classOrMixinDeclaration)
+        listener: handleNoTypeVariables(extends)
+        listener: beginClassDeclaration(class, null, DND1)
+        parseClass(DND1, class, class, DND1)
+          parseClassHeaderOpt(DND1, class, class)
+            parseClassExtendsOpt(DND1)
+              listener: handleIdentifier(Object, typeReference)
+              listener: handleNoTypeArguments(with)
+              listener: handleType(Object, null)
+              listener: handleClassExtends(extends)
+            parseWithClauseOpt(Object)
+              parseTypeList(with)
+                listener: beginTypeList(M)
+                listener: handleNoTypeVariables(()
+                listener: beginFunctionType(M)
+                ensureIdentifier(with, typeReference)
+                  listener: handleIdentifier(M, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(dynamic, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(dynamic, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(M, null)
+                parseFormalParametersRequiredOpt(Function, MemberKind.GeneralizedFunctionType)
+                  parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+                    listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+                    listener: endFormalParameters(0, (, ), MemberKind.GeneralizedFunctionType)
+                listener: endFunctionType(Function, null)
+                listener: endTypeList(1)
+              listener: handleClassWithClause(with)
+            parseClassOrMixinImplementsOpt())
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassHeaderRecovery(DND1, class, class)
+            parseClassHeaderOpt(DND1, class, class)
+              parseClassExtendsOpt(DND1)
+              parseWithClauseOpt(Object)
+                parseTypeList(with)
+                  ensureIdentifier(with, typeReference)
+                  parseFormalParametersRequiredOpt(Function, MemberKind.GeneralizedFunctionType)
+                    parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+              parseClassOrMixinImplementsOpt())
+            skipUnexpectedTokenOpt(), [extends, with, implements, {])
+              reportRecoverableErrorWithToken(>, Instance of 'Template<(Token) => Message>')
+                listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token '>'., null, {token: >}], >, >)
+            parseClassExtendsOpt(>)
+              listener: handleNoType(>)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(>)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(>)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleRecoverClassHeader()
+          ensureBlock(>, null, class declaration)
+          parseClassOrMixinOrExtensionBody(>, DeclarationKind.Class, DND1)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(3, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.parser.expect
new file mode 100644
index 0000000..0f00c7a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.parser.expect
@@ -0,0 +1,15 @@
+class A<T> {}
+
+mixin M<T> {}
+
+class DND1 extends Object with M<dynamic> Function()> {
+}
+
+
+class[KeywordToken] A[StringToken]<[BeginToken]T[StringToken]>[SimpleToken] {[BeginToken]}[SimpleToken]
+
+mixin[KeywordToken] M[StringToken]<[BeginToken]T[StringToken]>[SimpleToken] {[BeginToken]}[SimpleToken]
+
+class[KeywordToken] DND1[StringToken] extends[KeywordToken] Object[StringToken] with[KeywordToken] M[StringToken]<[BeginToken]dynamic[KeywordToken]>[SimpleToken] Function[KeywordToken]([BeginToken])[SimpleToken]>[SimpleToken] {[BeginToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.scanner.expect
new file mode 100644
index 0000000..0f00c7a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.scanner.expect
@@ -0,0 +1,15 @@
+class A<T> {}
+
+mixin M<T> {}
+
+class DND1 extends Object with M<dynamic> Function()> {
+}
+
+
+class[KeywordToken] A[StringToken]<[BeginToken]T[StringToken]>[SimpleToken] {[BeginToken]}[SimpleToken]
+
+mixin[KeywordToken] M[StringToken]<[BeginToken]T[StringToken]>[SimpleToken] {[BeginToken]}[SimpleToken]
+
+class[KeywordToken] DND1[StringToken] extends[KeywordToken] Object[StringToken] with[KeywordToken] M[StringToken]<[BeginToken]dynamic[KeywordToken]>[SimpleToken] Function[KeywordToken]([BeginToken])[SimpleToken]>[SimpleToken] {[BeginToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart
new file mode 100644
index 0000000..ed232d2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart
@@ -0,0 +1,9 @@
+class C {
+  int with() => 7;
+  int with = 7;
+  int get with => 7;
+  void set with(int x) {}
+}
+
+int with() => 7;
+int with = 7;
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect
new file mode 100644
index 0000000..eac2ae2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect
@@ -0,0 +1,326 @@
+Problems reported:
+
+parser/error_recovery/method_called_with:2:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int with() => 7;
+  ^^^
+
+parser/error_recovery/method_called_with:2:3: Expected ';' after this.
+  int with() => 7;
+  ^^^
+
+parser/error_recovery/method_called_with:2:7: Expected a class member, but got 'with'.
+  int with() => 7;
+      ^^^^
+
+parser/error_recovery/method_called_with:2:11: Expected an identifier, but got '('.
+  int with() => 7;
+          ^
+
+parser/error_recovery/method_called_with:3:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int with = 7;
+  ^^^
+
+parser/error_recovery/method_called_with:3:3: Expected ';' after this.
+  int with = 7;
+  ^^^
+
+parser/error_recovery/method_called_with:3:7: Expected a class member, but got 'with'.
+  int with = 7;
+      ^^^^
+
+parser/error_recovery/method_called_with:3:12: Operator declarations must be preceded by the keyword 'operator'.
+  int with = 7;
+           ^
+
+parser/error_recovery/method_called_with:3:12: The string '=' isn't a user-definable operator.
+  int with = 7;
+           ^
+
+parser/error_recovery/method_called_with:3:12: A method declaration needs an explicit list of parameters.
+  int with = 7;
+           ^
+
+parser/error_recovery/method_called_with:3:14: Expected a function body, but got '7'.
+  int with = 7;
+             ^
+
+parser/error_recovery/method_called_with:3:14: Expected a class member, but got '7'.
+  int with = 7;
+             ^
+
+parser/error_recovery/method_called_with:3:15: Expected a class member, but got ';'.
+  int with = 7;
+              ^
+
+parser/error_recovery/method_called_with:4:7: Expected ';' after this.
+  int get with => 7;
+      ^^^
+
+parser/error_recovery/method_called_with:4:11: Expected a class member, but got 'with'.
+  int get with => 7;
+          ^^^^
+
+parser/error_recovery/method_called_with:4:16: Expected an identifier, but got '=>'.
+  int get with => 7;
+               ^^
+
+parser/error_recovery/method_called_with:4:16: A method declaration needs an explicit list of parameters.
+  int get with => 7;
+               ^^
+
+parser/error_recovery/method_called_with:5:8: Expected ';' after this.
+  void set with(int x) {}
+       ^^^
+
+parser/error_recovery/method_called_with:5:12: Expected a class member, but got 'with'.
+  void set with(int x) {}
+           ^^^^
+
+parser/error_recovery/method_called_with:5:16: Expected an identifier, but got '('.
+  void set with(int x) {}
+               ^
+
+parser/error_recovery/method_called_with:8:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int with() => 7;
+^^^
+
+parser/error_recovery/method_called_with:8:1: Expected ';' after this.
+int with() => 7;
+^^^
+
+parser/error_recovery/method_called_with:8:5: Expected an identifier, but got 'with'.
+int with() => 7;
+    ^^^^
+
+parser/error_recovery/method_called_with:9:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int with = 7;
+^^^
+
+parser/error_recovery/method_called_with:9:1: Expected ';' after this.
+int with = 7;
+^^^
+
+parser/error_recovery/method_called_with:9:5: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int with = 7;
+    ^^^^
+
+parser/error_recovery/method_called_with:9:5: Expected an identifier, but got 'with'.
+int with = 7;
+    ^^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(C, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, C)
+      handleNoType(C)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          handleRecoverableError(MissingConstFinalVarOrType, int, int)
+          handleNoType({)
+          handleIdentifier(int, fieldDeclaration)
+          handleNoFieldInitializer(with)
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+        endClassFields(null, null, null, null, 1, int, ;)
+      endMember()
+      beginMetadataStar(with)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+        handleInvalidMember(with)
+      endMember()
+      beginMetadataStar(()
+      endMetadataStar(0)
+      beginMember()
+        beginMethod(null, null, null, null, null, ()
+          handleNoType(with)
+          handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+          handleIdentifier(, methodDeclaration)
+          handleNoTypeVariables(()
+          beginFormalParameters((, MemberKind.NonStaticMethod)
+          endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          handleLiteralInt(7)
+          handleExpressionFunctionBody(=>, ;)
+        endClassMethod(null, , (, null, ;)
+      endMember()
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        handleNoType(;)
+        handleIdentifier(int, fieldDeclaration)
+        handleNoFieldInitializer(with)
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+      endClassFields(null, null, null, null, 1, int, ;)
+    endMember()
+    beginMetadataStar(with)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+      handleInvalidMember(with)
+    endMember()
+    beginMetadataStar(=)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(MissingOperatorKeyword, =, =)
+      beginMethod(null, null, null, null, null, operator)
+        handleNoType(with)
+        handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+        handleInvalidOperatorName(operator, =)
+        handleNoTypeVariables(7)
+        handleRecoverableError(MissingMethodParameters, =, =)
+        beginFormalParameters((, MemberKind.NonStaticMethod)
+        endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+        handleNoInitializers()
+        handleAsyncModifier(null, null)
+        handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '7'., null, {token: 7}], 7, 7)
+        handleInvalidFunctionBody({)
+      endClassMethod(null, operator, (, null, })
+    endMember()
+    beginMetadataStar(7)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '7'., null, {token: 7}], 7, 7)
+      handleInvalidMember(7)
+    endMember()
+    beginMetadataStar(;)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+      handleInvalidMember(;)
+    endMember()
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginMember()
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(get)
+      handleType(int, null)
+      handleIdentifier(get, fieldDeclaration)
+      handleNoFieldInitializer(with)
+      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], get, get)
+    endClassFields(null, null, null, null, 1, int, ;)
+  endMember()
+  beginMetadataStar(with)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+    handleInvalidMember(with)
+  endMember()
+  beginMetadataStar(=>)
+  endMetadataStar(0)
+  beginMember()
+    beginMethod(null, null, null, null, null, =>)
+      handleNoType(with)
+      handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '=>'., null, {token: =>}], =>, =>)
+      handleIdentifier(, methodDeclaration)
+      handleNoTypeVariables(=>)
+      handleRecoverableError(MissingMethodParameters, =>, =>)
+      beginFormalParameters((, MemberKind.NonStaticMethod)
+      endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+      handleNoInitializers()
+      handleAsyncModifier(null, null)
+      handleLiteralInt(7)
+      handleExpressionFunctionBody(=>, ;)
+    endClassMethod(null, , (, null, ;)
+  endMember()
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginMember()
+    handleVoidKeyword(void)
+    handleIdentifier(set, fieldDeclaration)
+    handleNoFieldInitializer(with)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], set, set)
+  endClassFields(null, null, null, null, 1, void, ;)
+endMember()
+beginMetadataStar(with)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+  handleInvalidMember(with)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+  beginMethod(null, null, null, null, null, ()
+    handleNoType(with)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+    handleIdentifier(, methodDeclaration)
+    handleNoTypeVariables(()
+    beginFormalParameters((, MemberKind.NonStaticMethod)
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(x)
+        handleType(int, null)
+        handleIdentifier(x, formalParameterDeclaration)
+        handleFormalParameterWithoutValue())
+      endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+    endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+    handleNoInitializers()
+    handleAsyncModifier(null, null)
+    beginBlockFunctionBody({)
+    endBlockFunctionBody(0, {, })
+  endClassMethod(null, , (, null, })
+endMember()
+endClassOrMixinBody(DeclarationKind.Class, 14, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(with)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(with)
+beginMetadataStar(with)
+endMetadataStar(0)
+beginTopLevelMember(with)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+handleLiteralInt(7)
+handleExpressionFunctionBody(=>, ;)
+endTopLevelMethod(with, null, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(with)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(with)
+beginMetadataStar(with)
+endMetadataStar(0)
+beginTopLevelMember(with)
+handleRecoverableError(MissingConstFinalVarOrType, with, with)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(7)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, with, ;)
+endTopLevelDeclaration()
+endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect
new file mode 100644
index 0000000..3335498
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect
@@ -0,0 +1,461 @@
+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(C, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, C)
+        parseClass(C, class, class, C)
+          parseClassHeaderOpt(C, class, class)
+            parseClassExtendsOpt(C)
+              listener: handleNoType(C)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(C)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(C)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(C, DeclarationKind.Class, C)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, C)
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, {, Instance of 'NoType', int, DeclarationKind.Class, C)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType({)
+                ensureIdentifier({, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, C)
+                  listener: handleNoFieldInitializer(with)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, with)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(with)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, C)
+                reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+                listener: handleInvalidMember(with)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(with, DeclarationKind.Class, C)
+              parseMetadataStar(with)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(with, with, null, null, null, null, null, with, Instance of 'NoType', null, DeclarationKind.Class, C)
+                parseMethod(with, null, null, null, null, null, with, Instance of 'NoType', null, (, DeclarationKind.Class, C)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(with)
+                  ensureIdentifier(with, methodDeclaration)
+                    insertSyntheticIdentifier(with, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                  parseInitializersOpt())
+                    listener: handleNoInitializers()
+                  parseAsyncModifierOpt())
+                    listener: handleAsyncModifier(null, null)
+                    inPlainSync()
+                  inPlainSync()
+                  parseFunctionBody(), false, true)
+                    parseExpressionFunctionBody(=>, false)
+                      parseExpression(=>)
+                        parsePrecedenceExpression(=>, 1, true)
+                          parseUnaryExpression(=>, true)
+                            parsePrimary(=>, expression)
+                              parseLiteralInt(=>)
+                                listener: handleLiteralInt(7)
+                      ensureSemicolon(7)
+                      listener: handleExpressionFunctionBody(=>, ;)
+                      inGenerator()
+                  listener: endClassMethod(null, , (, null, ;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, C)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, C)
+                  listener: handleNoFieldInitializer(with)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, with)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(with)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, C)
+                reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+                listener: handleInvalidMember(with)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(with, DeclarationKind.Class, C)
+              parseMetadataStar(with)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(with, with, null, null, null, null, null, with, Instance of 'NoType', null, DeclarationKind.Class, C)
+                parseInvalidOperatorDeclaration(with, null, null, null, null, null, with, DeclarationKind.Class, C)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(with, null, null, null, null, null, with, Instance of 'NoType', null, operator, DeclarationKind.Class, C)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(with)
+                    parseOperatorName(with)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(7)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(7, Message[ExpectedFunctionBody, Expected a function body, but got '7'., null, {token: 7}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '7'., null, {token: 7}], 7, 7)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 7)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, C)
+              parseMetadataStar(})
+                listener: beginMetadataStar(7)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, C)
+                reportRecoverableErrorWithToken(7, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '7'., null, {token: 7}], 7, 7)
+                listener: handleInvalidMember(7)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(7, DeclarationKind.Class, C)
+              parseMetadataStar(7)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(7, 7, null, null, null, null, null, 7, Instance of 'NoType', null, DeclarationKind.Class, C)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', get, DeclarationKind.Class, C)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(get)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(get, fieldDeclaration)
+                parseFieldInitializerOpt(get, get, null, null, DeclarationKind.Class, C)
+                  listener: handleNoFieldInitializer(with)
+                ensureSemicolon(get)
+                  reportRecoverableError(get, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], get, get)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, with)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(with)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, C)
+                reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+                listener: handleInvalidMember(with)
+                listener: endMember()
+            notEofOrValue(}, =>)
+            parseClassOrMixinOrExtensionMemberImpl(with, DeclarationKind.Class, C)
+              parseMetadataStar(with)
+                listener: beginMetadataStar(=>)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(with, with, null, null, null, null, null, with, Instance of 'NoType', null, DeclarationKind.Class, C)
+                parseMethod(with, null, null, null, null, null, with, Instance of 'NoType', null, =>, DeclarationKind.Class, C)
+                  listener: beginMethod(null, null, null, null, null, =>)
+                  listener: handleNoType(with)
+                  ensureIdentifier(with, methodDeclaration)
+                    insertSyntheticIdentifier(with, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError(=>, Message[ExpectedIdentifier, Expected an identifier, but got '=>'., null, {token: =>}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '=>'., null, {token: =>}], =>, =>)
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(=>)
+                  parseGetterOrFormalParameters(, =>, false, MemberKind.NonStaticMethod)
+                    missingParameterMessage(MemberKind.NonStaticMethod)
+                    reportRecoverableError(=>, MissingMethodParameters)
+                      listener: handleRecoverableError(MissingMethodParameters, =>, =>)
+                    rewriter()
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                  parseInitializersOpt())
+                    listener: handleNoInitializers()
+                  parseAsyncModifierOpt())
+                    listener: handleAsyncModifier(null, null)
+                    inPlainSync()
+                  inPlainSync()
+                  parseFunctionBody(), false, true)
+                    parseExpressionFunctionBody(=>, false)
+                      parseExpression(=>)
+                        parsePrecedenceExpression(=>, 1, true)
+                          parseUnaryExpression(=>, true)
+                            parsePrimary(=>, expression)
+                              parseLiteralInt(=>)
+                                listener: handleLiteralInt(7)
+                      ensureSemicolon(7)
+                      listener: handleExpressionFunctionBody(=>, ;)
+                      inGenerator()
+                  listener: endClassMethod(null, , (, null, ;)
+                listener: endMember()
+            notEofOrValue(}, void)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(void)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'VoidType', set, DeclarationKind.Class, C)
+                listener: handleVoidKeyword(void)
+                ensureIdentifier(void, fieldDeclaration)
+                  listener: handleIdentifier(set, fieldDeclaration)
+                parseFieldInitializerOpt(set, set, null, null, DeclarationKind.Class, C)
+                  listener: handleNoFieldInitializer(with)
+                ensureSemicolon(set)
+                  reportRecoverableError(set, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], set, set)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, void, ;)
+              listener: endMember()
+            notEofOrValue(}, with)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(with)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, C)
+                reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+                listener: handleInvalidMember(with)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(with, DeclarationKind.Class, C)
+              parseMetadataStar(with)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(with, with, null, null, null, null, null, with, Instance of 'NoType', null, DeclarationKind.Class, C)
+                parseMethod(with, null, null, null, null, null, with, Instance of 'NoType', null, (, DeclarationKind.Class, C)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(with)
+                  ensureIdentifier(with, methodDeclaration)
+                    insertSyntheticIdentifier(with, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(}, })
+                    listener: endBlockFunctionBody(0, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 14, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(with)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(with)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(with)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(with)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, with)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+          listener: handleIdentifier(with, topLevelFunctionDeclaration)
+        parseMethodTypeVar(with)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(with, with, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(with, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          parseExpressionFunctionBody(=>, false)
+            parseExpression(=>)
+              parsePrecedenceExpression(=>, 1, true)
+                parseUnaryExpression(=>, true)
+                  parsePrimary(=>, expression)
+                    parseLiteralInt(=>)
+                      listener: handleLiteralInt(7)
+            ensureSemicolon(7)
+            listener: handleExpressionFunctionBody(=>, ;)
+            inGenerator()
+        listener: endTopLevelMethod(with, null, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(with)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(with)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(with)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(with)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', with, DeclarationKind.TopLevel, null)
+        reportRecoverableError(with, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, with, with)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelVariableDeclaration)
+          reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+          listener: handleIdentifier(with, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(with, with, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(7)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, with, ;)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.parser.expect
new file mode 100644
index 0000000..0d88f7f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.parser.expect
@@ -0,0 +1,23 @@
+NOTICE: Stream was rewritten by parser!
+
+class C {
+int ;with() => 7;
+int ;with operator= (){}7;
+int get ;with ()=> 7;
+void set ;with(int x) {}
+}
+
+int ;with() => 7;
+int ;with = 7;
+
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+int[StringToken] ;[SyntheticToken]with[KeywordToken][SyntheticStringToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]with[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]7[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] ;[SyntheticToken]with[KeywordToken] [SyntheticStringToken]([SyntheticBeginToken])[SyntheticToken]=>[SimpleToken] 7[StringToken];[SimpleToken]
+void[KeywordToken] set[KeywordToken] ;[SyntheticToken]with[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]with[KeywordToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]with[KeywordToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.scanner.expect
new file mode 100644
index 0000000..8295b68
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.scanner.expect
@@ -0,0 +1,21 @@
+class C {
+int with() => 7;
+int with = 7;
+int get with => 7;
+void set with(int x) {}
+}
+
+int with() => 7;
+int with = 7;
+
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+int[StringToken] with[KeywordToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] with[KeywordToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] with[KeywordToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+void[KeywordToken] set[KeywordToken] with[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] with[KeywordToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] with[KeywordToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart
new file mode 100644
index 0000000..ed5ce5e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart
@@ -0,0 +1,9 @@
+class C {
+  int With() => 7;
+  int With = 7;
+  int get With => 7;
+  void set With(int x) {}
+}
+
+int With() => 7;
+int With = 7;
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect
new file mode 100644
index 0000000..5dd0a88
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect
@@ -0,0 +1,114 @@
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(C, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, C)
+      handleNoType(C)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, With)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(With)
+            handleType(int, null)
+            handleIdentifier(With, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+            endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            handleLiteralInt(7)
+            handleExpressionFunctionBody(=>, ;)
+          endClassMethod(null, int, (, null, ;)
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(With)
+          handleType(int, null)
+          handleIdentifier(With, fieldDeclaration)
+          beginFieldInitializer(=)
+            handleLiteralInt(7)
+          endFieldInitializer(=, ;)
+        endClassFields(null, null, null, null, 1, int, ;)
+      endMember()
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginMember()
+        beginMethod(null, null, null, null, get, With)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(get)
+          handleType(int, null)
+          handleIdentifier(With, methodDeclaration)
+          handleNoTypeVariables(=>)
+          handleNoFormalParameters(=>, MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          handleLiteralInt(7)
+          handleExpressionFunctionBody(=>, ;)
+        endClassMethod(get, int, =>, null, ;)
+      endMember()
+      beginMetadataStar(void)
+      endMetadataStar(0)
+      beginMember()
+        beginMethod(null, null, null, null, set, With)
+          handleVoidKeyword(void)
+          handleIdentifier(With, methodDeclaration)
+          handleNoTypeVariables(()
+          beginFormalParameters((, MemberKind.NonStaticMethod)
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(x)
+              handleType(int, null)
+              handleIdentifier(x, formalParameterDeclaration)
+              handleFormalParameterWithoutValue())
+            endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+          endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          beginBlockFunctionBody({)
+          endBlockFunctionBody(0, {, })
+        endClassMethod(set, void, (, null, })
+      endMember()
+    endClassOrMixinBody(DeclarationKind.Class, 4, {, })
+  endClassDeclaration(class, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+  beginTopLevelMethod(}, null)
+    handleIdentifier(int, typeReference)
+    handleNoTypeArguments(With)
+    handleType(int, null)
+    handleIdentifier(With, topLevelFunctionDeclaration)
+    handleNoTypeVariables(()
+    beginFormalParameters((, MemberKind.TopLevelMethod)
+    endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+    handleAsyncModifier(null, null)
+    handleLiteralInt(7)
+    handleExpressionFunctionBody(=>, ;)
+  endTopLevelMethod(int, null, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+  handleIdentifier(int, typeReference)
+  handleNoTypeArguments(With)
+  handleType(int, null)
+  handleIdentifier(With, topLevelVariableDeclaration)
+  beginFieldInitializer(=)
+    handleLiteralInt(7)
+  endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration()
+endCompilationUnit(3, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect
new file mode 100644
index 0000000..695beee
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect
@@ -0,0 +1,236 @@
+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(C, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, C)
+        parseClass(C, class, class, C)
+          parseClassHeaderOpt(C, class, class)
+            parseClassExtendsOpt(C)
+              listener: handleNoType(C)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(C)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(C)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(C, DeclarationKind.Class, C)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, C)
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod({, null, null, null, null, null, {, Instance of 'SimpleType', null, With, DeclarationKind.Class, C)
+                listener: beginMethod(null, null, null, null, null, With)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(With)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(With, methodDeclaration)
+                parseQualifiedRestOpt(With, methodDeclarationContinuation)
+                parseMethodTypeVar(With)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(With, With, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(With, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  parseExpressionFunctionBody(=>, false)
+                    parseExpression(=>)
+                      parsePrecedenceExpression(=>, 1, true)
+                        parseUnaryExpression(=>, true)
+                          parsePrimary(=>, expression)
+                            parseLiteralInt(=>)
+                              listener: handleLiteralInt(7)
+                    ensureSemicolon(7)
+                    listener: handleExpressionFunctionBody(=>, ;)
+                    inGenerator()
+                listener: endClassMethod(null, int, (, null, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', With, DeclarationKind.Class, C)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(With)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(With, fieldDeclaration)
+                parseFieldInitializerOpt(With, With, null, null, DeclarationKind.Class, C)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(7)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(;, null, null, null, null, null, ;, Instance of 'SimpleType', get, With, DeclarationKind.Class, C)
+                listener: beginMethod(null, null, null, null, get, With)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(get)
+                listener: handleType(int, null)
+                ensureIdentifier(get, methodDeclaration)
+                  listener: handleIdentifier(With, methodDeclaration)
+                parseQualifiedRestOpt(With, methodDeclarationContinuation)
+                listener: handleNoTypeVariables(=>)
+                parseGetterOrFormalParameters(With, With, true, MemberKind.NonStaticMethod)
+                  listener: handleNoFormalParameters(=>, MemberKind.NonStaticMethod)
+                parseInitializersOpt(With)
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt(With)
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                inPlainSync()
+                parseFunctionBody(With, false, true)
+                  parseExpressionFunctionBody(=>, false)
+                    parseExpression(=>)
+                      parsePrecedenceExpression(=>, 1, true)
+                        parseUnaryExpression(=>, true)
+                          parsePrimary(=>, expression)
+                            parseLiteralInt(=>)
+                              listener: handleLiteralInt(7)
+                    ensureSemicolon(7)
+                    listener: handleExpressionFunctionBody(=>, ;)
+                    inGenerator()
+                listener: endClassMethod(get, int, =>, null, ;)
+              listener: endMember()
+            notEofOrValue(}, void)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(void)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(;, null, null, null, null, null, ;, Instance of 'VoidType', set, With, DeclarationKind.Class, C)
+                listener: beginMethod(null, null, null, null, set, With)
+                listener: handleVoidKeyword(void)
+                ensureIdentifier(set, methodDeclaration)
+                  listener: handleIdentifier(With, methodDeclaration)
+                parseQualifiedRestOpt(With, methodDeclarationContinuation)
+                listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(With, With, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(With, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: beginBlockFunctionBody({)
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(0, {, })
+                listener: endClassMethod(set, void, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 4, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, With)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(With)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(With, topLevelFunctionDeclaration)
+        parseMethodTypeVar(With)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(With, With, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(With, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          parseExpressionFunctionBody(=>, false)
+            parseExpression(=>)
+              parsePrecedenceExpression(=>, 1, true)
+                parseUnaryExpression(=>, true)
+                  parsePrimary(=>, expression)
+                    parseLiteralInt(=>)
+                      listener: handleLiteralInt(7)
+            ensureSemicolon(7)
+            listener: handleExpressionFunctionBody(=>, ;)
+            inGenerator()
+        listener: endTopLevelMethod(int, null, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', With, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(With)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(With, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(With, With, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(7)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(3, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.parser.expect
new file mode 100644
index 0000000..285faf2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.parser.expect
@@ -0,0 +1,21 @@
+class C {
+int With() => 7;
+int With = 7;
+int get With => 7;
+void set With(int x) {}
+}
+
+int With() => 7;
+int With = 7;
+
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+int[StringToken] With[StringToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] With[StringToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] With[StringToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+void[KeywordToken] set[KeywordToken] With[StringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] With[StringToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] With[StringToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.scanner.expect
new file mode 100644
index 0000000..285faf2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.scanner.expect
@@ -0,0 +1,21 @@
+class C {
+int With() => 7;
+int With = 7;
+int get With => 7;
+void set With(int x) {}
+}
+
+int With() => 7;
+int With = 7;
+
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+int[StringToken] With[StringToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] With[StringToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] With[StringToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+void[KeywordToken] set[KeywordToken] With[StringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] With[StringToken]([BeginToken])[SimpleToken] =>[SimpleToken] 7[StringToken];[SimpleToken]
+int[StringToken] With[StringToken] =[SimpleToken] 7[StringToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart
new file mode 100644
index 0000000..30ca978
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart
@@ -0,0 +1,35 @@
+class WrapperClass {
+  int assert = 42;
+  int break = 42;
+  int case = 42;
+  int catch = 42;
+  int class = 42;
+  int const = 42;
+  int continue = 42;
+  int default = 42;
+  int do = 42;
+  int else = 42;
+  int enum = 42;
+  int extends = 42;
+  int false = 42;
+  int final = 42;
+  int finally = 42;
+  int for = 42;
+  int if = 42;
+  int in = 42;
+  int is = 42;
+  int new = 42;
+  int null = 42;
+  int rethrow = 42;
+  int return = 42;
+  int super = 42;
+  int switch = 42;
+  int this = 42;
+  int throw = 42;
+  int true = 42;
+  int try = 42;
+  int var = 42;
+  int void = 42;
+  int while = 42;
+  int with = 42;
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.expect
new file mode 100644
index 0000000..313f38a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.expect
@@ -0,0 +1,2633 @@
+Problems reported:
+
+parser/error_recovery/reserved_words_class_fields:2:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int assert = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:2:3: Expected ';' after this.
+  int assert = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:2:7: Expected a class member, but got 'assert'.
+  int assert = 42;
+      ^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:2:14: Operator declarations must be preceded by the keyword 'operator'.
+  int assert = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:2:14: The string '=' isn't a user-definable operator.
+  int assert = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:2:14: A method declaration needs an explicit list of parameters.
+  int assert = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:2:16: Expected a function body, but got '42'.
+  int assert = 42;
+               ^^
+
+parser/error_recovery/reserved_words_class_fields:2:16: Expected a class member, but got '42'.
+  int assert = 42;
+               ^^
+
+parser/error_recovery/reserved_words_class_fields:2:18: Expected a class member, but got ';'.
+  int assert = 42;
+                 ^
+
+parser/error_recovery/reserved_words_class_fields:3:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int break = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:3:3: Expected ';' after this.
+  int break = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:3:7: Expected a class member, but got 'break'.
+  int break = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:3:13: Operator declarations must be preceded by the keyword 'operator'.
+  int break = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:3:13: The string '=' isn't a user-definable operator.
+  int break = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:3:13: A method declaration needs an explicit list of parameters.
+  int break = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:3:15: Expected a function body, but got '42'.
+  int break = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:3:15: Expected a class member, but got '42'.
+  int break = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:3:17: Expected a class member, but got ';'.
+  int break = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:4:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int case = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:4:3: Expected ';' after this.
+  int case = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:4:7: Expected a class member, but got 'case'.
+  int case = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:4:12: Operator declarations must be preceded by the keyword 'operator'.
+  int case = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:4:12: The string '=' isn't a user-definable operator.
+  int case = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:4:12: A method declaration needs an explicit list of parameters.
+  int case = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:4:14: Expected a function body, but got '42'.
+  int case = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:4:14: Expected a class member, but got '42'.
+  int case = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:4:16: Expected a class member, but got ';'.
+  int case = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:5:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int catch = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:5:3: Expected ';' after this.
+  int catch = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:5:7: Expected a class member, but got 'catch'.
+  int catch = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:5:13: Operator declarations must be preceded by the keyword 'operator'.
+  int catch = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:5:13: The string '=' isn't a user-definable operator.
+  int catch = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:5:13: A method declaration needs an explicit list of parameters.
+  int catch = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:5:15: Expected a function body, but got '42'.
+  int catch = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:5:15: Expected a class member, but got '42'.
+  int catch = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:5:17: Expected a class member, but got ';'.
+  int catch = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:6:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int class = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:6:3: Expected ';' after this.
+  int class = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:6:7: Classes can't be declared inside other classes.
+  int class = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:6:13: Operator declarations must be preceded by the keyword 'operator'.
+  int class = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:6:13: The string '=' isn't a user-definable operator.
+  int class = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:6:13: A method declaration needs an explicit list of parameters.
+  int class = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:6:15: Expected a function body, but got '42'.
+  int class = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:6:15: Expected a class member, but got '42'.
+  int class = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:6:17: Expected a class member, but got ';'.
+  int class = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:7:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int const = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:7:3: Expected ';' after this.
+  int const = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:7:13: Operator declarations must be preceded by the keyword 'operator'.
+  int const = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:7:13: The string '=' isn't a user-definable operator.
+  int const = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:7:13: A method declaration needs an explicit list of parameters.
+  int const = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:7:15: Expected a function body, but got '42'.
+  int const = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:7:7: Getters, setters and methods can't be declared to be 'const'.
+  int const = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:7:15: Expected a class member, but got '42'.
+  int const = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:7:17: Expected a class member, but got ';'.
+  int const = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:8:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int continue = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:8:3: Expected ';' after this.
+  int continue = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:8:7: Expected a class member, but got 'continue'.
+  int continue = 42;
+      ^^^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:8:16: Operator declarations must be preceded by the keyword 'operator'.
+  int continue = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:8:16: The string '=' isn't a user-definable operator.
+  int continue = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:8:16: A method declaration needs an explicit list of parameters.
+  int continue = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:8:18: Expected a function body, but got '42'.
+  int continue = 42;
+                 ^^
+
+parser/error_recovery/reserved_words_class_fields:8:18: Expected a class member, but got '42'.
+  int continue = 42;
+                 ^^
+
+parser/error_recovery/reserved_words_class_fields:8:20: Expected a class member, but got ';'.
+  int continue = 42;
+                   ^
+
+parser/error_recovery/reserved_words_class_fields:9:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int default = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:9:3: Expected ';' after this.
+  int default = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:9:7: Expected a class member, but got 'default'.
+  int default = 42;
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:9:15: Operator declarations must be preceded by the keyword 'operator'.
+  int default = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:9:15: The string '=' isn't a user-definable operator.
+  int default = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:9:15: A method declaration needs an explicit list of parameters.
+  int default = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:9:17: Expected a function body, but got '42'.
+  int default = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:9:17: Expected a class member, but got '42'.
+  int default = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:9:19: Expected a class member, but got ';'.
+  int default = 42;
+                  ^
+
+parser/error_recovery/reserved_words_class_fields:10:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int do = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:10:3: Expected ';' after this.
+  int do = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:10:7: Expected a class member, but got 'do'.
+  int do = 42;
+      ^^
+
+parser/error_recovery/reserved_words_class_fields:10:10: Operator declarations must be preceded by the keyword 'operator'.
+  int do = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:10:10: The string '=' isn't a user-definable operator.
+  int do = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:10:10: A method declaration needs an explicit list of parameters.
+  int do = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:10:12: Expected a function body, but got '42'.
+  int do = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:10:12: Expected a class member, but got '42'.
+  int do = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:10:14: Expected a class member, but got ';'.
+  int do = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:11:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int else = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:11:3: Expected ';' after this.
+  int else = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:11:7: Expected a class member, but got 'else'.
+  int else = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:11:12: Operator declarations must be preceded by the keyword 'operator'.
+  int else = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:11:12: The string '=' isn't a user-definable operator.
+  int else = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:11:12: A method declaration needs an explicit list of parameters.
+  int else = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:11:14: Expected a function body, but got '42'.
+  int else = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:11:14: Expected a class member, but got '42'.
+  int else = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:11:16: Expected a class member, but got ';'.
+  int else = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:12:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int enum = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:12:3: Expected ';' after this.
+  int enum = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:12:7: Enums can't be declared inside classes.
+  int enum = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:12:12: Operator declarations must be preceded by the keyword 'operator'.
+  int enum = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:12:12: The string '=' isn't a user-definable operator.
+  int enum = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:12:12: A method declaration needs an explicit list of parameters.
+  int enum = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:12:14: Expected a function body, but got '42'.
+  int enum = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:12:14: Expected a class member, but got '42'.
+  int enum = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:12:16: Expected a class member, but got ';'.
+  int enum = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:13:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int extends = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:13:3: Expected ';' after this.
+  int extends = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:13:7: Expected a class member, but got 'extends'.
+  int extends = 42;
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:13:15: Operator declarations must be preceded by the keyword 'operator'.
+  int extends = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:13:15: The string '=' isn't a user-definable operator.
+  int extends = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:13:15: A method declaration needs an explicit list of parameters.
+  int extends = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:13:17: Expected a function body, but got '42'.
+  int extends = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:13:17: Expected a class member, but got '42'.
+  int extends = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:13:19: Expected a class member, but got ';'.
+  int extends = 42;
+                  ^
+
+parser/error_recovery/reserved_words_class_fields:14:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int false = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:14:3: Expected ';' after this.
+  int false = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:14:7: Expected a class member, but got 'false'.
+  int false = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:14:13: Operator declarations must be preceded by the keyword 'operator'.
+  int false = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:14:13: The string '=' isn't a user-definable operator.
+  int false = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:14:13: A method declaration needs an explicit list of parameters.
+  int false = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:14:15: Expected a function body, but got '42'.
+  int false = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:14:15: Expected a class member, but got '42'.
+  int false = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:14:17: Expected a class member, but got ';'.
+  int false = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:15:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int final = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:15:3: Expected ';' after this.
+  int final = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:15:13: Operator declarations must be preceded by the keyword 'operator'.
+  int final = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:15:7: Can't have modifier 'final' here.
+  int final = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:15:13: The string '=' isn't a user-definable operator.
+  int final = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:15:13: A method declaration needs an explicit list of parameters.
+  int final = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:15:15: Expected a function body, but got '42'.
+  int final = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:15:15: Expected a class member, but got '42'.
+  int final = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:15:17: Expected a class member, but got ';'.
+  int final = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:16:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int finally = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:16:3: Expected ';' after this.
+  int finally = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:16:7: Expected a class member, but got 'finally'.
+  int finally = 42;
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:16:15: Operator declarations must be preceded by the keyword 'operator'.
+  int finally = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:16:15: The string '=' isn't a user-definable operator.
+  int finally = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:16:15: A method declaration needs an explicit list of parameters.
+  int finally = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:16:17: Expected a function body, but got '42'.
+  int finally = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:16:17: Expected a class member, but got '42'.
+  int finally = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:16:19: Expected a class member, but got ';'.
+  int finally = 42;
+                  ^
+
+parser/error_recovery/reserved_words_class_fields:17:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int for = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:17:3: Expected ';' after this.
+  int for = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:17:7: Expected a class member, but got 'for'.
+  int for = 42;
+      ^^^
+
+parser/error_recovery/reserved_words_class_fields:17:11: Operator declarations must be preceded by the keyword 'operator'.
+  int for = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:17:11: The string '=' isn't a user-definable operator.
+  int for = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:17:11: A method declaration needs an explicit list of parameters.
+  int for = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:17:13: Expected a function body, but got '42'.
+  int for = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:17:13: Expected a class member, but got '42'.
+  int for = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:17:15: Expected a class member, but got ';'.
+  int for = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:18:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int if = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:18:3: Expected ';' after this.
+  int if = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:18:7: Expected a class member, but got 'if'.
+  int if = 42;
+      ^^
+
+parser/error_recovery/reserved_words_class_fields:18:10: Operator declarations must be preceded by the keyword 'operator'.
+  int if = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:18:10: The string '=' isn't a user-definable operator.
+  int if = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:18:10: A method declaration needs an explicit list of parameters.
+  int if = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:18:12: Expected a function body, but got '42'.
+  int if = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:18:12: Expected a class member, but got '42'.
+  int if = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:18:14: Expected a class member, but got ';'.
+  int if = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:19:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int in = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:19:3: Expected ';' after this.
+  int in = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:19:7: Expected a class member, but got 'in'.
+  int in = 42;
+      ^^
+
+parser/error_recovery/reserved_words_class_fields:19:10: Operator declarations must be preceded by the keyword 'operator'.
+  int in = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:19:10: The string '=' isn't a user-definable operator.
+  int in = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:19:10: A method declaration needs an explicit list of parameters.
+  int in = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:19:12: Expected a function body, but got '42'.
+  int in = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:19:12: Expected a class member, but got '42'.
+  int in = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:19:14: Expected a class member, but got ';'.
+  int in = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:20:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int is = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:20:3: Expected ';' after this.
+  int is = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:20:7: Expected a class member, but got 'is'.
+  int is = 42;
+      ^^
+
+parser/error_recovery/reserved_words_class_fields:20:10: Operator declarations must be preceded by the keyword 'operator'.
+  int is = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:20:10: The string '=' isn't a user-definable operator.
+  int is = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:20:10: A method declaration needs an explicit list of parameters.
+  int is = 42;
+         ^
+
+parser/error_recovery/reserved_words_class_fields:20:12: Expected a function body, but got '42'.
+  int is = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:20:12: Expected a class member, but got '42'.
+  int is = 42;
+           ^^
+
+parser/error_recovery/reserved_words_class_fields:20:14: Expected a class member, but got ';'.
+  int is = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:21:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int new = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:21:3: Expected ';' after this.
+  int new = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:21:7: Expected a class member, but got 'new'.
+  int new = 42;
+      ^^^
+
+parser/error_recovery/reserved_words_class_fields:21:11: Operator declarations must be preceded by the keyword 'operator'.
+  int new = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:21:11: The string '=' isn't a user-definable operator.
+  int new = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:21:11: A method declaration needs an explicit list of parameters.
+  int new = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:21:13: Expected a function body, but got '42'.
+  int new = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:21:13: Expected a class member, but got '42'.
+  int new = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:21:15: Expected a class member, but got ';'.
+  int new = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:22:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int null = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:22:3: Expected ';' after this.
+  int null = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:22:7: Expected a class member, but got 'null'.
+  int null = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:22:12: Operator declarations must be preceded by the keyword 'operator'.
+  int null = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:22:12: The string '=' isn't a user-definable operator.
+  int null = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:22:12: A method declaration needs an explicit list of parameters.
+  int null = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:22:14: Expected a function body, but got '42'.
+  int null = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:22:14: Expected a class member, but got '42'.
+  int null = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:22:16: Expected a class member, but got ';'.
+  int null = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:23:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int rethrow = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:23:3: Expected ';' after this.
+  int rethrow = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:23:7: Expected a class member, but got 'rethrow'.
+  int rethrow = 42;
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:23:15: Operator declarations must be preceded by the keyword 'operator'.
+  int rethrow = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:23:15: The string '=' isn't a user-definable operator.
+  int rethrow = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:23:15: A method declaration needs an explicit list of parameters.
+  int rethrow = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:23:17: Expected a function body, but got '42'.
+  int rethrow = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:23:17: Expected a class member, but got '42'.
+  int rethrow = 42;
+                ^^
+
+parser/error_recovery/reserved_words_class_fields:23:19: Expected a class member, but got ';'.
+  int rethrow = 42;
+                  ^
+
+parser/error_recovery/reserved_words_class_fields:24:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int return = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:24:3: Expected ';' after this.
+  int return = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:24:7: Expected a class member, but got 'return'.
+  int return = 42;
+      ^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:24:14: Operator declarations must be preceded by the keyword 'operator'.
+  int return = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:24:14: The string '=' isn't a user-definable operator.
+  int return = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:24:14: A method declaration needs an explicit list of parameters.
+  int return = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:24:16: Expected a function body, but got '42'.
+  int return = 42;
+               ^^
+
+parser/error_recovery/reserved_words_class_fields:24:16: Expected a class member, but got '42'.
+  int return = 42;
+               ^^
+
+parser/error_recovery/reserved_words_class_fields:24:18: Expected a class member, but got ';'.
+  int return = 42;
+                 ^
+
+parser/error_recovery/reserved_words_class_fields:25:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int super = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:25:3: Expected ';' after this.
+  int super = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:25:7: Expected a class member, but got 'super'.
+  int super = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:25:13: Operator declarations must be preceded by the keyword 'operator'.
+  int super = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:25:13: The string '=' isn't a user-definable operator.
+  int super = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:25:13: A method declaration needs an explicit list of parameters.
+  int super = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:25:15: Expected a function body, but got '42'.
+  int super = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:25:15: Expected a class member, but got '42'.
+  int super = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:25:17: Expected a class member, but got ';'.
+  int super = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:26:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int switch = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:26:3: Expected ';' after this.
+  int switch = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:26:7: Expected a class member, but got 'switch'.
+  int switch = 42;
+      ^^^^^^
+
+parser/error_recovery/reserved_words_class_fields:26:14: Operator declarations must be preceded by the keyword 'operator'.
+  int switch = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:26:14: The string '=' isn't a user-definable operator.
+  int switch = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:26:14: A method declaration needs an explicit list of parameters.
+  int switch = 42;
+             ^
+
+parser/error_recovery/reserved_words_class_fields:26:16: Expected a function body, but got '42'.
+  int switch = 42;
+               ^^
+
+parser/error_recovery/reserved_words_class_fields:26:16: Expected a class member, but got '42'.
+  int switch = 42;
+               ^^
+
+parser/error_recovery/reserved_words_class_fields:26:18: Expected a class member, but got ';'.
+  int switch = 42;
+                 ^
+
+parser/error_recovery/reserved_words_class_fields:27:7: Expected an identifier, but got 'this'.
+  int this = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:28:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int throw = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:28:3: Expected ';' after this.
+  int throw = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:28:7: Expected a class member, but got 'throw'.
+  int throw = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:28:13: Operator declarations must be preceded by the keyword 'operator'.
+  int throw = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:28:13: The string '=' isn't a user-definable operator.
+  int throw = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:28:13: A method declaration needs an explicit list of parameters.
+  int throw = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:28:15: Expected a function body, but got '42'.
+  int throw = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:28:15: Expected a class member, but got '42'.
+  int throw = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:28:17: Expected a class member, but got ';'.
+  int throw = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:29:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int true = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:29:3: Expected ';' after this.
+  int true = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:29:7: Expected a class member, but got 'true'.
+  int true = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:29:12: Operator declarations must be preceded by the keyword 'operator'.
+  int true = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:29:12: The string '=' isn't a user-definable operator.
+  int true = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:29:12: A method declaration needs an explicit list of parameters.
+  int true = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:29:14: Expected a function body, but got '42'.
+  int true = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:29:14: Expected a class member, but got '42'.
+  int true = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:29:16: Expected a class member, but got ';'.
+  int true = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:30:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int try = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:30:3: Expected ';' after this.
+  int try = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:30:7: Expected a class member, but got 'try'.
+  int try = 42;
+      ^^^
+
+parser/error_recovery/reserved_words_class_fields:30:11: Operator declarations must be preceded by the keyword 'operator'.
+  int try = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:30:11: The string '=' isn't a user-definable operator.
+  int try = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:30:11: A method declaration needs an explicit list of parameters.
+  int try = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:30:13: Expected a function body, but got '42'.
+  int try = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:30:13: Expected a class member, but got '42'.
+  int try = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:30:15: Expected a class member, but got ';'.
+  int try = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:31:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int var = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:31:3: Expected ';' after this.
+  int var = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:31:11: Operator declarations must be preceded by the keyword 'operator'.
+  int var = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:31:7: The return type can't be 'var'.
+  int var = 42;
+      ^^^
+
+parser/error_recovery/reserved_words_class_fields:31:11: The string '=' isn't a user-definable operator.
+  int var = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:31:11: A method declaration needs an explicit list of parameters.
+  int var = 42;
+          ^
+
+parser/error_recovery/reserved_words_class_fields:31:13: Expected a function body, but got '42'.
+  int var = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:31:13: Expected a class member, but got '42'.
+  int var = 42;
+            ^^
+
+parser/error_recovery/reserved_words_class_fields:31:15: Expected a class member, but got ';'.
+  int var = 42;
+              ^
+
+parser/error_recovery/reserved_words_class_fields:32:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int void = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:32:3: Expected ';' after this.
+  int void = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:32:12: Operator declarations must be preceded by the keyword 'operator'.
+  int void = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:32:12: The string '=' isn't a user-definable operator.
+  int void = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:32:12: A method declaration needs an explicit list of parameters.
+  int void = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:32:14: Expected a function body, but got '42'.
+  int void = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:32:14: Expected a class member, but got '42'.
+  int void = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:32:16: Expected a class member, but got ';'.
+  int void = 42;
+               ^
+
+parser/error_recovery/reserved_words_class_fields:33:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int while = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:33:3: Expected ';' after this.
+  int while = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:33:7: Expected a class member, but got 'while'.
+  int while = 42;
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_fields:33:13: Operator declarations must be preceded by the keyword 'operator'.
+  int while = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:33:13: The string '=' isn't a user-definable operator.
+  int while = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:33:13: A method declaration needs an explicit list of parameters.
+  int while = 42;
+            ^
+
+parser/error_recovery/reserved_words_class_fields:33:15: Expected a function body, but got '42'.
+  int while = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:33:15: Expected a class member, but got '42'.
+  int while = 42;
+              ^^
+
+parser/error_recovery/reserved_words_class_fields:33:17: Expected a class member, but got ';'.
+  int while = 42;
+                ^
+
+parser/error_recovery/reserved_words_class_fields:34:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int with = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:34:3: Expected ';' after this.
+  int with = 42;
+  ^^^
+
+parser/error_recovery/reserved_words_class_fields:34:7: Expected a class member, but got 'with'.
+  int with = 42;
+      ^^^^
+
+parser/error_recovery/reserved_words_class_fields:34:12: Operator declarations must be preceded by the keyword 'operator'.
+  int with = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:34:12: The string '=' isn't a user-definable operator.
+  int with = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:34:12: A method declaration needs an explicit list of parameters.
+  int with = 42;
+           ^
+
+parser/error_recovery/reserved_words_class_fields:34:14: Expected a function body, but got '42'.
+  int with = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:34:14: Expected a class member, but got '42'.
+  int with = 42;
+             ^^
+
+parser/error_recovery/reserved_words_class_fields:34:16: Expected a class member, but got ';'.
+  int with = 42;
+               ^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(WrapperClass, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, WrapperClass)
+      handleNoType(WrapperClass)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          handleRecoverableError(MissingConstFinalVarOrType, int, int)
+          handleNoType({)
+          handleIdentifier(int, fieldDeclaration)
+          handleNoFieldInitializer(assert)
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+        endClassFields(null, null, null, null, 1, int, ;)
+      endMember()
+      beginMetadataStar(assert)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'assert'., null, {token: assert}], assert, assert)
+        handleInvalidMember(assert)
+      endMember()
+      beginMetadataStar(=)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(MissingOperatorKeyword, =, =)
+        beginMethod(null, null, null, null, null, operator)
+          handleNoType(assert)
+          handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+          handleInvalidOperatorName(operator, =)
+          handleNoTypeVariables(42)
+          handleRecoverableError(MissingMethodParameters, =, =)
+          beginFormalParameters((, MemberKind.NonStaticMethod)
+          endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+          handleInvalidFunctionBody({)
+        endClassMethod(null, operator, (, null, })
+      endMember()
+      beginMetadataStar(42)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+        handleInvalidMember(42)
+      endMember()
+      beginMetadataStar(;)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+        handleInvalidMember(;)
+      endMember()
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        handleNoType(;)
+        handleIdentifier(int, fieldDeclaration)
+        handleNoFieldInitializer(break)
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+      endClassFields(null, null, null, null, 1, int, ;)
+    endMember()
+    beginMetadataStar(break)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'break'., null, {token: break}], break, break)
+      handleInvalidMember(break)
+    endMember()
+    beginMetadataStar(=)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(MissingOperatorKeyword, =, =)
+      beginMethod(null, null, null, null, null, operator)
+        handleNoType(break)
+        handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+        handleInvalidOperatorName(operator, =)
+        handleNoTypeVariables(42)
+        handleRecoverableError(MissingMethodParameters, =, =)
+        beginFormalParameters((, MemberKind.NonStaticMethod)
+        endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+        handleNoInitializers()
+        handleAsyncModifier(null, null)
+        handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+        handleInvalidFunctionBody({)
+      endClassMethod(null, operator, (, null, })
+    endMember()
+    beginMetadataStar(42)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+      handleInvalidMember(42)
+    endMember()
+    beginMetadataStar(;)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+      handleInvalidMember(;)
+    endMember()
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(MissingConstFinalVarOrType, int, int)
+      handleNoType(;)
+      handleIdentifier(int, fieldDeclaration)
+      handleNoFieldInitializer(case)
+      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+    endClassFields(null, null, null, null, 1, int, ;)
+  endMember()
+  beginMetadataStar(case)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'case'., null, {token: case}], case, case)
+    handleInvalidMember(case)
+  endMember()
+  beginMetadataStar(=)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(MissingOperatorKeyword, =, =)
+    beginMethod(null, null, null, null, null, operator)
+      handleNoType(case)
+      handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+      handleInvalidOperatorName(operator, =)
+      handleNoTypeVariables(42)
+      handleRecoverableError(MissingMethodParameters, =, =)
+      beginFormalParameters((, MemberKind.NonStaticMethod)
+      endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+      handleNoInitializers()
+      handleAsyncModifier(null, null)
+      handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+      handleInvalidFunctionBody({)
+    endClassMethod(null, operator, (, null, })
+  endMember()
+  beginMetadataStar(42)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+    handleInvalidMember(42)
+  endMember()
+  beginMetadataStar(;)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+    handleInvalidMember(;)
+  endMember()
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(MissingConstFinalVarOrType, int, int)
+    handleNoType(;)
+    handleIdentifier(int, fieldDeclaration)
+    handleNoFieldInitializer(catch)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+  endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(catch)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'catch'., null, {token: catch}], catch, catch)
+  handleInvalidMember(catch)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(MissingOperatorKeyword, =, =)
+  beginMethod(null, null, null, null, null, operator)
+    handleNoType(catch)
+    handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+    handleInvalidOperatorName(operator, =)
+    handleNoTypeVariables(42)
+    handleRecoverableError(MissingMethodParameters, =, =)
+    beginFormalParameters((, MemberKind.NonStaticMethod)
+    endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+    handleNoInitializers()
+    handleAsyncModifier(null, null)
+    handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+    handleInvalidFunctionBody({)
+  endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+  handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+  handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(MissingConstFinalVarOrType, int, int)
+  handleNoType(;)
+  handleIdentifier(int, fieldDeclaration)
+  handleNoFieldInitializer(class)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(class)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(ClassInClass, class, class)
+handleInvalidMember(class)
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(MissingOperatorKeyword, =, =)
+  beginMethod(null, null, null, null, null, operator)
+    handleNoType(class)
+    handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+    handleInvalidOperatorName(operator, =)
+    handleNoTypeVariables(42)
+    handleRecoverableError(MissingMethodParameters, =, =)
+    beginFormalParameters((, MemberKind.NonStaticMethod)
+    endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+    handleNoInitializers()
+    handleAsyncModifier(null, null)
+    handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+    handleInvalidFunctionBody({)
+  endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+  handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+  handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(MissingConstFinalVarOrType, int, int)
+  handleNoType(;)
+  handleIdentifier(int, fieldDeclaration)
+  handleNoFieldInitializer(const)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(const)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, const, null, operator)
+  handleNoType(const)
+  handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+  handleInvalidOperatorName(operator, =)
+  handleNoTypeVariables(42)
+  handleRecoverableError(MissingMethodParameters, =, =)
+  beginFormalParameters((, MemberKind.NonStaticMethod)
+  endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+  handleNoInitializers()
+  handleAsyncModifier(null, null)
+  handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+  handleInvalidFunctionBody({)
+  handleRecoverableError(ConstMethod, const, const)
+endClassMethod(null, const, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(continue)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'continue'., null, {token: continue}], continue, continue)
+handleInvalidMember(continue)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(continue)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(default)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(default)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'default'., null, {token: default}], default, default)
+handleInvalidMember(default)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(default)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(do)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'do'., null, {token: do}], do, do)
+handleInvalidMember(do)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(do)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(else)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'else'., null, {token: else}], else, else)
+handleInvalidMember(else)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(else)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(enum)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(enum)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(EnumInClass, enum, enum)
+handleInvalidMember(enum)
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(enum)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(extends)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(extends)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'extends'., null, {token: extends}], extends, extends)
+handleInvalidMember(extends)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(extends)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(false)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'false'., null, {token: false}], false, false)
+handleInvalidMember(false)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(false)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(final)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(final)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, final, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(finally)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(finally)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'finally'., null, {token: finally}], finally, finally)
+handleInvalidMember(finally)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(finally)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(for)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'for'., null, {token: for}], for, for)
+handleInvalidMember(for)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(for)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(if)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'if'., null, {token: if}], if, if)
+handleInvalidMember(if)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(if)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(in)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(in)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'in'., null, {token: in}], in, in)
+handleInvalidMember(in)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(in)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(is)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(is)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'is'., null, {token: is}], is, is)
+handleInvalidMember(is)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(is)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(new)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(new)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'new'., null, {token: new}], new, new)
+handleInvalidMember(new)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(new)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(null)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'null'., null, {token: null}], null, null)
+handleInvalidMember(null)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(null)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(rethrow)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(rethrow)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleInvalidMember(rethrow)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(rethrow)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(return)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(return)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'return'., null, {token: return}], return, return)
+handleInvalidMember(return)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(return)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(super)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(super)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'super'., null, {token: super}], super, super)
+handleInvalidMember(super)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(super)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(switch)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'switch'., null, {token: switch}], switch, switch)
+handleInvalidMember(switch)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(switch)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(this)
+handleType(int, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+handleIdentifier(this, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(throw)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(throw)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'throw'., null, {token: throw}], throw, throw)
+handleInvalidMember(throw)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(throw)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(true)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(true)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'true'., null, {token: true}], true, true)
+handleInvalidMember(true)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(true)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(try)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'try'., null, {token: try}], try, try)
+handleInvalidMember(try)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(try)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(var)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+handleRecoverableError(VarReturnType, var, var)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(var)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, var, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(void)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleVoidKeyword(void)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, void, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(while)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'while'., null, {token: while}], while, while)
+handleInvalidMember(while)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(while)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(;)
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(with)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(with)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+handleInvalidMember(with)
+endMember()
+beginMetadataStar(=)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingOperatorKeyword, =, =)
+beginMethod(null, null, null, null, null, operator)
+handleNoType(with)
+handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+handleInvalidOperatorName(operator, =)
+handleNoTypeVariables(42)
+handleRecoverableError(MissingMethodParameters, =, =)
+beginFormalParameters((, MemberKind.NonStaticMethod)
+endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidFunctionBody({)
+endClassMethod(null, operator, (, null, })
+endMember()
+beginMetadataStar(42)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+handleInvalidMember(42)
+endMember()
+beginMetadataStar(;)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+handleInvalidMember(;)
+endMember()
+endClassOrMixinBody(DeclarationKind.Class, 157, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.intertwined.expect
new file mode 100644
index 0000000..3cd1733
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.intertwined.expect
@@ -0,0 +1,3158 @@
+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(WrapperClass, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, WrapperClass)
+        parseClass(WrapperClass, class, class, WrapperClass)
+          parseClassHeaderOpt(WrapperClass, class, class)
+            parseClassExtendsOpt(WrapperClass)
+              listener: handleNoType(WrapperClass)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(WrapperClass)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(WrapperClass)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(WrapperClass, DeclarationKind.Class, WrapperClass)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, {, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType({)
+                ensureIdentifier({, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(assert)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, assert)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(assert)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(assert, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'assert'., null, {token: assert}], assert, assert)
+                listener: handleInvalidMember(assert)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(assert, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(assert)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(assert, assert, null, null, null, null, null, assert, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(assert, null, null, null, null, null, assert, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(assert, null, null, null, null, null, assert, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(assert)
+                    parseOperatorName(assert)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(break)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, break)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(break)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'break'., null, {token: break}], break, break)
+                listener: handleInvalidMember(break)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(break, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(break)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(break, break, null, null, null, null, null, break, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(break, null, null, null, null, null, break, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(break, null, null, null, null, null, break, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(break)
+                    parseOperatorName(break)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(case)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, case)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(case)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'case'., null, {token: case}], case, case)
+                listener: handleInvalidMember(case)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(case, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(case)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(case, case, null, null, null, null, null, case, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(case, null, null, null, null, null, case, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(case, null, null, null, null, null, case, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(case)
+                    parseOperatorName(case)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(catch)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, catch)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(catch)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'catch'., null, {token: catch}], catch, catch)
+                listener: handleInvalidMember(catch)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(catch, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(catch)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(catch, catch, null, null, null, null, null, catch, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(catch, null, null, null, null, null, catch, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(catch, null, null, null, null, null, catch, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(catch)
+                    parseOperatorName(catch)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(class)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, class)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(class)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportAndSkipClassInClass(class)
+                  reportRecoverableError(class, ClassInClass)
+                    listener: handleRecoverableError(ClassInClass, class, class)
+                  listener: handleInvalidMember(class)
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(class, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(class)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(class, class, null, null, null, null, null, class, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(class, null, null, null, null, null, class, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(class, null, null, null, null, null, class, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(class)
+                    parseOperatorName(class)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(const)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, const)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(const)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(const, ;, null, null, null, null, const, const, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(;, null, null, null, null, const, const, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(;, null, null, null, null, const, const, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, const, null, operator)
+                    listener: handleNoType(const)
+                    parseOperatorName(const)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    reportRecoverableError(const, ConstMethod)
+                      listener: handleRecoverableError(ConstMethod, const, const)
+                    listener: endClassMethod(null, const, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(continue)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, continue)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(continue)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'continue'., null, {token: continue}], continue, continue)
+                listener: handleInvalidMember(continue)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(continue, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(continue)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(continue, continue, null, null, null, null, null, continue, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(continue, null, null, null, null, null, continue, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(continue, null, null, null, null, null, continue, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(continue)
+                    parseOperatorName(continue)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(default)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, default)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(default)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'default'., null, {token: default}], default, default)
+                listener: handleInvalidMember(default)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(default, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(default)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(default, default, null, null, null, null, null, default, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(default, null, null, null, null, null, default, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(default, null, null, null, null, null, default, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(default)
+                    parseOperatorName(default)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(do)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, do)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(do)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'do'., null, {token: do}], do, do)
+                listener: handleInvalidMember(do)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(do, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(do)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(do, do, null, null, null, null, null, do, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(do, null, null, null, null, null, do, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(do, null, null, null, null, null, do, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(do)
+                    parseOperatorName(do)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(else)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, else)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(else)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'else'., null, {token: else}], else, else)
+                listener: handleInvalidMember(else)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(else, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(else)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(else, else, null, null, null, null, null, else, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(else, null, null, null, null, null, else, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(else, null, null, null, null, null, else, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(else)
+                    parseOperatorName(else)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(enum)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, enum)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(enum)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportAndSkipEnumInClass(enum)
+                  reportRecoverableError(enum, EnumInClass)
+                    listener: handleRecoverableError(EnumInClass, enum, enum)
+                  listener: handleInvalidMember(enum)
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(enum, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(enum)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(enum, enum, null, null, null, null, null, enum, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(enum, null, null, null, null, null, enum, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(enum, null, null, null, null, null, enum, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(enum)
+                    parseOperatorName(enum)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(extends)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, extends)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(extends)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'extends'., null, {token: extends}], extends, extends)
+                listener: handleInvalidMember(extends)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(extends, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(extends)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(extends, extends, null, null, null, null, null, extends, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(extends, null, null, null, null, null, extends, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(extends, null, null, null, null, null, extends, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(extends)
+                    parseOperatorName(extends)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(false)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, false)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(false)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(false, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'false'., null, {token: false}], false, false)
+                listener: handleInvalidMember(false)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(false, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(false)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(false, false, null, null, null, null, null, false, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(false, null, null, null, null, null, false, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(false, null, null, null, null, null, false, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(false)
+                    parseOperatorName(false)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(final)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(final, ;, null, null, null, null, final, final, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(;, null, null, null, null, final, final, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(;, null, null, null, null, final, final, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+                      listener: handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(final)
+                    parseOperatorName(final)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, final, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(finally)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, finally)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(finally)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'finally'., null, {token: finally}], finally, finally)
+                listener: handleInvalidMember(finally)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(finally, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(finally)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(finally, finally, null, null, null, null, null, finally, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(finally, null, null, null, null, null, finally, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(finally, null, null, null, null, null, finally, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(finally)
+                    parseOperatorName(finally)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(for)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, for)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(for)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'for'., null, {token: for}], for, for)
+                listener: handleInvalidMember(for)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(for, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(for)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(for, for, null, null, null, null, null, for, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(for, null, null, null, null, null, for, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(for, null, null, null, null, null, for, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(for)
+                    parseOperatorName(for)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(if)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, if)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(if)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'if'., null, {token: if}], if, if)
+                listener: handleInvalidMember(if)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(if, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(if)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(if, if, null, null, null, null, null, if, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(if, null, null, null, null, null, if, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(if, null, null, null, null, null, if, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(if)
+                    parseOperatorName(if)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(in)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, in)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(in)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'in'., null, {token: in}], in, in)
+                listener: handleInvalidMember(in)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(in, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(in)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(in, in, null, null, null, null, null, in, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(in, null, null, null, null, null, in, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(in, null, null, null, null, null, in, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(in)
+                    parseOperatorName(in)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(is)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, is)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(is)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'is'., null, {token: is}], is, is)
+                listener: handleInvalidMember(is)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(is, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(is)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(is, is, null, null, null, null, null, is, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(is, null, null, null, null, null, is, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(is, null, null, null, null, null, is, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(is)
+                    parseOperatorName(is)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(new)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, new)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(new)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(new, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'new'., null, {token: new}], new, new)
+                listener: handleInvalidMember(new)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(new, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(new)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(new, new, null, null, null, null, null, new, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(new, null, null, null, null, null, new, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(new, null, null, null, null, null, new, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(new)
+                    parseOperatorName(new)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(null)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, null)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(null)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(null, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'null'., null, {token: null}], null, null)
+                listener: handleInvalidMember(null)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(null, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(null)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(null, null, null, null, null, null, null, null, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(null, null, null, null, null, null, null, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(null, null, null, null, null, null, null, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(null)
+                    parseOperatorName(null)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(rethrow)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, rethrow)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(rethrow)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+                listener: handleInvalidMember(rethrow)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(rethrow, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(rethrow)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(rethrow, rethrow, null, null, null, null, null, rethrow, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(rethrow, null, null, null, null, null, rethrow, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(rethrow, null, null, null, null, null, rethrow, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(rethrow)
+                    parseOperatorName(rethrow)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(return)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, return)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(return)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'return'., null, {token: return}], return, return)
+                listener: handleInvalidMember(return)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(return, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(return)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(return, return, null, null, null, null, null, return, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(return, null, null, null, null, null, return, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(return, null, null, null, null, null, return, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(return)
+                    parseOperatorName(return)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(super)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, super)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(super)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(super, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'super'., null, {token: super}], super, super)
+                listener: handleInvalidMember(super)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(super, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(super)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(super, super, null, null, null, null, null, super, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(super, null, null, null, null, null, super, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(super, null, null, null, null, null, super, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(super)
+                    parseOperatorName(super)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(switch)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, switch)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(switch)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'switch'., null, {token: switch}], switch, switch)
+                listener: handleInvalidMember(switch)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(switch, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(switch)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(switch, switch, null, null, null, null, null, switch, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(switch, null, null, null, null, null, switch, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(switch, null, null, null, null, null, switch, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(switch)
+                    parseOperatorName(switch)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(int, ;, null, null, null, null, null, ;, Instance of 'SimpleType', null, DeclarationKind.Class, WrapperClass)
+                parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', this, DeclarationKind.Class, WrapperClass)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(this)
+                  listener: handleType(int, null)
+                  ensureIdentifier(int, fieldDeclaration)
+                    reportRecoverableErrorWithToken(this, Instance of 'Template<(Token) => Message>')
+                      listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+                    listener: handleIdentifier(this, fieldDeclaration)
+                  parseFieldInitializerOpt(this, this, null, null, DeclarationKind.Class, WrapperClass)
+                    listener: beginFieldInitializer(=)
+                    parseExpression(=)
+                      parsePrecedenceExpression(=, 1, true)
+                        parseUnaryExpression(=, true)
+                          parsePrimary(=, expression)
+                            parseLiteralInt(=)
+                              listener: handleLiteralInt(42)
+                    listener: endFieldInitializer(=, ;)
+                  listener: endClassFields(null, null, null, null, 1, int, ;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(throw)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, throw)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(throw)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(throw, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'throw'., null, {token: throw}], throw, throw)
+                listener: handleInvalidMember(throw)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(throw, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(throw)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(throw, throw, null, null, null, null, null, throw, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(throw, null, null, null, null, null, throw, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(throw, null, null, null, null, null, throw, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(throw)
+                    parseOperatorName(throw)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(true)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, true)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(true)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(true, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'true'., null, {token: true}], true, true)
+                listener: handleInvalidMember(true)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(true, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(true)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(true, true, null, null, null, null, null, true, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(true, null, null, null, null, null, true, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(true, null, null, null, null, null, true, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(true)
+                    parseOperatorName(true)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(try)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, try)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(try)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'try'., null, {token: try}], try, try)
+                listener: handleInvalidMember(try)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(try, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(try)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(try, try, null, null, null, null, null, try, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(try, null, null, null, null, null, try, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(try, null, null, null, null, null, try, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(try)
+                    parseOperatorName(try)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(var)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, var)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(var, ;, null, null, null, null, var, var, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(;, null, null, null, null, var, var, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(;, null, null, null, null, var, var, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    reportRecoverableError(var, VarReturnType)
+                      listener: handleRecoverableError(VarReturnType, var, var)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(var)
+                    parseOperatorName(var)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, var, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(void)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, void)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(void)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(void, ;, null, null, null, null, null, ;, Instance of 'VoidType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(;, null, null, null, null, null, ;, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(;, null, null, null, null, null, ;, Instance of 'VoidType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleVoidKeyword(void)
+                    parseOperatorName(void)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, void, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(while)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, while)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(while)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'while'., null, {token: while}], while, while)
+                listener: handleInvalidMember(while)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(while, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(while)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(while, while, null, null, null, null, null, while, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(while, null, null, null, null, null, while, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(while, null, null, null, null, null, while, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(while)
+                    parseOperatorName(while)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(;)
+                ensureIdentifier(;, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(with)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, with)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(with)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+                listener: handleInvalidMember(with)
+                listener: endMember()
+            notEofOrValue(}, =)
+            parseClassOrMixinOrExtensionMemberImpl(with, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(with)
+                listener: beginMetadataStar(=)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(with, with, null, null, null, null, null, with, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseInvalidOperatorDeclaration(with, null, null, null, null, null, with, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(=, MissingOperatorKeyword)
+                    listener: handleRecoverableError(MissingOperatorKeyword, =, =)
+                  rewriter()
+                  parseMethod(with, null, null, null, null, null, with, Instance of 'NoType', null, operator, DeclarationKind.Class, WrapperClass)
+                    listener: beginMethod(null, null, null, null, null, operator)
+                    listener: handleNoType(with)
+                    parseOperatorName(with)
+                      isUnaryMinus(=)
+                      reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[InvalidOperator, The string '=' isn't a user-definable operator., null, {token: =}], =, =)
+                      listener: handleInvalidOperatorName(operator, =)
+                    parseMethodTypeVar(=)
+                      listener: handleNoTypeVariables(42)
+                    parseGetterOrFormalParameters(=, operator, false, MemberKind.NonStaticMethod)
+                      missingParameterMessage(MemberKind.NonStaticMethod)
+                      reportRecoverableError(=, MissingMethodParameters)
+                        listener: handleRecoverableError(MissingMethodParameters, =, =)
+                      rewriter()
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                    parseInitializersOpt())
+                      listener: handleNoInitializers()
+                    parseAsyncModifierOpt())
+                      listener: handleAsyncModifier(null, null)
+                      inPlainSync()
+                    inPlainSync()
+                    parseFunctionBody(), false, true)
+                      ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+                        reportRecoverableError(42, Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}])
+                          listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '42'., null, {token: 42}], 42, 42)
+                        insertBlock())
+                          rewriter()
+                          rewriter()
+                      listener: handleInvalidFunctionBody({)
+                    listener: endClassMethod(null, operator, (, null, })
+                  listener: endMember()
+            notEofOrValue(}, 42)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(42)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(}, }, null, null, null, null, null, }, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(42, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got '42'., null, {token: 42}], 42, 42)
+                listener: handleInvalidMember(42)
+                listener: endMember()
+            notEofOrValue(}, ;)
+            parseClassOrMixinOrExtensionMemberImpl(42, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(42)
+                listener: beginMetadataStar(;)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(42, 42, null, null, null, null, null, 42, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(;, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got ';'., null, {token: ;}], ;, ;)
+                listener: handleInvalidMember(;)
+                listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 157, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.parser.expect
new file mode 100644
index 0000000..0ed105a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.parser.expect
@@ -0,0 +1,73 @@
+NOTICE: Stream was rewritten by parser!
+
+class WrapperClass {
+int ;assert operator= (){}42;
+int ;break operator= (){}42;
+int ;case operator= (){}42;
+int ;catch operator= (){}42;
+int ;class operator= (){}42;
+int ;const operator= (){}42;
+int ;continue operator= (){}42;
+int ;default operator= (){}42;
+int ;do operator= (){}42;
+int ;else operator= (){}42;
+int ;enum operator= (){}42;
+int ;extends operator= (){}42;
+int ;false operator= (){}42;
+int ;final operator= (){}42;
+int ;finally operator= (){}42;
+int ;for operator= (){}42;
+int ;if operator= (){}42;
+int ;in operator= (){}42;
+int ;is operator= (){}42;
+int ;new operator= (){}42;
+int ;null operator= (){}42;
+int ;rethrow operator= (){}42;
+int ;return operator= (){}42;
+int ;super operator= (){}42;
+int ;switch operator= (){}42;
+int this = 42;
+int ;throw operator= (){}42;
+int ;true operator= (){}42;
+int ;try operator= (){}42;
+int ;var operator= (){}42;
+int ;void operator= (){}42;
+int ;while operator= (){}42;
+int ;with operator= (){}42;
+}
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] ;[SyntheticToken]assert[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]break[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]case[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]catch[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]class[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]const[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]continue[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]default[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]do[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]else[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]enum[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]extends[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]false[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]final[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]finally[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]for[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]if[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]in[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]is[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]new[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]null[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]rethrow[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]return[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]super[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]switch[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] this[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]throw[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]true[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]try[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]var[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]void[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]while[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+int[StringToken] ;[SyntheticToken]with[KeywordToken] operator[SyntheticKeywordToken]=[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]42[StringToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.scanner.expect
new file mode 100644
index 0000000..99a26c4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_fields.dart.scanner.expect
@@ -0,0 +1,71 @@
+class WrapperClass {
+int assert = 42;
+int break = 42;
+int case = 42;
+int catch = 42;
+int class = 42;
+int const = 42;
+int continue = 42;
+int default = 42;
+int do = 42;
+int else = 42;
+int enum = 42;
+int extends = 42;
+int false = 42;
+int final = 42;
+int finally = 42;
+int for = 42;
+int if = 42;
+int in = 42;
+int is = 42;
+int new = 42;
+int null = 42;
+int rethrow = 42;
+int return = 42;
+int super = 42;
+int switch = 42;
+int this = 42;
+int throw = 42;
+int true = 42;
+int try = 42;
+int var = 42;
+int void = 42;
+int while = 42;
+int with = 42;
+}
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] assert[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] break[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] case[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] catch[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] class[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] const[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] continue[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] default[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] do[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] else[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] enum[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] extends[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] false[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] final[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] finally[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] for[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] if[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] in[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] is[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] new[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] null[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] rethrow[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] return[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] super[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] switch[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] this[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] throw[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] true[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] try[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] var[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] void[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] while[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] with[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart
new file mode 100644
index 0000000..0ee7ab3
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart
@@ -0,0 +1,166 @@
+class WrapperClass {
+  int assert(int x) {
+    if (x == 0) return 42;
+    return assert(x-1) + 1;
+  }
+
+  int break(int x) {
+    if (x == 0) return 42;
+    return break(x-1) + 1;
+  }
+
+  int case(int x) {
+    if (x == 0) return 42;
+    return case(x-1) + 1;
+  }
+
+  int catch(int x) {
+    if (x == 0) return 42;
+    return catch(x-1) + 1;
+  }
+
+  int class(int x) {
+    if (x == 0) return 42;
+    return class(x-1) + 1;
+  }
+
+  int const(int x) {
+    if (x == 0) return 42;
+    return const(x-1) + 1;
+  }
+
+  int continue(int x) {
+    if (x == 0) return 42;
+    return continue(x-1) + 1;
+  }
+
+  int default(int x) {
+    if (x == 0) return 42;
+    return default(x-1) + 1;
+  }
+
+  int do(int x) {
+    if (x == 0) return 42;
+    return do(x-1) + 1;
+  }
+
+  int else(int x) {
+    if (x == 0) return 42;
+    return else(x-1) + 1;
+  }
+
+  int enum(int x) {
+    if (x == 0) return 42;
+    return enum(x-1) + 1;
+  }
+
+  int extends(int x) {
+    if (x == 0) return 42;
+    return extends(x-1) + 1;
+  }
+
+  int false(int x) {
+    if (x == 0) return 42;
+    return false(x-1) + 1;
+  }
+
+  int final(int x) {
+    if (x == 0) return 42;
+    return final(x-1) + 1;
+  }
+
+  int finally(int x) {
+    if (x == 0) return 42;
+    return finally(x-1) + 1;
+  }
+
+  int for(int x) {
+    if (x == 0) return 42;
+    return for(x-1) + 1;
+  }
+
+  int if(int x) {
+    if (x == 0) return 42;
+    return if(x-1) + 1;
+  }
+
+  int in(int x) {
+    if (x == 0) return 42;
+    return in(x-1) + 1;
+  }
+
+  int is(int x) {
+    if (x == 0) return 42;
+    return is(x-1) + 1;
+  }
+
+  int new(int x) {
+    if (x == 0) return 42;
+    return new(x-1) + 1;
+  }
+
+  int null(int x) {
+    if (x == 0) return 42;
+    return null(x-1) + 1;
+  }
+
+  int rethrow(int x) {
+    if (x == 0) return 42;
+    return rethrow(x-1) + 1;
+  }
+
+  int return(int x) {
+    if (x == 0) return 42;
+    return return(x-1) + 1;
+  }
+
+  int super(int x) {
+    if (x == 0) return 42;
+    return super(x-1) + 1;
+  }
+
+  int switch(int x) {
+    if (x == 0) return 42;
+    return switch(x-1) + 1;
+  }
+
+  int this(int x) {
+    if (x == 0) return 42;
+    return this(x-1) + 1;
+  }
+
+  int throw(int x) {
+    if (x == 0) return 42;
+    return throw(x-1) + 1;
+  }
+
+  int true(int x) {
+    if (x == 0) return 42;
+    return true(x-1) + 1;
+  }
+
+  int try(int x) {
+    if (x == 0) return 42;
+    return try(x-1) + 1;
+  }
+
+  int var(int x) {
+    if (x == 0) return 42;
+    return var(x-1) + 1;
+  }
+
+  int void(int x) {
+    if (x == 0) return 42;
+    return void(x-1) + 1;
+  }
+
+  int while(int x) {
+    if (x == 0) return 42;
+    return while(x-1) + 1;
+  }
+
+  int with(int x) {
+    if (x == 0) return 42;
+    return with(x-1) + 1;
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.expect
new file mode 100644
index 0000000..adf4e0b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.expect
@@ -0,0 +1,3465 @@
+Problems reported:
+
+parser/error_recovery/reserved_words_class_methods:2:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int assert(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:2:3: Expected ';' after this.
+  int assert(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:2:7: Expected a class member, but got 'assert'.
+  int assert(int x) {
+      ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:2:13: Expected an identifier, but got '('.
+  int assert(int x) {
+            ^
+
+parser/error_recovery/reserved_words_class_methods:4:12: `assert` can't be used as an expression.
+    return assert(x-1) + 1;
+           ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:7:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int break(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:7:3: Expected ';' after this.
+  int break(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:7:7: Expected a class member, but got 'break'.
+  int break(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:7:12: Expected an identifier, but got '('.
+  int break(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:9:12: Expected an identifier, but got 'break'.
+    return break(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:9:12: Expected ';' after this.
+    return break(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:9:12: A break statement can't be used outside of a loop or switch statement.
+    return break(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:9:12: Expected ';' after this.
+    return break(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:12:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int case(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:12:3: Expected ';' after this.
+  int case(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:12:7: Expected a class member, but got 'case'.
+  int case(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:12:11: Expected an identifier, but got '('.
+  int case(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:14:12: Expected an identifier, but got 'case'.
+    return case(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:17:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int catch(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:17:3: Expected ';' after this.
+  int catch(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:17:7: Expected a class member, but got 'catch'.
+  int catch(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:17:12: Expected an identifier, but got '('.
+  int catch(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:19:12: Expected an identifier, but got 'catch'.
+    return catch(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:22:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int class(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:22:3: Expected ';' after this.
+  int class(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:22:7: Classes can't be declared inside other classes.
+  int class(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:22:12: Expected an identifier, but got '('.
+  int class(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:24:12: Expected an identifier, but got 'class'.
+    return class(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:27:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int const(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:27:3: Expected ';' after this.
+  int const(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:27:12: Expected an identifier, but got '('.
+  int const(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:29:17: Expected an identifier, but got '('.
+    return const(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_class_methods:27:7: Getters, setters and methods can't be declared to be 'const'.
+  int const(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:32:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int continue(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:32:3: Expected ';' after this.
+  int continue(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:32:7: Expected a class member, but got 'continue'.
+  int continue(int x) {
+      ^^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:32:15: Expected an identifier, but got '('.
+  int continue(int x) {
+              ^
+
+parser/error_recovery/reserved_words_class_methods:34:12: Expected an identifier, but got 'continue'.
+    return continue(x-1) + 1;
+           ^^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:34:12: Expected ';' after this.
+    return continue(x-1) + 1;
+           ^^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:34:12: A continue statement can't be used outside of a loop or switch statement.
+    return continue(x-1) + 1;
+           ^^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:34:12: Expected ';' after this.
+    return continue(x-1) + 1;
+           ^^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:37:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int default(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:37:3: Expected ';' after this.
+  int default(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:37:7: Expected a class member, but got 'default'.
+  int default(int x) {
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:37:14: Expected an identifier, but got '('.
+  int default(int x) {
+             ^
+
+parser/error_recovery/reserved_words_class_methods:39:12: Expected an identifier, but got 'default'.
+    return default(x-1) + 1;
+           ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:42:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int do(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:42:3: Expected ';' after this.
+  int do(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:42:7: Expected a class member, but got 'do'.
+  int do(int x) {
+      ^^
+
+parser/error_recovery/reserved_words_class_methods:42:9: Expected an identifier, but got '('.
+  int do(int x) {
+        ^
+
+parser/error_recovery/reserved_words_class_methods:44:12: Expected an identifier, but got 'do'.
+    return do(x-1) + 1;
+           ^^
+
+parser/error_recovery/reserved_words_class_methods:44:12: Expected ';' after this.
+    return do(x-1) + 1;
+           ^^
+
+parser/error_recovery/reserved_words_class_methods:45:3: Expected 'while' before this.
+  }
+  ^
+
+parser/error_recovery/reserved_words_class_methods:45:3: Expected to find '('.
+  }
+  ^
+
+parser/error_recovery/reserved_words_class_methods:45:3: Expected an identifier, but got '}'.
+  }
+  ^
+
+parser/error_recovery/reserved_words_class_methods:45:3: Expected ';' after this.
+  }
+  ^
+
+parser/error_recovery/reserved_words_class_methods:47:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int else(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:47:3: Expected ';' after this.
+  int else(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:47:7: Expected a class member, but got 'else'.
+  int else(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:47:11: Expected an identifier, but got '('.
+  int else(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:49:12: Expected an identifier, but got 'else'.
+    return else(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:49:12: Expected ';' after this.
+    return else(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:49:12: Expected an identifier, but got 'else'.
+    return else(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:49:12: Expected ';' after this.
+    return else(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:49:12: Unexpected token ';'.
+    return else(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:52:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int enum(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:52:3: Expected ';' after this.
+  int enum(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:52:7: Enums can't be declared inside classes.
+  int enum(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:52:11: Expected an identifier, but got '('.
+  int enum(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:54:12: Expected an identifier, but got 'enum'.
+    return enum(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:57:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int extends(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:57:3: Expected ';' after this.
+  int extends(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:57:7: Expected a class member, but got 'extends'.
+  int extends(int x) {
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:57:14: Expected an identifier, but got '('.
+  int extends(int x) {
+             ^
+
+parser/error_recovery/reserved_words_class_methods:59:12: Expected an identifier, but got 'extends'.
+    return extends(x-1) + 1;
+           ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:62:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int false(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:62:3: Expected ';' after this.
+  int false(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:62:7: Expected a class member, but got 'false'.
+  int false(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:62:12: Expected an identifier, but got '('.
+  int false(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:67:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int final(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:67:3: Expected ';' after this.
+  int final(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:67:7: Can't have modifier 'final' here.
+  int final(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:67:12: Expected an identifier, but got '('.
+  int final(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:69:12: Expected an identifier, but got 'final'.
+    return final(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:69:12: Expected ';' after this.
+    return final(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:69:17: Expected an identifier, but got '('.
+    return final(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_class_methods:69:18: Expected ';' after this.
+    return final(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_class_methods:69:20: Expected ';' after this.
+    return final(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_class_methods:69:21: Expected an identifier, but got ')'.
+    return final(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_class_methods:69:21: Expected ';' after this.
+    return final(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_class_methods:69:21: Unexpected token ';'.
+    return final(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_class_methods:69:23: '+' is not a prefix operator.
+    return final(x-1) + 1;
+                      ^
+
+parser/error_recovery/reserved_words_class_methods:72:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int finally(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:72:3: Expected ';' after this.
+  int finally(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:72:7: Expected a class member, but got 'finally'.
+  int finally(int x) {
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:72:14: Expected an identifier, but got '('.
+  int finally(int x) {
+             ^
+
+parser/error_recovery/reserved_words_class_methods:74:12: Expected an identifier, but got 'finally'.
+    return finally(x-1) + 1;
+           ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:77:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int for(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:77:3: Expected ';' after this.
+  int for(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:77:7: Expected a class member, but got 'for'.
+  int for(int x) {
+      ^^^
+
+parser/error_recovery/reserved_words_class_methods:77:10: Expected an identifier, but got '('.
+  int for(int x) {
+         ^
+
+parser/error_recovery/reserved_words_class_methods:79:12: Expected an identifier, but got 'for'.
+    return for(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:79:12: Expected ';' after this.
+    return for(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:79:18: Expected ';' after this.
+    return for(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_class_methods:79:19: Expected an identifier, but got ')'.
+    return for(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_class_methods:79:19: Expected ';' after this.
+    return for(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_class_methods:79:21: '+' is not a prefix operator.
+    return for(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_class_methods:82:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int if(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:82:3: Expected ';' after this.
+  int if(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:82:7: Expected a class member, but got 'if'.
+  int if(int x) {
+      ^^
+
+parser/error_recovery/reserved_words_class_methods:82:9: Expected an identifier, but got '('.
+  int if(int x) {
+        ^
+
+parser/error_recovery/reserved_words_class_methods:84:12: Expected an identifier, but got 'if'.
+    return if(x-1) + 1;
+           ^^
+
+parser/error_recovery/reserved_words_class_methods:84:12: Expected ';' after this.
+    return if(x-1) + 1;
+           ^^
+
+parser/error_recovery/reserved_words_class_methods:84:20: '+' is not a prefix operator.
+    return if(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_class_methods:87:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int in(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:87:3: Expected ';' after this.
+  int in(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:87:7: Expected a class member, but got 'in'.
+  int in(int x) {
+      ^^
+
+parser/error_recovery/reserved_words_class_methods:87:9: Expected an identifier, but got '('.
+  int in(int x) {
+        ^
+
+parser/error_recovery/reserved_words_class_methods:89:12: Expected an identifier, but got 'in'.
+    return in(x-1) + 1;
+           ^^
+
+parser/error_recovery/reserved_words_class_methods:92:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int is(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:92:3: Expected ';' after this.
+  int is(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:92:7: Expected a class member, but got 'is'.
+  int is(int x) {
+      ^^
+
+parser/error_recovery/reserved_words_class_methods:92:9: Expected an identifier, but got '('.
+  int is(int x) {
+        ^
+
+parser/error_recovery/reserved_words_class_methods:94:12: Expected an identifier, but got 'is'.
+    return is(x-1) + 1;
+           ^^
+
+parser/error_recovery/reserved_words_class_methods:94:14: Expected a type, but got '('.
+    return is(x-1) + 1;
+             ^
+
+parser/error_recovery/reserved_words_class_methods:94:14: Expected ';' after this.
+    return is(x-1) + 1;
+             ^
+
+parser/error_recovery/reserved_words_class_methods:97:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int new(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:97:3: Expected ';' after this.
+  int new(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:97:7: Expected a class member, but got 'new'.
+  int new(int x) {
+      ^^^
+
+parser/error_recovery/reserved_words_class_methods:97:10: Expected an identifier, but got '('.
+  int new(int x) {
+         ^
+
+parser/error_recovery/reserved_words_class_methods:99:15: Expected an identifier, but got '('.
+    return new(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_class_methods:102:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int null(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:102:3: Expected ';' after this.
+  int null(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:102:7: Expected a class member, but got 'null'.
+  int null(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:102:11: Expected an identifier, but got '('.
+  int null(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:107:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int rethrow(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:107:3: Expected ';' after this.
+  int rethrow(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:107:7: Expected a class member, but got 'rethrow'.
+  int rethrow(int x) {
+      ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:107:14: Expected an identifier, but got '('.
+  int rethrow(int x) {
+             ^
+
+parser/error_recovery/reserved_words_class_methods:109:12: Expected an identifier, but got 'rethrow'.
+    return rethrow(x-1) + 1;
+           ^^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:112:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int return(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:112:3: Expected ';' after this.
+  int return(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:112:7: Expected a class member, but got 'return'.
+  int return(int x) {
+      ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:112:13: Expected an identifier, but got '('.
+  int return(int x) {
+            ^
+
+parser/error_recovery/reserved_words_class_methods:114:12: Unexpected token 'return'.
+    return return(x-1) + 1;
+           ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:117:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int super(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:117:3: Expected ';' after this.
+  int super(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:117:7: Expected a class member, but got 'super'.
+  int super(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:117:12: Expected an identifier, but got '('.
+  int super(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:122:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int switch(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:122:3: Expected ';' after this.
+  int switch(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:122:7: Expected a class member, but got 'switch'.
+  int switch(int x) {
+      ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:122:13: Expected an identifier, but got '('.
+  int switch(int x) {
+            ^
+
+parser/error_recovery/reserved_words_class_methods:124:12: Expected an identifier, but got 'switch'.
+    return switch(x-1) + 1;
+           ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:124:12: Expected ';' after this.
+    return switch(x-1) + 1;
+           ^^^^^^
+
+parser/error_recovery/reserved_words_class_methods:124:22: A switch statement must have a body, even if it is empty.
+    return switch(x-1) + 1;
+                     ^
+
+parser/error_recovery/reserved_words_class_methods:124:24: '+' is not a prefix operator.
+    return switch(x-1) + 1;
+                       ^
+
+parser/error_recovery/reserved_words_class_methods:127:7: Expected an identifier, but got 'this'.
+  int this(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:127:7: Expected ';' after this.
+  int this(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:127:11: Expected an identifier, but got '('.
+  int this(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:132:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int throw(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:132:3: Expected ';' after this.
+  int throw(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:132:7: Expected a class member, but got 'throw'.
+  int throw(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:132:12: Expected an identifier, but got '('.
+  int throw(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:137:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int true(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:137:3: Expected ';' after this.
+  int true(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:137:7: Expected a class member, but got 'true'.
+  int true(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:137:11: Expected an identifier, but got '('.
+  int true(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:142:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int try(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:142:3: Expected ';' after this.
+  int try(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:142:7: Expected a class member, but got 'try'.
+  int try(int x) {
+      ^^^
+
+parser/error_recovery/reserved_words_class_methods:142:10: Expected an identifier, but got '('.
+  int try(int x) {
+         ^
+
+parser/error_recovery/reserved_words_class_methods:144:12: Expected an identifier, but got 'try'.
+    return try(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:144:12: Expected ';' after this.
+    return try(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:144:12: A try statement must have a body, even if it is empty.
+    return try(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:144:12: A try block must be followed by an 'on', 'catch', or 'finally' clause.
+    return try(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:147:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int var(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:147:3: Expected ';' after this.
+  int var(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:147:7: The return type can't be 'var'.
+  int var(int x) {
+      ^^^
+
+parser/error_recovery/reserved_words_class_methods:147:10: Expected an identifier, but got '('.
+  int var(int x) {
+         ^
+
+parser/error_recovery/reserved_words_class_methods:149:12: Expected an identifier, but got 'var'.
+    return var(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:149:12: Expected ';' after this.
+    return var(x-1) + 1;
+           ^^^
+
+parser/error_recovery/reserved_words_class_methods:149:15: Expected an identifier, but got '('.
+    return var(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_class_methods:149:16: Expected ';' after this.
+    return var(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_class_methods:149:18: Expected ';' after this.
+    return var(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_class_methods:149:19: Expected an identifier, but got ')'.
+    return var(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_class_methods:149:19: Expected ';' after this.
+    return var(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_class_methods:149:19: Unexpected token ';'.
+    return var(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_class_methods:149:21: '+' is not a prefix operator.
+    return var(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_class_methods:152:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int void(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:152:3: Expected ';' after this.
+  int void(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:152:11: Expected an identifier, but got '('.
+  int void(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:154:12: Expected an identifier, but got 'void'.
+    return void(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:154:12: Expected ';' after this.
+    return void(x-1) + 1;
+           ^^^^
+
+parser/error_recovery/reserved_words_class_methods:154:16: Expected an identifier, but got '('.
+    return void(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_class_methods:154:17: Expected ';' after this.
+    return void(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_class_methods:154:19: Expected ';' after this.
+    return void(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_class_methods:154:20: Expected an identifier, but got ')'.
+    return void(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_class_methods:154:20: Expected ';' after this.
+    return void(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_class_methods:154:20: Unexpected token ';'.
+    return void(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_class_methods:154:22: '+' is not a prefix operator.
+    return void(x-1) + 1;
+                     ^
+
+parser/error_recovery/reserved_words_class_methods:157:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int while(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:157:3: Expected ';' after this.
+  int while(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:157:7: Expected a class member, but got 'while'.
+  int while(int x) {
+      ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:157:12: Expected an identifier, but got '('.
+  int while(int x) {
+           ^
+
+parser/error_recovery/reserved_words_class_methods:159:12: Expected an identifier, but got 'while'.
+    return while(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:159:12: Expected ';' after this.
+    return while(x-1) + 1;
+           ^^^^^
+
+parser/error_recovery/reserved_words_class_methods:159:23: '+' is not a prefix operator.
+    return while(x-1) + 1;
+                      ^
+
+parser/error_recovery/reserved_words_class_methods:162:3: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  int with(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:162:3: Expected ';' after this.
+  int with(int x) {
+  ^^^
+
+parser/error_recovery/reserved_words_class_methods:162:7: Expected a class member, but got 'with'.
+  int with(int x) {
+      ^^^^
+
+parser/error_recovery/reserved_words_class_methods:162:11: Expected an identifier, but got '('.
+  int with(int x) {
+          ^
+
+parser/error_recovery/reserved_words_class_methods:164:12: Expected an identifier, but got 'with'.
+    return with(x-1) + 1;
+           ^^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(WrapperClass, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, WrapperClass)
+      handleNoType(WrapperClass)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          handleRecoverableError(MissingConstFinalVarOrType, int, int)
+          handleNoType({)
+          handleIdentifier(int, fieldDeclaration)
+          handleNoFieldInitializer(assert)
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+        endClassFields(null, null, null, null, 1, int, ;)
+      endMember()
+      beginMetadataStar(assert)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'assert'., null, {token: assert}], assert, assert)
+        handleInvalidMember(assert)
+      endMember()
+      beginMetadataStar(()
+      endMetadataStar(0)
+      beginMember()
+        beginMethod(null, null, null, null, null, ()
+          handleNoType(assert)
+          handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+          handleIdentifier(, methodDeclaration)
+          handleNoTypeVariables(()
+          beginFormalParameters((, MemberKind.NonStaticMethod)
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(x)
+              handleType(int, null)
+              handleIdentifier(x, formalParameterDeclaration)
+              handleFormalParameterWithoutValue())
+            endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+          endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          beginBlockFunctionBody({)
+            beginIfStatement(if)
+              handleIdentifier(x, expression)
+              handleNoTypeArguments(==)
+              handleNoArguments(==)
+              handleSend(x, ==)
+              beginBinaryExpression(==)
+              handleLiteralInt(0)
+              endBinaryExpression(==)
+              handleParenthesizedCondition(()
+              beginThenStatement(return)
+                beginReturnStatement(return)
+                  handleLiteralInt(42)
+                endReturnStatement(true, return, ;)
+              endThenStatement(;)
+            endIfStatement(if, null)
+            beginReturnStatement(return)
+              beginAssert(assert, Assert.Expression)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(-)
+                handleNoArguments(-)
+                handleSend(x, -)
+                beginBinaryExpression(-)
+                handleLiteralInt(1)
+                endBinaryExpression(-)
+                handleRecoverableError(AssertAsExpression, assert, assert)
+              endAssert(assert, Assert.Expression, (, null, +)
+              beginBinaryExpression(+)
+              handleLiteralInt(1)
+              endBinaryExpression(+)
+            endReturnStatement(true, return, ;)
+          endBlockFunctionBody(2, {, })
+        endClassMethod(null, , (, null, })
+      endMember()
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginMember()
+        handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        handleNoType(})
+        handleIdentifier(int, fieldDeclaration)
+        handleNoFieldInitializer(break)
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+      endClassFields(null, null, null, null, 1, int, ;)
+    endMember()
+    beginMetadataStar(break)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'break'., null, {token: break}], break, break)
+      handleInvalidMember(break)
+    endMember()
+    beginMetadataStar(()
+    endMetadataStar(0)
+    beginMember()
+      beginMethod(null, null, null, null, null, ()
+        handleNoType(break)
+        handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        handleIdentifier(, methodDeclaration)
+        handleNoTypeVariables(()
+        beginFormalParameters((, MemberKind.NonStaticMethod)
+          beginMetadataStar(int)
+          endMetadataStar(0)
+          beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(x)
+            handleType(int, null)
+            handleIdentifier(x, formalParameterDeclaration)
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+        endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+        handleNoInitializers()
+        handleAsyncModifier(null, null)
+        beginBlockFunctionBody({)
+          beginIfStatement(if)
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(==)
+            handleNoArguments(==)
+            handleSend(x, ==)
+            beginBinaryExpression(==)
+            handleLiteralInt(0)
+            endBinaryExpression(==)
+            handleParenthesizedCondition(()
+            beginThenStatement(return)
+              beginReturnStatement(return)
+                handleLiteralInt(42)
+              endReturnStatement(true, return, ;)
+            endThenStatement(;)
+          endIfStatement(if, null)
+          beginReturnStatement(return)
+            handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+            handleIdentifier(, expression)
+            handleNoTypeArguments(break)
+            handleNoArguments(break)
+            handleSend(, break)
+            handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+          endReturnStatement(true, return, ;)
+          handleRecoverableError(BreakOutsideOfLoop, break, break)
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+          handleBreakStatement(false, break, ;)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(-)
+          handleNoArguments(-)
+          handleSend(x, -)
+          beginBinaryExpression(-)
+          handleLiteralInt(1)
+          endBinaryExpression(-)
+          handleParenthesizedExpression(()
+          beginBinaryExpression(+)
+          handleLiteralInt(1)
+          endBinaryExpression(+)
+          handleExpressionStatement(;)
+        endBlockFunctionBody(4, {, })
+      endClassMethod(null, , (, null, })
+    endMember()
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginMember()
+      handleRecoverableError(MissingConstFinalVarOrType, int, int)
+      handleNoType(})
+      handleIdentifier(int, fieldDeclaration)
+      handleNoFieldInitializer(case)
+      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+    endClassFields(null, null, null, null, 1, int, ;)
+  endMember()
+  beginMetadataStar(case)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'case'., null, {token: case}], case, case)
+    handleInvalidMember(case)
+  endMember()
+  beginMetadataStar(()
+  endMetadataStar(0)
+  beginMember()
+    beginMethod(null, null, null, null, null, ()
+      handleNoType(case)
+      handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+      handleIdentifier(, methodDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.NonStaticMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+      endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+      handleNoInitializers()
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+          handleIdentifier(case, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(case, +)
+          beginBinaryExpression(+)
+          handleLiteralInt(1)
+          endBinaryExpression(+)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endClassMethod(null, , (, null, })
+  endMember()
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginMember()
+    handleRecoverableError(MissingConstFinalVarOrType, int, int)
+    handleNoType(})
+    handleIdentifier(int, fieldDeclaration)
+    handleNoFieldInitializer(catch)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+  endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(catch)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'catch'., null, {token: catch}], catch, catch)
+  handleInvalidMember(catch)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+  beginMethod(null, null, null, null, null, ()
+    handleNoType(catch)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+    handleIdentifier(, methodDeclaration)
+    handleNoTypeVariables(()
+    beginFormalParameters((, MemberKind.NonStaticMethod)
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(x)
+        handleType(int, null)
+        handleIdentifier(x, formalParameterDeclaration)
+        handleFormalParameterWithoutValue())
+      endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+    endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+    handleNoInitializers()
+    handleAsyncModifier(null, null)
+    beginBlockFunctionBody({)
+      beginIfStatement(if)
+        handleIdentifier(x, expression)
+        handleNoTypeArguments(==)
+        handleNoArguments(==)
+        handleSend(x, ==)
+        beginBinaryExpression(==)
+        handleLiteralInt(0)
+        endBinaryExpression(==)
+        handleParenthesizedCondition(()
+        beginThenStatement(return)
+          beginReturnStatement(return)
+            handleLiteralInt(42)
+          endReturnStatement(true, return, ;)
+        endThenStatement(;)
+      endIfStatement(if, null)
+      beginReturnStatement(return)
+        handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+        handleIdentifier(catch, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(-)
+          handleNoArguments(-)
+          handleSend(x, -)
+          beginBinaryExpression(-)
+          handleLiteralInt(1)
+          endBinaryExpression(-)
+        endArguments(1, (, ))
+        handleSend(catch, +)
+        beginBinaryExpression(+)
+        handleLiteralInt(1)
+        endBinaryExpression(+)
+      endReturnStatement(true, return, ;)
+    endBlockFunctionBody(2, {, })
+  endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(MissingConstFinalVarOrType, int, int)
+  handleNoType(})
+  handleIdentifier(int, fieldDeclaration)
+  handleNoFieldInitializer(class)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(class)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(ClassInClass, class, class)
+handleInvalidMember(class)
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+  beginMethod(null, null, null, null, null, ()
+    handleNoType(class)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+    handleIdentifier(, methodDeclaration)
+    handleNoTypeVariables(()
+    beginFormalParameters((, MemberKind.NonStaticMethod)
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(x)
+        handleType(int, null)
+        handleIdentifier(x, formalParameterDeclaration)
+        handleFormalParameterWithoutValue())
+      endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+    endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+    handleNoInitializers()
+    handleAsyncModifier(null, null)
+    beginBlockFunctionBody({)
+      beginIfStatement(if)
+        handleIdentifier(x, expression)
+        handleNoTypeArguments(==)
+        handleNoArguments(==)
+        handleSend(x, ==)
+        beginBinaryExpression(==)
+        handleLiteralInt(0)
+        endBinaryExpression(==)
+        handleParenthesizedCondition(()
+        beginThenStatement(return)
+          beginReturnStatement(return)
+            handleLiteralInt(42)
+          endReturnStatement(true, return, ;)
+        endThenStatement(;)
+      endIfStatement(if, null)
+      beginReturnStatement(return)
+        handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'class'., null, {token: class}], class, class)
+        handleIdentifier(class, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(-)
+          handleNoArguments(-)
+          handleSend(x, -)
+          beginBinaryExpression(-)
+          handleLiteralInt(1)
+          endBinaryExpression(-)
+        endArguments(1, (, ))
+        handleSend(class, +)
+        beginBinaryExpression(+)
+        handleLiteralInt(1)
+        endBinaryExpression(+)
+      endReturnStatement(true, return, ;)
+    endBlockFunctionBody(2, {, })
+  endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+  handleRecoverableError(MissingConstFinalVarOrType, int, int)
+  handleNoType(})
+  handleIdentifier(int, fieldDeclaration)
+  handleNoFieldInitializer(const)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(const)
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, const, null, ()
+  handleNoType(const)
+  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+  handleIdentifier(, methodDeclaration)
+  handleNoTypeVariables(()
+  beginFormalParameters((, MemberKind.NonStaticMethod)
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(x)
+      handleType(int, null)
+      handleIdentifier(x, formalParameterDeclaration)
+      handleFormalParameterWithoutValue())
+    endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+  endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+  handleNoInitializers()
+  handleAsyncModifier(null, null)
+  beginBlockFunctionBody({)
+    beginIfStatement(if)
+      handleIdentifier(x, expression)
+      handleNoTypeArguments(==)
+      handleNoArguments(==)
+      handleSend(x, ==)
+      beginBinaryExpression(==)
+      handleLiteralInt(0)
+      endBinaryExpression(==)
+      handleParenthesizedCondition(()
+      beginThenStatement(return)
+        beginReturnStatement(return)
+          handleLiteralInt(42)
+        endReturnStatement(true, return, ;)
+      endThenStatement(;)
+    endIfStatement(if, null)
+    beginReturnStatement(return)
+      beginConstExpression(const)
+        handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        handleIdentifier(, constructorReference)
+        beginConstructorReference()
+          handleNoTypeArguments(()
+          handleNoConstructorReferenceContinuationAfterTypeArguments(()
+        endConstructorReference(, null, ()
+        beginArguments(()
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(-)
+          handleNoArguments(-)
+          handleSend(x, -)
+          beginBinaryExpression(-)
+          handleLiteralInt(1)
+          endBinaryExpression(-)
+        endArguments(1, (, ))
+      endConstExpression(const)
+      beginBinaryExpression(+)
+      handleLiteralInt(1)
+      endBinaryExpression(+)
+    endReturnStatement(true, return, ;)
+  endBlockFunctionBody(2, {, })
+  handleRecoverableError(ConstMethod, const, const)
+endClassMethod(null, const, (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(continue)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'continue'., null, {token: continue}], continue, continue)
+handleInvalidMember(continue)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(continue)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+    handleIdentifier(int, typeReference)
+    handleNoTypeArguments(x)
+    handleType(int, null)
+    handleIdentifier(x, formalParameterDeclaration)
+    handleFormalParameterWithoutValue())
+  endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+  beginIfStatement(if)
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(==)
+    handleNoArguments(==)
+    handleSend(x, ==)
+    beginBinaryExpression(==)
+    handleLiteralInt(0)
+    endBinaryExpression(==)
+    handleParenthesizedCondition(()
+    beginThenStatement(return)
+      beginReturnStatement(return)
+        handleLiteralInt(42)
+      endReturnStatement(true, return, ;)
+    endThenStatement(;)
+  endIfStatement(if, null)
+  beginReturnStatement(return)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+    handleIdentifier(, expression)
+    handleNoTypeArguments(continue)
+    handleNoArguments(continue)
+    handleSend(, continue)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+  endReturnStatement(true, return, ;)
+  handleRecoverableError(ContinueOutsideOfLoop, continue, continue)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+  handleContinueStatement(false, continue, ;)
+  handleIdentifier(x, expression)
+  handleNoTypeArguments(-)
+  handleNoArguments(-)
+  handleSend(x, -)
+  beginBinaryExpression(-)
+  handleLiteralInt(1)
+  endBinaryExpression(-)
+  handleParenthesizedExpression(()
+  beginBinaryExpression(+)
+  handleLiteralInt(1)
+  endBinaryExpression(+)
+  handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(default)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(default)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'default'., null, {token: default}], default, default)
+handleInvalidMember(default)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(default)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+  handleIdentifier(int, typeReference)
+  handleNoTypeArguments(x)
+  handleType(int, null)
+  handleIdentifier(x, formalParameterDeclaration)
+  handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+  handleIdentifier(x, expression)
+  handleNoTypeArguments(==)
+  handleNoArguments(==)
+  handleSend(x, ==)
+  beginBinaryExpression(==)
+  handleLiteralInt(0)
+  endBinaryExpression(==)
+  handleParenthesizedCondition(()
+  beginThenStatement(return)
+    beginReturnStatement(return)
+      handleLiteralInt(42)
+    endReturnStatement(true, return, ;)
+  endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+  handleIdentifier(default, expression)
+  handleNoTypeArguments(()
+  beginArguments(()
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(-)
+    handleNoArguments(-)
+    handleSend(x, -)
+    beginBinaryExpression(-)
+    handleLiteralInt(1)
+    endBinaryExpression(-)
+  endArguments(1, (, ))
+  handleSend(default, +)
+  beginBinaryExpression(+)
+  handleLiteralInt(1)
+  endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(do)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'do'., null, {token: do}], do, do)
+handleInvalidMember(do)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(do)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+  beginReturnStatement(return)
+    handleLiteralInt(42)
+  endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+handleIdentifier(, expression)
+handleNoTypeArguments(do)
+handleNoArguments(do)
+handleSend(, do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], do, do)
+endReturnStatement(true, return, ;)
+beginDoWhileStatement(do)
+beginDoWhileStatementBody(()
+  handleIdentifier(x, expression)
+  handleNoTypeArguments(-)
+  handleNoArguments(-)
+  handleSend(x, -)
+  beginBinaryExpression(-)
+  handleLiteralInt(1)
+  endBinaryExpression(-)
+  handleParenthesizedExpression(()
+  beginBinaryExpression(+)
+  handleLiteralInt(1)
+  endBinaryExpression(+)
+  handleExpressionStatement(;)
+endDoWhileStatementBody(;)
+handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
+handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '}'., null, {token: }}], }, })
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleParenthesizedCondition(()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+endDoWhileStatement(do, while, ;)
+endBlockFunctionBody(3, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(else)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'else'., null, {token: else}], else, else)
+handleInvalidMember(else)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(else)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+  handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(, expression)
+handleNoTypeArguments(else)
+handleNoArguments(else)
+handleSend(, else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+endReturnStatement(true, return, ;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(, expression)
+handleNoTypeArguments(else)
+handleNoArguments(else)
+handleSend(, else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], else, else)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(enum)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(enum)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(EnumInClass, enum, enum)
+handleInvalidMember(enum)
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(enum)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+  handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'enum'., null, {token: enum}], enum, enum)
+handleIdentifier(enum, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(enum, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(extends)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(extends)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'extends'., null, {token: extends}], extends, extends)
+handleInvalidMember(extends)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(extends)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+handleIdentifier(extends, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(extends, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(false)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'false'., null, {token: false}], false, false)
+handleInvalidMember(false)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(false)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralBool(false)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(final)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+beginMethod(null, null, null, null, null, ()
+handleNoType(final)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'final'., null, {token: final}], final, final)
+handleIdentifier(, expression)
+handleNoTypeArguments(final)
+handleNoArguments(final)
+handleSend(, final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], final, final)
+endReturnStatement(true, return, ;)
+beginMetadataStar(final)
+endMetadataStar(0)
+handleNoType(final)
+beginVariablesDeclaration((, null, final)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endClassMethod(null, final, (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(finally)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(finally)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'finally'., null, {token: finally}], finally, finally)
+handleInvalidMember(finally)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(finally)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+handleIdentifier(finally, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(finally, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(for)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'for'., null, {token: for}], for, for)
+handleInvalidMember(for)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(for)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+handleIdentifier(, expression)
+handleNoTypeArguments(for)
+handleNoArguments(for)
+handleSend(, for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], for, for)
+endReturnStatement(true, return, ;)
+beginForStatement(for)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleForInitializerExpressionStatement(1, false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleForLoopParts(for, (, ;, 0)
+beginForStatementBody(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endForStatementBody(})
+endForStatement(})
+endBlockFunctionBody(3, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(if)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'if'., null, {token: if}], if, if)
+handleInvalidMember(if)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(if)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+handleIdentifier(, expression)
+handleNoTypeArguments(if)
+handleNoArguments(if)
+handleSend(, if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], if, if)
+endReturnStatement(true, return, ;)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+beginThenStatement(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endThenStatement(;)
+endIfStatement(if, null)
+endBlockFunctionBody(3, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(in)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(in)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'in'., null, {token: in}], in, in)
+handleInvalidMember(in)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(in)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+handleIdentifier(in, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(in, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(is)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(is)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'is'., null, {token: is}], is, is)
+handleInvalidMember(is)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(is)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+handleIdentifier(, expression)
+handleNoTypeArguments(is)
+handleNoArguments(is)
+handleSend(, is)
+beginIsOperatorType(is)
+handleRecoverableError(Message[ExpectedType, Expected a type, but got '('., null, {token: (}], (, ()
+handleIdentifier(, typeReference)
+handleNoTypeArguments(()
+handleType(, null)
+endIsOperatorType(is)
+handleIsOperator(is, null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
+endReturnStatement(true, return, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(3, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(new)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(new)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'new'., null, {token: new}], new, new)
+handleInvalidMember(new)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(new)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+beginNewExpression(new)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, constructorReference)
+beginConstructorReference()
+handleNoTypeArguments(()
+handleNoConstructorReferenceContinuationAfterTypeArguments(()
+endConstructorReference(, null, ()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+endNewExpression(new)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(null)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'null'., null, {token: null}], null, null)
+handleInvalidMember(null)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralNull(null)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(rethrow)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(rethrow)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleInvalidMember(rethrow)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(rethrow)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleIdentifier(rethrow, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(rethrow, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(return)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(return)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'return'., null, {token: return}], return, return)
+handleInvalidMember(return)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {token: return}], return, return)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(super)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(super)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'super'., null, {token: super}], super, super)
+handleInvalidMember(super)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(super)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleSuperExpression(super, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(super, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(switch)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'switch'., null, {token: switch}], switch, switch)
+handleInvalidMember(switch)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(switch)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+handleIdentifier(, expression)
+handleNoTypeArguments(switch)
+handleNoArguments(switch)
+handleSend(, switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], switch, switch)
+endReturnStatement(true, return, ;)
+beginSwitchStatement(switch)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
+beginSwitchBlock({)
+endSwitchBlock(0, {, })
+endSwitchStatement(switch, })
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(this)
+handleType(int, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+handleIdentifier(this, fieldDeclaration)
+handleNoFieldInitializer(()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], this, this)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleThisExpression(this, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(this, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(throw)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(throw)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'throw'., null, {token: throw}], throw, throw)
+handleInvalidMember(throw)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(throw)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleThrowExpression(throw, ;)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(true)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(true)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'true'., null, {token: true}], true, true)
+handleInvalidMember(true)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(true)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralBool(true)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(try)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'try'., null, {token: try}], try, try)
+handleInvalidMember(try)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(try)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+handleIdentifier(, expression)
+handleNoTypeArguments(try)
+handleNoArguments(try)
+handleSend(, try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], try, try)
+endReturnStatement(true, return, ;)
+beginTryStatement(try)
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}], try, try)
+beginBlock({, BlockKind(try statement))
+endBlock(0, {, }, BlockKind(try statement))
+handleRecoverableError(OnlyTry, try, try)
+endTryStatement(0, try, null)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(var)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(VarReturnType, var, var)
+beginMethod(null, null, null, null, null, ()
+handleNoType(var)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'var'., null, {token: var}], var, var)
+handleIdentifier(, expression)
+handleNoTypeArguments(var)
+handleNoArguments(var)
+handleSend(, var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], var, var)
+endReturnStatement(true, return, ;)
+beginMetadataStar(var)
+endMetadataStar(0)
+handleNoType(var)
+beginVariablesDeclaration((, null, var)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endClassMethod(null, var, (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(void)
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleVoidKeyword(void)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'void'., null, {token: void}], void, void)
+handleIdentifier(, expression)
+handleNoTypeArguments(void)
+handleNoArguments(void)
+handleSend(, void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
+endReturnStatement(true, return, ;)
+beginMetadataStar(void)
+endMetadataStar(0)
+handleVoidKeyword(void)
+beginVariablesDeclaration((, null, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endClassMethod(null, void, (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(while)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'while'., null, {token: while}], while, while)
+handleInvalidMember(while)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(while)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+handleIdentifier(, expression)
+handleNoTypeArguments(while)
+handleNoArguments(while)
+handleSend(, while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], while, while)
+endReturnStatement(true, return, ;)
+beginWhileStatement(while)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+beginWhileStatementBody(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endWhileStatementBody(})
+endWhileStatement(while, })
+endBlockFunctionBody(3, {, })
+endClassMethod(null, , (, null, })
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, fieldDeclaration)
+handleNoFieldInitializer(with)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(with)
+endMetadataStar(0)
+beginMember()
+handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+handleInvalidMember(with)
+endMember()
+beginMetadataStar(()
+endMetadataStar(0)
+beginMember()
+beginMethod(null, null, null, null, null, ()
+handleNoType(with)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, methodDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.NonStaticMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+handleNoInitializers()
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(with, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endClassMethod(null, , (, null, })
+endMember()
+endClassOrMixinBody(DeclarationKind.Class, 94, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.intertwined.expect
new file mode 100644
index 0000000..2b33d7b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.intertwined.expect
@@ -0,0 +1,6400 @@
+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(WrapperClass, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, WrapperClass)
+        parseClass(WrapperClass, class, class, WrapperClass)
+          parseClassHeaderOpt(WrapperClass, class, class)
+            parseClassExtendsOpt(WrapperClass)
+              listener: handleNoType(WrapperClass)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(WrapperClass)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(WrapperClass)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(WrapperClass, DeclarationKind.Class, WrapperClass)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, {, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType({)
+                ensureIdentifier({, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(assert)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, assert)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(assert)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(assert, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'assert'., null, {token: assert}], assert, assert)
+                listener: handleInvalidMember(assert)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(assert, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(assert)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(assert, assert, null, null, null, null, null, assert, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(assert, null, null, null, null, null, assert, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(assert)
+                  ensureIdentifier(assert, methodDeclaration)
+                    insertSyntheticIdentifier(assert, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseAssert(return, Assert.Expression)
+                                    listener: beginAssert(assert, Assert.Expression)
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    reportRecoverableError(assert, AssertAsExpression)
+                                      listener: handleRecoverableError(AssertAsExpression, assert, assert)
+                                    listener: endAssert(assert, Assert.Expression, (, null, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(break)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, break)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(break)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'break'., null, {token: break}], break, break)
+                listener: handleInvalidMember(break)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(break, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(break)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(break, break, null, null, null, null, null, break, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(break, null, null, null, null, null, break, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(break)
+                  ensureIdentifier(break, methodDeclaration)
+                    insertSyntheticIdentifier(break, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(break)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(break)
+                                    listener: handleSend(, break)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, break)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseBreakStatement(;)
+                          isBreakAllowed()
+                          reportRecoverableError(break, BreakOutsideOfLoop)
+                            listener: handleRecoverableError(BreakOutsideOfLoop, break, break)
+                          ensureSemicolon(break)
+                            reportRecoverableError(break, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+                            rewriter()
+                          listener: handleBreakStatement(false, break, ;)
+                    notEofOrValue(}, ()
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction(()
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      parseParenthesizedExpressionOrFunctionLiteral(;)
+                                        parseParenthesizedExpression(;)
+                                          parseExpressionInParenthesis(;)
+                                            parseExpressionInParenthesisRest(()
+                                              parseExpression(()
+                                                parsePrecedenceExpression((, 1, true)
+                                                  parseUnaryExpression((, true)
+                                                    parsePrimary((, expression)
+                                                      parseSendOrFunctionLiteral((, expression)
+                                                        parseSend((, expression)
+                                                          ensureIdentifier((, expression)
+                                                            listener: handleIdentifier(x, expression)
+                                                          listener: handleNoTypeArguments(-)
+                                                          parseArgumentsOpt(x)
+                                                            listener: handleNoArguments(-)
+                                                          listener: handleSend(x, -)
+                                                  listener: beginBinaryExpression(-)
+                                                  parsePrecedenceExpression(-, 14, true)
+                                                    parseUnaryExpression(-, true)
+                                                      parsePrimary(-, expression)
+                                                        parseLiteralInt(-)
+                                                          listener: handleLiteralInt(1)
+                                                  listener: endBinaryExpression(-)
+                                              ensureCloseParen(1, ()
+                                          listener: handleParenthesizedExpression(()
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(4, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(case)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, case)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(case)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'case'., null, {token: case}], case, case)
+                listener: handleInvalidMember(case)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(case, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(case)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(case, case, null, null, null, null, null, case, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(case, null, null, null, null, null, case, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(case)
+                  ensureIdentifier(case, methodDeclaration)
+                    insertSyntheticIdentifier(case, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+                                      listener: handleIdentifier(case, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(case)
+                                      parseArguments(case)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(case, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(catch)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, catch)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(catch)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'catch'., null, {token: catch}], catch, catch)
+                listener: handleInvalidMember(catch)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(catch, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(catch)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(catch, catch, null, null, null, null, null, catch, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(catch, null, null, null, null, null, catch, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(catch)
+                  ensureIdentifier(catch, methodDeclaration)
+                    insertSyntheticIdentifier(catch, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+                                      listener: handleIdentifier(catch, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(catch)
+                                      parseArguments(catch)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(catch, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(class)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, class)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(class)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportAndSkipClassInClass(class)
+                  reportRecoverableError(class, ClassInClass)
+                    listener: handleRecoverableError(ClassInClass, class, class)
+                  listener: handleInvalidMember(class)
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(class, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(class)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(class, class, null, null, null, null, null, class, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(class, null, null, null, null, null, class, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(class)
+                  ensureIdentifier(class, methodDeclaration)
+                    insertSyntheticIdentifier(class, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(class, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'class'., null, {token: class}], class, class)
+                                      listener: handleIdentifier(class, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(class)
+                                      parseArguments(class)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(class, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(const)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, const)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(const)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(const, ;, null, null, null, null, const, const, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(;, null, null, null, null, const, const, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, const, null, ()
+                  listener: handleNoType(const)
+                  ensureIdentifier(const, methodDeclaration)
+                    insertSyntheticIdentifier(const, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseConstExpression(return)
+                                    listener: beginConstExpression(const)
+                                    parseConstructorReference(const, null)
+                                      ensureIdentifier(const, constructorReference)
+                                        insertSyntheticIdentifier(const, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], messageOnToken: null)
+                                          reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                          rewriter()
+                                        listener: handleIdentifier(, constructorReference)
+                                      listener: beginConstructorReference()
+                                      parseQualifiedRestOpt(, constructorReferenceContinuation)
+                                      listener: handleNoTypeArguments(()
+                                      listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                                      listener: endConstructorReference(, null, ()
+                                    parseConstructorInvocationArguments()
+                                      parseArgumentsRest(()
+                                        listener: beginArguments(()
+                                        parseExpression(()
+                                          parsePrecedenceExpression((, 1, true)
+                                            parseUnaryExpression((, true)
+                                              parsePrimary((, expression)
+                                                parseSendOrFunctionLiteral((, expression)
+                                                  parseSend((, expression)
+                                                    ensureIdentifier((, expression)
+                                                      listener: handleIdentifier(x, expression)
+                                                    listener: handleNoTypeArguments(-)
+                                                    parseArgumentsOpt(x)
+                                                      listener: handleNoArguments(-)
+                                                    listener: handleSend(x, -)
+                                            listener: beginBinaryExpression(-)
+                                            parsePrecedenceExpression(-, 14, true)
+                                              parseUnaryExpression(-, true)
+                                                parsePrimary(-, expression)
+                                                  parseLiteralInt(-)
+                                                    listener: handleLiteralInt(1)
+                                            listener: endBinaryExpression(-)
+                                        listener: endArguments(1, (, ))
+                                    listener: endConstExpression(const)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  reportRecoverableError(const, ConstMethod)
+                    listener: handleRecoverableError(ConstMethod, const, const)
+                  listener: endClassMethod(null, const, (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(continue)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, continue)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(continue)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'continue'., null, {token: continue}], continue, continue)
+                listener: handleInvalidMember(continue)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(continue, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(continue)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(continue, continue, null, null, null, null, null, continue, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(continue, null, null, null, null, null, continue, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(continue)
+                  ensureIdentifier(continue, methodDeclaration)
+                    insertSyntheticIdentifier(continue, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(continue)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(continue)
+                                    listener: handleSend(, continue)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, continue)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseContinueStatement(;)
+                          isContinueAllowed()
+                          reportRecoverableError(continue, ContinueOutsideOfLoop)
+                            listener: handleRecoverableError(ContinueOutsideOfLoop, continue, continue)
+                          ensureSemicolon(continue)
+                            reportRecoverableError(continue, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+                            rewriter()
+                          listener: handleContinueStatement(false, continue, ;)
+                    notEofOrValue(}, ()
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction(()
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      parseParenthesizedExpressionOrFunctionLiteral(;)
+                                        parseParenthesizedExpression(;)
+                                          parseExpressionInParenthesis(;)
+                                            parseExpressionInParenthesisRest(()
+                                              parseExpression(()
+                                                parsePrecedenceExpression((, 1, true)
+                                                  parseUnaryExpression((, true)
+                                                    parsePrimary((, expression)
+                                                      parseSendOrFunctionLiteral((, expression)
+                                                        parseSend((, expression)
+                                                          ensureIdentifier((, expression)
+                                                            listener: handleIdentifier(x, expression)
+                                                          listener: handleNoTypeArguments(-)
+                                                          parseArgumentsOpt(x)
+                                                            listener: handleNoArguments(-)
+                                                          listener: handleSend(x, -)
+                                                  listener: beginBinaryExpression(-)
+                                                  parsePrecedenceExpression(-, 14, true)
+                                                    parseUnaryExpression(-, true)
+                                                      parsePrimary(-, expression)
+                                                        parseLiteralInt(-)
+                                                          listener: handleLiteralInt(1)
+                                                  listener: endBinaryExpression(-)
+                                              ensureCloseParen(1, ()
+                                          listener: handleParenthesizedExpression(()
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(4, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(default)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, default)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(default)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'default'., null, {token: default}], default, default)
+                listener: handleInvalidMember(default)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(default, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(default)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(default, default, null, null, null, null, null, default, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(default, null, null, null, null, null, default, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(default)
+                  ensureIdentifier(default, methodDeclaration)
+                    insertSyntheticIdentifier(default, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+                                      listener: handleIdentifier(default, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(default)
+                                      parseArguments(default)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(default, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(do)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, do)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(do)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'do'., null, {token: do}], do, do)
+                listener: handleInvalidMember(do)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(do, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(do)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(do, do, null, null, null, null, null, do, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(do, null, null, null, null, null, do, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(do)
+                  ensureIdentifier(do, methodDeclaration)
+                    insertSyntheticIdentifier(do, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(do)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(do)
+                                    listener: handleSend(, do)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], do, do)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, do)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseDoWhileStatement(;)
+                          listener: beginDoWhileStatement(do)
+                          listener: beginDoWhileStatementBody(()
+                          parseStatement(do)
+                            parseStatementX(do)
+                              parseExpressionStatementOrDeclaration(do, false)
+                                parseExpressionStatementOrDeclarationAfterModifiers(do, do, null, null, null, false)
+                                  looksLikeLocalFunction(()
+                                  parseExpressionStatement(do)
+                                    parseExpression(do)
+                                      parsePrecedenceExpression(do, 1, true)
+                                        parseUnaryExpression(do, true)
+                                          parsePrimary(do, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(do)
+                                              parseParenthesizedExpression(do)
+                                                parseExpressionInParenthesis(do)
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseSendOrFunctionLiteral((, expression)
+                                                              parseSend((, expression)
+                                                                ensureIdentifier((, expression)
+                                                                  listener: handleIdentifier(x, expression)
+                                                                listener: handleNoTypeArguments(-)
+                                                                parseArgumentsOpt(x)
+                                                                  listener: handleNoArguments(-)
+                                                                listener: handleSend(x, -)
+                                                        listener: beginBinaryExpression(-)
+                                                        parsePrecedenceExpression(-, 14, true)
+                                                          parseUnaryExpression(-, true)
+                                                            parsePrimary(-, expression)
+                                                              parseLiteralInt(-)
+                                                                listener: handleLiteralInt(1)
+                                                        listener: endBinaryExpression(-)
+                                                    ensureCloseParen(1, ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: beginBinaryExpression(+)
+                                        parsePrecedenceExpression(+, 14, true)
+                                          parseUnaryExpression(+, true)
+                                            parsePrimary(+, expression)
+                                              parseLiteralInt(+)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(+)
+                                    ensureSemicolon(1)
+                                    listener: handleExpressionStatement(;)
+                          listener: endDoWhileStatementBody(;)
+                          reportRecoverableError(}, Message[ExpectedButGot, Expected 'while' before this., null, {string: while}])
+                            listener: handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
+                          rewriter()
+                          ensureParenthesizedCondition(while)
+                            reportRecoverableError(}, Message[ExpectedToken, Expected to find '('., null, {string: (}])
+                              listener: handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
+                            rewriter()
+                            parseExpressionInParenthesisRest(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSend((, expression)
+                                        ensureIdentifier((, expression)
+                                          reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '}'., null, {token: }}], }, })
+                                          rewriter()
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments())
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments())
+                                        listener: handleSend(, ))
+                              ensureCloseParen(, ()
+                            listener: handleParenthesizedCondition(()
+                          ensureSemicolon())
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                            rewriter()
+                          listener: endDoWhileStatement(do, while, ;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(3, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(else)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, else)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(else)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'else'., null, {token: else}], else, else)
+                listener: handleInvalidMember(else)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(else, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(else)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(else, else, null, null, null, null, null, else, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(else, null, null, null, null, null, else, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(else)
+                  ensureIdentifier(else, methodDeclaration)
+                    insertSyntheticIdentifier(else, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(else)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(else)
+                                    listener: handleSend(, else)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, else)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction(else)
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      inPlainSync()
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+                                          rewriter()
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments(else)
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments(else)
+                                        listener: handleSend(, else)
+                              ensureSemicolon()
+                                reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                  listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+                                rewriter()
+                              listener: handleExpressionStatement(;)
+                    reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+                      listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], else, else)
+                    notEofOrValue(}, ()
+                    parseStatement(else)
+                      parseStatementX(else)
+                        parseExpressionStatementOrDeclaration(else, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(else, else, null, null, null, false)
+                            looksLikeLocalFunction(()
+                            parseExpressionStatement(else)
+                              parseExpression(else)
+                                parsePrecedenceExpression(else, 1, true)
+                                  parseUnaryExpression(else, true)
+                                    parsePrimary(else, expression)
+                                      parseParenthesizedExpressionOrFunctionLiteral(else)
+                                        parseParenthesizedExpression(else)
+                                          parseExpressionInParenthesis(else)
+                                            parseExpressionInParenthesisRest(()
+                                              parseExpression(()
+                                                parsePrecedenceExpression((, 1, true)
+                                                  parseUnaryExpression((, true)
+                                                    parsePrimary((, expression)
+                                                      parseSendOrFunctionLiteral((, expression)
+                                                        parseSend((, expression)
+                                                          ensureIdentifier((, expression)
+                                                            listener: handleIdentifier(x, expression)
+                                                          listener: handleNoTypeArguments(-)
+                                                          parseArgumentsOpt(x)
+                                                            listener: handleNoArguments(-)
+                                                          listener: handleSend(x, -)
+                                                  listener: beginBinaryExpression(-)
+                                                  parsePrecedenceExpression(-, 14, true)
+                                                    parseUnaryExpression(-, true)
+                                                      parsePrimary(-, expression)
+                                                        parseLiteralInt(-)
+                                                          listener: handleLiteralInt(1)
+                                                  listener: endBinaryExpression(-)
+                                              ensureCloseParen(1, ()
+                                          listener: handleParenthesizedExpression(()
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(4, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(enum)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, enum)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(enum)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportAndSkipEnumInClass(enum)
+                  reportRecoverableError(enum, EnumInClass)
+                    listener: handleRecoverableError(EnumInClass, enum, enum)
+                  listener: handleInvalidMember(enum)
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(enum, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(enum)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(enum, enum, null, null, null, null, null, enum, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(enum, null, null, null, null, null, enum, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(enum)
+                  ensureIdentifier(enum, methodDeclaration)
+                    insertSyntheticIdentifier(enum, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'enum'., null, {token: enum}], enum, enum)
+                                      listener: handleIdentifier(enum, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(enum)
+                                      parseArguments(enum)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(enum, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(extends)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, extends)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(extends)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'extends'., null, {token: extends}], extends, extends)
+                listener: handleInvalidMember(extends)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(extends, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(extends)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(extends, extends, null, null, null, null, null, extends, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(extends, null, null, null, null, null, extends, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(extends)
+                  ensureIdentifier(extends, methodDeclaration)
+                    insertSyntheticIdentifier(extends, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+                                      listener: handleIdentifier(extends, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(extends)
+                                      parseArguments(extends)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(extends, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(false)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, false)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(false)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(false, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'false'., null, {token: false}], false, false)
+                listener: handleInvalidMember(false)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(false, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(false)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(false, false, null, null, null, null, null, false, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(false, null, null, null, null, null, false, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(false)
+                  ensureIdentifier(false, methodDeclaration)
+                    insertSyntheticIdentifier(false, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseLiteralBool(return)
+                                    listener: handleLiteralBool(false)
+                              parseArgumentOrIndexStar(false, Instance of 'NoTypeParamOrArg', false)
+                                listener: handleNoTypeArguments(()
+                                parseArguments(false)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    listener: endArguments(1, (, ))
+                                listener: handleSend((, ))
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(final)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(final, ;, null, null, null, null, final, final, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(;, null, null, null, null, final, final, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+                    listener: handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(final)
+                  ensureIdentifier(final, methodDeclaration)
+                    insertSyntheticIdentifier(final, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'final'., null, {token: final}], final, final)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(final)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(final)
+                                    listener: handleSend(, final)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], final, final)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, final)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclarationAfterModifiers(final, ;, null, final, null, false)
+                          looksLikeLocalFunction(()
+                          listener: beginMetadataStar(final)
+                          listener: endMetadataStar(0)
+                          listener: handleNoType(final)
+                          listener: beginVariablesDeclaration((, null, final)
+                          parseVariablesDeclarationRest(final, true)
+                            parseOptionallyInitializedIdentifier(final)
+                              ensureIdentifier(final, localVariableDeclaration)
+                                reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                                listener: handleIdentifier(, localVariableDeclaration)
+                              listener: beginInitializedIdentifier()
+                              parseVariableInitializerOpt()
+                                listener: handleNoVariableInitializer(x)
+                              listener: endInitializedIdentifier()
+                            ensureSemicolon()
+                              reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                              rewriter()
+                            listener: endVariablesDeclaration(1, ;)
+                    notEofOrValue(}, x)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                          looksLikeLocalFunction(x)
+                          parseExpressionStatement(;)
+                            parseExpression(;)
+                              parsePrecedenceExpression(;, 1, true)
+                                parseUnaryExpression(;, true)
+                                  parsePrimary(;, expression)
+                                    parseSendOrFunctionLiteral(;, expression)
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          listener: handleIdentifier(x, expression)
+                                        listener: handleNoTypeArguments(-)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(-)
+                                        listener: handleSend(x, -)
+                                listener: beginBinaryExpression(-)
+                                parsePrecedenceExpression(-, 14, true)
+                                  parseUnaryExpression(-, true)
+                                    parsePrimary(-, expression)
+                                      parseLiteralInt(-)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(-)
+                            ensureSemicolon(1)
+                              reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                              rewriter()
+                            listener: handleExpressionStatement(;)
+                    notEofOrValue(}, ))
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction())
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                          rewriter()
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments())
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments())
+                                        listener: handleSend(, ))
+                              ensureSemicolon()
+                                reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                  listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                                rewriter()
+                              listener: handleExpressionStatement(;)
+                    reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+                      listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+                    notEofOrValue(}, +)
+                    parseStatement())
+                      parseStatementX())
+                        parseExpressionStatementOrDeclaration(), false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                            looksLikeLocalFunction(+)
+                            parseExpressionStatement())
+                              parseExpression())
+                                parsePrecedenceExpression(), 1, true)
+                                  parseUnaryExpression(), true)
+                                    rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                      reportRecoverableError(+, UnsupportedPrefixPlus)
+                                        listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                      rewriter()
+                                    parsePrimary(), expression)
+                                      parseSendOrFunctionLiteral(), expression)
+                                        parseSend(), expression)
+                                          ensureIdentifier(), expression)
+                                            listener: handleIdentifier(, expression)
+                                          listener: handleNoTypeArguments(+)
+                                          parseArgumentsOpt()
+                                            listener: handleNoArguments(+)
+                                          listener: handleSend(, +)
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(6, {, })
+                  listener: endClassMethod(null, final, (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(finally)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, finally)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(finally)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'finally'., null, {token: finally}], finally, finally)
+                listener: handleInvalidMember(finally)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(finally, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(finally)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(finally, finally, null, null, null, null, null, finally, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(finally, null, null, null, null, null, finally, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(finally)
+                  ensureIdentifier(finally, methodDeclaration)
+                    insertSyntheticIdentifier(finally, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+                                      listener: handleIdentifier(finally, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(finally)
+                                      parseArguments(finally)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(finally, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(for)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, for)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(for)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'for'., null, {token: for}], for, for)
+                listener: handleInvalidMember(for)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(for, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(for)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(for, for, null, null, null, null, null, for, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(for, null, null, null, null, null, for, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(for)
+                  ensureIdentifier(for, methodDeclaration)
+                    insertSyntheticIdentifier(for, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(for)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(for)
+                                    listener: handleSend(, for)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], for, for)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, for)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseForStatement(;, null)
+                          listener: beginForStatement(for)
+                          parseForLoopPartsStart(null, for)
+                            parseExpressionStatementOrDeclaration((, true)
+                              parseExpressionStatementOrDeclarationAfterModifiers((, (, null, null, null, true)
+                          parseForLoopPartsMid((, null, for)
+                            parseExpression(()
+                              parsePrecedenceExpression((, 1, true)
+                                parseUnaryExpression((, true)
+                                  parsePrimary((, expression)
+                                    parseSendOrFunctionLiteral((, expression)
+                                      parseSend((, expression)
+                                        ensureIdentifier((, expression)
+                                          listener: handleIdentifier(x, expression)
+                                        listener: handleNoTypeArguments(-)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(-)
+                                        listener: handleSend(x, -)
+                                listener: beginBinaryExpression(-)
+                                parsePrecedenceExpression(-, 14, true)
+                                  parseUnaryExpression(-, true)
+                                    parsePrimary(-, expression)
+                                      parseLiteralInt(-)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(-)
+                            listener: handleForInitializerExpressionStatement(1, false)
+                          parseForRest(null, 1, for)
+                            parseForLoopPartsRest(1, for, null)
+                              ensureSemicolon(1)
+                                reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                  listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                                rewriter()
+                              parseExpressionStatement(;)
+                                parseExpression(;)
+                                  parsePrecedenceExpression(;, 1, true)
+                                    parseUnaryExpression(;, true)
+                                      parsePrimary(;, expression)
+                                        parseSend(;, expression)
+                                          ensureIdentifier(;, expression)
+                                            reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                            rewriter()
+                                            listener: handleIdentifier(, expression)
+                                          listener: handleNoTypeArguments())
+                                          parseArgumentsOpt()
+                                            listener: handleNoArguments())
+                                          listener: handleSend(, ))
+                                ensureSemicolon()
+                                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                                  rewriter()
+                                listener: handleExpressionStatement(;)
+                              listener: handleForLoopParts(for, (, ;, 0)
+                            listener: beginForStatementBody(+)
+                            parseStatement())
+                              parseStatementX())
+                                parseExpressionStatementOrDeclaration(), false)
+                                  parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                                    looksLikeLocalFunction(+)
+                                    parseExpressionStatement())
+                                      parseExpression())
+                                        parsePrecedenceExpression(), 1, true)
+                                          parseUnaryExpression(), true)
+                                            rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                              reportRecoverableError(+, UnsupportedPrefixPlus)
+                                                listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                              rewriter()
+                                            parsePrimary(), expression)
+                                              parseSendOrFunctionLiteral(), expression)
+                                                parseSend(), expression)
+                                                  ensureIdentifier(), expression)
+                                                    listener: handleIdentifier(, expression)
+                                                  listener: handleNoTypeArguments(+)
+                                                  parseArgumentsOpt()
+                                                    listener: handleNoArguments(+)
+                                                  listener: handleSend(, +)
+                                          listener: beginBinaryExpression(+)
+                                          parsePrecedenceExpression(+, 14, true)
+                                            parseUnaryExpression(+, true)
+                                              parsePrimary(+, expression)
+                                                parseLiteralInt(+)
+                                                  listener: handleLiteralInt(1)
+                                          listener: endBinaryExpression(+)
+                                      ensureSemicolon(1)
+                                      listener: handleExpressionStatement(;)
+                            listener: endForStatementBody(})
+                            listener: endForStatement(})
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(3, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(if)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, if)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(if)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'if'., null, {token: if}], if, if)
+                listener: handleInvalidMember(if)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(if, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(if)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(if, if, null, null, null, null, null, if, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(if, null, null, null, null, null, if, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(if)
+                  ensureIdentifier(if, methodDeclaration)
+                    insertSyntheticIdentifier(if, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(if)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(if)
+                                    listener: handleSend(, if)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], if, if)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    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(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              ensureCloseParen(1, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(+)
+                          parseStatement())
+                            parseStatementX())
+                              parseExpressionStatementOrDeclaration(), false)
+                                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                                  looksLikeLocalFunction(+)
+                                  parseExpressionStatement())
+                                    parseExpression())
+                                      parsePrecedenceExpression(), 1, true)
+                                        parseUnaryExpression(), true)
+                                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                            rewriter()
+                                          parsePrimary(), expression)
+                                            parseSendOrFunctionLiteral(), expression)
+                                              parseSend(), expression)
+                                                ensureIdentifier(), expression)
+                                                  listener: handleIdentifier(, expression)
+                                                listener: handleNoTypeArguments(+)
+                                                parseArgumentsOpt()
+                                                  listener: handleNoArguments(+)
+                                                listener: handleSend(, +)
+                                        listener: beginBinaryExpression(+)
+                                        parsePrecedenceExpression(+, 14, true)
+                                          parseUnaryExpression(+, true)
+                                            parsePrimary(+, expression)
+                                              parseLiteralInt(+)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(+)
+                                    ensureSemicolon(1)
+                                    listener: handleExpressionStatement(;)
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(3, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(in)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, in)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(in)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'in'., null, {token: in}], in, in)
+                listener: handleInvalidMember(in)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(in, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(in)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(in, in, null, null, null, null, null, in, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(in, null, null, null, null, null, in, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(in)
+                  ensureIdentifier(in, methodDeclaration)
+                    insertSyntheticIdentifier(in, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+                                      listener: handleIdentifier(in, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(in)
+                                      parseArguments(in)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(in, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(is)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, is)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(is)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'is'., null, {token: is}], is, is)
+                listener: handleInvalidMember(is)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(is, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(is)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(is, is, null, null, null, null, null, is, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(is, null, null, null, null, null, is, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(is)
+                  ensureIdentifier(is, methodDeclaration)
+                    insertSyntheticIdentifier(is, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(is)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(is)
+                                    listener: handleSend(, is)
+                              parseIsOperatorRest()
+                                listener: beginIsOperatorType(is)
+                                computeTypeAfterIsOrAs(is)
+                                reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                                listener: handleIdentifier(, typeReference)
+                                listener: handleNoTypeArguments(()
+                                listener: handleType(, null)
+                                listener: endIsOperatorType(is)
+                                listener: handleIsOperator(is, null)
+                                skipChainedAsIsOperators()
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, ()
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction(()
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      parseParenthesizedExpressionOrFunctionLiteral(;)
+                                        parseParenthesizedExpression(;)
+                                          parseExpressionInParenthesis(;)
+                                            parseExpressionInParenthesisRest(()
+                                              parseExpression(()
+                                                parsePrecedenceExpression((, 1, true)
+                                                  parseUnaryExpression((, true)
+                                                    parsePrimary((, expression)
+                                                      parseSendOrFunctionLiteral((, expression)
+                                                        parseSend((, expression)
+                                                          ensureIdentifier((, expression)
+                                                            listener: handleIdentifier(x, expression)
+                                                          listener: handleNoTypeArguments(-)
+                                                          parseArgumentsOpt(x)
+                                                            listener: handleNoArguments(-)
+                                                          listener: handleSend(x, -)
+                                                  listener: beginBinaryExpression(-)
+                                                  parsePrecedenceExpression(-, 14, true)
+                                                    parseUnaryExpression(-, true)
+                                                      parsePrimary(-, expression)
+                                                        parseLiteralInt(-)
+                                                          listener: handleLiteralInt(1)
+                                                  listener: endBinaryExpression(-)
+                                              ensureCloseParen(1, ()
+                                          listener: handleParenthesizedExpression(()
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(3, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(new)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, new)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(new)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(new, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'new'., null, {token: new}], new, new)
+                listener: handleInvalidMember(new)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(new, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(new)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(new, new, null, null, null, null, null, new, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(new, null, null, null, null, null, new, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(new)
+                  ensureIdentifier(new, methodDeclaration)
+                    insertSyntheticIdentifier(new, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseNewExpression(return)
+                                    listener: beginNewExpression(new)
+                                    parseConstructorReference(new, null)
+                                      ensureIdentifier(new, constructorReference)
+                                        insertSyntheticIdentifier(new, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], messageOnToken: null)
+                                          reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                          rewriter()
+                                        listener: handleIdentifier(, constructorReference)
+                                      listener: beginConstructorReference()
+                                      parseQualifiedRestOpt(, constructorReferenceContinuation)
+                                      listener: handleNoTypeArguments(()
+                                      listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                                      listener: endConstructorReference(, null, ()
+                                    parseConstructorInvocationArguments()
+                                      parseArgumentsRest(()
+                                        listener: beginArguments(()
+                                        parseExpression(()
+                                          parsePrecedenceExpression((, 1, true)
+                                            parseUnaryExpression((, true)
+                                              parsePrimary((, expression)
+                                                parseSendOrFunctionLiteral((, expression)
+                                                  parseSend((, expression)
+                                                    ensureIdentifier((, expression)
+                                                      listener: handleIdentifier(x, expression)
+                                                    listener: handleNoTypeArguments(-)
+                                                    parseArgumentsOpt(x)
+                                                      listener: handleNoArguments(-)
+                                                    listener: handleSend(x, -)
+                                            listener: beginBinaryExpression(-)
+                                            parsePrecedenceExpression(-, 14, true)
+                                              parseUnaryExpression(-, true)
+                                                parsePrimary(-, expression)
+                                                  parseLiteralInt(-)
+                                                    listener: handleLiteralInt(1)
+                                            listener: endBinaryExpression(-)
+                                        listener: endArguments(1, (, ))
+                                    listener: endNewExpression(new)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(null)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, null)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(null)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(null, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'null'., null, {token: null}], null, null)
+                listener: handleInvalidMember(null)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(null, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(null)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(null, null, null, null, null, null, null, null, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(null, null, null, null, null, null, null, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(null)
+                  ensureIdentifier(null, methodDeclaration)
+                    insertSyntheticIdentifier(null, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseLiteralNull(return)
+                                    listener: handleLiteralNull(null)
+                              parseArgumentOrIndexStar(null, Instance of 'NoTypeParamOrArg', false)
+                                listener: handleNoTypeArguments(()
+                                parseArguments(null)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    listener: endArguments(1, (, ))
+                                listener: handleSend((, ))
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(rethrow)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, rethrow)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(rethrow)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+                listener: handleInvalidMember(rethrow)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(rethrow, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(rethrow)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(rethrow, rethrow, null, null, null, null, null, rethrow, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(rethrow, null, null, null, null, null, rethrow, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(rethrow)
+                  ensureIdentifier(rethrow, methodDeclaration)
+                    insertSyntheticIdentifier(rethrow, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+                                      listener: handleIdentifier(rethrow, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(rethrow)
+                                      parseArguments(rethrow)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(rethrow, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(return)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, return)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(return)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'return'., null, {token: return}], return, return)
+                listener: handleInvalidMember(return)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(return, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(return)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(return, return, null, null, null, null, null, return, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(return, null, null, null, null, null, return, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(return)
+                  ensureIdentifier(return, methodDeclaration)
+                    insertSyntheticIdentifier(return, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+                                    listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {token: return}], return, return)
+                                  parsePrimary(return, expression)
+                                    parseParenthesizedExpressionOrFunctionLiteral(return)
+                                      parseParenthesizedExpression(return)
+                                        parseExpressionInParenthesis(return)
+                                          parseExpressionInParenthesisRest(()
+                                            parseExpression(()
+                                              parsePrecedenceExpression((, 1, true)
+                                                parseUnaryExpression((, true)
+                                                  parsePrimary((, expression)
+                                                    parseSendOrFunctionLiteral((, expression)
+                                                      parseSend((, expression)
+                                                        ensureIdentifier((, expression)
+                                                          listener: handleIdentifier(x, expression)
+                                                        listener: handleNoTypeArguments(-)
+                                                        parseArgumentsOpt(x)
+                                                          listener: handleNoArguments(-)
+                                                        listener: handleSend(x, -)
+                                                listener: beginBinaryExpression(-)
+                                                parsePrecedenceExpression(-, 14, true)
+                                                  parseUnaryExpression(-, true)
+                                                    parsePrimary(-, expression)
+                                                      parseLiteralInt(-)
+                                                        listener: handleLiteralInt(1)
+                                                listener: endBinaryExpression(-)
+                                            ensureCloseParen(1, ()
+                                        listener: handleParenthesizedExpression(()
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(super)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, super)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(super)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(super, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'super'., null, {token: super}], super, super)
+                listener: handleInvalidMember(super)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(super, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(super)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(super, super, null, null, null, null, null, super, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(super, null, null, null, null, null, super, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(super)
+                  ensureIdentifier(super, methodDeclaration)
+                    insertSyntheticIdentifier(super, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseSuperExpression(return, expression)
+                                    listener: handleSuperExpression(super, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArguments(super)
+                                      parseArgumentsRest(()
+                                        listener: beginArguments(()
+                                        parseExpression(()
+                                          parsePrecedenceExpression((, 1, true)
+                                            parseUnaryExpression((, true)
+                                              parsePrimary((, expression)
+                                                parseSendOrFunctionLiteral((, expression)
+                                                  parseSend((, expression)
+                                                    ensureIdentifier((, expression)
+                                                      listener: handleIdentifier(x, expression)
+                                                    listener: handleNoTypeArguments(-)
+                                                    parseArgumentsOpt(x)
+                                                      listener: handleNoArguments(-)
+                                                    listener: handleSend(x, -)
+                                            listener: beginBinaryExpression(-)
+                                            parsePrecedenceExpression(-, 14, true)
+                                              parseUnaryExpression(-, true)
+                                                parsePrimary(-, expression)
+                                                  parseLiteralInt(-)
+                                                    listener: handleLiteralInt(1)
+                                            listener: endBinaryExpression(-)
+                                        listener: endArguments(1, (, ))
+                                    listener: handleSend(super, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(switch)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, switch)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(switch)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'switch'., null, {token: switch}], switch, switch)
+                listener: handleInvalidMember(switch)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(switch, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(switch)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(switch, switch, null, null, null, null, null, switch, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(switch, null, null, null, null, null, switch, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(switch)
+                  ensureIdentifier(switch, methodDeclaration)
+                    insertSyntheticIdentifier(switch, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(switch)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(switch)
+                                    listener: handleSend(, switch)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], switch, switch)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, switch)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseSwitchStatement(;)
+                          listener: beginSwitchStatement(switch)
+                          ensureParenthesizedCondition(switch)
+                            parseExpressionInParenthesisRest(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              ensureCloseParen(1, ()
+                            listener: handleParenthesizedCondition(()
+                          parseSwitchBlock())
+                            ensureBlock(), null, switch statement)
+                              reportRecoverableError(), Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}])
+                                listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
+                              insertBlock())
+                                rewriter()
+                                rewriter()
+                            listener: beginSwitchBlock({)
+                            notEofOrValue(}, })
+                            listener: endSwitchBlock(0, {, })
+                          listener: endSwitchStatement(switch, })
+                    notEofOrValue(}, +)
+                    parseStatement(})
+                      parseStatementX(})
+                        parseExpressionStatementOrDeclaration(}, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
+                            looksLikeLocalFunction(+)
+                            parseExpressionStatement(})
+                              parseExpression(})
+                                parsePrecedenceExpression(}, 1, true)
+                                  parseUnaryExpression(}, true)
+                                    rewriteAndRecover(}, UnsupportedPrefixPlus, )
+                                      reportRecoverableError(+, UnsupportedPrefixPlus)
+                                        listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                      rewriter()
+                                    parsePrimary(}, expression)
+                                      parseSendOrFunctionLiteral(}, expression)
+                                        parseSend(}, expression)
+                                          ensureIdentifier(}, expression)
+                                            listener: handleIdentifier(, expression)
+                                          listener: handleNoTypeArguments(+)
+                                          parseArgumentsOpt()
+                                            listener: handleNoArguments(+)
+                                          listener: handleSend(, +)
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(4, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(int, }, null, null, null, null, null, }, Instance of 'SimpleType', null, DeclarationKind.Class, WrapperClass)
+                parseFields(}, null, null, null, null, null, }, Instance of 'SimpleType', this, DeclarationKind.Class, WrapperClass)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(this)
+                  listener: handleType(int, null)
+                  ensureIdentifier(int, fieldDeclaration)
+                    reportRecoverableErrorWithToken(this, Instance of 'Template<(Token) => Message>')
+                      listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+                    listener: handleIdentifier(this, fieldDeclaration)
+                  parseFieldInitializerOpt(this, this, null, null, DeclarationKind.Class, WrapperClass)
+                    listener: handleNoFieldInitializer(()
+                  ensureSemicolon(this)
+                    reportRecoverableError(this, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], this, this)
+                    rewriter()
+                  listener: endClassFields(null, null, null, null, 1, int, ;)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(;, null, null, null, null, null, ;, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(;)
+                  ensureIdentifier(;, methodDeclaration)
+                    insertSyntheticIdentifier(;, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseThisExpression(return, expression)
+                                    listener: handleThisExpression(this, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArguments(this)
+                                      parseArgumentsRest(()
+                                        listener: beginArguments(()
+                                        parseExpression(()
+                                          parsePrecedenceExpression((, 1, true)
+                                            parseUnaryExpression((, true)
+                                              parsePrimary((, expression)
+                                                parseSendOrFunctionLiteral((, expression)
+                                                  parseSend((, expression)
+                                                    ensureIdentifier((, expression)
+                                                      listener: handleIdentifier(x, expression)
+                                                    listener: handleNoTypeArguments(-)
+                                                    parseArgumentsOpt(x)
+                                                      listener: handleNoArguments(-)
+                                                    listener: handleSend(x, -)
+                                            listener: beginBinaryExpression(-)
+                                            parsePrecedenceExpression(-, 14, true)
+                                              parseUnaryExpression(-, true)
+                                                parsePrimary(-, expression)
+                                                  parseLiteralInt(-)
+                                                    listener: handleLiteralInt(1)
+                                            listener: endBinaryExpression(-)
+                                        listener: endArguments(1, (, ))
+                                    listener: handleSend(this, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(throw)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, throw)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(throw)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(throw, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'throw'., null, {token: throw}], throw, throw)
+                listener: handleInvalidMember(throw)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(throw, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(throw)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(throw, throw, null, null, null, null, null, throw, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(throw, null, null, null, null, null, throw, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(throw)
+                  ensureIdentifier(throw, methodDeclaration)
+                    insertSyntheticIdentifier(throw, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parseThrowExpression(return, true)
+                              parseExpression(throw)
+                                parsePrecedenceExpression(throw, 1, true)
+                                  parseUnaryExpression(throw, true)
+                                    parsePrimary(throw, expression)
+                                      parseParenthesizedExpressionOrFunctionLiteral(throw)
+                                        parseParenthesizedExpression(throw)
+                                          parseExpressionInParenthesis(throw)
+                                            parseExpressionInParenthesisRest(()
+                                              parseExpression(()
+                                                parsePrecedenceExpression((, 1, true)
+                                                  parseUnaryExpression((, true)
+                                                    parsePrimary((, expression)
+                                                      parseSendOrFunctionLiteral((, expression)
+                                                        parseSend((, expression)
+                                                          ensureIdentifier((, expression)
+                                                            listener: handleIdentifier(x, expression)
+                                                          listener: handleNoTypeArguments(-)
+                                                          parseArgumentsOpt(x)
+                                                            listener: handleNoArguments(-)
+                                                          listener: handleSend(x, -)
+                                                  listener: beginBinaryExpression(-)
+                                                  parsePrecedenceExpression(-, 14, true)
+                                                    parseUnaryExpression(-, true)
+                                                      parsePrimary(-, expression)
+                                                        parseLiteralInt(-)
+                                                          listener: handleLiteralInt(1)
+                                                  listener: endBinaryExpression(-)
+                                              ensureCloseParen(1, ()
+                                          listener: handleParenthesizedExpression(()
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              listener: handleThrowExpression(throw, ;)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(true)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, true)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(true)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(true, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'true'., null, {token: true}], true, true)
+                listener: handleInvalidMember(true)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(true, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(true)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(true, true, null, null, null, null, null, true, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(true, null, null, null, null, null, true, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(true)
+                  ensureIdentifier(true, methodDeclaration)
+                    insertSyntheticIdentifier(true, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseLiteralBool(return)
+                                    listener: handleLiteralBool(true)
+                              parseArgumentOrIndexStar(true, Instance of 'NoTypeParamOrArg', false)
+                                listener: handleNoTypeArguments(()
+                                parseArguments(true)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    listener: endArguments(1, (, ))
+                                listener: handleSend((, ))
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(try)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, try)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(try)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'try'., null, {token: try}], try, try)
+                listener: handleInvalidMember(try)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(try, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(try)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(try, try, null, null, null, null, null, try, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(try, null, null, null, null, null, try, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(try)
+                  ensureIdentifier(try, methodDeclaration)
+                    insertSyntheticIdentifier(try, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(try)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(try)
+                                    listener: handleSend(, try)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], try, try)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, try)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseTryStatement(;)
+                          listener: beginTryStatement(try)
+                          parseBlock(try, BlockKind(try statement))
+                            ensureBlock(try, null, try statement)
+                              reportRecoverableError(try, Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}])
+                                listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}], try, try)
+                              insertBlock(try)
+                                rewriter()
+                                rewriter()
+                            listener: beginBlock({, BlockKind(try statement))
+                            notEofOrValue(}, })
+                            listener: endBlock(0, {, }, BlockKind(try statement))
+                          reportRecoverableError(try, OnlyTry)
+                            listener: handleRecoverableError(OnlyTry, try, try)
+                          listener: endTryStatement(0, try, null)
+                    notEofOrValue(}, ()
+                    parseStatement(})
+                      parseStatementX(})
+                        parseExpressionStatementOrDeclaration(}, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
+                            looksLikeLocalFunction(()
+                            parseExpressionStatement(})
+                              parseExpression(})
+                                parsePrecedenceExpression(}, 1, true)
+                                  parseUnaryExpression(}, true)
+                                    parsePrimary(}, expression)
+                                      parseParenthesizedExpressionOrFunctionLiteral(})
+                                        parseParenthesizedExpression(})
+                                          parseExpressionInParenthesis(})
+                                            parseExpressionInParenthesisRest(()
+                                              parseExpression(()
+                                                parsePrecedenceExpression((, 1, true)
+                                                  parseUnaryExpression((, true)
+                                                    parsePrimary((, expression)
+                                                      parseSendOrFunctionLiteral((, expression)
+                                                        parseSend((, expression)
+                                                          ensureIdentifier((, expression)
+                                                            listener: handleIdentifier(x, expression)
+                                                          listener: handleNoTypeArguments(-)
+                                                          parseArgumentsOpt(x)
+                                                            listener: handleNoArguments(-)
+                                                          listener: handleSend(x, -)
+                                                  listener: beginBinaryExpression(-)
+                                                  parsePrecedenceExpression(-, 14, true)
+                                                    parseUnaryExpression(-, true)
+                                                      parsePrimary(-, expression)
+                                                        parseLiteralInt(-)
+                                                          listener: handleLiteralInt(1)
+                                                  listener: endBinaryExpression(-)
+                                              ensureCloseParen(1, ()
+                                          listener: handleParenthesizedExpression(()
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(4, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(var)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, var)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(var, ;, null, null, null, null, var, var, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(;, null, null, null, null, var, var, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  reportRecoverableError(var, VarReturnType)
+                    listener: handleRecoverableError(VarReturnType, var, var)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(var)
+                  ensureIdentifier(var, methodDeclaration)
+                    insertSyntheticIdentifier(var, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(var, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'var'., null, {token: var}], var, var)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(var)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(var)
+                                    listener: handleSend(, var)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], var, var)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, var)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                          looksLikeLocalFunction(()
+                          listener: beginMetadataStar(var)
+                          listener: endMetadataStar(0)
+                          listener: handleNoType(var)
+                          listener: beginVariablesDeclaration((, null, var)
+                          parseVariablesDeclarationRest(var, true)
+                            parseOptionallyInitializedIdentifier(var)
+                              ensureIdentifier(var, localVariableDeclaration)
+                                reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                                listener: handleIdentifier(, localVariableDeclaration)
+                              listener: beginInitializedIdentifier()
+                              parseVariableInitializerOpt()
+                                listener: handleNoVariableInitializer(x)
+                              listener: endInitializedIdentifier()
+                            ensureSemicolon()
+                              reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                              rewriter()
+                            listener: endVariablesDeclaration(1, ;)
+                    notEofOrValue(}, x)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                          looksLikeLocalFunction(x)
+                          parseExpressionStatement(;)
+                            parseExpression(;)
+                              parsePrecedenceExpression(;, 1, true)
+                                parseUnaryExpression(;, true)
+                                  parsePrimary(;, expression)
+                                    parseSendOrFunctionLiteral(;, expression)
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          listener: handleIdentifier(x, expression)
+                                        listener: handleNoTypeArguments(-)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(-)
+                                        listener: handleSend(x, -)
+                                listener: beginBinaryExpression(-)
+                                parsePrecedenceExpression(-, 14, true)
+                                  parseUnaryExpression(-, true)
+                                    parsePrimary(-, expression)
+                                      parseLiteralInt(-)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(-)
+                            ensureSemicolon(1)
+                              reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                              rewriter()
+                            listener: handleExpressionStatement(;)
+                    notEofOrValue(}, ))
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction())
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                          rewriter()
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments())
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments())
+                                        listener: handleSend(, ))
+                              ensureSemicolon()
+                                reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                  listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                                rewriter()
+                              listener: handleExpressionStatement(;)
+                    reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+                      listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+                    notEofOrValue(}, +)
+                    parseStatement())
+                      parseStatementX())
+                        parseExpressionStatementOrDeclaration(), false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                            looksLikeLocalFunction(+)
+                            parseExpressionStatement())
+                              parseExpression())
+                                parsePrecedenceExpression(), 1, true)
+                                  parseUnaryExpression(), true)
+                                    rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                      reportRecoverableError(+, UnsupportedPrefixPlus)
+                                        listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                      rewriter()
+                                    parsePrimary(), expression)
+                                      parseSendOrFunctionLiteral(), expression)
+                                        parseSend(), expression)
+                                          ensureIdentifier(), expression)
+                                            listener: handleIdentifier(, expression)
+                                          listener: handleNoTypeArguments(+)
+                                          parseArgumentsOpt()
+                                            listener: handleNoArguments(+)
+                                          listener: handleSend(, +)
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(6, {, })
+                  listener: endClassMethod(null, var, (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(void)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, void)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(void)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(void, ;, null, null, null, null, null, ;, Instance of 'VoidType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(;, null, null, null, null, null, ;, Instance of 'VoidType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleVoidKeyword(void)
+                  ensureIdentifier(void, methodDeclaration)
+                    insertSyntheticIdentifier(void, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  parseSendOrFunctionLiteral(return, expression)
+                                    parseSend(return, expression)
+                                      ensureIdentifier(return, expression)
+                                        reportRecoverableErrorWithToken(void, Instance of 'Template<(Token) => Message>')
+                                          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'void'., null, {token: void}], void, void)
+                                        rewriter()
+                                        listener: handleIdentifier(, expression)
+                                      listener: handleNoTypeArguments(void)
+                                      parseArgumentsOpt()
+                                        listener: handleNoArguments(void)
+                                      listener: handleSend(, void)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, void)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction(()
+                            listener: beginMetadataStar(void)
+                            listener: endMetadataStar(0)
+                            listener: handleVoidKeyword(void)
+                            listener: beginVariablesDeclaration((, null, null)
+                            parseVariablesDeclarationRest(void, true)
+                              parseOptionallyInitializedIdentifier(void)
+                                ensureIdentifier(void, localVariableDeclaration)
+                                  reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                                    listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                  rewriter()
+                                  listener: handleIdentifier(, localVariableDeclaration)
+                                listener: beginInitializedIdentifier()
+                                parseVariableInitializerOpt()
+                                  listener: handleNoVariableInitializer(x)
+                                listener: endInitializedIdentifier()
+                              ensureSemicolon()
+                                reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                  listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                                rewriter()
+                              listener: endVariablesDeclaration(1, ;)
+                    notEofOrValue(}, x)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                          looksLikeLocalFunction(x)
+                          parseExpressionStatement(;)
+                            parseExpression(;)
+                              parsePrecedenceExpression(;, 1, true)
+                                parseUnaryExpression(;, true)
+                                  parsePrimary(;, expression)
+                                    parseSendOrFunctionLiteral(;, expression)
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          listener: handleIdentifier(x, expression)
+                                        listener: handleNoTypeArguments(-)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(-)
+                                        listener: handleSend(x, -)
+                                listener: beginBinaryExpression(-)
+                                parsePrecedenceExpression(-, 14, true)
+                                  parseUnaryExpression(-, true)
+                                    parsePrimary(-, expression)
+                                      parseLiteralInt(-)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(-)
+                            ensureSemicolon(1)
+                              reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                              rewriter()
+                            listener: handleExpressionStatement(;)
+                    notEofOrValue(}, ))
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseExpressionStatementOrDeclaration(;, false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                            looksLikeLocalFunction())
+                            parseExpressionStatement(;)
+                              parseExpression(;)
+                                parsePrecedenceExpression(;, 1, true)
+                                  parseUnaryExpression(;, true)
+                                    parsePrimary(;, expression)
+                                      parseSend(;, expression)
+                                        ensureIdentifier(;, expression)
+                                          reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                          rewriter()
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments())
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments())
+                                        listener: handleSend(, ))
+                              ensureSemicolon()
+                                reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                  listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                                rewriter()
+                              listener: handleExpressionStatement(;)
+                    reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+                      listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+                    notEofOrValue(}, +)
+                    parseStatement())
+                      parseStatementX())
+                        parseExpressionStatementOrDeclaration(), false)
+                          parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                            looksLikeLocalFunction(+)
+                            parseExpressionStatement())
+                              parseExpression())
+                                parsePrecedenceExpression(), 1, true)
+                                  parseUnaryExpression(), true)
+                                    rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                      reportRecoverableError(+, UnsupportedPrefixPlus)
+                                        listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                      rewriter()
+                                    parsePrimary(), expression)
+                                      parseSendOrFunctionLiteral(), expression)
+                                        parseSend(), expression)
+                                          ensureIdentifier(), expression)
+                                            listener: handleIdentifier(, expression)
+                                          listener: handleNoTypeArguments(+)
+                                          parseArgumentsOpt()
+                                            listener: handleNoArguments(+)
+                                          listener: handleSend(, +)
+                                  listener: beginBinaryExpression(+)
+                                  parsePrecedenceExpression(+, 14, true)
+                                    parseUnaryExpression(+, true)
+                                      parsePrimary(+, expression)
+                                        parseLiteralInt(+)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(+)
+                              ensureSemicolon(1)
+                              listener: handleExpressionStatement(;)
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(6, {, })
+                  listener: endClassMethod(null, void, (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(while)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, while)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(while)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'while'., null, {token: while}], while, while)
+                listener: handleInvalidMember(while)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(while, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(while)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(while, while, null, null, null, null, null, while, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(while, null, null, null, null, null, while, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(while)
+                  ensureIdentifier(while, methodDeclaration)
+                    insertSyntheticIdentifier(while, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(while)
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(while)
+                                    listener: handleSend(, while)
+                          ensureSemicolon()
+                            reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], while, while)
+                            rewriter()
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, while)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseWhileStatement(;)
+                          listener: beginWhileStatement(while)
+                          ensureParenthesizedCondition(while)
+                            parseExpressionInParenthesisRest(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              ensureCloseParen(1, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginWhileStatementBody(+)
+                          parseStatement())
+                            parseStatementX())
+                              parseExpressionStatementOrDeclaration(), false)
+                                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                                  looksLikeLocalFunction(+)
+                                  parseExpressionStatement())
+                                    parseExpression())
+                                      parsePrecedenceExpression(), 1, true)
+                                        parseUnaryExpression(), true)
+                                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                            rewriter()
+                                          parsePrimary(), expression)
+                                            parseSendOrFunctionLiteral(), expression)
+                                              parseSend(), expression)
+                                                ensureIdentifier(), expression)
+                                                  listener: handleIdentifier(, expression)
+                                                listener: handleNoTypeArguments(+)
+                                                parseArgumentsOpt()
+                                                  listener: handleNoArguments(+)
+                                                listener: handleSend(, +)
+                                        listener: beginBinaryExpression(+)
+                                        parsePrecedenceExpression(+, 14, true)
+                                          parseUnaryExpression(+, true)
+                                            parsePrimary(+, expression)
+                                              parseLiteralInt(+)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(+)
+                                    ensureSemicolon(1)
+                                    listener: handleExpressionStatement(;)
+                          listener: endWhileStatementBody(})
+                          listener: endWhileStatement(while, })
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(3, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.Class, WrapperClass)
+                reportRecoverableError(int, MissingConstFinalVarOrType)
+                  listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+                listener: handleNoType(})
+                ensureIdentifier(}, fieldDeclaration)
+                  listener: handleIdentifier(int, fieldDeclaration)
+                parseFieldInitializerOpt(int, int, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: handleNoFieldInitializer(with)
+                ensureSemicolon(int)
+                  reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+                  rewriter()
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, with)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(with)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(;, ;, null, null, null, null, null, ;, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedClassMember, Expected a class member, but got 'with'., null, {token: with}], with, with)
+                listener: handleInvalidMember(with)
+                listener: endMember()
+            notEofOrValue(}, ()
+            parseClassOrMixinOrExtensionMemberImpl(with, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(with)
+                listener: beginMetadataStar(()
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              recoverFromInvalidMember(with, with, null, null, null, null, null, with, Instance of 'NoType', null, DeclarationKind.Class, WrapperClass)
+                parseMethod(with, null, null, null, null, null, with, Instance of 'NoType', null, (, DeclarationKind.Class, WrapperClass)
+                  listener: beginMethod(null, null, null, null, null, ()
+                  listener: handleNoType(with)
+                  ensureIdentifier(with, methodDeclaration)
+                    insertSyntheticIdentifier(with, methodDeclaration, message: null, messageOnToken: null)
+                      reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                    listener: handleIdentifier(, methodDeclaration)
+                  parseQualifiedRestOpt(, methodDeclarationContinuation)
+                  parseMethodTypeVar()
+                    listener: handleNoTypeVariables(()
+                  parseGetterOrFormalParameters(, (, false, MemberKind.NonStaticMethod)
+                    parseFormalParameters(, MemberKind.NonStaticMethod)
+                      parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                        listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                        parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                          parseMetadataStar(()
+                            listener: beginMetadataStar(int)
+                            listener: endMetadataStar(0)
+                          listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(x)
+                          listener: handleType(int, null)
+                          ensureIdentifier(int, formalParameterDeclaration)
+                            listener: handleIdentifier(x, formalParameterDeclaration)
+                          listener: handleFormalParameterWithoutValue())
+                          listener: endFormalParameter(null, null, x, 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(x, expression)
+                                          listener: handleNoTypeArguments(==)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(==)
+                                          listener: handleSend(x, ==)
+                                  listener: beginBinaryExpression(==)
+                                  parsePrecedenceExpression(==, 8, true)
+                                    parseUnaryExpression(==, true)
+                                      parsePrimary(==, expression)
+                                        parseLiteralInt(==)
+                                          listener: handleLiteralInt(0)
+                                  listener: endBinaryExpression(==)
+                              ensureCloseParen(0, ()
+                            listener: handleParenthesizedCondition(()
+                          listener: beginThenStatement(return)
+                          parseStatement())
+                            parseStatementX())
+                              parseReturnStatement())
+                                listener: beginReturnStatement(return)
+                                parseExpression(return)
+                                  parsePrecedenceExpression(return, 1, true)
+                                    parseUnaryExpression(return, true)
+                                      parsePrimary(return, expression)
+                                        parseLiteralInt(return)
+                                          listener: handleLiteralInt(42)
+                                ensureSemicolon(42)
+                                listener: endReturnStatement(true, return, ;)
+                                inGenerator()
+                          listener: endThenStatement(;)
+                          listener: endIfStatement(if, null)
+                    notEofOrValue(}, return)
+                    parseStatement(;)
+                      parseStatementX(;)
+                        parseReturnStatement(;)
+                          listener: beginReturnStatement(return)
+                          parseExpression(return)
+                            parsePrecedenceExpression(return, 1, true)
+                              parseUnaryExpression(return, true)
+                                parsePrimary(return, expression)
+                                  inPlainSync()
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+                                      listener: handleIdentifier(with, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(with)
+                                      parseArguments(with)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(with, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: endReturnStatement(true, return, ;)
+                          inGenerator()
+                    notEofOrValue(}, })
+                    listener: endBlockFunctionBody(2, {, })
+                  listener: endClassMethod(null, , (, null, })
+                listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 94, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.parser.expect
new file mode 100644
index 0000000..2d842d0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.parser.expect
@@ -0,0 +1,335 @@
+NOTICE: Stream was rewritten by parser!
+
+class WrapperClass {
+int ;assert(int x) {
+if (x == 0) return 42;
+return assert(x-1) + 1;
+}
+
+int ;break(int x) {
+if (x == 0) return 42;
+return ;break;(x-1) + 1;
+}
+
+int ;case(int x) {
+if (x == 0) return 42;
+return case(x-1) + 1;
+}
+
+int ;catch(int x) {
+if (x == 0) return 42;
+return catch(x-1) + 1;
+}
+
+int ;class(int x) {
+if (x == 0) return 42;
+return class(x-1) + 1;
+}
+
+int ;const(int x) {
+if (x == 0) return 42;
+return const(x-1) + 1;
+}
+
+int ;continue(int x) {
+if (x == 0) return 42;
+return ;continue;(x-1) + 1;
+}
+
+int ;default(int x) {
+if (x == 0) return 42;
+return default(x-1) + 1;
+}
+
+int ;do(int x) {
+if (x == 0) return 42;
+return ;do(x-1) + 1;
+while();}
+
+int ;else(int x) {
+if (x == 0) return 42;
+return ;;else(x-1) + 1;
+}
+
+int ;enum(int x) {
+if (x == 0) return 42;
+return enum(x-1) + 1;
+}
+
+int ;extends(int x) {
+if (x == 0) return 42;
+return extends(x-1) + 1;
+}
+
+int ;false(int x) {
+if (x == 0) return 42;
+return false(x-1) + 1;
+}
+
+int ;final(int x) {
+if (x == 0) return 42;
+return ;final(;x-1;;) + 1;
+}
+
+int ;finally(int x) {
+if (x == 0) return 42;
+return finally(x-1) + 1;
+}
+
+int ;for(int x) {
+if (x == 0) return 42;
+return ;for(x-1;;) + 1;
+}
+
+int ;if(int x) {
+if (x == 0) return 42;
+return ;if(x-1) + 1;
+}
+
+int ;in(int x) {
+if (x == 0) return 42;
+return in(x-1) + 1;
+}
+
+int ;is(int x) {
+if (x == 0) return 42;
+return is;(x-1) + 1;
+}
+
+int ;new(int x) {
+if (x == 0) return 42;
+return new(x-1) + 1;
+}
+
+int ;null(int x) {
+if (x == 0) return 42;
+return null(x-1) + 1;
+}
+
+int ;rethrow(int x) {
+if (x == 0) return 42;
+return rethrow(x-1) + 1;
+}
+
+int ;return(int x) {
+if (x == 0) return 42;
+return return(x-1) + 1;
+}
+
+int ;super(int x) {
+if (x == 0) return 42;
+return super(x-1) + 1;
+}
+
+int ;switch(int x) {
+if (x == 0) return 42;
+return ;switch(x-1) {}+ 1;
+}
+
+int this;(int x) {
+if (x == 0) return 42;
+return this(x-1) + 1;
+}
+
+int ;throw(int x) {
+if (x == 0) return 42;
+return throw(x-1) + 1;
+}
+
+int ;true(int x) {
+if (x == 0) return 42;
+return true(x-1) + 1;
+}
+
+int ;try(int x) {
+if (x == 0) return 42;
+return ;try{}(x-1) + 1;
+}
+
+int ;var(int x) {
+if (x == 0) return 42;
+return ;var(;x-1;;) + 1;
+}
+
+int ;void(int x) {
+if (x == 0) return 42;
+return ;void(;x-1;;) + 1;
+}
+
+int ;while(int x) {
+if (x == 0) return 42;
+return ;while(x-1) + 1;
+}
+
+int ;with(int x) {
+if (x == 0) return 42;
+return with(x-1) + 1;
+}
+}
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] ;[SyntheticToken]assert[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] assert[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]break[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]break[KeywordToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]case[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] case[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]catch[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] catch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]class[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] class[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]const[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]continue[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]continue[KeywordToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]default[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] default[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]do[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]do[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+while[SyntheticKeywordToken]([SyntheticBeginToken][SyntheticStringToken])[SyntheticToken];[SyntheticToken]}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]else[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken]else[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]enum[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] enum[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]extends[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] extends[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]false[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] false[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]final[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]final[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]finally[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] finally[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]for[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]for[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]if[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]if[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]in[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] in[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]is[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken]is[KeywordToken][SyntheticStringToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]new[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] new[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]null[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] null[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]rethrow[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] rethrow[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]return[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] return[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]super[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] super[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]switch[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]switch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] {[SyntheticBeginToken]}[SyntheticToken][SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] this[KeywordToken];[SyntheticToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] this[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]throw[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] throw[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]true[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] true[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]try[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]try[KeywordToken]{[SyntheticBeginToken]}[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]var[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]var[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]void[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]void[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]while[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]while[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]with[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] with[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.scanner.expect
new file mode 100644
index 0000000..3401113
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_class_methods.dart.scanner.expect
@@ -0,0 +1,333 @@
+class WrapperClass {
+int assert(int x) {
+if (x == 0) return 42;
+return assert(x-1) + 1;
+}
+
+int break(int x) {
+if (x == 0) return 42;
+return break(x-1) + 1;
+}
+
+int case(int x) {
+if (x == 0) return 42;
+return case(x-1) + 1;
+}
+
+int catch(int x) {
+if (x == 0) return 42;
+return catch(x-1) + 1;
+}
+
+int class(int x) {
+if (x == 0) return 42;
+return class(x-1) + 1;
+}
+
+int const(int x) {
+if (x == 0) return 42;
+return const(x-1) + 1;
+}
+
+int continue(int x) {
+if (x == 0) return 42;
+return continue(x-1) + 1;
+}
+
+int default(int x) {
+if (x == 0) return 42;
+return default(x-1) + 1;
+}
+
+int do(int x) {
+if (x == 0) return 42;
+return do(x-1) + 1;
+}
+
+int else(int x) {
+if (x == 0) return 42;
+return else(x-1) + 1;
+}
+
+int enum(int x) {
+if (x == 0) return 42;
+return enum(x-1) + 1;
+}
+
+int extends(int x) {
+if (x == 0) return 42;
+return extends(x-1) + 1;
+}
+
+int false(int x) {
+if (x == 0) return 42;
+return false(x-1) + 1;
+}
+
+int final(int x) {
+if (x == 0) return 42;
+return final(x-1) + 1;
+}
+
+int finally(int x) {
+if (x == 0) return 42;
+return finally(x-1) + 1;
+}
+
+int for(int x) {
+if (x == 0) return 42;
+return for(x-1) + 1;
+}
+
+int if(int x) {
+if (x == 0) return 42;
+return if(x-1) + 1;
+}
+
+int in(int x) {
+if (x == 0) return 42;
+return in(x-1) + 1;
+}
+
+int is(int x) {
+if (x == 0) return 42;
+return is(x-1) + 1;
+}
+
+int new(int x) {
+if (x == 0) return 42;
+return new(x-1) + 1;
+}
+
+int null(int x) {
+if (x == 0) return 42;
+return null(x-1) + 1;
+}
+
+int rethrow(int x) {
+if (x == 0) return 42;
+return rethrow(x-1) + 1;
+}
+
+int return(int x) {
+if (x == 0) return 42;
+return return(x-1) + 1;
+}
+
+int super(int x) {
+if (x == 0) return 42;
+return super(x-1) + 1;
+}
+
+int switch(int x) {
+if (x == 0) return 42;
+return switch(x-1) + 1;
+}
+
+int this(int x) {
+if (x == 0) return 42;
+return this(x-1) + 1;
+}
+
+int throw(int x) {
+if (x == 0) return 42;
+return throw(x-1) + 1;
+}
+
+int true(int x) {
+if (x == 0) return 42;
+return true(x-1) + 1;
+}
+
+int try(int x) {
+if (x == 0) return 42;
+return try(x-1) + 1;
+}
+
+int var(int x) {
+if (x == 0) return 42;
+return var(x-1) + 1;
+}
+
+int void(int x) {
+if (x == 0) return 42;
+return void(x-1) + 1;
+}
+
+int while(int x) {
+if (x == 0) return 42;
+return while(x-1) + 1;
+}
+
+int with(int x) {
+if (x == 0) return 42;
+return with(x-1) + 1;
+}
+}
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] assert[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] assert[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] break[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] break[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] case[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] case[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] catch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] catch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] class[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] class[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] const[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] continue[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] default[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] default[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] do[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] do[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] else[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] else[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] enum[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] enum[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] extends[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] extends[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] false[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] false[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] final[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] final[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] finally[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] finally[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] for[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] for[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] if[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] if[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] in[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] in[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] is[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] is[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] new[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] new[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] null[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] null[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] rethrow[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] rethrow[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] return[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] return[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] super[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] super[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] switch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] switch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] this[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] this[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] throw[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] throw[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] true[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] true[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] try[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] try[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] var[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] var[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] void[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] void[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] while[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] while[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] with[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] with[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart
new file mode 100644
index 0000000..30bed69
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart
@@ -0,0 +1,164 @@
+int assert(int x) {
+  if (x == 0) return 42;
+  return assert(x-1) + 1;
+}
+
+int break(int x) {
+  if (x == 0) return 42;
+  return break(x-1) + 1;
+}
+
+int case(int x) {
+  if (x == 0) return 42;
+  return case(x-1) + 1;
+}
+
+int catch(int x) {
+  if (x == 0) return 42;
+  return catch(x-1) + 1;
+}
+
+int class(int x) {
+  if (x == 0) return 42;
+  return class(x-1) + 1;
+}
+
+int const(int x) {
+  if (x == 0) return 42;
+  return const(x-1) + 1;
+}
+
+int continue(int x) {
+  if (x == 0) return 42;
+  return continue(x-1) + 1;
+}
+
+int default(int x) {
+  if (x == 0) return 42;
+  return default(x-1) + 1;
+}
+
+int do(int x) {
+  if (x == 0) return 42;
+  return do(x-1) + 1;
+}
+
+int else(int x) {
+  if (x == 0) return 42;
+  return else(x-1) + 1;
+}
+
+int enum(int x) {
+  if (x == 0) return 42;
+  return enum(x-1) + 1;
+}
+
+int extends(int x) {
+  if (x == 0) return 42;
+  return extends(x-1) + 1;
+}
+
+int false(int x) {
+  if (x == 0) return 42;
+  return false(x-1) + 1;
+}
+
+int final(int x) {
+  if (x == 0) return 42;
+  return final(x-1) + 1;
+}
+
+int finally(int x) {
+  if (x == 0) return 42;
+  return finally(x-1) + 1;
+}
+
+int for(int x) {
+  if (x == 0) return 42;
+  return for(x-1) + 1;
+}
+
+int if(int x) {
+  if (x == 0) return 42;
+  return if(x-1) + 1;
+}
+
+int in(int x) {
+  if (x == 0) return 42;
+  return in(x-1) + 1;
+}
+
+int is(int x) {
+  if (x == 0) return 42;
+  return is(x-1) + 1;
+}
+
+int new(int x) {
+  if (x == 0) return 42;
+  return new(x-1) + 1;
+}
+
+int null(int x) {
+  if (x == 0) return 42;
+  return null(x-1) + 1;
+}
+
+int rethrow(int x) {
+  if (x == 0) return 42;
+  return rethrow(x-1) + 1;
+}
+
+int return(int x) {
+  if (x == 0) return 42;
+  return return(x-1) + 1;
+}
+
+int super(int x) {
+  if (x == 0) return 42;
+  return super(x-1) + 1;
+}
+
+int switch(int x) {
+  if (x == 0) return 42;
+  return switch(x-1) + 1;
+}
+
+int this(int x) {
+  if (x == 0) return 42;
+  return this(x-1) + 1;
+}
+
+int throw(int x) {
+  if (x == 0) return 42;
+  return throw(x-1) + 1;
+}
+
+int true(int x) {
+  if (x == 0) return 42;
+  return true(x-1) + 1;
+}
+
+int try(int x) {
+  if (x == 0) return 42;
+  return try(x-1) + 1;
+}
+
+int var(int x) {
+  if (x == 0) return 42;
+  return var(x-1) + 1;
+}
+
+int void(int x) {
+  if (x == 0) return 42;
+  return void(x-1) + 1;
+}
+
+int while(int x) {
+  if (x == 0) return 42;
+  return while(x-1) + 1;
+}
+
+int with(int x) {
+  if (x == 0) return 42;
+  return with(x-1) + 1;
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.expect
new file mode 100644
index 0000000..ca1fdb1
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.expect
@@ -0,0 +1,3177 @@
+Problems reported:
+
+parser/error_recovery/reserved_words_top_level_fields:1:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int assert(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:1:1: Expected ';' after this.
+int assert(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:1:5: Expected an identifier, but got 'assert'.
+int assert(int x) {
+    ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:3:10: `assert` can't be used as an expression.
+  return assert(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:6:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int break(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:6:1: Expected ';' after this.
+int break(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:6:5: Expected an identifier, but got 'break'.
+int break(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:8:10: Expected an identifier, but got 'break'.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:8:10: Expected ';' after this.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:8:10: A break statement can't be used outside of a loop or switch statement.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:8:10: Expected ';' after this.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:11:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int case(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:11:1: Expected ';' after this.
+int case(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:11:5: Expected an identifier, but got 'case'.
+int case(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:13:10: Expected an identifier, but got 'case'.
+  return case(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:16:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int catch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:16:1: Expected ';' after this.
+int catch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:16:5: Expected an identifier, but got 'catch'.
+int catch(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:18:10: Expected an identifier, but got 'catch'.
+  return catch(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:21:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int class(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:21:1: Expected ';' after this.
+int class(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:21:10: Expected an identifier, but got '('.
+int class(int x) {
+         ^
+
+parser/error_recovery/reserved_words_top_level_fields:21:11: A class declaration must have a body, even if it is empty.
+int class(int x) {
+          ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:21:15: Expected ';' after this.
+int class(int x) {
+              ^
+
+parser/error_recovery/reserved_words_top_level_fields:21:16: Expected a declaration, but got ')'.
+int class(int x) {
+               ^
+
+parser/error_recovery/reserved_words_top_level_fields:21:18: Expected a declaration, but got '{'.
+int class(int x) {
+                 ^
+
+parser/error_recovery/reserved_words_top_level_fields:26:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int const(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:26:1: Expected ';' after this.
+int const(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:26:10: Expected an identifier, but got '('.
+int const(int x) {
+         ^
+
+parser/error_recovery/reserved_words_top_level_fields:26:5: Can't have modifier 'const' here.
+int const(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:28:15: Expected an identifier, but got '('.
+  return const(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_top_level_fields:31:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int continue(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:31:1: Expected ';' after this.
+int continue(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:31:5: Expected an identifier, but got 'continue'.
+int continue(int x) {
+    ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:33:10: Expected an identifier, but got 'continue'.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:33:10: Expected ';' after this.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:33:10: A continue statement can't be used outside of a loop or switch statement.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:33:10: Expected ';' after this.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:36:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int default(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:36:1: Expected ';' after this.
+int default(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:36:5: Expected an identifier, but got 'default'.
+int default(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:38:10: Expected an identifier, but got 'default'.
+  return default(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:41:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int do(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:41:1: Expected ';' after this.
+int do(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:41:5: Expected an identifier, but got 'do'.
+int do(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_fields:43:10: Expected an identifier, but got 'do'.
+  return do(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_fields:43:10: Expected ';' after this.
+  return do(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_fields:44:1: Expected 'while' before this.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_fields:44:1: Expected to find '('.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_fields:44:1: Expected an identifier, but got '}'.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_fields:44:1: Expected ';' after this.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_fields:46:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int else(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:46:1: Expected ';' after this.
+int else(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:46:5: Expected an identifier, but got 'else'.
+int else(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:48:10: Expected an identifier, but got 'else'.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:48:10: Expected ';' after this.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:48:10: Expected an identifier, but got 'else'.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:48:10: Expected ';' after this.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:48:10: Unexpected token ';'.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:51:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int enum(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:51:1: Expected ';' after this.
+int enum(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:51:9: Expected an identifier, but got '('.
+int enum(int x) {
+        ^
+
+parser/error_recovery/reserved_words_top_level_fields:51:10: Expected a enum body, but got 'int'.
+int enum(int x) {
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:51:14: Expected ';' after this.
+int enum(int x) {
+             ^
+
+parser/error_recovery/reserved_words_top_level_fields:51:15: Expected a declaration, but got ')'.
+int enum(int x) {
+              ^
+
+parser/error_recovery/reserved_words_top_level_fields:51:17: Expected a declaration, but got '{'.
+int enum(int x) {
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:56:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int extends(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:56:1: Expected ';' after this.
+int extends(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:56:5: Expected an identifier, but got 'extends'.
+int extends(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:58:10: Expected an identifier, but got 'extends'.
+  return extends(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:61:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int false(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:61:1: Expected ';' after this.
+int false(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:61:5: Expected an identifier, but got 'false'.
+int false(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:66:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int final(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:66:1: Expected ';' after this.
+int final(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:66:10: Expected an identifier, but got '('.
+int final(int x) {
+         ^
+
+parser/error_recovery/reserved_words_top_level_fields:66:5: Can't have modifier 'final' here.
+int final(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:68:10: Expected an identifier, but got 'final'.
+  return final(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:68:10: Expected ';' after this.
+  return final(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:68:15: Expected an identifier, but got '('.
+  return final(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_top_level_fields:68:16: Expected ';' after this.
+  return final(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_top_level_fields:68:18: Expected ';' after this.
+  return final(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_fields:68:19: Expected an identifier, but got ')'.
+  return final(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_fields:68:19: Expected ';' after this.
+  return final(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_fields:68:19: Unexpected token ';'.
+  return final(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_fields:68:21: '+' is not a prefix operator.
+  return final(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_top_level_fields:71:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int finally(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:71:1: Expected ';' after this.
+int finally(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:71:5: Expected an identifier, but got 'finally'.
+int finally(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:73:10: Expected an identifier, but got 'finally'.
+  return finally(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:76:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int for(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:76:1: Expected ';' after this.
+int for(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:76:5: Expected an identifier, but got 'for'.
+int for(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:78:10: Expected an identifier, but got 'for'.
+  return for(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:78:10: Expected ';' after this.
+  return for(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:78:16: Expected ';' after this.
+  return for(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_top_level_fields:78:17: Expected an identifier, but got ')'.
+  return for(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:78:17: Expected ';' after this.
+  return for(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:78:19: '+' is not a prefix operator.
+  return for(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_fields:81:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int if(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:81:1: Expected ';' after this.
+int if(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:81:5: Expected an identifier, but got 'if'.
+int if(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_fields:83:10: Expected an identifier, but got 'if'.
+  return if(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_fields:83:10: Expected ';' after this.
+  return if(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_fields:83:18: '+' is not a prefix operator.
+  return if(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_fields:86:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int in(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:86:1: Expected ';' after this.
+int in(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:86:5: Expected an identifier, but got 'in'.
+int in(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_fields:88:10: Expected an identifier, but got 'in'.
+  return in(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_fields:91:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int is(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:91:1: Expected ';' after this.
+int is(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:91:5: Expected an identifier, but got 'is'.
+int is(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_fields:93:10: Expected an identifier, but got 'is'.
+  return is(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_fields:93:12: Expected a type, but got '('.
+  return is(x-1) + 1;
+           ^
+
+parser/error_recovery/reserved_words_top_level_fields:93:12: Expected ';' after this.
+  return is(x-1) + 1;
+           ^
+
+parser/error_recovery/reserved_words_top_level_fields:96:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int new(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:96:1: Expected ';' after this.
+int new(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:96:5: Expected an identifier, but got 'new'.
+int new(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:98:13: Expected an identifier, but got '('.
+  return new(x-1) + 1;
+            ^
+
+parser/error_recovery/reserved_words_top_level_fields:101:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int null(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:101:1: Expected ';' after this.
+int null(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:101:5: Expected an identifier, but got 'null'.
+int null(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:106:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int rethrow(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:106:1: Expected ';' after this.
+int rethrow(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:106:5: Expected an identifier, but got 'rethrow'.
+int rethrow(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:108:10: Expected an identifier, but got 'rethrow'.
+  return rethrow(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:111:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int return(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:111:1: Expected ';' after this.
+int return(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:111:5: Expected an identifier, but got 'return'.
+int return(int x) {
+    ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:113:10: Unexpected token 'return'.
+  return return(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:116:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int super(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:116:1: Expected ';' after this.
+int super(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:116:5: Expected an identifier, but got 'super'.
+int super(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:121:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int switch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:121:1: Expected ';' after this.
+int switch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:121:5: Expected an identifier, but got 'switch'.
+int switch(int x) {
+    ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:123:10: Expected an identifier, but got 'switch'.
+  return switch(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:123:10: Expected ';' after this.
+  return switch(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:123:20: A switch statement must have a body, even if it is empty.
+  return switch(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_top_level_fields:123:22: '+' is not a prefix operator.
+  return switch(x-1) + 1;
+                     ^
+
+parser/error_recovery/reserved_words_top_level_fields:126:5: Expected an identifier, but got 'this'.
+int this(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:131:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int throw(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:131:1: Expected ';' after this.
+int throw(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:131:5: Expected an identifier, but got 'throw'.
+int throw(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:136:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int true(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:136:1: Expected ';' after this.
+int true(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:136:5: Expected an identifier, but got 'true'.
+int true(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:141:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int try(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:141:1: Expected ';' after this.
+int try(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:141:5: Expected an identifier, but got 'try'.
+int try(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:143:10: Expected an identifier, but got 'try'.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:143:10: Expected ';' after this.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:143:10: A try statement must have a body, even if it is empty.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:143:10: A try block must be followed by an 'on', 'catch', or 'finally' clause.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:146:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int var(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:146:1: Expected ';' after this.
+int var(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:146:8: Expected an identifier, but got '('.
+int var(int x) {
+       ^
+
+parser/error_recovery/reserved_words_top_level_fields:146:5: The return type can't be 'var'.
+int var(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:148:10: Expected an identifier, but got 'var'.
+  return var(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:148:10: Expected ';' after this.
+  return var(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_fields:148:13: Expected an identifier, but got '('.
+  return var(x-1) + 1;
+            ^
+
+parser/error_recovery/reserved_words_top_level_fields:148:14: Expected ';' after this.
+  return var(x-1) + 1;
+             ^
+
+parser/error_recovery/reserved_words_top_level_fields:148:16: Expected ';' after this.
+  return var(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_top_level_fields:148:17: Expected an identifier, but got ')'.
+  return var(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:148:17: Expected ';' after this.
+  return var(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:148:17: Unexpected token ';'.
+  return var(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:148:19: '+' is not a prefix operator.
+  return var(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_fields:151:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int void(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:151:1: Expected ';' after this.
+int void(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:151:9: Expected an identifier, but got '('.
+int void(int x) {
+        ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:10: Expected an identifier, but got 'void'.
+  return void(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:153:10: Expected ';' after this.
+  return void(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:153:14: Expected an identifier, but got '('.
+  return void(x-1) + 1;
+             ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:15: Expected ';' after this.
+  return void(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:17: Expected ';' after this.
+  return void(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:18: Expected an identifier, but got ')'.
+  return void(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:18: Expected ';' after this.
+  return void(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:18: Unexpected token ';'.
+  return void(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_fields:153:20: '+' is not a prefix operator.
+  return void(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_top_level_fields:156:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int while(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:156:1: Expected ';' after this.
+int while(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:156:5: Expected an identifier, but got 'while'.
+int while(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:158:10: Expected an identifier, but got 'while'.
+  return while(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:158:10: Expected ';' after this.
+  return while(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:158:21: '+' is not a prefix operator.
+  return while(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_top_level_fields:161:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int with(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:161:1: Expected ';' after this.
+int with(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_fields:161:5: Expected an identifier, but got 'with'.
+int with(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_fields:163:10: Expected an identifier, but got 'with'.
+  return with(x-1) + 1;
+         ^^^^
+
+beginCompilationUnit(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    handleRecoverableError(MissingConstFinalVarOrType, int, int)
+    handleNoType()
+    handleIdentifier(int, topLevelVariableDeclaration)
+    handleNoFieldInitializer(assert)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+  endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(assert)
+beginMetadataStar(assert)
+endMetadataStar(0)
+beginTopLevelMember(assert)
+  beginTopLevelMethod(;, null)
+    handleNoType(;)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'assert'., null, {token: assert}], assert, assert)
+    handleIdentifier(assert, topLevelFunctionDeclaration)
+    handleNoTypeVariables(()
+    beginFormalParameters((, MemberKind.TopLevelMethod)
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(x)
+        handleType(int, null)
+        handleIdentifier(x, formalParameterDeclaration)
+        handleFormalParameterWithoutValue())
+      endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+    endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+    handleAsyncModifier(null, null)
+    beginBlockFunctionBody({)
+      beginIfStatement(if)
+        handleIdentifier(x, expression)
+        handleNoTypeArguments(==)
+        handleNoArguments(==)
+        handleSend(x, ==)
+        beginBinaryExpression(==)
+        handleLiteralInt(0)
+        endBinaryExpression(==)
+        handleParenthesizedCondition(()
+        beginThenStatement(return)
+          beginReturnStatement(return)
+            handleLiteralInt(42)
+          endReturnStatement(true, return, ;)
+        endThenStatement(;)
+      endIfStatement(if, null)
+      beginReturnStatement(return)
+        beginAssert(assert, Assert.Expression)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(-)
+          handleNoArguments(-)
+          handleSend(x, -)
+          beginBinaryExpression(-)
+          handleLiteralInt(1)
+          endBinaryExpression(-)
+          handleRecoverableError(AssertAsExpression, assert, assert)
+        endAssert(assert, Assert.Expression, (, null, +)
+        beginBinaryExpression(+)
+        handleLiteralInt(1)
+        endBinaryExpression(+)
+      endReturnStatement(true, return, ;)
+    endBlockFunctionBody(2, {, })
+  endTopLevelMethod(assert, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+  handleRecoverableError(MissingConstFinalVarOrType, int, int)
+  handleNoType(})
+  handleIdentifier(int, topLevelVariableDeclaration)
+  handleNoFieldInitializer(break)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(break)
+beginMetadataStar(break)
+endMetadataStar(0)
+beginTopLevelMember(break)
+beginTopLevelMethod(;, null)
+  handleNoType(;)
+  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+  handleIdentifier(break, topLevelFunctionDeclaration)
+  handleNoTypeVariables(()
+  beginFormalParameters((, MemberKind.TopLevelMethod)
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(x)
+      handleType(int, null)
+      handleIdentifier(x, formalParameterDeclaration)
+      handleFormalParameterWithoutValue())
+    endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+  endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+  handleAsyncModifier(null, null)
+  beginBlockFunctionBody({)
+    beginIfStatement(if)
+      handleIdentifier(x, expression)
+      handleNoTypeArguments(==)
+      handleNoArguments(==)
+      handleSend(x, ==)
+      beginBinaryExpression(==)
+      handleLiteralInt(0)
+      endBinaryExpression(==)
+      handleParenthesizedCondition(()
+      beginThenStatement(return)
+        beginReturnStatement(return)
+          handleLiteralInt(42)
+        endReturnStatement(true, return, ;)
+      endThenStatement(;)
+    endIfStatement(if, null)
+    beginReturnStatement(return)
+      handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+      handleIdentifier(, expression)
+      handleNoTypeArguments(break)
+      handleNoArguments(break)
+      handleSend(, break)
+      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+    endReturnStatement(true, return, ;)
+    handleRecoverableError(BreakOutsideOfLoop, break, break)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+    handleBreakStatement(false, break, ;)
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(-)
+    handleNoArguments(-)
+    handleSend(x, -)
+    beginBinaryExpression(-)
+    handleLiteralInt(1)
+    endBinaryExpression(-)
+    handleParenthesizedExpression(()
+    beginBinaryExpression(+)
+    handleLiteralInt(1)
+    endBinaryExpression(+)
+    handleExpressionStatement(;)
+  endBlockFunctionBody(4, {, })
+endTopLevelMethod(break, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(case)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(case)
+beginMetadataStar(case)
+endMetadataStar(0)
+beginTopLevelMember(case)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+handleIdentifier(case, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+    handleIdentifier(int, typeReference)
+    handleNoTypeArguments(x)
+    handleType(int, null)
+    handleIdentifier(x, formalParameterDeclaration)
+    handleFormalParameterWithoutValue())
+  endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+  beginIfStatement(if)
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(==)
+    handleNoArguments(==)
+    handleSend(x, ==)
+    beginBinaryExpression(==)
+    handleLiteralInt(0)
+    endBinaryExpression(==)
+    handleParenthesizedCondition(()
+    beginThenStatement(return)
+      beginReturnStatement(return)
+        handleLiteralInt(42)
+      endReturnStatement(true, return, ;)
+    endThenStatement(;)
+  endIfStatement(if, null)
+  beginReturnStatement(return)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+    handleIdentifier(case, expression)
+    handleNoTypeArguments(()
+    beginArguments(()
+      handleIdentifier(x, expression)
+      handleNoTypeArguments(-)
+      handleNoArguments(-)
+      handleSend(x, -)
+      beginBinaryExpression(-)
+      handleLiteralInt(1)
+      endBinaryExpression(-)
+    endArguments(1, (, ))
+    handleSend(case, +)
+    beginBinaryExpression(+)
+    handleLiteralInt(1)
+    endBinaryExpression(+)
+  endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(case, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(catch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(catch)
+beginMetadataStar(catch)
+endMetadataStar(0)
+beginTopLevelMember(catch)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+handleIdentifier(catch, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+  handleIdentifier(int, typeReference)
+  handleNoTypeArguments(x)
+  handleType(int, null)
+  handleIdentifier(x, formalParameterDeclaration)
+  handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+  handleIdentifier(x, expression)
+  handleNoTypeArguments(==)
+  handleNoArguments(==)
+  handleSend(x, ==)
+  beginBinaryExpression(==)
+  handleLiteralInt(0)
+  endBinaryExpression(==)
+  handleParenthesizedCondition(()
+  beginThenStatement(return)
+    beginReturnStatement(return)
+      handleLiteralInt(42)
+    endReturnStatement(true, return, ;)
+  endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+  handleIdentifier(catch, expression)
+  handleNoTypeArguments(()
+  beginArguments(()
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(-)
+    handleNoArguments(-)
+    handleSend(x, -)
+    beginBinaryExpression(-)
+    handleLiteralInt(1)
+    endBinaryExpression(-)
+  endArguments(1, (, ))
+  handleSend(catch, +)
+  beginBinaryExpression(+)
+  handleLiteralInt(1)
+  endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(catch, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(class)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(class)
+beginMetadataStar(class)
+endMetadataStar(0)
+beginClassOrNamedMixinApplicationPrelude(class)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, classOrMixinDeclaration)
+handleNoTypeVariables(int)
+beginClassDeclaration(class, null, )
+handleNoType()
+handleClassExtends(null)
+handleClassNoWithClause()
+handleClassOrMixinImplements(null, 0)
+handleClassHeader(class, class, null)
+handleNoType()
+handleClassExtends(null)
+handleClassNoWithClause()
+handleClassOrMixinImplements(null, 0)
+handleRecoverClassHeader()
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A class declaration must have a body, even if it is empty., Try adding an empty body., {string: class declaration}], int, int)
+beginClassOrMixinBody(DeclarationKind.Class, {)
+endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, topLevelVariableDeclaration)
+handleNoFieldInitializer())
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration())
+beginMetadataStar())
+endMetadataStar(0)
+beginTopLevelMember())
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+handleInvalidTopLevelDeclaration())
+endTopLevelDeclaration({)
+beginMetadataStar({)
+endMetadataStar(0)
+beginTopLevelMember({)
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+beginBlock({, BlockKind(invalid))
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(class, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(class, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlock(2, {, }, BlockKind(invalid))
+handleInvalidTopLevelBlock({)
+handleInvalidTopLevelDeclaration(})
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(const)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(const)
+beginMetadataStar(const)
+endMetadataStar(0)
+beginTopLevelMember(const)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'const' here., Try removing 'const'., {token: const}], const, const)
+beginTopLevelMethod(;, null)
+handleNoType(const)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+beginConstExpression(const)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, constructorReference)
+beginConstructorReference()
+handleNoTypeArguments(()
+handleNoConstructorReferenceContinuationAfterTypeArguments(()
+endConstructorReference(, null, ()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+endConstExpression(const)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(const, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(continue)
+beginMetadataStar(continue)
+endMetadataStar(0)
+beginTopLevelMember(continue)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+handleIdentifier(continue, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+handleIdentifier(, expression)
+handleNoTypeArguments(continue)
+handleNoArguments(continue)
+handleSend(, continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+endReturnStatement(true, return, ;)
+handleRecoverableError(ContinueOutsideOfLoop, continue, continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+handleContinueStatement(false, continue, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(continue, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(default)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(default)
+beginMetadataStar(default)
+endMetadataStar(0)
+beginTopLevelMember(default)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+handleIdentifier(default, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+handleIdentifier(default, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(default, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(default, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(do)
+beginMetadataStar(do)
+endMetadataStar(0)
+beginTopLevelMember(do)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+handleIdentifier(do, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+handleIdentifier(, expression)
+handleNoTypeArguments(do)
+handleNoArguments(do)
+handleSend(, do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], do, do)
+endReturnStatement(true, return, ;)
+beginDoWhileStatement(do)
+beginDoWhileStatementBody(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endDoWhileStatementBody(;)
+handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
+handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '}'., null, {token: }}], }, })
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleParenthesizedCondition(()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+endDoWhileStatement(do, while, ;)
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(do, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(else)
+beginMetadataStar(else)
+endMetadataStar(0)
+beginTopLevelMember(else)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(else, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(, expression)
+handleNoTypeArguments(else)
+handleNoArguments(else)
+handleSend(, else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+endReturnStatement(true, return, ;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(, expression)
+handleNoTypeArguments(else)
+handleNoArguments(else)
+handleSend(, else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], else, else)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(else, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(enum)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(enum)
+beginMetadataStar(enum)
+endMetadataStar(0)
+beginEnum(enum)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, enumDeclaration)
+handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {token: int}], int, int)
+endEnum(enum, {, 0)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, topLevelVariableDeclaration)
+handleNoFieldInitializer())
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration())
+beginMetadataStar())
+endMetadataStar(0)
+beginTopLevelMember())
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+handleInvalidTopLevelDeclaration())
+endTopLevelDeclaration({)
+beginMetadataStar({)
+endMetadataStar(0)
+beginTopLevelMember({)
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+beginBlock({, BlockKind(invalid))
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(enum, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(enum, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlock(2, {, }, BlockKind(invalid))
+handleInvalidTopLevelBlock({)
+handleInvalidTopLevelDeclaration(})
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(extends)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(extends)
+beginMetadataStar(extends)
+endMetadataStar(0)
+beginTopLevelMember(extends)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+handleIdentifier(extends, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+handleIdentifier(extends, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(extends, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(extends, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(false)
+beginMetadataStar(false)
+endMetadataStar(0)
+beginTopLevelMember(false)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'false'., null, {token: false}], false, false)
+handleIdentifier(false, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralBool(false)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(false, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(final)
+beginMetadataStar(final)
+endMetadataStar(0)
+beginTopLevelMember(final)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+beginTopLevelMethod(;, null)
+handleNoType(final)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'final'., null, {token: final}], final, final)
+handleIdentifier(, expression)
+handleNoTypeArguments(final)
+handleNoArguments(final)
+handleSend(, final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], final, final)
+endReturnStatement(true, return, ;)
+beginMetadataStar(final)
+endMetadataStar(0)
+handleNoType(final)
+beginVariablesDeclaration((, null, final)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endTopLevelMethod(final, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(finally)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(finally)
+beginMetadataStar(finally)
+endMetadataStar(0)
+beginTopLevelMember(finally)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+handleIdentifier(finally, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+handleIdentifier(finally, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(finally, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(finally, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(for)
+beginMetadataStar(for)
+endMetadataStar(0)
+beginTopLevelMember(for)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+handleIdentifier(for, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+handleIdentifier(, expression)
+handleNoTypeArguments(for)
+handleNoArguments(for)
+handleSend(, for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], for, for)
+endReturnStatement(true, return, ;)
+beginForStatement(for)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleForInitializerExpressionStatement(1, false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleForLoopParts(for, (, ;, 0)
+beginForStatementBody(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endForStatementBody(})
+endForStatement(})
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(for, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(if)
+beginMetadataStar(if)
+endMetadataStar(0)
+beginTopLevelMember(if)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+handleIdentifier(if, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+handleIdentifier(, expression)
+handleNoTypeArguments(if)
+handleNoArguments(if)
+handleSend(, if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], if, if)
+endReturnStatement(true, return, ;)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+beginThenStatement(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endThenStatement(;)
+endIfStatement(if, null)
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(if, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(in)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(in)
+beginMetadataStar(in)
+endMetadataStar(0)
+beginTopLevelMember(in)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+handleIdentifier(in, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+handleIdentifier(in, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(in, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(in, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(is)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(is)
+beginMetadataStar(is)
+endMetadataStar(0)
+beginTopLevelMember(is)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+handleIdentifier(is, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+handleIdentifier(, expression)
+handleNoTypeArguments(is)
+handleNoArguments(is)
+handleSend(, is)
+beginIsOperatorType(is)
+handleRecoverableError(Message[ExpectedType, Expected a type, but got '('., null, {token: (}], (, ()
+handleIdentifier(, typeReference)
+handleNoTypeArguments(()
+handleType(, null)
+endIsOperatorType(is)
+handleIsOperator(is, null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
+endReturnStatement(true, return, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(is, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(new)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(new)
+beginMetadataStar(new)
+endMetadataStar(0)
+beginTopLevelMember(new)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'new'., null, {token: new}], new, new)
+handleIdentifier(new, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+beginNewExpression(new)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, constructorReference)
+beginConstructorReference()
+handleNoTypeArguments(()
+handleNoConstructorReferenceContinuationAfterTypeArguments(()
+endConstructorReference(, null, ()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+endNewExpression(new)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(new, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(null)
+beginMetadataStar(null)
+endMetadataStar(0)
+beginTopLevelMember(null)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'null'., null, {token: null}], null, null)
+handleIdentifier(null, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralNull(null)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(null, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(rethrow)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(rethrow)
+beginMetadataStar(rethrow)
+endMetadataStar(0)
+beginTopLevelMember(rethrow)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleIdentifier(rethrow, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleIdentifier(rethrow, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(rethrow, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(rethrow, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(return)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(return)
+beginMetadataStar(return)
+endMetadataStar(0)
+beginTopLevelMember(return)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'return'., null, {token: return}], return, return)
+handleIdentifier(return, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {token: return}], return, return)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(return, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(super)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(super)
+beginMetadataStar(super)
+endMetadataStar(0)
+beginTopLevelMember(super)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'super'., null, {token: super}], super, super)
+handleIdentifier(super, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleSuperExpression(super, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(super, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(super, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(switch)
+beginMetadataStar(switch)
+endMetadataStar(0)
+beginTopLevelMember(switch)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+handleIdentifier(switch, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+handleIdentifier(, expression)
+handleNoTypeArguments(switch)
+handleNoArguments(switch)
+handleSend(, switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], switch, switch)
+endReturnStatement(true, return, ;)
+beginSwitchStatement(switch)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
+beginSwitchBlock({)
+endSwitchBlock(0, {, })
+endSwitchStatement(switch, })
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(switch, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+beginTopLevelMethod(}, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(this)
+handleType(int, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+handleIdentifier(this, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleThisExpression(this, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(this, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(int, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(throw)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(throw)
+beginMetadataStar(throw)
+endMetadataStar(0)
+beginTopLevelMember(throw)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'throw'., null, {token: throw}], throw, throw)
+handleIdentifier(throw, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleThrowExpression(throw, ;)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(throw, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(true)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(true)
+beginMetadataStar(true)
+endMetadataStar(0)
+beginTopLevelMember(true)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'true'., null, {token: true}], true, true)
+handleIdentifier(true, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralBool(true)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(true, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(try)
+beginMetadataStar(try)
+endMetadataStar(0)
+beginTopLevelMember(try)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+handleIdentifier(try, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+handleIdentifier(, expression)
+handleNoTypeArguments(try)
+handleNoArguments(try)
+handleSend(, try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], try, try)
+endReturnStatement(true, return, ;)
+beginTryStatement(try)
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}], try, try)
+beginBlock({, BlockKind(try statement))
+endBlock(0, {, }, BlockKind(try statement))
+handleRecoverableError(OnlyTry, try, try)
+endTryStatement(0, try, null)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(try, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(var)
+beginMetadataStar(var)
+endMetadataStar(0)
+beginTopLevelMember(var)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleRecoverableError(VarReturnType, var, var)
+beginTopLevelMethod(;, null)
+handleNoType(var)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'var'., null, {token: var}], var, var)
+handleIdentifier(, expression)
+handleNoTypeArguments(var)
+handleNoArguments(var)
+handleSend(, var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], var, var)
+endReturnStatement(true, return, ;)
+beginMetadataStar(var)
+endMetadataStar(0)
+handleNoType(var)
+beginVariablesDeclaration((, null, var)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endTopLevelMethod(var, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(void)
+beginMetadataStar(void)
+endMetadataStar(0)
+beginTopLevelMember(void)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+beginTopLevelMethod(;, null)
+handleVoidKeyword(void)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'void'., null, {token: void}], void, void)
+handleIdentifier(, expression)
+handleNoTypeArguments(void)
+handleNoArguments(void)
+handleSend(, void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
+endReturnStatement(true, return, ;)
+beginMetadataStar(void)
+endMetadataStar(0)
+handleVoidKeyword(void)
+beginVariablesDeclaration((, null, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endTopLevelMethod(void, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(while)
+beginMetadataStar(while)
+endMetadataStar(0)
+beginTopLevelMember(while)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+handleIdentifier(while, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+handleIdentifier(, expression)
+handleNoTypeArguments(while)
+handleNoArguments(while)
+handleSend(, while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], while, while)
+endReturnStatement(true, return, ;)
+beginWhileStatement(while)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+beginWhileStatementBody(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endWhileStatementBody(})
+endWhileStatement(while, })
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(while, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(with)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(with)
+beginMetadataStar(with)
+endMetadataStar(0)
+beginTopLevelMember(with)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(with, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(with, null, })
+endTopLevelDeclaration()
+endCompilationUnit(71, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.intertwined.expect
new file mode 100644
index 0000000..90e26b1
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.intertwined.expect
@@ -0,0 +1,5902 @@
+parseUnit(int)
+  skipErrorTokens(int)
+  listener: beginCompilationUnit(int)
+  syntheticPreviousToken(int)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(int)
+      parseFields(, null, null, null, null, null, , Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(assert)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(assert)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(assert)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(assert)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, assert)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(assert, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'assert'., null, {token: assert}], assert, assert)
+          listener: handleIdentifier(assert, topLevelFunctionDeclaration)
+        parseMethodTypeVar(assert)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(assert, assert, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(assert, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseAssert(return, Assert.Expression)
+                          listener: beginAssert(assert, Assert.Expression)
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          reportRecoverableError(assert, AssertAsExpression)
+                            listener: handleRecoverableError(AssertAsExpression, assert, assert)
+                          listener: endAssert(assert, Assert.Expression, (, null, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(assert, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(break)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(break)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(break)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(break)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, break)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+          listener: handleIdentifier(break, topLevelFunctionDeclaration)
+        parseMethodTypeVar(break)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(break, break, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(break, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(break)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(break)
+                          listener: handleSend(, break)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, break)
+          parseStatement(;)
+            parseStatementX(;)
+              parseBreakStatement(;)
+                isBreakAllowed()
+                reportRecoverableError(break, BreakOutsideOfLoop)
+                  listener: handleRecoverableError(BreakOutsideOfLoop, break, break)
+                ensureSemicolon(break)
+                  reportRecoverableError(break, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+                  rewriter()
+                listener: handleBreakStatement(false, break, ;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(break, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(case)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(case)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(case)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(case)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, case)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+          listener: handleIdentifier(case, topLevelFunctionDeclaration)
+        parseMethodTypeVar(case)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(case, case, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(case, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+                            listener: handleIdentifier(case, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(case)
+                            parseArguments(case)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(case, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(case, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(catch)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(catch)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(catch)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(catch)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, catch)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+          listener: handleIdentifier(catch, topLevelFunctionDeclaration)
+        parseMethodTypeVar(catch)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(catch, catch, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(catch, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+                            listener: handleIdentifier(catch, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(catch)
+                            parseArguments(catch)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(catch, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(catch, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(class)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(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)
+          reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+          rewriter()
+          listener: handleIdentifier(, classOrMixinDeclaration)
+        listener: handleNoTypeVariables(int)
+        listener: beginClassDeclaration(class, null, )
+        parseClass(, class, class, )
+          parseClassHeaderOpt(, class, class)
+            parseClassExtendsOpt()
+              listener: handleNoType()
+              listener: handleClassExtends(null)
+            parseWithClauseOpt()
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt()
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassHeaderRecovery(, class, class)
+            parseClassHeaderOpt(, class, class)
+              parseClassExtendsOpt()
+              parseWithClauseOpt()
+              parseClassOrMixinImplementsOpt()
+            skipUnexpectedTokenOpt(, [extends, with, implements, {])
+            parseClassExtendsOpt()
+              listener: handleNoType()
+              listener: handleClassExtends(null)
+            parseWithClauseOpt()
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt()
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleRecoverClassHeader()
+          ensureBlock(, null, class declaration)
+            reportRecoverableError(, Message[ExpectedClassOrMixinBody, A class declaration must have a body, even if it is empty., Try adding an empty body., {string: class declaration}])
+              listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A class declaration must have a body, even if it is empty., Try adding an empty body., {string: class declaration}], int, int)
+            insertBlock()
+              rewriter()
+              rewriter()
+          parseClassOrMixinOrExtensionBody(, DeclarationKind.Class, )
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(x)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(x, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer())
+        ensureSemicolon(x)
+          reportRecoverableError(x, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration())
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar())
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember())
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+      listener: handleInvalidTopLevelDeclaration())
+  listener: endTopLevelDeclaration({)
+  parseTopLevelDeclarationImpl(), Instance of 'DirectiveContext')
+    parseMetadataStar())
+      listener: beginMetadataStar({)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember({)
+    parseInvalidTopLevelDeclaration())
+      reportRecoverableErrorWithToken({, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+      parseInvalidBlock())
+        parseBlock(), BlockKind(invalid))
+          ensureBlock(), null, null)
+          listener: beginBlock({, BlockKind(invalid))
+          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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(class, Instance of 'Template<(Token) => Message>')
+                            listener: handleIdentifier(class, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(class)
+                            parseArguments(class)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(class, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlock(2, {, }, BlockKind(invalid))
+        listener: handleInvalidTopLevelBlock({)
+      listener: handleInvalidTopLevelDeclaration(})
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(const)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(const)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(const)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(const)
+      insertSyntheticIdentifier(const, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      reportRecoverableErrorWithToken(const, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'const' here., Try removing 'const'., {token: const}], const, const)
+      parseTopLevelMethod(;, null, const, Instance of 'NoType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(const)
+        ensureIdentifier(const, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseConstExpression(return)
+                          listener: beginConstExpression(const)
+                          parseConstructorReference(const, null)
+                            ensureIdentifier(const, constructorReference)
+                              insertSyntheticIdentifier(const, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], messageOnToken: null)
+                                reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                              listener: handleIdentifier(, constructorReference)
+                            listener: beginConstructorReference()
+                            parseQualifiedRestOpt(, constructorReferenceContinuation)
+                            listener: handleNoTypeArguments(()
+                            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                            listener: endConstructorReference(, null, ()
+                          parseConstructorInvocationArguments()
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: endConstExpression(const)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(const, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(continue)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(continue)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(continue)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(continue)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, continue)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+          listener: handleIdentifier(continue, topLevelFunctionDeclaration)
+        parseMethodTypeVar(continue)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(continue, continue, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(continue, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(continue)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(continue)
+                          listener: handleSend(, continue)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, continue)
+          parseStatement(;)
+            parseStatementX(;)
+              parseContinueStatement(;)
+                isContinueAllowed()
+                reportRecoverableError(continue, ContinueOutsideOfLoop)
+                  listener: handleRecoverableError(ContinueOutsideOfLoop, continue, continue)
+                ensureSemicolon(continue)
+                  reportRecoverableError(continue, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+                  rewriter()
+                listener: handleContinueStatement(false, continue, ;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(continue, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(default)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(default)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(default)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(default)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, default)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+          listener: handleIdentifier(default, topLevelFunctionDeclaration)
+        parseMethodTypeVar(default)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(default, default, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(default, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+                            listener: handleIdentifier(default, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(default)
+                            parseArguments(default)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(default, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(default, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(do)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(do)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(do)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(do)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, do)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+          listener: handleIdentifier(do, topLevelFunctionDeclaration)
+        parseMethodTypeVar(do)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(do, do, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(do, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(do)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(do)
+                          listener: handleSend(, do)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], do, do)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, do)
+          parseStatement(;)
+            parseStatementX(;)
+              parseDoWhileStatement(;)
+                listener: beginDoWhileStatement(do)
+                listener: beginDoWhileStatementBody(()
+                parseStatement(do)
+                  parseStatementX(do)
+                    parseExpressionStatementOrDeclaration(do, false)
+                      parseExpressionStatementOrDeclarationAfterModifiers(do, do, null, null, null, false)
+                        looksLikeLocalFunction(()
+                        parseExpressionStatement(do)
+                          parseExpression(do)
+                            parsePrecedenceExpression(do, 1, true)
+                              parseUnaryExpression(do, true)
+                                parsePrimary(do, expression)
+                                  parseParenthesizedExpressionOrFunctionLiteral(do)
+                                    parseParenthesizedExpression(do)
+                                      parseExpressionInParenthesis(do)
+                                        parseExpressionInParenthesisRest(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          ensureCloseParen(1, ()
+                                      listener: handleParenthesizedExpression(()
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: handleExpressionStatement(;)
+                listener: endDoWhileStatementBody(;)
+                reportRecoverableError(}, Message[ExpectedButGot, Expected 'while' before this., null, {string: while}])
+                  listener: handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
+                rewriter()
+                ensureParenthesizedCondition(while)
+                  reportRecoverableError(}, Message[ExpectedToken, Expected to find '('., null, {string: (}])
+                    listener: handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
+                  rewriter()
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSend((, expression)
+                              ensureIdentifier((, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '}'., null, {token: }}], }, })
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureCloseParen(, ()
+                  listener: handleParenthesizedCondition(()
+                ensureSemicolon())
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                  rewriter()
+                listener: endDoWhileStatement(do, while, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(do, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(else)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(else)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(else)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(else)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, else)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+          listener: handleIdentifier(else, topLevelFunctionDeclaration)
+        parseMethodTypeVar(else)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(else, else, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(else, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(else)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(else)
+                          listener: handleSend(, else)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, else)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(else)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            inPlainSync()
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments(else)
+                              parseArgumentsOpt()
+                                listener: handleNoArguments(else)
+                              listener: handleSend(, else)
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], else, else)
+          notEofOrValue(}, ()
+          parseStatement(else)
+            parseStatementX(else)
+              parseExpressionStatementOrDeclaration(else, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(else, else, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(else)
+                    parseExpression(else)
+                      parsePrecedenceExpression(else, 1, true)
+                        parseUnaryExpression(else, true)
+                          parsePrimary(else, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(else)
+                              parseParenthesizedExpression(else)
+                                parseExpressionInParenthesis(else)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(else, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(enum)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, enum, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, enum)
+      parseEnum(enum)
+        listener: beginEnum(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+          rewriter()
+          listener: handleIdentifier(, enumDeclaration)
+        ensureBlock(, Instance of 'Template<(Token) => Message>', null)
+          reportRecoverableError(int, Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {token: int}])
+            listener: handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {token: int}], int, int)
+          insertBlock()
+            rewriter()
+            rewriter()
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(x)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(x, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer())
+        ensureSemicolon(x)
+          reportRecoverableError(x, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration())
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar())
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember())
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+      listener: handleInvalidTopLevelDeclaration())
+  listener: endTopLevelDeclaration({)
+  parseTopLevelDeclarationImpl(), Instance of 'DirectiveContext')
+    parseMetadataStar())
+      listener: beginMetadataStar({)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember({)
+    parseInvalidTopLevelDeclaration())
+      reportRecoverableErrorWithToken({, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+      parseInvalidBlock())
+        parseBlock(), BlockKind(invalid))
+          ensureBlock(), null, null)
+          listener: beginBlock({, BlockKind(invalid))
+          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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                            listener: handleIdentifier(enum, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(enum)
+                            parseArguments(enum)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(enum, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlock(2, {, }, BlockKind(invalid))
+        listener: handleInvalidTopLevelBlock({)
+      listener: handleInvalidTopLevelDeclaration(})
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(extends)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(extends)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(extends)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(extends)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, extends)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+          listener: handleIdentifier(extends, topLevelFunctionDeclaration)
+        parseMethodTypeVar(extends)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(extends, extends, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(extends, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+                            listener: handleIdentifier(extends, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(extends)
+                            parseArguments(extends)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(extends, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(extends, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(false)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(false)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(false)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(false)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, false)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(false, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'false'., null, {token: false}], false, false)
+          listener: handleIdentifier(false, topLevelFunctionDeclaration)
+        parseMethodTypeVar(false)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(false, false, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(false, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseLiteralBool(return)
+                          listener: handleLiteralBool(false)
+                    parseArgumentOrIndexStar(false, Instance of 'NoTypeParamOrArg', false)
+                      listener: handleNoTypeArguments(()
+                      parseArguments(false)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          listener: endArguments(1, (, ))
+                      listener: handleSend((, ))
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(false, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(final)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(final)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(final)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(final)
+      insertSyntheticIdentifier(final, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+      parseTopLevelMethod(;, null, final, Instance of 'NoType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(final)
+        ensureIdentifier(final, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'final'., null, {token: final}], final, final)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(final)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(final)
+                          listener: handleSend(, final)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], final, final)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, final)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(final, ;, null, final, null, false)
+                looksLikeLocalFunction(()
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+                listener: handleNoType(final)
+                listener: beginVariablesDeclaration((, null, final)
+                parseVariablesDeclarationRest(final, true)
+                  parseOptionallyInitializedIdentifier(final)
+                    ensureIdentifier(final, localVariableDeclaration)
+                      reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                      listener: handleIdentifier(, localVariableDeclaration)
+                    listener: beginInitializedIdentifier()
+                    parseVariableInitializerOpt()
+                      listener: handleNoVariableInitializer(x)
+                    listener: endInitializedIdentifier()
+                  ensureSemicolon()
+                    reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                    rewriter()
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, x)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(x)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  ensureSemicolon(1)
+                    reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                    rewriter()
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, ))
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction())
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+          notEofOrValue(}, +)
+          parseStatement())
+            parseStatementX())
+              parseExpressionStatementOrDeclaration(), false)
+                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement())
+                    parseExpression())
+                      parsePrecedenceExpression(), 1, true)
+                        parseUnaryExpression(), true)
+                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(), expression)
+                            parseSendOrFunctionLiteral(), expression)
+                              parseSend(), expression)
+                                ensureIdentifier(), expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(final, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(finally)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(finally)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(finally)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(finally)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, finally)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+          listener: handleIdentifier(finally, topLevelFunctionDeclaration)
+        parseMethodTypeVar(finally)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(finally, finally, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(finally, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+                            listener: handleIdentifier(finally, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(finally)
+                            parseArguments(finally)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(finally, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(finally, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(for)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(for)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(for)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(for)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, for)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+          listener: handleIdentifier(for, topLevelFunctionDeclaration)
+        parseMethodTypeVar(for)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(for, for, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(for, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(for)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(for)
+                          listener: handleSend(, for)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], for, for)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, for)
+          parseStatement(;)
+            parseStatementX(;)
+              parseForStatement(;, null)
+                listener: beginForStatement(for)
+                parseForLoopPartsStart(null, for)
+                  parseExpressionStatementOrDeclaration((, true)
+                    parseExpressionStatementOrDeclarationAfterModifiers((, (, null, null, null, true)
+                parseForLoopPartsMid((, null, for)
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseSendOrFunctionLiteral((, expression)
+                            parseSend((, expression)
+                              ensureIdentifier((, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  listener: handleForInitializerExpressionStatement(1, false)
+                parseForRest(null, 1, for)
+                  parseForLoopPartsRest(1, for, null)
+                    ensureSemicolon(1)
+                      reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                      rewriter()
+                    parseExpressionStatement(;)
+                      parseExpression(;)
+                        parsePrecedenceExpression(;, 1, true)
+                          parseUnaryExpression(;, true)
+                            parsePrimary(;, expression)
+                              parseSend(;, expression)
+                                ensureIdentifier(;, expression)
+                                  reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                    listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                  rewriter()
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments())
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments())
+                                listener: handleSend(, ))
+                      ensureSemicolon()
+                        reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                          listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                        rewriter()
+                      listener: handleExpressionStatement(;)
+                    listener: handleForLoopParts(for, (, ;, 0)
+                  listener: beginForStatementBody(+)
+                  parseStatement())
+                    parseStatementX())
+                      parseExpressionStatementOrDeclaration(), false)
+                        parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                          looksLikeLocalFunction(+)
+                          parseExpressionStatement())
+                            parseExpression())
+                              parsePrecedenceExpression(), 1, true)
+                                parseUnaryExpression(), true)
+                                  rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                    reportRecoverableError(+, UnsupportedPrefixPlus)
+                                      listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                    rewriter()
+                                  parsePrimary(), expression)
+                                    parseSendOrFunctionLiteral(), expression)
+                                      parseSend(), expression)
+                                        ensureIdentifier(), expression)
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments(+)
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments(+)
+                                        listener: handleSend(, +)
+                                listener: beginBinaryExpression(+)
+                                parsePrecedenceExpression(+, 14, true)
+                                  parseUnaryExpression(+, true)
+                                    parsePrimary(+, expression)
+                                      parseLiteralInt(+)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(+)
+                            ensureSemicolon(1)
+                            listener: handleExpressionStatement(;)
+                  listener: endForStatementBody(})
+                  listener: endForStatement(})
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(for, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(if)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(if)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(if)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(if)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, if)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+          listener: handleIdentifier(if, topLevelFunctionDeclaration)
+        parseMethodTypeVar(if)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(if, if, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(if, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(if)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(if)
+                          listener: handleSend(, if)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], if, if)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          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(x, expression)
+                                listener: handleNoTypeArguments(-)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(-)
+                                listener: handleSend(x, -)
+                        listener: beginBinaryExpression(-)
+                        parsePrecedenceExpression(-, 14, true)
+                          parseUnaryExpression(-, true)
+                            parsePrimary(-, expression)
+                              parseLiteralInt(-)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(-)
+                    ensureCloseParen(1, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(+)
+                parseStatement())
+                  parseStatementX())
+                    parseExpressionStatementOrDeclaration(), false)
+                      parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                        looksLikeLocalFunction(+)
+                        parseExpressionStatement())
+                          parseExpression())
+                            parsePrecedenceExpression(), 1, true)
+                              parseUnaryExpression(), true)
+                                rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                  reportRecoverableError(+, UnsupportedPrefixPlus)
+                                    listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                  rewriter()
+                                parsePrimary(), expression)
+                                  parseSendOrFunctionLiteral(), expression)
+                                    parseSend(), expression)
+                                      ensureIdentifier(), expression)
+                                        listener: handleIdentifier(, expression)
+                                      listener: handleNoTypeArguments(+)
+                                      parseArgumentsOpt()
+                                        listener: handleNoArguments(+)
+                                      listener: handleSend(, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: handleExpressionStatement(;)
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(if, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(in)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(in)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(in)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(in)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, in)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+          listener: handleIdentifier(in, topLevelFunctionDeclaration)
+        parseMethodTypeVar(in)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(in, in, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(in, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+                            listener: handleIdentifier(in, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(in)
+                            parseArguments(in)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(in, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(in, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(is)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(is)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(is)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(is)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, is)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+          listener: handleIdentifier(is, topLevelFunctionDeclaration)
+        parseMethodTypeVar(is)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(is, is, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(is, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(is)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(is)
+                          listener: handleSend(, is)
+                    parseIsOperatorRest()
+                      listener: beginIsOperatorType(is)
+                      computeTypeAfterIsOrAs(is)
+                      reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                      listener: handleIdentifier(, typeReference)
+                      listener: handleNoTypeArguments(()
+                      listener: handleType(, null)
+                      listener: endIsOperatorType(is)
+                      listener: handleIsOperator(is, null)
+                      skipChainedAsIsOperators()
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(is, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(new)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(new)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(new)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(new)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, new)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(new, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'new'., null, {token: new}], new, new)
+          listener: handleIdentifier(new, topLevelFunctionDeclaration)
+        parseMethodTypeVar(new)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(new, new, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(new, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseNewExpression(return)
+                          listener: beginNewExpression(new)
+                          parseConstructorReference(new, null)
+                            ensureIdentifier(new, constructorReference)
+                              insertSyntheticIdentifier(new, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], messageOnToken: null)
+                                reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                              listener: handleIdentifier(, constructorReference)
+                            listener: beginConstructorReference()
+                            parseQualifiedRestOpt(, constructorReferenceContinuation)
+                            listener: handleNoTypeArguments(()
+                            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                            listener: endConstructorReference(, null, ()
+                          parseConstructorInvocationArguments()
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: endNewExpression(new)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(new, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(null)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(null)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(null)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(null)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, null)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(null, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'null'., null, {token: null}], null, null)
+          listener: handleIdentifier(null, topLevelFunctionDeclaration)
+        parseMethodTypeVar(null)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(null, null, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(null, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseLiteralNull(return)
+                          listener: handleLiteralNull(null)
+                    parseArgumentOrIndexStar(null, Instance of 'NoTypeParamOrArg', false)
+                      listener: handleNoTypeArguments(()
+                      parseArguments(null)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          listener: endArguments(1, (, ))
+                      listener: handleSend((, ))
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(null, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(rethrow)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(rethrow)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(rethrow)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(rethrow)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, rethrow)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+          listener: handleIdentifier(rethrow, topLevelFunctionDeclaration)
+        parseMethodTypeVar(rethrow)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(rethrow, rethrow, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(rethrow, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+                            listener: handleIdentifier(rethrow, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(rethrow)
+                            parseArguments(rethrow)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(rethrow, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(rethrow, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(return)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(return)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(return)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(return)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, return)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'return'., null, {token: return}], return, return)
+          listener: handleIdentifier(return, topLevelFunctionDeclaration)
+        parseMethodTypeVar(return)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(return, return, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(return, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+                          listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {token: return}], return, return)
+                        parsePrimary(return, expression)
+                          parseParenthesizedExpressionOrFunctionLiteral(return)
+                            parseParenthesizedExpression(return)
+                              parseExpressionInParenthesis(return)
+                                parseExpressionInParenthesisRest(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  ensureCloseParen(1, ()
+                              listener: handleParenthesizedExpression(()
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(return, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(super)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(super)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(super)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(super)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, super)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(super, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'super'., null, {token: super}], super, super)
+          listener: handleIdentifier(super, topLevelFunctionDeclaration)
+        parseMethodTypeVar(super)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(super, super, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(super, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseSuperExpression(return, expression)
+                          listener: handleSuperExpression(super, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArguments(super)
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: handleSend(super, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(super, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(switch)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(switch)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(switch)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(switch)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, switch)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+          listener: handleIdentifier(switch, topLevelFunctionDeclaration)
+        parseMethodTypeVar(switch)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(switch, switch, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(switch, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(switch)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(switch)
+                          listener: handleSend(, switch)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], switch, switch)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, switch)
+          parseStatement(;)
+            parseStatementX(;)
+              parseSwitchStatement(;)
+                listener: beginSwitchStatement(switch)
+                ensureParenthesizedCondition(switch)
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSendOrFunctionLiteral((, expression)
+                              parseSend((, expression)
+                                ensureIdentifier((, expression)
+                                  listener: handleIdentifier(x, expression)
+                                listener: handleNoTypeArguments(-)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(-)
+                                listener: handleSend(x, -)
+                        listener: beginBinaryExpression(-)
+                        parsePrecedenceExpression(-, 14, true)
+                          parseUnaryExpression(-, true)
+                            parsePrimary(-, expression)
+                              parseLiteralInt(-)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(-)
+                    ensureCloseParen(1, ()
+                  listener: handleParenthesizedCondition(()
+                parseSwitchBlock())
+                  ensureBlock(), null, switch statement)
+                    reportRecoverableError(), Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}])
+                      listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
+                    insertBlock())
+                      rewriter()
+                      rewriter()
+                  listener: beginSwitchBlock({)
+                  notEofOrValue(}, })
+                  listener: endSwitchBlock(0, {, })
+                listener: endSwitchStatement(switch, })
+          notEofOrValue(}, +)
+          parseStatement(})
+            parseStatementX(})
+              parseExpressionStatementOrDeclaration(}, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement(})
+                    parseExpression(})
+                      parsePrecedenceExpression(}, 1, true)
+                        parseUnaryExpression(}, true)
+                          rewriteAndRecover(}, UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(}, expression)
+                            parseSendOrFunctionLiteral(}, expression)
+                              parseSend(}, expression)
+                                ensureIdentifier(}, expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(switch, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, this)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(this)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(this, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+          listener: handleIdentifier(this, topLevelFunctionDeclaration)
+        parseMethodTypeVar(this)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(this, this, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(this, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseThisExpression(return, expression)
+                          listener: handleThisExpression(this, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArguments(this)
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: handleSend(this, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(throw)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(throw)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(throw)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(throw)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, throw)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(throw, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'throw'., null, {token: throw}], throw, throw)
+          listener: handleIdentifier(throw, topLevelFunctionDeclaration)
+        parseMethodTypeVar(throw)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(throw, throw, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(throw, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parseThrowExpression(return, true)
+                    parseExpression(throw)
+                      parsePrecedenceExpression(throw, 1, true)
+                        parseUnaryExpression(throw, true)
+                          parsePrimary(throw, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(throw)
+                              parseParenthesizedExpression(throw)
+                                parseExpressionInParenthesis(throw)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    listener: handleThrowExpression(throw, ;)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(throw, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(true)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(true)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(true)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(true)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, true)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(true, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'true'., null, {token: true}], true, true)
+          listener: handleIdentifier(true, topLevelFunctionDeclaration)
+        parseMethodTypeVar(true)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(true, true, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(true, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseLiteralBool(return)
+                          listener: handleLiteralBool(true)
+                    parseArgumentOrIndexStar(true, Instance of 'NoTypeParamOrArg', false)
+                      listener: handleNoTypeArguments(()
+                      parseArguments(true)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          listener: endArguments(1, (, ))
+                      listener: handleSend((, ))
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(true, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(try)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(try)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(try)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(try)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, try)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+          listener: handleIdentifier(try, topLevelFunctionDeclaration)
+        parseMethodTypeVar(try)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(try, try, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(try, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(try)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(try)
+                          listener: handleSend(, try)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], try, try)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, try)
+          parseStatement(;)
+            parseStatementX(;)
+              parseTryStatement(;)
+                listener: beginTryStatement(try)
+                parseBlock(try, BlockKind(try statement))
+                  ensureBlock(try, null, try statement)
+                    reportRecoverableError(try, Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}])
+                      listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}], try, try)
+                    insertBlock(try)
+                      rewriter()
+                      rewriter()
+                  listener: beginBlock({, BlockKind(try statement))
+                  notEofOrValue(}, })
+                  listener: endBlock(0, {, }, BlockKind(try statement))
+                reportRecoverableError(try, OnlyTry)
+                  listener: handleRecoverableError(OnlyTry, try, try)
+                listener: endTryStatement(0, try, null)
+          notEofOrValue(}, ()
+          parseStatement(})
+            parseStatementX(})
+              parseExpressionStatementOrDeclaration(}, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(})
+                    parseExpression(})
+                      parsePrecedenceExpression(}, 1, true)
+                        parseUnaryExpression(}, true)
+                          parsePrimary(}, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(})
+                              parseParenthesizedExpression(})
+                                parseExpressionInParenthesis(})
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(try, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(var)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(var)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(var)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(var)
+      insertSyntheticIdentifier(var, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      reportRecoverableError(var, VarReturnType)
+        listener: handleRecoverableError(VarReturnType, var, var)
+      parseTopLevelMethod(;, null, var, Instance of 'NoType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(var)
+        ensureIdentifier(var, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(var, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'var'., null, {token: var}], var, var)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(var)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(var)
+                          listener: handleSend(, var)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], var, var)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(()
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration((, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                      listener: handleIdentifier(, localVariableDeclaration)
+                    listener: beginInitializedIdentifier()
+                    parseVariableInitializerOpt()
+                      listener: handleNoVariableInitializer(x)
+                    listener: endInitializedIdentifier()
+                  ensureSemicolon()
+                    reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                    rewriter()
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, x)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(x)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  ensureSemicolon(1)
+                    reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                    rewriter()
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, ))
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction())
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+          notEofOrValue(}, +)
+          parseStatement())
+            parseStatementX())
+              parseExpressionStatementOrDeclaration(), false)
+                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement())
+                    parseExpression())
+                      parsePrecedenceExpression(), 1, true)
+                        parseUnaryExpression(), true)
+                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(), expression)
+                            parseSendOrFunctionLiteral(), expression)
+                              parseSend(), expression)
+                                ensureIdentifier(), expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(var, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(void)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(void)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(void)
+      insertSyntheticIdentifier(void, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      parseTopLevelMethod(;, null, ;, Instance of 'VoidType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifier(void, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseSendOrFunctionLiteral(return, expression)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              reportRecoverableErrorWithToken(void, Instance of 'Template<(Token) => Message>')
+                                listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'void'., null, {token: void}], void, void)
+                              rewriter()
+                              listener: handleIdentifier(, expression)
+                            listener: handleNoTypeArguments(void)
+                            parseArgumentsOpt()
+                              listener: handleNoArguments(void)
+                            listener: handleSend(, void)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, void)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  listener: beginMetadataStar(void)
+                  listener: endMetadataStar(0)
+                  listener: handleVoidKeyword(void)
+                  listener: beginVariablesDeclaration((, null, null)
+                  parseVariablesDeclarationRest(void, true)
+                    parseOptionallyInitializedIdentifier(void)
+                      ensureIdentifier(void, localVariableDeclaration)
+                        reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                        rewriter()
+                        listener: handleIdentifier(, localVariableDeclaration)
+                      listener: beginInitializedIdentifier()
+                      parseVariableInitializerOpt()
+                        listener: handleNoVariableInitializer(x)
+                      listener: endInitializedIdentifier()
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                      rewriter()
+                    listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, x)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(x)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  ensureSemicolon(1)
+                    reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                    rewriter()
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, ))
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction())
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+          notEofOrValue(}, +)
+          parseStatement())
+            parseStatementX())
+              parseExpressionStatementOrDeclaration(), false)
+                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement())
+                    parseExpression())
+                      parsePrecedenceExpression(), 1, true)
+                        parseUnaryExpression(), true)
+                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(), expression)
+                            parseSendOrFunctionLiteral(), expression)
+                              parseSend(), expression)
+                                ensureIdentifier(), expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(while)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(while)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(while)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(while)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, while)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+          listener: handleIdentifier(while, topLevelFunctionDeclaration)
+        parseMethodTypeVar(while)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(while, while, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(while, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(while)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(while)
+                          listener: handleSend(, while)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], while, while)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, while)
+          parseStatement(;)
+            parseStatementX(;)
+              parseWhileStatement(;)
+                listener: beginWhileStatement(while)
+                ensureParenthesizedCondition(while)
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSendOrFunctionLiteral((, expression)
+                              parseSend((, expression)
+                                ensureIdentifier((, expression)
+                                  listener: handleIdentifier(x, expression)
+                                listener: handleNoTypeArguments(-)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(-)
+                                listener: handleSend(x, -)
+                        listener: beginBinaryExpression(-)
+                        parsePrecedenceExpression(-, 14, true)
+                          parseUnaryExpression(-, true)
+                            parsePrimary(-, expression)
+                              parseLiteralInt(-)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(-)
+                    ensureCloseParen(1, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginWhileStatementBody(+)
+                parseStatement())
+                  parseStatementX())
+                    parseExpressionStatementOrDeclaration(), false)
+                      parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                        looksLikeLocalFunction(+)
+                        parseExpressionStatement())
+                          parseExpression())
+                            parsePrecedenceExpression(), 1, true)
+                              parseUnaryExpression(), true)
+                                rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                  reportRecoverableError(+, UnsupportedPrefixPlus)
+                                    listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                  rewriter()
+                                parsePrimary(), expression)
+                                  parseSendOrFunctionLiteral(), expression)
+                                    parseSend(), expression)
+                                      ensureIdentifier(), expression)
+                                        listener: handleIdentifier(, expression)
+                                      listener: handleNoTypeArguments(+)
+                                      parseArgumentsOpt()
+                                        listener: handleNoArguments(+)
+                                      listener: handleSend(, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: handleExpressionStatement(;)
+                listener: endWhileStatementBody(})
+                listener: endWhileStatement(while, })
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(while, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(with)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(with)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(with)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(with)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, with)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+          listener: handleIdentifier(with, topLevelFunctionDeclaration)
+        parseMethodTypeVar(with)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(with, with, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(with, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+                            listener: handleIdentifier(with, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(with)
+                            parseArguments(with)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(with, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(with, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(int)
+  listener: endCompilationUnit(71, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.parser.expect
new file mode 100644
index 0000000..1dc529d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.parser.expect
@@ -0,0 +1,333 @@
+NOTICE: Stream was rewritten by parser!
+
+int ;assert(int x) {
+if (x == 0) return 42;
+return assert(x-1) + 1;
+}
+
+int ;break(int x) {
+if (x == 0) return 42;
+return ;break;(x-1) + 1;
+}
+
+int ;case(int x) {
+if (x == 0) return 42;
+return case(x-1) + 1;
+}
+
+int ;catch(int x) {
+if (x == 0) return 42;
+return catch(x-1) + 1;
+}
+
+int ;class({}int x;) {
+if (x == 0) return 42;
+return class(x-1) + 1;
+}
+
+int ;const(int x) {
+if (x == 0) return 42;
+return const(x-1) + 1;
+}
+
+int ;continue(int x) {
+if (x == 0) return 42;
+return ;continue;(x-1) + 1;
+}
+
+int ;default(int x) {
+if (x == 0) return 42;
+return default(x-1) + 1;
+}
+
+int ;do(int x) {
+if (x == 0) return 42;
+return ;do(x-1) + 1;
+while();}
+
+int ;else(int x) {
+if (x == 0) return 42;
+return ;;else(x-1) + 1;
+}
+
+int ;enum({}int x;) {
+if (x == 0) return 42;
+return enum(x-1) + 1;
+}
+
+int ;extends(int x) {
+if (x == 0) return 42;
+return extends(x-1) + 1;
+}
+
+int ;false(int x) {
+if (x == 0) return 42;
+return false(x-1) + 1;
+}
+
+int ;final(int x) {
+if (x == 0) return 42;
+return ;final(;x-1;;) + 1;
+}
+
+int ;finally(int x) {
+if (x == 0) return 42;
+return finally(x-1) + 1;
+}
+
+int ;for(int x) {
+if (x == 0) return 42;
+return ;for(x-1;;) + 1;
+}
+
+int ;if(int x) {
+if (x == 0) return 42;
+return ;if(x-1) + 1;
+}
+
+int ;in(int x) {
+if (x == 0) return 42;
+return in(x-1) + 1;
+}
+
+int ;is(int x) {
+if (x == 0) return 42;
+return is;(x-1) + 1;
+}
+
+int ;new(int x) {
+if (x == 0) return 42;
+return new(x-1) + 1;
+}
+
+int ;null(int x) {
+if (x == 0) return 42;
+return null(x-1) + 1;
+}
+
+int ;rethrow(int x) {
+if (x == 0) return 42;
+return rethrow(x-1) + 1;
+}
+
+int ;return(int x) {
+if (x == 0) return 42;
+return return(x-1) + 1;
+}
+
+int ;super(int x) {
+if (x == 0) return 42;
+return super(x-1) + 1;
+}
+
+int ;switch(int x) {
+if (x == 0) return 42;
+return ;switch(x-1) {}+ 1;
+}
+
+int this(int x) {
+if (x == 0) return 42;
+return this(x-1) + 1;
+}
+
+int ;throw(int x) {
+if (x == 0) return 42;
+return throw(x-1) + 1;
+}
+
+int ;true(int x) {
+if (x == 0) return 42;
+return true(x-1) + 1;
+}
+
+int ;try(int x) {
+if (x == 0) return 42;
+return ;try{}(x-1) + 1;
+}
+
+int ;var(int x) {
+if (x == 0) return 42;
+return ;var(;x-1;;) + 1;
+}
+
+int ;void(int x) {
+if (x == 0) return 42;
+return ;void(;x-1;;) + 1;
+}
+
+int ;while(int x) {
+if (x == 0) return 42;
+return ;while(x-1) + 1;
+}
+
+int ;with(int x) {
+if (x == 0) return 42;
+return with(x-1) + 1;
+}
+
+
+int[StringToken] ;[SyntheticToken]assert[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] assert[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]break[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]break[KeywordToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]case[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] case[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]catch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] catch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]class[KeywordToken]([BeginToken][SyntheticStringToken]{[SyntheticBeginToken]}[SyntheticToken]int[StringToken] x[StringToken];[SyntheticToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] class[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]const[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]continue[KeywordToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]default[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] default[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]do[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]do[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+while[SyntheticKeywordToken]([SyntheticBeginToken][SyntheticStringToken])[SyntheticToken];[SyntheticToken]}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]else[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken]else[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]enum[KeywordToken]([BeginToken][SyntheticStringToken]{[SyntheticBeginToken]}[SyntheticToken]int[StringToken] x[StringToken];[SyntheticToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] enum[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]extends[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] extends[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]false[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] false[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]final[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]final[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]finally[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] finally[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]for[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]for[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]if[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]if[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]in[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] in[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]is[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken]is[KeywordToken][SyntheticStringToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]new[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] new[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]null[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] null[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]rethrow[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] rethrow[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]return[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] return[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]super[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] super[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]switch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]switch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] {[SyntheticBeginToken]}[SyntheticToken][SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] this[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] this[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]throw[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] throw[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]true[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] true[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]try[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]try[KeywordToken]{[SyntheticBeginToken]}[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]var[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]var[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]void[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]void[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]while[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]while[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]with[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] with[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.scanner.expect
new file mode 100644
index 0000000..896ca86
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_fields.dart.scanner.expect
@@ -0,0 +1,331 @@
+int assert(int x) {
+if (x == 0) return 42;
+return assert(x-1) + 1;
+}
+
+int break(int x) {
+if (x == 0) return 42;
+return break(x-1) + 1;
+}
+
+int case(int x) {
+if (x == 0) return 42;
+return case(x-1) + 1;
+}
+
+int catch(int x) {
+if (x == 0) return 42;
+return catch(x-1) + 1;
+}
+
+int class(int x) {
+if (x == 0) return 42;
+return class(x-1) + 1;
+}
+
+int const(int x) {
+if (x == 0) return 42;
+return const(x-1) + 1;
+}
+
+int continue(int x) {
+if (x == 0) return 42;
+return continue(x-1) + 1;
+}
+
+int default(int x) {
+if (x == 0) return 42;
+return default(x-1) + 1;
+}
+
+int do(int x) {
+if (x == 0) return 42;
+return do(x-1) + 1;
+}
+
+int else(int x) {
+if (x == 0) return 42;
+return else(x-1) + 1;
+}
+
+int enum(int x) {
+if (x == 0) return 42;
+return enum(x-1) + 1;
+}
+
+int extends(int x) {
+if (x == 0) return 42;
+return extends(x-1) + 1;
+}
+
+int false(int x) {
+if (x == 0) return 42;
+return false(x-1) + 1;
+}
+
+int final(int x) {
+if (x == 0) return 42;
+return final(x-1) + 1;
+}
+
+int finally(int x) {
+if (x == 0) return 42;
+return finally(x-1) + 1;
+}
+
+int for(int x) {
+if (x == 0) return 42;
+return for(x-1) + 1;
+}
+
+int if(int x) {
+if (x == 0) return 42;
+return if(x-1) + 1;
+}
+
+int in(int x) {
+if (x == 0) return 42;
+return in(x-1) + 1;
+}
+
+int is(int x) {
+if (x == 0) return 42;
+return is(x-1) + 1;
+}
+
+int new(int x) {
+if (x == 0) return 42;
+return new(x-1) + 1;
+}
+
+int null(int x) {
+if (x == 0) return 42;
+return null(x-1) + 1;
+}
+
+int rethrow(int x) {
+if (x == 0) return 42;
+return rethrow(x-1) + 1;
+}
+
+int return(int x) {
+if (x == 0) return 42;
+return return(x-1) + 1;
+}
+
+int super(int x) {
+if (x == 0) return 42;
+return super(x-1) + 1;
+}
+
+int switch(int x) {
+if (x == 0) return 42;
+return switch(x-1) + 1;
+}
+
+int this(int x) {
+if (x == 0) return 42;
+return this(x-1) + 1;
+}
+
+int throw(int x) {
+if (x == 0) return 42;
+return throw(x-1) + 1;
+}
+
+int true(int x) {
+if (x == 0) return 42;
+return true(x-1) + 1;
+}
+
+int try(int x) {
+if (x == 0) return 42;
+return try(x-1) + 1;
+}
+
+int var(int x) {
+if (x == 0) return 42;
+return var(x-1) + 1;
+}
+
+int void(int x) {
+if (x == 0) return 42;
+return void(x-1) + 1;
+}
+
+int while(int x) {
+if (x == 0) return 42;
+return while(x-1) + 1;
+}
+
+int with(int x) {
+if (x == 0) return 42;
+return with(x-1) + 1;
+}
+
+
+int[StringToken] assert[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] assert[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] break[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] break[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] case[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] case[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] catch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] catch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] class[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] class[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] const[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] continue[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] default[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] default[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] do[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] do[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] else[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] else[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] enum[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] enum[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] extends[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] extends[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] false[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] false[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] final[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] final[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] finally[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] finally[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] for[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] for[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] if[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] if[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] in[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] in[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] is[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] is[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] new[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] new[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] null[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] null[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] rethrow[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] rethrow[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] return[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] return[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] super[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] super[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] switch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] switch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] this[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] this[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] throw[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] throw[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] true[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] true[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] try[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] try[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] var[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] var[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] void[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] void[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] while[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] while[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] with[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] with[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart
new file mode 100644
index 0000000..30bed69
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart
@@ -0,0 +1,164 @@
+int assert(int x) {
+  if (x == 0) return 42;
+  return assert(x-1) + 1;
+}
+
+int break(int x) {
+  if (x == 0) return 42;
+  return break(x-1) + 1;
+}
+
+int case(int x) {
+  if (x == 0) return 42;
+  return case(x-1) + 1;
+}
+
+int catch(int x) {
+  if (x == 0) return 42;
+  return catch(x-1) + 1;
+}
+
+int class(int x) {
+  if (x == 0) return 42;
+  return class(x-1) + 1;
+}
+
+int const(int x) {
+  if (x == 0) return 42;
+  return const(x-1) + 1;
+}
+
+int continue(int x) {
+  if (x == 0) return 42;
+  return continue(x-1) + 1;
+}
+
+int default(int x) {
+  if (x == 0) return 42;
+  return default(x-1) + 1;
+}
+
+int do(int x) {
+  if (x == 0) return 42;
+  return do(x-1) + 1;
+}
+
+int else(int x) {
+  if (x == 0) return 42;
+  return else(x-1) + 1;
+}
+
+int enum(int x) {
+  if (x == 0) return 42;
+  return enum(x-1) + 1;
+}
+
+int extends(int x) {
+  if (x == 0) return 42;
+  return extends(x-1) + 1;
+}
+
+int false(int x) {
+  if (x == 0) return 42;
+  return false(x-1) + 1;
+}
+
+int final(int x) {
+  if (x == 0) return 42;
+  return final(x-1) + 1;
+}
+
+int finally(int x) {
+  if (x == 0) return 42;
+  return finally(x-1) + 1;
+}
+
+int for(int x) {
+  if (x == 0) return 42;
+  return for(x-1) + 1;
+}
+
+int if(int x) {
+  if (x == 0) return 42;
+  return if(x-1) + 1;
+}
+
+int in(int x) {
+  if (x == 0) return 42;
+  return in(x-1) + 1;
+}
+
+int is(int x) {
+  if (x == 0) return 42;
+  return is(x-1) + 1;
+}
+
+int new(int x) {
+  if (x == 0) return 42;
+  return new(x-1) + 1;
+}
+
+int null(int x) {
+  if (x == 0) return 42;
+  return null(x-1) + 1;
+}
+
+int rethrow(int x) {
+  if (x == 0) return 42;
+  return rethrow(x-1) + 1;
+}
+
+int return(int x) {
+  if (x == 0) return 42;
+  return return(x-1) + 1;
+}
+
+int super(int x) {
+  if (x == 0) return 42;
+  return super(x-1) + 1;
+}
+
+int switch(int x) {
+  if (x == 0) return 42;
+  return switch(x-1) + 1;
+}
+
+int this(int x) {
+  if (x == 0) return 42;
+  return this(x-1) + 1;
+}
+
+int throw(int x) {
+  if (x == 0) return 42;
+  return throw(x-1) + 1;
+}
+
+int true(int x) {
+  if (x == 0) return 42;
+  return true(x-1) + 1;
+}
+
+int try(int x) {
+  if (x == 0) return 42;
+  return try(x-1) + 1;
+}
+
+int var(int x) {
+  if (x == 0) return 42;
+  return var(x-1) + 1;
+}
+
+int void(int x) {
+  if (x == 0) return 42;
+  return void(x-1) + 1;
+}
+
+int while(int x) {
+  if (x == 0) return 42;
+  return while(x-1) + 1;
+}
+
+int with(int x) {
+  if (x == 0) return 42;
+  return with(x-1) + 1;
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.expect
new file mode 100644
index 0000000..5d0f1b4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.expect
@@ -0,0 +1,3177 @@
+Problems reported:
+
+parser/error_recovery/reserved_words_top_level_methods:1:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int assert(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:1:1: Expected ';' after this.
+int assert(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:1:5: Expected an identifier, but got 'assert'.
+int assert(int x) {
+    ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:3:10: `assert` can't be used as an expression.
+  return assert(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:6:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int break(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:6:1: Expected ';' after this.
+int break(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:6:5: Expected an identifier, but got 'break'.
+int break(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:8:10: Expected an identifier, but got 'break'.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:8:10: Expected ';' after this.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:8:10: A break statement can't be used outside of a loop or switch statement.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:8:10: Expected ';' after this.
+  return break(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:11:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int case(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:11:1: Expected ';' after this.
+int case(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:11:5: Expected an identifier, but got 'case'.
+int case(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:13:10: Expected an identifier, but got 'case'.
+  return case(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:16:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int catch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:16:1: Expected ';' after this.
+int catch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:16:5: Expected an identifier, but got 'catch'.
+int catch(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:18:10: Expected an identifier, but got 'catch'.
+  return catch(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:21:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int class(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:21:1: Expected ';' after this.
+int class(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:21:10: Expected an identifier, but got '('.
+int class(int x) {
+         ^
+
+parser/error_recovery/reserved_words_top_level_methods:21:11: A class declaration must have a body, even if it is empty.
+int class(int x) {
+          ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:21:15: Expected ';' after this.
+int class(int x) {
+              ^
+
+parser/error_recovery/reserved_words_top_level_methods:21:16: Expected a declaration, but got ')'.
+int class(int x) {
+               ^
+
+parser/error_recovery/reserved_words_top_level_methods:21:18: Expected a declaration, but got '{'.
+int class(int x) {
+                 ^
+
+parser/error_recovery/reserved_words_top_level_methods:26:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int const(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:26:1: Expected ';' after this.
+int const(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:26:10: Expected an identifier, but got '('.
+int const(int x) {
+         ^
+
+parser/error_recovery/reserved_words_top_level_methods:26:5: Can't have modifier 'const' here.
+int const(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:28:15: Expected an identifier, but got '('.
+  return const(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_top_level_methods:31:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int continue(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:31:1: Expected ';' after this.
+int continue(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:31:5: Expected an identifier, but got 'continue'.
+int continue(int x) {
+    ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:33:10: Expected an identifier, but got 'continue'.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:33:10: Expected ';' after this.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:33:10: A continue statement can't be used outside of a loop or switch statement.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:33:10: Expected ';' after this.
+  return continue(x-1) + 1;
+         ^^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:36:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int default(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:36:1: Expected ';' after this.
+int default(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:36:5: Expected an identifier, but got 'default'.
+int default(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:38:10: Expected an identifier, but got 'default'.
+  return default(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:41:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int do(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:41:1: Expected ';' after this.
+int do(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:41:5: Expected an identifier, but got 'do'.
+int do(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_methods:43:10: Expected an identifier, but got 'do'.
+  return do(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_methods:43:10: Expected ';' after this.
+  return do(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_methods:44:1: Expected 'while' before this.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_methods:44:1: Expected to find '('.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_methods:44:1: Expected an identifier, but got '}'.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_methods:44:1: Expected ';' after this.
+}
+^
+
+parser/error_recovery/reserved_words_top_level_methods:46:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int else(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:46:1: Expected ';' after this.
+int else(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:46:5: Expected an identifier, but got 'else'.
+int else(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:48:10: Expected an identifier, but got 'else'.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:48:10: Expected ';' after this.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:48:10: Expected an identifier, but got 'else'.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:48:10: Expected ';' after this.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:48:10: Unexpected token ';'.
+  return else(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:51:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int enum(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:51:1: Expected ';' after this.
+int enum(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:51:9: Expected an identifier, but got '('.
+int enum(int x) {
+        ^
+
+parser/error_recovery/reserved_words_top_level_methods:51:10: Expected a enum body, but got 'int'.
+int enum(int x) {
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:51:14: Expected ';' after this.
+int enum(int x) {
+             ^
+
+parser/error_recovery/reserved_words_top_level_methods:51:15: Expected a declaration, but got ')'.
+int enum(int x) {
+              ^
+
+parser/error_recovery/reserved_words_top_level_methods:51:17: Expected a declaration, but got '{'.
+int enum(int x) {
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:56:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int extends(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:56:1: Expected ';' after this.
+int extends(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:56:5: Expected an identifier, but got 'extends'.
+int extends(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:58:10: Expected an identifier, but got 'extends'.
+  return extends(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:61:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int false(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:61:1: Expected ';' after this.
+int false(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:61:5: Expected an identifier, but got 'false'.
+int false(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:66:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int final(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:66:1: Expected ';' after this.
+int final(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:66:10: Expected an identifier, but got '('.
+int final(int x) {
+         ^
+
+parser/error_recovery/reserved_words_top_level_methods:66:5: Can't have modifier 'final' here.
+int final(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:68:10: Expected an identifier, but got 'final'.
+  return final(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:68:10: Expected ';' after this.
+  return final(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:68:15: Expected an identifier, but got '('.
+  return final(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_top_level_methods:68:16: Expected ';' after this.
+  return final(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_top_level_methods:68:18: Expected ';' after this.
+  return final(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_methods:68:19: Expected an identifier, but got ')'.
+  return final(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_methods:68:19: Expected ';' after this.
+  return final(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_methods:68:19: Unexpected token ';'.
+  return final(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_methods:68:21: '+' is not a prefix operator.
+  return final(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_top_level_methods:71:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int finally(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:71:1: Expected ';' after this.
+int finally(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:71:5: Expected an identifier, but got 'finally'.
+int finally(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:73:10: Expected an identifier, but got 'finally'.
+  return finally(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:76:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int for(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:76:1: Expected ';' after this.
+int for(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:76:5: Expected an identifier, but got 'for'.
+int for(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:78:10: Expected an identifier, but got 'for'.
+  return for(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:78:10: Expected ';' after this.
+  return for(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:78:16: Expected ';' after this.
+  return for(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_top_level_methods:78:17: Expected an identifier, but got ')'.
+  return for(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:78:17: Expected ';' after this.
+  return for(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:78:19: '+' is not a prefix operator.
+  return for(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_methods:81:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int if(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:81:1: Expected ';' after this.
+int if(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:81:5: Expected an identifier, but got 'if'.
+int if(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_methods:83:10: Expected an identifier, but got 'if'.
+  return if(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_methods:83:10: Expected ';' after this.
+  return if(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_methods:83:18: '+' is not a prefix operator.
+  return if(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_methods:86:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int in(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:86:1: Expected ';' after this.
+int in(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:86:5: Expected an identifier, but got 'in'.
+int in(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_methods:88:10: Expected an identifier, but got 'in'.
+  return in(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_methods:91:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int is(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:91:1: Expected ';' after this.
+int is(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:91:5: Expected an identifier, but got 'is'.
+int is(int x) {
+    ^^
+
+parser/error_recovery/reserved_words_top_level_methods:93:10: Expected an identifier, but got 'is'.
+  return is(x-1) + 1;
+         ^^
+
+parser/error_recovery/reserved_words_top_level_methods:93:12: Expected a type, but got '('.
+  return is(x-1) + 1;
+           ^
+
+parser/error_recovery/reserved_words_top_level_methods:93:12: Expected ';' after this.
+  return is(x-1) + 1;
+           ^
+
+parser/error_recovery/reserved_words_top_level_methods:96:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int new(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:96:1: Expected ';' after this.
+int new(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:96:5: Expected an identifier, but got 'new'.
+int new(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:98:13: Expected an identifier, but got '('.
+  return new(x-1) + 1;
+            ^
+
+parser/error_recovery/reserved_words_top_level_methods:101:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int null(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:101:1: Expected ';' after this.
+int null(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:101:5: Expected an identifier, but got 'null'.
+int null(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:106:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int rethrow(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:106:1: Expected ';' after this.
+int rethrow(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:106:5: Expected an identifier, but got 'rethrow'.
+int rethrow(int x) {
+    ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:108:10: Expected an identifier, but got 'rethrow'.
+  return rethrow(x-1) + 1;
+         ^^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:111:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int return(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:111:1: Expected ';' after this.
+int return(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:111:5: Expected an identifier, but got 'return'.
+int return(int x) {
+    ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:113:10: Unexpected token 'return'.
+  return return(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:116:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int super(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:116:1: Expected ';' after this.
+int super(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:116:5: Expected an identifier, but got 'super'.
+int super(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:121:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int switch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:121:1: Expected ';' after this.
+int switch(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:121:5: Expected an identifier, but got 'switch'.
+int switch(int x) {
+    ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:123:10: Expected an identifier, but got 'switch'.
+  return switch(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:123:10: Expected ';' after this.
+  return switch(x-1) + 1;
+         ^^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:123:20: A switch statement must have a body, even if it is empty.
+  return switch(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_top_level_methods:123:22: '+' is not a prefix operator.
+  return switch(x-1) + 1;
+                     ^
+
+parser/error_recovery/reserved_words_top_level_methods:126:5: Expected an identifier, but got 'this'.
+int this(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:131:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int throw(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:131:1: Expected ';' after this.
+int throw(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:131:5: Expected an identifier, but got 'throw'.
+int throw(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:136:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int true(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:136:1: Expected ';' after this.
+int true(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:136:5: Expected an identifier, but got 'true'.
+int true(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:141:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int try(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:141:1: Expected ';' after this.
+int try(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:141:5: Expected an identifier, but got 'try'.
+int try(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:143:10: Expected an identifier, but got 'try'.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:143:10: Expected ';' after this.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:143:10: A try statement must have a body, even if it is empty.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:143:10: A try block must be followed by an 'on', 'catch', or 'finally' clause.
+  return try(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:146:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int var(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:146:1: Expected ';' after this.
+int var(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:146:8: Expected an identifier, but got '('.
+int var(int x) {
+       ^
+
+parser/error_recovery/reserved_words_top_level_methods:146:5: The return type can't be 'var'.
+int var(int x) {
+    ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:148:10: Expected an identifier, but got 'var'.
+  return var(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:148:10: Expected ';' after this.
+  return var(x-1) + 1;
+         ^^^
+
+parser/error_recovery/reserved_words_top_level_methods:148:13: Expected an identifier, but got '('.
+  return var(x-1) + 1;
+            ^
+
+parser/error_recovery/reserved_words_top_level_methods:148:14: Expected ';' after this.
+  return var(x-1) + 1;
+             ^
+
+parser/error_recovery/reserved_words_top_level_methods:148:16: Expected ';' after this.
+  return var(x-1) + 1;
+               ^
+
+parser/error_recovery/reserved_words_top_level_methods:148:17: Expected an identifier, but got ')'.
+  return var(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:148:17: Expected ';' after this.
+  return var(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:148:17: Unexpected token ';'.
+  return var(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:148:19: '+' is not a prefix operator.
+  return var(x-1) + 1;
+                  ^
+
+parser/error_recovery/reserved_words_top_level_methods:151:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int void(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:151:1: Expected ';' after this.
+int void(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:151:9: Expected an identifier, but got '('.
+int void(int x) {
+        ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:10: Expected an identifier, but got 'void'.
+  return void(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:153:10: Expected ';' after this.
+  return void(x-1) + 1;
+         ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:153:14: Expected an identifier, but got '('.
+  return void(x-1) + 1;
+             ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:15: Expected ';' after this.
+  return void(x-1) + 1;
+              ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:17: Expected ';' after this.
+  return void(x-1) + 1;
+                ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:18: Expected an identifier, but got ')'.
+  return void(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:18: Expected ';' after this.
+  return void(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:18: Unexpected token ';'.
+  return void(x-1) + 1;
+                 ^
+
+parser/error_recovery/reserved_words_top_level_methods:153:20: '+' is not a prefix operator.
+  return void(x-1) + 1;
+                   ^
+
+parser/error_recovery/reserved_words_top_level_methods:156:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int while(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:156:1: Expected ';' after this.
+int while(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:156:5: Expected an identifier, but got 'while'.
+int while(int x) {
+    ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:158:10: Expected an identifier, but got 'while'.
+  return while(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:158:10: Expected ';' after this.
+  return while(x-1) + 1;
+         ^^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:158:21: '+' is not a prefix operator.
+  return while(x-1) + 1;
+                    ^
+
+parser/error_recovery/reserved_words_top_level_methods:161:1: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+int with(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:161:1: Expected ';' after this.
+int with(int x) {
+^^^
+
+parser/error_recovery/reserved_words_top_level_methods:161:5: Expected an identifier, but got 'with'.
+int with(int x) {
+    ^^^^
+
+parser/error_recovery/reserved_words_top_level_methods:163:10: Expected an identifier, but got 'with'.
+  return with(x-1) + 1;
+         ^^^^
+
+beginCompilationUnit(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    handleRecoverableError(MissingConstFinalVarOrType, int, int)
+    handleNoType()
+    handleIdentifier(int, topLevelVariableDeclaration)
+    handleNoFieldInitializer(assert)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+  endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(assert)
+beginMetadataStar(assert)
+endMetadataStar(0)
+beginTopLevelMember(assert)
+  beginTopLevelMethod(;, null)
+    handleNoType(;)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'assert'., null, {token: assert}], assert, assert)
+    handleIdentifier(assert, topLevelFunctionDeclaration)
+    handleNoTypeVariables(()
+    beginFormalParameters((, MemberKind.TopLevelMethod)
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(x)
+        handleType(int, null)
+        handleIdentifier(x, formalParameterDeclaration)
+        handleFormalParameterWithoutValue())
+      endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+    endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+    handleAsyncModifier(null, null)
+    beginBlockFunctionBody({)
+      beginIfStatement(if)
+        handleIdentifier(x, expression)
+        handleNoTypeArguments(==)
+        handleNoArguments(==)
+        handleSend(x, ==)
+        beginBinaryExpression(==)
+        handleLiteralInt(0)
+        endBinaryExpression(==)
+        handleParenthesizedCondition(()
+        beginThenStatement(return)
+          beginReturnStatement(return)
+            handleLiteralInt(42)
+          endReturnStatement(true, return, ;)
+        endThenStatement(;)
+      endIfStatement(if, null)
+      beginReturnStatement(return)
+        beginAssert(assert, Assert.Expression)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(-)
+          handleNoArguments(-)
+          handleSend(x, -)
+          beginBinaryExpression(-)
+          handleLiteralInt(1)
+          endBinaryExpression(-)
+          handleRecoverableError(AssertAsExpression, assert, assert)
+        endAssert(assert, Assert.Expression, (, null, +)
+        beginBinaryExpression(+)
+        handleLiteralInt(1)
+        endBinaryExpression(+)
+      endReturnStatement(true, return, ;)
+    endBlockFunctionBody(2, {, })
+  endTopLevelMethod(assert, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+  handleRecoverableError(MissingConstFinalVarOrType, int, int)
+  handleNoType(})
+  handleIdentifier(int, topLevelVariableDeclaration)
+  handleNoFieldInitializer(break)
+  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(break)
+beginMetadataStar(break)
+endMetadataStar(0)
+beginTopLevelMember(break)
+beginTopLevelMethod(;, null)
+  handleNoType(;)
+  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+  handleIdentifier(break, topLevelFunctionDeclaration)
+  handleNoTypeVariables(()
+  beginFormalParameters((, MemberKind.TopLevelMethod)
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(x)
+      handleType(int, null)
+      handleIdentifier(x, formalParameterDeclaration)
+      handleFormalParameterWithoutValue())
+    endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+  endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+  handleAsyncModifier(null, null)
+  beginBlockFunctionBody({)
+    beginIfStatement(if)
+      handleIdentifier(x, expression)
+      handleNoTypeArguments(==)
+      handleNoArguments(==)
+      handleSend(x, ==)
+      beginBinaryExpression(==)
+      handleLiteralInt(0)
+      endBinaryExpression(==)
+      handleParenthesizedCondition(()
+      beginThenStatement(return)
+        beginReturnStatement(return)
+          handleLiteralInt(42)
+        endReturnStatement(true, return, ;)
+      endThenStatement(;)
+    endIfStatement(if, null)
+    beginReturnStatement(return)
+      handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+      handleIdentifier(, expression)
+      handleNoTypeArguments(break)
+      handleNoArguments(break)
+      handleSend(, break)
+      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+    endReturnStatement(true, return, ;)
+    handleRecoverableError(BreakOutsideOfLoop, break, break)
+    handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+    handleBreakStatement(false, break, ;)
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(-)
+    handleNoArguments(-)
+    handleSend(x, -)
+    beginBinaryExpression(-)
+    handleLiteralInt(1)
+    endBinaryExpression(-)
+    handleParenthesizedExpression(()
+    beginBinaryExpression(+)
+    handleLiteralInt(1)
+    endBinaryExpression(+)
+    handleExpressionStatement(;)
+  endBlockFunctionBody(4, {, })
+endTopLevelMethod(break, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(case)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(case)
+beginMetadataStar(case)
+endMetadataStar(0)
+beginTopLevelMember(case)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+handleIdentifier(case, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+    handleIdentifier(int, typeReference)
+    handleNoTypeArguments(x)
+    handleType(int, null)
+    handleIdentifier(x, formalParameterDeclaration)
+    handleFormalParameterWithoutValue())
+  endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+  beginIfStatement(if)
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(==)
+    handleNoArguments(==)
+    handleSend(x, ==)
+    beginBinaryExpression(==)
+    handleLiteralInt(0)
+    endBinaryExpression(==)
+    handleParenthesizedCondition(()
+    beginThenStatement(return)
+      beginReturnStatement(return)
+        handleLiteralInt(42)
+      endReturnStatement(true, return, ;)
+    endThenStatement(;)
+  endIfStatement(if, null)
+  beginReturnStatement(return)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+    handleIdentifier(case, expression)
+    handleNoTypeArguments(()
+    beginArguments(()
+      handleIdentifier(x, expression)
+      handleNoTypeArguments(-)
+      handleNoArguments(-)
+      handleSend(x, -)
+      beginBinaryExpression(-)
+      handleLiteralInt(1)
+      endBinaryExpression(-)
+    endArguments(1, (, ))
+    handleSend(case, +)
+    beginBinaryExpression(+)
+    handleLiteralInt(1)
+    endBinaryExpression(+)
+  endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(case, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(catch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(catch)
+beginMetadataStar(catch)
+endMetadataStar(0)
+beginTopLevelMember(catch)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+handleIdentifier(catch, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+  handleIdentifier(int, typeReference)
+  handleNoTypeArguments(x)
+  handleType(int, null)
+  handleIdentifier(x, formalParameterDeclaration)
+  handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+  handleIdentifier(x, expression)
+  handleNoTypeArguments(==)
+  handleNoArguments(==)
+  handleSend(x, ==)
+  beginBinaryExpression(==)
+  handleLiteralInt(0)
+  endBinaryExpression(==)
+  handleParenthesizedCondition(()
+  beginThenStatement(return)
+    beginReturnStatement(return)
+      handleLiteralInt(42)
+    endReturnStatement(true, return, ;)
+  endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+  handleIdentifier(catch, expression)
+  handleNoTypeArguments(()
+  beginArguments(()
+    handleIdentifier(x, expression)
+    handleNoTypeArguments(-)
+    handleNoArguments(-)
+    handleSend(x, -)
+    beginBinaryExpression(-)
+    handleLiteralInt(1)
+    endBinaryExpression(-)
+  endArguments(1, (, ))
+  handleSend(catch, +)
+  beginBinaryExpression(+)
+  handleLiteralInt(1)
+  endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(catch, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(class)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(class)
+beginMetadataStar(class)
+endMetadataStar(0)
+beginClassOrNamedMixinApplicationPrelude(class)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, classOrMixinDeclaration)
+handleNoTypeVariables(int)
+beginClassDeclaration(class, null, )
+handleNoType()
+handleClassExtends(null)
+handleClassNoWithClause()
+handleClassOrMixinImplements(null, 0)
+handleClassHeader(class, class, null)
+handleNoType()
+handleClassExtends(null)
+handleClassNoWithClause()
+handleClassOrMixinImplements(null, 0)
+handleRecoverClassHeader()
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A class declaration must have a body, even if it is empty., Try adding an empty body., {string: class declaration}], int, int)
+beginClassOrMixinBody(DeclarationKind.Class, {)
+endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, topLevelVariableDeclaration)
+handleNoFieldInitializer())
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration())
+beginMetadataStar())
+endMetadataStar(0)
+beginTopLevelMember())
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+handleInvalidTopLevelDeclaration())
+endTopLevelDeclaration({)
+beginMetadataStar({)
+endMetadataStar(0)
+beginTopLevelMember({)
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+beginBlock({, BlockKind(invalid))
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(class, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(class, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlock(2, {, }, BlockKind(invalid))
+handleInvalidTopLevelBlock({)
+handleInvalidTopLevelDeclaration(})
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(const)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(const)
+beginMetadataStar(const)
+endMetadataStar(0)
+beginTopLevelMember(const)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'const' here., Try removing 'const'., {token: const}], const, const)
+beginTopLevelMethod(;, null)
+handleNoType(const)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+beginConstExpression(const)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, constructorReference)
+beginConstructorReference()
+handleNoTypeArguments(()
+handleNoConstructorReferenceContinuationAfterTypeArguments(()
+endConstructorReference(, null, ()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+endConstExpression(const)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(const, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(continue)
+beginMetadataStar(continue)
+endMetadataStar(0)
+beginTopLevelMember(continue)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+handleIdentifier(continue, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+handleIdentifier(, expression)
+handleNoTypeArguments(continue)
+handleNoArguments(continue)
+handleSend(, continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+endReturnStatement(true, return, ;)
+handleRecoverableError(ContinueOutsideOfLoop, continue, continue)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+handleContinueStatement(false, continue, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(continue, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(default)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(default)
+beginMetadataStar(default)
+endMetadataStar(0)
+beginTopLevelMember(default)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+handleIdentifier(default, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+handleIdentifier(default, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(default, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(default, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(do)
+beginMetadataStar(do)
+endMetadataStar(0)
+beginTopLevelMember(do)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+handleIdentifier(do, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+handleIdentifier(, expression)
+handleNoTypeArguments(do)
+handleNoArguments(do)
+handleSend(, do)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], do, do)
+endReturnStatement(true, return, ;)
+beginDoWhileStatement(do)
+beginDoWhileStatementBody(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endDoWhileStatementBody(;)
+handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
+handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '}'., null, {token: }}], }, })
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleParenthesizedCondition(()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+endDoWhileStatement(do, while, ;)
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(do, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(else)
+beginMetadataStar(else)
+endMetadataStar(0)
+beginTopLevelMember(else)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(else, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(, expression)
+handleNoTypeArguments(else)
+handleNoArguments(else)
+handleSend(, else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+endReturnStatement(true, return, ;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+handleIdentifier(, expression)
+handleNoTypeArguments(else)
+handleNoArguments(else)
+handleSend(, else)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], else, else)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(else, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(enum)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(enum)
+beginMetadataStar(enum)
+endMetadataStar(0)
+beginEnum(enum)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, enumDeclaration)
+handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {token: int}], int, int)
+endEnum(enum, {, 0)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, topLevelVariableDeclaration)
+handleNoFieldInitializer())
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration())
+beginMetadataStar())
+endMetadataStar(0)
+beginTopLevelMember())
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+handleInvalidTopLevelDeclaration())
+endTopLevelDeclaration({)
+beginMetadataStar({)
+endMetadataStar(0)
+beginTopLevelMember({)
+handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+beginBlock({, BlockKind(invalid))
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(enum, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(enum, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlock(2, {, }, BlockKind(invalid))
+handleInvalidTopLevelBlock({)
+handleInvalidTopLevelDeclaration(})
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(extends)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(extends)
+beginMetadataStar(extends)
+endMetadataStar(0)
+beginTopLevelMember(extends)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+handleIdentifier(extends, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+handleIdentifier(extends, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(extends, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(extends, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(false)
+beginMetadataStar(false)
+endMetadataStar(0)
+beginTopLevelMember(false)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'false'., null, {token: false}], false, false)
+handleIdentifier(false, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralBool(false)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(false, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(final)
+beginMetadataStar(final)
+endMetadataStar(0)
+beginTopLevelMember(final)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+beginTopLevelMethod(;, null)
+handleNoType(final)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'final'., null, {token: final}], final, final)
+handleIdentifier(, expression)
+handleNoTypeArguments(final)
+handleNoArguments(final)
+handleSend(, final)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], final, final)
+endReturnStatement(true, return, ;)
+beginMetadataStar(final)
+endMetadataStar(0)
+handleNoType(final)
+beginVariablesDeclaration((, null, final)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endTopLevelMethod(final, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(finally)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(finally)
+beginMetadataStar(finally)
+endMetadataStar(0)
+beginTopLevelMember(finally)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+handleIdentifier(finally, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+handleIdentifier(finally, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(finally, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(finally, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(for)
+beginMetadataStar(for)
+endMetadataStar(0)
+beginTopLevelMember(for)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+handleIdentifier(for, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+handleIdentifier(, expression)
+handleNoTypeArguments(for)
+handleNoArguments(for)
+handleSend(, for)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], for, for)
+endReturnStatement(true, return, ;)
+beginForStatement(for)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleForInitializerExpressionStatement(1, false)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleForLoopParts(for, (, ;, 0)
+beginForStatementBody(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endForStatementBody(})
+endForStatement(})
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(for, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(if)
+beginMetadataStar(if)
+endMetadataStar(0)
+beginTopLevelMember(if)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+handleIdentifier(if, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+handleIdentifier(, expression)
+handleNoTypeArguments(if)
+handleNoArguments(if)
+handleSend(, if)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], if, if)
+endReturnStatement(true, return, ;)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+beginThenStatement(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endThenStatement(;)
+endIfStatement(if, null)
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(if, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(in)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(in)
+beginMetadataStar(in)
+endMetadataStar(0)
+beginTopLevelMember(in)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+handleIdentifier(in, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+handleIdentifier(in, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(in, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(in, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(is)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(is)
+beginMetadataStar(is)
+endMetadataStar(0)
+beginTopLevelMember(is)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+handleIdentifier(is, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+handleIdentifier(, expression)
+handleNoTypeArguments(is)
+handleNoArguments(is)
+handleSend(, is)
+beginIsOperatorType(is)
+handleRecoverableError(Message[ExpectedType, Expected a type, but got '('., null, {token: (}], (, ()
+handleIdentifier(, typeReference)
+handleNoTypeArguments(()
+handleType(, null)
+endIsOperatorType(is)
+handleIsOperator(is, null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
+endReturnStatement(true, return, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(is, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(new)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(new)
+beginMetadataStar(new)
+endMetadataStar(0)
+beginTopLevelMember(new)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'new'., null, {token: new}], new, new)
+handleIdentifier(new, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+beginNewExpression(new)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, constructorReference)
+beginConstructorReference()
+handleNoTypeArguments(()
+handleNoConstructorReferenceContinuationAfterTypeArguments(()
+endConstructorReference(, null, ()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+endNewExpression(new)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(new, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(null)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(null)
+beginMetadataStar(null)
+endMetadataStar(0)
+beginTopLevelMember(null)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'null'., null, {token: null}], null, null)
+handleIdentifier(null, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralNull(null)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(null, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(rethrow)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(rethrow)
+beginMetadataStar(rethrow)
+endMetadataStar(0)
+beginTopLevelMember(rethrow)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleIdentifier(rethrow, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+handleIdentifier(rethrow, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(rethrow, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(rethrow, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(return)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(return)
+beginMetadataStar(return)
+endMetadataStar(0)
+beginTopLevelMember(return)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'return'., null, {token: return}], return, return)
+handleIdentifier(return, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {token: return}], return, return)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(return, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(super)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(super)
+beginMetadataStar(super)
+endMetadataStar(0)
+beginTopLevelMember(super)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'super'., null, {token: super}], super, super)
+handleIdentifier(super, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleSuperExpression(super, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(super, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(super, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(switch)
+beginMetadataStar(switch)
+endMetadataStar(0)
+beginTopLevelMember(switch)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+handleIdentifier(switch, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+handleIdentifier(, expression)
+handleNoTypeArguments(switch)
+handleNoArguments(switch)
+handleSend(, switch)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], switch, switch)
+endReturnStatement(true, return, ;)
+beginSwitchStatement(switch)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
+beginSwitchBlock({)
+endSwitchBlock(0, {, })
+endSwitchStatement(switch, })
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(switch, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+beginTopLevelMethod(}, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(this)
+handleType(int, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+handleIdentifier(this, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleThisExpression(this, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(this, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(int, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(throw)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(throw)
+beginMetadataStar(throw)
+endMetadataStar(0)
+beginTopLevelMember(throw)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'throw'., null, {token: throw}], throw, throw)
+handleIdentifier(throw, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleThrowExpression(throw, ;)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(throw, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(true)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(true)
+beginMetadataStar(true)
+endMetadataStar(0)
+beginTopLevelMember(true)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'true'., null, {token: true}], true, true)
+handleIdentifier(true, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleLiteralBool(true)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend((, ))
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(true, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(try)
+beginMetadataStar(try)
+endMetadataStar(0)
+beginTopLevelMember(try)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+handleIdentifier(try, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+handleIdentifier(, expression)
+handleNoTypeArguments(try)
+handleNoArguments(try)
+handleSend(, try)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], try, try)
+endReturnStatement(true, return, ;)
+beginTryStatement(try)
+handleRecoverableError(Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}], try, try)
+beginBlock({, BlockKind(try statement))
+endBlock(0, {, }, BlockKind(try statement))
+handleRecoverableError(OnlyTry, try, try)
+endTryStatement(0, try, null)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedExpression(()
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(4, {, })
+endTopLevelMethod(try, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(var)
+beginMetadataStar(var)
+endMetadataStar(0)
+beginTopLevelMember(var)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleRecoverableError(VarReturnType, var, var)
+beginTopLevelMethod(;, null)
+handleNoType(var)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'var'., null, {token: var}], var, var)
+handleIdentifier(, expression)
+handleNoTypeArguments(var)
+handleNoArguments(var)
+handleSend(, var)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], var, var)
+endReturnStatement(true, return, ;)
+beginMetadataStar(var)
+endMetadataStar(0)
+handleNoType(var)
+beginVariablesDeclaration((, null, var)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endTopLevelMethod(var, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(void)
+beginMetadataStar(void)
+endMetadataStar(0)
+beginTopLevelMember(void)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+beginTopLevelMethod(;, null)
+handleVoidKeyword(void)
+handleIdentifier(, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'void'., null, {token: void}], void, void)
+handleIdentifier(, expression)
+handleNoTypeArguments(void)
+handleNoArguments(void)
+handleSend(, void)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
+endReturnStatement(true, return, ;)
+beginMetadataStar(void)
+endMetadataStar(0)
+handleVoidKeyword(void)
+beginVariablesDeclaration((, null, null)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+handleIdentifier(, localVariableDeclaration)
+beginInitializedIdentifier()
+handleNoVariableInitializer(x)
+endInitializedIdentifier()
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+endVariablesDeclaration(1, ;)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+handleExpressionStatement(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+handleIdentifier(, expression)
+handleNoTypeArguments())
+handleNoArguments())
+handleSend(, ))
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+handleExpressionStatement(;)
+handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endBlockFunctionBody(6, {, })
+endTopLevelMethod(void, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(while)
+beginMetadataStar(while)
+endMetadataStar(0)
+beginTopLevelMember(while)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+handleIdentifier(while, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+handleIdentifier(, expression)
+handleNoTypeArguments(while)
+handleNoArguments(while)
+handleSend(, while)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], while, while)
+endReturnStatement(true, return, ;)
+beginWhileStatement(while)
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+handleParenthesizedCondition(()
+beginWhileStatementBody(+)
+handleRecoverableError(UnsupportedPrefixPlus, +, +)
+handleIdentifier(, expression)
+handleNoTypeArguments(+)
+handleNoArguments(+)
+handleSend(, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+handleExpressionStatement(;)
+endWhileStatementBody(})
+endWhileStatement(while, })
+endBlockFunctionBody(3, {, })
+endTopLevelMethod(while, null, })
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleRecoverableError(MissingConstFinalVarOrType, int, int)
+handleNoType(})
+handleIdentifier(int, topLevelVariableDeclaration)
+handleNoFieldInitializer(with)
+handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(with)
+beginMetadataStar(with)
+endMetadataStar(0)
+beginTopLevelMember(with)
+beginTopLevelMethod(;, null)
+handleNoType(;)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, topLevelFunctionDeclaration)
+handleNoTypeVariables(()
+beginFormalParameters((, MemberKind.TopLevelMethod)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(x)
+handleType(int, null)
+handleIdentifier(x, formalParameterDeclaration)
+handleFormalParameterWithoutValue())
+endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+handleAsyncModifier(null, null)
+beginBlockFunctionBody({)
+beginIfStatement(if)
+handleIdentifier(x, expression)
+handleNoTypeArguments(==)
+handleNoArguments(==)
+handleSend(x, ==)
+beginBinaryExpression(==)
+handleLiteralInt(0)
+endBinaryExpression(==)
+handleParenthesizedCondition(()
+beginThenStatement(return)
+beginReturnStatement(return)
+handleLiteralInt(42)
+endReturnStatement(true, return, ;)
+endThenStatement(;)
+endIfStatement(if, null)
+beginReturnStatement(return)
+handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+handleIdentifier(with, expression)
+handleNoTypeArguments(()
+beginArguments(()
+handleIdentifier(x, expression)
+handleNoTypeArguments(-)
+handleNoArguments(-)
+handleSend(x, -)
+beginBinaryExpression(-)
+handleLiteralInt(1)
+endBinaryExpression(-)
+endArguments(1, (, ))
+handleSend(with, +)
+beginBinaryExpression(+)
+handleLiteralInt(1)
+endBinaryExpression(+)
+endReturnStatement(true, return, ;)
+endBlockFunctionBody(2, {, })
+endTopLevelMethod(with, null, })
+endTopLevelDeclaration()
+endCompilationUnit(71, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.intertwined.expect
new file mode 100644
index 0000000..90e26b1
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.intertwined.expect
@@ -0,0 +1,5902 @@
+parseUnit(int)
+  skipErrorTokens(int)
+  listener: beginCompilationUnit(int)
+  syntheticPreviousToken(int)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(int)
+      parseFields(, null, null, null, null, null, , Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(assert)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(assert)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(assert)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(assert)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, assert)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(assert, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'assert'., null, {token: assert}], assert, assert)
+          listener: handleIdentifier(assert, topLevelFunctionDeclaration)
+        parseMethodTypeVar(assert)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(assert, assert, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(assert, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseAssert(return, Assert.Expression)
+                          listener: beginAssert(assert, Assert.Expression)
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          reportRecoverableError(assert, AssertAsExpression)
+                            listener: handleRecoverableError(AssertAsExpression, assert, assert)
+                          listener: endAssert(assert, Assert.Expression, (, null, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(assert, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(break)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(break)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(break)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(break)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, break)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+          listener: handleIdentifier(break, topLevelFunctionDeclaration)
+        parseMethodTypeVar(break)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(break, break, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(break, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(break, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'break'., null, {token: break}], break, break)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(break)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(break)
+                          listener: handleSend(, break)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, break)
+          parseStatement(;)
+            parseStatementX(;)
+              parseBreakStatement(;)
+                isBreakAllowed()
+                reportRecoverableError(break, BreakOutsideOfLoop)
+                  listener: handleRecoverableError(BreakOutsideOfLoop, break, break)
+                ensureSemicolon(break)
+                  reportRecoverableError(break, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], break, break)
+                  rewriter()
+                listener: handleBreakStatement(false, break, ;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(break, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(case)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(case)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(case)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(case)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, case)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+          listener: handleIdentifier(case, topLevelFunctionDeclaration)
+        parseMethodTypeVar(case)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(case, case, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(case, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(case, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'case'., null, {token: case}], case, case)
+                            listener: handleIdentifier(case, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(case)
+                            parseArguments(case)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(case, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(case, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(catch)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(catch)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(catch)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(catch)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, catch)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+          listener: handleIdentifier(catch, topLevelFunctionDeclaration)
+        parseMethodTypeVar(catch)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(catch, catch, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(catch, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(catch, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'catch'., null, {token: catch}], catch, catch)
+                            listener: handleIdentifier(catch, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(catch)
+                            parseArguments(catch)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(catch, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(catch, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(class)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(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)
+          reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+          rewriter()
+          listener: handleIdentifier(, classOrMixinDeclaration)
+        listener: handleNoTypeVariables(int)
+        listener: beginClassDeclaration(class, null, )
+        parseClass(, class, class, )
+          parseClassHeaderOpt(, class, class)
+            parseClassExtendsOpt()
+              listener: handleNoType()
+              listener: handleClassExtends(null)
+            parseWithClauseOpt()
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt()
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassHeaderRecovery(, class, class)
+            parseClassHeaderOpt(, class, class)
+              parseClassExtendsOpt()
+              parseWithClauseOpt()
+              parseClassOrMixinImplementsOpt()
+            skipUnexpectedTokenOpt(, [extends, with, implements, {])
+            parseClassExtendsOpt()
+              listener: handleNoType()
+              listener: handleClassExtends(null)
+            parseWithClauseOpt()
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt()
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleRecoverClassHeader()
+          ensureBlock(, null, class declaration)
+            reportRecoverableError(, Message[ExpectedClassOrMixinBody, A class declaration must have a body, even if it is empty., Try adding an empty body., {string: class declaration}])
+              listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A class declaration must have a body, even if it is empty., Try adding an empty body., {string: class declaration}], int, int)
+            insertBlock()
+              rewriter()
+              rewriter()
+          parseClassOrMixinOrExtensionBody(, DeclarationKind.Class, )
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(x)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(x, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer())
+        ensureSemicolon(x)
+          reportRecoverableError(x, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration())
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar())
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember())
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+      listener: handleInvalidTopLevelDeclaration())
+  listener: endTopLevelDeclaration({)
+  parseTopLevelDeclarationImpl(), Instance of 'DirectiveContext')
+    parseMetadataStar())
+      listener: beginMetadataStar({)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember({)
+    parseInvalidTopLevelDeclaration())
+      reportRecoverableErrorWithToken({, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+      parseInvalidBlock())
+        parseBlock(), BlockKind(invalid))
+          ensureBlock(), null, null)
+          listener: beginBlock({, BlockKind(invalid))
+          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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(class, Instance of 'Template<(Token) => Message>')
+                            listener: handleIdentifier(class, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(class)
+                            parseArguments(class)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(class, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlock(2, {, }, BlockKind(invalid))
+        listener: handleInvalidTopLevelBlock({)
+      listener: handleInvalidTopLevelDeclaration(})
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(const)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(const)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(const)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(const)
+      insertSyntheticIdentifier(const, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      reportRecoverableErrorWithToken(const, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'const' here., Try removing 'const'., {token: const}], const, const)
+      parseTopLevelMethod(;, null, const, Instance of 'NoType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(const)
+        ensureIdentifier(const, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseConstExpression(return)
+                          listener: beginConstExpression(const)
+                          parseConstructorReference(const, null)
+                            ensureIdentifier(const, constructorReference)
+                              insertSyntheticIdentifier(const, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], messageOnToken: null)
+                                reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                              listener: handleIdentifier(, constructorReference)
+                            listener: beginConstructorReference()
+                            parseQualifiedRestOpt(, constructorReferenceContinuation)
+                            listener: handleNoTypeArguments(()
+                            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                            listener: endConstructorReference(, null, ()
+                          parseConstructorInvocationArguments()
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: endConstExpression(const)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(const, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(continue)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(continue)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(continue)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(continue)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, continue)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+          listener: handleIdentifier(continue, topLevelFunctionDeclaration)
+        parseMethodTypeVar(continue)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(continue, continue, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(continue, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(continue, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'continue'., null, {token: continue}], continue, continue)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(continue)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(continue)
+                          listener: handleSend(, continue)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, continue)
+          parseStatement(;)
+            parseStatementX(;)
+              parseContinueStatement(;)
+                isContinueAllowed()
+                reportRecoverableError(continue, ContinueOutsideOfLoop)
+                  listener: handleRecoverableError(ContinueOutsideOfLoop, continue, continue)
+                ensureSemicolon(continue)
+                  reportRecoverableError(continue, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], continue, continue)
+                  rewriter()
+                listener: handleContinueStatement(false, continue, ;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(continue, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(default)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(default)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(default)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(default)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, default)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+          listener: handleIdentifier(default, topLevelFunctionDeclaration)
+        parseMethodTypeVar(default)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(default, default, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(default, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(default, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'default'., null, {token: default}], default, default)
+                            listener: handleIdentifier(default, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(default)
+                            parseArguments(default)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(default, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(default, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(do)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(do)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(do)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(do)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, do)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+          listener: handleIdentifier(do, topLevelFunctionDeclaration)
+        parseMethodTypeVar(do)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(do, do, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(do, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(do, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'do'., null, {token: do}], do, do)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(do)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(do)
+                          listener: handleSend(, do)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], do, do)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, do)
+          parseStatement(;)
+            parseStatementX(;)
+              parseDoWhileStatement(;)
+                listener: beginDoWhileStatement(do)
+                listener: beginDoWhileStatementBody(()
+                parseStatement(do)
+                  parseStatementX(do)
+                    parseExpressionStatementOrDeclaration(do, false)
+                      parseExpressionStatementOrDeclarationAfterModifiers(do, do, null, null, null, false)
+                        looksLikeLocalFunction(()
+                        parseExpressionStatement(do)
+                          parseExpression(do)
+                            parsePrecedenceExpression(do, 1, true)
+                              parseUnaryExpression(do, true)
+                                parsePrimary(do, expression)
+                                  parseParenthesizedExpressionOrFunctionLiteral(do)
+                                    parseParenthesizedExpression(do)
+                                      parseExpressionInParenthesis(do)
+                                        parseExpressionInParenthesisRest(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          ensureCloseParen(1, ()
+                                      listener: handleParenthesizedExpression(()
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: handleExpressionStatement(;)
+                listener: endDoWhileStatementBody(;)
+                reportRecoverableError(}, Message[ExpectedButGot, Expected 'while' before this., null, {string: while}])
+                  listener: handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
+                rewriter()
+                ensureParenthesizedCondition(while)
+                  reportRecoverableError(}, Message[ExpectedToken, Expected to find '('., null, {string: (}])
+                    listener: handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
+                  rewriter()
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSend((, expression)
+                              ensureIdentifier((, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '}'., null, {token: }}], }, })
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureCloseParen(, ()
+                  listener: handleParenthesizedCondition(()
+                ensureSemicolon())
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                  rewriter()
+                listener: endDoWhileStatement(do, while, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(do, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(else)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(else)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(else)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(else)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, else)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+          listener: handleIdentifier(else, topLevelFunctionDeclaration)
+        parseMethodTypeVar(else)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(else, else, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(else, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(else)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(else)
+                          listener: handleSend(, else)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, else)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(else)
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            inPlainSync()
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(else, Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'else'., null, {token: else}], else, else)
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments(else)
+                              parseArgumentsOpt()
+                                listener: handleNoArguments(else)
+                              listener: handleSend(, else)
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], else, else)
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], else, else)
+          notEofOrValue(}, ()
+          parseStatement(else)
+            parseStatementX(else)
+              parseExpressionStatementOrDeclaration(else, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(else, else, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(else)
+                    parseExpression(else)
+                      parsePrecedenceExpression(else, 1, true)
+                        parseUnaryExpression(else, true)
+                          parsePrimary(else, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(else)
+                              parseParenthesizedExpression(else)
+                                parseExpressionInParenthesis(else)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(else, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(enum)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, enum, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, enum)
+      parseEnum(enum)
+        listener: beginEnum(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+          rewriter()
+          listener: handleIdentifier(, enumDeclaration)
+        ensureBlock(, Instance of 'Template<(Token) => Message>', null)
+          reportRecoverableError(int, Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {token: int}])
+            listener: handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {token: int}], int, int)
+          insertBlock()
+            rewriter()
+            rewriter()
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(x)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(x, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer())
+        ensureSemicolon(x)
+          reportRecoverableError(x, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration())
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar())
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember())
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ')'., null, {token: )}], ), ))
+      listener: handleInvalidTopLevelDeclaration())
+  listener: endTopLevelDeclaration({)
+  parseTopLevelDeclarationImpl(), Instance of 'DirectiveContext')
+    parseMetadataStar())
+      listener: beginMetadataStar({)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember({)
+    parseInvalidTopLevelDeclaration())
+      reportRecoverableErrorWithToken({, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '{'., null, {token: {}], {, {)
+      parseInvalidBlock())
+        parseBlock(), BlockKind(invalid))
+          ensureBlock(), null, null)
+          listener: beginBlock({, BlockKind(invalid))
+          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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                            listener: handleIdentifier(enum, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(enum)
+                            parseArguments(enum)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(enum, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlock(2, {, }, BlockKind(invalid))
+        listener: handleInvalidTopLevelBlock({)
+      listener: handleInvalidTopLevelDeclaration(})
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(extends)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(extends)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(extends)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(extends)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, extends)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+          listener: handleIdentifier(extends, topLevelFunctionDeclaration)
+        parseMethodTypeVar(extends)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(extends, extends, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(extends, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(extends, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'extends'., null, {token: extends}], extends, extends)
+                            listener: handleIdentifier(extends, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(extends)
+                            parseArguments(extends)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(extends, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(extends, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(false)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(false)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(false)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(false)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, false)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(false, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'false'., null, {token: false}], false, false)
+          listener: handleIdentifier(false, topLevelFunctionDeclaration)
+        parseMethodTypeVar(false)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(false, false, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(false, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseLiteralBool(return)
+                          listener: handleLiteralBool(false)
+                    parseArgumentOrIndexStar(false, Instance of 'NoTypeParamOrArg', false)
+                      listener: handleNoTypeArguments(()
+                      parseArguments(false)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          listener: endArguments(1, (, ))
+                      listener: handleSend((, ))
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(false, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(final)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(final)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(final)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(final)
+      insertSyntheticIdentifier(final, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExtraneousModifier, Can't have modifier 'final' here., Try removing 'final'., {token: final}], final, final)
+      parseTopLevelMethod(;, null, final, Instance of 'NoType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(final)
+        ensureIdentifier(final, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(final, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'final'., null, {token: final}], final, final)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(final)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(final)
+                          listener: handleSend(, final)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], final, final)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, final)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(final, ;, null, final, null, false)
+                looksLikeLocalFunction(()
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+                listener: handleNoType(final)
+                listener: beginVariablesDeclaration((, null, final)
+                parseVariablesDeclarationRest(final, true)
+                  parseOptionallyInitializedIdentifier(final)
+                    ensureIdentifier(final, localVariableDeclaration)
+                      reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                      listener: handleIdentifier(, localVariableDeclaration)
+                    listener: beginInitializedIdentifier()
+                    parseVariableInitializerOpt()
+                      listener: handleNoVariableInitializer(x)
+                    listener: endInitializedIdentifier()
+                  ensureSemicolon()
+                    reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                    rewriter()
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, x)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(x)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  ensureSemicolon(1)
+                    reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                    rewriter()
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, ))
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction())
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+          notEofOrValue(}, +)
+          parseStatement())
+            parseStatementX())
+              parseExpressionStatementOrDeclaration(), false)
+                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement())
+                    parseExpression())
+                      parsePrecedenceExpression(), 1, true)
+                        parseUnaryExpression(), true)
+                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(), expression)
+                            parseSendOrFunctionLiteral(), expression)
+                              parseSend(), expression)
+                                ensureIdentifier(), expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(final, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(finally)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(finally)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(finally)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(finally)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, finally)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+          listener: handleIdentifier(finally, topLevelFunctionDeclaration)
+        parseMethodTypeVar(finally)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(finally, finally, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(finally, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(finally, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'finally'., null, {token: finally}], finally, finally)
+                            listener: handleIdentifier(finally, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(finally)
+                            parseArguments(finally)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(finally, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(finally, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(for)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(for)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(for)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(for)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, for)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+          listener: handleIdentifier(for, topLevelFunctionDeclaration)
+        parseMethodTypeVar(for)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(for, for, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(for, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(for, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'for'., null, {token: for}], for, for)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(for)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(for)
+                          listener: handleSend(, for)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], for, for)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, for)
+          parseStatement(;)
+            parseStatementX(;)
+              parseForStatement(;, null)
+                listener: beginForStatement(for)
+                parseForLoopPartsStart(null, for)
+                  parseExpressionStatementOrDeclaration((, true)
+                    parseExpressionStatementOrDeclarationAfterModifiers((, (, null, null, null, true)
+                parseForLoopPartsMid((, null, for)
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseSendOrFunctionLiteral((, expression)
+                            parseSend((, expression)
+                              ensureIdentifier((, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  listener: handleForInitializerExpressionStatement(1, false)
+                parseForRest(null, 1, for)
+                  parseForLoopPartsRest(1, for, null)
+                    ensureSemicolon(1)
+                      reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                      rewriter()
+                    parseExpressionStatement(;)
+                      parseExpression(;)
+                        parsePrecedenceExpression(;, 1, true)
+                          parseUnaryExpression(;, true)
+                            parsePrimary(;, expression)
+                              parseSend(;, expression)
+                                ensureIdentifier(;, expression)
+                                  reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                    listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                  rewriter()
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments())
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments())
+                                listener: handleSend(, ))
+                      ensureSemicolon()
+                        reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                          listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                        rewriter()
+                      listener: handleExpressionStatement(;)
+                    listener: handleForLoopParts(for, (, ;, 0)
+                  listener: beginForStatementBody(+)
+                  parseStatement())
+                    parseStatementX())
+                      parseExpressionStatementOrDeclaration(), false)
+                        parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                          looksLikeLocalFunction(+)
+                          parseExpressionStatement())
+                            parseExpression())
+                              parsePrecedenceExpression(), 1, true)
+                                parseUnaryExpression(), true)
+                                  rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                    reportRecoverableError(+, UnsupportedPrefixPlus)
+                                      listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                    rewriter()
+                                  parsePrimary(), expression)
+                                    parseSendOrFunctionLiteral(), expression)
+                                      parseSend(), expression)
+                                        ensureIdentifier(), expression)
+                                          listener: handleIdentifier(, expression)
+                                        listener: handleNoTypeArguments(+)
+                                        parseArgumentsOpt()
+                                          listener: handleNoArguments(+)
+                                        listener: handleSend(, +)
+                                listener: beginBinaryExpression(+)
+                                parsePrecedenceExpression(+, 14, true)
+                                  parseUnaryExpression(+, true)
+                                    parsePrimary(+, expression)
+                                      parseLiteralInt(+)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(+)
+                            ensureSemicolon(1)
+                            listener: handleExpressionStatement(;)
+                  listener: endForStatementBody(})
+                  listener: endForStatement(})
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(for, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(if)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(if)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(if)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(if)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, if)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+          listener: handleIdentifier(if, topLevelFunctionDeclaration)
+        parseMethodTypeVar(if)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(if, if, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(if, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., null, {token: if}], if, if)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(if)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(if)
+                          listener: handleSend(, if)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], if, if)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          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(x, expression)
+                                listener: handleNoTypeArguments(-)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(-)
+                                listener: handleSend(x, -)
+                        listener: beginBinaryExpression(-)
+                        parsePrecedenceExpression(-, 14, true)
+                          parseUnaryExpression(-, true)
+                            parsePrimary(-, expression)
+                              parseLiteralInt(-)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(-)
+                    ensureCloseParen(1, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(+)
+                parseStatement())
+                  parseStatementX())
+                    parseExpressionStatementOrDeclaration(), false)
+                      parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                        looksLikeLocalFunction(+)
+                        parseExpressionStatement())
+                          parseExpression())
+                            parsePrecedenceExpression(), 1, true)
+                              parseUnaryExpression(), true)
+                                rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                  reportRecoverableError(+, UnsupportedPrefixPlus)
+                                    listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                  rewriter()
+                                parsePrimary(), expression)
+                                  parseSendOrFunctionLiteral(), expression)
+                                    parseSend(), expression)
+                                      ensureIdentifier(), expression)
+                                        listener: handleIdentifier(, expression)
+                                      listener: handleNoTypeArguments(+)
+                                      parseArgumentsOpt()
+                                        listener: handleNoArguments(+)
+                                      listener: handleSend(, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: handleExpressionStatement(;)
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(if, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(in)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(in)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(in)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(in)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, in)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+          listener: handleIdentifier(in, topLevelFunctionDeclaration)
+        parseMethodTypeVar(in)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(in, in, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(in, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(in, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'in'., null, {token: in}], in, in)
+                            listener: handleIdentifier(in, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(in)
+                            parseArguments(in)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(in, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(in, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(is)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(is)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(is)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(is)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, is)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+          listener: handleIdentifier(is, topLevelFunctionDeclaration)
+        parseMethodTypeVar(is)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(is, is, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(is, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(is, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'is'., null, {token: is}], is, is)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(is)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(is)
+                          listener: handleSend(, is)
+                    parseIsOperatorRest()
+                      listener: beginIsOperatorType(is)
+                      computeTypeAfterIsOrAs(is)
+                      reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                      listener: handleIdentifier(, typeReference)
+                      listener: handleNoTypeArguments(()
+                      listener: handleType(, null)
+                      listener: endIsOperatorType(is)
+                      listener: handleIsOperator(is, null)
+                      skipChainedAsIsOperators()
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(is, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(new)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(new)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(new)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(new)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, new)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(new, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'new'., null, {token: new}], new, new)
+          listener: handleIdentifier(new, topLevelFunctionDeclaration)
+        parseMethodTypeVar(new)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(new, new, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(new, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseNewExpression(return)
+                          listener: beginNewExpression(new)
+                          parseConstructorReference(new, null)
+                            ensureIdentifier(new, constructorReference)
+                              insertSyntheticIdentifier(new, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], messageOnToken: null)
+                                reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                                rewriter()
+                              listener: handleIdentifier(, constructorReference)
+                            listener: beginConstructorReference()
+                            parseQualifiedRestOpt(, constructorReferenceContinuation)
+                            listener: handleNoTypeArguments(()
+                            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                            listener: endConstructorReference(, null, ()
+                          parseConstructorInvocationArguments()
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: endNewExpression(new)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(new, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(null)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(null)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(null)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(null)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, null)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(null, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'null'., null, {token: null}], null, null)
+          listener: handleIdentifier(null, topLevelFunctionDeclaration)
+        parseMethodTypeVar(null)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(null, null, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(null, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseLiteralNull(return)
+                          listener: handleLiteralNull(null)
+                    parseArgumentOrIndexStar(null, Instance of 'NoTypeParamOrArg', false)
+                      listener: handleNoTypeArguments(()
+                      parseArguments(null)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          listener: endArguments(1, (, ))
+                      listener: handleSend((, ))
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(null, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(rethrow)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(rethrow)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(rethrow)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(rethrow)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, rethrow)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+          listener: handleIdentifier(rethrow, topLevelFunctionDeclaration)
+        parseMethodTypeVar(rethrow)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(rethrow, rethrow, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(rethrow, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(rethrow, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'rethrow'., null, {token: rethrow}], rethrow, rethrow)
+                            listener: handleIdentifier(rethrow, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(rethrow)
+                            parseArguments(rethrow)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(rethrow, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(rethrow, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(return)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(return)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(return)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(return)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, return)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'return'., null, {token: return}], return, return)
+          listener: handleIdentifier(return, topLevelFunctionDeclaration)
+        parseMethodTypeVar(return)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(return, return, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(return, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        reportRecoverableErrorWithToken(return, Instance of 'Template<(Token) => Message>')
+                          listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {token: return}], return, return)
+                        parsePrimary(return, expression)
+                          parseParenthesizedExpressionOrFunctionLiteral(return)
+                            parseParenthesizedExpression(return)
+                              parseExpressionInParenthesis(return)
+                                parseExpressionInParenthesisRest(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  ensureCloseParen(1, ()
+                              listener: handleParenthesizedExpression(()
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(return, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(super)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(super)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(super)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(super)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, super)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(super, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'super'., null, {token: super}], super, super)
+          listener: handleIdentifier(super, topLevelFunctionDeclaration)
+        parseMethodTypeVar(super)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(super, super, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(super, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseSuperExpression(return, expression)
+                          listener: handleSuperExpression(super, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArguments(super)
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: handleSend(super, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(super, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(switch)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(switch)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(switch)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(switch)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, switch)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+          listener: handleIdentifier(switch, topLevelFunctionDeclaration)
+        parseMethodTypeVar(switch)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(switch, switch, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(switch, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(switch, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'switch'., null, {token: switch}], switch, switch)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(switch)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(switch)
+                          listener: handleSend(, switch)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], switch, switch)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, switch)
+          parseStatement(;)
+            parseStatementX(;)
+              parseSwitchStatement(;)
+                listener: beginSwitchStatement(switch)
+                ensureParenthesizedCondition(switch)
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSendOrFunctionLiteral((, expression)
+                              parseSend((, expression)
+                                ensureIdentifier((, expression)
+                                  listener: handleIdentifier(x, expression)
+                                listener: handleNoTypeArguments(-)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(-)
+                                listener: handleSend(x, -)
+                        listener: beginBinaryExpression(-)
+                        parsePrecedenceExpression(-, 14, true)
+                          parseUnaryExpression(-, true)
+                            parsePrimary(-, expression)
+                              parseLiteralInt(-)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(-)
+                    ensureCloseParen(1, ()
+                  listener: handleParenthesizedCondition(()
+                parseSwitchBlock())
+                  ensureBlock(), null, switch statement)
+                    reportRecoverableError(), Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}])
+                      listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
+                    insertBlock())
+                      rewriter()
+                      rewriter()
+                  listener: beginSwitchBlock({)
+                  notEofOrValue(}, })
+                  listener: endSwitchBlock(0, {, })
+                listener: endSwitchStatement(switch, })
+          notEofOrValue(}, +)
+          parseStatement(})
+            parseStatementX(})
+              parseExpressionStatementOrDeclaration(}, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement(})
+                    parseExpression(})
+                      parsePrecedenceExpression(}, 1, true)
+                        parseUnaryExpression(}, true)
+                          rewriteAndRecover(}, UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(}, expression)
+                            parseSendOrFunctionLiteral(}, expression)
+                              parseSend(}, expression)
+                                ensureIdentifier(}, expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(switch, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, this)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(this)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(this, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'this'., null, {token: this}], this, this)
+          listener: handleIdentifier(this, topLevelFunctionDeclaration)
+        parseMethodTypeVar(this)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(this, this, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(this, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseThisExpression(return, expression)
+                          listener: handleThisExpression(this, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArguments(this)
+                            parseArgumentsRest(()
+                              listener: beginArguments(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseSendOrFunctionLiteral((, expression)
+                                        parseSend((, expression)
+                                          ensureIdentifier((, expression)
+                                            listener: handleIdentifier(x, expression)
+                                          listener: handleNoTypeArguments(-)
+                                          parseArgumentsOpt(x)
+                                            listener: handleNoArguments(-)
+                                          listener: handleSend(x, -)
+                                  listener: beginBinaryExpression(-)
+                                  parsePrecedenceExpression(-, 14, true)
+                                    parseUnaryExpression(-, true)
+                                      parsePrimary(-, expression)
+                                        parseLiteralInt(-)
+                                          listener: handleLiteralInt(1)
+                                  listener: endBinaryExpression(-)
+                              listener: endArguments(1, (, ))
+                          listener: handleSend(this, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(throw)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(throw)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(throw)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(throw)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, throw)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(throw, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'throw'., null, {token: throw}], throw, throw)
+          listener: handleIdentifier(throw, topLevelFunctionDeclaration)
+        parseMethodTypeVar(throw)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(throw, throw, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(throw, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parseThrowExpression(return, true)
+                    parseExpression(throw)
+                      parsePrecedenceExpression(throw, 1, true)
+                        parseUnaryExpression(throw, true)
+                          parsePrimary(throw, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(throw)
+                              parseParenthesizedExpression(throw)
+                                parseExpressionInParenthesis(throw)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    listener: handleThrowExpression(throw, ;)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(throw, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(true)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(true)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(true)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(true)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, true)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(true, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'true'., null, {token: true}], true, true)
+          listener: handleIdentifier(true, topLevelFunctionDeclaration)
+        parseMethodTypeVar(true)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(true, true, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(true, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseLiteralBool(return)
+                          listener: handleLiteralBool(true)
+                    parseArgumentOrIndexStar(true, Instance of 'NoTypeParamOrArg', false)
+                      listener: handleNoTypeArguments(()
+                      parseArguments(true)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseSendOrFunctionLiteral((, expression)
+                                    parseSend((, expression)
+                                      ensureIdentifier((, expression)
+                                        listener: handleIdentifier(x, expression)
+                                      listener: handleNoTypeArguments(-)
+                                      parseArgumentsOpt(x)
+                                        listener: handleNoArguments(-)
+                                      listener: handleSend(x, -)
+                              listener: beginBinaryExpression(-)
+                              parsePrecedenceExpression(-, 14, true)
+                                parseUnaryExpression(-, true)
+                                  parsePrimary(-, expression)
+                                    parseLiteralInt(-)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(-)
+                          listener: endArguments(1, (, ))
+                      listener: handleSend((, ))
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(true, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(try)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(try)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(try)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(try)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, try)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+          listener: handleIdentifier(try, topLevelFunctionDeclaration)
+        parseMethodTypeVar(try)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(try, try, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(try, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(try, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'try'., null, {token: try}], try, try)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(try)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(try)
+                          listener: handleSend(, try)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], try, try)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, try)
+          parseStatement(;)
+            parseStatementX(;)
+              parseTryStatement(;)
+                listener: beginTryStatement(try)
+                parseBlock(try, BlockKind(try statement))
+                  ensureBlock(try, null, try statement)
+                    reportRecoverableError(try, Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}])
+                      listener: handleRecoverableError(Message[ExpectedClassOrMixinBody, A try statement must have a body, even if it is empty., Try adding an empty body., {string: try statement}], try, try)
+                    insertBlock(try)
+                      rewriter()
+                      rewriter()
+                  listener: beginBlock({, BlockKind(try statement))
+                  notEofOrValue(}, })
+                  listener: endBlock(0, {, }, BlockKind(try statement))
+                reportRecoverableError(try, OnlyTry)
+                  listener: handleRecoverableError(OnlyTry, try, try)
+                listener: endTryStatement(0, try, null)
+          notEofOrValue(}, ()
+          parseStatement(})
+            parseStatementX(})
+              parseExpressionStatementOrDeclaration(}, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(})
+                    parseExpression(})
+                      parsePrecedenceExpression(}, 1, true)
+                        parseUnaryExpression(}, true)
+                          parsePrimary(}, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(})
+                              parseParenthesizedExpression(})
+                                parseExpressionInParenthesis(})
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 14, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(try, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(var)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(var)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(var)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(var)
+      insertSyntheticIdentifier(var, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      reportRecoverableError(var, VarReturnType)
+        listener: handleRecoverableError(VarReturnType, var, var)
+      parseTopLevelMethod(;, null, var, Instance of 'NoType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(var)
+        ensureIdentifier(var, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(var, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'var'., null, {token: var}], var, var)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(var)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(var)
+                          listener: handleSend(, var)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], var, var)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(()
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration((, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                      rewriter()
+                      listener: handleIdentifier(, localVariableDeclaration)
+                    listener: beginInitializedIdentifier()
+                    parseVariableInitializerOpt()
+                      listener: handleNoVariableInitializer(x)
+                    listener: endInitializedIdentifier()
+                  ensureSemicolon()
+                    reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                    rewriter()
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, x)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(x)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  ensureSemicolon(1)
+                    reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                    rewriter()
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, ))
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction())
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+          notEofOrValue(}, +)
+          parseStatement())
+            parseStatementX())
+              parseExpressionStatementOrDeclaration(), false)
+                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement())
+                    parseExpression())
+                      parsePrecedenceExpression(), 1, true)
+                        parseUnaryExpression(), true)
+                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(), expression)
+                            parseSendOrFunctionLiteral(), expression)
+                              parseSend(), expression)
+                                ensureIdentifier(), expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(var, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(void)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(void)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(void)
+      insertSyntheticIdentifier(void, methodDeclaration, message: null, messageOnToken: null)
+        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}])
+          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+        rewriter()
+      parseTopLevelMethod(;, null, ;, Instance of 'VoidType', null, )
+        listener: beginTopLevelMethod(;, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifier(void, topLevelFunctionDeclaration)
+          listener: handleIdentifier(, topLevelFunctionDeclaration)
+        parseMethodTypeVar()
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(, , false, MemberKind.TopLevelMethod)
+          parseFormalParameters(, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        parseSendOrFunctionLiteral(return, expression)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              reportRecoverableErrorWithToken(void, Instance of 'Template<(Token) => Message>')
+                                listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'void'., null, {token: void}], void, void)
+                              rewriter()
+                              listener: handleIdentifier(, expression)
+                            listener: handleNoTypeArguments(void)
+                            parseArgumentsOpt()
+                              listener: handleNoArguments(void)
+                            listener: handleSend(, void)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, void)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  listener: beginMetadataStar(void)
+                  listener: endMetadataStar(0)
+                  listener: handleVoidKeyword(void)
+                  listener: beginVariablesDeclaration((, null, null)
+                  parseVariablesDeclarationRest(void, true)
+                    parseOptionallyInitializedIdentifier(void)
+                      ensureIdentifier(void, localVariableDeclaration)
+                        reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
+                          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., null, {token: (}], (, ()
+                        rewriter()
+                        listener: handleIdentifier(, localVariableDeclaration)
+                      listener: beginInitializedIdentifier()
+                      parseVariableInitializerOpt()
+                        listener: handleNoVariableInitializer(x)
+                      listener: endInitializedIdentifier()
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], x, x)
+                      rewriter()
+                    listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, x)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(x)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(x, expression)
+                              listener: handleNoTypeArguments(-)
+                              parseArgumentsOpt(x)
+                                listener: handleNoArguments(-)
+                              listener: handleSend(x, -)
+                      listener: beginBinaryExpression(-)
+                      parsePrecedenceExpression(-, 14, true)
+                        parseUnaryExpression(-, true)
+                          parsePrimary(-, expression)
+                            parseLiteralInt(-)
+                              listener: handleLiteralInt(1)
+                      listener: endBinaryExpression(-)
+                  ensureSemicolon(1)
+                    reportRecoverableError(1, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], 1, 1)
+                    rewriter()
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, ))
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction())
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., null, {token: )}], ), ))
+                                rewriter()
+                                listener: handleIdentifier(, expression)
+                              listener: handleNoTypeArguments())
+                              parseArgumentsOpt()
+                                listener: handleNoArguments())
+                              listener: handleSend(, ))
+                    ensureSemicolon()
+                      reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                        listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), ))
+                      rewriter()
+                    listener: handleExpressionStatement(;)
+          reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}])
+            listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {token: ;}], ), ))
+          notEofOrValue(}, +)
+          parseStatement())
+            parseStatementX())
+              parseExpressionStatementOrDeclaration(), false)
+                parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                  looksLikeLocalFunction(+)
+                  parseExpressionStatement())
+                    parseExpression())
+                      parsePrecedenceExpression(), 1, true)
+                        parseUnaryExpression(), true)
+                          rewriteAndRecover(), UnsupportedPrefixPlus, )
+                            reportRecoverableError(+, UnsupportedPrefixPlus)
+                              listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                            rewriter()
+                          parsePrimary(), expression)
+                            parseSendOrFunctionLiteral(), expression)
+                              parseSend(), expression)
+                                ensureIdentifier(), expression)
+                                  listener: handleIdentifier(, expression)
+                                listener: handleNoTypeArguments(+)
+                                parseArgumentsOpt()
+                                  listener: handleNoArguments(+)
+                                listener: handleSend(, +)
+                        listener: beginBinaryExpression(+)
+                        parsePrecedenceExpression(+, 14, true)
+                          parseUnaryExpression(+, true)
+                            parsePrimary(+, expression)
+                              parseLiteralInt(+)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(+)
+                    ensureSemicolon(1)
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(while)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(while)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(while)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(while)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, while)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+          listener: handleIdentifier(while, topLevelFunctionDeclaration)
+        parseMethodTypeVar(while)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(while, while, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(while, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(while, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'while'., null, {token: while}], while, while)
+                            rewriter()
+                            listener: handleIdentifier(, expression)
+                          listener: handleNoTypeArguments(while)
+                          parseArgumentsOpt()
+                            listener: handleNoArguments(while)
+                          listener: handleSend(, while)
+                ensureSemicolon()
+                  reportRecoverableError(, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], while, while)
+                  rewriter()
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, while)
+          parseStatement(;)
+            parseStatementX(;)
+              parseWhileStatement(;)
+                listener: beginWhileStatement(while)
+                ensureParenthesizedCondition(while)
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSendOrFunctionLiteral((, expression)
+                              parseSend((, expression)
+                                ensureIdentifier((, expression)
+                                  listener: handleIdentifier(x, expression)
+                                listener: handleNoTypeArguments(-)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(-)
+                                listener: handleSend(x, -)
+                        listener: beginBinaryExpression(-)
+                        parsePrecedenceExpression(-, 14, true)
+                          parseUnaryExpression(-, true)
+                            parsePrimary(-, expression)
+                              parseLiteralInt(-)
+                                listener: handleLiteralInt(1)
+                        listener: endBinaryExpression(-)
+                    ensureCloseParen(1, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginWhileStatementBody(+)
+                parseStatement())
+                  parseStatementX())
+                    parseExpressionStatementOrDeclaration(), false)
+                      parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                        looksLikeLocalFunction(+)
+                        parseExpressionStatement())
+                          parseExpression())
+                            parsePrecedenceExpression(), 1, true)
+                              parseUnaryExpression(), true)
+                                rewriteAndRecover(), UnsupportedPrefixPlus, )
+                                  reportRecoverableError(+, UnsupportedPrefixPlus)
+                                    listener: handleRecoverableError(UnsupportedPrefixPlus, +, +)
+                                  rewriter()
+                                parsePrimary(), expression)
+                                  parseSendOrFunctionLiteral(), expression)
+                                    parseSend(), expression)
+                                      ensureIdentifier(), expression)
+                                        listener: handleIdentifier(, expression)
+                                      listener: handleNoTypeArguments(+)
+                                      parseArgumentsOpt()
+                                        listener: handleNoArguments(+)
+                                      listener: handleSend(, +)
+                              listener: beginBinaryExpression(+)
+                              parsePrecedenceExpression(+, 14, true)
+                                parseUnaryExpression(+, true)
+                                  parsePrimary(+, expression)
+                                    parseLiteralInt(+)
+                                      listener: handleLiteralInt(1)
+                              listener: endBinaryExpression(+)
+                          ensureSemicolon(1)
+                          listener: handleExpressionStatement(;)
+                listener: endWhileStatementBody(})
+                listener: endWhileStatement(while, })
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(while, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseFields(}, null, null, null, null, null, }, Instance of 'NoType', int, DeclarationKind.TopLevel, null)
+        reportRecoverableError(int, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, int, int)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelVariableDeclaration)
+          listener: handleIdentifier(int, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(int, int, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(with)
+        ensureSemicolon(int)
+          reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(with)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(with)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(with)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, with)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+          listener: handleIdentifier(with, topLevelFunctionDeclaration)
+        parseMethodTypeVar(with)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(with, with, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(with, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSend(return, expression)
+                          ensureIdentifier(return, expression)
+                            reportRecoverableErrorWithToken(with, Instance of 'Template<(Token) => Message>')
+                              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'with'., null, {token: with}], with, with)
+                            listener: handleIdentifier(with, expression)
+                          listener: handleNoTypeArguments(()
+                          parseArgumentsOpt(with)
+                            parseArguments(with)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                parseExpression(()
+                                  parsePrecedenceExpression((, 1, true)
+                                    parseUnaryExpression((, true)
+                                      parsePrimary((, expression)
+                                        parseSendOrFunctionLiteral((, expression)
+                                          parseSend((, expression)
+                                            ensureIdentifier((, expression)
+                                              listener: handleIdentifier(x, expression)
+                                            listener: handleNoTypeArguments(-)
+                                            parseArgumentsOpt(x)
+                                              listener: handleNoArguments(-)
+                                            listener: handleSend(x, -)
+                                    listener: beginBinaryExpression(-)
+                                    parsePrecedenceExpression(-, 14, true)
+                                      parseUnaryExpression(-, true)
+                                        parsePrimary(-, expression)
+                                          parseLiteralInt(-)
+                                            listener: handleLiteralInt(1)
+                                    listener: endBinaryExpression(-)
+                                listener: endArguments(1, (, ))
+                          listener: handleSend(with, +)
+                    listener: beginBinaryExpression(+)
+                    parsePrecedenceExpression(+, 14, true)
+                      parseUnaryExpression(+, true)
+                        parsePrimary(+, expression)
+                          parseLiteralInt(+)
+                            listener: handleLiteralInt(1)
+                    listener: endBinaryExpression(+)
+                ensureSemicolon(1)
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(with, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(int)
+  listener: endCompilationUnit(71, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.parser.expect
new file mode 100644
index 0000000..1dc529d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.parser.expect
@@ -0,0 +1,333 @@
+NOTICE: Stream was rewritten by parser!
+
+int ;assert(int x) {
+if (x == 0) return 42;
+return assert(x-1) + 1;
+}
+
+int ;break(int x) {
+if (x == 0) return 42;
+return ;break;(x-1) + 1;
+}
+
+int ;case(int x) {
+if (x == 0) return 42;
+return case(x-1) + 1;
+}
+
+int ;catch(int x) {
+if (x == 0) return 42;
+return catch(x-1) + 1;
+}
+
+int ;class({}int x;) {
+if (x == 0) return 42;
+return class(x-1) + 1;
+}
+
+int ;const(int x) {
+if (x == 0) return 42;
+return const(x-1) + 1;
+}
+
+int ;continue(int x) {
+if (x == 0) return 42;
+return ;continue;(x-1) + 1;
+}
+
+int ;default(int x) {
+if (x == 0) return 42;
+return default(x-1) + 1;
+}
+
+int ;do(int x) {
+if (x == 0) return 42;
+return ;do(x-1) + 1;
+while();}
+
+int ;else(int x) {
+if (x == 0) return 42;
+return ;;else(x-1) + 1;
+}
+
+int ;enum({}int x;) {
+if (x == 0) return 42;
+return enum(x-1) + 1;
+}
+
+int ;extends(int x) {
+if (x == 0) return 42;
+return extends(x-1) + 1;
+}
+
+int ;false(int x) {
+if (x == 0) return 42;
+return false(x-1) + 1;
+}
+
+int ;final(int x) {
+if (x == 0) return 42;
+return ;final(;x-1;;) + 1;
+}
+
+int ;finally(int x) {
+if (x == 0) return 42;
+return finally(x-1) + 1;
+}
+
+int ;for(int x) {
+if (x == 0) return 42;
+return ;for(x-1;;) + 1;
+}
+
+int ;if(int x) {
+if (x == 0) return 42;
+return ;if(x-1) + 1;
+}
+
+int ;in(int x) {
+if (x == 0) return 42;
+return in(x-1) + 1;
+}
+
+int ;is(int x) {
+if (x == 0) return 42;
+return is;(x-1) + 1;
+}
+
+int ;new(int x) {
+if (x == 0) return 42;
+return new(x-1) + 1;
+}
+
+int ;null(int x) {
+if (x == 0) return 42;
+return null(x-1) + 1;
+}
+
+int ;rethrow(int x) {
+if (x == 0) return 42;
+return rethrow(x-1) + 1;
+}
+
+int ;return(int x) {
+if (x == 0) return 42;
+return return(x-1) + 1;
+}
+
+int ;super(int x) {
+if (x == 0) return 42;
+return super(x-1) + 1;
+}
+
+int ;switch(int x) {
+if (x == 0) return 42;
+return ;switch(x-1) {}+ 1;
+}
+
+int this(int x) {
+if (x == 0) return 42;
+return this(x-1) + 1;
+}
+
+int ;throw(int x) {
+if (x == 0) return 42;
+return throw(x-1) + 1;
+}
+
+int ;true(int x) {
+if (x == 0) return 42;
+return true(x-1) + 1;
+}
+
+int ;try(int x) {
+if (x == 0) return 42;
+return ;try{}(x-1) + 1;
+}
+
+int ;var(int x) {
+if (x == 0) return 42;
+return ;var(;x-1;;) + 1;
+}
+
+int ;void(int x) {
+if (x == 0) return 42;
+return ;void(;x-1;;) + 1;
+}
+
+int ;while(int x) {
+if (x == 0) return 42;
+return ;while(x-1) + 1;
+}
+
+int ;with(int x) {
+if (x == 0) return 42;
+return with(x-1) + 1;
+}
+
+
+int[StringToken] ;[SyntheticToken]assert[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] assert[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]break[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]break[KeywordToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]case[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] case[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]catch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] catch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]class[KeywordToken]([BeginToken][SyntheticStringToken]{[SyntheticBeginToken]}[SyntheticToken]int[StringToken] x[StringToken];[SyntheticToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] class[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]const[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]continue[KeywordToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]default[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] default[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]do[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]do[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+while[SyntheticKeywordToken]([SyntheticBeginToken][SyntheticStringToken])[SyntheticToken];[SyntheticToken]}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]else[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken]else[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]enum[KeywordToken]([BeginToken][SyntheticStringToken]{[SyntheticBeginToken]}[SyntheticToken]int[StringToken] x[StringToken];[SyntheticToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] enum[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]extends[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] extends[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]false[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] false[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]final[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]final[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]finally[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] finally[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]for[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]for[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]if[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]if[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]in[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] in[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]is[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken]is[KeywordToken][SyntheticStringToken];[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]new[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] new[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]null[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] null[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]rethrow[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] rethrow[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]return[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] return[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]super[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] super[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]switch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]switch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] {[SyntheticBeginToken]}[SyntheticToken][SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] this[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] this[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]throw[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] throw[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]true[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] true[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]try[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]try[KeywordToken]{[SyntheticBeginToken]}[SyntheticToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]var[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]var[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]void[KeywordToken][SyntheticStringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]void[KeywordToken]([BeginToken][SyntheticStringToken];[SyntheticToken]x[StringToken]-[SimpleToken]1[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]while[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] [SyntheticStringToken];[SyntheticToken]while[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] [SyntheticStringToken]+[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] ;[SyntheticToken]with[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] with[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.scanner.expect
new file mode 100644
index 0000000..896ca86
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/reserved_words_top_level_methods.dart.scanner.expect
@@ -0,0 +1,331 @@
+int assert(int x) {
+if (x == 0) return 42;
+return assert(x-1) + 1;
+}
+
+int break(int x) {
+if (x == 0) return 42;
+return break(x-1) + 1;
+}
+
+int case(int x) {
+if (x == 0) return 42;
+return case(x-1) + 1;
+}
+
+int catch(int x) {
+if (x == 0) return 42;
+return catch(x-1) + 1;
+}
+
+int class(int x) {
+if (x == 0) return 42;
+return class(x-1) + 1;
+}
+
+int const(int x) {
+if (x == 0) return 42;
+return const(x-1) + 1;
+}
+
+int continue(int x) {
+if (x == 0) return 42;
+return continue(x-1) + 1;
+}
+
+int default(int x) {
+if (x == 0) return 42;
+return default(x-1) + 1;
+}
+
+int do(int x) {
+if (x == 0) return 42;
+return do(x-1) + 1;
+}
+
+int else(int x) {
+if (x == 0) return 42;
+return else(x-1) + 1;
+}
+
+int enum(int x) {
+if (x == 0) return 42;
+return enum(x-1) + 1;
+}
+
+int extends(int x) {
+if (x == 0) return 42;
+return extends(x-1) + 1;
+}
+
+int false(int x) {
+if (x == 0) return 42;
+return false(x-1) + 1;
+}
+
+int final(int x) {
+if (x == 0) return 42;
+return final(x-1) + 1;
+}
+
+int finally(int x) {
+if (x == 0) return 42;
+return finally(x-1) + 1;
+}
+
+int for(int x) {
+if (x == 0) return 42;
+return for(x-1) + 1;
+}
+
+int if(int x) {
+if (x == 0) return 42;
+return if(x-1) + 1;
+}
+
+int in(int x) {
+if (x == 0) return 42;
+return in(x-1) + 1;
+}
+
+int is(int x) {
+if (x == 0) return 42;
+return is(x-1) + 1;
+}
+
+int new(int x) {
+if (x == 0) return 42;
+return new(x-1) + 1;
+}
+
+int null(int x) {
+if (x == 0) return 42;
+return null(x-1) + 1;
+}
+
+int rethrow(int x) {
+if (x == 0) return 42;
+return rethrow(x-1) + 1;
+}
+
+int return(int x) {
+if (x == 0) return 42;
+return return(x-1) + 1;
+}
+
+int super(int x) {
+if (x == 0) return 42;
+return super(x-1) + 1;
+}
+
+int switch(int x) {
+if (x == 0) return 42;
+return switch(x-1) + 1;
+}
+
+int this(int x) {
+if (x == 0) return 42;
+return this(x-1) + 1;
+}
+
+int throw(int x) {
+if (x == 0) return 42;
+return throw(x-1) + 1;
+}
+
+int true(int x) {
+if (x == 0) return 42;
+return true(x-1) + 1;
+}
+
+int try(int x) {
+if (x == 0) return 42;
+return try(x-1) + 1;
+}
+
+int var(int x) {
+if (x == 0) return 42;
+return var(x-1) + 1;
+}
+
+int void(int x) {
+if (x == 0) return 42;
+return void(x-1) + 1;
+}
+
+int while(int x) {
+if (x == 0) return 42;
+return while(x-1) + 1;
+}
+
+int with(int x) {
+if (x == 0) return 42;
+return with(x-1) + 1;
+}
+
+
+int[StringToken] assert[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] assert[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] break[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] break[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] case[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] case[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] catch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] catch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] class[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] class[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] const[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] continue[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] default[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] default[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] do[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] do[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] else[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] else[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] enum[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] enum[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] extends[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] extends[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] false[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] false[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] final[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] final[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] finally[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] finally[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] for[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] for[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] if[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] if[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] in[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] in[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] is[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] is[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] new[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] new[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] null[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] null[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] rethrow[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] rethrow[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] return[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] return[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] super[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] super[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] switch[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] switch[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] this[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] this[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] throw[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] throw[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] true[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] true[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] try[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] try[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] var[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] var[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] void[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] void[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] while[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] while[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] with[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] with[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart
new file mode 100644
index 0000000..5d74600
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart
Binary files differ
diff --git a/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.expect
new file mode 100644
index 0000000..cbfa036
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.expect
Binary files differ
diff --git a/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.intertwined.expect
new file mode 100644
index 0000000..95a1a29
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.intertwined.expect
@@ -0,0 +1,2729 @@
+parseUnit(EncodingErrorToken())
+  skipErrorTokens(EncodingErrorToken())
+  listener: beginCompilationUnit(/)
+  syntheticPreviousToken(/)
+  parseTopLevelDeclarationImpl(AsciiControlCharacterToken(0), Instance of 'DirectiveContext')
+    parseMetadataStar(AsciiControlCharacterToken(0))
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(AsciiControlCharacterToken(0))
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(/)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(C)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(C)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(/)
+      listener: beginTopLevelMember(C)
+      parseFields(/, null, null, null, null, null, /, Instance of 'SimpleType', o, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(C, typeReference)
+        listener: handleNoTypeArguments(o)
+        listener: handleType(C, null)
+        ensureIdentifier(C, topLevelVariableDeclaration)
+          listener: handleIdentifier(o, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(o, o, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(p)
+        ensureSemicolon(o)
+          reportRecoverableError(o, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], o, o)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, C, ;)
+  listener: endTopLevelDeclaration(p)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(p)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(p)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', y, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(p, typeReference)
+        listener: handleNoTypeArguments(y)
+        listener: handleType(p, null)
+        ensureIdentifier(p, topLevelVariableDeclaration)
+          listener: handleIdentifier(y, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(y, y, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(r)
+        ensureSemicolon(y)
+          reportRecoverableError(y, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], y, y)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, p, ;)
+  listener: endTopLevelDeclaration(r)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(r)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(r)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', i, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(r, typeReference)
+        listener: handleNoTypeArguments(i)
+        listener: handleType(r, null)
+        ensureIdentifier(r, topLevelVariableDeclaration)
+          listener: handleIdentifier(i, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(i, i, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(g)
+        ensureSemicolon(i)
+          reportRecoverableError(i, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], i, i)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, r, ;)
+  listener: endTopLevelDeclaration(g)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(g)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(g)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', h, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(g, typeReference)
+        listener: handleNoTypeArguments(h)
+        listener: handleType(g, null)
+        ensureIdentifier(g, topLevelVariableDeclaration)
+          listener: handleIdentifier(h, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(h, h, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(t)
+        ensureSemicolon(h)
+          reportRecoverableError(h, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], h, h)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, g, ;)
+  listener: endTopLevelDeclaration(t)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(t)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(t)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, t)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          listener: handleIdentifier(t, topLevelFunctionDeclaration)
+        parseMethodTypeVar(t)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(t, t, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(t, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(c)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(c, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleNoType(()
+                ensureIdentifier((, formalParameterDeclaration)
+                  listener: handleIdentifier(c, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, c, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(2, Message[ExpectedFunctionBody, Expected a function body, but got '2'., null, {token: 2}])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '2'., null, {token: 2}], 2, 2)
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(t, null, })
+  listener: endTopLevelDeclaration(2)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(2)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(2)
+    parseInvalidTopLevelDeclaration(})
+      reportRecoverableErrorWithToken(2, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '2'., null, {token: 2}], 2, 2)
+      listener: handleInvalidTopLevelDeclaration(2)
+  listener: endTopLevelDeclaration(0)
+  parseTopLevelDeclarationImpl(2, Instance of 'DirectiveContext')
+    parseMetadataStar(2)
+      listener: beginMetadataStar(0)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(0)
+    parseInvalidTopLevelDeclaration(2)
+      reportRecoverableErrorWithToken(0, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '0'., null, {token: 0}], 0, 0)
+      listener: handleInvalidTopLevelDeclaration(0)
+  listener: endTopLevelDeclaration(2)
+  parseTopLevelDeclarationImpl(0, Instance of 'DirectiveContext')
+    parseMetadataStar(0)
+      listener: beginMetadataStar(2)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(2)
+    parseInvalidTopLevelDeclaration(0)
+      reportRecoverableErrorWithToken(2, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '2'., null, {token: 2}], 2, 2)
+      listener: handleInvalidTopLevelDeclaration(2)
+  listener: endTopLevelDeclaration(0)
+  parseTopLevelDeclarationImpl(2, Instance of 'DirectiveContext')
+    parseMetadataStar(2)
+      listener: beginMetadataStar(0)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(0)
+    parseInvalidTopLevelDeclaration(2)
+      reportRecoverableErrorWithToken(0, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '0'., null, {token: 0}], 0, 0)
+      listener: handleInvalidTopLevelDeclaration(0)
+  listener: endTopLevelDeclaration(,)
+  parseTopLevelDeclarationImpl(0, Instance of 'DirectiveContext')
+    parseMetadataStar(0)
+      listener: beginMetadataStar(,)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(,)
+    parseInvalidTopLevelDeclaration(0)
+      reportRecoverableErrorWithToken(,, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got ','., null, {token: ,}], ,, ,)
+      listener: handleInvalidTopLevelDeclaration(,)
+  listener: endTopLevelDeclaration(t)
+  parseTopLevelDeclarationImpl(,, Instance of 'DirectiveContext')
+    parseMetadataStar(,)
+      listener: beginMetadataStar(t)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(,)
+      listener: beginTopLevelMember(t)
+      parseFields(,, null, null, null, null, null, ,, Instance of 'SimpleType', h, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(t, typeReference)
+        listener: handleNoTypeArguments(h)
+        listener: handleType(t, null)
+        ensureIdentifier(t, topLevelVariableDeclaration)
+          listener: handleIdentifier(h, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(h, h, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(h)
+          reportRecoverableError(h, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], h, h)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, t, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', D, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(D)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(D, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(D, D, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(a)
+        ensureSemicolon(D)
+          reportRecoverableError(D, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], D, D)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(a)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(a)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(a)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', r, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(a, typeReference)
+        listener: handleNoTypeArguments(r)
+        listener: handleType(a, null)
+        ensureIdentifier(a, topLevelVariableDeclaration)
+          listener: handleIdentifier(r, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(r, r, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(t)
+        ensureSemicolon(r)
+          reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, a, ;)
+  listener: endTopLevelDeclaration(t)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(t)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(t)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', p, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(t, typeReference)
+        listener: handleNoTypeArguments(p)
+        listener: handleType(t, null)
+        ensureIdentifier(t, topLevelVariableDeclaration)
+          listener: handleIdentifier(p, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(p, p, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(r)
+        ensureSemicolon(p)
+          reportRecoverableError(p, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], p, p)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, t, ;)
+  listener: endTopLevelDeclaration(r)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(r)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(r)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', o, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(r, typeReference)
+        listener: handleNoTypeArguments(o)
+        listener: handleType(r, null)
+        ensureIdentifier(r, topLevelVariableDeclaration)
+          listener: handleIdentifier(o, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(o, o, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(j)
+        ensureSemicolon(o)
+          reportRecoverableError(o, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], o, o)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, r, ;)
+  listener: endTopLevelDeclaration(j)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(j)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(j)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(j, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(j, null)
+        ensureIdentifier(j, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(c)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, j, ;)
+  listener: endTopLevelDeclaration(c)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(c)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(c)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(c, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(c, null)
+        ensureIdentifier(c, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(a)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, c, ;)
+  listener: endTopLevelDeclaration(a)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(a)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(a)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', u, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(a, typeReference)
+        listener: handleNoTypeArguments(u)
+        listener: handleType(a, null)
+        ensureIdentifier(a, topLevelVariableDeclaration)
+          listener: handleIdentifier(u, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(u, u, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(t)
+        ensureSemicolon(u)
+          reportRecoverableError(u, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], u, u)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, a, ;)
+  listener: endTopLevelDeclaration(t)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(t)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(t)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', h, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(t, typeReference)
+        listener: handleNoTypeArguments(h)
+        listener: handleType(t, null)
+        ensureIdentifier(t, topLevelVariableDeclaration)
+          listener: handleIdentifier(h, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(h, h, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(o)
+        ensureSemicolon(h)
+          reportRecoverableError(h, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], h, h)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, t, ;)
+  listener: endTopLevelDeclaration(o)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(o)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(o)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', r, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(o, typeReference)
+        listener: handleNoTypeArguments(r)
+        listener: handleType(o, null)
+        ensureIdentifier(o, topLevelVariableDeclaration)
+          listener: handleIdentifier(r, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(r, r, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(r)
+          reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, o, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'PrefixedType', l, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, prefixedTypeReference)
+        listener: handleIdentifier(P, typeReferenceContinuation)
+        listener: handleQualified(.)
+        listener: handleNoTypeArguments(l)
+        listener: handleType(s, null)
+        ensureIdentifier(P, topLevelVariableDeclaration)
+          listener: handleIdentifier(l, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l, l, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(l)
+          reportRecoverableError(l, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], l, l)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', a, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(a)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(a, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(a, a, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(a)
+          reportRecoverableError(a, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], a, a)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(h)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(h)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(h)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(h)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(h, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(h, null)
+        ensureIdentifier(h, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(A)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, h, ;)
+  listener: endTopLevelDeclaration(A)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(A)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(A)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', U, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(A, typeReference)
+        listener: handleNoTypeArguments(U)
+        listener: handleType(A, null)
+        ensureIdentifier(A, topLevelVariableDeclaration)
+          listener: handleIdentifier(U, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(U, U, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(T)
+        ensureSemicolon(U)
+          reportRecoverableError(U, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], U, U)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, A, ;)
+  listener: endTopLevelDeclaration(T)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(T)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(T)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', H, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(T, typeReference)
+        listener: handleNoTypeArguments(H)
+        listener: handleType(T, null)
+        ensureIdentifier(T, topLevelVariableDeclaration)
+          listener: handleIdentifier(H, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(H, H, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(O)
+        ensureSemicolon(H)
+          reportRecoverableError(H, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], H, H)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, T, ;)
+  listener: endTopLevelDeclaration(O)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(O)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(O)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', R, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(O, typeReference)
+        listener: handleNoTypeArguments(R)
+        listener: handleType(O, null)
+        ensureIdentifier(O, topLevelVariableDeclaration)
+          listener: handleIdentifier(R, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(R, R, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(S)
+        ensureSemicolon(R)
+          reportRecoverableError(R, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], R, R)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, O, ;)
+  listener: endTopLevelDeclaration(S)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(S)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(S)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', f, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(S, typeReference)
+        listener: handleNoTypeArguments(f)
+        listener: handleType(S, null)
+        ensureIdentifier(S, topLevelVariableDeclaration)
+          listener: handleIdentifier(f, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(f, f, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(f)
+          reportRecoverableError(f, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], f, f)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, S, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', l, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(l)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelVariableDeclaration)
+          listener: handleIdentifier(l, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l, l, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(l)
+          reportRecoverableError(l, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], l, l)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, i, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', e, DeclarationKind.TopLevel, null)
+        reportRecoverableError(e, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, e, e)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(/)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(/)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(f)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(/)
+      listener: beginTopLevelMember(f)
+      parseFields(/, null, null, null, null, null, /, Instance of 'SimpleType', o, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(f, typeReference)
+        listener: handleNoTypeArguments(o)
+        listener: handleType(f, null)
+        ensureIdentifier(f, topLevelVariableDeclaration)
+          listener: handleIdentifier(o, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(o, o, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(r)
+        ensureSemicolon(o)
+          reportRecoverableError(o, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], o, o)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, f, ;)
+  listener: endTopLevelDeclaration(r)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(r)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(r)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', d, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(r, typeReference)
+        listener: handleNoTypeArguments(d)
+        listener: handleType(r, null)
+        ensureIdentifier(r, topLevelVariableDeclaration)
+          listener: handleIdentifier(d, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(d, d, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(d)
+          reportRecoverableError(d, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], d, d)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, r, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(a)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(a)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(a)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(a)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', i, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(a, typeReference)
+        listener: handleNoTypeArguments(i)
+        listener: handleType(a, null)
+        ensureIdentifier(a, topLevelVariableDeclaration)
+          listener: handleIdentifier(i, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(i, i, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(l)
+        ensureSemicolon(i)
+          reportRecoverableError(i, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], i, i)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, a, ;)
+  listener: endTopLevelDeclaration(l)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(l)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(l)
+      parseTopLevelMethod(;, null, ;, Instance of 'SimpleType', null, s)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleIdentifier(l, typeReference)
+        listener: handleNoTypeArguments(s)
+        listener: handleType(l, null)
+        ensureIdentifier(l, topLevelFunctionDeclaration)
+          listener: handleIdentifier(s, topLevelFunctionDeclaration)
+        parseMethodTypeVar(s)
+          listener: handleNoTypeVariables(.)
+        parseGetterOrFormalParameters(s, s, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(s, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, s, s)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(., Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}], ., .)
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(l, null, })
+  listener: endTopLevelDeclaration(.)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(.)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(.)
+    parseInvalidTopLevelDeclaration(})
+      reportRecoverableErrorWithToken(., Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '.'., null, {token: .}], ., .)
+      listener: handleInvalidTopLevelDeclaration(.)
+  listener: endTopLevelDeclaration(A)
+  parseTopLevelDeclarationImpl(., Instance of 'DirectiveContext')
+    parseMetadataStar(.)
+      listener: beginMetadataStar(A)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(.)
+      listener: beginTopLevelMember(A)
+      parseFields(., null, null, null, null, null, ., Instance of 'SimpleType', l, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(A, typeReference)
+        listener: handleNoTypeArguments(l)
+        listener: handleType(A, null)
+        ensureIdentifier(A, topLevelVariableDeclaration)
+          listener: handleIdentifier(l, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l, l, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(l)
+        ensureSemicolon(l)
+          reportRecoverableError(l, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], l, l)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, A, ;)
+  listener: endTopLevelDeclaration(l)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(l)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(l)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', r, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(l, typeReference)
+        listener: handleNoTypeArguments(r)
+        listener: handleType(l, null)
+        ensureIdentifier(l, topLevelVariableDeclaration)
+          listener: handleIdentifier(r, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(r, r, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(r)
+          reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, l, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', g, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(g)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelVariableDeclaration)
+          listener: handleIdentifier(g, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(g, g, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(h)
+        ensureSemicolon(g)
+          reportRecoverableError(g, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], g, g)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, i, ;)
+  listener: endTopLevelDeclaration(h)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(h)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(h)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(h, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(h, null)
+        ensureIdentifier(h, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, h, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', r, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(r)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(r, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(r, r, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(r)
+          reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', s, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(s)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(s, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(s, s, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(s)
+          reportRecoverableError(s, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], s, s)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', r, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(r)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(r, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(r, r, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(v)
+        ensureSemicolon(r)
+          reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(v)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(v)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(v)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(v, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(v, null)
+        ensureIdentifier(v, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(d)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, v, ;)
+  listener: endTopLevelDeclaration(d)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(d)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(d)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'PrefixedType', s, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(d, prefixedTypeReference)
+        listener: handleIdentifier(U, typeReferenceContinuation)
+        listener: handleQualified(.)
+        listener: handleNoTypeArguments(s)
+        listener: handleType(d, null)
+        ensureIdentifier(U, topLevelVariableDeclaration)
+          listener: handleIdentifier(s, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(s, s, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(s)
+          reportRecoverableError(s, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], s, s)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, d, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', o, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(o)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(o, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(o, o, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(f)
+        ensureSemicolon(o)
+          reportRecoverableError(o, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], o, o)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(f)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(f)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(f, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(f, null)
+        ensureIdentifier(f, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(h)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, f, ;)
+  listener: endTopLevelDeclaration(h)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(h)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(h)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', i, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(h, typeReference)
+        listener: handleNoTypeArguments(i)
+        listener: handleType(h, null)
+        ensureIdentifier(h, topLevelVariableDeclaration)
+          listener: handleIdentifier(i, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(i, i, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(i)
+          reportRecoverableError(i, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], i, i)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, h, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', s, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(s)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(s, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(s, s, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(o)
+        ensureSemicolon(s)
+          reportRecoverableError(s, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], s, s)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(o)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(o)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(o)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', u, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(o, typeReference)
+        listener: handleNoTypeArguments(u)
+        listener: handleType(o, null)
+        ensureIdentifier(o, topLevelVariableDeclaration)
+          listener: handleIdentifier(u, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(u, u, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(r)
+        ensureSemicolon(u)
+          reportRecoverableError(u, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], u, u)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, o, ;)
+  listener: endTopLevelDeclaration(r)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(r)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(r)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', c, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(r, typeReference)
+        listener: handleNoTypeArguments(c)
+        listener: handleType(r, null)
+        ensureIdentifier(r, topLevelVariableDeclaration)
+          listener: handleIdentifier(c, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(c, c, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(c)
+          reportRecoverableError(c, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], c, c)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, r, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', c, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(c)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(c, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(c, c, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(o)
+        ensureSemicolon(c)
+          reportRecoverableError(c, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], c, c)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(o)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(o)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(o)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', d, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(o, typeReference)
+        listener: handleNoTypeArguments(d)
+        listener: handleType(o, null)
+        ensureIdentifier(o, topLevelVariableDeclaration)
+          listener: handleIdentifier(d, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(d, d, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(d)
+          reportRecoverableError(d, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], d, d)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, o, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', i, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(i)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(i, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(i, i, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(i)
+          reportRecoverableError(i, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], i, i)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', g, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(g)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(g, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(g, g, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(o)
+        ensureSemicolon(g)
+          reportRecoverableError(g, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], g, g)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(o)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(o)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(o)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', v, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(o, typeReference)
+        listener: handleNoTypeArguments(v)
+        listener: handleType(o, null)
+        ensureIdentifier(o, topLevelVariableDeclaration)
+          listener: handleIdentifier(v, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(v, v, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(v)
+          reportRecoverableError(v, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], v, v)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, o, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', r, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(r)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(r, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(r, r, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(n)
+        ensureSemicolon(r)
+          reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(n)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(n)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(n)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(n, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(n, null)
+        ensureIdentifier(n, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(d)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, n, ;)
+  listener: endTopLevelDeclaration(d)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(d)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(d)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', b, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(d, typeReference)
+        listener: handleNoTypeArguments(b)
+        listener: handleType(d, null)
+        ensureIdentifier(d, topLevelVariableDeclaration)
+          listener: handleIdentifier(b, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(b, b, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(y)
+        ensureSemicolon(b)
+          reportRecoverableError(b, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], b, b)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, d, ;)
+  listener: endTopLevelDeclaration(y)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(y)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(y)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', a, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(y, typeReference)
+        listener: handleNoTypeArguments(a)
+        listener: handleType(y, null)
+        ensureIdentifier(y, topLevelVariableDeclaration)
+          listener: handleIdentifier(a, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(a, a, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(/)
+        ensureSemicolon(a)
+          reportRecoverableError(a, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], a, a)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, y, ;)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(/)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(B)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(B)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(/)
+      listener: beginTopLevelMember(B)
+      parseFields(/, null, null, null, null, null, /, Instance of 'SimpleType', S, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(B, typeReference)
+        listener: handleNoTypeArguments(S)
+        listener: handleType(B, null)
+        ensureIdentifier(B, topLevelVariableDeclaration)
+          listener: handleIdentifier(S, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(S, S, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(D)
+        ensureSemicolon(S)
+          reportRecoverableError(S, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], S, S)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, B, ;)
+  listener: endTopLevelDeclaration(D)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(D)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(D)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'NoType', D, DeclarationKind.TopLevel, null)
+        reportRecoverableError(D, MissingConstFinalVarOrType)
+          listener: handleRecoverableError(MissingConstFinalVarOrType, D, D)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelVariableDeclaration)
+          listener: handleIdentifier(D, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(D, D, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(-)
+        ensureSemicolon(D)
+          reportRecoverableError(D, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], D, D)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, D, ;)
+  listener: endTopLevelDeclaration(-)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(-)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(-)
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(-, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '-'., null, {token: -}], -, -)
+      listener: handleInvalidTopLevelDeclaration(-)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(-, Instance of 'DirectiveContext')
+    parseMetadataStar(-)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(-)
+      listener: beginTopLevelMember(s)
+      parseFields(-, null, null, null, null, null, -, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(y)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(y)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(y)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(y)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', l, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(y, typeReference)
+        listener: handleNoTypeArguments(l)
+        listener: handleType(y, null)
+        ensureIdentifier(y, topLevelVariableDeclaration)
+          listener: handleIdentifier(l, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l, l, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(l)
+          reportRecoverableError(l, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], l, l)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, y, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', l, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(l)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(l, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l, l, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(l)
+          reportRecoverableError(l, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], l, l)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', c, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(c)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelVariableDeclaration)
+          listener: handleIdentifier(c, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(c, c, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(c)
+          reportRecoverableError(c, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], c, c)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, i, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', n, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(n)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(n, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(n, n, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(n)
+          reportRecoverableError(n, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], n, n)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(t)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(t)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(t)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(t)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', h, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(t, typeReference)
+        listener: handleNoTypeArguments(h)
+        listener: handleType(t, null)
+        ensureIdentifier(t, topLevelVariableDeclaration)
+          listener: handleIdentifier(h, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(h, h, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(a)
+        ensureSemicolon(h)
+          reportRecoverableError(h, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], h, h)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, t, ;)
+  listener: endTopLevelDeclaration(a)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(a)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(a)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', t, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(a, typeReference)
+        listener: handleNoTypeArguments(t)
+        listener: handleType(a, null)
+        ensureIdentifier(a, topLevelVariableDeclaration)
+          listener: handleIdentifier(t, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(t, t, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(c)
+        ensureSemicolon(t)
+          reportRecoverableError(t, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], t, t)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, a, ;)
+  listener: endTopLevelDeclaration(c)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(c)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(c)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', a, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(c, typeReference)
+        listener: handleNoTypeArguments(a)
+        listener: handleType(c, null)
+        ensureIdentifier(c, topLevelVariableDeclaration)
+          listener: handleIdentifier(a, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(a, a, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(n)
+        ensureSemicolon(a)
+          reportRecoverableError(a, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], a, a)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, c, ;)
+  listener: endTopLevelDeclaration(n)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(n)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(n)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', b, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(n, typeReference)
+        listener: handleNoTypeArguments(b)
+        listener: handleType(n, null)
+        ensureIdentifier(n, topLevelVariableDeclaration)
+          listener: handleIdentifier(b, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(b, b, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(b)
+          reportRecoverableError(b, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], b, b)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, n, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', f, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(f)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(f, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(f, f, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(o)
+        ensureSemicolon(f)
+          reportRecoverableError(f, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], f, f)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(o)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(o)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(o)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', u, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(o, typeReference)
+        listener: handleNoTypeArguments(u)
+        listener: handleType(o, null)
+        ensureIdentifier(o, topLevelVariableDeclaration)
+          listener: handleIdentifier(u, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(u, u, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(n)
+        ensureSemicolon(u)
+          reportRecoverableError(u, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], u, u)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, o, ;)
+  listener: endTopLevelDeclaration(n)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(n)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(n)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', d, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(n, typeReference)
+        listener: handleNoTypeArguments(d)
+        listener: handleType(n, null)
+        ensureIdentifier(n, topLevelVariableDeclaration)
+          listener: handleIdentifier(d, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(d, d, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(d)
+          reportRecoverableError(d, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], d, d)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, n, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', n, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(n)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelVariableDeclaration)
+          listener: handleIdentifier(n, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(n, n, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(t)
+        ensureSemicolon(n)
+          reportRecoverableError(n, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], n, n)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, i, ;)
+  listener: endTopLevelDeclaration(t)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(t)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(t)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', h, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(t, typeReference)
+        listener: handleNoTypeArguments(h)
+        listener: handleType(t, null)
+        ensureIdentifier(t, topLevelVariableDeclaration)
+          listener: handleIdentifier(h, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(h, h, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(e)
+        ensureSemicolon(h)
+          reportRecoverableError(h, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], h, h)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, t, ;)
+  listener: endTopLevelDeclaration(e)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(e)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(e)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', L, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(e, typeReference)
+        listener: handleNoTypeArguments(L)
+        listener: handleType(e, null)
+        ensureIdentifier(e, topLevelVariableDeclaration)
+          listener: handleIdentifier(L, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(L, L, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(I)
+        ensureSemicolon(L)
+          reportRecoverableError(L, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], L, L)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, e, ;)
+  listener: endTopLevelDeclaration(I)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(I)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(I)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', C, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(I, typeReference)
+        listener: handleNoTypeArguments(C)
+        listener: handleType(I, null)
+        ensureIdentifier(I, topLevelVariableDeclaration)
+          listener: handleIdentifier(C, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(C, C, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(E)
+        ensureSemicolon(C)
+          reportRecoverableError(C, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], C, C)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, I, ;)
+  listener: endTopLevelDeclaration(E)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(E)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(E)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', N, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(E, typeReference)
+        listener: handleNoTypeArguments(N)
+        listener: handleType(E, null)
+        ensureIdentifier(E, topLevelVariableDeclaration)
+          listener: handleIdentifier(N, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(N, N, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(S)
+        ensureSemicolon(N)
+          reportRecoverableError(N, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], N, N)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, E, ;)
+  listener: endTopLevelDeclaration(S)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(S)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(S)
+      parseTopLevelMethod(;, null, ;, Instance of 'SimpleType', null, E)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleIdentifier(S, typeReference)
+        listener: handleNoTypeArguments(E)
+        listener: handleType(S, null)
+        ensureIdentifier(S, topLevelFunctionDeclaration)
+          listener: handleIdentifier(E, topLevelFunctionDeclaration)
+        parseMethodTypeVar(E)
+          listener: handleNoTypeVariables(.)
+        parseGetterOrFormalParameters(E, E, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(E, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, E, E)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(., Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}], ., .)
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(S, null, })
+  listener: endTopLevelDeclaration(.)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(.)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(.)
+    parseInvalidTopLevelDeclaration(})
+      reportRecoverableErrorWithToken(., Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '.'., null, {token: .}], ., .)
+      listener: handleInvalidTopLevelDeclaration(.)
+  listener: endTopLevelDeclaration(m)
+  parseTopLevelDeclarationImpl(., Instance of 'DirectiveContext')
+    parseMetadataStar(.)
+      listener: beginMetadataStar(m)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(.)
+      listener: beginTopLevelMember(m)
+      parseFields(., null, null, null, null, null, ., Instance of 'SimpleType', d, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(m, typeReference)
+        listener: handleNoTypeArguments(d)
+        listener: handleType(m, null)
+        ensureIdentifier(m, topLevelVariableDeclaration)
+          listener: handleIdentifier(d, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(d, d, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(f)
+        ensureSemicolon(d)
+          reportRecoverableError(d, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], d, d)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, m, ;)
+  listener: endTopLevelDeclaration(f)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(f)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', i, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(f, typeReference)
+        listener: handleNoTypeArguments(i)
+        listener: handleType(f, null)
+        ensureIdentifier(f, topLevelVariableDeclaration)
+          listener: handleIdentifier(i, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(i, i, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(l)
+        ensureSemicolon(i)
+          reportRecoverableError(i, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], i, i)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, f, ;)
+  listener: endTopLevelDeclaration(l)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(l)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(l)
+      parseTopLevelMethod(;, null, ;, Instance of 'SimpleType', null, e)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleIdentifier(l, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(l, null)
+        ensureIdentifier(l, topLevelFunctionDeclaration)
+          listener: handleIdentifier(e, topLevelFunctionDeclaration)
+        parseMethodTypeVar(e)
+          listener: handleNoTypeVariables(.)
+        parseGetterOrFormalParameters(e, e, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(e, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, e, e)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(., Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}], ., .)
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(l, null, })
+  listener: endTopLevelDeclaration(.)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(.)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(.)
+    parseInvalidTopLevelDeclaration(})
+      reportRecoverableErrorWithToken(., Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '.'., null, {token: .}], ., .)
+      listener: handleInvalidTopLevelDeclaration(.)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(., Instance of 'DirectiveContext')
+    parseMetadataStar(.)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(.)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(/)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(/)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(/)
+    parseInvalidTopLevelDeclaration(/)
+      reportRecoverableErrorWithToken(/, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '/'., null, {token: /}], /, /)
+      listener: handleInvalidTopLevelDeclaration(/)
+  listener: endTopLevelDeclaration(T)
+  parseTopLevelDeclarationImpl(/, Instance of 'DirectiveContext')
+    parseMetadataStar(/)
+      listener: beginMetadataStar(T)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(/)
+      listener: beginTopLevelMember(T)
+      parseFields(/, null, null, null, null, null, /, Instance of 'SimpleType', h, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(T, typeReference)
+        listener: handleNoTypeArguments(h)
+        listener: handleType(T, null)
+        ensureIdentifier(T, topLevelVariableDeclaration)
+          listener: handleIdentifier(h, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(h, h, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(h)
+          reportRecoverableError(h, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], h, h)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, T, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', s, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(s)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelVariableDeclaration)
+          listener: handleIdentifier(s, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(s, s, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(f)
+        ensureSemicolon(s)
+          reportRecoverableError(s, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], s, s)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, i, ;)
+  listener: endTopLevelDeclaration(f)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(f)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', i, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(f, typeReference)
+        listener: handleNoTypeArguments(i)
+        listener: handleType(f, null)
+        ensureIdentifier(f, topLevelVariableDeclaration)
+          listener: handleIdentifier(i, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(i, i, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(l)
+        ensureSemicolon(i)
+          reportRecoverableError(i, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], i, i)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, f, ;)
+  listener: endTopLevelDeclaration(l)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(l)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(l)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(l, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(l, null)
+        ensureIdentifier(l, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, l, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', s, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(s)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelVariableDeclaration)
+          listener: handleIdentifier(s, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(s, s, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(s)
+          reportRecoverableError(s, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], s, s)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, i, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', a, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(a)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(a, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(a, a, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(v)
+        ensureSemicolon(a)
+          reportRecoverableError(a, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], a, a)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(v)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(v)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(v)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', e, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(v, typeReference)
+        listener: handleNoTypeArguments(e)
+        listener: handleType(v, null)
+        ensureIdentifier(v, topLevelVariableDeclaration)
+          listener: handleIdentifier(e, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(e, e, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(d)
+        ensureSemicolon(e)
+          reportRecoverableError(e, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], e, e)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, v, ;)
+  listener: endTopLevelDeclaration(d)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(d)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(d)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', a, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(d, typeReference)
+        listener: handleNoTypeArguments(a)
+        listener: handleType(d, null)
+        ensureIdentifier(d, topLevelVariableDeclaration)
+          listener: handleIdentifier(a, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(a, a, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(s)
+        ensureSemicolon(a)
+          reportRecoverableError(a, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], a, a)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, d, ;)
+  listener: endTopLevelDeclaration(s)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(s)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(s)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', U, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(s, typeReference)
+        listener: handleNoTypeArguments(U)
+        listener: handleType(s, null)
+        ensureIdentifier(s, topLevelVariableDeclaration)
+          listener: handleIdentifier(U, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(U, U, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(T)
+        ensureSemicolon(U)
+          reportRecoverableError(U, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], U, U)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, s, ;)
+  listener: endTopLevelDeclaration(T)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(T)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(T)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', F, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(T, typeReference)
+        listener: handleNoTypeArguments(F)
+        listener: handleType(T, null)
+        ensureIdentifier(T, topLevelVariableDeclaration)
+          listener: handleIdentifier(F, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(F, F, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(-)
+        ensureSemicolon(F)
+          reportRecoverableError(F, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], F, F)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, T, ;)
+  listener: endTopLevelDeclaration(-)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(-)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(-)
+    parseInvalidTopLevelDeclaration(;)
+      reportRecoverableErrorWithToken(-, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '-'., null, {token: -}], -, -)
+      listener: handleInvalidTopLevelDeclaration(-)
+  listener: endTopLevelDeclaration(1)
+  parseTopLevelDeclarationImpl(-, Instance of 'DirectiveContext')
+    parseMetadataStar(-)
+      listener: beginMetadataStar(1)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(1)
+    parseInvalidTopLevelDeclaration(-)
+      reportRecoverableErrorWithToken(1, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '1'., null, {token: 1}], 1, 1)
+      listener: handleInvalidTopLevelDeclaration(1)
+  listener: endTopLevelDeclaration(6)
+  parseTopLevelDeclarationImpl(1, Instance of 'DirectiveContext')
+    parseMetadataStar(1)
+      listener: beginMetadataStar(6)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(6)
+    parseInvalidTopLevelDeclaration(1)
+      reportRecoverableErrorWithToken(6, Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '6'., null, {token: 6}], 6, 6)
+      listener: handleInvalidTopLevelDeclaration(6)
+  listener: endTopLevelDeclaration(L)
+  parseTopLevelDeclarationImpl(6, Instance of 'DirectiveContext')
+    parseMetadataStar(6)
+      listener: beginMetadataStar(L)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(6)
+      listener: beginTopLevelMember(L)
+      parseTopLevelMethod(6, null, 6, Instance of 'SimpleType', null, E)
+        listener: beginTopLevelMethod(6, null)
+        listener: handleIdentifier(L, typeReference)
+        listener: handleNoTypeArguments(E)
+        listener: handleType(L, null)
+        ensureIdentifier(L, topLevelFunctionDeclaration)
+          listener: handleIdentifier(E, topLevelFunctionDeclaration)
+        parseMethodTypeVar(E)
+          listener: handleNoTypeVariables(.)
+        parseGetterOrFormalParameters(E, E, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(E, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, E, E)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(., Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got '.'., null, {token: .}], ., .)
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(L, null, })
+  listener: endTopLevelDeclaration(.)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(.)
+      listener: endMetadataStar(0)
+    listener: beginTopLevelMember(.)
+    parseInvalidTopLevelDeclaration(})
+      reportRecoverableErrorWithToken(., Instance of 'Template<(Token) => Message>')
+        listener: handleRecoverableError(Message[ExpectedDeclaration, Expected a declaration, but got '.'., null, {token: .}], ., .)
+      listener: handleInvalidTopLevelDeclaration(.)
+  listener: endTopLevelDeclaration(m)
+  parseTopLevelDeclarationImpl(., Instance of 'DirectiveContext')
+    parseMetadataStar(.)
+      listener: beginMetadataStar(m)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(.)
+      listener: beginTopLevelMember(m)
+      parseFields(., null, null, null, null, null, ., Instance of 'SimpleType', a, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(m, typeReference)
+        listener: handleNoTypeArguments(a)
+        listener: handleType(m, null)
+        ensureIdentifier(m, topLevelVariableDeclaration)
+          listener: handleIdentifier(a, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(a, a, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(i)
+        ensureSemicolon(a)
+          reportRecoverableError(a, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], a, a)
+          rewriter()
+        listener: endTopLevelFields(null, null, null, null, 1, m, ;)
+  listener: endTopLevelDeclaration(i)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(i)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(i)
+      parseTopLevelMethod(;, null, ;, Instance of 'SimpleType', null, n)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleIdentifier(i, typeReference)
+        listener: handleNoTypeArguments(n)
+        listener: handleType(i, null)
+        ensureIdentifier(i, topLevelFunctionDeclaration)
+          listener: handleIdentifier(n, topLevelFunctionDeclaration)
+        parseMethodTypeVar(n)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(n, n, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(n, 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(}, p)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(r)
+                listener: beginMetadataStar(p)
+                listener: endMetadataStar(0)
+                listener: handleIdentifier(p, typeReference)
+                listener: handleNoTypeArguments(r)
+                listener: handleType(p, null)
+                listener: beginVariablesDeclaration(r, null, null)
+                parseVariablesDeclarationRest(p, true)
+                  parseOptionallyInitializedIdentifier(p)
+                    ensureIdentifier(p, localVariableDeclaration)
+                      listener: handleIdentifier(r, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r)
+                    parseVariableInitializerOpt(r)
+                      listener: handleNoVariableInitializer(i)
+                    listener: endInitializedIdentifier(r)
+                  ensureSemicolon(r)
+                    reportRecoverableError(r, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], r, r)
+                    rewriter()
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, i)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(n)
+                listener: beginMetadataStar(i)
+                listener: endMetadataStar(0)
+                listener: handleIdentifier(i, typeReference)
+                listener: handleNoTypeArguments(n)
+                listener: handleType(i, null)
+                listener: beginVariablesDeclaration(n, null, null)
+                parseVariablesDeclarationRest(i, true)
+                  parseOptionallyInitializedIdentifier(i)
+                    ensureIdentifier(i, localVariableDeclaration)
+                      listener: handleIdentifier(n, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(n)
+                    parseVariableInitializerOpt(n)
+                      listener: handleNoVariableInitializer(t)
+                    listener: endInitializedIdentifier(n)
+                  ensureSemicolon(n)
+                    reportRecoverableError(n, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], n, n)
+                    rewriter()
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, t)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(t)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(t, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(t)
+                                parseArguments(t)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseLiteralString(()
+                                              parseSingleLiteralString(()
+                                                listener: beginLiteralString("")
+                                                listener: endLiteralString(0, H)
+                                    rewriteAndRecover("", Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(H, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], H, H)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(H, expression)
+                                                listener: handleNoTypeArguments(e)
+                                                parseArgumentsOpt(H)
+                                                  listener: handleNoArguments(e)
+                                                listener: handleSend(H, e)
+                                    rewriteAndRecover(H, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(e, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], e, e)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(e, expression)
+                                                listener: handleNoTypeArguments(l)
+                                                parseArgumentsOpt(e)
+                                                  listener: handleNoArguments(l)
+                                                listener: handleSend(e, l)
+                                    rewriteAndRecover(e, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(l, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], l, l)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(l, expression)
+                                                listener: handleNoTypeArguments(l)
+                                                parseArgumentsOpt(l)
+                                                  listener: handleNoArguments(l)
+                                                listener: handleSend(l, l)
+                                    rewriteAndRecover(l, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(l, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], l, l)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(l, expression)
+                                                listener: handleNoTypeArguments(o)
+                                                parseArgumentsOpt(l)
+                                                  listener: handleNoArguments(o)
+                                                listener: handleSend(l, o)
+                                    rewriteAndRecover(l, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(o, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], o, o)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(o, expression)
+                                                listener: handleNoTypeArguments(,)
+                                                parseArgumentsOpt(o)
+                                                  listener: handleNoArguments(,)
+                                                listener: handleSend(o, ,)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(w, expression)
+                                                listener: handleNoTypeArguments(o)
+                                                parseArgumentsOpt(w)
+                                                  listener: handleNoArguments(o)
+                                                listener: handleSend(w, o)
+                                    rewriteAndRecover(w, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(o, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], o, o)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(o, expression)
+                                                listener: handleNoTypeArguments(r)
+                                                parseArgumentsOpt(o)
+                                                  listener: handleNoArguments(r)
+                                                listener: handleSend(o, r)
+                                    rewriteAndRecover(o, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(r, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], r, r)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(r, expression)
+                                                listener: handleNoTypeArguments(l)
+                                                parseArgumentsOpt(r)
+                                                  listener: handleNoArguments(l)
+                                                listener: handleSend(r, l)
+                                    rewriteAndRecover(r, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(l, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], l, l)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(l, expression)
+                                                listener: handleNoTypeArguments(d)
+                                                parseArgumentsOpt(l)
+                                                  listener: handleNoArguments(d)
+                                                listener: handleSend(l, d)
+                                    rewriteAndRecover(l, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError(d, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], d, d)
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(d, expression)
+                                                listener: handleNoTypeArguments(!)
+                                                parseArgumentsOpt(d)
+                                                  listener: handleNoArguments(!)
+                                                listener: handleSend(d, !)
+                                        listener: handleNonNullAssertExpression(!)
+                                    rewriteAndRecover(!, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,)
+                                      reportRecoverableError("", Message[ExpectedButGot, Expected ',' before this., null, {string: ,}])
+                                        listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], "", "")
+                                      rewriter()
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseLiteralString(,)
+                                              parseSingleLiteralString(,)
+                                                listener: beginLiteralString("")
+                                                listener: endLiteralString(0, ))
+                                    listener: endArguments(12, (, ))
+                              listener: handleSend(t, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(i, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(EncodingErrorToken())
+    listener: handleErrorToken(EncodingErrorToken())
+    listener: handleErrorToken(EncodingErrorToken())
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(UnterminatedString("))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(UnterminatedString("))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+    listener: handleErrorToken(AsciiControlCharacterToken(0))
+  listener: endCompilationUnit(114, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.parser.expect
new file mode 100644
index 0000000..188f401c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.parser.expect
@@ -0,0 +1,31 @@
+NOTICE: Stream was rewritten by parser!
+
+/ / C o ;p y ;r i ;g h ;t ( c ) {}2 0 2 0 , t h ;e D ;a r ;t p ;r o ;j e ;c t ;a u ;t h ;o r ;s . P l ;e a ;s e ;s e ;e t ;h e ;A U ;T H ;O R ;S f ;i l ;e
+;/ / f o ;r d ;e t ;a i ;l s (){}. A l ;l r ;i g ;h t ;s r ;e s ;e r ;v e ;d . U s ;e o ;f t ;h i ;s s ;o u ;r c ;e c ;o d ;e i ;s g ;o v ;e r ;n e ;d b ;y a
+;/ / B S ;D ;- s t ;y l ;e l ;i c ;e n ;s e ;t h ;a t ;c a ;n b ;e f ;o u ;n d ;i n ;t h ;e L ;I C ;E N ;S E (){}. m d ;f i ;l e (){}.
+
+/ / T h ;i s ;f i ;l e ;i s ;s a ;v e ;d a ;s U ;T F ;- 1 6 L E (){}.
+
+m a ;i n ( ) {
+p r ;i n ;t ( "" ,H ,e ,l ,l ,o , w ,o ,r ,l ,d ! ,"" ) ;
+}
+
+
+[EncodingErrorToken][EncodingErrorToken][AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [UnterminatedString][AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [UnterminatedString][AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]/[SimpleToken] /[SimpleToken] C[StringToken] o[StringToken] ;[SyntheticToken]p[StringToken] y[StringToken] ;[SyntheticToken]r[StringToken] i[StringToken] ;[SyntheticToken]g[StringToken] h[StringToken] ;[SyntheticToken]t[StringToken] ([BeginToken] c[StringToken] )[SimpleToken] {[SyntheticBeginToken]}[SyntheticToken]2[StringToken] 0[StringToken] 2[StringToken] 0[StringToken] ,[SimpleToken] t[StringToken] h[StringToken] ;[SyntheticToken]e[StringToken] D[StringToken] ;[SyntheticToken]a[StringToken] r[StringToken] ;[SyntheticToken]t[StringToken] p[StringToken] ;[SyntheticToken]r[StringToken] o[StringToken] ;[SyntheticToken]j[StringToken] e[StringToken] ;[SyntheticToken]c[StringToken] t[StringToken] ;[SyntheticToken]a[StringToken] u[StringToken] ;[SyntheticToken]t[StringToken] h[StringToken] ;[SyntheticToken]o[StringToken] r[StringToken] ;[SyntheticToken]s[StringToken] .[SimpleToken] P[StringToken] l[StringToken] ;[SyntheticToken]e[StringToken] a[StringToken] ;[SyntheticToken]s[StringToken] e[StringToken] ;[SyntheticToken]s[StringToken] e[StringToken] ;[SyntheticToken]e[StringToken] t[StringToken] ;[SyntheticToken]h[StringToken] e[StringToken] ;[SyntheticToken]A[StringToken] U[StringToken] ;[SyntheticToken]T[StringToken] H[StringToken] ;[SyntheticToken]O[StringToken] R[StringToken] ;[SyntheticToken]S[StringToken] f[StringToken] ;[SyntheticToken]i[StringToken] l[StringToken] ;[SyntheticToken]e[StringToken]
+;[SyntheticToken]/[SimpleToken] /[SimpleToken] f[StringToken] o[StringToken] ;[SyntheticToken]r[StringToken] d[StringToken] ;[SyntheticToken]e[StringToken] t[StringToken] ;[SyntheticToken]a[StringToken] i[StringToken] ;[SyntheticToken]l[StringToken] s[StringToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken].[SimpleToken] A[StringToken] l[StringToken] ;[SyntheticToken]l[StringToken] r[StringToken] ;[SyntheticToken]i[StringToken] g[StringToken] ;[SyntheticToken]h[StringToken] t[StringToken] ;[SyntheticToken]s[StringToken] r[StringToken] ;[SyntheticToken]e[StringToken] s[StringToken] ;[SyntheticToken]e[StringToken] r[StringToken] ;[SyntheticToken]v[StringToken] e[StringToken] ;[SyntheticToken]d[StringToken] .[SimpleToken] U[StringToken] s[StringToken] ;[SyntheticToken]e[StringToken] o[StringToken] ;[SyntheticToken]f[StringToken] t[StringToken] ;[SyntheticToken]h[StringToken] i[StringToken] ;[SyntheticToken]s[StringToken] s[StringToken] ;[SyntheticToken]o[StringToken] u[StringToken] ;[SyntheticToken]r[StringToken] c[StringToken] ;[SyntheticToken]e[StringToken] c[StringToken] ;[SyntheticToken]o[StringToken] d[StringToken] ;[SyntheticToken]e[StringToken] i[StringToken] ;[SyntheticToken]s[StringToken] g[StringToken] ;[SyntheticToken]o[StringToken] v[StringToken] ;[SyntheticToken]e[StringToken] r[StringToken] ;[SyntheticToken]n[StringToken] e[StringToken] ;[SyntheticToken]d[StringToken] b[StringToken] ;[SyntheticToken]y[StringToken] a[StringToken]
+;[SyntheticToken]/[SimpleToken] /[SimpleToken] B[StringToken] S[StringToken] ;[SyntheticToken]D[StringToken] ;[SyntheticToken]-[SimpleToken] s[StringToken] t[StringToken] ;[SyntheticToken]y[StringToken] l[StringToken] ;[SyntheticToken]e[StringToken] l[StringToken] ;[SyntheticToken]i[StringToken] c[StringToken] ;[SyntheticToken]e[StringToken] n[StringToken] ;[SyntheticToken]s[StringToken] e[StringToken] ;[SyntheticToken]t[StringToken] h[StringToken] ;[SyntheticToken]a[StringToken] t[StringToken] ;[SyntheticToken]c[StringToken] a[StringToken] ;[SyntheticToken]n[StringToken] b[StringToken] ;[SyntheticToken]e[StringToken] f[StringToken] ;[SyntheticToken]o[StringToken] u[StringToken] ;[SyntheticToken]n[StringToken] d[StringToken] ;[SyntheticToken]i[StringToken] n[StringToken] ;[SyntheticToken]t[StringToken] h[StringToken] ;[SyntheticToken]e[StringToken] L[StringToken] ;[SyntheticToken]I[StringToken] C[StringToken] ;[SyntheticToken]E[StringToken] N[StringToken] ;[SyntheticToken]S[StringToken] E[StringToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken].[SimpleToken] m[StringToken] d[StringToken] ;[SyntheticToken]f[StringToken] i[StringToken] ;[SyntheticToken]l[StringToken] e[StringToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken].[SimpleToken]
+
+/[SimpleToken] /[SimpleToken] T[StringToken] h[StringToken] ;[SyntheticToken]i[StringToken] s[StringToken] ;[SyntheticToken]f[StringToken] i[StringToken] ;[SyntheticToken]l[StringToken] e[StringToken] ;[SyntheticToken]i[StringToken] s[StringToken] ;[SyntheticToken]s[StringToken] a[StringToken] ;[SyntheticToken]v[StringToken] e[StringToken] ;[SyntheticToken]d[StringToken] a[StringToken] ;[SyntheticToken]s[StringToken] U[StringToken] ;[SyntheticToken]T[StringToken] F[StringToken] ;[SyntheticToken]-[SimpleToken] 1[StringToken] 6[StringToken] L[StringToken] E[StringToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken].[SimpleToken]
+
+m[StringToken] a[StringToken] ;[SyntheticToken]i[StringToken] n[StringToken] ([BeginToken] )[SimpleToken] {[BeginToken]
+p[StringToken] r[StringToken] ;[SyntheticToken]i[StringToken] n[StringToken] ;[SyntheticToken]t[StringToken] ([BeginToken] ""[SyntheticStringToken] ,[SyntheticToken]H[StringToken] ,[SyntheticToken]e[StringToken] ,[SyntheticToken]l[StringToken] ,[SyntheticToken]l[StringToken] ,[SyntheticToken]o[StringToken] ,[SimpleToken] w[StringToken] ,[SyntheticToken]o[StringToken] ,[SyntheticToken]r[StringToken] ,[SyntheticToken]l[StringToken] ,[SyntheticToken]d[StringToken] ![SimpleToken] ,[SyntheticToken]""[SyntheticStringToken] )[SimpleToken] ;[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.scanner.expect
new file mode 100644
index 0000000..669e1c9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/utf_16_le_content.crash_dart.scanner.expect
@@ -0,0 +1,29 @@
+/ / C o p y r i g h t ( c ) 2 0 2 0 , t h e D a r t p r o j e c t a u t h o r s . P l e a s e s e e t h e A U T H O R S f i l e
+/ / f o r d e t a i l s . A l l r i g h t s r e s e r v e d . U s e o f t h i s s o u r c e c o d e i s g o v e r n e d b y a
+/ / B S D - s t y l e l i c e n s e t h a t c a n b e f o u n d i n t h e L I C E N S E . m d f i l e .
+
+/ / T h i s f i l e i s s a v e d a s U T F - 1 6 L E .
+
+m a i n ( ) {
+p r i n t ( "" H e l l o , w o r l d ! "" ) ;
+}
+
+
+[EncodingErrorToken][EncodingErrorToken][AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [UnterminatedString][AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [UnterminatedString][AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]
+[AsciiControlCharacterToken] [AsciiControlCharacterToken] [AsciiControlCharacterToken]/[SimpleToken] /[SimpleToken] C[StringToken] o[StringToken] p[StringToken] y[StringToken] r[StringToken] i[StringToken] g[StringToken] h[StringToken] t[StringToken] ([BeginToken] c[StringToken] )[SimpleToken] 2[StringToken] 0[StringToken] 2[StringToken] 0[StringToken] ,[SimpleToken] t[StringToken] h[StringToken] e[StringToken] D[StringToken] a[StringToken] r[StringToken] t[StringToken] p[StringToken] r[StringToken] o[StringToken] j[StringToken] e[StringToken] c[StringToken] t[StringToken] a[StringToken] u[StringToken] t[StringToken] h[StringToken] o[StringToken] r[StringToken] s[StringToken] .[SimpleToken] P[StringToken] l[StringToken] e[StringToken] a[StringToken] s[StringToken] e[StringToken] s[StringToken] e[StringToken] e[StringToken] t[StringToken] h[StringToken] e[StringToken] A[StringToken] U[StringToken] T[StringToken] H[StringToken] O[StringToken] R[StringToken] S[StringToken] f[StringToken] i[StringToken] l[StringToken] e[StringToken]
+/[SimpleToken] /[SimpleToken] f[StringToken] o[StringToken] r[StringToken] d[StringToken] e[StringToken] t[StringToken] a[StringToken] i[StringToken] l[StringToken] s[StringToken] .[SimpleToken] A[StringToken] l[StringToken] l[StringToken] r[StringToken] i[StringToken] g[StringToken] h[StringToken] t[StringToken] s[StringToken] r[StringToken] e[StringToken] s[StringToken] e[StringToken] r[StringToken] v[StringToken] e[StringToken] d[StringToken] .[SimpleToken] U[StringToken] s[StringToken] e[StringToken] o[StringToken] f[StringToken] t[StringToken] h[StringToken] i[StringToken] s[StringToken] s[StringToken] o[StringToken] u[StringToken] r[StringToken] c[StringToken] e[StringToken] c[StringToken] o[StringToken] d[StringToken] e[StringToken] i[StringToken] s[StringToken] g[StringToken] o[StringToken] v[StringToken] e[StringToken] r[StringToken] n[StringToken] e[StringToken] d[StringToken] b[StringToken] y[StringToken] a[StringToken]
+/[SimpleToken] /[SimpleToken] B[StringToken] S[StringToken] D[StringToken] -[SimpleToken] s[StringToken] t[StringToken] y[StringToken] l[StringToken] e[StringToken] l[StringToken] i[StringToken] c[StringToken] e[StringToken] n[StringToken] s[StringToken] e[StringToken] t[StringToken] h[StringToken] a[StringToken] t[StringToken] c[StringToken] a[StringToken] n[StringToken] b[StringToken] e[StringToken] f[StringToken] o[StringToken] u[StringToken] n[StringToken] d[StringToken] i[StringToken] n[StringToken] t[StringToken] h[StringToken] e[StringToken] L[StringToken] I[StringToken] C[StringToken] E[StringToken] N[StringToken] S[StringToken] E[StringToken] .[SimpleToken] m[StringToken] d[StringToken] f[StringToken] i[StringToken] l[StringToken] e[StringToken] .[SimpleToken]
+
+/[SimpleToken] /[SimpleToken] T[StringToken] h[StringToken] i[StringToken] s[StringToken] f[StringToken] i[StringToken] l[StringToken] e[StringToken] i[StringToken] s[StringToken] s[StringToken] a[StringToken] v[StringToken] e[StringToken] d[StringToken] a[StringToken] s[StringToken] U[StringToken] T[StringToken] F[StringToken] -[SimpleToken] 1[StringToken] 6[StringToken] L[StringToken] E[StringToken] .[SimpleToken]
+
+m[StringToken] a[StringToken] i[StringToken] n[StringToken] ([BeginToken] )[SimpleToken] {[BeginToken]
+p[StringToken] r[StringToken] i[StringToken] n[StringToken] t[StringToken] ([BeginToken] ""[SyntheticStringToken] H[StringToken] e[StringToken] l[StringToken] l[StringToken] o[StringToken] ,[SimpleToken] w[StringToken] o[StringToken] r[StringToken] l[StringToken] d[StringToken] ![SimpleToken] ""[SyntheticStringToken] )[SimpleToken] ;[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart
new file mode 100644
index 0000000..b337598
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart
@@ -0,0 +1,22 @@
+class WrapperClass {
+  int abstract = 42;
+  int as = 42;
+  int covariant = 42;
+  int deferred = 42;
+  int dynamic = 42;
+  int export = 42;
+  int external = 42;
+  int factory = 42;
+  int Function = 42;
+  int get = 42;
+  int implements = 42;
+  int import = 42;
+  int interface = 42;
+  int library = 42;
+  int operator = 42;
+  int mixin = 42;
+  int part = 42;
+  int set = 42;
+  int static = 42;
+  int typedef = 42;
+}
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect
new file mode 100644
index 0000000..3b9db40
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect
@@ -0,0 +1,257 @@
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(WrapperClass, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, WrapperClass)
+      handleNoType(WrapperClass)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(abstract)
+          handleType(int, null)
+          handleIdentifier(abstract, fieldDeclaration)
+          beginFieldInitializer(=)
+            handleLiteralInt(42)
+          endFieldInitializer(=, ;)
+        endClassFields(null, null, null, null, 1, int, ;)
+      endMember()
+      beginMetadataStar(int)
+      endMetadataStar(0)
+      beginMember()
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(as)
+        handleType(int, null)
+        handleIdentifier(as, fieldDeclaration)
+        beginFieldInitializer(=)
+          handleLiteralInt(42)
+        endFieldInitializer(=, ;)
+      endClassFields(null, null, null, null, 1, int, ;)
+    endMember()
+    beginMetadataStar(int)
+    endMetadataStar(0)
+    beginMember()
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(covariant)
+      handleType(int, null)
+      handleIdentifier(covariant, fieldDeclaration)
+      beginFieldInitializer(=)
+        handleLiteralInt(42)
+      endFieldInitializer(=, ;)
+    endClassFields(null, null, null, null, 1, int, ;)
+  endMember()
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginMember()
+    handleIdentifier(int, typeReference)
+    handleNoTypeArguments(deferred)
+    handleType(int, null)
+    handleIdentifier(deferred, fieldDeclaration)
+    beginFieldInitializer(=)
+      handleLiteralInt(42)
+    endFieldInitializer(=, ;)
+  endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+  handleIdentifier(int, typeReference)
+  handleNoTypeArguments(dynamic)
+  handleType(int, null)
+  handleIdentifier(dynamic, fieldDeclaration)
+  beginFieldInitializer(=)
+    handleLiteralInt(42)
+  endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(export)
+handleType(int, null)
+handleIdentifier(export, fieldDeclaration)
+beginFieldInitializer(=)
+  handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(external)
+handleType(int, null)
+handleIdentifier(external, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(factory)
+handleType(int, null)
+handleIdentifier(factory, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(Function)
+handleType(int, null)
+handleIdentifier(Function, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(get)
+handleType(int, null)
+handleIdentifier(get, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(implements)
+handleType(int, null)
+handleIdentifier(implements, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(import)
+handleType(int, null)
+handleIdentifier(import, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(interface)
+handleType(int, null)
+handleIdentifier(interface, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(library)
+handleType(int, null)
+handleIdentifier(library, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(operator)
+handleType(int, null)
+handleIdentifier(operator, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(mixin)
+handleType(int, null)
+handleIdentifier(mixin, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(part)
+handleType(int, null)
+handleIdentifier(part, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(set)
+handleType(int, null)
+handleIdentifier(set, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(static)
+handleType(int, null)
+handleIdentifier(static, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+beginMetadataStar(int)
+endMetadataStar(0)
+beginMember()
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(typedef)
+handleType(int, null)
+handleIdentifier(typedef, fieldDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endClassFields(null, null, null, null, 1, int, ;)
+endMember()
+endClassOrMixinBody(DeclarationKind.Class, 20, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect
new file mode 100644
index 0000000..b8e145f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect
@@ -0,0 +1,495 @@
+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(WrapperClass, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, WrapperClass)
+        parseClass(WrapperClass, class, class, WrapperClass)
+          parseClassHeaderOpt(WrapperClass, class, class)
+            parseClassExtendsOpt(WrapperClass)
+              listener: handleNoType(WrapperClass)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(WrapperClass)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(WrapperClass)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(WrapperClass, DeclarationKind.Class, WrapperClass)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, {, Instance of 'SimpleType', abstract, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(abstract)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(abstract, fieldDeclaration)
+                parseFieldInitializerOpt(abstract, abstract, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', as, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(as)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(as, fieldDeclaration)
+                parseFieldInitializerOpt(as, as, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', covariant, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(covariant)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(covariant, fieldDeclaration)
+                parseFieldInitializerOpt(covariant, covariant, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', deferred, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(deferred)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(deferred, fieldDeclaration)
+                parseFieldInitializerOpt(deferred, deferred, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', dynamic, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(dynamic)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(dynamic, fieldDeclaration)
+                parseFieldInitializerOpt(dynamic, dynamic, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', export, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(export)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(export, fieldDeclaration)
+                parseFieldInitializerOpt(export, export, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', external, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(external)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(external, fieldDeclaration)
+                parseFieldInitializerOpt(external, external, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', factory, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(factory)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(factory, fieldDeclaration)
+                parseFieldInitializerOpt(factory, factory, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', Function, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(Function)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(Function, fieldDeclaration)
+                parseFieldInitializerOpt(Function, Function, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', get, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(get)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(get, fieldDeclaration)
+                parseFieldInitializerOpt(get, get, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', implements, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(implements)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(implements, fieldDeclaration)
+                parseFieldInitializerOpt(implements, implements, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', import, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(import)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(import, fieldDeclaration)
+                parseFieldInitializerOpt(import, import, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', interface, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(interface)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(interface, fieldDeclaration)
+                parseFieldInitializerOpt(interface, interface, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', library, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(library)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(library, fieldDeclaration)
+                parseFieldInitializerOpt(library, library, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              isUnaryMinus(=)
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', operator, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(operator)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(operator, fieldDeclaration)
+                parseFieldInitializerOpt(operator, operator, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', mixin, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(mixin)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(mixin, fieldDeclaration)
+                parseFieldInitializerOpt(mixin, mixin, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', part, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(part)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(part, fieldDeclaration)
+                parseFieldInitializerOpt(part, part, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', set, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(set)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(set, fieldDeclaration)
+                parseFieldInitializerOpt(set, set, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', static, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(static)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(static, fieldDeclaration)
+                parseFieldInitializerOpt(static, static, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', typedef, DeclarationKind.Class, WrapperClass)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(typedef)
+                listener: handleType(int, null)
+                ensureIdentifier(int, fieldDeclaration)
+                  listener: handleIdentifier(typedef, fieldDeclaration)
+                parseFieldInitializerOpt(typedef, typedef, null, null, DeclarationKind.Class, WrapperClass)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralInt(=)
+                            listener: handleLiteralInt(42)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, 1, int, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 20, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.parser.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.parser.expect
new file mode 100644
index 0000000..1f7ddbf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.parser.expect
@@ -0,0 +1,47 @@
+class WrapperClass {
+int abstract = 42;
+int as = 42;
+int covariant = 42;
+int deferred = 42;
+int dynamic = 42;
+int export = 42;
+int external = 42;
+int factory = 42;
+int Function = 42;
+int get = 42;
+int implements = 42;
+int import = 42;
+int interface = 42;
+int library = 42;
+int operator = 42;
+int mixin = 42;
+int part = 42;
+int set = 42;
+int static = 42;
+int typedef = 42;
+}
+
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] abstract[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] as[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] covariant[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] deferred[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] dynamic[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] export[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] external[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] factory[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] Function[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] implements[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] import[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] interface[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] library[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] operator[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] mixin[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] part[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] set[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] static[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] typedef[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.scanner.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.scanner.expect
new file mode 100644
index 0000000..1f7ddbf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.scanner.expect
@@ -0,0 +1,47 @@
+class WrapperClass {
+int abstract = 42;
+int as = 42;
+int covariant = 42;
+int deferred = 42;
+int dynamic = 42;
+int export = 42;
+int external = 42;
+int factory = 42;
+int Function = 42;
+int get = 42;
+int implements = 42;
+int import = 42;
+int interface = 42;
+int library = 42;
+int operator = 42;
+int mixin = 42;
+int part = 42;
+int set = 42;
+int static = 42;
+int typedef = 42;
+}
+
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] abstract[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] as[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] covariant[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] deferred[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] dynamic[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] export[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] external[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] factory[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] Function[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] implements[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] import[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] interface[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] library[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] operator[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] mixin[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] part[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] set[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] static[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] typedef[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart
new file mode 100644
index 0000000..58f62e2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart
@@ -0,0 +1,101 @@
+class WrapperClass {
+  int abstract(int x) {
+    if (x == 0) return 42;
+    return abstract(x - 1);
+  }
+
+  int as(int x) {
+    if (x == 0) return 42;
+    return as(x - 1);
+  }
+
+  int covariant(int x) {
+    if (x == 0) return 42;
+    return covariant(x - 1);
+  }
+
+  int deferred(int x) {
+    if (x == 0) return 42;
+    return deferred(x - 1);
+  }
+
+  int dynamic(int x) {
+    if (x == 0) return 42;
+    return dynamic(x - 1);
+  }
+
+  int export(int x) {
+    if (x == 0) return 42;
+    return export(x - 1);
+  }
+
+  int external(int x) {
+    if (x == 0) return 42;
+    return external(x - 1);
+  }
+
+  int factory(int x) {
+    if (x == 0) return 42;
+    return factory(x - 1);
+  }
+
+  int Function(int x) {
+    if (x == 0) return 42;
+    return Function(x - 1);
+  }
+
+  int get(int x) {
+    if (x == 0) return 42;
+    return get(x - 1);
+  }
+
+  int implements(int x) {
+    if (x == 0) return 42;
+    return implements(x - 1);
+  }
+
+  int import(int x) {
+    if (x == 0) return 42;
+    return import(x - 1);
+  }
+
+  int interface(int x) {
+    if (x == 0) return 42;
+    return interface(x - 1);
+  }
+
+  int library(int x) {
+    if (x == 0) return 42;
+    return library(x - 1);
+  }
+
+  int operator(int x) {
+    if (x == 0) return 42;
+    return operator(x - 1);
+  }
+
+  int mixin(int x) {
+    if (x == 0) return 42;
+    return mixin(x - 1);
+  }
+
+  int part(int x) {
+    if (x == 0) return 42;
+    return part(x - 1);
+  }
+
+  int set(int x) {
+    if (x == 0) return 42;
+    return set(x - 1);
+  }
+
+  int static(int x) {
+    if (x == 0) return 42;
+    return static(x - 1);
+  }
+
+  int typedef(int x) {
+    if (x == 0) return 42;
+    return typedef(x - 1);
+  }
+}
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
new file mode 100644
index 0000000..4e94eac
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
@@ -0,0 +1,1117 @@
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(WrapperClass, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, WrapperClass)
+      handleNoType(WrapperClass)
+      handleClassExtends(null)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, abstract)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(abstract)
+            handleType(int, null)
+            handleIdentifier(abstract, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(abstract, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(abstract, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, as)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(as)
+            handleType(int, null)
+            handleIdentifier(as, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(as, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(as, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, covariant)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(covariant)
+            handleType(int, null)
+            handleIdentifier(covariant, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(covariant, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(covariant, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, deferred)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(deferred)
+            handleType(int, null)
+            handleIdentifier(deferred, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(deferred, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(deferred, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, dynamic)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(dynamic)
+            handleType(int, null)
+            handleIdentifier(dynamic, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(dynamic, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(dynamic, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, export)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(export)
+            handleType(int, null)
+            handleIdentifier(export, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(export, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(export, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, external)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(external)
+            handleType(int, null)
+            handleIdentifier(external, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(external, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(external, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, factory)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(factory)
+            handleType(int, null)
+            handleIdentifier(factory, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(factory, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(factory, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, Function)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(Function)
+            handleType(int, null)
+            handleIdentifier(Function, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(Function, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(Function, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, get)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(get)
+            handleType(int, null)
+            handleIdentifier(get, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(get, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(get, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, implements)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(implements)
+            handleType(int, null)
+            handleIdentifier(implements, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(implements, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(implements, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, import)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(import)
+            handleType(int, null)
+            handleIdentifier(import, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(import, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(import, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, interface)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(interface)
+            handleType(int, null)
+            handleIdentifier(interface, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(interface, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(interface, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, library)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(library)
+            handleType(int, null)
+            handleIdentifier(library, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(library, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(library, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, operator)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(operator)
+            handleType(int, null)
+            handleIdentifier(operator, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(operator, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(operator, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, mixin)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(mixin)
+            handleType(int, null)
+            handleIdentifier(mixin, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(mixin, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(mixin, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, part)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(part)
+            handleType(int, null)
+            handleIdentifier(part, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(part, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(part, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, set)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(set)
+            handleType(int, null)
+            handleIdentifier(set, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(set, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(set, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, static)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(static)
+            handleType(int, null)
+            handleIdentifier(static, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(static, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(static, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, typedef)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(typedef)
+            handleType(int, null)
+            handleIdentifier(typedef, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(==)
+                handleNoArguments(==)
+                handleSend(x, ==)
+                beginBinaryExpression(==)
+                handleLiteralInt(0)
+                endBinaryExpression(==)
+                handleParenthesizedCondition(()
+                beginThenStatement(return)
+                  beginReturnStatement(return)
+                    handleLiteralInt(42)
+                  endReturnStatement(true, return, ;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+              beginReturnStatement(return)
+                handleIdentifier(typedef, expression)
+                handleNoTypeArguments(()
+                beginArguments(()
+                  handleIdentifier(x, expression)
+                  handleNoTypeArguments(-)
+                  handleNoArguments(-)
+                  handleSend(x, -)
+                  beginBinaryExpression(-)
+                  handleLiteralInt(1)
+                  endBinaryExpression(-)
+                endArguments(1, (, ))
+                handleSend(typedef, ;)
+              endReturnStatement(true, return, ;)
+            endBlockFunctionBody(2, {, })
+          endClassMethod(null, int, (, null, })
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 20, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
new file mode 100644
index 0000000..34e9020
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
@@ -0,0 +1,2716 @@
+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(WrapperClass, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, WrapperClass)
+        parseClass(WrapperClass, class, class, WrapperClass)
+          parseClassHeaderOpt(WrapperClass, class, class)
+            parseClassExtendsOpt(WrapperClass)
+              listener: handleNoType(WrapperClass)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(WrapperClass)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(WrapperClass)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(WrapperClass, DeclarationKind.Class, WrapperClass)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod({, null, null, null, null, null, {, Instance of 'SimpleType', null, abstract, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, abstract)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(abstract)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(abstract, methodDeclaration)
+                parseQualifiedRestOpt(abstract, methodDeclarationContinuation)
+                parseMethodTypeVar(abstract)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(abstract, abstract, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(abstract, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(abstract, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(abstract)
+                                      parseArguments(abstract)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(abstract, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, as, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, as)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(as)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(as, methodDeclaration)
+                parseQualifiedRestOpt(as, methodDeclarationContinuation)
+                parseMethodTypeVar(as)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(as, as, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(as, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(as, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(as)
+                                      parseArguments(as)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(as, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, covariant, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, covariant)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(covariant)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(covariant, methodDeclaration)
+                parseQualifiedRestOpt(covariant, methodDeclarationContinuation)
+                parseMethodTypeVar(covariant)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(covariant, covariant, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(covariant, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(covariant, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(covariant)
+                                      parseArguments(covariant)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(covariant, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, deferred, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, deferred)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(deferred)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(deferred, methodDeclaration)
+                parseQualifiedRestOpt(deferred, methodDeclarationContinuation)
+                parseMethodTypeVar(deferred)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(deferred, deferred, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(deferred, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(deferred, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(deferred)
+                                      parseArguments(deferred)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(deferred, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, dynamic, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, dynamic)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(dynamic)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(dynamic, methodDeclaration)
+                parseQualifiedRestOpt(dynamic, methodDeclarationContinuation)
+                parseMethodTypeVar(dynamic)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(dynamic, dynamic, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(dynamic, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(dynamic, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(dynamic)
+                                      parseArguments(dynamic)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(dynamic, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, export, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, export)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(export)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(export, methodDeclaration)
+                parseQualifiedRestOpt(export, methodDeclarationContinuation)
+                parseMethodTypeVar(export)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(export, export, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(export, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(export, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(export)
+                                      parseArguments(export)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(export, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, external, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, external)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(external)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(external, methodDeclaration)
+                parseQualifiedRestOpt(external, methodDeclarationContinuation)
+                parseMethodTypeVar(external)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(external, external, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(external, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(external, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(external)
+                                      parseArguments(external)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(external, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, factory, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, factory)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(factory)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(factory, methodDeclaration)
+                parseQualifiedRestOpt(factory, methodDeclarationContinuation)
+                parseMethodTypeVar(factory)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(factory, factory, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(factory, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(factory, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(factory)
+                                      parseArguments(factory)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(factory, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, Function, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, Function)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(Function)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(Function, methodDeclaration)
+                parseQualifiedRestOpt(Function, methodDeclarationContinuation)
+                parseMethodTypeVar(Function)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(Function, Function, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(Function, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(Function, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(Function)
+                                      parseArguments(Function)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(Function, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, get, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, get)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(get)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(get, methodDeclaration)
+                parseQualifiedRestOpt(get, methodDeclarationContinuation)
+                parseMethodTypeVar(get)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(get, get, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(get, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(get, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(get)
+                                      parseArguments(get)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(get, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, implements, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, implements)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(implements)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(implements, methodDeclaration)
+                parseQualifiedRestOpt(implements, methodDeclarationContinuation)
+                parseMethodTypeVar(implements)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(implements, implements, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(implements, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(implements, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(implements)
+                                      parseArguments(implements)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(implements, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, import, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, import)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(import)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(import, methodDeclaration)
+                parseQualifiedRestOpt(import, methodDeclarationContinuation)
+                parseMethodTypeVar(import)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(import, import, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(import, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(import, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(import)
+                                      parseArguments(import)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(import, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, interface, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, interface)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(interface)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(interface, methodDeclaration)
+                parseQualifiedRestOpt(interface, methodDeclarationContinuation)
+                parseMethodTypeVar(interface)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(interface, interface, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(interface, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(interface, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(interface)
+                                      parseArguments(interface)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(interface, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, library, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, library)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(library)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(library, methodDeclaration)
+                parseQualifiedRestOpt(library, methodDeclarationContinuation)
+                parseMethodTypeVar(library)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(library, library, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(library, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(library, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(library)
+                                      parseArguments(library)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(library, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              isUnaryMinus(()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, operator, DeclarationKind.Class, WrapperClass)
+                isUnaryMinus(()
+                listener: beginMethod(null, null, null, null, null, operator)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(operator)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(operator, methodDeclaration)
+                parseQualifiedRestOpt(operator, methodDeclarationContinuation)
+                parseMethodTypeVar(operator)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(operator, operator, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(operator, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(operator, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(operator)
+                                      parseArguments(operator)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(operator, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, mixin, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, mixin)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(mixin)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(mixin, methodDeclaration)
+                parseQualifiedRestOpt(mixin, methodDeclarationContinuation)
+                parseMethodTypeVar(mixin)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(mixin, mixin, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(mixin, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(mixin, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(mixin)
+                                      parseArguments(mixin)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(mixin, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, part, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, part)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(part)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(part, methodDeclaration)
+                parseQualifiedRestOpt(part, methodDeclarationContinuation)
+                parseMethodTypeVar(part)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(part, part, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(part, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(part, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(part)
+                                      parseArguments(part)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(part, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, set, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, set)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(set)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(set, methodDeclaration)
+                parseQualifiedRestOpt(set, methodDeclarationContinuation)
+                parseMethodTypeVar(set)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(set, set, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(set, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(set, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(set)
+                                      parseArguments(set)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(set, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, static, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, static)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(static)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(static, methodDeclaration)
+                parseQualifiedRestOpt(static, methodDeclarationContinuation)
+                parseMethodTypeVar(static)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(static, static, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(static, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(static, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(static)
+                                      parseArguments(static)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(static, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, int)
+            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, WrapperClass)
+              parseMetadataStar(})
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(}, null, null, null, null, null, }, Instance of 'SimpleType', null, typedef, DeclarationKind.Class, WrapperClass)
+                listener: beginMethod(null, null, null, null, null, typedef)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(typedef)
+                listener: handleType(int, null)
+                ensureIdentifier(int, methodDeclaration)
+                  listener: handleIdentifier(typedef, methodDeclaration)
+                parseQualifiedRestOpt(typedef, methodDeclarationContinuation)
+                parseMethodTypeVar(typedef)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(typedef, typedef, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(typedef, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, x, 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(x, expression)
+                                        listener: handleNoTypeArguments(==)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(==)
+                                        listener: handleSend(x, ==)
+                                listener: beginBinaryExpression(==)
+                                parsePrecedenceExpression(==, 8, true)
+                                  parseUnaryExpression(==, true)
+                                    parsePrimary(==, expression)
+                                      parseLiteralInt(==)
+                                        listener: handleLiteralInt(0)
+                                listener: endBinaryExpression(==)
+                            ensureCloseParen(0, ()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(return)
+                        parseStatement())
+                          parseStatementX())
+                            parseReturnStatement())
+                              listener: beginReturnStatement(return)
+                              parseExpression(return)
+                                parsePrecedenceExpression(return, 1, true)
+                                  parseUnaryExpression(return, true)
+                                    parsePrimary(return, expression)
+                                      parseLiteralInt(return)
+                                        listener: handleLiteralInt(42)
+                              ensureSemicolon(42)
+                              listener: endReturnStatement(true, return, ;)
+                              inGenerator()
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, return)
+                  parseStatement(;)
+                    parseStatementX(;)
+                      parseReturnStatement(;)
+                        listener: beginReturnStatement(return)
+                        parseExpression(return)
+                          parsePrecedenceExpression(return, 1, true)
+                            parseUnaryExpression(return, true)
+                              parsePrimary(return, expression)
+                                inPlainSync()
+                                parseSendOrFunctionLiteral(return, expression)
+                                  looksLikeFunctionBody(;)
+                                  parseSend(return, expression)
+                                    ensureIdentifier(return, expression)
+                                      inPlainSync()
+                                      listener: handleIdentifier(typedef, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArgumentsOpt(typedef)
+                                      parseArguments(typedef)
+                                        parseArgumentsRest(()
+                                          listener: beginArguments(()
+                                          parseExpression(()
+                                            parsePrecedenceExpression((, 1, true)
+                                              parseUnaryExpression((, true)
+                                                parsePrimary((, expression)
+                                                  parseSendOrFunctionLiteral((, expression)
+                                                    parseSend((, expression)
+                                                      ensureIdentifier((, expression)
+                                                        listener: handleIdentifier(x, expression)
+                                                      listener: handleNoTypeArguments(-)
+                                                      parseArgumentsOpt(x)
+                                                        listener: handleNoArguments(-)
+                                                      listener: handleSend(x, -)
+                                              listener: beginBinaryExpression(-)
+                                              parsePrecedenceExpression(-, 14, true)
+                                                parseUnaryExpression(-, true)
+                                                  parsePrimary(-, expression)
+                                                    parseLiteralInt(-)
+                                                      listener: handleLiteralInt(1)
+                                              listener: endBinaryExpression(-)
+                                          listener: endArguments(1, (, ))
+                                    listener: handleSend(typedef, ;)
+                        ensureSemicolon())
+                        listener: endReturnStatement(true, return, ;)
+                        inGenerator()
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(2, {, })
+                listener: endClassMethod(null, int, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 20, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.parser.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.parser.expect
new file mode 100644
index 0000000..055374b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.parser.expect
@@ -0,0 +1,205 @@
+class WrapperClass {
+int abstract(int x) {
+if (x == 0) return 42;
+return abstract(x - 1);
+}
+
+int as(int x) {
+if (x == 0) return 42;
+return as(x - 1);
+}
+
+int covariant(int x) {
+if (x == 0) return 42;
+return covariant(x - 1);
+}
+
+int deferred(int x) {
+if (x == 0) return 42;
+return deferred(x - 1);
+}
+
+int dynamic(int x) {
+if (x == 0) return 42;
+return dynamic(x - 1);
+}
+
+int export(int x) {
+if (x == 0) return 42;
+return export(x - 1);
+}
+
+int external(int x) {
+if (x == 0) return 42;
+return external(x - 1);
+}
+
+int factory(int x) {
+if (x == 0) return 42;
+return factory(x - 1);
+}
+
+int Function(int x) {
+if (x == 0) return 42;
+return Function(x - 1);
+}
+
+int get(int x) {
+if (x == 0) return 42;
+return get(x - 1);
+}
+
+int implements(int x) {
+if (x == 0) return 42;
+return implements(x - 1);
+}
+
+int import(int x) {
+if (x == 0) return 42;
+return import(x - 1);
+}
+
+int interface(int x) {
+if (x == 0) return 42;
+return interface(x - 1);
+}
+
+int library(int x) {
+if (x == 0) return 42;
+return library(x - 1);
+}
+
+int operator(int x) {
+if (x == 0) return 42;
+return operator(x - 1);
+}
+
+int mixin(int x) {
+if (x == 0) return 42;
+return mixin(x - 1);
+}
+
+int part(int x) {
+if (x == 0) return 42;
+return part(x - 1);
+}
+
+int set(int x) {
+if (x == 0) return 42;
+return set(x - 1);
+}
+
+int static(int x) {
+if (x == 0) return 42;
+return static(x - 1);
+}
+
+int typedef(int x) {
+if (x == 0) return 42;
+return typedef(x - 1);
+}
+}
+
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] abstract[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] abstract[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] as[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] as[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] covariant[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] covariant[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] deferred[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] deferred[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] dynamic[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] dynamic[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] export[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] export[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] external[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] external[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] factory[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] factory[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] Function[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] Function[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] get[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] get[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] implements[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] implements[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] import[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] import[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] interface[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] interface[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] library[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] library[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] operator[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] operator[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] mixin[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] mixin[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] part[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] part[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] set[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] set[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] static[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] static[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] typedef[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] typedef[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.scanner.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.scanner.expect
new file mode 100644
index 0000000..055374b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.scanner.expect
@@ -0,0 +1,205 @@
+class WrapperClass {
+int abstract(int x) {
+if (x == 0) return 42;
+return abstract(x - 1);
+}
+
+int as(int x) {
+if (x == 0) return 42;
+return as(x - 1);
+}
+
+int covariant(int x) {
+if (x == 0) return 42;
+return covariant(x - 1);
+}
+
+int deferred(int x) {
+if (x == 0) return 42;
+return deferred(x - 1);
+}
+
+int dynamic(int x) {
+if (x == 0) return 42;
+return dynamic(x - 1);
+}
+
+int export(int x) {
+if (x == 0) return 42;
+return export(x - 1);
+}
+
+int external(int x) {
+if (x == 0) return 42;
+return external(x - 1);
+}
+
+int factory(int x) {
+if (x == 0) return 42;
+return factory(x - 1);
+}
+
+int Function(int x) {
+if (x == 0) return 42;
+return Function(x - 1);
+}
+
+int get(int x) {
+if (x == 0) return 42;
+return get(x - 1);
+}
+
+int implements(int x) {
+if (x == 0) return 42;
+return implements(x - 1);
+}
+
+int import(int x) {
+if (x == 0) return 42;
+return import(x - 1);
+}
+
+int interface(int x) {
+if (x == 0) return 42;
+return interface(x - 1);
+}
+
+int library(int x) {
+if (x == 0) return 42;
+return library(x - 1);
+}
+
+int operator(int x) {
+if (x == 0) return 42;
+return operator(x - 1);
+}
+
+int mixin(int x) {
+if (x == 0) return 42;
+return mixin(x - 1);
+}
+
+int part(int x) {
+if (x == 0) return 42;
+return part(x - 1);
+}
+
+int set(int x) {
+if (x == 0) return 42;
+return set(x - 1);
+}
+
+int static(int x) {
+if (x == 0) return 42;
+return static(x - 1);
+}
+
+int typedef(int x) {
+if (x == 0) return 42;
+return typedef(x - 1);
+}
+}
+
+
+class[KeywordToken] WrapperClass[StringToken] {[BeginToken]
+int[StringToken] abstract[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] abstract[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] as[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] as[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] covariant[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] covariant[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] deferred[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] deferred[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] dynamic[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] dynamic[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] export[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] export[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] external[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] external[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] factory[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] factory[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] Function[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] Function[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] get[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] get[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] implements[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] implements[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] import[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] import[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] interface[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] interface[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] library[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] library[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] operator[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] operator[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] mixin[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] mixin[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] part[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] part[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] set[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] set[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] static[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] static[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] typedef[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] typedef[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart
new file mode 100644
index 0000000..ad56230
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart
@@ -0,0 +1,20 @@
+int abstract = 42;
+int as = 42;
+int covariant = 42;
+int deferred = 42;
+int dynamic = 42;
+int export = 42;
+int external = 42;
+int factory = 42;
+int Function = 42;
+int get = 42;
+int implements = 42;
+int import = 42;
+int interface = 42;
+int library = 42;
+int operator = 42;
+int mixin = 42;
+int part = 42;
+int set = 42;
+int static = 42;
+int typedef = 42;
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.expect
new file mode 100644
index 0000000..77809be
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.expect
@@ -0,0 +1,242 @@
+beginCompilationUnit(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    handleIdentifier(int, typeReference)
+    handleNoTypeArguments(abstract)
+    handleType(int, null)
+    handleIdentifier(abstract, topLevelVariableDeclaration)
+    beginFieldInitializer(=)
+      handleLiteralInt(42)
+    endFieldInitializer(=, ;)
+  endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+  handleIdentifier(int, typeReference)
+  handleNoTypeArguments(as)
+  handleType(int, null)
+  handleIdentifier(as, topLevelVariableDeclaration)
+  beginFieldInitializer(=)
+    handleLiteralInt(42)
+  endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(covariant)
+handleType(int, null)
+handleIdentifier(covariant, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+  handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(deferred)
+handleType(int, null)
+handleIdentifier(deferred, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(dynamic)
+handleType(int, null)
+handleIdentifier(dynamic, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(export)
+handleType(int, null)
+handleIdentifier(export, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(external)
+handleType(int, null)
+handleIdentifier(external, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(factory)
+handleType(int, null)
+handleIdentifier(factory, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(Function)
+handleType(int, null)
+handleIdentifier(Function, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(get)
+handleType(int, null)
+handleIdentifier(get, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(implements)
+handleType(int, null)
+handleIdentifier(implements, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(import)
+handleType(int, null)
+handleIdentifier(import, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(interface)
+handleType(int, null)
+handleIdentifier(interface, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(library)
+handleType(int, null)
+handleIdentifier(library, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(operator)
+handleType(int, null)
+handleIdentifier(operator, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(mixin)
+handleType(int, null)
+handleIdentifier(mixin, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(part)
+handleType(int, null)
+handleIdentifier(part, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(set)
+handleType(int, null)
+handleIdentifier(set, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(static)
+handleType(int, null)
+handleIdentifier(static, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration(int)
+beginMetadataStar(int)
+endMetadataStar(0)
+beginTopLevelMember(int)
+handleIdentifier(int, typeReference)
+handleNoTypeArguments(typedef)
+handleType(int, null)
+handleIdentifier(typedef, topLevelVariableDeclaration)
+beginFieldInitializer(=)
+handleLiteralInt(42)
+endFieldInitializer(=, ;)
+endTopLevelFields(null, null, null, null, 1, int, ;)
+endTopLevelDeclaration()
+endCompilationUnit(20, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.intertwined.expect
new file mode 100644
index 0000000..eed1e21
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.intertwined.expect
@@ -0,0 +1,466 @@
+parseUnit(int)
+  skipErrorTokens(int)
+  listener: beginCompilationUnit(int)
+  syntheticPreviousToken(int)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(int)
+      parseFields(, null, null, null, null, null, , Instance of 'SimpleType', abstract, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(abstract)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(abstract, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(abstract, abstract, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', as, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(as)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(as, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(as, as, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', covariant, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(covariant)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(covariant, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(covariant, covariant, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', deferred, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(deferred)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(deferred, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(deferred, deferred, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', dynamic, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(dynamic)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(dynamic, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(dynamic, dynamic, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', export, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(export)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(export, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(export, export, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', external, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(external)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(external, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(external, external, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', factory, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(factory)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(factory, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(factory, factory, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', Function, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(Function, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(Function, Function, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', get, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(get)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(get, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(get, get, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', implements, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(implements)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(implements, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(implements, implements, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', import, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(import)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(import, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(import, import, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', interface, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(interface)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(interface, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(interface, interface, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', library, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(library)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(library, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(library, library, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', operator, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(operator)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(operator, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(operator, operator, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', mixin, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(mixin)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(mixin, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(mixin, mixin, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', part, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(part)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(part, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(part, part, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', set, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(set)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(set, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(set, set, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', static, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(static)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(static, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(static, static, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(int)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', typedef, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(typedef)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelVariableDeclaration)
+          listener: handleIdentifier(typedef, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(typedef, typedef, null, null, DeclarationKind.TopLevel, null)
+          listener: beginFieldInitializer(=)
+          parseExpression(=)
+            parsePrecedenceExpression(=, 1, true)
+              parseUnaryExpression(=, true)
+                parsePrimary(=, expression)
+                  parseLiteralInt(=)
+                    listener: handleLiteralInt(42)
+          listener: endFieldInitializer(=, ;)
+        listener: endTopLevelFields(null, null, null, null, 1, int, ;)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(int)
+  listener: endCompilationUnit(20, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.parser.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.parser.expect
new file mode 100644
index 0000000..9b81eaf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.parser.expect
@@ -0,0 +1,43 @@
+int abstract = 42;
+int as = 42;
+int covariant = 42;
+int deferred = 42;
+int dynamic = 42;
+int export = 42;
+int external = 42;
+int factory = 42;
+int Function = 42;
+int get = 42;
+int implements = 42;
+int import = 42;
+int interface = 42;
+int library = 42;
+int operator = 42;
+int mixin = 42;
+int part = 42;
+int set = 42;
+int static = 42;
+int typedef = 42;
+
+
+int[StringToken] abstract[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] as[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] covariant[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] deferred[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] dynamic[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] export[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] external[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] factory[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] Function[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] implements[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] import[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] interface[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] library[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] operator[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] mixin[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] part[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] set[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] static[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] typedef[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.scanner.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.scanner.expect
new file mode 100644
index 0000000..9b81eaf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_fields.dart.scanner.expect
@@ -0,0 +1,43 @@
+int abstract = 42;
+int as = 42;
+int covariant = 42;
+int deferred = 42;
+int dynamic = 42;
+int export = 42;
+int external = 42;
+int factory = 42;
+int Function = 42;
+int get = 42;
+int implements = 42;
+int import = 42;
+int interface = 42;
+int library = 42;
+int operator = 42;
+int mixin = 42;
+int part = 42;
+int set = 42;
+int static = 42;
+int typedef = 42;
+
+
+int[StringToken] abstract[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] as[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] covariant[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] deferred[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] dynamic[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] export[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] external[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] factory[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] Function[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] get[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] implements[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] import[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] interface[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] library[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] operator[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] mixin[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] part[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] set[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] static[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+int[StringToken] typedef[KeywordToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart
new file mode 100644
index 0000000..aa2717a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart
@@ -0,0 +1,99 @@
+int abstract(int x) {
+  if (x == 0) return 42;
+  return abstract(x - 1);
+}
+
+int as(int x) {
+  if (x == 0) return 42;
+  return as(x - 1);
+}
+
+int covariant(int x) {
+  if (x == 0) return 42;
+  return covariant(x - 1);
+}
+
+int deferred(int x) {
+  if (x == 0) return 42;
+  return deferred(x - 1);
+}
+
+int dynamic(int x) {
+  if (x == 0) return 42;
+  return dynamic(x - 1);
+}
+
+int export(int x) {
+  if (x == 0) return 42;
+  return export(x - 1);
+}
+
+int external(int x) {
+  if (x == 0) return 42;
+  return external(x - 1);
+}
+
+int factory(int x) {
+  if (x == 0) return 42;
+  return factory(x - 1);
+}
+
+int Function(int x) {
+  if (x == 0) return 42;
+  return Function(x - 1);
+}
+
+int get(int x) {
+  if (x == 0) return 42;
+  return get(x - 1);
+}
+
+int implements(int x) {
+  if (x == 0) return 42;
+  return implements(x - 1);
+}
+
+int import(int x) {
+  if (x == 0) return 42;
+  return import(x - 1);
+}
+
+int interface(int x) {
+  if (x == 0) return 42;
+  return interface(x - 1);
+}
+
+int library(int x) {
+  if (x == 0) return 42;
+  return library(x - 1);
+}
+
+int operator(int x) {
+  if (x == 0) return 42;
+  return operator(x - 1);
+}
+
+int mixin(int x) {
+  if (x == 0) return 42;
+  return mixin(x - 1);
+}
+
+int part(int x) {
+  if (x == 0) return 42;
+  return part(x - 1);
+}
+
+int set(int x) {
+  if (x == 0) return 42;
+  return set(x - 1);
+}
+
+int static(int x) {
+  if (x == 0) return 42;
+  return static(x - 1);
+}
+
+int typedef(int x) {
+  if (x == 0) return 42;
+  return typedef(x - 1);
+}
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect
new file mode 100644
index 0000000..e32cd8e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect
@@ -0,0 +1,1082 @@
+beginCompilationUnit(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(abstract)
+      handleType(int, null)
+      handleIdentifier(abstract, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(abstract, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(abstract, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(as)
+      handleType(int, null)
+      handleIdentifier(as, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(as, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(as, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(covariant)
+      handleType(int, null)
+      handleIdentifier(covariant, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(covariant, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(covariant, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(deferred)
+      handleType(int, null)
+      handleIdentifier(deferred, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(deferred, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(deferred, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(dynamic)
+      handleType(int, null)
+      handleIdentifier(dynamic, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(dynamic, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(dynamic, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(export)
+      handleType(int, null)
+      handleIdentifier(export, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(export, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(export, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(external)
+      handleType(int, null)
+      handleIdentifier(external, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(external, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(external, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(factory)
+      handleType(int, null)
+      handleIdentifier(factory, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(factory, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(factory, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(Function)
+      handleType(int, null)
+      handleIdentifier(Function, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(Function, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(Function, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(get)
+      handleType(int, null)
+      handleIdentifier(get, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(get, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(get, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(implements)
+      handleType(int, null)
+      handleIdentifier(implements, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(implements, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(implements, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(import)
+      handleType(int, null)
+      handleIdentifier(import, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(import, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(import, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(interface)
+      handleType(int, null)
+      handleIdentifier(interface, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(interface, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(interface, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(library)
+      handleType(int, null)
+      handleIdentifier(library, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(library, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(library, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(operator)
+      handleType(int, null)
+      handleIdentifier(operator, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(operator, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(operator, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(mixin)
+      handleType(int, null)
+      handleIdentifier(mixin, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(mixin, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(mixin, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(part)
+      handleType(int, null)
+      handleIdentifier(part, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(part, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(part, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(set)
+      handleType(int, null)
+      handleIdentifier(set, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(set, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(set, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(static)
+      handleType(int, null)
+      handleIdentifier(static, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(static, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(static, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(typedef)
+      handleType(int, null)
+      handleIdentifier(typedef, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginMetadataStar(int)
+        endMetadataStar(0)
+        beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(x)
+          handleType(int, null)
+          handleIdentifier(x, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(x, expression)
+          handleNoTypeArguments(==)
+          handleNoArguments(==)
+          handleSend(x, ==)
+          beginBinaryExpression(==)
+          handleLiteralInt(0)
+          endBinaryExpression(==)
+          handleParenthesizedCondition(()
+          beginThenStatement(return)
+            beginReturnStatement(return)
+              handleLiteralInt(42)
+            endReturnStatement(true, return, ;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+        beginReturnStatement(return)
+          handleIdentifier(typedef, expression)
+          handleNoTypeArguments(()
+          beginArguments(()
+            handleIdentifier(x, expression)
+            handleNoTypeArguments(-)
+            handleNoArguments(-)
+            handleSend(x, -)
+            beginBinaryExpression(-)
+            handleLiteralInt(1)
+            endBinaryExpression(-)
+          endArguments(1, (, ))
+          handleSend(typedef, ;)
+        endReturnStatement(true, return, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(20, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect
new file mode 100644
index 0000000..3c006e5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect
@@ -0,0 +1,2606 @@
+parseUnit(int)
+  skipErrorTokens(int)
+  listener: beginCompilationUnit(int)
+  syntheticPreviousToken(int)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(, null, , Instance of 'SimpleType', null, abstract)
+        listener: beginTopLevelMethod(, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(abstract)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(abstract, topLevelFunctionDeclaration)
+        parseMethodTypeVar(abstract)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(abstract, abstract, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(abstract, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(abstract, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(abstract)
+                              parseArguments(abstract)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(abstract, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, as)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(as)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(as, topLevelFunctionDeclaration)
+        parseMethodTypeVar(as)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(as, as, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(as, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(as, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(as)
+                              parseArguments(as)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(as, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, covariant)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(covariant)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(covariant, topLevelFunctionDeclaration)
+        parseMethodTypeVar(covariant)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(covariant, covariant, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(covariant, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(covariant, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(covariant)
+                              parseArguments(covariant)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(covariant, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, deferred)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(deferred)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(deferred, topLevelFunctionDeclaration)
+        parseMethodTypeVar(deferred)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(deferred, deferred, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(deferred, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(deferred, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(deferred)
+                              parseArguments(deferred)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(deferred, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, dynamic)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(dynamic)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(dynamic, topLevelFunctionDeclaration)
+        parseMethodTypeVar(dynamic)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(dynamic, dynamic, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(dynamic, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(dynamic, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(dynamic)
+                              parseArguments(dynamic)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(dynamic, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, export)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(export)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(export, topLevelFunctionDeclaration)
+        parseMethodTypeVar(export)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(export, export, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(export, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(export, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(export)
+                              parseArguments(export)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(export, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, external)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(external)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(external, topLevelFunctionDeclaration)
+        parseMethodTypeVar(external)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(external, external, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(external, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(external, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(external)
+                              parseArguments(external)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(external, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, factory)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(factory)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(factory, topLevelFunctionDeclaration)
+        parseMethodTypeVar(factory)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(factory, factory, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(factory, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(factory, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(factory)
+                              parseArguments(factory)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(factory, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, Function)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(Function, topLevelFunctionDeclaration)
+        parseMethodTypeVar(Function)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(Function, Function, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(Function, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(Function, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(Function)
+                              parseArguments(Function)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(Function, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, get)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(get)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(get, topLevelFunctionDeclaration)
+        parseMethodTypeVar(get)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(get, get, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(get, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(get, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(get)
+                              parseArguments(get)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(get, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, implements)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(implements)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(implements, topLevelFunctionDeclaration)
+        parseMethodTypeVar(implements)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(implements, implements, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(implements, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(implements, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(implements)
+                              parseArguments(implements)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(implements, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, import)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(import)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(import, topLevelFunctionDeclaration)
+        parseMethodTypeVar(import)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(import, import, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(import, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(import, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(import)
+                              parseArguments(import)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(import, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, interface)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(interface)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(interface, topLevelFunctionDeclaration)
+        parseMethodTypeVar(interface)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(interface, interface, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(interface, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(interface, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(interface)
+                              parseArguments(interface)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(interface, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, library)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(library)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(library, topLevelFunctionDeclaration)
+        parseMethodTypeVar(library)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(library, library, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(library, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(library, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(library)
+                              parseArguments(library)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(library, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, operator)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(operator)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(operator, topLevelFunctionDeclaration)
+        parseMethodTypeVar(operator)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(operator, operator, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(operator, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(operator, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(operator)
+                              parseArguments(operator)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(operator, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, mixin)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(mixin)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(mixin, topLevelFunctionDeclaration)
+        parseMethodTypeVar(mixin)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(mixin, mixin, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(mixin, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(mixin, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(mixin)
+                              parseArguments(mixin)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(mixin, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, part)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(part)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(part, topLevelFunctionDeclaration)
+        parseMethodTypeVar(part)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(part, part, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(part, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(part, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(part)
+                              parseArguments(part)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(part, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, set)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(set)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(set, topLevelFunctionDeclaration)
+        parseMethodTypeVar(set)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(set, set, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(set, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(set, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(set)
+                              parseArguments(set)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(set, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, static)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(static)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(static, topLevelFunctionDeclaration)
+        parseMethodTypeVar(static)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(static, static, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(static, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(static, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(static)
+                              parseArguments(static)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(static, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, }, Instance of 'SimpleType', null, typedef)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(typedef)
+        listener: handleType(int, null)
+        ensureIdentifier(int, topLevelFunctionDeclaration)
+          listener: handleIdentifier(typedef, topLevelFunctionDeclaration)
+        parseMethodTypeVar(typedef)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(typedef, typedef, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(typedef, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(int)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(int, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleIdentifier(int, typeReference)
+                listener: handleNoTypeArguments(x)
+                listener: handleType(int, null)
+                ensureIdentifier(int, formalParameterDeclaration)
+                  listener: handleIdentifier(x, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), 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(x, expression)
+                                listener: handleNoTypeArguments(==)
+                                parseArgumentsOpt(x)
+                                  listener: handleNoArguments(==)
+                                listener: handleSend(x, ==)
+                        listener: beginBinaryExpression(==)
+                        parsePrecedenceExpression(==, 8, true)
+                          parseUnaryExpression(==, true)
+                            parsePrimary(==, expression)
+                              parseLiteralInt(==)
+                                listener: handleLiteralInt(0)
+                        listener: endBinaryExpression(==)
+                    ensureCloseParen(0, ()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(return)
+                parseStatement())
+                  parseStatementX())
+                    parseReturnStatement())
+                      listener: beginReturnStatement(return)
+                      parseExpression(return)
+                        parsePrecedenceExpression(return, 1, true)
+                          parseUnaryExpression(return, true)
+                            parsePrimary(return, expression)
+                              parseLiteralInt(return)
+                                listener: handleLiteralInt(42)
+                      ensureSemicolon(42)
+                      listener: endReturnStatement(true, return, ;)
+                      inGenerator()
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, return)
+          parseStatement(;)
+            parseStatementX(;)
+              parseReturnStatement(;)
+                listener: beginReturnStatement(return)
+                parseExpression(return)
+                  parsePrecedenceExpression(return, 1, true)
+                    parseUnaryExpression(return, true)
+                      parsePrimary(return, expression)
+                        inPlainSync()
+                        parseSendOrFunctionLiteral(return, expression)
+                          looksLikeFunctionBody(;)
+                          parseSend(return, expression)
+                            ensureIdentifier(return, expression)
+                              inPlainSync()
+                              listener: handleIdentifier(typedef, expression)
+                            listener: handleNoTypeArguments(()
+                            parseArgumentsOpt(typedef)
+                              parseArguments(typedef)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseSendOrFunctionLiteral((, expression)
+                                            parseSend((, expression)
+                                              ensureIdentifier((, expression)
+                                                listener: handleIdentifier(x, expression)
+                                              listener: handleNoTypeArguments(-)
+                                              parseArgumentsOpt(x)
+                                                listener: handleNoArguments(-)
+                                              listener: handleSend(x, -)
+                                      listener: beginBinaryExpression(-)
+                                      parsePrecedenceExpression(-, 14, true)
+                                        parseUnaryExpression(-, true)
+                                          parsePrimary(-, expression)
+                                            parseLiteralInt(-)
+                                              listener: handleLiteralInt(1)
+                                      listener: endBinaryExpression(-)
+                                  listener: endArguments(1, (, ))
+                            listener: handleSend(typedef, ;)
+                ensureSemicolon())
+                listener: endReturnStatement(true, return, ;)
+                inGenerator()
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(int)
+  listener: endCompilationUnit(20, )
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.parser.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.parser.expect
new file mode 100644
index 0000000..cef190a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.parser.expect
@@ -0,0 +1,201 @@
+int abstract(int x) {
+if (x == 0) return 42;
+return abstract(x - 1);
+}
+
+int as(int x) {
+if (x == 0) return 42;
+return as(x - 1);
+}
+
+int covariant(int x) {
+if (x == 0) return 42;
+return covariant(x - 1);
+}
+
+int deferred(int x) {
+if (x == 0) return 42;
+return deferred(x - 1);
+}
+
+int dynamic(int x) {
+if (x == 0) return 42;
+return dynamic(x - 1);
+}
+
+int export(int x) {
+if (x == 0) return 42;
+return export(x - 1);
+}
+
+int external(int x) {
+if (x == 0) return 42;
+return external(x - 1);
+}
+
+int factory(int x) {
+if (x == 0) return 42;
+return factory(x - 1);
+}
+
+int Function(int x) {
+if (x == 0) return 42;
+return Function(x - 1);
+}
+
+int get(int x) {
+if (x == 0) return 42;
+return get(x - 1);
+}
+
+int implements(int x) {
+if (x == 0) return 42;
+return implements(x - 1);
+}
+
+int import(int x) {
+if (x == 0) return 42;
+return import(x - 1);
+}
+
+int interface(int x) {
+if (x == 0) return 42;
+return interface(x - 1);
+}
+
+int library(int x) {
+if (x == 0) return 42;
+return library(x - 1);
+}
+
+int operator(int x) {
+if (x == 0) return 42;
+return operator(x - 1);
+}
+
+int mixin(int x) {
+if (x == 0) return 42;
+return mixin(x - 1);
+}
+
+int part(int x) {
+if (x == 0) return 42;
+return part(x - 1);
+}
+
+int set(int x) {
+if (x == 0) return 42;
+return set(x - 1);
+}
+
+int static(int x) {
+if (x == 0) return 42;
+return static(x - 1);
+}
+
+int typedef(int x) {
+if (x == 0) return 42;
+return typedef(x - 1);
+}
+
+
+int[StringToken] abstract[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] abstract[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] as[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] as[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] covariant[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] covariant[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] deferred[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] deferred[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] dynamic[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] dynamic[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] export[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] export[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] external[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] external[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] factory[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] factory[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] Function[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] Function[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] get[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] get[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] implements[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] implements[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] import[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] import[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] interface[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] interface[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] library[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] library[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] operator[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] operator[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] mixin[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] mixin[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] part[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] part[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] set[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] set[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] static[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] static[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] typedef[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] typedef[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.scanner.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.scanner.expect
new file mode 100644
index 0000000..cef190a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.scanner.expect
@@ -0,0 +1,201 @@
+int abstract(int x) {
+if (x == 0) return 42;
+return abstract(x - 1);
+}
+
+int as(int x) {
+if (x == 0) return 42;
+return as(x - 1);
+}
+
+int covariant(int x) {
+if (x == 0) return 42;
+return covariant(x - 1);
+}
+
+int deferred(int x) {
+if (x == 0) return 42;
+return deferred(x - 1);
+}
+
+int dynamic(int x) {
+if (x == 0) return 42;
+return dynamic(x - 1);
+}
+
+int export(int x) {
+if (x == 0) return 42;
+return export(x - 1);
+}
+
+int external(int x) {
+if (x == 0) return 42;
+return external(x - 1);
+}
+
+int factory(int x) {
+if (x == 0) return 42;
+return factory(x - 1);
+}
+
+int Function(int x) {
+if (x == 0) return 42;
+return Function(x - 1);
+}
+
+int get(int x) {
+if (x == 0) return 42;
+return get(x - 1);
+}
+
+int implements(int x) {
+if (x == 0) return 42;
+return implements(x - 1);
+}
+
+int import(int x) {
+if (x == 0) return 42;
+return import(x - 1);
+}
+
+int interface(int x) {
+if (x == 0) return 42;
+return interface(x - 1);
+}
+
+int library(int x) {
+if (x == 0) return 42;
+return library(x - 1);
+}
+
+int operator(int x) {
+if (x == 0) return 42;
+return operator(x - 1);
+}
+
+int mixin(int x) {
+if (x == 0) return 42;
+return mixin(x - 1);
+}
+
+int part(int x) {
+if (x == 0) return 42;
+return part(x - 1);
+}
+
+int set(int x) {
+if (x == 0) return 42;
+return set(x - 1);
+}
+
+int static(int x) {
+if (x == 0) return 42;
+return static(x - 1);
+}
+
+int typedef(int x) {
+if (x == 0) return 42;
+return typedef(x - 1);
+}
+
+
+int[StringToken] abstract[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] abstract[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] as[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] as[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] covariant[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] covariant[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] deferred[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] deferred[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] dynamic[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] dynamic[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] export[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] export[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] external[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] external[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] factory[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] factory[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] Function[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] Function[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] get[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] get[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] implements[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] implements[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] import[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] import[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] interface[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] interface[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] library[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] library[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] operator[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] operator[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] mixin[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] mixin[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] part[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] part[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] set[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] set[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] static[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] static[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+int[StringToken] typedef[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
+return[KeywordToken] typedef[KeywordToken]([BeginToken]x[StringToken] -[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.expect
index 21feac2..3392c1f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.expect
@@ -24,9 +24,11 @@
       handleNoArguments(])
       handleSend(logKey, ])
       handleIndexedExpression(null, [, ])
-      handleIdentifier(Logger, typeReference)
-      handleNoTypeArguments(?)
-      handleType(Logger, ?)
+      beginAsOperatorType(as)
+        handleIdentifier(Logger, typeReference)
+        handleNoTypeArguments(?)
+        handleType(Logger, ?)
+      endAsOperatorType(as)
       handleAsOperator(as)
       beginBinaryExpression(??)
       handleIdentifier(_default, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.intertwined.expect
index 938f7a6..6193bf7 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39697.dart.intertwined.expect
@@ -61,10 +61,12 @@
                               listener: handleSend(logKey, ])
                   listener: handleIndexedExpression(null, [, ])
                 parseAsOperatorRest(])
+                  listener: beginAsOperatorType(as)
                   computeTypeAfterIsOrAs(as)
                   listener: handleIdentifier(Logger, typeReference)
                   listener: handleNoTypeArguments(?)
                   listener: handleType(Logger, ?)
+                  listener: endAsOperatorType(as)
                   listener: handleAsOperator(as)
                   skipChainedAsIsOperators(?)
                 listener: beginBinaryExpression(??)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.expect
index 428d1b6..0656ee2 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.expect
@@ -24,9 +24,11 @@
       handleNoArguments(])
       handleSend(logKey, ])
       handleIndexedExpression(null, [, ])
-      handleIdentifier(Logger, typeReference)
-      handleNoTypeArguments(?)
-      handleType(Logger, ?)
+      beginAsOperatorType(as)
+        handleIdentifier(Logger, typeReference)
+        handleNoTypeArguments(?)
+        handleType(Logger, ?)
+      endAsOperatorType(as)
       handleAsOperator(as)
       handleParenthesizedExpression(()
       beginBinaryExpression(??)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect
index 8e1f84f..08ff17d 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect
@@ -69,10 +69,12 @@
                                               listener: handleSend(logKey, ])
                                   listener: handleIndexedExpression(null, [, ])
                                 parseAsOperatorRest(])
+                                  listener: beginAsOperatorType(as)
                                   computeTypeAfterIsOrAs(as)
                                   listener: handleIdentifier(Logger, typeReference)
                                   listener: handleNoTypeArguments(?)
                                   listener: handleType(Logger, ?)
+                                  listener: endAsOperatorType(as)
                                   listener: handleAsOperator(as)
                                   skipChainedAsIsOperators(?)
                             ensureCloseParen(?, ()
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect
index 04ba926..ba78b91 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect
@@ -59,9 +59,11 @@
             handleNoTypeArguments(as)
             handleNoArguments(as)
             handleSend(o, as)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, ?)
+            beginAsOperatorType(as)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, ?)
+            endAsOperatorType(as)
             handleAsOperator(as)
             handleAssignmentExpression(=)
           endInitializer(,)
@@ -108,9 +110,11 @@
             handleNoTypeArguments(is)
             handleNoArguments(is)
             handleSend(o, is)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, null)
+            beginIsOperatorType(is)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, null)
+            endIsOperatorType(is)
             handleIsOperator(is, null)
             beginConditionalExpression(?)
               handleIdentifier(o, expression)
@@ -170,9 +174,11 @@
             handleNoTypeArguments(is)
             handleNoArguments(is)
             handleSend(o, is)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, ?)
+            beginIsOperatorType(is)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, ?)
+            endIsOperatorType(is)
             handleIsOperator(is, null)
             beginConditionalExpression(?)
               handleIdentifier(o, expression)
@@ -232,9 +238,11 @@
             handleNoTypeArguments(as)
             handleNoArguments(as)
             handleSend(o, as)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, null)
+            beginAsOperatorType(as)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, null)
+            endAsOperatorType(as)
             handleAsOperator(as)
             beginConditionalExpression(?)
               handleIdentifier(o, expression)
@@ -294,9 +302,11 @@
             handleNoTypeArguments(as)
             handleNoArguments(as)
             handleSend(o, as)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, ?)
+            beginAsOperatorType(as)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, ?)
+            endAsOperatorType(as)
             handleAsOperator(as)
             beginConditionalExpression(?)
               handleIdentifier(o, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect
index 12268f2..e271d8f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect
@@ -119,10 +119,12 @@
                                         listener: handleNoArguments(as)
                                       listener: handleSend(o, as)
                               parseAsOperatorRest(o)
+                                listener: beginAsOperatorType(as)
                                 computeTypeAfterIsOrAs(as)
                                 listener: handleIdentifier(String, typeReference)
                                 listener: handleNoTypeArguments(?)
                                 listener: handleType(String, ?)
+                                listener: endAsOperatorType(as)
                                 listener: handleAsOperator(as)
                                 skipChainedAsIsOperators(?)
                             listener: handleAssignmentExpression(=)
@@ -223,10 +225,12 @@
                                         listener: handleNoArguments(is)
                                       listener: handleSend(o, is)
                               parseIsOperatorRest(o)
+                                listener: beginIsOperatorType(is)
                                 computeTypeAfterIsOrAs(is)
                                 listener: handleIdentifier(String, typeReference)
                                 listener: handleNoTypeArguments(?)
                                 listener: handleType(String, null)
+                                listener: endIsOperatorType(is)
                                 listener: handleIsOperator(is, null)
                                 skipChainedAsIsOperators(String)
                               parseConditionalExpressionRest(String)
@@ -360,10 +364,12 @@
                                         listener: handleNoArguments(is)
                                       listener: handleSend(o, is)
                               parseIsOperatorRest(o)
+                                listener: beginIsOperatorType(is)
                                 computeTypeAfterIsOrAs(is)
                                 listener: handleIdentifier(String, typeReference)
                                 listener: handleNoTypeArguments(?)
                                 listener: handleType(String, ?)
+                                listener: endIsOperatorType(is)
                                 listener: handleIsOperator(is, null)
                                 skipChainedAsIsOperators(?)
                               parseConditionalExpressionRest(?)
@@ -497,10 +503,12 @@
                                         listener: handleNoArguments(as)
                                       listener: handleSend(o, as)
                               parseAsOperatorRest(o)
+                                listener: beginAsOperatorType(as)
                                 computeTypeAfterIsOrAs(as)
                                 listener: handleIdentifier(String, typeReference)
                                 listener: handleNoTypeArguments(?)
                                 listener: handleType(String, null)
+                                listener: endAsOperatorType(as)
                                 listener: handleAsOperator(as)
                                 skipChainedAsIsOperators(String)
                               parseConditionalExpressionRest(String)
@@ -634,10 +642,12 @@
                                         listener: handleNoArguments(as)
                                       listener: handleSend(o, as)
                               parseAsOperatorRest(o)
+                                listener: beginAsOperatorType(as)
                                 computeTypeAfterIsOrAs(as)
                                 listener: handleIdentifier(String, typeReference)
                                 listener: handleNoTypeArguments(?)
                                 listener: handleType(String, ?)
+                                listener: endAsOperatorType(as)
                                 listener: handleAsOperator(as)
                                 skipChainedAsIsOperators(?)
                               parseConditionalExpressionRest(?)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect
index 6872f75..188a65b 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect
@@ -59,9 +59,11 @@
             handleNoTypeArguments(as)
             handleNoArguments(as)
             handleSend(o, as)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(,)
-            handleType(String, null)
+            beginAsOperatorType(as)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+            endAsOperatorType(as)
             handleAsOperator(as)
             handleAssignmentExpression(=)
           endInitializer(,)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect
index a584066..edd176f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect
@@ -119,10 +119,12 @@
                                         listener: handleNoArguments(as)
                                       listener: handleSend(o, as)
                               parseAsOperatorRest(o)
+                                listener: beginAsOperatorType(as)
                                 computeTypeAfterIsOrAs(as)
                                 listener: handleIdentifier(String, typeReference)
                                 listener: handleNoTypeArguments(,)
                                 listener: handleType(String, null)
+                                listener: endAsOperatorType(as)
                                 listener: handleAsOperator(as)
                                 skipChainedAsIsOperators(String)
                             listener: handleAssignmentExpression(=)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
index 8571be3..d54c20a 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
@@ -67,9 +67,11 @@
               handleNoTypeArguments(as)
               handleNoArguments(as)
               handleSend(o, as)
-              handleIdentifier(String, typeReference)
-              handleNoTypeArguments(?)
-              handleType(String, ?)
+              beginAsOperatorType(as)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(?)
+                handleType(String, ?)
+              endAsOperatorType(as)
               handleAsOperator(as)
               handleConditionalExpressionColon()
               handleLiteralNull(null)
@@ -115,9 +117,11 @@
             handleNoTypeArguments(is)
             handleNoArguments(is)
             handleSend(x, is)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, ?)
+            beginIsOperatorType(is)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, ?)
+            endIsOperatorType(is)
             handleIsOperator(is, null)
             beginConditionalExpression(?)
               handleLiteralInt(4)
@@ -170,9 +174,11 @@
             handleNoTypeArguments(is)
             handleNoArguments(is)
             handleSend(x, is)
-            handleIdentifier(String, typeReference)
-            handleNoTypeArguments(?)
-            handleType(String, null)
+            beginIsOperatorType(is)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(?)
+              handleType(String, null)
+            endIsOperatorType(is)
             handleIsOperator(is, null)
             beginConditionalExpression(?)
               handleLiteralInt(4)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
index 883e69d..af51107 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
@@ -140,10 +140,12 @@
                                               listener: handleNoArguments(as)
                                             listener: handleSend(o, as)
                                     parseAsOperatorRest(o)
+                                      listener: beginAsOperatorType(as)
                                       computeTypeAfterIsOrAs(as)
                                       listener: handleIdentifier(String, typeReference)
                                       listener: handleNoTypeArguments(?)
                                       listener: handleType(String, ?)
+                                      listener: endAsOperatorType(as)
                                       listener: handleAsOperator(as)
                                       skipChainedAsIsOperators(?)
                                 ensureColon(?)
@@ -247,10 +249,12 @@
                                           listener: handleNoArguments(is)
                                         listener: handleSend(x, is)
                                 parseIsOperatorRest(x)
+                                  listener: beginIsOperatorType(is)
                                   computeTypeAfterIsOrAs(is)
                                   listener: handleIdentifier(String, typeReference)
                                   listener: handleNoTypeArguments(?)
                                   listener: handleType(String, ?)
+                                  listener: endIsOperatorType(is)
                                   listener: handleIsOperator(is, null)
                                   skipChainedAsIsOperators(?)
                                 parseConditionalExpressionRest(?)
@@ -384,10 +388,12 @@
                                           listener: handleNoArguments(is)
                                         listener: handleSend(x, is)
                                 parseIsOperatorRest(x)
+                                  listener: beginIsOperatorType(is)
                                   computeTypeAfterIsOrAs(is)
                                   listener: handleIdentifier(String, typeReference)
                                   listener: handleNoTypeArguments(?)
                                   listener: handleType(String, null)
+                                  listener: endIsOperatorType(is)
                                   listener: handleIsOperator(is, null)
                                   skipChainedAsIsOperators(String)
                                 parseConditionalExpressionRest(String)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart
new file mode 100644
index 0000000..b75f50a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool x;
+bool x;
+
+errors() {
+  print(x);
+  print(x!);
+  print(!x);
+}
+
+class C {
+  C.c0() : super();
+  C.c1() : super()!;
+}
+
+main() {}
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
new file mode 100644
index 0000000..b56f22d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
@@ -0,0 +1,146 @@
+beginCompilationUnit(bool)
+  beginMetadataStar(bool)
+  endMetadataStar(0)
+  beginTopLevelMember(bool)
+    handleIdentifier(bool, typeReference)
+    handleNoTypeArguments(x)
+    handleType(bool, null)
+    handleIdentifier(x, topLevelVariableDeclaration)
+    handleNoFieldInitializer(;)
+  endTopLevelFields(null, null, null, null, 1, bool, ;)
+endTopLevelDeclaration(bool)
+beginMetadataStar(bool)
+endMetadataStar(0)
+beginTopLevelMember(bool)
+  handleIdentifier(bool, typeReference)
+  handleNoTypeArguments(x)
+  handleType(bool, null)
+  handleIdentifier(x, topLevelVariableDeclaration)
+  handleNoFieldInitializer(;)
+endTopLevelFields(null, null, null, null, 1, bool, ;)
+endTopLevelDeclaration(errors)
+beginMetadataStar(errors)
+endMetadataStar(0)
+beginTopLevelMember(errors)
+beginTopLevelMethod(;, null)
+  handleNoType(;)
+  handleIdentifier(errors, topLevelFunctionDeclaration)
+  handleNoTypeVariables(()
+  beginFormalParameters((, MemberKind.TopLevelMethod)
+  endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+  handleAsyncModifier(null, null)
+  beginBlockFunctionBody({)
+    handleIdentifier(print, expression)
+    handleNoTypeArguments(()
+    beginArguments(()
+      handleIdentifier(x, expression)
+      handleNoTypeArguments())
+      handleNoArguments())
+      handleSend(x, ))
+    endArguments(1, (, ))
+    handleSend(print, ;)
+    handleExpressionStatement(;)
+    handleIdentifier(print, expression)
+    handleNoTypeArguments(()
+    beginArguments(()
+      handleIdentifier(x, expression)
+      handleNoTypeArguments(!)
+      handleNoArguments(!)
+      handleSend(x, !)
+      handleNonNullAssertExpression(!)
+    endArguments(1, (, ))
+    handleSend(print, ;)
+    handleExpressionStatement(;)
+    handleIdentifier(print, expression)
+    handleNoTypeArguments(()
+    beginArguments(()
+      handleIdentifier(x, expression)
+      handleNoTypeArguments())
+      handleNoArguments())
+      handleSend(x, ))
+      handleUnaryPrefixExpression(!)
+    endArguments(1, (, ))
+    handleSend(print, ;)
+    handleExpressionStatement(;)
+  endBlockFunctionBody(3, {, })
+endTopLevelMethod(errors, null, })
+endTopLevelDeclaration(class)
+beginMetadataStar(class)
+endMetadataStar(0)
+beginClassOrNamedMixinApplicationPrelude(class)
+handleIdentifier(C, classOrMixinDeclaration)
+handleNoTypeVariables({)
+beginClassDeclaration(class, null, C)
+  handleNoType(C)
+  handleClassExtends(null)
+  handleClassNoWithClause()
+  handleClassOrMixinImplements(null, 0)
+  handleClassHeader(class, class, null)
+  beginClassOrMixinBody(DeclarationKind.Class, {)
+    beginMetadataStar(C)
+    endMetadataStar(0)
+    beginMember()
+      beginMethod(null, null, null, null, null, C)
+        handleNoType({)
+        handleIdentifier(C, methodDeclaration)
+        handleIdentifier(c0, methodDeclarationContinuation)
+        handleQualified(.)
+        handleNoTypeVariables(()
+        beginFormalParameters((, MemberKind.NonStaticMethod)
+        endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+        beginInitializers(:)
+          beginInitializer(super)
+            handleSuperExpression(super, expression)
+            handleNoTypeArguments(()
+            beginArguments(()
+            endArguments(0, (, ))
+            handleSend(super, ;)
+          endInitializer(;)
+        endInitializers(1, :, ;)
+        handleAsyncModifier(null, null)
+        handleEmptyFunctionBody(;)
+      endClassConstructor(null, C, (, :, ;)
+    endMember()
+    beginMetadataStar(C)
+    endMetadataStar(0)
+    beginMember()
+      beginMethod(null, null, null, null, null, C)
+        handleNoType(;)
+        handleIdentifier(C, methodDeclaration)
+        handleIdentifier(c1, methodDeclarationContinuation)
+        handleQualified(.)
+        handleNoTypeVariables(()
+        beginFormalParameters((, MemberKind.NonStaticMethod)
+        endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+        beginInitializers(:)
+          beginInitializer(super)
+            handleSuperExpression(super, expression)
+            handleNoTypeArguments(()
+            beginArguments(()
+            endArguments(0, (, ))
+            handleSend(super, !)
+            handleNonNullAssertExpression(!)
+          endInitializer(;)
+        endInitializers(1, :, ;)
+        handleAsyncModifier(null, null)
+        handleEmptyFunctionBody(;)
+      endClassConstructor(null, C, (, :, ;)
+    endMember()
+  endClassOrMixinBody(DeclarationKind.Class, 2, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration(main)
+beginMetadataStar(main)
+endMetadataStar(0)
+beginTopLevelMember(main)
+beginTopLevelMethod(}, null)
+  handleNoType(})
+  handleIdentifier(main, topLevelFunctionDeclaration)
+  handleNoTypeVariables(()
+  beginFormalParameters((, MemberKind.TopLevelMethod)
+  endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+  handleAsyncModifier(null, null)
+  beginBlockFunctionBody({)
+  endBlockFunctionBody(0, {, })
+endTopLevelMethod(main, null, })
+endTopLevelDeclaration()
+endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
new file mode 100644
index 0000000..ac4681d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
@@ -0,0 +1,337 @@
+parseUnit(bool)
+  skipErrorTokens(bool)
+  listener: beginCompilationUnit(bool)
+  syntheticPreviousToken(bool)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(bool)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(bool)
+      parseFields(, null, null, null, null, null, , Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(bool, typeReference)
+        listener: handleNoTypeArguments(x)
+        listener: handleType(bool, null)
+        ensureIdentifier(bool, topLevelVariableDeclaration)
+          listener: handleIdentifier(x, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, 1, bool, ;)
+  listener: endTopLevelDeclaration(bool)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(bool)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(bool)
+      parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+        listener: handleIdentifier(bool, typeReference)
+        listener: handleNoTypeArguments(x)
+        listener: handleType(bool, null)
+        ensureIdentifier(bool, topLevelVariableDeclaration)
+          listener: handleIdentifier(x, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, 1, bool, ;)
+  listener: endTopLevelDeclaration(errors)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(errors)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(errors)
+      parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, errors)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleNoType(;)
+        ensureIdentifier(;, topLevelFunctionDeclaration)
+          listener: handleIdentifier(errors, topLevelFunctionDeclaration)
+        parseMethodTypeVar(errors)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(errors, errors, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(errors, 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(}, print)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments())
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments())
+                                                listener: handleSend(x, ))
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, print)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(!)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(!)
+                                                listener: handleSend(x, !)
+                                        listener: handleNonNullAssertExpression(!)
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, print)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrecedenceExpression(!, 16, true)
+                                            parseUnaryExpression(!, true)
+                                              parsePrimary(!, expression)
+                                                parseSendOrFunctionLiteral(!, expression)
+                                                  parseSend(!, expression)
+                                                    ensureIdentifier(!, expression)
+                                                      listener: handleIdentifier(x, expression)
+                                                    listener: handleNoTypeArguments())
+                                                    parseArgumentsOpt(x)
+                                                      listener: handleNoArguments())
+                                                    listener: handleSend(x, ))
+                                          listener: handleUnaryPrefixExpression(!)
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(3, {, })
+        listener: endTopLevelMethod(errors, null, })
+  listener: endTopLevelDeclaration(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(C, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, C)
+        parseClass(C, class, class, C)
+          parseClassHeaderOpt(C, class, class)
+            parseClassExtendsOpt(C)
+              listener: handleNoType(C)
+              listener: handleClassExtends(null)
+            parseWithClauseOpt(C)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(C)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(C, DeclarationKind.Class, C)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, C)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, C)
+              parseMetadataStar({)
+                listener: beginMetadataStar(C)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod({, null, null, null, null, null, {, Instance of 'NoType', null, C, DeclarationKind.Class, C)
+                listener: beginMethod(null, null, null, null, null, C)
+                listener: handleNoType({)
+                ensureIdentifier({, methodDeclaration)
+                  listener: handleIdentifier(C, methodDeclaration)
+                parseQualifiedRestOpt(C, methodDeclarationContinuation)
+                  parseQualifiedRest(C, methodDeclarationContinuation)
+                    ensureIdentifier(., methodDeclarationContinuation)
+                      listener: handleIdentifier(c0, methodDeclarationContinuation)
+                    listener: handleQualified(.)
+                parseMethodTypeVar(c0)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(c0, C, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(c0, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  parseInitializers(:)
+                    listener: beginInitializers(:)
+                    parseInitializer(:)
+                      listener: beginInitializer(super)
+                      parseSuperInitializerExpression(:)
+                        parseInitializerExpressionRest(:)
+                          parseExpression(:)
+                            parsePrecedenceExpression(:, 1, true)
+                              parseUnaryExpression(:, true)
+                                parsePrimary(:, expression)
+                                  parseSuperExpression(:, expression)
+                                    listener: handleSuperExpression(super, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArguments(super)
+                                      parseArgumentsRest(()
+                                        listener: beginArguments(()
+                                        listener: endArguments(0, (, ))
+                                    listener: handleSend(super, ;)
+                          listener: endInitializer(;)
+                    listener: endInitializers(1, :, ;)
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: handleEmptyFunctionBody(;)
+                listener: endClassConstructor(null, C, (, :, ;)
+              listener: endMember()
+            notEofOrValue(}, C)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(C)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod(;, null, null, null, null, null, ;, Instance of 'NoType', null, C, DeclarationKind.Class, C)
+                listener: beginMethod(null, null, null, null, null, C)
+                listener: handleNoType(;)
+                ensureIdentifier(;, methodDeclaration)
+                  listener: handleIdentifier(C, methodDeclaration)
+                parseQualifiedRestOpt(C, methodDeclarationContinuation)
+                  parseQualifiedRest(C, methodDeclarationContinuation)
+                    ensureIdentifier(., methodDeclarationContinuation)
+                      listener: handleIdentifier(c1, methodDeclarationContinuation)
+                    listener: handleQualified(.)
+                parseMethodTypeVar(c1)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(c1, C, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(c1, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  parseInitializers(:)
+                    listener: beginInitializers(:)
+                    parseInitializer(:)
+                      listener: beginInitializer(super)
+                      parseSuperInitializerExpression(:)
+                        parseInitializerExpressionRest(:)
+                          parseExpression(:)
+                            parsePrecedenceExpression(:, 1, true)
+                              parseUnaryExpression(:, true)
+                                parsePrimary(:, expression)
+                                  parseSuperExpression(:, expression)
+                                    listener: handleSuperExpression(super, expression)
+                                    listener: handleNoTypeArguments(()
+                                    parseArguments(super)
+                                      parseArgumentsRest(()
+                                        listener: beginArguments(()
+                                        listener: endArguments(0, (, ))
+                                    listener: handleSend(super, !)
+                              listener: handleNonNullAssertExpression(!)
+                          listener: endInitializer(;)
+                    listener: endInitializers(1, :, ;)
+                parseAsyncModifierOpt(!)
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(!, false, true)
+                  listener: handleEmptyFunctionBody(;)
+                listener: endClassConstructor(null, C, (, :, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 2, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(main)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(main)
+      parseTopLevelMethod(}, null, }, Instance of 'NoType', null, main)
+        listener: beginTopLevelMethod(}, null)
+        listener: handleNoType(})
+        ensureIdentifier(}, topLevelFunctionDeclaration)
+          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(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(bool)
+  listener: endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.parser.expect
new file mode 100644
index 0000000..2261909
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.parser.expect
@@ -0,0 +1,33 @@
+bool x;
+bool x;
+
+errors() {
+print(x);
+print(x!);
+print(!x);
+}
+
+class C {
+C.c0() : super();
+C.c1() : super()!;
+}
+
+main() {}
+
+
+bool[StringToken] x[StringToken];[SimpleToken]
+bool[StringToken] x[StringToken];[SimpleToken]
+
+errors[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]x[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]x[StringToken]![SimpleToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]![SimpleToken]x[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+C[StringToken].[SimpleToken]c0[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
+C[StringToken].[SimpleToken]c1[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken]![SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.scanner.expect
new file mode 100644
index 0000000..2261909
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.scanner.expect
@@ -0,0 +1,33 @@
+bool x;
+bool x;
+
+errors() {
+print(x);
+print(x!);
+print(!x);
+}
+
+class C {
+C.c0() : super();
+C.c1() : super()!;
+}
+
+main() {}
+
+
+bool[StringToken] x[StringToken];[SimpleToken]
+bool[StringToken] x[StringToken];[SimpleToken]
+
+errors[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]x[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]x[StringToken]![SimpleToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]![SimpleToken]x[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+C[StringToken].[SimpleToken]c0[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
+C[StringToken].[SimpleToken]c1[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken]![SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index cc63ae0..dd1b0c5 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -8,7 +8,7 @@
 environment:
   sdk: '>=2.2.2 <3.0.0'
 dependencies:
-  _fe_analyzer_shared: 1.0.0
+  _fe_analyzer_shared: ^2.0.0
   kernel: 0.3.29
   package_config:
     path: ../../third_party/pkg_tested/package_config/
diff --git a/pkg/front_end/test/analyser_ignored/load_dill_twice_test.dart b/pkg/front_end/test/analyser_ignored/load_dill_twice_test.dart
index bda78e9..ba07019 100644
--- a/pkg/front_end/test/analyser_ignored/load_dill_twice_test.dart
+++ b/pkg/front_end/test/analyser_ignored/load_dill_twice_test.dart
@@ -18,6 +18,10 @@
 
   Component c = new Component();
   new BinaryBuilder(bytes).readComponent(c);
+  // Print once to lazy-load whatever it needs to lazy-load to print.
+  // This *might* change the textual representation because references can be
+  // created.
+  componentToString(c);
   String loadedOnceString = componentToString(c);
   new BinaryBuilder(bytes).readComponent(c);
   String loadedTwiceString = componentToString(c);
@@ -76,4 +80,5 @@
 
     exit(1);
   }
+  print("OK");
 }
diff --git a/pkg/front_end/test/ast_nodes_has_to_string_test.dart b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
index efab92a0..dd3cbf7 100644
--- a/pkg/front_end/test/ast_nodes_has_to_string_test.dart
+++ b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
@@ -18,7 +18,7 @@
 
   {
     Uri input = Platform.script.resolve("../tool/_fasta/compile.dart");
-    CompilerOptions options = helper.getOptions(targetName: "VM");
+    CompilerOptions options = helper.getOptions();
     helper.TestIncrementalCompiler compiler =
         new helper.TestIncrementalCompiler(
             options,
diff --git a/pkg/front_end/test/binary_md_dill_reader.dart b/pkg/front_end/test/binary_md_dill_reader.dart
index ab2c574..01cf4d9 100644
--- a/pkg/front_end/test/binary_md_dill_reader.dart
+++ b/pkg/front_end/test/binary_md_dill_reader.dart
@@ -117,7 +117,7 @@
 
     // Skip to the start of the index.
     _binaryOffset = _dillContent.length -
-        ((numLibs + 1) + 9 /* number of fixed fields */) * 4;
+        ((numLibs + 1) + 10 /* number of fixed fields */) * 4;
 
     // Read index.
     binaryOffsetForSourceTable = _peekUint32();
@@ -133,6 +133,8 @@
     binaryOffsetForConstantTable = _peekUint32();
     _binaryOffset += 4;
     mainMethodReference = _peekUint32();
+    _binaryOffset += 4;
+    /*int compilationMode = */ _peekUint32();
 
     _binaryOffset = binaryOffsetForStringTable;
     var saved = _readingInstructions["ComponentFile"];
@@ -439,7 +441,7 @@
           instruction == "Byte[] 8bitAlignment;") {
         // Special-case 8-byte alignment.
         int sizeWithoutPadding = _binaryOffset +
-            ((numLibs + 1) + 9 /* number of fixed fields */) * 4;
+            ((numLibs + 1) + 10 /* number of fixed fields */) * 4;
         int padding = 8 - sizeWithoutPadding % 8;
         if (padding == 8) padding = 0;
         _binaryOffset += padding;
diff --git a/pkg/front_end/test/compile_dart2js_with_no_sdk_test.dart b/pkg/front_end/test/compile_dart2js_with_no_sdk_test.dart
new file mode 100644
index 0000000..4939c11
--- /dev/null
+++ b/pkg/front_end/test/compile_dart2js_with_no_sdk_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/api_prototype/compiler_options.dart';
+
+import 'incremental_load_from_dill_suite.dart'
+    show TestIncrementalCompiler, getOptions;
+
+main() async {
+  final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
+  CompilerOptions options = getOptions();
+  options.sdkSummary = options.sdkSummary.resolve("nonexisting.dill");
+  options.librariesSpecificationUri = null;
+  int diagnosticCount = 0;
+  options.onDiagnostic = (DiagnosticMessage message) {
+    // ignoring
+    diagnosticCount++;
+  };
+  TestIncrementalCompiler compiler =
+      new TestIncrementalCompiler(options, dart2jsUrl);
+  await compiler.computeDelta();
+  print("Got a total of $diagnosticCount diagnostics.");
+  if (diagnosticCount < 10000) {
+    // We currently get 43.000+.
+    throw "Less diagnostics than expected.";
+  }
+}
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
new file mode 100644
index 0000000..09bedc5
--- /dev/null
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -0,0 +1,610 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show utf8;
+
+import 'dart:io' show BytesBuilder, File;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
+
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ScannerConfiguration, Token;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, DiagnosticMessage;
+
+import 'package:front_end/src/api_prototype/file_system.dart'
+    show FileSystem, FileSystemEntity, FileSystemException;
+
+import 'package:front_end/src/base/processed_options.dart'
+    show ProcessedOptions;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+    show IncrementalCompiler;
+
+import 'package:kernel/ast.dart' show Component;
+
+import 'package:kernel/target/targets.dart' show Target, TargetFlags;
+
+import "package:vm/target/flutter.dart" show FlutterTarget;
+
+import "package:vm/target/vm.dart" show VmTarget;
+
+import 'incremental_load_from_dill_suite.dart' show getOptions;
+
+import 'parser_test_listener.dart' show ParserTestListener;
+
+import 'parser_suite.dart' as parser_suite;
+
+final FakeFileSystem fs = new FakeFileSystem();
+Uri mainUri;
+Uri platformUri;
+bool nnbd = false;
+bool widgetTransformation = false;
+List<Uri> invalidate = [];
+String targetString = "VM";
+String expectedCrashLine;
+bool byteDelete = false;
+
+main(List<String> arguments) async {
+  String filename;
+  for (String arg in arguments) {
+    if (arg.startsWith("--")) {
+      if (arg == "--nnbd") {
+        nnbd = true;
+      } else if (arg.startsWith("--platform=")) {
+        String platform = arg.substring("--platform=".length);
+        platformUri = Uri.base.resolve(platform);
+      } else if (arg.startsWith("--invalidate=")) {
+        for (String s in arg.substring("--invalidate=".length).split(",")) {
+          invalidate.add(Uri.base.resolve(s));
+        }
+      } else if (arg.startsWith("--widgetTransformation")) {
+        widgetTransformation = true;
+      } else if (arg.startsWith("--target=VM")) {
+        targetString = "VM";
+      } else if (arg.startsWith("--target=flutter")) {
+        targetString = "flutter";
+      } else if (arg.startsWith("--target=ddc")) {
+        targetString = "ddc";
+      } else if (arg == "--byteDelete") {
+        byteDelete = true;
+      } else {
+        throw "Unknown option $arg";
+      }
+    } else if (filename != null) {
+      throw "Already got '$filename', '$arg' is also a filename; "
+          "can only get one";
+    } else {
+      filename = arg;
+    }
+  }
+  if (platformUri == null) {
+    throw "No platform given. Use --platform=/path/to/platform.dill";
+  }
+  if (!new File.fromUri(platformUri).existsSync()) {
+    throw "The platform file '$platformUri' doesn't exist";
+  }
+  if (filename == null) {
+    throw "Need file to operate on";
+  }
+  File file = new File(filename);
+  if (!file.existsSync()) throw "File $filename doesn't exist.";
+  mainUri = file.absolute.uri;
+
+  await tryToMinimize();
+}
+
+Future tryToMinimize() async {
+  // Set main to be basically empty up front.
+  fs.data[mainUri] = utf8.encode("main() {}");
+  Component initialComponent = await getInitialComponent();
+  print("Compiled initially (without data)");
+  // Remove fake cache.
+  fs.data.remove(mainUri);
+
+  // First assure it actually crash on the input.
+  if (!await crashesOnCompile(initialComponent)) {
+    throw "Input doesn't crash the compiler.";
+  }
+  print("Step #1: We did crash on the input!");
+
+  // All file should now be cached.
+  fs._redirectAndRecord = false;
+
+  // For all dart files: Parse them as set their source as the parsed source
+  // to "get around" any encoding issues when printing later.
+  Map<Uri, Uint8List> copy = new Map.from(fs.data);
+  for (Uri uri in fs.data.keys) {
+    String uriString = uri.toString();
+    if (uriString.endsWith(".json") ||
+        uriString.endsWith(".json") ||
+        uriString.endsWith(".packages") ||
+        uriString.endsWith(".dill") ||
+        fs.data[uri] == null ||
+        fs.data[uri].isEmpty) {
+      // skip
+    } else {
+      try {
+        String parsedString = getFileAsStringContent(fs.data[uri], nnbd);
+        fs.data[uri] = utf8.encode(parsedString);
+      } catch (e) {
+        // crash in scanner/parser --- keep original file. This crash might
+        // be what we're looking for!
+      }
+    }
+  }
+  if (!await crashesOnCompile(initialComponent)) {
+    // Now - for whatever reason - we didn't crash. Restore.
+    fs.data.clear();
+    fs.data.addAll(copy);
+  }
+
+  // Operate on one file at a time: Try to delete all content in file.
+  List<Uri> uris = new List<Uri>.from(fs.data.keys);
+
+  bool removedSome = true;
+  while (removedSome) {
+    while (removedSome) {
+      removedSome = false;
+      for (int i = 0; i < uris.length; i++) {
+        Uri uri = uris[i];
+        if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+        print("About to work on file $i of ${uris.length}");
+        await deleteContent(uris, i, false, initialComponent);
+        if (fs.data[uri] == null || fs.data[uri].isEmpty) removedSome = true;
+      }
+    }
+    int left = 0;
+    for (Uri uri in uris) {
+      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+      left++;
+    }
+    print("There's now $left files of ${fs.data.length} files left");
+
+    // Operate on one file at a time.
+    for (Uri uri in fs.data.keys) {
+      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+
+      print("Now working on $uri");
+
+      // Try to delete lines.
+      int prevLength = fs.data[uri].length;
+      await deleteLines(uri, initialComponent);
+      print("We're now at ${fs.data[uri].length} bytes for $uri.");
+      if (prevLength != fs.data[uri].length) removedSome = true;
+      if (fs.data[uri].isEmpty) continue;
+
+      if (byteDelete) {
+        // Now try to delete 'arbitrarily' (for any given start offset do an
+        // exponential binary search).
+        int prevLength = fs.data[uri].length;
+        while (true) {
+          await binarySearchDeleteData(uri, initialComponent);
+
+          if (fs.data[uri].length == prevLength) {
+            // No progress.
+            break;
+          } else {
+            print("We're now at ${fs.data[uri].length} bytes");
+            prevLength = fs.data[uri].length;
+            removedSome = true;
+          }
+        }
+      }
+    }
+  }
+
+  print("\n\nDONE\n\n");
+
+  for (Uri uri in uris) {
+    if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+    print("Uri $uri has this content:");
+
+    try {
+      String utfDecoded = utf8.decode(fs.data[uri], allowMalformed: true);
+      print(utfDecoded);
+    } catch (e) {
+      print(fs.data[uri]);
+      print("(which crashes when trying to decode as utf8)");
+    }
+    print("\n\n====================\n\n");
+  }
+}
+
+Uint8List sublist(Uint8List data, int start, int end) {
+  Uint8List result = new Uint8List(end - start);
+  result.setRange(0, result.length, data, start);
+  return result;
+}
+
+String dataToText(Uint8List data) {
+  StringBuffer sb = new StringBuffer();
+  String comma = "[";
+  for (int i = 0; i < data.length; i++) {
+    sb.write(comma);
+    sb.write(data[i]);
+    comma = ", ";
+    if (i > 100) break;
+  }
+  if (data.length > 100) {
+    sb.write("...");
+  }
+  sb.write("]");
+  return sb.toString();
+}
+
+void binarySearchDeleteData(Uri uri, Component initialComponent) async {
+  Uint8List latestCrashData = fs.data[uri];
+  int offset = 0;
+  while (offset < latestCrashData.length) {
+    print("Working at offset $offset of ${latestCrashData.length}");
+    BytesBuilder builder = new BytesBuilder();
+    builder.add(sublist(latestCrashData, 0, offset));
+    builder.add(sublist(latestCrashData, offset + 1, latestCrashData.length));
+    Uint8List candidate = builder.takeBytes();
+    fs.data[uri] = candidate;
+    if (!await crashesOnCompile(initialComponent)) {
+      // Deleting 1 char didn't crash; don't try to delete anymore starting
+      // here.
+      offset++;
+      continue;
+    }
+
+    // Find how long we can go.
+    int crashingAt = 1;
+    int noLongerCrashingAt;
+    while (true) {
+      int deleteChars = 2 * crashingAt;
+      if (offset + deleteChars > latestCrashData.length) {
+        deleteChars = latestCrashData.length - offset;
+      }
+      builder = new BytesBuilder();
+      builder.add(sublist(latestCrashData, 0, offset));
+      builder.add(sublist(
+          latestCrashData, offset + deleteChars, latestCrashData.length));
+      candidate = builder.takeBytes();
+      fs.data[uri] = candidate;
+      if (!await crashesOnCompile(initialComponent)) {
+        noLongerCrashingAt = deleteChars;
+        break;
+      }
+      crashingAt = deleteChars;
+      if (crashingAt + offset == latestCrashData.length) break;
+    }
+
+    if (noLongerCrashingAt == null) {
+      // We can delete the rest.
+      latestCrashData = candidate;
+      continue;
+    }
+
+    // Binary search between [crashingAt] and [noLongerCrashingAt].
+    while (crashingAt < noLongerCrashingAt) {
+      int mid = noLongerCrashingAt -
+          ((noLongerCrashingAt - crashingAt) >> 1); // Get middle, rounding up.
+      builder = new BytesBuilder();
+      builder.add(sublist(latestCrashData, 0, offset));
+      builder
+          .add(sublist(latestCrashData, offset + mid, latestCrashData.length));
+      candidate = builder.takeBytes();
+      fs.data[uri] = candidate;
+      if (await crashesOnCompile(initialComponent)) {
+        crashingAt = mid;
+      } else {
+        // [noLongerCrashingAt] might actually crash now.
+        noLongerCrashingAt = mid - 1;
+      }
+    }
+
+    // This is basically an assert.
+    builder = new BytesBuilder();
+    builder.add(sublist(latestCrashData, 0, offset));
+    builder.add(
+        sublist(latestCrashData, offset + crashingAt, latestCrashData.length));
+    candidate = builder.takeBytes();
+    fs.data[uri] = candidate;
+    if (!await crashesOnCompile(initialComponent)) {
+      throw "Error in binary search.";
+    }
+    latestCrashData = candidate;
+  }
+
+  fs.data[uri] = latestCrashData;
+}
+
+void _tryToRemoveUnreferencedFileContent(Component initialComponent) async {
+  // Check if there now are any unused files.
+  if (_latestComponent == null) return;
+  Set<Uri> neededUris = _latestComponent.uriToSource.keys.toSet();
+  Map<Uri, Uint8List> copy = new Map.from(fs.data);
+  bool removedSome = false;
+  for (MapEntry<Uri, Uint8List> entry in fs.data.entries) {
+    if (entry.value == null || entry.value.isEmpty) continue;
+    if (!entry.key.toString().endsWith(".dart")) continue;
+    if (!neededUris.contains(entry.key)) {
+      fs.data[entry.key] = new Uint8List(0);
+      print(" => Can probably also delete ${entry.key}");
+      removedSome = true;
+    }
+  }
+  if (removedSome) {
+    if (await crashesOnCompile(initialComponent)) {
+      print(" => Yes; Could remove those too!");
+    } else {
+      print(" => No; Couldn't remove those too!");
+      fs.data.clear();
+      fs.data.addAll(copy);
+    }
+  }
+}
+
+void deleteContent(List<Uri> uris, int uriIndex, bool limitTo1,
+    Component initialComponent) async {
+  if (!limitTo1) {
+    Map<Uri, Uint8List> copy = new Map.from(fs.data);
+    // Try to remove content of i and the next 9 (10 files in total).
+    for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+      Uri uri = uris[j];
+      fs.data[uri] = new Uint8List(0);
+    }
+    if (!await crashesOnCompile(initialComponent)) {
+      // Couldn't delete all 10 files. Restore and try the single one.
+      fs.data.clear();
+      fs.data.addAll(copy);
+    } else {
+      for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+        Uri uri = uris[j];
+        print("Can delete all content of file $uri");
+      }
+      await _tryToRemoveUnreferencedFileContent(initialComponent);
+      return;
+    }
+  }
+
+  Uri uri = uris[uriIndex];
+  Uint8List data = fs.data[uri];
+  fs.data[uri] = new Uint8List(0);
+  if (!await crashesOnCompile(initialComponent)) {
+    print("Can't delete all content of file $uri -- keeping it (for now)");
+    fs.data[uri] = data;
+  } else {
+    print("Can delete all content of file $uri");
+    await _tryToRemoveUnreferencedFileContent(initialComponent);
+  }
+}
+
+void deleteLines(Uri uri, Component initialComponent) async {
+  // Try to delete "lines".
+  Uint8List data = fs.data[uri];
+  const int $LF = 10;
+  List<Uint8List> lines = [];
+  int start = 0;
+  for (int i = 0; i < data.length; i++) {
+    if (data[i] == $LF) {
+      lines.add(sublist(data, start, i));
+      start = i + 1;
+    }
+  }
+  lines.add(sublist(data, start, data.length));
+  List<bool> include = new List.filled(lines.length, true);
+  Uint8List latestCrashData = data;
+  int length = 1;
+  int i = 0;
+  while (i < lines.length) {
+    if (i + length > lines.length) {
+      length = lines.length - i;
+    }
+    for (int j = i; j < i + length; j++) {
+      include[j] = false;
+    }
+    final BytesBuilder builder = new BytesBuilder();
+    for (int j = 0; j < lines.length; j++) {
+      if (include[j]) {
+        builder.add(lines[j]);
+        if (j + 1 < lines.length) {
+          builder.addByte($LF);
+        }
+      }
+    }
+    Uint8List candidate = builder.takeBytes();
+    fs.data[uri] = candidate;
+    if (!await crashesOnCompile(initialComponent)) {
+      // Didn't crash => Can't remove line i-j.
+      for (int j = i; j < i + length; j++) {
+        include[j] = true;
+      }
+      if (length > 2) {
+        // Retry with length 2 at same i.
+        // The idea here is that for instance formatted json might have lines
+        // looking like
+        // {
+        // }
+        // where deleting just one line makes it invalid.
+        length = 2;
+      } else if (length > 1) {
+        // Retry with length 1 at same i.
+        length = 1;
+      } else {
+        // Couldn't with length 1 either.
+        i++;
+      }
+    } else {
+      print("Can delete line $i (inclusive) - ${i + length} (exclusive) "
+          "(of ${lines.length})");
+      latestCrashData = candidate;
+      i += length;
+      length *= 2;
+    }
+  }
+  fs.data[uri] = latestCrashData;
+}
+
+Component _latestComponent;
+
+Future<bool> crashesOnCompile(Component initialComponent) async {
+  IncrementalCompiler incrementalCompiler =
+      new IncrementalCompiler.fromComponent(
+          setupCompilerContext(), initialComponent);
+  incrementalCompiler.invalidate(mainUri);
+  try {
+    _latestComponent = await incrementalCompiler.computeDelta();
+    for (Uri uri in invalidate) {
+      incrementalCompiler.invalidate(uri);
+      await incrementalCompiler.computeDelta();
+    }
+    return false;
+  } catch (e, st) {
+    // Find line with #0 in it.
+    String eWithSt = "$e\n\n$st";
+    List<String> lines = eWithSt.split("\n");
+    String foundLine;
+    for (String line in lines) {
+      if (line.startsWith("#0")) {
+        foundLine = line;
+        break;
+      }
+    }
+    if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
+    if (expectedCrashLine == null) {
+      print("Got $foundLine");
+      expectedCrashLine = foundLine;
+      return true;
+    } else if (foundLine == expectedCrashLine) {
+      return true;
+    } else {
+      print("Crashed, but another place: $foundLine");
+      return false;
+    }
+  }
+}
+
+Future<Component> getInitialComponent() async {
+  IncrementalCompiler incrementalCompiler =
+      new IncrementalCompiler(setupCompilerContext());
+  Component originalComponent = await incrementalCompiler.computeDelta();
+  return originalComponent;
+}
+
+CompilerContext setupCompilerContext() {
+  CompilerOptions options = getOptions();
+
+  TargetFlags targetFlags = new TargetFlags(
+      enableNullSafety: nnbd, trackWidgetCreation: widgetTransformation);
+  Target target;
+  switch (targetString) {
+    case "VM":
+      target = new VmTarget(targetFlags);
+      break;
+    case "flutter":
+      target = new FlutterTarget(targetFlags);
+      break;
+    case "ddc":
+      target = new DevCompilerTarget(targetFlags);
+      break;
+    default:
+      throw "Unknown target '$target'";
+  }
+  options.target = target;
+  options.fileSystem = fs;
+  options.sdkRoot = null;
+  options.sdkSummary = platformUri;
+  options.omitPlatform = false;
+  options.onDiagnostic = (DiagnosticMessage message) {
+    // don't care.
+  };
+
+  CompilerContext compilerContext = new CompilerContext(
+      new ProcessedOptions(options: options, inputs: [mainUri]));
+  return compilerContext;
+}
+
+String getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
+  List<int> lineStarts = new List<int>();
+
+  Token firstToken = parser_suite.scanRawBytes(rawBytes,
+      nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
+
+  if (firstToken == null) {
+    throw "Got null token from scanner";
+  }
+
+  ParserTestListener parserTestListener = new ParserTestListener(false);
+  Parser parser = new Parser(parserTestListener);
+  parser.parseUnit(firstToken);
+  String parsedString =
+      parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
+  return parsedString;
+}
+
+ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+    enableTripleShift: true,
+    enableExtensionMethods: true,
+    enableNonNullable: true);
+
+ScannerConfiguration scannerConfigurationNonNNBD = new ScannerConfiguration(
+    enableTripleShift: true,
+    enableExtensionMethods: true,
+    enableNonNullable: false);
+
+class FakeFileSystem extends FileSystem {
+  bool _redirectAndRecord = true;
+  final Map<Uri, Uint8List> data = {};
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    return new FakeFileSystemEntity(this, uri);
+  }
+}
+
+class FakeFileSystemEntity extends FileSystemEntity {
+  final FakeFileSystem fs;
+  final Uri uri;
+  FakeFileSystemEntity(this.fs, this.uri);
+
+  void _ensureCachedIfOk() {
+    if (fs.data.containsKey(uri)) return;
+    if (!fs._redirectAndRecord) {
+      throw "Asked for file in non-recording mode that wasn't known";
+    }
+    File f = new File.fromUri(uri);
+    if (!f.existsSync()) {
+      fs.data[uri] = null;
+      return;
+    }
+    fs.data[uri] = f.readAsBytesSync();
+  }
+
+  @override
+  Future<bool> exists() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) return Future.value(false);
+    return Future.value(true);
+  }
+
+  @override
+  Future<List<int>> readAsBytes() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+    return Future.value(data);
+  }
+
+  @override
+  Future<String> readAsString() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+    return Future.value(utf8.decode(data));
+  }
+}
diff --git a/pkg/front_end/test/explicit_creation_test.dart b/pkg/front_end/test/explicit_creation_test.dart
index c6d3fca..fd6ded1 100644
--- a/pkg/front_end/test/explicit_creation_test.dart
+++ b/pkg/front_end/test/explicit_creation_test.dart
@@ -224,7 +224,8 @@
       String name,
       List<UnresolvedType> typeArguments,
       int charOffset,
-      Constness constness) {
+      Constness constness,
+      {bool isTypeArgumentsInForest = false}) {
     Token maybeNewOrConst = nameToken.previous;
     bool doReport = true;
     if (maybeNewOrConst is KeywordToken) {
@@ -247,7 +248,8 @@
           nameToken.length);
     }
     return super.buildConstructorInvocation(type, nameToken, nameLastToken,
-        arguments, name, typeArguments, charOffset, constness);
+        arguments, name, typeArguments, charOffset, constness,
+        isTypeArgumentsInForest: isTypeArgumentsInForest);
   }
 }
 
diff --git a/pkg/front_end/test/fasta/bootstrap_test.dart b/pkg/front_end/test/fasta/bootstrap_test.dart
index f4755f4..39effb5 100644
--- a/pkg/front_end/test/fasta/bootstrap_test.dart
+++ b/pkg/front_end/test/fasta/bootstrap_test.dart
@@ -8,6 +8,8 @@
 
 import 'package:async_helper/async_helper.dart' show asyncEnd, asyncStart;
 
+import 'package:front_end/src/base/command_line_options.dart';
+
 import 'package:testing/testing.dart' show StdioProcess;
 
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
@@ -50,9 +52,9 @@
       dartVm.toFilePath(),
       <String>[
         compiler.toFilePath(),
-        "--compile-sdk=sdk/",
-        "--output=${output.toFilePath()}",
-        "--verify",
+        "${Flags.compileSdk}=sdk/",
+        "${Flags.output}=${output.toFilePath()}",
+        Flags.verify,
         input.toFilePath(),
       ],
       suppressOutput: false);
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 6158ba6..356924f 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -170,7 +170,7 @@
     check("IncompleteErrorGenerator(offset: 4, message: Unspecified)",
         new IncompleteErrorGenerator(helper, token, message));
     check("SendAccessGenerator(offset: 4, name: bar, arguments: (\"arg\"))",
-        new SendAccessGenerator(helper, token, name, arguments));
+        new SendAccessGenerator(helper, token, name, null, arguments));
     check("IncompletePropertyAccessGenerator(offset: 4, name: bar)",
         new IncompletePropertyAccessGenerator(helper, token, name));
     check(
diff --git a/pkg/front_end/test/fasta/object_supertype_test.dart b/pkg/front_end/test/fasta/object_supertype_test.dart
index 3d13824..1f37142 100644
--- a/pkg/front_end/test/fasta/object_supertype_test.dart
+++ b/pkg/front_end/test/fasta/object_supertype_test.dart
@@ -51,7 +51,9 @@
       }));
 
   fs.entityForUri(base.resolve("sdk/lib/core/core.dart")).writeAsStringSync(
-      defaultDartCoreSource.replaceAll("class Object {", "$objectHeader"));
+      defaultDartCoreSource
+          .replaceAll("class Object {", "$objectHeader")
+          .replaceAll("const Object();", ""));
 
   final List<DiagnosticMessage> messages = <DiagnosticMessage>[];
 
diff --git a/pkg/front_end/test/fasta/parser/parser.status b/pkg/front_end/test/fasta/parser/parser.status
index 94d326c3..741a8c4 100644
--- a/pkg/front_end/test/fasta/parser/parser.status
+++ b/pkg/front_end/test/fasta/parser/parser.status
@@ -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.md file.
 
+issue23520: Fail
+issue28367: Fail
 pkg/analyzer_cli/test/data/file_with_error: Fail
+pkg/front_end/test/fasta/function_type_recovery: Fail
 pkg/front_end/test/fasta/rasta/bad_interpolation: Fail
 pkg/front_end/test/fasta/rasta/issue_000032: Fail
 pkg/front_end/test/fasta/rasta/issue_000035: Fail
@@ -47,15 +50,15 @@
 runtime/lib/core_patch: Fail
 runtime/lib/date_patch: Fail
 runtime/lib/developer: Fail
-runtime/lib/double: Fail
 runtime/lib/double_patch: Fail
+runtime/lib/double: Fail
 runtime/lib/errors_patch: Fail
-runtime/lib/function: Fail
 runtime/lib/function_patch: Fail
+runtime/lib/function: Fail
 runtime/lib/growable_array: Fail
 runtime/lib/identical_patch: Fail
-runtime/lib/integers: Fail
 runtime/lib/integers_patch: Fail
+runtime/lib/integers: Fail
 runtime/lib/internal_patch: Fail
 runtime/lib/isolate_patch: Fail
 runtime/lib/lib_prefix: Fail
@@ -71,8 +74,8 @@
 runtime/lib/string_patch: Fail
 runtime/lib/timeline: Fail
 runtime/lib/type_patch: Fail
-runtime/lib/typed_data: Fail
 runtime/lib/typed_data_patch: Fail
+runtime/lib/typed_data: Fail
 runtime/lib/uri_patch: Fail
 runtime/lib/vmservice_patch: Fail
 runtime/lib/weak_property: Fail
@@ -117,40 +120,6 @@
 tests/co19/src/Language/Classes/Constructors/Generative_Constructors/initializers_t16: Fail
 tests/co19/src/Language/Classes/Constructors/Generative_Constructors/syntax_t03: Fail
 tests/co19/src/Language/Classes/Constructors/Generative_Constructors/syntax_t06: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t02: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t03: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t04: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t05: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t06: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t07: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t08: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t09: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t10: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t11: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t12: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t13: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t14: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t15: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t16: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t17: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t18: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t19: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t20: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t21: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t22: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/optional_parameter_t05: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/optional_parameter_t07: Fail
-tests/co19/src/Language/Classes/Instance_Methods/Operators/syntax_t02: Fail
-tests/co19/src/Language/Classes/Setters/name_t08: Fail
-tests/co19/src/Language/Classes/Setters/name_t09: Fail
-tests/co19/src/Language/Classes/Setters/name_t10: Fail
-tests/co19/src/Language/Classes/Setters/name_t11: Fail
-tests/co19/src/Language/Classes/Setters/name_t12: Fail
-tests/co19/src/Language/Classes/Setters/name_t13: Fail
-tests/co19/src/Language/Classes/Setters/name_t14: Fail
-tests/co19/src/Language/Classes/Setters/name_t15: Fail
-tests/co19/src/Language/Classes/Superclasses/wrong_superclass_t06: Fail
-tests/co19/src/Language/Classes/Superinterfaces/syntax_t02: Fail
 tests/co19/src/Language/Classes/declarations_t12: Fail
 tests/co19/src/Language/Classes/declarations_t13: Fail
 tests/co19/src/Language/Classes/declarations_t14: Fail
@@ -192,6 +161,30 @@
 tests/co19/src/Language/Classes/definition_t19: Fail
 tests/co19/src/Language/Classes/definition_t21: Fail
 tests/co19/src/Language/Classes/definition_t22: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t02: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t03: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t04: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t05: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t06: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t07: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t08: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t09: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t10: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t11: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t12: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t13: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t14: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t15: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t16: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t17: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t18: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t19: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t20: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t21: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/allowed_names_t22: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/optional_parameter_t05: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/optional_parameter_t07: Fail
+tests/co19/src/Language/Classes/Instance_Methods/Operators/syntax_t02: Fail
 tests/co19/src/Language/Classes/member_definition_t01: Fail
 tests/co19/src/Language/Classes/member_definition_t02: Fail
 tests/co19/src/Language/Classes/member_definition_t04: Fail
@@ -218,14 +211,24 @@
 tests/co19/src/Language/Classes/method_definition_t08: Fail
 tests/co19/src/Language/Classes/method_definition_t09: Fail
 tests/co19/src/Language/Classes/mixins_t02: Fail
+tests/co19/src/Language/Classes/Setters/name_t08: Fail
+tests/co19/src/Language/Classes/Setters/name_t09: Fail
+tests/co19/src/Language/Classes/Setters/name_t10: Fail
+tests/co19/src/Language/Classes/Setters/name_t11: Fail
+tests/co19/src/Language/Classes/Setters/name_t12: Fail
+tests/co19/src/Language/Classes/Setters/name_t13: Fail
+tests/co19/src/Language/Classes/Setters/name_t14: Fail
+tests/co19/src/Language/Classes/Setters/name_t15: Fail
+tests/co19/src/Language/Classes/Superclasses/wrong_superclass_t06: Fail
+tests/co19/src/Language/Classes/Superinterfaces/syntax_t02: Fail
 tests/co19/src/Language/Enums/syntax_t04: Fail
 tests/co19/src/Language/Enums/syntax_t05: Fail
 tests/co19/src/Language/Enums/syntax_t06: Fail
 tests/co19/src/Language/Enums/syntax_t07: Fail
 tests/co19/src/Language/Enums/syntax_t08: Fail
 tests/co19/src/Language/Enums/syntax_t09: Fail
-tests/co19/src/Language/Errors_and_Warnings/compile_error_lib: Fail
 tests/co19/src/Language/Errors_and_Warnings/compile_error_lib_p2: Fail
+tests/co19/src/Language/Errors_and_Warnings/compile_error_lib: Fail
 tests/co19/src/Language/Errors_and_Warnings/compile_error_t01: Fail
 tests/co19/src/Language/Errors_and_Warnings/compile_error_t02: Fail
 tests/co19/src/Language/Errors_and_Warnings/compile_error_t03: Fail
@@ -667,15 +670,6 @@
 tests/co19/src/Language/Expressions/Shift/syntax_t05: Fail
 tests/co19/src/Language/Expressions/Shift/syntax_t06: Fail
 tests/co19/src/Language/Expressions/Shift/syntax_t07: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t02: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t03: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t08: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t09: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t10: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t11: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t14: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t15: Fail
-tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t16: Fail
 tests/co19/src/Language/Expressions/Strings/multi_line_t02: Fail
 tests/co19/src/Language/Expressions/Strings/multi_line_t03: Fail
 tests/co19/src/Language/Expressions/Strings/multi_line_t04: Fail
@@ -714,6 +708,15 @@
 tests/co19/src/Language/Expressions/Strings/multi_line_t40: Fail
 tests/co19/src/Language/Expressions/Strings/multi_line_t42: Fail
 tests/co19/src/Language/Expressions/Strings/multi_line_t44: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t02: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t03: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t08: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t09: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t10: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t11: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t14: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t15: Fail
+tests/co19/src/Language/Expressions/Strings/String_Interpolation/syntax_t16: Fail
 tests/co19/src/Language/Expressions/Strings/string_literal_t02: Fail
 tests/co19/src/Language/Expressions/Strings/string_literal_t03: Fail
 tests/co19/src/Language/Expressions/Strings/string_literal_t04: Fail
@@ -818,6 +821,21 @@
 tests/co19/src/Language/Generics/syntax_t15: Fail
 tests/co19/src/Language/Generics/syntax_t17: Fail
 tests/co19/src/Language/Interfaces/Superinterfaces/definition_t05: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t15_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t16_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t17_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t18_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t19_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t20_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t21_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t22_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t23_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t24_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t25_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t26_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t27_lib: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t28: Fail
+tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t29_lib: Fail
 tests/co19/src/Language/Libraries_and_Scripts/Exports/syntax_t01_lib: Fail
 tests/co19/src/Language/Libraries_and_Scripts/Exports/syntax_t04_lib: Fail
 tests/co19/src/Language/Libraries_and_Scripts/Exports/syntax_t05_lib: Fail
@@ -892,21 +910,6 @@
 tests/co19/src/Language/Libraries_and_Scripts/Scripts/top_level_syntax_t16: Fail
 tests/co19/src/Language/Libraries_and_Scripts/Scripts/top_level_syntax_t17: Fail
 tests/co19/src/Language/Libraries_and_Scripts/Scripts/top_level_syntax_t18: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t15_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t16_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t17_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t18_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t19_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t20_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t21_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t22_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t23_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t24_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t25_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t26_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t27_lib: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t28: Fail
-tests/co19/src/Language/Libraries_and_Scripts/definition_syntax_t29_lib: Fail
 tests/co19/src/Language/Libraries_and_Scripts/top_level_syntax_t02_lib: Fail
 tests/co19/src/Language/Libraries_and_Scripts/top_level_syntax_t03_lib: Fail
 tests/co19/src/Language/Libraries_and_Scripts/top_level_syntax_t04_lib: Fail
@@ -1466,6 +1469,10 @@
 tests/co19/src/Language/Statements/While/syntax_t02: Fail
 tests/co19/src/Language/Statements/While/syntax_t03: Fail
 tests/co19/src/Language/Statements/While/syntax_t04: Fail
+tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t07: Fail
+tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t08: Fail
+tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t09: Fail
+tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t10: Fail
 tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield/location_t01: Fail
 tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield/location_t03: Fail
 tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield/location_t05: Fail
@@ -1473,10 +1480,6 @@
 tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield/syntax_t08: Fail
 tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield/syntax_t09: Fail
 tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield/syntax_t10: Fail
-tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t07: Fail
-tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t08: Fail
-tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t09: Fail
-tests/co19/src/Language/Statements/Yield_and_Yield_Each/Yield_Each/syntax_t10: Fail
 tests/co19/src/Language/Types/Static_Types/syntax_t01: Fail
 tests/co19/src/Language/Types/Static_Types/syntax_t02: Fail
 tests/co19/src/Language/Types/Static_Types/syntax_t03: Fail
@@ -1533,16 +1536,15 @@
 tests/co19/src/Language/Variables/syntax_t22: Fail
 tests/co19/src/Language/Variables/syntax_t23: Fail
 tests/co19/src/LibTest/html/HttpRequest/responseType_A01_t03: Fail
-tests/co19/src/WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: Fail
 tests/co19/src/WebPlatformTest/dom/nodes/Document-createElement_t01: Fail
+tests/co19/src/WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: Fail
 tests/co19/src/WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: Fail
-tests/compiler/dart2js/data/one_line_dart_program: Fail
-tests/compiler/dart2js_extra/LayoutTests_fast_mediastream_getusermedia_t01_test: Fail
 tests/compiler/dart2js_extra/deferred_custom_loader_test: Fail
 tests/compiler/dart2js_extra/empty_negative_test: Fail
-tests/compiler/dart2js_extra/invalid_annotation2_test: Fail
 tests/compiler/dart2js_extra/invalid_annotation_test: Fail
+tests/compiler/dart2js_extra/invalid_annotation2_test: Fail
 tests/compiler/dart2js_extra/invalid_length_negative_test: Fail
+tests/compiler/dart2js_extra/LayoutTests_fast_mediastream_getusermedia_t01_test: Fail
 tests/compiler/dart2js_extra/switch_test: Fail
 tests/compiler/dart2js_extra/timer_negative_test: Fail
 tests/compiler/dart2js_extra/typed_locals_test: Fail
@@ -1558,8 +1560,8 @@
 tests/compiler/dart2js_native/event_loop_test: Fail
 tests/compiler/dart2js_native/fake_thing_2_test: Fail
 tests/compiler/dart2js_native/fake_thing_test: Fail
-tests/compiler/dart2js_native/field_type2_test: Fail
 tests/compiler/dart2js_native/field_type_test: Fail
+tests/compiler/dart2js_native/field_type2_test: Fail
 tests/compiler/dart2js_native/fixup_get_tag_test: Fail
 tests/compiler/dart2js_native/hash_code_test: Fail
 tests/compiler/dart2js_native/issue9182_test: Fail
@@ -1585,12 +1587,12 @@
 tests/compiler/dart2js_native/native_equals_frog_test: Fail
 tests/compiler/dart2js_native/native_exception2_test: Fail
 tests/compiler/dart2js_native/native_exceptions1_frog_test: Fail
+tests/compiler/dart2js_native/native_field_invocation_test: Fail
 tests/compiler/dart2js_native/native_field_invocation2_test: Fail
 tests/compiler/dart2js_native/native_field_invocation3_test: Fail
 tests/compiler/dart2js_native/native_field_invocation4_test: Fail
 tests/compiler/dart2js_native/native_field_invocation5_test: Fail
 tests/compiler/dart2js_native/native_field_invocation6_test: Fail
-tests/compiler/dart2js_native/native_field_invocation_test: Fail
 tests/compiler/dart2js_native/native_field_name_test: Fail
 tests/compiler/dart2js_native/native_field_optimization_test: Fail
 tests/compiler/dart2js_native/native_field_rename_1_frog_test: Fail
@@ -1605,18 +1607,18 @@
 tests/compiler/dart2js_native/native_missing_method1_frog_test: Fail
 tests/compiler/dart2js_native/native_missing_method2_frog_test: Fail
 tests/compiler/dart2js_native/native_mixin_field_test: Fail
+tests/compiler/dart2js_native/native_mixin_multiple_test: Fail
 tests/compiler/dart2js_native/native_mixin_multiple2_test: Fail
 tests/compiler/dart2js_native/native_mixin_multiple3_test: Fail
-tests/compiler/dart2js_native/native_mixin_multiple_test: Fail
 tests/compiler/dart2js_native/native_mixin_test: Fail
 tests/compiler/dart2js_native/native_mixin_with_plain_test: Fail
 tests/compiler/dart2js_native/native_named_constructors2_frog_test: Fail
 tests/compiler/dart2js_native/native_named_constructors3_frog_test: Fail
+tests/compiler/dart2js_native/native_no_such_method_exception_frog_test: Fail
 tests/compiler/dart2js_native/native_no_such_method_exception2_frog_test: Fail
 tests/compiler/dart2js_native/native_no_such_method_exception3_frog_test: Fail
 tests/compiler/dart2js_native/native_no_such_method_exception4_frog_test: Fail
 tests/compiler/dart2js_native/native_no_such_method_exception5_frog_test: Fail
-tests/compiler/dart2js_native/native_no_such_method_exception_frog_test: Fail
 tests/compiler/dart2js_native/native_novel_html_test: Fail
 tests/compiler/dart2js_native/native_null_closure_frog_test: Fail
 tests/compiler/dart2js_native/native_null_frog_test: Fail
@@ -1624,8 +1626,8 @@
 tests/compiler/dart2js_native/native_testing: Fail
 tests/compiler/dart2js_native/native_to_string_frog_test: Fail
 tests/compiler/dart2js_native/native_use_native_name_in_table_frog_test: Fail
-tests/compiler/dart2js_native/native_wrapping_function3_frog_test: Fail
 tests/compiler/dart2js_native/native_wrapping_function_frog_test: Fail
+tests/compiler/dart2js_native/native_wrapping_function3_frog_test: Fail
 tests/compiler/dart2js_native/oddly_named_fields_test: Fail
 tests/compiler/dart2js_native/runtimetype_test: Fail
 tests/compiler/dart2js_native/static_methods_test: Fail
@@ -1641,12 +1643,160 @@
 tests/compiler/dart2js_native/subclassing_type_test: Fail
 tests/compiler/dart2js_native/super_call_test: Fail
 tests/compiler/dart2js_native/super_property_test: Fail
-tests/corelib/from_environment_const_type_test: Fail
-tests/corelib/from_environment_const_type_undefined_test: Fail
-tests/corelib/symbol_reserved_word_test: Fail
+tests/compiler/dart2js/data/one_line_dart_program: Fail
 tests/corelib_strong/from_environment_const_type_test: Fail
 tests/corelib_strong/from_environment_const_type_undefined_test: Fail
 tests/corelib_strong/symbol_reserved_word_test: Fail
+tests/corelib/from_environment_const_type_test: Fail
+tests/corelib/from_environment_const_type_undefined_test: Fail
+tests/corelib/symbol_reserved_word_test: Fail
+tests/language_2/abstract_syntax_test: Fail
+tests/language_2/arg_param_trailing_comma_test: Fail
+tests/language_strong/argument_definition_test: Fail
+tests/language_strong/assign_instance_method_negative_test: Fail
+tests/language_strong/async_await_syntax_test: Fail
+tests/language_strong/await_backwards_compatibility_test: Fail
+tests/language_strong/bad_constructor_test: Fail
+tests/language_strong/bad_initializer1_negative_test: Fail
+tests/language_strong/bad_initializer2_negative_test: Fail
+tests/language_strong/bad_named_constructor_negative_test: Fail
+tests/language_strong/bad_raw_string_test: Fail
+tests/language_strong/black_listed_test: Fail
+tests/language_strong/body_less_constructor_wrong_arg_negative_test: Fail
+tests/language_strong/built_in_identifier_prefix_test: Fail
+tests/language_strong/built_in_identifier_test: Fail
+tests/language_strong/cascade_test: Fail
+tests/language_strong/class_cycle2_test: Fail
+tests/language_strong/class_keyword_test: Fail
+tests/language_strong/class_syntax_test: Fail
+tests/language_strong/closure_call_wrong_argument_count_negative_test: Fail
+tests/language_strong/compile_time_constant13_test: Fail
+tests/language_strong/const_counter_negative_test: Fail
+tests/language_strong/const_native_factory_test: Fail
+tests/language_strong/const_optional_args_negative_test: Fail
+tests/language_strong/constructor_call_wrong_argument_count_negative_test: Fail
+tests/language_strong/constructor_initializer_test: Fail
+tests/language_strong/constructor_name_test: Fail
+tests/language_strong/constructor_redirect1_negative_test: Fail
+tests/language_strong/constructor_redirect2_negative_test: Fail
+tests/language_strong/constructor_setter_negative_test: Fail
+tests/language_strong/constructor3_negative_test: Fail
+tests/language_strong/cyclic_typedef_test: Fail
+tests/language_strong/deferred_type_dependency_test: Fail
+tests/language_strong/duplicate_export_negative_test: Fail
+tests/language_strong/duplicate_interface_negative_test: Fail
+tests/language_strong/enum_is_keyword_test: Fail
+tests/language_strong/enum_syntax_test: Fail
+tests/language_strong/export_ambiguous_main_negative_test: Fail
+tests/language_strong/extend_type_parameter_negative_test: Fail
+tests/language_strong/extend_type_parameter2_negative_test: Fail
+tests/language_strong/external_test: Fail
+tests/language_strong/factory_negative_test: Fail
+tests/language_strong/factory2_negative_test: Fail
+tests/language_strong/field_method4_negative_test: Fail
+tests/language_strong/field1_negative_test: Fail
+tests/language_strong/field2_negative_test: Fail
+tests/language_strong/field3a_negative_test: Fail
+tests/language_strong/field4_negative_test: Fail
+tests/language_strong/field5_negative_test: Fail
+tests/language_strong/field6_negative_test: Fail
+tests/language_strong/field6a_negative_test: Fail
+tests/language_strong/function_syntax_test: Fail
+tests/language_strong/function_type_parameter_negative_test: Fail
+tests/language_strong/function_type_parameter2_negative_test: Fail
+tests/language_strong/get_set_syntax_test: Fail
+tests/language_strong/getter_declaration_negative_test: Fail
+tests/language_strong/illegal_declaration_test: Fail
+tests/language_strong/import_combinators_negative_test: Fail
+tests/language_strong/inst_field_initializer1_negative_test: Fail
+tests/language_strong/instance_call_wrong_argument_count_negative_test: Fail
+tests/language_strong/instance_method_negative_test: Fail
+tests/language_strong/instance_method2_negative_test: Fail
+tests/language_strong/interface_cycle_test: Fail
+tests/language_strong/interface_static_non_final_fields_negative_test: Fail
+tests/language_strong/interface2_negative_test: Fail
+tests/language_strong/keyword_type_expression_test: Fail
+tests/language_strong/label2_negative_test: Fail
+tests/language_strong/label3_negative_test: Fail
+tests/language_strong/label5_negative_test: Fail
+tests/language_strong/label6_negative_test: Fail
+tests/language_strong/library_negative_test: Fail
+tests/language_strong/list_literal_syntax_test: Fail
+tests/language_strong/list_literal2_negative_test: Fail
+tests/language_strong/literal_unary_plus_test: Fail
+tests/language_strong/main_test: Fail
+tests/language_strong/malformed_inheritance_test: Fail
+tests/language_strong/malformed_test: Fail
+tests/language_strong/map_literal2_negative_test: Fail
+tests/language_strong/metadata_test: Fail
+tests/language_strong/method_override2_test: Fail
+tests/language_strong/mixin_forwarding_constructor4_test: Fail
+tests/language_strong/mixin_illegal_syntax_test: Fail
+tests/language_strong/mixin_invalid_inheritance1_test: Fail
+tests/language_strong/named_constructor_test: Fail
+tests/language_strong/named_parameters_aggregated_test: Fail
+tests/language_strong/no_such_method_negative_test: Fail
+tests/language_strong/non_const_super_negative_test: Fail
+tests/language_strong/null_test: Fail
+tests/language_strong/number_identifier_test: Fail
+tests/language_strong/override_field_method1_negative_test: Fail
+tests/language_strong/override_field_method2_negative_test: Fail
+tests/language_strong/override_field_method4_negative_test: Fail
+tests/language_strong/override_field_method5_negative_test: Fail
+tests/language_strong/override_inheritance_generic_test: Fail
+tests/language_strong/parameter_default_test: Fail
+tests/language_strong/parameter_initializer1_negative_test: Fail
+tests/language_strong/parameter_initializer2_negative_test: Fail
+tests/language_strong/parameter_initializer3_negative_test: Fail
+tests/language_strong/parameter_initializer4_negative_test: Fail
+tests/language_strong/parameter_initializer6_negative_test: Fail
+tests/language_strong/prefix1_negative_test: Fail
+tests/language_strong/prefix10_negative_test: Fail
+tests/language_strong/prefix11_negative_test: Fail
+tests/language_strong/prefix12_negative_test: Fail
+tests/language_strong/prefix13_negative_test: Fail
+tests/language_strong/prefix15_negative_test: Fail
+tests/language_strong/prefix2_negative_test: Fail
+tests/language_strong/prefix3_negative_test: Fail
+tests/language_strong/prefix4_negative_test: Fail
+tests/language_strong/prefix5_negative_test: Fail
+tests/language_strong/prefix6_negative_test: Fail
+tests/language_strong/prefix7_negative_test: Fail
+tests/language_strong/prefix8_negative_test: Fail
+tests/language_strong/private_member1_negative_test: Fail
+tests/language_strong/private_member2_negative_test: Fail
+tests/language_strong/private_member3_negative_test: Fail
+tests/language_strong/regress_23051_test: Fail
+tests/language_strong/script1_negative_test: Fail
+tests/language_strong/script2_negative_test: Fail
+tests/language_strong/source_self_negative_test: Fail
+tests/language_strong/static_call_wrong_argument_count_negative_test: Fail
+tests/language_strong/static_parameter_test: Fail
+tests/language_strong/static_top_level_test: Fail
+tests/language_strong/string_interpolation9_test: Fail
+tests/language_strong/string_unicode1_negative_test: Fail
+tests/language_strong/string_unicode2_negative_test: Fail
+tests/language_strong/string_unicode3_negative_test: Fail
+tests/language_strong/string_unicode4_negative_test: Fail
+tests/language_strong/switch1_negative_test: Fail
+tests/language_strong/switch3_negative_test: Fail
+tests/language_strong/switch4_negative_test: Fail
+tests/language_strong/switch5_negative_test: Fail
+tests/language_strong/switch7_negative_test: Fail
+tests/language_strong/sync_generator2_test: Fail
+tests/language_strong/syntax_test: Fail
+tests/language_strong/tearoff_basic_test: Fail
+tests/language_strong/tearoff_constructor_basic_test: Fail
+tests/language_strong/try_catch_on_syntax_test: Fail
+tests/language_strong/try_catch_syntax_test: Fail
+tests/language_strong/type_variable_bounds2_test: Fail
+tests/language_strong/type_variable_static_context_negative_test: Fail
+tests/language_strong/unbalanced_brace_test: Fail
+tests/language_strong/unresolved_in_factory_negative_test: Fail
+tests/language_strong/unresolved_top_level_method_negative_test: Fail
+tests/language_strong/unresolved_top_level_var_negative_test: Fail
+tests/language_strong/unsigned_right_shift_test: Fail
+tests/language_strong/variable_declaration_metadata_test: Fail
 tests/language/argument_definition_test: Fail
 tests/language/assert_initializer_test: Fail
 tests/language/assign_instance_method_negative_test: Fail
@@ -1656,6 +1806,7 @@
 tests/language/bad_initializer1_negative_test: Fail
 tests/language/bad_initializer2_negative_test: Fail
 tests/language/bad_named_constructor_negative_test: Fail
+tests/language/bad_raw_string_test: Fail
 tests/language/bad_typedef_test: Fail
 tests/language/black_listed_test: Fail
 tests/language/body_less_constructor_wrong_arg_negative_test: Fail
@@ -1670,13 +1821,13 @@
 tests/language/const_getter_test: Fail
 tests/language/const_native_factory_test: Fail
 tests/language/const_optional_args_negative_test: Fail
-tests/language/constructor3_negative_test: Fail
 tests/language/constructor_call_wrong_argument_count_negative_test: Fail
 tests/language/constructor_initializer_test: Fail
 tests/language/constructor_name_test: Fail
 tests/language/constructor_redirect1_negative_test: Fail
 tests/language/constructor_redirect2_negative_test: Fail
 tests/language/constructor_setter_negative_test: Fail
+tests/language/constructor3_negative_test: Fail
 tests/language/covariant_test: Fail
 tests/language/cyclic_typedef_test: Fail
 tests/language/deferred_type_dependency_test: Fail
@@ -1685,11 +1836,12 @@
 tests/language/enum_is_keyword_test: Fail
 tests/language/enum_syntax_test: Fail
 tests/language/export_ambiguous_main_negative_test: Fail
-tests/language/extend_type_parameter2_negative_test: Fail
 tests/language/extend_type_parameter_negative_test: Fail
+tests/language/extend_type_parameter2_negative_test: Fail
 tests/language/external_test: Fail
-tests/language/factory2_negative_test: Fail
 tests/language/factory_negative_test: Fail
+tests/language/factory2_negative_test: Fail
+tests/language/field_method4_negative_test: Fail
 tests/language/field1_negative_test: Fail
 tests/language/field2_negative_test: Fail
 tests/language/field3a_negative_test: Fail
@@ -1697,29 +1849,29 @@
 tests/language/field5_negative_test: Fail
 tests/language/field6_negative_test: Fail
 tests/language/field6a_negative_test: Fail
-tests/language/field_method4_negative_test: Fail
 tests/language/function_syntax_test: Fail
-tests/language/function_type_parameter2_negative_test: Fail
 tests/language/function_type_parameter_negative_test: Fail
+tests/language/function_type_parameter2_negative_test: Fail
+tests/language/generic_function_typedef2_test: Fail
 tests/language/get_set_syntax_test: Fail
 tests/language/getter_declaration_negative_test: Fail
 tests/language/illegal_declaration_test: Fail
 tests/language/import_combinators_negative_test: Fail
 tests/language/inst_field_initializer1_negative_test: Fail
 tests/language/instance_call_wrong_argument_count_negative_test: Fail
-tests/language/instance_method2_negative_test: Fail
 tests/language/instance_method_negative_test: Fail
-tests/language/interface2_negative_test: Fail
+tests/language/instance_method2_negative_test: Fail
 tests/language/interface_cycle_test: Fail
 tests/language/interface_static_non_final_fields_negative_test: Fail
+tests/language/interface2_negative_test: Fail
 tests/language/keyword_type_expression_test: Fail
 tests/language/label2_negative_test: Fail
 tests/language/label3_negative_test: Fail
 tests/language/label5_negative_test: Fail
 tests/language/label6_negative_test: Fail
 tests/language/library_negative_test: Fail
-tests/language/list_literal2_negative_test: Fail
 tests/language/list_literal_syntax_test: Fail
+tests/language/list_literal2_negative_test: Fail
 tests/language/literal_unary_plus_test: Fail
 tests/language/main_test: Fail
 tests/language/malformed_inheritance_test: Fail
@@ -1731,9 +1883,9 @@
 tests/language/mixin_forwarding_constructor4_test: Fail
 tests/language/mixin_illegal_syntax_test: Fail
 tests/language/mixin_invalid_inheritance1_test: Fail
+tests/language/mixin_supertype_subclass_test: Fail
 tests/language/mixin_supertype_subclass2_test: Fail
 tests/language/mixin_supertype_subclass4_test: Fail
-tests/language/mixin_supertype_subclass_test: Fail
 tests/language/named_constructor_test: Fail
 tests/language/named_parameters_aggregated_test: Fail
 tests/language/no_such_method_negative_test: Fail
@@ -1752,12 +1904,12 @@
 tests/language/parameter_initializer4_negative_test: Fail
 tests/language/parameter_initializer5_negative_test: Fail
 tests/language/parameter_initializer6_negative_test: Fail
+tests/language/prefix1_negative_test: Fail
 tests/language/prefix10_negative_test: Fail
 tests/language/prefix11_negative_test: Fail
 tests/language/prefix12_negative_test: Fail
 tests/language/prefix13_negative_test: Fail
 tests/language/prefix15_negative_test: Fail
-tests/language/prefix1_negative_test: Fail
 tests/language/prefix2_negative_test: Fail
 tests/language/prefix3_negative_test: Fail
 tests/language/prefix4_negative_test: Fail
@@ -1807,152 +1959,12 @@
 tests/language/variable_declaration_metadata_test: Fail
 tests/language/vm/debug_break_enabled_vm_test: Fail
 tests/language/vm/debug_break_vm_test: Fail
-tests/language_2/abstract_syntax_test: Fail
-tests/language_2/arg_param_trailing_comma_test: Fail
-tests/language_strong/argument_definition_test: Fail
-tests/language_strong/assign_instance_method_negative_test: Fail
-tests/language_strong/async_await_syntax_test: Fail
-tests/language_strong/await_backwards_compatibility_test: Fail
-tests/language_strong/bad_constructor_test: Fail
-tests/language_strong/bad_initializer1_negative_test: Fail
-tests/language_strong/bad_initializer2_negative_test: Fail
-tests/language_strong/bad_named_constructor_negative_test: Fail
-tests/language_strong/black_listed_test: Fail
-tests/language_strong/body_less_constructor_wrong_arg_negative_test: Fail
-tests/language_strong/built_in_identifier_prefix_test: Fail
-tests/language_strong/built_in_identifier_test: Fail
-tests/language_strong/cascade_test: Fail
-tests/language_strong/class_cycle2_test: Fail
-tests/language_strong/class_keyword_test: Fail
-tests/language_strong/class_syntax_test: Fail
-tests/language_strong/closure_call_wrong_argument_count_negative_test: Fail
-tests/language_strong/compile_time_constant13_test: Fail
-tests/language_strong/const_counter_negative_test: Fail
-tests/language_strong/const_native_factory_test: Fail
-tests/language_strong/const_optional_args_negative_test: Fail
-tests/language_strong/constructor3_negative_test: Fail
-tests/language_strong/constructor_call_wrong_argument_count_negative_test: Fail
-tests/language_strong/constructor_initializer_test: Fail
-tests/language_strong/constructor_name_test: Fail
-tests/language_strong/constructor_redirect1_negative_test: Fail
-tests/language_strong/constructor_redirect2_negative_test: Fail
-tests/language_strong/constructor_setter_negative_test: Fail
-tests/language_strong/cyclic_typedef_test: Fail
-tests/language_strong/deferred_type_dependency_test: Fail
-tests/language_strong/duplicate_export_negative_test: Fail
-tests/language_strong/duplicate_interface_negative_test: Fail
-tests/language_strong/enum_is_keyword_test: Fail
-tests/language_strong/enum_syntax_test: Fail
-tests/language_strong/export_ambiguous_main_negative_test: Fail
-tests/language_strong/extend_type_parameter2_negative_test: Fail
-tests/language_strong/extend_type_parameter_negative_test: Fail
-tests/language_strong/external_test: Fail
-tests/language_strong/factory2_negative_test: Fail
-tests/language_strong/factory_negative_test: Fail
-tests/language_strong/field1_negative_test: Fail
-tests/language_strong/field2_negative_test: Fail
-tests/language_strong/field3a_negative_test: Fail
-tests/language_strong/field4_negative_test: Fail
-tests/language_strong/field5_negative_test: Fail
-tests/language_strong/field6_negative_test: Fail
-tests/language_strong/field6a_negative_test: Fail
-tests/language_strong/field_method4_negative_test: Fail
-tests/language_strong/function_syntax_test: Fail
-tests/language_strong/function_type_parameter2_negative_test: Fail
-tests/language_strong/function_type_parameter_negative_test: Fail
-tests/language_strong/get_set_syntax_test: Fail
-tests/language_strong/getter_declaration_negative_test: Fail
-tests/language_strong/illegal_declaration_test: Fail
-tests/language_strong/import_combinators_negative_test: Fail
-tests/language_strong/inst_field_initializer1_negative_test: Fail
-tests/language_strong/instance_call_wrong_argument_count_negative_test: Fail
-tests/language_strong/instance_method2_negative_test: Fail
-tests/language_strong/instance_method_negative_test: Fail
-tests/language_strong/interface2_negative_test: Fail
-tests/language_strong/interface_cycle_test: Fail
-tests/language_strong/interface_static_non_final_fields_negative_test: Fail
-tests/language_strong/keyword_type_expression_test: Fail
-tests/language_strong/label2_negative_test: Fail
-tests/language_strong/label3_negative_test: Fail
-tests/language_strong/label5_negative_test: Fail
-tests/language_strong/label6_negative_test: Fail
-tests/language_strong/library_negative_test: Fail
-tests/language_strong/list_literal2_negative_test: Fail
-tests/language_strong/list_literal_syntax_test: Fail
-tests/language_strong/literal_unary_plus_test: Fail
-tests/language_strong/main_test: Fail
-tests/language_strong/malformed_inheritance_test: Fail
-tests/language_strong/malformed_test: Fail
-tests/language_strong/map_literal2_negative_test: Fail
-tests/language_strong/metadata_test: Fail
-tests/language_strong/method_override2_test: Fail
-tests/language_strong/mixin_forwarding_constructor4_test: Fail
-tests/language_strong/mixin_illegal_syntax_test: Fail
-tests/language_strong/mixin_invalid_inheritance1_test: Fail
-tests/language_strong/named_constructor_test: Fail
-tests/language_strong/named_parameters_aggregated_test: Fail
-tests/language_strong/no_such_method_negative_test: Fail
-tests/language_strong/non_const_super_negative_test: Fail
-tests/language_strong/null_test: Fail
-tests/language_strong/number_identifier_test: Fail
-tests/language_strong/override_field_method1_negative_test: Fail
-tests/language_strong/override_field_method2_negative_test: Fail
-tests/language_strong/override_field_method4_negative_test: Fail
-tests/language_strong/override_field_method5_negative_test: Fail
-tests/language_strong/override_inheritance_generic_test: Fail
-tests/language_strong/parameter_default_test: Fail
-tests/language_strong/parameter_initializer1_negative_test: Fail
-tests/language_strong/parameter_initializer2_negative_test: Fail
-tests/language_strong/parameter_initializer3_negative_test: Fail
-tests/language_strong/parameter_initializer4_negative_test: Fail
-tests/language_strong/parameter_initializer6_negative_test: Fail
-tests/language_strong/prefix10_negative_test: Fail
-tests/language_strong/prefix11_negative_test: Fail
-tests/language_strong/prefix12_negative_test: Fail
-tests/language_strong/prefix13_negative_test: Fail
-tests/language_strong/prefix15_negative_test: Fail
-tests/language_strong/prefix1_negative_test: Fail
-tests/language_strong/prefix2_negative_test: Fail
-tests/language_strong/prefix3_negative_test: Fail
-tests/language_strong/prefix4_negative_test: Fail
-tests/language_strong/prefix5_negative_test: Fail
-tests/language_strong/prefix6_negative_test: Fail
-tests/language_strong/prefix7_negative_test: Fail
-tests/language_strong/prefix8_negative_test: Fail
-tests/language_strong/private_member1_negative_test: Fail
-tests/language_strong/private_member2_negative_test: Fail
-tests/language_strong/private_member3_negative_test: Fail
-tests/language_strong/regress_23051_test: Fail
-tests/language_strong/script1_negative_test: Fail
-tests/language_strong/script2_negative_test: Fail
-tests/language_strong/source_self_negative_test: Fail
-tests/language_strong/static_call_wrong_argument_count_negative_test: Fail
-tests/language_strong/static_parameter_test: Fail
-tests/language_strong/static_top_level_test: Fail
-tests/language_strong/string_interpolation9_test: Fail
-tests/language_strong/string_unicode1_negative_test: Fail
-tests/language_strong/string_unicode2_negative_test: Fail
-tests/language_strong/string_unicode3_negative_test: Fail
-tests/language_strong/string_unicode4_negative_test: Fail
-tests/language_strong/switch1_negative_test: Fail
-tests/language_strong/switch3_negative_test: Fail
-tests/language_strong/switch4_negative_test: Fail
-tests/language_strong/switch5_negative_test: Fail
-tests/language_strong/switch7_negative_test: Fail
-tests/language_strong/sync_generator2_test: Fail
-tests/language_strong/syntax_test: Fail
-tests/language_strong/tearoff_basic_test: Fail
-tests/language_strong/tearoff_constructor_basic_test: Fail
-tests/language_strong/try_catch_on_syntax_test: Fail
-tests/language_strong/try_catch_syntax_test: Fail
-tests/language_strong/type_variable_bounds2_test: Fail
-tests/language_strong/type_variable_static_context_negative_test: Fail
-tests/language_strong/unbalanced_brace_test: Fail
-tests/language_strong/unresolved_in_factory_negative_test: Fail
-tests/language_strong/unresolved_top_level_method_negative_test: Fail
-tests/language_strong/unresolved_top_level_var_negative_test: Fail
-tests/language_strong/unsigned_right_shift_test: Fail
-tests/language_strong/variable_declaration_metadata_test: Fail
+tests/lib_strong/mirrors/metadata_allowed_values_test: Fail
+tests/lib_strong/mirrors/metadata_scope_test: Fail
+tests/lib_strong/mirrors/mirror_in_static_init_test: Fail
+tests/lib_strong/mirrors/other_declarations_location_test: Fail
+tests/lib_strong/mirrors/syntax_error_test: Fail
+tests/lib_strong/mirrors/typevariable_mirror_metadata_test: Fail
 tests/lib/async/future_or_bad_type_test: Fail
 tests/lib/mirrors/metadata_allowed_values_test: Fail
 tests/lib/mirrors/metadata_scope_test: Fail
@@ -1960,12 +1972,6 @@
 tests/lib/mirrors/other_declarations_location_test: Fail
 tests/lib/mirrors/syntax_error_test: Fail
 tests/lib/mirrors/typevariable_mirror_metadata_test: Fail
-tests/lib_strong/mirrors/metadata_allowed_values_test: Fail
-tests/lib_strong/mirrors/metadata_scope_test: Fail
-tests/lib_strong/mirrors/mirror_in_static_init_test: Fail
-tests/lib_strong/mirrors/other_declarations_location_test: Fail
-tests/lib_strong/mirrors/syntax_error_test: Fail
-tests/lib_strong/mirrors/typevariable_mirror_metadata_test: Fail
 tests/standalone/io/snapshot_fail_script: Fail
 tests/standalone/io/test_extension: Fail
 tests/standalone/io/test_relative_extension: Fail
@@ -1975,10 +1981,3 @@
 third_party/pkg/resource/test/loader_data_test: Fail
 third_party/pkg/resource/test/loader_file_test: Fail
 third_party/pkg/resource/test/loader_http_test: Fail
-
-issue23520: Fail
-issue28367: Fail
-pkg/front_end/test/fasta/function_type_recovery: Fail
-tests/language/bad_raw_string_test: Fail
-tests/language/generic_function_typedef2_test: Fail
-tests/language_strong/bad_raw_string_test: Fail
diff --git a/pkg/front_end/test/fasta/scanner/scanner.status b/pkg/front_end/test/fasta/scanner/scanner.status
index 33d4d5e..4cdc798 100644
--- a/pkg/front_end/test/fasta/scanner/scanner.status
+++ b/pkg/front_end/test/fasta/scanner/scanner.status
@@ -6,121 +6,6 @@
 tests/compiler/dart2js_extra/empty_negative_test: Fail
 tests/compiler/dart2js_extra/invalid_length_negative_test: Fail
 tests/compiler/dart2js_extra/timer_negative_test: Fail
-tests/language/assign_instance_method_negative_test: Fail
-tests/language/bad_initializer1_negative_test: Fail
-tests/language/bad_initializer2_negative_test: Fail
-tests/language/bad_named_constructor_negative_test: Fail
-tests/language/body_less_constructor_wrong_arg_negative_test: Fail
-tests/language/closure_call_wrong_argument_count_negative_test: Fail
-tests/language/const_counter_negative_test: Fail
-tests/language/const_optional_args_negative_test: Fail
-tests/language/constructor3_negative_test: Fail
-tests/language/constructor_call_wrong_argument_count_negative_test: Fail
-tests/language/constructor_redirect1_negative_test: Fail
-tests/language/constructor_redirect2_negative_test: Fail
-tests/language/constructor_setter_negative_test: Fail
-tests/language/deep_nesting1_negative_test: Fail
-tests/language/deep_nesting2_negative_test: Fail
-tests/language/duplicate_export_negative_test: Fail
-tests/language/duplicate_interface_negative_test: Fail
-tests/language/export_ambiguous_main_negative_test: Fail
-tests/language/extend_type_parameter2_negative_test: Fail
-tests/language/extend_type_parameter_negative_test: Fail
-tests/language/factory2_negative_test: Fail
-tests/language/factory3_negative_test: Fail
-tests/language/factory_negative_test: Fail
-tests/language/field1_negative_test: Fail
-tests/language/field2_negative_test: Fail
-tests/language/field3_negative_test: Fail
-tests/language/field3a_negative_test: Fail
-tests/language/field4_negative_test: Fail
-tests/language/field5_negative_test: Fail
-tests/language/field6_negative_test: Fail
-tests/language/field6a_negative_test: Fail
-tests/language/field_method4_negative_test: Fail
-tests/language/function_type_parameter2_negative_test: Fail
-tests/language/function_type_parameter_negative_test: Fail
-tests/language/getter_declaration_negative_test: Fail
-tests/language/import_combinators_negative_test: Fail
-tests/language/inst_field_initializer1_negative_test: Fail
-tests/language/instance_call_wrong_argument_count_negative_test: Fail
-tests/language/instance_method2_negative_test: Fail
-tests/language/instance_method_negative_test: Fail
-tests/language/interface2_negative_test: Fail
-tests/language/interface_injection1_negative_test: Fail
-tests/language/interface_injection2_negative_test: Fail
-tests/language/interface_static_method_negative_test: Fail
-tests/language/interface_static_non_final_fields_negative_test: Fail
-tests/language/is_not_class1_negative_test: Fail
-tests/language/is_not_class4_negative_test: Fail
-tests/language/issue1578_negative_test: Fail
-tests/language/label2_negative_test: Fail
-tests/language/label3_negative_test: Fail
-tests/language/label5_negative_test: Fail
-tests/language/label6_negative_test: Fail
-tests/language/label8_negative_test: Fail
-tests/language/library_negative_test: Fail
-tests/language/list_literal2_negative_test: Fail
-tests/language/list_literal_negative_test: Fail
-tests/language/map_literal2_negative_test: Fail
-tests/language/map_literal_negative_test: Fail
-tests/language/new_expression1_negative_test: Fail
-tests/language/new_expression2_negative_test: Fail
-tests/language/new_expression3_negative_test: Fail
-tests/language/no_such_method_negative_test: Fail
-tests/language/non_const_super_negative_test: Fail
-tests/language/operator1_negative_test: Fail
-tests/language/operator2_negative_test: Fail
-tests/language/override_field_method1_negative_test: Fail
-tests/language/override_field_method2_negative_test: Fail
-tests/language/override_field_method4_negative_test: Fail
-tests/language/override_field_method5_negative_test: Fail
-tests/language/parameter_initializer1_negative_test: Fail
-tests/language/parameter_initializer2_negative_test: Fail
-tests/language/parameter_initializer3_negative_test: Fail
-tests/language/parameter_initializer4_negative_test: Fail
-tests/language/parameter_initializer5_negative_test: Fail
-tests/language/parameter_initializer6_negative_test: Fail
-tests/language/prefix10_negative_test: Fail
-tests/language/prefix11_negative_test: Fail
-tests/language/prefix12_negative_test: Fail
-tests/language/prefix13_negative_test: Fail
-tests/language/prefix15_negative_test: Fail
-tests/language/prefix18_negative_test: Fail
-tests/language/prefix1_negative_test: Fail
-tests/language/prefix2_negative_test: Fail
-tests/language/prefix3_negative_test: Fail
-tests/language/prefix4_negative_test: Fail
-tests/language/prefix5_negative_test: Fail
-tests/language/prefix6_negative_test: Fail
-tests/language/prefix7_negative_test: Fail
-tests/language/prefix8_negative_test: Fail
-tests/language/private_member1_negative_test: Fail
-tests/language/private_member2_negative_test: Fail
-tests/language/private_member3_negative_test: Fail
-tests/language/script1_negative_test: Fail
-tests/language/script2_negative_test: Fail
-tests/language/source_self_negative_test: Fail
-tests/language/static_call_wrong_argument_count_negative_test: Fail
-tests/language/string_escape4_negative_test: Fail
-tests/language/string_interpolate1_negative_test: Fail
-tests/language/string_interpolate2_negative_test: Fail
-tests/language/string_unicode1_negative_test: Fail
-tests/language/string_unicode2_negative_test: Fail
-tests/language/string_unicode3_negative_test: Fail
-tests/language/string_unicode4_negative_test: Fail
-tests/language/switch1_negative_test: Fail
-tests/language/switch3_negative_test: Fail
-tests/language/switch4_negative_test: Fail
-tests/language/switch5_negative_test: Fail
-tests/language/switch7_negative_test: Fail
-tests/language/test_negative_test: Fail
-tests/language/type_variable_static_context_negative_test: Fail
-tests/language/unary_plus_negative_test: Fail
-tests/language/unhandled_exception_negative_test: Fail
-tests/language/unresolved_in_factory_negative_test: Fail
-tests/language/unresolved_top_level_method_negative_test: Fail
-tests/language/unresolved_top_level_var_negative_test: Fail
 tests/language_strong/assign_instance_method_negative_test: Fail
 tests/language_strong/bad_initializer1_negative_test: Fail
 tests/language_strong/bad_initializer2_negative_test: Fail
@@ -129,19 +14,20 @@
 tests/language_strong/closure_call_wrong_argument_count_negative_test: Fail
 tests/language_strong/const_counter_negative_test: Fail
 tests/language_strong/const_optional_args_negative_test: Fail
-tests/language_strong/constructor3_negative_test: Fail
 tests/language_strong/constructor_call_wrong_argument_count_negative_test: Fail
 tests/language_strong/constructor_redirect1_negative_test: Fail
 tests/language_strong/constructor_redirect2_negative_test: Fail
 tests/language_strong/constructor_setter_negative_test: Fail
+tests/language_strong/constructor3_negative_test: Fail
 tests/language_strong/duplicate_export_negative_test: Fail
 tests/language_strong/duplicate_interface_negative_test: Fail
 tests/language_strong/export_ambiguous_main_negative_test: Fail
-tests/language_strong/extend_type_parameter2_negative_test: Fail
 tests/language_strong/extend_type_parameter_negative_test: Fail
+tests/language_strong/extend_type_parameter2_negative_test: Fail
+tests/language_strong/factory_negative_test: Fail
 tests/language_strong/factory2_negative_test: Fail
 tests/language_strong/factory3_negative_test: Fail
-tests/language_strong/factory_negative_test: Fail
+tests/language_strong/field_method4_negative_test: Fail
 tests/language_strong/field1_negative_test: Fail
 tests/language_strong/field2_negative_test: Fail
 tests/language_strong/field3_negative_test: Fail
@@ -150,20 +36,19 @@
 tests/language_strong/field5_negative_test: Fail
 tests/language_strong/field6_negative_test: Fail
 tests/language_strong/field6a_negative_test: Fail
-tests/language_strong/field_method4_negative_test: Fail
-tests/language_strong/function_type_parameter2_negative_test: Fail
 tests/language_strong/function_type_parameter_negative_test: Fail
+tests/language_strong/function_type_parameter2_negative_test: Fail
 tests/language_strong/getter_declaration_negative_test: Fail
 tests/language_strong/import_combinators_negative_test: Fail
 tests/language_strong/inst_field_initializer1_negative_test: Fail
 tests/language_strong/instance_call_wrong_argument_count_negative_test: Fail
-tests/language_strong/instance_method2_negative_test: Fail
 tests/language_strong/instance_method_negative_test: Fail
-tests/language_strong/interface2_negative_test: Fail
+tests/language_strong/instance_method2_negative_test: Fail
 tests/language_strong/interface_injection1_negative_test: Fail
 tests/language_strong/interface_injection2_negative_test: Fail
 tests/language_strong/interface_static_method_negative_test: Fail
 tests/language_strong/interface_static_non_final_fields_negative_test: Fail
+tests/language_strong/interface2_negative_test: Fail
 tests/language_strong/is_not_class1_negative_test: Fail
 tests/language_strong/is_not_class4_negative_test: Fail
 tests/language_strong/issue1578_negative_test: Fail
@@ -173,10 +58,10 @@
 tests/language_strong/label6_negative_test: Fail
 tests/language_strong/label8_negative_test: Fail
 tests/language_strong/library_negative_test: Fail
-tests/language_strong/list_literal2_negative_test: Fail
 tests/language_strong/list_literal_negative_test: Fail
-tests/language_strong/map_literal2_negative_test: Fail
+tests/language_strong/list_literal2_negative_test: Fail
 tests/language_strong/map_literal_negative_test: Fail
+tests/language_strong/map_literal2_negative_test: Fail
 tests/language_strong/new_expression1_negative_test: Fail
 tests/language_strong/new_expression2_negative_test: Fail
 tests/language_strong/new_expression3_negative_test: Fail
@@ -193,13 +78,13 @@
 tests/language_strong/parameter_initializer3_negative_test: Fail
 tests/language_strong/parameter_initializer4_negative_test: Fail
 tests/language_strong/parameter_initializer6_negative_test: Fail
+tests/language_strong/prefix1_negative_test: Fail
 tests/language_strong/prefix10_negative_test: Fail
 tests/language_strong/prefix11_negative_test: Fail
 tests/language_strong/prefix12_negative_test: Fail
 tests/language_strong/prefix13_negative_test: Fail
 tests/language_strong/prefix15_negative_test: Fail
 tests/language_strong/prefix18_negative_test: Fail
-tests/language_strong/prefix1_negative_test: Fail
 tests/language_strong/prefix2_negative_test: Fail
 tests/language_strong/prefix3_negative_test: Fail
 tests/language_strong/prefix4_negative_test: Fail
@@ -239,4 +124,119 @@
 tests/language_strong/unresolved_in_factory_negative_test: Fail
 tests/language_strong/unresolved_top_level_method_negative_test: Fail
 tests/language_strong/unresolved_top_level_var_negative_test: Fail
+tests/language/assign_instance_method_negative_test: Fail
+tests/language/bad_initializer1_negative_test: Fail
+tests/language/bad_initializer2_negative_test: Fail
+tests/language/bad_named_constructor_negative_test: Fail
+tests/language/body_less_constructor_wrong_arg_negative_test: Fail
+tests/language/closure_call_wrong_argument_count_negative_test: Fail
+tests/language/const_counter_negative_test: Fail
+tests/language/const_optional_args_negative_test: Fail
+tests/language/constructor_call_wrong_argument_count_negative_test: Fail
+tests/language/constructor_redirect1_negative_test: Fail
+tests/language/constructor_redirect2_negative_test: Fail
+tests/language/constructor_setter_negative_test: Fail
+tests/language/constructor3_negative_test: Fail
+tests/language/deep_nesting1_negative_test: Fail
+tests/language/deep_nesting2_negative_test: Fail
+tests/language/duplicate_export_negative_test: Fail
+tests/language/duplicate_interface_negative_test: Fail
+tests/language/export_ambiguous_main_negative_test: Fail
+tests/language/extend_type_parameter_negative_test: Fail
+tests/language/extend_type_parameter2_negative_test: Fail
+tests/language/factory_negative_test: Fail
+tests/language/factory2_negative_test: Fail
+tests/language/factory3_negative_test: Fail
+tests/language/field_method4_negative_test: Fail
+tests/language/field1_negative_test: Fail
+tests/language/field2_negative_test: Fail
+tests/language/field3_negative_test: Fail
+tests/language/field3a_negative_test: Fail
+tests/language/field4_negative_test: Fail
+tests/language/field5_negative_test: Fail
+tests/language/field6_negative_test: Fail
+tests/language/field6a_negative_test: Fail
+tests/language/function_type_parameter_negative_test: Fail
+tests/language/function_type_parameter2_negative_test: Fail
+tests/language/getter_declaration_negative_test: Fail
+tests/language/import_combinators_negative_test: Fail
+tests/language/inst_field_initializer1_negative_test: Fail
+tests/language/instance_call_wrong_argument_count_negative_test: Fail
+tests/language/instance_method_negative_test: Fail
+tests/language/instance_method2_negative_test: Fail
+tests/language/interface_injection1_negative_test: Fail
+tests/language/interface_injection2_negative_test: Fail
+tests/language/interface_static_method_negative_test: Fail
+tests/language/interface_static_non_final_fields_negative_test: Fail
+tests/language/interface2_negative_test: Fail
+tests/language/is_not_class1_negative_test: Fail
+tests/language/is_not_class4_negative_test: Fail
+tests/language/issue1578_negative_test: Fail
+tests/language/label2_negative_test: Fail
+tests/language/label3_negative_test: Fail
+tests/language/label5_negative_test: Fail
+tests/language/label6_negative_test: Fail
+tests/language/label8_negative_test: Fail
+tests/language/library_negative_test: Fail
+tests/language/list_literal_negative_test: Fail
+tests/language/list_literal2_negative_test: Fail
+tests/language/map_literal_negative_test: Fail
+tests/language/map_literal2_negative_test: Fail
+tests/language/new_expression1_negative_test: Fail
+tests/language/new_expression2_negative_test: Fail
+tests/language/new_expression3_negative_test: Fail
+tests/language/no_such_method_negative_test: Fail
+tests/language/non_const_super_negative_test: Fail
+tests/language/operator1_negative_test: Fail
+tests/language/operator2_negative_test: Fail
+tests/language/override_field_method1_negative_test: Fail
+tests/language/override_field_method2_negative_test: Fail
+tests/language/override_field_method4_negative_test: Fail
+tests/language/override_field_method5_negative_test: Fail
+tests/language/parameter_initializer1_negative_test: Fail
+tests/language/parameter_initializer2_negative_test: Fail
+tests/language/parameter_initializer3_negative_test: Fail
+tests/language/parameter_initializer4_negative_test: Fail
+tests/language/parameter_initializer5_negative_test: Fail
+tests/language/parameter_initializer6_negative_test: Fail
+tests/language/prefix1_negative_test: Fail
+tests/language/prefix10_negative_test: Fail
+tests/language/prefix11_negative_test: Fail
+tests/language/prefix12_negative_test: Fail
+tests/language/prefix13_negative_test: Fail
+tests/language/prefix15_negative_test: Fail
+tests/language/prefix18_negative_test: Fail
+tests/language/prefix2_negative_test: Fail
+tests/language/prefix3_negative_test: Fail
+tests/language/prefix4_negative_test: Fail
+tests/language/prefix5_negative_test: Fail
+tests/language/prefix6_negative_test: Fail
+tests/language/prefix7_negative_test: Fail
+tests/language/prefix8_negative_test: Fail
+tests/language/private_member1_negative_test: Fail
+tests/language/private_member2_negative_test: Fail
+tests/language/private_member3_negative_test: Fail
+tests/language/script1_negative_test: Fail
+tests/language/script2_negative_test: Fail
+tests/language/source_self_negative_test: Fail
+tests/language/static_call_wrong_argument_count_negative_test: Fail
+tests/language/string_escape4_negative_test: Fail
+tests/language/string_interpolate1_negative_test: Fail
+tests/language/string_interpolate2_negative_test: Fail
+tests/language/string_unicode1_negative_test: Fail
+tests/language/string_unicode2_negative_test: Fail
+tests/language/string_unicode3_negative_test: Fail
+tests/language/string_unicode4_negative_test: Fail
+tests/language/switch1_negative_test: Fail
+tests/language/switch3_negative_test: Fail
+tests/language/switch4_negative_test: Fail
+tests/language/switch5_negative_test: Fail
+tests/language/switch7_negative_test: Fail
+tests/language/test_negative_test: Fail
+tests/language/type_variable_static_context_negative_test: Fail
+tests/language/unary_plus_negative_test: Fail
+tests/language/unhandled_exception_negative_test: Fail
+tests/language/unresolved_in_factory_negative_test: Fail
+tests/language/unresolved_top_level_method_negative_test: Fail
+tests/language/unresolved_top_level_var_negative_test: Fail
 tests/standalone/io/process_exit_negative_test: Fail
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index de177ef..65b8127 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -183,7 +183,7 @@
   final Set<Uri> content;
   final bool nnbdAgnosticMode;
   Component component;
-  String errors;
+  List<Iterable<String>> errors;
 
   LinkDependenciesOptions(this.content, {this.nnbdAgnosticMode})
       : assert(content != null),
@@ -201,8 +201,8 @@
   final bool weak;
   final Map<Component, KernelTarget> componentToTarget =
       <Component, KernelTarget>{};
-  final Map<Component, StringBuffer> componentToDiagnostics =
-      <Component, StringBuffer>{};
+  final Map<Component, List<Iterable<String>>> componentToDiagnostics =
+      <Component, List<Iterable<String>>>{};
   final Uri platformBinaries;
   final Map<Uri, UriTranslator> _uriTranslators = {};
   final Map<Uri, TestOptions> _testOptions = {};
@@ -251,11 +251,13 @@
     if (!ignoreExpectations) {
       steps.add(new MatchExpectation(
           fullCompile ? "$fullPrefix.expect" : "$outlinePrefix.expect",
-          serializeFirst: false));
+          serializeFirst: false,
+          isLastMatchStep: updateExpectations));
       if (!updateExpectations) {
         steps.add(new MatchExpectation(
             fullCompile ? "$fullPrefix.expect" : "$outlinePrefix.expect",
-            serializeFirst: true));
+            serializeFirst: true,
+            isLastMatchStep: true));
       }
     }
     steps.add(const TypeCheck());
@@ -270,13 +272,15 @@
             fullCompile
                 ? "$fullPrefix.transformed.expect"
                 : "$outlinePrefix.transformed.expect",
-            serializeFirst: false));
+            serializeFirst: false,
+            isLastMatchStep: updateExpectations));
         if (!updateExpectations) {
           steps.add(new MatchExpectation(
               fullCompile
                   ? "$fullPrefix.transformed.expect"
                   : "$outlinePrefix.transformed.expect",
-              serializeFirst: true));
+              serializeFirst: true,
+              isLastMatchStep: true));
         }
       }
       steps.add(const EnsureNoErrors());
@@ -589,7 +593,7 @@
 
   Future<Result<ComponentResult>> run(
       TestDescription description, FastaContext context) async {
-    StringBuffer errors = new StringBuffer();
+    List<Iterable<String>> errors = <Iterable<String>>[];
 
     Uri librariesSpecificationUri =
         context.computeLibrariesSpecificationUri(description);
@@ -606,10 +610,7 @@
     ProcessedOptions createProcessedOptions(NnbdMode nnbdMode) {
       CompilerOptions compilerOptions = new CompilerOptions()
         ..onDiagnostic = (DiagnosticMessage message) {
-          if (errors.isNotEmpty) {
-            errors.write("\n\n");
-          }
-          errors.writeAll(message.plainTextFormatted, "\n");
+          errors.add(message.plainTextFormatted);
         }
         ..environmentDefines = {}
         ..experimentalFlags = experimentalFlags
@@ -639,7 +640,7 @@
         KernelTarget sourceTarget = await outlineInitialization(context,
             description, testOptions, linkDependenciesOptions.content.toList());
         if (linkDependenciesOptions.errors != null) {
-          errors.write(linkDependenciesOptions.errors);
+          errors.addAll(linkDependenciesOptions.errors);
         }
         Component p = await sourceTarget.buildOutlines();
         if (fullCompile) {
@@ -654,7 +655,7 @@
         }
         p.libraries.clear();
         p.libraries.addAll(keepLibraries);
-        linkDependenciesOptions.errors = errors.toString();
+        linkDependenciesOptions.errors = errors.toList();
         errors.clear();
       });
     }
@@ -844,10 +845,14 @@
 
   Future<Result<ComponentResult>> run(
       ComponentResult result, FastaContext context) async {
-    StringBuffer buffer = context.componentToDiagnostics[result.component];
-    return buffer.isEmpty
+    List<Iterable<String>> errors =
+        context.componentToDiagnostics[result.component];
+    return errors.isEmpty
         ? pass(result)
-        : fail(result, """Unexpected errors:\n$buffer""");
+        : fail(
+            result,
+            "Unexpected errors:\n"
+            "${errors.map((error) => error.join('\n')).join('\n\n')}");
   }
 }
 
diff --git a/pkg/front_end/test/fasta/textual_outline_suite.dart b/pkg/front_end/test/fasta/textual_outline_suite.dart
new file mode 100644
index 0000000..fa98bdb
--- /dev/null
+++ b/pkg/front_end/test/fasta/textual_outline_suite.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.md file.
+
+library fasta.test.textual_outline_test;
+
+import 'dart:async' show Future;
+import 'dart:io';
+
+import 'package:dart_style/dart_style.dart' show DartFormatter;
+
+import 'package:front_end/src/fasta/util/textual_outline.dart';
+import 'package:testing/testing.dart'
+    show
+        Chain,
+        ChainContext,
+        Expectation,
+        ExpectationSet,
+        Result,
+        Step,
+        TestDescription,
+        runMe;
+
+import '../utils/kernel_chain.dart' show MatchContext;
+
+const List<Map<String, String>> EXPECTATIONS = [
+  {
+    "name": "ExpectationFileMismatch",
+    "group": "Fail",
+  },
+  {
+    "name": "ExpectationFileMissing",
+    "group": "Fail",
+  },
+  {
+    "name": "EmptyOutput",
+    "group": "Fail",
+  },
+  {
+    "name": "FormatterCrash",
+    "group": "Fail",
+  },
+];
+
+Future<Context> createContext(
+    Chain suite, Map<String, String> environment) async {
+  return new Context(environment["updateExpectations"] == "true");
+}
+
+main([List<String> arguments = const []]) =>
+    runMe(arguments, createContext, configurationPath: "../../testing.json");
+
+class Context extends ChainContext with MatchContext {
+  final bool updateExpectations;
+  Context(this.updateExpectations);
+
+  final List<Step> steps = const <Step>[
+    const TextualOutline(),
+  ];
+
+  final ExpectationSet expectationSet =
+      new ExpectationSet.fromJsonList(EXPECTATIONS);
+}
+
+class TextualOutline extends Step<TestDescription, TestDescription, Context> {
+  const TextualOutline();
+
+  String get name => "TextualOutline";
+
+  Future<Result<TestDescription>> run(
+      TestDescription description, Context context) async {
+    List<int> bytes = new File.fromUri(description.uri).readAsBytesSync();
+    for (bool modelled in [false, true]) {
+      String result = textualOutline(bytes,
+          throwOnUnexpected: true, performModelling: modelled);
+      if (result == null) {
+        return new Result(null, context.expectationSet["EmptyOutput"],
+            description.uri, StackTrace.current);
+      }
+
+      // In an attempt to make it less sensitive to formatting first remove
+      // excess new lines, then format.
+      List<String> lines = result.split("\n");
+      StringBuffer sb = new StringBuffer();
+      for (String line in lines) {
+        if (line.trim() != "") sb.writeln(line);
+      }
+      result = sb.toString().trim();
+
+      // Try to format.
+      Exception formatterException;
+      StackTrace formatterExceptionSt;
+      try {
+        result = new DartFormatter().format(result);
+      } catch (e, st) {
+        formatterException = e;
+        formatterExceptionSt = st;
+      }
+
+      String filename = ".textual_outline.expect";
+      if (modelled) {
+        filename = ".textual_outline_modelled.expect";
+      }
+
+      Result expectMatch = await context.match<TestDescription>(
+          filename, result, description.uri, description);
+      if (expectMatch.outcome != Expectation.Pass) return expectMatch;
+
+      if (formatterException != null) {
+        return new Result(null, context.expectationSet["FormatterCrash"],
+            formatterException, formatterExceptionSt);
+      }
+    }
+
+    return new Result.pass(description);
+  }
+}
diff --git a/pkg/front_end/test/fasta/type_inference/factor_type_test.dart b/pkg/front_end/test/fasta/type_inference/factor_type_test.dart
new file mode 100644
index 0000000..c56155d
--- /dev/null
+++ b/pkg/front_end/test/fasta/type_inference/factor_type_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/flow_analysis/factory_type_test_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:front_end/src/api_prototype/compiler_options.dart';
+import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/fasta/type_inference/factor_type.dart';
+import 'package:front_end/src/kernel_generator_impl.dart';
+import 'package:front_end/src/testing/id_testing_utils.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
+
+import 'package:front_end/src/testing/compiler_common.dart';
+
+class FactorTypeTest extends FactorTypeTestMixin<DartType> {
+  final TypeEnvironment typeEnvironment;
+
+  FactorTypeTest(this.typeEnvironment);
+
+  CoreTypes get coreTypes => typeEnvironment.coreTypes;
+
+  void run() {
+    test_dynamic();
+    test_futureOr();
+    test_object();
+    test_subtype();
+    test_void();
+  }
+
+  @override
+  void expect(
+      DartType T, DartType S, String actualResult, String expectedResult) {
+    Expect.equals(
+        expectedResult, actualResult, "Unexpected result for factor($T, $S)");
+  }
+
+  @override
+  DartType factor(DartType T, DartType S) {
+    return factorType(typeEnvironment, T, S);
+  }
+
+  @override
+  DartType futureNone(DartType type) =>
+      new InterfaceType(coreTypes.futureClass, Nullability.nonNullable, [type]);
+
+  @override
+  DartType futureOrNone(DartType type) => new InterfaceType(
+      coreTypes.futureOrClass, Nullability.nonNullable, [type]);
+
+  @override
+  DartType get dynamicType => const DynamicType();
+
+  @override
+  DartType get intNone => coreTypes.intNonNullableRawType;
+
+  @override
+  DartType get intQuestion => coreTypes.intNullableRawType;
+
+  @override
+  DartType get intStar => coreTypes.intLegacyRawType;
+
+  @override
+  DartType get nullNone => coreTypes.nullType;
+
+  @override
+  DartType get numNone => coreTypes.numNonNullableRawType;
+
+  @override
+  DartType get numQuestion => coreTypes.numNullableRawType;
+
+  @override
+  DartType get numStar => coreTypes.numLegacyRawType;
+
+  @override
+  DartType get objectNone => coreTypes.objectNonNullableRawType;
+
+  @override
+  DartType get objectQuestion => coreTypes.objectNullableRawType;
+
+  @override
+  DartType get objectStar => coreTypes.objectLegacyRawType;
+
+  @override
+  DartType get stringNone => coreTypes.stringNonNullableRawType;
+
+  @override
+  DartType get stringQuestion => coreTypes.stringNullableRawType;
+
+  @override
+  DartType get stringStar => coreTypes.stringLegacyRawType;
+
+  @override
+  DartType get voidType => const VoidType();
+
+  @override
+  String typeString(DartType type) =>
+      typeToText(type, TypeRepresentation.analyzerNonNullableByDefault);
+}
+
+main() async {
+  CompilerOptions options = new CompilerOptions()
+    ..experimentalFlags[ExperimentalFlag.nonNullable] = true;
+  InternalCompilerResult result = await compileScript('',
+      options: options, requireMain: false, retainDataForTesting: true);
+  new FactorTypeTest(
+          new TypeEnvironment(result.coreTypes, result.classHierarchy))
+      .run();
+}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
index b177855..cc03f2a 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
@@ -28,12 +28,12 @@
 
   DartType greatestClosure(DartType schema) {
     return typeSchemaElimination.greatestClosure(
-        schema, const NeverType(Nullability.nonNullable));
+        schema, const DynamicType(), const NeverType(Nullability.nonNullable));
   }
 
   DartType leastClosure(DartType schema) {
     return typeSchemaElimination.leastClosure(
-        schema, const NeverType(Nullability.nonNullable));
+        schema, const DynamicType(), const NeverType(Nullability.nonNullable));
   }
 
   void test_greatestClosure_contravariant() {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index c21fee9..d7cf9e6 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -29,11 +29,11 @@
   DartType get objectType => coreTypes.objectLegacyRawType;
 
   DartType greatestClosure(DartType schema) {
-    return typeSchemaElimination.greatestClosure(schema, nullType);
+    return typeSchemaElimination.greatestClosure(schema, dynamicType, nullType);
   }
 
   DartType leastClosure(DartType schema) {
-    return typeSchemaElimination.leastClosure(schema, nullType);
+    return typeSchemaElimination.leastClosure(schema, dynamicType, nullType);
   }
 
   void test_greatestClosure_contravariant() {
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 306c52f..168cf74 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
@@ -473,6 +473,30 @@
     testLower("B*", "A", "B");
     testLower("B?", "A", "B");
     testLower("B", "A", "B");
+
+    testLower("Iterable<A>*", "List<B>*", "List<B>*");
+    testLower("Iterable<A>*", "List<B>?", "List<B>*");
+    testLower("Iterable<A>*", "List<B>", "List<B>");
+
+    testLower("Iterable<A>?", "List<B>*", "List<B>*");
+    testLower("Iterable<A>?", "List<B>?", "List<B>?");
+    testLower("Iterable<A>?", "List<B>", "List<B>");
+
+    testLower("Iterable<A>", "List<B>*", "List<B>");
+    testLower("Iterable<A>", "List<B>?", "List<B>");
+    testLower("Iterable<A>", "List<B>", "List<B>");
+
+    testLower("List<B>*", "Iterable<A>*", "List<B>*");
+    testLower("List<B>?", "Iterable<A>*", "List<B>*");
+    testLower("List<B>", "Iterable<A>*", "List<B>");
+
+    testLower("List<B>*", "Iterable<A>?", "List<B>*");
+    testLower("List<B>?", "Iterable<A>?", "List<B>?");
+    testLower("List<B>", "Iterable<A>?", "List<B>");
+
+    testLower("List<B>*", "Iterable<A>", "List<B>");
+    testLower("List<B>?", "Iterable<A>", "List<B>");
+    testLower("List<B>", "Iterable<A>", "List<B>");
   }
 
   void test_lower_bound_top() {
@@ -840,11 +864,20 @@
     testUpper("List<B*>", "Iterable<A*>", "Iterable<A*>");
     testUpper("List<B*>", "Iterable<A?>", "Iterable<A?>");
     testUpper("List<B*>", "Iterable<A>", "Iterable<A>");
+    testUpper("List<B>*", "Iterable<A>*", "Iterable<A>*");
+    testUpper("List<B>*", "Iterable<A>?", "Iterable<A>?");
+    testUpper("List<B>*", "Iterable<A>", "Iterable<A>*");
+    testUpper("List<B>?", "Iterable<A>*", "Iterable<A>?");
+    testUpper("List<B>?", "Iterable<A>?", "Iterable<A>?");
+    testUpper("List<B>?", "Iterable<A>", "Iterable<A>?");
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
     testUpper("List<B?>", "Iterable<A*>", "Iterable<A*>");
     testUpper("List<B?>", "Iterable<A?>", "Iterable<A?>");
+    testUpper("List<B>?", "Iterable<A>*", "Iterable<A>?");
+    testUpper("List<B>?", "Iterable<A>?", "Iterable<A>?");
+    testUpper("List<B>?", "Iterable<A>", "Iterable<A>?");
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //     = least upper bound of two interfaces as in Dart 1.
     testUpper("List<B?>", "Iterable<A>", "Object");
@@ -854,22 +887,31 @@
     testUpper("List<B>", "Iterable<A*>", "Iterable<A*>");
     testUpper("List<B>", "Iterable<A?>", "Iterable<A?>");
     testUpper("List<B>", "Iterable<A>", "Iterable<A>");
+    testUpper("List<B>", "Iterable<A>*", "Iterable<A>*");
+    testUpper("List<B>", "Iterable<A>?", "Iterable<A>?");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
     testUpper("Iterable<A*>", "List<B*>", "Iterable<A*>");
     testUpper("Iterable<A*>", "List<B?>", "Iterable<A*>");
     testUpper("Iterable<A*>", "List<B>", "Iterable<A*>");
+    testUpper("Iterable<A>*", "List<B>*", "Iterable<A>*");
+    testUpper("Iterable<A>*", "List<B>?", "Iterable<A>?");
+    testUpper("Iterable<A>*", "List<B>", "Iterable<A>*");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
     testUpper("Iterable<A?>", "List<B*>", "Iterable<A?>");
     testUpper("Iterable<A?>", "List<B?>", "Iterable<A?>");
     testUpper("Iterable<A?>", "List<B>", "Iterable<A?>");
+    testUpper("Iterable<A>?", "List<B>*", "Iterable<A>?");
+    testUpper("Iterable<A>?", "List<B>?", "Iterable<A>?");
+    testUpper("Iterable<A>?", "List<B>", "Iterable<A>?");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
     testUpper("Iterable<A>", "List<B*>", "Iterable<A>");
+    testUpper("Iterable<A>", "List<B>*", "Iterable<A>*");
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //     = least upper bound of two interfaces as in Dart 1.
     testUpper("Iterable<A>", "List<B?>", "Object");
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
index 910a00b..55d81db 100644
--- a/pkg/front_end/test/fasta/types/shared_type_tests.dart
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -248,7 +248,6 @@
     isSubtype('Future<int*>*', 'FutureOr<num*>*');
     isSubtype('Future<int*>*', 'FutureOr<Object*>*');
     isSubtype('FutureOr<int*>*', 'FutureOr<int*>*');
-    isSubtype('FutureOr<int*>*', 'FutureOr<num*>*');
     isSubtype('FutureOr<int*>*', 'Object*');
     isSubtype('Null', 'FutureOr<num?>');
     isSubtype('Null', 'FutureOr<num>?');
@@ -265,6 +264,14 @@
     isSubtype('FutureOr<X>', 'FutureOr<Future<X>>',
         typeParameters: 'X extends Future<Future<X>>');
 
+    isSubtype('FutureOr<int*>*', 'FutureOr<num*>*');
+    isSubtype('FutureOr<A>', 'FutureOr<B>', typeParameters: 'B,A extends B');
+
+    isSubtype('X', 'FutureOr<int>',
+        typeParameters: 'X extends FutureOr<int*>*');
+    isSubtype('X*', 'FutureOr<int>',
+        typeParameters: 'X extends FutureOr<int*>*');
+
     isSubtype('num?', 'FutureOr<FutureOr<FutureOr<num>>?>');
     isSubtype('Future<num>?', 'FutureOr<FutureOr<FutureOr<num>>?>');
     isSubtype('Future<Future<num>>?', 'FutureOr<FutureOr<FutureOr<num>>?>');
@@ -282,6 +289,16 @@
     isSubtype('FutureOr<num>?', 'FutureOr<num?>');
     isObliviousSubtype('FutureOr<num?>', 'FutureOr<num>?');
 
+    isSubtype('List<FutureOr<List<dynamic>>>',
+        'List<FutureOr<List<FutureOr<dynamic>>>>');
+    isSubtype('List<FutureOr<List<FutureOr<dynamic>>>>',
+        'List<FutureOr<List<dynamic>>>');
+
+    isSubtype('X', 'FutureOr<List<X>>',
+        typeParameters: 'X extends FutureOr<List<X>>');
+    isNotSubtype('X', 'FutureOr<List<X>>',
+        typeParameters: 'X extends List<FutureOr<X>>');
+
     isSubtype('dynamic', 'FutureOr<Object?>');
     isSubtype('dynamic', 'FutureOr<Object>?');
     isSubtype('void', 'FutureOr<Object?>');
diff --git a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
index c869e7c..8a81b61 100644
--- a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
+++ b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
@@ -108,8 +108,8 @@
     List<SubtypeCheck> checks, ClassHierarchyBuilder hierarchy) {
   for (int i = 0; i < checks.length; i++) {
     SubtypeCheck check = checks[i];
-    bool isSubtype = hierarchy.types.isSubtypeOfKernel(
-        check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
+    bool isSubtype = hierarchy.types
+        .isSubtypeOf(check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
     if (isSubtype != check.isSubtype) {
       throw "Check failed: $check";
     }
diff --git a/pkg/front_end/test/id_testing/data/marker.options b/pkg/front_end/test/id_testing/data/marker.options
index bb35ae5..c846376b 100644
--- a/pkg/front_end/test/id_testing/data/marker.options
+++ b/pkg/front_end/test/id_testing/data/marker.options
@@ -1,2 +1,3 @@
 cfe=pkg/front_end/test/id_testing/id_testing_test.dart
 dart2js=tests/compiler/dart2js/equivalence/id_testing_test.dart
+dart2js:nnbd-sdk=tests/compiler/dart2js/equivalence/id_testing_test.dart
diff --git a/pkg/front_end/test/id_tests/assigned_variables_test.dart b/pkg/front_end/test/id_tests/assigned_variables_test.dart
index cdff0ce..51832e2 100644
--- a/pkg/front_end/test/id_tests/assigned_variables_test.dart
+++ b/pkg/front_end/test/id_tests/assigned_variables_test.dart
@@ -100,7 +100,7 @@
   const _AssignedVariablesDataInterpreter();
 
   @override
-  String getText(_Data actualData) {
+  String getText(_Data actualData, [String indentation]) {
     var parts = <String>[];
     if (actualData.declared.isNotEmpty) {
       parts.add('declared=${_setToString(actualData.declared)}');
diff --git a/pkg/front_end/test/id_tests/definite_assignment_test.dart b/pkg/front_end/test/id_tests/definite_assignment_test.dart
index cb48f84..68b66ed 100644
--- a/pkg/front_end/test/id_tests/definite_assignment_test.dart
+++ b/pkg/front_end/test/id_tests/definite_assignment_test.dart
@@ -67,7 +67,7 @@
   String computeNodeValue(Id id, TreeNode node) {
     if (node is VariableGet) {
       TreeNode alias = _sourceLoaderDataForTesting.toOriginal(node);
-      if (_flowResult.unassignedNodes.contains(alias)) {
+      if (_flowResult.potentiallyUnassignedNodes.contains(alias)) {
         return 'unassigned';
       }
     }
diff --git a/pkg/front_end/test/id_tests/inheritance_test.dart b/pkg/front_end/test/id_tests/inheritance_test.dart
index 33de8fd..a042a8a 100644
--- a/pkg/front_end/test/id_tests/inheritance_test.dart
+++ b/pkg/front_end/test/id_tests/inheritance_test.dart
@@ -132,8 +132,17 @@
           type = substitution
               .substituteType(member.function.positionalParameters.single.type);
         } else {
-          type = substitution.substituteType(member.function
-              .computeThisFunctionType(member.enclosingLibrary.nonNullable));
+          Nullability functionTypeNullability;
+          if (node.enclosingLibrary.isNonNullableByDefault) {
+            functionTypeNullability = member.enclosingLibrary.nonNullable;
+          } else {
+            // We don't create a member signature when the member is just
+            // a substitution. We should still take the nullability to be
+            // legacy, though.
+            functionTypeNullability = node.enclosingLibrary.nonNullable;
+          }
+          type = substitution.substituteType(
+              member.function.computeThisFunctionType(functionTypeNullability));
         }
       } else if (member is Field) {
         type = substitution.substituteType(member.type);
diff --git a/pkg/front_end/test/id_tests/reachability_test.dart b/pkg/front_end/test/id_tests/reachability_test.dart
index e0cb2cd..1cdf867 100644
--- a/pkg/front_end/test/id_tests/reachability_test.dart
+++ b/pkg/front_end/test/id_tests/reachability_test.dart
@@ -117,7 +117,8 @@
   const _ReachabilityDataInterpreter();
 
   @override
-  String getText(Set<_ReachabilityAssertion> actualData) =>
+  String getText(Set<_ReachabilityAssertion> actualData,
+          [String indentation]) =>
       _sortedRepresentation(_toStrings(actualData));
 
   @override
diff --git a/pkg/front_end/test/id_tests/type_promotion_test.dart b/pkg/front_end/test/id_tests/type_promotion_test.dart
index 58dd40f..5e963c7 100644
--- a/pkg/front_end/test/id_tests/type_promotion_test.dart
+++ b/pkg/front_end/test/id_tests/type_promotion_test.dart
@@ -61,7 +61,7 @@
   const _TypePromotionDataInterpreter();
 
   @override
-  String getText(DartType actualData) =>
+  String getText(DartType actualData, [String indentation]) =>
       typeToText(actualData, TypeRepresentation.analyzerNonNullableByDefault);
 
   @override
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index ec1eebd..2d7e57c 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -46,7 +46,7 @@
   // type inference occurring before or after mixin transformation.
   Stopwatch stopwatch = new Stopwatch()..start();
   await normalCompile(dart2jsUrl, normalDill,
-      options: getOptions()..target = new NoneTarget(new TargetFlags()));
+      options: getOptions(target: new NoneTarget(new TargetFlags())));
   print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
   {
     // Check that we don't include the source from files from the sdk.
@@ -84,7 +84,7 @@
     stopwatch.reset();
     bool initializeResult = await initializedCompile(
         dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri],
-        options: getOptions()..target = new NoneTarget(new TargetFlags()));
+        options: getOptions(target: new NoneTarget(new TargetFlags())));
     Expect.equals(initializeExpect, initializeResult);
     print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
         "took ${stopwatch.elapsedMilliseconds} ms");
@@ -99,7 +99,7 @@
     stopwatch.reset();
     initializeResult = await initializedCompile(
         dart2jsUrl, fullDillFromInitialized, initializeWith, [],
-        options: getOptions()..target = new NoneTarget(new TargetFlags()));
+        options: getOptions(target: new NoneTarget(new TargetFlags())));
     Expect.equals(initializeExpect, initializeResult);
     print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
         "took ${stopwatch.elapsedMilliseconds} ms");
diff --git a/pkg/front_end/test/incremental_dart2js_tester.dart b/pkg/front_end/test/incremental_dart2js_tester.dart
index 8a5401c..a67953d 100644
--- a/pkg/front_end/test/incremental_dart2js_tester.dart
+++ b/pkg/front_end/test/incremental_dart2js_tester.dart
@@ -174,7 +174,7 @@
     stopwatch.reset();
     stopwatch.start();
     Uri input = Platform.script.resolve("../../compiler/bin/dart2js.dart");
-    CompilerOptions options = helper.getOptions(targetName: "VM");
+    CompilerOptions options = helper.getOptions();
     helper.TestIncrementalCompiler compiler =
         new helper.TestIncrementalCompiler(options, input);
     compiler.useExperimentalInvalidation = useExperimentalInvalidation;
diff --git a/pkg/front_end/test/incremental_load_from_dill_suite.dart b/pkg/front_end/test/incremental_load_from_dill_suite.dart
index 97a33b5..015e3d5 100644
--- a/pkg/front_end/test/incremental_load_from_dill_suite.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_suite.dart
@@ -15,6 +15,8 @@
 
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
+import "package:dev_compiler/src/kernel/target.dart" show DevCompilerTarget;
+
 import 'package:expect/expect.dart' show Expect;
 
 import 'package:front_end/src/api_prototype/compiler_options.dart'
@@ -59,7 +61,8 @@
         LibraryDependency,
         Member,
         Name,
-        Procedure;
+        Procedure,
+        Supertype;
 
 import 'package:kernel/target/targets.dart'
     show NoneTarget, Target, TargetFlags;
@@ -164,6 +167,7 @@
           "omitPlatform",
           "target",
           "forceLateLoweringForTesting",
+          "trackWidgetCreation",
           "incrementalSerialization"
         ]);
         await new NewWorldTest().newWorldTest(
@@ -173,7 +177,8 @@
           map["modules"],
           map["omitPlatform"],
           map["target"],
-          map["forceLateLoweringForTesting"],
+          map["forceLateLoweringForTesting"] ?? false,
+          map["trackWidgetCreation"] ?? false,
           map["incrementalSerialization"],
         );
         break;
@@ -245,16 +250,13 @@
   checkIsEqual(normalDillData, initializedDillData);
 }
 
-Future<Map<String, List<int>>> createModules(
-    Map module,
-    final List<int> sdkSummaryData,
-    String targetName,
-    bool forceLateLoweringForTesting) async {
+Future<Map<String, List<int>>> createModules(Map module,
+    final List<int> sdkSummaryData, Target target, String sdkSummary) async {
   final Uri base = Uri.parse("org-dartlang-test:///");
-  final Uri sdkSummary = base.resolve("vm_platform_strong.dill");
+  final Uri sdkSummaryUri = base.resolve(sdkSummary);
 
   MemoryFileSystem fs = new MemoryFileSystem(base);
-  fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
+  fs.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
 
   // Setup all sources
   for (Map moduleSources in module.values) {
@@ -281,12 +283,11 @@
         moduleSources.add(uri);
       }
     }
-    CompilerOptions options = getOptions(
-        targetName: targetName,
-        forceLateLoweringForTesting: forceLateLoweringForTesting);
+    CompilerOptions options =
+        getOptions(target: target, sdkSummary: sdkSummary);
     options.fileSystem = fs;
     options.sdkRoot = null;
-    options.sdkSummary = sdkSummary;
+    options.sdkSummary = sdkSummaryUri;
     options.omitPlatform = true;
     options.onDiagnostic = (DiagnosticMessage message) {
       if (getMessageCodeObject(message)?.name == "InferredPackageUri") return;
@@ -334,12 +335,32 @@
       bool omitPlatform,
       String targetName,
       bool forceLateLoweringForTesting,
+      bool trackWidgetCreation,
       bool incrementalSerialization) async {
     final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
+
+    TargetFlags targetFlags = new TargetFlags(
+        forceLateLoweringForTesting: forceLateLoweringForTesting,
+        trackWidgetCreation: trackWidgetCreation);
+    Target target = new VmTarget(targetFlags);
+    String sdkSummary = "vm_platform_strong.dill";
+    if (targetName != null) {
+      if (targetName == "None") {
+        target = new NoneTarget(targetFlags);
+      } else if (targetName == "DDC") {
+        target = new DevCompilerTarget(targetFlags);
+        sdkSummary = "ddc_platform.dill";
+      } else if (targetName == "VM") {
+        // default.
+      } else {
+        throw "Unknown target name '$targetName'";
+      }
+    }
+
     final Uri base = Uri.parse("org-dartlang-test:///");
-    final Uri sdkSummary = base.resolve("vm_platform_strong.dill");
+    final Uri sdkSummaryUri = base.resolve(sdkSummary);
     final Uri initializeFrom = base.resolve("initializeFrom.dill");
-    Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
+    Uri platformUri = sdkRoot.resolve(sdkSummary);
     final List<int> sdkSummaryData =
         await new File.fromUri(platformUri).readAsBytes();
 
@@ -354,8 +375,8 @@
     Map<String, Component> moduleComponents;
 
     if (modules != null) {
-      moduleData = await createModules(
-          modules, sdkSummaryData, targetName, forceLateLoweringForTesting);
+      moduleData =
+          await createModules(modules, sdkSummaryData, target, sdkSummary);
       sdk = newestWholeComponent = new Component();
       new BinaryBuilder(sdkSummaryData,
               filename: null, disableLazyReading: false)
@@ -411,7 +432,7 @@
       if (brandNewWorld) {
         fs = new MemoryFileSystem(base);
       }
-      fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
+      fs.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
       bool expectInitializeFromDill = false;
       if (newestWholeComponentData != null &&
           newestWholeComponentData.isNotEmpty) {
@@ -443,12 +464,10 @@
       }
 
       if (brandNewWorld) {
-        options = getOptions(
-            targetName: targetName,
-            forceLateLoweringForTesting: forceLateLoweringForTesting);
+        options = getOptions(target: target, sdkSummary: sdkSummary);
         options.fileSystem = fs;
         options.sdkRoot = null;
-        options.sdkSummary = sdkSummary;
+        options.sdkSummary = sdkSummaryUri;
         options.omitPlatform = omitPlatform != false;
         if (world["experiments"] != null) {
           Map<ExperimentalFlag, bool> experimentalFlags =
@@ -908,10 +927,32 @@
     sb.writeln("Library ${library.importUri}");
     for (Class c in library.classes) {
       sb.writeln("  - Class ${c.name}");
+
+      Set<Class> checkedSupertypes = <Class>{};
+      void checkSupertype(Supertype supertype) {
+        if (supertype == null) return;
+        Class superclass = supertype.classNode;
+        if (checkedSupertypes.add(superclass)) {
+          Supertype asSuperClass =
+              classHierarchy.getClassAsInstanceOf(c, superclass);
+          if (asSuperClass == null) {
+            throw "${superclass} not found as a superclass of $c";
+          }
+          checkSupertype(superclass.supertype);
+          checkSupertype(superclass.mixedInType);
+          for (Supertype interface in superclass.implementedTypes) {
+            checkSupertype(interface);
+          }
+        }
+      }
+
+      checkSupertype(c.asThisSupertype);
+
       ForTestingClassInfo info = classHierarchyMap[c];
       if (info == null) {
         throw "Didn't find any class hierarchy info for $c";
       }
+
       if (info.lazyDeclaredGettersAndCalls != null) {
         sb.writeln("    - lazyDeclaredGettersAndCalls:");
         for (Member member in info.lazyDeclaredGettersAndCalls) {
@@ -1330,20 +1371,10 @@
   Expect.equals(a.length, b.length);
 }
 
-CompilerOptions getOptions(
-    {String targetName, bool forceLateLoweringForTesting: false}) {
+CompilerOptions getOptions({Target target, String sdkSummary}) {
+  target ??= new VmTarget(new TargetFlags());
+  sdkSummary ??= 'vm_platform_strong.dill';
   final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
-  Target target = new VmTarget(new TargetFlags(
-      forceLateLoweringForTesting: forceLateLoweringForTesting));
-  if (targetName != null) {
-    if (targetName == "None") {
-      target = new NoneTarget(new TargetFlags());
-    } else if (targetName == "VM") {
-      // default.
-    } else {
-      throw "Unknown target name '$targetName'";
-    }
-  }
   CompilerOptions options = new CompilerOptions()
     ..sdkRoot = sdkRoot
     ..target = target
@@ -1356,7 +1387,7 @@
             "Unexpected error: ${message.plainTextFormatted.join('\n')}");
       }
     }
-    ..sdkSummary = sdkRoot.resolve("vm_platform_strong.dill")
+    ..sdkSummary = sdkRoot.resolve(sdkSummary)
     ..environmentDefines = const {};
   return options;
 }
diff --git a/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart b/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
index ccd1823..62d6624 100644
--- a/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
@@ -40,7 +40,8 @@
 
 import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
 
-import 'package:kernel/kernel.dart' show Component, Library;
+import 'package:kernel/kernel.dart'
+    show Component, Library, NonNullableByDefaultCompiledMode;
 
 import 'incremental_load_from_dill_suite.dart' show getOptions;
 
@@ -236,6 +237,38 @@
     // Should be ok (for now), but we shouldn't actually initialize from dill.
     fs.entityForUri(initializeFrom).writeAsBytesSync(dataLinkedToSdkWithFoo);
     await compileExpectOk(false, entryPoint);
+
+    // Try to initialize from a dill which contains mixed compilation modes:
+    // Should be ok, but we shouldn't actually initialize from dill.
+    List<int> mixedPart1;
+    {
+      compiler = new IncrementalCompiler(
+          new CompilerContext(
+              new ProcessedOptions(options: options, inputs: [helper2File])),
+          null);
+      Component c = await compiler.computeDelta();
+      c.setMainMethodAndMode(
+          null, false, NonNullableByDefaultCompiledMode.Disabled);
+      mixedPart1 = serializeComponent(c);
+    }
+
+    List<int> mixedPart2;
+    {
+      compiler = new IncrementalCompiler(
+          new CompilerContext(
+              new ProcessedOptions(options: options, inputs: [helperFile])),
+          null);
+      Component c = await compiler.computeDelta();
+      c.setMainMethodAndMode(
+          null, false, NonNullableByDefaultCompiledMode.Strong);
+      mixedPart2 = serializeComponent(c);
+    }
+
+    List<int> mixed = [];
+    mixed.addAll(mixedPart1);
+    mixed.addAll(mixedPart2);
+    fs.entityForUri(initializeFrom).writeAsBytesSync(mixed);
+    await compileExpectOk(false, entryPoint);
   }
 }
 
diff --git a/pkg/front_end/test/language_versioning/language_versioning_test.dart b/pkg/front_end/test/language_versioning/language_versioning_test.dart
index fca5c65..08631e7 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_test.dart
@@ -20,7 +20,7 @@
         onFailure,
         runTestFor;
 
-import 'package:kernel/ast.dart' show Component, Library;
+import 'package:kernel/ast.dart' show Component, Library, Version;
 
 main(List<String> args) async {
   // Fix default/max major and minor version so we can test it.
@@ -76,19 +76,16 @@
   Future<void> inspectComponent(Component component) async {
     for (Library library in component.libraries) {
       if (library.importUri.scheme == "dart") continue;
-      lv.LanguageVersionForUri lvFile =
+      Version lvFile =
           await lv.languageVersionForUri(library.fileUri, stashedOptions);
-      lv.LanguageVersionForUri lvImportUri =
+      Version lvImportUri =
           await lv.languageVersionForUri(library.importUri, stashedOptions);
-      if ((lvFile.major != lvImportUri.major ||
-              lvFile.major != library.languageVersionMajor) ||
-          (lvFile.minor != lvImportUri.minor ||
-              lvFile.minor != library.languageVersionMinor)) {
+      if ((lvFile != lvImportUri || lvFile != library.languageVersion)) {
         throw """
 Language version disagreement:
-Library: ${library.languageVersionMajor}.${library.languageVersionMinor}
-Language version API (file URI): ${lvFile.major}.${lvFile.minor}
-Language version API (import URI): ${lvImportUri.major}.${lvImportUri.minor}
+Library: ${library.languageVersion}
+Language version API (file URI): ${lvFile}
+Language version API (import URI): ${lvImportUri}
 """;
       }
     }
@@ -123,9 +120,8 @@
 
   @override
   String computeLibraryValue(Id id, Library library) {
-    return "languageVersion="
-        "${library.languageVersionMajor}"
+    return "languageVersion=${library.languageVersion.major}"
         "."
-        "${library.languageVersionMinor}";
+        "${library.languageVersion.minor}";
   }
 }
diff --git a/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart b/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart
index 171e212..3e20772 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart
@@ -6,8 +6,7 @@
 
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 
-import 'package:kernel/default_language_version.dart' as kernel
-    show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
+import 'package:kernel/ast.dart' as kernel show Version, defaultLanguageVersion;
 
 import '../utils/io_utils.dart';
 
@@ -36,14 +35,12 @@
   List<String> dotSeparatedParts = versionString.split(".");
   int major = int.tryParse(dotSeparatedParts[0]);
   int minor = int.tryParse(dotSeparatedParts[1]);
+  kernel.Version version = new kernel.Version(major, minor);
 
-  if (kernel.defaultLanguageVersionMajor != major ||
-      kernel.defaultLanguageVersionMinor != minor) {
+  if (kernel.defaultLanguageVersion != version) {
     throw "Kernel defaults "
-        "${kernel.defaultLanguageVersionMajor}"
-        "."
-        "${kernel.defaultLanguageVersionMinor}"
-        " does not match output from make_version.py ($major.$minor)";
+        "${kernel.defaultLanguageVersion}"
+        " does not match output from make_version.py ($version)";
   } else {
     print("Kernel version matches.");
   }
diff --git a/pkg/front_end/test/lint_test.status b/pkg/front_end/test/lint_test.status
index c236ac1..c0e36d4 100644
--- a/pkg/front_end/test/lint_test.status
+++ b/pkg/front_end/test/lint_test.status
@@ -2,33 +2,33 @@
 # 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.
 
-src/api_unstable/bazel_worker/ImportsTwice: Fail
-src/fasta/incremental_compiler/ImportsTwice: Fail
-src/fasta/kernel/body_builder/ImportsTwice: Fail
-src/fasta/kernel/expression_generator_helper/ImportsTwice: Fail
-src/fasta/parser/parser/ImportsTwice: Fail
-src/fasta/scanner/abstract_scanner/ImportsTwice: Fail
-src/fasta/scanner/recover/ImportsTwice: Fail
-src/fasta/scanner/string_scanner/ImportsTwice: Fail
-src/fasta/scanner/token/ImportsTwice: Fail
-src/fasta/scanner/utf8_bytes_scanner/ImportsTwice: Fail
-src/fasta/source/source_class_builder/ImportsTwice: Fail
-src/fasta/source/value_kinds/ImportsTwice: Fail
-src/fasta/type_inference/type_constraint_gatherer/ImportsTwice: Fail
-src/fasta/type_inference/type_inferrer/ImportsTwice: Fail
-
 src/api_prototype/compiler_options/Exports: Fail
 src/api_prototype/constant_evaluator/Exports: Fail
 src/api_prototype/front_end/Exports: Fail
 src/api_prototype/incremental_kernel_generator/Exports: Fail
+src/api_prototype/language_version/Exports: Fail
+src/api_unstable/bazel_worker/ImportsTwice: Fail
 src/fasta/fasta_codes/Exports: Fail
+src/fasta/incremental_compiler/ImportsTwice: Fail
+src/fasta/kernel/body_builder/ImportsTwice: Fail
 src/fasta/kernel/constant_evaluator/ExplicitType: Pass
+src/fasta/kernel/expression_generator_helper/ImportsTwice: Fail
 src/fasta/kernel/kernel_api/Exports: Fail
 src/fasta/kernel/kernel_ast_api/Exports: Fail
 src/fasta/kernel/kernel_builder/Exports: Fail
 src/fasta/kernel/type_algorithms/Exports: Fail
 src/fasta/messages/Exports: Fail
 src/fasta/parser/Exports: Fail
+src/fasta/parser/parser/ImportsTwice: Fail
+src/fasta/scanner/abstract_scanner/ImportsTwice: Fail
 src/fasta/scanner/Exports: Fail
+src/fasta/scanner/recover/ImportsTwice: Fail
+src/fasta/scanner/string_scanner/ImportsTwice: Fail
+src/fasta/scanner/token/ImportsTwice: Fail
+src/fasta/scanner/utf8_bytes_scanner/ImportsTwice: Fail
 src/fasta/source/scope_listener/Exports: Fail
+src/fasta/source/source_class_builder/ImportsTwice: Fail
+src/fasta/source/value_kinds/ImportsTwice: Fail
+src/fasta/type_inference/type_constraint_gatherer/ImportsTwice: Fail
+src/fasta/type_inference/type_inferrer/ImportsTwice: Fail
 src/testing/id_testing_helper/Exports: Fail
diff --git a/pkg/front_end/test/old_dill_suite.dart b/pkg/front_end/test/old_dill_suite.dart
index 7e70850..c48c30b 100644
--- a/pkg/front_end/test/old_dill_suite.dart
+++ b/pkg/front_end/test/old_dill_suite.dart
@@ -8,6 +8,8 @@
 
 import 'package:kernel/binary/tag.dart' show Tag;
 
+import 'package:front_end/src/base/command_line_options.dart';
+
 import 'package:testing/testing.dart'
     show ChainContext, Result, Step, TestDescription, Chain, runMe;
 
@@ -73,11 +75,11 @@
       [
         fastaCompile.toFilePath(),
         "sdkroot:/pkg/compiler/bin/dart2js.dart",
-        "-o",
+        "${Flags.output}",
         output.toFilePath(),
-        "--target=vm",
-        "--single-root-base=${Uri.base.toFilePath()}",
-        "--single-root-scheme=sdkroot",
+        "${Flags.target}=vm",
+        "${Flags.singleRootBase}=${Uri.base.toFilePath()}",
+        "${Flags.singleRootScheme}=sdkroot",
       ],
       workingDirectory: Uri.base.toFilePath());
   if (result.exitCode != 0) {
diff --git a/pkg/front_end/test/parser_suite.dart b/pkg/front_end/test/parser_suite.dart
index ce28c25..cbbf1219 100644
--- a/pkg/front_end/test/parser_suite.dart
+++ b/pkg/front_end/test/parser_suite.dart
@@ -237,11 +237,14 @@
       }
     });
   }
+}
 
-  StringBuffer tokenStreamToString(Token firstToken, List<int> lineStarts,
-      {bool addTypes: false}) {
-    StringBuffer sb = new StringBuffer();
-    Token token = firstToken;
+StringBuffer tokenStreamToString(Token firstToken, List<int> lineStarts,
+    {bool addTypes: false}) {
+  StringBuffer sb = new StringBuffer();
+  Token token = firstToken;
+
+  Token process(Token token, bool errorTokens) {
     bool printed = false;
     int endOfLast = -1;
     int lineStartsIteratorLine = 1;
@@ -249,7 +252,15 @@
     lineStartsIterator.moveNext();
     lineStartsIterator.moveNext();
     lineStartsIteratorLine++;
+
     while (token != null) {
+      if (errorTokens && token is! ErrorToken) return token;
+      if (!errorTokens && token is ErrorToken) {
+        if (token == token.next) break;
+        token = token.next;
+        continue;
+      }
+
       int prevLine = lineStartsIteratorLine;
       while (token.offset >= lineStartsIterator.current &&
           lineStartsIterator.moveNext()) {
@@ -276,8 +287,16 @@
       if (token == token.next) break;
       token = token.next;
     }
-    return sb;
+
+    return token;
   }
+
+  if (addTypes) {
+    token = process(token, true);
+  }
+  token = process(token, false);
+
+  return sb;
 }
 
 Token scanUri(Uri uri, String shortName, {List<int> lineStarts}) {
@@ -293,6 +312,11 @@
   File f = new File.fromUri(uri);
   List<int> rawBytes = f.readAsBytesSync();
 
+  return scanRawBytes(rawBytes, config, lineStarts);
+}
+
+Token scanRawBytes(
+    List<int> rawBytes, ScannerConfiguration config, List<int> lineStarts) {
   Uint8List bytes = new Uint8List(rawBytes.length + 1);
   bytes.setRange(0, rawBytes.length, rawBytes);
 
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index 25cf6c1..54b7c6b 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -265,15 +265,15 @@
   }
 
   void endExtensionDeclaration(
-      Token extensionKeyword, Token onKeyword, Token token) {
+      Token extensionKeyword, Token onKeyword, Token endToken) {
     indent--;
     seen(extensionKeyword);
     seen(onKeyword);
-    seen(token);
+    seen(endToken);
     doPrint('endExtensionDeclaration('
         '$extensionKeyword, '
         '$onKeyword, '
-        '$token)');
+        '$endToken)');
   }
 
   void beginCombinators(Token token) {
@@ -1644,6 +1644,18 @@
     doPrint('endWhileStatement(' '$whileKeyword, ' '$endToken)');
   }
 
+  void beginAsOperatorType(Token operator) {
+    seen(operator);
+    doPrint('beginAsOperatorType(' '$operator)');
+    indent++;
+  }
+
+  void endAsOperatorType(Token operator) {
+    indent--;
+    seen(operator);
+    doPrint('endAsOperatorType(' '$operator)');
+  }
+
   void handleAsOperator(Token operator) {
     seen(operator);
     doPrint('handleAsOperator(' '$operator)');
@@ -1775,6 +1787,18 @@
         '$closeSquareBracket)');
   }
 
+  void beginIsOperatorType(Token operator) {
+    seen(operator);
+    doPrint('beginIsOperatorType(' '$operator)');
+    indent++;
+  }
+
+  void endIsOperatorType(Token operator) {
+    indent--;
+    seen(operator);
+    doPrint('endIsOperatorType(' '$operator)');
+  }
+
   void handleIsOperator(Token isOperator, Token not) {
     seen(isOperator);
     seen(not);
diff --git a/pkg/front_end/test/read_dill_from_binary_md_test.dart b/pkg/front_end/test/read_dill_from_binary_md_test.dart
index 8b9c6d3..4907f4e 100644
--- a/pkg/front_end/test/read_dill_from_binary_md_test.dart
+++ b/pkg/front_end/test/read_dill_from_binary_md_test.dart
@@ -23,7 +23,7 @@
   final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
   Stopwatch stopwatch = new Stopwatch()..start();
   List<int> bytes = await normalCompileToBytes(dart2jsUrl,
-      options: getOptions()..target = new NoneTarget(new TargetFlags()));
+      options: getOptions(target: new NoneTarget(new TargetFlags())));
   print("Compiled dart2js in ${stopwatch.elapsedMilliseconds} ms");
 
   stopwatch.reset();
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 26b64c8..d342281 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -43,6 +43,8 @@
 ap
 api
 app
+apparently
+applicable
 arg
 args
 argument1
@@ -105,6 +107,7 @@
 bj
 blob
 blocking
+bmp
 bn
 bo
 bodied
@@ -141,6 +144,7 @@
 carets
 carriage
 cascades
+casing
 cast
 casted
 casts
@@ -151,6 +155,7 @@
 charcode
 chars
 checkpoint
+chunks
 ci
 ck
 cl
@@ -205,6 +210,7 @@
 config
 configs
 configured
+consideration
 constness
 consult
 consumers
@@ -236,6 +242,7 @@
 cyclically
 d
 d11e
+d7c
 dag
 dangerous
 dangling
@@ -300,7 +307,6 @@
 dispatched
 divided
 dmitryas
-dupdate
 doc
 docs
 dom
@@ -313,6 +319,7 @@
 dquote
 dst
 dummy
+dupdate
 e
 easy
 ecma
@@ -343,6 +350,7 @@
 equation
 erasure
 es
+established
 estimate
 eval
 excludes
@@ -363,6 +371,7 @@
 f
 faced
 factor
+factored
 fangorn
 fasta
 favoring
@@ -481,6 +490,7 @@
 imply
 implying
 importantly
+inapplicable
 inc
 incomparable
 inconsistency
@@ -570,6 +580,7 @@
 lm
 locationd
 logging
+logically
 lots
 lp
 lparen
@@ -590,12 +601,14 @@
 mangled
 manipulation
 markdown
+masking
 matcher
 mb
 md
 me
 merely
 meta
+metadata's
 method10a
 method10b
 method1a
@@ -631,6 +644,7 @@
 mm
 mn
 mockito
+modelling
 momentarily
 monomorphic
 morebottom
@@ -684,6 +698,7 @@
 o
 oauth
 obj
+obligated
 observatory
 observe
 obstruct
@@ -704,6 +719,7 @@
 orphans
 ors
 os
+outputting
 overlap
 overloader
 overshadowed
@@ -885,6 +901,7 @@
 rooted
 roughly
 rounding
+roundtrip
 rparen
 rpc
 rs
@@ -919,6 +936,7 @@
 shallow
 shas
 shelf
+shifts
 showing
 shrinking
 shru
@@ -948,6 +966,7 @@
 sole
 solely
 somewhat
+sortable
 sourcemap
 spaced
 sparse
@@ -974,6 +993,7 @@
 stdout
 stmt
 str
+streak
 streaming
 strict
 stringified
@@ -1040,6 +1060,7 @@
 testers
 testing
 tex
+textualize
 tflite
 th
 therein
@@ -1193,6 +1214,7 @@
 worthwhile
 writeln
 wrt
+wtf
 www
 x
 x0
@@ -1233,6 +1255,7 @@
 xn
 xnon
 xor
+xor's
 xpotentially
 xs
 xss
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 87d9f28..885f530 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1054,8 +1054,8 @@
 exited
 exits
 expand
-expands
 expanding
+expands
 expansion
 expect
 expectation
@@ -1170,6 +1170,7 @@
 fixes
 fixing
 flag
+flagged
 flags
 flat
 flatten
@@ -1369,6 +1370,7 @@
 identity
 ie
 if
+ignorable
 ignorant
 ignore
 ignored
@@ -1410,6 +1412,7 @@
 included
 includes
 including
+inclusion
 inclusive
 incoming
 incompatible
@@ -1446,6 +1449,7 @@
 inferring
 infers
 infinite
+infinity
 infix
 info
 inform
@@ -1704,6 +1708,7 @@
 logging
 logic
 logical
+lone
 long
 longer
 longest
@@ -1766,6 +1771,7 @@
 matter
 maturity
 max
+maximal
 maximum
 may
 maybe
@@ -1841,6 +1847,7 @@
 modulo
 moment
 mongolian
+monotonous
 more
 moreover
 most
@@ -1875,6 +1882,7 @@
 names
 namespace
 naming
+nan
 narrow
 narrower
 native
@@ -1941,6 +1949,7 @@
 objects
 oblivious
 observation
+observations
 observed
 obtain
 obtained
@@ -2244,6 +2253,7 @@
 promotion
 promotions
 propagate
+propagates
 propagating
 propagation
 proper
@@ -2324,6 +2334,8 @@
 recognizes
 recommend
 recommendations
+recomputation
+recomputes
 record
 recorded
 recording
@@ -2556,6 +2568,7 @@
 searching
 second
 section
+security
 see
 seeing
 seem
@@ -2987,6 +3000,7 @@
 translates
 translating
 translator
+traveling
 traversed
 treat
 treated
@@ -3013,6 +3027,8 @@
 truly
 truncate
 truncating
+trust
+trusts
 truth
 try
 trying
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index 1dbcdac..1e01dae 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -46,6 +46,7 @@
 opts
 part(s)
 patch(es)
+pubspec.yaml
 re
 sdksummary
 stacktrace
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 46fad1f..2c2610c 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -27,8 +27,10 @@
 aoo
 approval
 approximation
+arbitrarily
 asdf
 asserter
+assure
 auth
 authority
 auto
@@ -61,6 +63,7 @@
 bots
 bowtie
 boz
+bq
 brand
 brave
 brown
@@ -133,6 +136,7 @@
 detector
 deviation
 dfast
+di
 dictionaries
 dictionary
 differences
@@ -159,6 +163,7 @@
 dumping
 dupe
 durations
+dw
 dyn
 e's
 e2e
@@ -174,6 +179,7 @@
 err
 everytime
 evicting
+excess
 exe
 execute
 exercised
@@ -272,6 +278,11 @@
 isolate
 isolates
 issue41210b
+issue41436c
+issue41496b
+issue41498b
+issue41499b
+it'll
 iter
 joo
 jumped
@@ -333,6 +344,7 @@
 metrics
 mf
 micro
+minimize
 minutes
 mismatched
 misnamed
@@ -340,6 +352,7 @@
 misspelled
 mistake
 mistakes
+modelled
 month
 moo
 mx
@@ -358,6 +371,7 @@
 oh
 okay
 ooo
+operate
 ops
 optimal
 oracle
@@ -437,6 +451,7 @@
 sdks
 secondary
 segment
+sensitive
 severe
 sheets
 shipped
diff --git a/pkg/front_end/test/split_dill_test.dart b/pkg/front_end/test/split_dill_test.dart
index dee8bf3..55f52ba 100644
--- a/pkg/front_end/test/split_dill_test.dart
+++ b/pkg/front_end/test/split_dill_test.dart
@@ -38,7 +38,8 @@
     Component libComponent = new Component(nameRoot: component.root);
     libComponent.libraries.add(lib);
     libComponent.uriToSource.addAll(component.uriToSource);
-    libComponent.mainMethod = component.mainMethod;
+    libComponent.setMainMethodAndMode(
+        component.mainMethodName, true, component.mode);
     libComponents.add(serializeComponent(libComponent));
   }
   print("Serialized ${libComponents.length} separate library components "
diff --git a/pkg/front_end/test/static_types/data/for_in.dart b/pkg/front_end/test/static_types/data/for_in.dart
index 8ae7137..93dcd4f 100644
--- a/pkg/front_end/test/static_types/data/for_in.dart
+++ b/pkg/front_end/test/static_types/data/for_in.dart
@@ -29,7 +29,8 @@
   for (var e in
       /*cfe.List<int>*/
       /*cfe:nnbd.List<int!>!*/ list) {
-    /*int*/
+    /*cfe.int*/
+    /*cfe:nnbd.int!*/
     e;
   }
 }
@@ -72,7 +73,8 @@
       /*cfe.Stream<int>*/
       /*cfe:nnbd.Stream<int!>!*/
       stream) {
-    /*int*/
+    /*cfe.int*/
+    /*cfe:nnbd.int!*/
     e;
   }
 }
diff --git a/pkg/front_end/test/test_generator_test.dart b/pkg/front_end/test/test_generator_test.dart
index d0e3e1a..9ce654d 100644
--- a/pkg/front_end/test/test_generator_test.dart
+++ b/pkg/front_end/test/test_generator_test.dart
@@ -130,7 +130,7 @@
     MemoryFileSystem fs = new MemoryFileSystem(base);
     fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
 
-    CompilerOptions options = helper.getOptions(targetName: "VM");
+    CompilerOptions options = helper.getOptions();
     options.fileSystem = fs;
     options.sdkRoot = null;
     options.sdkSummary = sdkSummary;
diff --git a/pkg/front_end/test/textual_outline_test.dart b/pkg/front_end/test/textual_outline_test.dart
new file mode 100644
index 0000000..c22aff6
--- /dev/null
+++ b/pkg/front_end/test/textual_outline_test.dart
@@ -0,0 +1,99 @@
+import "dart:convert";
+import "package:front_end/src/fasta/util/textual_outline.dart";
+
+main() {
+  // Doesn't sort if not asked to perform modelling.
+  String result = textualOutline(utf8.encode("""
+b() { print("hello"); }
+a() { print("hello"); }
+"""), throwOnUnexpected: true, performModelling: false);
+  if (result !=
+      """
+b() { }
+
+a() { }""") {
+    throw "Unexpected result: $result";
+  }
+
+  // Sort if asked to perform modelling.
+  result = textualOutline(utf8.encode("""
+b() { print("hello"); }
+a() { print("hello"); }
+"""), throwOnUnexpected: true, performModelling: true);
+  if (result !=
+      """
+a() { }
+
+b() { }""") {
+    throw "Unexpected result: $result";
+  }
+
+  // Content between braces or not doesn't make any difference.
+  // Procedure without content.
+  result = textualOutline(utf8.encode("""
+a() {}
+"""), throwOnUnexpected: true, performModelling: true);
+  if (result !=
+      """
+a() { }""") {
+    throw "Unexpected result: $result";
+  }
+
+  // Procedure with content.
+  result = textualOutline(utf8.encode("""
+a() {
+  // Whatever
+}
+"""), throwOnUnexpected: true, performModelling: true);
+  if (result !=
+      """
+a() { }""") {
+    throw "Unexpected result: $result";
+  }
+
+  // Class without content.
+  result = textualOutline(utf8.encode("""
+class A {}
+"""), throwOnUnexpected: true, performModelling: true);
+  if (result !=
+      """
+class A {
+}""") {
+    throw "Unexpected result: $result";
+  }
+
+  // Class without real content.
+  result = textualOutline(utf8.encode("""
+class A {
+  // Whatever
+}
+"""), throwOnUnexpected: true, performModelling: true);
+  if (result !=
+      """
+class A {
+}""") {
+    throw "Unexpected result: $result";
+  }
+
+  // Has space between entries.
+  result = textualOutline(utf8.encode("""
+@a
+@A(2)
+typedef void F1();
+
+@a
+@A(3)
+int f1, f2;
+"""), throwOnUnexpected: true, performModelling: true);
+  if (result !=
+      """
+@a
+@A(2)
+typedef void F1();
+
+@a
+@A(3)
+int f1, f2;""") {
+    throw "Unexpected result: $result";
+  }
+}
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 643ffcb..01edfe0 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -31,7 +31,8 @@
 
 import 'package:front_end/src/fasta/kernel/verifier.dart' show verifyComponent;
 
-import 'package:front_end/src/fasta/messages.dart' show LocatedMessage;
+import 'package:front_end/src/fasta/messages.dart'
+    show DiagnosticMessageFromJson, LocatedMessage;
 
 import 'package:kernel/ast.dart' show Component, Library;
 
@@ -49,6 +50,7 @@
 
 import 'package:kernel/text/text_serialization_verifier.dart'
     show
+        RoundTripStatus,
         TextDeserializationFailure,
         TextRoundTripFailure,
         TextSerializationFailure,
@@ -222,12 +224,15 @@
     extends Step<ComponentResult, ComponentResult, MatchContext> {
   final String suffix;
   final bool serializeFirst;
+  final bool isLastMatchStep;
 
   /// Check if a textual representation of the component matches the expectation
   /// located at [suffix]. If [serializeFirst] is true, the input component will
   /// be serialized, deserialized, and the textual representation of that is
   /// compared. It is still the original component that is returned though.
-  const MatchExpectation(this.suffix, {this.serializeFirst: false});
+  const MatchExpectation(this.suffix,
+      {this.serializeFirst: false, this.isLastMatchStep})
+      : assert(isLastMatchStep != null);
 
   String get name => "match expectations";
 
@@ -259,16 +264,58 @@
       component.adoptChildren();
     }
 
-    StringBuffer messages =
-        (context as dynamic).componentToDiagnostics[component];
     Uri uri =
         component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
     Iterable<Library> libraries =
         componentToText.libraries.where(result.isUserLibrary);
     Uri base = uri.resolve(".");
     Uri dartBase = Uri.base;
+
     StringBuffer buffer = new StringBuffer();
-    messages.clear();
+
+    List<Iterable<String>> errors =
+        (context as dynamic).componentToDiagnostics[component];
+    Set<String> reportedErrors = <String>{};
+    for (Iterable<String> message in errors) {
+      reportedErrors.add(message.join('\n'));
+    }
+    Set<String> problemsAsJson = <String>{};
+    void addProblemsAsJson(List<String> problems) {
+      if (problems != null) {
+        for (String jsonString in problems) {
+          DiagnosticMessage message =
+              new DiagnosticMessageFromJson.fromJson(jsonString);
+          problemsAsJson.add(message.plainTextFormatted.join('\n'));
+        }
+      }
+    }
+
+    addProblemsAsJson(componentToText.problemsAsJson);
+    libraries.forEach((Library library) {
+      addProblemsAsJson(library.problemsAsJson);
+    });
+
+    bool hasProblemsOutsideComponent = false;
+    for (String reportedError in reportedErrors) {
+      if (!problemsAsJson.contains(reportedError)) {
+        if (!hasProblemsOutsideComponent) {
+          buffer.writeln('//');
+          buffer.writeln('// Problems outside component:');
+        }
+        buffer.writeln('//');
+        buffer.writeln('// ${reportedError.split('\n').join('\n// ')}');
+        hasProblemsOutsideComponent = true;
+      }
+    }
+    if (hasProblemsOutsideComponent) {
+      buffer.writeln('//');
+    }
+    if (isLastMatchStep) {
+      // Clear errors only in the last match step. This is needed to verify
+      // problems reported outside the component in both the serialized and
+      // non-serialized step.
+      errors.clear();
+    }
     Printer printer = new Printer(buffer)
       ..writeProblemsAsJson(
           "Problems in component", componentToText.problemsAsJson);
@@ -299,6 +346,12 @@
 
 class KernelTextSerialization
     extends Step<ComponentResult, ComponentResult, ChainContext> {
+  static const bool writeRoundTripStatus = bool.fromEnvironment(
+      "text_serialization.writeRoundTripStatus",
+      defaultValue: false);
+
+  static const String suffix = ".roundtrip";
+
   const KernelTextSerialization();
 
   String get name => "kernel text serialization";
@@ -318,24 +371,23 @@
     return await CompilerContext.runWithOptions(options,
         (compilerContext) async {
       compilerContext.uriToSource.addAll(component.uriToSource);
-      TextSerializationVerifier verifier = new TextSerializationVerifier();
+      TextSerializationVerifier verifier =
+          new TextSerializationVerifier(root: component.root);
       for (Library library in component.libraries) {
         if (library.importUri.scheme != "dart" &&
             library.importUri.scheme != "package") {
-          library.accept(verifier);
+          verifier.verify(library);
         }
       }
       for (TextSerializationVerificationFailure failure in verifier.failures) {
         LocatedMessage message;
         if (failure is TextSerializationFailure) {
           message = templateUnspecified
-              .withArguments(
-                  "Failed to serialize a node: ${failure.message.isNotEmpty}")
+              .withArguments("Failed to serialize a node: ${failure.message}")
               .withLocation(failure.uri, failure.offset, 1);
         } else if (failure is TextDeserializationFailure) {
           message = templateUnspecified
-              .withArguments(
-                  "Failed to deserialize a node: ${failure.message.isNotEmpty}")
+              .withArguments("Failed to deserialize a node: ${failure.message}")
               .withLocation(failure.uri, failure.offset, 1);
         } else if (failure is TextRoundTripFailure) {
           String formattedInitial =
@@ -357,6 +409,20 @@
         options.report(message, message.code.severity);
       }
 
+      if (writeRoundTripStatus) {
+        Uri uri = component.uriToSource.keys
+            .firstWhere((uri) => uri?.scheme == "file");
+        String filename = "${uri.toFilePath()}${suffix}";
+        uri = new File(filename).uri;
+        StringBuffer buffer = new StringBuffer();
+        for (RoundTripStatus status in verifier.status) {
+          status.printOn(buffer);
+        }
+        await openWrite(uri, (IOSink sink) {
+          sink.write(buffer.toString());
+        });
+      }
+
       if (verifier.failures.isNotEmpty) {
         return new Result<ComponentResult>(
             null,
diff --git a/pkg/front_end/testcases/agnostic/identical.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline.expect
new file mode 100644
index 0000000..a880d41
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = identical(a, b);
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/identical.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a880d41
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = identical(a, b);
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/map.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/map.dart.textual_outline.expect
new file mode 100644
index 0000000..afb6162
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/map.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a: 0, b: 1};
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..afb6162
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/map.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a: 0, b: 1};
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/set.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/set.dart.textual_outline.expect
new file mode 100644
index 0000000..5de47e7
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/set.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a, b};
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5de47e7
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/set.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a, b};
+main() {}
diff --git a/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect b/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect
index 522353c..1a1c5a8 100644
--- a/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect
@@ -4,7 +4,7 @@
   return block {
     final dart.core::List<dart.core::String*>* #t1 = <dart.core::String*>[];
     {
-      dart.core::Iterator<dart.core::String*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::String*>*>(main::listOfStrings).{dart.core::Iterable::iterator};
+      dart.core::Iterator<dart.core::String*>* :sync-for-iterator = main::listOfStrings.{dart.core::Iterable::iterator};
       for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
         final dart.core::String* #t2 = :sync-for-iterator.{dart.core::Iterator::current};
         #t1.{dart.core::List::add}(#t2);
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
new file mode 100644
index 0000000..b00cda9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+extension A ;
+on C (){ }
+extension B ;
+on C (){ }
+class C {
+}
+errors(C c) { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
new file mode 100644
index 0000000..2140404
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+  @pragma('dart2js:noInline')
+  instanceMethod() { }
+  @pragma('dart2js:noInline')
+  static staticMethod() { }
+}
+extension Extension ;
+on Class (){ }
+@pragma('dart2js:noInline')
+topLevelMethod() { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
new file mode 100644
index 0000000..05b0d78
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+extension ;
+mixin on int {
+}
+extension extension ;
+on int (){ }
+extension as ;
+on int (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart b/pkg/front_end/testcases/extensions/call_methods.dart
index cf0ecfab..3ae8fe3 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart
+++ b/pkg/front_end/testcases/extensions/call_methods.dart
@@ -26,6 +26,15 @@
   ""();
 }
 
+var topLevel1 = 1(10);
+var topLevel2 = 1("10");
+var topLevel3 = 1.0(10);
+var topLevel4 = 1.0("10");
+A a = new A();
+var topLevel5 = a(2);
+B b = new B();
+var topLevel6 = a(2, "3");
+
 errors() {
   1(10);
   1("10");
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
index b57cf7b..04fd8c7 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
@@ -23,6 +23,14 @@
 extension _extension#2 on core::String* {
   get call = self::_extension#2|get#call;
 }
+static field core::String* topLevel1;
+static field core::String* topLevel2;
+static field core::String* topLevel3;
+static field core::String* topLevel4;
+static field self::A* a;
+static field core::String* topLevel5;
+static field self::B* b;
+static field core::String* topLevel6;
 static method _extension#0|get#call(final core::int* #this) → core::String*
   ;
 static method _extension#1|get#call(final core::num* #this) → core::String*
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect b/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
index e831fc5..7835653 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
@@ -2,49 +2,91 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:30:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel1 = 1(10);
+//                  ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:30:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel2 = 1("10");
+//                  ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:31:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel3 = 1.0(10);
+//                    ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:32:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel4 = 1.0("10");
+//                    ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:34:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel5 = a(2);
+//                  ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:34:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var topLevel5 = a(2);
+//                  ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:36:18: Error: Too many positional arguments: 0 allowed, but 2 found.
+// Try removing the extra positional arguments.
+// var topLevel6 = a(2, "3");
+//                  ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:36:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var topLevel6 = a(2, "3");
+//                  ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:39:4: Error: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
 //   1(10);
 //    ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:31:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:40:4: Error: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
 //   1("10");
 //    ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:32:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:41:6: Error: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
 //   1.0(10);
 //      ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:33:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:42:6: Error: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
 //   1.0("10");
 //      ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:35:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:44:4: Error: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
 //   a(2);
 //    ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:35:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+// pkg/front_end/testcases/extensions/call_methods.dart:44:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
 // Try changing 'call' to a method or explicitly invoke 'call'.
 //   a(2);
 //    ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:36:4: Error: Too many positional arguments: 0 allowed, but 2 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:45:4: Error: Too many positional arguments: 0 allowed, but 2 found.
 // Try removing the extra positional arguments.
 //   a(2, "3");
 //    ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:36:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+// pkg/front_end/testcases/extensions/call_methods.dart:45:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
 // Try changing 'call' to a method or explicitly invoke 'call'.
 //   a(2, "3");
 //    ^
 //
-// pkg/front_end/testcases/extensions/call_methods.dart:38:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
+// pkg/front_end/testcases/extensions/call_methods.dart:47:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
 // Try changing 'call' to a method or explicitly invoke 'call'.
 //   b();
@@ -76,6 +118,34 @@
 extension _extension#2 on core::String* {
   get call = self::_extension#2|get#call;
 }
+static field core::String* topLevel1 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel1 = 1(10);
+                 ^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call(10);
+static field core::String* topLevel2 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:30:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel2 = 1(\"10\");
+                 ^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call("10");
+static field core::String* topLevel3 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:31:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel3 = 1.0(10);
+                   ^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call(10);
+static field core::String* topLevel4 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:32:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel4 = 1.0(\"10\");
+                   ^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call("10");
+static field self::A* a = new self::A::•();
+static field core::String* topLevel5 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:34:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+ - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var topLevel5 = a(2);
+                 ^" as{TypeError,ForDynamic} core::String*;
+static field self::B* b = new self::B::•();
+static field core::String* topLevel6 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:36:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+ - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var topLevel6 = a(2, \"3\");
+                 ^" as{TypeError,ForDynamic} core::String*;
 static method _extension#0|get#call(final core::int* #this) → core::String*
   return "My name is int";
 static method _extension#1|get#call(final core::num* #this) → core::String*
@@ -86,35 +156,35 @@
   self::_extension#2|get#call("").call();
 }
 static method errors() → dynamic {
-  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:30:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+  let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:39:4: Error: Too many positional arguments: 0 allowed, but 1 found.
 Try removing the extra positional arguments.
   1(10);
    ^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call(10);
-  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:31:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:40:4: Error: Too many positional arguments: 0 allowed, but 1 found.
 Try removing the extra positional arguments.
   1(\"10\");
    ^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call("10");
-  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:32:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:41:6: Error: Too many positional arguments: 0 allowed, but 1 found.
 Try removing the extra positional arguments.
   1.0(10);
      ^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call(10);
-  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:33:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:42:6: Error: Too many positional arguments: 0 allowed, but 1 found.
 Try removing the extra positional arguments.
   1.0(\"10\");
      ^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call("10");
   self::A* a = new self::A::•();
-  invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:35:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+  invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:44:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
  - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
 Try changing 'call' to a method or explicitly invoke 'call'.
   a(2);
    ^";
-  invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:36:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+  invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:45:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
  - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
 Try changing 'call' to a method or explicitly invoke 'call'.
   a(2, \"3\");
    ^";
   self::B* b = new self::B::•();
-  invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:38:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
+  invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:47:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
  - 'B' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
 Try changing 'call' to a method or explicitly invoke 'call'.
   b();
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..3caae41
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class A {
+  String get call => "My name is A";
+}
+class B {
+  String Function() get call => () => "My name is B";
+}
+extension on ;
+int (){ }
+extension on ;
+num (){ }
+extension on ;
+String (){ }
+main() { }
+var topLevel1 = 1(10);
+var topLevel2 = 1("10");
+var topLevel3 = 1.0(10);
+var topLevel4 = 1.0("10");
+A a = new A();
+var topLevel5 = a(2);
+B b = new B();
+var topLevel6 = a(2, "3");
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..5d1e2be
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+part 'check_bounds_lib.dart';
+class A {
+}
+class B extends A {
+}
+class Class<T extends A> {
+}
+extension Extension<T extends B> ( ){ }
+on Class<T> (){ }
+main() { }
+test() { }
+final A a = new A();
+final Class<A> classA = new Class<A>();
+final field1 = classA.method();
+final field2 = Extension(classA).method();
+final field3 = Extension<A>(classA).method();
+final field4 = Extension<B>(classA).method();
+final field5 = Extension(classA).genericMethod(a);
+final field6 = Extension(classA).genericMethod<A>(a);
+final field7 = Extension(classA).genericMethod<B>(a);
+final field8 = Extension<A>(classA).genericMethod(a);
+final field9 = Extension<A>(classA).genericMethod<A>(a);
+final field10 = Extension<A>(classA).genericMethod<B>(a);
+final field11 = Extension<B>(classA).genericMethod(a);
+final field12 = Extension<B>(classA).genericMethod<A>(a);
+final field13 = Extension<B>(classA).genericMethod<B>(a);
+final Class<B> classB = new Class<B>();
+final field14 = classB.method();
+final field15 = Extension(classB).method();
+final field16 = Extension<A>(classB).method();
+final field17 = Extension<B>(classB).method();
+final field18 = classB.genericMethod(a);
+final field19 = classB.genericMethod<A>(a);
+final field20 = classB.genericMethod<B>(a);
+final field21 = Extension(classB).genericMethod(a);
+final field22 = Extension(classB).genericMethod<A>(a);
+final field23 = Extension(classB).genericMethod<B>(a);
+final field24 = Extension<A>(classB).genericMethod(a);
+final field25 = Extension<A>(classB).genericMethod<A>(a);
+final field26 = Extension<A>(classB).genericMethod<B>(a);
+final field27 = Extension<B>(classB).genericMethod(a);
+final field28 = Extension<B>(classB).genericMethod<A>(a);
+final field29 = Extension<B>(classB).genericMethod<B>(a);
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
new file mode 100644
index 0000000..38afdf4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+class Number {
+  final int value;
+  Number(this.value);
+  int get hashCode => value.hashCode;
+  bool operator ==(Object other) => other is Number && value == other.value;
+  String toString() => 'Number($value)';
+}
+extension NumberExtension ;
+on Number (){ }
+class Class {
+  Number field;
+  Class(this.field);
+}
+extension ClassExtension ;
+on Class (){ }
+class IntClass {
+  int field;
+  IntClass(this.field);
+}
+extension IntClassExtension ;
+on IntClass (){ }
+main() { }
+testLocals() { }
+testProperties() { }
+testIntProperties() { }
+testExplicitProperties() { }
+testExplicitIntProperties() { }
+testExplicitNullAwareProperties(Class v) { }
+testExplicitNullAwareIntProperties(IntClass v) { }
+expect(expected, actual, [expectNull = false]) { }
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
new file mode 100644
index 0000000..f358632
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+extension Extension ;
+on String (){ }
+main() { }
+errors() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
new file mode 100644
index 0000000..b98a63e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Class1 {
+}
+class Class2 {
+}
+extension DuplicateExtensionName ;
+on Class1 (){ }
+extension DuplicateExtensionName ;
+on Class2 (){ }
+extension UniqueExtensionName ;
+on Class1 (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..a5ed09e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
index 47f973b..9b085ee 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
@@ -18,8 +18,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -41,13 +41,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline.expect
new file mode 100644
index 0000000..5dedc9b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix;
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45edf2b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix;
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
index bcb6ce3..81805ba 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -32,13 +32,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline.expect
new file mode 100644
index 0000000..cd5075c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix hide Extension;
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..73bcfb8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix hide Extension;
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
new file mode 100644
index 0000000..0b176c5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+  var field;
+}
+extension Extension ;
+on Class (){ }
+class GenericClass<T> {
+  T field;
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
new file mode 100644
index 0000000..e29ee8a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+  static var field;
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
new file mode 100644
index 0000000..55962d9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+  noSuchMethod(Invocation i) => 123;
+}
+extension ClassExtension ;
+on Class (){ }
+extension Extension ;
+on dynamic (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
new file mode 100644
index 0000000..2a52c91
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Class {
+  int field1 = 42;
+  int field2 = 87;
+}
+extension Extension1 ;
+on Class (){ }
+extension Extension2 ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..2fbeb56
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+}
+class B extends A {
+}
+class C extends B {
+}
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
new file mode 100644
index 0000000..58b2995
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class<T extends num> {
+  T field1;
+  T field2;
+  Class(this.field1, this.field2);
+}
+extension Extension1<T extends num> ( ){ }
+on Class<T> (){ }
+extension Extension2<T extends num> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
new file mode 100644
index 0000000..3cf71b3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+errors(Class c) { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..7311a2f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A1 {
+  Object field;
+  void method1() { }
+}
+extension A2 ;
+on A1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline.expect
new file mode 100644
index 0000000..3e4ce72
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'export_twice_lib1.dart';
+import 'export_twice_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3e4ce72
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'export_twice_lib1.dart';
+import 'export_twice_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
new file mode 100644
index 0000000..aea56da
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class<T> {
+  T method(T a) => a;
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
new file mode 100644
index 0000000..4f88b19
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension E<U> ( ){ }
+on String (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..98012b9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'package:expect/expect.dart';
+class C {
+  int get one => 1;
+}
+extension E ;
+on C (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..8c8aedc
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+  int field;
+}
+extension Extension ;
+on Class (){ }
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
new file mode 100644
index 0000000..879feda
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+error() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..b85f14c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class<T> {
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..f9708a2
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+  int get m1 => 0;
+  void set m2(int x) { }
+}
+extension Extension0 ;
+on Class (){ }
+extension Extension1 ;
+on Class (){ }
+main() { }
+errors() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
new file mode 100644
index 0000000..1108949
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+  int field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..2fbeb56
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+}
+class B extends A {
+}
+class C extends B {
+}
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..7311a2f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A1 {
+  Object field;
+  void method1() { }
+}
+extension A2 ;
+on A1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..b1848ace
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'import_via_prefix_lib.dart' as prefix;
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72ac1a4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'import_via_prefix_lib.dart' as prefix;
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
new file mode 100644
index 0000000..e077e2c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class MapLike<K, V> {
+  final Map<K, V> _map = {};
+  V get(Object key) => _map[key];
+  V put(K key, V value) => _map[key] = value;
+}
+extension Extension<K, V> ( ){ }
+on MapLike<K, V> (){ }
+main() { }
+implicit() { }
+explicitWithTypeArguments() { }
+explicitInferredTypeArguments() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
new file mode 100644
index 0000000..06c1ade
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class1 {
+  int field;
+  Class1(this.field);
+  String toString() => 'Class1($field)';
+}
+class Class2 {
+  int field;
+  Class2(this.field);
+  String toString() => 'Class2($field)';
+}
+extension Extension1 ;
+on Class1 (){ }
+extension Extension2 ;
+on Class2 (){ }
+main() { }
+testExtension1() { }
+testExtension2() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
new file mode 100644
index 0000000..d1d5ea8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class1 {
+}
+extension Extension1 ;
+on Class1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
new file mode 100644
index 0000000..04526ab
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A1 {
+}
+extension A2 ;
+on A1 (){ }
+class B1<T> {
+}
+extension B2<T> ( ){ }
+on B1<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..06c1ade
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class1 {
+  int field;
+  Class1(this.field);
+  String toString() => 'Class1($field)';
+}
+class Class2 {
+  int field;
+  Class2(this.field);
+  String toString() => 'Class2($field)';
+}
+extension Extension1 ;
+on Class1 (){ }
+extension Extension2 ;
+on Class2 (){ }
+main() { }
+testExtension1() { }
+testExtension2() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..ae4f7ac
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+  int field;
+}
+extension on ;
+Class (){ }
+extension on ;
+Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
new file mode 100644
index 0000000..e289bf8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
new file mode 100644
index 0000000..fc40e6f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+extension Extension ;
+on String (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
new file mode 100644
index 0000000..166eb7d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+}
+extension ;
+try<T> ( ){ }
+on Class<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
new file mode 100644
index 0000000..409afa3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+extension C (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
new file mode 100644
index 0000000..8d9d55d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension C ;
+on int (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
new file mode 100644
index 0000000..71fe604
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C<T> {
+}
+extension ext<T> ( ){ }
+on C<T> (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline.expect
new file mode 100644
index 0000000..5bc7316
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'issue38750_lib1.dart';
+import 'issue38750_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cca0335
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'issue38750_lib1.dart';
+import 'issue38750_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
new file mode 100644
index 0000000..2b553f1
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+final list = ["a", "b", "c"].myMap((it) => it);
+extension A<T> ( ){ }
+on List<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
new file mode 100644
index 0000000..816061d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  int value = 0;
+}
+extension Extension1 ;
+on C (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
new file mode 100644
index 0000000..9225dc9e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C {
+}
+extension E ;
+on C (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline.expect
new file mode 100644
index 0000000..5a7bb14
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'issue39938_lib.dart';
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55e3b57
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'issue39938_lib.dart';
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
new file mode 100644
index 0000000..0060108
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+void main() { }
+extension Extension<T> ( ){ }
+on Stream<T> (){ }
diff --git a/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
new file mode 100644
index 0000000..793db07
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+extension SafeAccess<T> ( ){ }
+on Iterable<T> (){ }
+main() { }
+void test() { }
+void errors() { }
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
new file mode 100644
index 0000000..a6e9b07
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+}
+class B {
+}
+extension on ;
+A (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..8e5a18a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+var c = new Class();
+var missingGetter = c.setter += 42;
+main() { }
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
new file mode 100644
index 0000000..c3bdbbe
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<T> {
+}
+extension Extension<T> ( ){ }
+on A<A<T>> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..59bc4b7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+  int field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..12d1fac
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+extension<R, T> on ;
+R Function(T) { }
+class Class<T extends Class<T>> {
+}
+class Subclass extends Class<Subclass> {
+}
+extension<T extends Class<T>> on ;
+dynamic Function<S extends T>(T, S) { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..d115666
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+extension BestCom<T extends num> ( ){ }
+on Iterable<T> (){ }
+extension BestList<T> ( ){ }
+on List<T> (){ }
+extension BestSpec ;
+on List<num> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..bc1e66f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Struct {
+}
+class StructA extends Struct {
+}
+class StructB extends Struct {
+}
+class NonStruct {
+}
+extension Extension<T extends Struct> ( ){ }
+on T (){ }
+main() { }
+testNonStruct() { }
diff --git a/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
new file mode 100644
index 0000000..b40e2fb
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Complex {
+  final double real;
+  final double imaginary;
+  const Complex(this.real, this.imaginary);
+  Complex add(Complex other) { }
+  Complex sub(Complex other) { }
+  Complex negate() { }
+  int get hashCode => real.hashCode * 13 + imaginary.hashCode * 19;
+  bool operator ==(Object other) { }
+  String toString() => 'Complex($real,$imaginary)';
+}
+extension Operators ;
+on Complex (){ }
+main() { }
+implicit() { }
+explicit() { }
+void errors(Complex c) { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
new file mode 100644
index 0000000..7fd35bd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A1 {
+  int _instanceField;
+  int getInstanceField() => _instanceField;
+  void setInstanceField(int value) { }
+  static int _staticField = 0;
+  static int getStaticField() => _staticField;
+  static void setStaticField(int value) { }
+}
+extension A2 ;
+on A1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline.expect
new file mode 100644
index 0000000..ca40cab
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'private_members_lib.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dfeb024
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'private_members_lib.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
new file mode 100644
index 0000000..c80f35f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..dd1a367
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A1<T> {
+}
+extension A2<T> ( ){ }
+on A1<T> (){ }
+extension A3<T extends A1<T>> ( ){ }
+on A1<T> (){ }
+extension A4<T> ( ){ }
+on A1<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
new file mode 100644
index 0000000..7a779e4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class1 {
+  int field;
+  Class1(this.field);
+  String toString() => 'Class1($field)';
+}
+class Class2 {
+  int field;
+  Class2(this.field);
+  String toString() => 'Class2($field)';
+}
+extension on ;
+Class1 (){ }
+extension on ;
+Class2 (){ }
+main() { }
+testExtension1() { }
+testExtension2() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
new file mode 100644
index 0000000..04526ab
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A1 {
+}
+extension A2 ;
+on A1 (){ }
+class B1<T> {
+}
+extension B2<T> ( ){ }
+on B1<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline.expect b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline.expect
new file mode 100644
index 0000000..b0e9877
--- /dev/null
+++ b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline.expect
@@ -0,0 +1,153 @@
+main() {}
+
+class DeltaBlue {
+  void run() {}
+}
+
+class Strength {
+  final int value;
+  final String name;
+  const Strength(this.value, this.name);
+  Strength nextWeaker() => const <Strength>[
+        STRONG_PREFERRED,
+        PREFERRED,
+        STRONG_DEFAULT,
+        NORMAL,
+        WEAK_DEFAULT,
+        WEAKEST
+      ][value];
+  static bool stronger(Strength s1, Strength s2) {}
+  static bool weaker(Strength s1, Strength s2) {}
+  static Strength weakest(Strength s1, Strength s2) {}
+  static Strength strongest(Strength s1, Strength s2) {}
+}
+
+const REQUIRED = const Strength(0, "required");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const PREFERRED = const Strength(2, "preferred");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const NORMAL = const Strength(4, "normal");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const WEAKEST = const Strength(6, "weakest");
+
+abstract class Constraint {
+  final Strength strength;
+  const Constraint(this.strength);
+  bool isSatisfied();
+  void markUnsatisfied();
+  void addToGraph();
+  void removeFromGraph();
+  void chooseMethod(int mark);
+  void markInputs(int mark);
+  bool inputsKnown(int mark);
+  Variable output();
+  void execute();
+  void recalculate();
+  void addConstraint() {}
+  Constraint satisfy(mark) {}
+  void destroyConstraint() {}
+  bool isInput() => false;
+}
+
+abstract class UnaryConstraint extends Constraint {
+  final Variable myOutput;
+  bool satisfied = false;
+  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+  void addToGraph() {}
+  void chooseMethod(int mark) {}
+  bool isSatisfied() => satisfied;
+  void markInputs(int mark) {}
+  Variable output() => myOutput;
+  void recalculate() {}
+  void markUnsatisfied() {}
+  bool inputsKnown(int mark) => true;
+  void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+  StayConstraint(Variable v, Strength str) : super(v, str);
+  void execute() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+  EditConstraint(Variable v, Strength str) : super(v, str);
+  bool isInput() => true;
+  void execute() {}
+}
+
+const int NONE = 1;
+const int FORWARD = 2;
+const int BACKWARD = 0;
+
+abstract class BinaryConstraint extends Constraint {
+  Variable v1;
+  Variable v2;
+  int direction = NONE;
+  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+  void chooseMethod(int mark) {}
+  void addToGraph() {}
+  bool isSatisfied() => direction != NONE;
+  void markInputs(int mark) {}
+  Variable input() => direction == FORWARD ? v1 : v2;
+  Variable output() => direction == FORWARD ? v2 : v1;
+  void recalculate() {}
+  void markUnsatisfied() {}
+  bool inputsKnown(int mark) {}
+  void removeFromGraph() {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+  final Variable scale;
+  final Variable offset;
+  ScaleConstraint(
+      Variable src, this.scale, this.offset, Variable dest, Strength strength)
+      : super(src, dest, strength);
+  void addToGraph() {}
+  void removeFromGraph() {}
+  void markInputs(int mark) {}
+  void execute() {}
+  void recalculate() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+  EqualityConstraint(Variable v1, Variable v2, Strength strength)
+      : super(v1, v2, strength);
+  void execute() {}
+}
+
+class Variable {
+  List<Constraint> constraints = <Constraint>[];
+  Constraint determinedBy;
+  int mark = 0;
+  Strength walkStrength = WEAKEST;
+  bool stay = true;
+  int value;
+  final String name;
+  Variable(this.name, this.value);
+  void addConstraint(Constraint c) {}
+  void removeConstraint(Constraint c) {}
+}
+
+class Planner {
+  int currentMark = 0;
+  void incrementalAdd(Constraint c) {}
+  void incrementalRemove(Constraint c) {}
+  int newMark() => ++currentMark;
+  Plan makePlan(List<Constraint> sources) {}
+  Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+  bool addPropagate(Constraint c, int mark) {}
+  List<Constraint> removePropagateFrom(Variable out) {}
+  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+}
+
+class Plan {
+  List<Constraint> list = <Constraint>[];
+  void addConstraint(Constraint c) {}
+  int size() => list.length;
+  void execute() {}
+}
+
+void chainTest(int n) {}
+void projectionTest(int n) {}
+void change(Variable v, int newValue) {}
+Planner planner;
diff --git a/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43daecc
--- /dev/null
+++ b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline_modelled.expect
@@ -0,0 +1,151 @@
+Planner planner;
+
+abstract class BinaryConstraint extends Constraint {
+  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+  Variable input() => direction == FORWARD ? v1 : v2;
+  Variable output() => direction == FORWARD ? v2 : v1;
+  Variable v1;
+  Variable v2;
+  bool inputsKnown(int mark) {}
+  bool isSatisfied() => direction != NONE;
+  int direction = NONE;
+  void addToGraph() {}
+  void chooseMethod(int mark) {}
+  void markInputs(int mark) {}
+  void markUnsatisfied() {}
+  void recalculate() {}
+  void removeFromGraph() {}
+}
+
+abstract class Constraint {
+  Constraint satisfy(mark) {}
+  Variable output();
+  bool inputsKnown(int mark);
+  bool isInput() => false;
+  bool isSatisfied();
+  const Constraint(this.strength);
+  final Strength strength;
+  void addConstraint() {}
+  void addToGraph();
+  void chooseMethod(int mark);
+  void destroyConstraint() {}
+  void execute();
+  void markInputs(int mark);
+  void markUnsatisfied();
+  void recalculate();
+  void removeFromGraph();
+}
+
+abstract class UnaryConstraint extends Constraint {
+  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+  Variable output() => myOutput;
+  bool inputsKnown(int mark) => true;
+  bool isSatisfied() => satisfied;
+  bool satisfied = false;
+  final Variable myOutput;
+  void addToGraph() {}
+  void chooseMethod(int mark) {}
+  void markInputs(int mark) {}
+  void markUnsatisfied() {}
+  void recalculate() {}
+  void removeFromGraph() {}
+}
+
+class DeltaBlue {
+  void run() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+  EditConstraint(Variable v, Strength str) : super(v, str);
+  bool isInput() => true;
+  void execute() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+  EqualityConstraint(Variable v1, Variable v2, Strength strength)
+      : super(v1, v2, strength);
+  void execute() {}
+}
+
+class Plan {
+  List<Constraint> list = <Constraint>[];
+  int size() => list.length;
+  void addConstraint(Constraint c) {}
+  void execute() {}
+}
+
+class Planner {
+  List<Constraint> removePropagateFrom(Variable out) {}
+  Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+  Plan makePlan(List<Constraint> sources) {}
+  bool addPropagate(Constraint c, int mark) {}
+  int currentMark = 0;
+  int newMark() => ++currentMark;
+  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+  void incrementalAdd(Constraint c) {}
+  void incrementalRemove(Constraint c) {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+  ScaleConstraint(
+      Variable src, this.scale, this.offset, Variable dest, Strength strength)
+      : super(src, dest, strength);
+  final Variable offset;
+  final Variable scale;
+  void addToGraph() {}
+  void execute() {}
+  void markInputs(int mark) {}
+  void recalculate() {}
+  void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+  StayConstraint(Variable v, Strength str) : super(v, str);
+  void execute() {}
+}
+
+class Strength {
+  Strength nextWeaker() => const <Strength>[
+        STRONG_PREFERRED,
+        PREFERRED,
+        STRONG_DEFAULT,
+        NORMAL,
+        WEAK_DEFAULT,
+        WEAKEST
+      ][value];
+  const Strength(this.value, this.name);
+  final String name;
+  final int value;
+  static Strength strongest(Strength s1, Strength s2) {}
+  static Strength weakest(Strength s1, Strength s2) {}
+  static bool stronger(Strength s1, Strength s2) {}
+  static bool weaker(Strength s1, Strength s2) {}
+}
+
+class Variable {
+  Constraint determinedBy;
+  List<Constraint> constraints = <Constraint>[];
+  Strength walkStrength = WEAKEST;
+  Variable(this.name, this.value);
+  bool stay = true;
+  final String name;
+  int mark = 0;
+  int value;
+  void addConstraint(Constraint c) {}
+  void removeConstraint(Constraint c) {}
+}
+
+const NORMAL = const Strength(4, "normal");
+const PREFERRED = const Strength(2, "preferred");
+const REQUIRED = const Strength(0, "required");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const WEAKEST = const Strength(6, "weakest");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const int BACKWARD = 0;
+const int FORWARD = 2;
+const int NONE = 1;
+main() {}
+void chainTest(int n) {}
+void change(Variable v, int newValue) {}
+void projectionTest(int n) {}
diff --git a/pkg/front_end/testcases/general/abstract_members.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline.expect
new file mode 100644
index 0000000..866053c
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline.expect
@@ -0,0 +1,80 @@
+class Interface1 {
+  void interfaceMethod1() {}
+}
+
+class Interface2 {
+  void interfaceMethod2() {}
+  var interfaceMethod1;
+}
+
+class Interface3 {
+  void interfaceMethod3() {}
+}
+
+abstract class A implements Interface1, Interface2, Interface3 {
+  aMethod() {}
+  abstractMethod();
+  void set property1(_);
+  void set property2(_);
+  void set property3(_);
+}
+
+abstract class B extends A {
+  final property1 = null;
+  aMethod() {}
+  bMethod() {}
+}
+
+class MyClass extends B {
+  var property2;
+  aaMethod() {}
+  aMethod() {}
+  bMethod() {}
+  cMethod() {}
+}
+
+class MyMock1 extends B {
+  noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+  noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+  noSuchMethod(_);
+}
+
+class C {
+  void interfaceMethod1(_) {}
+}
+
+abstract class D extends C implements Interface2 {}
+
+class E {
+  void set interfaceMethod1(_) {}
+}
+
+abstract class F extends E implements Interface1 {}
+
+class Foo {
+  void foo() {}
+}
+
+class G {
+  Object get foo => null;
+}
+
+abstract class H extends G implements Foo {}
+
+class Bar {
+  Object get foo => null;
+}
+
+class I {
+  Object foo() {}
+}
+
+abstract class J extends I implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/abstract_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77e8755
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,80 @@
+abstract class A implements Interface1, Interface2, Interface3 {
+  aMethod() {}
+  abstractMethod();
+  void set property1(_);
+  void set property2(_);
+  void set property3(_);
+}
+
+abstract class B extends A {
+  aMethod() {}
+  bMethod() {}
+  final property1 = null;
+}
+
+abstract class D extends C implements Interface2 {}
+
+abstract class F extends E implements Interface1 {}
+
+abstract class H extends G implements Foo {}
+
+abstract class J extends I implements Bar {}
+
+class Bar {
+  Object get foo => null;
+}
+
+class C {
+  void interfaceMethod1(_) {}
+}
+
+class E {
+  void set interfaceMethod1(_) {}
+}
+
+class Foo {
+  void foo() {}
+}
+
+class G {
+  Object get foo => null;
+}
+
+class I {
+  Object foo() {}
+}
+
+class Interface1 {
+  void interfaceMethod1() {}
+}
+
+class Interface2 {
+  var interfaceMethod1;
+  void interfaceMethod2() {}
+}
+
+class Interface3 {
+  void interfaceMethod3() {}
+}
+
+class MyClass extends B {
+  aMethod() {}
+  aaMethod() {}
+  bMethod() {}
+  cMethod() {}
+  var property2;
+}
+
+class MyMock1 extends B {
+  noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+  noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+  noSuchMethod(_);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
new file mode 100644
index 0000000..a22c063
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+abstract class A {
+  A foo() => null;
+}
+
+abstract class B extends A {
+  B foo();
+}
+
+class C {
+  noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a22c063
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class A {
+  A foo() => null;
+}
+
+abstract class B extends A {
+  B foo();
+}
+
+class C {
+  noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general/accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..9c4a898
--- /dev/null
+++ b/pkg/front_end/testcases/general/accessors.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+void set onlySetter(value) {}
+
+class C {
+  void set onlySetter(value) {}
+  testC() {}
+  testD() {}
+}
+
+class D extends C {
+  String get onlySetter => "D.onlySetter called.";
+  void set onlySetter(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3072e99
--- /dev/null
+++ b/pkg/front_end/testcases/general/accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class C {
+  testC() {}
+  testD() {}
+  void set onlySetter(value) {}
+}
+
+class D extends C {
+  String get onlySetter => "D.onlySetter called.";
+  void set onlySetter(value) {}
+}
+
+main() {}
+void set onlySetter(value) {}
diff --git a/pkg/front_end/testcases/general/all_variances.dart.textual_outline.expect b/pkg/front_end/testcases/general/all_variances.dart.textual_outline.expect
new file mode 100644
index 0000000..e174256
--- /dev/null
+++ b/pkg/front_end/testcases/general/all_variances.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
+main() {}
diff --git a/pkg/front_end/testcases/general/all_variances.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/all_variances.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..487ff53
--- /dev/null
+++ b/pkg/front_end/testcases/general/all_variances.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
diff --git a/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline.expect b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline.expect
new file mode 100644
index 0000000..7fe554b
--- /dev/null
+++ b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7fe554b
--- /dev/null
+++ b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general/annotation_eof.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_eof.dart.textual_outline.expect
new file mode 100644
index 0000000..4f0c503
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_eof.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() { }
+@AnnotationAtEOF
diff --git a/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline.expect
new file mode 100644
index 0000000..42c4aa9
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+const int hest = 42;
+
+class Fisk<T> {
+  final T x;
+  const Fisk.fisk(this.x);
+}
+
+enum Foo {
+  @hest
+  bar,
+  @Fisk.fisk(hest)
+  baz,
+  cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1866609
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Fisk<T> {
+  const Fisk.fisk(this.x);
+  final T x;
+}
+
+const int hest = 42;
+enum Foo {
+  @hest
+  bar,
+  @Fisk.fisk(hest)
+  baz,
+  cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_top.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline.expect
new file mode 100644
index 0000000..579bc70
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+@a
+@A(1)
+library test;
+
+const Object a = const Object();
+
+class A {
+  const A(int value);
+}
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(4)
+void main() {}
diff --git a/pkg/front_end/testcases/general/annotation_top.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faefe48
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+@a
+@A(1)
+library test;
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(4)
+void main() {}
+
+class A {
+  const A(int value);
+}
+
+const Object a = const Object();
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline.expect
new file mode 100644
index 0000000..15fb5d5
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+const int foo = 21;
+const int bar = 42;
+const int baz = 84;
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b301156
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+const int bar = 42;
+const int baz = 84;
+const int foo = 21;
+main() {}
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..31a5a66
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+const int app = 0;
+typedef int F(@app int app);
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e353a08
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+const int app = 0;
+main() {}
+typedef int F(@app int app);
diff --git a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..52559a9
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+const int foo = 42;
+
+class Bar {
+  const Bar();
+  const Bar.named(x);
+}
+
+class Baz {
+  Baz(@foo constructorFormal);
+  factory Baz.bazFactory(@foo factoryFormal) => null;
+  fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+      @foo @Bar.named(foo) formal4,
+      [@foo optional]) {}
+  hest({@foo named}) => null;
+}
+
+typedef hest_t({@foo named});
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a18629
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Bar {
+  const Bar();
+  const Bar.named(x);
+}
+
+class Baz {
+  Baz(@foo constructorFormal);
+  factory Baz.bazFactory(@foo factoryFormal) => null;
+  fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+      @foo @Bar.named(foo) formal4,
+      [@foo optional]) {}
+  hest({@foo named}) => null;
+}
+
+const int foo = 42;
+main() {}
+typedef hest_t({@foo named});
diff --git a/pkg/front_end/testcases/general/argument.dart.textual_outline.expect b/pkg/front_end/testcases/general/argument.dart.textual_outline.expect
new file mode 100644
index 0000000..09a1fdd
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+abstract class Base {}
+
+class Foo extends Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+void foo(x) {}
+void bar(x) {}
+void foo_escaped(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3150668
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+abstract class Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+class Foo extends Base {}
+
+main() {}
+void bar(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+void foo(x) {}
+void foo_escaped(x) {}
diff --git a/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..3b58842
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo() {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1391a6a
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+foo() {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/arithmetic.dart.textual_outline.expect b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline.expect
new file mode 100644
index 0000000..5c6fdec
--- /dev/null
+++ b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+int foo(int x, int y) {}
+void loop(List xs) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/arithmetic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2e4a11
--- /dev/null
+++ b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+int foo(int x, int y) {}
+main() {}
+void loop(List xs) {}
diff --git a/pkg/front_end/testcases/general/arrow_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline.expect
new file mode 100644
index 0000000..b66ca49
--- /dev/null
+++ b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline.expect
@@ -0,0 +1 @@
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general/arrow_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66ca49
--- /dev/null
+++ b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline.expect b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline.expect
new file mode 100644
index 0000000..0ee755e
--- /dev/null
+++ b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class A {
+  var x, y;
+  A(this.x)
+      : y = (() {
+          x = 3;
+        });
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d7dc12
--- /dev/null
+++ b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class A {
+  A(this.x)
+      : y = (() {
+          x = 3;
+        });
+  var x, y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
index a4a39f8..c86613d 100644
--- a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -25,21 +25,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method asyncString2() → asy::Future<core::String*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -52,13 +52,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
@@ -101,8 +101,8 @@
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -128,7 +128,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -145,8 +145,8 @@
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -163,7 +163,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -180,8 +180,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -195,12 +195,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general/async_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/async_function.dart.textual_outline.expect
new file mode 100644
index 0000000..20ff937
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_function.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+List<String> stringList = ["bar"];
+main() async {}
diff --git a/pkg/front_end/testcases/general/async_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/async_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2451edd
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+List<String> stringList = ["bar"];
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+main() async {}
diff --git a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
index 2d6ae21..bdf5176 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
@@ -22,8 +22,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -56,13 +56,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 
diff --git a/pkg/front_end/testcases/general/async_nested.dart.textual_outline.expect b/pkg/front_end/testcases/general/async_nested.dart.textual_outline.expect
new file mode 100644
index 0000000..01c5288
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_nested.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import 'dart:async';
+
+void main() async {}
+
+class Node {
+  final List<Node> nested;
+  final String name;
+  Node(this.name, [this.nested]) {}
+  String toString() => '<$name:[${nested?.join(', ')}]>';
+  toSimpleString() {}
+}
diff --git a/pkg/front_end/testcases/general/async_nested.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/async_nested.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8be533c
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_nested.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'dart:async';
+
+class Node {
+  Node(this.name, [this.nested]) {}
+  String toString() => '<$name:[${nested?.join(', ')}]>';
+  final List<Node> nested;
+  final String name;
+  toSimpleString() {}
+}
+
+void main() async {}
diff --git a/pkg/front_end/testcases/general/await.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
index a4fa440..8c66908 100644
--- a/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
@@ -8,8 +8,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -23,12 +23,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general/await.dart.textual_outline.expect b/pkg/front_end/testcases/general/await.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/await.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/await.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
index 8a2da7f..dfafacd 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
@@ -50,8 +50,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -93,21 +93,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method topLevelMembers() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -144,21 +144,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method instanceMembers() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -196,21 +196,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method others() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -248,21 +248,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method conditionals() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -320,21 +320,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method asserts() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -344,7 +344,7 @@
       #L6:
       {
         {
-          core::Iterator<core::Function*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Function*>*>(<core::Function*>[#C1, #C2]).{core::Iterable::iterator};
+          core::Iterator<core::Function*>* :sync-for-iterator = <core::Function*>[#C1, #C2].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Function* #t26 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -393,21 +393,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method controlFlow() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -423,7 +423,7 @@
       #L7:
       {
         {
-          core::Iterator<core::Function*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Function*>*>(<core::Function*>[#C1, #C2]).{core::Iterable::iterator};
+          core::Iterator<core::Function*>* :sync-for-iterator = <core::Function*>[#C1, #C2].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Function* #t33 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -539,8 +539,8 @@
                 final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
                 asy::FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -555,13 +555,13 @@
                     asy::_completeOnAsyncReturn(:async_completer, :return_value);
                     return;
                   }
-                  on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                  on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                     :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.start(:async_op);
+                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
                 return :async_completer.{asy::Completer::future};
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
@@ -569,8 +569,8 @@
                 final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
                 asy::FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -583,13 +583,13 @@
                     asy::_completeOnAsyncReturn(:async_completer, :return_value);
                     return;
                   }
-                  on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                  on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                     :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.start(:async_op);
+                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
                 return :async_completer.{asy::Completer::future};
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
@@ -597,8 +597,8 @@
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -616,7 +616,7 @@
                       }
                       return;
                     }
-                    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                       :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
                     }
                   finally {
@@ -636,8 +636,8 @@
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -655,7 +655,7 @@
                       }
                       return;
                     }
-                    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                       :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
                     }
                   finally {
@@ -678,21 +678,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method future<T extends core::Object* = dynamic>(self::future::T* value) → asy::FutureOr<self::future::T*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<self::future::T*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::future::T*>();
   asy::FutureOr<self::future::T*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -705,13 +705,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method id<T extends core::Object* = dynamic>(self::id::T* value) → asy::FutureOr<self::id::T*>*
@@ -720,8 +720,8 @@
   asy::_AsyncStarStreamController<core::int*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -738,7 +738,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -755,8 +755,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -784,13 +784,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general/await_complex.dart.textual_outline.expect b/pkg/front_end/testcases/general/await_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..16785e4
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_complex.dart.textual_outline.expect
@@ -0,0 +1,40 @@
+import 'dart:async';
+
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+int get topLevelGetter => globalVariable;
+void set topLevelSetter(val) {}
+
+class C {
+  static int staticField = 1;
+  static int get staticGetter => staticField;
+  static void set staticSetter(val) {}
+  static int staticFoo(int param) => param;
+  int field = 1;
+  int get getter => field;
+  void set setter(val) {}
+  int foo(int param) => param;
+}
+
+dummy() => 1;
+staticMembers() async {}
+topLevelMembers() async {}
+instanceMembers() async {}
+others() async {}
+conditionals() async {}
+asserts() async {}
+controlFlow() async {}
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+final bool assertStatementsEnabled = () {
+  try {
+    assert(false);
+    return false;
+  } catch (_) {
+    return true;
+  }
+}();
+main() async {}
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
diff --git a/pkg/front_end/testcases/general/await_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ddaab5f
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,40 @@
+import 'dart:async';
+
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+asserts() async {}
+
+class C {
+  int field = 1;
+  int foo(int param) => param;
+  int get getter => field;
+  static int get staticGetter => staticField;
+  static int staticField = 1;
+  static int staticFoo(int param) => param;
+  static void set staticSetter(val) {}
+  void set setter(val) {}
+}
+
+conditionals() async {}
+controlFlow() async {}
+dummy() => 1;
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
+final bool assertStatementsEnabled = () {
+  try {
+    assert(false);
+    return false;
+  } catch (_) {
+    return true;
+  }
+}();
+instanceMembers() async {}
+int get topLevelGetter => globalVariable;
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+main() async {}
+others() async {}
+staticMembers() async {}
+topLevelMembers() async {}
+void set topLevelSetter(val) {}
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
index be2d683..72c6420 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
@@ -14,8 +14,8 @@
     final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
     asy::FutureOr<core::List<core::int*>*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -31,21 +31,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   method _m() → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -58,13 +58,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -72,8 +72,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -87,13 +87,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..543028a
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:async';
+
+class C {
+  Future<List<int>> m() async => []..add(await _m());
+  Future<int> _m() async => 42;
+}
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..305a56e
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'dart:async';
+
+class C {
+  Future<List<int>> m() async => []..add(await _m());
+  Future<int> _m() async => 42;
+}
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline.expect b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline.expect
new file mode 100644
index 0000000..afc9a41
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+foo() {}
diff --git a/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d530fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bad_setter_abstract.dart.textual_outline.expect b/pkg/front_end/testcases/general/bad_setter_abstract.dart.textual_outline.expect
new file mode 100644
index 0000000..dbf31c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_setter_abstract.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+set b();
+set c(x, y);
+class A {
+  set a();
+  set d(x, y);
+}
+abstract class B {
+  set a();
+  set d(x, y);
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/bad_store.dart.textual_outline.expect b/pkg/front_end/testcases/general/bad_store.dart.textual_outline.expect
new file mode 100644
index 0000000..1749c06
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_store.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo {
+  var field;
+}
+
+dynamic identity(x) => x;
+void use(x) {}
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/bad_store.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bad_store.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1745116
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_store.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo {
+  var field;
+}
+
+dynamic identity(x) => x;
+main(List<String> args) {}
+void use(x) {}
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..c9ae869
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
@@ -0,0 +1,78 @@
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+
+class Empty {}
+
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jccc<T>
+    extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2ebaf0c
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,77 @@
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class Empty {}
+
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Jccc<T>
+    extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..1b987ae
--- /dev/null
+++ b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A<X> {
+  bar<Y extends X>() => null;
+}
+
+class B {
+  static A<Y> foo<Y extends Object>() => null;
+}
+
+baz() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..da490d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+baz() {}
+
+class A<X> {
+  bar<Y extends X>() => null;
+}
+
+class B {
+  static A<Y> foo<Y extends Object>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug21938.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug21938.dart.textual_outline.expect
new file mode 100644
index 0000000..ec6b9e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug21938.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug21938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug21938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f67dbb0
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug21938.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/bug30695.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug30695.dart.textual_outline.expect
new file mode 100644
index 0000000..8f35078
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug30695.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  var foo = 42;
+}
+
+class B extends A {
+  foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug30695.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug30695.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f35078
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug30695.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  var foo = 42;
+}
+
+class B extends A {
+  foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug31124.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug31124.dart.textual_outline.expect
new file mode 100644
index 0000000..331dc8b
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug31124.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+var a = () => 'b';
+a();
diff --git a/pkg/front_end/testcases/general/bug32414a.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline.expect
new file mode 100644
index 0000000..41786bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/bug32414a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e0980f
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/bug32414b.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline.expect
new file mode 100644
index 0000000..41786bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/bug32414b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e0980f
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/bug32426.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32426.dart.textual_outline.expect
new file mode 100644
index 0000000..9a90eda
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32426.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class I {
+  void call();
+}
+
+class C implements I {
+  void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug32426.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32426.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a90eda
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32426.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class I {
+  void call();
+}
+
+class C implements I {
+  void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug32629.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32629.dart.textual_outline.expect
new file mode 100644
index 0000000..79a8b78
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32629.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  dynamic call(dynamic a, dynamic b) {}
+}
+
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug32629.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32629.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..499e1c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32629.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+  dynamic call(dynamic a, dynamic b) {}
+}
+
+main() {}
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/bug32866.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32866.dart.textual_outline.expect
new file mode 100644
index 0000000..8207658
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32866.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class B {
+  String get f;
+}
+
+class A implements B {
+  final f;
+  A(this.f);
+}
+
+var a = new A("foo");
+main() => print(a);
diff --git a/pkg/front_end/testcases/general/bug32866.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32866.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9acbfae
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32866.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class B {
+  String get f;
+}
+
+class A implements B {
+  A(this.f);
+  final f;
+}
+
+main() => print(a);
+var a = new A("foo");
diff --git a/pkg/front_end/testcases/general/bug33099.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33099.dart.textual_outline.expect
new file mode 100644
index 0000000..dfdc73b
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33099.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+import 'dart:mirrors';
+
+const _FailingTest failingTest = const _FailingTest();
+
+class _FailingTest {
+  const _FailingTest();
+}
+
+class MyTest {
+  @failingTest
+  void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+main() {}
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+    declaration.metadata.any((InstanceMirror annotation) {
+      print('annotation: ${annotation.reflectee}');
+      return identical(annotation.reflectee, instance);
+    });
diff --git a/pkg/front_end/testcases/general/bug33099.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33099.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4aa3b4d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33099.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+import 'dart:mirrors';
+
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+    declaration.metadata.any((InstanceMirror annotation) {
+      print('annotation: ${annotation.reflectee}');
+      return identical(annotation.reflectee, instance);
+    });
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+
+class MyTest {
+  @failingTest
+  void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+class _FailingTest {
+  const _FailingTest();
+}
+
+const _FailingTest failingTest = const _FailingTest();
+main() {}
diff --git a/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
index ca4c8a8..895484d 100644
--- a/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
@@ -13,8 +13,8 @@
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -27,12 +27,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general/bug33196.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33196.dart.textual_outline.expect
new file mode 100644
index 0000000..527244a
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33196.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+
+main() {}
+FutureOr<String> returnsString() async {}
diff --git a/pkg/front_end/testcases/general/bug33196.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33196.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66d5579
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33196.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+
+FutureOr<String> returnsString() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
index 052b974..fa92a38 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
@@ -25,8 +25,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::Object*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::Object*>*>();
   asy::FutureOr<core::List<core::Object*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -39,13 +39,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method f2() → core::List<core::Object*>*
@@ -54,8 +54,8 @@
   final asy::_AsyncAwaitCompleter<core::Object*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object*>();
   asy::FutureOr<core::Object*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,21 +68,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method foo() → asy::Future<self::X*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<self::X*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::X*>();
   asy::FutureOr<self::X*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -101,21 +101,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → asy::Future<void>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
   asy::FutureOr<void>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -129,12 +129,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general/bug33206.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33206.dart.textual_outline.expect
new file mode 100644
index 0000000..1d7feb68
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33206.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+
+class X {
+  final x;
+  final y;
+  X(this.x, this.y);
+  toString() => "X($x, $y)";
+}
+
+class Y {
+  f(_) {}
+}
+
+Future<List<Object>> f1() async {}
+List<Object> f2() => [2];
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
diff --git a/pkg/front_end/testcases/general/bug33206.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33206.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d229418
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33206.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+
+Future<List<Object>> f1() async {}
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
+List<Object> f2() => [2];
+
+class X {
+  X(this.x, this.y);
+  final x;
+  final y;
+  toString() => "X($x, $y)";
+}
+
+class Y {
+  f(_) {}
+}
diff --git a/pkg/front_end/testcases/general/bug33298.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33298.dart.textual_outline.expect
new file mode 100644
index 0000000..e2157d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33298.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {
+  String call(String s) => '$s$s';
+}
+
+class B<T> {
+  T call(T t) => t;
+}
+
+class C {
+  T call<T>(T t) => t;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug33298.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33298.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1bf1c4a
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33298.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {
+  String call(String s) => '$s$s';
+}
+
+class B<T> {
+  T call(T t) => t;
+}
+
+class C {
+  T call<T>(T t) => t;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/bug34511.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug34511.dart.textual_outline.expect
new file mode 100644
index 0000000..d85c73d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug34511.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug34511.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug34511.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d85c73d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug34511.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug35470.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug35470.dart.textual_outline.expect
new file mode 100644
index 0000000..880e7ff
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug35470.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<X> {
+  foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+bar(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug35470.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug35470.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ee614fb
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug35470.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+bar(B b) {}
+
+class A<X> {
+  foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug37476.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug37476.dart.textual_outline.expect
new file mode 100644
index 0000000..5f90d7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug37476.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A<T extends num> {
+  void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+  void Function(T x) foo() {}
+}
+
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+main() {}
diff --git a/pkg/front_end/testcases/general/bug37476.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug37476.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cbb59f
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug37476.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+
+class A<T extends num> {
+  void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+  void Function(T x) foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/call.dart b/pkg/front_end/testcases/general/call.dart
index 1543991..4152cd8 100644
--- a/pkg/front_end/testcases/general/call.dart
+++ b/pkg/front_end/testcases/general/call.dart
@@ -46,3 +46,36 @@
   var nothing11 = callableGetter.call.call();
   var nothing12 = callableGetter.call.call.call();
 }
+
+var closure = (x) => x;
+var int1 = closure(1);
+var int2 = closure.call(1);
+var int3 = closure.call.call(1);
+var int4 = closure.call.call.call(1);
+
+var callable = new Callable();
+var string1 = callable(1);
+var string2 = callable.call(1);
+var string3 = callable.call.call(1);
+var string4 = callable.call.call.call(1);
+
+var callableGetter = new CallableGetter();
+var string5 = callableGetter(1);
+var string6 = callableGetter.call(1);
+var string7 = callableGetter.call.call(1);
+var string8 = callableGetter.call.call.call(1);
+
+var nothing1 = closure();
+var nothing2 = closure.call();
+var nothing3 = closure.call.call();
+var nothing4 = closure.call.call.call();
+
+var nothing5 = callable();
+var nothing6 = callable.call();
+var nothing7 = callable.call.call();
+var nothing8 = callable.call.call.call();
+
+var nothing9 = callableGetter();
+var nothing10 = callableGetter.call();
+var nothing11 = callableGetter.call.call();
+var nothing12 = callableGetter.call.call.call();
diff --git a/pkg/front_end/testcases/general/call.dart.outline.expect b/pkg/front_end/testcases/general/call.dart.outline.expect
index 5aba50d..93fbf2a 100644
--- a/pkg/front_end/testcases/general/call.dart.outline.expect
+++ b/pkg/front_end/testcases/general/call.dart.outline.expect
@@ -14,5 +14,32 @@
   get call() → dynamic
     ;
 }
+static field (dynamic) →* dynamic closure;
+static field dynamic int1;
+static field dynamic int2;
+static field dynamic int3;
+static field dynamic int4;
+static field self::Callable* callable;
+static field dynamic string1;
+static field dynamic string2;
+static field dynamic string3;
+static field dynamic string4;
+static field self::CallableGetter* callableGetter;
+static field dynamic string5;
+static field dynamic string6;
+static field dynamic string7;
+static field dynamic string8;
+static field dynamic nothing1;
+static field dynamic nothing2;
+static field dynamic nothing3;
+static field dynamic nothing4;
+static field dynamic nothing5;
+static field dynamic nothing6;
+static field dynamic nothing7;
+static field dynamic nothing8;
+static field dynamic nothing9;
+static field dynamic nothing10;
+static field dynamic nothing11;
+static field dynamic nothing12;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/general/call.dart.strong.expect b/pkg/front_end/testcases/general/call.dart.strong.expect
index 9efa544..9bbc04c 100644
--- a/pkg/front_end/testcases/general/call.dart.strong.expect
+++ b/pkg/front_end/testcases/general/call.dart.strong.expect
@@ -46,6 +46,50 @@
 //   var nothing9 = callableGetter();
 //                                ^
 //
+// pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+//  - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var string5 = callableGetter(1);
+//                             ^
+//
+// pkg/front_end/testcases/general/call.dart:68:23: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing1 = closure();
+//                       ^
+//
+// pkg/front_end/testcases/general/call.dart:69:28: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing2 = closure.call();
+//                            ^
+//
+// pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing3 = closure.call.call();
+//                                 ^
+//
+// pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing4 = closure.call.call.call();
+//                                      ^
+//
+// pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing5 = callable();
+//                        ^
+//
+// pkg/front_end/testcases/general/call.dart:74:29: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing6 = callable.call();
+//                             ^
+//
+// pkg/front_end/testcases/general/call.dart:75:34: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing7 = callable.call.call();
+//                                  ^
+//
+// pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing8 = callable.call.call.call();
+//                                       ^
+//
+// pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+//  - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var nothing9 = callableGetter();
+//                              ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -64,6 +108,57 @@
   get call() → dynamic
     return new self::Callable::•();
 }
+static field (dynamic) →* dynamic closure = (dynamic x) → dynamic => x;
+static field dynamic int1 = self::closure.call(1);
+static field dynamic int2 = self::closure.call(1);
+static field dynamic int3 = self::closure.call.call(1);
+static field dynamic int4 = self::closure.call.call.call(1);
+static field self::Callable* callable = new self::Callable::•();
+static field dynamic string1 = self::callable.{self::Callable::call}(1);
+static field dynamic string2 = self::callable.{self::Callable::call}(1);
+static field dynamic string3 = self::callable.{self::Callable::call}.call(1);
+static field dynamic string4 = self::callable.{self::Callable::call}.call.call(1);
+static field self::CallableGetter* callableGetter = new self::CallableGetter::•();
+static field dynamic string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+ - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var string5 = callableGetter(1);
+                            ^";
+static field dynamic string6 = let final self::CallableGetter* #t1 = self::callableGetter in let final core::int* #t2 = 1 in #t1.{self::CallableGetter::call}.call(#t2);
+static field dynamic string7 = self::callableGetter.{self::CallableGetter::call}.call(1);
+static field dynamic string8 = self::callableGetter.{self::CallableGetter::call}.call.call(1);
+static field dynamic nothing1 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/call.dart:68:23: Error: Too few positional arguments: 1 required, 0 given.
+var nothing1 = closure();
+                      ^" in self::closure.call();
+static field dynamic nothing2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/call.dart:69:28: Error: Too few positional arguments: 1 required, 0 given.
+var nothing2 = closure.call();
+                           ^" in self::closure.call();
+static field dynamic nothing3 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given.
+var nothing3 = closure.call.call();
+                                ^" in self::closure.call.call();
+static field dynamic nothing4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given.
+var nothing4 = closure.call.call.call();
+                                     ^" in self::closure.call.call.call();
+static field dynamic nothing5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given.
+var nothing5 = callable();
+                       ^" in self::callable.{self::Callable::call}();
+static field dynamic nothing6 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/call.dart:74:29: Error: Too few positional arguments: 1 required, 0 given.
+var nothing6 = callable.call();
+                            ^" in self::callable.{self::Callable::call}();
+static field dynamic nothing7 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/call.dart:75:34: Error: Too few positional arguments: 1 required, 0 given.
+var nothing7 = callable.call.call();
+                                 ^" in self::callable.{self::Callable::call}.call();
+static field dynamic nothing8 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given.
+var nothing8 = callable.call.call.call();
+                                      ^" in self::callable.{self::Callable::call}.call.call();
+static field dynamic nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+ - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var nothing9 = callableGetter();
+                             ^";
+static field dynamic nothing10 = self::callableGetter.{self::CallableGetter::call}.call();
+static field dynamic nothing11 = self::callableGetter.{self::CallableGetter::call}.call();
+static field dynamic nothing12 = self::callableGetter.{self::CallableGetter::call}.call.call();
 static method main() → dynamic {
   (dynamic) →* dynamic closure = (dynamic x) → dynamic => x;
   dynamic int1 = closure.call(1);
@@ -81,31 +176,31 @@
 Try changing 'call' to a method or explicitly invoke 'call'.
   var string5 = callableGetter(1);
                               ^";
-  dynamic string6 = let final self::CallableGetter* #t1 = callableGetter in let final core::int* #t2 = 1 in #t1.{self::CallableGetter::call}.call(#t2);
+  dynamic string6 = let final self::CallableGetter* #t11 = callableGetter in let final core::int* #t12 = 1 in #t11.{self::CallableGetter::call}.call(#t12);
   dynamic string7 = callableGetter.{self::CallableGetter::call}.call(1);
   dynamic string8 = callableGetter.{self::CallableGetter::call}.call.call(1);
-  invalid-type nothing1 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/call.dart:34:25: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing1 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general/call.dart:34:25: Error: Too few positional arguments: 1 required, 0 given.
   var nothing1 = closure();
                         ^" in closure.call();
-  invalid-type nothing2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/call.dart:35:30: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing2 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/call.dart:35:30: Error: Too few positional arguments: 1 required, 0 given.
   var nothing2 = closure.call();
                              ^" in closure.call();
-  invalid-type nothing3 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing3 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
   var nothing3 = closure.call.call();
                                   ^" in closure.call.call();
-  invalid-type nothing4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing4 = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
   var nothing4 = closure.call.call.call();
                                        ^" in closure.call.call.call();
-  invalid-type nothing5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing5 = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
   var nothing5 = callable();
                          ^" in callable.{self::Callable::call}();
-  invalid-type nothing6 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/call.dart:40:31: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing6 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general/call.dart:40:31: Error: Too few positional arguments: 1 required, 0 given.
   var nothing6 = callable.call();
                               ^" in callable.{self::Callable::call}();
-  invalid-type nothing7 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/call.dart:41:36: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing7 = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general/call.dart:41:36: Error: Too few positional arguments: 1 required, 0 given.
   var nothing7 = callable.call.call();
                                    ^" in callable.{self::Callable::call}.call();
-  invalid-type nothing8 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
+  invalid-type nothing8 = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
   var nothing8 = callable.call.call.call();
                                         ^" in callable.{self::Callable::call}.call.call();
   dynamic nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:44:32: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
diff --git a/pkg/front_end/testcases/general/call.dart.textual_outline.expect b/pkg/front_end/testcases/general/call.dart.textual_outline.expect
new file mode 100644
index 0000000..f9a3aa0
--- /dev/null
+++ b/pkg/front_end/testcases/general/call.dart.textual_outline.expect
@@ -0,0 +1,36 @@
+class Callable {
+  call(x) {}
+}
+
+class CallableGetter {
+  get call => new Callable();
+}
+
+main() {}
+var closure = (x) => x;
+var int1 = closure(1);
+var int2 = closure.call(1);
+var int3 = closure.call.call(1);
+var int4 = closure.call.call.call(1);
+var callable = new Callable();
+var string1 = callable(1);
+var string2 = callable.call(1);
+var string3 = callable.call.call(1);
+var string4 = callable.call.call.call(1);
+var callableGetter = new CallableGetter();
+var string5 = callableGetter(1);
+var string6 = callableGetter.call(1);
+var string7 = callableGetter.call.call(1);
+var string8 = callableGetter.call.call.call(1);
+var nothing1 = closure();
+var nothing2 = closure.call();
+var nothing3 = closure.call.call();
+var nothing4 = closure.call.call.call();
+var nothing5 = callable();
+var nothing6 = callable.call();
+var nothing7 = callable.call.call();
+var nothing8 = callable.call.call.call();
+var nothing9 = callableGetter();
+var nothing10 = callableGetter.call();
+var nothing11 = callableGetter.call.call();
+var nothing12 = callableGetter.call.call.call();
diff --git a/pkg/front_end/testcases/general/call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2eca437
--- /dev/null
+++ b/pkg/front_end/testcases/general/call.dart.textual_outline_modelled.expect
@@ -0,0 +1,36 @@
+class Callable {
+  call(x) {}
+}
+
+class CallableGetter {
+  get call => new Callable();
+}
+
+main() {}
+var callable = new Callable();
+var callableGetter = new CallableGetter();
+var closure = (x) => x;
+var int1 = closure(1);
+var int2 = closure.call(1);
+var int3 = closure.call.call(1);
+var int4 = closure.call.call.call(1);
+var nothing1 = closure();
+var nothing10 = callableGetter.call();
+var nothing11 = callableGetter.call.call();
+var nothing12 = callableGetter.call.call.call();
+var nothing2 = closure.call();
+var nothing3 = closure.call.call();
+var nothing4 = closure.call.call.call();
+var nothing5 = callable();
+var nothing6 = callable.call();
+var nothing7 = callable.call.call();
+var nothing8 = callable.call.call.call();
+var nothing9 = callableGetter();
+var string1 = callable(1);
+var string2 = callable.call(1);
+var string3 = callable.call.call(1);
+var string4 = callable.call.call.call(1);
+var string5 = callableGetter(1);
+var string6 = callableGetter.call(1);
+var string7 = callableGetter.call.call(1);
+var string8 = callableGetter.call.call.call(1);
diff --git a/pkg/front_end/testcases/general/candidate_found.dart.textual_outline.expect b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline.expect
new file mode 100644
index 0000000..59e6dfd
--- /dev/null
+++ b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Fisk {
+  Fisk(int x) {}
+  Fisk.named(int x) {}
+  void method(int x) {}
+  static void staticMethod(int x) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/candidate_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49525b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Fisk {
+  Fisk(int x) {}
+  Fisk.named(int x) {}
+  static void staticMethod(int x) {}
+  void method(int x) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general/cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/cascade.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/casts.dart.textual_outline.expect b/pkg/front_end/testcases/general/casts.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/casts.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/casts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/casts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/casts.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline.expect
new file mode 100644
index 0000000..4ddbfed
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
+m2() => 1;
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e73aad
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'deferred_lib.dart' deferred as lib;
+
+m2() => 1;
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
index d20f094..1164433 100644
--- a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -27,13 +27,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline.expect
new file mode 100644
index 0000000..72746c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72746c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..b8fbde2
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b8fbde2
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline.expect b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline.expect
new file mode 100644
index 0000000..9252577
--- /dev/null
+++ b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+var x = new C._circular(null);
+
+class C {
+  var f = new C._circular(null);
+  C._circular(this.f);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e8e7de
--- /dev/null
+++ b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+  C._circular(this.f);
+  var f = new C._circular(null);
+}
+
+main() {}
+var x = new C._circular(null);
diff --git a/pkg/front_end/testcases/general/classes.dart.textual_outline.expect b/pkg/front_end/testcases/general/classes.dart.textual_outline.expect
new file mode 100644
index 0000000..db9b2ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/classes.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+  final int x;
+  final int y;
+  A(this.y) : x = 42;
+  method() {}
+}
+
+class B extends A {
+  B(x) : super(x);
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/classes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/classes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b4696f
--- /dev/null
+++ b/pkg/front_end/testcases/general/classes.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A {
+  A(this.y) : x = 42;
+  final int x;
+  final int y;
+  method() {}
+}
+
+class B extends A {
+  B(x) : super(x);
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/clone_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/clone_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..767a6f0
--- /dev/null
+++ b/pkg/front_end/testcases/general/clone_function_type.dart.textual_outline.expect
@@ -0,0 +1,146 @@
+class Am1<X, Y> {
+}
+class Bm1<Z> extends Object with Am1<Function(int), Z> {
+}
+class Cm1<Z> extends Object with Am1<Function(int x), Z> {
+}
+class Dm1<Z> extends Object with Am1<int Function(), Z> {
+}
+class Em1<Z> extends Object with Am1<Function(), Z> {
+}
+class Fm1<Z> extends Object with Am1<Function({int}), Z> {
+}
+class Gm1<Z> extends Object with Am1<Function({int x}), Z> {
+}
+class Hm1<Z> extends Object with Am1<Function([int]), Z> {
+}
+class Im1<Z> extends Object with Am1<Function([int x]), Z> {
+}
+class Jm1<Z> extends Object with Am1<Function, Z> {
+}
+class Km1<Z> extends Object with Am1<Function(Function Function), Z> {
+}
+class Lm1<Z> extends Object with Am1<Function(Function Function() Function) Function(), Z> {
+}
+class Mm1<Z> = Object with Am1<Function(int), Z>; class Nm1<Z> = Object with Am1<Function(int x), Z>; class Om1<Z> = Object with Am1<int Function(), Z>; class Pm1<Z> = Object with Am1<Function(), Z>; class Qm1<Z> = Object with Am1<Function({int}), Z>; class Rm1<Z> = Object with Am1<Function({int x}), Z>; class Sm1<Z> = Object with Am1<Function([int]), Z>; class Tm1<Z> = Object with Am1<Function([int x]), Z>; class Um1<Z> = Object with Am1<Function, Z>; class Vm1<Z> = Object with Am1<Function(Function Function), Z>; class Wm1<Z> = Object with Am1<Function(Function Function() Function) Function(), Z>;
+class Am2<X extends Function(), Y> {
+}
+class Bm2<Z> extends Object with Am2<Function(int), Z> {
+}
+class Cm2<Z> extends Object with Am2<Function(int x), Z> {
+}
+class Dm2<Z> extends Object with Am2<int Function(), Z> {
+}
+class Em2<Z> extends Object with Am2<Function(), Z> {
+}
+class Fm2<Z> extends Object with Am2<Function({int}), Z> {
+}
+class Gm2<Z> extends Object with Am2<Function({int x}), Z> {
+}
+class Hm2<Z> extends Object with Am2<Function([int]), Z> {
+}
+class Im2<Z> extends Object with Am2<Function([int x]), Z> {
+}
+class Jm2<Z> extends Object with Am2<Function, Z> {
+}
+class Km2<Z> extends Object with Am2<Function(Function Function), Z> {
+}
+class Lm2<Z> extends Object with Am2<Function(Function Function() Function) Function(), Z> {
+}
+class Mm2<Z> = Object with Am2<Function(int), Z>; class Nm2<Z> = Object with Am2<Function(int x), Z>; class Om2<Z> = Object with Am2<int Function(), Z>; class Pm2<Z> = Object with Am2<Function(), Z>; class Qm2<Z> = Object with Am2<Function({int}), Z>; class Rm2<Z> = Object with Am2<Function({int x}), Z>; class Sm2<Z> = Object with Am2<Function([int]), Z>; class Tm2<Z> = Object with Am2<Function([int x]), Z>; class Um2<Z> = Object with Am2<Function, Z>; class Vm2<Z> = Object with Am2<Function(Function Function), Z>; class Wm2<Z> = Object with Am2<Function(Function Function() Function) Function(), Z>;
+typedef TdB = Function(int);
+typedef TdC = Function(int x);
+typedef TdD = int Function();
+typedef TdE = Function();
+typedef TdF = Function({int});
+typedef TdG = Function({int x});
+typedef TdH = Function([int]);
+typedef TdI = Function([int x]);
+typedef TdJ = Function(Function Function);
+typedef TdK = Function(Function Function() Function) Function();
+class Am3<L, Y> {
+}
+class Bm3<Z> extends Object with Am3<TdB, Z> {
+}
+class Cm3<Z> extends Object with Am3<TdC, Z> {
+}
+class Dm3<Z> extends Object with Am3<TdD, Z> {
+}
+class Em3<Z> extends Object with Am3<TdE, Z> {
+}
+class Fm3<Z> extends Object with Am3<TdF, Z> {
+}
+class Gm3<Z> extends Object with Am3<TdG, Z> {
+}
+class Hm3<Z> extends Object with Am3<TdH, Z> {
+}
+class Im3<Z> extends Object with Am3<TdI, Z> {
+}
+class Jm3<Z> extends Object with Am3<TdJ, Z> {
+}
+class Km3<Z> extends Object with Am3<TdK, Z> {
+}
+class Af1<X extends Function(int)> {
+  factory Af1.foo() => null;
+}
+class Bf1<X extends Function(int x)> {
+  factory Bf1.foo() => null;
+}
+class Cf1<X extends int Function()> {
+  factory Cf1.foo() => null;
+}
+class Df1<X extends Function()> {
+  factory Df1.foo() => null;
+}
+class Ef1<X extends Function({int})> {
+  factory Ef1.foo() => null;
+}
+class Ff1<X extends Function({int x})> {
+  factory Ff1.foo() => null;
+}
+class Gf1<X extends Function([int])> {
+  factory Gf1.foo() => null;
+}
+class Hf1<X extends Function([int x])> {
+  factory Hf1.foo() => null;
+}
+class If1<X extends Function> {
+  factory If1.foo() => null;
+}
+class Jf1<X extends Function(Function Function)> {
+  factory Jf1.foo() => null;
+}
+class Kf1<X extends Function(Function Function() Function) Function()> {
+  factory Kf1.foo() => null;
+}
+class Bf2<X extends TdB> {
+  factory Bf2.foo() => null;
+}
+class Cf2<X extends TdC> {
+  factory Cf2.foo() => null;
+}
+class Df2<X extends TdD> {
+  factory Df2.foo() => null;
+}
+class Ef2<X extends TdE> {
+  factory Ef2.foo() => null;
+}
+class Ff2<X extends TdF> {
+  factory Ff2.foo() => null;
+}
+class Gf2<X extends TdG> {
+  factory Gf2.foo() => null;
+}
+class Hf2<X extends TdH> {
+  factory Hf2.foo() => null;
+}
+class If2<X extends TdI> {
+  factory If2.foo() => null;
+}
+class Jf2<X extends TdJ> {
+  factory Jf2.foo() => null;
+}
+class Kf2<X extends TdK> {
+  factory Kf2.foo() => null;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/closure.dart.textual_outline.expect b/pkg/front_end/testcases/general/closure.dart.textual_outline.expect
new file mode 100644
index 0000000..544a9e7
--- /dev/null
+++ b/pkg/front_end/testcases/general/closure.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class Foo {
+  var _field = new Bar();
+}
+
+class Bar {}
+
+useCallback(callback) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f6023d
--- /dev/null
+++ b/pkg/front_end/testcases/general/closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Bar {}
+
+class Foo {
+  var _field = new Bar();
+}
+
+main() {}
+useCallback(callback) {}
diff --git a/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline.expect b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline.expect
new file mode 100644
index 0000000..896c9f0
--- /dev/null
+++ b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  const A();
+}
+
+A() {}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c112c59
--- /dev/null
+++ b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+A() {}
+
+class A {
+  const A();
+}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..adeaf17
--- /dev/null
+++ b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+main() {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+class W implements Z {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class GW implements Z, GD {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class ARN extends ARQ<A> {}
diff --git a/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca66b2f
--- /dev/null
+++ b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,43 @@
+class A {}
+
+class ARN extends ARQ<A> {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class GW implements Z, GD {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class W implements Z {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline.expect
new file mode 100644
index 0000000..19f543a
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {}
+
+class B extends A {
+  A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f543a
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {}
+
+class B extends A {
+  A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect
new file mode 100644
index 0000000..8d81665e
--- /dev/null
+++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+  const A() : this.bad();
+  A.bad() {}
+}
+
+class B extends A {
+  const B() : super.bad();
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bee691e
--- /dev/null
+++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+  A.bad() {}
+  const A() : this.bad();
+}
+
+class B extends A {
+  const B() : super.bad();
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart b/pkg/front_end/testcases/general/constant_truncate.dart
new file mode 100644
index 0000000..2f2e792
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.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.
+
+const a0 = 0 ~/ 0; // error
+const a1 = 0.0 ~/ 0; // error
+const a2 = -0.0 ~/ 0; // error
+const a3 = double.nan ~/ 0; // error
+const a4 = double.infinity ~/ 0; // error
+const a5 = double.negativeInfinity ~/ 0; // error
+
+const b0 = 0 ~/ 0.0; // error
+const b1 = 0.0 ~/ 0.0; // error
+const b2 = -0.0 ~/ 0.0; // error
+const b3 = double.nan ~/ 0.0; // error
+const b4 = double.infinity ~/ 0.0; // error
+const b5 = double.negativeInfinity ~/ 0.0; // error
+
+const c0 = 0 ~/ -0.0; // error
+const c1 = 0.0 ~/ -0.0; // error
+const c2 = -0.0 ~/ -0.0; // error
+const c3 = double.nan ~/ -0.0; // error
+const c4 = double.infinity ~/ -0.0; // error
+const c5 = double.negativeInfinity ~/ -0.0; // error
+
+const d0 = 0 ~/ double.nan; // error
+const d1 = 0.0 ~/ double.nan; // error
+const d2 = -0.0 ~/ double.nan; // error
+const d3 = double.nan ~/ double.nan; // error
+const d4 = double.infinity ~/ double.nan; // error
+const d5 = double.negativeInfinity ~/ double.nan; // error
+
+const e0 = 0 ~/ double.infinity; // ok
+const e1 = 0.0 ~/ double.infinity; // ok
+const e2 = -0.0 ~/ double.infinity; // ok
+const e3 = double.nan ~/ double.infinity; // error
+const e4 = double.infinity ~/ double.infinity; // error
+const e5 = double.negativeInfinity ~/ double.infinity; // error
+
+const f0 = 0 ~/ double.negativeInfinity; // ok
+const f1 = 0.0 ~/ double.negativeInfinity; // ok
+const f2 = -0.0 ~/ double.negativeInfinity; // ok
+const f3 = double.nan ~/ double.negativeInfinity; // error
+const f4 = double.infinity ~/ double.negativeInfinity; // error
+const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+
+main() {
+  test(0, 0, () => a0);
+  test(0.0, 0, () => a1);
+  test(-0.0, 0, () => a2);
+  test(double.nan, 0, () => a3);
+  test(double.infinity, 0, () => a4);
+  test(double.negativeInfinity, 0, () => a5);
+
+  test(0, 0.0, () => b0);
+  test(0.0, 0.0, () => b1);
+  test(-0.0, 0.0, () => b2);
+  test(double.nan, 0.0, () => b3);
+  test(double.infinity, 0.0, () => b4);
+  test(double.negativeInfinity, 0.0, () => b5);
+
+  test(0, -0.0, () => c0);
+  test(0.0, -0.0, () => c1);
+  test(-0.0, -0.0, () => c2);
+  test(double.nan, -0.0, () => c3);
+  test(double.infinity, -0.0, () => c4);
+  test(double.negativeInfinity, -0.0, () => c5);
+
+  test(0, double.nan, () => d0);
+  test(0.0, double.nan, () => d1);
+  test(-0.0, double.nan, () => d2);
+  test(double.nan, double.nan, () => d3);
+  test(double.infinity, double.nan, () => d4);
+  test(double.negativeInfinity, double.nan, () => d5);
+
+  test(0, double.infinity, () => e0);
+  test(0.0, double.infinity, () => e1);
+  test(-0.0, double.infinity, () => e2);
+  test(double.nan, double.infinity, () => e3);
+  test(double.infinity, double.infinity, () => e4);
+  test(double.negativeInfinity, double.infinity, () => e5);
+
+  test(0, double.negativeInfinity, () => f0);
+  test(0.0, double.negativeInfinity, () => f1);
+  test(-0.0, double.negativeInfinity, () => f2);
+  test(double.nan, double.negativeInfinity, () => f3);
+  test(double.infinity, double.negativeInfinity, () => f4);
+  test(double.negativeInfinity, double.negativeInfinity, () => f5);
+}
+
+void test(num a, num b, num Function() f) {
+  num result;
+  try {
+    result = a ~/ b;
+    print('$a ~/ $b = $result');
+  } catch (e) {
+    print('$a ~/ $b throws $e');
+    throws(f);
+    return;
+  }
+  expect(f(), result);
+}
+
+void expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected $expected, actual $actual';
+  }
+}
+
+void throws(num Function() f) {
+  try {
+    f();
+  } catch (e) {
+    return;
+  }
+  throw 'Expected exception';
+}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.outline.expect b/pkg/front_end/testcases/general/constant_truncate.dart.outline.expect
new file mode 100644
index 0000000..579ea4a
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.outline.expect
@@ -0,0 +1,48 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* a0 = 0.{core::num::~/}(0);
+static const field core::int* a1 = 0.0.{core::double::~/}(0);
+static const field core::int* a2 = 0.0.{core::double::unary-}().{core::double::~/}(0);
+static const field core::int* a3 = core::double::nan.{core::double::~/}(0);
+static const field core::int* a4 = core::double::infinity.{core::double::~/}(0);
+static const field core::int* a5 = core::double::negativeInfinity.{core::double::~/}(0);
+static const field core::int* b0 = 0.{core::num::~/}(0.0);
+static const field core::int* b1 = 0.0.{core::double::~/}(0.0);
+static const field core::int* b2 = 0.0.{core::double::unary-}().{core::double::~/}(0.0);
+static const field core::int* b3 = core::double::nan.{core::double::~/}(0.0);
+static const field core::int* b4 = core::double::infinity.{core::double::~/}(0.0);
+static const field core::int* b5 = core::double::negativeInfinity.{core::double::~/}(0.0);
+static const field core::int* c0 = 0.{core::num::~/}(0.0.{core::double::unary-}());
+static const field core::int* c1 = 0.0.{core::double::~/}(0.0.{core::double::unary-}());
+static const field core::int* c2 = 0.0.{core::double::unary-}().{core::double::~/}(0.0.{core::double::unary-}());
+static const field core::int* c3 = core::double::nan.{core::double::~/}(0.0.{core::double::unary-}());
+static const field core::int* c4 = core::double::infinity.{core::double::~/}(0.0.{core::double::unary-}());
+static const field core::int* c5 = core::double::negativeInfinity.{core::double::~/}(0.0.{core::double::unary-}());
+static const field core::int* d0 = 0.{core::num::~/}(core::double::nan);
+static const field core::int* d1 = 0.0.{core::double::~/}(core::double::nan);
+static const field core::int* d2 = 0.0.{core::double::unary-}().{core::double::~/}(core::double::nan);
+static const field core::int* d3 = core::double::nan.{core::double::~/}(core::double::nan);
+static const field core::int* d4 = core::double::infinity.{core::double::~/}(core::double::nan);
+static const field core::int* d5 = core::double::negativeInfinity.{core::double::~/}(core::double::nan);
+static const field core::int* e0 = 0.{core::num::~/}(core::double::infinity);
+static const field core::int* e1 = 0.0.{core::double::~/}(core::double::infinity);
+static const field core::int* e2 = 0.0.{core::double::unary-}().{core::double::~/}(core::double::infinity);
+static const field core::int* e3 = core::double::nan.{core::double::~/}(core::double::infinity);
+static const field core::int* e4 = core::double::infinity.{core::double::~/}(core::double::infinity);
+static const field core::int* e5 = core::double::negativeInfinity.{core::double::~/}(core::double::infinity);
+static const field core::int* f0 = 0.{core::num::~/}(core::double::negativeInfinity);
+static const field core::int* f1 = 0.0.{core::double::~/}(core::double::negativeInfinity);
+static const field core::int* f2 = 0.0.{core::double::unary-}().{core::double::~/}(core::double::negativeInfinity);
+static const field core::int* f3 = core::double::nan.{core::double::~/}(core::double::negativeInfinity);
+static const field core::int* f4 = core::double::infinity.{core::double::~/}(core::double::negativeInfinity);
+static const field core::int* f5 = core::double::negativeInfinity.{core::double::~/}(core::double::negativeInfinity);
+static method main() → dynamic
+  ;
+static method test(core::num* a, core::num* b, () →* core::num* f) → void
+  ;
+static method expect(dynamic expected, dynamic actual) → void
+  ;
+static method throws(() →* core::num* f) → void
+  ;
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.strong.expect b/pkg/front_end/testcases/general/constant_truncate.dart.strong.expect
new file mode 100644
index 0000000..5e6673e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.strong.expect
@@ -0,0 +1,415 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:5:14: Error: Constant evaluation error:
+// const a0 = 0 ~/ 0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:5:14: Context: Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.
+// const a0 = 0 ~/ 0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:5:7: Context: While analyzing:
+// const a0 = 0 ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:6:16: Error: Constant evaluation error:
+// const a1 = 0.0 ~/ 0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:6:16: Context: Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.
+// const a1 = 0.0 ~/ 0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:6:7: Context: While analyzing:
+// const a1 = 0.0 ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:7:17: Error: Constant evaluation error:
+// const a2 = -0.0 ~/ 0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:7:17: Context: Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.
+// const a2 = -0.0 ~/ 0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:7:7: Context: While analyzing:
+// const a2 = -0.0 ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:8:23: Error: Constant evaluation error:
+// const a3 = double.nan ~/ 0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:8:23: Context: Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.
+// const a3 = double.nan ~/ 0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:8:7: Context: While analyzing:
+// const a3 = double.nan ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:9:28: Error: Constant evaluation error:
+// const a4 = double.infinity ~/ 0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:9:28: Context: Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.
+// const a4 = double.infinity ~/ 0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:9:7: Context: While analyzing:
+// const a4 = double.infinity ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:10:36: Error: Constant evaluation error:
+// const a5 = double.negativeInfinity ~/ 0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:10:36: Context: Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.
+// const a5 = double.negativeInfinity ~/ 0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:10:7: Context: While analyzing:
+// const a5 = double.negativeInfinity ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:12:14: Error: Constant evaluation error:
+// const b0 = 0 ~/ 0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:12:14: Context: Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.
+// const b0 = 0 ~/ 0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:12:7: Context: While analyzing:
+// const b0 = 0 ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:13:16: Error: Constant evaluation error:
+// const b1 = 0.0 ~/ 0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:13:16: Context: Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.
+// const b1 = 0.0 ~/ 0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:13:7: Context: While analyzing:
+// const b1 = 0.0 ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:14:17: Error: Constant evaluation error:
+// const b2 = -0.0 ~/ 0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:14:17: Context: Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.
+// const b2 = -0.0 ~/ 0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:14:7: Context: While analyzing:
+// const b2 = -0.0 ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:15:23: Error: Constant evaluation error:
+// const b3 = double.nan ~/ 0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:15:23: Context: Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.
+// const b3 = double.nan ~/ 0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:15:7: Context: While analyzing:
+// const b3 = double.nan ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:16:28: Error: Constant evaluation error:
+// const b4 = double.infinity ~/ 0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:16:28: Context: Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.
+// const b4 = double.infinity ~/ 0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:16:7: Context: While analyzing:
+// const b4 = double.infinity ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:17:36: Error: Constant evaluation error:
+// const b5 = double.negativeInfinity ~/ 0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:17:36: Context: Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.
+// const b5 = double.negativeInfinity ~/ 0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:17:7: Context: While analyzing:
+// const b5 = double.negativeInfinity ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:19:14: Error: Constant evaluation error:
+// const c0 = 0 ~/ -0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:19:14: Context: Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.
+// const c0 = 0 ~/ -0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:19:7: Context: While analyzing:
+// const c0 = 0 ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:20:16: Error: Constant evaluation error:
+// const c1 = 0.0 ~/ -0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:20:16: Context: Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.
+// const c1 = 0.0 ~/ -0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:20:7: Context: While analyzing:
+// const c1 = 0.0 ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:21:17: Error: Constant evaluation error:
+// const c2 = -0.0 ~/ -0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:21:17: Context: Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.
+// const c2 = -0.0 ~/ -0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:21:7: Context: While analyzing:
+// const c2 = -0.0 ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:22:23: Error: Constant evaluation error:
+// const c3 = double.nan ~/ -0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:22:23: Context: Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.
+// const c3 = double.nan ~/ -0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:22:7: Context: While analyzing:
+// const c3 = double.nan ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:23:28: Error: Constant evaluation error:
+// const c4 = double.infinity ~/ -0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:23:28: Context: Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.
+// const c4 = double.infinity ~/ -0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:23:7: Context: While analyzing:
+// const c4 = double.infinity ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:24:36: Error: Constant evaluation error:
+// const c5 = double.negativeInfinity ~/ -0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:24:36: Context: Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.
+// const c5 = double.negativeInfinity ~/ -0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:24:7: Context: While analyzing:
+// const c5 = double.negativeInfinity ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:26:14: Error: Constant evaluation error:
+// const d0 = 0 ~/ double.nan; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:26:14: Context: Binary operator '0 ~/ NaN' results is Infinity or NaN.
+// const d0 = 0 ~/ double.nan; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:26:7: Context: While analyzing:
+// const d0 = 0 ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:27:16: Error: Constant evaluation error:
+// const d1 = 0.0 ~/ double.nan; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:27:16: Context: Binary operator '0.0 ~/ NaN' results is Infinity or NaN.
+// const d1 = 0.0 ~/ double.nan; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:27:7: Context: While analyzing:
+// const d1 = 0.0 ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:28:17: Error: Constant evaluation error:
+// const d2 = -0.0 ~/ double.nan; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:28:17: Context: Binary operator '-0.0 ~/ NaN' results is Infinity or NaN.
+// const d2 = -0.0 ~/ double.nan; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:28:7: Context: While analyzing:
+// const d2 = -0.0 ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:29:23: Error: Constant evaluation error:
+// const d3 = double.nan ~/ double.nan; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:29:23: Context: Binary operator 'NaN ~/ NaN' results is Infinity or NaN.
+// const d3 = double.nan ~/ double.nan; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:29:7: Context: While analyzing:
+// const d3 = double.nan ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:30:28: Error: Constant evaluation error:
+// const d4 = double.infinity ~/ double.nan; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:30:28: Context: Binary operator 'Infinity ~/ NaN' results is Infinity or NaN.
+// const d4 = double.infinity ~/ double.nan; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:30:7: Context: While analyzing:
+// const d4 = double.infinity ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:31:36: Error: Constant evaluation error:
+// const d5 = double.negativeInfinity ~/ double.nan; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:31:36: Context: Binary operator '-Infinity ~/ NaN' results is Infinity or NaN.
+// const d5 = double.negativeInfinity ~/ double.nan; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:31:7: Context: While analyzing:
+// const d5 = double.negativeInfinity ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:36:23: Error: Constant evaluation error:
+// const e3 = double.nan ~/ double.infinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:36:23: Context: Binary operator 'NaN ~/ Infinity' results is Infinity or NaN.
+// const e3 = double.nan ~/ double.infinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:36:7: Context: While analyzing:
+// const e3 = double.nan ~/ double.infinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:37:28: Error: Constant evaluation error:
+// const e4 = double.infinity ~/ double.infinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:37:28: Context: Binary operator 'Infinity ~/ Infinity' results is Infinity or NaN.
+// const e4 = double.infinity ~/ double.infinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:37:7: Context: While analyzing:
+// const e4 = double.infinity ~/ double.infinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:38:36: Error: Constant evaluation error:
+// const e5 = double.negativeInfinity ~/ double.infinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:38:36: Context: Binary operator '-Infinity ~/ Infinity' results is Infinity or NaN.
+// const e5 = double.negativeInfinity ~/ double.infinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:38:7: Context: While analyzing:
+// const e5 = double.negativeInfinity ~/ double.infinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:43:23: Error: Constant evaluation error:
+// const f3 = double.nan ~/ double.negativeInfinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:43:23: Context: Binary operator 'NaN ~/ -Infinity' results is Infinity or NaN.
+// const f3 = double.nan ~/ double.negativeInfinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:43:7: Context: While analyzing:
+// const f3 = double.nan ~/ double.negativeInfinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:44:28: Error: Constant evaluation error:
+// const f4 = double.infinity ~/ double.negativeInfinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:44:28: Context: Binary operator 'Infinity ~/ -Infinity' results is Infinity or NaN.
+// const f4 = double.infinity ~/ double.negativeInfinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:44:7: Context: While analyzing:
+// const f4 = double.infinity ~/ double.negativeInfinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:45:36: Error: Constant evaluation error:
+// const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:45:36: Context: Binary operator '-Infinity ~/ -Infinity' results is Infinity or NaN.
+// const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:45:7: Context: While analyzing:
+// const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+//       ^
+//
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* a0 = invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a1 = invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a2 = invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a3 = invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a4 = invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a5 = invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b0 = invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b1 = invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b2 = invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b3 = invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b4 = invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b5 = invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c0 = invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c1 = invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c2 = invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c3 = invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c4 = invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c5 = invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* d0 = invalid-expression "Binary operator '0 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d1 = invalid-expression "Binary operator '0.0 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d2 = invalid-expression "Binary operator '-0.0 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d3 = invalid-expression "Binary operator 'NaN ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d4 = invalid-expression "Binary operator 'Infinity ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d5 = invalid-expression "Binary operator '-Infinity ~/ NaN' results is Infinity or NaN.";
+static const field core::int* e0 = #C1;
+static const field core::int* e1 = #C1;
+static const field core::int* e2 = #C1;
+static const field core::int* e3 = invalid-expression "Binary operator 'NaN ~/ Infinity' results is Infinity or NaN.";
+static const field core::int* e4 = invalid-expression "Binary operator 'Infinity ~/ Infinity' results is Infinity or NaN.";
+static const field core::int* e5 = invalid-expression "Binary operator '-Infinity ~/ Infinity' results is Infinity or NaN.";
+static const field core::int* f0 = #C1;
+static const field core::int* f1 = #C1;
+static const field core::int* f2 = #C1;
+static const field core::int* f3 = invalid-expression "Binary operator 'NaN ~/ -Infinity' results is Infinity or NaN.";
+static const field core::int* f4 = invalid-expression "Binary operator 'Infinity ~/ -Infinity' results is Infinity or NaN.";
+static const field core::int* f5 = invalid-expression "Binary operator '-Infinity ~/ -Infinity' results is Infinity or NaN.";
+static method main() → dynamic {
+  self::test(0, 0, () → core::int* => invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0, 0, () → core::int* => invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0.{core::double::unary-}(), 0, () → core::int* => invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C2, 0, () → core::int* => invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C3, 0, () → core::int* => invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C4, 0, () → core::int* => invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(0, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0.{core::double::unary-}(), 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C2, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C3, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C4, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(0, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0.{core::double::unary-}(), 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C2, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C3, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C4, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(0, #C2, () → core::int* => invalid-expression "Binary operator '0 ~/ NaN' results is Infinity or NaN.");
+  self::test(0.0, #C2, () → core::int* => invalid-expression "Binary operator '0.0 ~/ NaN' results is Infinity or NaN.");
+  self::test(0.0.{core::double::unary-}(), #C2, () → core::int* => invalid-expression "Binary operator '-0.0 ~/ NaN' results is Infinity or NaN.");
+  self::test(#C2, #C2, () → core::int* => invalid-expression "Binary operator 'NaN ~/ NaN' results is Infinity or NaN.");
+  self::test(#C3, #C2, () → core::int* => invalid-expression "Binary operator 'Infinity ~/ NaN' results is Infinity or NaN.");
+  self::test(#C4, #C2, () → core::int* => invalid-expression "Binary operator '-Infinity ~/ NaN' results is Infinity or NaN.");
+  self::test(0, #C3, () → core::int* => #C1);
+  self::test(0.0, #C3, () → core::int* => #C1);
+  self::test(0.0.{core::double::unary-}(), #C3, () → core::int* => #C1);
+  self::test(#C2, #C3, () → core::int* => invalid-expression "Binary operator 'NaN ~/ Infinity' results is Infinity or NaN.");
+  self::test(#C3, #C3, () → core::int* => invalid-expression "Binary operator 'Infinity ~/ Infinity' results is Infinity or NaN.");
+  self::test(#C4, #C3, () → core::int* => invalid-expression "Binary operator '-Infinity ~/ Infinity' results is Infinity or NaN.");
+  self::test(0, #C4, () → core::int* => #C1);
+  self::test(0.0, #C4, () → core::int* => #C1);
+  self::test(0.0.{core::double::unary-}(), #C4, () → core::int* => #C1);
+  self::test(#C2, #C4, () → core::int* => invalid-expression "Binary operator 'NaN ~/ -Infinity' results is Infinity or NaN.");
+  self::test(#C3, #C4, () → core::int* => invalid-expression "Binary operator 'Infinity ~/ -Infinity' results is Infinity or NaN.");
+  self::test(#C4, #C4, () → core::int* => invalid-expression "Binary operator '-Infinity ~/ -Infinity' results is Infinity or NaN.");
+}
+static method test(core::num* a, core::num* b, () →* core::num* f) → void {
+  core::num* result;
+  try {
+    result = a.{core::num::~/}(b);
+    core::print("${a} ~/ ${b} = ${result}");
+  }
+  on dynamic catch(final dynamic e) {
+    core::print("${a} ~/ ${b} throws ${e}");
+    self::throws(f);
+    return;
+  }
+  self::expect(f.call(), result);
+}
+static method expect(dynamic expected, dynamic actual) → void {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+static method throws(() →* core::num* f) → void {
+  try {
+    f.call();
+  }
+  on dynamic catch(final dynamic e) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = 0
+  #C2 = NaN
+  #C3 = Infinity
+  #C4 = -Infinity
+}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constant_truncate.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e6673e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.strong.transformed.expect
@@ -0,0 +1,415 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:5:14: Error: Constant evaluation error:
+// const a0 = 0 ~/ 0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:5:14: Context: Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.
+// const a0 = 0 ~/ 0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:5:7: Context: While analyzing:
+// const a0 = 0 ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:6:16: Error: Constant evaluation error:
+// const a1 = 0.0 ~/ 0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:6:16: Context: Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.
+// const a1 = 0.0 ~/ 0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:6:7: Context: While analyzing:
+// const a1 = 0.0 ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:7:17: Error: Constant evaluation error:
+// const a2 = -0.0 ~/ 0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:7:17: Context: Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.
+// const a2 = -0.0 ~/ 0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:7:7: Context: While analyzing:
+// const a2 = -0.0 ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:8:23: Error: Constant evaluation error:
+// const a3 = double.nan ~/ 0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:8:23: Context: Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.
+// const a3 = double.nan ~/ 0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:8:7: Context: While analyzing:
+// const a3 = double.nan ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:9:28: Error: Constant evaluation error:
+// const a4 = double.infinity ~/ 0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:9:28: Context: Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.
+// const a4 = double.infinity ~/ 0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:9:7: Context: While analyzing:
+// const a4 = double.infinity ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:10:36: Error: Constant evaluation error:
+// const a5 = double.negativeInfinity ~/ 0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:10:36: Context: Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.
+// const a5 = double.negativeInfinity ~/ 0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:10:7: Context: While analyzing:
+// const a5 = double.negativeInfinity ~/ 0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:12:14: Error: Constant evaluation error:
+// const b0 = 0 ~/ 0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:12:14: Context: Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.
+// const b0 = 0 ~/ 0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:12:7: Context: While analyzing:
+// const b0 = 0 ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:13:16: Error: Constant evaluation error:
+// const b1 = 0.0 ~/ 0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:13:16: Context: Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.
+// const b1 = 0.0 ~/ 0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:13:7: Context: While analyzing:
+// const b1 = 0.0 ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:14:17: Error: Constant evaluation error:
+// const b2 = -0.0 ~/ 0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:14:17: Context: Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.
+// const b2 = -0.0 ~/ 0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:14:7: Context: While analyzing:
+// const b2 = -0.0 ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:15:23: Error: Constant evaluation error:
+// const b3 = double.nan ~/ 0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:15:23: Context: Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.
+// const b3 = double.nan ~/ 0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:15:7: Context: While analyzing:
+// const b3 = double.nan ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:16:28: Error: Constant evaluation error:
+// const b4 = double.infinity ~/ 0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:16:28: Context: Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.
+// const b4 = double.infinity ~/ 0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:16:7: Context: While analyzing:
+// const b4 = double.infinity ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:17:36: Error: Constant evaluation error:
+// const b5 = double.negativeInfinity ~/ 0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:17:36: Context: Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.
+// const b5 = double.negativeInfinity ~/ 0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:17:7: Context: While analyzing:
+// const b5 = double.negativeInfinity ~/ 0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:19:14: Error: Constant evaluation error:
+// const c0 = 0 ~/ -0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:19:14: Context: Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.
+// const c0 = 0 ~/ -0.0; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:19:7: Context: While analyzing:
+// const c0 = 0 ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:20:16: Error: Constant evaluation error:
+// const c1 = 0.0 ~/ -0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:20:16: Context: Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.
+// const c1 = 0.0 ~/ -0.0; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:20:7: Context: While analyzing:
+// const c1 = 0.0 ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:21:17: Error: Constant evaluation error:
+// const c2 = -0.0 ~/ -0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:21:17: Context: Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.
+// const c2 = -0.0 ~/ -0.0; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:21:7: Context: While analyzing:
+// const c2 = -0.0 ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:22:23: Error: Constant evaluation error:
+// const c3 = double.nan ~/ -0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:22:23: Context: Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.
+// const c3 = double.nan ~/ -0.0; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:22:7: Context: While analyzing:
+// const c3 = double.nan ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:23:28: Error: Constant evaluation error:
+// const c4 = double.infinity ~/ -0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:23:28: Context: Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.
+// const c4 = double.infinity ~/ -0.0; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:23:7: Context: While analyzing:
+// const c4 = double.infinity ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:24:36: Error: Constant evaluation error:
+// const c5 = double.negativeInfinity ~/ -0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:24:36: Context: Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.
+// const c5 = double.negativeInfinity ~/ -0.0; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:24:7: Context: While analyzing:
+// const c5 = double.negativeInfinity ~/ -0.0; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:26:14: Error: Constant evaluation error:
+// const d0 = 0 ~/ double.nan; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:26:14: Context: Binary operator '0 ~/ NaN' results is Infinity or NaN.
+// const d0 = 0 ~/ double.nan; // error
+//              ^
+// pkg/front_end/testcases/general/constant_truncate.dart:26:7: Context: While analyzing:
+// const d0 = 0 ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:27:16: Error: Constant evaluation error:
+// const d1 = 0.0 ~/ double.nan; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:27:16: Context: Binary operator '0.0 ~/ NaN' results is Infinity or NaN.
+// const d1 = 0.0 ~/ double.nan; // error
+//                ^
+// pkg/front_end/testcases/general/constant_truncate.dart:27:7: Context: While analyzing:
+// const d1 = 0.0 ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:28:17: Error: Constant evaluation error:
+// const d2 = -0.0 ~/ double.nan; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:28:17: Context: Binary operator '-0.0 ~/ NaN' results is Infinity or NaN.
+// const d2 = -0.0 ~/ double.nan; // error
+//                 ^
+// pkg/front_end/testcases/general/constant_truncate.dart:28:7: Context: While analyzing:
+// const d2 = -0.0 ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:29:23: Error: Constant evaluation error:
+// const d3 = double.nan ~/ double.nan; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:29:23: Context: Binary operator 'NaN ~/ NaN' results is Infinity or NaN.
+// const d3 = double.nan ~/ double.nan; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:29:7: Context: While analyzing:
+// const d3 = double.nan ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:30:28: Error: Constant evaluation error:
+// const d4 = double.infinity ~/ double.nan; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:30:28: Context: Binary operator 'Infinity ~/ NaN' results is Infinity or NaN.
+// const d4 = double.infinity ~/ double.nan; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:30:7: Context: While analyzing:
+// const d4 = double.infinity ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:31:36: Error: Constant evaluation error:
+// const d5 = double.negativeInfinity ~/ double.nan; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:31:36: Context: Binary operator '-Infinity ~/ NaN' results is Infinity or NaN.
+// const d5 = double.negativeInfinity ~/ double.nan; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:31:7: Context: While analyzing:
+// const d5 = double.negativeInfinity ~/ double.nan; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:36:23: Error: Constant evaluation error:
+// const e3 = double.nan ~/ double.infinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:36:23: Context: Binary operator 'NaN ~/ Infinity' results is Infinity or NaN.
+// const e3 = double.nan ~/ double.infinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:36:7: Context: While analyzing:
+// const e3 = double.nan ~/ double.infinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:37:28: Error: Constant evaluation error:
+// const e4 = double.infinity ~/ double.infinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:37:28: Context: Binary operator 'Infinity ~/ Infinity' results is Infinity or NaN.
+// const e4 = double.infinity ~/ double.infinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:37:7: Context: While analyzing:
+// const e4 = double.infinity ~/ double.infinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:38:36: Error: Constant evaluation error:
+// const e5 = double.negativeInfinity ~/ double.infinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:38:36: Context: Binary operator '-Infinity ~/ Infinity' results is Infinity or NaN.
+// const e5 = double.negativeInfinity ~/ double.infinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:38:7: Context: While analyzing:
+// const e5 = double.negativeInfinity ~/ double.infinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:43:23: Error: Constant evaluation error:
+// const f3 = double.nan ~/ double.negativeInfinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:43:23: Context: Binary operator 'NaN ~/ -Infinity' results is Infinity or NaN.
+// const f3 = double.nan ~/ double.negativeInfinity; // error
+//                       ^
+// pkg/front_end/testcases/general/constant_truncate.dart:43:7: Context: While analyzing:
+// const f3 = double.nan ~/ double.negativeInfinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:44:28: Error: Constant evaluation error:
+// const f4 = double.infinity ~/ double.negativeInfinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:44:28: Context: Binary operator 'Infinity ~/ -Infinity' results is Infinity or NaN.
+// const f4 = double.infinity ~/ double.negativeInfinity; // error
+//                            ^
+// pkg/front_end/testcases/general/constant_truncate.dart:44:7: Context: While analyzing:
+// const f4 = double.infinity ~/ double.negativeInfinity; // error
+//       ^
+//
+// pkg/front_end/testcases/general/constant_truncate.dart:45:36: Error: Constant evaluation error:
+// const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:45:36: Context: Binary operator '-Infinity ~/ -Infinity' results is Infinity or NaN.
+// const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+//                                    ^
+// pkg/front_end/testcases/general/constant_truncate.dart:45:7: Context: While analyzing:
+// const f5 = double.negativeInfinity ~/ double.negativeInfinity; // error
+//       ^
+//
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* a0 = invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a1 = invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a2 = invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a3 = invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a4 = invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* a5 = invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b0 = invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b1 = invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b2 = invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b3 = invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b4 = invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* b5 = invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c0 = invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c1 = invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c2 = invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c3 = invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c4 = invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* c5 = invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* d0 = invalid-expression "Binary operator '0 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d1 = invalid-expression "Binary operator '0.0 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d2 = invalid-expression "Binary operator '-0.0 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d3 = invalid-expression "Binary operator 'NaN ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d4 = invalid-expression "Binary operator 'Infinity ~/ NaN' results is Infinity or NaN.";
+static const field core::int* d5 = invalid-expression "Binary operator '-Infinity ~/ NaN' results is Infinity or NaN.";
+static const field core::int* e0 = #C1;
+static const field core::int* e1 = #C1;
+static const field core::int* e2 = #C1;
+static const field core::int* e3 = invalid-expression "Binary operator 'NaN ~/ Infinity' results is Infinity or NaN.";
+static const field core::int* e4 = invalid-expression "Binary operator 'Infinity ~/ Infinity' results is Infinity or NaN.";
+static const field core::int* e5 = invalid-expression "Binary operator '-Infinity ~/ Infinity' results is Infinity or NaN.";
+static const field core::int* f0 = #C1;
+static const field core::int* f1 = #C1;
+static const field core::int* f2 = #C1;
+static const field core::int* f3 = invalid-expression "Binary operator 'NaN ~/ -Infinity' results is Infinity or NaN.";
+static const field core::int* f4 = invalid-expression "Binary operator 'Infinity ~/ -Infinity' results is Infinity or NaN.";
+static const field core::int* f5 = invalid-expression "Binary operator '-Infinity ~/ -Infinity' results is Infinity or NaN.";
+static method main() → dynamic {
+  self::test(0, 0, () → core::int* => invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0, 0, () → core::int* => invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0.{core::double::unary-}(), 0, () → core::int* => invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C2, 0, () → core::int* => invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C3, 0, () → core::int* => invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C4, 0, () → core::int* => invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(0, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0.{core::double::unary-}(), 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C2, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C3, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C4, 0.0, () → core::int* => invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(0, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(0.0.{core::double::unary-}(), 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '-0.0' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C2, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on 'NaN' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C3, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on 'Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(#C4, 0.0.{core::double::unary-}(), () → core::int* => invalid-expression "Binary operator '~/' on '-Infinity' requires non-zero divisor, but divisor was '0'.");
+  self::test(0, #C2, () → core::int* => invalid-expression "Binary operator '0 ~/ NaN' results is Infinity or NaN.");
+  self::test(0.0, #C2, () → core::int* => invalid-expression "Binary operator '0.0 ~/ NaN' results is Infinity or NaN.");
+  self::test(0.0.{core::double::unary-}(), #C2, () → core::int* => invalid-expression "Binary operator '-0.0 ~/ NaN' results is Infinity or NaN.");
+  self::test(#C2, #C2, () → core::int* => invalid-expression "Binary operator 'NaN ~/ NaN' results is Infinity or NaN.");
+  self::test(#C3, #C2, () → core::int* => invalid-expression "Binary operator 'Infinity ~/ NaN' results is Infinity or NaN.");
+  self::test(#C4, #C2, () → core::int* => invalid-expression "Binary operator '-Infinity ~/ NaN' results is Infinity or NaN.");
+  self::test(0, #C3, () → core::int* => #C1);
+  self::test(0.0, #C3, () → core::int* => #C1);
+  self::test(0.0.{core::double::unary-}(), #C3, () → core::int* => #C1);
+  self::test(#C2, #C3, () → core::int* => invalid-expression "Binary operator 'NaN ~/ Infinity' results is Infinity or NaN.");
+  self::test(#C3, #C3, () → core::int* => invalid-expression "Binary operator 'Infinity ~/ Infinity' results is Infinity or NaN.");
+  self::test(#C4, #C3, () → core::int* => invalid-expression "Binary operator '-Infinity ~/ Infinity' results is Infinity or NaN.");
+  self::test(0, #C4, () → core::int* => #C1);
+  self::test(0.0, #C4, () → core::int* => #C1);
+  self::test(0.0.{core::double::unary-}(), #C4, () → core::int* => #C1);
+  self::test(#C2, #C4, () → core::int* => invalid-expression "Binary operator 'NaN ~/ -Infinity' results is Infinity or NaN.");
+  self::test(#C3, #C4, () → core::int* => invalid-expression "Binary operator 'Infinity ~/ -Infinity' results is Infinity or NaN.");
+  self::test(#C4, #C4, () → core::int* => invalid-expression "Binary operator '-Infinity ~/ -Infinity' results is Infinity or NaN.");
+}
+static method test(core::num* a, core::num* b, () →* core::num* f) → void {
+  core::num* result;
+  try {
+    result = a.{core::num::~/}(b);
+    core::print("${a} ~/ ${b} = ${result}");
+  }
+  on dynamic catch(final dynamic e) {
+    core::print("${a} ~/ ${b} throws ${e}");
+    self::throws(f);
+    return;
+  }
+  self::expect(f.call(), result);
+}
+static method expect(dynamic expected, dynamic actual) → void {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+static method throws(() →* core::num* f) → void {
+  try {
+    f.call();
+  }
+  on dynamic catch(final dynamic e) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = 0
+  #C2 = NaN
+  #C3 = Infinity
+  #C4 = -Infinity
+}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline.expect b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline.expect
new file mode 100644
index 0000000..44d49e8
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline.expect
@@ -0,0 +1,40 @@
+const a0 = 0 ~/ 0;
+const a1 = 0.0 ~/ 0;
+const a2 = -0.0 ~/ 0;
+const a3 = double.nan ~/ 0;
+const a4 = double.infinity ~/ 0;
+const a5 = double.negativeInfinity ~/ 0;
+const b0 = 0 ~/ 0.0;
+const b1 = 0.0 ~/ 0.0;
+const b2 = -0.0 ~/ 0.0;
+const b3 = double.nan ~/ 0.0;
+const b4 = double.infinity ~/ 0.0;
+const b5 = double.negativeInfinity ~/ 0.0;
+const c0 = 0 ~/ -0.0;
+const c1 = 0.0 ~/ -0.0;
+const c2 = -0.0 ~/ -0.0;
+const c3 = double.nan ~/ -0.0;
+const c4 = double.infinity ~/ -0.0;
+const c5 = double.negativeInfinity ~/ -0.0;
+const d0 = 0 ~/ double.nan;
+const d1 = 0.0 ~/ double.nan;
+const d2 = -0.0 ~/ double.nan;
+const d3 = double.nan ~/ double.nan;
+const d4 = double.infinity ~/ double.nan;
+const d5 = double.negativeInfinity ~/ double.nan;
+const e0 = 0 ~/ double.infinity;
+const e1 = 0.0 ~/ double.infinity;
+const e2 = -0.0 ~/ double.infinity;
+const e3 = double.nan ~/ double.infinity;
+const e4 = double.infinity ~/ double.infinity;
+const e5 = double.negativeInfinity ~/ double.infinity;
+const f0 = 0 ~/ double.negativeInfinity;
+const f1 = 0.0 ~/ double.negativeInfinity;
+const f2 = -0.0 ~/ double.negativeInfinity;
+const f3 = double.nan ~/ double.negativeInfinity;
+const f4 = double.infinity ~/ double.negativeInfinity;
+const f5 = double.negativeInfinity ~/ double.negativeInfinity;
+main() {}
+void test(num a, num b, num Function() f) {}
+void expect(expected, actual) {}
+void throws(num Function() f) {}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4eeedfa
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline_modelled.expect
@@ -0,0 +1,40 @@
+const a0 = 0 ~/ 0;
+const a1 = 0.0 ~/ 0;
+const a2 = -0.0 ~/ 0;
+const a3 = double.nan ~/ 0;
+const a4 = double.infinity ~/ 0;
+const a5 = double.negativeInfinity ~/ 0;
+const b0 = 0 ~/ 0.0;
+const b1 = 0.0 ~/ 0.0;
+const b2 = -0.0 ~/ 0.0;
+const b3 = double.nan ~/ 0.0;
+const b4 = double.infinity ~/ 0.0;
+const b5 = double.negativeInfinity ~/ 0.0;
+const c0 = 0 ~/ -0.0;
+const c1 = 0.0 ~/ -0.0;
+const c2 = -0.0 ~/ -0.0;
+const c3 = double.nan ~/ -0.0;
+const c4 = double.infinity ~/ -0.0;
+const c5 = double.negativeInfinity ~/ -0.0;
+const d0 = 0 ~/ double.nan;
+const d1 = 0.0 ~/ double.nan;
+const d2 = -0.0 ~/ double.nan;
+const d3 = double.nan ~/ double.nan;
+const d4 = double.infinity ~/ double.nan;
+const d5 = double.negativeInfinity ~/ double.nan;
+const e0 = 0 ~/ double.infinity;
+const e1 = 0.0 ~/ double.infinity;
+const e2 = -0.0 ~/ double.infinity;
+const e3 = double.nan ~/ double.infinity;
+const e4 = double.infinity ~/ double.infinity;
+const e5 = double.negativeInfinity ~/ double.infinity;
+const f0 = 0 ~/ double.negativeInfinity;
+const f1 = 0.0 ~/ double.negativeInfinity;
+const f2 = -0.0 ~/ double.negativeInfinity;
+const f3 = double.nan ~/ double.negativeInfinity;
+const f4 = double.infinity ~/ double.negativeInfinity;
+const f5 = double.negativeInfinity ~/ double.negativeInfinity;
+main() {}
+void expect(expected, actual) {}
+void test(num a, num b, num Function() f) {}
+void throws(num Function() f) {}
diff --git a/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..f6ab576
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class _Y<T> {
+  const _Y();
+}
+
+class A<T> {
+  _Y<T> x;
+  A(this.x);
+}
+
+class B<T> extends A<T> {
+  B() : super(const _Y());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b4aec7
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A<T> {
+  A(this.x);
+  _Y<T> x;
+}
+
+class B<T> extends A<T> {
+  B() : super(const _Y());
+}
+
+class _Y<T> {
+  const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..4471e83
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  A.foo() : this.bar();
+  A.bar() : this.foo();
+  A.baz() : this.foo();
+  A() : this();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..051f9f7
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+  A() : this();
+  A.bar() : this.foo();
+  A.baz() : this.foo();
+  A.foo() : this.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline.expect
new file mode 100644
index 0000000..52ecd80
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class A {
+  A();
+}
+
+class B {
+  B(int x, double y, String s);
+}
+
+class C<T> {
+  C();
+}
+
+class D<T, S> {
+  D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52ecd80
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+  A();
+}
+
+class B {
+  B(int x, double y, String s);
+}
+
+class C<T> {
+  C();
+}
+
+class D<T, S> {
+  D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.textual_outline.expect
new file mode 100644
index 0000000..2516417
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class C1 {
+  int f;
+  C1() : =;
+}
+class C2 {
+  int f;
+  C2() : f=;
+}
+class C3 {
+  int f;
+  C3() : =f++;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline.expect b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline.expect
new file mode 100644
index 0000000..419aa23
--- /dev/null
+++ b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2384d20
--- /dev/null
+++ b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect
index 7bd3d63..9cdff84 100644
--- a/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method main() → dynamic {
@@ -18,14 +17,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t1.{core::List::add}(4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -48,14 +47,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t2.{core::Set::add}(4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t2.{core::Set::add}(i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -78,14 +77,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t3.{core::Map::[]=}(4, 4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t3.{core::Map::[]=}(i, i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..f4795c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4795c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index 1c89f63..0057f19 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -424,8 +424,8 @@
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
-import "dart:_internal" as _in;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → self::A*
@@ -496,7 +496,7 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
         #t10.{core::List::add}(#t11);
@@ -506,7 +506,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t12 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t13 = :sync-for-iterator.{core::Iterator::current};
         #t12.{core::Set::add}(#t13);
@@ -517,7 +517,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
         #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
@@ -528,7 +528,7 @@
   core::List<dynamic>* list21 = block {
     final core::List<dynamic>* #t16 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::List::add}(#t17);
@@ -538,7 +538,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t18 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Set::add}(#t19);
@@ -549,7 +549,7 @@
   core::Map<core::String*, dynamic>* map21 = block {
     final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, dynamic>* #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
@@ -560,7 +560,7 @@
   core::List<core::List<core::int*>*>* list22 = block {
     final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t23 = :sync-for-iterator.{core::Iterator::current};
         #t22.{core::List::add}(#t23);
@@ -570,7 +570,7 @@
   core::Set<core::List<core::int*>*>* set22 = block {
     final core::Set<core::List<core::int*>*>* #t24 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
         #t24.{core::Set::add}(#t25);
@@ -581,7 +581,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 = :sync-for-iterator.{core::Iterator::current};
         #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
@@ -593,7 +593,7 @@
     final core::List<core::int*>* #t28 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
           #t28.{core::List::add}(#t29);
@@ -604,7 +604,7 @@
     final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t31 = :sync-for-iterator.{core::Iterator::current};
           #t30.{core::Set::add}(#t31);
@@ -616,7 +616,7 @@
     final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t33 = :sync-for-iterator.{core::Iterator::current};
           #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
@@ -628,7 +628,7 @@
     final core::List<dynamic>* #t34 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
           #t34.{core::List::add}(#t35);
@@ -639,7 +639,7 @@
     final core::Set<dynamic>* #t36 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t37 = :sync-for-iterator.{core::Iterator::current};
           #t36.{core::Set::add}(#t37);
@@ -651,7 +651,7 @@
     final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, dynamic>* #t39 = :sync-for-iterator.{core::Iterator::current};
           #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
@@ -663,7 +663,7 @@
     final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t41 = :sync-for-iterator.{core::Iterator::current};
           #t40.{core::List::add}(#t41);
@@ -674,7 +674,7 @@
     final core::Set<core::List<core::int*>*>* #t42 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t43 = :sync-for-iterator.{core::Iterator::current};
           #t42.{core::Set::add}(#t43);
@@ -686,7 +686,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 = :sync-for-iterator.{core::Iterator::current};
           #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
@@ -697,7 +697,7 @@
   core::List<core::List<core::int*>*>* list40 = block {
     final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
         #t46.{core::List::add}(#t47);
@@ -707,7 +707,7 @@
   core::Set<core::List<core::int*>*>* set40 = block {
     final core::Set<core::List<core::int*>*>* #t48 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t49 = :sync-for-iterator.{core::Iterator::current};
         #t48.{core::Set::add}(#t49);
@@ -721,7 +721,7 @@
   core::List<core::List<core::int*>*>* list41 = block {
     final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t51 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t52 = #t51.{core::Set::add}(<core::int*>[]) in #t51).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t51 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t52 = #t51.{core::Set::add}(<core::int*>[]) in #t51).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t53 = :sync-for-iterator.{core::Iterator::current};
         #t50.{core::List::add}(#t53);
@@ -731,7 +731,7 @@
   core::Set<core::List<core::int*>*>* set41 = block {
     final core::Set<core::List<core::int*>*>* #t54 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t56 = #t55.{core::Set::add}(<core::int*>[]) in #t55).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t56 = #t55.{core::Set::add}(<core::int*>[]) in #t55).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t57 = :sync-for-iterator.{core::Iterator::current};
         #t54.{core::Set::add}(#t57);
@@ -743,7 +743,7 @@
     final core::List<core::List<core::int*>*>* #t58 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
           #t58.{core::List::add}(#t59);
@@ -754,7 +754,7 @@
     final core::Set<core::List<core::int*>*>* #t60 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t61 = :sync-for-iterator.{core::Iterator::current};
           #t60.{core::Set::add}(#t61);
@@ -766,7 +766,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 = :sync-for-iterator.{core::Iterator::current};
           #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
@@ -777,7 +777,7 @@
   core::List<core::int*>* list50 = block {
     final core::List<core::int*>* #t64 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t65 = :sync-for-iterator.{core::Iterator::current};
         #t64.{core::List::add}(#t65);
@@ -787,7 +787,7 @@
   core::Set<core::int*>* set50 = block {
     final core::Set<core::int*>* #t66 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t67 = :sync-for-iterator.{core::Iterator::current};
         #t66.{core::Set::add}(#t67);
@@ -798,7 +798,7 @@
   core::Map<core::String*, core::int*>* map50 = block {
     final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t69 = :sync-for-iterator.{core::Iterator::current};
         #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
@@ -809,7 +809,7 @@
   core::List<core::int*>* list51 = block {
     final core::List<core::int*>* #t70 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>() in #t71).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>() in #t71).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t72 = :sync-for-iterator.{core::Iterator::current};
         #t70.{core::List::add}(#t72);
@@ -819,7 +819,7 @@
   core::Set<core::int*>* set51 = block {
     final core::Set<core::int*>* #t73 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>() in #t74).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>() in #t74).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t75 = :sync-for-iterator.{core::Iterator::current};
         #t73.{core::Set::add}(#t75);
@@ -831,7 +831,7 @@
     final core::List<core::int*>* #t76 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t77 = :sync-for-iterator.{core::Iterator::current};
           #t76.{core::List::add}(#t77);
@@ -842,7 +842,7 @@
     final core::Set<core::int*>* #t78 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t79 = :sync-for-iterator.{core::Iterator::current};
           #t78.{core::Set::add}(#t79);
@@ -854,7 +854,7 @@
     final core::Map<core::String*, core::int*>* #t80 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
           #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
@@ -865,7 +865,7 @@
   core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t82 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
         #t82.{core::List::add}(#t83);
@@ -875,7 +875,7 @@
   core::Set<core::List<core::int*>*>* set60 = block {
     final core::Set<core::List<core::int*>*>* #t84 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t85 = :sync-for-iterator.{core::Iterator::current};
         #t84.{core::Set::add}(#t85);
@@ -886,7 +886,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t86 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t87 = :sync-for-iterator.{core::Iterator::current};
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
@@ -898,7 +898,7 @@
     final core::List<core::List<core::int*>*>* #t88 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t89 = :sync-for-iterator.{core::Iterator::current};
           #t88.{core::List::add}(#t89);
@@ -909,7 +909,7 @@
     final core::Set<core::List<core::int*>*>* #t90 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t91 = :sync-for-iterator.{core::Iterator::current};
           #t90.{core::Set::add}(#t91);
@@ -921,7 +921,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t92 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t93 = :sync-for-iterator.{core::Iterator::current};
           #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
@@ -979,14 +979,14 @@
   core::List<core::num*>* list81 = block {
     final core::List<core::num*>* #t101 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t102 = :sync-for-iterator.{core::Iterator::current};
         #t101.{core::List::add}(#t102);
       }
     }
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t103 = :sync-for-iterator.{core::Iterator::current};
         #t101.{core::List::add}(#t103);
@@ -996,14 +996,14 @@
   core::Set<core::num*>* set81 = block {
     final core::Set<core::num*>* #t104 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t105 = :sync-for-iterator.{core::Iterator::current};
         #t104.{core::Set::add}(#t105);
       }
     }
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t106 = :sync-for-iterator.{core::Iterator::current};
         #t104.{core::Set::add}(#t106);
@@ -1014,14 +1014,14 @@
   core::Map<core::String*, core::num*>* map81 = block {
     final core::Map<core::String*, core::num*>* #t107 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapToInt.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t108 = :sync-for-iterator.{core::Iterator::current};
         #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value});
       }
     }
     else {
-      core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::double*>*>*>(mapToDouble.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = mapToDouble.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t109 = :sync-for-iterator.{core::Iterator::current};
         #t107.{core::Map::[]=}(#t109.{core::MapEntry::key}, #t109.{core::MapEntry::value});
@@ -1032,14 +1032,14 @@
   core::List<dynamic>* list82 = block {
     final core::List<dynamic>* #t110 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t111 = :sync-for-iterator.{core::Iterator::current};
         #t110.{core::List::add}(#t111);
       }
     }
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t112 = :sync-for-iterator.{core::Iterator::current};
         #t110.{core::List::add}(#t112);
@@ -1049,14 +1049,14 @@
   core::Set<dynamic>* set82 = block {
     final core::Set<dynamic>* #t113 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t114 = :sync-for-iterator.{core::Iterator::current};
         #t113.{core::Set::add}(#t114);
       }
     }
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t115 = :sync-for-iterator.{core::Iterator::current};
         #t113.{core::Set::add}(#t115);
@@ -1072,7 +1072,7 @@
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t117 = :sync-for-iterator.{core::Iterator::current};
         #t116.{core::Set::add}(#t117);
@@ -1085,7 +1085,7 @@
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t118.{core::List::add}(42);
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t119 = :sync-for-iterator.{core::Iterator::current};
         #t118.{core::List::add}(#t119);
@@ -1095,7 +1095,7 @@
   core::Set<core::num*>* set83 = block {
     final core::Set<core::num*>* #t120 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t121 = :sync-for-iterator.{core::Iterator::current};
         #t120.{core::Set::add}(#t121);
@@ -1108,7 +1108,7 @@
   core::Map<core::String*, core::num*>* map83 = block {
     final core::Map<core::String*, core::num*>* #t122 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapToInt.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t123 = :sync-for-iterator.{core::Iterator::current};
         #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value});
@@ -1138,7 +1138,7 @@
   core::List<core::int*>* list91 = block {
     final core::List<core::int*>* #t127 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t128 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1151,7 +1151,7 @@
   core::Set<core::int*>* set91 = block {
     final core::Set<core::int*>* #t130 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t131 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1165,7 +1165,7 @@
   core::Map<core::String*, core::int*>* map91 = block {
     final core::Map<core::String*, core::int*>* #t133 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t134 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1220,9 +1220,9 @@
   block {
     final core::List<core::int*>* #t146 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t148 = :sync-for-iterator.{core::Iterator::current};
         #t146.{core::List::add}(#t148);
@@ -1232,9 +1232,9 @@
   block {
     final core::Set<core::int*>* #t149 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t151 = :sync-for-iterator.{core::Iterator::current};
         #t149.{core::Set::add}(#t151);
@@ -1245,9 +1245,9 @@
   block {
     final core::Map<core::String*, core::int*>* #t152 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                              ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}).{core::Iterable::iterator};
+                                              ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t154 = :sync-for-iterator.{core::Iterator::current};
         #t152.{core::Map::[]=}(#t154.{core::MapEntry::key}, #t154.{core::MapEntry::value});
@@ -1509,7 +1509,7 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t197 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t198 = :sync-for-iterator.{core::Iterator::current};
         #t197.{core::List::add}(#t198);
@@ -1519,7 +1519,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t199 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t200 = :sync-for-iterator.{core::Iterator::current};
         #t199.{core::Set::add}(#t200);
@@ -1530,7 +1530,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t201 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t202 = :sync-for-iterator.{core::Iterator::current};
         #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
@@ -1541,7 +1541,7 @@
   core::List<dynamic>* list21 = block {
     final core::List<dynamic>* #t203 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t204 = :sync-for-iterator.{core::Iterator::current};
         #t203.{core::List::add}(#t204);
@@ -1551,7 +1551,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t205 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t206 = :sync-for-iterator.{core::Iterator::current};
         #t205.{core::Set::add}(#t206);
@@ -1562,7 +1562,7 @@
   core::Map<core::String*, dynamic>* map21 = block {
     final core::Map<core::String*, dynamic>* #t207 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, dynamic>* #t208 = :sync-for-iterator.{core::Iterator::current};
         #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value});
@@ -1573,7 +1573,7 @@
   core::List<core::List<core::int*>*>* list22 = block {
     final core::List<core::List<core::int*>*>* #t209 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t210 = :sync-for-iterator.{core::Iterator::current};
         #t209.{core::List::add}(#t210);
@@ -1583,7 +1583,7 @@
   core::Set<core::List<core::int*>*>* set22 = block {
     final core::Set<core::List<core::int*>*>* #t211 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t212 = :sync-for-iterator.{core::Iterator::current};
         #t211.{core::Set::add}(#t212);
@@ -1594,7 +1594,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t214 = :sync-for-iterator.{core::Iterator::current};
         #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value});
@@ -1606,7 +1606,7 @@
     final core::List<core::int*>* #t215 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t216 = :sync-for-iterator.{core::Iterator::current};
           #t215.{core::List::add}(#t216);
@@ -1617,7 +1617,7 @@
     final core::Set<core::int*>* #t217 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t218 = :sync-for-iterator.{core::Iterator::current};
           #t217.{core::Set::add}(#t218);
@@ -1629,7 +1629,7 @@
     final core::Map<core::String*, core::int*>* #t219 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t220 = :sync-for-iterator.{core::Iterator::current};
           #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
@@ -1641,7 +1641,7 @@
     final core::List<dynamic>* #t221 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t222 = :sync-for-iterator.{core::Iterator::current};
           #t221.{core::List::add}(#t222);
@@ -1652,7 +1652,7 @@
     final core::Set<dynamic>* #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t224 = :sync-for-iterator.{core::Iterator::current};
           #t223.{core::Set::add}(#t224);
@@ -1664,7 +1664,7 @@
     final core::Map<core::String*, dynamic>* #t225 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, dynamic>* #t226 = :sync-for-iterator.{core::Iterator::current};
           #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
@@ -1676,7 +1676,7 @@
     final core::List<core::List<core::int*>*>* #t227 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t228 = :sync-for-iterator.{core::Iterator::current};
           #t227.{core::List::add}(#t228);
@@ -1687,7 +1687,7 @@
     final core::Set<core::List<core::int*>*>* #t229 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t230 = :sync-for-iterator.{core::Iterator::current};
           #t229.{core::Set::add}(#t230);
@@ -1699,7 +1699,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t231 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t232 = :sync-for-iterator.{core::Iterator::current};
           #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value});
@@ -1710,7 +1710,7 @@
   core::List<core::List<core::int*>*>* list40 = block {
     final core::List<core::List<core::int*>*>* #t233 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t234 = :sync-for-iterator.{core::Iterator::current};
         #t233.{core::List::add}(#t234);
@@ -1720,7 +1720,7 @@
   core::Set<core::List<core::int*>*>* set40 = block {
     final core::Set<core::List<core::int*>*>* #t235 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t236 = :sync-for-iterator.{core::Iterator::current};
         #t235.{core::Set::add}(#t236);
@@ -1731,7 +1731,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map40 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t237 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t238 = :sync-for-iterator.{core::Iterator::current};
         #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value});
@@ -1742,7 +1742,7 @@
   core::List<core::List<core::int*>*>* list41 = block {
     final core::List<core::List<core::int*>*>* #t239 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t241 = #t240.{core::Set::add}(<core::int*>[]) in #t240).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t241 = #t240.{core::Set::add}(<core::int*>[]) in #t240).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t242 = :sync-for-iterator.{core::Iterator::current};
         #t239.{core::List::add}(#t242);
@@ -1752,7 +1752,7 @@
   core::Set<core::List<core::int*>*>* set41 = block {
     final core::Set<core::List<core::int*>*>* #t243 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t244 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t245 = #t244.{core::Set::add}(<core::int*>[]) in #t244).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t244 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t245 = #t244.{core::Set::add}(<core::int*>[]) in #t244).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t246 = :sync-for-iterator.{core::Iterator::current};
         #t243.{core::Set::add}(#t246);
@@ -1764,7 +1764,7 @@
     final core::List<core::List<core::int*>*>* #t247 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t248 = :sync-for-iterator.{core::Iterator::current};
           #t247.{core::List::add}(#t248);
@@ -1775,7 +1775,7 @@
     final core::Set<core::List<core::int*>*>* #t249 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t250 = :sync-for-iterator.{core::Iterator::current};
           #t249.{core::Set::add}(#t250);
@@ -1787,7 +1787,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t251 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t252 = :sync-for-iterator.{core::Iterator::current};
           #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value});
@@ -1798,7 +1798,7 @@
   core::List<core::int*>* list50 = block {
     final core::List<core::int*>* #t253 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t254 = :sync-for-iterator.{core::Iterator::current};
         #t253.{core::List::add}(#t254);
@@ -1808,7 +1808,7 @@
   core::Set<core::int*>* set50 = block {
     final core::Set<core::int*>* #t255 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t256 = :sync-for-iterator.{core::Iterator::current};
         #t255.{core::Set::add}(#t256);
@@ -1819,7 +1819,7 @@
   core::Map<core::String*, core::int*>* map50 = block {
     final core::Map<core::String*, core::int*>* #t257 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t258 = :sync-for-iterator.{core::Iterator::current};
         #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value});
@@ -1830,7 +1830,7 @@
   core::List<core::int*>* list51 = block {
     final core::List<core::int*>* #t259 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>() in #t260).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>() in #t260).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t261 = :sync-for-iterator.{core::Iterator::current};
         #t259.{core::List::add}(#t261);
@@ -1840,7 +1840,7 @@
   core::Set<core::int*>* set51 = block {
     final core::Set<core::int*>* #t262 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>() in #t263).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>() in #t263).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t264 = :sync-for-iterator.{core::Iterator::current};
         #t262.{core::Set::add}(#t264);
@@ -1852,7 +1852,7 @@
     final core::List<core::int*>* #t265 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t266 = :sync-for-iterator.{core::Iterator::current};
           #t265.{core::List::add}(#t266);
@@ -1863,7 +1863,7 @@
     final core::Set<core::int*>* #t267 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t268 = :sync-for-iterator.{core::Iterator::current};
           #t267.{core::Set::add}(#t268);
@@ -1874,7 +1874,7 @@
   core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t269 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t270 = :sync-for-iterator.{core::Iterator::current};
         #t269.{core::List::add}(#t270);
@@ -1884,7 +1884,7 @@
   core::Set<core::List<core::int*>*>* set60 = block {
     final core::Set<core::List<core::int*>*>* #t271 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t272 = :sync-for-iterator.{core::Iterator::current};
         #t271.{core::Set::add}(#t272);
@@ -1895,7 +1895,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t273 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t274 = :sync-for-iterator.{core::Iterator::current};
         #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
@@ -1907,7 +1907,7 @@
     final core::List<core::List<core::int*>*>* #t275 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t276 = :sync-for-iterator.{core::Iterator::current};
           #t275.{core::List::add}(#t276);
@@ -1918,7 +1918,7 @@
     final core::Set<core::List<core::int*>*>* #t277 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t278 = :sync-for-iterator.{core::Iterator::current};
           #t277.{core::Set::add}(#t278);
@@ -1930,7 +1930,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t280 = :sync-for-iterator.{core::Iterator::current};
           #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value});
@@ -2005,14 +2005,14 @@
     final core::List<core::num*>* #t290 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t291 = :sync-for-iterator.{core::Iterator::current};
           #t290.{core::List::add}(#t291);
         }
       }
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t292 = :sync-for-iterator.{core::Iterator::current};
           #t290.{core::List::add}(#t292);
@@ -2023,14 +2023,14 @@
     final core::Set<core::num*>* #t293 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t294 = :sync-for-iterator.{core::Iterator::current};
           #t293.{core::Set::add}(#t294);
         }
       }
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t295 = :sync-for-iterator.{core::Iterator::current};
           #t293.{core::Set::add}(#t295);
@@ -2042,14 +2042,14 @@
     final core::Map<core::String*, core::num*>* #t296 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t297 = :sync-for-iterator.{core::Iterator::current};
           #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value});
         }
       }
       else {
-        core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::double*>*>*>(mapStringDouble.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = mapStringDouble.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t298 = :sync-for-iterator.{core::Iterator::current};
           #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value});
@@ -2061,14 +2061,14 @@
     final core::List<dynamic>* #t299 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t300 = :sync-for-iterator.{core::Iterator::current};
           #t299.{core::List::add}(#t300);
         }
       }
       else {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t301 = :sync-for-iterator.{core::Iterator::current};
           #t299.{core::List::add}(#t301);
@@ -2079,14 +2079,14 @@
     final core::Set<dynamic>* #t302 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t303 = :sync-for-iterator.{core::Iterator::current};
           #t302.{core::Set::add}(#t303);
         }
       }
       else {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t304 = :sync-for-iterator.{core::Iterator::current};
           #t302.{core::Set::add}(#t304);
@@ -2098,14 +2098,14 @@
     final core::Map<dynamic, dynamic>* #t305 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, dynamic>* #t306 = :sync-for-iterator.{core::Iterator::current};
           #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value});
         }
       }
       else {
-        core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, dynamic>* #t307 = :sync-for-iterator.{core::Iterator::current};
           #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value});
@@ -2119,7 +2119,7 @@
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t308.{core::List::add}(42);
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t309 = :sync-for-iterator.{core::Iterator::current};
           #t308.{core::List::add}(#t309);
@@ -2130,7 +2130,7 @@
     final core::Set<core::num*>* #t310 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t311 = :sync-for-iterator.{core::Iterator::current};
           #t310.{core::Set::add}(#t311);
@@ -2144,7 +2144,7 @@
     final core::Map<core::String*, core::num*>* #t312 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t313 = :sync-for-iterator.{core::Iterator::current};
           #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value});
@@ -2174,7 +2174,7 @@
   core::List<core::int*>* list91 = block {
     final core::List<core::int*>* #t317 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t318 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2187,7 +2187,7 @@
   core::Set<core::int*>* set91 = block {
     final core::Set<core::int*>* #t320 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t321 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2201,7 +2201,7 @@
   core::Map<core::String*, core::int*>* map91 = block {
     final core::Map<core::String*, core::int*>* #t323 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t324 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2231,7 +2231,7 @@
   core::List<core::int*>* list110 = block {
     final core::List<core::int*>* #t333 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t333.{core::List::add}(i);
@@ -2241,7 +2241,7 @@
   core::Set<core::int*>* set110 = block {
     final core::Set<core::int*>* #t334 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t334.{core::Set::add}(i);
@@ -2252,7 +2252,7 @@
   core::Map<core::String*, core::int*>* map110 = block {
     final core::Map<core::String*, core::int*>* #t335 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t335.{core::Map::[]=}("bar", i);
@@ -2263,7 +2263,7 @@
   core::List<core::int*>* list120 = block {
     final core::List<core::int*>* #t336 = <core::int*>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t336.{core::List::add}(i as{TypeError,ForDynamic} core::int*);
@@ -2273,7 +2273,7 @@
   core::Set<core::int*>* set120 = block {
     final core::Set<core::int*>* #t337 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t337.{core::Set::add}(i as{TypeError,ForDynamic} core::int*);
@@ -2284,7 +2284,7 @@
   core::Map<core::String*, core::int*>* map120 = block {
     final core::Map<core::String*, core::int*>* #t338 = <core::String*, core::int*>{};
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t338.{core::Map::[]=}("bar", i as{TypeError,ForDynamic} core::int*);
@@ -2312,8 +2312,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -2354,9 +2354,9 @@
         block {
           final core::List<core::int*>* #t350 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t352 = :sync-for-iterator.{core::Iterator::current};
               #t350.{core::List::add}(#t352);
@@ -2366,9 +2366,9 @@
         block {
           final core::Set<core::int*>* #t353 = col::LinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t355 = :sync-for-iterator.{core::Iterator::current};
               #t353.{core::Set::add}(#t355);
@@ -2379,11 +2379,11 @@
         block {
           final core::Map<core::int*, core::int*>* #t356 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                      ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                            ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}).{core::Iterable::iterator};
+                                                            ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::MapEntry<core::int*, core::int*>* #t359 = :sync-for-iterator.{core::Iterator::current};
               #t356.{core::Map::[]=}(#t359.{core::MapEntry::key}, #t359.{core::MapEntry::value});
@@ -2519,7 +2519,7 @@
         block {
           final core::List<core::int*>* #t376 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2534,7 +2534,7 @@
         block {
           final core::Set<core::int*>* #t378 = col::LinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t379 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2550,7 +2550,7 @@
         block {
           final core::Map<core::String*, core::int*>* #t380 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t381 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2566,7 +2566,7 @@
         core::List<dynamic>* list10 = block {
           final core::List<dynamic>* #t382 = <dynamic>[];
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2579,7 +2579,7 @@
         core::Set<dynamic>* set10 = block {
           final core::Set<dynamic>* #t384 = col::LinkedHashSet::•<dynamic>();
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2593,7 +2593,7 @@
         core::Map<core::String*, dynamic>* map10 = block {
           final core::Map<core::String*, dynamic>* #t386 = <core::String*, dynamic>{};
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2607,11 +2607,11 @@
         core::List<core::int*>* list20 = block {
           final core::List<core::int*>* #t388 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                ^" in "not" as{TypeError} core::int*, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                                      ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t388.{core::List::add}(i);
@@ -2621,11 +2621,11 @@
         core::Set<core::int*>* set20 = block {
           final core::Set<core::int*>* #t391 = col::LinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                                     ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                     ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t391.{core::Set::add}(i);
@@ -2636,11 +2636,11 @@
         core::Map<core::String*, core::int*>* map20 = block {
           final core::Map<core::String*, core::int*>* #t394 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                                     ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                     ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t394.{core::Map::[]=}("bar", i);
@@ -2650,7 +2650,7 @@
         } =>#t394;
         final core::List<dynamic>* #t397 = <dynamic>[];
         {
-          dynamic :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2677,7 +2677,7 @@
         core::List<dynamic>* list30 = block {} =>#t397;
         final core::Set<dynamic>* #t402 = col::LinkedHashSet::•<dynamic>();
         {
-          dynamic :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2706,7 +2706,7 @@
         } =>#t402;
         final core::Map<core::String*, dynamic>* #t407 = <core::String*, dynamic>{};
         {
-          dynamic :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2735,7 +2735,7 @@
         } =>#t407;
         final core::List<core::int*>* #t412 = <core::int*>[];
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                          ^" in "not" as{TypeError} core::int*, let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
@@ -2763,7 +2763,7 @@
         core::List<core::int*>* list40 = block {} =>#t412;
         final core::Set<core::int*>* #t418 = col::LinkedHashSet::•<core::int*>();
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
@@ -2793,7 +2793,7 @@
         } =>#t418;
         final core::Map<core::String*, core::int*>* #t424 = <core::String*, core::int*>{};
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t426 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
@@ -2865,13 +2865,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..e011ec5
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+oracle<T>([T t]) => true;
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+    Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testForElement(
+    dynamic dynVar,
+    List<int> listInt,
+    List<double> listDouble,
+    int index,
+    Map<String, int> mapStringInt,
+    Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+
+class A {}
+
+class B extends A {
+  int get foo => 42;
+}
+
+testPromotion(A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a8e5b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+class A {}
+
+class B extends A {
+  int get foo => 42;
+}
+
+main() {}
+oracle<T>([T t]) => true;
+testForElement(
+    dynamic dynVar,
+    List<int> listInt,
+    List<double> listDouble,
+    int index,
+    Map<String, int> mapStringInt,
+    Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+    Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testPromotion(A a) {}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart b/pkg/front_end/testcases/general/covariant_equals.dart
new file mode 100644
index 0000000..474dfbd
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {
+  a == a; // ok
+  a == b; // ok
+  a == c_dynamic; // error
+  a == c_int; // error
+  a == c_string; // error
+  a == d; // error
+
+  b == a; // ok
+  b == b; // ok
+  b == c_dynamic; // error
+  b == c_int; // error
+  b == c_string; // error
+  b == d; // error
+
+  c_dynamic == a; // error
+  c_dynamic == b; // error
+  c_dynamic == c_dynamic; // ok
+  c_dynamic == c_int; // ok
+  c_dynamic == c_string; // ok
+  c_dynamic == d; // ok
+
+  c_int == a; // error
+  c_int == b; // error
+  c_int == c_dynamic; // ok
+  c_int == c_int; // ok
+  c_int == c_string; // error
+  c_int == d; // ok}
+
+  c_string == a; // error
+  c_string == b; // error
+  c_string == c_dynamic; // ok
+  c_string == c_int; // error
+  c_string == c_string; // ok
+  c_string == d; // error
+
+  d == a; // error
+  d == b; // error
+  d == c_dynamic; // ok
+  d == c_int; // ok
+  d == c_string; // error
+  d == d; // ok
+}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.outline.expect b/pkg/front_end/testcases/general/covariant_equals.dart.outline.expect
new file mode 100644
index 0000000..d521bc4
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    ;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    ;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    ;
+}
+static method main() → dynamic
+  ;
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.strong.expect b/pkg/front_end/testcases/general/covariant_equals.dart.strong.expect
new file mode 100644
index 0000000..aa641a4
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.strong.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+//  - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    return true;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError} self::A*);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError} self::A*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_dynamic as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+ - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError} self::C<core::String*>*);
+  d.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/general/covariant_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..aa641a4
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.strong.transformed.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+//  - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/general/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    return true;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError} self::A*);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError} self::A*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_dynamic as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+ - 'D' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError} self::C<core::String*>*);
+  d.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline.expect b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..cfe571a
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cfe571a
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline.expect b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..4fe7336
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+typedef void Callback<T>(T x);
+
+class Foo<T> {
+  final T finalField;
+  final Callback<T> callbackField;
+  T mutableField;
+  Callback<T> mutableCallbackField;
+  Foo(this.finalField, this.callbackField);
+  void method(T x) {}
+  set setter(T x) {}
+  void withCallback(Callback<T> callback) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40004ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Foo<T> {
+  Callback<T> mutableCallbackField;
+  Foo(this.finalField, this.callbackField);
+  T mutableField;
+  final Callback<T> callbackField;
+  final T finalField;
+  set setter(T x) {}
+  void method(T x) {}
+  void withCallback(Callback<T> callback) {}
+}
+
+main() {}
+typedef void Callback<T>(T x);
diff --git a/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..914deb7
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class A {
+  void foo(covariant num x) {}
+}
+
+class B {
+  void foo(num x) {}
+}
+
+class C {
+  void foo(num x) {}
+}
+
+class D extends A with B implements C {
+  void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..914deb7
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+  void foo(covariant num x) {}
+}
+
+class B {
+  void foo(num x) {}
+}
+
+class C {
+  void foo(num x) {}
+}
+
+class D extends A with B implements C {
+  void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/cycles.dart.textual_outline.expect b/pkg/front_end/testcases/general/cycles.dart.textual_outline.expect
new file mode 100644
index 0000000..362437f
--- /dev/null
+++ b/pkg/front_end/testcases/general/cycles.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/cycles.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/cycles.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..362437f
--- /dev/null
+++ b/pkg/front_end/testcases/general/cycles.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general/default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..c04eb61
--- /dev/null
+++ b/pkg/front_end/testcases/general/default_values.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+topLevel([a = 42]) => a;
+main() {}
diff --git a/pkg/front_end/testcases/general/default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c95e3f3
--- /dev/null
+++ b/pkg/front_end/testcases/general/default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+topLevel([a = 42]) => a;
diff --git a/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..5139710
--- /dev/null
+++ b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5139710
--- /dev/null
+++ b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline.expect b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline.expect
new file mode 100644
index 0000000..fee39b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+method<T>(T a, T b) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..caff637
--- /dev/null
+++ b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+method<T>(T a, T b) {}
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..17b7541
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class Dupe {}
+
+class Dupe {}
+
+class C {
+  Dupe.a b;
+  dupe.C d;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8169867
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class C {
+  Dupe.a b;
+  dupe.C d;
+}
+
+class Dupe {}
+
+class Dupe {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_declarations.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_declarations.dart.textual_outline.expect
new file mode 100644
index 0000000..6e1f5b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_declarations.dart.textual_outline.expect
@@ -0,0 +1,33 @@
+part "duplicated_declarations_part.dart"; import 'duplicated_declarations_lib.dart' as Typedef; import 'duplicated_declarations_lib.dart' as Typedef;
+typedef Typedef = void Function();
+typedef Typedef = Object Function();
+import 'duplicated_declarations_lib.dart' as Typedef;
+typedef void OldTypedef();
+typedef Object OldTypedef();
+var field = "1st";
+var field = "2nd";
+main() { }
+main() { }
+foo() { }
+class C {
+  C(a);
+  C(a, b);
+  var field = "1st";
+  var field = "2nd";
+  m() { }
+  m() { }
+  static s() { }
+  static s() { }
+  static f() => s;
+}
+class Sub extends C {
+  Sub() : super(null);
+  m() => super.m();
+}
+class C {
+  C._();
+}
+enum Enum { Enum, a, a, b, }
+enum Enum { a, b, c, }
+enum AnotherEnum { a, b, c, _name, index, toString, values, }
+useAnotherEnum() { }
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..541f502
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  int a;
+  int a;
+  A(this.a);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1261a73
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+  A(this.a);
+  int a;
+  int a;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline.expect
new file mode 100644
index 0000000..0b2371b
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  static m({int a: 0}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..461825b
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  static m({int a: 0}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.expect b/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.expect
index 6211e60..2bac3e8 100644
--- a/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.expect
+++ b/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.expect
@@ -11,6 +11,6 @@
 import "dart:core";
 
 static method testDynamic() → invalid-type
-  return 0 as{TypeError} invalid-type;
+  return 0;
 static method testVoid() → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.transformed.expect b/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.transformed.expect
index 6211e60..2bac3e8 100644
--- a/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/dynamic_and_void.dart.strong.transformed.expect
@@ -11,6 +11,6 @@
 import "dart:core";
 
 static method testDynamic() → invalid-type
-  return 0 as{TypeError} invalid-type;
+  return 0;
 static method testVoid() → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline.expect b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline.expect
new file mode 100644
index 0000000..64c5d3e
--- /dev/null
+++ b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+void testVoid() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd30a61
--- /dev/null
+++ b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+main() {}
+void testVoid() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline.expect
new file mode 100644
index 0000000..5332212
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5332212
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline.expect
new file mode 100644
index 0000000..0bb920e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bb920e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline.expect
new file mode 100644
index 0000000..6ee4f4b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ee4f4b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline.expect
new file mode 100644
index 0000000..9dce0c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9dce0c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline.expect
new file mode 100644
index 0000000..3097149
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3097149
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline.expect
new file mode 100644
index 0000000..3f290d4
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3f290d4
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart
new file mode 100644
index 0000000..fb84c75
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart
@@ -0,0 +1,5 @@
+Future<void> f() => Future.value();
+
+void g() {
+  await f();
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.outline.expect
new file mode 100644
index 0000000..338ee14
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.outline.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:async" as asy;
+
+static method f() → asy::Future<void>*
+  ;
+static method g() → void
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.strong.expect
new file mode 100644
index 0000000..7569116
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.strong.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart:4:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+//   await f();
+//   ^^^^^
+//
+import self as self;
+import "dart:async" as asy;
+
+static method f() → asy::Future<void>*
+  return asy::Future::value<void>();
+static method g() → void {
+  invalid-expression "pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart:4:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+  await f();
+  ^^^^^";
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..7569116
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart:4:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+//   await f();
+//   ^^^^^
+//
+import self as self;
+import "dart:async" as asy;
+
+static method f() → asy::Future<void>*
+  return asy::Future::value<void>();
+static method g() → void {
+  invalid-expression "pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart:4:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+  await f();
+  ^^^^^";
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline.expect
new file mode 100644
index 0000000..055b8c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+Future<void> f() => Future.value();
+void g() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..055b8c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+Future<void> f() => Future.value();
+void g() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart
new file mode 100644
index 0000000..18fd65a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart
@@ -0,0 +1,41 @@
+class Foo {
+  foo.x() {
+    // Not OK.
+  }
+  foo.x() : initializer = true {
+    // Not OK.
+  }
+  foo() : initializer = true {
+    // Not OK.
+  }
+  get Foo => 0;
+  get Foo {
+    return 0;
+  }
+  get Foo.X => 0;
+  get Foo.X {
+    return 0;
+  }
+  get Foo : bla = null => 0;
+  get Foo.X : bla = null {
+    return 0;
+  }
+  set Foo => 0;
+  set Foo {
+    return 0;
+  }
+  set Foo.X => 0;
+  set Foo.X {
+    return 0;
+  }
+  set Foo : bla = null => 0;
+  set Foo.X : bla = null {
+    return 0;
+  }
+  external Foo() : bla = null;
+  external Foo.X() : bla = null {
+    return 0;
+  }
+  int Foo;
+  int A, Foo, B;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.outline.expect
new file mode 100644
index 0000000..19f76f8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.outline.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:2:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:3: Error: 'Foo.x' is already declared in this scope.
+//   foo.x() : initializer = true {
+//   ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:2:3: Context: Previous declaration of 'Foo.x'.
+//   foo.x() {
+//   ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:11:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Error: 'Foo' is already declared in this scope.
+//   get Foo {
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:11:7: Context: Previous declaration of 'Foo'.
+//   get Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Error: 'Foo.X' is already declared in this scope.
+//   get Foo.X {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X => 0;
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo : bla = null => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X : bla = null {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X : bla = null {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Error: 'Foo.X' is already declared in this scope.
+//   get Foo.X : bla = null {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: 'Foo' is already declared in this scope.
+//   set Foo {
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Context: Previous declaration of 'Foo'.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X => 0;
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X : bla = null {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X => 0;
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo : bla = null => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Error: 'Foo' is already declared in this scope.
+//   set Foo : bla = null => 0;
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:7: Context: Previous declaration of 'Foo'.
+//   get Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X : bla = null {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X : bla = null {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X : bla = null {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:35:18: Error: An external constructor can't have any initializers.
+//   external Foo() : bla = null;
+//                  ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:35:12: Error: 'Foo' is already declared in this scope.
+//   external Foo() : bla = null;
+//            ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Context: Previous declaration of 'Foo'.
+//   set Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:33: Error: An external or native method can't have a body.
+//   external Foo.X() : bla = null {
+//                                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:20: Error: An external constructor can't have any initializers.
+//   external Foo.X() : bla = null {
+//                    ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:12: Error: 'Foo.X' is already declared in this scope.
+//   external Foo.X() : bla = null {
+//            ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X : bla = null {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   int Foo;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Error: 'Foo' is already declared in this scope.
+//   int Foo;
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Context: Previous declaration of 'Foo'.
+//   get Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   int A, Foo, B;
+//          ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: 'Foo' is already declared in this scope.
+//   int A, Foo, B;
+//          ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Context: Previous declaration of 'Foo'.
+//   int Foo;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: Conflicts with member 'Foo'.
+//   set Foo {
+//       ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: Conflicts with setter 'Foo'.
+//   int A, Foo, B;
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int* A;
+  field core::int* B;
+  constructor x() → self::Foo*
+    ;
+  constructor foo() → self::Foo*
+    ;
+  constructor X() → self::Foo*
+    ;
+  constructor •() → self::Foo*
+    ;
+  get Foo() → dynamic
+    ;
+  set Foo(dynamic #synthetic) → void
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.strong.expect
new file mode 100644
index 0000000..ed0fc2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.strong.expect
@@ -0,0 +1,363 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:2:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:3: Error: 'Foo.x' is already declared in this scope.
+//   foo.x() : initializer = true {
+//   ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:2:3: Context: Previous declaration of 'Foo.x'.
+//   foo.x() {
+//   ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:11:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Error: 'Foo' is already declared in this scope.
+//   get Foo {
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:11:7: Context: Previous declaration of 'Foo'.
+//   get Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Error: 'Foo.X' is already declared in this scope.
+//   get Foo.X {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X => 0;
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo : bla = null => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X : bla = null {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X : bla = null {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Error: 'Foo.X' is already declared in this scope.
+//   get Foo.X : bla = null {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: 'Foo' is already declared in this scope.
+//   set Foo {
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Context: Previous declaration of 'Foo'.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X => 0;
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X : bla = null {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X => 0;
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo : bla = null => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Error: 'Foo' is already declared in this scope.
+//   set Foo : bla = null => 0;
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:7: Context: Previous declaration of 'Foo'.
+//   get Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X : bla = null {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X : bla = null {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X : bla = null {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:35:18: Error: An external constructor can't have any initializers.
+//   external Foo() : bla = null;
+//                  ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:35:12: Error: 'Foo' is already declared in this scope.
+//   external Foo() : bla = null;
+//            ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Context: Previous declaration of 'Foo'.
+//   set Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:33: Error: An external or native method can't have a body.
+//   external Foo.X() : bla = null {
+//                                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:20: Error: An external constructor can't have any initializers.
+//   external Foo.X() : bla = null {
+//                    ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:12: Error: 'Foo.X' is already declared in this scope.
+//   external Foo.X() : bla = null {
+//            ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X : bla = null {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   int Foo;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Error: 'Foo' is already declared in this scope.
+//   int Foo;
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Context: Previous declaration of 'Foo'.
+//   get Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   int A, Foo, B;
+//          ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: 'Foo' is already declared in this scope.
+//   int A, Foo, B;
+//          ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Context: Previous declaration of 'Foo'.
+//   int Foo;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: Conflicts with member 'Foo'.
+//   set Foo {
+//       ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: Conflicts with setter 'Foo'.
+//   int A, Foo, B;
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:13: Error: 'initializer' isn't an instance field of this class.
+//   foo.x() : initializer = true {
+//             ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:11: Error: 'initializer' isn't an instance field of this class.
+//   foo() : initializer = true {
+//           ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:16: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   get Foo.X => 0;
+//                ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:17:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:13: Error: 'bla' isn't an instance field of this class.
+//   get Foo : bla = null => 0;
+//             ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:27: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   get Foo : bla = null => 0;
+//                           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:15: Error: 'bla' isn't an instance field of this class.
+//   get Foo.X : bla = null {
+//               ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:21:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:11: Error: A setter should have exactly one formal parameter.
+//   set Foo => 0;
+//           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:25:12: Error: Can't return a value from a void function.
+//     return 0;
+//            ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:11: Error: A setter should have exactly one formal parameter.
+//   set Foo {
+//           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:16: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   set Foo.X => 0;
+//                ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:29:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:13: Error: 'bla' isn't an instance field of this class.
+//   set Foo : bla = null => 0;
+//             ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:27: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   set Foo : bla = null => 0;
+//                           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:15: Error: 'bla' isn't an instance field of this class.
+//   set Foo.X : bla = null {
+//               ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:33:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:37:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int* A = null;
+  field core::int* B = null;
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:11: Error: 'initializer' isn't an instance field of this class.
+  foo() : initializer = true {
+          ^^^^^^^^^^^" {}
+  constructor X() → self::Foo*
+    : super core::Object::•()
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:16: Error: Constructors can't have a return type.
+Try removing the return type.
+  get Foo.X => 0;
+               ^";
+  constructor •() → self::Foo*
+    : final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:13: Error: 'bla' isn't an instance field of this class.
+  get Foo : bla = null => 0;
+            ^^^"
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:27: Error: Constructors can't have a return type.
+Try removing the return type.
+  get Foo : bla = null => 0;
+                          ^";
+  get Foo() → dynamic
+    return 0;
+  set Foo(dynamic #synthetic) → void {
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:11: Error: A setter should have exactly one formal parameter.
+  set Foo => 0;
+          ^";
+    return 0;
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..ed0fc2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.strong.transformed.expect
@@ -0,0 +1,363 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:2:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:3: Error: 'Foo.x' is already declared in this scope.
+//   foo.x() : initializer = true {
+//   ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:2:3: Context: Previous declaration of 'Foo.x'.
+//   foo.x() {
+//   ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:3: Error: The name of a constructor must match the name of the enclosing class.
+//   foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:11:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Error: 'Foo' is already declared in this scope.
+//   get Foo {
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:11:7: Context: Previous declaration of 'Foo'.
+//   get Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Error: 'Foo.X' is already declared in this scope.
+//   get Foo.X {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X => 0;
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo : bla = null => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   get Foo.X : bla = null {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.X : bla = null {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Error: 'Foo.X' is already declared in this scope.
+//   get Foo.X : bla = null {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:16:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: 'Foo' is already declared in this scope.
+//   set Foo {
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:7: Context: Previous declaration of 'Foo'.
+//   set Foo => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X => 0;
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:7: Context: Previous declaration of 'Foo.X'.
+//   get Foo.X : bla = null {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X => 0;
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo : bla = null => 0;
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Error: 'Foo' is already declared in this scope.
+//   set Foo : bla = null => 0;
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:7: Context: Previous declaration of 'Foo'.
+//   get Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   set Foo.X : bla = null {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.X : bla = null {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Error: 'Foo.X' is already declared in this scope.
+//   set Foo.X : bla = null {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:28:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:35:18: Error: An external constructor can't have any initializers.
+//   external Foo() : bla = null;
+//                  ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:35:12: Error: 'Foo' is already declared in this scope.
+//   external Foo() : bla = null;
+//            ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:7: Context: Previous declaration of 'Foo'.
+//   set Foo : bla = null => 0;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:33: Error: An external or native method can't have a body.
+//   external Foo.X() : bla = null {
+//                                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:20: Error: An external constructor can't have any initializers.
+//   external Foo.X() : bla = null {
+//                    ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:36:12: Error: 'Foo.X' is already declared in this scope.
+//   external Foo.X() : bla = null {
+//            ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:7: Context: Previous declaration of 'Foo.X'.
+//   set Foo.X : bla = null {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   int Foo;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Error: 'Foo' is already declared in this scope.
+//   int Foo;
+//       ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:12:7: Context: Previous declaration of 'Foo'.
+//   get Foo {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   int A, Foo, B;
+//          ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: 'Foo' is already declared in this scope.
+//   int A, Foo, B;
+//          ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:39:7: Context: Previous declaration of 'Foo'.
+//   int Foo;
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:7: Error: Conflicts with member 'Foo'.
+//   set Foo {
+//       ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:40:10: Error: Conflicts with setter 'Foo'.
+//   int A, Foo, B;
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:5:13: Error: 'initializer' isn't an instance field of this class.
+//   foo.x() : initializer = true {
+//             ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:11: Error: 'initializer' isn't an instance field of this class.
+//   foo() : initializer = true {
+//           ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:16: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   get Foo.X => 0;
+//                ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:17:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:13: Error: 'bla' isn't an instance field of this class.
+//   get Foo : bla = null => 0;
+//             ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:27: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   get Foo : bla = null => 0;
+//                           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:20:15: Error: 'bla' isn't an instance field of this class.
+//   get Foo.X : bla = null {
+//               ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:21:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:11: Error: A setter should have exactly one formal parameter.
+//   set Foo => 0;
+//           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:25:12: Error: Can't return a value from a void function.
+//     return 0;
+//            ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:24:11: Error: A setter should have exactly one formal parameter.
+//   set Foo {
+//           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:27:16: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   set Foo.X => 0;
+//                ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:29:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:13: Error: 'bla' isn't an instance field of this class.
+//   set Foo : bla = null => 0;
+//             ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:31:27: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   set Foo : bla = null => 0;
+//                           ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:32:15: Error: 'bla' isn't an instance field of this class.
+//   set Foo.X : bla = null {
+//               ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:33:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:37:5: Error: Constructors can't have a return type.
+// Try removing the return type.
+//     return 0;
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int* A = null;
+  field core::int* B = null;
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:8:11: Error: 'initializer' isn't an instance field of this class.
+  foo() : initializer = true {
+          ^^^^^^^^^^^" {}
+  constructor X() → self::Foo*
+    : super core::Object::•()
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:15:16: Error: Constructors can't have a return type.
+Try removing the return type.
+  get Foo.X => 0;
+               ^";
+  constructor •() → self::Foo*
+    : final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:13: Error: 'bla' isn't an instance field of this class.
+  get Foo : bla = null => 0;
+            ^^^"
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:19:27: Error: Constructors can't have a return type.
+Try removing the return type.
+  get Foo : bla = null => 0;
+                          ^";
+  get Foo() → dynamic
+    return 0;
+  set Foo(dynamic #synthetic) → void {
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart:23:11: Error: A setter should have exactly one formal parameter.
+  set Foo => 0;
+          ^";
+    return 0;
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..7a39d56
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.textual_outline.expect
@@ -0,0 +1,21 @@
+class Foo {
+  foo.x() { }
+  foo.x() : initializer = true { }
+  foo() : initializer = true { }
+  get Foo => 0;
+  get Foo { }
+  get Foo.X ()=> 0;
+  get Foo.X (){ }
+  get Foo (): bla = null => 0;
+  get Foo.X (): bla = null { }
+  set Foo ()=> 0;
+  set Foo (){ }
+  set Foo.X ()=> 0;
+  set Foo.X (){ }
+  set Foo (): bla = null => 0;
+  set Foo.X (): bla = null { }
+  external Foo() : bla = null;
+  external Foo.X() : bla = null { }
+  int Foo;
+  int A, Foo, B;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart
new file mode 100644
index 0000000..9025e56
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart
@@ -0,0 +1,11 @@
+class Foo {
+  get foo.x() {
+    // Not OK.
+  }
+  get foo.x() : initializer = true {
+    // Not OK.
+  }
+  get foo() : initializer = true {
+    // Not OK.
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.outline.expect
new file mode 100644
index 0000000..fe0b497
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.outline.expect
@@ -0,0 +1,52 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo.x() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo.x() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:7: Error: 'Foo.x' is already declared in this scope.
+//   get foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:7: Context: Previous declaration of 'Foo.x'.
+//   get foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get foo() : initializer = true {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo() : initializer = true {
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    ;
+  constructor foo() → self::Foo*
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.strong.expect
new file mode 100644
index 0000000..869b1d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.strong.expect
@@ -0,0 +1,62 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo.x() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo.x() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:7: Error: 'Foo.x' is already declared in this scope.
+//   get foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:7: Context: Previous declaration of 'Foo.x'.
+//   get foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get foo() : initializer = true {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:17: Error: 'initializer' isn't an instance field of this class.
+//   get foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+//   get foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+  get foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..869b1d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo.x() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo.x() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:7: Error: 'Foo.x' is already declared in this scope.
+//   get foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:2:7: Context: Previous declaration of 'Foo.x'.
+//   get foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get foo() : initializer = true {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:7: Error: The name of a constructor must match the name of the enclosing class.
+//   get foo() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:5:17: Error: 'initializer' isn't an instance field of this class.
+//   get foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+//   get foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+  get foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..b3cbfd2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+  get foo.x() { }
+  get foo.x() : initializer = true { }
+  get foo() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart
new file mode 100644
index 0000000..2c827a6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart
@@ -0,0 +1,11 @@
+class Foo {
+  void foo.x() {
+    // Not OK.
+  }
+  void foo.x() : initializer = true {
+    // Not OK.
+  }
+  void foo() : initializer = true {
+    // Not OK.
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.outline.expect
new file mode 100644
index 0000000..38d4897
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.outline.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo.x() {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo.x() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo.x() : initializer = true {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo.x() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:8: Error: 'Foo.x' is already declared in this scope.
+//   void foo.x() : initializer = true {
+//        ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:8: Context: Previous declaration of 'Foo.x'.
+//   void foo.x() {
+//        ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo() : initializer = true {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo() : initializer = true {
+//   ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    ;
+  constructor foo() → self::Foo*
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.strong.expect
new file mode 100644
index 0000000..3864448
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.strong.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo.x() {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo.x() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo.x() : initializer = true {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo.x() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:8: Error: 'Foo.x' is already declared in this scope.
+//   void foo.x() : initializer = true {
+//        ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:8: Context: Previous declaration of 'Foo.x'.
+//   void foo.x() {
+//        ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo() : initializer = true {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:18: Error: 'initializer' isn't an instance field of this class.
+//   void foo.x() : initializer = true {
+//                  ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:16: Error: 'initializer' isn't an instance field of this class.
+//   void foo() : initializer = true {
+//                ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:16: Error: 'initializer' isn't an instance field of this class.
+  void foo() : initializer = true {
+               ^^^^^^^^^^^" {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..3864448
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo.x() {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo.x() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo.x() : initializer = true {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo.x() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:8: Error: 'Foo.x' is already declared in this scope.
+//   void foo.x() : initializer = true {
+//        ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:2:8: Context: Previous declaration of 'Foo.x'.
+//   void foo.x() {
+//        ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:8: Error: The name of a constructor must match the name of the enclosing class.
+//   void foo() : initializer = true {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void foo() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:5:18: Error: 'initializer' isn't an instance field of this class.
+//   void foo.x() : initializer = true {
+//                  ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:16: Error: 'initializer' isn't an instance field of this class.
+//   void foo() : initializer = true {
+//                ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart:8:16: Error: 'initializer' isn't an instance field of this class.
+  void foo() : initializer = true {
+               ^^^^^^^^^^^" {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..d35936c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+  void foo.x() { }
+  void foo.x() : initializer = true { }
+  void foo() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart
new file mode 100644
index 0000000..4ecd30e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart
@@ -0,0 +1,11 @@
+class Foo {
+  set foo.x() {
+    // Not OK.
+  }
+  set foo.x() : initializer = true {
+    // Not OK.
+  }
+  set foo() : initializer = true {
+    // Not OK.
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.outline.expect
new file mode 100644
index 0000000..7fc2664
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.outline.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo.x() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo.x() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:7: Error: 'Foo.x' is already declared in this scope.
+//   set foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:7: Context: Previous declaration of 'Foo.x'.
+//   set foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo() : initializer = true {
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    ;
+  constructor foo() → self::Foo*
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.strong.expect
new file mode 100644
index 0000000..2a38c47
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.strong.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo.x() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo.x() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:7: Error: 'Foo.x' is already declared in this scope.
+//   set foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:7: Context: Previous declaration of 'Foo.x'.
+//   set foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:17: Error: 'initializer' isn't an instance field of this class.
+//   set foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+//   set foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+  set foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..2a38c47
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo.x() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo.x() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:7: Error: 'Foo.x' is already declared in this scope.
+//   set foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:2:7: Context: Previous declaration of 'Foo.x'.
+//   set foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:7: Error: The name of a constructor must match the name of the enclosing class.
+//   set foo() : initializer = true {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:5:17: Error: 'initializer' isn't an instance field of this class.
+//   set foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+//   set foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  constructor foo() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart:8:15: Error: 'initializer' isn't an instance field of this class.
+  set foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..3bf5301
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+  set foo.x() { }
+  set foo.x() : initializer = true { }
+  set foo() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart
new file mode 100644
index 0000000..5921c10
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart
@@ -0,0 +1,14 @@
+class Foo {
+  get Foo() {
+    // Not OK.
+  }
+  get Foo() : initializer = true {
+    // Not OK.
+  }
+  get Foo.x() {
+    // Not OK.
+  }
+  get Foo.x() : initializer = true {
+    // Not OK.
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.outline.expect
new file mode 100644
index 0000000..edb2408
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.outline.expect
@@ -0,0 +1,52 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:2:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get Foo() {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:2:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get Foo() : initializer = true {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:8:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:7: Error: 'Foo.x' is already declared in this scope.
+//   get Foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:8:7: Context: Previous declaration of 'Foo.x'.
+//   get Foo.x() {
+//       ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    ;
+  constructor x() → self::Foo*
+    ;
+  get Foo() → dynamic
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.strong.expect
new file mode 100644
index 0000000..5abfca6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.strong.expect
@@ -0,0 +1,61 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:2:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get Foo() {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:2:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get Foo() : initializer = true {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:8:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:7: Error: 'Foo.x' is already declared in this scope.
+//   get Foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:8:7: Context: Previous declaration of 'Foo.x'.
+//   get Foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+//   get Foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:17: Error: 'initializer' isn't an instance field of this class.
+//   get Foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+  get Foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  get Foo() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..5abfca6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.strong.transformed.expect
@@ -0,0 +1,61 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:2:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get Foo() {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:2:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   get Foo() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:10: Error: A getter can't have formal parameters.
+// Try removing '(...)'.
+//   get Foo() : initializer = true {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:8:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:3: Error: Constructors can't be a getter.
+// Try removing 'get'.
+//   get Foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:7: Error: 'Foo.x' is already declared in this scope.
+//   get Foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:8:7: Context: Previous declaration of 'Foo.x'.
+//   get Foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+//   get Foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:11:17: Error: 'initializer' isn't an instance field of this class.
+//   get Foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+  get Foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  get Foo() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.textual_outline.expect
new file mode 100644
index 0000000..3ce8e72
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+  get Foo() { }
+  get Foo() : initializer = true { }
+  get Foo.x() { }
+  get Foo.x() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart
new file mode 100644
index 0000000..6a532a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart
@@ -0,0 +1,14 @@
+class Foo {
+  Foo() {
+    // OK.
+  }
+  Foo() : initializer = true {
+    // OK.
+  }
+  Foo.x() {
+    // OK.
+  }
+  Foo.x() : initializer = true {
+    // OK.
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.outline.expect
new file mode 100644
index 0000000..8613684
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.outline.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:5:3: Error: 'Foo' is already declared in this scope.
+//   Foo() : initializer = true {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:2:3: Context: Previous declaration of 'Foo'.
+//   Foo() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:11:3: Error: 'Foo.x' is already declared in this scope.
+//   Foo.x() : initializer = true {
+//   ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:8:3: Context: Previous declaration of 'Foo.x'.
+//   Foo.x() {
+//   ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    ;
+  constructor x() → self::Foo*
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.strong.expect
new file mode 100644
index 0000000..3544a52
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.strong.expect
@@ -0,0 +1,35 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:5:3: Error: 'Foo' is already declared in this scope.
+//   Foo() : initializer = true {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:2:3: Context: Previous declaration of 'Foo'.
+//   Foo() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:11:3: Error: 'Foo.x' is already declared in this scope.
+//   Foo.x() : initializer = true {
+//   ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:8:3: Context: Previous declaration of 'Foo.x'.
+//   Foo.x() {
+//   ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:5:11: Error: 'initializer' isn't an instance field of this class.
+//   Foo() : initializer = true {
+//           ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:11:13: Error: 'initializer' isn't an instance field of this class.
+//   Foo.x() : initializer = true {
+//             ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : super core::Object::•() {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.strong.transformed.expect
new file mode 100644
index 0000000..3544a52
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:5:3: Error: 'Foo' is already declared in this scope.
+//   Foo() : initializer = true {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:2:3: Context: Previous declaration of 'Foo'.
+//   Foo() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:11:3: Error: 'Foo.x' is already declared in this scope.
+//   Foo.x() : initializer = true {
+//   ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:8:3: Context: Previous declaration of 'Foo.x'.
+//   Foo.x() {
+//   ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:5:11: Error: 'initializer' isn't an instance field of this class.
+//   Foo() : initializer = true {
+//           ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart:11:13: Error: 'initializer' isn't an instance field of this class.
+//   Foo.x() : initializer = true {
+//             ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : super core::Object::•() {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline.expect
new file mode 100644
index 0000000..2318374
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+  Foo() {}
+  Foo() : initializer = true {}
+  Foo.x() {}
+  Foo.x() : initializer = true {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f87cd03
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Foo {
+  Foo() : initializer = true {}
+  Foo() {}
+  Foo.x() : initializer = true {}
+  Foo.x() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart
new file mode 100644
index 0000000..44d5847
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart
@@ -0,0 +1,14 @@
+class Foo {
+  Foo() / : super() {
+    // Not OK.
+  }
+  Foo()./ : super() {
+    // Not OK.
+  }
+  foo() / : super() {
+    // Not OK.
+  }
+  foo()./ : super() {
+    // Not OK.
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.outline.expect
new file mode 100644
index 0000000..e8c9145
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.outline.expect
@@ -0,0 +1,146 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Expected '{' before this.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: The name of a constructor must match the name of the enclosing class.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Operator '/' should have exactly one parameter.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:8: Error: Expected '{' before this.
+//   Foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:3: Error: 'Foo' is already declared in this scope.
+//   Foo()./ : super() {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:3: Context: Previous declaration of 'Foo'.
+//   Foo() / : super() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:8: Error: Expected a class member, but got '.'.
+//   Foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: The name of a constructor must match the name of the enclosing class.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: Operator '/' should have exactly one parameter.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: 'Foo./' is already declared in this scope.
+//   Foo()./ : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Context: Previous declaration of 'Foo./'.
+//   Foo() / : super() {
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Expected '{' before this.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: The name of a constructor must match the name of the enclosing class.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Operator '/' should have exactly one parameter.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: 'Foo./' is already declared in this scope.
+//   foo() / : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Context: Previous declaration of 'Foo./'.
+//   Foo()./ : super() {
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:8: Error: Expected '{' before this.
+//   foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:3: Error: 'foo' is already declared in this scope.
+//   foo()./ : super() {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:3: Context: Previous declaration of 'foo'.
+//   foo() / : super() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:8: Error: Expected a class member, but got '.'.
+//   foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: The name of a constructor must match the name of the enclosing class.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: Operator '/' should have exactly one parameter.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: 'Foo./' is already declared in this scope.
+//   foo()./ : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Context: Previous declaration of 'Foo./'.
+//   foo() / : super() {
+//         ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    ;
+  constructor /() → self::Foo*
+    ;
+  method foo() → dynamic
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.strong.expect
new file mode 100644
index 0000000..c7113bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.strong.expect
@@ -0,0 +1,145 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Expected '{' before this.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: The name of a constructor must match the name of the enclosing class.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Operator '/' should have exactly one parameter.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:8: Error: Expected '{' before this.
+//   Foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:3: Error: 'Foo' is already declared in this scope.
+//   Foo()./ : super() {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:3: Context: Previous declaration of 'Foo'.
+//   Foo() / : super() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:8: Error: Expected a class member, but got '.'.
+//   Foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: The name of a constructor must match the name of the enclosing class.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: Operator '/' should have exactly one parameter.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: 'Foo./' is already declared in this scope.
+//   Foo()./ : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Context: Previous declaration of 'Foo./'.
+//   Foo() / : super() {
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Expected '{' before this.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: The name of a constructor must match the name of the enclosing class.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Operator '/' should have exactly one parameter.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: 'Foo./' is already declared in this scope.
+//   foo() / : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Context: Previous declaration of 'Foo./'.
+//   Foo()./ : super() {
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:8: Error: Expected '{' before this.
+//   foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:3: Error: 'foo' is already declared in this scope.
+//   foo()./ : super() {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:3: Context: Previous declaration of 'foo'.
+//   foo() / : super() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:8: Error: Expected a class member, but got '.'.
+//   foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: The name of a constructor must match the name of the enclosing class.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: Operator '/' should have exactly one parameter.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: 'Foo./' is already declared in this scope.
+//   foo()./ : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Context: Previous declaration of 'Foo./'.
+//   foo() / : super() {
+//         ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : super core::Object::•() {}
+  constructor /() → self::Foo*
+    : super core::Object::•() {}
+  method foo() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..c7113bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.strong.transformed.expect
@@ -0,0 +1,145 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Expected '{' before this.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: The name of a constructor must match the name of the enclosing class.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Error: Operator '/' should have exactly one parameter.
+//   Foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:8: Error: Expected '{' before this.
+//   Foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:3: Error: 'Foo' is already declared in this scope.
+//   Foo()./ : super() {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:3: Context: Previous declaration of 'Foo'.
+//   Foo() / : super() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:8: Error: Expected a class member, but got '.'.
+//   Foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: The name of a constructor must match the name of the enclosing class.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: Operator '/' should have exactly one parameter.
+//   Foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Error: 'Foo./' is already declared in this scope.
+//   Foo()./ : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:2:9: Context: Previous declaration of 'Foo./'.
+//   Foo() / : super() {
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Expected '{' before this.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: The name of a constructor must match the name of the enclosing class.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: Operator '/' should have exactly one parameter.
+//   foo() / : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Error: 'Foo./' is already declared in this scope.
+//   foo() / : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:5:9: Context: Previous declaration of 'Foo./'.
+//   Foo()./ : super() {
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:8: Error: Expected '{' before this.
+//   foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:3: Error: 'foo' is already declared in this scope.
+//   foo()./ : super() {
+//   ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:3: Context: Previous declaration of 'foo'.
+//   foo() / : super() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:8: Error: Expected a class member, but got '.'.
+//   foo()./ : super() {
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: The name of a constructor must match the name of the enclosing class.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: Operator '/' should have exactly one parameter.
+//   foo()./ : super() {
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:11:9: Error: 'Foo./' is already declared in this scope.
+//   foo()./ : super() {
+//         ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart:8:9: Context: Previous declaration of 'Foo./'.
+//   foo() / : super() {
+//         ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : super core::Object::•() {}
+  constructor /() → self::Foo*
+    : super core::Object::•() {}
+  method foo() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..07d90ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Foo {
+  Foo() { }
+  operator/ (): super() { }
+  Foo(){ }
+  .
+  operator/ (): super() { }
+  foo() { }
+  operator/ (): super() { }
+  foo(){ }
+  .
+  operator/ (): super() { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart
new file mode 100644
index 0000000..fd9a67c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart
@@ -0,0 +1,14 @@
+class Foo {
+  void Foo() {
+    // Not OK.
+  }
+  void Foo() : initializer = true {
+    // Not OK.
+  }
+  void Foo.x() {
+    // Not OK.
+  }
+  void Foo.x() : initializer = true {
+    // Not OK.
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.outline.expect
new file mode 100644
index 0000000..ff6c7df
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.outline.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:2:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:8: Error: 'Foo' is already declared in this scope.
+//   void Foo() : initializer = true {
+//        ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:2:8: Context: Previous declaration of 'Foo'.
+//   void Foo() {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:8:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo.x() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo.x() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:8: Error: 'Foo.x' is already declared in this scope.
+//   void Foo.x() : initializer = true {
+//        ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:8:8: Context: Previous declaration of 'Foo.x'.
+//   void Foo.x() {
+//        ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    ;
+  constructor x() → self::Foo*
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.strong.expect
new file mode 100644
index 0000000..20c0062
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.strong.expect
@@ -0,0 +1,55 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:2:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:8: Error: 'Foo' is already declared in this scope.
+//   void Foo() : initializer = true {
+//        ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:2:8: Context: Previous declaration of 'Foo'.
+//   void Foo() {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:8:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo.x() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo.x() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:8: Error: 'Foo.x' is already declared in this scope.
+//   void Foo.x() : initializer = true {
+//        ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:8:8: Context: Previous declaration of 'Foo.x'.
+//   void Foo.x() {
+//        ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:16: Error: 'initializer' isn't an instance field of this class.
+//   void Foo() : initializer = true {
+//                ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:18: Error: 'initializer' isn't an instance field of this class.
+//   void Foo.x() : initializer = true {
+//                  ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : super core::Object::•() {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..20c0062
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.strong.transformed.expect
@@ -0,0 +1,55 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:2:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:8: Error: 'Foo' is already declared in this scope.
+//   void Foo() : initializer = true {
+//        ^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:2:8: Context: Previous declaration of 'Foo'.
+//   void Foo() {
+//        ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:8:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo.x() {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:3: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   void Foo.x() : initializer = true {
+//   ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:8: Error: 'Foo.x' is already declared in this scope.
+//   void Foo.x() : initializer = true {
+//        ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:8:8: Context: Previous declaration of 'Foo.x'.
+//   void Foo.x() {
+//        ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:5:16: Error: 'initializer' isn't an instance field of this class.
+//   void Foo() : initializer = true {
+//                ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart:11:18: Error: 'initializer' isn't an instance field of this class.
+//   void Foo.x() : initializer = true {
+//                  ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : super core::Object::•() {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..84de529
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+  void Foo() { }
+  void Foo() : initializer = true { }
+  void Foo.x() { }
+  void Foo.x() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart
new file mode 100644
index 0000000..6f5b73e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart
@@ -0,0 +1,14 @@
+class Foo {
+  set Foo() {
+    // Not OK.
+  }
+  set Foo() : initializer = true {
+    // Not OK.
+  }
+  set Foo.x() {
+    // Not OK.
+  }
+  set Foo.x() : initializer = true {
+    // Not OK.
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.outline.expect
new file mode 100644
index 0000000..59ce93c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.outline.expect
@@ -0,0 +1,42 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:8:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:7: Error: 'Foo.x' is already declared in this scope.
+//   set Foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:8:7: Context: Previous declaration of 'Foo.x'.
+//   set Foo.x() {
+//       ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    ;
+  constructor x() → self::Foo*
+    ;
+  set Foo(dynamic #synthetic) → void
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.strong.expect
new file mode 100644
index 0000000..5995c47
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.strong.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:8:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:7: Error: 'Foo.x' is already declared in this scope.
+//   set Foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:8:7: Context: Previous declaration of 'Foo.x'.
+//   set Foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:10: Error: A setter should have exactly one formal parameter.
+//   set Foo() {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+//   set Foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:17: Error: 'initializer' isn't an instance field of this class.
+//   set Foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+  set Foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  set Foo(dynamic #synthetic) → void {
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:10: Error: A setter should have exactly one formal parameter.
+  set Foo() {
+         ^";
+    {}
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.strong.transformed.expect
new file mode 100644
index 0000000..5995c47
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.strong.transformed.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:7: Error: A class member can't have the same name as the enclosing class.
+// Try renaming the member.
+//   set Foo() {
+//       ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:8:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.x() {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:3: Error: Constructors can't be a setter.
+// Try removing 'set'.
+//   set Foo.x() : initializer = true {
+//   ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:7: Error: 'Foo.x' is already declared in this scope.
+//   set Foo.x() : initializer = true {
+//       ^^^^^
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:8:7: Context: Previous declaration of 'Foo.x'.
+//   set Foo.x() {
+//       ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:10: Error: A setter should have exactly one formal parameter.
+//   set Foo() {
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+//   set Foo() : initializer = true {
+//               ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:11:17: Error: 'initializer' isn't an instance field of this class.
+//   set Foo.x() : initializer = true {
+//                 ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → self::Foo*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:5:15: Error: 'initializer' isn't an instance field of this class.
+  set Foo() : initializer = true {
+              ^^^^^^^^^^^" {}
+  constructor x() → self::Foo*
+    : super core::Object::•() {}
+  set Foo(dynamic #synthetic) → void {
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart:2:10: Error: A setter should have exactly one formal parameter.
+  set Foo() {
+         ^";
+    {}
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.textual_outline.expect
new file mode 100644
index 0000000..f2dfad0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+  set Foo() { }
+  set Foo() : initializer = true { }
+  set Foo.x() { }
+  set Foo.x() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart
new file mode 100644
index 0000000..19771e9
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart
@@ -0,0 +1,3 @@
+main() async {
+  await for () {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.outline.expect
new file mode 100644
index 0000000..6a28c0d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.outline.expect
@@ -0,0 +1,5 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.expect
new file mode 100644
index 0000000..e8becc5
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.expect
@@ -0,0 +1,24 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: Expected an identifier, but got ')'.
+//   await for () {}
+//              ^
+//
+// pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: Expected 'in' before this.
+//   await for () {}
+//              ^
+//
+import self as self;
+import "dart:async" as asy;
+
+static method main() → dynamic async {
+  await for (final dynamic #t1 in invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
+  await for () {}
+             ^" as{TypeError,ForDynamic} asy::Stream<dynamic>*) {
+    invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
+  await for () {}
+             ^";
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
new file mode 100644
index 0000000..a9a80da
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
@@ -0,0 +1,74 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: Expected an identifier, but got ')'.
+//   await for () {}
+//              ^
+//
+// pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: Expected 'in' before this.
+//   await for () {}
+//              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>* :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+  core::int* :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        {
+          asy::Stream<dynamic>* :stream = invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
+  await for () {}
+             ^" as{TypeError,ForDynamic} asy::Stream<dynamic>*;
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
+          try
+            #L2:
+            while (true) {
+              dynamic #t1 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(_in::unsafeCast<core::bool*>(:result)) {
+                final dynamic #t3 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
+  await for () {}
+             ^";
+                }
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart b/pkg/front_end/testcases/general/error_recovery/empty_for.dart
new file mode 100644
index 0000000..3c33ee5
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart
@@ -0,0 +1,3 @@
+main() {
+  for () {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.outline.expect
new file mode 100644
index 0000000..6a28c0d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.outline.expect
@@ -0,0 +1,5 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.expect
new file mode 100644
index 0000000..3bb7f2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.expect
@@ -0,0 +1,23 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: Expected an identifier, but got ')'.
+//   for () {}
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: Expected ';' after this.
+//   for () {}
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: This couldn't be parsed.
+  for () {}
+       ^"; invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: This couldn't be parsed.
+  for () {}
+       ^" as{TypeError,ForDynamic} core::bool*; ) {
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect
new file mode 100644
index 0000000..3bb7f2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: Expected an identifier, but got ')'.
+//   for () {}
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: Expected ';' after this.
+//   for () {}
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: This couldn't be parsed.
+  for () {}
+       ^"; invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: This couldn't be parsed.
+  for () {}
+       ^" as{TypeError,ForDynamic} core::bool*; ) {
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart
new file mode 100644
index 0000000..c6672ff
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart
@@ -0,0 +1 @@
+f() { m(T<R(<Z
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.outline.expect
new file mode 100644
index 0000000..2aafef5
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.outline.expect
@@ -0,0 +1,24 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:12: Error: Can't find ')' to match '('.
+// f() { m(T<R(<Z
+//            ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:10: Error: Can't find '>' to match '<'.
+// f() { m(T<R(<Z
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:8: Error: Can't find ')' to match '('.
+// f() { m(T<R(<Z
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:5: Error: Can't find '}' to match '{'.
+// f() { m(T<R(<Z
+//     ^
+//
+import self as self;
+
+static method f() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.strong.expect
new file mode 100644
index 0000000..3b6f734
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.strong.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:12: Error: Can't find ')' to match '('.
+// f() { m(T<R(<Z
+//            ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:10: Error: Can't find '>' to match '<'.
+// f() { m(T<R(<Z
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:8: Error: Can't find ')' to match '('.
+// f() { m(T<R(<Z
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:5: Error: Can't find '}' to match '{'.
+// f() { m(T<R(<Z
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:14: Error: 'Z' isn't a type.
+// f() { m(T<R(<Z
+//              ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected '[' before this.
+// f() { m(T<R(<Z
+//               ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:11: Error: Method not found: 'R'.
+// f() { m(T<R(<Z
+//           ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:9: Error: Getter not found: 'T'.
+// f() { m(T<R(<Z
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:7: Error: Method not found: 'm'.
+// f() { m(T<R(<Z
+//       ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected ';' after this.
+// f() { m(T<R(<Z
+//               ^...
+//
+import self as self;
+
+static method f() → dynamic {
+  invalid-expression "pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:7: Error: Method not found: 'm'.
+f() { m(T<R(<Z
+      ^";
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..3b6f734
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.strong.transformed.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:12: Error: Can't find ')' to match '('.
+// f() { m(T<R(<Z
+//            ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:10: Error: Can't find '>' to match '<'.
+// f() { m(T<R(<Z
+//          ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:8: Error: Can't find ')' to match '('.
+// f() { m(T<R(<Z
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:5: Error: Can't find '}' to match '{'.
+// f() { m(T<R(<Z
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:14: Error: 'Z' isn't a type.
+// f() { m(T<R(<Z
+//              ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected '[' before this.
+// f() { m(T<R(<Z
+//               ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:11: Error: Method not found: 'R'.
+// f() { m(T<R(<Z
+//           ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:9: Error: Getter not found: 'T'.
+// f() { m(T<R(<Z
+//         ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:7: Error: Method not found: 'm'.
+// f() { m(T<R(<Z
+//       ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected ';' after this.
+// f() { m(T<R(<Z
+//               ^...
+//
+import self as self;
+
+static method f() → dynamic {
+  invalid-expression "pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:7: Error: Method not found: 'm'.
+f() { m(T<R(<Z
+      ^";
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart
new file mode 100644
index 0000000..7094494
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart
@@ -0,0 +1 @@
+n<S e(
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.outline.expect
new file mode 100644
index 0000000..74ed3a8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.outline.expect
@@ -0,0 +1,42 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:6: Error: Can't find ')' to match '('.
+// n<S e(
+//      ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:2: Error: Can't find '>' to match '<'.
+// n<S e(
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:3: Error: Expected '>' after this.
+// n<S e(
+//   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: Expected an identifier, but got ''.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: Expected '{' before this.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:3: Error: Type 'S' not found.
+// n<S e(
+//   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:1: Error: Type 'n' not found.
+// n<S e(
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:1: Error: Expected 0 type arguments.
+// n<S e(
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.strong.expect
new file mode 100644
index 0000000..74ed3a8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.strong.expect
@@ -0,0 +1,42 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:6: Error: Can't find ')' to match '('.
+// n<S e(
+//      ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:2: Error: Can't find '>' to match '<'.
+// n<S e(
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:3: Error: Expected '>' after this.
+// n<S e(
+//   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: Expected an identifier, but got ''.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: Expected '{' before this.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:3: Error: Type 'S' not found.
+// n<S e(
+//   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:1: Error: Type 'n' not found.
+// n<S e(
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:1: Error: Expected 0 type arguments.
+// n<S e(
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..74ed3a8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart.strong.transformed.expect
@@ -0,0 +1,42 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:6: Error: Can't find ')' to match '('.
+// n<S e(
+//      ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:2: Error: Can't find '>' to match '<'.
+// n<S e(
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:3: Error: Expected '>' after this.
+// n<S e(
+//   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: Expected an identifier, but got ''.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:7: Error: Expected '{' before this.
+// n<S e(
+//       ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:3: Error: Type 'S' not found.
+// n<S e(
+//   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:1: Error: Type 'n' not found.
+// n<S e(
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39024.crash_dart:1:1: Error: Expected 0 type arguments.
+// n<S e(
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart
new file mode 100644
index 0000000..9ec285b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart
@@ -0,0 +1,4 @@
+class A{
+    co <{
+    }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.outline.expect
new file mode 100644
index 0000000..295fe3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.outline.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: Operator '<' should have exactly one parameter.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:5: Error: Type 'co' not found.
+//     co <{
+//     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+  operator <() → invalid-type
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.strong.expect
new file mode 100644
index 0000000..b4527e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.strong.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: Operator '<' should have exactly one parameter.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:5: Error: Type 'co' not found.
+//     co <{
+//     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator <() → invalid-type {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..b4527e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:8: Error: Operator '<' should have exactly one parameter.
+//     co <{
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart:2:5: Error: Type 'co' not found.
+//     co <{
+//     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator <() → invalid-type {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A {
+  co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A {
+  co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart
new file mode 100644
index 0000000..e5a6c50
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart
@@ -0,0 +1,4 @@
+class A{
+    co operator <{
+    }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.outline.expect
new file mode 100644
index 0000000..ae9916b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.outline.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:17: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     co operator <{
+//                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:17: Error: Operator '<' should have exactly one parameter.
+//     co operator <{
+//                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:5: Error: Type 'co' not found.
+//     co operator <{
+//     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+  operator <() → invalid-type
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.strong.expect
new file mode 100644
index 0000000..8d68a65
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.strong.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:17: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     co operator <{
+//                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:17: Error: Operator '<' should have exactly one parameter.
+//     co operator <{
+//                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:5: Error: Type 'co' not found.
+//     co operator <{
+//     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator <() → invalid-type {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..8d68a65
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:17: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     co operator <{
+//                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:17: Error: Operator '<' should have exactly one parameter.
+//     co operator <{
+//                 ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart:2:5: Error: Type 'co' not found.
+//     co operator <{
+//     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator <() → invalid-type {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A {
+  co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A {
+  co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart
new file mode 100644
index 0000000..efd5943
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart
@@ -0,0 +1 @@
+typedef F<Glib.=
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.outline.expect
new file mode 100644
index 0000000..97e06f2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.outline.expect
@@ -0,0 +1,24 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:11: Error: Expected '>' after this.
+// typedef F<Glib.=
+//           ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:17: Error: Expected a type, but got ''.
+// typedef F<Glib.=
+//                 ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:17: Error: Expected ';' after this.
+// typedef F<Glib.=
+//                 ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:16: Error: Can't create typedef from non-function type.
+// typedef F<Glib.=
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated Glib extends core::Object* = dynamic> = invalid-type;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.strong.expect
new file mode 100644
index 0000000..97e06f2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.strong.expect
@@ -0,0 +1,24 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:11: Error: Expected '>' after this.
+// typedef F<Glib.=
+//           ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:17: Error: Expected a type, but got ''.
+// typedef F<Glib.=
+//                 ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:17: Error: Expected ';' after this.
+// typedef F<Glib.=
+//                 ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:16: Error: Can't create typedef from non-function type.
+// typedef F<Glib.=
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated Glib extends core::Object* = dynamic> = invalid-type;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..97e06f2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:11: Error: Expected '>' after this.
+// typedef F<Glib.=
+//           ^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:17: Error: Expected a type, but got ''.
+// typedef F<Glib.=
+//                 ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:17: Error: Expected ';' after this.
+// typedef F<Glib.=
+//                 ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart:1:16: Error: Can't create typedef from non-function type.
+// typedef F<Glib.=
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated Glib extends core::Object* = dynamic> = invalid-type;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..2a84e27
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.textual_outline.expect
@@ -0,0 +1 @@
+typedef F<Glib>.=;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart
new file mode 100644
index 0000000..7e8a2e8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart
@@ -0,0 +1 @@
+{<[](
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.outline.expect
new file mode 100644
index 0000000..19f98e21
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.outline.expect
@@ -0,0 +1,21 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:5: Error: Can't find ')' to match '('.
+// {<[](
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:2: Error: Can't find '>' to match '<'.
+// {<[](
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:1: Error: Can't find '}' to match '{'.
+// {<[](
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:1: Error: Expected a declaration, but got '{'.
+// {<[](
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.strong.expect
new file mode 100644
index 0000000..19f98e21
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.strong.expect
@@ -0,0 +1,21 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:5: Error: Can't find ')' to match '('.
+// {<[](
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:2: Error: Can't find '>' to match '<'.
+// {<[](
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:1: Error: Can't find '}' to match '{'.
+// {<[](
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:1: Error: Expected a declaration, but got '{'.
+// {<[](
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..19f98e21
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:5: Error: Can't find ')' to match '('.
+// {<[](
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:2: Error: Can't find '>' to match '<'.
+// {<[](
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:1: Error: Can't find '}' to match '{'.
+// {<[](
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058.crash_dart:1:1: Error: Expected a declaration, but got '{'.
+// {<[](
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart
new file mode 100644
index 0000000..e042400
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart
@@ -0,0 +1 @@
+{<[]()>}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.outline.expect
new file mode 100644
index 0000000..3866d3c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.outline.expect
@@ -0,0 +1,9 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart:1:1: Error: Expected a declaration, but got '{'.
+// {<[]()>}
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.strong.expect
new file mode 100644
index 0000000..3866d3c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart:1:1: Error: Expected a declaration, but got '{'.
+// {<[]()>}
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..3866d3c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart:1:1: Error: Expected a declaration, but got '{'.
+// {<[]()>}
+// ^
+//
+import self as self;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..e042400
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.textual_outline.expect
@@ -0,0 +1 @@
+{<[]()>}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart
new file mode 100644
index 0000000..b8fb0cdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart
@@ -0,0 +1,3 @@
+main() {
+  {s A<}>
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.outline.expect
new file mode 100644
index 0000000..6a28c0d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.outline.expect
@@ -0,0 +1,5 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.strong.expect
new file mode 100644
index 0000000..7981214
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:4: Error: 's' isn't a type.
+//   {s A<}>
+//    ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:6: Error: Expected ';' after this.
+//   {s A<}>
+//      ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:8: Error: Expected a type, but got '}'.
+//   {s A<}>
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:8: Error: This couldn't be parsed.
+//   {s A<}>
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:1: Error: Expected '[' before this.
+// }
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:1: Error: Expected ';' after this.
+// }
+// ^
+//
+import self as self;
+
+static method main() → dynamic {
+  {
+    invalid-type A;
+    <invalid-type>[];
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.strong.transformed.expect
new file mode 100644
index 0000000..7981214
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:4: Error: 's' isn't a type.
+//   {s A<}>
+//    ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:6: Error: Expected ';' after this.
+//   {s A<}>
+//      ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:8: Error: Expected a type, but got '}'.
+//   {s A<}>
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:2:8: Error: This couldn't be parsed.
+//   {s A<}>
+//        ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:1: Error: Expected '[' before this.
+// }
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:1: Error: Expected ';' after this.
+// }
+// ^
+//
+import self as self;
+
+static method main() → dynamic {
+  {
+    invalid-type A;
+    <invalid-type>[];
+  }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart
new file mode 100644
index 0000000..70bdad5
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart
@@ -0,0 +1 @@
+() async => a b < c $? >
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.outline.expect
new file mode 100644
index 0000000..961d9a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.outline.expect
@@ -0,0 +1,45 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:1: Error: Expected a declaration, but got '('.
+// () async => a b < c $? >
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:2: Error: Expected a declaration, but got ')'.
+// () async => a b < c $? >
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:4: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// () async => a b < c $? >
+//    ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:19: Error: Expected '>' after this.
+// () async => a b < c $? >
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:25: Error: Expected an identifier, but got ''.
+// () async => a b < c $? >
+//                         ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:25: Error: Expected ';' after this.
+// () async => a b < c $? >
+//                         ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:19: Error: Type 'c' not found.
+// () async => a b < c $? >
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Type 'b' not found.
+// () async => a b < c $? >
+//               ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Expected 0 type arguments.
+// () async => a b < c $? >
+//               ^
+//
+import self as self;
+
+static method async() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.strong.expect
new file mode 100644
index 0000000..4ad3dc2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.strong.expect
@@ -0,0 +1,59 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:1: Error: Expected a declaration, but got '('.
+// () async => a b < c $? >
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:2: Error: Expected a declaration, but got ')'.
+// () async => a b < c $? >
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:4: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// () async => a b < c $? >
+//    ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:19: Error: Expected '>' after this.
+// () async => a b < c $? >
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:25: Error: Expected an identifier, but got ''.
+// () async => a b < c $? >
+//                         ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:25: Error: Expected ';' after this.
+// () async => a b < c $? >
+//                         ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:19: Error: Type 'c' not found.
+// () async => a b < c $? >
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Type 'b' not found.
+// () async => a b < c $? >
+//               ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Expected 0 type arguments.
+// () async => a b < c $? >
+//               ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:13: Error: Expected ';' after this.
+// () async => a b < c $? >
+//             ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:13: Error: Getter not found: 'a'.
+// () async => a b < c $? >
+//             ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Unexpected token 'b'.
+// () async => a b < c $? >
+//               ^
+//
+import self as self;
+
+static method async() → dynamic
+  return invalid-expression "pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:13: Error: Getter not found: 'a'.
+() async => a b < c \$? >
+            ^";
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..4ad3dc2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:1: Error: Expected a declaration, but got '('.
+// () async => a b < c $? >
+// ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:2: Error: Expected a declaration, but got ')'.
+// () async => a b < c $? >
+//  ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:4: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// () async => a b < c $? >
+//    ^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:19: Error: Expected '>' after this.
+// () async => a b < c $? >
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:25: Error: Expected an identifier, but got ''.
+// () async => a b < c $? >
+//                         ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:25: Error: Expected ';' after this.
+// () async => a b < c $? >
+//                         ^...
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:19: Error: Type 'c' not found.
+// () async => a b < c $? >
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Type 'b' not found.
+// () async => a b < c $? >
+//               ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Expected 0 type arguments.
+// () async => a b < c $? >
+//               ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:13: Error: Expected ';' after this.
+// () async => a b < c $? >
+//             ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:13: Error: Getter not found: 'a'.
+// () async => a b < c $? >
+//             ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:15: Error: Unexpected token 'b'.
+// () async => a b < c $? >
+//               ^
+//
+import self as self;
+
+static method async() → dynamic
+  return invalid-expression "pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart:1:13: Error: Getter not found: 'a'.
+() async => a b < c \$? >
+            ^";
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..9b170f7
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.textual_outline.expect
@@ -0,0 +1,3 @@
+()
+async ()=> a
+b < c $? >;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart
new file mode 100644
index 0000000..b3588d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart
@@ -0,0 +1,5 @@
+class C {
+  C()
+    /
+    : super();
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.outline.expect
new file mode 100644
index 0000000..46d7222
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.outline.expect
@@ -0,0 +1,35 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Expected '{' before this.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: The name of a constructor must match the name of the enclosing class.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Operator '/' should have exactly one parameter.
+//     /
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C*
+    ;
+  constructor /() → self::C*
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.strong.expect
new file mode 100644
index 0000000..3af922c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Expected '{' before this.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: The name of a constructor must match the name of the enclosing class.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Operator '/' should have exactly one parameter.
+//     /
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C*
+    : super core::Object::•() {}
+  constructor /() → self::C*
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..3af922c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Expected '{' before this.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: The name of a constructor must match the name of the enclosing class.
+//     /
+//     ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart:3:5: Error: Operator '/' should have exactly one parameter.
+//     /
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C*
+    : super core::Object::•() {}
+  constructor /() → self::C*
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..41e0a64
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  C() { }
+  operator/ (): super();
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart
new file mode 100644
index 0000000..8bde84a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart
@@ -0,0 +1 @@
+void<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.outline.expect
new file mode 100644
index 0000000..0698786
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.outline.expect
@@ -0,0 +1,13 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart:1:5: Error: Type 'void' can't have type arguments.
+// Try removing the type arguments.
+// void<int> f() {}
+//     ^
+//
+import self as self;
+
+static method f() → void
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.strong.expect
new file mode 100644
index 0000000..6945be8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.strong.expect
@@ -0,0 +1,12 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart:1:5: Error: Type 'void' can't have type arguments.
+// Try removing the type arguments.
+// void<int> f() {}
+//     ^
+//
+import self as self;
+
+static method f() → void {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.strong.transformed.expect
new file mode 100644
index 0000000..6945be8
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart:1:5: Error: Type 'void' can't have type arguments.
+// Try removing the type arguments.
+// void<int> f() {}
+//     ^
+//
+import self as self;
+
+static method f() → void {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.textual_outline.expect
new file mode 100644
index 0000000..5cab0bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.textual_outline.expect
@@ -0,0 +1 @@
+void<int> f() { }
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart
new file mode 100644
index 0000000..58b5740
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart
@@ -0,0 +1 @@
+dynamic<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.outline.expect
new file mode 100644
index 0000000..ba0fe79b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart:1:1: Error: Expected 0 type arguments.
+// dynamic<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.strong.expect
new file mode 100644
index 0000000..e7fc2a2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.strong.expect
@@ -0,0 +1,11 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart:1:1: Error: Expected 0 type arguments.
+// dynamic<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.strong.transformed.expect
new file mode 100644
index 0000000..e7fc2a2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart:1:1: Error: Expected 0 type arguments.
+// dynamic<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline.expect
new file mode 100644
index 0000000..f03cd81
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline.expect
@@ -0,0 +1 @@
+dynamic<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f03cd81
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+dynamic<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart
new file mode 100644
index 0000000..1a13723
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart
@@ -0,0 +1 @@
+int<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.outline.expect
new file mode 100644
index 0000000..5118ad3
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart:1:1: Error: Expected 0 type arguments.
+// int<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.strong.expect
new file mode 100644
index 0000000..6782f5b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.strong.expect
@@ -0,0 +1,11 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart:1:1: Error: Expected 0 type arguments.
+// int<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.strong.transformed.expect
new file mode 100644
index 0000000..6782f5b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart:1:1: Error: Expected 0 type arguments.
+// int<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline.expect
new file mode 100644
index 0000000..26e95ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline.expect
@@ -0,0 +1 @@
+int<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..26e95ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+int<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart
new file mode 100644
index 0000000..1a373f5
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart
@@ -0,0 +1 @@
+Foo<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.outline.expect
new file mode 100644
index 0000000..7cf8e23
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart:1:1: Error: Type 'Foo' not found.
+// Foo<int> f() {}
+// ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart:1:1: Error: Expected 0 type arguments.
+// Foo<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.strong.expect
new file mode 100644
index 0000000..03024b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.strong.expect
@@ -0,0 +1,15 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart:1:1: Error: Type 'Foo' not found.
+// Foo<int> f() {}
+// ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart:1:1: Error: Expected 0 type arguments.
+// Foo<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.strong.transformed.expect
new file mode 100644
index 0000000..03024b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart:1:1: Error: Type 'Foo' not found.
+// Foo<int> f() {}
+// ^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart:1:1: Error: Expected 0 type arguments.
+// Foo<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline.expect
new file mode 100644
index 0000000..78a05ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline.expect
@@ -0,0 +1 @@
+Foo<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..78a05ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+Foo<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart
new file mode 100644
index 0000000..ad56555
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart
@@ -0,0 +1,5 @@
+Future<int> f() => Future.value(7);
+
+List<int> g() {
+  yield f();
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.outline.expect
new file mode 100644
index 0000000..3000fe7
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.outline.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method f() → asy::Future<core::int*>*
+  ;
+static method g() → core::List<core::int*>*
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.strong.expect
new file mode 100644
index 0000000..962b6f1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.strong.expect
@@ -0,0 +1,19 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart:4:3: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
+//   yield f();
+//   ^^^^^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method f() → asy::Future<core::int*>*
+  return asy::Future::value<core::int*>(7);
+static method g() → core::List<core::int*>* {
+  invalid-expression "pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart:4:3: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
+  yield f();
+  ^";
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.strong.transformed.expect
new file mode 100644
index 0000000..962b6f1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart:4:3: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
+//   yield f();
+//   ^^^^^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method f() → asy::Future<core::int*>*
+  return asy::Future::value<core::int*>(7);
+static method g() → core::List<core::int*>* {
+  invalid-expression "pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart:4:3: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
+  yield f();
+  ^";
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline.expect
new file mode 100644
index 0000000..f9aee8d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+Future<int> f() => Future.value(7);
+List<int> g() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f9aee8d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+Future<int> f() => Future.value(7);
+List<int> g() {}
diff --git a/pkg/front_end/testcases/general/escape.dart.textual_outline.expect b/pkg/front_end/testcases/general/escape.dart.textual_outline.expect
new file mode 100644
index 0000000..55378bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/escape.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {
+  var field;
+}
+
+class B {
+  var field;
+}
+
+class C {
+  operator ==(x) => false;
+}
+
+class X implements A, B {
+  var field;
+}
+
+void useAsA(A object) {}
+void useAsB(B object) {}
+void escape(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/escape.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/escape.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8cd132
--- /dev/null
+++ b/pkg/front_end/testcases/general/escape.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class A {
+  var field;
+}
+
+class B {
+  var field;
+}
+
+class C {
+  operator ==(x) => false;
+}
+
+class X implements A, B {
+  var field;
+}
+
+main() {}
+void escape(x) {}
+void useAsA(A object) {}
+void useAsB(B object) {}
diff --git a/pkg/front_end/testcases/general/export_main.dart.textual_outline.expect b/pkg/front_end/testcases/general/export_main.dart.textual_outline.expect
new file mode 100644
index 0000000..8692093
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_main.dart.textual_outline.expect
@@ -0,0 +1 @@
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general/export_main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/export_main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8692093
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_main.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general/export_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/export_test.dart.textual_outline.expect
new file mode 100644
index 0000000..069d6b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_test.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/export_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/export_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..069d6b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/expressions.dart.textual_outline.expect b/pkg/front_end/testcases/general/expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..bfda72e
--- /dev/null
+++ b/pkg/front_end/testcases/general/expressions.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo({fisk}) {}
+caller(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a1c989b
--- /dev/null
+++ b/pkg/front_end/testcases/general/expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+caller(f) {}
+foo({fisk}) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..0ff9f7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class SuperClass {}
+
+mixin Mixin<T> {}
+
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..975364e
--- /dev/null
+++ b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+class SuperClass {}
+
+main() {}
+mixin Mixin<T> {}
diff --git a/pkg/front_end/testcases/general/external.dart.textual_outline.expect b/pkg/front_end/testcases/general/external.dart.textual_outline.expect
new file mode 100644
index 0000000..fbcbaee
--- /dev/null
+++ b/pkg/front_end/testcases/general/external.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:isolate';
+
+var subscription;
+void onData(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/external.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/external.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1db5cd5
--- /dev/null
+++ b/pkg/front_end/testcases/general/external.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:isolate';
+
+main() {}
+var subscription;
+void onData(x) {}
diff --git a/pkg/front_end/testcases/general/external_import.dart.textual_outline.expect b/pkg/front_end/testcases/general/external_import.dart.textual_outline.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general/external_import.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/external_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/external_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general/external_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/fallthrough.dart.textual_outline.expect b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline.expect
new file mode 100644
index 0000000..64fdb31
--- /dev/null
+++ b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline.expect
@@ -0,0 +1 @@
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/fallthrough.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..64fdb31
--- /dev/null
+++ b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline.expect b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline.expect
new file mode 100644
index 0000000..eb10d58
--- /dev/null
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+  @Double()
+  double x;
+  @Double()
+  double y;
+  Pointer<Coordinate> next;
+  factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb10d58
--- /dev/null
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+  @Double()
+  double x;
+  @Double()
+  double y;
+  Pointer<Coordinate> next;
+  factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/fibonacci.dart.textual_outline.expect b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline.expect
new file mode 100644
index 0000000..178655b
--- /dev/null
+++ b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/fibonacci.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..178655b
--- /dev/null
+++ b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/for_in_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general/for_in_scope.dart.strong.transformed.expect
index cb9a540..ae6b6e7 100644
--- a/pkg/front_end/testcases/general/for_in_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/for_in_scope.dart.strong.transformed.expect
@@ -1,11 +1,10 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method main(core::List<core::String*>* arguments) → dynamic {
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(arguments).{core::Iterable::iterator};
+    core::Iterator<core::String*>* :sync-for-iterator = arguments.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String* arguments = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..24765f4
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline.expect
@@ -0,0 +1 @@
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..24765f4
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
index e6b4f0c..6065d16 100644
--- a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
@@ -66,7 +66,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Super extends core::Object {
   field core::int* superInstanceField = null;
@@ -87,7 +86,7 @@
     core::String* local;
     dynamic untypedLocal;
     {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String*>[]).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = <core::String*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t1 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -96,7 +95,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -105,7 +104,7 @@
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t3 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -114,7 +113,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -123,7 +122,7 @@
       }
     }
     {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(<core::double*>[]).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = <core::double*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::double* #t5 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -132,7 +131,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -141,7 +140,7 @@
       }
     }
     {
-      core::Iterator<core::bool*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::bool*>*>(<core::bool*>[]).{core::Iterable::iterator};
+      core::Iterator<core::bool*>* :sync-for-iterator = <core::bool*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::bool* #t7 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -150,7 +149,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -159,7 +158,7 @@
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t9 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -168,7 +167,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -178,7 +177,7 @@
     }
     self::C* c = new self::C::•();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -187,7 +186,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -196,7 +195,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t13 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -209,7 +208,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -222,7 +221,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t15 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -239,7 +238,7 @@
     for (main() in []) {}
          ^^^^";
       {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -256,7 +255,7 @@
     for (var x, y in <int>[]) {
          ^^^";
       {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t17 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -272,7 +271,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..1b8a2ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+bool topLevelField;
+var untypedTopLevelField;
+
+class Super {
+  int superInstanceField;
+  var untypedSuperInstanceField;
+}
+
+class C extends Super {
+  int instanceField;
+  var untypedInstanceField;
+  static double staticField;
+  static var untypedStaticField;
+  m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82cde47
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+bool topLevelField;
+
+class C extends Super {
+  int instanceField;
+  m() {}
+  static double staticField;
+  static var untypedStaticField;
+  var untypedInstanceField;
+}
+
+class Super {
+  int superInstanceField;
+  var untypedSuperInstanceField;
+}
+
+main() {}
+var untypedTopLevelField;
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..c81b41e
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class A {
+  dynamic operator +(covariant int a) => null;
+}
+
+class B {
+  dynamic operator +(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+class D {
+  dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+  dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1eb7ad
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+abstract class C implements A, B {}
+
+class A {
+  dynamic operator +(covariant int a) => null;
+}
+
+class B {
+  dynamic operator +(dynamic b) => null;
+}
+
+class D {
+  dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+  dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/function_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..48b83ef
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+var x = () {
+  var y = 42;
+  return y;
+};
+main() {}
diff --git a/pkg/front_end/testcases/general/function_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dde78ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+main() {}
+var x = () {
+  var y = 42;
+  return y;
+};
diff --git a/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline.expect
new file mode 100644
index 0000000..4e7d345
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+T identity<T>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+String x = identity;
+String y = identityObject;
+String z = identityList;
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..260816e
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+String x = identity;
+String y = identityObject;
+String z = identityList;
+T identity<T>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_default_value.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_default_value.dart.textual_outline.expect
new file mode 100644
index 0000000..5b2ed24
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_default_value.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void Function({obj: Object}) x;
+main() { }
diff --git a/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..0f294ea
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart" show Expect;
+
+test(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..22e03b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart" show Expect;
+
+main() {}
+test(f) {}
diff --git a/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline.expect
new file mode 100644
index 0000000..2efaae2
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef F = int Function(int f(String x));
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a2bb0c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef F = int Function(int f(String x));
diff --git a/pkg/front_end/testcases/general/functions.dart.textual_outline.expect b/pkg/front_end/testcases/general/functions.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/functions.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/functions.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect b/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
index 1d1c466..206c905 100644
--- a/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
@@ -21,8 +21,8 @@
     final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -35,13 +35,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -54,8 +54,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,13 +68,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e798df9
--- /dev/null
+++ b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import 'dart:async';
+
+class A {
+  dynamic foo() => null;
+}
+
+class B {
+  A a;
+  Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+  B b = B();
+  Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e798df9
--- /dev/null
+++ b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+import 'dart:async';
+
+class A {
+  dynamic foo() => null;
+}
+
+class B {
+  A a;
+  Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+  B b = B();
+  Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline.expect
new file mode 100644
index 0000000..8711ddc
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3eb959f
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
diff --git a/pkg/front_end/testcases/general/getter_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/getter_call.dart.textual_outline.expect
new file mode 100644
index 0000000..d9d43c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/getter_call.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+int read(int value) => enableRead ? value : -1;
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+
+class Class {
+  Function field1a = method1;
+  int Function() field1b = method1;
+  int Function(int a) field2 = method2;
+  int Function(int a, int b) field3 = method3;
+  int Function(int a, [int b]) field4 = method4;
+  int Function([int a, int b]) field5 = method5;
+  int Function(int a, {int b}) field6 = method6;
+  int Function({int a, int b}) field7 = method7;
+  Function get getter1a => method1;
+  int Function() get getter1b => method1;
+  int Function(int a) get getter2 => method2;
+  int Function(int a, int b) get getter3 => method3;
+  int Function(int a, [int b]) get getter4 => method4;
+  int Function([int a, int b]) get getter5 => method5;
+  int Function(int a, {int b}) get getter6 => method6;
+  int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+  Function get field1a {}
+  int Function() get field1b {}
+  int Function(int a) get field2 {}
+  int Function(int a, int b) get field3 {}
+  int Function(int a, [int b]) get field4 {}
+  int Function([int a, int b]) get field5 {}
+  int Function(int a, {int b}) get field6 {}
+  int Function({int a, int b}) get field7 {}
+  Function get getter1a {}
+  int Function() get getter1b {}
+  int Function(int a) get getter2 {}
+  int Function(int a, int b) get getter3 {}
+  int Function(int a, [int b]) get getter4 {}
+  int Function([int a, int b]) get getter5 {}
+  int Function(int a, {int b}) get getter6 {}
+  int Function({int a, int b}) get getter7 {}
+}
+
+main() {}
+callField(Class c) {}
+callGetter(Class c) {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/getter_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/getter_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fafec6e
--- /dev/null
+++ b/pkg/front_end/testcases/general/getter_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+callField(Class c) {}
+callGetter(Class c) {}
+
+class Class {
+  Function field1a = method1;
+  Function get getter1a => method1;
+  int Function() field1b = method1;
+  int Function() get getter1b => method1;
+  int Function([int a, int b]) field5 = method5;
+  int Function([int a, int b]) get getter5 => method5;
+  int Function(int a) field2 = method2;
+  int Function(int a) get getter2 => method2;
+  int Function(int a, [int b]) field4 = method4;
+  int Function(int a, [int b]) get getter4 => method4;
+  int Function(int a, int b) field3 = method3;
+  int Function(int a, int b) get getter3 => method3;
+  int Function(int a, {int b}) field6 = method6;
+  int Function(int a, {int b}) get getter6 => method6;
+  int Function({int a, int b}) field7 = method7;
+  int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+  Function get field1a {}
+  Function get getter1a {}
+  int Function() get field1b {}
+  int Function() get getter1b {}
+  int Function([int a, int b]) get field5 {}
+  int Function([int a, int b]) get getter5 {}
+  int Function(int a) get field2 {}
+  int Function(int a) get getter2 {}
+  int Function(int a, [int b]) get field4 {}
+  int Function(int a, [int b]) get getter4 {}
+  int Function(int a, int b) get field3 {}
+  int Function(int a, int b) get getter3 {}
+  int Function(int a, {int b}) get field6 {}
+  int Function(int a, {int b}) get getter6 {}
+  int Function({int a, int b}) get field7 {}
+  int Function({int a, int b}) get getter7 {}
+}
+
+expect(expected, actual) {}
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+int read(int value) => enableRead ? value : -1;
+main() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..b2d893c
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ce86ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..24ca63b
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..754ba3f
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general/hello.dart.textual_outline.expect b/pkg/front_end/testcases/general/hello.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/hello.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/hello.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/hello.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/hello.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..c83fa07
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c83fa07
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Class {
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/ignore_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline.expect
new file mode 100644
index 0000000..81dde83
--- /dev/null
+++ b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+import "dart:core" as core;
+
+class A implements core.Function {
+  operator ==(other) => false;
+}
+
+class B implements Function {
+  operator ==(other) => false;
+}
+
+class Function {
+  core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/ignore_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81dde83
--- /dev/null
+++ b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+import "dart:core" as core;
+
+class A implements core.Function {
+  operator ==(other) => false;
+}
+
+class B implements Function {
+  operator ==(other) => false;
+}
+
+class Function {
+  core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline.expect b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..31deaf6
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+const constTopLevelField = 42;
+
+class C {
+  const C(x);
+  static const constField = 87;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7a87544
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+  const C(x);
+  static const constField = 87;
+}
+
+const constTopLevelField = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_new.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline.expect
new file mode 100644
index 0000000..c3f5004
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import "implicit_new.dart" as prefix;
+
+class Foo {
+  operator +(other) => null;
+}
+
+class Bar {
+  Bar.named();
+  operator +(other) => null;
+}
+
+testNSM() {}
+f(x) => x;
+
+class IndexTester {
+  operator [](_) => null;
+  void operator []=(_a, _b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_new.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72ae030
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import "implicit_new.dart" as prefix;
+
+class Bar {
+  Bar.named();
+  operator +(other) => null;
+}
+
+class Foo {
+  operator +(other) => null;
+}
+
+class IndexTester {
+  operator [](_) => null;
+  void operator []=(_a, _b) {}
+}
+
+f(x) => x;
+main() {}
+testNSM() {}
diff --git a/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline.expect
new file mode 100644
index 0000000..ea2f363
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+  static bool alwaysTrue() {}
+  static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea2f363
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+  static bool alwaysTrue() {}
+  static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..663566a
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class C {
+  m() {}
+  testC() {}
+}
+
+class D extends C {
+  testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..663566a
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class C {
+  m() {}
+  testC() {}
+}
+
+class D extends C {
+  testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline.expect
new file mode 100644
index 0000000..4e8aa56
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c010bc
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..9f1f251
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4bc9bf2
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline.expect
new file mode 100644
index 0000000..5f91bbc
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4574f84
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline.expect
new file mode 100644
index 0000000..1d6b54a
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8b0c6e4
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/incomplete_field_formal_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/general/incomplete_field_formal_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..5811235
--- /dev/null
+++ b/pkg/front_end/testcases/general/incomplete_field_formal_parameter.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  C.a(this.);
+  C.b(this.);
+  C.c(this., p);
+  C.d(this., p);
+}
diff --git a/pkg/front_end/testcases/general/infer_field_from_multiple.dart.strong.expect b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.strong.expect
index 4b93926..9281410 100644
--- a/pkg/front_end/testcases/general/infer_field_from_multiple.dart.strong.expect
+++ b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.strong.expect
@@ -213,11 +213,11 @@
   field core::int* field1;
   field invalid-type field2;
   field core::int* field3 = 0;
-  field invalid-type field4 = 0 as{TypeError} invalid-type;
+  field invalid-type field4 = 0;
   field core::int* field5;
   field invalid-type field6;
   field core::int* field7 = 0;
-  field invalid-type field8 = 0 as{TypeError} invalid-type;
+  field invalid-type field8 = 0;
   field dynamic field9;
   generic-covariant-impl field core::int* field10;
   generic-covariant-impl field invalid-type field11;
@@ -236,11 +236,11 @@
   field core::int* field1;
   field invalid-type field2;
   field core::int* field3 = 0;
-  field invalid-type field4 = 0 as{TypeError} invalid-type;
+  field invalid-type field4 = 0;
   field core::int* field5;
   field invalid-type field6;
   field core::int* field7 = 0;
-  field invalid-type field8 = 0 as{TypeError} invalid-type;
+  field invalid-type field8 = 0;
   field dynamic field9;
   generic-covariant-impl field self::D::T* field10;
   generic-covariant-impl field self::D::T* field11;
diff --git a/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline.expect
new file mode 100644
index 0000000..9131faf
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline.expect
@@ -0,0 +1,121 @@
+class A<T> {
+  var field1 = 0;
+  var field2 = 0;
+  var field3 = 0;
+  var field4 = 0;
+  int field5;
+  int field6;
+  int field7;
+  int field8;
+  var field9;
+  T field10;
+  T field11;
+  T field12;
+  T field13;
+  T field14;
+  var field15 = 0;
+  int field16;
+  var field17 = 0;
+  int field18;
+}
+
+class B<T, S> {
+  var field1 = 1;
+  var field2 = '';
+  var field3 = 1;
+  var field4 = '';
+  int field5;
+  String field6;
+  int field7;
+  String field8;
+  var field9;
+  T field10;
+  S field11;
+  T field12;
+  T field13;
+  S field14;
+  int field15;
+  var field16 = 0;
+  String field17;
+  var field18 = '';
+}
+
+class C implements A<int>, B<int, String> {
+  var field1;
+  var field2;
+  var field3 = 0;
+  var field4 = 0;
+  var field5;
+  var field6;
+  var field7 = 0;
+  var field8 = 0;
+  var field9;
+  var field10;
+  var field11;
+  int field12;
+  var field13 = 0;
+  int field14;
+  var field15;
+  var field16;
+  var field17;
+  var field18;
+  C(
+      this.field1,
+      this.field2,
+      this.field3,
+      this.field4,
+      this.field5,
+      this.field6,
+      this.field7,
+      this.field8,
+      this.field9,
+      this.field10,
+      this.field11,
+      this.field12,
+      this.field13,
+      this.field14,
+      this.field15,
+      this.field16,
+      this.field17,
+      this.field18);
+}
+
+class D<T> implements A<T>, B<T, T> {
+  var field1;
+  var field2;
+  var field3 = 0;
+  var field4 = 0;
+  var field5;
+  var field6;
+  var field7 = 0;
+  var field8 = 0;
+  var field9;
+  var field10;
+  var field11;
+  T field12;
+  var field13 = null;
+  T field14;
+  var field15;
+  var field16;
+  var field17;
+  var field18;
+  D(
+      this.field1,
+      this.field2,
+      this.field3,
+      this.field4,
+      this.field5,
+      this.field6,
+      this.field7,
+      this.field8,
+      this.field9,
+      this.field10,
+      this.field11,
+      this.field12,
+      this.field13,
+      this.field14,
+      this.field15,
+      this.field16,
+      this.field17,
+      this.field18);
+}
diff --git a/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b2f2254
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline_modelled.expect
@@ -0,0 +1,121 @@
+class A<T> {
+  T field10;
+  T field11;
+  T field12;
+  T field13;
+  T field14;
+  int field16;
+  int field18;
+  int field5;
+  int field6;
+  int field7;
+  int field8;
+  var field1 = 0;
+  var field15 = 0;
+  var field17 = 0;
+  var field2 = 0;
+  var field3 = 0;
+  var field4 = 0;
+  var field9;
+}
+
+class B<T, S> {
+  S field11;
+  S field14;
+  String field17;
+  String field6;
+  String field8;
+  T field10;
+  T field12;
+  T field13;
+  int field15;
+  int field5;
+  int field7;
+  var field1 = 1;
+  var field16 = 0;
+  var field18 = '';
+  var field2 = '';
+  var field3 = 1;
+  var field4 = '';
+  var field9;
+}
+
+class C implements A<int>, B<int, String> {
+  C(
+      this.field1,
+      this.field2,
+      this.field3,
+      this.field4,
+      this.field5,
+      this.field6,
+      this.field7,
+      this.field8,
+      this.field9,
+      this.field10,
+      this.field11,
+      this.field12,
+      this.field13,
+      this.field14,
+      this.field15,
+      this.field16,
+      this.field17,
+      this.field18);
+  int field12;
+  int field14;
+  var field10;
+  var field11;
+  var field13 = 0;
+  var field15;
+  var field16;
+  var field17;
+  var field18;
+  var field1;
+  var field2;
+  var field3 = 0;
+  var field4 = 0;
+  var field5;
+  var field6;
+  var field7 = 0;
+  var field8 = 0;
+  var field9;
+}
+
+class D<T> implements A<T>, B<T, T> {
+  D(
+      this.field1,
+      this.field2,
+      this.field3,
+      this.field4,
+      this.field5,
+      this.field6,
+      this.field7,
+      this.field8,
+      this.field9,
+      this.field10,
+      this.field11,
+      this.field12,
+      this.field13,
+      this.field14,
+      this.field15,
+      this.field16,
+      this.field17,
+      this.field18);
+  T field12;
+  T field14;
+  var field10;
+  var field11;
+  var field13 = null;
+  var field15;
+  var field16;
+  var field17;
+  var field18;
+  var field1;
+  var field2;
+  var field3 = 0;
+  var field4 = 0;
+  var field5;
+  var field6;
+  var field7 = 0;
+  var field8 = 0;
+  var field9;
+}
diff --git a/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline.expect
new file mode 100644
index 0000000..42aad86
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class C extends B {
+  var field;
+}
+
+class B extends A {
+  get field => null;
+  set field(value) {}
+}
+
+class A {
+  var field = 0;
+}
+
+var topLevelFieldFromA = new A().field;
+var topLevelFieldFromB = new B().field;
+var topLevelFieldFromC = new C().field;
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..69cf59c
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+  var field = 0;
+}
+
+class B extends A {
+  get field => null;
+  set field(value) {}
+}
+
+class C extends B {
+  var field;
+}
+
+main() {}
+var topLevelFieldFromA = new A().field;
+var topLevelFieldFromB = new B().field;
+var topLevelFieldFromC = new C().field;
diff --git a/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..b5af5e7
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+abstract class Base {}
+
+abstract class MixinA<T> {
+  T method(Object t);
+}
+
+abstract class Class extends Base with MixinA {
+  method(t) {}
+}
+
+abstract class YamlNode {}
+
+abstract class Map<K, V> {
+  V operator [](Object key);
+}
+
+abstract class MapMixin<K, V> implements Map<K, V> {
+  V operator [](Object key);
+}
+
+abstract class UnmodifiableMapMixin<K, V> implements Map<K, V> {}
+
+class YamlMap extends YamlNode with MapMixin, UnmodifiableMapMixin {
+  operator [](key) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e13a164
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+abstract class Base {}
+
+abstract class Class extends Base with MixinA {
+  method(t) {}
+}
+
+abstract class Map<K, V> {
+  V operator [](Object key);
+}
+
+abstract class MapMixin<K, V> implements Map<K, V> {
+  V operator [](Object key);
+}
+
+abstract class MixinA<T> {
+  T method(Object t);
+}
+
+abstract class UnmodifiableMapMixin<K, V> implements Map<K, V> {}
+
+abstract class YamlNode {}
+
+class YamlMap extends YamlNode with MapMixin, UnmodifiableMapMixin {
+  operator [](key) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..e1d5d9a
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+  var map = {
+    'foo': (String a) {
+      int c = a.length;
+    }
+  };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1d5d9a
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Class {
+  var map = {
+    'foo': (String a) {
+      int c = a.length;
+    }
+  };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/inherit_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline.expect
new file mode 100644
index 0000000..a94f799
--- /dev/null
+++ b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A implements Function {}
+
+class B extends Function {}
+
+class C extends Object with Function {}
+
+class D = Object with Function;
+main() {}
diff --git a/pkg/front_end/testcases/general/inherit_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a94f799
--- /dev/null
+++ b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A implements Function {}
+
+class B extends Function {}
+
+class C extends Object with Function {}
+
+class D = Object with Function;
+main() {}
diff --git a/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..669b460
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+  int get n => 1;
+}
+
+class B {
+  double get n => 2.0;
+}
+
+abstract class C implements A, B {}
+
+abstract class D implements C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d216e6b
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class C implements A, B {}
+
+abstract class D implements C {}
+
+class A {
+  int get n => 1;
+}
+
+class B {
+  double get n => 2.0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..fc2a60f
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+  T f(int x) {}
+}
+
+abstract class I<T> {
+  T f(Object x);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1269acd
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+  T f(Object x);
+}
+
+class B<T> {
+  T f(int x) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..aec0365
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+  void f(F<T> x, int y) {}
+}
+
+abstract class I<T> {
+  void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..033ea81
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+  void f(F<T> x, Object y);
+}
+
+class B<T> {
+  void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..203e8cd
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+typedef void F<T>(T t);
+
+abstract class A<T> {
+  void f(T x, int y);
+}
+
+class B<T> implements A<F<T>> {
+  void f(F<T> x, int y) {}
+}
+
+abstract class I<T> implements A<F<T>> {
+  void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4615ebb
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+abstract class A<T> {
+  void f(T x, int y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> implements A<F<T>> {
+  void f(F<T> x, Object y);
+}
+
+class B<T> implements A<F<T>> {
+  void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..60f20bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  String operator +(int i) => '';
+}
+
+test(int i, String s, A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a50d569
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+  String operator +(int i) => '';
+}
+
+main() {}
+test(int i, String s, A a) {}
diff --git a/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline.expect
new file mode 100644
index 0000000..225b633
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class C {
+  C();
+  factory C.fact() => null;
+  factory C.fact2() = D;
+  C.nonFact();
+  C.nonFact2() : this.nonFact();
+  static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+void topLevelFunction(int i) {}
+bad() {}
+ok() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45d7ffc
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+bad() {}
+
+class C {
+  C();
+  C.nonFact();
+  C.nonFact2() : this.nonFact();
+  factory C.fact() => null;
+  factory C.fact2() = D;
+  static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+main() {}
+ok() {}
+void topLevelFunction(int i) {}
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..6f6cae0
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.textual_outline.expect
@@ -0,0 +1,147 @@
+class Operators1 {
+  operator ==() => true;
+  operator <() => true;
+  operator >() => true;
+  operator <=() => true;
+  operator >=() => true;
+  operator +() => true;
+  operator /() => true;
+  operator ~/() => true;
+  operator *() => true;
+  operator %() => true;
+  operator |() => true;
+  operator ^() => true;
+  operator &() => true;
+  operator <<() => true;
+  operator >>() => true;
+  operator []=(a, b, c) => true;
+  operator []() => true;
+  operator ~(a) => true;
+}
+class Operators2 {
+  operator ==(a, b) => true;
+  operator <(a, b) => true;
+  operator >(a, b) => true;
+  operator <=(a, b) => true;
+  operator >=(a, b) => true;
+  operator -(a, b) => true;
+  operator +(a, b) => true;
+  operator /(a, b) => true;
+  operator ~/(a, b) => true;
+  operator *(a, b) => true;
+  operator %(a, b) => true;
+  operator |(a, b) => true;
+  operator ^(a, b) => true;
+  operator &(a, b) => true;
+  operator <<(a, b) => true;
+  operator >>(a, b) => true;
+  operator []=(a, b, c) => true;
+  operator [](a, b) => true;
+  operator ~(a, b) => true;
+}
+class Operators3 {
+  operator ==([a]) => true;
+  operator <([a]) => true;
+  operator >([a]) => true;
+  operator <=([a]) => true;
+  operator >=([a]) => true;
+  operator -([a]) => true;
+  operator +([a]) => true;
+  operator /([a]) => true;
+  operator ~/([a]) => true;
+  operator *([a]) => true;
+  operator %([a]) => true;
+  operator |([a]) => true;
+  operator ^([a]) => true;
+  operator &([a]) => true;
+  operator <<([a]) => true;
+  operator >>([a]) => true;
+  operator []=([a, b]) => true;
+  operator []([a]) => true;
+  operator ~([a]) => true;
+}
+class Operators4 {
+  operator ==({a}) => true;
+  operator <({a}) => true;
+  operator >({a}) => true;
+  operator <=({a}) => true;
+  operator >=({a}) => true;
+  operator -({a}) => true;
+  operator +({a}) => true;
+  operator /({a}) => true;
+  operator ~/({a}) => true;
+  operator *({a}) => true;
+  operator %({a}) => true;
+  operator |({a}) => true;
+  operator ^({a}) => true;
+  operator &({a}) => true;
+  operator <<({a}) => true;
+  operator >>({a}) => true;
+  operator []=({a, b}) => true;
+  operator []({a}) => true;
+  operator ~({a}) => true;
+}
+class Operators5 {
+  operator ==(a, [b]) => true;
+  operator <(a, [b]) => true;
+  operator >(a, [b]) => true;
+  operator <=(a, [b]) => true;
+  operator >=(a, [b]) => true;
+  operator -(a, [b]) => true;
+  operator +(a, [b]) => true;
+  operator /(a, [b]) => true;
+  operator ~/(a, [b]) => true;
+  operator *(a, [b]) => true;
+  operator %(a, [b]) => true;
+  operator |(a, [b]) => true;
+  operator ^(a, [b]) => true;
+  operator &(a, [b]) => true;
+  operator <<(a, [b]) => true;
+  operator >>(a, [b]) => true;
+  operator []=(a, b, [c]) => true;
+  operator [](a, [b]) => true;
+  operator ~(a, [b]) => true;
+}
+class Operators6 {
+  operator ==(a, {b}) => true;
+  operator <(a, {b}) => true;
+  operator >(a, {b}) => true;
+  operator <=(a, {b}) => true;
+  operator >=(a, {b}) => true;
+  operator -(a, {b}) => true;
+  operator +(a, {b}) => true;
+  operator /(a, {b}) => true;
+  operator ~/(a, {b}) => true;
+  operator *(a, {b}) => true;
+  operator %(a, {b}) => true;
+  operator |(a, {b}) => true;
+  operator ^(a, {b}) => true;
+  operator &(a, {b}) => true;
+  operator <<(a, {b}) => true;
+  operator >>(a, {b}) => true;
+  operator []=(a, b, {c}) => true;
+  operator [](a, {b}) => true;
+  operator ~(a, {b}) => true;
+}
+class Operators7 {
+  operator ==<T>(a) => true;
+  operator ><T>(a) => true;
+  operator <=<T>(a) => true;
+  operator >=<T>(a) => true;
+  operator -<T>() => true;
+  operator -<T>(a) => true;
+  operator +<T>(a) => true;
+  operator /<T>(a) => true;
+  operator ~/<T>(a) => true;
+  operator *<T>(a) => true;
+  operator %<T>(a) => true;
+  operator |<T>(a) => true;
+  operator ^<T>(a) => true;
+  operator &<T>(a) => true;
+  operator <<<T>(a) => true;
+  operator >><T>(a) => true;
+  operator []=<T>(a, b) => true;
+  operator []<T>(a) => true;
+  operator ~<T>() => true;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/invalid_operator2.dart.strong.expect b/pkg/front_end/testcases/general/invalid_operator2.dart.strong.expect
index ada9780..26fc9ec 100644
--- a/pkg/front_end/testcases/general/invalid_operator2.dart.strong.expect
+++ b/pkg/front_end/testcases/general/invalid_operator2.dart.strong.expect
@@ -33,6 +33,6 @@
     ;
   operator <<() → dynamic {}
   operator >(dynamic a) → invalid-type
-    return true as{TypeError} invalid-type;
+    return true;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/invalid_operator2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/invalid_operator2.dart.strong.transformed.expect
index ada9780..26fc9ec 100644
--- a/pkg/front_end/testcases/general/invalid_operator2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/invalid_operator2.dart.strong.transformed.expect
@@ -33,6 +33,6 @@
     ;
   operator <<() → dynamic {}
   operator >(dynamic a) → invalid-type
-    return true as{TypeError} invalid-type;
+    return true;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/invalid_operator2.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_operator2.dart.textual_outline.expect
new file mode 100644
index 0000000..5f489fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_operator2.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Operators7 {
+  operator <<( ){ }
+  Toperator>(a) => true;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/invalid_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline.expect
new file mode 100644
index 0000000..6cef1e5
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  static foo() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a02ed16
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  static foo() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/invocations.dart.textual_outline.expect b/pkg/front_end/testcases/general/invocations.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/invocations.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invocations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/invocations.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/issue129167943.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline.expect
new file mode 100644
index 0000000..2d33b0a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline.expect
@@ -0,0 +1,55 @@
+abstract class A {}
+
+abstract class B {
+  void foo(num x);
+}
+
+abstract class C implements B {
+  void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+  void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+  void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+  void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+  void foo(num x);
+}
+
+abstract class E {
+  void set foo(num x);
+}
+
+abstract class G implements E {
+  void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+  void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+  void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+  void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+  void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue129167943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3d5bb93
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline_modelled.expect
@@ -0,0 +1,55 @@
+abstract class A {}
+
+abstract class B {
+  void foo(num x);
+}
+
+abstract class C implements B {
+  void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+  void foo(covariant int x);
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+  void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+  void foo(num x);
+}
+
+abstract class E {
+  void set foo(num x);
+}
+
+abstract class G implements E {
+  void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+  void set foo(covariant int x);
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+  void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+  void set foo(num x);
+}
+
+class D2 implements A, C, B {
+  void foo(covariant int x) {}
+}
+
+class H2 implements A, E, G {
+  void set foo(covariant int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue34515.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue34515.dart.textual_outline.expect
new file mode 100644
index 0000000..0d74c15
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34515.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue34515.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue34515.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..608fcf1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34515.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/issue34899.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue34899.dart.textual_outline.expect
new file mode 100644
index 0000000..18c8795
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34899.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class Foo<T> {
+  final Future<dynamic> Function() quux;
+  T t;
+  Foo(this.quux, this.t);
+  Future<T> call() => quux().then<T>((_) => t);
+}
+
+class Bar {
+  Foo<Baz> qux;
+  Future<void> quuz() =>
+      qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+  Grault corge(Baz baz) => null;
+  void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue34899.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue34899.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1b2af4b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34899.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class Bar {
+  Foo<Baz> qux;
+  Future<void> quuz() =>
+      qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+  Grault corge(Baz baz) => null;
+  void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Foo<T> {
+  Foo(this.quux, this.t);
+  Future<T> call() => quux().then<T>((_) => t);
+  T t;
+  final Future<dynamic> Function() quux;
+}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue35875.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue35875.dart.textual_outline.expect
new file mode 100644
index 0000000..5552256
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue35875.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  int a;
+  A(int a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue35875.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue35875.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a56bd0f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue35875.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+  A(int a) {}
+  int a;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37027.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue37027.dart.strong.transformed.expect
index 606d3a0..342575d 100644
--- a/pkg/front_end/testcases/general/issue37027.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue37027.dart.strong.transformed.expect
@@ -2,7 +2,6 @@
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
-import "dart:_internal" as _in;
 
 class C extends core::Object {
   final field core::Set<core::int*>* s;
@@ -10,7 +9,7 @@
     : self::C::s = block {
       final core::Set<core::int*>* #t1 = col::LinkedHashSet::•<core::int*>();
       {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(ell).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = ell.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           core::int* e = :sync-for-iterator.{core::Iterator::current};
           if(e.{core::int::isOdd})
diff --git a/pkg/front_end/testcases/general/issue37027.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue37027.dart.textual_outline.expect
new file mode 100644
index 0000000..40abec7
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37027.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class C {
+  final Set<int> s;
+  C(List<int> ell)
+      : s = {
+          for (var e in ell)
+            if (e.isOdd) 2 * e
+        };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37027.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue37027.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a6b9aa
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37027.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class C {
+  C(List<int> ell)
+      : s = {
+          for (var e in ell)
+            if (e.isOdd) 2 * e
+        };
+  final Set<int> s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37381.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue37381.dart.textual_outline.expect
new file mode 100644
index 0000000..0e78f9c
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37381.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<X> {
+  R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37381.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue37381.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e78f9c
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37381.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<X> {
+  R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue37776.dart.textual_outline.expect
new file mode 100644
index 0000000..fe9bbfe
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class X {
+  const X.foo();
+}
+
+class X {
+  const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue37776.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe9bbfe
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class X {
+  const X.foo();
+}
+
+class X {
+  const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue38812.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38812.dart.textual_outline.expect
new file mode 100644
index 0000000..f69b6fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38812.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef G<X> = void Function();
+
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue38812.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38812.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0058f6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38812.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
+typedef G<X> = void Function();
diff --git a/pkg/front_end/testcases/general/issue38938.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38938.dart.textual_outline.expect
new file mode 100644
index 0000000..82bf141
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38938.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  int v;
+  int v;
+  A(this.v);
+  A.second();
+}
diff --git a/pkg/front_end/testcases/general/issue38938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc11ff3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38938.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+  A(this.v);
+  A.second();
+  int v;
+  int v;
+}
diff --git a/pkg/front_end/testcases/general/issue38943.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38943.dart.textual_outline.expect
new file mode 100644
index 0000000..f78c92f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38943.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class D<X extends void Function()> {
+  factory D.foo() => new D._();
+  D._() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue38943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..256c973
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38943.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class D<X extends void Function()> {
+  D._() {}
+  factory D.foo() => new D._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue38944.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38944.dart.textual_outline.expect
new file mode 100644
index 0000000..279bc70
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38944.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general/issue38944.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38944.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..279bc70
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38944.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general/issue38961.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38961.dart.textual_outline.expect
new file mode 100644
index 0000000..f38f3d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38961.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  dynamic x = this;
+  var x = this;
+}
diff --git a/pkg/front_end/testcases/general/issue38961.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38961.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f38f3d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38961.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class C {
+  dynamic x = this;
+  var x = this;
+}
diff --git a/pkg/front_end/testcases/general/issue39344.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue39344.dart.textual_outline.expect
new file mode 100644
index 0000000..4b6675e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39344.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class A {}
+
+class B extends A {}
+
+List<B> xs;
+List<List<B>> xss;
+
+class Class<T extends A> {
+  void method1a(T t) {}
+  void method1b(T t) {}
+  void method2a(T t) {}
+  void method2b(T t) {}
+}
+
+void main() {}
+void errors() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue39344.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue39344.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc29cea
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39344.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+List<B> xs;
+List<List<B>> xss;
+
+class A {}
+
+class B extends A {}
+
+class Class<T extends A> {
+  void method1a(T t) {}
+  void method1b(T t) {}
+  void method2a(T t) {}
+  void method2b(T t) {}
+}
+
+void errors() {}
+void main() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue39421.dart.outline.expect b/pkg/front_end/testcases/general/issue39421.dart.outline.expect
index 1987156..1ca93fb 100644
--- a/pkg/front_end/testcases/general/issue39421.dart.outline.expect
+++ b/pkg/front_end/testcases/general/issue39421.dart.outline.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general/issue39421.dart:16:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general/issue39421.dart:12:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/general/issue39421.dart.strong.expect b/pkg/front_end/testcases/general/issue39421.dart.strong.expect
index 6103be6..5bdde44 100644
--- a/pkg/front_end/testcases/general/issue39421.dart.strong.expect
+++ b/pkg/front_end/testcases/general/issue39421.dart.strong.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general/issue39421.dart:16:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general/issue39421.dart:12:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 // pkg/front_end/testcases/general/issue39421.dart:16:12: Error: Can't use 'A' because it is declared more than once.
 //   foo(List<A> a) {}
 //            ^
diff --git a/pkg/front_end/testcases/general/issue39421.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue39421.dart.strong.transformed.expect
index 6103be6..5bdde44 100644
--- a/pkg/front_end/testcases/general/issue39421.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue39421.dart.strong.transformed.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general/issue39421.dart:16:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general/issue39421.dart:12:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 // pkg/front_end/testcases/general/issue39421.dart:16:12: Error: Can't use 'A' because it is declared more than once.
 //   foo(List<A> a) {}
 //            ^
diff --git a/pkg/front_end/testcases/general/issue39421.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue39421.dart.textual_outline.expect
new file mode 100644
index 0000000..8ac9791
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39421.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {}
+
+class A {}
+
+class B {
+  foo(List<Null> a) {}
+}
+
+class C extends B {
+  foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue39421.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue39421.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ac9791
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39421.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A {}
+
+class A {}
+
+class B {
+  foo(List<Null> a) {}
+}
+
+class C extends B {
+  foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue39817.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue39817.dart.strong.transformed.expect
index 896e8eb..da4a799 100644
--- a/pkg/front_end/testcases/general/issue39817.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue39817.dart.strong.transformed.expect
@@ -1,12 +1,11 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method foo() → dynamic {
   core::Null? _null;
   {
-    core::Iterator<core::Null?>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Null?>*>(_null).{core::Iterable::iterator};
+    core::Iterator<core::Null?>* :sync-for-iterator = _null.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic i = :sync-for-iterator.{core::Iterator::current};
       {}
diff --git a/pkg/front_end/testcases/general/issue39817.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue39817.dart.textual_outline.expect
new file mode 100644
index 0000000..d530fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39817.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue39817.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue39817.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d530fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39817.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
new file mode 100644
index 0000000..3071c2b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+}
+extension E ;
+on C (){ }
+errors() { }
+main() { }
diff --git a/pkg/front_end/testcases/general/issue40428.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40428.dart.textual_outline.expect
new file mode 100644
index 0000000..4508570
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40428.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+abstract class SuperClass1 {
+  final String value;
+  SuperClass1(this.value);
+}
+
+abstract class SuperClass2 {
+  final String value;
+  SuperClass2(String i) : value = i;
+}
+
+class Mixin {}
+
+class NamedMixin1 = SuperClass1 with Mixin;
+class NamedMixin2 = SuperClass2 with Mixin;
+void main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/issue40428.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40428.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b9d7f4f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40428.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+abstract class SuperClass1 {
+  SuperClass1(this.value);
+  final String value;
+}
+
+abstract class SuperClass2 {
+  SuperClass2(String i) : value = i;
+  final String value;
+}
+
+class Mixin {}
+
+class NamedMixin1 = SuperClass1 with Mixin;
+class NamedMixin2 = SuperClass2 with Mixin;
+errors() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
index 52fd146..b69d96b 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
@@ -12,8 +12,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -41,21 +41,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → void /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -70,13 +70,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general/issue40662.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40662.dart.textual_outline.expect
new file mode 100644
index 0000000..422ab5e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40662.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+bar(int a, List<int> b) {}
+foo(int x) async => bar(x - 1, x != null ? [x + 1, x + 2, await null] : null);
+void main() async => await foo(0);
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/issue40662.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40662.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19a1c91
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40662.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+bar(int a, List<int> b) {}
+expect(expected, actual) {}
+foo(int x) async => bar(x - 1, x != null ? [x + 1, x + 2, await null] : null);
+void main() async => await foo(0);
diff --git a/pkg/front_end/testcases/general/issue40744.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40744.dart.textual_outline.expect
new file mode 100644
index 0000000..dd27ae6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40744.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+const generatorConfigDefaultJson = <String, dynamic>{'a': 1};
+void helper(Map<String, dynamic> input) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue40744.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40744.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd27ae6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40744.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+const generatorConfigDefaultJson = <String, dynamic>{'a': 1};
+void helper(Map<String, dynamic> input) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue41070.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41070.dart.textual_outline.expect
new file mode 100644
index 0000000..6b9ed3f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41070.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+abstract class Mixin {}
+
+class Base {
+  final int x;
+  const Base(this.x);
+}
+
+class Application = Base with Mixin;
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/issue41070.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41070.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0d6b4da
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41070.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+abstract class Mixin {}
+
+class Base {
+  const Base(this.x);
+  final int x;
+}
+
+class Application = Base with Mixin;
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue41210a.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline.expect
new file mode 100644
index 0000000..8fc1032
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+abstract class Interface {
+  String method(num i);
+}
+
+abstract class Interface2 {
+  String method(covariant int i);
+}
+
+mixin A implements Interface {
+  String method(num i, {String s = "hello"}) => s;
+}
+
+abstract class B implements Interface {
+  String method(num i);
+}
+
+class C with A, B {}
+
+abstract class D implements Interface, Interface2 {}
+
+class E with A, D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue41210a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ec25da
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+abstract class B implements Interface {
+  String method(num i);
+}
+
+abstract class D implements Interface, Interface2 {}
+
+abstract class Interface {
+  String method(num i);
+}
+
+abstract class Interface2 {
+  String method(covariant int i);
+}
+
+class C with A, B {}
+
+class E with A, D {}
+
+main() {}
+mixin A implements Interface {
+  String method(num i, {String s = "hello"}) => s;
+}
diff --git a/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline.expect
new file mode 100644
index 0000000..7354b67
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'issue41210_lib.dart';
+
+class C with A, B {}
+
+class E with A, D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7354b67
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'issue41210_lib.dart';
+
+class C with A, B {}
+
+class E with A, D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/literals.dart.textual_outline.expect b/pkg/front_end/testcases/general/literals.dart.textual_outline.expect
new file mode 100644
index 0000000..8732e5c8
--- /dev/null
+++ b/pkg/front_end/testcases/general/literals.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+testString() {}
+testInt() {}
+testBool() {}
+testDouble() {}
+testNull() {}
+testList() {}
+testMap() {}
+testSymbol() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e45ac05
--- /dev/null
+++ b/pkg/front_end/testcases/general/literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+main() {}
+testBool() {}
+testDouble() {}
+testInt() {}
+testList() {}
+testMap() {}
+testNull() {}
+testString() {}
+testSymbol() {}
diff --git a/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline.expect b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline.expect
new file mode 100644
index 0000000..22729bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
+main() {}
diff --git a/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..20e1848
--- /dev/null
+++ b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+main() {}
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
diff --git a/pkg/front_end/testcases/general/magic_const.dart.textual_outline.expect b/pkg/front_end/testcases/general/magic_const.dart.textual_outline.expect
new file mode 100644
index 0000000..63982d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/magic_const.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Constant {
+  const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/magic_const.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/magic_const.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..98f38df
--- /dev/null
+++ b/pkg/front_end/testcases/general/magic_const.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Constant {
+  const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/many_errors.dart.textual_outline.expect b/pkg/front_end/testcases/general/many_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..76b7c69
--- /dev/null
+++ b/pkg/front_end/testcases/general/many_errors.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+  final x = null;
+  const A.named1() sync* { }
+  const A.named2() : x = new Object();
+}
+external foo(String x) { }
+class B {
+}
+class C {
+  B b;
+}
+abstract class AbstractClass {
+  const AbstractClass.id();
+}
+m() { }
+main() { }
diff --git a/pkg/front_end/testcases/general/map.dart.textual_outline.expect b/pkg/front_end/testcases/general/map.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/map.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/map.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline.expect b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline.expect
new file mode 100644
index 0000000..ab7b226
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = null;
+@a
+enum E { E1, E2, E3 }
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6cb51de
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+@a
+enum E { E1, E2, E3 }
+const a = null;
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..525a405
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+const a = null;
+@a
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77307d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+@a
+const a = null;
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/micro.dart.textual_outline.expect b/pkg/front_end/testcases/general/micro.dart.textual_outline.expect
new file mode 100644
index 0000000..1c27a80
--- /dev/null
+++ b/pkg/front_end/testcases/general/micro.dart.textual_outline.expect
@@ -0,0 +1,42 @@
+staticMethod() {}
+
+class Foo {
+  instanceMethod() {}
+}
+
+external bool externalStatic();
+
+abstract class ExternalValue {}
+
+abstract class Bar {
+  ExternalValue externalInstanceMethod();
+}
+
+external Bar createBar();
+
+class Box {
+  var field;
+}
+
+stringArgument(x) {}
+intArgument(x) {}
+
+class FinalBox {
+  final finalField;
+  FinalBox(this.finalField);
+}
+
+class SubFinalBox extends FinalBox {
+  SubFinalBox(value) : super(value);
+}
+
+class DynamicReceiver1 {
+  dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+  dynamicallyCalled(x) {}
+}
+
+void makeDynamicCall(receiver) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/micro.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/micro.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ec1840
--- /dev/null
+++ b/pkg/front_end/testcases/general/micro.dart.textual_outline_modelled.expect
@@ -0,0 +1,38 @@
+abstract class Bar {
+  ExternalValue externalInstanceMethod();
+}
+
+abstract class ExternalValue {}
+
+class Box {
+  var field;
+}
+
+class DynamicReceiver1 {
+  dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+  dynamicallyCalled(x) {}
+}
+
+class FinalBox {
+  FinalBox(this.finalField);
+  final finalField;
+}
+
+class Foo {
+  instanceMethod() {}
+}
+
+class SubFinalBox extends FinalBox {
+  SubFinalBox(value) : super(value);
+}
+
+external Bar createBar();
+external bool externalStatic();
+intArgument(x) {}
+main() {}
+staticMethod() {}
+stringArgument(x) {}
+void makeDynamicCall(receiver) {}
diff --git a/pkg/front_end/testcases/general/minimum_int.dart.textual_outline.expect b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general/minimum_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..021aaf9
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class Super {
+  Super._();
+}
+
+class Sub extends Super {
+  Sub() : super();
+  Sub.foo() : super.foo();
+}
+
+class Bad {
+  Bad.foo() : this();
+  Bad.bar() : this.baz();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+  MixinApplication() : super();
+  MixinApplication.foo() : super.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..44085f9
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class Bad {
+  Bad.bar() : this.baz();
+  Bad.foo() : this();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+  MixinApplication() : super();
+  MixinApplication.foo() : super.foo();
+}
+
+class Sub extends Super {
+  Sub() : super();
+  Sub.foo() : super.foo();
+}
+
+class Super {
+  Super._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..ee318d7
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+class EmptyClass {}
+
+var emptyClass = new EmptyClass();
+
+class ClassWithProperty {
+  EmptyClass property;
+}
+
+var classWithProperty = new ClassWithProperty();
+
+class ClassWithIndexSet {
+  operator []=(int index, int value) {}
+}
+
+var classWithIndexSet = new ClassWithIndexSet();
+
+class ClassWithIndexGet {
+  int operator [](int index) => 42;
+}
+
+var classWithIndexGet = new ClassWithIndexGet();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c685729
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class ClassWithIndexGet {
+  int operator [](int index) => 42;
+}
+
+class ClassWithIndexSet {
+  operator []=(int index, int value) {}
+}
+
+class ClassWithProperty {
+  EmptyClass property;
+}
+
+class EmptyClass {}
+
+main() {}
+var classWithIndexGet = new ClassWithIndexGet();
+var classWithIndexSet = new ClassWithIndexSet();
+var classWithProperty = new ClassWithProperty();
+var emptyClass = new EmptyClass();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
diff --git a/pkg/front_end/testcases/general/mixin.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..74bf0c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class B extends Object with M1, M2 {
+  B(value);
+}
+
+abstract class M1 {
+  m() => print("M1");
+}
+
+abstract class M2 {
+  m() => print("M2");
+}
+
+class C extends Object with M1, M2 {
+  C(value);
+}
+
+abstract class G1<T> {
+  m() => print(T);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4fd20a5
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+abstract class G1<T> {
+  m() => print(T);
+}
+
+abstract class M1 {
+  m() => print("M1");
+}
+
+abstract class M2 {
+  m() => print("M2");
+}
+
+class B extends Object with M1, M2 {
+  B(value);
+}
+
+class C extends Object with M1, M2 {
+  C(value);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline.expect
new file mode 100644
index 0000000..ee10660
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Mixin {}
+
+class Super {
+  var field = 42;
+  Super(this.field);
+}
+
+class Class = Super with Mixin;
+main() {}
+error() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..422bc1b
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Mixin {}
+
+class Super {
+  Super(this.field);
+  var field = 42;
+}
+
+class Class = Super with Mixin;
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline.expect
new file mode 100644
index 0000000..ee4aef8
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+class S {
+  foo([x]) {}
+}
+
+class M {
+  foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B1 extends S with M1, M {}
+
+class B2 extends S with M1, M2, M {}
+
+class B0X extends S with M, MX {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..70161a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,34 @@
+class M {
+  foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class S {
+  foo([x]) {}
+}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B0X extends S with M, MX {}
+
+class B1 extends S with M1, M {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2 extends S with M1, M2, M {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline.expect
new file mode 100644
index 0000000..5f79e28
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class M {
+  foo() {}
+}
+
+class N = Object with M;
+
+class C extends Object with N {}
+
+abstract class M2 implements M {
+  bar() {}
+}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+class C2 extends Object with M2 {}
+
+abstract class C3 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cce55c
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class M {
+  foo() {}
+}
+
+class N = Object with M;
+
+abstract class M2 implements M {
+  bar() {}
+}
+
+class C extends Object with N {}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+abstract class C3 extends Object with M2 {}
+
+class C2 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..d671b85
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+import "package:expect/expect.dart";
+
+class C<T> {
+  String trace;
+  C({a: 0, b: T}) : trace = "a: $a, b: $b";
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5c380c
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+import "package:expect/expect.dart";
+
+class C<T> {
+  C({a: 0, b: T}) : trace = "a: $a, b: $b";
+  String trace;
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..c16e66d
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline.expect
@@ -0,0 +1,89 @@
+typedef void TakeInts(int a, int b, int c, int d, int e);
+typedef void TakeObjectsAndInts(Object a, int b, Object c, int d, int e);
+typedef void TakeObjects(Object a, Object b, Object c, Object d, Object e);
+typedef void TakeOptionalInts([int a, int b, int c, int d]);
+typedef void TakeOptionalObjectsAndInts([Object a, int b, Object c, int d]);
+typedef void TakeNamedInts({int a, int b, int c, int d});
+typedef void TakeNamedObjectsAndInts({Object a, int b, Object c, int d});
+
+class M1 {
+  method(covariant int a, int b) {}
+}
+
+class M2 {
+  method(int a, covariant int b) {}
+}
+
+class C extends Object with M1, M2 {}
+
+class Direct {
+  void positional(covariant int a, int b, covariant int c, int d, int e) {}
+  void optional([covariant int a, int b, covariant int c, int d]) {}
+  void named({covariant int a, int b, covariant int c, int d}) {}
+}
+
+class Inherited extends Direct {}
+
+class Override1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Override2 extends Override1 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Override3 extends Override2 {
+  void method(int a, int b, int c, int d, int e) {}
+}
+
+abstract class Implement1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Implement2 {
+  void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Implement3 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement4 implements Implement3 {
+  void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Implement5 implements Implement1, Implement2, Implement4 {
+  void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Interface1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Interface2 {
+  void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Mixin1 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Mixin2 {
+  void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Superclass {
+  void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Mixed extends Superclass
+    with Mixin1, Mixin2
+    implements Interface1, Interface2 {}
+
+void main() {}
+void testDirect() {}
+void testInherited() {}
+void testOverridden() {}
+void testImplemented() {}
+void testMixed() {}
+void isTrue(bool value) {}
diff --git a/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1e2d8c
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,88 @@
+abstract class Implement1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class C extends Object with M1, M2 {}
+
+class Direct {
+  void named({covariant int a, int b, covariant int c, int d}) {}
+  void optional([covariant int a, int b, covariant int c, int d]) {}
+  void positional(covariant int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement2 {
+  void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Implement3 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement4 implements Implement3 {
+  void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Implement5 implements Implement1, Implement2, Implement4 {
+  void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Inherited extends Direct {}
+
+class Interface1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Interface2 {
+  void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class M1 {
+  method(covariant int a, int b) {}
+}
+
+class M2 {
+  method(int a, covariant int b) {}
+}
+
+class Mixed extends Superclass
+    with Mixin1, Mixin2
+    implements Interface1, Interface2 {}
+
+class Mixin1 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Mixin2 {
+  void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Override1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Override2 extends Override1 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Override3 extends Override2 {
+  void method(int a, int b, int c, int d, int e) {}
+}
+
+class Superclass {
+  void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+typedef void TakeInts(int a, int b, int c, int d, int e);
+typedef void TakeNamedInts({int a, int b, int c, int d});
+typedef void TakeNamedObjectsAndInts({Object a, int b, Object c, int d});
+typedef void TakeObjects(Object a, Object b, Object c, Object d, Object e);
+typedef void TakeObjectsAndInts(Object a, int b, Object c, int d, int e);
+typedef void TakeOptionalInts([int a, int b, int c, int d]);
+typedef void TakeOptionalObjectsAndInts([Object a, int b, Object c, int d]);
+void isTrue(bool value) {}
+void main() {}
+void testDirect() {}
+void testImplemented() {}
+void testInherited() {}
+void testMixed() {}
+void testOverridden() {}
diff --git a/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e0817ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {}
+
+class C<T extends A> {
+  T _field;
+  foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5993153
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {}
+
+class B extends A {}
+
+class C<T extends A> {
+  T _field;
+  foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..d373953
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class B {
+  int get n => 1;
+}
+
+class C {
+  double get n => 2.0;
+}
+
+mixin M on B, C {}
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e2a50a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class B {
+  int get n => 1;
+}
+
+class C {
+  double get n => 2.0;
+}
+
+main() {}
+mixin M on B, C {}
diff --git a/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline.expect
new file mode 100644
index 0000000..e92d32e
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+abstract class M {
+  var m;
+}
+
+abstract class N extends M {
+  void set superM(value) {}
+  get superM => super.m;
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0877c4a
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class M {
+  var m;
+}
+
+abstract class N extends M {
+  get superM => super.m;
+  void set superM(value) {}
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline.expect
new file mode 100644
index 0000000..2e0fe67
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A extends B with M {}
+
+class B {
+  final Object m = null;
+}
+
+class M {
+  static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e0fe67
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends B with M {}
+
+class B {
+  final Object m = null;
+}
+
+class M {
+  static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..b05a61b
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b05a61b
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..cf9319d
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class Superclass {
+  foo({alpha, beta}) {}
+  bar({beta, alpha}) {}
+  namedCallback(callback({String alpha, int beta})) {}
+}
+
+class Subclass extends Superclass {
+  foo({beta, alpha}) {}
+  bar({alpha, beta}) {}
+  namedCallback(callback({int beta, String alpha})) {}
+}
+
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a020dc2
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class Subclass extends Superclass {
+  bar({alpha, beta}) {}
+  foo({beta, alpha}) {}
+  namedCallback(callback({int beta, String alpha})) {}
+}
+
+class Superclass {
+  bar({beta, alpha}) {}
+  foo({alpha, beta}) {}
+  namedCallback(callback({String alpha, int beta})) {}
+}
+
+main() {}
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
diff --git a/pkg/front_end/testcases/general/native_as_name.dart.textual_outline.expect b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline.expect
new file mode 100644
index 0000000..546fe36
--- /dev/null
+++ b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+main() {}
+
+class W {
+  String native;
+  W() : native = "field";
+}
+
+class X {
+  String native() => "method";
+}
+
+abstract class Y1 {
+  String get native;
+}
+
+class Y2 extends Y1 {
+  @override
+  String get native => "getter";
+}
+
+class Z {
+  set native(String s) => f = s;
+  String f;
+}
diff --git a/pkg/front_end/testcases/general/native_as_name.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2897b36
--- /dev/null
+++ b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+abstract class Y1 {
+  String get native;
+}
+
+class W {
+  String native;
+  W() : native = "field";
+}
+
+class X {
+  String native() => "method";
+}
+
+class Y2 extends Y1 {
+  @override
+  String get native => "getter";
+}
+
+class Z {
+  String f;
+  set native(String s) => f = s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline.expect
new file mode 100644
index 0000000..0bad45d
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+const int foo = const int.fromEnvironment("fisk");
+
+class A {
+  final int bar;
+  const A(this.bar);
+}
+
+class B {
+  final A baz;
+  const B(this.baz);
+}
+
+class C {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2ae67e
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class A {
+  const A(this.bar);
+  final int bar;
+}
+
+class B {
+  const B(this.baz);
+  final A baz;
+}
+
+class C {
+  fun() {}
+}
+
+const int foo = const int.fromEnvironment("fisk");
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline.expect
new file mode 100644
index 0000000..bf9e0fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class NumField {
+  num field;
+}
+
+class IntField {
+  int field;
+}
+
+class DoubleField {
+  double field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..15987b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class DoubleField {
+  double field;
+}
+
+class IntField {
+  int field;
+}
+
+class NumField {
+  num field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variance.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline.expect
new file mode 100644
index 0000000..5ce634d
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+void testTypeAliasAsTypeArgument() {}
+void testNested() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d86b71
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+F<X> toF<X>(X x) => null;
+
+class A<X> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+main() {}
+typedef F<X> = void Function<Y extends X>();
+typedef Fcon<X> = Function(X);
+typedef FconBound<X extends num> = Function(X);
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef Fcov<X> = X Function();
+typedef FcovBound<X extends num> = X Function();
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef Finv<X> = X Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+void testNested() {}
+void testTypeAliasAsTypeArgument() {}
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..8aa3b3b
--- /dev/null
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8aa3b3b
--- /dev/null
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline.expect b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..d3da106
--- /dev/null
+++ b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline.expect
@@ -0,0 +1,79 @@
+class C<T> {
+  C(this.field1)
+      : field2 = (() => field1),
+        field3 = ((T t) {}),
+        field4 = ((T t) => t),
+        field5 = (() => () => field1),
+        field6 = ((T Function() f) {}),
+        field7 = ((T Function() f) => field1),
+        field8 = ((void Function(T) f) {}),
+        field9 = ((void Function(T) f) => field1),
+        field10 = ((T Function(T) f) {}),
+        field11 = ((T Function(T) f) => field1),
+        field12 = <S extends T>() => null,
+        field13 = <S extends T>(S s) {},
+        field14 = <S extends T>(S s) => s,
+        field15 = ((S Function<S extends T>() f) {});
+  T field1;
+  T Function() field2;
+  void Function(T) field3;
+  T Function(T) field4;
+  T Function() Function() field5;
+  void Function(T Function()) field6;
+  T Function(T Function()) field7;
+  void Function(void Function(T)) field8;
+  T Function(void Function(T)) field9;
+  void Function(T Function(T)) field10;
+  T Function(T Function(T)) field11;
+  S Function<S extends T>() field12;
+  void Function<S extends T>(S) field13;
+  S Function<S extends T>(S) field14;
+  void Function(S Function<S extends T>()) field15;
+  T get getter1 => field1;
+  T Function() get getter2 => field2;
+  void Function(T) get getter3 => field3;
+  T Function(T) get getter4 => field4;
+  T Function() Function() get getter5 => field5;
+  void Function(T Function()) get getter6 => field6;
+  T Function(T Function()) get getter7 => field7;
+  void Function(void Function(T)) get getter8 => field8;
+  T Function(void Function(T)) get getter9 => field9;
+  void Function(T Function(T)) get getter10 => field10;
+  T Function(T Function(T)) get getter11 => field11;
+  S Function<S extends T>() get getter12 => field12;
+  void Function<S extends T>(S) get getter13 => field13;
+  S Function<S extends T>(S) get getter14 => field14;
+  void Function(S Function<S extends T>()) get getter15 => field15;
+  void set setter1(T value) {}
+  void set setter2(T Function() value) {}
+  void set setter3(void Function(T) value) {}
+  void set setter4(T Function(T) value) {}
+  void set setter5(T Function() Function() value) {}
+  void set setter6(void Function(T Function()) value) {}
+  void set setter7(T Function(T Function()) value) {}
+  void set setter8(void Function(void Function(T)) value) {}
+  void set setter9(T Function(void Function(T)) value) {}
+  void set setter10(void Function(T Function(T)) value) {}
+  void set setter11(T Function(T Function(T)) value) {}
+  void set setter12(S Function<S extends T>() value) {}
+  void set setter13(void Function<S extends T>(S) value) {}
+  void set setter14(S Function<S extends T>(S) value) {}
+  void set setter15(void Function(S Function<S extends T>()) value) {}
+  void method1(T value) {}
+  void method2(T Function() value) {}
+  void method3(void Function(T) value) {}
+  void method4(T Function(T) value) {}
+  void method5(T Function() Function() value) {}
+  void method6(void Function(T Function()) value) {}
+  void method7(T Function(T Function()) value) {}
+  void method8(void Function(void Function(T)) value) {}
+  void method9(T Function(void Function(T)) value) {}
+  void method10(void Function(T Function(T)) value) {}
+  void method11(T Function(T Function(T)) value) {}
+  void method12(S Function<S extends T>() value) {}
+  void method13(void Function<S extends T>(S) value) {}
+  void method14(S Function<S extends T>(S) value) {}
+  void method15(void Function(S Function<S extends T>()) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc7f6db
--- /dev/null
+++ b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,79 @@
+class C<T> {
+  C(this.field1)
+      : field2 = (() => field1),
+        field3 = ((T t) {}),
+        field4 = ((T t) => t),
+        field5 = (() => () => field1),
+        field6 = ((T Function() f) {}),
+        field7 = ((T Function() f) => field1),
+        field8 = ((void Function(T) f) {}),
+        field9 = ((void Function(T) f) => field1),
+        field10 = ((T Function(T) f) {}),
+        field11 = ((T Function(T) f) => field1),
+        field12 = <S extends T>() => null,
+        field13 = <S extends T>(S s) {},
+        field14 = <S extends T>(S s) => s,
+        field15 = ((S Function<S extends T>() f) {});
+  S Function<S extends T>() field12;
+  S Function<S extends T>() get getter12 => field12;
+  S Function<S extends T>(S) field14;
+  S Function<S extends T>(S) get getter14 => field14;
+  T Function(T Function()) field7;
+  T Function(T Function()) get getter7 => field7;
+  T Function(T Function(T)) field11;
+  T Function(T Function(T)) get getter11 => field11;
+  T Function(T) field4;
+  T Function(T) get getter4 => field4;
+  T Function() Function() field5;
+  T Function() Function() get getter5 => field5;
+  T Function() field2;
+  T Function() get getter2 => field2;
+  T Function(void Function(T)) field9;
+  T Function(void Function(T)) get getter9 => field9;
+  T field1;
+  T get getter1 => field1;
+  void Function(T Function()) field6;
+  void Function(T Function()) get getter6 => field6;
+  void Function(T Function(T)) field10;
+  void Function(T Function(T)) get getter10 => field10;
+  void Function(T) field3;
+  void Function(T) get getter3 => field3;
+  void Function(S Function<S extends T>()) field15;
+  void Function(S Function<S extends T>()) get getter15 => field15;
+  void Function(void Function(T)) field8;
+  void Function(void Function(T)) get getter8 => field8;
+  void Function<S extends T>(S) field13;
+  void Function<S extends T>(S) get getter13 => field13;
+  void method1(T value) {}
+  void method10(void Function(T Function(T)) value) {}
+  void method11(T Function(T Function(T)) value) {}
+  void method12(S Function<S extends T>() value) {}
+  void method13(void Function<S extends T>(S) value) {}
+  void method14(S Function<S extends T>(S) value) {}
+  void method15(void Function(S Function<S extends T>()) value) {}
+  void method2(T Function() value) {}
+  void method3(void Function(T) value) {}
+  void method4(T Function(T) value) {}
+  void method5(T Function() Function() value) {}
+  void method6(void Function(T Function()) value) {}
+  void method7(T Function(T Function()) value) {}
+  void method8(void Function(void Function(T)) value) {}
+  void method9(T Function(void Function(T)) value) {}
+  void set setter1(T value) {}
+  void set setter10(void Function(T Function(T)) value) {}
+  void set setter11(T Function(T Function(T)) value) {}
+  void set setter12(S Function<S extends T>() value) {}
+  void set setter13(void Function<S extends T>(S) value) {}
+  void set setter14(S Function<S extends T>(S) value) {}
+  void set setter15(void Function(S Function<S extends T>()) value) {}
+  void set setter2(T Function() value) {}
+  void set setter3(void Function(T) value) {}
+  void set setter4(T Function(T) value) {}
+  void set setter5(T Function() Function() value) {}
+  void set setter6(void Function(T Function()) value) {}
+  void set setter7(T Function(T Function()) value) {}
+  void set setter8(void Function(void Function(T)) value) {}
+  void set setter9(T Function(void Function(T)) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..987eca0
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+  int field;
+  static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..987eca0
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Foo {
+  int field;
+  static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect
index eb4e616..10d831b 100644
--- a/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Class extends core::Object {
   synthetic constructor •() → self::Class*
@@ -12,7 +11,7 @@
   dynamic o;
   if(false) {
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((let final dynamic #t1 = o in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.iterable) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((let final dynamic #t1 = o in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.iterable) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline.expect
new file mode 100644
index 0000000..52b290c
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52b290c
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline.expect
new file mode 100644
index 0000000..5602235
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+  B b;
+}
+
+class B {
+  C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5602235
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+  B b;
+}
+
+class B {
+  C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect
index e746568..c75c586 100644
--- a/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
@@ -10,7 +9,7 @@
     #t1.{core::List::add}("foo");
     final core::Iterable<core::String*>* #t2 = list;
     if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t2).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t3 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t3);
@@ -24,7 +23,7 @@
     #t4.{core::Set::add}("foo");
     final core::Iterable<core::String*>* #t5 = set;
     if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t5).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = #t5.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t4.{core::Set::add}(#t6);
@@ -38,7 +37,7 @@
     #t7.{core::Map::[]=}(0, "foo");
     final core::Map<core::int*, core::String*>* #t8 = map;
     if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::String*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::String*>*>*>(#t8.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::String*>*>* :sync-for-iterator = #t8.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::String*>* #t9 = :sync-for-iterator.{core::Iterator::current};
         #t7.{core::Map::[]=}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline.expect
new file mode 100644
index 0000000..321264d
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+nullAwareListSpread(List<String> list) {}
+nullAwareSetSpread(Set<String> set) {}
+nullAwareMapSpread(Map<int, String> map) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c84dac
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+nullAwareListSpread(List<String> list) {}
+nullAwareMapSpread(Map<int, String> map) {}
+nullAwareSetSpread(Set<String> set) {}
diff --git a/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline.expect b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline.expect
new file mode 100644
index 0000000..a467bf8
--- /dev/null
+++ b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a467bf8
--- /dev/null
+++ b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/operators.dart.textual_outline.expect b/pkg/front_end/testcases/general/operators.dart.textual_outline.expect
new file mode 100644
index 0000000..21c00c7
--- /dev/null
+++ b/pkg/front_end/testcases/general/operators.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class Operators {
+  operator +(other) => null;
+  operator &(other) => null;
+  operator ~() => null;
+  operator |(other) => null;
+  operator ^(other) => null;
+  operator /(other) => null;
+  operator ==(other) => null;
+  operator >(other) => null;
+  operator >=(other) => null;
+  operator [](index) => null;
+  void operator []=(index, value) {}
+  operator <<(other) => null;
+  operator <(other) => null;
+  operator <=(other) => null;
+  operator *(other) => null;
+  operator %(other) => null;
+  operator >>(other) => null;
+  operator -(other) => null;
+  operator ~/(other) => null;
+  operator -() => null;
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general/operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c6b5f5a
--- /dev/null
+++ b/pkg/front_end/testcases/general/operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Operators {
+  operator %(other) => null;
+  operator &(other) => null;
+  operator *(other) => null;
+  operator +(other) => null;
+  operator -() => null;
+  operator -(other) => null;
+  operator /(other) => null;
+  operator <(other) => null;
+  operator <<(other) => null;
+  operator <=(other) => null;
+  operator ==(other) => null;
+  operator >(other) => null;
+  operator >=(other) => null;
+  operator >>(other) => null;
+  operator [](index) => null;
+  operator ^(other) => null;
+  operator |(other) => null;
+  operator ~() => null;
+  operator ~/(other) => null;
+  void operator []=(index, value) {}
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general/optional.dart.textual_outline.expect b/pkg/front_end/testcases/general/optional.dart.textual_outline.expect
new file mode 100644
index 0000000..737d5bc
--- /dev/null
+++ b/pkg/front_end/testcases/general/optional.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+class Foo {
+  method(x, [y, z]) {}
+}
+
+abstract class External {
+  String externalMethod(int x, [int y, int z]);
+  void listen(Listener listener);
+}
+
+external External createExternal();
+
+abstract class Listener {
+  void event(String input, [int x, int y]);
+}
+
+class TestListener extends Listener {
+  void event(input, [x, y]) {}
+}
+
+class ExtendedListener extends Listener {
+  void event(input, [x, y, z]) {}
+}
+
+class InvalidListener {
+  void event(input, [x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/optional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/optional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..53593a5
--- /dev/null
+++ b/pkg/front_end/testcases/general/optional.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+abstract class External {
+  String externalMethod(int x, [int y, int z]);
+  void listen(Listener listener);
+}
+
+abstract class Listener {
+  void event(String input, [int x, int y]);
+}
+
+class ExtendedListener extends Listener {
+  void event(input, [x, y, z]) {}
+}
+
+class Foo {
+  method(x, [y, z]) {}
+}
+
+class InvalidListener {
+  void event(input, [x]) {}
+}
+
+class TestListener extends Listener {
+  void event(input, [x, y]) {}
+}
+
+external External createExternal();
+main() {}
diff --git a/pkg/front_end/testcases/general/override.dart.textual_outline.expect b/pkg/front_end/testcases/general/override.dart.textual_outline.expect
new file mode 100644
index 0000000..272b930
--- /dev/null
+++ b/pkg/front_end/testcases/general/override.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class Foo {}
+
+class Bar extends Foo {}
+
+class Base {
+  Foo method() {}
+}
+
+class Sub extends Base {
+  Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef2c070
--- /dev/null
+++ b/pkg/front_end/testcases/general/override.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Bar extends Foo {}
+
+class Base {
+  Foo method() {}
+}
+
+class Foo {}
+
+class Sub extends Base {
+  Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..8e908b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x(A value) {}
+  B get y => null;
+}
+
+class D extends C {
+  void set x(value) {}
+  get y => null;
+}
+
+class E extends D {
+  void set x(A value) {}
+  B get y => null;
+}
+
+class F extends D {
+  void set x(B value) {}
+  A get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..768ee0f
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  B get y => null;
+  void set x(A value) {}
+}
+
+class D extends C {
+  get y => null;
+  void set x(value) {}
+}
+
+class E extends D {
+  B get y => null;
+  void set x(A value) {}
+}
+
+class F extends D {
+  A get y => null;
+  void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..9a762a7
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x(A value) {}
+  A get y => null;
+}
+
+class D extends C {
+  void set x(Object value) {}
+  B get y => null;
+}
+
+class E extends C {
+  void set x(B value) {}
+  Object get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..363c517
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  A get y => null;
+  void set x(A value) {}
+}
+
+class D extends C {
+  B get y => null;
+  void set x(Object value) {}
+}
+
+class E extends C {
+  Object get y => null;
+  void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..015eb02
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x1(covariant A value) {}
+  void set x2(A value) {}
+  void set x3(covariant A value) {}
+  void set x4(A value) {}
+  void set x5(covariant A value) {}
+  void set x6(covariant B value) {}
+}
+
+class D extends C {
+  void set x1(B value) {}
+  void set x2(covariant B value) {}
+  void set x3(covariant B value) {}
+  void set x4(B value) {}
+  void set x5(covariant String value) {}
+  void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..015eb02
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x1(covariant A value) {}
+  void set x2(A value) {}
+  void set x3(covariant A value) {}
+  void set x4(A value) {}
+  void set x5(covariant A value) {}
+  void set x6(covariant B value) {}
+}
+
+class D extends C {
+  void set x1(B value) {}
+  void set x2(covariant B value) {}
+  void set x3(covariant B value) {}
+  void set x4(B value) {}
+  void set x5(covariant String value) {}
+  void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..b2c8457
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(A x) {}
+}
+
+class D extends C {
+  void f(x) {}
+}
+
+class E extends D {
+  void f(A x) {}
+}
+
+class F extends D {
+  void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b2c8457
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(A x) {}
+}
+
+class D extends C {
+  void f(x) {}
+}
+
+class E extends D {
+  void f(A x) {}
+}
+
+class F extends D {
+  void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..d6322d8
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void f1(A x) {}
+  void f2([A x]) {}
+  void f3({A x}) {}
+  A f4() {}
+}
+
+class D extends C {
+  void f1(Object x) {}
+  void f2([Object x]) {}
+  void f3({Object x}) {}
+  B f4() {}
+}
+
+class E extends C {
+  void f1(B x) {}
+  void f2([B x]) {}
+  void f3({B x}) {}
+  Object f4() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7ca06d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  A f4() {}
+  void f1(A x) {}
+  void f2([A x]) {}
+  void f3({A x}) {}
+}
+
+class D extends C {
+  B f4() {}
+  void f1(Object x) {}
+  void f2([Object x]) {}
+  void f3({Object x}) {}
+}
+
+class E extends C {
+  Object f4() {}
+  void f1(B x) {}
+  void f2([B x]) {}
+  void f3({B x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline.expect
new file mode 100644
index 0000000..eaac90c
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Foo<T extends Foo<T>> {}
+
+abstract class Bar {
+  void fisk<S extends Foo<S>>();
+}
+
+class Hest implements Bar {
+  @override
+  void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cdebc76
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class Bar {
+  void fisk<S extends Foo<S>>();
+}
+
+class Foo<T extends Foo<T>> {}
+
+class Hest implements Bar {
+  @override
+  void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline.expect
new file mode 100644
index 0000000..9548980
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A<T> {
+  void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+  void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9548980
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A<T> {
+  void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+  void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..1c8bfe2
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void f1(covariant A x) {}
+  void f2(A x) {}
+  void f3(covariant A x) {}
+  void f4(A x) {}
+  void f5(covariant A x) {}
+  void f6(covariant B x) {}
+}
+
+class D extends C {
+  void f1(B x) {}
+  void f2(covariant B x) {}
+  void f3(covariant B x) {}
+  void f4(B x) {}
+  void f5(covariant String x) {}
+  void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1c8bfe2
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void f1(covariant A x) {}
+  void f2(A x) {}
+  void f3(covariant A x) {}
+  void f4(A x) {}
+  void f5(covariant A x) {}
+  void f6(covariant B x) {}
+}
+
+class D extends C {
+  void f1(B x) {}
+  void f2(covariant B x) {}
+  void f3(covariant B x) {}
+  void f4(B x) {}
+  void f5(covariant String x) {}
+  void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..d720f29
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline.expect
@@ -0,0 +1,57 @@
+abstract class A {
+  num get getterFromGetter;
+  set setterFromSetter(num value);
+  set getterFromSetter(num value);
+  num get setterFromGetter;
+  num get getterFromGetterWithSetterConflict;
+  set getterFromGetterWithSetterConflict(num);
+  num get setterFromSetterWithGetterConflict;
+  set setterFromSetterWithGetterConflict(num);
+}
+
+abstract class B {
+  int get getterFromGetter;
+  set setterFromSetter(int value);
+  int get setterFromGetter;
+  int get setterFromSetterWithGetterConflict;
+  set getterFromGetterWithSetterConflict(int value);
+  set getterFromSetter(int value);
+}
+
+abstract class C extends A {
+  get getterFromGetter;
+  set setterFromSetter(value);
+  get getterFromSetter;
+  set setterFromGetter(value);
+  get getterFromGetterWithSetterConflict;
+  set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class D extends A implements B {
+  get getterFromGetter;
+  set setterFromSetter(value);
+  get getterFromSetter;
+  set setterFromGetter(value);
+  get getterFromGetterWithSetterConflict;
+  set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class E implements A {
+  get getterFromGetter;
+  set setterFromSetter(value);
+  get getterFromSetter;
+  set setterFromGetter(value);
+  get getterFromGetterWithSetterConflict;
+  set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class F implements A, B {
+  get getterFromGetter;
+  set setterFromSetter(value);
+  get getterFromSetter;
+  set setterFromGetter(value);
+  get getterFromGetterWithSetterConflict;
+  set setterFromSetterWithGetterConflict(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81cac22
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,57 @@
+abstract class A {
+  num get getterFromGetter;
+  num get getterFromGetterWithSetterConflict;
+  num get setterFromGetter;
+  num get setterFromSetterWithGetterConflict;
+  set getterFromGetterWithSetterConflict(num);
+  set getterFromSetter(num value);
+  set setterFromSetter(num value);
+  set setterFromSetterWithGetterConflict(num);
+}
+
+abstract class B {
+  int get getterFromGetter;
+  int get setterFromGetter;
+  int get setterFromSetterWithGetterConflict;
+  set getterFromGetterWithSetterConflict(int value);
+  set getterFromSetter(int value);
+  set setterFromSetter(int value);
+}
+
+abstract class C extends A {
+  get getterFromGetter;
+  get getterFromGetterWithSetterConflict;
+  get getterFromSetter;
+  set setterFromGetter(value);
+  set setterFromSetter(value);
+  set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class D extends A implements B {
+  get getterFromGetter;
+  get getterFromGetterWithSetterConflict;
+  get getterFromSetter;
+  set setterFromGetter(value);
+  set setterFromSetter(value);
+  set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class E implements A {
+  get getterFromGetter;
+  get getterFromGetterWithSetterConflict;
+  get getterFromSetter;
+  set setterFromGetter(value);
+  set setterFromSetter(value);
+  set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class F implements A, B {
+  get getterFromGetter;
+  get getterFromGetterWithSetterConflict;
+  get getterFromSetter;
+  set setterFromGetter(value);
+  set setterFromSetter(value);
+  set setterFromSetterWithGetterConflict(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..0ae1e3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class B {
+  num get foo => null;
+  set foo(dynamic newFoo) {}
+}
+
+class A extends B {
+  set foo(newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1e629f
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A extends B {
+  set foo(newFoo) {}
+}
+
+class B {
+  num get foo => null;
+  set foo(dynamic newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline.expect
new file mode 100644
index 0000000..231f88e
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class A {
+  foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+  foo({c = true, bool a}) {}
+}
+
+class C extends B {
+  foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+  foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+  foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+  foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef3a56b
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class A {
+  foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+  foo({bool a = true, bool c}) {}
+}
+
+class B extends A {
+  foo({c = true, bool a}) {}
+}
+
+class B1 extends A1 {
+  foo({a = true, bool c}) {}
+}
+
+class C extends B {
+  foo({bool c = true, bool a}) {}
+}
+
+class C1 extends B1 {
+  foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e605f98
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A {
+  void set x(Object y);
+}
+
+class B implements A {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e605f98
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A {
+  void set x(Object y);
+}
+
+class B implements A {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline.expect
new file mode 100644
index 0000000..07ab488
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline.expect
@@ -0,0 +1 @@
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07ab488
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline.expect
new file mode 100644
index 0000000..d7c7da3
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7c7da3
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..bf4aa7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bf4aa7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline.expect
new file mode 100644
index 0000000..a400a31
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a400a31
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..2897172
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2897172
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/platform.dart.textual_outline.expect b/pkg/front_end/testcases/general/platform.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/platform.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/platform.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline.expect b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline.expect
new file mode 100644
index 0000000..27c1d98
--- /dev/null
+++ b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class B {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..47e2b29
--- /dev/null
+++ b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+main() {}
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..929342c
--- /dev/null
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import './private_method_tearoff_lib.dart';
+
+class Foo implements Bar {}
+
+class Baz extends Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2092d9c
--- /dev/null
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import './private_method_tearoff_lib.dart';
+
+class Baz extends Foo {}
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/promoted_access.dart.textual_outline.expect b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline.expect
new file mode 100644
index 0000000..e0aa09a
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+  method(T o) {}
+}
+
+method<T>(T o) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/promoted_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..35276e6
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+  method(T o) {}
+}
+
+main() {}
+method<T>(T o) {}
diff --git a/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline.expect b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline.expect
new file mode 100644
index 0000000..2ed1e94
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+method<T>(T o) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8fa980e
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+method<T>(T o) {}
diff --git a/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..e266da1
--- /dev/null
+++ b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e266da1
--- /dev/null
+++ b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/qualified.dart.textual_outline.expect b/pkg/front_end/testcases/general/qualified.dart.textual_outline.expect
new file mode 100644
index 0000000..accfab2
--- /dev/null
+++ b/pkg/front_end/testcases/general/qualified.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+  lib.Missing method() {}
+  factory WrongName() {}
+}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/qualified.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/qualified.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0713429
--- /dev/null
+++ b/pkg/front_end/testcases/general/qualified.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+  factory WrongName() {}
+  lib.Missing method() {}
+}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..2e2eb1f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  A();
+  factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e2eb1f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+  A();
+  factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..b6e0d0a
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+abstract class FooBase<Tf> {
+  int get x;
+  factory FooBase(int x) = Foo<Tf>;
+}
+
+abstract class Foo<T> implements FooBase {
+  factory Foo(int x) = Bar<String, T>;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+  int x;
+  Bar(this.x) {}
+}
+
+class Builder<X> {
+  method() {}
+}
+
+class SimpleCase<A, B> {
+  factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+  factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class Base<M> {}
+
+class Mixin<M> {}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd93039
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,34 @@
+abstract class Foo<T> implements FooBase {
+  factory Foo(int x) = Bar<String, T>;
+}
+
+abstract class FooBase<Tf> {
+  factory FooBase(int x) = Foo<Tf>;
+  int get x;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+  Bar(this.x) {}
+  int x;
+}
+
+class Base<M> {}
+
+class Builder<X> {
+  method() {}
+}
+
+class Mixin<M> {}
+
+class SimpleCase<A, B> {
+  factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+  factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline.expect
new file mode 100644
index 0000000..f7ca084
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library redirecting_factory_constructors.chain_test;
+
+class A {
+  A();
+  factory A.first() = A;
+  factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f7ca084
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library redirecting_factory_constructors.chain_test;
+
+class A {
+  A();
+  factory A.first() = A;
+  factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..1eae718
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class _X<T> {
+  const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+  const _Y();
+}
+
+class A<T> {
+  _X<T> x;
+  A(this.x);
+}
+
+class B<T> extends A<T> {
+  B() : super(const _X());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71b737f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A<T> {
+  A(this.x);
+  _X<T> x;
+}
+
+class B<T> extends A<T> {
+  B() : super(const _X());
+}
+
+class _X<T> {
+  const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+  const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..d486790
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+const forParameter = 1;
+const forFactoryItself = 2;
+const anotherForParameter = 3;
+
+class Foo {
+  @forFactoryItself
+  factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+  Foo.named(p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5455e6c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Foo {
+  @forFactoryItself
+  factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+  Foo.named(p);
+}
+
+const anotherForParameter = 3;
+const forFactoryItself = 2;
+const forParameter = 1;
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline.expect
new file mode 100644
index 0000000..bbefe2c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.simple_test;
+
+class A {
+  A();
+  factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bbefe2c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.simple_test;
+
+class A {
+  A();
+  factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline.expect
new file mode 100644
index 0000000..50ddae4
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library redirecting_factory_constructors.typeargs_test;
+
+class X {}
+
+class Y extends X {}
+
+class A {
+  A();
+  factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+  B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d52aa92
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library redirecting_factory_constructors.typeargs_test;
+
+class A {
+  A();
+  factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+  B();
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e04255c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e04255c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e6ad16e
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library redirecting_factory_constructors.typeparambounds_test;
+
+class X {}
+
+class Y extends X {}
+
+class A<T, S extends T> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..036a788
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library redirecting_factory_constructors.typeparambounds_test;
+
+class A<T, S extends T> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
new file mode 100644
index 0000000..1de1d30
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class X {}
+
+class Foo<T extends X> {
+  T x;
+  Foo.fromX(X _init) : this._internal(x: _init);
+  Foo.fromT(T _init) : this._internal(x: _init);
+  Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f132422
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Foo<T extends X> {
+  Foo._internal({this.x});
+  Foo.fromT(T _init) : this._internal(x: _init);
+  Foo.fromX(X _init) : this._internal(x: _init);
+  T x;
+}
+
+class X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline.expect
new file mode 100644
index 0000000..67a67e9
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo<T> {
+  T x;
+  Foo.from(String _init) : this._internal(x: _init);
+  Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b96053
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo<T> {
+  Foo._internal({this.x});
+  Foo.from(String _init) : this._internal(x: _init);
+  T x;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..772fcd2
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+class A<T> {
+  factory A() = B<T, num>;
+  A.empty();
+}
+
+class B<U, W> extends A<U> {
+  factory B() = C<U, W, String>;
+  B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f267ca
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+class A<T> {
+  A.empty();
+  factory A() = B<T, num>;
+}
+
+class B<U, W> extends A<U> {
+  B.empty() : super.empty();
+  factory B() = C<U, W, String>;
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline.expect
new file mode 100644
index 0000000..29e8862
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+  factory A() = B<T, List<T>>;
+  A.empty();
+}
+
+abstract class B<U, W> extends A<U> {
+  factory B() = C<U, W, Map<U, W>>;
+  B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7040eb4
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+  A.empty();
+  factory A() = B<T, List<T>>;
+}
+
+abstract class B<U, W> extends A<U> {
+  B.empty() : super.empty();
+  factory B() = C<U, W, Map<U, W>>;
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..10ae984
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'package:expect/expect.dart';
+
+class A {
+  const factory A() = B<String>;
+  const A.empty();
+}
+
+class B<T> extends A {
+  const B() : super.empty();
+  toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..561ace4
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'package:expect/expect.dart';
+
+class A {
+  const A.empty();
+  const factory A() = B<String>;
+}
+
+class B<T> extends A {
+  const B() : super.empty();
+  toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..27c53cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27c53cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline.expect b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline.expect
new file mode 100644
index 0000000..fcee7cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fcee7cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline.expect
new file mode 100644
index 0000000..1a2b8fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C extends Iterable<Object> {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..23c1a60
--- /dev/null
+++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class C extends Iterable<Object> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect
index 0b31b37..19e0ff1 100644
--- a/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect
@@ -9,7 +9,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method main() → dynamic {
@@ -17,7 +16,7 @@
     final core::List<core::int*>* #t1 = <core::int*>[];
     #t1.{core::List::add}(1);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[2]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t2 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t2);
@@ -25,7 +24,7 @@
     }
     final core::Iterable<core::int*>* #t3 = <core::int*>[3];
     if(!#t3.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t3).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t3.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t4 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t4);
@@ -36,7 +35,7 @@
     final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
     #t5.{core::Map::[]=}(1, 1);
     {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{2: 2}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{2: 2}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
@@ -44,7 +43,7 @@
     }
     final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
     if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(#t7.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = #t7.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t8 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
@@ -55,7 +54,7 @@
     final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
     #t9.{core::Set::add}(1);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[2]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::Set::add}(#t10);
@@ -63,7 +62,7 @@
     }
     final core::Iterable<core::int*>* #t11 = <core::int*>[3];
     if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t11).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t11.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::Set::add}(#t12);
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..a527799
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+foo() => null;
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d461a14
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
index 22a6806..3215846 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
@@ -98,7 +98,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method bar<K extends core::Object* = dynamic, V extends core::Object* = dynamic>() → core::Map<self::bar::K*, self::bar::V*>*
@@ -113,7 +112,7 @@
   core::List<dynamic>* lhs10 = block {
     final core::List<dynamic>* #t1 = <dynamic>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t2);
@@ -123,7 +122,7 @@
   core::Set<dynamic>* set10 = block {
     final core::Set<dynamic>* #t3 = col::LinkedHashSet::•<dynamic>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         #t3.{core::Set::add}(#t4);
@@ -133,7 +132,7 @@
   core::Map<dynamic, dynamic>* map10 = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(<dynamic, dynamic>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
@@ -143,7 +142,7 @@
   core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(<dynamic, dynamic>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t8 = :sync-for-iterator.{core::Iterator::current};
         #t7.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
@@ -153,7 +152,7 @@
   core::List<core::int*>* lhs20 = block {
     final core::List<core::int*>* #t9 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::List::add}(#t10);
@@ -163,7 +162,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
         #t11.{core::Set::add}(#t12);
@@ -174,7 +173,7 @@
   core::Set<core::int*>* set20ambiguous = block {
     final core::Set<core::int*>* #t13 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -187,7 +186,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
@@ -198,7 +197,7 @@
   core::Map<core::String*, core::int*>* map20ambiguous = block {
     final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Map::[]=}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
@@ -208,7 +207,7 @@
   core::List<dynamic>* lhs21 = block {
     final core::List<dynamic>* #t20 = <dynamic>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::List::add}(#t21);
@@ -218,7 +217,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t22 = col::LinkedHashSet::•<dynamic>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
         #t22.{core::Set::add}(#t23);
@@ -229,7 +228,7 @@
   core::Map<dynamic, dynamic>* map21 = block {
     final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t25 = :sync-for-iterator.{core::Iterator::current};
         #t24.{core::Map::[]=}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
@@ -244,7 +243,7 @@
   core::List<core::int*>* lhs22 = block {
     final core::List<core::int*>* #t26 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t27 = :sync-for-iterator.{core::Iterator::current};
         #t26.{core::List::add}(#t27);
@@ -254,7 +253,7 @@
   core::Set<core::int*>* set22 = block {
     final core::Set<core::int*>* #t28 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
         #t28.{core::Set::add}(#t29);
@@ -265,7 +264,7 @@
   core::Set<core::int*>* set22ambiguous = block {
     final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t31 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -278,7 +277,7 @@
   core::Map<core::String*, core::int*>* map22 = block {
     final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t34 = :sync-for-iterator.{core::Iterator::current};
         #t33.{core::Map::[]=}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
@@ -288,7 +287,7 @@
   core::List<core::List<core::int*>*>* lhs23 = block {
     final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t36 = :sync-for-iterator.{core::Iterator::current};
         #t35.{core::List::add}(#t36);
@@ -298,7 +297,7 @@
   core::Set<core::List<core::int*>*>* set23 = block {
     final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t38 = :sync-for-iterator.{core::Iterator::current};
         #t37.{core::Set::add}(#t38);
@@ -309,7 +308,7 @@
   core::Set<core::List<core::int*>*>* set23ambiguous = block {
     final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t40 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -322,7 +321,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map23 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
         #t42.{core::Map::[]=}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
@@ -338,7 +337,7 @@
                                    ^" in ( block {
     final core::List<core::int*>* #t45 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t46 = :sync-for-iterator.{core::Iterator::current};
         #t45.{core::List::add}(#t46);
@@ -351,7 +350,7 @@
                                    ^" in ( block {
     final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t49 = :sync-for-iterator.{core::Iterator::current};
         #t48.{core::Set::add}(#t49);
@@ -365,7 +364,7 @@
       ^" in ( block {
     final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t52 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -381,7 +380,7 @@
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t56 = :sync-for-iterator.{core::Iterator::current};
         #t55.{core::Map::[]=}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
@@ -395,7 +394,7 @@
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
         #t58.{core::Map::[]=}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
@@ -444,7 +443,7 @@
     ...null,
        ^");
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t69 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -461,7 +460,7 @@
     final core::List<core::int*>* #t71 = <core::int*>[];
     final core::Iterable<core::int*>* #t72 = null;
     if(!#t72.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t72).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t72.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t73 = :sync-for-iterator.{core::Iterator::current};
         #t71.{core::List::add}(#t73);
@@ -472,7 +471,7 @@
     final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>();
     final core::Iterable<core::int*>* #t75 = null;
     if(!#t75.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t75).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t75.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t76 = :sync-for-iterator.{core::Iterator::current};
         #t74.{core::Set::add}(#t76);
@@ -483,7 +482,7 @@
     final core::Set<dynamic>* #t77 = col::LinkedHashSet::•<dynamic>();
     final core::Iterable<dynamic>* #t78 = null;
     if(!#t78.{core::Object::==}(null)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(#t78).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = #t78.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t79 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -493,7 +492,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t81 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -507,7 +506,7 @@
     final core::Map<core::String*, core::int*>* #t83 = <core::String*, core::int*>{};
     final core::Map<core::String*, core::int*>* #t84 = null;
     if(!#t84.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t84.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = #t84.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t85 = :sync-for-iterator.{core::Iterator::current};
         #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
@@ -517,7 +516,7 @@
   core::Map<core::String*, core::int*>* map90 = block {
     final core::Map<core::String*, core::int*>* #t86 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(self::bar<core::String*, core::int*>().{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t87 = :sync-for-iterator.{core::Iterator::current};
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
@@ -527,7 +526,7 @@
   core::List<core::int*>* list100 = block {
     final core::List<core::int*>* #t88 = <core::int*>[];
     {
-      core::Iterator<core::num*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::num*>*>(listNum).{core::Iterable::iterator};
+      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t89 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -540,7 +539,7 @@
   core::Map<core::num*, core::int*>* map100 = block {
     final core::Map<core::num*, core::int*>* #t91 = <core::num*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::int*, core::num*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::num*>*>*>(mapIntNum.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::num*>*>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t92 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -554,7 +553,7 @@
   core::List<core::int*>* list110 = block {
     final core::List<core::int*>* #t95 = <core::int*>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t96 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -567,7 +566,7 @@
   core::Map<core::num*, core::int*>* map110 = block {
     final core::Map<core::num*, core::int*>* #t98 = <core::num*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t99 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..5ebffd1
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ebffd1
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/statements.dart.textual_outline.expect b/pkg/front_end/testcases/general/statements.dart.textual_outline.expect
new file mode 100644
index 0000000..cec9847
--- /dev/null
+++ b/pkg/front_end/testcases/general/statements.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo() {}
+bar() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general/statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c4d710
--- /dev/null
+++ b/pkg/front_end/testcases/general/statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+bar() async {}
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/static_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general/static_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..e45f3a8
--- /dev/null
+++ b/pkg/front_end/testcases/general/static_setter.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class Foo {}
+
+set foo(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/static_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/static_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cad463e
--- /dev/null
+++ b/pkg/front_end/testcases/general/static_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class Foo {}
+
+main() {}
+set foo(x) {}
diff --git a/pkg/front_end/testcases/general/store_load.dart.textual_outline.expect b/pkg/front_end/testcases/general/store_load.dart.textual_outline.expect
new file mode 100644
index 0000000..12677c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/store_load.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class Foo {
+  var _field;
+}
+
+class FooValue {}
+
+class Bar {
+  var _field;
+}
+
+class BarValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/store_load.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/store_load.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d24c44c
--- /dev/null
+++ b/pkg/front_end/testcases/general/store_load.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Bar {
+  var _field;
+}
+
+class BarValue {}
+
+class Foo {
+  var _field;
+}
+
+class FooValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/stringliteral.dart.textual_outline.expect b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline.expect
new file mode 100644
index 0000000..203a809
--- /dev/null
+++ b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+var color = 'brown';
+var thing = 'lazy dog';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var adjacent = '$color$color$color';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+main() {}
diff --git a/pkg/front_end/testcases/general/stringliteral.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ef0a48
--- /dev/null
+++ b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+main() {}
+var adjacent = '$color$color$color';
+var color = 'brown';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var thing = 'lazy dog';
diff --git a/pkg/front_end/testcases/general/super_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/super_call.dart.textual_outline.expect
new file mode 100644
index 0000000..08fd0e2
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_call.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+  int call(int x) => x * 2;
+}
+
+class B extends A {
+  int call(int x) => x * 3;
+  int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/super_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..08fd0e2
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A {
+  int call(int x) => x * 2;
+}
+
+class B extends A {
+  int call(int x) => x * 3;
+  int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_nsm.dart.textual_outline.expect b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline.expect
new file mode 100644
index 0000000..39c0416
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+abstract class I {
+  interfaceMethod();
+}
+
+class C implements I {
+  noSuchMethod(_) => "C";
+}
+
+class D extends C {
+  noSuchMethod(_) => "D";
+  dMethod() => super.interfaceMethod();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_nsm.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8dcf482
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+abstract class I {
+  interfaceMethod();
+}
+
+class C implements I {
+  noSuchMethod(_) => "C";
+}
+
+class D extends C {
+  dMethod() => super.interfaceMethod();
+  noSuchMethod(_) => "D";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/tabs.dart.textual_outline.expect b/pkg/front_end/testcases/general/tabs.dart.textual_outline.expect
new file mode 100644
index 0000000..ec6b9e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/tabs.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/tabs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/tabs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f67dbb0
--- /dev/null
+++ b/pkg/front_end/testcases/general/tabs.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/this_field_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline.expect
new file mode 100644
index 0000000..eb3e361
--- /dev/null
+++ b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {
+  void Function(T) f;
+  A(this.f);
+  foo(T x) => this.f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/this_field_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b5116cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {
+  A(this.f);
+  foo(T x) => this.f(x);
+  void Function(T) f;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..0e6af39
--- /dev/null
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef Foo<T> = void Function(Bar<T>);
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+main() {}
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d241b1c
--- /dev/null
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+typedef Foo<T> = void Function(Bar<T>);
diff --git a/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..184dba8
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..184dba8
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline.expect b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline.expect
new file mode 100644
index 0000000..e6ec156
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6ec156
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..54f0474
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  const A();
+}
+
+@A
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4127317
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+@A
+class B {}
+
+class A {
+  const A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_of_null.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline.expect
new file mode 100644
index 0000000..f8de85e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+Null foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general/type_of_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..28d7893
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+Null foo() => null;
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline.expect
new file mode 100644
index 0000000..84e0e68
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class Foo<T> {
+  List<T> get list;
+  void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+  List<int> list;
+  void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..84e0e68
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class Foo<T> {
+  List<T> get list;
+  void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+  List<int> list;
+  void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline.expect
new file mode 100644
index 0000000..dab722e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class Foo<U> {
+  static U foo1() {}
+  static List<U> foo1Prime() {}
+  static void foo2(U x) {}
+  static void foo2Prime(List<U> x) {}
+  static void foo3() {}
+  static U Function() foo8() {}
+  static List<U> Function() foo8Prime() {}
+  static void Function(U) foo9() {}
+  static void Function(List<U>) foo9Prime() {}
+  static void foo10(U Function()) {}
+  static void foo10Prime(List<U> Function()) {}
+  static void foo11(void Function(U)) {}
+  static void foo12(void Function(U) b) {}
+  static void foo12Prime(void Function(List<U>) b) {}
+  static void foo13(void Function(U b)) {}
+  static void foo13Prime(void Function(List<U> b)) {}
+  static U foo14 = null;
+  static List<U> foo14Prime = null;
+  static U Function(U) foo15 = null;
+  static List<U> Function(List<U>) foo15Prime = null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..531ae41
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Foo<U> {
+  static List<U> Function() foo8Prime() {}
+  static List<U> Function(List<U>) foo15Prime = null;
+  static List<U> foo14Prime = null;
+  static List<U> foo1Prime() {}
+  static U Function() foo8() {}
+  static U Function(U) foo15 = null;
+  static U foo1() {}
+  static U foo14 = null;
+  static void Function(List<U>) foo9Prime() {}
+  static void Function(U) foo9() {}
+  static void foo10(U Function()) {}
+  static void foo10Prime(List<U> Function()) {}
+  static void foo11(void Function(U)) {}
+  static void foo12(void Function(U) b) {}
+  static void foo12Prime(void Function(List<U>) b) {}
+  static void foo13(void Function(U b)) {}
+  static void foo13Prime(void Function(List<U> b)) {}
+  static void foo2(U x) {}
+  static void foo2Prime(List<U> x) {}
+  static void foo3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..cd75193
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension Foo<U> ( ){ }
+on List (){ }
+main() { }
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..e628591
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+dynamic<int> f() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e628591
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+dynamic<int> f() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_void.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameters_on_void.dart.textual_outline.expect
new file mode 100644
index 0000000..c9c869a
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_void.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void<int> f() { }
+main() { }
diff --git a/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline.expect
new file mode 100644
index 0000000..1fb7f08
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+  B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1fb7f08
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+  B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect
new file mode 100644
index 0000000..d7f2e46
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class DynamicClass<T extends dynamic, S extends T> {
+  T field1;
+  T field2;
+  DynamicClass(this.field1, this.field2);
+  method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+  T field1;
+  S field2;
+  NumClass(this.field1, this.field2);
+  num method1() => field1 * field2;
+  num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b92c57e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class DynamicClass<T extends dynamic, S extends T> {
+  DynamicClass(this.field1, this.field2);
+  T field1;
+  T field2;
+  method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+  NumClass(this.field1, this.field2);
+  S field2;
+  T field1;
+  num method1() => field1 * field2;
+  num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.expect b/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.expect
index 3a5b1a7..8056cc0 100644
--- a/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.expect
+++ b/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.expect
@@ -16,9 +16,9 @@
     : super core::Object::•()
     ;
   method method() → invalid-type
-    return "Hello, World!" as{TypeError} invalid-type;
+    return "Hello, World!";
 }
 static method main() → dynamic {
-  core::String* s = new self::C::•<dynamic>().{self::C::method}() as{TypeError} core::String*;
+  core::String* s = new self::C::•<dynamic>().{self::C::method}();
   core::print(s);
 }
diff --git a/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.transformed.expect
index 3a5b1a7..8056cc0 100644
--- a/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/type_variable_prefix.dart.strong.transformed.expect
@@ -16,9 +16,9 @@
     : super core::Object::•()
     ;
   method method() → invalid-type
-    return "Hello, World!" as{TypeError} invalid-type;
+    return "Hello, World!";
 }
 static method main() → dynamic {
-  core::String* s = new self::C::•<dynamic>().{self::C::method}() as{TypeError} core::String*;
+  core::String* s = new self::C::•<dynamic>().{self::C::method}();
   core::print(s);
 }
diff --git a/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..17664d53
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import "dart:core" as T;
+
+class C<T> {
+  T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17664d53
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import "dart:core" as T;
+
+class C<T> {
+  T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline.expect
new file mode 100644
index 0000000..4ea252b
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class C<T> {
+  const C();
+  static C<T> staticMethod() {}
+  C<T> instanceMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8414ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C<T> {
+  C<T> instanceMethod() {}
+  const C();
+  static C<T> staticMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/typedef.dart.textual_outline.expect b/pkg/front_end/testcases/general/typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..f652ebb
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
+typedef _BinaryFunction(args, message);
+main() {}
diff --git a/pkg/front_end/testcases/general/typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7714b6b
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+typedef _BinaryFunction(args, message);
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
diff --git a/pkg/front_end/testcases/general/undefined.dart.textual_outline.expect b/pkg/front_end/testcases/general/undefined.dart.textual_outline.expect
new file mode 100644
index 0000000..7c1f7be
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class C {
+  var x;
+  void f() {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/undefined.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/undefined.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6775e59
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+  var x;
+  void f() {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..627bd18
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  void set x(value) {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1044c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  void set x(value) {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..29870cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class Uninitialized {
+  int x;
+}
+
+class PartiallyInitialized {
+  int x;
+  PartiallyInitialized(this.x);
+  PartiallyInitialized.noInitializer();
+}
+
+class Initialized {
+  int x;
+  Initialized(this.x);
+}
+
+class Forwarding {
+  int x;
+  Forwarding.initialize(this.x);
+  Forwarding(int arg) : this.initialize(arg);
+}
+
+int uninitializedTopLevel;
+int initializedTopLevel = 4;
+main() {}
diff --git a/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a6b77e3
--- /dev/null
+++ b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Forwarding {
+  Forwarding(int arg) : this.initialize(arg);
+  Forwarding.initialize(this.x);
+  int x;
+}
+
+class Initialized {
+  Initialized(this.x);
+  int x;
+}
+
+class PartiallyInitialized {
+  PartiallyInitialized(this.x);
+  PartiallyInitialized.noInitializer();
+  int x;
+}
+
+class Uninitialized {
+  int x;
+}
+
+int initializedTopLevel = 4;
+int uninitializedTopLevel;
+main() {}
diff --git a/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..0e5f983
--- /dev/null
+++ b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+List<A> list;
+List<T> g<T extends A>(T t) {}
+List<S> f<S>(S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b3488fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+List<A> list;
+List<S> f<S>(S s) {}
+List<T> g<T extends A>(T t) {}
+
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/unused_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..d30480d
--- /dev/null
+++ b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline.expect
@@ -0,0 +1,36 @@
+class UnusedClass {
+  UnusedClass() {}
+}
+
+abstract class UsedAsBaseClass {
+  void usedInSubclass() {}
+  void calledFromB() {}
+  void calledFromSubclass() {}
+}
+
+class UsedAsInterface {
+  void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+  void calledFromSubclass() {}
+}
+
+void baseClassCall(UsedAsBaseClass object) {}
+void interfaceCall(UsedAsInterface object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+unusedTopLevel() {}
+usedTopLevel() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/unused_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe88e83
--- /dev/null
+++ b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,36 @@
+abstract class UsedAsBaseClass {
+  void calledFromB() {}
+  void calledFromSubclass() {}
+  void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void calledFromSubclass() {}
+  void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class UnusedClass {
+  UnusedClass() {}
+}
+
+class UsedAsInterface {
+  void usedInSubclass() {}
+}
+
+main() {}
+unusedTopLevel() {}
+usedTopLevel() {}
+void baseClassCall(UsedAsBaseClass object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+void interfaceCall(UsedAsInterface object) {}
diff --git a/pkg/front_end/testcases/general/var_as_type_name.dart.textual_outline.expect b/pkg/front_end/testcases/general/var_as_type_name.dart.textual_outline.expect
new file mode 100644
index 0000000..4852e57
--- /dev/null
+++ b/pkg/front_end/testcases/general/var_as_type_name.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+  Map<String, var> m;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect
index 3950bfe..441c807 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect
@@ -48,7 +48,7 @@
     ;
   method foo8<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void
     ;
-  forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
+  forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
     return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
 }
 static field core::List<core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect
index ced2c81..1418ee2 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect
@@ -68,7 +68,7 @@
     : super self::G::•()
     ;
   method foo8<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void {}
-  forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
+  forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
     return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
 }
 static field core::List<core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect
index ced2c81..1418ee2 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect
@@ -68,7 +68,7 @@
     : super self::G::•()
     ;
   method foo8<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void {}
-  forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
+  forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
     return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
 }
 static field core::List<core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline.expect
new file mode 100644
index 0000000..2acf1f6
--- /dev/null
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline.expect
@@ -0,0 +1,38 @@
+class A<T> {}
+
+class B extends A<String> {}
+
+class C<T1, T2, T3> extends B {}
+
+foo1(x) {}
+
+class D<P, Q> extends C<int, Q, P> {
+  Map<P, Q> foo;
+  D(tt) : foo = tt;
+  foo2(y) {}
+  foo3<T1, T2>(z) {}
+  Map<P, Q> foo4(w) {}
+}
+
+List<Iterable> globalVar;
+void foo5(x) {}
+
+class E<P extends String> {
+  factory E() => null;
+  void foo6<T extends P, U extends List<T>>(Map<T, U> map) {}
+}
+
+abstract class F<T> {
+  void foo7<Q extends T>(Q a, covariant num b, T c);
+  void foo8<Q extends T>(Q a, covariant num b, T c);
+}
+
+class G<T> {
+  void foo7<Q extends T>(Q a, int b, T c) {}
+}
+
+class H<T> extends G<T> implements F<T> {
+  void foo8<Q extends T>(Q a, int b, T c) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96d4e65
--- /dev/null
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+List<Iterable> globalVar;
+
+abstract class F<T> {
+  void foo7<Q extends T>(Q a, covariant num b, T c);
+  void foo8<Q extends T>(Q a, covariant num b, T c);
+}
+
+class A<T> {}
+
+class B extends A<String> {}
+
+class C<T1, T2, T3> extends B {}
+
+class D<P, Q> extends C<int, Q, P> {
+  D(tt) : foo = tt;
+  Map<P, Q> foo4(w) {}
+  Map<P, Q> foo;
+  foo2(y) {}
+  foo3<T1, T2>(z) {}
+}
+
+class E<P extends String> {
+  factory E() => null;
+  void foo6<T extends P, U extends List<T>>(Map<T, U> map) {}
+}
+
+class G<T> {
+  void foo7<Q extends T>(Q a, int b, T c) {}
+}
+
+class H<T> extends G<T> implements F<T> {
+  void foo8<Q extends T>(Q a, int b, T c) {}
+}
+
+foo1(x) {}
+main() {}
+void foo5(x) {}
diff --git a/pkg/front_end/testcases/general/void_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general/void_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..a23d97f
--- /dev/null
+++ b/pkg/front_end/testcases/general/void_methods.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class Foo {
+  List list = [1, 2, 3];
+  set first(x) => list[0] = x;
+  operator []=(x, y) => list[x] = y;
+  void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/void_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/void_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5f0084
--- /dev/null
+++ b/pkg/front_end/testcases/general/void_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Foo {
+  List list = [1, 2, 3];
+  operator []=(x, y) => list[x] = y;
+  set first(x) => list[0] = x;
+  void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline.expect b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline.expect
new file mode 100644
index 0000000..9862754
--- /dev/null
+++ b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class C {
+  var superField;
+  superMethod() {}
+  get setterOnly => null;
+  void set setterOnly(_) {}
+  get getterOnly => null;
+  void set getterOnly(_) {}
+}
+
+class D extends C {
+  var field;
+  void set setterOnly(_) {}
+  get getterOnly => null;
+  method() {}
+  void test() {}
+}
+
+class E extends D {
+  var missingField;
+  void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..73c7281
--- /dev/null
+++ b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+class C {
+  get getterOnly => null;
+  get setterOnly => null;
+  superMethod() {}
+  var superField;
+  void set getterOnly(_) {}
+  void set setterOnly(_) {}
+}
+
+class D extends C {
+  get getterOnly => null;
+  method() {}
+  var field;
+  void set setterOnly(_) {}
+  void test() {}
+}
+
+class E extends D {
+  var missingField;
+  void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
new file mode 100644
index 0000000..e49eb01
--- /dev/null
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A<X extends int> {
+}
+class B {
+  A<num> fieldOfA;
+  static A<num> staticFieldOfA;
+}
+extension E<X extends A<num>> ( ){ }
+on A (){ }
+main() { }
diff --git a/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline.expect
new file mode 100644
index 0000000..085740d
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'main_lib.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..085740d
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'main_lib.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..76f9b18
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'extension_from_dill_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..76f9b18
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'extension_from_dill_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..541fc41
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "variance_from_dill_lib.dart";
+
+typedef G<T> = Function(F<T>);
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17d9aa1
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "variance_from_dill_lib.dart";
+
+main() {}
+typedef G<T> = Function(F<T>);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline.expect
new file mode 100644
index 0000000..55a63ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline.expect
@@ -0,0 +1,154 @@
+// @dart = 2.6
+main() {}
+
+class DeltaBlue {
+  void run() {}
+}
+
+class Strength {
+  final int value;
+  final String name;
+  const Strength(this.value, this.name);
+  Strength nextWeaker() => const <Strength>[
+        STRONG_PREFERRED,
+        PREFERRED,
+        STRONG_DEFAULT,
+        NORMAL,
+        WEAK_DEFAULT,
+        WEAKEST
+      ][value];
+  static bool stronger(Strength s1, Strength s2) {}
+  static bool weaker(Strength s1, Strength s2) {}
+  static Strength weakest(Strength s1, Strength s2) {}
+  static Strength strongest(Strength s1, Strength s2) {}
+}
+
+const REQUIRED = const Strength(0, "required");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const PREFERRED = const Strength(2, "preferred");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const NORMAL = const Strength(4, "normal");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const WEAKEST = const Strength(6, "weakest");
+
+abstract class Constraint {
+  final Strength strength;
+  const Constraint(this.strength);
+  bool isSatisfied();
+  void markUnsatisfied();
+  void addToGraph();
+  void removeFromGraph();
+  void chooseMethod(int mark);
+  void markInputs(int mark);
+  bool inputsKnown(int mark);
+  Variable output();
+  void execute();
+  void recalculate();
+  void addConstraint() {}
+  Constraint satisfy(mark) {}
+  void destroyConstraint() {}
+  bool isInput() => false;
+}
+
+abstract class UnaryConstraint extends Constraint {
+  final Variable myOutput;
+  bool satisfied = false;
+  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+  void addToGraph() {}
+  void chooseMethod(int mark) {}
+  bool isSatisfied() => satisfied;
+  void markInputs(int mark) {}
+  Variable output() => myOutput;
+  void recalculate() {}
+  void markUnsatisfied() {}
+  bool inputsKnown(int mark) => true;
+  void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+  StayConstraint(Variable v, Strength str) : super(v, str);
+  void execute() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+  EditConstraint(Variable v, Strength str) : super(v, str);
+  bool isInput() => true;
+  void execute() {}
+}
+
+const int NONE = 1;
+const int FORWARD = 2;
+const int BACKWARD = 0;
+
+abstract class BinaryConstraint extends Constraint {
+  Variable v1;
+  Variable v2;
+  int direction = NONE;
+  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+  void chooseMethod(int mark) {}
+  void addToGraph() {}
+  bool isSatisfied() => direction != NONE;
+  void markInputs(int mark) {}
+  Variable input() => direction == FORWARD ? v1 : v2;
+  Variable output() => direction == FORWARD ? v2 : v1;
+  void recalculate() {}
+  void markUnsatisfied() {}
+  bool inputsKnown(int mark) {}
+  void removeFromGraph() {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+  final Variable scale;
+  final Variable offset;
+  ScaleConstraint(
+      Variable src, this.scale, this.offset, Variable dest, Strength strength)
+      : super(src, dest, strength);
+  void addToGraph() {}
+  void removeFromGraph() {}
+  void markInputs(int mark) {}
+  void execute() {}
+  void recalculate() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+  EqualityConstraint(Variable v1, Variable v2, Strength strength)
+      : super(v1, v2, strength);
+  void execute() {}
+}
+
+class Variable {
+  List<Constraint> constraints = <Constraint>[];
+  Constraint determinedBy;
+  int mark = 0;
+  Strength walkStrength = WEAKEST;
+  bool stay = true;
+  int value;
+  final String name;
+  Variable(this.name, this.value);
+  void addConstraint(Constraint c) {}
+  void removeConstraint(Constraint c) {}
+}
+
+class Planner {
+  int currentMark = 0;
+  void incrementalAdd(Constraint c) {}
+  void incrementalRemove(Constraint c) {}
+  int newMark() => ++currentMark;
+  Plan makePlan(List<Constraint> sources) {}
+  Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+  bool addPropagate(Constraint c, int mark) {}
+  List<Constraint> removePropagateFrom(Variable out) {}
+  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+}
+
+class Plan {
+  List<Constraint> list = <Constraint>[];
+  void addConstraint(Constraint c) {}
+  int size() => list.length;
+  void execute() {}
+}
+
+void chainTest(int n) {}
+void projectionTest(int n) {}
+void change(Variable v, int newValue) {}
+Planner planner;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65dc50b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline_modelled.expect
@@ -0,0 +1,152 @@
+// @dart = 2.6
+Planner planner;
+
+abstract class BinaryConstraint extends Constraint {
+  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+  Variable input() => direction == FORWARD ? v1 : v2;
+  Variable output() => direction == FORWARD ? v2 : v1;
+  Variable v1;
+  Variable v2;
+  bool inputsKnown(int mark) {}
+  bool isSatisfied() => direction != NONE;
+  int direction = NONE;
+  void addToGraph() {}
+  void chooseMethod(int mark) {}
+  void markInputs(int mark) {}
+  void markUnsatisfied() {}
+  void recalculate() {}
+  void removeFromGraph() {}
+}
+
+abstract class Constraint {
+  Constraint satisfy(mark) {}
+  Variable output();
+  bool inputsKnown(int mark);
+  bool isInput() => false;
+  bool isSatisfied();
+  const Constraint(this.strength);
+  final Strength strength;
+  void addConstraint() {}
+  void addToGraph();
+  void chooseMethod(int mark);
+  void destroyConstraint() {}
+  void execute();
+  void markInputs(int mark);
+  void markUnsatisfied();
+  void recalculate();
+  void removeFromGraph();
+}
+
+abstract class UnaryConstraint extends Constraint {
+  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+  Variable output() => myOutput;
+  bool inputsKnown(int mark) => true;
+  bool isSatisfied() => satisfied;
+  bool satisfied = false;
+  final Variable myOutput;
+  void addToGraph() {}
+  void chooseMethod(int mark) {}
+  void markInputs(int mark) {}
+  void markUnsatisfied() {}
+  void recalculate() {}
+  void removeFromGraph() {}
+}
+
+class DeltaBlue {
+  void run() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+  EditConstraint(Variable v, Strength str) : super(v, str);
+  bool isInput() => true;
+  void execute() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+  EqualityConstraint(Variable v1, Variable v2, Strength strength)
+      : super(v1, v2, strength);
+  void execute() {}
+}
+
+class Plan {
+  List<Constraint> list = <Constraint>[];
+  int size() => list.length;
+  void addConstraint(Constraint c) {}
+  void execute() {}
+}
+
+class Planner {
+  List<Constraint> removePropagateFrom(Variable out) {}
+  Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+  Plan makePlan(List<Constraint> sources) {}
+  bool addPropagate(Constraint c, int mark) {}
+  int currentMark = 0;
+  int newMark() => ++currentMark;
+  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+  void incrementalAdd(Constraint c) {}
+  void incrementalRemove(Constraint c) {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+  ScaleConstraint(
+      Variable src, this.scale, this.offset, Variable dest, Strength strength)
+      : super(src, dest, strength);
+  final Variable offset;
+  final Variable scale;
+  void addToGraph() {}
+  void execute() {}
+  void markInputs(int mark) {}
+  void recalculate() {}
+  void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+  StayConstraint(Variable v, Strength str) : super(v, str);
+  void execute() {}
+}
+
+class Strength {
+  Strength nextWeaker() => const <Strength>[
+        STRONG_PREFERRED,
+        PREFERRED,
+        STRONG_DEFAULT,
+        NORMAL,
+        WEAK_DEFAULT,
+        WEAKEST
+      ][value];
+  const Strength(this.value, this.name);
+  final String name;
+  final int value;
+  static Strength strongest(Strength s1, Strength s2) {}
+  static Strength weakest(Strength s1, Strength s2) {}
+  static bool stronger(Strength s1, Strength s2) {}
+  static bool weaker(Strength s1, Strength s2) {}
+}
+
+class Variable {
+  Constraint determinedBy;
+  List<Constraint> constraints = <Constraint>[];
+  Strength walkStrength = WEAKEST;
+  Variable(this.name, this.value);
+  bool stay = true;
+  final String name;
+  int mark = 0;
+  int value;
+  void addConstraint(Constraint c) {}
+  void removeConstraint(Constraint c) {}
+}
+
+const NORMAL = const Strength(4, "normal");
+const PREFERRED = const Strength(2, "preferred");
+const REQUIRED = const Strength(0, "required");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const WEAKEST = const Strength(6, "weakest");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const int BACKWARD = 0;
+const int FORWARD = 2;
+const int NONE = 1;
+main() {}
+void chainTest(int n) {}
+void change(Variable v, int newValue) {}
+void projectionTest(int n) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline.expect
new file mode 100644
index 0000000..020c9cd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline.expect
@@ -0,0 +1,81 @@
+// @dart = 2.6
+class Interface1 {
+  void interfaceMethod1() {}
+}
+
+class Interface2 {
+  void interfaceMethod2() {}
+  var interfaceMethod1;
+}
+
+class Interface3 {
+  void interfaceMethod3() {}
+}
+
+abstract class A implements Interface1, Interface2, Interface3 {
+  aMethod() {}
+  abstractMethod();
+  void set property1(_);
+  void set property2(_);
+  void set property3(_);
+}
+
+abstract class B extends A {
+  final property1 = null;
+  aMethod() {}
+  bMethod() {}
+}
+
+class MyClass extends B {
+  var property2;
+  aaMethod() {}
+  aMethod() {}
+  bMethod() {}
+  cMethod() {}
+}
+
+class MyMock1 extends B {
+  noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+  noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+  noSuchMethod(_);
+}
+
+class C {
+  void interfaceMethod1(_) {}
+}
+
+abstract class D extends C implements Interface2 {}
+
+class E {
+  void set interfaceMethod1(_) {}
+}
+
+abstract class F extends E implements Interface1 {}
+
+class Foo {
+  void foo() {}
+}
+
+class G {
+  Object get foo => null;
+}
+
+abstract class H extends G implements Foo {}
+
+class Bar {
+  Object get foo => null;
+}
+
+class I {
+  Object foo() {}
+}
+
+abstract class J extends I implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b5b578
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,81 @@
+// @dart = 2.6
+abstract class A implements Interface1, Interface2, Interface3 {
+  aMethod() {}
+  abstractMethod();
+  void set property1(_);
+  void set property2(_);
+  void set property3(_);
+}
+
+abstract class B extends A {
+  aMethod() {}
+  bMethod() {}
+  final property1 = null;
+}
+
+abstract class D extends C implements Interface2 {}
+
+abstract class F extends E implements Interface1 {}
+
+abstract class H extends G implements Foo {}
+
+abstract class J extends I implements Bar {}
+
+class Bar {
+  Object get foo => null;
+}
+
+class C {
+  void interfaceMethod1(_) {}
+}
+
+class E {
+  void set interfaceMethod1(_) {}
+}
+
+class Foo {
+  void foo() {}
+}
+
+class G {
+  Object get foo => null;
+}
+
+class I {
+  Object foo() {}
+}
+
+class Interface1 {
+  void interfaceMethod1() {}
+}
+
+class Interface2 {
+  var interfaceMethod1;
+  void interfaceMethod2() {}
+}
+
+class Interface3 {
+  void interfaceMethod3() {}
+}
+
+class MyClass extends B {
+  aMethod() {}
+  aaMethod() {}
+  bMethod() {}
+  cMethod() {}
+  var property2;
+}
+
+class MyMock1 extends B {
+  noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+  noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+  noSuchMethod(_);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
new file mode 100644
index 0000000..51384b1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+abstract class A {
+  A foo() => null;
+}
+
+abstract class B extends A {
+  B foo();
+}
+
+class C {
+  noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..51384b1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+abstract class A {
+  A foo() => null;
+}
+
+abstract class B extends A {
+  B foo();
+}
+
+class C {
+  noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..1bfd600
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+void set onlySetter(value) {}
+
+class C {
+  void set onlySetter(value) {}
+  testC() {}
+  testD() {}
+}
+
+class D extends C {
+  String get onlySetter => "D.onlySetter called.";
+  void set onlySetter(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d39408e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class C {
+  testC() {}
+  testD() {}
+  void set onlySetter(value) {}
+}
+
+class D extends C {
+  String get onlySetter => "D.onlySetter called.";
+  void set onlySetter(value) {}
+}
+
+main() {}
+void set onlySetter(value) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline.expect
new file mode 100644
index 0000000..858862a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8e98e2c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline.expect
new file mode 100644
index 0000000..1ee4fc3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ee4fc3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_eof.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_eof.dart.textual_outline.expect
new file mode 100644
index 0000000..3e30daf
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_eof.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() { }
+@AnnotationAtEOF
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline.expect
new file mode 100644
index 0000000..3887a59
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+const int hest = 42;
+
+class Fisk<T> {
+  final T x;
+  const Fisk.fisk(this.x);
+}
+
+enum Foo {
+  @hest
+  bar,
+  @Fisk.fisk(hest)
+  baz,
+  cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..971520a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class Fisk<T> {
+  const Fisk.fisk(this.x);
+  final T x;
+}
+
+const int hest = 42;
+enum Foo {
+  @hest
+  bar,
+  @Fisk.fisk(hest)
+  baz,
+  cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline.expect
new file mode 100644
index 0000000..9309807
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+@a
+@A(1)
+library test;
+
+const Object a = const Object();
+
+class A {
+  const A(int value);
+}
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(4)
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..093fb5b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+@a
+@A(1)
+library test;
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(4)
+void main() {}
+
+class A {
+  const A(int value);
+}
+
+const Object a = const Object();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline.expect
new file mode 100644
index 0000000..615ace3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+const int foo = 21;
+const int bar = 42;
+const int baz = 84;
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..837f56e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+const int bar = 42;
+const int baz = 84;
+const int foo = 21;
+main() {}
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..8f7e683
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+const int app = 0;
+typedef int F(@app int app);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89c11f5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+const int app = 0;
+main() {}
+typedef int F(@app int app);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..344db06
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+const int foo = 42;
+
+class Bar {
+  const Bar();
+  const Bar.named(x);
+}
+
+class Baz {
+  Baz(@foo constructorFormal);
+  factory Baz.bazFactory(@foo factoryFormal) => null;
+  fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+      @foo @Bar.named(foo) formal4,
+      [@foo optional]) {}
+  hest({@foo named}) => null;
+}
+
+typedef hest_t({@foo named});
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..867b039
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class Bar {
+  const Bar();
+  const Bar.named(x);
+}
+
+class Baz {
+  Baz(@foo constructorFormal);
+  factory Baz.bazFactory(@foo factoryFormal) => null;
+  fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+      @foo @Bar.named(foo) formal4,
+      [@foo optional]) {}
+  hest({@foo named}) => null;
+}
+
+const int foo = 42;
+main() {}
+typedef hest_t({@foo named});
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline.expect
new file mode 100644
index 0000000..e20f5e7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class Base {}
+
+class Foo extends Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+void foo(x) {}
+void bar(x) {}
+void foo_escaped(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d47274
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+class Foo extends Base {}
+
+main() {}
+void bar(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+void foo(x) {}
+void foo_escaped(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..efa46bf
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo() {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6201b42
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo() {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline.expect
new file mode 100644
index 0000000..ca67ea8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+int foo(int x, int y) {}
+void loop(List xs) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1ce4ed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+int foo(int x, int y) {}
+main() {}
+void loop(List xs) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline.expect
new file mode 100644
index 0000000..75db4ee
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..75db4ee
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline.expect
new file mode 100644
index 0000000..68305dd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class A {
+  var x, y;
+  A(this.x)
+      : y = (() {
+          x = 3;
+        });
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b0144e8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class A {
+  A(this.x)
+      : y = (() {
+          x = 3;
+        });
+  var x, y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.strong.transformed.expect
index a4a39f8..c86613d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -25,21 +25,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method asyncString2() → asy::Future<core::String*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -52,13 +52,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
@@ -101,8 +101,8 @@
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -128,7 +128,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -145,8 +145,8 @@
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -163,7 +163,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -180,8 +180,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -195,12 +195,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline.expect
new file mode 100644
index 0000000..a305334
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+List<String> stringList = ["bar"];
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4121d7b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+List<String> stringList = ["bar"];
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
index a4a39f8..c86613d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -25,21 +25,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method asyncString2() → asy::Future<core::String*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -52,13 +52,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
@@ -101,8 +101,8 @@
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -128,7 +128,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -145,8 +145,8 @@
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -163,7 +163,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -180,8 +180,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -195,12 +195,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect
index 2d6ae21..bdf5176 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect
@@ -22,8 +22,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -56,13 +56,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline.expect
new file mode 100644
index 0000000..9fc36c1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import 'dart:async';
+
+void main() async {}
+
+class Node {
+  final List<Node> nested;
+  final String name;
+  Node(this.name, [this.nested]) {}
+  String toString() => '<$name:[${nested?.join(', ')}]>';
+  toSimpleString() {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3092b93
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import 'dart:async';
+
+class Node {
+  Node(this.name, [this.nested]) {}
+  String toString() => '<$name:[${nested?.join(', ')}]>';
+  final List<Node> nested;
+  final String name;
+  toSimpleString() {}
+}
+
+void main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
index 2d6ae21..bdf5176 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
@@ -22,8 +22,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -56,13 +56,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.strong.transformed.expect
index a4fa440..8c66908 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.strong.transformed.expect
@@ -8,8 +8,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -23,12 +23,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline.expect
new file mode 100644
index 0000000..f072043
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f072043
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
index a4fa440..8c66908 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
@@ -8,8 +8,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -23,12 +23,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect
index 8a2da7f..dfafacd 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect
@@ -50,8 +50,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -93,21 +93,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method topLevelMembers() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -144,21 +144,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method instanceMembers() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -196,21 +196,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method others() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -248,21 +248,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method conditionals() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -320,21 +320,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method asserts() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -344,7 +344,7 @@
       #L6:
       {
         {
-          core::Iterator<core::Function*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Function*>*>(<core::Function*>[#C1, #C2]).{core::Iterable::iterator};
+          core::Iterator<core::Function*>* :sync-for-iterator = <core::Function*>[#C1, #C2].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Function* #t26 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -393,21 +393,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method controlFlow() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -423,7 +423,7 @@
       #L7:
       {
         {
-          core::Iterator<core::Function*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Function*>*>(<core::Function*>[#C1, #C2]).{core::Iterable::iterator};
+          core::Iterator<core::Function*>* :sync-for-iterator = <core::Function*>[#C1, #C2].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Function* #t33 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -539,8 +539,8 @@
                 final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
                 asy::FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -555,13 +555,13 @@
                     asy::_completeOnAsyncReturn(:async_completer, :return_value);
                     return;
                   }
-                  on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                  on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                     :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.start(:async_op);
+                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
                 return :async_completer.{asy::Completer::future};
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
@@ -569,8 +569,8 @@
                 final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
                 asy::FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -583,13 +583,13 @@
                     asy::_completeOnAsyncReturn(:async_completer, :return_value);
                     return;
                   }
-                  on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                  on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                     :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.start(:async_op);
+                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
                 return :async_completer.{asy::Completer::future};
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
@@ -597,8 +597,8 @@
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -616,7 +616,7 @@
                       }
                       return;
                     }
-                    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                       :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
                     }
                   finally {
@@ -636,8 +636,8 @@
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -655,7 +655,7 @@
                       }
                       return;
                     }
-                    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                       :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
                     }
                   finally {
@@ -678,21 +678,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method future<T extends core::Object* = dynamic>(self::future::T* value) → asy::FutureOr<self::future::T*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<self::future::T*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::future::T*>();
   asy::FutureOr<self::future::T*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -705,13 +705,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method id<T extends core::Object* = dynamic>(self::id::T* value) → asy::FutureOr<self::id::T*>*
@@ -720,8 +720,8 @@
   asy::_AsyncStarStreamController<core::int*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -738,7 +738,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -755,8 +755,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -784,13 +784,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..74baac0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline.expect
@@ -0,0 +1,41 @@
+// @dart = 2.6
+import 'dart:async';
+
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+int get topLevelGetter => globalVariable;
+void set topLevelSetter(val) {}
+
+class C {
+  static int staticField = 1;
+  static int get staticGetter => staticField;
+  static void set staticSetter(val) {}
+  static int staticFoo(int param) => param;
+  int field = 1;
+  int get getter => field;
+  void set setter(val) {}
+  int foo(int param) => param;
+}
+
+dummy() => 1;
+staticMembers() async {}
+topLevelMembers() async {}
+instanceMembers() async {}
+others() async {}
+conditionals() async {}
+asserts() async {}
+controlFlow() async {}
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+final bool assertStatementsEnabled = () {
+  try {
+    assert(false);
+    return false;
+  } catch (_) {
+    return true;
+  }
+}();
+main() async {}
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cf5c4b2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,41 @@
+// @dart = 2.6
+import 'dart:async';
+
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+asserts() async {}
+
+class C {
+  int field = 1;
+  int foo(int param) => param;
+  int get getter => field;
+  static int get staticGetter => staticField;
+  static int staticField = 1;
+  static int staticFoo(int param) => param;
+  static void set staticSetter(val) {}
+  void set setter(val) {}
+}
+
+conditionals() async {}
+controlFlow() async {}
+dummy() => 1;
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
+final bool assertStatementsEnabled = () {
+  try {
+    assert(false);
+    return false;
+  } catch (_) {
+    return true;
+  }
+}();
+instanceMembers() async {}
+int get topLevelGetter => globalVariable;
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+main() async {}
+others() async {}
+staticMembers() async {}
+topLevelMembers() async {}
+void set topLevelSetter(val) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
index 8a2da7f..dfafacd 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
@@ -50,8 +50,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -93,21 +93,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method topLevelMembers() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -144,21 +144,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method instanceMembers() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -196,21 +196,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method others() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -248,21 +248,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method conditionals() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -320,21 +320,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method asserts() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -344,7 +344,7 @@
       #L6:
       {
         {
-          core::Iterator<core::Function*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Function*>*>(<core::Function*>[#C1, #C2]).{core::Iterable::iterator};
+          core::Iterator<core::Function*>* :sync-for-iterator = <core::Function*>[#C1, #C2].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Function* #t26 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -393,21 +393,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method controlFlow() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -423,7 +423,7 @@
       #L7:
       {
         {
-          core::Iterator<core::Function*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Function*>*>(<core::Function*>[#C1, #C2]).{core::Iterable::iterator};
+          core::Iterator<core::Function*>* :sync-for-iterator = <core::Function*>[#C1, #C2].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Function* #t33 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -539,8 +539,8 @@
                 final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
                 asy::FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -555,13 +555,13 @@
                     asy::_completeOnAsyncReturn(:async_completer, :return_value);
                     return;
                   }
-                  on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                  on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                     :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.start(:async_op);
+                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
                 return :async_completer.{asy::Completer::future};
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
@@ -569,8 +569,8 @@
                 final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
                 asy::FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -583,13 +583,13 @@
                     asy::_completeOnAsyncReturn(:async_completer, :return_value);
                     return;
                   }
-                  on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                  on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                     :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.start(:async_op);
+                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
                 return :async_completer.{asy::Completer::future};
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
@@ -597,8 +597,8 @@
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -616,7 +616,7 @@
                       }
                       return;
                     }
-                    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                       :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
                     }
                   finally {
@@ -636,8 +636,8 @@
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
                 dynamic :async_stack_trace;
-                dynamic :async_op_then;
-                dynamic :async_op_error;
+                (dynamic) →* dynamic :async_op_then;
+                (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
                 dynamic :await_ctx_var;
                 dynamic :saved_try_context_var0;
@@ -655,7 +655,7 @@
                       }
                       return;
                     }
-                    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                       :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
                     }
                   finally {
@@ -678,21 +678,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method future<T extends core::Object* = dynamic>(self::future::T* value) → asy::FutureOr<self::future::T*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<self::future::T*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::future::T*>();
   asy::FutureOr<self::future::T*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -705,13 +705,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method id<T extends core::Object* = dynamic>(self::id::T* value) → asy::FutureOr<self::id::T*>*
@@ -720,8 +720,8 @@
   asy::_AsyncStarStreamController<core::int*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -738,7 +738,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -755,8 +755,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -784,13 +784,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.strong.transformed.expect
index be2d683..72c6420 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.strong.transformed.expect
@@ -14,8 +14,8 @@
     final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
     asy::FutureOr<core::List<core::int*>*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -31,21 +31,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   method _m() → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -58,13 +58,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -72,8 +72,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -87,13 +87,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..037786a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+import 'dart:async';
+
+class C {
+  Future<List<int>> m() async => []..add(await _m());
+  Future<int> _m() async => 42;
+}
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19d43fa
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+import 'dart:async';
+
+class C {
+  Future<List<int>> m() async => []..add(await _m());
+  Future<int> _m() async => 42;
+}
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
index be2d683..72c6420 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
@@ -14,8 +14,8 @@
     final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
     asy::FutureOr<core::List<core::int*>*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -31,21 +31,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   method _m() → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -58,13 +58,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -72,8 +72,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -87,13 +87,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline.expect
new file mode 100644
index 0000000..3c7699f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+foo() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..41dbdca
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_setter_abstract.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_setter_abstract.dart.textual_outline.expect
new file mode 100644
index 0000000..795c033
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_setter_abstract.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+set b();
+set c(x, y);
+class A {
+  set a();
+  set d(x, y);
+}
+abstract class B {
+  set a();
+  set d(x, y);
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline.expect
new file mode 100644
index 0000000..3955e86
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo {
+  var field;
+}
+
+dynamic identity(x) => x;
+void use(x) {}
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1bfa6a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo {
+  var field;
+}
+
+dynamic identity(x) => x;
+main(List<String> args) {}
+void use(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..9fe865d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
@@ -0,0 +1,79 @@
+// @dart = 2.6
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+
+class Empty {}
+
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jccc<T>
+    extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a1f06bf3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,78 @@
+// @dart = 2.6
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class Empty {}
+
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Jccc<T>
+    extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..2cbc0b1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A<X> {
+  bar<Y extends X>() => null;
+}
+
+class B {
+  static A<Y> foo<Y extends Object>() => null;
+}
+
+baz() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f38302
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+baz() {}
+
+class A<X> {
+  bar<Y extends X>() => null;
+}
+
+class B {
+  static A<Y> foo<Y extends Object>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline.expect
new file mode 100644
index 0000000..5cf5db8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..94295cd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline.expect
new file mode 100644
index 0000000..5a9e0bc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {
+  var foo = 42;
+}
+
+class B extends A {
+  foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5a9e0bc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {
+  var foo = 42;
+}
+
+class B extends A {
+  foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug31124.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug31124.dart.textual_outline.expect
new file mode 100644
index 0000000..fe4ea03
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug31124.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+var a = () => 'b';
+a();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline.expect
new file mode 100644
index 0000000..c1995a0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f1f745
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline.expect
new file mode 100644
index 0000000..c1995a0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f1f745
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline.expect
new file mode 100644
index 0000000..df070ac
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class I {
+  void call();
+}
+
+class C implements I {
+  void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df070ac
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class I {
+  void call();
+}
+
+class C implements I {
+  void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline.expect
new file mode 100644
index 0000000..06ad4f4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  dynamic call(dynamic a, dynamic b) {}
+}
+
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc42c66
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  dynamic call(dynamic a, dynamic b) {}
+}
+
+main() {}
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline.expect
new file mode 100644
index 0000000..233366a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+abstract class B {
+  String get f;
+}
+
+class A implements B {
+  final f;
+  A(this.f);
+}
+
+var a = new A("foo");
+main() => print(a);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..166e7e6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+abstract class B {
+  String get f;
+}
+
+class A implements B {
+  A(this.f);
+  final f;
+}
+
+main() => print(a);
+var a = new A("foo");
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline.expect
new file mode 100644
index 0000000..004d115
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+import 'dart:mirrors';
+
+const _FailingTest failingTest = const _FailingTest();
+
+class _FailingTest {
+  const _FailingTest();
+}
+
+class MyTest {
+  @failingTest
+  void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+main() {}
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+    declaration.metadata.any((InstanceMirror annotation) {
+      print('annotation: ${annotation.reflectee}');
+      return identical(annotation.reflectee, instance);
+    });
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..187b0dc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+import 'dart:mirrors';
+
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+    declaration.metadata.any((InstanceMirror annotation) {
+      print('annotation: ${annotation.reflectee}');
+      return identical(annotation.reflectee, instance);
+    });
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+
+class MyTest {
+  @failingTest
+  void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+class _FailingTest {
+  const _FailingTest();
+}
+
+const _FailingTest failingTest = const _FailingTest();
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.strong.transformed.expect
index ca4c8a8..895484d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.strong.transformed.expect
@@ -13,8 +13,8 @@
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -27,12 +27,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline.expect
new file mode 100644
index 0000000..8386cde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:async';
+
+main() {}
+FutureOr<String> returnsString() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71a68ef2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:async';
+
+FutureOr<String> returnsString() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
index ca4c8a8..895484d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
@@ -13,8 +13,8 @@
   final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
   asy::FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -27,12 +27,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.strong.transformed.expect
index 052b974..fa92a38 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.strong.transformed.expect
@@ -25,8 +25,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::Object*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::Object*>*>();
   asy::FutureOr<core::List<core::Object*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -39,13 +39,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method f2() → core::List<core::Object*>*
@@ -54,8 +54,8 @@
   final asy::_AsyncAwaitCompleter<core::Object*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object*>();
   asy::FutureOr<core::Object*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,21 +68,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method foo() → asy::Future<self::X*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<self::X*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::X*>();
   asy::FutureOr<self::X*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -101,21 +101,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → asy::Future<void>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
   asy::FutureOr<void>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -129,12 +129,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline.expect
new file mode 100644
index 0000000..2e821ff
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'dart:async';
+
+class X {
+  final x;
+  final y;
+  X(this.x, this.y);
+  toString() => "X($x, $y)";
+}
+
+class Y {
+  f(_) {}
+}
+
+Future<List<Object>> f1() async {}
+List<Object> f2() => [2];
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0fd457d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'dart:async';
+
+Future<List<Object>> f1() async {}
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
+List<Object> f2() => [2];
+
+class X {
+  X(this.x, this.y);
+  final x;
+  final y;
+  toString() => "X($x, $y)";
+}
+
+class Y {
+  f(_) {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
index 052b974..fa92a38 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
@@ -25,8 +25,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::Object*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::Object*>*>();
   asy::FutureOr<core::List<core::Object*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -39,13 +39,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method f2() → core::List<core::Object*>*
@@ -54,8 +54,8 @@
   final asy::_AsyncAwaitCompleter<core::Object*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object*>();
   asy::FutureOr<core::Object*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,21 +68,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method foo() → asy::Future<self::X*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<self::X*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::X*>();
   asy::FutureOr<self::X*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -101,21 +101,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → asy::Future<void>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
   asy::FutureOr<void>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -129,12 +129,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline.expect
new file mode 100644
index 0000000..f13a69c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {
+  String call(String s) => '$s$s';
+}
+
+class B<T> {
+  T call(T t) => t;
+}
+
+class C {
+  T call<T>(T t) => t;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a95aef3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {
+  String call(String s) => '$s$s';
+}
+
+class B<T> {
+  T call(T t) => t;
+}
+
+class C {
+  T call<T>(T t) => t;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline.expect
new file mode 100644
index 0000000..909ecab
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..909ecab
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline.expect
new file mode 100644
index 0000000..1b15757
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A<X> {
+  foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+bar(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72036e5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+bar(B b) {}
+
+class A<X> {
+  foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline.expect
new file mode 100644
index 0000000..ba5130c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A<T extends num> {
+  void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+  void Function(T x) foo() {}
+}
+
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14bd5a1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+
+class A<T extends num> {
+  void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+  void Function(T x) foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline.expect
new file mode 100644
index 0000000..1dcd347
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Callable {
+  call(x) {}
+}
+
+class CallableGetter {
+  get call => new Callable();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1dcd347
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Callable {
+  call(x) {}
+}
+
+class CallableGetter {
+  get call => new Callable();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline.expect
new file mode 100644
index 0000000..5dd8173
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Fisk {
+  Fisk(int x) {}
+  Fisk.named(int x) {}
+  void method(int x) {}
+  static void staticMethod(int x) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3887387
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Fisk {
+  Fisk(int x) {}
+  Fisk.named(int x) {}
+  static void staticMethod(int x) {}
+  void method(int x) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline.expect
new file mode 100644
index 0000000..e2d52fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
+m2() => 1;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79e9487
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+m2() => 1;
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.strong.transformed.expect
index d20f094..1164433 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -27,13 +27,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline.expect
new file mode 100644
index 0000000..d3c388c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d3c388c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
index d20f094..1164433 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -27,13 +27,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..b4c7b69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b4c7b69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline.expect
new file mode 100644
index 0000000..8152764
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+var x = new C._circular(null);
+
+class C {
+  var f = new C._circular(null);
+  C._circular(this.f);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1a372d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+  C._circular(this.f);
+  var f = new C._circular(null);
+}
+
+main() {}
+var x = new C._circular(null);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline.expect
new file mode 100644
index 0000000..f95711e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {
+  final int x;
+  final int y;
+  A(this.y) : x = 42;
+  method() {}
+}
+
+class B extends A {
+  B(x) : super(x);
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f02021
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {
+  A(this.y) : x = 42;
+  final int x;
+  final int y;
+  method() {}
+}
+
+class B extends A {
+  B(x) : super(x);
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/clone_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/clone_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..aaa6bd0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/clone_function_type.dart.textual_outline.expect
@@ -0,0 +1,147 @@
+// @dart = 2.6
+class Am1<X, Y> {
+}
+class Bm1<Z> extends Object with Am1<Function(int), Z> {
+}
+class Cm1<Z> extends Object with Am1<Function(int x), Z> {
+}
+class Dm1<Z> extends Object with Am1<int Function(), Z> {
+}
+class Em1<Z> extends Object with Am1<Function(), Z> {
+}
+class Fm1<Z> extends Object with Am1<Function({int}), Z> {
+}
+class Gm1<Z> extends Object with Am1<Function({int x}), Z> {
+}
+class Hm1<Z> extends Object with Am1<Function([int]), Z> {
+}
+class Im1<Z> extends Object with Am1<Function([int x]), Z> {
+}
+class Jm1<Z> extends Object with Am1<Function, Z> {
+}
+class Km1<Z> extends Object with Am1<Function(Function Function), Z> {
+}
+class Lm1<Z> extends Object with Am1<Function(Function Function() Function) Function(), Z> {
+}
+class Mm1<Z> = Object with Am1<Function(int), Z>; class Nm1<Z> = Object with Am1<Function(int x), Z>; class Om1<Z> = Object with Am1<int Function(), Z>; class Pm1<Z> = Object with Am1<Function(), Z>; class Qm1<Z> = Object with Am1<Function({int}), Z>; class Rm1<Z> = Object with Am1<Function({int x}), Z>; class Sm1<Z> = Object with Am1<Function([int]), Z>; class Tm1<Z> = Object with Am1<Function([int x]), Z>; class Um1<Z> = Object with Am1<Function, Z>; class Vm1<Z> = Object with Am1<Function(Function Function), Z>; class Wm1<Z> = Object with Am1<Function(Function Function() Function) Function(), Z>;
+class Am2<X extends Function(), Y> {
+}
+class Bm2<Z> extends Object with Am2<Function(int), Z> {
+}
+class Cm2<Z> extends Object with Am2<Function(int x), Z> {
+}
+class Dm2<Z> extends Object with Am2<int Function(), Z> {
+}
+class Em2<Z> extends Object with Am2<Function(), Z> {
+}
+class Fm2<Z> extends Object with Am2<Function({int}), Z> {
+}
+class Gm2<Z> extends Object with Am2<Function({int x}), Z> {
+}
+class Hm2<Z> extends Object with Am2<Function([int]), Z> {
+}
+class Im2<Z> extends Object with Am2<Function([int x]), Z> {
+}
+class Jm2<Z> extends Object with Am2<Function, Z> {
+}
+class Km2<Z> extends Object with Am2<Function(Function Function), Z> {
+}
+class Lm2<Z> extends Object with Am2<Function(Function Function() Function) Function(), Z> {
+}
+class Mm2<Z> = Object with Am2<Function(int), Z>; class Nm2<Z> = Object with Am2<Function(int x), Z>; class Om2<Z> = Object with Am2<int Function(), Z>; class Pm2<Z> = Object with Am2<Function(), Z>; class Qm2<Z> = Object with Am2<Function({int}), Z>; class Rm2<Z> = Object with Am2<Function({int x}), Z>; class Sm2<Z> = Object with Am2<Function([int]), Z>; class Tm2<Z> = Object with Am2<Function([int x]), Z>; class Um2<Z> = Object with Am2<Function, Z>; class Vm2<Z> = Object with Am2<Function(Function Function), Z>; class Wm2<Z> = Object with Am2<Function(Function Function() Function) Function(), Z>;
+typedef TdB = Function(int);
+typedef TdC = Function(int x);
+typedef TdD = int Function();
+typedef TdE = Function();
+typedef TdF = Function({int});
+typedef TdG = Function({int x});
+typedef TdH = Function([int]);
+typedef TdI = Function([int x]);
+typedef TdJ = Function(Function Function);
+typedef TdK = Function(Function Function() Function) Function();
+class Am3<L, Y> {
+}
+class Bm3<Z> extends Object with Am3<TdB, Z> {
+}
+class Cm3<Z> extends Object with Am3<TdC, Z> {
+}
+class Dm3<Z> extends Object with Am3<TdD, Z> {
+}
+class Em3<Z> extends Object with Am3<TdE, Z> {
+}
+class Fm3<Z> extends Object with Am3<TdF, Z> {
+}
+class Gm3<Z> extends Object with Am3<TdG, Z> {
+}
+class Hm3<Z> extends Object with Am3<TdH, Z> {
+}
+class Im3<Z> extends Object with Am3<TdI, Z> {
+}
+class Jm3<Z> extends Object with Am3<TdJ, Z> {
+}
+class Km3<Z> extends Object with Am3<TdK, Z> {
+}
+class Af1<X extends Function(int)> {
+  factory Af1.foo() => null;
+}
+class Bf1<X extends Function(int x)> {
+  factory Bf1.foo() => null;
+}
+class Cf1<X extends int Function()> {
+  factory Cf1.foo() => null;
+}
+class Df1<X extends Function()> {
+  factory Df1.foo() => null;
+}
+class Ef1<X extends Function({int})> {
+  factory Ef1.foo() => null;
+}
+class Ff1<X extends Function({int x})> {
+  factory Ff1.foo() => null;
+}
+class Gf1<X extends Function([int])> {
+  factory Gf1.foo() => null;
+}
+class Hf1<X extends Function([int x])> {
+  factory Hf1.foo() => null;
+}
+class If1<X extends Function> {
+  factory If1.foo() => null;
+}
+class Jf1<X extends Function(Function Function)> {
+  factory Jf1.foo() => null;
+}
+class Kf1<X extends Function(Function Function() Function) Function()> {
+  factory Kf1.foo() => null;
+}
+class Bf2<X extends TdB> {
+  factory Bf2.foo() => null;
+}
+class Cf2<X extends TdC> {
+  factory Cf2.foo() => null;
+}
+class Df2<X extends TdD> {
+  factory Df2.foo() => null;
+}
+class Ef2<X extends TdE> {
+  factory Ef2.foo() => null;
+}
+class Ff2<X extends TdF> {
+  factory Ff2.foo() => null;
+}
+class Gf2<X extends TdG> {
+  factory Gf2.foo() => null;
+}
+class Hf2<X extends TdH> {
+  factory Hf2.foo() => null;
+}
+class If2<X extends TdI> {
+  factory If2.foo() => null;
+}
+class Jf2<X extends TdJ> {
+  factory Jf2.foo() => null;
+}
+class Kf2<X extends TdK> {
+  factory Kf2.foo() => null;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline.expect
new file mode 100644
index 0000000..6a14f58
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Foo {
+  var _field = new Bar();
+}
+
+class Bar {}
+
+useCallback(callback) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f357b93
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Bar {}
+
+class Foo {
+  var _field = new Bar();
+}
+
+main() {}
+useCallback(callback) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline.expect
new file mode 100644
index 0000000..14119f9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {
+  const A();
+}
+
+A() {}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e211177
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+A() {}
+
+class A {
+  const A();
+}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..a1e1341
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,44 @@
+// @dart = 2.6
+main() {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+class W implements Z {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class GW implements Z, GD {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class ARN extends ARQ<A> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7fa14d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,44 @@
+// @dart = 2.6
+class A {}
+
+class ARN extends ARQ<A> {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class GW implements Z, GD {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class W implements Z {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline.expect
new file mode 100644
index 0000000..5b66c35
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {
+  A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b66c35
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {
+  A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline.expect
new file mode 100644
index 0000000..5e13631
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+  const A() : this.bad();
+  A.bad() {}
+}
+
+class B extends A {
+  const B() : super.bad();
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bfc5d3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+  A.bad() {}
+  const A() : this.bad();
+}
+
+class B extends A {
+  const B() : super.bad();
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..dfe7905
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class _Y<T> {
+  const _Y();
+}
+
+class A<T> {
+  _Y<T> x;
+  A(this.x);
+}
+
+class B<T> extends A<T> {
+  B() : super(const _Y());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd5e3b9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A<T> {
+  A(this.x);
+  _Y<T> x;
+}
+
+class B<T> extends A<T> {
+  B() : super(const _Y());
+}
+
+class _Y<T> {
+  const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..5bf13d8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  A.foo() : this.bar();
+  A.bar() : this.foo();
+  A.baz() : this.foo();
+  A() : this();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4889e4e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  A() : this();
+  A.bar() : this.foo();
+  A.baz() : this.foo();
+  A.foo() : this.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline.expect
new file mode 100644
index 0000000..6654976
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+  A();
+}
+
+class B {
+  B(int x, double y, String s);
+}
+
+class C<T> {
+  C();
+}
+
+class D<T, S> {
+  D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6654976
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+  A();
+}
+
+class B {
+  B(int x, double y, String s);
+}
+
+class C<T> {
+  C();
+}
+
+class D<T, S> {
+  D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.textual_outline.expect
new file mode 100644
index 0000000..c29650c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class C1 {
+  int f;
+  C1() : =;
+}
+class C2 {
+  int f;
+  C2() : f=;
+}
+class C3 {
+  int f;
+  C3() : =f++;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline.expect
new file mode 100644
index 0000000..07cb3bd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a5d615d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.strong.transformed.expect
index 7bd3d63..9cdff84 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method main() → dynamic {
@@ -18,14 +17,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t1.{core::List::add}(4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -48,14 +47,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t2.{core::Set::add}(4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t2.{core::Set::add}(i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -78,14 +77,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t3.{core::Map::[]=}(4, 4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t3.{core::Map::[]=}(i, i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..7436629
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7436629
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect
index 7bd3d63..9cdff84 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method main() → dynamic {
@@ -18,14 +17,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t1.{core::List::add}(4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -48,14 +47,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t2.{core::Set::add}(4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t2.{core::Set::add}(i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -78,14 +77,14 @@
       if(self::oracle() as{TypeError,ForDynamic} core::bool*)
         #t3.{core::Map::[]=}(4, 4);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[5, 6, 7]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[5, 6, 7].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t3.{core::Map::[]=}(i, i);
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[8, 9, 10]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[8, 9, 10].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         if(self::oracle() as{TypeError,ForDynamic} core::bool*)
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect
index 4dce82d..5964136 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect
@@ -424,8 +424,8 @@
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
-import "dart:_internal" as _in;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → self::A*
@@ -496,7 +496,7 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
         #t10.{core::List::add}(#t11);
@@ -506,7 +506,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t12 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t13 = :sync-for-iterator.{core::Iterator::current};
         #t12.{core::Set::add}(#t13);
@@ -517,7 +517,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
         #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
@@ -528,7 +528,7 @@
   core::List<dynamic>* list21 = block {
     final core::List<dynamic>* #t16 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::List::add}(#t17);
@@ -538,7 +538,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t18 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Set::add}(#t19);
@@ -549,7 +549,7 @@
   core::Map<core::String*, dynamic>* map21 = block {
     final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, dynamic>* #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
@@ -560,7 +560,7 @@
   core::List<core::List<core::int*>*>* list22 = block {
     final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t23 = :sync-for-iterator.{core::Iterator::current};
         #t22.{core::List::add}(#t23);
@@ -570,7 +570,7 @@
   core::Set<core::List<core::int*>*>* set22 = block {
     final core::Set<core::List<core::int*>*>* #t24 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
         #t24.{core::Set::add}(#t25);
@@ -581,7 +581,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 = :sync-for-iterator.{core::Iterator::current};
         #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
@@ -593,7 +593,7 @@
     final core::List<core::int*>* #t28 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
           #t28.{core::List::add}(#t29);
@@ -604,7 +604,7 @@
     final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t31 = :sync-for-iterator.{core::Iterator::current};
           #t30.{core::Set::add}(#t31);
@@ -616,7 +616,7 @@
     final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t33 = :sync-for-iterator.{core::Iterator::current};
           #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
@@ -628,7 +628,7 @@
     final core::List<dynamic>* #t34 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
           #t34.{core::List::add}(#t35);
@@ -639,7 +639,7 @@
     final core::Set<dynamic>* #t36 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t37 = :sync-for-iterator.{core::Iterator::current};
           #t36.{core::Set::add}(#t37);
@@ -651,7 +651,7 @@
     final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, dynamic>* #t39 = :sync-for-iterator.{core::Iterator::current};
           #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
@@ -663,7 +663,7 @@
     final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t41 = :sync-for-iterator.{core::Iterator::current};
           #t40.{core::List::add}(#t41);
@@ -674,7 +674,7 @@
     final core::Set<core::List<core::int*>*>* #t42 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t43 = :sync-for-iterator.{core::Iterator::current};
           #t42.{core::Set::add}(#t43);
@@ -686,7 +686,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 = :sync-for-iterator.{core::Iterator::current};
           #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
@@ -697,7 +697,7 @@
   core::List<core::List<core::int*>*>* list40 = block {
     final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
         #t46.{core::List::add}(#t47);
@@ -707,7 +707,7 @@
   core::Set<core::List<core::int*>*>* set40 = block {
     final core::Set<core::List<core::int*>*>* #t48 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t49 = :sync-for-iterator.{core::Iterator::current};
         #t48.{core::Set::add}(#t49);
@@ -721,7 +721,7 @@
   core::List<core::List<core::int*>*>* list41 = block {
     final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t51 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t52 = #t51.{core::Set::add}(<core::int*>[]) in #t51).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t51 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t52 = #t51.{core::Set::add}(<core::int*>[]) in #t51).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t53 = :sync-for-iterator.{core::Iterator::current};
         #t50.{core::List::add}(#t53);
@@ -731,7 +731,7 @@
   core::Set<core::List<core::int*>*>* set41 = block {
     final core::Set<core::List<core::int*>*>* #t54 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t56 = #t55.{core::Set::add}(<core::int*>[]) in #t55).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t56 = #t55.{core::Set::add}(<core::int*>[]) in #t55).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t57 = :sync-for-iterator.{core::Iterator::current};
         #t54.{core::Set::add}(#t57);
@@ -743,7 +743,7 @@
     final core::List<core::List<core::int*>*>* #t58 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
           #t58.{core::List::add}(#t59);
@@ -754,7 +754,7 @@
     final core::Set<core::List<core::int*>*>* #t60 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t61 = :sync-for-iterator.{core::Iterator::current};
           #t60.{core::Set::add}(#t61);
@@ -766,7 +766,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 = :sync-for-iterator.{core::Iterator::current};
           #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
@@ -777,7 +777,7 @@
   core::List<core::int*>* list50 = block {
     final core::List<core::int*>* #t64 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t65 = :sync-for-iterator.{core::Iterator::current};
         #t64.{core::List::add}(#t65);
@@ -787,7 +787,7 @@
   core::Set<core::int*>* set50 = block {
     final core::Set<core::int*>* #t66 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t67 = :sync-for-iterator.{core::Iterator::current};
         #t66.{core::Set::add}(#t67);
@@ -798,7 +798,7 @@
   core::Map<core::String*, core::int*>* map50 = block {
     final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t69 = :sync-for-iterator.{core::Iterator::current};
         #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
@@ -809,7 +809,7 @@
   core::List<core::int*>* list51 = block {
     final core::List<core::int*>* #t70 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>() in #t71).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>() in #t71).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t72 = :sync-for-iterator.{core::Iterator::current};
         #t70.{core::List::add}(#t72);
@@ -819,7 +819,7 @@
   core::Set<core::int*>* set51 = block {
     final core::Set<core::int*>* #t73 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>() in #t74).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>() in #t74).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t75 = :sync-for-iterator.{core::Iterator::current};
         #t73.{core::Set::add}(#t75);
@@ -831,7 +831,7 @@
     final core::List<core::int*>* #t76 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t77 = :sync-for-iterator.{core::Iterator::current};
           #t76.{core::List::add}(#t77);
@@ -842,7 +842,7 @@
     final core::Set<core::int*>* #t78 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t79 = :sync-for-iterator.{core::Iterator::current};
           #t78.{core::Set::add}(#t79);
@@ -854,7 +854,7 @@
     final core::Map<core::String*, core::int*>* #t80 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
           #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
@@ -865,7 +865,7 @@
   core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t82 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
         #t82.{core::List::add}(#t83);
@@ -875,7 +875,7 @@
   core::Set<core::List<core::int*>*>* set60 = block {
     final core::Set<core::List<core::int*>*>* #t84 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t85 = :sync-for-iterator.{core::Iterator::current};
         #t84.{core::Set::add}(#t85);
@@ -886,7 +886,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t86 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t87 = :sync-for-iterator.{core::Iterator::current};
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
@@ -898,7 +898,7 @@
     final core::List<core::List<core::int*>*>* #t88 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t89 = :sync-for-iterator.{core::Iterator::current};
           #t88.{core::List::add}(#t89);
@@ -909,7 +909,7 @@
     final core::Set<core::List<core::int*>*>* #t90 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t91 = :sync-for-iterator.{core::Iterator::current};
           #t90.{core::Set::add}(#t91);
@@ -921,7 +921,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t92 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t93 = :sync-for-iterator.{core::Iterator::current};
           #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
@@ -979,14 +979,14 @@
   core::List<core::num*>* list81 = block {
     final core::List<core::num*>* #t101 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t102 = :sync-for-iterator.{core::Iterator::current};
         #t101.{core::List::add}(#t102);
       }
     }
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t103 = :sync-for-iterator.{core::Iterator::current};
         #t101.{core::List::add}(#t103);
@@ -996,14 +996,14 @@
   core::Set<core::num*>* set81 = block {
     final core::Set<core::num*>* #t104 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t105 = :sync-for-iterator.{core::Iterator::current};
         #t104.{core::Set::add}(#t105);
       }
     }
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t106 = :sync-for-iterator.{core::Iterator::current};
         #t104.{core::Set::add}(#t106);
@@ -1014,14 +1014,14 @@
   core::Map<core::String*, core::num*>* map81 = block {
     final core::Map<core::String*, core::num*>* #t107 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapToInt.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t108 = :sync-for-iterator.{core::Iterator::current};
         #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value});
       }
     }
     else {
-      core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::double*>*>*>(mapToDouble.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = mapToDouble.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t109 = :sync-for-iterator.{core::Iterator::current};
         #t107.{core::Map::[]=}(#t109.{core::MapEntry::key}, #t109.{core::MapEntry::value});
@@ -1032,14 +1032,14 @@
   core::List<dynamic>* list82 = block {
     final core::List<dynamic>* #t110 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t111 = :sync-for-iterator.{core::Iterator::current};
         #t110.{core::List::add}(#t111);
       }
     }
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t112 = :sync-for-iterator.{core::Iterator::current};
         #t110.{core::List::add}(#t112);
@@ -1049,14 +1049,14 @@
   core::Set<dynamic>* set82 = block {
     final core::Set<dynamic>* #t113 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t114 = :sync-for-iterator.{core::Iterator::current};
         #t113.{core::Set::add}(#t114);
       }
     }
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t115 = :sync-for-iterator.{core::Iterator::current};
         #t113.{core::Set::add}(#t115);
@@ -1072,7 +1072,7 @@
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t117 = :sync-for-iterator.{core::Iterator::current};
         #t116.{core::Set::add}(#t117);
@@ -1085,7 +1085,7 @@
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t118.{core::List::add}(42);
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t119 = :sync-for-iterator.{core::Iterator::current};
         #t118.{core::List::add}(#t119);
@@ -1095,7 +1095,7 @@
   core::Set<core::num*>* set83 = block {
     final core::Set<core::num*>* #t120 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t121 = :sync-for-iterator.{core::Iterator::current};
         #t120.{core::Set::add}(#t121);
@@ -1108,7 +1108,7 @@
   core::Map<core::String*, core::num*>* map83 = block {
     final core::Map<core::String*, core::num*>* #t122 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapToInt.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t123 = :sync-for-iterator.{core::Iterator::current};
         #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value});
@@ -1138,7 +1138,7 @@
   core::List<core::int*>* list91 = block {
     final core::List<core::int*>* #t127 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t128 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1151,7 +1151,7 @@
   core::Set<core::int*>* set91 = block {
     final core::Set<core::int*>* #t130 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t131 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1165,7 +1165,7 @@
   core::Map<core::String*, core::int*>* map91 = block {
     final core::Map<core::String*, core::int*>* #t133 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t134 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1220,9 +1220,9 @@
   block {
     final core::List<core::int*>* #t146 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t148 = :sync-for-iterator.{core::Iterator::current};
         #t146.{core::List::add}(#t148);
@@ -1232,9 +1232,9 @@
   block {
     final core::Set<core::int*>* #t149 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t151 = :sync-for-iterator.{core::Iterator::current};
         #t149.{core::Set::add}(#t151);
@@ -1245,9 +1245,9 @@
   block {
     final core::Map<core::String*, core::int*>* #t152 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                              ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}).{core::Iterable::iterator};
+                                              ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t154 = :sync-for-iterator.{core::Iterator::current};
         #t152.{core::Map::[]=}(#t154.{core::MapEntry::key}, #t154.{core::MapEntry::value});
@@ -1509,7 +1509,7 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t197 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t198 = :sync-for-iterator.{core::Iterator::current};
         #t197.{core::List::add}(#t198);
@@ -1519,7 +1519,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t199 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t200 = :sync-for-iterator.{core::Iterator::current};
         #t199.{core::Set::add}(#t200);
@@ -1530,7 +1530,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t201 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t202 = :sync-for-iterator.{core::Iterator::current};
         #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
@@ -1541,7 +1541,7 @@
   core::List<dynamic>* list21 = block {
     final core::List<dynamic>* #t203 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t204 = :sync-for-iterator.{core::Iterator::current};
         #t203.{core::List::add}(#t204);
@@ -1551,7 +1551,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t205 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t206 = :sync-for-iterator.{core::Iterator::current};
         #t205.{core::Set::add}(#t206);
@@ -1562,7 +1562,7 @@
   core::Map<core::String*, dynamic>* map21 = block {
     final core::Map<core::String*, dynamic>* #t207 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, dynamic>* #t208 = :sync-for-iterator.{core::Iterator::current};
         #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value});
@@ -1573,7 +1573,7 @@
   core::List<core::List<core::int*>*>* list22 = block {
     final core::List<core::List<core::int*>*>* #t209 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t210 = :sync-for-iterator.{core::Iterator::current};
         #t209.{core::List::add}(#t210);
@@ -1583,7 +1583,7 @@
   core::Set<core::List<core::int*>*>* set22 = block {
     final core::Set<core::List<core::int*>*>* #t211 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t212 = :sync-for-iterator.{core::Iterator::current};
         #t211.{core::Set::add}(#t212);
@@ -1594,7 +1594,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t214 = :sync-for-iterator.{core::Iterator::current};
         #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value});
@@ -1606,7 +1606,7 @@
     final core::List<core::int*>* #t215 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t216 = :sync-for-iterator.{core::Iterator::current};
           #t215.{core::List::add}(#t216);
@@ -1617,7 +1617,7 @@
     final core::Set<core::int*>* #t217 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t218 = :sync-for-iterator.{core::Iterator::current};
           #t217.{core::Set::add}(#t218);
@@ -1629,7 +1629,7 @@
     final core::Map<core::String*, core::int*>* #t219 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t220 = :sync-for-iterator.{core::Iterator::current};
           #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
@@ -1641,7 +1641,7 @@
     final core::List<dynamic>* #t221 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t222 = :sync-for-iterator.{core::Iterator::current};
           #t221.{core::List::add}(#t222);
@@ -1652,7 +1652,7 @@
     final core::Set<dynamic>* #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t224 = :sync-for-iterator.{core::Iterator::current};
           #t223.{core::Set::add}(#t224);
@@ -1664,7 +1664,7 @@
     final core::Map<core::String*, dynamic>* #t225 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, dynamic>* #t226 = :sync-for-iterator.{core::Iterator::current};
           #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
@@ -1676,7 +1676,7 @@
     final core::List<core::List<core::int*>*>* #t227 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t228 = :sync-for-iterator.{core::Iterator::current};
           #t227.{core::List::add}(#t228);
@@ -1687,7 +1687,7 @@
     final core::Set<core::List<core::int*>*>* #t229 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t230 = :sync-for-iterator.{core::Iterator::current};
           #t229.{core::Set::add}(#t230);
@@ -1699,7 +1699,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t231 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t232 = :sync-for-iterator.{core::Iterator::current};
           #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value});
@@ -1710,7 +1710,7 @@
   core::List<core::List<core::int*>*>* list40 = block {
     final core::List<core::List<core::int*>*>* #t233 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t234 = :sync-for-iterator.{core::Iterator::current};
         #t233.{core::List::add}(#t234);
@@ -1720,7 +1720,7 @@
   core::Set<core::List<core::int*>*>* set40 = block {
     final core::Set<core::List<core::int*>*>* #t235 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t236 = :sync-for-iterator.{core::Iterator::current};
         #t235.{core::Set::add}(#t236);
@@ -1731,7 +1731,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map40 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t237 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t238 = :sync-for-iterator.{core::Iterator::current};
         #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value});
@@ -1742,7 +1742,7 @@
   core::List<core::List<core::int*>*>* list41 = block {
     final core::List<core::List<core::int*>*>* #t239 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t241 = #t240.{core::Set::add}(<core::int*>[]) in #t240).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t241 = #t240.{core::Set::add}(<core::int*>[]) in #t240).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t242 = :sync-for-iterator.{core::Iterator::current};
         #t239.{core::List::add}(#t242);
@@ -1752,7 +1752,7 @@
   core::Set<core::List<core::int*>*>* set41 = block {
     final core::Set<core::List<core::int*>*>* #t243 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t244 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t245 = #t244.{core::Set::add}(<core::int*>[]) in #t244).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t244 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t245 = #t244.{core::Set::add}(<core::int*>[]) in #t244).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t246 = :sync-for-iterator.{core::Iterator::current};
         #t243.{core::Set::add}(#t246);
@@ -1764,7 +1764,7 @@
     final core::List<core::List<core::int*>*>* #t247 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t248 = :sync-for-iterator.{core::Iterator::current};
           #t247.{core::List::add}(#t248);
@@ -1775,7 +1775,7 @@
     final core::Set<core::List<core::int*>*>* #t249 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t250 = :sync-for-iterator.{core::Iterator::current};
           #t249.{core::Set::add}(#t250);
@@ -1787,7 +1787,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t251 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t252 = :sync-for-iterator.{core::Iterator::current};
           #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value});
@@ -1798,7 +1798,7 @@
   core::List<core::int*>* list50 = block {
     final core::List<core::int*>* #t253 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t254 = :sync-for-iterator.{core::Iterator::current};
         #t253.{core::List::add}(#t254);
@@ -1808,7 +1808,7 @@
   core::Set<core::int*>* set50 = block {
     final core::Set<core::int*>* #t255 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t256 = :sync-for-iterator.{core::Iterator::current};
         #t255.{core::Set::add}(#t256);
@@ -1819,7 +1819,7 @@
   core::Map<core::String*, core::int*>* map50 = block {
     final core::Map<core::String*, core::int*>* #t257 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t258 = :sync-for-iterator.{core::Iterator::current};
         #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value});
@@ -1830,7 +1830,7 @@
   core::List<core::int*>* list51 = block {
     final core::List<core::int*>* #t259 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>() in #t260).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>() in #t260).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t261 = :sync-for-iterator.{core::Iterator::current};
         #t259.{core::List::add}(#t261);
@@ -1840,7 +1840,7 @@
   core::Set<core::int*>* set51 = block {
     final core::Set<core::int*>* #t262 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>() in #t263).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>() in #t263).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t264 = :sync-for-iterator.{core::Iterator::current};
         #t262.{core::Set::add}(#t264);
@@ -1852,7 +1852,7 @@
     final core::List<core::int*>* #t265 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t266 = :sync-for-iterator.{core::Iterator::current};
           #t265.{core::List::add}(#t266);
@@ -1863,7 +1863,7 @@
     final core::Set<core::int*>* #t267 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t268 = :sync-for-iterator.{core::Iterator::current};
           #t267.{core::Set::add}(#t268);
@@ -1874,7 +1874,7 @@
   core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t269 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t270 = :sync-for-iterator.{core::Iterator::current};
         #t269.{core::List::add}(#t270);
@@ -1884,7 +1884,7 @@
   core::Set<core::List<core::int*>*>* set60 = block {
     final core::Set<core::List<core::int*>*>* #t271 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t272 = :sync-for-iterator.{core::Iterator::current};
         #t271.{core::Set::add}(#t272);
@@ -1895,7 +1895,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t273 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t274 = :sync-for-iterator.{core::Iterator::current};
         #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
@@ -1907,7 +1907,7 @@
     final core::List<core::List<core::int*>*>* #t275 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t276 = :sync-for-iterator.{core::Iterator::current};
           #t275.{core::List::add}(#t276);
@@ -1918,7 +1918,7 @@
     final core::Set<core::List<core::int*>*>* #t277 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t278 = :sync-for-iterator.{core::Iterator::current};
           #t277.{core::Set::add}(#t278);
@@ -1930,7 +1930,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t280 = :sync-for-iterator.{core::Iterator::current};
           #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value});
@@ -2005,14 +2005,14 @@
     final core::List<core::num*>* #t290 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t291 = :sync-for-iterator.{core::Iterator::current};
           #t290.{core::List::add}(#t291);
         }
       }
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t292 = :sync-for-iterator.{core::Iterator::current};
           #t290.{core::List::add}(#t292);
@@ -2023,14 +2023,14 @@
     final core::Set<core::num*>* #t293 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t294 = :sync-for-iterator.{core::Iterator::current};
           #t293.{core::Set::add}(#t294);
         }
       }
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t295 = :sync-for-iterator.{core::Iterator::current};
           #t293.{core::Set::add}(#t295);
@@ -2042,14 +2042,14 @@
     final core::Map<core::String*, core::num*>* #t296 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t297 = :sync-for-iterator.{core::Iterator::current};
           #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value});
         }
       }
       else {
-        core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::double*>*>*>(mapStringDouble.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = mapStringDouble.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t298 = :sync-for-iterator.{core::Iterator::current};
           #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value});
@@ -2061,14 +2061,14 @@
     final core::List<dynamic>* #t299 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t300 = :sync-for-iterator.{core::Iterator::current};
           #t299.{core::List::add}(#t300);
         }
       }
       else {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t301 = :sync-for-iterator.{core::Iterator::current};
           #t299.{core::List::add}(#t301);
@@ -2079,14 +2079,14 @@
     final core::Set<dynamic>* #t302 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t303 = :sync-for-iterator.{core::Iterator::current};
           #t302.{core::Set::add}(#t303);
         }
       }
       else {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t304 = :sync-for-iterator.{core::Iterator::current};
           #t302.{core::Set::add}(#t304);
@@ -2098,14 +2098,14 @@
     final core::Map<dynamic, dynamic>* #t305 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, dynamic>* #t306 = :sync-for-iterator.{core::Iterator::current};
           #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value});
         }
       }
       else {
-        core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, dynamic>* #t307 = :sync-for-iterator.{core::Iterator::current};
           #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value});
@@ -2119,7 +2119,7 @@
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t308.{core::List::add}(42);
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t309 = :sync-for-iterator.{core::Iterator::current};
           #t308.{core::List::add}(#t309);
@@ -2130,7 +2130,7 @@
     final core::Set<core::num*>* #t310 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t311 = :sync-for-iterator.{core::Iterator::current};
           #t310.{core::Set::add}(#t311);
@@ -2144,7 +2144,7 @@
     final core::Map<core::String*, core::num*>* #t312 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t313 = :sync-for-iterator.{core::Iterator::current};
           #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value});
@@ -2174,7 +2174,7 @@
   core::List<core::int*>* list91 = block {
     final core::List<core::int*>* #t317 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t318 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2187,7 +2187,7 @@
   core::Set<core::int*>* set91 = block {
     final core::Set<core::int*>* #t320 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t321 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2201,7 +2201,7 @@
   core::Map<core::String*, core::int*>* map91 = block {
     final core::Map<core::String*, core::int*>* #t323 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t324 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2231,7 +2231,7 @@
   core::List<core::int*>* list110 = block {
     final core::List<core::int*>* #t333 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t333.{core::List::add}(i);
@@ -2241,7 +2241,7 @@
   core::Set<core::int*>* set110 = block {
     final core::Set<core::int*>* #t334 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t334.{core::Set::add}(i);
@@ -2252,7 +2252,7 @@
   core::Map<core::String*, core::int*>* map110 = block {
     final core::Map<core::String*, core::int*>* #t335 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t335.{core::Map::[]=}("bar", i);
@@ -2263,7 +2263,7 @@
   core::List<core::int*>* list120 = block {
     final core::List<core::int*>* #t336 = <core::int*>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t336.{core::List::add}(i as{TypeError,ForDynamic} core::int*);
@@ -2273,7 +2273,7 @@
   core::Set<core::int*>* set120 = block {
     final core::Set<core::int*>* #t337 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t337.{core::Set::add}(i as{TypeError,ForDynamic} core::int*);
@@ -2284,7 +2284,7 @@
   core::Map<core::String*, core::int*>* map120 = block {
     final core::Map<core::String*, core::int*>* #t338 = <core::String*, core::int*>{};
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t338.{core::Map::[]=}("bar", i as{TypeError,ForDynamic} core::int*);
@@ -2312,8 +2312,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -2354,9 +2354,9 @@
         block {
           final core::List<core::int*>* #t350 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t352 = :sync-for-iterator.{core::Iterator::current};
               #t350.{core::List::add}(#t352);
@@ -2366,9 +2366,9 @@
         block {
           final core::Set<core::int*>* #t353 = col::LinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t355 = :sync-for-iterator.{core::Iterator::current};
               #t353.{core::Set::add}(#t355);
@@ -2379,11 +2379,11 @@
         block {
           final core::Map<core::int*, core::int*>* #t356 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                      ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                            ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}).{core::Iterable::iterator};
+                                                            ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::MapEntry<core::int*, core::int*>* #t359 = :sync-for-iterator.{core::Iterator::current};
               #t356.{core::Map::[]=}(#t359.{core::MapEntry::key}, #t359.{core::MapEntry::value});
@@ -2519,7 +2519,7 @@
         block {
           final core::List<core::int*>* #t376 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2534,7 +2534,7 @@
         block {
           final core::Set<core::int*>* #t378 = col::LinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t379 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2550,7 +2550,7 @@
         block {
           final core::Map<core::String*, core::int*>* #t380 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t381 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2566,7 +2566,7 @@
         core::List<dynamic>* list10 = block {
           final core::List<dynamic>* #t382 = <dynamic>[];
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2579,7 +2579,7 @@
         core::Set<dynamic>* set10 = block {
           final core::Set<dynamic>* #t384 = col::LinkedHashSet::•<dynamic>();
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2593,7 +2593,7 @@
         core::Map<core::String*, dynamic>* map10 = block {
           final core::Map<core::String*, dynamic>* #t386 = <core::String*, dynamic>{};
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2607,11 +2607,11 @@
         core::List<core::int*>* list20 = block {
           final core::List<core::int*>* #t388 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                ^" in "not" as{TypeError} core::int*, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                                      ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t388.{core::List::add}(i);
@@ -2621,11 +2621,11 @@
         core::Set<core::int*>* set20 = block {
           final core::Set<core::int*>* #t391 = col::LinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                                     ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                     ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t391.{core::Set::add}(i);
@@ -2636,11 +2636,11 @@
         core::Map<core::String*, core::int*>* map20 = block {
           final core::Map<core::String*, core::int*>* #t394 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                                     ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                     ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t394.{core::Map::[]=}("bar", i);
@@ -2650,7 +2650,7 @@
         } =>#t394;
         final core::List<dynamic>* #t397 = <dynamic>[];
         {
-          dynamic :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2677,7 +2677,7 @@
         core::List<dynamic>* list30 = block {} =>#t397;
         final core::Set<dynamic>* #t402 = col::LinkedHashSet::•<dynamic>();
         {
-          dynamic :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2706,7 +2706,7 @@
         } =>#t402;
         final core::Map<core::String*, dynamic>* #t407 = <core::String*, dynamic>{};
         {
-          dynamic :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2735,7 +2735,7 @@
         } =>#t407;
         final core::List<core::int*>* #t412 = <core::int*>[];
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                          ^" in "not" as{TypeError} core::int*, let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
@@ -2763,7 +2763,7 @@
         core::List<core::int*>* list40 = block {} =>#t412;
         final core::Set<core::int*>* #t418 = col::LinkedHashSet::•<core::int*>();
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
@@ -2793,7 +2793,7 @@
         } =>#t418;
         final core::Map<core::String*, core::int*>* #t424 = <core::String*, core::int*>{};
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t426 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
@@ -2865,13 +2865,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..3974366
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+oracle<T>([T t]) => true;
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+    Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testForElement(
+    dynamic dynVar,
+    List<int> listInt,
+    List<double> listDouble,
+    int index,
+    Map<String, int> mapStringInt,
+    Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+
+class A {}
+
+class B extends A {
+  int get foo => 42;
+}
+
+testPromotion(A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1d03b2c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {
+  int get foo => 42;
+}
+
+main() {}
+oracle<T>([T t]) => true;
+testForElement(
+    dynamic dynVar,
+    List<int> listInt,
+    List<double> listDouble,
+    int index,
+    Map<String, int> mapStringInt,
+    Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+    Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testPromotion(A a) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
index 4dce82d..5964136 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
@@ -424,8 +424,8 @@
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
-import "dart:_internal" as _in;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → self::A*
@@ -496,7 +496,7 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
         #t10.{core::List::add}(#t11);
@@ -506,7 +506,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t12 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t13 = :sync-for-iterator.{core::Iterator::current};
         #t12.{core::Set::add}(#t13);
@@ -517,7 +517,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
         #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
@@ -528,7 +528,7 @@
   core::List<dynamic>* list21 = block {
     final core::List<dynamic>* #t16 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::List::add}(#t17);
@@ -538,7 +538,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t18 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Set::add}(#t19);
@@ -549,7 +549,7 @@
   core::Map<core::String*, dynamic>* map21 = block {
     final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, dynamic>* #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
@@ -560,7 +560,7 @@
   core::List<core::List<core::int*>*>* list22 = block {
     final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t23 = :sync-for-iterator.{core::Iterator::current};
         #t22.{core::List::add}(#t23);
@@ -570,7 +570,7 @@
   core::Set<core::List<core::int*>*>* set22 = block {
     final core::Set<core::List<core::int*>*>* #t24 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
         #t24.{core::Set::add}(#t25);
@@ -581,7 +581,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 = :sync-for-iterator.{core::Iterator::current};
         #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
@@ -593,7 +593,7 @@
     final core::List<core::int*>* #t28 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
           #t28.{core::List::add}(#t29);
@@ -604,7 +604,7 @@
     final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t31 = :sync-for-iterator.{core::Iterator::current};
           #t30.{core::Set::add}(#t31);
@@ -616,7 +616,7 @@
     final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t33 = :sync-for-iterator.{core::Iterator::current};
           #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
@@ -628,7 +628,7 @@
     final core::List<dynamic>* #t34 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
           #t34.{core::List::add}(#t35);
@@ -639,7 +639,7 @@
     final core::Set<dynamic>* #t36 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t37 = :sync-for-iterator.{core::Iterator::current};
           #t36.{core::Set::add}(#t37);
@@ -651,7 +651,7 @@
     final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, dynamic>* #t39 = :sync-for-iterator.{core::Iterator::current};
           #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
@@ -663,7 +663,7 @@
     final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t41 = :sync-for-iterator.{core::Iterator::current};
           #t40.{core::List::add}(#t41);
@@ -674,7 +674,7 @@
     final core::Set<core::List<core::int*>*>* #t42 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t43 = :sync-for-iterator.{core::Iterator::current};
           #t42.{core::Set::add}(#t43);
@@ -686,7 +686,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 = :sync-for-iterator.{core::Iterator::current};
           #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
@@ -697,7 +697,7 @@
   core::List<core::List<core::int*>*>* list40 = block {
     final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
         #t46.{core::List::add}(#t47);
@@ -707,7 +707,7 @@
   core::Set<core::List<core::int*>*>* set40 = block {
     final core::Set<core::List<core::int*>*>* #t48 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t49 = :sync-for-iterator.{core::Iterator::current};
         #t48.{core::Set::add}(#t49);
@@ -721,7 +721,7 @@
   core::List<core::List<core::int*>*>* list41 = block {
     final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t51 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t52 = #t51.{core::Set::add}(<core::int*>[]) in #t51).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t51 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t52 = #t51.{core::Set::add}(<core::int*>[]) in #t51).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t53 = :sync-for-iterator.{core::Iterator::current};
         #t50.{core::List::add}(#t53);
@@ -731,7 +731,7 @@
   core::Set<core::List<core::int*>*>* set41 = block {
     final core::Set<core::List<core::int*>*>* #t54 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t56 = #t55.{core::Set::add}(<core::int*>[]) in #t55).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t56 = #t55.{core::Set::add}(<core::int*>[]) in #t55).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t57 = :sync-for-iterator.{core::Iterator::current};
         #t54.{core::Set::add}(#t57);
@@ -743,7 +743,7 @@
     final core::List<core::List<core::int*>*>* #t58 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
           #t58.{core::List::add}(#t59);
@@ -754,7 +754,7 @@
     final core::Set<core::List<core::int*>*>* #t60 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t61 = :sync-for-iterator.{core::Iterator::current};
           #t60.{core::Set::add}(#t61);
@@ -766,7 +766,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 = :sync-for-iterator.{core::Iterator::current};
           #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
@@ -777,7 +777,7 @@
   core::List<core::int*>* list50 = block {
     final core::List<core::int*>* #t64 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t65 = :sync-for-iterator.{core::Iterator::current};
         #t64.{core::List::add}(#t65);
@@ -787,7 +787,7 @@
   core::Set<core::int*>* set50 = block {
     final core::Set<core::int*>* #t66 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t67 = :sync-for-iterator.{core::Iterator::current};
         #t66.{core::Set::add}(#t67);
@@ -798,7 +798,7 @@
   core::Map<core::String*, core::int*>* map50 = block {
     final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t69 = :sync-for-iterator.{core::Iterator::current};
         #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
@@ -809,7 +809,7 @@
   core::List<core::int*>* list51 = block {
     final core::List<core::int*>* #t70 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>() in #t71).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>() in #t71).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t72 = :sync-for-iterator.{core::Iterator::current};
         #t70.{core::List::add}(#t72);
@@ -819,7 +819,7 @@
   core::Set<core::int*>* set51 = block {
     final core::Set<core::int*>* #t73 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>() in #t74).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>() in #t74).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t75 = :sync-for-iterator.{core::Iterator::current};
         #t73.{core::Set::add}(#t75);
@@ -831,7 +831,7 @@
     final core::List<core::int*>* #t76 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t77 = :sync-for-iterator.{core::Iterator::current};
           #t76.{core::List::add}(#t77);
@@ -842,7 +842,7 @@
     final core::Set<core::int*>* #t78 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t79 = :sync-for-iterator.{core::Iterator::current};
           #t78.{core::Set::add}(#t79);
@@ -854,7 +854,7 @@
     final core::Map<core::String*, core::int*>* #t80 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
           #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
@@ -865,7 +865,7 @@
   core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t82 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
         #t82.{core::List::add}(#t83);
@@ -875,7 +875,7 @@
   core::Set<core::List<core::int*>*>* set60 = block {
     final core::Set<core::List<core::int*>*>* #t84 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t85 = :sync-for-iterator.{core::Iterator::current};
         #t84.{core::Set::add}(#t85);
@@ -886,7 +886,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t86 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t87 = :sync-for-iterator.{core::Iterator::current};
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
@@ -898,7 +898,7 @@
     final core::List<core::List<core::int*>*>* #t88 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t89 = :sync-for-iterator.{core::Iterator::current};
           #t88.{core::List::add}(#t89);
@@ -909,7 +909,7 @@
     final core::Set<core::List<core::int*>*>* #t90 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t91 = :sync-for-iterator.{core::Iterator::current};
           #t90.{core::Set::add}(#t91);
@@ -921,7 +921,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t92 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t93 = :sync-for-iterator.{core::Iterator::current};
           #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
@@ -979,14 +979,14 @@
   core::List<core::num*>* list81 = block {
     final core::List<core::num*>* #t101 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t102 = :sync-for-iterator.{core::Iterator::current};
         #t101.{core::List::add}(#t102);
       }
     }
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t103 = :sync-for-iterator.{core::Iterator::current};
         #t101.{core::List::add}(#t103);
@@ -996,14 +996,14 @@
   core::Set<core::num*>* set81 = block {
     final core::Set<core::num*>* #t104 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t105 = :sync-for-iterator.{core::Iterator::current};
         #t104.{core::Set::add}(#t105);
       }
     }
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t106 = :sync-for-iterator.{core::Iterator::current};
         #t104.{core::Set::add}(#t106);
@@ -1014,14 +1014,14 @@
   core::Map<core::String*, core::num*>* map81 = block {
     final core::Map<core::String*, core::num*>* #t107 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapToInt.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t108 = :sync-for-iterator.{core::Iterator::current};
         #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value});
       }
     }
     else {
-      core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::double*>*>*>(mapToDouble.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = mapToDouble.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t109 = :sync-for-iterator.{core::Iterator::current};
         #t107.{core::Map::[]=}(#t109.{core::MapEntry::key}, #t109.{core::MapEntry::value});
@@ -1032,14 +1032,14 @@
   core::List<dynamic>* list82 = block {
     final core::List<dynamic>* #t110 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t111 = :sync-for-iterator.{core::Iterator::current};
         #t110.{core::List::add}(#t111);
       }
     }
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t112 = :sync-for-iterator.{core::Iterator::current};
         #t110.{core::List::add}(#t112);
@@ -1049,14 +1049,14 @@
   core::Set<dynamic>* set82 = block {
     final core::Set<dynamic>* #t113 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t114 = :sync-for-iterator.{core::Iterator::current};
         #t113.{core::Set::add}(#t114);
       }
     }
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t115 = :sync-for-iterator.{core::Iterator::current};
         #t113.{core::Set::add}(#t115);
@@ -1072,7 +1072,7 @@
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
     else {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t117 = :sync-for-iterator.{core::Iterator::current};
         #t116.{core::Set::add}(#t117);
@@ -1085,7 +1085,7 @@
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t118.{core::List::add}(42);
     else {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t119 = :sync-for-iterator.{core::Iterator::current};
         #t118.{core::List::add}(#t119);
@@ -1095,7 +1095,7 @@
   core::Set<core::num*>* set83 = block {
     final core::Set<core::num*>* #t120 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::num* #t121 = :sync-for-iterator.{core::Iterator::current};
         #t120.{core::Set::add}(#t121);
@@ -1108,7 +1108,7 @@
   core::Map<core::String*, core::num*>* map83 = block {
     final core::Map<core::String*, core::num*>* #t122 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapToInt.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::num*>* #t123 = :sync-for-iterator.{core::Iterator::current};
         #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value});
@@ -1138,7 +1138,7 @@
   core::List<core::int*>* list91 = block {
     final core::List<core::int*>* #t127 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t128 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1151,7 +1151,7 @@
   core::Set<core::int*>* set91 = block {
     final core::Set<core::int*>* #t130 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t131 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1165,7 +1165,7 @@
   core::Map<core::String*, core::int*>* map91 = block {
     final core::Map<core::String*, core::int*>* #t133 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t134 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -1220,9 +1220,9 @@
   block {
     final core::List<core::int*>* #t146 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t148 = :sync-for-iterator.{core::Iterator::current};
         #t146.{core::List::add}(#t148);
@@ -1232,9 +1232,9 @@
   block {
     final core::Set<core::int*>* #t149 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t151 = :sync-for-iterator.{core::Iterator::current};
         #t149.{core::Set::add}(#t151);
@@ -1245,9 +1245,9 @@
   block {
     final core::Map<core::String*, core::int*>* #t152 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                              ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}).{core::Iterable::iterator};
+                                              ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t154 = :sync-for-iterator.{core::Iterator::current};
         #t152.{core::Map::[]=}(#t154.{core::MapEntry::key}, #t154.{core::MapEntry::value});
@@ -1509,7 +1509,7 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t197 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t198 = :sync-for-iterator.{core::Iterator::current};
         #t197.{core::List::add}(#t198);
@@ -1519,7 +1519,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t199 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t200 = :sync-for-iterator.{core::Iterator::current};
         #t199.{core::Set::add}(#t200);
@@ -1530,7 +1530,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t201 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t202 = :sync-for-iterator.{core::Iterator::current};
         #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
@@ -1541,7 +1541,7 @@
   core::List<dynamic>* list21 = block {
     final core::List<dynamic>* #t203 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t204 = :sync-for-iterator.{core::Iterator::current};
         #t203.{core::List::add}(#t204);
@@ -1551,7 +1551,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t205 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t206 = :sync-for-iterator.{core::Iterator::current};
         #t205.{core::Set::add}(#t206);
@@ -1562,7 +1562,7 @@
   core::Map<core::String*, dynamic>* map21 = block {
     final core::Map<core::String*, dynamic>* #t207 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, dynamic>* #t208 = :sync-for-iterator.{core::Iterator::current};
         #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value});
@@ -1573,7 +1573,7 @@
   core::List<core::List<core::int*>*>* list22 = block {
     final core::List<core::List<core::int*>*>* #t209 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t210 = :sync-for-iterator.{core::Iterator::current};
         #t209.{core::List::add}(#t210);
@@ -1583,7 +1583,7 @@
   core::Set<core::List<core::int*>*>* set22 = block {
     final core::Set<core::List<core::int*>*>* #t211 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t212 = :sync-for-iterator.{core::Iterator::current};
         #t211.{core::Set::add}(#t212);
@@ -1594,7 +1594,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t214 = :sync-for-iterator.{core::Iterator::current};
         #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value});
@@ -1606,7 +1606,7 @@
     final core::List<core::int*>* #t215 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t216 = :sync-for-iterator.{core::Iterator::current};
           #t215.{core::List::add}(#t216);
@@ -1617,7 +1617,7 @@
     final core::Set<core::int*>* #t217 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[42]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t218 = :sync-for-iterator.{core::Iterator::current};
           #t217.{core::Set::add}(#t218);
@@ -1629,7 +1629,7 @@
     final core::Map<core::String*, core::int*>* #t219 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{"bar": 42}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::int*>* #t220 = :sync-for-iterator.{core::Iterator::current};
           #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
@@ -1641,7 +1641,7 @@
     final core::List<dynamic>* #t221 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t222 = :sync-for-iterator.{core::Iterator::current};
           #t221.{core::List::add}(#t222);
@@ -1652,7 +1652,7 @@
     final core::Set<dynamic>* #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[dynVar]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t224 = :sync-for-iterator.{core::Iterator::current};
           #t223.{core::Set::add}(#t224);
@@ -1664,7 +1664,7 @@
     final core::Map<core::String*, dynamic>* #t225 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, dynamic>*>*>(<core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, dynamic>*>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, dynamic>* #t226 = :sync-for-iterator.{core::Iterator::current};
           #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
@@ -1676,7 +1676,7 @@
     final core::List<core::List<core::int*>*>* #t227 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t228 = :sync-for-iterator.{core::Iterator::current};
           #t227.{core::List::add}(#t228);
@@ -1687,7 +1687,7 @@
     final core::Set<core::List<core::int*>*>* #t229 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[42]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t230 = :sync-for-iterator.{core::Iterator::current};
           #t229.{core::Set::add}(#t230);
@@ -1699,7 +1699,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t231 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t232 = :sync-for-iterator.{core::Iterator::current};
           #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value});
@@ -1710,7 +1710,7 @@
   core::List<core::List<core::int*>*>* list40 = block {
     final core::List<core::List<core::int*>*>* #t233 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t234 = :sync-for-iterator.{core::Iterator::current};
         #t233.{core::List::add}(#t234);
@@ -1720,7 +1720,7 @@
   core::Set<core::List<core::int*>*>* set40 = block {
     final core::Set<core::List<core::int*>*>* #t235 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t236 = :sync-for-iterator.{core::Iterator::current};
         #t235.{core::Set::add}(#t236);
@@ -1731,7 +1731,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map40 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t237 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t238 = :sync-for-iterator.{core::Iterator::current};
         #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value});
@@ -1742,7 +1742,7 @@
   core::List<core::List<core::int*>*>* list41 = block {
     final core::List<core::List<core::int*>*>* #t239 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t241 = #t240.{core::Set::add}(<core::int*>[]) in #t240).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t241 = #t240.{core::Set::add}(<core::int*>[]) in #t240).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t242 = :sync-for-iterator.{core::Iterator::current};
         #t239.{core::List::add}(#t242);
@@ -1752,7 +1752,7 @@
   core::Set<core::List<core::int*>*>* set41 = block {
     final core::Set<core::List<core::int*>*>* #t243 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(let final core::Set<core::List<core::int*>*>* #t244 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t245 = #t244.{core::Set::add}(<core::int*>[]) in #t244).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = (let final core::Set<core::List<core::int*>*>* #t244 = col::LinkedHashSet::•<core::List<core::int*>*>() in let final core::bool* #t245 = #t244.{core::Set::add}(<core::int*>[]) in #t244).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t246 = :sync-for-iterator.{core::Iterator::current};
         #t243.{core::Set::add}(#t246);
@@ -1764,7 +1764,7 @@
     final core::List<core::List<core::int*>*>* #t247 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t248 = :sync-for-iterator.{core::Iterator::current};
           #t247.{core::List::add}(#t248);
@@ -1775,7 +1775,7 @@
     final core::Set<core::List<core::int*>*>* #t249 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t250 = :sync-for-iterator.{core::Iterator::current};
           #t249.{core::Set::add}(#t250);
@@ -1787,7 +1787,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t251 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t252 = :sync-for-iterator.{core::Iterator::current};
           #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value});
@@ -1798,7 +1798,7 @@
   core::List<core::int*>* list50 = block {
     final core::List<core::int*>* #t253 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t254 = :sync-for-iterator.{core::Iterator::current};
         #t253.{core::List::add}(#t254);
@@ -1808,7 +1808,7 @@
   core::Set<core::int*>* set50 = block {
     final core::Set<core::int*>* #t255 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t256 = :sync-for-iterator.{core::Iterator::current};
         #t255.{core::Set::add}(#t256);
@@ -1819,7 +1819,7 @@
   core::Map<core::String*, core::int*>* map50 = block {
     final core::Map<core::String*, core::int*>* #t257 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t258 = :sync-for-iterator.{core::Iterator::current};
         #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value});
@@ -1830,7 +1830,7 @@
   core::List<core::int*>* list51 = block {
     final core::List<core::int*>* #t259 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>() in #t260).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>() in #t260).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t261 = :sync-for-iterator.{core::Iterator::current};
         #t259.{core::List::add}(#t261);
@@ -1840,7 +1840,7 @@
   core::Set<core::int*>* set51 = block {
     final core::Set<core::int*>* #t262 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(let final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>() in #t263).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = (let final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>() in #t263).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t264 = :sync-for-iterator.{core::Iterator::current};
         #t262.{core::Set::add}(#t264);
@@ -1852,7 +1852,7 @@
     final core::List<core::int*>* #t265 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t266 = :sync-for-iterator.{core::Iterator::current};
           #t265.{core::List::add}(#t266);
@@ -1863,7 +1863,7 @@
     final core::Set<core::int*>* #t267 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t268 = :sync-for-iterator.{core::Iterator::current};
           #t267.{core::Set::add}(#t268);
@@ -1874,7 +1874,7 @@
   core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t269 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t270 = :sync-for-iterator.{core::Iterator::current};
         #t269.{core::List::add}(#t270);
@@ -1884,7 +1884,7 @@
   core::Set<core::List<core::int*>*>* set60 = block {
     final core::Set<core::List<core::int*>*>* #t271 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t272 = :sync-for-iterator.{core::Iterator::current};
         #t271.{core::Set::add}(#t272);
@@ -1895,7 +1895,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t273 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t274 = :sync-for-iterator.{core::Iterator::current};
         #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
@@ -1907,7 +1907,7 @@
     final core::List<core::List<core::int*>*>* #t275 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t276 = :sync-for-iterator.{core::Iterator::current};
           #t275.{core::List::add}(#t276);
@@ -1918,7 +1918,7 @@
     final core::Set<core::List<core::int*>*>* #t277 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::List<core::int*>* #t278 = :sync-for-iterator.{core::Iterator::current};
           #t277.{core::Set::add}(#t278);
@@ -1930,7 +1930,7 @@
     final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::List<core::int*>*>* #t280 = :sync-for-iterator.{core::Iterator::current};
           #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value});
@@ -2005,14 +2005,14 @@
     final core::List<core::num*>* #t290 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t291 = :sync-for-iterator.{core::Iterator::current};
           #t290.{core::List::add}(#t291);
         }
       }
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t292 = :sync-for-iterator.{core::Iterator::current};
           #t290.{core::List::add}(#t292);
@@ -2023,14 +2023,14 @@
     final core::Set<core::num*>* #t293 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t294 = :sync-for-iterator.{core::Iterator::current};
           #t293.{core::Set::add}(#t294);
         }
       }
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t295 = :sync-for-iterator.{core::Iterator::current};
           #t293.{core::Set::add}(#t295);
@@ -2042,14 +2042,14 @@
     final core::Map<core::String*, core::num*>* #t296 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t297 = :sync-for-iterator.{core::Iterator::current};
           #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value});
         }
       }
       else {
-        core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::double*>*>*>(mapStringDouble.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::double*>*>* :sync-for-iterator = mapStringDouble.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t298 = :sync-for-iterator.{core::Iterator::current};
           #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value});
@@ -2061,14 +2061,14 @@
     final core::List<dynamic>* #t299 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t300 = :sync-for-iterator.{core::Iterator::current};
           #t299.{core::List::add}(#t300);
         }
       }
       else {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t301 = :sync-for-iterator.{core::Iterator::current};
           #t299.{core::List::add}(#t301);
@@ -2079,14 +2079,14 @@
     final core::Set<dynamic>* #t302 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t303 = :sync-for-iterator.{core::Iterator::current};
           #t302.{core::Set::add}(#t303);
         }
       }
       else {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t304 = :sync-for-iterator.{core::Iterator::current};
           #t302.{core::Set::add}(#t304);
@@ -2098,14 +2098,14 @@
     final core::Map<dynamic, dynamic>* #t305 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, dynamic>* #t306 = :sync-for-iterator.{core::Iterator::current};
           #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value});
         }
       }
       else {
-        core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, dynamic>* #t307 = :sync-for-iterator.{core::Iterator::current};
           #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value});
@@ -2119,7 +2119,7 @@
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t308.{core::List::add}(42);
       else {
-        core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(listDouble).{core::Iterable::iterator};
+        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t309 = :sync-for-iterator.{core::Iterator::current};
           #t308.{core::List::add}(#t309);
@@ -2130,7 +2130,7 @@
     final core::Set<core::num*>* #t310 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(listInt).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::num* #t311 = :sync-for-iterator.{core::Iterator::current};
           #t310.{core::Set::add}(#t311);
@@ -2144,7 +2144,7 @@
     final core::Map<core::String*, core::num*>* #t312 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapStringInt.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<core::String*, core::num*>* #t313 = :sync-for-iterator.{core::Iterator::current};
           #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value});
@@ -2174,7 +2174,7 @@
   core::List<core::int*>* list91 = block {
     final core::List<core::int*>* #t317 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t318 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2187,7 +2187,7 @@
   core::Set<core::int*>* set91 = block {
     final core::Set<core::int*>* #t320 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t321 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2201,7 +2201,7 @@
   core::Map<core::String*, core::int*>* map91 = block {
     final core::Map<core::String*, core::int*>* #t323 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t324 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -2231,7 +2231,7 @@
   core::List<core::int*>* list110 = block {
     final core::List<core::int*>* #t333 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t333.{core::List::add}(i);
@@ -2241,7 +2241,7 @@
   core::Set<core::int*>* set110 = block {
     final core::Set<core::int*>* #t334 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t334.{core::Set::add}(i);
@@ -2252,7 +2252,7 @@
   core::Map<core::String*, core::int*>* map110 = block {
     final core::Map<core::String*, core::int*>* #t335 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
         #t335.{core::Map::[]=}("bar", i);
@@ -2263,7 +2263,7 @@
   core::List<core::int*>* list120 = block {
     final core::List<core::int*>* #t336 = <core::int*>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t336.{core::List::add}(i as{TypeError,ForDynamic} core::int*);
@@ -2273,7 +2273,7 @@
   core::Set<core::int*>* set120 = block {
     final core::Set<core::int*>* #t337 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t337.{core::Set::add}(i as{TypeError,ForDynamic} core::int*);
@@ -2284,7 +2284,7 @@
   core::Map<core::String*, core::int*>* map120 = block {
     final core::Map<core::String*, core::int*>* #t338 = <core::String*, core::int*>{};
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
         #t338.{core::Map::[]=}("bar", i as{TypeError,ForDynamic} core::int*);
@@ -2312,8 +2312,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -2354,9 +2354,9 @@
         block {
           final core::List<core::int*>* #t350 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t352 = :sync-for-iterator.{core::Iterator::current};
               #t350.{core::List::add}(#t352);
@@ -2366,9 +2366,9 @@
         block {
           final core::Set<core::int*>* #t353 = col::LinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t355 = :sync-for-iterator.{core::Iterator::current};
               #t353.{core::Set::add}(#t355);
@@ -2379,11 +2379,11 @@
         block {
           final core::Map<core::int*, core::int*>* #t356 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                      ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                            ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}).{core::Iterable::iterator};
+                                                            ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::MapEntry<core::int*, core::int*>* #t359 = :sync-for-iterator.{core::Iterator::current};
               #t356.{core::Map::[]=}(#t359.{core::MapEntry::key}, #t359.{core::MapEntry::value});
@@ -2519,7 +2519,7 @@
         block {
           final core::List<core::int*>* #t376 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2534,7 +2534,7 @@
         block {
           final core::Set<core::int*>* #t378 = col::LinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t379 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2550,7 +2550,7 @@
         block {
           final core::Map<core::String*, core::int*>* #t380 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1]).{core::Iterable::iterator};
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t381 = :sync-for-iterator.{core::Iterator::current};
               {
@@ -2566,7 +2566,7 @@
         core::List<dynamic>* list10 = block {
           final core::List<dynamic>* #t382 = <dynamic>[];
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2579,7 +2579,7 @@
         core::Set<dynamic>* set10 = block {
           final core::Set<dynamic>* #t384 = col::LinkedHashSet::•<dynamic>();
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2593,7 +2593,7 @@
         core::Map<core::String*, dynamic>* map10 = block {
           final core::Map<core::String*, dynamic>* #t386 = <core::String*, dynamic>{};
           {
-            core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -2607,11 +2607,11 @@
         core::List<core::int*>* list20 = block {
           final core::List<core::int*>* #t388 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                ^" in "not" as{TypeError} core::int*, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                                      ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t388.{core::List::add}(i);
@@ -2621,11 +2621,11 @@
         core::Set<core::int*>* set20 = block {
           final core::Set<core::int*>* #t391 = col::LinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                                     ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                     ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t391.{core::Set::add}(i);
@@ -2636,11 +2636,11 @@
         core::Map<core::String*, core::int*>* map20 = block {
           final core::Map<core::String*, core::int*>* #t394 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                                     ^" in "int" as{TypeError} core::int*]).{core::Iterable::iterator};
+                                     ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
               #t394.{core::Map::[]=}("bar", i);
@@ -2650,7 +2650,7 @@
         } =>#t394;
         final core::List<dynamic>* #t397 = <dynamic>[];
         {
-          dynamic :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2677,7 +2677,7 @@
         core::List<dynamic>* list30 = block {} =>#t397;
         final core::Set<dynamic>* #t402 = col::LinkedHashSet::•<dynamic>();
         {
-          dynamic :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2706,7 +2706,7 @@
         } =>#t402;
         final core::Map<core::String*, dynamic>* #t407 = <core::String*, dynamic>{};
         {
-          dynamic :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2735,7 +2735,7 @@
         } =>#t407;
         final core::List<core::int*>* #t412 = <core::int*>[];
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                          ^" in "not" as{TypeError} core::int*, let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
@@ -2763,7 +2763,7 @@
         core::List<core::int*>* list40 = block {} =>#t412;
         final core::Set<core::int*>* #t418 = col::LinkedHashSet::•<core::int*>();
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
@@ -2793,7 +2793,7 @@
         } =>#t418;
         final core::Map<core::String*, core::int*>* #t424 = <core::String*, core::int*>{};
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*>* :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t426 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
@@ -2865,13 +2865,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart
new file mode 100644
index 0000000..4ac4d16
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {
+  a == a; // ok
+  a == b; // ok
+  a == c_dynamic; // error
+  a == c_int; // error
+  a == c_string; // error
+  a == d; // error
+
+  b == a; // ok
+  b == b; // ok
+  b == c_dynamic; // error
+  b == c_int; // error
+  b == c_string; // error
+  b == d; // error
+
+  c_dynamic == a; // error
+  c_dynamic == b; // error
+  c_dynamic == c_dynamic; // ok
+  c_dynamic == c_int; // ok
+  c_dynamic == c_string; // ok
+  c_dynamic == d; // ok
+
+  c_int == a; // error
+  c_int == b; // error
+  c_int == c_dynamic; // ok
+  c_int == c_int; // ok
+  c_int == c_string; // error
+  c_int == d; // ok}
+
+  c_string == a; // error
+  c_string == b; // error
+  c_string == c_dynamic; // ok
+  c_string == c_int; // error
+  c_string == c_string; // ok
+  c_string == d; // error
+
+  d == a; // error
+  d == b; // error
+  d == c_dynamic; // ok
+  d == c_int; // ok
+  d == c_string; // error
+  d == d; // ok
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.outline.expect
new file mode 100644
index 0000000..d521bc4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    ;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    ;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    ;
+}
+static method main() → dynamic
+  ;
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.strong.expect
new file mode 100644
index 0000000..f58c540
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.strong.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    return true;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError} self::A*);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError} self::A*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_dynamic as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError} self::C<core::String*>*);
+  d.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..f58c540
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.strong.transformed.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    return true;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError} self::A*);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError} self::A*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_dynamic as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError} self::C<core::String*>*);
+  d.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..e4fba1e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e4fba1e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.weak.expect
new file mode 100644
index 0000000..f58c540
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.weak.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    return true;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError} self::A*);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError} self::A*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_dynamic as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError} self::C<core::String*>*);
+  d.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.weak.transformed.expect
new file mode 100644
index 0000000..f58c540
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.weak.transformed.expect
@@ -0,0 +1,266 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+//  - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+//  - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+//  - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+//  - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A* other) → core::bool*
+    return true;
+}
+class C<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T*>*
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T*>* other) → core::bool*
+    return true;
+}
+class D extends self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method test(self::A* a, self::B* b, self::C<dynamic>* c_dynamic, self::C<core::int*>* c_int, self::C<core::String*>* c_string, self::D* d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:26:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:27:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:28:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:29:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError} self::A*);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:33:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:34:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:35:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError} self::A*);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:36:8: Error: The argument type 'D' can't be assigned to the parameter type 'A'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError} self::A*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:38:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:39:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError} self::C<dynamic>*);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:45:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:46:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:49:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError} self::C<core::int*>*);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:52:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:53:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_dynamic as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:55:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError} self::C<core::String*>*);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:57:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>'.
+ - 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError} self::C<core::String*>*);
+  d.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:59:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>'.
+ - 'A' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:60:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>'.
+ - 'B' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_dynamic as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart:63:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>'.
+ - 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError} self::C<core::int*>*);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..72ea40f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+typedef void Callback<T>(T x);
+
+class Foo<T> {
+  final T finalField;
+  final Callback<T> callbackField;
+  T mutableField;
+  Callback<T> mutableCallbackField;
+  Foo(this.finalField, this.callbackField);
+  void method(T x) {}
+  set setter(T x) {}
+  void withCallback(Callback<T> callback) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..31c6cd5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Foo<T> {
+  Callback<T> mutableCallbackField;
+  Foo(this.finalField, this.callbackField);
+  T mutableField;
+  final Callback<T> callbackField;
+  final T finalField;
+  set setter(T x) {}
+  void method(T x) {}
+  void withCallback(Callback<T> callback) {}
+}
+
+main() {}
+typedef void Callback<T>(T x);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..9bbf948
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+  void foo(covariant num x) {}
+}
+
+class B {
+  void foo(num x) {}
+}
+
+class C {
+  void foo(num x) {}
+}
+
+class D extends A with B implements C {
+  void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9bbf948
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+  void foo(covariant num x) {}
+}
+
+class B {
+  void foo(num x) {}
+}
+
+class C {
+  void foo(num x) {}
+}
+
+class D extends A with B implements C {
+  void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline.expect
new file mode 100644
index 0000000..63a5f33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..63a5f33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..d390870
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+topLevel([a = 42]) => a;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ddce93f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+topLevel([a = 42]) => a;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..5b64564
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b64564
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..2c4038e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class Dupe {}
+
+class Dupe {}
+
+class C {
+  Dupe.a b;
+  dupe.C d;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f7b1746
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class C {
+  Dupe.a b;
+  dupe.C d;
+}
+
+class Dupe {}
+
+class Dupe {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_declarations.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_declarations.dart.textual_outline.expect
new file mode 100644
index 0000000..f7ac94b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_declarations.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+// @dart = 2.6
+part "duplicated_declarations_part.dart"; import 'duplicated_declarations_lib.dart' as Typedef; import 'duplicated_declarations_lib.dart' as Typedef;
+typedef Typedef = void Function();
+typedef Typedef = Object Function();
+import 'duplicated_declarations_lib.dart' as Typedef;
+typedef void OldTypedef();
+typedef Object OldTypedef();
+var field = "1st";
+var field = "2nd";
+main() { }
+main() { }
+foo() { }
+class C {
+  C(a);
+  C(a, b);
+  var field = "1st";
+  var field = "2nd";
+  m() { }
+  m() { }
+  static s() { }
+  static s() { }
+  static f() => s;
+}
+class Sub extends C {
+  Sub() : super(null);
+  m() => super.m();
+}
+class C {
+  C._();
+}
+enum Enum { Enum, a, a, b, }
+enum Enum { a, b, c, }
+enum AnotherEnum { a, b, c, _name, index, toString, values, }
+useAnotherEnum() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..9d71884
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class A {
+  int a;
+  int a;
+  A(this.a);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82dc367
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class A {
+  A(this.a);
+  int a;
+  int a;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline.expect
new file mode 100644
index 0000000..a8791fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library test;
+
+class C {
+  static m({int a: 0}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d76a64
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library test;
+
+class C {
+  static m({int a: 0}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.expect
index 0e3241e..87aef8c 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.expect
@@ -11,6 +11,6 @@
 import "dart:core";
 
 static method testDynamic() → invalid-type
-  return 0 as{TypeError} invalid-type;
+  return 0;
 static method testVoid() → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.transformed.expect
index 0e3241e..87aef8c 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.strong.transformed.expect
@@ -11,6 +11,6 @@
 import "dart:core";
 
 static method testDynamic() → invalid-type
-  return 0 as{TypeError} invalid-type;
+  return 0;
 static method testVoid() → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline.expect
new file mode 100644
index 0000000..32b4171
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+void testVoid() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e08ab2d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+main() {}
+void testVoid() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.expect
index 0e3241e..87aef8c 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.expect
@@ -11,6 +11,6 @@
 import "dart:core";
 
 static method testDynamic() → invalid-type
-  return 0 as{TypeError} invalid-type;
+  return 0;
 static method testVoid() → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.transformed.expect
index 0e3241e..87aef8c 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.weak.transformed.expect
@@ -11,6 +11,6 @@
 import "dart:core";
 
 static method testDynamic() → invalid-type
-  return 0 as{TypeError} invalid-type;
+  return 0;
 static method testVoid() → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline.expect
new file mode 100644
index 0000000..c7f2b39
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7f2b39
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline.expect
new file mode 100644
index 0000000..4a65ff5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a65ff5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline.expect
new file mode 100644
index 0000000..028a793
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..028a793
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline.expect
new file mode 100644
index 0000000..3deded7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3deded7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline.expect
new file mode 100644
index 0000000..e2be00e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e2be00e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline.expect
new file mode 100644
index 0000000..218450a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..218450a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline.expect
new file mode 100644
index 0000000..bdc547b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {
+  var field;
+}
+
+class B {
+  var field;
+}
+
+class C {
+  operator ==(x) => false;
+}
+
+class X implements A, B {
+  var field;
+}
+
+void useAsA(A object) {}
+void useAsB(B object) {}
+void escape(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..344fffd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {
+  var field;
+}
+
+class B {
+  var field;
+}
+
+class C {
+  operator ==(x) => false;
+}
+
+class X implements A, B {
+  var field;
+}
+
+main() {}
+void escape(x) {}
+void useAsA(A object) {}
+void useAsB(B object) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline.expect
new file mode 100644
index 0000000..711d1b4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..711d1b4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline.expect
new file mode 100644
index 0000000..8188bed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8188bed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..1b5dea8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo({fisk}) {}
+caller(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2426a32
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+caller(f) {}
+foo({fisk}) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..4fb5044
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class SuperClass {}
+
+mixin Mixin<T> {}
+
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d6e04d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+class SuperClass {}
+
+main() {}
+mixin Mixin<T> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline.expect
new file mode 100644
index 0000000..72d8f00
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:isolate';
+
+var subscription;
+void onData(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..de46c08
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:isolate';
+
+main() {}
+var subscription;
+void onData(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline.expect
new file mode 100644
index 0000000..9b82bc0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b82bc0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
new file mode 100644
index 0000000..e4af729
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+  @Double()
+  double x;
+  @Double()
+  double y;
+  Pointer<Coordinate> next;
+  factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e4af729
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+  @Double()
+  double x;
+  @Double()
+  double y;
+  Pointer<Coordinate> next;
+  factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline.expect
new file mode 100644
index 0000000..5e1c191
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5e1c191
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.strong.transformed.expect
index cb9a540..ae6b6e7 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.strong.transformed.expect
@@ -1,11 +1,10 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method main(core::List<core::String*>* arguments) → dynamic {
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(arguments).{core::Iterable::iterator};
+    core::Iterator<core::String*>* :sync-for-iterator = arguments.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String* arguments = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..b6ad80a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b6ad80a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.weak.transformed.expect
index cb9a540..ae6b6e7 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.weak.transformed.expect
@@ -1,11 +1,10 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method main(core::List<core::String*>* arguments) → dynamic {
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(arguments).{core::Iterable::iterator};
+    core::Iterator<core::String*>* :sync-for-iterator = arguments.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String* arguments = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect
index 220fbaa..99eaa37 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect
@@ -66,7 +66,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Super extends core::Object {
   field core::int* superInstanceField = null;
@@ -87,7 +86,7 @@
     core::String* local;
     dynamic untypedLocal;
     {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String*>[]).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = <core::String*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t1 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -96,7 +95,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -105,7 +104,7 @@
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t3 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -114,7 +113,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -123,7 +122,7 @@
       }
     }
     {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(<core::double*>[]).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = <core::double*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::double* #t5 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -132,7 +131,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -141,7 +140,7 @@
       }
     }
     {
-      core::Iterator<core::bool*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::bool*>*>(<core::bool*>[]).{core::Iterable::iterator};
+      core::Iterator<core::bool*>* :sync-for-iterator = <core::bool*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::bool* #t7 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -150,7 +149,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -159,7 +158,7 @@
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t9 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -168,7 +167,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -178,7 +177,7 @@
     }
     self::C* c = new self::C::•();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -187,7 +186,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -196,7 +195,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t13 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -209,7 +208,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -222,7 +221,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t15 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -239,7 +238,7 @@
     for (main() in []) {}
          ^^^^";
       {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -256,7 +255,7 @@
     for (var x, y in <int>[]) {
          ^^^";
       {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t17 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -272,7 +271,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..9808898
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+bool topLevelField;
+var untypedTopLevelField;
+
+class Super {
+  int superInstanceField;
+  var untypedSuperInstanceField;
+}
+
+class C extends Super {
+  int instanceField;
+  var untypedInstanceField;
+  static double staticField;
+  static var untypedStaticField;
+  m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b2d0b2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+bool topLevelField;
+
+class C extends Super {
+  int instanceField;
+  m() {}
+  static double staticField;
+  static var untypedStaticField;
+  var untypedInstanceField;
+}
+
+class Super {
+  int superInstanceField;
+  var untypedSuperInstanceField;
+}
+
+main() {}
+var untypedTopLevelField;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect
index 220fbaa..99eaa37 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect
@@ -66,7 +66,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Super extends core::Object {
   field core::int* superInstanceField = null;
@@ -87,7 +86,7 @@
     core::String* local;
     dynamic untypedLocal;
     {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String*>[]).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = <core::String*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t1 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -96,7 +95,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -105,7 +104,7 @@
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t3 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -114,7 +113,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -123,7 +122,7 @@
       }
     }
     {
-      core::Iterator<core::double*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::double*>*>(<core::double*>[]).{core::Iterable::iterator};
+      core::Iterator<core::double*>* :sync-for-iterator = <core::double*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::double* #t5 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -132,7 +131,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -141,7 +140,7 @@
       }
     }
     {
-      core::Iterator<core::bool*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::bool*>*>(<core::bool*>[]).{core::Iterable::iterator};
+      core::Iterator<core::bool*>* :sync-for-iterator = <core::bool*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::bool* #t7 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -150,7 +149,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -159,7 +158,7 @@
       }
     }
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t9 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -168,7 +167,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -178,7 +177,7 @@
     }
     self::C* c = new self::C::•();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -187,7 +186,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -196,7 +195,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t13 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -209,7 +208,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -222,7 +221,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t15 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -239,7 +238,7 @@
     for (main() in []) {}
          ^^^^";
       {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -256,7 +255,7 @@
     for (var x, y in <int>[]) {
          ^^^";
       {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::int* #t17 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -272,7 +271,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..797b2be
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+class A {
+  dynamic operator +(covariant int a) => null;
+}
+
+class B {
+  dynamic operator +(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+class D {
+  dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+  dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d028dc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+abstract class C implements A, B {}
+
+class A {
+  dynamic operator +(covariant int a) => null;
+}
+
+class B {
+  dynamic operator +(dynamic b) => null;
+}
+
+class D {
+  dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+  dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..cf6cafe
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+var x = () {
+  var y = 42;
+  return y;
+};
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..186e9b4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+main() {}
+var x = () {
+  var y = 42;
+  return y;
+};
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline.expect
new file mode 100644
index 0000000..008e4b9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+T identity<T>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+String x = identity;
+String y = identityObject;
+String z = identityList;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b27eac3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+String x = identity;
+String y = identityObject;
+String z = identityList;
+T identity<T>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_default_value.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_default_value.dart.textual_outline.expect
new file mode 100644
index 0000000..6650610
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_default_value.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void Function({obj: Object}) x;
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..eade016
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import "package:expect/expect.dart" show Expect;
+
+test(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..207b09a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import "package:expect/expect.dart" show Expect;
+
+main() {}
+test(f) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline.expect
new file mode 100644
index 0000000..569b9be
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+typedef F = int Function(int f(String x));
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95953c9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+typedef F = int Function(int f(String x));
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.strong.transformed.expect
index 1d1c466..206c905 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.strong.transformed.expect
@@ -21,8 +21,8 @@
     final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -35,13 +35,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -54,8 +54,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,13 +68,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline.expect
new file mode 100644
index 0000000..7123fde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+import 'dart:async';
+
+class A {
+  dynamic foo() => null;
+}
+
+class B {
+  A a;
+  Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+  B b = B();
+  Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7123fde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+import 'dart:async';
+
+class A {
+  dynamic foo() => null;
+}
+
+class B {
+  A a;
+  Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+  B b = B();
+  Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
index 1d1c466..206c905 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
@@ -21,8 +21,8 @@
     final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -35,13 +35,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -54,8 +54,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,13 +68,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline.expect
new file mode 100644
index 0000000..c120177
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a09c841
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+main() {}
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..2e43bfb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c66d6f8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..48738fd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..485fed8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..d00fcfd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class Class {
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d00fcfd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class Class {
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline.expect
new file mode 100644
index 0000000..d0ad2e6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+import "dart:core" as core;
+
+class A implements core.Function {
+  operator ==(other) => false;
+}
+
+class B implements Function {
+  operator ==(other) => false;
+}
+
+class Function {
+  core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0ad2e6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+import "dart:core" as core;
+
+class A implements core.Function {
+  operator ==(other) => false;
+}
+
+class B implements Function {
+  operator ==(other) => false;
+}
+
+class Function {
+  core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..c31ef38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+const constTopLevelField = 42;
+
+class C {
+  const C(x);
+  static const constField = 87;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a51783
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+  const C(x);
+  static const constField = 87;
+}
+
+const constTopLevelField = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline.expect
new file mode 100644
index 0000000..7b7c2fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+import "implicit_new.dart" as prefix;
+
+class Foo {
+  operator +(other) => null;
+}
+
+class Bar {
+  Bar.named();
+  operator +(other) => null;
+}
+
+testNSM() {}
+f(x) => x;
+
+class IndexTester {
+  operator [](_) => null;
+  void operator []=(_a, _b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1ae95e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+import "implicit_new.dart" as prefix;
+
+class Bar {
+  Bar.named();
+  operator +(other) => null;
+}
+
+class Foo {
+  operator +(other) => null;
+}
+
+class IndexTester {
+  operator [](_) => null;
+  void operator []=(_a, _b) {}
+}
+
+f(x) => x;
+main() {}
+testNSM() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline.expect
new file mode 100644
index 0000000..ea15953
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+  static bool alwaysTrue() {}
+  static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea15953
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+  static bool alwaysTrue() {}
+  static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..7971f11
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+  m() {}
+  testC() {}
+}
+
+class D extends C {
+  testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7971f11
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+  m() {}
+  testC() {}
+}
+
+class D extends C {
+  testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline.expect
new file mode 100644
index 0000000..a245e33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d91e80
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..ac0d854
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..592f7b0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline.expect
new file mode 100644
index 0000000..79e6e92
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71e6b48
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline.expect
new file mode 100644
index 0000000..287c61f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..48302b2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/incomplete_field_formal_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/incomplete_field_formal_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..23e89ac
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/incomplete_field_formal_parameter.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+  C.a(this.);
+  C.b(this.);
+  C.c(this., p);
+  C.d(this., p);
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..121eb31
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+  T f(int x) {}
+}
+
+abstract class I<T> {
+  T f(Object x);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c05413
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+  T f(Object x);
+}
+
+class B<T> {
+  T f(int x) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..5525e8f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+  void f(F<T> x, int y) {}
+}
+
+abstract class I<T> {
+  void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b877341
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+  void f(F<T> x, Object y);
+}
+
+class B<T> {
+  void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..6d9f5e3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+library test;
+
+typedef void F<T>(T t);
+
+abstract class A<T> {
+  void f(T x, int y);
+}
+
+class B<T> implements A<F<T>> {
+  void f(F<T> x, int y) {}
+}
+
+abstract class I<T> implements A<F<T>> {
+  void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff9bcce
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+library test;
+
+abstract class A<T> {
+  void f(T x, int y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> implements A<F<T>> {
+  void f(F<T> x, Object y);
+}
+
+class B<T> implements A<F<T>> {
+  void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..d8b263a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+  String operator +(int i) => '';
+}
+
+test(int i, String s, A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f55ddde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+  String operator +(int i) => '';
+}
+
+main() {}
+test(int i, String s, A a) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline.expect
new file mode 100644
index 0000000..44ec294
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class C {
+  C();
+  factory C.fact() => null;
+  factory C.fact2() = D;
+  C.nonFact();
+  C.nonFact2() : this.nonFact();
+  static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+void topLevelFunction(int i) {}
+bad() {}
+ok() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1bc0c5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+bad() {}
+
+class C {
+  C();
+  C.nonFact();
+  C.nonFact2() : this.nonFact();
+  factory C.fact() => null;
+  factory C.fact2() = D;
+  static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+main() {}
+ok() {}
+void topLevelFunction(int i) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline.expect
new file mode 100644
index 0000000..48caf67
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+  static foo() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..499c0b6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+  static foo() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline.expect
new file mode 100644
index 0000000..5f82a89
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline.expect
@@ -0,0 +1,56 @@
+// @dart = 2.6
+abstract class A {}
+
+abstract class B {
+  void foo(num x);
+}
+
+abstract class C implements B {
+  void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+  void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+  void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+  void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+  void foo(num x);
+}
+
+abstract class E {
+  void set foo(num x);
+}
+
+abstract class G implements E {
+  void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+  void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+  void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+  void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+  void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5031f69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline_modelled.expect
@@ -0,0 +1,56 @@
+// @dart = 2.6
+abstract class A {}
+
+abstract class B {
+  void foo(num x);
+}
+
+abstract class C implements B {
+  void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+  void foo(covariant int x);
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+  void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+  void foo(num x);
+}
+
+abstract class E {
+  void set foo(num x);
+}
+
+abstract class G implements E {
+  void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+  void set foo(covariant int x);
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+  void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+  void set foo(num x);
+}
+
+class D2 implements A, C, B {
+  void foo(covariant int x) {}
+}
+
+class H2 implements A, E, G {
+  void set foo(covariant int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline.expect
new file mode 100644
index 0000000..148d7dd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2357783
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline.expect
new file mode 100644
index 0000000..45604e7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class Foo<T> {
+  final Future<dynamic> Function() quux;
+  T t;
+  Foo(this.quux, this.t);
+  Future<T> call() => quux().then<T>((_) => t);
+}
+
+class Bar {
+  Foo<Baz> qux;
+  Future<void> quuz() =>
+      qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+  Grault corge(Baz baz) => null;
+  void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..67e1bed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class Bar {
+  Foo<Baz> qux;
+  Future<void> quuz() =>
+      qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+  Grault corge(Baz baz) => null;
+  void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Foo<T> {
+  Foo(this.quux, this.t);
+  Future<T> call() => quux().then<T>((_) => t);
+  T t;
+  final Future<dynamic> Function() quux;
+}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline.expect
new file mode 100644
index 0000000..1db249f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+  int a;
+  A(int a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1369a93
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+  A(int a) {}
+  int a;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.strong.transformed.expect
index 606d3a0..342575d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.strong.transformed.expect
@@ -2,7 +2,6 @@
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
-import "dart:_internal" as _in;
 
 class C extends core::Object {
   final field core::Set<core::int*>* s;
@@ -10,7 +9,7 @@
     : self::C::s = block {
       final core::Set<core::int*>* #t1 = col::LinkedHashSet::•<core::int*>();
       {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(ell).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = ell.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           core::int* e = :sync-for-iterator.{core::Iterator::current};
           if(e.{core::int::isOdd})
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline.expect
new file mode 100644
index 0000000..be597eb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+  final Set<int> s;
+  C(List<int> ell)
+      : s = {
+          for (var e in ell)
+            if (e.isOdd) 2 * e
+        };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d3c4d06
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+  C(List<int> ell)
+      : s = {
+          for (var e in ell)
+            if (e.isOdd) 2 * e
+        };
+  final Set<int> s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.weak.transformed.expect
index 606d3a0..342575d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.weak.transformed.expect
@@ -2,7 +2,6 @@
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
-import "dart:_internal" as _in;
 
 class C extends core::Object {
   final field core::Set<core::int*>* s;
@@ -10,7 +9,7 @@
     : self::C::s = block {
       final core::Set<core::int*>* #t1 = col::LinkedHashSet::•<core::int*>();
       {
-        core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(ell).{core::Iterable::iterator};
+        core::Iterator<core::int*>* :sync-for-iterator = ell.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           core::int* e = :sync-for-iterator.{core::Iterator::current};
           if(e.{core::int::isOdd})
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline.expect
new file mode 100644
index 0000000..6761b51
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {
+  R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6761b51
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {
+  R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline.expect
new file mode 100644
index 0000000..a6efc6f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class X {
+  const X.foo();
+}
+
+class X {
+  const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a6efc6f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class X {
+  const X.foo();
+}
+
+class X {
+  const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline.expect
new file mode 100644
index 0000000..bc1d3b5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+typedef G<X> = void Function();
+
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3a99d60
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
+typedef G<X> = void Function();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline.expect
new file mode 100644
index 0000000..82a3e53
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+  int v;
+  int v;
+  A(this.v);
+  A.second();
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f239ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+  A(this.v);
+  A.second();
+  int v;
+  int v;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline.expect
new file mode 100644
index 0000000..84dc47f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class D<X extends void Function()> {
+  factory D.foo() => new D._();
+  D._() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a160055
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class D<X extends void Function()> {
+  D._() {}
+  factory D.foo() => new D._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline.expect
new file mode 100644
index 0000000..3b0969c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b0969c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline.expect
new file mode 100644
index 0000000..41ad065
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C {
+  dynamic x = this;
+  var x = this;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..41ad065
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C {
+  dynamic x = this;
+  var x = this;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline.expect
new file mode 100644
index 0000000..9226278
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+List<B> xs;
+List<List<B>> xss;
+
+class Class<T extends A> {
+  void method1a(T t) {}
+  void method1b(T t) {}
+  void method2a(T t) {}
+  void method2b(T t) {}
+}
+
+void main() {}
+void errors() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ba257d0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+List<B> xs;
+List<List<B>> xss;
+
+class A {}
+
+class B extends A {}
+
+class Class<T extends A> {
+  void method1a(T t) {}
+  void method1b(T t) {}
+  void method2a(T t) {}
+  void method2b(T t) {}
+}
+
+void errors() {}
+void main() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.outline.expect
index 26f9451..4a7ea21 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.outline.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.outline.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:14:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.expect
index af49ff8..687b222 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:14:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 // pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:12: Error: Can't use 'A' because it is declared more than once.
 //   foo(List<A> a) {}
 //            ^
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.transformed.expect
index af49ff8..687b222 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.strong.transformed.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:14:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 // pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:12: Error: Can't use 'A' because it is declared more than once.
 //   foo(List<A> a) {}
 //            ^
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline.expect
new file mode 100644
index 0000000..b597c8a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {}
+
+class A {}
+
+class B {
+  foo(List<Null> a) {}
+}
+
+class C extends B {
+  foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b597c8a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {}
+
+class A {}
+
+class B {
+  foo(List<Null> a) {}
+}
+
+class C extends B {
+  foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.expect
index af49ff8..687b222 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:14:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 // pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:12: Error: Can't use 'A' because it is declared more than once.
 //   foo(List<A> a) {}
 //            ^
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.transformed.expect
index af49ff8..687b222 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.weak.transformed.expect
@@ -16,15 +16,6 @@
 //   foo(List<A> a) {}
 //            ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:15: Error: The parameter 'a' of the method 'C.foo' has type 'List<invalid-type>', which does not match the corresponding type, 'List<Null>', in the overridden method, 'B.foo'.
-//  - 'List' is from 'dart:core'.
-// Change to a supertype of 'List<Null>', or, for a covariant parameter, a subtype.
-//   foo(List<A> a) {}
-//               ^
-// pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:14:3: Context: This is the overridden method ('foo').
-//   foo(List<Null> a) {}
-//   ^
-//
 // pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart:18:12: Error: Can't use 'A' because it is declared more than once.
 //   foo(List<A> a) {}
 //            ^
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.strong.transformed.expect
index 896e8eb..da4a799 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.strong.transformed.expect
@@ -1,12 +1,11 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method foo() → dynamic {
   core::Null? _null;
   {
-    core::Iterator<core::Null?>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Null?>*>(_null).{core::Iterable::iterator};
+    core::Iterator<core::Null?>* :sync-for-iterator = _null.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic i = :sync-for-iterator.{core::Iterator::current};
       {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline.expect
new file mode 100644
index 0000000..41dbdca
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..41dbdca
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.weak.transformed.expect
index 896e8eb..da4a799 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.weak.transformed.expect
@@ -1,12 +1,11 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method foo() → dynamic {
   core::Null? _null;
   {
-    core::Iterator<core::Null?>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Null?>*>(_null).{core::Iterable::iterator};
+    core::Iterator<core::Null?>* :sync-for-iterator = _null.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic i = :sync-for-iterator.{core::Iterator::current};
       {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline.expect
new file mode 100644
index 0000000..4ac4f62
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+testString() {}
+testInt() {}
+testBool() {}
+testDouble() {}
+testNull() {}
+testList() {}
+testMap() {}
+testSymbol() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae913a9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+main() {}
+testBool() {}
+testDouble() {}
+testInt() {}
+testList() {}
+testMap() {}
+testNull() {}
+testString() {}
+testSymbol() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline.expect
new file mode 100644
index 0000000..0c87ff5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..62fc26e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+main() {}
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline.expect
new file mode 100644
index 0000000..ee3bb292
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Constant {
+  const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7c029de
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Constant {
+  const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/many_errors.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/many_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..32bba3e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/many_errors.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+  final x = null;
+  const A.named1() sync* { }
+  const A.named2() : x = new Object();
+}
+external foo(String x) { }
+class B {
+}
+class C {
+  B b;
+}
+abstract class AbstractClass {
+  const AbstractClass.id();
+}
+m() { }
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline.expect
new file mode 100644
index 0000000..0bccd4a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+const a = null;
+@a
+enum E { E1, E2, E3 }
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..591a2e5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+@a
+enum E { E1, E2, E3 }
+const a = null;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..73fde59
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+const a = null;
+@a
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02cfd25
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+@a
+const a = null;
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline.expect
new file mode 100644
index 0000000..cb155f6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+// @dart = 2.6
+staticMethod() {}
+
+class Foo {
+  instanceMethod() {}
+}
+
+external bool externalStatic();
+
+abstract class ExternalValue {}
+
+abstract class Bar {
+  ExternalValue externalInstanceMethod();
+}
+
+external Bar createBar();
+
+class Box {
+  var field;
+}
+
+stringArgument(x) {}
+intArgument(x) {}
+
+class FinalBox {
+  final finalField;
+  FinalBox(this.finalField);
+}
+
+class SubFinalBox extends FinalBox {
+  SubFinalBox(value) : super(value);
+}
+
+class DynamicReceiver1 {
+  dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+  dynamicallyCalled(x) {}
+}
+
+void makeDynamicCall(receiver) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a927605
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline_modelled.expect
@@ -0,0 +1,39 @@
+// @dart = 2.6
+abstract class Bar {
+  ExternalValue externalInstanceMethod();
+}
+
+abstract class ExternalValue {}
+
+class Box {
+  var field;
+}
+
+class DynamicReceiver1 {
+  dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+  dynamicallyCalled(x) {}
+}
+
+class FinalBox {
+  FinalBox(this.finalField);
+  final finalField;
+}
+
+class Foo {
+  instanceMethod() {}
+}
+
+class SubFinalBox extends FinalBox {
+  SubFinalBox(value) : super(value);
+}
+
+external Bar createBar();
+external bool externalStatic();
+intArgument(x) {}
+main() {}
+staticMethod() {}
+stringArgument(x) {}
+void makeDynamicCall(receiver) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..f2b9597
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+class Super {
+  Super._();
+}
+
+class Sub extends Super {
+  Sub() : super();
+  Sub.foo() : super.foo();
+}
+
+class Bad {
+  Bad.foo() : this();
+  Bad.bar() : this.baz();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+  MixinApplication() : super();
+  MixinApplication.foo() : super.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..06f8c69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+class Bad {
+  Bad.bar() : this.baz();
+  Bad.foo() : this();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+  MixinApplication() : super();
+  MixinApplication.foo() : super.foo();
+}
+
+class Sub extends Super {
+  Sub() : super();
+  Sub.foo() : super.foo();
+}
+
+class Super {
+  Super._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..c8b0fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+// @dart = 2.6
+class EmptyClass {}
+
+var emptyClass = new EmptyClass();
+
+class ClassWithProperty {
+  EmptyClass property;
+}
+
+var classWithProperty = new ClassWithProperty();
+
+class ClassWithIndexSet {
+  operator []=(int index, int value) {}
+}
+
+var classWithIndexSet = new ClassWithIndexSet();
+
+class ClassWithIndexGet {
+  int operator [](int index) => 42;
+}
+
+var classWithIndexGet = new ClassWithIndexGet();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16d597a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class ClassWithIndexGet {
+  int operator [](int index) => 42;
+}
+
+class ClassWithIndexSet {
+  operator []=(int index, int value) {}
+}
+
+class ClassWithProperty {
+  EmptyClass property;
+}
+
+class EmptyClass {}
+
+main() {}
+var classWithIndexGet = new ClassWithIndexGet();
+var classWithIndexSet = new ClassWithIndexSet();
+var classWithProperty = new ClassWithProperty();
+var emptyClass = new EmptyClass();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..f50acc7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class B extends Object with M1, M2 {
+  B(value);
+}
+
+abstract class M1 {
+  m() => print("M1");
+}
+
+abstract class M2 {
+  m() => print("M2");
+}
+
+class C extends Object with M1, M2 {
+  C(value);
+}
+
+abstract class G1<T> {
+  m() => print(T);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..efc6453
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+abstract class G1<T> {
+  m() => print(T);
+}
+
+abstract class M1 {
+  m() => print("M1");
+}
+
+abstract class M2 {
+  m() => print("M2");
+}
+
+class B extends Object with M1, M2 {
+  B(value);
+}
+
+class C extends Object with M1, M2 {
+  C(value);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline.expect
new file mode 100644
index 0000000..977b29e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Mixin {}
+
+class Super {
+  var field = 42;
+  Super(this.field);
+}
+
+class Class = Super with Mixin;
+main() {}
+error() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bfdb845
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Mixin {}
+
+class Super {
+  Super(this.field);
+  var field = 42;
+}
+
+class Class = Super with Mixin;
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline.expect
new file mode 100644
index 0000000..ad2f273
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+class S {
+  foo([x]) {}
+}
+
+class M {
+  foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B1 extends S with M1, M {}
+
+class B2 extends S with M1, M2, M {}
+
+class B0X extends S with M, MX {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed18e1c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+class M {
+  foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class S {
+  foo([x]) {}
+}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B0X extends S with M, MX {}
+
+class B1 extends S with M1, M {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2 extends S with M1, M2, M {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline.expect
new file mode 100644
index 0000000..65b69bb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class M {
+  foo() {}
+}
+
+class N = Object with M;
+
+class C extends Object with N {}
+
+abstract class M2 implements M {
+  bar() {}
+}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+class C2 extends Object with M2 {}
+
+abstract class C3 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d6b9fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class M {
+  foo() {}
+}
+
+class N = Object with M;
+
+abstract class M2 implements M {
+  bar() {}
+}
+
+class C extends Object with N {}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+abstract class C3 extends Object with M2 {}
+
+class C2 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..e5cb16d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class C<T> {
+  String trace;
+  C({a: 0, b: T}) : trace = "a: $a, b: $b";
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd7c911
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class C<T> {
+  C({a: 0, b: T}) : trace = "a: $a, b: $b";
+  String trace;
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..5c4acda
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {}
+
+class C<T extends A> {
+  T _field;
+  foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c765f3a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C<T extends A> {
+  T _field;
+  foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline.expect
new file mode 100644
index 0000000..0a4bcf8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+abstract class M {
+  var m;
+}
+
+abstract class N extends M {
+  void set superM(value) {}
+  get superM => super.m;
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e41069c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+abstract class M {
+  var m;
+}
+
+abstract class N extends M {
+  get superM => super.m;
+  void set superM(value) {}
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline.expect
new file mode 100644
index 0000000..8cbf995
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A extends B with M {}
+
+class B {
+  final Object m = null;
+}
+
+class M {
+  static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cbf995
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A extends B with M {}
+
+class B {
+  final Object m = null;
+}
+
+class M {
+  static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..2cdd1a7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2cdd1a7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..c269fb4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Superclass {
+  foo({alpha, beta}) {}
+  bar({beta, alpha}) {}
+  namedCallback(callback({String alpha, int beta})) {}
+}
+
+class Subclass extends Superclass {
+  foo({beta, alpha}) {}
+  bar({alpha, beta}) {}
+  namedCallback(callback({int beta, String alpha})) {}
+}
+
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07b9e96
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Subclass extends Superclass {
+  bar({alpha, beta}) {}
+  foo({beta, alpha}) {}
+  namedCallback(callback({int beta, String alpha})) {}
+}
+
+class Superclass {
+  bar({beta, alpha}) {}
+  foo({alpha, beta}) {}
+  namedCallback(callback({String alpha, int beta})) {}
+}
+
+main() {}
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline.expect
new file mode 100644
index 0000000..f9ea52b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+main() {}
+
+class W {
+  String native;
+  W() : native = "field";
+}
+
+class X {
+  String native() => "method";
+}
+
+abstract class Y1 {
+  String get native;
+}
+
+class Y2 extends Y1 {
+  @override
+  String get native => "getter";
+}
+
+class Z {
+  set native(String s) => f = s;
+  String f;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dea0ab9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+abstract class Y1 {
+  String get native;
+}
+
+class W {
+  String native;
+  W() : native = "field";
+}
+
+class X {
+  String native() => "method";
+}
+
+class Y2 extends Y1 {
+  @override
+  String get native => "getter";
+}
+
+class Z {
+  String f;
+  set native(String s) => f = s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline.expect
new file mode 100644
index 0000000..f881723
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+const int foo = const int.fromEnvironment("fisk");
+
+class A {
+  final int bar;
+  const A(this.bar);
+}
+
+class B {
+  final A baz;
+  const B(this.baz);
+}
+
+class C {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f951d0e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+  const A(this.bar);
+  final int bar;
+}
+
+class B {
+  const B(this.baz);
+  final A baz;
+}
+
+class C {
+  fun() {}
+}
+
+const int foo = const int.fromEnvironment("fisk");
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline.expect
new file mode 100644
index 0000000..7feca64
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class NumField {
+  num field;
+}
+
+class IntField {
+  int field;
+}
+
+class DoubleField {
+  double field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6053fe8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class DoubleField {
+  double field;
+}
+
+class IntField {
+  int field;
+}
+
+class NumField {
+  num field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline.expect
new file mode 100644
index 0000000..f6f8d28
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline.expect
@@ -0,0 +1,53 @@
+// @dart = 2.6
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+void testTypeAliasAsTypeArgument() {}
+void testNested() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..402b4d5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline_modelled.expect
@@ -0,0 +1,50 @@
+// @dart = 2.6
+F<X> toF<X>(X x) => null;
+
+class A<X> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+main() {}
+typedef F<X> = void Function<Y extends X>();
+typedef Fcon<X> = Function(X);
+typedef FconBound<X extends num> = Function(X);
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef Fcov<X> = X Function();
+typedef FcovBound<X extends num> = X Function();
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef Finv<X> = X Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+void testNested() {}
+void testTypeAliasAsTypeArgument() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..65d942d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65d942d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..4184ffb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline.expect
@@ -0,0 +1,80 @@
+// @dart = 2.6
+class C<T> {
+  C(this.field1)
+      : field2 = (() => field1),
+        field3 = ((T t) {}),
+        field4 = ((T t) => t),
+        field5 = (() => () => field1),
+        field6 = ((T Function() f) {}),
+        field7 = ((T Function() f) => field1),
+        field8 = ((void Function(T) f) {}),
+        field9 = ((void Function(T) f) => field1),
+        field10 = ((T Function(T) f) {}),
+        field11 = ((T Function(T) f) => field1),
+        field12 = <S extends T>() => null,
+        field13 = <S extends T>(S s) {},
+        field14 = <S extends T>(S s) => s,
+        field15 = ((S Function<S extends T>() f) {});
+  T field1;
+  T Function() field2;
+  void Function(T) field3;
+  T Function(T) field4;
+  T Function() Function() field5;
+  void Function(T Function()) field6;
+  T Function(T Function()) field7;
+  void Function(void Function(T)) field8;
+  T Function(void Function(T)) field9;
+  void Function(T Function(T)) field10;
+  T Function(T Function(T)) field11;
+  S Function<S extends T>() field12;
+  void Function<S extends T>(S) field13;
+  S Function<S extends T>(S) field14;
+  void Function(S Function<S extends T>()) field15;
+  T get getter1 => field1;
+  T Function() get getter2 => field2;
+  void Function(T) get getter3 => field3;
+  T Function(T) get getter4 => field4;
+  T Function() Function() get getter5 => field5;
+  void Function(T Function()) get getter6 => field6;
+  T Function(T Function()) get getter7 => field7;
+  void Function(void Function(T)) get getter8 => field8;
+  T Function(void Function(T)) get getter9 => field9;
+  void Function(T Function(T)) get getter10 => field10;
+  T Function(T Function(T)) get getter11 => field11;
+  S Function<S extends T>() get getter12 => field12;
+  void Function<S extends T>(S) get getter13 => field13;
+  S Function<S extends T>(S) get getter14 => field14;
+  void Function(S Function<S extends T>()) get getter15 => field15;
+  void set setter1(T value) {}
+  void set setter2(T Function() value) {}
+  void set setter3(void Function(T) value) {}
+  void set setter4(T Function(T) value) {}
+  void set setter5(T Function() Function() value) {}
+  void set setter6(void Function(T Function()) value) {}
+  void set setter7(T Function(T Function()) value) {}
+  void set setter8(void Function(void Function(T)) value) {}
+  void set setter9(T Function(void Function(T)) value) {}
+  void set setter10(void Function(T Function(T)) value) {}
+  void set setter11(T Function(T Function(T)) value) {}
+  void set setter12(S Function<S extends T>() value) {}
+  void set setter13(void Function<S extends T>(S) value) {}
+  void set setter14(S Function<S extends T>(S) value) {}
+  void set setter15(void Function(S Function<S extends T>()) value) {}
+  void method1(T value) {}
+  void method2(T Function() value) {}
+  void method3(void Function(T) value) {}
+  void method4(T Function(T) value) {}
+  void method5(T Function() Function() value) {}
+  void method6(void Function(T Function()) value) {}
+  void method7(T Function(T Function()) value) {}
+  void method8(void Function(void Function(T)) value) {}
+  void method9(T Function(void Function(T)) value) {}
+  void method10(void Function(T Function(T)) value) {}
+  void method11(T Function(T Function(T)) value) {}
+  void method12(S Function<S extends T>() value) {}
+  void method13(void Function<S extends T>(S) value) {}
+  void method14(S Function<S extends T>(S) value) {}
+  void method15(void Function(S Function<S extends T>()) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6969145
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,80 @@
+// @dart = 2.6
+class C<T> {
+  C(this.field1)
+      : field2 = (() => field1),
+        field3 = ((T t) {}),
+        field4 = ((T t) => t),
+        field5 = (() => () => field1),
+        field6 = ((T Function() f) {}),
+        field7 = ((T Function() f) => field1),
+        field8 = ((void Function(T) f) {}),
+        field9 = ((void Function(T) f) => field1),
+        field10 = ((T Function(T) f) {}),
+        field11 = ((T Function(T) f) => field1),
+        field12 = <S extends T>() => null,
+        field13 = <S extends T>(S s) {},
+        field14 = <S extends T>(S s) => s,
+        field15 = ((S Function<S extends T>() f) {});
+  S Function<S extends T>() field12;
+  S Function<S extends T>() get getter12 => field12;
+  S Function<S extends T>(S) field14;
+  S Function<S extends T>(S) get getter14 => field14;
+  T Function(T Function()) field7;
+  T Function(T Function()) get getter7 => field7;
+  T Function(T Function(T)) field11;
+  T Function(T Function(T)) get getter11 => field11;
+  T Function(T) field4;
+  T Function(T) get getter4 => field4;
+  T Function() Function() field5;
+  T Function() Function() get getter5 => field5;
+  T Function() field2;
+  T Function() get getter2 => field2;
+  T Function(void Function(T)) field9;
+  T Function(void Function(T)) get getter9 => field9;
+  T field1;
+  T get getter1 => field1;
+  void Function(T Function()) field6;
+  void Function(T Function()) get getter6 => field6;
+  void Function(T Function(T)) field10;
+  void Function(T Function(T)) get getter10 => field10;
+  void Function(T) field3;
+  void Function(T) get getter3 => field3;
+  void Function(S Function<S extends T>()) field15;
+  void Function(S Function<S extends T>()) get getter15 => field15;
+  void Function(void Function(T)) field8;
+  void Function(void Function(T)) get getter8 => field8;
+  void Function<S extends T>(S) field13;
+  void Function<S extends T>(S) get getter13 => field13;
+  void method1(T value) {}
+  void method10(void Function(T Function(T)) value) {}
+  void method11(T Function(T Function(T)) value) {}
+  void method12(S Function<S extends T>() value) {}
+  void method13(void Function<S extends T>(S) value) {}
+  void method14(S Function<S extends T>(S) value) {}
+  void method15(void Function(S Function<S extends T>()) value) {}
+  void method2(T Function() value) {}
+  void method3(void Function(T) value) {}
+  void method4(T Function(T) value) {}
+  void method5(T Function() Function() value) {}
+  void method6(void Function(T Function()) value) {}
+  void method7(T Function(T Function()) value) {}
+  void method8(void Function(void Function(T)) value) {}
+  void method9(T Function(void Function(T)) value) {}
+  void set setter1(T value) {}
+  void set setter10(void Function(T Function(T)) value) {}
+  void set setter11(T Function(T Function(T)) value) {}
+  void set setter12(S Function<S extends T>() value) {}
+  void set setter13(void Function<S extends T>(S) value) {}
+  void set setter14(S Function<S extends T>(S) value) {}
+  void set setter15(void Function(S Function<S extends T>()) value) {}
+  void set setter2(T Function() value) {}
+  void set setter3(void Function(T) value) {}
+  void set setter4(T Function(T) value) {}
+  void set setter5(T Function() Function() value) {}
+  void set setter6(void Function(T Function()) value) {}
+  void set setter7(T Function(T Function()) value) {}
+  void set setter8(void Function(void Function(T)) value) {}
+  void set setter9(T Function(void Function(T)) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..bafe8cc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Foo {
+  int field;
+  static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bafe8cc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Foo {
+  int field;
+  static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.strong.transformed.expect
index eb4e616..10d831b 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Class extends core::Object {
   synthetic constructor •() → self::Class*
@@ -12,7 +11,7 @@
   dynamic o;
   if(false) {
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((let final dynamic #t1 = o in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.iterable) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((let final dynamic #t1 = o in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.iterable) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline.expect
new file mode 100644
index 0000000..43e0a72
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43e0a72
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.weak.transformed.expect
index eb4e616..10d831b 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.weak.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Class extends core::Object {
   synthetic constructor •() → self::Class*
@@ -12,7 +11,7 @@
   dynamic o;
   if(false) {
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((let final dynamic #t1 = o in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.iterable) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((let final dynamic #t1 = o in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.iterable) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline.expect
new file mode 100644
index 0000000..7fa7e53
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+  B b;
+}
+
+class B {
+  C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7fa7e53
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+  B b;
+}
+
+class B {
+  C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.strong.transformed.expect
index e746568..c75c586 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
@@ -10,7 +9,7 @@
     #t1.{core::List::add}("foo");
     final core::Iterable<core::String*>* #t2 = list;
     if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t2).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t3 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t3);
@@ -24,7 +23,7 @@
     #t4.{core::Set::add}("foo");
     final core::Iterable<core::String*>* #t5 = set;
     if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t5).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = #t5.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t4.{core::Set::add}(#t6);
@@ -38,7 +37,7 @@
     #t7.{core::Map::[]=}(0, "foo");
     final core::Map<core::int*, core::String*>* #t8 = map;
     if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::String*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::String*>*>*>(#t8.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::String*>*>* :sync-for-iterator = #t8.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::String*>* #t9 = :sync-for-iterator.{core::Iterator::current};
         #t7.{core::Map::[]=}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline.expect
new file mode 100644
index 0000000..5e023d7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+nullAwareListSpread(List<String> list) {}
+nullAwareSetSpread(Set<String> set) {}
+nullAwareMapSpread(Map<int, String> map) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..20bd984
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+main() {}
+nullAwareListSpread(List<String> list) {}
+nullAwareMapSpread(Map<int, String> map) {}
+nullAwareSetSpread(Set<String> set) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect
index e746568..c75c586 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
@@ -10,7 +9,7 @@
     #t1.{core::List::add}("foo");
     final core::Iterable<core::String*>* #t2 = list;
     if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t2).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t3 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t3);
@@ -24,7 +23,7 @@
     #t4.{core::Set::add}("foo");
     final core::Iterable<core::String*>* #t5 = set;
     if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t5).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = #t5.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t4.{core::Set::add}(#t6);
@@ -38,7 +37,7 @@
     #t7.{core::Map::[]=}(0, "foo");
     final core::Map<core::int*, core::String*>* #t8 = map;
     if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::String*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::String*>*>*>(#t8.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::String*>*>* :sync-for-iterator = #t8.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::String*>* #t9 = :sync-for-iterator.{core::Iterator::current};
         #t7.{core::Map::[]=}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline.expect
new file mode 100644
index 0000000..1a0868f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a0868f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline.expect
new file mode 100644
index 0000000..481687e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Operators {
+  operator +(other) => null;
+  operator &(other) => null;
+  operator ~() => null;
+  operator |(other) => null;
+  operator ^(other) => null;
+  operator /(other) => null;
+  operator ==(other) => null;
+  operator >(other) => null;
+  operator >=(other) => null;
+  operator [](index) => null;
+  void operator []=(index, value) {}
+  operator <<(other) => null;
+  operator <(other) => null;
+  operator <=(other) => null;
+  operator *(other) => null;
+  operator %(other) => null;
+  operator >>(other) => null;
+  operator -(other) => null;
+  operator ~/(other) => null;
+  operator -() => null;
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..078d711
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Operators {
+  operator %(other) => null;
+  operator &(other) => null;
+  operator *(other) => null;
+  operator +(other) => null;
+  operator -() => null;
+  operator -(other) => null;
+  operator /(other) => null;
+  operator <(other) => null;
+  operator <<(other) => null;
+  operator <=(other) => null;
+  operator ==(other) => null;
+  operator >(other) => null;
+  operator >=(other) => null;
+  operator >>(other) => null;
+  operator [](index) => null;
+  operator ^(other) => null;
+  operator |(other) => null;
+  operator ~() => null;
+  operator ~/(other) => null;
+  void operator []=(index, value) {}
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline.expect
new file mode 100644
index 0000000..fefc2ed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+// @dart = 2.6
+class Foo {
+  method(x, [y, z]) {}
+}
+
+abstract class External {
+  String externalMethod(int x, [int y, int z]);
+  void listen(Listener listener);
+}
+
+external External createExternal();
+
+abstract class Listener {
+  void event(String input, [int x, int y]);
+}
+
+class TestListener extends Listener {
+  void event(input, [x, y]) {}
+}
+
+class ExtendedListener extends Listener {
+  void event(input, [x, y, z]) {}
+}
+
+class InvalidListener {
+  void event(input, [x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..686656a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+// @dart = 2.6
+abstract class External {
+  String externalMethod(int x, [int y, int z]);
+  void listen(Listener listener);
+}
+
+abstract class Listener {
+  void event(String input, [int x, int y]);
+}
+
+class ExtendedListener extends Listener {
+  void event(input, [x, y, z]) {}
+}
+
+class Foo {
+  method(x, [y, z]) {}
+}
+
+class InvalidListener {
+  void event(input, [x]) {}
+}
+
+class TestListener extends Listener {
+  void event(input, [x, y]) {}
+}
+
+external External createExternal();
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline.expect
new file mode 100644
index 0000000..bd802d4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Foo {}
+
+class Bar extends Foo {}
+
+class Base {
+  Foo method() {}
+}
+
+class Sub extends Base {
+  Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..857d43d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Bar extends Foo {}
+
+class Base {
+  Foo method() {}
+}
+
+class Foo {}
+
+class Sub extends Base {
+  Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..e0a4d3b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x(A value) {}
+  B get y => null;
+}
+
+class D extends C {
+  void set x(value) {}
+  get y => null;
+}
+
+class E extends D {
+  void set x(A value) {}
+  B get y => null;
+}
+
+class F extends D {
+  void set x(B value) {}
+  A get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5cef13
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  B get y => null;
+  void set x(A value) {}
+}
+
+class D extends C {
+  get y => null;
+  void set x(value) {}
+}
+
+class E extends D {
+  B get y => null;
+  void set x(A value) {}
+}
+
+class F extends D {
+  A get y => null;
+  void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..2eac781
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x(A value) {}
+  A get y => null;
+}
+
+class D extends C {
+  void set x(Object value) {}
+  B get y => null;
+}
+
+class E extends C {
+  void set x(B value) {}
+  Object get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..434390e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  A get y => null;
+  void set x(A value) {}
+}
+
+class D extends C {
+  B get y => null;
+  void set x(Object value) {}
+}
+
+class E extends C {
+  Object get y => null;
+  void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..37a5988
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x1(covariant A value) {}
+  void set x2(A value) {}
+  void set x3(covariant A value) {}
+  void set x4(A value) {}
+  void set x5(covariant A value) {}
+  void set x6(covariant B value) {}
+}
+
+class D extends C {
+  void set x1(B value) {}
+  void set x2(covariant B value) {}
+  void set x3(covariant B value) {}
+  void set x4(B value) {}
+  void set x5(covariant String value) {}
+  void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37a5988
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void set x1(covariant A value) {}
+  void set x2(A value) {}
+  void set x3(covariant A value) {}
+  void set x4(A value) {}
+  void set x5(covariant A value) {}
+  void set x6(covariant B value) {}
+}
+
+class D extends C {
+  void set x1(B value) {}
+  void set x2(covariant B value) {}
+  void set x3(covariant B value) {}
+  void set x4(B value) {}
+  void set x5(covariant String value) {}
+  void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..27efff1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(A x) {}
+}
+
+class D extends C {
+  void f(x) {}
+}
+
+class E extends D {
+  void f(A x) {}
+}
+
+class F extends D {
+  void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27efff1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(A x) {}
+}
+
+class D extends C {
+  void f(x) {}
+}
+
+class E extends D {
+  void f(A x) {}
+}
+
+class F extends D {
+  void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..16702e3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void f1(A x) {}
+  void f2([A x]) {}
+  void f3({A x}) {}
+  A f4() {}
+}
+
+class D extends C {
+  void f1(Object x) {}
+  void f2([Object x]) {}
+  void f3({Object x}) {}
+  B f4() {}
+}
+
+class E extends C {
+  void f1(B x) {}
+  void f2([B x]) {}
+  void f3({B x}) {}
+  Object f4() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ae09bf
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  A f4() {}
+  void f1(A x) {}
+  void f2([A x]) {}
+  void f3({A x}) {}
+}
+
+class D extends C {
+  B f4() {}
+  void f1(Object x) {}
+  void f2([Object x]) {}
+  void f3({Object x}) {}
+}
+
+class E extends C {
+  Object f4() {}
+  void f1(B x) {}
+  void f2([B x]) {}
+  void f3({B x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline.expect
new file mode 100644
index 0000000..4f5df34
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+class Foo<T extends Foo<T>> {}
+
+abstract class Bar {
+  void fisk<S extends Foo<S>>();
+}
+
+class Hest implements Bar {
+  @override
+  void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6832671
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+abstract class Bar {
+  void fisk<S extends Foo<S>>();
+}
+
+class Foo<T extends Foo<T>> {}
+
+class Hest implements Bar {
+  @override
+  void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline.expect
new file mode 100644
index 0000000..bb679c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A<T> {
+  void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+  void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb679c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A<T> {
+  void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+  void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..9a29d45
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void f1(covariant A x) {}
+  void f2(A x) {}
+  void f3(covariant A x) {}
+  void f4(A x) {}
+  void f5(covariant A x) {}
+  void f6(covariant B x) {}
+}
+
+class D extends C {
+  void f1(B x) {}
+  void f2(covariant B x) {}
+  void f3(covariant B x) {}
+  void f4(B x) {}
+  void f5(covariant String x) {}
+  void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a29d45
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+  void f1(covariant A x) {}
+  void f2(A x) {}
+  void f3(covariant A x) {}
+  void f4(A x) {}
+  void f5(covariant A x) {}
+  void f6(covariant B x) {}
+}
+
+class D extends C {
+  void f1(B x) {}
+  void f2(covariant B x) {}
+  void f3(covariant B x) {}
+  void f4(B x) {}
+  void f5(covariant String x) {}
+  void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..405d608
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class B {
+  num get foo => null;
+  set foo(dynamic newFoo) {}
+}
+
+class A extends B {
+  set foo(newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aded191
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A extends B {
+  set foo(newFoo) {}
+}
+
+class B {
+  num get foo => null;
+  set foo(dynamic newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline.expect
new file mode 100644
index 0000000..c56c48e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {
+  foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+  foo({c = true, bool a}) {}
+}
+
+class C extends B {
+  foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+  foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+  foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+  foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd5ed60e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {
+  foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+  foo({bool a = true, bool c}) {}
+}
+
+class B extends A {
+  foo({c = true, bool a}) {}
+}
+
+class B1 extends A1 {
+  foo({a = true, bool c}) {}
+}
+
+class C extends B {
+  foo({bool c = true, bool a}) {}
+}
+
+class C1 extends B1 {
+  foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline.expect
new file mode 100644
index 0000000..efb031f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A {
+  void set x(Object y);
+}
+
+class B implements A {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..efb031f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A {
+  void set x(Object y);
+}
+
+class B implements A {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline.expect
new file mode 100644
index 0000000..56c5193
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..56c5193
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline.expect
new file mode 100644
index 0000000..49e7a9f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49e7a9f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..5094fa1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5094fa1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline.expect
new file mode 100644
index 0000000..24b780d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..24b780d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..ea5cdd5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea5cdd5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline.expect
new file mode 100644
index 0000000..f124a27
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class A {}
+
+class B {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..615035f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class A {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+main() {}
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..d709d38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import './private_method_tearoff_lib.dart';
+
+class Foo implements Bar {}
+
+class Baz extends Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d346af
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import './private_method_tearoff_lib.dart';
+
+class Baz extends Foo {}
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline.expect
new file mode 100644
index 0000000..4e30433
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class<T> {
+  method(T o) {}
+}
+
+method<T>(T o) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e6741a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class<T> {
+  method(T o) {}
+}
+
+main() {}
+method<T>(T o) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..c43b7fd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c43b7fd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline.expect
new file mode 100644
index 0000000..437d273
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+  lib.Missing method() {}
+  factory WrongName() {}
+}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4102d33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+  factory WrongName() {}
+  lib.Missing method() {}
+}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..470f695
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  A();
+  factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..470f695
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  A();
+  factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..7efd803
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+abstract class FooBase<Tf> {
+  int get x;
+  factory FooBase(int x) = Foo<Tf>;
+}
+
+abstract class Foo<T> implements FooBase {
+  factory Foo(int x) = Bar<String, T>;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+  int x;
+  Bar(this.x) {}
+}
+
+class Builder<X> {
+  method() {}
+}
+
+class SimpleCase<A, B> {
+  factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+  factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class Base<M> {}
+
+class Mixin<M> {}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43e7c92
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+abstract class Foo<T> implements FooBase {
+  factory Foo(int x) = Bar<String, T>;
+}
+
+abstract class FooBase<Tf> {
+  factory FooBase(int x) = Foo<Tf>;
+  int get x;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+  Bar(this.x) {}
+  int x;
+}
+
+class Base<M> {}
+
+class Builder<X> {
+  method() {}
+}
+
+class Mixin<M> {}
+
+class SimpleCase<A, B> {
+  factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+  factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline.expect
new file mode 100644
index 0000000..25a1082
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+library redirecting_factory_constructors.chain_test;
+
+class A {
+  A();
+  factory A.first() = A;
+  factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25a1082
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+library redirecting_factory_constructors.chain_test;
+
+class A {
+  A();
+  factory A.first() = A;
+  factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..4767533
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+class _X<T> {
+  const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+  const _Y();
+}
+
+class A<T> {
+  _X<T> x;
+  A(this.x);
+}
+
+class B<T> extends A<T> {
+  B() : super(const _X());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..889323b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+class A<T> {
+  A(this.x);
+  _X<T> x;
+}
+
+class B<T> extends A<T> {
+  B() : super(const _X());
+}
+
+class _X<T> {
+  const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+  const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..1a59844
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+const forParameter = 1;
+const forFactoryItself = 2;
+const anotherForParameter = 3;
+
+class Foo {
+  @forFactoryItself
+  factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+  Foo.named(p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..465cd5b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Foo {
+  @forFactoryItself
+  factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+  Foo.named(p);
+}
+
+const anotherForParameter = 3;
+const forFactoryItself = 2;
+const forParameter = 1;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline.expect
new file mode 100644
index 0000000..72e8dd1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.simple_test;
+
+class A {
+  A();
+  factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72e8dd1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.simple_test;
+
+class A {
+  A();
+  factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e6e9dba
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeargs_test;
+
+class X {}
+
+class Y extends X {}
+
+class A {
+  A();
+  factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+  B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bc43b3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeargs_test;
+
+class A {
+  A();
+  factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+  B();
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline.expect
new file mode 100644
index 0000000..06f0190
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..06f0190
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
new file mode 100644
index 0000000..80e15be
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparambounds_test;
+
+class X {}
+
+class Y extends X {}
+
+class A<T, S extends T> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d63864
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparambounds_test;
+
+class A<T, S extends T> {
+  A(T t, S s);
+  factory A.redir(T t, S s) = A<T, S>;
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
new file mode 100644
index 0000000..1473d4d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class X {}
+
+class Foo<T extends X> {
+  T x;
+  Foo.fromX(X _init) : this._internal(x: _init);
+  Foo.fromT(T _init) : this._internal(x: _init);
+  Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6cc8c23
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Foo<T extends X> {
+  Foo._internal({this.x});
+  Foo.fromT(T _init) : this._internal(x: _init);
+  Foo.fromX(X _init) : this._internal(x: _init);
+  T x;
+}
+
+class X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline.expect
new file mode 100644
index 0000000..ee6bdf0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo<T> {
+  T x;
+  Foo.from(String _init) : this._internal(x: _init);
+  Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..987d68d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo<T> {
+  Foo._internal({this.x});
+  Foo.from(String _init) : this._internal(x: _init);
+  T x;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..1f7d067
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A<T> {
+  factory A() = B<T, num>;
+  A.empty();
+}
+
+class B<U, W> extends A<U> {
+  factory B() = C<U, W, String>;
+  B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ebbc0f2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A<T> {
+  A.empty();
+  factory A() = B<T, num>;
+}
+
+class B<U, W> extends A<U> {
+  B.empty() : super.empty();
+  factory B() = C<U, W, String>;
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline.expect
new file mode 100644
index 0000000..ccc7cc7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+  factory A() = B<T, List<T>>;
+  A.empty();
+}
+
+abstract class B<U, W> extends A<U> {
+  factory B() = C<U, W, Map<U, W>>;
+  B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..60429ec
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+  A.empty();
+  factory A() = B<T, List<T>>;
+}
+
+abstract class B<U, W> extends A<U> {
+  B.empty() : super.empty();
+  factory B() = C<U, W, Map<U, W>>;
+}
+
+class C<V, S, R> extends B<V, S> {
+  C() : super.empty();
+  toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..6394a90
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A {
+  const factory A() = B<String>;
+  const A.empty();
+}
+
+class B<T> extends A {
+  const B() : super.empty();
+  toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc1e553
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A {
+  const A.empty();
+  const factory A() = B<String>;
+}
+
+class B<T> extends A {
+  const B() : super.empty();
+  toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..72477c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72477c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline.expect
new file mode 100644
index 0000000..fcffd7e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fcffd7e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline.expect
new file mode 100644
index 0000000..2c7d4ce
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C extends Iterable<Object> {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9771aa3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C extends Iterable<Object> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.strong.transformed.expect
index 935dc38..ab00273 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.strong.transformed.expect
@@ -9,7 +9,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method main() → dynamic {
@@ -17,7 +16,7 @@
     final core::List<core::int*>* #t1 = <core::int*>[];
     #t1.{core::List::add}(1);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[2]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t2 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t2);
@@ -25,7 +24,7 @@
     }
     final core::Iterable<core::int*>* #t3 = <core::int*>[3];
     if(!#t3.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t3).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t3.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t4 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t4);
@@ -36,7 +35,7 @@
     final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
     #t5.{core::Map::[]=}(1, 1);
     {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{2: 2}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{2: 2}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
@@ -44,7 +43,7 @@
     }
     final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
     if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(#t7.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = #t7.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t8 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
@@ -55,7 +54,7 @@
     final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
     #t9.{core::Set::add}(1);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[2]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::Set::add}(#t10);
@@ -63,7 +62,7 @@
     }
     final core::Iterable<core::int*>* #t11 = <core::int*>[3];
     if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t11).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t11.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::Set::add}(#t12);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..f5f9183
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+foo() => null;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e69d5d9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect
index 935dc38..ab00273 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect
@@ -9,7 +9,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method main() → dynamic {
@@ -17,7 +16,7 @@
     final core::List<core::int*>* #t1 = <core::int*>[];
     #t1.{core::List::add}(1);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[2]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t2 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t2);
@@ -25,7 +24,7 @@
     }
     final core::Iterable<core::int*>* #t3 = <core::int*>[3];
     if(!#t3.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t3).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t3.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t4 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t4);
@@ -36,7 +35,7 @@
     final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
     #t5.{core::Map::[]=}(1, 1);
     {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{2: 2}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{2: 2}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
@@ -44,7 +43,7 @@
     }
     final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
     if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(#t7.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = #t7.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t8 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
@@ -55,7 +54,7 @@
     final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
     #t9.{core::Set::add}(1);
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[2]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::Set::add}(#t10);
@@ -63,7 +62,7 @@
     }
     final core::Iterable<core::int*>* #t11 = <core::int*>[3];
     if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t11).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t11.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::Set::add}(#t12);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.strong.transformed.expect
index db8baa1..8eb50fc 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.strong.transformed.expect
@@ -98,7 +98,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method bar<K extends core::Object* = dynamic, V extends core::Object* = dynamic>() → core::Map<self::bar::K*, self::bar::V*>*
@@ -113,7 +112,7 @@
   core::List<dynamic>* lhs10 = block {
     final core::List<dynamic>* #t1 = <dynamic>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t2);
@@ -123,7 +122,7 @@
   core::Set<dynamic>* set10 = block {
     final core::Set<dynamic>* #t3 = col::LinkedHashSet::•<dynamic>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         #t3.{core::Set::add}(#t4);
@@ -133,7 +132,7 @@
   core::Map<dynamic, dynamic>* map10 = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(<dynamic, dynamic>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
@@ -143,7 +142,7 @@
   core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(<dynamic, dynamic>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t8 = :sync-for-iterator.{core::Iterator::current};
         #t7.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
@@ -153,7 +152,7 @@
   core::List<core::int*>* lhs20 = block {
     final core::List<core::int*>* #t9 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::List::add}(#t10);
@@ -163,7 +162,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
         #t11.{core::Set::add}(#t12);
@@ -174,7 +173,7 @@
   core::Set<core::int*>* set20ambiguous = block {
     final core::Set<core::int*>* #t13 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -187,7 +186,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
@@ -198,7 +197,7 @@
   core::Map<core::String*, core::int*>* map20ambiguous = block {
     final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Map::[]=}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
@@ -208,7 +207,7 @@
   core::List<dynamic>* lhs21 = block {
     final core::List<dynamic>* #t20 = <dynamic>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::List::add}(#t21);
@@ -218,7 +217,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t22 = col::LinkedHashSet::•<dynamic>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
         #t22.{core::Set::add}(#t23);
@@ -229,7 +228,7 @@
   core::Map<dynamic, dynamic>* map21 = block {
     final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t25 = :sync-for-iterator.{core::Iterator::current};
         #t24.{core::Map::[]=}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
@@ -244,7 +243,7 @@
   core::List<core::int*>* lhs22 = block {
     final core::List<core::int*>* #t26 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t27 = :sync-for-iterator.{core::Iterator::current};
         #t26.{core::List::add}(#t27);
@@ -254,7 +253,7 @@
   core::Set<core::int*>* set22 = block {
     final core::Set<core::int*>* #t28 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
         #t28.{core::Set::add}(#t29);
@@ -265,7 +264,7 @@
   core::Set<core::int*>* set22ambiguous = block {
     final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t31 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -278,7 +277,7 @@
   core::Map<core::String*, core::int*>* map22 = block {
     final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t34 = :sync-for-iterator.{core::Iterator::current};
         #t33.{core::Map::[]=}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
@@ -288,7 +287,7 @@
   core::List<core::List<core::int*>*>* lhs23 = block {
     final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t36 = :sync-for-iterator.{core::Iterator::current};
         #t35.{core::List::add}(#t36);
@@ -298,7 +297,7 @@
   core::Set<core::List<core::int*>*>* set23 = block {
     final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t38 = :sync-for-iterator.{core::Iterator::current};
         #t37.{core::Set::add}(#t38);
@@ -309,7 +308,7 @@
   core::Set<core::List<core::int*>*>* set23ambiguous = block {
     final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t40 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -322,7 +321,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map23 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
         #t42.{core::Map::[]=}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
@@ -338,7 +337,7 @@
                                    ^" in ( block {
     final core::List<core::int*>* #t45 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t46 = :sync-for-iterator.{core::Iterator::current};
         #t45.{core::List::add}(#t46);
@@ -351,7 +350,7 @@
                                    ^" in ( block {
     final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t49 = :sync-for-iterator.{core::Iterator::current};
         #t48.{core::Set::add}(#t49);
@@ -365,7 +364,7 @@
       ^" in ( block {
     final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t52 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -381,7 +380,7 @@
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t56 = :sync-for-iterator.{core::Iterator::current};
         #t55.{core::Map::[]=}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
@@ -395,7 +394,7 @@
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
         #t58.{core::Map::[]=}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
@@ -444,7 +443,7 @@
     ...null,
        ^");
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t69 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -461,7 +460,7 @@
     final core::List<core::int*>* #t71 = <core::int*>[];
     final core::Iterable<core::int*>* #t72 = null;
     if(!#t72.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t72).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t72.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t73 = :sync-for-iterator.{core::Iterator::current};
         #t71.{core::List::add}(#t73);
@@ -472,7 +471,7 @@
     final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>();
     final core::Iterable<core::int*>* #t75 = null;
     if(!#t75.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t75).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t75.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t76 = :sync-for-iterator.{core::Iterator::current};
         #t74.{core::Set::add}(#t76);
@@ -483,7 +482,7 @@
     final core::Set<dynamic>* #t77 = col::LinkedHashSet::•<dynamic>();
     final core::Iterable<dynamic>* #t78 = null;
     if(!#t78.{core::Object::==}(null)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(#t78).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = #t78.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t79 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -493,7 +492,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t81 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -507,7 +506,7 @@
     final core::Map<core::String*, core::int*>* #t83 = <core::String*, core::int*>{};
     final core::Map<core::String*, core::int*>* #t84 = null;
     if(!#t84.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t84.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = #t84.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t85 = :sync-for-iterator.{core::Iterator::current};
         #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
@@ -517,7 +516,7 @@
   core::Map<core::String*, core::int*>* map90 = block {
     final core::Map<core::String*, core::int*>* #t86 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(self::bar<core::String*, core::int*>().{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t87 = :sync-for-iterator.{core::Iterator::current};
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
@@ -527,7 +526,7 @@
   core::List<core::int*>* list100 = block {
     final core::List<core::int*>* #t88 = <core::int*>[];
     {
-      core::Iterator<core::num*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::num*>*>(listNum).{core::Iterable::iterator};
+      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t89 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -540,7 +539,7 @@
   core::Map<core::num*, core::int*>* map100 = block {
     final core::Map<core::num*, core::int*>* #t91 = <core::num*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::int*, core::num*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::num*>*>*>(mapIntNum.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::num*>*>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t92 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -554,7 +553,7 @@
   core::List<core::int*>* list110 = block {
     final core::List<core::int*>* #t95 = <core::int*>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t96 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -567,7 +566,7 @@
   core::Map<core::num*, core::int*>* map110 = block {
     final core::Map<core::num*, core::int*>* #t98 = <core::num*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t99 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..aea5ba4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aea5ba4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect
index db8baa1..8eb50fc 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect
@@ -98,7 +98,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 static method bar<K extends core::Object* = dynamic, V extends core::Object* = dynamic>() → core::Map<self::bar::K*, self::bar::V*>*
@@ -113,7 +112,7 @@
   core::List<dynamic>* lhs10 = block {
     final core::List<dynamic>* #t1 = <dynamic>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         #t1.{core::List::add}(#t2);
@@ -123,7 +122,7 @@
   core::Set<dynamic>* set10 = block {
     final core::Set<dynamic>* #t3 = col::LinkedHashSet::•<dynamic>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         #t3.{core::Set::add}(#t4);
@@ -133,7 +132,7 @@
   core::Map<dynamic, dynamic>* map10 = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(<dynamic, dynamic>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t6 = :sync-for-iterator.{core::Iterator::current};
         #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
@@ -143,7 +142,7 @@
   core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(<dynamic, dynamic>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t8 = :sync-for-iterator.{core::Iterator::current};
         #t7.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
@@ -153,7 +152,7 @@
   core::List<core::int*>* lhs20 = block {
     final core::List<core::int*>* #t9 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
         #t9.{core::List::add}(#t10);
@@ -163,7 +162,7 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
         #t11.{core::Set::add}(#t12);
@@ -174,7 +173,7 @@
   core::Set<core::int*>* set20ambiguous = block {
     final core::Set<core::int*>* #t13 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -187,7 +186,7 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
@@ -198,7 +197,7 @@
   core::Map<core::String*, core::int*>* map20ambiguous = block {
     final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Map::[]=}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
@@ -208,7 +207,7 @@
   core::List<dynamic>* lhs21 = block {
     final core::List<dynamic>* #t20 = <dynamic>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::List::add}(#t21);
@@ -218,7 +217,7 @@
   core::Set<dynamic>* set21 = block {
     final core::Set<dynamic>* #t22 = col::LinkedHashSet::•<dynamic>();
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
         #t22.{core::Set::add}(#t23);
@@ -229,7 +228,7 @@
   core::Map<dynamic, dynamic>* map21 = block {
     final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t25 = :sync-for-iterator.{core::Iterator::current};
         #t24.{core::Map::[]=}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
@@ -244,7 +243,7 @@
   core::List<core::int*>* lhs22 = block {
     final core::List<core::int*>* #t26 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t27 = :sync-for-iterator.{core::Iterator::current};
         #t26.{core::List::add}(#t27);
@@ -254,7 +253,7 @@
   core::Set<core::int*>* set22 = block {
     final core::Set<core::int*>* #t28 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
         #t28.{core::Set::add}(#t29);
@@ -265,7 +264,7 @@
   core::Set<core::int*>* set22ambiguous = block {
     final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[]).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t31 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -278,7 +277,7 @@
   core::Map<core::String*, core::int*>* map22 = block {
     final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(<core::String*, core::int*>{}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t34 = :sync-for-iterator.{core::Iterator::current};
         #t33.{core::Map::[]=}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
@@ -288,7 +287,7 @@
   core::List<core::List<core::int*>*>* lhs23 = block {
     final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t36 = :sync-for-iterator.{core::Iterator::current};
         #t35.{core::List::add}(#t36);
@@ -298,7 +297,7 @@
   core::Set<core::List<core::int*>*>* set23 = block {
     final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::List<core::int*>* #t38 = :sync-for-iterator.{core::Iterator::current};
         #t37.{core::Set::add}(#t38);
@@ -309,7 +308,7 @@
   core::Set<core::List<core::int*>*>* set23ambiguous = block {
     final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::List<core::int*>*>*>(<core::List<core::int*>*>[<core::int*>[]]).{core::Iterable::iterator};
+      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t40 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -322,7 +321,7 @@
   core::Map<core::String*, core::List<core::int*>*>* map23 = block {
     final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::List<core::int*>*>*>*>(<core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>*>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
         #t42.{core::Map::[]=}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
@@ -338,7 +337,7 @@
                                    ^" in ( block {
     final core::List<core::int*>* #t45 = <core::int*>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t46 = :sync-for-iterator.{core::Iterator::current};
         #t45.{core::List::add}(#t46);
@@ -351,7 +350,7 @@
                                    ^" in ( block {
     final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t49 = :sync-for-iterator.{core::Iterator::current};
         #t48.{core::Set::add}(#t49);
@@ -365,7 +364,7 @@
       ^" in ( block {
     final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(spread).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t52 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -381,7 +380,7 @@
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t56 = :sync-for-iterator.{core::Iterator::current};
         #t55.{core::Map::[]=}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
@@ -395,7 +394,7 @@
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(mapSpread.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
         #t58.{core::Map::[]=}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
@@ -444,7 +443,7 @@
     ...null,
        ^");
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t69 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -461,7 +460,7 @@
     final core::List<core::int*>* #t71 = <core::int*>[];
     final core::Iterable<core::int*>* #t72 = null;
     if(!#t72.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t72).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t72.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t73 = :sync-for-iterator.{core::Iterator::current};
         #t71.{core::List::add}(#t73);
@@ -472,7 +471,7 @@
     final core::Set<core::int*>* #t74 = col::LinkedHashSet::•<core::int*>();
     final core::Iterable<core::int*>* #t75 = null;
     if(!#t75.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(#t75).{core::Iterable::iterator};
+      core::Iterator<core::int*>* :sync-for-iterator = #t75.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::int* #t76 = :sync-for-iterator.{core::Iterator::current};
         #t74.{core::Set::add}(#t76);
@@ -483,7 +482,7 @@
     final core::Set<dynamic>* #t77 = col::LinkedHashSet::•<dynamic>();
     final core::Iterable<dynamic>* #t78 = null;
     if(!#t78.{core::Object::==}(null)) {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(#t78).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = #t78.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t79 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -493,7 +492,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t81 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -507,7 +506,7 @@
     final core::Map<core::String*, core::int*>* #t83 = <core::String*, core::int*>{};
     final core::Map<core::String*, core::int*>* #t84 = null;
     if(!#t84.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t84.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = #t84.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t85 = :sync-for-iterator.{core::Iterator::current};
         #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
@@ -517,7 +516,7 @@
   core::Map<core::String*, core::int*>* map90 = block {
     final core::Map<core::String*, core::int*>* #t86 = <core::String*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(self::bar<core::String*, core::int*>().{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String*, core::int*>* #t87 = :sync-for-iterator.{core::Iterator::current};
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
@@ -527,7 +526,7 @@
   core::List<core::int*>* list100 = block {
     final core::List<core::int*>* #t88 = <core::int*>[];
     {
-      core::Iterator<core::num*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::num*>*>(listNum).{core::Iterable::iterator};
+      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t89 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -540,7 +539,7 @@
   core::Map<core::num*, core::int*>* map100 = block {
     final core::Map<core::num*, core::int*>* #t91 = <core::num*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<core::int*, core::num*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::num*>*>*>(mapIntNum.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::num*>*>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t92 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -554,7 +553,7 @@
   core::List<core::int*>* list110 = block {
     final core::List<core::int*>* #t95 = <core::int*>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t96 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -567,7 +566,7 @@
   core::Map<core::num*, core::int*>* map110 = block {
     final core::Map<core::num*, core::int*>* #t98 = <core::num*, core::int*>{};
     {
-      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>((dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, dynamic>* #t99 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline.expect
new file mode 100644
index 0000000..43f51e0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo() {}
+bar() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8532037
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+bar() async {}
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..8d98297
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class Foo {}
+
+set foo(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..42cccc3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class Foo {}
+
+main() {}
+set foo(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline.expect
new file mode 100644
index 0000000..1ecc972
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Foo {
+  var _field;
+}
+
+class FooValue {}
+
+class Bar {
+  var _field;
+}
+
+class BarValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe6cd34
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Bar {
+  var _field;
+}
+
+class BarValue {}
+
+class Foo {
+  var _field;
+}
+
+class FooValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline.expect
new file mode 100644
index 0000000..e79dab7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+var color = 'brown';
+var thing = 'lazy dog';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var adjacent = '$color$color$color';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dc991f6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+main() {}
+var adjacent = '$color$color$color';
+var color = 'brown';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var thing = 'lazy dog';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline.expect
new file mode 100644
index 0000000..25ae6c7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A {
+  int call(int x) => x * 2;
+}
+
+class B extends A {
+  int call(int x) => x * 3;
+  int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25ae6c7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A {
+  int call(int x) => x * 2;
+}
+
+class B extends A {
+  int call(int x) => x * 3;
+  int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline.expect
new file mode 100644
index 0000000..6f8142a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class I {
+  interfaceMethod();
+}
+
+class C implements I {
+  noSuchMethod(_) => "C";
+}
+
+class D extends C {
+  noSuchMethod(_) => "D";
+  dMethod() => super.interfaceMethod();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e8ad96
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class I {
+  interfaceMethod();
+}
+
+class C implements I {
+  noSuchMethod(_) => "C";
+}
+
+class D extends C {
+  dMethod() => super.interfaceMethod();
+  noSuchMethod(_) => "D";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline.expect
new file mode 100644
index 0000000..5cf5db8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..94295cd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..8c08006
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+typedef Foo<T> = void Function(Bar<T>);
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6beff18
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+main() {}
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+typedef Foo<T> = void Function(Bar<T>);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..14ca2ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14ca2ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline.expect
new file mode 100644
index 0000000..9a2faad
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a2faad
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..83562c7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+  const A();
+}
+
+@A
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed301d3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+@A
+class B {}
+
+class A {
+  const A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline.expect
new file mode 100644
index 0000000..312495f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+Null foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..444071f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+Null foo() => null;
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline.expect
new file mode 100644
index 0000000..0f82905
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class Foo<T> {
+  List<T> get list;
+  void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+  List<int> list;
+  void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f82905
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class Foo<T> {
+  List<T> get list;
+  void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+  List<int> list;
+  void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline.expect
new file mode 100644
index 0000000..829888b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+  B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..829888b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+  B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline.expect
new file mode 100644
index 0000000..60421d4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class DynamicClass<T extends dynamic, S extends T> {
+  T field1;
+  T field2;
+  DynamicClass(this.field1, this.field2);
+  method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+  T field1;
+  S field2;
+  NumClass(this.field1, this.field2);
+  num method1() => field1 * field2;
+  num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65451d7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class DynamicClass<T extends dynamic, S extends T> {
+  DynamicClass(this.field1, this.field2);
+  T field1;
+  T field2;
+  method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+  NumClass(this.field1, this.field2);
+  S field2;
+  T field1;
+  num method1() => field1 * field2;
+  num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.expect
index 299c8ab..62bc2c5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.expect
@@ -16,9 +16,9 @@
     : super core::Object::•()
     ;
   method method() → invalid-type
-    return "Hello, World!" as{TypeError} invalid-type;
+    return "Hello, World!";
 }
 static method main() → dynamic {
-  core::String* s = new self::C::•<dynamic>().{self::C::method}() as{TypeError} core::String*;
+  core::String* s = new self::C::•<dynamic>().{self::C::method}();
   core::print(s);
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.transformed.expect
index 299c8ab..62bc2c5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.strong.transformed.expect
@@ -16,9 +16,9 @@
     : super core::Object::•()
     ;
   method method() → invalid-type
-    return "Hello, World!" as{TypeError} invalid-type;
+    return "Hello, World!";
 }
 static method main() → dynamic {
-  core::String* s = new self::C::•<dynamic>().{self::C::method}() as{TypeError} core::String*;
+  core::String* s = new self::C::•<dynamic>().{self::C::method}();
   core::print(s);
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..8ce9e43
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import "dart:core" as T;
+
+class C<T> {
+  T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ce9e43
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import "dart:core" as T;
+
+class C<T> {
+  T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.expect
index 299c8ab..62bc2c5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.expect
@@ -16,9 +16,9 @@
     : super core::Object::•()
     ;
   method method() → invalid-type
-    return "Hello, World!" as{TypeError} invalid-type;
+    return "Hello, World!";
 }
 static method main() → dynamic {
-  core::String* s = new self::C::•<dynamic>().{self::C::method}() as{TypeError} core::String*;
+  core::String* s = new self::C::•<dynamic>().{self::C::method}();
   core::print(s);
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.transformed.expect
index 299c8ab..62bc2c5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.weak.transformed.expect
@@ -16,9 +16,9 @@
     : super core::Object::•()
     ;
   method method() → invalid-type
-    return "Hello, World!" as{TypeError} invalid-type;
+    return "Hello, World!";
 }
 static method main() → dynamic {
-  core::String* s = new self::C::•<dynamic>().{self::C::method}() as{TypeError} core::String*;
+  core::String* s = new self::C::•<dynamic>().{self::C::method}();
   core::print(s);
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline.expect
new file mode 100644
index 0000000..f26d098
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C<T> {
+  const C();
+  static C<T> staticMethod() {}
+  C<T> instanceMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..39e4742
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C<T> {
+  C<T> instanceMethod() {}
+  const C();
+  static C<T> staticMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..3e2bcc6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
+typedef _BinaryFunction(args, message);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e9e640
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+main() {}
+typedef _BinaryFunction(args, message);
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline.expect
new file mode 100644
index 0000000..9fd10ce
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+  var x;
+  void f() {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..646c90b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+  var x;
+  void f() {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..d78b4c8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+  void set x(value) {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e21b39a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+  void set x(value) {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..ae51bee
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Uninitialized {
+  int x;
+}
+
+class PartiallyInitialized {
+  int x;
+  PartiallyInitialized(this.x);
+  PartiallyInitialized.noInitializer();
+}
+
+class Initialized {
+  int x;
+  Initialized(this.x);
+}
+
+class Forwarding {
+  int x;
+  Forwarding.initialize(this.x);
+  Forwarding(int arg) : this.initialize(arg);
+}
+
+int uninitializedTopLevel;
+int initializedTopLevel = 4;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7bd0081
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Forwarding {
+  Forwarding(int arg) : this.initialize(arg);
+  Forwarding.initialize(this.x);
+  int x;
+}
+
+class Initialized {
+  Initialized(this.x);
+  int x;
+}
+
+class PartiallyInitialized {
+  PartiallyInitialized(this.x);
+  PartiallyInitialized.noInitializer();
+  int x;
+}
+
+class Uninitialized {
+  int x;
+}
+
+int initializedTopLevel = 4;
+int uninitializedTopLevel;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..fe7b0e7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+List<A> list;
+List<T> g<T extends A>(T t) {}
+List<S> f<S>(S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6664ade
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+List<A> list;
+List<S> f<S>(S s) {}
+List<T> g<T extends A>(T t) {}
+
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..5bbb73f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline.expect
@@ -0,0 +1,37 @@
+// @dart = 2.6
+class UnusedClass {
+  UnusedClass() {}
+}
+
+abstract class UsedAsBaseClass {
+  void usedInSubclass() {}
+  void calledFromB() {}
+  void calledFromSubclass() {}
+}
+
+class UsedAsInterface {
+  void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+  void calledFromSubclass() {}
+}
+
+void baseClassCall(UsedAsBaseClass object) {}
+void interfaceCall(UsedAsInterface object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+unusedTopLevel() {}
+usedTopLevel() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9d94c52
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+// @dart = 2.6
+abstract class UsedAsBaseClass {
+  void calledFromB() {}
+  void calledFromSubclass() {}
+  void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+    implements UsedAsInterface, InstantiatedButMethodsUnused {
+  void calledFromSubclass() {}
+  void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+  void usedInSubclass() {}
+}
+
+class UnusedClass {
+  UnusedClass() {}
+}
+
+class UsedAsInterface {
+  void usedInSubclass() {}
+}
+
+main() {}
+unusedTopLevel() {}
+usedTopLevel() {}
+void baseClassCall(UsedAsBaseClass object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+void interfaceCall(UsedAsInterface object) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/var_as_type_name.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/var_as_type_name.dart.textual_outline.expect
new file mode 100644
index 0000000..75b4c1c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/var_as_type_name.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class A {
+  Map<String, var> m;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..2121500
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Foo {
+  List list = [1, 2, 3];
+  set first(x) => list[0] = x;
+  operator []=(x, y) => list[x] = y;
+  void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e233a9b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Foo {
+  List list = [1, 2, 3];
+  operator []=(x, y) => list[x] = y;
+  set first(x) => list[0] = x;
+  void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline.expect
new file mode 100644
index 0000000..a0231de
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class C {
+  var superField;
+  superMethod() {}
+  get setterOnly => null;
+  void set setterOnly(_) {}
+  get getterOnly => null;
+  void set getterOnly(_) {}
+}
+
+class D extends C {
+  var field;
+  void set setterOnly(_) {}
+  get getterOnly => null;
+  method() {}
+  void test() {}
+}
+
+class E extends D {
+  var missingField;
+  void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cce7cbc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class C {
+  get getterOnly => null;
+  get setterOnly => null;
+  superMethod() {}
+  var superField;
+  void set getterOnly(_) {}
+  void set setterOnly(_) {}
+}
+
+class D extends C {
+  get getterOnly => null;
+  method() {}
+  var field;
+  void set setterOnly(_) {}
+  void test() {}
+}
+
+class E extends D {
+  var missingField;
+  void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline.expect b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline.expect
new file mode 100644
index 0000000..d9d43c9
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+int read(int value) => enableRead ? value : -1;
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+
+class Class {
+  Function field1a = method1;
+  int Function() field1b = method1;
+  int Function(int a) field2 = method2;
+  int Function(int a, int b) field3 = method3;
+  int Function(int a, [int b]) field4 = method4;
+  int Function([int a, int b]) field5 = method5;
+  int Function(int a, {int b}) field6 = method6;
+  int Function({int a, int b}) field7 = method7;
+  Function get getter1a => method1;
+  int Function() get getter1b => method1;
+  int Function(int a) get getter2 => method2;
+  int Function(int a, int b) get getter3 => method3;
+  int Function(int a, [int b]) get getter4 => method4;
+  int Function([int a, int b]) get getter5 => method5;
+  int Function(int a, {int b}) get getter6 => method6;
+  int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+  Function get field1a {}
+  int Function() get field1b {}
+  int Function(int a) get field2 {}
+  int Function(int a, int b) get field3 {}
+  int Function(int a, [int b]) get field4 {}
+  int Function([int a, int b]) get field5 {}
+  int Function(int a, {int b}) get field6 {}
+  int Function({int a, int b}) get field7 {}
+  Function get getter1a {}
+  int Function() get getter1b {}
+  int Function(int a) get getter2 {}
+  int Function(int a, int b) get getter3 {}
+  int Function(int a, [int b]) get getter4 {}
+  int Function([int a, int b]) get getter5 {}
+  int Function(int a, {int b}) get getter6 {}
+  int Function({int a, int b}) get getter7 {}
+}
+
+main() {}
+callField(Class c) {}
+callGetter(Class c) {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fafec6e
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+callField(Class c) {}
+callGetter(Class c) {}
+
+class Class {
+  Function field1a = method1;
+  Function get getter1a => method1;
+  int Function() field1b = method1;
+  int Function() get getter1b => method1;
+  int Function([int a, int b]) field5 = method5;
+  int Function([int a, int b]) get getter5 => method5;
+  int Function(int a) field2 = method2;
+  int Function(int a) get getter2 => method2;
+  int Function(int a, [int b]) field4 = method4;
+  int Function(int a, [int b]) get getter4 => method4;
+  int Function(int a, int b) field3 = method3;
+  int Function(int a, int b) get getter3 => method3;
+  int Function(int a, {int b}) field6 = method6;
+  int Function(int a, {int b}) get getter6 => method6;
+  int Function({int a, int b}) field7 = method7;
+  int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+  Function get field1a {}
+  Function get getter1a {}
+  int Function() get field1b {}
+  int Function() get getter1b {}
+  int Function([int a, int b]) get field5 {}
+  int Function([int a, int b]) get getter5 {}
+  int Function(int a) get field2 {}
+  int Function(int a) get getter2 {}
+  int Function(int a, [int b]) get field4 {}
+  int Function(int a, [int b]) get getter4 {}
+  int Function(int a, int b) get field3 {}
+  int Function(int a, int b) get getter3 {}
+  int Function(int a, {int b}) get field6 {}
+  int Function(int a, {int b}) get getter6 {}
+  int Function({int a, int b}) get field7 {}
+  int Function({int a, int b}) get getter7 {}
+}
+
+expect(expected, actual) {}
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+int read(int value) => enableRead ? value : -1;
+main() {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline.expect b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline.expect
new file mode 100644
index 0000000..eb3e361
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {
+  void Function(T) f;
+  A(this.f);
+  foo(T x) => this.f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b5116cc
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {
+  A(this.f);
+  foo(T x) => this.f(x);
+  void Function(T) f;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml
new file mode 100644
index 0000000..3e3b988
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml
@@ -0,0 +1,65 @@
+# 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.
+
+type: newworld
+target: DDC
+trackWidgetCreation: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import 'package:flutter/src/widgets/framework.dart';
+        import 'package:flutter/src/widgets/widget_inspector.dart';
+
+        class Foo extends Widget {}
+      flutter/lib/src/widgets/framework.dart: |
+        abstract class Bar {}
+
+        abstract class Widget extends Bar {}
+      flutter/lib/src/widgets/widget_inspector.dart: |
+        abstract class _HasCreationLocation {
+          _Location get _location;
+        }
+
+        /// A tuple with file, line, and column number, for displaying human-readable
+        /// file locations.
+        class _Location {
+          const _Location({
+            this.file,
+            this.line,
+            this.column,
+            this.name,
+            this.parameterLocations,
+          });
+
+          /// File path of the location.
+          final String file;
+
+          /// 1-based line number.
+          final int line;
+
+          /// 1-based column number.
+          final int column;
+
+          /// Optional name of the parameter or function at this location.
+          final String name;
+
+          /// Optional locations of the parameters of the member at this location.
+          final List<_Location> parameterLocations;
+        }
+      .packages: |
+        flutter:flutter/lib
+    expectedLibraryCount: 3
+  - entry: main.dart
+    worldType: updated
+    invalidate:
+      - main.dart
+    expectInitializeFromDill: false
+    sources:
+      main.dart: |
+        import 'package:flutter/src/widgets/framework.dart';
+        import 'package:flutter/src/widgets/widget_inspector.dart';
+
+        class Foo extends Widget {}
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.1.expect
new file mode 100644
index 0000000..95a88d7
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.1.expect
@@ -0,0 +1,48 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  abstract class Bar extends dart.core::Object {
+    synthetic constructor •() → fra::Bar*
+      : super dart.core::Object::•()
+      ;
+  }
+  abstract class Widget extends fra::Bar implements wid::_HasCreationLocation {
+    final field wid::_Location* _location /* from null */;
+    synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → fra::Widget*
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+      ;
+  }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+  abstract class _HasCreationLocation extends dart.core::Object {
+    synthetic constructor •() → wid::_HasCreationLocation*
+      : super dart.core::Object::•()
+      ;
+    abstract get _location() → wid::_Location*;
+  }
+  class _Location extends dart.core::Object /*hasConstConstructor*/  {
+    final field dart.core::String* file;
+    final field dart.core::int* line;
+    final field dart.core::int* column;
+    final field dart.core::String* name;
+    final field dart.core::List<wid::_Location*>* parameterLocations;
+    const constructor •({dart.core::String* file = #C1, dart.core::int* line = #C1, dart.core::int* column = #C1, dart.core::String* name = #C1, dart.core::List<wid::_Location*>* parameterLocations = #C1}) → wid::_Location*
+      : wid::_Location::file = file, wid::_Location::line = line, wid::_Location::column = column, wid::_Location::name = name, wid::_Location::parameterLocations = parameterLocations, super dart.core::Object::•()
+      ;
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+  import "package:flutter/src/widgets/widget_inspector.dart";
+
+  class Foo extends fra::Widget {
+    synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → main::Foo*
+      : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
+      ;
+  }
+}
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.2.expect
new file mode 100644
index 0000000..95a88d7
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.2.expect
@@ -0,0 +1,48 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  abstract class Bar extends dart.core::Object {
+    synthetic constructor •() → fra::Bar*
+      : super dart.core::Object::•()
+      ;
+  }
+  abstract class Widget extends fra::Bar implements wid::_HasCreationLocation {
+    final field wid::_Location* _location /* from null */;
+    synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → fra::Widget*
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+      ;
+  }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+  abstract class _HasCreationLocation extends dart.core::Object {
+    synthetic constructor •() → wid::_HasCreationLocation*
+      : super dart.core::Object::•()
+      ;
+    abstract get _location() → wid::_Location*;
+  }
+  class _Location extends dart.core::Object /*hasConstConstructor*/  {
+    final field dart.core::String* file;
+    final field dart.core::int* line;
+    final field dart.core::int* column;
+    final field dart.core::String* name;
+    final field dart.core::List<wid::_Location*>* parameterLocations;
+    const constructor •({dart.core::String* file = #C1, dart.core::int* line = #C1, dart.core::int* column = #C1, dart.core::String* name = #C1, dart.core::List<wid::_Location*>* parameterLocations = #C1}) → wid::_Location*
+      : wid::_Location::file = file, wid::_Location::line = line, wid::_Location::column = column, wid::_Location::name = name, wid::_Location::parameterLocations = parameterLocations, super dart.core::Object::•()
+      ;
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+  import "package:flutter/src/widgets/widget_inspector.dart";
+
+  class Foo extends fra::Widget {
+    synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → main::Foo*
+      : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
+      ;
+  }
+}
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
index 4a9ec12..4da97d9 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
@@ -212,7 +212,7 @@
     method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable<dart.core::int*>* iterable) → void {
       dart.core::int* i = this.{dart.core::List::length};
       {
-        dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(iterable).{dart.core::Iterable::iterator};
+        dart.core::Iterator<dart.core::int*>* :sync-for-iterator = iterable.{dart.core::Iterable::iterator};
         for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
           dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
           {
@@ -458,7 +458,7 @@
       }
       else {
         {
-          dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(iterable).{dart.core::Iterable::iterator};
+          dart.core::Iterator<dart.core::int*>* :sync-for-iterator = iterable.{dart.core::Iterable::iterator};
           for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
             dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
             {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
index 4a9ec12..4da97d9 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
@@ -212,7 +212,7 @@
     method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable<dart.core::int*>* iterable) → void {
       dart.core::int* i = this.{dart.core::List::length};
       {
-        dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(iterable).{dart.core::Iterable::iterator};
+        dart.core::Iterator<dart.core::int*>* :sync-for-iterator = iterable.{dart.core::Iterable::iterator};
         for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
           dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
           {
@@ -458,7 +458,7 @@
       }
       else {
         {
-          dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(iterable).{dart.core::Iterable::iterator};
+          dart.core::Iterator<dart.core::int*>* :sync-for-iterator = iterable.{dart.core::Iterable::iterator};
           for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
             dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
             {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
index b765c13..c3e26f0 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
@@ -5,8 +5,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -22,13 +22,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
@@ -48,8 +48,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -64,13 +64,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
index c5de17c..e864fa8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
@@ -5,8 +5,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -22,13 +22,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
@@ -48,8 +48,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -65,13 +65,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
index 42d7120..373b5c9 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
@@ -14,8 +14,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -30,21 +30,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -60,13 +60,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
index 418248d..b65715d 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
@@ -14,8 +14,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -30,21 +30,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -60,13 +60,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
index 13582f4..306cc91 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
@@ -14,8 +14,8 @@
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -31,21 +31,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
     dart.async::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -61,13 +61,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
 }
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..18f0b60
--- /dev/null
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+abstract class C {}
+
+abstract class D<T> {
+  D(T t);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1aba12d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+abstract class C {}
+
+abstract class D<T> {
+  D(T t);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/assert.dart.textual_outline.expect b/pkg/front_end/testcases/inference/assert.dart.textual_outline.expect
new file mode 100644
index 0000000..cdb201d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/assert.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/assert.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..bfa7fcc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  C.expressionOnly() : assert(f());
+  C.expressionAndMessage() : assert(f(), f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9871f1a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  C.expressionAndMessage() : assert(f(), f());
+  C.expressionOnly() : assert(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline.expect
new file mode 100644
index 0000000..dab01df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dab01df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
index ecb9078..cd1110d 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
@@ -15,8 +15,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -38,8 +38,8 @@
           final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
           asy::FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -52,21 +52,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test1() → asy::Future<core::int*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
           asy::FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -79,21 +79,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test2() → asy::Future<asy::Future<core::int*>*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<asy::Future<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<asy::Future<core::int*>*>();
           asy::FutureOr<asy::Future<core::int*>*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -106,21 +106,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test3() → asy::Future<asy::FutureOr<core::int*>*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<asy::FutureOr<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<asy::FutureOr<core::int*>*>();
           asy::FutureOr<asy::FutureOr<core::int*>*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -133,21 +133,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test4() → asy::Future<self::MyFuture*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<self::MyFuture*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::MyFuture*>();
           asy::FutureOr<self::MyFuture*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test5() → asy::Future<core::int*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
           asy::FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,21 +187,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test6() → asy::Future<asy::Future<core::int*>*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<asy::Future<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<asy::Future<core::int*>*>();
           asy::FutureOr<asy::Future<core::int*>*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -214,21 +214,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test7() → asy::Future<asy::FutureOr<core::int*>*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<asy::FutureOr<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<asy::FutureOr<core::int*>*>();
           asy::FutureOr<asy::FutureOr<core::int*>*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -241,21 +241,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test8() → asy::Future<self::MyFuture*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<self::MyFuture*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::MyFuture*>();
           asy::FutureOr<self::MyFuture*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -268,21 +268,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         function test9() → asy::Future<core::int*>* /* originally async */ {
           final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
           asy::FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -295,13 +295,13 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         [yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
@@ -328,13 +328,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_await.dart.textual_outline.expect
new file mode 100644
index 0000000..0ff2309
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyFuture implements Future<int> {}
+
+void test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..28c7ff1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyFuture implements Future<int> {}
+
+main() {}
+void test() async {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
index c587b4b..b9580fb 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -25,13 +25,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 };
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline.expect
new file mode 100644
index 0000000..2394f32
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+Future<int> futureInt = null;
+var f = () => futureInt;
+var g = () async => futureInt;
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..92b84b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+Future<int> futureInt = null;
+main() {}
+var f = () => futureInt;
+var g = () async => futureInt;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
index 69a4666..bd3ef80 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
@@ -7,8 +7,8 @@
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -21,13 +21,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 };
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline.expect
new file mode 100644
index 0000000..d5d8f30
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var f = () async => 0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95b148d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var f = () async => 0;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
index 13ab2d2..913d676 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -25,13 +25,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 };
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline.expect
new file mode 100644
index 0000000..acecf1d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+FutureOr<int> futureOrInt = null;
+var f = () => futureOrInt;
+var g = () async => futureOrInt;
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c8ad68a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+FutureOr<int> futureOrInt = null;
+main() {}
+var f = () => futureOrInt;
+var g = () async => futureOrInt;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
index 461478b..d0e8788 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
@@ -12,8 +12,8 @@
     final asy::_AsyncAwaitCompleter<core::num*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::num*>();
     asy::FutureOr<core::num*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -32,13 +32,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   asy::Future<core::num*>* g = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline.expect
new file mode 100644
index 0000000..2d20965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0962407
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
index 6675875..30eabe7 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
@@ -12,8 +12,8 @@
     final asy::_AsyncAwaitCompleter<core::num*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::num*>();
     asy::FutureOr<core::num*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -32,13 +32,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   asy::Future<core::num*>* g = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline.expect
new file mode 100644
index 0000000..2d20965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0962407
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
index 83d4912..cddac4a 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
@@ -12,8 +12,8 @@
     final asy::_AsyncAwaitCompleter<core::num*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::num*>();
     asy::FutureOr<core::num*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -32,13 +32,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   asy::Future<core::num*>* g = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline.expect
new file mode 100644
index 0000000..2d20965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0962407
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
index c640de2..a0abb09 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
     asy::_AsyncStarStreamController<core::num*>* :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -33,7 +33,7 @@
           }
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline.expect
new file mode 100644
index 0000000..242deb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8318b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..0a7258b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+String f() => null;
+var g = f;
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b7a3a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+String f() => null;
+main() {}
+var g = f;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
index 72c0762..b6a939d 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -23,8 +23,8 @@
           final asy::_AsyncAwaitCompleter<core::Null?>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
           asy::FutureOr<core::Null?>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -37,13 +37,13 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         asy::Future<dynamic>* y = f.call();
@@ -54,12 +54,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
index c810580..cd7251f 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -23,8 +23,8 @@
           asy::_AsyncStarStreamController<core::Null?>* :controller;
           dynamic :controller_stream;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           dynamic :saved_try_context_var0;
@@ -41,7 +41,7 @@
                 }
                 return;
               }
-              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                 :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
               }
             finally {
@@ -62,12 +62,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline.expect
new file mode 100644
index 0000000..4a1f36a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+var h = null;
+void foo(int f(Object _)) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1183aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+main() {}
+test() {}
+var h = null;
+void foo(int f(Object _)) {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline.expect
new file mode 100644
index 0000000..2d51ce5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math' show Random;
+
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02a9440
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math' show Random;
+
+main() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bottom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bottom.dart.textual_outline.expect
new file mode 100644
index 0000000..3a3a838
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bottom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bottom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..513df85
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var v = null;
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..5c8173a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var v = () => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..09b085b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var v = () => null;
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline.expect
new file mode 100644
index 0000000..8c82e9b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+  final x;
+  C(int p) : x = f(1 + p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a9f43dc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+  C(int p) : x = f(1 + p);
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline.expect
new file mode 100644
index 0000000..fec1eb3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+  final String foo;
+  A(this.foo);
+  bool operator ==(Object other) => other is A && other.foo == this.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0fcdf5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+  A(this.foo);
+  bool operator ==(Object other) => other is A && other.foo == this.foo;
+  final String foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline.expect
new file mode 100644
index 0000000..503a2af
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+  final String foo;
+  A(this.foo);
+  bool operator ==(Object other) =>
+      other is A && other.foo == this.foo && other.foo == this.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..329f32b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+  A(this.foo);
+  bool operator ==(Object other) =>
+      other is A && other.foo == this.foo && other.foo == this.foo;
+  final String foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline.expect
new file mode 100644
index 0000000..42c642b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+  final String foo;
+  A(this.foo);
+  bool operator ==(Object other) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ecf601
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+  A(this.foo);
+  bool operator ==(Object other) {}
+  final String foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline.expect
new file mode 100644
index 0000000..ce7f4b7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+String foo(obj) => obj is String ? obj.toUpperCase() : null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ce7f4b7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+String foo(obj) => obj is String ? obj.toUpperCase() : null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline.expect
new file mode 100644
index 0000000..2224470
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+void foo<E>(C<E> c, int cmp(E a, E b)) {}
+
+class C<E> {
+  void barA([int cmp(E a, E b)]) {}
+  void barB([int cmp(E a, E b)]) {}
+  void barC([int cmp(E a, E b)]) {}
+  void barD([int cmp(E a, E b)]) {}
+  void barE([int cmp(E a, E b)]) {}
+  void barF([int cmp(E a, E b)]) {}
+  static int _default(a, b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb56b97
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class C<E> {
+  static int _default(a, b) {}
+  void barA([int cmp(E a, E b)]) {}
+  void barB([int cmp(E a, E b)]) {}
+  void barC([int cmp(E a, E b)]) {}
+  void barD([int cmp(E a, E b)]) {}
+  void barE([int cmp(E a, E b)]) {}
+  void barF([int cmp(E a, E b)]) {}
+}
+
+main() {}
+void foo<E>(C<E> c, int cmp(E a, E b)) {}
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline.expect
new file mode 100644
index 0000000..977a33d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class B {}
+
+class C extends B {
+  var z;
+}
+
+void test(B x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b742b0c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class B {}
+
+class C extends B {
+  var z;
+}
+
+main() {}
+void test(B x) {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline.expect
new file mode 100644
index 0000000..eaa5347
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void block_test() {}
+void arrow_test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b6b538
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void arrow_test() {}
+void block_test() {}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/bug33324.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline.expect
new file mode 100644
index 0000000..b085311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+int foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug33324.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b085311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+int foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline.expect
new file mode 100644
index 0000000..48e6f56
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+  int call() => 0;
+}
+
+class B {
+  A get call => new A();
+}
+
+class D {
+  A fieldA = new A();
+  A get getA => new A();
+  B fieldB = new B();
+  B get getB => new B();
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..73709ae
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+  int call() => 0;
+}
+
+class B {
+  A get call => new A();
+}
+
+class D {
+  A fieldA = new A();
+  A get getA => new A();
+  B fieldB = new B();
+  B get getB => new B();
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline.expect
new file mode 100644
index 0000000..0114b01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class ActionDispatcher<P> {
+  void call([P value]) {}
+}
+
+class Bar {}
+
+class FooActions {
+  ActionDispatcher<Bar> get foo => new ActionDispatcher<Bar>();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0114b01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class ActionDispatcher<P> {
+  void call([P value]) {}
+}
+
+class Bar {}
+
+class FooActions {
+  ActionDispatcher<Bar> get foo => new ActionDispatcher<Bar>();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..10f2489
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A extends B {
+  f(x);
+}
+
+abstract class B extends A {
+  f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10f2489
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A extends B {
+  f(x);
+}
+
+abstract class B extends A {
+  f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
index d1e47f9..189aa8d 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
@@ -9,6 +9,6 @@
 //
 import self as self;
 
-static field invalid-type x = (() → () →* invalid-type => self::y) as{TypeError} invalid-type;
+static field invalid-type x = () → () →* invalid-type => self::y;
 static field () →* invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
index d1e47f9..189aa8d 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
@@ -9,6 +9,6 @@
 //
 import self as self;
 
-static field invalid-type x = (() → () →* invalid-type => self::y) as{TypeError} invalid-type;
+static field invalid-type x = () → () →* invalid-type => self::y;
 static field () →* invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline.expect
new file mode 100644
index 0000000..34a8c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+var x = () => y;
+var y = () => x;
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1be8547
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var x = () => y;
+var y = () => x;
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
index 758e00e..2439199 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
@@ -9,6 +9,6 @@
 //
 import self as self;
 
-static field invalid-type x = (() → () →* invalid-type => self::y) as{TypeError} invalid-type;
+static field invalid-type x = () → () →* invalid-type => self::y;
 static field () →* invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
index 758e00e..2439199 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
@@ -9,6 +9,6 @@
 //
 import self as self;
 
-static field invalid-type x = (() → () →* invalid-type => self::y) as{TypeError} invalid-type;
+static field invalid-type x = () → () →* invalid-type => self::y;
 static field () →* invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline.expect
new file mode 100644
index 0000000..34a8c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+var x = () => y;
+var y = () => x;
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1be8547
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var x = () => y;
+var y = () => x;
diff --git a/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline.expect b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline.expect b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline.expect
new file mode 100644
index 0000000..8dcdc49
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool b = true;
+int x = 0;
+double y = 0.0;
+var z = b ? x : y;
+main() {}
diff --git a/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c98a8f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool b = true;
+double y = 0.0;
+int x = 0;
+main() {}
+var z = b ? x : y;
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..65185f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  C(List<T> x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65185f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  C(List<T> x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..411a1c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A {
+  dynamic field1;
+  int field2;
+}
+
+class I {
+  int field1;
+  dynamic field2;
+}
+
+class B extends A implements I {
+  get field1 => null;
+  get field2 => null;
+  set field1(value) {}
+  set field2(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..145da2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A {
+  dynamic field1;
+  int field2;
+}
+
+class B extends A implements I {
+  get field1 => null;
+  get field2 => null;
+  set field1(value) {}
+  set field2(value) {}
+}
+
+class I {
+  dynamic field2;
+  int field1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline.expect
new file mode 100644
index 0000000..0cae63c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+class I1 {
+  int x;
+}
+
+class I2 extends I1 {
+  int y;
+}
+
+class A {
+  final I1 a = null;
+}
+
+class B {
+  final I2 a = null;
+}
+
+class C1 implements A, B {
+  get a => null;
+}
+
+class C2 implements B, A {
+  get a => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fbcfeb5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+library test;
+
+class A {
+  final I1 a = null;
+}
+
+class B {
+  final I2 a = null;
+}
+
+class C1 implements A, B {
+  get a => null;
+}
+
+class C2 implements B, A {
+  get a => null;
+}
+
+class I1 {
+  int x;
+}
+
+class I2 extends I1 {
+  int y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline.expect
new file mode 100644
index 0000000..99ab361
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline.expect
@@ -0,0 +1,32 @@
+library test;
+
+class I1 {
+  int x;
+}
+
+class I2 {
+  int y;
+}
+
+class I3 implements I1, I2 {
+  int x;
+  int y;
+}
+
+class A {
+  final I1 a = null;
+}
+
+class B {
+  final I2 a = null;
+}
+
+class C1 implements A, B {
+  I3 get a => null;
+}
+
+class C2 implements A, B {
+  get a => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae75406
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline_modelled.expect
@@ -0,0 +1,32 @@
+library test;
+
+class A {
+  final I1 a = null;
+}
+
+class B {
+  final I2 a = null;
+}
+
+class C1 implements A, B {
+  I3 get a => null;
+}
+
+class C2 implements A, B {
+  get a => null;
+}
+
+class I1 {
+  int x;
+}
+
+class I2 {
+  int y;
+}
+
+class I3 implements I1, I2 {
+  int x;
+  int y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline.expect
new file mode 100644
index 0000000..3317fee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {}
+
+class B extends A {}
+
+class Foo<T extends A> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3317fee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {}
+
+class B extends A {}
+
+class Foo<T extends A> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..e5bb6f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+  T t;
+  C(this.t);
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..413457c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+  C(this.t);
+  T t;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline.expect
new file mode 100644
index 0000000..5cd2e23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class A {}
+
+typedef T F<T>();
+
+class C<T extends A> {
+  C(F<T> f);
+}
+
+class NotA {}
+
+NotA myF() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b220a27
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+NotA myF() => null;
+
+class A {}
+
+class C<T extends A> {
+  C(F<T> f);
+}
+
+class NotA {}
+
+main() {}
+typedef T F<T>();
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline.expect
new file mode 100644
index 0000000..a3c6d99
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  final T t;
+  const C(this.t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d6c509
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  const C(this.t);
+  final T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..228e705
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T extends num> {
+  final T x;
+  const C(this.x);
+}
+
+class D<T extends num> {
+  const D();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df658a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T extends num> {
+  const C(this.x);
+  final T x;
+}
+
+class D<T extends num> {
+  const D();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..af80416
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  C(List<T> list);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..af80416
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  C(List<T> list);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..6328816
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  T t;
+  C._();
+  factory C(T t) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..33f4f60
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C._();
+  T t;
+  factory C(T t) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..e3c1708
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A<T> {
+  A<T> f = new A();
+  A();
+  factory A.factory() => new A();
+  A<T> m() => new A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f3f4f5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A<T> {
+  A();
+  A<T> f = new A();
+  A<T> m() => new A();
+  factory A.factory() => new A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline.expect
new file mode 100644
index 0000000..7dd7722
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  T t;
+  C.named(List<T> t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..93750d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  C.named(List<T> t);
+  T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..6019b7f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+  T t;
+  C();
+  factory C.named(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5970e4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+  C();
+  T t;
+  factory C.named(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline.expect
new file mode 100644
index 0000000..ca7d831
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+  T t;
+  C(this.t);
+  C.named(List<T> t) : this(t[0]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..010a7db
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+  C(this.t);
+  C.named(List<T> t) : this(t[0]);
+  T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..86de0c0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> {
+  T get t;
+  void set t(T x);
+  factory C(T t) = CImpl<T>;
+}
+
+class CImpl<T> implements C<T> {
+  T t;
+  CImpl(this.t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8bc935e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> {
+  T get t;
+  factory C(T t) = CImpl<T>;
+  void set t(T x);
+}
+
+class CImpl<T> implements C<T> {
+  CImpl(this.t);
+  T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..f75f8c2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class C<T> {
+  T get t;
+  void set t(T x);
+  factory C(T t) = CImpl<T>;
+}
+
+class CImpl<T> implements C<T> {
+  T t;
+  CImpl._(this.t);
+  factory CImpl(T t) => new CImpl._(t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2ee205e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class C<T> {
+  T get t;
+  factory C(T t) = CImpl<T>;
+  void set t(T x);
+}
+
+class CImpl<T> implements C<T> {
+  CImpl._(this.t);
+  T t;
+  factory CImpl(T t) => new CImpl._(t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline.expect
new file mode 100644
index 0000000..9663430
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Cloneable<T> {}
+
+class Pair<T extends Cloneable<T>, U extends Cloneable<U>> {
+  T t;
+  U u;
+  Pair(this.t, this.u);
+  Pair._();
+  Pair<U, T> get reversed => new Pair(u, t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd68431
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Cloneable<T> {}
+
+class Pair<T extends Cloneable<T>, U extends Cloneable<U>> {
+  Pair(this.t, this.u);
+  Pair._();
+  Pair<U, T> get reversed => new Pair(u, t);
+  T t;
+  U u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..08b5285
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class Pair<T, U> {
+  T t;
+  U u;
+  Pair(this.t, this.u);
+  Pair<U, T> get reversed => new Pair(u, t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..32b945d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class Pair<T, U> {
+  Pair(this.t, this.u);
+  Pair<U, T> get reversed => new Pair(u, t);
+  T t;
+  U u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..d3ee256
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+class A<T> {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a4a2d50
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+class A<T> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline.expect
new file mode 100644
index 0000000..27f0e71
--- /dev/null
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  final int x = 2;
+}
+
+class B implements A {
+  dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27f0e71
--- /dev/null
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  final int x = 2;
+}
+
+class B implements A {
+  dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline.expect
new file mode 100644
index 0000000..0114cbd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+var x = null;
+var y = 3;
+
+class A {
+  static var x = null;
+  static var y = 3;
+  var x2 = null;
+  var y2 = 3;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..295e0ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  static var x = null;
+  static var y = 3;
+  var x2 = null;
+  var y2 = 3;
+}
+
+main() {}
+var x = null;
+var y = 3;
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..1e0f033
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math';
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e0f033
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math';
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline.expect
new file mode 100644
index 0000000..f36fe08
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+typedef T Function2<S, T>(S x);
+
+class A<T> {
+  Function2<T, T> x;
+  A(this.x);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..697ff80
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+  A(this.x);
+  Function2<T, T> x;
+}
+
+typedef T Function2<S, T>(S x);
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline.expect
new file mode 100644
index 0000000..16ed9ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+  Iterable<String> get foo;
+}
+
+class B implements A {
+  final foo = const [];
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16ed9ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+  Iterable<String> get foo;
+}
+
+class B implements A {
+  final foo = const [];
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline.expect
new file mode 100644
index 0000000..fb5daf2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+  const Foo.named(List<String> l);
+}
+
+@Foo(const [])
+class Bar {}
+
+@Foo.named(const [])
+class Baz {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..af71307
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+@Foo(const [])
+class Bar {}
+
+@Foo.named(const [])
+class Baz {}
+
+class Foo {
+  const Foo(List<String> l);
+  const Foo.named(List<String> l);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline.expect
new file mode 100644
index 0000000..3cc94f4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+abstract class Bar {
+  @Foo(const [])
+  Bar();
+  @Foo(const [])
+  var x;
+  @Foo(const [])
+  void f();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..900fab8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class Bar {
+  @Foo(const [])
+  Bar();
+  @Foo(const [])
+  var x;
+  @Foo(const [])
+  void f();
+}
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect
index 41a115e..c81fe3a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library test;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Foo extends core::Object /*hasConstConstructor*/  {
   const constructor •(core::List<core::String*>* l) → self::Foo*
@@ -12,7 +11,7 @@
   for (@#C1 core::int* i = 0; i.{core::num::<}(1); i = i.{core::num::+}(1)) {
   }
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[0]).{core::Iterable::iterator};
+    core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[0].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       @#C1 core::int* i = :sync-for-iterator.{core::Iterator::current};
       {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline.expect
new file mode 100644
index 0000000..45f63cd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(dynamic l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..109def4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(dynamic l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..85424cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+void f(@Foo(const []) x) {}
+
+class C {
+  void m(@Foo(const []) x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3d34b57
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C {
+  void m(@Foo(const []) x) {}
+}
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
+void f(@Foo(const []) x) {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..fdc2d82
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+class C<@Foo(const []) T> {}
+
+typedef void F<@Foo(const []) T>();
+void f<@Foo(const []) T>() {}
+
+class D {
+  void m<@Foo(const []) T>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..26f3f04
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C<@Foo(const []) T> {}
+
+class D {
+  void m<@Foo(const []) T>() {}
+}
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
+typedef void F<@Foo(const []) T>();
+void f<@Foo(const []) T>() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..e7416ab
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+@Foo(const [])
+typedef void F();
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b53595
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+@Foo(const [])
+typedef void F();
+
+class Foo {
+  const Foo(List<String> l);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
index 92361c9..1ab4c3c 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -28,12 +28,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline.expect
new file mode 100644
index 0000000..122c5de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+Future main() async {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..122c5de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+Future main() async {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
index f95b190..99eb58d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
@@ -16,8 +16,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -31,28 +31,28 @@
         dynamic d;
         core::Object* o;
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::F<core::Iterable<dynamic>*>()).{core::Iterable::iterator};
+          core::Iterator<dynamic>* :sync-for-iterator = self::F<core::Iterable<dynamic>*>().{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             dynamic x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::F<core::Iterable<dynamic>*>()).{core::Iterable::iterator};
+          core::Iterator<dynamic>* :sync-for-iterator = self::F<core::Iterable<dynamic>*>().{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             dynamic x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          core::Iterator<core::Object*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Object*>*>(self::F<core::Iterable<core::Object*>*>()).{core::Iterable::iterator};
+          core::Iterator<core::Object*>* :sync-for-iterator = self::F<core::Iterable<core::Object*>*>().{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             core::Object* x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::F<core::Iterable<dynamic>*>()).{core::Iterable::iterator};
+          core::Iterator<dynamic>* :sync-for-iterator = self::F<core::Iterable<dynamic>*>().{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final dynamic #t1 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -61,7 +61,7 @@
           }
         }
         {
-          core::Iterator<core::Object*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::Object*>*>(self::F<core::Iterable<core::Object*>*>()).{core::Iterable::iterator};
+          core::Iterator<core::Object*>* :sync-for-iterator = self::F<core::Iterable<core::Object*>*>().{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final core::Object* #t2 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -70,7 +70,7 @@
           }
         }
         {
-          dynamic :stream = self::F<asy::Stream<dynamic>*>();
+          asy::Stream<dynamic>* :stream = self::F<asy::Stream<dynamic>*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -92,7 +92,7 @@
             }
         }
         {
-          dynamic :stream = self::F<asy::Stream<dynamic>*>();
+          asy::Stream<dynamic>* :stream = self::F<asy::Stream<dynamic>*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -114,7 +114,7 @@
             }
         }
         {
-          dynamic :stream = self::F<asy::Stream<core::Object*>*>();
+          asy::Stream<core::Object*>* :stream = self::F<asy::Stream<core::Object*>*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::Object*>* :for-iterator = new asy::_StreamIterator::•<core::Object*>(:stream);
           try
@@ -136,7 +136,7 @@
             }
         }
         {
-          dynamic :stream = self::F<asy::Stream<dynamic>*>();
+          asy::Stream<dynamic>* :stream = self::F<asy::Stream<dynamic>*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -160,7 +160,7 @@
             }
         }
         {
-          dynamic :stream = self::F<asy::Stream<core::Object*>*>();
+          asy::Stream<core::Object*>* :stream = self::F<asy::Stream<core::Object*>*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::Object*>* :for-iterator = new asy::_StreamIterator::•<core::Object*>(:stream);
           try
@@ -187,21 +187,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → asy::Future<dynamic>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -213,28 +213,28 @@
       #L7:
       {
         {
-          core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+          core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             core::int* x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          core::Iterator<core::num*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::num*>*>(<core::num*>[1, 2, 3]).{core::Iterable::iterator};
+          core::Iterator<core::num*>* :sync-for-iterator = <core::num*>[1, 2, 3].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             core::num* x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3]).{core::Iterable::iterator};
+          core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             core::int* x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          dynamic :stream = self::MyStream::•<core::int*>();
+          self::MyStream<core::int*>* :stream = self::MyStream::•<core::int*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
@@ -256,7 +256,7 @@
             }
         }
         {
-          dynamic :stream = self::MyStream::•<core::int*>();
+          self::MyStream<core::int*>* :stream = self::MyStream::•<core::int*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
@@ -281,12 +281,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline.expect
new file mode 100644
index 0000000..f7b4524
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyStream<T> extends Stream<T> {
+  factory MyStream() => null;
+}
+
+T F<T>() => null;
+Future f() async {}
+Future main() async {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..305c039
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+Future f() async {}
+Future main() async {}
+T F<T>() => null;
+
+abstract class MyStream<T> extends Stream<T> {
+  factory MyStream() => null;
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline.expect
new file mode 100644
index 0000000..af6edf3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef T Function2<S, T>([S x]);
+
+class Foo {
+  List<int> x;
+  Foo([this.x = const [1]]);
+  Foo.named([List<int> x = const [1]]);
+}
+
+void f([List<int> l = const [1]]) {}
+Function2<List<int>, String> g = ([llll = const [1]]) => "hello";
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ca9e3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+Function2<List<int>, String> g = ([llll = const [1]]) => "hello";
+
+class Foo {
+  Foo([this.x = const [1]]);
+  Foo.named([List<int> x = const [1]]);
+  List<int> x;
+}
+
+main() {}
+typedef T Function2<S, T>([S x]);
+void f([List<int> l = const [1]]) {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..1425d39
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  B<int> b;
+}
+
+class B<T> {
+  B(T x);
+}
+
+var t1 = new A()..b = new B(1);
+var t2 = <B<int>>[new B(2)];
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ac056b3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  B<int> b;
+}
+
+class B<T> {
+  B(T x);
+}
+
+main() {}
+var t1 = new A()..b = new B(1);
+var t2 = <B<int>>[new B(2)];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline.expect
new file mode 100644
index 0000000..0c60385
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+  A(T x);
+}
+
+var t1 = <A<int>>[new A(1)];
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..84d90fc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+  A(T x);
+}
+
+main() {}
+var t1 = <A<int>>[new A(1)];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..df0025f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0 {
+  F0(List<int> a) {}
+}
+
+class F1 {
+  F1({List<int> a}) {}
+}
+
+class F2 {
+  F2(Iterable<int> a) {}
+}
+
+class F3 {
+  F3(Iterable<Iterable<int>> a) {}
+}
+
+class F4 {
+  F4({Iterable<Iterable<int>> a}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e349236
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0 {
+  F0(List<int> a) {}
+}
+
+class F1 {
+  F1({List<int> a}) {}
+}
+
+class F2 {
+  F2(Iterable<int> a) {}
+}
+
+class F3 {
+  F3(Iterable<Iterable<int>> a) {}
+}
+
+class F4 {
+  F4({Iterable<Iterable<int>> a}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..48d5e7a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+void f0(List<int> a) {}
+void f1({List<int> a}) {}
+void f2(Iterable<int> a) {}
+void f3(Iterable<Iterable<int>> a) {}
+void f4({Iterable<Iterable<int>> a}) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1799ee7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+main() {}
+void f0(List<int> a) {}
+void f1({List<int> a}) {}
+void f2(Iterable<int> a) {}
+void f3(Iterable<Iterable<int>> a) {}
+void f4({Iterable<Iterable<int>> a}) {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..c66b28f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef T Function2<S, T>(S x);
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..894e031
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+typedef T Function2<S, T>(S x);
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline.expect
new file mode 100644
index 0000000..a13b45e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class F3<T> {
+  F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+  F4({Iterable<Iterable<T>> a}) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a13b45e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class F3<T> {
+  F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+  F4({Iterable<Iterable<T>> a}) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..3906f3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0<T> {
+  F0(List<T> a) {}
+}
+
+class F1<T> {
+  F1({List<T> a}) {}
+}
+
+class F2<T> {
+  F2(Iterable<T> a) {}
+}
+
+class F3<T> {
+  F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+  F4({Iterable<Iterable<T>> a}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e9d27b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0<T> {
+  F0(List<T> a) {}
+}
+
+class F1<T> {
+  F1({List<T> a}) {}
+}
+
+class F2<T> {
+  F2(Iterable<T> a) {}
+}
+
+class F3<T> {
+  F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+  F4({Iterable<Iterable<T>> a}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..8ed5bad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+library test;
+
+class A<S, T> {
+  S x;
+  T y;
+  A(this.x, this.y);
+  A.named(this.x, this.y);
+}
+
+class B<S, T> extends A<T, S> {
+  B(S y, T x) : super(x, y);
+  B.named(S y, T x) : super.named(x, y);
+}
+
+class C<S> extends B<S, S> {
+  C(S a) : super(a, a);
+  C.named(S a) : super.named(a, a);
+}
+
+class D<S, T> extends B<T, int> {
+  D(T a) : super(a, 3);
+  D.named(T a) : super.named(a, 3);
+}
+
+class E<S, T> extends A<C<S>, T> {
+  E(T a) : super(null, a);
+}
+
+class F<S, T> extends A<S, T> {
+  F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
+  F.named(S x, T y, [S a, T b]) : super(a, b);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b73942e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+library test;
+
+class A<S, T> {
+  A(this.x, this.y);
+  A.named(this.x, this.y);
+  S x;
+  T y;
+}
+
+class B<S, T> extends A<T, S> {
+  B(S y, T x) : super(x, y);
+  B.named(S y, T x) : super.named(x, y);
+}
+
+class C<S> extends B<S, S> {
+  C(S a) : super(a, a);
+  C.named(S a) : super.named(a, a);
+}
+
+class D<S, T> extends B<T, int> {
+  D(T a) : super(a, 3);
+  D.named(T a) : super.named(a, 3);
+}
+
+class E<S, T> extends A<C<S>, T> {
+  E(T a) : super(null, a);
+}
+
+class F<S, T> extends A<S, T> {
+  F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
+  F.named(S x, T y, [S a, T b]) : super(a, b);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..428644a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void foo([List<String> list1 = const [], List<String> list2 = const [42]]) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..428644a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+void foo([List<String> list1 = const [], List<String> list2 = const [42]]) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline.expect
new file mode 100644
index 0000000..96844fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+library test;
+
+class DartType {}
+
+typedef void Asserter<T>(T type);
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+
+abstract class C {
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf =>
+      null;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+}
+
+abstract class G<T> {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+}
+
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf => null;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..559999a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+library test;
+
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf => null;
+
+abstract class C {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf =>
+      null;
+}
+
+abstract class G<T> {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+}
+
+class DartType {}
+
+main() {}
+test() {}
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+typedef void Asserter<T>(T type);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..423bbf0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+void foo(
+    [Map<int, String> m1 = const {1: "hello"},
+    Map<int, String> m2 = const {"hello": "world"}]) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e39c4b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+void foo(
+    [Map<int, String> m1 = const {1: "hello"},
+    Map<int, String> m2 = const {"hello": "world"}]) {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
index b784630..1dc5905 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
@@ -40,8 +40,8 @@
   asy::_AsyncStarStreamController<core::List<core::int*>*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -78,7 +78,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline.expect
new file mode 100644
index 0000000..579e9aa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyStream<T> extends Stream<T> {
+  factory MyStream() => null;
+}
+
+Stream<List<int>> foo() async* {}
+Iterable<Map<int, int>> bar() sync* {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca60c6e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+Iterable<Map<int, int>> bar() sync* {}
+Stream<List<int>> foo() async* {}
+
+abstract class MyStream<T> extends Stream<T> {
+  factory MyStream() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..d2690b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  int foo(int x) => x;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..441f1e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  int foo(int x) => x;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline.expect
new file mode 100644
index 0000000..5834483
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  final int x;
+  C() : x = f();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c0625ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  C() : x = f();
+  final int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline.expect
new file mode 100644
index 0000000..f06b5ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+T f<T>() => null;
+
+class C implements B {
+  final x;
+  C() : x = f();
+}
+
+abstract class B {
+  int get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c75d5e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+T f<T>() => null;
+
+abstract class B {
+  int get x;
+}
+
+class C implements B {
+  C() : x = f();
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline.expect
new file mode 100644
index 0000000..b7af1b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  final int x;
+  C() : this.x = f();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1c779c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  C() : this.x = f();
+  final int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..94b8c9a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+  final x;
+  C(int p) : x = f(p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8596052
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+  C(int p) : x = f(p);
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..77eff22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  final x = _x;
+  static int get _x => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77eff22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  final x = _x;
+  static int get _x => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..66535ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  final x = y;
+}
+
+int get y => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66535ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  final x = y;
+}
+
+int get y => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
index 2bc7b4c..525b2c0 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
@@ -8,8 +8,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -22,14 +22,14 @@
       {
         core::Object* o;
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(o as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
+          core::Iterator<dynamic>* :sync-for-iterator = (o as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             dynamic x = :sync-for-iterator.{core::Iterator::current};
             {}
           }
         }
         {
-          dynamic :stream = o as{TypeError} asy::Stream<dynamic>*;
+          asy::Stream<dynamic>* :stream = o as{TypeError} asy::Stream<dynamic>*;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -52,7 +52,7 @@
         }
         core::int* y;
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(o as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
+          core::Iterator<dynamic>* :sync-for-iterator = (o as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -61,7 +61,7 @@
           }
         }
         {
-          dynamic :stream = o as{TypeError} asy::Stream<dynamic>*;
+          asy::Stream<dynamic>* :stream = o as{TypeError} asy::Stream<dynamic>*;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -88,13 +88,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline.expect
new file mode 100644
index 0000000..178286b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4791aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect
index a5c5985..bda8d12 100644
--- a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect
@@ -1,11 +1,10 @@
 library test;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method test(core::List<core::num*>* nums) → void {
   {
-    core::Iterator<core::num*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::num*>*>(nums).{core::Iterable::iterator};
+    core::Iterator<core::num*>* :sync-for-iterator = nums.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::num* x = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..9d1fb80
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(List<num> nums) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7c5b5b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(List<num> nums) {}
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline.expect
new file mode 100644
index 0000000..553900b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+void add(int x) {}
+add2(int y) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..98466bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+add2(int y) {}
+main() {}
+test() {}
+void add(int x) {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index 48ef203..1c08fc3 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -46,21 +46,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -75,21 +75,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -102,21 +102,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -129,13 +129,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
@@ -146,8 +146,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,13 +187,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
 }
diff --git a/pkg/front_end/testcases/inference/future_then.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index a340d04..b4d284b 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -46,21 +46,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -75,21 +75,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -102,21 +102,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -129,13 +129,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3));
@@ -146,8 +146,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,13 +187,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
 }
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
index 61dc898..d3bd398 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -46,21 +46,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -75,21 +75,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -102,21 +102,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -129,13 +129,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
@@ -146,8 +146,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,13 +187,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
 }
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
index 36e80aa..24a4359 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -46,21 +46,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -75,21 +75,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -102,21 +102,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -129,13 +129,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3));
@@ -146,8 +146,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,13 +187,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
 }
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
index 9d8eb63..282f036 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -46,21 +46,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -75,21 +75,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -102,21 +102,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -129,13 +129,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3));
@@ -146,8 +146,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,13 +187,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
 }
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
index 9efbea1..fd93688 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -46,21 +46,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -75,21 +75,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -102,21 +102,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -129,13 +129,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
@@ -146,8 +146,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -160,21 +160,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -187,13 +187,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
 }
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
index c53bad4..0ec550c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -53,21 +53,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -82,13 +82,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
index 20f8e91..e3e191c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -53,21 +53,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -82,13 +82,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
index 2be73df..aaf989c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -53,21 +53,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -82,13 +82,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
index ab579f5..d767998 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -53,21 +53,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -82,13 +82,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
index f68b46e..0702c99 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -53,21 +53,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -82,13 +82,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
index a7f2f7a..7a8790e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -53,21 +53,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -82,13 +82,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline.expect
new file mode 100644
index 0000000..242deb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8318b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline.expect
new file mode 100644
index 0000000..64e9564
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import "dart:async";
+
+m1() {}
+m2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..64e9564
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import "dart:async";
+
+m1() {}
+m2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index 9d9e7dc..8f10629 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -54,21 +54,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -83,13 +83,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* => (let final core::int* #t5 = x in #t5.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t5) as{TypeError} asy::FutureOr<core::int*>*);
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..7170757
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void main() {}
+MyFuture foo() => new MyFuture<int>.value(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca061ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'dart:async';
+
+MyFuture foo() => new MyFuture<int>.value(1);
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline.expect
new file mode 100644
index 0000000..7170757
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void main() {}
+MyFuture foo() => new MyFuture<int>.value(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca061ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'dart:async';
+
+MyFuture foo() => new MyFuture<int>.value(1);
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline.expect
new file mode 100644
index 0000000..50e61e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+Future foo() => new Future<int>.value(1);
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96a1287b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+import 'dart:async';
+
+Future foo() => new Future<int>.value(1);
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline.expect
new file mode 100644
index 0000000..242deb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8318b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
index 0c1809a..e8d3a2b 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
@@ -27,8 +27,8 @@
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -41,21 +41,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,21 +68,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -96,13 +96,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline.expect
new file mode 100644
index 0000000..8c3a854
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new Future.value(42);
+Future<int> g3(bool x) async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c118a02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new Future.value(42);
+Future<int> g3(bool x) async {}
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
index 1812257..d51f046 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
@@ -27,8 +27,8 @@
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -41,21 +41,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -68,21 +68,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
   asy::FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -96,13 +96,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline.expect
new file mode 100644
index 0000000..159bf6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(x) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new MyFuture.value(42);
+Future<int> g3(bool x) async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13e1b1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new MyFuture.value(42);
+Future<int> g3(bool x) async {}
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(x) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
index 829fcb3..c45e377 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -41,8 +41,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -55,21 +55,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -82,13 +82,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..93f6f0d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+MyFuture f;
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef4133f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+MyFuture f;
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
index a99851d..90cc080 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -44,21 +44,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -71,13 +71,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline.expect
new file mode 100644
index 0000000..5d93ae7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+MyFuture f;
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0a80cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+MyFuture f;
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
index 585b9a59..4e9ddea 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -41,8 +41,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -55,21 +55,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -82,13 +82,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline.expect
new file mode 100644
index 0000000..b9a2d35
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future f;
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9307472
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future f;
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
index 7448b01..b54c92f 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
@@ -30,8 +30,8 @@
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -44,21 +44,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
   asy::FutureOr<core::List<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -71,13 +71,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline.expect
new file mode 100644
index 0000000..cf8d63e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  dynamic noSuchMethod(invocation) => null;
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future f;
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3d8b7c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future f;
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([x]) {}
+  MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+  dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
index 69f42e3..fad67c5 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
@@ -15,8 +15,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -32,13 +32,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline.expect
new file mode 100644
index 0000000..ff812a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:async';
+
+foo() async {}
+
+class A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13d8da5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+class A {}
+
+foo() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
index ce99844..fce1d5c 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
@@ -12,8 +12,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -28,13 +28,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline.expect
new file mode 100644
index 0000000..f2493de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+T id<T>(T x) => x;
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b74ebd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+T id<T>(T x) => x;
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
index c71cd17..6e13ec4 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
@@ -25,8 +25,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -47,12 +47,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..b625587
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0cb32a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
index fc34967..6c34434 100644
--- a/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
     asy::_AsyncStarStreamController<core::int*>* :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -33,7 +33,7 @@
           }
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..d7b3836
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+void foo(Stream<int> Function() values) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7b3836
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+void foo(Stream<int> Function() values) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..7213e8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef void ToValue<T>(T value);
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..97bb62099
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef void ToValue<T>(T value);
diff --git a/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..c2ccf15
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+T f<S, T>(S s) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2ccf15
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+T f<S, T>(S s) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..c453bac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Foo<T extends Pattern> {
+  U method<U extends T>(U u) => u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c453bac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Foo<T extends Pattern> {
+  U method<U extends T>(U u) => u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline.expect
new file mode 100644
index 0000000..b914263
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:math';
+
+void printInt(int x) => print(x);
+void printDouble(double x) => print(x);
+num myMax(num x, num y) => max(x, y);
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d493668
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:math';
+
+f() {}
+main() {}
+num myMax(num x, num y) => max(x, y);
+void printDouble(double x) => print(x);
+void printInt(int x) => print(x);
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect
index 1e35606..a0717bb 100644
--- a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect
@@ -39,8 +39,8 @@
     return x;
 }
 static method main() → dynamic {
-  core::int* y = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:18:74: Error: Expected 0 type arguments.
+  core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:18:74: Error: Expected 0 type arguments.
       . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ m<int>(
-                                                                         ^" in new self::D::•().{self::D::m}<core::int*>(42)) as{TypeError} core::int*;
+                                                                         ^" in new self::D::•().{self::D::m}<core::int*>(42);
   core::print(y);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline.expect
new file mode 100644
index 0000000..2f8aafa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  T m<T>(T x) => x;
+}
+
+class D extends C {
+  m(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f8aafa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  T m<T>(T x) => x;
+}
+
+class D extends C {
+  m(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..f93fc4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>(List<T> s) => null;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8caec4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>(List<T> s) => null;
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline.expect
new file mode 100644
index 0000000..0fedf11
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void test() {}
+void functionExpressionInvocation() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fbb56e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void functionExpressionInvocation() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..9964182
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class C {
+  m(x) => x;
+  dynamic g(int x) => x;
+}
+
+class D extends C {
+  T m<T>(T x) => x;
+  T g<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c3f4d33
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class C {
+  dynamic g(int x) => x;
+  m(x) => x;
+}
+
+class D extends C {
+  T g<T>(T x) => x;
+  T m<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline.expect
new file mode 100644
index 0000000..9702395
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+  f<U>(x) {}
+}
+
+class D<T> {
+  F<U> f<U>(U u) => null;
+}
+
+typedef void F<V>(V v);
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..445c8d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+  f<U>(x) {}
+}
+
+class D<T> {
+  F<U> f<U>(U u) => null;
+}
+
+main() {}
+typedef void F<V>(V v);
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline.expect
new file mode 100644
index 0000000..7bcb050
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+  f<U>(g) => null;
+}
+
+abstract class D<T> {
+  void f<U>(G<U> g);
+}
+
+typedef List<V> G<V>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6958c93
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class D<T> {
+  void f<U>(G<U> g);
+}
+
+class C<T> extends D<T> {
+  f<U>(g) => null;
+}
+
+main() {}
+typedef List<V> G<V>();
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..99aa0ee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+  f<U>(x) {}
+}
+
+class D<T> {
+  F<U> f<U>(U u) => null;
+}
+
+typedef V F<V>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2fedb57
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+  f<U>(x) {}
+}
+
+class D<T> {
+  F<U> f<U>(U u) => null;
+}
+
+main() {}
+typedef V F<V>();
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..3271c03
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+import 'dart:math' as math;
+import 'dart:math' show min;
+
+class C {
+  T m<T extends num>(T x, T y) => null;
+}
+
+test() {}
+void takeIII(int fn(int a, int b)) {}
+void takeDDD(double fn(double a, double b)) {}
+void takeIDI(int fn(double a, int b)) {}
+void takeDID(double fn(int a, double b)) {}
+void takeIDN(num fn(double a, int b)) {}
+void takeDIN(num fn(int a, double b)) {}
+void takeIIN(num fn(int a, int b)) {}
+void takeDDN(num fn(double a, double b)) {}
+void takeNNN(num fn(num a, num b)) {}
+void takeOON(num fn(Object a, Object b)) {}
+void takeOOO(num fn(Object a, Object b)) {}
+void takeOOI(int fn(Object a, Object b)) {}
+void takeIIO(Object fn(int a, int b)) {}
+void takeDDO(Object fn(double a, double b)) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ec53965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+library test;
+
+import 'dart:math' as math;
+import 'dart:math' show min;
+
+class C {
+  T m<T extends num>(T x, T y) => null;
+}
+
+main() {}
+test() {}
+void takeDDD(double fn(double a, double b)) {}
+void takeDDN(num fn(double a, double b)) {}
+void takeDDO(Object fn(double a, double b)) {}
+void takeDID(double fn(int a, double b)) {}
+void takeDIN(num fn(int a, double b)) {}
+void takeIDI(int fn(double a, int b)) {}
+void takeIDN(num fn(double a, int b)) {}
+void takeIII(int fn(int a, int b)) {}
+void takeIIN(num fn(int a, int b)) {}
+void takeIIO(Object fn(int a, int b)) {}
+void takeNNN(num fn(num a, num b)) {}
+void takeOOI(int fn(Object a, Object b)) {}
+void takeOON(num fn(Object a, Object b)) {}
+void takeOOO(num fn(Object a, Object b)) {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline.expect
new file mode 100644
index 0000000..6dbee2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  T m<T>(T x) => x;
+}
+
+class D extends C {
+  m<S>(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6dbee2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  T m<T>(T x) => x;
+}
+
+class D extends C {
+  m<S>(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.outline.expect
index f23adfb..f702343 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.outline.expect
@@ -1,3 +1,10 @@
+//
+// Problems outside component:
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:9:8: Error: Not found: 'dart:_foreign_helper'
+// import 'dart:_foreign_helper' show JS; // error
+//        ^
+//
 library test;
 //
 // Problems in library:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.expect
index 7b69eef..e9116be 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.expect
@@ -1,3 +1,10 @@
+//
+// Problems outside component:
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:9:8: Error: Not found: 'dart:_foreign_helper'
+// import 'dart:_foreign_helper' show JS; // error
+//        ^
+//
 library test;
 //
 // Problems in library:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline.expect
new file mode 100644
index 0000000..7454c6f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:_foreign_helper' show JS;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..482fa81
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:_foreign_helper' show JS;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline.expect
new file mode 100644
index 0000000..e710694
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..42c4800
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void f() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline.expect
new file mode 100644
index 0000000..649c05e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+Future<int> make(int x) => (new Future(() => x));
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..67fe832
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+Future<int> make(int x) => (new Future(() => x));
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..5998d2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:math' as math;
+
+class Trace {
+  List<Frame> frames = [];
+}
+
+class Frame {
+  String location = '';
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2248ecd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:math' as math;
+
+class Frame {
+  String location = '';
+}
+
+class Trace {
+  List<Frame> frames = [];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..299707a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+typedef Iterable<num> F(int x);
+typedef List<int> G(double x);
+T generic<T>(a(T _), b(T _)) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ecd0b24
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T generic<T>(a(T _), b(T _)) => null;
+main() {}
+typedef Iterable<num> F(int x);
+typedef List<int> G(double x);
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline.expect
new file mode 100644
index 0000000..f36e1a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+abstract class C<E> {
+  void sort([int compare(E a, E b)]) {}
+  static int _compareAny(a, b) {}
+  static void sort2<E>(C<E> a, int compare(E a, E b)) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..928adb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+abstract class C<E> {
+  static int _compareAny(a, b) {}
+  static void sort2<E>(C<E> a, int compare(E a, E b)) {}
+  void sort([int compare(E a, E b)]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline.expect
new file mode 100644
index 0000000..67da6aa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {
+  A f(A x, {A y}) {}
+  A g(A x, {A y}) {}
+  A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+  f(x, {y}) {}
+  g(x, {y}) {}
+  h(x, {y}) {}
+}
+
+class I {
+  I f(I x, {I y}) {}
+  A g(I x, {I y}) {}
+  A h(A x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4c44599
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {
+  A f(A x, {A y}) {}
+  A g(A x, {A y}) {}
+  A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+  f(x, {y}) {}
+  g(x, {y}) {}
+  h(x, {y}) {}
+}
+
+class I {
+  A g(I x, {I y}) {}
+  A h(A x, {I y}) {}
+  I f(I x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..71f35b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  dynamic operator []=(dynamic index, dynamic value) {}
+}
+
+abstract class I {
+  void operator []=(dynamic index, dynamic value) {}
+}
+
+class D extends C implements I {
+  operator []=(dynamic index, dynamic value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d950bce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I {
+  void operator []=(dynamic index, dynamic value) {}
+}
+
+class C {
+  dynamic operator []=(dynamic index, dynamic value) {}
+}
+
+class D extends C implements I {
+  operator []=(dynamic index, dynamic value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline.expect
new file mode 100644
index 0000000..5b865ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  dynamic operator []=(int index, dynamic value) {}
+}
+
+abstract class I {
+  void operator []=(int index, dynamic value) {}
+}
+
+class D extends C implements I {
+  operator []=(int index, value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..700f73a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I {
+  void operator []=(int index, dynamic value) {}
+}
+
+class C {
+  dynamic operator []=(int index, dynamic value) {}
+}
+
+class D extends C implements I {
+  operator []=(int index, value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e8e8fb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A implements B {
+  get x => f();
+  void set x(value) {}
+}
+
+class B {
+  var x = 0;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8e8fb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A implements B {
+  get x => f();
+  void set x(value) {}
+}
+
+class B {
+  var x = 0;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..cce1286
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B member;
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fedf127
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+  B member;
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..5aea77f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+  int t;
+  void test() {}
+}
+
+class Test2 {
+  num t;
+  void test() {}
+}
+
+class Test3 {
+  double t;
+  void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07ae2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+  int t;
+  void test() {}
+}
+
+class Test2 {
+  num t;
+  void test() {}
+}
+
+class Test3 {
+  double t;
+  void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline.expect
new file mode 100644
index 0000000..0082739
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3153d49
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class Base {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline.expect
new file mode 100644
index 0000000..54818ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..370d98d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d9659ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f01f8e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline.expect
new file mode 100644
index 0000000..2d1227e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+  B member;
+}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cdf4959
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class Base {
+  B member;
+}
+
+class C extends B {}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..31af0c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Base {
+  int intProp;
+  num numProp;
+  double doubleProp;
+}
+
+class Test1 extends Base {
+  void test() {}
+}
+
+class Test2 extends Base {
+  void test() {}
+}
+
+class Test3 extends Base {
+  void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d5e219
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Base {
+  double doubleProp;
+  int intProp;
+  num numProp;
+}
+
+class Test1 extends Base {
+  void test() {}
+}
+
+class Test2 extends Base {
+  void test() {}
+}
+
+class Test3 extends Base {
+  void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..6566843
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+  int f;
+}
+
+A a = new A();
+var c = 0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1170f43
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+A a = new A();
+
+class A {
+  int f;
+}
+
+main() {}
+var c = 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline.expect
new file mode 100644
index 0000000..3ee6268
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+  static B staticVariable;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+B topLevelVariable;
+void test_topLevelVariable() {}
+void test_staticVariable() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..667b734
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+B topLevelVariable;
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+  static B staticVariable;
+}
+
+class C extends B {}
+
+main() {}
+void test_staticVariable() {}
+void test_topLevelVariable() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..13362e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+int topLevelInt;
+num topLevelNum;
+double topLevelDouble;
+void test1() {}
+void test2() {}
+void test3() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b31b13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+double getDouble() => 0.0;
+double topLevelDouble;
+int getInt() => 0;
+int topLevelInt;
+main() {}
+num getNum() => 0;
+num topLevelNum;
+void test1() {}
+void test2() {}
+void test3() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline.expect
new file mode 100644
index 0000000..80ca252
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+  int operator +(other) => 1;
+  double operator -(other) => 2.0;
+}
+
+var v_add = new A() + 'foo';
+var v_minus = new A() - 'bar';
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b2556e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+  double operator -(other) => 2.0;
+  int operator +(other) => 1;
+}
+
+main() {}
+var v_add = new A() + 'foo';
+var v_minus = new A() - 'bar';
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline.expect
new file mode 100644
index 0000000..afb98b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+var a_equal = 1.0 == 2.0;
+var a_notEqual = 1.0 != 2.0;
+var a_add = 1.0 + 2.0;
+var a_subtract = 1.0 - 2.0;
+var a_multiply = 1.0 * 2.0;
+var a_divide = 1.0 / 2.0;
+var a_floorDivide = 1.0 ~/ 2.0;
+var a_greater = 1.0 > 2.0;
+var a_less = 1.0 < 2.0;
+var a_greaterEqual = 1.0 >= 2.0;
+var a_lessEqual = 1.0 <= 2.0;
+var a_modulo = 1.0 % 2.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ca4cc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+main() {}
+var a_add = 1.0 + 2.0;
+var a_divide = 1.0 / 2.0;
+var a_equal = 1.0 == 2.0;
+var a_floorDivide = 1.0 ~/ 2.0;
+var a_greater = 1.0 > 2.0;
+var a_greaterEqual = 1.0 >= 2.0;
+var a_less = 1.0 < 2.0;
+var a_lessEqual = 1.0 <= 2.0;
+var a_modulo = 1.0 % 2.0;
+var a_multiply = 1.0 * 2.0;
+var a_notEqual = 1.0 != 2.0;
+var a_subtract = 1.0 - 2.0;
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline.expect
new file mode 100644
index 0000000..5b6dace
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+var a_equal = 1.0 == 2;
+var a_notEqual = 1.0 != 2;
+var a_add = 1.0 + 2;
+var a_subtract = 1.0 - 2;
+var a_multiply = 1.0 * 2;
+var a_divide = 1.0 / 2;
+var a_floorDivide = 1.0 ~/ 2;
+var a_greater = 1.0 > 2;
+var a_less = 1.0 < 2;
+var a_greaterEqual = 1.0 >= 2;
+var a_lessEqual = 1.0 <= 2;
+var a_modulo = 1.0 % 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8ac0d0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+main() {}
+var a_add = 1.0 + 2;
+var a_divide = 1.0 / 2;
+var a_equal = 1.0 == 2;
+var a_floorDivide = 1.0 ~/ 2;
+var a_greater = 1.0 > 2;
+var a_greaterEqual = 1.0 >= 2;
+var a_less = 1.0 < 2;
+var a_lessEqual = 1.0 <= 2;
+var a_modulo = 1.0 % 2;
+var a_multiply = 1.0 * 2;
+var a_notEqual = 1.0 != 2;
+var a_subtract = 1.0 - 2;
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline.expect
new file mode 100644
index 0000000..f4d00de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+var a_equal = 1 == 2.0;
+var a_notEqual = 1 != 2.0;
+var a_add = 1 + 2.0;
+var a_subtract = 1 - 2.0;
+var a_multiply = 1 * 2.0;
+var a_divide = 1 / 2.0;
+var a_floorDivide = 1 ~/ 2.0;
+var a_greater = 1 > 2.0;
+var a_less = 1 < 2.0;
+var a_greaterEqual = 1 >= 2.0;
+var a_lessEqual = 1 <= 2.0;
+var a_modulo = 1 % 2.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ba59e589
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+main() {}
+var a_add = 1 + 2.0;
+var a_divide = 1 / 2.0;
+var a_equal = 1 == 2.0;
+var a_floorDivide = 1 ~/ 2.0;
+var a_greater = 1 > 2.0;
+var a_greaterEqual = 1 >= 2.0;
+var a_less = 1 < 2.0;
+var a_lessEqual = 1 <= 2.0;
+var a_modulo = 1 % 2.0;
+var a_multiply = 1 * 2.0;
+var a_notEqual = 1 != 2.0;
+var a_subtract = 1 - 2.0;
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline.expect
new file mode 100644
index 0000000..f139d16
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+var a_equal = 1 == 2;
+var a_notEqual = 1 != 2;
+var a_bitXor = 1 ^ 2;
+var a_bitAnd = 1 & 2;
+var a_bitOr = 1 | 2;
+var a_bitShiftRight = 1 >> 2;
+var a_bitShiftLeft = 1 << 2;
+var a_add = 1 + 2;
+var a_subtract = 1 - 2;
+var a_multiply = 1 * 2;
+var a_divide = 1 / 2;
+var a_floorDivide = 1 ~/ 2;
+var a_greater = 1 > 2;
+var a_less = 1 < 2;
+var a_greaterEqual = 1 >= 2;
+var a_lessEqual = 1 <= 2;
+var a_modulo = 1 % 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dae8595
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+main() {}
+var a_add = 1 + 2;
+var a_bitAnd = 1 & 2;
+var a_bitOr = 1 | 2;
+var a_bitShiftLeft = 1 << 2;
+var a_bitShiftRight = 1 >> 2;
+var a_bitXor = 1 ^ 2;
+var a_divide = 1 / 2;
+var a_equal = 1 == 2;
+var a_floorDivide = 1 ~/ 2;
+var a_greater = 1 > 2;
+var a_greaterEqual = 1 >= 2;
+var a_less = 1 < 2;
+var a_lessEqual = 1 <= 2;
+var a_modulo = 1 % 2;
+var a_multiply = 1 * 2;
+var a_notEqual = 1 != 2;
+var a_subtract = 1 - 2;
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline.expect
new file mode 100644
index 0000000..49f6015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+var a = 1 == 2 ? 1 : 2.0;
+var b = 1 == 2 ? 1.0 : 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..da56220
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var a = 1 == 2 ? 1 : 2.0;
+var b = 1 == 2 ? 1.0 : 2;
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline.expect
new file mode 100644
index 0000000..e7967d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_consts_transitively_2_a.dart';
+
+const m1 = a1;
+const m2 = a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e7967d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_consts_transitively_2_a.dart';
+
+const m1 = a1;
+const m2 = a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..3db058a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import 'infer_consts_transitively_2.dart';
+import 'infer_consts_transitively_2_b.dart';
+
+const a1 = m2;
+const a2 = b1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3db058a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import 'infer_consts_transitively_2.dart';
+import 'infer_consts_transitively_2_b.dart';
+
+const a1 = m2;
+const a2 = b1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline.expect
new file mode 100644
index 0000000..8a3d947
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  var x, y = 2, z = "hi";
+}
+
+class B implements A {
+  var x = 2, y = 3, z, w = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a3d947
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  var x, y = 2, z = "hi";
+}
+
+class B implements A {
+  var x = 2, y = 3, z, w = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline.expect
new file mode 100644
index 0000000..449b974
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A implements B {
+  var x;
+}
+
+class B {
+  var x = 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..449b974
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A implements B {
+  var x;
+}
+
+class B {
+  var x = 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..2a897a8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A implements B {
+  var x;
+}
+
+abstract class B implements C {
+  get x;
+}
+
+abstract class C {
+  int get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..baffda4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class B implements C {
+  get x;
+}
+
+abstract class C {
+  int get x;
+}
+
+class A implements B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..953911e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A implements B {
+  var x;
+}
+
+abstract class B implements C {
+  void set x(value);
+}
+
+abstract class C {
+  void set x(int value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8533862
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class B implements C {
+  void set x(value);
+}
+
+abstract class C {
+  void set x(int value);
+}
+
+class A implements B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline.expect
new file mode 100644
index 0000000..0636207
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+library test;
+
+abstract class A {
+  int get x;
+}
+
+abstract class B {
+  int get x;
+}
+
+abstract class C {
+  num get x;
+}
+
+abstract class D {
+  double get x;
+}
+
+class E extends A implements B {
+  var x;
+}
+
+class F extends A implements C {
+  var x;
+}
+
+class G extends A implements D {
+  var x;
+}
+
+class H extends C implements D {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0636207
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+library test;
+
+abstract class A {
+  int get x;
+}
+
+abstract class B {
+  int get x;
+}
+
+abstract class C {
+  num get x;
+}
+
+abstract class D {
+  double get x;
+}
+
+class E extends A implements B {
+  var x;
+}
+
+class F extends A implements C {
+  var x;
+}
+
+class G extends A implements D {
+  var x;
+}
+
+class H extends C implements D {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline.expect
new file mode 100644
index 0000000..57505e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+  num get x;
+}
+
+abstract class B extends A {
+  int get x;
+}
+
+class C extends B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..57505e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+  num get x;
+}
+
+abstract class B extends A {
+  int get x;
+}
+
+class C extends B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..1a94541
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A<T> {
+  List<T> get x;
+  void set y(List<T> value);
+  List<T> z;
+}
+
+class B extends A<int> {
+  var x;
+  var y;
+  var z;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..793f675
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A<T> {
+  List<T> get x;
+  List<T> z;
+  void set y(List<T> value);
+}
+
+class B extends A<int> {
+  var x;
+  var y;
+  var z;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..ae8f2ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+  int get x;
+}
+
+class B {
+  int get x => 0;
+}
+
+class C extends A {
+  var x;
+}
+
+class D extends B {
+  var x;
+}
+
+class E implements A {
+  var x;
+}
+
+class F implements B {
+  var x;
+}
+
+class G extends Object with B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae8f2ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+  int get x;
+}
+
+class B {
+  int get x => 0;
+}
+
+class C extends A {
+  var x;
+}
+
+class D extends B {
+  var x;
+}
+
+class E implements A {
+  var x;
+}
+
+class F implements B {
+  var x;
+}
+
+class G extends Object with B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..4758097
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+  void set x(int value);
+}
+
+class B {
+  void set x(int value) {}
+}
+
+class C extends A {
+  var x;
+}
+
+class D extends B {
+  var x;
+}
+
+class E implements A {
+  var x;
+}
+
+class F implements B {
+  var x;
+}
+
+class G extends Object with B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4758097
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+  void set x(int value);
+}
+
+class B {
+  void set x(int value) {}
+}
+
+class C extends A {
+  var x;
+}
+
+class D extends B {
+  var x;
+}
+
+class E implements A {
+  var x;
+}
+
+class F implements B {
+  var x;
+}
+
+class G extends Object with B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline.expect
new file mode 100644
index 0000000..7a13d2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+dynamic f() => null;
+
+abstract class A {
+  static int get x => 0;
+}
+
+class B extends A {
+  static var x = f();
+}
+
+class C extends A {
+  static var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a746ec3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class A {
+  static int get x => 0;
+}
+
+class B extends A {
+  static var x = f();
+}
+
+class C extends A {
+  static var x;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..2fcbeb6b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class A {
+  int get x;
+  void set x(double value) {}
+}
+
+class B extends A {
+  final x;
+  B(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..226c18d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class A {
+  int get x;
+  void set x(double value) {}
+}
+
+class B extends A {
+  B(this.x);
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline.expect
new file mode 100644
index 0000000..98e63d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+  int get x;
+}
+
+class B extends A {
+  final x;
+  B(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c719f5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+  int get x;
+}
+
+class B extends A {
+  B(this.x);
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline.expect
new file mode 100644
index 0000000..e6b33d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+  void set x(double value) {}
+}
+
+class B extends A {
+  final x;
+  B(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b763af
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+  void set x(double value) {}
+}
+
+class B extends A {
+  B(this.x);
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline.expect
new file mode 100644
index 0000000..1c2997f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {
+  int x;
+  B operator +(other) => null;
+}
+
+class B extends A {
+  B(ignore);
+}
+
+var a = new A();
+var b = new B(x);
+var c1 = [x];
+var c2 = const [];
+var d = <dynamic, dynamic>{'a': 'b'};
+var e = new A()..x = 3;
+var f = 2 + 3;
+var g = -3;
+var h = new A() + 3;
+var i = -new A();
+var j = null as B;
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e2fe4c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {
+  B operator +(other) => null;
+  int x;
+}
+
+class B extends A {
+  B(ignore);
+}
+
+main() {}
+test1() {}
+var a = new A();
+var b = new B(x);
+var c1 = [x];
+var c2 = const [];
+var d = <dynamic, dynamic>{'a': 'b'};
+var e = new A()..x = 3;
+var f = 2 + 3;
+var g = -3;
+var h = new A() + 3;
+var i = -new A();
+var j = null as B;
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..34ce1a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  var x;
+}
+
+class B implements A {
+  var x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..34ce1a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  var x;
+}
+
+class B implements A {
+  var x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline.expect
new file mode 100644
index 0000000..aa0f066
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  final x = null;
+}
+
+class B implements A {
+  final x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aa0f066
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  final x = null;
+}
+
+class B implements A {
+  final x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline.expect
new file mode 100644
index 0000000..d492a1f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart';
+
+var y = x;
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7f49eac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart';
+
+main() {}
+test1() {}
+var y = x;
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline.expect
new file mode 100644
index 0000000..88b9f22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart';
+
+class B {
+  static var y = A.x;
+}
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1c629e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart';
+
+class B {
+  static var y = A.x;
+}
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..4506b1e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+class A {
+  static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4506b1e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+class A {
+  static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline.expect
new file mode 100644
index 0000000..b6179eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+var x = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7bbfa38
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+main() {}
+var x = 2;
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline.expect
new file mode 100644
index 0000000..3866c4e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag_a.dart';
+
+var y = x;
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc53ea1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag_a.dart';
+
+main() {}
+test1() {}
+var y = x;
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline.expect
new file mode 100644
index 0000000..7aa039a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag2_a.dart';
+
+class B {
+  static var y = A.x;
+}
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5077b56
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag2_a.dart';
+
+class B {
+  static var y = A.x;
+}
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..7525c2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+  static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7525c2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+  static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline.expect
new file mode 100644
index 0000000..bd89adb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+var x = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a415471
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+var x = 2;
diff --git a/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline.expect
new file mode 100644
index 0000000..62a3a59
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A<X> {
+  X field;
+}
+
+abstract class B<Y> implements A<Y> {
+  get field;
+  set field(value);
+}
+
+abstract class C implements A<int> {
+  get field;
+  set field(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3a0740d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class B<Y> implements A<Y> {
+  get field;
+  set field(value);
+}
+
+abstract class C implements A<int> {
+  get field;
+  set field(value);
+}
+
+class A<X> {
+  X field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline.expect
new file mode 100644
index 0000000..e30c11e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(int a, {String b, T c}) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e30c11e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(int a, {String b, T c}) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline.expect
new file mode 100644
index 0000000..067bf3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(int a, [T b]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..067bf3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(int a, [T b]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline.expect
new file mode 100644
index 0000000..bb6abf4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(int a, [String b, T c]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb6abf4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(int a, [String b, T c]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline.expect
new file mode 100644
index 0000000..62d0c61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..62d0c61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  T m<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..110bf8d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+  void set x(double value);
+}
+
+abstract class B extends A {
+  get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..110bf8d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+  void set x(double value);
+}
+
+abstract class B extends A {
+  get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..32a29d8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A implements B {
+  get x => f();
+}
+
+abstract class B implements C {
+  get x;
+}
+
+abstract class C {
+  int get x;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1b7bfe1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class B implements C {
+  get x;
+}
+
+abstract class C {
+  int get x;
+}
+
+class A implements B {
+  get x => f();
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..2ba130d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Resource {}
+
+class Folder extends Resource {}
+
+Resource getResource(String str) => null;
+
+class Foo<T> {
+  Foo(T t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a02d3d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+Resource getResource(String str) => null;
+
+class Folder extends Resource {}
+
+class Foo<T> {
+  Foo(T t);
+}
+
+class Resource {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
index e6b1e38..8446ce803 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -24,13 +24,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function f2() → core::int* {
@@ -40,8 +40,8 @@
     final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
     asy::FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -54,13 +54,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function f4() → core::Iterable<core::int*>* /* originally sync* */ {
@@ -81,8 +81,8 @@
     asy::_AsyncStarStreamController<core::int*>* :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -99,7 +99,7 @@
           }
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..289c1fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef int F();
+
+abstract class A {
+  void x(F value);
+}
+
+abstract class B extends A {
+  void x(value());
+}
+
+T f<T>() => null;
+g(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a02e51
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>() => null;
+
+abstract class A {
+  void x(F value);
+}
+
+abstract class B extends A {
+  void x(value());
+}
+
+g(B b) {}
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline.expect
new file mode 100644
index 0000000..ef2bee8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+abstract class A {
+  int f(int x, int y);
+  int g(int x, [int y]);
+  int h(int x, {int y});
+}
+
+abstract class B {
+  int f(int x);
+  int g(int x);
+  int h(int x);
+}
+
+abstract class C implements A, B {
+  f(x, y);
+  g(x, [y]);
+  h(x, {y});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef2bee8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+abstract class A {
+  int f(int x, int y);
+  int g(int x, [int y]);
+  int h(int x, {int y});
+}
+
+abstract class B {
+  int f(int x);
+  int g(int x);
+  int h(int x);
+}
+
+abstract class C implements A, B {
+  f(x, y);
+  g(x, [y]);
+  h(x, {y});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline.expect
new file mode 100644
index 0000000..865f30c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+  set foo(x) {}
+}
+
+class D {
+  int foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..865f30c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+  set foo(x) {}
+}
+
+class D {
+  int foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..275351d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+  set foo(x) {}
+}
+
+class D {
+  set foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..275351d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+  set foo(x) {}
+}
+
+class D {
+  set foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..a4602b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+var a_not = !true;
+var a_complement = ~1;
+var a_negate = -1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..927498a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+main() {}
+var a_complement = ~1;
+var a_negate = -1;
+var a_not = !true;
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline.expect
new file mode 100644
index 0000000..c9d8c68
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  A();
+  int operator ~() => 1;
+  double operator -() => 2.0;
+}
+
+var a = new A();
+var v_complement = ~a;
+var v_negate = -a;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1cedf13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  A();
+  double operator -() => 2.0;
+  int operator ~() => 1;
+}
+
+main() {}
+var a = new A();
+var v_complement = ~a;
+var v_negate = -a;
diff --git a/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline.expect
new file mode 100644
index 0000000..a3b6c53
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test(f(), g()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a9809c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test(f(), g()) {}
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline.expect
new file mode 100644
index 0000000..4707e1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<String> strings() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4707e1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<String> strings() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..659aede
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  static set foo(int x) {}
+}
+
+set bar(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5e7be8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  static set foo(int x) {}
+}
+
+main() {}
+set bar(int x) {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..250fada
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+  double get x;
+}
+
+abstract class B extends A {
+  void set x(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..250fada
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+  double get x;
+}
+
+abstract class B extends A {
+  void set x(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..9f48a64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A implements B {
+  void set x(value) {}
+}
+
+abstract class B implements C {
+  void set x(value);
+}
+
+abstract class C {
+  void set x(int value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c70b4f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class B implements C {
+  void set x(value);
+}
+
+abstract class C {
+  void set x(int value);
+}
+
+class A implements B {
+  void set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..6f14c5a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef int F();
+
+abstract class A {
+  void set x(F value);
+}
+
+abstract class B extends A {
+  void set x(value());
+}
+
+T f<T>() => null;
+g(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..558610c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>() => null;
+
+abstract class A {
+  void set x(F value);
+}
+
+abstract class B extends A {
+  void set x(value());
+}
+
+g(B b) {}
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline.expect
new file mode 100644
index 0000000..eb6e1ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+  void set x(int i) {}
+}
+
+class B extends A {
+  set x(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb6e1ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+  void set x(int i) {}
+}
+
+class B extends A {
+  set x(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline.expect
new file mode 100644
index 0000000..a2adc8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_statics_transitively_a.dart';
+
+final m1 = a1;
+final m2 = A.a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a2adc8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_statics_transitively_a.dart';
+
+final m1 = a1;
+final m2 = A.a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline.expect
new file mode 100644
index 0000000..3c1f88e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+const x1 = 1;
+final x2 = 1;
+final y1 = x1;
+final y2 = x2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c1f88e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+const x1 = 1;
+final x2 = 1;
+final y1 = x1;
+final y2 = x2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline.expect
new file mode 100644
index 0000000..3ff7fa6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'infer_statics_transitively3_a.dart' show a1, A;
+import 'infer_statics_transitively3_a.dart' as p show a2, A;
+
+const t1 = 1;
+const t2 = t1;
+const t3 = a1;
+const t4 = p.a2;
+const t5 = A.a3;
+const t6 = p.A.a3;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3ff7fa6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'infer_statics_transitively3_a.dart' show a1, A;
+import 'infer_statics_transitively3_a.dart' as p show a2, A;
+
+const t1 = 1;
+const t2 = t1;
+const t3 = a1;
+const t4 = p.a2;
+const t5 = A.a3;
+const t6 = p.A.a3;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline.expect
new file mode 100644
index 0000000..ef4e7b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+const a1 = 3;
+const a2 = 4;
+
+class A {
+  static const a3 = null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..594222f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+  static const a3 = null;
+}
+
+const a1 = 3;
+const a2 = 4;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..905ce2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+final a1 = m2;
+
+class A {
+  static final a2 = b1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6e4d7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+class A {
+  static final a2 = b1;
+}
+
+final a1 = m2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline.expect
new file mode 100644
index 0000000..905ce2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+final a1 = m2;
+
+class A {
+  static final a2 = b1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6e4d7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+class A {
+  static final a2 = b1;
+}
+
+final a1 = m2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline.expect
new file mode 100644
index 0000000..01611d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+final b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..01611d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+final b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline.expect
new file mode 100644
index 0000000..d3d25f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'infer_statics_with_method_invocations_a.dart';
+
+class T {
+  static final T foo = m1(m2(m3('', '')));
+  static T m1(String m) {}
+  static String m2(e) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bdbc3a1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'infer_statics_with_method_invocations_a.dart';
+
+class T {
+  static String m2(e) {}
+  static T m1(String m) {}
+  static final T foo = m1(m2(m3('', '')));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline.expect
new file mode 100644
index 0000000..9908614
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+m3(String a, String b, [a1, a2]) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9908614
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+m3(String a, String b, [a1, a2]) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline.expect
new file mode 100644
index 0000000..7a172c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+var t = true;
+var a = (throw 0);
+var b = (throw 0) ? 1 : 2;
+var c = t ? (throw 1) : 2;
+var d = t ? 1 : (throw 2);
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b649fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+main() {}
+var a = (throw 0);
+var b = (throw 0) ? 1 : 2;
+var c = t ? (throw 1) : 2;
+var d = t ? 1 : (throw 2);
+var t = true;
diff --git a/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d2157a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+T f<T>() => null;
+var x = throw f();
+void g() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e2510ef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T f<T>() => null;
+main() {}
+var x = throw f();
+void g() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline.expect
new file mode 100644
index 0000000..18f8608
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+class B extends A {
+  get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..18f8608
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+class B extends A {
+  get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline.expect
new file mode 100644
index 0000000..29aa0a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  final int x = 2;
+}
+
+class B implements A {
+  get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..29aa0a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  final int x = 2;
+}
+
+class B implements A {
+  get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline.expect
new file mode 100644
index 0000000..715fb78
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c5447d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline.expect
new file mode 100644
index 0000000..f68289e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+  int x = 0;
+  test1() {}
+  int y;
+  final z = 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2cea60e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+  final z = 42;
+  int x = 0;
+  int y;
+  test1() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..fdb603c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+int x = 0;
+test1() {}
+int y = 0;
+final z = 42;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ad86a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+final z = 42;
+int x = 0;
+int y = 0;
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline.expect
new file mode 100644
index 0000000..38d22e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'infer_type_regardless_of_declaration_order_or_cycles_b.dart';
+
+class C extends B {
+  get x => null;
+}
+
+class A {
+  int get x => 0;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17812e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'infer_type_regardless_of_declaration_order_or_cycles_b.dart';
+
+class A {
+  int get x => 0;
+}
+
+class C extends B {
+  get x => null;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline.expect
new file mode 100644
index 0000000..0c9213c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'infer_type_regardless_of_declaration_order_or_cycles.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0c9213c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'infer_type_regardless_of_declaration_order_or_cycles.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..36cd503
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+var a = <int, String>{0: 'aaa', 1: 'bbb'};
+var b = <double, int>{1.1: 1, 2.2: 2};
+var c = <List<int>, Map<String, double>>{};
+var d = <int, dynamic>{};
+var e = <dynamic, int>{};
+var f = <dynamic, dynamic>{};
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4531ba6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+main() {}
+var a = <int, String>{0: 'aaa', 1: 'bbb'};
+var b = <double, int>{1.1: 1, 2.2: 2};
+var c = <List<int>, Map<String, double>>{};
+var d = <int, dynamic>{};
+var e = <dynamic, int>{};
+var f = <dynamic, dynamic>{};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline.expect
new file mode 100644
index 0000000..0024591
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class A<T> {
+  final T x = null;
+  final T w = null;
+}
+
+class B implements A<int> {
+  get x => 3;
+  get w => "hello";
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55397b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class A<T> {
+  final T w = null;
+  final T x = null;
+}
+
+class B implements A<int> {
+  get w => "hello";
+  get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline.expect
new file mode 100644
index 0000000..40264e4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A<T> {
+  T x;
+}
+
+class B<E> extends A<E> {
+  E y;
+  get x => y;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40264e4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A<T> {
+  T x;
+}
+
+class B<E> extends A<E> {
+  E y;
+  get x => y;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline.expect
new file mode 100644
index 0000000..2bc7ba9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+library test;
+
+abstract class I<E> {
+  String m(a, String f(v, E e));
+}
+
+abstract class A<E> implements I<E> {
+  const A();
+  String m(a, String f(v, E e));
+}
+
+abstract class M {
+  final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+  const B();
+  int get y => 0;
+  m(a, f(v, E e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..336ae88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+library test;
+
+abstract class A<E> implements I<E> {
+  String m(a, String f(v, E e));
+  const A();
+}
+
+abstract class I<E> {
+  String m(a, String f(v, E e));
+}
+
+abstract class M {
+  final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+  const B();
+  int get y => 0;
+  m(a, f(v, E e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..fb866c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'infer_types_on_generic_instantiations_in_library_cycle_a.dart';
+
+abstract class A<E> implements I<E> {
+  const A();
+  final E value = null;
+}
+
+abstract class M {
+  final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+  const B();
+  int get y => 0;
+  m(a, f(v, int e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fb866c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'infer_types_on_generic_instantiations_in_library_cycle_a.dart';
+
+abstract class A<E> implements I<E> {
+  const A();
+  final E value = null;
+}
+
+abstract class M {
+  final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+  const B();
+  int get y => 0;
+  m(a, f(v, int e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline.expect
new file mode 100644
index 0000000..05abbc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'infer_types_on_generic_instantiations_in_library_cycle.dart';
+
+abstract class I<E> {
+  A<E> m(a, String f(v, int e));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05abbc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'infer_types_on_generic_instantiations_in_library_cycle.dart';
+
+abstract class I<E> {
+  A<E> m(a, String f(v, int e));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline.expect
new file mode 100644
index 0000000..92c8792
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A<T> {
+  final T x = null;
+}
+
+class B implements A<int> {
+  dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..92c8792
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A<T> {
+  final T x = null;
+}
+
+class B implements A<int> {
+  dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
index 8b874fc..c15b9d3 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
@@ -30,7 +30,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Foo extends core::Object {
   field core::int* bar = 42;
@@ -44,7 +43,7 @@
     ;
   method foo(generic-covariant-impl self::Bar::T* t) → void {
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(t).{core::Iterable::iterator};
+      core::Iterator<core::String*>* :sync-for-iterator = t.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::String* i = :sync-for-iterator.{core::Iterator::current};
         {
@@ -62,7 +61,7 @@
     ;
   method foo(generic-covariant-impl self::Baz::S* t) → void {
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(t).{core::Iterable::iterator};
+      core::Iterator<self::Baz::T*>* :sync-for-iterator = t.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         self::Baz::T* i = :sync-for-iterator.{core::Iterator::current};
         {
@@ -78,7 +77,7 @@
 static method test() → dynamic {
   core::List<self::Foo*>* list = <self::Foo*>[];
   {
-    core::Iterator<self::Foo*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::Foo*>*>(list).{core::Iterable::iterator};
+    core::Iterator<self::Foo*>* :sync-for-iterator = list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       self::Foo* x = :sync-for-iterator.{core::Iterator::current};
       {
@@ -90,7 +89,7 @@
     }
   }
   {
-    core::Iterator<self::Foo*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::Foo*>*>(list).{core::Iterable::iterator};
+    core::Iterator<self::Foo*>* :sync-for-iterator = list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic x = :sync-for-iterator.{core::Iterator::current};
       {
@@ -99,7 +98,7 @@
     }
   }
   {
-    core::Iterator<self::Foo*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::Foo*>*>(list).{core::Iterable::iterator};
+    core::Iterator<self::Foo*>* :sync-for-iterator = list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final self::Foo* #t4 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -114,7 +113,7 @@
   }
   dynamic z;
   {
-    core::Iterator<self::Foo*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::Foo*>*>(list).{core::Iterable::iterator};
+    core::Iterator<self::Foo*>* :sync-for-iterator = list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final self::Foo* #t6 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -125,7 +124,7 @@
   }
   core::Iterable<dynamic>* iter = list;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(iter).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = iter.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t7 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -136,7 +135,7 @@
   }
   dynamic iter2 = list;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(iter2 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = (iter2 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -147,7 +146,7 @@
   }
   core::Map<core::String*, self::Foo*>* map = <core::String*, self::Foo*>{};
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:60:70: Error: The type 'Map<String, Foo>' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:60:70: Error: The type 'Map<String, Foo>' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Map' is from 'dart:core'.
  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
  - 'Iterable' is from 'dart:core'.
@@ -161,7 +160,7 @@
     }
   }
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(map.{core::Map::keys}).{core::Iterable::iterator};
+    core::Iterator<core::String*>* :sync-for-iterator = map.{core::Map::keys}.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String* x = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..db1a358
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Foo {
+  int bar = 42;
+}
+
+class Bar<T extends Iterable<String>> {
+  void foo(T t) {}
+}
+
+class Baz<T, E extends Iterable<T>, S extends E> {
+  void foo(S t) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1dd9b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Bar<T extends Iterable<String>> {
+  void foo(T t) {}
+}
+
+class Baz<T, E extends Iterable<T>, S extends E> {
+  void foo(S t) {}
+}
+
+class Foo {
+  int bar = 42;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
index 7f3335c..7959a66 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
@@ -49,8 +49,8 @@
     final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -62,7 +62,7 @@
         #L1:
         {
           {
-            dynamic :stream = t;
+            self::Bar::T* :stream = t;
             asy::_asyncStarListenHelper(:stream, :async_op);
             asy::_StreamIterator<core::String*>* :for-iterator = new asy::_StreamIterator::•<core::String*>(:stream);
             try
@@ -91,13 +91,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -109,8 +109,8 @@
     final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -122,7 +122,7 @@
         #L3:
         {
           {
-            dynamic :stream = t;
+            self::Baz::S* :stream = t;
             asy::_asyncStarListenHelper(:stream, :async_op);
             asy::_StreamIterator<self::Baz::T*>* :for-iterator = new asy::_StreamIterator::•<self::Baz::T*>(:stream);
             try
@@ -152,13 +152,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
 }
@@ -170,8 +170,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -184,7 +184,7 @@
       {
         self::MyStream<self::Foo*>* myStream = self::MyStream::•<self::Foo*>();
         {
-          dynamic :stream = myStream;
+          self::MyStream<self::Foo*>* :stream = myStream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::Foo*>* :for-iterator = new asy::_StreamIterator::•<self::Foo*>(:stream);
           try
@@ -211,7 +211,7 @@
             }
         }
         {
-          dynamic :stream = myStream;
+          self::MyStream<self::Foo*>* :stream = myStream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -235,7 +235,7 @@
             }
         }
         {
-          dynamic :stream = myStream;
+          self::MyStream<self::Foo*>* :stream = myStream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::Foo*>* :for-iterator = new asy::_StreamIterator::•<self::Foo*>(:stream);
           try
@@ -265,7 +265,7 @@
         }
         dynamic z;
         {
-          dynamic :stream = myStream;
+          self::MyStream<self::Foo*>* :stream = myStream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::Foo*>* :for-iterator = new asy::_StreamIterator::•<self::Foo*>(:stream);
           try
@@ -291,7 +291,7 @@
         }
         asy::Stream<dynamic>* stream = myStream;
         {
-          dynamic :stream = stream;
+          asy::Stream<dynamic>* :stream = stream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -317,7 +317,7 @@
         }
         dynamic stream2 = myStream;
         {
-          dynamic :stream = stream2 as{TypeError,ForDynamic} asy::Stream<dynamic>*;
+          asy::Stream<dynamic>* :stream = stream2 as{TypeError,ForDynamic} asy::Stream<dynamic>*;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -343,7 +343,7 @@
         }
         core::Map<core::String*, self::Foo*>* map = <core::String*, self::Foo*>{};
         {
-          dynamic :stream = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:66:76: Error: The type 'Map<String, Foo>' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:66:76: Error: The type 'Map<String, Foo>' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Map' is from 'dart:core'.
  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
  - 'Stream' is from 'dart:async'.
@@ -375,13 +375,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline.expect
new file mode 100644
index 0000000..178b1385
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+import 'dart:async';
+
+class Foo {
+  int bar = 42;
+}
+
+class Bar<T extends Stream<String>> {
+  foo(T t) async {}
+}
+
+class Baz<T, E extends Stream<T>, S extends E> {
+  foo(S t) async {}
+}
+
+abstract class MyStream<T> extends Stream<T> {
+  factory MyStream() => null;
+}
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..225ac1c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyStream<T> extends Stream<T> {
+  factory MyStream() => null;
+}
+
+class Bar<T extends Stream<String>> {
+  foo(T t) async {}
+}
+
+class Baz<T, E extends Stream<T>, S extends E> {
+  foo(S t) async {}
+}
+
+class Foo {
+  int bar = 42;
+}
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline.expect
new file mode 100644
index 0000000..37187cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void f() {}
+void g() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e388e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void f() {}
+void g() {}
diff --git a/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline.expect
new file mode 100644
index 0000000..e064860
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void f() {}
+var x = f();
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e93269
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var x = f();
+void f() {}
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline.expect
new file mode 100644
index 0000000..4e7cbdc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  var x = 1;
+  Foo([this.x = "1"]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..57d515d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+  Foo([this.x = "1"]);
+  var x = 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..ab2bd61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  static var x = 'x';
+  var y = {
+    'a': {'b': 'c'},
+    'd': {'e': x}
+  };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab2bd61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  static var x = 'x';
+  var y = {
+    'a': {'b': 'c'},
+    'd': {'e': x}
+  };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline.expect
new file mode 100644
index 0000000..766e416
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+var x = 'x';
+
+class C {
+  var y = x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd2cec5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  var y = x;
+}
+
+main() {}
+var x = 'x';
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline.expect
new file mode 100644
index 0000000..beb68c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  C(void func()) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..beb68c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  C(void func()) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..3cd51b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  int a;
+  List<int> b;
+  void m() {}
+}
+
+var v = new A()
+  ..a = 1
+  ..b.add(2)
+  ..m();
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ef708f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  List<int> b;
+  int a;
+  void m() {}
+}
+
+main() {}
+var v = new A()
+  ..a = 1
+  ..b.add(2)
+  ..m();
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline.expect
new file mode 100644
index 0000000..e6999dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+  bool operator *(C other) => true;
+}
+
+C c = new C();
+var x = c * c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82580a5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C c = new C();
+
+class C {
+  bool operator *(C other) => true;
+}
+
+main() {}
+var x = c * c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..3c0524e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+  bool operator *(C other) => true;
+}
+
+abstract class C implements I {}
+
+C c;
+var x = c * c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce465b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C c;
+
+abstract class C implements I {}
+
+class I {
+  bool operator *(C other) => true;
+}
+
+main() {}
+var x = c * c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline.expect
new file mode 100644
index 0000000..2d475c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  bool operator [](int index) => true;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2d475c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  bool operator [](int index) => true;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..c0719da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class I {
+  bool operator [](int index) => true;
+}
+
+abstract class C implements I {}
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3d9042
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+abstract class C implements I {}
+
+class I {
+  bool operator [](int index) => true;
+}
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline.expect
new file mode 100644
index 0000000..8f42327
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+  bool operator -() => true;
+}
+
+C c = new C();
+var x = -c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faae8e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C c = new C();
+
+class C {
+  bool operator -() => true;
+}
+
+main() {}
+var x = -c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..8e685fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+  bool operator -() => true;
+}
+
+abstract class C implements I {}
+
+C c;
+var x = -c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd59e6e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C c;
+
+abstract class C implements I {}
+
+class I {
+  bool operator -() => true;
+}
+
+main() {}
+var x = -c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..f835fa3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+  bool g() => true;
+}
+
+C f() => null;
+var x = f().g;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef601f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C f() => null;
+
+class C {
+  bool g() => true;
+}
+
+main() {}
+var x = f().g;
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..b33b523
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+  bool g() => true;
+}
+
+abstract class C implements I {}
+
+C f() => null;
+var x = f().g;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c42584c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C f() => null;
+
+abstract class C implements I {}
+
+class I {
+  bool g() => true;
+}
+
+main() {}
+var x = f().g;
diff --git a/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..cff7f24
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var v = print;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b24205c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var v = print;
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline.expect
new file mode 100644
index 0000000..f1ef9c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+  bool g() => true;
+}
+
+C f() => null;
+var x = f().g();
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f10023
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C f() => null;
+
+class C {
+  bool g() => true;
+}
+
+main() {}
+var x = f().g();
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..ece4df6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+  bool g() => true;
+}
+
+abstract class C implements I {}
+
+C f() => null;
+var x = f().g();
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46f69cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C f() => null;
+
+abstract class C implements I {}
+
+class I {
+  bool g() => true;
+}
+
+main() {}
+var x = f().g();
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline.expect
new file mode 100644
index 0000000..0ce53ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.v1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce53ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.v1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline.expect
new file mode 100644
index 0000000..c3999a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.values;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c3999a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.values;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..ef330db
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef void F();
+final x = <String, F>{};
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19c52ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+final x = <String, F>{};
+main() {}
+typedef void F();
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline.expect
new file mode 100644
index 0000000..52d5fdc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef T F<T>();
+final x = <String, F<int>>{};
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ede87e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+final x = <String, F<int>>{};
+main() {}
+typedef T F<T>();
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..5f05b3e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f() => null;
+String g() => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0efdef0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g() => null;
+int f() => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline.expect
new file mode 100644
index 0000000..a01e141
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f13be17
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g(int x(String y)) => null;
+int f(int x(String y)) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline.expect
new file mode 100644
index 0000000..f49560d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f({int x}) => null;
+String g({int x}) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b9d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g({int x}) => null;
+int f({int x}) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline.expect
new file mode 100644
index 0000000..ff5ab50
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f([int x]) => null;
+String g([int x]) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99a139a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g([int x]) => null;
+int f([int x]) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline.expect
new file mode 100644
index 0000000..4aa6f7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f(int x) => null;
+String g(int x) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8eff357
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g(int x) => null;
+int f(int x) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline.expect
new file mode 100644
index 0000000..a5cc028
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  static final f = (bool b) => (int i) => {i: b};
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a5cc028
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  static final f = (bool b) => (int i) => {i: b};
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline.expect
new file mode 100644
index 0000000..fc48846
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  static final f = (bool b) => b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc48846
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  static final f = (bool b) => b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline.expect
new file mode 100644
index 0000000..015c510
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  static final f = (bool b) => 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..015c510
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  static final f = (bool b) => 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..2cfa51b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+final f = (bool b) => 1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2cfa51b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+final f = (bool b) => 1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline.expect
new file mode 100644
index 0000000..134a70e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class I1 {
+  final x = y;
+}
+
+abstract class I2 {
+  num get x;
+}
+
+class C extends Object implements I1, I2 {
+  int get x => 0;
+}
+
+var y = new C().x;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71382d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class I2 {
+  num get x;
+}
+
+class C extends Object implements I1, I2 {
+  int get x => 0;
+}
+
+class I1 {
+  final x = y;
+}
+
+main() {}
+var y = new C().x;
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..3809765
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+  A(B<List<T>> b);
+}
+
+class B<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3809765
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+  A(B<List<T>> b);
+}
+
+class B<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..bfdc465
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>(T x) => x;
+
+class C {
+  T f<T>(T x) => x;
+  static T g<T>(T x) => x;
+}
+
+class D extends C {
+  void test() {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..885153c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>(T x) => x;
+
+class C {
+  T f<T>(T x) => x;
+  static T g<T>(T x) => x;
+}
+
+class D extends C {
+  void test() {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline.expect
new file mode 100644
index 0000000..585e21c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  void Function(T) f<U>(U x) => (y) {};
+}
+
+void test(C<String> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1a470c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  void Function(T) f<U>(U x) => (y) {};
+}
+
+main() {}
+void test(C<String> c) {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline.expect
new file mode 100644
index 0000000..3ac64a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(T Function<T>(T) f) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b579dab
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(T Function<T>(T) f) {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline.expect
new file mode 100644
index 0000000..0e78705
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class B<T extends A> {}
+
+class A<T extends int> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25872ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A<T extends int> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline.expect
new file mode 100644
index 0000000..a0a4e79
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T extends int> {}
+
+class B<T extends A> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25872ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A<T extends int> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..f36f71c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {}
+
+class B<T extends A> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5c6a17a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A<T> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline.expect
new file mode 100644
index 0000000..e88b99a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+A v = null;
+
+class A<T extends int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e88b99a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+A v = null;
+
+class A<T extends int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline.expect
new file mode 100644
index 0000000..e39f07f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+class A<T extends int> {}
+
+A v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e88b99a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+A v = null;
+
+class A<T extends int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..3c2908d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+class C<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c2908d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+class C<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline.expect
new file mode 100644
index 0000000..c265515
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+class C<T extends num> {}
+
+var x = new C<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71e70ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+class C<T extends num> {}
+
+main() {}
+var x = new C<int>();
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..58d69fb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {}
+
+class B<T extends A> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3845e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart b/pkg/front_end/testcases/inference/issue41199.dart
new file mode 100644
index 0000000..778bf42
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.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.
+
+foo<X>(Map<X, Y> Function<Y>() f) => null;
+baz() => foo(<Z>() => <dynamic, Z>{});
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.outline.expect b/pkg/front_end/testcases/inference/issue41199.dart.outline.expect
new file mode 100644
index 0000000..69b0cc3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo<X extends core::Object* = dynamic>(<Y extends core::Object* = dynamic>() →* core::Map<self::foo::X*, Y*>* f) → dynamic
+  ;
+static method baz() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.strong.expect b/pkg/front_end/testcases/inference/issue41199.dart.strong.expect
new file mode 100644
index 0000000..6d7392d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo<X extends core::Object* = dynamic>(<Y extends core::Object* = dynamic>() →* core::Map<self::foo::X*, Y*>* f) → dynamic
+  return null;
+static method baz() → dynamic
+  return self::foo<dynamic>(<Z extends core::Object* = dynamic>() → core::Map<dynamic, Z*>* => <dynamic, Z*>{});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/issue41199.dart.strong.transformed.expect
new file mode 100644
index 0000000..6d7392d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo<X extends core::Object* = dynamic>(<Y extends core::Object* = dynamic>() →* core::Map<self::foo::X*, Y*>* f) → dynamic
+  return null;
+static method baz() → dynamic
+  return self::foo<dynamic>(<Z extends core::Object* = dynamic>() → core::Map<dynamic, Z*>* => <dynamic, Z*>{});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.textual_outline.expect b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline.expect
new file mode 100644
index 0000000..a90b5ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo<X>(Map<X, Y> Function<Y>() f) => null;
+baz() => foo(<Z>() => <dynamic, Z>{});
+main() {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81ec7c1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+baz() => foo(<Z>() => <dynamic, Z>{});
+foo<X>(Map<X, Y> Function<Y>() f) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline.expect b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline.expect
new file mode 100644
index 0000000..8090ea1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+List<String> getListOfString() => const <String>[];
+void foo() {}
+void bar() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd53744
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+List<String> getListOfString() => const <String>[];
+main() {}
+void bar() {}
+void foo() {}
diff --git a/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..431191c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef num FunctionReturningNum();
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a159045
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+test() {}
+typedef num FunctionReturningNum();
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..a8bb8ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var a = <int>[];
+var b = <double>[1.0, 2.0, 3.0];
+var c = <List<int>>[];
+var d = <dynamic>[1, 2.0, false];
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..64454d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+var a = <int>[];
+var b = <double>[1.0, 2.0, 3.0];
+var c = <List<int>>[];
+var d = <dynamic>[1, 2.0, false];
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..5609202
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+test1() {}
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..140f235
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..6756ba5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var x1 = [1, 2, 3];
+test1() {}
+var x2 = [1, 2.0, 3];
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0f5ec2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
+var x1 = [1, 2, 3];
+var x2 = [1, 2.0, 3];
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..37920c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  T t;
+  C(this.t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c831b3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+  C(this.t);
+  T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline.expect
new file mode 100644
index 0000000..c807ee6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c807ee6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
index 1a8ef87..62c551c 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'FutureOr' is from 'dart:async'.
 //     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                      ^
@@ -19,7 +20,8 @@
     return (core::int* x) → core::int* => x;
   }
   function b() → asy::Future<(core::int*) →* core::int*>* async {
-    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
  - 'FutureOr' is from 'dart:async'.
     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                      ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
index d796649..7d91b21 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'FutureOr' is from 'dart:async'.
 //     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                      ^
@@ -22,15 +23,16 @@
     final asy::_AsyncAwaitCompleter<(core::int*) →* core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<(core::int*) →* core::int*>();
     asy::FutureOr<(core::int*) →* core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
       try {
         #L1:
         {
-          :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+          :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
  - 'FutureOr' is from 'dart:async'.
     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                      ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
@@ -39,13 +41,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function c() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
@@ -80,8 +82,8 @@
     asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -98,7 +100,7 @@
           }
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
@@ -115,8 +117,8 @@
     asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -133,7 +135,7 @@
           }
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline.expect
new file mode 100644
index 0000000..7a5100f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+typedef int IntToInt(int i);
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ad856ae
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+typedef int IntToInt(int i);
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..0562d88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {}
+
+abstract class B {}
+
+class C {
+  A a;
+  void f(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0562d88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {}
+
+abstract class B {}
+
+class C {
+  A a;
+  void f(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..5609202
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+test1() {}
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..140f235
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..6f3b811
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var x1 = {1: 'x', 2: 'y'};
+test1() {}
+var x2 = {1: 'x', 2: 'y', 3.0: new RegExp('.')};
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1bd3bfa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
+var x1 = {1: 'x', 2: 'y'};
+var x2 = {1: 'x', 2: 'y', 3.0: new RegExp('.')};
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline.expect
new file mode 100644
index 0000000..6de6cbe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+var f = new C().f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8d922a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+main() {}
+var f = new C().f<int>();
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline.expect
new file mode 100644
index 0000000..c522b9e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+C c;
+var f = c.f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..18dc8f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C c;
+
+class C {
+  D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+main() {}
+var f = c.f<int>();
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline.expect
new file mode 100644
index 0000000..add0023
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  static D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+var f = C.f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f8f547
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  static D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+main() {}
+var f = C.f<int>();
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline.expect
new file mode 100644
index 0000000..0e5b2a1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+D<T> f<T>() => null;
+
+class D<T> {}
+
+var g = f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6666457
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+D<T> f<T>() => null;
+
+class D<T> {}
+
+main() {}
+var g = f<int>();
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline.expect
new file mode 100644
index 0000000..0f627e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<X, Y extends String> extends I<X> {}
+
+class M1 implements I<int> {}
+
+class A extends M1 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..74e76cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M1 with M0 {}
+
+class I<X> {}
+
+class M0<X, Y extends String> extends I<X> {}
+
+class M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline.expect
new file mode 100644
index 0000000..45d38b0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<X, Y extends X> extends I<X> {}
+
+class M1 implements I<int> {}
+
+class A extends M1 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4c4a6eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M1 with M0 {}
+
+class I<X> {}
+
+class M0<X, Y extends X> extends I<X> {}
+
+class M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline.expect
new file mode 100644
index 0000000..4937c62
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<X, Y extends Comparable<Y>> extends I<X> {}
+
+class M1 implements I<int> {}
+
+class A extends M1 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3a6cbd7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M1 with M0 {}
+
+class I<X> {}
+
+class M0<X, Y extends Comparable<Y>> extends I<X> {}
+
+class M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline.expect
new file mode 100644
index 0000000..0a537f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class I<X> {}
+
+class J<X> {}
+
+class M0<X, Y> extends I<X> with J<Y> {}
+
+class M1 implements I<int> {}
+
+class M2 extends M1 implements J<double> {}
+
+class A extends M2 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..368c442
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A extends M2 with M0 {}
+
+class I<X> {}
+
+class J<X> {}
+
+class M0<X, Y> extends I<X> with J<Y> {}
+
+class M1 implements I<int> {}
+
+class M2 extends M1 implements J<double> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline.expect
new file mode 100644
index 0000000..dd6e38e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class I<X> {}
+
+class M0<T> extends I<List<T>> {}
+
+class M1<T> extends I<List<T>> {}
+
+class M2<T> extends M1<Map<T, T>> {}
+
+class A extends M2<int> with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ca8e99
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends M2<int> with M0 {}
+
+class I<X> {}
+
+class M0<T> extends I<List<T>> {}
+
+class M1<T> extends I<List<T>> {}
+
+class M2<T> extends M1<Map<T, T>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline.expect
new file mode 100644
index 0000000..88e4fe0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+class A extends M0<int> with M1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..daa14db
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M0<int> with M1 {}
+
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline.expect
new file mode 100644
index 0000000..95cdfee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+class M2<T> extends I<T> {}
+
+class A extends M0<int> with M1, M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..00c6217
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends M0<int> with M1, M2 {}
+
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+class M2<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline.expect
new file mode 100644
index 0000000..2ef4f06
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+class A extends Object with M0, M1<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..39209e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1<int> {}
+
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline.expect
new file mode 100644
index 0000000..9eec41a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+class A extends Object with M0, M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..50e9d09
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1 implements I<int> {}
+
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline.expect
new file mode 100644
index 0000000..18ceb4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X, Y> {}
+
+class M0<T> implements I<T, int> {}
+
+class M1<T> implements I<String, T> {}
+
+class A extends Object with M0, M1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3a249c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1 {}
+
+class I<X, Y> {}
+
+class M0<T> implements I<T, int> {}
+
+class M1<T> implements I<String, T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline.expect
new file mode 100644
index 0000000..875a303
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X, Y> {}
+
+class M0<T> implements I<T, List<T>> {}
+
+class M1<T> implements I<List<T>, T> {}
+
+class A extends Object with M0, M1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8a5311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1 {}
+
+class I<X, Y> {}
+
+class M0<T> implements I<T, List<T>> {}
+
+class M1<T> implements I<List<T>, T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..a12a138
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+typedef V F<U, V>(U u);
+
+class Foo<T> {
+  Bar<T> get v1 => new Bar();
+  Bar<List<T>> get v2 => new Bar();
+  Bar<F<T, T>> get v3 => new Bar();
+  Bar<F<F<T, T>, T>> get v4 => new Bar();
+  List<T> get v5 => [];
+  List<F<T, T>> get v6 => [];
+  Map<T, T> get v7 => {};
+  Map<F<T, T>, T> get v8 => {};
+  Map<T, F<T, T>> get v9 => {};
+}
+
+class Bar<T> {
+  const Bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6fb4bb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+class Bar<T> {
+  const Bar();
+}
+
+class Foo<T> {
+  Bar<F<F<T, T>, T>> get v4 => new Bar();
+  Bar<F<T, T>> get v3 => new Bar();
+  Bar<List<T>> get v2 => new Bar();
+  Bar<T> get v1 => new Bar();
+  List<F<T, T>> get v6 => [];
+  List<T> get v5 => [];
+  Map<F<T, T>, T> get v8 => {};
+  Map<T, F<T, T>> get v9 => {};
+  Map<T, T> get v7 => {};
+}
+
+main() {}
+typedef V F<U, V>(U u);
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..d565888
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  get x => null;
+  void set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d565888
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  get x => null;
+  void set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..bdcdbfe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  int f() => null;
+}
+
+g(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bdcdbfe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  int f() => null;
+}
+
+g(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline.expect
new file mode 100644
index 0000000..ce42724
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  int x;
+}
+
+void f(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99cd276
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  int x;
+}
+
+main() {}
+void f(C c) {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline.expect
new file mode 100644
index 0000000..4a1f36a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+var h = null;
+void foo(int f(Object _)) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1183aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+main() {}
+test() {}
+var h = null;
+void foo(int f(Object _)) {}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline.expect b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..e9719ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class NullEquality {
+  @override
+  Null operator ==(Object other) => null;
+}
+
+class SubNullEquality extends NullEquality {
+  void test() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b6b202b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class NullEquality {
+  @override
+  Null operator ==(Object other) => null;
+}
+
+class SubNullEquality extends NullEquality {
+  void test() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..60962ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A<X> {
+  final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+  final foo;
+  B(this.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dbeb61d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A<X> {
+  final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+  B(this.foo);
+  final foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..d69f3e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A<X> {
+  void foo({Iterable<X> x});
+}
+
+class B<Y> implements A<Y> {
+  void foo({x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d69f3e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A<X> {
+  void foo({Iterable<X> x});
+}
+
+class B<Y> implements A<Y> {
+  void foo({x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0f15872d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void optional_toplevel([List<int> x = const []]) {}
+void named_toplevel({List<int> x: const []}) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..88548f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void named_toplevel({List<int> x: const []}) {}
+void optional_toplevel([List<int> x = const []]) {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..99ee48d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C.optional(void func([T x])) {}
+  C.named(void func({T x})) {}
+}
+
+void optional_toplevel([x = const [0]]) {}
+void named_toplevel({x: const [0]}) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b07f840
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C.named(void func({T x})) {}
+  C.optional(void func([T x])) {}
+}
+
+main() {}
+void named_toplevel({x: const [0]}) {}
+void optional_toplevel([x = const [0]]) {}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..a353121
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class B {
+  void foo();
+}
+
+abstract class C extends B {
+  void bar();
+}
+
+void f<T extends B>(T a) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..08ef9b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class B {
+  void foo();
+}
+
+abstract class C extends B {
+  void bar();
+}
+
+main() {}
+void f<T extends B>(T a) {}
diff --git a/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline.expect b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline.expect
new file mode 100644
index 0000000..31d41a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(Object a, bool b) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17f0601
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(Object a, bool b) {}
diff --git a/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline.expect b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline.expect
new file mode 100644
index 0000000..563c2f1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void f(Object x) {}
+void g(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8442684
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void f(Object x) {}
+void g(int x) {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline.expect
new file mode 100644
index 0000000..40b29e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+test5() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ee5c2f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+  int x = 2;
+}
+
+main() {}
+test5() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline.expect
new file mode 100644
index 0000000..774ec6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+  int x = 42;
+}
+
+class B {
+  A a = new A();
+}
+
+class C {
+  B b = new B();
+}
+
+class D {
+  C c = new C();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..774ec6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+  int x = 42;
+}
+
+class B {
+  A a = new A();
+}
+
+class C {
+  B b = new B();
+}
+
+class D {
+  C c = new C();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..46d302a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C {
+  int field = 0;
+  int get getter => 0;
+  int function() => 0;
+}
+
+C c = new C();
+var function_ref = c.function;
+var function_ref_list = [c.function];
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb636c41
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+C c = new C();
+
+class C {
+  int field = 0;
+  int function() => 0;
+  int get getter => 0;
+}
+
+main() {}
+var function_ref = c.function;
+var function_ref_list = [c.function];
diff --git a/pkg/front_end/testcases/inference/property_set.dart.textual_outline.expect b/pkg/front_end/testcases/inference/property_set.dart.textual_outline.expect
new file mode 100644
index 0000000..fbf41d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+  List<T> x;
+  void set y(List<T> value) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/property_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99f7782
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+  List<T> x;
+  void set y(List<T> value) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..6eadbb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+  void set x() {}
+}
+
+void f(A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3df6a19
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+  void set x() {}
+}
+
+main() {}
+void f(A a) {}
diff --git a/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline.expect b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline.expect
new file mode 100644
index 0000000..f07684b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void _mergeSort<T>(
+    T Function(T) list, int compare(T a, T b), T Function(T) target) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f5ec10
--- /dev/null
+++ b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void _mergeSort<T>(
+    T Function(T) list, int compare(T a, T b), T Function(T) target) {}
diff --git a/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..1868d7f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef void F();
+final x = F;
+main() {}
diff --git a/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..808266d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+final x = F;
+main() {}
+typedef void F();
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline.expect
new file mode 100644
index 0000000..0b91a55
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T extends num> {
+  T a;
+  void op(double b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b91a55
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T extends num> {
+  T a;
+  void op(double b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline.expect
new file mode 100644
index 0000000..e352327
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+  T a;
+  void op(int b) {}
+  void opEq(int b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e352327
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+  T a;
+  void op(int b) {}
+  void opEq(int b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline.expect
new file mode 100644
index 0000000..34c354c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+  T a;
+  void op(T b) {}
+  void opEq(T b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..34c354c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+  T a;
+  void op(T b) {}
+  void opEq(T b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..f9485e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  dynamic set x(int value) {}
+}
+
+abstract class I {
+  void set x(int value) {}
+}
+
+class D extends C implements I {
+  set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..001950d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I {
+  void set x(int value) {}
+}
+
+class C {
+  dynamic set x(int value) {}
+}
+
+class D extends C implements I {
+  set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline.expect
new file mode 100644
index 0000000..452bced
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = true;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7a57ef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = true;
diff --git a/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline.expect
new file mode 100644
index 0000000..04971e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = 1.2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb4b7ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = 1.2;
diff --git a/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline.expect
new file mode 100644
index 0000000..83e091a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = 1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..60b453a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = 1;
diff --git a/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline.expect
new file mode 100644
index 0000000..5ca6d2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..931bd7b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = null;
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..26d186e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+const v = C.f;
+
+class C {
+  static int f(String s) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bf32f5c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  static int f(String s) => null;
+}
+
+const v = C.f;
+main() {}
diff --git a/pkg/front_end/testcases/inference/string_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..40f25d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var x = 1;
+var a = 'aaa';
+var b = 'b ${x} bb';
+var c = 'c ${x} cc' 'ccc';
+main() {}
diff --git a/pkg/front_end/testcases/inference/string_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8bb8a7d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+var a = 'aaa';
+var b = 'b ${x} bb';
+var c = 'c ${x} cc' 'ccc';
+var x = 1;
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..46a9d5d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  List<num> x = [0];
+}
+
+List<num> y = [0];
+main() {}
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fa8bd40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+List<num> y = [0];
+
+class C {
+  List<num> x = [0];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline.expect
new file mode 100644
index 0000000..dcae9ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+  void operator []=(int x, String y) {}
+}
+
+class C extends B {
+  void operator []=(Object x, Object y) {}
+  void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aeaf352
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+  void operator []=(int x, String y) {}
+}
+
+class C extends B {
+  void h() {}
+  void operator []=(Object x, Object y) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..aac365a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+  void operator []=(Map<int, T> x, List<T> y) {}
+}
+
+class C<U> extends B<Future<U>> {
+  void operator []=(Object x, Object y) {}
+  void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5a33bc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+  void operator []=(Map<int, T> x, List<T> y) {}
+}
+
+class C<U> extends B<Future<U>> {
+  void h() {}
+  void operator []=(Object x, Object y) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..adf9262
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class C extends B {
+  C() : super(f());
+}
+
+class B {
+  B(int x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d335a89
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class B {
+  B(int x);
+}
+
+class C extends B {
+  C() : super(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..9ebda13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class B<T> {
+  B(T t);
+}
+
+class C<U> extends B<List<U>> {
+  C() : super(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ebda13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class B<T> {
+  B(T t);
+}
+
+class C<U> extends B<List<U>> {
+  C() : super(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  int f() => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  int f() => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..d1bf59d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+  D<T> g(E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> g(Object x) => null;
+  void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..276cc12
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+  D<T> g(E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> g(Object x) => null;
+  void h() {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline.expect
new file mode 100644
index 0000000..e878396
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  var x = 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e878396
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  var x = 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..7d71a90
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  var f = () => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d71a90
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  var f = () => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline.expect
new file mode 100644
index 0000000..f9b1f9f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class CallableClass {
+  int call() => 0;
+}
+
+class C {
+  var f = new CallableClass();
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4764b64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  var f = new CallableClass();
+}
+
+class CallableClass {
+  int call() => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..fd7f136
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+import 'dart:async';
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+  D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> get x => null;
+  void set x(Object x) {}
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1082016
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+import 'dart:async';
+
+class B<T> {
+  D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> get x => null;
+  void g() {}
+  void set x(Object x) {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  int f() => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  int f() => 0;
+}
+
+class D extends C {
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..52e795a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+  D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> get x => null;
+  void set x(Object x) {}
+  void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45e3806
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+  D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> get x => null;
+  void g() {}
+  void set x(Object x) {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline.expect b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline.expect
new file mode 100644
index 0000000..de6340a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(int x, void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3712403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(int x, void f()) {}
diff --git a/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline.expect
new file mode 100644
index 0000000..c213951
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  void f() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c213951
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  void f() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
index a34ea59..dc1653d 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'FutureOr' is from 'dart:async'.
 //   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                    ^
@@ -18,7 +19,8 @@
   return (core::int* x) → core::int* => x;
 }
 static method b() → asy::Future<(core::int*) →* core::int*>* async {
-  return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+  return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
  - 'FutureOr' is from 'dart:async'.
   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                    ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
index f6ea666..9ebedc0 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'FutureOr' is from 'dart:async'.
 //   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                    ^
@@ -21,15 +22,16 @@
   final asy::_AsyncAwaitCompleter<(core::int*) →* core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<(core::int*) →* core::int*>();
   asy::FutureOr<(core::int*) →* core::int*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
     try {
       #L1:
       {
-        :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+        :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
  - 'FutureOr' is from 'dart:async'.
   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                    ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
@@ -38,13 +40,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method c() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
@@ -79,8 +81,8 @@
   asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -97,7 +99,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -114,8 +116,8 @@
   asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -132,7 +134,7 @@
         }
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline.expect
new file mode 100644
index 0000000..505dfb3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+typedef int IntToInt(int i);
+IntToInt a() {}
+Future<IntToInt> b() async {}
+Iterable<IntToInt> c() sync* {}
+Iterable<IntToInt> d() sync* {}
+Stream<IntToInt> e() async* {}
+Stream<IntToInt> f() async* {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1047aa8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+Future<IntToInt> b() async {}
+IntToInt a() {}
+Iterable<IntToInt> c() sync* {}
+Iterable<IntToInt> d() sync* {}
+Stream<IntToInt> e() async* {}
+Stream<IntToInt> f() async* {}
+main() {}
+typedef int IntToInt(int i);
diff --git a/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline.expect b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline.expect
new file mode 100644
index 0000000..8a7c345
--- /dev/null
+++ b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var i = 0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13c449d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var i = 0;
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline.expect
new file mode 100644
index 0000000..e8f8435
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f476f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline.expect
new file mode 100644
index 0000000..e8f8435
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f476f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..a9c0032
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D extends C {}
+
+class E extends StackTrace {}
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..595703f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D extends C {}
+
+class E extends StackTrace {}
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/try_finally.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline.expect
new file mode 100644
index 0000000..4323848
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_finally.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6847854
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline.expect
new file mode 100644
index 0000000..eccaf58
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A<T> {}
+
+class B<T> extends A<T> {
+  foo() {}
+}
+
+A<num> a = new B<int>();
+var b = (a as B<int>);
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5483162
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+A<num> a = new B<int>();
+
+class A<T> {}
+
+class B<T> extends A<T> {
+  foo() {}
+}
+
+main() {}
+var b = (a as B<int>);
diff --git a/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline.expect
new file mode 100644
index 0000000..0c1f1fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef int FunctionReturningInt();
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..350cc2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef int FunctionReturningInt();
diff --git a/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline.expect
new file mode 100644
index 0000000..0970cc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void f(Object x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e9a9e8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void f(Object x) {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline.expect
new file mode 100644
index 0000000..46441e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46441e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline.expect
new file mode 100644
index 0000000..94fe6c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C(T x());
+}
+
+var v = new C<dynamic>(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faaeac6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C(T x());
+}
+
+main() {}
+var v = new C<dynamic>(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..045c2e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C(T x());
+}
+
+var v = new C<int>(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7917d91
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  C(T x());
+}
+
+main() {}
+var v = new C<int>(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..db10511
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  C(T x());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..db10511
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+  C(T x());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..77314e89
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  C(x());
+}
+
+var v = new C(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b916948
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  C(x());
+}
+
+main() {}
+var v = new C(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline.expect
new file mode 100644
index 0000000..5426b5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = f<dynamic>(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aed6c69
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = f<dynamic>(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.textual_outline.expect
new file mode 100644
index 0000000..584632f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f<dynamic>)( () { return 1; });
+main() { }
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..6fabe27
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)<dynamic>(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99e882a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)<dynamic>(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..3146638
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = f<int>(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df8a26a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = f<int>(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.textual_outline.expect
new file mode 100644
index 0000000..a966a2f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f<int>)( () { return 1; });
+main() { }
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..c7bca42
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)<int>(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f634c6a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)<int>(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..6104397
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+List<T> f<T>(T g()) => <T>[g()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..158c522b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline.expect
new file mode 100644
index 0000000..6104397
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+List<T> f<T>(T g()) => <T>[g()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..158c522b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..a0e3c88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+double f(x) => 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3fe047c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+double f(x) => 1.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline.expect
new file mode 100644
index 0000000..a0e3c88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+double f(x) => 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3fe047c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+double f(x) => 1.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..0286208
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef int F();
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..226c034
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..0286208
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef int F();
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..226c034
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..5dfe4b0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  double f(x) => 1.0;
+}
+
+var v = new C().f(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..470fb87
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  double f(x) => 1.0;
+}
+
+main() {}
+var v = new C().f(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..ffe2084
--- /dev/null
+++ b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+void printRunning() {}
+var x = run<dynamic>(printRunning);
+main() {}
diff --git a/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65a862b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+main() {}
+var x = run<dynamic>(printRunning);
+void printRunning() {}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..e44b24c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+typedef V F<U, V>(U u);
+
+class Foo<T> {
+  Bar<T> get v1 => const Bar();
+  Bar<List<T>> get v2 => const Bar();
+  Bar<F<T, T>> get v3 => const Bar();
+  Bar<F<F<T, T>, T>> get v4 => const Bar();
+  List<T> get v5 => const [];
+  List<F<T, T>> get v6 => const [];
+  Map<T, T> get v7 => const {};
+  Map<F<T, T>, T> get v8 => const {};
+  Map<T, F<T, T>> get v9 => const {};
+}
+
+class Bar<T> {
+  const Bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ebcecde
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+class Bar<T> {
+  const Bar();
+}
+
+class Foo<T> {
+  Bar<F<F<T, T>, T>> get v4 => const Bar();
+  Bar<F<T, T>> get v3 => const Bar();
+  Bar<List<T>> get v2 => const Bar();
+  Bar<T> get v1 => const Bar();
+  List<F<T, T>> get v6 => const [];
+  List<T> get v5 => const [];
+  Map<F<T, T>, T> get v8 => const {};
+  Map<T, F<T, T>> get v9 => const {};
+  Map<T, T> get v7 => const {};
+}
+
+main() {}
+typedef V F<U, V>(U u);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
index 3b1a187..e89c7cf 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
@@ -20,7 +20,7 @@
     return 0;
 }
 static field self::A* a = new self::A::•();
-static field invalid-type b = (() → () →* invalid-type => self::a.{self::A::f}<() →* invalid-type>(self::c)) as{TypeError} invalid-type;
+static field invalid-type b = () → () →* invalid-type => self::a.{self::A::f}<() →* invalid-type>(self::c);
 static field () →* invalid-type c = () → invalid-type => self::a.{self::A::f}<invalid-type>(self::b);
 static field () →* () →* core::int* d = () → () →* core::int* => self::a.{self::A::f}<() →* core::int*>(self::e);
 static field () →* core::int* e = () → core::int* => self::a.{self::A::g}(self::d);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
index 3b1a187..e89c7cf 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
@@ -20,7 +20,7 @@
     return 0;
 }
 static field self::A* a = new self::A::•();
-static field invalid-type b = (() → () →* invalid-type => self::a.{self::A::f}<() →* invalid-type>(self::c)) as{TypeError} invalid-type;
+static field invalid-type b = () → () →* invalid-type => self::a.{self::A::f}<() →* invalid-type>(self::c);
 static field () →* invalid-type c = () → invalid-type => self::a.{self::A::f}<invalid-type>(self::b);
 static field () →* () →* core::int* d = () → () →* core::int* => self::a.{self::A::f}<() →* core::int*>(self::e);
 static field () →* core::int* e = () → core::int* => self::a.{self::A::g}(self::d);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline.expect
new file mode 100644
index 0000000..05229f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  T f<T>(T t) => t;
+  int g(dynamic i) => 0;
+}
+
+var a = new A();
+var b = () => a.f(c);
+var c = () => a.f(b);
+var d = () => a.f(e);
+var e = () => a.g(d);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f55a46
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  T f<T>(T t) => t;
+  int g(dynamic i) => 0;
+}
+
+main() {}
+var a = new A();
+var b = () => a.f(c);
+var c = () => a.f(b);
+var d = () => a.f(e);
+var e = () => a.g(d);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
index 2620e6d..f3dce3c 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
@@ -13,7 +13,7 @@
 static field core::int* intValue = 0;
 static field core::num* numValue = 0;
 static field core::double* doubleValue = 0.0;
-static field invalid-type a = (() → core::num* => self::intValue.{core::num::+}(self::b as{TypeError,ForDynamic} core::num*)) as{TypeError} invalid-type;
+static field invalid-type a = () → core::num* => self::intValue.{core::num::+}(self::b as{TypeError,ForDynamic} core::num*);
 static field dynamic b = self::a.call();
 static field () →* core::num* c = () → core::num* => self::numValue.{core::num::+}(self::d);
 static field core::num* d = self::c.call();
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
index 2620e6d..f3dce3c 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
@@ -13,7 +13,7 @@
 static field core::int* intValue = 0;
 static field core::num* numValue = 0;
 static field core::double* doubleValue = 0.0;
-static field invalid-type a = (() → core::num* => self::intValue.{core::num::+}(self::b as{TypeError,ForDynamic} core::num*)) as{TypeError} invalid-type;
+static field invalid-type a = () → core::num* => self::intValue.{core::num::+}(self::b as{TypeError,ForDynamic} core::num*);
 static field dynamic b = self::a.call();
 static field () →* core::num* c = () → core::num* => self::numValue.{core::num::+}(self::d);
 static field core::num* d = self::c.call();
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline.expect
new file mode 100644
index 0000000..db69969
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+int intValue = 0;
+num numValue = 0;
+double doubleValue = 0.0;
+var a = () => intValue + b;
+var b = a();
+var c = () => numValue + d;
+var d = c();
+var e = () => doubleValue + f;
+var f = e();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5009f27
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+double doubleValue = 0.0;
+int intValue = 0;
+main() {}
+num numValue = 0;
+var a = () => intValue + b;
+var b = a();
+var c = () => numValue + d;
+var d = c();
+var e = () => doubleValue + f;
+var f = e();
diff --git a/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..cdb201d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..d781f4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  B<int> b;
+}
+
+class B<T> {
+  B(T x);
+}
+
+var t3 = [new B(3)];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..56d49b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+  B<int> b;
+}
+
+class B<T> {
+  B(T x);
+}
+
+main() {}
+var t3 = [new B(3)];
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline.expect
new file mode 100644
index 0000000..c5e4a4c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+  A(T x);
+}
+
+var t2 = [new A(2)];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4da7ccb
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+  A(T x);
+}
+
+main() {}
+var t2 = [new A(2)];
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
index 3de0169..5367e37 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 
 class A extends core::Object {
-  field invalid-type x = (() → invalid-type => new self::B::•().{self::B::x}) as{TypeError} invalid-type;
+  field invalid-type x = () → invalid-type => new self::B::•().{self::B::x};
   field () →* invalid-type y = () → invalid-type => new self::B::•().{self::B::x};
   synthetic constructor •() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
index 3de0169..5367e37 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 
 class A extends core::Object {
-  field invalid-type x = (() → invalid-type => new self::B::•().{self::B::x}) as{TypeError} invalid-type;
+  field invalid-type x = () → invalid-type => new self::B::•().{self::B::x};
   field () →* invalid-type y = () → invalid-type => new self::B::•().{self::B::x};
   synthetic constructor •() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline.expect
new file mode 100644
index 0000000..fa0576a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  var x = () => new B().x;
+  var y = () => new B().x;
+}
+
+class B extends A {
+  var x;
+  var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fa0576a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+  var x = () => new B().x;
+  var y = () => new B().x;
+}
+
+class B extends A {
+  var x;
+  var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect
index 6bbfddf..3b7b28d 100644
--- a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library test;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → self::A*
@@ -17,7 +16,7 @@
   method test() → void {
     self::A* aLocal;
     {
-      core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(self::f<core::Iterable<self::A*>*>()).{core::Iterable::iterator};
+      core::Iterator<self::A*>* :sync-for-iterator = self::f<core::Iterable<self::A*>*>().{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final self::A* #t1 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -26,7 +25,7 @@
       }
     }
     {
-      core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(self::f<core::Iterable<self::A*>*>()).{core::Iterable::iterator};
+      core::Iterator<self::A*>* :sync-for-iterator = self::f<core::Iterable<self::A*>*>().{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final self::A* #t2 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -35,7 +34,7 @@
       }
     }
     {
-      core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(self::f<core::Iterable<self::A*>*>()).{core::Iterable::iterator};
+      core::Iterator<self::A*>* :sync-for-iterator = self::f<core::Iterable<self::A*>*>().{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final self::A* #t3 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -44,7 +43,7 @@
       }
     }
     {
-      core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(self::f<core::Iterable<self::A*>*>()).{core::Iterable::iterator};
+      core::Iterator<self::A*>* :sync-for-iterator = self::f<core::Iterable<self::A*>*>().{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final self::A* #t4 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -53,7 +52,7 @@
       }
     }
     {
-      core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(self::f<core::Iterable<self::A*>*>()).{core::Iterable::iterator};
+      core::Iterator<self::A*>* :sync-for-iterator = self::f<core::Iterable<self::A*>*>().{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final self::A* #t5 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..81dec4b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+A aTopLevel;
+void set aTopLevelSetter(A value) {}
+
+class C {
+  A aField;
+  void set aSetter(A value) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..492e0aa
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+A aTopLevel;
+T f<T>() => null;
+
+class A {}
+
+class C {
+  A aField;
+  void set aSetter(A value) {}
+  void test() {}
+}
+
+main() {}
+void set aTopLevelSetter(A value) {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
index 796c34d..4cab266 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
@@ -31,8 +31,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -45,7 +45,7 @@
       {
         core::String* s;
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:17: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+          core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:17: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   for (int x in s) {}
                 ^" in s as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -57,7 +57,7 @@
           }
         }
         {
-          dynamic :stream = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:11:23: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:11:23: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   await for (int x in s) {}
                       ^" in s as{TypeError} asy::Stream<dynamic>*;
@@ -85,7 +85,7 @@
         }
         core::int* y;
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:13:13: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+          core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:13:13: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   for (y in s) {}
             ^" in s as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
@@ -97,7 +97,7 @@
           }
         }
         {
-          dynamic :stream = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:14:19: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:14:19: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   await for (y in s) {}
                   ^" in s as{TypeError} asy::Stream<dynamic>*;
@@ -127,13 +127,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline.expect
new file mode 100644
index 0000000..178286b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4791aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
index 480adea..eac8b7c 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
@@ -37,8 +37,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -55,7 +55,7 @@
         self::B* b;
         core::int* i;
         {
-          core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(iterable).{core::Iterable::iterator};
+          core::Iterator<self::A*>* :sync-for-iterator = iterable.{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final self::A* #t1 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -64,7 +64,7 @@
           }
         }
         {
-          dynamic :stream = stream;
+          asy::Stream<self::A*>* :stream = stream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::A*>* :for-iterator = new asy::_StreamIterator::•<self::A*>(:stream);
           try
@@ -88,7 +88,7 @@
             }
         }
         {
-          core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(iterable).{core::Iterable::iterator};
+          core::Iterator<self::A*>* :sync-for-iterator = iterable.{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final self::A* #t6 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -97,7 +97,7 @@
           }
         }
         {
-          dynamic :stream = stream;
+          asy::Stream<self::A*>* :stream = stream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::A*>* :for-iterator = new asy::_StreamIterator::•<self::A*>(:stream);
           try
@@ -121,7 +121,7 @@
             }
         }
         {
-          core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(iterable).{core::Iterable::iterator};
+          core::Iterator<self::A*>* :sync-for-iterator = iterable.{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final self::A* #t11 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -134,7 +134,7 @@
           }
         }
         {
-          dynamic :stream = stream;
+          asy::Stream<self::A*>* :stream = stream;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::A*>* :for-iterator = new asy::_StreamIterator::•<self::A*>(:stream);
           try
@@ -162,7 +162,7 @@
             }
         }
         {
-          core::Iterator<self::A*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::A*>*>(self::f<core::Iterable<self::A*>*>()).{core::Iterable::iterator};
+          core::Iterator<self::A*>* :sync-for-iterator = self::f<core::Iterable<self::A*>*>().{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             final self::A* #t18 = :sync-for-iterator.{core::Iterator::current};
             {
@@ -171,7 +171,7 @@
           }
         }
         {
-          dynamic :stream = self::f<asy::Stream<self::A*>*>();
+          asy::Stream<self::A*>* :stream = self::f<asy::Stream<self::A*>*>();
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<self::A*>* :for-iterator = new asy::_StreamIterator::•<self::A*>(:stream);
           try
@@ -198,13 +198,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline.expect
new file mode 100644
index 0000000..d166bc9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {}
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f55cead
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {}
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..a7060ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+  C operator +(int value) => null;
+  C operator *(D value) => null;
+}
+
+class B {
+  E operator +(int value) => null;
+  E operator *(F value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+  A operator [](int i) => null;
+  void operator []=(int i, B value) {}
+}
+
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e78520
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+  C operator *(D value) => null;
+  C operator +(int value) => null;
+}
+
+class B {
+  E operator *(F value) => null;
+  E operator +(int value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+  A operator [](int i) => null;
+  void operator []=(int i, B value) {}
+}
+
+main() {}
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..cce1286
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B member;
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fedf127
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+  B member;
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..5aea77f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+  int t;
+  void test() {}
+}
+
+class Test2 {
+  num t;
+  void test() {}
+}
+
+class Test3 {
+  double t;
+  void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07ae2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+  int t;
+  void test() {}
+}
+
+class Test2 {
+  num t;
+  void test() {}
+}
+
+class Test3 {
+  double t;
+  void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline.expect
new file mode 100644
index 0000000..c70181a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+List<double> a = <double>[];
+var b = (a[0] = 1.0);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89115d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+List<double> a = <double>[];
+main() {}
+var b = (a[0] = 1.0);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline.expect
new file mode 100644
index 0000000..d7ce8b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+class Index {}
+
+class A {
+  C operator +(F v) => null;
+  C operator -(int i) => null;
+}
+
+class B extends A {
+  D operator +(E v) => null;
+  D operator -(int i) => null;
+}
+
+class C extends B {}
+
+class D extends C {}
+
+class E extends D {}
+
+class F extends E {}
+
+T f<T>() => null;
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, A v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82d9240
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+  C operator +(F v) => null;
+  C operator -(int i) => null;
+}
+
+class B extends A {
+  D operator +(E v) => null;
+  D operator -(int i) => null;
+}
+
+class C extends B {}
+
+class D extends C {}
+
+class E extends D {}
+
+class F extends E {}
+
+class Index {}
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, A v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline.expect
new file mode 100644
index 0000000..0082739
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3153d49
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class Base {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..532c44a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline.expect
@@ -0,0 +1,50 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+abstract class Base<T, U> {
+  T operator [](String s) => getValue(s);
+  void operator []=(String s, U v) => setValue(s, v);
+  T getValue(String s);
+  void setValue(String s, U v);
+}
+
+abstract class Test1 extends Base<int, int> {
+  void test() {}
+}
+
+abstract class Test2 extends Base<int, num> {
+  void test() {}
+}
+
+abstract class Test3 extends Base<int, double> {
+  void test() {}
+}
+
+abstract class Test4 extends Base<num, int> {
+  void test() {}
+}
+
+abstract class Test5 extends Base<num, num> {
+  void test() {}
+}
+
+abstract class Test6 extends Base<num, double> {
+  void test() {}
+}
+
+abstract class Test7 extends Base<double, int> {
+  void test() {}
+}
+
+abstract class Test8 extends Base<double, num> {
+  void test() {}
+}
+
+abstract class Test9 extends Base<double, double> {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8860e7d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+library test;
+
+abstract class Base<T, U> {
+  T getValue(String s);
+  T operator [](String s) => getValue(s);
+  void operator []=(String s, U v) => setValue(s, v);
+  void setValue(String s, U v);
+}
+
+abstract class Test1 extends Base<int, int> {
+  void test() {}
+}
+
+abstract class Test2 extends Base<int, num> {
+  void test() {}
+}
+
+abstract class Test3 extends Base<int, double> {
+  void test() {}
+}
+
+abstract class Test4 extends Base<num, int> {
+  void test() {}
+}
+
+abstract class Test5 extends Base<num, num> {
+  void test() {}
+}
+
+abstract class Test6 extends Base<num, double> {
+  void test() {}
+}
+
+abstract class Test7 extends Base<double, int> {
+  void test() {}
+}
+
+abstract class Test8 extends Base<double, num> {
+  void test() {}
+}
+
+abstract class Test9 extends Base<double, double> {
+  void test() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+  B operator [](Index i) => null;
+  void operator []=(Index i, B v) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d4cf186
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline.expect
@@ -0,0 +1,61 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+abstract class Test1 {
+  int operator [](String s);
+  void operator []=(String s, int v);
+  void test() {}
+}
+
+abstract class Test2 {
+  int operator [](String s);
+  void operator []=(String s, num v);
+  void test() {}
+}
+
+abstract class Test3 {
+  int operator [](String s);
+  void operator []=(String s, double v);
+  void test() {}
+}
+
+abstract class Test4 {
+  num operator [](String s);
+  void operator []=(String s, int v);
+  void test() {}
+}
+
+abstract class Test5 {
+  num operator [](String s);
+  void operator []=(String s, num v);
+  void test() {}
+}
+
+abstract class Test6 {
+  num operator [](String s);
+  void operator []=(String s, double v);
+  void test() {}
+}
+
+abstract class Test7 {
+  double operator [](String s);
+  void operator []=(String s, int v);
+  void test() {}
+}
+
+abstract class Test8 {
+  double operator [](String s);
+  void operator []=(String s, num v);
+  void test() {}
+}
+
+abstract class Test9 {
+  double operator [](String s);
+  void operator []=(String s, double v);
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..97ebc39
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,60 @@
+library test;
+
+abstract class Test1 {
+  int operator [](String s);
+  void operator []=(String s, int v);
+  void test() {}
+}
+
+abstract class Test2 {
+  int operator [](String s);
+  void operator []=(String s, num v);
+  void test() {}
+}
+
+abstract class Test3 {
+  int operator [](String s);
+  void operator []=(String s, double v);
+  void test() {}
+}
+
+abstract class Test4 {
+  num operator [](String s);
+  void operator []=(String s, int v);
+  void test() {}
+}
+
+abstract class Test5 {
+  num operator [](String s);
+  void operator []=(String s, num v);
+  void test() {}
+}
+
+abstract class Test6 {
+  num operator [](String s);
+  void operator []=(String s, double v);
+  void test() {}
+}
+
+abstract class Test7 {
+  double operator [](String s);
+  void operator []=(String s, int v);
+  void test() {}
+}
+
+abstract class Test8 {
+  double operator [](String s);
+  void operator []=(String s, num v);
+  void test() {}
+}
+
+abstract class Test9 {
+  double operator [](String s);
+  void operator []=(String s, double v);
+  void test() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..3217b84
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+abstract class Test<T, U> {
+  T operator [](String s);
+  void operator []=(String s, U v);
+}
+
+void test1(Test<int, int> t) {}
+void test2(Test<int, num> t) {}
+void test3(Test<int, double> t) {}
+void test4(Test<num, int> t) {}
+void test5(Test<num, num> t) {}
+void test6(Test<num, double> t) {}
+void test7(Test<double, int> t) {}
+void test8(Test<double, num> t) {}
+void test9(Test<double, double> t) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..db75467
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+abstract class Test<T, U> {
+  T operator [](String s);
+  void operator []=(String s, U v);
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
+void test1(Test<int, int> t) {}
+void test2(Test<int, num> t) {}
+void test3(Test<int, double> t) {}
+void test4(Test<num, int> t) {}
+void test5(Test<num, num> t) {}
+void test6(Test<num, double> t) {}
+void test7(Test<double, int> t) {}
+void test8(Test<double, num> t) {}
+void test9(Test<double, double> t) {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline.expect
new file mode 100644
index 0000000..54818ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..370d98d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d9659ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f01f8e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline.expect
new file mode 100644
index 0000000..578332f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A {
+  int f;
+}
+
+var v_assign = (new A().f = 1);
+var v_plus = (new A().f += 1);
+var v_minus = (new A().f -= 1);
+var v_multiply = (new A().f *= 1);
+var v_prefix_pp = (++new A().f);
+var v_prefix_mm = (--new A().f);
+var v_postfix_pp = (new A().f++);
+var v_postfix_mm = (new A().f--);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..35df05a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A {
+  int f;
+}
+
+main() {}
+var v_assign = (new A().f = 1);
+var v_minus = (new A().f -= 1);
+var v_multiply = (new A().f *= 1);
+var v_plus = (new A().f += 1);
+var v_postfix_mm = (new A().f--);
+var v_postfix_pp = (new A().f++);
+var v_prefix_mm = (--new A().f);
+var v_prefix_pp = (++new A().f);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline.expect
new file mode 100644
index 0000000..7edc4ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {
+  int operator +(other) => 1;
+  double operator -(other) => 2.0;
+}
+
+class B {
+  A a;
+}
+
+var v_prefix_pp = (++new B().a);
+var v_prefix_mm = (--new B().a);
+var v_postfix_pp = (new B().a++);
+var v_postfix_mm = (new B().a--);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..50cda50
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {
+  double operator -(other) => 2.0;
+  int operator +(other) => 1;
+}
+
+class B {
+  A a;
+}
+
+main() {}
+var v_postfix_mm = (new B().a--);
+var v_postfix_pp = (new B().a++);
+var v_prefix_mm = (--new B().a);
+var v_prefix_pp = (++new B().a);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+  B member;
+  static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline.expect
new file mode 100644
index 0000000..2d1227e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+  B member;
+}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cdf4959
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+}
+
+class Base {
+  B member;
+}
+
+class C extends B {}
+
+class Test extends Base {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..31af0c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Base {
+  int intProp;
+  num numProp;
+  double doubleProp;
+}
+
+class Test1 extends Base {
+  void test() {}
+}
+
+class Test2 extends Base {
+  void test() {}
+}
+
+class Test3 extends Base {
+  void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d5e219
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Base {
+  double doubleProp;
+  int intProp;
+  num numProp;
+}
+
+class Test1 extends Base {
+  void test() {}
+}
+
+class Test2 extends Base {
+  void test() {}
+}
+
+class Test3 extends Base {
+  void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+  int prop;
+  static void test(Test1 t) {}
+}
+
+class Test2 {
+  num prop;
+  static void test(Test2 t) {}
+}
+
+class Test3 {
+  double prop;
+  static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..433e168
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+  int f;
+}
+
+A a = new A();
+var b = (a.f = 1);
+var c = 0;
+var d = (c = 1);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1ca26e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+A a = new A();
+
+class A {
+  int f;
+}
+
+main() {}
+var b = (a.f = 1);
+var c = 0;
+var d = (c = 1);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline.expect
new file mode 100644
index 0000000..3ee6268
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator -(int i) => null;
+  B operator *(B v) => null;
+  C operator &(A v) => null;
+  static B staticVariable;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+B topLevelVariable;
+void test_topLevelVariable() {}
+void test_staticVariable() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..667b734
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+B topLevelVariable;
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+  A operator +(C v) => null;
+  B operator *(B v) => null;
+  B operator -(int i) => null;
+  C operator &(A v) => null;
+  static B staticVariable;
+}
+
+class C extends B {}
+
+main() {}
+void test_staticVariable() {}
+void test_topLevelVariable() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..13362e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+int topLevelInt;
+num topLevelNum;
+double topLevelDouble;
+void test1() {}
+void test2() {}
+void test3() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b31b13
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+double getDouble() => 0.0;
+double topLevelDouble;
+int getInt() => 0;
+int topLevelInt;
+main() {}
+num getNum() => 0;
+num topLevelNum;
+void test1() {}
+void test2() {}
+void test3() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..b979107
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+  int get x;
+  void set x(double value);
+}
+
+class B extends A {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b979107
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+  int get x;
+  void set x(double value);
+}
+
+class B extends A {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..0edf6d2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+abstract class A {
+  A get x;
+  void set x(B value);
+  B get y;
+  void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+  var x;
+  var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4747c1a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class A {
+  A get x;
+  B get y;
+  void set x(B value);
+  void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+  var x;
+  var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..305abb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+  void set x(num value);
+}
+
+abstract class B extends A {
+  int get x;
+}
+
+class C extends B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..305abb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+  void set x(num value);
+}
+
+abstract class B extends A {
+  int get x;
+}
+
+class C extends B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..bd5d090
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+  num get x;
+}
+
+abstract class B extends A {
+  void set x(int value);
+}
+
+class C extends B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd5d090
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+  num get x;
+}
+
+abstract class B extends A {
+  void set x(int value);
+}
+
+class C extends B {
+  var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..2f8867c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+  B b;
+}
+
+class B {
+  C get c => null;
+  void set c(C value) {}
+}
+
+class C {}
+
+class D extends C {}
+
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4dbc562
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+  B b;
+}
+
+class B {
+  C get c => null;
+  void set c(C value) {}
+}
+
+class C {}
+
+class D extends C {}
+
+main() {}
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..1c47cb0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+library test;
+
+class A {
+  B b;
+}
+
+class B {
+  C c;
+}
+
+class C {}
+
+class D extends C {}
+
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..83d5264
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+class A {
+  B b;
+}
+
+class B {
+  C c;
+}
+
+class C {}
+
+class D extends C {}
+
+main() {}
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
index e6998d8..0f7cb20 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 
 class A extends core::Object {
-  field invalid-type b = (() → () →* invalid-type => self::x) as{TypeError} invalid-type;
+  field invalid-type b = () → () →* invalid-type => self::x;
   field () →* () →* invalid-type c = () → () →* invalid-type => self::x;
   synthetic constructor •() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
index e6998d8..0f7cb20 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 
 class A extends core::Object {
-  field invalid-type b = (() → () →* invalid-type => self::x) as{TypeError} invalid-type;
+  field invalid-type b = () → () →* invalid-type => self::x;
   field () →* () →* invalid-type c = () → () →* invalid-type => self::x;
   synthetic constructor •() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline.expect
new file mode 100644
index 0000000..1d3b6a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+  var b = () => x;
+  var c = () => x;
+}
+
+var a = new A();
+var x = () => a.b;
+var y = () => a.c;
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e8f476
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+  var b = () => x;
+  var c = () => x;
+}
+
+main() {}
+var a = new A();
+var x = () => a.b;
+var y = () => a.c;
diff --git a/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline.expect
new file mode 100644
index 0000000..a739ce7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+T f<T>() => null;
+var x = f() || f();
+var y = f() && f();
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..15d8c5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+T f<T>() => null;
+main() {}
+var x = f() || f();
+var y = f() && f();
+void test() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline.expect
new file mode 100644
index 0000000..fccbad0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class B {
+  void f() {}
+}
+
+class C extends B {
+  f() {}
+}
+
+var x = new C().f();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..deba2e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class B {
+  void f() {}
+}
+
+class C extends B {
+  f() {}
+}
+
+main() {}
+var x = new C().f();
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..7981f61
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+int i;
+String s;
+var x = i = s;
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46ffb37
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+String s;
+int i;
+main() {}
+var x = i = s;
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..38b2446
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var x = [null];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9294248
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var x = [null];
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..1954ad0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var x = {null: null};
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..412a917
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var x = {null: null};
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline.expect
new file mode 100644
index 0000000..b52257c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+abstract class I1 {
+  void f(int i);
+}
+
+abstract class I2 {
+  void f(Object o);
+}
+
+abstract class C implements I1, I2 {}
+
+class D extends C {
+  void f(Object o) {}
+}
+
+abstract class E implements I2, I1 {}
+
+class F extends E {
+  void f(Object o) {}
+}
+
+void g1(C c) {}
+void g2(E e) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fa895e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+library test;
+
+abstract class C implements I1, I2 {}
+
+abstract class E implements I2, I1 {}
+
+abstract class I1 {
+  void f(int i);
+}
+
+abstract class I2 {
+  void f(Object o);
+}
+
+class D extends C {
+  void f(Object o) {}
+}
+
+class F extends E {
+  void f(Object o) {}
+}
+
+main() {}
+void g1(C c) {}
+void g2(E e) {}
diff --git a/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline.expect
new file mode 100644
index 0000000..f19d7b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Class {
+  T method<T>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f19d7b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Class {
+  T method<T>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..530257a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+  C operator +(int value) => null;
+  C operator *(D value) => null;
+}
+
+class B {
+  E operator +(int value) => null;
+  E operator *(F value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+  A get target => null;
+  void set target(B value) {}
+}
+
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fdf8b09
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+  C operator *(D value) => null;
+  C operator +(int value) => null;
+}
+
+class B {
+  E operator *(F value) => null;
+  E operator +(int value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+  A get target => null;
+  void set target(B value) {}
+}
+
+main() {}
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..efab0ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class C {
+  int field = 0;
+  int get getter => 0;
+  int function() => 0;
+}
+
+C c = new C();
+var field_ref = c.field;
+var getter_ref = c.getter;
+var function_ref = c.function;
+var field_ref_list = [c.field];
+var getter_ref_list = [c.getter];
+var function_ref_list = [c.function];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e1e6c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+C c = new C();
+
+class C {
+  int field = 0;
+  int function() => 0;
+  int get getter => 0;
+}
+
+main() {}
+var field_ref = c.field;
+var field_ref_list = [c.field];
+var function_ref = c.function;
+var function_ref_list = [c.function];
+var getter_ref = c.getter;
+var getter_ref_list = [c.getter];
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..f23864b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+  C operator +(int value) => null;
+  C operator *(D value) => null;
+}
+
+class B {
+  E operator +(int value) => null;
+  E operator *(F value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+A get target => null;
+void set target(B value) {}
+void test1() {}
+void test2() {}
+void test3() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1fbf16f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+library test;
+
+A get target => null;
+T f<T>() => null;
+
+class A {
+  C operator *(D value) => null;
+  C operator +(int value) => null;
+}
+
+class B {
+  E operator *(F value) => null;
+  E operator +(int value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+main() {}
+void set target(B value) {}
+void test1() {}
+void test2() {}
+void test3() {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
index d5891bf..276a1c2 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
@@ -10,7 +10,7 @@
 import self as self;
 import "dart:core" as core;
 
-static field invalid-type x = (() → () →* invalid-type => self::f() ?{() →* invalid-type} self::y : self::z) as{TypeError} invalid-type;
+static field invalid-type x = () → () →* invalid-type => self::f() ?{() →* invalid-type} self::y : self::z;
 static field () →* invalid-type y = () → invalid-type => self::x;
 static field () →* invalid-type z = () → invalid-type => self::x;
 static method f() → core::bool*
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
index d5891bf..276a1c2 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
@@ -10,7 +10,7 @@
 import self as self;
 import "dart:core" as core;
 
-static field invalid-type x = (() → () →* invalid-type => self::f() ?{() →* invalid-type} self::y : self::z) as{TypeError} invalid-type;
+static field invalid-type x = () → () →* invalid-type => self::f() ?{() →* invalid-type} self::y : self::z;
 static field () →* invalid-type y = () → invalid-type => self::x;
 static field () →* invalid-type z = () → invalid-type => self::x;
 static method f() → core::bool*
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline.expect
new file mode 100644
index 0000000..d4c04a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool f() => null;
+var x = () => f() ? y : z;
+var y = () => x;
+var z = () => x;
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..667ba69
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool f() => null;
+main() {}
+var x = () => f() ? y : z;
+var y = () => x;
+var z = () => x;
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline.expect
new file mode 100644
index 0000000..17a5a7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+  num operator [](int x) => null;
+}
+
+class C extends B {
+  int operator [](Object x) => null;
+  void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17a5a7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+  num operator [](int x) => null;
+}
+
+class C extends B {
+  int operator [](Object x) => null;
+  void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..9fe3d8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+  D<T> operator [](E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> operator [](Object x) => null;
+  void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7d40b7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+  D<T> operator [](E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+  E<Future<U>> operator [](Object x) => null;
+  void h() {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline.expect
new file mode 100644
index 0000000..05de058
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C<T> {
+  const C();
+}
+
+void test(C<int> x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9107352
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C<T> {
+  const C();
+}
+
+main() {}
+void test(C<int> x) {}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline.expect
new file mode 100644
index 0000000..7486465
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+library test;
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+abstract class D {
+  A foo();
+}
+
+abstract class E {
+  B foo();
+}
+
+abstract class F {
+  Object foo();
+}
+
+abstract class G extends Object implements D, E, F {}
+
+class H extends G {
+  C foo() => new C();
+}
+
+G bar() => new H();
+var x = bar().foo();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16dd2e3e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline_modelled.expect
@@ -0,0 +1,30 @@
+library test;
+
+G bar() => new H();
+
+abstract class D {
+  A foo();
+}
+
+abstract class E {
+  B foo();
+}
+
+abstract class F {
+  Object foo();
+}
+
+abstract class G extends Object implements D, E, F {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class H extends G {
+  C foo() => new C();
+}
+
+main() {}
+var x = bar().foo();
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..7e89a23
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4b01cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..7e89a23
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)(() {
+  return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4b01cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)(() {
+  return 1;
+});
diff --git a/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..2536526
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+void printRunning() {}
+var y = run(printRunning);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e8174f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+main() {}
+var y = run(printRunning);
+void printRunning() {}
diff --git a/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..cdb201d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline.expect
new file mode 100644
index 0000000..a476c9a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>, Z extends X Function(Y),
+    W extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a476c9a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>, Z extends X Function(Y),
+    W extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..1f89431
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'dart:collection';
+
+class A {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1f89431
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'dart:collection';
+
+class A {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..276f316
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<U> {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..276f316
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<U> {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..ed3c7fe
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:collection';
+
+class A<T> {}
+
+class C {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed3c7fe
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'dart:collection';
+
+class A<T> {}
+
+class C {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..2b6461d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T extends A<T>> {}
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b6461d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T extends A<T>> {}
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..bc2eead
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T extends num>(T p);
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..30c7151
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class B {
+  foo() {}
+}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..edfd3bd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T>(T p);
+
+class B<U> {
+  fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c142ab4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class B<U> {
+  fun() {}
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..bc2eead
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T extends num>(T p);
+
+class B {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..30c7151
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class B {
+  foo() {}
+}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..a5935b8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T>(T p);
+
+class C {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9881ae4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  foo() {}
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..0fdd67a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T>(T p);
+typedef B<U extends A<U>>(U p);
+
+class C {
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e05e4bd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+  foo() {}
+}
+
+main() {}
+typedef A<T>(T p);
+typedef B<U extends A<U>>(U p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..fcc1eeb
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C<X extends num, Y extends void Function(X)> {}
+
+C c;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e511f6a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+C c;
+
+class C<X extends num, Y extends void Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..e4cafc7
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C<X extends num, Y extends void Function(X)> {}
+
+var lc = <C>[];
+var mc = <C, C>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1572ad5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class C<X extends num, Y extends void Function(X)> {}
+
+main() {}
+var lc = <C>[];
+var mc = <C, C>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..4365e51
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+D d;
+
+class E<X extends void Function(X)> {}
+
+E e;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..18b63b4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+D d;
+E e;
+
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+class E<X extends void Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..0e699bf
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+
+class E<X extends void Function(X)> {}
+
+var le = <E>[];
+var me = <E, E>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c05a14c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+class E<X extends void Function(X)> {}
+
+main() {}
+var ld = <D>[];
+var le = <E>[];
+var md = <D, D>{};
+var me = <E, E>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..4144570
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+C c;
+
+class D<X extends num, Y extends A<X>> {}
+
+D d;
+
+class E<X, Y extends X Function()> {}
+
+E e;
+
+class F<X extends num, Y extends X Function()> {}
+
+F f;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6df593
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+C c;
+D d;
+E e;
+F f;
+
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+class D<X extends num, Y extends A<X>> {}
+
+class E<X, Y extends X Function()> {}
+
+class F<X extends num, Y extends X Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..498ba79
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+var lc = <C>[];
+var mc = <C, C>{};
+
+class D<X extends num, Y extends A<X>> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+
+class E<X, Y extends X Function()> {}
+
+var le = <E>[];
+var me = <E, E>{};
+
+class F<X extends num, Y extends X Function()> {}
+
+var lf = <F>[];
+var mf = <F, F>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ae4099
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+class D<X extends num, Y extends A<X>> {}
+
+class E<X, Y extends X Function()> {}
+
+class F<X extends num, Y extends X Function()> {}
+
+main() {}
+var lc = <C>[];
+var ld = <D>[];
+var le = <E>[];
+var lf = <F>[];
+var mc = <C, C>{};
+var md = <D, D>{};
+var me = <E, E>{};
+var mf = <F, F>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..03f7e21
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+D d;
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+E e;
+
+class F<X extends X Function()> {}
+
+F f;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c2e53b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+D d;
+E e;
+F f;
+
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+class F<X extends X Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..bd6e734
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+var le = <E>[];
+var me = <E, E>{};
+
+class F<X extends X Function()> {}
+
+var lf = <F>[];
+var mf = <F, F>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb9c16e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+class F<X extends X Function()> {}
+
+main() {}
+var ld = <D>[];
+var le = <E>[];
+var lf = <F>[];
+var md = <D, D>{};
+var me = <E, E>{};
+var mf = <F, F>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..6d25aa6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+C c;
+
+class D<X extends num, Y extends X Function(X)> {}
+
+D d;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..90db448
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+C c;
+D d;
+
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+class D<X extends num, Y extends X Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..fc6b50f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+var lc = <C>[];
+var mc = <C, C>{};
+
+class D<X extends num, Y extends X Function(X)> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd05869
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+class D<X extends num, Y extends X Function(X)> {}
+
+main() {}
+var lc = <C>[];
+var ld = <D>[];
+var mc = <C, C>{};
+var md = <D, D>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..f49c29b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:collection';
+
+LinkedListEntry y;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f49c29b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:collection';
+
+LinkedListEntry y;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline.expect
new file mode 100644
index 0000000..d7289c3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<T extends num, S extends List<T>> extends A<T> {
+  B([T x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7289c3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<T extends num, S extends List<T>> extends A<T> {
+  B([T x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline.expect
new file mode 100644
index 0000000..d9993ef
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class B<T extends Comparable<T>> {}
+
+var y = new B();
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..58bc104
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class B<T extends Comparable<T>> {}
+
+main() {}
+var y = new B();
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline.expect
new file mode 100644
index 0000000..e4c532d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<T extends num> {}
+
+class B {
+  foo(A a) => null;
+  A bar() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e5c7b8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<T extends num> {}
+
+class B {
+  A bar() => null;
+  foo(A a) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..2e3bf3c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+var a = <A>[];
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b30539
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+main() {}
+var a = <A>[];
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..fcb0347
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+class B<S> {
+  final List<A<S>> foo = <A<S>>[];
+  final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fcb0347
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+class B<S> {
+  final List<A<S>> foo = <A<S>>[];
+  final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..3f4f92e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+var a = <A, A>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4ec5d2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+main() {}
+var a = <A, A>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline.expect
new file mode 100644
index 0000000..d99aa50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline.expect
@@ -0,0 +1,47 @@
+class A<X> {}
+
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends A<X>, Y extends A<Y>> {}
+
+D d;
+
+class E<W extends B<W, X>, X extends C<W, X>, Y extends B<Y, Z>,
+    Z extends C<Y, Z>> {}
+
+E e;
+
+class F<V extends num, W extends B<W, X>, X extends C<W, X>, Y extends B<W, X>,
+    Z extends C<Y, Z>> {}
+
+F f;
+
+class G<V extends num, W extends B<V, X>, X extends C<W, V>, Y extends B<W, X>,
+    Z extends C<Y, Z>> {}
+
+G g;
+
+class H<S extends A<S>, T extends B<T, U>, U extends C<T, U>, V extends A<V>,
+    W extends S, X extends T, Y extends U, Z extends V> {}
+
+H h;
+
+class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+    X extends Function(V), Y extends Z, Z extends T> {}
+
+I i;
+
+class J<
+    S extends T Function(U),
+    T extends U Function(S),
+    U extends S Function(T),
+    V extends W,
+    W extends X,
+    X extends Y Function(V),
+    Y extends Z,
+    Z extends X> {}
+
+J j;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ecd3e9f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline_modelled.expect
@@ -0,0 +1,42 @@
+D d;
+E e;
+F f;
+G g;
+H h;
+I i;
+J j;
+
+class A<X> {}
+
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends A<X>, Y extends A<Y>> {}
+
+class E<W extends B<W, X>, X extends C<W, X>, Y extends B<Y, Z>,
+    Z extends C<Y, Z>> {}
+
+class F<V extends num, W extends B<W, X>, X extends C<W, X>, Y extends B<W, X>,
+    Z extends C<Y, Z>> {}
+
+class G<V extends num, W extends B<V, X>, X extends C<W, V>, Y extends B<W, X>,
+    Z extends C<Y, Z>> {}
+
+class H<S extends A<S>, T extends B<T, U>, U extends C<T, U>, V extends A<V>,
+    W extends S, X extends T, Y extends U, Z extends V> {}
+
+class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+    X extends Function(V), Y extends Z, Z extends T> {}
+
+class J<
+    S extends T Function(U),
+    T extends U Function(S),
+    U extends S Function(T),
+    V extends W,
+    W extends X,
+    X extends Y Function(V),
+    Y extends Z,
+    Z extends X> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..78b4c2d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline.expect
@@ -0,0 +1,38 @@
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+C1 c1;
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+C2 c2;
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+C3 c3;
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+C4 c4;
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+D1 d1;
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+D2 d2;
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+D3 d3;
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+D4 d4;
+
+class E<X extends X Function(X)> {}
+
+E e;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e9b691b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+C1 c1;
+C2 c2;
+C3 c3;
+C4 c4;
+D1 d1;
+D2 d2;
+D3 d3;
+D4 d4;
+E e;
+
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+class E<X extends X Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..4c6bc43
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,47 @@
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+var lc1 = <C1>[];
+var mc1 = <C1, C1>{};
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+var lc2 = <C2>[];
+var mc2 = <C2, C2>{};
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+var lc3 = <C3>[];
+var mc3 = <C3, C3>{};
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+var lc4 = <C4>[];
+var mc4 = <C4, C4>{};
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+var ld1 = <D1>[];
+var md1 = <D1, D1>{};
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+var ld2 = <D2>[];
+var md2 = <D2, D2>{};
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+var ld3 = <D3>[];
+var md3 = <D3, D3>{};
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+var ld4 = <D4>[];
+var md4 = <D4, D4>{};
+
+class E<X extends X Function(X)> {}
+
+var le = <E>[];
+var me = <E, E>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df9101b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,39 @@
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+class E<X extends X Function(X)> {}
+
+main() {}
+var lc1 = <C1>[];
+var lc2 = <C2>[];
+var lc3 = <C3>[];
+var lc4 = <C4>[];
+var ld1 = <D1>[];
+var ld2 = <D2>[];
+var ld3 = <D3>[];
+var ld4 = <D4>[];
+var le = <E>[];
+var mc1 = <C1, C1>{};
+var mc2 = <C2, C2>{};
+var mc3 = <C3, C3>{};
+var mc4 = <C4, C4>{};
+var md1 = <D1, D1>{};
+var md2 = <D2, D2>{};
+var md3 = <D3, D3>{};
+var md4 = <D4, D4>{};
+var me = <E, E>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline.expect
new file mode 100644
index 0000000..4c7df9e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+class C<TypeV extends B> {}
+
+C c;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fabfa1a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+C c;
+
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+class C<TypeV extends B> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..4b40c441
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+B b;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1d7b57f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+B b;
+
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..e977e49
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+typedef Fisk = void Function<TypeY extends Hest>();
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7213ffd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+main() {}
+typedef Fisk = void Function<TypeY extends Hest>();
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..f524d0c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+typedef void Fisk<TypeY extends Hest>();
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b7b4f11
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+main() {}
+typedef void Fisk<TypeY extends Hest>();
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline.expect
new file mode 100644
index 0000000..bd9ba50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd9ba50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline.expect
new file mode 100644
index 0000000..ff0266b2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest, TypeY extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff0266b2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest, TypeY extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline.expect
new file mode 100644
index 0000000..c2a3766
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Map<Hest, Hest>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2a3766
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Map<Hest, Hest>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline.expect
new file mode 100644
index 0000000..d637216
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX> {}
+
+class Fisk<TypeY extends Hest<Hest<Object>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e5df9718
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Hest<Hest<Object>>> {}
+
+class Hest<TypeX> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline.expect
new file mode 100644
index 0000000..dec8c30
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8fe427
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline.expect
new file mode 100644
index 0000000..ae4efd5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:collection';
+
+class Hest<X extends LinkedListEntry> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae4efd5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:collection';
+
+class Hest<X extends LinkedListEntry> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline.expect
new file mode 100644
index 0000000..16b2fd1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d4c532a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline.expect
new file mode 100644
index 0000000..2138431
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Fisk<TypeY>> {}
+
+class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c60a816
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Fisk<TypeY extends Fisk<TypeY>> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..cd141ca
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import './non_simple_many_libs_same_name_cycle_lib.dart' as lib;
+
+class Hest<TypeX extends lib.Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd141ca
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import './non_simple_many_libs_same_name_cycle_lib.dart' as lib;
+
+class Hest<TypeX extends lib.Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline.expect
new file mode 100644
index 0000000..9d9cb28
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Map<Hest, Hest>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b11d407
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Map<Hest, Hest>> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline.expect
new file mode 100644
index 0000000..98cfbeb
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Hest> {}
+
+class Naebdyr<TypeZ extends Fisk> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..568af17
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Fisk<TypeY extends Hest> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Naebdyr<TypeZ extends Fisk> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline.expect
new file mode 100644
index 0000000..0755cda
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1177bb
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Hest> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..6360eb1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'dart:collection';
+
+class A<T> {}
+
+A a;
+DoubleLinkedQueue c;
+
+class C {
+  A foo() => null;
+  DoubleLinkedQueue baz() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d391e8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'dart:collection';
+
+A a;
+DoubleLinkedQueue c;
+
+class A<T> {}
+
+class C {
+  A foo() => null;
+  DoubleLinkedQueue baz() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..7391350
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<T extends num> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7391350
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<T extends num> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..f965240
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<X extends Comparable<X>> {}
+
+class B<Y extends A<dynamic>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f965240
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<X extends Comparable<X>> {}
+
+class B<Y extends A<dynamic>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..4293253
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<T extends A<T>> {}
+
+A a;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c99abd3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+A a;
+
+class A<T extends A<T>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..7ff14a2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'package:expect/expect.dart';
+
+class B {}
+
+class X<T extends B> {}
+
+class Y extends X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7ff14a2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'package:expect/expect.dart';
+
+class B {}
+
+class X<T extends B> {}
+
+class Y extends X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline.expect
new file mode 100644
index 0000000..9d30ea1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T extends num>(T p);
+
+class B {
+  foo(A a) => null;
+  A bar() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..652f3ca
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class B {
+  A bar() => null;
+  foo(A a) => null;
+}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..62a0a7e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef A<T extends num>(T p);
+var a = <A>[];
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f07241b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+typedef A<T extends num>(T p);
+var a = <A>[];
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..9b7bab7
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T>(T p);
+
+class B<S> {
+  final List<A<S>> foo = <A<S>>[];
+  final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..86ca2d6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class B<S> {
+  final List<A<S>> foo = <A<S>>[];
+  final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..8924ab9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef A<T extends num>(T p);
+var a = <A, A>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b88eb51
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+typedef A<T extends num>(T p);
+var a = <A, A>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..5eb24cf
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T>(T p);
+A a;
+
+class C {
+  A foo() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1af4af2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+A a;
+
+class C {
+  A foo() => null;
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..f90dddc
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef A<T extends num>(T p);
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fb74707
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class B<T extends A> {}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..4e39887
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef A<T>(T p);
+typedef B<S extends A<S>>(S p);
+B b;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..becf3c9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+B b;
+main() {}
+typedef A<T>(T p);
+typedef B<S extends A<S>>(S p);
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline.expect
new file mode 100644
index 0000000..69ffc5c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+error() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2780646
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+error() {}
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline.expect
new file mode 100644
index 0000000..1932ec0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  if (b) {
+    local2 = value;
+    local4 = 0;
+    local6 = 0;
+  }
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
+methodCompound() {}
+var fieldCompound = () {
+  late;
+  final int local4;
+  local4 = 0;
+  local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..be04eb0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+  late;
+  final int local4;
+  local4 = 0;
+  local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  if (b) {
+    local2 = value;
+    local4 = 0;
+    local6 = 0;
+  }
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
+var fieldDirect = <T>(T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline.expect
new file mode 100644
index 0000000..f27c6c0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  if (b) {
+    local1 = value;
+    local2 = value;
+    local3 = 0;
+    local4 = 0;
+    local5 = 0;
+    local6 = 0;
+    local7;
+  }
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
+methodCompound() {}
+var fieldCompound = () {
+  int local3;
+  late int;
+  local4;
+  local3 += 0;
+  local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46a4371
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+  int local3;
+  late int;
+  local4;
+  local3 += 0;
+  local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  if (b) {
+    local1 = value;
+    local2 = value;
+    local3 = 0;
+    local4 = 0;
+    local5 = 0;
+    local6 = 0;
+    local7;
+  }
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
+var fieldDirect = <T>(T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/infer_late_field_type.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/infer_late_field_type.dart.textual_outline.expect
new file mode 100644
index 0000000..ec3d9da
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/infer_late_field_type.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  int? field;
+}
+class B implements A {
+  late ;
+  var field;
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect
index 3259378..38ca669 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect
@@ -21,7 +21,7 @@
     return let final core::int? #t1 = self::Class::_#nonNullableStaticField in #t1.==(null) ?{core::int} let final core::int #t2 = (let final core::int #t3 = self::Class::nonNullableStaticFieldReads in let final core::int #t4 = self::Class::nonNullableStaticFieldReads = #t3.{core::num::+}(1) in #t3).{core::num::==}(0) ?{core::int} self::Class::nonNullableStaticField.{core::num::+}(1) : 0 in self::Class::_#nonNullableStaticField.==(null) ?{core::int} self::Class::_#nonNullableStaticField = #t2 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableStaticField' has been assigned during initialization.") : #t1{core::int};
   static get nullableStaticField() → core::int? {
     if(!self::Class::_#nullableStaticField#isSet) {
-      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::num::hashCode} : 0;
+      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
       if(self::Class::_#nullableStaticField#isSet)
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
       self::Class::_#nullableStaticField#isSet = true;
@@ -33,7 +33,7 @@
     return let final core::int? #t8 = this.{self::Class::_#Class#nonNullableInstanceField} in #t8.==(null) ?{core::int} let final core::int #t9 = (let final core::int #t10 = this.{self::Class::nonNullableInstanceFieldReads} in let final core::int #t11 = this.{self::Class::nonNullableInstanceFieldReads} = #t10.{core::num::+}(1) in #t10).{core::num::==}(0) ?{core::int} this.{self::Class::nonNullableInstanceField}.{core::num::+}(1) : 0 in this.{self::Class::_#Class#nonNullableInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#nonNullableInstanceField} = #t9 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableInstanceField' has been assigned during initialization.") : #t8{core::int};
   get nullableInstanceField() → core::int? {
     if(!this.{self::Class::_#Class#nullableInstanceField#isSet}) {
-      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::num::hashCode} : 0;
+      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
       if(this.{self::Class::_#Class#nullableInstanceField#isSet})
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
       this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
@@ -51,7 +51,7 @@
   return let final core::int? #t15 = self::_#nonNullableTopLevelField in #t15.==(null) ?{core::int} let final core::int #t16 = (let final core::int #t17 = self::nonNullableTopLevelFieldReads in let final core::int #t18 = self::nonNullableTopLevelFieldReads = #t17.{core::num::+}(1) in #t17).{core::num::==}(0) ?{core::int} self::nonNullableTopLevelField.{core::num::+}(1) : 0 in self::_#nonNullableTopLevelField.==(null) ?{core::int} self::_#nonNullableTopLevelField = #t16 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableTopLevelField' has been assigned during initialization.") : #t15{core::int};
 static get nullableTopLevelField() → core::int? {
   if(!self::_#nullableTopLevelField#isSet) {
-    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::num::hashCode} : 0;
+    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::Object::hashCode} : 0;
     if(self::_#nullableTopLevelField#isSet)
       throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
     self::_#nullableTopLevelField#isSet = true;
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect
index 3259378..38ca669 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
     return let final core::int? #t1 = self::Class::_#nonNullableStaticField in #t1.==(null) ?{core::int} let final core::int #t2 = (let final core::int #t3 = self::Class::nonNullableStaticFieldReads in let final core::int #t4 = self::Class::nonNullableStaticFieldReads = #t3.{core::num::+}(1) in #t3).{core::num::==}(0) ?{core::int} self::Class::nonNullableStaticField.{core::num::+}(1) : 0 in self::Class::_#nonNullableStaticField.==(null) ?{core::int} self::Class::_#nonNullableStaticField = #t2 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableStaticField' has been assigned during initialization.") : #t1{core::int};
   static get nullableStaticField() → core::int? {
     if(!self::Class::_#nullableStaticField#isSet) {
-      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::num::hashCode} : 0;
+      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
       if(self::Class::_#nullableStaticField#isSet)
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
       self::Class::_#nullableStaticField#isSet = true;
@@ -33,7 +33,7 @@
     return let final core::int? #t8 = this.{self::Class::_#Class#nonNullableInstanceField} in #t8.==(null) ?{core::int} let final core::int #t9 = (let final core::int #t10 = this.{self::Class::nonNullableInstanceFieldReads} in let final core::int #t11 = this.{self::Class::nonNullableInstanceFieldReads} = #t10.{core::num::+}(1) in #t10).{core::num::==}(0) ?{core::int} this.{self::Class::nonNullableInstanceField}.{core::num::+}(1) : 0 in this.{self::Class::_#Class#nonNullableInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#nonNullableInstanceField} = #t9 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableInstanceField' has been assigned during initialization.") : #t8{core::int};
   get nullableInstanceField() → core::int? {
     if(!this.{self::Class::_#Class#nullableInstanceField#isSet}) {
-      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::num::hashCode} : 0;
+      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
       if(this.{self::Class::_#Class#nullableInstanceField#isSet})
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
       this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
@@ -51,7 +51,7 @@
   return let final core::int? #t15 = self::_#nonNullableTopLevelField in #t15.==(null) ?{core::int} let final core::int #t16 = (let final core::int #t17 = self::nonNullableTopLevelFieldReads in let final core::int #t18 = self::nonNullableTopLevelFieldReads = #t17.{core::num::+}(1) in #t17).{core::num::==}(0) ?{core::int} self::nonNullableTopLevelField.{core::num::+}(1) : 0 in self::_#nonNullableTopLevelField.==(null) ?{core::int} self::_#nonNullableTopLevelField = #t16 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableTopLevelField' has been assigned during initialization.") : #t15{core::int};
 static get nullableTopLevelField() → core::int? {
   if(!self::_#nullableTopLevelField#isSet) {
-    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::num::hashCode} : 0;
+    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::Object::hashCode} : 0;
     if(self::_#nullableTopLevelField#isSet)
       throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
     self::_#nullableTopLevelField#isSet = true;
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.textual_outline.expect
new file mode 100644
index 0000000..aea51f7
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+int nonNullableTopLevelFieldReads = 0;
+late ;
+final int nonNullableTopLevelField = nonNullableTopLevelFieldReads++ == 0 ? nonNullableTopLevelField + 1 : 0;
+int nullableTopLevelFieldReads = 0;
+late ;
+final int? nullableTopLevelField = nullableTopLevelFieldReads++ == 0 ? nullableTopLevelField.hashCode : 0;
+class Class {
+  static int nonNullableStaticFieldReads = 0;
+  static late ;
+  final int nonNullableStaticField = nonNullableStaticFieldReads++ == 0 ? nonNullableStaticField + 1 : 0;
+  static int nullableStaticFieldReads = 0;
+  static late ;
+  final int? nullableStaticField = nullableStaticFieldReads++ == 0 ? nullableStaticField.hashCode : 0;
+  int nonNullableInstanceFieldReads = 0;
+  late ;
+  final int nonNullableInstanceField = nonNullableInstanceFieldReads++ == 0 ? nonNullableInstanceField + 1 : 0;
+  int nullableInstanceFieldReads = 0;
+  late ;
+  final int? nullableInstanceField = nullableInstanceFieldReads++ == 0 ? nullableInstanceField.hashCode : 0;
+}
+void main() { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect
index 3259378..38ca669 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect
@@ -21,7 +21,7 @@
     return let final core::int? #t1 = self::Class::_#nonNullableStaticField in #t1.==(null) ?{core::int} let final core::int #t2 = (let final core::int #t3 = self::Class::nonNullableStaticFieldReads in let final core::int #t4 = self::Class::nonNullableStaticFieldReads = #t3.{core::num::+}(1) in #t3).{core::num::==}(0) ?{core::int} self::Class::nonNullableStaticField.{core::num::+}(1) : 0 in self::Class::_#nonNullableStaticField.==(null) ?{core::int} self::Class::_#nonNullableStaticField = #t2 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableStaticField' has been assigned during initialization.") : #t1{core::int};
   static get nullableStaticField() → core::int? {
     if(!self::Class::_#nullableStaticField#isSet) {
-      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::num::hashCode} : 0;
+      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
       if(self::Class::_#nullableStaticField#isSet)
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
       self::Class::_#nullableStaticField#isSet = true;
@@ -33,7 +33,7 @@
     return let final core::int? #t8 = this.{self::Class::_#Class#nonNullableInstanceField} in #t8.==(null) ?{core::int} let final core::int #t9 = (let final core::int #t10 = this.{self::Class::nonNullableInstanceFieldReads} in let final core::int #t11 = this.{self::Class::nonNullableInstanceFieldReads} = #t10.{core::num::+}(1) in #t10).{core::num::==}(0) ?{core::int} this.{self::Class::nonNullableInstanceField}.{core::num::+}(1) : 0 in this.{self::Class::_#Class#nonNullableInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#nonNullableInstanceField} = #t9 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableInstanceField' has been assigned during initialization.") : #t8{core::int};
   get nullableInstanceField() → core::int? {
     if(!this.{self::Class::_#Class#nullableInstanceField#isSet}) {
-      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::num::hashCode} : 0;
+      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
       if(this.{self::Class::_#Class#nullableInstanceField#isSet})
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
       this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
@@ -51,7 +51,7 @@
   return let final core::int? #t15 = self::_#nonNullableTopLevelField in #t15.==(null) ?{core::int} let final core::int #t16 = (let final core::int #t17 = self::nonNullableTopLevelFieldReads in let final core::int #t18 = self::nonNullableTopLevelFieldReads = #t17.{core::num::+}(1) in #t17).{core::num::==}(0) ?{core::int} self::nonNullableTopLevelField.{core::num::+}(1) : 0 in self::_#nonNullableTopLevelField.==(null) ?{core::int} self::_#nonNullableTopLevelField = #t16 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableTopLevelField' has been assigned during initialization.") : #t15{core::int};
 static get nullableTopLevelField() → core::int? {
   if(!self::_#nullableTopLevelField#isSet) {
-    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::num::hashCode} : 0;
+    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::Object::hashCode} : 0;
     if(self::_#nullableTopLevelField#isSet)
       throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
     self::_#nullableTopLevelField#isSet = true;
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect
index 3259378..38ca669 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
     return let final core::int? #t1 = self::Class::_#nonNullableStaticField in #t1.==(null) ?{core::int} let final core::int #t2 = (let final core::int #t3 = self::Class::nonNullableStaticFieldReads in let final core::int #t4 = self::Class::nonNullableStaticFieldReads = #t3.{core::num::+}(1) in #t3).{core::num::==}(0) ?{core::int} self::Class::nonNullableStaticField.{core::num::+}(1) : 0 in self::Class::_#nonNullableStaticField.==(null) ?{core::int} self::Class::_#nonNullableStaticField = #t2 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableStaticField' has been assigned during initialization.") : #t1{core::int};
   static get nullableStaticField() → core::int? {
     if(!self::Class::_#nullableStaticField#isSet) {
-      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::num::hashCode} : 0;
+      final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int*} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
       if(self::Class::_#nullableStaticField#isSet)
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
       self::Class::_#nullableStaticField#isSet = true;
@@ -33,7 +33,7 @@
     return let final core::int? #t8 = this.{self::Class::_#Class#nonNullableInstanceField} in #t8.==(null) ?{core::int} let final core::int #t9 = (let final core::int #t10 = this.{self::Class::nonNullableInstanceFieldReads} in let final core::int #t11 = this.{self::Class::nonNullableInstanceFieldReads} = #t10.{core::num::+}(1) in #t10).{core::num::==}(0) ?{core::int} this.{self::Class::nonNullableInstanceField}.{core::num::+}(1) : 0 in this.{self::Class::_#Class#nonNullableInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#nonNullableInstanceField} = #t9 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableInstanceField' has been assigned during initialization.") : #t8{core::int};
   get nullableInstanceField() → core::int? {
     if(!this.{self::Class::_#Class#nullableInstanceField#isSet}) {
-      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::num::hashCode} : 0;
+      final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int*} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
       if(this.{self::Class::_#Class#nullableInstanceField#isSet})
         throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
       this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
@@ -51,7 +51,7 @@
   return let final core::int? #t15 = self::_#nonNullableTopLevelField in #t15.==(null) ?{core::int} let final core::int #t16 = (let final core::int #t17 = self::nonNullableTopLevelFieldReads in let final core::int #t18 = self::nonNullableTopLevelFieldReads = #t17.{core::num::+}(1) in #t17).{core::num::==}(0) ?{core::int} self::nonNullableTopLevelField.{core::num::+}(1) : 0 in self::_#nonNullableTopLevelField.==(null) ?{core::int} self::_#nonNullableTopLevelField = #t16 : throw new _in::LateInitializationErrorImpl::•("Field 'nonNullableTopLevelField' has been assigned during initialization.") : #t15{core::int};
 static get nullableTopLevelField() → core::int? {
   if(!self::_#nullableTopLevelField#isSet) {
-    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::num::hashCode} : 0;
+    final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int*} self::nullableTopLevelField.{core::Object::hashCode} : 0;
     if(self::_#nullableTopLevelField#isSet)
       throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
     self::_#nullableTopLevelField#isSet = true;
diff --git a/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..25677b9
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class {
+  late int ;
+  field = 10;
+  Class.constructor1();
+  Class.constructor2(this.field);
+  Class.constructor3(int value) : this.field = value + 1;
+  Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+  Subclass.constructor1() : super.constructor1();
+  Subclass.constructor2(int value) : super.constructor2(value);
+  Subclass.constructor3(int value) : super.constructor3(value);
+  Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..21809ff
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Class {
+  late int ;
+  field;
+  Class.constructor1();
+  Class.constructor2(this.field);
+  Class.constructor3(int value) : this.field = value + 1;
+  Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+  Subclass.constructor1() : super.constructor1();
+  Subclass.constructor2(int value) : super.constructor2(value);
+  Subclass.constructor3(int value) : super.constructor3(value);
+  Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3a3d178
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Class {
+  late ;
+  final int field;
+  Class.constructor1();
+  Class.constructor2(this.field);
+  Class.constructor3(int value) : this.field = value + 1;
+  Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+  Subclass.constructor1() : super.constructor1();
+  Subclass.constructor2(int value) : super.constructor2(value);
+  Subclass.constructor3(int value) : super.constructor3(value);
+  Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3102d50
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+int? initField() => 10;
+class Class {
+  late int;
+  operator? ( ){ }
+  field = initField();
+  Class.constructor1();
+  Class.constructor2(this.field);
+  Class.constructor3(int value) : this.field = value + 1;
+  Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+  Subclass.constructor1() : super.constructor1();
+  Subclass.constructor2(int value) : super.constructor2(value);
+  Subclass.constructor3(int value) : super.constructor3(value);
+  Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..9196f4b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class Class {
+  late int;
+  operator? ( ){ }
+  field;
+  Class.constructor1();
+  Class.constructor2(this.field);
+  Class.constructor3(int value) : this.field = value + 1;
+  Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+  Subclass.constructor1() : super.constructor1();
+  Subclass.constructor2(int value) : super.constructor2(value);
+  Subclass.constructor3(int value) : super.constructor3(value);
+  Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..2d9596f
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Class {
+  late ;
+  final int? field;
+  Class.constructor1();
+  Class.constructor2(this.field);
+  Class.constructor3(int value) : this.field = value + 1;
+  Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+  Subclass.constructor1() : super.constructor1();
+  Subclass.constructor2(int value) : super.constructor2(value);
+  Subclass.constructor3(int value) : super.constructor3(value);
+  Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect
index 1f469d7..2787548 100644
--- a/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect
@@ -14,14 +14,13 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method error() → dynamic {
   for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print(i);
   }
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    core::Iterator<core::int*> :sync-for-iterator = <core::int>[].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int i = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect
index 1f469d7..2787548 100644
--- a/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect
@@ -14,14 +14,13 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method error() → dynamic {
   for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print(i);
   }
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    core::Iterator<core::int*> :sync-for-iterator = <core::int>[].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int i = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/late_lowering/issue40373.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40373.dart.textual_outline.expect
new file mode 100644
index 0000000..233c4a9
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40373.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class C {
+  num pi = 3.14;
+  late num ;
+  p1 = this.pi;
+  late ;
+  final p2 = this.pi;
+}
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue40373b.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40373b.dart.textual_outline.expect
new file mode 100644
index 0000000..e89731e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40373b.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+late ;
+final g;
+class C {
+  static late ;
+  final s;
+  late ;
+  final v;
+}
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+  T baz();
+  bar(T value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+  T baz();
+  bar(T value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40805.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40805.dart.textual_outline.expect
new file mode 100644
index 0000000..4c9d91e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40805.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+main() { }
+class C {
+  covariant late ;
+  final int x;
+}
+class D extends C {
+  set x(num value) { }
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart
new file mode 100644
index 0000000..5ec6fd4
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.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.
+
+import 'dart:test';
+
+main() {
+  A a;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.outline.expect
new file mode 100644
index 0000000..6c7f4d3
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.outline.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "dart:test";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x;
+  synthetic constructor •() → self2::A
+    ;
+  get x() → core::int;
+  set x(core::int #t1) → void;
+}
+class _B extends core::Object implements self2::A {
+  field core::int x;
+  synthetic constructor •() → self2::_B
+    ;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.strong.expect
new file mode 100644
index 0000000..139a488
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.strong.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::A a;
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{test::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{test::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements test::A {
+  field core::int x = 3;
+  synthetic constructor •() → test::_B
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.strong.transformed.expect
new file mode 100644
index 0000000..139a488
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::A a;
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{test::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{test::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements test::A {
+  field core::int x = 3;
+  synthetic constructor •() → test::_B
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.weak.expect
new file mode 100644
index 0000000..139a488
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::A a;
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{test::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{test::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements test::A {
+  field core::int x = 3;
+  synthetic constructor •() → test::_B
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.weak.transformed.expect
new file mode 100644
index 0000000..139a488
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::A a;
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{test::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{test::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements test::A {
+  field core::int x = 3;
+  synthetic constructor •() → test::_B
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/libraries.json b/pkg/front_end/testcases/late_lowering/issue41436/libraries.json
new file mode 100644
index 0000000..154c73c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/libraries.json
@@ -0,0 +1,12 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "patches": [
+          "patch_lib.dart"
+        ],
+        "uri": "origin_lib.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/origin_lib.dart b/pkg/front_end/testcases/late_lowering/issue41436/origin_lib.dart
new file mode 100644
index 0000000..f223fd12
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/origin_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {
+  late int x;
+}
+
+class _B implements A {
+  int x = 3;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/patch_lib.dart b/pkg/front_end/testcases/late_lowering/issue41436/patch_lib.dart
new file mode 100644
index 0000000..a08c72e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/patch_lib.dart
@@ -0,0 +1,3 @@
+// 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.
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart b/pkg/front_end/testcases/late_lowering/issue41436b.dart
new file mode 100644
index 0000000..2371d6c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {
+  late int x;
+}
+
+class _B implements A {
+  int x = 3;
+}
+
+main() {
+  A a;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.outline.expect
new file mode 100644
index 0000000..bdf7500
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x;
+  synthetic constructor •() → self::A
+    ;
+  get x() → core::int;
+  set x(core::int #t1) → void;
+}
+class _B extends core::Object implements self::A {
+  field core::int x;
+  synthetic constructor •() → self::_B
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.strong.expect
new file mode 100644
index 0000000..61c5d86
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.strong.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{self::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{self::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements self::A {
+  field core::int x = 3;
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A a;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.strong.transformed.expect
new file mode 100644
index 0000000..61c5d86
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{self::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{self::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements self::A {
+  field core::int x = 3;
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A a;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.textual_outline.expect
new file mode 100644
index 0000000..7b9adf1
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+abstract class A {
+  late int ;
+  x;
+}
+class _B implements A {
+  int x = 3;
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.weak.expect
new file mode 100644
index 0000000..61c5d86
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{self::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{self::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements self::A {
+  field core::int x = 3;
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A a;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.weak.transformed.expect
new file mode 100644
index 0000000..61c5d86
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{self::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{self::A::_#A#x} = #t2;
+}
+class _B extends core::Object implements self::A {
+  field core::int x = 3;
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A a;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart
new file mode 100644
index 0000000..ec85c08
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'issue41436c_lib.dart';
+
+class C extends B {}
+
+main() {
+  new C();
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline.expect
new file mode 100644
index 0000000..016393b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'issue41436c_lib.dart';
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..016393b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'issue41436c_lib.dart';
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart
new file mode 100644
index 0000000..d7adb14
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {
+  late int x;
+}
+
+class B implements A {
+  int x = 3;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.outline.expect
new file mode 100644
index 0000000..de879f1
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.outline.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41436c_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41436c_lib.dart";
+
+class C extends iss::B {
+  synthetic constructor •() → self::C
+    ;
+  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
+  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#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
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x;
+  synthetic constructor •() → iss::A
+    ;
+  get x() → core::int;
+  set x(core::int #t1) → void;
+}
+class B extends core::Object implements iss::A {
+  field core::int x;
+  synthetic constructor •() → iss::B
+    ;
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.strong.expect
new file mode 100644
index 0000000..05bf5e3
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.strong.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41436c_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41436c_lib.dart";
+
+class C extends iss::B {
+  synthetic constructor •() → self::C
+    : super iss::B::•()
+    ;
+  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
+  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+}
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → iss::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{iss::A::_#A#x} = #t2;
+}
+class B extends core::Object implements iss::A {
+  field core::int x = 3;
+  synthetic constructor •() → iss::B
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
+  #C2 = <core::Type*>[]
+  #C3 = <dynamic>[]
+  #C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
+  #C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.strong.transformed.expect
new file mode 100644
index 0000000..05bf5e3
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41436c_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41436c_lib.dart";
+
+class C extends iss::B {
+  synthetic constructor •() → self::C
+    : super iss::B::•()
+    ;
+  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
+  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+}
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → iss::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{iss::A::_#A#x} = #t2;
+}
+class B extends core::Object implements iss::A {
+  field core::int x = 3;
+  synthetic constructor •() → iss::B
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
+  #C2 = <core::Type*>[]
+  #C3 = <dynamic>[]
+  #C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
+  #C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.weak.expect
new file mode 100644
index 0000000..05bf5e3
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.weak.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41436c_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41436c_lib.dart";
+
+class C extends iss::B {
+  synthetic constructor •() → self::C
+    : super iss::B::•()
+    ;
+  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
+  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+}
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → iss::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{iss::A::_#A#x} = #t2;
+}
+class B extends core::Object implements iss::A {
+  field core::int x = 3;
+  synthetic constructor •() → iss::B
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
+  #C2 = <core::Type*>[]
+  #C3 = <dynamic>[]
+  #C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
+  #C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.weak.transformed.expect
new file mode 100644
index 0000000..05bf5e3
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c_lib.dart.weak.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41436c_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41436c_lib.dart";
+
+class C extends iss::B {
+  synthetic constructor •() → self::C
+    : super iss::B::•()
+    ;
+  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
+  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
+    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+}
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class A extends core::Object {
+  field core::int? _#A#x = null;
+  synthetic constructor •() → iss::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
+  set x(core::int #t2) → void
+    this.{iss::A::_#A#x} = #t2;
+}
+class B extends core::Object implements iss::A {
+  field core::int x = 3;
+  synthetic constructor •() → iss::B
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
+  #C2 = <core::Type*>[]
+  #C3 = <dynamic>[]
+  #C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
+  #C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/link.options b/pkg/front_end/testcases/late_lowering/issue41436c/link.options
new file mode 100644
index 0000000..8503704
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/link.options
@@ -0,0 +1 @@
+issue41436c_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..ec35e3c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+int? method() => null;
+late ;
+var nonNullableTopLevelField = 0;
+late ;
+var nullableTopLevelField = method();
+class A {
+  late ;
+  var nonNullableInstanceField = 0;
+  late ;
+  var nullableInstanceField = method();
+  static late ;
+  var nonNullableStaticField = 0;
+  static late ;
+  var nullableStaticField = method();
+}
+class B extends A {
+  get nonNullableInstanceField => 0;
+  set nonNullableInstanceField(value) { }
+  get nullableInstanceField => 0;
+  set nullableInstanceField(value) { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..659d61d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+late int ;
+lateTopLevelField1 = 123;
+class Class<T> {
+  static late int ;
+  lateStaticField1 = 87;
+  static late int ;
+  lateStaticField2 = 42;
+  static staticMethod() { }
+  late int ;
+  lateInstanceField = 16;
+  final T field;
+  late T ;
+  lateGenericField1 = field;
+  late T ;
+  lateGenericField2 = field;
+  Class(this.field);
+  instanceMethod(T value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3db9332
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+late int ;
+lateTopLevelField;
+class Class<T> {
+  static late int ;
+  lateStaticField1;
+  static late int ;
+  lateStaticField2;
+  static staticMethod() { }
+  late int ;
+  lateInstanceField;
+  late T ;
+  lateGenericInstanceField;
+  instanceMethod(T value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..8785f2d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+int? lateTopLevelField1Init;
+int initLateTopLevelField1(int value) { }
+late ;
+final int lateTopLevelField1 = initLateTopLevelField1(123);
+class Class<T> {
+  static int? lateStaticField1Init;
+  static int initLateStaticField1(int value) { }
+  static late ;
+  final int lateStaticField1 = initLateStaticField1(87);
+  static int? lateStaticField2Init;
+  static int initLateStaticField2(int value) { }
+  static late ;
+  final int lateStaticField2 = initLateStaticField2(42);
+  static staticMethod() { }
+  int? lateInstanceFieldInit;
+  int initLateInstanceField(int value) { }
+  late ;
+  final int lateInstanceField = initLateInstanceField(16);
+  T? lateGenericFieldInit;
+  T initLateGenericField(T value) { }
+  final T field;
+  late ;
+  final T lateGenericField = initLateGenericField(field);
+  Class(this.field);
+  instanceMethod() { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3f83924
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+late ;
+final int lateTopLevelField;
+class Class {
+  static late ;
+  final int lateStaticField1;
+  static late ;
+  final int lateStaticField2;
+  static staticMethod() { }
+  late ;
+  final int lateInstanceField;
+  instanceMethod() { }
+}
+extension Extension ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..456a9fa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8c8350
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..38ba267
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+int? lateTopLevelField1Init;
+int? initLateTopLevelField1(int value) { }
+late ;
+final int? lateTopLevelField1 = initLateTopLevelField1(123);
+class Class<T> {
+  static int? lateStaticField1Init;
+  static int? initLateStaticField1(int value) { }
+  static late ;
+  final int? lateStaticField1 = initLateStaticField1(87);
+  static int? lateStaticField2Init;
+  static int? initLateStaticField2(int value) { }
+  static late ;
+  final int? lateStaticField2 = initLateStaticField2(42);
+  static staticMethod() { }
+  int? lateInstanceFieldInit;
+  int? initLateInstanceField(int value) { }
+  late ;
+  final int? lateInstanceField = initLateInstanceField(16);
+  T? lateGenericInstanceFieldInit;
+  T? initLateGenericInstanceField(T? value) { }
+  final T? field;
+  late ;
+  final T? lateGenericInstanceField = initLateGenericInstanceField(field);
+  Class(this.field);
+  instanceMethod() { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..e23b4bf
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+late ;
+final int? lateTopLevelField;
+class Class<T> {
+  static late ;
+  final int? lateStaticField1;
+  static late ;
+  final int? lateStaticField2;
+  static staticMethod() { }
+  late ;
+  final int? lateInstanceField;
+  late ;
+  final T? lateGenericInstanceField;
+  instanceMethod(T value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..456a9fa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8c8350
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.textual_outline.expect
new file mode 100644
index 0000000..af64f8b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+import 'dart:async';
+FutureOr method1() => null;
+FutureOr? method2() => null;
+FutureOr<dynamic> method3() => null;
+FutureOr<int> method4() => 0;
+FutureOr<int?> method5() => null;
+FutureOr<int?>? method6() => null;
+late ;
+var field1 = method1();
+late ;
+var field2 = method2();
+late ;
+var field3 = method3();
+late ;
+var field4 = method4();
+late ;
+var field5 = method5();
+late ;
+var field6 = method6();
+class C<T> {
+  late FutureOr ;
+  field1;
+  late FutureOr;
+  operator? ( ){ }
+  field2;
+  late FutureOr<T> ( ){ }
+  field3;
+  late FutureOr<T?> ( ){ }
+  field4;
+  late FutureOr<T?>( ){ }
+  operator? ( ){ }
+  field5;
+  method() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..456a9fa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8c8350
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..d3feb52
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+int? lateTopLevelField1Init() => 123;
+late int;
+?
+lateTopLevelField1 = lateTopLevelField1Init();
+class Class<T> {
+  static int? lateStaticField1Init() => 87;
+  static late int;
+  operator? ( ){ }
+  lateStaticField1 = lateStaticField1Init();
+  static int? lateStaticField2Init() => 42;
+  static late int;
+  operator? ( ){ }
+  lateStaticField2 = lateStaticField2Init();
+  static staticMethod() { }
+  int? lateInstanceFieldInit() => 16;
+  late int;
+  operator? ( ){ }
+  lateInstanceField = lateInstanceFieldInit();
+  final T? field;
+  T? lateGenericInstanceFieldInit() => field;
+  late T;
+  operator? ( ){ }
+  lateGenericInstanceField = lateGenericInstanceFieldInit();
+  Class(this.field);
+  instanceMethod(T? value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..bbebbdb
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+late int;
+?
+lateTopLevelField;
+class Class<T> {
+  static late int;
+  operator? ( ){ }
+  lateStaticField1;
+  static late int;
+  operator? ( ){ }
+  lateStaticField2;
+  static staticMethod() { }
+  late int;
+  operator? ( ){ }
+  lateInstanceField;
+  late T;
+  operator? ( ){ }
+  lateGenericInstanceField;
+  instanceMethod(T? value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..b491e36
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+int? lateLocalInit() => 123;
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9af13bc
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+int? lateLocalInit() => 123;
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
index a0a1523..66413d4 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
@@ -122,7 +122,7 @@
     core::print("baz");
   }
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String>["baz"]).{core::Iterable::iterator};
+    core::Iterator<core::String*> :sync-for-iterator = <core::String>["baz"].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String s = :sync-for-iterator.{core::Iterator::current};
       {
@@ -140,8 +140,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -153,7 +153,7 @@
       #L1:
       {
         {
-          dynamic :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
+          asy::Stream<core::String*>* :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::String>? :for-iterator = new asy::_StreamIterator::•<core::String>(:stream);
           try
@@ -182,21 +182,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method fisk() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -223,8 +223,8 @@
             final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
             asy::FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
-            dynamic :async_op_then;
-            dynamic :async_op_error;
+            (dynamic) → dynamic :async_op_then;
+            (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
             dynamic :await_ctx_var;
             dynamic :saved_try_context_var0;
@@ -239,13 +239,13 @@
                 asy::_completeOnAsyncReturn(:async_completer, :return_value);
                 return;
               }
-              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
                 :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.start(:async_op);
+            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
             return :async_completer.{asy::Completer::future};
           } : #t15{core::Function};
         function #f#set(core::Function #t17) → dynamic
@@ -254,13 +254,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/later.dart.textual_outline.expect
new file mode 100644
index 0000000..cb89651
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/later.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+// @dart = 2.9999
+class A {
+  int a = 42;
+  late int ;
+  b = (this.a * 2) >> 1;
+  foo(late int x) { }
+}
+bar(late int x) { }
+baz() { }
+hest() async { }
+fisk() async { }
+class B {
+  late ;
+  final int x = 42;
+  const B();
+}
+class C {
+  late ;
+  final int x;
+  initVars() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
index a0a1523..66413d4 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
@@ -122,7 +122,7 @@
     core::print("baz");
   }
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String>["baz"]).{core::Iterable::iterator};
+    core::Iterator<core::String*> :sync-for-iterator = <core::String>["baz"].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String s = :sync-for-iterator.{core::Iterator::current};
       {
@@ -140,8 +140,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -153,7 +153,7 @@
       #L1:
       {
         {
-          dynamic :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
+          asy::Stream<core::String*>* :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::String>? :for-iterator = new asy::_StreamIterator::•<core::String>(:stream);
           try
@@ -182,21 +182,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method fisk() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -223,8 +223,8 @@
             final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
             asy::FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
-            dynamic :async_op_then;
-            dynamic :async_op_error;
+            (dynamic) → dynamic :async_op_then;
+            (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
             dynamic :await_ctx_var;
             dynamic :saved_try_context_var0;
@@ -239,13 +239,13 @@
                 asy::_completeOnAsyncReturn(:async_completer, :return_value);
                 return;
               }
-              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
                 :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.start(:async_op);
+            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
             return :async_completer.{asy::Completer::future};
           } : #t15{core::Function};
         function #f#set(core::Function #t17) → dynamic
@@ -254,13 +254,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/override.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/override.dart.textual_outline.expect
new file mode 100644
index 0000000..66a20aa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/override.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+class Class {
+  late int ;
+  field1;
+  late int ;
+  field2;
+  late ;
+  final int field3;
+  late ;
+  final int field4;
+}
+class SubClass extends Class {
+  late int ;
+  field1;
+  late int ;
+  field2 = 0;
+  late ;
+  final int field3;
+  late ;
+  final int field4 = 0;
+  int get directField1 => super.field1;
+  void set directField1(int value) { }
+  int get directField2 => super.field2;
+  void set directField2(int value) { }
+  int get directField3 => super.field3;
+  int get directField4 => super.field4;
+}
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..7bf8597
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class A {
+  late ;
+  final int x;
+  late ;
+  final int? y;
+}
+class B extends A {
+  int get x => 1;
+  int? get y => 1;
+}
+class C extends A {
+  late ;
+  final int x = 2;
+  late ;
+  final int? y = 2;
+}
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline.expect
new file mode 100644
index 0000000..3d93fd2
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+  final E field;
+  Class(this.field);
+  E returnTypeVariable() {}
+}
+
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1ef11f
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+  Class(this.field);
+  E returnTypeVariable() {}
+  final E field;
+}
+
+expect(expected, actual) {}
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/uninitialized_non_nullable_late_fields.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..86269fb
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  late int ;
+  x;
+  A.foo(this.x);
+  A.bar();
+}
+main() { }
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline.expect
new file mode 100644
index 0000000..e387ab9
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  final int x;
+  const A(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c15976
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+  const A(this.x);
+  final int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..57b1335
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<E> {
+  void method(E e) {}
+}
+
+T id<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f46f8a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+T id<T>(T t) => t;
+
+class Class<E> {
+  void method(E e) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline.expect
new file mode 100644
index 0000000..1197640
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline.expect
@@ -0,0 +1,49 @@
+class Tearoffable {
+  void call() {}
+}
+
+ok<
+        XnonNull extends Object,
+        YnonNull extends XnonNull,
+        XpotentiallyNull extends Object?,
+        YpotentiallyNull extends XpotentiallyNull>(
+    dynamic dynamicArg,
+    Object objectArg,
+    num numArg,
+    int intArg,
+    double doubleArg,
+    Function functionArg,
+    void Function() toVoidArg,
+    Tearoffable tearoffableArg,
+    XnonNull xNonNullArg,
+    XpotentiallyNull xPotentiallyNullArg,
+    YnonNull yNonNullArg,
+    YpotentiallyNull yPotentiallyNullArg) {}
+error<
+        XnonNull extends Object,
+        YnonNull extends XnonNull,
+        XpotentiallyNull extends Object?,
+        YpotentiallyNull extends XpotentiallyNull>(
+    Object objectArg,
+    Object? objectNullableArg,
+    num numArg,
+    num? numNullableArg,
+    int intArg,
+    int? intNullableArg,
+    double doubleArg,
+    double? doubleNullableArg,
+    Function functionArg,
+    Function? functionNullableArg,
+    void Function() toVoidArg,
+    void Function()? toVoidNullableArg,
+    Tearoffable tearoffableArg,
+    Tearoffable? tearoffableNullableArg,
+    XnonNull xNonNullArg,
+    XnonNull? xNonNullNullableArg,
+    XpotentiallyNull xPotentiallyNullArg,
+    XpotentiallyNull? xPotentiallyNullNullableArg,
+    YnonNull yNonNullArg,
+    YnonNull? yNonNullNullableArg,
+    YpotentiallyNull yPotentiallyNullArg,
+    YpotentiallyNull? yPotentiallyNullNullableArg) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..23eaee3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+class Tearoffable {
+  void call() {}
+}
+
+error<
+        XnonNull extends Object,
+        YnonNull extends XnonNull,
+        XpotentiallyNull extends Object?,
+        YpotentiallyNull extends XpotentiallyNull>(
+    Object objectArg,
+    Object? objectNullableArg,
+    num numArg,
+    num? numNullableArg,
+    int intArg,
+    int? intNullableArg,
+    double doubleArg,
+    double? doubleNullableArg,
+    Function functionArg,
+    Function? functionNullableArg,
+    void Function() toVoidArg,
+    void Function()? toVoidNullableArg,
+    Tearoffable tearoffableArg,
+    Tearoffable? tearoffableNullableArg,
+    XnonNull xNonNullArg,
+    XnonNull? xNonNullNullableArg,
+    XpotentiallyNull xPotentiallyNullArg,
+    XpotentiallyNull? xPotentiallyNullNullableArg,
+    YnonNull yNonNullArg,
+    YnonNull? yNonNullNullableArg,
+    YpotentiallyNull yPotentiallyNullArg,
+    YpotentiallyNull? yPotentiallyNullNullableArg) {}
+main() {}
+ok<
+        XnonNull extends Object,
+        YnonNull extends XnonNull,
+        XpotentiallyNull extends Object?,
+        YpotentiallyNull extends XpotentiallyNull>(
+    dynamic dynamicArg,
+    Object objectArg,
+    num numArg,
+    int intArg,
+    double doubleArg,
+    Function functionArg,
+    void Function() toVoidArg,
+    Tearoffable tearoffableArg,
+    XnonNull xNonNullArg,
+    XpotentiallyNull xPotentiallyNullArg,
+    YnonNull yNonNullArg,
+    YpotentiallyNull yPotentiallyNullArg) {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..8827b4d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A<X extends num> {}
+
+foo(A<num?> a) {}
+A<num?>? bar() {}
+baz<T extends A<num?>>() {}
+
+class B extends A<num?> {}
+
+class C<T extends A<num?>> {}
+
+void hest<T extends num>() {}
+
+class Hest {
+  void hest<T extends num>() {}
+}
+
+fisk(Hest h) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9c93979
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+A<num?>? bar() {}
+baz<T extends A<num?>>() {}
+
+class A<X extends num> {}
+
+class B extends A<num?> {}
+
+class C<T extends A<num?>> {}
+
+class Hest {
+  void hest<T extends num>() {}
+}
+
+fisk(Hest h) {}
+foo(A<num?> a) {}
+main() {}
+void hest<T extends num>() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart
new file mode 100644
index 0000000..54eb0eb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+import 'bounds_from_opt_in_lib.dart';
+
+class LegacyClass<T extends Null> extends Class<T> {
+  method<T extends Null>() {}
+}
+
+test() {
+  Class<Null> c = new Class<Null>();
+  c.method<Null>();
+  method<Null>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.outline.expect
new file mode 100644
index 0000000..695900a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "bounds_from_opt_in_lib.dart" as bou;
+
+import "org-dartlang-testcase:///bounds_from_opt_in_lib.dart";
+
+class LegacyClass<T extends core::Null? = core::Null?> extends bou::Class<self::LegacyClass::T*> {
+  synthetic constructor •() → self::LegacyClass<self::LegacyClass::T*>*
+    ;
+  method method<T extends core::Null? = core::Null?>() → dynamic
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as bou;
+import "dart:core" as core;
+
+class Class<T extends Never = Never> extends core::Object {
+  synthetic constructor •() → bou::Class<bou::Class::T>
+    ;
+  method method<T extends Never = Never>() → dynamic
+    ;
+}
+static method method<T extends Never = Never>() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.strong.expect
new file mode 100644
index 0000000..45d24f4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.strong.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "bounds_from_opt_in_lib.dart" as bou;
+
+import "org-dartlang-testcase:///bounds_from_opt_in_lib.dart";
+
+class LegacyClass<T extends core::Null? = core::Null?> extends bou::Class<self::LegacyClass::T*> {
+  synthetic constructor •() → self::LegacyClass<self::LegacyClass::T*>*
+    : super bou::Class::•()
+    ;
+  method method<T extends core::Null? = core::Null?>() → dynamic {}
+}
+static method test() → dynamic {
+  bou::Class<core::Null?>* c = new bou::Class::•<core::Null?>();
+  c.{bou::Class::method}<core::Null?>();
+  bou::method<core::Null?>();
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as bou;
+import "dart:core" as core;
+
+class Class<T extends Never = Never> extends core::Object {
+  synthetic constructor •() → bou::Class<bou::Class::T>
+    : super core::Object::•()
+    ;
+  method method<T extends Never = Never>() → dynamic {}
+}
+static method method<T extends Never = Never>() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.strong.transformed.expect
new file mode 100644
index 0000000..45d24f4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "bounds_from_opt_in_lib.dart" as bou;
+
+import "org-dartlang-testcase:///bounds_from_opt_in_lib.dart";
+
+class LegacyClass<T extends core::Null? = core::Null?> extends bou::Class<self::LegacyClass::T*> {
+  synthetic constructor •() → self::LegacyClass<self::LegacyClass::T*>*
+    : super bou::Class::•()
+    ;
+  method method<T extends core::Null? = core::Null?>() → dynamic {}
+}
+static method test() → dynamic {
+  bou::Class<core::Null?>* c = new bou::Class::•<core::Null?>();
+  c.{bou::Class::method}<core::Null?>();
+  bou::method<core::Null?>();
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as bou;
+import "dart:core" as core;
+
+class Class<T extends Never = Never> extends core::Object {
+  synthetic constructor •() → bou::Class<bou::Class::T>
+    : super core::Object::•()
+    ;
+  method method<T extends Never = Never>() → dynamic {}
+}
+static method method<T extends Never = Never>() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..fb1115b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import 'bounds_from_opt_in_lib.dart';
+
+class LegacyClass<T extends Null> extends Class<T> {
+  method<T extends Null>() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8221626
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import 'bounds_from_opt_in_lib.dart';
+
+class LegacyClass<T extends Null> extends Class<T> {
+  method<T extends Null>() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.weak.expect
new file mode 100644
index 0000000..45d24f4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.weak.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "bounds_from_opt_in_lib.dart" as bou;
+
+import "org-dartlang-testcase:///bounds_from_opt_in_lib.dart";
+
+class LegacyClass<T extends core::Null? = core::Null?> extends bou::Class<self::LegacyClass::T*> {
+  synthetic constructor •() → self::LegacyClass<self::LegacyClass::T*>*
+    : super bou::Class::•()
+    ;
+  method method<T extends core::Null? = core::Null?>() → dynamic {}
+}
+static method test() → dynamic {
+  bou::Class<core::Null?>* c = new bou::Class::•<core::Null?>();
+  c.{bou::Class::method}<core::Null?>();
+  bou::method<core::Null?>();
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as bou;
+import "dart:core" as core;
+
+class Class<T extends Never = Never> extends core::Object {
+  synthetic constructor •() → bou::Class<bou::Class::T>
+    : super core::Object::•()
+    ;
+  method method<T extends Never = Never>() → dynamic {}
+}
+static method method<T extends Never = Never>() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.weak.transformed.expect
new file mode 100644
index 0000000..45d24f4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "bounds_from_opt_in_lib.dart" as bou;
+
+import "org-dartlang-testcase:///bounds_from_opt_in_lib.dart";
+
+class LegacyClass<T extends core::Null? = core::Null?> extends bou::Class<self::LegacyClass::T*> {
+  synthetic constructor •() → self::LegacyClass<self::LegacyClass::T*>*
+    : super bou::Class::•()
+    ;
+  method method<T extends core::Null? = core::Null?>() → dynamic {}
+}
+static method test() → dynamic {
+  bou::Class<core::Null?>* c = new bou::Class::•<core::Null?>();
+  c.{bou::Class::method}<core::Null?>();
+  bou::method<core::Null?>();
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as bou;
+import "dart:core" as core;
+
+class Class<T extends Never = Never> extends core::Object {
+  synthetic constructor •() → bou::Class<bou::Class::T>
+    : super core::Object::•()
+    ;
+  method method<T extends Never = Never>() → dynamic {}
+}
+static method method<T extends Never = Never>() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in_lib.dart b/pkg/front_end/testcases/nnbd/bounds_from_opt_in_lib.dart
new file mode 100644
index 0000000..cddbf37
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class<T extends Never> {
+  method<T extends Never>() {}
+}
+
+method<T extends Never>() {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/call.dart.textual_outline.expect
new file mode 100644
index 0000000..d90b603
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+  void Function()? field;
+  void Function()? get getter => null;
+}
+
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d90b603
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Class {
+  void Function()? field;
+  void Function()? get getter => null;
+}
+
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart b/pkg/front_end/testcases/nnbd/constant_null_is.dart
new file mode 100644
index 0000000..fa999f7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart
@@ -0,0 +1,42 @@
+// 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 'constant_null_is_lib.dart';
+
+const c0 = null is int?;
+const c1 = null is int;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+
+main() {
+  expect(null is int?, c0, "null is int?");
+  expect(null is int, c1, "null is int");
+  expect(null is Null, c2, "null is Null");
+  expect(null is Never?, c3, "null is Never?");
+  expect(null is Never, c4, "null is Never");
+  expect(null is FutureOr<int?>, c5, "null is FutureOr<int?>");
+  expect(null is FutureOr<int>, c6, "null is FutureOr<int>");
+  expect(null is FutureOr<int>?, c7, "null is FutureOr<int>?");
+  expect(null is FutureOr<Null>, c8, "null is FutureOr<Null>");
+  expect(null is FutureOr<Null>?, c9, "null is FutureOr<Null>?");
+  expect(null is FutureOr<Never>, c10, "null is FutureOr<Never>");
+  expect(null is FutureOr<Never?>, c11, "null is FutureOr<Never?>");
+  expect(null is FutureOr<Never>?, c12, "null is FutureOr<Never>?");
+  test();
+}
+
+expect(expected, actual, String message) {
+  if (expected != actual)
+    throw 'Expected $expected, actual $actual for $message';
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.outline.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.outline.expect
new file mode 100644
index 0000000..9a984f8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.outline.expect
@@ -0,0 +1,37 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is_lib.dart";
+
+static const field core::bool c0 = null is{ForNonNullableByDefault} core::int?;
+static const field core::bool c1 = null is{ForNonNullableByDefault} core::int;
+static const field core::bool c2 = null is{ForNonNullableByDefault} core::Null?;
+static const field core::bool c3 = null is{ForNonNullableByDefault} Never?;
+static const field core::bool c4 = null is{ForNonNullableByDefault} Never;
+static const field core::bool c5 = null is{ForNonNullableByDefault} asy::FutureOr<core::int?>;
+static const field core::bool c6 = null is{ForNonNullableByDefault} asy::FutureOr<core::int>;
+static const field core::bool c7 = null is{ForNonNullableByDefault} asy::FutureOr<core::int>?;
+static const field core::bool c8 = null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>;
+static const field core::bool c9 = null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?;
+static const field core::bool c10 = null is{ForNonNullableByDefault} asy::FutureOr<Never>;
+static const field core::bool c11 = null is{ForNonNullableByDefault} asy::FutureOr<Never?>;
+static const field core::bool c12 = null is{ForNonNullableByDefault} asy::FutureOr<Never>?;
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic
+  ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is.dart";
+
+static const field core::bool* d0 = null is core::int*;
+static const field core::bool* d1 = null is core::Null?;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.expect
new file mode 100644
index 0000000..6490709
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "constant_null_is_lib.dart" as con;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is_lib.dart";
+
+static const field core::bool c0 = #C1;
+static const field core::bool c1 = #C2;
+static const field core::bool c2 = #C1;
+static const field core::bool c3 = #C1;
+static const field core::bool c4 = #C2;
+static const field core::bool c5 = #C1;
+static const field core::bool c6 = #C2;
+static const field core::bool c7 = #C1;
+static const field core::bool c8 = #C1;
+static const field core::bool c9 = #C1;
+static const field core::bool c10 = #C2;
+static const field core::bool c11 = #C1;
+static const field core::bool c12 = #C1;
+static method main() → dynamic {
+  self::expect(null is{ForNonNullableByDefault} core::int?, #C1, "null is int?");
+  self::expect(null is{ForNonNullableByDefault} core::int, #C2, "null is int");
+  self::expect(null is{ForNonNullableByDefault} core::Null?, #C1, "null is Null");
+  self::expect(null is{ForNonNullableByDefault} Never?, #C1, "null is Never?");
+  self::expect(null is{ForNonNullableByDefault} Never, #C2, "null is Never");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C1, "null is FutureOr<int?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C2, "null is FutureOr<int>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C1, "null is FutureOr<int>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C1, "null is FutureOr<Null>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C1, "null is FutureOr<Null>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C2, "null is FutureOr<Never>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C1, "null is FutureOr<Never?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C1, "null is FutureOr<Never>?");
+  con::test();
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+library;
+import self as con;
+import "constant_null_is.dart" as self;
+import "dart:core" as core;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is.dart";
+
+static const field core::bool* d0 = #C2;
+static const field core::bool* d1 = #C1;
+static method test() → dynamic {
+  self::expect(null is core::int*, #C2, "null is int (opt-out)");
+  self::expect(null is core::Null?, #C1, "null is Null");
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.transformed.expect
new file mode 100644
index 0000000..6490709
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "constant_null_is_lib.dart" as con;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is_lib.dart";
+
+static const field core::bool c0 = #C1;
+static const field core::bool c1 = #C2;
+static const field core::bool c2 = #C1;
+static const field core::bool c3 = #C1;
+static const field core::bool c4 = #C2;
+static const field core::bool c5 = #C1;
+static const field core::bool c6 = #C2;
+static const field core::bool c7 = #C1;
+static const field core::bool c8 = #C1;
+static const field core::bool c9 = #C1;
+static const field core::bool c10 = #C2;
+static const field core::bool c11 = #C1;
+static const field core::bool c12 = #C1;
+static method main() → dynamic {
+  self::expect(null is{ForNonNullableByDefault} core::int?, #C1, "null is int?");
+  self::expect(null is{ForNonNullableByDefault} core::int, #C2, "null is int");
+  self::expect(null is{ForNonNullableByDefault} core::Null?, #C1, "null is Null");
+  self::expect(null is{ForNonNullableByDefault} Never?, #C1, "null is Never?");
+  self::expect(null is{ForNonNullableByDefault} Never, #C2, "null is Never");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C1, "null is FutureOr<int?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C2, "null is FutureOr<int>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C1, "null is FutureOr<int>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C1, "null is FutureOr<Null>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C1, "null is FutureOr<Null>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C2, "null is FutureOr<Never>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C1, "null is FutureOr<Never?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C1, "null is FutureOr<Never>?");
+  con::test();
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+library;
+import self as con;
+import "constant_null_is.dart" as self;
+import "dart:core" as core;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is.dart";
+
+static const field core::bool* d0 = #C2;
+static const field core::bool* d1 = #C1;
+static method test() → dynamic {
+  self::expect(null is core::int*, #C2, "null is int (opt-out)");
+  self::expect(null is core::Null?, #C1, "null is Null");
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect
new file mode 100644
index 0000000..93feb55
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+import 'constant_null_is_lib.dart';
+
+const c0 = null is int?;
+const c1 = null is int;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+main() {}
+expect(expected, actual, String message) {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..04683eb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+import 'constant_null_is_lib.dart';
+
+const c0 = null is int?;
+const c1 = null is int;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+expect(expected, actual, String message) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.expect
new file mode 100644
index 0000000..6490709
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "constant_null_is_lib.dart" as con;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is_lib.dart";
+
+static const field core::bool c0 = #C1;
+static const field core::bool c1 = #C2;
+static const field core::bool c2 = #C1;
+static const field core::bool c3 = #C1;
+static const field core::bool c4 = #C2;
+static const field core::bool c5 = #C1;
+static const field core::bool c6 = #C2;
+static const field core::bool c7 = #C1;
+static const field core::bool c8 = #C1;
+static const field core::bool c9 = #C1;
+static const field core::bool c10 = #C2;
+static const field core::bool c11 = #C1;
+static const field core::bool c12 = #C1;
+static method main() → dynamic {
+  self::expect(null is{ForNonNullableByDefault} core::int?, #C1, "null is int?");
+  self::expect(null is{ForNonNullableByDefault} core::int, #C2, "null is int");
+  self::expect(null is{ForNonNullableByDefault} core::Null?, #C1, "null is Null");
+  self::expect(null is{ForNonNullableByDefault} Never?, #C1, "null is Never?");
+  self::expect(null is{ForNonNullableByDefault} Never, #C2, "null is Never");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C1, "null is FutureOr<int?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C2, "null is FutureOr<int>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C1, "null is FutureOr<int>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C1, "null is FutureOr<Null>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C1, "null is FutureOr<Null>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C2, "null is FutureOr<Never>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C1, "null is FutureOr<Never?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C1, "null is FutureOr<Never>?");
+  con::test();
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+library;
+import self as con;
+import "constant_null_is.dart" as self;
+import "dart:core" as core;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is.dart";
+
+static const field core::bool* d0 = #C2;
+static const field core::bool* d1 = #C1;
+static method test() → dynamic {
+  self::expect(null is core::int*, #C2, "null is int (opt-out)");
+  self::expect(null is core::Null?, #C1, "null is Null");
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.transformed.expect
new file mode 100644
index 0000000..6490709
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "constant_null_is_lib.dart" as con;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is_lib.dart";
+
+static const field core::bool c0 = #C1;
+static const field core::bool c1 = #C2;
+static const field core::bool c2 = #C1;
+static const field core::bool c3 = #C1;
+static const field core::bool c4 = #C2;
+static const field core::bool c5 = #C1;
+static const field core::bool c6 = #C2;
+static const field core::bool c7 = #C1;
+static const field core::bool c8 = #C1;
+static const field core::bool c9 = #C1;
+static const field core::bool c10 = #C2;
+static const field core::bool c11 = #C1;
+static const field core::bool c12 = #C1;
+static method main() → dynamic {
+  self::expect(null is{ForNonNullableByDefault} core::int?, #C1, "null is int?");
+  self::expect(null is{ForNonNullableByDefault} core::int, #C2, "null is int");
+  self::expect(null is{ForNonNullableByDefault} core::Null?, #C1, "null is Null");
+  self::expect(null is{ForNonNullableByDefault} Never?, #C1, "null is Never?");
+  self::expect(null is{ForNonNullableByDefault} Never, #C2, "null is Never");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C1, "null is FutureOr<int?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C2, "null is FutureOr<int>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C1, "null is FutureOr<int>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C1, "null is FutureOr<Null>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C1, "null is FutureOr<Null>?");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C2, "null is FutureOr<Never>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C1, "null is FutureOr<Never?>");
+  self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C1, "null is FutureOr<Never>?");
+  con::test();
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+library;
+import self as con;
+import "constant_null_is.dart" as self;
+import "dart:core" as core;
+
+import "dart:async";
+import "org-dartlang-testcase:///constant_null_is.dart";
+
+static const field core::bool* d0 = #C2;
+static const field core::bool* d1 = #C1;
+static method test() → dynamic {
+  self::expect(null is core::int*, #C2, "null is int (opt-out)");
+  self::expect(null is core::Null?, #C1, "null is Null");
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is_lib.dart b/pkg/front_end/testcases/nnbd/constant_null_is_lib.dart
new file mode 100644
index 0000000..16b98a5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is_lib.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+import 'dart:async';
+import 'constant_null_is.dart';
+
+const d0 = null is int;
+const d1 = null is Null;
+//const d2 = null is FutureOr<Null>;
+//const d3 = null is Never;
+
+test() {
+  expect(null is int, d0, "null is int (opt-out)");
+  expect(null is Null, d1, "null is Null");
+  //expect(null is FutureOr<Null>, d2, "null is FutureOr<Null> (opt-out)");
+  //expect(null is Never, d3, "null is Never (opt-out)");
+}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect
new file mode 100644
index 0000000..abf8e2f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect
@@ -0,0 +1,37 @@
+import 'constants_lib.dart' as lib;
+
+typedef F1<T> = T Function(T);
+typedef F2 = T Function<T>(T);
+const objectTypeLiteral = Object;
+const int Function(int) partialInstantiation = lib.id;
+const instance = const lib.Class<int>(0);
+const functionTypeLiteral = F1;
+const genericFunctionTypeLiteral = F2;
+const listLiteral = <int>[0];
+const setLiteral = <int>{0};
+const mapLiteral = <int, String>{0: 'foo'};
+const listConcatenation = <int>[...listLiteral];
+const setConcatenation = <int>{...setLiteral};
+const mapConcatenation = <int, String>{...mapLiteral};
+const objectTypeLiteralIdentical =
+    identical(objectTypeLiteral, lib.objectTypeLiteral);
+const partialInstantiationIdentical =
+    identical(partialInstantiation, lib.partialInstantiation);
+const instanceIdentical = identical(instance, lib.instance);
+const functionTypeLiteralIdentical =
+    identical(functionTypeLiteral, lib.functionTypeLiteral);
+const genericFunctionTypeLiteralIdentical =
+    identical(genericFunctionTypeLiteral, lib.genericFunctionTypeLiteral);
+const listLiteralIdentical = identical(listLiteral, lib.listLiteral);
+const setLiteralIdentical = identical(setLiteral, lib.setLiteral);
+const mapLiteralIdentical = identical(mapLiteral, lib.mapLiteral);
+const listConcatenationIdentical =
+    identical(listConcatenation, lib.listConcatenation);
+const setConcatenationIdentical =
+    identical(setConcatenation, lib.setConcatenation);
+const mapConcatenationIdentical =
+    identical(mapConcatenation, lib.mapConcatenation);
+final bool inStrongMode = _inStrongMode();
+bool _inStrongMode() {}
+main() {}
+test(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..03b68b2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+import 'constants_lib.dart' as lib;
+
+bool _inStrongMode() {}
+const functionTypeLiteral = F1;
+const functionTypeLiteralIdentical =
+    identical(functionTypeLiteral, lib.functionTypeLiteral);
+const genericFunctionTypeLiteral = F2;
+const genericFunctionTypeLiteralIdentical =
+    identical(genericFunctionTypeLiteral, lib.genericFunctionTypeLiteral);
+const instance = const lib.Class<int>(0);
+const instanceIdentical = identical(instance, lib.instance);
+const int Function(int) partialInstantiation = lib.id;
+const listConcatenation = <int>[...listLiteral];
+const listConcatenationIdentical =
+    identical(listConcatenation, lib.listConcatenation);
+const listLiteral = <int>[0];
+const listLiteralIdentical = identical(listLiteral, lib.listLiteral);
+const mapConcatenation = <int, String>{...mapLiteral};
+const mapConcatenationIdentical =
+    identical(mapConcatenation, lib.mapConcatenation);
+const mapLiteral = <int, String>{0: 'foo'};
+const mapLiteralIdentical = identical(mapLiteral, lib.mapLiteral);
+const objectTypeLiteral = Object;
+const objectTypeLiteralIdentical =
+    identical(objectTypeLiteral, lib.objectTypeLiteral);
+const partialInstantiationIdentical =
+    identical(partialInstantiation, lib.partialInstantiation);
+const setConcatenation = <int>{...setLiteral};
+const setConcatenationIdentical =
+    identical(setConcatenation, lib.setConcatenation);
+const setLiteral = <int>{0};
+const setLiteralIdentical = identical(setLiteral, lib.setLiteral);
+final bool inStrongMode = _inStrongMode();
+main() {}
+test(expected, actual) {}
+typedef F1<T> = T Function(T);
+typedef F2 = T Function<T>(T);
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart b/pkg/front_end/testcases/nnbd/covariant_equals.dart
new file mode 100644
index 0000000..b69bb3e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+
+testNonNullable(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {
+  a == a; // ok
+  a == b; // ok
+  a == c_dynamic; // error
+  a == c_int; // error
+  a == c_string; // error
+  a == d; // error
+
+  b == a; // ok
+  b == b; // ok
+  b == c_dynamic; // error
+  b == c_int; // error
+  b == c_string; // error
+  b == d; // error
+
+  c_dynamic == a; // error
+  c_dynamic == b; // error
+  c_dynamic == c_dynamic; // ok
+  c_dynamic == c_int; // ok
+  c_dynamic == c_string; // ok
+  c_dynamic == d; // ok
+
+  c_int == a; // error
+  c_int == b; // error
+  c_int == c_dynamic; // error
+  c_int == c_int; // ok
+  c_int == c_string; // error
+  c_int == d; // ok}
+
+  c_string == a; // error
+  c_string == b; // error
+  c_string == c_dynamic; // error
+  c_string == c_int; // error
+  c_string == c_string; // ok
+  c_string == d; // error
+
+  d == a; // error
+  d == b; // error
+  d == c_dynamic; // error
+  d == c_int; // ok
+  d == c_string; // error
+  d == d; // ok
+}
+
+testNullable(
+    A? a, B? b, C? c_dynamic, C<int>? c_int, C<String>? c_string, D? d) {
+  // Since the receiver type is nullable, the calls are checked against the
+  // Object member.
+
+  a == a; // ok
+  a == b; // ok
+  // TODO(johnniwinther): Awaiting spec update about `==`. Before NNBD these
+  // would cause an error but with the current (insufficient) specification for
+  // `==` it is ok.
+  a == c_dynamic; // ok or error ?
+  a == c_int; // ok or error ?
+  a == c_string; // ok or error ?
+  a == d; // ok or error ?
+
+  b == a; // ok
+  b == b; // ok
+  b == c_dynamic; // ok or error ?
+  b == c_int; // ok or error ?
+  b == c_string; // ok or error ?
+  b == d; // ok or error ?
+
+  c_dynamic == a; // ok or error ?
+  c_dynamic == b; // ok or error ?
+  c_dynamic == c_dynamic; // ok
+  c_dynamic == c_int; // ok
+  c_dynamic == c_string; // ok
+  c_dynamic == d; // ok
+
+  c_int == a; // ok or error ?
+  c_int == b; // ok or error ?
+  c_int == c_dynamic; // ok or error ?
+  c_int == c_int; // ok
+  c_int == c_string; // ok or error ?
+  c_int == d; // ok}
+
+  c_string == a; // ok or error ?
+  c_string == b; // ok or error ?
+  c_string == c_dynamic; // ok or error ?
+  c_string == c_int; // ok or error ?
+  c_string == c_string; // ok
+  c_string == d; // ok or error ?
+
+  d == a; // ok or error ?
+  d == b; // ok or error ?
+  d == c_dynamic; // ok or error ?
+  d == c_int; // ok
+  d == c_string; // ok or error ?
+  d == d; // ok
+}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.outline.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.outline.expect
new file mode 100644
index 0000000..7ead045
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  operator ==(covariant self::A other) → core::bool
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  operator ==(covariant self::A other) → core::bool
+    ;
+}
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T%> other) → core::bool
+    ;
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → self::D
+    ;
+}
+static method main() → dynamic
+  ;
+static method testNonNullable(self::A a, self::B b, self::C<dynamic> c_dynamic, self::C<core::int> c_int, self::C<core::String> c_string, self::D d) → dynamic
+  ;
+static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect
new file mode 100644
index 0000000..6c746cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect
@@ -0,0 +1,546 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // ok or error ?
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T%> other) → core::bool
+    return true;
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method testNonNullable(self::A a, self::B b, self::C<dynamic> c_dynamic, self::C<core::int> c_int, self::C<core::String> c_string, self::D d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // error
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // error
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
+static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // ok or error ?
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // ok or error ?
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // ok or error ?
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // ok or error ?
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // ok or error ?
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // ok or error ?
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // ok or error ?
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // ok or error ?
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // ok or error ?
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // ok or error ?
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // ok or error ?
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // ok or error ?
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // ok or error ?
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..6c746cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect
@@ -0,0 +1,546 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // ok or error ?
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T%> other) → core::bool
+    return true;
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method testNonNullable(self::A a, self::B b, self::C<dynamic> c_dynamic, self::C<core::int> c_int, self::C<core::String> c_string, self::D d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // error
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // error
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
+static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // ok or error ?
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // ok or error ?
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // ok or error ?
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // ok or error ?
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // ok or error ?
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // ok or error ?
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // ok or error ?
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // ok or error ?
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // ok or error ?
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // ok or error ?
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // ok or error ?
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // ok or error ?
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // ok or error ?
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..adc9984
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+testNonNullable(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
+testNullable(
+    A? a, B? b, C? c_dynamic, C<int>? c_int, C<String>? c_string, D? d) {}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..adc9984
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A {
+  bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+  bool operator ==(other) => true;
+}
+
+class C<T> {
+  bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+testNonNullable(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
+testNullable(
+    A? a, B? b, C? c_dynamic, C<int>? c_int, C<String>? c_string, D? d) {}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect
new file mode 100644
index 0000000..6c746cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect
@@ -0,0 +1,546 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // ok or error ?
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T%> other) → core::bool
+    return true;
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method testNonNullable(self::A a, self::B b, self::C<dynamic> c_dynamic, self::C<core::int> c_int, self::C<core::String> c_string, self::D d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // error
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // error
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
+static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // ok or error ?
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // ok or error ?
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // ok or error ?
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // ok or error ?
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // ok or error ?
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // ok or error ?
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // ok or error ?
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // ok or error ?
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // ok or error ?
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // ok or error ?
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // ok or error ?
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // ok or error ?
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // ok or error ?
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect
new file mode 100644
index 0000000..6c746cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect
@@ -0,0 +1,546 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // error
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   a == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_int; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == c_string; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   b == d; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == a; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_dynamic == b; // ok or error ?
+//                ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == a; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == b; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_dynamic; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_int == c_string; // ok or error ?
+//            ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == a; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == b; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_dynamic; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == c_int; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+//  - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   c_string == d; // ok or error ?
+//               ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == a; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == b; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_dynamic; // ok or error ?
+//        ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+//  - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+//   d == c_string; // ok or error ?
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  operator ==(covariant self::A other) → core::bool
+    return true;
+}
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  operator ==(covariant generic-covariant-impl self::C<self::C::T%> other) → core::bool
+    return true;
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
+static method testNonNullable(self::A a, self::B b, self::C<dynamic> c_dynamic, self::C<core::int> c_int, self::C<core::String> c_string, self::D d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:24:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:25:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:26:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:27:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:31:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:32:8: Error: The argument type 'C<int>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // error
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:33:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:34:8: Error: The argument type 'D' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // error
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:36:16: Error: The argument type 'A' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // error
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:37:16: Error: The argument type 'B' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // error
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:43:12: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // error
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:44:12: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // error
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:45:12: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // error
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:47:12: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // error
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:50:15: Error: The argument type 'A' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // error
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:51:15: Error: The argument type 'B' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // error
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:52:15: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // error
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:53:15: Error: The argument type 'C<int>' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // error
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:55:15: Error: The argument type 'D' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // error
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:57:8: Error: The argument type 'A' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // error
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:58:8: Error: The argument type 'B' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // error
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:59:8: Error: The argument type 'C<dynamic>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // error
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:61:8: Error: The argument type 'C<String>' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // error
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
+static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
+  a.{self::A::==}(a);
+  a.{self::A::==}(b);
+  a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  a == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(a);
+  b.{self::B::==}(b);
+  b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_int; // ok or error ?
+       ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+  b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  b == d; // ok or error ?
+       ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == a; // ok or error ?
+               ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_dynamic == b; // ok or error ?
+               ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+  c_dynamic.{self::C::==}(c_dynamic);
+  c_dynamic.{self::C::==}(c_int);
+  c_dynamic.{self::C::==}(c_string);
+  c_dynamic.{self::C::==}(d);
+  c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == a; // ok or error ?
+           ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == b; // ok or error ?
+           ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_dynamic; // ok or error ?
+           ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(c_int);
+  c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_int == c_string; // ok or error ?
+           ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  c_int.{self::C::==}(d);
+  c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == a; // ok or error ?
+              ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == b; // ok or error ?
+              ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_dynamic; // ok or error ?
+              ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == c_int; // ok or error ?
+              ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  c_string.{self::C::==}(c_string);
+  c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  c_string == d; // ok or error ?
+              ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+  d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == a; // ok or error ?
+       ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == b; // ok or error ?
+       ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_dynamic; // ok or error ?
+       ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(c_int);
+  d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+  d == c_string; // ok or error ?
+       ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+  d.{self::C::==}(d);
+}
diff --git a/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline.expect
new file mode 100644
index 0000000..7e4bc1e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+abstract class A {
+  void method(dynamic a);
+}
+
+abstract class B {
+  void method(covariant num a);
+}
+
+abstract class C {
+  void method(covariant int a);
+}
+
+abstract class D1 implements A, B, C {}
+
+abstract class D2 implements A, B {}
+
+abstract class D3 implements B, C {}
+
+abstract class D4 implements C, B {}
+
+abstract class D5 implements A, C {}
+
+abstract class E {
+  void method(num a);
+}
+
+abstract class F {
+  void method(covariant int a);
+}
+
+abstract class G1 implements E, F {}
+
+abstract class G2 implements F, E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7e4bc1e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+abstract class A {
+  void method(dynamic a);
+}
+
+abstract class B {
+  void method(covariant num a);
+}
+
+abstract class C {
+  void method(covariant int a);
+}
+
+abstract class D1 implements A, B, C {}
+
+abstract class D2 implements A, B {}
+
+abstract class D3 implements B, C {}
+
+abstract class D4 implements C, B {}
+
+abstract class D5 implements A, C {}
+
+abstract class E {
+  void method(num a);
+}
+
+abstract class F {
+  void method(covariant int a);
+}
+
+abstract class G1 implements E, F {}
+
+abstract class G2 implements F, E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline.expect
new file mode 100644
index 0000000..5f6d991
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+int foo() {}
+int bar() => 0;
+int baz(int x) {}
+int boz(int x) => x;
+
+class Class {
+  final int x;
+  const Class(int x) : this.x = x;
+  int foo() {}
+  int bar() => 0;
+  int baz(int x) {}
+  int boz(int x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..84320f1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Class {
+  const Class(int x) : this.x = x;
+  final int x;
+  int bar() => 0;
+  int baz(int x) {}
+  int boz(int x) => x;
+  int foo() {}
+}
+
+int bar() => 0;
+int baz(int x) {}
+int boz(int x) => x;
+int foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline.expect
new file mode 100644
index 0000000..1932ec0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  if (b) {
+    local2 = value;
+    local4 = 0;
+    local6 = 0;
+  }
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
+methodCompound() {}
+var fieldCompound = () {
+  late;
+  final int local4;
+  local4 = 0;
+  local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..be04eb0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+  late;
+  final int local4;
+  local4 = 0;
+  local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  if (b) {
+    local2 = value;
+    local4 = 0;
+    local6 = 0;
+  }
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
+var fieldDirect = <T>(T value) {
+  late;
+  final T local2;
+  late;
+  final int local4;
+  late;
+  final FutureOr<int> local6;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+  local2 = value;
+  local4 = 0;
+  local6 = 0;
+};
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline.expect
new file mode 100644
index 0000000..f27c6c0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  if (b) {
+    local1 = value;
+    local2 = value;
+    local3 = 0;
+    local4 = 0;
+    local5 = 0;
+    local6 = 0;
+    local7;
+  }
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
+methodCompound() {}
+var fieldCompound = () {
+  int local3;
+  late int;
+  local4;
+  local3 += 0;
+  local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46a4371
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+  int local3;
+  late int;
+  local4;
+  local3 += 0;
+  local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  if (b) {
+    local1 = value;
+    local2 = value;
+    local3 = 0;
+    local4 = 0;
+    local5 = 0;
+    local6 = 0;
+    local7;
+  }
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
+var fieldDirect = <T>(T value) {
+  T local1;
+  late T;
+  local2;
+  int local3;
+  late int;
+  local4;
+  FutureOr<int> local5;
+  late FutureOr;
+  <int>[];
+  local6;
+  late T;
+  local7 = value;
+  local1;
+  local2;
+  local3;
+  local4;
+  local5;
+  local6;
+  local7;
+};
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..fe91737
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+  bar(T value) {}
+  barInt(int value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe91737
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+  bar(T value) {}
+  barInt(int value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline.expect
new file mode 100644
index 0000000..fee39b9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+method<T>(T a, T b) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..caff637
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+method<T>(T a, T b) {}
diff --git a/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..24a177d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+export 'export_from_opt_out_lib1.dart';
+export 'export_from_opt_out_lib2.dart' hide legacyMethod2;
+export 'export_from_opt_out_lib3.dart' show LegacyClass2;
+export 'export_from_opt_out_lib3.dart' show legacyMethod1;
+export 'export_from_opt_out_lib3.dart' show LegacyExtension;
+export 'export_from_opt_out_lib3.dart' show LegacyTypedef;
+export 'export_from_opt_out_lib3.dart' show NnbdClass1;
+export 'export_from_opt_out_lib3.dart'
+    hide LegacyClass2, LegacyExtension, LegacyTypedef, legacyMethod1;
+export 'export_from_opt_out_lib4.dart';
+export 'export_from_opt_out_lib5.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..24a177d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+export 'export_from_opt_out_lib1.dart';
+export 'export_from_opt_out_lib2.dart' hide legacyMethod2;
+export 'export_from_opt_out_lib3.dart' show LegacyClass2;
+export 'export_from_opt_out_lib3.dart' show legacyMethod1;
+export 'export_from_opt_out_lib3.dart' show LegacyExtension;
+export 'export_from_opt_out_lib3.dart' show LegacyTypedef;
+export 'export_from_opt_out_lib3.dart' show NnbdClass1;
+export 'export_from_opt_out_lib3.dart'
+    hide LegacyClass2, LegacyExtension, LegacyTypedef, legacyMethod1;
+export 'export_from_opt_out_lib4.dart';
+export 'export_from_opt_out_lib5.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.textual_outline.expect
new file mode 100644
index 0000000..7b4b277
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.textual_outline.expect
@@ -0,0 +1,40 @@
+class Aoo {
+}
+class Boo {
+}
+class Coo extends Boo with Aoo? {
+}
+class Doo extends Aoo? {
+}
+class Eoo implements Boo? {
+}
+class Foo extends Boo? with Aoo {
+}
+class Goo = Boo? with Aoo?;
+class Hoo extends Object with Aoo implements Boo? {
+}
+class Ioo = Object with Aoo implements Boo?;
+class Joo extends Boo with Never {
+}
+class Koo extends Never {
+}
+class Loo implements Never {
+}
+mixin Moo1 on Aoo? implements Boo? {
+}
+mixin Moo2 on Aoo?, Boo? {
+}
+mixin Moo3 implements Aoo?, Boo? {
+}
+mixin Moo4 on Aoo implements Never {
+}
+mixin Moo5 on Aoo, Never {
+}
+mixin Moo6 on Never {
+}
+mixin Moo7 implements Aoo, Never {
+}
+mixin Moo8 implements Never {
+}
+class Noo = Never with Aoo; class NooDynamic = dynamic with Aoo; class NooVoid = void with Aoo; class Ooo = Aoo with Never;
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
index b65a75c..0b1f6c0 100644
--- a/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
@@ -50,11 +50,10 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method error(core::Iterable<core::int>? i2, core::List<core::int>? l2, core::Object o1, core::Object? o2) → dynamic {
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   for (int x in i2) x;
                 ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
@@ -66,7 +65,7 @@
   block {
     final core::List<core::int> #t2 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in i2) x];
                  ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
@@ -77,7 +76,7 @@
     }
   } =>#t2;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:12:17: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:12:17: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'List' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in l2) x;
@@ -90,7 +89,7 @@
   block {
     final core::List<core::int> #t5 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:13:18: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:13:18: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'List' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in l2) x];
@@ -102,7 +101,7 @@
     }
   } =>#t5;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:15:17: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:15:17: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in o1) x;
@@ -118,7 +117,7 @@
   block {
     final core::List<core::int> #t9 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:16:18: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:16:18: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in o1) x];
@@ -133,7 +132,7 @@
     }
   } =>#t9;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:18:17: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:18:17: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in o2) x;
@@ -149,7 +148,7 @@
   block {
     final core::List<core::int> #t14 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:19:18: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:19:18: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in o2) x];
@@ -166,7 +165,7 @@
 }
 static method ok(core::Iterable<core::int> i1, core::List<core::int> l1, dynamic d) → dynamic {
   {
-    core::Iterator<core::int>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int>*>(i1).{core::Iterable::iterator};
+    core::Iterator<core::int> :sync-for-iterator = i1.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int x = :sync-for-iterator.{core::Iterator::current};
       x;
@@ -175,7 +174,7 @@
   block {
     final core::List<core::int> #t17 = <core::int>[];
     {
-      core::Iterator<core::int>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int>*>(i1).{core::Iterable::iterator};
+      core::Iterator<core::int> :sync-for-iterator = i1.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int x = :sync-for-iterator.{core::Iterator::current};
         #t17.{core::List::add}(x);
@@ -183,7 +182,7 @@
     }
   } =>#t17;
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(l1).{core::Iterable::iterator};
+    core::Iterator<core::int*> :sync-for-iterator = l1.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int x = :sync-for-iterator.{core::Iterator::current};
       x;
@@ -192,7 +191,7 @@
   block {
     final core::List<core::int> #t18 = <core::int>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(l1).{core::Iterable::iterator};
+      core::Iterator<core::int*> :sync-for-iterator = l1.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int x = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::List::add}(x);
@@ -200,7 +199,7 @@
     }
   } =>#t18;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+    core::Iterator<dynamic> :sync-for-iterator = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -212,7 +211,7 @@
   block {
     final core::List<core::int> #t20 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      core::Iterator<dynamic> :sync-for-iterator = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline.expect
new file mode 100644
index 0000000..1456cad
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+error(Iterable<int>? i2, List<int>? l2, Object o1, Object? o2) {}
+ok(Iterable<int> i1, List<int> l1, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8e81031
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+error(Iterable<int>? i2, List<int>? l2, Object o1, Object? o2) {}
+main() {}
+ok(Iterable<int> i1, List<int> l1, dynamic d) {}
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect
index b65a75c..0b1f6c0 100644
--- a/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect
@@ -50,11 +50,10 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method error(core::Iterable<core::int>? i2, core::List<core::int>? l2, core::Object o1, core::Object? o2) → dynamic {
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   for (int x in i2) x;
                 ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
@@ -66,7 +65,7 @@
   block {
     final core::List<core::int> #t2 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in i2) x];
                  ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
@@ -77,7 +76,7 @@
     }
   } =>#t2;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:12:17: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:12:17: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'List' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in l2) x;
@@ -90,7 +89,7 @@
   block {
     final core::List<core::int> #t5 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:13:18: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:13:18: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'List' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in l2) x];
@@ -102,7 +101,7 @@
     }
   } =>#t5;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:15:17: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:15:17: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in o1) x;
@@ -118,7 +117,7 @@
   block {
     final core::List<core::int> #t9 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:16:18: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:16:18: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in o1) x];
@@ -133,7 +132,7 @@
     }
   } =>#t9;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:18:17: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:18:17: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   for (int x in o2) x;
@@ -149,7 +148,7 @@
   block {
     final core::List<core::int> #t14 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:19:18: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+      core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:19:18: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Object' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   [for (int x in o2) x];
@@ -166,7 +165,7 @@
 }
 static method ok(core::Iterable<core::int> i1, core::List<core::int> l1, dynamic d) → dynamic {
   {
-    core::Iterator<core::int>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int>*>(i1).{core::Iterable::iterator};
+    core::Iterator<core::int> :sync-for-iterator = i1.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int x = :sync-for-iterator.{core::Iterator::current};
       x;
@@ -175,7 +174,7 @@
   block {
     final core::List<core::int> #t17 = <core::int>[];
     {
-      core::Iterator<core::int>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int>*>(i1).{core::Iterable::iterator};
+      core::Iterator<core::int> :sync-for-iterator = i1.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int x = :sync-for-iterator.{core::Iterator::current};
         #t17.{core::List::add}(x);
@@ -183,7 +182,7 @@
     }
   } =>#t17;
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(l1).{core::Iterable::iterator};
+    core::Iterator<core::int*> :sync-for-iterator = l1.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int x = :sync-for-iterator.{core::Iterator::current};
       x;
@@ -192,7 +191,7 @@
   block {
     final core::List<core::int> #t18 = <core::int>[];
     {
-      core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(l1).{core::Iterable::iterator};
+      core::Iterator<core::int*> :sync-for-iterator = l1.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int x = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::List::add}(x);
@@ -200,7 +199,7 @@
     }
   } =>#t18;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+    core::Iterator<dynamic> :sync-for-iterator = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -212,7 +211,7 @@
   block {
     final core::List<core::int> #t20 = <core::int>[];
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      core::Iterator<dynamic> :sync-for-iterator = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline.expect
new file mode 100644
index 0000000..9d9786f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+import 'from_agnostic_lib.dart';
+
+const c1 = identical(a, b);
+const c2 = {a: 0, b: 1};
+const c3 = {a, b};
+const c4 = a;
+const c5 = b;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9d9786f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import 'from_agnostic_lib.dart';
+
+const c1 = identical(a, b);
+const c2 = {a: 0, b: 1};
+const c3 = {a, b};
+const c4 = a;
+const c5 = b;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline.expect
new file mode 100644
index 0000000..1f61005
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+typedef F = void Function();
+void foo() {}
+F bar() => foo;
+F? baz() => foo;
+void Function() hest() => foo;
+void Function()? fisk() => foo;
+Function()? foobar(Function()? x) => null;
+
+class A<T> {}
+
+class B extends A<Function()?> {
+  Function()? method(Function()? x) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a2c7a1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+F bar() => foo;
+F? baz() => foo;
+Function()? foobar(Function()? x) => null;
+
+class A<T> {}
+
+class B extends A<Function()?> {
+  Function()? method(Function()? x) => null;
+}
+
+main() {}
+typedef F = void Function();
+void Function() hest() => foo;
+void Function()? fisk() => foo;
+void foo() {}
diff --git a/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..a1e748f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline.expect
@@ -0,0 +1,49 @@
+import 'dart:async';
+
+FutureOr topLevelField1;
+FutureOr<int?> topLevelField2;
+FutureOr<FutureOr> topLevelField3;
+void toplevelMethod1(
+    [FutureOr parameter1,
+    FutureOr<int?> parameter2,
+    FutureOr<FutureOr> parameter3]) {}
+void toplevelMethod2(
+    {FutureOr parameter1,
+    FutureOr<int?> parameter2,
+    FutureOr<FutureOr> parameter3}) {}
+
+class Class1 {
+  FutureOr instanceField1;
+  FutureOr<int?> instanceField2;
+  FutureOr<FutureOr> instanceField3;
+  static FutureOr staticField1;
+  static FutureOr<int?> staticField2;
+  static FutureOr<FutureOr> staticField3;
+  void instanceMethod1(
+      [FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3]) {}
+  void instanceMethod2(
+      {FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3}) {}
+  static void staticMethod1(
+      [FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3]) {}
+  static void staticMethod2(
+      {FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3}) {}
+}
+
+class Class2 {
+  FutureOr instanceField1;
+  FutureOr<int?> instanceField2;
+  FutureOr<FutureOr> instanceField3;
+  Class2.constructor1(
+      this.instanceField1, this.instanceField2, this.instanceField3);
+  Class2.constructor2();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff98b1c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+import 'dart:async';
+
+FutureOr topLevelField1;
+FutureOr<FutureOr> topLevelField3;
+FutureOr<int?> topLevelField2;
+
+class Class1 {
+  FutureOr instanceField1;
+  FutureOr<FutureOr> instanceField3;
+  FutureOr<int?> instanceField2;
+  static FutureOr staticField1;
+  static FutureOr<FutureOr> staticField3;
+  static FutureOr<int?> staticField2;
+  static void staticMethod1(
+      [FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3]) {}
+  static void staticMethod2(
+      {FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3}) {}
+  void instanceMethod1(
+      [FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3]) {}
+  void instanceMethod2(
+      {FutureOr parameter1,
+      FutureOr<int?> parameter2,
+      FutureOr<FutureOr> parameter3}) {}
+}
+
+class Class2 {
+  Class2.constructor1(
+      this.instanceField1, this.instanceField2, this.instanceField3);
+  Class2.constructor2();
+  FutureOr instanceField1;
+  FutureOr<FutureOr> instanceField3;
+  FutureOr<int?> instanceField2;
+}
+
+main() {}
+void toplevelMethod1(
+    [FutureOr parameter1,
+    FutureOr<int?> parameter2,
+    FutureOr<FutureOr> parameter3]) {}
+void toplevelMethod2(
+    {FutureOr parameter1,
+    FutureOr<int?> parameter2,
+    FutureOr<FutureOr> parameter3}) {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart b/pkg/front_end/testcases/nnbd/generic_override.dart
index f898600..8a3f194 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart
+++ b/pkg/front_end/testcases/nnbd/generic_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.
 
+import 'generic_override_lib.dart';
+
 abstract class Class1 {
   void method1a<T>();
   void method1b<T>();
@@ -42,4 +44,24 @@
   void method5c<T extends Class1>(); // error
 }
 
+abstract class Class3 extends LegacyClass1 {
+  void method1a<T>();
+  void method1b<T extends Object?>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object?>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object?>();
+  void method3c<T extends dynamic>();
+
+  void method4a<T extends Object>();
+  void method4b<T extends Object?>();
+  void method4c<T extends Object>();
+
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1?>();
+  void method5c<T extends Class1>();
+}
+
 main() {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
index 7af22c0..1364f7a 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
@@ -2,40 +2,43 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
 //  - 'Object' is from 'dart:core'.
 //   void method4b<T extends Object?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
 //   void method4b<T extends Object>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
 //  - 'Object' is from 'dart:core'.
 //   void method4c<T extends Object>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
 //   void method4c<T extends Object?>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5b<T extends Class1?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
 //   void method5b<T extends Class1>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5c<T extends Class1>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
 //   void method5c<T extends Class1?>();
 //        ^
 //
 import self as self;
 import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
 
 abstract class Class1 extends core::Object {
   synthetic constructor •() → self::Class1
@@ -75,5 +78,88 @@
   abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
   abstract method method5c<T extends self::Class1 = self::Class1>() → void;
 }
+abstract class Class3 extends gen::LegacyClass1 {
+  synthetic constructor •() → self::Class3
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic
+  ;
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+  synthetic constructor •() → gen::LegacyClass1*
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = dynamic>() → void;
+  abstract method method1c<T extends core::Object* = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass2*
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = core::Object*>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = dynamic>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object* = dynamic>() → void;
+  abstract method method3b<T extends core::Object* = core::Object*>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass3*
+    ;
+  abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
@@ -2,40 +2,43 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
 //  - 'Object' is from 'dart:core'.
 //   void method4b<T extends Object?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
 //   void method4b<T extends Object>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
 //  - 'Object' is from 'dart:core'.
 //   void method4c<T extends Object>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
 //   void method4c<T extends Object?>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5b<T extends Class1?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
 //   void method5b<T extends Class1>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5c<T extends Class1>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
 //   void method5c<T extends Class1?>();
 //        ^
 //
 import self as self;
 import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
 
 abstract class Class1 extends core::Object {
   synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
   abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
   abstract method method5c<T extends self::Class1 = self::Class1>() → void;
 }
+abstract class Class3 extends gen::LegacyClass1 {
+  synthetic constructor •() → self::Class3
+    : super gen::LegacyClass1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+  synthetic constructor •() → gen::LegacyClass1*
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = dynamic>() → void;
+  abstract method method1c<T extends core::Object* = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass2*
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = core::Object*>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = dynamic>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object* = dynamic>() → void;
+  abstract method method3b<T extends core::Object* = core::Object*>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass3*
+    : super self::Class1::•()
+    ;
+  abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
@@ -2,40 +2,43 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
 //  - 'Object' is from 'dart:core'.
 //   void method4b<T extends Object?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
 //   void method4b<T extends Object>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
 //  - 'Object' is from 'dart:core'.
 //   void method4c<T extends Object>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
 //   void method4c<T extends Object?>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5b<T extends Class1?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
 //   void method5b<T extends Class1>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5c<T extends Class1>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
 //   void method5c<T extends Class1?>();
 //        ^
 //
 import self as self;
 import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
 
 abstract class Class1 extends core::Object {
   synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
   abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
   abstract method method5c<T extends self::Class1 = self::Class1>() → void;
 }
+abstract class Class3 extends gen::LegacyClass1 {
+  synthetic constructor •() → self::Class3
+    : super gen::LegacyClass1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+  synthetic constructor •() → gen::LegacyClass1*
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = dynamic>() → void;
+  abstract method method1c<T extends core::Object* = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass2*
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = core::Object*>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = dynamic>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object* = dynamic>() → void;
+  abstract method method3b<T extends core::Object* = core::Object*>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass3*
+    : super self::Class1::•()
+    ;
+  abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline.expect
new file mode 100644
index 0000000..fc94cdb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline.expect
@@ -0,0 +1,57 @@
+import 'generic_override_lib.dart';
+
+abstract class Class1 {
+  void method1a<T>();
+  void method1b<T>();
+  void method1c<T>();
+  void method2a<T extends Object?>();
+  void method2b<T extends Object?>();
+  void method2c<T extends Object?>();
+  void method3a<T extends dynamic>();
+  void method3b<T extends dynamic>();
+  void method3c<T extends dynamic>();
+  void method4a<T extends Object>();
+  void method4b<T extends Object>();
+  void method4c<T extends Object?>();
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1>();
+  void method5c<T extends Class1?>();
+}
+
+abstract class Class2 extends Class1 {
+  void method1a<T>();
+  void method1b<T extends Object?>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object?>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object?>();
+  void method3c<T extends dynamic>();
+  void method4a<T extends Object>();
+  void method4b<T extends Object?>();
+  void method4c<T extends Object>();
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1?>();
+  void method5c<T extends Class1>();
+}
+
+abstract class Class3 extends LegacyClass1 {
+  void method1a<T>();
+  void method1b<T extends Object?>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object?>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object?>();
+  void method3c<T extends dynamic>();
+  void method4a<T extends Object>();
+  void method4b<T extends Object?>();
+  void method4c<T extends Object>();
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1?>();
+  void method5c<T extends Class1>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc94cdb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,57 @@
+import 'generic_override_lib.dart';
+
+abstract class Class1 {
+  void method1a<T>();
+  void method1b<T>();
+  void method1c<T>();
+  void method2a<T extends Object?>();
+  void method2b<T extends Object?>();
+  void method2c<T extends Object?>();
+  void method3a<T extends dynamic>();
+  void method3b<T extends dynamic>();
+  void method3c<T extends dynamic>();
+  void method4a<T extends Object>();
+  void method4b<T extends Object>();
+  void method4c<T extends Object?>();
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1>();
+  void method5c<T extends Class1?>();
+}
+
+abstract class Class2 extends Class1 {
+  void method1a<T>();
+  void method1b<T extends Object?>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object?>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object?>();
+  void method3c<T extends dynamic>();
+  void method4a<T extends Object>();
+  void method4b<T extends Object?>();
+  void method4c<T extends Object>();
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1?>();
+  void method5c<T extends Class1>();
+}
+
+abstract class Class3 extends LegacyClass1 {
+  void method1a<T>();
+  void method1b<T extends Object?>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object?>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object?>();
+  void method3c<T extends dynamic>();
+  void method4a<T extends Object>();
+  void method4b<T extends Object?>();
+  void method4c<T extends Object>();
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1?>();
+  void method5c<T extends Class1>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
@@ -2,40 +2,43 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
 //  - 'Object' is from 'dart:core'.
 //   void method4b<T extends Object?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
 //   void method4b<T extends Object>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
 //  - 'Object' is from 'dart:core'.
 //   void method4c<T extends Object>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
 //   void method4c<T extends Object?>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5b<T extends Class1?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
 //   void method5b<T extends Class1>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5c<T extends Class1>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
 //   void method5c<T extends Class1?>();
 //        ^
 //
 import self as self;
 import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
 
 abstract class Class1 extends core::Object {
   synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
   abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
   abstract method method5c<T extends self::Class1 = self::Class1>() → void;
 }
+abstract class Class3 extends gen::LegacyClass1 {
+  synthetic constructor •() → self::Class3
+    : super gen::LegacyClass1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+  synthetic constructor •() → gen::LegacyClass1*
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = dynamic>() → void;
+  abstract method method1c<T extends core::Object* = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass2*
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = core::Object*>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = dynamic>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object* = dynamic>() → void;
+  abstract method method3b<T extends core::Object* = core::Object*>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass3*
+    : super self::Class1::•()
+    ;
+  abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
@@ -2,40 +2,43 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
 //  - 'Object' is from 'dart:core'.
 //   void method4b<T extends Object?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
 //   void method4b<T extends Object>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
 //  - 'Object' is from 'dart:core'.
 //   void method4c<T extends Object>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
 //   void method4c<T extends Object?>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5b<T extends Class1?>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
 //   void method5b<T extends Class1>();
 //        ^
 //
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
 //  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
 //   void method5c<T extends Class1>(); // error
 //        ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
 //   void method5c<T extends Class1?>();
 //        ^
 //
 import self as self;
 import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
 
 abstract class Class1 extends core::Object {
   synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
   abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
   abstract method method5c<T extends self::Class1 = self::Class1>() → void;
 }
+abstract class Class3 extends gen::LegacyClass1 {
+  synthetic constructor •() → self::Class3
+    : super gen::LegacyClass1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+  synthetic constructor •() → gen::LegacyClass1*
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = dynamic>() → void;
+  abstract method method1c<T extends core::Object* = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass2*
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object* = dynamic>() → void;
+  abstract method method1b<T extends core::Object* = core::Object*>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object* = dynamic>() → void;
+  abstract method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object* = dynamic>() → void;
+  abstract method method3b<T extends core::Object* = core::Object*>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+  synthetic constructor •() → gen::LegacyClass3*
+    : super self::Class1::•()
+    ;
+  abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+  abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+  abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+  abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override_lib.dart b/pkg/front_end/testcases/nnbd/generic_override_lib.dart
new file mode 100644
index 0000000..8a2640df
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override_lib.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+import 'generic_override.dart';
+
+abstract class LegacyClass1 {
+  void method1a<T>();
+  void method1b<T>();
+  void method1c<T>();
+  void method2a<T extends Object>();
+  void method2b<T extends Object>();
+  void method2c<T extends Object>();
+  void method3a<T extends dynamic>();
+  void method3b<T extends dynamic>();
+  void method3c<T extends dynamic>();
+
+  void method4a<T extends Object>();
+  void method4b<T extends Object>();
+  void method4c<T extends Object>();
+
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1>();
+  void method5c<T extends Class1>();
+}
+
+abstract class LegacyClass2 extends Class1 {
+  void method1a<T>();
+  void method1b<T extends Object>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object>();
+  void method3c<T extends dynamic>();
+
+  void method4a<T extends Object>();
+  void method4b<T extends Object>();
+  void method4c<T extends Object>();
+
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1>();
+  void method5c<T extends Class1>();
+}
+
+abstract class LegacyClass3 extends Class1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..1c32596
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.5
+import 'infer_constraints_from_opt_in_lib.dart';
+
+main() {}
+
+abstract class A {
+  baz(B b) {}
+}
diff --git a/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d34fee7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.5
+import 'infer_constraints_from_opt_in_lib.dart';
+
+abstract class A {
+  baz(B b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..b42d5fa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_in_lib.dart';
+
+reify<T>(T arg) => T;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0c543e4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_in_lib.dart';
+
+main() {}
+reify<T>(T arg) => T;
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..a8d0a04
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_out_lib.dart';
+
+reify<T>(T arg) => T;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3ba5457
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_out_lib.dart';
+
+main() {}
+reify<T>(T arg) => T;
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
new file mode 100644
index 0000000..bd0c406
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+T hest1<T>() => throw "hest";
+test1() { }
+class A2 {
+  String? foo;
+}
+test2(A2 a) { }
+test3() { }
+test4() { }
+class A5 {
+  void operator []=(int index, String? value) { }
+  String? operator [](int index) => null;
+}
+class B5 extends A5 {
+  test5() { }
+}
+extension E6 ;
+on double (){ }
+test6() { }
+class A7 {
+  String foo = "foo";
+  String? bar;
+}
+test7(A7? a) { }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline.expect
new file mode 100644
index 0000000..40f74b8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import './infer_in_legacy_from_opted_in_lib.dart';
+
+bar(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40f74b8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import './infer_in_legacy_from_opted_in_lib.dart';
+
+bar(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect
index 5f8c4b8..f0f39bc4 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect
@@ -40,7 +40,7 @@
 abstract class H extends core::Object implements self::D, self::E, self::F, self::C {
   synthetic constructor •() → self::H
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class I extends core::Object implements self::D {
   synthetic constructor •() → self::I
@@ -50,17 +50,17 @@
 abstract class J extends core::Object implements self::H {
   synthetic constructor •() → self::J
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 abstract class K extends core::Object implements self::I, self::E, self::G {
   synthetic constructor •() → self::K
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class L extends core::Object implements self::K {
   synthetic constructor •() → self::L
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect
@@ -48,7 +48,7 @@
   synthetic constructor •() → self::H
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class I extends core::Object implements self::D {
   synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
   synthetic constructor •() → self::J
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 abstract class K extends core::Object implements self::I, self::E, self::G {
   synthetic constructor •() → self::K
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class L extends core::Object implements self::K {
   synthetic constructor •() → self::L
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect
@@ -48,7 +48,7 @@
   synthetic constructor •() → self::H
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class I extends core::Object implements self::D {
   synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
   synthetic constructor •() → self::J
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 abstract class K extends core::Object implements self::I, self::E, self::G {
   synthetic constructor •() → self::K
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class L extends core::Object implements self::K {
   synthetic constructor •() → self::L
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline.expect
new file mode 100644
index 0000000..316cf4c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+abstract class A {
+  Object? m(covariant int a);
+}
+
+abstract class B {
+  dynamic m(covariant num a);
+}
+
+abstract class C {
+  void m(num a);
+}
+
+abstract class D implements A {
+  Object? m(int a);
+}
+
+abstract class E implements B {
+  dynamic m(num a);
+}
+
+abstract class F {
+  Object? m(int a);
+}
+
+abstract class G implements C {
+  m(a);
+}
+
+abstract class H implements D, E, F, C {}
+
+abstract class I implements D {
+  m(a);
+}
+
+abstract class J implements H {
+  m(a);
+}
+
+abstract class K implements I, E, G {}
+
+abstract class L implements K {
+  m(a);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..316cf4c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+abstract class A {
+  Object? m(covariant int a);
+}
+
+abstract class B {
+  dynamic m(covariant num a);
+}
+
+abstract class C {
+  void m(num a);
+}
+
+abstract class D implements A {
+  Object? m(int a);
+}
+
+abstract class E implements B {
+  dynamic m(num a);
+}
+
+abstract class F {
+  Object? m(int a);
+}
+
+abstract class G implements C {
+  m(a);
+}
+
+abstract class H implements D, E, F, C {}
+
+abstract class I implements D {
+  m(a);
+}
+
+abstract class J implements H {
+  m(a);
+}
+
+abstract class K implements I, E, G {}
+
+abstract class L implements K {
+  m(a);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect
@@ -48,7 +48,7 @@
   synthetic constructor •() → self::H
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class I extends core::Object implements self::D {
   synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
   synthetic constructor •() → self::J
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 abstract class K extends core::Object implements self::I, self::E, self::G {
   synthetic constructor •() → self::K
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class L extends core::Object implements self::K {
   synthetic constructor •() → self::L
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect
@@ -48,7 +48,7 @@
   synthetic constructor •() → self::H
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class I extends core::Object implements self::D {
   synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
   synthetic constructor •() → self::J
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 abstract class K extends core::Object implements self::I, self::E, self::G {
   synthetic constructor •() → self::K
     : super core::Object::•()
     ;
-  abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+  abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
 }
 abstract class L extends core::Object implements self::K {
   synthetic constructor •() → self::L
     : super core::Object::•()
     ;
-  abstract method m(covariant core::num a) → void;
+  abstract method m(covariant core::num a) → core::Object?;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..01cba4e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.5
+import 'inheritance_from_opt_in_lib.dart';
+class LegacyClass1 extends Class1 {
+}
+class LegacyClass2<T> extends Class2<T> {
+}
+class LegacyClass3a<T> extends Class3<T> {
+}
+class LegacyClass3b<T> extends Class3<T> implements GenericInterface<T> {
+}
+class LegacyClass4a extends Class4a {
+}
+class LegacyClass4b implements GenericInterface<num> {
+}
+class LegacyClass4c implements GenericInterface<num?> {
+}
+class LegacyClass4d extends Class4a implements GenericInterface<num> {
+}
+class LegacyClass4e implements Class4a, Class4b {
+}
+class LegacyClass5 extends Class5 implements GenericInterface<Object> {
+}
+class LegacyClass6a<T> extends Class3<T> implements GenericSubInterface<T> {
+}
+class LegacyClass6b<T> extends LegacyClass3a<T> implements GenericSubInterface<T> {
+}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e42e9ac
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.5
+import 'inheritance_from_opt_in_lib.dart';
+
+class LegacyClass1 extends Class1 {}
+
+class LegacyClass2<T> extends Class2<T> {}
+
+class LegacyClass3a<T> extends Class3<T> {}
+
+class LegacyClass3b<T> extends Class3<T> implements GenericInterface<T> {}
+
+class LegacyClass4a extends Class4a {}
+
+class LegacyClass4b implements GenericInterface<num> {}
+
+class LegacyClass4c implements GenericInterface<num?> {}
+
+class LegacyClass4d extends Class4a implements GenericInterface<num> {}
+
+class LegacyClass4e implements Class4a, Class4b {}
+
+class LegacyClass5 extends Class5 implements GenericInterface<Object> {}
+
+class LegacyClass6a<T> extends Class3<T> implements GenericSubInterface<T> {}
+
+class LegacyClass6b<T> extends LegacyClass3a<T>
+    implements GenericSubInterface<T> {}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..dfb4c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import 'inheritance_from_opt_out_lib.dart';
+
+class Class1 extends LegacyClass1 {}
+
+class Class2<T> extends LegacyClass2<T> {}
+
+class Class3a<T> extends LegacyClass3<T> {}
+
+class Class3b<T> extends LegacyClass3<T> implements GenericInterface<T> {}
+
+class Class4a extends LegacyClass4 {}
+
+class Class4b implements GenericInterface<num> {}
+
+class Class4c implements GenericInterface<num?> {}
+
+class Class4d extends LegacyClass4 implements GenericInterface<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dfb4c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import 'inheritance_from_opt_out_lib.dart';
+
+class Class1 extends LegacyClass1 {}
+
+class Class2<T> extends LegacyClass2<T> {}
+
+class Class3a<T> extends LegacyClass3<T> {}
+
+class Class3b<T> extends LegacyClass3<T> implements GenericInterface<T> {}
+
+class Class4a extends LegacyClass4 {}
+
+class Class4b implements GenericInterface<num> {}
+
+class Class4c implements GenericInterface<num?> {}
+
+class Class4d extends LegacyClass4 implements GenericInterface<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline.expect
new file mode 100644
index 0000000..ad879ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class Foo<T extends A?> {
+  doPromotionsToNullable(T t) {}
+  doPromotionsToNonNullable(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5a6a42a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class Foo<T extends A?> {
+  doPromotionsToNonNullable(T t) {}
+  doPromotionsToNullable(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline.expect
new file mode 100644
index 0000000..fa47f13
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo() {}
+String? bar() => "asdf";
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4df9bca
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+String? bar() => "asdf";
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline.expect
new file mode 100644
index 0000000..e73ad63
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo(Null x) {}
+bar(int y) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e94881
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+bar(int y) {}
+foo(Null x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect
index 83177be..d1038a3 100644
--- a/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect
@@ -14,14 +14,13 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method error() → dynamic {
   for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print(i);
   }
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    core::Iterator<core::int*> :sync-for-iterator = <core::int>[].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int i = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect
index 83177be..d1038a3 100644
--- a/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect
@@ -14,14 +14,13 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method error() → dynamic {
   for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print(i);
   }
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    core::Iterator<core::int*> :sync-for-iterator = <core::int>[].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int i = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline.expect
new file mode 100644
index 0000000..9297f99
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class GenericMethodBounds<T> {
+  Type get t => T;
+  GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
+  GenericMethodBounds<E> bar<E extends void Function(T)>() =>
+      new GenericMethodBounds<E>();
+}
+
+class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
+  GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
+  GenericMethodBounds<E> bar<E extends void Function(num)>() =>
+      new GenericMethodBounds<E>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f3cd4f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class GenericMethodBounds<T> {
+  GenericMethodBounds<E> bar<E extends void Function(T)>() =>
+      new GenericMethodBounds<E>();
+  GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
+  Type get t => T;
+}
+
+class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
+  GenericMethodBounds<E> bar<E extends void Function(num)>() =>
+      new GenericMethodBounds<E>();
+  GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline.expect
new file mode 100644
index 0000000..6d60882
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue40512_lib.dart';
+
+class C extends Object with A, B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d60882
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue40512_lib.dart';
+
+class C extends Object with A, B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline.expect
new file mode 100644
index 0000000..e698e05
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import 'dart:async';
+
+class B<Y> {
+  bar(FutureOr<Y> y) {}
+}
+
+class A<X> {
+  final b = new B<X>();
+  foo([FutureOr<X>? x]) {}
+}
+
+class C<T> {
+  FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+class D<T> extends C<T> {
+  FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..88df60c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+import 'dart:async';
+
+class A<X> {
+  final b = new B<X>();
+  foo([FutureOr<X>? x]) {}
+}
+
+class B<Y> {
+  bar(FutureOr<Y> y) {}
+}
+
+class C<T> {
+  FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+class D<T> extends C<T> {
+  FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+  T baz();
+  bar(T value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+  T baz();
+  bar(T value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40805.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40805.dart.textual_outline.expect
new file mode 100644
index 0000000..4c9d91e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40805.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+main() { }
+class C {
+  covariant late ;
+  final int x;
+}
+class D extends C {
+  set x(num value) { }
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart b/pkg/front_end/testcases/nnbd/issue41102.dart
index f10ab27..a237a56 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart
@@ -38,7 +38,7 @@
 
 final s10 = s7.length;
 
-final s11 = s5.length = 0;
+final s11 = s7.length = 0;
 
 final s12 = -s5;
 
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect
index ea7aadc..34eb654 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t;
+static final field asy::StreamTransformer<core::Object?, core::Object?> t;
 static final field core::List<dynamic> s1;
 static final field core::int? s2;
 static final field core::List<core::int> s3;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
index 7157bfd..3daaf3e 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
@@ -43,14 +43,10 @@
 // final s10 = s7.length;
 //                ^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-//                ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+//  - 'List' is from 'dart:core'.
 // Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
 //                ^^^^^^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -62,7 +58,7 @@
 // final s14 = (s13)();
 //                  ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 // final s15 = throw null;
 //                   ^
 //
@@ -72,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
@@ -111,13 +107,11 @@
 Try accessing using ?. instead.
 final s10 = s7.length;
                ^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
-final s11 = s5.length = 0;
-               ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
-               ^^^^^^";
+final s11 = s7.length = 0;
+               ^^^^^^" in self::s7.{core::List::length} = 0;
 static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 final s12 = -s5;
             ^" in self::s5.{core::int::unary-}();
@@ -126,7 +120,7 @@
 Try calling using ?.call instead.
 final s14 = (s13)();
                  ^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 final s15 = throw null;
                   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index d888b44..df8f463 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -43,14 +43,10 @@
 // final s10 = s7.length;
 //                ^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-//                ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+//  - 'List' is from 'dart:core'.
 // Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
 //                ^^^^^^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -62,7 +58,7 @@
 // final s14 = (s13)();
 //                  ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 // final s15 = throw null;
 //                   ^
 //
@@ -72,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
@@ -111,13 +107,11 @@
 Try accessing using ?. instead.
 final s10 = s7.length;
                ^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
-final s11 = s5.length = 0;
-               ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
-               ^^^^^^";
+final s11 = s7.length = 0;
+               ^^^^^^" in self::s7.{core::List::length} = 0;
 static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 final s12 = -s5;
             ^" in self::s5.{core::int::unary-}();
@@ -126,7 +120,7 @@
 Try calling using ?.call instead.
 final s14 = (s13)();
                  ^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 final s15 = throw null;
                   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
new file mode 100644
index 0000000..841a03e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+import 'dart:async';
+
+void main() {}
+final t = StreamTransformer.fromHandlers(
+    handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+    handleDone: (sink) => Future.microtask(() => sink.close()));
+final s1 = [];
+final s2 = s1?.length;
+final s3 = new List<int>(2);
+final s4 = () {
+  var e = 0;
+  switch (e) {
+    case 0:
+      print('fallthrough');
+    case 1:
+    case '':
+  }
+}();
+int? s5;
+final s6 = s5 + 0;
+List? s7;
+final s8 = s7[0];
+final s9 = s7[0] = 0;
+final s10 = s7.length;
+final s11 = s7.length = 0;
+final s12 = -s5;
+int Function()? s13;
+final s14 = (s13)();
+final s15 = throw null;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dee803a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
@@ -0,0 +1,29 @@
+import 'dart:async';
+
+List? s7;
+final s1 = [];
+final s10 = s7.length;
+final s11 = s7.length = 0;
+final s12 = -s5;
+final s14 = (s13)();
+final s15 = throw null;
+final s2 = s1?.length;
+final s3 = new List<int>(2);
+final s4 = () {
+  var e = 0;
+  switch (e) {
+    case 0:
+      print('fallthrough');
+    case 1:
+    case '':
+  }
+}();
+final s6 = s5 + 0;
+final s8 = s7[0];
+final s9 = s7[0] = 0;
+final t = StreamTransformer.fromHandlers(
+    handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+    handleDone: (sink) => Future.microtask(() => sink.close()));
+int Function()? s13;
+int? s5;
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
index 7157bfd..3daaf3e 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
@@ -43,14 +43,10 @@
 // final s10 = s7.length;
 //                ^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-//                ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+//  - 'List' is from 'dart:core'.
 // Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
 //                ^^^^^^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -62,7 +58,7 @@
 // final s14 = (s13)();
 //                  ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 // final s15 = throw null;
 //                   ^
 //
@@ -72,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
@@ -111,13 +107,11 @@
 Try accessing using ?. instead.
 final s10 = s7.length;
                ^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
-final s11 = s5.length = 0;
-               ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
-               ^^^^^^";
+final s11 = s7.length = 0;
+               ^^^^^^" in self::s7.{core::List::length} = 0;
 static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 final s12 = -s5;
             ^" in self::s5.{core::int::unary-}();
@@ -126,7 +120,7 @@
 Try calling using ?.call instead.
 final s14 = (s13)();
                  ^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 final s15 = throw null;
                   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index d888b44..df8f463 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -43,14 +43,10 @@
 // final s10 = s7.length;
 //                ^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-//                ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+//  - 'List' is from 'dart:core'.
 // Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
 //                ^^^^^^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -62,7 +58,7 @@
 // final s14 = (s13)();
 //                  ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 // final s15 = throw null;
 //                   ^
 //
@@ -72,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
@@ -111,13 +107,11 @@
 Try accessing using ?. instead.
 final s10 = s7.length;
                ^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
-final s11 = s5.length = 0;
-               ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
-               ^^^^^^";
+final s11 = s7.length = 0;
+               ^^^^^^" in self::s7.{core::List::length} = 0;
 static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 final s12 = -s5;
             ^" in self::s5.{core::int::unary-}();
@@ -126,7 +120,7 @@
 Try calling using ?.call instead.
 final s14 = (s13)();
                  ^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
 final s15 = throw null;
                   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect
index 49a4279..28aee32 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect
@@ -1,9 +1,10 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t;
+static final field asy::StreamTransformer<core::Object?, core::Object?> t;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline.expect
new file mode 100644
index 0000000..a80fd48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import 'dart:async';
+
+void main() {}
+final t = StreamTransformer.fromHandlers(
+    handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+    handleDone: (sink) => Future.microtask(() => sink.close()));
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55b3256
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import 'dart:async';
+
+final t = StreamTransformer.fromHandlers(
+    handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+    handleDone: (sink) => Future.microtask(() => sink.close()));
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart b/pkg/front_end/testcases/nnbd/issue41114.dart
new file mode 100644
index 0000000..7db889f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() async {
+  List<String>? a = <String>[];
+  Iterable<String>? b = a?.map((e) => e);
+  Iterable<String>? i = b ?? a;
+  print(i);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.outline.expect
new file mode 100644
index 0000000..e2cba6b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.outline.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect
new file mode 100644
index 0000000..0354e2d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic async {
+  core::List<core::String>? a = <core::String>[];
+  core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1.{core::List::==}(null) ?{core::Iterable<core::String*>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e);
+  core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2.{core::Object::==}(null) ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
+  core::print(i);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
new file mode 100644
index 0000000..22f3911
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::List<core::String>? a = <core::String>[];
+        core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1.{core::List::==}(null) ?{core::Iterable<core::String*>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e);
+        core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2.{core::Object::==}(null) ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
+        core::print(i);
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect
new file mode 100644
index 0000000..0354e2d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic async {
+  core::List<core::String>? a = <core::String>[];
+  core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1.{core::List::==}(null) ?{core::Iterable<core::String*>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e);
+  core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2.{core::Object::==}(null) ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
+  core::print(i);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
new file mode 100644
index 0000000..22f3911
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::List<core::String>? a = <core::String>[];
+        core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1.{core::List::==}(null) ?{core::Iterable<core::String*>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e);
+        core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2.{core::Object::==}(null) ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
+        core::print(i);
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
index b79d082..873c7eb 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
@@ -59,8 +59,8 @@
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -73,21 +73,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -99,21 +99,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -126,21 +126,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -153,21 +153,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -179,21 +179,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -206,13 +206,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
 }
@@ -220,8 +220,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -272,8 +272,8 @@
           final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
           asy::FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -293,21 +293,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
           final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
           asy::FutureOr<Never>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -328,21 +328,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* originally async */ {
           final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
           asy::FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -362,21 +362,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
           final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
           asy::FutureOr<Never>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -397,25 +397,25 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline.expect
new file mode 100644
index 0000000..2dcb814
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Never throwing() => throw '';
+void main() {}
+void errors() async {}
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bacddb3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Never throwing() => throw '';
+void errors() async {}
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
index b79d082..873c7eb 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
@@ -59,8 +59,8 @@
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -73,21 +73,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -99,21 +99,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -126,21 +126,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -153,21 +153,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -179,21 +179,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
   (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
     final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
     asy::FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -206,13 +206,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   };
 }
@@ -220,8 +220,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -272,8 +272,8 @@
           final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
           asy::FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -293,21 +293,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
           final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
           asy::FutureOr<Never>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -328,21 +328,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* originally async */ {
           final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
           asy::FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -362,21 +362,21 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
         (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
           final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
           asy::FutureOr<Never>? :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -397,25 +397,25 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         };
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline.expect
new file mode 100644
index 0000000..51c776d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.5
+import 'issue41180_lib.dart';
+
+class D<Y> {
+  C<Y> method() => new C<Y>(() => null);
+}
+
+void main() {}
+void findKey(Map<String, dynamic> m, dynamic search) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66718e1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.5
+import 'issue41180_lib.dart';
+
+class D<Y> {
+  C<Y> method() => new C<Y>(() => null);
+}
+
+void findKey(Map<String, dynamic> m, dynamic search) {}
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline.expect
new file mode 100644
index 0000000..8cdec02
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cdec02
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210a/issue41210_lib1.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41210a/issue41210_lib1.dart.strong.transformed.expect
new file mode 100644
index 0000000..a170b13
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210a/issue41210_lib1.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "issue41210_lib1.dart" as iss;
+
+import "org-dartlang-testcase:///issue41210_lib1.dart";
+
+abstract class _C&Object&A extends core::Object implements iss::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A*
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///issue41210_lib1.dart */ method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class _C&Object&A&B extends self::_C&Object&A implements iss::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A&B*
+    : super self::_C&Object&A::•()
+    ;
+  abstract forwarding-stub method method({core::String* s = #C1}) → core::String*;
+}
+class C extends self::_C&Object&A&B {
+  synthetic constructor •() → self::C*
+    : super self::_C&Object&A&B::•()
+    ;
+  abstract forwarding-stub method method({core::String* s = #C1}) → core::String*;
+}
+static method main() → dynamic {
+  core::print(new self::C::•().{self::C::method}());
+}
+
+library;
+import self as iss;
+import "dart:core" as core;
+import "issue41210_lib2.dart" as iss2;
+
+import "org-dartlang-testcase:///issue41210_lib2.dart";
+
+abstract class A extends core::Object implements iss2::Interface /*isMixinDeclaration*/  {
+  method method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class B extends core::Object implements iss2::Interface {
+  synthetic constructor •() → iss::B*
+    : super core::Object::•()
+    ;
+  abstract member-signature method method() → core::String*;
+}
+static method main() → void {}
+
+library /*isNonNullableByDefault*/;
+import self as iss2;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+  synthetic constructor •() → iss2::Interface
+    : super core::Object::•()
+    ;
+  abstract method method() → core::String;
+}
+
+constants  {
+  #C1 = "hello"
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41210a/issue41210_lib1.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41210a/issue41210_lib1.dart.weak.transformed.expect
new file mode 100644
index 0000000..a170b13
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210a/issue41210_lib1.dart.weak.transformed.expect
@@ -0,0 +1,63 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "issue41210_lib1.dart" as iss;
+
+import "org-dartlang-testcase:///issue41210_lib1.dart";
+
+abstract class _C&Object&A extends core::Object implements iss::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A*
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///issue41210_lib1.dart */ method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class _C&Object&A&B extends self::_C&Object&A implements iss::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A&B*
+    : super self::_C&Object&A::•()
+    ;
+  abstract forwarding-stub method method({core::String* s = #C1}) → core::String*;
+}
+class C extends self::_C&Object&A&B {
+  synthetic constructor •() → self::C*
+    : super self::_C&Object&A&B::•()
+    ;
+  abstract forwarding-stub method method({core::String* s = #C1}) → core::String*;
+}
+static method main() → dynamic {
+  core::print(new self::C::•().{self::C::method}());
+}
+
+library;
+import self as iss;
+import "dart:core" as core;
+import "issue41210_lib2.dart" as iss2;
+
+import "org-dartlang-testcase:///issue41210_lib2.dart";
+
+abstract class A extends core::Object implements iss2::Interface /*isMixinDeclaration*/  {
+  method method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class B extends core::Object implements iss2::Interface {
+  synthetic constructor •() → iss::B*
+    : super core::Object::•()
+    ;
+  abstract member-signature method method() → core::String*;
+}
+static method main() → void {}
+
+library /*isNonNullableByDefault*/;
+import self as iss2;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+  synthetic constructor •() → iss2::Interface
+    : super core::Object::•()
+    ;
+  abstract method method() → core::String;
+}
+
+constants  {
+  #C1 = "hello"
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41210b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41210b.dart.strong.transformed.expect
new file mode 100644
index 0000000..8f2efe4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210b.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "issue41210b_lib1.dart" as iss;
+
+import "org-dartlang-testcase:///issue41210b_lib1.dart";
+
+abstract class _C&Object&A extends core::Object implements iss::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A*
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///issue41210b_lib1.dart */ method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class _C&Object&A&B extends self::_C&Object&A implements iss::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A&B*
+    : super self::_C&Object&A::•()
+    ;
+  abstract member-signature method /* from org-dartlang-testcase:///issue41210b_lib1.dart */ method() → core::String*;
+}
+class C extends self::_C&Object&A&B {
+  synthetic constructor •() → self::C*
+    : super self::_C&Object&A&B::•()
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::C::•().{iss::A::method}());
+}
+
+library;
+import self as iss;
+import "dart:core" as core;
+import "issue41210b_lib2.dart" as iss2;
+
+import "org-dartlang-testcase:///issue41210b_lib2.dart";
+
+abstract class A extends core::Object implements iss2::Interface /*isMixinDeclaration*/  {
+  method method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class B extends core::Object implements iss2::Interface {
+  synthetic constructor •() → iss::B*
+    : super core::Object::•()
+    ;
+  abstract member-signature method method() → core::String*;
+}
+static method main() → void {}
+
+library /*isNonNullableByDefault*/;
+import self as iss2;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+  synthetic constructor •() → iss2::Interface
+    : super core::Object::•()
+    ;
+  abstract method method() → core::String;
+}
+
+constants  {
+  #C1 = "hello"
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline.expect
new file mode 100644
index 0000000..083c54f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210b_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..083c54f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210b_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41210b.dart.weak.transformed.expect
new file mode 100644
index 0000000..8f2efe4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210b.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "issue41210b_lib1.dart" as iss;
+
+import "org-dartlang-testcase:///issue41210b_lib1.dart";
+
+abstract class _C&Object&A extends core::Object implements iss::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A*
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///issue41210b_lib1.dart */ method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class _C&Object&A&B extends self::_C&Object&A implements iss::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C&Object&A&B*
+    : super self::_C&Object&A::•()
+    ;
+  abstract member-signature method /* from org-dartlang-testcase:///issue41210b_lib1.dart */ method() → core::String*;
+}
+class C extends self::_C&Object&A&B {
+  synthetic constructor •() → self::C*
+    : super self::_C&Object&A&B::•()
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::C::•().{iss::A::method}());
+}
+
+library;
+import self as iss;
+import "dart:core" as core;
+import "issue41210b_lib2.dart" as iss2;
+
+import "org-dartlang-testcase:///issue41210b_lib2.dart";
+
+abstract class A extends core::Object implements iss2::Interface /*isMixinDeclaration*/  {
+  method method({core::String* s = #C1}) → core::String*
+    return s;
+}
+abstract class B extends core::Object implements iss2::Interface {
+  synthetic constructor •() → iss::B*
+    : super core::Object::•()
+    ;
+  abstract member-signature method method() → core::String*;
+}
+static method main() → void {}
+
+library /*isNonNullableByDefault*/;
+import self as iss2;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+  synthetic constructor •() → iss2::Interface
+    : super core::Object::•()
+    ;
+  abstract method method() → core::String;
+}
+
+constants  {
+  #C1 = "hello"
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart b/pkg/front_end/testcases/nnbd/issue41273.dart
new file mode 100644
index 0000000..f490918
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void test(var x) {
+  if (x is Never) {
+    Never n1 = x.toString();
+    Never n2 = x.runtimeType;
+    Never n3 = x.someGetter;
+    Never n4 = x.someMethod();
+    Never n5 = x + x;
+    Never n6 = x[x];
+    Never n7 = x();
+    Never n8 = x.runtimeType();
+    Never n9 = x.toString;
+    x.runtimeType = Object;
+    x.toString = () => '';
+    var v1 = x.toString();
+    var v2 = x.runtimeType;
+    var v3 = x.someGetter;
+    var v4 = x.someMethod();
+    var v5 = x + x;
+    var v6 = x[x];
+    var v7 = x();
+    var v8 = x.runtimeType();
+    var v9 = x.toString;
+  }
+}
+
+main() {
+  test(null);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.outline.expect
new file mode 100644
index 0000000..a79e819
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method test(dynamic x) → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.strong.expect
new file mode 100644
index 0000000..eff260bc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.strong.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(dynamic x) → void {
+  if(x is{ForNonNullableByDefault} Never) {
+    Never n1 = x{Never}.toString();
+    Never n2 = x{Never}.runtimeType;
+    Never n3 = x{Never}.someGetter;
+    Never n4 = x{Never}.someMethod();
+    Never n5 = x{Never}.+(x{Never});
+    Never n6 = x{Never}.[](x{Never});
+    Never n7 = x{Never}.call();
+    Never n8 = x{Never}.runtimeType();
+    Never n9 = x{Never}.toString;
+    x{Never}.runtimeType = core::Object;
+    x{Never}.toString = () → core::String => "";
+    Never v1 = x{Never}.toString();
+    Never v2 = x{Never}.runtimeType;
+    Never v3 = x{Never}.someGetter;
+    Never v4 = x{Never}.someMethod();
+    Never v5 = x{Never}.+(x{Never});
+    Never v6 = x{Never}.[](x{Never});
+    Never v7 = x{Never}.call();
+    Never v8 = x{Never}.runtimeType();
+    Never v9 = x{Never}.toString;
+  }
+}
+static method main() → dynamic {
+  self::test(null);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.strong.transformed.expect
new file mode 100644
index 0000000..eff260bc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(dynamic x) → void {
+  if(x is{ForNonNullableByDefault} Never) {
+    Never n1 = x{Never}.toString();
+    Never n2 = x{Never}.runtimeType;
+    Never n3 = x{Never}.someGetter;
+    Never n4 = x{Never}.someMethod();
+    Never n5 = x{Never}.+(x{Never});
+    Never n6 = x{Never}.[](x{Never});
+    Never n7 = x{Never}.call();
+    Never n8 = x{Never}.runtimeType();
+    Never n9 = x{Never}.toString;
+    x{Never}.runtimeType = core::Object;
+    x{Never}.toString = () → core::String => "";
+    Never v1 = x{Never}.toString();
+    Never v2 = x{Never}.runtimeType;
+    Never v3 = x{Never}.someGetter;
+    Never v4 = x{Never}.someMethod();
+    Never v5 = x{Never}.+(x{Never});
+    Never v6 = x{Never}.[](x{Never});
+    Never v7 = x{Never}.call();
+    Never v8 = x{Never}.runtimeType();
+    Never v9 = x{Never}.toString;
+  }
+}
+static method main() → dynamic {
+  self::test(null);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline.expect
new file mode 100644
index 0000000..6592fa9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void test(var x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59b6cb1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void test(var x) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect
new file mode 100644
index 0000000..eff260bc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(dynamic x) → void {
+  if(x is{ForNonNullableByDefault} Never) {
+    Never n1 = x{Never}.toString();
+    Never n2 = x{Never}.runtimeType;
+    Never n3 = x{Never}.someGetter;
+    Never n4 = x{Never}.someMethod();
+    Never n5 = x{Never}.+(x{Never});
+    Never n6 = x{Never}.[](x{Never});
+    Never n7 = x{Never}.call();
+    Never n8 = x{Never}.runtimeType();
+    Never n9 = x{Never}.toString;
+    x{Never}.runtimeType = core::Object;
+    x{Never}.toString = () → core::String => "";
+    Never v1 = x{Never}.toString();
+    Never v2 = x{Never}.runtimeType;
+    Never v3 = x{Never}.someGetter;
+    Never v4 = x{Never}.someMethod();
+    Never v5 = x{Never}.+(x{Never});
+    Never v6 = x{Never}.[](x{Never});
+    Never v7 = x{Never}.call();
+    Never v8 = x{Never}.runtimeType();
+    Never v9 = x{Never}.toString;
+  }
+}
+static method main() → dynamic {
+  self::test(null);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect
new file mode 100644
index 0000000..eff260bc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(dynamic x) → void {
+  if(x is{ForNonNullableByDefault} Never) {
+    Never n1 = x{Never}.toString();
+    Never n2 = x{Never}.runtimeType;
+    Never n3 = x{Never}.someGetter;
+    Never n4 = x{Never}.someMethod();
+    Never n5 = x{Never}.+(x{Never});
+    Never n6 = x{Never}.[](x{Never});
+    Never n7 = x{Never}.call();
+    Never n8 = x{Never}.runtimeType();
+    Never n9 = x{Never}.toString;
+    x{Never}.runtimeType = core::Object;
+    x{Never}.toString = () → core::String => "";
+    Never v1 = x{Never}.toString();
+    Never v2 = x{Never}.runtimeType;
+    Never v3 = x{Never}.someGetter;
+    Never v4 = x{Never}.someMethod();
+    Never v5 = x{Never}.+(x{Never});
+    Never v6 = x{Never}.[](x{Never});
+    Never v7 = x{Never}.call();
+    Never v8 = x{Never}.runtimeType();
+    Never v9 = x{Never}.toString;
+  }
+}
+static method main() → dynamic {
+  self::test(null);
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart b/pkg/front_end/testcases/nnbd/issue41349.dart
new file mode 100644
index 0000000..0ded2f1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  foo() => 23;
+}
+
+extension B on A? {
+  foo() => 42;
+  bar() => 87;
+}
+
+extension C on A {
+  bar() => 123;
+}
+
+extension D on int Function()? {
+  int call() => 76;
+}
+
+main() {
+  testA(new A());
+  testFunction(() => 53);
+}
+
+testA(A? a) {
+  expect(23, a?.foo()); // A.foo instead of B.foo.
+  expect(42, a.foo()); // B.foo instead of nullable access to A.foo.
+  expect(123, a?.bar()); // C.bar instead of B.bar.
+  expect(87, a.bar()); // B.bar instead of nullable access to C.bar.
+}
+
+testFunction(int Function()? f) {
+  expect(53, f?.call()); // Function.call instead of D.call.
+  expect(76, f.call()); // D.call instead of nullable access to Function.call.
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
new file mode 100644
index 0000000..15071a6e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method foo() → dynamic
+    ;
+}
+extension B on self::A? {
+  method foo = self::B|foo;
+  tearoff foo = self::B|get#foo;
+  method bar = self::B|bar;
+  tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+  method bar = self::C|bar;
+  tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+  method call = self::D|call;
+  tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+  ;
+static method B|get#foo(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+  ;
+static method B|get#bar(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+  ;
+static method C|get#bar(final self::A #this) → () → dynamic
+  return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+  ;
+static method D|get#call(final () →? core::int #this) → () → core::int
+  return () → core::int => self::D|call(#this);
+static method main() → dynamic
+  ;
+static method testA(self::A? a) → dynamic
+  ;
+static method testFunction(() →? core::int f) → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 23;
+}
+extension B on self::A? {
+  method foo = self::B|foo;
+  tearoff foo = self::B|get#foo;
+  method bar = self::B|bar;
+  tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+  method bar = self::C|bar;
+  tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+  method call = self::D|call;
+  tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+  return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+  return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+  return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+  return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+  return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+  return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+  self::testA(new self::A::•());
+  self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+  self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+  self::expect(42, self::B|foo(a));
+  self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+  self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+  self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+  self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 23;
+}
+extension B on self::A? {
+  method foo = self::B|foo;
+  tearoff foo = self::B|get#foo;
+  method bar = self::B|bar;
+  tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+  method bar = self::C|bar;
+  tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+  method call = self::D|call;
+  tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+  return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+  return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+  return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+  return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+  return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+  return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+  self::testA(new self::A::•());
+  self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+  self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+  self::expect(42, self::B|foo(a));
+  self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+  self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+  self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+  self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
new file mode 100644
index 0000000..ada5148
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+  foo() => 23;
+}
+extension B ;
+on A;
+? { foo() => 42; bar() => 87; }
+extension C ;
+on A (){ }
+extension D ;
+on int ;
+Function(){ }
+? { int call() => 76; }
+main() { }
+testA(A? a) { }
+testFunction(int Function()? f) { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 23;
+}
+extension B on self::A? {
+  method foo = self::B|foo;
+  tearoff foo = self::B|get#foo;
+  method bar = self::B|bar;
+  tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+  method bar = self::C|bar;
+  tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+  method call = self::D|call;
+  tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+  return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+  return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+  return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+  return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+  return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+  return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+  self::testA(new self::A::•());
+  self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+  self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+  self::expect(42, self::B|foo(a));
+  self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+  self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+  self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+  self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 23;
+}
+extension B on self::A? {
+  method foo = self::B|foo;
+  tearoff foo = self::B|get#foo;
+  method bar = self::B|bar;
+  tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+  method bar = self::C|bar;
+  tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+  method call = self::D|call;
+  tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+  return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+  return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+  return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+  return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+  return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+  return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+  return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+  self::testA(new self::A::•());
+  self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+  self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+  self::expect(42, self::B|foo(a));
+  self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+  self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+  self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+  self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart b/pkg/front_end/testcases/nnbd/issue41386.dart
new file mode 100644
index 0000000..8f7d938
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool Function(T) predicate<T>(bool Function(T) fn) => (T val) => fn(val);
+
+void test() {
+  print(predicate((v) => v % 2 == 1)(3));
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.outline.expect
new file mode 100644
index 0000000..16f60b9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.outline.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  ;
+static method test() → void
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.transformed.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.transformed.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart b/pkg/front_end/testcases/nnbd/issue41386b.dart
new file mode 100644
index 0000000..bdab2fd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void test() {
+  var map = {};
+  map[0].foo;
+  Iterable<String> elements = <String>[];
+  var list = new List.from(elements);
+  new List.from(elements).forEach((element) => element.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.outline.expect
new file mode 100644
index 0000000..d7d3d2f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method test() → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.transformed.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.transformed.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart b/pkg/front_end/testcases/nnbd/issue41415.dart
new file mode 100644
index 0000000..1b33195
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart
@@ -0,0 +1,15 @@
+// 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.
+
+main() {
+  // Pre-NNBD bottom type.
+  int Function(Null) f = (x) => 1; // Runtime type is int Function(Object?)
+  // NNBD bottom type.
+  int Function(Never) g = (x) => 1; // Runtime type is int Function(Object?)
+  // NNBD bottom type.
+
+  int Function(Never?) h = (x) => 1; // Runtime type is int Function(Object?)
+
+  int Function(String) i = (x) => 1; // Runtime type is int Function(String)
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
new file mode 100644
index 0000000..e2cba6b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
new file mode 100644
index 0000000..4c844e6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+  (Never) → core::int g = (core::Object? x) → core::int => 1;
+  (Never?) → core::int h = (core::Object? x) → core::int => 1;
+  (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
new file mode 100644
index 0000000..4c844e6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+  (Never) → core::int g = (core::Object? x) → core::int => 1;
+  (Never?) → core::int h = (core::Object? x) → core::int => 1;
+  (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline.expect
new file mode 100644
index 0000000..d2c1f3b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import "package:expect/expect.dart";
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2c1f3b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import "package:expect/expect.dart";
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
new file mode 100644
index 0000000..4c844e6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+  (Never) → core::int g = (core::Object? x) → core::int => 1;
+  (Never?) → core::int h = (core::Object? x) → core::int => 1;
+  (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
new file mode 100644
index 0000000..4c844e6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+  (Never) → core::int g = (core::Object? x) → core::int => 1;
+  (Never?) → core::int h = (core::Object? x) → core::int => 1;
+  (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart b/pkg/front_end/testcases/nnbd/issue41437a.dart
new file mode 100644
index 0000000..778cd69
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dynamic getNull() => null;
+Future<dynamic> getFutureNull() async {
+  return null;
+}
+
+Future<bool> getFutureBool() async {
+  return true;
+}
+
+Future<bool> test1() async => await getNull(); // error
+Future<bool> test2() => getNull(); // ok
+bool test3() => getNull(); // ok
+Future<bool> test4() async => await getFutureNull(); // error
+Future<bool> test5() => getFutureNull(); // error
+Future<bool> test6() => getFutureBool(); // ok
+Future<bool> test7() async => getFutureBool(); // ok
+
+test() async {
+  Future<bool> test1() async => await getNull(); // error
+  Future<bool> test2() => getNull(); // ok
+  bool test3() => getNull(); // ok
+  Future<bool> test4() async => await getFutureNull(); // error
+  Future<bool> test5() => getFutureNull(); // error
+  Future<bool> test6() => getFutureBool(); // ok
+  Future<bool> test7() async => getFutureBool(); // ok
+
+  Future<bool> var1 = (() async => await getNull())(); // error
+  Future<bool> var2 = (() => getNull())(); // ok
+  bool var3 = (() => getNull())(); // ok
+  Future<bool> var4 = (() async => await getFutureNull())(); // error
+  Future<bool> var5 = (() => getFutureNull())(); // error
+  Future<bool> var6 = (() => getFutureBool())(); // ok
+  Future<bool> var7 = (() async => getFutureBool())(); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.outline.expect
new file mode 100644
index 0000000..7e28ffc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  ;
+static method getFutureNull() → asy::Future<dynamic>
+  ;
+static method getFutureBool() → asy::Future<core::bool>
+  ;
+static method test1() → asy::Future<core::bool>
+  ;
+static method test2() → asy::Future<core::bool>
+  ;
+static method test3() → core::bool
+  ;
+static method test4() → asy::Future<core::bool>
+  ;
+static method test5() → asy::Future<core::bool>
+  ;
+static method test6() → asy::Future<core::bool>
+  ;
+static method test7() → asy::Future<core::bool>
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
new file mode 100644
index 0000000..9f84dd0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
@@ -0,0 +1,134 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test1() async => await getNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test4() async => await getFutureNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> test5() => getFutureNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var1 = (() async => await getNull())(); // error
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var4 = (() async => await getFutureNull())(); // error
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var5 = (() => getFutureNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getFutureNull() → asy::Future<dynamic> async {
+  return null;
+}
+static method getFutureBool() → asy::Future<core::bool> async {
+  return true;
+}
+static method test1() → asy::Future<core::bool> async 
+  return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+                              ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test2() → asy::Future<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> async 
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+                              ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test5() → asy::Future<core::bool>
+  return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+                        ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+  return self::getFutureBool();
+static method test7() → asy::Future<core::bool> async 
+  return self::getFutureBool();
+static method test() → dynamic async {
+  function test1() → asy::Future<core::bool> async 
+    return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test1() async => await getNull(); // error
+                                ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+  function test2() → asy::Future<core::bool>
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+  function test3() → core::bool
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  function test4() → asy::Future<core::bool> async 
+    return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test4() async => await getFutureNull(); // error
+                                ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+  function test5() → asy::Future<core::bool>
+    return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> test5() => getFutureNull(); // error
+                          ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  function test6() → asy::Future<core::bool>
+    return self::getFutureBool();
+  function test7() → asy::Future<core::bool> async 
+    return self::getFutureBool();
+  asy::Future<core::bool> var1 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var1 = (() async => await getNull())(); // error
+                                                   ^" in (() → asy::Future<dynamic> async => await self::getNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+  core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  asy::Future<core::bool> var4 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var4 = (() async => await getFutureNull())(); // error
+                                                         ^" in (() → asy::Future<dynamic> async => await self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  asy::Future<core::bool> var5 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var5 = (() => getFutureNull())(); // error
+                                             ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool()).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
new file mode 100644
index 0000000..2e9e775
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
@@ -0,0 +1,449 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test1() async => await getNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test4() async => await getFutureNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> test5() => getFutureNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var1 = (() async => await getNull())(); // error
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var4 = (() async => await getFutureNull())(); // error
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var5 = (() => getFutureNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = null;
+        break #L1;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = true;
+        break #L2;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test1() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+                              ^";
+        [yield] let dynamic #t2 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+        :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+        break #L3;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test2() → asy::Future<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L4:
+      {
+        final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+                              ^";
+        [yield] let dynamic #t4 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+        :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+        break #L4;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test5() → asy::Future<core::bool>
+  return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+                        ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+  return self::getFutureBool();
+static method test7() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L5:
+      {
+        :return_value = self::getFutureBool();
+        break #L5;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L6:
+      {
+        function test1() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L7:
+              {
+                final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test1() async => await getNull(); // error
+                                ^";
+                [yield] let dynamic #t7 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+                break #L7;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        function test2() → asy::Future<core::bool>
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+        function test3() → core::bool
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        function test4() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L8:
+              {
+                final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test4() async => await getFutureNull(); // error
+                                ^";
+                [yield] let dynamic #t9 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+                break #L8;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        function test5() → asy::Future<core::bool>
+          return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> test5() => getFutureNull(); // error
+                          ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        function test6() → asy::Future<core::bool>
+          return self::getFutureBool();
+        function test7() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L9:
+              {
+                :return_value = self::getFutureBool();
+                break #L9;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        asy::Future<core::bool> var1 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var1 = (() async => await getNull())(); // error
+                                                   ^" in (() → asy::Future<dynamic> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          asy::FutureOr<dynamic>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L10:
+              {
+                [yield] let dynamic #t12 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result;
+                break #L10;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+        core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        asy::Future<core::bool> var4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var4 = (() async => await getFutureNull())(); // error
+                                                         ^" in (() → asy::Future<dynamic> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          asy::FutureOr<dynamic>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L11:
+              {
+                [yield] let dynamic #t14 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result;
+                break #L11;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        asy::Future<core::bool> var5 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var5 = (() => getFutureNull())(); // error
+                                             ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+        asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L12:
+              {
+                :return_value = self::getFutureBool();
+                break #L12;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }).call();
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
new file mode 100644
index 0000000..9f84dd0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
@@ -0,0 +1,134 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test1() async => await getNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test4() async => await getFutureNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> test5() => getFutureNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var1 = (() async => await getNull())(); // error
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var4 = (() async => await getFutureNull())(); // error
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var5 = (() => getFutureNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getFutureNull() → asy::Future<dynamic> async {
+  return null;
+}
+static method getFutureBool() → asy::Future<core::bool> async {
+  return true;
+}
+static method test1() → asy::Future<core::bool> async 
+  return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+                              ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test2() → asy::Future<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> async 
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+                              ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test5() → asy::Future<core::bool>
+  return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+                        ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+  return self::getFutureBool();
+static method test7() → asy::Future<core::bool> async 
+  return self::getFutureBool();
+static method test() → dynamic async {
+  function test1() → asy::Future<core::bool> async 
+    return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test1() async => await getNull(); // error
+                                ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+  function test2() → asy::Future<core::bool>
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+  function test3() → core::bool
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  function test4() → asy::Future<core::bool> async 
+    return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test4() async => await getFutureNull(); // error
+                                ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+  function test5() → asy::Future<core::bool>
+    return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> test5() => getFutureNull(); // error
+                          ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  function test6() → asy::Future<core::bool>
+    return self::getFutureBool();
+  function test7() → asy::Future<core::bool> async 
+    return self::getFutureBool();
+  asy::Future<core::bool> var1 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var1 = (() async => await getNull())(); // error
+                                                   ^" in (() → asy::Future<dynamic> async => await self::getNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+  core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  asy::Future<core::bool> var4 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var4 = (() async => await getFutureNull())(); // error
+                                                         ^" in (() → asy::Future<dynamic> async => await self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  asy::Future<core::bool> var5 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var5 = (() => getFutureNull())(); // error
+                                             ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+  asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool()).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
new file mode 100644
index 0000000..2e9e775
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
@@ -0,0 +1,449 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test1() async => await getNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+//  - 'Future' is from 'dart:async'.
+//  - 'FutureOr' is from 'dart:async'.
+//   Future<bool> test4() async => await getFutureNull(); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> test5() => getFutureNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var1 = (() async => await getNull())(); // error
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var4 = (() async => await getFutureNull())(); // error
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+//  - 'Future' is from 'dart:async'.
+//   Future<bool> var5 = (() => getFutureNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = null;
+        break #L1;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = true;
+        break #L2;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test1() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+                              ^";
+        [yield] let dynamic #t2 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+        :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+        break #L3;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test2() → asy::Future<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L4:
+      {
+        final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+                              ^";
+        [yield] let dynamic #t4 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+        :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+        break #L4;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test5() → asy::Future<core::bool>
+  return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+                        ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+  return self::getFutureBool();
+static method test7() → asy::Future<core::bool> /* originally async */ {
+  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  asy::FutureOr<core::bool>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L5:
+      {
+        :return_value = self::getFutureBool();
+        break #L5;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method test() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L6:
+      {
+        function test1() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L7:
+              {
+                final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test1() async => await getNull(); // error
+                                ^";
+                [yield] let dynamic #t7 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+                break #L7;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        function test2() → asy::Future<core::bool>
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+        function test3() → core::bool
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        function test4() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L8:
+              {
+                final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+  Future<bool> test4() async => await getFutureNull(); // error
+                                ^";
+                [yield] let dynamic #t9 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+                break #L8;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        function test5() → asy::Future<core::bool>
+          return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> test5() => getFutureNull(); // error
+                          ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        function test6() → asy::Future<core::bool>
+          return self::getFutureBool();
+        function test7() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L9:
+              {
+                :return_value = self::getFutureBool();
+                break #L9;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        asy::Future<core::bool> var1 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var1 = (() async => await getNull())(); // error
+                                                   ^" in (() → asy::Future<dynamic> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          asy::FutureOr<dynamic>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L10:
+              {
+                [yield] let dynamic #t12 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result;
+                break #L10;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+        core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        asy::Future<core::bool> var4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var4 = (() async => await getFutureNull())(); // error
+                                                         ^" in (() → asy::Future<dynamic> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          asy::FutureOr<dynamic>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L11:
+              {
+                [yield] let dynamic #t14 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+                :return_value = :result;
+                break #L11;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        asy::Future<core::bool> var5 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+  Future<bool> var5 = (() => getFutureNull())(); // error
+                                             ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+        asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+        asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
+          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          asy::FutureOr<core::bool>? :return_value;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L12:
+              {
+                :return_value = self::getFutureBool();
+                break #L12;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }).call();
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart b/pkg/front_end/testcases/nnbd/issue41437b.dart
new file mode 100644
index 0000000..6a03c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dynamic getNull() => null;
+Iterable<dynamic> getIterableNull() sync* {
+  yield null;
+}
+
+Iterable<bool> getIterableBool() sync* {
+  yield true;
+}
+
+Iterable<bool> test1() sync* {
+  yield getNull(); // ok
+}
+
+Iterable<bool> test2() => getNull(); // ok
+bool test3() => getNull(); // ok
+Iterable<bool> test4() sync* {
+  yield* getIterableNull(); // error
+}
+
+Iterable<bool> test5() => getIterableNull(); // error
+Iterable<bool> test6() => getIterableBool(); // ok
+Iterable<bool> test7() sync* {
+  yield* getIterableBool(); // ok
+}
+
+test() async {
+  Iterable<bool> test1() sync* {
+    yield getNull(); // ok
+  }
+
+  Iterable<bool> test2() => getNull(); // ok
+  bool test3() => getNull(); // ok
+  Iterable<bool> test4() sync* {
+    yield* getIterableNull(); // error
+  }
+
+  Iterable<bool> test5() => getIterableNull(); // error
+  Iterable<bool> test6() => getIterableBool(); // ok
+  Iterable<bool> test7() sync* {
+    yield* getIterableBool(); // ok
+  }
+
+  Iterable<bool> var1 = (() sync* {
+    yield getNull();
+  })(); // error
+  Iterable<bool> var2 = (() => getNull())(); // ok
+  bool var3 = (() => getNull())(); // ok
+  Iterable<bool> var4 = (() sync* {
+    yield* getIterableNull();
+  })(); // error
+  Iterable<bool> var5 = (() => getIterableNull())(); // error
+  Iterable<bool> var6 = (() => getIterableBool())(); // ok
+  Iterable<bool> var7 = (() sync* {
+    yield* getIterableBool();
+  })(); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.outline.expect
new file mode 100644
index 0000000..ab30e91
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  ;
+static method getIterableNull() → core::Iterable<dynamic>
+  ;
+static method getIterableBool() → core::Iterable<core::bool>
+  ;
+static method test1() → core::Iterable<core::bool>
+  ;
+static method test2() → core::Iterable<core::bool>
+  ;
+static method test3() → core::bool
+  ;
+static method test4() → core::Iterable<core::bool>
+  ;
+static method test5() → core::Iterable<core::bool>
+  ;
+static method test6() → core::Iterable<core::bool>
+  ;
+static method test7() → core::Iterable<core::bool>
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
new file mode 100644
index 0000000..3c4069e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
@@ -0,0 +1,121 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   yield* getIterableNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//     yield* getIterableNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> test5() => getIterableNull(); // error
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> var5 = (() => getIterableNull())(); // error
+//                                                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getIterableNull() → core::Iterable<dynamic> sync* {
+  yield null;
+}
+static method getIterableBool() → core::Iterable<core::bool> sync* {
+  yield true;
+}
+static method test1() → core::Iterable<core::bool> sync* {
+  yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → core::Iterable<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> sync* {
+  yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  yield* getIterableNull(); // error
+         ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+}
+static method test5() → core::Iterable<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+                          ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+  return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> sync* {
+  yield* self::getIterableBool();
+}
+static method test() → dynamic async {
+  function test1() → core::Iterable<core::bool> sync* {
+    yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  }
+  function test2() → core::Iterable<core::bool>
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+  function test3() → core::bool
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  function test4() → core::Iterable<core::bool> sync* {
+    yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+    yield* getIterableNull(); // error
+           ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  }
+  function test5() → core::Iterable<core::bool>
+    return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> test5() => getIterableNull(); // error
+                            ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  function test6() → core::Iterable<core::bool>
+    return self::getIterableBool();
+  function test7() → core::Iterable<core::bool> sync* {
+    yield* self::getIterableBool();
+  }
+  core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> sync* {
+    yield self::getNull();
+  }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> sync* {
+    yield* self::getIterableNull();
+  }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> var5 = (() => getIterableNull())(); // error
+                                                 ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+  core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> sync* {
+    yield* self::getIterableBool();
+  }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
new file mode 100644
index 0000000..07830cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
@@ -0,0 +1,266 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   yield* getIterableNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//     yield* getIterableNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> test5() => getIterableNull(); // error
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> var5 = (() => getIterableNull())(); // error
+//                                                  ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method getNull() → dynamic
+  return null;
+static method getIterableNull() → core::Iterable<dynamic> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = null;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method getIterableBool() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = true;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test1() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test2() → core::Iterable<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  yield* getIterableNull(); // error
+         ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test5() → core::Iterable<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+                          ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+  return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        function test1() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }
+        function test2() → core::Iterable<core::bool>
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+        function test3() → core::bool
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        function test4() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+    yield* getIterableNull(); // error
+           ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }
+        function test5() → core::Iterable<core::bool>
+          return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> test5() => getIterableNull(); // error
+                            ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        function test6() → core::Iterable<core::bool>
+          return self::getIterableBool();
+        function test7() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }
+        core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_current} = self::getNull();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<dynamic>(:sync_op);
+        }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableNull();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<dynamic>(:sync_op);
+        }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> var5 = (() => getIterableNull())(); // error
+                                                 ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+        core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }).call();
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
new file mode 100644
index 0000000..3c4069e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
@@ -0,0 +1,121 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   yield* getIterableNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//     yield* getIterableNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> test5() => getIterableNull(); // error
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> var5 = (() => getIterableNull())(); // error
+//                                                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getIterableNull() → core::Iterable<dynamic> sync* {
+  yield null;
+}
+static method getIterableBool() → core::Iterable<core::bool> sync* {
+  yield true;
+}
+static method test1() → core::Iterable<core::bool> sync* {
+  yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → core::Iterable<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> sync* {
+  yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  yield* getIterableNull(); // error
+         ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+}
+static method test5() → core::Iterable<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+                          ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+  return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> sync* {
+  yield* self::getIterableBool();
+}
+static method test() → dynamic async {
+  function test1() → core::Iterable<core::bool> sync* {
+    yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  }
+  function test2() → core::Iterable<core::bool>
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+  function test3() → core::bool
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  function test4() → core::Iterable<core::bool> sync* {
+    yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+    yield* getIterableNull(); // error
+           ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  }
+  function test5() → core::Iterable<core::bool>
+    return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> test5() => getIterableNull(); // error
+                            ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  function test6() → core::Iterable<core::bool>
+    return self::getIterableBool();
+  function test7() → core::Iterable<core::bool> sync* {
+    yield* self::getIterableBool();
+  }
+  core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> sync* {
+    yield self::getNull();
+  }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> sync* {
+    yield* self::getIterableNull();
+  }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> var5 = (() => getIterableNull())(); // error
+                                                 ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+  core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+  core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> sync* {
+    yield* self::getIterableBool();
+  }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
new file mode 100644
index 0000000..07830cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
@@ -0,0 +1,266 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   yield* getIterableNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//     yield* getIterableNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> test5() => getIterableNull(); // error
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+//  - 'Iterable' is from 'dart:core'.
+//   Iterable<bool> var5 = (() => getIterableNull())(); // error
+//                                                  ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method getNull() → dynamic
+  return null;
+static method getIterableNull() → core::Iterable<dynamic> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = null;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method getIterableBool() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = true;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test1() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test2() → core::Iterable<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  yield* getIterableNull(); // error
+         ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test5() → core::Iterable<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+                          ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+  return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> /* originally sync* */ {
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        function test1() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }
+        function test2() → core::Iterable<core::bool>
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+        function test3() → core::bool
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        function test4() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+    yield* getIterableNull(); // error
+           ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }
+        function test5() → core::Iterable<core::bool>
+          return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> test5() => getIterableNull(); // error
+                            ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        function test6() → core::Iterable<core::bool>
+          return self::getIterableBool();
+        function test7() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }
+        core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_current} = self::getNull();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<dynamic>(:sync_op);
+        }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  })(); // error
+    ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableNull();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<dynamic>(:sync_op);
+        }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+  Iterable<bool> var5 = (() => getIterableNull())(); // error
+                                                 ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+        core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+        core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> /* originally sync* */ {
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<core::bool>(:sync_op);
+        }).call();
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart b/pkg/front_end/testcases/nnbd/issue41437c.dart
new file mode 100644
index 0000000..2be47c3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dynamic getNull() => null;
+Stream<dynamic> getStreamNull() async* {
+  yield null;
+}
+
+Stream<bool> getStreamBool() async* {
+  yield true;
+}
+
+Stream<bool> test1() async* {
+  yield getNull(); // ok
+}
+
+Stream<bool> test2() => getNull(); // ok
+bool test3() => getNull(); // ok
+Stream<bool> test4() async* {
+  yield* getStreamNull(); // error
+}
+
+Stream<bool> test5() => getStreamNull(); // error
+Stream<bool> test6() => getStreamBool(); // ok
+Stream<bool> test7() async* {
+  yield* getStreamBool(); // ok
+}
+
+test() async {
+  Stream<bool> test1() async* {
+    yield getNull(); // ok
+  }
+
+  Stream<bool> test2() => getNull(); // ok
+  bool test3() => getNull(); // ok
+  Stream<bool> test4() async* {
+    yield* getStreamNull(); // error
+  }
+
+  Stream<bool> test5() => getStreamNull(); // error
+  Stream<bool> test6() => getStreamBool(); // ok
+  Stream<bool> test7() async* {
+    yield* getStreamBool(); // ok
+  }
+
+  Stream<bool> var1 = (() async* {
+    yield getNull();
+  })(); // error
+  Stream<bool> var2 = (() => getNull())(); // ok
+  bool var3 = (() => getNull())(); // ok
+  Stream<bool> var4 = (() async* {
+    yield* getStreamNull();
+  })(); // error
+  Stream<bool> var5 = (() => getStreamNull())(); // error
+  Stream<bool> var6 = (() => getStreamBool())(); // ok
+  Stream<bool> var7 = (() async* {
+    yield* getStreamBool();
+  })(); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.outline.expect
new file mode 100644
index 0000000..f877e4d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  ;
+static method getStreamNull() → asy::Stream<dynamic>
+  ;
+static method getStreamBool() → asy::Stream<core::bool>
+  ;
+static method test1() → asy::Stream<core::bool>
+  ;
+static method test2() → asy::Stream<core::bool>
+  ;
+static method test3() → core::bool
+  ;
+static method test4() → asy::Stream<core::bool>
+  ;
+static method test5() → asy::Stream<core::bool>
+  ;
+static method test6() → asy::Stream<core::bool>
+  ;
+static method test7() → asy::Stream<core::bool>
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
new file mode 100644
index 0000000..16b4fb1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
@@ -0,0 +1,122 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   yield* getStreamNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//     yield* getStreamNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> test5() => getStreamNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> var5 = (() => getStreamNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getStreamNull() → asy::Stream<dynamic> async* {
+  yield null;
+}
+static method getStreamBool() → asy::Stream<core::bool> async* {
+  yield true;
+}
+static method test1() → asy::Stream<core::bool> async* {
+  yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → asy::Stream<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> async* {
+  yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  yield* getStreamNull(); // error
+         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+}
+static method test5() → asy::Stream<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+                        ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+  return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> async* {
+  yield* self::getStreamBool();
+}
+static method test() → dynamic async {
+  function test1() → asy::Stream<core::bool> async* {
+    yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  }
+  function test2() → asy::Stream<core::bool>
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+  function test3() → core::bool
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  function test4() → asy::Stream<core::bool> async* {
+    yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+    yield* getStreamNull(); // error
+           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  }
+  function test5() → asy::Stream<core::bool>
+    return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> test5() => getStreamNull(); // error
+                          ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  function test6() → asy::Stream<core::bool>
+    return self::getStreamBool();
+  function test7() → asy::Stream<core::bool> async* {
+    yield* self::getStreamBool();
+  }
+  asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> async* {
+    yield self::getNull();
+  }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+  core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> async* {
+    yield* self::getStreamNull();
+  }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> var5 = (() => getStreamNull())(); // error
+                                             ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+  asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> async* {
+    yield* self::getStreamBool();
+  }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
new file mode 100644
index 0000000..26e901c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
@@ -0,0 +1,497 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   yield* getStreamNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//     yield* getStreamNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> test5() => getStreamNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> var5 = (() => getStreamNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getStreamNull() → asy::Stream<dynamic> /* originally async* */ {
+  asy::_AsyncStarStreamController<dynamic>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L1:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(null))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method getStreamBool() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L2:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(true))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test1() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L3:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test2() → asy::Stream<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L4:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  yield* getStreamNull(); // error
+         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test5() → asy::Stream<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+                        ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+  return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L5:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L6:
+      {
+        function test1() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L7:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        function test2() → asy::Stream<core::bool>
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+        function test3() → core::bool
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        function test4() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L8:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+    yield* getStreamNull(); // error
+           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        function test5() → asy::Stream<core::bool>
+          return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> test5() => getStreamNull(); // error
+                          ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        function test6() → asy::Stream<core::bool>
+          return self::getStreamBool();
+        function test7() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L9:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+          asy::_AsyncStarStreamController<dynamic>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L10:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+        core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+          asy::_AsyncStarStreamController<dynamic>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L11:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> var5 = (() => getStreamNull())(); // error
+                                             ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+        asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L12:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }).call();
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
new file mode 100644
index 0000000..16b4fb1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
@@ -0,0 +1,122 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   yield* getStreamNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//     yield* getStreamNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> test5() => getStreamNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> var5 = (() => getStreamNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getStreamNull() → asy::Stream<dynamic> async* {
+  yield null;
+}
+static method getStreamBool() → asy::Stream<core::bool> async* {
+  yield true;
+}
+static method test1() → asy::Stream<core::bool> async* {
+  yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → asy::Stream<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> async* {
+  yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  yield* getStreamNull(); // error
+         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+}
+static method test5() → asy::Stream<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+                        ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+  return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> async* {
+  yield* self::getStreamBool();
+}
+static method test() → dynamic async {
+  function test1() → asy::Stream<core::bool> async* {
+    yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  }
+  function test2() → asy::Stream<core::bool>
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+  function test3() → core::bool
+    return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  function test4() → asy::Stream<core::bool> async* {
+    yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+    yield* getStreamNull(); // error
+           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  }
+  function test5() → asy::Stream<core::bool>
+    return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> test5() => getStreamNull(); // error
+                          ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  function test6() → asy::Stream<core::bool>
+    return self::getStreamBool();
+  function test7() → asy::Stream<core::bool> async* {
+    yield* self::getStreamBool();
+  }
+  asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> async* {
+    yield self::getNull();
+  }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+  core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+  asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> async* {
+    yield* self::getStreamNull();
+  }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> var5 = (() => getStreamNull())(); // error
+                                             ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+  asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+  asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> async* {
+    yield* self::getStreamBool();
+  }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
new file mode 100644
index 0000000..26e901c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
@@ -0,0 +1,497 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   yield* getStreamNull(); // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+//                         ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//     yield* getStreamNull(); // error
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> test5() => getStreamNull(); // error
+//                           ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   })(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+//  - 'Stream' is from 'dart:async'.
+//   Stream<bool> var5 = (() => getStreamNull())(); // error
+//                                              ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+  return null;
+static method getStreamNull() → asy::Stream<dynamic> /* originally async* */ {
+  asy::_AsyncStarStreamController<dynamic>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L1:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(null))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method getStreamBool() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L2:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(true))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test1() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L3:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test2() → asy::Stream<core::bool>
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+  return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L4:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  yield* getStreamNull(); // error
+         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test5() → asy::Stream<core::bool>
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+                        ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+  return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::bool>? :controller;
+  dynamic :controller_stream;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L5:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+  :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+  return :controller_stream;
+}
+static method test() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>? :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
+  core::int :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L6:
+      {
+        function test1() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L7:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        function test2() → asy::Stream<core::bool>
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+        function test3() → core::bool
+          return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        function test4() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L8:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+    yield* getStreamNull(); // error
+           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        function test5() → asy::Stream<core::bool>
+          return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> test5() => getStreamNull(); // error
+                          ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        function test6() → asy::Stream<core::bool>
+          return self::getStreamBool();
+        function test7() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L9:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+          asy::_AsyncStarStreamController<dynamic>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L10:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+        core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+        asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  })(); // error
+    ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+          asy::_AsyncStarStreamController<dynamic>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L11:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+  Stream<bool> var5 = (() => getStreamNull())(); // error
+                                             ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+        asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+        asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::bool>? :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          (dynamic) → dynamic :async_op_then;
+          (core::Object, core::StackTrace) → dynamic :async_op_error;
+          core::int :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L12:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }).call();
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart b/pkg/front_end/testcases/nnbd/issue41495.dart
new file mode 100644
index 0000000..ceaf89a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  int c1 = 1;
+  int test() => 2;
+}
+
+main() {}
+
+errors() {
+  A? a1 = new A();
+  a1.c1;
+  a1.test;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.outline.expect
new file mode 100644
index 0000000..20f3ce6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.outline.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int c1;
+  synthetic constructor •() → self::A
+    ;
+  method test() → core::int
+    ;
+}
+static method main() → dynamic
+  ;
+static method errors() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.c1;
+//      ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.test;
+//      ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int c1 = 1;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method test() → core::int
+    return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+  self::A? a1 = new self::A::•();
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.c1;
+     ^^" in a1.{self::A::c1};
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.test;
+     ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.transformed.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.c1;
+//      ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.test;
+//      ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int c1 = 1;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method test() → core::int
+    return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+  self::A? a1 = new self::A::•();
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.c1;
+     ^^" in a1.{self::A::c1};
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.test;
+     ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline.expect
new file mode 100644
index 0000000..b1feffb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  int c1 = 1;
+  int test() => 2;
+}
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faa0d89
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+  int c1 = 1;
+  int test() => 2;
+}
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.c1;
+//      ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.test;
+//      ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int c1 = 1;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method test() → core::int
+    return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+  self::A? a1 = new self::A::•();
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.c1;
+     ^^" in a1.{self::A::c1};
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.test;
+     ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.transformed.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.c1;
+//      ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+//   a1.test;
+//      ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int c1 = 1;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method test() → core::int
+    return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+  self::A? a1 = new self::A::•();
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.c1;
+     ^^" in a1.{self::A::c1};
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+  a1.test;
+     ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart b/pkg/front_end/testcases/nnbd/issue41496.dart
new file mode 100644
index 0000000..93d3769
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "issue41496_lib.dart";
+
+LegacyFoo f1;
+
+class C {
+  static LegacyFoo f2;
+}
+
+main() {
+  new C();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.outline.expect
new file mode 100644
index 0000000..de2e711
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496_lib.dart";
+
+class C extends core::Object {
+  static field () → void f2;
+  synthetic constructor •() → self::C
+    ;
+}
+static field () → void f1;
+static method main() → dynamic
+  ;
+
+library opted_out_lib;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.strong.expect
new file mode 100644
index 0000000..5a1bc313
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.strong.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496_lib.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library opted_out_lib;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.strong.transformed.expect
new file mode 100644
index 0000000..5a1bc313
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496_lib.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library opted_out_lib;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline.expect
new file mode 100644
index 0000000..bab3915
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import "issue41496_lib.dart";
+
+LegacyFoo f1;
+
+class C {
+  static LegacyFoo f2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bab3915
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import "issue41496_lib.dart";
+
+LegacyFoo f1;
+
+class C {
+  static LegacyFoo f2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.weak.expect
new file mode 100644
index 0000000..5a1bc313
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.weak.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496_lib.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library opted_out_lib;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.weak.transformed.expect
new file mode 100644
index 0000000..5a1bc313
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.weak.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496_lib.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new self::C::•();
+}
+
+library opted_out_lib;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496_lib.dart b/pkg/front_end/testcases/nnbd/issue41496_lib.dart
new file mode 100644
index 0000000..8950f0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+library opted_out_lib;
+
+typedef void LegacyFoo();
+
+test(LegacyFoo f) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart b/pkg/front_end/testcases/nnbd/issue41496b.dart
new file mode 100644
index 0000000..4bafd01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+library opted_out_lib;
+
+import 'issue41496b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+
+test(LegacyFoo f) {}
+
+main() {
+  opt_in.main();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.outline.expect
new file mode 100644
index 0000000..e596933
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.outline.expect
@@ -0,0 +1,36 @@
+library opted_out_lib;
+import self as self;
+
+import "org-dartlang-testcase:///issue41496b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496b.dart";
+
+class C extends core::Object {
+  static field () → void f2;
+  synthetic constructor •() → self2::C
+    ;
+}
+static field () → void f1;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.strong.expect
new file mode 100644
index 0000000..b70a566
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.strong.expect
@@ -0,0 +1,39 @@
+library opted_out_lib;
+import self as self;
+import "issue41496b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41496b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496b.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new iss::C::•();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.strong.transformed.expect
new file mode 100644
index 0000000..b70a566
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library opted_out_lib;
+import self as self;
+import "issue41496b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41496b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496b.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new iss::C::•();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline.expect
new file mode 100644
index 0000000..d47c066
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41496b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+test(LegacyFoo f) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40de3a0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41496b_lib.dart' as opt_in;
+
+main() {}
+test(LegacyFoo f) {}
+typedef void LegacyFoo();
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.weak.expect
new file mode 100644
index 0000000..b70a566
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.weak.expect
@@ -0,0 +1,39 @@
+library opted_out_lib;
+import self as self;
+import "issue41496b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41496b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496b.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new iss::C::•();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.weak.transformed.expect
new file mode 100644
index 0000000..b70a566
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library opted_out_lib;
+import self as self;
+import "issue41496b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41496b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:7:11: Error: Field 'f1' should be initialized because its type 'void Function()' doesn't allow null.
+// LegacyFoo f1;
+//           ^^
+//
+// pkg/front_end/testcases/nnbd/issue41496b_lib.dart:10:20: Error: Field 'f2' should be initialized because its type 'void Function()' doesn't allow null.
+//   static LegacyFoo f2;
+//                    ^^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41496b.dart";
+
+class C extends core::Object {
+  static field () → void f2 = null;
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+}
+static field () → void f1;
+static method main() → dynamic {
+  new iss::C::•();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b_lib.dart b/pkg/front_end/testcases/nnbd/issue41496b_lib.dart
new file mode 100644
index 0000000..06bf01a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "issue41496b.dart";
+
+LegacyFoo f1;
+
+class C {
+  static LegacyFoo f2;
+}
+
+main() {
+  new C();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart b/pkg/front_end/testcases/nnbd/issue41498.dart
new file mode 100644
index 0000000..e6c1130
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "issue41498_lib.dart";
+
+class C {
+  static void test() {
+    LegacyFoo f;
+
+    f.toString(); // error
+  }
+
+  void test2() {
+    LegacyFoo f;
+
+    f.toString(); // error
+  }
+}
+
+test() {
+  LegacyFoo f;
+
+  f.toString(); // error
+
+  Function foo = () {
+    LegacyFoo f;
+
+    f.toString(); // error
+  };
+  C.test();
+  new C().test2();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.outline.expect
new file mode 100644
index 0000000..b4fdb09
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.outline.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  static method test() → void
+    ;
+  method test2() → void
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library opted_out_lib;
+import self as self2;
+import "dart:core" as core;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self2::C*
+    ;
+  static method test() → void
+    ;
+  method test2() → void
+    ;
+}
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.strong.expect
new file mode 100644
index 0000000..f2f0faa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.strong.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as self2;
+import "dart:core" as core;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self2::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self2::C::test();
+  new self2::C::•().{self2::C::test2}();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.strong.transformed.expect
new file mode 100644
index 0000000..f2f0faa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.strong.transformed.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as self2;
+import "dart:core" as core;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self2::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self2::C::test();
+  new self2::C::•().{self2::C::test2}();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline.expect
new file mode 100644
index 0000000..843b73c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import "issue41498_lib.dart";
+
+class C {
+  static void test() {}
+  void test2() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a871709
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import "issue41498_lib.dart";
+
+class C {
+  static void test() {}
+  void test2() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.weak.expect
new file mode 100644
index 0000000..f2f0faa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.weak.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as self2;
+import "dart:core" as core;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self2::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self2::C::test();
+  new self2::C::•().{self2::C::test2}();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.weak.transformed.expect
new file mode 100644
index 0000000..f2f0faa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.weak.transformed.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as self2;
+import "dart:core" as core;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self2::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self2::C::test();
+  new self2::C::•().{self2::C::test2}();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498_lib.dart b/pkg/front_end/testcases/nnbd/issue41498_lib.dart
new file mode 100644
index 0000000..9d4a423
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498_lib.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+library opted_out_lib;
+
+typedef void LegacyFoo();
+
+class C {
+  static void test() {
+    LegacyFoo f;
+
+    f.toString(); // ok
+  }
+
+  void test2() {
+    LegacyFoo f;
+
+    f.toString(); // ok
+  }
+}
+
+test() {
+  LegacyFoo f;
+
+  f.toString(); // ok
+
+  Function foo = () {
+    LegacyFoo f;
+
+    f.toString(); // ok
+  };
+  C.test();
+  new C().test2();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart b/pkg/front_end/testcases/nnbd/issue41498b.dart
new file mode 100644
index 0000000..4a6a49c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+library opted_out_lib;
+
+import 'issue41498b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+
+class C {
+  static void test() {
+    LegacyFoo f;
+
+    f.toString(); // ok
+  }
+
+  void test2() {
+    LegacyFoo f;
+
+    f.toString(); // ok
+  }
+}
+
+test() {
+  LegacyFoo f;
+
+  f.toString(); // ok
+
+  Function foo = () {
+    LegacyFoo f;
+
+    f.toString(); // ok
+  };
+  C.test();
+  new C().test2();
+}
+
+main() {
+  opt_in.main();
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.outline.expect
new file mode 100644
index 0000000..86599c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.outline.expect
@@ -0,0 +1,38 @@
+library opted_out_lib;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    ;
+  static method test() → void
+    ;
+  method test2() → void
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    ;
+  static method test() → void
+    ;
+  method test2() → void
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.strong.expect
new file mode 100644
index 0000000..6d86cf5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.strong.expect
@@ -0,0 +1,92 @@
+library opted_out_lib;
+import self as self;
+import "dart:core" as core;
+import "issue41498b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41498b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  iss::C::test();
+  new iss::C::•().{iss::C::test2}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.strong.transformed.expect
new file mode 100644
index 0000000..6d86cf5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.strong.transformed.expect
@@ -0,0 +1,92 @@
+library opted_out_lib;
+import self as self;
+import "dart:core" as core;
+import "issue41498b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41498b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  iss::C::test();
+  new iss::C::•().{iss::C::test2}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline.expect
new file mode 100644
index 0000000..6ad2a78
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41498b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+
+class C {
+  static void test() {}
+  void test2() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17f71c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41498b_lib.dart' as opt_in;
+
+class C {
+  static void test() {}
+  void test2() {}
+}
+
+main() {}
+test() {}
+typedef void LegacyFoo();
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.weak.expect
new file mode 100644
index 0000000..6d86cf5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.weak.expect
@@ -0,0 +1,92 @@
+library opted_out_lib;
+import self as self;
+import "dart:core" as core;
+import "issue41498b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41498b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  iss::C::test();
+  new iss::C::•().{iss::C::test2}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.weak.transformed.expect
new file mode 100644
index 0000000..6d86cf5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.weak.transformed.expect
@@ -0,0 +1,92 @@
+library opted_out_lib;
+import self as self;
+import "dart:core" as core;
+import "issue41498b_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41498b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+  method test2() → void {
+    () →* void f;
+    f.{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () →* void f;
+  f.{core::Object::toString}();
+  core::Function* foo = () → core::Null? {
+    () →* void f;
+    f.{core::Object::toString}();
+  };
+  self::C::test();
+  new self::C::•().{self::C::test2}();
+}
+static method main() → dynamic {
+  iss::main();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//   f.toString(); // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+//     f.toString(); // error
+//     ^
+//
+import self as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41498b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → iss::C
+    : super core::Object::•()
+    ;
+  static method test() → void {
+    () → void f;
+    (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:11:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+  method test2() → void {
+    () → void f;
+    (let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:17:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  }
+}
+static method test() → dynamic {
+  () → void f;
+  (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:24:3: Error: Non-nullable variable 'f' must be assigned before it can be used.
+  f.toString(); // error
+  ^" in f).{core::Object::toString}();
+  core::Function foo = () → core::Null? {
+    () → void f;
+    (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41498b_lib.dart:29:5: Error: Non-nullable variable 'f' must be assigned before it can be used.
+    f.toString(); // error
+    ^" in f).{core::Object::toString}();
+  };
+  iss::C::test();
+  new iss::C::•().{iss::C::test2}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b_lib.dart b/pkg/front_end/testcases/nnbd/issue41498b_lib.dart
new file mode 100644
index 0000000..ba3e746
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b_lib.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "issue41498b.dart";
+
+class C {
+  static void test() {
+    LegacyFoo f;
+
+    f.toString(); // error
+  }
+
+  void test2() {
+    LegacyFoo f;
+
+    f.toString(); // error
+  }
+}
+
+test() {
+  LegacyFoo f;
+
+  f.toString(); // error
+
+  Function foo = () {
+    LegacyFoo f;
+
+    f.toString(); // error
+  };
+  C.test();
+  new C().test2();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart b/pkg/front_end/testcases/nnbd/issue41499.dart
new file mode 100644
index 0000000..60fac65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "issue41499_lib.dart";
+
+class C {
+  static LegacyFoo sTest() {}
+
+  LegacyFoo mTest() {}
+
+  LegacyFoo get gTest {}
+}
+
+LegacyFoo test() {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.outline.expect
new file mode 100644
index 0000000..4b8ad7d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.outline.expect
@@ -0,0 +1,27 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  static method sTest() → () → void
+    ;
+  method mTest() → () → void
+    ;
+  get gTest() → () → void
+    ;
+}
+static method test() → () → void
+  ;
+static method main() → dynamic
+  ;
+
+library;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.strong.expect
new file mode 100644
index 0000000..e55976c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.strong.expect
@@ -0,0 +1,57 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.strong.transformed.expect
new file mode 100644
index 0000000..e55976c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline.expect
new file mode 100644
index 0000000..040ccd2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import "issue41499_lib.dart";
+
+class C {
+  static LegacyFoo sTest() {}
+  LegacyFoo mTest() {}
+  LegacyFoo get gTest {}
+}
+
+LegacyFoo test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d62fe6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "issue41499_lib.dart";
+
+LegacyFoo test() {}
+
+class C {
+  LegacyFoo get gTest {}
+  LegacyFoo mTest() {}
+  static LegacyFoo sTest() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.weak.expect
new file mode 100644
index 0000000..e55976c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.weak.expect
@@ -0,0 +1,57 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.weak.transformed.expect
new file mode 100644
index 0000000..e55976c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.weak.transformed.expect
@@ -0,0 +1,57 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499_lib.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499_lib.dart b/pkg/front_end/testcases/nnbd/issue41499_lib.dart
new file mode 100644
index 0000000..ae38a19
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499_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.
+
+// @dart=2.6
+typedef void LegacyFoo();
+
+test(LegacyFoo f) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart b/pkg/front_end/testcases/nnbd/issue41499b.dart
new file mode 100644
index 0000000..e03840c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+import 'issue41499b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+
+test(LegacyFoo f) {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.outline.expect
new file mode 100644
index 0000000..dd70ad6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue41499b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    ;
+  static method sTest() → () → void
+    ;
+  method mTest() → () → void
+    ;
+  get gTest() → () → void
+    ;
+}
+static method test() → () → void
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.strong.expect
new file mode 100644
index 0000000..06d4715
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.strong.expect
@@ -0,0 +1,59 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue41499b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.strong.transformed.expect
new file mode 100644
index 0000000..06d4715
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue41499b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline.expect
new file mode 100644
index 0000000..f853f4d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41499b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+test(LegacyFoo f) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae7272f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41499b_lib.dart' as opt_in;
+
+main() {}
+test(LegacyFoo f) {}
+typedef void LegacyFoo();
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.weak.expect
new file mode 100644
index 0000000..06d4715
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.weak.expect
@@ -0,0 +1,59 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue41499b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.weak.transformed.expect
new file mode 100644
index 0000000..06d4715
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.weak.transformed.expect
@@ -0,0 +1,59 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue41499b_lib.dart" as opt_in;
+
+typedef LegacyFoo = () →* void;
+static method test(() →* void f) → dynamic {}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   static LegacyFoo sTest() {}
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo mTest() {}
+//             ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+//   LegacyFoo get gTest {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+// LegacyFoo test() {}
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41499b.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method sTest() → () → void {
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:8:20: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  static LegacyFoo sTest() {}
+                   ^" in null;
+  }
+  method mTest() → () → void {
+    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:10:13: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo mTest() {}
+            ^" in null;
+  }
+  get gTest() → () → void {
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:12:17: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+  LegacyFoo get gTest {}
+                ^" in null;
+  }
+}
+static method test() → () → void {
+  return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41499b_lib.dart:15:11: Error: A non-null value must be returned since the return type 'void Function()' doesn't allow null.
+LegacyFoo test() {}
+          ^" in null;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b_lib.dart b/pkg/front_end/testcases/nnbd/issue41499b_lib.dart
new file mode 100644
index 0000000..0e205c2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "issue41499b.dart";
+
+class C {
+  static LegacyFoo sTest() {}
+
+  LegacyFoo mTest() {}
+
+  LegacyFoo get gTest {}
+}
+
+LegacyFoo test() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart b/pkg/front_end/testcases/nnbd/issue41567.dart
new file mode 100644
index 0000000..9df5590
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'issue41567_lib.dart';
+
+class B extends A {}
+
+class in1 extends out_Object implements B {} // ok
+
+class in2 extends B implements out_Object {} // ok
+
+class in3 extends out_int implements B {} // error
+
+class in4 extends B implements out_int {} // error
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.outline.expect
new file mode 100644
index 0000000..4214a62
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.outline.expect
@@ -0,0 +1,58 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:13:7: Error: 'in3' can't implement both 'A<int>' and 'A<dynamic>'
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in3 extends out_int implements B {} // error
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:15:7: Error: 'in4' can't implement both 'A<dynamic>' and 'A<int>'
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in4 extends B implements out_int {} // error
+//       ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41567_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41567_lib.dart";
+
+class B extends iss::A<dynamic> {
+  synthetic constructor •() → self::B
+    ;
+}
+class in1 extends iss::out_Object implements self::B {
+  synthetic constructor •() → self::in1
+    ;
+}
+class in2 extends self::B implements iss::out_Object {
+  synthetic constructor •() → self::in2
+    ;
+}
+class in3 extends iss::out_int implements self::B {
+  synthetic constructor •() → self::in3
+    ;
+}
+class in4 extends self::B implements iss::out_int {
+  synthetic constructor •() → self::in4
+    ;
+}
+static method main() → dynamic
+  ;
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → iss::A<iss::A::T*>*
+    ;
+}
+class out_int extends iss::A<core::int*> {
+  synthetic constructor •() → iss::out_int*
+    ;
+}
+class out_Object extends iss::A<core::Object*> {
+  synthetic constructor •() → iss::out_Object*
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.strong.expect
new file mode 100644
index 0000000..5ae9d25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.strong.expect
@@ -0,0 +1,65 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:13:7: Error: 'in3' can't implement both 'A<int>' and 'A<dynamic>'
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in3 extends out_int implements B {} // error
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:15:7: Error: 'in4' can't implement both 'A<dynamic>' and 'A<int>'
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in4 extends B implements out_int {} // error
+//       ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41567_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41567_lib.dart";
+
+class B extends iss::A<dynamic> {
+  synthetic constructor •() → self::B
+    : super iss::A::•()
+    ;
+}
+class in1 extends iss::out_Object implements self::B {
+  synthetic constructor •() → self::in1
+    : super iss::out_Object::•()
+    ;
+}
+class in2 extends self::B implements iss::out_Object {
+  synthetic constructor •() → self::in2
+    : super self::B::•()
+    ;
+}
+class in3 extends iss::out_int implements self::B {
+  synthetic constructor •() → self::in3
+    : super iss::out_int::•()
+    ;
+}
+class in4 extends self::B implements iss::out_int {
+  synthetic constructor •() → self::in4
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → iss::A<iss::A::T*>*
+    : super core::Object::•()
+    ;
+}
+class out_int extends iss::A<core::int*> {
+  synthetic constructor •() → iss::out_int*
+    : super iss::A::•()
+    ;
+}
+class out_Object extends iss::A<core::Object*> {
+  synthetic constructor •() → iss::out_Object*
+    : super iss::A::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline.expect
new file mode 100644
index 0000000..4a39bd7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'issue41567_lib.dart';
+
+class B extends A {}
+
+class in1 extends out_Object implements B {}
+
+class in2 extends B implements out_Object {}
+
+class in3 extends out_int implements B {}
+
+class in4 extends B implements out_int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a39bd7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'issue41567_lib.dart';
+
+class B extends A {}
+
+class in1 extends out_Object implements B {}
+
+class in2 extends B implements out_Object {}
+
+class in3 extends out_int implements B {}
+
+class in4 extends B implements out_int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.weak.expect
new file mode 100644
index 0000000..5ae9d25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.weak.expect
@@ -0,0 +1,65 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:13:7: Error: 'in3' can't implement both 'A<int>' and 'A<dynamic>'
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in3 extends out_int implements B {} // error
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:15:7: Error: 'in4' can't implement both 'A<dynamic>' and 'A<int>'
+//  - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in4 extends B implements out_int {} // error
+//       ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41567_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41567_lib.dart";
+
+class B extends iss::A<dynamic> {
+  synthetic constructor •() → self::B
+    : super iss::A::•()
+    ;
+}
+class in1 extends iss::out_Object implements self::B {
+  synthetic constructor •() → self::in1
+    : super iss::out_Object::•()
+    ;
+}
+class in2 extends self::B implements iss::out_Object {
+  synthetic constructor •() → self::in2
+    : super self::B::•()
+    ;
+}
+class in3 extends iss::out_int implements self::B {
+  synthetic constructor •() → self::in3
+    : super iss::out_int::•()
+    ;
+}
+class in4 extends self::B implements iss::out_int {
+  synthetic constructor •() → self::in4
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → iss::A<iss::A::T*>*
+    : super core::Object::•()
+    ;
+}
+class out_int extends iss::A<core::int*> {
+  synthetic constructor •() → iss::out_int*
+    : super iss::A::•()
+    ;
+}
+class out_Object extends iss::A<core::Object*> {
+  synthetic constructor •() → iss::out_Object*
+    : super iss::A::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567_lib.dart b/pkg/front_end/testcases/nnbd/issue41567_lib.dart
new file mode 100644
index 0000000..e45bcd9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+class A<T> {}
+
+class out_int extends A<int> {}
+
+class out_Object extends A<Object> {}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart b/pkg/front_end/testcases/nnbd/issue41597.dart
new file mode 100644
index 0000000..0180159
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'issue41597_lib.dart';
+
+bool x;
+bool x;
+
+errors() {
+  print(x);
+  print(x!);
+  print(!x);
+}
+
+class C {
+  C.c0() : super();
+  C.c1() : super()!;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.outline.expect
new file mode 100644
index 0000000..6a4719a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.outline.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+//      ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+  constructor c0() → self::C
+    ;
+  constructor c1() → self::C
+    ;
+}
+static field core::bool x;
+static method errors() → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library;
+import self as self2;
+
+static method errors(dynamic c) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+//      ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x!);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+//   print(!x);
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C.c1() : super()!;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+//   C.c1() : super()!;
+//                   ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+  constructor c0() → self::C
+    : super core::Object::•()
+    ;
+  constructor c1() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  C.c1() : super()!;
+           ^"!
+    ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+  print(x);
+        ^");
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+  print(x!);
+        ^"!);
+  core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+  print(!x);
+         ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+//   c?..f!;
+//        ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+  c?..f;
+     ^".f;
+  !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+  !c?..f;
+      ^".f as{TypeError,ForDynamic} core::bool*);
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+  c?..f!;
+     ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.transformed.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.transformed.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+//      ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x!);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+//   print(!x);
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C.c1() : super()!;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+//   C.c1() : super()!;
+//                   ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+  constructor c0() → self::C
+    : super core::Object::•()
+    ;
+  constructor c1() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  C.c1() : super()!;
+           ^"!
+    ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+  print(x);
+        ^");
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+  print(x!);
+        ^"!);
+  core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+  print(!x);
+         ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+//   c?..f!;
+//        ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+  c?..f;
+     ^".f;
+  !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+  !c?..f;
+      ^".f as{TypeError,ForDynamic} core::bool*);
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+  c?..f!;
+     ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.textual_outline.expect
new file mode 100644
index 0000000..792707c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'issue41597_lib.dart';
+bool x;
+bool x;
+errors() { }
+class C {
+  C.c0() : super();
+  C.c1() : super()!;
+}
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+//      ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x!);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+//   print(!x);
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C.c1() : super()!;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+//   C.c1() : super()!;
+//                   ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+  constructor c0() → self::C
+    : super core::Object::•()
+    ;
+  constructor c1() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  C.c1() : super()!;
+           ^"!
+    ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+  print(x);
+        ^");
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+  print(x!);
+        ^"!);
+  core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+  print(!x);
+         ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+//   c?..f!;
+//        ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+  c?..f;
+     ^".f;
+  !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+  !c?..f;
+      ^".f as{TypeError,ForDynamic} core::bool*);
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+  c?..f!;
+     ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.transformed.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.transformed.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+//      ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+//   print(x!);
+//         ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+//   print(!x);
+//          ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C.c1() : super()!;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+//   C.c1() : super()!;
+//                   ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+  constructor c0() → self::C
+    : super core::Object::•()
+    ;
+  constructor c1() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  C.c1() : super()!;
+           ^"!
+    ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+  print(x);
+        ^");
+  core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+  print(x!);
+        ^"!);
+  core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+  print(!x);
+         ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+//   c?..f;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+//   !c?..f;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+//   c?..f!;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+//   c?..f!;
+//        ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+  c?..f;
+     ^".f;
+  !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+  !c?..f;
+      ^".f as{TypeError,ForDynamic} core::bool*);
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+  c?..f!;
+     ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597_lib.dart b/pkg/front_end/testcases/nnbd/issue41597_lib.dart
new file mode 100644
index 0000000..b810fd8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+errors(c) {
+  c?..f;
+  !c?..f;
+  c?..f!;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart b/pkg/front_end/testcases/nnbd/issue41700a.dart
new file mode 100644
index 0000000..d04ab3e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.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.
+
+test() {
+  Null x = null;
+  x.foo();
+  Null? y = null;
+  y.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.outline.expect
new file mode 100644
index 0000000..64923de
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  core::Null? x = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  core::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.transformed.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  core::Null? x = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  core::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  core::Null? x = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  core::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.transformed.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.transformed.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  core::Null? x = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  core::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart b/pkg/front_end/testcases/nnbd/issue41700b.dart
new file mode 100644
index 0000000..5cc3693
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Null {}
+
+test() {
+  Null x = null;
+  x.foo();
+  Null? y = null;
+  y.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.outline.expect
new file mode 100644
index 0000000..2e0425c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.outline.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+  synthetic constructor •() → self::Null
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+//  - 'Null/*1*/' is from 'dart:core'.
+//  - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+//   Null x = null;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+  synthetic constructor •() → self::Null
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+  Null x = null;
+           ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  self::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+//  - 'Null/*1*/' is from 'dart:core'.
+//  - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+//   Null x = null;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+  synthetic constructor •() → self::Null
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+  Null x = null;
+           ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  self::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+//  - 'Null/*1*/' is from 'dart:core'.
+//  - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+//   Null x = null;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+  synthetic constructor •() → self::Null
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+  Null x = null;
+           ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  self::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+//  - 'Null/*1*/' is from 'dart:core'.
+//  - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+//   Null x = null;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   x.foo();
+//     ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+//  - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+//   y.foo();
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+  synthetic constructor •() → self::Null
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+  Null x = null;
+           ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  x.foo();
+    ^^^";
+  self::Null? y = null;
+  invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+  y.foo();
+    ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline.expect
new file mode 100644
index 0000000..c90f902
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class C {
+  D? f() => new D();
+  void h() {}
+}
+
+class D {
+  void g() {}
+}
+
+void test(C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c43f630
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class C {
+  D? f() => new D();
+  void h() {}
+}
+
+class D {
+  void g() {}
+}
+
+main() {}
+void test(C x) {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline.expect
new file mode 100644
index 0000000..15af755
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class C {
+  int y = 42;
+  D? f() => new D();
+  C h() => this;
+}
+
+class D {
+  D g() => this;
+  String operator [](String s) {}
+}
+
+void test(C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bf01dba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class C {
+  C h() => this;
+  D? f() => new D();
+  int y = 42;
+}
+
+class D {
+  D g() => this;
+  String operator [](String s) {}
+}
+
+main() {}
+void test(C x) {}
diff --git a/pkg/front_end/testcases/nnbd/late.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/late.dart.textual_outline.expect
new file mode 100644
index 0000000..596c5f8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.textual_outline.expect
@@ -0,0 +1,33 @@
+late int ;
+lateTopLevelField;
+late ;
+final int lateFinalTopLevelField;
+late ;
+final int lateFinalTopLevelFieldWithInit = 0;
+class Class {
+  late int ;
+  lateInstanceField;
+  late ;
+  final int lateFinalInstanceField1;
+  late ;
+  final int lateFinalInstanceField2;
+  late ;
+  final int lateFinalInstanceFieldWithInit = 0;
+  late Class ;
+  lateInstanceFieldThis = this;
+  late ;
+  final Class lateFinalInstanceFieldThis = this;
+  static late int ;
+  lateStaticField;
+  static late ;
+  final int lateFinalStaticField1;
+  static late ;
+  final int lateFinalStaticField2;
+  static late ;
+  final int lateFinalStaticFieldWithInit = 0;
+  method() { }
+  methodWithErrors() { }
+}
+main() { }
+noErrors() { }
+errors() { }
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index 37628df..13a5cc4 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -64,8 +64,8 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   field core::int a = 42;
@@ -109,7 +109,7 @@
     core::print("baz");
   }
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String>["baz"]).{core::Iterable::iterator};
+    core::Iterator<core::String*> :sync-for-iterator = <core::String>["baz"].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String s = :sync-for-iterator.{core::Iterator::current};
       {
@@ -127,8 +127,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -140,7 +140,7 @@
       #L1:
       {
         {
-          dynamic :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
+          asy::Stream<core::String*>* :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::String>? :for-iterator = new asy::_StreamIterator::•<core::String>(:stream);
           try
@@ -169,21 +169,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method fisk() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -205,8 +205,8 @@
             final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
             asy::FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
-            dynamic :async_op_then;
-            dynamic :async_op_error;
+            (dynamic) → dynamic :async_op_then;
+            (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
             dynamic :await_ctx_var;
             dynamic :saved_try_context_var0;
@@ -221,13 +221,13 @@
                 asy::_completeOnAsyncReturn(:async_completer, :return_value);
                 return;
               }
-              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
                 :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.start(:async_op);
+            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
             return :async_completer.{asy::Completer::future};
           };
         late core::Function f = #f#initializer.call();
@@ -235,13 +235,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/later.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/later.dart.textual_outline.expect
new file mode 100644
index 0000000..e0c821d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/later.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+class A {
+  int a = 42;
+  late int ;
+  b = (this.a * 2) >> 1;
+  foo(late int x) { }
+}
+bar(late int x) { }
+baz() { }
+hest() async { }
+fisk() async { }
+class B {
+  late ;
+  final int x = 42;
+  const B();
+}
+class C {
+  late ;
+  final int x;
+  initVars() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index 37628df..13a5cc4 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -64,8 +64,8 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   field core::int a = 42;
@@ -109,7 +109,7 @@
     core::print("baz");
   }
   {
-    core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String>["baz"]).{core::Iterable::iterator};
+    core::Iterator<core::String*> :sync-for-iterator = <core::String>["baz"].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::String s = :sync-for-iterator.{core::Iterator::current};
       {
@@ -127,8 +127,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -140,7 +140,7 @@
       #L1:
       {
         {
-          dynamic :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
+          asy::Stream<core::String*>* :stream = asy::Stream::fromIterable<core::String>(<core::String>["hest"]);
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<core::String>? :for-iterator = new asy::_StreamIterator::•<core::String>(:stream);
           try
@@ -169,21 +169,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method fisk() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -205,8 +205,8 @@
             final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
             asy::FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
-            dynamic :async_op_then;
-            dynamic :async_op_error;
+            (dynamic) → dynamic :async_op_then;
+            (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
             dynamic :await_ctx_var;
             dynamic :saved_try_context_var0;
@@ -221,13 +221,13 @@
                 asy::_completeOnAsyncReturn(:async_completer, :return_value);
                 return;
               }
-              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
                 :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.start(:async_op);
+            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
             return :async_completer.{asy::Completer::future};
           };
         late core::Function f = #f#initializer.call();
@@ -235,13 +235,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline.expect
new file mode 100644
index 0000000..145fce3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Object f() => g(null) ?? 0;
+T g<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..145fce3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Object f() => g(null) ?? 0;
+T g<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..81dcd51
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo<T extends Object?>() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81dcd51
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo<T extends Object?>() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..cd7a827
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.5
+import 'literal_from_opt_in_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd7a827
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.5
+import 'literal_from_opt_in_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline.expect
new file mode 100644
index 0000000..8f208e0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import "dart:math" deferred as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f208e0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import "dart:math" deferred as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..af85f0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+// @dart = 2.5
+import 'member_inheritance_from_opt_in_lib.dart';
+
+class LegacyClass extends Class implements Interface {
+  int method3() => 0;
+  int method4() => 0;
+  int method6a(int a, int b) => 0;
+  int method6b(int a, [int b]) => 0;
+  int method6c([int a, int b]) => 0;
+  int method8a(int a, {int b: 0}) => 0;
+  int method8b({int a, int b: 0}) => 0;
+  int method10a(int a, {int b}) => 0;
+  int method10b({int a, int b}) => 0;
+  int get getter3 => 0;
+  int get getter4 => 0;
+  void set setter3(int value) {}
+  void set setter4(int value) {}
+  int field3;
+  int field4;
+  int get property3 => 0;
+  void set property3(int value) {}
+  int get property4 => 0;
+  void set property4(int value) {}
+  int property7;
+  int property8;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0cad16e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+// @dart = 2.5
+import 'member_inheritance_from_opt_in_lib.dart';
+
+class LegacyClass extends Class implements Interface {
+  int field3;
+  int field4;
+  int get getter3 => 0;
+  int get getter4 => 0;
+  int get property3 => 0;
+  int get property4 => 0;
+  int method10a(int a, {int b}) => 0;
+  int method10b({int a, int b}) => 0;
+  int method3() => 0;
+  int method4() => 0;
+  int method6a(int a, int b) => 0;
+  int method6b(int a, [int b]) => 0;
+  int method6c([int a, int b]) => 0;
+  int method8a(int a, {int b: 0}) => 0;
+  int method8b({int a, int b: 0}) => 0;
+  int property7;
+  int property8;
+  void set property3(int value) {}
+  void set property4(int value) {}
+  void set setter3(int value) {}
+  void set setter4(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..b7107c1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,81 @@
+library main;
+
+import 'member_inheritance_from_opt_out_lib.dart';
+
+abstract class Interface {
+  int method1();
+  int? method2();
+  int method3a(int a, int b);
+  int method3b(int a, [int b]);
+  int method3c([int a, int b]);
+  int? method4a(int? a, int? b);
+  int? method4b(int? a, [int? b]);
+  int? method4c([int? a, int? b]);
+  int method5a(int a, {int b: 0});
+  int method5b({int a: 0, int b: 0});
+  int method5c({required int a, required int b});
+  int? method6a(int? a, {int? b});
+  int? method6b({int? a, int? b});
+  int? method6c({required int? a, required int? b});
+  int get getter1;
+  int? get getter2;
+  void set setter1(int value);
+  void set setter2(int? value);
+  int field1 = 0;
+  int? field2;
+  int get field3;
+  void set field3(int value);
+  int? get field4;
+  void set field4(int? value);
+  int get property1;
+  void set property1(int value);
+  int? get property2;
+  void set property2(int? value);
+  int property3 = 0;
+  int? property4;
+}
+
+class Class1 extends LegacyClass {}
+
+class Class2a extends LegacyClass implements Interface {}
+
+class Class2b extends LegacyClass implements Interface {
+  int method1() => 0;
+  int? method2() => 0;
+  int method3a(int a, int b) => 0;
+  int method3b(int a, [int b = 42]) => 0;
+  int method3c([int a = 42, int b = 42]) => 0;
+  int? method4a(int? a, int? b) => 0;
+  int? method4b(int? a, [int? b]) => 0;
+  int? method4c([int? a, int? b]) => 0;
+  int method5a(int a, {int b: 0}) => 0;
+  int method5b({int a: 0, int b: 0}) => 0;
+  int method5c({required int a, required int b}) => 0;
+  int? method6a(int? a, {int? b}) => 0;
+  int? method6b({int? a, int? b}) => 0;
+  int? method6c({required int? a, required int? b}) => 0;
+  int get getter1 => 0;
+  int? get getter2 => 0;
+  void set setter1(int value) {}
+  void set setter2(int? value) {}
+  int field1 = 0;
+  int? field2;
+  int get field3 => 0;
+  void set field3(int value) {}
+  int? get field4 => 0;
+  void set field4(int? value) {}
+  int get property1 => 0;
+  void set property1(int value) {}
+  int? get property2 => 0;
+  void set property2(int? value) {}
+  int property3 = 0;
+  int? property4;
+}
+
+class Class3a extends GenericLegacyClass<int> {}
+
+class Class3b extends GenericLegacyClass<int?> {}
+
+class Class3c<S> extends GenericLegacyClass<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..860366f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,81 @@
+library main;
+
+import 'member_inheritance_from_opt_out_lib.dart';
+
+abstract class Interface {
+  int field1 = 0;
+  int get field3;
+  int get getter1;
+  int get property1;
+  int method1();
+  int method3a(int a, int b);
+  int method3b(int a, [int b]);
+  int method3c([int a, int b]);
+  int method5a(int a, {int b: 0});
+  int method5b({int a: 0, int b: 0});
+  int method5c({required int a, required int b});
+  int property3 = 0;
+  int? field2;
+  int? get field4;
+  int? get getter2;
+  int? get property2;
+  int? method2();
+  int? method4a(int? a, int? b);
+  int? method4b(int? a, [int? b]);
+  int? method4c([int? a, int? b]);
+  int? method6a(int? a, {int? b});
+  int? method6b({int? a, int? b});
+  int? method6c({required int? a, required int? b});
+  int? property4;
+  void set field3(int value);
+  void set field4(int? value);
+  void set property1(int value);
+  void set property2(int? value);
+  void set setter1(int value);
+  void set setter2(int? value);
+}
+
+class Class1 extends LegacyClass {}
+
+class Class2a extends LegacyClass implements Interface {}
+
+class Class2b extends LegacyClass implements Interface {
+  int field1 = 0;
+  int get field3 => 0;
+  int get getter1 => 0;
+  int get property1 => 0;
+  int method1() => 0;
+  int method3a(int a, int b) => 0;
+  int method3b(int a, [int b = 42]) => 0;
+  int method3c([int a = 42, int b = 42]) => 0;
+  int method5a(int a, {int b: 0}) => 0;
+  int method5b({int a: 0, int b: 0}) => 0;
+  int method5c({required int a, required int b}) => 0;
+  int property3 = 0;
+  int? field2;
+  int? get field4 => 0;
+  int? get getter2 => 0;
+  int? get property2 => 0;
+  int? method2() => 0;
+  int? method4a(int? a, int? b) => 0;
+  int? method4b(int? a, [int? b]) => 0;
+  int? method4c([int? a, int? b]) => 0;
+  int? method6a(int? a, {int? b}) => 0;
+  int? method6b({int? a, int? b}) => 0;
+  int? method6c({required int? a, required int? b}) => 0;
+  int? property4;
+  void set field3(int value) {}
+  void set field4(int? value) {}
+  void set property1(int value) {}
+  void set property2(int? value) {}
+  void set setter1(int value) {}
+  void set setter2(int? value) {}
+}
+
+class Class3a extends GenericLegacyClass<int> {}
+
+class Class3b extends GenericLegacyClass<int?> {}
+
+class Class3c<S> extends GenericLegacyClass<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..ac9dab0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+import 'messages_with_types_opt_out.dart';
+
+class SuperIn {
+  String? nullableSame() => "foo";
+  String nonNullableSame() => "bar";
+  int? nullableBad<T>(T t) => 1;
+  int nonNullableBad<T>(T t) => 2;
+}
+
+class SubInIn extends SuperIn {
+  String? nullableSame() => "foo";
+  String nonNullableSame() => "bar";
+  T? nullableBad<T>(T t) => null;
+  T nonNullableBad<T>(T t) => t;
+}
+
+class SubOutIn extends SuperOut {
+  String? nullableSame() => "foo";
+  String nonNullableSame() => "bar";
+  T? nullableBad<T>(T t) => null;
+  T nonNullableBad<T>(T t) => t;
+}
+
+int Function()? nullableVar = () => 3;
+double nonNullableVar = 4.0;
+testOptIn() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f30fad
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+import 'messages_with_types_opt_out.dart';
+
+class SubInIn extends SuperIn {
+  String nonNullableSame() => "bar";
+  String? nullableSame() => "foo";
+  T nonNullableBad<T>(T t) => t;
+  T? nullableBad<T>(T t) => null;
+}
+
+class SubOutIn extends SuperOut {
+  String nonNullableSame() => "bar";
+  String? nullableSame() => "foo";
+  T nonNullableBad<T>(T t) => t;
+  T? nullableBad<T>(T t) => null;
+}
+
+class SuperIn {
+  String nonNullableSame() => "bar";
+  String? nullableSame() => "foo";
+  int nonNullableBad<T>(T t) => 2;
+  int? nullableBad<T>(T t) => 1;
+}
+
+double nonNullableVar = 4.0;
+int Function()? nullableVar = () => 3;
+testOptIn() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..3271b71
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.5
+import 'messages_with_types_opt_in.dart';
+
+class SuperOut {
+  String nullableSame() => "foo";
+  String nonNullableSame() => "bar";
+  int nullableBad<T>(T t) => 1;
+  int nonNullableBad<T>(T t) => 2;
+}
+
+class SubOutOut extends SuperOut {
+  String nullableSame() => "foo";
+  String nonNullableSame() => "bar";
+  T nullableBad<T>(T t) => null;
+  T nonNullableBad<T>(T t) => t;
+}
+
+class SubInOut extends SuperIn {
+  String nullableSame() => "foo";
+  String nonNullableSame() => "bar";
+  T nullableBad<T>(T t) => null;
+  T nonNullableBad<T>(T t) => t;
+}
+
+String legacyVar = "legacy";
+testOptOut() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..29aa4bf
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.5
+import 'messages_with_types_opt_in.dart';
+
+String legacyVar = "legacy";
+
+class SubInOut extends SuperIn {
+  String nonNullableSame() => "bar";
+  String nullableSame() => "foo";
+  T nonNullableBad<T>(T t) => t;
+  T nullableBad<T>(T t) => null;
+}
+
+class SubOutOut extends SuperOut {
+  String nonNullableSame() => "bar";
+  String nullableSame() => "foo";
+  T nonNullableBad<T>(T t) => t;
+  T nullableBad<T>(T t) => null;
+}
+
+class SuperOut {
+  String nonNullableSame() => "bar";
+  String nullableSame() => "foo";
+  int nonNullableBad<T>(T t) => 2;
+  int nullableBad<T>(T t) => 1;
+}
+
+testOptOut() {}
diff --git a/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..1e4f84b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+void foo({required String s}) {}
+void Function({required String s}) g = ({required String s}) {};
+
+class A {
+  A({required int x});
+  foo({required int y}) {}
+  void Function({required String s}) f = ({required String s}) {};
+}
+
+bar() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d6834e7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+bar() {}
+
+class A {
+  A({required int x});
+  foo({required int y}) {}
+  void Function({required String s}) f = ({required String s}) {};
+}
+
+main() {}
+void Function({required String s}) g = ({required String s}) {};
+void foo({required String s}) {}
diff --git a/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..2200093
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import './mixed_mode_hierarchy_generic_methods_lib.dart';
+import "dart:async";
+
+class B implements A<int> {
+  then<B>() => Future<B>.value();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2200093
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import './mixed_mode_hierarchy_generic_methods_lib.dart';
+import "dart:async";
+
+class B implements A<int> {
+  then<B>() => Future<B>.value();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..fbc1a75
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'mixin_from_opt_in_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fbc1a75
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'mixin_from_opt_in_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart
new file mode 100644
index 0000000..dc5f062
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Declarations taken from
+//    language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_test
+
+import 'mixin_from_opt_in_out_in_lib1.dart';
+import 'mixin_from_opt_in_out_in_lib2.dart';
+
+// Member signatures: B.
+class DiB0 extends C0 implements B {}
+
+// Member signatures: Bq.
+class DiBq0 extends C0 implements Bq {}
+
+// Member signatures: B.
+class DwB0 extends C0 with B {}
+
+// Member signatures: Bq.
+class DwBq0 extends C0 with Bq {}
+
+// Member signatures: legacy.
+class DiB3 extends C3 implements B {}
+
+// Member signatures: legacy.
+class DiBq3 extends C3 implements Bq {}
+
+// Member signatures: B.
+class DwB3 extends C3 with B {}
+
+// Member signatures: Bq.
+class DwBq3 extends C3 with Bq {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.outline.expect
new file mode 100644
index 0000000..8aa3ee5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.outline.expect
@@ -0,0 +1,122 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "mixin_from_opt_in_out_in_lib1.dart" as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib1.dart";
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class DiB0 extends mix::C0 implements mix2::B {
+  synthetic constructor •() → self::DiB0
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq0 extends mix::C0 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq0
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB0&C0&B = mix::C0 with mix2::B /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwB0&C0&B
+    : super mix::C0::•()
+    ;
+}
+class DwB0 extends self::_DwB0&C0&B {
+  synthetic constructor •() → self::DwB0
+    ;
+}
+abstract class _DwBq0&C0&Bq = mix::C0 with mix2::Bq /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwBq0&C0&Bq
+    : super mix::C0::•()
+    ;
+}
+class DwBq0 extends self::_DwBq0&C0&Bq {
+  synthetic constructor •() → self::DwBq0
+    ;
+}
+class DiB3 extends mix::C3 implements mix2::B {
+  synthetic constructor •() → self::DiB3
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq3 extends mix::C3 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq3
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB3&C3&B = mix::C3 with mix2::B /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwB3&C3&B
+    : super mix::C3::•()
+    ;
+}
+class DwB3 extends self::_DwB3&C3&B {
+  synthetic constructor •() → self::DwB3
+    ;
+}
+abstract class _DwBq3&C3&Bq = mix::C3 with mix2::Bq /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwBq3&C3&Bq
+    : super mix::C3::•()
+    ;
+}
+class DwBq3 extends self::_DwBq3&C3&Bq {
+  synthetic constructor •() → self::DwBq3
+    ;
+}
+static method main() → dynamic
+  ;
+
+library;
+import self as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class C0 extends mix2::B {
+  synthetic constructor •() → mix::C0*
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+class C3 extends mix2::Bq {
+  synthetic constructor •() → mix::C3*
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mix2;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → mix2::B
+    ;
+  get a() → core::List<(core::int) → core::int>
+    ;
+  set a(core::List<(core::int) → core::int> _) → void
+    ;
+  method m((core::int) → core::int x) → (core::int) → core::int
+    ;
+}
+class Bq extends core::Object {
+  synthetic constructor •() → mix2::Bq
+    ;
+  get a() → core::List<(core::int?) → core::int?>
+    ;
+  set a(core::List<(core::int?) → core::int?> _) → void
+    ;
+  method m((core::int?) → core::int? x) → (core::int?) → core::int?
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.strong.expect
new file mode 100644
index 0000000..fe1d001
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.strong.expect
@@ -0,0 +1,131 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "mixin_from_opt_in_out_in_lib1.dart" as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib1.dart";
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class DiB0 extends mix::C0 implements mix2::B {
+  synthetic constructor •() → self::DiB0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq0 extends mix::C0 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB0&C0&B = mix::C0 with mix2::B /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwB0&C0&B
+    : super mix::C0::•()
+    ;
+}
+class DwB0 extends self::_DwB0&C0&B {
+  synthetic constructor •() → self::DwB0
+    : super self::_DwB0&C0&B::•()
+    ;
+}
+abstract class _DwBq0&C0&Bq = mix::C0 with mix2::Bq /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwBq0&C0&Bq
+    : super mix::C0::•()
+    ;
+}
+class DwBq0 extends self::_DwBq0&C0&Bq {
+  synthetic constructor •() → self::DwBq0
+    : super self::_DwBq0&C0&Bq::•()
+    ;
+}
+class DiB3 extends mix::C3 implements mix2::B {
+  synthetic constructor •() → self::DiB3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq3 extends mix::C3 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB3&C3&B = mix::C3 with mix2::B /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwB3&C3&B
+    : super mix::C3::•()
+    ;
+}
+class DwB3 extends self::_DwB3&C3&B {
+  synthetic constructor •() → self::DwB3
+    : super self::_DwB3&C3&B::•()
+    ;
+}
+abstract class _DwBq3&C3&Bq = mix::C3 with mix2::Bq /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwBq3&C3&Bq
+    : super mix::C3::•()
+    ;
+}
+class DwBq3 extends self::_DwBq3&C3&Bq {
+  synthetic constructor •() → self::DwBq3
+    : super self::_DwBq3&C3&Bq::•()
+    ;
+}
+static method main() → dynamic {}
+
+library;
+import self as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class C0 extends mix2::B {
+  synthetic constructor •() → mix::C0*
+    : super mix2::B::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+class C3 extends mix2::Bq {
+  synthetic constructor •() → mix::C3*
+    : super mix2::Bq::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mix2;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → mix2::B
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set a(core::List<(core::int) → core::int> _) → void {}
+  method m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class Bq extends core::Object {
+  synthetic constructor •() → mix2::Bq
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set a(core::List<(core::int?) → core::int?> _) → void {}
+  method m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.strong.transformed.expect
new file mode 100644
index 0000000..53ac2ec
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.strong.transformed.expect
@@ -0,0 +1,151 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "mixin_from_opt_in_out_in_lib1.dart" as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib1.dart";
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class DiB0 extends mix::C0 implements mix2::B {
+  synthetic constructor •() → self::DiB0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq0 extends mix::C0 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB0&C0&B extends mix::C0 implements mix2::B /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwB0&C0&B
+    : super mix::C0::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int) → core::int> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class DwB0 extends self::_DwB0&C0&B {
+  synthetic constructor •() → self::DwB0
+    : super self::_DwB0&C0&B::•()
+    ;
+}
+abstract class _DwBq0&C0&Bq extends mix::C0 implements mix2::Bq /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwBq0&C0&Bq
+    : super mix::C0::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int?) → core::int?> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
+class DwBq0 extends self::_DwBq0&C0&Bq {
+  synthetic constructor •() → self::DwBq0
+    : super self::_DwBq0&C0&Bq::•()
+    ;
+}
+class DiB3 extends mix::C3 implements mix2::B {
+  synthetic constructor •() → self::DiB3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq3 extends mix::C3 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB3&C3&B extends mix::C3 implements mix2::B /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwB3&C3&B
+    : super mix::C3::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int) → core::int> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class DwB3 extends self::_DwB3&C3&B {
+  synthetic constructor •() → self::DwB3
+    : super self::_DwB3&C3&B::•()
+    ;
+}
+abstract class _DwBq3&C3&Bq extends mix::C3 implements mix2::Bq /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwBq3&C3&Bq
+    : super mix::C3::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int?) → core::int?> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
+class DwBq3 extends self::_DwBq3&C3&Bq {
+  synthetic constructor •() → self::DwBq3
+    : super self::_DwBq3&C3&Bq::•()
+    ;
+}
+static method main() → dynamic {}
+
+library;
+import self as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class C0 extends mix2::B {
+  synthetic constructor •() → mix::C0*
+    : super mix2::B::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+class C3 extends mix2::Bq {
+  synthetic constructor •() → mix::C3*
+    : super mix2::Bq::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mix2;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → mix2::B
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set a(core::List<(core::int) → core::int> _) → void {}
+  method m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class Bq extends core::Object {
+  synthetic constructor •() → mix2::Bq
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set a(core::List<(core::int?) → core::int?> _) → void {}
+  method m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline.expect
new file mode 100644
index 0000000..3a5ba05
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import 'mixin_from_opt_in_out_in_lib1.dart';
+import 'mixin_from_opt_in_out_in_lib2.dart';
+
+class DiB0 extends C0 implements B {}
+
+class DiBq0 extends C0 implements Bq {}
+
+class DwB0 extends C0 with B {}
+
+class DwBq0 extends C0 with Bq {}
+
+class DiB3 extends C3 implements B {}
+
+class DiBq3 extends C3 implements Bq {}
+
+class DwB3 extends C3 with B {}
+
+class DwBq3 extends C3 with Bq {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b095d49
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+import 'mixin_from_opt_in_out_in_lib1.dart';
+import 'mixin_from_opt_in_out_in_lib2.dart';
+
+class DiB0 extends C0 implements B {}
+
+class DiB3 extends C3 implements B {}
+
+class DiBq0 extends C0 implements Bq {}
+
+class DiBq3 extends C3 implements Bq {}
+
+class DwB0 extends C0 with B {}
+
+class DwB3 extends C3 with B {}
+
+class DwBq0 extends C0 with Bq {}
+
+class DwBq3 extends C3 with Bq {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.weak.expect
new file mode 100644
index 0000000..fe1d001
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.weak.expect
@@ -0,0 +1,131 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "mixin_from_opt_in_out_in_lib1.dart" as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib1.dart";
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class DiB0 extends mix::C0 implements mix2::B {
+  synthetic constructor •() → self::DiB0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq0 extends mix::C0 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB0&C0&B = mix::C0 with mix2::B /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwB0&C0&B
+    : super mix::C0::•()
+    ;
+}
+class DwB0 extends self::_DwB0&C0&B {
+  synthetic constructor •() → self::DwB0
+    : super self::_DwB0&C0&B::•()
+    ;
+}
+abstract class _DwBq0&C0&Bq = mix::C0 with mix2::Bq /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwBq0&C0&Bq
+    : super mix::C0::•()
+    ;
+}
+class DwBq0 extends self::_DwBq0&C0&Bq {
+  synthetic constructor •() → self::DwBq0
+    : super self::_DwBq0&C0&Bq::•()
+    ;
+}
+class DiB3 extends mix::C3 implements mix2::B {
+  synthetic constructor •() → self::DiB3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq3 extends mix::C3 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB3&C3&B = mix::C3 with mix2::B /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwB3&C3&B
+    : super mix::C3::•()
+    ;
+}
+class DwB3 extends self::_DwB3&C3&B {
+  synthetic constructor •() → self::DwB3
+    : super self::_DwB3&C3&B::•()
+    ;
+}
+abstract class _DwBq3&C3&Bq = mix::C3 with mix2::Bq /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DwBq3&C3&Bq
+    : super mix::C3::•()
+    ;
+}
+class DwBq3 extends self::_DwBq3&C3&Bq {
+  synthetic constructor •() → self::DwBq3
+    : super self::_DwBq3&C3&Bq::•()
+    ;
+}
+static method main() → dynamic {}
+
+library;
+import self as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class C0 extends mix2::B {
+  synthetic constructor •() → mix::C0*
+    : super mix2::B::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+class C3 extends mix2::Bq {
+  synthetic constructor •() → mix::C3*
+    : super mix2::Bq::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mix2;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → mix2::B
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set a(core::List<(core::int) → core::int> _) → void {}
+  method m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class Bq extends core::Object {
+  synthetic constructor •() → mix2::Bq
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set a(core::List<(core::int?) → core::int?> _) → void {}
+  method m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.weak.transformed.expect
new file mode 100644
index 0000000..53ac2ec
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.weak.transformed.expect
@@ -0,0 +1,151 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "mixin_from_opt_in_out_in_lib1.dart" as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib1.dart";
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class DiB0 extends mix::C0 implements mix2::B {
+  synthetic constructor •() → self::DiB0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq0 extends mix::C0 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq0
+    : super mix::C0::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB0&C0&B extends mix::C0 implements mix2::B /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwB0&C0&B
+    : super mix::C0::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int) → core::int> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class DwB0 extends self::_DwB0&C0&B {
+  synthetic constructor •() → self::DwB0
+    : super self::_DwB0&C0&B::•()
+    ;
+}
+abstract class _DwBq0&C0&Bq extends mix::C0 implements mix2::Bq /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwBq0&C0&Bq
+    : super mix::C0::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int?) → core::int?> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
+class DwBq0 extends self::_DwBq0&C0&Bq {
+  synthetic constructor •() → self::DwBq0
+    : super self::_DwBq0&C0&Bq::•()
+    ;
+}
+class DiB3 extends mix::C3 implements mix2::B {
+  synthetic constructor •() → self::DiB3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int) → core::int>;
+  abstract member-signature set a(core::List<(core::int) → core::int> _) → void;
+  abstract member-signature method m((core::int) → core::int x) → (core::int) → core::int;
+}
+class DiBq3 extends mix::C3 implements mix2::Bq {
+  synthetic constructor •() → self::DiBq3
+    : super mix::C3::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int?) → core::int?>;
+  abstract member-signature set a(core::List<(core::int?) → core::int?> _) → void;
+  abstract member-signature method m((core::int?) → core::int? x) → (core::int?) → core::int?;
+}
+abstract class _DwB3&C3&B extends mix::C3 implements mix2::B /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwB3&C3&B
+    : super mix::C3::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int) → core::int> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class DwB3 extends self::_DwB3&C3&B {
+  synthetic constructor •() → self::DwB3
+    : super self::_DwB3&C3&B::•()
+    ;
+}
+abstract class _DwBq3&C3&Bq extends mix::C3 implements mix2::Bq /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_DwBq3&C3&Bq
+    : super mix::C3::•()
+    ;
+  get /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ a(core::List<(core::int?) → core::int?> _) → void {}
+  method /* from org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart */ m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
+class DwBq3 extends self::_DwBq3&C3&Bq {
+  synthetic constructor •() → self::DwBq3
+    : super self::_DwBq3&C3&Bq::•()
+    ;
+}
+static method main() → dynamic {}
+
+library;
+import self as mix;
+import "mixin_from_opt_in_out_in_lib2.dart" as mix2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///mixin_from_opt_in_out_in_lib2.dart";
+
+class C0 extends mix2::B {
+  synthetic constructor •() → mix::C0*
+    : super mix2::B::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+class C3 extends mix2::Bq {
+  synthetic constructor •() → mix::C3*
+    : super mix2::Bq::•()
+    ;
+  abstract member-signature get a() → core::List<(core::int*) →* core::int*>*;
+  abstract member-signature set a(core::List<(core::int*) →* core::int*>* _) → void;
+  abstract member-signature method m((core::int*) →* core::int* x) → (core::int*) →* core::int*;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mix2;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → mix2::B
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int) → core::int>
+    return <(core::int) → core::int>[];
+  set a(core::List<(core::int) → core::int> _) → void {}
+  method m((core::int) → core::int x) → (core::int) → core::int
+    return x;
+}
+class Bq extends core::Object {
+  synthetic constructor •() → mix2::Bq
+    : super core::Object::•()
+    ;
+  get a() → core::List<(core::int?) → core::int?>
+    return <(core::int?) → core::int?>[];
+  set a(core::List<(core::int?) → core::int?> _) → void {}
+  method m((core::int?) → core::int? x) → (core::int?) → core::int?
+    return x;
+}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in_lib1.dart b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in_lib1.dart
new file mode 100644
index 0000000..e08646b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in_lib1.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+import 'mixin_from_opt_in_out_in_lib2.dart';
+
+class C0 extends B {}
+
+class C3 extends Bq {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in_lib2.dart b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in_lib2.dart
new file mode 100644
index 0000000..55a1a29
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in_lib2.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..07b9747
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'mixin_from_opt_out_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07b9747
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'mixin_from_opt_out_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
 // Try changing type arguments so that they conform to the bounds.
 //   GenericNever<Null>();
 //   ^
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
 // Try changing type arguments so that they conform to the bounds.
 //   GenericNever<Null>();
 //   ^
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..9004607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class GenericNever<T extends Never> {
+  dynamic getParamType() => T;
+}
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9004607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class GenericNever<T extends Never> {
+  dynamic getParamType() => T;
+}
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
 // Try changing type arguments so that they conform to the bounds.
 //   GenericNever<Null>();
 //   ^
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
 // Try changing type arguments so that they conform to the bounds.
 //   GenericNever<Null>();
 //   ^
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect
index 83a210a..b3d52ba 100644
--- a/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect
@@ -102,7 +102,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
 //  - 'Type' is from 'dart:core'.
 //   Null get nullProperty => Null;
 //                            ^
@@ -127,7 +127,7 @@
   method nullMethod(core::Null? value) → core::Null?
     return value;
   get nullProperty() → core::Null?
-    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
  - 'Type' is from 'dart:core'.
   Null get nullProperty => Null;
                            ^" in core::Null? as{TypeError,ForNonNullableByDefault} core::Null?;
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..0630e92
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+// @dart = 2.6
+import 'never_opt_out_lib.dart';
+
+Never optOutNever;
+var inferredOptOutNever = optInNever;
+main() {}
+
+class B extends A {
+  Null neverField;
+  Null neverMethod(Null value) => value;
+  Null get neverProperty => null;
+  void set neverProperty(Null value) {}
+  Null nullField;
+  Null nullMethod(Null value) => value;
+  Null get nullProperty => null;
+  void set nullProperty(Null value) {}
+}
+
+class C extends A {
+  Never neverField;
+  Never neverMethod(Never value) => value;
+  Never get neverProperty => null;
+  void set neverProperty(Never value) {}
+  Never nullField;
+  Never nullMethod(Never value) => value;
+  Never get nullProperty => null;
+  void set nullProperty(Never value) {}
+}
+
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..26f5017
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,30 @@
+// @dart = 2.6
+import 'never_opt_out_lib.dart';
+
+Never optOutNever;
+
+class B extends A {
+  Null get neverProperty => null;
+  Null get nullProperty => null;
+  Null neverField;
+  Null neverMethod(Null value) => value;
+  Null nullField;
+  Null nullMethod(Null value) => value;
+  void set neverProperty(Null value) {}
+  void set nullProperty(Null value) {}
+}
+
+class C extends A {
+  Never get neverProperty => null;
+  Never get nullProperty => null;
+  Never neverField;
+  Never neverMethod(Never value) => value;
+  Never nullField;
+  Never nullMethod(Never value) => value;
+  void set neverProperty(Never value) {}
+  void set nullProperty(Never value) {}
+}
+
+main() {}
+throws(void Function() f) {}
+var inferredOptOutNever = optInNever;
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect
index 83a210a..b3d52ba 100644
--- a/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect
@@ -102,7 +102,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
 //  - 'Type' is from 'dart:core'.
 //   Null get nullProperty => Null;
 //                            ^
@@ -127,7 +127,7 @@
   method nullMethod(core::Null? value) → core::Null?
     return value;
   get nullProperty() → core::Null?
-    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+    return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
  - 'Type' is from 'dart:core'.
   Null get nullProperty => Null;
                            ^" in core::Null? as{TypeError,ForNonNullableByDefault} core::Null?;
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart b/pkg/front_end/testcases/nnbd/never_receiver.dart
index 61af20a..caf301bf 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart
@@ -21,6 +21,12 @@
   y?.[42]; // Not an error.
   y?.[42] = 42; // Not an error.
 
+  x?.foo(); // Warning.
+  x?.bar; // Warning.
+  x?.baz = 42; // Warning.
+  x?.[42]; // Warning.
+  x?.[42] = 42; // Warning.
+
   y.foo(); // Error.
   y.bar; // Error.
   y.baz = 42; // Error.
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
index 06d0203..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
@@ -2,72 +2,66 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:24:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.foo(); // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:25:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.bar; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:26:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.baz = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42]; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42] = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'foo'.
 //   y.foo(); // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
 //   y.bar; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.bar; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
 //   y.baz = 42; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.baz = 42; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //   y(); // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y++; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y++; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y += 1; // Error.
 //     ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y += 1; // Error.
-//     ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]' operator.
 //   y[42]; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-//   y[42]; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]=' operator.
 //   y[42] = 42; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-//   y[42] = 42; // Error.
-//    ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -82,55 +76,46 @@
   x.[]=(42, 42);
   x = x.+(1);
   x = x.+(1);
-  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
+  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{core::Null?} null : #t1{Never}.foo();
   let final Never? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
   let final Never? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
-  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
+  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{core::Null?} null : #t4{Never}.call();
   let final Never? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
   let final Never? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+  let final Never #t7 = x in #t7.{core::Object::==}(null) ?{core::Null?} null : #t7.foo();
+  let final Never #t8 = x in #t8.{core::Object::==}(null) ?{core::Null?} null : #t8.bar;
+  let final Never #t9 = x in #t9.{core::Object::==}(null) ?{core::int?} null : #t9.baz = 42;
+  let final Never #t10 = x in #t10.{core::Object::==}(null) ?{core::Null?} null : #t10.[](42);
+  let final Never #t11 = x in #t11.{core::Object::==}(null) ?{core::int?} null : #t11.[]=(42, 42);
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'foo'.
   y.foo(); // Error.
     ^^^";
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.bar; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
   y.bar; // Error.
     ^^^";
-  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.baz = 42; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
   y.baz = 42; // Error.
     ^^^";
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   y(); // Error.
    ^";
-  y = (let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y++; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y++; // Error.
-   ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  y = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y += 1; // Error.
-    ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y += 1; // Error.
-    ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-  y[42]; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+    ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]' operator.
   y[42]; // Error.
    ^";
-  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-  y[42] = 42; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]=' operator.
   y[42] = 42; // Error.
    ^";
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
index 06d0203..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
@@ -2,72 +2,66 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:24:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.foo(); // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:25:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.bar; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:26:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.baz = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42]; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42] = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'foo'.
 //   y.foo(); // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
 //   y.bar; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.bar; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
 //   y.baz = 42; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.baz = 42; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //   y(); // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y++; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y++; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y += 1; // Error.
 //     ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y += 1; // Error.
-//     ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]' operator.
 //   y[42]; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-//   y[42]; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]=' operator.
 //   y[42] = 42; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-//   y[42] = 42; // Error.
-//    ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -82,55 +76,46 @@
   x.[]=(42, 42);
   x = x.+(1);
   x = x.+(1);
-  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
+  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{core::Null?} null : #t1{Never}.foo();
   let final Never? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
   let final Never? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
-  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
+  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{core::Null?} null : #t4{Never}.call();
   let final Never? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
   let final Never? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+  let final Never #t7 = x in #t7.{core::Object::==}(null) ?{core::Null?} null : #t7.foo();
+  let final Never #t8 = x in #t8.{core::Object::==}(null) ?{core::Null?} null : #t8.bar;
+  let final Never #t9 = x in #t9.{core::Object::==}(null) ?{core::int?} null : #t9.baz = 42;
+  let final Never #t10 = x in #t10.{core::Object::==}(null) ?{core::Null?} null : #t10.[](42);
+  let final Never #t11 = x in #t11.{core::Object::==}(null) ?{core::int?} null : #t11.[]=(42, 42);
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'foo'.
   y.foo(); // Error.
     ^^^";
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.bar; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
   y.bar; // Error.
     ^^^";
-  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.baz = 42; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
   y.baz = 42; // Error.
     ^^^";
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   y(); // Error.
    ^";
-  y = (let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y++; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y++; // Error.
-   ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  y = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y += 1; // Error.
-    ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y += 1; // Error.
-    ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-  y[42]; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+    ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]' operator.
   y[42]; // Error.
    ^";
-  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-  y[42] = 42; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]=' operator.
   y[42] = 42; // Error.
    ^";
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline.expect
new file mode 100644
index 0000000..741b909
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo(Never x, Never? y) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..741b909
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo(Never x, Never? y) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
index 06d0203..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
@@ -2,72 +2,66 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:24:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.foo(); // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:25:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.bar; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:26:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.baz = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42]; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42] = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'foo'.
 //   y.foo(); // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
 //   y.bar; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.bar; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
 //   y.baz = 42; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.baz = 42; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //   y(); // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y++; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y++; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y += 1; // Error.
 //     ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y += 1; // Error.
-//     ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]' operator.
 //   y[42]; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-//   y[42]; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]=' operator.
 //   y[42] = 42; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-//   y[42] = 42; // Error.
-//    ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -82,55 +76,46 @@
   x.[]=(42, 42);
   x = x.+(1);
   x = x.+(1);
-  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
+  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{core::Null?} null : #t1{Never}.foo();
   let final Never? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
   let final Never? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
-  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
+  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{core::Null?} null : #t4{Never}.call();
   let final Never? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
   let final Never? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+  let final Never #t7 = x in #t7.{core::Object::==}(null) ?{core::Null?} null : #t7.foo();
+  let final Never #t8 = x in #t8.{core::Object::==}(null) ?{core::Null?} null : #t8.bar;
+  let final Never #t9 = x in #t9.{core::Object::==}(null) ?{core::int?} null : #t9.baz = 42;
+  let final Never #t10 = x in #t10.{core::Object::==}(null) ?{core::Null?} null : #t10.[](42);
+  let final Never #t11 = x in #t11.{core::Object::==}(null) ?{core::int?} null : #t11.[]=(42, 42);
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'foo'.
   y.foo(); // Error.
     ^^^";
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.bar; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
   y.bar; // Error.
     ^^^";
-  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.baz = 42; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
   y.baz = 42; // Error.
     ^^^";
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   y(); // Error.
    ^";
-  y = (let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y++; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y++; // Error.
-   ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  y = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y += 1; // Error.
-    ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y += 1; // Error.
-    ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-  y[42]; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+    ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]' operator.
   y[42]; // Error.
    ^";
-  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-  y[42] = 42; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]=' operator.
   y[42] = 42; // Error.
    ^";
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
index 06d0203..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
@@ -2,72 +2,66 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:24:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.foo(); // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:25:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.bar; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:26:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.baz = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42]; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
+//   x?.[42] = 42; // Warning.
+//   ^
+//
+// pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'foo'.
 //   y.foo(); // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
 //   y.bar; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.bar; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
 //   y.baz = 42; // Error.
 //     ^^^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-//   y.baz = 42; // Error.
-//     ^^^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //   y(); // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y++; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y++; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '+' operator.
 //   y += 1; // Error.
 //     ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-//   y += 1; // Error.
-//     ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]' operator.
 //   y[42]; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-//   y[42]; // Error.
-//    ^
-//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 // Try correcting the operator to an existing operator, or defining a '[]=' operator.
 //   y[42] = 42; // Error.
 //    ^
 //
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-//   y[42] = 42; // Error.
-//    ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -82,55 +76,46 @@
   x.[]=(42, 42);
   x = x.+(1);
   x = x.+(1);
-  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
+  let final Never? #t1 = y in #t1.{core::Object::==}(null) ?{core::Null?} null : #t1{Never}.foo();
   let final Never? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
   let final Never? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
-  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
+  let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{core::Null?} null : #t4{Never}.call();
   let final Never? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
   let final Never? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
+  let final Never #t7 = x in #t7.{core::Object::==}(null) ?{core::Null?} null : #t7.foo();
+  let final Never #t8 = x in #t8.{core::Object::==}(null) ?{core::Null?} null : #t8.bar;
+  let final Never #t9 = x in #t9.{core::Object::==}(null) ?{core::int?} null : #t9.baz = 42;
+  let final Never #t10 = x in #t10.{core::Object::==}(null) ?{core::Null?} null : #t10.[](42);
+  let final Never #t11 = x in #t11.{core::Object::==}(null) ?{core::int?} null : #t11.[]=(42, 42);
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'foo'.
   y.foo(); // Error.
     ^^^";
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.bar; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
   y.bar; // Error.
     ^^^";
-  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
-  y.baz = 42; // Error.
-    ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
   y.baz = 42; // Error.
     ^^^";
-  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   y(); // Error.
    ^";
-  y = (let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y++; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The operator '+' isn't defined for the class 'Never'.
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y++; // Error.
-   ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  y = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-  y += 1; // Error.
-    ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The operator '+' isn't defined for the class 'Never'.
+   ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '+' operator.
   y += 1; // Error.
-    ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
-  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-  y[42]; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The operator '[]' isn't defined for the class 'Never'.
+    ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]' operator.
   y[42]; // Error.
    ^";
-  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-  y[42] = 42; // Error.
-   ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+  invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
 Try correcting the operator to an existing operator, or defining a '[]=' operator.
   y[42] = 42; // Error.
    ^";
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline.expect
new file mode 100644
index 0000000..339b98f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.4
+class late {
+  int get g => 1;
+}
+
+class required {
+  int get g => 2;
+}
+
+class C {
+  late l = late();
+  required r = required();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2ef980b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.4
+class C {
+  late l = late();
+  required r = required();
+}
+
+class late {
+  int get g => 1;
+}
+
+class required {
+  int get g => 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline.expect
new file mode 100644
index 0000000..890940b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.4
+// @dart = 2.8
+class late {
+  int get g => 1;
+}
+
+class required {
+  int get g => 2;
+}
+
+class C {
+  late l = late();
+  required r = required();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ad8c9f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.4
+// @dart = 2.8
+class C {
+  late l = late();
+  required r = required();
+}
+
+class late {
+  int get g => 1;
+}
+
+class required {
+  int get g => 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline.expect
new file mode 100644
index 0000000..6a4cb41
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Class {
+  Class field;
+  Class method() => field;
+  Class operator [](Class key) => field;
+  void operator []=(Class key, Class value) {}
+  Class operator +(int value) => field;
+  Class operator -() => field;
+}
+
+main() {}
+void propertyAccess(Class c) {}
+void indexAccess(Class c) {}
+void operatorAccess(Class c) {}
+void ifNull(Class c) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e31843
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Class {
+  Class field;
+  Class method() => field;
+  Class operator +(int value) => field;
+  Class operator -() => field;
+  Class operator [](Class key) => field;
+  void operator []=(Class key, Class value) {}
+}
+
+main() {}
+void ifNull(Class c) {}
+void indexAccess(Class c) {}
+void operatorAccess(Class c) {}
+void propertyAccess(Class c) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting_explicit_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_null_shorting_explicit_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..7fdf2c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting_explicit_extension.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class Class {
+  Class _field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
+void propertyAccess(Class c) { }
+void indexAccess(Class c) { }
+void operatorAccess(Class c) { }
+void ifNull(Class c) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_null_shorting_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..7fdf2c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting_extension.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class Class {
+  Class _field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
+void propertyAccess(Class c) { }
+void indexAccess(Class c) { }
+void operatorAccess(Class c) { }
+void ifNull(Class c) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
new file mode 100644
index 0000000..bceca95
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
@@ -0,0 +1,71 @@
+class Foo {
+}
+int topLevelField;
+class A {
+  static int staticFieldOfA;
+  int fieldOfA;
+  A.foo();
+  A.bar(this.fieldOfA);
+}
+class B<X extends Object?, Y extends Object> {
+  X fieldOfB;
+  Y fieldOfB2;
+  B.foo();
+  B.bar(this.fieldOfB, this.fieldOfB2);
+}
+mixin M {
+  static int staticFieldOfM;
+  int fieldOfM;
+}
+mixin N<X extends Object?, Y extends Object> {
+  X fieldOfN;
+  Y fieldOfN2;
+}
+extension P ;
+on Foo (){ }
+int? nullableTopLevelField;
+late int ;
+lateTopLevelField;
+int topLevelFieldWithInitializer = 42;
+class C<X extends Object?, Y extends Object> {
+  static int? staticFieldOfX;
+  static int staticFieldOfXInitialized = 42;
+  X? fieldOfX;
+  int? fieldOfX2;
+  dynamic fieldOfX3;
+  Null fieldOfX4;
+  int Function()? fieldOfX5;
+  Y? fieldOfX6;
+  static late int ;
+  lateStaticFieldOfC;
+  late int ;
+  fieldOfC7;
+  late X ;
+  fieldOfC8;
+  late Y ;
+  fieldOfC9;
+  int fieldOfC10;
+  C.foo(this.fieldOfC10);
+  C.bar(this.fieldOfC10);
+}
+mixin L<X extends Object?, Y extends Object> {
+  static int? staticFieldOfL;
+  static int staticFieldOfLInitialized = 42;
+  X? fieldOfL;
+  int? fieldOfL2;
+  dynamic fieldOfL3;
+  Null fieldOfL4;
+  int Function()? fieldOfL5;
+  Y? fieldOfL6;
+  static late int ;
+  lateStaticFieldOfM;
+  late int ;
+  fieldOfM7;
+  late X ;
+  fieldOfM8;
+  late Y ;
+  fieldOfM9;
+}
+extension Q ;
+on Foo (){ }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline.expect
new file mode 100644
index 0000000..14da563
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+part 'non_nullable_optional_part.dart';
+
+main() {}
+method1({int a}) {}
+method2([int a]) {}
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14da563
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+part 'non_nullable_optional_part.dart';
+
+main() {}
+method1({int a}) {}
+method2([int a]) {}
diff --git a/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..b52ce01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+abstract class A<T> {
+  T baz();
+  bar(T value) {}
+  barInt(int value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b52ce01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+abstract class A<T> {
+  T baz();
+  bar(T value) {}
+  barInt(int value) {}
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart
index fa74007..8452c473 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart
@@ -6,6 +6,13 @@
 
 import 'nsm_from_opt_in_lib.dart';
 
+abstract class A2 implements A {
+  @override
+  noSuchMethod(Invocation invocation) {
+    return super.noSuchMethod(invocation);
+  }
+}
+
 abstract class B2 extends A implements C2 {
   @override
   noSuchMethod(Invocation invocation) {
@@ -15,6 +22,9 @@
 
 abstract class C2 {
   int method(int i, {optional});
+  T genericMethod1<T>(T t);
+  T genericMethod2<T extends Object>(T t);
+  T genericMethod3<T extends Object>(T t);
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect
index 00778a8..aff6f51 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect
@@ -1,10 +1,21 @@
 library;
 import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
 import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
 
 import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
 
+abstract class A2 extends core::Object implements nsm::A {
+  synthetic constructor •() → self::A2*
+    ;
+  @core::override
+  method noSuchMethod(core::Invocation* invocation) → dynamic
+    ;
+  abstract member-signature method method(core::int* i) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
 abstract class B2 extends nsm::A implements self::C2 {
   synthetic constructor •() → self::B2*
     ;
@@ -12,11 +23,17 @@
   method noSuchMethod(core::Invocation* invocation) → dynamic
     ;
   abstract forwarding-stub method method(core::int* i, {dynamic optional}) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
 }
 abstract class C2 extends core::Object {
   synthetic constructor •() → self::C2*
     ;
   abstract method method(core::int* i, {dynamic optional}) → core::int*;
+  abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+  abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+  abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
 }
 static method main() → dynamic
   ;
@@ -30,6 +47,12 @@
     ;
   method method(core::int? i) → core::int
     ;
+  method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+    ;
+  method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+    ;
+  method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+    ;
 }
 abstract class B1 extends nsm::A implements nsm::C1 {
   synthetic constructor •() → nsm::B1
@@ -43,4 +66,7 @@
   synthetic constructor •() → nsm::C1
     ;
   abstract method method(core::int? i, {dynamic optional}) → core::int;
+  abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+  abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+  abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
 }
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect
@@ -1,10 +1,23 @@
 library;
 import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
 import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
 
 import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
 
+abstract class A2 extends core::Object implements nsm::A {
+  synthetic constructor •() → self::A2*
+    : super core::Object::•()
+    ;
+  @#C1
+  method noSuchMethod(core::Invocation* invocation) → dynamic {
+    return super.{core::Object::noSuchMethod}(invocation);
+  }
+  abstract member-signature method method(core::int* i) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
 abstract class B2 extends nsm::A implements self::C2 {
   synthetic constructor •() → self::B2*
     : super nsm::A::•()
@@ -14,12 +27,18 @@
     return super.{core::Object::noSuchMethod}(invocation);
   }
   abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
 }
 abstract class C2 extends core::Object {
   synthetic constructor •() → self::C2*
     : super core::Object::•()
     ;
   abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+  abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+  abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
 }
 static method main() → dynamic {}
 
@@ -33,6 +52,12 @@
     ;
   method method(core::int? i) → core::int
     return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+  method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+    return t;
+  method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+    return t;
+  method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+    return t;
 }
 abstract class B1 extends nsm::A implements nsm::C1 {
   synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
     : super core::Object::•()
     ;
   abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+  abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+  abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+  abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect
@@ -1,10 +1,23 @@
 library;
 import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
 import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
 
 import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
 
+abstract class A2 extends core::Object implements nsm::A {
+  synthetic constructor •() → self::A2*
+    : super core::Object::•()
+    ;
+  @#C1
+  method noSuchMethod(core::Invocation* invocation) → dynamic {
+    return super.{core::Object::noSuchMethod}(invocation);
+  }
+  abstract member-signature method method(core::int* i) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
 abstract class B2 extends nsm::A implements self::C2 {
   synthetic constructor •() → self::B2*
     : super nsm::A::•()
@@ -14,12 +27,18 @@
     return super.{core::Object::noSuchMethod}(invocation);
   }
   abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
 }
 abstract class C2 extends core::Object {
   synthetic constructor •() → self::C2*
     : super core::Object::•()
     ;
   abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+  abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+  abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
 }
 static method main() → dynamic {}
 
@@ -33,6 +52,12 @@
     ;
   method method(core::int? i) → core::int
     return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+  method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+    return t;
+  method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+    return t;
+  method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+    return t;
 }
 abstract class B1 extends nsm::A implements nsm::C1 {
   synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
     : super core::Object::•()
     ;
   abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+  abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+  abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+  abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..2c1d4b5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+import 'nsm_from_opt_in_lib.dart';
+
+abstract class A2 implements A {
+  @override
+  noSuchMethod(Invocation invocation) {}
+}
+
+abstract class B2 extends A implements C2 {
+  @override
+  noSuchMethod(Invocation invocation) {}
+}
+
+abstract class C2 {
+  int method(int i, {optional});
+  T genericMethod1<T>(T t);
+  T genericMethod2<T extends Object>(T t);
+  T genericMethod3<T extends Object>(T t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b08f82b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+import 'nsm_from_opt_in_lib.dart';
+
+abstract class A2 implements A {
+  @override
+  noSuchMethod(Invocation invocation) {}
+}
+
+abstract class B2 extends A implements C2 {
+  @override
+  noSuchMethod(Invocation invocation) {}
+}
+
+abstract class C2 {
+  T genericMethod1<T>(T t);
+  T genericMethod2<T extends Object>(T t);
+  T genericMethod3<T extends Object>(T t);
+  int method(int i, {optional});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect
@@ -1,10 +1,23 @@
 library;
 import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
 import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
 
 import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
 
+abstract class A2 extends core::Object implements nsm::A {
+  synthetic constructor •() → self::A2*
+    : super core::Object::•()
+    ;
+  @#C1
+  method noSuchMethod(core::Invocation* invocation) → dynamic {
+    return super.{core::Object::noSuchMethod}(invocation);
+  }
+  abstract member-signature method method(core::int* i) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
 abstract class B2 extends nsm::A implements self::C2 {
   synthetic constructor •() → self::B2*
     : super nsm::A::•()
@@ -14,12 +27,18 @@
     return super.{core::Object::noSuchMethod}(invocation);
   }
   abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
 }
 abstract class C2 extends core::Object {
   synthetic constructor •() → self::C2*
     : super core::Object::•()
     ;
   abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+  abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+  abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
 }
 static method main() → dynamic {}
 
@@ -33,6 +52,12 @@
     ;
   method method(core::int? i) → core::int
     return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+  method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+    return t;
+  method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+    return t;
+  method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+    return t;
 }
 abstract class B1 extends nsm::A implements nsm::C1 {
   synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
     : super core::Object::•()
     ;
   abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+  abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+  abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+  abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect
@@ -1,10 +1,23 @@
 library;
 import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
 import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
 
 import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
 
+abstract class A2 extends core::Object implements nsm::A {
+  synthetic constructor •() → self::A2*
+    : super core::Object::•()
+    ;
+  @#C1
+  method noSuchMethod(core::Invocation* invocation) → dynamic {
+    return super.{core::Object::noSuchMethod}(invocation);
+  }
+  abstract member-signature method method(core::int* i) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
 abstract class B2 extends nsm::A implements self::C2 {
   synthetic constructor •() → self::B2*
     : super nsm::A::•()
@@ -14,12 +27,18 @@
     return super.{core::Object::noSuchMethod}(invocation);
   }
   abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+  abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+  abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
 }
 abstract class C2 extends core::Object {
   synthetic constructor •() → self::C2*
     : super core::Object::•()
     ;
   abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+  abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+  abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+  abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
 }
 static method main() → dynamic {}
 
@@ -33,6 +52,12 @@
     ;
   method method(core::int? i) → core::int
     return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+  method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+    return t;
+  method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+    return t;
+  method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+    return t;
 }
 abstract class B1 extends nsm::A implements nsm::C1 {
   synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
     : super core::Object::•()
     ;
   abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+  abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+  abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+  abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart b/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart
index 20d29b9..3b74079 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart
@@ -4,6 +4,9 @@
 
 class A {
   int method(int? i) => i ?? 0;
+  T genericMethod1<T>(T t) => t;
+  T genericMethod2<T extends Object?>(T t) => t;
+  T genericMethod3<T extends Object>(T t) => t;
 }
 
 abstract class B1 extends A implements C1 {
@@ -15,4 +18,7 @@
 
 abstract class C1 {
   int method(int? i, {optional});
+  T genericMethod1<T>(T t);
+  T genericMethod2<T extends Object?>(T t);
+  T genericMethod3<T extends Object>(T t);
 }
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline.expect
new file mode 100644
index 0000000..69042fc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class {
+  int nonNullableField = 0;
+  int? nullableField;
+  int operator [](int key) => key;
+  void operator []=(int key, int value) {}
+  Class get nonNullableClass => this;
+  Class call() => this;
+  NullableIndexClass get nonNullableNullableIndexClass => NullableIndexClass();
+}
+
+class NullableIndexClass {
+  int? operator [](int key) => key;
+  void operator []=(int key, int value) {}
+}
+
+main() {}
+errors(Class? nullableClass, Class nonNullableClass, int? nullableInt,
+    int nonNullableInt, NullableIndexClass? nullableNullableIndexClass) {}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..849bf32
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class Class {
+  Class call() => this;
+  Class get nonNullableClass => this;
+  NullableIndexClass get nonNullableNullableIndexClass => NullableIndexClass();
+  int nonNullableField = 0;
+  int operator [](int key) => key;
+  int? nullableField;
+  void operator []=(int key, int value) {}
+}
+
+class NullableIndexClass {
+  int? operator [](int key) => key;
+  void operator []=(int key, int value) {}
+}
+
+errors(Class? nullableClass, Class nonNullableClass, int? nullableInt,
+    int nonNullableInt, NullableIndexClass? nullableNullableIndexClass) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline.expect
new file mode 100644
index 0000000..2215727
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class Class {
+  Class get getter1 => this;
+  Class? get getter2 => field;
+  Class? field;
+  Class([this.field]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f928776
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Class {
+  Class get getter1 => this;
+  Class([this.field]);
+  Class? field;
+  Class? get getter2 => field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline.expect
new file mode 100644
index 0000000..e1ed616
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+  int? field;
+  int? method() => field;
+  Class operator +(Class other) => new Class();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fb8764d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Class {
+  Class operator +(Class other) => new Class();
+  int? field;
+  int? method() => field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline.expect
new file mode 100644
index 0000000..770d7e9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+abstract class A {
+  T bar<T>();
+  String foo() => bar()!;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c26a712
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+abstract class A {
+  String foo() => bar()!;
+  T bar<T>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline.expect
new file mode 100644
index 0000000..9527be1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline.expect
@@ -0,0 +1,39 @@
+class Class1 {
+  Class1? get property => null;
+  void set property(Class1? value) {}
+  Class1 get property1 => new Class1();
+  Class2 get property2 => new Class2();
+  Class1? get nullable1 => property1;
+  void set nullable1(Class1? value) {}
+  Class1 nonNullable1Method() => nonNullable1;
+  Class1? operator [](Class1? key) => nullable1;
+  void operator []=(Class1? key, Class1? value) {}
+  Class1? operator +(int value) => nullable1;
+  Class1? operator -() => nullable1;
+  Class1 get nonNullable1 => property1;
+  Class2 get nonNullable2 => property2;
+}
+
+class Class2 {
+  Class2 get property => this;
+  void set property(Class2 value) {}
+  Class2 nonNullable2Method() => nonNullable2;
+  Class2 operator [](Class2? key) => property;
+  void operator []=(Class2? key, Class2? value) => property;
+  Class2 operator +(int value) => property;
+  Class2 operator -() => property;
+  Class2 get nonNullable2 => property;
+  void set nonNullable2(Class2 value) {}
+}
+
+class Class3 {
+  Class2? get property => null;
+  Class2? operator [](Class3? key) => property;
+}
+
+main() {}
+void propertyAccess(Class1? n1) {}
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
+void operatorAccess(Class1? n1, Class2? n2) {}
+void ifNull(Class1? n1) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99a428a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline_modelled.expect
@@ -0,0 +1,39 @@
+class Class1 {
+  Class1 get nonNullable1 => property1;
+  Class1 get property1 => new Class1();
+  Class1 nonNullable1Method() => nonNullable1;
+  Class1? get nullable1 => property1;
+  Class1? get property => null;
+  Class1? operator +(int value) => nullable1;
+  Class1? operator -() => nullable1;
+  Class1? operator [](Class1? key) => nullable1;
+  Class2 get nonNullable2 => property2;
+  Class2 get property2 => new Class2();
+  void operator []=(Class1? key, Class1? value) {}
+  void set nullable1(Class1? value) {}
+  void set property(Class1? value) {}
+}
+
+class Class2 {
+  Class2 get nonNullable2 => property;
+  Class2 get property => this;
+  Class2 nonNullable2Method() => nonNullable2;
+  Class2 operator +(int value) => property;
+  Class2 operator -() => property;
+  Class2 operator [](Class2? key) => property;
+  void operator []=(Class2? key, Class2? value) => property;
+  void set nonNullable2(Class2 value) {}
+  void set property(Class2 value) {}
+}
+
+class Class3 {
+  Class2? get property => null;
+  Class2? operator [](Class3? key) => property;
+}
+
+main() {}
+void ifNull(Class1? n1) {}
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
+void operatorAccess(Class1? n1, Class2? n2) {}
+void propertyAccess(Class1? n1) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..fded929
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+  Class method() => this;
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..40fda8b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class Class1 {
+  Class1? get property => null;
+  void set property(Class1? value) { }
+  Class1 get property1 => new Class1();
+  Class2 get property2 => new Class2();
+}
+extension Extension1 ;
+on Class1 (){ }
+class Class2 {
+  Class2 get property => this;
+  void set property(Class2 value) { }
+}
+extension Extension2 ;
+on Class2 (){ }
+class Class3 {
+  Class2? get property => null;
+}
+extension Extension3 ;
+on Class3 (){ }
+main() { }
+void propertyAccess(Class1? n1) { }
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) { }
+void operatorAccess(Class1? n1, Class2? n2) { }
+void ifNull(Class1? n1) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..40fda8b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class Class1 {
+  Class1? get property => null;
+  void set property(Class1? value) { }
+  Class1 get property1 => new Class1();
+  Class2 get property2 => new Class2();
+}
+extension Extension1 ;
+on Class1 (){ }
+class Class2 {
+  Class2 get property => this;
+  void set property(Class2 value) { }
+}
+extension Extension2 ;
+on Class2 (){ }
+class Class3 {
+  Class2? get property => null;
+}
+extension Extension3 ;
+on Class3 (){ }
+main() { }
+void propertyAccess(Class1? n1) { }
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) { }
+void operatorAccess(Class1? n1, Class2? n2) { }
+void ifNull(Class1? n1) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
new file mode 100644
index 0000000..3e754ed
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class1 {
+  Class2? get field => null;
+  int operator [](int index) => index;
+  void operator []=(int index, int value) { }
+}
+class Class2 {
+  int field = 42;
+}
+extension Extension ;
+on Class2 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline.expect
new file mode 100644
index 0000000..a391c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class Class {
+  A nonNullableField = const A();
+  A get nonNullableProperty => nonNullableField;
+  void set nonNullableProperty(A value) {}
+  A nonNullableMethod() => nonNullableField;
+}
+
+class A {
+  const A();
+  A get nonNullableProperty => this;
+}
+
+main() {}
+expect(expected, actual) {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eed27fc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {
+  A get nonNullableProperty => this;
+  const A();
+}
+
+class Class {
+  A get nonNullableProperty => nonNullableField;
+  A nonNullableField = const A();
+  A nonNullableMethod() => nonNullableField;
+  void set nonNullableProperty(A value) {}
+}
+
+expect(expected, actual) {}
+main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline.expect
new file mode 100644
index 0000000..24bba59
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A<X> {}
+
+class B extends A<Null> {}
+
+class C {
+  Null foo(Null n, A<Null> an) => n;
+}
+
+foo() {}
+bar() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..604b26f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+bar() {}
+
+class A<X> {}
+
+class B extends A<Null> {}
+
+class C {
+  Null foo(Null n, A<Null> an) => n;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart b/pkg/front_end/testcases/nnbd/nullable_object_access.dart
new file mode 100644
index 0000000..82729ce
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class CustomType extends Type {
+  void call() {}
+}
+
+abstract class CustomInvocation implements Invocation {}
+
+abstract class Class {
+  CustomType get runtimeType;
+  String noSuchMethod(covariant CustomInvocation invocation);
+  bool operator ==(covariant Class o);
+  String toString({Object o});
+}
+
+main() {}
+
+void test(Class c1, Class? c2, Invocation invocation,
+    CustomInvocation customInvocation) {
+  CustomType runtimeType1 = c1.runtimeType; // ok
+  var runtimeTypeVariable1 = c1.runtimeType;
+  c1.runtimeType(); // ok
+
+  String Function(CustomInvocation) noSuchMethodTearOff1 =
+      c1.noSuchMethod; // ok
+  var noSuchMethodTearOffVariable1 = c1.noSuchMethod;
+
+  String noSuchMethod1a = c1.noSuchMethod(customInvocation); // ok
+  String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+  var noSuchMethodVariable1 = c1.noSuchMethod(customInvocation);
+
+  c1 == ''; // error
+  c1 == c2; // ok
+
+  String Function({Object o}) toStringTearOff1 = c1.toString; // ok
+  var toStringTearOffVariable1 = c1.toString;
+
+  c1.toString(o: c1); // ok
+
+  CustomType runtimeType2 = c2.runtimeType; // error
+  var runtimeTypeVariable2 = c2.runtimeType;
+  c2.runtimeType(); // error
+
+  String Function(CustomInvocation) noSuchMethodTearOff2 =
+      c2.noSuchMethod; // error
+  var noSuchMethodTearOffVariable2 = c2.noSuchMethod;
+
+  int noSuchMethod2 = c2.noSuchMethod(invocation); // ok
+  var noSuchMethodVariable2 = c2.noSuchMethod(invocation);
+
+  // TODO(johnniwinther): Awaiting spec update about `==`. Before NNBD this
+  // would cause an error but with the current (insufficient) specification for
+  // `==` it is ok (even though `c1 == ''` is an error).
+  c2 == ''; // ok or error?
+  c2 == c1; // ok
+
+  String Function({Object o}) toStringTearOff2 = c2.toString; // error
+  var toStringTearOffVariable2 = c2.toString;
+
+  c2.toString(o: c1); // error
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.outline.expect
new file mode 100644
index 0000000..f472974
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class CustomType extends core::Type {
+  synthetic constructor •() → self::CustomType
+    ;
+  method call() → void
+    ;
+}
+abstract class CustomInvocation extends core::Object implements core::Invocation {
+  synthetic constructor •() → self::CustomInvocation
+    ;
+}
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  abstract get runtimeType() → self::CustomType;
+  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant self::CustomInvocation invocation) → core::String
+    return super.{core::Object::noSuchMethod}(invocation);
+  forwarding-stub forwarding-semi-stub operator ==(covariant self::Class o) → core::bool
+    return super.{core::Object::==}(o);
+  abstract method toString({core::Object o}) → core::String;
+}
+static method main() → dynamic
+  ;
+static method test(self::Class c1, self::Class? c2, core::Invocation invocation, self::CustomInvocation customInvocation) → void
+  ;
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
new file mode 100644
index 0000000..ec3535f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
@@ -0,0 +1,127 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   c1 == ''; // error
+//         ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+//  - 'Type' is from 'dart:core'.
+//  - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   CustomType runtimeType2 = c2.runtimeType; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+//   c2.runtimeType(); // error
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//       c2.noSuchMethod; // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   c2 == ''; // ok or error?
+//         ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+//  - 'Object' is from 'dart:core'.
+//   String Function({Object o}) toStringTearOff2 = c2.toString; // error
+//                                                     ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
+//   c2.toString(o: c1); // error
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class CustomType extends core::Type {
+  synthetic constructor •() → self::CustomType
+    : super core::Type::•()
+    ;
+  method call() → void {}
+}
+abstract class CustomInvocation extends core::Object implements core::Invocation {
+  synthetic constructor •() → self::CustomInvocation
+    : super core::Object::•()
+    ;
+}
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract get runtimeType() → self::CustomType;
+  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant self::CustomInvocation invocation) → core::String
+    return super.{core::Object::noSuchMethod}(invocation);
+  forwarding-stub forwarding-semi-stub operator ==(covariant self::Class o) → core::bool
+    return super.{core::Object::==}(o);
+  abstract method toString({core::Object o = #C1}) → core::String;
+}
+static method main() → dynamic {}
+static method test(self::Class c1, self::Class? c2, core::Invocation invocation, self::CustomInvocation customInvocation) → void {
+  self::CustomType runtimeType1 = c1.{self::Class::runtimeType};
+  self::CustomType runtimeTypeVariable1 = c1.{self::Class::runtimeType};
+  c1.{self::Class::runtimeType}.{self::CustomType::call}();
+  (self::CustomInvocation) → core::String noSuchMethodTearOff1 = c1.{self::Class::noSuchMethod};
+  (self::CustomInvocation) → core::String noSuchMethodTearOffVariable1 = c1.{self::Class::noSuchMethod};
+  core::String noSuchMethod1a = c1.{self::Class::noSuchMethod}(customInvocation);
+  core::String noSuchMethod1b = c1.{self::Class::noSuchMethod}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+                                          ^" in invocation as{TypeError,ForNonNullableByDefault} self::CustomInvocation);
+  core::String noSuchMethodVariable1 = c1.{self::Class::noSuchMethod}(customInvocation);
+  c1.{self::Class::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  c1 == ''; // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+  c1.{self::Class::==}(c2);
+  ({o: core::Object}) → core::String toStringTearOff1 = c1.{self::Class::toString};
+  ({o: core::Object}) → core::String toStringTearOffVariable1 = c1.{self::Class::toString};
+  c1.{self::Class::toString}(o: c1);
+  self::CustomType runtimeType2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+ - 'Type' is from 'dart:core'.
+ - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  CustomType runtimeType2 = c2.runtimeType; // error
+                               ^" in c2.{core::Object::runtimeType} as{TypeError,ForNonNullableByDefault} self::CustomType;
+  core::Type runtimeTypeVariable2 = c2.{core::Object::runtimeType};
+  invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+  c2.runtimeType(); // error
+                ^^^^^^^^^^^";
+  (self::CustomInvocation) → core::String noSuchMethodTearOff2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+      c2.noSuchMethod; // error
+         ^" in c2.{core::Object::noSuchMethod} as{TypeError,ForNonNullableByDefault} (self::CustomInvocation) → core::String;
+  (core::Invocation) → dynamic noSuchMethodTearOffVariable2 = c2.{core::Object::noSuchMethod};
+  core::int noSuchMethod2 = c2.{core::Object::noSuchMethod}(invocation) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+  dynamic noSuchMethodVariable2 = c2.{core::Object::noSuchMethod}(invocation);
+  c2.{self::Class::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  c2 == ''; // ok or error?
+        ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+  c2.{self::Class::==}(c1);
+  ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+ - 'Object' is from 'dart:core'.
+  String Function({Object o}) toStringTearOff2 = c2.toString; // error
+                                                    ^" in c2.{core::Object::toString} as{TypeError,ForNonNullableByDefault} ({o: core::Object}) → core::String;
+  () → core::String toStringTearOffVariable2 = c2.{core::Object::toString};
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
+  c2.toString(o: c1); // error
+              ^" in c2.{core::Object::toString}(o: c1);
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..81b9a41
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect
@@ -0,0 +1,123 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   c1 == ''; // error
+//         ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+//  - 'Type' is from 'dart:core'.
+//  - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   CustomType runtimeType2 = c2.runtimeType; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+//   c2.runtimeType(); // error
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//       c2.noSuchMethod; // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+//  - 'Object' is from 'dart:core'.
+//   String Function({Object o}) toStringTearOff2 = c2.toString; // error
+//                                                     ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+// Try calling using ?. instead.
+//   c2.toString(o: c1); // error
+//      ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class CustomType extends core::Type {
+  synthetic constructor •() → self::CustomType
+    : super core::Type::•()
+    ;
+  method call() → void {}
+}
+abstract class CustomInvocation extends core::Object implements core::Invocation {
+  synthetic constructor •() → self::CustomInvocation
+    : super core::Object::•()
+    ;
+}
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract get runtimeType() → self::CustomType;
+  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant self::CustomInvocation invocation) → core::String
+    return super.{core::Object::noSuchMethod}(invocation);
+  forwarding-stub forwarding-semi-stub operator ==(covariant self::Class o) → core::bool
+    return super.{core::Object::==}(o);
+  abstract method toString({core::Object o = #C1}) → core::String;
+}
+static method main() → dynamic {}
+static method test(self::Class c1, self::Class? c2, core::Invocation invocation, self::CustomInvocation customInvocation) → void {
+  self::CustomType runtimeType1 = c1.{self::Class::runtimeType};
+  self::CustomType runtimeTypeVariable1 = c1.{self::Class::runtimeType};
+  c1.{self::Class::runtimeType}.{self::CustomType::call}();
+  (self::CustomInvocation) → core::String noSuchMethodTearOff1 = c1.{self::Class::noSuchMethod};
+  (self::CustomInvocation) → core::String noSuchMethodTearOffVariable1 = c1.{self::Class::noSuchMethod};
+  core::String noSuchMethod1a = c1.{self::Class::noSuchMethod}(customInvocation);
+  core::String noSuchMethod1b = c1.{self::Class::noSuchMethod}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+                                          ^" in invocation as{TypeError,ForNonNullableByDefault} self::CustomInvocation);
+  core::String noSuchMethodVariable1 = c1.{self::Class::noSuchMethod}(customInvocation);
+  c1.{self::Class::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  c1 == ''; // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+  c1.{self::Class::==}(c2);
+  ({o: core::Object}) → core::String toStringTearOff1 = c1.{self::Class::toString};
+  ({o: core::Object}) → core::String toStringTearOffVariable1 = c1.{self::Class::toString};
+  c1.{self::Class::toString}(o: c1);
+  self::CustomType runtimeType2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+ - 'Type' is from 'dart:core'.
+ - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  CustomType runtimeType2 = c2.runtimeType; // error
+                               ^" in c2.{core::Object::runtimeType} as{TypeError,ForNonNullableByDefault} self::CustomType;
+  core::Type runtimeTypeVariable2 = c2.{core::Object::runtimeType};
+  invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+  c2.runtimeType(); // error
+                ^^^^^^^^^^^";
+  (self::CustomInvocation) → core::String noSuchMethodTearOff2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+      c2.noSuchMethod; // error
+         ^" in c2.{core::Object::noSuchMethod} as{TypeError,ForNonNullableByDefault} (self::CustomInvocation) → core::String;
+  (core::Invocation) → dynamic noSuchMethodTearOffVariable2 = c2.{core::Object::noSuchMethod};
+  core::int noSuchMethod2 = c2.{core::Object::noSuchMethod}(invocation) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+  dynamic noSuchMethodVariable2 = c2.{core::Object::noSuchMethod}(invocation);
+  c2.{core::Object::==}("");
+  c2.{core::Object::==}(c1);
+  ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+ - 'Object' is from 'dart:core'.
+  String Function({Object o}) toStringTearOff2 = c2.toString; // error
+                                                    ^" in c2.{core::Object::toString} as{TypeError,ForNonNullableByDefault} ({o: core::Object}) → core::String;
+  () → core::String toStringTearOffVariable2 = c2.{core::Object::toString};
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+Try calling using ?. instead.
+  c2.toString(o: c1); // error
+     ^^^^^^^^" in c2.{self::Class::toString}(o: c1);
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline.expect
new file mode 100644
index 0000000..c224a86
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+abstract class CustomType extends Type {
+  void call() {}
+}
+
+abstract class CustomInvocation implements Invocation {}
+
+abstract class Class {
+  CustomType get runtimeType;
+  String noSuchMethod(covariant CustomInvocation invocation);
+  bool operator ==(covariant Class o);
+  String toString({Object o});
+}
+
+main() {}
+void test(Class c1, Class? c2, Invocation invocation,
+    CustomInvocation customInvocation) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b6a6c78
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+abstract class Class {
+  CustomType get runtimeType;
+  String noSuchMethod(covariant CustomInvocation invocation);
+  String toString({Object o});
+  bool operator ==(covariant Class o);
+}
+
+abstract class CustomInvocation implements Invocation {}
+
+abstract class CustomType extends Type {
+  void call() {}
+}
+
+main() {}
+void test(Class c1, Class? c2, Invocation invocation,
+    CustomInvocation customInvocation) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
new file mode 100644
index 0000000..ec3535f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
@@ -0,0 +1,127 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   c1 == ''; // error
+//         ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+//  - 'Type' is from 'dart:core'.
+//  - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   CustomType runtimeType2 = c2.runtimeType; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+//   c2.runtimeType(); // error
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//       c2.noSuchMethod; // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   c2 == ''; // ok or error?
+//         ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+//  - 'Object' is from 'dart:core'.
+//   String Function({Object o}) toStringTearOff2 = c2.toString; // error
+//                                                     ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
+//   c2.toString(o: c1); // error
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class CustomType extends core::Type {
+  synthetic constructor •() → self::CustomType
+    : super core::Type::•()
+    ;
+  method call() → void {}
+}
+abstract class CustomInvocation extends core::Object implements core::Invocation {
+  synthetic constructor •() → self::CustomInvocation
+    : super core::Object::•()
+    ;
+}
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract get runtimeType() → self::CustomType;
+  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant self::CustomInvocation invocation) → core::String
+    return super.{core::Object::noSuchMethod}(invocation);
+  forwarding-stub forwarding-semi-stub operator ==(covariant self::Class o) → core::bool
+    return super.{core::Object::==}(o);
+  abstract method toString({core::Object o = #C1}) → core::String;
+}
+static method main() → dynamic {}
+static method test(self::Class c1, self::Class? c2, core::Invocation invocation, self::CustomInvocation customInvocation) → void {
+  self::CustomType runtimeType1 = c1.{self::Class::runtimeType};
+  self::CustomType runtimeTypeVariable1 = c1.{self::Class::runtimeType};
+  c1.{self::Class::runtimeType}.{self::CustomType::call}();
+  (self::CustomInvocation) → core::String noSuchMethodTearOff1 = c1.{self::Class::noSuchMethod};
+  (self::CustomInvocation) → core::String noSuchMethodTearOffVariable1 = c1.{self::Class::noSuchMethod};
+  core::String noSuchMethod1a = c1.{self::Class::noSuchMethod}(customInvocation);
+  core::String noSuchMethod1b = c1.{self::Class::noSuchMethod}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+                                          ^" in invocation as{TypeError,ForNonNullableByDefault} self::CustomInvocation);
+  core::String noSuchMethodVariable1 = c1.{self::Class::noSuchMethod}(customInvocation);
+  c1.{self::Class::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  c1 == ''; // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+  c1.{self::Class::==}(c2);
+  ({o: core::Object}) → core::String toStringTearOff1 = c1.{self::Class::toString};
+  ({o: core::Object}) → core::String toStringTearOffVariable1 = c1.{self::Class::toString};
+  c1.{self::Class::toString}(o: c1);
+  self::CustomType runtimeType2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+ - 'Type' is from 'dart:core'.
+ - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  CustomType runtimeType2 = c2.runtimeType; // error
+                               ^" in c2.{core::Object::runtimeType} as{TypeError,ForNonNullableByDefault} self::CustomType;
+  core::Type runtimeTypeVariable2 = c2.{core::Object::runtimeType};
+  invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+  c2.runtimeType(); // error
+                ^^^^^^^^^^^";
+  (self::CustomInvocation) → core::String noSuchMethodTearOff2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+      c2.noSuchMethod; // error
+         ^" in c2.{core::Object::noSuchMethod} as{TypeError,ForNonNullableByDefault} (self::CustomInvocation) → core::String;
+  (core::Invocation) → dynamic noSuchMethodTearOffVariable2 = c2.{core::Object::noSuchMethod};
+  core::int noSuchMethod2 = c2.{core::Object::noSuchMethod}(invocation) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+  dynamic noSuchMethodVariable2 = c2.{core::Object::noSuchMethod}(invocation);
+  c2.{self::Class::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  c2 == ''; // ok or error?
+        ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+  c2.{self::Class::==}(c1);
+  ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+ - 'Object' is from 'dart:core'.
+  String Function({Object o}) toStringTearOff2 = c2.toString; // error
+                                                    ^" in c2.{core::Object::toString} as{TypeError,ForNonNullableByDefault} ({o: core::Object}) → core::String;
+  () → core::String toStringTearOffVariable2 = c2.{core::Object::toString};
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
+  c2.toString(o: c1); // error
+              ^" in c2.{core::Object::toString}(o: c1);
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect
new file mode 100644
index 0000000..81b9a41
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect
@@ -0,0 +1,123 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   c1 == ''; // error
+//         ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+//  - 'Type' is from 'dart:core'.
+//  - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//   CustomType runtimeType2 = c2.runtimeType; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+//   c2.runtimeType(); // error
+//                 ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+//  - 'Invocation' is from 'dart:core'.
+//  - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+//       c2.noSuchMethod; // error
+//          ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+//  - 'Object' is from 'dart:core'.
+//   String Function({Object o}) toStringTearOff2 = c2.toString; // error
+//                                                     ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+// Try calling using ?. instead.
+//   c2.toString(o: c1); // error
+//      ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class CustomType extends core::Type {
+  synthetic constructor •() → self::CustomType
+    : super core::Type::•()
+    ;
+  method call() → void {}
+}
+abstract class CustomInvocation extends core::Object implements core::Invocation {
+  synthetic constructor •() → self::CustomInvocation
+    : super core::Object::•()
+    ;
+}
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract get runtimeType() → self::CustomType;
+  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant self::CustomInvocation invocation) → core::String
+    return super.{core::Object::noSuchMethod}(invocation);
+  forwarding-stub forwarding-semi-stub operator ==(covariant self::Class o) → core::bool
+    return super.{core::Object::==}(o);
+  abstract method toString({core::Object o = #C1}) → core::String;
+}
+static method main() → dynamic {}
+static method test(self::Class c1, self::Class? c2, core::Invocation invocation, self::CustomInvocation customInvocation) → void {
+  self::CustomType runtimeType1 = c1.{self::Class::runtimeType};
+  self::CustomType runtimeTypeVariable1 = c1.{self::Class::runtimeType};
+  c1.{self::Class::runtimeType}.{self::CustomType::call}();
+  (self::CustomInvocation) → core::String noSuchMethodTearOff1 = c1.{self::Class::noSuchMethod};
+  (self::CustomInvocation) → core::String noSuchMethodTearOffVariable1 = c1.{self::Class::noSuchMethod};
+  core::String noSuchMethod1a = c1.{self::Class::noSuchMethod}(customInvocation);
+  core::String noSuchMethod1b = c1.{self::Class::noSuchMethod}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:31:43: Error: The argument type 'Invocation' can't be assigned to the parameter type 'CustomInvocation'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  String noSuchMethod1b = c1.noSuchMethod(invocation); // error
+                                          ^" in invocation as{TypeError,ForNonNullableByDefault} self::CustomInvocation);
+  core::String noSuchMethodVariable1 = c1.{self::Class::noSuchMethod}(customInvocation);
+  c1.{self::Class::==}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:34:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  c1 == ''; // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+  c1.{self::Class::==}(c2);
+  ({o: core::Object}) → core::String toStringTearOff1 = c1.{self::Class::toString};
+  ({o: core::Object}) → core::String toStringTearOffVariable1 = c1.{self::Class::toString};
+  c1.{self::Class::toString}(o: c1);
+  self::CustomType runtimeType2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:42:32: Error: A value of type 'Type' can't be assigned to a variable of type 'CustomType'.
+ - 'Type' is from 'dart:core'.
+ - 'CustomType' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+  CustomType runtimeType2 = c2.runtimeType; // error
+                               ^" in c2.{core::Object::runtimeType} as{TypeError,ForNonNullableByDefault} self::CustomType;
+  core::Type runtimeTypeVariable2 = c2.{core::Object::runtimeType};
+  invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:44:17: Error: 'runtimeType' isn't a function or method and can't be invoked.
+  c2.runtimeType(); // error
+                ^^^^^^^^^^^";
+  (self::CustomInvocation) → core::String noSuchMethodTearOff2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:47:10: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'String Function(CustomInvocation)'.
+ - 'Invocation' is from 'dart:core'.
+ - 'CustomInvocation' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+      c2.noSuchMethod; // error
+         ^" in c2.{core::Object::noSuchMethod} as{TypeError,ForNonNullableByDefault} (self::CustomInvocation) → core::String;
+  (core::Invocation) → dynamic noSuchMethodTearOffVariable2 = c2.{core::Object::noSuchMethod};
+  core::int noSuchMethod2 = c2.{core::Object::noSuchMethod}(invocation) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+  dynamic noSuchMethodVariable2 = c2.{core::Object::noSuchMethod}(invocation);
+  c2.{core::Object::==}("");
+  c2.{core::Object::==}(c1);
+  ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+ - 'Object' is from 'dart:core'.
+  String Function({Object o}) toStringTearOff2 = c2.toString; // error
+                                                    ^" in c2.{core::Object::toString} as{TypeError,ForNonNullableByDefault} ({o: core::Object}) → core::String;
+  () → core::String toStringTearOffVariable2 = c2.{core::Object::toString};
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+Try calling using ?. instead.
+  c2.toString(o: c1); // error
+     ^^^^^^^^" in c2.{self::Class::toString}(o: c1);
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart b/pkg/front_end/testcases/nnbd/nullable_param.dart
index 75cc3db..ba646b8 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart
@@ -1,6 +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.
+
 class Foo {
   int? field;
   int? bar(int? x) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline.expect
new file mode 100644
index 0000000..3d0a427
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo {
+  int? field;
+  int? bar(int? x) {}
+}
+
+main() {}
+int test_nullable_function_type_formal_param({int f()?: null}) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..307c9d6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo {
+  int? bar(int? x) {}
+  int? field;
+}
+
+int test_nullable_function_type_formal_param({int f()?: null}) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect
index 24d5f3d..b4de6e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect
@@ -36,11 +36,10 @@
 //   a();
 //    ^
 //
-// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-// Try calling using ?. instead.
+// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
 //   b.toString(0);
-//     ^^^^^^^^
+//             ^
 //
 // pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
 //   Function f1 = a;
@@ -103,11 +102,10 @@
 Try calling using ?.call instead.
   a();
    ^" in a.{self::A::call}();
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
- - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-Try calling using ?. instead.
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
   b.toString(0);
-    ^^^^^^^^" in b.{self::B::toString}(0);
+            ^" in b.{core::Object::toString}(0);
   core::Function f1 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
   Function f1 = a;
                 ^" in a as{TypeError} core::Function;
@@ -123,14 +121,14 @@
   a.{core::Object::==}(a);
   t.{core::Object::==}(t);
   b.{core::Object::==}(b);
-  s.{core::String::hashCode};
+  s.{core::Object::hashCode};
   a.{core::Object::hashCode};
   t.{core::Object::hashCode};
   b.{core::Object::hashCode};
   s.{core::Object::toString}();
   a.{core::Object::toString}();
   t.{core::Object::toString}();
-  b.{self::B::toString}();
+  b.{core::Object::toString}();
   try {
     s.{core::Object::noSuchMethod}(i);
   }
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.transformed.expect
index 24d5f3d..380d689 100644
--- a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.transformed.expect
@@ -119,18 +119,18 @@
                         ^" in a as{TypeError} () →? void;
 }
 static method ok<T extends core::Object? = core::Object?>(core::String? s, self::A? a, self::ok::T% t, self::B? b, core::Invocation i) → dynamic {
-  s.{core::String::==}(s);
+  s.{core::Object::==}(s);
   a.{core::Object::==}(a);
   t.{core::Object::==}(t);
   b.{core::Object::==}(b);
-  s.{core::String::hashCode};
+  s.{core::Object::hashCode};
   a.{core::Object::hashCode};
   t.{core::Object::hashCode};
   b.{core::Object::hashCode};
   s.{core::Object::toString}();
   a.{core::Object::toString}();
   t.{core::Object::toString}();
-  b.{self::B::toString}();
+  b.{core::Object::toString}();
   try {
     s.{core::Object::noSuchMethod}(i);
   }
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline.expect
new file mode 100644
index 0000000..b676129
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {
+  foo() {}
+  int get bar => 42;
+  void set baz(int value) {}
+  void call() {}
+}
+
+class B {
+  String toString([int extra = 42]) => super.toString();
+}
+
+error(String? s, A? a, B? b) {}
+ok<T extends Object?>(String? s, A? a, T t, B? b, Invocation i) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d77e911
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {
+  foo() {}
+  int get bar => 42;
+  void call() {}
+  void set baz(int value) {}
+}
+
+class B {
+  String toString([int extra = 42]) => super.toString();
+}
+
+error(String? s, A? a, B? b) {}
+main() {}
+ok<T extends Object?>(String? s, A? a, T t, B? b, Invocation i) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect
index 24d5f3d..b4de6e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect
@@ -36,11 +36,10 @@
 //   a();
 //    ^
 //
-// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-// Try calling using ?. instead.
+// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
 //   b.toString(0);
-//     ^^^^^^^^
+//             ^
 //
 // pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
 //   Function f1 = a;
@@ -103,11 +102,10 @@
 Try calling using ?.call instead.
   a();
    ^" in a.{self::A::call}();
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
- - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-Try calling using ?. instead.
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
   b.toString(0);
-    ^^^^^^^^" in b.{self::B::toString}(0);
+            ^" in b.{core::Object::toString}(0);
   core::Function f1 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
   Function f1 = a;
                 ^" in a as{TypeError} core::Function;
@@ -123,14 +121,14 @@
   a.{core::Object::==}(a);
   t.{core::Object::==}(t);
   b.{core::Object::==}(b);
-  s.{core::String::hashCode};
+  s.{core::Object::hashCode};
   a.{core::Object::hashCode};
   t.{core::Object::hashCode};
   b.{core::Object::hashCode};
   s.{core::Object::toString}();
   a.{core::Object::toString}();
   t.{core::Object::toString}();
-  b.{self::B::toString}();
+  b.{core::Object::toString}();
   try {
     s.{core::Object::noSuchMethod}(i);
   }
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.transformed.expect
index 24d5f3d..380d689 100644
--- a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.transformed.expect
@@ -119,18 +119,18 @@
                         ^" in a as{TypeError} () →? void;
 }
 static method ok<T extends core::Object? = core::Object?>(core::String? s, self::A? a, self::ok::T% t, self::B? b, core::Invocation i) → dynamic {
-  s.{core::String::==}(s);
+  s.{core::Object::==}(s);
   a.{core::Object::==}(a);
   t.{core::Object::==}(t);
   b.{core::Object::==}(b);
-  s.{core::String::hashCode};
+  s.{core::Object::hashCode};
   a.{core::Object::hashCode};
   t.{core::Object::hashCode};
   b.{core::Object::hashCode};
   s.{core::Object::toString}();
   a.{core::Object::toString}();
   t.{core::Object::toString}();
-  b.{self::B::toString}();
+  b.{core::Object::toString}();
   try {
     s.{core::Object::noSuchMethod}(i);
   }
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect
index 8c42147..dd56766 100644
--- a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect
@@ -10,9 +10,9 @@
 
 typedef F = invalid-type;
 static method foo(() → void x) → void {
-  self::bar(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::bar(x);
   self::bar(null);
-  self::baz(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::baz(x);
   self::baz(null);
 }
 static method bar(invalid-type x) → void {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect
index 8c42147..dd56766 100644
--- a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect
@@ -10,9 +10,9 @@
 
 typedef F = invalid-type;
 static method foo(() → void x) → void {
-  self::bar(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::bar(x);
   self::bar(null);
-  self::baz(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::baz(x);
   self::baz(null);
 }
 static method bar(invalid-type x) → void {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..a732d24
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef F = void Function()?;
+void foo(void Function() x) {}
+void bar(F x) {}
+void baz(F? x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..091d52a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+main() {}
+typedef F = void Function()?;
+void bar(F x) {}
+void baz(F? x) {}
+void foo(void Function() x) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect
index 8c42147..dd56766 100644
--- a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect
@@ -10,9 +10,9 @@
 
 typedef F = invalid-type;
 static method foo(() → void x) → void {
-  self::bar(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::bar(x);
   self::bar(null);
-  self::baz(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::baz(x);
   self::baz(null);
 }
 static method bar(invalid-type x) → void {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect
index 8c42147..dd56766 100644
--- a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect
@@ -10,9 +10,9 @@
 
 typedef F = invalid-type;
 static method foo(() → void x) → void {
-  self::bar(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::bar(x);
   self::bar(null);
-  self::baz(x as{TypeError,ForNonNullableByDefault} invalid-type);
+  self::baz(x);
   self::baz(null);
 }
 static method bar(invalid-type x) → void {}
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..78cc73c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+import 'opt_out_lib.dart';
+class A<T> {
+  late int ;
+  field = 42;
+}
+class B extends A<String?> {
+}
+typedef F = void Function()?;
+List<String?> l = [];
+String? s = null;
+var t = s!;
+late int ;
+field = 42;
+void method(void f()?, {required int a}) { }
+main() { }
+noErrors() { }
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..6b2ec3c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class A<X extends num> {}
+
+class B1 {
+  void set bar(num? value) {}
+  num get baz => 42;
+  void hest(num? value) {}
+}
+
+class B2 extends B1 {
+  num bar = 3.14;
+  num? get baz => null;
+  void hest(num value) {}
+}
+
+class C1 {
+  factory C1() = C2<int?>;
+}
+
+class C2<X extends int> implements C1 {}
+
+class D {
+  D.foo(num x);
+  factory D.bar(num? x) = D.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c0742df
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+class A<X extends num> {}
+
+class B1 {
+  num get baz => 42;
+  void hest(num? value) {}
+  void set bar(num? value) {}
+}
+
+class B2 extends B1 {
+  num bar = 3.14;
+  num? get baz => null;
+  void hest(num value) {}
+}
+
+class C1 {
+  factory C1() = C2<int?>;
+}
+
+class C2<X extends int> implements C1 {}
+
+class D {
+  D.foo(num x);
+  factory D.bar(num? x) = D.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart
new file mode 100644
index 0000000..d680fba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+Object? objectFunction(Object? o) => o;
+int intFunction(int i) => i;
+T idFunction<T>(T t) => t;
+
+const int Function(int) idAsIntFunction = idFunction;
+
+class Class<T> {
+  final T field;
+
+  const Class(dynamic value) : field = value as T;
+}
+
+class ClassWithBound<T extends num> {
+  final T field;
+
+  const ClassWithBound() : field = three as T;
+
+  const ClassWithBound.withValue(dynamic value) : field = value as T;
+}
+
+class ClassWithList<T> {
+  final List<T> field;
+
+  const ClassWithList(dynamic value) : field = value as List<T>;
+}
+
+class ClassWithFunction<T> {
+  final T Function(T) field;
+
+  const ClassWithFunction(dynamic value) : field = value as T Function(T);
+}
+
+void main() {
+  const Class(0); // ok
+  const Class<num>(0); // ok
+  const Class<int>(0); // ok
+  const Class<String>(''); // ok
+  const ClassWithBound<int>(); // ok
+  const ClassWithBound<int>.withValue(0); // ok
+  const ClassWithBound<int>.withValue(three); // ok
+  const ClassWithBound<double>.withValue(0.5); // ok
+  const ClassWithList([]); // ok
+  const ClassWithList<num>(<int>[0]); // ok
+  const ClassWithList<int>(<int>[0]); // ok
+  const ClassWithList<String>(<String>['']); // ok
+  const ClassWithFunction(dynamicFunction); // ok
+  const ClassWithFunction<Object?>(dynamicFunction); // ok
+  const ClassWithFunction(objectFunction); // ok
+  const ClassWithFunction<void>(objectFunction); // ok
+  const ClassWithFunction<int>(intFunction); // ok
+  const ClassWithFunction<int>(idAsIntFunction); // ok
+}
+
+weakMode() {
+  const ClassWithFunction<Object>(objectFunction); // ok in weak mode
+}
+
+errors() {
+  const Class<num>(''); // error
+  const Class<int>(0.5); // error
+  const Class<String>(0); // error
+  const ClassWithBound<double>(); // error
+  const ClassWithBound<double>.withValue(0); // error
+  const ClassWithBound<double>.withValue(three); // error
+  const ClassWithBound<num>.withValue(''); // error
+  const ClassWithList(0); // error
+  const ClassWithList<num>(<String>['']); // error
+  const ClassWithList<int>(<num>[0]); // error
+  const ClassWithList<String>(<int>[0]); // error
+  const ClassWithFunction(0); // error
+  const ClassWithFunction(intFunction); // error
+  const ClassWithFunction<Object>(intFunction); // error
+  const ClassWithFunction<void>(intFunction); // error
+  const ClassWithFunction<num>(intFunction); // error
+  const ClassWithFunction<int>(idFunction); // error
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.outline.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.outline.expect
new file mode 100644
index 0000000..fa3b2cf
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.outline.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field self::Class::T% field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value as{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field self::ClassWithBound::T field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = self::three as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::List<self::ClassWithList::T%> field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value as{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field (self::ClassWithFunction::T%) → self::ClassWithFunction::T% field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value as{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = 3;
+static const field (core::int) → core::int idAsIntFunction = self::idFunction<core::int>;
+static method dynamicFunction(dynamic d) → dynamic
+  ;
+static method objectFunction(core::Object? o) → core::Object?
+  ;
+static method intFunction(core::int i) → core::int
+  ;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  ;
+static method main() → void
+  ;
+static method weakMode() → dynamic
+  ;
+static method errors() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.strong.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.strong.expect
new file mode 100644
index 0000000..6ec69f6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.strong.expect
@@ -0,0 +1,256 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:61:9: Error: Constant evaluation error:
+//   const ClassWithFunction<Object>(objectFunction); // ok in weak mode
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'objectFunction' to be of type 'Object Function(Object)', but was of type 'Object? Function(Object?)'.
+//  - 'Object' is from 'dart:core'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:65:9: Error: Constant evaluation error:
+//   const Class<num>(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:66:9: Error: Constant evaluation error:
+//   const Class<int>(0.5); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0.5' to be of type 'int', but was of type 'double'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:67:9: Error: Constant evaluation error:
+//   const Class<String>(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0' to be of type 'String', but was of type 'int'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:68:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>(); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:22:42: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound() : field = three as T;
+//                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:69:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '0' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:70:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(three); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:71:9: Error: Constant evaluation error:
+//   const ClassWithBound<num>.withValue(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:72:9: Error: Constant evaluation error:
+//   const ClassWithList(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:73:9: Error: Constant evaluation error:
+//   const ClassWithList<num>(<String>['']); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<String>[""]' to be of type 'List<num>', but was of type 'List<String>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:74:9: Error: Constant evaluation error:
+//   const ClassWithList<int>(<num>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:75:9: Error: Constant evaluation error:
+//   const ClassWithList<String>(<int>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:76:9: Error: Constant evaluation error:
+//   const ClassWithFunction(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:77:9: Error: Constant evaluation error:
+//   const ClassWithFunction(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:78:9: Error: Constant evaluation error:
+//   const ClassWithFunction<Object>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+//  - 'Object' is from 'dart:core'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:79:9: Error: Constant evaluation error:
+//   const ClassWithFunction<void>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:80:9: Error: Constant evaluation error:
+//   const ClassWithFunction<num>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:81:9: Error: Constant evaluation error:
+//   const ClassWithFunction<int>(idFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field self::Class::T% field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value as{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field self::ClassWithBound::T field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::List<self::ClassWithList::T%> field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value as{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field (self::ClassWithFunction::T%) → self::ClassWithFunction::T% field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value as{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C9;
+  #C10;
+  #C11;
+  #C10;
+  #C13;
+  #C15;
+  #C17;
+  #C18;
+  #C20;
+  #C22;
+  #C23;
+  #C25;
+  #C26;
+  #C28;
+  #C29;
+}
+static method weakMode() → dynamic {
+  invalid-expression "Expected constant 'objectFunction' to be of type 'Object Function(Object)', but was of type 'Object? Function(Object?)'.
+ - 'Object' is from 'dart:core'.";
+}
+static method errors() → dynamic {
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0.5' to be of type 'int', but was of type 'double'.";
+  invalid-expression "Expected constant '0' to be of type 'String', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '0' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<String>[\"\"]' to be of type 'List<num>', but was of type 'List<String>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+ - 'Object' is from 'dart:core'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.";
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int>
+  #C4 = 0
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num> {field:#C4}
+  #C7 = self::Class<core::int> {field:#C4}
+  #C8 = ""
+  #C9 = self::Class<core::String> {field:#C8}
+  #C10 = self::ClassWithBound<core::int> {field:#C1}
+  #C11 = self::ClassWithBound<core::int> {field:#C4}
+  #C12 = 0.5
+  #C13 = self::ClassWithBound<core::double> {field:#C12}
+  #C14 = <dynamic>[]
+  #C15 = self::ClassWithList<dynamic> {field:#C14}
+  #C16 = <core::int>[#C4]
+  #C17 = self::ClassWithList<core::num> {field:#C16}
+  #C18 = self::ClassWithList<core::int> {field:#C16}
+  #C19 = <core::String>[#C8]
+  #C20 = self::ClassWithList<core::String> {field:#C19}
+  #C21 = tearoff self::dynamicFunction
+  #C22 = self::ClassWithFunction<dynamic> {field:#C21}
+  #C23 = self::ClassWithFunction<core::Object?> {field:#C21}
+  #C24 = tearoff self::objectFunction
+  #C25 = self::ClassWithFunction<dynamic> {field:#C24}
+  #C26 = self::ClassWithFunction<void> {field:#C24}
+  #C27 = tearoff self::intFunction
+  #C28 = self::ClassWithFunction<core::int> {field:#C27}
+  #C29 = self::ClassWithFunction<core::int> {field:#C3}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.strong.transformed.expect
new file mode 100644
index 0000000..6ec69f6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.strong.transformed.expect
@@ -0,0 +1,256 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:61:9: Error: Constant evaluation error:
+//   const ClassWithFunction<Object>(objectFunction); // ok in weak mode
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'objectFunction' to be of type 'Object Function(Object)', but was of type 'Object? Function(Object?)'.
+//  - 'Object' is from 'dart:core'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:65:9: Error: Constant evaluation error:
+//   const Class<num>(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:66:9: Error: Constant evaluation error:
+//   const Class<int>(0.5); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0.5' to be of type 'int', but was of type 'double'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:67:9: Error: Constant evaluation error:
+//   const Class<String>(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0' to be of type 'String', but was of type 'int'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:68:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>(); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:22:42: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound() : field = three as T;
+//                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:69:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '0' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:70:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(three); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:71:9: Error: Constant evaluation error:
+//   const ClassWithBound<num>.withValue(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:72:9: Error: Constant evaluation error:
+//   const ClassWithList(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:73:9: Error: Constant evaluation error:
+//   const ClassWithList<num>(<String>['']); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<String>[""]' to be of type 'List<num>', but was of type 'List<String>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:74:9: Error: Constant evaluation error:
+//   const ClassWithList<int>(<num>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:75:9: Error: Constant evaluation error:
+//   const ClassWithList<String>(<int>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:76:9: Error: Constant evaluation error:
+//   const ClassWithFunction(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:77:9: Error: Constant evaluation error:
+//   const ClassWithFunction(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:78:9: Error: Constant evaluation error:
+//   const ClassWithFunction<Object>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+//  - 'Object' is from 'dart:core'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:79:9: Error: Constant evaluation error:
+//   const ClassWithFunction<void>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:80:9: Error: Constant evaluation error:
+//   const ClassWithFunction<num>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:81:9: Error: Constant evaluation error:
+//   const ClassWithFunction<int>(idFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field self::Class::T% field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value as{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field self::ClassWithBound::T field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::List<self::ClassWithList::T%> field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value as{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field (self::ClassWithFunction::T%) → self::ClassWithFunction::T% field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value as{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C9;
+  #C10;
+  #C11;
+  #C10;
+  #C13;
+  #C15;
+  #C17;
+  #C18;
+  #C20;
+  #C22;
+  #C23;
+  #C25;
+  #C26;
+  #C28;
+  #C29;
+}
+static method weakMode() → dynamic {
+  invalid-expression "Expected constant 'objectFunction' to be of type 'Object Function(Object)', but was of type 'Object? Function(Object?)'.
+ - 'Object' is from 'dart:core'.";
+}
+static method errors() → dynamic {
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0.5' to be of type 'int', but was of type 'double'.";
+  invalid-expression "Expected constant '0' to be of type 'String', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '0' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<String>[\"\"]' to be of type 'List<num>', but was of type 'List<String>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+ - 'Object' is from 'dart:core'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.";
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int>
+  #C4 = 0
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num> {field:#C4}
+  #C7 = self::Class<core::int> {field:#C4}
+  #C8 = ""
+  #C9 = self::Class<core::String> {field:#C8}
+  #C10 = self::ClassWithBound<core::int> {field:#C1}
+  #C11 = self::ClassWithBound<core::int> {field:#C4}
+  #C12 = 0.5
+  #C13 = self::ClassWithBound<core::double> {field:#C12}
+  #C14 = <dynamic>[]
+  #C15 = self::ClassWithList<dynamic> {field:#C14}
+  #C16 = <core::int>[#C4]
+  #C17 = self::ClassWithList<core::num> {field:#C16}
+  #C18 = self::ClassWithList<core::int> {field:#C16}
+  #C19 = <core::String>[#C8]
+  #C20 = self::ClassWithList<core::String> {field:#C19}
+  #C21 = tearoff self::dynamicFunction
+  #C22 = self::ClassWithFunction<dynamic> {field:#C21}
+  #C23 = self::ClassWithFunction<core::Object?> {field:#C21}
+  #C24 = tearoff self::objectFunction
+  #C25 = self::ClassWithFunction<dynamic> {field:#C24}
+  #C26 = self::ClassWithFunction<void> {field:#C24}
+  #C27 = tearoff self::intFunction
+  #C28 = self::ClassWithFunction<core::int> {field:#C27}
+  #C29 = self::ClassWithFunction<core::int> {field:#C3}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline.expect
new file mode 100644
index 0000000..dca172b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+Object? objectFunction(Object? o) => o;
+int intFunction(int i) => i;
+T idFunction<T>(T t) => t;
+const int Function(int) idAsIntFunction = idFunction;
+
+class Class<T> {
+  final T field;
+  const Class(dynamic value) : field = value as T;
+}
+
+class ClassWithBound<T extends num> {
+  final T field;
+  const ClassWithBound() : field = three as T;
+  const ClassWithBound.withValue(dynamic value) : field = value as T;
+}
+
+class ClassWithList<T> {
+  final List<T> field;
+  const ClassWithList(dynamic value) : field = value as List<T>;
+}
+
+class ClassWithFunction<T> {
+  final T Function(T) field;
+  const ClassWithFunction(dynamic value) : field = value as T Function(T);
+}
+
+void main() {}
+weakMode() {}
+errors() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9241bde
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+Object? objectFunction(Object? o) => o;
+T idFunction<T>(T t) => t;
+
+class Class<T> {
+  const Class(dynamic value) : field = value as T;
+  final T field;
+}
+
+class ClassWithBound<T extends num> {
+  const ClassWithBound() : field = three as T;
+  const ClassWithBound.withValue(dynamic value) : field = value as T;
+  final T field;
+}
+
+class ClassWithFunction<T> {
+  const ClassWithFunction(dynamic value) : field = value as T Function(T);
+  final T Function(T) field;
+}
+
+class ClassWithList<T> {
+  const ClassWithList(dynamic value) : field = value as List<T>;
+  final List<T> field;
+}
+
+const int Function(int) idAsIntFunction = idFunction;
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+errors() {}
+int intFunction(int i) => i;
+void main() {}
+weakMode() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.weak.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.weak.expect
new file mode 100644
index 0000000..37e43f1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.weak.expect
@@ -0,0 +1,248 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:65:9: Error: Constant evaluation error:
+//   const Class<num>(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:66:9: Error: Constant evaluation error:
+//   const Class<int>(0.5); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0.5' to be of type 'int', but was of type 'double'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:67:9: Error: Constant evaluation error:
+//   const Class<String>(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0' to be of type 'String', but was of type 'int'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:68:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>(); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:22:42: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound() : field = three as T;
+//                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:69:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '0' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:70:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(three); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:71:9: Error: Constant evaluation error:
+//   const ClassWithBound<num>.withValue(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:72:9: Error: Constant evaluation error:
+//   const ClassWithList(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:73:9: Error: Constant evaluation error:
+//   const ClassWithList<num>(<String>['']); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<String>[""]' to be of type 'List<num>', but was of type 'List<String>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:74:9: Error: Constant evaluation error:
+//   const ClassWithList<int>(<num>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:75:9: Error: Constant evaluation error:
+//   const ClassWithList<String>(<int>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:76:9: Error: Constant evaluation error:
+//   const ClassWithFunction(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:77:9: Error: Constant evaluation error:
+//   const ClassWithFunction(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:78:9: Error: Constant evaluation error:
+//   const ClassWithFunction<Object>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+//  - 'Object' is from 'dart:core'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:79:9: Error: Constant evaluation error:
+//   const ClassWithFunction<void>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:80:9: Error: Constant evaluation error:
+//   const ClassWithFunction<num>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:81:9: Error: Constant evaluation error:
+//   const ClassWithFunction<int>(idFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field self::Class::T% field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value as{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field self::ClassWithBound::T field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::List<self::ClassWithList::T%> field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value as{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field (self::ClassWithFunction::T%) → self::ClassWithFunction::T% field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value as{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C9;
+  #C10;
+  #C11;
+  #C10;
+  #C13;
+  #C15;
+  #C17;
+  #C18;
+  #C20;
+  #C22;
+  #C23;
+  #C25;
+  #C26;
+  #C28;
+  #C29;
+}
+static method weakMode() → dynamic {
+  #C30;
+}
+static method errors() → dynamic {
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0.5' to be of type 'int', but was of type 'double'.";
+  invalid-expression "Expected constant '0' to be of type 'String', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '0' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<String>[\"\"]' to be of type 'List<num>', but was of type 'List<String>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+ - 'Object' is from 'dart:core'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.";
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int*>
+  #C4 = 0
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num*> {field:#C4}
+  #C7 = self::Class<core::int*> {field:#C4}
+  #C8 = ""
+  #C9 = self::Class<core::String*> {field:#C8}
+  #C10 = self::ClassWithBound<core::int*> {field:#C1}
+  #C11 = self::ClassWithBound<core::int*> {field:#C4}
+  #C12 = 0.5
+  #C13 = self::ClassWithBound<core::double*> {field:#C12}
+  #C14 = <dynamic>[]
+  #C15 = self::ClassWithList<dynamic> {field:#C14}
+  #C16 = <core::int*>[#C4]
+  #C17 = self::ClassWithList<core::num*> {field:#C16}
+  #C18 = self::ClassWithList<core::int*> {field:#C16}
+  #C19 = <core::String*>[#C8]
+  #C20 = self::ClassWithList<core::String*> {field:#C19}
+  #C21 = tearoff self::dynamicFunction
+  #C22 = self::ClassWithFunction<dynamic> {field:#C21}
+  #C23 = self::ClassWithFunction<core::Object*> {field:#C21}
+  #C24 = tearoff self::objectFunction
+  #C25 = self::ClassWithFunction<dynamic> {field:#C24}
+  #C26 = self::ClassWithFunction<void> {field:#C24}
+  #C27 = tearoff self::intFunction
+  #C28 = self::ClassWithFunction<core::int*> {field:#C27}
+  #C29 = self::ClassWithFunction<core::int*> {field:#C3}
+  #C30 = self::ClassWithFunction<core::Object*> {field:#C24}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.weak.transformed.expect
new file mode 100644
index 0000000..37e43f1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.weak.transformed.expect
@@ -0,0 +1,248 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:65:9: Error: Constant evaluation error:
+//   const Class<num>(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:66:9: Error: Constant evaluation error:
+//   const Class<int>(0.5); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0.5' to be of type 'int', but was of type 'double'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:67:9: Error: Constant evaluation error:
+//   const Class<String>(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:16:46: Context: Expected constant '0' to be of type 'String', but was of type 'int'.
+//   const Class(dynamic value) : field = value as T;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:68:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>(); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:22:42: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound() : field = three as T;
+//                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:69:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '0' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:70:9: Error: Constant evaluation error:
+//   const ClassWithBound<double>.withValue(three); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '3' to be of type 'double', but was of type 'int'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:71:9: Error: Constant evaluation error:
+//   const ClassWithBound<num>.withValue(''); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:24:65: Context: Expected constant '""' to be of type 'num', but was of type 'String'.
+//   const ClassWithBound.withValue(dynamic value) : field = value as T;
+//                                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:72:9: Error: Constant evaluation error:
+//   const ClassWithList(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:73:9: Error: Constant evaluation error:
+//   const ClassWithList<num>(<String>['']); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<String>[""]' to be of type 'List<num>', but was of type 'List<String>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:74:9: Error: Constant evaluation error:
+//   const ClassWithList<int>(<num>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:75:9: Error: Constant evaluation error:
+//   const ClassWithList<String>(<int>[0]); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:30:54: Context: Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+//   const ClassWithList(dynamic value) : field = value as List<T>;
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:76:9: Error: Constant evaluation error:
+//   const ClassWithFunction(0); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:77:9: Error: Constant evaluation error:
+//   const ClassWithFunction(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:78:9: Error: Constant evaluation error:
+//   const ClassWithFunction<Object>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+//  - 'Object' is from 'dart:core'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:79:9: Error: Constant evaluation error:
+//   const ClassWithFunction<void>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:80:9: Error: Constant evaluation error:
+//   const ClassWithFunction<num>(intFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:81:9: Error: Constant evaluation error:
+//   const ClassWithFunction<int>(idFunction); // error
+//         ^
+// pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart:36:58: Context: Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.
+//   const ClassWithFunction(dynamic value) : field = value as T Function(T);
+//                                                          ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field self::Class::T% field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value as{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field self::ClassWithBound::T field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value as{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::List<self::ClassWithList::T%> field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value as{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field (self::ClassWithFunction::T%) → self::ClassWithFunction::T% field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value as{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C9;
+  #C10;
+  #C11;
+  #C10;
+  #C13;
+  #C15;
+  #C17;
+  #C18;
+  #C20;
+  #C22;
+  #C23;
+  #C25;
+  #C26;
+  #C28;
+  #C29;
+}
+static method weakMode() → dynamic {
+  #C30;
+}
+static method errors() → dynamic {
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0.5' to be of type 'int', but was of type 'double'.";
+  invalid-expression "Expected constant '0' to be of type 'String', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '0' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '3' to be of type 'double', but was of type 'int'.";
+  invalid-expression "Expected constant '\"\"' to be of type 'num', but was of type 'String'.";
+  invalid-expression "Expected constant '0' to be of type 'List<dynamic>', but was of type 'int'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<String>[\"\"]' to be of type 'List<num>', but was of type 'List<String>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<num>[0]' to be of type 'List<int>', but was of type 'List<num>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '<int>[0]' to be of type 'List<String>', but was of type 'List<int>'.
+ - 'List' is from 'dart:core'.";
+  invalid-expression "Expected constant '0' to be of type 'dynamic Function(dynamic)', but was of type 'int'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'dynamic Function(dynamic)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'Object Function(Object)', but was of type 'int Function(int)'.
+ - 'Object' is from 'dart:core'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'void Function(void)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'intFunction' to be of type 'num Function(num)', but was of type 'int Function(int)'.";
+  invalid-expression "Expected constant 'idFunction' to be of type 'int Function(int)', but was of type 'T Function<T>(T)'.";
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int*>
+  #C4 = 0
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num*> {field:#C4}
+  #C7 = self::Class<core::int*> {field:#C4}
+  #C8 = ""
+  #C9 = self::Class<core::String*> {field:#C8}
+  #C10 = self::ClassWithBound<core::int*> {field:#C1}
+  #C11 = self::ClassWithBound<core::int*> {field:#C4}
+  #C12 = 0.5
+  #C13 = self::ClassWithBound<core::double*> {field:#C12}
+  #C14 = <dynamic>[]
+  #C15 = self::ClassWithList<dynamic> {field:#C14}
+  #C16 = <core::int*>[#C4]
+  #C17 = self::ClassWithList<core::num*> {field:#C16}
+  #C18 = self::ClassWithList<core::int*> {field:#C16}
+  #C19 = <core::String*>[#C8]
+  #C20 = self::ClassWithList<core::String*> {field:#C19}
+  #C21 = tearoff self::dynamicFunction
+  #C22 = self::ClassWithFunction<dynamic> {field:#C21}
+  #C23 = self::ClassWithFunction<core::Object*> {field:#C21}
+  #C24 = tearoff self::objectFunction
+  #C25 = self::ClassWithFunction<dynamic> {field:#C24}
+  #C26 = self::ClassWithFunction<void> {field:#C24}
+  #C27 = tearoff self::intFunction
+  #C28 = self::ClassWithFunction<core::int*> {field:#C27}
+  #C29 = self::ClassWithFunction<core::int*> {field:#C3}
+  #C30 = self::ClassWithFunction<core::Object*> {field:#C24}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart
new file mode 100644
index 0000000..e7793b7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+Object? objectFunction(Object? o) => o;
+int intFunction(int i) => i;
+T idFunction<T>(T t) => t;
+
+const int Function(int) idAsIntFunction = idFunction;
+
+class Class<T> {
+  final bool field;
+
+  const Class(dynamic value) : field = value is T;
+}
+
+class ClassWithBound<T extends num> {
+  final bool field;
+
+  const ClassWithBound() : field = three is T;
+
+  const ClassWithBound.withValue(dynamic value) : field = value is T;
+}
+
+class ClassWithList<T> {
+  final bool field;
+
+  const ClassWithList(dynamic value) : field = value is List<T>;
+}
+
+class ClassWithFunction<T> {
+  final bool field;
+
+  const ClassWithFunction(dynamic value) : field = value is T Function(T);
+}
+
+void main() {
+  const Class(0);
+  const Class<num>(0);
+  const Class<int>(0);
+  const Class<String>('');
+  const ClassWithBound<int>();
+  const ClassWithBound<int>.withValue(0);
+  const ClassWithBound<int>.withValue(three);
+  const ClassWithBound<double>.withValue(0.5);
+  const ClassWithList([]);
+  const ClassWithList<num>(<int>[0]);
+  const ClassWithList<int>(<int>[0]);
+  const ClassWithList<String>(<String>['']);
+  const ClassWithFunction(dynamicFunction);
+  const ClassWithFunction<Object?>(dynamicFunction);
+  const ClassWithFunction(objectFunction);
+  const ClassWithFunction<void>(objectFunction);
+  const ClassWithFunction<int>(intFunction);
+  const ClassWithFunction<int>(idAsIntFunction);
+  const ClassWithFunction<Object>(objectFunction);
+  const Class<num>('');
+  const Class<int>(0.5);
+  const Class<String>(0);
+  const ClassWithBound<double>();
+  const ClassWithBound<double>.withValue(0);
+  const ClassWithBound<double>.withValue(three);
+  const ClassWithBound<num>.withValue('');
+  const ClassWithList(0);
+  const ClassWithList<num>(<String>['']);
+  const ClassWithList<int>(<num>[0]);
+  const ClassWithList<String>(<int>[0]);
+  const ClassWithFunction(0);
+  const ClassWithFunction(intFunction);
+  const ClassWithFunction<Object>(intFunction);
+  const ClassWithFunction<void>(intFunction);
+  const ClassWithFunction<num>(intFunction);
+  const ClassWithFunction<int>(idFunction);
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.outline.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.outline.expect
new file mode 100644
index 0000000..59b2a45
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.outline.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = self::three is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value is{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value is{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = 3;
+static const field (core::int) → core::int idAsIntFunction = self::idFunction<core::int>;
+static method dynamicFunction(dynamic d) → dynamic
+  ;
+static method objectFunction(core::Object? o) → core::Object?
+  ;
+static method intFunction(core::int i) → core::int
+  ;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.strong.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.strong.expect
new file mode 100644
index 0000000..8ff2377
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.strong.expect
@@ -0,0 +1,115 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value is{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value is{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C8;
+  #C9;
+  #C9;
+  #C9;
+  #C10;
+  #C11;
+  #C12;
+  #C13;
+  #C14;
+  #C15;
+  #C16;
+  #C15;
+  #C17;
+  #C18;
+  #C18;
+  #C20;
+  #C21;
+  #C22;
+  #C23;
+  #C24;
+  #C24;
+  #C24;
+  #C25;
+  #C26;
+  #C27;
+  #C28;
+  #C29;
+  #C30;
+  #C30;
+  #C20;
+  #C31;
+  #C32;
+  #C33;
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int>
+  #C4 = true
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num> {field:#C4}
+  #C7 = self::Class<core::int> {field:#C4}
+  #C8 = self::Class<core::String> {field:#C4}
+  #C9 = self::ClassWithBound<core::int> {field:#C4}
+  #C10 = self::ClassWithBound<core::double> {field:#C4}
+  #C11 = self::ClassWithList<dynamic> {field:#C4}
+  #C12 = self::ClassWithList<core::num> {field:#C4}
+  #C13 = self::ClassWithList<core::int> {field:#C4}
+  #C14 = self::ClassWithList<core::String> {field:#C4}
+  #C15 = self::ClassWithFunction<dynamic> {field:#C4}
+  #C16 = self::ClassWithFunction<core::Object?> {field:#C4}
+  #C17 = self::ClassWithFunction<void> {field:#C4}
+  #C18 = self::ClassWithFunction<core::int> {field:#C4}
+  #C19 = false
+  #C20 = self::ClassWithFunction<core::Object> {field:#C19}
+  #C21 = self::Class<core::num> {field:#C19}
+  #C22 = self::Class<core::int> {field:#C19}
+  #C23 = self::Class<core::String> {field:#C19}
+  #C24 = self::ClassWithBound<core::double> {field:#C19}
+  #C25 = self::ClassWithBound<core::num> {field:#C19}
+  #C26 = self::ClassWithList<dynamic> {field:#C19}
+  #C27 = self::ClassWithList<core::num> {field:#C19}
+  #C28 = self::ClassWithList<core::int> {field:#C19}
+  #C29 = self::ClassWithList<core::String> {field:#C19}
+  #C30 = self::ClassWithFunction<dynamic> {field:#C19}
+  #C31 = self::ClassWithFunction<void> {field:#C19}
+  #C32 = self::ClassWithFunction<core::num> {field:#C19}
+  #C33 = self::ClassWithFunction<core::int> {field:#C19}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.strong.transformed.expect
new file mode 100644
index 0000000..8ff2377
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.strong.transformed.expect
@@ -0,0 +1,115 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value is{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value is{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C8;
+  #C9;
+  #C9;
+  #C9;
+  #C10;
+  #C11;
+  #C12;
+  #C13;
+  #C14;
+  #C15;
+  #C16;
+  #C15;
+  #C17;
+  #C18;
+  #C18;
+  #C20;
+  #C21;
+  #C22;
+  #C23;
+  #C24;
+  #C24;
+  #C24;
+  #C25;
+  #C26;
+  #C27;
+  #C28;
+  #C29;
+  #C30;
+  #C30;
+  #C20;
+  #C31;
+  #C32;
+  #C33;
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int>
+  #C4 = true
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num> {field:#C4}
+  #C7 = self::Class<core::int> {field:#C4}
+  #C8 = self::Class<core::String> {field:#C4}
+  #C9 = self::ClassWithBound<core::int> {field:#C4}
+  #C10 = self::ClassWithBound<core::double> {field:#C4}
+  #C11 = self::ClassWithList<dynamic> {field:#C4}
+  #C12 = self::ClassWithList<core::num> {field:#C4}
+  #C13 = self::ClassWithList<core::int> {field:#C4}
+  #C14 = self::ClassWithList<core::String> {field:#C4}
+  #C15 = self::ClassWithFunction<dynamic> {field:#C4}
+  #C16 = self::ClassWithFunction<core::Object?> {field:#C4}
+  #C17 = self::ClassWithFunction<void> {field:#C4}
+  #C18 = self::ClassWithFunction<core::int> {field:#C4}
+  #C19 = false
+  #C20 = self::ClassWithFunction<core::Object> {field:#C19}
+  #C21 = self::Class<core::num> {field:#C19}
+  #C22 = self::Class<core::int> {field:#C19}
+  #C23 = self::Class<core::String> {field:#C19}
+  #C24 = self::ClassWithBound<core::double> {field:#C19}
+  #C25 = self::ClassWithBound<core::num> {field:#C19}
+  #C26 = self::ClassWithList<dynamic> {field:#C19}
+  #C27 = self::ClassWithList<core::num> {field:#C19}
+  #C28 = self::ClassWithList<core::int> {field:#C19}
+  #C29 = self::ClassWithList<core::String> {field:#C19}
+  #C30 = self::ClassWithFunction<dynamic> {field:#C19}
+  #C31 = self::ClassWithFunction<void> {field:#C19}
+  #C32 = self::ClassWithFunction<core::num> {field:#C19}
+  #C33 = self::ClassWithFunction<core::int> {field:#C19}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline.expect
new file mode 100644
index 0000000..1fb936c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+Object? objectFunction(Object? o) => o;
+int intFunction(int i) => i;
+T idFunction<T>(T t) => t;
+const int Function(int) idAsIntFunction = idFunction;
+
+class Class<T> {
+  final bool field;
+  const Class(dynamic value) : field = value is T;
+}
+
+class ClassWithBound<T extends num> {
+  final bool field;
+  const ClassWithBound() : field = three is T;
+  const ClassWithBound.withValue(dynamic value) : field = value is T;
+}
+
+class ClassWithList<T> {
+  final bool field;
+  const ClassWithList(dynamic value) : field = value is List<T>;
+}
+
+class ClassWithFunction<T> {
+  final bool field;
+  const ClassWithFunction(dynamic value) : field = value is T Function(T);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ee4178
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,29 @@
+Object? objectFunction(Object? o) => o;
+T idFunction<T>(T t) => t;
+
+class Class<T> {
+  const Class(dynamic value) : field = value is T;
+  final bool field;
+}
+
+class ClassWithBound<T extends num> {
+  const ClassWithBound() : field = three is T;
+  const ClassWithBound.withValue(dynamic value) : field = value is T;
+  final bool field;
+}
+
+class ClassWithFunction<T> {
+  const ClassWithFunction(dynamic value) : field = value is T Function(T);
+  final bool field;
+}
+
+class ClassWithList<T> {
+  const ClassWithList(dynamic value) : field = value is List<T>;
+  final bool field;
+}
+
+const int Function(int) idAsIntFunction = idFunction;
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+int intFunction(int i) => i;
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.weak.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.weak.expect
new file mode 100644
index 0000000..839df94
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.weak.expect
@@ -0,0 +1,115 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value is{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value is{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C8;
+  #C9;
+  #C9;
+  #C9;
+  #C10;
+  #C11;
+  #C12;
+  #C13;
+  #C14;
+  #C15;
+  #C16;
+  #C15;
+  #C17;
+  #C18;
+  #C18;
+  #C16;
+  #C20;
+  #C21;
+  #C22;
+  #C23;
+  #C23;
+  #C23;
+  #C24;
+  #C25;
+  #C26;
+  #C27;
+  #C28;
+  #C29;
+  #C29;
+  #C30;
+  #C31;
+  #C32;
+  #C33;
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int*>
+  #C4 = true
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num*> {field:#C4}
+  #C7 = self::Class<core::int*> {field:#C4}
+  #C8 = self::Class<core::String*> {field:#C4}
+  #C9 = self::ClassWithBound<core::int*> {field:#C4}
+  #C10 = self::ClassWithBound<core::double*> {field:#C4}
+  #C11 = self::ClassWithList<dynamic> {field:#C4}
+  #C12 = self::ClassWithList<core::num*> {field:#C4}
+  #C13 = self::ClassWithList<core::int*> {field:#C4}
+  #C14 = self::ClassWithList<core::String*> {field:#C4}
+  #C15 = self::ClassWithFunction<dynamic> {field:#C4}
+  #C16 = self::ClassWithFunction<core::Object*> {field:#C4}
+  #C17 = self::ClassWithFunction<void> {field:#C4}
+  #C18 = self::ClassWithFunction<core::int*> {field:#C4}
+  #C19 = false
+  #C20 = self::Class<core::num*> {field:#C19}
+  #C21 = self::Class<core::int*> {field:#C19}
+  #C22 = self::Class<core::String*> {field:#C19}
+  #C23 = self::ClassWithBound<core::double*> {field:#C19}
+  #C24 = self::ClassWithBound<core::num*> {field:#C19}
+  #C25 = self::ClassWithList<dynamic> {field:#C19}
+  #C26 = self::ClassWithList<core::num*> {field:#C19}
+  #C27 = self::ClassWithList<core::int*> {field:#C19}
+  #C28 = self::ClassWithList<core::String*> {field:#C19}
+  #C29 = self::ClassWithFunction<dynamic> {field:#C19}
+  #C30 = self::ClassWithFunction<core::Object*> {field:#C19}
+  #C31 = self::ClassWithFunction<void> {field:#C19}
+  #C32 = self::ClassWithFunction<core::num*> {field:#C19}
+  #C33 = self::ClassWithFunction<core::int*> {field:#C19}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.weak.transformed.expect
new file mode 100644
index 0000000..839df94
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.weak.transformed.expect
@@ -0,0 +1,115 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::Class<self::Class::T%>
+    : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+    ;
+}
+class ClassWithBound<T extends core::num = core::num> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •() → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = (#C1) is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+  const constructor withValue(dynamic value) → self::ClassWithBound<self::ClassWithBound::T>
+    : self::ClassWithBound::field = value is{ForNonNullableByDefault} self::ClassWithBound::T, super core::Object::•()
+    ;
+}
+class ClassWithList<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithList<self::ClassWithList::T%>
+    : self::ClassWithList::field = value is{ForNonNullableByDefault} core::List<self::ClassWithList::T%>, super core::Object::•()
+    ;
+}
+class ClassWithFunction<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field core::bool field;
+  const constructor •(dynamic value) → self::ClassWithFunction<self::ClassWithFunction::T%>
+    : self::ClassWithFunction::field = value is{ForNonNullableByDefault} (self::ClassWithFunction::T%) → self::ClassWithFunction::T%, super core::Object::•()
+    ;
+}
+static const field core::num three = #C1;
+static const field (core::int) → core::int idAsIntFunction = #C3;
+static method dynamicFunction(dynamic d) → dynamic
+  return d;
+static method objectFunction(core::Object? o) → core::Object?
+  return o;
+static method intFunction(core::int i) → core::int
+  return i;
+static method idFunction<T extends core::Object? = dynamic>(self::idFunction::T% t) → self::idFunction::T%
+  return t;
+static method main() → void {
+  #C5;
+  #C6;
+  #C7;
+  #C8;
+  #C9;
+  #C9;
+  #C9;
+  #C10;
+  #C11;
+  #C12;
+  #C13;
+  #C14;
+  #C15;
+  #C16;
+  #C15;
+  #C17;
+  #C18;
+  #C18;
+  #C16;
+  #C20;
+  #C21;
+  #C22;
+  #C23;
+  #C23;
+  #C23;
+  #C24;
+  #C25;
+  #C26;
+  #C27;
+  #C28;
+  #C29;
+  #C29;
+  #C30;
+  #C31;
+  #C32;
+  #C33;
+}
+
+constants  {
+  #C1 = 3
+  #C2 = tearoff self::idFunction
+  #C3 = partial-instantiation self::idFunction <core::int*>
+  #C4 = true
+  #C5 = self::Class<dynamic> {field:#C4}
+  #C6 = self::Class<core::num*> {field:#C4}
+  #C7 = self::Class<core::int*> {field:#C4}
+  #C8 = self::Class<core::String*> {field:#C4}
+  #C9 = self::ClassWithBound<core::int*> {field:#C4}
+  #C10 = self::ClassWithBound<core::double*> {field:#C4}
+  #C11 = self::ClassWithList<dynamic> {field:#C4}
+  #C12 = self::ClassWithList<core::num*> {field:#C4}
+  #C13 = self::ClassWithList<core::int*> {field:#C4}
+  #C14 = self::ClassWithList<core::String*> {field:#C4}
+  #C15 = self::ClassWithFunction<dynamic> {field:#C4}
+  #C16 = self::ClassWithFunction<core::Object*> {field:#C4}
+  #C17 = self::ClassWithFunction<void> {field:#C4}
+  #C18 = self::ClassWithFunction<core::int*> {field:#C4}
+  #C19 = false
+  #C20 = self::Class<core::num*> {field:#C19}
+  #C21 = self::Class<core::int*> {field:#C19}
+  #C22 = self::Class<core::String*> {field:#C19}
+  #C23 = self::ClassWithBound<core::double*> {field:#C19}
+  #C24 = self::ClassWithBound<core::num*> {field:#C19}
+  #C25 = self::ClassWithList<dynamic> {field:#C19}
+  #C26 = self::ClassWithList<core::num*> {field:#C19}
+  #C27 = self::ClassWithList<core::int*> {field:#C19}
+  #C28 = self::ClassWithList<core::String*> {field:#C19}
+  #C29 = self::ClassWithFunction<dynamic> {field:#C19}
+  #C30 = self::ClassWithFunction<core::Object*> {field:#C19}
+  #C31 = self::ClassWithFunction<void> {field:#C19}
+  #C32 = self::ClassWithFunction<core::num*> {field:#C19}
+  #C33 = self::ClassWithFunction<core::int*> {field:#C19}
+}
diff --git a/pkg/front_end/testcases/nnbd/potentially_non_nullable_field.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_non_nullable_field.dart.textual_outline.expect
new file mode 100644
index 0000000..b745878
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_non_nullable_field.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+int x;
+int? y;
+late int ;
+z;
+class A<T extends Object?> {
+  static int x;
+  static int? y;
+  static late int ;
+  z;
+  int lx;
+  int? ly;
+  late int;
+  operator? ( ){ }
+  lz;
+  int lv;
+  int lu;
+  T lt;
+  T? ls;
+  late T ;
+  lr;
+  T lp;
+  T lq;
+  A(this.lv, this.lp, T t) : this.lu = 42, this.lq = t;
+}
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
new file mode 100644
index 0000000..3fe3d5f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+class Class {
+  int property = 0;
+  int method() => 0;
+  Function functionField = () {};
+  void Function() functionTypeField = () {};
+  Function get functionGetter => () {};
+  void Function() get functionTypeGetter => () {};
+}
+
+extension Extension on Class {
+  int operator +(int value) => 0;
+  int operator -() => 0;
+  int operator [](int index) => 0;
+  void operator []=(int index, int value) {}
+  int call() => 0;
+  int get extensionProperty => 0;
+  void set extensionProperty(int value) {}
+  int extensionMethod() => 0;
+  Function get extensionFunctionGetter => () {};
+  void Function() get extensionFunctionTypeGetter => () {};
+}
+
+Function? get nullableFunction => () {};
+
+void Function()? get nullableFunctionType => () {};
+
+int? get nullableInt => 0;
+
+Map<dynamic, dynamic>? get nullableMap => {};
+
+Class? get nullableClass => new Class();
+
+var topLevelBinary = nullableInt + 0;
+var topLevelUnary = -nullableInt;
+var topLevelIndexGet = nullableMap[0];
+var topLevelIndexSet = nullableMap[0] = 1;
+var topLevelIndexGetSet = nullableMap[0] += 1;
+var topLevelPropertyGet = nullableClass.property;
+var topLevelPropertySet = nullableClass.property = 1;
+var topLevelPropertyGetSet = nullableClass.property += 1;
+var topLevelMethodInvocation = nullableClass.method();
+var topLevelMethodTearOff = nullableClass.method;
+var topLevelFunctionImplicitCall = nullableFunction();
+var topLevelFunctionExplicitCall = nullableFunction.call();
+var topLevelFunctionTearOff = nullableFunction.call;
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+var topLevelFunctionField = nullableClass.functionField();
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+var topLevelFunctionGetter = nullableClass.functionGetter();
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+
+var topLevelExtensionBinary = nullableClass + 0;
+var topLevelExtensionUnary = -nullableClass;
+var topLevelExtensionIndexGet = nullableClass[0];
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+var topLevelExtensionFunctionTypeGetter =
+    nullableClass.extensionFunctionTypeGetter();
+
+test() {
+  var localBinary = nullableInt + 0;
+  var localUnary = -nullableInt;
+  var localIndexGet = nullableMap[0];
+  var localIndexSet = nullableMap[0] = 1;
+  var localIndexGetSet = nullableMap[0] += 1;
+  var localPropertyGet = nullableClass.property;
+  var localPropertySet = nullableClass.property = 1;
+  var localPropertyGetSet = nullableClass.property += 1;
+  var localMethodInvocation = nullableClass.method();
+  var localMethodTearOff = nullableClass.method;
+  var localFunctionImplicitCall = nullableFunction();
+  var localFunctionExplicitCall = nullableFunction.call();
+  var localFunctionTearOff = nullableFunction.call;
+  var localFunctionTypeImplicitCall = nullableFunctionType();
+  var localFunctionTypeExplicitCall = nullableFunctionType.call();
+  var localFunctionTypeTearOff = nullableFunctionType.call;
+  var localFunctionField = nullableClass.functionField();
+  var localFunctionTypeField = nullableClass.functionTypeField();
+  var localFunctionGetter = nullableClass.functionGetter();
+  var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+
+  var localExtensionBinary = nullableClass + 0;
+  var localExtensionUnary = -nullableClass;
+  var localExtensionIndexGet = nullableClass[0];
+  var localExtensionIndexSet = nullableClass[0] = 1;
+  var localExtensionIndexGetSet = nullableClass[0] += 1;
+  var localExtensionPropertyGet = nullableClass.extensionProperty;
+  var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+  var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+  var localExtensionMethodInvocation = nullableClass.extensionMethod();
+  var localExtensionMethodTearOff = nullableClass.extensionMethod;
+  var localExtensionFunctionTypeImplicitCall = nullableClass();
+  var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+  var localExtensionFunctionTypeTearOff = nullableClass.call;
+  var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+  var localExtensionFunctionTypeGetter =
+      nullableClass.extensionFunctionTypeGetter();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
new file mode 100644
index 0000000..7ba4b0f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
@@ -0,0 +1,104 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int property;
+  field core::Function functionField;
+  field () → void functionTypeField;
+  synthetic constructor •() → self::Class
+    ;
+  method method() → core::int
+    ;
+  get functionGetter() → core::Function
+    ;
+  get functionTypeGetter() → () → void
+    ;
+}
+extension Extension on self::Class {
+  operator + = self::Extension|+;
+  operator unary- = self::Extension|unary-;
+  operator [] = self::Extension|[];
+  operator []= = self::Extension|[]=;
+  method call = self::Extension|call;
+  tearoff call = self::Extension|get#call;
+  get extensionProperty = self::Extension|get#extensionProperty;
+  method extensionMethod = self::Extension|extensionMethod;
+  tearoff extensionMethod = self::Extension|get#extensionMethod;
+  get extensionFunctionGetter = self::Extension|get#extensionFunctionGetter;
+  get extensionFunctionTypeGetter = self::Extension|get#extensionFunctionTypeGetter;
+  set extensionProperty = self::Extension|set#extensionProperty;
+}
+static field core::int? topLevelBinary;
+static field core::int topLevelUnary;
+static field dynamic topLevelIndexGet;
+static field core::int topLevelIndexSet;
+static field dynamic topLevelIndexGetSet;
+static field core::int topLevelPropertyGet;
+static field core::int topLevelPropertySet;
+static field core::int topLevelPropertyGetSet;
+static field core::int topLevelMethodInvocation;
+static field () → core::int topLevelMethodTearOff;
+static field dynamic topLevelFunctionImplicitCall;
+static field dynamic topLevelFunctionExplicitCall;
+static field core::Function? topLevelFunctionTearOff;
+static field void topLevelFunctionTypeImplicitCall;
+static field void topLevelFunctionTypeExplicitCall;
+static field () →? void topLevelFunctionTypeTearOff;
+static field dynamic topLevelFunctionField;
+static field void topLevelFunctionTypeField;
+static field dynamic topLevelFunctionGetter;
+static field void topLevelFunctionTypeGetter;
+static field core::int topLevelExtensionBinary;
+static field core::int topLevelExtensionUnary;
+static field core::int topLevelExtensionIndexGet;
+static field core::int topLevelExtensionIndexSet;
+static field core::int topLevelExtensionIndexGetSet;
+static field core::int topLevelExtensionPropertyGet;
+static field core::int topLevelExtensionPropertySet;
+static field core::int topLevelExtensionPropertyGetSet;
+static field core::int topLevelExtensionMethodInvocation;
+static field () → core::int topLevelExtensionMethodTearOff;
+static field core::int topLevelExtensionFunctionTypeImplicitCall;
+static field core::int topLevelExtensionFunctionTypeExplicitCall;
+static field () → core::int topLevelExtensionFunctionTypeTearOff;
+static field dynamic topLevelExtensionFunctionGetter;
+static field void topLevelExtensionFunctionTypeGetter;
+static method Extension|+(final self::Class #this, core::int value) → core::int
+  ;
+static method Extension|unary-(final self::Class #this) → core::int
+  ;
+static method Extension|[](final self::Class #this, core::int index) → core::int
+  ;
+static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void
+  ;
+static method Extension|call(final self::Class #this) → core::int
+  ;
+static method Extension|get#call(final self::Class #this) → () → core::int
+  return () → core::int => self::Extension|call(#this);
+static method Extension|get#extensionProperty(final self::Class #this) → core::int
+  ;
+static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void
+  ;
+static method Extension|extensionMethod(final self::Class #this) → core::int
+  ;
+static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+  return () → core::int => self::Extension|extensionMethod(#this);
+static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+  ;
+static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+  ;
+static get nullableFunction() → core::Function?
+  ;
+static get nullableFunctionType() → () →? void
+  ;
+static get nullableInt() → core::int?
+  ;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+  ;
+static get nullableClass() → self::Class?
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
new file mode 100644
index 0000000..7c80c76
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
@@ -0,0 +1,828 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+//                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+//                                            ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+//                                              ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+//                                           ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+//                                                     ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+//                                                ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+//                                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                             ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+//                                                        ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionField = nullableClass.functionField();
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeField = nullableClass.functionTypeField();
+//                                               ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionGetter = nullableClass.functionGetter();
+//                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+//                                                ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionBinary = nullableClass + 0;
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionUnary = -nullableClass;
+//                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGet = nullableClass[0];
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexSet = nullableClass[0] = 1;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+//                                                  ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+//                                                  ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+//                                                     ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+//                                                       ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+//                                                    ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+//                                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+//                                                               ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+//                                                          ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+//                                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//     nullableClass.extensionFunctionTypeGetter();
+//                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   var localBinary = nullableInt + 0;
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+//   var localUnary = -nullableInt;
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGet = nullableMap[0];
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexSet = nullableMap[0] = 1;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGet = nullableClass.property;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertySet = nullableClass.property = 1;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGetSet = nullableClass.property += 1;
+//                                           ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localMethodInvocation = nullableClass.method();
+//                                             ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localMethodTearOff = nullableClass.method;
+//                                          ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+//   var localFunctionImplicitCall = nullableFunction();
+//                                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+//   var localFunctionExplicitCall = nullableFunction.call();
+//                                                    ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+//   var localFunctionTearOff = nullableFunction.call;
+//                                               ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+//   var localFunctionTypeImplicitCall = nullableFunctionType();
+//                                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   var localFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                            ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+//   var localFunctionTypeTearOff = nullableFunctionType.call;
+//                                                       ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionField = nullableClass.functionField();
+//                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionTypeField = nullableClass.functionTypeField();
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionGetter = nullableClass.functionGetter();
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+//                                               ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionBinary = nullableClass + 0;
+//                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionUnary = -nullableClass;
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexGet = nullableClass[0];
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexSet = nullableClass[0] = 1;
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionPropertyGet = nullableClass.extensionProperty;
+//                                                 ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+//                                                 ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+//                                                    ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localExtensionMethodInvocation = nullableClass.extensionMethod();
+//                                                      ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionMethodTearOff = nullableClass.extensionMethod;
+//                                                   ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localExtensionFunctionTypeImplicitCall = nullableClass();
+//                                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+//                                                              ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionFunctionTypeTearOff = nullableClass.call;
+//                                                         ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//       nullableClass.extensionFunctionTypeGetter();
+//                     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int property = 0;
+  field core::Function functionField = () → core::Null? {};
+  field () → void functionTypeField = () → core::Null? {};
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method method() → core::int
+    return 0;
+  get functionGetter() → core::Function
+    return () → core::Null? {};
+  get functionTypeGetter() → () → void
+    return () → core::Null? {};
+}
+extension Extension on self::Class {
+  operator + = self::Extension|+;
+  operator unary- = self::Extension|unary-;
+  operator [] = self::Extension|[];
+  operator []= = self::Extension|[]=;
+  method call = self::Extension|call;
+  tearoff call = self::Extension|get#call;
+  get extensionProperty = self::Extension|get#extensionProperty;
+  method extensionMethod = self::Extension|extensionMethod;
+  tearoff extensionMethod = self::Extension|get#extensionMethod;
+  get extensionFunctionGetter = self::Extension|get#extensionFunctionGetter;
+  get extensionFunctionTypeGetter = self::Extension|get#extensionFunctionTypeGetter;
+  set extensionProperty = self::Extension|set#extensionProperty;
+}
+static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+                                 ^" in self::nullableInt.{core::num::+}(0);
+static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+                    ^" in self::nullableInt.{core::int::unary-}();
+static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+                                  ^" in self::nullableMap.{core::Map::[]}(0);
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+                                  ^" in #t4.{core::Map::[]=}(#t5, #t6) in #t6;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^" in #t9.{core::Map::[]=}(#t10, #t11) in #t11;
+static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+                                        ^^^^^^^^" in self::nullableClass.{self::Class::property};
+static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+                                        ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+                                           ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+                                           ^^^^^^^^" in #t17.{self::Class::property}).{core::num::+}(1);
+static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+                                             ^^^^^^" in self::nullableClass.{self::Class::method}();
+static field () → core::int topLevelMethodTearOff = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+                                          ^^^^^^" in self::nullableClass.{self::Class::method};
+static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+                                                   ^" in self::nullableFunction.call();
+static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+                                                    ^^^^" in self::nullableFunction.call();
+static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+                                               ^^^^" in self::nullableFunction.call;
+static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+                                                           ^" in self::nullableFunctionType.call();
+static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                            ^^^^" in self::nullableFunctionType.call();
+static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+                                                       ^^^^" in self::nullableFunctionType.call;
+static field dynamic topLevelFunctionField = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionField = nullableClass.functionField();
+                                          ^" in self::nullableClass.{self::Class::functionField}.call();
+static field void topLevelFunctionTypeField = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+                                              ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+static field dynamic topLevelFunctionGetter = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionGetter = nullableClass.functionGetter();
+                                           ^" in self::nullableClass.{self::Class::functionGetter}.call();
+static field void topLevelFunctionTypeGetter = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+                                               ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+static field core::int topLevelExtensionBinary = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionBinary = nullableClass + 0;
+                                            ^" in self::Extension|+(self::nullableClass, 0);
+static field core::int topLevelExtensionUnary = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionUnary = -nullableClass;
+                             ^" in self::Extension|unary-(self::nullableClass);
+static field core::int topLevelExtensionIndexGet = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGet = nullableClass[0];
+                                             ^" in self::Extension|[](self::nullableClass, 0);
+static field core::int topLevelExtensionIndexSet = let final self::Class? #t35 = self::nullableClass in let final core::int #t36 = 0 in let final core::int #t37 = 1 in let final void #t38 = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+                                             ^" in self::Extension|[]=(#t35, #t36, #t37) in #t37;
+static field core::int topLevelExtensionIndexGetSet = let final self::Class? #t40 = self::nullableClass in let final core::int #t41 = 0 in let final core::int #t42 = (let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+                                                ^" in self::Extension|[](#t40, #t41)).{core::num::+}(1) in let final void #t44 = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+                                                ^" in self::Extension|[]=(#t40, #t41, #t42) in #t42;
+static field core::int topLevelExtensionPropertyGet = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+                                                 ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+static field core::int topLevelExtensionPropertySet = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+                                                 ^^^^^^^^^^^^^^^^^" in let final core::int #t48 = 1 in let final void #t49 = self::Extension|set#extensionProperty(self::nullableClass, #t48) in #t48;
+static field core::int topLevelExtensionPropertyGetSet = let final self::Class? #t50 = self::nullableClass in let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                    ^^^^^^^^^^^^^^^^^" in let final core::int #t52 = (let final<BottomType> #t53 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                    ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t50)).{core::num::+}(1) in let final void #t54 = self::Extension|set#extensionProperty(#t50, #t52) in #t52;
+static field core::int topLevelExtensionMethodInvocation = let final<BottomType> #t55 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+                                                      ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+static field () → core::int topLevelExtensionMethodTearOff = let final<BottomType> #t56 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+                                                   ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeImplicitCall = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+                                                             ^" in self::Extension|call(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeExplicitCall = let final<BottomType> #t58 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+                                                              ^^^^" in self::Extension|call(self::nullableClass);
+static field () → core::int topLevelExtensionFunctionTypeTearOff = let final<BottomType> #t59 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+                                                         ^^^^" in self::Extension|get#call(self::nullableClass);
+static field dynamic topLevelExtensionFunctionGetter = let final<BottomType> #t60 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+                                                    ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+static field void topLevelExtensionFunctionTypeGetter = let final<BottomType> #t61 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+    nullableClass.extensionFunctionTypeGetter();
+                  ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
+static method Extension|+(final self::Class #this, core::int value) → core::int
+  return 0;
+static method Extension|unary-(final self::Class #this) → core::int
+  return 0;
+static method Extension|[](final self::Class #this, core::int index) → core::int
+  return 0;
+static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void {}
+static method Extension|call(final self::Class #this) → core::int
+  return 0;
+static method Extension|get#call(final self::Class #this) → () → core::int
+  return () → core::int => self::Extension|call(#this);
+static method Extension|get#extensionProperty(final self::Class #this) → core::int
+  return 0;
+static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void {}
+static method Extension|extensionMethod(final self::Class #this) → core::int
+  return 0;
+static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+  return () → core::int => self::Extension|extensionMethod(#this);
+static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+  return () → core::Null? {};
+static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+  return () → core::Null? {};
+static get nullableFunction() → core::Function?
+  return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+  return () → core::Null? {};
+static get nullableInt() → core::int?
+  return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+  return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+  return new self::Class::•();
+static method test() → dynamic {
+  core::int? localBinary = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  var localBinary = nullableInt + 0;
+                                ^" in self::nullableInt.{core::num::+}(0);
+  core::int localUnary = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+  var localUnary = -nullableInt;
+                   ^" in self::nullableInt.{core::int::unary-}();
+  dynamic localIndexGet = let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGet = nullableMap[0];
+                                 ^" in self::nullableMap.{core::Map::[]}(0);
+  core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t65 = self::nullableMap in let final core::int #t66 = 0 in let final core::int #t67 = 1 in let final void #t68 = let final<BottomType> #t69 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexSet = nullableMap[0] = 1;
+                                 ^" in #t65.{core::Map::[]=}(#t66, #t67) in #t67;
+  dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t70 = self::nullableMap in let final core::int #t71 = 0 in let final dynamic #t72 = (let final<BottomType> #t73 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^" in #t70.{core::Map::[]}(#t71)).+(1) in let final void #t74 = let final<BottomType> #t75 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^" in #t70.{core::Map::[]=}(#t71, #t72) in #t72;
+  core::int localPropertyGet = let final<BottomType> #t76 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGet = nullableClass.property;
+                                       ^^^^^^^^" in self::nullableClass.{self::Class::property};
+  core::int localPropertySet = let final<BottomType> #t77 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertySet = nullableClass.property = 1;
+                                       ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+  core::int localPropertyGetSet = let final self::Class? #t78 = self::nullableClass in let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGetSet = nullableClass.property += 1;
+                                          ^^^^^^^^" in #t78.{self::Class::property} = (let final<BottomType> #t80 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGetSet = nullableClass.property += 1;
+                                          ^^^^^^^^" in #t78.{self::Class::property}).{core::num::+}(1);
+  core::int localMethodInvocation = let final<BottomType> #t81 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localMethodInvocation = nullableClass.method();
+                                            ^^^^^^" in self::nullableClass.{self::Class::method}();
+  () → core::int localMethodTearOff = let final<BottomType> #t82 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localMethodTearOff = nullableClass.method;
+                                         ^^^^^^" in self::nullableClass.{self::Class::method};
+  dynamic localFunctionImplicitCall = let final<BottomType> #t83 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+  var localFunctionImplicitCall = nullableFunction();
+                                                  ^" in self::nullableFunction.call();
+  dynamic localFunctionExplicitCall = let final<BottomType> #t84 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+  var localFunctionExplicitCall = nullableFunction.call();
+                                                   ^^^^" in self::nullableFunction.call();
+  core::Function? localFunctionTearOff = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+  var localFunctionTearOff = nullableFunction.call;
+                                              ^^^^" in self::nullableFunction.call;
+  void localFunctionTypeImplicitCall = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+  var localFunctionTypeImplicitCall = nullableFunctionType();
+                                                          ^" in self::nullableFunctionType.call();
+  void localFunctionTypeExplicitCall = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  var localFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                           ^^^^" in self::nullableFunctionType.call();
+  () →? void localFunctionTypeTearOff = let final<BottomType> #t88 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+  var localFunctionTypeTearOff = nullableFunctionType.call;
+                                                      ^^^^" in self::nullableFunctionType.call;
+  dynamic localFunctionField = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionField = nullableClass.functionField();
+                                         ^" in self::nullableClass.{self::Class::functionField}.call();
+  void localFunctionTypeField = let final<BottomType> #t90 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionTypeField = nullableClass.functionTypeField();
+                                             ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+  dynamic localFunctionGetter = let final<BottomType> #t91 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionGetter = nullableClass.functionGetter();
+                                          ^" in self::nullableClass.{self::Class::functionGetter}.call();
+  void localFunctionTypeGetter = let final<BottomType> #t92 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+                                              ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+  core::int localExtensionBinary = let final<BottomType> #t93 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionBinary = nullableClass + 0;
+                                           ^" in self::Extension|+(self::nullableClass, 0);
+  core::int localExtensionUnary = let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionUnary = -nullableClass;
+                            ^" in self::Extension|unary-(self::nullableClass);
+  core::int localExtensionIndexGet = let final<BottomType> #t95 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexGet = nullableClass[0];
+                                            ^" in self::Extension|[](self::nullableClass, 0);
+  core::int localExtensionIndexSet = let final self::Class? #t96 = self::nullableClass in let final core::int #t97 = 0 in let final core::int #t98 = 1 in let final void #t99 = let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexSet = nullableClass[0] = 1;
+                                            ^" in self::Extension|[]=(#t96, #t97, #t98) in #t98;
+  core::int localExtensionIndexGetSet = let final self::Class? #t101 = self::nullableClass in let final core::int #t102 = 0 in let final core::int #t103 = (let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexGetSet = nullableClass[0] += 1;
+                                               ^" in self::Extension|[](#t101, #t102)).{core::num::+}(1) in let final void #t105 = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexGetSet = nullableClass[0] += 1;
+                                               ^" in self::Extension|[]=(#t101, #t102, #t103) in #t103;
+  core::int localExtensionPropertyGet = let final<BottomType> #t107 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertyGet = nullableClass.extensionProperty;
+                                                ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+  core::int localExtensionPropertySet = let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+                                                ^^^^^^^^^^^^^^^^^" in let final core::int #t109 = 1 in let final void #t110 = self::Extension|set#extensionProperty(self::nullableClass, #t109) in #t109;
+  core::int localExtensionPropertyGetSet = let final self::Class? #t111 = self::nullableClass in let final<BottomType> #t112 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                   ^^^^^^^^^^^^^^^^^" in let final core::int #t113 = (let final<BottomType> #t114 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                   ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t111)).{core::num::+}(1) in let final void #t115 = self::Extension|set#extensionProperty(#t111, #t113) in #t113;
+  core::int localExtensionMethodInvocation = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localExtensionMethodInvocation = nullableClass.extensionMethod();
+                                                     ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+  () → core::int localExtensionMethodTearOff = let final<BottomType> #t117 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionMethodTearOff = nullableClass.extensionMethod;
+                                                  ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+  core::int localExtensionFunctionTypeImplicitCall = let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localExtensionFunctionTypeImplicitCall = nullableClass();
+                                                            ^" in self::Extension|call(self::nullableClass);
+  core::int localExtensionFunctionTypeExplicitCall = let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+                                                             ^^^^" in self::Extension|call(self::nullableClass);
+  () → core::int localExtensionFunctionTypeTearOff = let final<BottomType> #t120 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionFunctionTypeTearOff = nullableClass.call;
+                                                        ^^^^" in self::Extension|get#call(self::nullableClass);
+  dynamic localExtensionFunctionGetter = let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+                                                   ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+  void localExtensionFunctionTypeGetter = let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+      nullableClass.extensionFunctionTypeGetter();
+                    ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..f0ea1d5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect
@@ -0,0 +1,356 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+//                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+//                                            ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+//                                              ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+//                                           ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+//                                                     ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+//                                                ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+//                                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                             ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+//                                                        ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   var localBinary = nullableInt + 0;
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+//   var localUnary = -nullableInt;
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGet = nullableMap[0];
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexSet = nullableMap[0] = 1;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGet = nullableClass.property;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertySet = nullableClass.property = 1;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGetSet = nullableClass.property += 1;
+//                                           ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localMethodInvocation = nullableClass.method();
+//                                             ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localMethodTearOff = nullableClass.method;
+//                                          ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+//   var localFunctionImplicitCall = nullableFunction();
+//                                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+//   var localFunctionExplicitCall = nullableFunction.call();
+//                                                    ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+//   var localFunctionTearOff = nullableFunction.call;
+//                                               ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   var localFunctionTypeImplicitCall = nullableFunctionType();
+//                                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   var localFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                            ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+//   var localFunctionTypeTearOff = nullableFunctionType.call;
+//                                                       ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int property = 0;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method method() → core::int
+    return 0;
+}
+static field core::num topLevelBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+                                 ^";
+static field core::int topLevelUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+                    ^";
+static field dynamic topLevelIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+                                  ^";
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t1 = self::nullableMap in let final core::int #t2 = 0 in let final core::int #t3 = 1 in let final void #t4 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+                                  ^" in #t3;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t5 = self::nullableMap in let final core::int #t6 = 0 in let final dynamic #t7 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^".+(1) in let final void #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^" in #t7;
+static field core::int topLevelPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+                                        ^^^^^^^^";
+static field core::int topLevelPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+                                        ^^^^^^^^";
+static field core::int topLevelPropertyGetSet = let final self::Class? #t9 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+                                           ^^^^^^^^";
+static field dynamic topLevelMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+                                             ^^^^^^";
+static field () → core::int topLevelMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+                                          ^^^^^^";
+static field dynamic topLevelFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+                                                   ^";
+static field dynamic topLevelFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+                                                    ^^^^";
+static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+                                               ^^^^";
+static field dynamic topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+                                                           ^";
+static field dynamic topLevelFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                            ^^^^";
+static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+                                                       ^^^^";
+static get nullableFunction() → core::Function?
+  return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+  return () → core::Null? {};
+static get nullableInt() → core::int?
+  return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+  return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+  return new self::Class::•();
+static method test() → dynamic {
+  core::num localBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  var localBinary = nullableInt + 0;
+                                ^";
+  core::int localUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+  var localUnary = -nullableInt;
+                   ^";
+  dynamic localIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGet = nullableMap[0];
+                                 ^";
+  core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t10 = self::nullableMap in let final core::int #t11 = 0 in let final core::int #t12 = 1 in let final void #t13 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexSet = nullableMap[0] = 1;
+                                 ^" in #t12;
+  dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t14 = self::nullableMap in let final core::int #t15 = 0 in let final dynamic #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^".+(1) in let final void #t17 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^" in #t16;
+  core::int localPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGet = nullableClass.property;
+                                       ^^^^^^^^";
+  core::int localPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertySet = nullableClass.property = 1;
+                                       ^^^^^^^^";
+  core::int localPropertyGetSet = let final self::Class? #t18 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGetSet = nullableClass.property += 1;
+                                          ^^^^^^^^";
+  dynamic localMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localMethodInvocation = nullableClass.method();
+                                            ^^^^^^";
+  () → core::int localMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localMethodTearOff = nullableClass.method;
+                                         ^^^^^^";
+  dynamic localFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+  var localFunctionImplicitCall = nullableFunction();
+                                                  ^";
+  dynamic localFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+  var localFunctionExplicitCall = nullableFunction.call();
+                                                   ^^^^";
+  core::Function? localFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+  var localFunctionTearOff = nullableFunction.call;
+                                              ^^^^";
+  dynamic localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  var localFunctionTypeImplicitCall = nullableFunctionType();
+                                                          ^";
+  dynamic localFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  var localFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                           ^^^^";
+  () →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+  var localFunctionTypeTearOff = nullableFunctionType.call;
+                                                      ^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
new file mode 100644
index 0000000..05e9dc0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+class Class {
+  int property = 0;
+  int method() => 0;
+  Function functionField = () {};
+  void Function() functionTypeField = () {};
+  Function get functionGetter => () {};
+  void Function() get functionTypeGetter => () {};
+}
+extension Extension ;
+on Class (){ }
+Function? get nullableFunction => () {};
+void Function()? get nullableFunctionType => () {};
+int? get nullableInt => 0;
+Map<dynamic, dynamic>? get nullableMap => {};
+Class? get nullableClass => new Class();
+var topLevelBinary = nullableInt + 0;
+var topLevelUnary = -nullableInt;
+var topLevelIndexGet = nullableMap[0];
+var topLevelIndexSet = nullableMap[0] = 1;
+var topLevelIndexGetSet = nullableMap[0] += 1;
+var topLevelPropertyGet = nullableClass.property;
+var topLevelPropertySet = nullableClass.property = 1;
+var topLevelPropertyGetSet = nullableClass.property += 1;
+var topLevelMethodInvocation = nullableClass.method();
+var topLevelMethodTearOff = nullableClass.method;
+var topLevelFunctionImplicitCall = nullableFunction();
+var topLevelFunctionExplicitCall = nullableFunction.call();
+var topLevelFunctionTearOff = nullableFunction.call;
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+var topLevelFunctionField = nullableClass.functionField();
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+var topLevelFunctionGetter = nullableClass.functionGetter();
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+var topLevelExtensionBinary = nullableClass + 0;
+var topLevelExtensionUnary = -nullableClass;
+var topLevelExtensionIndexGet = nullableClass[0];
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+var topLevelExtensionFunctionTypeGetter = nullableClass.extensionFunctionTypeGetter();
+test() { }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
new file mode 100644
index 0000000..7c80c76
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
@@ -0,0 +1,828 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+//                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+//                                            ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+//                                              ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+//                                           ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+//                                                     ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+//                                                ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+//                                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                             ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+//                                                        ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionField = nullableClass.functionField();
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeField = nullableClass.functionTypeField();
+//                                               ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionGetter = nullableClass.functionGetter();
+//                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+//                                                ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionBinary = nullableClass + 0;
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionUnary = -nullableClass;
+//                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGet = nullableClass[0];
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexSet = nullableClass[0] = 1;
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+//                                                  ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+//                                                  ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+//                                                     ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+//                                                       ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+//                                                    ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+//                                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+//                                                               ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+//                                                          ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+//                                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//     nullableClass.extensionFunctionTypeGetter();
+//                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   var localBinary = nullableInt + 0;
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+//   var localUnary = -nullableInt;
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGet = nullableMap[0];
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexSet = nullableMap[0] = 1;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGet = nullableClass.property;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertySet = nullableClass.property = 1;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGetSet = nullableClass.property += 1;
+//                                           ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localMethodInvocation = nullableClass.method();
+//                                             ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localMethodTearOff = nullableClass.method;
+//                                          ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+//   var localFunctionImplicitCall = nullableFunction();
+//                                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+//   var localFunctionExplicitCall = nullableFunction.call();
+//                                                    ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+//   var localFunctionTearOff = nullableFunction.call;
+//                                               ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+//   var localFunctionTypeImplicitCall = nullableFunctionType();
+//                                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   var localFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                            ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+//   var localFunctionTypeTearOff = nullableFunctionType.call;
+//                                                       ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionField = nullableClass.functionField();
+//                                          ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionTypeField = nullableClass.functionTypeField();
+//                                              ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionGetter = nullableClass.functionGetter();
+//                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+//                                               ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionBinary = nullableClass + 0;
+//                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionUnary = -nullableClass;
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexGet = nullableClass[0];
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexSet = nullableClass[0] = 1;
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+//   var localExtensionIndexGetSet = nullableClass[0] += 1;
+//                                                ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionPropertyGet = nullableClass.extensionProperty;
+//                                                 ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+//                                                 ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+//                                                    ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localExtensionMethodInvocation = nullableClass.extensionMethod();
+//                                                      ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionMethodTearOff = nullableClass.extensionMethod;
+//                                                   ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localExtensionFunctionTypeImplicitCall = nullableClass();
+//                                                             ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+//                                                              ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localExtensionFunctionTypeTearOff = nullableClass.call;
+//                                                         ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//   var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+//       nullableClass.extensionFunctionTypeGetter();
+//                     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int property = 0;
+  field core::Function functionField = () → core::Null? {};
+  field () → void functionTypeField = () → core::Null? {};
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method method() → core::int
+    return 0;
+  get functionGetter() → core::Function
+    return () → core::Null? {};
+  get functionTypeGetter() → () → void
+    return () → core::Null? {};
+}
+extension Extension on self::Class {
+  operator + = self::Extension|+;
+  operator unary- = self::Extension|unary-;
+  operator [] = self::Extension|[];
+  operator []= = self::Extension|[]=;
+  method call = self::Extension|call;
+  tearoff call = self::Extension|get#call;
+  get extensionProperty = self::Extension|get#extensionProperty;
+  method extensionMethod = self::Extension|extensionMethod;
+  tearoff extensionMethod = self::Extension|get#extensionMethod;
+  get extensionFunctionGetter = self::Extension|get#extensionFunctionGetter;
+  get extensionFunctionTypeGetter = self::Extension|get#extensionFunctionTypeGetter;
+  set extensionProperty = self::Extension|set#extensionProperty;
+}
+static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+                                 ^" in self::nullableInt.{core::num::+}(0);
+static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+                    ^" in self::nullableInt.{core::int::unary-}();
+static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+                                  ^" in self::nullableMap.{core::Map::[]}(0);
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+                                  ^" in #t4.{core::Map::[]=}(#t5, #t6) in #t6;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^" in #t9.{core::Map::[]=}(#t10, #t11) in #t11;
+static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+                                        ^^^^^^^^" in self::nullableClass.{self::Class::property};
+static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+                                        ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+                                           ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+                                           ^^^^^^^^" in #t17.{self::Class::property}).{core::num::+}(1);
+static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+                                             ^^^^^^" in self::nullableClass.{self::Class::method}();
+static field () → core::int topLevelMethodTearOff = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+                                          ^^^^^^" in self::nullableClass.{self::Class::method};
+static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+                                                   ^" in self::nullableFunction.call();
+static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+                                                    ^^^^" in self::nullableFunction.call();
+static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+                                               ^^^^" in self::nullableFunction.call;
+static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+                                                           ^" in self::nullableFunctionType.call();
+static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                            ^^^^" in self::nullableFunctionType.call();
+static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+                                                       ^^^^" in self::nullableFunctionType.call;
+static field dynamic topLevelFunctionField = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionField = nullableClass.functionField();
+                                          ^" in self::nullableClass.{self::Class::functionField}.call();
+static field void topLevelFunctionTypeField = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+                                              ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+static field dynamic topLevelFunctionGetter = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionGetter = nullableClass.functionGetter();
+                                           ^" in self::nullableClass.{self::Class::functionGetter}.call();
+static field void topLevelFunctionTypeGetter = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+                                               ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+static field core::int topLevelExtensionBinary = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionBinary = nullableClass + 0;
+                                            ^" in self::Extension|+(self::nullableClass, 0);
+static field core::int topLevelExtensionUnary = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionUnary = -nullableClass;
+                             ^" in self::Extension|unary-(self::nullableClass);
+static field core::int topLevelExtensionIndexGet = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGet = nullableClass[0];
+                                             ^" in self::Extension|[](self::nullableClass, 0);
+static field core::int topLevelExtensionIndexSet = let final self::Class? #t35 = self::nullableClass in let final core::int #t36 = 0 in let final core::int #t37 = 1 in let final void #t38 = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+                                             ^" in self::Extension|[]=(#t35, #t36, #t37) in #t37;
+static field core::int topLevelExtensionIndexGetSet = let final self::Class? #t40 = self::nullableClass in let final core::int #t41 = 0 in let final core::int #t42 = (let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+                                                ^" in self::Extension|[](#t40, #t41)).{core::num::+}(1) in let final void #t44 = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+                                                ^" in self::Extension|[]=(#t40, #t41, #t42) in #t42;
+static field core::int topLevelExtensionPropertyGet = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+                                                 ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+static field core::int topLevelExtensionPropertySet = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+                                                 ^^^^^^^^^^^^^^^^^" in let final core::int #t48 = 1 in let final void #t49 = self::Extension|set#extensionProperty(self::nullableClass, #t48) in #t48;
+static field core::int topLevelExtensionPropertyGetSet = let final self::Class? #t50 = self::nullableClass in let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                    ^^^^^^^^^^^^^^^^^" in let final core::int #t52 = (let final<BottomType> #t53 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                    ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t50)).{core::num::+}(1) in let final void #t54 = self::Extension|set#extensionProperty(#t50, #t52) in #t52;
+static field core::int topLevelExtensionMethodInvocation = let final<BottomType> #t55 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+                                                      ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+static field () → core::int topLevelExtensionMethodTearOff = let final<BottomType> #t56 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+                                                   ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeImplicitCall = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+                                                             ^" in self::Extension|call(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeExplicitCall = let final<BottomType> #t58 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+                                                              ^^^^" in self::Extension|call(self::nullableClass);
+static field () → core::int topLevelExtensionFunctionTypeTearOff = let final<BottomType> #t59 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+                                                         ^^^^" in self::Extension|get#call(self::nullableClass);
+static field dynamic topLevelExtensionFunctionGetter = let final<BottomType> #t60 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+                                                    ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+static field void topLevelExtensionFunctionTypeGetter = let final<BottomType> #t61 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+    nullableClass.extensionFunctionTypeGetter();
+                  ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
+static method Extension|+(final self::Class #this, core::int value) → core::int
+  return 0;
+static method Extension|unary-(final self::Class #this) → core::int
+  return 0;
+static method Extension|[](final self::Class #this, core::int index) → core::int
+  return 0;
+static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void {}
+static method Extension|call(final self::Class #this) → core::int
+  return 0;
+static method Extension|get#call(final self::Class #this) → () → core::int
+  return () → core::int => self::Extension|call(#this);
+static method Extension|get#extensionProperty(final self::Class #this) → core::int
+  return 0;
+static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void {}
+static method Extension|extensionMethod(final self::Class #this) → core::int
+  return 0;
+static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+  return () → core::int => self::Extension|extensionMethod(#this);
+static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+  return () → core::Null? {};
+static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+  return () → core::Null? {};
+static get nullableFunction() → core::Function?
+  return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+  return () → core::Null? {};
+static get nullableInt() → core::int?
+  return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+  return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+  return new self::Class::•();
+static method test() → dynamic {
+  core::int? localBinary = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  var localBinary = nullableInt + 0;
+                                ^" in self::nullableInt.{core::num::+}(0);
+  core::int localUnary = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+  var localUnary = -nullableInt;
+                   ^" in self::nullableInt.{core::int::unary-}();
+  dynamic localIndexGet = let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGet = nullableMap[0];
+                                 ^" in self::nullableMap.{core::Map::[]}(0);
+  core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t65 = self::nullableMap in let final core::int #t66 = 0 in let final core::int #t67 = 1 in let final void #t68 = let final<BottomType> #t69 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexSet = nullableMap[0] = 1;
+                                 ^" in #t65.{core::Map::[]=}(#t66, #t67) in #t67;
+  dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t70 = self::nullableMap in let final core::int #t71 = 0 in let final dynamic #t72 = (let final<BottomType> #t73 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^" in #t70.{core::Map::[]}(#t71)).+(1) in let final void #t74 = let final<BottomType> #t75 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^" in #t70.{core::Map::[]=}(#t71, #t72) in #t72;
+  core::int localPropertyGet = let final<BottomType> #t76 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGet = nullableClass.property;
+                                       ^^^^^^^^" in self::nullableClass.{self::Class::property};
+  core::int localPropertySet = let final<BottomType> #t77 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertySet = nullableClass.property = 1;
+                                       ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+  core::int localPropertyGetSet = let final self::Class? #t78 = self::nullableClass in let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGetSet = nullableClass.property += 1;
+                                          ^^^^^^^^" in #t78.{self::Class::property} = (let final<BottomType> #t80 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGetSet = nullableClass.property += 1;
+                                          ^^^^^^^^" in #t78.{self::Class::property}).{core::num::+}(1);
+  core::int localMethodInvocation = let final<BottomType> #t81 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localMethodInvocation = nullableClass.method();
+                                            ^^^^^^" in self::nullableClass.{self::Class::method}();
+  () → core::int localMethodTearOff = let final<BottomType> #t82 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localMethodTearOff = nullableClass.method;
+                                         ^^^^^^" in self::nullableClass.{self::Class::method};
+  dynamic localFunctionImplicitCall = let final<BottomType> #t83 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+  var localFunctionImplicitCall = nullableFunction();
+                                                  ^" in self::nullableFunction.call();
+  dynamic localFunctionExplicitCall = let final<BottomType> #t84 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+  var localFunctionExplicitCall = nullableFunction.call();
+                                                   ^^^^" in self::nullableFunction.call();
+  core::Function? localFunctionTearOff = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+  var localFunctionTearOff = nullableFunction.call;
+                                              ^^^^" in self::nullableFunction.call;
+  void localFunctionTypeImplicitCall = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+  var localFunctionTypeImplicitCall = nullableFunctionType();
+                                                          ^" in self::nullableFunctionType.call();
+  void localFunctionTypeExplicitCall = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  var localFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                           ^^^^" in self::nullableFunctionType.call();
+  () →? void localFunctionTypeTearOff = let final<BottomType> #t88 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+  var localFunctionTypeTearOff = nullableFunctionType.call;
+                                                      ^^^^" in self::nullableFunctionType.call;
+  dynamic localFunctionField = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionField = nullableClass.functionField();
+                                         ^" in self::nullableClass.{self::Class::functionField}.call();
+  void localFunctionTypeField = let final<BottomType> #t90 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionTypeField = nullableClass.functionTypeField();
+                                             ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+  dynamic localFunctionGetter = let final<BottomType> #t91 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionGetter = nullableClass.functionGetter();
+                                          ^" in self::nullableClass.{self::Class::functionGetter}.call();
+  void localFunctionTypeGetter = let final<BottomType> #t92 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+                                              ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+  core::int localExtensionBinary = let final<BottomType> #t93 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionBinary = nullableClass + 0;
+                                           ^" in self::Extension|+(self::nullableClass, 0);
+  core::int localExtensionUnary = let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionUnary = -nullableClass;
+                            ^" in self::Extension|unary-(self::nullableClass);
+  core::int localExtensionIndexGet = let final<BottomType> #t95 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexGet = nullableClass[0];
+                                            ^" in self::Extension|[](self::nullableClass, 0);
+  core::int localExtensionIndexSet = let final self::Class? #t96 = self::nullableClass in let final core::int #t97 = 0 in let final core::int #t98 = 1 in let final void #t99 = let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexSet = nullableClass[0] = 1;
+                                            ^" in self::Extension|[]=(#t96, #t97, #t98) in #t98;
+  core::int localExtensionIndexGetSet = let final self::Class? #t101 = self::nullableClass in let final core::int #t102 = 0 in let final core::int #t103 = (let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexGetSet = nullableClass[0] += 1;
+                                               ^" in self::Extension|[](#t101, #t102)).{core::num::+}(1) in let final void #t105 = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+  var localExtensionIndexGetSet = nullableClass[0] += 1;
+                                               ^" in self::Extension|[]=(#t101, #t102, #t103) in #t103;
+  core::int localExtensionPropertyGet = let final<BottomType> #t107 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertyGet = nullableClass.extensionProperty;
+                                                ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+  core::int localExtensionPropertySet = let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+                                                ^^^^^^^^^^^^^^^^^" in let final core::int #t109 = 1 in let final void #t110 = self::Extension|set#extensionProperty(self::nullableClass, #t109) in #t109;
+  core::int localExtensionPropertyGetSet = let final self::Class? #t111 = self::nullableClass in let final<BottomType> #t112 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                   ^^^^^^^^^^^^^^^^^" in let final core::int #t113 = (let final<BottomType> #t114 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+                                                   ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t111)).{core::num::+}(1) in let final void #t115 = self::Extension|set#extensionProperty(#t111, #t113) in #t113;
+  core::int localExtensionMethodInvocation = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localExtensionMethodInvocation = nullableClass.extensionMethod();
+                                                     ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+  () → core::int localExtensionMethodTearOff = let final<BottomType> #t117 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionMethodTearOff = nullableClass.extensionMethod;
+                                                  ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+  core::int localExtensionFunctionTypeImplicitCall = let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localExtensionFunctionTypeImplicitCall = nullableClass();
+                                                            ^" in self::Extension|call(self::nullableClass);
+  core::int localExtensionFunctionTypeExplicitCall = let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+                                                             ^^^^" in self::Extension|call(self::nullableClass);
+  () → core::int localExtensionFunctionTypeTearOff = let final<BottomType> #t120 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localExtensionFunctionTypeTearOff = nullableClass.call;
+                                                        ^^^^" in self::Extension|get#call(self::nullableClass);
+  dynamic localExtensionFunctionGetter = let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+  var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+                                                   ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+  void localExtensionFunctionTypeGetter = let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+      nullableClass.extensionFunctionTypeGetter();
+                    ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect
new file mode 100644
index 0000000..f0ea1d5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect
@@ -0,0 +1,356 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+//                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+//                                      ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+//                                            ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+//                                              ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+//                                           ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+//                                                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+//                                                     ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+//                                                ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+//                                                            ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                             ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+//                                                        ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   var localBinary = nullableInt + 0;
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+//   var localUnary = -nullableInt;
+//                    ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGet = nullableMap[0];
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexSet = nullableMap[0] = 1;
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+//  - 'Map' is from 'dart:core'.
+//   var localIndexGetSet = nullableMap[0] += 1;
+//                                     ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGet = nullableClass.property;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertySet = nullableClass.property = 1;
+//                                        ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localPropertyGetSet = nullableClass.property += 1;
+//                                           ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+//   var localMethodInvocation = nullableClass.method();
+//                                             ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+//   var localMethodTearOff = nullableClass.method;
+//                                          ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+//   var localFunctionImplicitCall = nullableFunction();
+//                                                   ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+//   var localFunctionExplicitCall = nullableFunction.call();
+//                                                    ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+//  - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+//   var localFunctionTearOff = nullableFunction.call;
+//                                               ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   var localFunctionTypeImplicitCall = nullableFunctionType();
+//                                                           ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   var localFunctionTypeExplicitCall = nullableFunctionType.call();
+//                                                            ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+//   var localFunctionTypeTearOff = nullableFunctionType.call;
+//                                                       ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int property = 0;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method method() → core::int
+    return 0;
+}
+static field core::num topLevelBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+                                 ^";
+static field core::int topLevelUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+                    ^";
+static field dynamic topLevelIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+                                  ^";
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t1 = self::nullableMap in let final core::int #t2 = 0 in let final core::int #t3 = 1 in let final void #t4 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+                                  ^" in #t3;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t5 = self::nullableMap in let final core::int #t6 = 0 in let final dynamic #t7 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^".+(1) in let final void #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+                                     ^" in #t7;
+static field core::int topLevelPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+                                        ^^^^^^^^";
+static field core::int topLevelPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+                                        ^^^^^^^^";
+static field core::int topLevelPropertyGetSet = let final self::Class? #t9 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+                                           ^^^^^^^^";
+static field dynamic topLevelMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+                                             ^^^^^^";
+static field () → core::int topLevelMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+                                          ^^^^^^";
+static field dynamic topLevelFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+                                                   ^";
+static field dynamic topLevelFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+                                                    ^^^^";
+static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+                                               ^^^^";
+static field dynamic topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+                                                           ^";
+static field dynamic topLevelFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                            ^^^^";
+static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+                                                       ^^^^";
+static get nullableFunction() → core::Function?
+  return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+  return () → core::Null? {};
+static get nullableInt() → core::int?
+  return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+  return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+  return new self::Class::•();
+static method test() → dynamic {
+  core::num localBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  var localBinary = nullableInt + 0;
+                                ^";
+  core::int localUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+  var localUnary = -nullableInt;
+                   ^";
+  dynamic localIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGet = nullableMap[0];
+                                 ^";
+  core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t10 = self::nullableMap in let final core::int #t11 = 0 in let final core::int #t12 = 1 in let final void #t13 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexSet = nullableMap[0] = 1;
+                                 ^" in #t12;
+  dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t14 = self::nullableMap in let final core::int #t15 = 0 in let final dynamic #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^".+(1) in let final void #t17 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+  var localIndexGetSet = nullableMap[0] += 1;
+                                    ^" in #t16;
+  core::int localPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGet = nullableClass.property;
+                                       ^^^^^^^^";
+  core::int localPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertySet = nullableClass.property = 1;
+                                       ^^^^^^^^";
+  core::int localPropertyGetSet = let final self::Class? #t18 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localPropertyGetSet = nullableClass.property += 1;
+                                          ^^^^^^^^";
+  dynamic localMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+  var localMethodInvocation = nullableClass.method();
+                                            ^^^^^^";
+  () → core::int localMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+  var localMethodTearOff = nullableClass.method;
+                                         ^^^^^^";
+  dynamic localFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+  var localFunctionImplicitCall = nullableFunction();
+                                                  ^";
+  dynamic localFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+  var localFunctionExplicitCall = nullableFunction.call();
+                                                   ^^^^";
+  core::Function? localFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+  var localFunctionTearOff = nullableFunction.call;
+                                              ^^^^";
+  dynamic localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  var localFunctionTypeImplicitCall = nullableFunctionType();
+                                                          ^";
+  dynamic localFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  var localFunctionTypeExplicitCall = nullableFunctionType.call();
+                                                           ^^^^";
+  () →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+  var localFunctionTypeTearOff = nullableFunctionType.call;
+                                                      ^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.strong.transformed.expect
index a7e6b48..14ff5aa 100644
--- a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 class Class extends core::Object {
@@ -15,7 +14,7 @@
       #t1.{core::List::add}(node);
       final core::Iterable<core::String*>* #t2 = let final core::Iterable<core::String*>* #t3 = let final core::Set<core::String*>* #t4 = this.{self::Class::map}.{core::Map::[]}(node) in #t4.{core::Object::==}(null) ?{core::Iterable<core::String*>*} null : #t4.{core::Iterable::expand}<core::String*>((core::String* node) → core::List<core::String*>* => this.{self::Class::method}(node, set)) in #t3.{core::Object::==}(null) ?{core::List<core::String*>*} null : #t3.{core::Iterable::toList}();
       if(!#t2.{core::Object::==}(null)) {
-        core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t2).{core::Iterable::iterator};
+        core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::String* #t5 = :sync-for-iterator.{core::Iterator::current};
           #t1.{core::List::add}(#t5);
diff --git a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..c2626cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Class {
+  Map<String, Set<String>> map;
+  List<String> method(String node, Set<String> set) => set.add(node)
+      ? [node, ...?map[node]?.expand((node) => method(node, set))?.toList()]
+      : [];
+}
+
+main(args) {}
diff --git a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..655c194
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Class {
+  List<String> method(String node, Set<String> set) => set.add(node)
+      ? [node, ...?map[node]?.expand((node) => method(node, set))?.toList()]
+      : [];
+  Map<String, Set<String>> map;
+}
+
+main(args) {}
diff --git a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.weak.transformed.expect
index a7e6b48..14ff5aa 100644
--- a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.weak.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 class Class extends core::Object {
@@ -15,7 +14,7 @@
       #t1.{core::List::add}(node);
       final core::Iterable<core::String*>* #t2 = let final core::Iterable<core::String*>* #t3 = let final core::Set<core::String*>* #t4 = this.{self::Class::map}.{core::Map::[]}(node) in #t4.{core::Object::==}(null) ?{core::Iterable<core::String*>*} null : #t4.{core::Iterable::expand}<core::String*>((core::String* node) → core::List<core::String*>* => this.{self::Class::method}(node, set)) in #t3.{core::Object::==}(null) ?{core::List<core::String*>*} null : #t3.{core::Iterable::toList}();
       if(!#t2.{core::Object::==}(null)) {
-        core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(#t2).{core::Iterable::iterator};
+        core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::String* #t5 = :sync-for-iterator.{core::Iterator::current};
           #t1.{core::List::add}(#t5);
diff --git a/pkg/front_end/testcases/nnbd/required.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/required.dart.textual_outline.expect
new file mode 100644
index 0000000..5ddcc25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+method({int a = 42, required int b, required final int c}) {}
+
+class Class {
+  method(
+      {int a = 42,
+      required int b,
+      required final int c,
+      required covariant final int d}) {}
+}
+
+typedef Typedef1 = Function({int a, required int b});
+typedef Typedef2({int a, required int b});
+Function({int a, required int b}) field = ({int a = 42, required int b}) {};
+
+abstract class A {
+  foo({int x});
+}
+
+class B extends A {
+  foo({x}) {}
+}
+
+class C extends A {
+  foo({x = 42}) {}
+}
+
+ok() {}
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/required.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c9af5d3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+Function({int a, required int b}) field = ({int a = 42, required int b}) {};
+
+abstract class A {
+  foo({int x});
+}
+
+class B extends A {
+  foo({x}) {}
+}
+
+class C extends A {
+  foo({x = 42}) {}
+}
+
+class Class {
+  method(
+      {int a = 42,
+      required int b,
+      required final int c,
+      required covariant final int d}) {}
+}
+
+error() {}
+main() {}
+method({int a = 42, required int b, required final int c}) {}
+ok() {}
+typedef Typedef1 = Function({int a, required int b});
+typedef Typedef2({int a, required int b});
diff --git a/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline.expect
new file mode 100644
index 0000000..81c1483
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import 'required_name_override_lib.dart';
+
+class B {
+  void test_default({int? i}) {}
+  void test_nondefault({int? i = 1}) {}
+}
+
+class A extends B implements C {
+  void test_default({required int? i}) {}
+  void test_nondefault({required int? i}) {}
+  void test_legacy({required int? i}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ad5428
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import 'required_name_override_lib.dart';
+
+class A extends B implements C {
+  void test_default({required int? i}) {}
+  void test_legacy({required int? i}) {}
+  void test_nondefault({required int? i}) {}
+}
+
+class B {
+  void test_default({int? i}) {}
+  void test_nondefault({int? i = 1}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..63a8f9e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+foo({required int parameter = 42}) {}
+foo2({int parameter}) {}
+foo3([int parameter]) {}
+bar({required int parameter}) {}
+bar2({int parameter = 42}) {}
+bar3([int parameter = 42]) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a48b7f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+bar({required int parameter}) {}
+bar2({int parameter = 42}) {}
+bar3([int parameter = 42]) {}
+foo({required int parameter = 42}) {}
+foo2({int parameter}) {}
+foo3([int parameter]) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline.expect
new file mode 100644
index 0000000..3d93fd2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+  final E field;
+  Class(this.field);
+  E returnTypeVariable() {}
+}
+
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1ef11f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+  Class(this.field);
+  E returnTypeVariable() {}
+  final E field;
+}
+
+expect(expected, actual) {}
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
index 336e616..f5bbf44 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
@@ -6,11 +6,11 @@
 // String returnImplicit() /*error*/ {
 //        ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //   return null; // error
 //          ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
@@ -31,11 +31,11 @@
 //   String returnImplicit() /* error */ {
 //   ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //       return null; // error
 //              ^
 //
@@ -82,14 +82,14 @@
 }
 static method returnExplicit() → core::String {
   core::print("foo");
-  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
   return null; // error
          ^" in null as{TypeError,ForNonNullableByDefault} core::String;
 }
 static method returnMixed(core::bool b) → core::String {
   if(b) {
     core::print("foo");
-    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
@@ -151,14 +151,14 @@
   }
   function returnExplicit() → core::String {
     core::print("foo");
-    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
   function returnMixed(core::bool b) → core::String {
     if(b) {
       core::print("foo");
-      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
       return null; // error
              ^" in null as{TypeError,ForNonNullableByDefault} core::String;
     }
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index 7c0e736..1b65644 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -6,11 +6,11 @@
 // String returnImplicit() /*error*/ {
 //        ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //   return null; // error
 //          ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
@@ -31,11 +31,11 @@
 //   String returnImplicit() /* error */ {
 //   ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //       return null; // error
 //              ^
 //
@@ -82,14 +82,14 @@
 }
 static method returnExplicit() → core::String {
   core::print("foo");
-  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
   return null; // error
          ^" in null as{TypeError,ForNonNullableByDefault} core::String;
 }
 static method returnMixed(core::bool b) → core::String {
   if(b) {
     core::print("foo");
-    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
@@ -101,8 +101,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -112,21 +112,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync2() → asy::FutureOr<dynamic> /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -136,21 +136,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync3() → asy::FutureOr<core::int> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
   asy::FutureOr<core::int>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -165,21 +165,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync4() → asy::FutureOr<core::int?> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
   asy::FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -189,21 +189,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync5() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -213,21 +213,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync6() → asy::Future<core::int?> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
   asy::FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -240,21 +240,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync7() → asy::Future<core::int?> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
   asy::FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -264,13 +264,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
@@ -286,8 +286,8 @@
   asy::_AsyncStarStreamController<dynamic>? :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -297,7 +297,7 @@
         {}
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -349,14 +349,14 @@
   }
   function returnExplicit() → core::String {
     core::print("foo");
-    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
   function returnMixed(core::bool b) → core::String {
     if(b) {
       core::print("foo");
-      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
       return null; // error
              ^" in null as{TypeError,ForNonNullableByDefault} core::String;
     }
@@ -368,8 +368,8 @@
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -379,21 +379,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync2() → asy::FutureOr<dynamic> /* originally async */ {
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -403,21 +403,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync3() → asy::FutureOr<core::int> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
     asy::FutureOr<core::int>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -432,21 +432,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync4() → asy::FutureOr<core::int?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
     asy::FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -456,21 +456,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync5() → asy::Future<core::Null?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::Null?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
     asy::FutureOr<core::Null?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -480,21 +480,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync6() → asy::Future<core::int?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
     asy::FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -507,21 +507,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync7() → asy::Future<core::int?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
     asy::FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -531,13 +531,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
@@ -553,8 +553,8 @@
     asy::_AsyncStarStreamController<dynamic>? :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -564,7 +564,7 @@
           {}
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline.expect
new file mode 100644
index 0000000..0823c8f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import 'dart:async';
+
+String returnImplicit() {}
+String returnExplicit() {}
+String returnMixed(bool b) {}
+Future returnAsync1() async {}
+FutureOr returnAsync2() async {}
+FutureOr<int> returnAsync3() async {}
+FutureOr<int?> returnAsync4() async {}
+returnAsync5() async {}
+Future<int?> returnAsync6() async {}
+Future<int?> returnAsync7() async {}
+Iterable yieldSync() sync* {}
+Stream yieldAsync() async* {}
+enum Enum { a, b }
+Enum caseReturn1(Enum e) {}
+Enum caseReturn2(Enum e) {}
+localFunctions() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d7cbcb6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import 'dart:async';
+
+Enum caseReturn1(Enum e) {}
+Enum caseReturn2(Enum e) {}
+Future returnAsync1() async {}
+Future<int?> returnAsync6() async {}
+Future<int?> returnAsync7() async {}
+FutureOr returnAsync2() async {}
+FutureOr<int> returnAsync3() async {}
+FutureOr<int?> returnAsync4() async {}
+Iterable yieldSync() sync* {}
+Stream yieldAsync() async* {}
+String returnExplicit() {}
+String returnImplicit() {}
+String returnMixed(bool b) {}
+enum Enum { a, b }
+localFunctions() {}
+main() {}
+returnAsync5() async {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
index 9180305..397d54c 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
@@ -6,11 +6,11 @@
 // String returnImplicit() /*error*/ {
 //        ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //   return null; // error
 //          ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
@@ -31,11 +31,11 @@
 //   String returnImplicit() /* error */ {
 //   ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //       return null; // error
 //              ^
 //
@@ -82,14 +82,14 @@
 }
 static method returnExplicit() → core::String {
   core::print("foo");
-  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
   return null; // error
          ^" in null as{TypeError,ForNonNullableByDefault} core::String;
 }
 static method returnMixed(core::bool b) → core::String {
   if(b) {
     core::print("foo");
-    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
@@ -151,14 +151,14 @@
   }
   function returnExplicit() → core::String {
     core::print("foo");
-    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
   function returnMixed(core::bool b) → core::String {
     if(b) {
       core::print("foo");
-      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
       return null; // error
              ^" in null as{TypeError,ForNonNullableByDefault} core::String;
     }
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index 319833c..a41a122 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -6,11 +6,11 @@
 // String returnImplicit() /*error*/ {
 //        ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //   return null; // error
 //          ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
@@ -31,11 +31,11 @@
 //   String returnImplicit() /* error */ {
 //   ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //     return null; // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
 //       return null; // error
 //              ^
 //
@@ -82,14 +82,14 @@
 }
 static method returnExplicit() → core::String {
   core::print("foo");
-  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+  return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
   return null; // error
          ^" in null as{TypeError,ForNonNullableByDefault} core::String;
 }
 static method returnMixed(core::bool b) → core::String {
   if(b) {
     core::print("foo");
-    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
@@ -101,8 +101,8 @@
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -112,21 +112,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync2() → asy::FutureOr<dynamic> /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -136,21 +136,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync3() → asy::FutureOr<core::int> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
   asy::FutureOr<core::int>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -165,21 +165,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync4() → asy::FutureOr<core::int?> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
   asy::FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -189,21 +189,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync5() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -213,21 +213,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync6() → asy::Future<core::int?> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
   asy::FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -240,21 +240,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method returnAsync7() → asy::Future<core::int?> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
   asy::FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -264,13 +264,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
@@ -286,8 +286,8 @@
   asy::_AsyncStarStreamController<dynamic>? :controller;
   dynamic :controller_stream;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) → dynamic :async_op_then;
+  (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -297,7 +297,7 @@
         {}
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
       }
     finally {
@@ -349,14 +349,14 @@
   }
   function returnExplicit() → core::String {
     core::print("foo");
-    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+    return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
     return null; // error
            ^" in null as{TypeError,ForNonNullableByDefault} core::String;
   }
   function returnMixed(core::bool b) → core::String {
     if(b) {
       core::print("foo");
-      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+      return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
       return null; // error
              ^" in null as{TypeError,ForNonNullableByDefault} core::String;
     }
@@ -368,8 +368,8 @@
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -379,21 +379,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync2() → asy::FutureOr<dynamic> /* originally async */ {
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
     asy::FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -403,21 +403,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync3() → asy::FutureOr<core::int> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
     asy::FutureOr<core::int>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -432,21 +432,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync4() → asy::FutureOr<core::int?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
     asy::FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -456,21 +456,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync5() → asy::Future<core::Null?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::Null?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
     asy::FutureOr<core::Null?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -480,21 +480,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync6() → asy::Future<core::int?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
     asy::FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -507,21 +507,21 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function returnAsync7() → asy::Future<core::int?> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
     asy::FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -531,13 +531,13 @@
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
         :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{asy::Completer::future};
   }
   function yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
@@ -553,8 +553,8 @@
     asy::_AsyncStarStreamController<dynamic>? :controller;
     dynamic :controller_stream;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -564,7 +564,7 @@
           {}
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
           :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
         }
       finally {
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline.expect
new file mode 100644
index 0000000..2b0383f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Class {
+  int field = 0;
+  Class get next => this;
+  int operator [](int key) => key;
+  void operator []=(int key, int value) {}
+}
+
+main() {}
+test(Class? c) {}
+final bool inStrongMode = _inStrongMode();
+bool _inStrongMode() {}
+void throwsInStrong(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..704a646
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+bool _inStrongMode() {}
+
+class Class {
+  Class get next => this;
+  int field = 0;
+  int operator [](int key) => key;
+  void operator []=(int key, int value) {}
+}
+
+final bool inStrongMode = _inStrongMode();
+main() {}
+test(Class? c) {}
+void throwsInStrong(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline.expect
new file mode 100644
index 0000000..a729e48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Never foo() {}
+Never? bar() => null;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a729e48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Never foo() {}
+Never? bar() => null;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..920e335
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+abstract class Sink<T> {
+  void close();
+}
+
+abstract class EventSink<T> implements Sink<T> {
+  void close();
+}
+
+abstract class StreamConsumer<S> {
+  Future close();
+}
+
+abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
+  Future close();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b450f4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+abstract class EventSink<T> implements Sink<T> {
+  void close();
+}
+
+abstract class Sink<T> {
+  void close();
+}
+
+abstract class StreamConsumer<S> {
+  Future close();
+}
+
+abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
+  Future close();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
index 3d6a2f4..218772f 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
@@ -102,7 +102,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 class A extends core::Object {
@@ -140,7 +139,7 @@
     final core::List<core::String> #t6 = <core::String>[];
     final core::Iterable<core::String>? #t7 = l;
     if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::String>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String>*>(#t7{core::Iterable<core::String>}).{core::Iterable::iterator};
+      core::Iterator<core::String> :sync-for-iterator = #t7{core::Iterable<core::String>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String #t8 = :sync-for-iterator.{core::Iterator::current};
         #t6.{core::List::add}(#t8);
@@ -151,7 +150,7 @@
     final core::Set<core::String> #t9 = col::LinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t10 = l;
     if(!#t10.{core::Object::==}(null)) {
-      core::Iterator<core::String>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String>*>(#t10{core::Iterable<core::String>}).{core::Iterable::iterator};
+      core::Iterator<core::String> :sync-for-iterator = #t10{core::Iterable<core::String>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -165,7 +164,7 @@
     final core::Set<core::String> #t13 = col::LinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t14 = l;
     if(!#t14.{core::Object::==}(null)) {
-      core::Iterator<core::String>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String>*>(#t14{core::Iterable<core::String>}).{core::Iterable::iterator};
+      core::Iterator<core::String> :sync-for-iterator = #t14{core::Iterable<core::String>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String #t15 = :sync-for-iterator.{core::Iterator::current};
         #t13.{core::Set::add}(#t15);
@@ -176,7 +175,7 @@
     final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
     final core::Map<core::String, core::int>? #t17 = m;
     if(!#t17.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t17{core::Map<core::String, core::int>}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*> :sync-for-iterator = #t17{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String, core::int> #t18 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
@@ -187,7 +186,7 @@
     final core::Map<core::String, core::int> #t19 = <core::String, core::int>{};
     final core::Map<core::String, core::int>? #t20 = m;
     if(!#t20.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t20{core::Map<core::String, core::int>}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*> :sync-for-iterator = #t20{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String, core::int> #t21 = :sync-for-iterator.{core::Iterator::current};
         #t19.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
new file mode 100644
index 0000000..9aff973
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+extension E ;
+on String (){ }
+class A {
+  String operator[](int index) => "foo";
+  void operator[]=(int index, String value) { }
+}
+class B extends A {
+  void test() { }
+}
+warning(String s, List<String> l, Map<String, int> m) { }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
index 3d6a2f4..218772f 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
@@ -102,7 +102,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "dart:collection" as col;
 
 class A extends core::Object {
@@ -140,7 +139,7 @@
     final core::List<core::String> #t6 = <core::String>[];
     final core::Iterable<core::String>? #t7 = l;
     if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::String>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String>*>(#t7{core::Iterable<core::String>}).{core::Iterable::iterator};
+      core::Iterator<core::String> :sync-for-iterator = #t7{core::Iterable<core::String>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String #t8 = :sync-for-iterator.{core::Iterator::current};
         #t6.{core::List::add}(#t8);
@@ -151,7 +150,7 @@
     final core::Set<core::String> #t9 = col::LinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t10 = l;
     if(!#t10.{core::Object::==}(null)) {
-      core::Iterator<core::String>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String>*>(#t10{core::Iterable<core::String>}).{core::Iterable::iterator};
+      core::Iterator<core::String> :sync-for-iterator = #t10{core::Iterable<core::String>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -165,7 +164,7 @@
     final core::Set<core::String> #t13 = col::LinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t14 = l;
     if(!#t14.{core::Object::==}(null)) {
-      core::Iterator<core::String>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String>*>(#t14{core::Iterable<core::String>}).{core::Iterable::iterator};
+      core::Iterator<core::String> :sync-for-iterator = #t14{core::Iterable<core::String>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::String #t15 = :sync-for-iterator.{core::Iterator::current};
         #t13.{core::Set::add}(#t15);
@@ -176,7 +175,7 @@
     final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
     final core::Map<core::String, core::int>? #t17 = m;
     if(!#t17.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t17{core::Map<core::String, core::int>}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*> :sync-for-iterator = #t17{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String, core::int> #t18 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
@@ -187,7 +186,7 @@
     final core::Map<core::String, core::int> #t19 = <core::String, core::int>{};
     final core::Map<core::String, core::int>? #t20 = m;
     if(!#t20.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::String*, core::int*>*>*>(#t20{core::Map<core::String, core::int>}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::int*>*> :sync-for-iterator = #t20{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::String, core::int> #t21 = :sync-for-iterator.{core::Iterator::current};
         #t19.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..c248ef3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+foo<T extends Object?, S extends List<T>>(T t) => null;
+bar<T extends Object?, S extends List<T?>>(T t) => null;
+baz(int? x, int y) {}
+
+class A<T extends Object?, S extends Object> {
+  hest<X extends T, Y extends List<X>, Z extends List<X?>>() => null;
+  fisk<X extends S, Y extends List<X>, Z extends List<X?>>() => null;
+  mus<X extends Object?, Y extends List<X>, Z extends List<X?>>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca5c31e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+bar<T extends Object?, S extends List<T?>>(T t) => null;
+baz(int? x, int y) {}
+
+class A<T extends Object?, S extends Object> {
+  fisk<X extends S, Y extends List<X>, Z extends List<X?>>() => null;
+  hest<X extends T, Y extends List<X>, Z extends List<X?>>() => null;
+  mus<X extends Object?, Y extends List<X>, Z extends List<X?>>() => null;
+}
+
+foo<T extends Object?, S extends List<T>>(T t) => null;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline.expect
new file mode 100644
index 0000000..97c69c0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+bar() {}
+foo(int x, bool b) {}
+
+abstract class A {
+  foo(int x, bool b) {}
+  Never neverReturn();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f92853d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+abstract class A {
+  Never neverReturn();
+  foo(int x, bool b) {}
+}
+
+bar() {}
+foo(int x, bool b) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline.expect
new file mode 100644
index 0000000..02a881f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {
+  final int foo;
+  const A(this.foo);
+}
+
+class B extends A {
+  const B(int foo) : super(foo);
+}
+
+class C extends B {
+  const C(int foo) : super(foo);
+}
+
+class D extends B {
+  const D(int foo) : super(foo);
+  bool operator ==(dynamic other) => identical(this, other);
+}
+
+bar(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49e84fe
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+bar(B b) {}
+
+class A {
+  const A(this.foo);
+  final int foo;
+}
+
+class B extends A {
+  const B(int foo) : super(foo);
+}
+
+class C extends B {
+  const C(int foo) : super(foo);
+}
+
+class D extends B {
+  bool operator ==(dynamic other) => identical(this, other);
+  const D(int foo) : super(foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline.expect
new file mode 100644
index 0000000..81af6ded
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class C {
+  int call() => 0;
+}
+
+functionContext(int Function() f) {}
+nullableFunctionContext(int Function()? f) {}
+foo<T extends C?>(C? c, T t, T? nt) {}
+bar<T extends C>(C c, T t) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16298a3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+bar<T extends C>(C c, T t) {}
+
+class C {
+  int call() => 0;
+}
+
+foo<T extends C?>(C? c, T t, T? nt) {}
+functionContext(int Function() f) {}
+main() {}
+nullableFunctionContext(int Function()? f) {}
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline.expect
new file mode 100644
index 0000000..6350615
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+Never never() => throw "Never";
+
+class A<X extends Object, Y extends Object?> {
+  X foo() => never();
+  X? bar() => null;
+  Y baz() => never();
+}
+
+class B<X extends List<Y>, Y extends Object?> {
+  foo(X x, Y y) {}
+}
+
+class C<X extends List<Y>?, Y extends List<X>?> {
+  foo(X x, Y y) {}
+}
+
+class D<X extends Y, Y extends Z, Z> {
+  foo(X x, Y y, Z z) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6350615
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+Never never() => throw "Never";
+
+class A<X extends Object, Y extends Object?> {
+  X foo() => never();
+  X? bar() => null;
+  Y baz() => never();
+}
+
+class B<X extends List<Y>, Y extends Object?> {
+  foo(X x, Y y) {}
+}
+
+class C<X extends List<Y>?, Y extends List<X>?> {
+  foo(X x, Y y) {}
+}
+
+class D<X extends Y, Y extends Z, Z> {
+  foo(X x, Y y, Z z) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/uninitialized_non_nullable_late_fields.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..86269fb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  late int ;
+  x;
+  A.foo(this.x);
+  A.bar();
+}
+main() { }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline.expect
new file mode 100644
index 0000000..9333088
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+void expectTypeError(callback()) {}
+
+abstract class I {
+  int foo;
+}
+
+class A implements I {
+  dynamic noSuchMethod(i) => "bar";
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7487d5
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class I {
+  int foo;
+}
+
+class A implements I {
+  dynamic noSuchMethod(i) => "bar";
+}
+
+class B extends A {}
+
+main() {}
+void expectTypeError(callback()) {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline.expect
new file mode 100644
index 0000000..0c3243c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+int count = 0;
+
+abstract class A {
+  int foo;
+}
+
+class B implements A {
+  noSuchMethod(i) {}
+}
+
+class C extends Object with B {
+  int get foo => 42;
+  void set foo(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95afa4a
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class A {
+  int foo;
+}
+
+class B implements A {
+  noSuchMethod(i) {}
+}
+
+class C extends Object with B {
+  int get foo => 42;
+  void set foo(int value) {}
+}
+
+int count = 0;
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline.expect
new file mode 100644
index 0000000..0a9f2c8
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+void expectTypeError(callback()) {}
+
+abstract class A {
+  int foo;
+}
+
+abstract class B implements A {
+  int get foo => 42;
+  noSuchMethod(i) => "bar";
+}
+
+class C extends B {}
+
+abstract class D implements A {
+  void set foo(int value) {}
+  noSuchMethod(i) => "bar";
+}
+
+class E extends D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f5c068
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+abstract class A {
+  int foo;
+}
+
+abstract class B implements A {
+  int get foo => 42;
+  noSuchMethod(i) => "bar";
+}
+
+abstract class D implements A {
+  noSuchMethod(i) => "bar";
+  void set foo(int value) {}
+}
+
+class C extends B {}
+
+class E extends D {}
+
+main() {}
+void expectTypeError(callback()) {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..45fe92b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+void expectTypeError(callback()) {}
+
+abstract class A<X> {
+  List<X> foo;
+}
+
+class B implements A<int> {
+  dynamic noSuchMethod(i) => <dynamic>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..127e73c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+abstract class A<X> {
+  List<X> foo;
+}
+
+class B implements A<int> {
+  dynamic noSuchMethod(i) => <dynamic>[];
+}
+
+main() {}
+void expectTypeError(callback()) {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline.expect
new file mode 100644
index 0000000..43533ee
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+abstract class I {
+  void foo();
+}
+
+class B extends A implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f7e0e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class I {
+  void foo();
+}
+
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends A implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.strong.transformed.expect
index c033f30..5600544 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class Base extends core::Object {
   synthetic constructor •() → self::Base*
@@ -31,7 +30,7 @@
 static method main() → dynamic {
   core::List<self::Base*>* list = <self::Base*>[new self::Me::•(), new self::You::•()];
   {
-    core::Iterator<self::Base*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<self::Base*>*>(list).{core::Iterable::iterator};
+    core::Iterator<self::Base*>* :sync-for-iterator = list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       self::Base* baba = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline.expect
new file mode 100644
index 0000000..05bec89
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class Base {
+  set push(int x);
+  set float(covariant int x);
+  noSuchMethod(i) => print("${runtimeType}: ${i.positionalArguments[0]}");
+}
+
+class Me extends Base {}
+
+class You extends Base {
+  set push(num x);
+  set float(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a9d0939
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Base {
+  noSuchMethod(i) => print("${runtimeType}: ${i.positionalArguments[0]}");
+  set float(covariant int x);
+  set push(int x);
+}
+
+class Me extends Base {}
+
+class You extends Base {
+  set float(num x);
+  set push(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline.expect
new file mode 100644
index 0000000..7882e0f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class Cat {
+  bool eatFood(String food) => true;
+}
+
+class MockCat implements Cat {
+  dynamic noSuchMethod(Invocation invocation) {}
+}
+
+class MockCat2 extends MockCat {
+  noSuchMethod(_);
+}
+
+class MockCat3 extends MockCat2 implements Cat {
+  bool eatFood(String food, {double amount});
+}
+
+class MockCat4 extends MockCat2 implements HungryCat {}
+
+abstract class HungryCat {
+  bool eatFood(String food, {double amount, double yetAnother});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9db578e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+abstract class HungryCat {
+  bool eatFood(String food, {double amount, double yetAnother});
+}
+
+class Cat {
+  bool eatFood(String food) => true;
+}
+
+class MockCat implements Cat {
+  dynamic noSuchMethod(Invocation invocation) {}
+}
+
+class MockCat2 extends MockCat {
+  noSuchMethod(_);
+}
+
+class MockCat3 extends MockCat2 implements Cat {
+  bool eatFood(String food, {double amount});
+}
+
+class MockCat4 extends MockCat2 implements HungryCat {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..d94d661
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+abstract class I {
+  foo();
+}
+
+class A {
+  foo() {}
+}
+
+class B implements I {
+  noSuchMethod(_) => null;
+}
+
+class C extends A with B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d94d661
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class I {
+  foo();
+}
+
+class A {
+  foo() {}
+}
+
+class B implements I {
+  noSuchMethod(_) => null;
+}
+
+class C extends A with B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline.expect
new file mode 100644
index 0000000..4af18d8
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A {
+  noSuchMethod(Invocation i) {}
+  String foo({String bar = "baz"});
+  int hest([int fisk = 42]);
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f49625
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A {
+  String foo({String bar = "baz"});
+  int hest([int fisk = 42]);
+  noSuchMethod(Invocation i) {}
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline.expect
new file mode 100644
index 0000000..c5dc3c0
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+abstract class I1 {
+  void foo();
+}
+
+abstract class I2 {
+  void foo();
+}
+
+class M implements I1, I2 {
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c5dc3c0
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class I1 {
+  void foo();
+}
+
+abstract class I2 {
+  void foo();
+}
+
+class M implements I1, I2 {
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline.expect
new file mode 100644
index 0000000..aaadcb4
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import './forwarder_propagation_lib.dart';
+
+abstract class A {
+  void set foo(int value);
+  int get bar;
+  void baz(int x, {String y, double z});
+}
+
+class B implements A {
+  noSuchMethod(_) {}
+}
+
+class C extends B {}
+
+class E implements D {}
+
+class F extends E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d3bb17c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import './forwarder_propagation_lib.dart';
+
+abstract class A {
+  int get bar;
+  void baz(int x, {String y, double z});
+  void set foo(int value);
+}
+
+class B implements A {
+  noSuchMethod(_) {}
+}
+
+class C extends B {}
+
+class E implements D {}
+
+class F extends E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..02f378d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class I {
+  void foo();
+}
+
+class A implements I {
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+class B extends Object with A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02f378d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class I {
+  void foo();
+}
+
+class A implements I {
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+class B extends Object with A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline.expect
new file mode 100644
index 0000000..9c32609
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+class I {
+  void foo() {}
+}
+
+class B extends A implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0318a57
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends A implements I {}
+
+class I {
+  void foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline.expect
new file mode 100644
index 0000000..bbc3c6c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class I {
+  dynamic noSuchMethod(Invocation i) => null;
+  void foo();
+}
+
+class M {
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+class A extends Object with M implements I {}
+
+class B extends Object with M implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a90747d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A extends Object with M implements I {}
+
+class B extends Object with M implements I {}
+
+class I {
+  dynamic noSuchMethod(Invocation i) => null;
+  void foo();
+}
+
+class M {
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..af6ee89
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {
+  void set foo(int value) {}
+  int get bar => null;
+}
+
+class B {
+  void set foo(double value) {}
+  double get bar => null;
+}
+
+class C {
+  void set foo(num value) {}
+  Null get bar => null;
+}
+
+class D implements C, A, B {
+  noSuchMethod(_) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02e07d5
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class A {
+  int get bar => null;
+  void set foo(int value) {}
+}
+
+class B {
+  double get bar => null;
+  void set foo(double value) {}
+}
+
+class C {
+  Null get bar => null;
+  void set foo(num value) {}
+}
+
+class D implements C, A, B {
+  noSuchMethod(_) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline.expect
new file mode 100644
index 0000000..85d405d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+abstract class A {
+  noSuchMethod(i) => null;
+  void foo();
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..85d405d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+abstract class A {
+  noSuchMethod(i) => null;
+  void foo();
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline.expect
new file mode 100644
index 0000000..09d5fc9
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+abstract class A {
+  noSuchMethod(i) => null;
+  void foo();
+}
+
+abstract class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..09d5fc9
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class A {
+  noSuchMethod(i) => null;
+  void foo();
+}
+
+abstract class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline.expect
new file mode 100644
index 0000000..7ce56ae
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class M {
+  dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+class A extends M {
+  void call(String s);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0421166
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M {
+  void call(String s);
+}
+
+class M {
+  dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline.expect
new file mode 100644
index 0000000..eece1da
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends Object with A {
+  void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eece1da
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends Object with A {
+  void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline.expect
new file mode 100644
index 0000000..284127b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library private;
+
+import './private_module.dart' show Fisk;
+
+abstract class Foo {
+  dynamic noSuchMethod(Invocation invocation) => 42;
+}
+
+class Bar extends Foo implements Fisk {}
+
+class Baz extends Foo implements Fisk {
+  _hest() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..284127b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library private;
+
+import './private_module.dart' show Fisk;
+
+abstract class Foo {
+  dynamic noSuchMethod(Invocation invocation) => 42;
+}
+
+class Bar extends Foo implements Fisk {}
+
+class Baz extends Foo implements Fisk {
+  _hest() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline.expect
new file mode 100644
index 0000000..ad5304f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library private_module;
+
+abstract class Fisk {
+  void _hest();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ad5304f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library private_module;
+
+abstract class Fisk {
+  void _hest();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline.expect
new file mode 100644
index 0000000..cb9b84e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class Foo {
+  void _foo();
+}
+
+class Bar extends Foo {
+  dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb9b84e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class Foo {
+  void _foo();
+}
+
+class Bar extends Foo {
+  dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline.expect
new file mode 100644
index 0000000..7b3ce88
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+  void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7b3ce88
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+  dynamic noSuchMethod(Invocation i) {}
+  void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline.expect
new file mode 100644
index 0000000..3ae19c6
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  void foo(int x) {}
+  void set foo(int x);
+  dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1ccdb0f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+  dynamic noSuchMethod(Invocation i) => null;
+  void foo(int x) {}
+  void set foo(int x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline.expect
new file mode 100644
index 0000000..9ae8a30
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class I<T> {
+  T foo();
+}
+
+class M {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+class A extends Object with M implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1762a6e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class I<T> {
+  T foo();
+}
+
+class A extends Object with M implements I<int> {}
+
+class M {
+  dynamic noSuchMethod(Invocation i) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart
new file mode 100644
index 0000000..0b00978
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'issue41501_lib.dart';
+
+typedef AAliasNonNullable = A;
+
+typedef AAliasNullable = A?;
+
+test() {
+  FutureOr<AAlias> foLegacyNonNullable = null; // error
+  FutureOr<AAlias?> foLegacyNullable = null; // ok
+  FutureOr<AAliasNonNullable> foNonNullable = null; // error
+  FutureOr<AAliasNullable> foNullable = null; // ok
+  FutureOr<AAliasNonNullable?> foNonNullableNullable = null; // ok
+  FutureOr<AAliasNullable?> foNullableNullable = null; // ok
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.outline.expect
new file mode 100644
index 0000000..7f9a293
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41501_lib.dart" as opt;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501_lib.dart";
+
+typedef AAliasNonNullable = opt::A;
+typedef AAliasNullable = opt::A?;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library opted_out_lib;
+import self as opt;
+import "dart:core" as core;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501.dart";
+
+typedef AAlias = opt::A*;
+class A extends core::Object {
+  synthetic constructor •() → opt::A*
+    ;
+}
+static method test() → dynamic
+  ;
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
new file mode 100644
index 0000000..a62ffbb
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAlias> foLegacyNonNullable = null; // error
+//                                          ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAliasNonNullable> foNonNullable = null; // error
+//                                               ^
+//
+import self as self;
+import "issue41501_lib.dart" as opt;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501_lib.dart";
+
+typedef AAliasNonNullable = opt::A;
+typedef AAliasNullable = opt::A?;
+static method test() → dynamic {
+  asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAlias> foLegacyNonNullable = null; // error
+                                         ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foLegacyNullable = null;
+  asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAliasNonNullable> foNonNullable = null; // error
+                                              ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foNullable = null;
+  asy::FutureOr<opt::A?> foNonNullableNullable = null;
+  asy::FutureOr<opt::A?> foNullableNullable = null;
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as opt;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501.dart";
+
+typedef AAlias = opt::A*;
+class A extends core::Object {
+  synthetic constructor •() → opt::A*
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  asy::FutureOr<opt::A*>* foLegacy = null;
+  asy::FutureOr<opt::A*>* foNonNullable = null;
+  asy::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
new file mode 100644
index 0000000..a62ffbb
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAlias> foLegacyNonNullable = null; // error
+//                                          ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAliasNonNullable> foNonNullable = null; // error
+//                                               ^
+//
+import self as self;
+import "issue41501_lib.dart" as opt;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501_lib.dart";
+
+typedef AAliasNonNullable = opt::A;
+typedef AAliasNullable = opt::A?;
+static method test() → dynamic {
+  asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAlias> foLegacyNonNullable = null; // error
+                                         ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foLegacyNullable = null;
+  asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAliasNonNullable> foNonNullable = null; // error
+                                              ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foNullable = null;
+  asy::FutureOr<opt::A?> foNonNullableNullable = null;
+  asy::FutureOr<opt::A?> foNullableNullable = null;
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as opt;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501.dart";
+
+typedef AAlias = opt::A*;
+class A extends core::Object {
+  synthetic constructor •() → opt::A*
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  asy::FutureOr<opt::A*>* foLegacy = null;
+  asy::FutureOr<opt::A*>* foNonNullable = null;
+  asy::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
new file mode 100644
index 0000000..8ff38a5
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:async'; import 'issue41501_lib.dart';
+typedef AAliasNonNullable = A;
+typedef AAliasNullable = A?;
+test() { }
+main() { }
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
new file mode 100644
index 0000000..a62ffbb
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAlias> foLegacyNonNullable = null; // error
+//                                          ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAliasNonNullable> foNonNullable = null; // error
+//                                               ^
+//
+import self as self;
+import "issue41501_lib.dart" as opt;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501_lib.dart";
+
+typedef AAliasNonNullable = opt::A;
+typedef AAliasNullable = opt::A?;
+static method test() → dynamic {
+  asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAlias> foLegacyNonNullable = null; // error
+                                         ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foLegacyNullable = null;
+  asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAliasNonNullable> foNonNullable = null; // error
+                                              ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foNullable = null;
+  asy::FutureOr<opt::A?> foNonNullableNullable = null;
+  asy::FutureOr<opt::A?> foNullableNullable = null;
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as opt;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501.dart";
+
+typedef AAlias = opt::A*;
+class A extends core::Object {
+  synthetic constructor •() → opt::A*
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  asy::FutureOr<opt::A*>* foLegacy = null;
+  asy::FutureOr<opt::A*>* foNonNullable = null;
+  asy::FutureOr<opt::A*>* foNullable = null;
+}
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
new file mode 100644
index 0000000..a62ffbb
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAlias> foLegacyNonNullable = null; // error
+//                                          ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+//   FutureOr<AAliasNonNullable> foNonNullable = null; // error
+//                                               ^
+//
+import self as self;
+import "issue41501_lib.dart" as opt;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501_lib.dart";
+
+typedef AAliasNonNullable = opt::A;
+typedef AAliasNullable = opt::A?;
+static method test() → dynamic {
+  asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAlias> foLegacyNonNullable = null; // error
+                                         ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foLegacyNullable = null;
+  asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ - 'FutureOr' is from 'dart:async'.
+ - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
+  FutureOr<AAliasNonNullable> foNonNullable = null; // error
+                                              ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+  asy::FutureOr<opt::A?> foNullable = null;
+  asy::FutureOr<opt::A?> foNonNullableNullable = null;
+  asy::FutureOr<opt::A?> foNullableNullable = null;
+}
+static method main() → dynamic {}
+
+library opted_out_lib;
+import self as opt;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///issue41501.dart";
+
+typedef AAlias = opt::A*;
+class A extends core::Object {
+  synthetic constructor •() → opt::A*
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  asy::FutureOr<opt::A*>* foLegacy = null;
+  asy::FutureOr<opt::A*>* foNonNullable = null;
+  asy::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
new file mode 100644
index 0000000..09e20d1
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+library opted_out_lib;
+
+import 'dart:async';
+import 'issue41501.dart';
+
+class A {}
+
+typedef AAlias = A;
+
+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/test.options b/pkg/front_end/testcases/nonfunction_type_aliases/test.options
new file mode 100644
index 0000000..e7c1048
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/test.options
@@ -0,0 +1 @@
+--enable-experiment=non-nullable,nonfunction-type-aliases
\ No newline at end of file
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 6d3a0e2..8103acb 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -2,26 +2,8 @@
 # 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.
 
-general/abstract_members: TypeCheckError
-general/bug30695: TypeCheckError
-general/bug30695: TypeCheckError
-general/infer_field_from_multiple: TypeCheckError
-general/invalid_operator: TypeCheckError
-general/issue41210a: TypeCheckError
-general/issue41210b/issue41210: TypeCheckError
-
-general/mixin_application_override: TypeCheckError
-general/override_check_accessor_after_inference: TypeCheckError
-general/override_check_accessor_basic: TypeCheckError
-general/override_check_accessor_with_covariant_modifier: TypeCheckError
-general/override_check_after_inference: TypeCheckError
-general/override_check_basic: TypeCheckError
-general/override_check_with_covariant_modifier: TypeCheckError
-general/override_setter_with_field: TypeCheckError
-
 general_nnbd_opt_out/abstract_members: TypeCheckError
 general_nnbd_opt_out/bug30695: TypeCheckError
-general_nnbd_opt_out/bug30695: TypeCheckError
 general_nnbd_opt_out/mixin_application_override: TypeCheckError
 general_nnbd_opt_out/override_check_accessor_after_inference: TypeCheckError
 general_nnbd_opt_out/override_check_accessor_basic: TypeCheckError
@@ -30,13 +12,26 @@
 general_nnbd_opt_out/override_check_basic: TypeCheckError
 general_nnbd_opt_out/override_check_with_covariant_modifier: TypeCheckError
 general_nnbd_opt_out/override_setter_with_field: TypeCheckError
-
+general/abstract_members: TypeCheckError
+general/bug30695: TypeCheckError
+general/infer_field_from_multiple: TypeCheckError
+general/invalid_operator: TypeCheckError
+general/issue41210a: TypeCheckError
+general/issue41210b/issue41210: TypeCheckError
+general/mixin_application_override: TypeCheckError
+general/override_check_accessor_after_inference: TypeCheckError
+general/override_check_accessor_basic: TypeCheckError
+general/override_check_accessor_with_covariant_modifier: TypeCheckError
+general/override_check_after_inference: TypeCheckError
+general/override_check_basic: TypeCheckError
+general/override_check_with_covariant_modifier: TypeCheckError
+general/override_setter_with_field: TypeCheckError
 inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: Fail
 inference/generic_methods_do_not_infer_invalid_override_of_generic_method: Fail
 inference/generic_methods_handle_override_of_non_generic_with_generic: Fail
 inference/infer_assign_to_index: Fail
-inference/infer_assign_to_property: Fail
 inference/infer_assign_to_property_custom: Fail
+inference/infer_assign_to_property: Fail
 inference/infer_method_missing_params: TypeCheckError
 inference/infer_type_cast: Fail
 inference/infer_types_on_generic_instantiations_infer: TypeCheckError
@@ -44,15 +39,11 @@
 inference/mixin_inference_outwards_4: TypeCheckError
 inference/mixin_inference_unification_1: TypeCheckError
 inference/mixin_inference_unification_2: TypeCheckError
-
 nnbd/inheritance_from_opt_in: TypeCheckError
+nnbd/issue41567: TypeCheckError
 nnbd/messages_with_types_opt_in: TypeCheckError
 nnbd/messages_with_types_opt_out: TypeCheckError
 nnbd/never_opt_out: TypeCheckError
-nnbd/issue41210a/issue41210: TypeCheckError
-nnbd/issue41210b: TypeCheckError
-
 rasta/native_is_illegal: Pass # Issue 29763
-
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
 runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..101867d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+abstract class C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..101867d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+abstract class C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline.expect
new file mode 100644
index 0000000..8c60ced
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  const C() : this.x(1);
+  const C.x();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c60ced
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  const C() : this.x(1);
+  const C.x();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..5f62a0e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  A(x);
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f62a0e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+  A(x);
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..a9880f1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  A(x);
+}
+
+class B extends A {
+  const B() : super();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a9880f1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  A(x);
+}
+
+class B extends A {
+  const B() : super();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..9f4c8b4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  A(this.x);
+}
+
+class B extends A {
+  const B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f4c8b4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  A(this.x);
+}
+
+class B extends A {
+  const B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_redirection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_redirection.dart.textual_outline.expect
new file mode 100644
index 0000000..5b6ce13
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_redirection.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo {
+  Foo() = Bar;
+}
+class Bar extends Foo {
+  factory Bar() => null;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..02d3a33
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  C() : field = null;
+  set field(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02d3a33
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  C() : field = null;
+  set field(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline.expect
new file mode 100644
index 0000000..014f06c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+  add(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..014f06c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+  add(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..4730157
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A extends Missing {}
+
+class B implements Missing {}
+
+class C = Object with Missing;
+
+class D {
+  factory D() = Missing;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4730157
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends Missing {}
+
+class B implements Missing {}
+
+class C = Object with Missing;
+
+class D {
+  factory D() = Missing;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/rasta/class_member.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline.expect
new file mode 100644
index 0000000..f3931ce
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Foo {
+  a() {}
+  b() {}
+  c() {}
+  var field1;
+  var field2;
+  var field3;
+  Foo.constructor1();
+  Foo.constructor2();
+  Foo.constructor3();
+}
diff --git a/pkg/front_end/testcases/rasta/class_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b3571b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Foo {
+  Foo.constructor1();
+  Foo.constructor2();
+  Foo.constructor3();
+  a() {}
+  b() {}
+  c() {}
+  var field1;
+  var field2;
+  var field3;
+}
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline.expect
new file mode 100644
index 0000000..6b59d01
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+const c = 1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b59d01
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+const c = 1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline.expect
new file mode 100644
index 0000000..e513d3a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e513d3a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..6da2cea
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Mixin {
+  var field;
+}
+
+class A extends Object with Mixin, Mixin {}
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..525de0e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A extends Object with Mixin, Mixin {}
+
+class Mixin {
+  var field;
+}
diff --git a/pkg/front_end/testcases/rasta/enum.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/enum.dart.textual_outline.expect
new file mode 100644
index 0000000..7d25fa5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/enum.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+enum Foo {
+  ec1,
+  ec2,
+}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d25fa5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+enum Foo {
+  ec1,
+  ec2,
+}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/export.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/export.dart.textual_outline.expect
new file mode 100644
index 0000000..a55dbf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/export.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library export;
+
+export 'foo.dart';
diff --git a/pkg/front_end/testcases/rasta/export.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/export.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a55dbf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/export.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library export;
+
+export 'foo.dart';
diff --git a/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/foo.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/foo.dart.textual_outline.expect
new file mode 100644
index 0000000..0d1b8df4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/foo.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library foo;
+
+foo() {}
diff --git a/pkg/front_end/testcases/rasta/foo.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/foo.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0d1b8df4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/foo.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library foo;
+
+foo() {}
diff --git a/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..0b8bde5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class C1 {}
+
+class C2 {}
+
+class C3 {}
+
+class A<T> {
+  A.internal();
+  factory A.a() = B<T>.a;
+  factory A.b() = B<C1>.a;
+  factory A.c() = Missing;
+}
+
+class B<S> extends A<S> {
+  B.internal() : super.internal();
+  factory B.a() = C<S>;
+  factory B.b() = C<C2>;
+}
+
+class C<U> extends B<U> {
+  C() : super.internal();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bec190
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class A<T> {
+  A.internal();
+  factory A.a() = B<T>.a;
+  factory A.b() = B<C1>.a;
+  factory A.c() = Missing;
+}
+
+class B<S> extends A<S> {
+  B.internal() : super.internal();
+  factory B.a() = C<S>;
+  factory B.b() = C<C2>;
+}
+
+class C1 {}
+
+class C2 {}
+
+class C3 {}
+
+class C<U> extends B<U> {
+  C() : super.internal();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/hello.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/hello.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/hello.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/hello.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/hello.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/hello.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline.expect
new file mode 100644
index 0000000..9b23e8d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'export.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b23e8d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'export.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline.expect
new file mode 100644
index 0000000..e580ef6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+test0(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..246dbef
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+test0(x) {}
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline.expect
new file mode 100644
index 0000000..e7403ac
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+var list = [1, 2, 3];
+
+class Foo {
+  final value;
+  Foo(this.value) {}
+  factory Foo.fac(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e19be7a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+class Foo {
+  Foo(this.value) {}
+  factory Foo.fac(value) {}
+  final value;
+}
+
+main() {}
+var list = [1, 2, 3];
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.strong.transformed.expect
index b962902..b17c1d1 100644
--- a/pkg/front_end/testcases/rasta/issue_000004.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 import "package:expect/expect.dart" as exp;
 
 import "package:expect/expect.dart";
@@ -10,7 +9,7 @@
 static method fact4() → dynamic {
   core::int* f = 1;
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2, 3, 4]).{core::Iterable::iterator};
+    core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3, 4].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int* n = :sync-for-iterator.{core::Iterator::current};
       {
@@ -24,7 +23,7 @@
   core::int* f = 1;
   dynamic n;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[1, 2, 3, 4, 5]).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[1, 2, 3, 4, 5].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t1 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -38,7 +37,7 @@
 static method fact6() → dynamic {
   core::int* f = 1;
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[1, 2, 3, 4, 5, 6]).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[1, 2, 3, 4, 5, 6].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
       {
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline.expect
new file mode 100644
index 0000000..ffd82da
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'package:expect/expect.dart';
+
+fact4() {}
+fact5() {}
+var global;
+fact6() {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..68c6364
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'package:expect/expect.dart';
+
+fact4() {}
+fact5() {}
+fact6() {}
+main() {}
+var global;
diff --git a/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline.expect
new file mode 100644
index 0000000..c9b955f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+var list = [1, 2, 3];
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef8eed0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+var list = [1, 2, 3];
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline.expect
new file mode 100644
index 0000000..58c40fa
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Base {}
+
+class Mixin {
+  foo() => print('foo');
+}
+
+class Sub extends Base with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..58c40fa
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Base {}
+
+class Mixin {
+  foo() => print('foo');
+}
+
+class Sub extends Base with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline.expect
new file mode 100644
index 0000000..7c1de3a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  final x;
+  C(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2a92244
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  C(this.x);
+  final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline.expect
new file mode 100644
index 0000000..fe1927c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  var field;
+}
+
+class B extends A {
+  m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe1927c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  var field;
+}
+
+class B extends A {
+  m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline.expect
new file mode 100644
index 0000000..b31966b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+get x => 42;
+set x(val) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..58187fc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+get x => 42;
+main() {}
+set x(val) {}
diff --git a/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline.expect
new file mode 100644
index 0000000..3c6152d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class C {
+  var a;
+  var b = 0;
+  var c = 1 + 2;
+}
+
+class D {
+  var a;
+  var b = 1;
+  var c = 2 - 3;
+  D();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae0f47e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class C {
+  var a;
+  var b = 0;
+  var c = 1 + 2;
+}
+
+class D {
+  D();
+  var a;
+  var b = 1;
+  var c = 2 - 3;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline.expect
new file mode 100644
index 0000000..1123642
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:math' as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1123642
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:math' as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000032.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000032.dart.textual_outline.expect
new file mode 100644
index 0000000..6a6d39c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000032.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  C< >( ){ }
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline.expect
new file mode 100644
index 0000000..c4716a7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+@JS()
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c4716a7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+@JS()
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.textual_outline.expect
new file mode 100644
index 0000000..a682f2e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  const C() : =this.x;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/issue_000036.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000036.dart.textual_outline.expect
new file mode 100644
index 0000000..603c715
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000036.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() => a. - 5;
diff --git a/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline.expect
new file mode 100644
index 0000000..823e1c7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  var a;
+  A(x) {}
+}
+
+class B extends A {}
diff --git a/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab5d564
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+  A(x) {}
+  var a;
+}
+
+class B extends A {}
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline.expect
new file mode 100644
index 0000000..0690e46
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  test() {}
+}
+
+use(_) => null;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..57013ed
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  test() {}
+}
+
+main() {}
+use(_) => null;
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.strong.transformed.expect
index e81f7fc..3e7ecfd 100644
--- a/pkg/front_end/testcases/rasta/issue_000042.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.strong.transformed.expect
@@ -22,7 +22,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method main() → dynamic {
   {
@@ -30,7 +29,7 @@
   for (var x, y in []) {}
        ^^^";
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t1 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline.expect
new file mode 100644
index 0000000..6bc9bc7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class C {
+  get x => '$C'.hashCode;
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6bc9bc7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class C {
+  get x => '$C'.hashCode;
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
index 1673fff..b936679 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
@@ -85,7 +85,7 @@
 static method b(dynamic c) → invalid-type
   return invalid-expression "pkg/front_end/testcases/rasta/issue_000044.dart:7:10: Error: Getter not found: 'd'.
 a b(c) = d;
-         ^" as{TypeError,ForDynamic} invalid-type;
+         ^";
 static method main() → dynamic {
   self::C* c = null;
   core::print(#C1);
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
index 211952a..efeabae 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
@@ -85,7 +85,7 @@
 static method b(dynamic c) → invalid-type
   return invalid-expression "pkg/front_end/testcases/rasta/issue_000044.dart:7:10: Error: Getter not found: 'd'.
 a b(c) = d;
-         ^" as{TypeError,ForDynamic} invalid-type;
+         ^";
 static method main() → dynamic {
   self::C* c = null;
   core::print(#C1);
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.textual_outline.expect
new file mode 100644
index 0000000..934729b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+a b(c) = d;
+class C {
+  const C.constant();
+  C.missingFactoryKeyword() = C.constant;
+  const factory C.good() = C.constant;
+  C notEvenAConstructor(a) = h;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.textual_outline.expect
new file mode 100644
index 0000000..0b29b47
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C {
+  C c = new Object();
+  )
+  ();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000047.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000047.dart.textual_outline.expect
new file mode 100644
index 0000000..0967161
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000047.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef void T(C<C>);
+T main() => null;
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline.expect
new file mode 100644
index 0000000..75793bc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A {
+  bool v1;
+  num v2;
+  A(bool this.v1, num this.v2);
+}
+
+class M1 {
+  num v2 = 0;
+}
+
+class C = A with M1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d8b868
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A {
+  A(bool this.v1, num this.v2);
+  bool v1;
+  num v2;
+}
+
+class M1 {
+  num v2 = 0;
+}
+
+class C = A with M1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline.expect
new file mode 100644
index 0000000..aa3a004
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  operator ==(other) => throw 'x';
+  test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aa3a004
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  operator ==(other) => throw 'x';
+  test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline.expect
new file mode 100644
index 0000000..a569cc4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import "package:expect/expect.dart";
+
+class A {
+  A() {}
+  factory A.foo() = C.bar;
+  int m() {}
+}
+
+class C extends A {
+  C() {}
+  factory C.bar() = D;
+  int m() {}
+}
+
+class D extends C {
+  int m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a569cc4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import "package:expect/expect.dart";
+
+class A {
+  A() {}
+  factory A.foo() = C.bar;
+  int m() {}
+}
+
+class C extends A {
+  C() {}
+  factory C.bar() = D;
+  int m() {}
+}
+
+class D extends C {
+  int m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline.expect
new file mode 100644
index 0000000..cde3517
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class G<T> {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd18446
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class G<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
new file mode 100644
index 0000000..18be5ac
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import "package:expect/expect.dart";
+
+class A<N, S, U> {
+  final List<U> field;
+  A(N n, S s) : field = new List<U>() {}
+  A.empty() : field = null {}
+  factory A.f(S s) {}
+  const A.c(U u, S s) : field = const [null];
+  List<U> get getter {}
+  void set setter(S s) {}
+}
+
+abstract class J<Aa, B> {}
+
+abstract class I<H, C, K> extends J<C, K> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cefd17f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+import "package:expect/expect.dart";
+
+abstract class I<H, C, K> extends J<C, K> {}
+
+abstract class J<Aa, B> {}
+
+class A<N, S, U> {
+  A(N n, S s) : field = new List<U>() {}
+  A.empty() : field = null {}
+  List<U> get getter {}
+  const A.c(U u, S s) : field = const [null];
+  factory A.f(S s) {}
+  final List<U> field;
+  void set setter(S s) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline.expect
new file mode 100644
index 0000000..e1dd6e2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Mixin {
+  var field;
+  foo() => 87;
+}
+
+class Foo extends Object with Mixin {
+  foo() => super.foo();
+  bar() => super.field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ed966c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Foo extends Object with Mixin {
+  bar() => super.field;
+  foo() => super.foo();
+}
+
+class Mixin {
+  foo() => 87;
+  var field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline.expect
new file mode 100644
index 0000000..e1cbad9
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Base {
+  int hashCode = 42;
+}
+
+class Sub extends Base {
+  int _hashCode = null;
+  get hashCode => _hashCode ??= super.hashCode;
+  foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0170932
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Base {
+  int hashCode = 42;
+}
+
+class Sub extends Base {
+  foo() {}
+  get hashCode => _hashCode ??= super.hashCode;
+  int _hashCode = null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..c0d76bf
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+  const A() : x = 'foo' { }
+  :
+  x = 'foo' ;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..6587e81
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef Handle Handle(String command);
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2afa7c6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef Handle Handle(String command);
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..881328b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.textual_outline.expect
@@ -0,0 +1 @@
+main(arguments = [x]) { }
diff --git a/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline.expect
new file mode 100644
index 0000000..6d98bf9
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+library test.mixin_library;
+
+f() => 2;
+V() => 87;
+_private() => 117;
+
+class Mixin<T> {
+  var x = f(), y, z;
+  T t;
+  foo() => super.foo() + f();
+  T g(T a) => null;
+  h() => V();
+  l() => _private();
+  _privateMethod() => 49;
+  publicMethod() => _privateMethod();
+}
+
+foo(m) => m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37481e9
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test.mixin_library;
+
+V() => 87;
+_private() => 117;
+
+class Mixin<T> {
+  T g(T a) => null;
+  T t;
+  _privateMethod() => 49;
+  foo() => super.foo() + f();
+  h() => V();
+  l() => _private();
+  publicMethod() => _privateMethod();
+  var x = f(), y, z;
+}
+
+f() => 2;
+foo(m) => m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline.expect
new file mode 100644
index 0000000..f28a475
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+foo() native "foo";
+
+class Bar {
+  Bar get x native "Bar_get_x";
+  set x(Bar value) native "Bar_set_x";
+  f() native "Bar_f";
+  factory Bar() native "Bar_constructor";
+}
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..61833c6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Bar {
+  Bar get x native "Bar_get_x";
+  f() native "Bar_f";
+  factory Bar() native "Bar_constructor";
+  set x(Bar value) native "Bar_set_x";
+}
+
+foo() native "foo";
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline.expect
new file mode 100644
index 0000000..bbfef96
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart";
+
+int test(a, {b, c}) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bbfef96
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart";
+
+int test(a, {b, c}) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/rasta/static.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/static.dart.textual_outline.expect
new file mode 100644
index 0000000..e24cfe0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/static.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Foo {
+  static const staticConstant = 42;
+  static var staticField = 42;
+  static staticFunction() {}
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+}
+
+use(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..079b3cc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/static.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Foo {
+  static const staticConstant = 42;
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticFunction() {}
+  static var staticField = 42;
+}
+
+main() {}
+use(x) {}
diff --git a/pkg/front_end/testcases/rasta/super.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super.dart.textual_outline.expect
new file mode 100644
index 0000000..df2c783
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+class A {
+  var a;
+  var b;
+  var c;
+  var d;
+  get e => null;
+  final f;
+  set g(_) {}
+  get h => null;
+  set h(_) {}
+  get i => null;
+  operator [](_) => null;
+  operator []=(a, b) {}
+  operator ~() => 117;
+  operator -() => 117;
+  operator ==(other) => true;
+  void m() {}
+  void n() {}
+  set n(_) {}
+}
+
+class B extends A {
+  get b => null;
+  set c(x) {}
+  final d;
+  set i(x) {}
+}
+
+class C extends B {
+  test() {}
+}
+
+use(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ce4369
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super.dart.textual_outline_modelled.expect
@@ -0,0 +1,34 @@
+class A {
+  final f;
+  get e => null;
+  get h => null;
+  get i => null;
+  operator -() => 117;
+  operator ==(other) => true;
+  operator [](_) => null;
+  operator []=(a, b) {}
+  operator ~() => 117;
+  set g(_) {}
+  set h(_) {}
+  set n(_) {}
+  var a;
+  var b;
+  var c;
+  var d;
+  void m() {}
+  void n() {}
+}
+
+class B extends A {
+  final d;
+  get b => null;
+  set c(x) {}
+  set i(x) {}
+}
+
+class C extends B {
+  test() {}
+}
+
+main() {}
+use(x) {}
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..c058c68
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Super {
+  Super.arg0();
+  Super.arg1(a);
+  Super.arg2(a, b);
+}
+
+class Sub extends Super {
+  var field;
+  Sub.arg0()
+      : super.arg0(),
+        field = 42;
+  Sub.arg1(a)
+      : super.arg1(a),
+        field = 42;
+  Sub.arg2(a, b)
+      : super.arg2(a, b),
+        field = 42;
+}
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65f2d20
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class Sub extends Super {
+  Sub.arg0()
+      : super.arg0(),
+        field = 42;
+  Sub.arg1(a)
+      : super.arg1(a),
+        field = 42;
+  Sub.arg2(a, b)
+      : super.arg2(a, b),
+        field = 42;
+  var field;
+}
+
+class Super {
+  Super.arg0();
+  Super.arg1(a);
+  Super.arg2(a, b);
+}
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..73b67ed
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import "mixin_library.dart" show Mixin;
+
+class Super<S> {
+  foo() => 40;
+  f() => 3;
+}
+
+class C<V> extends Super<V> with Mixin<V> {}
+
+class D extends Super with Mixin {}
+
+class C2<V> = Super<V> with Mixin<V>;
+class D2 = Super with Mixin;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7fb14f0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import "mixin_library.dart" show Mixin;
+
+class C<V> extends Super<V> with Mixin<V> {}
+
+class D extends Super with Mixin {}
+
+class Super<S> {
+  f() => 3;
+  foo() => 40;
+}
+
+class C2<V> = Super<V> with Mixin<V>;
+class D2 = Super with Mixin;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..0a07631
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A {
+  operator +(String s) => null;
+  operator [](i) => null;
+  operator []=(i, val) {}
+}
+
+class B extends A {
+  operator +(String s) => super + ("${s}${s}");
+  operator [](i) => super[i];
+  operator []=(i, val) => super[i++] += val;
+}
+
+class Autobianchi {
+  g() => super[0];
+}
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ecde10
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {
+  operator +(String s) => null;
+  operator [](i) => null;
+  operator []=(i, val) {}
+}
+
+class Autobianchi {
+  g() => super[0];
+}
+
+class B extends A {
+  operator +(String s) => super + ("${s}${s}");
+  operator [](i) => super[i];
+  operator []=(i, val) => super[i++] += val;
+}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline.expect
new file mode 100644
index 0000000..9157edc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+test(value) {}
+testEmptyCases(value) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7ab5d3
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+test(value) {}
+testEmptyCases(value) {}
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline.expect
new file mode 100644
index 0000000..ab53b16
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+  m(x) => this(x);
+  call(x) => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cabde6d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+  call(x) => 42;
+  m(x) => this(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/try_label.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/try_label.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..3e0fb14
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef void Func();
+
+class C<T> {
+  test() {}
+}
+
+use(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e51e370
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C<T> {
+  test() {}
+}
+
+main() {}
+typedef void Func();
+use(x) {}
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline.expect
new file mode 100644
index 0000000..10499e7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+main() {}
+
+class A {
+  foo() {}
+}
+
+class B<T> {
+  int i;
+}
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a2249be
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  foo() {}
+}
+
+class B<T> {
+  int i;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..3c109123
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef void Foo();
+main() {}
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7f7ac99
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef void Foo();
diff --git a/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..36e85d2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+  Foo(x, y);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..36e85d2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Foo {
+  Foo(x, y);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
index 48bbc83..cebfb0d 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
@@ -82,7 +82,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 import "dart:collection" as collection;
 
@@ -93,7 +92,7 @@
     ;
   method it1(dynamic x) → dynamic {
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t1 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -111,7 +110,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -123,7 +122,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t3 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -137,7 +136,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -153,7 +152,7 @@
     for (1 in x) {
          ^";
       {
-        core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+        core::Iterator<dynamic>* :sync-for-iterator = (x as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final dynamic #t5 = :sync-for-iterator.{core::Iterator::current};
           {
@@ -175,7 +174,7 @@
 static method main(dynamic arguments) → dynamic {
   new self::Fisk::•();
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = (arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -189,7 +188,7 @@
     }
   }
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = (arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t7 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -201,7 +200,7 @@
     }
   }
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = (arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -215,7 +214,7 @@
     }
   }
   {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = (arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
       {
@@ -231,7 +230,7 @@
   for (1 in arguments) {
        ^";
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = (arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline.expect
new file mode 100644
index 0000000..2b61e89
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:collection' as collection;
+
+typedef void VoidFunction();
+
+class Fisk {
+  it1(x) {}
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d7cff8
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import 'dart:collection' as collection;
+
+class Fisk {
+  it1(x) {}
+}
+
+main(arguments) {}
+typedef void VoidFunction();
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline.expect
new file mode 100644
index 0000000..b529ebe
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class E {
+  foo() {}
+}
+
+beforeTestMissingTry() {}
+testMissingTry() {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..97cd820
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+beforeTestMissingTry() {}
+
+class E {
+  foo() {}
+}
+
+main() {}
+testMissingTry() {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect
index d2b8d3d..b80948b 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect
@@ -1,3 +1,10 @@
+//
+// Problems outside component:
+//
+// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
+// import 'dart:html';
+//        ^
+//
 library;
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect
index 22b2878..7651a58 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect
@@ -1,3 +1,10 @@
+//
+// Problems outside component:
+//
+// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
+// import 'dart:html';
+//        ^
+//
 library;
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline.expect
new file mode 100644
index 0000000..afaa1af
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:html';
+import 'dart:io';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..afaa1af
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:html';
+import 'dart:io';
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29942.dart.textual_outline.expect
new file mode 100644
index 0000000..a63e3c7
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() { }
+f() = h() => null;
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29944.dart.textual_outline.expect
new file mode 100644
index 0000000..e66ce0f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C {
+  C();
+  var C;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline.expect
new file mode 100644
index 0000000..e3e4824
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef void F();
+typedef void F();
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3e4824
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+typedef void F();
+typedef void F();
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline.expect
new file mode 100644
index 0000000..86b4d9e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'data:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..86b4d9e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'data:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline.expect
new file mode 100644
index 0000000..2a44271
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo(a, b) => null;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2a44271
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo(a, b) => null;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline.expect
new file mode 100644
index 0000000..2dd5595
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C<T> {
+  C<String, String> field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2dd5595
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class C<T> {
+  C<String, String> field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29983.dart.textual_outline.expect
new file mode 100644
index 0000000..1f126e59
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+f() sync* { }
+g() sync* => dummy;
+h() sync* { }
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29986.dart.textual_outline.expect
new file mode 100644
index 0000000..87a6bb5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() { }
+C(this.name);
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline.expect
new file mode 100644
index 0000000..b891f0b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import "dart_:core";
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b891f0b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import "dart_:core";
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30834.dart.textual_outline.expect
new file mode 100644
index 0000000..ed95a52
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+  set A(v) { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline.expect
new file mode 100644
index 0000000..5a96f26
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+  final int x;
+  A() {}
+}
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..32f0ddd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A {
+  A() {}
+  final int x;
+}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline.expect
new file mode 100644
index 0000000..5ba2d20
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo<int> bar() => foo;
+void test1() {}
+
+class A {
+  Foo<int> f;
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14b3da3
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+Foo<int> bar() => foo;
+
+class A {
+  Foo<int> f;
+  void test() {}
+}
+
+int foo<T>(T x) => 3;
+main() {}
+typedef Foo<S> = S Function<T>(T x);
+void test1() {}
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30981.dart.textual_outline.expect
new file mode 100644
index 0000000..9a413c6
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+  get A { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30994.dart.textual_outline.expect
new file mode 100644
index 0000000..10992017
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+library lib; part '$foo'; part '$foo/bar'; part '$for/bar'; part '${true}'; part 'the${1}thing'; part 'part_$foo${'a'}.dart'; part 'part_${'a'}_$foo.dart';
+main() { }
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
new file mode 100644
index 0000000..187e259
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+}
+class B {
+}
+class C {
+  var f = Map<A, B;
+  operator> (){ }
+  ;
+}
+void main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31171.dart.textual_outline.expect
new file mode 100644
index 0000000..945c614
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() { }
+typedef T = ;
+typedef F = Map<String, dynamic> Function();
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline.expect
new file mode 100644
index 0000000..5b23e22
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef Foo<T> = T Function<T>(T a);
+Foo x;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..954749e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Foo x;
+main() {}
+typedef Foo<T> = T Function<T>(T a);
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31183.dart.textual_outline.expect
new file mode 100644
index 0000000..2017348
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  operator unary- ()=> 0;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline.expect
new file mode 100644
index 0000000..4a2b0ae
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+int i = 5;
+int test1() {}
+int test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a2b0ae
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+int i = 5;
+int test1() {}
+int test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
index 8a0e754..d20d13f 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
@@ -34,6 +34,6 @@
  - 'Type' is from 'dart:core'.
 Try correcting the operator to an existing operator, or defining a '<' operator.
 type T = Map<A, B>
-            ^" as{TypeError,ForDynamic} invalid-type;
+            ^";
 static field invalid-type B;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
index 8a0e754..d20d13f 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
@@ -34,6 +34,6 @@
  - 'Type' is from 'dart:core'.
 Try correcting the operator to an existing operator, or defining a '<' operator.
 type T = Map<A, B>
-            ^" as{TypeError,ForDynamic} invalid-type;
+            ^";
 static field invalid-type B;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31188.dart.textual_outline.expect
new file mode 100644
index 0000000..1ecda27
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() { }
+type T = Map<A, B;
+>
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline.expect
new file mode 100644
index 0000000..52c03bd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Typed<T> {
+  T<U> v;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52c03bd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Typed<T> {
+  T<U> v;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31192.dart.textual_outline.expect
new file mode 100644
index 0000000..2fdc0b7
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Increment {
+  int x;
+  Increment() : =x++ { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31198.dart.textual_outline.expect
new file mode 100644
index 0000000..39bb035
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A {
+}
+class B extends A {
+  B(): super().foo() { }
+}
+bad() { }
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline.expect
new file mode 100644
index 0000000..87e854f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef C<A, K> = int Function<B>(A x, K y, B v);
+typedef D<K> = C<A, K> Function<A>(int z);
+dynamic producer<K>() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..480f6f2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+dynamic producer<K>() {}
+main() {}
+typedef C<A, K> = int Function<B>(A x, K y, B v);
+typedef D<K> = C<A, K> Function<A>(int z);
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline.expect
new file mode 100644
index 0000000..0298c3a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  int m;
+  A() : m = 1;
+  A.foo() : m = 2;
+  int foo(int a, int b) => a + b * m;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2c8de1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  A() : m = 1;
+  A.foo() : m = 2;
+  int foo(int a, int b) => a + b * m;
+  int m;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline.expect
new file mode 100644
index 0000000..27434f1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+  foo() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27434f1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+  foo() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline.expect
new file mode 100644
index 0000000..7ebf1bc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class B<T> {}
+
+abstract class C<T> {}
+
+class Base implements B {}
+
+class Child1 extends Base implements C<int> {}
+
+class Child2 extends Base implements C<double> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7ebf1bc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class B<T> {}
+
+abstract class C<T> {}
+
+class Base implements B {}
+
+class Child1 extends Base implements C<int> {}
+
+class Child2 extends Base implements C<double> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline.expect
new file mode 100644
index 0000000..22f0c87
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "issue_32182.dart" as self;
+
+class A<T> {}
+
+class M {
+  m() => 42;
+}
+
+class C extends A<self.A> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0f5e79
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "issue_32182.dart" as self;
+
+class A<T> {}
+
+class C extends A<self.A> with M {}
+
+class M {
+  m() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline.expect
new file mode 100644
index 0000000..7fecce8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+  final String name;
+  A.get(this.name);
+  A.set(this.name);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13664b5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+  A.get(this.name);
+  A.set(this.name);
+  final String name;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32200.dart.strong.expect
index 99cd03a..4750f38 100644
--- a/pkg/front_end/testcases/regress/issue_32200.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.strong.expect
@@ -19,5 +19,5 @@
 }
 static method main() → dynamic {
   self::Foo* instance = new self::Foo::•();
-  instance.{self::Foo::self} = instance as{TypeError} invalid-type;
+  instance.{self::Foo::self} = instance;
 }
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect
index 99cd03a..4750f38 100644
--- a/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect
@@ -19,5 +19,5 @@
 }
 static method main() → dynamic {
   self::Foo* instance = new self::Foo::•();
-  instance.{self::Foo::self} = instance as{TypeError} invalid-type;
+  instance.{self::Foo::self} = instance;
 }
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline.expect
new file mode 100644
index 0000000..7912167
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import "issue_32200.dart" as self;
+
+class Foo {
+  self.Foo self;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7912167
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import "issue_32200.dart" as self;
+
+class Foo {
+  self.Foo self;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline.expect
new file mode 100644
index 0000000..07c64a4
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class A {
+  foo(int x) => x;
+}
+
+class B {
+  foo(int x, {int y}) => y;
+}
+
+class C extends A implements B {
+  noSuchMethod(i) {}
+}
+
+class D {
+  foo(int x) => x;
+}
+
+class E extends D {
+  foo(int x, {int y});
+  noSuchMethod(i) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07c64a4
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class A {
+  foo(int x) => x;
+}
+
+class B {
+  foo(int x, {int y}) => y;
+}
+
+class C extends A implements B {
+  noSuchMethod(i) {}
+}
+
+class D {
+  foo(int x) => x;
+}
+
+class E extends D {
+  foo(int x, {int y});
+  noSuchMethod(i) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline.expect
new file mode 100644
index 0000000..afd767f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+void foo<X>(X i) {}
+
+class Foo {
+  static foo<X>(X i) {}
+  bar<X>(X i) {}
+}
+
+class Bar<X, Y> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fedb95a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Bar<X, Y> {}
+
+class Foo {
+  bar<X>(X i) {}
+  static foo<X>(X i) {}
+}
+
+main() {}
+void foo<X>(X i) {}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline.expect
new file mode 100644
index 0000000..eff2983
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class ExistingClass {
+  ExistingClass.existingConstructor();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eff2983
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class ExistingClass {
+  ExistingClass.existingConstructor();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34225.dart.textual_outline.expect
new file mode 100644
index 0000000..587ce92
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class C {
+  static set C(v) { }
+}
+class D {
+  set D(v) { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline.expect
new file mode 100644
index 0000000..0019a54
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import "issue_34291_lib.dart" as lib;
+
+class B {}
+
+lib.A<B> foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0019a54
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import "issue_34291_lib.dart" as lib;
+
+class B {}
+
+lib.A<B> foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline.expect
new file mode 100644
index 0000000..6ec803e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import 'issue_34403_lib.dart' as p;
+
+class C<T> {
+  C.bar();
+}
+
+class D<T> {
+  const D.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ec803e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'issue_34403_lib.dart' as p;
+
+class C<T> {
+  C.bar();
+}
+
+class D<T> {
+  const D.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline.expect
new file mode 100644
index 0000000..cc0607c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import 'issue_34498_lib.dart' as lib;
+
+class A {
+  lib.MyClass get lib => null;
+  foo foo() {}
+  Missing bar() {}
+}
+
+class B extends A {}
+
+final A a = null;
+
+class C<T> {
+  T<String> foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a3837b8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+import 'issue_34498_lib.dart' as lib;
+
+class A {
+  Missing bar() {}
+  foo foo() {}
+  lib.MyClass get lib => null;
+}
+
+class B extends A {}
+
+class C<T> {
+  T<String> foo() {}
+}
+
+final A a = null;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34563.dart.textual_outline.expect
new file mode 100644
index 0000000..e2de5d8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+mixin M1 {
+  int get m => 1;
+}
+mixin M2 extend M1 {
+}
+mixin M3 extends M1 {
+}
+class C1 {
+  int get c => 2;
+}
+class C2 extend C1 with M2 {
+}
+class C3 on C1 with M3 {
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34610.dart.textual_outline.expect
new file mode 100644
index 0000000..cd96318
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+  get A.named ()=> null;
+  get bar => 1;
+}
+class B {
+  B.named (): super();
+  get bar => 1;
+}
+class C {
+  C.named ()=> null;
+  get bar => 1;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34614.dart.textual_outline.expect
new file mode 100644
index 0000000..d25190b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  C. ( ){ }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
index 356eb8e..ad3a1ce 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
@@ -50,10 +50,6 @@
 // Future<List<>> f3() async {
 // ^
 //
-// pkg/front_end/testcases/regress/issue_34850.dart:14:16: Error: Functions marked 'async' must have a return type assignable to 'Future'.
-// Future<List<>> f3() async {
-//                ^^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
index 1175daa..730777c 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
@@ -50,10 +50,6 @@
 // Future<List<>> f3() async {
 // ^
 //
-// pkg/front_end/testcases/regress/issue_34850.dart:14:16: Error: Functions marked 'async' must have a return type assignable to 'Future'.
-// Future<List<>> f3() async {
-//                ^^
-//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
@@ -67,8 +63,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -81,21 +77,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method f3() → invalid-type /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -108,21 +104,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -139,12 +135,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34850.dart.textual_outline.expect
new file mode 100644
index 0000000..ce8cb35
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+<
+foo< int >f1() { }
+foo Future<List<int>> ( ){ }
+f2() async => null;
+Future<List<>> f3() async { }
+main() async { }
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35151.dart.textual_outline.expect
new file mode 100644
index 0000000..24a2200
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+  int a;
+}
+class B extends A {
+  B() : super.a = 42;
+}
+class C {
+  C() : super = 42;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline.expect
new file mode 100644
index 0000000..55bc6cb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+f(int a, int b) {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55bc6cb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+f(int a, int b) {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline.expect
new file mode 100644
index 0000000..81e059b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+  A bad() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81e059b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+  A bad() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline.expect
new file mode 100644
index 0000000..639a601
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+main() {}
+
+class C {
+  final d;
+  C() {}
+  C(this.d) {}
+}
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4d4891
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+  C() {}
+  C(this.d) {}
+  final d;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline.expect
new file mode 100644
index 0000000..a47d649
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Supertype {
+  factory Supertype() = Unresolved;
+  factory Supertype() = Unresolved;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a47d649
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Supertype {
+  factory Supertype() = Unresolved;
+  factory Supertype() = Unresolved;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline.expect
new file mode 100644
index 0000000..beaef36
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Supertype {
+  factory Supertype() = X;
+  factory Supertype() = X;
+}
+
+class X implements Supertype {
+  X();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..beaef36
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Supertype {
+  factory Supertype() = X;
+  factory Supertype() = X;
+}
+
+class X implements Supertype {
+  X();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline.expect
new file mode 100644
index 0000000..1d6a7d0
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class B<T> extends C<T> {
+  B();
+  factory B.foo() = B<T>;
+  factory B.foo() = B<T>;
+}
+
+class C<K> {
+  C();
+  factory C.bar() = B<K>.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1d6a7d0
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class B<T> extends C<T> {
+  B();
+  factory B.foo() = B<T>;
+  factory B.foo() = B<T>;
+}
+
+class C<K> {
+  C();
+  factory C.bar() = B<K>.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36400.dart.textual_outline.expect
new file mode 100644
index 0000000..8317039
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Test {
+  Test factory Test() { }
+}
diff --git a/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline.expect
new file mode 100644
index 0000000..489c840
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline.expect
@@ -0,0 +1 @@
+import 'issue_36647_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..489c840
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+import 'issue_36647_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline.expect
new file mode 100644
index 0000000..f3a511c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline.expect
@@ -0,0 +1 @@
+export 'issue_36647_2_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f3a511c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+export 'issue_36647_2_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline.expect
new file mode 100644
index 0000000..6cdd387
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class NoUnnamedConstuctor {
+  NoUnnamedConstuctor._();
+}
+
+class MixMeIn {}
+
+class Foo extends NoUnnamedConstuctor with MixMeIn {}
diff --git a/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c4b4f56
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo extends NoUnnamedConstuctor with MixMeIn {}
+
+class MixMeIn {}
+
+class NoUnnamedConstuctor {
+  NoUnnamedConstuctor._();
+}
diff --git a/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline.expect
new file mode 100644
index 0000000..b3d1993
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+const int y = 42;
+@y
+int x = 1;
+@y
+int x = 2;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aefe023
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+@y
+int x = 1;
+@y
+int x = 2;
+const int y = 42;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_37285.dart.textual_outline.expect
new file mode 100644
index 0000000..9feb16a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+  C() : super()[];
+}
+main () { }
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
index 79ba707..b47cf9c 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
@@ -23,8 +23,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -39,8 +39,8 @@
           final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
           asy::FutureOr<dynamic>* :return_value;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -53,13 +53,13 @@
               asy::_completeOnAsyncReturn(:async_completer, :return_value);
               return;
             }
-            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+            on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
               :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.start(:async_op);
+          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
           return :async_completer.{asy::Completer::future};
         }
         [yield] let dynamic #t1 = asy::_awaitHelper(f_async.call(), :async_op_then, :async_op_error, :async_op) in null;
@@ -68,8 +68,8 @@
           asy::_AsyncStarStreamController<dynamic>* :controller;
           dynamic :controller_stream;
           dynamic :async_stack_trace;
-          dynamic :async_op_then;
-          dynamic :async_op_error;
+          (dynamic) →* dynamic :async_op_then;
+          (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
           dynamic :await_ctx_var;
           dynamic :saved_try_context_var0;
@@ -86,7 +86,7 @@
                 }
                 return;
               }
-              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
                 :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
               }
             finally {
@@ -100,7 +100,7 @@
           return :controller_stream;
         }
         {
-          dynamic :stream = (f_async_star.call() as dynamic) as{TypeError,ForDynamic} asy::Stream<dynamic>*;
+          asy::Stream<dynamic>* :stream = (f_async_star.call() as dynamic) as{TypeError,ForDynamic} asy::Stream<dynamic>*;
           asy::_asyncStarListenHelper(:stream, :async_op);
           asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
           try
@@ -138,7 +138,7 @@
           return new core::_SyncIterable::•<dynamic>(:sync_op);
         }
         {
-          core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>((f_sync_star.call() as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+          core::Iterator<dynamic>* :sync-for-iterator = ((f_sync_star.call() as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
           for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
             dynamic x = :sync-for-iterator.{core::Iterator::current};
             {
@@ -150,12 +150,12 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline.expect
new file mode 100644
index 0000000..ab73b3a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline.expect
@@ -0,0 +1 @@
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab73b3a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_39091_1.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_39091_1.dart.textual_outline.expect
new file mode 100644
index 0000000..943e3f5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39091_1.dart.textual_outline.expect
@@ -0,0 +1 @@
+hello;
diff --git a/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline.expect
new file mode 100644
index 0000000..1d2a6fb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "issue_39682_lib.dart" deferred as foo;
+
+main() {}
+String __loadLibrary_foo() {}
diff --git a/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea21c2f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "issue_39682_lib.dart" deferred as foo;
+
+String __loadLibrary_foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_41265.crash_dart b/pkg/front_end/testcases/regress/issue_41265.crash_dart
new file mode 100644
index 0000000..b4deaff
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_41265.crash_dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+class A<T> {}
+
+mixin M<T> {}
+
+class DND1 extends Object with M<dynamic> Function()> {
+}
+
+class DND2 extends Object with M<dynamic> Function() {
+}
+
+class DND3 extends M<dynamic> Function() {
+}
+
+class DND4 implements M<dynamic> Function() {
+}
+
+main() {
+  // nothing.
+}
diff --git a/pkg/front_end/testcases/regress/issue_41265.crash_dart.outline.expect b/pkg/front_end/testcases/regress/issue_41265.crash_dart.outline.expect
new file mode 100644
index 0000000..a373059
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_41265.crash_dart.outline.expect
@@ -0,0 +1,67 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:53: Error: Unexpected token '>'.
+// class DND1 extends Object with M<dynamic> Function()> {
+//                                                     ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:7: Error: The type '() -> M<dynamic>' can't be mixed in.
+// class DND1 extends Object with M<dynamic> Function()> {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:12:7: Error: The type '() -> M<dynamic>' can't be mixed in.
+// class DND2 extends Object with M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:7: Error: Can't use a function type as supertype.
+// class DND1 extends Object with M<dynamic> Function()> {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:12:7: Error: Can't use a function type as supertype.
+// class DND2 extends Object with M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:15:7: Error: Can't use a function type as supertype.
+// class DND3 extends M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:18:7: Error: Can't use a function type as supertype.
+// class DND4 implements M<dynamic> Function() {
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T*>*
+    ;
+}
+abstract class M<T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _DND1&Object extends core::Object /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DND1&Object*
+    ;
+}
+class DND1 extends self::_DND1&Object {
+  synthetic constructor •() → self::DND1*
+    ;
+}
+abstract class _DND2&Object extends core::Object /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DND2&Object*
+    ;
+}
+class DND2 extends self::_DND2&Object {
+  synthetic constructor •() → self::DND2*
+    ;
+}
+class DND3 extends core::Object {
+  synthetic constructor •() → self::DND3*
+    ;
+}
+class DND4 extends core::Object {
+  synthetic constructor •() → self::DND4*
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/regress/issue_41265.crash_dart.strong.expect b/pkg/front_end/testcases/regress/issue_41265.crash_dart.strong.expect
new file mode 100644
index 0000000..a161395
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_41265.crash_dart.strong.expect
@@ -0,0 +1,73 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:53: Error: Unexpected token '>'.
+// class DND1 extends Object with M<dynamic> Function()> {
+//                                                     ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:7: Error: The type '() -> M<dynamic>' can't be mixed in.
+// class DND1 extends Object with M<dynamic> Function()> {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:12:7: Error: The type '() -> M<dynamic>' can't be mixed in.
+// class DND2 extends Object with M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:7: Error: Can't use a function type as supertype.
+// class DND1 extends Object with M<dynamic> Function()> {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:12:7: Error: Can't use a function type as supertype.
+// class DND2 extends Object with M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:15:7: Error: Can't use a function type as supertype.
+// class DND3 extends M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:18:7: Error: Can't use a function type as supertype.
+// class DND4 implements M<dynamic> Function() {
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T*>*
+    : super core::Object::•()
+    ;
+}
+abstract class M<T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _DND1&Object extends core::Object /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DND1&Object*
+    : super core::Object::•()
+    ;
+}
+class DND1 extends self::_DND1&Object {
+  synthetic constructor •() → self::DND1*
+    : super self::_DND1&Object::•()
+    ;
+}
+abstract class _DND2&Object extends core::Object /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DND2&Object*
+    : super core::Object::•()
+    ;
+}
+class DND2 extends self::_DND2&Object {
+  synthetic constructor •() → self::DND2*
+    : super self::_DND2&Object::•()
+    ;
+}
+class DND3 extends core::Object {
+  synthetic constructor •() → self::DND3*
+    : super core::Object::•()
+    ;
+}
+class DND4 extends core::Object {
+  synthetic constructor •() → self::DND4*
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_41265.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_41265.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..a161395
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_41265.crash_dart.strong.transformed.expect
@@ -0,0 +1,73 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:53: Error: Unexpected token '>'.
+// class DND1 extends Object with M<dynamic> Function()> {
+//                                                     ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:7: Error: The type '() -> M<dynamic>' can't be mixed in.
+// class DND1 extends Object with M<dynamic> Function()> {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:12:7: Error: The type '() -> M<dynamic>' can't be mixed in.
+// class DND2 extends Object with M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:9:7: Error: Can't use a function type as supertype.
+// class DND1 extends Object with M<dynamic> Function()> {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:12:7: Error: Can't use a function type as supertype.
+// class DND2 extends Object with M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:15:7: Error: Can't use a function type as supertype.
+// class DND3 extends M<dynamic> Function() {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_41265.crash_dart:18:7: Error: Can't use a function type as supertype.
+// class DND4 implements M<dynamic> Function() {
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T*>*
+    : super core::Object::•()
+    ;
+}
+abstract class M<T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _DND1&Object extends core::Object /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DND1&Object*
+    : super core::Object::•()
+    ;
+}
+class DND1 extends self::_DND1&Object {
+  synthetic constructor •() → self::DND1*
+    : super self::_DND1&Object::•()
+    ;
+}
+abstract class _DND2&Object extends core::Object /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_DND2&Object*
+    : super core::Object::•()
+    ;
+}
+class DND2 extends self::_DND2&Object {
+  synthetic constructor •() → self::DND2*
+    : super self::_DND2&Object::•()
+    ;
+}
+class DND3 extends core::Object {
+  synthetic constructor •() → self::DND3*
+    : super core::Object::•()
+    ;
+}
+class DND4 extends core::Object {
+  synthetic constructor •() → self::DND4*
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_41265.crash_dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_41265.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..0ebe3c9
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_41265.crash_dart.textual_outline.expect
@@ -0,0 +1 @@
+class A<T> {} mixin M<T> {} class DND1 extends Object with M<dynamic> Function()> { } class DND2 extends Object with M<dynamic> Function() { } class DND3 extends M<dynamic> Function() { } class DND4 implements M<dynamic> Function() { } main() { }
diff --git a/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart
new file mode 100644
index 0000000..3c1884f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart
Binary files differ
diff --git a/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.outline.expect b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.outline.expect
new file mode 100644
index 0000000..13bf5cc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.outline.expect
Binary files differ
diff --git a/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.expect b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.expect
new file mode 100644
index 0000000..03dca82
--- /dev/null
+++ b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.expect
Binary files differ
diff --git a/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..03dca82
--- /dev/null
+++ b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.transformed.expect
Binary files differ
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline.expect
new file mode 100644
index 0000000..de4942d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F();
+
+class C {
+  void f() {}
+  F get g => null;
+  dynamic get h => null;
+  void test() {}
+}
+
+void test(C c, F f, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..078b15a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C {
+  F get g => null;
+  dynamic get h => null;
+  void f() {}
+  void test() {}
+}
+
+main() {}
+typedef void F();
+void test(C c, F f, dynamic d) {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline.expect
new file mode 100644
index 0000000..aaf824e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  dynamic get x => null;
+  dynamic y;
+  void test() {}
+}
+
+void test(C c, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..588c9cd
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  dynamic get x => null;
+  dynamic y;
+  void test() {}
+}
+
+main() {}
+void test(C c, dynamic d) {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline.expect
new file mode 100644
index 0000000..c96f079
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  void set x(dynamic value) {}
+  dynamic y;
+  void test() {}
+}
+
+void test(C c, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ea93b3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+  dynamic y;
+  void set x(dynamic value) {}
+  void test() {}
+}
+
+main() {}
+void test(C c, dynamic d) {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..acd8a15
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..acd8a15
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline.expect
new file mode 100644
index 0000000..c9eba70
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:async';
+
+class C {
+  void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c9eba70
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:async';
+
+class C {
+  void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline.expect
new file mode 100644
index 0000000..8d81028
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> y;
+  void f() {}
+}
+
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..54efdb7
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  F<T> y;
+  void f() {}
+}
+
+typedef void F<T>(T x);
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..3bc94cd
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+typedef void F<T>(T t);
+
+class C<T> {
+  void f<U extends F<T>>(U x) {}
+}
+
+void g(C<num> c) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d45149c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f<U extends F<T>>(U x) {}
+}
+
+typedef void F<T>(T t);
+void g(C<num> c) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline.expect
new file mode 100644
index 0000000..dc2912a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> f1() {}
+  List<F<T>> f2() {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c35eb5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+  F<T> f1() {}
+  List<F<T>> f2() {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..dc2912a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> f1() {}
+  List<F<T>> f2() {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c35eb5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+  F<T> f1() {}
+  List<F<T>> f2() {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..950b57d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+typedef F<T> G<T>();
+
+class C<T> {
+  F<T> _x;
+  C(this._x);
+  F<T> f() => _x;
+}
+
+G<num> g(C<num> c) {}
+void h(int i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ac397a4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+G<num> g(C<num> c) {}
+
+class C<T> {
+  C(this._x);
+  F<T> _x;
+  F<T> f() => _x;
+}
+
+typedef F<T> G<T>();
+typedef void F<T>(T x);
+void h(int i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..69264e5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> y;
+  void f(T value) {}
+}
+
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f9b4c27
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  F<T> y;
+  void f(T value) {}
+}
+
+typedef void F<T>(T x);
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline.expect
new file mode 100644
index 0000000..c87589e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> get f1 => null;
+  List<F<T>> get f2 {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc0e76e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+  F<T> get f1 => null;
+  List<F<T>> get f2 {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..c87589e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> get f1 => null;
+  List<F<T>> get f2 {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc0e76e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+  F<T> get f1 => null;
+  List<F<T>> get f2 {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..066813e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f<U extends T>(U x) {}
+  void g1<U extends T>() {}
+}
+
+void g2(C<Object> c) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bbb372
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f<U extends T>(U x) {}
+  void g1<U extends T>() {}
+}
+
+void g2(C<Object> c) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..9eb7363
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f(T x) {}
+}
+
+void g1(C<num> c) {}
+void g2(C<int> c) {}
+void g3(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a772405
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f(T x) {}
+}
+
+main() {}
+void g1(C<num> c) {}
+void g2(C<int> c) {}
+void g3(C<num> c) {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..be90d87
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class C<T> {
+  void f1(List<T> x) {}
+  void f2(T callback()) {}
+  void f3(T callback(T x)) {}
+  void f4(void callback(T x)) {}
+}
+
+void g1(C<num> c, List<num> l) {}
+void g2(C<num> c, num callback()) {}
+void g3(C<num> c, num callback(num x)) {}
+void g4(C<num> c, void callback(num x)) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b83d94
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class C<T> {
+  void f1(List<T> x) {}
+  void f2(T callback()) {}
+  void f3(T callback(T x)) {}
+  void f4(void callback(T x)) {}
+}
+
+main() {}
+void g1(C<num> c, List<num> l) {}
+void g2(C<num> c, num callback()) {}
+void g3(C<num> c, num callback(num x)) {}
+void g4(C<num> c, void callback(num x)) {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..51601b9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+abstract class I<T> {
+  void f1(T x);
+  void f2(T x);
+}
+
+class C<U> implements I<int> {
+  void f1(int x) {}
+  void f2(int x, [U y]) {}
+}
+
+class D<U> extends C<U> {
+  void f1(int x) {}
+  void f2(int x, [U y]) {}
+}
+
+void g1(C<num> c) {}
+void g2(I<num> i) {}
+void g3(C<num> c) {}
+void g4(D<num> d) {}
+void g5(D<num> d) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..15e7d8a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+abstract class I<T> {
+  void f1(T x);
+  void f2(T x);
+}
+
+class C<U> implements I<int> {
+  void f1(int x) {}
+  void f2(int x, [U y]) {}
+}
+
+class D<U> extends C<U> {
+  void f1(int x) {}
+  void f2(int x, [U y]) {}
+}
+
+void g1(C<num> c) {}
+void g2(I<num> i) {}
+void g3(C<num> c) {}
+void g4(D<num> d) {}
+void g5(D<num> d) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..7d6cf9b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class B {
+  void f(int x) {}
+}
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class M {
+  void f(int x) {}
+}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b47acf4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class B {
+  void f(int x) {}
+}
+
+class M {
+  void f(int x) {}
+}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline.expect
new file mode 100644
index 0000000..1995799
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class B {
+  void f(int x) {}
+}
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class C extends B implements I<int> {}
+
+void g1(C c) {}
+void g2(I<num> i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..da6ecc9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class B {
+  void f(int x) {}
+}
+
+class C extends B implements I<int> {}
+
+void g1(C c) {}
+void g2(I<num> i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..ef098bf
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+class B {
+  void f(int x) {}
+}
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class M {}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f80a0b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class B {
+  void f(int x) {}
+}
+
+class M {}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..86fd3b6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+typedef U G<T, U>(T x);
+
+class C<T> {
+  void f1(T x) {}
+  T f2(List<T> x) => x.first;
+}
+
+F<num> g1(C<num> c) {}
+void g2(C<int> c, Object x) {}
+G<List<num>, num> g3(C<num> c) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c813f8d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+F<num> g1(C<num> c) {}
+G<List<num>, num> g3(C<num> c) {}
+
+class C<T> {
+  T f2(List<T> x) => x.first;
+  void f1(T x) {}
+}
+
+main() {}
+typedef U G<T, U>(T x);
+typedef void F<T>(T x);
+void g2(C<int> c, Object x) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline.expect
new file mode 100644
index 0000000..a0211e4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+typedef F<T>(T x);
+
+class C {
+  void f(num x) {}
+}
+
+class D extends C {
+  void f(covariant int x) {}
+}
+
+class E extends D {
+  void f(int x) {}
+}
+
+void g1(C c) {}
+F<num> g2(C c) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7b38b24
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+F<num> g2(C c) {}
+
+class C {
+  void f(num x) {}
+}
+
+class D extends C {
+  void f(covariant int x) {}
+}
+
+class E extends D {
+  void f(int x) {}
+}
+
+main() {}
+test() {}
+typedef F<T>(T x);
+void g1(C c) {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline.expect
new file mode 100644
index 0000000..42ad63f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  num x;
+}
+
+class D implements C {
+  covariant int x;
+}
+
+class E implements D {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..42ad63f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  num x;
+}
+
+class D implements C {
+  covariant int x;
+}
+
+class E implements D {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..0e97340
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class C {
+  num x;
+}
+
+class D implements C {
+  covariant int x;
+}
+
+class E implements D {
+  int get x => 0;
+  void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e97340
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+class C {
+  num x;
+}
+
+class D implements C {
+  covariant int x;
+}
+
+class E implements D {
+  int get x => 0;
+  void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..3e18946
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  void set x(num value) {}
+}
+
+class D extends C {
+  void set x(covariant int value) {}
+}
+
+class E extends D {
+  void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3e18946
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  void set x(num value) {}
+}
+
+class D extends C {
+  void set x(covariant int value) {}
+}
+
+class E extends D {
+  void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline.expect
new file mode 100644
index 0000000..335e47d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  void set x(num value) {}
+}
+
+class D extends C {
+  void set x(covariant int value) {}
+}
+
+class E implements D {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..335e47d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+  void set x(num value) {}
+}
+
+class D extends C {
+  void set x(covariant int value) {}
+}
+
+class E implements D {
+  int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..b8c3d2f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  T x;
+  void set y(T value) {}
+  void f(T value) {}
+}
+
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b7e0f42
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C<T> {
+  T x;
+  void f(T value) {}
+  void set y(T value) {}
+}
+
+typedef void F<T>(T x);
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..3385f7f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C<T> {
+  void f1(T x) {}
+  void f2(int x) {}
+}
+
+class D extends C<num> {
+  void f1(covariant int x) {}
+}
+
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89135dc
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C<T> {
+  void f1(T x) {}
+  void f2(int x) {}
+}
+
+class D extends C<num> {
+  void f1(covariant int x) {}
+}
+
+main() {}
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..3ab451a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f<U extends T>(U x) {}
+}
+
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cc44c99
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+  void f<U extends T>(U x) {}
+}
+
+main() {}
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..7737325
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  dynamic f;
+  C(this.f);
+}
+
+void g(C c) {}
+void h(int i) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e49871
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+  C(this.f);
+  dynamic f;
+}
+
+main() {}
+void g(C c) {}
+void h(int i) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..8c4b40b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B<T> {
+  T x;
+}
+
+class C {
+  num x;
+}
+
+class D extends C implements B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c4b40b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B<T> {
+  T x;
+}
+
+class C {
+  num x;
+}
+
+class D extends C implements B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..289a96e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+class B {
+  Object _x;
+  void f([num x = 10]) {}
+  void g({num x = 20}) {}
+  void check(Object expectedValue) {}
+}
+
+abstract class I<T> {
+  void f([T x]);
+  void g({T x});
+}
+
+class C extends B implements I<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ca314d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class I<T> {
+  void f([T x]);
+  void g({T x});
+}
+
+class B {
+  Object _x;
+  void check(Object expectedValue) {}
+  void f([num x = 10]) {}
+  void g({num x = 20}) {}
+}
+
+class C extends B implements I<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8c6231b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+  void f(int x, int y) {}
+}
+
+abstract class I<T> {
+  void f(T x, int y);
+}
+
+class C extends B implements I<int> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..345dc98
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class I<T> {
+  void f(T x, int y);
+}
+
+class B {
+  void f(int x, int y) {}
+}
+
+class C extends B implements I<int> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline.expect
new file mode 100644
index 0000000..04e6489
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class C<T> {
+  void set x(T t) {}
+  T y;
+}
+
+class D implements C<num> {
+  num x;
+  num y;
+}
+
+class E implements C<num> {
+  void set x(num t) {}
+  num get y => null;
+  void set y(num t) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8d40bf2
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class C<T> {
+  T y;
+  void set x(T t) {}
+}
+
+class D implements C<num> {
+  num x;
+  num y;
+}
+
+class E implements C<num> {
+  num get y => null;
+  void set x(num t) {}
+  void set y(num t) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline.expect
new file mode 100644
index 0000000..9423c72
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class A {
+  void set x(covariant Object value);
+}
+
+class B implements A {
+  void f(covariant Object x) {}
+  Object x;
+}
+
+class C<T> implements B {
+  void f(T x) {}
+  T x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49de95f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class A {
+  void set x(covariant Object value);
+}
+
+class B implements A {
+  Object x;
+  void f(covariant Object x) {}
+}
+
+class C<T> implements B {
+  T x;
+  void f(T x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..1c0e505
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  C(Object o) : assert(o);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1c0e505
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+  C(Object o) : assert(o);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..5767080
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  bool b;
+  C(Object o) : b = o;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37e2b22
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+  C(Object o) : b = o;
+  bool b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline.expect
new file mode 100644
index 0000000..84c7157
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class B {
+  void f(num x) {}
+}
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class C extends B implements I<num> {
+  void f(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..168422a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I<T> {
+  void f(T x);
+}
+
+class B {
+  void f(num x) {}
+}
+
+class C extends B implements I<num> {
+  void f(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline.expect
new file mode 100644
index 0000000..6c7fe09
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+typedef F<T>(T x);
+
+class C<T> {
+  void f(T x) {}
+  void g1(T x) {}
+  void g2(T x) {}
+  void g3(C<T> c, T x) {}
+  F<T> g4() => this.f;
+}
+
+class D extends C<int> {}
+
+class E extends C<num> {
+  void f(covariant int x) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a210365
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class C<T> {
+  F<T> g4() => this.f;
+  void f(T x) {}
+  void g1(T x) {}
+  void g2(T x) {}
+  void g3(C<T> c, T x) {}
+}
+
+class D extends C<int> {}
+
+class E extends C<num> {
+  void f(covariant int x) {}
+}
+
+main() {}
+test() {}
+typedef F<T>(T x);
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..bd7aa707
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+typedef void F<T>(T x);
+
+class B<T, U extends F<T>> {
+  B<T, F<T>> operator +(other) => null;
+}
+
+class C {
+  B<num, F<num>> x;
+  static B<num, F<num>> y;
+  B<num, F<num>> operator [](int i) => null;
+  void operator []=(int i, B<num, F<num>> v) {}
+}
+
+void test1(B<num, F<num>> b) {}
+void test2(C c) {}
+void test3(C c) {}
+void test4(C c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..231976b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class B<T, U extends F<T>> {
+  B<T, F<T>> operator +(other) => null;
+}
+
+class C {
+  B<num, F<num>> operator [](int i) => null;
+  B<num, F<num>> x;
+  static B<num, F<num>> y;
+  void operator []=(int i, B<num, F<num>> v) {}
+}
+
+typedef void F<T>(T x);
+void main() {}
+void test1(B<num, F<num>> b) {}
+void test2(C c) {}
+void test3(C c) {}
+void test4(C c) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline.expect
new file mode 100644
index 0000000..c331f05
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class C<T> {
+  C(this.plusResult);
+  final num Function(T) plusResult;
+  num Function(T) operator +(int i) => plusResult;
+}
+
+class D {
+  D(this.getValue);
+  final C<num> getValue;
+  C<num> get value => getValue;
+  int Function(int) setValue;
+  void set value(int Function(int) value) {}
+}
+
+int numToInt(num n) => 1;
+num numToNum(num n) => 2;
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2c9d06
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class C<T> {
+  C(this.plusResult);
+  final num Function(T) plusResult;
+  num Function(T) operator +(int i) => plusResult;
+}
+
+class D {
+  C<num> get value => getValue;
+  D(this.getValue);
+  final C<num> getValue;
+  int Function(int) setValue;
+  void set value(int Function(int) value) {}
+}
+
+int numToInt(num n) => 1;
+num numToNum(num n) => 2;
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline.expect
new file mode 100644
index 0000000..b03de79
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+
+class B<T> {
+  B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+  B<F<T>> get x => null;
+  void set x(B<F<T>> value) {}
+}
+
+void test(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e87293
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+  B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+  B<F<T>> get x => null;
+  void set x(B<F<T>> value) {}
+}
+
+main() {}
+typedef void F<T>(T x);
+void test(C<num> c) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline.expect
new file mode 100644
index 0000000..63f05d9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+
+class B<T> {
+  B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+  B<F<T>> operator [](int i) => null;
+  void operator []=(int i, B<F<T>> x) {}
+}
+
+void test(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ee8f9fa
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+  B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+  B<F<T>> operator [](int i) => null;
+  void operator []=(int i, B<F<T>> x) {}
+}
+
+main() {}
+typedef void F<T>(T x);
+void test(C<num> c) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline.expect
new file mode 100644
index 0000000..3e84e6d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+  F<T> operator [](int i) => null;
+}
+
+F<num> test(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f10da16
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+F<num> test(C<num> c) {}
+
+class C<T> {
+  F<T> operator [](int i) => null;
+}
+
+main() {}
+typedef void F<T>(T x);
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..6f29a54
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+  void f(T x) {}
+  void g({T x}) {}
+  void h<U extends T>() {}
+}
+
+class C extends B<int> {}
+
+void g1(B<num> b) {}
+void g2(C c) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8dc39af
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+  void f(T x) {}
+  void g({T x}) {}
+  void h<U extends T>() {}
+}
+
+class C extends B<int> {}
+
+void g1(B<num> b) {}
+void g2(C c) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..7cfc8c5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class B<T> {
+  T x;
+}
+
+class C extends B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7cfc8c5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class B<T> {
+  T x;
+}
+
+class C extends B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..13b768c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+  covariant num x;
+}
+
+class C {
+  int x;
+}
+
+class D extends C implements B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13b768c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+  covariant num x;
+}
+
+class C {
+  int x;
+}
+
+class D extends C implements B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect
index 5ae1f55..6a96046 100644
--- a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect
@@ -1,7 +1,6 @@
 library test;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class C extends core::Object {
   static field dynamic staticField = null;
@@ -14,7 +13,7 @@
   method test() → void {
     dynamic localVar;
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t1 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -23,7 +22,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -32,7 +31,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t3 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -41,7 +40,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -50,7 +49,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t5 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -59,7 +58,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
         {
@@ -68,7 +67,7 @@
       }
     }
     {
-      core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(<dynamic>[]).{core::Iterable::iterator};
+      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t7 = :sync-for-iterator.{core::Iterator::current};
         {
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline.expect
new file mode 100644
index 0000000..f3282d1
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+var topLevel;
+void set topLevelSetter(x) {}
+
+class C {
+  static var staticField;
+  static void set staticSetter(x) {}
+  var instanceField;
+  void set instanceSetter(x) {}
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b85754
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class C {
+  static var staticField;
+  static void set staticSetter(x) {}
+  var instanceField;
+  void set instanceSetter(x) {}
+  void test() {}
+}
+
+main() {}
+var topLevel;
+void set topLevelSetter(x) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..e27dd81
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+class B<T> {
+  T x;
+  T y;
+}
+
+abstract class C<T> implements B<num> {
+  var x;
+  get y;
+  set y(value);
+}
+
+abstract class D<T> implements B<T> {
+  var x;
+  get y;
+  set y(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5c970ba
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+abstract class C<T> implements B<num> {
+  get y;
+  set y(value);
+  var x;
+}
+
+abstract class D<T> implements B<T> {
+  get y;
+  set y(value);
+  var x;
+}
+
+class B<T> {
+  T x;
+  T y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline.expect
new file mode 100644
index 0000000..340c0be
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+Object o = 1;
+bool topLevelValue = o;
+
+class C {
+  static bool staticValue = o;
+  bool instanceValue = o;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b8f20e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+Object o = 1;
+bool topLevelValue = o;
+
+class C {
+  bool instanceValue = o;
+  static bool staticValue = o;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline.expect
new file mode 100644
index 0000000..532c570
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class B {
+  int get x {}
+  void set x(int value) {}
+  int get y {}
+  void set y(int value) {}
+}
+
+abstract class I<T> {
+  T get x;
+  void set x(T value);
+  Object get y;
+  void set y(covariant Object value);
+}
+
+class M {
+  int x;
+  int y;
+}
+
+class C = B with M implements I<int>;
+void test(I<Object> i) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89b6b10
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+library test;
+
+abstract class I<T> {
+  Object get y;
+  T get x;
+  void set x(T value);
+  void set y(covariant Object value);
+}
+
+class B {
+  int get x {}
+  int get y {}
+  void set x(int value) {}
+  void set y(int value) {}
+}
+
+class M {
+  int x;
+  int y;
+}
+
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+class C = B with M implements I<int>;
+void main() {}
+void test(I<Object> i) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..7b50e59
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class B {
+  int get x {}
+  void set x(int value) {}
+  int get y {}
+  void set y(int value) {}
+}
+
+abstract class I<T> {
+  T get x;
+  void set x(T value);
+  Object get y;
+  void set y(covariant Object value);
+}
+
+class M {
+  int get x => 1;
+  void set x(int value) {}
+  int get y => 3;
+  void set y(int value) {}
+}
+
+class C = B with M implements I<int>;
+void test(I<Object> i) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a23006b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+library test;
+
+abstract class I<T> {
+  Object get y;
+  T get x;
+  void set x(T value);
+  void set y(covariant Object value);
+}
+
+class B {
+  int get x {}
+  int get y {}
+  void set x(int value) {}
+  void set y(int value) {}
+}
+
+class M {
+  int get x => 1;
+  int get y => 3;
+  void set x(int value) {}
+  void set y(int value) {}
+}
+
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+class C = B with M implements I<int>;
+void main() {}
+void test(I<Object> i) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline.expect
new file mode 100644
index 0000000..c474b44
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class B {
+  int f(int x) {}
+}
+
+abstract class I {
+  int f(covariant Object x);
+}
+
+class C extends B implements I {}
+
+void g(C c) {}
+void test(C c, I i) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d49ed63
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class I {
+  int f(covariant Object x);
+}
+
+class B {
+  int f(int x) {}
+}
+
+class C extends B implements I {}
+
+main() {}
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+void g(C c) {}
+void test(C c, I i) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..83b6b0f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+  void f(int x, int y) {}
+}
+
+abstract class I<T> {
+  void f(T x, Object y);
+}
+
+abstract class C extends B implements I<int> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..90a097c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B implements I<int> {}
+
+abstract class I<T> {
+  void f(T x, Object y);
+}
+
+class B {
+  void f(int x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline.expect
new file mode 100644
index 0000000..ac08d82
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B<T> {
+  void f(T x, int y) {}
+}
+
+abstract class I {
+  void f(int x, Object y);
+}
+
+abstract class C extends B<int> implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..22c5f69
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B<int> implements I {}
+
+abstract class I {
+  void f(int x, Object y);
+}
+
+class B<T> {
+  void f(T x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..d453753
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+  void f(int x, int y) {}
+}
+
+abstract class I {
+  void f(covariant int x, Object y);
+}
+
+abstract class C extends B implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f722096
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B implements I {}
+
+abstract class I {
+  void f(covariant int x, Object y);
+}
+
+class B {
+  void f(int x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline.expect
new file mode 100644
index 0000000..e101817
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+  void f(covariant int x, int y) {}
+}
+
+abstract class I {
+  void f(int x, Object y);
+}
+
+abstract class C extends B implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5bade16
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B implements I {}
+
+abstract class I {
+  void f(int x, Object y);
+}
+
+class B {
+  void f(covariant int x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/sdk.status b/pkg/front_end/testcases/sdk.status
index f795f08..9119938 100644
--- a/pkg/front_end/testcases/sdk.status
+++ b/pkg/front_end/testcases/sdk.status
@@ -13,6 +13,9 @@
 language_2/conditional_property_increment_decrement_test/16_generated: VerificationError
 language_2/conditional_property_increment_decrement_test/21_generated: VerificationError
 language_2/conditional_property_increment_decrement_test/27_generated: VerificationError
+language_2/constructor5_test: VerificationError
+language_2/constructor6_test: VerificationError
+language_2/extension_methods/static_extension_operators_test: VerificationError
 language_2/if_null_assignment_behavior_test/13_generated: Crash
 language_2/if_null_assignment_behavior_test/15_generated: Crash
 language_2/if_null_assignment_behavior_test/29_generated: Crash
@@ -34,6 +37,3 @@
 language_2/type_variable_scope_test/03_generated: VerificationError
 language_2/void/void_type_usage_test/final_local_use_in_conditional_assignment_left_generated: Crash
 language_2/void/void_type_usage_test/paren_use_in_conditional_assignment_left_generated: Crash
-language_2/constructor5_test: VerificationError
-language_2/constructor6_test: VerificationError
-language_2/extension_methods/static_extension_operators_test: VerificationError
\ No newline at end of file
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
index 486d1399..11b9194 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
@@ -16,14 +16,16 @@
 //   LinkedHashMap<int, bool> lhm = {};
 //                                  ^
 //
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'Set' is from 'dart:core'.
 //  - 'LinkedHashSet' is from 'dart:collection'.
 // Change the type of the set literal or the context in which it is used.
 // Future<LinkedHashSet<int>> lhsfun() async => {};
 //                                              ^
 //
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'Map' is from 'dart:core'.
 //  - 'LinkedHashMap' is from 'dart:collection'.
 // Change the type of the map literal or the context in which it is used.
@@ -86,14 +88,16 @@
 static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async 
   return let final core::Set<core::int*>* #t7 = col::LinkedHashSet::•<core::int*>() in #t7;
 static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async 
-  return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+  return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+ - 'Future' is from 'dart:async'.
  - 'Set' is from 'dart:core'.
  - 'LinkedHashSet' is from 'dart:collection'.
 Change the type of the set literal or the context in which it is used.
 Future<LinkedHashSet<int>> lhsfun() async => {};
                                              ^" in let final core::Set<dynamic>* #t9 = col::LinkedHashSet::•<dynamic>() in #t9;
 static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async 
-  return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+  return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+ - 'Future' is from 'dart:async'.
  - 'Map' is from 'dart:core'.
  - 'LinkedHashMap' is from 'dart:collection'.
 Change the type of the map literal or the context in which it is used.
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
index 3f7f9e6..c5bd85d 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
@@ -16,14 +16,16 @@
 //   LinkedHashMap<int, bool> lhm = {};
 //                                  ^
 //
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'Set' is from 'dart:core'.
 //  - 'LinkedHashSet' is from 'dart:collection'.
 // Change the type of the set literal or the context in which it is used.
 // Future<LinkedHashSet<int>> lhsfun() async => {};
 //                                              ^
 //
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+//  - 'Future' is from 'dart:async'.
 //  - 'Map' is from 'dart:core'.
 //  - 'LinkedHashMap' is from 'dart:collection'.
 // Change the type of the map literal or the context in which it is used.
@@ -57,8 +59,8 @@
   final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   dynamic :saved_try_context_var0;
@@ -105,21 +107,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::Map<core::int*, core::bool*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Map<core::int*, core::bool*>*>();
   asy::FutureOr<core::Map<core::int*, core::bool*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -132,21 +134,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method setfun() → asy::Future<core::Set<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::Set<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Set<core::int*>*>();
   asy::FutureOr<core::Set<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -159,21 +161,21 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::Iterable<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Iterable<core::int*>*>();
   asy::FutureOr<core::Iterable<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -186,28 +188,29 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<col::LinkedHashSet<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<col::LinkedHashSet<core::int*>*>();
   asy::FutureOr<col::LinkedHashSet<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
     try {
       #L5:
       {
-        :return_value = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+        :return_value = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+ - 'Future' is from 'dart:async'.
  - 'Set' is from 'dart:core'.
  - 'LinkedHashSet' is from 'dart:collection'.
 Change the type of the set literal or the context in which it is used.
@@ -218,28 +221,29 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* /* originally async */ {
   final asy::_AsyncAwaitCompleter<col::LinkedHashMap<core::int*, core::bool*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<col::LinkedHashMap<core::int*, core::bool*>*>();
   asy::FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>* :return_value;
   dynamic :async_stack_trace;
-  dynamic :async_op_then;
-  dynamic :async_op_error;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
   dynamic :await_ctx_var;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
     try {
       #L6:
       {
-        :return_value = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+        :return_value = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+ - 'Future' is from 'dart:async'.
  - 'Map' is from 'dart:core'.
  - 'LinkedHashMap' is from 'dart:collection'.
 Change the type of the map literal or the context in which it is used.
@@ -250,13 +254,13 @@
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
     }
-    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
       :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.start(:async_op);
+  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
   return :async_completer.{asy::Completer::future};
 }
 static method mapfun2() → asy::FutureOr<core::Map<core::int*, core::bool*>*>*
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline.expect
new file mode 100644
index 0000000..183ae0c
--- /dev/null
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import 'dart:async' show FutureOr;
+import 'dart:collection' show LinkedHashMap, LinkedHashSet;
+
+main() async {}
+Future<Map<int, bool>> mapfun() async => {};
+Future<Set<int>> setfun() async => {};
+Future<Iterable<int>> iterablefun() async => {};
+Future<LinkedHashSet<int>> lhsfun() async => {};
+Future<LinkedHashMap<int, bool>> lhmfun() async => {};
+FutureOr<Map<int, bool>> mapfun2() => {};
+FutureOr<Set<int>> setfun2() => {};
+FutureOr<Iterable<int>> iterablefun2() => {};
+FutureOr<LinkedHashSet<int>> lhsfun2() => {};
+FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd5d4f6
--- /dev/null
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import 'dart:async' show FutureOr;
+import 'dart:collection' show LinkedHashMap, LinkedHashSet;
+
+Future<Iterable<int>> iterablefun() async => {};
+Future<LinkedHashMap<int, bool>> lhmfun() async => {};
+Future<LinkedHashSet<int>> lhsfun() async => {};
+Future<Map<int, bool>> mapfun() async => {};
+Future<Set<int>> setfun() async => {};
+FutureOr<Iterable<int>> iterablefun2() => {};
+FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
+FutureOr<LinkedHashSet<int>> lhsfun2() => {};
+FutureOr<Map<int, bool>> mapfun2() => {};
+FutureOr<Set<int>> setfun2() => {};
+main() async {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 61f29c9e..8707c0c 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -31,6 +31,32 @@
 general/error_locations/error_location_03: RuntimeError
 general/error_locations/error_location_05: RuntimeError
 general/error_locations/error_location_06: RuntimeError
+general/error_recovery/await_not_in_async: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_general.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_get.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_return_type.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_set.crash: RuntimeError
+general/error_recovery/constructor_recovery_get: RuntimeError
+general/error_recovery/constructor_recovery_ok: RuntimeError
+general/error_recovery/constructor_recovery_operator.crash: RuntimeError
+general/error_recovery/constructor_recovery_return_type: RuntimeError
+general/error_recovery/constructor_recovery_set: RuntimeError
+general/error_recovery/empty_await_for: RuntimeError
+general/error_recovery/empty_for: RuntimeError
+general/error_recovery/issue_38415.crash: RuntimeError
+general/error_recovery/issue_39024.crash: RuntimeError
+general/error_recovery/issue_39026.crash: RuntimeError
+general/error_recovery/issue_39026_prime.crash: RuntimeError
+general/error_recovery/issue_39033.crash: RuntimeError
+general/error_recovery/issue_39058.crash: RuntimeError
+general/error_recovery/issue_39058_prime.crash: RuntimeError
+general/error_recovery/issue_39202.crash: RuntimeError
+general/error_recovery/issue_39230.crash: RuntimeError
+general/error_recovery/issue_39958_01: RuntimeError
+general/error_recovery/issue_39958_02: RuntimeError
+general/error_recovery/issue_39958_03: RuntimeError
+general/error_recovery/issue_39958_04: RuntimeError
+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/incomplete_field_formal_parameter: RuntimeError
@@ -141,11 +167,13 @@
 instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError # Expected
 nnbd/inheritance_from_opt_in: TypeCheckError
 nnbd/issue41180: RuntimeError # Strong mode runtime checking fails due to mixed strong mode.
-nnbd/issue41210a/issue41210: TypeCheckError
-nnbd/issue41210b: TypeCheckError
+nnbd/issue41567: TypeCheckError
 nnbd/messages_with_types_opt_in: TypeCheckError
 nnbd/messages_with_types_opt_out: TypeCheckError
 nnbd/never_opt_out: TypeCheckError
+nnbd/nullable_object_access: TypeCheckError
+nnbd/nullable_receiver: TypeCheckError
+nnbd/potentially_nullable_access: TypeCheckError
 rasta/abstract_constructor: RuntimeError
 rasta/bad_constructor_redirection: RuntimeError
 rasta/bad_continue: RuntimeError
@@ -212,6 +240,7 @@
 regress/issue_39035.crash: RuntimeError
 regress/issue_39091_1: RuntimeError
 regress/issue_39091_2: RuntimeError
+regress/utf_16_le_content.crash: RuntimeError
 runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
 runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 9e2e2bb..7ea610f 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -6,1636 +6,240 @@
 # the round trip for Kernel textual serialization where the initial binary
 # Kernel files are produced by compiling Dart code via Fasta.
 
-agnostic/identical: TextSerializationFailure
-agnostic/map: TextSerializationFailure
-agnostic/set: TextSerializationFailure
-expression/eval: TextSerializationFailure # Was: Pass
-expression/main: TextSerializationFailure # Was: Pass
-extensions/ambiguous: TextSerializationFailure
-extensions/annotations: TextSerializationFailure
-extensions/builtin_identifiers: TextSerializationFailure
 extensions/call_methods: TypeCheckError
-extensions/check_bounds: TextSerializationFailure
-extensions/compounds: TextSerializationFailure
-extensions/conflict_with_object: TextSerializationFailure
-extensions/conflicts: TextSerializationFailure
-extensions/default_values: TextSerializationFailure
-extensions/deferred_explicit_access: TextSerializationFailure
-extensions/deferred_import_hidden: TextSerializationFailure
-extensions/direct_instance_access: TextSerializationFailure
-extensions/direct_static_access: TextSerializationFailure
-extensions/dynamic_invoke: TextSerializationFailure
-extensions/explicit_extension_access: TextSerializationFailure
-extensions/explicit_extension_inference: TextSerializationFailure
-extensions/explicit_generic_extension_access: TextSerializationFailure
-extensions/explicit_invalid_access: TextSerializationFailure
-extensions/explicit_this: TextSerializationFailure
-extensions/export_twice: TextSerializationFailure
-extensions/extension_call: TextSerializationFailure
-extensions/extension_constructor: TextSerializationFailure
-extensions/extension_field_with_type_parameter_usage: TextSerializationFailure
-extensions/extension_methods: TextSerializationFailure
-extensions/extension_setter: TextSerializationFailure
 extensions/extension_setter_error: TypeCheckError
-extensions/generic_function_in_generic_extension: TextSerializationFailure
-extensions/getter_setter_conflict: TextSerializationFailure
-extensions/if_null: TextSerializationFailure
-extensions/implicit_extension_inference: TextSerializationFailure
-extensions/implicit_this: TextSerializationFailure
-extensions/import_via_prefix: TextSerializationFailure
-extensions/index: TextSerializationFailure
-extensions/instance_access: TextSerializationFailure
-extensions/instance_access_of_static: TextSerializationFailure
-extensions/instance_members: TextSerializationFailure
-extensions/instance_tearoff: TextSerializationFailure
-extensions/internal_resolution: TextSerializationFailure
-extensions/invalid_explicit_access: TextSerializationFailure
-extensions/invalid_explicit_static_access: TextSerializationFailure
-extensions/issue38600: TextSerializationFailure
-extensions/issue38712: TextSerializationFailure
-extensions/issue38713: TextSerializationFailure
-extensions/issue38745: TextSerializationFailure
-extensions/issue38750: TextSerializationFailure
-extensions/issue38755: TextSerializationFailure
-extensions/issue38915: TextSerializationFailure
-extensions/issue39527: TextSerializationFailure
-extensions/issue39889: TextSerializationFailure
-extensions/issue39938/issue39938: TextSerializationFailure
-extensions/issue40596: TextSerializationFailure
+extensions/instance_access_of_static: RuntimeError
+extensions/invalid_explicit_access: RuntimeError
 extensions/issue40713: TypeCheckError
-extensions/issue40816: TextSerializationFailure
-extensions/missing_toplevel: TextSerializationFailure
-extensions/nested_on_types: TextSerializationFailure
-extensions/null_aware: TextSerializationFailure
-extensions/on_function_type: TextSerializationFailure
-extensions/on_type_inference: TextSerializationFailure
-extensions/on_type_variable_inference: TextSerializationFailure
-extensions/operators: TextSerializationFailure
-extensions/other_kinds: TextSerializationFailure
-extensions/private_members: TextSerializationFailure
-extensions/static_access: TextSerializationFailure
-extensions/static_access_of_instance: TextSerializationFailure
-extensions/tear_offs: TextSerializationFailure
-extensions/type_variables: TextSerializationFailure
-extensions/unnamed_extensions: TextSerializationFailure
-extensions/use_this: TextSerializationFailure
-general/DeltaBlue: TextSerializationFailure # Was: Pass
+extensions/static_access_of_instance: RuntimeError
 general/abstract_members: TypeCheckError
-general/abstract_overrides_concrete_with_no_such_method: TextSerializationFailure
-general/accessors: TextSerializationFailure # Was: RuntimeError
-general/all_variances: TextSerializationFailure
-general/ambiguous_exports: TextSerializationFailure # Was: RuntimeError # Expected, this file exports two main methods.
-general/annotation_eof: TextSerializationFailure # Was: Pass
-general/annotation_on_enum_values: TextSerializationFailure # Was: Pass
-general/annotation_top: TextSerializationFailure # Was: Pass
-general/annotation_typedef_formals: TextSerializationFailure # Was: Pass
-general/annotation_typedef_formals_resolution: TextSerializationFailure # Was: Pass
-general/annotation_variable_declaration: TextSerializationFailure # Was: Pass
-general/argument: TextSerializationFailure # Was: Pass
-general/argument_mismatch: TextSerializationFailure
-general/arithmetic: TextSerializationFailure # Was: Pass
-general/arrow_function: TextSerializationFailure # Was: Pass
-general/assign_to_initializing_formal: TextSerializationFailure
-general/async_function: TextSerializationFailure # Was: Pass
-general/async_nested: TextSerializationFailure # Was: Pass
-general/await: TextSerializationFailure # Was: Pass
-general/await_complex: TextSerializationFailure
-general/await_in_cascade: TextSerializationFailure
-general/await_in_non_async: TextSerializationFailure
-general/bad_setter_abstract: TextSerializationFailure # Was: Pass
-general/bad_store: TextSerializationFailure # Was: Pass
-general/bad_type_variable_uses_in_supertypes: TextSerializationFailure
-general/bounds_check_depends_on_inference: TextSerializationFailure # Was: Pass
+general/accessors: RuntimeError
+general/ambiguous_exports: RuntimeError
+general/await_in_non_async: RuntimeError
 general/bug21938: TypeCheckError
 general/bug30695: TypeCheckError
-general/bug31124: TextSerializationFailure # Was: RuntimeError # Test has no main method (and we shouldn't add one).
-general/bug32414a: TextSerializationFailure # Was: Pass
-general/bug32414b: TextSerializationFailure # Was: Pass
-general/bug32426: TextSerializationFailure # Was: Pass
-general/bug32629: TextSerializationFailure
-general/bug32866: TextSerializationFailure # Was: Pass
-general/bug33099: TextSerializationFailure # Was: Pass
-general/bug33196: TextSerializationFailure # Was: Pass
-general/bug33206: TextSerializationFailure # Was: Pass
-general/bug33298: TextSerializationFailure # Was: Pass
-general/bug34511: TextSerializationFailure # Was: Pass
-general/bug35470: TextSerializationFailure # Was: Pass
-general/bug37476: TextSerializationFailure
+general/bug31124: RuntimeError
 general/call: TypeCheckError
 general/candidate_found: TypeCheckError
-general/cascade: TextSerializationFailure # Was: RuntimeError
-general/casts: TextSerializationFailure # Was: Pass
-general/check_deferred_allocation: TextSerializationFailure # Was: Pass
-general/check_deferred_as_check: TextSerializationFailure # Was: Pass
-general/check_deferred_before_args2: TextSerializationFailure # Was: Pass
-general/check_deferred_before_args: TextSerializationFailure # Was: Pass
-general/check_deferred_before_call: TextSerializationFailure # Was: Pass
-general/check_deferred_before_write: TextSerializationFailure # Was: Pass
-general/check_deferred_is_check: TextSerializationFailure # Was: Pass
-general/check_deferred_read: TextSerializationFailure # Was: Pass
-general/check_deferred_read_static_field: TextSerializationFailure # Was: Pass
-general/check_deferred_read_type: TextSerializationFailure # Was: Pass
-general/check_deferred_static_method_call: TextSerializationFailure # Was: Pass
-general/check_deferred_type_declaration: TextSerializationFailure # Was: Pass
-general/circularity-via-initializing-formal: TextSerializationFailure # Was: Pass
-general/classes: TextSerializationFailure # Was: Pass
-general/clone_function_type: TextSerializationFailure # Was: Pass
-general/closure: TextSerializationFailure # Was: Pass
-general/co19_language_metadata_syntax_t04: TextSerializationFailure # Was: Pass
-general/complex_class_hierarchy: TextSerializationFailure
-general/compound_binary_implicit_as: TextSerializationFailure
-general/const_redirect_to_nonconst: TextSerializationFailure
-general/constructor_const_inference: TextSerializationFailure # Was: Pass
-general/constructor_cycle: TextSerializationFailure # Was: Pass
-general/constructor_function_types: TextSerializationFailure # Was: Pass
-general/constructor_initializer_invalid: TextSerializationFailure # Was: RuntimeError # Fails execution after recovery
-general/continue_inference_after_error: TextSerializationFailure # Was: Pass
-general/continue_inference_after_error_lib: TextSerializationFailure # Was: Pass
-general/control_flow_collection: TextSerializationFailure
-general/control_flow_collection_inference: TextSerializationFailure
-general/covariant_generic: TextSerializationFailure # Was: RuntimeError
-general/covariant_parameter_in_superclass_of_mixin_application: TextSerializationFailure
-general/cycles: TextSerializationFailure # Was: Pass
-general/default_values: TextSerializationFailure # Was: Pass
-general/deferred_lib: TextSerializationFailure # Was: Pass
-general/deferred_type_annotation: TextSerializationFailure # Was: Pass
-general/demote_closure_types: TextSerializationFailure
-general/duplicated_bad_prefix: TextSerializationFailure # Was: Pass
-general/duplicated_bad_prefix_lib1: TextSerializationFailure # Was: Pass
-general/duplicated_bad_prefix_lib2: TextSerializationFailure # Was: Pass
+general/cascade: RuntimeError
+general/constructor_initializer_invalid: RuntimeError
+general/covariant_generic: RuntimeError
 general/duplicated_declarations: TypeCheckError
-general/duplicated_declarations_lib: TextSerializationFailure # Was: Pass
-general/duplicated_declarations_part: TextSerializationFailure # Was: Pass
-general/duplicated_field_initializer: TextSerializationFailure # Was: RuntimeError
-general/duplicated_named_args_3: TextSerializationFailure # Was: Pass
-general/dynamic_and_void: TextSerializationFailure
-general/error_locations/error_location_01: TextSerializationFailure
-general/error_locations/error_location_02: TextSerializationFailure
-general/error_locations/error_location_03: TextSerializationFailure
-general/error_locations/error_location_04: TextSerializationFailure
-general/error_locations/error_location_05: TextSerializationFailure
-general/error_locations/error_location_06: TextSerializationFailure
-general/escape: TextSerializationFailure # Was: Pass
-general/export_main: TextSerializationFailure # Was: Pass
-general/export_test: TextSerializationFailure # Was: Pass
-general/expressions: TextSerializationFailure # Was: RuntimeError
-general/extend_with_type_variable: TextSerializationFailure
-general/external: TextSerializationFailure # Was: Pass
-general/external_import: TextSerializationFailure # Was: RuntimeError # The native extension to import doesn't exist. This is ok.
-general/fallthrough: TextSerializationFailure
-general/ffi_sample: TextSerializationFailure
-general/fibonacci: TextSerializationFailure # Was: Pass
-general/for_in_scope: TextSerializationFailure # Was: Pass
-general/for_in_without_declaration: TextSerializationFailure
-general/forwarding_stub_for_operator: TextSerializationFailure
-general/function_in_field: TextSerializationFailure # Was: Pass
-general/function_type_assignments: TextSerializationFailure # Was: Pass
-general/function_type_default_value: TextSerializationFailure
-general/function_type_is_check: TextSerializationFailure # Was: Pass
-general/function_type_recovery: TextSerializationFailure # Was: Pass
-general/functions: TextSerializationFailure # Was: Pass
-general/future_or_test: TextSerializationFailure # Was: Pass
-general/generic_function_type_in_message: TextSerializationFailure
-general/getter_call: TextSerializationFailure
-general/having_part_with_part_and_annotation: TextSerializationFailure
-general/having_part_with_parts_and_annotation: TextSerializationFailure
-general/hello: TextSerializationFailure # Was: Pass
-general/if_null_in_cascade: TextSerializationFailure
-general/if_null_in_list_literal: TextSerializationFailure
-general/if_null_in_set_literal: TextSerializationFailure
-general/ignore_function: TextSerializationFailure
-general/illegal_named_function_expression: TextSerializationFailure # Was: Pass
-general/illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
-general/implicit_const_with_static_fields: TextSerializationFailure # Was: Pass
-general/implicit_new: TextSerializationFailure # Was: Pass
-general/implicit_scope_test: TextSerializationFailure # Was: Pass
-general/implicit_this: TextSerializationFailure # Was: Pass
-general/import_conflicting_getters: TextSerializationFailure
-general/import_conflicting_setters: TextSerializationFailure
-general/import_conflicting_type_member: TextSerializationFailure
-general/import_conflicting_types: TextSerializationFailure
-general/incomplete_field_formal_parameter: TextSerializationFailure # Was: RuntimeError
+general/duplicated_field_initializer: RuntimeError
+general/error_locations/error_location_01: RuntimeError
+general/error_locations/error_location_02: RuntimeError
+general/error_locations/error_location_03: RuntimeError
+general/error_locations/error_location_05: RuntimeError
+general/error_locations/error_location_06: RuntimeError
+general/error_recovery/await_not_in_async: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_general.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_get.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_return_type.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_set.crash: RuntimeError
+general/error_recovery/constructor_recovery_get: RuntimeError
+general/error_recovery/constructor_recovery_ok: RuntimeError
+general/error_recovery/constructor_recovery_operator.crash: RuntimeError
+general/error_recovery/constructor_recovery_return_type: RuntimeError
+general/error_recovery/constructor_recovery_set: RuntimeError
+general/error_recovery/empty_await_for: RuntimeError
+general/error_recovery/empty_for: RuntimeError
+general/error_recovery/issue_38415.crash: RuntimeError
+general/error_recovery/issue_39024.crash: RuntimeError
+general/error_recovery/issue_39026.crash: RuntimeError
+general/error_recovery/issue_39026_prime.crash: RuntimeError
+general/error_recovery/issue_39033.crash: RuntimeError
+general/error_recovery/issue_39058.crash: RuntimeError
+general/error_recovery/issue_39058_prime.crash: RuntimeError
+general/error_recovery/issue_39202.crash: RuntimeError
+general/error_recovery/issue_39230.crash: RuntimeError
+general/error_recovery/issue_39958_01: RuntimeError
+general/error_recovery/issue_39958_02: RuntimeError
+general/error_recovery/issue_39958_03: RuntimeError
+general/error_recovery/issue_39958_04: RuntimeError
+general/error_recovery/yield_not_in_generator: RuntimeError
+general/expressions: RuntimeError
+general/external_import: RuntimeError
+general/incomplete_field_formal_parameter: RuntimeError
 general/infer_field_from_multiple: TypeCheckError
-general/infer_field_type: TextSerializationFailure
-general/infer_fixed_generic_return_type: TextSerializationFailure
-general/infer_map_literal_with_closure: TextSerializationFailure
-general/inherit_function: TextSerializationFailure
-general/interface_conflict: TextSerializationFailure
-general/interface_contravariant_from_class: TextSerializationFailure
-general/interface_covariantImpl_from_class: TextSerializationFailure
-general/interface_covariantInterface_from_class: TextSerializationFailure
-general/invalid_assignment: TextSerializationFailure # Was: Pass
-general/invalid_cast: TextSerializationFailure # Was: Pass
-general/invalid_operator2: TextSerializationFailure
 general/invalid_operator: TypeCheckError
-general/invalid_type: TextSerializationFailure
-general/invocations: TextSerializationFailure # Was: RuntimeError
-general/issue129167943: TextSerializationFailure
-general/issue34515: TextSerializationFailure
-general/issue34899: TextSerializationFailure
-general/issue35875: TextSerializationFailure
-general/issue37027: TextSerializationFailure
-general/issue37381: TextSerializationFailure
-general/issue37776: TextSerializationFailure
-general/issue38812: TextSerializationFailure
-general/issue38938: TextSerializationFailure
-general/issue38943: TextSerializationFailure
-general/issue38944: TextSerializationFailure
-general/issue38961: TextSerializationFailure
-general/issue39344: TextSerializationFailure
-general/issue39421: TextSerializationFailure
-general/issue39817: TextSerializationFailure
-general/issue40242: TextSerializationFailure
-general/issue40428: TextSerializationFailure
-general/issue40662: TextSerializationFailure
-general/issue40744: TextSerializationFailure
-general/issue41070: TextSerializationFailure
+general/invocations: RuntimeError
+general/issue37776: RuntimeError
+general/issue38938: RuntimeError
+general/issue38944: RuntimeError
+general/issue38961: RuntimeError
 general/issue41210a: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
-general/literals: TextSerializationFailure # Was: Pass
-general/local_generic_function: TextSerializationFailure # Was: Pass
-general/long_chain_of_typedefs: TextSerializationFailure
-general/magic_const: TextSerializationFailure # Was: Pass
-general/many_errors: TextSerializationFailure
-general/map: TextSerializationFailure # Was: Pass
-general/metadata_enum: TextSerializationFailure # Was: Pass
-general/metadata_named_mixin_application: TextSerializationFailure # Was: Pass
-general/micro: TextSerializationFailure # Was: RuntimeError
-general/minimum_int: TextSerializationFailure # Was: Pass
-general/missing_constructor: TextSerializationFailure # Was: Pass
-general/missing_toplevel: TextSerializationFailure
-general/mixin: TextSerializationFailure # Was: Pass
-general/mixin_application_inferred_parameter_type: TextSerializationFailure
-general/mixin_application_override: ExpectationFileMismatch
+general/micro: RuntimeError
 general/mixin_application_override: TypeCheckError
-general/mixin_conflicts: TextSerializationFailure
-general/mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
-general/mixin_covariant: TextSerializationFailure
-general/mixin_inherited_setter_for_mixed_in_field: TextSerializationFailure # Was: Pass
-general/mixin_interface_conflict: TextSerializationFailure
-general/mixin_super_repeated: TextSerializationFailure # Was: Pass
-general/mixin_with_static_member: TextSerializationFailure
-general/named_function_scope: TextSerializationFailure # Was: Pass
-general/named_parameters: TextSerializationFailure # Was: Pass
-general/native_as_name: TextSerializationFailure # Was: Pass
-general/nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
-general/nested_property_set: TextSerializationFailure
-general/nested_variable_set: TextSerializationFailure
-general/nested_variance: TextSerializationFailure
-general/no_such_method_private_setter: TextSerializationFailure # Was: Pass
-general/no_such_method_private_setter_lib: TextSerializationFailure # Was: Pass
-general/non_covariant_checks: TextSerializationFailure
-general/null_aware: TextSerializationFailure # Was: Pass
-general/null_aware_for_in: TextSerializationFailure
-general/null_aware_postfix: TextSerializationFailure
-general/null_aware_spread: TextSerializationFailure
-general/operator_method_not_found: TextSerializationFailure
-general/operators: TextSerializationFailure # Was: Pass
+general/mixin_constructors_with_default_values: RuntimeError
+general/operator_method_not_found: RuntimeError
 general/optional: TypeCheckError
-general/override: TextSerializationFailure # Was: Pass
 general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
 general/override_check_accessor_basic: TypeCheckError # Issue #31620
 general/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
 general/override_check_after_inference: TypeCheckError # Issue #31620
 general/override_check_basic: TypeCheckError # Issue #31620
-general/override_check_generic_method_f_bounded: TextSerializationFailure # Was: Pass
-general/override_check_two_substitutions: TextSerializationFailure # Was: Pass
 general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
-general/override_inference_for_getters_and_setters: TextSerializationFailure
-general/override_inference_for_setters: TextSerializationFailure
-general/override_inference_named_parameters_ordering: TextSerializationFailure
 general/override_setter_with_field: TypeCheckError
-general/part_as_entry_point: TextSerializationFailure # Was: Pass
-general/part_as_entry_point_lib: TextSerializationFailure # Was: Pass
-general/part_not_part_of: TextSerializationFailure
-general/part_not_part_of_same_named_library: TextSerializationFailure
-general/part_part_of_different_unnamed_library: TextSerializationFailure
-general/part_part_of_differently_named_library: TextSerializationFailure
-general/platform: TextSerializationFailure
-general/platform_invalid_uris/main: TextSerializationFailure
-general/prefer_baseclass: TextSerializationFailure # Was: Pass
-general/private_method_tearoff: TextSerializationFailure # Was: Pass
-general/private_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general/promoted_access: TextSerializationFailure
-general/promoted_null_aware_access: TextSerializationFailure
-general/public_method_tearoff: TextSerializationFailure # Was: Pass
-general/public_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general/qualified: TextSerializationFailure # Was: Pass
-general/qualified_lib: TextSerializationFailure # Was: Pass
-general/qualified_part: TextSerializationFailure # Was: Pass
-general/redirecting_constructor: TextSerializationFailure # Was: Pass
-general/redirecting_factory: TextSerializationFailure # Was: Pass
-general/redirecting_factory_chain_test: TextSerializationFailure # Was: Pass
-general/redirecting_factory_const_inference: TextSerializationFailure # Was: Pass
-general/redirecting_factory_metadata: TextSerializationFailure # Was: Pass
-general/redirecting_factory_simple_test: TextSerializationFailure # Was: Pass
-general/redirecting_factory_typeargs_test: TextSerializationFailure # Was: Pass
-general/redirecting_factory_typeparam_test: TextSerializationFailure # Was: Pass
-general/redirecting_factory_typeparambounds_test: TextSerializationFailure # Was: Pass
-general/redirecting_initializer_arguments_assignable_test: TextSerializationFailure # Was: Pass
-general/redirecting_initializer_arguments_test: TextSerializationFailure # Was: Pass
-general/redirection_chain_type_arguments: TextSerializationFailure # Was: Pass
-general/redirection_chain_type_arguments_subst: TextSerializationFailure # Was: Pass
-general/redirection_type_arguments: TextSerializationFailure # Was: Pass
-general/reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
-general/return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
-general/sdk_diagnostic: TextSerializationFailure
-general/spread_collection: TextSerializationFailure # Should be fixed as part of implementing spread collection support
-general/spread_collection_inference: TextSerializationFailure # Should be fixed as part of implementing spread collection support
+general/reject_generic_function_types_in_bounds: RuntimeError
+general/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
 general/statements: Crash
-general/static_setter: TextSerializationFailure # Was: Pass
-general/store_load: TextSerializationFailure # Was: Pass
-general/stringliteral: TextSerializationFailure # Was: Pass
-general/super_call: TextSerializationFailure # Was: Pass
-general/super_nsm: TextSerializationFailure # Was: Pass
-general/tabs: TextSerializationFailure # Was: Pass
-general/this_field_call: TextSerializationFailure
-general/three_typedefs_loop: TextSerializationFailure
-general/top_level_accessors: TextSerializationFailure # Was: Pass
-general/top_level_accessors_part: TextSerializationFailure # Was: Pass
-general/top_level_library_method: TextSerializationFailure # Was: Pass
-general/type_literal_as_metadata: TextSerializationFailure
-general/type_of_null: TextSerializationFailure
-general/type_parameter_type_named_int: TextSerializationFailure
-general/type_parameter_usage_in_static_method_in_class: TextSerializationFailure
-general/type_parameter_usage_in_static_method_in_extension: TextSerializationFailure
-general/type_parameters_on_dynamic: TextSerializationFailure
-general/type_parameters_on_void: TextSerializationFailure
-general/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
+general/type_parameter_type_named_int: RuntimeError
+general/type_variable_as_super: RuntimeError
 general/type_variable_bound_access: TypeCheckError
-general/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
-general/type_variable_uses: TextSerializationFailure # Was: Pass
-general/typedef: TextSerializationFailure # Was: Pass
-general/undefined: TextSerializationFailure # Was: Pass
-general/undefined_getter_in_compound_assignment: TextSerializationFailure # Was: Pass
-general/uninitialized_fields: TextSerializationFailure # Was: Pass
 general/unsound_promotion: TypeCheckError
-general/unused_methods: TextSerializationFailure # Was: Pass
-general/var_as_type_name: TextSerializationFailure # Was: Pass
-general/vm_type_ops: TextSerializationFailure
-general/void_methods: TextSerializationFailure
-general/warn_unresolved_sends: TextSerializationFailure
-general/well_boundness_checks_in_outline: TextSerializationFailure
-general/with_dependencies/abstract_members_from_dill/main: TextSerializationFailure
-general/with_dependencies/extension_from_dill/extension_from_dill: TextSerializationFailure
-general/with_dependencies/variance_from_dill/variance_from_dill: TextSerializationFailure
-general_nnbd_opt_out/DeltaBlue: TextSerializationFailure # Was: Pass
+general/void_methods: RuntimeError
 general_nnbd_opt_out/abstract_members: TypeCheckError
-general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method: TextSerializationFailure
-general_nnbd_opt_out/accessors: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/all_variances: TextSerializationFailure
-general_nnbd_opt_out/ambiguous_exports: TextSerializationFailure # Was: RuntimeError # Expected, this file exports two main methods.
-general_nnbd_opt_out/annotation_eof: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/annotation_on_enum_values: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/annotation_top: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/annotation_typedef_formals: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/annotation_typedef_formals_resolution: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/annotation_variable_declaration: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/argument: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/argument_mismatch: TextSerializationFailure
-general_nnbd_opt_out/arithmetic: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/arrow_function: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/assign_to_initializing_formal: TextSerializationFailure
-general_nnbd_opt_out/async_function: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/async_nested: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/await: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/await_complex: TextSerializationFailure
-general_nnbd_opt_out/await_in_cascade: TextSerializationFailure
-general_nnbd_opt_out/await_in_non_async: TextSerializationFailure
-general_nnbd_opt_out/bad_setter_abstract: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bad_store: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bad_type_variable_uses_in_supertypes: TextSerializationFailure
-general_nnbd_opt_out/bounds_check_depends_on_inference: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/accessors: RuntimeError
+general_nnbd_opt_out/ambiguous_exports: RuntimeError
+general_nnbd_opt_out/await_in_non_async: RuntimeError
 general_nnbd_opt_out/bug21938: TypeCheckError
 general_nnbd_opt_out/bug30695: TypeCheckError
-general_nnbd_opt_out/bug31124: TextSerializationFailure # Was: RuntimeError # Test has no main method (and we shouldn't add one).
-general_nnbd_opt_out/bug32414a: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug32414b: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug32426: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug32629: TextSerializationFailure
-general_nnbd_opt_out/bug32866: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33099: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33196: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33206: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33298: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug34511: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug35470: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug37476: TextSerializationFailure
+general_nnbd_opt_out/bug31124: RuntimeError
 general_nnbd_opt_out/call: TypeCheckError
 general_nnbd_opt_out/candidate_found: TypeCheckError
-general_nnbd_opt_out/cascade: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/casts: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_allocation: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_as_check: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_before_args2: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_before_args: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_before_call: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_before_write: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_is_check: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_read: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_read_static_field: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_read_type: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_static_method_call: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_type_declaration: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/circularity-via-initializing-formal: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/classes: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/clone_function_type: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/closure: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/co19_language_metadata_syntax_t04: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/complex_class_hierarchy: TextSerializationFailure
-general_nnbd_opt_out/compound_binary_implicit_as: TextSerializationFailure
-general_nnbd_opt_out/const_redirect_to_nonconst: TextSerializationFailure
-general_nnbd_opt_out/constructor_const_inference: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/constructor_cycle: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/constructor_function_types: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/constructor_initializer_invalid: TextSerializationFailure # Was: RuntimeError # Fails execution after recovery
-general_nnbd_opt_out/continue_inference_after_error: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/continue_inference_after_error_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/control_flow_collection: TextSerializationFailure
-general_nnbd_opt_out/control_flow_collection_inference: TextSerializationFailure
-general_nnbd_opt_out/covariant_generic: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application: TextSerializationFailure
-general_nnbd_opt_out/cycles: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/default_values: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/deferred_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/deferred_type_annotation: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_bad_prefix: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_bad_prefix_lib1: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_bad_prefix_lib2: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/cascade: RuntimeError
+general_nnbd_opt_out/constructor_initializer_invalid: RuntimeError
+general_nnbd_opt_out/covariant_generic: RuntimeError
 general_nnbd_opt_out/duplicated_declarations: TypeCheckError
-general_nnbd_opt_out/duplicated_declarations_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_declarations_part: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_field_initializer: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/duplicated_named_args_3: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/dynamic_and_void: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_01: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_02: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_03: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_04: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_05: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_06: TextSerializationFailure
-general_nnbd_opt_out/escape: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/export_main: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/export_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/expressions: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/extend_with_type_variable: TextSerializationFailure
-general_nnbd_opt_out/external: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/external_import: TextSerializationFailure # Was: RuntimeError # The native extension to import doesn't exist. This is ok.
-general_nnbd_opt_out/fallthrough: TextSerializationFailure
-general_nnbd_opt_out/ffi_sample: TextSerializationFailure
-general_nnbd_opt_out/fibonacci: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/for_in_scope: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/for_in_without_declaration: TextSerializationFailure
-general_nnbd_opt_out/forwarding_stub_for_operator: TextSerializationFailure
-general_nnbd_opt_out/function_in_field: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/function_type_assignments: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/function_type_default_value: TextSerializationFailure
-general_nnbd_opt_out/function_type_is_check: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/function_type_recovery: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/functions: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/future_or_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/generic_function_type_in_message: TextSerializationFailure
-general_nnbd_opt_out/having_part_with_part_and_annotation: TextSerializationFailure
-general_nnbd_opt_out/having_part_with_parts_and_annotation: TextSerializationFailure
-general_nnbd_opt_out/hello: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/if_null_in_cascade: TextSerializationFailure
-general_nnbd_opt_out/if_null_in_list_literal: TextSerializationFailure
-general_nnbd_opt_out/if_null_in_set_literal: TextSerializationFailure
-general_nnbd_opt_out/ignore_function: TextSerializationFailure
-general_nnbd_opt_out/illegal_named_function_expression: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/implicit_const_with_static_fields: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/implicit_new: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/implicit_scope_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/implicit_this: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/import_conflicting_getters: TextSerializationFailure
-general_nnbd_opt_out/import_conflicting_setters: TextSerializationFailure
-general_nnbd_opt_out/import_conflicting_type_member: TextSerializationFailure
-general_nnbd_opt_out/import_conflicting_types: TextSerializationFailure
-general_nnbd_opt_out/incomplete_field_formal_parameter: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/interface_contravariant_from_class: TextSerializationFailure
-general_nnbd_opt_out/interface_covariantImpl_from_class: TextSerializationFailure
-general_nnbd_opt_out/interface_covariantInterface_from_class: TextSerializationFailure
-general_nnbd_opt_out/invalid_assignment: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/invalid_cast: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/invalid_type: TextSerializationFailure
-general_nnbd_opt_out/invocations: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/issue129167943: TextSerializationFailure
-general_nnbd_opt_out/issue34515: TextSerializationFailure
-general_nnbd_opt_out/issue34899: TextSerializationFailure
-general_nnbd_opt_out/issue35875: TextSerializationFailure
-general_nnbd_opt_out/issue37027: TextSerializationFailure
-general_nnbd_opt_out/issue37381: TextSerializationFailure
-general_nnbd_opt_out/issue37776: TextSerializationFailure
-general_nnbd_opt_out/issue38812: TextSerializationFailure
-general_nnbd_opt_out/issue38938: TextSerializationFailure
-general_nnbd_opt_out/issue38943: TextSerializationFailure
-general_nnbd_opt_out/issue38944: TextSerializationFailure
-general_nnbd_opt_out/issue38961: TextSerializationFailure
-general_nnbd_opt_out/issue39344: TextSerializationFailure
-general_nnbd_opt_out/issue39421: TextSerializationFailure
-general_nnbd_opt_out/issue39817: TextSerializationFailure
-general_nnbd_opt_out/literals: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/local_generic_function: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/long_chain_of_typedefs: TextSerializationFailure
-general_nnbd_opt_out/magic_const: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/many_errors: TextSerializationFailure
-general_nnbd_opt_out/map: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/metadata_enum: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/metadata_named_mixin_application: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/micro: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/minimum_int: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/missing_constructor: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/missing_toplevel: TextSerializationFailure
-general_nnbd_opt_out/mixin: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_application_inferred_parameter_type: TextSerializationFailure
-general_nnbd_opt_out/mixin_application_override: ExpectationFileMismatch
+general_nnbd_opt_out/duplicated_field_initializer: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_01: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_02: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_03: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_05: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_06: RuntimeError
+general_nnbd_opt_out/expressions: RuntimeError
+general_nnbd_opt_out/external_import: RuntimeError
+general_nnbd_opt_out/incomplete_field_formal_parameter: RuntimeError
+general_nnbd_opt_out/invocations: RuntimeError
+general_nnbd_opt_out/issue37776: RuntimeError
+general_nnbd_opt_out/issue38938: RuntimeError
+general_nnbd_opt_out/issue38944: RuntimeError
+general_nnbd_opt_out/issue38961: RuntimeError
+general_nnbd_opt_out/micro: RuntimeError
 general_nnbd_opt_out/mixin_application_override: TypeCheckError
-general_nnbd_opt_out/mixin_conflicts: TextSerializationFailure
-general_nnbd_opt_out/mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_super_repeated: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_with_static_member: TextSerializationFailure
-general_nnbd_opt_out/named_function_scope: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/named_parameters: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/native_as_name: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/nested_property_set: TextSerializationFailure
-general_nnbd_opt_out/nested_variable_set: TextSerializationFailure
-general_nnbd_opt_out/nested_variance: TextSerializationFailure
-general_nnbd_opt_out/no_such_method_private_setter: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/no_such_method_private_setter_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/non_covariant_checks: TextSerializationFailure
-general_nnbd_opt_out/null_aware: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/null_aware_for_in: TextSerializationFailure
-general_nnbd_opt_out/null_aware_postfix: TextSerializationFailure
-general_nnbd_opt_out/null_aware_spread: TextSerializationFailure
-general_nnbd_opt_out/operator_method_not_found: TextSerializationFailure
-general_nnbd_opt_out/operators: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/mixin_constructors_with_default_values: RuntimeError
+general_nnbd_opt_out/operator_method_not_found: RuntimeError
 general_nnbd_opt_out/optional: TypeCheckError
-general_nnbd_opt_out/override: TextSerializationFailure # Was: Pass
 general_nnbd_opt_out/override_check_accessor_after_inference: TypeCheckError # Issue #31620
 general_nnbd_opt_out/override_check_accessor_basic: TypeCheckError # Issue #31620
 general_nnbd_opt_out/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
 general_nnbd_opt_out/override_check_after_inference: TypeCheckError # Issue #31620
 general_nnbd_opt_out/override_check_basic: TypeCheckError # Issue #31620
-general_nnbd_opt_out/override_check_generic_method_f_bounded: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/override_check_two_substitutions: TextSerializationFailure # Was: Pass
 general_nnbd_opt_out/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
-general_nnbd_opt_out/override_inference_for_setters: TextSerializationFailure
-general_nnbd_opt_out/override_inference_named_parameters_ordering: TextSerializationFailure
 general_nnbd_opt_out/override_setter_with_field: TypeCheckError
-general_nnbd_opt_out/part_as_entry_point: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/part_as_entry_point_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/part_not_part_of: TextSerializationFailure
-general_nnbd_opt_out/part_not_part_of_same_named_library: TextSerializationFailure
-general_nnbd_opt_out/part_part_of_different_unnamed_library: TextSerializationFailure
-general_nnbd_opt_out/part_part_of_differently_named_library: TextSerializationFailure
-general_nnbd_opt_out/platform: TextSerializationFailure
-general_nnbd_opt_out/prefer_baseclass: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/private_method_tearoff: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/private_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/promoted_access: TextSerializationFailure
-general_nnbd_opt_out/public_method_tearoff: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/public_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/qualified: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/qualified_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/qualified_part: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_constructor: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_chain_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_const_inference: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_metadata: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_simple_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_typeargs_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_typeparam_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_typeparambounds_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_initializer_arguments_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirection_chain_type_arguments: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirection_chain_type_arguments_subst: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirection_type_arguments: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
-general_nnbd_opt_out/return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/sdk_diagnostic: TextSerializationFailure
-general_nnbd_opt_out/spread_collection: TextSerializationFailure # Should be fixed as part of implementing spread collection support
-general_nnbd_opt_out/spread_collection_inference: TextSerializationFailure # Should be fixed as part of implementing spread collection support
+general_nnbd_opt_out/reject_generic_function_types_in_bounds: RuntimeError
+general_nnbd_opt_out/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
 general_nnbd_opt_out/statements: Crash
-general_nnbd_opt_out/static_setter: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/store_load: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/stringliteral: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/super_call: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/super_nsm: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/tabs: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/three_typedefs_loop: TextSerializationFailure
-general_nnbd_opt_out/top_level_accessors: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/top_level_accessors_part: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/top_level_library_method: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/type_literal_as_metadata: TextSerializationFailure
-general_nnbd_opt_out/type_of_null: TextSerializationFailure
-general_nnbd_opt_out/type_parameter_type_named_int: TextSerializationFailure
-general_nnbd_opt_out/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
+general_nnbd_opt_out/type_parameter_type_named_int: RuntimeError
+general_nnbd_opt_out/type_variable_as_super: RuntimeError
 general_nnbd_opt_out/type_variable_bound_access: TypeCheckError
-general_nnbd_opt_out/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/type_variable_uses: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/typedef: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/undefined: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/undefined_getter_in_compound_assignment: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/uninitialized_fields: TextSerializationFailure # Was: Pass
 general_nnbd_opt_out/unsound_promotion: TypeCheckError
-general_nnbd_opt_out/unused_methods: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/var_as_type_name: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/void_methods: TextSerializationFailure
-general_nnbd_opt_out/warn_unresolved_sends: TextSerializationFailure
-implicit_getter_calls/getter_call: TextSerializationFailure
-implicit_getter_calls/this_field_call: TextSerializationFailure
-inference/abstract_class_instantiation: TextSerializationFailure
-inference/assert: TextSerializationFailure # Was: Pass
-inference/assert_initializer: TextSerializationFailure # Was: Pass
-inference/assign_local: TextSerializationFailure # Was: Pass
-inference/async_await: TextSerializationFailure # Was: Pass
-inference/async_closure_return_type_flatten: TextSerializationFailure # Was: Pass
-inference/async_closure_return_type_future: TextSerializationFailure # Was: Pass
-inference/async_closure_return_type_future_or: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_all_returns_are_futures: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_all_returns_are_values: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_mix_of_values_and_futures: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_basic: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_basic_void: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_async: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_async_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_sync: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_sync_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_lub: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_nested_lambdas: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_no_return: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_returns: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_sync_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_void_context: TextSerializationFailure # Was: Pass
-inference/bottom: TextSerializationFailure # Was: Pass
-inference/bottom_in_closure: TextSerializationFailure # Was: Pass
-inference/bug30251: TextSerializationFailure # Was: Pass
-inference/bug30620: TextSerializationFailure # Was: Pass
-inference/bug30620_b: TextSerializationFailure # Was: Pass
-inference/bug30620_c: TextSerializationFailure # Was: Pass
-inference/bug30620_d: TextSerializationFailure # Was: Pass
-inference/bug30624: TextSerializationFailure # Was: Pass
-inference/bug31132: TextSerializationFailure # Was: Pass
-inference/bug31133: TextSerializationFailure # Was: Pass
-inference/bug31436: TextSerializationFailure # Was: Pass
-inference/bug32291: TextSerializationFailure # Was: Pass
-inference/bug33324: TextSerializationFailure # Was: Pass
-inference/call_corner_cases: TextSerializationFailure # Was: Pass
-inference/callable_generic_class: TextSerializationFailure # Was: Pass
-inference/circular_method_inference: TextSerializationFailure # Was: Pass
-inference/circular_reference_via_closures: TextSerializationFailure # Was: Pass
-inference/circular_reference_via_closures_initializer_types: TextSerializationFailure # Was: Pass
-inference/closure_param_null_to_object: TextSerializationFailure # Was: Pass
-inference/coerce_bottom_and_null_types: TextSerializationFailure # Was: Pass
-inference/complex_predecrement: TextSerializationFailure # Was: Pass
-inference/conditional_lub: TextSerializationFailure # Was: Pass
-inference/conditional_upwards_inference: TextSerializationFailure # Was: Pass
-inference/conflicting_fields: TextSerializationFailure
-inference/conflicts_can_happen2: TextSerializationFailure
-inference/conflicts_can_happen: TextSerializationFailure
-inference/constructors_downwards_with_constraint: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/void_methods: RuntimeError
 inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError
-inference/constructors_infer_from_arguments_const: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_const_with_upper_bound: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_downwards_from_constructor: TextSerializationFailure
-inference/constructors_infer_from_arguments_factory: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_factory_calls_constructor: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_named: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_named_factory: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_redirecting: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_redirecting_factory: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_redirecting_factory_to_factory: TextSerializationFailure # Was: Pass
-inference/constructors_inference_f_bounded: TextSerializationFailure # Was: Pass
-inference/constructors_reverse_type_parameters: TextSerializationFailure # Was: Pass
-inference/constructors_too_many_positional_arguments: TextSerializationFailure
 inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError
-inference/dont_infer_field_type_when_initializer_is_null: TextSerializationFailure # Was: Pass
-inference/dont_infer_type_on_dynamic: TextSerializationFailure # Was: Pass
-inference/dont_infer_type_when_initializer_is_null: TextSerializationFailure # Was: Pass
-inference/downward_inference_fixes_no_upwards_errors: TextSerializationFailure # Was: Pass
-inference/downward_inference_miscellaneous: TextSerializationFailure # Was: Pass
-inference/downwards_context_from_inferred_field_type: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_class_members: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_for_loop_variable: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_locals: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_locals_referring_to_locals: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_parameter: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_parameter_local: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_type_variable: TextSerializationFailure
-inference/downwards_inference_annotations_type_variable_local: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_typedef: TextSerializationFailure # Was: Pass
-inference/downwards_inference_assignment_statements: TextSerializationFailure # Was: Pass
-inference/downwards_inference_async_await: TextSerializationFailure # Was: Pass
-inference/downwards_inference_for_each: TextSerializationFailure # Was: Pass
-inference/downwards_inference_initializing_formal_default_formal: TextSerializationFailure # Was: Pass
-inference/downwards_inference_inside_top_level: TextSerializationFailure # Was: Pass
-inference/downwards_inference_inside_top_level_2: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_constructor_arguments_infer_downwards: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_function_arguments_infer_downwards: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_function_expressions: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_function_of_t_using_the_t: TextSerializationFailure
-inference/downwards_inference_on_generic_constructor_arguments_empty_list: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_generic_constructor_arguments_infer_downwards: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_generic_function_expressions: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_instance_creations_infer_downwards: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_list_literals_infer_downwards: TextSerializationFailure # Was: RuntimeError
-inference/downwards_inference_on_list_literals_infer_if_value_types_match_context: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_map_literals: TextSerializationFailure # Was: Pass
-inference/downwards_inference_yield_yield_star: TextSerializationFailure # Was: Pass
-inference/dynamic_methods: TextSerializationFailure # Was: Pass
-inference/field_initializer_context_explicit: TextSerializationFailure # Was: Pass
-inference/field_initializer_context_implicit: TextSerializationFailure # Was: Pass
-inference/field_initializer_context_this: TextSerializationFailure # Was: Pass
-inference/field_initializer_parameter: TextSerializationFailure # Was: Pass
-inference/field_refers_to_static_getter: TextSerializationFailure # Was: Pass
-inference/field_refers_to_top_level_getter: TextSerializationFailure # Was: Pass
-inference/for_each_downcast_iterable: TextSerializationFailure # Was: Pass
-inference/for_in_loop_promotion: TextSerializationFailure # Was: Pass
-inference/for_loop_empty_condition: TextSerializationFailure # Was: Pass
-inference/for_loop_initializer_expression: TextSerializationFailure # Was: Pass
-inference/for_loop_promotion: TextSerializationFailure # Was: Pass
-inference/future_or_subtyping: TextSerializationFailure # Was: Pass
-inference/future_then: TextSerializationFailure # Was: Pass
-inference/future_then_2: TextSerializationFailure # Was: Pass
-inference/future_then_3: TextSerializationFailure # Was: Pass
-inference/future_then_4: TextSerializationFailure # Was: Pass
-inference/future_then_5: TextSerializationFailure # Was: Pass
-inference/future_then_6: TextSerializationFailure # Was: Pass
-inference/future_then_conditional: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_2: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_3: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_4: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_5: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_6: TextSerializationFailure # Was: Pass
-inference/future_then_downwards_method_target: TextSerializationFailure # Was: Pass
-inference/future_then_explicit_future: TextSerializationFailure
-inference/future_then_ifNull: TextSerializationFailure # Was: Pass
-inference/future_then_upwards: TextSerializationFailure # Was: RuntimeError
-inference/future_then_upwards_2: TextSerializationFailure # Was: RuntimeError
-inference/future_then_upwards_3: TextSerializationFailure # Was: Pass
-inference/future_then_upwards_from_block: TextSerializationFailure # Was: Pass
-inference/future_union_async_conditional: TextSerializationFailure # Was: Pass
-inference/future_union_async_conditional_2: TextSerializationFailure # Was: Pass
-inference/future_union_downwards: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_2: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_3: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_4: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_generic_method_with_future_return: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_generic_method_with_generic_return: TextSerializationFailure # Was: Pass
-inference/future_union_upwards_generic_methods: TextSerializationFailure # Was: Pass
-inference/generator_closure: TextSerializationFailure # Was: Pass
-inference/generic_functions_return_typedef: TextSerializationFailure
-inference/generic_methods_basic_downward_inference: TextSerializationFailure # Was: Pass
+inference/downwards_inference_for_each: RuntimeError
+inference/downwards_inference_on_list_literals_infer_downwards: RuntimeError
+inference/future_then_upwards: RuntimeError
+inference/future_then_upwards_2: RuntimeError
 inference/generic_methods_correctly_recognize_generic_upper_bound: TypeCheckError
-inference/generic_methods_dart_math_min_max: TextSerializationFailure # Was: Pass
 inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
-inference/generic_methods_downwards_inference_affects_arguments: TextSerializationFailure # Was: Pass
-inference/generic_methods_downwards_inference_fold: TextSerializationFailure # Was: Pass
 inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
-inference/generic_methods_infer_generic_function_parameter_type2: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_function_parameter_type: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_function_return_type: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_instantiation: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_method_type: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_js_builtin: TextSerializationFailure
-inference/generic_methods_inference_error: TextSerializationFailure # Was: Pass
-inference/generic_methods_iterable_and_future: TextSerializationFailure # Was: Pass
-inference/generic_methods_nested_generic_instantiation: TextSerializationFailure # Was: Pass
-inference/generic_methods_uses_greatest_lower_bound: TextSerializationFailure # Was: Pass
-inference/greatest_closure_multiple_params: TextSerializationFailure # Was: Pass
-inference/inconsistent_overrides: TextSerializationFailure
-inference/index_assign_operator_return_type: TextSerializationFailure # Was: Pass
-inference/index_assign_operator_return_type_2: TextSerializationFailure # Was: Pass
-inference/infer_accessor_from_later_inferred_field: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_implicit_this: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_implicit_this_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_index_full: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_index_super: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_index_this: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_local: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_local_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_full: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_null_aware: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_null_aware_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_super: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_super_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_ref: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_static: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
-inference/infer_binary_custom: TextSerializationFailure # Was: Pass
-inference/infer_binary_double_double: TextSerializationFailure # Was: Pass
-inference/infer_binary_double_int: TextSerializationFailure # Was: Pass
-inference/infer_binary_int_double: TextSerializationFailure # Was: Pass
-inference/infer_binary_int_int: TextSerializationFailure # Was: Pass
-inference/infer_conditional: TextSerializationFailure # Was: Pass
-inference/infer_consts_transitively_2: TextSerializationFailure # Was: Pass
-inference/infer_consts_transitively_2_a: TextSerializationFailure # Was: Pass
-inference/infer_consts_transitively_2_b: TextSerializationFailure # Was: Pass
-inference/infer_consts_transitively_b: TextSerializationFailure # Was: Pass
-inference/infer_correctly_on_multiple_variables_declared_together: TextSerializationFailure # Was: Pass
-inference/infer_field_from_later_inferred_field: TextSerializationFailure # Was: Pass
-inference/infer_field_from_later_inferred_getter: TextSerializationFailure # Was: Pass
-inference/infer_field_from_later_inferred_setter: TextSerializationFailure # Was: Pass
-inference/infer_field_override_multiple: TextSerializationFailure
-inference/infer_field_override_of_override: TextSerializationFailure # Was: Pass
-inference/infer_field_override_with_substitution: TextSerializationFailure # Was: Pass
-inference/infer_field_overrides_getter: TextSerializationFailure # Was: Pass
-inference/infer_field_overrides_setter: TextSerializationFailure # Was: Pass
-inference/infer_field_static: TextSerializationFailure # Was: Pass
-inference/infer_final_field_getter_and_setter: TextSerializationFailure # Was: Pass
-inference/infer_final_field_getter_only: TextSerializationFailure # Was: Pass
-inference/infer_final_field_setter_only: TextSerializationFailure # Was: Pass
-inference/infer_from_complex_expressions_if_outer_most_value_is_precise: TextSerializationFailure
-inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2: TextSerializationFailure # Was: Pass
-inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on2: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_non_cycle_imports_with_flag2: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_non_cycle_imports_with_flag2_a: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_non_cycle_imports_with_flag: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_non_cycle_imports_with_flag_a: TextSerializationFailure # Was: Pass
-inference/infer_generic_field_types: TextSerializationFailure
-inference/infer_generic_method_type_named: TextSerializationFailure # Was: Pass
-inference/infer_generic_method_type_positional2: TextSerializationFailure # Was: Pass
-inference/infer_generic_method_type_positional: TextSerializationFailure # Was: Pass
-inference/infer_generic_method_type_required: TextSerializationFailure # Was: Pass
-inference/infer_getter_cross_to_setter: TextSerializationFailure # Was: Pass
-inference/infer_getter_from_later_inferred_getter: TextSerializationFailure # Was: Pass
-inference/infer_list_literal_nested_in_map_literal: TextSerializationFailure # Was: Pass
-inference/infer_local_function_referenced_before_declaration: TextSerializationFailure # Was: Pass
-inference/infer_local_function_return_type: TextSerializationFailure # Was: Pass
-inference/infer_method_function_typed: TextSerializationFailure # Was: Pass
-inference/infer_method_missing_params: ExpectationFileMismatch
 inference/infer_method_missing_params: TypeCheckError
-inference/infer_parameter_type_setter_from_field: TextSerializationFailure # Was: Pass
-inference/infer_parameter_type_setter_from_setter: TextSerializationFailure # Was: Pass
-inference/infer_prefix_expression: TextSerializationFailure # Was: Pass
-inference/infer_prefix_expression_custom: TextSerializationFailure # Was: Pass
-inference/infer_rethrow: TextSerializationFailure # Was: Pass
-inference/infer_return_of_statement_lambda: TextSerializationFailure # Was: Pass
-inference/infer_return_type_for_static_setter: TextSerializationFailure # Was: Pass
-inference/infer_setter_cross_to_getter: TextSerializationFailure # Was: Pass
-inference/infer_setter_from_later_inferred_setter: TextSerializationFailure # Was: Pass
-inference/infer_setter_function_typed: TextSerializationFailure # Was: Pass
-inference/infer_setter_return_type_only: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively2: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively3: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively3_a: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively_2_a: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively_a: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively_b: TextSerializationFailure # Was: Pass
-inference/infer_statics_with_method_invocations: TextSerializationFailure # Was: Pass
-inference/infer_statics_with_method_invocations_a: TextSerializationFailure # Was: Pass
-inference/infer_throw: TextSerializationFailure # Was: Pass
-inference/infer_throw_downwards: TextSerializationFailure # Was: Pass
-inference/infer_type_on_overridden_fields2: TextSerializationFailure # Was: Pass
-inference/infer_type_on_overridden_fields4: TextSerializationFailure # Was: Pass
-inference/infer_type_on_var2: TextSerializationFailure # Was: Pass
-inference/infer_type_on_var: TextSerializationFailure # Was: Pass
-inference/infer_type_on_var_from_field: TextSerializationFailure # Was: Pass
-inference/infer_type_on_var_from_top_level: TextSerializationFailure # Was: Pass
-inference/infer_type_regardless_of_declaration_order_or_cycles: TextSerializationFailure # Was: RuntimeError
-inference/infer_type_regardless_of_declaration_order_or_cycles_b: TextSerializationFailure # Was: Pass
-inference/infer_typed_map_literal: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_3: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_4: TextSerializationFailure # Was: RuntimeError
-inference/infer_types_on_generic_instantiations_5: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_in_library_cycle: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_in_library_cycle_a: TextSerializationFailure # Was: Pass
+inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError
+inference/infer_types_on_generic_instantiations_4: RuntimeError
 inference/infer_types_on_generic_instantiations_infer: TypeCheckError
-inference/infer_types_on_loop_indices_for_each_loop: TextSerializationFailure # Was: Pass
-inference/infer_types_on_loop_indices_for_each_loop_async: TextSerializationFailure # Was: Pass
-inference/infer_types_on_loop_indices_for_loop_with_inference: TextSerializationFailure # Was: Pass
-inference/infer_use_of_void_local: TextSerializationFailure # Was: Pass
-inference/infer_variable_void: TextSerializationFailure # Was: Pass
-inference/inferred_initializing_formal_checks_default_value: TextSerializationFailure # Was: Pass
-inference/inferred_nonstatic_field_depends_on_static_field_complex: TextSerializationFailure # Was: Pass
-inference/inferred_nonstatic_field_depends_on_top_level_var_simple: TextSerializationFailure # Was: Pass
-inference/inferred_type_block_closure_no_args_no_return: TextSerializationFailure # Was: Pass
-inference/inferred_type_block_closure_no_args_no_return_void_context: TextSerializationFailure # Was: Pass
-inference/inferred_type_cascade: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_binary_op: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_binary_op_via_interface: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_index_op: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_index_op_via_interface: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_unary_op: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_unary_op_via_interface: TextSerializationFailure # Was: Pass
-inference/inferred_type_extract_method_tear_off: TextSerializationFailure # Was: Pass
-inference/inferred_type_extract_method_tear_off_via_interface: TextSerializationFailure # Was: Pass
-inference/inferred_type_from_top_level_executable_tear_off: TextSerializationFailure # Was: Pass
-inference/inferred_type_invoke_method: TextSerializationFailure # Was: Pass
-inference/inferred_type_invoke_method_via_interface: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_enum: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_enum_values: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_typedef: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_typedef_parameterized: TextSerializationFailure # Was: Pass
-inference/inferred_type_uses_synthetic_function_type: TextSerializationFailure # Was: Pass
-inference/inferred_type_uses_synthetic_function_type_function_typed_param: TextSerializationFailure # Was: Pass
-inference/inferred_type_uses_synthetic_function_type_named_param: TextSerializationFailure # Was: Pass
-inference/inferred_type_uses_synthetic_function_type_positional_param: TextSerializationFailure # Was: Pass
-inference/inferred_type_uses_synthetic_function_type_required_param: TextSerializationFailure # Was: Pass
-inference/inferred_type_via_closure_multiple_levels_of_nesting: TextSerializationFailure # Was: Pass
-inference/inferred_type_via_closure_type_depends_on_args: TextSerializationFailure # Was: Pass
-inference/inferred_type_via_closure_type_independent_of_args_field: TextSerializationFailure # Was: Pass
-inference/inferred_type_via_closure_type_independent_of_args_top_level: TextSerializationFailure # Was: Pass
-inference/inheritance_does_not_imply_circularity: TextSerializationFailure # Was: Pass
-inference/instance_creation_downwards: TextSerializationFailure # Was: Pass
-inference/instantiate_tearoff: TextSerializationFailure # Was: Pass
-inference/instantiate_tearoff_after_contravariance_check: TextSerializationFailure # Was: Pass
 inference/instantiate_tearoff_of_call: TypeCheckError # Issue #31746
-inference/instantiate_to_bounds_generic2_has_bound_defined_after: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_generic2_has_bound_defined_before: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_generic2_no_bound: TextSerializationFailure # Was: Pass
 inference/instantiate_to_bounds_generic_has_bound_defined_after transform: RuntimeError
-inference/instantiate_to_bounds_generic_has_bound_defined_after: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_generic_has_bound_defined_before: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_invoke_constructor_no_bound: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_invoke_constructor_type_args_exact: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_not_generic: TextSerializationFailure # Was: Pass
-inference/int_upwards_local: TextSerializationFailure # Was: Pass
-inference/lambda_does_not_have_propagated_type_hint: TextSerializationFailure # Was: Pass
-inference/lambda_return_type: TextSerializationFailure # Was: Pass
-inference/lambda_void_context: TextSerializationFailure # Was: Pass
-inference/list_literal_typed: TextSerializationFailure # Was: Pass
-inference/list_literals: TextSerializationFailure # Was: Pass
-inference/list_literals_can_infer_null_bottom: TextSerializationFailure # Was: Pass
-inference/list_literals_top_level: TextSerializationFailure # Was: Pass
-inference/local_constructor_from_arguments: TextSerializationFailure # Was: Pass
-inference/local_reference_upwards_local: TextSerializationFailure # Was: Pass
-inference/local_return_and_yield: TextSerializationFailure # Was: Pass
-inference/logical_or_promotion: TextSerializationFailure # Was: Pass
-inference/map_literals: TextSerializationFailure # Was: Pass
-inference/map_literals_can_infer_null: TextSerializationFailure # Was: Pass
-inference/map_literals_top_level: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_instance_method: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_instance_method_identifier_sequence: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_static_method: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_top_level_function: TextSerializationFailure # Was: Pass
-inference/mixin_inference_instantiate_to_bounds_1: TextSerializationFailure # Was: Pass
-inference/mixin_inference_instantiate_to_bounds_2: TextSerializationFailure # Was: Pass
-inference/mixin_inference_instantiate_to_bounds_3: TextSerializationFailure # Was: Pass
-inference/mixin_inference_multiple_constraints: TextSerializationFailure # Was: Pass
-inference/mixin_inference_non_trivial_constraints: TextSerializationFailure # Was: Pass
-inference/mixin_inference_outwards_1: TextSerializationFailure # Was: Pass
-inference/mixin_inference_outwards_2: TextSerializationFailure # Was: Pass
 inference/mixin_inference_outwards_3: TypeCheckError
 inference/mixin_inference_outwards_4: TypeCheckError
 inference/mixin_inference_unification_1: TypeCheckError
 inference/mixin_inference_unification_2: TypeCheckError
-inference/no_error_when_declared_type_is_num_and_assigned_null: TextSerializationFailure # Was: Pass
-inference/non_const_invocation: TextSerializationFailure # Was: Pass
-inference/non_inferrable_getter_setter: TextSerializationFailure # Was: Pass
-inference/null_aware_method_invocation: TextSerializationFailure # Was: Pass
-inference/null_aware_property_get: TextSerializationFailure # Was: Pass
-inference/null_coalescing_operator: TextSerializationFailure # Was: Pass
-inference/null_coalescing_operator_2: TextSerializationFailure # Was: Pass
-inference/null_literal_should_not_infer_as_bottom: TextSerializationFailure # Was: Pass
-inference/overloaded_int_operators: TextSerializationFailure # Was: Pass
-inference/override_equals: TextSerializationFailure # Was: RuntimeError
-inference/override_inference_depends_on_field_inference: TextSerializationFailure
-inference/override_inference_with_type_parameters: TextSerializationFailure
-inference/parameter_defaults_downwards: TextSerializationFailure # Was: Pass
-inference/parameter_defaults_upwards: TextSerializationFailure # Was: Pass
-inference/promote_bounds: TextSerializationFailure # Was: Pass
-inference/promote_from_logical_rhs: TextSerializationFailure # Was: Pass
-inference/promotion_subtype_check: TextSerializationFailure # Was: Pass
-inference/propagate_inference_to_field_in_class: TextSerializationFailure # Was: Pass
-inference/propagate_inference_to_field_in_class_dynamic_warnings: TextSerializationFailure # Was: Pass
-inference/propagate_inference_transitively2: TextSerializationFailure # Was: Pass
-inference/propagate_inference_transitively: TextSerializationFailure # Was: Pass
-inference/propagate_variable_get: TextSerializationFailure # Was: Pass
-inference/property_get_toplevel: TextSerializationFailure # Was: Pass
-inference/property_set: TextSerializationFailure # Was: Pass
-inference/property_set_bad_setter: TextSerializationFailure # Was: Pass
-inference/recursive_generic_function: TextSerializationFailure # Was: Pass
-inference/reference_to_typedef: TextSerializationFailure # Was: Pass
-inference/refine_binary_expression_type_type_parameter_t_double: TextSerializationFailure # Was: Pass
-inference/refine_binary_expression_type_type_parameter_t_int: TextSerializationFailure # Was: Pass
-inference/refine_binary_expression_type_type_parameter_t_t: TextSerializationFailure # Was: Pass
-inference/setter_return_type: TextSerializationFailure # Was: Pass
-inference/simple_literal_bool: TextSerializationFailure # Was: Pass
-inference/simple_literal_double: TextSerializationFailure # Was: Pass
-inference/simple_literal_int: TextSerializationFailure # Was: Pass
-inference/simple_literal_null: TextSerializationFailure
-inference/static_method_tear_off: TextSerializationFailure # Was: Pass
-inference/string_literal: TextSerializationFailure # Was: Pass
-inference/subexpressions_of_explicitly_typed_fields: TextSerializationFailure # Was: Pass
-inference/super_index_set: TextSerializationFailure # Was: Pass
-inference/super_index_set_substitution: TextSerializationFailure # Was: Pass
-inference/super_initializer: TextSerializationFailure # Was: Pass
-inference/super_initializer_substitution: TextSerializationFailure # Was: Pass
-inference/super_method_invocation: TextSerializationFailure # Was: Pass
-inference/super_method_invocation_substitution: TextSerializationFailure # Was: Pass
-inference/super_property_get: TextSerializationFailure # Was: Pass
-inference/super_property_get_invoke_function_typed: TextSerializationFailure # Was: Pass
-inference/super_property_get_invoke_implicit_call: TextSerializationFailure # Was: Pass
-inference/super_property_get_substitution: TextSerializationFailure # Was: Pass
-inference/super_property_get_tearoff: TextSerializationFailure # Was: Pass
-inference/super_property_set_substitution: TextSerializationFailure # Was: Pass
-inference/switch_continue: TextSerializationFailure # Was: Pass
-inference/symbol_literal: TextSerializationFailure # Was: Pass
-inference/this_reference: TextSerializationFailure # Was: Pass
-inference/top_level_return_and_yield: TextSerializationFailure # Was: Pass
-inference/toplevel_inference_toplevel_var: TextSerializationFailure # Was: Pass
-inference/try_catch: TextSerializationFailure # Was: Pass
-inference/try_catch_finally: TextSerializationFailure # Was: Pass
-inference/try_catch_promotion: TextSerializationFailure # Was: Pass
-inference/try_finally: TextSerializationFailure # Was: Pass
-inference/type_cast: TextSerializationFailure # Was: Pass
-inference/type_promotion_ignores_local_functions: TextSerializationFailure # Was: Pass
-inference/type_promotion_not_and_not: TextSerializationFailure # Was: Pass
-inference/type_promotion_simple: TextSerializationFailure # Was: Pass
-inference/type_promotion_stopped_by_access_in_a_closure: TextSerializationFailure # Was: Pass
-inference/type_promotion_stopped_by_assignment_in_scope: TextSerializationFailure # Was: Pass
-inference/type_promotion_stopped_by_mutation_in_a_closure: TextSerializationFailure # Was: Pass
-inference/unresolved_super: TextSerializationFailure
-inference/unsafe_block_closure_inference_closure_call: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_constructor_call_explicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_constructor_call_implicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_constructor_call_no_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_explicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_implicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_no_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_in_list_dynamic: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_in_list_typed: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_in_list_untyped: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_in_map_dynamic: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_in_map_typed: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_in_map_untyped: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_explicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_implicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_no_type_param: TextSerializationFailure # Was: Pass
-inference/void_return_type_subtypes_dynamic: TextSerializationFailure # Was: Pass
-inference_new/const_invocation: TextSerializationFailure # Was: Pass
-inference_new/dependency_only_if_generic_method: TextSerializationFailure # Was: Pass
-inference_new/dependency_only_if_overloaded: TextSerializationFailure # Was: Pass
-inference_new/dependency_only_if_overloaded: TypeCheckError
-inference_new/do_loop: TextSerializationFailure # Was: Pass
-inference_new/downwards_inference_inside_top_level: TextSerializationFailure # Was: Pass
-inference_new/downwards_inference_inside_top_level_2: TextSerializationFailure # Was: Pass
-inference_new/field_inference_circularity: TextSerializationFailure # Was: Pass
-inference_new/for_each_identifier_downwards: TextSerializationFailure # Was: Pass
-inference_new/for_each_invalid_iterable: TextSerializationFailure # Was: Pass
-inference_new/for_each_outer_var_type: TextSerializationFailure # Was: Pass
-inference_new/indexed_assign_combiner: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_implicit_this: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_implicit_this_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index_full: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index_set_vs_get: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index_super: TextSerializationFailure # Was: Pass
+inference/override_equals: RuntimeError
 inference_new/infer_assign_to_index_super_upwards: TypeCheckError
-inference_new/infer_assign_to_index_this: TextSerializationFailure # Was: Pass
 inference_new/infer_assign_to_index_this_upwards: TypeCheckError
 inference_new/infer_assign_to_index_upwards: TypeCheckError
-inference_new/infer_assign_to_local: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_local_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property: TextSerializationFailure # Was: Pass
 inference_new/infer_assign_to_property_custom: TypeCheckError
-inference_new/infer_assign_to_property_full: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_null_aware: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_null_aware_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_super: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_super_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_ref: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_static: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_field_getter_setter_mismatch: TextSerializationFailure
-inference_new/infer_field_override_accessors: TextSerializationFailure
-inference_new/infer_field_override_getter_overrides_setter: TextSerializationFailure
-inference_new/infer_field_override_setter_overrides_getter: TextSerializationFailure # Was: Pass
-inference_new/infer_instance_accessor_ref: TextSerializationFailure # Was: Pass
-inference_new/infer_instance_field_ref: TextSerializationFailure # Was: Pass
-inference_new/infer_instance_field_ref_circular: TextSerializationFailure # Was: Pass
-inference_new/infer_logical: TextSerializationFailure # Was: Pass
-inference_new/infer_use_of_void: TextSerializationFailure # Was: Pass
 inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
-inference_new/list_literals_can_infer_null_top_level: TextSerializationFailure # Was: Pass
-inference_new/map_literals_can_infer_null_top_level: TextSerializationFailure # Was: Pass
-inference_new/multiple_interface_inheritance: TextSerializationFailure # Was: Pass
-inference_new/null_aware_property_get: TextSerializationFailure
-inference_new/property_assign_combiner: TextSerializationFailure # Was: Pass
-inference_new/property_get_toplevel: TextSerializationFailure # Was: Pass
-inference_new/static_assign_combiner: TextSerializationFailure # Was: Pass
-inference_new/strongly_connected_component: TextSerializationFailure # Was: Pass
-inference_new/strongly_connected_component: TypeCheckError
-inference_new/super_index_get: TextSerializationFailure # Was: Pass
-inference_new/super_index_get_substitution: TextSerializationFailure # Was: Pass
-inference_new/switch: TextSerializationFailure # Was: Pass
-inference_new/top_level_field_depends_on_multiple_inheritance: ExpectationFileMismatch
-inference_new/top_level_field_depends_on_multiple_inheritance: TextSerializationFailure # Was: Pass
-inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure # Was: Pass
-inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure # Was: Pass
-inference_new/void_return_type_subtypes_dynamic: TextSerializationFailure # Was: Pass
-inference_new/while_loop: TextSerializationFailure # Was: Pass
-instantiate_to_bound/all_steps: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_generic_classes_from_dill: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_super_bounded_type: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_super_bounded_type: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_mutual_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_mutual_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_mutual_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_mutual_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/generic_classes_from_dill: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_constrained_by_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_defaults_to_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_gives_input: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_super_bounded_rejected: TextSerializationFailure # Was: Pass
-instantiate_to_bound/instantiated_in_outline: TextSerializationFailure # Was: Pass
-instantiate_to_bound/literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/multiple_strongly_connected: TextSerializationFailure # Was: Pass
-instantiate_to_bound/mutual_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/mutual_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_bound_due_to_non_simple: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_bound_due_to_variables: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: TextSerializationFailure # Was: RuntimeError # Expected
-instantiate_to_bound/non_simple_class_typedef_cycle: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_co_inductive: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_co_inductive_for_each: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_co_inductive_no_dup: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_folded_regress: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_for_each: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_from_compiled: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_generic_function_in_bound_regress: TextSerializationFailure # Was: RuntimeError # Expected
-instantiate_to_bound/non_simple_many: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_many_libs_same_name_cycle: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_no_dup: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_suppress_consequence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_variables_from_same: TextSerializationFailure # Was: Pass
-instantiate_to_bound/omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/raw_in_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/super_bounded_in_bound: TextSerializationFailure
-instantiate_to_bound/super_bounded_type: TextSerializationFailure # Was: Pass
-instantiate_to_bound/supertypes: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_instantiated_in_outline: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_raw_in_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_super_bounded_type: TextSerializationFailure # Was: Pass
-late_lowering/compound: TextSerializationFailure
-late_lowering/definitely_assigned: TextSerializationFailure
-late_lowering/definitely_unassigned: TextSerializationFailure
-late_lowering/initializer_rewrite: TextSerializationFailure
-late_lowering/infer_late_field_type: TextSerializationFailure
-late_lowering/infer_from_late_variable: TextSerializationFailure
-late_lowering/injected_late_field_checks/main: TextSerializationFailure
-late_lowering/instance_field_with_initializer: TextSerializationFailure
-late_lowering/instance_field_without_initializer: TextSerializationFailure
-late_lowering/instance_final_field_without_initializer: TextSerializationFailure
-late_lowering/instance_nullable_field_with_initializer: TextSerializationFailure
-late_lowering/instance_nullable_field_without_initializer: TextSerializationFailure
-late_lowering/instance_nullable_final_field_without_initializer: TextSerializationFailure
-late_lowering/issue40093: TextSerializationFailure
-late_lowering/issue40373: TextSerializationFailure
-late_lowering/issue40373b: TextSerializationFailure
-late_lowering/issue40601: TextSerializationFailure
-late_lowering/issue40805: TextSerializationFailure
-late_lowering/late_field_inference: TextSerializationFailure
-late_lowering/late_field_with_initializer: TextSerializationFailure
-late_lowering/late_field_without_initializer: TextSerializationFailure
-late_lowering/late_final_field_with_initializer: TextSerializationFailure
-late_lowering/late_final_field_without_initializer: TextSerializationFailure
-late_lowering/late_final_local_with_initializer: TextSerializationFailure
-late_lowering/late_final_local_without_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_field_with_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_field_without_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_local_with_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_local_without_initializer: TextSerializationFailure
-late_lowering/late_future_or: TextSerializationFailure
-late_lowering/late_local_with_initializer: TextSerializationFailure
-late_lowering/late_local_without_initializer: TextSerializationFailure
-late_lowering/late_nullable_field_with_initializer: TextSerializationFailure
-late_lowering/late_nullable_field_without_initializer: TextSerializationFailure
-late_lowering/late_nullable_local_with_initializer: TextSerializationFailure
-late_lowering/late_nullable_local_without_initializer: TextSerializationFailure
-late_lowering/later: TextSerializationFailure
-late_lowering/override: TextSerializationFailure
-late_lowering/override_getter_setter: TextSerializationFailure
-late_lowering/return_late: TextSerializationFailure
-late_lowering/uninitialized_non_nullable_late_fields: TextSerializationFailure
-new_const_insertion/simple: TextSerializationFailure # Was: Pass
-nnbd/assign_type_variable: TextSerializationFailure
-nnbd/assignability: TextSerializationFailure
-nnbd/bounds_checks: TextSerializationFailure
-nnbd/call: TextSerializationFailure
-nnbd/constants: TextSerializationFailure
-nnbd/covariant_nnbd_top_merge: TextSerializationFailure
-nnbd/definite_assignment_and_completion: TextSerializationFailure
-nnbd/definitely_assigned: TextSerializationFailure
-nnbd/definitely_unassigned: TextSerializationFailure
-nnbd/definitely_unassigned_late_local_variables: TextSerializationFailure
-nnbd/demote_closure_types: TextSerializationFailure
-nnbd/export_from_opt_out: TextSerializationFailure
-nnbd/forbidden_supers: TextSerializationFailure
-nnbd/forin: TextSerializationFailure
-nnbd/from_agnostic/from_agnostic: TextSerializationFailure
-nnbd/function_types: TextSerializationFailure
-nnbd/future_or_variables: TextSerializationFailure
-nnbd/generic_override: TextSerializationFailure
-nnbd/infer_constraints_from_opt_in: TextSerializationFailure
-nnbd/infer_from_late_variable: TextSerializationFailure
-nnbd/infer_from_opt_in: TextSerializationFailure
-nnbd/infer_from_opt_out: TextSerializationFailure
-nnbd/infer_if_null: TextSerializationFailure
-nnbd/infer_in_legacy_from_opted_in: TextSerializationFailure
-nnbd/infer_method_types: TextSerializationFailure
+instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: RuntimeError
+instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError
 nnbd/inheritance_from_opt_in: TypeCheckError
-nnbd/inheritance_from_opt_out: TextSerializationFailure
-nnbd/injected_late_field_checks/main: TextSerializationFailure
-nnbd/intersection_types: TextSerializationFailure
-nnbd/issue39659: TextSerializationFailure
-nnbd/issue39822: TextSerializationFailure
-nnbd/issue40093: TextSerializationFailure
-nnbd/issue40134: TextSerializationFailure
-nnbd/issue40512/issue40512: TextSerializationFailure
-nnbd/issue40600: TextSerializationFailure
-nnbd/issue40601: TextSerializationFailure
-nnbd/issue40805: TextSerializationFailure
-nnbd/issue41102: TextSerializationFailure
-nnbd/issue41103: TextSerializationFailure
-nnbd/issue41156: TextSerializationFailure
-nnbd/issue41180: TextSerializationFailure
-nnbd/issue41210a/issue41210: TypeCheckError
-nnbd/issue41210b: TypeCheckError
-nnbd/issue_39286: TextSerializationFailure
-nnbd/issue_39286_2: TextSerializationFailure
-nnbd/late: TextSerializationFailure
-nnbd/later: TextSerializationFailure
-nnbd/lhs_of_if_null: TextSerializationFailure
-nnbd/list_constructor: TextSerializationFailure
-nnbd/literal_from_opt_in: TextSerializationFailure
-nnbd/load_library: TextSerializationFailure
-nnbd/member_inheritance_from_opt_in: TextSerializationFailure
-nnbd/member_inheritance_from_opt_out: TextSerializationFailure
+nnbd/issue41180: RuntimeError
+nnbd/issue41567: TypeCheckError
 nnbd/messages_with_types_opt_in: TypeCheckError
 nnbd/messages_with_types_opt_out: TypeCheckError
-nnbd/missing_required_named_parameter: TextSerializationFailure
-nnbd/mixed_mode_hierarchy_generic_methods: TextSerializationFailure
-nnbd/mixin_from_opt_in: TextSerializationFailure
-nnbd/mixin_from_opt_out: TextSerializationFailure
-nnbd/never_bound: TextSerializationFailure
 nnbd/never_opt_out: TypeCheckError
-nnbd/never_receiver: TextSerializationFailure
-nnbd/nnbd_opt_out_language_version: TextSerializationFailure
-nnbd/nnbd_opt_out_language_version_try_to_trick: TextSerializationFailure
-nnbd/no_null_shorting: TextSerializationFailure
-nnbd/no_null_shorting_explicit_extension: TextSerializationFailure
-nnbd/no_null_shorting_extension: TextSerializationFailure
-nnbd/non_nullable_field_initialization: TextSerializationFailure
-nnbd/non_nullable_optional: TextSerializationFailure
-nnbd/not_definitely_unassigned_late_local_variables: TextSerializationFailure
-nnbd/nsm_from_opt_in: TextSerializationFailure
-nnbd/null_access: TextSerializationFailure
-nnbd/null_aware_chain: TextSerializationFailure
-nnbd/null_check: TextSerializationFailure
-nnbd/null_check_context: TextSerializationFailure
-nnbd/null_shorting: TextSerializationFailure
-nnbd/null_shorting_cascade: TextSerializationFailure
-nnbd/null_shorting_explicit_extension: TextSerializationFailure
-nnbd/null_shorting_extension: TextSerializationFailure
-nnbd/null_shorting_index: TextSerializationFailure
-nnbd/nullable_access: TextSerializationFailure
-nnbd/nullable_null: TextSerializationFailure
-nnbd/nullable_param: TextSerializationFailure
-nnbd/nullable_receiver: TextSerializationFailure
-nnbd/nullable_rhs_of_typedef: TextSerializationFailure
-nnbd/opt_out: TextSerializationFailure
-nnbd/override_checks: TextSerializationFailure
-nnbd/platform_definite_assignment/main: TextSerializationFailure
-nnbd/platform_nonnullable_fields/main: TextSerializationFailure
-nnbd/platform_optional_parameters/main: TextSerializationFailure
-nnbd/potentially_non_nullable_field: TextSerializationFailure
-nnbd/regress_null_aware: TextSerializationFailure
-nnbd/required: TextSerializationFailure
-nnbd/required_name_override: TextSerializationFailure
-nnbd/required_named_parameter: TextSerializationFailure
-nnbd/return_late: TextSerializationFailure
-nnbd/return_null: TextSerializationFailure
-nnbd/shorting_stop: TextSerializationFailure
-nnbd/simple_never: TextSerializationFailure
-nnbd/sink_hierarchy: TextSerializationFailure
-nnbd/strictly_non_nullable_warnings: TextSerializationFailure
-nnbd/substitution_in_inference: TextSerializationFailure
-nnbd/switch_redesign_fall_over: TextSerializationFailure
-nnbd/switch_redesign_types: TextSerializationFailure
-nnbd/tearoff_from_nullable_receiver: TextSerializationFailure
-nnbd/type_parameter_types: TextSerializationFailure
-nnbd/uninitialized_non_nullable_late_fields: TextSerializationFailure
-no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_accessors_from_field_one_defined: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_accessors_from_field_with_substitution: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_interface_nsm_inherited: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_override_abstract_different_type: TextSerializationFailure
-no_such_method_forwarders/abstract_override_with_different_signature: TextSerializationFailure
-no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/default_argument_values: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/duplicated_abstract_method: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/forwarder_propagation: TextSerializationFailure
-no_such_method_forwarders/forwarders_not_assumed_from_mixin: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/interface_with_concrete: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/interface_with_nsm: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/multiple_abstract_setters: TextSerializationFailure
-no_such_method_forwarders/no_forwarders_for_abstract_classes: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/no_forwarders_for_abstract_classes_chain: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/nsm_inherited: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/nsm_mixed_in: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/private: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/private_module: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/private_same: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/same: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/setter_not_shadowed_by_method: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/subst_on_forwarder: TextSerializationFailure # Was: Pass
-rasta/abstract_constructor: TextSerializationFailure # Was: RuntimeError
-rasta/bad_constructor_redirection: TextSerializationFailure # Was: RuntimeError
-rasta/bad_continue: TextSerializationFailure # Was: RuntimeError
-rasta/bad_default_constructor: TextSerializationFailure
-rasta/bad_explicit_super_constructor: TextSerializationFailure # Was: RuntimeError
-rasta/bad_implicit_super_constructor: TextSerializationFailure # Was: RuntimeError
-rasta/bad_interpolation: TextSerializationFailure # Was: RuntimeError
-rasta/bad_redirection: TextSerializationFailure # Was: RuntimeError
-rasta/bad_setter_initializer: TextSerializationFailure # Was: RuntimeError
-rasta/bad_unicode: TextSerializationFailure # Was: Pass
-rasta/breaking_bad: TextSerializationFailure # Was: RuntimeError
-rasta/cascades: TextSerializationFailure # Was: Pass
-rasta/class_hierarchy: TextSerializationFailure # Was: RuntimeError
-rasta/class_member: TextSerializationFailure # Was: RuntimeError
-rasta/constant_get_and_invoke: TextSerializationFailure # Was: RuntimeError
-rasta/deferred_lib: TextSerializationFailure # Was: Pass
-rasta/deferred_load: TextSerializationFailure # Was: Pass
-rasta/duplicated_mixin: TextSerializationFailure # Was: RuntimeError # Expected, this file has no main method.
-rasta/enum: TextSerializationFailure # Was: Pass
-rasta/export: TextSerializationFailure # Was: RuntimeError # Expected, this file has no main method.
-rasta/external_factory_redirection: TextSerializationFailure # Was: Pass
-rasta/foo: TextSerializationFailure # Was: RuntimeError # Expected, this file has no main method.
-rasta/for_loop: TextSerializationFailure # Was: Pass
-rasta/generic_factory: TextSerializationFailure # Was: RuntimeError
-rasta/hello: TextSerializationFailure # Was: Pass
-rasta/import_export: TextSerializationFailure # Was: Pass
-rasta/issue_000001: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000002: TextSerializationFailure # Was: Pass
-rasta/issue_000004: TextSerializationFailure # Was: Pass
-rasta/issue_000006: TextSerializationFailure # Was: Pass
-rasta/issue_000007: TextSerializationFailure # Was: Pass
-rasta/issue_000008: TextSerializationFailure # Was: Pass
-rasta/issue_000011: TextSerializationFailure # Was: Pass
-rasta/issue_000012: TextSerializationFailure # Was: Pass
-rasta/issue_000025: TextSerializationFailure # Was: Pass
-rasta/issue_000026: TextSerializationFailure # Was: Pass
-rasta/issue_000031: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000032: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000033: TextSerializationFailure
-rasta/issue_000034: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000035: TextSerializationFailure # Was: Pass
-rasta/issue_000035a: TextSerializationFailure # Was: Pass
-rasta/issue_000036: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000039: TextSerializationFailure
-rasta/issue_000041: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000042: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000043: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000044: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000045: TextSerializationFailure
-rasta/issue_000046: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000047: TextSerializationFailure
-rasta/issue_000048: TextSerializationFailure # Was: Pass
-rasta/issue_000052: TextSerializationFailure # Was: Pass
-rasta/issue_000053: TextSerializationFailure # Was: Pass
-rasta/issue_000067: TextSerializationFailure # Was: Pass
-rasta/issue_000068: TextSerializationFailure # Was: Pass
-rasta/issue_000069: TextSerializationFailure # Was: Pass
-rasta/issue_000070: TextSerializationFailure # Was: Pass
-rasta/issue_000080: TextSerializationFailure # Was: Pass
-rasta/issue_000081: TextSerializationFailure # Was: RuntimeError
-rasta/malformed_const_constructor: TextSerializationFailure # Was: RuntimeError
-rasta/malformed_function: TextSerializationFailure # Was: RuntimeError
-rasta/malformed_function_type: TextSerializationFailure # Was: Pass
-rasta/mandatory_parameter_initializer: TextSerializationFailure
+nnbd/nullable_object_access: TypeCheckError
+nnbd/nullable_receiver: TypeCheckError
+nnbd/potentially_nullable_access: TypeCheckError
+rasta/abstract_constructor: RuntimeError
+rasta/bad_constructor_redirection: RuntimeError
+rasta/bad_continue: RuntimeError
+rasta/bad_default_constructor: RuntimeError
+rasta/bad_explicit_super_constructor: RuntimeError
+rasta/bad_implicit_super_constructor: RuntimeError
+rasta/bad_interpolation: RuntimeError
+rasta/bad_redirection: RuntimeError
+rasta/bad_setter_initializer: RuntimeError
+rasta/breaking_bad: RuntimeError
+rasta/class_hierarchy: RuntimeError
+rasta/class_member: RuntimeError
+rasta/constant_get_and_invoke: RuntimeError
+rasta/duplicated_mixin: RuntimeError
+rasta/export: RuntimeError
+rasta/foo: RuntimeError
+rasta/generic_factory: RuntimeError
+rasta/issue_000001: RuntimeError
+rasta/issue_000031: RuntimeError
+rasta/issue_000032: RuntimeError
+rasta/issue_000034: RuntimeError
+rasta/issue_000036: RuntimeError
+rasta/issue_000039: RuntimeError
+rasta/issue_000041: RuntimeError
+rasta/issue_000042: RuntimeError
+rasta/issue_000043: RuntimeError
+rasta/issue_000044: RuntimeError
+rasta/issue_000046: RuntimeError
+rasta/issue_000081: RuntimeError
+rasta/malformed_const_constructor: RuntimeError
+rasta/malformed_function: RuntimeError
 rasta/mixin_library: TypeCheckError
-rasta/native_is_illegal: TextSerializationFailure # Was: RuntimeError
-rasta/parser_error: TextSerializationFailure # Was: RuntimeError
-rasta/previsit_deferred: TextSerializationFailure # Was: Pass
-rasta/static: TextSerializationFailure # Was: RuntimeError
+rasta/native_is_illegal: RuntimeError
+rasta/parser_error: RuntimeError
+rasta/static: RuntimeError
 rasta/super: TypeCheckError
-rasta/super_initializer: TextSerializationFailure # Was: RuntimeError
+rasta/super_initializer: RuntimeError
 rasta/super_mixin: TypeCheckError
 rasta/super_operator: TypeCheckError
-rasta/supports_reflection: TextSerializationFailure # Was: Pass
-rasta/switch_execution_case_t02: TextSerializationFailure # Was: Pass
-rasta/switch_fall_through: TextSerializationFailure # Was: Pass
-rasta/this_invoke: TextSerializationFailure # Was: Pass
-rasta/try_label: TextSerializationFailure
-rasta/type_literals: TextSerializationFailure
-rasta/type_with_parse_error: TextSerializationFailure # Was: Pass
-rasta/typedef: TextSerializationFailure
-rasta/unresolved: TextSerializationFailure # Was: RuntimeError
-rasta/unresolved_constructor: TextSerializationFailure # Was: RuntimeError
-rasta/unresolved_for_in: TextSerializationFailure # Was: RuntimeError
+rasta/type_literals: RuntimeError
+rasta/typedef: RuntimeError
+rasta/unresolved: RuntimeError
+rasta/unresolved_constructor: RuntimeError
+rasta/unresolved_for_in: RuntimeError
 rasta/unresolved_recovery: TypeCheckError
-rasta/unsupported_platform_library: TextSerializationFailure
-regress/issue_29937: TextSerializationFailure # Was: Pass
-regress/issue_29940: TextSerializationFailure # Was: Pass
-regress/issue_29941: TextSerializationFailure # Was: Pass
-regress/issue_29942: TextSerializationFailure # Was: Pass
-regress/issue_29943: TextSerializationFailure
-regress/issue_29944: TextSerializationFailure # Was: Pass
-regress/issue_29945: TextSerializationFailure
-regress/issue_29975: TextSerializationFailure
-regress/issue_29976: TextSerializationFailure # Was:  RuntimeError # Tests runtime behavior of error recovery.
-regress/issue_29977: TextSerializationFailure
-regress/issue_29978: TextSerializationFailure # Was: Pass
-regress/issue_29979: TextSerializationFailure # Was: Pass
-regress/issue_29980: TextSerializationFailure
-regress/issue_29981: TextSerializationFailure # Was: Pass
-regress/issue_29982: TextSerializationFailure # Was: RuntimeError # Tests runtime behavior of error recovery.
-regress/issue_29983: TextSerializationFailure # Was: Pass
-regress/issue_29984: TextSerializationFailure # Was: Pass
-regress/issue_29985: TextSerializationFailure
-regress/issue_29986: TextSerializationFailure
-regress/issue_29987: TextSerializationFailure
-regress/issue_30834: TextSerializationFailure # Was: Pass
-regress/issue_30836: TextSerializationFailure # Was: RuntimeError # Issue 30836.
-regress/issue_30838: TextSerializationFailure # Was: Pass
-regress/issue_30981: TextSerializationFailure # Was: Pass
-regress/issue_30994: TextSerializationFailure
-regress/issue_31155: TextSerializationFailure # Was: Pass
-regress/issue_31157: TextSerializationFailure
-regress/issue_31171: TextSerializationFailure # Was: Pass
-regress/issue_31180: TextSerializationFailure
-regress/issue_31181: TextSerializationFailure # Was: Pass
-regress/issue_31183: TextSerializationFailure # Was: Pass
-regress/issue_31184: TextSerializationFailure # Was: Pass
-regress/issue_31185: TextSerializationFailure # Was: Pass
-regress/issue_31186: TextSerializationFailure
-regress/issue_31187: TextSerializationFailure
-regress/issue_31188: TextSerializationFailure
-regress/issue_31190: TextSerializationFailure # Was: Pass
-regress/issue_31192: TextSerializationFailure # Was: Pass
-regress/issue_31198: TextSerializationFailure # Was: Pass
-regress/issue_31213: TextSerializationFailure # Was: Pass
+regress/issue_29976: RuntimeError
+regress/issue_29982: RuntimeError
+regress/issue_30836: RuntimeError
 regress/issue_31299: TypeCheckError
-regress/issue_31766: TextSerializationFailure # Was: Pass
-regress/issue_31846: TextSerializationFailure # Was: Pass
-regress/issue_31996: TextSerializationFailure # Was: Pass
-regress/issue_32182: TextSerializationFailure # Was: Pass
-regress/issue_32196: TextSerializationFailure # Was: Pass
-regress/issue_32200: TextSerializationFailure # Was: RuntimeError # Invalid type.
-regress/issue_32660: TextSerializationFailure # Was: Pass
 regress/issue_32972: TypeCheckError
-regress/issue_33452: TextSerializationFailure # Was: RuntimeError # Test has an intentional error
-regress/issue_33672: TextSerializationFailure # Was: Pass
-regress/issue_34225: TextSerializationFailure # Was: RuntimeError
-regress/issue_34291: TextSerializationFailure # Was: Pass
-regress/issue_34291_lib: TextSerializationFailure # Was: Pass
-regress/issue_34403: TextSerializationFailure # Was: Pass
-regress/issue_34403_lib: TextSerializationFailure # Was: Pass
-regress/issue_34498: TextSerializationFailure # Was: Pass
-regress/issue_34498_lib: TextSerializationFailure # Was: Pass
-regress/issue_34563: TextSerializationFailure # Was: RuntimeError # Test execution after recovery
-regress/issue_34610: TextSerializationFailure # Was: Pass
-regress/issue_34614: TextSerializationFailure # Was: Pass
-regress/issue_34850: TextSerializationFailure # Was: Pass
-regress/issue_35151: TextSerializationFailure # Was: Pass
-regress/issue_35177: TextSerializationFailure # Was: RuntimeError
-regress/issue_35213: TextSerializationFailure # Was: Pass
-regress/issue_35220: TextSerializationFailure
-regress/issue_35258: TextSerializationFailure # Was: RuntimeError # Expected
-regress/issue_35259: TextSerializationFailure # Was: RuntimeError # Expected
-regress/issue_35260: TextSerializationFailure # Was: RuntimeError # Expected
-regress/issue_35266: TextSerializationFailure # Was: RuntimeError # Expected
-regress/issue_35900: TextSerializationFailure
-regress/issue_36400: TextSerializationFailure
-regress/issue_36647: TextSerializationFailure
-regress/issue_36647_2: TextSerializationFailure
-regress/issue_36669: TextSerializationFailure
-regress/issue_36793: TextSerializationFailure
-regress/issue_37285: TextSerializationFailure
-regress/issue_37681: TextSerializationFailure
-regress/issue_39035.crash: TextSerializationFailure
-regress/issue_39040: TextSerializationFailure
+regress/issue_33452: RuntimeError
+regress/issue_34225: RuntimeError
+regress/issue_34563: RuntimeError
+regress/issue_35177: RuntimeError
+regress/issue_35258: RuntimeError
+regress/issue_35259: RuntimeError
+regress/issue_35260: RuntimeError
+regress/issue_35266: RuntimeError
+regress/issue_36400: RuntimeError
+regress/issue_36647: RuntimeError
+regress/issue_36647_2: RuntimeError
+regress/issue_36669: RuntimeError
+regress/issue_37285: RuntimeError
+regress/issue_39035.crash: RuntimeError
 regress/issue_39091_1: RuntimeError
-regress/issue_39091_2: TextSerializationFailure
-regress/issue_39682: TextSerializationFailure
-runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
-runtime_checks/call_kinds_get: TextSerializationFailure # Was: Pass
-runtime_checks/call_kinds_set: TextSerializationFailure # Was: Pass
-runtime_checks/call_method_implicit_tear_off: TextSerializationFailure # Was: Pass
-runtime_checks/call_method_implicit_tear_off_future_or: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_field: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_method_type_parameter: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_return: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_return_null_aware: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_return_tear_off: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_getter: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_getter_return: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_getter_return_null_aware: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_method_type_parameter: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_complex: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface_mixin: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface_super: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface_super_mixin: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_tear_off: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_keyword: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_keyword_field: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_keyword_field_inherited_by_setter: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_keyword_setter: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_keyword_setter_inherited_by_field: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_setter: TextSerializationFailure # Was: Pass
-runtime_checks/dynamic_invocation: TextSerializationFailure # Was: Pass
-runtime_checks/dynamic_invocation_generic: TextSerializationFailure # Was: Pass
-runtime_checks/dynamic_invocation_of_getter: TextSerializationFailure # Was: Pass
-runtime_checks/field_forwarding_stub_generic_covariant: ExpectationFileMismatch
-runtime_checks/field_forwarding_stub_generic_covariant: TextSerializationFailure # Was: Pass
-runtime_checks/forwarding_stub_with_default_values: TextSerializationFailure # Was: Pass
-runtime_checks/forwarding_stub_with_non_covariant_param: TextSerializationFailure # Was: Pass
-runtime_checks/generic_covariance_inheritance_setter_field: TextSerializationFailure # Was: Pass
-runtime_checks/generic_vs_explicit_covariance: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_assert_initializer: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_assert_statement: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_constructor_initializer: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_do: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_for_condition: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_if: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_not: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_while: TextSerializationFailure # Was: Pass
-runtime_checks_new/abstract_override_becomes_forwarding_stub: ExpectationFileMismatch
-runtime_checks_new/abstract_override_becomes_forwarding_stub: TextSerializationFailure # Was: Pass
-runtime_checks_new/call_through_this: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_combiner: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: TextSerializationFailure # Was: RuntimeError
-runtime_checks_new/contravariant_getter_return_compound_assign: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_index_assign: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_index_get: TextSerializationFailure # Was: Pass
-runtime_checks_new/derived_class_typed: TextSerializationFailure # Was: Pass
-runtime_checks_new/field_forwarding_stub_abstract_generic_covariant: TextSerializationFailure # Was: Pass
-runtime_checks_new/field_forwarding_stub_explicit_covariant: ExpectationFileMismatch
-runtime_checks_new/field_forwarding_stub_explicit_covariant: TextSerializationFailure # Was: Pass
-runtime_checks_new/for_in_call_kinds: TextSerializationFailure # Was: Pass
-runtime_checks_new/generic_covariance_based_on_inference: TextSerializationFailure # Was: Pass
-runtime_checks_new/implicit_downcast_field: TextSerializationFailure # Was: Pass
-runtime_checks_new/mixin_forwarding_stub_field: ExpectationFileMismatch
+regress/issue_39091_2: RuntimeError
+regress/utf_16_le_content.crash: RuntimeError
+runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
-runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
-runtime_checks_new/mixin_forwarding_stub_setter: ExpectationFileMismatch
 runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
-runtime_checks_new/stub_checked_via_target: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_contravariant_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantImpl_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantImpl_from_interface: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantImpl_from_super: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantInterface_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariant_from_super: TextSerializationFailure # Was: Pass
-set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError
-top_level_variance_test: TextSerializationFailure
-triple_shift/invalid_operator: TextSerializationFailure
-unified_collections/mixed_entries: TextSerializationFailure
-unified_collections/string_concatenation: TextSerializationFailure
-variance/class_type_parameter_modifier: TextSerializationFailure
-variance/generic_covariance_sound_variance: TextSerializationFailure
-variance/mixin_type_parameter_modifier: TextSerializationFailure
-variance/unconstrained_inference: TextSerializationFailure
+set_literals/disambiguation_rule: RuntimeError
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
new file mode 100644
index 0000000..bbf696b
--- /dev/null
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -0,0 +1,208 @@
+# 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.
+
+# Status file for the textual_outline_suite.dart test suite. This is testing
+# the textual outline used for better incremental compilation.
+
+general/error_recovery/issue_38415.crash: EmptyOutput
+general/error_recovery/issue_39024.crash: EmptyOutput
+general/error_recovery/issue_39058.crash: EmptyOutput
+rasta/bad_interpolation: EmptyOutput
+rasta/issue_000035: EmptyOutput
+rasta/issue_000035a: EmptyOutput
+rasta/issue_000045: EmptyOutput
+regress/issue_29976: EmptyOutput
+regress/issue_29982: EmptyOutput
+regress/issue_29985: EmptyOutput
+regress/issue_35900: EmptyOutput
+regress/issue_39035.crash: EmptyOutput
+regress/issue_39091_2: EmptyOutput
+regress/utf_16_le_content.crash: EmptyOutput
+
+rasta/issue_000032: FormatterCrash
+regress/issue_34614: FormatterCrash
+extensions/ambiguous: FormatterCrash
+extensions/annotations: FormatterCrash
+extensions/builtin_identifiers: FormatterCrash
+extensions/call_methods: FormatterCrash
+extensions/check_bounds: FormatterCrash
+extensions/compounds: FormatterCrash
+extensions/conflict_with_object: FormatterCrash
+extensions/conflicts: FormatterCrash
+extensions/default_values: FormatterCrash
+extensions/direct_instance_access: FormatterCrash
+extensions/direct_static_access: FormatterCrash
+extensions/dynamic_invoke: FormatterCrash
+extensions/explicit_extension_access: FormatterCrash
+extensions/explicit_extension_inference: FormatterCrash
+extensions/explicit_generic_extension_access: FormatterCrash
+extensions/explicit_invalid_access: FormatterCrash
+extensions/explicit_this: FormatterCrash
+extensions/extension_call: FormatterCrash
+extensions/extension_constructor: FormatterCrash
+extensions/extension_field_with_type_parameter_usage: FormatterCrash
+extensions/extension_methods: FormatterCrash
+extensions/extension_setter_error: FormatterCrash
+extensions/extension_setter: FormatterCrash
+extensions/generic_function_in_generic_extension: FormatterCrash
+extensions/getter_setter_conflict: FormatterCrash
+extensions/if_null: FormatterCrash
+extensions/implicit_extension_inference: FormatterCrash
+extensions/implicit_this: FormatterCrash
+extensions/index: FormatterCrash
+extensions/instance_access_of_static: FormatterCrash
+extensions/instance_access: FormatterCrash
+extensions/instance_members: FormatterCrash
+extensions/instance_tearoff: FormatterCrash
+extensions/internal_resolution: FormatterCrash
+extensions/invalid_explicit_access: FormatterCrash
+extensions/invalid_explicit_static_access: FormatterCrash
+extensions/issue38600: FormatterCrash
+extensions/issue38712: FormatterCrash
+extensions/issue38713: FormatterCrash
+extensions/issue38745: FormatterCrash
+extensions/issue38755: FormatterCrash
+extensions/issue38915: FormatterCrash
+extensions/issue39527: FormatterCrash
+extensions/issue39889: FormatterCrash
+extensions/issue40596: FormatterCrash
+extensions/issue40713: FormatterCrash
+extensions/issue40816: FormatterCrash
+extensions/missing_toplevel: FormatterCrash
+extensions/nested_on_types: FormatterCrash
+extensions/null_aware: FormatterCrash
+extensions/on_function_type: FormatterCrash
+extensions/on_type_inference: FormatterCrash
+extensions/on_type_variable_inference: FormatterCrash
+extensions/operators: FormatterCrash
+extensions/other_kinds: FormatterCrash
+extensions/static_access_of_instance: FormatterCrash
+extensions/static_access: FormatterCrash
+extensions/tear_offs: FormatterCrash
+extensions/type_variables: FormatterCrash
+extensions/unnamed_extensions: FormatterCrash
+extensions/use_this: FormatterCrash
+general_nnbd_opt_out/annotation_eof: FormatterCrash
+general_nnbd_opt_out/bad_setter_abstract: FormatterCrash
+general_nnbd_opt_out/bug31124: FormatterCrash
+general_nnbd_opt_out/clone_function_type: FormatterCrash
+general_nnbd_opt_out/constructor_initializer_invalid: FormatterCrash
+general_nnbd_opt_out/duplicated_declarations: FormatterCrash
+general_nnbd_opt_out/function_type_default_value: FormatterCrash
+general_nnbd_opt_out/incomplete_field_formal_parameter: FormatterCrash
+general_nnbd_opt_out/many_errors: FormatterCrash
+general_nnbd_opt_out/var_as_type_name: FormatterCrash
+general/annotation_eof: FormatterCrash
+general/bad_setter_abstract: FormatterCrash
+general/bug31124: FormatterCrash
+general/clone_function_type: FormatterCrash
+general/constructor_initializer_invalid: FormatterCrash
+general/duplicated_declarations: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_general.crash: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_get.crash: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_return_type.crash: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_set.crash: FormatterCrash
+general/error_recovery/constructor_recovery_get: FormatterCrash
+general/error_recovery/constructor_recovery_operator.crash: FormatterCrash
+general/error_recovery/constructor_recovery_return_type: FormatterCrash
+general/error_recovery/constructor_recovery_set: FormatterCrash
+general/error_recovery/issue_39033.crash: FormatterCrash
+general/error_recovery/issue_39058_prime.crash: FormatterCrash
+general/error_recovery/issue_39202.crash: FormatterCrash
+general/error_recovery/issue_39230.crash: FormatterCrash
+general/error_recovery/issue_39958_01: FormatterCrash
+general/function_type_default_value: FormatterCrash
+general/incomplete_field_formal_parameter: FormatterCrash
+general/invalid_operator: FormatterCrash
+general/invalid_operator2: FormatterCrash
+general/issue40242: FormatterCrash
+general/many_errors: FormatterCrash
+general/type_parameter_usage_in_static_method_in_extension: FormatterCrash
+general/type_parameters_on_void: FormatterCrash
+general/var_as_type_name: FormatterCrash
+general/well_boundness_checks_in_outline: 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/infer_late_field_type: FormatterCrash
+late_lowering/initializer_rewrite: FormatterCrash
+late_lowering/instance_field_with_initializer: FormatterCrash
+late_lowering/instance_field_without_initializer: FormatterCrash
+late_lowering/instance_final_field_without_initializer: FormatterCrash
+late_lowering/instance_nullable_field_with_initializer: FormatterCrash
+late_lowering/instance_nullable_field_without_initializer: FormatterCrash
+late_lowering/instance_nullable_final_field_without_initializer: FormatterCrash
+late_lowering/issue40373: FormatterCrash
+late_lowering/issue40373b: FormatterCrash
+late_lowering/issue40805: FormatterCrash
+late_lowering/issue41436b: FormatterCrash
+late_lowering/late_field_inference: FormatterCrash
+late_lowering/late_field_with_initializer: FormatterCrash
+late_lowering/late_field_without_initializer: FormatterCrash
+late_lowering/late_final_field_with_initializer: FormatterCrash
+late_lowering/late_final_field_without_initializer: FormatterCrash
+late_lowering/late_final_nullable_field_with_initializer: FormatterCrash
+late_lowering/late_final_nullable_field_without_initializer: FormatterCrash
+late_lowering/late_future_or: FormatterCrash
+late_lowering/late_nullable_field_with_initializer: FormatterCrash
+late_lowering/late_nullable_field_without_initializer: FormatterCrash
+late_lowering/later: FormatterCrash
+late_lowering/override_getter_setter: FormatterCrash
+late_lowering/override: FormatterCrash
+late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
+nnbd/forbidden_supers: FormatterCrash
+nnbd/infer_if_null: FormatterCrash
+nnbd/inheritance_from_opt_in: FormatterCrash
+nnbd/issue40805: FormatterCrash
+nnbd/issue41349: FormatterCrash
+nnbd/issue41597: FormatterCrash
+nnbd/late: FormatterCrash
+nnbd/later: FormatterCrash
+nnbd/no_null_shorting_explicit_extension: FormatterCrash
+nnbd/no_null_shorting_extension: FormatterCrash
+nnbd/non_nullable_field_initialization: FormatterCrash
+nnbd/null_shorting_cascade: FormatterCrash
+nnbd/null_shorting_explicit_extension: FormatterCrash
+nnbd/null_shorting_extension: FormatterCrash
+nnbd/null_shorting_index: FormatterCrash
+nnbd/opt_out: FormatterCrash
+nnbd/potentially_non_nullable_field: FormatterCrash
+nnbd/potentially_nullable_access: FormatterCrash
+nnbd/strictly_non_nullable_warnings: FormatterCrash
+nnbd/uninitialized_non_nullable_late_fields: FormatterCrash
+nonfunction_type_aliases/issue41501: FormatterCrash
+rasta/bad_redirection: FormatterCrash
+rasta/issue_000034: FormatterCrash
+rasta/issue_000036: FormatterCrash
+rasta/issue_000044: FormatterCrash
+rasta/issue_000046: FormatterCrash
+rasta/issue_000047: FormatterCrash
+rasta/malformed_const_constructor: FormatterCrash
+rasta/mandatory_parameter_initializer: FormatterCrash
+regress/issue_29942: FormatterCrash
+regress/issue_29944: FormatterCrash
+regress/issue_29983: FormatterCrash
+regress/issue_29986: FormatterCrash
+regress/issue_30834: FormatterCrash
+regress/issue_30981: FormatterCrash
+regress/issue_30994: FormatterCrash
+regress/issue_31155: FormatterCrash
+regress/issue_31171: FormatterCrash
+regress/issue_31183: FormatterCrash
+regress/issue_31188: FormatterCrash
+regress/issue_31192: FormatterCrash
+regress/issue_31198: FormatterCrash
+regress/issue_34225: FormatterCrash
+regress/issue_34563: FormatterCrash
+regress/issue_34610: FormatterCrash
+regress/issue_34850: FormatterCrash
+regress/issue_35151: FormatterCrash
+regress/issue_36400: FormatterCrash
+regress/issue_37285: FormatterCrash
+regress/issue_39091_1: FormatterCrash
+regress/issue_41265.crash: Crash
+triple_shift/invalid_operator: FormatterCrash
+variance/class_type_parameter_modifier: FormatterCrash
+variance/generic_covariance_sound_variance: FormatterCrash
+variance/mixin_type_parameter_modifier: FormatterCrash
+variance/unconstrained_inference: FormatterCrash
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline.expect b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline.expect
new file mode 100644
index 0000000..7636a6d
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class B<X> {}
+
+void testTopLevel() {}
+void testNested() {}
+main() {}
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d694da5
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+F<X> toF<X>(X x) => null;
+
+class A<X> {}
+
+class B<X> {}
+
+main() {}
+typedef F<X> = void Function<Y extends X>();
+typedef Fcon<X> = Function(X);
+typedef FconBound<X extends num> = Function(X);
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef Fcov<X> = X Function();
+typedef FcovBound<X extends num> = X Function();
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef Finv<X> = X Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+void testNested() {}
+void testTopLevel() {}
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
new file mode 100644
index 0000000..708b749
--- /dev/null
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+class Operators1 {
+  operator >>( ){ }
+  operator>() => true;
+}
+class Operators2 {
+  operator >>( ){ }
+  operator>(a, b) => true;
+}
+class Operators3 {
+  operator >>( ){ }
+  operator>([a]) => true;
+}
+class Operators4 {
+  operator >>( ){ }
+  operator>({a}) => true;
+}
+class Operators5 {
+  operator >>( ){ }
+  operator>(a, [b]) => true;
+}
+class Operators6 {
+  operator >>( ){ }
+  operator>(a, {b}) => true;
+}
+class Operators7 {
+  operator >>( ){ }
+  operator><T>(a) => true;
+}
+main() { }
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect
index 083afec..94f58ef5 100644
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect
@@ -40,7 +40,6 @@
 //
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static field core::bool* b = false;
 static field core::List<dynamic>* list = <dynamic>[];
@@ -50,7 +49,7 @@
   if(self::b)
     #t1.{core::Map::[]=}(0, 1);
   else {
-    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(self::map0.{core::Map::entries}).{core::Iterable::iterator};
+    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final core::MapEntry<dynamic, dynamic>* #t2 = :sync-for-iterator.{core::Iterator::current};
       #t1.{core::Map::[]=}(#t2.{core::MapEntry::key}, #t2.{core::MapEntry::value});
@@ -60,7 +59,7 @@
 static field core::Map<dynamic, dynamic>* map2 = block {
   final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
   if(self::b) {
-    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(self::map0.{core::Map::entries}).{core::Iterable::iterator};
+    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final core::MapEntry<dynamic, dynamic>* #t4 = :sync-for-iterator.{core::Iterator::current};
       #t3.{core::Map::[]=}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
@@ -72,14 +71,14 @@
 static field core::Map<dynamic, dynamic>* map3 = block {
   final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
   if(self::b) {
-    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(self::map0.{core::Map::entries}).{core::Iterable::iterator};
+    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final core::MapEntry<dynamic, dynamic>* #t6 = :sync-for-iterator.{core::Iterator::current};
       #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
     }
   }
   else {
-    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, dynamic>*>*>(self::map0.{core::Map::entries}).{core::Iterable::iterator};
+    core::Iterator<core::MapEntry<dynamic, dynamic>*>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final core::MapEntry<dynamic, dynamic>* #t7 = :sync-for-iterator.{core::Iterator::current};
       #t5.{core::Map::[]=}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
@@ -91,7 +90,7 @@
   if(self::b)
     #t8.{core::Map::[]=}(0, 1);
   else {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::list).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic a = :sync-for-iterator.{core::Iterator::current};
       #t8.{core::Map::[]=}(a, 1);
@@ -101,7 +100,7 @@
 static field core::Map<dynamic, core::int*>* map5 = block {
   final core::Map<dynamic, core::int*>* #t9 = <dynamic, core::int*>{};
   if(self::b) {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::list).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic a = :sync-for-iterator.{core::Iterator::current};
       #t9.{core::Map::[]=}(a, 1);
@@ -115,11 +114,11 @@
   if(self::b)
     #t10.{core::Map::[]=}(0, 1);
   else {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::list).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic a = :sync-for-iterator.{core::Iterator::current};
       {
-        core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, core::int*>*>*>(<dynamic, core::int*>{a: 1}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = <dynamic, core::int*>{a: 1}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, core::int*>* #t11 = :sync-for-iterator.{core::Iterator::current};
           #t10.{core::Map::[]=}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
@@ -131,11 +130,11 @@
 static field core::Map<dynamic, core::int*>* map7 = block {
   final core::Map<dynamic, core::int*>* #t12 = <dynamic, core::int*>{};
   if(self::b) {
-    core::Iterator<dynamic>* :sync-for-iterator = _in::unsafeCast<core::Iterable<dynamic>*>(self::list).{core::Iterable::iterator};
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       dynamic a = :sync-for-iterator.{core::Iterator::current};
       {
-        core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, core::int*>*>*>(<dynamic, core::int*>{a: 1}.{core::Map::entries}).{core::Iterable::iterator};
+        core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = <dynamic, core::int*>{a: 1}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
           final core::MapEntry<dynamic, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
           #t12.{core::Map::[]=}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
@@ -168,7 +167,7 @@
     #t16.{core::Map::[]=}(0, 1);
   else
     for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, core::int*>*>*>(<dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
         #t16.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
@@ -179,7 +178,7 @@
   final core::Map<dynamic, core::int*>* #t18 = <dynamic, core::int*>{};
   if(self::b)
     for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<dynamic, core::int*>*>*>(<dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, core::int*>*>* :sync-for-iterator = <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<dynamic, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
         #t18.{core::Map::[]=}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
@@ -194,7 +193,7 @@
     #t20.{core::Map::[]=}(0, 1);
   else
     if(self::b) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::MapEntry<core::int*, core::int*>*>*>(<core::int*, core::int*>{0: 1}.{core::Map::entries}).{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::int*, core::int*>*>* :sync-for-iterator = <core::int*, core::int*>{0: 1}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
new file mode 100644
index 0000000..480a19e
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
@@ -0,0 +1,109 @@
+bool b = false;
+var list = [];
+var map0 = {};
+var map1 = {if (b) 0: 1 else ...map0};
+var map2 = {if (b) ...map0 else 0: 1};
+var map3 = {if (b) ...map0 else ...map0};
+var map4 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) a: 1
+};
+var map5 = {
+  if (b)
+    for (var a in list) a: 1
+  else
+    0: 1
+};
+var map6 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) ...{a: 1}
+};
+var map7 = {
+  if (b)
+    for (var a in list) ...{a: 1}
+  else
+    0: 1
+};
+var map8 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) list[i]: 1
+};
+var map9 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) list[i]: 1
+  else
+    0: 1
+};
+var map10 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+};
+var map11 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+  else
+    0: 1
+};
+var map12 = {
+  if (b) 0: 1 else if (b) ...{0: 1}
+};
+var error4 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) a
+};
+var error5 = {
+  if (b)
+    for (var a in list) a
+  else
+    0: 1
+};
+var error6 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) ...{a}
+};
+var error7 = {
+  if (b)
+    for (var a in list) ...{a}
+  else
+    0: 1
+};
+var error8 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) list[i]
+};
+var error9 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) list[i]
+  else
+    0: 1
+};
+var error10 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) ...{list[i]}
+};
+var error11 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) ...{list[i]}
+  else
+    0: 1
+};
+var error12 = {
+  if (b) 0: 1 else if (b) ...{0}
+};
+main() {}
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1843b5c
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
@@ -0,0 +1,109 @@
+bool b = false;
+main() {}
+var error10 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) ...{list[i]}
+};
+var error11 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) ...{list[i]}
+  else
+    0: 1
+};
+var error12 = {
+  if (b) 0: 1 else if (b) ...{0}
+};
+var error4 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) a
+};
+var error5 = {
+  if (b)
+    for (var a in list) a
+  else
+    0: 1
+};
+var error6 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) ...{a}
+};
+var error7 = {
+  if (b)
+    for (var a in list) ...{a}
+  else
+    0: 1
+};
+var error8 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) list[i]
+};
+var error9 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) list[i]
+  else
+    0: 1
+};
+var list = [];
+var map0 = {};
+var map1 = {if (b) 0: 1 else ...map0};
+var map10 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+};
+var map11 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+  else
+    0: 1
+};
+var map12 = {
+  if (b) 0: 1 else if (b) ...{0: 1}
+};
+var map2 = {if (b) ...map0 else 0: 1};
+var map3 = {if (b) ...map0 else ...map0};
+var map4 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) a: 1
+};
+var map5 = {
+  if (b)
+    for (var a in list) a: 1
+  else
+    0: 1
+};
+var map6 = {
+  if (b)
+    0: 1
+  else
+    for (var a in list) ...{a: 1}
+};
+var map7 = {
+  if (b)
+    for (var a in list) ...{a: 1}
+  else
+    0: 1
+};
+var map8 = {
+  if (b)
+    0: 1
+  else
+    for (var i = 0; i < list.length; i++) list[i]: 1
+};
+var map9 = {
+  if (b)
+    for (var i = 0; i < list.length; i++) list[i]: 1
+  else
+    0: 1
+};
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..f9fc129
--- /dev/null
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<out X, in Y, inout Z> {
+}
+main() { }
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
new file mode 100644
index 0000000..d888571
--- /dev/null
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect
@@ -0,0 +1,42 @@
+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;
+  void method(T t, void Function(U) u, V v) { }
+  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>>();
+  Map<U, Invariant<V>> get mapInv => new Map<U, Invariant<V>>();
+  Map<U, InvFunction<V>> get mapInvFn => new Map<U, InvFunction<V>>();
+}
+class B<inout T> {
+  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]) { }
+  void set x(T t) { }
+}
+abstract class D<T> {
+  int method(T x);
+}
+class E<inout T> {
+  final void Function(T) f;
+  E(this.f);
+  int method(T x) { }
+}
+class F<inout T> extends E<T> implements D<T> {
+  F(void Function(T) f) : super(f);
+}
+class NoSuchMethod<inout T> implements B<T> {
+  noSuchMethod(_) => 3;
+}
+main() { }
+expect(expected, actual) { }
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
new file mode 100644
index 0000000..2a9a258
--- /dev/null
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+}
+mixin B<inout X, out Y, in Z> on A {
+}
+main() { }
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
new file mode 100644
index 0000000..000a126
--- /dev/null
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Covariant<out T> {
+}
+class Contravariant<in T> {
+}
+class Invariant<inout T> {
+}
+void covariantListInfer<T>(Covariant<List<T>> x) { }
+void contravariantListInfer<T>(Contravariant<List<T>> x) { }
+void invariantListInfer<T>(Invariant<List<T>> x) { }
+main() { }
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 4a52efa..4de00b0 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -59,8 +59,11 @@
 general_nnbd_opt_out/unsound_promotion: TypeCheckError
 general_nnbd_opt_out/void_methods: RuntimeError
 nnbd/inheritance_from_opt_in: TypeCheckError
+nnbd/issue41567: TypeCheckError
 nnbd/messages_with_types_opt_in: TypeCheckError
 nnbd/messages_with_types_opt_out: TypeCheckError
 nnbd/never_opt_out: TypeCheckError
-nnbd/issue41210a/issue41210: TypeCheckError
-nnbd/issue41210b: TypeCheckError
+nnbd/nullable_object_access: TypeCheckError
+nnbd/nullable_receiver: TypeCheckError
+nnbd/potentially_nullable_access: TypeCheckError
+
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index af436d3..a9488bf 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -43,6 +43,24 @@
       ]
     },
     {
+      "name": "textual_outline",
+      "kind": "Chain",
+      "source": "test/fasta/textual_outline_suite.dart",
+      "path": "testcases/",
+      "status": "testcases/textual_outline.status",
+      "pattern": [
+        "\\.dart$",
+        "\\.crash_dart$"
+      ],
+      "exclude": [
+        "/testcases/.*_part[0-9]*\\.dart$",
+        "/testcases/.*_lib[0-9]*\\.dart$",
+        "/testcases/dartino/",
+        "/testcases/shaker/",
+        "/testcases/expression/"
+      ]
+    },
+    {
       "name": "outline",
       "kind": "Chain",
       "source": "test/fasta/outline_suite.dart",
diff --git a/pkg/front_end/tool/_fasta/additional_targets_test.dart b/pkg/front_end/tool/_fasta/additional_targets_test.dart
index 041a363..daffd49 100644
--- a/pkg/front_end/tool/_fasta/additional_targets_test.dart
+++ b/pkg/front_end/tool/_fasta/additional_targets_test.dart
@@ -6,6 +6,8 @@
 
 import 'package:kernel/target/targets.dart' show targets;
 
+import 'package:front_end/src/base/command_line_options.dart';
+
 import 'package:front_end/src/fasta/fasta_codes.dart'
     show MessageCode, messageFastaUsageLong;
 
@@ -13,7 +15,8 @@
 
 main() {
   installAdditionalTargets();
-  String expected = "  --target=${(targets.keys.toList()..sort()).join('|')}";
+  String expected =
+      "  ${Flags.target}=${(targets.keys.toList()..sort()).join('|')}";
   MessageCode code = messageFastaUsageLong;
   if (!code.message.contains(expected)) {
     throw "Error: ${code.name} in pkg/front_end/messages.yaml doesn't contain"
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 392a4d3..811f854 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -44,7 +44,7 @@
         messageFastaUsageShort,
         templateUnspecified;
 
-import 'package:front_end/src/fasta/problems.dart' show DebugAbort, unhandled;
+import 'package:front_end/src/fasta/problems.dart' show DebugAbort;
 
 import 'package:front_end/src/fasta/resolve_input_uri.dart'
     show resolveInputUri;
@@ -104,8 +104,8 @@
   /// All other options require an option value, either on the form `--option
   /// value` or `--option=value`.
   static ParsedArguments parse(
-      List<String> arguments, Map<String, dynamic> specification) {
-    specification ??= const <String, dynamic>{};
+      List<String> arguments, Map<String, ValueSpecification> specification) {
+    specification ??= const <String, ValueSpecification>{};
     ParsedArguments result = new ParsedArguments();
     int index = arguments.indexOf("--");
     Iterable<String> nonOptions = const <String>[];
@@ -128,26 +128,21 @@
             argument = argument.substring(0, index);
           }
         }
-        var valueSpecification = specification[argument];
+        ValueSpecification valueSpecification = specification[argument];
         if (valueSpecification == null) {
           throw new CommandLineProblem.deprecated(
               "Unknown option '$argument'.");
         }
         String canonicalArgument = argument;
-        if (valueSpecification is String &&
-            valueSpecification != "," &&
-            valueSpecification != "<define>") {
-          canonicalArgument = valueSpecification;
-          valueSpecification = specification[valueSpecification];
+        if (valueSpecification.alias != null) {
+          canonicalArgument = valueSpecification.alias;
+          valueSpecification = specification[valueSpecification.alias];
         }
-        if (valueSpecification == true || valueSpecification == false) {
-          valueSpecification = bool;
+        if (valueSpecification == null) {
+          throw new CommandLineProblem.deprecated(
+              "Unknown option alias '$canonicalArgument'.");
         }
-        if (valueSpecification is! String && valueSpecification is! Type) {
-          throw new CommandLineProblem.deprecated("Unrecognized type of value "
-              "specification: ${valueSpecification.runtimeType}.");
-        }
-        final bool requiresValue = valueSpecification != bool;
+        final bool requiresValue = valueSpecification.requiresValue;
         if (requiresValue && value == null) {
           if (!iterator.moveNext()) {
             throw new CommandLineProblem(
@@ -155,84 +150,15 @@
           }
           value = iterator.current;
         }
-        switch ("$valueSpecification") {
-          case ",":
-            result.options
-                .putIfAbsent(argument, () => <String>[])
-                .addAll(value.split(","));
-            break;
-
-          case "<define>":
-            int index = value.indexOf('=');
-            String name;
-            String expression;
-            if (index != -1) {
-              name = value.substring(0, index);
-              expression = value.substring(index + 1);
-            } else {
-              name = value;
-              expression = value;
-            }
-            result.defines[name] = expression;
-            break;
-
-          case "int":
-          case "bool":
-          case "String":
-          case "Uri":
-            if (result.options.containsKey(canonicalArgument)) {
-              return throw new CommandLineProblem.deprecated(
-                  "Multiple values for '$argument': "
-                  "'${result.options[canonicalArgument]}' and '$value'.");
-            }
-            var parsedValue;
-            if (valueSpecification == int) {
-              parsedValue = int.tryParse(value);
-              if (parsedValue == null) {
-                return throw new CommandLineProblem.deprecated(
-                    "Value for '$argument', '$value', isn't an int.");
-              }
-            } else if (valueSpecification == bool) {
-              if (value == null || value == "true" || value == "yes") {
-                parsedValue = true;
-              } else if (value == "false" || value == "no") {
-                parsedValue = false;
-              } else {
-                return throw new CommandLineProblem.deprecated(
-                    "Value for '$argument' is '$value', "
-                    "but expected one of: 'true', 'false', 'yes', or 'no'.");
-              }
-            } else if (valueSpecification == Uri) {
-              // TODO(ahe): resolve Uris lazily, so that schemes provided by
-              // other flags can be used for parsed command-line arguments too.
-              parsedValue = resolveInputUri(value);
-            } else if (valueSpecification == String) {
-              parsedValue = value;
-            } else if (valueSpecification is String) {
-              return throw new CommandLineProblem.deprecated(
-                  "Unrecognized value specification: "
-                  "'$valueSpecification', try using a type literal instead.");
-            } else {
-              // All possible cases should have been handled above.
-              return unhandled("${valueSpecification.runtimeType}",
-                  "CommandLine.parse", -1, null);
-            }
-            result.options[canonicalArgument] = parsedValue;
-            break;
-
-          default:
-            return throw new CommandLineProblem.deprecated(
-                "Unrecognized value specification: '$valueSpecification'.");
-        }
+        valueSpecification.processValue(
+            result, canonicalArgument, argument, value);
       } else {
         result.arguments.add(argument);
       }
     }
-    specification.forEach((String key, value) {
-      if (value == bool) {
-        result.options[key] ??= false;
-      } else if (value is bool) {
-        result.options[key] ??= value;
+    specification.forEach((String key, ValueSpecification value) {
+      if (value.defaultValue != null) {
+        result.options[key] ??= value.defaultValue;
       }
     });
     result.arguments.addAll(nonOptions);
@@ -243,76 +169,72 @@
 // Before adding new options here, you must:
 //  * Document the option.
 //  * Get an explicit approval from the front-end team.
-const Map<String, dynamic> optionSpecification = const <String, dynamic>{
-  "--bytecode": false,
-  "--compile-sdk": Uri,
-  "--dump-ir": false,
-  "--enable-experiment": ",",
-  "--exclude-source": false,
-  "--omit-platform": false,
-  "--fatal": ",",
-  "--fatal-skip": String,
-  Flags.forceLateLowering: false,
-  Flags.forceNoExplicitGetterCalls: false,
-  "--help": false,
-  // TODO(johnniwinther): Remove legacy option flags. Legacy mode is no longer
-  // supported.
-  "--legacy": "--legacy-mode",
-  "--legacy-mode": false,
-  "--libraries-json": Uri,
-  "--no-defines": false,
-  "--output": Uri,
-  "--packages": Uri,
-  "--platform": Uri,
-  "--sdk": Uri,
-  "--single-root-base": Uri,
-  "--single-root-scheme": String,
-  Flags.nnbdStrongMode: false,
-  Flags.nnbdAgnosticMode: false,
-  "--supermixin": true,
-  Flags.target: String,
-  "--enable-asserts": false,
-  "--verbose": false,
-  "--verify": false,
-  "-D": "<define>",
-  "-h": "--help",
-  "-o": "--output",
-  "-t": "--target",
-  "-v": "--verbose",
-  "/?": "--help",
-  "/h": "--help",
+const Map<String, ValueSpecification> optionSpecification =
+    const <String, ValueSpecification>{
+  Flags.bytecode: const BoolValue(false),
+  Flags.compileSdk: const UriValue(),
+  Flags.dumpIr: const BoolValue(false),
+  Flags.enableExperiment: const StringListValue(),
+  Flags.excludeSource: const BoolValue(false),
+  Flags.omitPlatform: const BoolValue(false),
+  Flags.fatal: const StringListValue(),
+  Flags.fatalSkip: const StringValue(),
+  Flags.forceLateLowering: const BoolValue(false),
+  Flags.forceNoExplicitGetterCalls: const BoolValue(false),
+  Flags.help: const BoolValue(false),
+  Flags.librariesJson: const UriValue(),
+  Flags.noDefines: const BoolValue(false),
+  Flags.output: const UriValue(),
+  Flags.packages: const UriValue(),
+  Flags.platform: const UriValue(),
+  Flags.sdk: const UriValue(),
+  Flags.singleRootBase: const UriValue(),
+  Flags.singleRootScheme: const StringValue(),
+  Flags.nnbdStrongMode: const BoolValue(false),
+  Flags.nnbdAgnosticMode: const BoolValue(false),
+  Flags.target: const StringValue(),
+  Flags.verbose: const BoolValue(false),
+  Flags.verify: const BoolValue(false),
+  Flags.linkDependencies: const UriListValue(),
+  "-D": const DefineValue(),
+  "-h": const AliasValue(Flags.help),
+  "--out": const AliasValue(Flags.output),
+  "-o": const AliasValue(Flags.output),
+  "-t": const AliasValue(Flags.target),
+  "-v": const AliasValue(Flags.verbose),
+  "/?": const AliasValue(Flags.help),
+  "/h": const AliasValue(Flags.help),
 };
 
 void throwCommandLineProblem(String message) {
   throw new CommandLineProblem.deprecated(message);
 }
 
-ProcessedOptions analyzeCommandLine(
-    String programName,
-    ParsedArguments parsedArguments,
-    bool areRestArgumentsInputs,
-    bool verbose) {
+ProcessedOptions analyzeCommandLine(String programName,
+    ParsedArguments parsedArguments, bool areRestArgumentsInputs) {
   final Map<String, dynamic> options = parsedArguments.options;
 
   final List<String> arguments = parsedArguments.arguments;
 
-  final bool help = options["--help"];
+  final bool help = options[Flags.help];
+
+  final bool verbose = options[Flags.verbose];
 
   if (help) {
     print(computeUsage(programName, verbose).message);
     exit(0);
   }
 
-  if (options.containsKey("--compile-sdk") &&
-      options.containsKey("--platform")) {
+  if (options.containsKey(Flags.compileSdk) &&
+      options.containsKey(Flags.platform)) {
     return throw new CommandLineProblem.deprecated(
-        "Can't specify both '--compile-sdk' and '--platform'.");
+        "Can't specify both '${Flags.compileSdk}' and '${Flags.platform}'.");
   }
 
-  final String targetName = options["--target"] ?? "vm";
+  final String targetName = options[Flags.target] ?? "vm";
 
   Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
-      parseExperimentalArguments(options["--enable-experiment"]),
+      parseExperimentalArguments(options[Flags.enableExperiment]),
       onError: throwCommandLineProblem,
       onWarning: print);
 
@@ -331,33 +253,33 @@
         "Valid targets are:\n  ${targets.keys.join("\n  ")}");
   }
 
-  final bool noDefines = options["--no-defines"];
+  final bool noDefines = options[Flags.noDefines];
 
-  final bool verify = options["--verify"];
+  final bool verify = options[Flags.verify];
 
-  final bool dumpIr = options["--dump-ir"];
+  final bool dumpIr = options[Flags.dumpIr];
 
-  final bool excludeSource = options["--exclude-source"];
+  final bool excludeSource = options[Flags.excludeSource];
 
-  final bool omitPlatform = options["--omit-platform"];
+  final bool omitPlatform = options[Flags.omitPlatform];
 
-  final Uri packages = options["--packages"];
+  final Uri packages = options[Flags.packages];
 
   final Set<String> fatal =
-      new Set<String>.from(options["--fatal"] ?? <String>[]);
+      new Set<String>.from(options[Flags.fatal] ?? <String>[]);
 
   final bool errorsAreFatal = fatal.contains("errors");
 
   final bool warningsAreFatal = fatal.contains("warnings");
 
-  final int fatalSkip = int.tryParse(options["--fatal-skip"] ?? "0") ?? -1;
+  final int fatalSkip = int.tryParse(options[Flags.fatalSkip] ?? "0") ?? -1;
 
-  final bool bytecode = options["--bytecode"];
+  final bool bytecode = options[Flags.bytecode];
 
-  final bool compileSdk = options.containsKey("--compile-sdk");
+  final bool compileSdk = options.containsKey(Flags.compileSdk);
 
-  final String singleRootScheme = options["--single-root-scheme"];
-  final Uri singleRootBase = options["--single-root-base"];
+  final String singleRootScheme = options[Flags.singleRootScheme];
+  final Uri singleRootBase = options[Flags.singleRootBase];
 
   final bool nnbdStrongMode = options[Flags.nnbdStrongMode];
 
@@ -367,6 +289,8 @@
       ? NnbdMode.Agnostic
       : (nnbdStrongMode ? NnbdMode.Strong : NnbdMode.Weak);
 
+  final List<Uri> linkDependencies = options[Flags.linkDependencies] ?? [];
+
   if (nnbdStrongMode && nnbdAgnosticMode) {
     return throw new CommandLineProblem.deprecated(
         "Can't specify both '${Flags.nnbdStrongMode}' and "
@@ -386,6 +310,24 @@
     });
   }
 
+  CompilerOptions compilerOptions = new CompilerOptions()
+    ..compileSdk = compileSdk
+    ..fileSystem = fileSystem
+    ..packagesFileUri = packages
+    ..target = target
+    ..throwOnErrorsForDebugging = errorsAreFatal
+    ..throwOnWarningsForDebugging = warningsAreFatal
+    ..skipForDebugging = fatalSkip
+    ..embedSourceText = !excludeSource
+    ..debugDump = dumpIr
+    ..omitPlatform = omitPlatform
+    ..verbose = verbose
+    ..verify = verify
+    ..experimentalFlags = experimentalFlags
+    ..environmentDefines = noDefines ? null : parsedArguments.defines
+    ..nnbdMode = nnbdMode
+    ..additionalDills = linkDependencies;
+
   if (programName == "compile_platform") {
     if (arguments.length != 5) {
       return throw new CommandLineProblem.deprecated(
@@ -393,33 +335,19 @@
     }
     if (compileSdk) {
       return throw new CommandLineProblem.deprecated(
-          "Cannot specify '--compile-sdk' option to compile_platform.");
+          "Cannot specify '${Flags.compileSdk}' option to compile_platform.");
     }
-    if (options.containsKey("--output")) {
+    if (options.containsKey(Flags.output)) {
       return throw new CommandLineProblem.deprecated(
-          "Cannot specify '--output' option to compile_platform.");
+          "Cannot specify '${Flags.output}' option to compile_platform.");
     }
 
     return new ProcessedOptions(
-        options: new CompilerOptions()
-          ..sdkSummary = options["--platform"]
+        options: compilerOptions
+          ..sdkSummary = options[Flags.platform]
           ..librariesSpecificationUri = resolveInputUri(arguments[1])
           ..setExitCodeOnProblem = true
-          ..fileSystem = fileSystem
-          ..packagesFileUri = packages
-          ..target = target
-          ..throwOnErrorsForDebugging = errorsAreFatal
-          ..throwOnWarningsForDebugging = warningsAreFatal
-          ..skipForDebugging = fatalSkip
-          ..embedSourceText = !excludeSource
-          ..debugDump = dumpIr
-          ..omitPlatform = omitPlatform
-          ..verbose = verbose
-          ..verify = verify
-          ..bytecode = bytecode
-          ..experimentalFlags = experimentalFlags
-          ..environmentDefines = noDefines ? null : parsedArguments.defines
-          ..nnbdMode = nnbdMode,
+          ..bytecode = bytecode,
         inputs: <Uri>[Uri.parse(arguments[0])],
         output: resolveInputUri(arguments[3]));
   } else if (arguments.isEmpty) {
@@ -428,9 +356,11 @@
 
   final Uri defaultOutput = resolveInputUri("${arguments.first}.dill");
 
-  final Uri output = options["-o"] ?? options["--output"] ?? defaultOutput;
+  final Uri output = options[Flags.output] ?? defaultOutput;
 
-  final Uri sdk = options["--sdk"] ?? options["--compile-sdk"];
+  final Uri sdk = options[Flags.sdk] ?? options[Flags.compileSdk];
+
+  final Uri librariesJson = options[Flags.librariesJson];
 
   String computePlatformDillName() {
     switch (target.name) {
@@ -447,38 +377,21 @@
       case 'none':
         return "vm_platform_strong.dill";
       default:
-        throwCommandLineProblem(
-            'Target "${target.name}" requires an explicit --platform option.');
+        throwCommandLineProblem("Target '${target.name}' requires an explicit "
+            "'${Flags.platform}' option.");
     }
     return null;
   }
 
   final Uri platform = compileSdk
       ? null
-      : (options["--platform"] ??
+      : (options[Flags.platform] ??
           computePlatformBinariesLocation(forceBuildDir: true)
               .resolve(computePlatformDillName()));
-
-  CompilerOptions compilerOptions = new CompilerOptions()
-    ..compileSdk = compileSdk
-    ..fileSystem = fileSystem
+  compilerOptions
     ..sdkRoot = sdk
     ..sdkSummary = platform
-    ..packagesFileUri = packages
-    ..target = target
-    ..throwOnErrorsForDebugging = errorsAreFatal
-    ..throwOnWarningsForDebugging = warningsAreFatal
-    ..skipForDebugging = fatalSkip
-    ..embedSourceText = !excludeSource
-    ..debugDump = dumpIr
-    ..omitPlatform = omitPlatform
-    ..verbose = verbose
-    ..verify = verify
-    ..experimentalFlags = experimentalFlags
-    ..environmentDefines = noDefines ? null : parsedArguments.defines
-    ..nnbdMode = nnbdMode;
-
-  // TODO(ahe): What about chase dependencies?
+    ..librariesSpecificationUri = librariesJson;
 
   List<Uri> inputs = <Uri>[];
   if (areRestArgumentsInputs) {
@@ -495,21 +408,13 @@
     List<String> arguments,
     bool areRestArgumentsInputs,
     Future<T> f(CompilerContext context, List<String> restArguments)) {
-  bool verbose = false;
-  for (String argument in arguments) {
-    if (argument == "--") break;
-    if (argument == "-v" || argument == "--verbose") {
-      verbose = true;
-      break;
-    }
-  }
   ParsedArguments parsedArguments;
   ProcessedOptions options;
   CommandLineProblem problem;
   try {
     parsedArguments = ParsedArguments.parse(arguments, optionSpecification);
     options = analyzeCommandLine(
-        programName, parsedArguments, areRestArgumentsInputs, verbose);
+        programName, parsedArguments, areRestArgumentsInputs);
   } on CommandLineProblem catch (e) {
     options = new ProcessedOptions();
     problem = e;
@@ -517,7 +422,7 @@
 
   return CompilerContext.runWithOptions<T>(options, (c) {
     if (problem != null) {
-      print(computeUsage(programName, verbose).message);
+      print(computeUsage(programName, options.verbose).message);
       print(c.formatWithoutLocation(problem.message, Severity.error));
       exit(1);
     }
@@ -580,3 +485,148 @@
   }
   return failingValue;
 }
+
+abstract class ValueSpecification {
+  const ValueSpecification();
+
+  String get alias => null;
+
+  dynamic get defaultValue => null;
+
+  bool get requiresValue => true;
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value);
+}
+
+class AliasValue extends ValueSpecification {
+  final String alias;
+
+  const AliasValue(this.alias);
+
+  bool get requiresValue =>
+      throw new UnsupportedError("AliasValue.requiresValue");
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    throw new UnsupportedError("AliasValue.processValue");
+  }
+}
+
+class UriValue extends ValueSpecification {
+  const UriValue();
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    if (result.options.containsKey(canonicalArgument)) {
+      throw new CommandLineProblem.deprecated(
+          "Multiple values for '$argument': "
+          "'${result.options[canonicalArgument]}' and '$value'.");
+    }
+    // TODO(ahe): resolve Uris lazily, so that schemes provided by
+    // other flags can be used for parsed command-line arguments too.
+    result.options[canonicalArgument] = resolveInputUri(value);
+  }
+}
+
+class StringValue extends ValueSpecification {
+  const StringValue();
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    if (result.options.containsKey(canonicalArgument)) {
+      throw new CommandLineProblem.deprecated(
+          "Multiple values for '$argument': "
+          "'${result.options[canonicalArgument]}' and '$value'.");
+    }
+    result.options[canonicalArgument] = value;
+  }
+}
+
+class BoolValue extends ValueSpecification {
+  final bool defaultValue;
+
+  const BoolValue(this.defaultValue);
+
+  bool get requiresValue => false;
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    if (result.options.containsKey(canonicalArgument)) {
+      throw new CommandLineProblem.deprecated(
+          "Multiple values for '$argument': "
+          "'${result.options[canonicalArgument]}' and '$value'.");
+    }
+    bool parsedValue;
+    if (value == null || value == "true" || value == "yes") {
+      parsedValue = true;
+    } else if (value == "false" || value == "no") {
+      parsedValue = false;
+    } else {
+      throw new CommandLineProblem.deprecated(
+          "Value for '$argument' is '$value', "
+          "but expected one of: 'true', 'false', 'yes', or 'no'.");
+    }
+    result.options[canonicalArgument] = parsedValue;
+  }
+}
+
+class IntValue extends ValueSpecification {
+  const IntValue();
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    if (result.options.containsKey(canonicalArgument)) {
+      throw new CommandLineProblem.deprecated(
+          "Multiple values for '$argument': "
+          "'${result.options[canonicalArgument]}' and '$value'.");
+    }
+    int parsedValue = int.tryParse(value);
+    if (parsedValue == null) {
+      throw new CommandLineProblem.deprecated(
+          "Value for '$argument', '$value', isn't an int.");
+    }
+    result.options[canonicalArgument] = parsedValue;
+  }
+}
+
+class DefineValue extends ValueSpecification {
+  const DefineValue();
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    int index = value.indexOf('=');
+    String name;
+    String expression;
+    if (index != -1) {
+      name = value.substring(0, index);
+      expression = value.substring(index + 1);
+    } else {
+      name = value;
+      expression = value;
+    }
+    result.defines[name] = expression;
+  }
+}
+
+class StringListValue extends ValueSpecification {
+  const StringListValue();
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    result.options
+        .putIfAbsent(canonicalArgument, () => <String>[])
+        .addAll(value.split(","));
+  }
+}
+
+class UriListValue extends ValueSpecification {
+  const UriListValue();
+
+  void processValue(ParsedArguments result, String canonicalArgument,
+      String argument, String value) {
+    result.options
+        .putIfAbsent(canonicalArgument, () => <Uri>[])
+        .addAll(value.split(",").map(resolveInputUri));
+  }
+}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 7676f1d..1ef0065 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -18,7 +18,7 @@
 
 import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
 
-import 'package:kernel/type_environment.dart' show SubtypeTester;
+import 'package:kernel/src/types.dart' show Types;
 
 import 'package:vm/bytecode/gen_bytecode.dart'
     show createFreshComponentWithBytecode, generateBytecode;
@@ -78,7 +78,7 @@
     stopwatch.stop();
 
     elapsedTimes.add(stopwatch.elapsedMilliseconds.toDouble());
-    List<Object> typeChecks = SubtypeTester.typeChecks;
+    List<Object> typeChecks = Types.typeChecksForTesting;
     if (typeChecks?.isNotEmpty ?? false) {
       BenchMaker.writeTypeChecks("type_checks.json", typeChecks);
     }
@@ -186,7 +186,7 @@
       options.sdkSummaryComponent = platformComponent;
     }
     CompileTask task = new CompileTask(c, ticker);
-    await task.compile(omitPlatform: true);
+    await task.compile(omitPlatform: true, supportAdditionalDills: false);
     CanonicalName root = platformComponent.root;
     for (Library library in platformComponent.libraries) {
       library.parent = platformComponent;
@@ -220,7 +220,7 @@
       }
       CompileTask task =
           new CompileTask(c, new Ticker(isVerbose: c.options.verbose));
-      return await task.buildOutline(c.options.output);
+      return await task.buildOutline(output: c.options.output);
     });
   });
 }
@@ -292,15 +292,31 @@
     return dFile;
   }
 
-  Future<KernelTarget> buildOutline([Uri output]) async {
+  Future<KernelTarget> buildOutline(
+      {Uri output, bool supportAdditionalDills: true}) async {
     UriTranslator uriTranslator = await c.options.getUriTranslator();
     ticker.logMs("Read packages file");
     DillTarget dillTarget = createDillTarget(uriTranslator);
     KernelTarget kernelTarget = createKernelTarget(dillTarget, uriTranslator);
-    Uri platform = c.options.sdkSummary;
-    if (platform != null) {
-      _appendDillForUri(dillTarget, platform);
+
+    if (supportAdditionalDills) {
+      Component sdkSummary = await c.options.loadSdkSummary(null);
+      if (sdkSummary != null) {
+        dillTarget.loader.appendLibraries(sdkSummary);
+      }
+
+      CanonicalName nameRoot = sdkSummary?.root ?? new CanonicalName.root();
+      for (Component additionalDill
+          in await c.options.loadAdditionalDills(nameRoot)) {
+        dillTarget.loader.appendLibraries(additionalDill);
+      }
+    } else {
+      Uri platform = c.options.sdkSummary;
+      if (platform != null) {
+        _appendDillForUri(dillTarget, platform);
+      }
     }
+
     kernelTarget.setEntryPoints(c.options.inputs);
     await dillTarget.buildOutlines();
     var outline = await kernelTarget.buildOutlines();
@@ -314,8 +330,10 @@
     return kernelTarget;
   }
 
-  Future<Uri> compile({bool omitPlatform: false}) async {
-    KernelTarget kernelTarget = await buildOutline();
+  Future<Uri> compile(
+      {bool omitPlatform: false, bool supportAdditionalDills: true}) async {
+    KernelTarget kernelTarget =
+        await buildOutline(supportAdditionalDills: supportAdditionalDills);
     Uri uri = c.options.output;
     Component component =
         await kernelTarget.buildComponent(verify: c.options.verify);
@@ -328,7 +346,8 @@
       Component userCode = new Component(
           nameRoot: component.root,
           uriToSource: new Map<Uri, Source>.from(component.uriToSource));
-      userCode.mainMethodName = component.mainMethodName;
+      userCode.setMainMethodAndMode(
+          component.mainMethodName, true, component.mode);
       for (Library library in component.libraries) {
         if (library.importUri.scheme != "dart") {
           userCode.libraries.add(library);
@@ -346,10 +365,11 @@
 
 /// Load the [Component] from the given [uri] and append its libraries
 /// to the [dillTarget].
-void _appendDillForUri(DillTarget dillTarget, Uri uri) {
+Component _appendDillForUri(DillTarget dillTarget, Uri uri) {
   var bytes = new File.fromUri(uri).readAsBytesSync();
   var platformComponent = loadComponentFromBytes(bytes);
   dillTarget.loader.appendLibraries(platformComponent, byteCount: bytes.length);
+  return platformComponent;
 }
 
 Future<void> compilePlatform(List<String> arguments) async {
diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
index 9d8b634..5b1356b 100644
--- a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
+++ b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
@@ -59,8 +59,9 @@
 // Instead modify 'tools/experimental_features.yaml' and run
 // 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
 
-  int defaultLanguageVersionMajor = $currentVersionMajor;
-  int defaultLanguageVersionMinor = $currentVersionMinor;
+import "ast.dart";
+
+Version defaultLanguageVersion = const Version($currentVersionMajor, $currentVersionMinor);
 ''');
 
   return new DartFormatter().format("$sb");
@@ -91,6 +92,8 @@
 //
 // Instead modify 'tools/experimental_features.yaml' and run
 // 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
+
+import 'package:kernel/kernel.dart' show Version;
 ''');
 
   Map<dynamic, dynamic> features = yaml['features'];
@@ -122,12 +125,9 @@
       major = int.parse(split[0]);
       minor = int.parse(split[1]);
     }
-    sb.writeln('  const int enable'
+    sb.writeln('  const Version enable'
         '${keyToIdentifier(key, upperCaseFirst: true)}'
-        'MajorVersion = $major;');
-    sb.writeln('  const int enable'
-        '${keyToIdentifier(key, upperCaseFirst: true)}'
-        'MinorVersion = $minor;');
+        'Version = const Version($major, $minor);');
   }
 
   sb.write('''
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 17ea976..6571a7a 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -58,9 +58,14 @@
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: false)
+  ..addFlag('tree-shake-write-only-fields',
+      help: 'Enable tree shaking of fields which are only written in AOT mode.',
+      defaultsTo: false)
   ..addFlag('protobuf-tree-shaker',
       help: 'Enable protobuf tree shaker transformation in AOT mode.',
       defaultsTo: false)
+  ..addFlag('minimal-kernel',
+      help: 'Produce minimal tree-shaken kernel file.', defaultsTo: false)
   ..addFlag('link-platform',
       help:
           'When in batch mode, link platform kernel file into result kernel file.'
@@ -162,7 +167,10 @@
   ..addOption('libraries-spec',
       help: 'A path or uri to the libraries specification JSON file')
   ..addFlag('debugger-module-names',
-      help: 'Use debugger-friendly modules names', defaultsTo: false);
+      help: 'Use debugger-friendly modules names', defaultsTo: false)
+  ..addOption('dartdevc-module-format',
+      help: 'The module format to use on for the dartdevc compiler',
+      defaultsTo: 'amd');
 
 String usage = '''
 Usage: server [options] [input.dart]
@@ -514,17 +522,19 @@
           useGlobalTypeFlowAnalysis: options['tfa'],
           environmentDefines: environmentDefines,
           enableAsserts: options['enable-asserts'],
-          useProtobufTreeShaker: options['protobuf-tree-shaker']));
+          useProtobufTreeShaker: options['protobuf-tree-shaker'],
+          minimalKernel: options['minimal-kernel'],
+          treeShakeWriteOnlyFields: options['tree-shake-write-only-fields']));
     }
     if (results.component != null) {
       transformer?.transform(results.component);
 
       if (_compilerOptions.target.name == 'dartdevc') {
-        await writeJavascriptBundle(
-            results, _kernelBinaryFilename, options['filesystem-scheme']);
+        await writeJavascriptBundle(results, _kernelBinaryFilename,
+            options['filesystem-scheme'], options['dartdevc-module-format']);
       }
       await writeDillFile(results, _kernelBinaryFilename,
-          filterExternal: importDill != null,
+          filterExternal: importDill != null || options['minimal-kernel'],
           incrementalSerializer: incrementalSerializer);
 
       _outputStream.writeln(boundaryKey);
@@ -591,7 +601,7 @@
 
   /// Write a JavaScript bundle containg the provided component.
   Future<void> writeJavascriptBundle(KernelCompilationResults results,
-      String filename, String fileSystemScheme) async {
+      String filename, String fileSystemScheme, String moduleFormat) async {
     var packageConfig = await loadPackageConfigUri(
         _compilerOptions.packagesFileUri ?? File('.packages').absolute.uri);
     final Component component = results.component;
@@ -609,7 +619,8 @@
     }
     _bundler = JavaScriptBundler(
         component, strongComponents, fileSystemScheme, packageConfig,
-        useDebuggerModuleNames: useDebuggerModuleNames);
+        useDebuggerModuleNames: useDebuggerModuleNames,
+        moduleFormat: moduleFormat);
     final sourceFileSink = sourceFile.openWrite();
     final manifestFileSink = manifestFile.openWrite();
     final sourceMapsFileSink = sourceMapsFile.openWrite();
@@ -853,8 +864,8 @@
         deltaProgram.uriToSource.keys);
 
     if (_compilerOptions.target.name == 'dartdevc') {
-      await writeJavascriptBundle(
-          results, _kernelBinaryFilename, _options['filesystem-scheme']);
+      await writeJavascriptBundle(results, _kernelBinaryFilename,
+          _options['filesystem-scheme'], _options['dartdevc-module-format']);
     } else {
       await writeDillFile(results, _kernelBinaryFilename,
           incrementalSerializer: _generator.incrementalSerializer);
@@ -902,46 +913,45 @@
       Map<String, String> jsFrameValues,
       String moduleName,
       String expression) async {
-    final String boundaryKey = Uuid().generateV4();
-    _outputStream.writeln('result $boundaryKey');
-
     _generator.accept();
     errors.clear();
 
-    if (_bundler != null) {
-      var kernel2jsCompiler = _bundler.compilers[moduleName];
-      if (kernel2jsCompiler == null) {
-        throw Exception('Cannot find kernel2js compiler for $moduleName. '
-            'Compilers are avaiable for modules: '
-            '\n\t${_bundler.compilers.keys.toString()}');
-      }
-      assert(kernel2jsCompiler != null);
+    if (_bundler == null) {
+      reportError('JavaScript bundler is null');
+      return;
+    }
+    if (!_bundler.compilers.containsKey(moduleName)) {
+      reportError('Cannot find kernel2js compiler for $moduleName.');
+      return;
+    }
 
-      var evaluator = new ExpressionCompiler(
-          _generator.generator, kernel2jsCompiler, _component,
-          verbose: _compilerOptions.verbose,
-          onDiagnostic: _compilerOptions.onDiagnostic);
+    final String boundaryKey = Uuid().generateV4();
+    _outputStream.writeln('result $boundaryKey');
 
-      var procedure = await evaluator.compileExpressionToJs(libraryUri, line,
-          column, jsModules, jsFrameValues, moduleName, expression);
+    var kernel2jsCompiler = _bundler.compilers[moduleName];
 
-      var result = errors.length > 0 ? errors[0] : procedure;
+    var evaluator = new ExpressionCompiler(
+        _generator.generator, kernel2jsCompiler, _component,
+        verbose: _compilerOptions.verbose,
+        onDiagnostic: _compilerOptions.onDiagnostic);
 
-      // TODO(annagrin): kernelBinaryFilename is too specific
-      // rename to _outputFileName?
-      await File(_kernelBinaryFilename).writeAsString(result);
+    var procedure = await evaluator.compileExpressionToJs(libraryUri, line,
+        column, jsModules, jsFrameValues, moduleName, expression);
 
-      _outputStream
-          .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
+    var result = errors.length > 0 ? errors[0] : procedure;
 
-      // TODO(annagrin): do we need to add asserts/error reporting if
-      // initial compilation didn't happen and _kernelBinaryFilename
-      // is different from below?
-      if (procedure != null) {
-        _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
-      }
-    } else {
-      _outputStream.writeln('$boundaryKey');
+    // TODO(annagrin): kernelBinaryFilename is too specific
+    // rename to _outputFileName?
+    await File(_kernelBinaryFilename).writeAsString(result);
+
+    _outputStream
+        .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
+
+    // TODO(annagrin): do we need to add asserts/error reporting if
+    // initial compilation didn't happen and _kernelBinaryFilename
+    // is different from below?
+    if (procedure != null) {
+      _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
     }
   }
 
diff --git a/pkg/frontend_server/lib/src/expression_compiler.dart b/pkg/frontend_server/lib/src/expression_compiler.dart
index 2902fc5..d104a7d 100644
--- a/pkg/frontend_server/lib/src/expression_compiler.dart
+++ b/pkg/frontend_server/lib/src/expression_compiler.dart
@@ -63,7 +63,7 @@
 }
 
 /// DartScopeBuilder finds dart scope information in
-/// [component] on a given [line]:
+/// [component] on a given 1-based [line]:
 /// library, class, locals, formals, and any other
 /// avaiable symbols at that location.
 /// TODO(annagrin): Refine scope detection
@@ -75,11 +75,13 @@
   Procedure _procedure;
   final List<FunctionNode> _functions = [];
   final int _line;
+  final int _column;
+  int _offset;
   final Set<String> _privateFields = {};
   final Map<String, DartType> _definitions = {};
   final List<TypeParameter> _typeParameters = [];
 
-  DartScopeBuilder(this._component, this._line);
+  DartScopeBuilder(this._component, this._line, this._column);
 
   DartScope build() {
     if (_library == null || _procedure == null) return null;
@@ -96,13 +98,14 @@
   @override
   void visitLibrary(Library library) {
     _library = library;
+    _offset = _component.getOffset(_library.fileUri, _line, _column);
 
     super.visitLibrary(library);
   }
 
   @override
   void visitClass(Class cls) {
-    if (_scopeContainsLine(cls.fileOffset, cls.fileEndOffset, _line)) {
+    if (_scopeContainsOffset(cls.fileOffset, cls.fileEndOffset, _offset)) {
       _cls = cls;
       _typeParameters.addAll(cls.typeParameters);
 
@@ -126,7 +129,7 @@
 
   @override
   void visitProcedure(Procedure p) {
-    if (_scopeContainsLine(p.fileOffset, p.fileEndOffset, _line)) {
+    if (_scopeContainsOffset(p.fileOffset, p.fileEndOffset, _offset)) {
       _procedure = p;
 
       super.visitProcedure(p);
@@ -135,7 +138,7 @@
 
   @override
   void visitFunctionNode(FunctionNode fun) {
-    if (_scopeContainsLine(fun.fileOffset, fun.fileEndOffset, _line)) {
+    if (_scopeContainsOffset(fun.fileOffset, fun.fileEndOffset, _offset)) {
       _collectDefinitions(fun);
       _typeParameters.addAll(fun.typeParameters);
 
@@ -171,20 +174,12 @@
     }
   }
 
-  // TODO(annagrin): use offset instead of line to find containing scope
-  // See [issue 40281](https://github.com/dart-lang/sdk/issues/40281)
-  bool _scopeContainsLine(int startOffset, int endOffset, int line) {
-    if (line < 0) return false;
+  static bool _scopeContainsOffset(int startOffset, int endOffset, int offset) {
+    if (offset < 0) return false;
     if (startOffset < 0) return false;
+    if (endOffset < 0) return false;
 
-    var startLine = _getLine(startOffset);
-    var endLine = _getLine(endOffset);
-
-    return line >= startLine && line <= endLine;
-  }
-
-  int _getLine(int offset) {
-    return _component.getLocation(_library.fileUri, offset).line;
+    return startOffset <= offset && offset <= endOffset;
   }
 }
 
@@ -246,6 +241,8 @@
   /// Compiles [expression] in [libraryUri] at [line]:[column] to JavaScript
   /// in [moduleName].
   ///
+  /// [line] and [column] are 1-based.
+  ///
   /// Values listed in [jsFrameValues] are substituted for their names in the
   /// [expression].
   ///
@@ -357,7 +354,7 @@
       return null;
     }
 
-    var builder = DartScopeBuilder(_component, line);
+    var builder = DartScopeBuilder(_component, line, column);
     library.accept(builder);
     var scope = builder.build();
     if (scope == null) {
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index 201d379f..98443f8 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.dart
@@ -25,8 +25,9 @@
 class JavaScriptBundler {
   JavaScriptBundler(this._originalComponent, this._strongComponents,
       this._fileSystemScheme, this._packageConfig,
-      {this.useDebuggerModuleNames = false})
-      : compilers = <String, ProgramCompiler>{} {
+      {this.useDebuggerModuleNames = false, String moduleFormat})
+      : compilers = <String, ProgramCompiler>{},
+        _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd') {
     _summaries = <Component>[];
     _summaryUris = <Uri>[];
     _moduleImportForSummary = <Uri, String>{};
@@ -58,6 +59,7 @@
   final PackageConfig _packageConfig;
   final bool useDebuggerModuleNames;
   final Map<String, ProgramCompiler> compilers;
+  final ModuleFormat _moduleFormat;
 
   List<Component> _summaries;
   List<Uri> _summaryUris;
@@ -149,7 +151,7 @@
       }
       final code = jsProgramToCode(
         jsModule,
-        ModuleFormat.amd,
+        _moduleFormat,
         inlineSourceMap: true,
         buildSourceMap: true,
         jsUrl: '$moduleUrl.lib.js',
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index c14c3b8..2effb3b 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -3,6 +3,9 @@
 # version: do-not-upload
 description: A resident kernel compiler
 
+environment:
+  sdk: "^2.7.0"
+
 dependencies:
   build_integration:
     path: ../build_integration
diff --git a/pkg/frontend_server/test/src/expression_compiler_test.dart b/pkg/frontend_server/test/src/expression_compiler_test.dart
index 4528537..996a103 100644
--- a/pkg/frontend_server/test/src/expression_compiler_test.dart
+++ b/pkg/frontend_server/test/src/expression_compiler_test.dart
@@ -50,6 +50,7 @@
 
   static CompilerOptions getOptions() {
     var options = CompilerOptions()
+      ..verbose = false // set to true for debugging
       ..sdkRoot = sdkRoot
       ..target = DevCompilerTarget(TargetFlags())
       ..librariesSpecificationUri = Uri.base.resolve('sdk/lib/libraries.json')
@@ -240,7 +241,7 @@
     for (int line = 0; line < lines.length; line++) {
       var content = lines[line];
       if (placeholderRegExp.firstMatch(content) != null) {
-        return line;
+        return line + 1;
       }
     }
     return -1;
@@ -259,7 +260,7 @@
           return ret;
         }
       }
-      main => 0;
+      main() => 0;
     ''';
 
     TestDriver driver;
@@ -331,6 +332,8 @@
           return x;
         }
       }
+
+      main() => 0;
       ''';
 
     TestDriver driver;
@@ -649,6 +652,8 @@
           return x;
         }
       }
+
+      main() => 0;
       ''';
 
     TestDriver driver;
@@ -825,6 +830,8 @@
           return x;
         }
       }
+
+      main() => 0;
       ''';
 
     TestDriver driver;
@@ -1192,6 +1199,8 @@
       outerClosure(3);
       return 0;
     }
+
+    main() => 0;
     ''';
 
     TestDriver driver;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index ce59c92..2b37b2c 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -68,12 +68,12 @@
 ```
 
 A string table consists of an array of end offsets and a payload array of
-strings encoded as UTF-8.  The array of end offsets maps a string index to the
+strings encoded as WTF-8.  The array of end offsets maps a string index to the
 offset of the _next_ string in the table or the offset of the end of the array
 for the last string.  These offsets are relative to the string payload array.
-Thus, string number 0 consists of the UTF-8 encoded string stretching from
+Thus, string number 0 consists of the WTF-8 encoded string stretching from
 offset 0 (inclusive) to endOffset[0] (exclusive); and string number N for N > 0
-consists of the UTF-8 encoded string stretching from offset endOffset[N-1]
+consists of the WTF-8 encoded string stretching from offset endOffset[N-1]
 (inclusive) to endOffset[N] (exclusive).
 
 ``` scala
@@ -143,7 +143,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 40;
+  UInt32 formatVersion = 42;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
   UriSource sourceMap;
@@ -180,6 +180,7 @@
   UInt32 binaryOffsetForStringTable;
   UInt32 binaryOffsetForConstantTable;
   UInt32 mainMethodReference; // This is a ProcedureReference with a fixed-size integer.
+  UInt32 compilationMode; // enum NonNullableByDefaultCompiledMode { Disabled = 0, Weak = 1, Strong = 2, Agnostic = 3 } with a fixed-size integer.
   UInt32[libraryCount + 1] libraryOffsets;
   UInt32 libraryCount;
   UInt32 componentFileSizeInBytes;
@@ -370,7 +371,7 @@
   FileOffset fileEndOffset;
   UInt flags (isFinal, isConst, isStatic, hasImplicitGetter, hasImplicitSetter,
                 isCovariant, isGenericCovariantImpl, isLate, isExtensionMember,
-                isNonNullableByDefault);
+                isNonNullableByDefault, isInternalImplementation);
   Name name;
   List<Expression> annotations;
   DartType type;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 846cd93..1437c1d 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -73,7 +73,8 @@
 import 'canonical_name.dart' show CanonicalName;
 export 'canonical_name.dart' show CanonicalName;
 
-import 'default_language_version.dart';
+import 'default_language_version.dart' show defaultLanguageVersion;
+export 'default_language_version.dart' show defaultLanguageVersion;
 
 import 'transformations/flags.dart';
 import 'text/ast_to_text.dart' as astToText;
@@ -353,18 +354,14 @@
   /// The URI of the source file this library was loaded from.
   Uri fileUri;
 
-  int _languageVersionMajor;
-  int _languageVersionMinor;
-  int get languageVersionMajor =>
-      _languageVersionMajor ?? defaultLanguageVersionMajor;
-  int get languageVersionMinor =>
-      _languageVersionMinor ?? defaultLanguageVersionMinor;
-  void setLanguageVersion(int languageVersionMajor, int languageVersionMinor) {
-    if (languageVersionMajor == null || languageVersionMinor == null) {
+  Version _languageVersion;
+  Version get languageVersion => _languageVersion ?? defaultLanguageVersion;
+
+  void setLanguageVersion(Version languageVersion) {
+    if (languageVersion == null) {
       throw new StateError("Trying to set language version 'null'");
     }
-    _languageVersionMajor = languageVersionMajor;
-    _languageVersionMinor = languageVersionMinor;
+    _languageVersion = languageVersion;
   }
 
   static const int SyntheticFlag = 1 << 1;
@@ -1739,6 +1736,7 @@
   static const int FlagLate = 1 << 7;
   static const int FlagExtensionMember = 1 << 8;
   static const int FlagNonNullableByDefault = 1 << 9;
+  static const int FlagInternalImplementation = 1 << 10;
 
   /// Whether the field is declared with the `covariant` keyword.
   bool get isCovariant => flags & FlagCovariant != 0;
@@ -1780,6 +1778,13 @@
   /// Whether the field is declared with the `late` keyword.
   bool get isLate => flags & FlagLate != 0;
 
+  // If `true` this field is not part of the interface but only part of the
+  // class members.
+  //
+  // This is `true` for instance for synthesized fields added for the late
+  // lowering.
+  bool get isInternalImplementation => flags & FlagInternalImplementation != 0;
+
   void set isCovariant(bool value) {
     flags = value ? (flags | FlagCovariant) : (flags & ~FlagCovariant);
   }
@@ -1823,6 +1828,12 @@
     flags = value ? (flags | FlagLate) : (flags & ~FlagLate);
   }
 
+  void set isInternalImplementation(bool value) {
+    flags = value
+        ? (flags | FlagInternalImplementation)
+        : (flags & ~FlagInternalImplementation);
+  }
+
   /// True if the field is neither final nor const.
   bool get isMutable => flags & (FlagFinal | FlagConst) == 0;
   bool get isInstanceMember => !isStatic;
@@ -7922,7 +7933,23 @@
 
   @override
   String toStringInternal() {
-    return "";
+    StringBuffer sb = new StringBuffer();
+    if (_verboseTypeToString) {
+      sb.write(className.toStringInternal());
+    } else {
+      sb.write(classNode.name);
+    }
+    if (typeArguments.isNotEmpty) {
+      sb.write("<");
+      String comma = "";
+      for (DartType typeArgument in typeArguments) {
+        sb.write(comma);
+        sb.write(typeArgument.toStringInternal());
+        comma = ", ";
+      }
+      sb.write(">");
+    }
+    return sb.toString();
   }
 }
 
@@ -8417,7 +8444,14 @@
       <String, MetadataRepository<dynamic>>{};
 
   /// Reference to the main method in one of the libraries.
-  Reference mainMethodName;
+  Reference _mainMethodName;
+  Reference get mainMethodName => _mainMethodName;
+  NonNullableByDefaultCompiledMode _mode;
+  NonNullableByDefaultCompiledMode get mode {
+    return _mode ?? NonNullableByDefaultCompiledMode.Disabled;
+  }
+
+  NonNullableByDefaultCompiledMode get modeRaw => _mode;
 
   Component(
       {CanonicalName nameRoot,
@@ -8501,8 +8535,12 @@
 
   Procedure get mainMethod => mainMethodName?.asProcedure;
 
-  void set mainMethod(Procedure main) {
-    mainMethodName = getMemberReference(main);
+  void setMainMethodAndMode(Reference main, bool overwriteMainIfSet,
+      NonNullableByDefaultCompiledMode mode) {
+    if (_mainMethodName == null || overwriteMainIfSet) {
+      _mainMethodName = main;
+    }
+    _mode = mode;
   }
 
   R accept<R>(TreeVisitor<R> v) => v.visitComponent(this);
@@ -8523,6 +8561,15 @@
     return uriToSource[file]?.getLocation(file, offset);
   }
 
+  /// Translates line and column numbers to an offset in the given file.
+  ///
+  /// Returns offset of the line and column in the file, or -1 if the
+  /// source is not available or has no lines.
+  /// Throws [RangeError] if line or calculated offset are out of range.
+  int getOffset(Uri file, int line, int column) {
+    return uriToSource[file]?.getOffset(line, column) ?? -1;
+  }
+
   void addMetadataRepository(MetadataRepository repository) {
     metadata[repository.tag] = repository;
   }
@@ -8768,7 +8815,7 @@
     throw "Internal error";
   }
 
-  /// Translates an offset to line and column numbers in the given file.
+  /// Translates an offset to 1-based line and column numbers in the given file.
   Location getLocation(Uri file, int offset) {
     if (lineStarts == null || lineStarts.isEmpty) {
       return new Location(file, TreeNode.noOffset, TreeNode.noOffset);
@@ -8790,6 +8837,21 @@
     int columnNumber = 1 + offset - lineStart;
     return new Location(file, lineNumber, columnNumber);
   }
+
+  /// Translates 1-based line and column numbers to an offset in the given file
+  ///
+  /// Returns offset of the line and column in the file, or -1 if the source
+  /// has no lines.
+  /// Throws [RangeError] if line or calculated offset are out of range.
+  int getOffset(int line, int column) {
+    if (lineStarts == null || lineStarts.isEmpty) {
+      return -1;
+    }
+    RangeError.checkValueInInterval(line, 1, lineStarts.length, 'line');
+    var offset = lineStarts[line - 1] + column - 1;
+    RangeError.checkValueInInterval(offset, 0, lineStarts.last, 'offset');
+    return offset;
+  }
 }
 
 /// Returns the [Reference] object for the given member.
@@ -9044,3 +9106,65 @@
   }
   return result;
 }
+
+class Version extends Object {
+  final int major;
+  final int minor;
+
+  const Version(this.major, this.minor)
+      : assert(major != null),
+        assert(minor != null);
+
+  bool operator <(Version other) {
+    if (major < other.major) return true;
+    if (major > other.major) return false;
+
+    // Major is the same.
+    if (minor < other.minor) return true;
+    return false;
+  }
+
+  bool operator <=(Version other) {
+    if (major < other.major) return true;
+    if (major > other.major) return false;
+
+    // Major is the same.
+    if (minor <= other.minor) return true;
+    return false;
+  }
+
+  bool operator >(Version other) {
+    if (major > other.major) return true;
+    if (major < other.major) return false;
+
+    // Major is the same.
+    if (minor > other.minor) return true;
+    return false;
+  }
+
+  bool operator >=(Version other) {
+    if (major > other.major) return true;
+    if (major < other.major) return false;
+
+    // Major is the same.
+    if (minor >= other.minor) return true;
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return major.hashCode * 13 + minor.hashCode * 17;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! Version) return false;
+    return major == other.major && minor == other.minor;
+  }
+
+  @override
+  String toString() {
+    return "Version(major=$major, minor=$minor)";
+  }
+}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index aabfcf0..df48c44 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -4,7 +4,6 @@
 library kernel.ast_from_binary;
 
 import 'dart:core' hide MapEntry;
-import 'dart:convert';
 import 'dart:developer';
 import 'dart:typed_data';
 
@@ -34,6 +33,12 @@
   }
 }
 
+class CompilationModeError {
+  final String message;
+
+  CompilationModeError(this.message);
+}
+
 class CanonicalNameError {
   final String message;
 
@@ -45,7 +50,7 @@
 }
 
 class _ComponentIndex {
-  static const numberOfFixedFields = 9;
+  static const numberOfFixedFields = 10;
 
   int binaryOffsetForSourceTable;
   int binaryOffsetForCanonicalNames;
@@ -54,6 +59,7 @@
   int binaryOffsetForStringTable;
   int binaryOffsetForConstantTable;
   int mainMethodReference;
+  NonNullableByDefaultCompiledMode compiledMode;
   List<int> libraryOffsets;
   int libraryCount;
   int componentFileSizeInBytes;
@@ -85,6 +91,7 @@
   int _transformerFlags = 0;
   Library _currentLibrary;
   int _componentStartOffset = 0;
+  NonNullableByDefaultCompiledMode compilationMode;
 
   // If something goes wrong, this list should indicate what library,
   // class, and member was being built.
@@ -163,36 +170,74 @@
     return _doubleBuffer[0];
   }
 
-  List<int> readBytes(int length) {
-    List<int> bytes = new Uint8List(length);
+  Uint8List readBytes(int length) {
+    Uint8List bytes = new Uint8List(length);
     bytes.setRange(0, bytes.length, _bytes, _byteOffset);
     _byteOffset += bytes.length;
     return bytes;
   }
 
-  List<int> readByteList() {
+  Uint8List readByteList() {
     return readBytes(readUInt());
   }
 
+  String readString() {
+    return readStringEntry(readUInt());
+  }
+
   String readStringEntry(int numBytes) {
-    // Utf8Decoder will skip leading BOM characters, but we must preserve them.
-    // Collect leading BOMs before passing the bytes onto Utf8Decoder.
-    int numByteOrderMarks = 0;
-    while (_byteOffset + 2 < _bytes.length &&
-        _bytes[_byteOffset] == 0xef &&
-        _bytes[_byteOffset + 1] == 0xbb &&
-        _bytes[_byteOffset + 2] == 0xbf) {
-      ++numByteOrderMarks;
-      _byteOffset += 3;
-      numBytes -= 3;
+    int start = _byteOffset;
+    int end = start + numBytes;
+    _byteOffset = end;
+    for (int i = start; i < end; i++) {
+      if (_bytes[i] > 127) {
+        return _decodeWtf8(start, end);
+      }
     }
-    String string = const Utf8Decoder()
-        .convert(_bytes, _byteOffset, _byteOffset + numBytes);
-    _byteOffset += numBytes;
-    if (numByteOrderMarks > 0) {
-      return '\ufeff' * numByteOrderMarks + string;
+    return new String.fromCharCodes(_bytes, start, end);
+  }
+
+  String _decodeWtf8(int start, int end) {
+    // WTF-8 decoder that trusts its input, meaning that the correctness of
+    // the code depends on the bytes from start to end being valid and
+    // complete WTF-8. Instead of masking off the control bits from every
+    // byte, it simply xor's the byte values together at their appropriate
+    // bit shifts, and then xor's out all of the control bits at once.
+    Uint16List charCodes = new Uint16List(end - start);
+    int i = start;
+    int j = 0;
+    while (i < end) {
+      int byte = _bytes[i++];
+      if (byte < 0x80) {
+        // ASCII.
+        charCodes[j++] = byte;
+      } else if (byte < 0xE0) {
+        // Two-byte sequence (11-bit unicode value).
+        int byte2 = _bytes[i++];
+        int value = (byte << 6) ^ byte2 ^ 0x3080;
+        assert(value >= 0x80 && value < 0x800);
+        charCodes[j++] = value;
+      } else if (byte < 0xF0) {
+        // Three-byte sequence (16-bit unicode value).
+        int byte2 = _bytes[i++];
+        int byte3 = _bytes[i++];
+        int value = (byte << 12) ^ (byte2 << 6) ^ byte3 ^ 0xE2080;
+        assert(value >= 0x800 && value < 0x10000);
+        charCodes[j++] = value;
+      } else {
+        // Four-byte sequence (non-BMP unicode value).
+        int byte2 = _bytes[i++];
+        int byte3 = _bytes[i++];
+        int byte4 = _bytes[i++];
+        int value =
+            (byte << 18) ^ (byte2 << 12) ^ (byte3 << 6) ^ byte4 ^ 0x3C82080;
+        assert(value >= 0x10000 && value < 0x110000);
+        charCodes[j++] = 0xD7C0 + (value >> 10);
+        charCodes[j++] = 0xDC00 + (value & 0x3FF);
+      }
     }
-    return string;
+    assert(i == end);
+    return new String.fromCharCodes(charCodes, 0, j);
   }
 
   /// Read metadataMappings section from the binary.
@@ -214,7 +259,7 @@
     for (int i = 0; i < length; ++i) {
       endOffsets[i] = readUInt();
     }
-    // Read the UTF-8 encoded strings.
+    // Read the WTF-8 encoded strings.
     table.length = length;
     int startOffset = 0;
     for (int i = 0; i < length; ++i) {
@@ -621,6 +666,7 @@
     result.binaryOffsetForStringTable = _componentStartOffset + readUint32();
     result.binaryOffsetForConstantTable = _componentStartOffset + readUint32();
     result.mainMethodReference = readUint32();
+    result.compiledMode = NonNullableByDefaultCompiledMode.values[readUint32()];
     for (int i = 0; i < result.libraryCount + 1; ++i) {
       result.libraryOffsets[i] = _componentStartOffset + readUint32();
     }
@@ -675,6 +721,24 @@
 
     // Read component index from the end of this ComponentFiles serialized data.
     _ComponentIndex index = _readComponentIndex(componentFileSize);
+    if (compilationMode == null) {
+      compilationMode = component.modeRaw;
+    }
+    if (compilationMode == null) {
+      compilationMode = index.compiledMode;
+    } else if (compilationMode != index.compiledMode) {
+      if (compilationMode == NonNullableByDefaultCompiledMode.Agnostic) {
+        compilationMode = index.compiledMode;
+      } else if (index.compiledMode ==
+          NonNullableByDefaultCompiledMode.Agnostic) {
+        // Keep as-is.
+      } else {
+        // Mixed mode where agnostic isn't involved.
+        throw new CompilationModeError(
+            "Mixed compilation mode found: $compilationMode "
+            "and ${index.compiledMode}.");
+      }
+    }
 
     _byteOffset = index.binaryOffsetForStringTable;
     readStringTable(_stringTable);
@@ -711,9 +775,9 @@
       }
     }
 
-    var mainMethod =
+    Reference mainMethod =
         getMemberReferenceFromInt(index.mainMethodReference, allowNull: true);
-    component.mainMethodName ??= mainMethod;
+    component.setMainMethodAndMode(mainMethod, false, compilationMode);
 
     _byteOffset = _componentStartOffset + componentFileSize;
 
@@ -729,7 +793,7 @@
     List<String> strings =
         new List<String>.filled(length, null, growable: true);
     for (int i = 0; i < length; i++) {
-      String s = const Utf8Decoder().convert(readByteList());
+      String s = readString();
       strings[i] = s;
     }
     return strings;
@@ -742,12 +806,10 @@
     _sourceUriTable.length = length;
     Map<Uri, Source> uriToSource = <Uri, Source>{};
     for (int i = 0; i < length; ++i) {
-      List<int> uriBytes = readByteList();
-      Uri uri = uriBytes.isEmpty
-          ? null
-          : Uri.parse(const Utf8Decoder().convert(uriBytes));
+      String uriString = readString();
+      Uri uri = uriString.isEmpty ? null : Uri.parse(uriString);
       _sourceUriTable[i] = uri;
-      List<int> sourceCode = readByteList();
+      Uint8List sourceCode = readByteList();
       int lineCount = readUInt();
       List<int> lineStarts = new List<int>(lineCount);
       int previousLineStart = 0;
@@ -756,10 +818,9 @@
         lineStarts[j] = lineStart;
         previousLineStart = lineStart;
       }
-      List<int> importUriBytes = readByteList();
-      Uri importUri = importUriBytes.isEmpty
-          ? null
-          : Uri.parse(const Utf8Decoder().convert(importUriBytes));
+      String importUriString = readString();
+      Uri importUri =
+          importUriString.isEmpty ? null : Uri.parse(importUriString);
       uriToSource[uri] = new Source(lineStarts, sourceCode, importUri, uri);
     }
 
@@ -899,7 +960,8 @@
     List<String> problemsAsJson = readListOfStrings();
 
     library.flags = flags;
-    library.setLanguageVersion(languageVersionMajor, languageVersionMinor);
+    library.setLanguageVersion(
+        new Version(languageVersionMajor, languageVersionMinor));
     library.name = name;
     library.fileUri = fileUri;
     library.problemsAsJson = problemsAsJson;
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index dbdee4d..c481d69 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -4,7 +4,6 @@
 library kernel.ast_to_binary;
 
 import 'dart:core' hide MapEntry;
-import 'dart:convert' show utf8;
 import 'dart:developer';
 import 'dart:io' show BytesBuilder;
 import 'dart:typed_data';
@@ -105,9 +104,9 @@
         (value >> 8) & 0xFF, value & 0xFF);
   }
 
-  void writeByteList(List<int> utf8Bytes) {
-    writeUInt30(utf8Bytes.length);
-    writeBytes(utf8Bytes);
+  void writeByteList(List<int> bytes) {
+    writeUInt30(bytes.length);
+    writeBytes(bytes);
   }
 
   int getBufferOffset() {
@@ -117,7 +116,7 @@
   void writeStringTable(StringIndexer indexer) {
     _binaryOffsetForStringTable = getBufferOffset();
 
-    // Containers for the utf8 encoded strings.
+    // Containers for the WTF-8 encoded strings.
     final List<Uint8List> data = new List<Uint8List>();
     int totalLength = 0;
     const int minLength = 1 << 16;
@@ -141,24 +140,13 @@
             index = 0;
             buffer = new Uint8List(newLength);
           }
-          newIndex = NotQuiteString.writeUtf8(buffer, index, key);
+          newIndex = _writeWtf8(buffer, index, key);
           if (newIndex != -1) break;
           requiredMinLength = allocateMinLength;
         }
-        if (newIndex < 0) {
-          // Utf8 encoding failed.
-          if (buffer != null && index > 0) {
-            data.add(new Uint8List.view(buffer.buffer, 0, index));
-            buffer = null;
-            index = 0;
-          }
-          List<int> converted = utf8.encoder.convert(key);
-          data.add(converted);
-          totalLength += converted.length;
-        } else {
-          totalLength += newIndex - index;
-          index = newIndex;
-        }
+        assert(newIndex >= 0);
+        totalLength += newIndex - index;
+        index = newIndex;
       }
       writeUInt30(totalLength);
     }
@@ -166,7 +154,7 @@
       data.add(Uint8List.view(buffer.buffer, 0, index));
     }
 
-    // Write the UTF-8 encoded strings.
+    // Write the WTF-8 encoded strings.
     for (int i = 0; i < data.length; ++i) {
       writeBytes(data[i]);
     }
@@ -586,9 +574,7 @@
     if (strings != null) {
       for (int i = 0; i < strings.length; i++) {
         String s = strings[i];
-        // This is slow, but we expect there to in general be no problems. If this
-        // turns out to be wrong we can optimize it as we do URLs for instance.
-        writeByteList(utf8.encoder.convert(s));
+        outputStringViaBuffer(s, new Uint8List(s.length * 3));
       }
     }
   }
@@ -730,7 +716,7 @@
     const int kernelFileAlignment = 8;
 
     // Keep this in sync with number of writeUInt32 below.
-    int numComponentIndexEntries = 7 + libraryOffsets.length + 3;
+    int numComponentIndexEntries = 8 + libraryOffsets.length + 3;
 
     int unalignedSize = getBufferOffset() + numComponentIndexEntries * 4;
     int padding =
@@ -760,6 +746,7 @@
     } else {
       writeUInt32(main.index + 1);
     }
+    writeUInt32(component.mode.index);
 
     assert(libraryOffsets.length == libraries.length);
     for (int offset in libraryOffsets) {
@@ -819,21 +806,16 @@
     }
   }
 
-  void outputStringViaBuffer(String uriAsString, Uint8List buffer) {
-    if (uriAsString.length * 3 < buffer.length) {
-      int length = NotQuiteString.writeUtf8(buffer, 0, uriAsString);
-      if (length < 0) {
-        // Utf8 encoding failed.
-        writeByteList(utf8.encoder.convert(uriAsString));
-      } else {
-        writeUInt30(length);
-        for (int j = 0; j < length; j++) {
-          writeByte(buffer[j]);
-        }
+  void outputStringViaBuffer(String s, Uint8List buffer) {
+    int length = _writeWtf8(buffer, 0, s);
+    if (length >= 0) {
+      writeUInt30(length);
+      for (int j = 0; j < length; j++) {
+        writeByte(buffer[j]);
       }
     } else {
       // Uncommon case with very long url.
-      writeByteList(utf8.encoder.convert(uriAsString));
+      outputStringViaBuffer(s, new Uint8List(s.length * 3));
     }
   }
 
@@ -954,8 +936,8 @@
     libraryOffsets.add(getBufferOffset());
     writeByte(node.flags);
 
-    writeUInt30(node.languageVersionMajor);
-    writeUInt30(node.languageVersionMinor);
+    writeUInt30(node.languageVersion.major);
+    writeUInt30(node.languageVersion.minor);
 
     writeNonNullCanonicalNameReference(getCanonicalNameOfLibrary(node));
     writeStringReference(node.name ?? '');
@@ -2757,63 +2739,58 @@
   }
 }
 
-class NotQuiteString {
-  /**
-   * Write [source] string into [target] starting at index [index].
-   *
-   * Optionally only write part of the input [source] starting at [start] and
-   * ending at [end].
-   *
-   * The output space needed is at most [source.length] * 3.
-   *
-   * Returns
-   *  * Non-negative on success (the new index in [target]).
-   *  * -1 when [target] doesn't have enough space. Note that [target] can be
-   *    polluted starting at [index].
-   *  * -2 on input error, i.e. an unpaired lead or tail surrogate.
-   */
-  static int writeUtf8(List<int> target, int index, String source,
-      [int start = 0, int end]) {
-    RangeError.checkValidIndex(index, target, null, target.length);
-    end = RangeError.checkValidRange(start, end, source.length);
-    if (start == end) return index;
-    int i = start;
-    int length = target.length;
-    do {
-      int codeUnit = source.codeUnitAt(i++);
-      while (codeUnit < 128) {
-        if (index >= length) return -1;
-        target[index++] = codeUnit;
-        if (i >= end) return index;
-        codeUnit = source.codeUnitAt(i++);
-      }
-      if (codeUnit < 0x800) {
-        index += 2;
-        if (index > length) return -1;
-        target[index - 2] = 0xC0 | (codeUnit >> 6);
-        target[index - 1] = 0x80 | (codeUnit & 0x3f);
-      } else if (codeUnit & 0xF800 != 0xD800) {
-        // Not a surrogate.
-        index += 3;
-        if (index > length) return -1;
-        target[index - 3] = 0xE0 | (codeUnit >> 12);
-        target[index - 2] = 0x80 | ((codeUnit >> 6) & 0x3f);
-        target[index - 1] = 0x80 | (codeUnit & 0x3f);
-      } else {
-        if (codeUnit >= 0xDC00) return -2; // Unpaired tail surrogate.
-        if (i >= end) return -2; // Unpaired lead surrogate.
-        int nextChar = source.codeUnitAt(i++);
-        if (nextChar & 0xFC00 != 0xDC00) return -2; // Unpaired lead surrogate.
-        index += 4;
-        if (index > length) return -1;
-        codeUnit = (codeUnit & 0x3FF) + 0x40;
-        target[index - 4] = 0xF0 | (codeUnit >> 8);
-        target[index - 3] = 0x80 | ((codeUnit >> 2) & 0x3F);
-        target[index - 2] =
-            0x80 | (((codeUnit & 3) << 4) | ((nextChar & 0x3FF) >> 6));
-        target[index - 1] = 0x80 | (nextChar & 0x3f);
-      }
-    } while (i < end);
-    return index;
-  }
+/**
+ * Write [source] string into [target] starting at index [index].
+ *
+ * The output space needed is at most [source.length] * 3.
+ *
+ * Returns
+ *  * Non-negative on success (the new index in [target]).
+ *  * -1 when [target] doesn't have enough space. Note that [target] can be
+ *    polluted starting at [index].
+ */
+int _writeWtf8(Uint8List target, int index, String source) {
+  int end = source.length;
+  if (end == 0) return index;
+  int length = target.length;
+  assert(index <= length);
+  int i = 0;
+  do {
+    int codeUnit = source.codeUnitAt(i++);
+    while (codeUnit < 128) {
+      // ASCII.
+      if (index >= length) return -1;
+      target[index++] = codeUnit;
+      if (i >= end) return index;
+      codeUnit = source.codeUnitAt(i++);
+    }
+    if (codeUnit < 0x800) {
+      // Two-byte sequence (11-bit unicode value).
+      index += 2;
+      if (index > length) return -1;
+      target[index - 2] = 0xC0 | (codeUnit >> 6);
+      target[index - 1] = 0x80 | (codeUnit & 0x3f);
+    } else if ((codeUnit & 0xFC00) == 0xD800 &&
+        i < end &&
+        (source.codeUnitAt(i) & 0xFC00) == 0xDC00) {
+      // Surrogate pair -> four-byte sequence (non-BMP unicode value).
+      index += 4;
+      if (index > length) return -1;
+      int codeUnit2 = source.codeUnitAt(i++);
+      int unicode = 0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF);
+      target[index - 4] = 0xF0 | (unicode >> 18);
+      target[index - 3] = 0x80 | ((unicode >> 12) & 0x3F);
+      target[index - 2] = 0x80 | ((unicode >> 6) & 0x3F);
+      target[index - 1] = 0x80 | (unicode & 0x3F);
+    } else {
+      // Three-byte sequence (16-bit unicode value), including lone
+      // surrogates.
+      index += 3;
+      if (index > length) return -1;
+      target[index - 3] = 0xE0 | (codeUnit >> 12);
+      target[index - 2] = 0x80 | ((codeUnit >> 6) & 0x3f);
+      target[index - 1] = 0x80 | (codeUnit & 0x3f);
+    }
+  } while (i < end);
+  return index;
 }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index a18adf3..cec2308 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -149,7 +149,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 = 40;
+  static const int BinaryFormatVersion = 42;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 9d460d4..8bbae44 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -23,8 +23,36 @@
   void infer(ClassHierarchy hierarchy, Class classNode);
 }
 
+/// Core interface for answering queries needed to compute the subtyping
+/// relation.
+abstract class ClassHierarchyBase {
+  CoreTypes get coreTypes;
+
+  /// Returns the instantiation of [superclass] that is implemented by [type],
+  /// or `null` if [type] does not implement [superclass] at all.
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
+      Library clientLibrary, CoreTypes coreTypes);
+
+  /// Returns the type arguments of the instantiation of [superclass] that is
+  /// implemented by [type], or `null` if [type] does not implement [superclass]
+  /// at all.
+  List<DartType> getTypeArgumentsAsInstanceOf(
+      InterfaceType type, Class superclass);
+
+  /// Returns the possibly abstract interface member of [class_] with the given
+  /// [name].
+  ///
+  /// If [setter] is `false`, only fields, methods, and getters with that name
+  /// will be found.  If [setter] is `true`, only non-final fields and setters
+  /// will be found.
+  ///
+  /// If multiple members with that name are inherited and not overridden, the
+  /// member from the first declared supertype is returned.
+  Member getInterfaceMember(Class class_, Name name, {bool setter: false});
+}
+
 /// Interface for answering various subclassing queries.
-abstract class ClassHierarchy {
+abstract class ClassHierarchy implements ClassHierarchyBase {
   factory ClassHierarchy(Component component, CoreTypes coreTypes,
       {HandleAmbiguousSupertypes onAmbiguousSupertypes,
       MixinInferrer mixinInferrer}) {
@@ -77,17 +105,6 @@
   Supertype getClassAsInstanceOf(Class class_, Class superclass);
 
   /// Returns the instantiation of [superclass] that is implemented by [type],
-  /// or `null` if [type] does not implement [superclass] at all.
-  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
-      Library clientLibrary, CoreTypes coreTypes);
-
-  /// Returns the type arguments of the instantiation of [superclass] that is
-  /// implemented by [type], or `null` if [type] does not implement [superclass]
-  /// at all.
-  List<DartType> getTypeArgumentsAsInstanceOf(
-      InterfaceType type, Class superclass);
-
-  /// Returns the instantiation of [superclass] that is implemented by [type],
   /// or `null` if [type] does not implement [superclass].  [superclass] must
   /// be a generic class.
   Supertype asInstantiationOf(Supertype type, Class superclass);
@@ -119,17 +136,6 @@
   /// The returned list should not be modified.
   List<Member> getDispatchTargets(Class class_, {bool setters: false});
 
-  /// Returns the possibly abstract interface member of [class_] with the given
-  /// [name].
-  ///
-  /// If [setter] is `false`, only fields, methods, and getters with that name
-  /// will be found.  If [setter] is `true`, only non-final fields and setters
-  /// will be found.
-  ///
-  /// If multiple members with that name are inherited and not overridden, the
-  /// member from the first declared supertype is returned.
-  Member getInterfaceMember(Class class_, Name name, {bool setter: false});
-
   /// Returns the list of members denoting the interface for [class_], which
   /// may include abstract members.
   ///
@@ -198,8 +204,10 @@
   ///
   /// Note, that it is the clients responsibility to mark all subclasses as
   /// changed too.
+  // TODO(johnniwinther): Support class hierarchy changes directly. Currently
+  // we can handle added superclasses but not removed superclasses.
   ClassHierarchy applyTreeChanges(Iterable<Library> removedLibraries,
-      Iterable<Library> ensureKnownLibraries,
+      Iterable<Library> ensureKnownLibraries, Iterable<Class> updatedClasses,
       {Component reissueAmbiguousSupertypesFor});
 
   /// This method is invoked by the client after a member change on classes:
@@ -795,30 +803,61 @@
 
   @override
   ClassHierarchy applyTreeChanges(Iterable<Library> removedLibraries,
-      Iterable<Library> ensureKnownLibraries,
+      Iterable<Library> ensureKnownLibraries, Iterable<Class> updatedClasses,
       {Component reissueAmbiguousSupertypesFor}) {
+    Set<_ClassInfo> changedClasses = <_ClassInfo>{};
+
+    void removeClass(Class cls) {
+      _ClassInfo info = _infoMap[cls];
+      if (info == null) return;
+      if (cls.supertype != null) {
+        _infoMap[cls.supertype.classNode]?.directExtenders?.remove(info);
+      }
+      if (cls.mixedInType != null) {
+        _infoMap[cls.mixedInType.classNode]?.directMixers?.remove(info);
+      }
+      for (Supertype supertype in cls.implementedTypes) {
+        _infoMap[supertype.classNode]?.directImplementers?.remove(info);
+        // Remove from directMixers too as the mixin transformation will
+        // "move" the type here.
+        if (cls.isAnonymousMixin || cls.isEliminatedMixin) {
+          _infoMap[supertype.classNode]?.directMixers?.remove(info);
+        }
+      }
+      _infoMap.remove(cls);
+      _recordedAmbiguousSupertypes.remove(cls);
+    }
+
+    void invalidateClass(_ClassInfo info) {
+      if (info == null) return;
+      if (!changedClasses.add(info)) return;
+      if (info.directExtenders != null) {
+        for (_ClassInfo i in info.directExtenders.toList()) {
+          invalidateClass(i);
+        }
+      }
+      if (info.directMixers != null) {
+        for (_ClassInfo i in info.directMixers.toList()) {
+          invalidateClass(i);
+        }
+      }
+      if (info.directImplementers != null) {
+        for (_ClassInfo i in info.directImplementers.toList()) {
+          invalidateClass(i);
+        }
+      }
+      removeClass(info.classNode);
+    }
+
+    for (Class cls in updatedClasses) {
+      invalidateClass(_infoMap[cls]);
+    }
+
     // Remove all references to the removed classes.
     for (Library lib in removedLibraries) {
       if (!knownLibraries.contains(lib)) continue;
       for (Class class_ in lib.classes) {
-        _ClassInfo info = _infoMap[class_];
-        if (class_.supertype != null) {
-          _infoMap[class_.supertype.classNode]?.directExtenders?.remove(info);
-        }
-        if (class_.mixedInType != null) {
-          _infoMap[class_.mixedInType.classNode]?.directMixers?.remove(info);
-        }
-        for (Supertype supertype in class_.implementedTypes) {
-          _infoMap[supertype.classNode]?.directImplementers?.remove(info);
-          // Remove from directMixers too as the mixin transformation will
-          // "move" the type here.
-          if (class_.isAnonymousMixin || class_.isEliminatedMixin) {
-            _infoMap[supertype.classNode]?.directMixers?.remove(info);
-          }
-        }
-
-        _infoMap.remove(class_);
-        _recordedAmbiguousSupertypes.remove(class_);
+        removeClass(class_);
       }
       knownLibraries.remove(lib);
     }
@@ -854,6 +893,10 @@
       }
       knownLibraries.add(lib);
     }
+    for (_ClassInfo info in changedClasses) {
+      _topologicalSortVisit(info.classNode, new Set<Class>(),
+          orderedList: addedClassesSorted);
+    }
     _initializeTopologicallySortedClasses(
         addedClassesSorted, expectedStartIndex);
 
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index bb3dd53..1ebce70 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -79,6 +79,7 @@
   Class _asyncAwaitCompleterClass;
   Class _futureOrClass;
   Constructor _asyncAwaitCompleterConstructor;
+  Procedure _asyncAwaitCompleterStartProcedure;
   Procedure _completeOnAsyncReturnProcedure;
   Procedure _completerCompleteError;
   Constructor _syncIterableDefaultConstructor;
@@ -261,6 +262,11 @@
         index.getMember('dart:async', '_AsyncAwaitCompleter', '');
   }
 
+  Procedure get asyncAwaitCompleterStartProcedure {
+    return _asyncAwaitCompleterStartProcedure ??=
+        index.getMember('dart:async', '_AsyncAwaitCompleter', 'start');
+  }
+
   Member get completeOnAsyncReturn {
     return _completeOnAsyncReturnProcedure ??=
         index.getTopLevelMember('dart:async', '_completeOnAsyncReturn');
diff --git a/pkg/kernel/lib/default_language_version.dart b/pkg/kernel/lib/default_language_version.dart
index 73670a5..4aa2488 100644
--- a/pkg/kernel/lib/default_language_version.dart
+++ b/pkg/kernel/lib/default_language_version.dart
@@ -7,5 +7,6 @@
 // Instead modify 'tools/experimental_features.yaml' and run
 // 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
 
-int defaultLanguageVersionMajor = 2;
-int defaultLanguageVersionMinor = 8;
+import "ast.dart";
+
+Version defaultLanguageVersion = const Version(2, 9);
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index e18a1125..ef93768 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -131,6 +131,13 @@
   /// but it additionally accounts for parameter covariance.
   String _checkFunctionOverride(
       Class host, Member ownMember, Member superMember) {
+    if (ownMember is Procedure &&
+        (ownMember.isMemberSignature ||
+            (ownMember.isForwardingStub && !ownMember.isForwardingSemiStub))) {
+      // Synthesized members are not obligated to override super members.
+      return null;
+    }
+
     final FunctionNode ownFunction = ownMember.function;
     final FunctionNode superFunction = superMember.function;
     Substitution ownSubstitution = _makeSubstitutionForMember(host, ownMember);
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index c1ea1f8..4e48572 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -30,6 +30,8 @@
 
 import '../visitor.dart' show DartTypeVisitor, DartTypeVisitor1;
 
+import 'legacy_erasure.dart';
+
 class TypeVariableGraph extends Graph<int> {
   List<int> vertices;
   List<TypeParameter> typeParameters;
@@ -257,6 +259,7 @@
 // TODO(dmitryas):  Remove [typedefInstantiations] when type arguments passed to
 // typedefs are preserved in the Kernel output.
 List<TypeArgumentIssue> findTypeArgumentIssues(
+    Library library,
     DartType type,
     TypeEnvironment typeEnvironment,
     SubtypeCheckMode subtypeCheckMode,
@@ -281,7 +284,7 @@
         requiredParameterCount: functionType.requiredParameterCount,
         typedefType: null);
     typedefRhsResult = findTypeArgumentIssues(
-        cloned, typeEnvironment, subtypeCheckMode, bottomType,
+        library, cloned, typeEnvironment, subtypeCheckMode, bottomType,
         allowSuperBounded: true);
     type = functionType.typedefType;
   }
@@ -295,25 +298,25 @@
   } else if (type is FunctionType) {
     List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
     for (TypeParameter parameter in type.typeParameters) {
-      result.addAll(findTypeArgumentIssues(
-              parameter.bound, typeEnvironment, subtypeCheckMode, bottomType,
+      result.addAll(findTypeArgumentIssues(library, parameter.bound,
+              typeEnvironment, subtypeCheckMode, bottomType,
               allowSuperBounded: true) ??
           const <TypeArgumentIssue>[]);
     }
     for (DartType formal in type.positionalParameters) {
       result.addAll(findTypeArgumentIssues(
-              formal, typeEnvironment, subtypeCheckMode, bottomType,
+              library, formal, typeEnvironment, subtypeCheckMode, bottomType,
               allowSuperBounded: true) ??
           const <TypeArgumentIssue>[]);
     }
     for (NamedType named in type.namedParameters) {
-      result.addAll(findTypeArgumentIssues(
-              named.type, typeEnvironment, subtypeCheckMode, bottomType,
+      result.addAll(findTypeArgumentIssues(library, named.type, typeEnvironment,
+              subtypeCheckMode, bottomType,
               allowSuperBounded: true) ??
           const <TypeArgumentIssue>[]);
     }
-    result.addAll(findTypeArgumentIssues(
-            type.returnType, typeEnvironment, subtypeCheckMode, bottomType,
+    result.addAll(findTypeArgumentIssues(library, type.returnType,
+            typeEnvironment, subtypeCheckMode, bottomType,
             allowSuperBounded: true) ??
         const <TypeArgumentIssue>[]);
     return result.isEmpty ? null : result;
@@ -334,19 +337,21 @@
       // Generic function types aren't allowed as type arguments either.
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(i, argument, variables[i], type));
-    } else if (variables[i].bound is! InvalidType &&
-        !typeEnvironment.isSubtypeOf(
-            argument,
-            substitute(variables[i].bound, substitutionMap),
-            subtypeCheckMode)) {
-      // If the bound is InvalidType it's not checked, because an error was
-      // reported already at the time of the creation of InvalidType.
-      result ??= <TypeArgumentIssue>[];
-      result.add(new TypeArgumentIssue(i, argument, variables[i], type));
+    } else if (variables[i].bound is! InvalidType) {
+      DartType bound = substitute(variables[i].bound, substitutionMap);
+      if (!library.isNonNullableByDefault) {
+        bound = legacyErasure(typeEnvironment.coreTypes, bound);
+      }
+      if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) {
+        // If the bound is InvalidType it's not checked, because an error was
+        // reported already at the time of the creation of InvalidType.
+        result ??= <TypeArgumentIssue>[];
+        result.add(new TypeArgumentIssue(i, argument, variables[i], type));
+      }
     }
 
     List<TypeArgumentIssue> issues = findTypeArgumentIssues(
-        argument, typeEnvironment, subtypeCheckMode, bottomType,
+        library, argument, typeEnvironment, subtypeCheckMode, bottomType,
         allowSuperBounded: true);
     if (issues != null) {
       argumentsResult ??= <TypeArgumentIssue>[];
@@ -413,6 +418,7 @@
 // TODO(dmitryas):  Remove [typedefInstantiations] when type arguments passed to
 // typedefs are preserved in the Kernel output.
 List<TypeArgumentIssue> findTypeArgumentIssuesForInvocation(
+    Library library,
     List<TypeParameter> parameters,
     List<DartType> arguments,
     TypeEnvironment typeEnvironment,
@@ -436,14 +442,19 @@
       // Generic function types aren't allowed as type arguments either.
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
-    } else if (!typeEnvironment.isSubtypeOf(argument,
-        substitute(parameters[i].bound, substitutionMap), subtypeCheckMode)) {
-      result ??= <TypeArgumentIssue>[];
-      result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
+    } else if (parameters[i].bound is! InvalidType) {
+      DartType bound = substitute(parameters[i].bound, substitutionMap);
+      if (!library.isNonNullableByDefault) {
+        bound = legacyErasure(typeEnvironment.coreTypes, bound);
+      }
+      if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) {
+        result ??= <TypeArgumentIssue>[];
+        result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
+      }
     }
 
     List<TypeArgumentIssue> issues = findTypeArgumentIssues(
-        argument, typeEnvironment, subtypeCheckMode, bottomType,
+        library, argument, typeEnvironment, subtypeCheckMode, bottomType,
         allowSuperBounded: true);
     if (issues != null) {
       result ??= <TypeArgumentIssue>[];
diff --git a/pkg/kernel/lib/src/hierarchy_based_type_environment.dart b/pkg/kernel/lib/src/hierarchy_based_type_environment.dart
index 2384e50..eadc8fa 100644
--- a/pkg/kernel/lib/src/hierarchy_based_type_environment.dart
+++ b/pkg/kernel/lib/src/hierarchy_based_type_environment.dart
@@ -6,17 +6,17 @@
 
 import '../ast.dart' show Class, DartType, InterfaceType, Library, Member, Name;
 
-import '../class_hierarchy.dart' show ClassHierarchy;
+import '../class_hierarchy.dart' show ClassHierarchyBase;
 
 import '../core_types.dart' show CoreTypes;
 
 import '../type_environment.dart' show TypeEnvironment;
 
 class HierarchyBasedTypeEnvironment extends TypeEnvironment {
-  final ClassHierarchy hierarchy;
+  final ClassHierarchyBase hierarchy;
 
   HierarchyBasedTypeEnvironment(CoreTypes coreTypes, this.hierarchy)
-      : super.fromSubclass(coreTypes);
+      : super.fromSubclass(coreTypes, hierarchy);
 
   @override
   InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
diff --git a/pkg/kernel/lib/src/nnbd_top_merge.dart b/pkg/kernel/lib/src/nnbd_top_merge.dart
index 317b1df..f0c5b4e 100644
--- a/pkg/kernel/lib/src/nnbd_top_merge.dart
+++ b/pkg/kernel/lib/src/nnbd_top_merge.dart
@@ -55,8 +55,8 @@
         // NNBD_TOP_MERGE(Object?, dynamic) = Object?
         return coreTypes.objectNullableRawType;
       } else if (b is VoidType) {
-        // NNBD_TOP_MERGE(Object?, void) = void
-        return const VoidType();
+        // NNBD_TOP_MERGE(Object?, void) = Object?
+        return coreTypes.objectNullableRawType;
       } else if (b == coreTypes.objectNullableRawType) {
         // NNBD_TOP_MERGE(Object?, Object?) = Object?
         return coreTypes.objectNullableRawType;
@@ -66,8 +66,8 @@
         // NNBD_TOP_MERGE(Object*, dynamic) = Object?
         return coreTypes.objectNullableRawType;
       } else if (b is VoidType) {
-        // NNBD_TOP_MERGE(Object*, void) = void
-        return const VoidType();
+        // NNBD_TOP_MERGE(Object*, void) = Object?
+        return coreTypes.objectNullableRawType;
       }
     } else if (a == coreTypes.nullType &&
         b is NeverType &&
@@ -81,17 +81,17 @@
   @override
   DartType visitVoidType(VoidType a, DartType b) {
     if (b is DynamicType) {
-      // NNBD_TOP_MERGE(void, dynamic) = void
-      return const VoidType();
+      // NNBD_TOP_MERGE(void, dynamic) = Object?
+      return coreTypes.objectNullableRawType;
     } else if (b is VoidType) {
       // NNBD_TOP_MERGE(void, void) = void
       return const VoidType();
     } else if (b == coreTypes.objectNullableRawType) {
-      // NNBD_TOP_MERGE(void, Object?) = void
-      return const VoidType();
+      // NNBD_TOP_MERGE(void, Object?) = Object?
+      return coreTypes.objectNullableRawType;
     } else if (b == coreTypes.objectLegacyRawType) {
-      // NNBD_TOP_MERGE(void, Object*) = void
-      return const VoidType();
+      // NNBD_TOP_MERGE(void, Object*) = Object?
+      return coreTypes.objectNullableRawType;
     }
     return null;
   }
@@ -102,8 +102,8 @@
       // NNBD_TOP_MERGE(dynamic, dynamic) = dynamic
       return const DynamicType();
     } else if (b is VoidType) {
-      // NNBD_TOP_MERGE(dynamic, void) = void
-      return const VoidType();
+      // NNBD_TOP_MERGE(dynamic, void) = Object?
+      return coreTypes.objectNullableRawType;
     } else if (b == coreTypes.objectNullableRawType) {
       // NNBD_TOP_MERGE(dynamic, Object?) = Object?
       return coreTypes.objectNullableRawType;
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
new file mode 100644
index 0000000..af97773
--- /dev/null
+++ b/pkg/kernel/lib/src/types.dart
@@ -0,0 +1,965 @@
+// 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 '../ast.dart'
+    show
+        BottomType,
+        Class,
+        DartType,
+        DynamicType,
+        FunctionType,
+        InterfaceType,
+        InvalidType,
+        Library,
+        NamedType,
+        NeverType,
+        Nullability,
+        TypeParameter,
+        TypeParameterType,
+        TypedefType,
+        Variance,
+        VoidType;
+
+import '../class_hierarchy.dart' show ClassHierarchyBase;
+
+import '../core_types.dart' show CoreTypes;
+
+import '../type_algebra.dart'
+    show Substitution, combineNullabilitiesForSubstitution;
+
+import '../type_environment.dart' show IsSubtypeOf, SubtypeCheckMode;
+
+import 'future_or.dart';
+
+class Types {
+  final ClassHierarchyBase hierarchy;
+
+  Types(this.hierarchy);
+
+  bool _isSubtypeFromMode(IsSubtypeOf isSubtypeOf, SubtypeCheckMode mode) {
+    switch (mode) {
+      case SubtypeCheckMode.withNullabilities:
+        return isSubtypeOf.isSubtypeWhenUsingNullabilities();
+      case SubtypeCheckMode.ignoringNullabilities:
+        return isSubtypeOf.isSubtypeWhenIgnoringNullabilities();
+      default:
+        throw new StateError("Unhandled subtype checking mode '$mode'");
+    }
+  }
+
+  /// Returns true if [s] is a subtype of [t].
+  bool isSubtypeOf(DartType s, DartType t, SubtypeCheckMode mode) {
+    IsSubtypeOf result = performNullabilityAwareSubtypeCheck(s, t);
+    return _isSubtypeFromMode(result, mode);
+  }
+
+  /// Can be use to collect type checks. To use:
+  /// 1. Rename `performNullabilityAwareSubtypeCheck` to
+  ///    `_performNullabilityAwareSubtypeCheck`.
+  /// 2. Rename `_collect_performNullabilityAwareSubtypeCheck` to
+  ///    `performNullabilityAwareSubtypeCheck`.
+  /// 3. Comment out the call to `_performNullabilityAwareSubtypeCheck` below.
+  // ignore:unused_element
+  bool _collect_performNullabilityAwareSubtypeCheck(
+      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
+    IsSubtypeOf result = const IsSubtypeOf.always();
+    //result = _performNullabilityAwareSubtypeCheck(subtype, supertype, mode);
+    bool booleanResult = _isSubtypeFromMode(result, mode);
+    typeChecksForTesting ??= <Object>[];
+    typeChecksForTesting.add([subtype, supertype, booleanResult]);
+    return booleanResult;
+  }
+
+  IsSubtypeOf performNullabilityAwareSubtypeCheck(DartType s, DartType t) {
+    // TODO(johnniwinther,dmitryas): Ensure complete handling of InvalidType in
+    // the subtype relation.
+    if (s is InvalidType || t is InvalidType) {
+      return const IsSubtypeOf.always();
+    }
+
+    if (s is BottomType) {
+      return const IsSubtypeOf.always(); // Rule 3.
+    }
+    if (t is DynamicType) {
+      return const IsSubtypeOf.always(); // Rule 2.
+    }
+    if (t is VoidType) {
+      return const IsSubtypeOf.always(); // Rule 2.
+    }
+    if (t is BottomType) {
+      return const IsSubtypeOf.never();
+    }
+    if (s is NeverType) {
+      return new IsSubtypeOf.basedSolelyOnNullabilities(
+          s, t, hierarchy.coreTypes.futureOrClass);
+    }
+
+    if (t is InterfaceType) {
+      Class cls = t.classNode;
+      if (cls == hierarchy.coreTypes.objectClass &&
+          !(s is InterfaceType &&
+              s.classNode == hierarchy.coreTypes.futureOrClass)) {
+        return new IsSubtypeOf.basedSolelyOnNullabilities(
+            s, t, hierarchy.coreTypes.futureOrClass);
+      }
+      if (cls == hierarchy.coreTypes.futureOrClass) {
+        const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
+        if (s is DynamicType) {
+          return relation.isDynamicRelated(s, t, this);
+        } else if (s is VoidType) {
+          return relation.isVoidRelated(s, t, this);
+        } else if (s is InterfaceType) {
+          return s.classNode == hierarchy.coreTypes.futureOrClass
+              ? relation.isFutureOrRelated(s, t, this)
+              : relation.isInterfaceRelated(s, t, this);
+        } else if (s is FunctionType) {
+          return relation.isFunctionRelated(s, t, this);
+        } else if (s is TypeParameterType) {
+          return s.promotedBound == null
+              ? relation.isTypeParameterRelated(s, t, this)
+              : relation.isIntersectionRelated(s, t, this);
+        } else if (s is TypedefType) {
+          return relation.isTypedefRelated(s, t, this);
+        }
+      } else {
+        const IsInterfaceSubtypeOf relation = const IsInterfaceSubtypeOf();
+        if (s is DynamicType) {
+          return relation.isDynamicRelated(s, t, this);
+        } else if (s is VoidType) {
+          return relation.isVoidRelated(s, t, this);
+        } else if (s is InterfaceType) {
+          return s.classNode == hierarchy.coreTypes.futureOrClass
+              ? relation.isFutureOrRelated(s, t, this)
+              : relation.isInterfaceRelated(s, t, this);
+        } else if (s is FunctionType) {
+          return relation.isFunctionRelated(s, t, this);
+        } else if (s is TypeParameterType) {
+          return s.promotedBound == null
+              ? relation.isTypeParameterRelated(s, t, this)
+              : relation.isIntersectionRelated(s, t, this);
+        } else if (s is TypedefType) {
+          return relation.isTypedefRelated(s, t, this);
+        }
+      }
+    } else if (t is FunctionType) {
+      const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
+      if (s is DynamicType) {
+        return relation.isDynamicRelated(s, t, this);
+      } else if (s is VoidType) {
+        return relation.isVoidRelated(s, t, this);
+      } else if (s is InterfaceType) {
+        return s.classNode == hierarchy.coreTypes.futureOrClass
+            ? relation.isFutureOrRelated(s, t, this)
+            : relation.isInterfaceRelated(s, t, this);
+      } else if (s is FunctionType) {
+        return relation.isFunctionRelated(s, t, this);
+      } else if (s is TypeParameterType) {
+        return s.promotedBound == null
+            ? relation.isTypeParameterRelated(s, t, this)
+            : relation.isIntersectionRelated(s, t, this);
+      } else if (s is TypedefType) {
+        return relation.isTypedefRelated(s, t, this);
+      }
+    } else if (t is TypeParameterType) {
+      if (t.promotedBound == null) {
+        const IsTypeParameterSubtypeOf relation =
+            const IsTypeParameterSubtypeOf();
+        if (s is DynamicType) {
+          return relation.isDynamicRelated(s, t, this);
+        } else if (s is VoidType) {
+          return relation.isVoidRelated(s, t, this);
+        } else if (s is InterfaceType) {
+          return s.classNode == hierarchy.coreTypes.futureOrClass
+              ? relation.isFutureOrRelated(s, t, this)
+              : relation.isInterfaceRelated(s, t, this);
+        } else if (s is FunctionType) {
+          return relation.isFunctionRelated(s, t, this);
+        } else if (s is TypeParameterType) {
+          return s.promotedBound == null
+              ? relation.isTypeParameterRelated(s, t, this)
+              : relation.isIntersectionRelated(s, t, this);
+        } else if (s is TypedefType) {
+          return relation.isTypedefRelated(s, t, this);
+        }
+      } else {
+        const IsIntersectionSubtypeOf relation =
+            const IsIntersectionSubtypeOf();
+        if (s is DynamicType) {
+          return relation.isDynamicRelated(s, t, this);
+        } else if (s is VoidType) {
+          return relation.isVoidRelated(s, t, this);
+        } else if (s is InterfaceType) {
+          return s.classNode == hierarchy.coreTypes.futureOrClass
+              ? relation.isFutureOrRelated(s, t, this)
+              : relation.isInterfaceRelated(s, t, this);
+        } else if (s is FunctionType) {
+          return relation.isFunctionRelated(s, t, this);
+        } else if (s is TypeParameterType) {
+          return s.promotedBound == null
+              ? relation.isTypeParameterRelated(s, t, this)
+              : relation.isIntersectionRelated(s, t, this);
+        } else if (s is TypedefType) {
+          return relation.isTypedefRelated(s, t, this);
+        }
+      }
+    } else if (t is TypedefType) {
+      const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
+      if (s is DynamicType) {
+        return relation.isDynamicRelated(s, t, this);
+      } else if (s is VoidType) {
+        return relation.isVoidRelated(s, t, this);
+      } else if (s is InterfaceType) {
+        return s.classNode == hierarchy.coreTypes.futureOrClass
+            ? relation.isFutureOrRelated(s, t, this)
+            : relation.isInterfaceRelated(s, t, this);
+      } else if (s is FunctionType) {
+        return relation.isFunctionRelated(s, t, this);
+      } else if (s is TypeParameterType) {
+        return s.promotedBound == null
+            ? relation.isTypeParameterRelated(s, t, this)
+            : relation.isIntersectionRelated(s, t, this);
+      } else if (s is TypedefType) {
+        return relation.isTypedefRelated(s, t, this);
+      }
+    } else if (t is NeverType) {
+      const IsNeverTypeSubtypeOf relation = const IsNeverTypeSubtypeOf();
+      if (s is DynamicType) {
+        return relation.isDynamicRelated(s, t, this);
+      } else if (s is VoidType) {
+        return relation.isVoidRelated(s, t, this);
+      } else if (s is InterfaceType) {
+        return relation.isInterfaceRelated(s, t, this);
+      } else if (s is FunctionType) {
+        return relation.isFunctionRelated(s, t, this);
+      } else if (s is TypeParameterType) {
+        return s.promotedBound == null
+            ? relation.isTypeParameterRelated(s, t, this)
+            : relation.isIntersectionRelated(s, t, this);
+      } else if (s is TypedefType) {
+        return relation.isTypedefRelated(s, t, this);
+      }
+    } else {
+      throw "Unhandled type: ${t.runtimeType}";
+    }
+    throw "Unhandled type combination: ${t.runtimeType} ${s.runtimeType}";
+  }
+
+  /// Returns true if all type arguments in [s] and [t] pairwise are subtypes
+  /// with respect to the variance of the corresponding [p] type parameter.
+  IsSubtypeOf areTypeArgumentsOfSubtypeKernel(
+      List<DartType> s, List<DartType> t, List<TypeParameter> p) {
+    if (s.length != t.length || s.length != p.length) {
+      throw "Numbers of type arguments don't match $s $t with parameters $p.";
+    }
+    IsSubtypeOf result = const IsSubtypeOf.always();
+    for (int i = 0; i < s.length; i++) {
+      int variance = p[i].variance;
+      if (variance == Variance.contravariant) {
+        result = result.and(performNullabilityAwareSubtypeCheck(t[i], s[i]));
+        if (!result.isSubtypeWhenIgnoringNullabilities()) {
+          return const IsSubtypeOf.never();
+        }
+      } else if (variance == Variance.invariant) {
+        result =
+            result.and(performNullabilityAwareMutualSubtypesCheck(s[i], t[i]));
+        if (!result.isSubtypeWhenIgnoringNullabilities()) {
+          return const IsSubtypeOf.never();
+        }
+      } else {
+        result = result.and(performNullabilityAwareSubtypeCheck(s[i], t[i]));
+        if (!result.isSubtypeWhenIgnoringNullabilities()) {
+          return const IsSubtypeOf.never();
+        }
+      }
+    }
+    return result;
+  }
+
+  static List<Object> typeChecksForTesting;
+
+  Class get futureOrClass => hierarchy.coreTypes.futureOrClass;
+
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
+      Library clientLibrary, CoreTypes coreTypes) {
+    return hierarchy.getTypeAsInstanceOf(
+        type, superclass, clientLibrary, coreTypes);
+  }
+
+  List<DartType> getTypeArgumentsAsInstanceOf(
+      InterfaceType type, Class superclass) {
+    return hierarchy.getTypeArgumentsAsInstanceOf(type, superclass);
+  }
+
+  bool isTop(DartType type) {
+    return type is DynamicType ||
+        type is VoidType ||
+        type == hierarchy.coreTypes.objectLegacyRawType ||
+        type == hierarchy.coreTypes.objectNullableRawType;
+  }
+
+  IsSubtypeOf performNullabilityAwareMutualSubtypesCheck(
+      DartType type1, DartType type2) {
+    return performNullabilityAwareSubtypeCheck(type1, type2)
+        .andSubtypeCheckFor(type2, type1, this);
+  }
+}
+
+abstract class TypeRelation<T extends DartType> {
+  const TypeRelation();
+
+  IsSubtypeOf isDynamicRelated(DynamicType s, T t, Types types);
+
+  IsSubtypeOf isVoidRelated(VoidType s, T t, Types types);
+
+  IsSubtypeOf isInterfaceRelated(InterfaceType s, T t, Types types);
+
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, T t, Types types);
+
+  IsSubtypeOf isFunctionRelated(FunctionType s, T t, Types types);
+
+  IsSubtypeOf isFutureOrRelated(InterfaceType futureOr, T t, Types types);
+
+  IsSubtypeOf isTypeParameterRelated(TypeParameterType s, T t, Types types);
+
+  IsSubtypeOf isTypedefRelated(TypedefType s, T t, Types types);
+}
+
+class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
+  const IsInterfaceSubtypeOf();
+
+  @override
+  IsSubtypeOf isInterfaceRelated(
+      InterfaceType s, InterfaceType t, Types types) {
+    if (s.classNode == types.hierarchy.coreTypes.nullClass) {
+      // This is an optimization, to avoid instantiating unnecessary type
+      // arguments in getKernelTypeAsInstanceOf.
+      return new IsSubtypeOf.basedSolelyOnNullabilities(
+          s, t, types.hierarchy.coreTypes.futureOrClass);
+    }
+    List<DartType> asSupertypeArguments =
+        types.hierarchy.getTypeArgumentsAsInstanceOf(s, t.classNode);
+    if (asSupertypeArguments == null) {
+      return const IsSubtypeOf.never();
+    }
+    return types
+        .areTypeArgumentsOfSubtypeKernel(
+            asSupertypeArguments, t.typeArguments, t.classNode.typeParameters)
+        .and(new IsSubtypeOf.basedSolelyOnNullabilities(
+            s, t, types.hierarchy.coreTypes.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, InterfaceType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s.parameter.bound, t).and(
+        new IsSubtypeOf.basedSolelyOnNullabilities(
+            s, t, types.hierarchy.coreTypes.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType futureOr, InterfaceType t, Types types) {
+    List<DartType> arguments = futureOr.typeArguments;
+    // Rules 7.1 and 7.2.
+    return types
+        .performNullabilityAwareSubtypeCheck(arguments.single, t)
+        .andSubtypeCheckFor(
+            new InterfaceType(types.hierarchy.coreTypes.futureClass,
+                Nullability.nonNullable, arguments),
+            t,
+            types)
+        .and(new IsSubtypeOf.basedSolelyOnNullabilities(
+            futureOr, t, types.hierarchy.coreTypes.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, InterfaceType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(
+        intersection.promotedBound, t); // Rule 12.
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(DynamicType s, InterfaceType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFunctionRelated(FunctionType s, InterfaceType t, Types types) {
+    return t.classNode == types.hierarchy.coreTypes.functionClass
+        ? new IsSubtypeOf.basedSolelyOnNullabilities(
+            s, t, types.hierarchy.coreTypes.futureOrClass)
+        : const IsSubtypeOf.never(); // Rule 14.
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(TypedefType s, InterfaceType t, Types types) {
+    // Rule 5.
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, t).and(
+        new IsSubtypeOf.basedSolelyOnNullabilities(
+            s, t, types.hierarchy.coreTypes.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(VoidType s, InterfaceType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+}
+
+class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
+  const IsFunctionSubtypeOf();
+
+  @override
+  IsSubtypeOf isFunctionRelated(FunctionType s, FunctionType t, Types types) {
+    List<TypeParameter> sTypeVariables = s.typeParameters;
+    List<TypeParameter> tTypeVariables = t.typeParameters;
+    if (sTypeVariables.length != tTypeVariables.length) {
+      return const IsSubtypeOf.never();
+    }
+    IsSubtypeOf result = const IsSubtypeOf.always();
+    if (sTypeVariables.isNotEmpty) {
+      // If the function types have type variables, we alpha-rename the type
+      // variables of [s] to use those of [t].
+
+      // As an optimization, we first check if the bounds of the type variables
+      // of the two types on the same positions are mutual subtypes without
+      // alpha-renaming them.
+      List<DartType> typeVariableSubstitution = <DartType>[];
+      for (int i = 0; i < sTypeVariables.length; i++) {
+        TypeParameter sTypeVariable = sTypeVariables[i];
+        TypeParameter tTypeVariable = tTypeVariables[i];
+        result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
+            sTypeVariable.bound, tTypeVariable.bound));
+        typeVariableSubstitution.add(new TypeParameterType.forAlphaRenaming(
+            sTypeVariable, tTypeVariable));
+      }
+      Substitution substitution =
+          Substitution.fromPairs(sTypeVariables, typeVariableSubstitution);
+      // If the bounds aren't the same, we need to try again after computing the
+      // substitution of type variables.
+      if (!result.isSubtypeWhenIgnoringNullabilities()) {
+        result = const IsSubtypeOf.always();
+        for (int i = 0; i < sTypeVariables.length; i++) {
+          TypeParameter sTypeVariable = sTypeVariables[i];
+          TypeParameter tTypeVariable = tTypeVariables[i];
+          result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
+              substitution.substituteType(sTypeVariable.bound),
+              tTypeVariable.bound));
+          if (!result.isSubtypeWhenIgnoringNullabilities()) {
+            return const IsSubtypeOf.never();
+          }
+        }
+      }
+      s = substitution.substituteType(s.withoutTypeParameters);
+    }
+    result = result.and(
+        types.performNullabilityAwareSubtypeCheck(s.returnType, t.returnType));
+    if (!result.isSubtypeWhenIgnoringNullabilities()) {
+      return const IsSubtypeOf.never();
+    }
+    List<DartType> sPositional = s.positionalParameters;
+    List<DartType> tPositional = t.positionalParameters;
+    if (s.requiredParameterCount > t.requiredParameterCount) {
+      // Rule 15, n1 <= n2.
+      return const IsSubtypeOf.never();
+    }
+    if (sPositional.length < tPositional.length) {
+      // Rule 15, n1 + k1 >= n2 + k2.
+      return const IsSubtypeOf.never();
+    }
+    for (int i = 0; i < tPositional.length; i++) {
+      result = result.and(types.performNullabilityAwareSubtypeCheck(
+          tPositional[i], sPositional[i]));
+      if (!result.isSubtypeWhenIgnoringNullabilities()) {
+        // Rule 15, Tj <: Sj.
+        return const IsSubtypeOf.never();
+      }
+    }
+    List<NamedType> sNamed = s.namedParameters;
+    List<NamedType> tNamed = t.namedParameters;
+    if (sNamed.isNotEmpty || tNamed.isNotEmpty) {
+      // Rule 16, the number of positional parameters must be the same.
+      if (sPositional.length != tPositional.length) {
+        return const IsSubtypeOf.never();
+      }
+      if (s.requiredParameterCount != t.requiredParameterCount) {
+        return const IsSubtypeOf.never();
+      }
+
+      // Rule 16, the parameter names of [t] must be a subset of those of
+      // [s]. Also, for the intersection, the type of the parameter of [t] must
+      // be a subtype of the type of the parameter of [s].
+      int sCount = 0;
+      for (int tCount = 0; tCount < tNamed.length; tCount++) {
+        String name = tNamed[tCount].name;
+        for (; sCount < sNamed.length; sCount++) {
+          if (sNamed[sCount].name == name) break;
+        }
+        if (sCount == sNamed.length) return const IsSubtypeOf.never();
+        result = result.and(types.performNullabilityAwareSubtypeCheck(
+            tNamed[tCount].type, sNamed[sCount].type));
+        if (!result.isSubtypeWhenIgnoringNullabilities()) {
+          return const IsSubtypeOf.never();
+        }
+      }
+    }
+    return result.and(
+        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isInterfaceRelated(InterfaceType s, FunctionType t, Types types) {
+    if (s.classNode == types.hierarchy.coreTypes.nullClass) {
+      // Rule 4.
+      return new IsSubtypeOf.basedSolelyOnNullabilities(
+          s, t, types.futureOrClass);
+    }
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(DynamicType s, FunctionType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType futureOr, FunctionType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, FunctionType t, Types types) {
+    // Rule 12.
+    return types.performNullabilityAwareSubtypeCheck(
+        intersection.promotedBound, t);
+  }
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, FunctionType t, Types types) {
+    // Rule 13.
+    return types.performNullabilityAwareSubtypeCheck(s.parameter.bound, t).and(
+        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(TypedefType s, FunctionType t, Types types) {
+    // Rule 5.
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(VoidType s, FunctionType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+}
+
+class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
+  const IsTypeParameterSubtypeOf();
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, TypeParameterType t, Types types) {
+    IsSubtypeOf result = const IsSubtypeOf.always();
+    if (s.parameter != t.parameter) {
+      result = types.performNullabilityAwareSubtypeCheck(s.bound, t);
+    }
+    if (s.nullability == Nullability.undetermined &&
+        t.nullability == Nullability.undetermined) {
+      // The two nullabilities are undetermined, but are connected via
+      // additional constraint, namely that they will be equal at run time.
+      return result;
+    }
+    return result.and(
+        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, TypeParameterType t, Types types) {
+    // Nullable types aren't promoted to intersection types.
+    // TODO(dmitryas): Uncomment the following when the inference is updated.
+    //assert(intersection.typeParameterTypeNullability != Nullability.nullable);
+
+    // Rule 8.
+    if (intersection.parameter == t.parameter) {
+      if (intersection.nullability == Nullability.undetermined &&
+          t.nullability == Nullability.undetermined) {
+        // The two nullabilities are undetermined, but are connected via
+        // additional constraint, namely that they will be equal at run time.
+        return const IsSubtypeOf.always();
+      }
+      return new IsSubtypeOf.basedSolelyOnNullabilities(
+          intersection, t, types.futureOrClass);
+    }
+
+    // Rule 12.
+    return types.performNullabilityAwareSubtypeCheck(
+        intersection.promotedBound.withNullability(intersection.nullability),
+        t);
+  }
+
+  @override
+  IsSubtypeOf isInterfaceRelated(
+      InterfaceType s, TypeParameterType t, Types types) {
+    if (s.classNode == types.hierarchy.coreTypes.nullClass) {
+      // Rule 4.
+      return new IsSubtypeOf.basedSolelyOnNullabilities(
+          s, t, types.futureOrClass);
+    }
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(
+      DynamicType s, TypeParameterType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFunctionRelated(
+      FunctionType s, TypeParameterType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType futureOr, TypeParameterType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(
+      TypedefType s, TypeParameterType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(VoidType s, TypeParameterType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+}
+
+class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
+  const IsTypedefSubtypeOf();
+
+  @override
+  IsSubtypeOf isInterfaceRelated(InterfaceType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(DynamicType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isFunctionRelated(FunctionType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType futureOr, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(futureOr, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(intersection, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(TypedefType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, t.unalias);
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(VoidType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
+  }
+}
+
+class IsFutureOrSubtypeOf extends TypeRelation<InterfaceType> {
+  const IsFutureOrSubtypeOf();
+
+  @override
+  IsSubtypeOf isInterfaceRelated(
+      InterfaceType s, InterfaceType futureOr, Types types) {
+    List<DartType> arguments = futureOr.typeArguments;
+
+    Nullability unitedNullability = computeNullabilityOfFutureOr(
+        futureOr, types.hierarchy.coreTypes.futureOrClass);
+
+    return types
+        // Rule 11.
+        .performNullabilityAwareSubtypeCheck(
+            s, arguments.single.withNullability(unitedNullability))
+        // Rule 10.
+        .orSubtypeCheckFor(
+            s,
+            new InterfaceType(types.hierarchy.coreTypes.futureClass,
+                unitedNullability, arguments),
+            types);
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType sFutureOr, InterfaceType tFutureOr, Types types) {
+    // This follows from combining rules 7, 10, and 11.
+    DartType sArgument = sFutureOr.typeArguments.single;
+    DartType tArgument = tFutureOr.typeArguments.single;
+    DartType sFutureOfArgument = new InterfaceType(
+        types.hierarchy.coreTypes.futureClass,
+        Nullability.nonNullable,
+        sFutureOr.typeArguments);
+    DartType tFutureOfArgument = new InterfaceType(
+        types.hierarchy.coreTypes.futureClass,
+        Nullability.nonNullable,
+        tFutureOr.typeArguments);
+    Nullability sNullability = computeNullabilityOfFutureOr(
+        sFutureOr, types.hierarchy.coreTypes.futureOrClass);
+    Nullability tNullability = computeNullabilityOfFutureOr(
+        tFutureOr, types.hierarchy.coreTypes.futureOrClass);
+    // The following is an optimized is-subtype-of test for the case where
+    // both LHS and RHS are FutureOrs.  It's based on the following:
+    // FutureOr<X> <: FutureOr<Y> iff X <: Y OR (X <: Future<Y> AND
+    // Future<X> <: Y).
+    //
+    // The correctness of that can be shown as follows:
+    //   1. FutureOr<X> <: FutureOr<Y> iff
+    //
+    //          X <: FutureOr<Y> AND Future<X> <: FutureOr<Y>
+    //
+    //   2a. X <: FutureOr<Y> iff
+    //
+    //          X <: Y OR X <: Future<Y>
+    //
+    //   2b. Future<X> <: FutureOr<Y> iff
+    //
+    //          Future<X> <: Y OR Future<X> <: Future<Y>
+    //
+    //   3. 1,2a,2b => FutureOr<X> <: FutureOr<Y> iff
+    //
+    //          (X <: Y OR X <: Future<Y>) AND
+    //            (Future<X> <: Y OR Future<X> <: Future<Y>)
+    //
+    //   4. X <: Y iff Future<X> <: Future<Y>
+    //
+    //   5. 3,4 => FutureOr<X> <: FutureOr<Y> iff
+    //
+    //          (X <: Y OR X <: Future<Y>) AND
+    //            (X <: Y OR Future<X> <: Y) iff
+    //
+    //          X <: Y OR (X <: Future<Y> AND Future<X> <: Y)
+    //
+    return types
+        .performNullabilityAwareSubtypeCheck(sArgument, tArgument)
+        .or(types
+            .performNullabilityAwareSubtypeCheck(sArgument, tFutureOfArgument)
+            .andSubtypeCheckFor(sFutureOfArgument, tArgument, types))
+        .and(new IsSubtypeOf.basedSolelyOnNullabilities(
+            sFutureOr.withNullability(sNullability),
+            tFutureOr.withNullability(tNullability),
+            types.futureOrClass));
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(
+      DynamicType s, InterfaceType futureOr, Types types) {
+    // Rule 11.
+    DartType argument = futureOr.typeArguments.single;
+    return types.performNullabilityAwareSubtypeCheck(
+        s,
+        argument.withNullability(computeNullabilityOfFutureOr(
+            futureOr, types.hierarchy.coreTypes.futureOrClass)));
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(VoidType s, InterfaceType futureOr, Types types) {
+    // Rule 11.
+    DartType argument = futureOr.typeArguments.single;
+    return types.performNullabilityAwareSubtypeCheck(
+        s,
+        argument.withNullability(computeNullabilityOfFutureOr(
+            futureOr, types.hierarchy.coreTypes.futureOrClass)));
+  }
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, InterfaceType futureOr, Types types) {
+    List<DartType> arguments = futureOr.typeArguments;
+    Nullability unitedNullability = computeNullabilityOfFutureOr(
+        futureOr, types.hierarchy.coreTypes.futureOrClass);
+    // TODO(dmitryas): Revise the original optimization.
+    return types
+        // Rule 11.
+        .performNullabilityAwareSubtypeCheck(
+            s, arguments.single.withNullability(unitedNullability))
+        // Rule 13.
+        .orSubtypeCheckFor(
+            s.parameter.bound.withNullability(
+                combineNullabilitiesForSubstitution(
+                    s.parameter.bound.nullability, s.nullability)),
+            futureOr,
+            types)
+        // Rule 10.
+        .orSubtypeCheckFor(
+            s,
+            new InterfaceType(types.hierarchy.coreTypes.futureClass,
+                unitedNullability, arguments),
+            types);
+  }
+
+  @override
+  IsSubtypeOf isFunctionRelated(
+      FunctionType s, InterfaceType futureOr, Types types) {
+    // Rule 11.
+    DartType argument = futureOr.typeArguments.single;
+    return types.performNullabilityAwareSubtypeCheck(
+        s,
+        argument.withNullability(computeNullabilityOfFutureOr(
+            futureOr, types.hierarchy.coreTypes.futureOrClass)));
+  }
+
+  @override
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, InterfaceType futureOr, Types types) {
+    return isTypeParameterRelated(intersection, futureOr, types) // Rule 8.
+        .orSubtypeCheckFor(
+            intersection.promotedBound, futureOr, types); // Rule 12.
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(
+      TypedefType s, InterfaceType futureOr, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, futureOr);
+  }
+}
+
+class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
+  const IsIntersectionSubtypeOf();
+
+  @override
+  IsSubtypeOf isIntersectionRelated(TypeParameterType sIntersection,
+      TypeParameterType tIntersection, Types types) {
+    // Rule 9.
+    return const IsTypeParameterSubtypeOf()
+        .isIntersectionRelated(sIntersection, tIntersection, types)
+        .andSubtypeCheckFor(sIntersection, tIntersection.promotedBound, types);
+  }
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, TypeParameterType intersection, Types types) {
+    // Rule 9.
+    return const IsTypeParameterSubtypeOf()
+        .isTypeParameterRelated(s, intersection, types)
+        .andSubtypeCheckFor(s, intersection.promotedBound, types);
+  }
+
+  @override
+  IsSubtypeOf isInterfaceRelated(
+      InterfaceType s, TypeParameterType intersection, Types types) {
+    if (s.classNode == types.hierarchy.coreTypes.nullClass) {
+      // Rule 4.
+      return new IsSubtypeOf.basedSolelyOnNullabilities(
+          s, intersection, types.futureOrClass);
+    }
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(
+      DynamicType s, TypeParameterType intersection, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFunctionRelated(
+      FunctionType s, TypeParameterType intersection, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType futureOr, TypeParameterType intersection, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(
+      TypedefType s, TypeParameterType intersection, Types types) {
+    // Rule 5.
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, intersection);
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(
+      VoidType s, TypeParameterType intersection, Types types) {
+    return const IsSubtypeOf.never();
+  }
+}
+
+class IsNeverTypeSubtypeOf implements TypeRelation<NeverType> {
+  const IsNeverTypeSubtypeOf();
+
+  IsSubtypeOf isDynamicRelated(DynamicType s, NeverType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  IsSubtypeOf isVoidRelated(VoidType s, NeverType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  IsSubtypeOf isInterfaceRelated(InterfaceType s, NeverType t, Types types) {
+    if (s.classNode == types.hierarchy.coreTypes.nullClass) {
+      if (t.nullability == Nullability.nullable ||
+          t.nullability == Nullability.legacy) {
+        return const IsSubtypeOf.always();
+      }
+      if (t.nullability == Nullability.nonNullable) {
+        return const IsSubtypeOf.never();
+      }
+      throw new StateError(
+          "Unexpected nullability '$t.nullability' of type Never");
+    }
+    return const IsSubtypeOf.never();
+  }
+
+  IsSubtypeOf isIntersectionRelated(
+      TypeParameterType intersection, NeverType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(
+        intersection.promotedBound, t);
+  }
+
+  IsSubtypeOf isFunctionRelated(FunctionType s, NeverType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  IsSubtypeOf isFutureOrRelated(
+      InterfaceType futureOr, NeverType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, NeverType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s.bound, t).and(
+        new IsSubtypeOf.basedSolelyOnNullabilities(s, t, types.futureOrClass));
+  }
+
+  IsSubtypeOf isTypedefRelated(TypedefType s, NeverType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
+  }
+}
diff --git a/pkg/kernel/lib/target/changed_structure_notifier.dart b/pkg/kernel/lib/target/changed_structure_notifier.dart
index d18c7de..e1b2c7f 100644
--- a/pkg/kernel/lib/target/changed_structure_notifier.dart
+++ b/pkg/kernel/lib/target/changed_structure_notifier.dart
@@ -7,6 +7,9 @@
 /// Meant for notifying the backend (the compiler) that the structure has
 /// changed, in turn allowing it to update its internal model.
 abstract class ChangedStructureNotifier {
-  /// Mark the class [c] as having changed in that its members have changed.
-  void forClass(Class c);
+  /// Mark the members of class [cls] have changed.
+  void registerClassMemberChange(Class cls);
+
+  /// Mark that the class hierarchy for class [cls] has changed.
+  void registerClassHierarchyChange(Class cls);
 }
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
index e166cb2..30eb6a3 100644
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ b/pkg/kernel/lib/text/serializer_combinators.dart
@@ -26,7 +26,7 @@
 
   T addBinder(String name, T node) {
     if (usedNames.contains(name)) {
-      throw StateError("name '$name' is already declared in this scope");
+      throw StateError("Name '${name}' is already declared in this scope.");
     }
     usedNames.add(name);
     return binders[name] = node;
@@ -115,7 +115,7 @@
 
   String readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
-      throw StateError("expected an atom, found a list");
+      throw StateError("Expected an atom, found a list: '${stream.current}'.");
     }
     String result = json.decode(stream.current);
     stream.moveNext();
@@ -132,7 +132,7 @@
 
   int readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
-      throw StateError("expected an atom, found a list");
+      throw StateError("Expected an atom, found a list: '${stream.current}'.");
     }
     int result = int.parse(stream.current);
     stream.moveNext();
@@ -149,7 +149,7 @@
 
   double readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
-      throw StateError("expected an atom, found a list");
+      throw StateError("Expected an atom, found a list: '${stream.current}'.");
     }
     double result = double.parse(stream.current);
     stream.moveNext();
@@ -166,7 +166,7 @@
 
   bool readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
-      throw StateError("expected an atom, found a list");
+      throw StateError("Expected an atom, found a list: '${stream.current}'.");
     }
     bool result;
     if (stream.current == "true") {
@@ -174,7 +174,7 @@
     } else if (stream.current == "false") {
       result = false;
     } else {
-      throw StateError("expected 'true' or 'false', found '${stream.current}'");
+      throw StateError("Expected 'true' or 'false', found '${stream.current}'");
     }
     stream.moveNext();
     return result;
@@ -185,6 +185,19 @@
   }
 }
 
+class UriSerializer extends TextSerializer<Uri> {
+  const UriSerializer();
+
+  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) {
+    const DartString().writeTo(buffer, object.toString(), state);
+  }
+}
+
 // == Serializers for tagged (disjoint) unions.
 //
 // They require a function mapping serializables to a tag string.  This is
@@ -192,53 +205,61 @@
 // A tagged union of serializer/deserializers.
 class Case<T extends Node> extends TextSerializer<T> {
   final Tagger<T> tagger;
-  final List<String> tags;
-  final List<TextSerializer<T>> serializers;
+  final List<String> _tags;
+  final List<TextSerializer<T>> _serializers;
 
-  Case(this.tagger, this.tags, this.serializers);
+  Case(this.tagger, Map<String, TextSerializer<T>> tagsAndSerializers)
+      : _tags = tagsAndSerializers.keys.toList(),
+        _serializers = tagsAndSerializers.values.toList();
 
   Case.uninitialized(this.tagger)
-      : tags = [],
-        serializers = [];
+      : _tags = [],
+        _serializers = [];
+
+  void registerTags(Map<String, TextSerializer<T>> tagsAndSerializers) {
+    _tags.addAll(tagsAndSerializers.keys);
+    _serializers.addAll(tagsAndSerializers.values);
+  }
 
   T readFrom(Iterator<Object> stream, DeserializationState state) {
     if (stream.current is! Iterator) {
-      throw StateError("expected list, found atom");
+      throw StateError("Expected list, found atom: '${stream.current}'.");
     }
     Iterator nested = stream.current;
     nested.moveNext();
     if (nested.current is! String) {
-      throw StateError("expected atom, found list");
+      throw StateError("Expected atom, found list: '${nested.current}'.");
     }
     String tag = nested.current;
-    for (int i = 0; i < tags.length; ++i) {
-      if (tags[i] == tag) {
+    for (int i = 0; i < _tags.length; ++i) {
+      if (_tags[i] == tag) {
         nested.moveNext();
-        T result = serializers[i].readFrom(nested, state);
+        T result = _serializers[i].readFrom(nested, state);
         if (nested.moveNext()) {
-          throw StateError("extra cruft in tagged '${tag}'");
+          throw StateError(
+              "Extra data in tagged '${tag}': '${nested.current}'.");
         }
         stream.moveNext();
         return result;
       }
     }
-    throw StateError("unrecognized tag '${tag}'");
+    throw StateError("Unrecognized tag '${tag}'.");
   }
 
   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) {
+    for (int i = 0; i < _tags.length; ++i) {
+      if (_tags[i] == tag) {
         buffer.write("(${tag}");
-        if (!serializers[i].isEmpty) {
+        if (!_serializers[i].isEmpty) {
           buffer.write(" ");
         }
-        serializers[i].writeTo(buffer, object, state);
+        _serializers[i].writeTo(buffer, object, state);
         buffer.write(")");
         return;
       }
     }
-    throw StateError("unrecognized tag '${tag}");
+    throw StateError("Unrecognized tag '${tag}'.");
   }
 }
 
@@ -249,7 +270,7 @@
   final K Function(S) wrap;
   final TextSerializer<S> contents;
 
-  Wrapped(this.unwrap, this.wrap, this.contents);
+  const Wrapped(this.unwrap, this.wrap, this.contents);
 
   K readFrom(Iterator<Object> stream, DeserializationState state) {
     return wrap(contents.readFrom(stream, state));
@@ -381,7 +402,7 @@
 
   List<T> readFrom(Iterator<Object> stream, DeserializationState state) {
     if (stream.current is! Iterator) {
-      throw StateError("expected a list, found an atom");
+      throw StateError("Expected a list, found an atom: '${stream.current}'.");
     }
     Iterator<Object> list = stream.current;
     list.moveNext();
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 4b7eff8..9b83f3c 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -16,8 +16,6 @@
         initializeSerializers,
         statementSerializer;
 
-import '../visitor.dart' show Visitor;
-
 const Uri noUri = null;
 
 const int noOffset = -1;
@@ -56,19 +54,258 @@
       : super(uri, offset);
 }
 
-class TextSerializationVerifier implements Visitor<void> {
+class VerificationState {
+  final VerificationState parent;
+
+  final Node node;
+
+  bool allChildrenAreSupported = true;
+  final List<Node> roundTripReadyNodes = [];
+
+  final Set<VariableDeclaration> variableDeclarations =
+      new Set<VariableDeclaration>.identity();
+  final Set<TypeParameter> typeParameters = new Set<TypeParameter>.identity();
+
+  final Set<VariableDeclaration> usedVariables =
+      new Set<VariableDeclaration>.identity();
+  final Set<TypeParameter> usedTypeParameters =
+      new Set<TypeParameter>.identity();
+
+  VerificationState(this.parent, this.node);
+
+  bool get isRoot => parent == null;
+
+  bool get isFullySupported => isSupported(node) && allChildrenAreSupported;
+
+  bool get hasSufficientScope {
+    return usedVariables.every((v) => variableDeclarations.contains(v)) &&
+        usedTypeParameters.every((p) => typeParameters.contains(p));
+  }
+
+  bool get isRoundTripReady => isFullySupported && hasSufficientScope;
+
+  bool isVariableDeclared(VariableDeclaration node) {
+    return variableDeclarations.contains(node) ||
+        !isRoot && parent.isVariableDeclared(node);
+  }
+
+  bool isTypeParameterDeclared(TypeParameter node) {
+    return typeParameters.contains(node) ||
+        !isRoot && parent.isTypeParameterDeclared(node);
+  }
+
+  void handleChild(VerificationState childState) {
+    allChildrenAreSupported =
+        allChildrenAreSupported && childState.isFullySupported;
+  }
+
+  void handleDeclarations() {
+    Node node = this.node;
+    if (node is VariableDeclaration) {
+      parent.variableDeclarations.add(node);
+    }
+    if (node is TypeParameter) {
+      parent.typeParameters.add(node);
+    }
+    if (node is VariableGet) {
+      usedVariables.add(node.variable);
+    }
+    if (node is VariableSet) {
+      usedVariables.add(node.variable);
+    }
+    if (node is TypeParameterType) {
+      usedTypeParameters.add(node.parameter);
+    }
+  }
+
+  /// Computes round-trip ready nodes or propagates them further in the stack.
+  ///
+  /// The returned nodes are the roots of maximal-by-inclusion subtrees that are
+  /// ready for the round-trip textual serialization.
+  List<Node> takeRoundTripReadyNodes() {
+    if (isRoot) {
+      // If the node is the root of the AST and is round-trip ready, return just
+      // the root because it's maximal-by-inclusion.
+      // Otherwise, return the nodes collected so far.
+      List<Node> result =
+          isRoundTripReady ? <Node>[node] : roundTripReadyNodes.toList();
+      roundTripReadyNodes.clear();
+      return result;
+    }
+
+    // The algorithm in this branch is based on the following observations:
+    //   - The isFullySupported property is monotonous.  That is, when traveling
+    //     from a leaf to the root, the property may only change its value from
+    //     true to false.
+    //   - The isRoundTripReady property is not monotonous because the sub-tree
+    //     that is ready for the round trip shouldn't contain free variables or
+    //     free type parameters.
+    //   - The isRoundTripReady property implies the isFullySupported property.
+
+    if (!isFullySupported) {
+      // We're out of the isFullySupported sub-tree, run the round trip on the
+      // nodes that are ready for it so far -- they are maximal-by-inclusion by
+      // construction.
+      List<Node> result = roundTripReadyNodes.toList();
+      roundTripReadyNodes.clear();
+      return result;
+    } else {
+      // We're still in the isFullySupported sub-tree.  It's to early to decide
+      // if the collected sub-trees or the node itself are maximal-by-inclusion.
+      // The decision should be made in one of the parent nodes.  So, we just
+      // propagate the information to the parent, returning an empty list for
+      // the current node.
+      if (isRoundTripReady) {
+        // The current tree is ready for the round trip.  Its sub-trees, which
+        // are also round-trip ready, are not maximal-by-inclusion.  So only the
+        // node itself is passed to the parent.
+        parent.roundTripReadyNodes.add(node);
+      } else {
+        // The node is not round-trip ready.  The round-trip ready sub-trees
+        // collected so far remain the candidates for being
+        // maximal-by-inclusion.
+        parent.roundTripReadyNodes.addAll(roundTripReadyNodes);
+      }
+      return const <Node>[];
+    }
+  }
+
+  /// Passes the necessary information to the parent when popped from the stack.
+  void mergeToParent() {
+    // Pass the free occurrences of variables and type parameters to the parent.
+    if (parent != null) {
+      parent.usedVariables
+          .addAll(usedVariables.difference(variableDeclarations));
+      parent.usedTypeParameters
+          .addAll(usedTypeParameters.difference(typeParameters));
+      parent.handleChild(this);
+    }
+  }
+
+  static bool isDartTypeSupported(DartType node) =>
+      node is InvalidType ||
+      node is DynamicType ||
+      node is VoidType ||
+      node is BottomType ||
+      node is FunctionType ||
+      node is TypeParameterType ||
+      node is InterfaceType;
+
+  static bool isExpressionSupported(Expression node) =>
+      node is StringLiteral ||
+      node is SymbolLiteral ||
+      node is IntLiteral ||
+      node is DoubleLiteral ||
+      node is BoolLiteral ||
+      node is NullLiteral ||
+      node is ListLiteral ||
+      node is SetLiteral ||
+      node is MapLiteral ||
+      node is TypeLiteral ||
+      node is InvalidExpression ||
+      node is Not ||
+      node is LogicalExpression ||
+      node is StringConcatenation ||
+      node is ThisExpression ||
+      node is Rethrow ||
+      node is Throw ||
+      node is AwaitExpression ||
+      node is ConditionalExpression ||
+      node is IsExpression ||
+      node is AsExpression ||
+      node is Let ||
+      node is PropertyGet ||
+      node is PropertySet ||
+      node is SuperPropertyGet ||
+      node is SuperPropertySet ||
+      node is MethodInvocation ||
+      node is SuperMethodInvocation ||
+      node is VariableGet ||
+      node is VariableSet ||
+      node is StaticGet ||
+      node is StaticSet ||
+      node is DirectPropertyGet ||
+      node is DirectPropertySet ||
+      node is StaticInvocation ||
+      node is DirectMethodInvocation ||
+      node is ConstructorInvocation ||
+      node is FunctionExpression;
+
+  static bool isStatementSupported(Statement node) =>
+      node is ExpressionStatement ||
+      node is ReturnStatement && node.expression != null;
+
+  static bool isSupported(Node node) =>
+      node is DartType && isDartTypeSupported(node) ||
+      node is Expression && isExpressionSupported(node) ||
+      node is Statement && isStatementSupported(node);
+}
+
+class TextSerializationVerifier extends RecursiveVisitor<void> {
+  static const bool showStackTrace = bool.fromEnvironment(
+      "text_serialization.showStackTrace",
+      defaultValue: false);
+
   /// List of errors produced during round trips on the visited nodes.
   final List<TextSerializationVerificationFailure> failures =
       <TextSerializationVerificationFailure>[];
 
+  /// List of status for all round-trip serialization attempts.
+  final List<RoundTripStatus> status = <RoundTripStatus>[];
+
+  final CanonicalName root;
+
   Uri lastSeenUri = noUri;
 
   int lastSeenOffset = noOffset;
 
-  TextSerializationVerifier() {
+  VerificationState _stateStackTop;
+
+  TextSerializationVerifier({CanonicalName root})
+      : root = root ?? new CanonicalName.root() {
     initializeSerializers();
   }
 
+  VerificationState get currentState => _stateStackTop;
+
+  void pushStateFor(Node node) {
+    _stateStackTop = new VerificationState(_stateStackTop, node);
+  }
+
+  void dropState() {
+    if (_stateStackTop == null) {
+      throw new StateError("Attempting to remove a state from an empty stack.");
+    }
+    _stateStackTop = _stateStackTop.parent;
+  }
+
+  void verify(Node node) => node.accept(this);
+
+  void defaultNode(Node node) {
+    enterNode(node);
+    node.visitChildren(this);
+    exitNode(node);
+  }
+
+  void enterNode(node) {
+    storeLastSeenUriAndOffset(node);
+    pushStateFor(node);
+    currentState.handleDeclarations();
+  }
+
+  void exitNode(node) {
+    if (!identical(node, currentState.node)) {
+      throw new StateError("Trying to remove node '${node}' from the stack, "
+          "while another node '${currentState.node}' is on the top of it.");
+    }
+    List<Node> roundTripReadyNodes = currentState.takeRoundTripReadyNodes();
+    for (Node node in roundTripReadyNodes) {
+      status.add(makeRoundTripDispatch(node));
+    }
+    currentState.mergeToParent();
+    dropState();
+  }
+
   void storeLastSeenUriAndOffset(Node node) {
     if (node is TreeNode) {
       Location location = node.location;
@@ -85,16 +322,23 @@
     stream.moveNext();
     T result;
     try {
-      result = serializer.readFrom(
-          stream, new DeserializationState(null, new CanonicalName.root()));
-    } catch (exception) {
-      failures.add(
-          new TextDeserializationFailure(exception.toString(), uri, offset));
+      result =
+          serializer.readFrom(stream, new DeserializationState(null, root));
+    } catch (exception, stackTrace) {
+      String message =
+          showStackTrace ? "${exception}\n${stackTrace}" : "${exception}";
+      failures.add(new TextDeserializationFailure(message, uri, offset));
     }
     if (stream.moveNext()) {
       failures.add(new TextDeserializationFailure(
           "unexpected trailing text", uri, offset));
     }
+    if (result == null) {
+      failures.add(new TextDeserializationFailure(
+          "Deserialization of the following returned null: '${input}'",
+          uri,
+          offset));
+    }
     return result;
   }
 
@@ -103,949 +347,121 @@
     StringBuffer buffer = new StringBuffer();
     try {
       serializer.writeTo(buffer, node, new SerializationState(null));
-    } catch (exception) {
-      failures
-          .add(new TextSerializationFailure(exception.toString(), uri, offset));
+    } catch (exception, stackTrace) {
+      String message =
+          showStackTrace ? "${exception}\n${stackTrace}" : "${exception}";
+      failures.add(new TextSerializationFailure(message, uri, offset));
     }
     return buffer.toString();
   }
 
-  void makeExpressionRoundTrip(Expression node) {
-    Uri uri = noUri;
-    int offset = noOffset;
-    Location location = node.location;
-    if (location != null) {
-      uri = location.file;
-      offset = node.fileOffset;
+  RoundTripStatus makeRoundTripDispatch(Node node) {
+    if (node is DartType) {
+      return makeRoundTrip<DartType>(node, dartTypeSerializer);
+    } else if (node is Expression) {
+      return makeRoundTrip<Expression>(node, expressionSerializer);
+    } else if (node is Statement) {
+      return makeRoundTrip<Statement>(node, statementSerializer);
+    } else {
+      throw new StateError(
+          "Don't know how to make a round trip for a supported node '${node.runtimeType}'");
     }
+  }
 
-    String initial = writeNode(node, expressionSerializer, uri, offset);
+  RoundTripStatus makeRoundTrip<T extends Node>(
+      T node, TextSerializer<T> serializer) {
+    String initial = writeNode(node, serializer, lastSeenUri, lastSeenOffset);
 
     // Do the round trip.
-    Expression deserialized =
-        readNode(initial, expressionSerializer, uri, offset);
+    T deserialized = readNode(initial, serializer, lastSeenUri, lastSeenOffset);
+
+    // The error is reported elsewhere for the case of null.
+    if (deserialized == null) {
+      return new RoundTripStatus(false, node, initial);
+    }
+
     String serialized =
-        writeNode(deserialized, expressionSerializer, uri, offset);
+        writeNode(deserialized, serializer, lastSeenUri, lastSeenOffset);
 
     if (initial != serialized) {
-      failures.add(new TextRoundTripFailure(initial, serialized, uri, offset));
+      failures.add(new TextRoundTripFailure(
+          initial, serialized, lastSeenUri, lastSeenOffset));
+      return new RoundTripStatus(false, node, initial);
     }
+    return new RoundTripStatus(true, node, initial);
   }
+}
 
-  void makeDartTypeRoundTrip(DartType node) {
-    Uri uri = lastSeenUri;
-    int offset = lastSeenOffset;
+class RoundTripStatus implements Comparable<RoundTripStatus> {
+  final bool successful;
+  final Node node;
+  final String serialized;
 
-    String initial = writeNode(node, dartTypeSerializer, uri, offset);
+  RoundTripStatus(this.successful, this.node, this.serialized)
+      : assert(successful != null),
+        assert(node != null),
+        assert(serialized != null);
 
-    // Do the round trip.
-    DartType deserialized = readNode(initial, dartTypeSerializer, uri, offset);
-    String serialized =
-        writeNode(deserialized, dartTypeSerializer, uri, offset);
-
-    if (initial != serialized) {
-      failures.add(new TextRoundTripFailure(initial, serialized, uri, offset));
+  void printOn(StringBuffer sb) {
+    sb.writeln(
+        ";; -----------------------------------------------------------------------------");
+    sb.writeln("Status: ${successful ? "OK" : "ERROR"}");
+    sb.writeln("Node type: ${node.runtimeType}");
+    sb.writeln("Node: ${node.leakingDebugToString()}");
+    if (node is TreeNode) {
+      TreeNode treeNode = node;
+      sb.writeln("Parent type: ${treeNode.parent.runtimeType}");
+      sb.writeln("Parent: ${treeNode.parent.leakingDebugToString()}");
     }
+    sb.writeln("Serialized: ${serialized}");
+    sb.writeln();
   }
 
-  void makeStatementRoundTrip(Statement node) {
-    Uri uri = noUri;
-    int offset = noOffset;
-    Location location = node.location;
-    if (location != null) {
-      uri = location.file;
-      offset = node.fileOffset;
+  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;
+      int thisOffset = thisNode.fileOffset;
+      int otherOffset = otherNode.fileOffset;
+
+      int compareUri;
+      if (thisUri == null && otherUri == null) {
+        compareUri = 0;
+      } else if (thisUri == null) {
+        compareUri = 1;
+      } else if (otherUri == null) {
+        return -1;
+      } else {
+        assert(thisUri != null && otherUri != null);
+        compareUri = thisUri.toString().compareTo(otherUri.toString());
+      }
+      if (compareUri != 0) return compareUri;
+
+      int compareOffset;
+      if (thisOffset == null && otherOffset == null) {
+        compareOffset = 0;
+      } else if (thisOffset == null) {
+        compareOffset = 1;
+      } else if (otherOffset == null) {
+        compareOffset = -1;
+      } else {
+        compareOffset = thisOffset = otherOffset;
+      }
+      if (compareOffset != 0) return compareOffset;
+
+      if (!successful && other.successful) {
+        return -1;
+      } else if (successful && !other.successful) {
+        return 1;
+      }
+
+      return serialized.compareTo(other.serialized);
+    } else if (node is TreeNode) {
+      return -1;
+    } else {
+      return 1;
     }
-
-    String initial = writeNode(node, statementSerializer, uri, offset);
-
-    // Do the round trip.
-    Statement deserialized =
-        readNode(initial, statementSerializer, uri, offset);
-    String serialized =
-        writeNode(deserialized, expressionSerializer, uri, offset);
-
-    if (initial != serialized) {
-      failures.add(new TextRoundTripFailure(initial, serialized, uri, offset));
-    }
-  }
-
-  @override
-  void defaultExpression(Expression node) {
-    throw new UnsupportedError("defaultExpression");
-  }
-
-  @override
-  void defaultMemberReference(Member node) {
-    throw new UnsupportedError("defaultMemberReference");
-  }
-
-  @override
-  void defaultConstantReference(Constant node) {
-    throw new UnsupportedError("defaultConstantReference");
-  }
-
-  @override
-  void defaultConstant(Constant node) {
-    throw new UnsupportedError("defaultConstant");
-  }
-
-  @override
-  void defaultDartType(DartType node) {
-    throw new UnsupportedError("defaultDartType");
-  }
-
-  @override
-  void defaultTreeNode(TreeNode node) {
-    throw new UnsupportedError("defaultTreeNode");
-  }
-
-  @override
-  void defaultNode(Node node) {
-    throw new UnsupportedError("defaultNode");
-  }
-
-  @override
-  void defaultInitializer(Initializer node) {
-    throw new UnsupportedError("defaultInitializer");
-  }
-
-  @override
-  void defaultMember(Member node) {
-    throw new UnsupportedError("defaultMember");
-  }
-
-  @override
-  void defaultStatement(Statement node) {
-    throw new UnsupportedError("defaultStatement");
-  }
-
-  @override
-  void defaultBasicLiteral(BasicLiteral node) {
-    throw new UnsupportedError("defaultBasicLiteral");
-  }
-
-  @override
-  void visitNamedType(NamedType node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSupertype(Supertype node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitName(Name node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitRedirectingFactoryConstructorReference(
-      RedirectingFactoryConstructor node) {}
-
-  @override
-  void visitProcedureReference(Procedure node) {}
-
-  @override
-  void visitConstructorReference(Constructor node) {}
-
-  @override
-  void visitFieldReference(Field node) {}
-
-  @override
-  void visitTypeLiteralConstantReference(TypeLiteralConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitTearOffConstantReference(TearOffConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPartialInstantiationConstantReference(
-      PartialInstantiationConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitInstanceConstantReference(InstanceConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitListConstantReference(ListConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSetConstantReference(SetConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitMapConstantReference(MapConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSymbolConstantReference(SymbolConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitStringConstantReference(StringConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitDoubleConstantReference(DoubleConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIntConstantReference(IntConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitBoolConstantReference(BoolConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitNullConstantReference(NullConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitUnevaluatedConstantReference(UnevaluatedConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitTypedefReference(Typedef node) {}
-
-  @override
-  void visitClassReference(Class node) {}
-
-  @override
-  void visitTypeLiteralConstant(TypeLiteralConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitTearOffConstant(TearOffConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPartialInstantiationConstant(PartialInstantiationConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitInstanceConstant(InstanceConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitListConstant(ListConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSetConstant(SetConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitMapConstant(MapConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitInstanceCreation(InstanceCreation node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFileUriExpression(FileUriExpression node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSymbolConstant(SymbolConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitStringConstant(StringConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitDoubleConstant(DoubleConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIntConstant(IntConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitBoolConstant(BoolConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitNullConstant(NullConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitUnevaluatedConstant(UnevaluatedConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitTypedefType(TypedefType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitTypeParameterType(TypeParameterType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitFunctionType(FunctionType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitInterfaceType(InterfaceType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitBottomType(BottomType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitNeverType(NeverType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitVoidType(VoidType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitDynamicType(DynamicType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitInvalidType(InvalidType node) {
-    storeLastSeenUriAndOffset(node);
-    makeDartTypeRoundTrip(node);
-  }
-
-  @override
-  void visitComponent(Component node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitMapEntry(MapEntry node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitCatch(Catch node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSwitchCase(SwitchCase node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitNamedExpression(NamedExpression node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitArguments(Arguments node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFunctionNode(FunctionNode node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitTypeParameter(TypeParameter node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitTypedef(Typedef node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitLibraryPart(LibraryPart node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitCombinator(Combinator node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitLibraryDependency(LibraryDependency node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitLibrary(Library node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitAssertInitializer(AssertInitializer node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitLocalInitializer(LocalInitializer node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitRedirectingInitializer(RedirectingInitializer node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSuperInitializer(SuperInitializer node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFieldInitializer(FieldInitializer node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitInvalidInitializer(InvalidInitializer node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitClass(Class node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitExtension(Extension node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitField(Field node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitProcedure(Procedure node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitConstructor(Constructor node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitYieldStatement(YieldStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitTryFinally(TryFinally node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitTryCatch(TryCatch node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitContinueSwitchStatement(ContinueSwitchStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitForInStatement(ForInStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitLabeledStatement(LabeledStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitAssertStatement(AssertStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitEmptyStatement(EmptyStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitAssertBlock(AssertBlock node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitBlock(Block node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitExpressionStatement(ExpressionStatement node) {
-    storeLastSeenUriAndOffset(node);
-    makeStatementRoundTrip(node);
-  }
-
-  @override
-  void visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitLoadLibrary(LoadLibrary node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitInstantiation(Instantiation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitLet(Let node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitBlockExpression(BlockExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitNullLiteral(NullLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitBoolLiteral(BoolLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitDoubleLiteral(DoubleLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitIntLiteral(IntLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitStringLiteral(StringLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitConstantExpression(ConstantExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitAwaitExpression(AwaitExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitMapLiteral(MapLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitSetLiteral(SetLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitListLiteral(ListLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitThrow(Throw node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitRethrow(Rethrow node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitThisExpression(ThisExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitTypeLiteral(TypeLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitSymbolLiteral(SymbolLiteral node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitStringConcatenation(StringConcatenation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitListConcatenation(ListConcatenation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitSetConcatenation(SetConcatenation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitMapConcatenation(MapConcatenation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitLogicalExpression(LogicalExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitNot(Not node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitNullCheck(NullCheck node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitConstructorInvocation(ConstructorInvocation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitStaticInvocation(StaticInvocation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitSuperMethodInvocation(SuperMethodInvocation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitDirectMethodInvocation(DirectMethodInvocation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitMethodInvocation(MethodInvocation node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitStaticSet(StaticSet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitStaticGet(StaticGet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitSuperPropertySet(SuperPropertySet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitSuperPropertyGet(SuperPropertyGet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitDirectPropertySet(DirectPropertySet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitDirectPropertyGet(DirectPropertyGet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitPropertySet(PropertySet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitPropertyGet(PropertyGet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitVariableSet(VariableSet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitVariableGet(VariableGet node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
-  }
-
-  @override
-  void visitInvalidExpression(InvalidExpression node) {
-    storeLastSeenUriAndOffset(node);
-    makeExpressionRoundTrip(node);
   }
 }
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index d2a9bb6..70fa064 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -20,14 +20,14 @@
   String tag(Name name) => name.isPrivate ? "private" : "public";
 }
 
-TextSerializer<Name> publicName =
-    new Wrapped(unwrapPublicName, wrapPublicName, const DartString());
+const TextSerializer<Name> publicName =
+    const Wrapped(unwrapPublicName, wrapPublicName, const DartString());
 
 String unwrapPublicName(Name name) => name.name;
 
 Name wrapPublicName(String name) => new Name(name);
 
-TextSerializer<Name> privateName = new Wrapped(unwrapPrivateName,
+const TextSerializer<Name> privateName = const Wrapped(unwrapPrivateName,
     wrapPrivateName, Tuple2Serializer(const DartString(), const DartString()));
 
 Tuple2<String, String> unwrapPrivateName(Name name) {
@@ -37,16 +37,11 @@
 Name wrapPrivateName(Tuple2<String, String> tuple) {
   // We need a map from import URI to libraries.  More generally, we will need
   // a way to map any 'named' node to the node's reference.
-  throw UnimplementedError('deserialization of private names');
+  throw UnimplementedError('Deserialization of private names.');
 }
 
-TextSerializer<Name> nameSerializer = new Case(const NameTagger(), [
-  "public",
-  "private",
-], [
-  publicName,
-  privateName
-]);
+TextSerializer<Name> nameSerializer = new Case(
+    const NameTagger(), {"public": publicName, "private": privateName});
 
 class ExpressionTagger extends ExpressionVisitor<String>
     implements Tagger<Expression> {
@@ -119,8 +114,9 @@
   String visitFunctionExpression(FunctionExpression _) => "fun";
 }
 
-TextSerializer<InvalidExpression> invalidExpressionSerializer = new Wrapped(
-    unwrapInvalidExpression, wrapInvalidExpression, const DartString());
+const TextSerializer<InvalidExpression> invalidExpressionSerializer =
+    const Wrapped(
+        unwrapInvalidExpression, wrapInvalidExpression, const DartString());
 
 String unwrapInvalidExpression(InvalidExpression expression) {
   return expression.message;
@@ -173,57 +169,57 @@
   return new StringConcatenation(expressions);
 }
 
-TextSerializer<StringLiteral> stringLiteralSerializer =
-    new Wrapped(unwrapStringLiteral, wrapStringLiteral, const DartString());
+const TextSerializer<StringLiteral> stringLiteralSerializer =
+    const Wrapped(unwrapStringLiteral, wrapStringLiteral, const DartString());
 
 String unwrapStringLiteral(StringLiteral literal) => literal.value;
 
 StringLiteral wrapStringLiteral(String value) => new StringLiteral(value);
 
-TextSerializer<IntLiteral> intLiteralSerializer =
-    new Wrapped(unwrapIntLiteral, wrapIntLiteral, const DartInt());
+const TextSerializer<IntLiteral> intLiteralSerializer =
+    const Wrapped(unwrapIntLiteral, wrapIntLiteral, const DartInt());
 
 int unwrapIntLiteral(IntLiteral literal) => literal.value;
 
 IntLiteral wrapIntLiteral(int value) => new IntLiteral(value);
 
-TextSerializer<DoubleLiteral> doubleLiteralSerializer =
-    new Wrapped(unwrapDoubleLiteral, wrapDoubleLiteral, const DartDouble());
+const TextSerializer<DoubleLiteral> doubleLiteralSerializer =
+    const Wrapped(unwrapDoubleLiteral, wrapDoubleLiteral, const DartDouble());
 
 double unwrapDoubleLiteral(DoubleLiteral literal) => literal.value;
 
 DoubleLiteral wrapDoubleLiteral(double value) => new DoubleLiteral(value);
 
-TextSerializer<BoolLiteral> boolLiteralSerializer =
-    new Wrapped(unwrapBoolLiteral, wrapBoolLiteral, const DartBool());
+const TextSerializer<BoolLiteral> boolLiteralSerializer =
+    const Wrapped(unwrapBoolLiteral, wrapBoolLiteral, const DartBool());
 
 bool unwrapBoolLiteral(BoolLiteral literal) => literal.value;
 
 BoolLiteral wrapBoolLiteral(bool value) => new BoolLiteral(value);
 
-TextSerializer<NullLiteral> nullLiteralSerializer =
-    new Wrapped(unwrapNullLiteral, wrapNullLiteral, const Nothing());
+const TextSerializer<NullLiteral> nullLiteralSerializer =
+    const Wrapped(unwrapNullLiteral, wrapNullLiteral, const Nothing());
 
 void unwrapNullLiteral(NullLiteral literal) {}
 
 NullLiteral wrapNullLiteral(void ignored) => new NullLiteral();
 
-TextSerializer<SymbolLiteral> symbolLiteralSerializer =
-    new Wrapped(unwrapSymbolLiteral, wrapSymbolLiteral, const DartString());
+const TextSerializer<SymbolLiteral> symbolLiteralSerializer =
+    const Wrapped(unwrapSymbolLiteral, wrapSymbolLiteral, const DartString());
 
 String unwrapSymbolLiteral(SymbolLiteral expression) => expression.value;
 
 SymbolLiteral wrapSymbolLiteral(String value) => new SymbolLiteral(value);
 
-TextSerializer<ThisExpression> thisExpressionSerializer =
-    new Wrapped(unwrapThisExpression, wrapThisExpression, const Nothing());
+const TextSerializer<ThisExpression> thisExpressionSerializer =
+    const Wrapped(unwrapThisExpression, wrapThisExpression, const Nothing());
 
 void unwrapThisExpression(ThisExpression expression) {}
 
 ThisExpression wrapThisExpression(void ignored) => new ThisExpression();
 
-TextSerializer<Rethrow> rethrowSerializer =
-    new Wrapped(unwrapRethrow, wrapRethrow, const Nothing());
+const TextSerializer<Rethrow> rethrowSerializer =
+    const Wrapped(unwrapRethrow, wrapRethrow, const Nothing());
 
 void unwrapRethrow(Rethrow expression) {}
 
@@ -553,8 +549,8 @@
   }
 }
 
-TextSerializer<StaticGet> staticGetSerializer =
-    new Wrapped(unwrapStaticGet, wrapStaticGet, new CanonicalNameSerializer());
+const TextSerializer<StaticGet> staticGetSerializer = const Wrapped(
+    unwrapStaticGet, wrapStaticGet, const CanonicalNameSerializer());
 
 CanonicalName unwrapStaticGet(StaticGet expression) {
   return expression.targetReference.canonicalName;
@@ -742,8 +738,8 @@
   const VariableDeclarationTagger();
 
   String tag(VariableDeclaration decl) {
-    if (decl.isCovariant) throw UnimplementedError("covariant declaration");
-    if (decl.isFieldFormal) throw UnimplementedError("initializing formal");
+    if (decl.isCovariant) throw UnimplementedError("Covariant declaration.");
+    if (decl.isFieldFormal) throw UnimplementedError("Initializing formal.");
     if (decl.isConst) {
       // It's not clear what invariants we assume about const/final.  For now
       // throw if we have both.
@@ -821,18 +817,14 @@
 }
 
 TextSerializer<VariableDeclaration> variableDeclarationSerializer =
-    new Case(const VariableDeclarationTagger(), [
-  "var",
-  "final",
-  "const",
-], [
-  varDeclarationSerializer,
-  finalDeclarationSerializer,
-  constDeclarationSerializer,
-]);
+    new Case(const VariableDeclarationTagger(), {
+  "var": varDeclarationSerializer,
+  "final": finalDeclarationSerializer,
+  "const": constDeclarationSerializer,
+});
 
-TextSerializer<TypeParameter> typeParameterSerializer =
-    new Wrapped(unwrapTypeParameter, wrapTypeParameter, const DartString());
+const TextSerializer<TypeParameter> typeParameterSerializer =
+    const Wrapped(unwrapTypeParameter, wrapTypeParameter, const DartString());
 
 String unwrapTypeParameter(TypeParameter node) => node.name;
 
@@ -887,31 +879,32 @@
   String visitBottomType(BottomType _) => "bottom";
   String visitFunctionType(FunctionType _) => "->";
   String visitTypeParameterType(TypeParameterType _) => "par";
+  String visitInterfaceType(InterfaceType _) => "interface";
 }
 
-TextSerializer<InvalidType> invalidTypeSerializer =
-    new Wrapped(unwrapInvalidType, wrapInvalidType, const Nothing());
+const TextSerializer<InvalidType> invalidTypeSerializer =
+    const Wrapped(unwrapInvalidType, wrapInvalidType, const Nothing());
 
 void unwrapInvalidType(InvalidType type) {}
 
 InvalidType wrapInvalidType(void ignored) => const InvalidType();
 
-TextSerializer<DynamicType> dynamicTypeSerializer =
-    new Wrapped(unwrapDynamicType, wrapDynamicType, const Nothing());
+const TextSerializer<DynamicType> dynamicTypeSerializer =
+    const Wrapped(unwrapDynamicType, wrapDynamicType, const Nothing());
 
 void unwrapDynamicType(DynamicType type) {}
 
 DynamicType wrapDynamicType(void ignored) => const DynamicType();
 
-TextSerializer<VoidType> voidTypeSerializer =
-    new Wrapped(unwrapVoidType, wrapVoidType, const Nothing());
+const TextSerializer<VoidType> voidTypeSerializer =
+    const Wrapped(unwrapVoidType, wrapVoidType, const Nothing());
 
 void unwrapVoidType(VoidType type) {}
 
 VoidType wrapVoidType(void ignored) => const VoidType();
 
-TextSerializer<BottomType> bottomTypeSerializer =
-    new Wrapped(unwrapBottomType, wrapBottomType, const Nothing());
+const TextSerializer<BottomType> bottomTypeSerializer =
+    const Wrapped(unwrapBottomType, wrapBottomType, const Nothing());
 
 void unwrapBottomType(BottomType type) {}
 
@@ -978,6 +971,21 @@
   return new TypeParameterType(tuple.first, Nullability.legacy, tuple.second);
 }
 
+TextSerializer<InterfaceType> interfaceTypeSerializer = new Wrapped(
+    unwrapInterfaceType,
+    wrapInterfaceType,
+    Tuple2Serializer(const CanonicalNameSerializer(),
+        new ListSerializer(dartTypeSerializer)));
+
+Tuple2<CanonicalName, List<DartType>> unwrapInterfaceType(InterfaceType node) {
+  return new Tuple2(node.className.canonicalName, node.typeArguments);
+}
+
+InterfaceType wrapInterfaceType(Tuple2<CanonicalName, List<DartType>> tuple) {
+  return new InterfaceType.byReference(
+      tuple.first.reference, Nullability.legacy, tuple.second);
+}
+
 Case<DartType> dartTypeSerializer =
     new Case.uninitialized(const DartTypeTagger());
 
@@ -1227,135 +1235,132 @@
 Case<FunctionNode> functionNodeSerializer =
     new Case.uninitialized(const FunctionNodeTagger());
 
+class ProcedureTagger implements Tagger<Procedure> {
+  const ProcedureTagger();
+
+  String tag(Procedure node) {
+    String prefix = node.isStatic ? "static-" : "";
+    switch (node.kind) {
+      case ProcedureKind.Method:
+        return "${prefix}method";
+      default:
+        throw new UnsupportedError("${node.kind}");
+    }
+  }
+}
+
+TextSerializer<Procedure> staticMethodSerializer = new Wrapped(
+    unwrapStaticMethod,
+    wrapStaticMethod,
+    new Tuple2Serializer(nameSerializer, functionNodeSerializer));
+
+Tuple2<Name, FunctionNode> unwrapStaticMethod(Procedure procedure) {
+  return new Tuple2(procedure.name, procedure.function);
+}
+
+Procedure wrapStaticMethod(Tuple2<Name, FunctionNode> tuple) {
+  return new Procedure(tuple.first, ProcedureKind.Method, tuple.second,
+      isStatic: true);
+}
+
+Case<Procedure> procedureSerializer =
+    new Case.uninitialized(const ProcedureTagger());
+
+class LibraryTagger implements Tagger<Library> {
+  const LibraryTagger();
+
+  String tag(Library node) {
+    return node.isNonNullableByDefault ? "null-safe" : "legacy";
+  }
+}
+
+TextSerializer<Library> libraryContentsSerializer = new Wrapped(
+  unwrapLibraryNode,
+  wrapLibraryNode,
+  new Tuple2Serializer(
+      const UriSerializer(), new ListSerializer(procedureSerializer)),
+);
+
+Tuple2<Uri, List<Procedure>> unwrapLibraryNode(Library library) {
+  return new Tuple2(library.importUri, library.procedures);
+}
+
+Library wrapLibraryNode(Tuple2<Uri, List<Procedure>> tuple) {
+  return new Library(tuple.first, procedures: tuple.second);
+}
+
+Case<Library> librarySerializer = new Case.uninitialized(const LibraryTagger());
+
 void initializeSerializers() {
-  expressionSerializer.tags.addAll([
-    "string",
-    "int",
-    "double",
-    "bool",
-    "null",
-    "invalid",
-    "not",
-    "&&",
-    "||",
-    "concat",
-    "symbol",
-    "this",
-    "rethrow",
-    "throw",
-    "await",
-    "cond",
-    "is",
-    "as",
-    "type",
-    "list",
-    "const-list",
-    "set",
-    "const-set",
-    "map",
-    "const-map",
-    "let",
-    "get-prop",
-    "set-prop",
-    "get-super",
-    "set-super",
-    "invoke-method",
-    "invoke-super",
-    "get-var",
-    "set-var",
-    "get-static",
-    "set-static",
-    "get-direct-prop",
-    "set-direct-prop",
-    "invoke-static",
-    "invoke-const-static",
-    "invoke-direct-method",
-    "invoke-constructor",
-    "invoke-const-constructor",
-    "fun",
-  ]);
-  expressionSerializer.serializers.addAll([
-    stringLiteralSerializer,
-    intLiteralSerializer,
-    doubleLiteralSerializer,
-    boolLiteralSerializer,
-    nullLiteralSerializer,
-    invalidExpressionSerializer,
-    notSerializer,
-    logicalAndSerializer,
-    logicalOrSerializer,
-    stringConcatenationSerializer,
-    symbolLiteralSerializer,
-    thisExpressionSerializer,
-    rethrowSerializer,
-    throwSerializer,
-    awaitExpressionSerializer,
-    conditionalExpressionSerializer,
-    isExpressionSerializer,
-    asExpressionSerializer,
-    typeLiteralSerializer,
-    listLiteralSerializer,
-    constListLiteralSerializer,
-    setLiteralSerializer,
-    constSetLiteralSerializer,
-    mapLiteralSerializer,
-    constMapLiteralSerializer,
-    letSerializer,
-    propertyGetSerializer,
-    propertySetSerializer,
-    superPropertyGetSerializer,
-    superPropertySetSerializer,
-    methodInvocationSerializer,
-    superMethodInvocationSerializer,
-    variableGetSerializer,
-    variableSetSerializer,
-    staticGetSerializer,
-    staticSetSerializer,
-    directPropertyGetSerializer,
-    directPropertySetSerializer,
-    staticInvocationSerializer,
-    constStaticInvocationSerializer,
-    directMethodInvocationSerializer,
-    constructorInvocationSerializer,
-    constConstructorInvocationSerializer,
-    functionExpressionSerializer,
-  ]);
-  dartTypeSerializer.tags.addAll([
-    "invalid",
-    "dynamic",
-    "void",
-    "bottom",
-    "->",
-    "par",
-  ]);
-  dartTypeSerializer.serializers.addAll([
-    invalidTypeSerializer,
-    dynamicTypeSerializer,
-    voidTypeSerializer,
-    bottomTypeSerializer,
-    functionTypeSerializer,
-    typeParameterTypeSerializer,
-  ]);
-  statementSerializer.tags.addAll([
-    "expr",
-    "ret",
-  ]);
-  statementSerializer.serializers.addAll([
-    expressionStatementSerializer,
-    returnStatementSerializer,
-  ]);
-  functionNodeSerializer.tags.addAll([
-    "sync",
-    "async",
-    "sync-star",
-    "async-star",
-    "sync-yielding",
-  ]);
-  functionNodeSerializer.serializers.addAll([
-    syncFunctionNodeSerializer,
-    asyncFunctionNodeSerializer,
-    syncStarFunctionNodeSerializer,
-    asyncStarFunctionNodeSerializer,
-    syncYieldingStarFunctionNodeSerializer,
-  ]);
+  expressionSerializer.registerTags({
+    "string": stringLiteralSerializer,
+    "int": intLiteralSerializer,
+    "double": doubleLiteralSerializer,
+    "bool": boolLiteralSerializer,
+    "null": nullLiteralSerializer,
+    "invalid": invalidExpressionSerializer,
+    "not": notSerializer,
+    "&&": logicalAndSerializer,
+    "||": logicalOrSerializer,
+    "concat": stringConcatenationSerializer,
+    "symbol": symbolLiteralSerializer,
+    "this": thisExpressionSerializer,
+    "rethrow": rethrowSerializer,
+    "throw": throwSerializer,
+    "await": awaitExpressionSerializer,
+    "cond": conditionalExpressionSerializer,
+    "is": isExpressionSerializer,
+    "as": asExpressionSerializer,
+    "type": typeLiteralSerializer,
+    "list": listLiteralSerializer,
+    "const-list": constListLiteralSerializer,
+    "set": setLiteralSerializer,
+    "const-set": constSetLiteralSerializer,
+    "map": mapLiteralSerializer,
+    "const-map": constMapLiteralSerializer,
+    "let": letSerializer,
+    "get-prop": propertyGetSerializer,
+    "set-prop": propertySetSerializer,
+    "get-super": superPropertyGetSerializer,
+    "set-super": superPropertySetSerializer,
+    "invoke-method": methodInvocationSerializer,
+    "invoke-super": superMethodInvocationSerializer,
+    "get-var": variableGetSerializer,
+    "set-var": variableSetSerializer,
+    "get-static": staticGetSerializer,
+    "set-static": staticSetSerializer,
+    "get-direct-prop": directPropertyGetSerializer,
+    "set-direct-prop": directPropertySetSerializer,
+    "invoke-static": staticInvocationSerializer,
+    "invoke-const-static": constStaticInvocationSerializer,
+    "invoke-direct-method": directMethodInvocationSerializer,
+    "invoke-constructor": constructorInvocationSerializer,
+    "invoke-const-constructor": constConstructorInvocationSerializer,
+    "fun": functionExpressionSerializer,
+  });
+  dartTypeSerializer.registerTags({
+    "invalid": invalidTypeSerializer,
+    "dynamic": dynamicTypeSerializer,
+    "void": voidTypeSerializer,
+    "bottom": bottomTypeSerializer,
+    "->": functionTypeSerializer,
+    "par": typeParameterTypeSerializer,
+    "interface": interfaceTypeSerializer,
+  });
+  statementSerializer.registerTags({
+    "expr": expressionStatementSerializer,
+    "ret": returnStatementSerializer,
+  });
+  functionNodeSerializer.registerTags({
+    "sync": syncFunctionNodeSerializer,
+    "async": asyncFunctionNodeSerializer,
+    "sync-star": syncStarFunctionNodeSerializer,
+    "async-star": asyncStarFunctionNodeSerializer,
+    "sync-yielding": syncYieldingStarFunctionNodeSerializer,
+  });
+  procedureSerializer.registerTags({"static-method": staticMethodSerializer});
+  librarySerializer.registerTags({
+    "legacy": libraryContentsSerializer,
+    "null-safe": libraryContentsSerializer,
+  });
 }
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 25d1d41..6d4444b 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -155,24 +155,42 @@
     //  }
     final CoreTypes coreTypes = staticTypeContext.typeEnvironment.coreTypes;
 
-    // TODO(39565): We should be able to use forInElementType.
-    helper.unsafeCast;
-    final DartType iterableType =
-        stmt.iterable.getStaticType(staticTypeContext);
-    final DartType iterationType = iterableType is InterfaceType
-        ? staticTypeContext.typeEnvironment.forInElementType(stmt, iterableType)
-        : DynamicType();
-    final expectedIterableType = InterfaceType(
-        coreTypes.iterableClass, Nullability.legacy, [iterationType]);
-    final iteratorType = InterfaceType(
-        coreTypes.iteratorClass, Nullability.legacy, [iterationType]);
+    DartType iterableType = stmt.iterable.getStaticType(staticTypeContext);
+    while (iterableType is TypeParameterType) {
+      TypeParameterType typeParameterType = iterableType;
+      iterableType =
+          typeParameterType.promotedBound ?? typeParameterType.parameter.bound;
+    }
 
-    // TODO(39566): Iterable expression is not always well typed in the AST.
-    final typedIterable = StaticInvocation(helper.unsafeCast,
-        Arguments([stmt.iterable], types: [expectedIterableType]));
+    // The CFE might invoke this transformation despite the program having
+    // compile-time errors. So we will not transform this [stmt] if the
+    // `stmt.iterable` is not a subtype of non-nullable/legacy Iterable.
+    if (iterableType is! InterfaceType ||
+        !staticTypeContext.typeEnvironment.isSubtypeOf(
+            iterableType,
+            coreTypes.iterableRawType(staticTypeContext.nonNullable),
+            staticTypeContext.isNonNullableByDefault
+                ? SubtypeCheckMode.withNullabilities
+                : SubtypeCheckMode.ignoringNullabilities)) {
+      return super.visitForInStatement(stmt);
+    }
+
+    final DartType iterationType = staticTypeContext.typeEnvironment
+        .forInElementType(stmt, (iterableType as InterfaceType));
+
+    // The NNBD sdk declares that Iterable.get:iterator returns a non-nullable
+    // `Iterator<E>`.
+    assert(const [
+      Nullability.nonNullable,
+      Nullability.legacy
+    ].contains(coreTypes.iterableGetIterator.function.returnType.nullability));
+
+    final iteratorType = InterfaceType(coreTypes.iteratorClass,
+        staticTypeContext.nonNullable, [iterationType]);
+
     final iterator = VariableDeclaration(':sync-for-iterator',
         initializer: PropertyGet(
-            typedIterable, Name('iterator'), coreTypes.iterableGetIterator)
+            stmt.iterable, Name('iterator'), coreTypes.iterableGetIterator)
           ..fileOffset = stmt.iterable.fileOffset,
         type: iteratorType)
       ..fileOffset = stmt.iterable.fileOffset;
@@ -382,14 +400,16 @@
 }
 
 abstract class AsyncRewriterBase extends ContinuationRewriterBase {
-  final VariableDeclaration nestedClosureVariable =
-      new VariableDeclaration(":async_op");
-  final VariableDeclaration stackTraceVariable =
-      new VariableDeclaration(ContinuationVariables.asyncStackTraceVar);
-  final VariableDeclaration thenContinuationVariable =
-      new VariableDeclaration(":async_op_then");
-  final VariableDeclaration catchErrorContinuationVariable =
-      new VariableDeclaration(":async_op_error");
+  final VariableDeclaration stackTraceVariable;
+
+  // :async_op has type ([dynamic result, dynamic e, StackTrace? s]) -> dynamic
+  final VariableDeclaration nestedClosureVariable;
+
+  // :async_op_then has type (dynamic result) -> dynamic
+  final VariableDeclaration thenContinuationVariable;
+
+  // :async_op_error has type (Object e, StackTrace s) -> dynamic
+  final VariableDeclaration catchErrorContinuationVariable;
 
   LabeledStatement labeledBody;
 
@@ -397,7 +417,24 @@
 
   AsyncRewriterBase(HelperNodes helper, FunctionNode enclosingFunction,
       StaticTypeContext staticTypeContext)
-      : super(helper, enclosingFunction, staticTypeContext) {}
+      : stackTraceVariable =
+            VariableDeclaration(ContinuationVariables.asyncStackTraceVar),
+        nestedClosureVariable = VariableDeclaration(":async_op",
+            type: FunctionType([
+              const DynamicType(),
+              const DynamicType(),
+              helper.coreTypes.stackTraceRawType(staticTypeContext.nullable),
+            ], const DynamicType(), staticTypeContext.nonNullable,
+                requiredParameterCount: 0)),
+        thenContinuationVariable = VariableDeclaration(":async_op_then",
+            type: FunctionType(const [const DynamicType()], const DynamicType(),
+                staticTypeContext.nonNullable)),
+        catchErrorContinuationVariable = VariableDeclaration(":async_op_error",
+            type: FunctionType([
+              helper.coreTypes.objectRawType(staticTypeContext.nonNullable),
+              helper.coreTypes.stackTraceRawType(staticTypeContext.nonNullable),
+            ], const DynamicType(), staticTypeContext.nonNullable)),
+        super(helper, enclosingFunction, staticTypeContext) {}
 
   void setupAsyncContinuations(List<Statement> statements) {
     expressionRewriter = new ExpressionLifter(this);
@@ -476,7 +513,9 @@
     --currentTryDepth;
 
     var exceptionVariable = new VariableDeclaration(":exception");
-    var stackTraceVariable = new VariableDeclaration(":stack_trace");
+    var stackTraceVariable = new VariableDeclaration(":stack_trace",
+        type:
+            helper.coreTypes.stackTraceRawType(staticTypeContext.nonNullable));
 
     return new TryCatch(
       buildReturn(labeledBody),
@@ -845,8 +884,9 @@
       //   }
       var valueVariable = stmt.variable;
 
-      var streamVariable =
-          new VariableDeclaration(':stream', initializer: stmt.iterable);
+      var streamVariable = new VariableDeclaration(':stream',
+          initializer: stmt.iterable,
+          type: stmt.iterable.getStaticType(staticTypeContext));
 
       var asyncStarListenHelper = new ExpressionStatement(new StaticInvocation(
           helper.asyncStarListenHelper,
@@ -1173,7 +1213,8 @@
     var startStatement = new ExpressionStatement(new MethodInvocation(
         new VariableGet(completerVariable),
         new Name('start'),
-        new Arguments([new VariableGet(nestedClosureVariable)]))
+        new Arguments([new VariableGet(nestedClosureVariable)]),
+        helper.asyncAwaitCompleterStartProcedure)
       ..fileOffset = enclosingFunction.fileOffset);
     statements.add(startStatement);
     // return :async_completer.future;
@@ -1243,6 +1284,7 @@
   final Class asyncAwaitCompleterClass;
   final Member completerCompleteError;
   final Member asyncAwaitCompleterConstructor;
+  final Member asyncAwaitCompleterStartProcedure;
   final Member completeOnAsyncReturn;
   final Member completerFuture;
   final Library coreLibrary;
@@ -1283,6 +1325,7 @@
       this.asyncAwaitCompleterClass,
       this.completerCompleteError,
       this.asyncAwaitCompleterConstructor,
+      this.asyncAwaitCompleterStartProcedure,
       this.completeOnAsyncReturn,
       this.completerFuture,
       this.coreLibrary,
@@ -1323,6 +1366,7 @@
         coreTypes.asyncAwaitCompleterClass,
         coreTypes.completerCompleteError,
         coreTypes.asyncAwaitCompleterConstructor,
+        coreTypes.asyncAwaitCompleterStartProcedure,
         coreTypes.completeOnAsyncReturn,
         coreTypes.completerFuture,
         coreTypes.coreLibrary,
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 44a7285..3a0bc0dd 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -7,6 +7,7 @@
 import 'package:meta/meta.dart';
 
 import '../ast.dart';
+import '../target/changed_structure_notifier.dart';
 
 // Parameter name used to track were widget constructor calls were made from.
 //
@@ -309,11 +310,13 @@
   Class _widgetClass;
   Class _locationClass;
 
+  final ChangedStructureNotifier _changedStructureNotifier;
+
   /// Marker interface indicating that a private _location field is
   /// available.
   Class _hasCreationLocationClass;
 
-  WidgetCreatorTracker();
+  WidgetCreatorTracker(this._changedStructureNotifier);
 
   void _resolveFlutterClasses(Iterable<Library> libraries) {
     // If the Widget or Debug location classes have been updated we need to get
@@ -358,6 +361,8 @@
     }
     clazz.implementedTypes
         .add(new Supertype(_hasCreationLocationClass, <DartType>[]));
+    _changedStructureNotifier?.registerClassHierarchyChange(clazz);
+
     // We intentionally use the library context of the _HasCreationLocation
     // class for the private field even if [clazz] is in a different library
     // so that all classes implementing Widget behave consistently.
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 5af2a2d..fbe87af 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -475,6 +475,7 @@
 
   DartType visit(DartType node) => node.accept(this);
 
+  DartType defaultDartType(DartType node) => node;
   DartType visitInvalidType(InvalidType node) => node;
   DartType visitDynamicType(DynamicType node) => node;
   DartType visitVoidType(VoidType node) => node;
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index 5320c4a..a5ef956 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -6,22 +6,23 @@
 import 'ast.dart';
 import 'class_hierarchy.dart';
 import 'core_types.dart';
-import 'type_algebra.dart';
 
 import 'src/future_or.dart';
 import 'src/hierarchy_based_type_environment.dart'
     show HierarchyBasedTypeEnvironment;
+import 'src/types.dart';
 
 typedef void ErrorHandler(TreeNode node, String message);
 
-abstract class TypeEnvironment extends SubtypeTester {
+abstract class TypeEnvironment extends Types {
   final CoreTypes coreTypes;
 
   /// An error handler for use in debugging, or `null` if type errors should not
   /// be tolerated.  See [typeError].
   ErrorHandler errorHandler;
 
-  TypeEnvironment.fromSubclass(this.coreTypes);
+  TypeEnvironment.fromSubclass(this.coreTypes, ClassHierarchyBase base)
+      : super(base);
 
   factory TypeEnvironment(CoreTypes coreTypes, ClassHierarchy hierarchy) {
     return new HierarchyBasedTypeEnvironment(coreTypes, hierarchy);
@@ -309,11 +310,12 @@
           unwrappedSupertype =
               (unwrappedSupertype as InterfaceType).typeArguments.single;
         }
-        if (unwrappedSubtype is TypeParameterType &&
-            unwrappedSubtype.promotedBound == null &&
-            unwrappedSupertype is TypeParameterType &&
-            unwrappedSupertype.promotedBound == null &&
-            unwrappedSubtype.parameter == unwrappedSupertype.parameter) {
+        Nullability unwrappedSubtypeNullability =
+            computeNullability(unwrappedSubtype, futureOrClass);
+        Nullability unwrappedSupertypeNullability =
+            computeNullability(unwrappedSupertype, futureOrClass);
+        if (unwrappedSubtypeNullability == unwrappedSupertypeNullability) {
+          // The relationship between the types must be established elsewhere.
           return const IsSubtypeOf.always();
         }
       }
@@ -343,7 +345,7 @@
   /// [IsSubtypeOf.never] because the right-hand side will not change the
   /// overall result anyway.
   IsSubtypeOf andSubtypeCheckFor(
-      DartType subtype, DartType supertype, SubtypeTester tester) {
+      DartType subtype, DartType supertype, Types tester) {
     if (_value == _valueNever) return this;
     return this
         .and(tester.performNullabilityAwareSubtypeCheck(subtype, supertype));
@@ -370,7 +372,7 @@
   /// as [IsSubtypeOf.always] because the right-hand side will not change the
   /// overall result anyway.
   IsSubtypeOf orSubtypeCheckFor(
-      DartType subtype, DartType supertype, SubtypeTester tester) {
+      DartType subtype, DartType supertype, Types tester) {
     if (_value == _valueAlways) return this;
     return this
         .or(tester.performNullabilityAwareSubtypeCheck(subtype, supertype));
@@ -402,340 +404,6 @@
   ignoringNullabilities,
 }
 
-/// The part of [TypeEnvironment] that deals with subtype tests.
-///
-/// This lives in a separate class so it can be tested independently of the SDK.
-abstract class SubtypeTester {
-  InterfaceType get objectLegacyRawType;
-  InterfaceType get objectNullableRawType;
-  InterfaceType get nullType;
-  InterfaceType get functionLegacyRawType;
-  Class get objectClass;
-  Class get functionClass;
-  Class get futureOrClass;
-  InterfaceType futureType(DartType type, Nullability nullability);
-
-  static List<Object> typeChecks;
-
-  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
-      Library clientLibrary, CoreTypes coreTypes);
-
-  List<DartType> getTypeArgumentsAsInstanceOf(
-      InterfaceType type, Class superclass);
-
-  /// Determines if the given type is at the top of the type hierarchy.  May be
-  /// overridden in subclasses.
-  bool isTop(DartType type) {
-    return type is DynamicType ||
-        type is VoidType ||
-        type == objectLegacyRawType ||
-        type == objectNullableRawType;
-  }
-
-  /// Can be use to collect type checks. To use:
-  /// 1. Rename `isSubtypeOf` to `_isSubtypeOf`.
-  /// 2. Rename `_collect_isSubtypeOf` to `isSubtypeOf`.
-  /// 3. Comment out the call to `_isSubtypeOf` below.
-  // ignore:unused_element
-  bool _collect_isSubtypeOf(
-      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
-    bool result = true;
-    //result = _isSubtypeOf(subtype, supertype, mode);
-    typeChecks ??= <Object>[];
-    typeChecks.add([subtype, supertype, result]);
-    return result;
-  }
-
-  /// Returns true if [subtype] is a subtype of [supertype].
-  bool isSubtypeOf(
-      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
-    IsSubtypeOf result =
-        performNullabilityAwareSubtypeCheck(subtype, supertype);
-    switch (mode) {
-      case SubtypeCheckMode.ignoringNullabilities:
-        return result.isSubtypeWhenIgnoringNullabilities();
-      case SubtypeCheckMode.withNullabilities:
-        return result.isSubtypeWhenUsingNullabilities();
-      default:
-        throw new StateError("Unhandled subtype checking mode '$mode'");
-    }
-  }
-
-  /// Performs a nullability-aware subtype check.
-  ///
-  /// The outcome is described in the comments to [IsSubtypeOf].
-  IsSubtypeOf performNullabilityAwareSubtypeCheck(
-      DartType subtype, DartType supertype) {
-    subtype = subtype.unalias;
-    supertype = supertype.unalias;
-    if (identical(subtype, supertype)) return const IsSubtypeOf.always();
-    if (subtype is BottomType) return const IsSubtypeOf.always();
-    if (subtype is NeverType) {
-      return supertype is BottomType
-          ? const IsSubtypeOf.never()
-          : new IsSubtypeOf.basedSolelyOnNullabilities(
-              subtype, supertype, futureOrClass);
-    }
-    if (subtype == nullType) {
-      // TODO(dmitryas): Remove InvalidType from subtype relation.
-      if (supertype is InvalidType) {
-        // The return value is supposed to keep the backward compatibility.
-        return const IsSubtypeOf.always();
-      }
-
-      Nullability supertypeNullability =
-          computeNullability(supertype, futureOrClass);
-      if (supertypeNullability == Nullability.nullable ||
-          supertypeNullability == Nullability.legacy) {
-        return const IsSubtypeOf.always();
-      }
-      // See rule 4 of the subtype rules from the Dart Language Specification.
-      return supertype is BottomType || supertype is NeverType
-          ? const IsSubtypeOf.never()
-          : const IsSubtypeOf.onlyIfIgnoringNullabilities();
-    }
-    if (isTop(supertype)) return const IsSubtypeOf.always();
-
-    // Handle FutureOr<T> union type.
-    if (subtype is InterfaceType &&
-        identical(subtype.classNode, futureOrClass)) {
-      var subtypeArg = subtype.typeArguments[0];
-      if (supertype is InterfaceType &&
-          identical(supertype.classNode, futureOrClass)) {
-        DartType supertypeArg = supertype.typeArguments[0];
-        Nullability subtypeNullability =
-            computeNullabilityOfFutureOr(subtype, futureOrClass);
-        Nullability supertypeNullability =
-            computeNullabilityOfFutureOr(supertype, futureOrClass);
-        // The following is an optimized is-subtype-of test for the case where
-        // both LHS and RHS are FutureOrs.  It's based on the following:
-        // FutureOr<X> <: FutureOr<Y> iff X <: Y OR (X <: Future<Y> AND
-        // Future<X> <: Y).
-        //
-        // The correctness of that can be shown as follows:
-        //   1. FutureOr<X> <: Y iff X <: Y AND Future<X> <: Y
-        //   2. X <: FutureOr<Y> iff X <: Y OR X <: Future<Y>
-        //   3. 1,2 => FutureOr<X> <: FutureOr<Y> iff
-        //          (X <: Y OR X <: Future<Y>) AND
-        //            (Future<X> <: Y OR Future<X> <: Future<Y>)
-        //   4. X <: Y iff Future<X> <: Future<Y>
-        //   5. 3,4 => FutureOr<X> <: FutureOr<Y> iff
-        //          (X <: Y OR X <: Future<Y>) AND
-        //            (X <: Y OR Future<X> <: Y) iff
-        //          X <: Y OR (X <: Future<Y> AND Future<X> <: Y)
-        return performNullabilityAwareSubtypeCheck(subtypeArg, supertypeArg)
-            .or(performNullabilityAwareSubtypeCheck(subtypeArg,
-                    futureType(supertypeArg, Nullability.nonNullable))
-                .andSubtypeCheckFor(
-                    futureType(subtypeArg, Nullability.nonNullable),
-                    supertypeArg,
-                    this))
-            .and(new IsSubtypeOf.basedSolelyOnNullabilities(
-                subtype.withNullability(subtypeNullability),
-                supertype.withNullability(supertypeNullability),
-                futureOrClass));
-      }
-
-      // given t1 is Future<A> | A, then:
-      // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
-      return performNullabilityAwareSubtypeCheck(subtypeArg, supertype)
-          .andSubtypeCheckFor(
-              futureType(subtypeArg, Nullability.nonNullable), supertype, this)
-          .and(new IsSubtypeOf.basedSolelyOnNullabilities(
-              subtype, supertype, futureOrClass));
-    }
-
-    if (supertype is InterfaceType && supertype.classNode == objectClass) {
-      assert(supertype.nullability == Nullability.nonNullable);
-      return new IsSubtypeOf.basedSolelyOnNullabilities(
-          subtype, supertype, futureOrClass);
-    }
-
-    if (supertype is InterfaceType &&
-        identical(supertype.classNode, futureOrClass)) {
-      // given t2 is Future<A> | A, then:
-      // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
-      Nullability unitedNullability =
-          computeNullabilityOfFutureOr(supertype, futureOrClass);
-      DartType supertypeArg = supertype.typeArguments[0];
-      DartType supertypeFuture = futureType(supertypeArg, unitedNullability);
-      return performNullabilityAwareSubtypeCheck(subtype, supertypeFuture)
-          .orSubtypeCheckFor(
-              subtype, supertypeArg.withNullability(unitedNullability), this);
-    }
-
-    if (subtype is InterfaceType && supertype is InterfaceType) {
-      Class supertypeClass = supertype.classNode;
-      List<DartType> upcastTypeArguments =
-          getTypeArgumentsAsInstanceOf(subtype, supertypeClass);
-      if (upcastTypeArguments == null) return const IsSubtypeOf.never();
-      IsSubtypeOf result = const IsSubtypeOf.always();
-      for (int i = 0; i < upcastTypeArguments.length; ++i) {
-        // Termination: the 'supertype' parameter decreases in size.
-        int variance = supertypeClass.typeParameters[i].variance;
-        DartType leftType = upcastTypeArguments[i];
-        DartType rightType = supertype.typeArguments[i];
-        if (variance == Variance.contravariant) {
-          result = result
-              .and(performNullabilityAwareSubtypeCheck(rightType, leftType));
-          if (!result.isSubtypeWhenIgnoringNullabilities()) {
-            return const IsSubtypeOf.never();
-          }
-        } else if (variance == Variance.invariant) {
-          result = result.and(
-              performNullabilityAwareMutualSubtypesCheck(leftType, rightType));
-          if (!result.isSubtypeWhenIgnoringNullabilities()) {
-            return const IsSubtypeOf.never();
-          }
-        } else {
-          result = result
-              .and(performNullabilityAwareSubtypeCheck(leftType, rightType));
-          if (!result.isSubtypeWhenIgnoringNullabilities()) {
-            return const IsSubtypeOf.never();
-          }
-        }
-      }
-      return result.and(new IsSubtypeOf.basedSolelyOnNullabilities(
-          subtype, supertype, futureOrClass));
-    }
-    if (subtype is TypeParameterType) {
-      if (supertype is TypeParameterType) {
-        IsSubtypeOf result = const IsSubtypeOf.always();
-        if (subtype.parameter == supertype.parameter) {
-          if (supertype.promotedBound != null) {
-            return performNullabilityAwareSubtypeCheck(
-                    subtype,
-                    new TypeParameterType(supertype.parameter,
-                        supertype.typeParameterTypeNullability))
-                .andSubtypeCheckFor(subtype, supertype.bound, this);
-          } else {
-            // Promoted bound should always be a subtype of the declared bound.
-            // TODO(dmitryas): Use the following assertion when type promotion
-            // is updated.
-            // assert(subtype.promotedBound == null ||
-            //     performNullabilityAwareSubtypeCheck(
-            //         subtype.bound, supertype.bound)
-            //         .isSubtypeWhenUsingNullabilities());
-            assert(subtype.promotedBound == null ||
-                performNullabilityAwareSubtypeCheck(
-                        subtype.bound, supertype.bound)
-                    .isSubtypeWhenIgnoringNullabilities());
-            result = const IsSubtypeOf.always();
-          }
-        } else {
-          result =
-              performNullabilityAwareSubtypeCheck(subtype.bound, supertype);
-        }
-        if (subtype.nullability == Nullability.undetermined &&
-            supertype.nullability == Nullability.undetermined) {
-          // The two nullabilities are undetermined, but are connected via
-          // additional constraint, namely that they will be equal at run time.
-          return result;
-        }
-        return result.and(new IsSubtypeOf.basedSolelyOnNullabilities(
-            subtype, supertype, futureOrClass));
-      }
-      // Termination: if there are no cyclically bound type parameters, this
-      // recursive call can only occur a finite number of times, before reaching
-      // a shrinking recursive call (or terminating).
-      return performNullabilityAwareSubtypeCheck(subtype.bound, supertype).and(
-          new IsSubtypeOf.basedSolelyOnNullabilities(
-              subtype, supertype, futureOrClass));
-    }
-    if (subtype is FunctionType) {
-      if (supertype is InterfaceType && supertype.classNode == functionClass) {
-        return new IsSubtypeOf.basedSolelyOnNullabilities(
-            subtype, supertype, futureOrClass);
-      }
-      if (supertype is FunctionType) {
-        return _performNullabilityAwareFunctionSubtypeCheck(subtype, supertype);
-      }
-    }
-    return const IsSubtypeOf.never();
-  }
-
-  IsSubtypeOf performNullabilityAwareMutualSubtypesCheck(
-      DartType type1, DartType type2) {
-    // TODO(dmitryas): Replace it with one recursive descent instead of two.
-    return performNullabilityAwareSubtypeCheck(type1, type2)
-        .andSubtypeCheckFor(type2, type1, this);
-  }
-
-  IsSubtypeOf _performNullabilityAwareFunctionSubtypeCheck(
-      FunctionType subtype, FunctionType supertype) {
-    if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
-      return const IsSubtypeOf.never();
-    }
-    if (subtype.positionalParameters.length <
-        supertype.positionalParameters.length) {
-      return const IsSubtypeOf.never();
-    }
-    if (subtype.typeParameters.length != supertype.typeParameters.length) {
-      return const IsSubtypeOf.never();
-    }
-
-    IsSubtypeOf result = const IsSubtypeOf.always();
-    if (subtype.typeParameters.isNotEmpty) {
-      var substitution = <TypeParameter, DartType>{};
-      for (int i = 0; i < subtype.typeParameters.length; ++i) {
-        var subParameter = subtype.typeParameters[i];
-        var superParameter = supertype.typeParameters[i];
-        substitution[subParameter] = new TypeParameterType.forAlphaRenaming(
-            subParameter, superParameter);
-      }
-      for (int i = 0; i < subtype.typeParameters.length; ++i) {
-        var subParameter = subtype.typeParameters[i];
-        var superParameter = supertype.typeParameters[i];
-        var subBound = substitute(subParameter.bound, substitution);
-        // Termination: if there are no cyclically bound type parameters, this
-        // recursive call can only occur a finite number of times before
-        // reaching a shrinking recursive call (or terminating).
-        result = result.and(performNullabilityAwareMutualSubtypesCheck(
-            superParameter.bound, subBound));
-        if (!result.isSubtypeWhenIgnoringNullabilities()) {
-          return const IsSubtypeOf.never();
-        }
-      }
-      subtype = substitute(subtype.withoutTypeParameters, substitution);
-    }
-    result = result.and(performNullabilityAwareSubtypeCheck(
-        subtype.returnType, supertype.returnType));
-    if (!result.isSubtypeWhenIgnoringNullabilities()) {
-      return const IsSubtypeOf.never();
-    }
-    for (int i = 0; i < supertype.positionalParameters.length; ++i) {
-      var supertypeParameter = supertype.positionalParameters[i];
-      var subtypeParameter = subtype.positionalParameters[i];
-      // Termination: Both types shrink in size.
-      result = result.and(performNullabilityAwareSubtypeCheck(
-          supertypeParameter, subtypeParameter));
-      if (!result.isSubtypeWhenIgnoringNullabilities()) {
-        return const IsSubtypeOf.never();
-      }
-    }
-    int subtypeNameIndex = 0;
-    for (NamedType supertypeParameter in supertype.namedParameters) {
-      while (subtypeNameIndex < subtype.namedParameters.length &&
-          subtype.namedParameters[subtypeNameIndex].name !=
-              supertypeParameter.name) {
-        ++subtypeNameIndex;
-      }
-      if (subtypeNameIndex == subtype.namedParameters.length) {
-        return const IsSubtypeOf.never();
-      }
-      NamedType subtypeParameter = subtype.namedParameters[subtypeNameIndex];
-      // Termination: Both types shrink in size.
-      result = result.and(performNullabilityAwareSubtypeCheck(
-          supertypeParameter.type, subtypeParameter.type));
-      if (!result.isSubtypeWhenIgnoringNullabilities()) {
-        return const IsSubtypeOf.never();
-      }
-    }
-    return result.and(new IsSubtypeOf.basedSolelyOnNullabilities(
-        subtype, supertype, futureOrClass));
-  }
-}
-
 /// Context object needed for computing `Expression.getStaticType`.
 ///
 /// The [StaticTypeContext] provides access to the [TypeEnvironment] and the
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 59cec06..78cd33e 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -178,6 +178,10 @@
         problem(
             currentParent, "Missing bound for type parameter '$parameter'.");
       }
+      if (parameter.defaultType == null) {
+        problem(currentParent,
+            "Missing default type for type parameter '$parameter'.");
+      }
       if (!typeParametersInScope.add(parameter)) {
         problem(parameter, "Type parameter '$parameter' redeclared.");
       }
diff --git a/pkg/kernel/test/binary/component_mode_test.dart b/pkg/kernel/test/binary/component_mode_test.dart
new file mode 100644
index 0000000..d30c99d
--- /dev/null
+++ b/pkg/kernel/test/binary/component_mode_test.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/binary/ast_from_binary.dart';
+
+import 'utils.dart';
+
+main() {
+  setCompileMode(Component c, NonNullableByDefaultCompiledMode mode) {
+    c.setMainMethodAndMode(null, true, mode);
+  }
+
+  verifyMode(Component c, NonNullableByDefaultCompiledMode mode) {
+    if (c.mode != mode) {
+      throw "Serialized and re-read component had change in mode: "
+          "Expected $mode got ${c.mode}.";
+    }
+  }
+
+  const List<NonNullableByDefaultCompiledMode> modes = const [
+    NonNullableByDefaultCompiledMode.Disabled,
+    NonNullableByDefaultCompiledMode.Weak,
+    NonNullableByDefaultCompiledMode.Strong,
+    NonNullableByDefaultCompiledMode.Agnostic,
+  ];
+
+  int combination = 0;
+  for (NonNullableByDefaultCompiledMode c1Mode in modes) {
+    for (NonNullableByDefaultCompiledMode c2Mode in modes) {
+      combination++;
+      print("Checking combination #$combination ("
+          "c1Mode: $c1Mode; "
+          "c2Mode: $c2Mode; "
+          ")");
+
+      // Try individually.
+      List<int> c1Serialized;
+      {
+        Library lib1 = new Library(Uri.parse("foo://bar.dart"));
+        Component c1 = new Component(libraries: [lib1]);
+        setCompileMode(c1, c1Mode);
+        c1Serialized = serializeComponent(c1);
+        Component c1RoundTrip = loadComponentFromBytes(c1Serialized);
+        verifyMode(c1RoundTrip, c1Mode);
+      }
+
+      List<int> c2Serialized;
+      {
+        Library lib2 = new Library(Uri.parse("foo://baz.dart"));
+        Component c2 = new Component(libraries: [lib2]);
+        setCompileMode(c2, c2Mode);
+        c2Serialized = serializeComponent(c2);
+        Component c2RoundTrip = loadComponentFromBytes(c2Serialized);
+        verifyMode(c2RoundTrip, c2Mode);
+      }
+
+      // Try with combined binary.
+      try {
+        List<int> combined = [];
+        combined.addAll(c1Serialized);
+        combined.addAll(c2Serialized);
+        Component combinedRoundTrip = loadComponentFromBytes(combined);
+        verifyMode(combinedRoundTrip, verifyOK(c1Mode, c2Mode));
+        print(" -> OK with $c1Mode and $c2Mode");
+      } on CompilationModeError catch (e) {
+        print(" -> Got $e with $c1Mode and $c2Mode");
+        verifyError(c1Mode, c2Mode);
+      }
+      // Try other order.
+      try {
+        List<int> combined = [];
+        combined.addAll(c2Serialized);
+        combined.addAll(c1Serialized);
+        Component combinedRoundTrip = loadComponentFromBytes(combined);
+        verifyMode(combinedRoundTrip, verifyOK(c1Mode, c2Mode));
+        print(" -> OK with $c1Mode and $c2Mode");
+      } on CompilationModeError catch (e) {
+        print(" -> Got $e with $c1Mode and $c2Mode");
+        verifyError(c1Mode, c2Mode);
+      }
+
+      // Try with individual binary, but loaded into same component.
+      try {
+        Component combinedRoundTrip = loadComponentFromBytes(c1Serialized);
+        combinedRoundTrip =
+            loadComponentFromBytes(c2Serialized, combinedRoundTrip);
+        verifyMode(combinedRoundTrip, verifyOK(c1Mode, c2Mode));
+        print(" -> OK with $c1Mode and $c2Mode");
+      } on CompilationModeError catch (e) {
+        print(" -> Got $e with $c1Mode and $c2Mode");
+        verifyError(c1Mode, c2Mode);
+      }
+      // Try other order.
+      try {
+        Component combinedRoundTrip = loadComponentFromBytes(c2Serialized);
+        combinedRoundTrip =
+            loadComponentFromBytes(c1Serialized, combinedRoundTrip);
+        verifyMode(combinedRoundTrip, verifyOK(c1Mode, c2Mode));
+        print(" -> OK with $c1Mode and $c2Mode");
+      } on CompilationModeError catch (e) {
+        print(" -> Got $e with $c1Mode and $c2Mode");
+        verifyError(c1Mode, c2Mode);
+      }
+
+      // Try with individual binary, but loaded into same component where
+      // component initially does not have a mode.
+      try {
+        Component combinedRoundTrip = new Component();
+        combinedRoundTrip =
+            loadComponentFromBytes(c1Serialized, combinedRoundTrip);
+        combinedRoundTrip =
+            loadComponentFromBytes(c2Serialized, combinedRoundTrip);
+        verifyMode(combinedRoundTrip, verifyOK(c1Mode, c2Mode));
+        print(" -> OK with $c1Mode and $c2Mode");
+      } on CompilationModeError catch (e) {
+        print(" -> Got $e with $c1Mode and $c2Mode");
+        verifyError(c1Mode, c2Mode);
+      }
+    }
+  }
+
+  print("Done: Everything looks good.");
+}
+
+bool isOK(NonNullableByDefaultCompiledMode c1Mode,
+    NonNullableByDefaultCompiledMode c2Mode) {
+  if (c1Mode == c2Mode) return true;
+  if (c1Mode == NonNullableByDefaultCompiledMode.Agnostic) return true;
+  if (c2Mode == NonNullableByDefaultCompiledMode.Agnostic) return true;
+  return false;
+}
+
+NonNullableByDefaultCompiledMode verifyOK(
+    NonNullableByDefaultCompiledMode c1Mode,
+    NonNullableByDefaultCompiledMode c2Mode) {
+  if (isOK(c1Mode, c2Mode)) {
+    if (c1Mode == NonNullableByDefaultCompiledMode.Agnostic) return c2Mode;
+    return c1Mode;
+  }
+  throw "Not OK combination: $c1Mode and $c2Mode";
+}
+
+void verifyError(NonNullableByDefaultCompiledMode c1Mode,
+    NonNullableByDefaultCompiledMode c2Mode) {
+  if (isOK(c1Mode, c2Mode)) {
+    throw "Unexpected error for $c1Mode and $c2Mode";
+  }
+}
diff --git a/pkg/kernel/test/binary/utils.dart b/pkg/kernel/test/binary/utils.dart
index 28bf4be..801f322 100644
--- a/pkg/kernel/test/binary/utils.dart
+++ b/pkg/kernel/test/binary/utils.dart
@@ -14,12 +14,16 @@
 
 List<Library> serializationRoundTrip(List<Library> libraries) {
   Component c = new Component(libraries: libraries);
+  List<int> bytes = serializeComponent(c);
+  Component c2 = loadComponentFromBytes(bytes);
+  return c2.libraries;
+}
+
+List<int> serializeComponent(Component c) {
   ByteSink byteSink = new ByteSink();
   BinaryPrinter printer = new BinaryPrinter(byteSink);
   printer.writeComponentFile(c);
-  List<int> bytes = byteSink.builder.takeBytes();
-  Component c2 = loadComponentFromBytes(bytes);
-  return c2.libraries;
+  return byteSink.builder.takeBytes();
 }
 
 /// A [Sink] that directly writes data into a byte builder.
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index 17c380a..3f6d770 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -118,7 +118,7 @@
 ''');
 
     // No updated classes, the same hierarchy.
-    expect(hierarchy.applyTreeChanges([], []), same(hierarchy));
+    expect(hierarchy.applyTreeChanges([], [], []), same(hierarchy));
 
     // Has updated classes, still the same hierarchy (instance). Can answer
     // queries about the new classes.
@@ -129,12 +129,13 @@
     component.libraries.add(libWithC);
     libWithC.addClass(c);
 
-    expect(hierarchy.applyTreeChanges([libWithB], [libWithC]), same(hierarchy));
+    expect(hierarchy.applyTreeChanges([libWithB], [libWithC], []),
+        same(hierarchy));
     expect(hierarchy.isSubclassOf(a, c), false);
     expect(hierarchy.isSubclassOf(c, a), true);
 
     // Remove so A should no longer be a super of anything.
-    expect(hierarchy.applyTreeChanges([libWithC], []), same(hierarchy));
+    expect(hierarchy.applyTreeChanges([libWithC], [], []), same(hierarchy));
   }
 
   void test_applyMemberChanges() {
diff --git a/pkg/kernel/test/nnbd_top_merge_test.dart b/pkg/kernel/test/nnbd_top_merge_test.dart
index da9bd8d..4eb5d40 100644
--- a/pkg/kernel/test/nnbd_top_merge_test.dart
+++ b/pkg/kernel/test/nnbd_top_merge_test.dart
@@ -17,10 +17,10 @@
   'Object vs Object': 'Object',
   'dynamic vs dynamic': 'dynamic',
   'void vs void': 'void',
-  'Object? vs void': 'void',
-  'Object* vs void': 'void',
+  'Object? vs void': 'Object?',
+  'Object* vs void': 'Object?',
   'Object vs void': null,
-  'dynamic vs void': 'void',
+  'dynamic vs void': 'Object?',
   'Object? vs dynamic': 'Object?',
   'Object* vs dynamic': 'Object?',
   'Object vs dynamic': null,
@@ -41,10 +41,10 @@
   'List<Object> vs List<Object>': 'List<Object>',
   'List<dynamic> vs List<dynamic>': 'List<dynamic>',
   'List<void> vs List<void>': 'List<void>',
-  'List<Object?> vs List<void>': 'List<void>',
-  'List<Object*> vs List<void>': 'List<void>',
+  'List<Object?> vs List<void>': 'List<Object?>',
+  'List<Object*> vs List<void>': 'List<Object?>',
   'List<Object> vs List<void>': null,
-  'List<dynamic> vs List<void>': 'List<void>',
+  'List<dynamic> vs List<void>': 'List<Object?>',
   'List<Object?> vs List<dynamic>': 'List<Object?>',
   'List<Object*> vs List<dynamic>': 'List<Object?>',
   'List<Object> vs List<dynamic>': null,
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 7eb39c7..8035631 100644
--- a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
+++ b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
@@ -13,61 +13,66 @@
   test();
 }
 
-// Wrappers for testing.
-Statement readStatement(String input, DeserializationState state) {
-  TextIterator stream = new TextIterator(input, 0);
-  stream.moveNext();
-  Statement result = statementSerializer.readFrom(stream, state);
-  if (stream.moveNext()) {
-    throw StateError("extra cruft in basic literal");
-  }
-  return result;
-}
-
-String writeStatement(Statement statement, SerializationState state) {
-  StringBuffer buffer = new StringBuffer();
-  statementSerializer.writeTo(buffer, statement, state);
-  return buffer.toString();
-}
-
-class TestCase {
+class TestCase<T extends Node> {
   final String name;
-  final Node node;
+  final T node;
   final SerializationState serializationState;
   final DeserializationState deserializationState;
   final String expectation;
+  final TextSerializer<T> serializer;
 
   TestCase(
       {this.name,
       this.node,
       this.expectation,
+      this.serializer,
       SerializationState serializationState,
       DeserializationState deserializationState})
-      : this.serializationState =
+      : assert(node != null),
+        assert(expectation != null),
+        assert(serializer != null),
+        this.serializationState =
             serializationState ?? new SerializationState(null),
         this.deserializationState = deserializationState ??
             new DeserializationState(null, new CanonicalName.root());
+
+  T readNode(String input, DeserializationState state) {
+    TextIterator stream = new TextIterator(input, 0);
+    stream.moveNext();
+    T result = serializer.readFrom(stream, state);
+    if (stream.moveNext()) {
+      throw new StateError("Found extra tokens at the end.");
+    }
+    return result;
+  }
+
+  String writeNode(T node, SerializationState state) {
+    StringBuffer buffer = new StringBuffer();
+    serializer.writeTo(buffer, node, state);
+    return buffer.toString();
+  }
 }
 
 void test() {
   List<String> failures = [];
   List<TestCase> tests = <TestCase>[
-    new TestCase(
-        name: "let dynamic x = 42 in x;",
+    new TestCase<Statement>(
+        name: 'let dynamic x = 42 in x;',
         node: () {
-          VariableDeclaration x = new VariableDeclaration("x",
+          VariableDeclaration x = new VariableDeclaration('x',
               type: const DynamicType(), initializer: new IntLiteral(42));
           return new ExpressionStatement(new Let(x, new VariableGet(x)));
         }(),
         expectation: ''
             '(expr (let (var "x^0" (dynamic) (int 42) ())'
-            ' (get-var "x^0" _)))'),
-    new TestCase(
-        name: "let dynamic x = 42 in let Bottom x^0 = null in x;",
+            ' (get-var "x^0" _)))',
+        serializer: statementSerializer),
+    new TestCase<Statement>(
+        name: 'let dynamic x = 42 in let Bottom x^0 = null in x;',
         node: () {
-          VariableDeclaration outterLetVar = new VariableDeclaration("x",
+          VariableDeclaration outterLetVar = new VariableDeclaration('x',
               type: const DynamicType(), initializer: new IntLiteral(42));
-          VariableDeclaration innerLetVar = new VariableDeclaration("x",
+          VariableDeclaration innerLetVar = new VariableDeclaration('x',
               type: const BottomType(), initializer: new NullLiteral());
           return new ExpressionStatement(new Let(outterLetVar,
               new Let(innerLetVar, new VariableGet(outterLetVar))));
@@ -75,13 +80,14 @@
         expectation: ''
             '(expr (let (var "x^0" (dynamic) (int 42) ())'
             ' (let (var "x^1" (bottom) (null) ())'
-            ' (get-var "x^0" _))))'),
-    new TestCase(
-        name: "let dynamic x = 42 in let Bottom x^0 = null in x^0;",
+            ' (get-var "x^0" _))))',
+        serializer: statementSerializer),
+    new TestCase<Statement>(
+        name: 'let dynamic x = 42 in let Bottom x^0 = null in x^0;',
         node: () {
-          VariableDeclaration outterLetVar = new VariableDeclaration("x",
+          VariableDeclaration outterLetVar = new VariableDeclaration('x',
               type: const DynamicType(), initializer: new IntLiteral(42));
-          VariableDeclaration innerLetVar = new VariableDeclaration("x",
+          VariableDeclaration innerLetVar = new VariableDeclaration('x',
               type: const BottomType(), initializer: new NullLiteral());
           return new ExpressionStatement(new Let(outterLetVar,
               new Let(innerLetVar, new VariableGet(innerLetVar))));
@@ -89,72 +95,76 @@
         expectation: ''
             '(expr (let (var "x^0" (dynamic) (int 42) ())'
             ' (let (var "x^1" (bottom) (null) ())'
-            ' (get-var "x^1" _))))'),
+            ' (get-var "x^1" _))))',
+        serializer: statementSerializer),
     () {
       VariableDeclaration x =
-          new VariableDeclaration("x", type: const DynamicType());
-      return new TestCase(
-          name: "/* suppose: dynamic x; */ x = 42;",
+          new VariableDeclaration('x', type: const DynamicType());
+      return new TestCase<Statement>(
+          name: '/* suppose: dynamic x; */ x = 42;',
           node: new ExpressionStatement(new VariableSet(x, new IntLiteral(42))),
           expectation: '(expr (set-var "x^0" (int 42)))',
           serializationState: new SerializationState(
             new SerializationEnvironment(null)
-              ..addBinder(x, "x^0")
+              ..addBinder(x, 'x^0')
               ..close(),
           ),
           deserializationState: new DeserializationState(
               new DeserializationEnvironment(null)
-                ..addBinder("x^0", x)
+                ..addBinder('x^0', x)
                 ..close(),
-              new CanonicalName.root()));
+              new CanonicalName.root()),
+          serializer: statementSerializer);
     }(),
     () {
-      Field field = new Field(new Name("field"), type: const DynamicType());
+      Field field = new Field(new Name('field'), type: const DynamicType());
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           fields: <Field>[field]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
-      return new TestCase(
-          name: "/* suppose top-level: dynamic field; */ field;",
+      return new TestCase<Statement>(
+          name: '/* suppose top-level: dynamic field; */ field;',
           node: new ExpressionStatement(new StaticGet(field)),
           expectation: ''
               '(expr (get-static "package:foo/bar.dart::@fields::field"))',
           serializationState: new SerializationState(null),
-          deserializationState: new DeserializationState(null, component.root));
+          deserializationState: new DeserializationState(null, component.root),
+          serializer: statementSerializer);
     }(),
     () {
-      Field field = new Field(new Name("field"), type: const DynamicType());
+      Field field = new Field(new Name('field'), type: const DynamicType());
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           fields: <Field>[field]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
-      return new TestCase(
-          name: "/* suppose top-level: dynamic field; */ field = 1;",
+      return new TestCase<Statement>(
+          name: '/* suppose top-level: dynamic field; */ field = 1;',
           node:
               new ExpressionStatement(new StaticSet(field, new IntLiteral(1))),
           expectation: ''
               '(expr'
               ' (set-static "package:foo/bar.dart::@fields::field" (int 1)))',
           serializationState: new SerializationState(null),
-          deserializationState: new DeserializationState(null, component.root));
+          deserializationState: new DeserializationState(null, component.root),
+          serializer: statementSerializer);
     }(),
     () {
       Procedure topLevelProcedure = new Procedure(
-          new Name("foo"),
+          new Name('foo'),
           ProcedureKind.Method,
           new FunctionNode(null, positionalParameters: <VariableDeclaration>[
-            new VariableDeclaration("x", type: const DynamicType())
+            new VariableDeclaration('x', type: const DynamicType())
           ]),
           isStatic: true);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           procedures: <Procedure>[topLevelProcedure]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
-      return new TestCase(
-          name: "/* suppose top-level: foo(dynamic x) {...}; */ foo(42);",
+      return new TestCase<Statement>(
+          name: '/* suppose top-level: foo(dynamic x) {...}; */ foo(42);',
           node: new ExpressionStatement(new StaticInvocation.byReference(
               topLevelProcedure.reference,
               new Arguments(<Expression>[new IntLiteral(42)]),
@@ -163,23 +173,24 @@
               '(expr (invoke-static "package:foo/bar.dart::@methods::foo"'
               ' () ((int 42)) ()))',
           serializationState: new SerializationState(null),
-          deserializationState: new DeserializationState(null, component.root));
+          deserializationState: new DeserializationState(null, component.root),
+          serializer: statementSerializer);
     }(),
     () {
       Procedure factoryConstructor = new Procedure(
-          new Name("foo"), ProcedureKind.Factory, new FunctionNode(null),
+          new Name('foo'), ProcedureKind.Factory, new FunctionNode(null),
           isStatic: true, isConst: true);
       Class klass =
-          new Class(name: "A", procedures: <Procedure>[factoryConstructor]);
+          new Class(name: 'A', procedures: <Procedure>[factoryConstructor]);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           classes: <Class>[klass]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
-      return new TestCase(
-          name: ""
-              "/* suppose A { const A(); const factory A.foo() = A; } */"
-              " const A.foo();",
+      return new TestCase<Statement>(
+          name: ''
+              '/* suppose A { const A(); const factory A.foo() = A; } */'
+              ' const A.foo();',
           node: new ExpressionStatement(new StaticInvocation.byReference(
               factoryConstructor.reference, new Arguments([]),
               isConst: true)),
@@ -188,21 +199,22 @@
               ' "package:foo/bar.dart::A::@factories::foo"'
               ' () () ()))',
           serializationState: new SerializationState(null),
-          deserializationState: new DeserializationState(null, component.root));
+          deserializationState: new DeserializationState(null, component.root),
+          serializer: statementSerializer);
     }(),
     () {
-      Field field = new Field(new Name("field"), type: const DynamicType());
-      Class klass = new Class(name: "A", fields: <Field>[field]);
+      Field field = new Field(new Name('field'), type: const DynamicType());
+      Class klass = new Class(name: 'A', fields: <Field>[field]);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           classes: <Class>[klass]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
 
       VariableDeclaration x =
-          new VariableDeclaration("x", type: const DynamicType());
-      return new TestCase(
-          name: "/* suppose A {dynamic field;} A x; */ x.{A::field};",
+          new VariableDeclaration('x', type: const DynamicType());
+      return new TestCase<Statement>(
+          name: '/* suppose A {dynamic field;} A x; */ x.{A::field};',
           node: new ExpressionStatement(new DirectPropertyGet.byReference(
               new VariableGet(x), field.reference)),
           expectation: ''
@@ -210,27 +222,28 @@
               ' "package:foo/bar.dart::A::@fields::field"))',
           serializationState:
               new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, "x^0")
+                ..addBinder(x, 'x^0')
                 ..close()),
           deserializationState: new DeserializationState(
               new DeserializationEnvironment(null)
-                ..addBinder("x^0", x)
+                ..addBinder('x^0', x)
                 ..close(),
-              component.root));
+              component.root),
+          serializer: statementSerializer);
     }(),
     () {
-      Field field = new Field(new Name("field"), type: const DynamicType());
-      Class klass = new Class(name: "A", fields: <Field>[field]);
+      Field field = new Field(new Name('field'), type: const DynamicType());
+      Class klass = new Class(name: 'A', fields: <Field>[field]);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           classes: <Class>[klass]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
 
       VariableDeclaration x =
-          new VariableDeclaration("x", type: const DynamicType());
-      return new TestCase(
-          name: "/* suppose A {dynamic field;} A x; */ x.{A::field} = 42;",
+          new VariableDeclaration('x', type: const DynamicType());
+      return new TestCase<Statement>(
+          name: '/* suppose A {dynamic field;} A x; */ x.{A::field} = 42;',
           node: new ExpressionStatement(new DirectPropertySet.byReference(
               new VariableGet(x), field.reference, new IntLiteral(42))),
           expectation: ''
@@ -238,29 +251,30 @@
               ' "package:foo/bar.dart::A::@fields::field" (int 42)))',
           serializationState:
               new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, "x^0")
+                ..addBinder(x, 'x^0')
                 ..close()),
           deserializationState: new DeserializationState(
               new DeserializationEnvironment(null)
-                ..addBinder("x^0", x)
+                ..addBinder('x^0', x)
                 ..close(),
-              component.root));
+              component.root),
+          serializer: statementSerializer);
     }(),
     () {
       Procedure method = new Procedure(
-          new Name("foo"), ProcedureKind.Method, new FunctionNode(null),
+          new Name('foo'), ProcedureKind.Method, new FunctionNode(null),
           isStatic: true, isConst: true);
-      Class klass = new Class(name: "A", procedures: <Procedure>[method]);
+      Class klass = new Class(name: 'A', procedures: <Procedure>[method]);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           classes: <Class>[klass]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
 
       VariableDeclaration x =
-          new VariableDeclaration("x", type: const DynamicType());
-      return new TestCase(
-          name: "/* suppose A {foo() {...}} A x; */ x.{A::foo}();",
+          new VariableDeclaration('x', type: const DynamicType());
+      return new TestCase<Statement>(
+          name: '/* suppose A {foo() {...}} A x; */ x.{A::foo}();',
           node: new ExpressionStatement(new DirectMethodInvocation.byReference(
               new VariableGet(x), method.reference, new Arguments([]))),
           expectation: ''
@@ -269,26 +283,27 @@
               ' () () ()))',
           serializationState:
               new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, "x^0")
+                ..addBinder(x, 'x^0')
                 ..close()),
           deserializationState: new DeserializationState(
               new DeserializationEnvironment(null)
-                ..addBinder("x^0", x)
+                ..addBinder('x^0', x)
                 ..close(),
-              component.root));
+              component.root),
+          serializer: statementSerializer);
     }(),
     () {
       Constructor constructor =
-          new Constructor(new FunctionNode(null), name: new Name("foo"));
+          new Constructor(new FunctionNode(null), name: new Name('foo'));
       Class klass =
-          new Class(name: "A", constructors: <Constructor>[constructor]);
+          new Class(name: 'A', constructors: <Constructor>[constructor]);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           classes: <Class>[klass]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
-      return new TestCase(
-          name: "/* suppose A {A.foo();} */ new A();",
+      return new TestCase<Statement>(
+          name: '/* suppose A {A.foo();} */ new A();',
           node: new ExpressionStatement(new ConstructorInvocation.byReference(
               constructor.reference, new Arguments([]))),
           expectation: ''
@@ -296,20 +311,21 @@
               ' "package:foo/bar.dart::A::@constructors::foo"'
               ' () () ()))',
           serializationState: new SerializationState(null),
-          deserializationState: new DeserializationState(null, component.root));
+          deserializationState: new DeserializationState(null, component.root),
+          serializer: statementSerializer);
     }(),
     () {
       Constructor constructor = new Constructor(new FunctionNode(null),
-          name: new Name("foo"), isConst: true);
+          name: new Name('foo'), isConst: true);
       Class klass =
-          new Class(name: "A", constructors: <Constructor>[constructor]);
+          new Class(name: 'A', constructors: <Constructor>[constructor]);
       Library library = new Library(
-          new Uri(scheme: "package", path: "foo/bar.dart"),
+          new Uri(scheme: 'package', path: 'foo/bar.dart'),
           classes: <Class>[klass]);
       Component component = new Component(libraries: <Library>[library]);
       component.computeCanonicalNames();
-      return new TestCase(
-          name: "/* suppose A {const A.foo();} */ const A();",
+      return new TestCase<Statement>(
+          name: '/* suppose A {const A.foo();} */ const A();',
           node: new ExpressionStatement(new ConstructorInvocation.byReference(
               constructor.reference, new Arguments([]),
               isConst: true)),
@@ -318,15 +334,16 @@
               ' "package:foo/bar.dart::A::@constructors::foo"'
               ' () () ()))',
           serializationState: new SerializationState(null),
-          deserializationState: new DeserializationState(null, component.root));
+          deserializationState: new DeserializationState(null, component.root),
+          serializer: statementSerializer);
     }(),
     () {
       TypeParameter outterParam =
-          new TypeParameter("T", const DynamicType(), const DynamicType());
+          new TypeParameter('T', const DynamicType(), const DynamicType());
       TypeParameter innerParam =
-          new TypeParameter("T", const DynamicType(), const DynamicType());
-      return new TestCase(
-          name: "/* T Function<T>(T Function<T>()); */",
+          new TypeParameter('T', const DynamicType(), const DynamicType());
+      return new TestCase<Statement>(
+          name: '/* T Function<T>(T Function<T>()); */',
           node: new ExpressionStatement(new TypeLiteral(new FunctionType(
               [
                 new FunctionType(
@@ -345,17 +362,18 @@
           serializationState:
               new SerializationState(new SerializationEnvironment(null)),
           deserializationState: new DeserializationState(
-              new DeserializationEnvironment(null), null));
+              new DeserializationEnvironment(null), null),
+          serializer: statementSerializer);
     }(),
     () {
       TypeParameter t =
-          new TypeParameter("T", const DynamicType(), const DynamicType());
-      VariableDeclaration t1 = new VariableDeclaration("t1",
+          new TypeParameter('T', const DynamicType(), const DynamicType());
+      VariableDeclaration t1 = new VariableDeclaration('t1',
           type: new TypeParameterType(t, Nullability.legacy));
-      VariableDeclaration t2 = new VariableDeclaration("t2",
+      VariableDeclaration t2 = new VariableDeclaration('t2',
           type: new TypeParameterType(t, Nullability.legacy));
-      return new TestCase(
-          name: "/* <T>(T t1, [T t2]) => t1; */",
+      return new TestCase<Statement>(
+          name: '/* <T>(T t1, [T t2]) => t1; */',
           node: new ExpressionStatement(new FunctionExpression(new FunctionNode(
               new ReturnStatement(new VariableGet(t1)),
               typeParameters: [t],
@@ -371,25 +389,118 @@
           serializationState:
               new SerializationState(new SerializationEnvironment(null)),
           deserializationState: new DeserializationState(
-              new DeserializationEnvironment(null), null));
+              new DeserializationEnvironment(null), null),
+          serializer: statementSerializer);
+    }(),
+    () {
+      VariableDeclaration x = VariableDeclaration('x', type: DynamicType());
+      Procedure foo = Procedure(
+          Name('foo'),
+          ProcedureKind.Method,
+          FunctionNode(ReturnStatement(VariableGet(x)),
+              positionalParameters: [x]),
+          isStatic: true);
+      Library library = Library(Uri(scheme: 'package', path: 'foo/bar.dart'),
+          procedures: [foo]);
+      Component component = Component(libraries: [library]);
+      component.computeCanonicalNames();
+      return new TestCase<Procedure>(
+          name: 'foo(x) => x;',
+          node: foo,
+          expectation: ''
+              '(static-method (public "foo")'
+              ' (sync () () () ((var "x^0" (dynamic) _ ())) () ()'
+              ' (dynamic) (ret (get-var "x^0" _))))',
+          serializationState:
+              new SerializationState(new SerializationEnvironment(null)),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null), null),
+          serializer: procedureSerializer);
+    }(),
+    () {
+      VariableDeclaration x1 = VariableDeclaration('x', type: DynamicType());
+      VariableDeclaration x2 = VariableDeclaration('x', type: DynamicType());
+      Procedure foo = Procedure(
+          Name('foo'),
+          ProcedureKind.Method,
+          FunctionNode(ReturnStatement(VariableGet(x1)),
+              positionalParameters: [x1]),
+          isStatic: true);
+      Procedure bar = Procedure(
+          Name('bar'),
+          ProcedureKind.Method,
+          FunctionNode(
+              ReturnStatement(
+                  StaticInvocation(foo, Arguments([VariableGet(x2)]))),
+              positionalParameters: [x2]),
+          isStatic: true);
+      Library library = Library(Uri(scheme: 'package', path: 'foo/bar.dart'),
+          procedures: [foo, bar]);
+      Component component = Component(libraries: [library]);
+      component.computeCanonicalNames();
+      return new TestCase<Library>(
+          name: 'foo(x) => x; bar(x) => foo(x);',
+          node: library,
+          expectation: ''
+              '(legacy "package:foo/bar.dart"'
+              ''
+              ' ((static-method (public "foo")'
+              ' (sync () () () ((var "x^0" (dynamic) _ ())) () () (dynamic)'
+              ' (ret (get-var "x^0" _))))'
+              ''
+              ' (static-method (public "bar")'
+              ' (sync () () () ((var "x^0" (dynamic) _ ())) () () (dynamic)'
+              ' (ret (invoke-static "package:foo/bar.dart::@methods::foo"'
+              ' () ((get-var "x^0" _)) ()))))))',
+          serializationState:
+              new SerializationState(new SerializationEnvironment(null)),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null), new CanonicalName.root()),
+          serializer: librarySerializer);
+    }(),
+    () {
+      Class a = Class(name: "A");
+      Procedure foo = Procedure(
+          Name("foo"),
+          ProcedureKind.Method,
+          FunctionNode(ReturnStatement(NullLiteral()),
+              returnType: InterfaceType(a, Nullability.legacy)),
+          isStatic: true);
+      Library library = Library(Uri(scheme: "package", path: "foo/bar.dart"),
+          classes: [a], procedures: [foo]);
+      Component component = Component(libraries: [library]);
+      component.computeCanonicalNames();
+      return new TestCase<Library>(
+          name: 'class A{} A foo() => null;',
+          node: library,
+          expectation: ''
+              '(legacy "package:foo/bar.dart"'
+              ' ((static-method (public "foo")'
+              ' (sync () () () () () () (interface "package:foo/bar.dart::A" ())'
+              ' (ret (null))))))',
+          serializationState:
+              new SerializationState(new SerializationEnvironment(null)),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null), component.root),
+          serializer: librarySerializer);
     }(),
   ];
   for (TestCase testCase in tests) {
     String roundTripInput =
-        writeStatement(testCase.node, testCase.serializationState);
+        testCase.writeNode(testCase.node, testCase.serializationState);
     if (roundTripInput != testCase.expectation) {
       failures.add(''
-          '* initial serialization for test "${testCase.name}"'
-          ' gave output "${roundTripInput}"');
+          "* initial serialization for test '${testCase.name}'"
+          " gave output '${roundTripInput}'");
     }
 
     TreeNode deserialized =
-        readStatement(roundTripInput, testCase.deserializationState);
+        testCase.readNode(roundTripInput, testCase.deserializationState);
     String roundTripOutput =
-        writeStatement(deserialized, testCase.serializationState);
+        testCase.writeNode(deserialized, testCase.serializationState);
     if (roundTripOutput != roundTripInput) {
       failures.add(''
-          '* input "${testCase.name}" gave output "${roundTripOutput}"');
+          "* input '${testCase.name}' gave output '${roundTripOutput}'");
     }
   }
   if (failures.isNotEmpty) {
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 3219f11..905375c 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -733,7 +733,7 @@
   VariableDeclaration makeVariable() => new VariableDeclaration(null);
 
   TypeParameter makeTypeParameter([String name]) {
-    return new TypeParameter(name, objectLegacyRawType);
+    return new TypeParameter(name, objectLegacyRawType, const DynamicType());
   }
 
   TestHarness() {
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
index 3e5ecaf..4ca8152 100644
--- a/pkg/meta/pubspec.yaml
+++ b/pkg/meta/pubspec.yaml
@@ -7,4 +7,4 @@
  semantic information about the program being annotated. These annotations are
  intended to be used by tools to provide a better user experience.
 environment:
-  sdk: '>=1.12.0 <3.0.0'
+  sdk: '>=2.9.0 <3.0.0'
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
index 06b1702..0d1a91d 100644
--- a/pkg/native_stack_traces/CHANGELOG.md
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Changelog
 
+## 0.3.4
+
+- Decoded Dart calls are now never considered internal, only VM stub calls.
+  This is due to a concurrent change in the Dart VM that no longer prints
+  non-symbolic frames for functions considered invisible, which matches the
+  symbolic frame printer and removes the need for the decoder to guess which
+  frames should be hidden.
+
+  This package still works on earlier versions of Dart, so the dependencies have
+  not changed. However, it may print more frame information than expected when
+  decoding stack frames from a Dart VM that does not include this change to
+  non-symbolic stack printing.
+
+## 0.3.3
+
+- No externally visible changes.
+
+## 0.3.2
+
+- The `find` command can now look up addresses given as offsets from static
+  symbols, not just hexadecimal virtual or absolute addresses.
+- Integer inputs (addresses or offsets) without an '0x' prefix or hexadecimal
+  digits will now be parsed as decimal unless the `-x`/`--force_hexadecimal`
+  flag is used.
+
 ## 0.3.1
 
 - Uses dynamic symbol information embedded in stack frame lines when available.
@@ -15,7 +40,7 @@
 
 ## 0.2.1
 
-- Added static method Dwarf.fromBuffer.
+- Added static method `Dwarf.fromBuffer`.
 
 ## 0.2.0
 
diff --git a/pkg/native_stack_traces/bin/decode.dart b/pkg/native_stack_traces/bin/decode.dart
index 4b864c0..22a5e7e 100644
--- a/pkg/native_stack_traces/bin/decode.dart
+++ b/pkg/native_stack_traces/bin/decode.dart
@@ -34,6 +34,10 @@
     _createBaseDebugParser(ArgParser(allowTrailingOptions: true))
       ..addMultiOption('location',
           abbr: 'l', help: 'PC address to find', valueHelp: 'PC')
+      ..addFlag('force_hexadecimal',
+          abbr: 'x',
+          negatable: false,
+          help: 'Always parse integers as hexadecimal')
       ..addOption('vm_start',
           help: 'Absolute address for start of VM instructions',
           valueHelp: 'PC')
@@ -88,19 +92,30 @@
 Usage: convert_stack_traces find [options] <PC> ...
 
 The find command looks up program counter (PC) addresses, either given as
-arguments on the command line or via the -l option. For each PC address,
-it outputs the file, function, and line number information if found.
+arguments on the command line or via the -l/--location option. For each
+successful PC lookup, it outputs the call information in one of two formats:
 
-PC addresses are expected to be hexadecimal numbers with or without an initial
-"0x" marker.
+- If the location corresponds to a call site in Dart source code, the call
+  information includes the file, function, and line number information.
+- If it corresponds to a Dart VM stub, the call information includes the dynamic
+  symbol name for the instructions payload and an offset into that payload.
 
 The -l option may be provided multiple times, or a single use of the -l option
 may be given multiple arguments separated by commas.
 
-By default, PC addresses are assumed to be virtual addresses valid for the
-given debugging information. To find absolute PC addresses, use both the
---vm_start and --isolate_start arguments tp provide the absolute addresses of
-the VM and isolate instructions sections.
+PC addresses can be provided in one of two formats:
+
+- An integer, e.g. 0x2a3f or 15049
+- A static symbol in the VM snapshot plus an integer offset, e.g.,
+  _kDartIsolateSnapshotInstructions+1523 or _kDartVMSnapshotInstructions+0x403f
+
+Integers without an "0x" prefix that do not includes hexadecimal digits are
+assumed to be decimal unless the -x/--force_hexadecimal flag is used.
+
+By default, integer PC addresses are assumed to be virtual addresses valid for
+the given debugging information. Otherwise, use both the --vm_start and
+--isolate_start arguments to provide the appropriate starting addresses of the
+VM and isolate instructions sections.
 
 Options shared by all commands:
 ${_argParser.usage}
@@ -159,67 +174,74 @@
 }
 
 void find(ArgResults options) {
+  final bool verbose = options['verbose'];
+  final bool forceHexadecimal = options['force_hexadecimal'];
+
   void usageError(String message) => errorWithUsage(message, command: 'find');
-  int convertAddress(String s) => int.tryParse(s, radix: 16);
+  int parseIntAddress(String s) {
+    if (!forceHexadecimal && !s.startsWith("0x")) {
+      final decimal = int.tryParse(s);
+      if (decimal != null) return decimal;
+    }
+    return int.tryParse(s.startsWith("0x") ? s.substring(2) : s, radix: 16);
+  }
+
+  PCOffset convertAddress(StackTraceHeader header, String s) {
+    final parsedOffset = tryParseSymbolOffset(s, forceHexadecimal);
+    if (parsedOffset != null) return parsedOffset;
+
+    final address = parseIntAddress(s);
+    if (address != null) return header.offsetOf(address);
+
+    return null;
+  }
 
   final dwarf = _loadFromFile(options['debug'], usageError);
-  if (dwarf == null) {
-    return;
-  }
+  if (dwarf == null) return;
+
   if (options['dump_debug_file_contents']) {
     print(dwarf.dumpFileInfo());
   }
-  final verbose = options['verbose'];
 
-  int vm_start;
+  if ((options['vm_start'] == null) != (options['isolate_start'] == null)) {
+    return usageError("need both VM start and isolate start");
+  }
+
+  int vmStart = dwarf.vmStartAddress;
   if (options['vm_start'] != null) {
-    vm_start = convertAddress(options['vm_start']);
-    if (vm_start == null) {
+    vmStart = parseIntAddress(options['vm_start']);
+    if (vmStart == null) {
       return usageError('could not parse VM start address '
           '${options['vm_start']}');
     }
   }
 
-  int isolate_start;
+  int isolateStart = dwarf.isolateStartAddress;
   if (options['isolate_start'] != null) {
-    isolate_start = convertAddress(options['isolate_start']);
-    if (isolate_start == null) {
+    isolateStart = parseIntAddress(options['isolate_start']);
+    if (isolateStart == null) {
       return usageError('could not parse isolate start address '
           '${options['isolate_start']}');
     }
   }
 
-  if ((vm_start == null) != (isolate_start == null)) {
-    return usageError("need both VM start and isolate start");
-  }
+  final header = StackTraceHeader(isolateStart, vmStart);
 
-  final locations = <int>[];
-  for (final s in options['location'] + options.rest) {
-    final location = convertAddress(s);
-    if (location == null) {
-      return usageError('could not parse PC address ${s}');
-    }
+  final locations = <PCOffset>[];
+  for (final String s in options['location'] + options.rest) {
+    final location = convertAddress(header, s);
+    if (location == null) return usageError('could not parse PC address ${s}');
     locations.add(location);
   }
   if (locations.isEmpty) return usageError('no PC addresses to find');
 
-  // Used to approximate how many hex digits we should have in the final output.
-  final maxDigits = options['location']
-      .fold(0, ((acc, s) => s.startsWith('0x') ? s.length - 2 : s.length));
-
-  Iterable<int> addresses = locations;
-  if (vm_start != null) {
-    final header = StackTraceHeader(isolate_start, vm_start);
-    addresses =
-        locations.map((l) => header.offsetOf(l).virtualAddressIn(dwarf));
-  }
-  for (final addr in addresses) {
+  for (final offset in locations) {
+    final addr = dwarf.virtualAddressOf(offset);
     final frames = dwarf
         .callInfoFor(addr, includeInternalFrames: verbose)
         ?.map((CallInfo c) => "  " + c.toString());
-    final addrString = addr > 0
-        ? "0x" + addr.toRadixString(16).padLeft(maxDigits, '0')
-        : addr.toString();
+    final addrString =
+        addr > 0 ? "0x" + addr.toRadixString(16) : addr.toString();
     print("For virtual address ${addrString}:");
     if (frames == null) {
       print("  Invalid virtual address.");
diff --git a/pkg/native_stack_traces/lib/native_stack_traces.dart b/pkg/native_stack_traces/lib/native_stack_traces.dart
index bbb59f7..13e28ff 100644
--- a/pkg/native_stack_traces/lib/native_stack_traces.dart
+++ b/pkg/native_stack_traces/lib/native_stack_traces.dart
@@ -3,6 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 export 'src/convert.dart'
-    show collectPCOffsets, DwarfStackTraceDecoder, StackTraceHeader;
+    show
+        collectPCOffsets,
+        tryParseSymbolOffset,
+        DwarfStackTraceDecoder,
+        StackTraceHeader;
 export 'src/dwarf.dart'
     show CallInfo, DartCallInfo, StubCallInfo, Dwarf, PCOffset;
diff --git a/pkg/native_stack_traces/lib/src/convert.dart b/pkg/native_stack_traces/lib/src/convert.dart
index df32604..f0a2d48 100644
--- a/pkg/native_stack_traces/lib/src/convert.dart
+++ b/pkg/native_stack_traces/lib/src/convert.dart
@@ -8,7 +8,8 @@
 import 'constants.dart' as constants;
 import "dwarf.dart";
 
-String _stackTracePiece(CallInfo call, int depth) => "#${depth}\t${call}";
+String _stackTracePiece(CallInfo call, int depth) =>
+    "#${depth.toString().padRight(6)} ${call}";
 
 // A pattern matching the last line of the non-symbolic stack trace header.
 //
@@ -55,42 +56,66 @@
 ///   - The virtual address of the program counter, if the snapshot was
 ///     loaded as a dynamic library, otherwise not present.
 ///   - The location of the virtual address, which is one of the following:
-///     - A dynamic symbol name, a plus sign, and a hexadecimal offset.
+///     - A dynamic symbol name, a plus sign, and an integer offset.
 ///     - The path to the snapshot, if it was loaded as a dynamic library,
 ///       otherwise the string "<unknown>".
-const _symbolREString = r'(?:(?<symbol>' +
+const _symbolOffsetREString = r'(?<symbol>' +
     constants.vmSymbolName +
     r'|' +
     constants.isolateSymbolName +
-    r')\+0x(?<offset>[\da-f]+))';
+    r')\+(?<offset>(?:0x)?[\da-f]+)';
+final _symbolOffsetRE = RegExp(_symbolOffsetREString);
 final _traceLineRE = RegExp(
-    r'    #(\d{2}) abs (?<address>[\da-f]+)(?: virt ([\da-f]+))? (?:' +
-        _symbolREString +
-        r'|.*)$');
+    r'    #(\d{2}) abs (?<address>[\da-f]+)(?: virt ([\da-f]+))? (?<rest>.*)$');
+
+/// Parses strings of the format <static symbol>+<integer offset>, where
+/// <static symbol> is one of the static symbols used for Dart instruction
+/// sections.
+///
+/// Unless forceHexadecimal is true, an integer offset without a "0x" prefix or
+/// any hexdecimal digits will be parsed as decimal.
+///
+/// Returns null if the string is not of the expected format.
+PCOffset tryParseSymbolOffset(String s, [bool forceHexadecimal = false]) {
+  final match = _symbolOffsetRE.firstMatch(s);
+  if (match == null) return null;
+  final symbolString = match.namedGroup('symbol');
+  final offsetString = match.namedGroup('offset');
+  int offset;
+  if (!forceHexadecimal && !offsetString.startsWith("0x")) {
+    offset = int.tryParse(offsetString);
+  }
+  if (offset == null) {
+    final digits = offsetString.startsWith("0x")
+        ? offsetString.substring(2)
+        : offsetString;
+    offset = int.tryParse(digits, radix: 16);
+  }
+  if (offset == null) return null;
+  switch (symbolString) {
+    case constants.vmSymbolName:
+      return PCOffset(offset, InstructionsSection.vm);
+    case constants.isolateSymbolName:
+      return PCOffset(offset, InstructionsSection.isolate);
+    default:
+      break;
+  }
+  return null;
+}
 
 PCOffset _retrievePCOffset(StackTraceHeader header, RegExpMatch match) {
   if (match == null) return null;
-  // Try using the symbol information first, since we don't need the header
+  final restString = match.namedGroup('rest');
+  // Try checking for symbol information first, since we don't need the header
   // information to translate it.
-  final symbolString = match.namedGroup('symbol');
-  final offsetString = match.namedGroup('offset');
-  if (symbolString != null && offsetString != null) {
-    final offset = int.tryParse(offsetString, radix: 16);
-    if (offset != null) {
-      switch (symbolString) {
-        case constants.vmSymbolName:
-          return PCOffset(offset, InstructionsSection.vm);
-        case constants.isolateSymbolName:
-          return PCOffset(offset, InstructionsSection.isolate);
-        default:
-          break;
-      }
-    }
+  if (restString.isNotEmpty) {
+    final offset = tryParseSymbolOffset(restString);
+    if (offset != null) return offset;
   }
   // If we're parsing the absolute address, we can only convert it into
   // a PCOffset if we saw the instructions line of the stack trace header.
-  final addressString = match.namedGroup('address');
-  if (addressString != null && header != null) {
+  if (header != null) {
+    final addressString = match.namedGroup('address');
     final address = int.tryParse(addressString, radix: 16);
     return header.offsetOf(address);
   }
diff --git a/pkg/native_stack_traces/lib/src/dwarf.dart b/pkg/native_stack_traces/lib/src/dwarf.dart
index 88c75b1..a6e842e 100644
--- a/pkg/native_stack_traces/lib/src/dwarf.dart
+++ b/pkg/native_stack_traces/lib/src/dwarf.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:collection';
 import 'dart:math';
 import 'dart:typed_data';
 
@@ -119,60 +120,84 @@
   final _AttributeName name;
   final _AttributeForm form;
 
-  _Attribute(this.name, this.form);
+  _Attribute._(this.name, this.form);
+
+  static _Attribute fromReader(Reader reader) {
+    final nameInt = reader.readLEB128EncodedInteger();
+    final formInt = reader.readLEB128EncodedInteger();
+    if (nameInt == 0 && formInt == 0) return null;
+    if (!_attributeNames.containsKey(nameInt)) {
+      throw FormatException("Unexpected DW_AT value 0x${paddedHex(nameInt)}");
+    }
+    if (!_attributeForms.containsKey(formInt)) {
+      throw FormatException("Unexpected DW_FORM value 0x${paddedHex(formInt)}");
+    }
+    return _Attribute._(_attributeNames[nameInt], _attributeForms[formInt]);
+  }
+
+  Object read(Reader reader, CompilationUnitHeader header) {
+    switch (form) {
+      case _AttributeForm.string:
+        return reader.readNullTerminatedString();
+      case _AttributeForm.address:
+        return reader.readBytes(header.addressSize);
+      case _AttributeForm.sectionOffset:
+        return reader.readBytes(4);
+      case _AttributeForm.constant:
+        return reader.readLEB128EncodedInteger();
+      case _AttributeForm.reference4:
+        return reader.readBytes(4);
+    }
+    return null;
+  }
+
+  String valueToString(Object value, [CompilationUnit unit]) {
+    switch (form) {
+      case _AttributeForm.string:
+        return value as String;
+      case _AttributeForm.address:
+        return '0x' + paddedHex(value as int, unit?.header?.addressSize ?? 0);
+      case _AttributeForm.sectionOffset:
+        return paddedHex(value as int, 4);
+      case _AttributeForm.constant:
+        return value.toString();
+      case _AttributeForm.reference4:
+        final unresolvedValue = paddedHex(value as int, 4);
+        final name = unit?.nameOfOrigin(value as int) ?? "(unresolved)";
+        return '0x${unresolvedValue} (origin: ${name})';
+    }
+    return "<unknown>";
+  }
 }
 
 class _Abbreviation {
-  final Reader reader;
+  final int code;
+  final _Tag tag;
+  final bool children;
+  final List<_Attribute> attributes;
 
-  _Tag tag;
-  bool children;
-  List<_Attribute> attributes;
-
-  _Abbreviation.fromReader(this.reader) {
-    _read();
-  }
+  _Abbreviation._(this.code, this.tag, this.children, this.attributes);
 
   // Constants from the DWARF specification.
   static const _DW_CHILDREN_no = 0x00;
   static const _DW_CHILDREN_yes = 0x01;
 
-  bool _readChildren() {
-    switch (reader.readByte()) {
-      case _DW_CHILDREN_no:
-        return false;
-      case _DW_CHILDREN_yes:
-        return true;
-      default:
-        throw FormatException("Expected DW_CHILDREN_no or DW_CHILDREN_yes");
-    }
-  }
-
-  void _read() {
-    reader.reset();
+  static _Abbreviation fromReader(Reader reader) {
+    final code = reader.readLEB128EncodedInteger();
+    if (code == 0) return null;
     final tagInt = reader.readLEB128EncodedInteger();
     if (!_tags.containsKey(tagInt)) {
       throw FormatException("Unexpected DW_TAG value 0x${paddedHex(tagInt)}");
     }
-    tag = _tags[tagInt];
-    children = _readChildren();
-    attributes = <_Attribute>[];
-    while (!reader.done) {
-      final nameInt = reader.readLEB128EncodedInteger();
-      final formInt = reader.readLEB128EncodedInteger();
-      if (nameInt == 0 && formInt == 0) {
-        break;
-      }
-      if (!_attributeNames.containsKey(nameInt)) {
-        throw FormatException("Unexpected DW_AT value 0x${paddedHex(nameInt)}");
-      }
-      if (!_attributeForms.containsKey(formInt)) {
-        throw FormatException(
-            "Unexpected DW_FORM value 0x${paddedHex(formInt)}");
-      }
-      attributes
-          .add(_Attribute(_attributeNames[nameInt], _attributeForms[formInt]));
+    final tag = _tags[tagInt];
+    final childrenByte = reader.readByte();
+    if (childrenByte != _DW_CHILDREN_no && childrenByte != _DW_CHILDREN_yes) {
+      throw FormatException("Expected DW_CHILDREN_no or DW_CHILDREN_yes: "
+          "${childrenByte}");
     }
+    final children = childrenByte == _DW_CHILDREN_yes;
+    final attributes = reader.readRepeated(_Attribute.fromReader).toList();
+    return _Abbreviation._(code, tag, children, attributes);
   }
 
   void writeToStringBuffer(StringBuffer buffer) {
@@ -200,30 +225,18 @@
 }
 
 class _AbbreviationsTable {
-  final Reader reader;
+  final Map<int, _Abbreviation> _abbreviations;
 
-  Map<int, _Abbreviation> _abbreviations;
-
-  _AbbreviationsTable.fromReader(this.reader) {
-    _read();
-  }
+  _AbbreviationsTable._(this._abbreviations);
 
   bool containsKey(int code) => _abbreviations.containsKey(code);
   _Abbreviation operator [](int code) => _abbreviations[code];
 
-  void _read() {
-    reader.reset();
-    _abbreviations = <int, _Abbreviation>{};
-    while (!reader.done) {
-      final code = reader.readLEB128EncodedInteger();
-      // Code of 0 marks end of abbreviations table.
-      if (code == 0) {
-        break;
-      }
-      final abbrev = _Abbreviation.fromReader(reader.shrink(reader.offset));
-      _abbreviations[code] = abbrev;
-      reader.seek(abbrev.reader.offset);
-    }
+  static _AbbreviationsTable fromReader(Reader reader) {
+    final abbreviations = Map.fromEntries(reader
+        .readRepeated(_Abbreviation.fromReader)
+        .map((abbr) => MapEntry(abbr.code, abbr)));
+    return _AbbreviationsTable._(abbreviations);
   }
 
   void writeToStringBuffer(StringBuffer buffer) {
@@ -248,110 +261,44 @@
 
 /// A DWARF Debug Information Entry (DIE).
 class DebugInformationEntry {
-  final Reader reader;
-  final CompilationUnit compilationUnit;
+  // The index of the entry in the abbreviation table for this DIE.
+  final int code;
+  final Map<_Attribute, Object> attributes;
+  final Map<int, DebugInformationEntry> children;
 
-  // The index of the entry in the abbreviation table for this DIE. If 0, then
-  // this is not actually a full DIE, but an end marker for a list of entries.
-  int code;
-  Map<_Attribute, Object> attributes;
-  List<DebugInformationEntry> children;
+  DebugInformationEntry._(this.code, this.attributes, this.children);
 
-  DebugInformationEntry.fromReader(this.reader, this.compilationUnit) {
-    _read();
-  }
-
-  Object _readAttribute(_Attribute attribute) {
-    switch (attribute.form) {
-      case _AttributeForm.string:
-        return reader.readNullTerminatedString();
-      case _AttributeForm.address:
-        return reader.readBytes(compilationUnit.addressSize);
-      case _AttributeForm.sectionOffset:
-        return reader.readBytes(4);
-      case _AttributeForm.constant:
-        return reader.readLEB128EncodedInteger();
-      case _AttributeForm.reference4:
-        return reader.readBytes(4);
-    }
-    return null;
-  }
-
-  String _nameOfOrigin(int offset) {
-    if (!compilationUnit.referenceTable.containsKey(offset)) {
-      throw ArgumentError(
-          "${paddedHex(offset)} is not the offset of an abbreviated unit");
-    }
-    final origin = compilationUnit.referenceTable[offset];
-    assert(origin.containsKey(_AttributeName.name));
-    return origin[_AttributeName.name] as String;
-  }
-
-  String _attributeValueToString(_Attribute attribute, Object value) {
-    switch (attribute.form) {
-      case _AttributeForm.string:
-        return value as String;
-      case _AttributeForm.address:
-        return paddedHex(value as int, compilationUnit.addressSize);
-      case _AttributeForm.sectionOffset:
-        return paddedHex(value as int, 4);
-      case _AttributeForm.constant:
-        return value.toString();
-      case _AttributeForm.reference4:
-        return paddedHex(value as int, 4) +
-            " (origin: ${_nameOfOrigin(value as int)})";
-    }
-    return "<unknown>";
-  }
-
-  int get _unitOffset => reader.start - compilationUnit.reader.start;
-
-  void _read() {
-    reader.reset();
-    code = reader.readLEB128EncodedInteger();
+  static DebugInformationEntry fromReader(
+      Reader reader, CompilationUnitHeader header) {
+    final code = reader.readLEB128EncodedInteger();
     // DIEs with an abbreviation table index of 0 are list end markers.
-    if (code == 0) {
-      return;
-    }
-    if (!compilationUnit.abbreviations.containsKey(code)) {
+    if (code == 0) return null;
+    if (!header.abbreviations.containsKey(code)) {
       throw FormatException("Unknown abbreviation code 0x${paddedHex(code)}");
     }
-    final abbreviation = compilationUnit.abbreviations[code];
-    attributes = <_Attribute, Object>{};
+    final abbreviation = header.abbreviations[code];
+    final attributes = <_Attribute, Object>{};
     for (final attribute in abbreviation.attributes) {
-      attributes[attribute] = _readAttribute(attribute);
+      attributes[attribute] = attribute.read(reader, header);
     }
-    compilationUnit.referenceTable[_unitOffset] = this;
-    if (!abbreviation.children) return;
-    children = <DebugInformationEntry>[];
-    while (!reader.done) {
-      final child = DebugInformationEntry.fromReader(
-          reader.shrink(reader.offset), compilationUnit);
-      reader.seek(child.reader.offset);
-      if (child.code == 0) {
-        break;
-      }
-      children.add(child);
+    Map<int, DebugInformationEntry> children;
+    if (abbreviation.children) {
+      children = Map.fromEntries(reader.readRepeatedWithOffsets(
+          (r) => DebugInformationEntry.fromReader(r, header),
+          absolute: true));
     }
+    assert((children != null) == abbreviation.children);
+    return DebugInformationEntry._(code, attributes, children);
   }
 
-  _Attribute _attributeForName(_AttributeName name) => attributes.keys
+  _Attribute _namedAttribute(_AttributeName name) => attributes.keys
       .firstWhere((_Attribute k) => k.name == name, orElse: () => null);
 
-  bool containsKey(_AttributeName name) => _attributeForName(name) != null;
+  bool containsKey(_AttributeName name) => _namedAttribute(name) != null;
 
-  Object operator [](_AttributeName name) {
-    final key = _attributeForName(name);
-    if (key == null) {
-      return null;
-    }
-    return attributes[key];
-  }
+  Object operator [](_AttributeName name) => attributes[_namedAttribute(name)];
 
-  DebugInformationEntry get abstractOrigin {
-    final index = this[_AttributeName.abstractOrigin] as int;
-    return compilationUnit.referenceTable[index];
-  }
+  int get abstractOrigin => this[_AttributeName.abstractOrigin] as int;
 
   int get lowPC => this[_AttributeName.lowProgramCounter] as int;
 
@@ -366,49 +313,49 @@
 
   int get callLine => this[_AttributeName.callLine] as int;
 
-  _Tag get tag => compilationUnit.abbreviations[code].tag;
+  List<CallInfo> callInfo(
+      CompilationUnit unit, LineNumberProgram lineNumberProgram, int address) {
+    String callFilename(int index) =>
+        lineNumberProgram.header.filesInfo[index].name;
+    if (!containsPC(address)) return null;
 
-  List<CallInfo> callInfo(int address, LineNumberProgram lineNumberProgram) {
-    String callFilename(int index) => lineNumberProgram.filesInfo[index].name;
-    if (!containsPC(address)) {
-      return null;
-    }
+    final tag = unit.header.abbreviations[code].tag;
     final inlined = tag == _Tag.inlinedSubroutine;
-    for (final unit in children) {
-      final callInfo = unit.callInfo(address, lineNumberProgram);
-      if (callInfo == null) {
-        continue;
+    if (children != null) {
+      for (final child in children.values) {
+        final callInfo = child.callInfo(unit, lineNumberProgram, address);
+        if (callInfo == null) continue;
+
+        if (tag == _Tag.compileUnit) return callInfo;
+
+        return callInfo
+          ..add(DartCallInfo(
+              function: unit.nameOfOrigin(abstractOrigin),
+              inlined: inlined,
+              filename: callFilename(child.callFileIndex),
+              line: child.callLine));
       }
-      if (tag != _Tag.compileUnit) {
-        callInfo.add(DartCallInfo(
-            function: abstractOrigin.name,
-            inlined: inlined,
-            filename: callFilename(unit.callFileIndex),
-            line: unit.callLine));
-      }
-      return callInfo;
     }
-    if (tag == _Tag.compileUnit) {
-      return null;
-    }
+
+    if (tag == _Tag.compileUnit) return null;
+
     final filename = lineNumberProgram.filename(address);
     final line = lineNumberProgram.lineNumber(address);
     return [
       DartCallInfo(
-          function: abstractOrigin.name,
+          function: unit.nameOfOrigin(abstractOrigin),
           inlined: inlined,
           filename: filename,
           line: line)
     ];
   }
 
-  void writeToStringBuffer(StringBuffer buffer, {String indent = ''}) {
+  void writeToStringBuffer(StringBuffer buffer,
+      {CompilationUnit unit, String indent = ''}) {
     buffer
       ..write(indent)
-      ..write('Abbreviated unit (code ')
+      ..write('Abbreviation code: ')
       ..write(code)
-      ..write(', offset ')
-      ..write(paddedHex(_unitOffset))
       ..writeln('):');
     for (final attribute in attributes.keys) {
       buffer
@@ -416,30 +363,28 @@
         ..write('  ')
         ..write(_attributeNameStrings[attribute.name])
         ..write(' => ')
-        ..writeln(_attributeValueToString(attribute, attributes[attribute]));
+        ..writeln(attribute.valueToString(attributes[attribute], unit));
     }
-    if (children == null || children.isEmpty) {
+    if (children != null) {
       buffer
         ..write(indent)
-        ..writeln('Has no children.');
-      return;
-    }
-    buffer
-      ..write(indent)
-      ..write('Has ')
-      ..write(children.length)
-      ..write(' ')
-      ..write(children.length == 1 ? "child" : "children")
-      ..writeln(':');
-    for (int i = 0; i < children.length; i++) {
-      buffer
-        ..write(indent)
-        ..write('Child ')
-        ..write(i)
-        ..write(' of unit at offset ')
-        ..write(paddedHex(_unitOffset))
-        ..writeln(':');
-      children[i].writeToStringBuffer(buffer, indent: indent + '  ');
+        ..write('Children (')
+        ..write(children.length)
+        ..writeln('):');
+      final sortedChildren = children.entries.toList()
+        ..sort((kv1, kv2) => Comparable.compare(kv1.key, kv2.key));
+      for (int i = 0; i < sortedChildren.length; i++) {
+        final offset = sortedChildren[i].key;
+        final child = sortedChildren[i].value;
+        buffer
+          ..write(indent)
+          ..write('Child ')
+          ..write(i)
+          ..write(' (at offset 0x')
+          ..write(paddedHex(offset))
+          ..writeln('):');
+        child.writeToStringBuffer(buffer, unit: unit, indent: indent + '  ');
+      }
     }
   }
 
@@ -450,82 +395,124 @@
   }
 }
 
-/// A class representing a DWARF compilation unit.
-class CompilationUnit {
-  final Reader reader;
-  final Map<int, _AbbreviationsTable> _abbreviationsTables;
-  final LineNumberInfo _lineNumberInfo;
+class CompilationUnitHeader {
+  final int size;
+  final int version;
+  final int abbreviationsOffset;
+  final int addressSize;
+  final _AbbreviationsTable abbreviations;
 
-  int size;
-  int version;
-  int abbreviationOffset;
-  int addressSize;
-  List<DebugInformationEntry> contents;
-  Map<int, DebugInformationEntry> referenceTable;
+  CompilationUnitHeader._(this.size, this.version, this.abbreviationsOffset,
+      this.addressSize, this.abbreviations);
 
-  CompilationUnit.fromReader(
-      this.reader, this._abbreviationsTables, this._lineNumberInfo) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    size = _initialLengthValue(reader);
+  static CompilationUnitHeader fromReader(
+      Reader reader, Map<int, _AbbreviationsTable> abbreviationsTables) {
+    final size = _initialLengthValue(reader);
     // An empty unit is an ending marker.
-    if (size == 0) {
-      return;
-    }
-    version = reader.readBytes(2);
+    if (size == 0) return null;
+    final version = reader.readBytes(2);
     if (version != 2) {
       throw FormatException("Expected DWARF version 2, got $version");
     }
-    abbreviationOffset = reader.readBytes(4);
-    if (!_abbreviationsTables.containsKey(abbreviationOffset)) {
+    final abbreviationsOffset = reader.readBytes(4);
+    if (!abbreviationsTables.containsKey(abbreviationsOffset)) {
       throw FormatException("No abbreviation table found for offset "
-          "0x${paddedHex(abbreviationOffset, 4)}");
+          "0x${paddedHex(abbreviationsOffset, 4)}");
     }
-    addressSize = reader.readByte();
-    contents = <DebugInformationEntry>[];
-    referenceTable = <int, DebugInformationEntry>{};
-    while (!reader.done) {
-      final subunit =
-          DebugInformationEntry.fromReader(reader.shrink(reader.offset), this);
-      reader.seek(subunit.reader.offset);
-      if (subunit.code == 0) {
-        break;
-      }
-      assert(subunit.tag == _Tag.compileUnit);
-      contents.add(subunit);
-    }
+    final addressSize = reader.readByte();
+    return CompilationUnitHeader._(size, version, abbreviationsOffset,
+        addressSize, abbreviationsTables[abbreviationsOffset]);
   }
 
-  Iterable<CallInfo> callInfo(int address) {
-    for (final unit in contents) {
-      final lineNumberProgram =
-          _lineNumberInfo[unit[_AttributeName.statementList]];
-      final callInfo = unit.callInfo(address, lineNumberProgram);
-      if (callInfo != null) {
-        return callInfo;
-      }
-    }
-    return null;
-  }
-
-  _AbbreviationsTable get abbreviations =>
-      _abbreviationsTables[abbreviationOffset];
-
   void writeToStringBuffer(StringBuffer buffer) {
     buffer
       ..writeln('Compilation unit:')
+      ..write('  Size: ')
+      ..writeln(size)
       ..write('  Version: ')
       ..writeln(version)
-      ..write('  Abbreviation offset: ')
-      ..writeln(paddedHex(abbreviationOffset, 4))
+      ..write('  Abbreviations offset: 0x')
+      ..writeln(paddedHex(abbreviationsOffset, 4))
       ..write('  Address size: ')
       ..writeln(addressSize)
       ..writeln();
-    for (final die in contents) {
-      die.writeToStringBuffer(buffer);
+  }
+
+  @override
+  String toString() {
+    final buffer = StringBuffer();
+    writeToStringBuffer(buffer);
+    return buffer.toString();
+  }
+}
+
+/// A class representing a DWARF compilation unit.
+class CompilationUnit {
+  CompilationUnitHeader header;
+  Map<int, DebugInformationEntry> referenceTable;
+
+  CompilationUnit._(this.header, this.referenceTable);
+
+  static CompilationUnit fromReader(
+      Reader reader, Map<int, _AbbreviationsTable> abbreviationsTables) {
+    final header =
+        CompilationUnitHeader.fromReader(reader, abbreviationsTables);
+    if (header == null) return null;
+
+    final referenceTable = Map.fromEntries(reader.readRepeatedWithOffsets(
+        (r) => DebugInformationEntry.fromReader(r, header),
+        absolute: true));
+    _addChildEntries(referenceTable);
+    return CompilationUnit._(header, referenceTable);
+  }
+
+  static void _addChildEntries(Map<int, DebugInformationEntry> table) {
+    final workList = Queue<MapEntry<int, DebugInformationEntry>>();
+    for (final die in table.values) {
+      if (die.children != null) {
+        workList.addAll(die.children.entries);
+      }
+    }
+    while (workList.isNotEmpty) {
+      final kv = workList.removeFirst();
+      final offset = kv.key;
+      final child = kv.value;
+      table[offset] = child;
+      if (child.children != null) {
+        workList.addAll(child.children.entries);
+      }
+    }
+  }
+
+  Iterable<CallInfo> callInfo(LineNumberInfo lineNumberInfo, int address) {
+    for (final die in referenceTable.values) {
+      final lineNumberProgram =
+          lineNumberInfo[die[_AttributeName.statementList]];
+      final callInfo = die.callInfo(this, lineNumberProgram, address);
+      if (callInfo != null) return callInfo;
+    }
+    return null;
+  }
+
+  String nameOfOrigin(int offset) {
+    if (!referenceTable.containsKey(offset)) {
+      throw ArgumentError(
+          "${paddedHex(offset)} is not the offset of an abbreviated unit");
+    }
+    final origin = referenceTable[offset];
+    assert(origin.containsKey(_AttributeName.name));
+    return origin[_AttributeName.name] as String;
+  }
+
+  void writeToStringBuffer(StringBuffer buffer) {
+    header.writeToStringBuffer(buffer);
+    for (final offset in referenceTable.keys) {
+      final die = referenceTable[offset];
+      buffer
+        ..write('Debug information entry at offset 0x')
+        ..write(paddedHex(offset))
+        ..writeln(':');
+      die.writeToStringBuffer(buffer, unit: this);
       buffer.writeln();
     }
   }
@@ -540,37 +527,23 @@
 
 /// A class representing a DWARF `.debug_info` section.
 class DebugInfo {
-  final Reader reader;
-  final Map<int, _AbbreviationsTable> _abbreviationsTables;
-  final LineNumberInfo _lineNumberInfo;
+  final List<CompilationUnit> units;
 
-  List<CompilationUnit> units;
+  DebugInfo._(this.units);
 
-  DebugInfo.fromReader(
-      this.reader, this._abbreviationsTables, this._lineNumberInfo) {
-    _read();
+  static DebugInfo fromReader(
+      Reader reader, Map<int, _AbbreviationsTable> abbreviationsTable) {
+    final units = reader
+        .readRepeated(
+            (r) => CompilationUnit.fromReader(reader, abbreviationsTable))
+        .toList();
+    return DebugInfo._(units);
   }
 
-  void _read() {
-    reader.reset();
-    units = <CompilationUnit>[];
-    while (!reader.done) {
-      final unit = CompilationUnit.fromReader(
-          reader.shrink(reader.offset), _abbreviationsTables, _lineNumberInfo);
-      reader.seek(unit.reader.offset);
-      if (unit.size == 0) {
-        break;
-      }
-      units.add(unit);
-    }
-  }
-
-  Iterable<CallInfo> callInfo(int address) {
+  Iterable<CallInfo> callInfo(LineNumberInfo lineNumberInfo, int address) {
     for (final unit in units) {
-      final callInfo = unit.callInfo(address);
-      if (callInfo != null) {
-        return callInfo;
-      }
+      final callInfo = unit.callInfo(lineNumberInfo, address);
+      if (callInfo != null) return callInfo;
     }
     return null;
   }
@@ -590,26 +563,21 @@
 }
 
 class FileEntry {
-  final Reader reader;
+  final String name;
+  final int directoryIndex;
+  final int lastModified;
+  final int size;
 
-  String name;
-  int directoryIndex;
-  int lastModified;
-  int size;
+  FileEntry._(this.name, this.directoryIndex, this.lastModified, this.size);
 
-  FileEntry.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    name = reader.readNullTerminatedString();
-    if (name == "") {
-      return;
-    }
-    directoryIndex = reader.readLEB128EncodedInteger();
-    lastModified = reader.readLEB128EncodedInteger();
-    size = reader.readLEB128EncodedInteger();
+  static FileEntry fromReader(Reader reader) {
+    final name = reader.readNullTerminatedString();
+    // An empty null-terminated string marks the table end.
+    if (name == "") return null;
+    final directoryIndex = reader.readLEB128EncodedInteger();
+    final lastModified = reader.readLEB128EncodedInteger();
+    final size = reader.readLEB128EncodedInteger();
+    return FileEntry._(name, directoryIndex, lastModified, size);
   }
 
   @override
@@ -620,28 +588,18 @@
 }
 
 class FileInfo {
-  final Reader reader;
+  final Map<int, FileEntry> _files;
 
-  Map<int, FileEntry> _files;
+  FileInfo._(this._files);
 
-  FileInfo.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    _files = <int, FileEntry>{};
-    int index = 1;
-    while (!reader.done) {
-      final file = FileEntry.fromReader(reader.shrink(reader.offset));
-      reader.seek(file.reader.offset);
-      // An empty null-terminated string marks the table end.
-      if (file.name == "") {
-        break;
-      }
-      _files[index] = file;
-      index++;
+  static FileInfo fromReader(Reader reader) {
+    final offsetFiles = reader.readRepeated(FileEntry.fromReader).toList();
+    final files = <int, FileEntry>{};
+    for (int i = 0; i < offsetFiles.length; i++) {
+      // File entries are one-based, not zero-based.
+      files[i + 1] = offsetFiles[i];
     }
+    return FileInfo._(files);
   }
 
   bool containsKey(int index) => _files.containsKey(index);
@@ -757,207 +715,85 @@
       "  Is ${endSequence ? "" : "not "}just after the end of a sequence.";
 }
 
-/// A class representing a DWARF line number program.
-class LineNumberProgram {
-  final Reader reader;
+class LineNumberProgramHeader {
+  final int size;
+  final int version;
+  final int headerLength;
+  final int minimumInstructionLength;
+  final bool defaultIsStatement;
+  final int lineBase;
+  final int lineRange;
+  final int opcodeBase;
+  final Map<int, int> standardOpcodeLengths;
+  final List<String> includeDirectories;
+  final FileInfo filesInfo;
 
-  int size;
-  int version;
-  int headerLength;
-  int minimumInstructionLength;
-  bool defaultIsStatement;
-  int lineBase;
-  int lineRange;
-  int opcodeBase;
-  Map<int, int> standardOpcodeLengths;
-  List<String> includeDirectories;
-  FileInfo filesInfo;
-  List<LineNumberState> calculatedMatrix;
-  Map<int, LineNumberState> cachedLookups;
+  LineNumberProgramHeader._(
+      this.size,
+      this.version,
+      this.headerLength,
+      this.minimumInstructionLength,
+      this.defaultIsStatement,
+      this.lineBase,
+      this.lineRange,
+      this.opcodeBase,
+      this.standardOpcodeLengths,
+      this.includeDirectories,
+      this.filesInfo);
 
-  LineNumberProgram.fromReader(this.reader) {
-    _read();
-  }
+  static LineNumberProgramHeader fromReader(Reader reader) {
+    final size = _initialLengthValue(reader);
+    if (size == 0) return null;
+    final version = reader.readBytes(2);
 
-  void _read() {
-    reader.reset();
-    size = _initialLengthValue(reader);
-    if (size == 0) {
-      return;
+    final headerLength = reader.readBytes(4);
+    // We'll need this later as a double-check that we've read the entire
+    // header.
+    final headerStart = reader.offset;
+    final minimumInstructionLength = reader.readByte();
+    final isStmtByte = reader.readByte();
+    if (isStmtByte < 0 || isStmtByte > 1) {
+      throw FormatException(
+          "Unexpected value for default_is_stmt: ${isStmtByte}");
     }
-    version = reader.readBytes(2);
-    headerLength = reader.readBytes(4);
-    minimumInstructionLength = reader.readByte();
-    switch (reader.readByte()) {
-      case 0:
-        defaultIsStatement = false;
-        break;
-      case 1:
-        defaultIsStatement = true;
-        break;
-      default:
-        throw FormatException("Unexpected value for default_is_stmt");
-    }
-    lineBase = reader.readByte(signed: true);
-    lineRange = reader.readByte();
-    opcodeBase = reader.readByte();
-    standardOpcodeLengths = <int, int>{};
+    final defaultIsStatement = isStmtByte == 1;
+    final lineBase = reader.readByte(signed: true);
+    final lineRange = reader.readByte();
+    final opcodeBase = reader.readByte();
+    final standardOpcodeLengths = <int, int>{};
     // Standard opcode numbering starts at 1.
     for (int i = 1; i < opcodeBase; i++) {
       standardOpcodeLengths[i] = reader.readLEB128EncodedInteger();
     }
-    includeDirectories = <String>[];
+    final includeDirectories = <String>[];
     while (!reader.done) {
       final directory = reader.readNullTerminatedString();
-      if (directory == "") {
-        break;
-      }
+      if (directory == "") break;
       includeDirectories.add(directory);
     }
-    filesInfo = FileInfo.fromReader(reader.shrink(reader.offset));
-    reader.seek(filesInfo.reader.offset);
-    // Header length doesn't include the 4-byte length or 2-byte version fields.
-    assert(reader.offset == headerLength + 6);
-    calculatedMatrix = <LineNumberState>[];
-    final currentState = LineNumberState(defaultIsStatement);
-    while (!reader.done) {
-      _applyNextOpcode(currentState);
+    if (reader.done) {
+      throw FormatException("Unterminated directory entry");
     }
-    if (calculatedMatrix.isEmpty) {
-      throw FormatException("No line number information generated by program");
-    }
-    // Set the offset to the declared size in case of padding.  The declared
-    // size does not include the size of the size field itself.
-    reader.seek(size + 4);
-    cachedLookups = <int, LineNumberState>{};
-  }
+    final filesInfo = FileInfo.fromReader(reader);
 
-  void _addStateToMatrix(LineNumberState state) {
-    calculatedMatrix.add(state.clone());
-  }
-
-  void _applyNextOpcode(LineNumberState state) {
-    void applySpecialOpcode(int opcode) {
-      final adjustedOpcode = opcode - opcodeBase;
-      state.address = adjustedOpcode ~/ lineRange;
-      state.line += lineBase + (adjustedOpcode % lineRange);
+    // Header length doesn't include the 2-byte version or 4-byte length fields.
+    if (reader.offset != headerStart + headerLength) {
+      throw FormatException("At offset ${reader.offset} after header, "
+          "expected to be at offset ${headerStart + headerLength}");
     }
 
-    final opcode = reader.readByte();
-    if (opcode >= opcodeBase) {
-      return applySpecialOpcode(opcode);
-    }
-    switch (opcode) {
-      case 0: // Extended opcodes
-        final extendedLength = reader.readByte();
-        final subOpcode = reader.readByte();
-        switch (subOpcode) {
-          case 0:
-            throw FormatException(
-                "Attempted to execute extended opcode ${subOpcode} (padding?)");
-          case 1: // DW_LNE_end_sequence
-            state.endSequence = true;
-            _addStateToMatrix(state);
-            state.reset();
-            break;
-          case 2: // DW_LNE_set_address
-            // The length includes the subopcode.
-            final valueLength = extendedLength - 1;
-            assert(valueLength == 4 || valueLength == 8);
-            final newAddress = reader.readBytes(valueLength);
-            state.address = newAddress;
-            break;
-          case 3: // DW_LNE_define_file
-            throw FormatException("DW_LNE_define_file instruction not handled");
-          default:
-            throw FormatException(
-                "Extended opcode ${subOpcode} not in DWARF 2");
-        }
-        break;
-      case 1: // DW_LNS_copy
-        _addStateToMatrix(state);
-        state.basicBlock = false;
-        break;
-      case 2: // DW_LNS_advance_pc
-        final increment = reader.readLEB128EncodedInteger();
-        state.address += minimumInstructionLength * increment;
-        break;
-      case 3: // DW_LNS_advance_line
-        state.line += reader.readLEB128EncodedInteger(signed: true);
-        break;
-      case 4: // DW_LNS_set_file
-        state.fileIndex = reader.readLEB128EncodedInteger();
-        break;
-      case 5: // DW_LNS_set_column
-        state.column = reader.readLEB128EncodedInteger();
-        break;
-      case 6: // DW_LNS_negate_stmt
-        state.isStatement = !state.isStatement;
-        break;
-      case 7: // DW_LNS_set_basic_block
-        state.basicBlock = true;
-        break;
-      case 8: // DW_LNS_const_add_pc
-        applySpecialOpcode(255);
-        break;
-      case 9: // DW_LNS_fixed_advance_pc
-        state.address += reader.readBytes(2);
-        break;
-      default:
-        throw FormatException("Standard opcode ${opcode} not in DWARF 2");
-    }
-  }
-
-  bool containsKey(int address) {
-    assert(calculatedMatrix.last.endSequence);
-    return address >= calculatedMatrix.first.address &&
-        address < calculatedMatrix.last.address;
-  }
-
-  LineNumberState operator [](int address) {
-    if (cachedLookups.containsKey(address)) {
-      return cachedLookups[address];
-    }
-    if (!containsKey(address)) {
-      return null;
-    }
-    // Since the addresses are generated in increasing order, we can do a
-    // binary search to find the right state.
-    assert(calculatedMatrix != null && calculatedMatrix.isNotEmpty);
-    var minIndex = 0;
-    var maxIndex = calculatedMatrix.length - 1;
-    while (true) {
-      if (minIndex == maxIndex || minIndex + 1 == maxIndex) {
-        final found = calculatedMatrix[minIndex];
-        cachedLookups[address] = found;
-        return found;
-      }
-      final index = minIndex + ((maxIndex - minIndex) ~/ 2);
-      final compared = calculatedMatrix[index].address.compareTo(address);
-      if (compared == 0) {
-        return calculatedMatrix[index];
-      } else if (compared < 0) {
-        minIndex = index;
-      } else if (compared > 0) {
-        maxIndex = index;
-      }
-    }
-  }
-
-  String filename(int address) {
-    final state = this[address];
-    if (state == null) {
-      return null;
-    }
-    return filesInfo[state.fileIndex].name;
-  }
-
-  int lineNumber(int address) {
-    final state = this[address];
-    if (state == null) {
-      return null;
-    }
-    return state.line;
+    return LineNumberProgramHeader._(
+        size,
+        version,
+        headerLength,
+        minimumInstructionLength,
+        defaultIsStatement,
+        lineBase,
+        lineRange,
+        opcodeBase,
+        standardOpcodeLengths,
+        includeDirectories,
+        filesInfo);
   }
 
   void writeToStringBuffer(StringBuffer buffer) {
@@ -999,6 +835,153 @@
     }
 
     filesInfo.writeToStringBuffer(buffer);
+  }
+
+  @override
+  String toString() {
+    final buffer = StringBuffer();
+    writeToStringBuffer(buffer);
+    return buffer.toString();
+  }
+}
+
+/// A class representing a DWARF line number program.
+class LineNumberProgram {
+  final LineNumberProgramHeader header;
+  final List<LineNumberState> calculatedMatrix;
+  final Map<int, LineNumberState> cachedLookups;
+
+  LineNumberProgram._(this.header, this.calculatedMatrix) : cachedLookups = {};
+
+  static LineNumberProgram fromReader(Reader reader) {
+    final header = LineNumberProgramHeader.fromReader(reader);
+    if (header == null) return null;
+    final calculatedMatrix = _readOpcodes(reader, header).toList();
+    if (calculatedMatrix.isEmpty) {
+      throw FormatException("No line number information generated by program");
+    }
+    return LineNumberProgram._(header, calculatedMatrix);
+  }
+
+  static Iterable<LineNumberState> _readOpcodes(
+      Reader reader, LineNumberProgramHeader header) sync* {
+    final state = LineNumberState(header.defaultIsStatement);
+
+    void applySpecialOpcode(int opcode) {
+      final adjustedOpcode = opcode - header.opcodeBase;
+      state.address = adjustedOpcode ~/ header.lineRange;
+      state.line += header.lineBase + (adjustedOpcode % header.lineRange);
+    }
+
+    while (!reader.done) {
+      final opcode = reader.readByte();
+      if (opcode >= header.opcodeBase) {
+        applySpecialOpcode(opcode);
+        continue;
+      }
+      switch (opcode) {
+        case 0: // Extended opcodes
+          final extendedLength = reader.readByte();
+          final subOpcode = reader.readByte();
+          switch (subOpcode) {
+            case 0:
+              throw FormatException("Attempted to execute extended opcode 0");
+            case 1: // DW_LNE_end_sequence
+              state.endSequence = true;
+              yield state.clone();
+              state.reset();
+              break;
+            case 2: // DW_LNE_set_address
+              // The length includes the subopcode.
+              final valueLength = extendedLength - 1;
+              assert(valueLength == 4 || valueLength == 8);
+              final newAddress = reader.readBytes(valueLength);
+              state.address = newAddress;
+              break;
+            case 3: // DW_LNE_define_file
+              throw FormatException(
+                  "DW_LNE_define_file instruction not handled");
+            default:
+              throw FormatException(
+                  "Extended opcode ${subOpcode} not in DWARF 2");
+          }
+          break;
+        case 1: // DW_LNS_copy
+          yield state.clone();
+          state.basicBlock = false;
+          break;
+        case 2: // DW_LNS_advance_pc
+          final increment = reader.readLEB128EncodedInteger();
+          state.address += header.minimumInstructionLength * increment;
+          break;
+        case 3: // DW_LNS_advance_line
+          state.line += reader.readLEB128EncodedInteger(signed: true);
+          break;
+        case 4: // DW_LNS_set_file
+          state.fileIndex = reader.readLEB128EncodedInteger();
+          break;
+        case 5: // DW_LNS_set_column
+          state.column = reader.readLEB128EncodedInteger();
+          break;
+        case 6: // DW_LNS_negate_stmt
+          state.isStatement = !state.isStatement;
+          break;
+        case 7: // DW_LNS_set_basic_block
+          state.basicBlock = true;
+          break;
+        case 8: // DW_LNS_const_add_pc
+          applySpecialOpcode(255);
+          break;
+        case 9: // DW_LNS_fixed_advance_pc
+          state.address += reader.readBytes(2);
+          break;
+        default:
+          throw FormatException("Standard opcode ${opcode} not in DWARF 2");
+      }
+    }
+  }
+
+  bool containsKey(int address) {
+    assert(calculatedMatrix.last.endSequence);
+    return address >= calculatedMatrix.first.address &&
+        address < calculatedMatrix.last.address;
+  }
+
+  LineNumberState operator [](int address) {
+    if (cachedLookups.containsKey(address)) return cachedLookups[address];
+
+    if (!containsKey(address)) return null;
+
+    // Since the addresses are generated in increasing order, we can do a
+    // binary search to find the right state.
+    assert(calculatedMatrix != null && calculatedMatrix.isNotEmpty);
+    var minIndex = 0;
+    var maxIndex = calculatedMatrix.length - 1;
+    while (true) {
+      if (minIndex == maxIndex || minIndex + 1 == maxIndex) {
+        final found = calculatedMatrix[minIndex];
+        cachedLookups[address] = found;
+        return found;
+      }
+      final index = minIndex + ((maxIndex - minIndex) ~/ 2);
+      final compared = calculatedMatrix[index].address.compareTo(address);
+      if (compared == 0) {
+        return calculatedMatrix[index];
+      } else if (compared < 0) {
+        minIndex = index;
+      } else if (compared > 0) {
+        maxIndex = index;
+      }
+    }
+  }
+
+  String filename(int address) =>
+      header.filesInfo[this[address]?.fileIndex]?.name;
+
+  int lineNumber(int address) => this[address]?.line;
+
+  void writeToStringBuffer(StringBuffer buffer) {
+    header.writeToStringBuffer(buffer);
 
     buffer.writeln("Results of line number program:");
     for (final state in calculatedMatrix) {
@@ -1015,26 +998,14 @@
 
 /// A class representing a DWARF .debug_line section.
 class LineNumberInfo {
-  final Reader reader;
+  final Map<int, LineNumberProgram> programs;
 
-  Map<int, LineNumberProgram> programs;
+  LineNumberInfo._(this.programs);
 
-  LineNumberInfo.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    programs = <int, LineNumberProgram>{};
-    while (!reader.done) {
-      final start = reader.offset;
-      final program = LineNumberProgram.fromReader(reader.shrink(start));
-      reader.seek(program.reader.offset);
-      if (program.size == 0) {
-        break;
-      }
-      programs[start] = program;
-    }
+  static LineNumberInfo fromReader(Reader reader) {
+    final programs = Map.fromEntries(
+        reader.readRepeatedWithOffsets(LineNumberProgram.fromReader));
+    return LineNumberInfo._(programs);
   }
 
   bool containsKey(int address) => programs.containsKey(address);
@@ -1087,7 +1058,7 @@
   DartCallInfo({this.inlined = false, this.function, this.filename, this.line});
 
   @override
-  bool get isInternal => line <= 0;
+  bool get isInternal => false;
 
   @override
   int get hashCode => _hashFinish(_hashCombine(
@@ -1108,8 +1079,7 @@
   }
 
   @override
-  String toString() =>
-      "${function} (${filename}:${isInternal ? "??" : line.toString()})";
+  String toString() => "${function} (${filename}${line <= 0 ? '' : ':$line'})";
 }
 
 /// Represents the information for a call site located in a Dart stub.
@@ -1132,7 +1102,7 @@
   }
 
   @override
-  String toString() => "${name} + ${offset}";
+  String toString() => "${name}+0x${offset.toRadixString(16)}";
 }
 
 /// The instructions section in which a program counter address is located.
@@ -1167,6 +1137,9 @@
         offset == other.offset &&
         section == other.section;
   }
+
+  @override
+  String toString() => 'PCOffset($section, $offset)';
 }
 
 /// The DWARF debugging information for a Dart snapshot.
@@ -1175,11 +1148,17 @@
   final Map<int, _AbbreviationsTable> _abbreviationTables;
   final DebugInfo _debugInfo;
   final LineNumberInfo _lineNumberInfo;
-  final int _vmStartAddress;
-  final int _isolateStartAddress;
+
+  /// Virtual address of the start of the VM instructions section in the DWARF
+  /// information.
+  final int vmStartAddress;
+
+  /// Virtual address of the start of the isolate instructions section in the
+  /// DWARF information.
+  final int isolateStartAddress;
 
   Dwarf._(this._elf, this._abbreviationTables, this._debugInfo,
-      this._lineNumberInfo, this._vmStartAddress, this._isolateStartAddress);
+      this._lineNumberInfo, this.vmStartAddress, this.isolateStartAddress);
 
   /// Attempts to load the DWARF debugging information from the reader.
   ///
@@ -1188,7 +1167,7 @@
     // Currently, the only DWARF-containing format we recognize is ELF.
     final elf = Elf.fromReader(reader);
     if (elf == null) return null;
-    return Dwarf._loadSectionsFromElf(elf);
+    return Dwarf._loadSectionsFromElf(reader, elf);
   }
 
   /// Attempts to load the DWARF debugging information from the given bytes.
@@ -1202,24 +1181,19 @@
   /// Returns a [Dwarf] object if the load succeeds, otherwise returns null.
   static Dwarf fromFile(String path) => Dwarf.fromReader(Reader.fromFile(path));
 
-  static Dwarf _loadSectionsFromElf(Elf elf) {
+  static Dwarf _loadSectionsFromElf(Reader reader, Elf elf) {
     final abbrevSection = elf.namedSections(".debug_abbrev").single;
-    final abbreviationTables = <int, _AbbreviationsTable>{};
-    var abbreviationOffset = 0;
-    while (abbreviationOffset < abbrevSection.reader.length) {
-      final table = _AbbreviationsTable.fromReader(
-          abbrevSection.reader.shrink(abbreviationOffset));
-      abbreviationTables[abbreviationOffset] = table;
-      abbreviationOffset += table.reader.offset;
-    }
-    assert(abbreviationOffset == abbrevSection.reader.length);
+    final abbrevReader = abbrevSection.refocusedCopy(reader);
+    final abbreviationTables = Map.fromEntries(
+        abbrevReader.readRepeatedWithOffsets(_AbbreviationsTable.fromReader));
 
     final lineNumberSection = elf.namedSections(".debug_line").single;
-    final lineNumberInfo = LineNumberInfo.fromReader(lineNumberSection.reader);
+    final lineNumberInfo =
+        LineNumberInfo.fromReader(lineNumberSection.refocusedCopy(reader));
 
     final infoSection = elf.namedSections(".debug_info").single;
     final debugInfo = DebugInfo.fromReader(
-        infoSection.reader, abbreviationTables, lineNumberInfo);
+        infoSection.refocusedCopy(reader), abbreviationTables);
 
     final vmStartSymbol = elf.dynamicSymbolFor(constants.vmSymbolName);
     if (vmStartSymbol == null) {
@@ -1248,19 +1222,16 @@
   /// to user or library code is returned.
   Iterable<CallInfo> callInfoFor(int address,
       {bool includeInternalFrames = false}) {
-    var calls = _debugInfo.callInfo(address);
+    var calls = _debugInfo.callInfo(_lineNumberInfo, address);
     if (calls == null) {
-      // Since we're dealing with return addresses in stack frames, subtract
-      // one in case the return address is just off the end of the stub (since
-      // the calling instruction is before the return address).
-      final symbol = _elf.staticSymbolAt(address - 1);
+      final symbol = _elf.staticSymbolAt(address);
       if (symbol != null) {
         final offset = address - symbol.value;
         calls = <CallInfo>[StubCallInfo(name: symbol.name, offset: offset)];
       }
     }
-    if (calls != null && !includeInternalFrames) {
-      return calls.where((CallInfo c) => !c.isInternal);
+    if (!includeInternalFrames) {
+      return calls?.where((CallInfo c) => !c.isInternal);
     }
     return calls;
   }
@@ -1269,9 +1240,9 @@
   int virtualAddressOf(PCOffset pcOffset) {
     switch (pcOffset.section) {
       case InstructionsSection.vm:
-        return pcOffset.offset + _vmStartAddress;
+        return pcOffset.offset + vmStartAddress;
       case InstructionsSection.isolate:
-        return pcOffset.offset + _isolateStartAddress;
+        return pcOffset.offset + isolateStartAddress;
       default:
         throw "Unexpected value for instructions section";
     }
diff --git a/pkg/native_stack_traces/lib/src/elf.dart b/pkg/native_stack_traces/lib/src/elf.dart
index 64b325a..cee46f0 100644
--- a/pkg/native_stack_traces/lib/src/elf.dart
+++ b/pkg/native_stack_traces/lib/src/elf.dart
@@ -65,94 +65,84 @@
   }
 }
 
+/// The header of the ELF file, which includes information necessary to parse
+/// the rest of the file.
 class ElfHeader {
-  final Reader startingReader;
+  final int wordSize;
+  final Endian endian;
+  final int entry;
+  final int flags;
+  final int headerSize;
+  final int programHeaderOffset;
+  final int programHeaderCount;
+  final int programHeaderEntrySize;
+  final int sectionHeaderOffset;
+  final int sectionHeaderCount;
+  final int sectionHeaderEntrySize;
+  final int sectionHeaderStringsIndex;
 
-  int wordSize;
-  Endian endian;
-  int entry;
-  int flags;
-  int headerSize;
-  int programHeaderOffset;
-  int sectionHeaderOffset;
-  int programHeaderCount;
-  int sectionHeaderCount;
-  int programHeaderEntrySize;
-  int sectionHeaderEntrySize;
-  int sectionHeaderStringsIndex;
+  ElfHeader._(
+      this.wordSize,
+      this.endian,
+      this.entry,
+      this.flags,
+      this.headerSize,
+      this.programHeaderOffset,
+      this.sectionHeaderOffset,
+      this.programHeaderCount,
+      this.sectionHeaderCount,
+      this.programHeaderEntrySize,
+      this.sectionHeaderEntrySize,
+      this.sectionHeaderStringsIndex);
 
-  int get programHeaderSize => programHeaderCount * programHeaderEntrySize;
-  int get sectionHeaderSize => sectionHeaderCount * sectionHeaderEntrySize;
+  static ElfHeader fromReader(Reader reader) {
+    final fileSize = reader.length;
 
-  // Constants used within the ELF specification.
-  static const _ELFMAG = "\x7fELF";
-  static const _ELFCLASS32 = 0x01;
-  static const _ELFCLASS64 = 0x02;
-  static const _ELFDATA2LSB = 0x01;
-  static const _ELFDATA2MSB = 0x02;
-
-  ElfHeader.fromReader(this.startingReader) {
-    _read();
-  }
-
-  static bool startsWithMagicNumber(Reader reader) {
-    reader.reset();
     for (final sigByte in _ELFMAG.codeUnits) {
       if (reader.readByte() != sigByte) {
-        return false;
+        return null;
       }
     }
-    return true;
-  }
 
-  int _readWordSize(Reader reader) {
+    int wordSize;
     switch (reader.readByte()) {
       case _ELFCLASS32:
-        return 4;
+        wordSize = 4;
+        break;
       case _ELFCLASS64:
-        return 8;
+        wordSize = 8;
+        break;
       default:
         throw FormatException("Unexpected e_ident[EI_CLASS] value");
     }
-  }
+    final calculatedHeaderSize = 0x18 + 3 * wordSize + 0x10;
 
-  int get calculatedHeaderSize => 0x18 + 3 * wordSize + 0x10;
-
-  Endian _readEndian(Reader reader) {
-    switch (reader.readByte()) {
-      case _ELFDATA2LSB:
-        return Endian.little;
-      case _ELFDATA2MSB:
-        return Endian.big;
-      default:
-        throw FormatException("Unexpected e_indent[EI_DATA] value");
-    }
-  }
-
-  void _read() {
-    startingReader.reset();
-    for (final sigByte in _ELFMAG.codeUnits) {
-      if (startingReader.readByte() != sigByte) {
-        throw FormatException("Not an ELF file");
-      }
-    }
-    wordSize = _readWordSize(startingReader);
-    final fileSize = startingReader.bdata.buffer.lengthInBytes;
     if (fileSize < calculatedHeaderSize) {
       throw FormatException("ELF file too small for header: "
           "file size ${fileSize} < "
           "calculated header size $calculatedHeaderSize");
     }
-    endian = _readEndian(startingReader);
-    if (startingReader.readByte() != 0x01) {
+
+    Endian endian;
+    switch (reader.readByte()) {
+      case _ELFDATA2LSB:
+        endian = Endian.little;
+        break;
+      case _ELFDATA2MSB:
+        endian = Endian.big;
+        break;
+      default:
+        throw FormatException("Unexpected e_indent[EI_DATA] value");
+    }
+
+    if (reader.readByte() != 0x01) {
       throw FormatException("Unexpected e_ident[EI_VERSION] value");
     }
 
     // After this point, we need the reader to be correctly set up re: word
     // size and endianness, since we start reading more than single bytes.
-    final reader = Reader.fromTypedData(startingReader.bdata,
-        wordSize: wordSize, endian: endian);
-    reader.seek(startingReader.offset);
+    reader.endian = endian;
+    reader.wordSize = wordSize;
 
     // Skip rest of e_ident/e_type/e_machine, i.e. move to e_version.
     reader.seek(0x14, absolute: true);
@@ -160,16 +150,26 @@
       throw FormatException("Unexpected e_version value");
     }
 
-    entry = _readElfAddress(reader);
-    programHeaderOffset = _readElfOffset(reader);
-    sectionHeaderOffset = _readElfOffset(reader);
-    flags = _readElfWord(reader);
-    headerSize = _readElfHalf(reader);
-    programHeaderEntrySize = _readElfHalf(reader);
-    programHeaderCount = _readElfHalf(reader);
-    sectionHeaderEntrySize = _readElfHalf(reader);
-    sectionHeaderCount = _readElfHalf(reader);
-    sectionHeaderStringsIndex = _readElfHalf(reader);
+    final entry = _readElfAddress(reader);
+    final programHeaderOffset = _readElfOffset(reader);
+    final sectionHeaderOffset = _readElfOffset(reader);
+    final flags = _readElfWord(reader);
+    final headerSize = _readElfHalf(reader);
+
+    final programHeaderEntrySize = _readElfHalf(reader);
+    final programHeaderCount = _readElfHalf(reader);
+    final programHeaderSize = programHeaderEntrySize * programHeaderCount;
+
+    final sectionHeaderEntrySize = _readElfHalf(reader);
+    final sectionHeaderCount = _readElfHalf(reader);
+    final sectionHeaderSize = sectionHeaderEntrySize * sectionHeaderCount;
+
+    final sectionHeaderStringsIndex = _readElfHalf(reader);
+
+    if (reader.offset != headerSize) {
+      throw FormatException("Only read ${reader.offset} bytes, not the "
+          "full header size ${headerSize}");
+    }
 
     if (headerSize != calculatedHeaderSize) {
       throw FormatException("Stored ELF header size ${headerSize} != "
@@ -187,8 +187,32 @@
     if (fileSize < sectionHeaderOffset + sectionHeaderSize) {
       throw FormatException("File is truncated within the section header");
     }
+
+    return ElfHeader._(
+        wordSize,
+        endian,
+        entry,
+        flags,
+        headerSize,
+        programHeaderOffset,
+        sectionHeaderOffset,
+        programHeaderCount,
+        sectionHeaderCount,
+        programHeaderEntrySize,
+        sectionHeaderEntrySize,
+        sectionHeaderStringsIndex);
   }
 
+  int get programHeaderSize => programHeaderCount * programHeaderEntrySize;
+  int get sectionHeaderSize => sectionHeaderCount * sectionHeaderEntrySize;
+
+  // Constants used within the ELF specification.
+  static const _ELFMAG = "\x7fELF";
+  static const _ELFCLASS32 = 0x01;
+  static const _ELFCLASS64 = 0x02;
+  static const _ELFDATA2LSB = 0x01;
+  static const _ELFDATA2MSB = 0x02;
+
   void writeToStringBuffer(StringBuffer buffer) {
     buffer..write('Format is ')..write(wordSize * 8)..write(' bits');
     switch (endian) {
@@ -228,17 +252,18 @@
   }
 }
 
+/// An entry in the [ProgramHeader] describing a memory segment loaded into
+/// memory and used during runtime.
 class ProgramHeaderEntry {
-  Reader reader;
-
-  int type;
-  int flags;
-  int offset;
-  int vaddr;
-  int paddr;
-  int filesz;
-  int memsz;
-  int align;
+  final int type;
+  final int flags;
+  final int offset;
+  final int vaddr;
+  final int paddr;
+  final int filesz;
+  final int memsz;
+  final int align;
+  final int wordSize;
 
   // p_type constants from ELF specification.
   static const _PT_NULL = 0;
@@ -246,26 +271,27 @@
   static const _PT_DYNAMIC = 2;
   static const _PT_PHDR = 6;
 
-  ProgramHeaderEntry.fromReader(this.reader) {
-    assert(reader.wordSize == 4 || reader.wordSize == 8);
-    _read();
-  }
+  ProgramHeaderEntry._(this.type, this.flags, this.offset, this.vaddr,
+      this.paddr, this.filesz, this.memsz, this.align, this.wordSize);
 
-  void _read() {
-    reader.reset();
-    type = _readElfWord(reader);
+  static ProgramHeaderEntry fromReader(Reader reader) {
+    assert(reader.wordSize == 4 || reader.wordSize == 8);
+    final type = _readElfWord(reader);
+    int flags;
     if (reader.wordSize == 8) {
       flags = _readElfWord(reader);
     }
-    offset = _readElfOffset(reader);
-    vaddr = _readElfAddress(reader);
-    paddr = _readElfAddress(reader);
-    filesz = _readElfNative(reader);
-    memsz = _readElfNative(reader);
+    final offset = _readElfOffset(reader);
+    final vaddr = _readElfAddress(reader);
+    final paddr = _readElfAddress(reader);
+    final filesz = _readElfNative(reader);
+    final memsz = _readElfNative(reader);
     if (reader.wordSize == 4) {
       flags = _readElfWord(reader);
     }
-    align = _readElfNative(reader);
+    final align = _readElfNative(reader);
+    return ProgramHeaderEntry._(type, flags, offset, vaddr, paddr, filesz,
+        memsz, align, reader.wordSize);
   }
 
   static const _typeStrings = <int, String>{
@@ -289,17 +315,17 @@
       ..write('Flags: 0x')
       ..writeln(paddedHex(flags, 4))
       ..write('Offset: 0x')
-      ..writeln(paddedHex(offset, reader.wordSize))
+      ..writeln(paddedHex(offset, wordSize))
       ..write('Virtual address: 0x')
-      ..writeln(paddedHex(vaddr, reader.wordSize))
+      ..writeln(paddedHex(vaddr, wordSize))
       ..write('Physical address: 0x')
-      ..writeln(paddedHex(paddr, reader.wordSize))
+      ..writeln(paddedHex(paddr, wordSize))
       ..write('Size in file: ')
       ..writeln(filesz)
       ..write('Size in memory')
       ..writeln(memsz)
       ..write('Alignment: 0x')
-      ..write(paddedHex(align, reader.wordSize));
+      ..write(paddedHex(align, wordSize));
   }
 
   String toString() {
@@ -309,28 +335,22 @@
   }
 }
 
+/// A list of [ProgramHeaderEntry]s describing the memory segments loaded at
+/// runtime when this file is used.
 class ProgramHeader {
-  final Reader reader;
-  final int entrySize;
-  final int entryCount;
+  final List<ProgramHeaderEntry> _entries;
 
-  List<ProgramHeaderEntry> _entries;
-
-  ProgramHeader.fromReader(this.reader, {this.entrySize, this.entryCount}) {
-    _read();
-  }
+  ProgramHeader._(this._entries);
 
   int get length => _entries.length;
   ProgramHeaderEntry operator [](int index) => _entries[index];
 
-  void _read() {
-    reader.reset();
-    _entries = <ProgramHeaderEntry>[];
-    for (var i = 0; i < entryCount; i++) {
-      final entry = ProgramHeaderEntry.fromReader(
-          reader.shrink(i * entrySize, entrySize));
-      _entries.add(entry);
-    }
+  static ProgramHeader fromReader(Reader reader, ElfHeader header) {
+    final programReader = reader.refocusedCopy(
+        header.programHeaderOffset, header.programHeaderSize);
+    final entries =
+        programReader.readRepeated(ProgramHeaderEntry.fromReader).toList();
+    return ProgramHeader._(entries);
   }
 
   void writeToStringBuffer(StringBuffer buffer) {
@@ -351,23 +371,47 @@
   }
 }
 
+/// An entry in the [SectionHeader] that describes a single [Section].
 class SectionHeaderEntry {
-  final Reader reader;
-
-  int nameIndex;
+  final int nameIndex;
+  final int type;
+  final int flags;
+  final int addr;
+  final int offset;
+  final int size;
+  final int link;
+  final int info;
+  final int addrAlign;
+  final int entrySize;
+  final int wordSize;
   String _cachedName;
-  int type;
-  int flags;
-  int addr;
-  int offset;
-  int size;
-  int link;
-  int info;
-  int addrAlign;
-  int entrySize;
 
-  SectionHeaderEntry.fromReader(this.reader) {
-    _read();
+  SectionHeaderEntry._(
+      this.nameIndex,
+      this.type,
+      this.flags,
+      this.addr,
+      this.offset,
+      this.size,
+      this.link,
+      this.info,
+      this.addrAlign,
+      this.entrySize,
+      this.wordSize);
+
+  static SectionHeaderEntry fromReader(Reader reader) {
+    final nameIndex = _readElfWord(reader);
+    final type = _readElfWord(reader);
+    final flags = _readElfNative(reader);
+    final addr = _readElfAddress(reader);
+    final offset = _readElfOffset(reader);
+    final size = _readElfNative(reader);
+    final link = _readElfWord(reader);
+    final info = _readElfWord(reader);
+    final addrAlign = _readElfNative(reader);
+    final entrySize = _readElfNative(reader);
+    return SectionHeaderEntry._(nameIndex, type, flags, addr, offset, size,
+        link, info, addrAlign, entrySize, reader.wordSize);
   }
 
   // sh_type constants from ELF specification.
@@ -380,20 +424,6 @@
   static const _SHT_NOBITS = 8;
   static const _SHT_DYNSYM = 11;
 
-  void _read() {
-    reader.reset();
-    nameIndex = _readElfWord(reader);
-    type = _readElfWord(reader);
-    flags = _readElfNative(reader);
-    addr = _readElfAddress(reader);
-    offset = _readElfOffset(reader);
-    size = _readElfNative(reader);
-    link = _readElfWord(reader);
-    info = _readElfWord(reader);
-    addrAlign = _readElfNative(reader);
-    entrySize = _readElfNative(reader);
-  }
-
   void setName(StringTable nameTable) {
     _cachedName = nameTable[nameIndex];
   }
@@ -434,11 +464,11 @@
       ..write('Type: ')
       ..writeln(_typeToString(type))
       ..write('Flags: 0x')
-      ..writeln(paddedHex(flags, reader.wordSize))
+      ..writeln(paddedHex(flags, wordSize))
       ..write('Address: 0x')
-      ..writeln(paddedHex(addr, reader.wordSize))
+      ..writeln(paddedHex(addr, wordSize))
       ..write('Offset: 0x')
-      ..writeln(paddedHex(offset, reader.wordSize))
+      ..writeln(paddedHex(offset, wordSize))
       ..write('Size: ')
       ..writeln(size)
       ..write('Link: ')
@@ -446,7 +476,7 @@
       ..write('Info: 0x')
       ..writeln(paddedHex(info, 4))
       ..write('Address alignment: 0x')
-      ..writeln(paddedHex(addrAlign, reader.wordSize))
+      ..writeln(paddedHex(addrAlign, wordSize))
       ..write('Entry size: ')
       ..write(entrySize);
   }
@@ -458,61 +488,30 @@
   }
 }
 
+/// A list of [SectionHeaderEntry]s describing the [Section]s in the ELF file.
 class SectionHeader {
-  final Reader reader;
-  final int entrySize;
-  final int entryCount;
-  final int stringsIndex;
+  final List<SectionHeaderEntry> entries;
 
-  List<SectionHeaderEntry> _entries;
-  StringTable nameTable;
+  SectionHeader._(this.entries);
 
-  SectionHeader.fromReader(this.reader,
-      {this.entrySize, this.entryCount, this.stringsIndex}) {
-    _read();
-  }
-
-  SectionHeaderEntry _readSectionHeaderEntry(int index) {
-    final ret = SectionHeaderEntry.fromReader(
-        reader.shrink(index * entrySize, entrySize));
-    if (nameTable != null) {
-      ret.setName(nameTable);
-    }
-    return ret;
-  }
-
-  void _read() {
-    reader.reset();
-    // Set up the section header string table first so we can use it
-    // for the other section header entries.
-    final nameTableEntry = _readSectionHeaderEntry(stringsIndex);
+  static SectionHeader fromReader(Reader reader, ElfHeader header) {
+    final headerReader = reader.refocusedCopy(
+        header.sectionHeaderOffset, header.sectionHeaderSize);
+    final entries =
+        headerReader.readRepeated(SectionHeaderEntry.fromReader).toList();
+    final nameTableEntry = entries[header.sectionHeaderStringsIndex];
     assert(nameTableEntry.type == SectionHeaderEntry._SHT_STRTAB);
-    nameTable = StringTable(nameTableEntry,
-        reader.refocus(nameTableEntry.offset, nameTableEntry.size));
-    nameTableEntry.setName(nameTable);
-
-    _entries = <SectionHeaderEntry>[];
-    for (var i = 0; i < entryCount; i++) {
-      // We don't need to reparse the shstrtab entry.
-      if (i == stringsIndex) {
-        _entries.add(nameTableEntry);
-      } else {
-        _entries.add(_readSectionHeaderEntry(i));
-      }
-    }
+    return SectionHeader._(entries);
   }
 
-  int get length => _entries.length;
-  SectionHeaderEntry operator [](int index) => _entries[index];
-
   void writeToStringBuffer(StringBuffer buffer) {
-    for (var i = 0; i < length; i++) {
+    for (var i = 0; i < entries.length; i++) {
       if (i != 0) buffer..writeln()..writeln();
       buffer
         ..write('Entry ')
         ..write(i)
         ..writeln(':');
-      _entries[i].writeToStringBuffer(buffer);
+      entries[i].writeToStringBuffer(buffer);
     }
   }
 
@@ -524,27 +523,39 @@
   }
 }
 
+/// A section in an ELF file.
+///
+/// Some sections correspond to segments from the [ProgramHeader] and contain
+/// the information that will be loaded into memory for that segment, whereas
+/// others include information, like debugging sections, that are not loaded
+/// at runtime.
+///
+/// Only some sections are currently parsed by the  ELF reader; most are left
+/// unparsed as they are not needed for DWARF address translation.
 class Section {
-  final Reader reader;
   final SectionHeaderEntry headerEntry;
 
-  Section(this.headerEntry, this.reader);
+  Section._(this.headerEntry);
 
-  factory Section.fromEntryAndReader(SectionHeaderEntry entry, Reader reader) {
+  static Section fromReader(Reader reader, SectionHeaderEntry entry) {
     switch (entry.type) {
       case SectionHeaderEntry._SHT_STRTAB:
-        return StringTable(entry, reader);
+        return StringTable.fromReader(reader, entry);
       case SectionHeaderEntry._SHT_SYMTAB:
-        return SymbolTable(entry, reader);
+        return SymbolTable.fromReader(reader, entry);
       case SectionHeaderEntry._SHT_DYNSYM:
-        return SymbolTable(entry, reader);
+        return SymbolTable.fromReader(reader, entry);
       default:
-        return Section(entry, reader);
+        return Section._(entry);
     }
   }
 
+  int get offset => headerEntry.offset;
   int get virtualAddress => headerEntry.addr;
-  int get length => reader.bdata.lengthInBytes;
+  int get length => headerEntry.size;
+
+  // Convenience function for preparing a reader to read a particular section.
+  Reader refocusedCopy(Reader reader) => reader.refocusedCopy(offset, length);
 
   void writeToStringBuffer(StringBuffer buffer) {
     buffer
@@ -557,19 +568,24 @@
 
   @override
   String toString() {
-    StringBuffer buffer;
+    final buffer = StringBuffer();
     writeToStringBuffer(buffer);
     return buffer.toString();
   }
 }
 
+/// A map from table offsets to strings, used to store names of ELF objects.
 class StringTable extends Section {
   final _entries;
 
-  StringTable(SectionHeaderEntry entry, Reader reader)
-      : _entries = Map<int, String>.fromEntries(
-            reader.readRepeated((r) => r.readNullTerminatedString())),
-        super(entry, reader);
+  StringTable._(entry, this._entries) : super._(entry);
+
+  static StringTable fromReader(Reader reader, SectionHeaderEntry entry) {
+    final sectionReader = reader.refocusedCopy(entry.offset, entry.size);
+    final entries = Map.fromEntries(sectionReader
+        .readRepeatedWithOffsets((r) => r.readNullTerminatedString()));
+    return StringTable._(entry, entries);
+  }
 
   String operator [](int index) => _entries[index];
   bool containsKey(int index) => _entries.containsKey(index);
@@ -608,6 +624,7 @@
   STV_PROTECTED,
 }
 
+/// A symbol in an ELF file, which names a portion of the virtual address space.
 class Symbol {
   final int nameIndex;
   final int info;
@@ -699,16 +716,20 @@
   }
 }
 
+/// A table of (static or dynamic) [Symbol]s.
 class SymbolTable extends Section {
   final List<Symbol> _entries;
-  final _nameCache = Map<String, Symbol>();
+  final Map<String, Symbol> _nameCache;
 
-  SymbolTable(SectionHeaderEntry entry, Reader reader)
-      : _entries = reader
-            .readRepeated(Symbol.fromReader)
-            .map((kv) => kv.value)
-            .toList(),
-        super(entry, reader);
+  SymbolTable._(SectionHeaderEntry entry, this._entries)
+      : _nameCache = {},
+        super._(entry);
+
+  static SymbolTable fromReader(Reader reader, SectionHeaderEntry entry) {
+    final sectionReader = reader.refocusedCopy(entry.offset, entry.size);
+    final entries = sectionReader.readRepeated(Symbol.fromReader).toList();
+    return SymbolTable._(entry, entries);
+  }
 
   void _cacheNames(StringTable stringTable) {
     _nameCache.clear();
@@ -719,6 +740,7 @@
   }
 
   Iterable<String> get keys => _nameCache.keys;
+  Iterable<Symbol> get values => _nameCache.values;
   Symbol operator [](String name) => _nameCache[name];
   bool containsKey(String name) => _nameCache.containsKey(name);
 
@@ -736,23 +758,16 @@
   }
 }
 
+/// Information parsed from an Executable and Linking Format (ELF) file.
 class Elf {
-  ElfHeader _header;
-  ProgramHeader _programHeader;
-  SectionHeader _sectionHeader;
-  Map<SectionHeaderEntry, Section> _sections;
+  final ElfHeader _header;
+  final ProgramHeader _programHeader;
+  final SectionHeader _sectionHeader;
+  final Map<SectionHeaderEntry, Section> _sections;
+  final Map<String, Set<Section>> _sectionsByName;
 
-  Elf._(this._header, this._programHeader, this._sectionHeader, this._sections);
-
-  /// Creates an [Elf] from the data pointed to by [reader].
-  ///
-  /// Returns null if the file does not start with the ELF magic number.
-  static Elf fromReader(Reader reader) {
-    final start = reader.offset;
-    if (!ElfHeader.startsWithMagicNumber(reader)) return null;
-    reader.seek(start, absolute: true);
-    return Elf._read(reader);
-  }
+  Elf._(this._header, this._programHeader, this._sectionHeader, this._sections,
+      this._sectionsByName);
 
   /// Creates an [Elf] from [bytes].
   ///
@@ -765,76 +780,73 @@
   /// Returns null if the file does not start with the ELF magic number.
   static Elf fromFile(String path) => Elf.fromReader(Reader.fromFile(path));
 
+  Iterable<Section> namedSections(String name) => _sectionsByName[name];
+
   /// Lookup of a dynamic symbol by name.
   ///
   /// Returns -1 if there is no dynamic symbol that matches [name].
   Symbol dynamicSymbolFor(String name) {
     for (final SymbolTable dynsym in namedSections(".dynsym")) {
-      if (dynsym.containsKey(name)) {
-        return dynsym[name];
-      }
+      if (dynsym.containsKey(name)) return dynsym[name];
     }
     return null;
   }
 
-  /// The [Section]s whose names match [name].
-  Iterable<Section> namedSections(String name) {
-    return _sections.keys
-        .where((entry) => entry.name == name)
-        .map((entry) => _sections[entry]);
-  }
-
   /// Reverse lookup of the static symbol that contains the given virtual
   /// address. Returns null if no static symbol matching the address is found.
   Symbol staticSymbolAt(int address) {
     for (final SymbolTable table in namedSections('.symtab')) {
-      for (final name in table.keys) {
-        final symbol = table[name];
-        if (symbol.value <= address && address < (symbol.value + symbol.size)) {
-          return symbol;
-        }
+      for (final symbol in table.values) {
+        final start = symbol.value;
+        final end = start + symbol.size;
+        if (start <= address && address < end) return symbol;
       }
     }
     return null;
   }
 
-  static Elf _read(Reader startingReader) {
-    final header = ElfHeader.fromReader(startingReader.copy());
-    // Now use the word size and endianness information from the header.
-    final reader = Reader.fromTypedData(startingReader.bdata,
-        wordSize: header.wordSize, endian: header.endian);
-    final programHeader = ProgramHeader.fromReader(
-        reader.refocus(header.programHeaderOffset, header.programHeaderSize),
-        entrySize: header.programHeaderEntrySize,
-        entryCount: header.programHeaderCount);
-    final sectionHeader = SectionHeader.fromReader(
-        reader.refocus(header.sectionHeaderOffset, header.sectionHeaderSize),
-        entrySize: header.sectionHeaderEntrySize,
-        entryCount: header.sectionHeaderCount,
-        stringsIndex: header.sectionHeaderStringsIndex);
+  /// Creates an [Elf] from the data pointed to by [reader].
+  ///
+  /// After succesful completion, the [endian] and [wordSize] fields of the
+  /// reader are set to match the values read from the ELF header. The position
+  /// of the reader will be unchanged.
+  ///
+  /// Returns null if the file does not start with the ELF magic number.
+  static Elf fromReader(Reader elfReader) {
+    // ELF files contain absolute offsets from the start of the file, so
+    // make sure we have a reader that a) makes no assumptions about the
+    // endianness or word size, since we'll read those in the header and b)
+    // has an internal offset of 0 so absolute offsets can be used directly.
+    final reader = Reader.fromTypedData(ByteData.sublistView(
+        elfReader.bdata, elfReader.bdata.offsetInBytes + elfReader.offset));
+    final header = ElfHeader.fromReader(reader);
+    // Only happens if the file didn't start with the expected magic number.
+    if (header == null) return null;
+    // At this point, the endianness and wordSize should have been set
+    // during ElfHeader.fromReader.
+    assert(reader.endian != null && reader.wordSize != null);
+    final programHeader = ProgramHeader.fromReader(reader, header);
+    final sectionHeader = SectionHeader.fromReader(reader, header);
     final sections = <SectionHeaderEntry, Section>{};
-    for (var i = 0; i < sectionHeader.length; i++) {
-      final entry = sectionHeader[i];
-      if (i == header.sectionHeaderStringsIndex) {
-        sections[entry] = sectionHeader.nameTable;
-        continue;
-      }
-      sections[entry] = Section.fromEntryAndReader(
-          entry, reader.refocus(entry.offset, entry.size));
+    for (var i = 0; i < sectionHeader.entries.length; i++) {
+      final entry = sectionHeader.entries[i];
+      sections[entry] = Section.fromReader(reader, entry);
+    }
+    // Now set up the by-name section table and cache the names in the section
+    // header entries.
+    final StringTable sectionHeaderStringTable =
+        sections[sectionHeader.entries[header.sectionHeaderStringsIndex]];
+    final sectionsByName = <String, Set<Section>>{};
+    for (final entry in sectionHeader.entries) {
+      entry.setName(sectionHeaderStringTable);
+      sectionsByName.putIfAbsent(entry.name, () => {}).add(sections[entry]);
     }
     void _cacheSymbolNames(String stringTableTag, String symbolTableTag) {
-      final stringTables = <SectionHeaderEntry, StringTable>{};
-      final symbolTables = <SymbolTable>[];
-      for (final entry in sections.keys) {
-        if (entry.name == stringTableTag) {
-          stringTables[entry] = sections[entry];
-        } else if (entry.name == symbolTableTag) {
-          symbolTables.add(sections[entry]);
-        }
-      }
-      for (final symbolTable in symbolTables) {
+      final stringTables = Map.fromEntries(sectionsByName[stringTableTag]
+          .map((s) => MapEntry(s.headerEntry, s)));
+      for (final SymbolTable symbolTable in sectionsByName[symbolTableTag]) {
         final link = symbolTable.headerEntry.link;
-        final entry = sectionHeader[link];
+        final entry = sectionHeader.entries[link];
         if (!stringTables.containsKey(entry)) {
           throw FormatException(
               "String table not found at section header entry ${link}");
@@ -845,7 +857,11 @@
 
     _cacheSymbolNames('.strtab', '.symtab');
     _cacheSymbolNames('.dynstr', '.dynsym');
-    return Elf._(header, programHeader, sectionHeader, sections);
+    // Set the wordSize and endian of the original reader before returning.
+    elfReader.wordSize = reader.wordSize;
+    elfReader.endian = reader.endian;
+    return Elf._(
+        header, programHeader, sectionHeader, sections, sectionsByName);
   }
 
   void writeToStringBuffer(StringBuffer buffer) {
@@ -878,7 +894,7 @@
       ..writeln('                 Section information')
       ..writeln('-----------------------------------------------------')
       ..writeln();
-    for (final entry in _sections.keys) {
+    for (final entry in _sectionHeader.entries) {
       _sections[entry].writeToStringBuffer(buffer);
       buffer.writeln();
     }
diff --git a/pkg/native_stack_traces/lib/src/reader.dart b/pkg/native_stack_traces/lib/src/reader.dart
index 8f6b637..21f6297 100644
--- a/pkg/native_stack_traces/lib/src/reader.dart
+++ b/pkg/native_stack_traces/lib/src/reader.dart
@@ -12,8 +12,10 @@
 
 class Reader {
   final ByteData bdata;
-  final Endian endian;
-  final int wordSize;
+  // These are mutable so we can update them, in case the endianness and
+  // wordSize are read using the reader (e.g., ELF files).
+  Endian endian;
+  int wordSize;
 
   int _offset = 0;
 
@@ -24,25 +26,10 @@
             ByteData.view(data.buffer, data.offsetInBytes, data.lengthInBytes);
 
   Reader.fromFile(String path, {this.wordSize, this.endian})
-      // TODO(sstrickl): Once Dart > 2.7.1 has been released, rewrite
-      // ByteData.view(<x>.buffer) => ByteData.sublistView(<x>).
-      : bdata = ByteData.view(File(path).readAsBytesSync().buffer);
+      : bdata = ByteData.sublistView(File(path).readAsBytesSync());
 
-  Reader copy() =>
-      Reader.fromTypedData(bdata, wordSize: wordSize, endian: endian);
-
-  Reader shrink(int offset, [int size = -1]) {
-    if (size < 0) size = bdata.lengthInBytes - offset;
-    assert(offset >= 0 && offset < bdata.lengthInBytes);
-    assert(size >= 0 && (offset + size) <= bdata.lengthInBytes);
-    return Reader.fromTypedData(
-        ByteData.view(bdata.buffer, bdata.offsetInBytes + offset, size),
-        wordSize: wordSize,
-        endian: endian);
-  }
-
-  Reader refocus(int pos, [int size = -1]) {
-    if (size < 0) size = bdata.lengthInBytes - pos;
+  /// Returns a reader focused on a different portion of the underlying buffer.
+  Reader refocusedCopy(int pos, int size) {
     assert(pos >= 0 && pos < bdata.buffer.lengthInBytes);
     assert(size >= 0 && (pos + size) <= bdata.buffer.lengthInBytes);
     return Reader.fromTypedData(ByteData.view(bdata.buffer, pos, size),
@@ -60,37 +47,33 @@
     _offset = newOffset;
   }
 
-  void reset() {
-    seek(0, absolute: true);
-  }
-
   int readBytes(int size, {bool signed = false}) {
-    assert(_offset + size < length);
-    int ret;
+    if (_offset + size > length) {
+      throw ArgumentError("attempt to read ${size} bytes with only "
+          "${length - _offset} bytes remaining in the reader");
+    }
+    final start = _offset;
+    _offset += size;
     switch (size) {
       case 1:
-        ret = signed ? bdata.getInt8(_offset) : bdata.getUint8(_offset);
-        break;
+        return signed ? bdata.getInt8(start) : bdata.getUint8(start);
       case 2:
-        ret = signed
-            ? bdata.getInt16(_offset, endian)
-            : bdata.getUint16(_offset, endian);
-        break;
+        return signed
+            ? bdata.getInt16(start, endian)
+            : bdata.getUint16(start, endian);
       case 4:
-        ret = signed
-            ? bdata.getInt32(_offset, endian)
-            : bdata.getUint32(_offset, endian);
+        return signed
+            ? bdata.getInt32(start, endian)
+            : bdata.getUint32(start, endian);
         break;
       case 8:
-        ret = signed
-            ? bdata.getInt64(_offset, endian)
-            : bdata.getUint64(_offset, endian);
-        break;
+        return signed
+            ? bdata.getInt64(start, endian)
+            : bdata.getUint64(start, endian);
       default:
+        _offset -= size;
         throw ArgumentError("invalid request to read $size bytes");
     }
-    _offset += size;
-    return ret;
   }
 
   int readByte({bool signed = false}) => readBytes(1, signed: signed);
@@ -123,13 +106,30 @@
     return ret;
   }
 
-  Iterable<MapEntry<int, S>> readRepeated<S>(
-      S Function(Reader) callback) sync* {
+  /// Repeatedly calls [callback] with this reader to retrieve items.
+  ///
+  /// The key of the returned [MapEntry]s are the offsets of the items. If
+  /// absolute is false, the offsets are from the reader position when
+  /// [readRepeated] was invoked, otherwise they are absolute offsets from
+  /// the start of the reader.
+  ///
+  /// Stops either when the reader is empty or when a null item is returned
+  /// from the callback.
+  Iterable<MapEntry<int, S>> readRepeatedWithOffsets<S>(
+      S Function(Reader) callback,
+      {bool absolute = false}) sync* {
+    final start = offset;
     while (!done) {
-      yield MapEntry<int, S>(offset, callback(this));
+      final itemStart = offset;
+      final item = callback(this);
+      if (item == null) break;
+      yield MapEntry(absolute ? itemStart : itemStart - start, item);
     }
   }
 
+  Iterable<S> readRepeated<S>(S Function(Reader) callback) =>
+      readRepeatedWithOffsets(callback).map((kv) => kv.value);
+
   void writeCurrentReaderPosition(StringBuffer buffer,
       {int maxSize = 0, int bytesPerLine = 16}) {
     var baseData = ByteData.view(bdata.buffer, 0, bdata.buffer.lengthInBytes);
@@ -159,20 +159,28 @@
   String toString() {
     final buffer = StringBuffer();
     buffer
+      ..write("Word size: ")
+      ..write(wordSize)
+      ..writeln();
+    buffer
+      ..write("Endianness: ")
+      ..write(endian)
+      ..writeln();
+    buffer
       ..write("Start:  0x")
-      ..write(paddedHex(start, wordSize))
+      ..write(paddedHex(start, wordSize ?? 0))
       ..write(" (")
       ..write(start)
       ..writeln(")");
     buffer
       ..write("Offset: 0x")
-      ..write(paddedHex(offset, wordSize))
+      ..write(paddedHex(offset, wordSize ?? 0))
       ..write(" (")
       ..write(offset)
       ..writeln(")");
     buffer
       ..write("Length: 0x")
-      ..write(paddedHex(length, wordSize))
+      ..write(paddedHex(length, wordSize ?? 0))
       ..write(" (")
       ..write(length)
       ..writeln(")");
diff --git a/pkg/native_stack_traces/pubspec.yaml b/pkg/native_stack_traces/pubspec.yaml
index ad15e37..c7f8f15 100644
--- a/pkg/native_stack_traces/pubspec.yaml
+++ b/pkg/native_stack_traces/pubspec.yaml
@@ -1,6 +1,6 @@
 name: native_stack_traces
 description: Utilities for working with non-symbolic stack traces.
-version: 0.3.1
+version: 0.3.4
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/native_stack_traces
 
diff --git a/pkg/nnbd_migration/.gitignore b/pkg/nnbd_migration/.gitignore
new file mode 100644
index 0000000..7138b41
--- /dev/null
+++ b/pkg/nnbd_migration/.gitignore
@@ -0,0 +1,3 @@
+lib/src/front_end/resources/*.js.deps
+lib/src/front_end/resources/*.js.map
+lib/src/front_end/resources/migration.js
diff --git a/pkg/nnbd_migration/bin/migrate.dart b/pkg/nnbd_migration/bin/migrate.dart
new file mode 100644
index 0000000..1b87fa3
--- /dev/null
+++ b/pkg/nnbd_migration/bin/migrate.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/migration_cli.dart';
+
+main(List<String> args) async {
+  var cli = MigrationCli(binaryName: 'nnbd_migration');
+  await cli.run(args);
+  exit(cli.exitCode ?? 0);
+}
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/dartfix_listener_interface.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/dartfix_listener_interface.dart
new file mode 100644
index 0000000..c2505a2
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/dartfix_listener_interface.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
+
+abstract class DartFixListenerInterface {
+  DriverProvider get server;
+
+  SourceChange get sourceChange;
+
+  /// Add the given [detail] to the list of details to be returned to the
+  /// client.
+  void addDetail(String detail);
+
+  /// Record an edit to be sent to the client.
+  ///
+  /// The associated suggestion should be separately added by calling
+  /// [addSuggestion].
+  void addEditWithoutSuggestion(Source source, SourceEdit edit);
+
+  /// Record a recommendation to be sent to the client.
+  void addRecommendation(String description, [Location location]);
+
+  /// Record a source change to be sent to the client.
+  void addSourceFileEdit(
+      String description, Location location, SourceFileEdit fileEdit);
+
+  /// Record a suggestion to be sent to the client.
+  ///
+  /// The associated edits should be separately added by calling
+  /// [addEditWithoutRecommendation].
+  void addSuggestion(String description, Location location);
+}
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/driver_provider.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/driver_provider.dart
new file mode 100644
index 0000000..2079378
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/driver_provider.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart';
+
+abstract class DriverProvider {
+  ResourceProvider get resourceProvider;
+
+  /// Return the appropriate analysis session for the file with the given
+  /// [path].
+  AnalysisSession getAnalysisSession(String path);
+}
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/http_preview_server.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/http_preview_server.dart
new file mode 100644
index 0000000..4a409a01
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/http_preview_server.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'package:nnbd_migration/src/preview/http_preview_server.dart'
+    show HttpPreviewServer;
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/instrumentation_listener.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/instrumentation_listener.dart
new file mode 100644
index 0000000..dc2785e
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/instrumentation_listener.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'package:nnbd_migration/src/front_end/instrumentation_listener.dart'
+    show InstrumentationListener;
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/migration_state.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/migration_state.dart
new file mode 100644
index 0000000..dabbeed
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/migration_state.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'package:nnbd_migration/src/front_end/migration_state.dart'
+    show MigrationState;
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/nnbd_migration.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/nnbd_migration.dart
new file mode 100644
index 0000000..e888dfc
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/nnbd_migration.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'package:nnbd_migration/nnbd_migration.dart'
+    show NullabilityMigration, NullabilityMigrationListener;
diff --git a/pkg/nnbd_migration/lib/fix_reason_target.dart b/pkg/nnbd_migration/lib/fix_reason_target.dart
new file mode 100644
index 0000000..d1c0caa
--- /dev/null
+++ b/pkg/nnbd_migration/lib/fix_reason_target.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+/// Data structure representing a part of a type.  When a fix has multiple
+/// reasons (due to a complex type having different nullabilities at different
+/// locations), this data structure allows us to tell which part of the type
+/// is associated with each reason.
+abstract class FixReasonTarget {
+  /// Fix reason target representing the full type, rather than a part of it.
+  static const FixReasonTarget root = const _FixReasonTarget_Root();
+
+  const FixReasonTarget._();
+
+  /// Gets a fix reason target representing the type's return type.
+  FixReasonTarget get returnType => _FixReasonTarget_ReturnType(this);
+
+  /// Returns a description of the fix reason target that's suitable for
+  /// appending to a description of a nullability trace.
+  ///
+  /// For example, `root.returnType.suffix` returns ` for return type`.  This
+  /// can be attached to a string like `nullability reason` to form
+  /// `nullability reason for return type`.
+  String get suffix => _describe('for');
+
+  /// Gets a fix reason target representing the type's yielded type.  This
+  /// represents the type argument of `Future` or `FutureOr`, or in the case
+  /// where `await` is applied to a non-future type, the type itself.
+  FixReasonTarget get yieldedType => _FixReasonTarget_YieldedType(this);
+
+  /// Gets a fix reason target representing one of the type's named parameters.
+  FixReasonTarget namedParameter(String name) =>
+      _FixReasonTarget_NamedParameter(this, name);
+
+  /// Gets a fix reason target representing one of the type's positional
+  /// parameters.
+  FixReasonTarget positionalParameter(int i) =>
+      _FixReasonTarget_PositionalParameter(this, i);
+
+  /// Gets a fix reason target representing one of the type's type arguments.
+  FixReasonTarget typeArgument(int i) => _FixReasonTarget_TypeArgument(this, i);
+
+  String _describe(String preposition);
+}
+
+/// Fix reason target representing a named parameter of a function type.
+class _FixReasonTarget_NamedParameter extends _FixReasonTarget_Part {
+  final String name;
+
+  _FixReasonTarget_NamedParameter(FixReasonTarget inner, this.name)
+      : super(inner);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash3(2, inner.hashCode, name.hashCode);
+
+  @override
+  bool operator ==(Object other) =>
+      other is _FixReasonTarget_NamedParameter &&
+      inner == other.inner &&
+      name == other.name;
+
+  @override
+  String _describe(String preposition) =>
+      ' $preposition parameter $name${inner._describe('of')}';
+}
+
+/// Fix reason target representing a type that forms part of a larger type (e.g.
+/// the `int` part of `List<int>`).
+abstract class _FixReasonTarget_Part extends FixReasonTarget {
+  final FixReasonTarget inner;
+
+  _FixReasonTarget_Part(this.inner) : super._();
+}
+
+/// Fix reason target representing a positional parameter of a function type.
+class _FixReasonTarget_PositionalParameter extends _FixReasonTarget_Part {
+  final int index;
+
+  _FixReasonTarget_PositionalParameter(FixReasonTarget inner, this.index)
+      : super(inner);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash3(1, inner.hashCode, index);
+
+  @override
+  bool operator ==(Object other) =>
+      other is _FixReasonTarget_PositionalParameter &&
+      inner == other.inner &&
+      index == other.index;
+
+  @override
+  String _describe(String preposition) =>
+      ' $preposition parameter $index${inner._describe('of')}';
+}
+
+/// Fix reason target representing the return type of a function type.
+class _FixReasonTarget_ReturnType extends _FixReasonTarget_Part {
+  _FixReasonTarget_ReturnType(FixReasonTarget inner) : super(inner);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash2(3, inner.hashCode);
+
+  @override
+  bool operator ==(Object other) =>
+      other is _FixReasonTarget_ReturnType && inner == other.inner;
+
+  @override
+  String _describe(String preposition) =>
+      ' $preposition return type${inner._describe('of')}';
+}
+
+/// Fix reason target representing the root of the type in question.
+class _FixReasonTarget_Root extends FixReasonTarget {
+  const _FixReasonTarget_Root() : super._();
+
+  @override
+  int get hashCode => 0;
+
+  @override
+  bool operator ==(Object other) => other is _FixReasonTarget_Root;
+
+  @override
+  String _describe(String preposition) => '';
+}
+
+/// Fix reason target representing a type argument of an interface type.
+class _FixReasonTarget_TypeArgument extends _FixReasonTarget_Part {
+  final int index;
+
+  _FixReasonTarget_TypeArgument(FixReasonTarget inner, this.index)
+      : super(inner);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash3(5, inner.hashCode, index);
+
+  @override
+  bool operator ==(Object other) =>
+      other is _FixReasonTarget_TypeArgument &&
+      inner == other.inner &&
+      index == other.index;
+
+  @override
+  String _describe(String preposition) =>
+      ' $preposition type argument $index${inner._describe('of')}';
+}
+
+/// Fix reason target representing the type argument of `Future` or `FutureOr`,
+/// or in the case where `await` is applied to a non-future type, the type
+/// itself.
+///
+/// This allows the migration tool to describe a type correspondence that exists
+/// in a subtype check involving `FutureOr`, for example if the user tries to
+/// assign `List<int?>` to `FutureOr<List<int*>>`, then the migration tool
+/// determines that it needs to change `*` into `?`.  To make this determination
+/// it has to form a correspondence between the type argument of the source type
+/// and the type argument of the type argument of the destination type.  To
+/// explain to the user which part of the two types is involved in the
+/// correspondence, we need an ambiguous way of referring to either "type
+/// argument of type argument of" or simply "type argument".  The solution is to
+/// describe the fix reason target as "type argument of yielded type".
+class _FixReasonTarget_YieldedType extends _FixReasonTarget_Part {
+  _FixReasonTarget_YieldedType(FixReasonTarget inner) : super(inner);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash2(4, inner.hashCode);
+
+  @override
+  bool operator ==(Object other) =>
+      other is _FixReasonTarget_YieldedType && inner == other.inner;
+
+  @override
+  String _describe(String preposition) =>
+      ' $preposition yielded type${inner._describe('from')}';
+}
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 8689967..e8a6404 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -17,22 +17,25 @@
 
   final int column;
 
+  final int offset;
+
   /// Name of the enclosing function, or `null` if not known.
   String function;
 
-  CodeReference(this.path, this.line, this.column, this.function);
+  CodeReference(this.path, this.offset, this.line, this.column, this.function);
 
   /// Creates a [CodeReference] pointing to the given [node].
   factory CodeReference.fromAstNode(AstNode node) {
     var compilationUnit = node.thisOrAncestorOfType<CompilationUnit>();
     var source = compilationUnit.declaredElement.source;
     var location = compilationUnit.lineInfo.getLocation(node.offset);
-    return CodeReference(source.fullName, location.lineNumber,
+    return CodeReference(source.fullName, node.offset, location.lineNumber,
         location.columnNumber, _computeEnclosingName(node));
   }
 
   CodeReference.fromJson(dynamic json)
       : path = json['path'] as String,
+        offset = json['offset'] as int,
         line = json['line'] as int,
         column = json['col'] as int,
         function = json['function'] as String;
@@ -50,6 +53,7 @@
   Map<String, Object> toJson() {
     return {
       'path': path,
+      'offset': offset,
       'line': line,
       'col': column,
       if (function != null) 'function': function
@@ -218,7 +222,10 @@
 enum EdgeOriginKind {
   alreadyMigratedType,
   alwaysNullableType,
+  argumentErrorCheckNotNull,
   compoundAssignment,
+  // See [DummyOrigin].
+  dummy,
   dynamicAssignment,
   enumValue,
   expressionChecks,
@@ -235,8 +242,8 @@
   instantiateToBounds,
   isCheckComponentType,
   isCheckMainType,
-  literal,
   listLengthConstructor,
+  literal,
   namedParameterNotSupplied,
   nonNullableBoolType,
   nonNullableObjectSuperclass,
@@ -245,6 +252,7 @@
   nullabilityComment,
   optionalFormalParameter,
   parameterInheritance,
+  quiverCheckNotNull,
   returnTypeInheritance,
   stackTraceTypeOrigin,
   thisOrSuper,
diff --git a/pkg/nnbd_migration/lib/isolate_server.dart b/pkg/nnbd_migration/lib/isolate_server.dart
new file mode 100644
index 0000000..c4ecfa2
--- /dev/null
+++ b/pkg/nnbd_migration/lib/isolate_server.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library implements [ServerBase], except unlike analysis_server_client's
+/// `Server`, [Server] runs the analysis server in an isolate.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:isolate';
+
+import 'package:analysis_server/starter.dart';
+import 'package:analysis_server_client/listener/server_listener.dart';
+import 'package:analysis_server_client/src/server_base.dart';
+import 'package:analysis_server_client/protocol.dart';
+import 'package:stream_channel/isolate_channel.dart';
+
+/// Wrap server arguments and communication port into a single parameter
+/// for [Isolate.spawn].
+class _IsolateParameters {
+  final List<String> arguments;
+  final SendPort sendPort;
+
+  _IsolateParameters(this.arguments, this.sendPort);
+}
+
+/// Manage an analysis_server launched in an isolate.
+class Server extends ServerBase {
+  /// Server isolate object, or `null` if server hasn't been started yet
+  /// or if the server has already been stopped.
+  Isolate _isolate;
+
+  /// The [ReceivePort] data subscription via an [IsolateChannel], or `null`
+  /// if either [listenToOutput] has not been called or [stop] has been called.
+  StreamSubscription<String> _receiveSubscription;
+
+  /// Construct a Server.
+  ///
+  /// [isolate] and [isolateChannel] are testing-only parameters, allowing
+  /// you to bypass start().
+  Server(
+      {ServerListener listener,
+      Isolate isolate,
+      IsolateChannel isolateChannel,
+      bool stdioPassthrough = false})
+      : _isolate = isolate,
+        _isolateChannel = isolateChannel,
+        super(listener: listener, stdioPassthrough: stdioPassthrough);
+
+  /// Completes when the [_isolate] has exited.
+  Completer isolateExited = Completer();
+
+  /// The [IsolateChannel] by which this class communicates with the [_isolate].
+  IsolateChannel _isolateChannel;
+
+  /// Force kill the server.  The returned future completes when the isolate
+  /// is dead.
+  Future<void> kill({String reason = 'none'}) {
+    listener?.killingServerProcess(reason);
+    final isolate = _isolate;
+    final isolateExitedOriginal = isolateExited;
+    _isolate = null;
+    isolateExited = null;
+    isolate.kill(priority: Isolate.immediate);
+    return isolateExitedOriginal.future;
+  }
+
+  /// Start listening to output from the server,
+  /// and deliver notifications to [notificationProcessor].
+  void listenToOutput({NotificationProcessor notificationProcessor}) {
+    _receiveSubscription = _isolateChannel.stream
+        .transform(utf8.decoder)
+        .transform(LineSplitter())
+        .listen((line) => outputProcessor(line, notificationProcessor));
+  }
+
+  /// Send a command to the server. An 'id' will be automatically assigned.
+  /// The returned [Future] will be completed when the server acknowledges
+  /// the command with a response.
+  /// If the server acknowledges the command with a 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) =>
+      sendCommandWith(method, params, _isolateChannel.sink.add);
+
+  /// Start the server in a new [Isolate].
+  Future start({
+    String clientId,
+    String clientVersion,
+    int diagnosticPort,
+    String instrumentationLogFile,
+    String sdkPath,
+    bool suppressAnalytics = true,
+    bool useAnalysisHighlight2 = false,
+  }) async {
+    if (_isolate != null) {
+      throw Exception('Isolate already started');
+    }
+
+    // Even though this is an isolate, most of the analysis server code
+    // can't tell the difference.  So we construct "command line" arguments
+    // just the same as analysis_server_client.
+    List<String> arguments = [];
+    arguments.addAll(getServerArguments(
+        clientId: clientId,
+        clientVersion: clientVersion,
+        suppressAnalytics: suppressAnalytics,
+        diagnosticPort: diagnosticPort,
+        instrumentationLogFile: instrumentationLogFile,
+        sdkPath: sdkPath,
+        useAnalysisHighlight2: useAnalysisHighlight2));
+
+    listener?.startingServer('((isolate))', arguments);
+    ReceivePort receivePort = ReceivePort();
+    ReceivePort onExitReceivePort = ReceivePort();
+    ReceivePort onErrorReceivePort = ReceivePort();
+    onExitReceivePort.listen((_) {
+      isolateExited.complete(0);
+    });
+    onErrorReceivePort.listen((_) {
+      listener?.unexpectedStop(null);
+    });
+    _isolateChannel = IsolateChannel<List<int>>.connectReceive(receivePort);
+    _isolate = await Isolate.spawn(
+        _runIsolate, _IsolateParameters(arguments, receivePort.sendPort),
+        onExit: onExitReceivePort.sendPort);
+  }
+
+  /// This is the function passed to [Isolate.spawn] to actually begin
+  /// the server.
+  static void _runIsolate(_IsolateParameters parameters) {
+    ServerStarter starter = ServerStarter();
+    // TODO(jcollins-g): consider a refactor that does not require passing
+    // text arguments to start the server.
+    starter.start(parameters.arguments, parameters.sendPort);
+  }
+
+  /// Attempt to gracefully shutdown the server.
+  /// If that fails, then kill the isolate.
+  Future<void> stop({Duration timeLimit}) async {
+    timeLimit ??= const Duration(seconds: 5);
+    if (_isolate == null) {
+      // isolate already exited
+      return;
+    }
+    final future = send(SERVER_REQUEST_SHUTDOWN, null);
+    final isolate = _isolate;
+    _isolate = null;
+    await future
+        // fall through to wait for exit
+        .timeout(timeLimit, onTimeout: () {
+      return null;
+    }).whenComplete(() async {
+      await _receiveSubscription?.cancel();
+      _receiveSubscription = null;
+    });
+    return isolateExited.future.timeout(timeLimit, onTimeout: () {
+      listener?.killingServerProcess('server failed to exit');
+      isolate.kill(priority: Isolate.immediate);
+    });
+  }
+}
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
new file mode 100644
index 0000000..41c3f0f
--- /dev/null
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -0,0 +1,683 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/sdk.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    hide AnalysisError;
+import 'package:args/args.dart';
+import 'package:cli_util/cli_logging.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
+import 'package:path/path.dart' show Context;
+
+String _pluralize(int count, String single, {String multiple}) {
+  return count == 1 ? single : (multiple ?? '${single}s');
+}
+
+String _removePeriod(String value) {
+  return value.endsWith('.') ? value.substring(0, value.length - 1) : value;
+}
+
+/// Data structure recording command-line options for the migration tool that
+/// have been passed in by the client.
+@visibleForTesting
+class CommandLineOptions {
+  static const applyChangesFlag = 'apply-changes';
+  static const helpFlag = 'help';
+  static const ignoreErrorsFlag = 'ignore-errors';
+  static const previewPortOption = 'preview-port';
+  static const sdkPathOption = 'sdk-path';
+  static const verboseFlag = 'verbose';
+  static const webPreviewFlag = 'web-preview';
+
+  final bool applyChanges;
+
+  final String directory;
+
+  final bool ignoreErrors;
+
+  final int previewPort;
+
+  final String sdkPath;
+
+  final bool webPreview;
+
+  CommandLineOptions(
+      {@required this.applyChanges,
+      @required this.directory,
+      @required this.ignoreErrors,
+      @required this.previewPort,
+      @required this.sdkPath,
+      @required this.webPreview});
+}
+
+/// Command-line API for the migration tool, with additional methods exposed for
+/// testing.
+class MigrationCli {
+  /// The name of the executable, for reporting in help messages.
+  final String binaryName;
+
+  /// The SDK path that should be used if none is provided by the user.  Used in
+  /// testing to install a mock SDK.
+  final String defaultSdkPathOverride;
+
+  /// Factory to create an appropriate Logger instance to give feedback to the
+  /// user.  Used in testing to allow user feedback messages to be tested.
+  final Logger Function(bool isVerbose) loggerFactory;
+
+  /// Resource provider that should be used to access the filesystem.  Used in
+  /// testing to redirect to an in-memory filesystem.
+  final ResourceProvider resourceProvider;
+
+  /// Logger instance we use to give feedback to the user.
+  Logger logger;
+
+  /// The result of parsing command-line options.
+  @visibleForTesting
+  /*late*/ CommandLineOptions options;
+
+  /// The exit code that should be used when the process terminates, or `null`
+  /// if there is still more work to do.
+  int exitCode;
+
+  final Map<String, List<AnalysisError>> fileErrors = {};
+
+  final Map<String, LineInfo> lineInfo = {};
+
+  MigrationCli(
+      {@required this.binaryName,
+      @visibleForTesting this.loggerFactory = _defaultLoggerFactory,
+      @visibleForTesting this.defaultSdkPathOverride,
+      @visibleForTesting ResourceProvider resourceProvider})
+      : logger = loggerFactory(false),
+        resourceProvider =
+            resourceProvider ?? PhysicalResourceProvider.INSTANCE;
+
+  Ansi get ansi => logger.ansi;
+
+  Context get pathContext => resourceProvider.pathContext;
+
+  /// Blocks until an interrupt signal (control-C) is received.  Tests may
+  /// override this method to simulate control-C.
+  @visibleForTesting
+  Future<void> blockUntilSignalInterrupt() {
+    Stream<ProcessSignal> stream = ProcessSignal.sigint.watch();
+    return stream.first;
+  }
+
+  /// Parses and validates command-line arguments, and stores the results in
+  /// [options].
+  ///
+  /// If no additional work should be done (e.g. because the user asked for
+  /// help, or supplied a bad option), a nonzero value is stored in [exitCode].
+  @visibleForTesting
+  void parseCommandLineArgs(List<String> args) {
+    try {
+      var argResults = _createParser().parse(args);
+      var isVerbose = argResults[CommandLineOptions.verboseFlag] as bool;
+      if (argResults[CommandLineOptions.helpFlag] as bool) {
+        _showUsage(isVerbose);
+        exitCode = 0;
+        return;
+      }
+      var rest = argResults.rest;
+      String migratePath;
+      if (rest.isEmpty) {
+        migratePath = Directory.current.path;
+      } else if (rest.length > 1) {
+        throw _BadArgException('No more than one path may be specified.');
+      } else {
+        migratePath = rest[0];
+      }
+      var applyChanges =
+          argResults[CommandLineOptions.applyChangesFlag] as bool;
+      var previewPortRaw =
+          argResults[CommandLineOptions.previewPortOption] as String;
+      int previewPort;
+      try {
+        previewPort = previewPortRaw == null ? null : int.parse(previewPortRaw);
+      } on FormatException catch (_) {
+        throw _BadArgException(
+            'Invalid value for --${CommandLineOptions.previewPortOption}');
+      }
+      var webPreview = argResults[CommandLineOptions.webPreviewFlag] as bool;
+      if (applyChanges && webPreview) {
+        throw _BadArgException('--apply-changes requires --no-web-preview');
+      }
+      options = CommandLineOptions(
+          applyChanges: applyChanges,
+          directory: migratePath,
+          ignoreErrors: argResults[CommandLineOptions.ignoreErrorsFlag] as bool,
+          previewPort: previewPort,
+          sdkPath: argResults[CommandLineOptions.sdkPathOption] as String ??
+              defaultSdkPathOverride ??
+              getSdkPath(),
+          webPreview: webPreview);
+      if (isVerbose) {
+        logger = loggerFactory(true);
+      }
+    } on Object catch (exception) {
+      String message;
+      if (exception is FormatException) {
+        message = exception.message;
+      } else if (exception is _BadArgException) {
+        message = exception.message;
+      } else {
+        message =
+            'Exception occurred while parsing command-line options: $exception';
+      }
+      logger.stderr(message);
+      _showUsage(false);
+      exitCode = 1;
+      return;
+    }
+  }
+
+  /// Runs the full migration process.
+  void run(List<String> args) async {
+    parseCommandLineArgs(args);
+    if (exitCode != null) return;
+
+    // TODO(paulberry): if debugging, create instrumentation log
+
+    logger.stdout('Migrating ${options.directory}');
+    logger.stdout('');
+
+    List<String> previewUrls;
+    NonNullableFix nonNullableFix;
+    _DartFixListener dartFixListener;
+    await _withProgress(
+        '${ansi.emphasized('Generating migration suggestions')}', () async {
+      var contextCollection = AnalysisContextCollectionImpl(
+          includedPaths: [options.directory],
+          resourceProvider: resourceProvider,
+          sdkPath: options.sdkPath);
+      var context = contextCollection.contexts.single;
+      var fixCodeProcessor = _FixCodeProcessor(context, this);
+      dartFixListener = _DartFixListener(
+          _DriverProvider(resourceProvider, context.currentSession));
+      nonNullableFix = NonNullableFix(dartFixListener,
+          included: [options.directory],
+          preferredPort: options.previewPort,
+          enablePreview: options.webPreview);
+      fixCodeProcessor.registerCodeTask(nonNullableFix);
+      try {
+        await fixCodeProcessor.runFirstPhase();
+        _checkForErrors();
+      } on StateError catch (e) {
+        logger.stdout(e.toString());
+        exitCode = 1;
+      }
+      if (exitCode != null) return;
+      previewUrls = await fixCodeProcessor.runLaterPhases();
+    });
+    if (exitCode != null) return;
+
+    if (options.applyChanges) {
+      logger.stdout(ansi.emphasized('Applying changes:'));
+
+      var allEdits = dartFixListener.sourceChange.edits;
+      _applyMigrationSuggestions(allEdits);
+
+      logger.stdout('');
+      logger.stdout(
+          'Applied ${allEdits.length} ${_pluralize(allEdits.length, 'edit')}.');
+
+      // Note: do not open the web preview if apply-changes is specified, as we
+      // currently cannot tell the web preview to disable the "apply migration"
+      // button.
+      exitCode = 0;
+      return;
+    }
+
+    if (options.webPreview) {
+      String url = previewUrls.first;
+      assert(previewUrls.length <= 1,
+          'Got unexpected extra preview URLs from server');
+
+      logger.stdout(ansi.emphasized('View migration results:'));
+
+      // TODO(devoncarew): Open a browser automatically.
+      logger.stdout('''
+Visit:
+  
+  ${ansi.emphasized(url)}
+
+to see the migration results. Use the interactive web view to review, improve, or apply
+the results (alternatively, to apply the results without using the web preview, re-run
+the tool with --${CommandLineOptions.applyChangesFlag}).
+''');
+
+      logger.stdout('When finished with the preview, hit ctrl-c '
+          'to terminate this process.');
+
+      // Block until sigint (ctrl-c).
+      await blockUntilSignalInterrupt();
+      nonNullableFix.shutdownServer();
+    } else {
+      logger.stdout(ansi.emphasized('Summary of changes:'));
+
+      _displayChangeSummary(dartFixListener);
+
+      logger.stdout('');
+      logger.stdout('To apply these changes, re-run the tool with '
+          '--${CommandLineOptions.applyChangesFlag}.');
+    }
+    exitCode = 0;
+  }
+
+  /// Perform the indicated source edits to the given source, returning the
+  /// resulting transformed text.
+  String _applyEdits(SourceFileEdit sourceFileEdit, String source) {
+    List<SourceEdit> edits = _sortEdits(sourceFileEdit);
+    return SourceEdit.applySequence(source, edits);
+  }
+
+  void _applyMigrationSuggestions(List<SourceFileEdit> edits) {
+    // Apply the changes to disk.
+    for (SourceFileEdit sourceFileEdit in edits) {
+      String relPath =
+          pathContext.relative(sourceFileEdit.file, from: options.directory);
+      int count = sourceFileEdit.edits.length;
+      logger.stdout('  $relPath ($count ${_pluralize(count, 'change')})');
+
+      String source;
+      var file = resourceProvider.getFile(sourceFileEdit.file);
+      try {
+        source = file.readAsStringSync();
+      } catch (_) {}
+
+      if (source == null) {
+        logger.stdout('    Unable to retrieve source for file.');
+      } else {
+        source = _applyEdits(sourceFileEdit, source);
+
+        try {
+          file.writeAsStringSync(source);
+        } catch (e) {
+          logger.stdout('    Unable to write source for file: $e');
+        }
+      }
+    }
+  }
+
+  void _checkForErrors() {
+    if (fileErrors.isEmpty) {
+      logger.stdout('No analysis issues found.');
+    } else {
+      logger.stdout('');
+
+      int issueCount =
+          fileErrors.values.map((list) => list.length).reduce((a, b) => a + b);
+      logger.stdout(
+          '$issueCount analysis ${_pluralize(issueCount, 'issue')} found:');
+      List<AnalysisError> allErrors = fileErrors.values
+          .fold(<AnalysisError>[], (list, element) => list..addAll(element));
+      _displayIssues(logger, options.directory, allErrors, lineInfo);
+      var importErrorCount = allErrors.where(_isUriError).length;
+
+      logger.stdout('');
+      logger.stdout(
+          'Note: analysis errors will result in erroneous migration suggestions.');
+
+      if (options.ignoreErrors) {
+        logger.stdout('Continuing with migration suggestions due to the use of '
+            '--${CommandLineOptions.ignoreErrorsFlag}.');
+      } else {
+        // Fail with how to continue.
+        logger.stdout('');
+        if (importErrorCount != 0) {
+          logger.stdout(
+              'Unresolved URIs found.  Did you forget to run "pub get"?');
+          logger.stdout('');
+        }
+        logger.stdout(
+            'Please fix the analysis issues (or, force generation of migration '
+            'suggestions by re-running with '
+            '--${CommandLineOptions.ignoreErrorsFlag}).');
+        exitCode = 1;
+        return;
+      }
+    }
+  }
+
+  ArgParser _createParser({bool hide = true}) {
+    var parser = ArgParser();
+    parser.addFlag(CommandLineOptions.applyChangesFlag,
+        defaultsTo: false,
+        negatable: false,
+        help: 'Apply the proposed null safety changes to the files on disk.');
+    parser.addFlag(CommandLineOptions.helpFlag,
+        abbr: 'h',
+        help:
+            'Display this help message. Add --verbose to show hidden options.',
+        defaultsTo: false,
+        negatable: false);
+    parser.addFlag(
+      CommandLineOptions.ignoreErrorsFlag,
+      defaultsTo: false,
+      negatable: false,
+      help: 'Attempt to perform null safety analysis even if there are '
+          'analysis errors in the project.',
+    );
+    parser.addOption(CommandLineOptions.previewPortOption,
+        help:
+            'Run the preview server on the specified port.  If not specified, '
+            'dynamically allocate a port.');
+    parser.addOption(CommandLineOptions.sdkPathOption,
+        help: 'The path to the Dart SDK.', hide: hide);
+    parser.addFlag(CommandLineOptions.verboseFlag,
+        abbr: 'v',
+        defaultsTo: false,
+        help: 'Verbose output.',
+        negatable: false);
+    parser.addFlag(CommandLineOptions.webPreviewFlag,
+        defaultsTo: true,
+        negatable: true,
+        help: 'Show an interactive preview of the proposed null safety changes '
+            'in a browser window.\n'
+            'With --no-web-preview, the proposed changes are instead printed to '
+            'the console.');
+    return parser;
+  }
+
+  void _displayChangeSummary(_DartFixListener migrationResults) {
+    Map<String, List<_DartFixSuggestion>> fileSuggestions = {};
+    for (_DartFixSuggestion suggestion in migrationResults.suggestions) {
+      String file = suggestion.location.file;
+      fileSuggestions.putIfAbsent(file, () => <_DartFixSuggestion>[]);
+      fileSuggestions[file].add(suggestion);
+    }
+
+    // present a diff-like view
+    for (SourceFileEdit sourceFileEdit in migrationResults.sourceChange.edits) {
+      String file = sourceFileEdit.file;
+      String relPath = pathContext.relative(file, from: options.directory);
+      int count = sourceFileEdit.edits.length;
+
+      logger.stdout('');
+      logger.stdout('${ansi.emphasized(relPath)} '
+          '($count ${_pluralize(count, 'change')}):');
+
+      String source;
+      try {
+        source = resourceProvider.getFile(file).readAsStringSync();
+      } catch (_) {}
+
+      if (source == null) {
+        logger.stdout('  (unable to retrieve source for file)');
+      } else {
+        // TODO(paulberry): implement this
+        logger.stdout('  (diff view not yet functional)');
+      }
+    }
+  }
+
+  void _displayIssues(Logger logger, String directory,
+      List<AnalysisError> issues, Map<String, LineInfo> lineInfo) {
+    issues.sort((AnalysisError one, AnalysisError two) {
+      if (one.source != two.source) {
+        return one.source.fullName.compareTo(two.source.fullName);
+      }
+      return one.offset - two.offset;
+    });
+
+    _IssueRenderer renderer =
+        _IssueRenderer(logger, directory, pathContext, lineInfo);
+    for (AnalysisError issue in issues) {
+      renderer.render(issue);
+    }
+  }
+
+  bool _isUriError(AnalysisError error) =>
+      error.errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST;
+
+  void _showUsage(bool isVerbose) {
+    logger.stderr('Usage: $binaryName [options...] [<package directory>]');
+
+    logger.stderr('');
+    logger.stderr(_createParser(hide: !isVerbose).usage);
+    if (!isVerbose) {
+      logger.stderr('');
+      logger
+          .stderr('Run "$binaryName -h -v" for verbose help output, including '
+              'less commonly used options.');
+    }
+  }
+
+  List<SourceEdit> _sortEdits(SourceFileEdit sourceFileEdit) {
+    // Sort edits in reverse offset order.
+    List<SourceEdit> edits = sourceFileEdit.edits.toList();
+    edits.sort((a, b) {
+      return b.offset - a.offset;
+    });
+    return edits;
+  }
+
+  Future<void> _withProgress(String message, FutureOr<void> callback()) async {
+    var progress = logger.progress(message);
+    try {
+      await callback();
+      progress.finish(showTiming: true);
+    } finally {
+      progress.cancel();
+    }
+  }
+
+  static Logger _defaultLoggerFactory(bool isVerbose) {
+    var ansi = Ansi(Ansi.terminalSupportsAnsi);
+    if (isVerbose) {
+      return Logger.verbose(ansi: ansi);
+    } else {
+      return Logger.standard(ansi: ansi);
+    }
+  }
+}
+
+class _BadArgException implements Exception {
+  final String message;
+
+  _BadArgException(this.message);
+}
+
+class _DartFixListener implements DartFixListenerInterface {
+  @override
+  final DriverProvider server;
+
+  @override
+  final SourceChange sourceChange = SourceChange('null safety migration');
+
+  final List<_DartFixSuggestion> suggestions = [];
+
+  _DartFixListener(this.server);
+
+  @override
+  void addDetail(String detail) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void addEditWithoutSuggestion(Source source, SourceEdit edit) {
+    sourceChange.addEdit(source.fullName, -1, edit);
+  }
+
+  @override
+  void addRecommendation(String description, [Location location]) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void addSourceFileEdit(
+      String description, Location location, SourceFileEdit fileEdit) {
+    suggestions.add(_DartFixSuggestion(description, location: location));
+    for (var sourceEdit in fileEdit.edits) {
+      sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
+    }
+  }
+
+  @override
+  void addSuggestion(String description, Location location) {
+    suggestions.add(_DartFixSuggestion(description, location: location));
+  }
+}
+
+class _DartFixSuggestion {
+  final String description;
+
+  final Location location;
+
+  _DartFixSuggestion(this.description, {@required this.location});
+}
+
+class _DriverProvider implements DriverProvider {
+  @override
+  final ResourceProvider resourceProvider;
+
+  final AnalysisSession analysisSession;
+
+  _DriverProvider(this.resourceProvider, this.analysisSession);
+
+  @override
+  AnalysisSession getAnalysisSession(String path) => analysisSession;
+}
+
+class _FixCodeProcessor extends Object with FixCodeProcessor {
+  final AnalysisContext context;
+
+  final Set<String> pathsToProcess;
+
+  final MigrationCli _migrationCli;
+
+  _FixCodeProcessor(this.context, this._migrationCli)
+      : pathsToProcess = context.contextRoot
+            .analyzedFiles()
+            .where((s) => s.endsWith('.dart'))
+            .toSet();
+
+  /// Call the supplied [process] function to process each compilation unit.
+  Future processResources(
+      Future<void> Function(ResolvedUnitResult result) process) async {
+    var driver = context.currentSession;
+    var pathsProcessed = <String>{};
+    for (var path in pathsToProcess) {
+      if (pathsProcessed.contains(path)) continue;
+      switch (await driver.getSourceKind(path)) {
+        case SourceKind.PART:
+          // Parts will either be found in a library, below, or if the library
+          // isn't [isIncluded], will be picked up in the final loop.
+          continue;
+          break;
+        case SourceKind.LIBRARY:
+          var result = await driver.getResolvedLibrary(path);
+          if (result != null) {
+            for (var unit in result.units) {
+              if (pathsToProcess.contains(unit.path) &&
+                  !pathsProcessed.contains(unit.path)) {
+                await process(unit);
+                pathsProcessed.add(unit.path);
+              }
+            }
+          }
+          break;
+        default:
+          break;
+      }
+    }
+
+    for (var path in pathsToProcess.difference(pathsProcessed)) {
+      var result = await driver.getResolvedUnit(path);
+      if (result == null || result.unit == null) {
+        continue;
+      }
+      await process(result);
+    }
+  }
+
+  Future<void> runFirstPhase() async {
+    // Process package
+    await processPackage(context.contextRoot.root);
+
+    // Process each source file.
+    await processResources((ResolvedUnitResult result) async {
+      List<AnalysisError> errors = result.errors
+          .where((error) => error.severity == Severity.error)
+          .toList();
+      if (errors.isNotEmpty) {
+        _migrationCli.fileErrors[result.path] = errors;
+        _migrationCli.lineInfo[result.path] = result.lineInfo;
+      }
+      if (_migrationCli.options.ignoreErrors ||
+          _migrationCli.fileErrors.isEmpty) {
+        await processCodeTasks(0, result);
+      }
+    });
+  }
+
+  Future<List<String>> runLaterPhases() async {
+    for (var phase = 1; phase < numPhases; phase++) {
+      await processResources((ResolvedUnitResult result) async {
+        await processCodeTasks(phase, result);
+      });
+    }
+    await finishCodeTasks();
+
+    return nonNullableFixTask.previewUrls;
+  }
+}
+
+/// Given a Logger and an analysis issue, render the issue to the logger.
+class _IssueRenderer {
+  final Logger logger;
+  final String rootDirectory;
+  final Context pathContext;
+  final Map<String, LineInfo> lineInfo;
+
+  _IssueRenderer(
+      this.logger, this.rootDirectory, this.pathContext, this.lineInfo);
+
+  void render(AnalysisError issue) {
+    // severity • Message ... at foo/bar.dart:6:1 • (error_code)
+    var lineInfoForThisFile = lineInfo[issue.source.fullName];
+    var location = lineInfoForThisFile.getLocation(issue.offset);
+
+    final Ansi ansi = logger.ansi;
+
+    logger.stdout(
+      '  ${ansi.error(_severityToString(issue.severity))} • '
+      '${ansi.emphasized(_removePeriod(issue.message))} '
+      'at ${pathContext.relative(issue.source.fullName, from: rootDirectory)}'
+      ':${location.lineNumber}:'
+      '${location.columnNumber} '
+      '• (${issue.errorCode.name.toLowerCase()})',
+    );
+  }
+
+  String _severityToString(Severity severity) {
+    switch (severity) {
+      case Severity.error:
+        return 'error';
+      case Severity.warning:
+        return 'warning';
+      case Severity.info:
+        return 'info';
+    }
+    return '???';
+  }
+}
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 677c7fa..613c600 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -4,50 +4,127 @@
 
 import 'dart:convert';
 
-import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/src/nullability_migration_impl.dart';
 
+export 'package:nnbd_migration/src/utilities/hint_utils.dart' show HintComment;
+
 /// Description of fixes that might be performed by nullability migration.
 class NullabilityFixDescription {
-  /// An if-test or conditional expression needs to have its condition and
-  /// "then" branch discarded.
-  static const discardThen = const NullabilityFixDescription._(
-    appliedMessage:
-        'Discarded a condition which is always false, and the "then" branch '
-        'that follows',
-    kind: NullabilityFixKind.discardThen,
+  /// A variable declaration needs to be marked as "late".
+  static const addLate = const NullabilityFixDescription._(
+      appliedMessage: 'Added a late keyword', kind: NullabilityFixKind.addLate);
+
+  /// A variable declaration needs to be marked as "late" due to the presence of
+  /// a `/*late*/` hint.
+  static const addLateDueToHint = const NullabilityFixDescription._(
+      appliedMessage: 'Added a late keyword, due to a hint',
+      kind: NullabilityFixKind.addLateDueToHint);
+
+  /// A variable declaration needs to be marked as "late" due to being certainly
+  /// assigned in test setup.
+  static const addLateDueToTestSetup = const NullabilityFixDescription._(
+      appliedMessage: 'Added a late keyword, due to assignment in `setUp`',
+      kind: NullabilityFixKind.addLateDueToTestSetup);
+
+  /// An expression's value needs to be null-checked.
+  static const checkExpression = const NullabilityFixDescription._(
+    appliedMessage: 'Added a non-null assertion to nullable expression',
+    kind: NullabilityFixKind.checkExpression,
   );
 
+  /// An expression's value will be null-checked due to a hint.
+  static const checkExpressionDueToHint = const NullabilityFixDescription._(
+    appliedMessage: 'Accepted a null check hint',
+    kind: NullabilityFixKind.checkExpressionDueToHint,
+  );
+
+  /// A compound assignment's combiner operator returns a type that isn't
+  /// assignable to the LHS of the assignment.
+  static const compoundAssignmentHasBadCombinedType =
+      const NullabilityFixDescription._(
+    appliedMessage: 'Compound assignment has bad combined type',
+    kind: NullabilityFixKind.compoundAssignmentHasBadCombinedType,
+  );
+
+  /// A compound assignment's LHS has a nullable type.
+  static const compoundAssignmentHasNullableSource =
+      const NullabilityFixDescription._(
+    appliedMessage: 'Compound assignment has nullable source',
+    kind: NullabilityFixKind.compoundAssignmentHasNullableSource,
+  );
+
+  /// Informative message: a condition of an if-test or conditional expression
+  /// will always evaluate to `false` in strong checking mode.
+  static const conditionFalseInStrongMode = const NullabilityFixDescription._(
+      appliedMessage: 'Condition will always be false in strong checking mode',
+      kind: NullabilityFixKind.conditionFalseInStrongMode);
+
+  /// Informative message: a condition of an if-test or conditional expression
+  /// will always evaluate to `true` in strong checking mode.
+  static const conditionTrueInStrongMode = const NullabilityFixDescription._(
+      appliedMessage: 'Condition will always be true in strong checking mode',
+      kind: NullabilityFixKind.conditionTrueInStrongMode);
+
   /// An if-test or conditional expression needs to have its condition
   /// discarded.
   static const discardCondition = const NullabilityFixDescription._(
     appliedMessage: 'Discarded a condition which is always true',
-    kind: NullabilityFixKind.discardCondition,
+    kind: NullabilityFixKind.removeDeadCode,
   );
 
   /// An if-test or conditional expression needs to have its condition and
   /// "else" branch discarded.
   static const discardElse = const NullabilityFixDescription._(
     appliedMessage: 'Discarded an unreachable conditional else branch',
-    kind: NullabilityFixKind.discardElse,
+    kind: NullabilityFixKind.removeDeadCode,
+  );
+
+  /// An if-test or conditional expression needs to have its condition and
+  /// "then" branch discarded.
+  static const discardThen = const NullabilityFixDescription._(
+    appliedMessage:
+        'Discarded a condition which is always false, and the "then" branch '
+        'that follows',
+    kind: NullabilityFixKind.removeDeadCode,
   );
 
   /// An if-test needs to be discarded completely.
   static const discardIf = const NullabilityFixDescription._(
     appliedMessage: 'Discarded an if-test with no effect',
-    kind: NullabilityFixKind.discardIf,
+    kind: NullabilityFixKind.removeDeadCode,
   );
 
-  /// An expression's value needs to be null-checked.
-  static const checkExpression = const NullabilityFixDescription._(
-    appliedMessage: 'Added a non-null assertion to nullable expression',
-    kind: NullabilityFixKind.checkExpression,
+  static const downcastExpression = const NullabilityFixDescription._(
+    appliedMessage: 'Added a downcast to an expression',
+    kind: NullabilityFixKind.downcastExpression,
+  );
+
+  /// Informative message: a null-aware access won't be necessary in strong
+  /// checking mode.
+  static const nullAwarenessUnnecessaryInStrongMode =
+      const NullabilityFixDescription._(
+          appliedMessage:
+              'Null-aware access will be unnecessary in strong checking mode',
+          kind: NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode);
+
+  /// Informative message: a null-aware assignment won't be necessary in strong
+  /// checking mode.
+  static const nullAwareAssignmentUnnecessaryInStrongMode =
+      const NullabilityFixDescription._(
+          appliedMessage:
+              'Null-aware assignment will be unnecessary in strong checking mode',
+          kind: NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode);
+
+  static const otherCastExpression = const NullabilityFixDescription._(
+    appliedMessage: 'Added a cast to an expression (non-downcast)',
+    kind: NullabilityFixKind.otherCastExpression,
   );
 
   /// An unnecessary downcast has been discarded.
@@ -68,7 +145,13 @@
   static const removeNullAwareness = const NullabilityFixDescription._(
       appliedMessage:
           'Changed a null-aware access into an ordinary access, because the target cannot be null',
-      kind: NullabilityFixKind.removeNullAwareness);
+      kind: NullabilityFixKind.removeDeadCode);
+
+  /// A null-aware assignment was removed because its LHS is non-nullable.
+  static const removeNullAwareAssignment = const NullabilityFixDescription._(
+      appliedMessage:
+          'Removed a null-aware assignment, because the target cannot be null',
+      kind: NullabilityFixKind.removeDeadCode);
 
   /// A message used to indicate a fix has been applied.
   final String appliedMessage;
@@ -85,6 +168,13 @@
         kind: NullabilityFixKind.addRequired,
       );
 
+  /// An explicit type needs to be added.
+  factory NullabilityFixDescription.addType(String typeText) =>
+      NullabilityFixDescription._(
+        appliedMessage: "Add the explicit type '$typeText'",
+        kind: NullabilityFixKind.replaceVar,
+      );
+
   /// An explicit type mentioned in the source program needs to be made
   /// nullable.
   factory NullabilityFixDescription.makeTypeNullable(String type) =>
@@ -93,6 +183,22 @@
         kind: NullabilityFixKind.makeTypeNullable,
       );
 
+  /// An explicit type mentioned in the source program will be made
+  /// nullable due to a nullability hint.
+  factory NullabilityFixDescription.makeTypeNullableDueToHint(String type) =>
+      NullabilityFixDescription._(
+        appliedMessage:
+            "Changed type '$type' to be nullable, due to a nullability hint",
+        kind: NullabilityFixKind.makeTypeNullableDueToHint,
+      );
+
+  /// A 'var' declaration needs to be replaced with an explicit type.
+  factory NullabilityFixDescription.replaceVar(String typeText) =>
+      NullabilityFixDescription._(
+        appliedMessage: "Replace 'var' with '$typeText'",
+        kind: NullabilityFixKind.replaceVar,
+      );
+
   /// An explicit type mentioned in the source program does not need to be made
   /// nullable.
   factory NullabilityFixDescription.typeNotMadeNullable(String type) =>
@@ -101,6 +207,14 @@
         kind: NullabilityFixKind.typeNotMadeNullable,
       );
 
+  /// An explicit type mentioned in the source program does not need to be made
+  /// nullable.
+  factory NullabilityFixDescription.typeNotMadeNullableDueToHint(String type) =>
+      NullabilityFixDescription._(
+        appliedMessage: "Type '$type' was not made nullable due to a hint",
+        kind: NullabilityFixKind.typeNotMadeNullableDueToHint,
+      );
+
   const NullabilityFixDescription._(
       {@required this.appliedMessage, @required this.kind});
 
@@ -125,17 +239,29 @@
 
 /// An enumeration of the various kinds of nullability fixes.
 enum NullabilityFixKind {
+  addLate,
+  addLateDueToHint,
+  addLateDueToTestSetup,
   addRequired,
+  addType,
   checkExpression,
-  discardCondition,
-  discardElse,
-  discardIf,
-  discardThen,
+  checkExpressionDueToHint,
+  compoundAssignmentHasNullableSource,
+  compoundAssignmentHasBadCombinedType,
+  conditionFalseInStrongMode,
+  conditionTrueInStrongMode,
+  downcastExpression,
   makeTypeNullable,
+  makeTypeNullableDueToHint,
+  nullAwarenessUnnecessaryInStrongMode,
+  nullAwareAssignmentUnnecessaryInStrongMode,
+  otherCastExpression,
   removeAs,
+  removeDeadCode,
   removeLanguageVersionComment,
-  removeNullAwareness,
+  replaceVar,
   typeNotMadeNullable,
+  typeNotMadeNullableDueToHint,
 }
 
 /// Provisional API for DartFix to perform nullability migration.
@@ -152,12 +278,17 @@
   /// complete.  TODO(paulberry): remove this mode once the migration algorithm
   /// is fully implemented.
   ///
-  /// Optional parameter [removeViaComments] indicates whether dead code should
-  /// be removed in its entirety (the default) or removed by commenting it out.
+  /// Optional parameter [removeViaComments] indicates whether code that the
+  /// migration tool wishes to remove should instead be commenting it out.
+  ///
+  /// Optional parameter [warnOnWeakCode] indicates whether weak-only code
+  /// should be warned about or removed (in the way specified by
+  /// [removeViaComments]).
   factory NullabilityMigration(NullabilityMigrationListener listener,
       {bool permissive,
       NullabilityMigrationInstrumentation instrumentation,
-      bool removeViaComments}) = NullabilityMigrationImpl;
+      bool removeViaComments,
+      bool warnOnWeakCode}) = NullabilityMigrationImpl;
 
   /// Check if this migration is being run permissively.
   bool get isPermissive;
diff --git a/pkg/nnbd_migration/lib/src/conditional_discard.dart b/pkg/nnbd_migration/lib/src/conditional_discard.dart
index ab4c7c8..abecbd5 100644
--- a/pkg/nnbd_migration/lib/src/conditional_discard.dart
+++ b/pkg/nnbd_migration/lib/src/conditional_discard.dart
@@ -53,8 +53,5 @@
   /// to `true` is reachable after migration.
   bool get keepTrue => trueGuard == null || trueGuard.isNullable;
 
-  Iterable<FixReasonInfo> get reasons sync* {
-    if (!keepTrue) yield trueGuard;
-    if (!keepFalse) yield falseGuard;
-  }
+  FixReasonInfo get reason => !keepTrue ? trueGuard : falseGuard;
 }
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index f69f365..5de23f2 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -20,6 +20,19 @@
       this._typeSystem, this._variableRepository, this._graph);
 
   @override
+  DecoratedType factor(DecoratedType from, DecoratedType what) {
+    // TODO(scheglov): https://github.com/dart-lang/sdk/issues/41672
+    return from;
+  }
+
+  @override
+  bool isLocalVariableWithoutDeclaredType(PromotableElement variable) {
+    return variable is LocalVariableElement &&
+        variable.hasImplicitType &&
+        variable.initializer == null;
+  }
+
+  @override
   bool isSameType(DecoratedType type1, DecoratedType type2) {
     return type1 == type2;
   }
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index bba1dd7..5d10877 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -16,6 +16,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:meta/meta.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/conditional_discard.dart';
@@ -66,13 +67,13 @@
       {@required DecoratedType source,
       @required DecoratedType destination,
       @required bool hard}) {
-    super._checkAssignment(origin,
+    super._checkAssignment(origin, FixReasonTarget.root,
         source: source, destination: destination, hard: hard);
   }
 
   @override
-  void _connect(
-      NullabilityNode source, NullabilityNode destination, EdgeOrigin origin,
+  void _connect(NullabilityNode source, NullabilityNode destination,
+      EdgeOrigin origin, FixReasonTarget edgeTarget,
       {bool hard = false, bool checkable = true}) {
     _graph.connect(source, destination, origin,
         hard: hard, checkable: checkable);
@@ -136,6 +137,8 @@
   /// return statements.
   DecoratedType _currentFunctionType;
 
+  FunctionExpression _currentFunctionExpression;
+
   /// The [ClassElement] or [ExtensionElement] of the current class or extension
   /// being visited, or null.
   Element _currentClassOrExtension;
@@ -207,6 +210,8 @@
 
   final Set<PromotableElement> _lateHintedLocals = {};
 
+  Map<Token, HintComment> _nullCheckHints = {};
+
   EdgeBuilder(this.typeProvider, this._typeSystem, this._variables, this._graph,
       this.source, this.listener, this._decoratedClassHierarchy,
       {this.instrumentation})
@@ -279,7 +284,7 @@
         node, _typeSystem as TypeSystemImpl)) {
       _variables.recordUnnecessaryCast(source, node);
     }
-    node.type.accept(this);
+    _dispatch(node.type);
     final typeNode = _variables.decoratedTypeAnnotation(source, node.type);
     _handleAssignment(node.expression, destinationType: typeNode);
     _flowAnalysis.asExpression_end(node.expression, typeNode);
@@ -298,7 +303,7 @@
       }
     }
     _flowAnalysis.assert_afterCondition(node.condition);
-    node.message?.accept(this);
+    _dispatch(node.message);
     _flowAnalysis.assert_end();
     return null;
   }
@@ -315,7 +320,7 @@
       }
     }
     _flowAnalysis.assert_afterCondition(node.condition);
-    node.message?.accept(this);
+    _dispatch(node.message);
     _flowAnalysis.assert_end();
     return null;
   }
@@ -329,22 +334,40 @@
     } else if (node.operator.type != TokenType.EQ) {
       isCompound = true;
     }
+
+    var sourceIsSetupCall = false;
+    if (node.leftHandSide is SimpleIdentifier &&
+        _isCurrentFunctionExpressionFoundInTestSetUpCall()) {
+      var assignee = (node.leftHandSide as SimpleIdentifier).staticElement;
+      var enclosingElementOfCurrentFunction =
+          _currentFunctionExpression.declaredElement.enclosingElement;
+      if (enclosingElementOfCurrentFunction == assignee.enclosingElement) {
+        // [node]'s enclosing function is a function expression passed directly
+        // to a call to the test package's `setUp` function, and [node] is an
+        // assignment to a variable declared in the same scope as the call to
+        // `setUp`.
+        sourceIsSetupCall = true;
+      }
+    }
+
     var expressionType = _handleAssignment(node.rightHandSide,
         destinationExpression: node.leftHandSide,
         compoundOperatorInfo: isCompound ? node : null,
-        questionAssignNode: isQuestionAssign ? node : null);
+        questionAssignNode: isQuestionAssign ? node : null,
+        sourceIsSetupCall: sourceIsSetupCall);
     var conditionalNode = _conditionalNodes[node.leftHandSide];
     if (conditionalNode != null) {
       expressionType = expressionType.withNode(
           NullabilityNode.forLUB(conditionalNode, expressionType.node));
       _variables.recordDecoratedExpressionType(node, expressionType);
     }
+
     return expressionType;
   }
 
   @override
   DecoratedType visitAwaitExpression(AwaitExpression node) {
-    var expressionType = node.expression.accept(this);
+    var expressionType = _dispatch(node.expression);
     // TODO(paulberry) Handle subclasses of Future.
     if (expressionType.type.isDartAsyncFuture ||
         expressionType.type.isDartAsyncFutureOr) {
@@ -359,9 +382,11 @@
     var leftOperand = node.leftOperand;
     var rightOperand = node.rightOperand;
     if (operatorType == TokenType.EQ_EQ || operatorType == TokenType.BANG_EQ) {
-      var leftType = leftOperand.accept(this);
+      var leftType = _dispatch(leftOperand);
+      _graph.connectDummy(leftType.node, DummyOrigin(source, node));
       _flowAnalysis.equalityOp_rightBegin(leftOperand);
-      var rightType = rightOperand.accept(this);
+      var rightType = _dispatch(rightOperand);
+      _graph.connectDummy(rightType.node, DummyOrigin(source, node));
       bool notEqual = operatorType == TokenType.BANG_EQ;
       _flowAnalysis.equalityOp_end(node, rightOperand, notEqual: notEqual);
 
@@ -399,20 +424,20 @@
       return _makeNonNullableBoolType(node);
     } else if (operatorType == TokenType.QUESTION_QUESTION) {
       DecoratedType expressionType;
-      var leftType = leftOperand.accept(this);
+      var leftType = _dispatch(leftOperand);
       _flowAnalysis.ifNullExpression_rightBegin(node.leftOperand);
       try {
         _guards.add(leftType.node);
         DecoratedType rightType;
         _postDominatedLocals.doScoped(action: () {
-          rightType = rightOperand.accept(this);
+          rightType = _dispatch(rightOperand);
         });
         var ifNullNode = NullabilityNode.forIfNotNull(node);
         expressionType = _decorateUpperOrLowerBound(
             node, node.staticType, leftType, rightType, true,
             node: ifNullNode);
-        _connect(
-            rightType.node, expressionType.node, IfNullOrigin(source, node));
+        _connect(rightType.node, expressionType.node,
+            IfNullOrigin(source, node), null);
       } finally {
         _flowAnalysis.ifNullExpression_end();
         _guards.removeLast();
@@ -423,7 +448,7 @@
       var targetType = _checkExpressionNotNull(leftOperand);
       var callee = node.staticElement;
       if (callee == null) {
-        rightOperand.accept(this);
+        _dispatch(rightOperand);
         return _makeNullableDynamicType(node);
       } else {
         var calleeType =
@@ -435,8 +460,8 @@
       }
     } else {
       // TODO(paulberry)
-      leftOperand.accept(this);
-      rightOperand.accept(this);
+      _dispatch(leftOperand);
+      _dispatch(rightOperand);
       _unimplemented(
           node, 'Binary expression with operator ${node.operator.lexeme}');
     }
@@ -465,7 +490,7 @@
     var oldCascadeTargetType = _currentCascadeTargetType;
     try {
       _currentCascadeTargetType = _checkExpressionNotNull(node.target);
-      node.cascadeSections.accept(this);
+      _dispatchList(node.cascadeSections);
       return _currentCascadeTargetType;
     } finally {
       _currentCascadeTargetType = oldCascadeTargetType;
@@ -477,10 +502,10 @@
     _flowAnalysis.tryCatchStatement_catchBegin(
         node.exceptionParameter?.staticElement as PromotableElement,
         node.stackTraceParameter?.staticElement as PromotableElement);
-    node.exceptionType?.accept(this);
+    _dispatch(node.exceptionType);
     // The catch clause may not execute, so create a new scope for
     // post-dominators.
-    _postDominatedLocals.doScoped(action: () => node.body.accept(this));
+    _postDominatedLocals.doScoped(action: () => _dispatch(node.body));
     _flowAnalysis.tryCatchStatement_catchEnd();
     return null;
   }
@@ -488,10 +513,10 @@
   @override
   DecoratedType visitClassDeclaration(ClassDeclaration node) {
     visitClassOrMixinOrExtensionDeclaration(node);
-    node.extendsClause?.accept(this);
-    node.implementsClause?.accept(this);
-    node.withClause?.accept(this);
-    node.typeParameters?.accept(this);
+    _dispatch(node.extendsClause);
+    _dispatch(node.implementsClause);
+    _dispatch(node.withClause);
+    _dispatch(node.typeParameters);
     return null;
   }
 
@@ -507,7 +532,7 @@
       _fieldsNotInitializedAtDeclaration = {
         for (var member in members)
           if (member is FieldDeclaration &&
-              !_variables.isLateHinted(source, member.fields))
+              _variables.getLateHint(source, member.fields) == null)
             for (var field in member.fields.variables)
               if (!field.declaredElement.isStatic && field.initializer == null)
                 field.declaredElement as FieldElement
@@ -519,8 +544,8 @@
               true) {
         _handleUninitializedFields(node, _fieldsNotInitializedAtDeclaration);
       }
-      node.metadata.accept(this);
-      members.accept(this);
+      _dispatchList(node.metadata);
+      _dispatchList(members);
       _fieldsNotInitializedAtDeclaration = null;
     } finally {
       _currentClassOrExtension = null;
@@ -530,9 +555,9 @@
 
   @override
   DecoratedType visitClassTypeAlias(ClassTypeAlias node) {
-    node.superclass.accept(this);
-    node.implementsClause?.accept(this);
-    node.withClause?.accept(this);
+    _dispatch(node.superclass);
+    _dispatch(node.implementsClause);
+    _dispatch(node.withClause);
     var classElement = node.declaredElement;
     var supertype = classElement.supertype;
     var superElement = supertype.element;
@@ -564,20 +589,52 @@
   @override
   DecoratedType visitConditionalExpression(ConditionalExpression node) {
     _checkExpressionNotNull(node.condition);
+    NullabilityNode trueGuard;
+    NullabilityNode falseGuard;
+    if (identical(_conditionInfo?.condition, node.condition)) {
+      trueGuard = _conditionInfo.trueGuard;
+      falseGuard = _conditionInfo.falseGuard;
+      _variables.recordConditionalDiscard(source, node,
+          ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
+    }
 
     DecoratedType thenType;
     DecoratedType elseType;
 
-    // TODO(paulberry): guard anything inside the true and false branches
-
     // Post-dominators diverge as we branch in the conditional.
     // Note: we don't have to create a scope for each branch because they can't
     // define variables.
     _postDominatedLocals.doScoped(action: () {
       _flowAnalysis.conditional_thenBegin(node.condition);
-      thenType = node.thenExpression.accept(this);
+      if (trueGuard != null) {
+        _guards.add(trueGuard);
+      }
+      try {
+        thenType = _dispatch(node.thenExpression);
+        if (trueGuard != null) {
+          thenType = thenType
+              .withNode(_nullabilityNodeForGLB(node, thenType.node, trueGuard));
+        }
+      } finally {
+        if (trueGuard != null) {
+          _guards.removeLast();
+        }
+      }
       _flowAnalysis.conditional_elseBegin(node.thenExpression);
-      elseType = node.elseExpression.accept(this);
+      if (falseGuard != null) {
+        _guards.add(falseGuard);
+      }
+      try {
+        elseType = _dispatch(node.elseExpression);
+        if (falseGuard != null) {
+          elseType = elseType.withNode(
+              _nullabilityNodeForGLB(node, elseType.node, falseGuard));
+        }
+      } finally {
+        if (falseGuard != null) {
+          _guards.removeLast();
+        }
+      }
       _flowAnalysis.conditional_end(node, node.elseExpression);
     });
 
@@ -591,7 +648,7 @@
   DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
     _fieldsNotInitializedByConstructor =
         _fieldsNotInitializedAtDeclaration.toSet();
-    node.redirectedConstructor?.type?.typeArguments?.accept(this);
+    _dispatch(node.redirectedConstructor?.type?.typeArguments);
     _handleExecutableDeclaration(
         node,
         node.declaredElement,
@@ -628,7 +685,7 @@
 
   @override
   DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
-    node.parameter.accept(this);
+    _dispatch(node.parameter);
     var defaultValue = node.defaultValue;
     if (defaultValue == null) {
       if (node.declaredElement.hasRequired) {
@@ -649,7 +706,7 @@
   @override
   DecoratedType visitDoStatement(DoStatement node) {
     _flowAnalysis.doStatement_bodyBegin(node);
-    node.body.accept(this);
+    _dispatch(node.body);
     _flowAnalysis.doStatement_conditionBegin();
     _checkExpressionNotNull(node.condition);
     _flowAnalysis.doStatement_end(node.condition);
@@ -675,16 +732,23 @@
     return null;
   }
 
+  @override
+  DecoratedType visitExpressionStatement(ExpressionStatement node) {
+    var decoratedType = _dispatch(node.expression);
+    _graph.connectDummy(decoratedType.node, DummyOrigin(source, node));
+    return decoratedType;
+  }
+
   DecoratedType visitExtensionDeclaration(ExtensionDeclaration node) {
     visitClassOrMixinOrExtensionDeclaration(node);
-    node.extendedType.accept(this);
+    _dispatch(node.extendedType);
     return null;
   }
 
   @override
   DecoratedType visitFieldFormalParameter(FieldFormalParameter node) {
-    node.metadata.accept(this);
-    node.parameters?.accept(this);
+    _dispatchList(node.metadata);
+    _dispatch(node.parameters);
     var parameterElement = node.declaredElement as FieldFormalParameterElement;
     var parameterType = _variables.decoratedElementType(parameterElement);
     var field = parameterElement.field;
@@ -694,8 +758,8 @@
     if (node.type == null) {
       _linkDecoratedTypes(parameterType, fieldType, origin, isUnion: false);
     } else {
-      node.type.accept(this);
-      _checkAssignment(origin,
+      _dispatch(node.type);
+      _checkAssignment(origin, FixReasonTarget.root,
           source: parameterType, destination: fieldType, hard: true);
     }
 
@@ -712,24 +776,24 @@
   @override
   DecoratedType visitForStatement(ForStatement node) {
     _handleForLoopParts(
-        node, node.forLoopParts, node.body, (body) => body.accept(this));
+        node, node.forLoopParts, node.body, (body) => _dispatch(body));
     return null;
   }
 
   @override
   DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
-    node.metadata.accept(this);
-    node.returnType?.accept(this);
+    _dispatchList(node.metadata);
+    _dispatch(node.returnType);
     if (_flowAnalysis != null) {
       // This is a local function.
       _flowAnalysis.functionExpression_begin(node);
-      node.functionExpression.accept(this);
+      _dispatch(node.functionExpression);
       _flowAnalysis.functionExpression_end();
     } else {
       _createFlowAnalysis(node, node.functionExpression.parameters);
       // Initialize a new postDominator scope that contains only the parameters.
       try {
-        node.functionExpression.accept(this);
+        _dispatch(node.functionExpression);
         _flowAnalysis.finish();
       } finally {
         _flowAnalysis = null;
@@ -742,25 +806,28 @@
   @override
   DecoratedType visitFunctionExpression(FunctionExpression node) {
     // TODO(mfairhurst): enable edge builder "_insideFunction" hard edge tests.
-    node.parameters?.accept(this);
-    node.typeParameters?.accept(this);
+    _dispatch(node.parameters);
+    _dispatch(node.typeParameters);
     if (node.parent is! FunctionDeclaration) {
       _flowAnalysis.functionExpression_begin(node);
     }
     _addParametersToFlowAnalysis(node.parameters);
+    var previousFunction = _currentFunctionExpression;
     var previousFunctionType = _currentFunctionType;
+    _currentFunctionExpression = node;
     _currentFunctionType =
         _variables.decoratedElementType(node.declaredElement);
     try {
       _postDominatedLocals.doScoped(
           elements: node.declaredElement.parameters,
-          action: () => node.body.accept(this));
+          action: () => _dispatch(node.body));
       return _currentFunctionType;
     } finally {
       if (node.parent is! FunctionDeclaration) {
         _flowAnalysis.functionExpression_end();
       }
       _currentFunctionType = previousFunctionType;
+      _currentFunctionExpression = previousFunction;
     }
   }
 
@@ -769,7 +836,7 @@
       FunctionExpressionInvocation node) {
     final argumentList = node.argumentList;
     final typeArguments = node.typeArguments;
-    typeArguments?.accept(this);
+    _dispatch(typeArguments);
     DecoratedType calleeType = _checkExpressionNotNull(node.function);
     DecoratedType result;
     if (calleeType.type is FunctionType) {
@@ -778,10 +845,10 @@
           invokeType: node.staticInvokeType);
     } else {
       // Invocation of type `dynamic` or `Function`.
-      argumentList.accept(this);
+      _dispatch(argumentList);
       result = _makeNullableDynamicType(node);
     }
-    return _handleNullCheckHint(node, result);
+    return result;
   }
 
   @override
@@ -840,7 +907,7 @@
       _flowAnalysis.ifStatement_thenBegin(node.condition);
       // We branched, so create a new scope for post-dominators.
       _postDominatedLocals.doScoped(
-          action: () => node.thenStatement.accept(this));
+          action: () => _dispatch(node.thenStatement));
     } finally {
       if (trueGuard != null) {
         _guards.removeLast();
@@ -855,7 +922,7 @@
         _flowAnalysis.ifStatement_elseBegin();
         // We branched, so create a new scope for post-dominators.
         _postDominatedLocals.doScoped(
-            action: () => node.elseStatement?.accept(this));
+            action: () => _dispatch(node.elseStatement));
       }
     } finally {
       _flowAnalysis.ifStatement_end(elseStatement != null);
@@ -893,7 +960,7 @@
         result = calleeType.returnType;
       }
     }
-    return _handleNullCheckHint(node, result);
+    return result;
   }
 
   @override
@@ -908,7 +975,7 @@
     var target =
         NullabilityNodeTarget.text('constructed type').withCodeRef(node);
     if (typeArguments != null) {
-      typeArguments.accept(this);
+      _dispatch(typeArguments);
       typeArgumentTypes = typeArguments.arguments.map((t) => t.type);
       decoratedTypeArguments = typeArguments.arguments
           .map((t) => _variables.decoratedTypeAnnotation(source, t))
@@ -951,6 +1018,7 @@
     var calleeType = getOrComputeElementType(callee, targetType: createdType);
     for (var i = 0; i < decoratedTypeArguments.length; ++i) {
       _checkAssignment(parameterEdgeOrigins?.elementAt(i),
+          FixReasonTarget.root.typeArgument(i),
           source: decoratedTypeArguments[i],
           destination:
               _variables.decoratedTypeParameterBound(typeParameters[i]),
@@ -969,7 +1037,7 @@
   @override
   DecoratedType visitIsExpression(IsExpression node) {
     var type = node.type;
-    type.accept(this);
+    _dispatch(type);
     var decoratedType = _variables.decoratedTypeAnnotation(source, type);
     if (type is NamedType) {
       // The main type of the is check historically could not be nullable.
@@ -986,7 +1054,7 @@
       _unimplemented(node, 'Is expression with GenericFunctionType');
     }
     var expression = node.expression;
-    expression.accept(this);
+    _dispatch(expression);
     _flowAnalysis.isExpression_end(
         node, expression, node.notOperator != null, decoratedType);
     return _makeNonNullableBoolType(node);
@@ -1002,7 +1070,7 @@
   @override
   DecoratedType visitLibraryDirective(LibraryDirective node) {
     // skip directives, but not their metadata
-    node.metadata.accept(this);
+    _dispatchList(node.metadata);
     return null;
   }
 
@@ -1019,7 +1087,7 @@
         instrumentation?.implicitTypeArguments(source, node, [elementType]);
         _currentLiteralElementType = elementType;
       } else {
-        node.typeArguments.accept(this);
+        _dispatch(node.typeArguments);
         _currentLiteralElementType = _variables.decoratedTypeAnnotation(
             source, node.typeArguments.arguments[0]);
       }
@@ -1044,7 +1112,7 @@
   DecoratedType visitMethodDeclaration(MethodDeclaration node) {
     _handleExecutableDeclaration(node, node.declaredElement, node.metadata,
         node.returnType, node.parameters, null, node.body, null);
-    node.typeParameters?.accept(this);
+    _dispatch(node.typeParameters);
     return null;
   }
 
@@ -1055,7 +1123,7 @@
     bool isNullAware = node.isNullAware;
     var callee = node.methodName.staticElement;
     bool calleeIsStatic = callee is ExecutableElement && callee.isStatic;
-    node.typeArguments?.accept(this);
+    _dispatch(node.typeArguments);
 
     if (node.isCascaded) {
       targetType = _currentCascadeTargetType;
@@ -1063,9 +1131,9 @@
       if (_isPrefix(target)) {
         // Nothing to do.
       } else if (calleeIsStatic) {
-        target.accept(this);
+        _dispatch(target);
       } else if (isNullAware) {
-        targetType = target.accept(this);
+        targetType = _dispatch(target);
       } else {
         targetType = _handleTarget(target, node.methodName.name, callee);
       }
@@ -1077,7 +1145,7 @@
       // Dynamic dispatch.  The return type is `dynamic`.
       // TODO(paulberry): would it be better to assume a return type of `Never`
       // so that we don't unnecessarily propagate nullabilities everywhere?
-      node.argumentList.accept(this);
+      _dispatch(node.argumentList);
       expressionType = _makeNullableDynamicType(node);
     } else {
       var calleeType = getOrComputeElementType(callee, targetType: targetType);
@@ -1098,22 +1166,34 @@
         _variables.recordDecoratedExpressionType(node, expressionType);
       }
     }
-    return _handleNullCheckHint(node, expressionType);
+    _handleArgumentErrorCheckNotNull(node);
+    _handleQuiverCheckNotNull(node);
+    return expressionType;
   }
 
   @override
   DecoratedType visitMixinDeclaration(MixinDeclaration node) {
     visitClassOrMixinOrExtensionDeclaration(node);
-    node.implementsClause?.accept(this);
-    node.onClause?.accept(this);
-    node.typeParameters?.accept(this);
+    _dispatch(node.implementsClause);
+    _dispatch(node.onClause);
+    _dispatch(node.typeParameters);
     return null;
   }
 
   @override
   DecoratedType visitNamespaceDirective(NamespaceDirective node) {
     // skip directives, but not their metadata
-    node.metadata.accept(this);
+    _dispatchList(node.metadata);
+    return null;
+  }
+
+  @override
+  DecoratedType visitNode(AstNode node) {
+    for (var child in node.childEntities) {
+      if (child is AstNode) {
+        _dispatch(child);
+      }
+    }
     return null;
   }
 
@@ -1129,15 +1209,15 @@
 
   @override
   DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
-    var result = node.expression.accept(this);
+    var result = _dispatch(node.expression);
     _flowAnalysis.parenthesizedExpression(node, node.expression);
-    return _handleNullCheckHint(node, result);
+    return result;
   }
 
   @override
   DecoratedType visitPartOfDirective(PartOfDirective node) {
     // skip directives, but not their metadata
-    node.metadata.accept(this);
+    _dispatchList(node.metadata);
     return null;
   }
 
@@ -1176,9 +1256,8 @@
       // TODO(paulberry)
       _unimplemented(node, 'PrefixedIdentifier with a prefix');
     } else {
-      var type = _handlePropertyAccess(
+      return _handlePropertyAccess(
           node, node.prefix, node.identifier, false, false);
-      return _handleNullCheckHint(node, type);
     }
   }
 
@@ -1223,9 +1302,8 @@
 
   @override
   DecoratedType visitPropertyAccess(PropertyAccess node) {
-    var type = _handlePropertyAccess(node, node.target, node.propertyName,
+    return _handlePropertyAccess(node, node.target, node.propertyName,
         node.isNullAware, node.isCascaded);
-    return _handleNullCheckHint(node, type);
   }
 
   @override
@@ -1260,7 +1338,7 @@
           typeProvider, typeProvider.nullType, _graph, target);
       var origin = ImplicitNullReturnOrigin(source, node);
       _graph.makeNullable(implicitNullType.node, origin);
-      _checkAssignment(origin,
+      _checkAssignment(origin, FixReasonTarget.root,
           source:
               isAsync ? _futureOf(implicitNullType, node) : implicitNullType,
           destination: returnType,
@@ -1297,7 +1375,7 @@
           _currentLiteralElementType = elementType;
         } else {
           assert(typeArguments.length == 1);
-          node.typeArguments.accept(this);
+          _dispatch(node.typeArguments);
           _currentLiteralElementType =
               _variables.decoratedTypeAnnotation(source, typeArguments[0]);
         }
@@ -1329,7 +1407,7 @@
               ?.implicitTypeArguments(source, node, [keyType, valueType]);
         } else {
           assert(typeArguments.length == 2);
-          node.typeArguments.accept(this);
+          _dispatch(node.typeArguments);
           _currentMapKeyType =
               _variables.decoratedTypeAnnotation(source, typeArguments[0]);
           _currentMapValueType =
@@ -1393,7 +1471,7 @@
       _unimplemented(node,
           'Simple identifier with a static element of type ${staticElement.runtimeType}');
     }
-    return _handleNullCheckHint(node, result);
+    return result;
   }
 
   @override
@@ -1479,18 +1557,20 @@
 
   @override
   DecoratedType visitSwitchStatement(SwitchStatement node) {
-    node.expression.accept(this);
+    _dispatch(node.expression);
     _flowAnalysis.switchStatement_expressionEnd(node);
     var hasDefault = false;
     for (var member in node.members) {
-      var hasLabel = member.labels.isNotEmpty;
-      _flowAnalysis.switchStatement_beginCase(hasLabel, node);
-      if (member is SwitchCase) {
-        member.expression.accept(this);
-      } else {
-        hasDefault = true;
-      }
-      member.statements.accept(this);
+      _postDominatedLocals.doScoped(action: () {
+        var hasLabel = member.labels.isNotEmpty;
+        _flowAnalysis.switchStatement_beginCase(hasLabel, node);
+        if (member is SwitchCase) {
+          _dispatch(member.expression);
+        } else {
+          hasDefault = true;
+        }
+        _dispatchList(member.statements);
+      });
     }
     _flowAnalysis.switchStatement_end(hasDefault);
     return null;
@@ -1503,13 +1583,12 @@
 
   @override
   DecoratedType visitThisExpression(ThisExpression node) {
-    var type = _thisOrSuper(node);
-    return _handleNullCheckHint(node, type);
+    return _thisOrSuper(node);
   }
 
   @override
   DecoratedType visitThrowExpression(ThrowExpression node) {
-    node.expression.accept(this);
+    _dispatch(node.expression);
     // TODO(paulberry): do we need to check the expression type?  I think not.
     _flowAnalysis.handleExit();
     var target =
@@ -1530,16 +1609,16 @@
       _flowAnalysis.tryCatchStatement_bodyBegin();
     }
     var body = node.body;
-    body.accept(this);
+    _dispatch(body);
     if (catchClauses.isNotEmpty) {
       _flowAnalysis.tryCatchStatement_bodyEnd(body);
-      catchClauses.accept(this);
+      _dispatchList(catchClauses);
       _flowAnalysis.tryCatchStatement_end();
     }
     if (finallyBlock != null) {
       _flowAnalysis.tryFinallyStatement_finallyBegin(
           catchClauses.isNotEmpty ? node : body);
-      finallyBlock.accept(this);
+      _dispatch(finallyBlock);
       _flowAnalysis.tryFinallyStatement_end(finallyBlock);
     }
     return null;
@@ -1606,6 +1685,7 @@
             }
             _checkAssignment(
                 TypeParameterInstantiationOrigin(source, typeArguments[i]),
+                FixReasonTarget.root,
                 source: argumentType,
                 destination: bound,
                 hard: true);
@@ -1626,10 +1706,10 @@
     var parent = node.parent;
     bool isTopLevel =
         parent is FieldDeclaration || parent is TopLevelVariableDeclaration;
-    node.metadata.accept(this);
-    node.type?.accept(this);
+    _dispatchList(node.metadata);
+    _dispatch(node.type);
     for (var variable in node.variables) {
-      variable.metadata.accept(this);
+      _dispatchList(variable.metadata);
       var initializer = variable.initializer;
       var declaredElement = variable.declaredElement;
       if (isTopLevel) {
@@ -1638,7 +1718,7 @@
       } else {
         assert(_flowAnalysis != null);
         if (declaredElement is PromotableElement &&
-            _variables.isLateHinted(source, node)) {
+            _variables.getLateHint(source, node) != null) {
           _lateHintedLocals.add(declaredElement);
         }
       }
@@ -1676,7 +1756,7 @@
           // when processing variable reads (only if flow analysis indicates
           // the variable isn't definitely assigned).
           if (isTopLevel &&
-              !_variables.isLateHinted(source, node) &&
+              _variables.getLateHint(source, node) == null &&
               !(declaredElement is FieldElement && !declaredElement.isStatic)) {
             _graph.makeNullable(
                 type.node, ImplicitNullInitializerOrigin(source, node));
@@ -1716,7 +1796,7 @@
     _flowAnalysis.whileStatement_conditionBegin(node);
     _checkExpressionNotNull(node.condition);
     _flowAnalysis.whileStatement_bodyBegin(node, node.condition);
-    _postDominatedLocals.doScoped(action: () => node.body.accept(this));
+    _postDominatedLocals.doScoped(action: () => _dispatch(node.body));
     _flowAnalysis.whileStatement_end();
     return null;
   }
@@ -1738,7 +1818,7 @@
     if (_isPrefix(expression)) {
       throw ArgumentError('cannot check non-nullability of a prefix');
     }
-    sourceType ??= expression.accept(this);
+    sourceType ??= _dispatch(expression);
     if (sourceType == null) {
       throw StateError('No type computed for ${expression.runtimeType} '
           '(${expression.toSource()}) offset=${expression.offset}');
@@ -1748,19 +1828,19 @@
         hard: _postDominatedLocals.isReferenceInScope(expression),
         guards: _guards);
     if (origin is ExpressionChecksOrigin) {
-      origin.checks.edges.add(edge);
+      origin.checks.edges[FixReasonTarget.root] = edge;
     }
     return sourceType;
   }
 
   @override
-  void _connect(
-      NullabilityNode source, NullabilityNode destination, EdgeOrigin origin,
+  void _connect(NullabilityNode source, NullabilityNode destination,
+      EdgeOrigin origin, FixReasonTarget edgeTarget,
       {bool hard = false, bool checkable = true}) {
     var edge = _graph.connect(source, destination, origin,
         hard: hard, checkable: checkable, guards: _guards);
     if (origin is ExpressionChecksOrigin) {
-      origin.checks.edges.add(edge);
+      origin.checks.edges[edgeTarget] = edge;
     }
   }
 
@@ -1950,6 +2030,21 @@
     _unimplemented(astNode, '_decorateUpperOrLowerBound');
   }
 
+  DecoratedType _dispatch(AstNode node, {bool skipNullCheckHint = false}) {
+    var type = node?.accept(this);
+    if (!skipNullCheckHint && node is Expression) {
+      type = _handleNullCheckHint(node, type);
+    }
+    return type;
+  }
+
+  void _dispatchList(NodeList nodeList) {
+    if (nodeList == null) return;
+    for (var node in nodeList) {
+      _dispatch(node);
+    }
+  }
+
   DecoratedType _fixNumericTypes(
       DecoratedType decoratedType, DartType undecoratedType) {
     if (decoratedType.type.isDartCoreNum && undecoratedType.isDartCoreInt) {
@@ -1978,6 +2073,30 @@
         .decoratedTypeParameterBound((type.type as TypeParameterType).element);
   }
 
+  void _handleArgumentErrorCheckNotNull(MethodInvocation node) {
+    var callee = node.methodName.staticElement;
+    var calleeIsStatic = callee is ExecutableElement && callee.isStatic;
+    var target = node.realTarget;
+    bool targetIsArgumentError =
+        (target is SimpleIdentifier && target.name == 'ArgumentError') ||
+            (target is PrefixedIdentifier &&
+                target.identifier.name == 'ArgumentError');
+
+    if (calleeIsStatic &&
+        targetIsArgumentError &&
+        callee.name == 'checkNotNull' &&
+        node.argumentList.arguments.isNotEmpty) {
+      var argument = node.argumentList.arguments.first;
+      if (argument is SimpleIdentifier &&
+          _postDominatedLocals.isReferenceInScope(argument)) {
+        var argumentType =
+            _variables.decoratedElementType(argument.staticElement);
+        _graph.makeNonNullable(argumentType.node,
+            ArgumentErrorCheckNotNullOrigin(source, argument));
+      }
+    }
+  }
+
   /// Creates the necessary constraint(s) for an assignment of the given
   /// [expression] to a destination whose type is [destinationType].
   ///
@@ -1993,7 +2112,8 @@
       AssignmentExpression compoundOperatorInfo,
       AssignmentExpression questionAssignNode,
       bool fromDefaultValue = false,
-      bool wrapFuture = false}) {
+      bool wrapFuture = false,
+      bool sourceIsSetupCall = false}) {
     assert(
         (destinationExpression == null) != (destinationType == null),
         'Either destinationExpression or destinationType should be supplied, '
@@ -2009,7 +2129,7 @@
       if (destinationLocalVariable != null) {
         destinationType = getOrComputeElementType(destinationLocalVariable);
       } else {
-        destinationType = destinationExpression.accept(this);
+        destinationType = _dispatch(destinationExpression);
       }
     }
 
@@ -2020,7 +2140,7 @@
     }
     DecoratedType sourceType;
     try {
-      sourceType = expression.accept(this);
+      sourceType = _dispatch(expression);
       if (wrapFuture) {
         sourceType = _wrapFuture(sourceType, expression);
       }
@@ -2028,12 +2148,14 @@
         throw StateError('No type computed for ${expression.runtimeType} '
             '(${expression.toSource()}) offset=${expression.offset}');
       }
-      EdgeOrigin edgeOrigin = _makeEdgeOrigin(sourceType, expression);
+      EdgeOrigin edgeOrigin = _makeEdgeOrigin(sourceType, expression,
+          isSetupAssignment: sourceIsSetupCall);
       if (compoundOperatorInfo != null) {
         var compoundOperatorMethod = compoundOperatorInfo.staticElement;
         if (compoundOperatorMethod != null) {
           _checkAssignment(
               CompoundAssignmentOrigin(source, compoundOperatorInfo),
+              FixReasonTarget.root,
               source: destinationType,
               destination: _createNonNullableType(compoundOperatorInfo),
               hard: _postDominatedLocals
@@ -2042,7 +2164,7 @@
               compoundOperatorMethod,
               targetType: destinationType);
           assert(compoundOperatorType.positionalParameters.length > 0);
-          _checkAssignment(edgeOrigin,
+          _checkAssignment(edgeOrigin, FixReasonTarget.root,
               source: sourceType,
               destination: compoundOperatorType.positionalParameters[0],
               hard: _postDominatedLocals.isReferenceInScope(expression),
@@ -2051,6 +2173,7 @@
               compoundOperatorType.returnType, compoundOperatorInfo.staticType);
           _checkAssignment(
               CompoundAssignmentOrigin(source, compoundOperatorInfo),
+              FixReasonTarget.root,
               source: sourceType,
               destination: destinationType,
               hard: false);
@@ -2058,7 +2181,7 @@
           sourceType = _makeNullableDynamicType(compoundOperatorInfo);
         }
       } else {
-        _checkAssignment(edgeOrigin,
+        _checkAssignment(edgeOrigin, FixReasonTarget.root,
             source: sourceType,
             destination: destinationType,
             hard: questionAssignNode == null &&
@@ -2093,7 +2216,7 @@
       return _handleAssignment(element,
           destinationType: _currentLiteralElementType);
     } else {
-      return element.accept(this);
+      return _dispatch(element);
     }
   }
 
@@ -2124,22 +2247,22 @@
       FunctionBody body,
       ConstructorName redirectedConstructor) {
     assert(_currentFunctionType == null);
-    metadata.accept(this);
-    returnType?.accept(this);
+    _dispatchList(metadata);
+    _dispatch(returnType);
     _createFlowAnalysis(node, parameters);
-    parameters?.accept(this);
+    _dispatch(parameters);
     _currentFunctionType = _variables.decoratedElementType(declaredElement);
     _addParametersToFlowAnalysis(parameters);
     // Push a scope of post-dominated declarations on the stack.
     _postDominatedLocals.pushScope(elements: declaredElement.parameters);
     try {
-      initializers?.accept(this);
+      _dispatchList(initializers);
       if (declaredElement is ConstructorElement &&
           !declaredElement.isFactory &&
           declaredElement.redirectedConstructor == null) {
         _handleUninitializedFields(node, _fieldsNotInitializedByConstructor);
       }
-      body.accept(this);
+      _dispatch(body);
       if (redirectedConstructor != null) {
         _handleConstructorRedirection(parameters, redirectedConstructor);
       }
@@ -2185,7 +2308,8 @@
       var overriddenFieldType =
           decoratedOverriddenField.substitute(substitution);
       if (method.isGetter) {
-        _checkAssignment(ReturnTypeInheritanceOrigin(source, node),
+        _checkAssignment(
+            ReturnTypeInheritanceOrigin(source, node), FixReasonTarget.root,
             source: _currentFunctionType.returnType,
             destination: overriddenFieldType,
             hard: true);
@@ -2194,7 +2318,8 @@
         DecoratedType currentParameterType =
             _currentFunctionType.positionalParameters.single;
         DecoratedType overriddenParameterType = overriddenFieldType;
-        _checkAssignment(ParameterInheritanceOrigin(source, node),
+        _checkAssignment(
+            ParameterInheritanceOrigin(source, node), FixReasonTarget.root,
             source: overriddenParameterType,
             destination: currentParameterType,
             hard: true);
@@ -2209,9 +2334,10 @@
             _currentFunctionType.returnType,
             overriddenFunctionType.returnType,
             ReturnTypeInheritanceOrigin(source, node),
-            isUnion: true);
+            isUnion: false);
       } else {
-        _checkAssignment(ReturnTypeInheritanceOrigin(source, node),
+        _checkAssignment(
+            ReturnTypeInheritanceOrigin(source, node), FixReasonTarget.root,
             source: _currentFunctionType.returnType,
             destination: overriddenFunctionType.returnType,
             hard: true);
@@ -2250,9 +2376,9 @@
             if (_isUntypedParameter(normalParameter)) {
               _linkDecoratedTypes(
                   overriddenParameterType, currentParameterType, origin,
-                  isUnion: true);
+                  isUnion: false);
             } else {
-              _checkAssignment(origin,
+              _checkAssignment(origin, FixReasonTarget.root,
                   source: overriddenParameterType,
                   destination: currentParameterType,
                   hard: false,
@@ -2291,11 +2417,13 @@
       }
       var overriddenType = unsubstitutedOverriddenType.substitute(substitution);
       if (overriddenElement.isGetter) {
-        _checkAssignment(ReturnTypeInheritanceOrigin(source, node),
+        _checkAssignment(
+            ReturnTypeInheritanceOrigin(source, node), FixReasonTarget.root,
             source: type, destination: overriddenType, hard: true);
       } else {
         assert(overriddenElement.isSetter);
-        _checkAssignment(ParameterInheritanceOrigin(source, node),
+        _checkAssignment(
+            ParameterInheritanceOrigin(source, node), FixReasonTarget.root,
             source: overriddenType, destination: type, hard: true);
       }
     } else {
@@ -2307,9 +2435,13 @@
       DecoratedType Function(AstNode) bodyHandler) {
     if (parts is ForParts) {
       if (parts is ForPartsWithDeclarations) {
-        parts.variables?.accept(this);
+        _dispatch(parts.variables);
       } else if (parts is ForPartsWithExpression) {
-        parts.initialization?.accept(this);
+        var initializationType = _dispatch(parts.initialization);
+        if (initializationType != null) {
+          _graph.connectDummy(
+              initializationType.node, DummyOrigin(source, parts));
+        }
       }
       _flowAnalysis.for_conditionBegin(node);
       if (parts.condition != null) {
@@ -2323,7 +2455,7 @@
         var variableElement = parts.loopVariable.declaredElement;
         _flowAnalysis.declare(variableElement, true);
         lhsElement = variableElement;
-        parts.loopVariable?.type?.accept(this);
+        _dispatch(parts.loopVariable?.type);
       } else if (parts is ForEachPartsWithIdentifier) {
         lhsElement = parts.identifier.staticElement;
       } else {
@@ -2341,7 +2473,8 @@
               .asInstanceOf(
                   iterableType, typeProvider.iterableDynamicType.element)
               .typeArguments[0];
-          _checkAssignment(ForEachVariableOrigin(source, parts),
+          _checkAssignment(
+              ForEachVariableOrigin(source, parts), FixReasonTarget.root,
               source: elementType, destination: lhsType, hard: false);
         }
       }
@@ -2358,7 +2491,10 @@
 
       if (parts is ForParts) {
         _flowAnalysis.for_updaterBegin();
-        parts.updaters.accept(this);
+        for (var updater in parts.updaters ?? <Expression>[]) {
+          var updaterType = _dispatch(updater);
+          _graph.connectDummy(updaterType.node, DummyOrigin(source, updater));
+        }
         _flowAnalysis.for_end();
       } else {
         _flowAnalysis.forEach_end();
@@ -2371,7 +2507,8 @@
   DecoratedType _handleInstantiation(DecoratedType type,
       List<DecoratedType> argumentTypes, List<EdgeOrigin> edgeOrigins) {
     for (var i = 0; i < argumentTypes.length; ++i) {
-      _checkAssignment(edgeOrigins?.elementAt(i),
+      _checkAssignment(
+          edgeOrigins?.elementAt(i), FixReasonTarget.root.typeArgument(i),
           source: argumentTypes[i],
           destination: DecoratedTypeParameterBounds.current
               .get((type.type as FunctionType).typeFormals[i]),
@@ -2488,12 +2625,17 @@
     // `/*!*/`s because they're not expression null check hints, they're type
     // non-nullability hints (which are handled by NodeBuilder).
     if (_typeNameNesting > 0) return type;
-    switch (getPostfixHint(expression)) {
-      case NullabilityComment.bang:
-        _variables.recordNullCheckHint(source, expression);
-        return type.withNode(_graph.never);
-      default:
-        return type;
+    var token = expression.endToken;
+    if (_nullCheckHints.containsKey(token)) {
+      // Already visited this location.
+      return type;
+    }
+    var hint = _nullCheckHints[token] = getPostfixHint(token);
+    if (hint != null && hint.kind == HintCommentKind.bang) {
+      _variables.recordNullCheckHint(source, expression, hint);
+      return type.withNode(_graph.never);
+    } else {
+      return type;
     }
   }
 
@@ -2505,11 +2647,11 @@
     if (isCascaded) {
       targetType = _currentCascadeTargetType;
     } else if (_isPrefix(target)) {
-      return propertyName.accept(this);
+      return _dispatch(propertyName, skipNullCheckHint: true);
     } else if (calleeIsStatic) {
-      target.accept(this);
+      _dispatch(target);
     } else if (isNullAware) {
-      targetType = target.accept(this);
+      targetType = _dispatch(target);
     } else {
       targetType = _handleTarget(target, propertyName.name, callee);
     }
@@ -2537,9 +2679,33 @@
     }
   }
 
+  /// Check whether [node] is a call to the quiver package's [`checkNotNull`],
+  /// and if so, potentially mark the first argument as non-nullable.
+  ///
+  /// [`checkNotNull`]: https://pub.dev/documentation/quiver/latest/quiver.check/checkNotNull.html
+  void _handleQuiverCheckNotNull(MethodInvocation node) {
+    var callee = node.methodName.staticElement;
+    var calleeUri = callee?.library?.source?.uri;
+    var isQuiverCheckNull = callee?.name == 'checkNotNull' &&
+        calleeUri != null &&
+        calleeUri.scheme == 'package' &&
+        calleeUri.path.startsWith('quiver/');
+
+    if (isQuiverCheckNull && node.argumentList.arguments.isNotEmpty) {
+      var argument = node.argumentList.arguments.first;
+      if (argument is SimpleIdentifier &&
+          _postDominatedLocals.isReferenceInScope(argument)) {
+        var argumentType =
+            _variables.decoratedElementType(argument.staticElement);
+        _graph.makeNonNullable(
+            argumentType.node, QuiverCheckNotNullOrigin(source, argument));
+      }
+    }
+  }
+
   DecoratedType _handleTarget(Expression target, String name, Element method) {
     if (isDeclaredOnObject(name)) {
-      return target.accept(this);
+      return _dispatch(target);
     } else if (method is MethodElement &&
         method.enclosingElement is ExtensionElement) {
       // Extension methods can be called on a `null` target, when the `on` type
@@ -2547,7 +2713,7 @@
       _handleAssignment(target,
           destinationType:
               _variables.decoratedElementType(method.enclosingElement));
-      return target.accept(this);
+      return _dispatch(target);
     } else {
       return _checkExpressionNotNull(target);
     }
@@ -2560,6 +2726,27 @@
     }
   }
 
+  /// Returns whether [_currentFunctionExpression] is an argument to the test
+  /// package's `setUp` function.
+  bool _isCurrentFunctionExpressionFoundInTestSetUpCall() {
+    var parent = _currentFunctionExpression?.parent;
+    if (parent is ArgumentList) {
+      var grandParent = parent.parent;
+      if (grandParent is MethodInvocation) {
+        var enclosingInvocation = grandParent.methodName;
+        if (enclosingInvocation.name == 'setUp') {
+          var uri = enclosingInvocation.staticElement.library?.source?.uri;
+          if (uri != null &&
+              uri.scheme == 'package' &&
+              uri.path.startsWith('test_core/')) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
   bool _isPrefix(Expression e) =>
       e is SimpleIdentifier && e.staticElement is PrefixElement;
 
@@ -2611,12 +2798,14 @@
     }
   }
 
-  EdgeOrigin _makeEdgeOrigin(DecoratedType sourceType, Expression expression) {
+  EdgeOrigin _makeEdgeOrigin(DecoratedType sourceType, Expression expression,
+      {bool isSetupAssignment = false}) {
     if (sourceType.type.isDynamic) {
       return DynamicAssignmentOrigin(source, expression);
     } else {
       ExpressionChecksOrigin expressionChecksOrigin = ExpressionChecksOrigin(
-          source, expression, ExpressionChecks(expression.end));
+          source, expression, ExpressionChecks(),
+          isSetupAssignment: isSetupAssignment);
       _variables.recordExpressionChecks(
           source, expression, expressionChecksOrigin);
       return expressionChecksOrigin;
@@ -2768,8 +2957,10 @@
   /// [destination].  [origin] should be used as the origin for any edges
   /// created.  [hard] indicates whether a hard edge should be created.
   /// [sourceIsFunctionLiteral] indicates whether the source of the assignment
-  /// is a function literal expression.
-  void _checkAssignment(EdgeOrigin origin,
+  /// is a function literal expression. [sourceIsSetupCall] indicates whether the
+  /// source of the assignment is a function literal passed to the test
+  /// package's `setUp` function.
+  void _checkAssignment(EdgeOrigin origin, FixReasonTarget edgeTarget,
       {@required DecoratedType source,
       @required DecoratedType destination,
       @required bool hard,
@@ -2792,12 +2983,12 @@
           _assumeNonNullabilityInCasts,
           'side cast not supported without assuming non-nullability:'
           ' $sourceType to $destinationType');
-      _connect(source.node, destination.node, origin, hard: hard);
+      _connect(source.node, destination.node, origin, edgeTarget, hard: hard);
       return;
     }
-    _connect(source.node, destination.node, origin,
+    _connect(source.node, destination.node, origin, edgeTarget,
         hard: hard, checkable: checkable);
-    _checkAssignment_recursion(origin,
+    _checkAssignment_recursion(origin, edgeTarget,
         source: source,
         destination: destination,
         sourceIsFunctionLiteral: sourceIsFunctionLiteral);
@@ -2807,7 +2998,7 @@
   /// constituting [source] and [destination], and creating the appropriate
   /// edges between them.  [sourceIsFunctionLiteral] indicates whether the
   /// source of the assignment is a function literal expression.
-  void _checkAssignment_recursion(EdgeOrigin origin,
+  void _checkAssignment_recursion(EdgeOrigin origin, FixReasonTarget edgeTarget,
       {@required DecoratedType source,
       @required DecoratedType destination,
       bool sourceIsFunctionLiteral = false}) {
@@ -2851,7 +3042,8 @@
         // So the RHS of the "or" is redundant, and we can simplify to:
         // - S0 <: S1.
         var s0 = source.typeArguments[0];
-        _checkAssignment(origin, source: s0, destination: s1, hard: false);
+        _checkAssignment(origin, edgeTarget.yieldedType,
+            source: s0, destination: s1, hard: false);
         return;
       }
       // (From the subtyping spec):
@@ -2866,7 +3058,8 @@
       // - or T0 <: S1
       else if (_typeSystem.isSubtypeOf(sourceType, s1.type)) {
         // E.g. FutureOr<int> = (... as int)
-        _checkAssignment_recursion(origin, source: source, destination: s1);
+        _checkAssignment_recursion(origin, edgeTarget.yieldedType,
+            source: source, destination: s1);
         return;
       }
       // - or T0 is X0 and X0 has bound S0 and S0 <: T1
@@ -2891,7 +3084,7 @@
       } else {
         // Effectively this is an assignment from the type parameter's bound to
         // the destination type.
-        _checkAssignment(origin,
+        _checkAssignment(origin, edgeTarget,
             source: _getTypeParameterTypeBound(source),
             destination: destination,
             hard: false);
@@ -2910,7 +3103,7 @@
       assert(rewrittenSource.typeArguments.length ==
           destination.typeArguments.length);
       for (int i = 0; i < rewrittenSource.typeArguments.length; i++) {
-        _checkAssignment(origin,
+        _checkAssignment(origin, edgeTarget.typeArgument(i),
             source: rewrittenSource.typeArguments[i],
             destination: destination.typeArguments[i],
             hard: false,
@@ -2921,7 +3114,7 @@
       // function returning non-null is required, we will insure that the
       // function literal has a non-nullable return type (e.g. by inserting null
       // checks into the function literal).
-      _checkAssignment(origin,
+      _checkAssignment(origin, edgeTarget.returnType,
           source: source.returnType,
           destination: destination.returnType,
           hard: sourceIsFunctionLiteral,
@@ -2935,7 +3128,7 @@
               i < destination.positionalParameters.length;
           i++) {
         // Note: source and destination are swapped due to contravariance.
-        _checkAssignment(origin,
+        _checkAssignment(origin, edgeTarget.positionalParameter(i),
             source: destination.positionalParameters[i],
             destination: source.positionalParameters[i],
             hard: false,
@@ -2943,7 +3136,7 @@
       }
       for (var entry in destination.namedParameters.entries) {
         // Note: source and destination are swapped due to contravariance.
-        _checkAssignment(origin,
+        _checkAssignment(origin, edgeTarget.namedParameter(entry.key),
             source: entry.value,
             destination: source.namedParameters[entry.key],
             hard: false,
@@ -2966,7 +3159,8 @@
     var destinationType = destination.type;
     assert(_typeSystem.isSubtypeOf(destinationType, source.type));
     // Nullability should narrow to maintain subtype relationship.
-    _connect(source.node, destination.node, origin, hard: hard);
+    _connect(source.node, destination.node, origin, FixReasonTarget.root,
+        hard: hard);
 
     if (source.type.isDynamic ||
         source.type.isDartCoreObject ||
@@ -2984,7 +3178,7 @@
     } else if (destinationType is TypeParameterType) {
       if (source.type is! TypeParameterType) {
         // Assume an assignment to the type parameter's bound.
-        _checkAssignment(origin,
+        _checkAssignment(origin, FixReasonTarget.root,
             source: source,
             destination: _getTypeParameterTypeBound(destination),
             hard: false);
@@ -2996,6 +3190,7 @@
       if (destination.type.isDartAsyncFuture) {
         // FutureOr<T?> is nullable, so the Future<T> should be nullable too.
         _connect(source.typeArguments[0].node, destination.node, origin,
+            FixReasonTarget.root.yieldedType,
             hard: hard);
         _checkDowncast(origin,
             source: source.typeArguments[0],
@@ -3039,8 +3234,8 @@
     }
   }
 
-  void _connect(
-      NullabilityNode source, NullabilityNode destination, EdgeOrigin origin,
+  void _connect(NullabilityNode source, NullabilityNode destination,
+      EdgeOrigin origin, FixReasonTarget edgeTarget,
       {bool hard = false, bool checkable = true});
 
   /// Given a [type] representing a type parameter, retrieves the type's bound.
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index e71c1b4..8348c81 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -430,6 +430,49 @@
   EdgeOriginKind get kind => EdgeOriginKind.nonNullAssertion;
 }
 
+/// Edge origin resulting from the presence of a call to quiver's
+/// `checkNotNull`.
+///
+/// For example, in the following code snippet:
+///   import 'package:quiver/check.dart';
+///   void f(int i) {
+///     checkNotNull(i);
+///   }
+///
+/// this class is used for the edge connecting the type of f's `i` parameter to
+/// `never`, due to the `checkNotNull` call proclaiming that `i` is not `null`.
+class QuiverCheckNotNullOrigin extends EdgeOrigin {
+  QuiverCheckNotNullOrigin(Source source, SimpleIdentifier node)
+      : super(source, node);
+
+  @override
+  String get description => 'value checked to be non-null';
+
+  @override
+  EdgeOriginKind get kind => EdgeOriginKind.quiverCheckNotNull;
+}
+
+/// Edge origin resulting from the presence of a call to
+/// `ArgumentError.checkNotNull`.
+///
+/// For example, in the following code snippet:
+///   void f(int i) {
+///     ArgumentError.checkNotNull(i);
+///   }
+///
+/// this class is used for the edge connecting the type of f's `i` parameter to
+/// `never`, due to the `checkNotNull` call proclaiming that `i` is not `null`.
+class ArgumentErrorCheckNotNullOrigin extends EdgeOrigin {
+  ArgumentErrorCheckNotNullOrigin(Source source, SimpleIdentifier node)
+      : super(source, node);
+
+  @override
+  String get description => 'value checked to be non-null';
+
+  @override
+  EdgeOriginKind get kind => EdgeOriginKind.argumentErrorCheckNotNull;
+}
+
 /// Edge origin resulting from the presence of an explicit nullability hint
 /// comment.
 ///
@@ -472,6 +515,18 @@
   EdgeOriginKind get kind => EdgeOriginKind.optionalFormalParameter;
 }
 
+/// Edge origin resulting from the use of an element which does not affect the
+/// nullability graph in other ways.
+class DummyOrigin extends EdgeOrigin {
+  DummyOrigin(Source source, AstNode node) : super(source, node);
+
+  @override
+  String get description => 'dummy';
+
+  @override
+  EdgeOriginKind get kind => EdgeOriginKind.dummy;
+}
+
 /// Edge origin resulting from an inheritance relationship between two method
 /// parameters.
 class ParameterInheritanceOrigin extends EdgeOrigin {
diff --git a/pkg/nnbd_migration/lib/src/edit_plan.dart b/pkg/nnbd_migration/lib/src/edit_plan.dart
index 00931b3..d2004de 100644
--- a/pkg/nnbd_migration/lib/src/edit_plan.dart
+++ b/pkg/nnbd_migration/lib/src/edit_plan.dart
@@ -11,8 +11,10 @@
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:meta/meta.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 
 Map<int, List<AtomicEdit>> _removeCode(
     int offset, int end, _RemovalStyle removalStyle, AtomicEditInfo info) {
@@ -78,10 +80,10 @@
   ///
   /// Optional argument [info] contains information about why the change was
   /// made.
-  const AtomicEdit.delete(this.length, {this.info})
+  const AtomicEdit.delete(this.length, {this.info, this.isInformative = false})
       : assert(length > 0),
-        replacement = '',
-        isInformative = false;
+        assert(isInformative is bool),
+        replacement = '';
 
   /// Initialize an edit to insert the [replacement] characters.
   ///
@@ -90,6 +92,7 @@
   const AtomicEdit.insert(this.replacement,
       {this.info, this.isInformative: false})
       : assert(replacement.length > 0),
+        assert(isInformative is bool),
         length = 0;
 
   /// Initialize an edit to replace [length] characters with the [replacement]
@@ -128,9 +131,13 @@
   final NullabilityFixDescription description;
 
   /// The reasons for the edit.
-  final List<FixReasonInfo> fixReasons;
+  final Map<FixReasonTarget, FixReasonInfo> fixReasons;
 
-  AtomicEditInfo(this.description, this.fixReasons);
+  /// If the edit is being made due to a hint, the hint in question; otherwise
+  /// `null`.
+  final HintComment hintComment;
+
+  AtomicEditInfo(this.description, this.fixReasons, {this.hintComment});
 }
 
 /// An [EditPlan] is a builder capable of accumulating a set of edits to be
@@ -178,6 +185,36 @@
   EditPlanner(this.lineInfo, this.sourceText, {this.removeViaComments = false});
 
   /// Creates a new edit plan that consists of executing [innerPlan], and then
+  /// converting the late [hint] into an explicit `late`.
+  NodeProducingEditPlan acceptLateHint(
+      NodeProducingEditPlan innerPlan, HintComment hint,
+      {AtomicEditInfo info}) {
+    var affixPlan = innerPlan is _CommentAffixPlan
+        ? innerPlan
+        : _CommentAffixPlan(innerPlan);
+    var changes = hint.changesToAccept(sourceText, info: info);
+    assert(affixPlan.offset >= _endForChanges(changes));
+    affixPlan.offset = _offsetForChanges(changes);
+    affixPlan._prefixChanges = changes + affixPlan._prefixChanges;
+    return affixPlan;
+  }
+
+  /// Creates a new edit plan that consists of executing [innerPlan], and then
+  /// converting the nullability [hint] into an explicit `?` or `!`.
+  NodeProducingEditPlan acceptNullabilityOrNullCheckHint(
+      NodeProducingEditPlan innerPlan, HintComment hint,
+      {AtomicEditInfo info}) {
+    var affixPlan = innerPlan is _CommentAffixPlan
+        ? innerPlan
+        : _CommentAffixPlan(innerPlan);
+    var changes = hint.changesToAccept(sourceText);
+    assert(affixPlan.end <= _offsetForChanges(changes));
+    affixPlan.end = _endForChanges(changes);
+    affixPlan._postfixChanges += hint.changesToAccept(sourceText, info: info);
+    return affixPlan;
+  }
+
+  /// Creates a new edit plan that consists of executing [innerPlan], and then
   /// appending the given [operand], with an intervening binary [operator].
   ///
   /// Optional argument [info] contains information about why the change was
@@ -223,6 +260,28 @@
   }
 
   /// Creates a new edit plan that consists of executing [innerPlan], and then
+  /// appending the given [comment]].
+  ///
+  /// Optional argument [info] contains information about why the change was
+  /// made.
+  ///
+  /// Optional argument [isInformative] indicates whether the comment is simply
+  /// informative, or should actually be applied to the final output (the
+  /// default).
+  NodeProducingEditPlan addCommentPostfix(
+      NodeProducingEditPlan innerPlan, String comment,
+      {AtomicEditInfo info, bool isInformative = false}) {
+    var end = innerPlan.end;
+    return surround(innerPlan, suffix: [
+      AtomicEdit.insert(' ', isInformative: isInformative),
+      AtomicEdit.insert(comment, info: info, isInformative: isInformative),
+      if (!_isJustBefore(end, const [')', ']', '}', ';']) &&
+          !_isJustBeforeWhitespace(end))
+        AtomicEdit.insert(' ', isInformative: isInformative)
+    ]);
+  }
+
+  /// 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.
   ///
@@ -263,6 +322,21 @@
       _PassThroughBuilderImpl(node);
 
   /// Creates a new edit plan that consists of executing [innerPlan], and then
+  /// dropping the given nullability [hint].
+  NodeProducingEditPlan dropNullabilityHint(
+      NodeProducingEditPlan innerPlan, HintComment hint,
+      {AtomicEditInfo info}) {
+    var affixPlan = innerPlan is _CommentAffixPlan
+        ? innerPlan
+        : _CommentAffixPlan(innerPlan);
+    var changes = hint.changesToRemove(sourceText, info: info);
+    assert(affixPlan.end <= _offsetForChanges(changes));
+    affixPlan.end = _endForChanges(changes);
+    affixPlan._postfixChanges += changes;
+    return affixPlan;
+  }
+
+  /// Creates a new edit plan that consists of executing [innerPlan], and then
   /// appending an informative ` `, to illustrate that the type is non-nullable.
   ///
   /// Optional argument [info] contains information about why the change was
@@ -318,6 +392,20 @@
     return (plan as NodeProducingEditPlan)._getChanges(false);
   }
 
+  /// Creates a new edit plan that adds an informative message to the given
+  /// [token].
+  ///
+  /// The created edit plan should be inserted into the list of inner plans for
+  /// a pass-through plan targeted at the [containingNode].  See [passThrough].
+  EditPlan informativeMessageForToken(AstNode containingNode, Token token,
+      {AtomicEditInfo info}) {
+    return _TokenChangePlan(containingNode, {
+      token.offset: [
+        AtomicEdit.delete(token.lexeme.length, info: info, isInformative: true)
+      ]
+    });
+  }
+
   /// Creates a new edit plan that inserts the text indicated by [edits] at the
   /// given [offset].
   ///
@@ -453,7 +541,15 @@
   ///
   /// The created edit plan should be inserted into the list of inner plans for
   /// a pass-through plan targeted at the source node.  See [passThrough].
-  EditPlan removeNullAwareness(Expression sourceNode, {AtomicEditInfo info}) {
+  ///
+  /// Optional argument [info] contains information about why the change was
+  /// made.
+  ///
+  /// Optional argument [isInformative] indicates whether the comment is simply
+  /// informative, or should actually be applied to the final output (the
+  /// default).
+  EditPlan removeNullAwareness(Expression sourceNode,
+      {AtomicEditInfo info, bool isInformative = false}) {
     Token operator;
     if (sourceNode is MethodInvocation) {
       operator = sourceNode.operator;
@@ -466,7 +562,9 @@
     }
     assert(operator.type == TokenType.QUESTION_PERIOD);
     return _TokenChangePlan(sourceNode, {
-      operator.offset: [AtomicEdit.delete(1, info: info)]
+      operator.offset: [
+        AtomicEdit.delete(1, info: info, isInformative: isInformative)
+      ]
     });
   }
 
@@ -500,16 +598,10 @@
   /// text.
   ///
   /// [parentNode] should be the innermost AST node containing [token].
-  EditPlan replaceToken(
-      AstNode parentNode, Token token, List<AtomicEdit> replacement,
+  EditPlan replaceToken(AstNode parentNode, Token token, String replacement,
       {AtomicEditInfo info}) {
-    assert(!replacement.any((edit) => !edit.isInsertion),
-        'All edits should be insertions');
     return _TokenChangePlan(parentNode, {
-      token.offset: [
-        AtomicEdit.delete(token.length, info: info),
-        ...replacement
-      ]
+      token.offset: [AtomicEdit.replace(token.length, replacement, info: info)]
     });
   }
 
@@ -554,10 +646,10 @@
     var innerChanges =
         innerPlan._getChanges(parensNeeded) ?? <int, List<AtomicEdit>>{};
     if (prefix != null) {
-      (innerChanges[innerPlan.sourceNode.offset] ??= []).insertAll(0, prefix);
+      (innerChanges[innerPlan.offset] ??= []).insertAll(0, prefix);
     }
     if (suffix != null) {
-      (innerChanges[innerPlan.sourceNode.end] ??= []).addAll(suffix);
+      (innerChanges[innerPlan.end] ??= []).addAll(suffix);
     }
     return _SimpleEditPlan(
         innerPlan.sourceNode,
@@ -608,6 +700,18 @@
     return lineInfo.lineStarts[lineNumber - 1];
   }
 
+  int _endForChanges(Map<int, List<AtomicEdit>> changes) {
+    int result;
+    for (var entry in changes.entries) {
+      var end = entry.key;
+      for (var edit in entry.value) {
+        end += edit.length;
+      }
+      if (result == null || end > result) result = end;
+    }
+    return result;
+  }
+
   /// Finds the deepest entry in [builderStack] that matches an entry in
   /// [ancestryStack], taking advantage of the fact that [builderStack] walks
   /// stepwise down the AST, and [ancestryStack] walks stepwise up the AST, with
@@ -653,16 +757,21 @@
     return lineInfo.lineStarts[lineNumber];
   }
 
-  /// Determines whether the given source [offset] comes just after an opener
-  /// ('(', '[', or '{').
-  bool _isJustAfterOpener(int offset) =>
-      offset > 0 && const ['(', '[', '{'].contains(sourceText[offset - 1]);
+  /// Determines whether the given source [offset] comes just after one of the
+  /// characters in [characters].
+  bool _isJustAfter(int offset, List<String> characters) =>
+      offset > 0 && characters.contains(sourceText[offset - 1]);
 
-  /// Determines whether the given source [end] comes just before a closer
-  /// (')', ']', or '}').
-  bool _isJustBeforeCloser(int end) =>
-      end < sourceText.length &&
-      const [')', ']', '}'].contains(sourceText[end]);
+  /// Determines whether the given source [end] comes just before one of the
+  /// characters in [characters].
+  bool _isJustBefore(int end, List<String> characters) =>
+      end < sourceText.length && characters.contains(sourceText[end]);
+
+  /// Determines whether the given source [end] comes just before whitespace.
+  /// For the purpose of this check, the end of the file is considered
+  /// whitespace.
+  bool _isJustBeforeWhitespace(int end) =>
+      end >= sourceText.length || _isWhitespaceRange(end, end + 1);
 
   /// Determines if the characters between [offset] and [end] in the source text
   /// are all whitespace characters.
@@ -670,6 +779,14 @@
     return sourceText.substring(offset, end).trimRight().isEmpty;
   }
 
+  int _offsetForChanges(Map<int, List<AtomicEdit>> changes) {
+    int result;
+    for (var key in changes.keys) {
+      if (result == null || key < result) result = key;
+    }
+    return result;
+  }
+
   /// If the given [node] maintains a variable-length sequence of child nodes,
   /// returns a list containing those child nodes, otherwise returns `null`.
   ///
@@ -715,11 +832,17 @@
 
   NodeProducingEditPlan._(this.sourceNode) : super._();
 
+  /// Offset just past the end of the source text affected by this plan.
+  int get end => sourceNode.end;
+
   /// If the result of executing this [EditPlan] will be an expression,
   /// indicates whether the expression will end in an unparenthesized cascade.
   @visibleForTesting
   bool get endsInCascade;
 
+  /// Offset of the start of the source text affected by this plan.
+  int get offset => sourceNode.offset;
+
   @override
   AstNode get parentNode => sourceNode.parent;
 
@@ -748,8 +871,8 @@
   Map<int, List<AtomicEdit>> _createAddParenChanges(
       Map<int, List<AtomicEdit>> changes) {
     changes ??= {};
-    (changes[sourceNode.offset] ??= []).insert(0, const AtomicEdit.insert('('));
-    (changes[sourceNode.end] ??= []).add(const AtomicEdit.insert(')'));
+    (changes[offset] ??= []).insert(0, const AtomicEdit.insert('('));
+    (changes[end] ??= []).add(const AtomicEdit.insert(')'));
     return changes;
   }
 
@@ -784,6 +907,28 @@
   NodeProducingEditPlan finish(EditPlanner planner);
 }
 
+/// [EditPlan] that wraps an inner plan with optional prefix and suffix changes.
+class _CommentAffixPlan extends _NestedEditPlan {
+  Map<int, List<AtomicEdit>> _prefixChanges;
+
+  Map<int, List<AtomicEdit>> _postfixChanges;
+
+  @override
+  int offset;
+
+  @override
+  int end;
+
+  _CommentAffixPlan(NodeProducingEditPlan innerPlan)
+      : offset = innerPlan.offset,
+        end = innerPlan.end,
+        super(innerPlan.sourceNode, innerPlan);
+
+  @override
+  Map<int, List<AtomicEdit>> _getChanges(bool parens) =>
+      _prefixChanges + innerPlan._getChanges(parens) + _postfixChanges;
+}
+
 /// Visitor that determines whether a given [AstNode] ends in a cascade.
 class _EndsInCascadeVisitor extends UnifyingAstVisitor<void> {
   bool endsInCascade = false;
@@ -829,16 +974,16 @@
     // Extract the inner expression.
     // TODO(paulberry): don't remove comments
     changes = _removeCode(
-            sourceNode.offset,
-            innerPlan.sourceNode.offset,
+            offset,
+            innerPlan.offset,
             _planner.removeViaComments
                 ? _RemovalStyle.commentSpace
                 : _RemovalStyle.delete,
             _infoBefore) +
         changes +
         _removeCode(
-            innerPlan.sourceNode.end,
-            sourceNode.end,
+            innerPlan.end,
+            end,
             _planner.removeViaComments
                 ? _RemovalStyle.spaceComment
                 : _RemovalStyle.delete,
@@ -1203,6 +1348,9 @@
       }
     }
     changes += innerPlan._getChanges(parensNeeded);
+    // Note: we use innerPlan.sourceNode.end here instead of innerPlan.end,
+    // because what we care about is the input grammar, so we don't want to be
+    // fooled by any whitespace or comments included in the innerPlan.
     if (endsInCascade == null && innerPlan.sourceNode.end == node.end) {
       endsInCascade = !parensNeeded && innerPlan.endsInCascade;
     }
@@ -1255,10 +1403,12 @@
         // that we're left with just `()`, `{}`, or `[]`.
         var candidateFirstRemovalOffset =
             planner._backAcrossWhitespace(firstRemovalOffset, node.offset);
-        if (planner._isJustAfterOpener(candidateFirstRemovalOffset)) {
+        if (planner
+            ._isJustAfter(candidateFirstRemovalOffset, const ['(', '[', '{'])) {
           var candidateLastRemovalEnd =
               planner._forwardAcrossWhitespace(lastRemovalEnd, node.end);
-          if (planner._isJustBeforeCloser(candidateLastRemovalEnd)) {
+          if (planner
+              ._isJustBefore(candidateLastRemovalEnd, const [')', ']', '}'])) {
             firstRemovalOffset = candidateFirstRemovalOffset;
             lastRemovalEnd = candidateLastRemovalEnd;
           }
@@ -1415,8 +1565,8 @@
     var changes = innerPlan._getChanges(false);
     if (!parens) {
       changes ??= {};
-      (changes[sourceNode.offset] ??= []).insert(0, const AtomicEdit.delete(1));
-      (changes[sourceNode.end - 1] ??= []).add(const AtomicEdit.delete(1));
+      (changes[offset] ??= []).insert(0, const AtomicEdit.delete(1));
+      (changes[end - 1] ??= []).add(const AtomicEdit.delete(1));
     }
     return changes;
   }
diff --git a/pkg/nnbd_migration/lib/src/expression_checks.dart b/pkg/nnbd_migration/lib/src/expression_checks.dart
index 17d4459..9379c9d 100644
--- a/pkg/nnbd_migration/lib/src/expression_checks.dart
+++ b/pkg/nnbd_migration/lib/src/expression_checks.dart
@@ -4,12 +4,10 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/edge_origin.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
-import 'package:nnbd_migration/src/potential_modification.dart';
 
 /// Container for information gathered during nullability migration about the
 /// set of runtime checks that might need to be performed on the value of an
@@ -19,60 +17,11 @@
 /// based on the nullability of the type itself (which can be checked by adding
 /// a trailing `!`) from checks based on type parameters (which will have to be
 /// checked using an `as` expression).
-class ExpressionChecks extends PotentialModification {
-  /// Source offset where a trailing `!` might need to be inserted.
-  final int offset;
+class ExpressionChecks {
+  /// All nullability edges that are related to this potential check.
+  final Map<FixReasonTarget, NullabilityEdge> edges = {};
 
-  /// List of all nullability edges that are related to this potential check.
-  ///
-  /// TODO(paulberry): update this data structure to keep track of all the ways
-  /// in which edges can be related to an [ExpressionChecks], including:
-  ///
-  /// - An edge which, if unsatisfied, indicates that the expression needs to be
-  ///   null-checked.
-  /// - An edge which, if unsatisfied, indicates that a type parameter of the
-  ///   expression needs to be checked for nullability (e.g. by the migration
-  ///   engine inserting a test like `as List<int>?`)
-  /// - An edge which, if unsatisfied, indicates that a return type of the
-  ///   expression needs to be checked for nullability (e.g. by the migration
-  ///   engine inserting a test like `as int Function(...)?`)
-  /// - An edge which, if unsatisfied, indicates that a parameter type of the
-  ///   expression needs to be checked for nullability (e.g. by the migration
-  ///   engine inserting a test like `as void Function(int?)?`)
-  ///
-  /// ...and so on.
-  final List<NullabilityEdge> edges = [];
-
-  ExpressionChecks(this.offset);
-
-  @override
-  NullabilityFixDescription get description =>
-      NullabilityFixDescription.checkExpression;
-
-  @override
-  bool get isEmpty {
-    for (var edge in edges) {
-      if (!edge.isSatisfied) return false;
-    }
-    return true;
-  }
-
-  @override
-  Iterable<SourceEdit> get modifications {
-    // TODO(paulberry): this assumes that the check that needs to be done is for
-    // the nullability of the type itself (in which case all we need is a simple
-    // null check).  Need to support checks that will have to be addressed by
-    // adding an `as` expression, e.g. `as List<int>?` to verify that a list is
-    // reified to contain only non-null ints.
-    return isEmpty ? [] : [SourceEdit(offset, 0, '!')];
-  }
-
-  @override
-  Iterable<FixReasonInfo> get reasons sync* {
-    for (var edge in edges) {
-      if (!edge.isSatisfied) yield edge;
-    }
-  }
+  ExpressionChecks();
 }
 
 /// [EdgeOrigin] object associated with [ExpressionChecks].  This is a separate
@@ -82,7 +31,13 @@
 class ExpressionChecksOrigin extends EdgeOrigin {
   final ExpressionChecks checks;
 
-  ExpressionChecksOrigin(Source source, Expression node, this.checks)
+  /// Whether the origin of the edge is due to the assignment of a variable
+  /// from within function literal argument to the `setUp` function of the test
+  /// package.
+  final bool isSetupAssignment;
+
+  ExpressionChecksOrigin(Source source, Expression node, this.checks,
+      {this.isSetupAssignment = false})
       : super(source, node);
 
   @override
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index 5a77827..ba4452c 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -9,11 +9,13 @@
 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:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
 import 'package:nnbd_migration/src/fix_builder.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 
 /// Visitor that combines together the changes produced by [FixBuilder] into a
 /// concrete set of source code edits using the infrastructure of [EditPlan].
@@ -31,7 +33,9 @@
   /// refers to it.
   final Map<LibraryElement, String> _importPrefixes = {};
 
-  FixAggregator._(this.planner, this._changes,
+  final bool _warnOnWeakCode;
+
+  FixAggregator._(this.planner, this._changes, this._warnOnWeakCode,
       CompilationUnitElement compilationUnitElement) {
     for (var importElement in compilationUnitElement.library.imports) {
       // TODO(paulberry): the `??=` should ensure that if there are two imports,
@@ -173,10 +177,11 @@
   /// Runs the [FixAggregator] on a [unit] and returns the resulting edits.
   static Map<int, List<AtomicEdit>> run(
       CompilationUnit unit, String sourceText, Map<AstNode, NodeChange> changes,
-      {bool removeViaComments: false}) {
+      {bool removeViaComments = true, bool warnOnWeakCode = false}) {
     var planner = EditPlanner(unit.lineInfo, sourceText,
         removeViaComments: removeViaComments);
-    var aggregator = FixAggregator._(planner, changes, unit.declaredElement);
+    var aggregator =
+        FixAggregator._(planner, changes, warnOnWeakCode, unit.declaredElement);
     unit.accept(aggregator);
     if (aggregator._plans.isEmpty) return {};
     EditPlan plan;
@@ -189,6 +194,17 @@
   }
 }
 
+/// Reasons that a variable declaration is to be made late.
+enum LateAdditionReason {
+  /// It was inferred that the associated variable declaration is to be made
+  /// late through the late-inferring algorithm.
+  inference,
+
+  /// It was inferred that the associated variable declaration is to be made
+  /// late, because it is a test variable which is assigned during setup.
+  testVariableInference,
+}
+
 /// Base class representing a kind of change that [FixAggregator] might make to
 /// a particular AST node.
 abstract class NodeChange<N extends AstNode> {
@@ -198,6 +214,11 @@
   /// information.
   bool get isInformative => false;
 
+  Iterable<String> get _toStringParts => const [];
+
+  @override
+  toString() => '$runtimeType(${_toStringParts.join(', ')})';
+
   /// Applies this change to the given [node], producing an [EditPlan].  The
   /// [aggregator] may be used to gather up any edits to the node's descendants
   /// into their own [EditPlan]s.
@@ -230,6 +251,10 @@
   NodeChangeForAnnotation() : super._();
 
   @override
+  Iterable<String> get _toStringParts =>
+      [if (changeToRequiredKeyword) 'changeToRequiredKeyword'];
+
+  @override
   EditPlan _apply(Annotation node, FixAggregator aggregator) {
     if (!changeToRequiredKeyword) {
       return aggregator.innerPlanForNode(node);
@@ -260,12 +285,16 @@
   bool removeAs = false;
 
   @override
+  Iterable<String> get _toStringParts =>
+      [...super._toStringParts, if (removeAs) 'removeAs'];
+
+  @override
   EditPlan _apply(AsExpression node, FixAggregator aggregator) {
     if (removeAs) {
       return aggregator.planner.extract(node,
           aggregator.planForNode(node.expression) as NodeProducingEditPlan,
           infoAfter:
-              AtomicEditInfo(NullabilityFixDescription.removeAs, const []));
+              AtomicEditInfo(NullabilityFixDescription.removeAs, const {}));
     } else {
       return super._apply(node, aggregator);
     }
@@ -273,6 +302,95 @@
 }
 
 /// Implementation of [NodeChange] specialized for operating on
+/// [AssignmentExpression] nodes.
+class NodeChangeForAssignment
+    extends NodeChangeForExpression<AssignmentExpression>
+    with NodeChangeForAssignmentLike {
+  /// Indicates whether the user should be warned that the assignment is a
+  /// null-aware assignment that will have no effect when strong checking is
+  /// enabled.
+  bool isWeakNullAware = false;
+
+  @override
+  Iterable<String> get _toStringParts =>
+      [...super._toStringParts, if (isWeakNullAware) 'isWeakNullAware'];
+
+  @override
+  NodeProducingEditPlan _apply(
+      AssignmentExpression node, FixAggregator aggregator) {
+    var lhsPlan = aggregator.planForNode(node.leftHandSide);
+    if (isWeakNullAware && !aggregator._warnOnWeakCode) {
+      // Just keep the LHS
+      return aggregator.planner.extract(node, lhsPlan as NodeProducingEditPlan,
+          infoAfter: AtomicEditInfo(
+              NullabilityFixDescription.removeNullAwareAssignment, const {}));
+    }
+    var operatorPlan = _makeOperatorPlan(aggregator, node, node.operator);
+    var rhsPlan = aggregator.planForNode(node.rightHandSide);
+    var innerPlans = <EditPlan>[
+      lhsPlan,
+      if (operatorPlan != null) operatorPlan,
+      rhsPlan
+    ];
+    return _applyExpression(aggregator,
+        aggregator.planner.passThrough(node, innerPlans: innerPlans));
+  }
+
+  EditPlan _makeOperatorPlan(
+      FixAggregator aggregator, AssignmentExpression node, Token operator) {
+    var operatorPlan = super._makeOperatorPlan(aggregator, node, operator);
+    if (operatorPlan != null) return operatorPlan;
+    if (isWeakNullAware) {
+      assert(aggregator._warnOnWeakCode);
+      return aggregator.planner.informativeMessageForToken(node, operator,
+          info: AtomicEditInfo(
+              NullabilityFixDescription
+                  .nullAwareAssignmentUnnecessaryInStrongMode,
+              const {}));
+    } else {
+      return null;
+    }
+  }
+}
+
+/// Common behaviors for expressions that can represent an assignment (possibly
+/// through desugaring).
+mixin NodeChangeForAssignmentLike<N extends Expression>
+    on NodeChangeForExpression<N> {
+  /// Indicates whether the user should be warned that the assignment has a
+  /// bad combined type (the return type of the combiner isn't assignable to the
+  /// write type of the target).
+  bool hasBadCombinedType = false;
+
+  /// Indicates whether the user should be warned that the assignment has a
+  /// nullable source type.
+  bool hasNullableSource = false;
+
+  @override
+  Iterable<String> get _toStringParts => [
+        ...super._toStringParts,
+        if (hasBadCombinedType) 'hasBadCombinedType',
+        if (hasNullableSource) 'hasNullableSource'
+      ];
+
+  EditPlan _makeOperatorPlan(FixAggregator aggregator, N node, Token operator) {
+    if (hasNullableSource) {
+      return aggregator.planner.informativeMessageForToken(node, operator,
+          info: AtomicEditInfo(
+              NullabilityFixDescription.compoundAssignmentHasNullableSource,
+              const {}));
+    } else if (hasBadCombinedType) {
+      return aggregator.planner.informativeMessageForToken(node, operator,
+          info: AtomicEditInfo(
+              NullabilityFixDescription.compoundAssignmentHasBadCombinedType,
+              const {}));
+    } else {
+      return null;
+    }
+  }
+}
+
+/// Implementation of [NodeChange] specialized for operating on
 /// [CompilationUnit] nodes.
 class NodeChangeForCompilationUnit extends NodeChange<CompilationUnit> {
   bool removeLanguageVersionComment = false;
@@ -280,15 +398,19 @@
   NodeChangeForCompilationUnit() : super._();
 
   @override
+  Iterable<String> get _toStringParts =>
+      [if (removeLanguageVersionComment) 'removeLanguageVersionComment'];
+
+  @override
   EditPlan _apply(CompilationUnit node, FixAggregator aggregator) {
     List<EditPlan> innerPlans = [];
     if (removeLanguageVersionComment) {
       final comment = (node as CompilationUnitImpl).languageVersionToken;
       assert(comment != null);
-      innerPlans.add(aggregator.planner.replaceToken(node, comment, [],
+      innerPlans.add(aggregator.planner.replaceToken(node, comment, '',
           info: AtomicEditInfo(
               NullabilityFixDescription.removeLanguageVersionComment,
-              const [])));
+              const {})));
     }
     innerPlans.addAll(aggregator.innerPlansForNode(node));
     return aggregator.planner.passThrough(node, innerPlans: innerPlans);
@@ -304,16 +426,36 @@
   /// conditional is dead code and should be eliminated.
   bool conditionValue;
 
-  /// If [conditionValue] is not `null`, the reasons that should be included in
+  /// If [conditionValue] is not `null`, the reason that should be included in
   /// the [AtomicEditInfo] for the edit that removes the dead code.
-  List<FixReasonInfo> conditionReasons;
+  FixReasonInfo conditionReason;
+
+  @override
+  Iterable<String> get _toStringParts =>
+      [...super._toStringParts, if (conditionValue != null) 'conditionValue'];
 
   /// If dead code removal is warranted for [node], returns an [EditPlan] that
   /// removes the dead code (and performs appropriate updates within any
   /// descendant AST nodes that remain).  Otherwise returns `null`.
-  EditPlan _applyConditional(
-      N node, FixAggregator aggregator, AstNode thenNode, AstNode elseNode) {
+  EditPlan _applyConditional(N node, FixAggregator aggregator,
+      AstNode conditionNode, AstNode thenNode, AstNode elseNode) {
     if (conditionValue == null) return null;
+    if (aggregator._warnOnWeakCode) {
+      var conditionPlan = aggregator.innerPlanForNode(conditionNode);
+      var info = AtomicEditInfo(
+          conditionValue
+              ? NullabilityFixDescription.conditionTrueInStrongMode
+              : NullabilityFixDescription.conditionFalseInStrongMode,
+          {FixReasonTarget.root: conditionReason});
+      var commentedConditionPlan = aggregator.planner.addCommentPostfix(
+          conditionPlan, '/* == $conditionValue */',
+          info: info, isInformative: true);
+      return aggregator.planner.passThrough(node, innerPlans: [
+        commentedConditionPlan,
+        aggregator.planForNode(thenNode),
+        if (elseNode != null) aggregator.planForNode(elseNode)
+      ]);
+    }
     AstNode nodeToKeep;
     NullabilityFixDescription descriptionBefore, descriptionAfter;
     if (conditionValue) {
@@ -333,8 +475,8 @@
         nodeToKeep is Block && nodeToKeep.statements.isEmpty) {
       // The conditional node collapses to a no-op, so try to remove it
       // entirely.
-      var info =
-          AtomicEditInfo(NullabilityFixDescription.discardIf, conditionReasons);
+      var info = AtomicEditInfo(NullabilityFixDescription.discardIf,
+          {FixReasonTarget.root: conditionReason});
       var removeNode = aggregator.planner.tryRemoveNode(node, info: info);
       if (removeNode != null) {
         return removeNode;
@@ -357,8 +499,10 @@
         }
       }
     }
-    var infoBefore = AtomicEditInfo(descriptionBefore, conditionReasons);
-    var infoAfter = AtomicEditInfo(descriptionAfter, conditionReasons);
+    var infoBefore = AtomicEditInfo(
+        descriptionBefore, {FixReasonTarget.root: conditionReason});
+    var infoAfter = AtomicEditInfo(
+        descriptionAfter, {FixReasonTarget.root: conditionReason});
     if (nodeToKeep is Block && nodeToKeep.statements.length == 1) {
       var singleStatement = (nodeToKeep as Block).statements[0];
       if (singleStatement is VariableDeclarationStatement) {
@@ -381,8 +525,8 @@
     with NodeChangeForConditional {
   @override
   EditPlan _apply(ConditionalExpression node, FixAggregator aggregator) {
-    return _applyConditional(
-            node, aggregator, node.thenExpression, node.elseExpression) ??
+    return _applyConditional(node, aggregator, node.condition,
+            node.thenExpression, node.elseExpression) ??
         super._apply(node, aggregator);
   }
 }
@@ -401,6 +545,10 @@
   NodeChangeForDefaultFormalParameter() : super._();
 
   @override
+  Iterable<String> get _toStringParts =>
+      [if (addRequiredKeyword) 'addRequiredKeyword'];
+
+  @override
   EditPlan _apply(DefaultFormalParameter node, FixAggregator aggregator) {
     var innerPlan = aggregator.innerPlanForNode(node);
     if (!addRequiredKeyword) return innerPlan;
@@ -416,6 +564,8 @@
 
   AtomicEditInfo _addNullCheckInfo;
 
+  HintComment _addNullCheckHint;
+
   DartType _introducesAsType;
 
   AtomicEditInfo _introduceAsInfo;
@@ -428,11 +578,25 @@
   /// 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 (_addsNullCheck) 'addsNullCheck',
+        if (_introducesAsType != null) 'introducesAsType'
+      ];
+
   /// Causes a null check to be added to this expression, with the given [info].
-  void addNullCheck(AtomicEditInfo 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
@@ -457,8 +621,14 @@
       FixAggregator aggregator, NodeProducingEditPlan innerPlan) {
     var plan = innerPlan;
     if (_addsNullCheck) {
-      plan = aggregator.planner
-          .addUnaryPostfix(plan, TokenType.BANG, info: _addNullCheckInfo);
+      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 (_introducesAsType != null) {
       plan = aggregator.planner.addBinaryPostfix(
@@ -477,8 +647,8 @@
 
   @override
   EditPlan _apply(IfElement node, FixAggregator aggregator) {
-    return _applyConditional(
-            node, aggregator, node.thenElement, node.elseElement) ??
+    return _applyConditional(node, aggregator, node.condition, node.thenElement,
+            node.elseElement) ??
         aggregator.innerPlanForNode(node);
   }
 }
@@ -491,8 +661,8 @@
 
   @override
   EditPlan _apply(IfStatement node, FixAggregator aggregator) {
-    return _applyConditional(
-            node, aggregator, node.thenStatement, node.elseStatement) ??
+    return _applyConditional(node, aggregator, node.condition,
+            node.thenStatement, node.elseStatement) ??
         aggregator.innerPlanForNode(node);
   }
 }
@@ -531,13 +701,58 @@
   /// Indicates whether null-awareness should be removed.
   bool removeNullAwareness = false;
 
+  @override
+  Iterable<String> get _toStringParts =>
+      [...super._toStringParts, if (removeNullAwareness) 'removeNullAwareness'];
+
   /// Returns an [EditPlan] that removes null awareness, if appropriate.
   /// Otherwise returns `null`.
   EditPlan _applyNullAware(N node, FixAggregator aggregator) {
     if (!removeNullAwareness) return null;
+    var description = aggregator._warnOnWeakCode
+        ? NullabilityFixDescription.nullAwarenessUnnecessaryInStrongMode
+        : NullabilityFixDescription.removeNullAwareness;
     return aggregator.planner.removeNullAwareness(node,
-        info:
-            AtomicEditInfo(NullabilityFixDescription.removeNullAwareness, []));
+        info: AtomicEditInfo(description, const {}),
+        isInformative: aggregator._warnOnWeakCode);
+  }
+}
+
+/// Implementation of [NodeChange] specialized for operating on
+/// [PostfixExpression] nodes.
+class NodeChangeForPostfixExpression
+    extends NodeChangeForExpression<PostfixExpression>
+    with NodeChangeForAssignmentLike {
+  @override
+  NodeProducingEditPlan _apply(
+      PostfixExpression node, FixAggregator aggregator) {
+    var operandPlan = aggregator.planForNode(node.operand);
+    var operatorPlan = _makeOperatorPlan(aggregator, node, node.operator);
+    var innerPlans = <EditPlan>[
+      operandPlan,
+      if (operatorPlan != null) operatorPlan
+    ];
+    return _applyExpression(aggregator,
+        aggregator.planner.passThrough(node, innerPlans: innerPlans));
+  }
+}
+
+/// Implementation of [NodeChange] specialized for operating on
+/// [PrefixExpression] nodes.
+class NodeChangeForPrefixExpression
+    extends NodeChangeForExpression<PrefixExpression>
+    with NodeChangeForAssignmentLike {
+  @override
+  NodeProducingEditPlan _apply(
+      PrefixExpression node, FixAggregator aggregator) {
+    var operatorPlan = _makeOperatorPlan(aggregator, node, node.operator);
+    var operandPlan = aggregator.planForNode(node.operand);
+    var innerPlans = <EditPlan>[
+      if (operatorPlan != null) operatorPlan,
+      operandPlan
+    ];
+    return _applyExpression(aggregator,
+        aggregator.planner.passThrough(node, innerPlans: innerPlans));
   }
 }
 
@@ -573,6 +788,10 @@
   NodeChangeForSimpleFormalParameter() : super._();
 
   @override
+  Iterable<String> get _toStringParts =>
+      [if (addExplicitType != null) 'addExplicitType'];
+
+  @override
   EditPlan _apply(SimpleFormalParameter node, FixAggregator aggregator) {
     var innerPlan = aggregator.innerPlanForNode(node);
     if (addExplicitType == null) return innerPlan;
@@ -587,37 +806,78 @@
 /// Implementation of [NodeChange] specialized for operating on [TypeAnnotation]
 /// nodes.
 class NodeChangeForTypeAnnotation extends NodeChange<TypeAnnotation> {
-  /// Indicates whether the type should be made nullable by adding a `?`.
-  bool makeNullable = false;
+  bool _makeNullable = false;
+
+  HintComment _nullabilityHint;
 
   /// The decorated type of the type annotation, or `null` if there is no
   /// decorated type info of interest.  If [makeNullable] is `true`, the node
   /// from this type will be attached to the edit that adds the `?`. If
-  /// [makeNullable] is `false`, the node from this type will be attached to the
+  /// [_makeNullable] is `false`, the node from this type will be attached to the
   /// information about why the node wasn't made nullable.
-  DecoratedType decoratedType;
+  DecoratedType _decoratedType;
 
   NodeChangeForTypeAnnotation() : super._();
 
   @override
-  bool get isInformative => !makeNullable;
+  bool get isInformative => !_makeNullable;
+
+  /// Indicates whether the type should be made nullable by adding a `?`.
+  bool get makeNullable => _makeNullable;
+
+  /// If we are making the type nullable due to a hint, the comment that caused
+  /// it.
+  HintComment get nullabilityHint => _nullabilityHint;
+
+  @override
+  Iterable<String> get _toStringParts => [
+        if (_makeNullable) 'makeNullable',
+        if (_nullabilityHint != null) 'nullabilityHint'
+      ];
+
+  void recordNullability(DecoratedType decoratedType, bool makeNullable,
+      {HintComment nullabilityHint}) {
+    _decoratedType = decoratedType;
+    _makeNullable = makeNullable;
+    _nullabilityHint = nullabilityHint;
+  }
 
   @override
   EditPlan _apply(TypeAnnotation node, FixAggregator aggregator) {
     var innerPlan = aggregator.innerPlanForNode(node);
-    if (decoratedType == null) return innerPlan;
-    if (makeNullable) {
-      return aggregator.planner.makeNullable(innerPlan,
-          info: AtomicEditInfo(
-              NullabilityFixDescription.makeTypeNullable(
-                  decoratedType.type.getDisplayString(withNullability: false)),
-              [decoratedType.node]));
+    if (_decoratedType == null) return innerPlan;
+    var typeName = _decoratedType.type.getDisplayString(withNullability: false);
+    var fixReasons = {FixReasonTarget.root: _decoratedType.node};
+    if (_makeNullable) {
+      var hint = _nullabilityHint;
+      if (hint != null) {
+        return aggregator.planner.acceptNullabilityOrNullCheckHint(
+            innerPlan, hint,
+            info: AtomicEditInfo(
+                NullabilityFixDescription.makeTypeNullableDueToHint(typeName),
+                fixReasons,
+                hintComment: hint));
+      } else {
+        return aggregator.planner.makeNullable(innerPlan,
+            info: AtomicEditInfo(
+                NullabilityFixDescription.makeTypeNullable(typeName),
+                fixReasons));
+      }
     } else {
-      return aggregator.planner.explainNonNullable(innerPlan,
-          info: AtomicEditInfo(
-              NullabilityFixDescription.typeNotMadeNullable(
-                  decoratedType.type.getDisplayString(withNullability: false)),
-              [decoratedType.node]));
+      var hint = _nullabilityHint;
+      if (hint != null) {
+        return aggregator.planner.dropNullabilityHint(innerPlan, hint,
+            info: AtomicEditInfo(
+                NullabilityFixDescription.typeNotMadeNullableDueToHint(
+                    typeName),
+                fixReasons,
+                hintComment: hint));
+      } else {
+        return aggregator.planner.explainNonNullable(innerPlan,
+            info: AtomicEditInfo(
+                NullabilityFixDescription.typeNotMadeNullable(typeName),
+                fixReasons));
+      }
     }
   }
 }
@@ -631,34 +891,59 @@
   DartType addExplicitType;
 
   /// Indicates whether a "late" annotation should be added to this variable
-  /// declaration.
-  bool addLate = false;
+  /// declaration, caused by inference.
+  LateAdditionReason lateAdditionReason;
+
+  /// If a "late" annotation should be added to this variable declaration, and
+  /// the cause is a "late" hint, the hint that caused it.  Otherwise `null`.
+  HintComment lateHint;
 
   NodeChangeForVariableDeclarationList() : super._();
 
   @override
+  Iterable<String> get _toStringParts => [
+        if (addExplicitType != null) 'addExplicitType',
+        if (lateAdditionReason != null) 'lateAdditionReason',
+        if (lateHint != null) 'lateHint'
+      ];
+
+  @override
   EditPlan _apply(VariableDeclarationList node, FixAggregator aggregator) {
     List<EditPlan> innerPlans = [];
-    if (addLate) {
+    if (lateAdditionReason != null) {
+      var description = lateAdditionReason == LateAdditionReason.inference
+          ? NullabilityFixDescription.addLate
+          : NullabilityFixDescription.addLateDueToTestSetup;
+      var info = AtomicEditInfo(description, {});
       innerPlans.add(aggregator.planner.insertText(
           node,
           node.firstTokenAfterCommentAndMetadata.offset,
-          [AtomicEdit.insert('late'), AtomicEdit.insert(' ')]));
+          [AtomicEdit.insert('late', info: info), AtomicEdit.insert(' ')]));
     }
     if (addExplicitType != null) {
       var typeText = addExplicitType.getDisplayString(withNullability: true);
       if (node.keyword?.keyword == Keyword.VAR) {
+        var info =
+            AtomicEditInfo(NullabilityFixDescription.replaceVar(typeText), {});
         innerPlans.add(aggregator.planner
-            .replaceToken(node, node.keyword, [AtomicEdit.insert(typeText)]));
+            .replaceToken(node, node.keyword, typeText, info: info));
       } else {
+        var info =
+            AtomicEditInfo(NullabilityFixDescription.addType(typeText), {});
         innerPlans.add(aggregator.planner.insertText(
             node,
             node.variables.first.offset,
-            [AtomicEdit.insert(typeText), AtomicEdit.insert(' ')]));
+            [AtomicEdit.insert(typeText, info: info), AtomicEdit.insert(' ')]));
       }
     }
     innerPlans.addAll(aggregator.innerPlansForNode(node));
-    return aggregator.planner.passThrough(node, innerPlans: innerPlans);
+    var plan = aggregator.planner.passThrough(node, innerPlans: innerPlans);
+    if (lateHint != null) {
+      plan = aggregator.planner.acceptLateHint(plan, lateHint,
+          info: AtomicEditInfo(NullabilityFixDescription.addLateDueToHint, {},
+              hintComment: lateHint));
+    }
+    return plan;
   }
 }
 
@@ -675,10 +960,18 @@
       NodeChangeForAsExpression();
 
   @override
+  NodeChange visitAssignmentExpression(AssignmentExpression node) =>
+      NodeChangeForAssignment();
+
+  @override
   NodeChange visitCompilationUnit(CompilationUnit node) =>
       NodeChangeForCompilationUnit();
 
   @override
+  NodeChange visitConditionalExpression(ConditionalExpression node) =>
+      NodeChangeForConditionalExpression();
+
+  @override
   NodeChange visitDefaultFormalParameter(DefaultFormalParameter node) =>
       NodeChangeForDefaultFormalParameter();
 
@@ -704,6 +997,14 @@
       throw StateError('Unexpected node type: ${node.runtimeType}');
 
   @override
+  NodeChange visitPostfixExpression(PostfixExpression node) =>
+      NodeChangeForPostfixExpression();
+
+  @override
+  NodeChange visitPrefixExpression(PrefixExpression node) =>
+      NodeChangeForPrefixExpression();
+
+  @override
   NodeChange visitPropertyAccess(PropertyAccess node) =>
       NodeChangeForPropertyAccess();
 
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index ae684e3..19128d2 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -25,6 +25,8 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/strong/checker.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
@@ -32,10 +34,21 @@
 import 'package:nnbd_migration/src/edit_plan.dart';
 import 'package:nnbd_migration/src/fix_aggregator.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
 import 'package:nnbd_migration/src/variables.dart';
 
+bool _isIncrementOrDecrementOperator(TokenType tokenType) {
+  switch (tokenType) {
+    case TokenType.PLUS_PLUS:
+    case TokenType.MINUS_MINUS:
+      return true;
+    default:
+      return false;
+  }
+}
+
 /// Problem reported by [FixBuilder] when encountering a compound assignment
 /// for which the combination result is nullable.  This occurs if the compound
 /// assignment resolves to a user-defined operator that returns a nullable type,
@@ -99,6 +112,10 @@
   /// that type should be.
   final Map<ParameterElement, DartType> _addedParameterTypes = {};
 
+  final bool warnOnWeakCode;
+
+  final NullabilityGraph _graph;
+
   factory FixBuilder(
       Source source,
       DecoratedClassHierarchy decoratedClassHierarchy,
@@ -107,7 +124,9 @@
       Variables variables,
       LibraryElement definingLibrary,
       NullabilityMigrationListener listener,
-      CompilationUnit unit) {
+      CompilationUnit unit,
+      bool warnOnWeakCode,
+      NullabilityGraph graph) {
     var migrationResolutionHooks = MigrationResolutionHooksImpl();
     return FixBuilder._(
         decoratedClassHierarchy,
@@ -120,7 +139,9 @@
         definingLibrary,
         listener,
         unit,
-        migrationResolutionHooks);
+        migrationResolutionHooks,
+        warnOnWeakCode,
+        graph);
   }
 
   FixBuilder._(
@@ -131,7 +152,9 @@
       LibraryElement definingLibrary,
       this.listener,
       this.unit,
-      this.migrationResolutionHooks)
+      this.migrationResolutionHooks,
+      this.warnOnWeakCode,
+      this._graph)
       : typeProvider = _typeSystem.typeProvider {
     migrationResolutionHooks._fixBuilder = this;
     // TODO(paulberry): make use of decoratedClassHierarchy
@@ -276,6 +299,9 @@
 
   final Expando<bool> _shouldStayNullAware = Expando();
 
+  final Map<Expression, _AssignmentLikeExpressionHandler>
+      _assignmentLikeExpressionHandlers = {};
+
   FlowAnalysis<AstNode, Statement, Expression, PromotableElement, DartType>
       _flowAnalysis;
 
@@ -301,14 +327,28 @@
           var conditionValue = conditionalDiscard.keepTrue;
           (_fixBuilder._getChange(node) as NodeChangeForConditional)
             ..conditionValue = conditionValue
-            ..conditionReasons = conditionalDiscard.reasons.toList();
-          return conditionValue;
+            ..conditionReason = conditionalDiscard.reason;
+          // If we're just issuing warnings, instruct the resolver to go ahead
+          // and visit both branches of the conditional.
+          return _fixBuilder.warnOnWeakCode ? null : conditionValue;
         }
       });
 
   @override
-  List<ParameterElement> getExecutableParameters(ExecutableElement element) =>
-      getExecutableType(element as ElementImplWithFunctionType).parameters;
+  List<ParameterElement> getExecutableParameters(
+      ExecutableElementImpl element) {
+    if (_fixBuilder._graph.isBeingMigrated(element.library.source)) {
+      // The element is part of a library that's being migrated, so its
+      // parameters all have been visited (and thus have their own final
+      // types).  So we don't need to do anything.
+      return const ElementTypeProvider().getExecutableParameters(element);
+    } else {
+      // The element is not part of a library that's being migrated, so its
+      // parameters probably haven't been visited; we need to get the parameters
+      // from the final function type.
+      return getExecutableType(element).parameters;
+    }
+  }
 
   @override
   DartType getExecutableReturnType(Element element) =>
@@ -397,30 +437,25 @@
   @override
   DartType modifyExpressionType(Expression node, DartType type) =>
       _wrapExceptions(node, () => type, () {
-        if (_fixBuilder._variables.hasNullCheckHint(_fixBuilder.source, node)) {
-          type = _addNullCheck(node, type,
-              info: AtomicEditInfo(NullabilityFixDescription.checkExpression,
-                  [FixReason_NullCheckHint(CodeReference.fromAstNode(node))]));
-        }
-        if (type.isDynamic) return type;
-        var ancestor = _findNullabilityContextAncestor(node);
-        var context =
-            InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
-        if (!_fixBuilder._typeSystem.isSubtypeOf(type, context)) {
-          // 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, context);
+        var parent = node.parent;
+        if (parent is AssignmentExpression) {
+          return (_assignmentLikeExpressionHandlers[parent] ??=
+                  _AssignmentExpressionHandler(parent))
+              .modifySubexpressionType(this, node, type);
+        } else if (parent is PrefixExpression) {
+          if (_isIncrementOrDecrementOperator(parent.operator.type)) {
+            return (_assignmentLikeExpressionHandlers[parent] ??=
+                    _PrefixExpressionHandler(parent))
+                .modifySubexpressionType(this, node, type);
+          }
+        } else if (parent is PostfixExpression) {
+          if (_isIncrementOrDecrementOperator(parent.operator.type)) {
+            return (_assignmentLikeExpressionHandlers[parent] ??=
+                    _PostfixExpressionHandler(parent))
+                .modifySubexpressionType(this, node, type);
           }
         }
-        if (!_fixBuilder._typeSystem.isNullable(type)) return type;
-        if (_needsNullCheckDueToStructure(ancestor)) {
-          return _addNullCheck(node, type);
-        }
-        return type;
+        return _modifyRValueType(node, type);
       });
 
   @override
@@ -442,13 +477,17 @@
     _flowAnalysis = flowAnalysis;
   }
 
-  DartType _addCast(Expression node, DartType contextType) {
+  DartType _addCast(
+      Expression node, DartType expressionType, DartType contextType) {
+    var isDowncast =
+        _fixBuilder._typeSystem.isSubtypeOf(contextType, expressionType);
     var checks =
         _fixBuilder._variables.expressionChecks(_fixBuilder.source, node);
-    var info = checks != null
-        ? AtomicEditInfo(
-            NullabilityFixDescription.checkExpression, checks.edges)
-        : null;
+    var info = AtomicEditInfo(
+        isDowncast
+            ? NullabilityFixDescription.downcastExpression
+            : NullabilityFixDescription.otherCastExpression,
+        checks != null ? checks.edges : {});
     (_fixBuilder._getChange(node) as NodeChangeForExpression)
         .introduceAs(contextType, info);
     _flowAnalysis.asExpression_end(node, contextType);
@@ -456,7 +495,7 @@
   }
 
   DartType _addNullCheck(Expression node, DartType type,
-      {AtomicEditInfo info}) {
+      {AtomicEditInfo info, HintComment hint}) {
     var checks =
         _fixBuilder._variables.expressionChecks(_fixBuilder.source, node);
     info ??= checks != null
@@ -464,7 +503,7 @@
             NullabilityFixDescription.checkExpression, checks.edges)
         : null;
     (_fixBuilder._getChange(node) as NodeChangeForExpression)
-        .addNullCheck(info);
+        .addNullCheck(info, hint: hint);
     _flowAnalysis.nonNullAssert_end(node);
     return _fixBuilder._typeSystem.promoteToNonNull(type as TypeImpl);
   }
@@ -482,6 +521,42 @@
     }
   }
 
+  DartType _modifyRValueType(Expression node, DartType type,
+      {DartType context}) {
+    var hint =
+        _fixBuilder._variables.getNullCheckHint(_fixBuilder.source, node);
+    if (hint != null) {
+      type = _addNullCheck(node, type,
+          info: AtomicEditInfo(
+              NullabilityFixDescription.checkExpressionDueToHint,
+              {
+                FixReasonTarget.root:
+                    FixReason_NullCheckHint(CodeReference.fromAstNode(node))
+              },
+              hintComment: hint),
+          hint: hint);
+    }
+    if (type.isDynamic) return type;
+    var ancestor = _findNullabilityContextAncestor(node);
+    context ??=
+        InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
+    if (!_fixBuilder._typeSystem.isSubtypeOf(type, context)) {
+      // 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);
+      }
+    }
+    if (!_fixBuilder._typeSystem.isNullable(type)) return type;
+    if (_needsNullCheckDueToStructure(ancestor)) {
+      return _addNullCheck(node, type);
+    }
+    return type;
+  }
+
   bool _needsNullCheckDueToStructure(Expression node) {
     var parent = node.parent;
     if (parent is BinaryExpression) {
@@ -573,6 +648,143 @@
 /// Common supertype for problems reported by [FixBuilder._addProblem].
 abstract class Problem {}
 
+/// Specialization of [_AssignmentLikeExpressionHandler] for
+/// [AssignmentExpression].
+class _AssignmentExpressionHandler extends _AssignmentLikeExpressionHandler {
+  @override
+  final AssignmentExpression node;
+
+  _AssignmentExpressionHandler(this.node);
+
+  @override
+  MethodElement get combiner => node.staticElement;
+
+  @override
+  TokenType get combinerType => node.operator.type;
+
+  @override
+  Expression get target => node.leftHandSide;
+}
+
+/// Data structure keeping track of intermediate results when the fix builder
+/// is handling an assignment expression, or an expression that desugars to an
+/// assignment.
+abstract class _AssignmentLikeExpressionHandler {
+  /// For compound and null-aware assignments, the type read from the LHS.
+  /*late final*/ DartType readType;
+
+  /// The type that may be written to the LHS.
+  /*late final*/ DartType writeType;
+
+  /// The type that should be used as a context type when inferring the RHS.
+  DartType rhsContextType;
+
+  /// Gets the static element representing the combiner.
+  MethodElement get combiner;
+
+  /// Gets the operator type representing the combiner.
+  TokenType get combinerType;
+
+  /// Gets the expression in question.
+  Expression get node;
+
+  /// Gets the target of the assignment.
+  Expression get target;
+
+  /// Called after visiting the RHS of the assignment, to verify that for
+  /// compound assignments, the return value of the assignment is assignable to
+  /// [writeType].
+  void handleAssignmentRhs(
+      MigrationResolutionHooksImpl hooks, DartType rhsType) {
+    MethodElement combiner = this.combiner;
+    if (combiner != null) {
+      var fixBuilder = hooks._fixBuilder;
+      var combinerReturnType =
+          fixBuilder._typeSystem.refineBinaryExpressionType(
+        readType,
+        combinerType,
+        rhsType,
+        combiner.returnType,
+      );
+      if (!fixBuilder._typeSystem.isSubtypeOf(combinerReturnType, writeType)) {
+        (fixBuilder._getChange(node) as NodeChangeForAssignmentLike)
+            .hasBadCombinedType = true;
+      }
+    }
+  }
+
+  /// Called after visiting the LHS of the assignment.  Records the [readType],
+  /// [writeType], and [rhsContextType].  Also verifies that for compound
+  /// assignments, the [readType] is non-nullable, and that for null-aware
+  /// assignments, the [readType] is nullable.
+  void handleLValueType(
+      MigrationResolutionHooksImpl hooks, DartType resolvedType) {
+    assert(resolvedType.nullabilitySuffix != NullabilitySuffix.star);
+    // Provisionally store the resolved type as the type of the target, so that
+    // getReadType can fall back on it if necessary.
+    var target = this.target;
+    target.staticType = resolvedType;
+    // The type passed in by the resolver for the LHS of an assignment is the
+    // "write type".
+    var writeType = resolvedType;
+    if (target is SimpleIdentifier) {
+      var element = target.staticElement;
+      if (element is PromotableElement) {
+        // However, if the LHS is a reference to a local variable that has
+        // been promoted, the resolver passes in the promoted type.  We
+        // want to use the variable element's type, so that we consider it
+        // ok to assign a value to the variable that un-does the
+        // promotion.  See https://github.com/dart-lang/sdk/issues/41411.
+        writeType = element.type;
+      }
+    }
+    assert(writeType.nullabilitySuffix != NullabilitySuffix.star);
+    this.writeType = writeType;
+    var fixBuilder = hooks._fixBuilder;
+    if (combinerType == TokenType.EQ) {
+      rhsContextType = writeType;
+    } else {
+      readType = getReadType(target);
+      assert(readType.nullabilitySuffix != NullabilitySuffix.star);
+      if (combinerType == TokenType.QUESTION_QUESTION_EQ) {
+        rhsContextType = writeType;
+        if (fixBuilder._typeSystem.isNonNullable(readType)) {
+          (fixBuilder._getChange(node) as NodeChangeForAssignment)
+              .isWeakNullAware = true;
+        }
+      } else {
+        if (!readType.isDynamic &&
+            fixBuilder._typeSystem.isPotentiallyNullable(readType)) {
+          (fixBuilder._getChange(node) as NodeChangeForAssignmentLike)
+              .hasNullableSource = true;
+        }
+      }
+    }
+  }
+
+  /// Called after visiting the LHS or the RHS of the assignment.
+  DartType modifySubexpressionType(MigrationResolutionHooksImpl hooks,
+      Expression subexpression, DartType type) {
+    if (identical(subexpression, target)) {
+      handleLValueType(hooks, type);
+      if (node is! AssignmentExpression) {
+        // Must be a pre or post increment/decrement, so the "RHS" is implicitly
+        // the integer 1.
+        handleAssignmentRhs(hooks, hooks._fixBuilder.typeProvider.intType);
+      }
+      return type;
+    } else {
+      var node = this.node;
+      assert(node is AssignmentExpression &&
+          identical(subexpression, node.rightHandSide));
+      type =
+          hooks._modifyRValueType(subexpression, type, context: rhsContextType);
+      handleAssignmentRhs(hooks, type);
+      return type;
+    }
+  }
+}
+
 /// Visitor that computes additional migrations on behalf of [FixBuilder] that
 /// should be run after resolution
 class _FixBuilderPostVisitor extends GeneralizingAstVisitor<void>
@@ -646,9 +858,35 @@
         }
       }
     }
-    if (_fixBuilder._variables.isLateHinted(source, node)) {
+
+    // Check if the nullability node for a single variable declaration has been
+    // declared to be late.
+    if (node.variables.length == 1) {
+      var variableElement = node.variables.single.declaredElement;
+      var lateCondition = _fixBuilder._variables
+          .decoratedElementType(variableElement)
+          .node
+          .lateCondition;
+      switch (lateCondition) {
+        case LateCondition.possiblyLate:
+          (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
+              .lateAdditionReason = LateAdditionReason.inference;
+          break;
+        case LateCondition.possiblyLateDueToTestSetup:
+          (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
+              .lateAdditionReason = LateAdditionReason.testVariableInference;
+          break;
+        case LateCondition.lateDueToHint:
+        // Handled below.
+        case LateCondition.notLate:
+        // Nothing to do.
+      }
+    }
+
+    var lateHint = _fixBuilder._variables.getLateHint(source, node);
+    if (lateHint != null) {
       (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
-          .addLate = true;
+          .lateHint = lateHint;
     }
     super.visitVariableDeclarationList(node);
   }
@@ -694,9 +932,7 @@
     var decoratedType = _fixBuilder._variables
         .decoratedTypeAnnotation(_fixBuilder.source, node);
     if (!typeIsNonNullableByContext(node)) {
-      (_fixBuilder._getChange(node) as NodeChangeForTypeAnnotation)
-        ..makeNullable = decoratedType.node.isNullable
-        ..decoratedType = decoratedType;
+      _makeTypeNameNullable(node, decoratedType);
     }
     (node as GenericFunctionTypeImpl).type =
         _fixBuilder._variables.toFinalType(decoratedType);
@@ -710,9 +946,7 @@
     if (!typeIsNonNullableByContext(node)) {
       var type = decoratedType.type;
       if (!type.isDynamic && !type.isVoid) {
-        (_fixBuilder._getChange(node) as NodeChangeForTypeAnnotation)
-          ..makeNullable = decoratedType.node.isNullable
-          ..decoratedType = decoratedType;
+        _makeTypeNameNullable(node, decoratedType);
       }
     }
     node.type = _fixBuilder._variables.toFinalType(decoratedType);
@@ -729,7 +963,7 @@
     var info = AtomicEditInfo(
         NullabilityFixDescription.addRequired(
             cls.name, method.name, element.name),
-        [node]);
+        {FixReasonTarget.root: node});
     var metadata = parameter.metadata;
     for (var annotation in metadata) {
       if (annotation.elementAnnotation.isRequired) {
@@ -746,4 +980,50 @@
       ..addRequiredKeyword = true
       ..addRequiredKeywordInfo = info;
   }
+
+  void _makeTypeNameNullable(TypeAnnotation node, DecoratedType decoratedType) {
+    (_fixBuilder._getChange(node) as NodeChangeForTypeAnnotation)
+        .recordNullability(
+            decoratedType, decoratedType.node.isNullable,
+            nullabilityHint:
+                _fixBuilder._variables.getNullabilityHint(source, node));
+  }
+}
+
+/// Specialization of [_AssignmentLikeExpressionHandler] for
+/// [PostfixExpression].
+class _PostfixExpressionHandler extends _AssignmentLikeExpressionHandler {
+  @override
+  final PostfixExpression node;
+
+  _PostfixExpressionHandler(this.node)
+      : assert(_isIncrementOrDecrementOperator(node.operator.type));
+
+  @override
+  MethodElement get combiner => node.staticElement;
+
+  @override
+  TokenType get combinerType => node.operator.type;
+
+  @override
+  Expression get target => node.operand;
+}
+
+/// Specialization of [_AssignmentLikeExpressionHandler] for
+/// [PrefixExpression].
+class _PrefixExpressionHandler extends _AssignmentLikeExpressionHandler {
+  @override
+  final PrefixExpression node;
+
+  _PrefixExpressionHandler(this.node)
+      : assert(_isIncrementOrDecrementOperator(node.operator.type));
+
+  @override
+  MethodElement get combiner => node.staticElement;
+
+  @override
+  TokenType get combinerType => node.operator.type;
+
+  @override
+  Expression get target => node.operand;
 }
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
new file mode 100644
index 0000000..2a45144
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -0,0 +1,538 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
+import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_information.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+
+/// A builder used to build the migration information for a library.
+class InfoBuilder {
+  /// The resource provider used to access the file system.
+  ResourceProvider provider;
+
+  String includedPath;
+
+  /// The instrumentation information gathered while the migration engine was
+  /// running.
+  final InstrumentationInformation info;
+
+  /// The listener used to gather the changes to be applied.
+  final DartFixListenerInterface listener;
+
+  /// The [NullabilityMigration] instance for this migration.
+  final NullabilityMigration migration;
+
+  /// A map from the path of a compilation unit to the information about that
+  /// unit.
+  final Map<String, UnitInfo> unitMap = {};
+
+  /// Initialize a newly created builder.
+  InfoBuilder(this.provider, this.includedPath, this.info, this.listener,
+      this.migration);
+
+  /// The provider used to get information about libraries.
+  DriverProvider get driverProvider => listener.server;
+
+  /// Return the migration information for all of the libraries that were
+  /// migrated.
+  Future<Set<UnitInfo>> explainMigration() async {
+    var sourceInfoMap = info.sourceInformation;
+    Set<UnitInfo> units =
+        SplayTreeSet<UnitInfo>((u1, u2) => u1.path.compareTo(u2.path));
+    for (var source in sourceInfoMap.keys) {
+      var filePath = source.fullName;
+      var session = driverProvider.getAnalysisSession(filePath);
+      if (!session.getFile(filePath).isPart) {
+        var result = await session.getResolvedLibrary(filePath);
+        for (var unitResult in result.units) {
+          var sourceInfo =
+              sourceInfoMap[unitResult.unit.declaredElement.source];
+          // Note: there might have been no information for this unit in
+          // sourceInfoMap.  That can happen if there's an already-migrated
+          // library being referenced by the code being migrated, but not all
+          // parts of that library are referenced.  To avoid exceptions later
+          // on, we just create an empty SourceInformation object.
+          // TODO(paulberry): we don't do a good job of the case where the
+          // already-migrated library's defining compilation unit isn't
+          // referenced (we'll just skip the entire library because we'll only
+          // ever see its parts).
+          sourceInfo ??= SourceInformation();
+          var edit = listener.sourceChange.getFileEdit(unitResult.path);
+          var unit = _explainUnit(sourceInfo, unitResult, edit);
+          if (provider.pathContext.isWithin(includedPath, unitResult.path)) {
+            units.add(unit);
+          }
+        }
+      }
+    }
+    return units;
+  }
+
+  Iterable<EdgeInfo> upstreamTriggeredEdges(NullabilityNodeInfo node,
+      {bool skipExactNullable = true}) {
+    var edges = <EdgeInfo>[];
+    for (var edge in node.upstreamEdges) {
+      if (skipExactNullable &&
+          node.isExactNullable &&
+          edge.sourceNode.isExactNullable) {
+        // When an exact nullable points here, the nullability propagated
+        // in the other direction.
+        continue;
+      }
+      if (edge.isTriggered) {
+        edges.add(edge);
+      }
+    }
+    for (final containerNode in node.outerCompoundNodes) {
+      // We must include the exact nullable edges in the upstream triggered
+      // edges of the container node. If this node is in a substitution node,
+      // then it's possible it was marked exact nullable because it's container
+      // was marked nullable. It's container could have been marked nullable by
+      // another exact nullable node. We cannot tell. Err on the side of
+      // surfacing too many reasons.
+      edges.addAll(
+          upstreamTriggeredEdges(containerNode, skipExactNullable: false));
+    }
+
+    return edges;
+  }
+
+  void _addSimpleTrace(SimpleFixReasonInfo info, List<TraceInfo> traces) {
+    traces.add(TraceInfo(
+        'Reason', [_makeTraceEntry(info.description, info.codeReference)]));
+  }
+
+  /// Return an edit that can be applied.
+  List<EditDetail> _computeEdits(
+      AtomicEditInfo fixInfo, int offset, String content) {
+    EditDetail _removeHint(String description) => EditDetail.fromSourceEdit(
+        description,
+        fixInfo.hintComment.changesToRemove(content).toSourceEdits().single);
+
+    EditDetail _changeHint(String description, String replacement) =>
+        EditDetail.fromSourceEdit(
+            description,
+            fixInfo.hintComment
+                .changesToReplace(content, replacement)
+                .toSourceEdits()
+                .single);
+
+    var edits = <EditDetail>[];
+    var fixKind = fixInfo.description.kind;
+    switch (fixKind) {
+      case NullabilityFixKind.addLateDueToHint:
+        edits.add(_removeHint('Remove /*late*/ hint'));
+        break;
+      case NullabilityFixKind.addRequired:
+        // TODO(brianwilkerson) This doesn't verify that the meta package has
+        //  been imported.
+        edits
+            .add(EditDetail("Mark with '@required'.", offset, 0, '@required '));
+        break;
+      case NullabilityFixKind.checkExpression:
+        // TODO(brianwilkerson) Determine whether we can know that the fix is
+        //  associated with a parameter and insert an assert if it is.
+        edits.add(EditDetail('Add /*!*/ hint', offset, 0, '/*!*/'));
+        break;
+      case NullabilityFixKind.checkExpressionDueToHint:
+        edits.add(_removeHint('Remove /*!*/ hint'));
+        break;
+      case NullabilityFixKind.downcastExpression:
+      case NullabilityFixKind.otherCastExpression:
+        // There's no useful hint to apply to casts.
+        break;
+      case NullabilityFixKind.removeAs:
+      case NullabilityFixKind.removeDeadCode:
+      case NullabilityFixKind.removeLanguageVersionComment:
+        // There's no need for hints around code that is being removed.
+        break;
+      case NullabilityFixKind.addType:
+      case NullabilityFixKind.replaceVar:
+        // There's no need for hints around inserted types.
+        break;
+      case NullabilityFixKind.makeTypeNullable:
+      case NullabilityFixKind.typeNotMadeNullable:
+        edits.add(EditDetail('Add /*!*/ hint', offset, 0, '/*!*/'));
+        edits.add(EditDetail('Add /*?*/ hint', offset, 0, '/*?*/'));
+        break;
+      case NullabilityFixKind.makeTypeNullableDueToHint:
+        edits.add(_changeHint('Change to /*!*/ hint', '/*!*/'));
+        edits.add(_removeHint('Remove /*?*/ hint'));
+        break;
+      case NullabilityFixKind.typeNotMadeNullableDueToHint:
+        edits.add(_removeHint('Remove /*!*/ hint'));
+        edits.add(_changeHint('Change to /*?*/ hint', '/*?*/'));
+        break;
+      case NullabilityFixKind.addLate:
+      case NullabilityFixKind.addLateDueToTestSetup:
+        // We could add an edit to add a `/*?*/` hint, but the offset is a
+        // little tricky.
+        break;
+      case NullabilityFixKind.conditionFalseInStrongMode:
+      case NullabilityFixKind.conditionTrueInStrongMode:
+      case NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode:
+      case NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode:
+        // We don't offer any edits around weak-only code.
+        // TODO(paulberry): offer edits to delete the code that would be dead in
+        // strong mode (https://github.com/dart-lang/sdk/issues/41554).
+        break;
+      case NullabilityFixKind.compoundAssignmentHasBadCombinedType:
+      case NullabilityFixKind.compoundAssignmentHasNullableSource:
+        // We don't offer any edits around bad compound assignments or bad
+        // increment/decrement operations.
+        break;
+    }
+    return edits;
+  }
+
+  /// Return the navigation sources for the unit associated with the [result].
+  List<NavigationSource> _computeNavigationSources(ResolvedUnitResult result) {
+    var collector = NavigationCollectorImpl();
+    computeDartNavigation(
+        result.session.resourceProvider, collector, result.unit, null, null);
+    collector.createRegions();
+    var files = collector.files;
+    var regions = collector.regions;
+    var rawTargets = collector.targets;
+    var convertedTargets = List<NavigationTarget>(rawTargets.length);
+    return regions.map((region) {
+      var targets = region.targets;
+      if (targets.isEmpty) {
+        throw StateError('Targets is empty');
+      }
+      var target = convertedTargets[targets[0]];
+      if (target == null) {
+        var rawTarget = rawTargets[targets[0]];
+        target = _targetForRawTarget(files[rawTarget.fileIndex], rawTarget);
+        convertedTargets[targets[0]] = target;
+      }
+      return NavigationSource(
+          region.offset, null /* line */, region.length, target);
+    }).toList();
+  }
+
+  void _computeTraceNonNullableInfo(NullabilityNodeInfo node,
+      List<TraceInfo> traces, FixReasonTarget target) {
+    var entries = <TraceEntryInfo>[];
+    var step = node.whyNotNullable;
+    if (step == null) {
+      return;
+    }
+    assert(identical(step.node, node));
+    while (step != null) {
+      entries.add(_nodeToTraceEntry(step.node));
+      if (step.codeReference != null) {
+        entries.add(_stepToTraceEntry(step));
+      }
+      step = step.principalCause;
+    }
+    var description = 'Non-nullability reason${target.suffix}';
+    traces.add(TraceInfo(description, entries));
+  }
+
+  void _computeTraceNullableInfo(NullabilityNodeInfo node,
+      List<TraceInfo> traces, FixReasonTarget target) {
+    var entries = <TraceEntryInfo>[];
+    var step = node.whyNullable;
+    if (step == null) {
+      return;
+    }
+    assert(identical(step.targetNode, node));
+    while (step != null) {
+      entries.add(_nodeToTraceEntry(step.targetNode));
+      if (step.codeReference != null) {
+        entries.add(_stepToTraceEntry(step));
+      }
+      step = step.principalCause;
+    }
+    var description = 'Nullability reason${target.suffix}';
+    traces.add(TraceInfo(description, entries));
+  }
+
+  List<TraceInfo> _computeTraces(
+      Map<FixReasonTarget, FixReasonInfo> fixReasons) {
+    var traces = <TraceInfo>[];
+    for (var entry in fixReasons.entries) {
+      var reason = entry.value;
+      if (reason is NullabilityNodeInfo) {
+        if (reason.isNullable) {
+          _computeTraceNullableInfo(reason, traces, FixReasonTarget.root);
+        } else {
+          _computeTraceNonNullableInfo(reason, traces, FixReasonTarget.root);
+        }
+      } else if (reason is EdgeInfo) {
+        if (reason.sourceNode.isNullable &&
+            !reason.destinationNode.isNullable) {
+          var target = entry.key;
+          _computeTraceNullableInfo(reason.sourceNode, traces, target);
+          _computeTraceNonNullableInfo(reason.destinationNode, traces, target);
+        }
+      } else if (reason is SimpleFixReasonInfo) {
+        _addSimpleTrace(reason, traces);
+      } else {
+        assert(false, 'Unrecognized reason type: ${reason.runtimeType}');
+      }
+    }
+    return traces;
+  }
+
+  /// Return the migration information for the unit associated with the
+  /// [result].
+  UnitInfo _explainUnit(SourceInformation sourceInfo, ResolvedUnitResult result,
+      SourceFileEdit fileEdit) {
+    var unitInfo = _unitForPath(result.path);
+    unitInfo.sources ??= _computeNavigationSources(result);
+    var content = result.content;
+    unitInfo.diskContent = content;
+    var regions = unitInfo.regions;
+    var lineInfo = result.unit.lineInfo;
+    var insertions = <int, List<AtomicEdit>>{};
+    var hintsSeen = <HintComment>{};
+
+    // Apply edits and build the regions.
+    var changes = sourceInfo.changes ?? {};
+    var sourceOffsets = changes.keys.toList();
+    sourceOffsets.sort();
+    var offset = 0;
+    var lastSourceOffset = 0;
+    for (var sourceOffset in sourceOffsets) {
+      offset += sourceOffset - lastSourceOffset;
+      lastSourceOffset = sourceOffset;
+      var changesForSourceOffset = changes[sourceOffset];
+      for (var edit in changesForSourceOffset) {
+        var length = edit.length;
+        var replacement = edit.replacement;
+        var end = offset + length;
+        // Insert the replacement text without deleting the replaced text.
+        if (replacement.isNotEmpty) {
+          content = content.replaceRange(end, end, replacement);
+          (insertions[sourceOffset] ??= []).add(AtomicEdit.insert(replacement));
+        }
+        var info = edit.info;
+        var edits = info != null
+            ? _computeEdits(info, sourceOffset, result.content)
+            : <EditDetail>[];
+        var lineNumber = lineInfo.getLocation(sourceOffset).lineNumber;
+        var traces = info == null
+            ? const <TraceInfo>[]
+            : _computeTraces(info.fixReasons);
+        var description = info?.description;
+        var hint = info?.hintComment;
+        var isCounted = hint == null || hintsSeen.add(hint);
+        if (description != null) {
+          var explanation = description.appliedMessage;
+          var kind = description.kind;
+          if (edit.isInsertion) {
+            regions.add(RegionInfo(
+                edit.isInformative ? RegionType.informative : RegionType.add,
+                offset,
+                replacement.length,
+                lineNumber,
+                explanation,
+                kind,
+                isCounted,
+                edits: edits,
+                traces: traces));
+          } else if (edit.isDeletion) {
+            regions.add(RegionInfo(
+                edit.isInformative ? RegionType.informative : RegionType.remove,
+                offset,
+                length,
+                lineNumber,
+                explanation,
+                kind,
+                isCounted,
+                edits: edits,
+                traces: traces));
+          } else if (edit.isReplacement) {
+            assert(!edit.isInformative);
+            regions.add(RegionInfo(RegionType.remove, offset, length,
+                lineNumber, explanation, kind, isCounted,
+                edits: edits, traces: traces));
+            regions.add(RegionInfo(RegionType.add, end, replacement.length,
+                lineNumber, explanation, kind, isCounted,
+                edits: edits, traces: traces));
+          } else {
+            throw StateError(
+                'Edit is not an insertion, deletion, replacement, nor '
+                'informative: $edit');
+          }
+        }
+        offset += replacement.length;
+      }
+    }
+
+    // Build the map from source file offset to offset in the modified text.
+    // We only account for insertions because in the code above, we don't delete
+    // the modified text.
+    var edits = insertions.toSourceEdits();
+    edits.sort((first, second) => first.offset.compareTo(second.offset));
+    var mapper = OffsetMapper.forEdits(edits);
+    regions.sort((first, second) => first.offset.compareTo(second.offset));
+    unitInfo.migrationOffsetMapper = mapper;
+    unitInfo.content = content;
+    return unitInfo;
+  }
+
+  TraceEntryInfo _makeTraceEntry(
+      String description, CodeReference codeReference) {
+    var length = 1; // TODO(paulberry): figure out the correct value.
+    return TraceEntryInfo(
+        description,
+        codeReference?.function,
+        codeReference == null
+            ? null
+            : NavigationTarget(codeReference.path, codeReference.offset,
+                codeReference.line, length));
+  }
+
+  TraceEntryInfo _nodeToTraceEntry(NullabilityNodeInfo node) {
+    var description = node.toString(); // TODO(paulberry): improve this message
+    return _makeTraceEntry(description, node.codeReference);
+  }
+
+  TraceEntryInfo _stepToTraceEntry(PropagationStepInfo step) {
+    var description = step.edge?.description;
+    description ??= step.toString(); // TODO(paulberry): improve this message.
+    return _makeTraceEntry(description, step.codeReference);
+  }
+
+  /// Return the navigation target in the file with the given [filePath] at the
+  /// given [offset] ans with the given [length].
+  NavigationTarget _targetForRawTarget(
+      String filePath, protocol.NavigationTarget rawTarget) {
+    var unitInfo = _unitForPath(filePath);
+    var offset = rawTarget.offset;
+    var length = rawTarget.length;
+    var target = NavigationTarget(filePath, offset, null /* line */, length);
+    unitInfo.targets.add(target);
+    return target;
+  }
+
+  /// Return the unit info for the file at the given [path].
+  UnitInfo _unitForPath(String path) {
+    return unitMap.putIfAbsent(path, () => UnitInfo(path));
+  }
+
+  /// Builds a description for [node]'s enclosing member(s).
+  ///
+  /// This may include a class and method name, for example, or the name of the
+  /// enclosing top-level member.
+  @visibleForTesting
+  static String buildEnclosingMemberDescription(AstNode node) {
+    for (var enclosingNode = node;
+        enclosingNode != null;
+        enclosingNode = enclosingNode.parent) {
+      if (enclosingNode is ConstructorDeclaration) {
+        if (enclosingNode.name == null) {
+          return _describeClassOrExtensionMember(
+              enclosingNode.parent as CompilationUnitMember,
+              'the default constructor of',
+              '');
+        } else {
+          return _describeClassOrExtensionMember(
+              enclosingNode.parent as CompilationUnitMember,
+              'the constructor',
+              enclosingNode.name.name);
+        }
+      } else if (enclosingNode is MethodDeclaration) {
+        var functionName = enclosingNode.name.name;
+        String baseDescription;
+        if (enclosingNode.isGetter) {
+          baseDescription = 'the getter';
+        } else if (enclosingNode.isOperator) {
+          baseDescription = 'the operator';
+        } else if (enclosingNode.isSetter) {
+          baseDescription = 'the setter';
+          functionName += '=';
+        } else {
+          baseDescription = 'the method';
+        }
+        return _describeClassOrExtensionMember(
+            enclosingNode.parent as CompilationUnitMember,
+            baseDescription,
+            functionName);
+      } else if (enclosingNode is FunctionDeclaration &&
+          enclosingNode.parent is CompilationUnit) {
+        var functionName = enclosingNode.name.name;
+        String baseDescription;
+        if (enclosingNode.isGetter) {
+          baseDescription = 'the getter';
+        } else if (enclosingNode.isSetter) {
+          baseDescription = 'the setter';
+          functionName += '=';
+        } else {
+          baseDescription = 'the function';
+        }
+        return "$baseDescription '$functionName'";
+      } else if (enclosingNode is VariableDeclaration) {
+        var description = _describeVariableDeclaration(enclosingNode);
+        if (description != null) return description;
+      } else if (enclosingNode is VariableDeclarationList) {
+        var description =
+            _describeVariableDeclaration(enclosingNode.variables[0]);
+        if (description != null) return description;
+      }
+    }
+    throw ArgumentError(
+        "Can't describe enclosing member of ${node.runtimeType}");
+  }
+
+  static String _describeClassOrExtensionMember(CompilationUnitMember parent,
+      String baseDescription, String functionName) {
+    if (parent is NamedCompilationUnitMember) {
+      var parentName = parent.name.name;
+      if (functionName.isEmpty) {
+        return "$baseDescription '$parentName'";
+      } else {
+        return "$baseDescription '$parentName.$functionName'";
+      }
+    } else if (parent is ExtensionDeclaration) {
+      if (parent.name == null) {
+        var extendedTypeString = parent.extendedType.type.getDisplayString(
+          withNullability: false,
+        );
+        return "$baseDescription '$functionName' in unnamed extension on $extendedTypeString";
+      } else {
+        return "$baseDescription '${parent.name.name}.$functionName'";
+      }
+    } else {
+      throw ArgumentError(
+          'Unexpected class or extension type ${parent.runtimeType}');
+    }
+  }
+
+  static String _describeVariableDeclaration(VariableDeclaration node) {
+    var variableName = node.name.name;
+    var parent = node.parent;
+    var grandParent = parent.parent;
+    if (grandParent is FieldDeclaration) {
+      return _describeClassOrExtensionMember(
+          grandParent.parent as CompilationUnitMember,
+          'the field',
+          variableName);
+    } else if (grandParent is TopLevelVariableDeclaration) {
+      return "the variable '$variableName'";
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_information.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
rename to pkg/nnbd_migration/lib/src/front_end/instrumentation_information.dart
diff --git a/pkg/nnbd_migration/lib/src/front_end/instrumentation_listener.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_listener.dart
new file mode 100644
index 0000000..fbbbbcf
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/instrumentation_listener.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_information.dart';
+
+/// A listener used to gather instrumentation information from the migration
+/// engine.
+class InstrumentationListener implements NullabilityMigrationInstrumentation {
+  /// The instrumentation information being gathered.
+  InstrumentationInformation data = InstrumentationInformation();
+
+  /// Initialize a newly created listener.
+  InstrumentationListener();
+
+  @override
+  void changes(Source source, Map<int, List<AtomicEdit>> changes) {
+    assert(_sourceInfo(source).changes == null);
+    _sourceInfo(source).changes = changes;
+  }
+
+  @override
+  void explicitTypeNullability(
+      Source source, TypeAnnotation typeAnnotation, NullabilityNodeInfo node) {
+    data.nodeInformation[node] =
+        NodeInformation(_filePathForSource(source), typeAnnotation, null);
+    _sourceInfo(source).explicitTypeNullability[typeAnnotation] = node;
+  }
+
+  @override
+  void externalDecoratedType(Element element, DecoratedTypeInfo decoratedType) {
+    _storeNodeInformation(decoratedType, element.source, null, element);
+  }
+
+  @override
+  void externalDecoratedTypeParameterBound(
+      TypeParameterElement typeParameter, DecoratedTypeInfo decoratedType) {
+    _storeNodeInformation(
+        decoratedType, typeParameter.source, null, typeParameter);
+  }
+
+  @override
+  void graphEdge(EdgeInfo edge, EdgeOriginInfo originInfo) {
+    data.edgeOrigin[edge] = originInfo;
+  }
+
+  @override
+  void immutableNodes(NullabilityNodeInfo never, NullabilityNodeInfo always) {
+    data.never = never;
+    data.always = always;
+  }
+
+  @override
+  void implicitReturnType(
+      Source source, AstNode node, DecoratedTypeInfo decoratedReturnType) {
+    _storeNodeInformation(decoratedReturnType, source, node, null);
+  }
+
+  @override
+  void implicitType(
+      Source source, AstNode node, DecoratedTypeInfo decoratedType) {
+    _storeNodeInformation(decoratedType, source, node, null);
+  }
+
+  @override
+  void implicitTypeArguments(
+      Source source, AstNode node, Iterable<DecoratedTypeInfo> types) {
+    for (var type in types) {
+      _storeNodeInformation(type, source, node, null);
+    }
+  }
+
+  @override
+  void prepareForUpdate() {
+    for (var source in data.sourceInformation.keys) {
+      _sourceInfo(source).changes = null;
+    }
+  }
+
+  String _filePathForSource(Source source) {
+    return source.fullName;
+  }
+
+  /// Return the source information associated with the given [source], creating
+  /// it if there has been no previous information for that source.
+  SourceInformation _sourceInfo(Source source) =>
+      data.sourceInformation.putIfAbsent(source, () => SourceInformation());
+
+  // TODO(srawlins): This code is completely untested.
+  void _storeNodeInformation(DecoratedTypeInfo decoratedType, Source source,
+      AstNode astNode, Element element) {
+    // Make sure source info exists for the given source.
+    _sourceInfo(source);
+    data.nodeInformation[decoratedType.node] =
+        NodeInformation(_filePathForSource(source), astNode, element);
+    var dartType = decoratedType.type;
+    if (dartType is InterfaceType) {
+      for (var i = 0; i < dartType.typeArguments.length; i++) {
+        _storeNodeInformation(
+            decoratedType.typeArgument(i), source, astNode, element);
+      }
+    } else if (dartType is FunctionType) {
+      _storeNodeInformation(
+        decoratedType.returnType,
+        source,
+        astNode,
+        element,
+      );
+      var i = 0;
+      for (var parameter in dartType.parameters) {
+        if (parameter.isNamed) {
+          var name = parameter.name;
+          _storeNodeInformation(
+              decoratedType.namedParameter(name), source, astNode, element);
+        } else {
+          _storeNodeInformation(
+              decoratedType.positionalParameter(i), source, astNode, element);
+          i++;
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
new file mode 100644
index 0000000..e5538ea
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/resources/resources.g.dart'
+    as resources;
+import 'package:path/path.dart' as path;
+
+String get _dartSdkVersion {
+  var version = Platform.version;
+
+  // Remove the build date and OS.
+  if (version.contains(' ')) {
+    version = version.substring(0, version.indexOf(' '));
+  }
+
+  // Convert a git hash to 8 chars.
+  // '2.8.0-edge.fd992e423ef69ece9f44bd3ac58fa2355b563212'
+  var versionRegExp = RegExp(r'^.*\.([0123456789abcdef]+)$');
+  var match = versionRegExp.firstMatch(version);
+  if (match != null && match.group(1).length == 40) {
+    var commit = match.group(1);
+    version = version.replaceAll(commit, commit.substring(0, 10));
+  }
+
+  return version;
+}
+
+String substituteVariables(String content, Map<String, String> variables) {
+  for (var variable in variables.keys) {
+    var value = variables[variable];
+    content = content.replaceAll('{{ $variable }}', value);
+  }
+
+  return content;
+}
+
+/// Instrumentation display output for a library that was migrated to use
+/// non-nullable types.
+class InstrumentationRenderer {
+  /// Information for a whole migration, so that libraries can reference each
+  /// other.
+  final MigrationInfo migrationInfo;
+
+  /// Whether the migration has been applied already or not.
+  final bool hasBeenApplied;
+
+  /// Whether the migration needs to be rerun due to disk changes.
+  final bool needsRerun;
+
+  /// An object used to map the file paths of analyzed files to the file paths
+  /// of the HTML files used to view the content of those files.
+  final PathMapper pathMapper;
+
+  /// Creates an output object for the given library info.
+  InstrumentationRenderer(this.migrationInfo, this.pathMapper,
+      this.hasBeenApplied, this.needsRerun);
+
+  /// Returns the path context used to manipulate paths.
+  path.Context get pathContext => migrationInfo.pathContext;
+
+  /// Builds an HTML view of the instrumentation information.
+  String render() {
+    var variables = <String, String>{
+      'root': migrationInfo.includedRoot,
+      'dartPageScript': resources.migration_js,
+      'dartPageStyle': resources.migration_css,
+      'highlightJsPath': migrationInfo.highlightJsPath,
+      'highlightStylePath': migrationInfo.highlightStylePath,
+      'sdkVersion': _dartSdkVersion,
+      'migrationAppliedStyle': hasBeenApplied ? 'applied' : 'proposed',
+      'needsRerunStyle': needsRerun ? 'needs-rerun' : '',
+    };
+
+    return substituteVariables(resources.index_html, variables);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
new file mode 100644
index 0000000..cafab98
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
@@ -0,0 +1,319 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:collection/collection.dart';
+import 'package:crypto/crypto.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:nnbd_migration/src/front_end/unit_link.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+import 'package:path/path.dart' as path;
+
+/// A description of an edit that can be applied before rerunning the migration
+/// in order to improve the migration results.
+class EditDetail {
+  /// A description of the edit that will be performed.
+  final String description;
+
+  /// The offset of the range to be replaced.
+  final int offset;
+
+  /// The length of the range to be replaced.
+  final int length;
+
+  /// The string with which the range will be replaced.
+  final String replacement;
+
+  /// Initialize a newly created detail.
+  EditDetail(this.description, this.offset, this.length, this.replacement);
+
+  /// Initializes a detail based on a [SourceEdit] object.
+  factory EditDetail.fromSourceEdit(
+          String description, SourceEdit sourceEdit) =>
+      EditDetail(description, sourceEdit.offset, sourceEdit.length,
+          sourceEdit.replacement);
+}
+
+/// A class storing rendering information for an entire migration report.
+///
+/// This generally provides one [InstrumentationRenderer] (for one library)
+/// with information about the rest of the libraries represented in the
+/// instrumentation output.
+class MigrationInfo {
+  /// The information about the compilation units that are are migrated.
+  final Set<UnitInfo> units;
+
+  /// A map from file paths to the unit infos created for those files. The units
+  /// in this map is a strict superset of the [units] that were migrated.
+  final Map<String, UnitInfo> unitMap;
+
+  /// The resource provider's path context.
+  final path.Context pathContext;
+
+  /// The filesystem root used to create relative paths for each unit.
+  final String includedRoot;
+
+  MigrationInfo(this.units, this.unitMap, this.pathContext, this.includedRoot);
+
+  /// The path to the highlight.pack.js script, relative to [unitInfo].
+  String get highlightJsPath => PreviewSite.highlightJsPath;
+
+  /// The path to the highlight.pack.js stylesheet, relative to [unitInfo].
+  String get highlightStylePath => PreviewSite.highlightCssPath;
+
+  /// Return the path to [unit] from [includedRoot], to be used as a display
+  /// name for a library.
+  String computeName(UnitInfo unit) =>
+      pathContext.relative(unit.path, from: includedRoot);
+
+  List<UnitLink> unitLinks() {
+    var links = <UnitLink>[];
+    for (var unit in units) {
+      var count = unit.fixRegions.length;
+      links.add(UnitLink(
+          _pathTo(target: unit), pathContext.split(computeName(unit)), count));
+    }
+    return links;
+  }
+
+  /// The path to [target], as an HTTP URI path, using forward slash separators.
+  String _pathTo({@required UnitInfo target}) =>
+      '/' + pathContext.split(target.path).skip(1).join('/');
+}
+
+/// A location from or to which a user might want to navigate.
+abstract class NavigationRegion {
+  /// The offset of the region.
+  final int offset;
+
+  /// The line number of the region.
+  final int line;
+
+  /// The length of the region.
+  final int length;
+
+  /// Initialize a newly created link.
+  NavigationRegion(int offset, this.line, this.length)
+      : assert(offset >= 0),
+        offset = offset < 0 ? 0 : offset;
+}
+
+/// A location from which a user might want to navigate.
+class NavigationSource extends NavigationRegion {
+  /// The target to which the user should be navigated.
+  final NavigationTarget target;
+
+  /// Initialize a newly created link.
+  NavigationSource(int offset, int line, int length, this.target)
+      : super(offset, line, length);
+}
+
+/// A location to which a user might want to navigate.
+class NavigationTarget extends NavigationRegion {
+  /// The file containing the anchor.
+  final String filePath;
+
+  /// Initialize a newly created anchor.
+  NavigationTarget(this.filePath, int offset, int line, int length)
+      : super(offset, line, length);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash3(filePath.hashCode, offset, length);
+
+  @override
+  bool operator ==(other) {
+    return other is NavigationTarget &&
+        other.filePath == filePath &&
+        other.offset == offset &&
+        other.length == length;
+  }
+
+  @override
+  String toString() => 'NavigationTarget["$filePath", $line, $offset, $length]';
+}
+
+/// A description of an explanation associated with a region of code that was
+/// modified.
+class RegionInfo {
+  /// Type type of region.
+  final RegionType regionType;
+
+  /// The offset to the beginning of the region.
+  final int offset;
+
+  /// The length of the region.
+  final int length;
+
+  /// The line number of the beginning of the region.
+  final int lineNumber;
+
+  /// The explanation to be displayed for the region.
+  final String explanation;
+
+  /// The kind of fix that was applied.
+  final NullabilityFixKind kind;
+
+  /// Indicates whether this region should be counted in the edit summary.
+  final bool isCounted;
+
+  /// A list of the edits that are related to this range.
+  List<EditDetail> edits;
+
+  /// A list of the nullability propagation traces that are related to this
+  /// range.
+  List<TraceInfo> traces;
+
+  /// Initialize a newly created region.
+  RegionInfo(this.regionType, this.offset, this.length, this.lineNumber,
+      this.explanation, this.kind, this.isCounted,
+      {this.edits = const [], this.traces = const []});
+}
+
+/// Different types of regions that are called out.
+enum RegionType {
+  /// This is a region of code that was added in migration.
+  add,
+
+  /// This is a region of code that was removed in migration.
+  remove,
+
+  /// This is a region of code that wasn't changed by migration, but is being
+  /// shown to give the user more information about the migration.
+  informative,
+}
+
+/// Information about a single entry in a nullability trace.
+class TraceEntryInfo {
+  /// Text description of the entry.
+  final String description;
+
+  /// Name of the enclosing function, or `null` if not known.
+  String function;
+
+  /// Source code location associated with the entry, or `null` if no source
+  /// code location is known.
+  final NavigationTarget target;
+
+  TraceEntryInfo(this.description, this.function, this.target);
+}
+
+/// Information about a nullability trace.
+class TraceInfo {
+  /// Text description of the trace.
+  final String description;
+
+  /// List of trace entries.
+  final List<TraceEntryInfo> entries;
+
+  TraceInfo(this.description, this.entries);
+}
+
+/// The migration information associated with a single compilation unit.
+class UnitInfo {
+  /// The absolute and normalized path of the unit.
+  final String path;
+
+  /// Hash of the original contents of the unit.
+  List<int> _diskContentHash;
+
+  /// The preview content of unit.
+  String content;
+
+  /// The information about the regions that have an explanation associated with
+  /// them. The offsets in these regions are offsets into the post-edit content.
+  final List<RegionInfo> regions = [];
+
+  /// The navigation sources that are located in this file. The offsets in these
+  /// sources are offsets into the pre-edit content.
+  List<NavigationSource> sources;
+
+  /// The navigation targets that are located in this file. The offsets in these
+  /// targets are offsets into the pre-edit content.
+  final Set<NavigationTarget> targets = {};
+
+  /// An offset mapper reflecting changes made by the migration edits.
+  OffsetMapper migrationOffsetMapper = OffsetMapper.identity;
+
+  /// An offset mapper reflecting changes made to disk since the migration was
+  /// run, which can be rebased on [migrationOffsetMapper] to create and
+  /// maintain an offset mapper from current disk state to migration result.
+  OffsetMapper diskChangesOffsetMapper = OffsetMapper.identity;
+
+  /// Initialize a newly created unit.
+  UnitInfo(this.path);
+
+  /// Set the original/disk content of this file to later use [hadDiskContent].
+  /// This does not have a getter because it is backed by a private hash.
+  set diskContent(String originalContent) {
+    _diskContentHash = md5.convert((originalContent ?? '').codeUnits).bytes;
+  }
+
+  /// Returns the [regions] that represent a fixed (changed) region of code.
+  List<RegionInfo> get fixRegions => regions
+      .where((region) => region.regionType != RegionType.informative)
+      .toList();
+
+  /// Returns the [regions] that are informative.
+  List<RegionInfo> get informativeRegions => regions
+      .where((region) => region.regionType == RegionType.informative)
+      .toList();
+
+  /// The object used to map the pre-edit offsets in the navigation targets to
+  /// the post-edit offsets in the [content].
+  OffsetMapper get offsetMapper =>
+      OffsetMapper.rebase(diskChangesOffsetMapper, migrationOffsetMapper);
+
+  /// Check if this unit's file had expected disk contents [checkContent].
+  bool hadDiskContent(String checkContent) {
+    assert(_diskContentHash != null);
+    return const ListEquality().equals(
+        _diskContentHash, md5.convert((checkContent ?? '').codeUnits).bytes);
+  }
+
+  void handleInsertion(int offset, String replacement) {
+    final contentCopy = content;
+    final regionsCopy = List<RegionInfo>.from(regions);
+    final length = replacement.length;
+    offset = offsetMapper.map(offset);
+    try {
+      content = content.replaceRange(offset, offset, replacement);
+      regions.clear();
+      regions.addAll(regionsCopy.map((region) {
+        if (region.offset < offset) {
+          return region;
+        }
+        // TODO: perhaps this should be handled by offset mapper instead, since
+        // offset mapper handles navigation, edits, and traces, and this is the
+        // odd ball out.
+        return RegionInfo(
+            region.regionType,
+            region.offset + length,
+            region.length,
+            region.lineNumber,
+            region.explanation,
+            region.kind,
+            region.isCounted,
+            edits: region.edits,
+            traces: region.traces);
+      }));
+
+      diskChangesOffsetMapper = OffsetMapper.sequence(
+          diskChangesOffsetMapper, OffsetMapper.forInsertion(offset, length));
+    } catch (e) {
+      regions.clear();
+      regions.addAll(regionsCopy);
+      content = contentCopy;
+      rethrow;
+    }
+  }
+
+  /// Returns the [RegionInfo] at offset [offset].
+  // TODO(srawlins): This is O(n), used each time the user clicks on a region.
+  //  Consider changing the type of [regions] to facilitate O(1) searching.
+  RegionInfo regionAt(int offset) =>
+      regions.firstWhere((region) => region.offset == offset);
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_state.dart b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
new file mode 100644
index 0000000..1d714bd
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/info_builder.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+
+/// The state of an NNBD migration.
+class MigrationState {
+  bool _hasBeenApplied = false;
+
+  /// The migration associated with the state.
+  final NullabilityMigration migration;
+
+  /// The root directory that contains all of the files that were migrated.
+  final String includedRoot;
+
+  /// The listener used to collect fixes.
+  final DartFixListenerInterface listener;
+
+  /// The listener that collected information during the migration.
+  final InstrumentationListener instrumentationListener;
+
+  /// The information that was built from the rest of the migration state.
+  MigrationInfo migrationInfo;
+
+  /// The object used to map paths.
+  PathMapper pathMapper;
+
+  /// If there have been changes to disk so the migration needs to be rerun.
+  bool needsRerun = false;
+
+  /// Initialize a newly created migration state with the given values.
+  MigrationState(this.migration, this.includedRoot, this.listener,
+      this.instrumentationListener);
+
+  /// If the migration has been applied to disk.
+  bool get hasBeenApplied => _hasBeenApplied;
+
+  /// Mark that the migration has been applied to disk.
+  void markApplied() {
+    assert(!hasBeenApplied);
+    _hasBeenApplied = true;
+  }
+
+  /// Refresh the state of the migration after the migration has been updated.
+  Future<void> refresh() async {
+    assert(!hasBeenApplied);
+    var provider = listener.server.resourceProvider;
+    var infoBuilder = InfoBuilder(provider, includedRoot,
+        instrumentationListener.data, listener, migration);
+    var unitInfos = await infoBuilder.explainMigration();
+    var pathContext = provider.pathContext;
+    migrationInfo = MigrationInfo(
+        unitInfos, infoBuilder.unitMap, pathContext, includedRoot);
+    pathMapper = PathMapper(provider);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
new file mode 100644
index 0000000..09d975c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/unit_link.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+import 'package:path/path.dart' as path;
+
+/// Groups the items in [iterable] by the result of applying [groupFn] to each
+/// item.
+Map<K, List<T>> _groupBy<K, T>(
+    Iterable<T> iterable, K Function(T item) groupFn) {
+  var result = <K, List<T>>{};
+  for (var item in iterable) {
+    var key = groupFn(item);
+    result.putIfAbsent(key, () => <T>[]).add(item);
+  }
+  return result;
+}
+
+/// The HTML that is displayed for a region of code.
+class NavigationTreeRenderer {
+  final MigrationInfo migrationInfo;
+
+  /// An object used to map the file paths of analyzed files to the file paths
+  /// of the HTML files used to view the content of those files.
+  final PathMapper pathMapper;
+
+  /// Initializes a newly created region page within the given [site]. The
+  /// [unitInfo] provides the information needed to render the page.
+  NavigationTreeRenderer(this.migrationInfo, this.pathMapper);
+
+  /// Returns the path context used to manipulate paths.
+  path.Context get pathContext => migrationInfo.pathContext;
+
+  /// Renders the navigation link tree.
+  List<NavigationTreeNode> render() {
+    var linkData = migrationInfo.unitLinks();
+    return _renderNavigationSubtree(linkData, 0);
+  }
+
+  /// Renders the navigation link subtree at [depth].
+  List<NavigationTreeNode> _renderNavigationSubtree(
+      List<UnitLink> links, int depth) {
+    var linksGroupedByDirectory = _groupBy(
+        links.where((link) => link.depth > depth),
+        (UnitLink link) => link.pathParts[depth]);
+    return [
+      for (var entry in linksGroupedByDirectory.entries)
+        NavigationTreeNode.directory(
+          name: entry.key,
+          subtree: _renderNavigationSubtree(entry.value, depth + 1),
+        ),
+      for (var link in links.where((link) => link.depth == depth))
+        NavigationTreeNode.file(
+          name: link.fileName,
+          path: pathContext.joinAll(link.pathParts),
+          href: link.url,
+          editCount: link.editCount,
+        ),
+    ];
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart b/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
new file mode 100644
index 0000000..f53fd79
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+
+/// An object that can map the offsets before a sequence of edits to the offsets
+/// after applying the edits.
+abstract class OffsetMapper {
+  /// A mapper used for files that were not modified.
+  static OffsetMapper identity = _IdentityMapper();
+
+  /// Return a mapper representing the file modified by the given [edits].
+  factory OffsetMapper.forEdits(List<SourceEdit> edits) => _EditMapper(edits);
+
+  /// Return a mapper representing the file modified by an insertion at [offset]
+  /// the given with [length].
+  factory OffsetMapper.forInsertion(int offset, int length) =>
+      _SimpleInsertionMapper(offset, length);
+
+  /// Return a mapper representing [rebased] rebased by [rebaser].
+  factory OffsetMapper.rebase(OffsetMapper rebaser, OffsetMapper rebased) {
+    return _RebasedOffsetMapper(rebaser, rebased);
+  }
+
+  /// Return a mapper representing a sequence of edits made in order, with the
+  /// offsets coming out of [first] being the offsets passed into [second].
+  factory OffsetMapper.sequence(OffsetMapper first, OffsetMapper second) {
+    return _OffsetMapperChain([first, second]);
+  }
+
+  /// Return the post-edit offset that corresponds to the given pre-edit
+  /// [offset].
+  int map(int offset);
+}
+
+/// A mapper used for files that were modified by a set of edits.
+class _EditMapper implements OffsetMapper {
+  /// A list whose elements are the highest pre-edit offset for which the
+  /// corresponding element of [_deltas] should be applied.
+  final List<int> _offsets = [];
+
+  /// A list whose elements are the deltas to be applied for all pre-edit
+  /// offsets that are less than or equal to the corresponding element of
+  /// [_offsets].
+  final List<int> _deltas = [];
+
+  /// Initialize a newly created mapper based on the given set of [edits].
+  _EditMapper(List<SourceEdit> edits) {
+    _initializeDeltas(edits);
+  }
+
+  @override
+  int map(int offset) => offset + _deltaFor(offset);
+
+  /// Return the delta to be added to the pre-edit [offset] to produce the
+  /// post-edit offset.
+  int _deltaFor(int offset) {
+    for (var i = 0; i < _offsets.length; i++) {
+      var currentOffset = _offsets[i];
+      if (currentOffset >= offset || currentOffset < 0) {
+        return _deltas[i];
+      }
+    }
+    // We should never get here because [_initializeDeltas] always adds an
+    // offset/delta pair at the end of the list whose offset is less than zero.
+    return 0;
+  }
+
+  /// Initialize the list of old offsets and deltas used by [_deltaFor].
+  void _initializeDeltas(List<SourceEdit> edits) {
+    var previousDelta = 0;
+    for (var edit in edits) {
+      var offset = edit.offset;
+      var length = edit.length;
+      _offsets.add(offset);
+      _deltas.add(previousDelta);
+      previousDelta += (edit.replacement.length - length);
+    }
+    _offsets.add(-1);
+    _deltas.add(previousDelta);
+  }
+}
+
+/// A mapper used for files that were not modified.
+class _IdentityMapper implements OffsetMapper {
+  @override
+  int map(int offset) => offset;
+}
+
+class _OffsetMapperChain implements OffsetMapper {
+  final List<OffsetMapper> innerMappers;
+
+  _OffsetMapperChain(this.innerMappers);
+
+  @override
+  int map(int offset) {
+    for (final mapper in innerMappers) {
+      offset = mapper.map(offset);
+    }
+    return offset;
+  }
+}
+
+class _RebasedOffsetMapper implements OffsetMapper {
+  final OffsetMapper rebaser;
+  final OffsetMapper rebased;
+
+  _RebasedOffsetMapper(this.rebaser, this.rebased);
+
+  @override
+  int map(int offset) {
+    final delta = rebased.map(offset) - offset;
+    return rebaser.map(offset) + delta;
+  }
+}
+
+class _SimpleInsertionMapper implements OffsetMapper {
+  final int offset;
+  final int length;
+
+  _SimpleInsertionMapper(this.offset, this.length);
+
+  @override
+  int map(int offset) => offset < this.offset ? offset : offset + length;
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/path_mapper.dart b/pkg/nnbd_migration/lib/src/front_end/path_mapper.dart
new file mode 100644
index 0000000..e8ac01c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/path_mapper.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+
+/// An object that can map the file paths of analyzed files to the file paths of
+/// the HTML files used to view the content of those files.
+class PathMapper {
+  /// The resource provider used to map paths.
+  ResourceProvider provider;
+
+  /// The index to be used when creating the next synthetic file name.
+  int nextIndex = 1;
+
+  /// Initialize a newly created path mapper.
+  PathMapper(this.provider);
+
+  /// Gets the symbol used as a path separator on the local filesystem.
+  String get separator => provider.pathContext.separator;
+
+  /// Return the path of the HTML file used to view the content of the analyzed
+  /// file with the given [path].
+  String map(String path) {
+    return provider.pathContext.toUri(path).path;
+  }
+
+  /// Returns the local filesystem path corresponding to the given [uri].
+  String reverseMap(Uri uri) {
+    return provider.pathContext.fromUri(uri);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
new file mode 100644
index 0000000..6b65c50
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
+import 'package:path/path.dart' as path;
+
+/// The HTML that is displayed for a region of code.
+class RegionRenderer {
+  /// A flag indicating whether the incremental workflow is currently supported.
+  static const bool supportsIncrementalWorkflow = true;
+
+  /// The region to render.
+  final RegionInfo region;
+
+  /// The compilation unit information containing the region.
+  final UnitInfo unitInfo;
+
+  final MigrationInfo migrationInfo;
+
+  /// An object used to map the file paths of analyzed files to the file paths
+  /// of the HTML files used to view the content of those files.
+  final PathMapper pathMapper;
+
+  /// Initializes a newly created region page within the given [site]. The
+  /// [unitInfo] provides the information needed to render the page.
+  RegionRenderer(
+      this.region, this.unitInfo, this.migrationInfo, this.pathMapper);
+
+  /// Returns the path context used to manipulate paths.
+  path.Context get pathContext => migrationInfo.pathContext;
+
+  EditDetails render() {
+    var unitDir = pathContext.dirname(pathMapper.map(unitInfo.path));
+
+    TargetLink linkForTarget(NavigationTarget target) {
+      var relativePath = _relativePathToTarget(target, unitDir);
+      var targetUri = _uriForRelativePath(relativePath, target);
+      return TargetLink(
+        path: relativePath,
+        href: targetUri,
+        line: target.line,
+      );
+    }
+
+    EditLink linkForEdit(EditDetail edit) => EditLink(
+        description: edit.description,
+        href: Uri(
+            scheme: 'http',
+            path: pathContext.basename(unitInfo.path),
+            queryParameters: {
+              'offset': edit.offset.toString(),
+              'end': (edit.offset + edit.length).toString(),
+              'replacement': edit.replacement
+            }).toString());
+
+    var response = EditDetails(
+      path: unitInfo.path,
+      line: region.lineNumber,
+      explanation: region.explanation,
+      edits: supportsIncrementalWorkflow
+          ? [
+              for (var edit in region.edits) linkForEdit(edit),
+            ]
+          : null,
+      traces: [
+        for (var trace in region.traces)
+          Trace(description: trace.description, entries: [
+            for (var entry in trace.entries)
+              TraceEntry(
+                  description: entry.description,
+                  function: entry.function,
+                  link:
+                      entry.target == null ? null : linkForTarget(entry.target))
+          ])
+      ],
+    );
+    return response;
+  }
+
+  /// Returns the URL that will navigate to the given [target].
+  String _relativePathToTarget(NavigationTarget target, String unitDir) {
+    if (target == null) {
+      // TODO(brianwilkerson) This is temporary support until we can get targets
+      //  for all nodes.
+      return '';
+    }
+    return pathContext.relative(pathMapper.map(target.filePath), from: unitDir);
+  }
+
+  /// Return the URL that will navigate to the given [target] in the file at the
+  /// given [relativePath].
+  String _uriForRelativePath(String relativePath, NavigationTarget target) {
+    var queryParams = {
+      'offset': target.offset,
+      if (target.line != null) 'line': target.line,
+    }.entries.map((entry) => '${entry.key}=${entry.value}').join('&');
+    return '$relativePath?$queryParams';
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/.clang-format b/pkg/nnbd_migration/lib/src/front_end/resources/.clang-format
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/.clang-format
rename to pkg/nnbd_migration/lib/src/front_end/resources/.clang-format
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.css b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.css
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.css
rename to pkg/nnbd_migration/lib/src/front_end/resources/highlight.css
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.md b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.md
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.md
rename to pkg/nnbd_migration/lib/src/front_end/resources/highlight.md
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.pack.js b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.pack.js
rename to pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/index.html b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
new file mode 100644
index 0000000..48d7a74
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
@@ -0,0 +1,78 @@
+<html>
+<head>
+    <title>Null Safety Preview</title>
+    <script src="{{ highlightJsPath }}"></script>
+    <script>{{ dartPageScript }}</script>
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap">
+    <link rel="stylesheet" href="{{ highlightStylePath }}">
+    <style>{{ dartPageStyle }}</style>
+</head>
+<body class="{{ migrationAppliedStyle }} {{ needsRerunStyle }}">
+<div class="rerunning-pane">
+  <h1>Rerunning...</h1>
+</div>
+<div class="popup-pane">
+  <div class="close button">X</div>
+  <h2></h2><!-- header placeholder element -->
+  <p></p><!-- subheader placeholder element -->
+  <pre></pre><!-- preformated content placeholder element -->
+  <a class="button bottom" target="_blank">File on GitHub</a><!-- post to github placeholder element -->
+</div>
+<p class="root">{{ root }}</p>
+<header class="elevation-z4">
+    <h1 class="before-apply">Proposed null safety changes</h1>
+    <h1 class="after-apply">&#10003; Null safety migration applied</h1>
+    <h2 id="unit-name">&nbsp;</h2>
+    <button class="apply-migration">&#9998; Apply Migration</button>
+    <button class="apply-migration" disabled>&#9998; Apply Migration</button>
+    <button class="rerun-migration before-apply">
+      <span class="optional">&#8635; Rerun From Sources</span>
+      <span class="required">
+        <span class="icon" 
+          title="Disk contents have changed. Rerun to get an up-to-date migration.">!</span>
+        Rerun With Changes
+      </span>
+    </button>
+</header>
+<div class="panels horizontal">
+    <div class="nav-panel">
+        <div class="nav-inner">
+            <div class="panel-heading">Project Files</div>
+            <div class="nav-tree"></div>
+        </div><!-- /nav-inner -->
+    </div><!-- /nav -->
+    <div class="content">
+        <div class="regions">
+            <!-- The regions overlay code copy of the content to provide -->
+            <!-- tooltips for modified regions. -->
+        </div><!-- /regions -->
+        <div class="code">
+            <!-- Compilation unit content is written here. -->
+            <p class="welcome">
+                Select a source file on the left to preview the proposed edits.
+            </p>
+        </div>
+    </div><!-- /content -->
+    <div class="info-panel">
+        <div class="edit-list">
+            <div class="panel-heading">Proposed Edits</div>
+            <div class="panel-content"></div>
+        </div><!-- /edit-list -->
+        <div class="edit-panel">
+            <div class="panel-heading">Edit Details</div>
+            <div class="panel-content">
+                <p class="placeholder">See details about a proposed edit.</p>
+            </div><!-- /panel-content -->
+        </div><!-- /edit-panel -->
+    </div><!-- /info-panel -->
+</div><!-- /panels -->
+<footer>
+    <a target="_blank"
+      href="https://goo.gle/dart-null-safety-migration-tool">Null safety
+        migration help</a>
+    <span class="wide"> </span>
+    <div>Based on <span id="sdk-version">{{ sdkVersion }}</span></div>
+    <button class="report-problem">Report a Problem</button>
+</footer>
+</body>
+</html>
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
new file mode 100644
index 0000000..41940da
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -0,0 +1,569 @@
+/* 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.                   */
+
+body {
+  background-color: #12202f;
+  color: #ccc;
+  font-family: "Roboto", sans-serif;
+  font-size: 14px;
+  display: flex;
+  flex-direction: column;
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  margin: 0;
+  padding: 0;
+  overflow: hidden;
+}
+
+.proposed .after-apply {
+  display: none;
+}
+
+.applied .before-apply {
+  display: none;
+}
+
+.applied .apply-migration:not([disabled]), .needs-rerun .apply-migration:not([disabled]) {
+  display: none;
+}
+
+.proposed:not(.needs-rerun) .apply-migration[disabled] {
+  display: none;
+}
+
+header {
+  background-color: #1c2834;
+  height: 48px;
+  padding-left: 24px;
+  align-items: center;
+  z-index: 4;
+}
+
+header h1,
+header h2 {
+  display: inline-block;
+  font-family: "Google Sans","Roboto",sans-serif;
+  font-weight: 400;
+  margin-right: 24px;
+}
+
+h1 {
+  font-size: 1.5em;
+}
+
+header h2 {
+  font-size: 1.2em;
+}
+
+header .apply-migration, .rerun-migration {
+  right: 0px;
+  float: right;
+  margin: 10px;
+}
+
+footer .report-problem {
+  right: 0px;
+  margin: 4px 8px;
+}
+
+.rerun-migration .required {
+  display: none;
+}
+
+.needs-rerun .rerun-migration .required {
+  display: initial;
+}
+
+.needs-rerun .rerun-migration .optional {
+  display:none;
+}
+
+/* Red triangle */
+.rerun-migration .required .icon::before {
+  transform: translate(-8px, -11px);
+  content: '\25B3';
+  font-size: 25px;
+  position: fixed;
+  color: #e82c2c;
+  text-shadow: 0px 0px 5px white;
+  z-index: -3;
+}
+
+/* Red triangle fill */
+.rerun-migration .required .icon::after {
+  transform: translate(-9px, -10px);
+  content: '\25B4';
+  font-size: 25px;
+  position: fixed;
+  color: #b3ecff;
+  z-index: -1;
+}
+
+/* Red triangle exclamation */
+.rerun-migration .required .icon {
+  display: inline-block;
+  margin-right: 8px;
+  transform: translate(0px, 2px);
+  margin-left: 2px;
+  color: #2b2b2b;
+}
+
+footer {
+  color: #ccc;
+  background-color: #27323a;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding: 8px 0 8px 24px;
+}
+
+footer .wide {
+  flex: 1;
+}
+
+.horizontal {
+  display: flex;
+}
+
+.panels {
+  background-color: #121a25;
+  flex: 1;
+  overflow: hidden;
+}
+
+.panel-heading {
+  color: gray;
+  margin: 8px;
+}
+
+.nav-link,
+.region {
+  cursor: pointer;
+}
+
+.nav-panel {
+  background-color: #282b2e;
+  flex: 1 200px;
+  margin: 0;
+  overflow: scroll;
+}
+
+.nav-inner {
+  padding: 0 0 7px 7px;
+}
+
+.fixed {
+  position: fixed;
+  top: 0;
+}
+
+.root {
+  margin: 0;
+  display: none;
+}
+
+.nav-tree > ul {
+  padding-left: 6px;
+}
+
+.nav-inner ul {
+  padding-left: 12px;
+  margin: 0;
+}
+
+.nav-inner li {
+  list-style-type: none;
+}
+
+.nav-inner li:not(.dir) {
+  margin-left: 20px;
+  margin-bottom: 3px;
+}
+
+.nav-inner li.dir .arrow {
+  cursor: pointer;
+  display: inline-block;
+  font-size: 10px;
+  margin-right: 4px;
+  transition: transform 0.5s ease-out;
+}
+
+.nav-inner li.dir .arrow.collapsed {
+  transform: rotate(-90deg);
+}
+
+.nav-inner ul {
+  max-height: 2000px;
+  transition: max-height 0.5s ease-out;
+}
+
+.nav-inner ul.collapsed {
+  max-height: 0 !important;
+  overflow: hidden;
+}
+
+.nav-inner .selected-file {
+  color: white;
+  cursor: inherit;
+  font-weight: 600;
+  text-decoration: none;
+}
+
+.edit-count {
+  background-color: #37aedc;
+  border-radius: 10px;
+  color: #000000;
+  display: inline-block;
+  font-size: 11px;
+  font-weight: 600;
+  margin-left: 5px;
+  min-width: 25px;
+  padding: 4px 0 2px 0;
+  text-align: center;
+  line-height: 1em;
+}
+
+.content {
+  flex: 4 300px;
+  background: #282b2e;
+  font-family: monospace;
+  margin: 0 6px;
+  position: relative;
+  white-space: pre;
+  overflow: scroll;
+}
+
+.code {
+  padding: 0.5em;
+  position: absolute;
+  left: 0;
+  top: 0;
+  margin-left: 56px;
+}
+
+.hljs {
+  background-color: #282b2e;
+  display: block;
+  overflow-x: auto;
+  padding: 0.5em;
+}
+
+.code .welcome {
+  font-family: "Google Sans","Roboto",sans-serif;
+  font-size: 18px;
+  margin-right: 62px;
+  color: #777;
+}
+
+.code .nav-link {
+  color: inherit;
+  text-decoration-line: none;
+}
+
+.code .nav-link:visited {
+  color: inherit;
+  text-decoration-line: none;
+}
+
+.code .nav-link:hover {
+  text-decoration-line: underline;
+  font-weight: 600;
+}
+
+.regions {
+  padding: 0.5em;
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+
+.regions table {
+  border-spacing: 0;
+  font-size: inherit;
+}
+
+.regions td {
+  border: none;
+  /* The content of the regions is not visible; the user instead will see the
+   * highlighted copy of the content. */
+  color: rgba(255, 255, 255, 0);
+  padding: 0;
+  white-space: pre;
+}
+
+.regions td:empty:after {
+  content: "\00a0";
+}
+
+.regions tr.highlight td:last-child {
+  background-color: #444444;
+  color: white;
+}
+
+.regions td.line-no {
+  border-right: solid #282b2e 2px;
+  color: #999999;
+  padding-right: 4px;
+  text-align: right;
+  visibility: visible;
+  width: 50px;
+  display: inline-block;
+}
+
+.regions tr.highlight td.line-no {
+  border-right: solid #ccc 2px;
+}
+
+.region {
+  display: inline-block;
+  position: relative;
+  visibility: visible;
+  z-index: 200;
+}
+
+.region.added-region {
+  background-color: #ccffcc;
+  color: #003300;
+}
+
+.region.removed-region {
+  background-color: #ff6666;
+  color: #001100;
+}
+
+.region.informative-region {
+  background-color: #888888;
+  color: #000000;
+}
+
+.target {
+  background-color: #444;
+  position: relative;
+  visibility: visible;
+  font-weight: 600;
+}
+
+.info-panel {
+  flex: 1 200px;
+  margin: 0;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.info-panel .edit-panel {
+  background-color: #282b2e;
+  overflow: auto;
+}
+
+.info-panel .panel-content {
+  padding: 7px;
+}
+
+.info-panel .panel-content> :first-child {
+  margin-top: 0;
+}
+
+.info-panel .nowrap {
+  white-space: nowrap;
+}
+
+.info-panel ul,
+.info-panel ol {
+  padding-left: 20px;
+}
+
+.info-panel li {
+  margin: 0 0 5px 0;
+}
+
+.info-panel a {
+  color: #33ccff;
+}
+
+.info-panel .edit-list {
+  background-color: #282b2e;
+  overflow: auto;
+}
+
+.edit-panel {
+  margin-top: 6px;
+  flex: 1 100px;
+}
+
+.edit-list {
+  flex: 2 100px;
+}
+
+.edit-list .edit {
+  margin: 3px 0;
+}
+
+.edit-list .edit-link {
+  cursor: pointer;
+}
+
+.popup-pane {
+  display: none;
+  position: fixed;
+  top: 150px;
+  left: 150px;
+  right: 150px;
+  bottom: 150px;
+  border: 1px solid black;
+  border-top: 2px solid black;
+  border-radius: 7px;
+  box-shadow: 0px 0px 20px 2px #b4bfcb22;
+  z-index: 1;
+  background: #2b3036;
+  padding: 20px;
+}
+
+.popup-pane .close {
+  position: absolute;
+  right: 10px;
+  top: 10px;
+  cursor: pointer;
+  text-shadow: 1px 1px 2px #888;
+  box-shadow: 1px 1px 2px #111;
+}
+
+.popup-pane h2 {
+  padding: 21px;
+  height: 10%;
+  margin: 0px;
+  box-sizing: border-box;
+}
+
+.popup-pane p {
+  height: 10%;
+  box-sizing: border-box;
+  padding: 0px 20px;
+}
+
+.popup-pane pre {
+  background: #282b2e;
+  padding: 20px;
+  bottom: 0px;
+  overflow: auto scroll;
+  height: 65%;
+  margin: 0px;
+  box-sizing: border-box;
+}
+
+.popup-pane .button.bottom {
+  margin: 20px 0px;
+  display: block;
+  text-align: center;
+}
+
+.rerunning-pane {
+  display: none;
+}
+
+body.rerunning .rerunning-pane {
+  display: block;
+  position: fixed;
+  top: 0px;
+  bottom: 0px;
+  left: 0px;
+  right: 0px;
+  background-color: #000000AA; /* translucent black */
+  z-index: 400;
+}
+
+.rerunning-pane h1 {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+
+p.trace .type-description {
+  /* From HLJS's .hljs-keyword, .hljs-selector-tag, .hljs-deletion */
+  color: #cc7832;
+  font-family: monospace;
+}
+
+ul.trace {
+  font-size: 13px;
+  list-style-type: none;
+  padding-left: 0px;
+}
+
+ul.trace li {
+  color: white;
+  margin-left: 14px;
+  text-indent: -14px;
+}
+
+ul.trace li .function {
+  /* From HLJS's .hljs-section, .hljs-title, .hljs-type */
+  color: #ffc66d;
+  font-family: monospace;
+  font-weight: 600;
+}
+
+.elevation-z4 {
+  box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
+      0px 4px 5px 0px rgba(0, 0, 0, 0.14),
+      0px 1px 10px 0px rgba(0, 0, 0, .12);
+}
+
+a {
+  color: #ccc;
+  fill: #ccc;
+  text-decoration: none;
+}
+
+a:hover {
+  color: #fff;
+  fill: #fff;
+}
+
+.add-hint-link {
+  display: inline-block;
+  margin: 3px;
+}
+
+button, a.button {
+  background-color: #33ccff;
+  border: 2px solid #37aedc;
+  border-radius: 3px;
+  padding: 6px 10px;
+  font-weight: bold;
+  color: #282828;
+}
+
+button:hover, .button:hover {
+  background-color: #80dfff;
+  border: 2px solid #52b8e0;
+  cursor: pointer;
+}
+
+button[disabled] {
+  background-color: #7aa8b8;
+  color: #507177;
+  border: 2px solid #507177;
+  cursor: not-allowed;
+}
+
+.placeholder {
+  color: #777;
+  text-align: center;
+  margin-top: 3em !important;
+}
+
+/**
+ * HLJS Overrides
+ */
+.hljs {
+  /**
+   * This allows the per-line highlights to show.
+   */
+  background: none;
+}
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
new file mode 100644
index 0000000..5bef8d6
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -0,0 +1,4134 @@
+// 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 is generated; don't edit it directly.
+//
+// See pkg/nnbd_migration/tool/codegen/generate_resources.dart for how
+// to edit the source content and for re-generation instructions.
+
+import 'dart:convert' as convert;
+
+String get highlight_css {
+  return _highlight_css ??= _decode(_highlight_css_base64);
+}
+
+String get highlight_pack_js {
+  return _highlight_pack_js ??= _decode(_highlight_pack_js_base64);
+}
+
+String get index_html {
+  return _index_html ??= _decode(_index_html_base64);
+}
+
+String get migration_css {
+  return _migration_css ??= _decode(_migration_css_base64);
+}
+
+String get migration_js {
+  return _migration_js ??= _decode(_migration_js_base64);
+}
+
+String _decode(String data) {
+  data = data.replaceAll('\n', '').trim();
+  return String.fromCharCodes(convert.base64Decode(data));
+}
+
+String _highlight_css;
+// highlight_css md5 is 'fb012626bafd286510d32da815dae448'
+String _highlight_css_base64 = '''
+LyoKRGF0ZTogMjQgRmV2IDIwMTUKQXV0aG9yOiBQZWRybyBPbGl2ZWlyYSA8a2FueXR1QGdtYWlsIC4g
+Y29tPgoqLwoKLmhsanMgewogIGNvbG9yOiAjYTliN2M2OwogIGJhY2tncm91bmQ6ICMyODJiMmU7CiAg
+ZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKfQoKLmhs
+anMtbnVtYmVyLAouaGxqcy1saXRlcmFsLAouaGxqcy1zeW1ib2wsCi5obGpzLWJ1bGxldCB7CiAgY29s
+b3I6ICM2ODk3QkI7Cn0KCi5obGpzLWtleXdvcmQsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhsanMtZGVs
+ZXRpb24gewogIGNvbG9yOiAjY2M3ODMyOwp9CgouaGxqcy12YXJpYWJsZSwKLmhsanMtdGVtcGxhdGUt
+dmFyaWFibGUsCi5obGpzLWxpbmsgewogIGNvbG9yOiAjNjI5NzU1Owp9CgouaGxqcy1jb21tZW50LAou
+aGxqcy1xdW90ZSB7CiAgY29sb3I6ICM4MDgwODA7Cn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjYmJi
+NTI5Owp9CgouaGxqcy1zdHJpbmcsCi5obGpzLWF0dHJpYnV0ZSwKLmhsanMtYWRkaXRpb24gewogIGNv
+bG9yOiAjNkE4NzU5Owp9CgouaGxqcy1zZWN0aW9uLAouaGxqcy10aXRsZSwKLmhsanMtdHlwZSB7CiAg
+Y29sb3I6ICNmZmM2NmQ7Cn0KCi5obGpzLW5hbWUsCi5obGpzLXNlbGVjdG9yLWlkLAouaGxqcy1zZWxl
+Y3Rvci1jbGFzcyB7CiAgY29sb3I6ICNlOGJmNmE7Cn0KCi5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0
+eWxlOiBpdGFsaWM7Cn0KCi5obGpzLXN0cm9uZyB7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7Cn0K
+''';
+
+String _highlight_pack_js;
+// highlight_pack_js md5 is '9104bfe8b056f8e00da50b0ea3d6e6d4'
+String _highlight_pack_js_base64 = '''
+LyohIGhpZ2hsaWdodC5qcyB2OS4xNS4xMCB8IEJTRDMgTGljZW5zZSB8IGdpdC5pby9obGpzbGljZW5z
+ZSAqLwohZnVuY3Rpb24oZSl7dmFyIG49Im9iamVjdCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvd3x8Im9i
+amVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmOyJ1bmRlZmluZWQiPT10eXBlb2YgZXhwb3J0c3x8ZXhwb3J0
+cy5ub2RlVHlwZT9uJiYobi5obGpzPWUoe30pLCJmdW5jdGlvbiI9PXR5cGVvZiBkZWZpbmUmJmRlZmlu
+ZS5hbWQmJmRlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiBuLmhsanN9KSk6ZShleHBvcnRzKX0oZnVu
+Y3Rpb24oYSl7dmFyIGY9W10sdT1PYmplY3Qua2V5cyxOPXt9LGM9e30sbj0vXihuby0/aGlnaGxpZ2h0
+fHBsYWlufHRleHQpJC9pLHM9L1xibGFuZyg/OnVhZ2UpPy0oW1x3LV0rKVxiL2ksdD0vKCheKDxbXj5d
+Kz58XHR8KSt8KD86XG4pKSkvZ20scj17Y2FzZV9pbnNlbnNpdGl2ZToiY0kiLGxleGVtZXM6ImwiLGNv
+bnRhaW5zOiJjIixrZXl3b3JkczoiayIsc3ViTGFuZ3VhZ2U6InNMIixjbGFzc05hbWU6ImNOIixiZWdp
+bjoiYiIsYmVnaW5LZXl3b3JkczoiYksiLGVuZDoiZSIsZW5kc1dpdGhQYXJlbnQ6ImVXIixpbGxlZ2Fs
+OiJpIixleGNsdWRlQmVnaW46ImVCIixleGNsdWRlRW5kOiJlRSIscmV0dXJuQmVnaW46InJCIixyZXR1
+cm5FbmQ6InJFIixyZWxldmFuY2U6InIiLHZhcmlhbnRzOiJ2IixJREVOVF9SRToiSVIiLFVOREVSU0NP
+UkVfSURFTlRfUkU6IlVJUiIsTlVNQkVSX1JFOiJOUiIsQ19OVU1CRVJfUkU6IkNOUiIsQklOQVJZX05V
+TUJFUl9SRToiQk5SIixSRV9TVEFSVEVSU19SRToiUlNSIixCQUNLU0xBU0hfRVNDQVBFOiJCRSIsQVBP
+U19TVFJJTkdfTU9ERToiQVNNIixRVU9URV9TVFJJTkdfTU9ERToiUVNNIixQSFJBU0FMX1dPUkRTX01P
+REU6IlBXTSIsQ19MSU5FX0NPTU1FTlRfTU9ERToiQ0xDTSIsQ19CTE9DS19DT01NRU5UX01PREU6IkNC
+Q00iLEhBU0hfQ09NTUVOVF9NT0RFOiJIQ00iLE5VTUJFUl9NT0RFOiJOTSIsQ19OVU1CRVJfTU9ERToi
+Q05NIixCSU5BUllfTlVNQkVSX01PREU6IkJOTSIsQ1NTX05VTUJFUl9NT0RFOiJDU1NOTSIsUkVHRVhQ
+X01PREU6IlJNIixUSVRMRV9NT0RFOiJUTSIsVU5ERVJTQ09SRV9USVRMRV9NT0RFOiJVVE0iLENPTU1F
+TlQ6IkMiLGJlZ2luUmU6ImJSIixlbmRSZToiZVIiLGlsbGVnYWxSZToiaVIiLGxleGVtZXNSZToibFIi
+LHRlcm1pbmF0b3JzOiJ0Iix0ZXJtaW5hdG9yX2VuZDoidEUifSxiPSI8L3NwYW4+IixoPXtjbGFzc1By
+ZWZpeDoiaGxqcy0iLHRhYlJlcGxhY2U6bnVsbCx1c2VCUjohMSxsYW5ndWFnZXM6dm9pZCAwfTtmdW5j
+dGlvbiBfKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsi
+KS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiBFKGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93
+ZXJDYXNlKCl9ZnVuY3Rpb24gdihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQu
+aW5kZXh9ZnVuY3Rpb24gbChlKXtyZXR1cm4gbi50ZXN0KGUpfWZ1bmN0aW9uIGcoZSl7dmFyIG4sdD17
+fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09
+ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1m
+dW5jdGlvbiBSKGUpe3ZhciBhPVtdO3JldHVybiBmdW5jdGlvbiBlKG4sdCl7Zm9yKHZhciByPW4uZmly
+c3RDaGlsZDtyO3I9ci5uZXh0U2libGluZykzPT09ci5ub2RlVHlwZT90Kz1yLm5vZGVWYWx1ZS5sZW5n
+dGg6MT09PXIubm9kZVR5cGUmJihhLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnQsbm9kZTpyfSks
+dD1lKHIsdCksRShyKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fGEucHVzaCh7ZXZlbnQ6InN0b3Ai
+LG9mZnNldDp0LG5vZGU6cn0pKTtyZXR1cm4gdH0oZSwwKSxhfWZ1bmN0aW9uIGkoZSl7aWYociYmIWUu
+bGFuZ0FwaVJlc3RvcmVkKXtmb3IodmFyIG4gaW4gZS5sYW5nQXBpUmVzdG9yZWQ9ITAscillW25dJiYo
+ZVtyW25dXT1lW25dKTsoZS5jfHxbXSkuY29uY2F0KGUudnx8W10pLmZvckVhY2goaSl9fWZ1bmN0aW9u
+IG0obyl7ZnVuY3Rpb24gcyhlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gYyhlLG4pe3Jl
+dHVybiBuZXcgUmVnRXhwKHMoZSksIm0iKyhvLmNJPyJpIjoiIikrKG4/ImciOiIiKSl9IWZ1bmN0aW9u
+IG4odCxlKXtpZighdC5jb21waWxlZCl7aWYodC5jb21waWxlZD0hMCx0Lms9dC5rfHx0LmJLLHQuayl7
+ZnVuY3Rpb24gcih0LGUpe28uY0kmJihlPWUudG9Mb3dlckNhc2UoKSksZS5zcGxpdCgiICIpLmZvckVh
+Y2goZnVuY3Rpb24oZSl7dmFyIG49ZS5zcGxpdCgifCIpO2FbblswXV09W3QsblsxXT9OdW1iZXIoblsx
+XSk6MV19KX12YXIgYT17fTsic3RyaW5nIj09dHlwZW9mIHQuaz9yKCJrZXl3b3JkIix0LmspOnUodC5r
+KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3IoZSx0LmtbZV0pfSksdC5rPWF9dC5sUj1jKHQubHx8L1x3Ky8s
+ITApLGUmJih0LmJLJiYodC5iPSJcXGIoIit0LmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiks
+dC5ifHwodC5iPS9cQnxcYi8pLHQuYlI9Yyh0LmIpLHQuZW5kU2FtZUFzQmVnaW4mJih0LmU9dC5iKSx0
+LmV8fHQuZVd8fCh0LmU9L1xCfFxiLyksdC5lJiYodC5lUj1jKHQuZSkpLHQudEU9cyh0LmUpfHwiIix0
+LmVXJiZlLnRFJiYodC50RSs9KHQuZT8ifCI6IiIpK2UudEUpKSx0LmkmJih0LmlSPWModC5pKSksbnVs
+bD09dC5yJiYodC5yPTEpLHQuY3x8KHQuYz1bXSksdC5jPUFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBw
+bHkoW10sdC5jLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4udiYmIW4u
+Y2FjaGVkX3ZhcmlhbnRzJiYobi5jYWNoZWRfdmFyaWFudHM9bi52Lm1hcChmdW5jdGlvbihlKXtyZXR1
+cm4gZyhuLHt2Om51bGx9LGUpfSkpLG4uY2FjaGVkX3ZhcmlhbnRzfHxuLmVXJiZbZyhuKV18fFtuXX0o
+InNlbGYiPT09ZT90OmUpfSkpLHQuYy5mb3JFYWNoKGZ1bmN0aW9uKGUpe24oZSx0KX0pLHQuc3RhcnRz
+JiZuKHQuc3RhcnRzLGUpO3ZhciBpPXQuYy5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGUuYks/IlxcLj8o
+PzoiK2UuYisiKVxcLj8iOmUuYn0pLmNvbmNhdChbdC50RSx0LmldKS5tYXAocykuZmlsdGVyKEJvb2xl
+YW4pO3QudD1pLmxlbmd0aD9jKGZ1bmN0aW9uKGUsbil7Zm9yKHZhciB0PS9cWyg/OlteXFxcXV18XFwu
+KSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixpPTA7aTxlLmxlbmd0aDtpKysp
+e3ZhciBvPXIsYz1zKGVbaV0pO2ZvcigwPGkmJihhKz1uKTswPGMubGVuZ3RoOyl7dmFyIHU9dC5leGVj
+KGMpO2lmKG51bGw9PXUpe2ErPWM7YnJlYWt9YSs9Yy5zdWJzdHJpbmcoMCx1LmluZGV4KSxjPWMuc3Vi
+c3RyaW5nKHUuaW5kZXgrdVswXS5sZW5ndGgpLCJcXCI9PXVbMF1bMF0mJnVbMV0/YSs9IlxcIitTdHJp
+bmcoTnVtYmVyKHVbMV0pK28pOihhKz11WzBdLCIoIj09dVswXSYmcisrKX19cmV0dXJuIGF9KGksInwi
+KSwhMCk6e2V4ZWM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH19fX0obyl9ZnVuY3Rpb24gQyhlLG4saSx0
+KXtmdW5jdGlvbiBjKGUsbix0LHIpe3ZhciBhPSc8c3BhbiBjbGFzcz0iJysocj8iIjpoLmNsYXNzUHJl
+Zml4KTtyZXR1cm4gZT8oYSs9ZSsnIj4nKStuKyh0PyIiOmIpOm59ZnVuY3Rpb24gbygpe0UrPW51bGwh
+PWwuc0w/ZnVuY3Rpb24oKXt2YXIgZT0ic3RyaW5nIj09dHlwZW9mIGwuc0w7aWYoZSYmIU5bbC5zTF0p
+cmV0dXJuIF8oZyk7dmFyIG49ZT9DKGwuc0wsZywhMCxmW2wuc0xdKTpPKGcsbC5zTC5sZW5ndGg/bC5z
+TDp2b2lkIDApO3JldHVybiAwPGwuciYmKFIrPW4uciksZSYmKGZbbC5zTF09bi50b3ApLGMobi5sYW5n
+dWFnZSxuLnZhbHVlLCExLCEwKX0oKTpmdW5jdGlvbigpe3ZhciBlLG4sdCxyLGEsaSxvO2lmKCFsLmsp
+cmV0dXJuIF8oZyk7Zm9yKHI9IiIsbj0wLGwubFIubGFzdEluZGV4PTAsdD1sLmxSLmV4ZWMoZyk7dDsp
+cis9XyhnLnN1YnN0cmluZyhuLHQuaW5kZXgpKSxhPWwsaT10LHZvaWQgMCxvPXMuY0k/aVswXS50b0xv
+d2VyQ2FzZSgpOmlbMF0sKGU9YS5rLmhhc093blByb3BlcnR5KG8pJiZhLmtbb10pPyhSKz1lWzFdLHIr
+PWMoZVswXSxfKHRbMF0pKSk6cis9Xyh0WzBdKSxuPWwubFIubGFzdEluZGV4LHQ9bC5sUi5leGVjKGcp
+O3JldHVybiByK18oZy5zdWJzdHIobikpfSgpLGc9IiJ9ZnVuY3Rpb24gdShlKXtFKz1lLmNOP2MoZS5j
+TiwiIiwhMCk6IiIsbD1PYmplY3QuY3JlYXRlKGUse3BhcmVudDp7dmFsdWU6bH19KX1mdW5jdGlvbiBy
+KGUsbil7aWYoZys9ZSxudWxsPT1uKXJldHVybiBvKCksMDt2YXIgdD1mdW5jdGlvbihlLG4pe3ZhciB0
+LHIsYTtmb3IodD0wLHI9bi5jLmxlbmd0aDt0PHI7dCsrKWlmKHYobi5jW3RdLmJSLGUpKXJldHVybiBu
+LmNbdF0uZW5kU2FtZUFzQmVnaW4mJihuLmNbdF0uZVI9KGE9bi5jW3RdLmJSLmV4ZWMoZSlbMF0sbmV3
+IFJlZ0V4cChhLnJlcGxhY2UoL1stXC9cXF4kKis/LigpfFtcXXt9XS9nLCJcXCQmIiksIm0iKSkpLG4u
+Y1t0XX0obixsKTtpZih0KXJldHVybiB0LnNraXA/Zys9bjoodC5lQiYmKGcrPW4pLG8oKSx0LnJCfHx0
+LmVCfHwoZz1uKSksdSh0KSx0LnJCPzA6bi5sZW5ndGg7dmFyIHI9ZnVuY3Rpb24gZShuLHQpe2lmKHYo
+bi5lUix0KSl7Zm9yKDtuLmVuZHNQYXJlbnQmJm4ucGFyZW50OyluPW4ucGFyZW50O3JldHVybiBufWlm
+KG4uZVcpcmV0dXJuIGUobi5wYXJlbnQsdCl9KGwsbik7aWYocil7dmFyIGE9bDtmb3IoYS5za2lwP2cr
+PW46KGEuckV8fGEuZUV8fChnKz1uKSxvKCksYS5lRSYmKGc9bikpO2wuY04mJihFKz1iKSxsLnNraXB8
+fGwuc0x8fChSKz1sLnIpLChsPWwucGFyZW50KSE9PXIucGFyZW50Oyk7cmV0dXJuIHIuc3RhcnRzJiYo
+ci5lbmRTYW1lQXNCZWdpbiYmKHIuc3RhcnRzLmVSPXIuZVIpLHUoci5zdGFydHMpKSxhLnJFPzA6bi5s
+ZW5ndGh9aWYoZnVuY3Rpb24oZSxuKXtyZXR1cm4haSYmdihuLmlSLGUpfShuLGwpKXRocm93IG5ldyBF
+cnJvcignSWxsZWdhbCBsZXhlbWUgIicrbisnIiBmb3IgbW9kZSAiJysobC5jTnx8Ijx1bm5hbWVkPiIp
+KyciJyk7cmV0dXJuIGcrPW4sbi5sZW5ndGh8fDF9dmFyIHM9QihlKTtpZighcyl0aHJvdyBuZXcgRXJy
+b3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTttKHMpO3ZhciBhLGw9dHx8cyxmPXt9LEU9IiI7
+Zm9yKGE9bDthIT09czthPWEucGFyZW50KWEuY04mJihFPWMoYS5jTiwiIiwhMCkrRSk7dmFyIGc9IiIs
+Uj0wO3RyeXtmb3IodmFyIGQscCxNPTA7bC50Lmxhc3RJbmRleD1NLGQ9bC50LmV4ZWMobik7KXA9cihu
+LnN1YnN0cmluZyhNLGQuaW5kZXgpLGRbMF0pLE09ZC5pbmRleCtwO2ZvcihyKG4uc3Vic3RyKE0pKSxh
+PWw7YS5wYXJlbnQ7YT1hLnBhcmVudClhLmNOJiYoRSs9Yik7cmV0dXJue3I6Uix2YWx1ZTpFLGxhbmd1
+YWdlOmUsdG9wOmx9fWNhdGNoKGUpe2lmKGUubWVzc2FnZSYmLTEhPT1lLm1lc3NhZ2UuaW5kZXhPZigi
+SWxsZWdhbCIpKXJldHVybntyOjAsdmFsdWU6XyhuKX07dGhyb3cgZX19ZnVuY3Rpb24gTyh0LGUpe2U9
+ZXx8aC5sYW5ndWFnZXN8fHUoTik7dmFyIHI9e3I6MCx2YWx1ZTpfKHQpfSxhPXI7cmV0dXJuIGUuZmls
+dGVyKEIpLmZpbHRlcihNKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBuPUMoZSx0LCExKTtuLmxhbmd1
+YWdlPWUsbi5yPmEuciYmKGE9biksbi5yPnIuciYmKGE9cixyPW4pfSksYS5sYW5ndWFnZSYmKHIuc2Vj
+b25kX2Jlc3Q9YSkscn1mdW5jdGlvbiBkKGUpe3JldHVybiBoLnRhYlJlcGxhY2V8fGgudXNlQlI/ZS5y
+ZXBsYWNlKHQsZnVuY3Rpb24oZSxuKXtyZXR1cm4gaC51c2VCUiYmIlxuIj09PWU/Ijxicj4iOmgudGFi
+UmVwbGFjZT9uLnJlcGxhY2UoL1x0L2csaC50YWJSZXBsYWNlKToiIn0pOmV9ZnVuY3Rpb24gbyhlKXt2
+YXIgbix0LHIsYSxpLG89ZnVuY3Rpb24oZSl7dmFyIG4sdCxyLGEsaT1lLmNsYXNzTmFtZSsiICI7aWYo
+aSs9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1zLmV4ZWMoaSkpcmV0dXJu
+IEIodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobj0wLHI9KGk9aS5zcGxpdCgvXHMrLykpLmxl
+bmd0aDtuPHI7bisrKWlmKGwoYT1pW25dKXx8QihhKSlyZXR1cm4gYX0oZSk7bChvKXx8KGgudXNlQlI/
+KG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwi
+ZGl2IikpLmlubmVySFRNTD1lLmlubmVySFRNTC5yZXBsYWNlKC9cbi9nLCIiKS5yZXBsYWNlKC88YnJb
+IFwvXSo+L2csIlxuIik6bj1lLGk9bi50ZXh0Q29udGVudCxyPW8/QyhvLGksITApOk8oaSksKHQ9Uihu
+KSkubGVuZ3RoJiYoKGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8x
+OTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1yLnZhbHVlLHIudmFsdWU9ZnVuY3Rpb24oZSxuLHQp
+e3ZhciByPTAsYT0iIixpPVtdO2Z1bmN0aW9uIG8oKXtyZXR1cm4gZS5sZW5ndGgmJm4ubGVuZ3RoP2Vb
+MF0ub2Zmc2V0IT09blswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8blswXS5vZmZzZXQ/ZTpuOiJzdGFydCI9
+PT1uWzBdLmV2ZW50P2U6bjplLmxlbmd0aD9lOm59ZnVuY3Rpb24gYyhlKXthKz0iPCIrRShlKStmLm1h
+cC5jYWxsKGUuYXR0cmlidXRlcyxmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsnPSInK18o
+ZS52YWx1ZSkucmVwbGFjZSgnIicsIiZxdW90OyIpKyciJ30pLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1
+KGUpe2ErPSI8LyIrRShlKSsiPiJ9ZnVuY3Rpb24gcyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShl
+Lm5vZGUpfWZvcig7ZS5sZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGw9bygpO2lmKGErPV8odC5zdWJzdHJp
+bmcocixsWzBdLm9mZnNldCkpLHI9bFswXS5vZmZzZXQsbD09PWUpe2ZvcihpLnJldmVyc2UoKS5mb3JF
+YWNoKHUpO3MobC5zcGxpY2UoMCwxKVswXSksKGw9bygpKT09PWUmJmwubGVuZ3RoJiZsWzBdLm9mZnNl
+dD09PXI7KTtpLnJldmVyc2UoKS5mb3JFYWNoKGMpfWVsc2Uic3RhcnQiPT09bFswXS5ldmVudD9pLnB1
+c2gobFswXS5ub2RlKTppLnBvcCgpLHMobC5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIGErXyh0LnN1YnN0
+cihyKSl9KHQsUihhKSxpKSksci52YWx1ZT1kKHIudmFsdWUpLGUuaW5uZXJIVE1MPXIudmFsdWUsZS5j
+bGFzc05hbWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPW4/Y1tuXTp0LGE9W2UudHJpbSgpXTtyZXR1cm4g
+ZS5tYXRjaCgvXGJobGpzXGIvKXx8YS5wdXNoKCJobGpzIiksLTE9PT1lLmluZGV4T2YocikmJmEucHVz
+aChyKSxhLmpvaW4oIiAiKS50cmltKCl9KGUuY2xhc3NOYW1lLG8sci5sYW5ndWFnZSksZS5yZXN1bHQ9
+e2xhbmd1YWdlOnIubGFuZ3VhZ2UscmU6ci5yfSxyLnNlY29uZF9iZXN0JiYoZS5zZWNvbmRfYmVzdD17
+bGFuZ3VhZ2U6ci5zZWNvbmRfYmVzdC5sYW5ndWFnZSxyZTpyLnNlY29uZF9iZXN0LnJ9KSl9ZnVuY3Rp
+b24gcCgpe2lmKCFwLmNhbGxlZCl7cC5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlTZWxlY3Rv
+ckFsbCgicHJlIGNvZGUiKTtmLmZvckVhY2guY2FsbChlLG8pfX1mdW5jdGlvbiBCKGUpe3JldHVybiBl
+PShlfHwiIikudG9Mb3dlckNhc2UoKSxOW2VdfHxOW2NbZV1dfWZ1bmN0aW9uIE0oZSl7dmFyIG49Qihl
+KTtyZXR1cm4gbiYmIW4uZGlzYWJsZUF1dG9kZXRlY3R9cmV0dXJuIGEuaGlnaGxpZ2h0PUMsYS5oaWdo
+bGlnaHRBdXRvPU8sYS5maXhNYXJrdXA9ZCxhLmhpZ2hsaWdodEJsb2NrPW8sYS5jb25maWd1cmU9ZnVu
+Y3Rpb24oZSl7aD1nKGgsZSl9LGEuaW5pdEhpZ2hsaWdodGluZz1wLGEuaW5pdEhpZ2hsaWdodGluZ09u
+TG9hZD1mdW5jdGlvbigpe2FkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLHAsITEpLGFk
+ZEV2ZW50TGlzdGVuZXIoImxvYWQiLHAsITEpfSxhLnJlZ2lzdGVyTGFuZ3VhZ2U9ZnVuY3Rpb24obixl
+KXt2YXIgdD1OW25dPWUoYSk7aSh0KSx0LmFsaWFzZXMmJnQuYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9u
+KGUpe2NbZV09bn0pfSxhLmxpc3RMYW5ndWFnZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdShOKX0sYS5nZXRM
+YW5ndWFnZT1CLGEuYXV0b0RldGVjdGlvbj1NLGEuaW5oZXJpdD1nLGEuSVI9YS5JREVOVF9SRT0iW2Et
+ekEtWl1cXHcqIixhLlVJUj1hLlVOREVSU0NPUkVfSURFTlRfUkU9IlthLXpBLVpfXVxcdyoiLGEuTlI9
+YS5OVU1CRVJfUkU9IlxcYlxcZCsoXFwuXFxkKyk/IixhLkNOUj1hLkNfTlVNQkVSX1JFPSIoLT8pKFxc
+YjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQr
+KT8pIixhLkJOUj1hLkJJTkFSWV9OVU1CRVJfUkU9IlxcYigwYlswMV0rKSIsYS5SU1I9YS5SRV9TVEFS
+VEVSU19SRT0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8LXwtPXwvPXwv
+fDp8O3w8PHw8PD18PD18PHw9PT18PT18PXw+Pj49fD4+PXw+PXw+Pj58Pj58PnxcXD98XFxbfFxce3xc
+XCh8XFxefFxcXj18XFx8fFxcfD18XFx8XFx8fH4iLGEuQkU9YS5CQUNLU0xBU0hfRVNDQVBFPXtiOiJc
+XFxcW1xcc1xcU10iLHI6MH0sYS5BU009YS5BUE9TX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiIn
+IixlOiInIixpOiJcXG4iLGM6W2EuQkVdfSxhLlFTTT1hLlFVT1RFX1NUUklOR19NT0RFPXtjTjoic3Ry
+aW5nIixiOiciJyxlOiciJyxpOiJcXG4iLGM6W2EuQkVdfSxhLlBXTT1hLlBIUkFTQUxfV09SRFNfTU9E
+RT17YjovXGIoYXxhbnx0aGV8YXJlfEknbXxpc24ndHxkb24ndHxkb2Vzbid0fHdvbid0fGJ1dHxqdXN0
+fHNob3VsZHxwcmV0dHl8c2ltcGx5fGVub3VnaHxnb25uYXxnb2luZ3x3dGZ8c298c3VjaHx3aWxsfHlv
+dXx5b3VyfHRoZXl8bGlrZXxtb3JlKVxiL30sYS5DPWEuQ09NTUVOVD1mdW5jdGlvbihlLG4sdCl7dmFy
+IHI9YS5pbmhlcml0KHtjTjoiY29tbWVudCIsYjplLGU6bixjOltdfSx0fHx7fSk7cmV0dXJuIHIuYy5w
+dXNoKGEuUFdNKSxyLmMucHVzaCh7Y046ImRvY3RhZyIsYjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xY
+WFgpOiIscjowfSkscn0sYS5DTENNPWEuQ19MSU5FX0NPTU1FTlRfTU9ERT1hLkMoIi8vIiwiJCIpLGEu
+Q0JDTT1hLkNfQkxPQ0tfQ09NTUVOVF9NT0RFPWEuQygiL1xcKiIsIlxcKi8iKSxhLkhDTT1hLkhBU0hf
+Q09NTUVOVF9NT0RFPWEuQygiIyIsIiQiKSxhLk5NPWEuTlVNQkVSX01PREU9e2NOOiJudW1iZXIiLGI6
+YS5OUixyOjB9LGEuQ05NPWEuQ19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLkNOUixyOjB9LGEu
+Qk5NPWEuQklOQVJZX05VTUJFUl9NT0RFPXtjTjoibnVtYmVyIixiOmEuQk5SLHI6MH0sYS5DU1NOTT1h
+LkNTU19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLk5SKyIoJXxlbXxleHxjaHxyZW18dnd8dmh8
+dm1pbnx2bWF4fGNtfG1tfGlufHB0fHBjfHB4fGRlZ3xncmFkfHJhZHx0dXJufHN8bXN8SHp8a0h6fGRw
+aXxkcGNtfGRwcHgpPyIscjowfSxhLlJNPWEuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxl
+Oi9cL1tnaW11eV0qLyxpOi9cbi8sYzpbYS5CRSx7YjovXFsvLGU6L1xdLyxyOjAsYzpbYS5CRV19XX0s
+YS5UTT1hLlRJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLklSLHI6MH0sYS5VVE09YS5VTkRFUlNDT1JF
+X1RJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLlVJUixyOjB9LGEuTUVUSE9EX0dVQVJEPXtiOiJcXC5c
+XHMqIithLlVJUixyOjB9LGF9KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24ocyl7
+dmFyIGU9e2VXOiEwLGk6LzwvLHI6MCxjOlt7Y046ImF0dHIiLGI6IltBLVphLXowLTlcXC5fOi1dKyIs
+cjowfSx7YjovPVxzKi8scjowLGM6W3tjTjoic3RyaW5nIixlbmRzUGFyZW50OiEwLHY6W3tiOi8iLyxl
+Oi8iL30se2I6LycvLGU6LycvfSx7YjovW15ccyInPTw+YF0rL31dfV19XX07cmV0dXJue2FsaWFzZXM6
+WyJodG1sIiwieGh0bWwiLCJyc3MiLCJhdG9tIiwieGpiIiwieHNkIiwieHNsIiwicGxpc3QiLCJ3c2Yi
+XSxjSTohMCxjOlt7Y046Im1ldGEiLGI6IjwhRE9DVFlQRSIsZToiPiIscjoxMCxjOlt7YjoiXFxbIixl
+OiJcXF0ifV19LHMuQygiXHgzYyEtLSIsIi0tXHgzZSIse3I6MTB9KSx7YjoiPFxcIVxcW0NEQVRBXFxb
+IixlOiJcXF1cXF0+IixyOjEwfSx7Y046Im1ldGEiLGI6LzxcP3htbC8sZTovXD8+LyxyOjEwfSx7Yjov
+PFw/KHBocCk/LyxlOi9cPz4vLHNMOiJwaHAiLGM6W3tiOiIvXFwqIixlOiJcXCovIixza2lwOiEwfSx7
+YjonYiInLGU6JyInLHNraXA6ITB9LHtiOiJiJyIsZToiJyIsc2tpcDohMH0scy5pbmhlcml0KHMuQVNN
+LHtpOm51bGwsY046bnVsbCxjOm51bGwsc2tpcDohMH0pLHMuaW5oZXJpdChzLlFTTSx7aTpudWxsLGNO
+Om51bGwsYzpudWxsLHNraXA6ITB9KV19LHtjTjoidGFnIixiOiI8c3R5bGUoPz1cXHN8PnwkKSIsZToi
+PiIsazp7bmFtZToic3R5bGUifSxjOltlXSxzdGFydHM6e2U6Ijwvc3R5bGU+IixyRTohMCxzTDpbImNz
+cyIsInhtbCJdfX0se2NOOiJ0YWciLGI6IjxzY3JpcHQoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToi
+c2NyaXB0In0sYzpbZV0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTohMCxzTDpbImFjdGlvbnNjcmlw
+dCIsImphdmFzY3JpcHQiLCJoYW5kbGViYXJzIiwieG1sIiwidmJzY3JpcHQiXX19LHtjTjoidGFnIixi
+OiI8Lz8iLGU6Ii8/PiIsYzpbe2NOOiJuYW1lIixiOi9bXlwvPjxcc10rLyxyOjB9LGVdfV19fSk7aGxq
+cy5yZWdpc3Rlckxhbmd1YWdlKCJtYXJrZG93biIsZnVuY3Rpb24oZSl7cmV0dXJue2FsaWFzZXM6WyJt
+ZCIsIm1rZG93biIsIm1rZCJdLGM6W3tjTjoic2VjdGlvbiIsdjpbe2I6Il4jezEsNn0iLGU6IiQifSx7
+YjoiXi4rP1xcbls9LV17Mix9JCJ9XX0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxs
+ZXQiLGI6Il5cXHMqKFsqKy1dfChcXGQrXFwuKSlcXHMrIn0se2NOOiJzdHJvbmciLGI6IlsqX117Mn0u
+Kz9bKl9dezJ9In0se2NOOiJlbXBoYXNpcyIsdjpbe2I6IlxcKi4rP1xcKiJ9LHtiOiJfLis/XyIscjow
+fV19LHtjTjoicXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsdjpbe2I6Il5gYGB3KnMq
+JCIsZToiXmBgYHMqJCJ9LHtiOiJgLis/YCJ9LHtiOiJeKCB7NH18XHQpIixlOiIkIixyOjB9XX0se2I6
+Il5bLVxcKl17Myx9IixlOiIkIn0se2I6IlxcWy4rP1xcXVtcXChcXFtdLio/W1xcKVxcXV0iLHJCOiEw
+LGM6W3tjTjoic3RyaW5nIixiOiJcXFsiLGU6IlxcXSIsZUI6ITAsckU6ITAscjowfSx7Y046Imxpbmsi
+LGI6IlxcXVxcKCIsZToiXFwpIixlQjohMCxlRTohMH0se2NOOiJzeW1ib2wiLGI6IlxcXVxcWyIsZToi
+XFxdIixlQjohMCxlRTohMH1dLHI6MTB9LHtiOi9eXFtbXlxuXStcXTovLHJCOiEwLGM6W3tjTjoic3lt
+Ym9sIixiOi9cWy8sZTovXF0vLGVCOiEwLGVFOiEwfSx7Y046ImxpbmsiLGI6LzpccyovLGU6LyQvLGVC
+OiEwfV19XX19KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoImRhcnQiLGZ1bmN0aW9uKGUpe3ZhciB0PXtj
+Tjoic3Vic3QiLHY6W3tiOiJcXCRbQS1aYS16MC05X10rIn1dfSxyPXtjTjoic3Vic3QiLHY6W3tiOiJc
+XCR7IixlOiJ9In1dLGs6InRydWUgZmFsc2UgbnVsbCB0aGlzIGlzIG5ldyBzdXBlciJ9LG49e2NOOiJz
+dHJpbmciLHY6W3tiOiJyJycnIixlOiInJycifSx7YjonciIiIicsZTonIiIiJ30se2I6InInIixlOiIn
+IixpOiJcXG4ifSx7YjonciInLGU6JyInLGk6IlxcbiJ9LHtiOiInJyciLGU6IicnJyIsYzpbZS5CRSx0
+LHJdfSx7YjonIiIiJyxlOiciIiInLGM6W2UuQkUsdCxyXX0se2I6IiciLGU6IiciLGk6IlxcbiIsYzpb
+ZS5CRSx0LHJdfSx7YjonIicsZTonIicsaToiXFxuIixjOltlLkJFLHQscl19XX07ci5jPVtlLkNOTSxu
+XTtyZXR1cm57azp7a2V5d29yZDoiYXNzZXJ0IGFzeW5jIGF3YWl0IGJyZWFrIGNhc2UgY2F0Y2ggY2xh
+c3MgY29uc3QgY29udGludWUgZGVmYXVsdCBkbyBlbHNlIGVudW0gZXh0ZW5kcyBmYWxzZSBmaW5hbCBm
+aW5hbGx5IGZvciBpZiBpbiBpcyBuZXcgbnVsbCByZXRocm93IHJldHVybiBzdXBlciBzd2l0Y2ggc3lu
+YyB0aGlzIHRocm93IHRydWUgdHJ5IHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQgYWJzdHJhY3QgYXMg
+ZHluYW1pYyBleHBvcnQgZXh0ZXJuYWwgZmFjdG9yeSBnZXQgaW1wbGVtZW50cyBpbXBvcnQgbGlicmFy
+eSBvcGVyYXRvciBwYXJ0IHNldCBzdGF0aWMgdHlwZWRlZiIsYnVpbHRfaW46InByaW50IENvbXBhcmFi
+bGUgRGF0ZVRpbWUgRHVyYXRpb24gRnVuY3Rpb24gSXRlcmFibGUgSXRlcmF0b3IgTGlzdCBNYXAgTWF0
+Y2ggTnVsbCBPYmplY3QgUGF0dGVybiBSZWdFeHAgU2V0IFN0b3B3YXRjaCBTdHJpbmcgU3RyaW5nQnVm
+ZmVyIFN0cmluZ1NpbmsgU3ltYm9sIFR5cGUgVXJpIGJvb2wgZG91YmxlIGludCBudW0gZG9jdW1lbnQg
+d2luZG93IHF1ZXJ5U2VsZWN0b3IgcXVlcnlTZWxlY3RvckFsbCBFbGVtZW50IEVsZW1lbnRMaXN0In0s
+YzpbbixlLkMoIi9cXCpcXCoiLCJcXCovIix7c0w6Im1hcmtkb3duIn0pLGUuQygiLy8vIiwiJCIse3NM
+OiJtYXJrZG93biJ9KSxlLkNMQ00sZS5DQkNNLHtjTjoiY2xhc3MiLGJLOiJjbGFzcyBpbnRlcmZhY2Ui
+LGU6InsiLGVFOiEwLGM6W3tiSzoiZXh0ZW5kcyBpbXBsZW1lbnRzIn0sZS5VVE1dfSxlLkNOTSx7Y046
+Im1ldGEiLGI6IkBbQS1aYS16XSsifSx7YjoiPT4ifV19fSk7Cg==
+''';
+
+String _index_html;
+// index_html md5 is 'b66394e479a3d5a43b260b7278cc74be'
+String _index_html_base64 = '''
+PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
+cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
+cnRQYWdlU2NyaXB0IH19PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0
+dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1PcGVuK1NhbnM6NDAwLDYwMCZkaXNw
+bGF5PXN3YXAiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJ7eyBoaWdobGlnaHRTdHls
+ZVBhdGggfX0iPgogICAgPHN0eWxlPnt7IGRhcnRQYWdlU3R5bGUgfX08L3N0eWxlPgo8L2hlYWQ+Cjxi
+b2R5IGNsYXNzPSJ7eyBtaWdyYXRpb25BcHBsaWVkU3R5bGUgfX0ge3sgbmVlZHNSZXJ1blN0eWxlIH19
+Ij4KPGRpdiBjbGFzcz0icmVydW5uaW5nLXBhbmUiPgogIDxoMT5SZXJ1bm5pbmcuLi48L2gxPgo8L2Rp
+dj4KPGRpdiBjbGFzcz0icG9wdXAtcGFuZSI+CiAgPGRpdiBjbGFzcz0iY2xvc2UgYnV0dG9uIj5YPC9k
+aXY+CiAgPGgyPjwvaDI+PCEtLSBoZWFkZXIgcGxhY2Vob2xkZXIgZWxlbWVudCAtLT4KICA8cD48L3A+
+PCEtLSBzdWJoZWFkZXIgcGxhY2Vob2xkZXIgZWxlbWVudCAtLT4KICA8cHJlPjwvcHJlPjwhLS0gcHJl
+Zm9ybWF0ZWQgY29udGVudCBwbGFjZWhvbGRlciBlbGVtZW50IC0tPgogIDxhIGNsYXNzPSJidXR0b24g
+Ym90dG9tIiB0YXJnZXQ9Il9ibGFuayI+RmlsZSBvbiBHaXRIdWI8L2E+PCEtLSBwb3N0IHRvIGdpdGh1
+YiBwbGFjZWhvbGRlciBlbGVtZW50IC0tPgo8L2Rpdj4KPHAgY2xhc3M9InJvb3QiPnt7IHJvb3QgfX08
+L3A+CjxoZWFkZXIgY2xhc3M9ImVsZXZhdGlvbi16NCI+CiAgICA8aDEgY2xhc3M9ImJlZm9yZS1hcHBs
+eSI+UHJvcG9zZWQgbnVsbCBzYWZldHkgY2hhbmdlczwvaDE+CiAgICA8aDEgY2xhc3M9ImFmdGVyLWFw
+cGx5Ij4mIzEwMDAzOyBOdWxsIHNhZmV0eSBtaWdyYXRpb24gYXBwbGllZDwvaDE+CiAgICA8aDIgaWQ9
+InVuaXQtbmFtZSI+Jm5ic3A7PC9oMj4KICAgIDxidXR0b24gY2xhc3M9ImFwcGx5LW1pZ3JhdGlvbiI+
+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxidXR0b24gY2xhc3M9ImFwcGx5LW1p
+Z3JhdGlvbiIgZGlzYWJsZWQ+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxidXR0
+b24gY2xhc3M9InJlcnVuLW1pZ3JhdGlvbiBiZWZvcmUtYXBwbHkiPgogICAgICA8c3BhbiBjbGFzcz0i
+b3B0aW9uYWwiPiYjODYzNTsgUmVydW4gRnJvbSBTb3VyY2VzPC9zcGFuPgogICAgICA8c3BhbiBjbGFz
+cz0icmVxdWlyZWQiPgogICAgICAgIDxzcGFuIGNsYXNzPSJpY29uIiAKICAgICAgICAgIHRpdGxlPSJE
+aXNrIGNvbnRlbnRzIGhhdmUgY2hhbmdlZC4gUmVydW4gdG8gZ2V0IGFuIHVwLXRvLWRhdGUgbWlncmF0
+aW9uLiI+ITwvc3Bhbj4KICAgICAgICBSZXJ1biBXaXRoIENoYW5nZXMKICAgICAgPC9zcGFuPgogICAg
+PC9idXR0b24+CjwvaGVhZGVyPgo8ZGl2IGNsYXNzPSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2
+IGNsYXNzPSJuYXYtcGFuZWwiPgogICAgICAgIDxkaXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAg
+ICAgIDxkaXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAg
+ICAgPGRpdiBjbGFzcz0ibmF2LXRyZWUiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5l
+ciAtLT4KICAgIDwvZGl2PjwhLS0gL25hdiAtLT4KICAgIDxkaXYgY2xhc3M9ImNvbnRlbnQiPgogICAg
+ICAgIDxkaXYgY2xhc3M9InJlZ2lvbnMiPgogICAgICAgICAgICA8IS0tIFRoZSByZWdpb25zIG92ZXJs
+YXkgY29kZSBjb3B5IG9mIHRoZSBjb250ZW50IHRvIHByb3ZpZGUgLS0+CiAgICAgICAgICAgIDwhLS0g
+dG9vbHRpcHMgZm9yIG1vZGlmaWVkIHJlZ2lvbnMuIC0tPgogICAgICAgIDwvZGl2PjwhLS0gL3JlZ2lv
+bnMgLS0+CiAgICAgICAgPGRpdiBjbGFzcz0iY29kZSI+CiAgICAgICAgICAgIDwhLS0gQ29tcGlsYXRp
+b24gdW5pdCBjb250ZW50IGlzIHdyaXR0ZW4gaGVyZS4gLS0+CiAgICAgICAgICAgIDxwIGNsYXNzPSJ3
+ZWxjb21lIj4KICAgICAgICAgICAgICAgIFNlbGVjdCBhIHNvdXJjZSBmaWxlIG9uIHRoZSBsZWZ0IHRv
+IHByZXZpZXcgdGhlIHByb3Bvc2VkIGVkaXRzLgogICAgICAgICAgICA8L3A+CiAgICAgICAgPC9kaXY+
+CiAgICA8L2Rpdj48IS0tIC9jb250ZW50IC0tPgogICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAg
+ICAgICAgPGRpdiBjbGFzcz0iZWRpdC1saXN0Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwt
+aGVhZGluZyI+UHJvcG9zZWQgRWRpdHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwt
+Y29udGVudCI+PC9kaXY+CiAgICAgICAgPC9kaXY+PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxk
+aXYgY2xhc3M9ImVkaXQtcGFuZWwiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5n
+Ij5FZGl0IERldGFpbHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+
+CiAgICAgICAgICAgICAgICA8cCBjbGFzcz0icGxhY2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEg
+cHJvcG9zZWQgZWRpdC48L3A+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+
+CiAgICAgICAgPC9kaXY+PCEtLSAvZWRpdC1wYW5lbCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFu
+ZWwgLS0+CjwvZGl2PjwhLS0gL3BhbmVscyAtLT4KPGZvb3Rlcj4KICAgIDxhIHRhcmdldD0iX2JsYW5r
+IgogICAgICBocmVmPSJodHRwczovL2dvby5nbGUvZGFydC1udWxsLXNhZmV0eS1taWdyYXRpb24tdG9v
+bCI+TnVsbCBzYWZldHkKICAgICAgICBtaWdyYXRpb24gaGVscDwvYT4KICAgIDxzcGFuIGNsYXNzPSJ3
+aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBvbiA8c3BhbiBpZD0ic2RrLXZlcnNpb24iPnt7IHNk
+a1ZlcnNpb24gfX08L3NwYW4+PC9kaXY+CiAgICA8YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+
+UmVwb3J0IGEgUHJvYmxlbTwvYnV0dG9uPgo8L2Zvb3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
+''';
+
+String _migration_css;
+// migration_css md5 is '3ac37808bdb8d07efd1c9ce21b67fccc'
+String _migration_css_base64 = '''
+LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
+dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
+ZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgKi8KLyogQlNELXN0eWxlIGxpY2Vu
+c2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4gICAgICAgICAgICAgICAgICAg
+Ki8KCmJvZHkgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgY29sb3I6ICNjY2M7CiAgZm9u
+dC1mYW1pbHk6ICJSb2JvdG8iLCBzYW5zLXNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKICBkaXNwbGF5
+OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRv
+cDogMDsKICByaWdodDogMDsKICBib3R0b206IDA7CiAgbGVmdDogMDsKICBtYXJnaW46IDA7CiAgcGFk
+ZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucHJvcG9zZWQgLmFmdGVyLWFwcGx5IHsKICBk
+aXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYmVmb3JlLWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9
+CgouYXBwbGllZCAuYXBwbHktbWlncmF0aW9uOm5vdChbZGlzYWJsZWRdKSwgLm5lZWRzLXJlcnVuIC5h
+cHBseS1taWdyYXRpb246bm90KFtkaXNhYmxlZF0pIHsKICBkaXNwbGF5OiBub25lOwp9CgoucHJvcG9z
+ZWQ6bm90KC5uZWVkcy1yZXJ1bikgLmFwcGx5LW1pZ3JhdGlvbltkaXNhYmxlZF0gewogIGRpc3BsYXk6
+IG5vbmU7Cn0KCmhlYWRlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzFjMjgzNDsKICBoZWlnaHQ6IDQ4
+cHg7CiAgcGFkZGluZy1sZWZ0OiAyNHB4OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgei1pbmRleDog
+NDsKfQoKaGVhZGVyIGgxLApoZWFkZXIgaDIgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250
+LWZhbWlseTogIkdvb2dsZSBTYW5zIiwiUm9ib3RvIixzYW5zLXNlcmlmOwogIGZvbnQtd2VpZ2h0OiA0
+MDA7CiAgbWFyZ2luLXJpZ2h0OiAyNHB4Owp9CgpoMSB7CiAgZm9udC1zaXplOiAxLjVlbTsKfQoKaGVh
+ZGVyIGgyIHsKICBmb250LXNpemU6IDEuMmVtOwp9CgpoZWFkZXIgLmFwcGx5LW1pZ3JhdGlvbiwgLnJl
+cnVuLW1pZ3JhdGlvbiB7CiAgcmlnaHQ6IDBweDsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luOiAxMHB4
+Owp9Cgpmb290ZXIgLnJlcG9ydC1wcm9ibGVtIHsKICByaWdodDogMHB4OwogIG1hcmdpbjogNHB4IDhw
+eDsKfQoKLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5uZWVk
+cy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCB7CiAgZGlzcGxheTogaW5pdGlhbDsKfQoK
+Lm5lZWRzLXJlcnVuIC5yZXJ1bi1taWdyYXRpb24gLm9wdGlvbmFsIHsKICBkaXNwbGF5Om5vbmU7Cn0K
+Ci8qIFJlZCB0cmlhbmdsZSAqLwoucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCAuaWNvbjo6YmVmb3Jl
+IHsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtOHB4LCAtMTFweCk7CiAgY29udGVudDogJ1wyNUIzJzsK
+ICBmb250LXNpemU6IDI1cHg7CiAgcG9zaXRpb246IGZpeGVkOwogIGNvbG9yOiAjZTgyYzJjOwogIHRl
+eHQtc2hhZG93OiAwcHggMHB4IDVweCB3aGl0ZTsKICB6LWluZGV4OiAtMzsKfQoKLyogUmVkIHRyaWFu
+Z2xlIGZpbGwgKi8KLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgLmljb246OmFmdGVyIHsKICB0cmFu
+c2Zvcm06IHRyYW5zbGF0ZSgtOXB4LCAtMTBweCk7CiAgY29udGVudDogJ1wyNUI0JzsKICBmb250LXNp
+emU6IDI1cHg7CiAgcG9zaXRpb246IGZpeGVkOwogIGNvbG9yOiAjYjNlY2ZmOwogIHotaW5kZXg6IC0x
+Owp9CgovKiBSZWQgdHJpYW5nbGUgZXhjbGFtYXRpb24gKi8KLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWly
+ZWQgLmljb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBtYXJnaW4tcmlnaHQ6IDhweDsKICB0
+cmFuc2Zvcm06IHRyYW5zbGF0ZSgwcHgsIDJweCk7CiAgbWFyZ2luLWxlZnQ6IDJweDsKICBjb2xvcjog
+IzJiMmIyYjsKfQoKZm9vdGVyIHsKICBjb2xvcjogI2NjYzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjcz
+MjNhOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IHJvdzsKICBhbGlnbi1pdGVtczog
+Y2VudGVyOwogIHBhZGRpbmc6IDhweCAwIDhweCAyNHB4Owp9Cgpmb290ZXIgLndpZGUgewogIGZsZXg6
+IDE7Cn0KCi5ob3Jpem9udGFsIHsKICBkaXNwbGF5OiBmbGV4Owp9CgoucGFuZWxzIHsKICBiYWNrZ3Jv
+dW5kLWNvbG9yOiAjMTIxYTI1OwogIGZsZXg6IDE7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLnBhbmVs
+LWhlYWRpbmcgewogIGNvbG9yOiBncmF5OwogIG1hcmdpbjogOHB4Owp9CgoubmF2LWxpbmssCi5yZWdp
+b24gewogIGN1cnNvcjogcG9pbnRlcjsKfQoKLm5hdi1wYW5lbCB7CiAgYmFja2dyb3VuZC1jb2xvcjog
+IzI4MmIyZTsKICBmbGV4OiAxIDIwMHB4OwogIG1hcmdpbjogMDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9
+CgoubmF2LWlubmVyIHsKICBwYWRkaW5nOiAwIDAgN3B4IDdweDsKfQoKLmZpeGVkIHsKICBwb3NpdGlv
+bjogZml4ZWQ7CiAgdG9wOiAwOwp9Cgoucm9vdCB7CiAgbWFyZ2luOiAwOwogIGRpc3BsYXk6IG5vbmU7
+Cn0KCi5uYXYtdHJlZSA+IHVsIHsKICBwYWRkaW5nLWxlZnQ6IDZweDsKfQoKLm5hdi1pbm5lciB1bCB7
+CiAgcGFkZGluZy1sZWZ0OiAxMnB4OwogIG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlz
+dC1zdHlsZS10eXBlOiBub25lOwp9CgoubmF2LWlubmVyIGxpOm5vdCguZGlyKSB7CiAgbWFyZ2luLWxl
+ZnQ6IDIwcHg7CiAgbWFyZ2luLWJvdHRvbTogM3B4Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cg
+ewogIGN1cnNvcjogcG9pbnRlcjsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1zaXplOiAx
+MHB4OwogIG1hcmdpbi1yaWdodDogNHB4OwogIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjVzIGVhc2Ut
+b3V0Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cuY29sbGFwc2VkIHsKICB0cmFuc2Zvcm06IHJv
+dGF0ZSgtOTBkZWcpOwp9CgoubmF2LWlubmVyIHVsIHsKICBtYXgtaGVpZ2h0OiAyMDAwcHg7CiAgdHJh
+bnNpdGlvbjogbWF4LWhlaWdodCAwLjVzIGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIHVsLmNvbGxhcHNl
+ZCB7CiAgbWF4LWhlaWdodDogMCAhaW1wb3J0YW50OwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5uYXYt
+aW5uZXIgLnNlbGVjdGVkLWZpbGUgewogIGNvbG9yOiB3aGl0ZTsKICBjdXJzb3I6IGluaGVyaXQ7CiAg
+Zm9udC13ZWlnaHQ6IDYwMDsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCi5lZGl0LWNvdW50IHsK
+ICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzdhZWRjOwogIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgY29sb3I6
+ICMwMDAwMDA7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtc2l6ZTogMTFweDsKICBmb250
+LXdlaWdodDogNjAwOwogIG1hcmdpbi1sZWZ0OiA1cHg7CiAgbWluLXdpZHRoOiAyNXB4OwogIHBhZGRp
+bmc6IDRweCAwIDJweCAwOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBsaW5lLWhlaWdodDogMWVtOwp9
+CgouY29udGVudCB7CiAgZmxleDogNCAzMDBweDsKICBiYWNrZ3JvdW5kOiAjMjgyYjJlOwogIGZvbnQt
+ZmFtaWx5OiBtb25vc3BhY2U7CiAgbWFyZ2luOiAwIDZweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAg
+d2hpdGUtc3BhY2U6IHByZTsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgouY29kZSB7CiAgcGFkZGluZzog
+MC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwogIG1hcmdpbi1s
+ZWZ0OiA1NnB4Owp9CgouaGxqcyB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBkaXNwbGF5
+OiBibG9jazsKICBvdmVyZmxvdy14OiBhdXRvOwogIHBhZGRpbmc6IDAuNWVtOwp9CgouY29kZSAud2Vs
+Y29tZSB7CiAgZm9udC1mYW1pbHk6ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBm
+b250LXNpemU6IDE4cHg7CiAgbWFyZ2luLXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29k
+ZSAubmF2LWxpbmsgewogIGNvbG9yOiBpbmhlcml0OwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25l
+Owp9CgouY29kZSAubmF2LWxpbms6dmlzaXRlZCB7CiAgY29sb3I6IGluaGVyaXQ7CiAgdGV4dC1kZWNv
+cmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5jb2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4dC1kZWNvcmF0
+aW9uLWxpbmU6IHVuZGVybGluZTsKICBmb250LXdlaWdodDogNjAwOwp9CgoucmVnaW9ucyB7CiAgcGFk
+ZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwp9Cgou
+cmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVyLXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBpbmhlcml0Owp9
+CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVyOiBub25lOwogIC8qIFRoZSBjb250ZW50IG9mIHRoZSByZWdp
+b25zIGlzIG5vdCB2aXNpYmxlOyB0aGUgdXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQogICAqIGhpZ2hs
+aWdodGVkIGNvcHkgb2YgdGhlIGNvbnRlbnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwg
+MCk7CiAgcGFkZGluZzogMDsKICB3aGl0ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0ZDplbXB0eTph
+ZnRlciB7CiAgY29udGVudDogIlwwMGEwIjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkOmxhc3Qt
+Y2hpbGQgewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRlOwp9CgoucmVn
+aW9ucyB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICMyODJiMmUgMnB4OwogIGNvbG9y
+OiAjOTk5OTk5OwogIHBhZGRpbmctcmlnaHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdodDsKICB2aXNp
+YmlsaXR5OiB2aXNpYmxlOwogIHdpZHRoOiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKfQoK
+LnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkLmxpbmUtbm8gewogIGJvcmRlci1yaWdodDogc29saWQgI2Nj
+YyAycHg7Cn0KCi5yZWdpb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwb3NpdGlvbjogcmVs
+YXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5yZWdpb24uYWRk
+ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjY2NmZmNjOwogIGNvbG9yOiAjMDAzMzAwOwp9
+CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmY2NjY2OwogIGNv
+bG9yOiAjMDAxMTAwOwp9CgoucmVnaW9uLmluZm9ybWF0aXZlLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1j
+b2xvcjogIzg4ODg4ODsKICBjb2xvcjogIzAwMDAwMDsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3VuZC1j
+b2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICBm
+b250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5lbCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46
+IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVt
+bjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMyODJiMmU7
+CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRkaW5n
+OiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1hcmdp
+bi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dyYXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0K
+Ci5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9Cgou
+aW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewogIGNv
+bG9yOiAjMzNjY2ZmOwp9CgouaW5mby1wYW5lbCAuZWRpdC1saXN0IHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiAjMjgyYjJlOwogIG92ZXJmbG93OiBhdXRvOwp9CgouZWRpdC1wYW5lbCB7CiAgbWFyZ2luLXRvcDog
+NnB4OwogIGZsZXg6IDEgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgewogIGZsZXg6IDIgMTAwcHg7Cn0KCi5l
+ZGl0LWxpc3QgLmVkaXQgewogIG1hcmdpbjogM3B4IDA7Cn0KCi5lZGl0LWxpc3QgLmVkaXQtbGluayB7
+CiAgY3Vyc29yOiBwb2ludGVyOwp9CgoucG9wdXAtcGFuZSB7CiAgZGlzcGxheTogbm9uZTsKICBwb3Np
+dGlvbjogZml4ZWQ7CiAgdG9wOiAxNTBweDsKICBsZWZ0OiAxNTBweDsKICByaWdodDogMTUwcHg7CiAg
+Ym90dG9tOiAxNTBweDsKICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsKICBib3JkZXItdG9wOiAycHgg
+c29saWQgYmxhY2s7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJveC1zaGFkb3c6IDBweCAwcHggMjBw
+eCAycHggI2I0YmZjYjIyOwogIHotaW5kZXg6IDE7CiAgYmFja2dyb3VuZDogIzJiMzAzNjsKICBwYWRk
+aW5nOiAyMHB4Owp9CgoucG9wdXAtcGFuZSAuY2xvc2UgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICBy
+aWdodDogMTBweDsKICB0b3A6IDEwcHg7CiAgY3Vyc29yOiBwb2ludGVyOwogIHRleHQtc2hhZG93OiAx
+cHggMXB4IDJweCAjODg4OwogIGJveC1zaGFkb3c6IDFweCAxcHggMnB4ICMxMTE7Cn0KCi5wb3B1cC1w
+YW5lIGgyIHsKICBwYWRkaW5nOiAyMXB4OwogIGhlaWdodDogMTAlOwogIG1hcmdpbjogMHB4OwogIGJv
+eC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5wb3B1cC1wYW5lIHAgewogIGhlaWdodDogMTAlOwogIGJv
+eC1zaXppbmc6IGJvcmRlci1ib3g7CiAgcGFkZGluZzogMHB4IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIHBy
+ZSB7CiAgYmFja2dyb3VuZDogIzI4MmIyZTsKICBwYWRkaW5nOiAyMHB4OwogIGJvdHRvbTogMHB4Owog
+IG92ZXJmbG93OiBhdXRvIHNjcm9sbDsKICBoZWlnaHQ6IDY1JTsKICBtYXJnaW46IDBweDsKICBib3gt
+c2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9wdXAtcGFuZSAuYnV0dG9uLmJvdHRvbSB7CiAgbWFyZ2lu
+OiAyMHB4IDBweDsKICBkaXNwbGF5OiBibG9jazsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCi5yZXJ1
+bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9uZTsKfQoKYm9keS5yZXJ1bm5pbmcgLnJlcnVubmluZy1w
+YW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwcHg7CiAgYm90
+dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJpZ2h0OiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzAw
+MDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFjayAqLwogIHotaW5kZXg6IDQwMDsKfQoKLnJlcnVubmlu
+Zy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9wOiA1MCU7CiAgbGVmdDogNTAlOwog
+IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpOwp9CgpwLnRyYWNlIC50eXBlLWRlc2NyaXB0
+aW9uIHsKICAvKiBGcm9tIEhMSlMncyAuaGxqcy1rZXl3b3JkLCAuaGxqcy1zZWxlY3Rvci10YWcsIC5o
+bGpzLWRlbGV0aW9uICovCiAgY29sb3I6ICNjYzc4MzI7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsK
+fQoKdWwudHJhY2UgewogIGZvbnQtc2l6ZTogMTNweDsKICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7CiAg
+cGFkZGluZy1sZWZ0OiAwcHg7Cn0KCnVsLnRyYWNlIGxpIHsKICBjb2xvcjogd2hpdGU7CiAgbWFyZ2lu
+LWxlZnQ6IDE0cHg7CiAgdGV4dC1pbmRlbnQ6IC0xNHB4Owp9Cgp1bC50cmFjZSBsaSAuZnVuY3Rpb24g
+ewogIC8qIEZyb20gSExKUydzIC5obGpzLXNlY3Rpb24sIC5obGpzLXRpdGxlLCAuaGxqcy10eXBlICov
+CiAgY29sb3I6ICNmZmM2NmQ7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250LXdlaWdodDog
+NjAwOwp9CgouZWxldmF0aW9uLXo0IHsKICBib3gtc2hhZG93OiAwcHggMnB4IDRweCAtMXB4IHJnYmEo
+MCwgMCwgMCwgMC4yKSwKICAgICAgMHB4IDRweCA1cHggMHB4IHJnYmEoMCwgMCwgMCwgMC4xNCksCiAg
+ICAgIDBweCAxcHggMTBweCAwcHggcmdiYSgwLCAwLCAwLCAuMTIpOwp9CgphIHsKICBjb2xvcjogI2Nj
+YzsKICBmaWxsOiAjY2NjOwogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKfQoKYTpob3ZlciB7CiAgY29s
+b3I6ICNmZmY7CiAgZmlsbDogI2ZmZjsKfQoKLmFkZC1oaW50LWxpbmsgewogIGRpc3BsYXk6IGlubGlu
+ZS1ibG9jazsKICBtYXJnaW46IDNweDsKfQoKYnV0dG9uLCBhLmJ1dHRvbiB7CiAgYmFja2dyb3VuZC1j
+b2xvcjogIzMzY2NmZjsKICBib3JkZXI6IDJweCBzb2xpZCAjMzdhZWRjOwogIGJvcmRlci1yYWRpdXM6
+IDNweDsKICBwYWRkaW5nOiA2cHggMTBweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogIzI4
+MjgyODsKfQoKYnV0dG9uOmhvdmVyLCAuYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
+ODBkZmZmOwogIGJvcmRlcjogMnB4IHNvbGlkICM1MmI4ZTA7CiAgY3Vyc29yOiBwb2ludGVyOwp9Cgpi
+dXR0b25bZGlzYWJsZWRdIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjN2FhOGI4OwogIGNvbG9yOiAjNTA3
+MTc3OwogIGJvcmRlcjogMnB4IHNvbGlkICM1MDcxNzc7CiAgY3Vyc29yOiBub3QtYWxsb3dlZDsKfQoK
+LnBsYWNlaG9sZGVyIHsKICBjb2xvcjogIzc3NzsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWFyZ2lu
+LXRvcDogM2VtICFpbXBvcnRhbnQ7Cn0KCi8qKgogKiBITEpTIE92ZXJyaWRlcwogKi8KLmhsanMgewog
+IC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBoaWdobGlnaHRzIHRvIHNob3cuCiAgICov
+CiAgYmFja2dyb3VuZDogbm9uZTsKfQo=
+''';
+
+String _migration_js;
+// migration_dart md5 is '1304024d7fb410d20ab30af7a6a25142'
+String _migration_js_base64 = '''
+KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
+YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
+cl19fXZhciB6PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oKXt9CnQucHJvdG90eXBlPXtwOnt9fQp2
+YXIgcz1uZXcgdCgpCmlmKCEocy5fX3Byb3RvX18mJnMuX19wcm90b19fLnA9PT10LnByb3RvdHlwZS5w
+KSlyZXR1cm4gZmFsc2UKdHJ5e2lmKHR5cGVvZiBuYXZpZ2F0b3IhPSJ1bmRlZmluZWQiJiZ0eXBlb2Yg
+bmF2aWdhdG9yLnVzZXJBZ2VudD09InN0cmluZyImJm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigi
+Q2hyb21lLyIpPj0wKXJldHVybiB0cnVlCmlmKHR5cGVvZiB2ZXJzaW9uPT0iZnVuY3Rpb24iJiZ2ZXJz
+aW9uLmxlbmd0aD09MCl7dmFyIHI9dmVyc2lvbigpCmlmKC9eXGQrXC5cZCtcLlxkK1wuXGQrJC8udGVz
+dChyKSlyZXR1cm4gdHJ1ZX19Y2F0Y2gocSl7fXJldHVybiBmYWxzZX0oKQpmdW5jdGlvbiBzZXRGdW5j
+dGlvbk5hbWVzSWZOZWNlc3NhcnkoYSl7ZnVuY3Rpb24gdCgpe307aWYodHlwZW9mIHQubmFtZT09InN0
+cmluZyIpcmV0dXJuCmZvcih2YXIgdD0wO3Q8YS5sZW5ndGg7dCsrKXt2YXIgcz1hW3RdCnZhciByPU9i
+amVjdC5rZXlzKHMpCmZvcih2YXIgcT0wO3E8ci5sZW5ndGg7cSsrKXt2YXIgcD1yW3FdCnZhciBvPXNb
+cF0KaWYodHlwZW9mIG89PSdmdW5jdGlvbicpby5uYW1lPXB9fX1mdW5jdGlvbiBpbmhlcml0KGEsYil7
+YS5wcm90b3R5cGUuY29uc3RydWN0b3I9YQphLnByb3RvdHlwZVsiJGkiK2EubmFtZV09YQppZihiIT1u
+dWxsKXtpZih6KXthLnByb3RvdHlwZS5fX3Byb3RvX189Yi5wcm90b3R5cGUKcmV0dXJufXZhciB0PU9i
+amVjdC5jcmVhdGUoYi5wcm90b3R5cGUpCmNvcHlQcm9wZXJ0aWVzKGEucHJvdG90eXBlLHQpCmEucHJv
+dG90eXBlPXR9fWZ1bmN0aW9uIGluaGVyaXRNYW55KGEsYil7Zm9yKHZhciB0PTA7dDxiLmxlbmd0aDt0
+KyspaW5oZXJpdChiW3RdLGEpfWZ1bmN0aW9uIG1peGluKGEsYil7Y29weVByb3BlcnRpZXMoYi5wcm90
+b3R5cGUsYS5wcm90b3R5cGUpCmEucHJvdG90eXBlLmNvbnN0cnVjdG9yPWF9ZnVuY3Rpb24gbGF6eShh
+LGIsYyxkKXt2YXIgdD1hCmFbYl09dAphW2NdPWZ1bmN0aW9uKCl7YVtjXT1mdW5jdGlvbigpe0guYWco
+Yil9CnZhciBzCnZhciByPWQKdHJ5e2lmKGFbYl09PT10KXtzPWFbYl09cgpzPWFbYl09ZCgpfWVsc2Ug
+cz1hW2JdfWZpbmFsbHl7aWYocz09PXIpYVtiXT1udWxsCmFbY109ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
+c1tiXX19cmV0dXJuIHN9fWZ1bmN0aW9uIG1ha2VDb25zdExpc3QoYSl7YS5pbW11dGFibGUkbGlzdD1B
+cnJheQphLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX1mdW5jdGlvbiBjb252ZXJ0VG9GYXN0T2Jq
+ZWN0KGEpe2Z1bmN0aW9uIHQoKXt9dC5wcm90b3R5cGU9YQpuZXcgdCgpCnJldHVybiBhfWZ1bmN0aW9u
+IGNvbnZlcnRBbGxUb0Zhc3RPYmplY3QoYSl7Zm9yKHZhciB0PTA7dDxhLmxlbmd0aDsrK3QpY29udmVy
+dFRvRmFzdE9iamVjdChhW3RdKX12YXIgeT0wCmZ1bmN0aW9uIHRlYXJPZmZHZXR0ZXIoYSxiLGMsZCxl
+KXtyZXR1cm4gZT9uZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
+ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
+IihyZWNlaXZlcikgeyIrImlmIChjID09PSBudWxsKSBjID0gIisiSC5LcSIrIigiKyJ0aGlzLCBmdW5j
+cywgYXBwbHlUcmFtcG9saW5lSW5kZXgsIHJlZmxlY3Rpb25JbmZvLCBmYWxzZSwgdHJ1ZSwgbmFtZSk7
+IisicmV0dXJuIG5ldyBjKHRoaXMsIGZ1bmNzWzBdLCByZWNlaXZlciwgbmFtZSk7IisifSIpKGEsYixj
+LGQsSCxudWxsKTpuZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
+ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
+IigpIHsiKyJpZiAoYyA9PT0gbnVsbCkgYyA9ICIrIkguS3EiKyIoIisidGhpcywgZnVuY3MsIGFwcGx5
+VHJhbXBvbGluZUluZGV4LCByZWZsZWN0aW9uSW5mbywgZmFsc2UsIGZhbHNlLCBuYW1lKTsiKyJyZXR1
+cm4gbmV3IGModGhpcywgZnVuY3NbMF0sIG51bGwsIG5hbWUpOyIrIn0iKShhLGIsYyxkLEgsbnVsbCl9
+ZnVuY3Rpb24gdGVhck9mZihhLGIsYyxkLGUsZil7dmFyIHQ9bnVsbApyZXR1cm4gZD9mdW5jdGlvbigp
+e2lmKHQ9PT1udWxsKXQ9SC5LcSh0aGlzLGEsYixjLHRydWUsZmFsc2UsZSkucHJvdG90eXBlCnJldHVy
+biB0fTp0ZWFyT2ZmR2V0dGVyKGEsYixjLGUsZil9dmFyIHg9MApmdW5jdGlvbiBpbnN0YWxsVGVhck9m
+ZihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdD1bXQpmb3IodmFyIHM9MDtzPGgubGVuZ3RoO3MrKyl7
+dmFyIHI9aFtzXQppZih0eXBlb2Ygcj09J3N0cmluZycpcj1hW3JdCnIuJGNhbGxOYW1lPWdbc10KdC5w
+dXNoKHIpfXZhciByPXRbMF0Kci4kUj1lCnIuJEQ9Zgp2YXIgcT1pCmlmKHR5cGVvZiBxPT0ibnVtYmVy
+IilxKz14CnZhciBwPWhbMF0Kci4kc3R1Yk5hbWU9cAp2YXIgbz10ZWFyT2ZmKHQsanx8MCxxLGMscCxk
+KQphW2JdPW8KaWYoYylyLiR0ZWFyT2ZmPW99ZnVuY3Rpb24gaW5zdGFsbFN0YXRpY1RlYXJPZmYoYSxi
+LGMsZCxlLGYsZyxoKXtyZXR1cm4gaW5zdGFsbFRlYXJPZmYoYSxiLHRydWUsZmFsc2UsYyxkLGUsZixn
+LGgpfWZ1bmN0aW9uIGluc3RhbGxJbnN0YW5jZVRlYXJPZmYoYSxiLGMsZCxlLGYsZyxoLGkpe3JldHVy
+biBpbnN0YWxsVGVhck9mZihhLGIsZmFsc2UsYyxkLGUsZixnLGgsaSl9ZnVuY3Rpb24gc2V0T3JVcGRh
+dGVJbnRlcmNlcHRvcnNCeVRhZyhhKXt2YXIgdD12LmludGVyY2VwdG9yc0J5VGFnCmlmKCF0KXt2Lmlu
+dGVyY2VwdG9yc0J5VGFnPWEKcmV0dXJufWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gc2V0T3JV
+cGRhdGVMZWFmVGFncyhhKXt2YXIgdD12LmxlYWZUYWdzCmlmKCF0KXt2LmxlYWZUYWdzPWEKcmV0dXJu
+fWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gdXBkYXRlVHlwZXMoYSl7dmFyIHQ9di50eXBlcwp2
+YXIgcz10Lmxlbmd0aAp0LnB1c2guYXBwbHkodCxhKQpyZXR1cm4gc31mdW5jdGlvbiB1cGRhdGVIb2xk
+ZXIoYSxiKXtjb3B5UHJvcGVydGllcyhiLGEpCnJldHVybiBhfXZhciBodW5rSGVscGVycz1mdW5jdGlv
+bigpe3ZhciB0PWZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIGZ1bmN0aW9uKGYsZyxoLGkpe3JldHVy
+biBpbnN0YWxsSW5zdGFuY2VUZWFyT2ZmKGYsZyxhLGIsYyxkLFtoXSxpLGUpfX0scz1mdW5jdGlvbihh
+LGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oZSxmLGcsaCl7cmV0dXJuIGluc3RhbGxTdGF0aWNUZWFyT2Zm
+KGUsZixhLGIsYyxbZ10saCxkKX19CnJldHVybntpbmhlcml0OmluaGVyaXQsaW5oZXJpdE1hbnk6aW5o
+ZXJpdE1hbnksbWl4aW46bWl4aW4saW5zdGFsbFN0YXRpY1RlYXJPZmY6aW5zdGFsbFN0YXRpY1RlYXJP
+ZmYsaW5zdGFsbEluc3RhbmNlVGVhck9mZjppbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLF9pbnN0YW5jZV8w
+dTp0KDAsMCxudWxsLFsiJDAiXSwwKSxfaW5zdGFuY2VfMXU6dCgwLDEsbnVsbCxbIiQxIl0sMCksX2lu
+c3RhbmNlXzJ1OnQoMCwyLG51bGwsWyIkMiJdLDApLF9pbnN0YW5jZV8waTp0KDEsMCxudWxsLFsiJDAi
+XSwwKSxfaW5zdGFuY2VfMWk6dCgxLDEsbnVsbCxbIiQxIl0sMCksX2luc3RhbmNlXzJpOnQoMSwyLG51
+bGwsWyIkMiJdLDApLF9zdGF0aWNfMDpzKDAsbnVsbCxbIiQwIl0sMCksX3N0YXRpY18xOnMoMSxudWxs
+LFsiJDEiXSwwKSxfc3RhdGljXzI6cygyLG51bGwsWyIkMiJdLDApLG1ha2VDb25zdExpc3Q6bWFrZUNv
+bnN0TGlzdCxsYXp5OmxhenksdXBkYXRlSG9sZGVyOnVwZGF0ZUhvbGRlcixjb252ZXJ0VG9GYXN0T2Jq
+ZWN0OmNvbnZlcnRUb0Zhc3RPYmplY3Qsc2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5OnNldEZ1bmN0
+aW9uTmFtZXNJZk5lY2Vzc2FyeSx1cGRhdGVUeXBlczp1cGRhdGVUeXBlcyxzZXRPclVwZGF0ZUludGVy
+Y2VwdG9yc0J5VGFnOnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcsc2V0T3JVcGRhdGVMZWFmVGFn
+czpzZXRPclVwZGF0ZUxlYWZUYWdzfX0oKQpmdW5jdGlvbiBpbml0aWFsaXplRGVmZXJyZWRIdW5rKGEp
+e3g9di50eXBlcy5sZW5ndGgKYShodW5rSGVscGVycyx2LHcsJCl9ZnVuY3Rpb24gZ2V0R2xvYmFsRnJv
+bU5hbWUoYSl7Zm9yKHZhciB0PTA7dDx3Lmxlbmd0aDt0Kyspe2lmKHdbdF09PUMpY29udGludWUKaWYo
+d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17ZW86ZnVuY3Rpb24gZW8oKXt9LApvbzpm
+dW5jdGlvbihhKXt2YXIgdCxzPWFeNDgKaWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8
+PTEwMilyZXR1cm4gdC04NwpyZXR1cm4tMX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3Rh
+cnQiKQppZihjIT1udWxsKXtQLmsxKGMsImVuZCIpCmlmKGI+YylILnZoKFAuVEUoYiwwLGMsInN0YXJ0
+IixudWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihh
+LGIsYyxkKXtpZih1Lmd3LmMoYSkpcmV0dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5D
+KCJ4eTwxLDI+IikpCnJldHVybiBuZXcgSC5pMShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygiaTE8MSwy
+PiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJObyBlbGVtZW50Iil9LApkVTpmdW5j
+dGlvbigpe3JldHVybiBuZXcgUC5saigiVG9vIG1hbnkgZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBQLmxqKCJUb28gZmV3IGVsZW1lbnRzIil9LApxajpmdW5jdGlvbiBxaihhKXt0aGlz
+LmE9YX0sCmJROmZ1bmN0aW9uIGJRKCl7fSwKYUw6ZnVuY3Rpb24gYUwoKXt9LApuSDpmdW5jdGlvbiBu
+SChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAphNzpmdW5jdGlv
+biBhNyhhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwK
+aTE6ZnVuY3Rpb24gaTEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp4eTpmdW5j
+dGlvbiB4eShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCk1IOmZ1bmN0aW9uIE1I
+KGEsYixjKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uJHRpPWN9LApBODpmdW5jdGlv
+biBBOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClU1OmZ1bmN0aW9uIFU1KGEs
+YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKU086ZnVuY3Rpb24gU08oYSxiLGMpe3Ro
+aXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApTVTpmdW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9u
+IFJlKCl7fSwKWEM6ZnVuY3Rpb24gWEMoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sCmRj
+OmZ1bmN0aW9uKCl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIE1hcCIp
+KX0sCk5ROmZ1bmN0aW9uKGEpe3ZhciB0LHM9SC5KZyhhKQppZih0eXBlb2Ygcz09InN0cmluZyIpcmV0
+dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihi
+IT1udWxsKXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmMoYSl9LApkOmZ1bmN0
+aW9uKGEpe3ZhciB0CmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2YgYT09Im51
+bWJlciIpe2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUiCmVsc2Ug
+aWYoITE9PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouaihh
+KQppZih0eXBlb2YgdCE9InN0cmluZyIpdGhyb3cgSC5iKEgudEwoYSkpCnJldHVybiB0fSwKZVE6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9YS4kaWRlbnRpdHlIYXNoCmlmKHQ9PW51bGwpe3Q9TWF0aC5yYW5kb20oKSow
+eDNmZmZmZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXR9cmV0dXJuIHR9LApIcDpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC50TChhKSkKdD0v
+XlxzKlsrLV0/KCgweFthLWYwLTldKyl8KFxkKyl8KFthLXowLTldKykpXHMqJC9pLmV4ZWMoYSkKaWYo
+dD09bnVsbClyZXR1cm4gbgppZigzPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LDMpCnM9SC55KHRbM10p
+CmlmKGI9PW51bGwpe2lmKHMhPW51bGwpcmV0dXJuIHBhcnNlSW50KGEsMTApCmlmKHRbMl0hPW51bGwp
+cmV0dXJuIHBhcnNlSW50KGEsMTYpCnJldHVybiBufWlmKGI8Mnx8Yj4zNil0aHJvdyBILmIoUC5URShi
+LDIsMzYsInJhZGl4IixuKSkKaWYoYj09PTEwJiZzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQpp
+ZihiPDEwfHxzPT1udWxsKXtyPWI8PTEwPzQ3K2I6ODYrYgpxPXRbMV0KZm9yKHA9cS5sZW5ndGgsbz0w
+O288cDsrK28paWYoKEMueEIuVyhxLG8pfDMyKT5yKXJldHVybiBufXJldHVybiBwYXJzZUludChhLGIp
+fSwKTTpmdW5jdGlvbihhKXt2YXIgdD1ILkg1KGEpCnJldHVybiB0fSwKSDU6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyCmlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIEguZG0oSC56SyhhKSxudWxsKQppZihKLmlh
+KGEpPT09Qy5Pa3x8dS5hay5jKGEpKXt0PUMuTzQoYSkKaWYoSC5mKHQpKXJldHVybiB0CnM9YS5jb25z
+dHJ1Y3RvcgppZih0eXBlb2Ygcz09ImZ1bmN0aW9uIil7cj1zLm5hbWUKaWYodHlwZW9mIHI9PSJzdHJp
+bmciJiZILmYocikpcmV0dXJuIHJ9fXJldHVybiBILmRtKEgueksoYSksbnVsbCl9LApmOmZ1bmN0aW9u
+KGEpe3ZhciB0PWEhPT0iT2JqZWN0IiYmYSE9PSIiCnJldHVybiB0fSwKTTA6ZnVuY3Rpb24oKXtpZigh
+IXNlbGYubG9jYXRpb24pcmV0dXJuIHNlbGYubG9jYXRpb24uaHJlZgpyZXR1cm4gbnVsbH0sClZLOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9YS5sZW5ndGgKaWYocDw9NTAwKXJldHVybiBTdHJpbmcuZnJv
+bUNoYXJDb2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9IiIscz0wO3M8cDtzPXIpe3I9cys1MDAKcT1yPHA/
+cjpwCnQrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnNsaWNlKHMscSkpfXJldHVybiB0
+fSwKQ3E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9SC5WTShbXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9
+MDtzPGEubGVuZ3RoO2EubGVuZ3RoPT09dHx8KDAsSC5saykoYSksKytzKXtyPWFbc10KaWYoIUgub2so
+cikpdGhyb3cgSC5iKEgudEwocikpCmlmKHI8PTY1NTM1KUMuTm0uaShxLHIpCmVsc2UgaWYocjw9MTEx
+NDExMSl7Qy5ObS5pKHEsNTUyOTYrKEMuam4ud0coci02NTUzNiwxMCkmMTAyMykpCkMuTm0uaShxLDU2
+MzIwKyhyJjEwMjMpKX1lbHNlIHRocm93IEguYihILnRMKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFI
+Lm9rKHIpKXRocm93IEguYihILnRMKHIpKQppZihyPDApdGhyb3cgSC5iKEgudEwocikpCmlmKHI+NjU1
+MzUpcmV0dXJuIEguQ3EoYSl9cmV0dXJuIEguVksoYSl9LApmdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
+cyxyLHEKaWYoYzw9NTAwJiZiPT09MCYmYz09PWEubGVuZ3RoKXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
+b2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9YixzPSIiO3Q8Yzt0PXIpe3I9dCs1MDAKcT1yPGM/cjpjCnMr
+PVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KHQscSkpfXJldHVybiBzfSwK
+THc6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoMDw9YSl7aWYoYTw9NjU1MzUpcmV0dXJuIFN0cmluZy5mcm9t
+Q2hhckNvZGUoYSkKaWYoYTw9MTExNDExMSl7dD1hLTY1NTM2CnJldHVybiBTdHJpbmcuZnJvbUNoYXJD
+b2RlKCg1NTI5NnxDLmpuLndHKHQsMTApKT4+PjAsNTYzMjB8dCYxMDIzKX19dGhyb3cgSC5iKFAuVEUo
+YSwwLDExMTQxMTEsbnVsbCxudWxsKSl9LApvMjpmdW5jdGlvbihhKXtpZihhLmRhdGU9PT12b2lkIDAp
+YS5kYXRlPW5ldyBEYXRlKGEuYSkKcmV0dXJuIGEuZGF0ZX0sCnRKOmZ1bmN0aW9uKGEpe3ZhciB0PUgu
+bzIoYSkuZ2V0RnVsbFllYXIoKSswCnJldHVybiB0fSwKTlM6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihh
+KS5nZXRNb250aCgpKzEKcmV0dXJuIHR9LApqQTpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldERh
+dGUoKSswCnJldHVybiB0fSwKSVg6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRIb3VycygpKzAK
+cmV0dXJuIHR9LApjaDpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbnV0ZXMoKSswCnJldHVy
+biB0fSwKSmQ6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRTZWNvbmRzKCkrMApyZXR1cm4gdH0s
+Cm8xOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TWlsbGlzZWNvbmRzKCkrMApyZXR1cm4gdH0s
+CnpvOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9e30Kci5hPTAKdD1bXQpzPVtdCnIuYT1iLmxlbmd0
+aApDLk5tLkZWKHQsYikKci5iPSIiCmlmKGMhPW51bGwmJmMuYSE9PTApYy5LKDAsbmV3IEguQ2oocixz
+LHQpKQoiIityLmEKcmV0dXJuIEouSnkoYSxuZXcgSC5MSShDLlRlLDAsdCxzLDApKX0sCkVrOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiIGluc3RhbmNlb2YgQXJyYXkpdD1jPT1udWxsfHxjLmE9
+PT0wCmVsc2UgdD0hMQppZih0KXtzPWIKcj1zLmxlbmd0aAppZihyPT09MCl7aWYoISFhLiQwKXJldHVy
+biBhLiQwKCl9ZWxzZSBpZihyPT09MSl7aWYoISFhLiQxKXJldHVybiBhLiQxKHNbMF0pfWVsc2UgaWYo
+cj09PTIpe2lmKCEhYS4kMilyZXR1cm4gYS4kMihzWzBdLHNbMV0pfWVsc2UgaWYocj09PTMpe2lmKCEh
+YS4kMylyZXR1cm4gYS4kMyhzWzBdLHNbMV0sc1syXSl9ZWxzZSBpZihyPT09NCl7aWYoISFhLiQ0KXJl
+dHVybiBhLiQ0KHNbMF0sc1sxXSxzWzJdLHNbM10pfWVsc2UgaWYocj09PTUpaWYoISFhLiQ1KXJldHVy
+biBhLiQ1KHNbMF0sc1sxXSxzWzJdLHNbM10sc1s0XSkKcT1hWyIiKyIkIityXQppZihxIT1udWxsKXJl
+dHVybiBxLmFwcGx5KGEscyl9cmV0dXJuIEguRXcoYSxiLGMpfSwKRXc6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbyxuLG0sbCxrPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx1LnopLGo9
+ay5sZW5ndGgsaT1hLiRSCmlmKGo8aSlyZXR1cm4gSC56byhhLGssYykKdD1hLiRECnM9dD09bnVsbApy
+PSFzP3QoKTpudWxsCnE9Si5pYShhKQpwPXEuJEMKaWYodHlwZW9mIHA9PSJzdHJpbmciKXA9cVtwXQpp
+ZihzKXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPT09aSlyZXR1cm4g
+cC5hcHBseShhLGspCnJldHVybiBILnpvKGEsayxjKX1pZihyIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMh
+PW51bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxrLGMpCmlmKGo+aStyLmxlbmd0aClyZXR1cm4gSC56
+byhhLGssbnVsbCkKQy5ObS5GVihrLHIuc2xpY2Uoai1pKSkKcmV0dXJuIHAuYXBwbHkoYSxrKX1lbHNl
+e2lmKGo+aSlyZXR1cm4gSC56byhhLGssYykKbz1PYmplY3Qua2V5cyhyKQppZihjPT1udWxsKWZvcihz
+PW8ubGVuZ3RoLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8KDAsSC5saykobyksKytuKUMuTm0u
+aShrLHJbSC55KG9bbl0pXSkKZWxzZXtmb3Iocz1vLmxlbmd0aCxtPTAsbj0wO248by5sZW5ndGg7by5s
+ZW5ndGg9PT1zfHwoMCxILmxrKShvKSwrK24pe2w9SC55KG9bbl0pCmlmKGMueDQobCkpeysrbQpDLk5t
+LmkoayxjLnEoMCxsKSl9ZWxzZSBDLk5tLmkoayxyW2xdKX1pZihtIT09Yy5hKXJldHVybiBILnpvKGEs
+ayxjKX1yZXR1cm4gcC5hcHBseShhLGspfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEguYihILnRMKGEp
+KX0sCk9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihILkhZKGEsYikp
+fSwKSFk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9ImluZGV4IgppZighSC5vayhiKSlyZXR1cm4gbmV3
+IFAudSghMCxiLHIsbnVsbCkKdD1ILlNjKEouSG0oYSkpCmlmKCEoYjwwKSl7aWYodHlwZW9mIHQhPT0i
+bnVtYmVyIilyZXR1cm4gSC5wWSh0KQpzPWI+PXR9ZWxzZSBzPSEwCmlmKHMpcmV0dXJuIFAuQ2YoYixh
+LHIsbnVsbCx0KQpyZXR1cm4gUC54KGIscil9LAphdTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9IkludmFs
+aWQgdmFsdWUiCmlmKGE+YylyZXR1cm4gbmV3IFAuYkooMCxjLCEwLGEsInN0YXJ0Iix0KQppZihiIT1u
+dWxsKXtpZighSC5vayhiKSlyZXR1cm4gbmV3IFAudSghMCxiLCJlbmQiLG51bGwpCmlmKGI8YXx8Yj5j
+KXJldHVybiBuZXcgUC5iSihhLGMsITAsYiwiZW5kIix0KX1yZXR1cm4gbmV3IFAudSghMCxiLCJlbmQi
+LG51bGwpfSwKdEw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITAsYSxudWxsLG51bGwpfSwKYjpm
+dW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAubigpCnQ9bmV3IEVycm9yKCkKdC5kYXJ0
+RXhjZXB0aW9uPWEKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qpe09iamVjdC5kZWZpbmVQcm9w
+ZXJ0eSh0LCJtZXNzYWdlIix7Z2V0OkguaH0pCnQubmFtZT0iIn1lbHNlIHQudG9TdHJpbmc9SC5oCnJl
+dHVybiB0fSwKaDpmdW5jdGlvbigpe3JldHVybiBKLmoodGhpcy5kYXJ0RXhjZXB0aW9uKX0sCnZoOmZ1
+bmN0aW9uKGEpe3Rocm93IEguYihhKX0sCmxrOmZ1bmN0aW9uKGEpe3Rocm93IEguYihQLmE0KGEpKX0s
+CmNNOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbwphPUguZUEoYS5yZXBsYWNlKFN0cmluZyh7fSks
+JyRyZWNlaXZlciQnKSkKdD1hLm1hdGNoKC9cXFwkW2EtekEtWl0rXFxcJC9nKQppZih0PT1udWxsKXQ9
+SC5WTShbXSx1LnMpCnM9dC5pbmRleE9mKCJcXCRhcmd1bWVudHNcXCQiKQpyPXQuaW5kZXhPZigiXFwk
+YXJndW1lbnRzRXhwclxcJCIpCnE9dC5pbmRleE9mKCJcXCRleHByXFwkIikKcD10LmluZGV4T2YoIlxc
+JG1ldGhvZFxcJCIpCm89dC5pbmRleE9mKCJcXCRyZWNlaXZlclxcJCIpCnJldHVybiBuZXcgSC5mOShh
+LnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGFyZ3VtZW50c1xcXFxcXCQnLCdnJyksJygoPzp4fFte
+eF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNFeHByXFxcXFxcJCcsJ2cn
+KSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGV4cHJcXFxcXFwkJywn
+ZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkbWV0aG9kXFxcXFxc
+JCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJHJlY2VpdmVy
+XFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLHMscixxLHAsbyl9LApTNzpmdW5jdGlvbihhKXty
+ZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5
+eyRleHByJC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHQpe3JldHVybiB0Lm1lc3NhZ2V9
+fShhKX0sCk1qOmZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbigkZXhwciQpe3RyeXskZXhwciQuJG1l
+dGhvZCR9Y2F0Y2godCl7cmV0dXJuIHQubWVzc2FnZX19KGEpfSwKSWo6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gbmV3IEguVzAoYSxiPT1udWxsP251bGw6Yi5tZXRob2QpfSwKVDM6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD1iPT1udWxsLHM9dD9udWxsOmIubWV0aG9kCnJldHVybiBuZXcgSC5heihhLHMsdD9udWxsOmIucmVj
+ZWl2ZXIpfSwKUnU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmPW51
+bGwsZT1uZXcgSC5BbShhKQppZihhPT1udWxsKXJldHVybiBmCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJl
+dHVybiBlLiQxKGEuYSkKaWYodHlwZW9mIGEhPT0ib2JqZWN0IilyZXR1cm4gYQppZigiZGFydEV4Y2Vw
+dGlvbiIgaW4gYSlyZXR1cm4gZS4kMShhLmRhcnRFeGNlcHRpb24pCmVsc2UgaWYoISgibWVzc2FnZSIg
+aW4gYSkpcmV0dXJuIGEKdD1hLm1lc3NhZ2UKaWYoIm51bWJlciIgaW4gYSYmdHlwZW9mIGEubnVtYmVy
+PT0ibnVtYmVyIil7cz1hLm51bWJlcgpyPXMmNjU1MzUKaWYoKEMuam4ud0cocywxNikmODE5MSk9PT0x
+MClzd2l0Y2gocil7Y2FzZSA0Mzg6cmV0dXJuIGUuJDEoSC5UMyhILmQodCkrIiAoRXJyb3IgIityKyIp
+IixmKSkKY2FzZSA0NDU6Y2FzZSA1MDA3OnJldHVybiBlLiQxKEguSWooSC5kKHQpKyIgKEVycm9yICIr
+cisiKSIsZikpfX1pZihhIGluc3RhbmNlb2YgVHlwZUVycm9yKXtxPSQuU24oKQpwPSQubHEoKQpvPSQu
+TjkoKQpuPSQuaUkoKQptPSQuS2YoKQpsPSQuWmgoKQprPSQuck4oKQokLmMzKCkKaj0kLkhLKCkKaT0k
+LnIxKCkKaD1xLnFTKHQpCmlmKGghPW51bGwpcmV0dXJuIGUuJDEoSC5UMyhILnkodCksaCkpCmVsc2V7
+aD1wLnFTKHQpCmlmKGghPW51bGwpe2gubWV0aG9kPSJjYWxsIgpyZXR1cm4gZS4kMShILlQzKEgueSh0
+KSxoKSl9ZWxzZXtoPW8ucVModCkKaWYoaD09bnVsbCl7aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9bS5x
+Uyh0KQppZihoPT1udWxsKXtoPWwucVModCkKaWYoaD09bnVsbCl7aD1rLnFTKHQpCmlmKGg9PW51bGwp
+e2g9bi5xUyh0KQppZihoPT1udWxsKXtoPWoucVModCkKaWYoaD09bnVsbCl7aD1pLnFTKHQpCmc9aCE9
+bnVsbH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2Ug
+Zz0hMH1lbHNlIGc9ITAKaWYoZylyZXR1cm4gZS4kMShILklqKEgueSh0KSxoKSl9fXJldHVybiBlLiQx
+KG5ldyBILnZWKHR5cGVvZiB0PT0ic3RyaW5nIj90OiIiKSl9aWYoYSBpbnN0YW5jZW9mIFJhbmdlRXJy
+b3Ipe2lmKHR5cGVvZiB0PT0ic3RyaW5nIiYmdC5pbmRleE9mKCJjYWxsIHN0YWNrIikhPT0tMSlyZXR1
+cm4gbmV3IFAuS1koKQp0PWZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gU3RyaW5nKGIpfWNhdGNoKGQpe31y
+ZXR1cm4gbnVsbH0oYSkKcmV0dXJuIGUuJDEobmV3IFAudSghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmci
+P3QucmVwbGFjZSgvXlJhbmdlRXJyb3I6XHMqLywiIik6dCkpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9y
+PT0iZnVuY3Rpb24iJiZhIGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2YgdD09InN0cmlu
+ZyImJnQ9PT0idG9vIG11Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRz
+OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVs
+bClyZXR1cm4gbmV3IEguWE8oYSkKdD1hLiRjYWNoZWRUcmFjZQppZih0IT1udWxsKXJldHVybiB0CnJl
+dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
+LHE9YS5sZW5ndGgKZm9yKHQ9MDt0PHE7dD1yKXtzPXQrMQpyPXMrMQpiLlkoMCxhW3RdLGFbc10pfXJl
+dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3UuWi5iKGEpCnN3aXRjaChILlNjKGIpKXtj
+YXNlIDA6cmV0dXJuIGEuJDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQy
+KGMsZCkKY2FzZSAzOnJldHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9
+dGhyb3cgSC5iKG5ldyBQLkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFw
+cGVkIGNsb3N1cmUiKSl9LAp0UjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51
+bGwKdD1hLiRpZGVudGl0eQppZighIXQpcmV0dXJuIHQKdD1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1
+bmN0aW9uKGYsZyxoLGkpe3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0
+eT10CnJldHVybiB0fSwKaUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG4s
+bSxsPW51bGwsaz1iWzBdLGo9ay4kY2FsbE5hbWUsaT1lP09iamVjdC5jcmVhdGUobmV3IEguengoKS5j
+b25zdHJ1Y3Rvci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguclQobCxsLGwsbCkuY29uc3Ry
+dWN0b3IucHJvdG90eXBlKQppLiRpbml0aWFsaXplPWkuY29uc3RydWN0b3IKaWYoZSl0PWZ1bmN0aW9u
+IHN0YXRpY190ZWFyX29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtzPSQueWoKaWYodHlwZW9m
+IHMhPT0ibnVtYmVyIilyZXR1cm4gcy5oKCkKJC55aj1zKzEKcz1uZXcgRnVuY3Rpb24oImEsYixjLGQi
+K3MsInRoaXMuJGluaXRpYWxpemUoYSxiLGMsZCIrcysiKSIpCnQ9c31pLmNvbnN0cnVjdG9yPXQKdC5w
+cm90b3R5cGU9aQppZighZSl7cj1ILmJ4KGEsayxmKQpyLiRyZWZsZWN0aW9uSW5mbz1kfWVsc2V7aS4k
+c3RhdGljX25hbWU9ZwpyPWt9cT1ILmltKGQsZSxmKQppLiRTPXEKaVtqXT1yCmZvcihwPXIsbz0xO288
+Yi5sZW5ndGg7KytvKXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEs
+bixmKQppW21dPW59aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1pLiRDPXAKaS4kUj1r
+LiRSCmkuJEQ9ay4kRApyZXR1cm4gdH0sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2Yg
+YT09Im51bWJlciIpcmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQo
+ZSl9fShILkJwLGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBj
+b21wdXRlIHNpZ25hdHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKdD1jP0guUFc6SC5UbgpyZXR1cm4g
+ZnVuY3Rpb24oZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSx0KX10aHJv
+dyBILmIoIkVycm9yIGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIs
+YyxkKXt2YXIgdD1ILkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXty
+ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyx0KQpjYXNlIDE6cmV0dXJuIGZ1
+bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyx0KQpj
+YXNlIDI6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhp
+cylbZV0oZyxoKX19KGMsdCkKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlv
+bihnLGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyx0KQpjYXNlIDQ6cmV0dXJuIGZ1bmN0
+aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGop
+fX0oYyx0KQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGos
+ayl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGksaixrKX19KGMsdCkKZGVmYXVsdDpyZXR1cm4gZnVuY3Rp
+b24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9
+fShkLHQpfX0sCmJ4OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbgppZihjKXJldHVybiBI
+LkhmKGEsYikKdD1iLiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09bnVsbDpi
+PT09cgpwPSFxfHxzPj0yNwppZihwKXJldHVybiBILnZxKHMsIXEsdCxiKQppZihzPT09MCl7cT0kLnlq
+CmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIHEuaCgpCiQueWo9cSsxCm89InNlbGYiK3EKcT0i
+cmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbysiID0gdGhpcy4iCnA9JC5tSgpyZXR1cm4gbmV3IEZ1bmN0
+aW9uKHErSC5kKHA9PW51bGw/JC5tSj1ILkUyKCJzZWxmIik6cCkrIjtyZXR1cm4gIitvKyIuIitILmQo
+dCkrIigpO30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNl
+KDAscykuam9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLmgoKQok
+LnlqPXErMQpuKz1xCnE9InJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIgpwPSQubUoK
+cmV0dXJuIG5ldyBGdW5jdGlvbihxK0guZChwPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnApKyIuIitI
+LmQodCkrIigiK24rIik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILkRWLHM9SC55
+Uwpzd2l0Y2goYj8tMTphKXtjYXNlIDA6dGhyb3cgSC5iKEguRWYoIkludGVyY2VwdGVkIGZ1bmN0aW9u
+IHdpdGggbm8gYXJndW1lbnRzLiIpKQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4g
+ZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpKX19KGMsdCxzKQpjYXNlIDI6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlz
+KSxoKX19KGMsdCxzKQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24o
+aCxpKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSl9fShjLHQscykKY2FzZSA0OnJldHVybiBm
+dW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
+aXMpLGgsaSxqKX19KGMsdCxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVu
+Y3Rpb24oaCxpLGosayl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrKX19KGMsdCxzKQpj
+YXNlIDY6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGosayxsKXtyZXR1
+cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGssbCl9fShjLHQscykKZGVmYXVsdDpyZXR1cm4gZnVu
+Y3Rpb24oZSxmLGcsaCl7cmV0dXJuIGZ1bmN0aW9uKCl7aD1bZyh0aGlzKV0KQXJyYXkucHJvdG90eXBl
+LnB1c2guYXBwbHkoaCxhcmd1bWVudHMpCnJldHVybiBlLmFwcGx5KGYodGhpcyksaCl9fShkLHQscyl9
+fSwKSGY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPSQubUoKaWYobT09bnVsbCltPSQu
+bUo9SC5FMigic2VsZiIpCnQ9JC5QNAppZih0PT1udWxsKXQ9JC5QND1ILkUyKCJyZWNlaXZlciIpCnM9
+Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51bGw6Yj09PXEKbz0hcHx8
+cj49MjgKaWYobylyZXR1cm4gSC5aNChyLCFwLHMsYikKaWYocj09PTEpe209InJldHVybiBmdW5jdGlv
+bigpe3JldHVybiB0aGlzLiIrSC5kKG0pKyIuIitILmQocykrIih0aGlzLiIrSC5kKHQpKyIpOyIKdD0k
+LnlqCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcg
+RnVuY3Rpb24obSt0KyJ9IikoKX1uPSJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIp
+LnNwbGljZSgwLHItMSkuam9pbigiLCIpCm09InJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRo
+aXMuIitILmQobSkrIi4iK0guZChzKSsiKHRoaXMuIitILmQodCkrIiwgIituKyIpOyIKdD0kLnlqCmlm
+KHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcgRnVuY3Rp
+b24obSt0KyJ9IikoKX0sCktxOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3JldHVybiBILmlBKGEsYixj
+LGQsISFlLCEhZixnKX0sClRuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2Us
+SC56SyhhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxI
+LnpLKGEuYyksYil9LApEVjpmdW5jdGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEuY30sCkUyOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPW5ldyBILnJUKCJzZWxmIiwidGFyZ2V0
+IiwicmVjZWl2ZXIiLCJuYW1lIikscD1KLkVwKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHEpKQpm
+b3IodD1wLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1hKXJldHVybiByfX0sCm9U
+OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBleHByZXNzaW9uIG11c3Qgbm90IGJl
+IG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93IEguYihuZXcgSC5rWShhKSl9LAph
+ZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApFZjpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguRXEoYSl9LApZZzpmdW5jdGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKVk06
+ZnVuY3Rpb24oYSxiKXthLiR0aT1iCnJldHVybiBhfSwKb1g6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbCly
+ZXR1cm4gbnVsbApyZXR1cm4gYS4kdGl9LApJTTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEguWTkoYVsi
+JGEiK0guZChjKV0sSC5vWChiKSl9LApZOTpmdW5jdGlvbihhLGIpe2lmKGE9PW51bGwpcmV0dXJuIGIK
+YT1hLmFwcGx5KG51bGwsYikKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihBcnJheS5pc0FycmF5KGEp
+KXJldHVybiBhCmlmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBhLmFwcGx5KG51bGwsYikKcmV0
+dXJuIGJ9LApJRzpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGEuYXBwbHkoYixILlk5KEouaWEoYilbIiRh
+IitILmQoYyldLEgub1goYikpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVy
+dHkoYSxiLHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6
+dHJ1ZX0pfSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1ILnkoJC5ORi4kMShhKSksbz0kLm53
+W3BdCmlmKG8hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5h
+bWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVl
+fSkKcmV0dXJuIG8uaX10PSQudnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0b3Jz
+QnlUYWdbcF0KaWYocz09bnVsbCl7cD1ILnkoJC5UWC4kMihhLHApKQppZihwIT1udWxsKXtvPSQubndb
+cF0KaWYobyE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFt
+ZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9
+KQpyZXR1cm4gby5pfXQ9JC52dltwXQppZih0IT1udWxsKXJldHVybiB0CnM9di5pbnRlcmNlcHRvcnNC
+eVRhZ1twXX19aWYocz09bnVsbClyZXR1cm4gbnVsbAp0PXMucHJvdG90eXBlCnI9cFswXQppZihyPT09
+IiEiKXtvPUguVmEodCkKJC5ud1twXT1vCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQ
+cm9wZXJ0eU5hbWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3Vy
+YWJsZTp0cnVlfSkKcmV0dXJuIG8uaX1pZihyPT09In4iKXskLnZ2W3BdPXQKcmV0dXJuIHR9aWYocj09
+PSItIil7cT1ILlZhKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2Yo
+YSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
+OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWlmKHI9PT0iKyIpcmV0dXJuIEguTGMo
+YSx0KQppZihyPT09IioiKXRocm93IEguYihQLlNZKHApKQppZih2LmxlYWZUYWdzW3BdPT09dHJ1ZSl7
+cT1ILlZhKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5k
+aXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUs
+Y29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWVsc2UgcmV0dXJuIEguTGMoYSx0KX0sCkxjOmZ1
+bmN0aW9uKGEsYil7dmFyIHQ9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9w
+ZXJ0eSh0LHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYix0LG51bGwsbnVsbCksZW51
+bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApW
+YTpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciB0PWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJldHVybiBILlZh
+KHQpCmVsc2UgcmV0dXJuIEouUXUodCxjLG51bGwsbnVsbCl9LApYRDpmdW5jdGlvbigpe2lmKCEwPT09
+JC5CdilyZXR1cm4KJC5Cdj0hMApILloxKCl9LApaMTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxu
+LG0KJC5udz1PYmplY3QuY3JlYXRlKG51bGwpCiQudnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmtPKCkK
+dD12LmludGVyY2VwdG9yc0J5VGFnCnM9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModCkKaWYodHlw
+ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpyPWZ1bmN0aW9uKCl7fQpmb3IocT0wO3E8cy5s
+ZW5ndGg7KytxKXtwPXNbcV0Kbz0kLng3LiQxKHApCmlmKG8hPW51bGwpe249SC5WRihwLHRbcF0sbykK
+aWYobiE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG8sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
+LnByb3RvdHlwZT1vfX19fWZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1txXQppZigvXltBLVphLXpf
+XS8udGVzdChwKSl7bT10W3BdCnRbIiEiK3BdPW0KdFsifiIrcF09bQp0WyItIitwXT1tCnRbIisiK3Bd
+PW0KdFsiKiIrcF09bX19fSwKa086ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj1DLllxKCkKbj1I
+LnVkKEMuS1UsSC51ZChDLmZRLEgudWQoQy5pNyxILnVkKEMuaTcsSC51ZChDLnhpLEgudWQoQy5kayxI
+LnVkKEMud2IoQy5PNCksbikpKSkpKSkKaWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJh
+bnNmb3JtZXIhPSJ1bmRlZmluZWQiKXt0PWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIK
+aWYodHlwZW9mIHQ9PSJmdW5jdGlvbiIpdD1bdF0KaWYodC5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHM9
+MDtzPHQubGVuZ3RoOysrcyl7cj10W3NdCmlmKHR5cGVvZiByPT0iZnVuY3Rpb24iKW49cihuKXx8bn19
+cT1uLmdldFRhZwpwPW4uZ2V0VW5rbm93blRhZwpvPW4ucHJvdG90eXBlRm9yVGFnCiQuTkY9bmV3IEgu
+ZEMocSkKJC5UWD1uZXcgSC53TihwKQokLng3PW5ldyBILlZYKG8pfSwKdWQ6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gYShiKXx8Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdD1iPyJtIjoiIixzPWM/
+IiI6ImkiLHI9ZD8idSI6IiIscT1lPyJzIjoiIixwPWY/ImciOiIiLG89ZnVuY3Rpb24oZyxoKXt0cnl7
+cmV0dXJuIG5ldyBSZWdFeHAoZyxoKX1jYXRjaChuKXtyZXR1cm4gbn19KGEsdCtzK3IrcStwKQppZihv
+IGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBvCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBw
+YXR0ZXJuICgiK1N0cmluZyhvKSsiKSIsYSxudWxsKSl9LAptMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5z
+dGFuY2VvZiBILlZSKXt0PUMueEIuRyhhLGMpCnJldHVybiBiLmIudGVzdCh0KX1lbHNle3Q9Si5GTChi
+LEMueEIuRyhhLGMpKQpyZXR1cm4hdC5nbDAodCl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9m
+KCIkIiwwKT49MClyZXR1cm4gYS5yZXBsYWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5j
+dGlvbihhKXtpZigvW1tcXXt9KCkqKz8uXFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tb
+XF17fSgpKis/LlxcXiR8XS9nLCJcXCQmIikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9SC5uTShhLGIsYykKcmV0dXJuIHR9LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYo
+Yj09PSIiKXtpZihhPT09IiIpcmV0dXJuIGMKdD1hLmxlbmd0aApmb3Iocz1jLHI9MDtyPHQ7KytyKXM9
+cythW3JdK2MKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9cT1hLmluZGV4T2YoYiwwKQppZihx
+PDApcmV0dXJuIGEKaWYoYS5sZW5ndGg8NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNw
+bGl0KGIpLmpvaW4oYykKcmV0dXJuIGEucmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0
+KGMpKX0sClBEOmZ1bmN0aW9uIFBEKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9u
+IFdVKCl7fSwKTFA6ZnVuY3Rpb24gTFAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLiR0aT1kfSwKWFI6ZnVuY3Rpb24gWFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVu
+Y3Rpb24gTEkoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1l
+fSwKQ2o6ZnVuY3Rpb24gQ2ooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVu
+Y3Rpb24gZjkoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5l
+PWUKXy5mPWZ9LApXMDpmdW5jdGlvbiBXMChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rp
+b24gYXooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7
+dGhpcy5hPWF9LApicTpmdW5jdGlvbiBicShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQW06ZnVuY3Rp
+b24gQW0oYSl7dGhpcy5hPWF9LApYTzpmdW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0s
+ClRwOmZ1bmN0aW9uIFRwKCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30s
+CnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
+LApFcTpmdW5jdGlvbiBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwK
+TjU6ZnVuY3Rpb24gTjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwK
+Xy5yPTAKXy4kdGk9YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9Ygpf
+LmQ9Xy5jPW51bGx9LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpm
+dW5jdGlvbiBONihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9
+Y30sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhpcy5hPWF9
+LApWWDpmdW5jdGlvbiBWWChhKXt0aGlzLmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhp
+cwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktX
+OmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9u
+IFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rp
+b24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IEludDhBcnJheShhKX0sCm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9
+PWF8fGE+PWMpdGhyb3cgSC5iKEguSFkoYixhKSl9LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYo
+IShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1ifHxhPmJ8fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIo
+SC5hdShhLGIsYykpCnJldHVybiBifSwKRVQ6ZnVuY3Rpb24gRVQoKXt9LApiMDpmdW5jdGlvbiBiMCgp
+e30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVuY3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigp
+e30sCmRFOmZ1bmN0aW9uIGRFKCl7fSwKWkE6ZnVuY3Rpb24gWkEoKXt9LAp3ZjpmdW5jdGlvbiB3Zigp
+e30sClBxOmZ1bmN0aW9uIFBxKCl7fSwKZUU6ZnVuY3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigp
+e30sClJHOmZ1bmN0aW9uIFJHKCl7fSwKVlA6ZnVuY3Rpb24gVlAoKXt9LApXQjpmdW5jdGlvbiBXQigp
+e30sClpHOmZ1bmN0aW9uIFpHKCl7fSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmQKcmV0dXJuIHQ9
+PW51bGw/Yi5kPUguSihhLCJiOCIsW2IuUV0pOnR9LApRMTpmdW5jdGlvbihhKXt2YXIgdD1hLnoKaWYo
+dD09PTZ8fHQ9PT03fHx0PT09OClyZXR1cm4gSC5RMShhLlEpCnJldHVybiB0PT09MTF8fHQ9PT0xMn0s
+Cm1EOmZ1bmN0aW9uKGEpe3JldHVybiBhLmRifSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5
+cGVVbml2ZXJzZSxhKX0sCkpTOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJFMKaWYodCE9bnVsbCl7aWYodHlw
+ZW9mIHQ9PSJudW1iZXIiKXJldHVybiBILkJwKHQpCnJldHVybiBhLiRTKCl9cmV0dXJuIG51bGx9LApV
+ZTpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKEguUTEoYikpaWYoYSBpbnN0YW5jZW9mIEguVHApe3Q9SC5K
+UyhhKQppZih0IT1udWxsKXJldHVybiB0fXJldHVybiBILnpLKGEpfSwKeks6ZnVuY3Rpb24oYSl7dmFy
+IHQKaWYoYSBpbnN0YW5jZW9mIFAuayl7dD1hLiR0aQpyZXR1cm4gdCE9bnVsbD90OkguVlUoYSl9aWYo
+QXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1
+bmN0aW9uKGEpe3ZhciB0PWEuJHRpLHM9dS5tCmlmKHQ9PW51bGwpcmV0dXJuIHMKaWYodC5jb25zdHJ1
+Y3RvciE9PXMuY29uc3RydWN0b3IpcmV0dXJuIHMKcmV0dXJuIHR9LApMaDpmdW5jdGlvbihhKXt2YXIg
+dD1hLiR0aQpyZXR1cm4gdCE9bnVsbD90OkguVlUoYSl9LApWVTpmdW5jdGlvbihhKXt2YXIgdD1hLmNv
+bnN0cnVjdG9yLHM9dC4kY2NhY2hlCmlmKHMhPW51bGwpcmV0dXJuIHMKcmV0dXJuIEgucjkoYSx0KX0s
+CnI5OmZ1bmN0aW9uKGEsYil7dmFyIHQ9YSBpbnN0YW5jZW9mIEguVHA/YS5fX3Byb3RvX18uX19wcm90
+b19fLmNvbnN0cnVjdG9yOmIscz1ILmFpKHYudHlwZVVuaXZlcnNlLHQubmFtZSkKYi4kY2NhY2hlPXMK
+cmV0dXJuIHN9LApCcDpmdW5jdGlvbihhKXt2YXIgdCxzPWEscj12LnR5cGVzLHE9cltzXQppZih0eXBl
+b2YgcT09InN0cmluZyIpe3Q9SC5FKHYudHlwZVVuaXZlcnNlLHEpCnJbc109dApyZXR1cm4gdH1yZXR1
+cm4gcX0sCkpKOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMueixxPUguWU8KaWYoSC5jYyhzKSl7
+cT1ILkl3CnMuYj1zLmE9SC5obn1lbHNlIGlmKHI9PT05KXt0PXMuZGIKaWYoIktOIj09PXQpcT1ILm9r
+CmVsc2UgaWYoIkNQIj09PXQpcT1ILktICmVsc2UgaWYoIkZLIj09PXQpcT1ILktICmVsc2UgaWYoInFV
+Ij09PXQpcT1ILk1NCmVsc2UgaWYoImEyIj09PXQpcT1ILmwKZWxzZXtyPXMuUQppZihzLmNoLmV2ZXJ5
+KEguY2MpKXtzLng9IiRpIityCnE9SC50NH19fXMuYz1xCnJldHVybiBzLmMoYSl9LApZTzpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzCnJldHVybiBILldlKHYudHlwZVVuaXZlcnNlLEguVWUoYSx0KSxudWxsLHQs
+bnVsbCl9LAp0NDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLngKaWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1
+cm4hIWFbdF0KcmV0dXJuISFKLmlhKGEpW3RdfSwKT3o6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVs
+bClyZXR1cm4gYQp0PXRoaXMKaWYodC5jKGEpKXJldHVybiBhCnRocm93IEguYihILlE1KEguV0soYSxI
+LlVlKGEsdCksSC5kbSh0LG51bGwpKSkpfSwKQXY6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbCly
+ZXR1cm4gYQp0PXRoaXMKaWYodC5jKGEpKXJldHVybiBhCnRocm93IEguYihILlpjKEguV0soYSxILlVl
+KGEsdCksSC5kbSh0LG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9bnVsbAppZihI
+LldlKHYudHlwZVVuaXZlcnNlLGEsdCxiLHQpKXJldHVybiBhCnRocm93IEguYihILlpjKCJUaGUgdHlw
+ZSBhcmd1bWVudCAnIitILmQoSC5kbShhLHQpKSsiJyBpcyBub3QgYSBzdWJ0eXBlIG9mIHRoZSB0eXBl
+IHZhcmlhYmxlIGJvdW5kICciK0guZChILmRtKGIsdCkpKyInIG9mIHR5cGUgdmFyaWFibGUgJyIrYysi
+JyBpbiAnIitILmQoZCkrIicuIikpfSwKV0s6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAucChhKSxzPUgu
+ZG0oYj09bnVsbD9ILnpLKGEpOmIsbnVsbCkKcmV0dXJuIHQrIjogdHlwZSAnIitILmQocykrIicgaXMg
+bm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guZChjKSsiJyJ9LApRNTpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguaHooIkNhc3RFcnJvcjogIithKX0sClB2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmh6
+KCJDYXN0RXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBI
+LmlNKCJUeXBlRXJyb3I6ICIrYSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBl
+RXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwKSXc6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApobjpmdW5j
+dGlvbihhKXtyZXR1cm4gYX0sCmw6ZnVuY3Rpb24oYSl7cmV0dXJuITA9PT1hfHwhMT09PWF9LApFOTpm
+dW5jdGlvbihhKXtpZighMD09PWF8fCExPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRo
+cm93IEguYihILlB2KGEsImJvb2wiKSl9LAp4ZDpmdW5jdGlvbihhKXtpZighMD09PWF8fCExPT09YSly
+ZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9vbCIpKX0sCmRqOmZ1
+bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBh
+CnRocm93IEguYihILlB2KGEsImRvdWJsZSIpKX0sCklnOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0i
+bnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiZG91Ymxl
+IikpfSwKb2s6ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihh
+KT09PWF9LApXWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9
+PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguUHYoYSwiaW50IikpfSwK
+U2M6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1
+cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiaW50IikpfSwKS0g6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIn0sCnVVOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
+PT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILlB2KGEsIm51
+bSIpKX0sCkROOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1u
+dWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKTU06ZnVuY3Rpb24oYSl7cmV0dXJu
+IHR5cGVvZiBhPT0ic3RyaW5nIn0sCmMwOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIily
+ZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILlB2KGEsIlN0cmluZyIpKX0sCnk6
+ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmciKSl9LAppbzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpm
+b3IodD0iIixzPSIiLHI9MDtyPGEubGVuZ3RoOysrcixzPSIsICIpdCs9Qy54Qi5oKHMsSC5kbShhW3Jd
+LGIpKQpyZXR1cm4gdH0sCmJJOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGMsYixhPSIsICIKaWYoYTIhPW51bGwpe3Q9YTIubGVuZ3RoCmlmKGExPT1u
+dWxsKXthMT1ILlZNKFtdLHUucykKcz1udWxsfWVsc2Ugcz1hMS5sZW5ndGgKcj1hMS5sZW5ndGgKZm9y
+KHE9dDtxPjA7LS1xKUMuTm0uaShhMSwiVCIrKHIrcSkpCmZvcihwPSI8IixvPSIiLHE9MDtxPHQ7Kytx
+LG89YSl7cCs9bwpuPWExLmxlbmd0aAptPW4tMS1xCmlmKG08MClyZXR1cm4gSC5PSChhMSxtKQpwPUMu
+eEIuaChwLGExW21dKQpsPWEyW3FdCmlmKCFILmNjKGwpKXArPUMueEIuaCgiIGV4dGVuZHMgIixILmRt
+KGwsYTEpKX1wKz0iPiJ9ZWxzZXtwPSIiCnM9bnVsbH1uPWEwLlEKaz1hMC5jaApqPWsuYQppPWoubGVu
+Z3RoCmg9ay5iCmc9aC5sZW5ndGgKZj1rLmMKZT1mLmxlbmd0aApkPUguZG0obixhMSkKZm9yKGM9IiIs
+Yj0iIixxPTA7cTxpOysrcSxiPWEpYys9Qy54Qi5oKGIsSC5kbShqW3FdLGExKSkKaWYoZz4wKXtjKz1i
+KyJbIgpmb3IoYj0iIixxPTA7cTxnOysrcSxiPWEpYys9Qy54Qi5oKGIsSC5kbShoW3FdLGExKSkKYys9
+Il0ifWlmKGU+MCl7Yys9YisieyIKZm9yKGI9IiIscT0wO3E8ZTtxKz0yLGI9YSljKz1DLnhCLmgoYixI
+LmRtKGZbcSsxXSxhMSkpKyIgIitmW3FdCmMrPSJ9In1pZihzIT1udWxsKWExLmxlbmd0aD1zCnJldHVy
+biBwKyIoIitjKyIpID0+ICIrSC5kKGQpfSwKZG06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEu
+egppZihwPT09NSlyZXR1cm4iZXJhc2VkIgppZihwPT09MilyZXR1cm4iZHluYW1pYyIKaWYocD09PTMp
+cmV0dXJuInZvaWQiCmlmKHA9PT0xKXJldHVybiJOZXZlciIKaWYocD09PTQpcmV0dXJuImFueSIKaWYo
+cD09PTYpcmV0dXJuIEguZChILmRtKGEuUSxiKSkrIioiCmlmKHA9PT03KXJldHVybiBILmQoSC5kbShh
+LlEsYikpKyI/IgppZihwPT09OClyZXR1cm4iRnV0dXJlT3I8IitILmQoSC5kbShhLlEsYikpKyI+Igpp
+ZihwPT09OSl7dD1ILm8zKGEuUSkKcz1hLmNoCnJldHVybiBzLmxlbmd0aCE9PTA/dCsoIjwiK0guaW8o
+cyxiKSsiPiIpOnR9aWYocD09PTExKXJldHVybiBILmJJKGEsYixudWxsKQppZihwPT09MTIpcmV0dXJu
+IEguYkkoYS5RLGIsYS5jaCkKaWYocD09PTEzKXtyPWEuUQpxPWIubGVuZ3RoCnI9cS0xLXIKaWYocjww
+fHxyPj1xKXJldHVybiBILk9IKGIscikKcmV0dXJuIGJbcl19cmV0dXJuIj8ifSwKbzM6ZnVuY3Rpb24o
+YSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVy
+biB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7dHlwZW9mIHQ9PSJzdHJpbmci
+Oyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1hLmVU
+LG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiKQplbHNlIGlmKHR5cGVvZiBuPT0ibnVtYmVy
+Iil7dD1uCnM9SC5tKGEsNSwiIyIpCnI9W10KZm9yKHE9MDtxPHQ7KytxKXIucHVzaChzKQpwPUguSihh
+LGIscikKb1tiXT1wCnJldHVybiBwfWVsc2UgcmV0dXJuIG59LAp4YjpmdW5jdGlvbihhLGIpe3JldHVy
+biBILkl4KGEudFIsYil9LApGRjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEuZVQsYil9LApFOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz1hLmVDLHI9cy5nZXQoYikKaWYociE9bnVsbClyZXR1cm4gcgp0PUgu
+eihhLG51bGwsYikKcy5zZXQoYix0KQpyZXR1cm4gdH0sCmNFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
+LHI9Yi5jeAppZihyPT1udWxsKXI9Yi5jeD1uZXcgTWFwKCkKdD1yLmdldChjKQppZih0IT1udWxsKXJl
+dHVybiB0CnM9SC56KGEsYixjKQpyLnNldChjLHMpCnJldHVybiBzfSwKdjU6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMscixxPWIuY3kKaWYocT09bnVsbClxPWIuY3k9bmV3IE1hcCgpCnQ9Yy5kYgpzPXEuZ2V0
+KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmEoYSxiLGMuej09PTEwP2MuY2g6W2NdKQpxLnNldCh0
+LHIpCnJldHVybiByfSwKejpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5pKEgubyhhLGIsYykpCnJldHVy
+biB0fSwKV0c6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmRiCmEuZUMuc2V0KHQsYikKYi5hPUguT3oKYi5i
+PUguQXYKYi5jPUguSkoKcmV0dXJuIGJ9LAptOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWEuZUMuZ2V0
+KGMpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD1uZXcgSC5KYyhudWxsLG51bGwsbnVsbCkKdC56PWIKdC5k
+Yj1jCnJldHVybiBILldHKGEsdCl9LAp2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9YS5lQy5nZXQo
+ZCkKaWYocyE9bnVsbClyZXR1cm4gcwp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxsKQp0Lno9Ygp0LlE9
+Ywp0LmRiPWQKcmV0dXJuIEguV0coYSx0KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPSIiK2IrIl4i
+LHI9YS5lQy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxs
+KQp0Lno9MTMKdC5RPWIKdC5kYj1zCnJldHVybiBILldHKGEsdCl9LApVeDpmdW5jdGlvbihhKXt2YXIg
+dCxzLHIscT1hLmxlbmd0aApmb3IodD0iIixzPSIiLHI9MDtyPHE7KytyLHM9IiwiKXQrPXMrYVtyXS5k
+YgpyZXR1cm4gdH0sClM0OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz1hLmxlbmd0aApmb3IodD0i
+IixzPSIiLHI9MDtyPG87cis9MixzPSIsIil7cT1hW3JdCnA9YVtyKzFdLmRiCnQrPXMrcSsiOiIrcH1y
+ZXR1cm4gdH0sCko6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iCmlmKGMubGVuZ3RoIT09MClyKz0i
+PCIrSC5VeChjKSsiPiIKdD1hLmVDLmdldChyKQppZih0IT1udWxsKXJldHVybiB0CnM9bmV3IEguSmMo
+bnVsbCxudWxsLG51bGwpCnMuej05CnMuUT1iCnMuY2g9YwppZihjLmxlbmd0aD4wKXMuZD1jWzBdCnMu
+ZGI9cgpyZXR1cm4gSC5XRyhhLHMpfSwKYTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscAppZihi
+Lno9PT0xMCl7dD1iLlEKcz1iLmNoLmNvbmNhdChjKX1lbHNle3M9Ywp0PWJ9cj10LmRiKyI7IisoIjwi
+K0guVXgocykrIj4iKQpxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcD1uZXcgSC5KYyhu
+dWxsLG51bGwsbnVsbCkKcC56PTEwCnAuUT10CnAuY2g9cwpwLmRiPXIKcmV0dXJuIEguV0coYSxwKX0s
+CkM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIuZGIscD1jLmEsbz1wLmxlbmd0aCxuPWMuYixt
+PW4ubGVuZ3RoLGw9Yy5jLGs9bC5sZW5ndGgsaj0iKCIrSC5VeChwKQppZihtPjApais9KG8+MD8iLCI6
+IiIpKyJbIitILlV4KG4pKyJdIgppZihrPjApais9KG8+MD8iLCI6IiIpKyJ7IitILlM0KGwpKyJ9Igp0
+PXErKGorIikiKQpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1uZXcgSC5KYyhudWxs
+LG51bGwsbnVsbCkKci56PTExCnIuUT1iCnIuY2g9YwpyLmRiPXQKcmV0dXJuIEguV0coYSxyKX0sCkQ6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5kYisiPCIrSC5VeChjKSsiPiIscj1hLmVDLmdldChzKQpp
+ZihyIT1udWxsKXJldHVybiByCnQ9bmV3IEguSmMobnVsbCxudWxsLG51bGwpCnQuej0xMgp0LlE9Ygp0
+LmNoPWMKdC5kYj1zCnJldHVybiBILldHKGEsdCl9LApvOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm57dTph
+LGU6YixyOmMsczpbXSxwOjB9fSwKaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
+LGksaCxnPWEucixmPWEucwpmb3IodD1nLmxlbmd0aCxzPTA7czx0Oyl7cj1nLmNoYXJDb2RlQXQocykK
+aWYocj49NDgmJnI8PTU3KXM9SC5BKHMrMSxyLGcsZikKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1
+NTM1KTwyNnx8cj09PTk1fHxyPT09MzYpcz1ILnQoYSxzLGcsZiwhMSkKZWxzZSBpZihyPT09NDYpcz1I
+LnQoYSxzLGcsZiwhMCkKZWxzZXsrK3MKc3dpdGNoKHIpe2Nhc2UgNDQ6YnJlYWsKY2FzZSA1ODpicmVh
+awpjYXNlIDU5OmYucHVzaChILksoYS51LGEuZSxmLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpmLnB1c2go
+SC5IKGEudSxmLnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpmLnB1c2goSC5tKGEudSw1LCIjIikpCmJyZWFr
+CmNhc2UgNjQ6Zi5wdXNoKEgubShhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpmLnB1c2goSC5tKGEu
+dSwzLCJ+IikpCmJyZWFrCmNhc2UgNjA6Zi5wdXNoKGEucCkKYS5wPWYubGVuZ3RoCmJyZWFrCmNhc2Ug
+NjI6cT1hLnUKcD1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLHApCmEucD1mLnBvcCgpCm89Zi5wb3Ao
+KQppZih0eXBlb2Ygbz09InN0cmluZyIpZi5wdXNoKEguSihxLG8scCkpCmVsc2V7bj1ILksocSxhLmUs
+bykKc3dpdGNoKG4ueil7Y2FzZSAxMTpmLnB1c2goSC5EKHEsbixwKSkKYnJlYWsKZGVmYXVsdDpmLnB1
+c2goSC5hKHEsbixwKSkKYnJlYWt9fWJyZWFrCmNhc2UgMzg6SC5JKGEsZikKYnJlYWsKY2FzZSA0Mjpt
+PWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sNixsLGwuZGIrIioiKSkKYnJlYWsK
+Y2FzZSA2MzptPWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sNyxsLGwuZGIrIj8i
+KSkKYnJlYWsKY2FzZSA0NzptPWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sOCxs
+LGwuZGIrIi8iKSkKYnJlYWsKY2FzZSA0MDpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2Fz
+ZSA0MTpxPWEudQprPW5ldyBILkcoKQpqPXEuc0VBCmk9cS5zRUEKbz1mLnBvcCgpCmlmKHR5cGVvZiBv
+PT0ibnVtYmVyIilzd2l0Y2gobyl7Y2FzZS0xOmo9Zi5wb3AoKQpicmVhawpjYXNlLTI6aT1mLnBvcCgp
+CmJyZWFrCmRlZmF1bHQ6Zi5wdXNoKG8pCmJyZWFrfWVsc2UgZi5wdXNoKG8pCnA9Zi5zcGxpY2UoYS5w
+KQpILnIoYS51LGEuZSxwKQphLnA9Zi5wb3AoKQprLmE9cAprLmI9agprLmM9aQpmLnB1c2goSC5DKHEs
+SC5LKHEsYS5lLGYucG9wKCkpLGspKQpicmVhawpjYXNlIDkxOmYucHVzaChhLnApCmEucD1mLmxlbmd0
+aApicmVhawpjYXNlIDkzOnA9Zi5zcGxpY2UoYS5wKQpILnIoYS51LGEuZSxwKQphLnA9Zi5wb3AoKQpm
+LnB1c2gocCkKZi5wdXNoKC0xKQpicmVhawpjYXNlIDEyMzpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgK
+YnJlYWsKY2FzZSAxMjU6cD1mLnNwbGljZShhLnApCkguQihhLnUsYS5lLHApCmEucD1mLnBvcCgpCmYu
+cHVzaChwKQpmLnB1c2goLTIpCmJyZWFrCmRlZmF1bHQ6dGhyb3ciQmFkIGNoYXJhY3RlciAiK3J9fX1o
+PWYucG9wKCkKcmV0dXJuIEguSyhhLnUsYS5lLGgpfSwKQTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHI9Yi00OApmb3IodD1jLmxlbmd0aDthPHQ7KythKXtzPWMuY2hhckNvZGVBdChhKQppZighKHM+PTQ4
+JiZzPD01NykpYnJlYWsKcj1yKjEwKyhzLTQ4KX1kLnB1c2gocikKcmV0dXJuIGF9LAp0OmZ1bmN0aW9u
+KGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG49YisxCmZvcih0PWMubGVuZ3RoO248dDsrK24pe3M9
+Yy5jaGFyQ29kZUF0KG4pCmlmKHM9PT00Nil7aWYoZSlicmVhawplPSEwfWVsc2V7aWYoISgoKChzfDMy
+KT4+PjApLTk3JjY1NTM1KTwyNnx8cz09PTk1fHxzPT09MzYpKXI9cz49NDgmJnM8PTU3CmVsc2Ugcj0h
+MAppZighcilicmVha319cT1jLnN1YnN0cmluZyhiLG4pCmlmKGUpe3Q9YS51CnA9YS5lCmlmKHAuej09
+PTEwKXA9cC5RCm89SC5Rbyh0LHAuUSlbcV0KaWYobz09bnVsbClILnZoKCdObyAiJytxKyciIGluICIn
+K0gubUQocCkrJyInKQpkLnB1c2goSC5jRSh0LHAsbykpfWVsc2UgZC5wdXNoKHEpCnJldHVybiBufSwK
+STpmdW5jdGlvbihhLGIpe3ZhciB0PWIucG9wKCkKaWYoMD09PXQpe2IucHVzaChILm0oYS51LDEsIjAm
+IikpCnJldHVybn1pZigxPT09dCl7Yi5wdXNoKEgubShhLnUsNCwiMSYiKSkKcmV0dXJufXRocm93IEgu
+YihQLmhWKCJVbmV4cGVjdGVkIGV4dGVuZGVkIG9wZXJhdGlvbiAiK0guZCh0KSkpfSwKSzpmdW5jdGlv
+bihhLGIsYyl7aWYodHlwZW9mIGM9PSJzdHJpbmciKXJldHVybiBILkooYSxjLGEuc0VBKQplbHNlIGlm
+KHR5cGVvZiBjPT0ibnVtYmVyIilyZXR1cm4gSC5UVihhLGIsYykKZWxzZSByZXR1cm4gY30sCnI6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9MDt0PHM7Kyt0KWNbdF09SC5LKGEsYixj
+W3RdKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9MTt0PHM7dCs9Milj
+W3RdPUguSyhhLGIsY1t0XSl9LApUVjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPWIuegppZihyPT09
+MTApe2lmKGM9PT0wKXJldHVybiBiLlEKdD1iLmNoCnM9dC5sZW5ndGgKaWYoYzw9cylyZXR1cm4gdFtj
+LTFdCmMtPXMKYj1iLlEKcj1iLnp9ZWxzZSBpZihjPT09MClyZXR1cm4gYgppZihyIT09OSl0aHJvdyBI
+LmIoUC5oVigiSW5kZXhlZCBiYXNlIG11c3QgYmUgYW4gaW50ZXJmYWNlIHR5cGUiKSkKdD1iLmNoCmlm
+KGM8PXQubGVuZ3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBm
+b3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbSxs
+LGsKaWYoYj09PWQpcmV0dXJuITAKaWYoSC5jYyhkKSlyZXR1cm4hMAp0PWIuegppZih0PT09NClyZXR1
+cm4hMAppZihILmNjKGIpKXJldHVybiExCmlmKGI9PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylp
+ZihILldlKGEsY1tiLlFdLGMsZCxlKSlyZXR1cm4hMApyPWQuegppZih0PT09NilyZXR1cm4gSC5XZShh
+LGIuUSxjLGQsZSkKaWYocj09PTYpe3E9ZC5RCnJldHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgp
+e2lmKCFILldlKGEsYi5RLGMsZCxlKSlyZXR1cm4hMQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQs
+ZSl9aWYodD09PTcpe3E9SC5XZShhLGIuUSxjLGQsZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2Uo
+YSxiLGMsZC5RLGUpKXJldHVybiEwCnJldHVybiBILldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09
+Nyl7cT1ILldlKGEsYixjLGQuUSxlKQpyZXR1cm4gcX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCgh
+cXx8dD09PTEyKSYmZD09PXUuWilyZXR1cm4hMAppZihyPT09MTIpe2lmKGI9PT11LmcpcmV0dXJuITAK
+aWYodCE9PTEyKXJldHVybiExCnA9Yi5jaApvPWQuY2gKbj1wLmxlbmd0aAppZihuIT09by5sZW5ndGgp
+cmV0dXJuITEKZm9yKHE9dS5hdixtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQpxLmIobCkKcS5iKGsp
+CmlmKCFILldlKGEsbCxjLGssZSl8fCFILldlKGEsayxlLGwsYykpcmV0dXJuITF9Yz1jPT1udWxsP3A6
+cC5jb25jYXQoYykKZT1lPT1udWxsP286by5jb25jYXQoZSkKcmV0dXJuIEguYk8oYSxiLlEsYyxkLlEs
+ZSl9aWYocj09PTExKXtpZihiPT09dS5nKXJldHVybiEwCmlmKHEpcmV0dXJuITEKcmV0dXJuIEguYk8o
+YSxiLGMsZCxlKX1pZih0PT09OSl7aWYociE9PTkpcmV0dXJuITEKcmV0dXJuIEgucEcoYSxiLGMsZCxl
+KX1yZXR1cm4hMX0sCmJPOmZ1bmN0aW9uKGEwLGExLGEyLGEzLGE0KXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnLGYsZSxkLGMsYixhCmlmKCFILldlKGEwLGExLlEsYTIsYTMuUSxhNCkpcmV0dXJu
+ITEKdD1hMS5jaApzPWEzLmNoCnI9dC5hCnE9cy5hCnA9ci5sZW5ndGgKbz1xLmxlbmd0aAppZihwPm8p
+cmV0dXJuITEKbj1vLXAKbT10LmIKbD1zLmIKaz1tLmxlbmd0aApqPWwubGVuZ3RoCmlmKHArazxvK2op
+cmV0dXJuITEKZm9yKGk9MDtpPHA7KytpKXtoPXJbaV0KaWYoIUguV2UoYTAscVtpXSxhNCxoLGEyKSly
+ZXR1cm4hMX1mb3IoaT0wO2k8bjsrK2kpe2g9bVtpXQppZighSC5XZShhMCxxW3AraV0sYTQsaCxhMikp
+cmV0dXJuITF9Zm9yKGk9MDtpPGo7KytpKXtoPW1bbitpXQppZighSC5XZShhMCxsW2ldLGE0LGgsYTIp
+KXJldHVybiExfWc9dC5jCmY9cy5jCmU9Zy5sZW5ndGgKZD1mLmxlbmd0aApmb3IoaT0wLGM9MDtjPGQ7
+Yys9Mil7Yj1mW2NdCmRve2lmKGk+PWUpcmV0dXJuITEKYT1nW2ldCmkrPTJ9d2hpbGUoYTxiKQppZihi
+PGEpcmV0dXJuITEKaD1nW2ktMV0KaWYoIUguV2UoYTAsZltjKzFdLGE0LGgsYTIpKXJldHVybiExfXJl
+dHVybiEwfSwKcEc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9Yi5RLGs9
+ZC5RCmlmKGw9PT1rKXt0PWIuY2gKcz1kLmNoCnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtwPXRb
+cV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8sZSkpcmV0dXJuITF9cmV0dXJuITB9bj1ILlFvKGEsbCkK
+aWYobj09bnVsbClyZXR1cm4hMQptPW5ba10KaWYobT09bnVsbClyZXR1cm4hMQpyPW0ubGVuZ3RoCnM9
+ZC5jaApmb3IocT0wO3E8cjsrK3EpaWYoIUguV2UoYSxILmNFKGEsYixtW3FdKSxjLHNbcV0sZSkpcmV0
+dXJuITEKcmV0dXJuITB9LApjYzpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9PT11LkspcmV0dXJuITAK
+dD1hLnoKaWYodCE9PTIpaWYodCE9PTMpaWYodCE9PTQpaWYodCE9PTUpcz10PT09OCYmSC5jYyhhLlEp
+CmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCkl4OmZ1bmN0
+aW9uKGEsYil7dmFyIHQscyxyPU9iamVjdC5rZXlzKGIpLHE9ci5sZW5ndGgKZm9yKHQ9MDt0PHE7Kyt0
+KXtzPXJbdF0KYVtzXT1iW3NdfX0sCkpjOmZ1bmN0aW9uIEpjKGEsYixjKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8ueT1fLng9Xy5kPW51bGwKXy56PTAKXy5kYj1fLmN5PV8uY3g9Xy5jaD1fLlE9
+bnVsbH0sCkc6ZnVuY3Rpb24gRygpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlv
+biB1OSgpe30sCmh6OmZ1bmN0aW9uIGh6KGEpe3RoaXMuYT1hfSwKaU06ZnVuY3Rpb24gaU0oYSl7dGhp
+cy5hPWF9LApSOTpmdW5jdGlvbihhKXtyZXR1cm4gdS5kLmMoYSl8fHUuQi5jKGEpfHx1LmR6LmMoYSl8
+fHUuSS5jKGEpfHx1LkEuYyhhKXx8dS5nNC5jKGEpfHx1LmcyLmMoYSl9LApKZzpmdW5jdGlvbihhKXty
+ZXR1cm4gdi5tYW5nbGVkR2xvYmFsTmFtZXNbYV19fSxKPXsKUXU6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0
+dXJue2k6YSxwOmIsZTpjLHg6ZH19LAprczpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPWFbdi5kaXNw
+YXRjaFByb3BlcnR5TmFtZV0KaWYocD09bnVsbClpZigkLkJ2PT1udWxsKXtILlhEKCkKcD1hW3YuZGlz
+cGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCExPT09dClyZXR1cm4gcC5pCmlm
+KCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT09cylyZXR1cm4g
+cC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAuU1koIlJldHVybiBpbnRlcmNlcHRvciBmb3IgIitILmQo
+dChhLHApKSkpfXI9YS5jb25zdHJ1Y3RvcgpxPXI9PW51bGw/bnVsbDpyWyQuVU4oKV0KaWYocSE9bnVs
+bClyZXR1cm4gcQpxPUgudzMoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0eXBlb2YgYT09ImZ1bmN0
+aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT1udWxsKXJldHVy
+biBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiByPT0iZnVu
+Y3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLlVOKCkse3ZhbHVlOkMudkIsZW51bWVyYWJs
+ZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJu
+IEMudkJ9LApRaTpmdW5jdGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRF
+KGEsMCw0Mjk0OTY3Mjk1LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9
+LApweTpmdW5jdGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpKX0sCkVwOmZ1
+bmN0aW9uKGEpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CnJldHVybiBhfSwKekM6ZnVuY3Rpb24oYSl7YS5m
+aXhlZCRsZW5ndGg9QXJyYXkKYS5pbW11dGFibGUkbGlzdD1BcnJheQpyZXR1cm4gYX0sCkdhOmZ1bmN0
+aW9uKGEpe2lmKGE8MjU2KXN3aXRjaChhKXtjYXNlIDk6Y2FzZSAxMDpjYXNlIDExOmNhc2UgMTI6Y2Fz
+ZSAxMzpjYXNlIDMyOmNhc2UgMTMzOmNhc2UgMTYwOnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9c3dp
+dGNoKGEpe2Nhc2UgNTc2MDpjYXNlIDgxOTI6Y2FzZSA4MTkzOmNhc2UgODE5NDpjYXNlIDgxOTU6Y2Fz
+ZSA4MTk2OmNhc2UgODE5NzpjYXNlIDgxOTg6Y2FzZSA4MTk5OmNhc2UgODIwMDpjYXNlIDgyMDE6Y2Fz
+ZSA4MjAyOmNhc2UgODIzMjpjYXNlIDgyMzM6Y2FzZSA4MjM5OmNhc2UgODI4NzpjYXNlIDEyMjg4OmNh
+c2UgNjUyNzk6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX19LAptbTpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMKZm9yKHQ9YS5sZW5ndGg7Yjx0Oyl7cz1DLnhCLlcoYSxiKQppZihzIT09MzImJnMhPT0xMyYmIUou
+R2EocykpYnJlYWs7KytifXJldHVybiBifSwKYzE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmZvcig7Yj4w
+O2I9dCl7dD1iLTEKcz1DLnhCLm0oYSx0KQppZihzIT09MzImJnMhPT0xMyYmIUouR2EocykpYnJlYWt9
+cmV0dXJuIGJ9LApSRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVy
+biBhfWlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApUSjpmdW5jdGlv
+bihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJvdG90eXBlCmlmKHR5cGVvZiBh
+PT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNv
+bnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3Qi
+KXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYo
+YSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sClU2OmZ1bmN0aW9uKGEpe2lm
+KHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4g
+YQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEh
+PSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0
+dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sCmlhOmZ1bmN0
+aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoTWF0aC5mbG9vcihhKT09YSlyZXR1cm4gSi51
+ci5wcm90b3R5cGUKcmV0dXJuIEouVkEucHJvdG90eXBlfWlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1
+cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gSi5ZRS5wcm90b3R5cGUKaWYodHlwZW9m
+IGE9PSJib29sZWFuIilyZXR1cm4gSi55RS5wcm90b3R5cGUKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkp
+cmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJm
+dW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLmsp
+cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmlu
+ZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNl
+b2YgUC5rKSlyZXR1cm4gSi5rZC5wcm90b3R5cGUKcmV0dXJuIGF9LAp3MTpmdW5jdGlvbihhKXtpZihh
+PT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlw
+ZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1
+LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5rKXJldHVybiBhCnJldHVybiBKLmtz
+KGEpfSwKQ006ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouUkUoYSkuZHUoYSxiLGMsZCl9LApGTDpm
+dW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVy
+biBKLncxKGEpLkUoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdtVyhhKX0sCkht
+OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+dzEoYSkuZ2t6KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4g
+Si5SRShhKS53ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9
+LApRejpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7
+aWYoYT09bnVsbClyZXR1cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51
+bGwmJmE9PT1iCnJldHVybiBKLmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5y
+WShhKS5iUyhhKX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBh
+PT0ibnVtYmVyIiYmdHlwZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChh
+LGIpfSwKY0g6ZnVuY3Rpb24oYSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXty
+ZXR1cm4gSi5SRShhKS5nUChhKX0sCmRaOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLlJFKGEpLk9u
+KGEsYixjLGQpfSwKZGc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9
+LApkaDpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5GRihhKX0sCmhmOmZ1bmN0aW9uKGEpe3JldHVy
+biBKLmlhKGEpLmdpTyhhKX0sCmh3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVGMoYSxiKX0s
+CmlnOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdRZyhhKX0sCmo6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouaWEoYSkudyhhKX0sCmw1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouUkUoYSkuc2hmKGEsYil9LAps
+ZDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuTmooYSxiLGMpfSwKcTA6ZnVuY3Rpb24oYSxi
+LGMpe3JldHVybiBKLnJZKGEpLlFpKGEsYixjKX0sCnFGOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEp
+LmdWbChhKX0sCnRIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5SRShhKS5wayhhLGIsYyl9LAp3Mjpm
+dW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiPT09Im51bWJlciIpaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXl8
+fHR5cGVvZiBhPT0ic3RyaW5nInx8SC53VihhLGFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV0pKWlmKGI+
+Pj4wPT09YiYmYjxhLmxlbmd0aClyZXR1cm4gYVtiXQpyZXR1cm4gSi5VNihhKS5xKGEsYil9LAp6bDpm
+dW5jdGlvbihhLGIpe3JldHVybiBKLlU2KGEpLnRnKGEsYil9LAp2QjpmdW5jdGlvbiB2Qigpe30sCnlF
+OmZ1bmN0aW9uIHlFKCl7fSwKWUU6ZnVuY3Rpb24gWUUoKXt9LApNRjpmdW5jdGlvbiBNRigpe30sCmlD
+OmZ1bmN0aW9uIGlDKCl7fSwKa2Q6ZnVuY3Rpb24ga2QoKXt9LApjNTpmdW5jdGlvbiBjNSgpe30sCmpk
+OmZ1bmN0aW9uIGpkKGEpe3RoaXMuJHRpPWF9LApQbzpmdW5jdGlvbiBQbyhhKXt0aGlzLiR0aT1hfSwK
+bTE6ZnVuY3Rpb24gbTEoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwK
+Xy4kdGk9Y30sCnFJOmZ1bmN0aW9uIHFJKCl7fSwKdXI6ZnVuY3Rpb24gdXIoKXt9LApWQTpmdW5jdGlv
+biBWQSgpe30sCkRyOmZ1bmN0aW9uIERyKCl7fX0sUD17Ck9qOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXt9
+CmlmKHNlbGYuc2NoZWR1bGVJbW1lZGlhdGUhPW51bGwpcmV0dXJuIFAuRVgoKQppZihzZWxmLk11dGF0
+aW9uT2JzZXJ2ZXIhPW51bGwmJnNlbGYuZG9jdW1lbnQhPW51bGwpe3Q9c2VsZi5kb2N1bWVudC5jcmVh
+dGVFbGVtZW50KCJkaXYiKQpzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpCnIuYT1u
+dWxsCm5ldyBzZWxmLk11dGF0aW9uT2JzZXJ2ZXIoSC50UihuZXcgUC50aChyKSwxKSkub2JzZXJ2ZSh0
+LHtjaGlsZExpc3Q6dHJ1ZX0pCnJldHVybiBuZXcgUC5oYShyLHQscyl9ZWxzZSBpZihzZWxmLnNldElt
+bWVkaWF0ZSE9bnVsbClyZXR1cm4gUC55dCgpCnJldHVybiBQLnFXKCl9LApaVjpmdW5jdGlvbihhKXtz
+ZWxmLnNjaGVkdWxlSW1tZWRpYXRlKEgudFIobmV3IFAuVnModS5NLmIoYSkpLDApKX0sCm9BOmZ1bmN0
+aW9uKGEpe3NlbGYuc2V0SW1tZWRpYXRlKEgudFIobmV3IFAuRnQodS5NLmIoYSkpLDApKX0sCkJ6OmZ1
+bmN0aW9uKGEpe3UuTS5iKGEpClAuUU4oMCxhKX0sClFOOmZ1bmN0aW9uKGEsYil7dmFyIHQ9bmV3IFAu
+VzMoKQp0LkNZKGEsYikKcmV0dXJuIHR9LApGWDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuaWgobmV3
+IFAudnMoJC5YMyxhLkMoInZzPDA+IikpLGEuQygiaWg8MD4iKSl9LApESTpmdW5jdGlvbihhLGIpe2Eu
+JDIoMCxudWxsKQpiLmI9ITAKcmV0dXJuIGIuYX0sCmpROmZ1bmN0aW9uKGEsYil7UC5KZShhLGIpfSwK
+eUM6ZnVuY3Rpb24oYSxiKXtiLmFNKDAsYSl9LApmMzpmdW5jdGlvbihhLGIpe2IudzAoSC5SdShhKSxI
+LnRzKGEpKX0sCkplOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPW5ldyBQLldNKGIpLHE9bmV3IFAuU1go
+YikKaWYoYSBpbnN0YW5jZW9mIFAudnMpYS5RZChyLHEsdS56KQplbHNle3Q9dS56CmlmKHUuYy5jKGEp
+KWEuU3EocixxLHQpCmVsc2V7cz1uZXcgUC52cygkLlgzLHUuXykKcy5hPTQKcy5jPWEKcy5RZChyLG51
+bGwsdCl9fX0sCmx6OmZ1bmN0aW9uKGEpe3ZhciB0PWZ1bmN0aW9uKGIsYyl7cmV0dXJuIGZ1bmN0aW9u
+KGQsZSl7d2hpbGUodHJ1ZSl0cnl7YihkLGUpCmJyZWFrfWNhdGNoKHMpe2U9cwpkPWN9fX0oYSwxKQpy
+ZXR1cm4gJC5YMy5MaihuZXcgUC5Hcyh0KSx1LlAsdS5lZyx1LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24o
+YSl7cmV0dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChh
+LGIuQygicTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpiLmE9MQp0cnl7YS5TcShu
+ZXcgUC5wVihiKSxuZXcgUC5VNyhiKSx1LlApfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5y
+YihuZXcgUC52cihiLHQscykpfX0sCkE5OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PXUuXztz
+PWEuYSxzPT09MjspYT10LmIoYS5jKQppZihzPj00KXtyPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5I
+WihiLHIpfWVsc2V7cj11LnguYihiLmMpCmIuYT0yCmIuYz1hCmEualEocil9fSwKSFo6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1udWxsLGQ9e30sYz1kLmE9YQpm
+b3IodD11Lm4scz11Lngscj11LmM7ITA7KXtxPXt9CnA9Yy5hPT09OAppZihiPT1udWxsKXtpZihwKXtv
+PXQuYihjLmMpClAuTDIoZSxlLGMuYixvLmEsby5iKX1yZXR1cm59Zm9yKDtuPWIuYSxuIT1udWxsO2I9
+bil7Yi5hPW51bGwKUC5IWihkLmEsYil9Yz1kLmEKbT1jLmMKcS5hPXAKcS5iPW0KbD0hcAppZihsKXtr
+PWIuYwprPShrJjEpIT09MHx8KGsmMTUpPT09OH1lbHNlIGs9ITAKaWYoayl7az1iLmIKaj1rLmIKaWYo
+cCl7aT1jLmI9PT1qCmk9IShpfHxpKX1lbHNlIGk9ITEKaWYoaSl7dC5iKG0pClAuTDIoZSxlLGMuYixt
+LmEsbS5iKQpyZXR1cm59aD0kLlgzCmlmKGghPT1qKSQuWDM9agplbHNlIGg9ZQpjPWIuYwppZigoYyYx
+NSk9PT04KW5ldyBQLlJUKGQscSxiLHApLiQwKCkKZWxzZSBpZihsKXtpZigoYyYxKSE9PTApbmV3IFAu
+cnEocSxiLG0pLiQwKCl9ZWxzZSBpZigoYyYyKSE9PTApbmV3IFAuUlcoZCxxLGIpLiQwKCkKaWYoaCE9
+bnVsbCkkLlgzPWgKYz1xLmIKaWYoci5jKGMpKXtpZihjLmE+PTQpe2c9cy5iKGsuYykKay5jPW51bGwK
+Yj1rLk44KGcpCmsuYT1jLmEKay5jPWMuYwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1
+cm59fWY9Yi5iCmc9cy5iKGYuYykKZi5jPW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtm
+LiR0aS5kLmIobCkKZi5hPTQKZi5jPWx9ZWxzZXt0LmIobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0s
+ClZIOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYodS5GLmMoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUu
+bCkKdD11LnkKaWYodC5jKGEpKXJldHVybiB0LmIoYSkKdGhyb3cgSC5iKFAuTDMoYSwib25FcnJvciIs
+IkVycm9yIGhhbmRsZXIgbXVzdCBhY2NlcHQgb25lIE9iamVjdCBvciBvbmUgT2JqZWN0IGFuZCBhIFN0
+YWNrVHJhY2UgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJuIGEgYSB2YWxpZCByZXN1bHQiKSl9LApwdTpm
+dW5jdGlvbigpe3ZhciB0LHMKZm9yKDt0PSQuUzYsdCE9bnVsbDspeyQubWc9bnVsbApzPXQuYgokLlM2
+PXMKaWYocz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRy
+eXtQLnB1KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQ
+LlVJKCkpfX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpCmlmKCQuUzY9PW51bGwpeyQu
+UzY9JC5rOD10CmlmKCEkLlVEKSQudXQoKS4kMShQLlVJKCkpfWVsc2UgJC5rOD0kLms4LmI9dH0sCnJS
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMscj0kLlM2CmlmKHI9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJl
+dHVybn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cgokLlM2PSQubWc9dH1lbHNl
+e3QuYj1zLmIKJC5tZz1zLmI9dAppZih0LmI9PW51bGwpJC5rOD10fX0sCnJiOmZ1bmN0aW9uKGEpe3Zh
+ciB0PW51bGwscz0kLlgzCmlmKEMuTlU9PT1zKXtQLlRrKHQsdCxDLk5VLGEpCnJldHVybn1QLlRrKHQs
+dCxzLHUuTS5iKHMuR1koYSkpKX0sClF3OmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClILnZoKFAuRWUo
+InN0cmVhbSIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sCkwyOmZ1bmN0aW9uKGEsYixj
+LGQsZSl7dmFyIHQ9e30KdC5hPWQKUC5yUihuZXcgUC5wSyh0LGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixj
+LGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1k
+LiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKeXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7
+dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQxKGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShl
+KQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7
+dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQyKGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQy
+KGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKVGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQK
+dS5NLmIoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5l
+VyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3Ro
+aXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpm
+dW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5i
+PSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNY
+KGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShh
+LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhp
+cy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlv
+biBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3Zh
+ciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0
+aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVu
+Y3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEp
+e3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1j
+fSwKckg6ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEs
+Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
+PWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
+Cl8uYz1jCl8uZD1kfSwKalo6ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShh
+LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVzpmdW5jdGlvbiBSVyhhLGIsYyl7dGhp
+cy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApPTTpmdW5jdGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9
+bnVsbH0sCnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVuY3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCnVPOmZ1bmN0aW9uIHVPKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBN
+Tygpe30sCmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVuY3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCkN3
+OmZ1bmN0aW9uIEN3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBL
+OmZ1bmN0aW9uIHBLKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApKaTpmdW5jdGlvbiBKaSgpe30sCmhq
+OmZ1bmN0aW9uIGhqKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClZwOmZ1bmN0aW9u
+IFZwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApPUjpmdW5jdGlvbiBPUihhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy5jPWN9LApFRjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGIuQygiQDwwPiIpLktx
+KGMpLkMoIkZvPDEsMj4iKS5iKEguQjcoYSxuZXcgSC5ONShiLkMoIkA8MD4iKS5LcShjKS5DKCJONTwx
+LDI+IikpKSl9LApGbDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5ONShhLkMoIkA8MD4iKS5LcShi
+KS5DKCJONTwxLDI+IikpfSwKTHM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmI2KGEuQygiYjY8MD4i
+KSl9LApUMjpmdW5jdGlvbigpe3ZhciB0PU9iamVjdC5jcmVhdGUobnVsbCkKdFsiPG5vbi1pZGVudGlm
+aWVyLWtleT4iXT10CmRlbGV0ZSB0WyI8bm9uLWlkZW50aWZpZXIta2V5PiJdCnJldHVybiB0fSwKcmo6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW5ldyBQLmxtKGEsYixjLkMoImxtPDA+IikpCnQuYz1hLmUKcmV0
+dXJuIHR9LApFUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscwppZihQLmhCKGEpKXtpZihiPT09IigiJiZj
+PT09IikiKXJldHVybiIoLi4uKSIKcmV0dXJuIGIrIi4uLiIrY310PUguVk0oW10sdS5zKQpDLk5tLmko
+JC54ZyxhKQp0cnl7UC5WcihhLHQpfWZpbmFsbHl7aWYoMD49JC54Zy5sZW5ndGgpcmV0dXJuIEguT0go
+JC54ZywtMSkKJC54Zy5wb3AoKX1zPVAudmcoYix1LlIuYih0KSwiLCAiKStjCnJldHVybiBzLmNoYXJD
+b2RlQXQoMCk9PTA/czpzfSwKV0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1
+cm4gYisiLi4uIitjCnQ9bmV3IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3M9dApzLmE9UC52Zyhz
+LmEsYSwiLCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQu
+eGcucG9wKCl9dC5hKz1jCnM9dC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKaEI6ZnVu
+Y3Rpb24oYSl7dmFyIHQscwpmb3IodD0kLnhnLmxlbmd0aCxzPTA7czx0OysrcylpZihhPT09JC54Z1tz
+XSlyZXR1cm4hMApyZXR1cm4hMX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbT1h
+LmdreihhKSxsPTAsaz0wCndoaWxlKCEwKXtpZighKGw8ODB8fGs8MykpYnJlYWsKaWYoIW0uRigpKXJl
+dHVybgp0PUguZChtLmdsKCkpCkMuTm0uaShiLHQpCmwrPXQubGVuZ3RoKzI7KytrfWlmKCFtLkYoKSl7
+aWYoazw9NSlyZXR1cm4KaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcz1iLnBvcCgpCmlm
+KDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKX1lbHNle3E9bS5nbCgpOysrawpp
+ZighbS5GKCkpe2lmKGs8PTQpe0MuTm0uaShiLEguZChxKSkKcmV0dXJufXM9SC5kKHEpCmlmKDA+PWIu
+bGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKQpsKz1zLmxlbmd0aCsyfWVsc2V7cD1tLmds
+KCk7KytrCmZvcig7bS5GKCk7cT1wLHA9byl7bz1tLmdsKCk7KytrCmlmKGs+MTAwKXt3aGlsZSghMCl7
+aWYoIShsPjc1JiZrPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmwtPWIu
+cG9wKCkubGVuZ3RoKzI7LS1rfUMuTm0uaShiLCIuLi4iKQpyZXR1cm59fXI9SC5kKHEpCnM9SC5kKHAp
+CmwrPXMubGVuZ3RoK3IubGVuZ3RoKzR9fWlmKGs+Yi5sZW5ndGgrMil7bCs9NQpuPSIuLi4ifWVsc2Ug
+bj1udWxsCndoaWxlKCEwKXtpZighKGw+ODAmJmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3Ro
+KXJldHVybiBILk9IKGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIu
+Li4ifX1pZihuIT1udWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDth
+Lmxlbmd0aD09PXR8fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmIoYVtzXSkpCnJldHVybiByfSwKbk86
+ZnVuY3Rpb24oYSl7dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5Sbigi
+IikKdHJ5e0MuTm0uaSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0
+LmErPSJ9In1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcu
+cG9wKCl9cz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApiNjpmdW5jdGlvbiBiNihh
+KXt2YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwK
+Ym46ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEKdGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24g
+bG0oYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpm
+dW5jdGlvbiBtVygpe30sCkxVOmZ1bmN0aW9uIExVKCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpm
+dW5jdGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9uIHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpm
+dW5jdGlvbiBZaygpe30sCnlROmZ1bmN0aW9uIHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1Ao
+KXt9LApQbjpmdW5jdGlvbiBQbigpe30sCkdqOmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4k
+dGk9Yn0sCmxmOmZ1bmN0aW9uIGxmKCl7fSwKVmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBY
+digpe30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwKVEM6ZnVuY3Rpb24gVEMoKXt9LApSVTpmdW5jdGlvbiBS
+VSgpe30sCkJTOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRo
+cm93IEguYihILnRMKGEpKQp0PW51bGwKdHJ5e3Q9SlNPTi5wYXJzZShhKX1jYXRjaChyKXtzPUguUnUo
+cikKcT1QLnJyKFN0cmluZyhzKSxudWxsLG51bGwpCnRocm93IEguYihxKX1xPVAuUWUodCkKcmV0dXJu
+IHF9LApRZTpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKHR5cGVvZiBh
+IT0ib2JqZWN0IilyZXR1cm4gYQppZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkhPT1BcnJheS5wcm90
+b3R5cGUpcmV0dXJuIG5ldyBQLnV3KGEsT2JqZWN0LmNyZWF0ZShudWxsKSkKZm9yKHQ9MDt0PGEubGVu
+Z3RoOysrdClhW3RdPVAuUWUoYVt0XSkKcmV0dXJuIGF9LApreTpmdW5jdGlvbihhLGIsYyxkKXtpZihi
+IGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gUC5SUCghMSxiLGMsZCkKcmV0dXJuIG51bGx9LApS
+UDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHI9JC5yZigpCmlmKHI9PW51bGwpcmV0dXJuIG51bGwK
+dD0wPT09YwppZih0JiYhMClyZXR1cm4gUC5PUShyLGIpCnM9Yi5sZW5ndGgKZD1QLmpCKGMsZCxzKQpp
+Zih0JiZkPT09cylyZXR1cm4gUC5PUShyLGIpCnJldHVybiBQLk9RKHIsYi5zdWJhcnJheShjLGQpKX0s
+Ck9ROmZ1bmN0aW9uKGEsYil7aWYoUC5CZShiKSlyZXR1cm4gbnVsbApyZXR1cm4gUC5KaChhLGIpfSwK
+Smg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRyeXt0PWEuZGVjb2RlKGIpCnJldHVybiB0fWNhdGNoKHMp
+e0guUnUocyl9cmV0dXJuIG51bGx9LApCZTpmdW5jdGlvbihhKXt2YXIgdCxzPWEubGVuZ3RoLTIKZm9y
+KHQ9MDt0PHM7Kyt0KWlmKGFbdF09PT0yMzcpaWYoKGFbdCsxXSYyMjQpPT09MTYwKXJldHVybiEwCnJl
+dHVybiExfSwKV0k6ZnVuY3Rpb24oKXt2YXIgdCxzCnRyeXt0PW5ldyBUZXh0RGVjb2RlcigidXRmLTgi
+LHtmYXRhbDp0cnVlfSkKcmV0dXJuIHR9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gbnVsbH0sCmNQOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9Si5VNihhKSxzPWI7czxjOysrcyl7cj10LnEoYSxz
+KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLnpNKCkKaWYoKHImMTI3KSE9PXIpcmV0dXJu
+IHMtYn1yZXR1cm4gYy1ifSwKeE06ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2lmKEMuam4uelkoZiw0KSE9
+PTApdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIHBhZGRlZCBsZW5ndGggbXVz
+dCBiZSBtdWx0aXBsZSBvZiBmb3VyLCBpcyAiK2YsYSxjKSkKaWYoZCtlIT09Zil0aHJvdyBILmIoUC5y
+cigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgJz0nIG5vdCBhdCB0aGUgZW5kIixhLGIpKQppZihlPjIp
+dGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIG1vcmUgdGhhbiB0d28gJz0nIGNo
+YXJhY3RlcnMiLGEsYikpfSwKdXc6ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlz
+LmM9bnVsbH0sCmk4OmZ1bmN0aW9uIGk4KGEpe3RoaXMuYT1hfSwKQ1Y6ZnVuY3Rpb24gQ1YoKXt9LApV
+ODpmdW5jdGlvbiBVOCgpe30sClVrOmZ1bmN0aW9uIFVrKCl7fSwKd0k6ZnVuY3Rpb24gd0koKXt9LApa
+aTpmdW5jdGlvbiBaaSgpe30sCmJ5OmZ1bmN0aW9uIGJ5KCl7fSwKTXg6ZnVuY3Rpb24gTXgoYSl7dGhp
+cy5hPWF9LAp1NTpmdW5jdGlvbiB1NSgpe30sCkUzOmZ1bmN0aW9uIEUzKCl7fSwKUnc6ZnVuY3Rpb24g
+UncoYSl7dGhpcy5iPTAKdGhpcy5jPWF9LApHWTpmdW5jdGlvbiBHWShhKXt0aGlzLmE9YX0sCmJ6OmZ1
+bmN0aW9uIGJ6KGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9ITAKXy5mPV8uZT1fLmQ9MH0s
+ClFBOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkhwKGEsYykKaWYodCE9bnVsbClyZXR1cm4gdAppZihi
+IT1udWxsKXJldHVybiBiLiQxKGEpCnRocm93IEguYihQLnJyKGEsbnVsbCxudWxsKSl9LApGOmZ1bmN0
+aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLncoMCkKcmV0dXJuIkluc3RhbmNlIG9m
+ICciK0guZChILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUouUWkoYSxjKQpp
+ZihhIT09MCYmITApZm9yKHQ9MDt0PHMubGVuZ3RoOysrdClDLk5tLlkocyx0LGIpCnJldHVybiBzfSwK
+Q0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9SC5WTShbXSxjLkMoImpkPDA+IikpCmZvcih0PUouSVQo
+YSk7dC5GKCk7KUMuTm0uaShzLGMuYih0LmdsKCkpKQppZihiKXJldHVybiBzCnJldHVybiBjLkMoInpN
+PDA+IikuYihKLkVwKHMpKX0sCkFGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGIuQygiek08MD4iKS5iKEou
+ekMoUC5DSChhLCExLGIpKSl9LApITTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoQXJyYXkuaXNBcnJh
+eShhKSl7dS50LmIoYSkKdD1hLmxlbmd0aApjPVAuakIoYixjLHQpCnJldHVybiBILmVUKGI+MHx8Yzx0
+P0MuTm0uRDYoYSxiLGMpOmEpfWlmKHUuYm0uYyhhKSlyZXR1cm4gSC5mdyhhLGIsUC5qQihiLGMsYS5s
+ZW5ndGgpKQpyZXR1cm4gUC5idyhhLGIsYyl9LApPbzpmdW5jdGlvbihhKXtyZXR1cm4gSC5MdyhhKX0s
+CmJ3OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwPW51bGwKaWYoYjwwKXRocm93IEguYihQLlRF
+KGIsMCxKLkhtKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixK
+LkhtKGEpLHAscCkpCnM9Si5JVChhKQpmb3Iocj0wO3I8YjsrK3IpaWYoIXMuRigpKXRocm93IEguYihQ
+LlRFKGIsMCxyLHAscCkpCnE9W10KaWYodClmb3IoO3MuRigpOylxLnB1c2gocy5nbCgpKQplbHNlIGZv
+cihyPWI7cjxjOysrcil7aWYoIXMuRigpKXRocm93IEguYihQLlRFKGMsYixyLHAscCkpCnEucHVzaChz
+LmdsKCkpfXJldHVybiBILmVUKHEpfSwKbnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52
+NChhLCExLCEwLCExLCExLCExKSl9LAp2ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Si5JVChiKQppZigh
+dC5GKCkpcmV0dXJuIGEKaWYoYy5sZW5ndGg9PT0wKXtkbyBhKz1ILmQodC5nbCgpKQp3aGlsZSh0LkYo
+KSl9ZWxzZXthKz1ILmQodC5nbCgpKQpmb3IoO3QuRigpOylhPWErYytILmQodC5nbCgpKX1yZXR1cm4g
+YX0sCmxyOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0
+aW9uKCl7dmFyIHQ9SC5NMCgpCmlmKHQhPW51bGwpcmV0dXJuIFAuaEsodCkKdGhyb3cgSC5iKFAuTDQo
+IidVcmkuYmFzZScgaXMgbm90IHN1cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
+LHMscixxLHAsbyxuPSIwMTIzNDU2Nzg5QUJDREVGIgppZihjPT09Qy54TSl7dD0kLno0KCkuYgppZih0
+eXBlb2YgYiE9InN0cmluZyIpSC52aChILnRMKGIpKQp0PXQudGVzdChiKX1lbHNlIHQ9ITEKaWYodCly
+ZXR1cm4gYgpILkxoKGMpLkMoIlVrLlMiKS5iKGIpCnM9Yy5nWkUoKS5XSihiKQpmb3IodD1zLmxlbmd0
+aCxyPTAscT0iIjtyPHQ7KytyKXtwPXNbcl0KaWYocDwxMjgpe289cD4+PjQKaWYobz49OClyZXR1cm4g
+SC5PSChhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQpl
+bHNlIHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hh
+ckNvZGVBdCgwKT09MD9xOnF9LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8i
+LSI6IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0x
+MClyZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEw
+MClyZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9u
+KGEpe2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApwOmZ1bmN0aW9uKGEpe2lmKHR5cGVv
+ZiBhPT0ibnVtYmVyInx8SC5sKGEpfHxudWxsPT1hKXJldHVybiBKLmooYSkKaWYodHlwZW9mIGE9PSJz
+dHJpbmciKXJldHVybiBKU09OLnN0cmluZ2lmeShhKQpyZXR1cm4gUC5GKGEpfSwKaFY6ZnVuY3Rpb24o
+YSl7cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITEsbnVs
+bCxudWxsLGEpfSwKTDM6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgUC51KCEwLGEsYixjKX0sCkVl
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51KCExLG51bGwsYSwiTXVzdCBub3QgYmUgbnVsbCIpfSwK
+eDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5iSihudWxsLG51bGwsITAsYSxiLCJWYWx1ZSBub3Qg
+aW4gcmFuZ2UiKX0sClRFOmZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIG5ldyBQLmJKKGIsYywhMCxh
+LGQsIkludmFsaWQgdmFsdWUiKX0sCndBOmZ1bmN0aW9uKGEsYixjLGQpe2lmKGE8Ynx8YT5jKXRocm93
+IEguYihQLlRFKGEsYixjLGQsbnVsbCkpfSwKakI6ZnVuY3Rpb24oYSxiLGMpe2lmKDA+YXx8YT5jKXRo
+cm93IEguYihQLlRFKGEsMCxjLCJzdGFydCIsbnVsbCkpCmlmKGIhPW51bGwpe2lmKGE+Ynx8Yj5jKXRo
+cm93IEguYihQLlRFKGIsYSxjLCJlbmQiLG51bGwpKQpyZXR1cm4gYn1yZXR1cm4gY30sCmsxOmZ1bmN0
+aW9uKGEsYil7aWYodHlwZW9mIGEhPT0ibnVtYmVyIilyZXR1cm4gYS5KKCkKaWYoYTwwKXRocm93IEgu
+YihQLlRFKGEsMCxudWxsLGIsbnVsbCkpfSwKQ2Y6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1ILlNj
+KGU9PW51bGw/Si5IbShiKTplKQpyZXR1cm4gbmV3IFAuZVkodCwhMCxhLGMsIkluZGV4IG91dCBvZiBy
+YW5nZSIpfSwKTDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnViKGEpfSwKU1k6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLmRzKGEpfSwKUFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmxqKGEpfSwKYTQ6
+ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlVWKGEpfSwKcnI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBu
+ZXcgUC5hRShhLGIsYyl9LApkSDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzPUguVk0oW10sZC5DKCJq
+ZDwwPiIpKQpDLk5tLnNBKHMsYSkKZm9yKHQ9MDt0PGE7Kyt0KUMuTm0uWShzLHQsYi4kMSh0KSkKcmV0
+dXJuIHN9LApoSzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1u
+dWxsLGQ9YS5sZW5ndGgKaWYoZD49NSl7dD0oKEouUXooYSw0KV41OCkqM3xDLnhCLlcoYSwwKV4xMDB8
+Qy54Qi5XKGEsMSleOTd8Qy54Qi5XKGEsMileMTE2fEMueEIuVyhhLDMpXjk3KT4+PjAKaWYodD09PTAp
+cmV0dXJuIFAuS0QoZDxkP0MueEIuTmooYSwwLGQpOmEsNSxlKS5nbFIoKQplbHNlIGlmKHQ9PT0zMily
+ZXR1cm4gUC5LRChDLnhCLk5qKGEsNSxkKSwwLGUpLmdsUigpfXM9bmV3IEFycmF5KDgpCnMuZml4ZWQk
+bGVuZ3RoPUFycmF5CnI9SC5WTShzLHUudCkKQy5ObS5ZKHIsMCwwKQpDLk5tLlkociwxLC0xKQpDLk5t
+LlkociwyLC0xKQpDLk5tLlkociw3LC0xKQpDLk5tLlkociwzLDApCkMuTm0uWShyLDQsMCkKQy5ObS5Z
+KHIsNSxkKQpDLk5tLlkociw2LGQpCmlmKFAuVUIoYSwwLGQsMCxyKT49MTQpQy5ObS5ZKHIsNyxkKQpx
+PXJbMV0KaWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS50QigpCmlmKHE+PTApaWYoUC5VQihh
+LDAscSwyMCxyKT09PTIwKXJbN109cQpzPXJbMl0KaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4g
+cy5oKCkKcD1zKzEKbz1yWzNdCm49cls0XQptPXJbNV0KbD1yWzZdCmlmKHR5cGVvZiBsIT09Im51bWJl
+ciIpcmV0dXJuIGwuSigpCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKaWYobDxt
+KW09bAppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPHApbj1tCmVsc2UgaWYo
+bjw9cSluPXErMQppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLkooKQppZihvPHApbz1uCnM9
+cls3XQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQprPXM8MAppZihrKWlmKHA+cSsz
+KXtqPWUKaz0hMX1lbHNle3M9bz4wCmlmKHMmJm8rMT09PW4pe2o9ZQprPSExfWVsc2V7aWYoIShtPGQm
+Jm09PT1uKzImJkoucTAoYSwiLi4iLG4pKSlpPW0+bisyJiZKLnEwKGEsIi8uLiIsbS0zKQplbHNlIGk9
+ITAKaWYoaSl7aj1lCms9ITF9ZWxzZXtpZihxPT09NClpZihKLnEwKGEsImZpbGUiLDApKXtpZihwPD0w
+KXtpZighQy54Qi5RaShhLCIvIixuKSl7aD0iZmlsZTovLy8iCnQ9M31lbHNle2g9ImZpbGU6Ly8iCnQ9
+Mn1hPWgrQy54Qi5OaihhLG4sZCkKcS09MApzPXQtMAptKz1zCmwrPXMKZD1hLmxlbmd0aApwPTcKbz03
+Cm49N31lbHNlIGlmKG49PT1tKXtnPW0rMTsrK2wKYT1DLnhCLmk3KGEsbixtLCIvIik7KytkCm09Z31q
+PSJmaWxlIn1lbHNlIGlmKEMueEIuUWkoYSwiaHR0cCIsMCkpe2lmKHMmJm8rMz09PW4mJkMueEIuUWko
+YSwiODAiLG8rMSkpe2Y9bi0zCm0tPTMKbC09MwphPUMueEIuaTcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9
+Imh0dHAifWVsc2Ugaj1lCmVsc2UgaWYocT09PTUmJkoucTAoYSwiaHR0cHMiLDApKXtpZihzJiZvKzQ9
+PT1uJiZKLnEwKGEsIjQ0MyIsbysxKSl7Zj1uLTQKbS09NApsLT00CmE9Si5kZyhhLG8sbiwiIikKZC09
+MwpuPWZ9aj0iaHR0cHMifWVsc2Ugaj1lCms9ITB9fX1lbHNlIGo9ZQppZihrKXtzPWEubGVuZ3RoCmlm
+KGQ8cyl7YT1KLmxkKGEsMCxkKQpxLT0wCnAtPTAKby09MApuLT0wCm0tPTAKbC09MH1yZXR1cm4gbmV3
+IFAuVWYoYSxxLHAsbyxuLG0sbCxqKX1yZXR1cm4gUC5qdihhLDAsZCxxLHAsbyxuLG0sbCxqKX0sCk10
+OmZ1bmN0aW9uKGEpe0gueShhKQpyZXR1cm4gUC5rdShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpm
+dW5jdGlvbihhKXt2YXIgdD11Lk4KcmV0dXJuIEMuTm0uTjAoSC5WTShhLnNwbGl0KCImIiksdS5zKSxQ
+LkZsKHQsdCksbmV3IFAubjEoQy54TSksdS5mKX0sCkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIs
+cSxwLG8sbixtPW51bGwsbD0iSVB2NCBhZGRyZXNzIHNob3VsZCBjb250YWluIGV4YWN0bHkgNCBwYXJ0
+cyIsaz0iZWFjaCBwYXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIDAuLjI1NSIsaj1uZXcgUC5jUyhhKSxp
+PW5ldyBVaW50OEFycmF5KDQpCmZvcih0PWkubGVuZ3RoLHM9YixyPXMscT0wO3M8YzsrK3Mpe3A9Qy54
+Qi5tKGEscykKaWYocCE9PTQ2KXtpZigocF40OCk+OSlqLiQyKCJpbnZhbGlkIGNoYXJhY3RlciIscyl9
+ZWxzZXtpZihxPT09MylqLiQyKGwscykKbz1QLlFBKEMueEIuTmooYSxyLHMpLG0sbSkKaWYodHlwZW9m
+IG8hPT0ibnVtYmVyIilyZXR1cm4gby5vcygpCmlmKG8+MjU1KWouJDIoayxyKQpuPXErMQppZihxPj10
+KXJldHVybiBILk9IKGkscSkKaVtxXT1vCnI9cysxCnE9bn19aWYocSE9PTMpai4kMihsLGMpCm89UC5R
+QShDLnhCLk5qKGEscixjKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQpp
+ZihvPjI1NSlqLiQyKGsscikKaWYocT49dClyZXR1cm4gSC5PSChpLHEpCmlbcV09bwpyZXR1cm4gaX0s
+CmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZD1u
+ZXcgUC5WQyhhKSxjPW5ldyBQLkpUKGQsYSkKaWYoYS5sZW5ndGg8MilkLiQxKCJhZGRyZXNzIGlzIHRv
+byBzaG9ydCIpCnQ9SC5WTShbXSx1LnQpCmZvcihzPWIscj1zLHE9ITEscD0hMTtzPGEwOysrcyl7bz1D
+LnhCLm0oYSxzKQppZihvPT09NTgpe2lmKHM9PT1iKXsrK3MKaWYoQy54Qi5tKGEscykhPT01OClkLiQy
+KCJpbnZhbGlkIHN0YXJ0IGNvbG9uLiIscykKcj1zfWlmKHM9PT1yKXtpZihxKWQuJDIoIm9ubHkgb25l
+IHdpbGRjYXJkIGA6OmAgaXMgYWxsb3dlZCIscykKQy5ObS5pKHQsLTEpCnE9ITB9ZWxzZSBDLk5tLmko
+dCxjLiQyKHIscykpCnI9cysxfWVsc2UgaWYobz09PTQ2KXA9ITB9aWYodC5sZW5ndGg9PT0wKWQuJDEo
+InRvbyBmZXcgcGFydHMiKQpuPXI9PT1hMAptPUMuTm0uZ3JaKHQpCmlmKG4mJm0hPT0tMSlkLiQyKCJl
+eHBlY3RlZCBhIHBhcnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbilpZighcClDLk5tLmkodCxjLiQy
+KHIsYTApKQplbHNle2w9UC5IaChhLHIsYTApCkMuTm0uaSh0LChsWzBdPDw4fGxbMV0pPj4+MCkKQy5O
+bS5pKHQsKGxbMl08PDh8bFszXSk+Pj4wKX1pZihxKXtpZih0Lmxlbmd0aD43KWQuJDEoImFuIGFkZHJl
+c3Mgd2l0aCBhIHdpbGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYodC5s
+ZW5ndGghPT04KWQuJDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBl
+eGFjdGx5IDggcGFydHMiKQprPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobT10Lmxlbmd0aCxqPWsubGVu
+Z3RoLGk9OS1tLHM9MCxoPTA7czxtOysrcyl7Zz10W3NdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8aTsrK2Yp
+e2lmKGg8MHx8aD49ailyZXR1cm4gSC5PSChrLGgpCmtbaF09MAplPWgrMQppZihlPj1qKXJldHVybiBI
+Lk9IKGssZSkKa1tlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJu
+IEguT0goayxoKQprW2hdPWUKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5PSChrLGUpCmtbZV09ZyYyNTUK
+aCs9Mn19cmV0dXJuIGt9LApqdjpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdCxzLHIs
+cSxwLG8sbixtPW51bGwKaWYoaj09bnVsbClpZihkPmIpaj1QLlBpKGEsYixkKQplbHNle2lmKGQ9PT1i
+KVAuUjMoYSxiLCJJbnZhbGlkIGVtcHR5IHNjaGVtZSIpCmo9IiJ9aWYoZT5iKXt0PWQrMwpzPXQ8ZT9Q
+LnpSKGEsdCxlLTEpOiIiCnI9UC5PZShhLGUsZiwhMSkKaWYodHlwZW9mIGYhPT0ibnVtYmVyIilyZXR1
+cm4gZi5oKCkKcT1mKzEKaWYodHlwZW9mIGchPT0ibnVtYmVyIilyZXR1cm4gSC5wWShnKQpwPXE8Zz9Q
+LndCKFAuUUEoSi5sZChhLHEsZyksbmV3IFAuZTEoYSxmKSxtKSxqKTptfWVsc2V7cD1tCnI9cApzPSIi
+fW89UC5rYShhLGcsaCxtLGosciE9bnVsbCkKaWYodHlwZW9mIGghPT0ibnVtYmVyIilyZXR1cm4gaC5K
+KCkKbj1oPGk/UC5sZShhLGgrMSxpLG0pOm0KcmV0dXJuIG5ldyBQLkRuKGoscyxyLHAsbyxuLGk8Yz9Q
+LnRHKGEsaSsxLGMpOm0pfSwKS0w6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxv
+CmY9UC5QaShmLDAsZj09bnVsbD8wOmYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0
+aCkKYT1QLk9lKGEsMCxhPT1udWxsPzA6YS5sZW5ndGgsITEpCnQ9UC5sZShudWxsLDAsMCxlKQpzPVAu
+dEcobnVsbCwwLDApCmQ9UC53QihkLGYpCnI9Zj09PSJmaWxlIgppZihhPT1udWxsKXE9Zy5sZW5ndGgh
+PT0wfHxkIT1udWxsfHxyCmVsc2UgcT0hMQppZihxKWE9IiIKcT1hPT1udWxsCnA9IXEKYj1QLmthKGIs
+MCxiPT1udWxsPzA6Yi5sZW5ndGgsYyxmLHApCm89Zi5sZW5ndGg9PT0wCmlmKG8mJnEmJiFDLnhCLm4o
+YiwiLyIpKWI9UC53RihiLCFvfHxwKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHEm
+JkMueEIubihiLCIvLyIpPyIiOmEsZCxiLHQscyl9LAp3SzpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAi
+KXJldHVybiA4MAppZihhPT09Imh0dHBzIilyZXR1cm4gNDQzCnJldHVybiAwfSwKUjM6ZnVuY3Rpb24o
+YSxiLGMpe3Rocm93IEguYihQLnJyKGMsYSxiKSl9LApYZDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHIscSxwLG8sbixtLGwsayxqLGk9bnVsbCxoPWIubGVuZ3RoCmlmKGghPT0wKXtyPTAKd2hpbGUoITAp
+e2lmKCEocjxoKSl7dD0iIgpzPTAKYnJlYWt9aWYoQy54Qi5XKGIscik9PT02NCl7dD1DLnhCLk5qKGIs
+MCxyKQpzPXIrMQpicmVha30rK3J9aWYoczxoJiZDLnhCLlcoYixzKT09PTkxKXtmb3IocT1zLHA9LTE7
+cTxoOysrcSl7bz1DLnhCLlcoYixxKQppZihvPT09MzcmJnA8MCl7bj1DLnhCLlFpKGIsIjI1IixxKzEp
+P3ErMjpxCnA9cQpxPW59ZWxzZSBpZihvPT09OTMpYnJlYWt9aWYocT09PWgpdGhyb3cgSC5iKFAucnIo
+IkludmFsaWQgSVB2NiBob3N0IGVudHJ5LiIsYixzKSkKbT1wPDA/cTpwClAuZWcoYixzKzEsbSk7Kytx
+CmlmKHEhPT1oJiZDLnhCLlcoYixxKSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBh
+dXRob3JpdHkiLGIscSkpfWVsc2UgcT1zCndoaWxlKCEwKXtpZighKHE8aCkpe2w9aQpicmVha31pZihD
+LnhCLlcoYixxKT09PTU4KXtrPUMueEIuRyhiLHErMSkKbD1rLmxlbmd0aCE9PTA/UC5RQShrLGksaSk6
+aQpicmVha30rK3F9aj1DLnhCLk5qKGIscyxxKX1lbHNle2w9aQpqPWwKdD0iIn1yZXR1cm4gUC5LTChq
+LGksSC5WTShjLnNwbGl0KCIvIiksdS5zKSxsLGQsYSx0KX0sCmtFOmZ1bmN0aW9uKGEsYil7Qy5ObS5L
+KGEsbmV3IFAuTlkoITEpKX0sCkhOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhh
+LGMsbnVsbCxILnQ2KGEpLmQpLHQ9bmV3IEguYTcodCx0LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+Iikp
+O3QuRigpOyl7cz10LmQKcj1QLm51KCdbIiovOjw+P1xcXFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihz
+LHIsMCkpe3Q9UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9
+fX0sCnJnOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISg2NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEy
+MgplbHNlIHQ9ITAKaWYodClyZXR1cm4KdD1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28o
+YSkpCnRocm93IEguYih0KX0sCndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikp
+cmV0dXJuIG51bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8K
+aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihiPT09YylyZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkx
+KXtpZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkhOKCkKdD1jLTEKaWYoQy54Qi5tKGEsdCkh
+PT05MylQLlIzKGEsYiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBob3N0IikKcz1iKzEK
+cj1QLnRvKGEscyx0KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLkooKQppZihyPHQpe3E9
+cisxCnA9UC5PQShhLEMueEIuUWkoYSwiMjUiLHEpP3IrMzpxLHQsIiUyNSIpfWVsc2UgcD0iIgpQLmVn
+KGEscyxyKQpyZXR1cm4gQy54Qi5OaihhLGIscikudG9Mb3dlckNhc2UoKStwKyJdIn1pZih0eXBlb2Yg
+YyE9PSJudW1iZXIiKXJldHVybiBILnBZKGMpCm89Ygpmb3IoO288YzsrK28paWYoQy54Qi5tKGEsbyk9
+PT01OCl7cj1DLnhCLlhVKGEsIiUiLGIpCmlmKCEocj49YiYmcjxjKSlyPWMKaWYocjxjKXtxPXIrMQpw
+PVAuT0EoYSxDLnhCLlFpKGEsIjI1IixxKT9yKzM6cSxjLCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLGIs
+cikKcmV0dXJuIlsiK0MueEIuTmooYSxiLHIpK3ArIl0ifXJldHVybiBQLk9MKGEsYixjKX0sCnRvOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzPUMueEIuWFUoYSwiJSIsYikKaWYocz49Yil7aWYodHlwZW9mIGMh
+PT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQp0PXM8Y31lbHNlIHQ9ITEKcmV0dXJuIHQ/czpjfSwKT0E6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9ZCE9PSIiP25ldyBQLlJuKGQp
+Om51bGwKaWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQp0PWIKcz10CnI9ITAKZm9y
+KDt0PGM7KXtxPUMueEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2KGEsdCwhMCkKbz1wPT1udWxsCmlm
+KG8mJnIpe3QrPTMKY29udGludWV9aWYoaz09bnVsbClrPW5ldyBQLlJuKCIiKQpuPWsuYSs9Qy54Qi5O
+aihhLHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJa
+b25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCmsuYT1uK3AKdCs9MwpzPXQKcj0hMH1l
+bHNle2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEguT0goQy5GMyxvKQpvPShDLkYzW29d
+JjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXtpZihyJiY2NTw9cSYmOTA+PXEpe2lmKGs9PW51
+bGwpaz1uZXcgUC5SbigiIikKaWYoczx0KXtrLmErPUMueEIuTmooYSxzLHQpCnM9dH1yPSExfSsrdH1l
+bHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7bT1DLnhCLm0oYSx0KzEpCmlmKChtJjY0NTEy
+KT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwxMHxtJjEwMjMKbD0yfWVsc2UgbD0xfWVsc2UgbD0x
+CmlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEscyx0KQprLmErPVAuelgocSkK
+dCs9bApzPXR9fX1pZihrPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpay5hKz1DLnhC
+Lk5qKGEscyxjKQpvPWsuYQpyZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0
+dXJuIEgucFkoYykKdD1iCnM9dApyPW51bGwKcT0hMApmb3IoO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYo
+cD09PTM3KXtvPVAucnYoYSx0LCEwKQpuPW89PW51bGwKaWYobiYmcSl7dCs9Mwpjb250aW51ZX1pZihy
+PT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNh
+c2UoKTptCmlmKG4pe289Qy54Qi5OaihhLHQsdCszKQprPTN9ZWxzZSBpZihvPT09IiUiKXtvPSIlMjUi
+Cms9MX1lbHNlIGs9MwpyLmE9bCtvCnQrPWsKcz10CnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NApp
+ZihuPj04KXJldHVybiBILk9IKEMuZWEsbikKbj0oQy5lYVtuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49
+ITEKaWYobil7aWYocSYmNjU8PXAmJjkwPj1wKXtpZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCmlmKHM8
+dCl7ci5hKz1DLnhCLk5qKGEscyx0KQpzPXR9cT0hMX0rK3R9ZWxzZXtpZihwPD05Myl7bj1wPj4+NApp
+ZihuPj04KXJldHVybiBILk9IKEMuYWssbikKbj0oQy5ha1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49
+ITEKaWYobilQLlIzKGEsdCwiSW52YWxpZCBjaGFyYWN0ZXIiKQplbHNle2lmKChwJjY0NTEyKT09PTU1
+Mjk2JiZ0KzE8Yyl7aj1DLnhCLm0oYSx0KzEpCmlmKChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChw
+JjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ugaz0xfWVsc2Ugaz0xCmlmKHI9PW51bGwpcj1uZXcgUC5S
+bigiIikKbT1DLnhCLk5qKGEscyx0KQpyLmErPSFxP20udG9Mb3dlckNhc2UoKTptCnIuYSs9UC56WChw
+KQp0Kz1rCnM9dH19fX1pZihyPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpe209Qy54
+Qi5OaihhLHMsYykKci5hKz0hcT9tLnRvTG93ZXJDYXNlKCk6bX1uPXIuYQpyZXR1cm4gbi5jaGFyQ29k
+ZUF0KDApPT0wP246bn0sClBpOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiPT09YylyZXR1
+cm4iIgppZighUC5FdChKLnJZKGEpLlcoYSxiKSkpUC5SMyhhLGIsIlNjaGVtZSBub3Qgc3RhcnRpbmcg
+d2l0aCBhbHBoYWJldGljIGNoYXJhY3RlciIpCmZvcih0PWIscz0hMTt0PGM7Kyt0KXtyPUMueEIuVyhh
+LHQpCmlmKHI8MTI4KXtxPXI+Pj40CmlmKHE+PTgpcmV0dXJuIEguT0goQy5tSyxxKQpxPShDLm1LW3Fd
+JjE8PChyJjE1KSkhPT0wfWVsc2UgcT0hMQppZighcSlQLlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hh
+cmFjdGVyIikKaWYoNjU8PXImJnI8PTkwKXM9ITB9YT1DLnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShz
+P2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0
+dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIK
+aWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIs
+Yyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0
+aW9uKGEsYixjLGQsZSxmKXt2YXIgdCxzPWU9PT0iZmlsZSIscj1zfHxmLHE9YT09bnVsbAppZihxJiZk
+PT1udWxsKXJldHVybiBzPyIvIjoiIgpxPSFxCmlmKHEmJmQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
+dGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQppZihxKXQ9UC5QSShhLGIsYyxDLldk
+LCEwKQplbHNle2QudG9TdHJpbmcKcT1ILnQ2KGQpCnQ9bmV3IEguQTgoZCxxLkMoInFVKDEpIikuYihu
+ZXcgUC5SWigpKSxxLkMoIkE4PDEscVU+IikpLnpWKDAsIi8iKX1pZih0Lmxlbmd0aD09PTApe2lmKHMp
+cmV0dXJuIi8ifWVsc2UgaWYociYmIUMueEIubih0LCIvIikpdD0iLyIrdApyZXR1cm4gUC5Kcih0LGUs
+Zil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Yi5sZW5ndGg9PT0wCmlmKHQmJiFjJiYhQy54Qi5u
+KGEsIi8iKSlyZXR1cm4gUC53RihhLCF0fHxjKQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEs
+YixjLGQpe3ZhciB0LHM9e30KaWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90
+aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxD
+LlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBudWxsCnQ9bmV3IFAuUm4oIiIpCnMuYT0iIgpkLksoMCxu
+ZXcgUC55NShuZXcgUC5NRShzLHQpKSkKcz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9
+LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIs
+YyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG89YisyCmlmKG8+PWEu
+bGVuZ3RoKXJldHVybiIlIgp0PUMueEIubShhLGIrMSkKcz1DLnhCLm0oYSxvKQpyPUgub28odCkKcT1I
+Lm9vKHMpCmlmKHI8MHx8cTwwKXJldHVybiIlIgpwPXIqMTYrcQppZihwPDEyNyl7bz1DLmpuLndHKHAs
+NCkKaWYobz49OClyZXR1cm4gSC5PSChDLkYzLG8pCm89KEMuRjNbb10mMTw8KHAmMTUpKSE9PTB9ZWxz
+ZSBvPSExCmlmKG8pcmV0dXJuIEguTHcoYyYmNjU8PXAmJjkwPj1wPyhwfDMyKT4+PjA6cCkKaWYodD49
+OTd8fHM+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51bGx9
+LAp6WDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbj0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYTwx
+Mjgpe3Q9bmV3IEFycmF5KDMpCnQuZml4ZWQkbGVuZ3RoPUFycmF5CnM9SC5WTSh0LHUudCkKQy5ObS5Z
+KHMsMCwzNykKQy5ObS5ZKHMsMSxDLnhCLlcobixhPj4+NCkpCkMuTm0uWShzLDIsQy54Qi5XKG4sYSYx
+NSkpfWVsc2V7aWYoYT4yMDQ3KWlmKGE+NjU1MzUpe3I9MjQwCnE9NH1lbHNle3I9MjI0CnE9M31lbHNl
+e3I9MTkyCnE9Mn10PW5ldyBBcnJheSgzKnEpCnQuZml4ZWQkbGVuZ3RoPUFycmF5CnM9SC5WTSh0LHUu
+dCkKZm9yKHA9MDstLXEscT49MDtyPTEyOCl7bz1DLmpuLmJmKGEsNipxKSY2M3xyCkMuTm0uWShzLHAs
+MzcpCkMuTm0uWShzLHArMSxDLnhCLlcobixvPj4+NCkpCkMuTm0uWShzLHArMixDLnhCLlcobixvJjE1
+KSkKcCs9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
+dD1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHQ9PW51bGw/Qy54Qi5OaihhLGIsYyk6dH0sClVsOmZ1bmN0
+aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvPW51bGwsbj0hZSxtPWIsbD1tLGs9bwp3aGlsZSgh
+MCl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5KKCkKaWYodHlwZW9mIGMhPT0ibnVtYmVy
+IilyZXR1cm4gSC5wWShjKQppZighKG08YykpYnJlYWsKYyQwOnt0PUMueEIubShhLG0pCmlmKHQ8MTI3
+KXtzPXQ+Pj40CmlmKHM+PTgpcmV0dXJuIEguT0goZCxzKQpzPShkW3NdJjE8PCh0JjE1KSkhPT0wfWVs
+c2Ugcz0hMQppZihzKSsrbQplbHNle2lmKHQ9PT0zNyl7cj1QLnJ2KGEsbSwhMSkKaWYocj09bnVsbCl7
+bSs9MwpicmVhayBjJDB9aWYoIiUiPT09cil7cj0iJTI1IgpxPTF9ZWxzZSBxPTN9ZWxzZXtpZihuKWlm
+KHQ8PTkzKXtzPXQ+Pj40CmlmKHM+PTgpcmV0dXJuIEguT0goQy5hayxzKQpzPShDLmFrW3NdJjE8PCh0
+JjE1KSkhPT0wfWVsc2Ugcz0hMQplbHNlIHM9ITEKaWYocyl7UC5SMyhhLG0sIkludmFsaWQgY2hhcmFj
+dGVyIikKcT1vCnI9cX1lbHNle2lmKCh0JjY0NTEyKT09PTU1Mjk2KXtzPW0rMQppZihzPGMpe3A9Qy54
+Qi5tKGEscykKaWYoKHAmNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzZ8KHQmMTAyMyk8PDEwfHAmMTAyMwpx
+PTJ9ZWxzZSBxPTF9ZWxzZSBxPTF9ZWxzZSBxPTEKcj1QLnpYKHQpfX1pZihrPT1udWxsKWs9bmV3IFAu
+Um4oIiIpCmsuYSs9Qy54Qi5OaihhLGwsbSkKay5hKz1ILmQocikKaWYodHlwZW9mIHEhPT0ibnVtYmVy
+IilyZXR1cm4gSC5wWShxKQptKz1xCmw9bX19fWlmKGs9PW51bGwpcmV0dXJuIG8KaWYodHlwZW9mIGwh
+PT0ibnVtYmVyIilyZXR1cm4gbC5KKCkKaWYobDxjKWsuYSs9Qy54Qi5OaihhLGwsYykKbj1rLmEKcmV0
+dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LAp5QjpmdW5jdGlvbihhKXtpZihDLnhCLm4oYSwiLiIp
+KXJldHVybiEwCnJldHVybiBDLnhCLk9ZKGEsIi8uIikhPT0tMX0sCnhlOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMscixxLHAsbyxuCmlmKCFQLnlCKGEpKXJldHVybiBhCnQ9SC5WTShbXSx1LnMpCmZvcihzPWEuc3Bs
+aXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ape289c1twXQppZihKLlJNKG8sIi4uIikp
+e249dC5sZW5ndGgKaWYobiE9PTApe2lmKDA+PW4pcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQppZih0
+Lmxlbmd0aD09PTApQy5ObS5pKHQsIiIpfXE9ITB9ZWxzZSBpZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5t
+LmkodCxvKQpxPSExfX1pZihxKUMuTm0uaSh0LCIiKQpyZXR1cm4gQy5ObS56Vih0LCIvIil9LAp3Rjpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwppZighUC55QihhKSlyZXR1cm4hYj9QLkMxKGEpOmEK
+dD1ILlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysr
+cCl7bz1zW3BdCmlmKCIuLiI9PT1vKWlmKHQubGVuZ3RoIT09MCYmQy5ObS5ncloodCkhPT0iLi4iKXtp
+ZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCnE9ITB9ZWxzZXtDLk5tLmkodCwi
+Li4iKQpxPSExfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0hMX19cz10Lmxl
+bmd0aAppZihzIT09MClpZihzPT09MSl7aWYoMD49cylyZXR1cm4gSC5PSCh0LDApCnM9dFswXS5sZW5n
+dGg9PT0wfWVsc2Ugcz0hMQplbHNlIHM9ITAKaWYocylyZXR1cm4iLi8iCmlmKHF8fEMuTm0uZ3JaKHQp
+PT09Ii4uIilDLk5tLmkodCwiIikKaWYoIWIpe2lmKDA+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsMCkK
+Qy5ObS5ZKHQsMCxQLkMxKHRbMF0pKX1yZXR1cm4gQy5ObS56Vih0LCIvIil9LApDMTpmdW5jdGlvbihh
+KXt2YXIgdCxzLHIscT1hLmxlbmd0aAppZihxPj0yJiZQLkV0KEouUXooYSwwKSkpZm9yKHQ9MTt0PHE7
+Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT01OClyZXR1cm4gQy54Qi5OaihhLDAsdCkrIiUzQSIrQy54
+Qi5HKGEsdCsxKQppZihzPD0xMjcpe3I9cz4+PjQKaWYocj49OClyZXR1cm4gSC5PSChDLm1LLHIpCnI9
+KEMubUtbcl0mMTw8KHMmMTUpKT09PTB9ZWxzZSByPSEwCmlmKHIpYnJlYWt9cmV0dXJuIGF9LAptbjpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLmdGaigpLHA9cS5sZW5ndGgKaWYocD4wJiZKLkhtKHFbMF0p
+PT09MiYmSi5hNihxWzBdLDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguT0gocSwwKQpQLnJnKEouYTYo
+cVswXSwwKSwhMSkKUC5ITihxLCExLDEpCnQ9ITB9ZWxzZXtQLkhOKHEsITEsMCkKdD0hMX1zPWEuZ3RU
+KCkmJiF0PyJcXCI6IiIKaWYoYS5nY2ooKSl7cj1hLmdKZihhKQppZihyLmxlbmd0aCE9PTApcz1zKyJc
+XCIrcisiXFwifXM9UC52ZyhzLHEsIlxcIikKcD10JiZwPT09MT9zKyJcXCI6cwpyZXR1cm4gcC5jaGFy
+Q29kZUF0KDApPT0wP3A6cH0sCkloOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PTAscz0wO3M8
+MjsrK3Mpe3I9Qy54Qi5XKGEsYitzKQppZig0ODw9ciYmcjw9NTcpdD10KjE2K3ItNDgKZWxzZXtyfD0z
+MgppZig5Nzw9ciYmcjw9MTAyKXQ9dCoxNityLTg3CmVsc2UgdGhyb3cgSC5iKFAueFkoIkludmFsaWQg
+VVJMIGVuY29kaW5nIikpfX1yZXR1cm4gdH0sCmt1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxy
+LHEscD1KLnJZKGEpLG89Ygp3aGlsZSghMCl7aWYoIShvPGMpKXt0PSEwCmJyZWFrfXM9cC5XKGEsbykK
+aWYoczw9MTI3KWlmKHMhPT0zNylyPWUmJnM9PT00MwplbHNlIHI9ITAKZWxzZSByPSEwCmlmKHIpe3Q9
+ITEKYnJlYWt9KytvfWlmKHQpe2lmKEMueE0hPT1kKXI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJuIHAu
+TmooYSxiLGMpCmVsc2UgcT1uZXcgSC5xaihwLk5qKGEsYixjKSl9ZWxzZXtxPUguVk0oW10sdS50KQpm
+b3Iobz1iO288YzsrK28pe3M9cC5XKGEsbykKaWYocz4xMjcpdGhyb3cgSC5iKFAueFkoIklsbGVnYWwg
+cGVyY2VudCBlbmNvZGluZyBpbiBVUkkiKSkKaWYocz09PTM3KXtpZihvKzM+YS5sZW5ndGgpdGhyb3cg
+SC5iKFAueFkoIlRydW5jYXRlZCBVUkkiKSkKQy5ObS5pKHEsUC5JaChhLG8rMSkpCm8rPTJ9ZWxzZSBp
+ZihlJiZzPT09NDMpQy5ObS5pKHEsMzIpCmVsc2UgQy5ObS5pKHEscyl9fXUuTC5iKHEpCnJldHVybiBu
+ZXcgUC5HWSghMSkuV0oocSl9LApFdDpmdW5jdGlvbihhKXt2YXIgdD1hfDMyCnJldHVybiA5Nzw9dCYm
+dDw9MTIyfSwKS0Q6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbD0iSW52YWxpZCBN
+SU1FIHR5cGUiLGs9SC5WTShbYi0xXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9YixyPS0xLHE9bnVsbDtz
+PHQ7KytzKXtxPUMueEIuVyhhLHMpCmlmKHE9PT00NHx8cT09PTU5KWJyZWFrCmlmKHE9PT00Nyl7aWYo
+cjwwKXtyPXMKY29udGludWV9dGhyb3cgSC5iKFAucnIobCxhLHMpKX19aWYocjwwJiZzPmIpdGhyb3cg
+SC5iKFAucnIobCxhLHMpKQpmb3IoO3EhPT00NDspe0MuTm0uaShrLHMpOysrcwpmb3IocD0tMTtzPHQ7
+KytzKXtxPUMueEIuVyhhLHMpCmlmKHE9PT02MSl7aWYocDwwKXA9c31lbHNlIGlmKHE9PT01OXx8cT09
+PTQ0KWJyZWFrfWlmKHA+PTApQy5ObS5pKGsscCkKZWxzZXtvPUMuTm0uZ3JaKGspCmlmKHEhPT00NHx8
+cyE9PW8rN3x8IUMueEIuUWkoYSwiYmFzZTY0IixvKzEpKXRocm93IEguYihQLnJyKCJFeHBlY3Rpbmcg
+Jz0nIixhLHMpKQpicmVha319Qy5ObS5pKGsscykKbj1zKzEKaWYoKGsubGVuZ3RoJjEpPT09MSlhPUMu
+aDkueXIoYSxuLHQpCmVsc2V7bT1QLlVsKGEsbix0LEMuVkMsITApCmlmKG0hPW51bGwpYT1DLnhCLmk3
+KGEsbix0LG0pfXJldHVybiBuZXcgUC5QRShhLGssYyl9LAp1eDpmdW5jdGlvbigpe3ZhciB0PSIwMTIz
+NDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0u
+X34hJCYnKCkqKyw7PSIscz0iLiIscj0iOiIscT0iLyIscD0iPyIsbz0iIyIsbj11LmdjLG09UC5kSCgy
+MixuZXcgUC5xMygpLCEwLG4pLGw9bmV3IFAueUkobSksaz1uZXcgUC5jNigpLGo9bmV3IFAucWQoKSxp
+PW4uYihsLiQyKDAsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLHMsMTQpCmsuJDMoaSxyLDM0KQprLiQz
+KGkscSwzKQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxNCwyMjUpKQprLiQz
+KGksdCwxKQprLiQzKGkscywxNSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcy
+KQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTUsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLCIlIiwy
+MjUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1u
+LmIobC4kMigxLDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwxMCkKay4kMyhp
+LHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMiwyMzUpKQprLiQzKGksdCwxMzkpCmsuJDMo
+aSxxLDEzMSkKay4kMyhpLHMsMTQ2KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4k
+MigzLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSw2OCkKay4kMyhpLHMsMTgpCmsuJDMoaSxwLDE3
+MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDQsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIs
+MjI5KQprLiQzKGksciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSwiWyIsMjMyKQprLiQzKGkscSwx
+MzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDUsMjI5KSkKay4kMyhpLHQs
+NSkKai4kMyhpLCJBWiIsMjI5KQprLiQzKGksciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEz
+OCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoNiwyMzEpKQpqLiQzKGksIjE5
+Iiw3KQprLiQzKGksIkAiLDY4KQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1
+KQppPW4uYihsLiQyKDcsMjMxKSkKai4kMyhpLCIwOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEs
+MTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKay4kMyhuLmIobC4kMig4LDgpKSwiXSIsNSkK
+aT1uLmIobC4kMig5LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxNikKay4kMyhpLHEsMjM0KQpr
+LiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxNiwyMzUpKQprLiQzKGksdCwxMSkK
+ay4kMyhpLHMsMTcpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5i
+KGwuJDIoMTcsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4kMyhp
+LG8sMjA1KQppPW4uYihsLiQyKDEwLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxOCkKay4kMyhp
+LHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxOCwyMzUpKQprLiQz
+KGksdCwxMSkKay4kMyhpLHMsMTkpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywy
+MDUpCmk9bi5iKGwuJDIoMTksMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAs
+MTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTEsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxx
+LDEwKQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxMiwyMzYpKQprLiQzKGks
+dCwxMikKay4kMyhpLHAsMTIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxMywyMzcpKQprLiQzKGks
+dCwxMykKay4kMyhpLHAsMTMpCmouJDMobi5iKGwuJDIoMjAsMjQ1KSksImF6IiwyMSkKbD1uLmIobC4k
+MigyMSwyNDUpKQpqLiQzKGwsImF6IiwyMSkKai4kMyhsLCIwOSIsMjEpCmsuJDMobCwiKy0uIiwyMSkK
+cmV0dXJuIG19LApVQjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbz0kLnZaKCkKZm9y
+KHQ9Si5yWShhKSxzPWI7czxjOysrcyl7aWYoZDwwfHxkPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLGQp
+CnI9b1tkXQpxPXQuVyhhLHMpXjk2CmlmKHE+OTUpcT0zMQppZihxPj1yLmxlbmd0aClyZXR1cm4gSC5P
+SChyLHEpCnA9cltxXQpkPXAmMzEKQy5ObS5ZKGUscD4+PjUscyl9cmV0dXJuIGR9LApXRjpmdW5jdGlv
+biBXRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYTI6ZnVuY3Rpb24gYTIoKXt9LAppUDpmdW5jdGlv
+biBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQ1A6ZnVuY3Rpb24gQ1AoKXt9LApYUzpmdW5jdGlv
+biBYUygpe30sCkM2OmZ1bmN0aW9uIEM2KGEpe3RoaXMuYT1hfSwKbjpmdW5jdGlvbiBuKCl7fSwKdTpm
+dW5jdGlvbiB1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApiSjpm
+dW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9YwpfLmI9ZApf
+LmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmY9YQpfLmE9
+YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0sCmRzOmZ1bmN0
+aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApVVjpmdW5jdGlv
+biBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24gS1koKXt9LApj
+OmZ1bmN0aW9uIGMoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlzLmE9YX0sCmFFOmZ1
+bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVIOmZ1bmN0aW9uIEVI
+KCl7fSwKS046ZnVuY3Rpb24gS04oKXt9LApjWDpmdW5jdGlvbiBjWCgpe30sCkFuOmZ1bmN0aW9uIEFu
+KCl7fSwKek06ZnVuY3Rpb24gek0oKXt9LApaMDpmdW5jdGlvbiBaMCgpe30sCk4zOmZ1bmN0aW9uIE4z
+KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6ZnVuY3Rpb24gYzgoKXt9LApG
+SzpmdW5jdGlvbiBGSygpe30sCms6ZnVuY3Rpb24gaygpe30sCk9kOmZ1bmN0aW9uIE9kKCl7fSwKaWI6
+ZnVuY3Rpb24gaWIoKXt9LAp4dTpmdW5jdGlvbiB4dSgpe30sCkd6OmZ1bmN0aW9uIEd6KCl7fSwKcVU6
+ZnVuY3Rpb24gcVUoKXt9LApSbjpmdW5jdGlvbiBSbihhKXt0aGlzLmE9YX0sCkdEOmZ1bmN0aW9uIEdE
+KCl7fSwKbjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9
+YX0sClZDOmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEK
+Xy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LApl
+MTpmdW5jdGlvbiBlMShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTlk6ZnVuY3Rpb24gTlkoYSl7dGhp
+cy5hPWF9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9uIE1FKGEsYil7dGhpcy5hPWEKdGhp
+cy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBFOmZ1bmN0aW9uIFBFKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnEzOmZ1bmN0aW9uIHEzKCl7fSwKeUk6ZnVuY3Rpb24g
+eUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9uIHFkKCl7fSwKVWY6
+ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8u
+ZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rpb24gcWUoYSxiLGMs
+ZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9
+ZwpfLlE9Xy56PV8ueT1fLng9bnVsbH0sCmlKOmZ1bmN0aW9uIGlKKCl7fSwKbFI6ZnVuY3Rpb24gbFIo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5i
+PWJ9LApCZjpmdW5jdGlvbiBCZihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQXM6ZnVuY3Rpb24gQXMo
+KXt9LApHRTpmdW5jdGlvbiBHRShhKXt0aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LAp1UTpmdW5jdGlvbiB1USgpe30sCmhGOmZ1bmN0aW9uIGhGKCl7fSwKUjQ6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCkgueGQoYikKdS5qLmIoZCkKaWYoSC5vVChiKSl7dD1bY10K
+Qy5ObS5GVih0LGQpCmQ9dH1zPXUuegpyPVAuQ0goSi5NMShkLFAudzAoKSxzKSwhMCxzKQp1LlouYihh
+KQpyZXR1cm4gUC53WShILkVrKGEscixudWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdHJ5
+e2lmKE9iamVjdC5pc0V4dGVuc2libGUoYSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5
+LmNhbGwoYSxiKSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1j
+YXRjaCh0KXtILlJ1KHQpfXJldHVybiExfSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90
+eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1
+bmN0aW9uKGEpe2lmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIi
+fHxILmwoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEp
+KXJldHVybiBhCmlmKHUudy5jKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBI
+Lm8yKGEpCmlmKHUuWi5jKGEpKXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBD
+KCkpCnJldHVybiBQLmhFKGEsIl8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApoRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHQ9UC5PbShhLGIpCmlmKHQ9PW51bGwpe3Q9Yy4kMShhKQpQLkRtKGEs
+Yix0KX1yZXR1cm4gdH0sCkw3OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYoYT09bnVsbHx8dHlwZW9mIGE9
+PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEK
+ZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0
+YW5jZW9mIE9iamVjdCYmdS53LmMoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgRGF0ZSl7
+dD1ILlNjKGEuZ2V0VGltZSgpKQppZihNYXRoLmFicyh0KTw9ODY0ZTEzKXM9ITEKZWxzZSBzPSEwCmlm
+KHMpSC52aChQLnhZKCJEYXRlVGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdlOiAiK3QpKQpyZXR1cm4g
+bmV3IFAuaVAodCwhMSl9ZWxzZSBpZihhLmNvbnN0cnVjdG9yPT09JC5rSSgpKXJldHVybiBhLm8KZWxz
+ZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJl
+dHVybiBQLmlRKGEsJC53KCksbmV3IFAuTnooKSkKaWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVybiBQ
+LmlRKGEsJC5SOCgpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLm5wKCkpfSwK
+aVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1udWxsfHwhKGEgaW5zdGFuY2Vv
+ZiBPYmplY3QpKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApQQzpmdW5jdGlvbiBQQygp
+e30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVuY3Rpb24gTnooKXt9LApRUzpmdW5j
+dGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVuY3Rpb24gRTQoYSl7dGhpcy5hPWF9
+LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0aW9uIFR6KGEsYil7dGhpcy5hPWEK
+dGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVuY3Rpb24gbmQoKXt9LApLZTpmdW5j
+dGlvbiBLZShhKXt0aGlzLmE9YX0sCmQ1OmZ1bmN0aW9uIGQ1KCl7fSwKbjY6ZnVuY3Rpb24gbjYoKXt9
+fSxXPXsKeDM6ZnVuY3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4gZG9j
+dW1lbnR9LApKNjpmdW5jdGlvbigpe3ZhciB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKQpyZXR1
+cm4gdH0sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1kb2N1bWVudC5ib2R5LHM9KHQmJkMuUlkpLnI2
+KHQsYSxiLGMpCnMudG9TdHJpbmcKdD11LmFjCnQ9bmV3IEguVTUobmV3IFcuZTcocyksdC5DKCJhMihs
+RC5FKSIpLmIobmV3IFcuQ3YoKSksdC5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdS5oLmIodC5ncjgodCkp
+fSwKclM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPSJlbGVtZW50IHRhZyB1bmF2YWlsYWJsZSIKdHJ5e3Q9
+Si5SRShhKQppZih0eXBlb2YgdC5nbnMoYSk9PSJzdHJpbmciKXI9dC5nbnMoYSl9Y2F0Y2gocyl7SC5S
+dShzKX1yZXR1cm4gcn0sCnFEOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9bmV3IFAudnMoJC5YMyx1
+LlkpLHA9bmV3IFAuWmYocSx1LkUpLG89bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5EdC5lbyhvLCJHRVQi
+LGEsITApCmIuSygwLG5ldyBXLmJVKG8pKQp0PXUuYW4Kcz10LmIobmV3IFcuaEgobyxwKSkKdS5NLmIo
+bnVsbCkKcj11LnAKVy5KRShvLCJsb2FkIixzLCExLHIpClcuSkUobywiZXJyb3IiLHQuYihwLmdZSigp
+KSwhMSxyKQpvLnNlbmQoKQpyZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT01MzY4NzA5MTEmYSti
+CmE9NTM2ODcwOTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9u
+KGEsYixjLGQpe3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxzPTUzNjg3MDkx
+MSZ0KygoNjcxMDg4NjMmdCk8PDMpCnNePXM+Pj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZz
+KTw8MTUpfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5jbGFzc0xpc3QKZm9yKHQ9Yi5sZW5n
+dGgscz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Mpci5hZGQoYltzXSl9
+LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PVcuYUYobmV3IFcudk4oYyksdS5CKQppZih0IT1u
+dWxsJiYhMClKLmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEsZS5DKCJ4QzwwPiIp
+KX0sClR3OmZ1bmN0aW9uKGEpe3ZhciB0PVcuSjYoKSxzPXdpbmRvdy5sb2NhdGlvbgp0PW5ldyBXLkpR
+KG5ldyBXLm1rKHQscykpCnQuQ1koYSkKcmV0dXJuIHR9LAp5VzpmdW5jdGlvbihhLGIsYyxkKXt1Lmgu
+YihhKQpILnkoYikKSC55KGMpCnUuTy5iKGQpCnJldHVybiEwfSwKUVc6ZnVuY3Rpb24oYSxiLGMsZCl7
+dmFyIHQscyxyCnUuaC5iKGEpCkgueShiKQpILnkoYykKdD11Lk8uYihkKS5hCnM9dC5hCnMuaHJlZj1j
+CnI9cy5ob3N0bmFtZQp0PXQuYgppZighKHI9PXQuaG9zdG5hbWUmJnMucG9ydD09dC5wb3J0JiZzLnBy
+b3RvY29sPT10LnByb3RvY29sKSlpZihyPT09IiIpaWYocy5wb3J0PT09IiIpe3Q9cy5wcm90b2NvbAp0
+PXQ9PT0iOiJ8fHQ9PT0iIn1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMApyZXR1cm4gdH0sCkJs
+OmZ1bmN0aW9uKCl7dmFyIHQ9dS5OLHM9UC50TShDLlF4LHQpLHI9dS5kRy5iKG5ldyBXLklBKCkpLHE9
+SC5WTShbIlRFTVBMQVRFIl0sdS5zKQp0PW5ldyBXLmN0KHMsUC5Mcyh0KSxQLkxzKHQpLFAuTHModCks
+bnVsbCkKdC5DWShudWxsLG5ldyBILkE4KEMuUXgscix1LmR2KSxxLG51bGwpCnJldHVybiB0fSwKdVY6
+ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gVy5QMShhKX0sCnFjOmZ1bmN0
+aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXt0
+PVcuUDEoYSkKaWYodS51LmModCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4gdS51LmIo
+YSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB1LmNpLmIoYSkKZWxzZSByZXR1
+cm4gbmV3IFcuZFcoYSl9LApISDpmdW5jdGlvbihhKXtpZihhPT09d2luZG93LmxvY2F0aW9uKXJldHVy
+biBhCmVsc2UgcmV0dXJuIG5ldyBXLkZiKCl9LAphRjpmdW5jdGlvbihhLGIpe3ZhciB0PSQuWDMKaWYo
+dD09PUMuTlUpcmV0dXJuIGEKcmV0dXJuIHQuUHkoYSxiKX0sCnFFOmZ1bmN0aW9uIHFFKCl7fSwKR2g6
+ZnVuY3Rpb24gR2goKXt9LApmWTpmdW5jdGlvbiBmWSgpe30sCm5COmZ1bmN0aW9uIG5CKCl7fSwKQXo6
+ZnVuY3Rpb24gQXooKXt9LApRUDpmdW5jdGlvbiBRUCgpe30sCm54OmZ1bmN0aW9uIG54KCl7fSwKb0o6
+ZnVuY3Rpb24gb0ooKXt9LAppZDpmdW5jdGlvbiBpZCgpe30sClFGOmZ1bmN0aW9uIFFGKCl7fSwKTmg6
+ZnVuY3Rpb24gTmgoKXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6
+ZnVuY3Rpb24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApD
+djpmdW5jdGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApU
+NTpmdW5jdGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApW
+YjpmdW5jdGlvbiBWYigpe30sCk83OmZ1bmN0aW9uIE83KCl7fSwKYlU6ZnVuY3Rpb24gYlUoYSl7dGhp
+cy5hPWF9LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKd2E6ZnVuY3Rpb24g
+d2EoKXt9LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1bmN0aW9uIHU4KCl7fSwKQWo6ZnVuY3Rpb24g
+QWooKXt9LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6
+ZnVuY3Rpb24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6
+ZnVuY3Rpb24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6
+ZnVuY3Rpb24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6
+ZnVuY3Rpb24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6
+ZnVuY3Rpb24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6
+ZnVuY3Rpb24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1
+bmN0aW9uIEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhh
+LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10
+aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3Zh
+ciBfPXRoaXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEp
+e3RoaXMuYT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30s
+CnZEOmZ1bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApF
+ZzpmdW5jdGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlv
+biBtNigpe30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlv
+biBjdChhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJ
+QTpmdW5jdGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMp
+e3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlv
+biBkVyhhKXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZiKCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LApt
+azpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhp
+cy5hPWF9LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6
+ZnVuY3Rpb24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6
+ZnVuY3Rpb24gb2EoKXt9fSxVPXsKamY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0
+PW51bGwKZWxzZXt0PUguVk0oW10sdS5mQSkKZm9yKHM9Si5JVCh1LlIuYihhKSk7cy5GKCk7KXtyPXMu
+Z2woKQpxPUouVTYocikKQy5ObS5pKHQsbmV3IFUuU2UoSC5jMChxLnEociwiZGVzY3JpcHRpb24iKSks
+SC5jMChxLnEociwiaHJlZiIpKSkpfX1yZXR1cm4gdH0sCk5kOmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYo
+YT09bnVsbCl0PW51bGwKZWxzZXt0PUguVk0oW10sdS5oaCkKZm9yKHM9Si5JVCh1LlIuYihhKSk7cy5G
+KCk7KUMuTm0uaSh0LFUuTmYocy5nbCgpKSl9cmV0dXJuIHR9LApOZjpmdW5jdGlvbihhKXt2YXIgdCxz
+LHIscSxwLG89ImRlc2NyaXB0aW9uIixuPUouVTYoYSksbT1ILmMwKG4ucShhLG8pKSxsPUguVk0oW10s
+dS5hSikKZm9yKG49Si5JVCh1LlIuYihuLnEoYSwiZW50cmllcyIpKSk7bi5GKCk7KXt0PW4uZ2woKQpz
+PUouVTYodCkKcj1ILmMwKHMucSh0LG8pKQpxPUguYzAocy5xKHQsImZ1bmN0aW9uIikpCnM9cy5xKHQs
+ImxpbmsiKQppZihzPT1udWxsKXM9bnVsbAplbHNle3A9Si5VNihzKQpzPW5ldyBVLk1sKEguYzAocC5x
+KHMsImhyZWYiKSksSC5XWShwLnEocywibGluZSIpKSxILmMwKHAucShzLCJwYXRoIikpKX1DLk5tLmko
+bCxuZXcgVS53YihyLHEscykpfXJldHVybiBuZXcgVS55RChtLGwpfSwKZDI6ZnVuY3Rpb24gZDIoYSxi
+LGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rp
+b24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LAp3YjpmdW5jdGlvbiB3YihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxCPXsKWWY6
+ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPUguYzAoYS5xKDAsInJlZ2lvbnMiKSksaz1I
+LmMwKGEucSgwLCJuYXZpZ2F0aW9uQ29udGVudCIpKSxqPUguYzAoYS5xKDAsInNvdXJjZUNvZGUiKSks
+aT1QLkZsKHUuTix1LmY0KQpmb3IodD11LlMuYShhLnEoMCwiZWRpdHMiKSksdD10LmdQdSh0KSx0PXQu
+Z2t6KHQpLHM9dS5SLHI9dS5naTt0LkYoKTspe3E9dC5nbCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3Io
+cT1KLklUKHMuYihxLmIpKTtxLkYoKTspe249cS5nbCgpCm09Si5VNihuKQpDLk5tLmkobyxuZXcgQi5q
+OChILldZKG0ucShuLCJsaW5lIikpLEguYzAobS5xKG4sImV4cGxhbmF0aW9uIikpLEguV1kobS5xKG4s
+Im9mZnNldCIpKSkpfWkuWSgwLHAsbyl9cmV0dXJuIG5ldyBCLnFwKGwsayxqLGkpfSwKajg6ZnVuY3Rp
+b24gajgoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxi
+LGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2OmZ1bmN0aW9uIGZ2KCl7
+fSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoIShhPj02NSYmYTw9OTApKXQ9YT49OTcmJmE8PTEyMgpl
+bHNlIHQ9ITAKcmV0dXJuIHR9LApZdTpmdW5jdGlvbihhLGIpe3ZhciB0PWEubGVuZ3RoLHM9YisyCmlm
+KHQ8cylyZXR1cm4hMQppZighQi5PUyhDLnhCLm0oYSxiKSkpcmV0dXJuITEKaWYoQy54Qi5tKGEsYisx
+KSE9PTU4KXJldHVybiExCmlmKHQ9PT1zKXJldHVybiEwCnJldHVybiBDLnhCLm0oYSxzKT09PTQ3fX0s
+VD17bVE6ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRP
+TUNvbnRlbnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwo
+KSl9LAprejpmdW5jdGlvbihhKXt2YXIgdCxzPXUuaC5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3Rv
+cigiOnNjb3BlID4gdWwiKSxyPXMuc3R5bGUscT0iIitDLkNELnpRKHMub2Zmc2V0SGVpZ2h0KSoyKyJw
+eCIKci5tYXhIZWlnaHQ9cQpyPUoucUYoYSkKcT1yLiR0aQp0PXEuQygifigxKSIpLmIobmV3IEwuV3go
+cyxhKSkKdS5NLmIobnVsbCkKVy5KRShyLmEsci5iLHQsITEscS5kKX0sCnlYOmZ1bmN0aW9uKGEsYil7
+dmFyIHQscyxyLHEscCxvPSJxdWVyeVNlbGVjdG9yQWxsIixuPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Io
+YSksbT11LmgKbi50b1N0cmluZwpILkRoKG0sbSwiVCIsbykKdD11LlQKcz1uZXcgVy53eihuLnF1ZXJ5
+U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHQpCnMuSyhzLG5ldyBMLkFPKGIpKQpILkRoKG0sbSwiVCIs
+bykKcj1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSx0KQppZihyLmdBKHIpIT09
+MCl7cT1uLnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpxLnRvU3RyaW5nCnIuSyhyLG5l
+dyBMLkhvKHEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocSkpLk8oInBhdGgi
+KSkpKX1ILkRoKG0sbSwiVCIsbykKcD1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5hZGQtaGlu
+dC1saW5rIiksdCkKcC5LKHAsbmV3IEwuSUMoKSl9LApRNjpmdW5jdGlvbihhLGIpe3ZhciB0PXUuTgpy
+ZXR1cm4gVy5xRChMLlE0KGEsYiksUC5FRihbIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247
+IGNoYXJzZXQ9VVRGLTgiXSx0LHQpKX0sCnR5OmZ1bmN0aW9uKGEpe3ZhciB0PTAscz1QLkZYKHUuUyks
+cixxLHAsbyxuLG0sbCxrCnZhciAkYXN5bmMkdHk9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXJl
+dHVybiBQLmYzKGMscykKd2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOm49bmV3IFAudnMoJC5YMyx1
+LlkpCm09bmV3IFAuWmYobix1LkUpCmw9bmV3IFhNTEh0dHBSZXF1ZXN0KCkKaz11Lk4KQy5EdC5lbyhs
+LCJQT1NUIixMLlE0KGEsUC5GbChrLGspKSwhMCkKbC5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5
+cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04IikKaz11LmFuCnE9ay5iKG5ldyBMLkwx
+KG0sbCkpCnUuTS5iKG51bGwpCnA9dS5wClcuSkUobCwibG9hZCIscSwhMSxwKQpXLkpFKGwsImVycm9y
+IixrLmIobS5nWUooKSksITEscCkKbC5zZW5kKCkKdD0zCnJldHVybiBQLmpRKG4sJGFzeW5jJHR5KQpj
+YXNlIDM6bz1DLkN0LnBXKDAsbC5yZXNwb25zZVRleHQsbnVsbCkKaWYobC5zdGF0dXM9PT0yMDApe3I9
+dS5TLmEobykKdD0xCmJyZWFrfWVsc2UgdGhyb3cgSC5iKG8pCmNhc2UgMTpyZXR1cm4gUC55QyhyLHMp
+fX0pCnJldHVybiBQLkRJKCRhc3luYyR0eSxzKX0sCmFLOmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSku
+Z2hZKCkucSgwLCJsaW5lIikKcmV0dXJuIHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LApHNjpmdW5j
+dGlvbihhKXt2YXIgdD1QLmhLKGEpLmdoWSgpLnEoMCwib2Zmc2V0IikKcmV0dXJuIHQ9PW51bGw/bnVs
+bDpILkhwKHQsbnVsbCl9LAppNjpmdW5jdGlvbihhKXtyZXR1cm4gTC5uVyh1LlYuYihhKSl9LApuVzpm
+dW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrCnZhciAkYXN5
+bmMkaTY9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNo
+KHQpe2Nhc2UgMDpsPXUuaC5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVm
+IikKYS5wcmV2ZW50RGVmYXVsdCgpCnI9Mwp0PTYKcmV0dXJuIFAualEoTC50eShsKSwkYXN5bmMkaTYp
+CmNhc2UgNjp1LmFfLmEoSi5HcihXLnVWKGRvY3VtZW50LmRlZmF1bHRWaWV3KSkpLnJlbG9hZCgpCnI9
+MQp0PTUKYnJlYWsKY2FzZSAzOnI9MgprPXEKbz1ILlJ1KGspCm49SC50cyhrKQpMLkMyKCJDb3VsZCBu
+b3QgYWRkL3JlbW92ZSBoaW50IixvLG4pCnQ9NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNhc2UgNTpy
+ZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRh
+c3luYyRpNixzKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9ImV4Y2VwdGlvbiIscT0ic3Rh
+Y2tUcmFjZSIscD11LlMuYyhiKSYmSi5STShiLnEoMCwic3VjY2VzcyIpLCExKSYmSC5vVChiLng0KHIp
+KSYmSC5vVChiLng0KHEpKSxvPUouaWEoYikKaWYocCl7dD1ILmMwKG8ucShiLHIpKQpjPW8ucShiLHEp
+fWVsc2UgdD1vLncoYikKcD1kb2N1bWVudApzPXAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpz
+LnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJU
+ZXh0PXQKcy5xdWVyeVNlbGVjdG9yKCJwcmUiKS5pbm5lclRleHQ9Si5qKGMpCm89dS5OCnUuYnEuYShz
+LnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikpLmhyZWY9UC5YZCgiaHR0cHMiLCJnaXRodWIuY29tIiwi
+ZGFydC1sYW5nL3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsidGl0bGUiLCJJc3N1ZSB3aXRoIE5OQkQgbWln
+cmF0aW9uIHRvb2w6ICIrYSwibGFiZWxzIiwiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3Jh
+dGlvbix0eXBlLWJ1ZyIsImJvZHkiLGErIlxuXG5FcnJvcjogIitILmQodCkrIlxuXG5QbGVhc2UgZmls
+bCBpbiB0aGUgZm9sbG93aW5nOlxuXG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAoaWYg
+cHVibGljKSoqOlxuKipXaGF0IEkgd2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoqOlxu
+KipJcyBpdCBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlzIGlz
+c3VlIGhhcHBlbmVkIGJlZm9yZSwgYW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsgdmVy
+c2lvbioqOiAiK0guZChwLmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRleHRDb250ZW50KSsi
+XG4qKkFkZGl0aW9uYWwgZGV0YWlscyoqOlxuXG5UaGFua3MgZm9yIGZpbGluZyFcblxuU3RhY2t0cmFj
+ZTogX2F1dG8gcG9wdWxhdGVkIGJ5IG1pZ3JhdGlvbiBwcmV2aWV3IHRvb2wuX1xuXG5gYGBcbiIrSC5k
+KGMpKyJcbmBgYFxuIl0sbyxvKSkudygwKQpvPXMuc3R5bGUKby5kaXNwbGF5PSJpbml0aWFsIgpMLnFK
+KGErIjogIitILmQoYiksYyl9LAp0MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49e30s
+bT11LmguYShXLnFjKGEuY3VycmVudFRhcmdldCkpCmEucHJldmVudERlZmF1bHQoKQp0PW4uYT1tLmdl
+dEF0dHJpYnV0ZSgiaHJlZiIpCmlmKEouemwodCwiPyIpKXtzPUMueEIuTmoodCwwLEMueEIuT1kodCwi
+PyIpKQpuLmE9cwpyPXN9ZWxzZSByPXQKaWYoYyE9bnVsbCl7cT0kLm5VKCkKcj1uLmE9cS5vNShELm5y
+KHEudE0oYykscikpfXA9TC5HNih0KQpvPUwuYUsodCkKaWYocCE9bnVsbClMLmFmKHIscCxvLGIsbmV3
+IEwublQobixwLG8pKQplbHNlIEwuYWYocixudWxsLG51bGwsYixuZXcgTC5CWihuKSl9LAp2VTpmdW5j
+dGlvbigpe3ZhciB0PWRvY3VtZW50LHM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIp
+CnQ9bmV3IFcud3oodC5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHUuVCkKdC5LKHQsbmV3IEwuR0go
+KSl9LApoWDpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dS5OCkwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVn
+aW9uIiwib2Zmc2V0IixILmQoYildLHQsdCkpLlc3KG5ldyBMLkRUKGEsYixjKSx1LlApLk9BKG5ldyBM
+LmVIKGEpKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQKaWYoIUouaHcoYSwiLmRhcnQiKSl7
+TC5CRShhLG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00pLGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUu
+JDAoKQpyZXR1cm59dD11Lk4KTC5RNihhLFAuRUYoWyJpbmxpbmUiLCJ0cnVlIl0sdCx0KSkuVzcobmV3
+IEwueXUoYSxkLGIsYyxlKSx1LlApLk9BKG5ldyBMLnpEKGEpKX0sCkdlOmZ1bmN0aW9uKCl7dmFyIHQ9
+Ii9fcHJldmlldy9uYXZpZ2F0aW9uVHJlZS5qc29uIgpMLlE2KHQsQy5XTykuVzcobmV3IEwuVFcoKSx1
+LlApLk9BKG5ldyBMLnhyKHQpKX0sCnFKOmZ1bmN0aW9uKGEsYil7dmFyIHQKd2luZG93CmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS5lcnJvcihhKQp3aW5kb3cKdD1ILmQo
+YikKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKHQpfSwK
+cU86ZnVuY3Rpb24oYSl7dmFyIHQ9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxzPUMuQ0QuelEoJC5m
+aSgpLm9mZnNldEhlaWdodCkscj13aW5kb3cuaW5uZXJIZWlnaHQscT1DLkNELnpRKCQuRFcoKS5vZmZz
+ZXRIZWlnaHQpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuSE4oKQppZih0LmJvdHRvbT5y
+LShxKzE0KSlKLmRoKGEpCmVsc2UgaWYodC50b3A8cysxNClKLmRoKGEpfSwKZkc6ZnVuY3Rpb24oYSxi
+KXt2YXIgdCxzLHIKaWYoYSE9bnVsbCl7dD1kb2N1bWVudApzPXQuZ2V0RWxlbWVudEJ5SWQoIm8iK0gu
+ZChhKSkKcj10LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKGIpKQppZihzIT1udWxsKXtMLnFPKHMp
+CkouZFIocykuaSgwLCJ0YXJnZXQiKX1lbHNlIGlmKHIhPW51bGwpTC5xTyhyLnBhcmVudEVsZW1lbnQp
+CmlmKHIhPW51bGwpSi5kUih1LmguYShyLnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2Ug
+TC5xTygkLkQ5KCkpfSwKYWY6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHI9TC5HNih3aW5kb3cu
+bG9jYXRpb24uaHJlZikscT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZihyIT1udWxsKXt0PWRv
+Y3VtZW50LmdldEVsZW1lbnRCeUlkKCJvIitILmQocikpCmlmKHQhPW51bGwpSi5kUih0KS5SKDAsInRh
+cmdldCIpfWlmKHEhPW51bGwpe3M9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILmQocSkp
+CmlmKHMhPW51bGwpSi5kUihzLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09d2lu
+ZG93LmxvY2F0aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhhLGIsYyxkLGUp
+fSwKUTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5oSyhhKSxxPXUuTgpxPVAuRmwocSxxKQpmb3Io
+dD1yLmdoWSgpLHQ9dC5nUHUodCksdD10Lmdreih0KTt0LkYoKTspe3M9dC5nbCgpCnEuWSgwLHMuYSxz
+LmIpfWZvcih0PWIuZ1B1KGIpLHQ9dC5na3oodCk7dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5i
+KX1xLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnJldHVybiByLm5tKDAscSkudygwKX0sClQxOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPSQuaEwoKQpKLmw1KGssIiIpCmlmKGE9PW51bGwp
+e3Q9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpCnQudGV4dENvbnRlbnQ9IlNlZSBkZXRhaWxzIGFi
+b3V0IGEgcHJvcG9zZWQgZWRpdC4iCkMuTHQuc1AodCxILlZNKFsicGxhY2Vob2xkZXIiXSx1LnMpKQpr
+LmFwcGVuZENoaWxkKHQpCkMuTHQuRkYodCkKcmV0dXJufXM9YS5kCnI9JC5uVSgpCnE9ci50TShzKQpw
+PWEuYgpvPWRvY3VtZW50Cm49ci5IUChzLEouVDAoby5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRD
+b250ZW50KSkKbT1hLmMKbD1vLmNyZWF0ZUVsZW1lbnQoInAiKQprLmFwcGVuZENoaWxkKGwpCmwuYXBw
+ZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShILmQocCkrIiBhdCAiK0guZChuKSsiOiIrSC5kKG0pKyIu
+IikpCkouZGgobCkKTC5DQyhhLGsscSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTAp
+e3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5k
+Q2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQ
+dShiKSxnPWcuZ2t6KGcpLHQ9dS5RLHI9dC5DKCJ+KDEpIikscT11Lk0sdD10LmQ7Zy5GKCk7KXtwPWcu
+Z2woKQpvPWRvY3VtZW50CnM9by5jcmVhdGVFbGVtZW50KCJwIikKbj0kLnlQKCkKbi5hcHBlbmRDaGls
+ZChzKQpzLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0
+ZUVsZW1lbnQoInVsIikKbi5hcHBlbmRDaGlsZChtKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXtuPXAu
+Z2woKQpsPW8uY3JlYXRlRWxlbWVudCgibGkiKQptLmFwcGVuZENoaWxkKGwpCkouZFIobCkuaSgwLCJl
+ZGl0IikKaz1vLmNyZWF0ZUVsZW1lbnQoImEiKQpsLmFwcGVuZENoaWxkKGspCmsuY2xhc3NMaXN0LmFk
+ZCgiZWRpdC1saW5rIikKaj1uLmMKaT1ILmQoaikKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5T
+eShuZXcgVy5pNyhrKSkuTygib2Zmc2V0IiksaSkKaD1uLmEKaT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUo
+ImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygibGluZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5j
+cmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChoKSkpCmk9ci5iKG5ldyBMLkVFKGosaCxhKSkKcS5iKG51
+bGwpClcuSkUoaywiY2xpY2siLGksITEsdCkKbC5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKCI6
+ICIrSC5kKG4uYikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
+cj13aW5kb3cubG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5nRHIocikrSC5kKGEpKQpyPXUuTgpyPVAu
+RmwocixyKQppZihiIT1udWxsKXIuWSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbClyLlkoMCwi
+bGluZSIsSC5kKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93
+Lmhpc3RvcnkKdD11LnoKcz1xLncoMCkKci50b1N0cmluZwpyLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxb
+XSkuUHYoUC5GbCh0LHQpKSwiIixzKX0sCkVuOmZ1bmN0aW9uKGEpe3ZhciB0PUouYmIoZG9jdW1lbnQu
+cXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCwiLyIpCmlmKEMueEIubihhLHQpKXJldHVy
+biBDLnhCLkcoYSx0Lmxlbmd0aCkKZWxzZSByZXR1cm4gYX0sCkJYOmZ1bmN0aW9uKGEsYil7dmFyIHQs
+cyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQokLkQ5KCkudGV4dENvbnRlbnQ9YQp0PWRvY3VtZW50
+CnM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9bmV3IFcud3oodC5xdWVyeVNl
+bGVjdG9yQWxsKCIubmF2LXBhbmVsIC5uYXYtbGluayIpLHUuVCkKdC5LKHQsbmV3IEwuVlMocikpfSwK
+QkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSIucmVnaW9ucyIscz1kb2N1bWVudCxyPXMucXVlcnlTZWxl
+Y3Rvcih0KSxxPXMucXVlcnlTZWxlY3RvcigiLmNvZGUiKQpKLnRIKHIsYi5hLCQuS0coKSkKSi50SChx
+LGIuYiwkLktHKCkpCkwuTEgoYSxiLmQsYykKTC52VSgpCkwueVgoIi5jb2RlIiwhMCkKTC55WCh0LCEw
+KX0sCnRYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZz1kb2N1bWVu
+dCxmPWcuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENoaWxkKGYpCmZvcih0PWIubGVuZ3RoLHM9
+dS5NLHI9MDtyPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytyKXtxPWJbcl0KcD1n
+LmNyZWF0ZUVsZW1lbnQoImxpIikKZi5hcHBlbmRDaGlsZChwKQpvPUouUkUocCkKaWYocS5hPT09Qy5Z
+Mil7by5nUChwKS5pKDAsImRpciIpCm49Zy5jcmVhdGVFbGVtZW50KCJzcGFuIikKcC5hcHBlbmRDaGls
+ZChuKQpvPUouUkUobikKby5nUChuKS5pKDAsImFycm93IikKby5zaGYobiwiJiN4MjVCQzsiKQptPWcu
+Y3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQobSkKSi5sNShtLCImI3gxRjRDMTsiKQpw
+LmFwcGVuZENoaWxkKGcuY3JlYXRlVGV4dE5vZGUocS5iKSkKTC50WChwLHEuYykKTC5reihuKX1lbHNl
+e28uc2hmKHAsIiYjeDFGNEM0OyIpCmw9Zy5jcmVhdGVFbGVtZW50KCJhIikKcC5hcHBlbmRDaGlsZChs
+KQpvPUouUkUobCkKby5nUChsKS5pKDAsIm5hdi1saW5rIikKbC5zZXRBdHRyaWJ1dGUoImRhdGEtIitu
+ZXcgVy5TeShuZXcgVy5pNyhsKSkuTygibmFtZSIpLHEuZCkKbC5zZXRBdHRyaWJ1dGUoImhyZWYiLHEu
+ZSkKbC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKHEuYikpCm89by5nVmwobCkKaz1vLiR0aQpq
+PWsuQygifigxKSIpLmIobmV3IEwuVEQoKSkKcy5iKG51bGwpClcuSkUoby5hLG8uYixqLCExLGsuZCkK
+aT1xLmYKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5vcygpCmlmKGk+MCl7aD1nLmNyZWF0
+ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKGgpCkouZFIoaCkuaSgwLCJlZGl0LWNvdW50IikK
+bz0iIitpKyIgIgppZihpPT09MSlrPSJlZGl0IgplbHNlIGs9ImVkaXRzIgpoLnNldEF0dHJpYnV0ZSgi
+dGl0bGUiLG8raykKaC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKEMuam4udyhpKSkpfX19fSwK
+Rno6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqPWEuYQppZihqIT1udWxsKXt0
+PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJwIikKYi5hcHBlbmRDaGlsZChzKQpmb3Iocj1qLmxl
+bmd0aCxxPXUucyxwPXUuWCxvPTA7bzxqLmxlbmd0aDtqLmxlbmd0aD09PXJ8fCgwLEgubGspKGopLCsr
+byl7bj1qW29dCm09dC5jcmVhdGVFbGVtZW50KCJhIikKcy5hcHBlbmRDaGlsZChtKQptLmFwcGVuZENo
+aWxkKHQuY3JlYXRlVGV4dE5vZGUobi5hKSkKbS5zZXRBdHRyaWJ1dGUoImhyZWYiLG4uYikKbD1wLmIo
+SC5WTShbImFkZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHkiLCJidXR0b24iXSxxKSkKaz1KLmRSKG0p
+CmsuVjEoMCkKay5GVigwLGwpfX19LApDQzpmdW5jdGlvbihhMixhMyxhNCl7dmFyIHQscyxyLHEscCxv
+LG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYSxhMCxhMT1udWxsCmZvcih0PWEyLmUscz10Lmxlbmd0
+aCxyPXUucyxxPXUuWCxwPTA7cDx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcCl7
+bz10W3BdCm49ZG9jdW1lbnQKbT1uLmNyZWF0ZUVsZW1lbnQoInAiKQpsPXEuYihILlZNKFsidHJhY2Ui
+XSxyKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpCmo9YTMuYXBwZW5kQ2hpbGQobSkKbT1uLmNy
+ZWF0ZUVsZW1lbnQoInNwYW4iKQpsPXEuYihILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHIpKQprPUou
+ZFIobSkKay5WMSgwKQprLkZWKDAsbCkKbS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKG8uYSkp
+CmouYXBwZW5kQ2hpbGQobSkKai5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKCI6IikpCm09bi5j
+cmVhdGVFbGVtZW50KCJ1bCIpCmw9cS5iKEguVk0oWyJ0cmFjZSJdLHIpKQprPUouZFIobSkKay5WMSgw
+KQprLkZWKDAsbCkKaT1qLmFwcGVuZENoaWxkKG0pCmZvcihtPW8uYixsPW0ubGVuZ3RoLGg9MDtoPG0u
+bGVuZ3RoO20ubGVuZ3RoPT09bHx8KDAsSC5saykobSksKytoKXtnPW1baF0KZj1uLmNyZWF0ZUVsZW1l
+bnQoImxpIikKSi5sNShmLCImI3gyNzRGOyAiKQppLmFwcGVuZENoaWxkKGYpCmU9bi5jcmVhdGVFbGVt
+ZW50KCJzcGFuIikKZD1xLmIoSC5WTShbImZ1bmN0aW9uIl0scikpCms9Si5kUihlKQprLlYxKDApCmsu
+RlYoMCxkKQpkPWcuYgpMLmtEKGUsZD09bnVsbD8idW5rbm93biI6ZCkKZi5hcHBlbmRDaGlsZChlKQpj
+PWcuYwppZihjIT1udWxsKXtmLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIiAoIikpCmI9Yy5i
+CmE9bi5jcmVhdGVFbGVtZW50KCJhIikKYS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKEguZChj
+LmMpKyI6IitILmQoYikpKQphMD1jLmEKZT0kLm5VKCkKYS5zZXRBdHRyaWJ1dGUoImhyZWYiLGUubzUo
+ZS5xNygwLGE0LGEwLGExLGExLGExLGExLGExLGExKSkpCmEuY2xhc3NMaXN0LmFkZCgibmF2LWxpbmsi
+KQpmLmFwcGVuZENoaWxkKGEpCmYuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1mLmFw
+cGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjogIikpCmU9Zy5hCkwua0QoZixlPT1udWxsPyJ1bmtu
+b3duIjplKX19fSwKa0Q6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9SC5WTShiLnNwbGl0KCIuIiksdS5z
+KSxxPUMuTm0uZ3RIKHIpLHA9ZG9jdW1lbnQKYS5hcHBlbmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKHEp
+KQpmb3IocT1ILnFDKHIsMSxudWxsLHUuTikscT1uZXcgSC5hNyhxLHEuZ0EocSkscS4kdGkuQygiYTc8
+YUwuRT4iKSksdD1KLlJFKGEpO3EuRigpOyl7cz1xLmQKdC5ueihhLCJiZWZvcmVlbmQiLCImIzgyMDM7
+LiIsbnVsbCxudWxsKQphLmFwcGVuZENoaWxkKHAuY3JlYXRlVGV4dE5vZGUocykpfX0sCmU6ZnVuY3Rp
+b24gZSgpe30sClZXOmZ1bmN0aW9uIFZXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+Cm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6ZnVuY3Rpb24ganIoKXt9LApxbDpmdW5jdGlvbiBxbCgpe30s
+Cnk4OmZ1bmN0aW9uIHk4KCl7fSwKSGk6ZnVuY3Rpb24gSGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30s
+Ckw6ZnVuY3Rpb24gTCgpe30sCld4OmZ1bmN0aW9uIFd4KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApB
+TzpmdW5jdGlvbiBBTyhhKXt0aGlzLmE9YX0sCmROOmZ1bmN0aW9uIGROKGEpe3RoaXMuYT1hfSwKSG86
+ZnVuY3Rpb24gSG8oYSl7dGhpcy5hPWF9LAp4ejpmdW5jdGlvbiB4eihhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKSUM6ZnVuY3Rpb24gSUMoKXt9LApMMTpmdW5jdGlvbiBMMShhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKQlo6
+ZnVuY3Rpb24gQlooYSl7dGhpcy5hPWF9LApHSDpmdW5jdGlvbiBHSCgpe30sCkRUOmZ1bmN0aW9uIERU
+KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmVIOmZ1bmN0aW9uIGVIKGEpe3RoaXMu
+YT1hfSwKeXU6ZnVuY3Rpb24geXUoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uZD1kCl8uZT1lfSwKekQ6ZnVuY3Rpb24gekQoYSl7dGhpcy5hPWF9LApUVzpmdW5jdGlvbiBUVygp
+e30sCnhyOmZ1bmN0aW9uIHhyKGEpe3RoaXMuYT1hfSwKRUU6ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMu
+YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVuY3Rpb24gUUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1hfSwKVEQ6ZnVuY3Rpb24gVEQoKXt9LApYQTpmdW5j
+dGlvbiBYQSgpe30sCm1LOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuPUguVk0oW10sdS5maCkK
+Zm9yKHQ9Si5JVCh1LlIuYihhKSk7dC5GKCk7KXtzPXQuZ2woKQpyPUouVTYocykKcT1MLnAyKEguYzAo
+ci5xKHMsInR5cGUiKSkpCnA9SC5jMChyLnEocywibmFtZSIpKQpvPXIucShzLCJzdWJ0cmVlIikKbz1v
+PT1udWxsP251bGw6TC5tSyhvKQpDLk5tLmkobixuZXcgTC5aWihxLHAsbyxILmMwKHIucShzLCJwYXRo
+IikpLEguYzAoci5xKHMsImhyZWYiKSksSC5XWShyLnEocywiZWRpdENvdW50IikpKSl9cmV0dXJuIG59
+LApwMjpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSJkaXJlY3RvcnkiOnJldHVybiBDLlkyCmNhc2Ui
+ZmlsZSI6cmV0dXJuIEMucmYKZGVmYXVsdDp0aHJvdyBILmIoUC5QVigiVW5yZWNvZ25pemVkIG5hdmln
+YXRpb24gdHJlZSBub2RlIHR5cGU6ICIrSC5kKGEpKSl9fSwKWlo6ZnVuY3Rpb24gWlooYSxiLGMsZCxl
+LGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApPOTpmdW5j
+dGlvbiBPOShhKXt0aGlzLmI9YX0sCklWOmZ1bmN0aW9uIElWKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5k
+PWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxNPXsKWUY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8s
+bgpmb3IodD1iLmxlbmd0aCxzPTE7czx0Oysrcyl7aWYoYltzXT09bnVsbHx8YltzLTFdIT1udWxsKWNv
+bnRpbnVlCmZvcig7dD49MTt0PXIpe3I9dC0xCmlmKGJbcl0hPW51bGwpYnJlYWt9cT1uZXcgUC5Sbigi
+IikKcD1hKyIoIgpxLmE9cApvPUgucUMoYiwwLHQsSC50NihiKS5kKQpuPW8uJHRpCm49cCtuZXcgSC5B
+OChvLG4uQygicVUoYUwuRSkiKS5iKG5ldyBNLk5vKCkpLG4uQygiQTg8YUwuRSxxVT4iKSkuelYoMCwi
+LCAiKQpxLmE9bgpxLmE9bisoIik6IHBhcnQgIisocy0xKSsiIHdhcyBudWxsLCBidXQgcGFydCAiK3Mr
+IiB3YXMgbm90LiIpCnRocm93IEguYihQLnhZKHEudygwKSkpfX0sCmxJOmZ1bmN0aW9uIGxJKGEpe3Ro
+aXMuYT1hfSwKTWk6ZnVuY3Rpb24gTWkoKXt9LApxNzpmdW5jdGlvbiBxNygpe30sCk5vOmZ1bmN0aW9u
+IE5vKCl7fX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWIueFooYSkKYi5oSyhh
+KQppZihvIT1udWxsKWE9Si5LVihhLG8ubGVuZ3RoKQp0PXUucwpzPUguVk0oW10sdCkKcj1ILlZNKFtd
+LHQpCnQ9YS5sZW5ndGgKaWYodCE9PTAmJmIucjQoQy54Qi5XKGEsMCkpKXtpZigwPj10KXJldHVybiBI
+Lk9IKGEsMCkKQy5ObS5pKHIsYVswXSkKcT0xfWVsc2V7Qy5ObS5pKHIsIiIpCnE9MH1mb3IocD1xO3A8
+dDsrK3ApaWYoYi5yNChDLnhCLlcoYSxwKSkpe0MuTm0uaShzLEMueEIuTmooYSxxLHApKQpDLk5tLmko
+cixhW3BdKQpxPXArMX1pZihxPHQpe0MuTm0uaShzLEMueEIuRyhhLHEpKQpDLk5tLmkociwiIil9cmV0
+dXJuIG5ldyBYLldEKGIsbyxzLHIpfSwKV0Q6ZnVuY3Rpb24gV0QoYSxiLGMsZCl7dmFyIF89dGhpcwpf
+LmE9YQpfLmI9YgpfLmQ9YwpfLmU9ZH0sCnFSOmZ1bmN0aW9uIHFSKGEpe3RoaXMuYT1hfSwKSTc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7dGhpcy5hPWF9fSxP
+PXsKUmg6ZnVuY3Rpb24oKXt2YXIgdCxzPW51bGwKaWYoUC51bygpLmdGaSgpIT09ImZpbGUiKXJldHVy
+biAkLkViKCkKdD1QLnVvKCkKaWYoIUMueEIuVGModC5nSWkodCksIi8iKSlyZXR1cm4gJC5FYigpCmlm
+KFAuS0wocywiYS9iIixzLHMscyxzLHMpLnQ0KCk9PT0iYVxcYiIpcmV0dXJuICQuS2soKQpyZXR1cm4g
+JC5iRCgpfSwKekw6ZnVuY3Rpb24gekwoKXt9fSxFPXtPRjpmdW5jdGlvbiBPRihhLGIsYyl7dGhpcy5k
+PWEKdGhpcy5lPWIKdGhpcy5mPWN9fSxGPXtydTpmdW5jdGlvbiBydShhLGIsYyxkKXt2YXIgXz10aGlz
+Cl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sRD17ClJYOmZ1bmN0aW9uKCl7dmFyIHQscyxyPVAudW8o
+KQppZihKLlJNKHIsJC5JNikpcmV0dXJuICQuRmYKJC5JNj1yCmlmKCQuSGsoKT09JC5FYigpKXJldHVy
+biAkLkZmPXIuWkkoIi4iKS53KDApCmVsc2V7dD1yLnQ0KCkKcz10Lmxlbmd0aC0xCnJldHVybiAkLkZm
+PXM9PT0wP3Q6Qy54Qi5Oaih0LDAscyl9fSwKbnI6ZnVuY3Rpb24oYSxiKXt2YXIgdD1udWxsCnJldHVy
+biAkLm5VKCkucTcoMCxhLGIsdCx0LHQsdCx0LHQpfX0KdmFyIHc9W0MsSCxKLFAsVyxVLEIsVCxMLE0s
+WCxPLEUsRixEXQpodW5rSGVscGVycy5zZXRGdW5jdGlvbk5hbWVzSWZOZWNlc3NhcnkodykKdmFyICQ9
+e30KSC5lby5wcm90b3R5cGU9e30KSi52Qi5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVy
+biBhPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0sCnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIkluc3RhbmNlIG9mICciK0guZChILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmIo
+YikKdGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5
+cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IGE/NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi5ZRS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIp
+e3JldHVybiBudWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24o
+YSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdS5vLmIoYikpfSwK
+JGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90
+b3R5cGU9e30KSi5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PWFbJC53KCldCmlmKHQ9
+PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILmQo
+Si5qKHQpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJue2Z1bmM6MSxvcHQ6WywsLCwsLCwsLCwsLCwsLCxd
+fX0sCiRpRUg6MX0KSi5qZC5wcm90b3R5cGU9ewppOmZ1bmN0aW9uKGEsYil7SC50NihhKS5kLmIoYikK
+aWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImFkZCIpKQphLnB1c2goYil9LApXNDpmdW5jdGlv
+bihhLGIpe3ZhciB0CmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVBdCIpKQp0PWEu
+bGVuZ3RoCmlmKGI+PXQpdGhyb3cgSC5iKFAueChiLG51bGwpKQpyZXR1cm4gYS5zcGxpY2UoYiwxKVsw
+XX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKSC50NihhKS5DKCJjWDwxPiIpLmIoYykKaWYo
+ISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImluc2VydEFsbCIpKQp0PWEubGVuZ3RoClAud0EoYiww
+LHQsImluZGV4IikKcz1jLmxlbmd0aAp0aGlzLnNBKGEsdCtzKQpyPWIrcwp0aGlzLllXKGEscixhLmxl
+bmd0aCxhLGIpCnRoaXMudmcoYSxiLHIsYyl9LAptdjpmdW5jdGlvbihhKXtpZighIWEuZml4ZWQkbGVu
+Z3RoKUgudmgoUC5MNCgicmVtb3ZlTGFzdCIpKQppZihhLmxlbmd0aD09PTApdGhyb3cgSC5iKEguSFko
+YSwtMSkpCnJldHVybiBhLnBvcCgpfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApILnQ2KGEpLkMoImNY
+PDE+IikuYihiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkQWxsIikpCmZvcih0PUou
+SVQoYik7dC5GKCk7KWEucHVzaCh0LmdsKCkpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50Nihh
+KS5DKCJ+KDEpIikuYihiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysrcyl7Yi4kMShhW3NdKQppZihh
+Lmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1I
+LnQ2KGEpCnJldHVybiBuZXcgSC5BOChhLHQuS3EoYykuQygiMSgyKSIpLmIoYiksdC5DKCJAPDE+Iiku
+S3EoYykuQygiQTg8MSwyPiIpKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1uZXcgQXJyYXkoYS5s
+ZW5ndGgpCnMuZml4ZWQkbGVuZ3RoPUFycmF5CmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpdGhpcy5ZKHMs
+dCxILmQoYVt0XSkpCnJldHVybiBzLmpvaW4oYil9LApOMDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHIKZC5iKGIpCkgudDYoYSkuS3EoZCkuQygiMSgxLDIpIikuYihjKQp0PWEubGVuZ3RoCmZvcihzPWIs
+cj0wO3I8dDsrK3Ipe3M9Yy4kMihzLGFbcl0pCmlmKGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChh
+KSl9cmV0dXJuIHN9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5P
+SChhLGIpCnJldHVybiBhW2JdfSwKRDY6ZnVuY3Rpb24oYSxiLGMpe2lmKGI8MHx8Yj5hLmxlbmd0aCl0
+aHJvdyBILmIoUC5URShiLDAsYS5sZW5ndGgsInN0YXJ0IixudWxsKSkKaWYoYzxifHxjPmEubGVuZ3Ro
+KXRocm93IEguYihQLlRFKGMsYixhLmxlbmd0aCwiZW5kIixudWxsKSkKaWYoYj09PWMpcmV0dXJuIEgu
+Vk0oW10sSC50NihhKSkKcmV0dXJuIEguVk0oYS5zbGljZShiLGMpLEgudDYoYSkpfSwKZ3RIOmZ1bmN0
+aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJuIGFbMF0KdGhyb3cgSC5iKEguV3AoKSl9LApnclo6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD4wKXJldHVybiBhW3QtMV0KdGhyb3cgSC5iKEguV3Ao
+KSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscj1ILnQ2KGEpCnIuQygiY1g8MT4iKS5i
+KGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoInNldFJhbmdlIikpClAuakIoYixjLGEu
+bGVuZ3RoKQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5rMShlLCJza2lwQ291bnQiKQpyLkMoInpNPDE+
+IikuYihkKQpyPUouVTYoZCkKaWYoZSt0PnIuZ0EoZCkpdGhyb3cgSC5iKEguYXIoKSkKaWYoZTxiKWZv
+cihzPXQtMTtzPj0wOy0tcylhW2Irc109ci5xKGQsZStzKQplbHNlIGZvcihzPTA7czx0OysrcylhW2Ir
+c109ci5xKGQsZStzKX0sCnZnOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLllXKGEsYixjLGQs
+MCl9LApWcjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50NihhKS5DKCJhMigxKSIpLmIoYikKdD1hLmxl
+bmd0aApmb3Iocz0wO3M8dDsrK3Mpe2lmKEgub1QoYi4kMShhW3NdKSkpcmV0dXJuITAKaWYoYS5sZW5n
+dGghPT10KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4hMX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQK
+Zm9yKHQ9MDt0PGEubGVuZ3RoOysrdClpZihKLlJNKGFbdF0sYikpcmV0dXJuITAKcmV0dXJuITF9LAp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LApna3o6ZnVuY3Rpb24oYSl7cmV0dXJu
+IG5ldyBKLm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXty
+ZXR1cm4gSC5lUShhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9u
+KGEsYil7aWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInNldCBsZW5ndGgiKSkKaWYoYjwwKXRo
+cm93IEguYihQLlRFKGIsMCxudWxsLCJuZXdMZW5ndGgiLG51bGwpKQphLmxlbmd0aD1ifSwKcTpmdW5j
+dGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQpy
+ZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuZC5iKGMpCmlmKCEhYS5pbW11dGFi
+bGUkbGlzdClILnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cg
+SC5iKEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5
+cGU9e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0
+aW9uKCl7dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJvdyBILmIoSC5s
+ayhyKSkKdD1zLmMKaWYodD49cSl7cy5zSChudWxsKQpyZXR1cm4hMX1zLnNIKHJbdF0pOysrcy5jCnJl
+dHVybiEwfSwKc0g6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSi5x
+SS5wcm90b3R5cGU9ewp5dTpmdW5jdGlvbihhKXt2YXIgdAppZihhPj0tMjE0NzQ4MzY0OCYmYTw9MjE0
+NzQ4MzY0NylyZXR1cm4gYXwwCmlmKGlzRmluaXRlKGEpKXt0PWE8MD9NYXRoLmNlaWwoYSk6TWF0aC5m
+bG9vcihhKQpyZXR1cm4gdCswfXRocm93IEguYihQLkw0KCIiK2ErIi50b0ludCgpIikpfSwKelE6ZnVu
+Y3Rpb24oYSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEpfWVsc2UgaWYoYT4t
+MS8wKXJldHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIithKyIucm91bmQoKSIp
+KX0sCldaOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYoYjwyfHxiPjM2KXRocm93IEguYihQLlRF
+KGIsMiwzNiwicmFkaXgiLG51bGwpKQp0PWEudG9TdHJpbmcoYikKaWYoQy54Qi5tKHQsdC5sZW5ndGgt
+MSkhPT00MSlyZXR1cm4gdApzPS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/XChlXCsoXGQrKVwp
+JC8uZXhlYyh0KQppZihzPT1udWxsKUgudmgoUC5MNCgiVW5leHBlY3RlZCB0b1N0cmluZyByZXN1bHQ6
+ICIrdCkpCnI9cy5sZW5ndGgKaWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sxXQppZigzPj1yKXJl
+dHVybiBILk9IKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1y
+ZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVy
+biItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAK
+aWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5
+MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcw
+OTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5Nytz
+KjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09MClyZXR1cm4gMAppZih0PjAp
+cmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxi
+KXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJl
+dHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0
+aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEs
+CiRpRks6MX0KSi51ci5wcm90b3R5cGU9eyRpS046MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90
+b3R5cGU9ewptOmZ1bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikpCmlmKGI+PWEu
+bGVuZ3RoKUgudmgoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihh
+LGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQo
+Yil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEs
+Yil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRocm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJu
+IGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5sZW5ndGgscz1hLmxlbmd0aAppZih0PnMpcmV0
+dXJuITEKcmV0dXJuIGI9PT10aGlzLkcoYSxzLXQpfSwKaTc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
+cwpjPVAuakIoYixjLGEubGVuZ3RoKQp0PWEuc3Vic3RyaW5nKDAsYikKcz1hLnN1YnN0cmluZyhjKQpy
+ZXR1cm4gdCtkK3N9LApRaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIUgub2soYykpSC52aChILnRM
+KGMpKQppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8fGM+YS5sZW5ndGgp
+dGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxlbmd0aAppZih0PmEu
+bGVuZ3RoKXJldHVybiExCnJldHVybiBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoIUgub2soYikpSC52
+aChILnRMKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0ibnVtYmVyIilyZXR1
+cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLngo
+YixudWxsKSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0
+cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixudWxsKX0sCmhjOmZ1
+bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIs
+cT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMuVyhxLDApPT09MTMz
+KXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpyPXRoaXMubShxLHMp
+PT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1cm4gcS5zdWJzdHJp
+bmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVybiIiCmlmKGI9PT0x
+fHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVxKQpmb3IodD1h
+LHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MClicmVhawp0Kz10fXJl
+dHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBI
+LmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixjKQpyZXR1cm4gdH0s
+Ck9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93
+IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9YS5sZW5ndGgKaWYo
+Yyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWEubGVuZ3RoCmlm
+KGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5tMihhLGIsYyl9LAp0
+ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9MCxyPTA7cjx0Oysr
+cil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcysoKDUyNDI4NyZzKTw8
+MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1zPj4xMQpyZXR1cm4g
+NTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
+fSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93IEguYihILkhZ
+KGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIu
+bSh0aGlzLmEsSC5TYyhiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17Cmdrejpm
+dW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ0EodCksSC5MaCh0KS5DKCJh
+NzxhTC5FPiIpKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYo
+Yi5sZW5ndGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUguZChxLkUoMCwwKSkKaWYocCE9PXEuZ0Eo
+cSkpdGhyb3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guZChxLkUoMCxy
+KSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9
+PTA/czpzfWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLkUoMCxyKSkKaWYocCE9PXEu
+Z0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYihi
+KSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguQTgodGhp
+cyx0LktxKGMpLkMoIjEoYUwuRSkiKS5iKGIpLHQuQygiQDxhTC5FPiIpLktxKGMpLkMoIkE4PDEsMj4i
+KSl9fQpILm5ILnByb3RvdHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRo
+aXMuYwppZihzPT1udWxsfHxzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQXM6ZnVuY3Rpb24oKXt2YXIg
+dD1KLkhtKHRoaXMuYSkscz10aGlzLmIKaWYocz50KXJldHVybiB0CnJldHVybiBzfSwKZ0E6ZnVuY3Rp
+b24oYSl7dmFyIHQscz1KLkhtKHRoaXMuYSkscj10aGlzLmIKaWYocj49cylyZXR1cm4gMAp0PXRoaXMu
+YwppZih0PT1udWxsfHx0Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4g
+dC5ITigpCnJldHVybiB0LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5nQXMoKSti
+CmlmKGI+PTApe3Q9cy5nVUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiBILnBZKHQpCnQ9
+cj49dH1lbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpy
+ZXR1cm4gSi5HQShzLmEscil9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQpp
+ZihzLmIhPT1wKXRocm93IEguYihQLmE0KHIpKQp0PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVy
+biExfXMuc0kocS5FKHIsdCkpOysrcy5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRo
+aXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFy
+IHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguTUgoSi5JVCh0aGlzLmEpLHRoaXMuYix0LkMoIkA8MT4i
+KS5LcSh0LmNoWzFdKS5DKCJNSDwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhp
+cy5hKX19CkgueHkucHJvdG90eXBlPXskaWJROjF9CkguTUgucHJvdG90eXBlPXsKRjpmdW5jdGlvbigp
+e3ZhciB0PXRoaXMscz10LmIKaWYocy5GKCkpe3Quc0kodC5jLiQxKHMuZ2woKSkpCnJldHVybiEwfXQu
+c0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9LApzSTpmdW5jdGlv
+bihhKXt0aGlzLmE9dGhpcy4kdGkuY2hbMV0uYihhKX19CkguQTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouSG0odGhpcy5hKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5iLiQx
+KEouR0EodGhpcy5hLGIpKX19CkguVTUucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgSC5TTyhKLklUKHRoaXMuYSksdGhpcy5iLHRoaXMuJHRpLkMoIlNPPDE+IikpfX0KSC5TTy5wcm90
+b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQscwpmb3IodD10aGlzLmEscz10aGlzLmI7dC5GKCk7KWlm
+KEgub1Qocy4kMSh0LmdsKCkpKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuYS5nbCgpfX0KSC5TVS5wcm90b3R5cGU9e30KSC5SZS5wcm90b3R5cGU9ewpZOmZ1bmN0aW9u
+KGEsYixjKXtILkxoKHRoaXMpLkMoIlJlLkUiKS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9k
+aWZ5IGFuIHVubW9kaWZpYWJsZSBsaXN0IikpfX0KSC5YQy5wcm90b3R5cGU9e30KSC53di5wcm90b3R5
+cGU9ewpnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5faGFzaENvZGUKaWYodCE9bnVsbClyZXR1cm4g
+dAp0PTUzNjg3MDkxMSY2NjQ1OTcqSi5oZih0aGlzLmEpCnRoaXMuX2hhc2hDb2RlPXQKcmV0dXJuIHR9
+LAp3OmZ1bmN0aW9uKGEpe3JldHVybidTeW1ib2woIicrSC5kKHRoaXMuYSkrJyIpJ30sCkROOmZ1bmN0
+aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIEgud3YmJnRoaXMu
+YT09Yi5hfSwKJGlHRDoxfQpILlBELnByb3RvdHlwZT17fQpILldVLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMp
+CnQuZC5iKGIpCnQuY2hbMV0uYihjKQpyZXR1cm4gSC5kYygpfSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLnE0KGEsSC5MaCh0aGlzKS5DKCJOMzwxLDI+IikpfSwKcTQ6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9uKCl7dmFyIHM9YQp2YXIgcj0wLHE9MSxwLG8sbixtCnJl
+dHVybiBmdW5jdGlvbiAkYXN5bmMkZ1B1KGMsZCl7aWYoYz09PTEpe3A9ZApyPXF9d2hpbGUodHJ1ZSlz
+d2l0Y2gocil7Y2FzZSAwOm89dC5nVigpLG89by5na3oobyksbj1ILkxoKHQpLG49bi5DKCJAPDE+Iiku
+S3Eobi5jaFsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighby5GKCkpe3I9MwpicmVha31tPW8uZ2wo
+KQpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sdC5xKDAsbSksbikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6
+cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0ocCl9fX0sYil9LAokaVowOjF9CkguTFAucHJv
+dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5
+cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJu
+IHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSly
+ZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5EKGIpfSwKRDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0gu
+eShhKV19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIp
+IikuYihiKQp0PXRoaXMuYwpmb3Iocz10Lmxlbmd0aCxwPXAuY2hbMV0scj0wO3I8czsrK3Ipe3E9dFty
+XQpiLiQyKHEscC5iKHRoaXMuRChxKSkpfX0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILlhSKHRo
+aXMsSC5MaCh0aGlzKS5DKCJYUjwxPiIpKX19CkguWFIucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYS5jCnJldHVybiBuZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4i
+KSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmMubGVuZ3RofX0KSC5MSS5wcm90b3R5cGU9
+ewpnV2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApnbmQ6ZnVuY3Rpb24oKXt2YXIg
+dCxzLHIscSxwPXRoaXMKaWYocC5jPT09MSlyZXR1cm4gQy5kbgp0PXAuZApzPXQubGVuZ3RoLXAuZS5s
+ZW5ndGgtcC5mCmlmKHM9PT0wKXJldHVybiBDLmRuCnI9W10KZm9yKHE9MDtxPHM7KytxKXtpZihxPj10
+Lmxlbmd0aClyZXR1cm4gSC5PSCh0LHEpCnIucHVzaCh0W3FdKX1yZXR1cm4gSi56QyhyKX0sCmdWbTpm
+dW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCmlmKGwuYyE9PTApcmV0dXJuIEMuRHgK
+dD1sLmUKcz10Lmxlbmd0aApyPWwuZApxPXIubGVuZ3RoLXMtbC5mCmlmKHM9PT0wKXJldHVybiBDLkR4
+CnA9bmV3IEguTjUodS5lbykKZm9yKG89MDtvPHM7KytvKXtpZihvPj10Lmxlbmd0aClyZXR1cm4gSC5P
+SCh0LG8pCm49dFtvXQptPXErbwppZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILk9IKHIsbSkKcC5Z
+KDAsbmV3IEgud3YobiksclttXSl9cmV0dXJuIG5ldyBILlBEKHAsdS5nRil9LAokaXZROjF9CkguQ2ou
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdApILnkoYSkKdD10aGlzLmEKdC5iPXQuYisi
+JCIrSC5kKGEpCkMuTm0uaSh0aGlzLmIsYSkKQy5ObS5pKHRoaXMuYyxiKTsrK3QuYX0sCiRTOjEzfQpI
+LmY5LnByb3RvdHlwZT17CnFTOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9bmV3IFJlZ0V4cChy
+LmEpLmV4ZWMoYSkKaWYocT09bnVsbClyZXR1cm4gbnVsbAp0PU9iamVjdC5jcmVhdGUobnVsbCkKcz1y
+LmIKaWYocyE9PS0xKXQuYXJndW1lbnRzPXFbcysxXQpzPXIuYwppZihzIT09LTEpdC5hcmd1bWVudHNF
+eHByPXFbcysxXQpzPXIuZAppZihzIT09LTEpdC5leHByPXFbcysxXQpzPXIuZQppZihzIT09LTEpdC5t
+ZXRob2Q9cVtzKzFdCnM9ci5mCmlmKHMhPT0tMSl0LnJlY2VpdmVyPXFbcysxXQpyZXR1cm4gdH19Ckgu
+VzAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4i
+Tm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBt
+ZXRob2Qgbm90IGZvdW5kOiAnIit0KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3ZhciB0LHM9dGhpcyxyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDog
+JyIscT1zLmIKaWYocT09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHMuYSkKdD1z
+LmMKaWYodD09bnVsbClyZXR1cm4gcitxKyInICgiK0guZChzLmEpKyIpIgpyZXR1cm4gcitxKyInIG9u
+ICciK3QrIicgKCIrSC5kKHMuYSkrIikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Zh
+ciB0PXRoaXMuYQpyZXR1cm4gdC5sZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3R9fQpILmJxLnBy
+b3RvdHlwZT17fQpILkFtLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUuYlUuYyhhKSlpZihh
+LiR0aHJvd25Kc0Vycm9yPT1udWxsKWEuJHRocm93bkpzRXJyb3I9dGhpcy5hCnJldHVybiBhfSwKJFM6
+NH0KSC5YTy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKHMhPW51bGwp
+cmV0dXJuIHMKcz10aGlzLmEKdD1zIT09bnVsbCYmdHlwZW9mIHM9PT0ib2JqZWN0Ij9zLnN0YWNrOm51
+bGwKcmV0dXJuIHRoaXMuYj10PT1udWxsPyIiOnR9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpm
+dW5jdGlvbihhKXt2YXIgdD10aGlzLmNvbnN0cnVjdG9yLHM9dD09bnVsbD9udWxsOnQubmFtZQpyZXR1
+cm4iQ2xvc3VyZSAnIitILk5RKHM9PW51bGw/InVua25vd24iOnMpKyInIn0sCiRpRUg6MSwKZ1FsOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlw
+ZT17fQpILnp4LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy4kc3RhdGljX25hbWUK
+aWYodD09bnVsbClyZXR1cm4iQ2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJD
+bG9zdXJlICciK0guTlEodCkrIicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3Zh
+ciB0PXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZih0PT09YilyZXR1cm4hMAppZighKGIgaW5zdGFu
+Y2VvZiBILnJUKSlyZXR1cm4hMQpyZXR1cm4gdC5hPT09Yi5hJiZ0LmI9PT1iLmImJnQuYz09PWIuY30s
+CmdpTzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYwppZihzPT1udWxsKXQ9SC5lUSh0aGlzLmEpCmVs
+c2UgdD10eXBlb2YgcyE9PSJvYmplY3QiP0ouaGYocyk6SC5lUShzKQpyZXR1cm4odF5ILmVRKHRoaXMu
+YikpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpdD10aGlzLmEKcmV0
+dXJuIkNsb3N1cmUgJyIrSC5kKHRoaXMuZCkrIicgb2YgIisoIkluc3RhbmNlIG9mICciK0guZChILk0o
+dCkpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJv
+cjogIitILmQodGhpcy5hKX19Ckgua1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQXNz
+ZXJ0aW9uIGZhaWxlZDogIitQLnAodGhpcy5hKX19CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuYX0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILmk1KHRoaXMsSC5MaCh0
+aGlzKS5DKCJpNTwxPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYodHlwZW9mIGE9PSJzdHJp
+bmciKXt0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLlh1KHQsYSl9ZWxzZXtz
+PXRoaXMuQ1goYSkKcmV0dXJuIHN9fSwKQ1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51
+bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuRmgodGhpcy5CdCh0LEouaGYoYSkmMHgzZmZmZmZmKSxhKT49
+MH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1udWxsCmlmKHR5cGVvZiBiPT0i
+c3RyaW5nIil7dD1wLmIKaWYodD09bnVsbClyZXR1cm4gbwpzPXAuajIodCxiKQpyPXM9PW51bGw/bzpz
+LmIKcmV0dXJuIHJ9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtx
+PXAuYwppZihxPT1udWxsKXJldHVybiBvCnM9cC5qMihxLGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4g
+cn1lbHNlIHJldHVybiBwLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMuZAppZihy
+PT1udWxsKXJldHVybiBudWxsCnQ9dGhpcy5CdChyLEouaGYoYSkmMHgzZmZmZmZmKQpzPXRoaXMuRmgo
+dCxhKQppZihzPDApcmV0dXJuIG51bGwKcmV0dXJuIHRbc10uYn0sClk6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbyxuPXRoaXMsbT1ILkxoKG4pCm0uZC5iKGIpCm0uY2hbMV0uYihjKQppZih0eXBl
+b2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRUgodD09bnVsbD9uLmI9bi56SygpOnQsYixjKX1lbHNlIGlm
+KHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3M9bi5jCm4uRUgocz09bnVsbD9u
+LmM9bi56SygpOnMsYixjKX1lbHNle3I9bi5kCmlmKHI9PW51bGwpcj1uLmQ9bi56SygpCnE9Si5oZihi
+KSYweDNmZmZmZmYKcD1uLkJ0KHIscSkKaWYocD09bnVsbCluLkVJKHIscSxbbi5IbihiLGMpXSkKZWxz
+ZXtvPW4uRmgocCxiKQppZihvPj0wKXBbb10uYj1jCmVsc2UgcC5wdXNoKG4uSG4oYixjKSl9fX0sCks6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLkMoIn4oMSwyKSIpLmIoYikKdD1yLmUK
+cz1yLnIKZm9yKDt0IT1udWxsOyl7Yi4kMih0LmEsdC5iKQppZihzIT09ci5yKXRocm93IEguYihQLmE0
+KHIpKQp0PXQuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLHI9SC5MaChzKQpyLmQu
+YihiKQpyLmNoWzFdLmIoYykKdD1zLmoyKGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykp
+CmVsc2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5ldyBILmRiKHIuZC5iKGEpLHIuY2hb
+MV0uYihiKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cQplbHNle3Q9cy5mCnEuZD10CnMuZj10LmM9cX0r
+K3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbCly
+ZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4g
+cwpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApqMjpmdW5jdGlvbihh
+LGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkVJOmZ1bmN0aW9u
+KGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2RlbGV0ZSBhW2JdfSwKWHU6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6ZnVuY3Rpb24oKXt2YXIgdD0iPG5vbi1p
+ZGVudGlmaWVyLWtleT4iLHM9T2JqZWN0LmNyZWF0ZShudWxsKQp0aGlzLkVJKHMsdCxzKQp0aGlzLnJu
+KHMsdCkKcmV0dXJuIHN9LAokaUZvOjF9CkguZGIucHJvdG90eXBlPXt9CkguaTUucHJvdG90eXBlPXsK
+Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
+YSxzPW5ldyBILk42KHQsdC5yLHRoaXMuJHRpLkMoIk42PDE+IikpCnMuYz10LmUKcmV0dXJuIHN9LAp0
+ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpILk42LnByb3RvdHlwZT17CmdsOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQu
+YiE9PXMucil0aHJvdyBILmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNxWShudWxs
+KQpyZXR1cm4hMX1lbHNle3Quc3FZKHMuYSkKdC5jPXQuYy5jCnJldHVybiEwfX19LApzcVk6ZnVuY3Rp
+b24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5kQy5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEpfSwKJFM6NH0KSC53Ti5wcm90b3R5cGU9ewokMjpmdW5j
+dGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxiKX0sCiRTOjQ3fQpILlZYLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC55KGEpKX0sCiRTOjQyfQpILlZSLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1
+bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwppZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0
+LmM9SC52NCh0LmEscy5tdWx0aWxpbmUsIXMuaWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITAp
+fSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5sYXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxs
+KXJldHVybiBudWxsCnJldHVybiBuZXcgSC5FSyh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3Rv
+dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3Ro
+KXJldHVybiBILk9IKHQsYikKcmV0dXJuIHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5
+cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19
+CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigp
+e3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYgppZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8u
+bGVuZ3RoKXtzPXAuYQpyPXMuVVoobyx0KQppZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgK
+cT10K29bMF0ubGVuZ3RoCmlmKHQ9PT1xKXtpZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIK
+aWYodDxzLmxlbmd0aCl7bz1KLnJZKHMpLm0ocyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54
+Qi5tKHMsdCkKbz1vPj01NjMyMCYmbzw9NTczNDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEK
+cT0obz9xKzE6cSkrMX1wLmM9cQpyZXR1cm4hMH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjox
+fQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGIhPT0wKUgudmgoUC54
+KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlw
+ZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5h
+LG09bi5sZW5ndGgKaWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYo
+dDwwKXtyLmM9bSsxCnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1z
+PT09ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjox
+fQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5iMC5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
+bihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
+LGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIs
+Yyl7SC5JZyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06
+MX0KSC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILlNjKGMpCkgub2QoYixhLGEubGVu
+Z3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVu
+Y3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJv
+dG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBh
+W2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxl
+bmd0aCkKcmV0dXJuIGFbYl19fQpILndmLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIp
+Ckgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlv
+bihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5
+cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhi
+KQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0
+aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEu
+bGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQ
+LnByb3RvdHlwZT17fQpILldCLnByb3RvdHlwZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3Rv
+dHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktx
+OmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkcucHJvdG90
+eXBlPXt9CkgudTkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfX0KSC5oei5w
+cm90b3R5cGU9e30KSC5pTS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
+KXt2YXIgdD10aGlzLmEscz10LmEKdC5hPW51bGwKcy4kMCgpfSwKJFM6MTJ9ClAuaGEucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp0aGlzLmEuYT11Lk0uYihhKQp0PXRoaXMuYgpzPXRoaXMu
+Ywp0LmZpcnN0Q2hpbGQ/dC5yZW1vdmVDaGlsZChzKTp0LmFwcGVuZENoaWxkKHMpfSwKJFM6Mzd9ClAu
+VnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRT
+OjB9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRS
+OjAsCiRTOjB9ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVv
+dXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRo
+cm93IEguYihQLkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5paC5wcm90
+b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzLiR0aQpyLkMoIjEvIikuYihiKQp0
+PSF0aGlzLmJ8fHIuQygiYjg8MT4iKS5jKGIpCnM9dGhpcy5hCmlmKHQpcy5YZihiKQplbHNlIHMuWDIo
+ci5kLmIoYikpfSwKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYodGhpcy5iKXQuWkwoYSxi
+KQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuYS4kMigwLGEpfSwKJFM6MjF9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlz
+LmEuJDIoMSxuZXcgSC5icShhLHUubC5iKGIpKSl9LAokQzoiJDIiLAokUjoyLAokUzoyNn0KUC5Hcy5w
+cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShILlNjKGEpLGIpfSwKJFM6Mjd9ClAuRnku
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhpcy5iKyIs
+ICIrSC5kKHRoaXMuYSkrIikifX0KUC5HVi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciB0PXRo
+aXMuYwppZih0PT1udWxsKXJldHVybiB0aGlzLmIKcmV0dXJuIHRoaXMuJHRpLmQuYih0LmdsKCkpfSwK
+RjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwpmb3IoOyEwOyl7dD1wLmMKaWYodCE9bnVsbClp
+Zih0LkYoKSlyZXR1cm4hMAplbHNlIHAuYz1udWxsCnM9ZnVuY3Rpb24oYSxiLGMpe3ZhciBvLG49Ygp3
+aGlsZSh0cnVlKXRyeXtyZXR1cm4gYShuLG8pfWNhdGNoKG0pe289bQpuPWN9fShwLmEsMCwxKQppZihz
+IGluc3RhbmNlb2YgUC5GeSl7cj1zLmIKaWYocj09PTIpe3Q9cC5kCmlmKHQ9PW51bGx8fHQubGVuZ3Ro
+PT09MCl7cC5zRUMobnVsbCkKcmV0dXJuITF9aWYoMD49dC5sZW5ndGgpcmV0dXJuIEguT0godCwtMSkK
+cC5hPXQucG9wKCkKY29udGludWV9ZWxzZXt0PXMuYQppZihyPT09Myl0aHJvdyB0CmVsc2V7cT1KLklU
+KHQpCmlmKHEgaW5zdGFuY2VvZiBQLkdWKXt0PXAuZAppZih0PT1udWxsKXQ9cC5kPVtdCkMuTm0uaSh0
+LHAuYSkKcC5hPXEuYQpjb250aW51ZX1lbHNle3AuYz1xCmNvbnRpbnVlfX19fWVsc2V7cC5zRUMocykK
+cmV0dXJuITB9fXJldHVybiExfSwKc0VDOmZ1bmN0aW9uKGEpe3RoaXMuYj10aGlzLiR0aS5kLmIoYSl9
+LAokaUFuOjF9ClAucTQucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0
+aGlzLmEoKSx0aGlzLiR0aS5DKCJHVjwxPiIpKX19ClAuYjgucHJvdG90eXBlPXt9ClAuUGYucHJvdG90
+eXBlPXsKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAubigpCnQ9dGhpcy5h
+CmlmKHQuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQp0Lk5r
+KGEsYil9LApwbTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5
+cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0CnRoaXMuJHRpLkMoIjEvIikuYihiKQp0PXRoaXMuYQpp
+Zih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5YZihi
+KX19ClAuRmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYxNSkhPT02KXJldHVy
+biEwCnJldHVybiB0aGlzLmIuYi5idih1LmFsLmIodGhpcy5kKSxhLmEsdS5jSix1LkspfSwKS3c6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5lLHM9dS56LHI9dS5LLHE9dGhpcy4kdGkuQygiMi8iKSxwPXRoaXMu
+Yi5iCmlmKHUuRi5jKHQpKXJldHVybiBxLmIocC5ycCh0LGEuYSxhLmIscyxyLHUubCkpCmVsc2UgcmV0
+dXJuIHEuYihwLmJ2KHUueS5iKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5iKGEpCnQ9JC5Y
+MwppZih0IT09Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHEuZCkuQygiMSgyKSIpLmIoYSkKaWYoYiE9bnVs
+bCliPVAuVkgoYix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRo
+aXMueGYobmV3IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1
+cm4gc30sClc3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIpLmIoYSkKdD1uZXcgUC52
+cygkLlgzLGMuQygidnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LChiPT1udWxsPzE6Myl8MTYsYSxi
+LHMuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiB0fSwKT0E6ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyCnUuYmYuYihudWxsKQp0PXRoaXMuJHRpCnM9JC5YMwpyPW5ldyBQLnZzKHMsdCkKaWYo
+cyE9PUMuTlUpYT1QLlZIKGEscykKdGhpcy54ZihuZXcgUC5GZShyLDIsbnVsbCxhLHQuQygiQDwxPiIp
+LktxKHQuZCkuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHJ9LAp4ZjpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
+aXMscj1zLmEKaWYocjw9MSl7YS5hPXUueC5iKHMuYykKcy5jPWF9ZWxzZXtpZihyPT09Mil7dD11Ll8u
+YihzLmMpCnI9dC5hCmlmKHI8NCl7dC54ZihhKQpyZXR1cm59cy5hPXIKcy5jPXQuY31QLlRrKG51bGws
+bnVsbCxzLmIsdS5NLmIobmV3IFAuZGEocyxhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
+LHAsbz10aGlzLG49e30Kbi5hPWEKaWYoYT09bnVsbClyZXR1cm4KdD1vLmEKaWYodDw9MSl7cz11Lngu
+YihvLmMpCnI9by5jPWEKaWYocyE9bnVsbCl7Zm9yKDtxPXIuYSxxIT1udWxsO3I9cSk7ci5hPXN9fWVs
+c2V7aWYodD09PTIpe3A9dS5fLmIoby5jKQp0PXAuYQppZih0PDQpe3AualEoYSkKcmV0dXJufW8uYT10
+Cm8uYz1wLmN9bi5hPW8uTjgoYSkKUC5UayhudWxsLG51bGwsby5iLHUuTS5iKG5ldyBQLm9RKG4sbykp
+KX19LAphaDpmdW5jdGlvbigpe3ZhciB0PXUueC5iKHRoaXMuYykKdGhpcy5jPW51bGwKcmV0dXJuIHRo
+aXMuTjgodCl9LApOODpmdW5jdGlvbihhKXt2YXIgdCxzLHIKZm9yKHQ9YSxzPW51bGw7dCE9bnVsbDtz
+PXQsdD1yKXtyPXQuYQp0LmE9c31yZXR1cm4gc30sCkhIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxy
+PXMuJHRpCnIuQygiMS8iKS5iKGEpCmlmKHIuQygiYjg8MT4iKS5jKGEpKWlmKHIuYyhhKSlQLkE5KGEs
+cykKZWxzZSBQLmszKGEscykKZWxzZXt0PXMuYWgoKQpyLmQuYihhKQpzLmE9NApzLmM9YQpQLkhaKHMs
+dCl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCnMuJHRpLmQuYihhKQp0PXMuYWgoKQpzLmE9
+NApzLmM9YQpQLkhaKHMsdCl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcwp1LmwuYihiKQp0
+PXMuYWgoKQpzLmE9OApzLmM9bmV3IFAuQ3coYSxiKQpQLkhaKHMsdCl9LApYZjpmdW5jdGlvbihhKXt2
+YXIgdD10aGlzLHM9dC4kdGkKcy5DKCIxLyIpLmIoYSkKaWYocy5DKCJiODwxPiIpLmMoYSkpe3QuY1Uo
+YSkKcmV0dXJufXQuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYihuZXcgUC5ySCh0LGEpKSl9LApj
+VTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9dC4kdGkKcy5DKCJiODwxPiIpLmIoYSkKaWYocy5jKGEp
+KXtpZihhLmE9PT04KXt0LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmIobmV3IFAuS0YodCxhKSkp
+fWVsc2UgUC5BOShhLHQpCnJldHVybn1QLmszKGEsdCl9LApOazpmdW5jdGlvbihhLGIpe3RoaXMuYT0x
+ClAuVGsobnVsbCxudWxsLHRoaXMuYix1Lk0uYihuZXcgUC5aTCh0aGlzLGEsYikpKX0sCiRpYjg6MX0K
+UC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5hLHRoaXMuYil9LAokUzowfQpQ
+Lm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIsdGhpcy5hLmEpfSwKJFM6MH0K
+UC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKdC5hPTAKdC5ISChhKX0s
+CiRTOjEyfQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dS5sLmIoYikKdGhpcy5hLlpM
+KGEsYil9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJEM6IiQyIiwKJEQ6
+ZnVuY3Rpb24oKXtyZXR1cm5bbnVsbF19LAokUzozMH0KUC52ci5wcm90b3R5cGU9ewokMDpmdW5jdGlv
+bigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuckgucHJvdG90eXBlPXsKJDA6ZnVu
+Y3Rpb24oKXt2YXIgdD10aGlzLmEKdC5YMih0LiR0aS5kLmIodGhpcy5iKSl9LAokUzowfQpQLktGLnBy
+b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwucHJv
+dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLlJU
+LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPW51bGwKdHJ5
+e3I9bi5jCm09ci5iLmIuenoodS5mTy5iKHIuZCksdS56KX1jYXRjaChxKXt0PUguUnUocSkKcz1ILnRz
+KHEpCmlmKG4uZCl7cj11Lm4uYihuLmEuYS5jKS5hCnA9dApwPXI9PW51bGw/cD09bnVsbDpyPT09cApy
+PXB9ZWxzZSByPSExCnA9bi5iCmlmKHIpcC5iPXUubi5iKG4uYS5hLmMpCmVsc2UgcC5iPW5ldyBQLkN3
+KHQscykKcC5hPSEwCnJldHVybn1pZih1LmMuYyhtKSl7aWYobSBpbnN0YW5jZW9mIFAudnMmJm0uYT49
+NCl7aWYobS5hPT09OCl7cj1uLmIKci5iPXUubi5iKG0uYykKci5hPSEwfXJldHVybn1vPW4uYS5hCnI9
+bi5iCnIuYj1tLlc3KG5ldyBQLmpaKG8pLHUueikKci5hPSExfX0sCiRTOjJ9ClAualoucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMzfQpQLnJxLnByb3RvdHlwZT17CiQw
+OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzCnRyeXtyPW0uYgpxPXIuJHRpCnA9cS5k
+Cm89cC5iKG0uYykKbS5hLmI9ci5iLmIuYnYocS5DKCIyLygxKSIpLmIoci5kKSxvLHEuQygiMi8iKSxw
+KX1jYXRjaChuKXt0PUguUnUobikKcz1ILnRzKG4pCnI9bS5hCnIuYj1uZXcgUC5Ddyh0LHMpCnIuYT0h
+MH19LAokUzoyfQpQLlJXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4s
+bSxsPXRoaXMKdHJ5e3Q9dS5uLmIobC5hLmEuYykKcT1sLmMKaWYoSC5vVChxLkhSKHQpKSYmcS5lIT1u
+dWxsKXtwPWwuYgpwLmI9cS5Ldyh0KQpwLmE9ITF9fWNhdGNoKG8pe3M9SC5SdShvKQpyPUgudHMobykK
+cT11Lm4uYihsLmEuYS5jKQpwPXEuYQpuPXMKbT1sLmIKaWYocD09bnVsbD9uPT1udWxsOnA9PT1uKW0u
+Yj1xCmVsc2UgbS5iPW5ldyBQLkN3KHMscikKbS5hPSEwfX0sCiRTOjJ9ClAuT00ucHJvdG90eXBlPXt9
+ClAucWgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQ
+LnZzKCQuWDMsdS5mSikKcS5hPTAKdD1ILkxoKHIpCnM9dC5DKCJ+KDEpIikuYihuZXcgUC5CNShxLHIp
+KQp1Lk0uYihuZXcgUC51TyhxLHApKQpXLkpFKHIuYSxyLmIscywhMSx0LmQpCnJldHVybiBwfX0KUC5C
+NS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILkxoKHRoaXMuYikuZC5iKGEpOysrdGhpcy5hLmF9
+LAokUzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYikuQygiYzgoMSkiKX19ClAudU8ucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmIuSEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5
+cGU9e30KUC5rVC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5Ddy5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBILmQodGhpcy5hKX0sCiRpWFM6MX0KUC5tMC5wcm90b3R5cGU9eyRp
+SkI6MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcy5hLHI9cy5hCnM9
+cj09bnVsbD9zLmE9bmV3IFAubigpOnIKcj10aGlzLmIKaWYocj09bnVsbCl0aHJvdyBILmIocykKdD1I
+LmIocykKdC5zdGFjaz1yLncoMCkKdGhyb3cgdH0sCiRTOjB9ClAuSmkucHJvdG90eXBlPXsKYkg6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHE9bnVsbAp1Lk0uYihhKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDAo
+KQpyZXR1cm59UC5UOChxLHEsdGhpcyxhLHUuSCl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQ
+LkwyKHEscSx0aGlzLHQsdS5sLmIocykpfX0sCkRsOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT1u
+dWxsCmMuQygifigwKSIpLmIoYSkKYy5iKGIpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMShiKQpyZXR1
+cm59UC55dihxLHEsdGhpcyxhLGIsdS5ILGMpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5M
+MihxLHEsdGhpcyx0LHUubC5iKHMpKX19LApSVDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5oaih0
+aGlzLGIuQygiMCgpIikuYihhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5WcCh0aGlz
+LHUuTS5iKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLk9SKHRoaXMsYi5DKCJ+KDAp
+IikuYihhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0sCnp6OmZ1bmN0aW9uKGEsYil7
+Yi5DKCIwKCkiKS5iKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQwKCkKcmV0dXJuIFAuVDgobnVs
+bCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2MuQygiQDwwPiIpLktxKGQpLkMo
+IjEoMikiKS5iKGEpCmQuYihiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMShiKQpyZXR1cm4gUC55
+dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXtkLkMoIkA8
+MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5iKGEpCmUuYihiKQpmLmIoYykKaWYoJC5YMz09PUMu
+TlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGwsdGhpcyxhLGIsYyxkLGUsZil9
+LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+IikuS3EoYykuS3EoZCkuQygiMSgy
+LDMpIikuYihhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLnp6
+KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIjAoKSIpfX0KUC5W
+cC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuYkgodGhpcy5iKX0sCiRTOjJ9
+ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0aGlzLmEu
+RGwodGhpcy5iLHQuYihhKSx0KX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9
+fQpQLmI2LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9bmV3IFAubG0odCx0
+LnIsSC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyIm
+JmIhPT0iX19wcm90b19fIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5KLmIo
+dFtiXSkhPW51bGx9ZWxzZXtzPXRoaXMuUFIoYikKcmV0dXJuIHN9fSwKUFI6ZnVuY3Rpb24oYSl7dmFy
+IHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuREYodFt0aGlzLk4oYSldLGEp
+Pj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCkguTGgocikuZC5iKGIpCmlmKHR5cGVv
+ZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXt0PXIuYgpyZXR1cm4gci5TKHQ9PW51bGw/ci5i
+PVAuVDIoKTp0LGIpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIp
+e3M9ci5jCnJldHVybiByLlMocz09bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhi
+KX0sCkI3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMKSC5MaChxKS5kLmIoYSkKdD1xLmQKaWYo
+dD09bnVsbCl0PXEuZD1QLlQyKCkKcz1xLk4oYSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhh
+KV0KZWxzZXtpZihxLkRGKHIsYSk+PTApcmV0dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwK
+UjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJv
+dG9fXyIpcmV0dXJuIHQuTCh0LmIsYikKZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3
+NDE4MjMpPT09YilyZXR1cm4gdC5MKHQuYyxiKQplbHNlIHJldHVybiB0LnFnKGIpfSwKcWc6ZnVuY3Rp
+b24oYSl7dmFyIHQscyxyLHEscD10aGlzLG89cC5kCmlmKG89PW51bGwpcmV0dXJuITEKdD1wLk4oYSkK
+cz1vW3RdCnI9cC5ERihzLGEpCmlmKHI8MClyZXR1cm4hMQpxPXMuc3BsaWNlKHIsMSlbMF0KaWYoMD09
+PXMubGVuZ3RoKWRlbGV0ZSBvW3RdCnAuR1MocSkKcmV0dXJuITB9LApTOmZ1bmN0aW9uKGEsYil7SC5M
+aCh0aGlzKS5kLmIoYikKaWYodS5KLmIoYVtiXSkhPW51bGwpcmV0dXJuITEKYVtiXT10aGlzLnlvKGIp
+CnJldHVybiEwfSwKTDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuITEKdD11Lkou
+YihhW2JdKQppZih0PT1udWxsKXJldHVybiExCnRoaXMuR1ModCkKZGVsZXRlIGFbYl0KcmV0dXJuITB9
+LApYOmZ1bmN0aW9uKCl7dGhpcy5yPTEwNzM3NDE4MjMmdGhpcy5yKzF9LAp5bzpmdW5jdGlvbihhKXt2
+YXIgdCxzPXRoaXMscj1uZXcgUC5ibihILkxoKHMpLmQuYihhKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9
+cgplbHNle3Q9cy5mCnIuYz10CnMuZj10LmI9cn0rK3MuYQpzLlgoKQpyZXR1cm4gcn0sCkdTOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMscz1hLmMscj1hLmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMuYj1yCmlm
+KHI9PW51bGwpdC5mPXMKZWxzZSByLmM9czstLXQuYQp0LlgoKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouaGYoYSkmMTA3Mzc0MTgyM30sCkRGOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJl
+dHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBz
+CnJldHVybi0xfX0KUC5ibi5wcm90b3R5cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIp
+dGhyb3cgSC5iKFAuYTQocykpCmVsc2V7cz10LmMKaWYocz09bnVsbCl7dC5zaihudWxsKQpyZXR1cm4h
+MX1lbHNle3Quc2oodC4kdGkuZC5iKHMuYSkpCnQuYz10LmMuYgpyZXR1cm4hMH19fSwKc2o6ZnVuY3Rp
+b24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KUC5tVy5wcm90b3R5cGU9e30KUC5M
+VS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxfQpQLmxELnByb3RvdHlwZT17CmdrejpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueksoYSkuQygiYTc8bEQuRT4iKSl9
+LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMKSC56SyhhKS5DKCJ+KGxELkUpIikuYihiKQp0PXRoaXMuZ0EoYSkKZm9yKHM9MDtzPHQ7KytzKXti
+LiQxKHRoaXMucShhLHMpKQppZih0IT09dGhpcy5nQShhKSl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgueksoYSkKcmV0dXJuIG5ldyBILkE4KGEsdC5LcShjKS5DKCIx
+KGxELkUpIikuYihiKSx0LkMoIkA8bEQuRT4iKS5LcShjKS5DKCJBODwxLDI+IikpfSwKZHU6ZnVuY3Rp
+b24oYSxiLGMsZCl7dmFyIHQKSC56SyhhKS5DKCJsRC5FIikuYihkKQpQLmpCKGIsYyx0aGlzLmdBKGEp
+KQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0Uo
+YSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAiCnMuYT0hMQpzPXRoaXMuYgp0
+PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1ILmQoYil9LAokUzoxfQpQLllrLnByb3RvdHlwZT17
+Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguTGgodGhpcykuQygifihZay5LLFlrLlYpIikuYihiKQpm
+b3IodD1KLklUKHRoaXMuZ1YoKSk7dC5GKCk7KXtzPXQuZ2woKQpiLiQyKHMsdGhpcy5xKDAscykpfX0s
+CmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gSi5NMSh0aGlzLmdWKCksbmV3IFAueVEodGhpcyksSC5MaCh0
+aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouemwodGhpcy5n
+VigpLGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nVigpKX0sCnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcy5hLHM9SC5MaCh0KQpzLkMoIllrLksiKS5iKGEpCnJldHVybiBuZXcgUC5OMyhh
+LHQucSgwLGEpLHMuQygiQDxZay5LPiIpLktxKHMuQygiWWsuViIpKS5DKCJOMzwxLDI+IikpfSwKJFM6
+ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsuVj4oWWsuSykiKX19ClAu
+S1AucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmQuYihiKQp0
+LmNoWzFdLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1hcCIp
+KX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIpfSwK
+WTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHQuZC5iKGIpLHQuY2hb
+MV0uYihjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlvbihh
+LGIpe3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5iKGIpKX0sCmdBOmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nQSh0KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaih0aGlz
+LmEpfSwKZ1B1OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nUHUodCl9LAokaVowOjF9
+ClAuR2oucHJvdG90eXBlPXt9ClAubGYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5X
+RSh0aGlzLCJ7IiwifSIpfX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl4dToxfQpQLlh2
+LnByb3RvdHlwZT17CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9Si5JVChILkxoKHRoaXMpLkMo
+ImNYPDE+IikuYihiKSk7dC5GKCk7KXRoaXMuaSgwLHQuZ2woKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
+biBQLldFKHRoaXMsInsiLCJ9Iil9LAp6VjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9UC5yaih0aGlzLHRo
+aXMucixILkxoKHRoaXMpLmQpCmlmKCFzLkYoKSlyZXR1cm4iIgppZihiPT09IiIpe3Q9IiIKZG8gdCs9
+SC5kKHMuZCkKd2hpbGUocy5GKCkpfWVsc2V7dD1ILmQocy5kKQpmb3IoO3MuRigpOyl0PXQrYitILmQo
+cy5kKX1yZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCiRpYlE6MSwKJGljWDoxLAokaXh1OjF9
+ClAublkucHJvdG90eXBlPXt9ClAuVEMucHJvdG90eXBlPXt9ClAuUlUucHJvdG90eXBlPXt9ClAudXcu
+cHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJu
+IHRoaXMuYy5xKDAsYikKZWxzZSBpZih0eXBlb2YgYiE9InN0cmluZyIpcmV0dXJuIG51bGwKZWxzZXt0
+PXNbYl0KcmV0dXJuIHR5cGVvZiB0PT0idW5kZWZpbmVkIj90aGlzLmZiKGIpOnR9fSwKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuYj09bnVsbD90aGlzLmMuYTp0aGlzLkNmKCkubGVuZ3RofSwKZ1Y6ZnVu
+Y3Rpb24oKXtpZih0aGlzLmI9PW51bGwpe3ZhciB0PXRoaXMuYwpyZXR1cm4gbmV3IEguaTUodCxILkxo
+KHQpLkMoImk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscj10aGlzCmlmKHIuYj09bnVsbClyLmMuWSgwLGIsYykKZWxzZSBpZihyLng0KGIpKXt0PXIu
+Ygp0W2JdPWMKcz1yLmEKaWYocz09bnVsbD90IT1udWxsOnMhPT10KXNbYl09bnVsbH1lbHNlIHIuWEso
+KS5ZKDAsYixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0
+KGEpCnJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwK
+SzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcwp1LmNBLmIoYikKaWYocC5iPT1udWxsKXJl
+dHVybiBwLmMuSygwLGIpCnQ9cC5DZigpCmZvcihzPTA7czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpxPXAu
+YltyXQppZih0eXBlb2YgcT09InVuZGVmaW5lZCIpe3E9UC5RZShwLmFbcl0pCnAuYltyXT1xfWIuJDIo
+cixxKQppZih0IT09cC5jKXRocm93IEguYihQLmE0KHApKX19LApDZjpmdW5jdGlvbigpe3ZhciB0PXUu
+ai5iKHRoaXMuYykKaWYodD09bnVsbCl0PXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdS5z
+KQpyZXR1cm4gdH0sClhLOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvPXRoaXMKaWYoby5iPT1udWxs
+KXJldHVybiBvLmMKdD1QLkZsKHUuTix1LnopCnM9by5DZigpCmZvcihyPTA7cT1zLmxlbmd0aCxyPHE7
+KytyKXtwPXNbcl0KdC5ZKDAscCxvLnEoMCxwKSl9aWYocT09PTApQy5ObS5pKHMsbnVsbCkKZWxzZSBD
+Lk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0
+CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBu
+dWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsK
+Z0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIp
+e3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYo
+YjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnQ9dFtiXX1yZXR1cm4gdH0sCmdrejpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXt0PXQuZ1YoKQp0PXQuZ2t6KHQpfWVsc2V7
+dD10LkNmKCkKdD1uZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4iKSl9cmV0dXJuIHR9
+LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLkNWLnByb3RvdHlwZT17Cnly
+OmZ1bmN0aW9uKGEsYTAsYTEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxi
+PSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMT1QLmpCKGEwLGExLGEubGVuZ3RoKQp0
+PSQuVjcoKQpmb3Iocz1hMCxyPXMscT1udWxsLHA9LTEsbz0tMSxuPTA7czxhMTtzPW0pe209cysxCmw9
+Qy54Qi5XKGEscykKaWYobD09PTM3KXtrPW0rMgppZihrPD1hMSl7aj1ILm9vKEMueEIuVyhhLG0pKQpp
+PUgub28oQy54Qi5XKGEsbSsxKSkKaD1qKjE2K2ktKGkmMjU2KQppZihoPT09MzcpaD0tMQptPWt9ZWxz
+ZSBoPS0xfWVsc2UgaD1sCmlmKDA8PWgmJmg8PTEyNyl7aWYoaDwwfHxoPj10Lmxlbmd0aClyZXR1cm4g
+SC5PSCh0LGgpCmc9dFtoXQppZihnPj0wKXtoPUMueEIubSgiQUJDREVGR0hJSktMTU5PUFFSU1RVVldY
+WVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyIsZykKaWYoaD09PWwpY29udGlu
+dWUKbD1ofWVsc2V7aWYoZz09PS0xKXtpZihwPDApe2Y9cT09bnVsbD9udWxsOnEuYS5sZW5ndGgKaWYo
+Zj09bnVsbClmPTAKcD1mKyhzLXIpCm89c30rK24KaWYobD09PTYxKWNvbnRpbnVlfWw9aH1pZihnIT09
+LTIpe2lmKHE9PW51bGwpcT1uZXcgUC5SbigiIikKcS5hKz1DLnhCLk5qKGEscixzKQpxLmErPUguTHco
+bCkKcj1tCmNvbnRpbnVlfX10aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYSxzKSl9
+aWYocSE9bnVsbCl7Zj1xLmErPUMueEIuTmooYSxyLGExKQplPWYubGVuZ3RoCmlmKHA+PTApUC54TShh
+LG8sYTEscCxuLGUpCmVsc2V7ZD1DLmpuLnpZKGUtMSw0KSsxCmlmKGQ9PT0xKXRocm93IEguYihQLnJy
+KGIsYSxhMSkpCmZvcig7ZDw0Oyl7Zis9Ij0iCnEuYT1mOysrZH19Zj1xLmEKcmV0dXJuIEMueEIuaTco
+YSxhMCxhMSxmLmNoYXJDb2RlQXQoMCk9PTA/ZjpmKX1jPWExLWEwCmlmKHA+PTApUC54TShhLG8sYTEs
+cCxuLGMpCmVsc2V7ZD1DLmpuLnpZKGMsNCkKaWYoZD09PTEpdGhyb3cgSC5iKFAucnIoYixhLGExKSkK
+aWYoZD4xKWE9Qy54Qi5pNyhhLGExLGExLGQ9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYX19ClAuVTgucHJv
+dG90eXBlPXt9ClAuVWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBl
+PXt9ClAuYnkucHJvdG90eXBlPXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZXAuYihjKQp0PVAu
+QlMoYix0aGlzLmdIZSgpLmEpCnJldHVybiB0fSwKZ0hlOmZ1bmN0aW9uKCl7cmV0dXJuIEMuQTN9fQpQ
+Lk14LnByb3RvdHlwZT17fQpQLnU1LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFr
+fX0KUC5FMy5wcm90b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHI9UC5qQigwLG51bGwsYS5s
+ZW5ndGgpLHE9ci0wCmlmKHE9PT0wKXJldHVybiBuZXcgVWludDhBcnJheSgwKQp0PW5ldyBVaW50OEFy
+cmF5KHEqMykKcz1uZXcgUC5Sdyh0KQppZihzLkd4KGEsMCxyKSE9PXIpcy5PNihKLmE2KGEsci0xKSww
+KQpyZXR1cm4gbmV3IFVpbnQ4QXJyYXkodC5zdWJhcnJheSgwLEguck0oMCxzLmIsdC5sZW5ndGgpKSl9
+fQpQLlJ3LnByb3RvdHlwZT17Ck82OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5jLHE9cy5i
+LHA9cSsxLG89ci5sZW5ndGgKaWYoKGImNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzYrKChhJjEwMjMpPDwx
+MCl8YiYxMDIzCnMuYj1wCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTI0MHx0Pj4+MTgKcT1z
+LmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHx0Pj4+MTImNjMKcD1zLmI9cSsx
+CmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTEyOHx0Pj4+NiY2MwpzLmI9cCsxCmlmKHA+PW8p
+cmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHx0JjYzCnJldHVybiEwfWVsc2V7cy5iPXAKaWYocT49byly
+ZXR1cm4gSC5PSChyLHEpCnJbcV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5P
+SChyLHApCnJbcF09MTI4fGE+Pj42JjYzCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJb
+cV09MTI4fGEmNjMKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxu
+LG09dGhpcwppZihiIT09YyYmKEMueEIubShhLGMtMSkmNjQ1MTIpPT09NTUyOTYpLS1jCmZvcih0PW0u
+YyxzPXQubGVuZ3RoLHI9YjtyPGM7KytyKXtxPUMueEIuVyhhLHIpCmlmKHE8PTEyNyl7cD1tLmIKaWYo
+cD49cylicmVhawptLmI9cCsxCnRbcF09cX1lbHNlIGlmKChxJjY0NTEyKT09PTU1Mjk2KXtpZihtLmIr
+Mz49cylicmVhawpvPXIrMQppZihtLk82KHEsQy54Qi5XKGEsbykpKXI9b31lbHNlIGlmKHE8PTIwNDcp
+e3A9bS5iCm49cCsxCmlmKG4+PXMpYnJlYWsKbS5iPW4KaWYocD49cylyZXR1cm4gSC5PSCh0LHApCnRb
+cF09MTkyfHE+Pj42Cm0uYj1uKzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlmKHArMj49cylicmVh
+awpuPW0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MjI0fHE+Pj4xMgpwPW0uYj1u
+KzEKaWYobj49cylyZXR1cm4gSC5PSCh0LG4pCnRbbl09MTI4fHE+Pj42JjYzCm0uYj1wKzEKaWYocD49
+cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5wcm90b3R5cGU9
+ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmIoYSkKdD1QLmt5KCExLGEs
+MCxudWxsKQppZih0IT1udWxsKXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IbShhKSkKcj1QLmNQKGEs
+MCxzKQppZihyPjApe3E9UC5ITShhLDAscikKaWYocj09PXMpcmV0dXJuIHEKcD1uZXcgUC5SbihxKQpv
+PXIKbj0hMX1lbHNle289MApwPW51bGwKbj0hMH1pZihwPT1udWxsKXA9bmV3IFAuUm4oIiIpCm09bmV3
+IFAuYnooITEscCkKbS5jPW4KbS5NRShhLG8scykKaWYobS5lPjApe0gudmgoUC5ycigiVW5maW5pc2hl
+ZCBVVEYtOCBvY3RldCBzZXF1ZW5jZSIsYSxzKSkKcC5hKz1ILkx3KDY1NTMzKQptLmY9bS5lPW0uZD0w
+fWw9cC5hCnJldHVybiBsLmNoYXJDb2RlQXQoMCk9PTA/bDpsfX0KUC5iei5wcm90b3R5cGU9ewpNRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGg9dGhpcyxnPSJCYWQgVVRG
+LTggZW5jb2RpbmcgMHgiCnUuTC5iKGEpCnQ9aC5kCnM9aC5lCnI9aC5mCmguZj1oLmU9aC5kPTAKJGxh
+YmVsMCQwOmZvcihxPUouVTYoYSkscD1oLmIsbz1iOyEwO289ail7JGxhYmVsMSQxOmlmKHM+MCl7ZG97
+aWYobz09PWMpYnJlYWsgJGxhYmVsMCQwCm49cS5xKGEsbykKaWYodHlwZW9mIG4hPT0ibnVtYmVyIily
+ZXR1cm4gbi56TSgpCmlmKChuJjE5MikhPT0xMjgpe209UC5ycihnK0Muam4uV1oobiwxNiksYSxvKQp0
+aHJvdyBILmIobSl9ZWxzZXt0PSh0PDw2fG4mNjMpPj4+MDstLXM7KytvfX13aGlsZShzPjApCm09ci0x
+CmlmKG08MHx8bT49NClyZXR1cm4gSC5PSChDLkdiLG0pCmlmKHQ8PUMuR2JbbV0pe209UC5ycigiT3Zl
+cmxvbmcgZW5jb2Rpbmcgb2YgMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlm
+KHQ+MTExNDExMSl7bT1QLnJyKCJDaGFyYWN0ZXIgb3V0c2lkZSB2YWxpZCBVbmljb2RlIHJhbmdlOiAw
+eCIrQy5qbi5XWih0LDE2KSxhLG8tci0xKQp0aHJvdyBILmIobSl9aWYoIWguY3x8dCE9PTY1Mjc5KXAu
+YSs9SC5Mdyh0KQpoLmM9ITF9Zm9yKG09bzxjO207KXtsPVAuY1AoYSxvLGMpCmlmKGw+MCl7aC5jPSEx
+Cms9bytsCnAuYSs9UC5ITShhLG8saykKaWYoaz09PWMpYnJlYWt9ZWxzZSBrPW8Kaj1rKzEKbj1xLnEo
+YSxrKQppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPDApe2k9UC5ycigiTmVn
+YXRpdmUgVVRGLTggY29kZSB1bml0OiAtMHgiK0Muam4uV1ooLW4sMTYpLGEsai0xKQp0aHJvdyBILmIo
+aSl9ZWxzZXtpZigobiYyMjQpPT09MTkyKXt0PW4mMzEKcz0xCnI9MQpjb250aW51ZSAkbGFiZWwwJDB9
+aWYoKG4mMjQwKT09PTIyNCl7dD1uJjE1CnM9MgpyPTIKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0
+OCk9PT0yNDAmJm48MjQ1KXt0PW4mNwpzPTMKcj0zCmNvbnRpbnVlICRsYWJlbDAkMH1pPVAucnIoZytD
+LmpuLldaKG4sMTYpLGEsai0xKQp0aHJvdyBILmIoaSl9fWJyZWFrICRsYWJlbDAkMH1pZihzPjApe2gu
+ZD10CmguZT1zCmguZj1yfX19ClAuV0YucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+LHIKdS5mby5iKGEpCnQ9dGhpcy5iCnM9dGhpcy5hCnQuYSs9cy5hCnI9dC5hKz1ILmQoYS5hKQp0LmE9
+cisiOiAiCnQuYSs9UC5wKGIpCnMuYT0iLCAifSwKJFM6Mzh9ClAuYTIucHJvdG90eXBlPXt9ClAuaVAu
+cHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGlu
+c3RhbmNlb2YgUC5pUCYmdGhpcy5hPT09Yi5hJiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LmEKcmV0dXJuKHReQy5qbi53Ryh0LDMwKSkmMTA3Mzc0MTgyM30sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9
+dGhpcyxzPVAuR3EoSC50Sih0KSkscj1QLmgwKEguTlModCkpLHE9UC5oMChILmpBKHQpKSxwPVAuaDAo
+SC5JWCh0KSksbz1QLmgwKEguY2godCkpLG49UC5oMChILkpkKHQpKSxtPVAuVngoSC5vMSh0KSksbD1z
+KyItIityKyItIitxKyIgIitwKyI6IitvKyI6IituKyIuIittCnJldHVybiBsfX0KUC5DUC5wcm90b3R5
+cGU9e30KUC5YUy5wcm90b3R5cGU9e30KUC5DNi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0
+PXRoaXMuYQppZih0IT1udWxsKXJldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AucCh0KQpyZXR1cm4i
+QXNzZXJ0aW9uIGZhaWxlZCJ9fQpQLm4ucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVGhy
+b3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIkludmFsaWQg
+YXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0dXJuIiJ9LAp3OmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYyxuPW8hPW51bGw/IiAoIitvKyIpIjoiIgpv
+PXAuZAp0PW89PW51bGw/IiI6IjogIitILmQobykKcz1wLmdaKCkrbit0CmlmKCFwLmEpcmV0dXJuIHMK
+cj1wLmd1KCkKcT1QLnAocC5iKQpyZXR1cm4gcytyKyI6ICIrcX19ClAuYkoucHJvdG90eXBlPXsKZ1o6
+ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlz
+LmUKaWYocj09bnVsbCl7cj10aGlzLmYKdD1yIT1udWxsPyI6IE5vdCBsZXNzIHRoYW4gb3IgZXF1YWwg
+dG8gIitILmQocik6IiJ9ZWxzZXtzPXRoaXMuZgppZihzPT1udWxsKXQ9IjogTm90IGdyZWF0ZXIgdGhh
+biBvciBlcXVhbCB0byAiK0guZChyKQplbHNlIGlmKHM+cil0PSI6IE5vdCBpbiByYW5nZSAiK0guZChy
+KSsiLi4iK0guZChzKSsiLCBpbmNsdXNpdmUiCmVsc2UgdD1zPHI/IjogVmFsaWQgdmFsdWUgcmFuZ2Ug
+aXMgZW1wdHkiOiI6IE9ubHkgdmFsaWQgdmFsdWUgaXMgIitILmQocil9cmV0dXJuIHR9fQpQLmVZLnBy
+b3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2
+YXIgdCxzPUguU2ModGhpcy5iKQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZihz
+PDApcmV0dXJuIjogaW5kZXggbXVzdCBub3QgYmUgbmVnYXRpdmUiCnQ9dGhpcy5mCmlmKHQ9PT0wKXJl
+dHVybiI6IG5vIGluZGljZXMgYXJlIHZhbGlkIgpyZXR1cm4iOiBpbmRleCBzaG91bGQgYmUgbGVzcyB0
+aGFuICIrSC5kKHQpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAucHJvdG90eXBl
+PXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcyxrPXt9LGo9bmV3IFAuUm4o
+IiIpCmsuYT0iIgpmb3IodD1sLmMscz10Lmxlbmd0aCxyPTAscT0iIixwPSIiO3I8czsrK3IscD0iLCAi
+KXtvPXRbcl0Kai5hPXErcApxPWouYSs9UC5wKG8pCmsuYT0iLCAifWwuZC5LKDAsbmV3IFAuV0Yoayxq
+KSkKbj1QLnAobC5hKQptPWoudygwKQp0PSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3Vu
+ZDogJyIrSC5kKGwuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbisiXG5Bcmd1bWVudHM6IFsiK20rIl0iCnJl
+dHVybiB0fX0KUC51Yi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJVbnN1cHBvcnRlZCBv
+cGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuYQpyZXR1cm4gdCE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAiK3Q6IlVuaW1wbGVtZW50ZWRF
+cnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkJhZCBzdGF0ZTogIit0
+aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQ9PW51
+bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb24uIgpyZXR1cm4i
+Q29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjogIitQLnAodCkrIi4ifX0KUC5r
+NS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJPdXQgb2YgTWVtb3J5In0sCiRpWFM6MX0K
+UC5LWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LAokaVhT
+OjF9ClAuYy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdD09bnVs
+bD8iUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiI6IlJlYWRp
+bmcgc3RhdGljIHZhcmlhYmxlICciK3QrIicgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiJ9fQpQLkNE
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkV4Y2VwdGlvbjogIit0aGlzLmF9fQpQLmFF
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGg9dGhp
+cy5hLGc9aCE9bnVsbCYmIiIhPT1oPyJGb3JtYXRFeGNlcHRpb246ICIrSC5kKGgpOiJGb3JtYXRFeGNl
+cHRpb24iLGY9dGhpcy5jLGU9dGhpcy5iCmlmKHR5cGVvZiBlPT0ic3RyaW5nIil7aWYoZiE9bnVsbClo
+PWY8MHx8Zj5lLmxlbmd0aAplbHNlIGg9ITEKaWYoaClmPW51bGwKaWYoZj09bnVsbCl7dD1lLmxlbmd0
+aD43OD9DLnhCLk5qKGUsMCw3NSkrIi4uLiI6ZQpyZXR1cm4gZysiXG4iK3R9Zm9yKHM9MSxyPTAscT0h
+MSxwPTA7cDxmOysrcCl7bz1DLnhCLlcoZSxwKQppZihvPT09MTApe2lmKHIhPT1wfHwhcSkrK3MKcj1w
+KzEKcT0hMX1lbHNlIGlmKG89PT0xMyl7KytzCnI9cCsxCnE9ITB9fWc9cz4xP2crKCIgKGF0IGxpbmUg
+IitzKyIsIGNoYXJhY3RlciAiKyhmLXIrMSkrIilcbiIpOmcrKCIgKGF0IGNoYXJhY3RlciAiKyhmKzEp
+KyIpXG4iKQpuPWUubGVuZ3RoCmZvcihwPWY7cDxuOysrcCl7bz1DLnhCLm0oZSxwKQppZihvPT09MTB8
+fG89PT0xMyl7bj1wCmJyZWFrfX1pZihuLXI+NzgpaWYoZi1yPDc1KXttPXIrNzUKbD1yCms9IiIKaj0i
+Li4uIn1lbHNle2lmKG4tZjw3NSl7bD1uLTc1Cm09bgpqPSIifWVsc2V7bD1mLTM2Cm09ZiszNgpqPSIu
+Li4ifWs9Ii4uLiJ9ZWxzZXttPW4KbD1yCms9IiIKaj0iIn1pPUMueEIuTmooZSxsLG0pCnJldHVybiBn
+K2sraStqKyJcbiIrQy54Qi5JeCgiICIsZi1sK2subGVuZ3RoKSsiXlxuIn1lbHNlIHJldHVybiBmIT1u
+dWxsP2crKCIgKGF0IG9mZnNldCAiK0guZChmKSsiKSIpOmd9fQpQLkVILnByb3RvdHlwZT17fQpQLktO
+LnByb3RvdHlwZT17fQpQLmNYLnByb3RvdHlwZT17CkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxo
+KHRoaXMpCnJldHVybiBILksxKHRoaXMsdC5LcShjKS5DKCIxKGNYLkUpIikuYihiKSx0LkMoImNYLkUi
+KSxjKX0sCmV2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhp
+cyx0LkMoImEyKGNYLkUpIikuYihiKSx0LkMoIlU1PGNYLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFy
+IHQscz10aGlzLmdreih0aGlzKQpmb3IodD0wO3MuRigpOykrK3QKcmV0dXJuIHR9LApnbDA6ZnVuY3Rp
+b24oYSl7cmV0dXJuIXRoaXMuZ2t6KHRoaXMpLkYoKX0sCmdyODpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
+aXMuZ2t6KHRoaXMpCmlmKCFzLkYoKSl0aHJvdyBILmIoSC5XcCgpKQp0PXMuZ2woKQppZihzLkYoKSl0
+aHJvdyBILmIoSC5kVSgpKQpyZXR1cm4gdH0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKUC5rMShi
+LCJpbmRleCIpCmZvcih0PXRoaXMuZ2t6KHRoaXMpLHM9MDt0LkYoKTspe3I9dC5nbCgpCmlmKGI9PT1z
+KXJldHVybiByOysrc310aHJvdyBILmIoUC5DZihiLHRoaXMsImluZGV4IixudWxsLHMpKX0sCnc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90eXBlPXt9ClAuek0u
+cHJvdG90eXBlPXskaWJROjEsJGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLk4zLnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIk1hcEVudHJ5KCIrSC5kKHRoaXMuYSkrIjogIitILmQodGhpcy5i
+KSsiKSJ9fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gUC5rLnByb3RvdHlw
+ZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9fQpQLkZLLnBy
+b3RvdHlwZT17fQpQLmsucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmssJGlrOjEsCkROOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKHRoaXMpfSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0aGlzKSkrIicifSwKZTc6
+ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5nbmQoKSxi
+LmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLncodGhpcyl9fQpQLk9kLnBy
+b3RvdHlwZT17fQpQLmliLnByb3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3RvdHlwZT17fQpQLkd6LnBy
+b3RvdHlwZT17fQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnByb3RvdHlwZT17CmdBOmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0
+dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0QucHJvdG90eXBlPXt9ClAubjEu
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmYuYihhKQpILnkoYikKdD1K
+LnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlkoMCxQLmt1KGIsMCxiLmxlbmd0
+aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmooYiwwLHQpCnI9Qy54Qi5HKGIs
+dCsxKQpxPXRoaXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEwKSxQLmt1KHIsMCxyLmxlbmd0
+aCxxLCEwKSl9cmV0dXJuIGF9LAokUzoyMH0KUC5jUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokUzo0
+M30KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2Fs
+IElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4k
+MihhLG51bGwpfSwKJFM6NDR9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdApp
+ZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250YWluIGEgbWF4aW11bSBv
+ZiA0IGhleCBkaWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIpLG51bGwsMTYpCmlmKHR5
+cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8MHx8dD42NTUzNSl0aGlzLmEuJDIoImVh
+Y2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZgIixhKQpyZXR1cm4gdH0s
+CiRTOjQ2fQpQLkRuLnByb3RvdHlwZT17CmdrdTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9LApnSmY6
+ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJuIiIKaWYoQy54Qi5uKHQsIlsi
+KSlyZXR1cm4gQy54Qi5Oaih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApndHA6ZnVuY3Rpb24oYSl7
+dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpyZXR1cm4gdH0sCmd0UDpm
+dW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9uKCl7
+dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbD10aGlzCnUuWC5iKG51bGwpCnUuYi5iKGIpCnQ9bC5hCnM9dD09PSJmaWxlIgpy
+PWwuYgpxPWwuZApwPWwuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxsfHxzPyIi
+Om51bGwKbz1sLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlmKG4mJiFD
+LnhCLm4obywiLyIpKW89Ii8iK28KbT1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcgUC5Ebih0LHIs
+cCxxLG8sbSxsLnIpfSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLngKaWYocyE9bnVsbClyZXR1
+cm4gcwp0PXRoaXMuZQppZih0Lmxlbmd0aCE9PTAmJkMueEIuVyh0LDApPT09NDcpdD1DLnhCLkcodCwx
+KQpzPXQ9PT0iIj9DLnhEOlAuQUYobmV3IEguQTgoSC5WTSh0LnNwbGl0KCIvIiksdS5zKSx1LmRPLmIo
+UC5QSCgpKSx1LmRvKSx1Lk4pCnRoaXMuc282KHMpCnJldHVybiBzfSwKZ2hZOmZ1bmN0aW9uKCl7dmFy
+IHQscz10aGlzCmlmKHMuUT09bnVsbCl7dD1zLmYKcy5zUkgobmV3IFAuR2ooUC5XWCh0PT1udWxsPyIi
+OnQpLHUuVykpfXJldHVybiBzLlF9LApKaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwpmb3Io
+dD0wLHM9MDtDLnhCLlFpKGIsIi4uLyIscyk7KXtzKz0zOysrdH1yPUMueEIuY24oYSwiLyIpCndoaWxl
+KCEwKXtpZighKHI+MCYmdD4wKSlicmVhawpxPUMueEIuUGsoYSwiLyIsci0xKQppZihxPDApYnJlYWsK
+cD1yLXEKbz1wIT09MgppZighb3x8cD09PTMpaWYoQy54Qi5tKGEscSsxKT09PTQ2KW89IW98fEMueEIu
+bShhLHErMik9PT00NgplbHNlIG89ITEKZWxzZSBvPSExCmlmKG8pYnJlYWs7LS10CnI9cX1yZXR1cm4g
+Qy54Qi5pNyhhLHIrMSxudWxsLEMueEIuRyhiLHMtMyp0KSl9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMsaj1udWxsCmlmKGEuZ0ZpKCkubGVuZ3RoIT09MCl7dD1hLmdGaSgpCmlmKGEuZ2NqKCkpe3M9YS5n
+a3UoKQpyPWEuZ0pmKGEpCnE9YS5neEEoKT9hLmd0cChhKTpqfWVsc2V7cT1qCnI9cQpzPSIifXA9UC54
+ZShhLmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3Q9ay5hCmlmKGEuZ2NqKCkpe3M9YS5n
+a3UoKQpyPWEuZ0pmKGEpCnE9UC53QihhLmd4QSgpP2EuZ3RwKGEpOmosdCkKcD1QLnhlKGEuZ0lpKGEp
+KQpvPWEuZ1FEKCk/YS5ndFAoKTpqfWVsc2V7cz1rLmIKcj1rLmMKcT1rLmQKaWYoYS5nSWkoYSk9PT0i
+Iil7cD1rLmUKbz1hLmdRRCgpP2EuZ3RQKCk6ay5mfWVsc2V7aWYoYS5ndFQoKSlwPVAueGUoYS5nSWko
+YSkpCmVsc2V7bj1rLmUKaWYobi5sZW5ndGg9PT0wKWlmKHI9PW51bGwpcD10Lmxlbmd0aD09PTA/YS5n
+SWkoYSk6UC54ZShhLmdJaShhKSkKZWxzZSBwPVAueGUoIi8iK2EuZ0lpKGEpKQplbHNle209ay5KaChu
+LGEuZ0lpKGEpKQpsPXQubGVuZ3RoPT09MAppZighbHx8ciE9bnVsbHx8Qy54Qi5uKG4sIi8iKSlwPVAu
+eGUobSkKZWxzZSBwPVAud0YobSwhbHx8ciE9bnVsbCl9fW89YS5nUUQoKT9hLmd0UCgpOmp9fX1yZXR1
+cm4gbmV3IFAuRG4odCxzLHIscSxwLG8sYS5nWjgoKT9hLmdLYSgpOmopfSwKZ2NqOmZ1bmN0aW9uKCl7
+cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmQhPW51bGx9LApn
+UUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4odGhpcy5lLCIvIil9LAp0NDpm
+dW5jdGlvbigpe3ZhciB0LHMscj10aGlzLHE9ci5hCmlmKHEhPT0iIiYmcSE9PSJmaWxlIil0aHJvdyBI
+LmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHEpKyIgVVJJIikp
+CnE9ci5mCmlmKChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0
+IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQpxPXIucgppZigo
+cT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0
+aCBmcm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSkKdD0kLndRKCkKaWYoSC5vVCh0
+KSlxPVAubW4ocikKZWxzZXtpZihyLmMhPW51bGwmJnIuZ0pmKHIpIT09IiIpSC52aChQLkw0KCJDYW5u
+b3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBh
+dXRob3JpdHkiKSkKcz1yLmdGaigpClAua0UocywhMSkKcT1QLnZnKEMueEIubihyLmUsIi8iKT8iLyI6
+IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyLHE9dGhpcyxwPXEueQppZihwPT1udWxsKXtwPXEuYQp0PXAubGVuZ3RoIT09MD9wKyI6
+IjoiIgpzPXEuYwpyPXM9PW51bGwKaWYoIXJ8fHA9PT0iZmlsZSIpe3A9dCsiLy8iCnQ9cS5iCmlmKHQu
+bGVuZ3RoIT09MClwPXArdCsiQCIKaWYoIXIpcCs9cwp0PXEuZAppZih0IT1udWxsKXA9cCsiOiIrSC5k
+KHQpfWVsc2UgcD10CnArPXEuZQp0PXEuZgppZih0IT1udWxsKXA9cCsiPyIrdAp0PXEucgppZih0IT1u
+dWxsKXA9cCsiIyIrdApwPXEueT1wLmNoYXJDb2RlQXQoMCk9PTA/cDpwfXJldHVybiBwfSwKRE46ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHI9PT1iKXJldHVy
+biEwCmlmKHUuRC5jKGIpKWlmKHIuYT09Yi5nRmkoKSlpZihyLmMhPW51bGw9PT1iLmdjaigpKWlmKHIu
+Yj09Yi5na3UoKSlpZihyLmdKZihyKT09Yi5nSmYoYikpaWYoci5ndHAocik9PWIuZ3RwKGIpKWlmKHIu
+ZT09PWIuZ0lpKGIpKXt0PXIuZgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdRRCgpKXtpZihzKXQ9IiIKaWYo
+dD09PWIuZ3RQKCkpe3Q9ci5yCnM9dD09bnVsbAppZighcz09PWIuZ1o4KCkpe2lmKHMpdD0iIgp0PXQ9
+PT1iLmdLYSgpfWVsc2UgdD0hMX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMQplbHNlIHQ9ITEK
+ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQpyZXR1cm4gdH0s
+CmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnoKcmV0dXJuIHQ9PW51bGw/dGhpcy56PUMueEIuZ2lP
+KHRoaXMudygwKSk6dH0sCnNvNjpmdW5jdGlvbihhKXt0aGlzLng9dS5hLmIoYSl9LApzUkg6ZnVuY3Rp
+b24oYSl7dGhpcy5RPXUuZi5iKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5h
+fSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLmUxLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3Rocm93IEguYihQLnJyKCJJbnZhbGlkIHBvcnQiLHRoaXMuYSx0aGlzLmIrMSkpfSwKJFM6
+MTR9ClAuTlkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9IklsbGVnYWwgcGF0aCBjaGFy
+YWN0ZXIgIgpILnkoYSkKaWYoSi56bChhLCIvIikpaWYodGhpcy5hKXRocm93IEguYihQLnhZKHQrYSkp
+CmVsc2UgdGhyb3cgSC5iKFAuTDQodCthKSl9LAokUzoxNH0KUC5SWi5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gUC5lUChDLlpKLEgueShhKSxDLnhNLCExKX0sCiRTOjV9ClAuTUUucHJvdG90
+eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmIscz10aGlzLmEKdC5hKz1zLmEKcy5hPSIm
+IgpzPXQuYSs9SC5kKFAuZVAoQy5GMyxhLEMueE0sITApKQppZihiIT1udWxsJiZiLmxlbmd0aCE9PTAp
+e3QuYT1zKyI9Igp0LmErPUguZChQLmVQKEMuRjMsYixDLnhNLCEwKSl9fSwKJFM6MjJ9ClAueTUucHJv
+dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgueShhKQppZihiPT1udWxsfHx0eXBlb2Yg
+Yj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC55KGIpKQplbHNlIGZvcih0PUouSVQodS5SLmIoYikpLHM9
+dGhpcy5hO3QuRigpOylzLiQyKGEsSC55KHQuZ2woKSkpfSwKJFM6MTN9ClAuUEUucHJvdG90eXBlPXsK
+Z2xSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbCxuPXAuYwppZihuIT1udWxsKXJl
+dHVybiBuCm49cC5iCmlmKDA+PW4ubGVuZ3RoKXJldHVybiBILk9IKG4sMCkKdD1wLmEKbj1uWzBdKzEK
+cz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLlBJKHQscysxLHIsQy5WQywh
+MSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxvLFAuUEkodCxuLHIs
+Qy5XZCwhMSkscSxvKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5sZW5ndGgp
+cmV0dXJuIEguT0gocywwKQp0PXRoaXMuYQpyZXR1cm4gc1swXT09PS0xPyJkYXRhOiIrdDp0fX0KUC5x
+My5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoOTYpfSwKJFM6
+MjN9ClAueUkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYoYT49dC5s
+ZW5ndGgpcmV0dXJuIEguT0godCxhKQp0PXRbYV0KSi5DTSh0LDAsOTYsYikKcmV0dXJuIHR9LAokUzoy
+NH0KUC5jNi5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKZm9yKHQ9Yi5s
+ZW5ndGgscz1hLmxlbmd0aCxyPTA7cjx0Oysrcil7cT1DLnhCLlcoYixyKV45NgppZihxPj1zKXJldHVy
+biBILk9IKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1zOysr
+dCl7cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fX0KUC5VZi5wcm90
+b3R5cGU9ewpnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jPjB9LApneEE6ZnVuY3Rpb24oKXt2YXIg
+dCxzCmlmKHRoaXMuYz4wKXt0PXRoaXMuZAppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lmgo
+KQpzPXRoaXMuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBILnBZKHMpCnM9dCsxPHMKdD1z
+fWVsc2UgdD0hMQpyZXR1cm4gdH0sCmdRRDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgppZih0eXBlb2Yg
+dCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDx0aGlzLnJ9LApnWjg6ZnVuY3Rpb24oKXty
+ZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09
+NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ3ZoOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQm
+JkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT01JiZD
+LnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIuUWkodGhpcy5h
+LCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9InBhY2thZ2UiLHE9cy5i
+CmlmKHE8PTApcmV0dXJuIiIKdD1zLngKaWYodCE9bnVsbClyZXR1cm4gdAppZihzLmd2aCgpKXE9cy54
+PSJodHRwIgplbHNlIGlmKHMuZ1JlKCkpe3MueD0iaHR0cHMiCnE9Imh0dHBzIn1lbHNlIGlmKHMuZ053
+KCkpe3MueD0iZmlsZSIKcT0iZmlsZSJ9ZWxzZSBpZihxPT09NyYmQy54Qi5uKHMuYSxyKSl7cy54PXIK
+cT1yfWVsc2V7cT1DLnhCLk5qKHMuYSwwLHEpCnMueD1xfXJldHVybiBxfSwKZ2t1OmZ1bmN0aW9uKCl7
+dmFyIHQ9dGhpcy5jLHM9dGhpcy5iKzMKcmV0dXJuIHQ+cz9DLnhCLk5qKHRoaXMuYSxzLHQtMSk6IiJ9
+LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0PjA/Qy54Qi5Oaih0aGlzLmEsdCx0
+aGlzLmQpOiIifSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcwppZihzLmd4QSgpKXt0PXMuZApp
+Zih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LmgoKQpyZXR1cm4gUC5RQShDLnhCLk5qKHMuYSx0
+KzEscy5lKSxudWxsLG51bGwpfWlmKHMuZ3ZoKCkpcmV0dXJuIDgwCmlmKHMuZ1JlKCkpcmV0dXJuIDQ0
+MwpyZXR1cm4gMH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi5Oaih0aGlzLmEsdGhpcy5lLHRo
+aXMuZil9LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYscz10aGlzLnIKaWYodHlwZW9mIHQhPT0i
+bnVtYmVyIilyZXR1cm4gdC5KKCkKcmV0dXJuIHQ8cz9DLnhCLk5qKHRoaXMuYSx0KzEscyk6IiJ9LApn
+S2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnIscz10aGlzLmEKcmV0dXJuIHQ8cy5sZW5ndGg/Qy54Qi5H
+KHMsdCsxKToiIn0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzLmUscT10aGlzLmYscD10aGlz
+LmEKaWYoQy54Qi5RaShwLCIvIixyKSl7aWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5oKCk7
+KytyfWlmKHI9PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUucykKcz1yCndoaWxlKCEwKXtpZih0eXBl
+b2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBI
+LnBZKHEpCmlmKCEoczxxKSlicmVhawppZihDLnhCLm0ocCxzKT09PTQ3KXtDLk5tLmkodCxDLnhCLk5q
+KHAscixzKSkKcj1zKzF9KytzfUMuTm0uaSh0LEMueEIuTmoocCxyLHEpKQpyZXR1cm4gUC5BRih0LHUu
+Til9LApnaFk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1
+cm4gdC5KKCkKaWYodD49dGhpcy5yKXJldHVybiBDLldPCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMu
+Z3RQKCkpLHUuVyl9LAprWDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZAppZih0eXBlb2YgcyE9PSJu
+dW1iZXIiKXJldHVybiBzLmgoKQp0PXMrMQpyZXR1cm4gdCthLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5R
+aSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQucixyPXQuYQppZihzPj1y
+Lmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihyLDAscyksdC5iLHQuYyx0LmQs
+dC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGo9
+dGhpcyxpPW51bGwKdS5YLmIobnVsbCkKdS5iLmIoYikKdD1qLmdGaSgpCnM9dD09PSJmaWxlIgpyPWou
+YwpxPXI+MD9DLnhCLk5qKGouYSxqLmIrMyxyKToiIgpwPWouZ3hBKCk/ai5ndHAoaik6aQpyPWouYwpp
+ZihyPjApbz1DLnhCLk5qKGouYSxyLGouZCkKZWxzZSBvPXEubGVuZ3RoIT09MHx8cCE9bnVsbHx8cz8i
+IjppCnI9ai5hCm49Qy54Qi5OaihyLGouZSxqLmYpCmlmKCFzKW09byE9bnVsbCYmbi5sZW5ndGghPT0w
+CmVsc2UgbT0hMAppZihtJiYhQy54Qi5uKG4sIi8iKSluPSIvIituCmw9UC5sZShpLDAsMCxiKQptPWou
+cgprPW08ci5sZW5ndGg/Qy54Qi5HKHIsbSsxKTppCnJldHVybiBuZXcgUC5Ebih0LHEsbyxwLG4sbCxr
+KX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7
+aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1cm4gdGhpcy52cygp
+Lm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYs
+ZT1iLmIKaWYoZT4wKXJldHVybiBiCnQ9Yi5jCmlmKHQ+MCl7cz1hLmIKaWYoczw9MClyZXR1cm4gYgpp
+ZihhLmdOdygpKXI9Yi5lIT1iLmYKZWxzZSBpZihhLmd2aCgpKXI9IWIua1goIjgwIikKZWxzZSByPSFh
+LmdSZSgpfHwhYi5rWCgiNDQzIikKaWYocil7cT1zKzEKcD1DLnhCLk5qKGEuYSwwLHEpK0MueEIuRyhi
+LmEsZSsxKQplPWIuZAppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpvPWIuZQppZih0
+eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLmgoKQpuPWIuZgppZih0eXBlb2YgbiE9PSJudW1iZXIi
+KXJldHVybiBuLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxzLHQrcSxlK3EsbytxLG4rcSxiLnIrcSxhLngp
+fWVsc2UgcmV0dXJuIHRoaXMudnMoKS5tUyhiKX1tPWIuZQplPWIuZgppZihtPT1lKXt0PWIucgppZih0
+eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLkooKQppZihlPHQpe3M9YS5mCmlmKHR5cGVvZiBzIT09
+Im51bWJlciIpcmV0dXJuIHMuSE4oKQpxPXMtZQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxz
+KStDLnhCLkcoYi5hLGUpLGEuYixhLmMsYS5kLGEuZSxlK3EsdCtxLGEueCl9ZT1iLmEKaWYodDxlLmxl
+bmd0aCl7cz1hLnIKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5HKGUsdCksYS5i
+LGEuYyxhLmQsYS5lLGEuZix0KyhzLXQpLGEueCl9cmV0dXJuIGEuTjkoKX10PWIuYQppZihDLnhCLlFp
+KHQsIi8iLG0pKXtzPWEuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKaWYodHlw
+ZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5wWShtKQpxPXMtbQpwPUMueEIuTmooYS5hLDAscykrQy54
+Qi5HKHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKcmV0dXJuIG5ldyBQLlVm
+KHAsYS5iLGEuYyxhLmQscyxlK3EsYi5yK3EsYS54KX1sPWEuZQprPWEuZgppZihsPT1rJiZhLmM+MCl7
+Zm9yKDtDLnhCLlFpKHQsIi4uLyIsbSk7KXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLmgo
+KQptKz0zfWlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQppZih0eXBlb2YgbSE9PSJu
+dW1iZXIiKXJldHVybiBILnBZKG0pCnE9bC1tKzEKcD1DLnhCLk5qKGEuYSwwLGwpKyIvIitDLnhCLkco
+dCxtKQppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxh
+LmIsYS5jLGEuZCxsLGUrcSxiLnIrcSxhLngpfWo9YS5hCmZvcihpPWw7Qy54Qi5RaShqLCIuLi8iLGkp
+Oyl7aWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5oKCkKaSs9M31oPTAKd2hpbGUoITApe2lm
+KHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0uaCgpCmc9bSszCmlmKHR5cGVvZiBlIT09Im51bWJl
+ciIpcmV0dXJuIEgucFkoZSkKaWYoIShnPD1lJiZDLnhCLlFpKHQsIi4uLyIsbSkpKWJyZWFrOysraApt
+PWd9Zj0iIgp3aGlsZSghMCl7aWYodHlwZW9mIGshPT0ibnVtYmVyIilyZXR1cm4gay5vcygpCmlmKHR5
+cGVvZiBpIT09Im51bWJlciIpcmV0dXJuIEgucFkoaSkKaWYoIShrPmkpKWJyZWFrOy0tawppZihDLnhC
+Lm0oaixrKT09PTQ3KXtpZihoPT09MCl7Zj0iLyIKYnJlYWt9LS1oCmY9Ii8ifX1pZihrPT09aSYmYS5i
+PD0wJiYhQy54Qi5RaShqLCIvIixsKSl7bS09aCozCmY9IiJ9cT1rLW0rZi5sZW5ndGgKcmV0dXJuIG5l
+dyBQLlVmKEMueEIuTmooaiwwLGspK2YrQy54Qi5HKHQsbSksYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3Es
+YS54KX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYj49MCYmIXAuZ053KCkp
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChwLmdG
+aSgpKSsiIFVSSSIpKQp0PXAuZgpzPXAuYQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lkoo
+KQppZih0PHMubGVuZ3RoKXtpZih0PHAucil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBm
+aWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkgY29tcG9uZW50IikpCnRocm93IEguYihQLkw0
+KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21w
+b25lbnQiKSl9cj0kLndRKCkKaWYoSC5vVChyKSl0PVAubW4ocCkKZWxzZXtxPXAuZAppZih0eXBlb2Yg
+cSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCmlmKHAuYzxxKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJh
+Y3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5
+IikpCnQ9Qy54Qi5OaihzLHAuZSx0KX1yZXR1cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LnkKcmV0dXJuIHQ9PW51bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6dH0sCkROOmZ1bmN0aW9uKGEs
+Yil7aWYoYj09bnVsbClyZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdS5ELmMoYikm
+JnRoaXMuYT09PWIudygwKX0sCnZzOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPW51bGwscj10LmdGaSgp
+LHE9dC5na3UoKSxwPXQuYz4wP3QuZ0pmKHQpOnMsbz10Lmd4QSgpP3QuZ3RwKHQpOnMsbj10LmEsbT10
+LmYsbD1DLnhCLk5qKG4sdC5lLG0pLGs9dC5yCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0u
+SigpCm09bTxrP3QuZ3RQKCk6cwpyZXR1cm4gbmV3IFAuRG4ocixxLHAsbyxsLG0sazxuLmxlbmd0aD90
+LmdLYSgpOnMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3Rv
+dHlwZT17fQpXLnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX0sCiRpR2g6MX0KVy5mWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVy
+biBTdHJpbmcoYSl9fQpXLm5CLnByb3RvdHlwZT17JGluQjoxfQpXLkF6LnByb3RvdHlwZT17JGlBejox
+fQpXLlFQLnByb3RvdHlwZT17JGlRUDoxfQpXLm54LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBhLmxlbmd0aH19Clcub0oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
+Z3RofX0KVy5pZC5wcm90b3R5cGU9e30KVy5RRi5wcm90b3R5cGU9e30KVy5OaC5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLklCLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQo
+YS53aWR0aCkrIiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbCly
+ZXR1cm4hMQpyZXR1cm4gdS5xLmMoYikmJmEubGVmdD09PWIubGVmdCYmYS50b3A9PT1iLnRvcCYmYS53
+aWR0aD09PWIud2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IFcuckUoQy5DRC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCksQy5DRC5naU8oYS53aWR0aCksQy5D
+RC5naU8oYS5oZWlnaHQpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
+ZXR1cm4gYS5sZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2MoYikKdD10aGlzLmEKaWYoYjwwfHxi
+Pj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0aGlzLiR0aS5kLmIodFtiXSl9LApZOmZ1
+bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5kLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkg
+bGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhh
+KX0sCmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNQOmZ1bmN0aW9uKGEsYil7dmFy
+IHQKdS5YLmIoYikKdD10aGlzLmdQKGEpCnQuVjEoMCkKdC5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXty
+ZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIgdD0hIWEuc2Nyb2xsSW50b1ZpZXdJ
+Zk5lZWRlZAppZih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmll
+dygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNo
+KGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9y
+ZShzLGEpCmJyZWFrCmNhc2UiYWZ0ZXJiZWdpbiI6dD1hLmNoaWxkTm9kZXMKYS5pbnNlcnRCZWZvcmUo
+cyx0Lmxlbmd0aD4wP3RbMF06bnVsbCkKYnJlYWsKY2FzZSJiZWZvcmVlbmQiOmEuYXBwZW5kQ2hpbGQo
+cykKYnJlYWsKY2FzZSJhZnRlcmVuZCI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzLGEubmV4dFNp
+YmxpbmcpCmJyZWFrCmRlZmF1bHQ6SC52aChQLnhZKCJJbnZhbGlkIHBvc2l0aW9uICIrYikpfX0sCnI2
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5s
+dAppZih0PT1udWxsKXt0PUguVk0oW10sdS5rKQpzPW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVs
+bCkpCkMuTm0uaSh0LFcuQmwoKSkKJC5sdD1zCmQ9c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7
+dD1uZXcgVy5LbyhkKQokLkVVPXQKYz10fWVsc2V7dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhy
+b3cgSC5iKFAueFkoInZhbGlkYXRvciBjYW4gb25seSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBp
+cyBudWxsIikpCmlmKCQueG89PW51bGwpe3Q9ZG9jdW1lbnQKcz10LmltcGxlbWVudGF0aW9uLmNyZWF0
+ZUhUTUxEb2N1bWVudCgiIikKJC54bz1zCiQuQk89cy5jcmVhdGVSYW5nZSgpCnM9JC54by5jcmVhdGVF
+bGVtZW50KCJiYXNlIikKdS5jUi5iKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVuZENo
+aWxkKHMpfXQ9JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikKdC5i
+b2R5PXUuaS5iKHMpfXQ9JC54bwppZih1LmkuYyhhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVFbGVt
+ZW50KGEudGFnTmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFs
+RnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1l
+KSl7JC5CTy5zZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVu
+dChiKX1lbHNle3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3Io
+O3Q9ci5maXJzdENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYocj09
+bnVsbD90IT1udWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0
+dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6
+ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29udGVu
+dD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUo
+YSwiY2xpY2siLCExLHUuUSl9LAokaWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1l
+fX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmModS5BLmIoYSkpfSwK
+JFM6MjV9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24o
+YSxiLGMsZCl7dS5VLmIoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9uKGEs
+YixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJu
+IGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmIoYyksMSksZCl9LAokaUQwOjF9ClcuVDUucHJv
+dG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
+Z3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZi
+LnByb3RvdHlwZT17fQpXLk83LnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBh
+Lm9wZW4oYixjLCEwKX0sCiRpTzc6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Ro
+aXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEgueShhKSxILnkoYikpfSwKJFM6OH0KVy5oSC5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCnUucC5iKGEpCnQ9dGhpcy5hCnM9dC5zdGF0dXMK
+aWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy50QigpCnI9cz49MjAwJiZzPDMwMApxPXM+MzA3
+JiZzPDQwMApzPXJ8fHM9PT0wfHxzPT09MzA0fHxxCnA9dGhpcy5iCmlmKHMpcC5hTSgwLHQpCmVsc2Ug
+cC5wbShhKX0sCiRTOjE1fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzoxfQpX
+LnU4LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBhLm9y
+aWdpbgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuQWoucHJvdG90eXBlPXskaUFqOjF9ClcuZTcucHJv
+dG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgK
+aWYocz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5Q
+VigiTW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5jdGlv
+bihhLGIpe3ZhciB0LHMscixxCnUuZWguYihiKQp0PWIuYQpzPXRoaXMuYQppZih0IT09cylmb3Iocj10
+LmNoaWxkTm9kZXMubGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hpbGQodC5maXJzdENoaWxkKQpy
+ZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5iKGMpCnQ9dGhpcy5hCnM9dC5jaGls
+ZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQp0LnJlcGxhY2VDaGlsZChj
+LHNbYl0pfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcg
+Vy5XOSh0LHQubGVuZ3RoLEgueksodCkuQygiVzk8R20uRT4iKSl9LApnQTpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5hLmNoaWxkTm9kZXMubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2MoYikK
+dD10aGlzLmEuY2hpbGROb2RlcwppZihiPDB8fGI+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsYikKcmV0
+dXJuIHRbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3ZhciB0PWEucGFyZW50Tm9k
+ZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihhKXt2YXIgdApmb3IoO3Q9
+YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0
+PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwKJGl1SDoxfQpXLkJILnByb3Rv
+dHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNj
+KGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxu
+dWxsKSkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYihjKQp0aHJvdyBILmIoUC5M
+NCgiQ2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCkU6ZnVuY3Rpb24o
+YSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJR
+OjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBlPXt9ClcuZXcucHJvdG90eXBl
+PXskaWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0K
+Vy5UYi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzCmlmKCJjcmVhdGVDb250
+ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxi
+LGMsZCkKdD1XLlU5KCI8dGFibGU+IitILmQoYikrIjwvdGFibGU+IixjLGQpCnM9ZG9jdW1lbnQuY3Jl
+YXRlRG9jdW1lbnRGcmFnbWVudCgpCnMudG9TdHJpbmcKdC50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigw
+LG5ldyBXLmU3KHQpKQpyZXR1cm4gc319ClcuSXYucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHQscyxyLHEKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdl
+LnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PWRvY3VtZW50CnM9dC5jcmVhdGVEb2N1
+bWVudEZyYWdtZW50KCkKdD1DLkllLnI2KHQuY3JlYXRlRWxlbWVudCgidGFibGUiKSxiLGMsZCkKdC50
+b1N0cmluZwp0PW5ldyBXLmU3KHQpCnI9dC5ncjgodCkKci50b1N0cmluZwp0PW5ldyBXLmU3KHIpCnE9
+dC5ncjgodCkKcy50b1N0cmluZwpxLnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcocSkp
+CnJldHVybiBzfX0KVy5XUC5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIK
+aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSlyZXR1
+cm4gdGhpcy5EVyhhLGIsYyxkKQp0PWRvY3VtZW50CnM9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkK
+dD1DLkllLnI2KHQuY3JlYXRlRWxlbWVudCgidGFibGUiKSxiLGMsZCkKdC50b1N0cmluZwp0PW5ldyBX
+LmU3KHQpCnI9dC5ncjgodCkKcy50b1N0cmluZwpyLnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3
+IFcuZTcocikpCnJldHVybiBzfX0KVy55WS5wcm90b3R5cGU9ewpwazpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQscwphLnRleHRDb250ZW50PW51bGwKdD1hLmNvbnRlbnQKdC50b1N0cmluZwpKLmJUKHQpCnM9dGhp
+cy5yNihhLGIsbnVsbCxjKQphLmNvbnRlbnQuYXBwZW5kQ2hpbGQocyl9LApZQzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCiRpeVk6MX0KVy53Ni5wcm90b3R5cGU9e30KVy5LNS5w
+cm90b3R5cGU9ewpQbzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Vy5QMShhLm9wZW4oYixjKSkKcmV0dXJu
+IHR9LApnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9jYXRpb259LAokaUs1OjEsCiRpdjY6MX0KVy5D
+bS5wcm90b3R5cGU9eyRpQ206MX0KVy5DUS5wcm90b3R5cGU9eyRpQ1E6MX0KVy53NC5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJSZWN0YW5nbGUgKCIrSC5kKGEubGVmdCkrIiwgIitILmQoYS50
+b3ApKyIpICIrSC5kKGEud2lkdGgpKyIgeCAiK0guZChhLmhlaWdodCl9LApETjpmdW5jdGlvbihhLGIp
+e2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUucS5jKGIpJiZhLmxlZnQ9PT1iLmxlZnQmJmEudG9w
+PT09Yi50b3AmJmEud2lkdGg9PT1iLndpZHRoJiZhLmhlaWdodD09PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0
+aW9uKGEpe3JldHVybiBXLnJFKEMuQ0QuZ2lPKGEubGVmdCksQy5DRC5naU8oYS50b3ApLEMuQ0QuZ2lP
+KGEud2lkdGgpLEMuQ0QuZ2lPKGEuaGVpZ2h0KSl9fQpXLnJoLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
+KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+Pj4wIT09Ynx8
+Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19
+LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBl
+bGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEu
+bGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDox
+LAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5l
+QS5iKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3Qu
+bGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHAp
+KX19LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtd
+LHUucykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1
+cm4gSC5PSChwLHIpCnE9cy5iKHBbcl0pCmlmKHEubmFtZXNwYWNlVVJJPT1udWxsKUMuTm0uaShvLHEu
+bmFtZSl9cmV0dXJuIG99fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEuaGFzQXR0cmlidXRlKGEpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0QXR0cmli
+dXRlKEgueShiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIsYyl9LApn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBlPXsKeDQ6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hLmhhc0F0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuTyhhKSl9
+LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMu
+TyhILnkoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0i
+K3RoaXMuTyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdS5l
+QS5iKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygwLG5ldyBX
+LkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5n
+dGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMpCmZvcih0PTE7
+dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQppZihzLmxlbmd0aD4wKUMuTm0uWShyLHQsc1swXS50b1VwcGVy
+Q2FzZSgpK0ouS1YocywxKSl9cmV0dXJuIEMuTm0uelYociwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMscixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7czx0Oysrcyl7cT1hW3NdCnA9cS50b0xvd2Vy
+Q2FzZSgpCnI9KHEhPT1wJiZzPjA/cisiLSI6cikrcH1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6
+cn19ClcuS1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0i
+KSl0aGlzLmIuJDIodGhpcy5hLmsoQy54Qi5HKGEsNSkpLGIpfSwKJFM6OH0KVy5BMy5wcm90b3R5cGU9
+ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0aGlzLmIsdGhp
+cy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRTOjh9ClcuSTQucHJvdG90eXBlPXsKREc6ZnVuY3Rpb24oKXt2
+YXIgdCxzLHIscSxwPVAuTHModS5OKQpmb3IodD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscz10
+Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClwLmkoMCxxKX1y
+ZXR1cm4gcH0sCnA6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT11LkMuYihhKS56VigwLCIgIil9
+LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApWMTpmdW5jdGlv
+bihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xh
+c3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiB0fSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5j
+bGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQuYWRkKGIpCnJldHVybiFzfSwKUjpmdW5jdGlvbihhLGIp
+e3ZhciB0PXRoaXMuYS5jbGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQucmVtb3ZlKGIpCnJldHVybiBz
+fSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRoaXMuYSx1LlguYihiKSl9fQpXLkZrLnByb3RvdHlwZT17
+fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZO
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodS5CLmIoYSkpfSwKJFM6
+Mjh9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoJC5vci5hPT09MCl7Zm9y
+KHQ9MDt0PDI2MjsrK3QpJC5vci5ZKDAsQy5jbVt0XSxXLnBTKCkpCmZvcih0PTA7dDwxMjsrK3QpJC5v
+ci5ZKDAsQy5CSVt0XSxXLlY0KCkpfX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiAkLkFOKCkudGcoMCxX
+LnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0kLm9yLnEoMCxILmQoVy5yUyhhKSkrIjo6
+IitiKQppZih0PT1udWxsKXQ9JC5vci5xKDAsIio6OiIrYikKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1
+cm4gSC54ZCh0LiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90b3R5cGU9ewpna3o6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBXLlc5KGEsdGhpcy5nQShhKSxILnpLKGEpLkMoIlc5PEdtLkU+Iikp
+fX0KVy52RC5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3
+IFcuVXYoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5F
+ZyhhLGIsYykpfSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1
+LmUuYihhKS5pMCh0aGlzLmEpfSwKJFM6MTZ9ClcuRWcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHUuZS5iKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjE2fQpXLm02LnByb3Rv
+dHlwZT17CkNZOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp0aGlzLmEuRlYoMCxjKQp0PWIuZXYo
+MCxuZXcgVy5FbygpKQpzPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYoMCx0KQpyPXRoaXMuYwpy
+LkZWKDAsQy54RCkKci5GVigwLHMpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS50ZygwLFcu
+clMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXRoaXMscz1XLnJTKGEpLHI9dC5jCmlmKHIu
+dGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2UgaWYoci50ZygwLCIqOjoiK2Ip
+KXJldHVybiB0LmQuRHQoYykKZWxzZXtyPXQuYgppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJu
+ITAKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsSC5kKHMpKyI6
+OioiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6KiIpKXJldHVybiEwfXJldHVybiExfSwKJGlr
+RjoxfQpXLkVvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiFDLk5tLnRnKEMuQkksSC55
+KGEpKX0sCiRTOjd9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0udGco
+Qy5CSSxILnkoYSkpfSwKJFM6N30KVy5jdC5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYo
+dGhpcy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSImJmM9PT0iIilyZXR1cm4hMApp
+ZihhLmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0aGlzLmUudGcoMCxiKQpyZXR1
+cm4hMX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIlRFTVBMQVRFOjoiK0gu
+ZChILnkoYSkpfSwKJFM6NX0KVy5Pdy5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXt2YXIgdAppZih1
+LmV3LmMoYSkpcmV0dXJuITEKdD11Lmc3LmMoYSkKaWYodCYmVy5yUyhhKT09PSJmb3JlaWduT2JqZWN0
+IilyZXR1cm4hMQppZih0KXJldHVybiEwCnJldHVybiExfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKGI9
+PT0iaXMifHxDLnhCLm4oYiwib24iKSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5pMChhKX0sCiRpa0Y6MX0K
+Vy5XOS5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYysxLHI9dC5iCmlmKHM8
+cil7dC5zTShKLncyKHQuYSxzKSkKdC5jPXMKcmV0dXJuITB9dC5zTShudWxsKQp0LmM9cgpyZXR1cm4h
+MX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCnNNOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlz
+LiR0aS5kLmIoYSl9LAokaUFuOjF9ClcuZFcucHJvdG90eXBlPXsKZ21XOmZ1bmN0aW9uKGEpe3JldHVy
+biBXLkhIKHRoaXMuYS5sb2NhdGlvbil9LAokaUQwOjEsCiRpdjY6MX0KVy5GYi5wcm90b3R5cGU9e30K
+Vy5rRi5wcm90b3R5cGU9e30KVy5tay5wcm90b3R5cGU9eyRpeTA6MX0KVy5Lby5wcm90b3R5cGU9ewpQ
+bjpmdW5jdGlvbihhKXtuZXcgVy5mbSh0aGlzKS4kMihhLG51bGwpfSwKRVA6ZnVuY3Rpb24oYSxiKXtp
+ZihiPT1udWxsKUouTHQoYSkKZWxzZSBiLnJlbW92ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG89ITAsbj1udWxsLG09bnVsbAp0cnl7bj1KLmlnKGEpCm09bi5hLmdldEF0dHJp
+YnV0ZSgiaXMiKQp1LmguYihhKQp0PWZ1bmN0aW9uKGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNl
+b2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQp2YXIgbD1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hp
+bGQmJmMubGFzdENoaWxkIT09bFtsLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlm
+KCEoYy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNl
+b2YgTm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBrPTAKaWYoYy5jaGlsZHJlbilrPWMuY2hpbGRyZW4u
+bGVuZ3RoCmZvcih2YXIgaj0wO2o8aztqKyspe3ZhciBpPWMuY2hpbGRyZW5bal0KaWYoaS5pZD09J2F0
+dHJpYnV0ZXMnfHxpLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aS5pZD09J2xhc3RDaGlsZCd8fGkubmFtZT09
+J2xhc3RDaGlsZCd8fGkuaWQ9PSdjaGlsZHJlbid8fGkubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1
+ZX1yZXR1cm4gZmFsc2V9KGEpCm89SC5vVCh0KT8hMDohKGEuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5h
+bWVkTm9kZU1hcCl9Y2F0Y2gocSl7SC5SdShxKX1zPSJlbGVtZW50IHVucHJpbnRhYmxlIgp0cnl7cz1K
+LmooYSl9Y2F0Y2gocSl7SC5SdShxKX10cnl7cj1XLnJTKGEpCnRoaXMua1IodS5oLmIoYSksYixvLHMs
+cix1LkcuYihuKSxILnkobSkpfWNhdGNoKHEpe2lmKEguUnUocSkgaW5zdGFuY2VvZiBQLnUpdGhyb3cg
+cQplbHNle3RoaXMuRVAoYSxiKQp3aW5kb3cKcD0iUmVtb3ZpbmcgY29ycnVwdGVkIGVsZW1lbnQgIitI
+LmQocykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCl9
+fX0sCmtSOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMKaWYoYyl7
+bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBlbGVtZW50IGR1ZSB0byBjb3JydXB0ZWQgYXR0cmli
+dXRlcyBvbiA8IitkKyI+IgppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNv
+bGUud2Fybih0KQpyZXR1cm59aWYoIW4uYS5pMChhKSl7bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmlu
+ZyBkaXNhbGxvd2VkIGVsZW1lbnQgPCIrSC5kKGUpKyI+IGZyb20gIitILmQoYikKaWYodHlwZW9mIGNv
+bnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKGchPW51bGwp
+aWYoIW4uYS5FYihhLCJpcyIsZykpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dl
+ZCB0eXBlIGV4dGVuc2lvbiA8IitILmQoZSkrJyBpcz0iJytnKyciPicKaWYodHlwZW9mIGNvbnNvbGUh
+PSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufXQ9Zi5nVigpCnM9SC5WTSh0
+LnNsaWNlKDApLEgudDYodCkuQygiamQ8MT4iKSkKZm9yKHI9Zi5nVigpLmxlbmd0aC0xLHQ9Zi5hO3I+
+PTA7LS1yKXtpZihyPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLHIpCnE9c1tyXQpwPW4uYQpvPUouY0go
+cSkKSC55KHEpCmlmKCFwLkViKGEsbyx0LmdldEF0dHJpYnV0ZShxKSkpe3dpbmRvdwpwPSJSZW1vdmlu
+ZyBkaXNhbGxvd2VkIGF0dHJpYnV0ZSA8IitILmQoZSkrIiAiK3ErJz0iJytILmQodC5nZXRBdHRyaWJ1
+dGUocSkpKyciPicKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndh
+cm4ocCkKdC5yZW1vdmVBdHRyaWJ1dGUocSl9fWlmKHUuYVcuYyhhKSluLlBuKGEuY29udGVudCl9LAok
+aW9uOjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMu
+YQpzd2l0Y2goYS5ub2RlVHlwZSl7Y2FzZSAxOnAuSTQoYSxiKQpicmVhawpjYXNlIDg6Y2FzZSAxMTpj
+YXNlIDM6Y2FzZSA0OmJyZWFrCmRlZmF1bHQ6cC5FUChhLGIpfXQ9YS5sYXN0Q2hpbGQKZm9yKHA9dS5B
+O251bGwhPXQ7KXtzPW51bGwKdHJ5e3M9dC5wcmV2aW91c1NpYmxpbmd9Y2F0Y2gocil7SC5SdShyKQpx
+PXAuYih0KQphLnJlbW92ZUNoaWxkKHEpCnQ9bnVsbApzPWEubGFzdENoaWxkfWlmKHQhPW51bGwpdGhp
+cy4kMih0LGEpCnQ9cC5iKHMpfX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnByb3RvdHlw
+ZT17fQpXLnJCLnByb3RvdHlwZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlwZT17fQpQ
+LmlKLnByb3RvdHlwZT17ClZIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5hLHI9cy5sZW5ndGgKZm9y
+KHQ9MDt0PHI7Kyt0KWlmKHNbdF09PT1hKXJldHVybiB0CkMuTm0uaShzLGEpCkMuTm0uaSh0aGlzLmIs
+bnVsbCkKcmV0dXJuIHJ9LApQdjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9e30KaWYoYT09
+bnVsbClyZXR1cm4gYQppZihILmwoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVy
+biBhCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1
+cm4gbmV3IERhdGUoYS5hKQppZih1LmZ2LmMoYSkpdGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xv
+bmUgb2YgUmVnRXhwIikpCmlmKHUuYzguYyhhKSlyZXR1cm4gYQppZih1LmQuYyhhKSlyZXR1cm4gYQpp
+Zih1LkkuYyhhKSlyZXR1cm4gYQp0PXUuZEQuYyhhKXx8ITEKaWYodClyZXR1cm4gYQppZih1LkcuYyhh
+KSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscykKcj1wLmE9dFtz
+XQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5hPXIKQy5ObS5ZKHQscyxyKQphLksoMCxuZXcgUC5s
+UihwLHEpKQpyZXR1cm4gcC5hfWlmKHUuai5jKGEpKXtzPXEuVkgoYSkKcD1xLmIKaWYocz49cC5sZW5n
+dGgpcmV0dXJuIEguT0gocCxzKQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gcS5layhh
+LHMpfWlmKHUuZUguYyhhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9I
+KHQscykKcj1wLmI9dFtzXQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5iPXIKQy5ObS5ZKHQscyxy
+KQpxLmltKGEsbmV3IFAuamcocCxxKSkKcmV0dXJuIHAuYn10aHJvdyBILmIoUC5TWSgic3RydWN0dXJl
+ZCBjbG9uZSBvZiBvdGhlciB0eXBlIikpfSwKZWs6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPUouVTYoYSks
+cj1zLmdBKGEpLHE9bmV3IEFycmF5KHIpCkMuTm0uWSh0aGlzLmIsYixxKQpmb3IodD0wO3Q8cjsrK3Qp
+Qy5ObS5ZKHEsdCx0aGlzLlB2KHMucShhLHQpKSkKcmV0dXJuIHF9fQpQLmxSLnByb3RvdHlwZT17CiQy
+OmZ1bmN0aW9uKGEsYil7dGhpcy5hLmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6MX0KUC5qZy5wcm90b3R5
+cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5iW2FdPXRoaXMuYi5QdihiKX0sCiRTOjF9ClAuQmYu
+cHJvdG90eXBlPXsKaW06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmI4LmIoYikKZm9yKHQ9T2Jq
+ZWN0LmtleXMoYSkscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxhW3FdKX19fQpQ
+LkFzLnByb3RvdHlwZT17ClQ6ZnVuY3Rpb24oYSl7dmFyIHQKSC55KGEpCnQ9JC5oRygpLmIKaWYodHlw
+ZW9mIGEhPSJzdHJpbmciKUgudmgoSC50TChhKSkKaWYodC50ZXN0KGEpKXJldHVybiBhCnRocm93IEgu
+YihQLkwzKGEsInZhbHVlIiwiTm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLkRHKCkuelYoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuREco
+KQpyZXR1cm4gUC5yaih0LHQucixILkxoKHQpLmQpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+REcoKS5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIHRoaXMuREcoKS50ZygwLGIp
+fSwKaTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gSC54ZCh0aGlzLk9TKG5ldyBQLkdFKGIp
+KSl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLkRHKCkKcz10LlIoMCxi
+KQp0aGlzLnAodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MobmV3IFAuTjcodGhp
+cyx1LlguYihiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMKdS5jaC5iKGEpCnQ9dGhpcy5ERygpCnM9YS4kMSh0KQp0aGlzLnAodCkKcmV0
+dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LkMuYihhKS5pKDAs
+dGhpcy5hKX0sCiRTOjQ4fQpQLk43LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
+YixzPUgudDYodCkKcmV0dXJuIHUuQy5iKGEpLkZWKDAsbmV3IEguQTgodCxzLkMoInFVKDEpIikuYih0
+aGlzLmEuZ3VNKCkpLHMuQygiQTg8MSxxVT4iKSkpfSwKJFM6MTd9ClAudVEucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7dS5DLmIoYSkKaWYoYS5hPjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAphLmE9
+MAphLlgoKX1yZXR1cm4gbnVsbH0sCiRTOjE3fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBDLnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuWi5iKGEpCnQ9ZnVuY3Rpb24oYixjLGQpe3Jl
+dHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBs
+eShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0LCQudygpLGEpCnJldHVybiB0fSwKJFM6NH0K
+UC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjR9
+ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6MzR9
+ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9LAok
+UzozNX0KUC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAok
+UzozNn0KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmci
+JiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmlu
+ZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5
+cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0
+eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24o
+YSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09
+Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEpCnJldHVybiB0fWNh
+dGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0aW9uKGEsYil7dmFy
+IHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1QLkNIKG5ldyBILkE4
+KGIsdC5DKCJAKDEpIikuYihQLmlHKCkpLHQuQygiQTg8MSxAPiIpKSwhMCx1LnopfXJldHVybiBQLkw3
+KHNbYV0uYXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlw
+ZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+PXQu
+Z0EodCkKaWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rp
+b24oYSxiKXtpZih0eXBlb2YgYj09Im51bWJlciImJmI9PT1DLmpuLnl1KGIpKXRoaXMuY1AoSC5TYyhi
+KSkKcmV0dXJuIHRoaXMuJHRpLmQuYih0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQKdGhpcy4kdGkuZC5iKGMpCnQ9Qy5qbi55dShiKQppZihiPT09dCl0aGlzLmNQKGIpCnRoaXMuZTQo
+MCxiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJu
+dW1iZXIiJiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0
+aCIpKX0sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAubmQucHJvdG90
+eXBlPXskaW5kOjF9ClAuS2UucHJvdG90eXBlPXsKREc6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRo
+aXMuYS5nZXRBdHRyaWJ1dGUoImNsYXNzIiksbz1QLkxzKHUuTikKaWYocD09bnVsbClyZXR1cm4gbwpm
+b3IodD1wLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEu
+bGVuZ3RoIT09MClvLmkoMCxxKX1yZXR1cm4gb30sCnA6ZnVuY3Rpb24oYSl7dGhpcy5hLnNldEF0dHJp
+YnV0ZSgiY2xhc3MiLGEuelYoMCwiICIpKX19ClAuZDUucHJvdG90eXBlPXsKZ1A6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcjY6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGQ9PW51bGwpe3Q9SC5WTShbXSx1LmspCmQ9
+bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgpKQpDLk5tLmkodCxu
+ZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnM9JzxzdmcgdmVyc2lvbj0iMS4xIj4nK0guZChiKSsiPC9z
+dmc+Igp0PWRvY3VtZW50CnI9dC5ib2R5CnE9KHImJkMuUlkpLkFIKHIscyxjKQpwPXQuY3JlYXRlRG9j
+dW1lbnRGcmFnbWVudCgpCnEudG9TdHJpbmcKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7dD1v
+LmZpcnN0Q2hpbGQsdCE9bnVsbDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCm56OmZ1bmN0aW9u
+KGEsYixjLGQsZSl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBpbnZva2UgaW5zZXJ0QWRqYWNlbnRIdG1s
+IG9uIFNWRy4iKSl9LApnVmw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwhMSx1
+LlEpfSwKJGlkNToxfQpQLm42LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjEsJGlBUzoxfQpV
+LmQyLnByb3RvdHlwZT17fQpVLlNlLnByb3RvdHlwZT17fQpVLk1sLnByb3RvdHlwZT17fQpVLnlELnBy
+b3RvdHlwZT17fQpVLndiLnByb3RvdHlwZT17fQpCLmo4LnByb3RvdHlwZT17fQpCLnFwLnByb3RvdHlw
+ZT17fQpULm1RLnByb3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQs
+cyxyLHEscCxvLG4KdS5CLmIoYSkKdD13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUKcz1MLkc2KHdpbmRv
+dy5sb2NhdGlvbi5ocmVmKQpyPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCkwuR2UoKQppZih0IT09
+Ii8iJiZ0IT09Si5UMChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSlM
+Lkc3KHQscyxyLCEwLG5ldyBMLlZXKHQscyxyKSkKcT1kb2N1bWVudApwPUoucUYocS5xdWVyeVNlbGVj
+dG9yKCIuYXBwbHktbWlncmF0aW9uIikpCm89cC4kdGkKbj1vLkMoIn4oMSkiKS5iKG5ldyBMLm9aKCkp
+CnUuTS5iKG51bGwpClcuSkUocC5hLHAuYixuLCExLG8uZCkKbz1KLnFGKHEucXVlcnlTZWxlY3Rvcigi
+LnJlcnVuLW1pZ3JhdGlvbiIpKQpuPW8uJHRpClcuSkUoby5hLG8uYixuLkMoIn4oMSkiKS5iKG5ldyBM
+Lnk4KCkpLCExLG4uZCkKbj1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm89
+bi4kdGkKVy5KRShuLmEsbi5iLG8uQygifigxKSIpLmIobmV3IEwuSGkoKSksITEsby5kKQpxPUoucUYo
+cS5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFuZSAuY2xvc2UiKSkKbz1xLiR0aQpXLkpFKHEuYSxxLmIs
+by5DKCJ+KDEpIikuYihuZXcgTC5CVCgpKSwhMSxvLmQpfSwKJFM6MTh9CkwuVlcucHJvdG90eXBlPXsK
+JDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5WLmIoYSkKaWYoSC5vVCh3aW5kb3cuY29uZmlybSgiVGhpcyB3
+aWxsIGFwcGx5IHRoZSBjaGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVj
+dG9yeS4gSXQgaXMgcmVjb21tZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZv
+cmUgZG9pbmcgdGhpcy4iKSkpTC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIpLlc3KG5ldyBMLmpyKCksdS5Q
+KS5PQShuZXcgTC5xbCgpKX0sCiRTOjN9CkwuanIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQKdS5TLmIoYSkKdD1kb2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQp0
+LmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjM5fQpMLnFsLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7TC5DMigiQ291bGQgbm90IGFwcGx5IG1pZ3JhdGlvbiIsYSxiKX0sCiRDOiIkMiIsCiRS
+OjIsCiRTOjF9CkwueTgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMueG4odS5W
+LmIoYSkpfSwKeG46ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgodS5QKSxyPTEscSxwPVtdLG8sbixt
+LGwKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUo
+dHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOnI9Mwpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVu
+bmluZyIpCnQ9NgpyZXR1cm4gUC5qUShMLnR5KCIvcmVydW4tbWlncmF0aW9uIiksJGFzeW5jJCQxKQpj
+YXNlIDY6d2luZG93LmxvY2F0aW9uLnJlbG9hZCgpCnAucHVzaCg1KQp0PTQKYnJlYWsKY2FzZSAzOnI9
+MgpsPXEKbz1ILlJ1KGwpCm49SC50cyhsKQpMLkMyKCJGYWlsZWQgdG8gcmVydW4gbWlncmF0aW9uIixv
+LG4pCnAucHVzaCg1KQp0PTQKYnJlYWsKY2FzZSAyOnA9WzFdCmNhc2UgNDpyPTEKZG9jdW1lbnQuYm9k
+eS5jbGFzc0xpc3QucmVtb3ZlKCJyZXJ1bm5pbmciKQp0PXAucG9wKCkKYnJlYWsKY2FzZSA1OnJldHVy
+biBQLnlDKG51bGwscykKY2FzZSAxOnJldHVybiBQLmYzKHEscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5j
+JCQxLHMpfSwKJFM6NDB9CkwuSGkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmIo
+YSkKdD11Lk4KQy5vbC5Qbyh3aW5kb3csUC5YZCgiaHR0cHMiLCJnaXRodWIuY29tIiwiZGFydC1sYW5n
+L3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsibGFiZWxzIiwiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJk
+LW1pZ3JhdGlvbix0eXBlLWJ1ZyIsImJvZHkiLCIjIyMjIFN0ZXBzIHRvIHJlcHJvZHVjZVxuXG4jIyMj
+IFdoYXQgZGlkIHlvdSBleHBlY3QgdG8gaGFwcGVuP1xuXG4jIyMjIFdoYXQgYWN0dWFsbHkgaGFwcGVu
+ZWQ/XG5cbl9TY3JlZW5zaG90cyBhcmUgYXBwcmVjaWF0ZWRfXG5cbioqRGFydCBTREsgdmVyc2lvbioq
+OiAiK0guZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkr
+IlxuXG5UaGFua3MgZm9yIGZpbGluZyFcbiJdLHQsdCkpLncoMCksInJlcG9ydC1wcm9ibGVtIil9LAok
+UzozfQpMLkJULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5iKGEpCnQ9ZG9jdW1l
+bnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQpyZXR1cm4gdC5kaXNwbGF5PSJub25l
+In0sCiRTOjQxfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuQi5iKGEp
+CnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcj1M
+LmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzcodCxzLHIsITEsbnVsbCkK
+ZWxzZXtMLkJFKHQsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksITApCkwuQlgoIiZuYnNwOyIsbnVsbCl9
+fSwKJFM6MTh9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9ImNvbGxh
+cHNlZCIKdS5WLmIoYSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdQKHQpLnRnKDAs
+cSkpe3MuZ1AodCkuaSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nUCh0KS5SKDAscSkKSi5kUihy
+KS5SKDAscSl9fSwKJFM6M30KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFG
+KHUuaC5iKGEpKSxzPXQuJHRpLHI9cy5DKCJ+KDEpIikuYihuZXcgTC5kTih0aGlzLmEpKQp1Lk0uYihu
+dWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmQpfSwKJFM6Nn0KTC5kTi5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXt2YXIgdAp1LlYuYihhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEt
+cGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcg
+Vy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzozfQpMLkhvLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscgp1LmguYihhKQp0PUoucUYoYSkKcz10LiR0aQpyPXMuQygifigxKSIp
+LmIobmV3IEwueHooYSx0aGlzLmEpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmQpfSwK
+JFM6Nn0KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPW51bGwKdS5WLmIoYSkK
+dD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5l
+dyBXLmk3KHQpKS5PKCJvZmZzZXQiKSkscyxzKSxQLlFBKHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3
+IFcuU3kobmV3IFcuaTcodCkpLk8oImxpbmUiKSkscyxzKSl9LAokUzozfQpMLklDLnByb3RvdHlwZT17
+CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PUoucUYodS5oLmIoYSkpLHM9dC4kdGkKcy5DKCJ+KDEpIikuYihM
+LmlTKCkpCnUuTS5iKG51bGwpClcuSkUodC5hLHQuYixMLmlTKCksITEscy5kKX0sCiRTOjZ9CkwuTDEu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5wLmIoYSkKdGhpcy5hLmFNKDAsdGhpcy5iKX0sCiRT
+OjE1fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSx0aGlzLmIsdGhp
+cy5jKX0sCiRTOjB9CkwuQloucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYS5hLG51
+bGwsbnVsbCl9LAokUzowfQpMLkdILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3UuaC5iKGEpCiQu
+ekIoKS50b1N0cmluZwp1LnYuYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRCbG9jayIs
+W2FdKX0sCiRTOjZ9CkwuRFQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1LnIuYihh
+KQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe3Q9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpCnM9
+Si5VNih0KQpMLlQxKG5ldyBVLmQyKFUuamYocy5xKHQsImVkaXRzIikpLEguYzAocy5xKHQsImV4cGxh
+bmF0aW9uIikpLEguV1kocy5xKHQsImxpbmUiKSksSC5jMChzLnEodCwicGF0aCIpKSxVLk5kKHMucSh0
+LCJ0cmFjZXMiKSkpKQpMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKQpMLnlYKCIuZWRpdC1wYW5lbCAu
+cGFuZWwtY29udGVudCIsITEpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVz
+IG9mICIrSC5kKHQpKX0sCiRTOjl9CkwuZUgucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFK
+KCJsb2FkUmVnaW9uRXhwbGFuYXRpb246ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90
+IGxvYWQgIitILmQodGhpcy5hKSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9
+CkwueXUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMKdS5yLmIoYSkKdD1h
+LnN0YXR1cwppZih0PT09MjAwKXtzPXIuYQpMLkJFKHMsQi5ZZih1LmIuYShDLkN0LnBXKDAsYS5yZXNw
+b25zZVRleHQsbnVsbCkpKSxyLmIpCnQ9ci5jCkwuZkcodCxyLmQpCkwuQlgoQy54Qi50ZyhzLCI/Iik/
+Qy54Qi5OaihzLDAsQy54Qi5PWShzLCI/IikpOnMsdCkKdD1yLmUKaWYodCE9bnVsbCl0LiQwKCl9ZWxz
+ZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6OX0K
+TC56RC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxvYWRGaWxlOiAiK0guZChhKSxi
+KQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5vdCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEpKyIpLiIpfSwK
+JEM6IiQyIiwKJFI6MiwKJFM6MX0KTC5UVy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxz
+LHIKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4
+dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5uYXYtdHJlZSIpCkoubDUociwiIikKTC50
+WChyLEwubUsocykpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIr
+SC5kKHQpKX0sCiRTOjl9CkwueHIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2Fk
+TmF2aWdhdGlvblRyZWU6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIit0
+aGlzLmErIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkVFLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5WLmIoYSkKdD10aGlzLmEKcz10aGlzLmIKTC5hZih3
+aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdCxzLCEwLG5ldyBMLlFMKHQscykpCkwuaFgodGhpcy5jLHQs
+cyl9LAokUzozfQpMLlFMLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih3aW5kb3cubG9jYXRp
+b24ucGF0aG5hbWUsdGhpcy5hLHRoaXMuYil9LAokUzowfQpMLlZTLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0LHM9InNlbGVjdGVkLWZpbGUiCnUuaC5iKGEpCmEudG9TdHJpbmcKdD1KLlJFKGEp
+CmlmKGEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcoYSkpLk8oIm5hbWUiKSk9
+PT10aGlzLmEuYSl0LmdQKGEpLmkoMCxzKQplbHNlIHQuZ1AoYSkuUigwLHMpfSwKJFM6Nn0KTC5URC5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gTC50Mih1LlYuYihhKSwhMCxudWxsKX0sCiRT
+OjE5fQpMLlhBLnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4hMH0sCmkwOmZ1bmN0
+aW9uKGEpe3JldHVybiEwfSwKJGlrRjoxfQpMLlpaLnByb3RvdHlwZT17fQpMLk85LnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19Ck0ubEkucHJvdG90eXBlPXsKV086ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPW51bGwKTS5ZRigiYWJzb2x1dGUiLEguVk0oW2IsbnVsbCxudWxsLG51bGwsbnVs
+bCxudWxsLG51bGxdLHUucykpCnQ9dGhpcy5hCnQ9dC5ZcihiKT4wJiYhdC5oSyhiKQppZih0KXJldHVy
+biBiCnQ9RC5SWCgpCnJldHVybiB0aGlzLnE3KDAsdCxiLHMscyxzLHMscyxzKX0sCnRNOmZ1bmN0aW9u
+KGEpe3ZhciB0LHMscj1YLkNMKGEsdGhpcy5hKQpyLklWKCkKdD1yLmQKcz10Lmxlbmd0aAppZihzPT09
+MCl7dD1yLmIKcmV0dXJuIHQ9PW51bGw/Ii4iOnR9aWYocz09PTEpe3Q9ci5iCnJldHVybiB0PT1udWxs
+PyIuIjp0fWlmKDA+PXMpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSkKci5JVigp
+CnJldHVybiByLncoMCl9LApxNzpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQ9SC5WTShb
+YixjLGQsZSxmLGcsaCxpXSx1LnMpCk0uWUYoImpvaW4iLHQpCnJldHVybiB0aGlzLklQKG5ldyBILlU1
+KHQsdS5iQi5iKG5ldyBNLk1pKCkpLHUuY2MpKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAs
+byxuLG0sbAp1LlguYihhKQpmb3IodD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5iKG5ldyBNLnE3KCkp
+LHI9YS5na3ooYSksdD1uZXcgSC5TTyhyLHMsdC5DKCJTTzxjWC5FPiIpKSxzPXRoaXMuYSxxPSExLHA9
+ITEsbz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikmJnApe209WC5DTChuLHMpCmw9by5jaGFy
+Q29kZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1vCmlmKHMuZHMobykp
+Qy5ObS5ZKG0uZSwwLHMuZ21JKCkpCm89bS53KDApfWVsc2UgaWYocy5ZcihuKT4wKXtwPSFzLmhLKG4p
+Cm89SC5kKG4pfWVsc2V7aWYoIShuLmxlbmd0aD4wJiZzLlVkKG5bMF0pKSlpZihxKW8rPXMuZ21JKCkK
+bys9SC5kKG4pfXE9cy5kcyhuKX1yZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCm81OmZ1bmN0
+aW9uKGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnQ9WC5DTChhLHRoaXMuYSkKdC5yUigp
+CnJldHVybiB0LncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsawphLnRv
+U3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09MCl7aWYodD09PSQuS2soKSlmb3Iocj0wO3I8
+czsrK3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4hMApxPXMKcD00N31lbHNle3E9MApwPW51bGx9
+Zm9yKG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9cSxtPW51bGw7cjxuOysrcixtPXAscD1sKXts
+PUMueEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0kLktrKCkmJmw9PT00NylyZXR1cm4hMAppZihw
+IT1udWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00NilrPW09PW51bGx8fG09PT00Nnx8dC5yNCht
+KQplbHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09bnVsbClyZXR1cm4hMAppZih0LnI0KHApKXJl
+dHVybiEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQobSl8fG09PT00NgplbHNlIHQ9ITEKaWYodCly
+ZXR1cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPXRoaXMsbj0n
+VW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5XTygwLGIpCnQ9by5hCmlmKHQuWXIoYik8PTAm
+JnQuWXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0LllyKGEpPD0wfHx0LmhLKGEpKWE9by5XTygwLGEp
+CmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBILmIoWC5JNyhuK0guZChhKSsnIiBmcm9tICIn
+K0guZChiKSsnIi4nKSkKcz1YLkNMKGIsdCkKcy5yUigpCnI9WC5DTChhLHQpCnIuclIoKQpxPXMuZApp
+ZihxLmxlbmd0aD4wJiZKLlJNKHFbMF0sIi4iKSlyZXR1cm4gci53KDApCnE9cy5iCnA9ci5iCmlmKHEh
+PXApcT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihxKXJldHVybiByLnco
+MCkKd2hpbGUoITApe3E9cy5kCmlmKHEubGVuZ3RoPjApe3A9ci5kCnE9cC5sZW5ndGg+MCYmdC5OYyhx
+WzBdLHBbMF0pfWVsc2UgcT0hMQppZighcSlicmVhawpDLk5tLlc0KHMuZCwwKQpDLk5tLlc0KHMuZSwx
+KQpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKX1xPXMuZAppZihxLmxlbmd0aD4wJiZKLlJNKHFb
+MF0sIi4uIikpdGhyb3cgSC5iKFguSTcobitILmQoYSkrJyIgZnJvbSAiJytILmQoYikrJyIuJykpCnE9
+dS5OCkMuTm0uVUcoci5kLDAsUC5POChzLmQubGVuZ3RoLCIuLiIscSkpCkMuTm0uWShyLmUsMCwiIikK
+Qy5ObS5VRyhyLmUsMSxQLk84KHMuZC5sZW5ndGgsdC5nbUkoKSxxKSkKdD1yLmQKcT10Lmxlbmd0aApp
+ZihxPT09MClyZXR1cm4iLiIKaWYocT4xJiZKLlJNKEMuTm0uZ3JaKHQpLCIuIikpe3Q9ci5kCmlmKDA+
+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKdD1yLmUKQy5ObS5tdih0KQpDLk5tLm12
+KHQpCkMuTm0uaSh0LCIiKX1yLmI9IiIKci5JVigpCnJldHVybiByLncoMCl9fQpNLk1pLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPW51bGx9LAokUzo3fQpNLnE3LnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPT0iIn0sCiRTOjd9Ck0uTm8ucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7SC55KGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAok
+Uzo1fQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5ZcihhKQppZihz
+PjApcmV0dXJuIEoubGQoYSwwLHMpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBI
+Lk9IKGEsMCkKdD1hWzBdfWVsc2UgdD1udWxsCnJldHVybiB0fSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSVY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcwp3aGls
+ZSghMCl7dD1yLmQKaWYoISh0Lmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloodCksIiIpKSlicmVhawp0
+PXIuZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCkMuTm0ubXYoci5lKX10
+PXIuZQpzPXQubGVuZ3RoCmlmKHM+MClDLk5tLlkodCxzLTEsIiIpfSwKclI6ZnVuY3Rpb24oKXt2YXIg
+dCxzLHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtdLHUucykKZm9yKHQ9bS5kLHM9dC5sZW5ndGgscj0w
+LHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0Kbz1KLmlh
+KHApCmlmKCEoby5ETihwLCIuIil8fG8uRE4ocCwiIikpKWlmKG8uRE4ocCwiLi4iKSlpZihsLmxlbmd0
+aD4wKWwucG9wKCkKZWxzZSArK3IKZWxzZSBDLk5tLmkobCxwKX1pZihtLmI9PW51bGwpQy5ObS5VRyhs
+LDAsUC5POChyLCIuLiIsdS5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9PW51bGwpQy5ObS5pKGwsIi4i
+KQpuPVAuZEgobC5sZW5ndGgsbmV3IFgucVIobSksITAsdS5OKQp0PW0uYgp0PXQhPW51bGwmJmwubGVu
+Z3RoPjAmJm0uYS5kcyh0KT9tLmEuZ21JKCk6IiIKSC50NihuKS5kLmIodCkKaWYoISFuLmZpeGVkJGxl
+bmd0aClILnZoKFAuTDQoImluc2VydCIpKQpuLnNwbGljZSgwLDAsdCkKbS5zbkoobCkKbS5zUGgobikK
+dD1tLmIKaWYodCE9bnVsbCYmbS5hPT09JC5LaygpKXt0LnRvU3RyaW5nCm0uYj1ILnlzKHQsIi8iLCJc
+XCIpfW0uSVYoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1yLmIKcT1xIT1udWxsP3E6
+IiIKZm9yKHQ9MDt0PHIuZC5sZW5ndGg7Kyt0KXtzPXIuZQppZih0Pj1zLmxlbmd0aClyZXR1cm4gSC5P
+SChzLHQpCnM9cStILmQoc1t0XSkKcT1yLmQKaWYodD49cS5sZW5ndGgpcmV0dXJuIEguT0gocSx0KQpx
+PXMrSC5kKHFbdF0pfXErPUguZChDLk5tLmdyWihyLmUpKQpyZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0w
+P3E6cX0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dS5hLmIoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhp
+cy5lPXUuYS5iKGEpfX0KWC5xUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+LmEuZ21JKCl9LAokUzo0NX0KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRo
+RXhjZXB0aW9uOiAiK3RoaXMuYX19Ck8uekwucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5nb2ModGhpcyl9fQpFLk9GLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhC
+LnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2
+YXIgdD1hLmxlbmd0aApyZXR1cm4gdCE9PTAmJkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9u
+KGEsYil7aWYoYS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwK
+WXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4h
+MX0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9
+fQpGLnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0
+OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aApp
+Zih0PT09MClyZXR1cm4hMQppZihDLnhCLm0oYSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIu
+VGMoYSwiOi8vIikmJnRoaXMuWXIoYSk9PT10fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
+PWEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9y
+KHQ9MDt0PHA7Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lm
+KHQ9PT0wKXJldHVybiAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQpp
+ZihyPD0wKXJldHVybiBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8i
+KSlyZXR1cm4gcgppZighQi5ZdShhLHIrMSkpcmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0
+fX1yZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rp
+b24oYSl7cmV0dXJuIGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigp
+e3JldHVybiJ1cmwifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpV
+ZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4g
+YT09PTQ3fHxhPT09OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1
+cm4hMQp0PUMueEIubShhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMscj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9
+PT00NylyZXR1cm4gMQppZih0PT09OTIpe2lmKHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpz
+PUMueEIuWFUoYSwiXFwiLDIpCmlmKHM+MCl7cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1
+cm4gc31yZXR1cm4gcn1pZihyPDMpcmV0dXJuIDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5X
+KGEsMSkhPT01OClyZXR1cm4gMApyPUMueEIuVyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVy
+biAwCnJldHVybiAzfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9
+PT1iKXJldHVybiEwCmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3
+CmlmKChhXmIpIT09MzIpcmV0dXJuITEKdD1hfDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHIKaWYoYT09YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxl
+bmd0aClyZXR1cm4hMQpmb3Iocz1KLnJZKGIpLHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhh
+LHIpLHMuVyhiLHIpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5k
+b3dzIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0
+PUoudkIucHJvdG90eXBlCnQuVT10LncKdC5Taj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQudwp0
+PVAuY1gucHJvdG90eXBlCnQuR0c9dC5ldgp0PVAuay5wcm90b3R5cGUKdC54Yj10LncKdD1XLmN2LnBy
+b3RvdHlwZQp0LkRXPXQucjYKdD1XLm02LnByb3RvdHlwZQp0LmpGPXQuRWIKdD1QLkU0LnByb3RvdHlw
+ZQp0LlVyPXQucQp0LmU0PXQuWX0pKCk7KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciB0PWh1
+bmtIZWxwZXJzLl9zdGF0aWNfMSxzPWh1bmtIZWxwZXJzLl9zdGF0aWNfMCxyPWh1bmtIZWxwZXJzLmlu
+c3RhbGxJbnN0YW5jZVRlYXJPZmYscT1odW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZixwPWh1
+bmtIZWxwZXJzLl9pbnN0YW5jZV8xdQp0KFAsIkVYIiwiWlYiLDEwKQp0KFAsInl0Iiwib0EiLDEwKQp0
+KFAsInFXIiwiQnoiLDEwKQpzKFAsIlVJIiwiZU4iLDIpCnIoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwx
+LG51bGwsWyIkMiIsIiQxIl0sWyJ3MCIsInBtIl0sMjksMCkKdChQLCJQSCIsIk10Iiw1KQpxKFcsInBT
+Iiw0LG51bGwsWyIkNCJdLFsieVciXSwxMSwwKQpxKFcsIlY0Iiw0LG51bGwsWyIkNCJdLFsiUVciXSwx
+MSwwKQpwKFAuQXMucHJvdG90eXBlLCJndU0iLCJUIiw1KQp0KFAsImlHIiwid1kiLDQpCnQoUCwidzAi
+LCJMNyIsMzIpCnQoTCwiaVMiLCJpNiIsMTkpfSkoKTsoZnVuY3Rpb24gaW5oZXJpdGFuY2UoKXt2YXIg
+dD1odW5rSGVscGVycy5taXhpbixzPWh1bmtIZWxwZXJzLmluaGVyaXQscj1odW5rSGVscGVycy5pbmhl
+cml0TWFueQpzKFAuayxudWxsKQpyKFAuayxbSC5lbyxKLnZCLEoubTEsUC5uWSxQLmNYLEguYTcsUC5B
+bixILlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksUC5YUyxILmJxLEguWE8sUC5Z
+ayxILmRiLEguTjYsSC5WUixILkVLLEguUGIsSC50USxILlNkLEguSmMsSC5HLFAuVzMsUC5paCxQLkZ5
+LFAuR1YsUC5iOCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQLmtULFAueEksUC5DdyxQLm0w
+LFAuWHYsUC5ibixQLmxtLFAubEQsUC5LUCxQLmxmLFAuVEMsUC5VayxQLlJ3LFAuYnosUC5hMixQLmlQ
+LFAuRkssUC5rNSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5aMCxQLk4zLFAuYzgsUC5PZCxQLmli
+LFAuR3osUC5xVSxQLlJuLFAuR0QsUC5EbixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZE
+LFcubTYsVy5PdyxXLlc5LFcuZFcsVy5GYixXLmtGLFcubWssVy5LbyxQLmlKLFAuRTQsUC5uNixVLmQy
+LFUuU2UsVS5NbCxVLnlELFUud2IsQi5qOCxCLnFwLFQubVEsTC5YQSxMLlpaLEwuTzksTS5sSSxPLnpM
+LFguV0QsWC5kdl0pCnIoSi52QixbSi55RSxKLllFLEouTUYsSi5qZCxKLnFJLEouRHIsSC5FVCxXLkQw
+LFcuQXosVy5MZSxXLk5oLFcuSUIsVy5uNyxXLmVhLFcuYnIsVy5TZyxXLnU4LFcuSzcsVy5YVyxQLmhG
+XSkKcihKLk1GLFtKLmlDLEoua2QsSi5jNV0pCnMoSi5QbyxKLmpkKQpyKEoucUksW0oudXIsSi5WQV0p
+CnMoUC5MVSxQLm5ZKQpyKFAuTFUsW0guWEMsVy53eixXLmU3XSkKcyhILnFqLEguWEMpCnIoUC5jWCxb
+SC5iUSxILmkxLEguVTUsSC5YUixQLm1XLEgudW5dKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1XSkKcihI
+LmFMLFtILm5ILEguQTgsUC5pOF0pCnMoSC54eSxILmkxKQpyKFAuQW4sW0guTUgsSC5TT10pCnMoUC5S
+VSxQLlBuKQpzKFAuR2osUC5SVSkKcyhILlBELFAuR2opCnMoSC5MUCxILldVKQpyKEguVHAsW0guQ2os
+SC5BbSxILmxjLEguZEMsSC53TixILlZYLFAudGgsUC5oYSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gs
+UC5HcyxQLmRhLFAub1EsUC5wVixQLlU3LFAudnIsUC5ySCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEs
+UC5SVyxQLkI1LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5PUixQLnJhLFAueVEsUC5XRixQLm4xLFAuY1Ms
+UC5WQyxQLkpULFAuZTEsUC5OWSxQLlJaLFAuTUUsUC55NSxQLnEzLFAueUksUC5jNixQLnFkLFcuQ3Ys
+Vy5iVSxXLmhILFcuS1MsVy5BMyxXLnZOLFcuVXYsVy5FZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAubFIs
+UC5qZyxQLkdFLFAuTjcsUC51USxQLlBDLFAubXQsUC5OeixQLlFTLFAubnAsTC5lLEwuVlcsTC5vWixM
+LmpyLEwucWwsTC55OCxMLkhpLEwuQlQsTC5MLEwuV3gsTC5BTyxMLmROLEwuSG8sTC54eixMLklDLEwu
+TDEsTC5uVCxMLkJaLEwuR0gsTC5EVCxMLmVILEwueXUsTC56RCxMLlRXLEwueHIsTC5FRSxMLlFMLEwu
+VlMsTC5URCxNLk1pLE0ucTcsTS5ObyxYLnFSXSkKcihQLlhTLFtILlcwLEguYXosSC52VixILkVxLFAu
+QzYsSC51OSxQLm4sUC51LFAubXAsUC51YixQLmRzLFAubGosUC5VVixQLmNdKQpyKEgubGMsW0guengs
+SC5yVF0pCnMoSC5rWSxQLkM2KQpzKFAuaWwsUC5ZaykKcihQLmlsLFtILk41LFAudXcsVy5jZixXLlN5
+XSkKcihQLm1XLFtILktXLFAucTRdKQpzKEguYjAsSC5FVCkKcihILmIwLFtILlJHLEguV0JdKQpzKEgu
+VlAsSC5SRykKcyhILkRnLEguVlApCnMoSC5aRyxILldCKQpzKEguUGcsSC5aRykKcihILlBnLFtILnhq
+LEguZEUsSC5aQSxILndmLEguUHEsSC5lRSxILlY2XSkKcihILnU5LFtILmh6LEguaU1dKQpzKFAuWmYs
+UC5QZikKcyhQLkppLFAubTApCnMoUC5iNixQLlh2KQpzKFAuVmosUC5UQykKcihQLlVrLFtQLkNWLFAu
+WmksUC5ieV0pCnMoUC53SSxQLmtUKQpyKFAud0ksW1AuVTgsUC5NeCxQLkUzLFAuR1ldKQpzKFAudTUs
+UC5aaSkKcihQLkZLLFtQLkNQLFAuS05dKQpyKFAudSxbUC5iSixQLmVZXSkKcyhQLnFlLFAuRG4pCnIo
+Vy5EMCxbVy51SCxXLndhLFcuSzUsVy5DbV0pCnIoVy51SCxbVy5jdixXLm54LFcuUUYsVy5DUV0pCnIo
+Vy5jdixbVy5xRSxQLmQ1XSkKcihXLnFFLFtXLkdoLFcuZlksVy5uQixXLlFQLFcuaDQsVy5TTixXLmxw
+LFcuVGIsVy5JdixXLldQLFcueVldKQpzKFcub0osVy5MZSkKcyhXLlQ1LFcuQXopCnMoVy5WYixXLlFG
+KQpzKFcuTzcsVy53YSkKcihXLmVhLFtXLnc2LFcuZXddKQpzKFcuQWosVy53NikKcyhXLnJCLFcuSzcp
+CnMoVy5CSCxXLnJCKQpzKFcudzQsVy5JQikKcyhXLm9hLFcuWFcpCnMoVy5yaCxXLm9hKQpzKFcuaTcs
+Vy5jZikKcyhQLkFzLFAuVmopCnIoUC5BcyxbVy5JNCxQLktlXSkKcyhXLlJPLFAucWgpCnMoVy5ldSxX
+LlJPKQpzKFcueEMsUC5NTykKcyhXLmN0LFcubTYpCnMoUC5CZixQLmlKKQpyKFAuRTQsW1AucjcsUC5j
+b10pCnMoUC5UeixQLmNvKQpzKFAubmQsUC5kNSkKcyhCLmZ2LE8uekwpCnIoQi5mdixbRS5PRixGLnJ1
+LEwuSVZdKQp0KEguWEMsSC5SZSkKdChILlJHLFAubEQpCnQoSC5WUCxILlNVKQp0KEguV0IsUC5sRCkK
+dChILlpHLEguU1UpCnQoUC5uWSxQLmxEKQp0KFAuVEMsUC5sZikKdChQLlJVLFAuS1ApCnQoVy5MZSxX
+LmlkKQp0KFcuSzcsUC5sRCkKdChXLnJCLFcuR20pCnQoVy5YVyxQLmxEKQp0KFcub2EsVy5HbSkKdChQ
+LmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30sZVQ6e30s
+dFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntLTjoiaW50IixDUDoiZG91YmxlIixGSzoi
+bnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xlZE5hbWVz
+Ont9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBlczpbImM4
+KCkiLCJjOChALEApIiwifigpIiwiYzgoQWopIiwiQChAKSIsInFVKHFVKSIsImM4KGN2KSIsImEyKHFV
+KSIsImM4KHFVLHFVKSIsImM4KE83KSIsIn4ofigpKSIsImEyKGN2LHFVLHFVLEpRKSIsImM4KEApIiwi
+YzgocVUsQCkiLCJjOChxVSkiLCJjOChldykiLCJhMihrRikiLCJ+KHh1PHFVPikiLCJjOChlYSkiLCJ+
+KEFqKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwifihAKSIsIn4ocVUscVUpIiwibjYoS04pIiwi
+bjYoQCxAKSIsImEyKHVIKSIsImM4KEAsR3opIiwiYzgoS04sQCkiLCJAKGVhKSIsIn4oa1tHel0pIiwi
+YzgoQFtHel0pIiwifih1SCx1SCkiLCJrKEApIiwidnM8QD4oQCkiLCJyNyhAKSIsIlR6PEA+KEApIiwi
+RTQoQCkiLCJjOCh+KCkpIiwiYzgoR0QsQCkiLCJjOChaMDxxVSxrPikiLCJiODxjOD4oQWopIiwicVUo
+QWopIiwiQChxVSkiLCJ+KHFVLEtOKSIsIn4ocVVbQF0pIiwicVUoS04pIiwiS04oS04sS04pIiwiQChA
+LHFVKSIsImEyKHh1PHFVPikiXSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGx9Ckgu
+eGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYi
+LCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJ0cCI6ImQ1IiwidjAiOiJldyIsIk1yIjoicUUi
+LCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwieWMiOiJBaiIsInk0IjoidzYi
+LCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEy
+IjpbXX0sIllFIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJd
+LCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIx
+Il0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiRksiOltdfSwidXIi
+OnsiS04iOltdLCJDUCI6W10sIkZLIjpbXX0sIlZBIjp7IkNQIjpbXSwiRksiOltdfSwiRHIiOnsicVUi
+OltdLCJ2WCI6W119LCJxaiI6eyJSZSI6WyJLTiJdLCJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJiUSI6
+WyJLTiJdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04iLCJSZS5FIjoiS04ifSwiYlEiOnsiY1giOlsiMSJd
+fSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwi
+Y1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNY
+IjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIy
+Il0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sIkE4Ijp7ImFMIjpbIjIiXSwiYlEiOlsiMiJd
+LCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoi
+MSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJYQyI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJd
+LCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0s
+IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19
+LCJXVSI6eyJaMCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0s
+IlhSIjp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwi
+YXoiOnsiWFMiOltdfSwidlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgiOltdfSwi
+bGMiOnsiRUgiOltdfSwiengiOnsiRUgiOltdfSwiclQiOnsiRUgiOltdfSwiRXEiOnsiWFMiOltdfSwi
+a1kiOnsiWFMiOltdfSwiTjUiOnsiRm8iOlsiMSIsIjIiXSwiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIs
+IjIiXSwiWWsuSyI6IjEiLCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1gu
+RSI6IjEifSwiTjYiOnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6eyJpYiI6
+W10sIk9kIjpbXX0sIktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6WyJpYiJd
+fSwidFEiOnsiT2QiOltdfSwidW4iOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7IkFuIjpb
+Ik9kIl19LCJFVCI6eyJBUyI6W119LCJiMCI6eyJYaiI6WyJAIl0sIkVUIjpbXSwiQVMiOltdfSwiRGci
+OnsibEQiOlsiQ1AiXSwiWGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIlNV
+IjpbIkNQIl0sIkFTIjpbXSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIktOIl0s
+InpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJdLCJBUyI6
+W10sImNYIjpbIktOIl19LCJ4aiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVU
+IjpbXSwiYlEiOlsiS04iXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04i
+fSwiZEUiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktO
+Il0sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIlpBIjp7ImxEIjpb
+IktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJd
+LCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJ3ZiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJL
+TiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiYlEiOlsiS04iXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6
+WyJLTiJdLCJsRC5FIjoiS04ifSwiUHEiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJd
+LCJFVCI6W10sImJRIjpbIktOIl0sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6
+IktOIn0sImVFIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6
+WyJLTiJdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJWNiI6eyJu
+NiI6W10sImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJd
+LCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJ1OSI6eyJYUyI6W119
+LCJoeiI6eyJYUyI6W119LCJpTSI6eyJYUyI6W119LCJHViI6eyJBbiI6WyIxIl19LCJxNCI6eyJjWCI6
+WyIxIl0sImNYLkUiOiIxIn0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4IjpbIjEiXX0sIkN3Ijp7
+IlhTIjpbXX0sIm0wIjp7IkpCIjpbXX0sIkppIjp7IkpCIjpbXX0sImI2Ijp7Ilh2IjpbIjEiXSwieHUi
+OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpb
+IjEiXX0sIkxVIjp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImls
+Ijp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4i
+OnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpb
+IjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJYdiI6eyJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwidXci
+OnsiWWsiOlsicVUiLCJAIl0sIlowIjpbInFVIiwiQCJdLCJZay5LIjoicVUiLCJZay5WIjoiQCJ9LCJp
+OCI6eyJhTCI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdLCJhTC5FIjoicVUiLCJjWC5FIjoi
+cVUifSwiQ1YiOnsiVWsiOlsiek08S04+IiwicVUiXSwiVWsuUyI6InpNPEtOPiJ9LCJVOCI6eyJ3SSI6
+WyJ6TTxLTj4iLCJxVSJdfSwiWmkiOnsiVWsiOlsicVUiLCJ6TTxLTj4iXX0sImJ5Ijp7IlVrIjpbImsi
+LCJxVSJdLCJVay5TIjoiayJ9LCJNeCI6eyJ3SSI6WyJxVSIsImsiXX0sInU1Ijp7IlVrIjpbInFVIiwi
+ek08S04+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPEtOPiJdfSwiR1kiOnsid0ki
+Olsiek08S04+IiwicVUiXX0sIkNQIjp7IkZLIjpbXX0sIkM2Ijp7IlhTIjpbXX0sIm4iOnsiWFMiOltd
+fSwidSI6eyJYUyI6W119LCJiSiI6eyJYUyI6W119LCJlWSI6eyJYUyI6W119LCJtcCI6eyJYUyI6W119
+LCJ1YiI6eyJYUyI6W119LCJkcyI6eyJYUyI6W119LCJsaiI6eyJYUyI6W119LCJVViI6eyJYUyI6W119
+LCJrNSI6eyJYUyI6W119LCJLWSI6eyJYUyI6W119LCJjIjp7IlhTIjpbXX0sIktOIjp7IkZLIjpbXX0s
+InpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJd
+LCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6eyJpRCI6W119LCJV
+ZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
+R2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119LCJJQiI6eyJ0biI6
+WyJGSyJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJs
+RC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sIlQ1Ijp7IkF6IjpbXX0sImg0Ijp7ImN2Ijpb
+XSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQwIjpbXX0sIk83Ijp7IkQwIjpbXX0sIndh
+Ijp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpNIjpbInVIIl0sImJR
+IjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119LCJCSCI6eyJHbSI6
+WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6
+WyJ1SCJdLCJHbS5FIjoidUgiLCJsRC5FIjoidUgifSwiU04iOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJUYiI6eyJjdiI6
+W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIldQIjp7ImN2
+IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwidzYiOnsi
+ZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJDUSI6eyJ1SCI6W10s
+IkQwIjpbXX0sInc0Ijp7InRuIjpbIkZLIl19LCJyaCI6eyJHbSI6WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6
+TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJHbS5FIjoidUgiLCJs
+RC5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl19LCJpNyI6eyJZ
+ayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIlN5
+Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoicVUi
+fSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sIlJP
+Ijp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgiOlsiMSJdfSwieEMiOnsiTU8iOlsiMSJd
+fSwiSlEiOnsia0YiOltdfSwidkQiOnsia0YiOltdfSwibTYiOnsia0YiOltdfSwiY3QiOnsia0YiOltd
+fSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwiZFciOnsidjYiOltdLCJEMCI6W119LCJt
+ayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJi
+USI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltdfSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6
+WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sIm5kIjp7ImQ1Ijpb
+XSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImJR
+IjpbInFVIl0sImNYIjpbInFVIl19LCJkNSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibjYiOnsi
+ek0iOlsiS04iXSwiYlEiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdfSwiWEEiOnsia0YiOltdfSwi
+T0YiOnsiZnYiOltdfSwicnUiOnsiZnYiOltdfSwiSVYiOnsiZnYiOltdfX0nKSkKSC5GRih2LnR5cGVV
+bml2ZXJzZSxKU09OLnBhcnNlKCd7ImJRIjoxLCJYQyI6MSwiTU8iOjEsImtUIjoyLCJtVyI6MSwiTFUi
+OjEsImlsIjoyLCJWaiI6MSwiblkiOjEsIlRDIjoxLCJjbyI6MX0nKSkKdmFyIHU9KGZ1bmN0aW9uIHJ0
+aWkoKXt2YXIgdD1ILk4wCnJldHVybnticTp0KCJHaCIpLG46dCgiQ3ciKSxjUjp0KCJuQiIpLGQ6dCgi
+QXoiKSxpOnQoIlFQIiksZ0Y6dCgiUEQ8R0QsQD4iKSxndzp0KCJiUTxAPiIpLGg6dCgiY3YiKSxiVTp0
+KCJYUyIpLEI6dCgiZWEiKSx1OnQoIkQwIiksYzg6dCgiVDUiKSxaOnQoIkVIIiksYzp0KCJiODxAPiIp
+LHI6dCgiTzciKSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVIPiIpLFg6dCgiY1g8cVU+Iiks
+Ujp0KCJjWDxAPiIpLGZBOnQoImpkPFNlPiIpLGdpOnQoImpkPGo4PiIpLGZoOnQoImpkPFpaPiIpLGs6
+dCgiamQ8a0Y+Iiksczp0KCJqZDxxVT4iKSxoaDp0KCJqZDx5RD4iKSxhSjp0KCJqZDx3Yj4iKSxtOnQo
+ImpkPEA+IiksdDp0KCJqZDxLTj4iKSxlSDp0KCJ2bSIpLGc6dCgiYzUiKSxhVTp0KCJYajxAPiIpLGFt
+OnQoIlR6PEA+IiksZW86dCgiTjU8R0QsQD4iKSx2OnQoIkU0IiksZHo6dCgiaEYiKSxmNDp0KCJ6TTxq
+OD4iKSxhOnQoInpNPHFVPiIpLGo6dCgiek08QD4iKSxMOnQoInpNPEtOPiIpLGFfOnQoInU4IiksUzp0
+KCJaMDxxVSxrPiIpLGY6dCgiWjA8cVUscVU+IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIp
+LGR2OnQoIkE4PHFVLHFVPiIpLGRvOnQoIkE4PHFVLEA+IiksVjp0KCJBaiIpLGREOnQoIkVUIiksYm06
+dCgiVjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxLOnQoImsiKSxwOnQoImV3IikscTp0
+KCJ0bjxGSz4iKSxmdjp0KCJ3TCIpLGF2OnQoIkpjIiksZXc6dCgibmQiKSxDOnQoInh1PHFVPiIpLGw6
+dCgiR3oiKSxOOnQoInFVIiksZEc6dCgicVUocVUpIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQo
+InlZIiksdzp0KCJBUyIpLGdjOnQoIm42IiksYWs6dCgia2QiKSxXOnQoIkdqPHFVLHFVPiIpLEQ6dCgi
+aUQiKSxjYzp0KCJVNTxxVT4iKSxnNDp0KCJLNSIpLGNpOnQoInY2IiksZzI6dCgiQ20iKSxFOnQoIlpm
+PE83PiIpLGg5OnQoIkNRIiksYWM6dCgiZTciKSxROnQoImV1PEFqPiIpLFQ6dCgid3o8Y3Y+IikseDp0
+KCJGZTxALEA+IiksWTp0KCJ2czxPNz4iKSxfOnQoInZzPEA+IiksZko6dCgidnM8S04+IiksTzp0KCJK
+USIpLEo6dCgiYm4iKSxjSjp0KCJhMiIpLGFsOnQoImEyKGspIiksYkI6dCgiYTIocVUpIiksYmY6dCgi
+YTIoQCkiKSx6OnQoIkAiKSxmTzp0KCJAKCkiKSxVOnQoIkAoZWEpIikseTp0KCJAKGspIiksZXA6dCgi
+QChrLGspIiksRjp0KCJAKGssR3opIiksY2g6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiODp0
+KCJAKEAsQCkiKSxlZzp0KCJLTiIpLEg6dCgifiIpLE06dCgifigpIiksYW46dCgifihldykiKSxlQTp0
+KCJ+KHFVLHFVKSIpLGNBOnQoIn4ocVUsQCkiKX19KSgpOyhmdW5jdGlvbiBjb25zdGFudHMoKXt2YXIg
+dD1odW5rSGVscGVycy5tYWtlQ29uc3RMaXN0CkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5CWj1XLlZiLnBy
+b3RvdHlwZQpDLkR0PVcuTzcucHJvdG90eXBlCkMuT2s9Si52Qi5wcm90b3R5cGUKQy5ObT1KLmpkLnBy
+b3RvdHlwZQpDLmpuPUoudXIucHJvdG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnBy
+b3RvdHlwZQpDLkRHPUouYzUucHJvdG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnBy
+b3RvdHlwZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnBy
+b3RvdHlwZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkK
+Qy5PND1mdW5jdGlvbiBnZXRUYWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBl
+LnRvU3RyaW5nLmNhbGwobyk7CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0K
+Qy5ZcT1mdW5jdGlvbigpIHsKICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUu
+dG9TdHJpbmc7CiAgZnVuY3Rpb24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlv
+bi5jYWxsKG8pOwogICAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1
+bmN0aW9uIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxl
+bWVudCQvLnRlc3QodGFnKSkgewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChv
+YmplY3QpOwogICAgICBpZiAobmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAg
+ICAgIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFn
+R2VuZXJpY0Jyb3dzZXIob2JqZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9i
+amVjdCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVy
+biBnZXRVbmtub3duVGFnKG9iamVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFn
+KHRhZykgewogICAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwog
+ICAgaWYgKHR5cGVvZiB3aW5kb3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2
+YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0g
+ImZ1bmN0aW9uIikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwog
+IH0KICBmdW5jdGlvbiBkaXNjcmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jy
+b3dzZXIgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6
+IGdldFRhZywKICAgIGdldFVua25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmlj
+QnJvd3NlciA6IGdldFVua25vd25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRh
+ZywKICAgIGRpc2NyaW1pbmF0b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRh
+Z0ZhbGxiYWNrKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmln
+YXRvciAhPSAib2JqZWN0IikgcmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJB
+Z2VudDsKICAgIGlmICh1YS5pbmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29r
+czsKICAgIGlmICh1YS5pbmRleE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZp
+cm0ocCkgewogICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1tw
+XSAmJiB3aW5kb3dbcF0ubmFtZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ci
+KSAmJiBjb25maXJtKCJIVE1MRWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5n
+ZXRUYWcgPSBnZXRUYWdGYWxsYmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAo
+dHlwZW9mIGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9v
+a3M7CiAgaG9va3MuZ2V0VGFnID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRh
+Zyk7Cn0KQy5mUT1mdW5jdGlvbihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAg
+dmFyIHByb3RvdHlwZUZvclRhZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRU
+YWdGaXhlZChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1l
+bnQiKSB7CiAgICAgIGlmICghIW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICBy
+ZXR1cm4gIiFIVE1MRG9jdW1lbnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24g
+cHJvdG90eXBlRm9yVGFnRml4ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVy
+biBudWxsOwogICAgcmV0dXJuIHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcg
+PSBnZXRUYWdGaXhlZDsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhl
+ZDsKfQpDLmRrPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0
+b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5p
+bmRleE9mKCJGaXJlZm94IikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3Mu
+Z2V0VGFnOwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIs
+CiAgICAiRGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2Vv
+bG9jYXRpb24iLAogICAgIkxvY2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2
+ZW50IjogIk1lc3NhZ2VFdmVudCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVu
+Y3Rpb24gZ2V0VGFnRmlyZWZveChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJu
+IHF1aWNrTWFwW3RhZ10gfHwgdGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9
+CkMueGk9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9
+PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4
+T2YoIlRyaWRlbnQvIikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0
+VGFnOwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAg
+ICAiRGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxl
+bWVudCIsCiAgICAiSFRNTERURWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVs
+ZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAg
+ZnVuY3Rpb24gZ2V0VGFnSUUobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdU
+YWcgPSBxdWlja01hcFt0YWddOwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0
+YWcgPT0gIk9iamVjdCIpIHsKICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9m
+IHdpbmRvdy5EYXRhVmlldykpIHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsK
+ICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3Ig
+PSB3aW5kb3dbdGFnXTsKICAgIGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAg
+IHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lF
+OwogIGhvb2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rp
+b24oaG9va3MpIHsgcmV0dXJuIGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgp
+CkMueE09bmV3IFAudTUoKQpDLlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMuQTM9bmV3IFAu
+TXgobnVsbCkKQy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5W
+TSh0KFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xh
+c3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0Iiwi
+Kjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxs
+Y2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIs
+IkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQi
+LCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJF
+QTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFV
+RElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0
+ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9y
+IiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRP
+Tjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFi
+aW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5W
+QVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpj
+aGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFs
+aWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwi
+Q09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01N
+QU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6
+OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwi
+REVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJ
+RUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJG
+T1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0
+aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6
+bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1Ojph
+bGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6
+d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIi
+LCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0
+aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklN
+Rzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2Vt
+YXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vz
+c2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5Q
+VVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6Omlu
+cHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjpt
+YXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBV
+VDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6
+c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6
+dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJL
+RVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZv
+ciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVl
+IiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJN
+RU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjpt
+aW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9M
+OjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BU
+R1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNl
+bGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxp
+Z24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6
+dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11
+bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNF
+TEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xv
+ciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmci
+LCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0
+aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFs
+aWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNo
+YXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0Iiwi
+VEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0
+aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6
+OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6
+Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJF
+QTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVB
+Ojp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09U
+Ojp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJU
+SDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWln
+aHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6
+OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFE
+Ojp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYi
+LCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIs
+IlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIs
+IlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11
+dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCww
+LDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCww
+LDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQi
+LCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJB
+TUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwi
+TUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMueEQ9SC5W
+TSh0KFtdKSx1LnMpCkMuZG49SC5WTSh0KFtdKSx1Lm0pCkMudG89SC5WTSh0KFswLDAsMzI3MjIsMTIy
+ODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAy
+Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2
+Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4
+Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4
+Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJy
+ZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpo
+cmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwi
+REVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRl
+IiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxI
+Lk4wKCJMUDxxVSx6TTxqOD4+IikpCkMuV089bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVLHFV
+PiIpKQpDLmhVPUguVk0odChbXSksSC5OMCgiamQ8R0Q+IikpCkMuRHg9bmV3IEguTFAoMCx7fSxDLmhV
+LEguTjAoIkxQPEdELEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGly
+ZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1u
+ZXcgSC53digiY2FsbCIpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0Zp
+ZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwKJC54Nz1u
+dWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwKJC5tZz1u
+dWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51bGwK
+JC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rp
+b24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIsInciLGZ1
+bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJZMiIsIlVOIixm
+dW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfanMiKX0pCnQoJCwiVTIiLCJTbiIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9
+fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51
+bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwiUjEiLCJO
+OSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnQoJCwiZk4iLCJpSSIsZnVuY3Rp
+b24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMk
+Jwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3Nh
+Z2V9fSgpKX0pCnQoJCwicWkiLCJLZiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkp
+fSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1
+bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhw
+ciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwia3EiLCJyTiIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4g
+SC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9
+fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkK
+dCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDAp
+LiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiV2MiLCJ1dCIsZnVu
+Y3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBQLldJ
+KCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7cmV0dXJuIEguRFEoSC5YRihILlZNKFstMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwt
+Miw2MiwtMiw2MiwtMiw2Myw1Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwt
+MiwtMiwtMiwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIw
+LDIxLDIyLDIzLDI0LDI1LC0yLC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0
+LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0y
+LC0yLC0yXSx1LnQpKSl9KQp0KCQsIk01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9j
+ZXNzIT0idW5kZWZpbmVkIiYmT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0i
+W29iamVjdCBwcm9jZXNzXSImJnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1mIiwiejQi
+LGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQoJCwiSkci
+LCJ2WiIsZnVuY3Rpb24oKXtyZXR1cm4gUC51eCgpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlvbigpe3Jl
+dHVybiBQLnRNKFsiQSIsIkFCQlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwi
+QVNJREUiLCJBVURJTyIsIkIiLCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRU
+T04iLCJDQU5WQVMiLCJDQVBUSU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9V
+UCIsIkNPTU1BTkQiLCJEQVRBIiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJE
+SVIiLCJESVYiLCJETCIsIkRUIiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJG
+T05UIiwiRk9PVEVSIiwiRk9STSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIs
+IkhHUk9VUCIsIkhSIiwiSSIsIklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwi
+LCJMRUdFTkQiLCJMSSIsIk1BUCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wi
+LCJPUFRHUk9VUCIsIk9QVElPTiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwi
+U0FNUCIsIlNFQ1RJT04iLCJTRUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJT
+VFJPTkciLCJTVUIiLCJTVU1NQVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEi
+LCJURk9PVCIsIlRIIiwiVEhFQUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFS
+IiwiVklERU8iLCJXQlIiXSx1Lk4pfSkKdCgkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51
+KCJeXFxTKyQiKX0pCnQoJCwid08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gdS52LmIoUC5ORChzZWxm
+KSl9KQp0KCQsImt0IiwiUjgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0T2JqZWN0
+Iil9KQp0KCQsImZLIiwia0kiLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uIERhcnRPYmplY3QoYSl7
+dGhpcy5vPWF9fSkKdCgkLCJxdCIsInpCIixmdW5jdGlvbigpe3JldHVybiBuZXcgVC5tUSgpfSkKdCgk
+LCJPbCIsIlVFIixmdW5jdGlvbigpe3JldHVybiBQLmhLKEMub2wuZ21XKFcueDMoKSkuaHJlZikuZ2hZ
+KCkucSgwLCJhdXRoVG9rZW4iKX0pCnQoJCwiaFQiLCJ5UCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigp
+LnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LWxpc3QgLnBhbmVsLWNvbnRlbnQiKX0pCnQoJCwiVzYiLCJoTCIs
+ZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LXBhbmVsIC5wYW5lbC1j
+b250ZW50Iil9KQp0KCQsIlRSIiwiRFciLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVj
+dG9yKCJmb290ZXIiKX0pCnQoJCwiRVkiLCJmaSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5
+U2VsZWN0b3IoImhlYWRlciIpfSkKdCgkLCJhdiIsIkQ5IixmdW5jdGlvbigpe3JldHVybiBXLlpyKCku
+cXVlcnlTZWxlY3RvcigiI3VuaXQtbmFtZSIpfSkKdCgkLCJmZSIsIktHIixmdW5jdGlvbigpe3JldHVy
+biBuZXcgTC5YQSgpfSkKdCgkLCJtTSIsIm5VIixmdW5jdGlvbigpe3JldHVybiBuZXcgTS5sSSgkLkhr
+KCkpfSkKdCgkLCJ5ciIsImJEIixmdW5jdGlvbigpe3JldHVybiBuZXcgRS5PRihQLm51KCIvIiksUC5u
+dSgiW14vXSQiKSxQLm51KCJeLyIpKX0pCnQoJCwiTWsiLCJLayIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3
+IEwuSVYoUC5udSgiWy9cXFxcXSIpLFAubnUoIlteL1xcXFxdJCIpLFAubnUoIl4oXFxcXFxcXFxbXlxc
+XFxdK1xcXFxbXlxcXFwvXSt8W2EtekEtWl06Wy9cXFxcXSkiKSxQLm51KCJeWy9cXFxcXSg/IVsvXFxc
+XF0pIikpfSkKdCgkLCJhayIsIkViIixmdW5jdGlvbigpe3JldHVybiBuZXcgRi5ydShQLm51KCIvIiks
+UC5udSgiKF5bYS16QS1aXVstKy5hLXpBLVpcXGRdKjovL3xbXi9dKSQiKSxQLm51KCJbYS16QS1aXVst
+Ky5hLXpBLVpcXGRdKjovL1teL10qIiksUC5udSgiXi8iKSl9KQp0KCQsImxzIiwiSGsiLGZ1bmN0aW9u
+KCl7cmV0dXJuIE8uUmgoKX0pfSkoKTsoZnVuY3Rpb24gbmF0aXZlU3VwcG9ydCgpeyFmdW5jdGlvbigp
+e3ZhciB0PWZ1bmN0aW9uKGEpe3ZhciBuPXt9Cm5bYV09MQpyZXR1cm4gT2JqZWN0LmtleXMoaHVua0hl
+bHBlcnMuY29udmVydFRvRmFzdE9iamVjdChuKSlbMF19CnYuZ2V0SXNvbGF0ZVRhZz1mdW5jdGlvbihh
+KXtyZXR1cm4gdCgiX19fZGFydF8iK2Erdi5pc29sYXRlVGFnKX0KdmFyIHM9Il9fX2RhcnRfaXNvbGF0
+ZV90YWdzXyIKdmFyIHI9T2JqZWN0W3NdfHwoT2JqZWN0W3NdPU9iamVjdC5jcmVhdGUobnVsbCkpCnZh
+ciBxPSJfWnhZeFgiCmZvcih2YXIgcD0wOztwKyspe3ZhciBvPXQocSsiXyIrcCsiXyIpCmlmKCEobyBp
+biByKSl7cltvXT0xCnYuaXNvbGF0ZVRhZz1vCmJyZWFrfX12LmRpc3BhdGNoUHJvcGVydHlOYW1lPXYu
+Z2V0SXNvbGF0ZVRhZygiZGlzcGF0Y2hfcmVjb3JkIil9KCkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVJ
+bnRlcmNlcHRvcnNCeVRhZyh7RE9NRXJyb3I6Si52QixET01JbXBsZW1lbnRhdGlvbjpKLnZCLE1lZGlh
+RXJyb3I6Si52QixOYXZpZ2F0b3I6Si52QixOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6Si52QixO
+YXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLnZCLE92ZXJjb25zdHJhaW5lZEVycm9yOkoudkIsUG9zaXRp
+b25FcnJvcjpKLnZCLFJhbmdlOkoudkIsU1FMRXJyb3I6Si52QixEYXRhVmlldzpILkVULEFycmF5QnVm
+ZmVyVmlldzpILkVULEZsb2F0MzJBcnJheTpILkRnLEZsb2F0NjRBcnJheTpILkRnLEludDE2QXJyYXk6
+SC54aixJbnQzMkFycmF5OkguZEUsSW50OEFycmF5OkguWkEsVWludDE2QXJyYXk6SC53ZixVaW50MzJB
+cnJheTpILlBxLFVpbnQ4Q2xhbXBlZEFycmF5OkguZUUsQ2FudmFzUGl4ZWxBcnJheTpILmVFLFVpbnQ4
+QXJyYXk6SC5WNixIVE1MQXVkaW9FbGVtZW50OlcucUUsSFRNTEJSRWxlbWVudDpXLnFFLEhUTUxCdXR0
+b25FbGVtZW50OlcucUUsSFRNTENhbnZhc0VsZW1lbnQ6Vy5xRSxIVE1MQ29udGVudEVsZW1lbnQ6Vy5x
+RSxIVE1MRExpc3RFbGVtZW50OlcucUUsSFRNTERhdGFFbGVtZW50OlcucUUsSFRNTERhdGFMaXN0RWxl
+bWVudDpXLnFFLEhUTUxEZXRhaWxzRWxlbWVudDpXLnFFLEhUTUxEaWFsb2dFbGVtZW50OlcucUUsSFRN
+TERpdkVsZW1lbnQ6Vy5xRSxIVE1MRW1iZWRFbGVtZW50OlcucUUsSFRNTEZpZWxkU2V0RWxlbWVudDpX
+LnFFLEhUTUxIUkVsZW1lbnQ6Vy5xRSxIVE1MSGVhZEVsZW1lbnQ6Vy5xRSxIVE1MSGVhZGluZ0VsZW1l
+bnQ6Vy5xRSxIVE1MSHRtbEVsZW1lbnQ6Vy5xRSxIVE1MSUZyYW1lRWxlbWVudDpXLnFFLEhUTUxJbWFn
+ZUVsZW1lbnQ6Vy5xRSxIVE1MSW5wdXRFbGVtZW50OlcucUUsSFRNTExJRWxlbWVudDpXLnFFLEhUTUxM
+YWJlbEVsZW1lbnQ6Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5rRWxlbWVudDpXLnFF
+LEhUTUxNYXBFbGVtZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxNZW51RWxlbWVudDpX
+LnFFLEhUTUxNZXRhRWxlbWVudDpXLnFFLEhUTUxNZXRlckVsZW1lbnQ6Vy5xRSxIVE1MTW9kRWxlbWVu
+dDpXLnFFLEhUTUxPTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MT2JqZWN0RWxlbWVudDpXLnFFLEhUTUxPcHRH
+cm91cEVsZW1lbnQ6Vy5xRSxIVE1MT3B0aW9uRWxlbWVudDpXLnFFLEhUTUxPdXRwdXRFbGVtZW50Olcu
+cUUsSFRNTFBhcmFtRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVudDpXLnFFLEhUTUxQcmVFbGVt
+ZW50OlcucUUsSFRNTFByb2dyZXNzRWxlbWVudDpXLnFFLEhUTUxRdW90ZUVsZW1lbnQ6Vy5xRSxIVE1M
+U2NyaXB0RWxlbWVudDpXLnFFLEhUTUxTaGFkb3dFbGVtZW50OlcucUUsSFRNTFNsb3RFbGVtZW50Olcu
+cUUsSFRNTFNvdXJjZUVsZW1lbnQ6Vy5xRSxIVE1MU3BhbkVsZW1lbnQ6Vy5xRSxIVE1MU3R5bGVFbGVt
+ZW50OlcucUUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDZWxsRWxlbWVudDpX
+LnFFLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50
+OlcucUUsSFRNTFRhYmxlQ29sRWxlbWVudDpXLnFFLEhUTUxUZXh0QXJlYUVsZW1lbnQ6Vy5xRSxIVE1M
+VGltZUVsZW1lbnQ6Vy5xRSxIVE1MVGl0bGVFbGVtZW50OlcucUUsSFRNTFRyYWNrRWxlbWVudDpXLnFF
+LEhUTUxVTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MVW5rbm93bkVsZW1lbnQ6Vy5xRSxIVE1MVmlkZW9FbGVt
+ZW50OlcucUUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6Vy5xRSxIVE1MRm9udEVsZW1lbnQ6Vy5xRSxIVE1M
+RnJhbWVFbGVtZW50OlcucUUsSFRNTEZyYW1lU2V0RWxlbWVudDpXLnFFLEhUTUxNYXJxdWVlRWxlbWVu
+dDpXLnFFLEhUTUxFbGVtZW50OlcucUUsSFRNTEFuY2hvckVsZW1lbnQ6Vy5HaCxIVE1MQXJlYUVsZW1l
+bnQ6Vy5mWSxIVE1MQmFzZUVsZW1lbnQ6Vy5uQixCbG9iOlcuQXosSFRNTEJvZHlFbGVtZW50OlcuUVAs
+Q0RBVEFTZWN0aW9uOlcubngsQ2hhcmFjdGVyRGF0YTpXLm54LENvbW1lbnQ6Vy5ueCxQcm9jZXNzaW5n
+SW5zdHJ1Y3Rpb246Vy5ueCxUZXh0OlcubngsQ1NTU3R5bGVEZWNsYXJhdGlvbjpXLm9KLE1TU3R5bGVD
+U1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixYTUxEb2N1bWVudDpXLlFGLERvY3Vt
+ZW50OlcuUUYsRE9NRXhjZXB0aW9uOlcuTmgsRE9NUmVjdFJlYWRPbmx5OlcuSUIsRE9NVG9rZW5MaXN0
+OlcubjcsRWxlbWVudDpXLmN2LEFib3J0UGF5bWVudEV2ZW50OlcuZWEsQW5pbWF0aW9uRXZlbnQ6Vy5l
+YSxBbmltYXRpb25QbGF5YmFja0V2ZW50OlcuZWEsQXBwbGljYXRpb25DYWNoZUVycm9yRXZlbnQ6Vy5l
+YSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRXZlbnQ6Vy5lYSxC
+YWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hlZEV2ZW50OlcuZWEsQmVm
+b3JlSW5zdGFsbFByb21wdEV2ZW50OlcuZWEsQmVmb3JlVW5sb2FkRXZlbnQ6Vy5lYSxCbG9iRXZlbnQ6
+Vy5lYSxDYW5NYWtlUGF5bWVudEV2ZW50OlcuZWEsQ2xpcGJvYXJkRXZlbnQ6Vy5lYSxDbG9zZUV2ZW50
+OlcuZWEsQ3VzdG9tRXZlbnQ6Vy5lYSxEZXZpY2VNb3Rpb25FdmVudDpXLmVhLERldmljZU9yaWVudGF0
+aW9uRXZlbnQ6Vy5lYSxFcnJvckV2ZW50OlcuZWEsRXh0ZW5kYWJsZUV2ZW50OlcuZWEsRXh0ZW5kYWJs
+ZU1lc3NhZ2VFdmVudDpXLmVhLEZldGNoRXZlbnQ6Vy5lYSxGb250RmFjZVNldExvYWRFdmVudDpXLmVh
+LEZvcmVpZ25GZXRjaEV2ZW50OlcuZWEsR2FtZXBhZEV2ZW50OlcuZWEsSGFzaENoYW5nZUV2ZW50Olcu
+ZWEsSW5zdGFsbEV2ZW50OlcuZWEsTWVkaWFFbmNyeXB0ZWRFdmVudDpXLmVhLE1lZGlhS2V5TWVzc2Fn
+ZUV2ZW50OlcuZWEsTWVkaWFRdWVyeUxpc3RFdmVudDpXLmVhLE1lZGlhU3RyZWFtRXZlbnQ6Vy5lYSxN
+ZWRpYVN0cmVhbVRyYWNrRXZlbnQ6Vy5lYSxNZXNzYWdlRXZlbnQ6Vy5lYSxNSURJQ29ubmVjdGlvbkV2
+ZW50OlcuZWEsTUlESU1lc3NhZ2VFdmVudDpXLmVhLE11dGF0aW9uRXZlbnQ6Vy5lYSxOb3RpZmljYXRp
+b25FdmVudDpXLmVhLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdEV2ZW50Olcu
+ZWEsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDpXLmVhLFBvcFN0YXRlRXZlbnQ6Vy5lYSxQcmVzZW50
+YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6Vy5lYSxQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xv
+c2VFdmVudDpXLmVhLFByb21pc2VSZWplY3Rpb25FdmVudDpXLmVhLFB1c2hFdmVudDpXLmVhLFJUQ0Rh
+dGFDaGFubmVsRXZlbnQ6Vy5lYSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50OlcuZWEsUlRDUGVlckNvbm5l
+Y3Rpb25JY2VFdmVudDpXLmVhLFJUQ1RyYWNrRXZlbnQ6Vy5lYSxTZWN1cml0eVBvbGljeVZpb2xhdGlv
+bkV2ZW50OlcuZWEsU2Vuc29yRXJyb3JFdmVudDpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXJyb3I6Vy5l
+YSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OlcuZWEsU3BlZWNoU3ludGhlc2lzRXZlbnQ6Vy5lYSxTdG9y
+YWdlRXZlbnQ6Vy5lYSxTeW5jRXZlbnQ6Vy5lYSxUcmFja0V2ZW50OlcuZWEsVHJhbnNpdGlvbkV2ZW50
+OlcuZWEsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OlcuZWEsVlJEZXZpY2VFdmVudDpXLmVhLFZSRGlzcGxh
+eUV2ZW50OlcuZWEsVlJTZXNzaW9uRXZlbnQ6Vy5lYSxNb2pvSW50ZXJmYWNlUmVxdWVzdEV2ZW50Olcu
+ZWEsVVNCQ29ubmVjdGlvbkV2ZW50OlcuZWEsSURCVmVyc2lvbkNoYW5nZUV2ZW50OlcuZWEsQXVkaW9Q
+cm9jZXNzaW5nRXZlbnQ6Vy5lYSxPZmZsaW5lQXVkaW9Db21wbGV0aW9uRXZlbnQ6Vy5lYSxXZWJHTENv
+bnRleHRFdmVudDpXLmVhLEV2ZW50OlcuZWEsSW5wdXRFdmVudDpXLmVhLEV2ZW50VGFyZ2V0OlcuRDAs
+RmlsZTpXLlQ1LEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1MRG9jdW1lbnQ6Vy5W
+YixYTUxIdHRwUmVxdWVzdDpXLk83LFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6Vy53YSxJbWFnZURh
+dGE6Vy5TZyxMb2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2ludGVy
+RXZlbnQ6Vy5BaixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6
+Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0
+OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50OlcuZXcsUmVzb3VyY2VQ
+cm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFibGVFbGVtZW50Olcu
+VGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OlcuV1AsSFRN
+TFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1c0V2ZW50OlcudzYs
+S2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53NixVSUV2ZW50Olcu
+dzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5D
+bSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNt
+LFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53NCxET01SZWN0Olcu
+dzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5UmFuZ2U6UC5oRixT
+VkdTY3JpcHRFbGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlRWxlbWVudDpQLmQ1
+LFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6UC5k
+NSxTVkdBbmltYXRpb25FbGVtZW50OlAuZDUsU1ZHQ2lyY2xlRWxlbWVudDpQLmQ1LFNWR0NsaXBQYXRo
+RWxlbWVudDpQLmQ1LFNWR0RlZnNFbGVtZW50OlAuZDUsU1ZHRGVzY0VsZW1lbnQ6UC5kNSxTVkdEaXNj
+YXJkRWxlbWVudDpQLmQ1LFNWR0VsbGlwc2VFbGVtZW50OlAuZDUsU1ZHRkVCbGVuZEVsZW1lbnQ6UC5k
+NSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50
+OlAuZDUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuZDUsU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6
+UC5kNSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRURpc3BsYWNlbWVudE1hcEVs
+ZW1lbnQ6UC5kNSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRUZsb29kRWxlbWVudDpQ
+LmQ1LFNWR0ZFRnVuY0FFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQkVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNH
+RWxlbWVudDpQLmQ1LFNWR0ZFRnVuY1JFbGVtZW50OlAuZDUsU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50
+OlAuZDUsU1ZHRkVJbWFnZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlRWxlbWVudDpQLmQ1LFNWR0ZFTWVy
+Z2VOb2RlRWxlbWVudDpQLmQ1LFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5kNSxTVkdGRU9mZnNldEVs
+ZW1lbnQ6UC5kNSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5n
+RWxlbWVudDpQLmQ1LFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFVGlsZUVsZW1lbnQ6UC5k
+NSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuZDUsU1ZHRmlsdGVyRWxlbWVudDpQLmQ1LFNWR0ZvcmVp
+Z25PYmplY3RFbGVtZW50OlAuZDUsU1ZHR0VsZW1lbnQ6UC5kNSxTVkdHZW9tZXRyeUVsZW1lbnQ6UC5k
+NSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5kNSxTVkdJbWFnZUVsZW1lbnQ6UC5kNSxTVkdMaW5lRWxlbWVu
+dDpQLmQ1LFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR01hcmtlckVsZW1lbnQ6UC5kNSxT
+VkdNYXNrRWxlbWVudDpQLmQ1LFNWR01ldGFkYXRhRWxlbWVudDpQLmQ1LFNWR1BhdGhFbGVtZW50OlAu
+ZDUsU1ZHUGF0dGVybkVsZW1lbnQ6UC5kNSxTVkdQb2x5Z29uRWxlbWVudDpQLmQ1LFNWR1BvbHlsaW5l
+RWxlbWVudDpQLmQ1LFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR1JlY3RFbGVtZW50OlAu
+ZDUsU1ZHU2V0RWxlbWVudDpQLmQ1LFNWR1N0b3BFbGVtZW50OlAuZDUsU1ZHU3R5bGVFbGVtZW50OlAu
+ZDUsU1ZHU1ZHRWxlbWVudDpQLmQ1LFNWR1N3aXRjaEVsZW1lbnQ6UC5kNSxTVkdTeW1ib2xFbGVtZW50
+OlAuZDUsU1ZHVFNwYW5FbGVtZW50OlAuZDUsU1ZHVGV4dENvbnRlbnRFbGVtZW50OlAuZDUsU1ZHVGV4
+dEVsZW1lbnQ6UC5kNSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5kNSxTVkdUZXh0UG9zaXRpb25pbmdFbGVt
+ZW50OlAuZDUsU1ZHVGl0bGVFbGVtZW50OlAuZDUsU1ZHVXNlRWxlbWVudDpQLmQ1LFNWR1ZpZXdFbGVt
+ZW50OlAuZDUsU1ZHR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlv
+bkVsZW1lbnQ6UC5kNSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuZDUsU1ZHTVBhdGhFbGVtZW50OlAu
+ZDUsU1ZHRWxlbWVudDpQLmQ1fSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFmVGFncyh7RE9NRXJy
+b3I6dHJ1ZSxET01JbXBsZW1lbnRhdGlvbjp0cnVlLE1lZGlhRXJyb3I6dHJ1ZSxOYXZpZ2F0b3I6dHJ1
+ZSxOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6dHJ1ZSxOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjp0
+cnVlLE92ZXJjb25zdHJhaW5lZEVycm9yOnRydWUsUG9zaXRpb25FcnJvcjp0cnVlLFJhbmdlOnRydWUs
+U1FMRXJyb3I6dHJ1ZSxEYXRhVmlldzp0cnVlLEFycmF5QnVmZmVyVmlldzpmYWxzZSxGbG9hdDMyQXJy
+YXk6dHJ1ZSxGbG9hdDY0QXJyYXk6dHJ1ZSxJbnQxNkFycmF5OnRydWUsSW50MzJBcnJheTp0cnVlLElu
+dDhBcnJheTp0cnVlLFVpbnQxNkFycmF5OnRydWUsVWludDMyQXJyYXk6dHJ1ZSxVaW50OENsYW1wZWRB
+cnJheTp0cnVlLENhbnZhc1BpeGVsQXJyYXk6dHJ1ZSxVaW50OEFycmF5OmZhbHNlLEhUTUxBdWRpb0Vs
+ZW1lbnQ6dHJ1ZSxIVE1MQlJFbGVtZW50OnRydWUsSFRNTEJ1dHRvbkVsZW1lbnQ6dHJ1ZSxIVE1MQ2Fu
+dmFzRWxlbWVudDp0cnVlLEhUTUxDb250ZW50RWxlbWVudDp0cnVlLEhUTUxETGlzdEVsZW1lbnQ6dHJ1
+ZSxIVE1MRGF0YUVsZW1lbnQ6dHJ1ZSxIVE1MRGF0YUxpc3RFbGVtZW50OnRydWUsSFRNTERldGFpbHNF
+bGVtZW50OnRydWUsSFRNTERpYWxvZ0VsZW1lbnQ6dHJ1ZSxIVE1MRGl2RWxlbWVudDp0cnVlLEhUTUxF
+bWJlZEVsZW1lbnQ6dHJ1ZSxIVE1MRmllbGRTZXRFbGVtZW50OnRydWUsSFRNTEhSRWxlbWVudDp0cnVl
+LEhUTUxIZWFkRWxlbWVudDp0cnVlLEhUTUxIZWFkaW5nRWxlbWVudDp0cnVlLEhUTUxIdG1sRWxlbWVu
+dDp0cnVlLEhUTUxJRnJhbWVFbGVtZW50OnRydWUsSFRNTEltYWdlRWxlbWVudDp0cnVlLEhUTUxJbnB1
+dEVsZW1lbnQ6dHJ1ZSxIVE1MTElFbGVtZW50OnRydWUsSFRNTExhYmVsRWxlbWVudDp0cnVlLEhUTUxM
+ZWdlbmRFbGVtZW50OnRydWUsSFRNTExpbmtFbGVtZW50OnRydWUsSFRNTE1hcEVsZW1lbnQ6dHJ1ZSxI
+VE1MTWVkaWFFbGVtZW50OnRydWUsSFRNTE1lbnVFbGVtZW50OnRydWUsSFRNTE1ldGFFbGVtZW50OnRy
+dWUsSFRNTE1ldGVyRWxlbWVudDp0cnVlLEhUTUxNb2RFbGVtZW50OnRydWUsSFRNTE9MaXN0RWxlbWVu
+dDp0cnVlLEhUTUxPYmplY3RFbGVtZW50OnRydWUsSFRNTE9wdEdyb3VwRWxlbWVudDp0cnVlLEhUTUxP
+cHRpb25FbGVtZW50OnRydWUsSFRNTE91dHB1dEVsZW1lbnQ6dHJ1ZSxIVE1MUGFyYW1FbGVtZW50OnRy
+dWUsSFRNTFBpY3R1cmVFbGVtZW50OnRydWUsSFRNTFByZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJvZ3Jlc3NF
+bGVtZW50OnRydWUsSFRNTFF1b3RlRWxlbWVudDp0cnVlLEhUTUxTY3JpcHRFbGVtZW50OnRydWUsSFRN
+TFNoYWRvd0VsZW1lbnQ6dHJ1ZSxIVE1MU2xvdEVsZW1lbnQ6dHJ1ZSxIVE1MU291cmNlRWxlbWVudDp0
+cnVlLEhUTUxTcGFuRWxlbWVudDp0cnVlLEhUTUxTdHlsZUVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDYXB0
+aW9uRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlRGF0YUNlbGxF
+bGVtZW50OnRydWUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDb2xFbGVt
+ZW50OnRydWUsSFRNTFRleHRBcmVhRWxlbWVudDp0cnVlLEhUTUxUaW1lRWxlbWVudDp0cnVlLEhUTUxU
+aXRsZUVsZW1lbnQ6dHJ1ZSxIVE1MVHJhY2tFbGVtZW50OnRydWUsSFRNTFVMaXN0RWxlbWVudDp0cnVl
+LEhUTUxVbmtub3duRWxlbWVudDp0cnVlLEhUTUxWaWRlb0VsZW1lbnQ6dHJ1ZSxIVE1MRGlyZWN0b3J5
+RWxlbWVudDp0cnVlLEhUTUxGb250RWxlbWVudDp0cnVlLEhUTUxGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1M
+RnJhbWVTZXRFbGVtZW50OnRydWUsSFRNTE1hcnF1ZWVFbGVtZW50OnRydWUsSFRNTEVsZW1lbnQ6ZmFs
+c2UsSFRNTEFuY2hvckVsZW1lbnQ6dHJ1ZSxIVE1MQXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MQmFzZUVsZW1l
+bnQ6dHJ1ZSxCbG9iOmZhbHNlLEhUTUxCb2R5RWxlbWVudDp0cnVlLENEQVRBU2VjdGlvbjp0cnVlLENo
+YXJhY3RlckRhdGE6dHJ1ZSxDb21tZW50OnRydWUsUHJvY2Vzc2luZ0luc3RydWN0aW9uOnRydWUsVGV4
+dDp0cnVlLENTU1N0eWxlRGVjbGFyYXRpb246dHJ1ZSxNU1N0eWxlQ1NTUHJvcGVydGllczp0cnVlLENT
+UzJQcm9wZXJ0aWVzOnRydWUsWE1MRG9jdW1lbnQ6dHJ1ZSxEb2N1bWVudDpmYWxzZSxET01FeGNlcHRp
+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
+dmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZhbHNlLEZpbGU6dHJ1ZSxIVE1M
+Rm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3VtZW50OnRydWUsWE1MSHR0cFJlcXVl
+c3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNlLEltYWdlRGF0YTp0cnVlLExvY2F0
+aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVlLFBvaW50ZXJFdmVudDp0cnVlLFdo
+ZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hhZG93Um9vdDp0cnVlLERvY3VtZW50
+VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05vZGVMaXN0OnRydWUsSFRNTFBh
+cmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVzb3VyY2VQcm9ncmVzc0V2ZW50
+OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRydWUsSFRNTFRhYmxl
+Um93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRNTFRlbXBsYXRlRWxl
+bWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50OnRydWUsS2V5Ym9hcmRFdmVu
+dDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2ZW50OmZhbHNlLFdpbmRvdzp0
+cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2VydmljZVdv
+cmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxXb3JrZXJHbG9i
+YWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9NUmVjdDp0cnVlLE5hbWVkTm9k
+ZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJhbmdlOnRydWUsU1ZHU2NyaXB0RWxl
+bWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRl
+TW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OnRydWUsU1ZHQW5pbWF0
+aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdDbGlwUGF0aEVsZW1lbnQ6dHJ1
+ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUsU1ZHRGlzY2FyZEVsZW1lbnQ6
+dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVtZW50OnRydWUsU1ZHRkVDb2xv
+ck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDp0cnVlLFNWR0ZF
+Q29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVE
+aWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OnRydWUs
+U1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1
+bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZHRkVGdW5jR0VsZW1lbnQ6dHJ1
+ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDp0cnVlLFNWR0ZF
+SW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlTm9kZUVsZW1l
+bnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVPZmZzZXRFbGVtZW50OnRydWUs
+U1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6dHJ1
+ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVtZW50OnRydWUsU1ZHRkVUdXJi
+dWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxTVkdGb3JlaWduT2JqZWN0RWxl
+bWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVtZW50OnRydWUsU1ZHR3JhcGhp
+Y3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZHTGluZUVsZW1lbnQ6dHJ1ZSxTVkdM
+aW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50OnRydWUsU1ZHTWFza0VsZW1l
+bnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxlbWVudDp0cnVlLFNWR1BhdHRl
+cm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5bGluZUVsZW1lbnQ6dHJ1
+ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxlbWVudDp0cnVlLFNWR1NldEVs
+ZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxlRWxlbWVudDp0cnVlLFNWR1NWR0Vs
+ZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9sRWxlbWVudDp0cnVlLFNWR1RT
+cGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0cnVlLFNWR1RleHRFbGVtZW50OnRy
+dWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDp0cnVlLFNW
+R1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdWaWV3RWxlbWVudDp0cnVlLFNW
+R0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OnRy
+dWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRoRWxlbWVudDp0cnVlLFNWR0VsZW1l
+bnQ6ZmFsc2V9KQpILmIwLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUkcu
+JG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0aXZlU3VwZXJjbGFz
+c1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZl
+clZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5aRy4kbmF0
+aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVTdXBlcmNsYXNzVGFn
+PSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0T2JqZWN0KHcpCmNvbnZlcnRUb0Zh
+c3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVudD09PSJ1bmRlZmluZWQiKXth
+KG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVudFNjcmlwdCE9J3VuZGVmaW5lZCcp
+e2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciB0PWRvY3VtZW50LnNjcmlwdHMKZnVu
+Y3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcj0wO3I8dC5sZW5ndGg7KytyKXRbcl0ucmVtb3ZlRXZlbnRM
+aXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0KX1mb3IodmFyIHM9MDtzPHQubGVu
+Z3RoOysrcyl0W3NdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSl9KShmdW5jdGlv
+bihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBlb2YgZGFydE1haW5SdW5uZXI9PT0iZnVuY3Rpb24i
+KWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2UgTC5JcShbXSl9KX0pKCkKLy8jIHNvdXJjZU1hcHBp
+bmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
+''';
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_link.dart b/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/unit_link.dart
rename to pkg/nnbd_migration/lib/src/front_end/unit_link.dart
diff --git a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
new file mode 100644
index 0000000..d6653ab
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
@@ -0,0 +1,318 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show HtmlEscape, HtmlEscapeMode, LineSplitter;
+
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/file_details.dart';
+import 'package:path/path.dart' as path;
+
+/// Instrumentation display output for a library that was migrated to use
+/// non-nullable types.
+class UnitRenderer {
+  /// A converter which only escapes "&", "<", and ">". Safe for use in HTML
+  /// text, between HTML elements.
+  static const HtmlEscape _htmlEscape =
+      HtmlEscape(HtmlEscapeMode(escapeLtGt: true));
+
+  /// List of kinds of nullability fixes that should be displayed in the
+  /// "proposed edits" area, in the order in which they should be displayed.
+  @visibleForTesting
+  static const List<NullabilityFixKind> kindPriorityOrder = [
+    NullabilityFixKind.compoundAssignmentHasBadCombinedType,
+    NullabilityFixKind.compoundAssignmentHasNullableSource,
+    NullabilityFixKind.removeDeadCode,
+    NullabilityFixKind.conditionTrueInStrongMode,
+    NullabilityFixKind.conditionFalseInStrongMode,
+    NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode,
+    NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode,
+    NullabilityFixKind.otherCastExpression,
+    NullabilityFixKind.checkExpression,
+    NullabilityFixKind.addRequired,
+    NullabilityFixKind.makeTypeNullable,
+    NullabilityFixKind.downcastExpression,
+    NullabilityFixKind.addType,
+    NullabilityFixKind.replaceVar,
+    NullabilityFixKind.removeAs,
+    NullabilityFixKind.addLate,
+    NullabilityFixKind.addLateDueToTestSetup,
+    NullabilityFixKind.addLateDueToHint,
+    NullabilityFixKind.checkExpressionDueToHint,
+    NullabilityFixKind.makeTypeNullableDueToHint,
+    NullabilityFixKind.removeLanguageVersionComment
+  ];
+
+  /// Displays information for a compilation unit.
+  final UnitInfo unitInfo;
+
+  /// Information for a whole migration, so that libraries can reference each
+  /// other.
+  final MigrationInfo migrationInfo;
+
+  /// An object used to map the file paths of analyzed files to the file paths
+  /// of the HTML files used to view the content of those files.
+  final PathMapper pathMapper;
+
+  /// Creates an output object for the given library info.
+  UnitRenderer(this.unitInfo, this.migrationInfo, this.pathMapper);
+
+  /// Return the path context used to manipulate paths.
+  path.Context get pathContext => migrationInfo.pathContext;
+
+  /// Builds a JSON view of the instrumentation information in [unitInfo].
+  FileDetails render() {
+    return FileDetails(
+        regions: _computeRegionContent(unitInfo),
+        navigationContent: _computeNavigationContent(),
+        sourceCode: unitInfo.content,
+        edits: _computeEditList());
+  }
+
+  /// Returns the list of edits, as JSON.
+  Map<String, List<EditListItem>> _computeEditList() {
+    var editListsByKind = <NullabilityFixKind, List<EditListItem>>{};
+    for (var region in unitInfo.regions) {
+      var kind = region.kind;
+      if (kind != null && region.isCounted) {
+        (editListsByKind[kind] ??= []).add(EditListItem(
+            line: region.lineNumber,
+            explanation: region.explanation,
+            offset: region.offset));
+      }
+    }
+    // Order the lists and filter out empty categories.
+    var result = <String, List<EditListItem>>{};
+    for (var kind in kindPriorityOrder) {
+      var edits = editListsByKind[kind];
+      if (edits != null) {
+        result[_headerForKind(kind, edits.length)] = edits;
+      }
+    }
+    return result;
+  }
+
+  /// Returns the content of the file with navigation links and anchors added.
+  ///
+  /// The content of the file (not including added links and anchors) will be
+  /// HTML-escaped.
+  String _computeNavigationContent() {
+    var unitDir = pathContext.dirname(pathMapper.map(unitInfo.path));
+    var content = unitInfo.content;
+    var mapper = unitInfo.offsetMapper;
+    var openInsertions = <int, String>{};
+    var closeInsertions = <int, String>{};
+    //
+    // Compute insertions for navigation targets.
+    //
+    for (var region in unitInfo.targets) {
+      if (region.length > 0) {
+        var openOffset = mapper.map(region.offset);
+        var openInsertion = openInsertions[openOffset] ?? '';
+        openInsertion = '<span id="o${region.offset}">$openInsertion';
+        openInsertions[openOffset] = openInsertion;
+
+        var closeOffset = openOffset + region.length;
+        var closeInsertion = closeInsertions[closeOffset] ?? '';
+        closeInsertion = '$closeInsertion</span>';
+        closeInsertions[closeOffset] = closeInsertion;
+      }
+    }
+    //
+    // Compute insertions for navigation sources, but skip the sources that
+    // point at themselves.
+    //
+    for (var region in unitInfo.sources ?? <NavigationSource>[]) {
+      if (region.length > 0) {
+        var openOffset = mapper.map(region.offset);
+        var target = region.target;
+        if (target.filePath != unitInfo.path ||
+            region.offset != target.offset) {
+          var openInsertion = openInsertions[openOffset] ?? '';
+          var unitPath = pathContext.relative(pathMapper.map(target.filePath),
+              from: unitDir);
+          var targetUri = _uriForRelativePath(unitPath, target);
+          openInsertion =
+              '<a href="$targetUri" class="nav-link">$openInsertion';
+          openInsertions[openOffset] = openInsertion;
+
+          var closeOffset = openOffset + region.length;
+          var closeInsertion = closeInsertions[closeOffset] ?? '';
+          closeInsertion = '$closeInsertion</a>';
+          closeInsertions[closeOffset] = closeInsertion;
+        }
+      }
+    }
+    //
+    // Apply the insertions that have been computed.
+    //
+    var offsets = <int>[...openInsertions.keys, ...closeInsertions.keys];
+    offsets.sort();
+    var navContent2 = StringBuffer();
+    var previousOffset = 0;
+    for (var offset in offsets) {
+      navContent2.write(
+          _htmlEscape.convert(content.substring(previousOffset, offset)));
+      navContent2.write(closeInsertions[offset] ?? '');
+      navContent2.write(openInsertions[offset] ?? '');
+      previousOffset = offset;
+    }
+    if (previousOffset < content.length) {
+      navContent2.write(_htmlEscape.convert(content.substring(previousOffset)));
+    }
+    return navContent2.toString();
+  }
+
+  /// Returns the content of regions, based on the [unitInfo] for both
+  /// unmodified and modified regions.
+  ///
+  /// The content of the file (not including added links and anchors) will be
+  /// HTML-escaped.
+  String _computeRegionContent(UnitInfo unit) {
+    var content = unitInfo.content;
+    var regions = StringBuffer();
+    var lineNumber = 1;
+
+    void writeSplitLines(
+      String lines, {
+      String perLineOpeningTag = '',
+      String perLineClosingTag = '',
+    }) {
+      var lineIterator = LineSplitter.split(lines).iterator;
+      lineIterator.moveNext();
+
+      while (true) {
+        regions.write(perLineOpeningTag);
+        regions.write(_htmlEscape.convert(lineIterator.current));
+        regions.write(perLineClosingTag);
+        if (lineIterator.moveNext()) {
+          // If we're not on the last element, end this table row, and start a
+          // new table row.
+          lineNumber++;
+          regions.write('</td></tr>'
+              '<tr><td class="line-no">$lineNumber</td>'
+              '<td class="line-$lineNumber">');
+        } else {
+          break;
+        }
+      }
+
+      if (lines.endsWith('\n')) {
+        lineNumber++;
+        regions.write('</td></tr>'
+            '<tr><td class="line-no">$lineNumber</td>'
+            '<td class="line-$lineNumber">');
+      }
+    }
+
+    /// Returns the CSS class for a region with a given [RegionType].
+    String classForRegion(RegionType type) {
+      switch (type) {
+        case RegionType.add:
+          return 'added-region';
+        case RegionType.remove:
+          return 'removed-region';
+        case RegionType.informative:
+          return 'informative-region';
+      }
+      throw StateError('Unexpected RegionType $type');
+    }
+
+    var previousOffset = 0;
+    regions.write('<table data-path="${unit.path}"><tbody>');
+    regions.write('<tr><td class="line-no">$lineNumber</td><td>');
+    for (var region in unitInfo.regions) {
+      var offset = region.offset;
+      var length = region.length;
+      if (offset > previousOffset) {
+        // Display a region of unmodified content.
+        writeSplitLines(content.substring(previousOffset, offset));
+      }
+      previousOffset = offset + length;
+      var regionClass = classForRegion(region.regionType);
+      var regionSpanTag = '<span class="region $regionClass" '
+          'data-offset="$offset" data-line="$lineNumber">';
+      writeSplitLines(content.substring(offset, offset + length),
+          perLineOpeningTag: regionSpanTag, perLineClosingTag: '</span>');
+    }
+    if (previousOffset < content.length) {
+      // Last region of unmodified content.
+      writeSplitLines(content.substring(previousOffset));
+    }
+    regions.write('</td></tr></tbody></table>');
+    return regions.toString();
+  }
+
+  String _headerForKind(NullabilityFixKind kind, int count) {
+    var s = count == 1 ? '' : 's';
+    var es = count == 1 ? '' : 'es';
+    switch (kind) {
+      case NullabilityFixKind.addLate:
+        return '$count late keyword$s added';
+      case NullabilityFixKind.addLateDueToHint:
+        return '$count late hint$s converted to late keyword$s';
+      case NullabilityFixKind.addLateDueToTestSetup:
+        return '$count late keyword$s added, due to assignment in `setUp`';
+      case NullabilityFixKind.addRequired:
+        return '$count required keyword$s added';
+      case NullabilityFixKind.addType:
+        return '$count type$s added';
+      case NullabilityFixKind.downcastExpression:
+        return '$count downcast$s added';
+      case NullabilityFixKind.otherCastExpression:
+        return '$count cast$s (non-downcast) added';
+      case NullabilityFixKind.checkExpression:
+        return '$count null check$s added';
+      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 '
+            'combined type)';
+      case NullabilityFixKind.compoundAssignmentHasNullableSource:
+        return '$count compound assignment$s could not be migrated (nullable '
+            'source)';
+      case NullabilityFixKind.conditionTrueInStrongMode:
+        return '$count condition$s will be true in strong checking mode';
+        break;
+      case NullabilityFixKind.conditionFalseInStrongMode:
+        return '$count condition$s will be false in strong checking mode';
+        break;
+      case NullabilityFixKind.makeTypeNullable:
+        return '$count type$s made nullable';
+      case NullabilityFixKind.makeTypeNullableDueToHint:
+        return '$count nullability hint$s converted to ?$s';
+      case NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode:
+        return '$count null-aware access$es will be unnecessary in strong '
+            'checking mode';
+      case NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode:
+        return '$count null-aware assignment$s will be unnecessary in strong '
+            'checking mode';
+      case NullabilityFixKind.removeAs:
+        return '$count cast$s now unnecessary';
+      case NullabilityFixKind.removeDeadCode:
+        return '$count dead code removal$s';
+      case NullabilityFixKind.removeLanguageVersionComment:
+        return '$count language version comment$s removed';
+      case NullabilityFixKind.replaceVar:
+        return "$count 'var' declaration$s replaced";
+      case NullabilityFixKind.typeNotMadeNullable:
+        return '$count type$s not made nullable';
+      case NullabilityFixKind.typeNotMadeNullableDueToHint:
+        return '$count type$s not made nullable due to hint$s';
+    }
+    throw StateError('Null kind');
+  }
+
+  /// Returns the URL that will navigate to the given [target] in the file at
+  /// the given [relativePath].
+  String _uriForRelativePath(String relativePath, NavigationTarget target) {
+    var queryParams = {
+      'offset': target.offset,
+      if (target.line != null) 'line': target.line,
+    }.entries.map((entry) => '${entry.key}=${entry.value}').join('&');
+    return '$relativePath?$queryParams';
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart b/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
new file mode 100644
index 0000000..1bbfecf
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// Information about what should be populated into the "Edit Details" view of
+/// the migration preview tool.
+class EditDetails {
+  /// A list of edits that can be offered to the user related to this source
+  /// location (e.g. adding/removing hints).  `null` if this feature is
+  /// disabled.
+  final List<EditLink> edits;
+
+  /// A string explanation of the edit.
+  final String explanation;
+
+  /// The line number of the edit.
+  final int line;
+
+  /// The path of the file that was edited.
+  final String path;
+
+  /// A list of traces representing stacktrace-like views of why the change was
+  /// made, or the empty list if there are no traces for this change.
+  final List<Trace> traces;
+
+  EditDetails(
+      {this.edits,
+      @required this.explanation,
+      @required this.line,
+      @required this.path,
+      this.traces = const []});
+
+  EditDetails.fromJson(dynamic json)
+      : edits = _decodeEdits(json['edits']),
+        explanation = json['explanation'] as String,
+        line = json['line'] as int,
+        path = json['path'] as String,
+        traces = _decodeTraces(json['traces']);
+
+  Map<String, Object> toJson() => {
+        if (edits != null) 'edits': [for (var edit in edits) edit.toJson()],
+        'explanation': explanation,
+        'line': line,
+        'path': path,
+        if (traces != null)
+          'traces': [for (var trace in traces) trace.toJson()],
+      };
+
+  static List<EditLink> _decodeEdits(dynamic json) =>
+      json == null ? null : [for (var edit in json) EditLink.fromJson(edit)];
+
+  static List<Trace> _decodeTraces(dynamic json) =>
+      json == null ? null : [for (var trace in json) Trace.fromJson(trace)];
+}
+
+/// Information about a single link that should be included in the
+/// "Edit Details" view of the migration preview tool, where the purpose of the
+/// link is to allow the user to make a change to the source file (e.g. to add
+/// or remove a hint).
+class EditLink {
+  /// Description of the change to be performed.
+  final String description;
+
+  /// The href to link to.
+  final String href;
+
+  EditLink({@required this.description, @required this.href});
+
+  EditLink.fromJson(dynamic json)
+      : description = json['description'] as String,
+        href = json['href'] as String;
+
+  Map<String, Object> toJson() => {
+        'description': description,
+        'href': href,
+      };
+}
+
+/// Information about a single link that should be included in the
+/// "Edit Details" view of the migration preview tool, where the purpose of the
+/// link is to allow the user to navigate to a source file containing
+/// information about the rationale for a change.
+class TargetLink {
+  /// The href to link to.
+  final String href;
+
+  /// The line number of the link.
+  final int line;
+
+  /// Relative path to the source file (intended for display).
+  final String path;
+
+  TargetLink({@required this.href, @required this.line, @required this.path});
+
+  TargetLink.fromJson(dynamic json)
+      : href = json['href'] as String,
+        line = json['line'] as int,
+        path = json['path'] as String;
+
+  Map<String, Object> toJson() => {
+        'href': href,
+        'line': line,
+        'path': path,
+      };
+}
+
+/// A trace of why a nullability decision was made.
+class Trace {
+  /// Text description of the trace.
+  final String description;
+
+  /// List of trace entries.
+  final List<TraceEntry> entries;
+
+  Trace({@required this.description, @required this.entries});
+
+  Trace.fromJson(dynamic json)
+      : description = json['description'] as String,
+        entries = [
+          for (var entry in json['entries']) TraceEntry.fromJson(entry)
+        ];
+
+  Map<String, Object> toJson() => {
+        'description': description,
+        'entries': [for (var entry in entries) entry.toJson()]
+      };
+}
+
+/// Information about a single entry in a nullability trace.
+class TraceEntry {
+  /// Text description of the entry.
+  final String description;
+
+  /// The function associated with the entry.  We display this before the link
+  /// so that the trace has the familiar appearance of a stacktrace.
+  ///
+  /// Null if not known.
+  final String function;
+
+  /// Source code location associated with the entry, or `null` if no source
+  /// code location is known.
+  final TargetLink link;
+
+  TraceEntry({@required this.description, this.function, this.link});
+
+  TraceEntry.fromJson(dynamic json)
+      : description = json['description'] as String,
+        function = json['function'] as String,
+        link = _decodeLink(json['link']);
+
+  Map<String, Object> toJson() => {
+        'description': description,
+        if (function != null) 'function': function,
+        if (link != null) 'link': link.toJson()
+      };
+
+  static TargetLink _decodeLink(dynamic json) =>
+      json == null ? null : TargetLink.fromJson(json);
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/file_details.dart b/pkg/nnbd_migration/lib/src/front_end/web/file_details.dart
new file mode 100644
index 0000000..7b140cf
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/web/file_details.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// Information about an item that should show up in the "proposed edits" panel.
+class EditListItem {
+  /// Line number of this edit.
+  final int line;
+
+  /// Human-readable explanation of this edit.
+  final String explanation;
+
+  /// File offset of this edit
+  final int offset;
+
+  EditListItem(
+      {@required this.line, @required this.explanation, @required this.offset});
+
+  EditListItem.fromJson(dynamic json)
+      : line = json['line'] as int,
+        explanation = json['explanation'] as String,
+        offset = json['offset'] as int;
+
+  Map<String, Object> toJson() =>
+      {'line': line, 'explanation': explanation, 'offset': offset};
+}
+
+/// Information about how a single file should be migrated.
+class FileDetails {
+  /// HTML representation of the source file with spans added to represent
+  /// added, removed, and unchanged file regions.
+  ///
+  /// TODO(paulberry): this should be replaced by a more neutral data structure.
+  final String regions;
+
+  /// HTML representation of the source file with links added to allow
+  /// navigation through source files.
+  ///
+  /// TODO(paulberry): this should be replaced by a more neutral data structure.
+  final String navigationContent;
+
+  /// Textual representation of the source file, including both added and
+  /// removed text.
+  final String sourceCode;
+
+  /// Items that should show up in the "proposed edits" panel for the file.
+  ///
+  /// Map keys are headers, and values are the list of edits under each header.
+  /// Map order is important--entries appearing earlier in the map are
+  /// considered more likely to be of interest to the user.
+  final Map<String, List<EditListItem>> edits;
+
+  FileDetails(
+      {@required this.regions,
+      @required this.navigationContent,
+      @required this.sourceCode,
+      @required this.edits});
+
+  FileDetails.empty()
+      : regions = '',
+        navigationContent = '',
+        sourceCode = '',
+        edits = const {};
+
+  FileDetails.fromJson(dynamic json)
+      : regions = json['regions'] as String,
+        navigationContent = json['navigationContent'] as String,
+        sourceCode = json['sourceCode'] as String,
+        edits = {
+          for (var entry in (json['edits'] as Map<String, Object>).entries)
+            entry.key: [
+              for (var edit in entry.value) EditListItem.fromJson(edit)
+            ]
+        };
+
+  Map<String, Object> toJson() => {
+        'regions': regions,
+        'navigationContent': navigationContent,
+        'sourceCode': sourceCode,
+        'edits': {
+          for (var entry in edits.entries)
+            entry.key: [for (var edit in entry.value) edit.toJson()]
+        }
+      };
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/highlight_js.dart b/pkg/nnbd_migration/lib/src/front_end/web/highlight_js.dart
new file mode 100644
index 0000000..82e7daf
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/web/highlight_js.dart
@@ -0,0 +1,19 @@
+// 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:html';
+import 'dart:js';
+
+final HighlightJs hljs = HighlightJs._();
+
+/// A small wrapper around the JavaScript highlight.js APIs.
+class HighlightJs {
+  static JsObject get _hljs => context['hljs'] as JsObject;
+
+  HighlightJs._();
+
+  void highlightBlock(Element block) {
+    _hljs.callMethod('highlightBlock', [block]);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
new file mode 100644
index 0000000..dba292b
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -0,0 +1,786 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
+
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
+import 'package:nnbd_migration/src/front_end/web/file_details.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+import 'package:path/path.dart' as _p;
+
+import 'highlight_js.dart';
+
+// TODO(devoncarew): Fix the issue where we can't load source maps.
+
+// TODO(devoncarew): Include a favicon.
+
+void main() {
+  document.addEventListener('DOMContentLoaded', (event) {
+    var path = window.location.pathname;
+    var offset = getOffset(window.location.href);
+    var lineNumber = getLine(window.location.href);
+    loadNavigationTree();
+    if (path != '/' && path != rootPath) {
+      // TODO(srawlins): replaceState?
+      loadFile(path, offset, lineNumber, true, callback: () {
+        pushState(path, offset, lineNumber);
+      });
+    }
+
+    final applyMigrationButton = document.querySelector('.apply-migration');
+    applyMigrationButton.onClick.listen((event) {
+      if (window.confirm(
+          "This will apply the changes you've previewed to your working "
+          'directory. It is recommended you commit any changes you made before '
+          'doing this.')) {
+        doPost('/apply-migration').then((xhr) {
+          document.body.classes
+            ..remove('proposed')
+            ..add('applied');
+        }).catchError((e, st) {
+          handleError('Could not apply migration', e, st);
+        });
+      }
+    });
+
+    final rerunMigrationButton = document.querySelector('.rerun-migration');
+    rerunMigrationButton.onClick.listen((event) async {
+      try {
+        document.body.classes..add('rerunning');
+        await doPost('/rerun-migration');
+        window.location.reload();
+      } catch (e, st) {
+        handleError('Failed to rerun migration', e, st);
+      } finally {
+        document.body.classes.remove('rerunning');
+      }
+    });
+
+    final reportProblemButton = document.querySelector('.report-problem');
+    reportProblemButton.onClick.listen((_) {
+      window.open(getGitHubProblemUri().toString(), 'report-problem');
+    });
+
+    document.querySelector('.popup-pane .close').onClick.listen(
+        (_) => document.querySelector('.popup-pane').style.display = 'none');
+  });
+
+  window.addEventListener('popstate', (event) {
+    var path = window.location.pathname;
+    var offset = getOffset(window.location.href);
+    var lineNumber = getLine(window.location.href);
+    if (path.length > 1) {
+      loadFile(path, offset, lineNumber, false);
+    } else {
+      // Blank out the page, for the index screen.
+      writeCodeAndRegions(path, FileDetails.empty(), true);
+      updatePage('&nbsp;', null);
+    }
+  });
+}
+
+/// Returns the "authToken" query parameter value of the current location.
+// TODO(srawlins): This feels a little fragile, as the user can accidentally
+//  change/remove this text, and break their session. Normally auth tokens are
+//  stored in cookies, but there is no authentication step during which the
+//  server would attach such a token to cookies. We could do a little step where
+//  the first request to the server with the token is considered
+//  "authentication", and we subsequently store the token in cookies thereafter.
+final String authToken =
+    Uri.parse(window.location.href).queryParameters['authToken'];
+
+final Element editListElement =
+    document.querySelector('.edit-list .panel-content');
+
+final Element editPanel = document.querySelector('.edit-panel .panel-content');
+
+final Element footerPanel = document.querySelector('footer');
+
+final Element headerPanel = document.querySelector('header');
+
+final Element unitName = document.querySelector('#unit-name');
+
+String get rootPath => querySelector('.root').text.trim();
+
+String get sdkVersion => document.getElementById('sdk-version').text;
+
+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
+  // have are hacks. The `* 2` allows for events in which the list grows in
+  // height when resized, with additional text wrapping.
+  // [1] https://css-tricks.com/using-css-transitions-auto-dimensions/
+  childList.style.maxHeight = '${childList.offsetHeight * 2}px';
+  arrow.onClick.listen((MouseEvent event) {
+    if (!childList.classes.contains('collapsed')) {
+      childList.classes.add('collapsed');
+      arrow.classes.add('collapsed');
+    } else {
+      childList.classes.remove('collapsed');
+      arrow.classes.remove('collapsed');
+    }
+  });
+}
+
+void addClickHandlers(String selector, bool clearEditDetails) {
+  var parentElement = document.querySelector(selector);
+
+  // Add navigation handlers for navigation links in the source code.
+  List<Element> navLinks = parentElement.querySelectorAll('.nav-link');
+  navLinks.forEach((link) {
+    link.onClick.listen((event) {
+      var tableElement = document.querySelector('table[data-path]');
+      var parentPath = tableElement.dataset['path'];
+      handleNavLinkClick(event, clearEditDetails, relativeTo: parentPath);
+    });
+  });
+
+  List<Element> regions = parentElement.querySelectorAll('.region');
+  if (regions.isNotEmpty) {
+    var table = parentElement.querySelector('table[data-path]');
+    var path = table.dataset['path'];
+    regions.forEach((Element anchor) {
+      anchor.onClick.listen((event) {
+        var offset = int.parse(anchor.dataset['offset']);
+        var line = int.parse(anchor.dataset['line']);
+        loadAndPopulateEditDetails(path, offset, line);
+      });
+    });
+  }
+
+  List<Element> addHintLinks = parentElement.querySelectorAll('.add-hint-link');
+  addHintLinks.forEach((link) {
+    link.onClick.listen(handleAddHintLinkClick);
+  });
+}
+
+Future<HttpRequest> doGet(String path,
+        {Map<String, String> queryParameters = const {}}) =>
+    HttpRequest.request(pathWithQueryParameters(path, queryParameters),
+        requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'});
+
+Future<Map<String, Object>> doPost(String path) async {
+  var completer = new Completer<HttpRequest>();
+
+  var xhr = HttpRequest()
+    ..open('POST', pathWithQueryParameters(path, {}), async: true)
+    ..setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
+
+  xhr.onLoad.listen((e) {
+    completer.complete(xhr);
+  });
+
+  xhr.onError.listen(completer.completeError);
+
+  xhr.send();
+
+  await completer.future;
+
+  final json = jsonDecode(xhr.responseText);
+  if (xhr.status == 200) {
+    // Request OK.
+    return json as Map<String, Object>;
+  } else {
+    throw json;
+  }
+}
+
+/// Returns the URL of the "new issue" form for the SDK repository,
+/// pre-populating the title, some labels, using [description], [exception], and
+/// [stackTrace] in the body.
+Uri getGitHubErrorUri(
+        String description, Object exception, Object stackTrace) =>
+    Uri.https('github.com', 'dart-lang/sdk/issues/new', {
+      'title': 'Issue with NNBD migration tool: $description',
+      'labels': 'area-analyzer,analyzer-nnbd-migration,type-bug',
+      'body': '''
+$description
+
+Error: $exception
+
+Please fill in the following:
+
+**Name of package being migrated (if public)**:
+**What I was doing when this issue occurred**:
+**Is it possible to work around this issue**:
+**Has this issue happened before, and if so, how often**:
+**Dart SDK version**: $sdkVersion
+**Additional details**:
+
+Thanks for filing!
+
+Stacktrace: _auto populated by migration preview tool._
+
+```
+$stackTrace
+```
+''',
+    });
+
+/// Returns the URL of the "new issue" form for the SDK repository,
+/// pre-populating some labels and a body template.
+Uri getGitHubProblemUri() =>
+    Uri.https('github.com', 'dart-lang/sdk/issues/new', {
+      'labels': 'area-analyzer,analyzer-nnbd-migration,type-bug',
+      'body': '''
+#### Steps to reproduce
+
+#### What did you expect to happen?
+
+#### What actually happened?
+
+_Screenshots are appreciated_
+
+**Dart SDK version**: $sdkVersion
+
+Thanks for filing!
+''',
+    });
+
+int getLine(String location) {
+  var str = Uri.parse(location).queryParameters['line'];
+  return str == null ? null : int.tryParse(str);
+}
+
+int getOffset(String location) {
+  var str = Uri.parse(location).queryParameters['offset'];
+  return str == null ? null : int.tryParse(str);
+}
+
+void handleAddHintLinkClick(MouseEvent event) async {
+  var path = (event.currentTarget as Element).getAttribute('href');
+
+  // Don't navigate on link click.
+  event.preventDefault();
+
+  try {
+    // Directing the server to produce an edit; request it, then do work with the
+    // response.
+    await doPost(path);
+    // TODO(mfairhurst): Only refresh the regions/dart code, not the window.
+    (document.window.location as Location).reload();
+  } catch (e, st) {
+    handleError('Could not add/remove hint', e, st);
+  }
+}
+
+void handleError(String header, Object exception, Object stackTrace) {
+  String subheader;
+  if (exception is Map<String, Object> &&
+      exception['success'] == false &&
+      exception.containsKey('exception') &&
+      exception.containsKey('stackTrace')) {
+    subheader = exception['exception'] as String;
+    stackTrace = exception['stackTrace'];
+  } else {
+    subheader = exception.toString();
+  }
+  final popupPane = document.querySelector('.popup-pane');
+  popupPane.querySelector('h2').innerText = header;
+  popupPane.querySelector('p').innerText = subheader;
+  popupPane.querySelector('pre').innerText = stackTrace.toString();
+  (popupPane.querySelector('a.bottom') as AnchorElement).href =
+      getGitHubErrorUri(header, subheader, stackTrace).toString();
+  popupPane..style.display = 'initial';
+  logError('$header: $exception', stackTrace);
+}
+
+void handleNavLinkClick(
+  MouseEvent event,
+  bool clearEditDetails, {
+  String relativeTo,
+}) {
+  Element target = event.currentTarget as Element;
+  event.preventDefault();
+
+  var location = target.getAttribute('href');
+  var path = location;
+  if (path.contains('?')) {
+    path = path.substring(0, path.indexOf('?'));
+  }
+  // Fix-up the path - it might be relative.
+  if (relativeTo != null) {
+    path = _p.normalize(_p.join(_p.dirname(relativeTo), path));
+  }
+
+  var offset = getOffset(location);
+  var lineNumber = getLine(location);
+
+  if (offset != null) {
+    navigate(path, offset, lineNumber, clearEditDetails, callback: () {
+      pushState(path, offset, lineNumber);
+    });
+  } else {
+    navigate(path, null, null, clearEditDetails, callback: () {
+      pushState(path, null, null);
+    });
+  }
+}
+
+void highlightAllCode() {
+  document.querySelectorAll('.code').forEach((Element block) {
+    hljs.highlightBlock(block);
+  });
+}
+
+/// Loads the explanation for [region], into the ".panel-content" div.
+void loadAndPopulateEditDetails(String path, int offset, int line) {
+  // Request the region, then do work with the response.
+  doGet(path, queryParameters: {'region': 'region', 'offset': '$offset'})
+      .then((HttpRequest xhr) {
+    if (xhr.status == 200) {
+      var response = EditDetails.fromJson(jsonDecode(xhr.responseText));
+      populateEditDetails(response);
+      pushState(path, offset, line);
+      addClickHandlers('.edit-panel .panel-content', false);
+    } else {
+      window.alert('Request failed; status of ${xhr.status}');
+    }
+  }).catchError((e, st) {
+    logError('loadRegionExplanation: $e', st);
+
+    window.alert('Could not load $path ($e).');
+  });
+}
+
+/// Load the file at [path] from the server, optionally scrolling [offset] into
+/// view.
+void loadFile(
+  String path,
+  int offset,
+  int line,
+  bool clearEditDetails, {
+  VoidCallback callback,
+}) {
+  // Handle the case where we're requesting a directory.
+  if (!path.endsWith('.dart')) {
+    writeCodeAndRegions(path, FileDetails.empty(), clearEditDetails);
+    updatePage(path);
+    if (callback != null) {
+      callback();
+    }
+
+    return;
+  }
+
+  // Navigating to another file; request it, then do work with the response.
+  doGet(path, queryParameters: {'inline': 'true'}).then((HttpRequest xhr) {
+    if (xhr.status == 200) {
+      Map<String, dynamic> response =
+          jsonDecode(xhr.responseText) as Map<String, dynamic>;
+      writeCodeAndRegions(
+          path, FileDetails.fromJson(response), clearEditDetails);
+      maybeScrollToAndHighlight(offset, line);
+      var filePathPart =
+          path.contains('?') ? path.substring(0, path.indexOf('?')) : path;
+      updatePage(filePathPart, offset);
+      if (callback != null) {
+        callback();
+      }
+    } else {
+      window.alert('Request failed; status of ${xhr.status}');
+    }
+  }).catchError((e, st) {
+    logError('loadFile: $e', st);
+
+    window.alert('Could not load $path ($e).');
+  });
+}
+
+/// Load the navigation tree into the ".nav-tree" div.
+void loadNavigationTree() {
+  var path = '/_preview/navigationTree.json';
+
+  // Request the navigation tree, then do work with the response.
+  doGet(path).then((HttpRequest xhr) {
+    if (xhr.status == 200) {
+      dynamic response = jsonDecode(xhr.responseText);
+      var navTree = document.querySelector('.nav-tree');
+      navTree.innerHtml = '';
+      writeNavigationSubtree(
+          navTree, NavigationTreeNode.listFromJson(response));
+    } else {
+      window.alert('Request failed; status of ${xhr.status}');
+    }
+  }).catchError((e, st) {
+    logError('loadNavigationTree: $e', st);
+
+    window.alert('Could not load $path ($e).');
+  });
+}
+
+void logError(e, st) {
+  window.console.error('$e');
+  window.console.error('$st');
+}
+
+/// Scroll an element into view if it is not visible.
+void maybeScrollIntoView(Element element) {
+  var rect = element.getBoundingClientRect();
+  // A line of text in the code view is 14px high. Including it here means we
+  // only choose to _not_ scroll a line of code into view if the entire line is
+  // visible.
+  var lineHeight = 14;
+  var visibleCeiling = headerPanel.offsetHeight + lineHeight;
+  var visibleFloor =
+      window.innerHeight - (footerPanel.offsetHeight + lineHeight);
+  if (rect.bottom > visibleFloor) {
+    element.scrollIntoView();
+  } else if (rect.top < visibleCeiling) {
+    element.scrollIntoView();
+  }
+}
+
+/// Scroll target with id [offset] into view if it is not currently in view.
+///
+/// If [offset] is null, instead scroll the "unit-name" header, at the top of
+/// the page, into view.
+///
+/// Also add the "target" class, highlighting the target. Also add the
+/// "highlight" class to the entire line on which the target lies.
+void maybeScrollToAndHighlight(int offset, int lineNumber) {
+  Element target;
+  Element line;
+
+  if (offset != null) {
+    target = document.getElementById('o$offset');
+    line = document.querySelector('.line-$lineNumber');
+    if (target != null) {
+      maybeScrollIntoView(target);
+      target.classes.add('target');
+    } else if (line != null) {
+      // If the target doesn't exist, but the line does, scroll that into view
+      // instead.
+      maybeScrollIntoView(line.parent);
+    }
+    if (line != null) {
+      (line.parentNode as Element).classes.add('highlight');
+    }
+  } else {
+    // If no offset is given, this is likely a navigation link, and we need to
+    // scroll back to the top of the page.
+    maybeScrollIntoView(unitName);
+  }
+}
+
+/// Navigate to [path] and optionally scroll [offset] into view.
+///
+/// If [callback] is present, it will be called after the server response has
+/// been processed, and the content has been updated on the page.
+void navigate(
+  String path,
+  int offset,
+  int lineNumber,
+  bool clearEditDetails, {
+  VoidCallback callback,
+}) {
+  var currentOffset = getOffset(window.location.href);
+  var currentLineNumber = getLine(window.location.href);
+  removeHighlight(currentOffset, currentLineNumber);
+  if (path == window.location.pathname) {
+    // Navigating to same file; just scroll into view.
+    maybeScrollToAndHighlight(offset, lineNumber);
+    if (callback != null) {
+      callback();
+    }
+  } else {
+    loadFile(path, offset, lineNumber, clearEditDetails, callback: callback);
+  }
+}
+
+/// Returns [path], which may include query parameters, with a new path which
+/// adds (or replaces) parameters from [queryParameters].
+///
+/// Additionally, the "authToken" parameter will be added with the authToken
+/// found in the current location.
+String pathWithQueryParameters(
+    String path, Map<String, String> queryParameters) {
+  var uri = Uri.parse(path);
+  var mergedQueryParameters = {
+    ...uri.queryParameters,
+    ...queryParameters,
+    'authToken': authToken
+  };
+  return uri.replace(queryParameters: mergedQueryParameters).toString();
+}
+
+String pluralize(int count, String single, {String multiple}) {
+  return count == 1 ? single : (multiple ?? '${single}s');
+}
+
+void populateEditDetails([EditDetails response]) {
+  // Clear out any current edit details.
+  editPanel.innerHtml = '';
+  if (response == null) {
+    Element p = ParagraphElement()
+      ..text = 'See details about a proposed edit.'
+      ..classes = ['placeholder'];
+    editPanel.append(p);
+    p.scrollIntoView();
+    return;
+  }
+
+  var filePath = response.path;
+  var parentDirectory = _p.dirname(filePath);
+
+  // 'Changed ... at foo.dart:12.'
+  var explanationMessage = response.explanation;
+  var relPath = _p.relative(filePath, from: rootPath);
+  var line = response.line;
+  Element explanation = document.createElement('p');
+  editPanel.append(explanation);
+  explanation.append(Text('$explanationMessage at $relPath:$line.'));
+  explanation.scrollIntoView();
+  _populateEditTraces(response, editPanel, parentDirectory);
+  _populateEditLinks(response, editPanel);
+}
+
+/// Write the contents of the Edit List, from JSON data [editListData].
+void populateProposedEdits(
+    String path, Map<String, List<EditListItem>> edits, bool clearEditDetails) {
+  editListElement.innerHtml = '';
+
+  var editCount = edits.length;
+  if (editCount == 0) {
+    Element p = document.createElement('p');
+    editListElement.append(p);
+    p.append(Text('No proposed edits'));
+  } else {
+    for (var entry in edits.entries) {
+      Element p = document.createElement('p');
+      editListElement.append(p);
+      p.append(Text('${entry.key}:'));
+
+      Element list = document.createElement('ul');
+      editListElement.append(list);
+      for (var edit in entry.value) {
+        Element item = document.createElement('li');
+        list.append(item);
+        item.classes.add('edit');
+        AnchorElement anchor = AnchorElement();
+        item.append(anchor);
+        anchor.classes.add('edit-link');
+        var offset = edit.offset;
+        anchor.dataset['offset'] = '$offset';
+        var line = edit.line;
+        anchor.dataset['line'] = '$line';
+        anchor.append(Text('line $line'));
+        anchor.onClick.listen((MouseEvent event) {
+          navigate(window.location.pathname, offset, line, true, callback: () {
+            pushState(window.location.pathname, offset, line);
+          });
+          loadAndPopulateEditDetails(path, offset, line);
+        });
+        item.append(Text(': ${edit.explanation}'));
+      }
+    }
+  }
+
+  if (clearEditDetails) {
+    populateEditDetails();
+  }
+}
+
+void pushState(String path, int offset, int line) {
+  var uri = Uri.parse('${window.location.origin}$path');
+
+  var params = {
+    if (offset != null) 'offset': '$offset',
+    if (line != null) 'line': '$line',
+    'authToken': authToken,
+  };
+
+  uri = uri.replace(queryParameters: params);
+  window.history.pushState({}, '', uri.toString());
+}
+
+/// If [path] lies within [root], return the relative path of [path] from [root].
+/// Otherwise, return [path].
+String relativePath(String path) {
+  var root = querySelector('.root').text + '/';
+  if (path.startsWith(root)) {
+    return path.substring(root.length);
+  } else {
+    return path;
+  }
+}
+
+/// Remove highlighting from [offset].
+void removeHighlight(int offset, int lineNumber) {
+  if (offset != null) {
+    var anchor = document.getElementById('o$offset');
+    if (anchor != null) {
+      anchor.classes.remove('target');
+    }
+  }
+  if (lineNumber != null) {
+    var line = document.querySelector('.line-$lineNumber');
+    if (line != null) {
+      line.parent.classes.remove('highlight');
+    }
+  }
+}
+
+/// Update the heading and navigation links.
+///
+/// Call this after updating page content on a navigation.
+void updatePage(String path, [int offset]) {
+  path = relativePath(path);
+  // Update page heading.
+  unitName.text = path;
+  // Update navigation styles.
+  document.querySelectorAll('.nav-panel .nav-link').forEach((Element link) {
+    var name = link.dataset['name'];
+    if (name == path) {
+      link.classes.add('selected-file');
+    } else {
+      link.classes.remove('selected-file');
+    }
+  });
+}
+
+/// Load data from [data] into the .code and the .regions divs.
+void writeCodeAndRegions(String path, FileDetails data, bool clearEditDetails) {
+  var regionsElement = document.querySelector('.regions');
+  var codeElement = document.querySelector('.code');
+
+  _PermissiveNodeValidator.setInnerHtml(regionsElement, data.regions);
+  _PermissiveNodeValidator.setInnerHtml(codeElement, data.navigationContent);
+  populateProposedEdits(path, data.edits, clearEditDetails);
+
+  highlightAllCode();
+  addClickHandlers('.code', true);
+  addClickHandlers('.regions', true);
+}
+
+void writeNavigationSubtree(
+    Element parentElement, List<NavigationTreeNode> tree) {
+  Element ul = document.createElement('ul');
+  parentElement.append(ul);
+  for (var entity in tree) {
+    Element li = document.createElement('li');
+    ul.append(li);
+    if (entity.type == NavigationTreeNodeType.directory) {
+      li.classes.add('dir');
+      Element arrow = document.createElement('span');
+      li.append(arrow);
+      arrow.classes.add('arrow');
+      arrow.innerHtml = '&#x25BC;';
+      Element icon = document.createElement('span');
+      li.append(icon);
+      icon.innerHtml = '&#x1F4C1;';
+      li.append(Text(entity.name));
+      writeNavigationSubtree(li, entity.subtree);
+      addArrowClickHandler(arrow);
+    } else {
+      li.innerHtml = '&#x1F4C4;';
+      Element a = document.createElement('a');
+      li.append(a);
+      a.classes.add('nav-link');
+      a.dataset['name'] = entity.path;
+      a.setAttribute('href', entity.href);
+      a.append(Text(entity.name));
+      a.onClick.listen((MouseEvent event) => handleNavLinkClick(event, true));
+      var editCount = entity.editCount;
+      if (editCount > 0) {
+        Element editsBadge = document.createElement('span');
+        li.append(editsBadge);
+        editsBadge.classes.add('edit-count');
+        editsBadge.setAttribute(
+            'title', '$editCount ${pluralize(editCount, 'edit')}');
+        editsBadge.append(Text(editCount.toString()));
+      }
+    }
+  }
+}
+
+AnchorElement _aElementForLink(TargetLink link, String parentDirectory) {
+  var targetLine = link.line;
+  AnchorElement a = AnchorElement();
+  a.append(Text('${link.path}:$targetLine'));
+
+  var relLink = link.href;
+  var fullPath = _p.normalize(_p.join(parentDirectory, relLink));
+
+  a.setAttribute('href', fullPath);
+  a.classes.add('nav-link');
+  return a;
+}
+
+void _populateEditLinks(EditDetails response, Element editPanel) {
+  if (response.edits != null) {
+    Element editParagraph = document.createElement('p');
+    editPanel.append(editParagraph);
+    for (var edit in response.edits) {
+      Element a = document.createElement('a');
+      editParagraph.append(a);
+      a.append(Text(edit.description));
+      a.setAttribute('href', edit.href);
+      a.classes = ['add-hint-link', 'before-apply', 'button'];
+    }
+  }
+}
+
+void _populateEditTraces(
+    EditDetails response, Element editPanel, String parentDirectory) {
+  for (var trace in response.traces) {
+    var traceParagraph =
+        editPanel.append(document.createElement('p')..classes = ['trace']);
+    traceParagraph.append(document.createElement('span')
+      ..classes = ['type-description']
+      ..append(Text(trace.description)));
+    traceParagraph.append(Text(':'));
+    var ul = traceParagraph
+        .append(document.createElement('ul')..classes = ['trace']);
+    for (var entry in trace.entries) {
+      Element li = document.createElement('li')..innerHtml = '&#x274F; ';
+      ul.append(li);
+      li.append(document.createElement('span')
+        ..classes = ['function']
+        ..appendTextWithBreaks(entry.function ?? 'unknown'));
+      var link = entry.link;
+      if (link != null) {
+        li.append(Text(' ('));
+        li.append(_aElementForLink(link, parentDirectory));
+        li.append(Text(')'));
+      }
+      li.append(Text(': '));
+      li.appendTextWithBreaks(entry.description ?? 'unknown');
+    }
+  }
+}
+
+class _PermissiveNodeValidator implements NodeValidator {
+  static _PermissiveNodeValidator instance = _PermissiveNodeValidator();
+
+  @override
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    return true;
+  }
+
+  @override
+  bool allowsElement(Element element) {
+    return true;
+  }
+
+  static void setInnerHtml(Element element, String html) {
+    element.setInnerHtml(html, validator: instance);
+  }
+}
+
+/// 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/front_end/web/navigation_tree.dart b/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
new file mode 100644
index 0000000..de29189
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// Information about a node in the migration tool's navigation tree.
+class NavigationTreeNode {
+  /// Type of the node.
+  final NavigationTreeNodeType type;
+
+  /// Name of the node.
+  final String name;
+
+  /// If this is a directory node, list of nodes nested under this one.
+  /// Otherwise `null`.
+  final List<NavigationTreeNode> subtree;
+
+  /// If this is a file node, full path to the file.  Otherwise `null`.
+  final String path;
+
+  /// If this is a file node, href that should be used if the file is clicked
+  /// on, otherwise `null`.
+  final String href;
+
+  /// If this is a file node, number of edits that were made in the file,
+  /// otherwise `null`.
+  final int editCount;
+
+  /// Creates a navigation tree node representing a directory.
+  NavigationTreeNode.directory({@required this.name, @required this.subtree})
+      : type = NavigationTreeNodeType.directory,
+        path = null,
+        href = null,
+        editCount = null;
+
+  /// Creates a navigation tree node representing a file.
+  NavigationTreeNode.file(
+      {@required this.name,
+      @required this.path,
+      @required this.href,
+      @required this.editCount})
+      : type = NavigationTreeNodeType.file,
+        subtree = null;
+
+  NavigationTreeNode.fromJson(dynamic json)
+      : type = _decodeType(json['type'] as String),
+        name = json['name'] as String,
+        subtree = listFromJsonOrNull(json['subtree']),
+        path = json['path'] as String,
+        href = json['href'] as String,
+        editCount = json['editCount'] as int;
+
+  Map<String, Object> toJson() => {
+        'type': _encodeType(type),
+        'name': name,
+        if (subtree != null) 'subtree': listToJson(subtree),
+        if (path != null) 'path': path,
+        if (href != null) 'href': href,
+        if (editCount != null) 'editCount': editCount
+      };
+
+  /// Deserializes a list of navigation tree nodes from a JSON list.
+  static List<NavigationTreeNode> listFromJson(dynamic json) =>
+      [for (var node in json) NavigationTreeNode.fromJson(node)];
+
+  /// Deserializes a list of navigation tree nodes from a possibly null JSON
+  /// list.  If the argument is `null`, `null` is returned.
+  static List<NavigationTreeNode> listFromJsonOrNull(dynamic json) =>
+      json == null ? null : listFromJson(json);
+
+  /// Serializes a list of navigation tree nodes into JSON.
+  static List<Map<String, Object>> listToJson(List<NavigationTreeNode> nodes) =>
+      [for (var node in nodes) node.toJson()];
+
+  static NavigationTreeNodeType _decodeType(String json) {
+    switch (json) {
+      case 'directory':
+        return NavigationTreeNodeType.directory;
+      case 'file':
+        return NavigationTreeNodeType.file;
+      default:
+        throw StateError('Unrecognized navigation tree node type: $json');
+    }
+  }
+
+  static String _encodeType(NavigationTreeNodeType type) {
+    switch (type) {
+      case NavigationTreeNodeType.directory:
+        return 'directory';
+      case NavigationTreeNodeType.file:
+        return 'file';
+    }
+    throw StateError('Unrecognized navigation tree node type: $type');
+  }
+}
+
+/// Enum representing the different types of [NavigationTreeNode]s.
+enum NavigationTreeNodeType {
+  directory,
+  file,
+}
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 256a199..4b19615 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -16,7 +16,6 @@
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
-import 'package:nnbd_migration/src/potential_modification.dart';
 import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
 import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
@@ -203,7 +202,6 @@
           '(${node.parent.parent.toSource()}) offset=${node.offset}');
     }
     decoratedType.node.trackPossiblyOptional();
-    _variables.recordPossiblyOptional(source, node, decoratedType.node);
     return null;
   }
 
@@ -421,8 +419,7 @@
     if (type.isVoid || type.isDynamic) {
       var nullabilityNode = NullabilityNode.forTypeAnnotation(target);
       var decoratedType = DecoratedType(type, nullabilityNode);
-      _variables.recordDecoratedTypeAnnotation(
-          source, node, decoratedType, null);
+      _variables.recordDecoratedTypeAnnotation(source, node, decoratedType);
       return decoratedType;
     }
     var typeArguments = const <DecoratedType>[];
@@ -495,23 +492,23 @@
           positionalParameters: positionalParameters,
           namedParameters: namedParameters);
     }
-    _variables.recordDecoratedTypeAnnotation(
-        source,
-        node,
-        decoratedType,
-        PotentiallyAddQuestionSuffix(
-            nullabilityNode, decoratedType.type, node.end));
-    switch (getPostfixHint(node)) {
-      case NullabilityComment.bang:
-        _graph.makeNonNullableUnion(
-            decoratedType.node, NullabilityCommentOrigin(source, node, false));
-        break;
-      case NullabilityComment.question:
-        _graph.makeNullableUnion(
-            decoratedType.node, NullabilityCommentOrigin(source, node, true));
-        break;
-      case NullabilityComment.none:
-        break;
+    _variables.recordDecoratedTypeAnnotation(source, node, decoratedType);
+    var hint = getPostfixHint(node.endToken);
+    if (hint != null) {
+      switch (hint.kind) {
+        case HintCommentKind.bang:
+          _graph.makeNonNullableUnion(decoratedType.node,
+              NullabilityCommentOrigin(source, node, false));
+          _variables.recordNullabilityHint(source, node, hint);
+          break;
+        case HintCommentKind.question:
+          _graph.makeNullableUnion(
+              decoratedType.node, NullabilityCommentOrigin(source, node, true));
+          _variables.recordNullabilityHint(source, node, hint);
+          break;
+        default:
+          break;
+      }
     }
     return decoratedType;
   }
@@ -545,12 +542,9 @@
     node.metadata.accept(this);
     var typeAnnotation = node.type;
     var type = typeAnnotation?.accept(this);
-    switch (getPrefixHint(node.firstTokenAfterCommentAndMetadata)) {
-      case PrefixHintComment.late_:
-        _variables.recordLateHint(source, node);
-        break;
-      case PrefixHintComment.none:
-        break;
+    var hint = getPrefixHint(node.firstTokenAfterCommentAndMetadata);
+    if (hint != null && hint.kind == HintCommentKind.late_) {
+      _variables.recordLateHint(source, node, hint);
     }
     for (var variable in node.variables) {
       variable.metadata.accept(this);
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 48d2fbc..d80b2b4 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
@@ -47,6 +47,8 @@
   /// code that is removed.
   final bool removeViaComments;
 
+  final bool warnOnWeakCode;
+
   final _decoratedTypeParameterBounds = DecoratedTypeParameterBounds();
 
   /// If not `null`, the object that will be used to write out post-mortem
@@ -61,17 +63,22 @@
   /// complete.  TODO(paulberry): remove this mode once the migration algorithm
   /// is fully implemented.
   ///
-  /// Optional parameter [removeViaComments] indicates whether dead code should
-  /// be removed in its entirety (the default) or removed by commenting it out.
+  /// Optional parameter [removeViaComments] indicates whether code that the
+  /// migration tool wishes to remove should instead be commenting it out.
+  ///
+  /// Optional parameter [warnOnWeakCode] indicates whether weak-only code
+  /// should be warned about or removed (in the way specified by
+  /// [removeViaComments]).
   NullabilityMigrationImpl(NullabilityMigrationListener listener,
       {bool permissive: false,
       NullabilityMigrationInstrumentation instrumentation,
-      bool removeViaComments = true})
+      bool removeViaComments = true,
+      bool warnOnWeakCode = true})
       : this._(listener, NullabilityGraph(instrumentation: instrumentation),
-            permissive, instrumentation, removeViaComments);
+            permissive, instrumentation, removeViaComments, warnOnWeakCode);
 
   NullabilityMigrationImpl._(this.listener, this._graph, this._permissive,
-      this._instrumentation, this.removeViaComments) {
+      this._instrumentation, this.removeViaComments, this.warnOnWeakCode) {
     _instrumentation?.immutableNodes(_graph.never, _graph.always);
     _postmortemFileWriter?.graph = _graph;
   }
@@ -97,8 +104,10 @@
         library.typeSystem as TypeSystemImpl,
         _variables,
         library,
-        listener,
-        unit);
+        _permissive ? listener : null,
+        unit,
+        warnOnWeakCode,
+        _graph);
     try {
       DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
       fixBuilder.visitAll();
@@ -106,7 +115,7 @@
       DecoratedTypeParameterBounds.current = null;
     }
     var changes = FixAggregator.run(unit, result.content, fixBuilder.changes,
-        removeViaComments: removeViaComments);
+        removeViaComments: removeViaComments, warnOnWeakCode: warnOnWeakCode);
     _instrumentation?.changes(source, changes);
     final lineInfo = LineInfo.fromContent(source.contents.data);
     var offsets = changes.keys.toList();
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index a7ce41f2..8d803b5 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -9,6 +9,7 @@
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nullability_state.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
 import 'package:nnbd_migration/src/postmortem_file.dart';
 
@@ -59,6 +60,26 @@
       : super.fromJson(json, deserializer);
 }
 
+/// Conditions of the "lateness" of a [NullabilityNode].
+enum LateCondition {
+  /// The associated [NullabilityNode] does not represent the type of a late
+  /// variable.
+  notLate,
+
+  /// The associated [NullabilityNode] represents the type of a late variable,
+  /// due to a `/*late*/` hint.
+  lateDueToHint,
+
+  /// The associated [NullabilityNode] represents an variable which is possibly
+  /// late, due to the late-inferring algorithm.
+  possiblyLate,
+
+  /// The associated [NullabilityNode] represents an variable which is possibly
+  /// late, due to being assigned in a function passed to a call to the test
+  /// package's `setUp` function.
+  possiblyLateDueToTestSetup,
+}
+
 /// Abstract interface for assigning ids numbers to nodes.  This allows us to
 /// annotate nodes with their ids when analyzing postmortem output.
 abstract class NodeToIdMapper {
@@ -86,6 +107,13 @@
 
   final String description;
 
+  /// Whether this edge is the result of an uninitialized variable declaration.
+  final bool isUninit;
+
+  /// Whether this edge is the result of an assignment within the test package's
+  /// `setUp` function.
+  final bool isSetupAssignment;
+
   NullabilityEdge.fromJson(
       dynamic json, NullabilityGraphDeserializer deserializer)
       : destinationNode = deserializer.nodeForId(json['dest'] as int),
@@ -93,7 +121,9 @@
         _kind = _deserializeKind(json['kind']),
         codeReference =
             json['code'] == null ? null : CodeReference.fromJson(json['code']),
-        description = json['description'] as String {
+        description = json['description'] as String,
+        isUninit = json['isUninit'] as bool,
+        isSetupAssignment = json['isSetupAssignment'] as bool {
     deserializer.defer(() {
       for (var id in json['us'] as List<dynamic>) {
         upstreamNodes.add(deserializer.nodeForId(id as int));
@@ -103,7 +133,7 @@
 
   NullabilityEdge._(
       this.destinationNode, this.upstreamNodes, this._kind, this.description,
-      {this.codeReference});
+      {this.codeReference, this.isUninit, this.isSetupAssignment});
 
   @override
   Iterable<NullabilityNode> get guards => upstreamNodes.skip(1);
@@ -158,6 +188,9 @@
       case _NullabilityEdgeKind.union:
         json['kind'] = 'union';
         break;
+      case _NullabilityEdgeKind.dummy:
+        json['kind'] = 'dummy';
+        break;
     }
     if (codeReference != null) json['code'] = codeReference.toJson();
     if (description != null) json['description'] = description;
@@ -183,6 +216,9 @@
       case _NullabilityEdgeKind.union:
         edgeDecorations.add('union');
         break;
+      case _NullabilityEdgeKind.dummy:
+        edgeDecorations.add('dummy');
+        break;
     }
     edgeDecorations.addAll(guards);
     var edgeDecoration =
@@ -271,6 +307,11 @@
     return _connect(upstreamNodes, destinationNode, kind, origin);
   }
 
+  /// Records that [sourceNode] is immediately upstream from [always], via a
+  /// dummy edge.
+  NullabilityEdge connectDummy(NullabilityNode sourceNode, EdgeOrigin origin) =>
+      _connect([sourceNode], always, _NullabilityEdgeKind.dummy, origin);
+
   /// Prints out a representation of the graph nodes.  Useful in debugging
   /// broken tests.
   void debugDump() {
@@ -429,9 +470,16 @@
       NullabilityNode destinationNode,
       _NullabilityEdgeKind kind,
       EdgeOrigin origin) {
+    var isUninit = origin?.kind == EdgeOriginKind.fieldNotInitialized ||
+        origin?.kind == EdgeOriginKind.implicitNullInitializer ||
+        origin?.kind == EdgeOriginKind.uninitializedRead;
+    var isSetupAssignment =
+        origin is ExpressionChecksOrigin && origin.isSetupAssignment;
     var edge = NullabilityEdge._(
         destinationNode, upstreamNodes, kind, origin?.description,
-        codeReference: origin?.codeReference);
+        codeReference: origin?.codeReference,
+        isUninit: isUninit,
+        isSetupAssignment: isSetupAssignment);
     instrumentation?.graphEdge(edge, origin);
     for (var upstreamNode in upstreamNodes) {
       _connectDownstream(upstreamNode, edge);
@@ -655,6 +703,8 @@
 /// variables.  Over time this will be replaced by a first class representation
 /// of the nullability inference graph.
 abstract class NullabilityNode implements NullabilityNodeInfo {
+  LateCondition _lateCondition = LateCondition.notLate;
+
   bool _isPossiblyOptional = false;
 
   /// List of [NullabilityEdge] objects describing this node's relationship to
@@ -765,6 +815,10 @@
   /// nullability migration needs to decide whether it is optional or required.
   bool get isPossiblyOptional => _isPossiblyOptional;
 
+  /// Indicates whether this node is associated with a variable declaration
+  /// which should be annotated with "late".
+  LateCondition get lateCondition => _lateCondition;
+
   /// After nullability propagation, this getter can be used to query the node's
   /// non-null intent state.
   NonNullIntent get nonNullIntent;
@@ -1238,6 +1292,10 @@
   /// Union edge.  Indicates that two nodes should have exactly the same
   /// nullability.
   union,
+
+  /// Dummy edge.  Indicates that two edges are connected in a way that should
+  /// not propagate (non-)nullability in either direction.
+  dummy,
 }
 
 class _NullabilityNodeImmutable extends NullabilityNode {
@@ -1386,11 +1444,35 @@
             continue;
           }
         }
+        if (edge.isUninit && !node.isNullable) {
+          // [edge] is an edge from always to an uninitialized variable
+          // declaration.
+          var isSetupAssigned = node.upstreamEdges
+              .any((e) => e is NullabilityEdge && e.isSetupAssignment);
+
+          // Whether all downstream edges go to nodes with non-null intent.
+          var allDownstreamHaveNonNullIntent = false;
+          if (node.downstreamEdges.isNotEmpty) {
+            allDownstreamHaveNonNullIntent = node.downstreamEdges.every((e) {
+              var destination = e.destinationNode;
+              return destination is NullabilityNode &&
+                  destination.nonNullIntent.isPresent;
+            });
+          }
+          if (allDownstreamHaveNonNullIntent) {
+            node._lateCondition = LateCondition.possiblyLate;
+            continue;
+          } else if (isSetupAssigned) {
+            node._lateCondition = LateCondition.possiblyLateDueToTestSetup;
+            continue;
+          }
+        }
         if (node is NullabilityNodeMutable && !node.isNullable) {
           assert(step.targetNode == null);
           step.targetNode = node;
           step.newState = Nullability.ordinaryNullable;
           _setNullable(step);
+          node._lateCondition = LateCondition.notLate;
         }
       }
       if (_pendingSubstitutions.isEmpty) break;
diff --git a/pkg/nnbd_migration/lib/src/potential_modification.dart b/pkg/nnbd_migration/lib/src/potential_modification.dart
index 1e170f9..08bf83e 100644
--- a/pkg/nnbd_migration/lib/src/potential_modification.dart
+++ b/pkg/nnbd_migration/lib/src/potential_modification.dart
@@ -3,16 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
-import 'package:nnbd_migration/instrumentation.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/conditional_discard.dart';
-import 'package:nnbd_migration/src/nullability_node.dart';
 
 /// Records information about how a conditional expression or statement might
 /// need to be modified.
-class ConditionalModification extends PotentialModification {
+class ConditionalModification {
   final int offset;
 
   final int end;
@@ -53,134 +48,6 @@
 
   ConditionalModification._(this.offset, this.end, this.isStatement,
       this.discard, this.condition, this.thenStatement, this.elseStatement);
-
-  @override
-  NullabilityFixDescription get description => discard.keepFalse
-      ? NullabilityFixDescription.discardThen
-      : (elseStatement == null
-          ? NullabilityFixDescription.discardCondition
-          : NullabilityFixDescription.discardElse);
-
-  @override
-  bool get isEmpty => discard.keepTrue && discard.keepFalse;
-
-  @override
-  Iterable<SourceEdit> get modifications {
-    if (isEmpty) return const [];
-    // TODO(paulberry): move the following logic into DartEditBuilder (see
-    // dartbug.com/35872).
-    var result = <SourceEdit>[];
-    var keepNodes = <_KeepNode>[];
-    if (!discard.pureCondition) {
-      keepNodes.add(condition); // TODO(paulberry): test
-    }
-    if (discard.keepTrue) {
-      keepNodes.add(thenStatement); // TODO(paulberry): test
-    }
-    if (discard.keepFalse && elseStatement != null) {
-      keepNodes.add(elseStatement); // TODO(paulberry): test
-    }
-    // TODO(paulberry): test thoroughly
-    for (int i = 0; i < keepNodes.length; i++) {
-      var keepNode = keepNodes[i];
-      if (i == 0 && keepNode.offset != offset) {
-        result.add(SourceEdit(offset, 0, '/* '));
-      }
-      if (i != 0 || keepNode.offset != offset) {
-        result.add(SourceEdit(keepNode.offset, 0, '*/ '));
-      }
-      if (i != keepNodes.length - 1 || keepNode.end != end) {
-        result.add(SourceEdit(keepNode.end, 0,
-            keepNode.isExpression && isStatement ? '; /*' : ' /*'));
-      }
-      if (i == keepNodes.length - 1 && keepNode.end != end) {
-        result.add(SourceEdit(end, 0, ' */'));
-      }
-    }
-    return result;
-  }
-
-  @override
-  Iterable<FixReasonInfo> get reasons => discard.reasons;
-}
-
-/// Records information about the possible addition of a `?` suffix to a type in
-/// the source code.
-class PotentiallyAddQuestionSuffix extends PotentialModification {
-  final NullabilityNode node;
-  final DartType type;
-  final int _offset;
-
-  PotentiallyAddQuestionSuffix(this.node, this.type, this._offset);
-
-  @override
-  NullabilityFixDescription get description =>
-      NullabilityFixDescription.makeTypeNullable(
-          type.getDisplayString(withNullability: false));
-
-  @override
-  bool get isEmpty => !node.isNullable;
-
-  @override
-  Iterable<SourceEdit> get modifications =>
-      isEmpty ? [] : [SourceEdit(_offset, 0, '?')];
-
-  @override
-  Iterable<FixReasonInfo> get reasons => [node];
-}
-
-/// Records information about the possible addition of a `required` keyword
-/// to the source code.
-class PotentiallyAddRequired extends PotentialModification {
-  final NullabilityNode _node;
-
-  final int _offset;
-  final String className;
-  final String methodName;
-  final String parameterName;
-
-  factory PotentiallyAddRequired(
-      DefaultFormalParameter parameter, NullabilityNode node) {
-    final element = parameter.declaredElement;
-    final method = element.enclosingElement;
-    final cls = method.enclosingElement;
-    return PotentiallyAddRequired._(
-        node, parameter.offset, cls.name, method.name, element.name);
-  }
-
-  PotentiallyAddRequired._(this._node, this._offset, this.className,
-      this.methodName, this.parameterName);
-
-  @override
-  NullabilityFixDescription get description =>
-      NullabilityFixDescription.addRequired(
-          className, methodName, parameterName);
-
-  @override
-  bool get isEmpty => _node.isNullable;
-
-  @override
-  Iterable<SourceEdit> get modifications =>
-      isEmpty ? const [] : [SourceEdit(_offset, 0, 'required ')];
-
-  @override
-  Iterable<FixReasonInfo> get reasons => [_node];
-}
-
-/// Interface used by data structures representing potential modifications to
-/// the code being migrated.
-abstract class PotentialModification {
-  /// Gets a [NullabilityFixDescription] describing this modification.
-  NullabilityFixDescription get description;
-
-  bool get isEmpty;
-
-  /// Gets the individual migrations that need to be done, considering the
-  /// solution to the constraint equations.
-  Iterable<SourceEdit> get modifications;
-
-  /// Gets the reasons for this potential modification.
-  Iterable<FixReasonInfo> get reasons;
 }
 
 /// Helper object used by [ConditionalModification] to keep track of AST nodes
diff --git a/pkg/nnbd_migration/lib/src/preview/dart_file_page.dart b/pkg/nnbd_migration/lib/src/preview/dart_file_page.dart
new file mode 100644
index 0000000..12aff05
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/dart_file_page.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/unit_renderer.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that is displayed when a preview of a valid Dart file is requested.
+class DartFilePage extends PreviewPage {
+  /// The information about the file being previewed.
+  final UnitInfo unitInfo;
+
+  /// Initialize a newly created Dart file page within the given [site]. The
+  /// [unitInfo] provides the information needed to render the page.
+  DartFilePage(PreviewSite site, this.unitInfo)
+      // TODO(brianwilkerson) The path needs to be converted to use '/' if that
+      //  isn't already done as part of building the unitInfo.
+      : super(site, unitInfo.path.substring(1));
+
+  @override
+  bool get requiresAuth => true;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    throw UnsupportedError('generateBody');
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    var renderer = UnitRenderer(unitInfo, site.migrationInfo, site.pathMapper);
+    buf.write(jsonEncode(renderer.render().toJson()));
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/exception_page.dart b/pkg/nnbd_migration/lib/src/preview/exception_page.dart
new file mode 100644
index 0000000..2d8abcc
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/exception_page.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that is displayed when an exception is encountered in the process
+/// of composing the content of a different page.
+class ExceptionPage extends PreviewPage {
+  /// The message from the exception that caused this page to be displayed.
+  final String message;
+
+  /// The stack trace of the exception that caused this page to be displayed.
+  final StackTrace stackTrace;
+
+  /// Initialize a newly created exception page within the given [site]. The
+  /// [message] and [stackTrace] are used to describe the exception to the user.
+  ExceptionPage(PreviewSite site, String path, this.message, this.stackTrace)
+      : super(site, path.substring(1));
+
+  @override
+  bool get requiresAuth => false;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    buf.write('''
+<h1>500 Exception in preview</h1>
+<p>
+We're sorry, but you've encountered a bug in the preview tool. Please visit
+<a href='https://github.com/dart-lang/sdk/issues/new'>
+github.com/dart-lang/sdk/issues/new</a> to report the issue and include the
+stack trace below.
+</p>
+<h2>$message</h2>
+<p style="white-space: pre">
+${htmlEscape.convert(stackTrace.toString())}
+</p>
+''');
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/highlight_css_page.dart b/pkg/nnbd_migration/lib/src/preview/highlight_css_page.dart
new file mode 100644
index 0000000..7553358
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/highlight_css_page.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:nnbd_migration/src/front_end/resources/resources.g.dart'
+    as resources;
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that contains the CSS used to style the semantic highlighting
+/// within a Dart file.
+class HighlightCssPage extends PreviewPage {
+  /// Initialize a newly created CSS page within the given [site].
+  HighlightCssPage(PreviewSite site)
+      : super(site, PreviewSite.highlightCssPath.substring(1));
+
+  @override
+  bool get requiresAuth => false;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    buf.write(resources.highlight_css);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/highlight_js_page.dart b/pkg/nnbd_migration/lib/src/preview/highlight_js_page.dart
new file mode 100644
index 0000000..177266c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/highlight_js_page.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:nnbd_migration/src/front_end/resources/resources.g.dart'
+    as resources;
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that contains the JavaScript used to apply semantic highlighting
+/// styles to a Dart file.
+class HighlightJSPage extends PreviewPage {
+  /// Initialize a newly created JS page within the given [site].
+  HighlightJSPage(PreviewSite site)
+      : super(site, PreviewSite.highlightJsPath.substring(1));
+
+  @override
+  bool get requiresAuth => false;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    buf.write(resources.highlight_pack_js);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/http_preview_server.dart b/pkg/nnbd_migration/lib/src/preview/http_preview_server.dart
new file mode 100644
index 0000000..5c95f02
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/http_preview_server.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:nnbd_migration/src/front_end/migration_state.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// Instances of the class [AbstractGetHandler] handle GET requests.
+abstract class AbstractGetHandler {
+  /// Handle a GET request received by the HTTP server.
+  Future<void> handleGetRequest(HttpRequest request);
+}
+
+/// Instances of the class [AbstractPostHandler] handle POST requests.
+abstract class AbstractPostHandler {
+  /// Handle a POST request received by the HTTP server.
+  Future<void> handlePostRequest(HttpRequest request);
+}
+
+/// Instances of the class [HttpPreviewServer] implement a simple HTTP server
+/// that serves up dartfix preview pages.
+class HttpPreviewServer {
+  /// The state of the migration being previewed.
+  final MigrationState migrationState;
+
+  /// The [PreviewSite] that can handle GET and POST requests.
+  PreviewSite previewSite;
+
+  /// Future that is completed with the HTTP server once it is running.
+  Future<HttpServer> _serverFuture;
+
+  // A function which allows the migration to be rerun, taking changed paths.
+  final Future<MigrationState> Function([List<String>]) rerunFunction;
+
+  /// Integer for a port to run the preview server on.  If null or zero, allow
+  /// [HttpServer.bind] to pick one.
+  final int preferredPort;
+
+  /// Initialize a newly created HTTP server.
+  HttpPreviewServer(
+      this.migrationState, this.rerunFunction, this.preferredPort);
+
+  Future<String> get authToken async {
+    await _serverFuture;
+    previewSite ??= PreviewSite(migrationState, rerunFunction);
+    return previewSite.serviceAuthToken;
+  }
+
+  /// Return the port this server is bound to.
+  Future<int> get boundPort async {
+    return (await _serverFuture)?.port;
+  }
+
+  void close() {
+    _serverFuture?.then((HttpServer server) {
+      server.close();
+    });
+  }
+
+  /// Begin serving HTTP requests over the given port.
+  Future<int> serveHttp() async {
+    if (_serverFuture != null) {
+      return boundPort;
+    }
+
+    try {
+      _serverFuture =
+          HttpServer.bind(InternetAddress.loopbackIPv4, preferredPort ?? 0);
+
+      var server = await _serverFuture;
+      _handleServer(server);
+      return server.port;
+    } catch (ignore) {
+      // If we can't bind to the specified port, don't remember the broken
+      // server.
+      _serverFuture = null;
+      // TODO(jcollins-g): Display a better error message?
+      rethrow;
+    }
+  }
+
+  /// Handle a GET request received by the HTTP server.
+  Future<void> _handleGetRequest(HttpRequest request) async {
+    previewSite ??= PreviewSite(migrationState, rerunFunction);
+    await previewSite.handleGetRequest(request);
+  }
+
+  /// Handle a POST request received by the HTTP server.
+  Future<void> _handlePostRequest(HttpRequest request) async {
+    previewSite ??= PreviewSite(migrationState, rerunFunction);
+    await previewSite.handlePostRequest(request);
+  }
+
+  /// Attach a listener to a newly created HTTP server.
+  void _handleServer(HttpServer httpServer) {
+    httpServer.listen((HttpRequest request) async {
+      var updateValues = request.headers[HttpHeaders.upgradeHeader];
+      if (request.method == 'GET') {
+        await _handleGetRequest(request);
+      } else if (request.method == 'POST') {
+        await _handlePostRequest(request);
+      } else if (updateValues != null && updateValues.contains('websocket')) {
+        // We do not support serving analysis server communications over
+        // WebSocket connections.
+        var response = request.response;
+        response.statusCode = HttpStatus.notFound;
+        response.headers.contentType = ContentType.text;
+        response.write(
+            'WebSocket connections not supported (${request.uri.path}).');
+        response.close();
+      } else {
+        _returnUnknownRequest(request);
+      }
+    });
+  }
+
+  /// Return an error in response to an unrecognized request received by the HTTP
+  /// server.
+  void _returnUnknownRequest(HttpRequest request) {
+    var response = request.response;
+    response.statusCode = HttpStatus.notFound;
+    response.headers.contentType = ContentType.text;
+    response.write('Not found');
+    response.close();
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/index_file_page.dart b/pkg/nnbd_migration/lib/src/preview/index_file_page.dart
new file mode 100644
index 0000000..b67d12c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/index_file_page.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/instrumentation_renderer.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that is displayed when the root of the included path is requested.
+class IndexFilePage extends PreviewPage {
+  /// Initialize a newly created index file page within the given [site].
+  IndexFilePage(PreviewSite site)
+      : super(site, site.migrationInfo.includedRoot);
+
+  @override
+  bool get requiresAuth => true;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    throw UnsupportedError('generateBody');
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    var renderer = InstrumentationRenderer(site.migrationInfo, site.pathMapper,
+        site.migrationState.hasBeenApplied, site.migrationState.needsRerun);
+    buf.write(renderer.render());
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/navigation_tree_page.dart b/pkg/nnbd_migration/lib/src/preview/navigation_tree_page.dart
new file mode 100644
index 0000000..5ee145f
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/navigation_tree_page.dart
@@ -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 file.
+
+import 'dart:convert';
+
+import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The JSON that is displayed for the navigation tree.
+class NavigationTreePage extends PreviewPage {
+  /// Initialize a newly created navigation tree page within the given [site].
+  NavigationTreePage(PreviewSite site)
+      : super(site, site.migrationInfo.includedRoot);
+
+  @override
+  bool get requiresAuth => true;
+
+  @override
+  // TODO(srawlins): Refactor JSON-returning pages like this to not inherit all
+  //  of the HTML logic from [PreviewPage].
+  void generateBody(Map<String, String> params) {
+    throw UnsupportedError('generateBody');
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    var renderer = NavigationTreeRenderer(site.migrationInfo, site.pathMapper);
+    buf.write(jsonEncode(NavigationTreeNode.listToJson(renderer.render())));
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/not_found_page.dart b/pkg/nnbd_migration/lib/src/preview/not_found_page.dart
new file mode 100644
index 0000000..7eca477
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/not_found_page.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that is displayed when an invalid URL is requested.
+class NotFoundPage extends PreviewPage {
+  /// Initialize a newly created file-not-found page within the given [site].
+  /// The [id] is the portion of the path to the page that follows the initial
+  /// slash ('/').
+  NotFoundPage(PreviewSite site, String id) : super(site, id);
+
+  @override
+  bool get requiresAuth => false;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    buf.write('''
+<h1>404 Not found</h1>
+<p>
+'$path' not found.
+</p>
+''');
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_page.dart b/pkg/nnbd_migration/lib/src/preview/preview_page.dart
new file mode 100644
index 0000000..7cebe8c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/preview_page.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+import 'package:analysis_server/src/status/pages.dart';
+
+/// A page displayed on the preview site.
+abstract class PreviewPage extends Page {
+  /// The site containing the page.
+  final PreviewSite site;
+
+  /// Initialize a newly created page within the given [site]. The [id] is the
+  /// portion of the path to the page that follows the initial slash ('/').
+  PreviewPage(this.site, String id) : super(id, '', description: '');
+
+  /// Whether pages of this type require authorization.
+  bool get requiresAuth;
+
+  /// Generate the content of the body tag.
+  void generateBody(Map<String, String> params);
+
+  /// Generate the content of the head tag.
+  void generateHead() {
+    buf.writeln('<meta charset="utf-8">');
+    buf.writeln('<meta name="viewport" content="width=device-width, '
+        'initial-scale=1.0">');
+    buf.writeln('<title>${site.title}</title>');
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    buf.writeln('<!DOCTYPE html><html lang="en">');
+    buf.writeln('<head>');
+    buf.writeln('</head>');
+    generateHead();
+    buf.writeln('<body>');
+    generateBody(params);
+    buf.writeln('</body>');
+    buf.writeln('</html>');
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
new file mode 100644
index 0000000..3f212ff
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -0,0 +1,362 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+import 'dart:typed_data';
+
+import 'package:analysis_server/src/status/pages.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/migration_state.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/preview/dart_file_page.dart';
+import 'package:nnbd_migration/src/preview/exception_page.dart';
+import 'package:nnbd_migration/src/preview/highlight_css_page.dart';
+import 'package:nnbd_migration/src/preview/highlight_js_page.dart';
+import 'package:nnbd_migration/src/preview/http_preview_server.dart';
+import 'package:nnbd_migration/src/preview/index_file_page.dart';
+import 'package:nnbd_migration/src/preview/navigation_tree_page.dart';
+import 'package:nnbd_migration/src/preview/not_found_page.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/region_page.dart';
+import 'package:nnbd_migration/src/preview/unauthorized_page.dart';
+
+// The randomly generated auth token used to access the preview site.
+String _makeAuthToken() {
+  final kTokenByteSize = 8;
+  var bytes = Uint8List(kTokenByteSize);
+  var random = Random.secure();
+  for (var i = 0; i < kTokenByteSize; i++) {
+    bytes[i] = random.nextInt(256);
+  }
+  return base64Url.encode(bytes);
+}
+
+/// The site used to serve pages for the preview tool.
+class PreviewSite extends Site
+    implements AbstractGetHandler, AbstractPostHandler {
+  /// The path of the CSS page used to style the semantic highlighting within a
+  /// Dart file.
+  static const highlightCssPath = '/highlight.css';
+
+  /// The path of the JS page used to associate highlighting within a Dart file.
+  static const highlightJsPath = '/highlight.pack.js';
+
+  static const navigationTreePath = '/_preview/navigationTree.json';
+
+  static const applyMigrationPath = '/apply-migration';
+
+  static const rerunMigrationPath = '/rerun-migration';
+
+  /// The state of the migration being previewed.
+  MigrationState migrationState;
+
+  /// A table mapping the paths of files to the information about the
+  /// compilation units at those paths.
+  final Map<String, UnitInfo> unitInfoMap = {};
+
+  // A function provided by DartFix to rerun the migration.
+  final Future<MigrationState> Function([List<String>]) rerunFunction;
+
+  final String serviceAuthToken = _makeAuthToken();
+
+  /// Initialize a newly created site to serve a preview of the results of an
+  /// NNBD migration.
+  PreviewSite(this.migrationState, this.rerunFunction)
+      : super('NNBD Migration Preview') {
+    reset();
+  }
+
+  /// Return the information about the migration that will be used to serve up
+  /// pages.
+  MigrationInfo get migrationInfo => migrationState.migrationInfo;
+
+  /// Return the path mapper used to map paths from the unit infos to the paths
+  /// being served.
+  PathMapper get pathMapper => migrationState.pathMapper;
+
+  @override
+  Page createExceptionPage(String message, StackTrace trace) {
+    // Use createExceptionPageWithPath instead.
+    throw UnimplementedError();
+  }
+
+  /// Return a page used to display an exception that occurred while attempting
+  /// to render another page. The [path] is the path to the page that was being
+  /// rendered when the exception was thrown. The [message] and [stackTrace] are
+  /// those from the exception.
+  Page createExceptionPageWithPath(
+      String path, String message, StackTrace stackTrace) {
+    return ExceptionPage(this, path, message, stackTrace);
+  }
+
+  /// Return a page used to display an exception that occurred while attempting
+  /// to render another page. The [path] is the path to the page that was being
+  /// rendered when the exception was thrown. The [message] and [stackTrace] are
+  /// those from the exception.
+  Page createJsonExceptionResponse(
+      String path, String message, StackTrace stackTrace) {
+    return ExceptionPage(this, path, message, stackTrace);
+  }
+
+  Page createUnauthorizedPage(String unauthorizedPath) {
+    return UnauthorizedPage(this, unauthorizedPath.substring(1));
+  }
+
+  @override
+  Page createUnknownPage(String unknownPath) {
+    return NotFoundPage(this, unknownPath.substring(1));
+  }
+
+  @override
+  Future<void> handleGetRequest(HttpRequest request) async {
+    var uri = request.uri;
+    var path = uri.path;
+    var decodedPath = pathMapper.reverseMap(uri);
+    try {
+      if (path == highlightCssPath) {
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/sdk/issues/39204
+        return await respond(request, HighlightCssPage(this));
+      } else if (path == highlightJsPath) {
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/sdk/issues/39204
+        return await respond(request, HighlightJSPage(this));
+      } else if (path == navigationTreePath) {
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/sdk/issues/39204
+        return await respond(request, NavigationTreePage(this));
+      } else if (path == '/' ||
+          decodedPath == migrationInfo.includedRoot ||
+          decodedPath ==
+              '${migrationInfo.includedRoot}${pathMapper.separator}') {
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/sdk/issues/39204
+        return await respond(request, IndexFilePage(this));
+      }
+
+      var unitInfo = unitInfoMap[decodedPath];
+      if (unitInfo != null) {
+        if (uri.queryParameters.containsKey('inline')) {
+          // TODO(devoncarew): Ensure that we don't serve content outside of our
+          //  project.
+
+          // Note: `return await` needed due to
+          // https://github.com/dart-lang/sdk/issues/39204
+          return await respond(request, DartFilePage(this, unitInfo));
+        } else if (uri.queryParameters.containsKey('region')) {
+          // TODO(devoncarew): Ensure that we don't serve content outside of our
+          //  project.
+
+          // Note: `return await` needed due to
+          // https://github.com/dart-lang/sdk/issues/39204
+          return await respond(request, RegionPage(this, unitInfo));
+        } else {
+          // Note: `return await` needed due to
+          // https://github.com/dart-lang/sdk/issues/39204
+          return await respond(request, IndexFilePage(this));
+        }
+      }
+      // Note: `return await` needed due to
+      // https://github.com/dart-lang/sdk/issues/39204
+      return await respond(
+          request, createUnknownPage(path), HttpStatus.notFound);
+    } catch (exception, stackTrace) {
+      _respondInternalError(request, path, exception, stackTrace);
+    }
+  }
+
+  @override
+  Future<void> handlePostRequest(HttpRequest request) async {
+    var uri = request.uri;
+    var path = uri.path;
+    try {
+      // All POST requests must be authorized.
+      if (!_isAuthorized(request)) {
+        return _respondUnauthorized(request);
+      }
+      if (path == applyMigrationPath) {
+        performApply();
+
+        respondOk(request);
+        return;
+      } else if (path == rerunMigrationPath) {
+        await rerunMigration();
+
+        respondOk(request);
+        return;
+      } else if (uri.queryParameters.containsKey('replacement')) {
+        await performEdit(uri);
+
+        respondOk(request);
+        return;
+      }
+    } catch (exception, stackTrace) {
+      _respondInternalError(request, path, exception, stackTrace);
+    }
+  }
+
+  /// Perform the migration.
+  void performApply() {
+    if (migrationState.hasBeenApplied) {
+      throw StateError(
+          'It looks like this migration has already been applied. Try'
+          ' restarting the migration tool if this is not the case.');
+    }
+
+    final edits = migrationState.listener.sourceChange.edits;
+
+    // Perform a full check that no files have changed before touching the disk.
+    for (final fileEdit in edits) {
+      final file = pathMapper.provider.getFile(fileEdit.file);
+      if (!file.path.endsWith('.dart')) {
+        continue;
+      }
+      var code = file.exists ? file.readAsStringSync() : '';
+      if (!unitInfoMap[file.path].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})');
+      }
+    }
+
+    // Eagerly mark the migration applied. If this throws, we cannot go back.
+    migrationState.markApplied();
+    for (final fileEdit in edits) {
+      final file = pathMapper.provider.getFile(fileEdit.file);
+      var code = file.exists ? file.readAsStringSync() : '';
+      code = SourceEdit.applySequence(code, fileEdit.edits);
+      file.writeAsStringSync(code);
+    }
+  }
+
+  /// Perform the edit indicated by the [uri].
+  Future<void> performEdit(Uri uri) async {
+    //
+    // Update the code on disk.
+    //
+    var params = uri.queryParameters;
+    var path = Uri.parse(uri.path).toFilePath();
+    var offset = int.parse(params['offset']);
+    var end = int.parse(params['end']);
+    var replacement = params['replacement'];
+    var file = pathMapper.provider.getFile(path);
+    var diskContent = file.readAsStringSync();
+    if (!unitInfoMap[path].hadDiskContent(diskContent)) {
+      throw StateError('Cannot perform edit. This file has been changed since'
+          ' last migration run. Press the "rerun from sources" button and then'
+          ' try again. (Changed file path is ${file.path})');
+    }
+    final unitInfo = unitInfoMap[path];
+    final diskMapper = unitInfo.diskChangesOffsetMapper;
+    final insertionOnly = offset == end;
+    if (insertionOnly) {
+      unitInfo.handleInsertion(offset, replacement);
+      migrationState.needsRerun = true;
+    }
+    var newContent = diskContent.replaceRange(
+        diskMapper.map(offset), diskMapper.map(end), replacement);
+    file.writeAsStringSync(newContent);
+    unitInfo.diskContent = newContent;
+    if (!insertionOnly) {
+      await rerunMigration([path]);
+    }
+  }
+
+  Future<void> rerunMigration([List<String> changedPaths]) async {
+    migrationState = await rerunFunction(changedPaths);
+    reset();
+  }
+
+  void reset() {
+    unitInfoMap.clear();
+    var unitInfos = migrationInfo.units;
+    var provider = pathMapper.provider;
+    for (var unit in unitInfos) {
+      unitInfoMap[unit.path] = unit;
+    }
+    for (var unit in migrationInfo.unitMap.values) {
+      if (!unitInfos.contains(unit)) {
+        if (unit.content == null) {
+          try {
+            unit.content = provider.getFile(unit.path).readAsStringSync();
+          } catch (_) {
+            // If we can't read the content of the file, then skip it.
+            continue;
+          }
+        }
+        unitInfoMap[unit.path] = unit;
+      }
+    }
+  }
+
+  @override
+  Future<void> respond(HttpRequest request, Page page,
+      [int code = HttpStatus.ok]) async {
+    if (page is PreviewPage && page.requiresAuth) {
+      if (!_isAuthorized(request)) {
+        return _respondUnauthorized(request);
+      }
+    }
+    var response = request.response;
+    response.statusCode = code;
+    if (page is HighlightCssPage) {
+      response.headers.contentType =
+          ContentType('text', 'css', charset: 'utf-8');
+    } else if (page is HighlightJSPage) {
+      response.headers.contentType =
+          ContentType('application', 'javascript', charset: 'utf-8');
+    } else {
+      response.headers.contentType = ContentType.html;
+    }
+    response.write(await page.generate(request.uri.queryParameters));
+    response.close();
+  }
+
+  /// Returns whether [request] is an authorized request.
+  bool _isAuthorized(HttpRequest request) {
+    var authToken = request.uri.queryParameters['authToken'];
+    return authToken == serviceAuthToken;
+  }
+
+  Future<void> _respondInternalError(HttpRequest request, String path,
+      dynamic exception, StackTrace stackTrace) async {
+    try {
+      if (request.headers.contentType.subType == 'json') {
+        return await respondJson(
+            request,
+            {
+              'success': false,
+              'exception': exception.toString(),
+              'stackTrace': stackTrace.toString(),
+            },
+            HttpStatus.internalServerError);
+      }
+      await respond(
+          request,
+          createExceptionPageWithPath(path, '$exception', stackTrace),
+          HttpStatus.internalServerError);
+    } catch (exception, stackTrace) {
+      var response = request.response;
+      response.statusCode = HttpStatus.internalServerError;
+      response.headers.contentType = ContentType.text;
+      response.write('$exception\n\n$stackTrace');
+      response.close();
+    }
+  }
+
+  /// Responds with a 401 Unauthorized response.
+  Future<void> _respondUnauthorized(HttpRequest request) async {
+    var page = createUnauthorizedPage(request.uri.path);
+    var response = request.response;
+    response
+      ..statusCode = HttpStatus.unauthorized
+      ..headers.contentType = ContentType.html
+      ..write(await page.generate(request.uri.queryParameters))
+      ..close();
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/region_page.dart b/pkg/nnbd_migration/lib/src/preview/region_page.dart
new file mode 100644
index 0000000..cb8dd99
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/region_page.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show jsonEncode;
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/region_renderer.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The HTML that is displayed for a region of code.
+class RegionPage extends PreviewPage {
+  /// The compilation unit information containing the region.
+  final UnitInfo unitInfo;
+
+  /// Initialize a newly created region page within the given [site]. The
+  /// [unitInfo] provides the information needed to render the page.
+  RegionPage(PreviewSite site, this.unitInfo)
+      : super(site, unitInfo.path.substring(1));
+
+  @override
+  bool get requiresAuth => true;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    throw UnsupportedError('generateBody');
+  }
+
+  @override
+  Future<void> generatePage(Map<String, String> params) async {
+    var region = unitInfo.regionAt(int.parse(params['offset']));
+    var renderer =
+        RegionRenderer(region, unitInfo, site.migrationInfo, site.pathMapper);
+    buf.write(jsonEncode(renderer.render().toJson()));
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/unauthorized_page.dart b/pkg/nnbd_migration/lib/src/preview/unauthorized_page.dart
new file mode 100644
index 0000000..8fff1c5
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/unauthorized_page.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+
+/// The page that is displayed when a request could not be authenticated.
+class UnauthorizedPage extends PreviewPage {
+  /// Initialize a newly created unauthorized page within the given [site].
+  /// The [id] is the portion of the path to the page that follows the initial
+  /// slash ('/').
+  UnauthorizedPage(PreviewSite site, String id) : super(site, id);
+
+  @override
+  bool get requiresAuth => false;
+
+  @override
+  void generateBody(Map<String, String> params) {
+    buf.write('''
+<h1>401 Unauthorized</h1>
+<p>
+Request for '$path' is unauthorized.
+</p>
+''');
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart b/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart
index 3249985..131fabf 100644
--- a/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart
@@ -3,27 +3,36 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
-import 'package:analyzer/dart/ast/ast.dart';
+import 'package:nnbd_migration/src/edit_plan.dart';
 
-/// Determine if the given token is a nullability hint, and if so, return the
-/// type of nullability hint it is.
-NullabilityComment classifyComment(Token token) {
-  if (token is CommentToken) {
-    if (token.lexeme == '/*!*/') return NullabilityComment.bang;
-    if (token.lexeme == '/*?*/') return NullabilityComment.question;
+/// Determines if the given [token] is followed by a nullability hint, and if
+/// so, returns information about it.  Otherwise returns `null`.
+HintComment getPostfixHint(Token token) {
+  var commentToken = token.next.precedingComments;
+  if (commentToken != null) {
+    HintCommentKind kind;
+    if (commentToken.lexeme == '/*!*/') {
+      kind = HintCommentKind.bang;
+    } else if (commentToken.lexeme == '/*?*/') {
+      kind = HintCommentKind.question;
+    } else {
+      return null;
+    }
+    return HintComment(
+        kind,
+        token.end,
+        commentToken.offset,
+        commentToken.offset + '/*'.length,
+        commentToken.end - '*/'.length,
+        commentToken.end,
+        commentToken.end);
   }
-  return NullabilityComment.none;
+  return null;
 }
 
-/// Determine if the given [node] is followed by a nullability hint, and if so,
-/// return the type of nullability hint it is followed by.
-NullabilityComment getPostfixHint(AstNode node) {
-  var commentToken = node.endToken.next.precedingComments;
-  var commentType = classifyComment(commentToken);
-  return commentType;
-}
-
-PrefixHintComment getPrefixHint(Token token) {
+/// Determines if the given [token] is preceded by a hint, and if so, returns
+/// information about it.  Otherwise returns `null`.
+HintComment getPrefixHint(Token token) {
   Token commentToken = token.precedingComments;
   if (commentToken != null) {
     while (true) {
@@ -31,13 +40,151 @@
       if (nextComment == null) break;
       commentToken = nextComment;
     }
-    if (commentToken.lexeme == '/*late*/') return PrefixHintComment.late_;
+    var lexeme = commentToken.lexeme;
+    if (lexeme.startsWith('/*') &&
+        lexeme.endsWith('*/') &&
+        lexeme.length > 'late'.length) {
+      var commentText =
+          lexeme.substring('/*'.length, lexeme.length - '*/'.length).trim();
+      if (commentText == 'late') {
+        var commentOffset = commentToken.offset;
+        var lateOffset = commentOffset + commentToken.lexeme.indexOf('late');
+        return HintComment(
+            HintCommentKind.late_,
+            commentOffset,
+            commentOffset,
+            lateOffset,
+            lateOffset + 'late'.length,
+            commentToken.end,
+            token.offset);
+      }
+    }
   }
-  return PrefixHintComment.none;
+  return null;
 }
 
-/// Types of comments that can influence nullability
-enum NullabilityComment {
+/// Information about a hint found in a source file.
+class HintComment {
+  static final _alphaNumericRegexp = RegExp('[a-zA-Z0-9]');
+
+  /// What kind of hint this is.
+  final HintCommentKind kind;
+
+  /// The file offset of the first character that should be removed if the hint
+  /// is to be removed.
+  final int _removeOffset;
+
+  /// The file offset of the first character of the hint comment itself.
+  final int _commentOffset;
+
+  /// The file offset of the first character that should be kept if the hint is
+  /// to be replaced with the hinted text.
+  final int _keepOffset;
+
+  /// The file offset just beyond the last character that should be kept if the
+  /// hint is to be replaced with the hinted text.
+  final int _keepEnd;
+
+  /// The file offset just beyond the last character of the hint comment itself.
+  final int _commentEnd;
+
+  /// The file offset just beyond the last character that should be removed if
+  /// the hint is to be removed.
+  final int _removeEnd;
+
+  HintComment(this.kind, this._removeOffset, this._commentOffset,
+      this._keepOffset, this._keepEnd, this._commentEnd, this._removeEnd)
+      : assert(_removeOffset <= _commentOffset),
+        assert(_commentOffset < _keepOffset),
+        assert(_keepOffset < _keepEnd),
+        assert(_keepEnd < _commentEnd),
+        assert(_commentEnd <= _removeEnd);
+
+  /// Creates the changes necessary to accept the given hint (replace it with
+  /// its contents and fix up whitespace).
+  Map<int, List<AtomicEdit>> changesToAccept(String sourceText,
+      {AtomicEditInfo info}) {
+    bool prependSpace = false;
+    bool appendSpace = false;
+    var removeOffset = _removeOffset;
+    var removeEnd = _removeEnd;
+    if (_isAlphaNumericBeforeOffset(sourceText, removeOffset) &&
+        _isAlphaNumericAtOffset(sourceText, _keepOffset)) {
+      if (sourceText[removeOffset] == ' ') {
+        // We can just keep this space.
+        removeOffset++;
+      } else {
+        prependSpace = true;
+      }
+    }
+    if (_isAlphaNumericBeforeOffset(sourceText, _keepEnd) &&
+        _isAlphaNumericAtOffset(sourceText, removeEnd)) {
+      if (sourceText[removeEnd - 1] == ' ') {
+        // We can just keep this space.
+        removeEnd--;
+      } else {
+        appendSpace = true;
+      }
+    }
+
+    return {
+      removeOffset: [
+        if (prependSpace) AtomicEdit.insert(' '),
+        AtomicEdit.delete(_keepOffset - removeOffset, info: info)
+      ],
+      _keepEnd: [AtomicEdit.delete(removeEnd - _keepEnd, info: info)],
+      if (appendSpace) removeEnd: [AtomicEdit.insert(' ')]
+    };
+  }
+
+  /// Creates the changes necessary to remove the given hint (and fix up
+  /// whitespace).
+  Map<int, List<AtomicEdit>> changesToRemove(String sourceText,
+      {AtomicEditInfo info}) {
+    bool appendSpace = false;
+    var removeOffset = this._removeOffset;
+    if (_isAlphaNumericBeforeOffset(sourceText, removeOffset) &&
+        _isAlphaNumericAtOffset(sourceText, _removeEnd)) {
+      if (sourceText[removeOffset] == ' ') {
+        // We can just keep this space.
+        removeOffset++;
+      } else {
+        appendSpace = true;
+      }
+    }
+    return {
+      removeOffset: [
+        AtomicEdit.delete(_removeEnd - removeOffset, info: info),
+        if (appendSpace) AtomicEdit.insert(' ')
+      ]
+    };
+  }
+
+  /// Creates the changes necessary to replace the given hint with a different
+  /// hint.
+  Map<int, List<AtomicEdit>> changesToReplace(
+      String sourceText, String replacement,
+      {AtomicEditInfo info}) {
+    return {
+      _commentOffset: [
+        AtomicEdit.replace(_commentEnd - _commentOffset, replacement,
+            info: info)
+      ]
+    };
+  }
+
+  static bool _isAlphaNumericAtOffset(String sourceText, int offset) {
+    return offset < sourceText.length &&
+        _alphaNumericRegexp.hasMatch(sourceText[offset]);
+  }
+
+  static bool _isAlphaNumericBeforeOffset(String sourceText, int offset) {
+    return offset > 0 && _alphaNumericRegexp.hasMatch(sourceText[offset - 1]);
+  }
+}
+
+/// Types of hint comments
+enum HintCommentKind {
   /// The comment `/*!*/`, which indicates that the type should not have a `?`
   /// appended.
   bang,
@@ -46,16 +193,7 @@
   /// appended.
   question,
 
-  /// No special comment.
-  none,
-}
-
-/// Types of comments that can appear before a token
-enum PrefixHintComment {
   /// The comment `/*late*/`, which indicates that the variable declaration
   /// should be late.
   late_,
-
-  /// No special comment
-  none,
 }
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 6b4096c..1d60f68 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -26,7 +26,7 @@
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
 import 'package:nnbd_migration/src/postmortem_file.dart';
-import 'package:nnbd_migration/src/potential_modification.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 
 /// Data structure used by [Variables.spanForUniqueIdentifier] to return an
 /// offset/end pair.
@@ -57,11 +57,11 @@
 
   final _expressionChecks = <Source, Map<int, ExpressionChecks>>{};
 
-  final _lateHints = <Source, Set<int>>{};
+  final _lateHints = <Source, Map<int, HintComment>>{};
 
-  final _nullCheckHints = <Source, Set<int>>{};
+  final _nullCheckHints = <Source, Map<int, HintComment>>{};
 
-  final _potentialModifications = <Source, List<PotentialModification>>{};
+  final _nullabilityHints = <Source, Map<int, HintComment>>{};
 
   final _unnecessaryCasts = <Source, Set<int>>{};
 
@@ -167,20 +167,26 @@
   ConditionalDiscard getConditionalDiscard(Source source, AstNode node) =>
       (_conditionalDiscards[source] ?? {})[node.offset];
 
-  Map<Source, List<PotentialModification>> getPotentialModifications() =>
-      _potentialModifications;
-
-  /// Queries whether the given [expression] is followed by a null check hint
-  /// (`/*!*/`).  See [recordNullCheckHint].
-  bool hasNullCheckHint(Source source, Expression expression) {
-    return (_nullCheckHints[source] ?? {})
-        .contains(uniqueIdentifierForSpan(expression.offset, expression.end));
+  /// If the given [node] is preceded by a `/*late*/` hint, returns the
+  /// HintComment for it; otherwise returns `null`.  See [recordLateHint].
+  HintComment getLateHint(Source source, VariableDeclarationList node) {
+    return (_lateHints[source] ?? {})[node.offset];
   }
 
-  /// Queries whether the given [node] is preceded by a `/*late*/` hint.  See
-  /// [recordLateHint].
-  bool isLateHinted(Source source, VariableDeclarationList node) {
-    return (_lateHints[source] ?? {}).contains(node.offset);
+  /// If the given [node] is followed by a `/*?*/` or /*!*/ hint, returns the
+  /// HintComment for it; otherwise returns `null`.  See
+  /// [recordNullabilityHint].
+  HintComment getNullabilityHint(Source source, TypeAnnotation node) {
+    return (_nullabilityHints[source] ??
+        {})[uniqueIdentifierForSpan(node.offset, node.end)];
+  }
+
+  /// If the given [expression] is followed by a null check hint (`/*!*/`),
+  /// returns the HintComment for it; otherwise returns `null`.  See
+  /// [recordNullCheckHint].
+  HintComment getNullCheckHint(Source source, Expression expression) {
+    return (_nullCheckHints[source] ??
+        {})[(uniqueIdentifierForSpan(expression.offset, expression.end))];
   }
 
   /// Records conditional discard information for the given AST node (which is
@@ -188,8 +194,6 @@
   void recordConditionalDiscard(
       Source source, AstNode node, ConditionalDiscard conditionalDiscard) {
     (_conditionalDiscards[source] ??= {})[node.offset] = conditionalDiscard;
-    _addPotentialModification(
-        source, ConditionalModification(node, conditionalDiscard));
   }
 
   /// Associates a [class_] with decorated type information for the superclasses
@@ -220,11 +224,9 @@
   void recordDecoratedExpressionType(Expression node, DecoratedType type) {}
 
   /// Associates decorated type information with the given [type] node.
-  void recordDecoratedTypeAnnotation(Source source, TypeAnnotation node,
-      DecoratedType type, PotentiallyAddQuestionSuffix potentialModification) {
+  void recordDecoratedTypeAnnotation(
+      Source source, TypeAnnotation node, DecoratedType type) {
     instrumentation?.explicitTypeNullability(source, node, type.node);
-    if (potentialModification != null)
-      _addPotentialModification(source, potentialModification);
     var id = uniqueIdentifierForSpan(node.offset, node.end);
     (_decoratedTypeAnnotations[source] ??= {})[id] = type;
     postmortemFileWriter?.storeFileDecorations(source.fullName, id, type);
@@ -233,31 +235,31 @@
   /// Associates a set of nullability checks with the given expression [node].
   void recordExpressionChecks(
       Source source, Expression expression, ExpressionChecksOrigin origin) {
-    _addPotentialModification(source, origin.checks);
     (_expressionChecks[source] ??=
             {})[uniqueIdentifierForSpan(expression.offset, expression.end)] =
         origin.checks;
   }
 
   /// Records that the given [node] was preceded by a `/*late*/` hint.
-  void recordLateHint(Source source, VariableDeclarationList node) {
-    (_lateHints[source] ??= {}).add(node.offset);
+  void recordLateHint(
+      Source source, VariableDeclarationList node, HintComment hint) {
+    (_lateHints[source] ??= {})[node.offset] = hint;
+  }
+
+  /// Records that the given [node] was followed by a `/*?*/` or `/*!*/` hint.
+  void recordNullabilityHint(
+      Source source, TypeAnnotation node, HintComment hintComment) {
+    (_nullabilityHints[source] ??=
+        {})[uniqueIdentifierForSpan(node.offset, node.end)] = hintComment;
   }
 
   /// Records that the given [expression] is followed by a null check hint
   /// (`/*!*/`), for later recall by [hasNullCheckHint].
-  void recordNullCheckHint(Source source, Expression expression) {
-    (_nullCheckHints[source] ??= {})
-        .add(uniqueIdentifierForSpan(expression.offset, expression.end));
-  }
-
-  /// Records that [node] is associated with the question of whether the named
-  /// [parameter] should be optional (should not have a `required`
-  /// annotation added to it).
-  void recordPossiblyOptional(
-      Source source, DefaultFormalParameter parameter, NullabilityNode node) {
-    var modification = PotentiallyAddRequired(parameter, node);
-    _addPotentialModification(source, modification);
+  void recordNullCheckHint(
+      Source source, Expression expression, HintComment hintComment) {
+    (_nullCheckHints[source] ??=
+            {})[uniqueIdentifierForSpan(expression.offset, expression.end)] =
+        hintComment;
   }
 
   /// Records the fact that prior to migration, an unnecessary cast existed at
@@ -342,11 +344,6 @@
       (_unnecessaryCasts[source] ?? const {})
           .contains(uniqueIdentifierForSpan(node.offset, node.end));
 
-  void _addPotentialModification(
-      Source source, PotentialModification potentialModification) {
-    (_potentialModifications[source] ??= []).add(potentialModification);
-  }
-
   /// Creates a decorated type for the given [element], which should come from
   /// an already-migrated library (or the SDK).
   DecoratedType _createDecoratedElementType(Element element) {
diff --git a/pkg/nnbd_migration/pubspec.yaml b/pkg/nnbd_migration/pubspec.yaml
index 5a21236..55968c0 100644
--- a/pkg/nnbd_migration/pubspec.yaml
+++ b/pkg/nnbd_migration/pubspec.yaml
@@ -3,10 +3,11 @@
 environment:
   sdk: '>=2.6.0 <3.0.0'
 dependencies:
-  _fe_analyzer_shared: 1.0.0
+  _fe_analyzer_shared: ^2.0.0
   analyzer: ^0.37.0
   analyzer_plugin: ^0.2.2
   path: ^1.6.2
+  stream_channel: any
   yaml: any
 dev_dependencies:
   args: ^1.5.2
diff --git a/pkg/nnbd_migration/test/abstract_context.dart b/pkg/nnbd_migration/test/abstract_context.dart
index 645ca41..b1ffcc8 100644
--- a/pkg/nnbd_migration/test/abstract_context.dart
+++ b/pkg/nnbd_migration/test/abstract_context.dart
@@ -18,6 +18,9 @@
 /// TODO(paulberry): this logic is duplicated from other packages.  Find a way
 /// share it, or avoid relying on it.
 class AbstractContextTest with ResourceProviderMixin {
+  static const _homePath = '/home';
+  static const testsPath = '$_homePath/tests';
+
   OverlayResourceProvider overlayResourceProvider;
 
   AnalysisContextCollection _analysisContextCollection;
@@ -40,15 +43,27 @@
 ''');
   }
 
-  /// Add a new file with the given [pathInLib] to the package with the
-  /// given [packageName].  Then ensure that the test package depends on the
-  /// [packageName].
+  /// Add a new file with the given [pathInLib] to the package with the given
+  /// [packageName].  Then ensure that the package under test depends on the
+  /// package.
   File addPackageFile(String packageName, String pathInLib, String content) {
     var packagePath = '/.pub-cache/$packageName';
     _addTestPackageDependency(packageName, packagePath);
     return newFile('$packagePath/lib/$pathInLib', content: content);
   }
 
+  /// Add the quiver package and a library with URI,
+  /// "package:quiver/check.dart".
+  ///
+  /// Then ensure that the package under test depends on the package.
+  void addQuiverPackage() {
+    addPackageFile('quiver', 'check.dart', r'''
+library quiver.check;
+
+T checkNotNull<T>(T reference, {dynamic message}) => T;
+''');
+  }
+
   Source addSource(String path, String content, [Uri uri]) {
     File file = newFile(path, content: content);
     Source source = file.createSource(uri);
@@ -57,17 +72,34 @@
     return source;
   }
 
-  /// Create all analysis contexts in `/home`.
+  /// Add the test_core package and a library with URI,
+  /// "package:test_core/test_core.dart".
+  ///
+  /// Then ensure that the package under test depends on the package.
+  void addTestCorePackage() {
+    addPackageFile('test_core', 'test_core.dart', r'''
+library test_core;
+
+void setUp(dynamic callback()) {}
+void group(dynamic description, dynamic body()) {}
+void test(dynamic description, dynamic body()) {}
+''');
+    addPackageFile('test', 'test.dart', r'''
+library test;
+export 'package:test_core/test_core.dart';
+''');
+  }
+
+  /// Create all analysis contexts in [_homePath].
   void createAnalysisContexts() {
     _analysisContextCollection = AnalysisContextCollectionImpl(
-      includedPaths: [convertPath('/home')],
+      includedPaths: [convertPath(_homePath)],
       enableIndex: true,
       resourceProvider: overlayResourceProvider,
       sdkPath: convertPath('/sdk'),
     );
 
-    var testPath = convertPath('/home/test');
-    _driver = getDriver(testPath);
+    _driver = getDriver(convertPath(testsPath));
   }
 
   /// Return the existing analysis context that should be used to analyze the
@@ -93,9 +125,9 @@
 
     new MockSdk(resourceProvider: resourceProvider);
 
-    newFolder('/home/test');
-    newFile('/home/test/.packages', content: r'''
-test:file:///home/test/lib
+    newFolder(testsPath);
+    newFile('$testsPath/.packages', content: '''
+tests:file://$testsPath/lib
 ''');
 
     createAnalysisContexts();
@@ -108,7 +140,7 @@
   }
 
   void _addTestPackageDependency(String name, String rootPath) {
-    var packagesFile = getFile('/home/test/.packages');
+    var packagesFile = getFile('$testsPath/.packages');
     var packagesContent = packagesFile.readAsStringSync();
 
     // Ignore if there is already the same package dependency.
@@ -125,13 +157,13 @@
 
   void _createDriver() {
     var collection = AnalysisContextCollectionImpl(
-      includedPaths: [convertPath('/home')],
+      includedPaths: [convertPath(_homePath)],
       enableIndex: true,
       resourceProvider: resourceProvider,
       sdkPath: convertPath('/sdk'),
     );
 
-    var testPath = convertPath('/home/test');
+    var testPath = convertPath(testsPath);
     var context = collection.contextFor(testPath) as DriverBasedAnalysisContext;
 
     _driver = context.driver;
diff --git a/pkg/nnbd_migration/test/abstract_single_unit.dart b/pkg/nnbd_migration/test/abstract_single_unit.dart
index 75a42a9..6c62f9e 100644
--- a/pkg/nnbd_migration/test/abstract_single_unit.dart
+++ b/pkg/nnbd_migration/test/abstract_single_unit.dart
@@ -65,7 +65,7 @@
 
   @override
   void setUp() {
-    var testRoot = '/home/test';
+    var testRoot = AbstractContextTest.testsPath;
     if (analyzeWithNnbd) {
       newFile(convertPath('$testRoot/analysis_options.yaml'), content: '''
 analyzer:
@@ -75,6 +75,6 @@
     }
     super.setUp();
     testFile = convertPath('$testRoot/lib/test.dart');
-    testUri = Uri.parse('package:test/test.dart');
+    testUri = Uri.parse('package:tests/test.dart');
   }
 }
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index dd1dc53..c13e7a8 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -41,7 +41,8 @@
   Future<void> _checkMultipleFileChanges(
       Map<String, String> input, Map<String, String> expectedOutput,
       {Map<String, String> migratedInput = const {},
-      bool removeViaComments = false}) async {
+      bool removeViaComments = false,
+      bool warnOnWeakCode = false}) async {
     for (var path in migratedInput.keys) {
       driver.getFileSync(newFile(path, content: migratedInput[path]).path);
     }
@@ -50,7 +51,9 @@
     }
     var listener = new TestMigrationListener();
     var migration = NullabilityMigration(listener,
-        permissive: _usePermissiveMode, removeViaComments: removeViaComments);
+        permissive: _usePermissiveMode,
+        removeViaComments: removeViaComments,
+        warnOnWeakCode: warnOnWeakCode);
     for (var path in input.keys) {
       if (!(await session.getFile(path)).isPart) {
         for (var unit in (await session.getResolvedLibrary(path)).units) {
@@ -96,11 +99,14 @@
   /// be removed in its entirety (the default) or removed by commenting it out.
   Future<void> _checkSingleFileChanges(String content, String expected,
       {Map<String, String> migratedInput = const {},
-      bool removeViaComments = false}) async {
+      bool removeViaComments = false,
+      bool warnOnWeakCode = false}) async {
     var sourcePath = convertPath('/home/test/lib/test.dart');
     await _checkMultipleFileChanges(
         {sourcePath: content}, {sourcePath: expected},
-        migratedInput: migratedInput, removeViaComments: removeViaComments);
+        migratedInput: migratedInput,
+        removeViaComments: removeViaComments,
+        warnOnWeakCode: warnOnWeakCode);
   }
 }
 
@@ -224,7 +230,7 @@
 }
 ''';
     var expected = '''
-class C<T extends num?/*?*/> {}
+class C<T extends num?> {}
 
 void main() {
   C<num> c = C();
@@ -233,6 +239,32 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_argumentError_checkNotNull_implies_non_null_intent() async {
+    var content = '''
+void f(int i) {
+  ArgumentError.checkNotNull(i);
+}
+void g(bool b, int i) {
+  if (b) f(i);
+}
+main() {
+  g(false, null);
+}
+''';
+    var expected = '''
+void f(int i) {
+  ArgumentError.checkNotNull(i);
+}
+void g(bool b, int? i) {
+  if (b) f(i!);
+}
+main() {
+  g(false, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_as_allows_null() async {
     var content = '''
 int f(Object o) => (o as int)?.gcd(1);
@@ -263,6 +295,36 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_assignment_to_promoted_var_can_undo_promotion() async {
+    var content = '''
+abstract class C {
+  void test() {
+    var x = f();
+    while (x != null) {
+      x = f();
+    }
+  }
+  int/*?*/ f();
+}
+''';
+    var expected = '''
+abstract class C {
+  void test() {
+    var x = f();
+    while (x != null) {
+      x = f();
+    }
+  }
+  int? f();
+}
+''';
+    // Prior to the fix for https://github.com/dart-lang/sdk/issues/41411,
+    // migration would consider the LHS of `x = f()` to have context type
+    // non-nullable `int`, so it would add a null check to the value returned
+    // from `f`.
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void>
       test_back_propagation_stops_at_implicitly_typed_variables() async {
     var content = '''
@@ -306,7 +368,7 @@
 }
 ''';
     var expected = '''
-class B<E> implements List<E?/*?*/> {
+class B<E> implements List<E?> {
   final C c;
   B(this.c);
   B<T> cast<T>() => c._castFrom<E, T>(this);
@@ -436,6 +498,53 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_code_inside_switch_does_not_imply_non_null_intent() async {
+    var content = '''
+int f(int i, int j) {
+  switch (i) {
+    case 0:
+      return j + 1;
+    default:
+      return 0;
+  }
+}
+int g(int i, int j) {
+  if (i == 0) {
+    return f(i, j);
+  } else {
+    return 0;
+  }
+}
+main() {
+  g(0, null);
+}
+''';
+    var expected = '''
+int f(int i, int? j) {
+  switch (i) {
+    case 0:
+      return j! + 1;
+    default:
+      return 0;
+  }
+}
+int g(int i, int? j) {
+  if (i == 0) {
+    return f(i, j);
+  } else {
+    return 0;
+  }
+}
+main() {
+  g(0, null);
+}
+''';
+    // Note: prior to the fix for https://github.com/dart-lang/sdk/issues/41407,
+    // we would consider the use of `j` in `f` to establish non-null intent, so
+    // the null check would be erroneously placed in `g`'s call to `f`.
+    await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+  }
+
   Future<void> test_comment_bang_implies_non_null_intent() async {
     var content = '''
 void f(int/*!*/ i) {}
@@ -447,7 +556,7 @@
 }
 ''';
     var expected = '''
-void f(int/*!*/ i) {}
+void f(int i) {}
 void g(bool b, int? i) {
   if (b) f(i!);
 }
@@ -466,7 +575,7 @@
 ''';
     var expected = '''
 void _f() {
-  int?/*?*/ i = 0;
+  int? i = 0;
 }
 ''';
     await _checkSingleFileChanges(content, expected);
@@ -528,6 +637,32 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_conditional_expression_guard_subexpression() async {
+    var content = '''
+void f(String s, int x) {
+  s == null ? (x = null) : (x = s.length);
+}
+''';
+    var expected = '''
+void f(String s, int x) {
+  s == null ? (x = null!) : (x = s.length);
+}
+''';
+    await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+  }
+
+  Future<void> test_conditional_expression_guard_value_ifFalse() async {
+    var content = 'int f(String s) => s != null ? s.length : null;';
+    var expected = 'int f(String s) => s != null ? s.length : null!;';
+    await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+  }
+
+  Future<void> test_conditional_expression_guard_value_ifTrue() async {
+    var content = 'int f(String s) => s == null ? null : s.length;';
+    var expected = 'int f(String s) => s == null ? null! : s.length;';
+    await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+  }
+
   Future<void>
       test_conditional_non_null_usage_does_not_imply_non_null_intent() async {
     var content = '''
@@ -609,8 +744,8 @@
 num f4<T extends num>(bool b, num x, T y) => b ? x : y;
 
 void main() {
-  int? x1 = f1<int?/*?*/>(true, 0, null) as int?;
-  int? x2 = f2<int/*!*/>(true, 0, null) as int?;
+  int? x1 = f1<int?>(true, 0, null) as int?;
+  int? x2 = f2<int>(true, 0, null) as int?;
   int? x3 = f3<int>(true, null, 0) as int?;
   int x4 = f4<int>(true, 0, 0) as int;
 }
@@ -798,7 +933,7 @@
 ''';
     var expected = '''
 class C {
-  int?/*?*/ f = 0;
+  int? f = 0;
 }
 int? f(C c) => c.f;
 ''';
@@ -928,7 +1063,7 @@
 abstract class C<T> {
   T getValue();
 }
-int? f(C<int?/*?*/> x) => x.getValue();
+int? f(C<int?> x) => x.getValue();
 ''';
     await _checkSingleFileChanges(content, expected);
   }
@@ -1245,7 +1380,7 @@
     // Note: https://github.com/dart-lang/sdk/issues/40471 tracks the fact that
     // we ought to alert the user to the presence of such casts.
     var expected = '''
-void f(int/*!*/ Function(int?) callback) {
+void f(int Function(int?) callback) {
   callback(null);
 }
 int? g(int? x) => x;
@@ -1332,16 +1467,14 @@
   nullNonNull = hardToNullNonNull
 }
 ''';
-
-    // TODO(paulberry): remove the /*!*/, /*?*/ comments on migration.
     var expected = '''
 void f(dynamic a) {
   List<int> hardToNonNullNonNull = a;
   List<int?> hardToNullNonNull = a;
   List<int>? hardToNonNullNull = a;
-  List<int/*!*/>/*!*/ nonNullNonNull;
-  List<int/*?*/>/*!*/ nullNonNull;
-  List<int/*!*/>/*?*/ nonNullNull;
+  List<int> nonNullNonNull;
+  List<int?> nullNonNull;
+  List<int>? nonNullNull;
   nonNullNonNull = hardToNonNullNonNull
   nonNullNull = hardToNonNullNull
   nullNonNull = hardToNullNonNull
@@ -1375,10 +1508,8 @@
     var content = '''
 List<int> f(Iterable<int/*?*/> a) => a;
 ''';
-
-    // TODO(paulberry): remove the /*!*/, /*?*/ comments on migration.
     var expected = '''
-List<int?> f(Iterable<int/*?*/> a) => a;
+List<int?> f(Iterable<int?> a) => a;
 ''';
     await _checkSingleFileChanges(content, expected);
   }
@@ -1406,8 +1537,6 @@
 abstract class C<A, B> implements List<A> {}
 C<int, num> f(List<int> a) => a;
 ''';
-
-    // TODO(paulberry): remove the /*!*/, /*?*/ comments on migration.
     var expected = '''
 abstract class C<A, B> implements List<A> {}
 C<int, num?> f(List<int> a) => a;
@@ -1509,7 +1638,7 @@
 List<int> _f(List<int/*!*/> xs) => [for(var x in xs) if (x == null) 1];
 ''';
     var expected = '''
-List<int> _f(List<int/*!*/> xs) => [];
+List<int> _f(List<int> xs) => [];
 ''';
     await _checkSingleFileChanges(content, expected);
   }
@@ -1692,7 +1821,7 @@
 int f(int/*?*/ i) => i + 1;
 ''';
     var expected = '''
-int f(int?/*?*/ i) => i! + 1;
+int f(int? i) => i! + 1;
 ''';
     await _checkSingleFileChanges(content, expected);
   }
@@ -1702,7 +1831,7 @@
 int f(int/*?*/ i) => i/*!*/;
 ''';
     var expected = '''
-int f(int?/*?*/ i) => i!/*!*/;
+int f(int? i) => i!;
 ''';
     await _checkSingleFileChanges(content, expected, removeViaComments: true);
   }
@@ -1714,16 +1843,22 @@
     // The user requested a null check so we should add it even if it's not
     // required to avoid compile errors.
     var expected = '''
-int?/*?*/ f(int?/*?*/ i) => i!/*!*/;
+int? f(int? i) => i!;
 ''';
     await _checkSingleFileChanges(content, expected, removeViaComments: true);
   }
 
+  Future<void> test_expression_bang_hint_unnecessary_literal() async {
+    var content = 'int/*?*/ f() => 1/*!*/;';
+    // The user requested a null check so we should add it even if it's not
+    // required to avoid compile errors.
+    var expected = 'int? f() => 1!;';
+    await _checkSingleFileChanges(content, expected, removeViaComments: true);
+  }
+
   Future<void> test_expression_bang_hint_with_cast() async {
     var content = 'int f(Object/*?*/ o) => o/*!*/;';
-    // TODO(paulberry): it would be better to remove the `/*` and `*/` so we
-    // would be left with `o! as int;`
-    var expected = 'int f(Object?/*?*/ o) => o! as int/*!*/;';
+    var expected = 'int f(Object? o) => o! as int;';
     await _checkSingleFileChanges(content, expected);
   }
 
@@ -1819,6 +1954,30 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_field_final_uninitalized_used() async {
+    var content = '''
+class C {
+  final String s;
+
+  f() {
+    g(s);
+  }
+}
+g(String /*!*/ s) {}
+''';
+    var expected = '''
+class C {
+  late final String s;
+
+  f() {
+    g(s);
+  }
+}
+g(String s) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_field_formal_param_typed() async {
     var content = '''
 class C {
@@ -1858,7 +2017,7 @@
 ''';
     var expected = '''
 class C {
-  int/*!*/ i;
+  int i;
   C(int this.i);
 }
 void f(int? i, bool b) {
@@ -1895,6 +2054,54 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_field_formal_parameters_do_not_promote() async {
+    var content = '''
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+abstract class D {
+  final A x;
+  D(this.x) {
+    if (x is B) {
+      visitB(x);
+    } else {
+      visitC(x as C);
+    }
+  }
+
+  void visitB(B b);
+
+  void visitC(C c);
+}
+''';
+    var expected = '''
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+abstract class D {
+  final A x;
+  D(this.x) {
+    if (x is B) {
+      visitB(x as B);
+    } else {
+      visitC(x as C);
+    }
+  }
+
+  void visitB(B b);
+
+  void visitC(C c);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_field_initialized_at_declaration_site() async {
     var content = '''
 class C {
@@ -2133,6 +2340,54 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_field_uninitalized_used() async {
+    var content = '''
+class C {
+  String s;
+
+  f() {
+    g(s);
+  }
+}
+g(String /*!*/ s) {}
+''';
+    var expected = '''
+class C {
+  late String s;
+
+  f() {
+    g(s);
+  }
+}
+g(String s) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_field_uninitalized_used_hint() async {
+    var content = '''
+class C {
+  String /*?*/ s;
+
+  f() {
+    g(s);
+  }
+}
+g(String /*!*/ s) {}
+''';
+    var expected = '''
+class C {
+  String? s;
+
+  f() {
+    g(s!);
+  }
+}
+g(String s) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_flow_analysis_complex() async {
     var content = '''
 int f(int x) {
@@ -2275,7 +2530,7 @@
     var expected = '''
 abstract class C {
   void Function(int?) f();
-  int?/*?*/ Function() g();
+  int? Function() g();
 }
 int? test(C c) {
   c.f()(null);
@@ -2299,7 +2554,7 @@
     var expected = '''
 abstract class C {
   void Function(int?) get f;
-  int?/*?*/ Function() get g;
+  int? Function() get g;
 }
 int? test(C c) {
   c.f(null);
@@ -2374,9 +2629,9 @@
 import 'dart:async';
 void f(
     FutureOr<int> foi1,
-    FutureOr<int?/*?*/> foi2,
-    FutureOr<int>?/*?*/ foi3,
-    FutureOr<int?/*?*/>?/*?*/ foi4
+    FutureOr<int?> foi2,
+    FutureOr<int>? foi3,
+    FutureOr<int?>? foi4
 ) {
   int i1 = foi1 as int;
   int? i2 = foi2 as int?;
@@ -2478,7 +2733,7 @@
 ''';
     var expected = '''
 class C {
-  final Comparator<int/*!*/> comparison;
+  final Comparator<int> comparison;
   C(int Function(int, int) comparison) : comparison = comparison;
   void test() {
     comparison(f()!, f()!);
@@ -2585,7 +2840,7 @@
   final T? value;
   A(this.value);
 }
-class C implements A<String/*!*/> {
+class C implements A<String> {
   String? get value => false ? "y" : null;
 }
 ''';
@@ -2622,7 +2877,7 @@
   x.add(null);
 }
 void g() {
-  f(<int/*!*/>[]);
+  f(<int>[]);
 }
 ''';
     await _checkSingleFileChanges(content, expected);
@@ -2643,6 +2898,64 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_implicit_parameter_type_override_does_not_union() async {
+    var content = '''
+abstract class A {
+  void f(int/*?*/ i);
+}
+abstract class B {
+  void f(int i);
+}
+class C implements A, B {
+  void f(i) {}
+}
+''';
+    // Even though the parameter type of C.f is implicit, its nullability
+    // shouldn't be unioned with that of A and B, because that would
+    // unnecessarily force B.f's parameter type to be nullable.
+    var expected = '''
+abstract class A {
+  void f(int? i);
+}
+abstract class B {
+  void f(int i);
+}
+class C implements A, B {
+  void f(i) {}
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_implicit_return_type_override_does_not_union() async {
+    var content = '''
+abstract class A {
+  int/*?*/ f();
+}
+abstract class B {
+  int f();
+}
+class C implements A, B {
+  f() => 0;
+}
+''';
+    // Even though the return type of C.f is implicit, its nullability shouldn't
+    // be unioned with that of A and B, because that would unnecessarily force
+    // B.f's return type to be nullable.
+    var expected = '''
+abstract class A {
+  int? f();
+}
+abstract class B {
+  int f();
+}
+class C implements A, B {
+  f() => 0;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_implicit_type_parameter_bound_nullable() async {
     var content = '''
 class C<T> {
@@ -2686,78 +2999,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_inferred_method_parameter_type_non_nullable() async {
-    var content = '''
-class B {
-  void f(int i) {
-    assert(i != null);
-  }
-}
-class C extends B {
-  void f(i) {}
-}
-void g(C c, int i, bool b) {
-  if (b) {
-    c.f(i);
-  }
-}
-void h(C c) {
-  g(c, null, false);
-}
-''';
-    // B.f's parameter type is `int`.  Since C.f's parameter type is inferred
-    // from B.f's, it has a parameter type of `int` too.  Therefore there must
-    // be a null check in g().
-    var expected = '''
-class B {
-  void f(int i) {
-    assert(i != null);
-  }
-}
-class C extends B {
-  void f(i) {}
-}
-void g(C c, int? i, bool b) {
-  if (b) {
-    c.f(i!);
-  }
-}
-void h(C c) {
-  g(c, null, false);
-}
-''';
-    await _checkSingleFileChanges(content, expected);
-  }
-
-  Future<void> test_inferred_method_parameter_type_nullable() async {
-    var content = '''
-class B {
-  void f(int i) {}
-}
-class C extends B {
-  void f(i) {}
-}
-void g(C c) {
-  c.f(null);
-}
-''';
-    // The call to C.f from g forces C.f's parameter to be nullable.  Since
-    // C.f's parameter type is inferred from B.f's parameter type, B.f's
-    // parameter must be nullable too.
-    var expected = '''
-class B {
-  void f(int? i) {}
-}
-class C extends B {
-  void f(i) {}
-}
-void g(C c) {
-  c.f(null);
-}
-''';
-    await _checkSingleFileChanges(content, expected);
-  }
-
   Future<void> test_inferred_method_return_type_non_nullable() async {
     var content = '''
 class B {
@@ -2783,31 +3024,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_inferred_method_return_type_nullable() async {
-    var content = '''
-class B {
-  int f() => null;
-}
-class C extends B {
-  f() => 1;
-}
-int g(C c) => c.f();
-''';
-    // B.f's return type is `int?`.  Since C.f's return type is inferred from
-    // B.f's, it has a return type of `int?` too.  Therefore g's return type
-    // must be `int?`.
-    var expected = '''
-class B {
-  int? f() => null;
-}
-class C extends B {
-  f() => 1;
-}
-int? g(C c) => c.f();
-''';
-    await _checkSingleFileChanges(content, expected);
-  }
-
   Future<void> test_insert_as_prefixed_type() async {
     var content = '''
 import 'dart:async' as a;
@@ -2891,8 +3107,8 @@
 }
 ''';
     var expected = '''
-class C<T extends Object/*!*/> {
-  C(T/*!*/ t);
+class C<T extends Object> {
+  C(T t);
 }
 main() {
   C<int> c = C<int>(null!);
@@ -2913,7 +3129,7 @@
 ''';
     var expected = '''
 class C<T> {
-  C(T/*!*/ t);
+  C(T t);
 }
 main() {
   C<int?> c = C<int?>(null);
@@ -2932,8 +3148,8 @@
 }
 ''';
     var expected = '''
-class C<T extends Object/*!*/> {
-  C(T/*!*/ t);
+class C<T extends Object> {
+  C(T t);
 }
 main() {
   C<int> c = C(null!);
@@ -2954,7 +3170,7 @@
 ''';
     var expected = '''
 class C<T> {
-  C(T/*!*/ t);
+  C(T t);
 }
 main() {
   C<int?> c = C(null);
@@ -3072,12 +3288,10 @@
   int g() => x;
 }
 ''';
-    // TODO(paulberry): it would be better to just replace the comment with the
-    // word `late`.
     var expected = '''
 class C {
   C();
-  /*late*/ late int x;
+  late int x;
   f() {
     x = 1;
   }
@@ -3097,11 +3311,9 @@
   int g() => x;
 }
 ''';
-    // TODO(paulberry): it would be better to just replace the comment with the
-    // word `late`.
     var expected = '''
 class C {
-  /*late*/ late int x;
+  late int x;
   f() {
     x = 1;
   }
@@ -3124,11 +3336,9 @@
   return 0;
 }
 ''';
-    // TODO(paulberry): it would be better to just replace the comment with the
-    // word `late`.
     var expected = '''
 int f(bool b1, bool b2) {
-  /*late*/ late int x;
+  late int x;
   if (b1) {
     x = 1;
   }
@@ -3151,11 +3361,9 @@
   int g() => x;
 }
 ''';
-    // TODO(paulberry): it would be better to just replace the comment with the
-    // word `late`.
     var expected = '''
 class C {
-  static /*late*/ late int x;
+  static late int x;
   f() {
     x = 1;
   }
@@ -3173,10 +3381,8 @@
 }
 int g() => x;
 ''';
-    // TODO(paulberry): it would be better to just replace the comment with the
-    // word `late`.
     var expected = '''
-/*late*/ late int x;
+late int x;
 f() {
   x = 1;
 }
@@ -3309,14 +3515,14 @@
 ''';
     var expected = '''
 int f() {
-  int? i;
+  late int i;
   g(int j) {
     i = 1;
   };
   ((int j) {
     i = 1;
   });
-  return i! + 1;
+  return i + 1;
 }
 ''';
     await _checkSingleFileChanges(content, expected);
@@ -3342,6 +3548,113 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_localVariable_uninitalized_assigned_non_nullable() async {
+    var content = '''
+f() {
+  String s;
+  if (1 == 2) s = g();
+  h(s);
+}
+String /*!*/ g() => "Hello";
+h(String /*!*/ s) {}
+''';
+    var expected = '''
+f() {
+  late String s;
+  if (1 == 2) s = g();
+  h(s);
+}
+String g() => "Hello";
+h(String s) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_localVariable_uninitalized_used() async {
+    var content = '''
+f() {
+  String s;
+  if (1 == 2) s = "Hello";
+  g(s);
+}
+g(String /*!*/ s) {}
+''';
+    var expected = '''
+f() {
+  late String s;
+  if (1 == 2) s = "Hello";
+  g(s);
+}
+g(String s) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_localVariable_uninitalized_usedInComparison() async {
+    var content = '''
+f() {
+  String s;
+  if (s == null) {}
+}
+''';
+    var expected = '''
+f() {
+  String? s;
+  if (s == null) {}
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void>
+      test_localVariable_uninitalized_usedInExpressionStatement() async {
+    var content = '''
+f() {
+  String s;
+  s;
+}
+''';
+    var expected = '''
+f() {
+  String? s;
+  s;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_localVariable_uninitalized_usedInForUpdaters() async {
+    var content = '''
+f() {
+  String s;
+  for (s;;) {}
+}
+''';
+    var expected = '''
+f() {
+  String? s;
+  for (s;;) {}
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_localVariable_uninitalized_usedInForVariable() async {
+    var content = '''
+f() {
+  String s;
+  for (;; s) {}
+}
+''';
+    var expected = '''
+f() {
+  String? s;
+  for (;; s) {}
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_make_downcast_explicit() async {
     var content = 'int f(num n) => n;';
     var expected = 'int f(num n) => n as int;';
@@ -3427,7 +3740,7 @@
 }
 ''';
     var expected = '''
-T f<T extends Object/*!*/>(T/*!*/ t) => t;
+T f<T extends Object>(T t) => t;
 void g() {
   int x = f<int>(null!);
 }
@@ -3444,7 +3757,7 @@
 }
 ''';
     var expected = '''
-T f<T>(T/*!*/ t) => t;
+T f<T>(T t) => t;
 void g() {
   int? x = f<int?>(null);
 }
@@ -3477,7 +3790,7 @@
 }
 ''';
     var expected = '''
-T f<T extends Object/*!*/>(T/*!*/ t) => t;
+T f<T extends Object>(T t) => t;
 void g() {
   int x = f(null!);
 }
@@ -3494,7 +3807,7 @@
 }
 ''';
     var expected = '''
-T f<T>(T/*!*/ t) => t;
+T f<T>(T t) => t;
 void g() {
   int? x = f(null);
 }
@@ -3812,10 +4125,10 @@
 ''';
     var expected = '''
 abstract class C {
-  void f(List<int/*!*/> x, int y) {
+  void f(List<int> x, int y) {
     x.add(y);
   }
-  int?/*?*/ g();
+  int? g();
   void test() {
     f(<int>[], g()!);
   }
@@ -3837,7 +4150,7 @@
     // safely passed to f.
     var expected = '''
 Iterable<int> f(List<int?> x) => x.map(g as int Function(int?));
-int g(int/*!*/ x) => x + 1;
+int g(int x) => x + 1;
 main() {
   f([null]);
 }
@@ -3957,8 +4270,8 @@
 class _C {
   f() {}
 }
-_C g(int/*!*/ i) => _C();
-test(int?/*?*/ j) {
+_C g(int i) => _C();
+test(int? j) {
   g(j!)..f();
 }
 ''';
@@ -3974,7 +4287,7 @@
 }
 ''';
     var expected = '''
-abstract class C<E, T extends Iterable<E>?/*?*/> {
+abstract class C<E, T extends Iterable<E>?> {
   void f(T iter) {
     for(var i in iter!) {}
   }
@@ -4133,7 +4446,7 @@
 ''';
     var expected = '''
 abstract class Base {
-  int/*!*/ f();
+  int f();
 }
 class Derived extends Base {
   int f() => g()!;
@@ -4284,7 +4597,7 @@
   D<T> operator-();
 }
 class D<U> {}
-D<int?> test(C<int?/*?*/> c) => -c;
+D<int?> test(C<int?> c) => -c;
 ''';
     await _checkSingleFileChanges(content, expected);
   }
@@ -4355,7 +4668,7 @@
     // `x ??= [0]` promotes x from List<int?>? to List<int?>.  Since there is
     // still a `?` on the `int`, `x[0]` must be null checked.
     var expected = '''
-int/*!*/ f(List<int?/*?*/>?/*?*/ x) {
+int f(List<int?>? x) {
   x ??= [0];
   return x[0]!;
 }
@@ -4378,7 +4691,7 @@
     // return type of the function literal.  As a result, the reference to `x`
     // in the function literal is null checked.
     var expected = '''
-void f(int/*!*/ Function(int?) callback) {
+void f(int Function(int?) callback) {
   callback(null);
 }
 void test() {
@@ -4414,6 +4727,35 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_quiver_checkNotNull_implies_non_null_intent() async {
+    addQuiverPackage();
+    var content = '''
+import 'package:quiver/check.dart';
+void f(int i) {
+  checkNotNull(i);
+}
+void g(bool b, int i) {
+  if (b) f(i);
+}
+main() {
+  g(false, null);
+}
+''';
+    var expected = '''
+import 'package:quiver/check.dart';
+void f(int i) {
+  checkNotNull(i);
+}
+void g(bool b, int? i) {
+  if (b) f(i!);
+}
+main() {
+  g(false, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_redirecting_constructor_factory() async {
     var content = '''
 class C {
@@ -4530,7 +4872,7 @@
 
   Future<void> test_remove_question_from_question_dot() async {
     var content = '_f(int/*!*/ i) => i?.isEven;';
-    var expected = '_f(int/*!*/ i) => i.isEven;';
+    var expected = '_f(int i) => i.isEven;';
     await _checkSingleFileChanges(content, expected);
   }
 
@@ -4543,16 +4885,16 @@
 ''';
     var expected = '''
 class C {
-  int?/*?*/ i;
+  int? i;
 }
-int/*!*/ f(C/*!*/ c) => c.i!;
+int f(C c) => c.i!;
 ''';
     await _checkSingleFileChanges(content, expected);
   }
 
   Future<void> test_remove_question_from_question_dot_method() async {
     var content = '_f(int/*!*/ i) => i?.abs();';
-    var expected = '_f(int/*!*/ i) => i.abs();';
+    var expected = '_f(int i) => i.abs();';
     await _checkSingleFileChanges(content, expected);
   }
 
@@ -4565,9 +4907,9 @@
 ''';
     var expected = '''
 class C {
-  int/*!*/ i;
+  int i;
 }
-bool?/*?*/ f(C?/*?*/ c) => c?.i.isEven;
+bool? f(C? c) => c?.i.isEven;
 ''';
     await _checkSingleFileChanges(content, expected);
   }
@@ -4721,6 +5063,118 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_testVariable_assignedNullableValue() async {
+    addTestCorePackage();
+    var content = '''
+import 'package:test/test.dart';
+void main() {
+  int i;
+  setUp(() {
+    i = null;
+  });
+  test('a', () {
+    i.isEven;
+  });
+}
+''';
+    var expected = '''
+import 'package:test/test.dart';
+void main() {
+  int? i;
+  setUp(() {
+    i = null;
+  });
+  test('a', () {
+    i!.isEven;
+  });
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_testVariable_downstreamAllNonNull() async {
+    addTestCorePackage();
+    var content = '''
+import 'package:test/test.dart';
+void main() {
+  int i;
+  setUp(() {
+    i = 1;
+  });
+  test('a', () {
+    i.isEven;
+  });
+}
+''';
+    var expected = '''
+import 'package:test/test.dart';
+void main() {
+  late int i;
+  setUp(() {
+    i = 1;
+  });
+  test('a', () {
+    i.isEven;
+  });
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_testVariable_hasInitializer() async {
+    addTestCorePackage();
+    var content = '''
+import 'package:test/test.dart';
+void main() {
+  int i = 1;
+  setUp(() {
+    i = 1;
+  });
+}
+''';
+    var expected = '''
+import 'package:test/test.dart';
+void main() {
+  int i = 1;
+  setUp(() {
+    i = 1;
+  });
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_testVariable_usedAsNullable() async {
+    addTestCorePackage();
+    var content = '''
+import 'package:test/test.dart';
+void main() {
+  int i;
+  setUp(() {
+    i = 1;
+  });
+  test('a', () {
+    f(i);
+  });
+  f(int /*?*/ i) {}
+}
+''';
+    var expected = '''
+import 'package:test/test.dart';
+void main() {
+  late int i;
+  setUp(() {
+    i = 1;
+  });
+  test('a', () {
+    f(i);
+  });
+  f(int? i) {}
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_topLevelFunction_parameterType_implicit_dynamic() async {
     var content = '''
 Object f(x) => x;
@@ -4767,6 +5221,24 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_topLevelVariable_uninitalized_used() async {
+    var content = '''
+String s;
+f() {
+  g(s);
+}
+g(String /*!*/ s) {}
+''';
+    var expected = '''
+late String s;
+f() {
+  g(s);
+}
+g(String s) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_two_files() async {
     var root = '/home/test/lib';
     var path1 = convertPath('$root/file1.dart');
@@ -4941,7 +5413,7 @@
     var expected = '''
 typedef F = Function(int?);
 
-F/*!*/ _f;
+F _f;
 
 f() {
   _f(null);
@@ -5006,7 +5478,7 @@
     var expected = '''
 typedef F = Function<T>(T);
 
-F/*!*/ _f;
+F _f;
 
 f() {
   _f<int?>(null);
@@ -5028,7 +5500,7 @@
     var expected = '''
 typedef F<R> = Function<T>(T);
 
-F<Object>/*!*/ _f;
+F<Object> _f;
 
 f() {
   _f<int?>(null);
@@ -5050,7 +5522,7 @@
     var expected = '''
 typedef F<T> = Function(T);
 
-F<int?>/*!*/ _f;
+F<int?> _f;
 
 f() {
   _f(null);
@@ -5072,7 +5544,7 @@
     var expected = '''
 typedef F<T> = Function(T);
 
-F<int?>/*!*/ _f;
+F<int?> _f;
 
 f() {
   _f(null);
@@ -5108,7 +5580,7 @@
     var expected = '''
 typedef F(int? x);
 
-F/*!*/ _f;
+F _f;
 
 f() {
   _f(null);
@@ -5158,7 +5630,7 @@
     var expected = '''
 typedef F<T>(T t);
 
-F<int?>/*!*/ _f;
+F<int?> _f;
 
 f() {
   _f(null);
@@ -5180,7 +5652,7 @@
     var expected = '''
 typedef F<T>(T t);
 
-F<int?>/*!*/ _f;
+F<int?> _f;
 
 f() {
   _f(null);
@@ -5609,6 +6081,28 @@
 ''';
     await _checkSingleFileChanges(content, expected);
   }
+
+  Future<void> test_weak_if_visit_weak_subexpression() async {
+    var content = '''
+int f(int x, int/*?*/ y) {
+  if (x == null) {
+    print(y.toDouble());
+  } else {
+    print(y.toDouble());
+  }
+}
+''';
+    var expected = '''
+int f(int x, int? y) {
+  if (x == null) {
+    print(y!.toDouble());
+  } else {
+    print(y!.toDouble());
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart b/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
index 1aff883..46a5782 100644
--- a/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
@@ -430,19 +430,19 @@
 
   Future<void> test_conditionalExpression() async {
     await analyze('''
-int f(int i) => i == null ? g(i) : h(i);
+int f(int i, int l) => i == null ? g(l) : h(i);
 int g(int j) => 1;
 int h(int k) => 1;
 ''');
     var iNode = decoratedTypeAnnotation('int i').node;
     var jNode = decoratedTypeAnnotation('int j').node;
     var kNode = decoratedTypeAnnotation('int k').node;
+    var lNode = decoratedTypeAnnotation('int l').node;
     // No edge from i to k because i is known to be non-nullable at the site of
     // the call to h()
     assertNoEdge(iNode, kNode);
-    // But there is an edge from i to j
-    // TODO(paulberry): there should be a guard on this edge.
-    assertEdge(iNode, jNode, hard: false);
+    // But there is an edge from l to j
+    assertEdge(lNode, jNode, hard: false, guards: [iNode]);
   }
 
   Future<void> test_conditionalExpression_propagates_promotions() async {
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index b529b8c..145e37b 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -9,9 +9,12 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/error/hint_codes.dart';
-import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
@@ -36,6 +39,8 @@
     with EdgeTester, DecoratedTypeTester {
   static const EdgeOrigin origin = const _TestEdgeOrigin();
 
+  LibraryElementImpl _myLibrary;
+
   ClassElement _myListOfListClass;
 
   DecoratedType _myListOfListSupertype;
@@ -53,6 +58,8 @@
 
   factory AssignmentCheckerTest() {
     var typeProvider = TestTypeProvider();
+    _setCoreLibrariesTypeSystem(typeProvider);
+
     var graph = NullabilityGraphForTesting();
     var decoratedClassHierarchy = _DecoratedClassHierarchyForTesting();
     var checker = AssignmentCheckerForTesting(
@@ -80,10 +87,12 @@
   }
 
   DecoratedType myListOfList(DecoratedType elementType) {
+    _initMyLibrary();
     if (_myListOfListClass == null) {
       var t = typeParameter('T', object());
       _myListOfListSupertype = list(list(typeParameterType(t)));
       _myListOfListClass = ClassElementImpl('MyListOfList', 0)
+        ..enclosingElement = _myLibrary.definingCompilationUnit
         ..typeParameters = [t]
         ..supertype = _myListOfListSupertype.type as InterfaceType;
     }
@@ -438,6 +447,63 @@
     checker.bounds[t] = bound;
     return t;
   }
+
+  void _initMyLibrary() {
+    if (_myLibrary != null) {
+      return;
+    }
+
+    var coreLibrary = typeProvider.boolElement.library as LibraryElementImpl;
+    var analysisContext = coreLibrary.context;
+    var analysisSession = coreLibrary.session;
+    var typeSystem = coreLibrary.typeSystem;
+
+    var uriStr = 'package:test/test.dart';
+
+    _myLibrary = LibraryElementImpl(analysisContext, analysisSession, uriStr,
+        -1, 0, typeSystem.isNonNullableByDefault);
+    _myLibrary.typeSystem = typeSystem;
+    _myLibrary.typeProvider = coreLibrary.typeProvider;
+
+    var uri = Uri.parse(uriStr);
+    var source = _MockSource(uri);
+
+    var definingUnit = CompilationUnitElementImpl();
+    definingUnit.source = source;
+    definingUnit.librarySource = source;
+
+    definingUnit.enclosingElement = _myLibrary;
+    _myLibrary.definingCompilationUnit = definingUnit;
+  }
+
+  static void _setCoreLibrariesTypeSystem(TestTypeProvider typeProvider) {
+    var typeSystem = TypeSystemImpl(
+      isNonNullableByDefault: false,
+      implicitCasts: true,
+      strictInference: false,
+      typeProvider: typeProvider,
+    );
+    _setLibraryTypeSystem(
+      typeProvider.objectElement.library,
+      typeProvider,
+      typeSystem,
+    );
+    _setLibraryTypeSystem(
+      typeProvider.futureElement.library,
+      typeProvider,
+      typeSystem,
+    );
+  }
+
+  static void _setLibraryTypeSystem(
+    LibraryElement libraryElement,
+    TypeProvider typeProvider,
+    TypeSystem typeSystem,
+  ) {
+    var libraryElementImpl = libraryElement as LibraryElementImpl;
+    libraryElementImpl.typeProvider = typeProvider as TypeProviderImpl;
+    libraryElementImpl.typeSystem = typeSystem as TypeSystemImpl;
+  }
 }
 
 @reflectiveTest
@@ -482,7 +548,7 @@
   /// needed.
   void assertNullCheck(
       ExpressionChecksOrigin expressionChecks, NullabilityEdge expectedEdge) {
-    expect(expressionChecks.checks.edges, contains(expectedEdge));
+    expect(expressionChecks.checks.edges.values, contains(expectedEdge));
   }
 
   /// Gets the [ExpressionChecks] associated with the expression whose text
@@ -500,7 +566,7 @@
   }
 
   bool hasNullCheckHint(Expression expression) =>
-      variables.hasNullCheckHint(testSource, expression);
+      variables.getNullCheckHint(testSource, expression) != null;
 
   Future<void> test_already_migrated_field() async {
     await analyze('''
@@ -512,6 +578,42 @@
         hard: false);
   }
 
+  Future<void> test_ArgumentError_checkNotNull_not_postDominating() async {
+    await analyze('''
+void f(bool b, int i, int j) {
+  ArgumentError.checkNotNull(j);
+  if (b) return;
+  ArgumentError.checkNotNull(i);
+}
+''');
+
+    // Asserts after ifs don't demonstrate non-null intent.
+    assertNoEdge(decoratedTypeAnnotation('int i').node, never);
+    // But asserts before ifs do
+    assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true);
+  }
+
+  Future<void> test_ArgumentError_checkNotNull_postDominating() async {
+    await analyze('''
+void f(int i) {
+  ArgumentError.checkNotNull(i);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+  }
+
+  Future<void> test_ArgumentError_checkNotNull_prefixed() async {
+    await analyze('''
+import 'dart:core' as core;
+void f(core.int i) {
+  core.ArgumentError.checkNotNull(i);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+  }
+
   Future<void> test_as_dynamic() async {
     await analyze('''
 void f(Object o) {
@@ -2000,6 +2102,19 @@
     assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
   }
 
+  Future<void> test_conditionalExpression_false_guard() async {
+    await analyze('int f(int x, int y, int z) => x != null ? null : y = z;');
+    var guard = decoratedTypeAnnotation('int x').node;
+    assertEdge(decoratedTypeAnnotation('int z').node,
+        decoratedTypeAnnotation('int y').node,
+        hard: false, guards: [guard]);
+    var conditionalDiscard =
+        variables.conditionalDiscard(findNode.conditionalExpression('!='));
+    expect(conditionalDiscard, isNotNull);
+    expect(conditionalDiscard.trueGuard, isNull);
+    expect(conditionalDiscard.falseGuard, same(guard));
+  }
+
   Future<void> test_conditionalExpression_functionTyped_namedParameter() async {
     await analyze('''
 void f(bool b, void Function({int p}) x, void Function({int p}) y) {
@@ -2389,6 +2504,19 @@
     assertLUB(nullable_conditional, nullable_t, inSet(alwaysPlus));
   }
 
+  Future<void> test_conditionalExpression_true_guard() async {
+    await analyze('int f(int x, int y, int z) => x == null ? y = z : null;');
+    var guard = decoratedTypeAnnotation('int x').node;
+    assertEdge(decoratedTypeAnnotation('int z').node,
+        decoratedTypeAnnotation('int y').node,
+        hard: false, guards: [guard]);
+    var conditionalDiscard =
+        variables.conditionalDiscard(findNode.conditionalExpression('=='));
+    expect(conditionalDiscard, isNotNull);
+    expect(conditionalDiscard.trueGuard, same(guard));
+    expect(conditionalDiscard.falseGuard, isNull);
+  }
+
   Future<void> test_conditionalExpression_typeParameter_bound() async {
     await analyze('''
 num f<T extends num>(bool b, num x, T y) {
@@ -2661,6 +2789,64 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
   }
 
+  Future<void> test_dummyNode_fromEqualityComparison_left() async {
+    await analyze('''
+f() {
+  int i;
+  if (i == 7) {}
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    assertDummyEdge(nullable_i);
+  }
+
+  Future<void> test_dummyNode_fromEqualityComparison_right() async {
+    await analyze('''
+f() {
+  int i;
+  if (7 == i) {}
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    assertDummyEdge(nullable_i);
+  }
+
+  Future<void> test_dummyNode_fromExpressionStatement() async {
+    await analyze('''
+f() {
+  int i;
+  i;
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    assertDummyEdge(nullable_i);
+  }
+
+  Future<void> test_dummyNode_fromForLoopUpdaters() async {
+    await analyze('''
+f() {
+  int i;
+  int j;
+  for (;; i, j) {}
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    assertDummyEdge(nullable_i);
+    assertDummyEdge(nullable_j);
+  }
+
+  Future<void> test_dummyNode_fromForLoopVariables() async {
+    await analyze('''
+f() {
+  int i;
+  for (i;;) {}
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    assertDummyEdge(nullable_i);
+  }
+
   Future<void> test_edgeOrigin_call_from_function() async {
     await analyze('''
 void f(int i) {}
@@ -3292,7 +3478,7 @@
   f();
 }
 ''');
-    var optional_i = possiblyOptionalParameter('int i');
+    var optional_i = decoratedTypeAnnotation('int i').node;
     expect(getEdges(always, optional_i), isNotEmpty);
   }
 
@@ -3308,8 +3494,6 @@
 }
 ''');
     // The call at `f()` is presumed to be in error; no constraint is recorded.
-    var optional_i = possiblyOptionalParameter('int i');
-    expect(optional_i, isNull);
     var nullable_i = decoratedTypeAnnotation('int i').node;
     assertNoUpstreamNullability(nullable_i);
   }
@@ -3902,8 +4086,8 @@
     var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
     var nullable_t = decoratedTypeAnnotation('T t').node;
     var check_i = checkExpression('i/*check*/');
-    var nullable_c_t_or_nullable_t = check_i.checks.edges.single.destinationNode
-        as NullabilityNodeForSubstitution;
+    var nullable_c_t_or_nullable_t = check_i.checks.edges[FixReasonTarget.root]
+        .destinationNode as NullabilityNodeForSubstitution;
     expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
     expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
     assertNullCheck(check_i,
@@ -3921,8 +4105,8 @@
     var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
     var nullable_t = decoratedTypeAnnotation('T t').node;
     var check_i = checkExpression('i/*check*/');
-    var nullable_c_t_or_nullable_t = check_i.checks.edges.single.destinationNode
-        as NullabilityNodeForSubstitution;
+    var nullable_c_t_or_nullable_t = check_i.checks.edges[FixReasonTarget.root]
+        .destinationNode as NullabilityNodeForSubstitution;
     expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
     expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
     assertNullCheck(check_i,
@@ -4279,7 +4463,7 @@
 ''');
     var bReturnType = decoratedMethodType('f/*B*/').positionalParameters[0];
     var cReturnType = decoratedMethodType('f/*C*/').positionalParameters[0];
-    assertUnion(bReturnType.node, cReturnType.node);
+    assertEdge(bReturnType.node, cReturnType.node, hard: true);
   }
 
   Future<void> test_method_parameterType_inferred_named() async {
@@ -4293,7 +4477,7 @@
 ''');
     var bReturnType = decoratedMethodType('f/*B*/').namedParameters['x'];
     var cReturnType = decoratedMethodType('f/*C*/').namedParameters['x'];
-    assertUnion(bReturnType.node, cReturnType.node);
+    assertEdge(bReturnType.node, cReturnType.node, hard: true);
   }
 
   Future<void> test_method_returnType_inferred() async {
@@ -4307,7 +4491,7 @@
 ''');
     var bReturnType = decoratedMethodType('f/*B*/').returnType;
     var cReturnType = decoratedMethodType('f/*C*/').returnType;
-    assertUnion(bReturnType.node, cReturnType.node);
+    assertEdge(cReturnType.node, bReturnType.node, hard: true);
   }
 
   Future<void>
@@ -4624,8 +4808,8 @@
     var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
     var nullable_t = decoratedTypeAnnotation('T t').node;
     var check_i = checkExpression('i/*check*/');
-    var nullable_c_t_or_nullable_t = check_i.checks.edges.single.destinationNode
-        as NullabilityNodeForSubstitution;
+    var nullable_c_t_or_nullable_t = check_i.checks.edges[FixReasonTarget.root]
+        .destinationNode as NullabilityNodeForSubstitution;
     expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
     expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
     assertNullCheck(check_i,
@@ -4651,7 +4835,9 @@
     assertEdge(nullable_t, never, hard: true, checkable: false);
     var check_i = checkExpression('i/*check*/');
     var nullable_list_t_or_nullable_t = check_i
-        .checks.edges.single.destinationNode as NullabilityNodeForSubstitution;
+        .checks
+        .edges[FixReasonTarget.root]
+        .destinationNode as NullabilityNodeForSubstitution;
     expect(nullable_list_t_or_nullable_t.innerNode, same(nullable_list_t));
     expect(nullable_list_t_or_nullable_t.outerNode, same(nullable_t));
     assertNullCheck(check_i,
@@ -4669,8 +4855,8 @@
     var nullable_f_t = decoratedTypeAnnotation('int>').node;
     var nullable_t = decoratedTypeAnnotation('T t').node;
     var check_i = checkExpression('i/*check*/');
-    var nullable_f_t_or_nullable_t = check_i.checks.edges.single.destinationNode
-        as NullabilityNodeForSubstitution;
+    var nullable_f_t_or_nullable_t = check_i.checks.edges[FixReasonTarget.root]
+        .destinationNode as NullabilityNodeForSubstitution;
     expect(nullable_f_t_or_nullable_t.innerNode, same(nullable_f_t));
     expect(nullable_f_t_or_nullable_t.outerNode, same(nullable_t));
     assertNullCheck(check_i,
@@ -4784,8 +4970,8 @@
     var check_i = checkExpression('(f<int>(1))');
     var t_bound = decoratedTypeAnnotation('Object').node;
     var nullable_f_t = decoratedTypeAnnotation('int>').node;
-    var nullable_f_t_or_nullable_t = check_i.checks.edges.single.sourceNode
-        as NullabilityNodeForSubstitution;
+    var nullable_f_t_or_nullable_t = check_i.checks.edges[FixReasonTarget.root]
+        .sourceNode as NullabilityNodeForSubstitution;
     var nullable_t = decoratedTypeAnnotation('T f').node;
     expect(nullable_f_t_or_nullable_t.innerNode, same(nullable_f_t));
     expect(nullable_f_t_or_nullable_t.outerNode, same(nullable_t));
@@ -6322,6 +6508,47 @@
         assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
   }
 
+  Future<void> test_quiver_checkNotNull_not_postDominating() async {
+    addQuiverPackage();
+    await analyze('''
+import 'package:quiver/check.dart';
+void f(bool b, int i, int j) {
+  checkNotNull(j);
+  if (b) return;
+  checkNotNull(i);
+}
+''');
+
+    // Asserts after ifs don't demonstrate non-null intent.
+    assertNoEdge(decoratedTypeAnnotation('int i').node, never);
+    // But asserts before ifs do
+    assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true);
+  }
+
+  Future<void> test_quiver_checkNotNull_postDominating() async {
+    addQuiverPackage();
+    await analyze('''
+import 'package:quiver/check.dart';
+void f(int i) {
+  checkNotNull(i);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+  }
+
+  Future<void> test_quiver_checkNotNull_prefixed() async {
+    addQuiverPackage();
+    await analyze('''
+import 'package:quiver/check.dart' as quiver;
+void f(int i) {
+  quiver.checkNotNull(i);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+  }
+
   Future<void> test_redirecting_constructor_factory() async {
     await analyze('''
 class C {
@@ -6771,6 +6998,140 @@
     assertEdge(string1.node, string2.node, hard: true);
   }
 
+  Future<void> test_setupAssignment_assignment_inDistantSetUp() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart';
+void main() {
+  int i;
+  // There could be tests here in which [i] is not certain to have been
+  // assigned.
+
+  group('g2', () {
+    setUp(() {
+      i = 1;
+    });
+  });
+}
+''');
+
+    assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+  }
+
+  Future<void> test_setupAssignment_assignment_inSetUp() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart';
+void main() {
+  int i;
+    int j = 1;
+  setUp(() {
+    i = j;
+  });
+}
+''');
+
+    assertNullCheck(
+        checkExpression('j;'),
+        assertEdge(decoratedTypeAnnotation('int j').node,
+            decoratedTypeAnnotation('int i').node,
+            hard: false, isSetupAssignment: true));
+  }
+
+  Future<void> test_setupAssignment_assignment_inUnrelatedSetUp() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart';
+void main() {
+  group('g1', () {
+    int/*1*/ i;
+  });
+
+  group('g2', () {
+    int/*2*/ i;
+    int j = 1;
+    setUp(() {
+      i = j;
+    });
+  });
+}
+''');
+
+    assertNoEdge(graph.never, decoratedTypeAnnotation('int/*1*/').node);
+    assertNullCheck(
+        checkExpression('j;'),
+        assertEdge(decoratedTypeAnnotation('int j').node,
+            decoratedTypeAnnotation('int/*2*/').node,
+            hard: false, isSetupAssignment: true));
+  }
+
+  Future<void> test_setupAssignment_assignment_inWrongSetUp() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart' as t;
+void main() {
+  int i;
+  setUp(() {
+    i = 1;
+  });
+}
+void setUp(dynamic callback()) {}
+''');
+
+    assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+  }
+
+  Future<void> test_setupAssignment_assignment_outsideSetUp() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart';
+void main() {
+  int i;
+  i = 1;
+}
+''');
+
+    assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+  }
+
+  Future<void> test_setupAssignment_assignment_toField() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart';
+void main() {
+  setUp(() {
+    C c = C();
+    c.i = 1;
+  });
+}
+class C {
+  int i;
+}
+''');
+
+    assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+  }
+
+  Future<void> test_setupAssignment_nullAwareAssignment_inSetUp() async {
+    addTestCorePackage();
+    await analyze('''
+import 'package:test/test.dart';
+void main() {
+  int i;
+    int j = 1;
+  setUp(() {
+    i ??= j;
+  });
+}
+''');
+
+    var iNullable = decoratedTypeAnnotation('int i').node;
+    assertNullCheck(
+        checkExpression('j;'),
+        assertEdge(decoratedTypeAnnotation('int j').node, iNullable,
+            hard: false, guards: [iNullable], isSetupAssignment: true));
+  }
+
   Future<void> test_simpleIdentifier_bangHint() async {
     await analyze('''
 int f1(int i1) => i1;
@@ -7401,6 +7762,16 @@
   }
 }
 
+class _MockSource implements Source {
+  @override
+  final Uri uri;
+
+  _MockSource(this.uri);
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
 class _TestEdgeOrigin implements EdgeOrigin {
   const _TestEdgeOrigin();
 
diff --git a/pkg/nnbd_migration/test/edit_plan_test.dart b/pkg/nnbd_migration/test/edit_plan_test.dart
index 5cb8c7f..910e7aa 100644
--- a/pkg/nnbd_migration/test/edit_plan_test.dart
+++ b/pkg/nnbd_migration/test/edit_plan_test.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -58,6 +59,62 @@
   NodeProducingEditPlan extract(AstNode inner, AstNode outer) =>
       planner.extract(outer, planner.passThrough(inner));
 
+  Future<void> test_acceptLateHint() async {
+    var code = '/* late */ int x = 0;';
+    await analyze(code);
+    var hint = getPrefixHint(findNode.simple('int').token);
+    var changes = checkPlan(
+        planner.acceptLateHint(
+            planner.passThrough(findNode.simple('int')), hint),
+        'late int x = 0;');
+    expect(changes.keys, unorderedEquals([0, 7]));
+    expect(changes[7], hasLength(1));
+    expect(changes[7][0].length, 3);
+  }
+
+  Future<void> test_acceptLateHint_space_needed_after() async {
+    var code = '/* late */int x = 0;';
+    await analyze(code);
+    var hint = getPrefixHint(findNode.simple('int').token);
+    checkPlan(
+        planner.acceptLateHint(
+            planner.passThrough(findNode.simple('int')), hint),
+        'late int x = 0;');
+  }
+
+  Future<void> test_acceptLateHint_space_needed_before() async {
+    var code = '@deprecated/* late */ int x = 0;';
+    await analyze(code);
+    var hint = getPrefixHint(findNode.simple('int').token);
+    checkPlan(
+        planner.acceptLateHint(
+            planner.passThrough(findNode.simple('int')), hint),
+        '@deprecated late int x = 0;');
+  }
+
+  Future<void> test_acceptNullabilityOrNullCheckHint() async {
+    var code = 'int /*?*/ x = 0;';
+    await analyze(code);
+    var intRef = findNode.simple('int');
+    var typeName = planner.passThrough(intRef);
+    checkPlan(
+        planner.acceptNullabilityOrNullCheckHint(
+            typeName, getPostfixHint(intRef.token)),
+        'int? x = 0;');
+  }
+
+  Future<void> test_acceptNullabilityOrNullCheckHint_inside_extract() async {
+    var code = 'f(x) => 3 * x /*!*/ * 4;';
+    await analyze(code);
+    var xRef = findNode.simple('x /*');
+    checkPlan(
+        planner.extract(
+            xRef.parent.parent,
+            planner.acceptNullabilityOrNullCheckHint(
+                planner.passThrough(xRef), getPostfixHint(xRef.token))),
+        'f(x) => x!;');
+  }
+
   Future<void> test_addBinaryPostfix_assignment_right_associative() async {
     await analyze('_f(a, b, c) => a = b;');
     // Admittedly this is sort of a bogus test case, since the code it produces
@@ -185,6 +242,48 @@
         'f(x) => x = () => null;');
   }
 
+  Future<void> test_addCommentPostfix_before_closer() async {
+    await analyze('f(g) => g(0);');
+    checkPlan(
+        planner.addCommentPostfix(
+            planner.passThrough(findNode.integerLiteral('0')), '/* zero */'),
+        'f(g) => g(0 /* zero */);');
+  }
+
+  Future<void> test_addCommentPostfix_before_other() async {
+    await analyze('f() => 0.isEven;');
+    checkPlan(
+        planner.addCommentPostfix(
+            planner.passThrough(findNode.integerLiteral('0')), '/* zero */'),
+        'f() => 0 /* zero */ .isEven;');
+  }
+
+  Future<void> test_addCommentPostfix_before_semicolon() async {
+    await analyze('f() => 0;');
+    checkPlan(
+        planner.addCommentPostfix(
+            planner.passThrough(findNode.integerLiteral('0')), '/* zero */'),
+        'f() => 0 /* zero */;');
+  }
+
+  Future<void> test_addCommentPostfix_before_space() async {
+    await analyze('f() => 0 + 1;');
+    checkPlan(
+        planner.addCommentPostfix(
+            planner.passThrough(findNode.integerLiteral('0')), '/* zero */'),
+        'f() => 0 /* zero */ + 1;');
+  }
+
+  Future<void> test_addCommentPostfix_informative() async {
+    await analyze('f() => 0.isEven;');
+    checkPlan(
+        planner.addCommentPostfix(
+            planner.passThrough(findNode.integerLiteral('0')), '/* zero */',
+            isInformative: true),
+        'f() => 0.isEven;',
+        expectedIncludingInformative: 'f() => 0 /* zero */ .isEven;');
+  }
+
   Future<void> test_addUnaryPostfix_inner_precedence_add_parens() async {
     await analyze('f(x) => -x;');
     checkPlan(
@@ -288,6 +387,50 @@
     }
   }
 
+  Future<void> test_dropNullabilityHint() async {
+    var code = 'int /*!*/ x = 0;';
+    await analyze(code);
+    var intRef = findNode.simple('int');
+    var typeName = planner.passThrough(intRef);
+    checkPlan(
+        planner.dropNullabilityHint(typeName, getPostfixHint(intRef.token)),
+        'int x = 0;');
+  }
+
+  Future<void> test_dropNullabilityHint_space_before_must_be_kept() async {
+    var code = 'int /*!*/x = 0;';
+    await analyze(code);
+    var intRef = findNode.simple('int');
+    var typeName = planner.passThrough(intRef);
+    var changes = checkPlan(
+        planner.dropNullabilityHint(typeName, getPostfixHint(intRef.token)),
+        'int x = 0;');
+    expect(changes.keys, unorderedEquals([code.indexOf('/*')]));
+  }
+
+  Future<void> test_dropNullabilityHint_space_needed() async {
+    var code = 'int/*!*/x = 0;';
+    await analyze(code);
+    var intRef = findNode.simple('int');
+    var typeName = planner.passThrough(intRef);
+    checkPlan(
+        planner.dropNullabilityHint(typeName, getPostfixHint(intRef.token)),
+        'int x = 0;');
+  }
+
+  Future<void> test_dropNullabilityHint_tight_no_space_needed() async {
+    // We try to minimize how much we alter the source code, so we don't insert
+    // a space in this example even though it would look prettier to do so.
+    var code = 'void Function()/*!*/x = () {};';
+    await analyze(code);
+    var functionType = findNode.genericFunctionType('Function');
+    var typeName = planner.passThrough(functionType);
+    checkPlan(
+        planner.dropNullabilityHint(
+            typeName, getPostfixHint(functionType.endToken)),
+        'void Function()x = () {};');
+  }
+
   Future<void> test_explainNonNullable() async {
     await analyze('int x = 0;');
     checkPlan(
@@ -392,6 +535,25 @@
         'var x = 0; var y = 0;');
   }
 
+  Future<void> test_informativeMessageForToken() async {
+    await analyze('f(x) => x + 1;');
+    var sum = findNode.binary('+');
+    var info = _MockInfo();
+    var changes = checkPlan(
+        planner.passThrough(sum, innerPlans: [
+          planner.informativeMessageForToken(sum, sum.operator, info: info)
+        ]),
+        'f(x) => x + 1;',
+        expectedIncludingInformative: 'f(x) => x  1;');
+    var expectedOffset = sum.operator.offset;
+    expect(changes.keys, unorderedEquals([expectedOffset]));
+    expect(changes[expectedOffset], hasLength(1));
+    expect(changes[expectedOffset][0].length, '+'.length);
+    expect(changes[expectedOffset][0].replacement, '');
+    expect(changes[expectedOffset][0].isInformative, isTrue);
+    expect(changes[expectedOffset][0].info, same(info));
+  }
+
   Future<void> test_insertText() async {
     await analyze('final x = 1;');
     var variableDeclarationList = findNode.variableDeclarationList('final');
@@ -1122,8 +1284,8 @@
     await analyze('var x = 1;');
     var variableDeclarationList = findNode.variableDeclarationList('var x');
     checkPlan(
-        planner.replaceToken(variableDeclarationList,
-            variableDeclarationList.keyword, [AtomicEdit.insert('int')]),
+        planner.replaceToken(
+            variableDeclarationList, variableDeclarationList.keyword, 'int'),
         'int x = 1;');
   }
 
@@ -1438,6 +1600,10 @@
   }
 }
 
+class _MockInfo implements AtomicEditInfo {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
 class _PrecedenceChecker extends UnifyingAstVisitor<void> {
   final EditPlanner planner;
 
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index 6abb6ef..db9f2ba 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
 import 'package:nnbd_migration/src/fix_aggregator.dart';
@@ -54,6 +55,105 @@
     expect(previewInfo.applyTo(code), 'f(a, b) => (a! + b!)!;');
   }
 
+  Future<void> test_assignment_add_null_check() async {
+    var content = 'f(int x, int y) => x += y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('+='): NodeChangeForAssignment()..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x, int y) => (x += y)!;');
+  }
+
+  Future<void> test_assignment_change_lhs() async {
+    var content = 'f(List<int> x, int y) => x[0] += y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('+='): NodeChangeForAssignment(),
+      findNode.index('[0]').target: NodeChangeForExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(List<int> x, int y) => x![0] += y;');
+  }
+
+  Future<void> test_assignment_change_rhs() async {
+    var content = 'f(int x, int y) => x += y;';
+    await analyze(content);
+    var assignment = findNode.assignment('+=');
+    var previewInfo = run({
+      assignment: NodeChangeForAssignment(),
+      assignment.rightHandSide: NodeChangeForExpression()..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x, int y) => x += y!;');
+  }
+
+  Future<void> test_assignment_compound_with_bad_combined_type() async {
+    var content = 'f(int x, int y) => x += y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('+='): NodeChangeForAssignment()
+        ..hasBadCombinedType = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('+=')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasBadCombinedType);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '+='.length);
+  }
+
+  Future<void> test_assignment_compound_with_nullable_source() async {
+    var content = 'f(int x, int y) => x += y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('+='): NodeChangeForAssignment()
+        ..hasNullableSource = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('+=')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasNullableSource);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '+='.length);
+  }
+
+  Future<void> test_assignment_introduce_as() async {
+    var content = 'f(int x, int y) => x += y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('+='): NodeChangeForAssignment()
+        ..introduceAs(nnbdTypeProvider.intType, null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x, int y) => (x += y) as int;');
+  }
+
+  Future<void> test_assignment_weak_null_aware() async {
+    var content = 'f(int x, int y) => x ??= y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('??='): NodeChangeForAssignment()
+        ..isWeakNullAware = true
+    }, warnOnWeakCode: true);
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('??=')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.nullAwareAssignmentUnnecessaryInStrongMode);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '??='.length);
+  }
+
+  Future<void> test_assignment_weak_null_aware_remove() async {
+    var content = 'f(int x, int y) => x ??= y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('??='): NodeChangeForAssignment()
+        ..isWeakNullAware = true
+    }, warnOnWeakCode: false);
+    expect(previewInfo.applyTo(code), 'f(int x, int y) => x;');
+  }
+
   Future<void> test_eliminateDeadIf_changesInKeptCode() async {
     await analyze('''
 f(int i, int/*?*/ j) {
@@ -695,9 +795,10 @@
     var typeName = findNode.typeName('int');
     var previewInfo = run({
       typeName: NodeChangeForTypeAnnotation()
-        ..makeNullable = true
-        ..decoratedType = MockDecoratedType(
-            MockDartType(toStringValueWithoutNullability: 'int'))
+        ..recordNullability(
+            MockDecoratedType(
+                MockDartType(toStringValueWithoutNullability: 'int')),
+            true)
     });
     expect(previewInfo.applyTo(code), 'f(int? x) {}');
   }
@@ -707,8 +808,10 @@
     var typeName = findNode.typeName('int');
     var previewInfo = run({
       typeName: NodeChangeForTypeAnnotation()
-        ..decoratedType = MockDecoratedType(
-            MockDartType(toStringValueWithoutNullability: 'int'))
+        ..recordNullability(
+            MockDecoratedType(
+                MockDartType(toStringValueWithoutNullability: 'int')),
+            false)
     });
     expect(previewInfo.applyTo(code), 'int x = 0;');
     expect(previewInfo.applyTo(code, includeInformative: true), 'int  x = 0;');
@@ -763,6 +866,131 @@
     expect(previewInfo.applyTo(code), 'f(a) => a..b!.c;');
   }
 
+  Future<void> test_post_increment_add_null_check() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => x++!;');
+  }
+
+  Future<void> test_post_increment_change_target() async {
+    var content = 'f(List<int> x) => x[0]++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression(),
+      findNode.index('[0]').target: NodeChangeForExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(List<int> x) => x![0]++;');
+  }
+
+  Future<void> test_post_increment_introduce_as() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..introduceAs(nnbdTypeProvider.intType, null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => x++ as int;');
+  }
+
+  Future<void> test_post_increment_with_bad_combined_type() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..hasBadCombinedType = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasBadCombinedType);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
+  Future<void> test_post_increment_with_nullable_source() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..hasNullableSource = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasNullableSource);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
+  Future<void> test_pre_increment_add_null_check() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => (++x)!;');
+  }
+
+  Future<void> test_pre_increment_change_target() async {
+    var content = 'f(List<int> x) => ++x[0];';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression(),
+      findNode.index('[0]').target: NodeChangeForExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(List<int> x) => ++x![0];');
+  }
+
+  Future<void> test_pre_increment_introduce_as() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..introduceAs(nnbdTypeProvider.intType, null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => ++x as int;');
+  }
+
+  Future<void> test_pre_increment_with_bad_combined_type() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..hasBadCombinedType = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasBadCombinedType);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
+  Future<void> test_pre_increment_with_nullable_source() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..hasNullableSource = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasNullableSource);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
   Future<void>
       test_removeAs_in_cascade_target_no_parens_needed_cascade() async {
     await analyze('f(a) => ((a..b) as dynamic)..c;');
@@ -934,9 +1162,10 @@
       findNode.unit: NodeChangeForCompilationUnit()
         ..removeLanguageVersionComment = true,
       findNode.typeAnnotation('int'): NodeChangeForTypeAnnotation()
-        ..makeNullable = true
-        ..decoratedType = MockDecoratedType(
-            MockDartType(toStringValueWithoutNullability: 'int'))
+        ..recordNullability(
+            MockDecoratedType(
+                MockDartType(toStringValueWithoutNullability: 'int')),
+            true)
     });
     // TODO(mfairhurst): Remove beginning \n once it renders properly in preview
     expect(previewInfo.applyTo(code), '\nint? f() => null;\n');
@@ -987,9 +1216,10 @@
       methodInvocation: NodeChangeForMethodInvocation()
         ..removeNullAwareness = true,
       typeAnnotation: NodeChangeForTypeAnnotation()
-        ..makeNullable = true
-        ..decoratedType = MockDecoratedType(
-            MockDartType(toStringValueWithoutNullability: 'int'))
+        ..recordNullability(
+            MockDecoratedType(
+                MockDartType(toStringValueWithoutNullability: 'int')),
+            true)
     });
     expect(previewInfo.applyTo(code), 'f(x) => x.m<int?>();');
   }
@@ -1109,6 +1339,58 @@
     });
     expect(previewInfo.applyTo(code), 'int x = 0;');
   }
+
+  Future<void> test_warnOnDeadIf_false() async {
+    await analyze('''
+f(int i) {
+  if (i == null) print(i);
+}
+''');
+    var previewInfo = run({
+      findNode.statement('if'): NodeChangeForIfStatement()
+        ..conditionValue = false
+    }, warnOnWeakCode: true);
+    expect(previewInfo.applyTo(code, includeInformative: true), '''
+f(int i) {
+  if (i == null /* == false */) print(i);
+}
+''');
+  }
+
+  Future<void> test_warnOnDeadIf_true() async {
+    await analyze('''
+f(int i) {
+  if (i != null) print(i);
+}
+''');
+    var previewInfo = run({
+      findNode.statement('if'): NodeChangeForIfStatement()
+        ..conditionValue = true
+    }, warnOnWeakCode: true);
+    expect(previewInfo.applyTo(code, includeInformative: true), '''
+f(int i) {
+  if (i != null /* == true */) print(i);
+}
+''');
+  }
+
+  Future<void> test_warnOnNullAwareAccess() async {
+    var content = '''
+f(int i) {
+  print(i?.isEven);
+}
+''';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.propertyAccess('?.'): NodeChangeForPropertyAccess()
+        ..removeNullAwareness = true
+    }, warnOnWeakCode: true);
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('?')].single;
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '?'.length);
+  }
 }
 
 class FixAggregatorTestBase extends AbstractSingleUnitTest {
@@ -1120,9 +1402,9 @@
   }
 
   Map<int, List<AtomicEdit>> run(Map<AstNode, NodeChange> changes,
-      {bool removeViaComments: false}) {
+      {bool removeViaComments = false, bool warnOnWeakCode = false}) {
     return FixAggregator.run(testUnit, testCode, changes,
-        removeViaComments: removeViaComments);
+        removeViaComments: removeViaComments, warnOnWeakCode: warnOnWeakCode);
   }
 }
 
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 3bdfcf7..b151462 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -10,10 +10,12 @@
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
 import 'package:nnbd_migration/src/fix_aggregator.dart';
 import 'package:nnbd_migration/src/fix_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -46,11 +48,25 @@
           .having((c) => c.addRequiredKeyword, 'addRequiredKeyword', true);
 
   static final isMakeNullable = TypeMatcher<NodeChangeForTypeAnnotation>()
-      .having((c) => c.makeNullable, 'makeNullable', true);
+      .having((c) => c.makeNullable, 'makeNullable', true)
+      .having((c) => c.nullabilityHint, 'nullabilityHint', isNull);
+
+  static final isMakeNullableDueToHint =
+      TypeMatcher<NodeChangeForTypeAnnotation>()
+          .having((c) => c.makeNullable, 'makeNullable', true)
+          .having((c) => c.nullabilityHint, 'nullabilityHint', isNotNull);
+
+  static const isEdge = TypeMatcher<NullabilityEdge>();
 
   static final isExplainNonNullable = TypeMatcher<NodeChangeForTypeAnnotation>()
       .having((c) => c.makeNullable, 'makeNullable', false);
 
+  static final isBadCombinedType = TypeMatcher<NodeChangeForAssignmentLike>()
+      .having((c) => c.hasBadCombinedType, 'hasBadCombinedType', true);
+
+  static final isNullableSource = TypeMatcher<NodeChangeForAssignmentLike>()
+      .having((c) => c.hasNullableSource, 'hasNullableSource', true);
+
   static final isNodeChangeForExpression =
       TypeMatcher<NodeChangeForExpression>();
 
@@ -74,6 +90,10 @@
       TypeMatcher<NodeChangeForAnnotation>().having(
           (c) => c.changeToRequiredKeyword, 'changeToRequiredKeyword', true);
 
+  static final isWeakNullAwareAssignment =
+      TypeMatcher<NodeChangeForAssignment>()
+          .having((c) => c.isWeakNullAware, 'isWeakNullAware', true);
+
   DartType get dynamicType => postMigrationTypeProvider.dynamicType;
 
   DartType get objectType => postMigrationTypeProvider.objectType;
@@ -332,6 +352,17 @@
     visitSubexpression(findNode.assignment('??='), '_C?');
   }
 
+  Future<void> test_assignmentExpression_null_aware_simple_promoted() async {
+    await analyze('''
+_f(bool/*?*/ x, bool/*?*/ y) => x != null && (x ??= y) != null;
+''');
+    // On the RHS of the `&&`, `x` is promoted to non-nullable, but it is still
+    // considered to be a nullable assignment target, so no null check is
+    // generated for `y`.
+    visitSubexpression(findNode.binary('&&'), 'bool',
+        changes: {findNode.assignment('??='): isWeakNullAwareAssignment});
+  }
+
   Future<void>
       test_assignmentExpression_simple_nonNullable_to_nonNullable() async {
     await analyze('''
@@ -364,7 +395,6 @@
     visitSubexpression(findNode.assignment('= '), 'int?');
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39641')
   Future<void> test_assignmentExpression_simple_promoted() async {
     await analyze('''
 _f(bool/*?*/ x, bool/*?*/ y) => x != null && (x = y) != null;
@@ -1028,6 +1058,127 @@
     visitSubexpression(findNode.booleanLiteral('true'), 'bool');
   }
 
+  Future<void> test_compound_assignment_null_shorted_ok() async {
+    await analyze('''
+class C {
+  int/*!*/ x;
+}
+_f(C/*?*/ c) {
+  c?.x += 1;
+}
+''');
+    // Even though c?.x is nullable, it should not be a problem to use it as the
+    // LHS of a compound assignment, because null shorting will ensure that the
+    // assignment only happens if c is non-null.
+    var assignment = findNode.assignment('+=');
+    visitSubexpression(assignment, 'int?');
+  }
+
+  Future<void> test_compound_assignment_nullable_result_bad() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C c) {
+  c += 1;
+}
+''');
+    var assignment = findNode.assignment('+=');
+    visitSubexpression(assignment, 'C?',
+        changes: {assignment: isBadCombinedType});
+  }
+
+  Future<void> test_compound_assignment_nullable_result_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+abstract class D {
+  void set x(C/*?*/ value);
+  C/*!*/ get x;
+  f() {
+    x += 1;
+  }
+}
+''');
+    var assignment = findNode.assignment('+=');
+    visitSubexpression(assignment, 'C?');
+  }
+
+  Future<void> test_compound_assignment_nullable_source() async {
+    await analyze('''
+_f(int/*?*/ x) {
+  x += 1;
+}
+''');
+    var assignment = findNode.assignment('+=');
+    visitSubexpression(assignment, 'int',
+        changes: {assignment: isNullableSource});
+  }
+
+  Future<void> test_compound_assignment_potentially_nullable_source() async {
+    await analyze('''
+class C<T extends num/*?*/> {
+  _f(T/*!*/ x) {
+    x += 1;
+  }
+}
+''');
+    var assignment = findNode.assignment('+=');
+    visitSubexpression(assignment, 'T',
+        changes: {assignment: isNullableSource});
+  }
+
+  Future<void> test_compound_assignment_promoted_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C/*?*/ x) {
+  if (x != null) {
+    x += 1;
+  }
+}
+''');
+    // The compound assignment is ok, because:
+    // - prior to the assignment, x's value is promoted to non-nullable
+    // - the nullable return value of operator+ is ok to assign to x, because it
+    //   un-does the promotion.
+    visitSubexpression(findNode.assignment('+='), 'C?');
+  }
+
+  Future<void> test_conditionalExpression_dead_else_remove() async {
+    await analyze('_f(int x, int/*?*/ y) => x != null ? x + 1 : y + 1.0;');
+    var expression = findNode.conditionalExpression('x != null');
+    visitSubexpression(expression, 'int',
+        changes: {expression: isConditionalWithKnownValue(true)});
+  }
+
+  Future<void> test_conditionalExpression_dead_else_warn() async {
+    await analyze('_f(int x, int/*?*/ y) => x != null ? x + 1 : y + 1.0;');
+    var expression = findNode.conditionalExpression('x != null');
+    visitSubexpression(expression, 'num', warnOnWeakCode: true, changes: {
+      expression: isConditionalWithKnownValue(true),
+      findNode.simple('y +'): isNullCheck
+    });
+  }
+
+  Future<void> test_conditionalExpression_dead_then_remove() async {
+    await analyze('_f(int x, int/*?*/ y) => x == null ? y + 1.0 : x + 1;');
+    var expression = findNode.conditionalExpression('x == null');
+    visitSubexpression(expression, 'int',
+        changes: {expression: isConditionalWithKnownValue(false)});
+  }
+
+  Future<void> test_conditionalExpression_dead_then_warn() async {
+    await analyze('_f(int x, int/*?*/ y) => x == null ? y + 1.0 : x + 1;');
+    var expression = findNode.conditionalExpression('x == null');
+    visitSubexpression(expression, 'num', warnOnWeakCode: true, changes: {
+      expression: isConditionalWithKnownValue(false),
+      findNode.simple('y +'): isNullCheck
+    });
+  }
+
   Future<void> test_conditionalExpression_flow_as_condition() async {
     await analyze('''
 _f(bool x, int/*?*/ y) => (x ? y != null : y != null) ? y + 1 : 0;
@@ -1100,7 +1251,8 @@
     await analyze('''
 int _f({int/*?*/ x}) => 1;
 ''');
-    visitAll(changes: {findNode.typeName('int/*?*/ x'): isMakeNullable});
+    visitAll(
+        changes: {findNode.typeName('int/*?*/ x'): isMakeNullableDueToHint});
   }
 
   Future<void>
@@ -1140,7 +1292,7 @@
 ''');
     visitAll(changes: {
       findNode.annotation('required'): isRequiredAnnotationToRequiredKeyword,
-      findNode.typeName('int'): isMakeNullable,
+      findNode.typeName('int'): isMakeNullableDueToHint,
     });
   }
 
@@ -1326,7 +1478,7 @@
 ''');
     var ifStatement = findNode.statement('if');
     visitStatement(ifStatement,
-        changes: {ifStatement: isEliminateDeadIf(true)});
+        changes: {ifStatement: isConditionalWithKnownValue(true)});
   }
 
   Future<void> test_ifStatement_dead_then() async {
@@ -1341,7 +1493,7 @@
 ''');
     var ifStatement = findNode.statement('if');
     visitStatement(ifStatement,
-        changes: {ifStatement: isEliminateDeadIf(false)});
+        changes: {ifStatement: isConditionalWithKnownValue(false)});
   }
 
   Future<void> test_ifStatement_flow_promote_in_else() async {
@@ -1383,6 +1535,17 @@
     visitStatement(findNode.statement('if'));
   }
 
+  Future<void> test_implicit_downcast() async {
+    await analyze('int f(num x) => x;');
+    var xRef = findNode.simple('x;');
+    visitSubexpression(xRef, 'int', changes: {
+      xRef: isNodeChangeForExpression.havingIndroduceAsWithInfo(
+          'int',
+          isInfo(NullabilityFixDescription.downcastExpression,
+              {FixReasonTarget.root: isEdge}))
+    });
+  }
+
   Future<void> test_indexExpression_dynamic() async {
     await analyze('''
 Object/*!*/ _f(dynamic d, int/*?*/ i) => d[i];
@@ -1491,7 +1654,7 @@
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
     visitSubexpression(findNode.listLiteral('['), 'List<int>', changes: {
-      findNode.ifElement('null'): isEliminateDeadIf(true),
+      findNode.ifElement('null'): isConditionalWithKnownValue(true),
       findNode.simple('y) else'): isNullCheck
     });
   }
@@ -1502,7 +1665,7 @@
 int/*!*/ g(int/*!*/ y) => y;
 ''');
     visitSubexpression(findNode.listLiteral('['), 'List<int>', changes: {
-      findNode.ifElement('null'): isEliminateDeadIf(true),
+      findNode.ifElement('null'): isConditionalWithKnownValue(true),
       findNode.simple('y)]'): isNullCheck
     });
   }
@@ -1514,7 +1677,7 @@
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
     visitSubexpression(findNode.listLiteral('['), 'List<int>', changes: {
-      findNode.ifElement('null'): isEliminateDeadIf(false),
+      findNode.ifElement('null'): isConditionalWithKnownValue(false),
       findNode.simple('y)]'): isNullCheck
     });
   }
@@ -1527,8 +1690,9 @@
 _f(int x, int/*?*/ y) => [if (x == null) h(y)];
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
-    visitSubexpression(findNode.listLiteral('['), 'List<dynamic>',
-        changes: {findNode.ifElement('null'): isEliminateDeadIf(false)});
+    visitSubexpression(findNode.listLiteral('['), 'List<dynamic>', changes: {
+      findNode.ifElement('null'): isConditionalWithKnownValue(false)
+    });
   }
 
   Future<void> test_list_make_explicit_type_nullable() async {
@@ -1593,7 +1757,7 @@
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Map<int, int>',
         changes: {
-          findNode.ifElement('null'): isEliminateDeadIf(true),
+          findNode.ifElement('null'): isConditionalWithKnownValue(true),
           findNode.simple('y) else'): isNullCheck
         });
   }
@@ -1605,7 +1769,7 @@
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Map<int, int>',
         changes: {
-          findNode.ifElement('null'): isEliminateDeadIf(true),
+          findNode.ifElement('null'): isConditionalWithKnownValue(true),
           findNode.simple('y)}'): isNullCheck
         });
   }
@@ -1618,7 +1782,7 @@
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Map<int, int>',
         changes: {
-          findNode.ifElement('null'): isEliminateDeadIf(false),
+          findNode.ifElement('null'): isConditionalWithKnownValue(false),
           findNode.simple('y)}'): isNullCheck
         });
   }
@@ -1632,7 +1796,9 @@
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Map<dynamic, dynamic>',
-        changes: {findNode.ifElement('null'): isEliminateDeadIf(false)});
+        changes: {
+          findNode.ifElement('null'): isConditionalWithKnownValue(false)
+        });
   }
 
   Future<void> test_map_make_explicit_key_type_nullable() async {
@@ -1748,6 +1914,49 @@
     visitSubexpression(findNode.methodInvocation('c.toString'), 'String');
   }
 
+  Future<void> test_null_aware_assignment_non_nullable_source() async {
+    await analyze('''
+abstract class C {
+  int/*!*/ f();
+  g(int/*!*/ x) {
+    x ??= f();
+  }
+}
+''');
+    var assignment = findNode.assignment('??=');
+    visitSubexpression(assignment, 'int',
+        changes: {assignment: isWeakNullAwareAssignment});
+  }
+
+  Future<void> test_null_aware_assignment_nullable_rhs_needs_check() async {
+    await analyze('''
+abstract class C {
+  void set x(int/*!*/ value);
+  int/*?*/ get x;
+  int/*?*/ f();
+  g() {
+    x ??= f();
+  }
+}
+''');
+    var assignment = findNode.assignment('??=');
+    visitSubexpression(assignment, 'int',
+        changes: {assignment.rightHandSide: isNullCheck});
+  }
+
+  Future<void> test_null_aware_assignment_nullable_rhs_ok() async {
+    await analyze('''
+abstract class C {
+  int/*?*/ f();
+  g(int/*?*/ x) {
+    x ??= f();
+  }
+}
+''');
+    var assignment = findNode.assignment('??=');
+    visitSubexpression(assignment, 'int?');
+  }
+
   Future<void> test_nullAssertion_promotes() async {
     await analyze('''
 _f(bool/*?*/ x) => x && x;
@@ -1779,6 +1988,113 @@
     visitSubexpression(findNode.binary('&&'), 'bool');
   }
 
+  Future<void> test_post_decrement_int_behavior() async {
+    await analyze('''
+_f(int x) => x--;
+''');
+    // It's not a problem that int.operator- returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.postfix('--'), 'int');
+  }
+
+  Future<void> test_post_increment_int_behavior() async {
+    await analyze('''
+_f(int x) => x++;
+''');
+    // It's not a problem that int.operator+ returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.postfix('++'), 'int');
+  }
+
+  Future<void> test_post_increment_null_shorted_ok() async {
+    await analyze('''
+class C {
+  int/*!*/ x;
+}
+_f(C/*?*/ c) {
+  c?.x++;
+}
+''');
+    // Even though c?.x is nullable, it should not be a problem to use it as the
+    // target of a post-increment, because null shorting will ensure that the
+    // increment only happens if c is non-null.
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'int?');
+  }
+
+  Future<void> test_post_increment_nullable_result_bad() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C c) {
+  c++;
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'C', changes: {increment: isBadCombinedType});
+  }
+
+  Future<void> test_post_increment_nullable_result_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+abstract class D {
+  void set x(C/*?*/ value);
+  C/*!*/ get x;
+  f() {
+    x++;
+  }
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'C');
+  }
+
+  Future<void> test_post_increment_nullable_source() async {
+    await analyze('''
+_f(int/*?*/ x) {
+  x++;
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'int?',
+        changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_post_increment_potentially_nullable_source() async {
+    await analyze('''
+class C<T extends num/*?*/> {
+  _f(T/*!*/ x) {
+    x++;
+  }
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'T', changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_post_increment_promoted_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C/*?*/ x) {
+  if (x != null) {
+    x++;
+  }
+}
+''');
+    // The increment is ok, because:
+    // - prior to the increment, x's value is promoted to non-nullable
+    // - the nullable return value of operator+ is ok to assign to x, because it
+    //   un-does the promotion.
+    visitSubexpression(findNode.postfix('++'), 'C');
+  }
+
   Future<void> test_postfixExpression_combined_nullable_noProblem() async {
     await analyze('''
 abstract class _C {
@@ -1896,6 +2212,115 @@
     visitSubexpression(findNode.postfix('++'), '_C');
   }
 
+  Future<void> test_pre_decrement_int_behavior() async {
+    await analyze('''
+_f(int x) => --x;
+''');
+    // It's not a problem that int.operator- returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.prefix('--'), 'int');
+  }
+
+  Future<void> test_pre_increment_int_behavior() async {
+    await analyze('''
+_f(int x) => ++x;
+''');
+    // It's not a problem that int.operator+ returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.prefix('++'), 'int');
+  }
+
+  Future<void> test_pre_increment_null_shorted_ok() async {
+    await analyze('''
+class C {
+  int/*!*/ x;
+}
+_f(C/*?*/ c) {
+  ++c?.x;
+}
+''');
+    // Even though c?.x is nullable, it should not be a problem to use it as the
+    // target of a pre-increment, because null shorting will ensure that the
+    // increment only happens if c is non-null.
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'int?');
+  }
+
+  Future<void> test_pre_increment_nullable_result_bad() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C c) {
+  ++c;
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'C?',
+        changes: {increment: isBadCombinedType});
+  }
+
+  Future<void> test_pre_increment_nullable_result_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+abstract class D {
+  void set x(C/*?*/ value);
+  C/*!*/ get x;
+  f() {
+    ++x;
+  }
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'C?');
+  }
+
+  Future<void> test_pre_increment_nullable_source() async {
+    await analyze('''
+_f(int/*?*/ x) {
+  ++x;
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'int',
+        changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_pre_increment_potentially_nullable_source() async {
+    await analyze('''
+class C<T extends num/*?*/> {
+  _f(T/*!*/ x) {
+    ++x;
+  }
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'num',
+        changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_pre_increment_promoted_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C/*?*/ x) {
+  if (x != null) {
+    ++x;
+  }
+}
+''');
+    // The increment is ok, because:
+    // - prior to the increment, x's value is promoted to non-nullable
+    // - the nullable return value of operator+ is ok to assign to x, because it
+    //   un-does the promotion.
+    visitSubexpression(findNode.prefix('++'), 'C?');
+  }
+
   Future<void> test_prefixedIdentifier_dynamic() async {
     await analyze('''
 Object/*!*/ _f(dynamic d) => d.x;
@@ -2010,7 +2435,6 @@
         changes: {findNode.simple('x;'): isNullCheck});
   }
 
-  @FailingTest(reason: 'TODO(paulberry)')
   Future<void> test_prefixExpression_combined_nullable_noProblem() async {
     await analyze('''
 abstract class _C {
@@ -2438,7 +2862,7 @@
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Set<int>', changes: {
-      findNode.ifElement('null'): isEliminateDeadIf(true),
+      findNode.ifElement('null'): isConditionalWithKnownValue(true),
       findNode.simple('y) else'): isNullCheck
     });
   }
@@ -2449,7 +2873,7 @@
 int/*!*/ g(int/*!*/ y) => y;
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Set<int>', changes: {
-      findNode.ifElement('null'): isEliminateDeadIf(true),
+      findNode.ifElement('null'): isConditionalWithKnownValue(true),
       findNode.simple('y)}'): isNullCheck
     });
   }
@@ -2461,7 +2885,7 @@
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Set<int>', changes: {
-      findNode.ifElement('null'): isEliminateDeadIf(false),
+      findNode.ifElement('null'): isConditionalWithKnownValue(false),
       findNode.simple('y)}'): isNullCheck
     });
   }
@@ -2475,7 +2899,9 @@
 double/*!*/ h(int/*!*/ y) => y.toDouble();
 ''');
     visitSubexpression(findNode.setOrMapLiteral('{'), 'Map<dynamic, dynamic>',
-        changes: {findNode.ifElement('null'): isEliminateDeadIf(false)});
+        changes: {
+          findNode.ifElement('null'): isConditionalWithKnownValue(false)
+        });
   }
 
   Future<void> test_set_make_explicit_type_nullable() async {
@@ -2566,8 +2992,8 @@
     var xRef = findNode.simple('x/*!*/');
     visitSubexpression(xRef, 'int', changes: {
       xRef: isNodeChangeForExpression.havingNullCheckWithInfo(isInfo(
-          NullabilityFixDescription.checkExpression,
-          [TypeMatcher<FixReason_NullCheckHint>()]))
+          NullabilityFixDescription.checkExpressionDueToHint,
+          {FixReasonTarget.root: TypeMatcher<FixReason_NullCheckHint>()}))
     });
   }
 
@@ -2578,6 +3004,22 @@
     visitSubexpression(findNode.stringLiteral("'foo'"), 'String');
   }
 
+  Future<void> test_suspicious_cast() async {
+    await analyze('''
+int f(Object o) {
+  if (o is! String) return 0;
+  return o;
+}
+''');
+    var xRef = findNode.simple('o;');
+    visitSubexpression(xRef, 'int', changes: {
+      xRef: isNodeChangeForExpression.havingIndroduceAsWithInfo(
+          'int',
+          isInfo(NullabilityFixDescription.otherCastExpression,
+              {FixReasonTarget.root: isEdge}))
+    });
+  }
+
   Future<void> test_symbolLiteral() async {
     await analyze('''
 f() => #foo;
@@ -2794,8 +3236,9 @@
 
   void visitSubexpression(Expression node, String expectedType,
       {Map<AstNode, Matcher> changes = const <Expression, Matcher>{},
-      Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{}}) {
-    var fixBuilder = _createFixBuilder(node);
+      Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{},
+      bool warnOnWeakCode = false}) {
+    var fixBuilder = _createFixBuilder(node, warnOnWeakCode: warnOnWeakCode);
     fixBuilder.visitAll();
     var type = node.staticType;
     expect(type.getDisplayString(withNullability: true), expectedType);
@@ -2833,7 +3276,7 @@
     }
   }
 
-  FixBuilder _createFixBuilder(AstNode scope) {
+  FixBuilder _createFixBuilder(AstNode scope, {bool warnOnWeakCode = false}) {
     var unit = scope.thisOrAncestorOfType<CompilationUnit>();
     var definingLibrary = unit.declaredElement.library;
     return FixBuilder(
@@ -2844,7 +3287,9 @@
         variables,
         definingLibrary,
         null,
-        scope.thisOrAncestorOfType<CompilationUnit>());
+        scope.thisOrAncestorOfType<CompilationUnit>(),
+        warnOnWeakCode,
+        graph);
   }
 
   bool _isInScope(AstNode node, AstNode scope) {
@@ -2853,13 +3298,20 @@
         null;
   }
 
-  static Matcher isEliminateDeadIf(bool knownValue) =>
+  static Matcher isConditionalWithKnownValue(bool knownValue) =>
       TypeMatcher<NodeChangeForConditional>()
           .having((c) => c.conditionValue, 'conditionValue', knownValue);
 }
 
 extension on TypeMatcher<NodeChangeForExpression> {
-  TypeMatcher<NodeChangeForExpression> havingNullCheckWithInfo(matcher) =>
+  TypeMatcher<NodeChangeForExpression> havingNullCheckWithInfo(
+          dynamic matcher) =>
       having((c) => c.addsNullCheck, 'addsNullCheck', true)
           .having((c) => c.addNullCheckInfo, 'addNullCheckInfo', matcher);
+
+  TypeMatcher<NodeChangeForExpression> havingIndroduceAsWithInfo(
+          dynamic typeStringMatcher, dynamic infoMatcher) =>
+      having((c) => c.introducesAsType.toString(), 'introducesAsType (string)',
+              typeStringMatcher)
+          .having((c) => c.introducesAsInfo, 'introducesAsInfo', infoMatcher);
 }
diff --git a/pkg/nnbd_migration/test/fix_reason_target_test.dart b/pkg/nnbd_migration/test/fix_reason_target_test.dart
new file mode 100644
index 0000000..c36391f
--- /dev/null
+++ b/pkg/nnbd_migration/test/fix_reason_target_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/fix_reason_target.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FixReasonTargetTest);
+  });
+}
+
+@reflectiveTest
+class FixReasonTargetTest {
+  void test_suffix_complex() {
+    var root = FixReasonTarget.root;
+    expect(root.returnType.typeArgument(0).suffix,
+        ' for type argument 0 of return type');
+    expect(root.yieldedType.namedParameter('foo').suffix,
+        ' for parameter foo of yielded type');
+    expect(root.namedParameter('foo').positionalParameter(0).suffix,
+        ' for parameter 0 of parameter foo');
+    expect(root.positionalParameter(0).returnType.suffix,
+        ' for return type of parameter 0');
+    expect(root.typeArgument(0).yieldedType.suffix,
+        ' for yielded type from type argument 0');
+  }
+
+  void test_suffix_simple() {
+    var root = FixReasonTarget.root;
+    expect(root.suffix, '');
+    expect(root.returnType.suffix, ' for return type');
+    expect(root.yieldedType.suffix, ' for yielded type');
+    expect(root.namedParameter('foo').suffix, ' for parameter foo');
+    expect(root.positionalParameter(0).suffix, ' for parameter 0');
+    expect(root.typeArgument(0).suffix, ' for type argument 0');
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/analysis_abstract.dart b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
new file mode 100644
index 0000000..d371a67
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_constants.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart'
+    hide AnalysisOptions;
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
+import 'package:analysis_server/src/utilities/mocks.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test/test.dart';
+
+import '../abstract_context.dart';
+import 'mocks.dart';
+
+/// An abstract base for all 'analysis' domain tests.
+class AbstractAnalysisTest extends AbstractContextTest
+    with ResourceProviderMixin {
+  bool generateSummaryFiles = false;
+  MockServerChannel serverChannel;
+  TestPluginManager pluginManager;
+  AnalysisServer server;
+  RequestHandler handler;
+
+  final List<GeneralAnalysisService> generalServices =
+      <GeneralAnalysisService>[];
+  final Map<AnalysisService, List<String>> analysisSubscriptions = {};
+
+  String projectPath;
+  String testFolder;
+  String testFile;
+  String testCode;
+
+  AbstractAnalysisTest();
+
+  AnalysisDomainHandler get analysisHandler =>
+      server.handlers.singleWhere((handler) => handler is AnalysisDomainHandler)
+          as AnalysisDomainHandler;
+
+  AnalysisOptions get analysisOptions => testDiver.analysisOptions;
+
+  AnalysisDriver get testDiver => server.getAnalysisDriver(testFile);
+
+  void addAnalysisOptionsFile(String content) {
+    newFile(
+        resourceProvider.pathContext.join(projectPath, 'analysis_options.yaml'),
+        content: content);
+  }
+
+  void addAnalysisSubscription(AnalysisService service, String file) {
+    // add file to subscription
+    var files = analysisSubscriptions[service];
+    if (files == null) {
+      files = <String>[];
+      analysisSubscriptions[service] = files;
+    }
+    files.add(file);
+    // set subscriptions
+    var request =
+        AnalysisSetSubscriptionsParams(analysisSubscriptions).toRequest('0');
+    handleSuccessfulRequest(request);
+  }
+
+  void addGeneralAnalysisSubscription(GeneralAnalysisService service) {
+    generalServices.add(service);
+    var request =
+        AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
+    handleSuccessfulRequest(request);
+  }
+
+  String addTestFile(String content) {
+    newFile(testFile, content: content);
+    testCode = content;
+    return testFile;
+  }
+
+  /// Create an analysis options file based on the given arguments.
+  void createAnalysisOptionsFile({List<String> experiments}) {
+    var buffer = StringBuffer();
+    if (experiments != null) {
+      buffer.writeln('analyzer:');
+      buffer.writeln('  enable-experiment:');
+      for (var experiment in experiments) {
+        buffer.writeln('    - $experiment');
+      }
+    }
+    addAnalysisOptionsFile(buffer.toString());
+  }
+
+  AnalysisServer createAnalysisServer() {
+    //
+    // Create an SDK in the mock file system.
+    //
+    MockSdk(
+        generateSummaryFiles: generateSummaryFiles,
+        resourceProvider: resourceProvider);
+    //
+    // Create server
+    //
+    var options = AnalysisServerOptions();
+    return AnalysisServer(
+        serverChannel,
+        resourceProvider,
+        options,
+        DartSdkManager(resourceProvider.convertPath('/sdk'), true),
+        CrashReportingAttachmentsBuilder.empty,
+        InstrumentationService.NULL_SERVICE);
+  }
+
+  /// Creates a project [projectPath].
+  void createProject({Map<String, String> packageRoots}) {
+    newFolder(projectPath);
+    var request = AnalysisSetAnalysisRootsParams([projectPath], [],
+            packageRoots: packageRoots)
+        .toRequest('0');
+    handleSuccessfulRequest(request, handler: analysisHandler);
+  }
+
+  void doAllDeclarationsTrackerWork() {
+    while (server.declarationsTracker.hasWork) {
+      server.declarationsTracker.doWork();
+    }
+  }
+
+  /// Returns the offset of [search] in the file at the given [path].
+  /// Fails if not found.
+  int findFileOffset(String path, String search) {
+    var file = getFile(path);
+    var code = file.createSource().contents.data;
+    var offset = code.indexOf(search);
+    expect(offset, isNot(-1), reason: '"$search" in\n$code');
+    return offset;
+  }
+
+  /// Returns the offset of [search] in [testCode].
+  /// Fails if not found.
+  int findOffset(String search) {
+    var offset = testCode.indexOf(search);
+    expect(offset, isNot(-1));
+    return offset;
+  }
+
+  /// Validates that the given [request] is handled successfully.
+  Response handleSuccessfulRequest(Request request, {RequestHandler handler}) {
+    handler ??= this.handler;
+    var response = handler.handleRequest(request);
+    expect(response, isResponseSuccess(request.id));
+    return response;
+  }
+
+  String modifyTestFile(String content) {
+    modifyFile(testFile, content);
+    testCode = content;
+    return testFile;
+  }
+
+  void processNotification(Notification notification) {
+    if (notification.event == SERVER_NOTIFICATION_ERROR) {
+      fail('${notification.toJson()}');
+    }
+  }
+
+  void removeGeneralAnalysisSubscription(GeneralAnalysisService service) {
+    generalServices.remove(service);
+    var request =
+        AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
+    handleSuccessfulRequest(request);
+  }
+
+  void setPriorityFiles(List<String> files) {
+    var request = AnalysisSetPriorityFilesParams(files).toRequest('0');
+    handleSuccessfulRequest(request);
+  }
+
+  void setUp() {
+    super.setUp();
+    serverChannel = MockServerChannel();
+    projectPath = convertPath(AbstractContextTest.testsPath);
+    testFolder = convertPath('${AbstractContextTest.testsPath}/bin');
+    testFile = convertPath('${AbstractContextTest.testsPath}/bin/test.dart');
+    pluginManager = TestPluginManager();
+    server = createAnalysisServer();
+    server.pluginManager = pluginManager;
+    handler = analysisHandler;
+    // listen for notifications
+    var notificationStream = serverChannel.notificationController.stream;
+    notificationStream.listen((Notification notification) {
+      processNotification(notification);
+    });
+  }
+
+  void tearDown() {
+    server.done();
+    handler = null;
+    server = null;
+    serverChannel = null;
+  }
+
+  /// Returns a [Future] that completes when the server's analysis is complete.
+  Future waitForTasksFinished() {
+    return server.onAnalysisComplete;
+  }
+
+  /// Completes with a successful [Response] for the given [request].
+  /// Otherwise fails.
+  Future<Response> waitResponse(Request request,
+      {bool throwOnError = true}) async {
+    return serverChannel.sendRequest(request, throwOnError: throwOnError);
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/info_builder_test.dart b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
new file mode 100644
index 0000000..a1490f0
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
@@ -0,0 +1,1368 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/info_builder.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'analysis_abstract.dart';
+import 'nnbd_migration_test_base.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BuildEnclosingMemberDescriptionTest);
+    defineReflectiveTests(InfoBuilderTest);
+  });
+}
+
+@reflectiveTest
+class BuildEnclosingMemberDescriptionTest extends AbstractAnalysisTest {
+  Future<ResolvedUnitResult> resolveTestFile() async {
+    var includedRoot = resourceProvider.pathContext.dirname(testFile);
+    server.setAnalysisRoots('0', [includedRoot], [], {});
+    return await server
+        .getAnalysisDriver(testFile)
+        .currentSession
+        .getResolvedUnit(testFile);
+  }
+
+  Future<void> test_classConstructor_named() async {
+    addTestFile(r'''
+class C {
+  C.aaa();
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    var constructor = class_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(constructor),
+        equals("the constructor 'C.aaa'"));
+  }
+
+  Future<void> test_classConstructor_unnamed() async {
+    addTestFile(r'''
+class C {
+  C();
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    var constructor = class_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(constructor),
+        equals("the default constructor of 'C'"));
+  }
+
+  Future<void> test_classField() async {
+    addTestFile(r'''
+class C {
+  int i;
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    FieldDeclaration fieldDeclaration =
+        class_.members.single as FieldDeclaration;
+    var field = fieldDeclaration.fields.variables[0];
+    expect(InfoBuilder.buildEnclosingMemberDescription(field),
+        equals("the field 'C.i'"));
+  }
+
+  Future<void> test_classField_from_type() async {
+    addTestFile(r'''
+class C {
+  int i;
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    FieldDeclaration fieldDeclaration =
+        class_.members.single as FieldDeclaration;
+    var type = fieldDeclaration.fields.type;
+    expect(InfoBuilder.buildEnclosingMemberDescription(type),
+        equals("the field 'C.i'"));
+  }
+
+  Future<void> test_classGetter() async {
+    addTestFile(r'''
+class C {
+  int get aaa => 7;
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    var getter = class_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(getter),
+        equals("the getter 'C.aaa'"));
+  }
+
+  Future<void> test_classMethod() async {
+    addTestFile(r'''
+class C {
+  int aaa() => 7;
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    var method = class_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(method),
+        equals("the method 'C.aaa'"));
+  }
+
+  Future<void> test_classOperator() async {
+    addTestFile(r'''
+class C {
+  bool operator ==(Object other) => false;
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    var operator = class_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(operator),
+        equals("the operator 'C.=='"));
+  }
+
+  Future<void> test_classSetter() async {
+    addTestFile(r'''
+class C {
+  void set aaa(value) {}
+}
+''');
+    var result = await resolveTestFile();
+    ClassDeclaration class_ =
+        result.unit.declarations.single as ClassDeclaration;
+    var setter = class_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(setter),
+        equals("the setter 'C.aaa='"));
+  }
+
+  Future<void> test_extensionMethod() async {
+    addTestFile(r'''
+extension E on List {
+  int aaa() => 7;
+}
+''');
+    var result = await resolveTestFile();
+    ExtensionDeclaration extension_ =
+        result.unit.declarations.single as ExtensionDeclaration;
+    var method = extension_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(method),
+        equals("the method 'E.aaa'"));
+  }
+
+  Future<void> test_extensionMethod_unnamed() async {
+    addTestFile(r'''
+extension on List {
+  int aaa() => 7;
+}
+''');
+    var result = await resolveTestFile();
+    ExtensionDeclaration extension_ =
+        result.unit.declarations.single as ExtensionDeclaration;
+    var method = extension_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(method),
+        equals("the method 'aaa' in unnamed extension on List<dynamic>"));
+  }
+
+  Future<void> test_mixinMethod() async {
+    addTestFile(r'''
+mixin C {
+  int aaa() => 7;
+}
+''');
+    var result = await resolveTestFile();
+    MixinDeclaration mixin_ =
+        result.unit.declarations.single as MixinDeclaration;
+    var method = mixin_.members.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(method),
+        equals("the method 'C.aaa'"));
+  }
+
+  Future<void> test_topLevelFunction() async {
+    addTestFile(r'''
+void aaa(value) {}
+''');
+    var result = await resolveTestFile();
+    var function = result.unit.declarations.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(function),
+        equals("the function 'aaa'"));
+  }
+
+  Future<void> test_topLevelGetter() async {
+    addTestFile(r'''
+int get aaa => 7;
+''');
+    var result = await resolveTestFile();
+    var getter = result.unit.declarations.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(getter),
+        equals("the getter 'aaa'"));
+  }
+
+  Future<void> test_topLevelSetter() async {
+    addTestFile(r'''
+void set aaa(value) {}
+''');
+    var result = await resolveTestFile();
+    var setter = result.unit.declarations.single;
+    expect(InfoBuilder.buildEnclosingMemberDescription(setter),
+        equals("the setter 'aaa='"));
+  }
+
+  Future<void> test_topLevelVariable() async {
+    addTestFile(r'''
+int i;
+''');
+    var result = await resolveTestFile();
+    TopLevelVariableDeclaration topLevelVariableDeclaration =
+        result.unit.declarations.single as TopLevelVariableDeclaration;
+    var variable = topLevelVariableDeclaration.variables.variables[0];
+    expect(InfoBuilder.buildEnclosingMemberDescription(variable),
+        equals("the variable 'i'"));
+  }
+
+  Future<void> test_topLevelVariable_from_type() async {
+    addTestFile(r'''
+int i;
+''');
+    var result = await resolveTestFile();
+    TopLevelVariableDeclaration topLevelVariableDeclaration =
+        result.unit.declarations.single as TopLevelVariableDeclaration;
+    var type = topLevelVariableDeclaration.variables.type;
+    expect(InfoBuilder.buildEnclosingMemberDescription(type),
+        equals("the variable 'i'"));
+  }
+}
+
+@reflectiveTest
+class InfoBuilderTest extends NnbdMigrationTestBase {
+  /// Assert various properties of the given [edit].
+  bool assertEdit(
+      {@required EditDetail edit, int offset, int length, String replacement}) {
+    expect(edit, isNotNull);
+    if (offset != null) {
+      expect(edit.offset, offset);
+    }
+    if (length != null) {
+      expect(edit.length, length);
+    }
+    if (replacement != null) {
+      expect(edit.replacement, replacement);
+    }
+    return true;
+  }
+
+  List<RegionInfo> getNonInformativeRegions(List<RegionInfo> regions) {
+    return regions
+        .where((region) =>
+            region.kind != NullabilityFixKind.typeNotMadeNullable &&
+            region.kind != NullabilityFixKind.typeNotMadeNullableDueToHint)
+        .toList();
+  }
+
+  Future<void> test_addLate() async {
+    var content = '''
+f() {
+  String s;
+  if (1 == 2) s = "Hello";
+  g(s);
+}
+g(String /*!*/ s) {}
+''';
+    var migratedContent = '''
+f() {
+  late String  s;
+  if (1 == 2) s = "Hello";
+  g(s);
+}
+g(String /*!*/ s) {}
+''';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(2));
+    var region = regions[0];
+    assertRegion(
+        region: region,
+        offset: 8,
+        length: 4,
+        explanation: 'Added a late keyword',
+        kind: NullabilityFixKind.addLate);
+  }
+
+  Future<void> test_addLate_dueToHint() async {
+    var content = '/*late*/ int x = 0;';
+    var migratedContent = '/*late*/ int  x = 0;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(2));
+    var textToRemove = '/*late*/ ';
+    assertRegionPair(regions, 0,
+        offset1: migratedContent.indexOf('/*'),
+        length1: 2,
+        offset2: migratedContent.indexOf('*/'),
+        length2: 2,
+        explanation: 'Added a late keyword, due to a hint',
+        kind: NullabilityFixKind.addLateDueToHint,
+        edits: (List<EditDetail> edits) => assertEdit(
+            edit: edits.single,
+            offset: content.indexOf(textToRemove),
+            length: textToRemove.length,
+            replacement: ''));
+  }
+
+  Future<void> test_addLate_dueToTestSetup() async {
+    addTestCorePackage();
+    var content = '''
+import 'package:test/test.dart';
+void main() {
+  int i;
+  setUp(() {
+    i = 1;
+  });
+  test('a', () {
+    f(i);
+  });
+  f(int /*?*/ i) {}
+}
+''';
+    var migratedContent = '''
+import 'package:test/test.dart';
+void main() {
+  late int  i;
+  setUp(() {
+    i = 1;
+  });
+  test('a', () {
+    f(i);
+  });
+  f(int /*?*/ i) {}
+}
+''';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(3));
+    var region = regions[0];
+    assertRegion(
+        region: region,
+        offset: 49,
+        length: 4,
+        explanation: 'Added a late keyword, due to assignment in `setUp`',
+        kind: NullabilityFixKind.addLateDueToTestSetup);
+  }
+
+  Future<void> test_compound_assignment_nullable_result() async {
+    var unit = await buildInfoForSingleTestFile('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+void f(C/*!*/ a, int b) {
+  a += b;
+}
+''', migratedContent: '''
+abstract class C {
+  C/*?*/ operator+(int  i);
+}
+void f(C/*!*/ a, int  b) {
+  a += b;
+}
+''');
+    var operator = '+=';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation: 'Compound assignment has bad combined type',
+        kind: NullabilityFixKind.compoundAssignmentHasBadCombinedType,
+        edits: isEmpty);
+  }
+
+  Future<void> test_compound_assignment_nullable_source() async {
+    var unit = await buildInfoForSingleTestFile('''
+void f(int/*?*/ a, int b) {
+  a += b;
+}
+''', migratedContent: '''
+void f(int/*?*/ a, int  b) {
+  a += b;
+}
+''');
+    var operator = '+=';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation: 'Compound assignment has nullable source',
+        kind: NullabilityFixKind.compoundAssignmentHasNullableSource,
+        edits: isEmpty);
+  }
+
+  Future<void> test_conditionFalseInStrongMode_expression() async {
+    var unit = await buildInfoForSingleTestFile(
+        'int f(String s) => s == null ? 0 : s.length;',
+        migratedContent:
+            'int  f(String  s) => s == null /* == false */ ? 0 : s.length;',
+        warnOnWeakCode: true);
+    var insertedComment = '/* == false */';
+    var insertedCommentOffset = unit.content.indexOf(insertedComment);
+    var region = unit.regions
+        .where((region) => region.offset == insertedCommentOffset)
+        .single;
+    assertRegion(
+        region: region,
+        length: insertedComment.length,
+        explanation: 'Condition will always be false in strong checking mode',
+        kind: NullabilityFixKind.conditionFalseInStrongMode,
+        edits: isEmpty);
+  }
+
+  Future<void> test_conditionFalseInStrongMode_if() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(String s) {
+  if (s == null) {
+    return 0;
+  } else {
+    return s.length;
+  }
+}
+''', migratedContent: '''
+int  f(String  s) {
+  if (s == null /* == false */) {
+    return 0;
+  } else {
+    return s.length;
+  }
+}
+''', warnOnWeakCode: true);
+    var insertedComment = '/* == false */';
+    var insertedCommentOffset = unit.content.indexOf(insertedComment);
+    var region = unit.regions
+        .where((region) => region.offset == insertedCommentOffset)
+        .single;
+    assertRegion(
+        region: region,
+        length: insertedComment.length,
+        explanation: 'Condition will always be false in strong checking mode',
+        kind: NullabilityFixKind.conditionFalseInStrongMode,
+        edits: isEmpty);
+  }
+
+  Future<void> test_conditionTrueInStrongMode_expression() async {
+    var unit = await buildInfoForSingleTestFile(
+        'int f(String s) => s != null ? s.length : 0;',
+        migratedContent:
+            'int  f(String  s) => s != null /* == true */ ? s.length : 0;',
+        warnOnWeakCode: true);
+    var insertedComment = '/* == true */';
+    var insertedCommentOffset = unit.content.indexOf(insertedComment);
+    var region = unit.regions
+        .where((region) => region.offset == insertedCommentOffset)
+        .single;
+    assertRegion(
+        region: region,
+        length: insertedComment.length,
+        explanation: 'Condition will always be true in strong checking mode',
+        kind: NullabilityFixKind.conditionTrueInStrongMode,
+        edits: isEmpty);
+  }
+
+  Future<void> test_conditionTrueInStrongMode_if() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(String s) {
+  if (s != null) {
+    return s.length;
+  } else {
+    return 0;
+  }
+}
+''', migratedContent: '''
+int  f(String  s) {
+  if (s != null /* == true */) {
+    return s.length;
+  } else {
+    return 0;
+  }
+}
+''', warnOnWeakCode: true);
+    var insertedComment = '/* == true */';
+    var insertedCommentOffset = unit.content.indexOf(insertedComment);
+    var region = unit.regions
+        .where((region) => region.offset == insertedCommentOffset)
+        .single;
+    assertRegion(
+        region: region,
+        length: insertedComment.length,
+        explanation: 'Condition will always be true in strong checking mode',
+        kind: NullabilityFixKind.conditionTrueInStrongMode,
+        edits: isEmpty);
+  }
+
+  Future<void> test_discardCondition() async {
+    var unit = await buildInfoForSingleTestFile('''
+void g(int i) {
+  print(i.isEven);
+  if (i != null) print('NULL');
+}
+''', migratedContent: '''
+void g(int  i) {
+  print(i.isEven);
+  /* if (i != null) */ print('NULL');
+}
+''');
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(2));
+    assertRegion(
+        region: regions[0],
+        offset: 38,
+        length: 3,
+        kind: NullabilityFixKind.removeDeadCode);
+    assertRegion(
+        region: regions[1],
+        offset: 56,
+        length: 3,
+        kind: NullabilityFixKind.removeDeadCode);
+  }
+
+  Future<void> test_downcast_nonNullable() async {
+    var content = 'int/*!*/ f(num/*!*/ n) => n;';
+    var migratedContent = 'int/*!*/ f(num/*!*/ n) => n as int;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = getNonInformativeRegions(unit.regions);
+    expect(regions, hasLength(1));
+    var region = regions.single;
+    var regionTarget = ' as int';
+    assertRegion(
+        region: region,
+        offset: migratedContent.indexOf(regionTarget),
+        length: regionTarget.length,
+        kind: NullabilityFixKind.downcastExpression,
+        edits: isEmpty,
+        traces: isEmpty);
+  }
+
+  Future<void> test_downcast_nonNullable_to_nullable() async {
+    var content = 'int/*?*/ f(num/*!*/ n) => n;';
+    // TODO(paulberry): we should actually cast to `int`, not `int?`, because we
+    // know `n` is non-nullable.
+    var migratedContent = 'int/*?*/ f(num/*!*/ n) => n as int?;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = getNonInformativeRegions(unit.regions);
+    var regionTarget = ' as int?';
+    var offset = migratedContent.indexOf(regionTarget);
+    var region = regions.where((region) => region.offset == offset).single;
+    // TODO(paulberry): once we are correctly casting to `int`, not `int?`, this
+    // should be classified as a downcast.  Currently it's classified as a side
+    // cast.
+    assertRegion(
+        region: region,
+        offset: offset,
+        length: regionTarget.length,
+        kind: NullabilityFixKind.otherCastExpression,
+        edits: isEmpty,
+        traces: isEmpty);
+  }
+
+  Future<void> test_downcast_nullable() async {
+    var content = 'int/*?*/ f(num/*?*/ n) => n;';
+    var migratedContent = 'int/*?*/ f(num/*?*/ n) => n as int?;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = getNonInformativeRegions(unit.regions);
+    var regionTarget = ' as int?';
+    var offset = migratedContent.indexOf(regionTarget);
+    var region = regions.where((region) => region.offset == offset).single;
+    assertRegion(
+        region: region,
+        offset: offset,
+        length: regionTarget.length,
+        kind: NullabilityFixKind.downcastExpression,
+        edits: isEmpty,
+        traces: isEmpty);
+  }
+
+  Future<void> test_downcast_nullable_to_nonNullable() async {
+    var content = 'int/*!*/ f(num/*?*/ n) => n;';
+    var migratedContent = 'int/*!*/ f(num/*?*/ n) => n as int;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = getNonInformativeRegions(unit.regions);
+    var regionTarget = ' as int';
+    var offset = migratedContent.indexOf(regionTarget);
+    var region = regions.where((region) => region.offset == offset).single;
+    assertRegion(
+        region: region,
+        offset: offset,
+        length: regionTarget.length,
+        kind: NullabilityFixKind.downcastExpression,
+        edits: isEmpty,
+        traces: isNotEmpty);
+  }
+
+  Future<void> test_downcast_with_traces() async {
+    var content = 'List<int/*!*/>/*!*/ f(List<int/*?*/>/*?*/ x) => x;';
+    var migratedContent =
+        'List<int/*!*/>/*!*/ f(List<int/*?*/>/*?*/ x) => x as List<int>;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.regions.where(
+        (region) => region.kind == NullabilityFixKind.downcastExpression);
+    expect(regions, hasLength(1));
+    var region = regions.single;
+    var regionTarget = ' as List<int>';
+    assertRegion(
+        region: region,
+        offset: migratedContent.indexOf(regionTarget),
+        length: regionTarget.length,
+        kind: NullabilityFixKind.downcastExpression,
+        edits: isEmpty,
+        traces: isNotEmpty);
+    var traceDescriptionToOffset = {
+      for (var trace in region.traces)
+        trace.description: trace.entries[0].target.offset
+    };
+    expect(traceDescriptionToOffset, {
+      'Nullability reason': content.indexOf('List<int/*?*/>/*?*/'),
+      'Non-nullability reason': content.indexOf('List<int/*!*/>/*!*/'),
+      'Nullability reason for type argument 0': content.indexOf('int/*?*/'),
+      'Non-nullability reason for type argument 0': content.indexOf('int/*!*/')
+    });
+  }
+
+  Future<void> test_dynamicValueIsUsed() async {
+    var unit = await buildInfoForSingleTestFile('''
+bool f(int i) {
+  if (i == null) return true;
+  else return false;
+}
+void g() {
+  dynamic i = null;
+  f(i);
+}
+''', migratedContent: '''
+bool  f(int? i) {
+  if (i == null) return true;
+  else return false;
+}
+void g() {
+  dynamic i = null;
+  f(i);
+}
+''');
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(1));
+    var region = regions[0];
+    var edits = region.edits;
+    assertRegion(
+        region: region,
+        offset: 11,
+        explanation: "Changed type 'int' to be nullable");
+    assertEdit(edit: edits[0], offset: 10, replacement: '/*!*/');
+    assertEdit(edit: edits[1], offset: 10, replacement: '/*?*/');
+  }
+
+  Future<void> test_expressionFunctionReturnTarget() async {
+    var unit = await buildInfoForSingleTestFile('''
+String g() => 1 == 2 ? "Hello" : null;
+''', migratedContent: '''
+String? g() => 1 == 2 ? "Hello" : null;
+''');
+    assertInTargets(targets: unit.targets, offset: 7, length: 1); // "g"
+    var regions = unit.regions;
+    expect(regions, hasLength(1));
+    assertRegion(
+        region: regions[0],
+        offset: 6,
+        explanation: "Changed type 'String' to be nullable");
+  }
+
+  Future<void> test_increment_nullable_result() async {
+    var unit = await buildInfoForSingleTestFile('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+void f(C/*!*/ a) {
+  a++;
+}
+''', migratedContent: '''
+abstract class C {
+  C/*?*/ operator+(int  i);
+}
+void f(C/*!*/ a) {
+  a++;
+}
+''');
+    var operator = '++';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation: 'Compound assignment has bad combined type',
+        kind: NullabilityFixKind.compoundAssignmentHasBadCombinedType,
+        edits: isEmpty);
+  }
+
+  Future<void> test_increment_nullable_source() async {
+    var unit = await buildInfoForSingleTestFile('''
+void f(int/*?*/ a) {
+  a++;
+}
+''', migratedContent: '''
+void f(int/*?*/ a) {
+  a++;
+}
+''');
+    var operator = '++';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation: 'Compound assignment has nullable source',
+        kind: NullabilityFixKind.compoundAssignmentHasNullableSource,
+        edits: isEmpty);
+  }
+
+  Future<void> test_insertedRequired_fieldFormal() async {
+    var unit = await buildInfoForSingleTestFile('''
+class C {
+  int level;
+  int level2;
+  C({this.level}) : this.level2 = level + 1;
+}
+''', migratedContent: '''
+class C {
+  int  level;
+  int  level2;
+  C({required this.level}) : this.level2 = level + 1;
+}
+''');
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(1));
+    var region = regions[0];
+    var edits = region.edits;
+    assertRegion(
+        region: region,
+        offset: 44,
+        length: 9,
+        explanation: "Add 'required' keyword to parameter 'level' in 'C.'",
+        kind: NullabilityFixKind.addRequired);
+    assertEdit(
+        edit: edits[0], offset: 42, length: 0, replacement: '@required ');
+  }
+
+  Future<void> test_insertedRequired_parameter() async {
+    var unit = await buildInfoForSingleTestFile('''
+class C {
+  int level = 0;
+  bool f({int lvl}) => lvl >= level;
+}
+''', migratedContent: '''
+class C {
+  int  level = 0;
+  bool  f({required int  lvl}) => lvl >= level;
+}
+''');
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(1));
+    var region = regions[0];
+    var edits = region.edits;
+    assertRegion(
+        region: region,
+        offset: 39,
+        length: 9,
+        explanation: "Add 'required' keyword to parameter 'lvl' in 'C.f'",
+        kind: NullabilityFixKind.addRequired);
+    assertEdit(
+        edit: edits[0], offset: 37, length: 0, replacement: '@required ');
+  }
+
+  Future<void> test_insertParens() async {
+    var originalContent = '''
+class C {
+  C operator+(C c) => null;
+}
+C/*!*/ _f(C c) => c + c;
+''';
+    var migratedContent = '''
+class C {
+  C? operator+(C  c) => null;
+}
+C/*!*/ _f(C  c) => (c + c)!;
+''';
+    var unit = await buildInfoForSingleTestFile(originalContent,
+        migratedContent: migratedContent);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(3));
+    assertRegion(
+        region: regions[0],
+        offset: migratedContent.indexOf('? operator'),
+        length: 1,
+        explanation: "Changed type 'C' to be nullable");
+    assertRegion(
+        region: regions[1],
+        offset: migratedContent.indexOf('/*!*/'),
+        length: 5,
+        explanation: "Type 'C' was not made nullable due to a hint",
+        kind: NullabilityFixKind.typeNotMadeNullableDueToHint);
+    assertRegion(
+        region: regions[2],
+        offset: migratedContent.indexOf('!;'),
+        length: 1,
+        explanation: 'Added a non-null assertion to nullable expression',
+        kind: NullabilityFixKind.checkExpression);
+  }
+
+  void test_nullAwareAssignment_remove() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(int/*!*/ x, int y) => x ??= y;
+''', migratedContent: '''
+int  f(int/*!*/ x, int  y) => x ??= y;
+''', warnOnWeakCode: false, removeViaComments: false);
+    var codeToRemove = ' ??= y';
+    var removalOffset = unit.content.indexOf(codeToRemove);
+    var region =
+        unit.regions.where((region) => region.offset == removalOffset).single;
+    assertRegion(
+        region: region,
+        length: codeToRemove.length,
+        explanation:
+            'Removed a null-aware assignment, because the target cannot be '
+            'null',
+        kind: NullabilityFixKind.removeDeadCode,
+        edits: isEmpty);
+  }
+
+  void test_nullAwareAssignment_unnecessaryInStrongMode() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(int/*!*/ x, int y) => x ??= y;
+''', migratedContent: '''
+int  f(int/*!*/ x, int  y) => x ??= y;
+''', warnOnWeakCode: true);
+    var operator = '??=';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation:
+            'Null-aware assignment will be unnecessary in strong checking mode',
+        kind: NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode,
+        edits: isEmpty);
+  }
+
+  void test_nullAwarenessUnnecessaryInStrongMode() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(String s) => s?.length;
+''', migratedContent: '''
+int  f(String  s) => s?.length;
+''', warnOnWeakCode: true);
+    var question = '?';
+    var questionOffset = unit.content.indexOf(question);
+    var region =
+        unit.regions.where((region) => region.offset == questionOffset).single;
+    assertRegion(
+        region: region,
+        length: question.length,
+        explanation:
+            'Null-aware access will be unnecessary in strong checking mode',
+        kind: NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode,
+        edits: isEmpty);
+  }
+
+  Future<void> test_nullCheck_dueToHint() async {
+    var content = 'int f(int/*?*/ x) => x/*!*/;';
+    var migratedContent = 'int  f(int/*?*/ x) => x/*!*/;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(4));
+    assertRegionPair(regions, 0,
+        kind: NullabilityFixKind.makeTypeNullableDueToHint);
+    var hintText = '/*!*/';
+    assertRegionPair(regions, 2,
+        offset1: migratedContent.indexOf(hintText),
+        length1: 2,
+        offset2: migratedContent.indexOf(hintText) + 3,
+        length2: 2,
+        explanation: 'Accepted a null check hint',
+        kind: NullabilityFixKind.checkExpressionDueToHint,
+        traces: isNotEmpty,
+        edits: ((List<EditDetail> edits) => assertEdit(
+            edit: edits.single,
+            offset: content.indexOf(hintText),
+            length: hintText.length,
+            replacement: '')));
+  }
+
+  Future<void> test_nullCheck_onMemberAccess() async {
+    var unit = await buildInfoForSingleTestFile('''
+class C {
+  int value;
+  C([this.value]);
+  void f() {
+    value.sign;
+  }
+}
+''', migratedContent: '''
+class C {
+  int? value;
+  C([this.value]);
+  void f() {
+    value!.sign;
+  }
+}
+''');
+    var regions = unit.regions;
+    expect(regions, hasLength(2));
+    // regions[0] is `int?`.
+    var region = regions[1];
+    var edits = region.edits;
+    assertRegion(
+        region: regions[1],
+        offset: 65,
+        explanation: 'Added a non-null assertion to nullable expression',
+        kind: NullabilityFixKind.checkExpression);
+    assertEdit(edit: edits[0], offset: 64, length: 0, replacement: '/*!*/');
+  }
+
+  Future<void> test_parameter_fromOverriddenField_explicit() async {
+    var unit = await buildInfoForSingleTestFile('''
+class A {
+  int m;
+}
+class B extends A {
+  void set m(Object p) {}
+}
+void f(A a) => a.m = null;
+''', migratedContent: '''
+class A {
+  int? m;
+}
+class B extends A {
+  void set m(Object? p) {}
+}
+void f(A  a) => a.m = null;
+''');
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(2));
+    assertRegion(
+        region: regions[0],
+        offset: 15,
+        explanation: "Changed type 'int' to be nullable");
+    assertRegion(
+        region: regions[1],
+        offset: 61,
+        explanation: "Changed type 'Object' to be nullable");
+
+    expect(regions[0].traces, hasLength(1));
+    var trace = regions[0].traces.first;
+    expect(trace.description, 'Nullability reason');
+    var entries = trace.entries;
+    expect(entries, hasLength(2));
+    // Entry 0 is the nullability of the type of A.m.
+    // TODO(srawlins): "A" is probably incorrect here. Should be "A.m".
+    assertTraceEntry(unit, entries[0], 'A', unit.content.indexOf('int?'),
+        contains('explicit type'));
+  }
+
+  Future<void> test_removal_handles_offsets_correctly() async {
+    var originalContent = '''
+void f(num n, int/*?*/ i) {
+  if (n is! int) return;
+  print((n as int).isEven);
+  print(i + 1);
+}
+''';
+    // Note: even though `as int` is removed, it still shows up in the
+    // preview, since we show deleted text.
+    var migratedContent = '''
+void f(num  n, int/*?*/ i) {
+  if (n is! int ) return;
+  print((n as int).isEven);
+  print(i! + 1);
+}
+''';
+    var unit = await buildInfoForSingleTestFile(originalContent,
+        migratedContent: migratedContent, removeViaComments: false);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(4));
+    assertRegionPair(regions, 0,
+        kind: NullabilityFixKind.makeTypeNullableDueToHint);
+    assertRegion(
+        region: regions[2],
+        offset: migratedContent.indexOf(' as int'),
+        length: ' as int'.length,
+        explanation: 'Discarded a downcast that is now unnecessary',
+        kind: NullabilityFixKind.removeAs);
+    assertRegion(
+        region: regions[3],
+        offset: migratedContent.indexOf('! + 1'),
+        explanation: 'Added a non-null assertion to nullable expression',
+        kind: NullabilityFixKind.checkExpression);
+  }
+
+  Future<void> test_returnDetailTarget() async {
+    var unit = await buildInfoForSingleTestFile('''
+String g() {
+  return 1 == 2 ? "Hello" : null;
+}
+''', migratedContent: '''
+String? g() {
+  return 1 == 2 ? "Hello" : null;
+}
+''');
+    assertInTargets(targets: unit.targets, offset: 7, length: 1); // "g"
+    var regions = unit.regions;
+    expect(regions, hasLength(1));
+    assertRegion(
+        region: regions[0],
+        offset: 6,
+        explanation: "Changed type 'String' to be nullable");
+  }
+
+  Future<void> test_suspicious_cast() async {
+    var content = '''
+int f(Object o) {
+  if (o is! String) return 0;
+  return o;
+}
+''';
+    var migratedContent = '''
+int  f(Object  o) {
+  if (o is! String ) return 0;
+  return o as int;
+}
+''';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = getNonInformativeRegions(unit.regions);
+    expect(regions, hasLength(1));
+    var region = regions.single;
+    var regionTarget = ' as int';
+    assertRegion(
+        region: region,
+        offset: migratedContent.indexOf(regionTarget),
+        length: regionTarget.length,
+        kind: NullabilityFixKind.otherCastExpression,
+        edits: isEmpty);
+  }
+
+  Future<void> test_trace_deadCode() async {
+    var unit = await buildInfoForSingleTestFile('''
+void f(int/*!*/ i) {
+  if (i == null) return;
+}
+''', migratedContent: '''
+void f(int/*!*/ i) {
+  /* if (i == null) return; */
+}
+''');
+    var region = unit.regions
+        .where(
+            (regionInfo) => regionInfo.offset == unit.content.indexOf('/* if'))
+        .single;
+    expect(region.traces, hasLength(1));
+    var trace = region.traces.single;
+    expect(trace.description, 'Non-nullability reason');
+    var entries = trace.entries;
+    expect(entries, hasLength(3));
+    // Entry 0 is the nullability of f's argument
+    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int'),
+        contains('parameter 0 of f'));
+    // Entry 1 is the edge from f's argument to never, due to the `/*!*/` hint.
+    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int'),
+        'explicitly hinted to be non-nullable');
+    // Entry 2 is the "never" node.
+    // TODO(paulberry): this node provides no additional useful information and
+    // shouldn't be included in the trace.
+    expect(entries[2].description, 'never');
+    expect(entries[2].function, null);
+    expect(entries[2].target, null);
+  }
+
+  Future<void> test_trace_nullableType() async {
+    var unit = await buildInfoForSingleTestFile('''
+void f(int i) {} // f
+void g(int i) { // g
+  f(i);
+}
+void h() {
+  g(null);
+}
+''', migratedContent: '''
+void f(int? i) {} // f
+void g(int? i) { // g
+  f(i);
+}
+void h() {
+  g(null);
+}
+''');
+    var region = unit.regions
+        .where((regionInfo) =>
+            regionInfo.offset == unit.content.indexOf('? i) {} // f'))
+        .single;
+    expect(region.traces, hasLength(1));
+    var trace = region.traces.single;
+    expect(trace.description, 'Nullability reason');
+    var entries = trace.entries;
+    expect(entries, hasLength(6));
+    // Entry 0 is the nullability of f's argument
+    assertTraceEntry(unit, entries[0], 'f',
+        unit.content.indexOf('int? i) {} // f'), contains('parameter 0 of f'));
+    // Entry 1 is the edge from g's argument to f's argument, due to g's call to
+    // f.
+    assertTraceEntry(
+        unit, entries[1], 'g', unit.content.indexOf('i);'), 'data flow');
+    // Entry 2 is the nullability of g's argument
+    assertTraceEntry(unit, entries[2], 'g',
+        unit.content.indexOf('int? i) { // g'), contains('parameter 0 of g'));
+    // Entry 3 is the edge from null to g's argument, due to h's call to g.
+    assertTraceEntry(
+        unit, entries[3], 'h', unit.content.indexOf('null'), 'data flow');
+    // Entry 4 is the nullability of the null literal.
+    assertTraceEntry(unit, entries[4], 'h', unit.content.indexOf('null'),
+        contains('null literal'));
+    // Entry 5 is the edge from always to null.
+    // TODO(paulberry): this edge provides no additional useful information and
+    // shouldn't be included in the trace.
+    assertTraceEntry(unit, entries[5], 'h', unit.content.indexOf('null'),
+        'literal expression');
+  }
+
+  Future<void> test_trace_nullCheck() async {
+    var unit = await buildInfoForSingleTestFile('int f(int/*?*/ i) => i + 1;',
+        migratedContent: 'int  f(int/*?*/ i) => i! + 1;');
+    var region = unit.regions
+        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('! +'))
+        .single;
+    expect(region.traces, hasLength(1));
+    var trace = region.traces.single;
+    expect(trace.description, 'Nullability reason');
+    var entries = trace.entries;
+    expect(entries, hasLength(2));
+    // Entry 0 is the nullability of the type of i.
+    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int/*?*/'),
+        contains('parameter 0 of f'));
+    // Entry 1 is the edge from always to the type of i.
+    // TODO(paulberry): this edge provides no additional useful information and
+    // shouldn't be included in the trace.
+    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int/*?*/'),
+        'explicitly hinted to be nullable');
+  }
+
+  Future<void> test_trace_nullCheck_notNullableReason() async {
+    var unit = await buildInfoForSingleTestFile('''
+void f(int i) { // f
+  assert(i != null);
+}
+void g(int i) { // g
+  f(i); // call f
+}
+void h(int/*?*/ i) {
+  g(i);
+}
+''', migratedContent: '''
+void f(int  i) { // f
+  assert(i != null);
+}
+void g(int  i) { // g
+  f(i); // call f
+}
+void h(int/*?*/ i) {
+  g(i!);
+}
+''');
+    var region = unit.regions
+        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('!)'))
+        .single;
+    expect(region.traces, hasLength(2));
+    // Trace 0 is the nullability reason; we don't care about that right now.
+    // Trace 1 is the non-nullability reason.
+    var trace = region.traces[1];
+    expect(trace.description, 'Non-nullability reason');
+    var entries = trace.entries;
+    expect(entries, hasLength(5));
+    // Entry 0 is the nullability of g's argument
+    assertTraceEntry(unit, entries[0], 'g',
+        unit.content.indexOf('int  i) { // g'), contains('parameter 0 of g'));
+    // Entry 1 is the edge from g's argument to f's argument, due to g's call to
+    // f.
+    assertTraceEntry(unit, entries[1], 'g',
+        unit.content.indexOf('i); // call f'), 'data flow');
+    // Entry 2 is the nullability of f's argument
+    assertTraceEntry(unit, entries[2], 'f',
+        unit.content.indexOf('int  i) { // f'), contains('parameter 0 of f'));
+    // Entry 3 is the edge f's argument to never, due to the assert.
+    assertTraceEntry(unit, entries[3], 'f', unit.content.indexOf('assert'),
+        'value asserted to be non-null');
+    // Entry 4 is the "never" node.
+    // TODO(paulberry): this node provides no additional useful information and
+    // shouldn't be included in the trace.
+    expect(entries[4].description, 'never');
+    expect(entries[4].function, null);
+    expect(entries[4].target, null);
+  }
+
+  Future<void> test_trace_nullCheckHint() async {
+    var unit = await buildInfoForSingleTestFile('int f(int/*?*/ i) => i/*!*/;',
+        migratedContent: 'int  f(int/*?*/ i) => i/*!*/;');
+    var region = unit.regions
+        .where(
+            (regionInfo) => regionInfo.offset == unit.content.indexOf('/*!*/'))
+        .single;
+    expect(region.traces, hasLength(1));
+    var trace = region.traces.single;
+    expect(trace.description, 'Reason');
+    expect(trace.entries, hasLength(1));
+    assertTraceEntry(unit, trace.entries.single, 'f',
+        unit.content.indexOf('i/*!*/'), 'Null check hint');
+  }
+
+  Future<void> test_trace_substitutionNode() async {
+    var unit = await buildInfoForSingleTestFile('''
+class C<T extends Object/*!*/> {}
+
+C<int /*?*/ > c;
+
+Map<int, String> x = {};
+String/*!*/ y = x[0];
+''', migratedContent: '''
+class C<T extends Object/*!*/> {}
+
+C<int /*?*/ >? c;
+
+Map<int , String >  x = {};
+String/*!*/ y = x[0]!;
+''');
+    var region = unit.regions
+        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('!;'))
+        .single;
+    // The "why nullable" node associated with adding the `!` is a substitution
+    // node, and we don't currently generate a trace for a substitution node.
+    // TODO(paulberry): fix this.
+    // We do, however, generate a trace for "why not nullable".
+    expect(region.traces, hasLength(1));
+    expect(region.traces[0].description, 'Non-nullability reason');
+  }
+
+  Future<void> test_type_made_nullable() async {
+    var unit = await buildInfoForSingleTestFile('''
+String g() => 1 == 2 ? "Hello" : null;
+''', migratedContent: '''
+String? g() => 1 == 2 ? "Hello" : null;
+''');
+    assertInTargets(targets: unit.targets, offset: 7, length: 1); // "g"
+    var regions = unit.regions;
+    expect(regions, hasLength(1));
+    assertRegion(
+        region: regions[0],
+        offset: 6,
+        explanation: "Changed type 'String' to be nullable");
+  }
+
+  Future<void> test_type_made_nullable_due_to_hint() async {
+    var content = 'int/*?*/ x = 0;';
+    var migratedContent = 'int/*?*/ x = 0;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.fixRegions;
+    expect(regions, hasLength(2));
+    var textToRemove = '/*?*/';
+    assertRegionPair(regions, 0,
+        offset1: migratedContent.indexOf(textToRemove),
+        length1: 2,
+        offset2: migratedContent.indexOf(textToRemove) + 3,
+        length2: 2,
+        explanation:
+            "Changed type 'int' to be nullable, due to a nullability hint",
+        kind: NullabilityFixKind.makeTypeNullableDueToHint,
+        traces: isNotNull, edits: (List<EditDetail> edits) {
+      expect(edits, hasLength(2));
+      var editsByDescription = {for (var edit in edits) edit.description: edit};
+      assertEdit(
+          edit: editsByDescription['Change to /*!*/ hint'],
+          offset: content.indexOf(textToRemove),
+          length: textToRemove.length,
+          replacement: '/*!*/');
+      assertEdit(
+          edit: editsByDescription['Remove /*?*/ hint'],
+          offset: content.indexOf(textToRemove),
+          length: textToRemove.length,
+          replacement: '');
+      return true;
+    });
+  }
+
+  Future<void> test_type_not_made_nullable() async {
+    var unit = await buildInfoForSingleTestFile('int i = 0;',
+        migratedContent: 'int  i = 0;');
+    var region = unit.regions
+        .where((regionInfo) => regionInfo.offset == unit.content.indexOf('  i'))
+        .single;
+    expect(region.length, 1);
+    expect(region.lineNumber, 1);
+    expect(region.explanation, "Type 'int' was not made nullable");
+    expect(region.edits.map((edit) => edit.description).toSet(),
+        {'Add /*?*/ hint', 'Add /*!*/ hint'});
+    expect(region.traces, isEmpty);
+    expect(region.kind, NullabilityFixKind.typeNotMadeNullable);
+  }
+
+  Future<void> test_type_not_made_nullable_due_to_hint() async {
+    var content = 'int/*!*/ i = 0;';
+    var migratedContent = 'int/*!*/ i = 0;';
+    var unit = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    var regions = unit.regions;
+    expect(regions, hasLength(1));
+    var textToRemove = '/*!*/';
+    assertRegion(
+        region: regions[0],
+        offset: migratedContent.indexOf(textToRemove),
+        length: 5,
+        explanation: "Type 'int' was not made nullable due to a hint",
+        kind: NullabilityFixKind.typeNotMadeNullableDueToHint,
+        traces: isNotNull,
+        edits: (List<EditDetail> edits) {
+          expect(edits, hasLength(2));
+          var editsByDescription = {
+            for (var edit in edits) edit.description: edit
+          };
+          assertEdit(
+              edit: editsByDescription['Change to /*?*/ hint'],
+              offset: content.indexOf(textToRemove),
+              length: textToRemove.length,
+              replacement: '/*?*/');
+          assertEdit(
+              edit: editsByDescription['Remove /*!*/ hint'],
+              offset: content.indexOf(textToRemove),
+              length: textToRemove.length,
+              replacement: '');
+          return true;
+        });
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/instrumentation_renderer_test.dart b/pkg/nnbd_migration/test/front_end/instrumentation_renderer_test.dart
new file mode 100644
index 0000000..5c456f8
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/instrumentation_renderer_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/instrumentation_renderer.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'nnbd_migration_test_base.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InstrumentationRendererTest);
+  });
+}
+
+@reflectiveTest
+class InstrumentationRendererTest extends NnbdMigrationTestBase {
+  /// Render the instrumentation view for [files].
+  Future<String> renderViewForTestFiles(Map<String, String> files,
+      {bool applied = false, bool needsRerun = false}) async {
+    var packageRoot = convertPath('/project');
+    await buildInfoForTestFiles(files, includedRoot: packageRoot);
+    var migrationInfo =
+        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
+    var instrumentationRenderer = InstrumentationRenderer(
+        migrationInfo, PathMapper(resourceProvider), applied, needsRerun);
+    return instrumentationRenderer.render();
+  }
+
+  Future<void> test_appliedStyle() async {
+    var renderedView = await renderViewForTestFiles(
+        {convertPath('/project/lib/a.dart'): 'int a = null;'},
+        applied: true);
+    // harmless space in class list due to other potential classes here.
+    expect(renderedView, contains('<body class="applied ">'));
+  }
+
+  Future<void> test_navigation_containsRoot() async {
+    var renderedView = await renderViewForTestFiles(
+        {convertPath('/project/lib/a.dart'): 'int a = null;'});
+    var expectedPath = convertPath('/project');
+    // harmless space in class list due to other potential classes here.
+    expect(renderedView, contains('<p class="root">$expectedPath</p>'));
+  }
+
+  Future<void> test_needsRerunStyle() async {
+    var renderedView = await renderViewForTestFiles(
+        {convertPath('/project/lib/a.dart'): 'int a = null;'},
+        needsRerun: true);
+    expect(renderedView, contains('<body class="proposed needs-rerun">'));
+  }
+
+  Future<void> test_notAppliedStyle() async {
+    var renderedView = await renderViewForTestFiles(
+        {convertPath('/project/lib/a.dart'): 'int a = null;'},
+        applied: false);
+    // harmless space in class list due to other potential classes here.
+    expect(renderedView, contains('<body class="proposed ">'));
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/migration_info_test.dart b/pkg/nnbd_migration/test/front_end/migration_info_test.dart
new file mode 100644
index 0000000..dcc1abb
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/migration_info_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnitInfoTest);
+  });
+}
+
+@reflectiveTest
+class UnitInfoTest {
+  static bool get _areAssertsEnabled {
+    try {
+      assert(false);
+      return false;
+    } on AssertionError {
+      return true;
+    }
+  }
+
+  void test_hadDiskContent_different() {
+    final unitInfo = UnitInfo('/foo.dart');
+    unitInfo.diskContent = 'abcd';
+    expect(unitInfo.hadDiskContent('dcba'), false);
+  }
+
+  void test_hadDiskContent_nullContentMatchesEmptyString() {
+    final unitInfo = UnitInfo('/foo.dart');
+    unitInfo.diskContent = '';
+    expect(unitInfo.hadDiskContent(null), true);
+    expect(unitInfo.hadDiskContent(''), true);
+  }
+
+  void test_hadDiskContent_nullMatchesEmptyStringContent() {
+    final unitInfo = UnitInfo('/foo.dart');
+    unitInfo.diskContent = null;
+    expect(unitInfo.hadDiskContent(null), true);
+    expect(unitInfo.hadDiskContent(''), true);
+  }
+
+  void test_hadDiskContent_theSame() {
+    final unitInfo = UnitInfo('/foo.dart');
+    unitInfo.diskContent = 'abcd';
+    expect(unitInfo.hadDiskContent('abcd'), true);
+  }
+
+  void test_hadDiskContent_usedBeforeSet_assertsDisabled() {
+    if (_areAssertsEnabled) return;
+
+    final unitInfo = UnitInfo('/foo.dart');
+    expect(unitInfo.hadDiskContent(''), false);
+  }
+
+  void test_hadDiskContent_usedBeforeSet_assertsEnabled() {
+    if (!_areAssertsEnabled) return;
+
+    final unitInfo = UnitInfo('/foo.dart');
+    expect(() => unitInfo.hadDiskContent(''), throwsA(isA<AssertionError>()));
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/mocks.dart b/pkg/nnbd_migration/test/front_end/mocks.dart
new file mode 100644
index 0000000..839623c
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/mocks.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:test/test.dart';
+
+/// A [Matcher] that check that the given [Response] has an expected identifier
+/// and no error.
+Matcher isResponseSuccess(String id) => _IsResponseSuccess(id);
+
+/// A [Matcher] that check that there are no `error` in a given [Response].
+class _IsResponseSuccess extends Matcher {
+  final String _id;
+
+  _IsResponseSuccess(this._id);
+
+  @override
+  Description describe(Description description) {
+    return description
+        .addDescriptionOf('response with identifier "$_id" and without error');
+  }
+
+  @override
+  Description describeMismatch(
+      item, Description mismatchDescription, Map matchState, bool verbose) {
+    Response response = item as Response;
+    if (response == null) {
+      mismatchDescription.add('is null response');
+    } else {
+      var id = response.id;
+      var error = response.error;
+      mismatchDescription.add('has identifier "$id"');
+      if (error != null) {
+        mismatchDescription.add(' and has error $error');
+      }
+    }
+    return mismatchDescription;
+  }
+
+  @override
+  bool matches(item, Map matchState) {
+    Response response = item as Response;
+    return response != null && response.id == _id && response.error == null;
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
new file mode 100644
index 0000000..b8b6231
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
@@ -0,0 +1,212 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'nnbd_migration_test_base.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NavigationTreeRendererTest);
+  });
+}
+
+const isNavigationTreeNode = TypeMatcher<NavigationTreeNode>();
+
+@reflectiveTest
+class NavigationTreeRendererTest extends NnbdMigrationTestBase {
+  /// Render the navigation tree view for [files].
+  Future<List<NavigationTreeNode>> renderNavigationTree(
+      Map<String, String> files) async {
+    var packageRoot = convertPath('/project');
+    await buildInfoForTestFiles(files, includedRoot: packageRoot);
+    var migrationInfo =
+        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
+    return NavigationTreeRenderer(migrationInfo, PathMapper(resourceProvider))
+        .render();
+  }
+
+  Future<void> test_containsEditCounts() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/lib/a.dart'): 'int a = 1;',
+      convertPath('/project/lib/b.dart'): 'int b = null;',
+      convertPath('/project/lib/c.dart'): 'int c = null;\nint d = null;',
+    });
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeNode.havingSubtree([
+          isNavigationTreeNode.havingEditCount(0),
+          isNavigationTreeNode.havingEditCount(1),
+          isNavigationTreeNode.havingEditCount(2)
+        ]));
+  }
+
+  Future<void> test_containsHrefs() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/lib/a.dart'): 'int a = null;',
+      convertPath('/project/lib/src/b.dart'): 'int b = null;',
+      convertPath('/project/tool.dart'): 'int c = null;',
+    });
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeNode.named('lib').havingSubtree([
+          isNavigationTreeNode.named('src').havingSubtree(
+              [isNavigationTreeNode.havingHref('/project/lib/src/b.dart')]),
+          isNavigationTreeNode.havingHref('/project/lib/a.dart')
+        ]));
+
+    var toolNode = response[1];
+    expect(toolNode.href, '/project/tool.dart');
+  }
+
+  Future<void> test_containsMultipleLinks_multipleDepths() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/lib/a.dart'): 'int a = null;',
+      convertPath('/project/lib/src/b.dart'): 'int b = null;',
+      convertPath('/project/tool.dart'): 'int c = null;',
+    });
+    expect(response, hasLength(2));
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeNode.named('lib').havingSubtree([
+          isNavigationTreeNode
+              .named('src')
+              .havingSubtree([isNavigationTreeNode.named('b.dart')]),
+          isNavigationTreeNode.named('a.dart')
+        ]));
+
+    var toolNode = response[1];
+    expect(toolNode.name, 'tool.dart');
+  }
+
+  Future<void> test_containsMultipleLinks_multipleRoots() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/bin/bin.dart'): 'int c = null;',
+      convertPath('/project/lib/a.dart'): 'int a = null;',
+    });
+    expect(response, hasLength(2));
+
+    var binNode = response[0];
+    expect(binNode.type, equals(NavigationTreeNodeType.directory));
+    expect(binNode.name, equals('bin'));
+    expect(binNode.subtree, hasLength(1));
+
+    var libNode = response[1];
+    expect(libNode.type, equals(NavigationTreeNodeType.directory));
+    expect(libNode.name, equals('lib'));
+    expect(libNode.subtree, hasLength(1));
+  }
+
+  Future<void> test_containsMultipleLinks_sameDepth() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/lib/a.dart'): 'int a = null;',
+      convertPath('/project/lib/b.dart'): 'int b = null;',
+    });
+    expect(response, hasLength(1));
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeNode.named('lib').havingSubtree([
+          isNavigationTreeNode
+              .named('a.dart')
+              .havingPath(convertPath('lib/a.dart'))
+              .havingHref('/project/lib/a.dart'),
+          isNavigationTreeNode
+              .named('b.dart')
+              .havingPath(convertPath('lib/b.dart'))
+              .havingHref('/project/lib/b.dart')
+        ]));
+  }
+
+  Future<void> test_containsPaths() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/lib/a.dart'): 'int a = null;',
+      convertPath('/project/lib/src/b.dart'): 'int b = null;',
+      convertPath('/project/tool.dart'): 'int c = null;',
+    });
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeNode.named('lib').havingSubtree([
+          isNavigationTreeNode.named('src').havingSubtree(
+              [isNavigationTreeNode.havingPath(convertPath('lib/src/b.dart'))]),
+          isNavigationTreeNode.havingPath(convertPath('lib/a.dart'))
+        ]));
+
+    var toolNode = response[1];
+    expect(toolNode.path, 'tool.dart');
+  }
+
+  Future<void> test_containsSingleLink_deep() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/lib/src/a.dart'): 'int a = null;',
+    });
+    expect(response, hasLength(1));
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeNode.named('lib').havingSubtree([
+          isNavigationTreeNode.named('src').havingSubtree([
+            isNavigationTreeNode
+                .named('a.dart')
+                .havingPath(convertPath('lib/src/a.dart'))
+                .havingHref('/project/lib/src/a.dart')
+          ])
+        ]));
+  }
+
+  Future<void> test_containsSingleLink_shallow() async {
+    var response = await renderNavigationTree({
+      convertPath('/project/a.dart'): 'int a = null;',
+    });
+    expect(response, hasLength(1));
+
+    var aNode = response[0];
+    expect(aNode.name, 'a.dart');
+    expect(aNode.path, 'a.dart');
+    expect(aNode.href, '/project/a.dart');
+  }
+}
+
+extension on TypeMatcher<NavigationTreeNode> {
+  TypeMatcher<NavigationTreeNode> havingSubtree(dynamic matcher) =>
+      having((node) => node.subtree, 'subtree', matcher);
+
+  TypeMatcher<NavigationTreeNode> havingEditCount(dynamic matcher) =>
+      having((node) => node.editCount, 'editCount', matcher);
+
+  TypeMatcher<NavigationTreeNode> named(dynamic matcher) =>
+      having((node) => node.name, 'name', matcher);
+
+  TypeMatcher<NavigationTreeNode> havingHref(dynamic matcher) =>
+      having((node) => node.href, 'href', matcher);
+
+  TypeMatcher<NavigationTreeNode> havingPath(dynamic matcher) =>
+      having((node) => node.path, 'path', matcher);
+}
+
+extension _E<T, U> on TypeMatcher<Map<T, U>> {
+  TypeMatcher<Map<T, U>> containing(Map<T, dynamic> matchers) {
+    var result = this;
+    for (var entry in matchers.entries) {
+      result = result.having(
+          (map) => map[entry.key], entry.key.toString(), entry.value);
+    }
+    return result;
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
new file mode 100644
index 0000000..559cf15
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/info_builder.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'analysis_abstract.dart';
+
+@reflectiveTest
+class NnbdMigrationTestBase extends AbstractAnalysisTest {
+  /// The information produced by the InfoBuilder, or `null` if [buildInfo] has
+  /// not yet completed.
+  Set<UnitInfo> infos;
+
+  /// Assert that some target in [targets] has various properties.
+  void assertInTargets(
+      {@required Iterable<NavigationTarget> targets,
+      int offset,
+      int length,
+      OffsetMapper offsetMapper}) {
+    var failureReasons = [
+      if (offset != null) 'offset: $offset',
+      if (length != null) 'length: $length',
+      if (offsetMapper != null) 'match a custom offset mapper',
+    ].join(' and ');
+    offsetMapper ??= OffsetMapper.identity;
+    expect(targets.any((t) {
+      return (offset == null || offset == offsetMapper.map(t.offset)) &&
+          (length == null || length == t.length);
+    }), isTrue, reason: 'Expected one of $targets to contain $failureReasons');
+  }
+
+  /// Assert various properties of the given [region]. If an [offset] is
+  /// provided but no [length] is provided, a default length of `1` will be
+  /// used.
+  void assertRegion(
+      {@required RegionInfo region,
+      int offset,
+      int length,
+      Object explanation = anything,
+      Object edits = anything,
+      Object traces = anything,
+      Object kind = NullabilityFixKind.makeTypeNullable}) {
+    if (offset != null) {
+      expect(region.offset, offset);
+      expect(region.length, length ?? 1);
+    } else if (length != null) {
+      expect(region.length, length);
+    }
+    expect(region.kind, kind);
+    expect(region.edits, edits);
+    expect(region.explanation, explanation);
+    expect(region.traces, traces);
+  }
+
+  /// Asserts various properties of the pair of [regions], `regions[index]` and
+  /// `regions[index + 1]`.  The expected offsets and lengths are specified
+  /// separately; everything else is asserted using the same matcher.
+  void assertRegionPair(List<RegionInfo> regions, int index,
+      {int offset1,
+      int length1,
+      int offset2,
+      int length2,
+      Object explanation = anything,
+      Object edits = anything,
+      Object traces = anything,
+      Object kind = anything}) {
+    assertRegion(
+        region: regions[index],
+        offset: offset1,
+        length: length1,
+        explanation: explanation,
+        edits: edits,
+        traces: traces,
+        kind: kind);
+    assertRegion(
+        region: regions[index + 1],
+        offset: offset2,
+        length: length2,
+        explanation: explanation,
+        edits: edits,
+        traces: traces,
+        kind: kind);
+  }
+
+  void assertTraceEntry(UnitInfo unit, TraceEntryInfo entryInfo,
+      String function, int offset, Object descriptionMatcher) {
+    assert(offset >= 0);
+    var lineInfo = LineInfo.fromContent(unit.content);
+    var expectedLocation = lineInfo.getLocation(offset);
+    expect(entryInfo.target.filePath, unit.path);
+    expect(entryInfo.target.line, expectedLocation.lineNumber);
+    expect(unit.offsetMapper.map(entryInfo.target.offset), offset);
+    expect(entryInfo.function, function);
+    expect(entryInfo.description, descriptionMatcher);
+  }
+
+  /// Uses the InfoBuilder to build information for [testFile].
+  ///
+  /// The information is stored in [infos].
+  Future<void> buildInfo(
+      {bool removeViaComments = true, bool warnOnWeakCode = false}) async {
+    var includedRoot = resourceProvider.pathContext.dirname(testFile);
+    await _buildMigrationInfo([testFile],
+        includedRoot: includedRoot,
+        removeViaComments: removeViaComments,
+        warnOnWeakCode: warnOnWeakCode);
+  }
+
+  /// Uses the InfoBuilder to build information for a single test file.
+  ///
+  /// Asserts that [originalContent] is migrated to [migratedContent]. Returns
+  /// the singular UnitInfo which was built.
+  Future<UnitInfo> buildInfoForSingleTestFile(String originalContent,
+      {@required String migratedContent,
+      bool removeViaComments = true,
+      bool warnOnWeakCode = false}) async {
+    addTestFile(originalContent);
+    await buildInfo(
+        removeViaComments: removeViaComments, warnOnWeakCode: warnOnWeakCode);
+    // Ignore info for dart:core.
+    var filteredInfos = [
+      for (var info in infos) if (!info.path.contains('core.dart')) info
+    ];
+    expect(filteredInfos, hasLength(1));
+    var unit = filteredInfos[0];
+    expect(unit.path, testFile);
+    expect(unit.content, migratedContent);
+    return unit;
+  }
+
+  /// Uses the InfoBuilder to build information for test files.
+  ///
+  /// Returns
+  /// the singular UnitInfo which was built.
+  Future<List<UnitInfo>> buildInfoForTestFiles(Map<String, String> files,
+      {String includedRoot}) async {
+    var testPaths = <String>[];
+    files.forEach((String path, String content) {
+      newFile(path, content: content);
+      testPaths.add(path);
+    });
+    await _buildMigrationInfo(testPaths, includedRoot: includedRoot);
+    // Ignore info for dart:core.
+    var filteredInfos = [
+      for (var info in infos) if (!info.path.contains('core.dart')) info
+    ];
+    return filteredInfos;
+  }
+
+  /// Uses the InfoBuilder to build information for files at [testPaths], which
+  /// should all share a common parent directory, [includedRoot].
+  Future<void> _buildMigrationInfo(List<String> testPaths,
+      {String includedRoot,
+      bool removeViaComments = true,
+      bool warnOnWeakCode = false}) async {
+    // Compute the analysis results.
+    server.setAnalysisRoots('0', [includedRoot], [], {});
+    // Run the migration engine.
+    var listener = DartFixListener(server);
+    var instrumentationListener = InstrumentationListener();
+    var adapter = NullabilityMigrationAdapter(listener);
+    var migration = NullabilityMigration(adapter,
+        permissive: false,
+        instrumentation: instrumentationListener,
+        removeViaComments: removeViaComments,
+        warnOnWeakCode: warnOnWeakCode);
+    Future<void> _forEachPath(
+        void Function(ResolvedUnitResult) callback) async {
+      for (var testPath in testPaths) {
+        var result = await server
+            .getAnalysisDriver(testPath)
+            .currentSession
+            .getResolvedUnit(testPath);
+        callback(result);
+      }
+    }
+
+    await _forEachPath(migration.prepareInput);
+    await _forEachPath(migration.processInput);
+    await _forEachPath(migration.finalizeInput);
+    migration.finish();
+    // Build the migration info.
+    var info = instrumentationListener.data;
+    var builder =
+        InfoBuilder(resourceProvider, includedRoot, info, listener, migration);
+    infos = await builder.explainMigration();
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart b/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
new file mode 100644
index 0000000..7bacfd2
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'analysis_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(OffsetMapperTest);
+  });
+}
+
+@reflectiveTest
+class OffsetMapperTest extends AbstractAnalysisTest {
+  void test_identity() {
+    var mapper = OffsetMapper.identity;
+    expect(mapper.map(0), 0);
+    expect(mapper.map(20), 20);
+    expect(mapper.map(0xFFFFFF), 0xFFFFFF);
+  }
+
+  void test_insertMapper() {
+    var mapper = OffsetMapper.forInsertion(10, 5);
+    expect(mapper.map(0), 0);
+    expect(mapper.map(9), 9);
+    expect(mapper.map(10), 15);
+    expect(mapper.map(11), 16);
+    expect(mapper.map(20), 25);
+  }
+
+  void test_multipleEdits() {
+    var mapper = OffsetMapper.forEdits([
+      SourceEdit(13, 0, '?'),
+      SourceEdit(21, 0, '!'),
+      SourceEdit(32, 0, '?'),
+    ]);
+    expect(mapper.map(0), 0);
+    expect(mapper.map(13), 13);
+    expect(mapper.map(14), 15);
+    expect(mapper.map(21), 22);
+    expect(mapper.map(22), 24);
+    expect(mapper.map(32), 34);
+    expect(mapper.map(33), 36);
+    expect(mapper.map(55), 58);
+  }
+
+  void test_rebase_insertMapper() {
+    var mapper = OffsetMapper.rebase(
+        OffsetMapper.forInsertion(5, 5), OffsetMapper.forInsertion(10, 5));
+    expect(mapper.map(0), 0);
+    expect(mapper.map(4), 4);
+    expect(mapper.map(5), 10);
+    expect(mapper.map(6), 11);
+    expect(mapper.map(9), 14);
+    expect(mapper.map(10), 20);
+    expect(mapper.map(11), 21);
+    expect(mapper.map(12), 22);
+  }
+
+  void test_sequence_insertMappers() {
+    var mapper = OffsetMapper.sequence(
+        OffsetMapper.forInsertion(30, 10), OffsetMapper.forInsertion(10, 10));
+    expect(mapper.map(0), 0);
+    expect(mapper.map(9), 9);
+    expect(mapper.map(10), 20);
+    expect(mapper.map(11), 21);
+    expect(mapper.map(29), 39);
+    expect(mapper.map(30), 50);
+    expect(mapper.map(31), 51);
+  }
+
+  void test_sequence_insertMappers_firstBeforeSecond() {
+    var mapper = OffsetMapper.sequence(
+        OffsetMapper.forInsertion(10, 10), OffsetMapper.forInsertion(30, 10));
+    expect(mapper.map(0), 0);
+    expect(mapper.map(9), 9);
+    expect(mapper.map(10), 20);
+    expect(mapper.map(11), 21);
+    expect(mapper.map(19), 29);
+    expect(mapper.map(20), 40);
+    expect(mapper.map(21), 41);
+  }
+
+  void test_sequence_insertMappers_overlapping() {
+    // by inserting into the middle of a previous insertion, we just effectively
+    // make the first insertion longer.
+    var mapper = OffsetMapper.sequence(
+        OffsetMapper.forInsertion(10, 10), OffsetMapper.forInsertion(15, 5));
+    expect(mapper.map(0), 0);
+    expect(mapper.map(9), 9);
+    expect(mapper.map(10), 25);
+    expect(mapper.map(11), 26);
+    expect(mapper.map(20), 35);
+  }
+
+  void test_singleEdit() {
+    var mapper = OffsetMapper.forEdits([
+      SourceEdit(13, 0, '?'),
+    ]);
+    expect(mapper.map(0), 0);
+    expect(mapper.map(13), 13);
+    expect(mapper.map(14), 15);
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/region_renderer_test.dart b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
new file mode 100644
index 0000000..934614a
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/region_renderer.dart';
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../abstract_context.dart';
+import 'nnbd_migration_test_base.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RegionRendererTest);
+  });
+}
+
+@reflectiveTest
+class RegionRendererTest extends NnbdMigrationTestBase {
+  /// Render the region at [offset], using a [MigrationInfo] which knows only
+  /// about the library at `infos.single`.
+  EditDetails renderRegion(int offset) {
+    var packageRoot = convertPath('/package');
+    var migrationInfo =
+        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
+    var unitInfo = infos.single;
+    var region = unitInfo.regionAt(offset);
+    return RegionRenderer(
+            region, unitInfo, migrationInfo, PathMapper(resourceProvider))
+        .render();
+  }
+
+  Future<void> test_modifiedOutput_containsExplanation() async {
+    await buildInfoForSingleTestFile('int a = null;',
+        migratedContent: 'int? a = null;');
+    var response = renderRegion(3);
+    expect(response.explanation, equals("Changed type 'int' to be nullable"));
+  }
+
+  Future<void> test_modifiedOutput_containsPath() async {
+    await buildInfoForSingleTestFile('int a = null;',
+        migratedContent: 'int? a = null;');
+    var response = renderRegion(3);
+    expect(response.path,
+        equals(convertPath('${AbstractContextTest.testsPath}/bin/test.dart')));
+    expect(response.line, equals(1));
+  }
+
+  Future<void> test_unmodifiedOutput_containsExplanation() async {
+    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
+        migratedContent: 'f(int  a) => a.isEven;');
+    var response = renderRegion(5);
+    expect(response.explanation, equals("Type 'int' was not made nullable"));
+  }
+
+  Future<void> test_unmodifiedOutput_containsPath() async {
+    await buildInfoForSingleTestFile('f(int a) => a.isEven;',
+        migratedContent: 'f(int  a) => a.isEven;');
+    var response = renderRegion(5);
+    expect(response.path,
+        equals(convertPath('${AbstractContextTest.testsPath}/bin/test.dart')));
+    expect(response.line, equals(1));
+  }
+}
diff --git a/pkg/nnbd_migration/test/front_end/test_all.dart b/pkg/nnbd_migration/test/front_end/test_all.dart
new file mode 100644
index 0000000..9a81148
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/test_all.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'info_builder_test.dart' as info_builder;
+import 'instrumentation_renderer_test.dart' as instrumentation_renderer;
+import 'migration_info_test.dart' as migration_info;
+import 'navigation_tree_renderer_test.dart' as navigation_tree_renderer;
+import 'offset_mapper_test.dart' as offset_mapper;
+import 'region_renderer_test.dart' as region_renderer;
+import 'unit_renderer_test.dart' as unit_renderer;
+
+main() {
+  defineReflectiveSuite(() {
+    info_builder.main();
+    instrumentation_renderer.main();
+    migration_info.main();
+    navigation_tree_renderer.main();
+    offset_mapper.main();
+    region_renderer.main();
+    unit_renderer.main();
+  }, name: 'front_end');
+}
diff --git a/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart b/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
new file mode 100644
index 0000000..3a932af
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
@@ -0,0 +1,420 @@
+// 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:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/unit_renderer.dart';
+import 'package:nnbd_migration/src/front_end/web/file_details.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'nnbd_migration_test_base.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnitRendererTest);
+  });
+}
+
+@reflectiveTest
+class UnitRendererTest extends NnbdMigrationTestBase {
+  /// Render [libraryInfo], using a [MigrationInfo] which knows only about this
+  /// library.
+  List<FileDetails> renderUnits() {
+    var packageRoot = convertPath('/package');
+    var migrationInfo =
+        MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
+
+    var contents = <FileDetails>[];
+    for (var unitInfo in infos) {
+      contents.add(
+          UnitRenderer(unitInfo, migrationInfo, PathMapper(resourceProvider))
+              .render());
+    }
+    return contents;
+  }
+
+  void test_conditionFalseInStrongMode() async {
+    await buildInfoForSingleTestFile('''
+int f(String s) {
+  if (s == null) {
+    return 0;
+  } else {
+    return s.length;
+  }
+}
+''', migratedContent: '''
+int  f(String  s) {
+  if (s == null /* == false */) {
+    return 0;
+  } else {
+    return s.length;
+  }
+}
+''', warnOnWeakCode: true);
+    var output = renderUnits()[0];
+    expect(
+        _stripDataAttributes(output.regions),
+        contains(
+            '<span class="region informative-region">/* == false */</span>'));
+    expect(output.edits.keys,
+        contains('1 condition will be false in strong checking mode'));
+  }
+
+  void test_conditionTrueInStrongMode() async {
+    await buildInfoForSingleTestFile('''
+int f(String s) {
+  if (s != null) {
+    return s.length;
+  } else {
+    return 0;
+  }
+}
+''', migratedContent: '''
+int  f(String  s) {
+  if (s != null /* == true */) {
+    return s.length;
+  } else {
+    return 0;
+  }
+}
+''', warnOnWeakCode: true);
+    var output = renderUnits()[0];
+    expect(
+        _stripDataAttributes(output.regions),
+        contains(
+            '<span class="region informative-region">/* == true */</span>'));
+    expect(output.edits.keys,
+        contains('1 condition will be true in strong checking mode'));
+  }
+
+  Future<void> test_editList_containsCount() async {
+    await buildInfoForSingleTestFile('''
+int a = null;
+bool b = a.isEven;
+''', migratedContent: '''
+int? a = null;
+bool  b = a!.isEven;
+''');
+    var output = renderUnits()[0];
+    var editList = output.edits;
+    expect(editList, hasLength(2));
+  }
+
+  Future<void> test_editList_containsEdits() async {
+    await buildInfoForSingleTestFile('''
+int a = null;
+bool b = a.isEven;
+''', migratedContent: '''
+int? a = null;
+bool  b = a!.isEven;
+''');
+    var output = renderUnits()[0];
+    // The null checks are higher priority than the assertions.
+    expect(output.edits.keys,
+        orderedEquals(['1 null check added', '1 type made nullable']));
+    var typesMadeNullable = output.edits['1 type made nullable'];
+    expect(typesMadeNullable, hasLength(1));
+    var typeMadeNullable = typesMadeNullable.single;
+    expect(typeMadeNullable.line, equals(1));
+    expect(typeMadeNullable.offset, equals(3));
+    expect(typeMadeNullable.explanation,
+        equals("Changed type 'int' to be nullable"));
+    var nullChecks = output.edits['1 null check added'];
+    expect(nullChecks, hasLength(1));
+    var nullCheck = nullChecks.single;
+    expect(nullCheck.line, equals(2));
+    expect(nullCheck.offset, equals(26));
+    expect(nullCheck.explanation,
+        equals('Added a non-null assertion to nullable expression'));
+  }
+
+  Future<void> test_editList_countsHintAcceptanceSingly() async {
+    await buildInfoForSingleTestFile('int f(int/*?*/ x) => x/*!*/;',
+        migratedContent: 'int  f(int/*?*/ x) => x/*!*/;');
+    var output = renderUnits()[0];
+    expect(
+        output.edits.keys,
+        unorderedEquals([
+          '1 null check hint converted to null check',
+          '1 nullability hint converted to ?'
+        ]));
+  }
+
+  Future<void> test_editList_countsHintAcceptanceSingly_late() async {
+    await buildInfoForSingleTestFile('/*late*/ int x = 0;',
+        migratedContent: '/*late*/ int  x = 0;');
+    var output = renderUnits()[0];
+    expect(output.edits.keys,
+        unorderedEquals(['1 late hint converted to late keyword']));
+  }
+
+  Future<void> test_editList_pluralHeader() async {
+    await buildInfoForSingleTestFile('''
+int a = null;
+int b = null;
+''', migratedContent: '''
+int? a = null;
+int? b = null;
+''');
+    var output = renderUnits()[0];
+    expect(output.edits.keys.toList(), ['2 types made nullable']);
+  }
+
+  Future<void> test_handle_large_deleted_region_near_top_of_file() async {
+    await buildInfoForSingleTestFile('''
+class C {
+  int hash(Iterable<int> elements) {
+    if (elements == null) {
+      return null.hashCode;
+    }
+    return 0;
+  }
+}
+
+List<int> x = [null];
+''', migratedContent: '''
+class C {
+  int  hash(Iterable<int >  elements) {
+    if (elements == null) {
+      return null.hashCode;
+    }
+    return 0;
+  }
+}
+
+List<int?>  x = [null];
+''', removeViaComments: false);
+    renderUnits();
+    // No assertions necessary; we are checking to make sure there is no crash.
+  }
+
+  Future<void> test_info_within_deleted_code() async {
+    await buildInfoForSingleTestFile('''
+class C {
+  int hash(Iterable<int> elements) {
+    if (elements == null) {
+      return null.hashCode;
+    }
+    return 0;
+  }
+}
+
+List<int> x = [null];
+''', migratedContent: '''
+class C {
+  int  hash(Iterable<int >  elements) {
+    if (elements == null) {
+      return null.hashCode;
+    }
+    return 0;
+  }
+}
+
+List<int?>  x = [null];
+''', removeViaComments: false);
+    var output = renderUnits()[0];
+    // Strip out URLs and span IDs; they're not being tested here.
+    var navContent = output.navigationContent
+        .replaceAll(RegExp('href="[^"]*"'), 'href="..."')
+        .replaceAll(RegExp('id="[^"]*"'), 'id="..."');
+    expect(navContent, '''
+class <span id="...">C</span> {
+  <a href="..." class="nav-link">int</a>  <span id="...">hash</span>(<a href="..." class="nav-link">Iterable</a>&lt;<a href="..." class="nav-link">int</a> &gt;  <span id="...">elements</span>) {
+    if (<a href="..." class="nav-link">elements</a> <a href="..." class="nav-link">==</a> null) {
+      return null.<a href="..." class="nav-link">hashCode</a>;
+    }
+    return 0;
+  }
+}
+
+<a href="..." class="nav-link">List</a>&lt;<a href="..." class="nav-link">int</a>?&gt;  <span id="...">x</span> = [null];
+''');
+  }
+
+  void test_kindPriorityOrder() {
+    var nonDisplayedKinds = NullabilityFixKind.values.toSet();
+    for (var kind in UnitRenderer.kindPriorityOrder) {
+      expect(nonDisplayedKinds.remove(kind), isTrue);
+    }
+    // The only kinds that should not be displayed are those associated with a
+    // place where nothing interesting occurred.
+    expect(nonDisplayedKinds, {
+      NullabilityFixKind.typeNotMadeNullable,
+      NullabilityFixKind.typeNotMadeNullableDueToHint
+    });
+  }
+
+  Future<void> test_navContentContainsEscapedHtml() async {
+    await buildInfoForSingleTestFile('List<String> a = null;',
+        migratedContent: 'List<String >? a = null;');
+    var output = renderUnits()[0];
+    // Strip out URLs which will change; not being tested here.
+    var navContent =
+        output.navigationContent.replaceAll(RegExp('href=".*?"'), 'href="..."');
+    expect(
+        navContent,
+        contains(r'<a href="..." class="nav-link">List</a>'
+            r'&lt;<a href="..." class="nav-link">String</a> &gt;? '
+            r'<span id="o13">a</span> = null;'));
+  }
+
+  void test_nullAwarenessUnnecessaryInStrongMode() async {
+    await buildInfoForSingleTestFile('''
+int f(String s) => s?.length;
+''', migratedContent: '''
+int  f(String  s) => s?.length;
+''', warnOnWeakCode: true);
+    var output = renderUnits()[0];
+    expect(_stripDataAttributes(output.regions),
+        contains('s<span class="region informative-region">?</span>.length'));
+    expect(
+        output.edits.keys,
+        contains(
+            '1 null-aware access will be unnecessary in strong checking mode'));
+  }
+
+  Future<void> test_outputContains_addedType() async {
+    await buildInfoForSingleTestFile('''
+void f() {
+  final a = <List<int>>[];
+  a.add([null]);
+}
+''', migratedContent: '''
+void f() {
+  final List<List<int?>> a = <List<int > >[];
+  a.add([null]);
+}
+''');
+    var output = renderUnits()[0];
+    var regions = _stripDataAttributes(output.regions);
+    expect(
+        regions,
+        contains('final '
+            '<span class="region added-region">List&lt;List&lt;int?&gt;&gt;</span>'
+            ' a = &lt;List&lt;int'
+            '<span class="region informative-region"> </span>'
+            '&gt;'
+            '<span class="region informative-region"> </span>'
+            '&gt;[];'));
+  }
+
+  Future<void> test_outputContains_replacedVar() async {
+    await buildInfoForSingleTestFile('''
+void f() {
+  var a = <List<int>>[];
+  a.add([null]);
+}
+''', migratedContent: '''
+void f() {
+  varList<List<int?>> a = <List<int > >[];
+  a.add([null]);
+}
+''');
+    var output = renderUnits()[0];
+    var regions = _stripDataAttributes(output.regions);
+    expect(
+        regions,
+        contains('<span class="region removed-region">var</span>'
+            '<span class="region added-region">List&lt;List&lt;int?&gt;&gt;</span>'
+            ' a = &lt;List&lt;int'
+            '<span class="region informative-region"> </span>'
+            '&gt;'
+            '<span class="region informative-region"> </span>'
+            '&gt;[];'));
+  }
+
+  Future<void> test_outputContainsModifiedAndUnmodifiedRegions() async {
+    await buildInfoForSingleTestFile('int a = null;',
+        migratedContent: 'int? a = null;');
+    var output = renderUnits()[0];
+    var regions = _stripDataAttributes(output.regions);
+    expect(regions,
+        contains('int<span class="region added-region">?</span> a = null;'));
+  }
+
+  Future<void> test_project_with_parts() async {
+    // In this test, we migrate a library and its part file.  Both files require
+    // addition of a `?`, but at different offsets.  We make sure the `?`s get
+    // added at the correct locations in each file.
+    var files = {
+      convertPath('/project/lib/a.dart'): '''
+part 'b.dart';
+
+int f() => null;
+''',
+      convertPath('/project/lib/b.dart'): '''
+part of 'a.dart';
+
+int g() => null;
+''',
+    };
+    var packageRoot = convertPath('/project');
+    await buildInfoForTestFiles(files, includedRoot: packageRoot);
+    var output = renderUnits();
+    expect(output[0].sourceCode, contains('int?'));
+    expect(output[1].sourceCode, contains('int?'));
+  }
+
+  Future<void> test_reference_to_sdk_file_with_parts() async {
+    await buildInfoForSingleTestFile('''
+import 'dart:async';
+Future<int> f(Future<int> x) {
+  return x.whenComplete(() {});
+}
+''', migratedContent: '''
+import 'dart:async';
+Future<int >  f(Future<int >  x) {
+  return x.whenComplete(() {});
+}
+''');
+    renderUnits();
+    // No assertions; we're just making sure there's no crash.
+  }
+
+  Future<void> test_regionsContainsEscapedHtml_ampersand() async {
+    await buildInfoForSingleTestFile('bool a = true && false;',
+        migratedContent: 'bool  a = true && false;');
+    var output = renderUnits()[0];
+    expect(
+        output.regions,
+        contains('bool<span class="region informative-region" data-offset="4" '
+            'data-line="1"> </span> a = true &amp;&amp; false;'));
+  }
+
+  Future<void> test_regionsContainsEscapedHtml_betweenRegions() async {
+    await buildInfoForSingleTestFile('List<String> a = null;',
+        migratedContent: 'List<String >? a = null;');
+    var output = renderUnits()[0];
+    var regions = _stripDataAttributes(output.regions);
+    expect(
+        regions,
+        contains(
+            'List&lt;String<span class="region informative-region"> </span>&gt;'
+            '<span class="region added-region">?</span> a = null;'));
+  }
+
+  Future<void> test_regionsContainsEscapedHtml_region() async {
+    await buildInfoForSingleTestFile('f(List<String> a) => a.join(",");',
+        migratedContent: 'f(List<String >  a) => a.join(",");');
+    var output = renderUnits()[0];
+    var regions = _stripDataAttributes(output.regions);
+    expect(
+        regions,
+        contains(
+            'List&lt;String<span class="region informative-region"> </span>'
+            '&gt;<span class="region informative-region"> </span>'));
+  }
+
+  UnitInfo unit(String path, String content, {List<RegionInfo> regions}) {
+    return UnitInfo(convertPath(path))
+      ..content = content
+      ..regions.addAll(regions);
+  }
+
+  /// Strip out data attributes which are not being tested here.
+  String _stripDataAttributes(String html) =>
+      html.replaceAll(RegExp(' data-[^=]+="[^"]+"'), '');
+}
diff --git a/pkg/nnbd_migration/test/instrumentation_test.dart b/pkg/nnbd_migration/test/instrumentation_test.dart
index d9d01f1..74c2c3f 100644
--- a/pkg/nnbd_migration/test/instrumentation_test.dart
+++ b/pkg/nnbd_migration/test/instrumentation_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:nnbd_migration/fix_reason_target.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
@@ -60,9 +61,11 @@
 
   @override
   void graphEdge(EdgeInfo edge, EdgeOriginInfo originInfo) {
-    expect(test.edgeOrigin, isNot(contains(edge)));
-    test.edges.add(edge);
-    test.edgeOrigin[edge] = originInfo;
+    if (edge.destinationNode != test.always) {
+      expect(test.edgeOrigin, isNot(contains(edge)));
+      test.edges.add(edge);
+      test.edgeOrigin[edge] = originInfo;
+    }
   }
 
   @override
@@ -132,13 +135,15 @@
 
   Source source;
 
-  Future<void> analyze(String content, {bool removeViaComments = false}) async {
+  Future<void> analyze(String content,
+      {bool removeViaComments = false, bool warnOnWeakCode = true}) async {
     var sourcePath = convertPath('/home/test/lib/test.dart');
     newFile(sourcePath, content: content);
     var listener = new TestMigrationListener();
     var migration = NullabilityMigration(listener,
         instrumentation: _InstrumentationClient(this),
-        removeViaComments: removeViaComments);
+        removeViaComments: removeViaComments,
+        warnOnWeakCode: warnOnWeakCode);
     var result = await session.getResolvedUnit(sourcePath);
     source = result.unit.declaredElement.source;
     findNode = FindNode(content, result.unit);
@@ -148,6 +153,13 @@
     migration.finish();
   }
 
+  void assertEdit(AtomicEdit edit,
+      {dynamic description = anything, dynamic fixReasons = anything}) {
+    var info = edit.info;
+    expect(info.description, description);
+    expect(info.fixReasons, fixReasons);
+  }
+
   Future<void> test_explicitTypeNullability() async {
     var content = '''
 int x = 1;
@@ -208,79 +220,78 @@
   }
 
   Future<void> test_fix_reason_add_required_function() async {
-    await analyze('_f({int/*!*/ i) {}');
+    var content = '_f({int/*!*/ i) {}';
+    await analyze(content);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description,
-            NullabilityFixDescription.addRequired(null, '_f', 'i'));
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var intPos = content.indexOf('int');
+    var commentPos = content.indexOf('/*');
+    expect(changes.keys, unorderedEquals([intPos, commentPos]));
+    assertEdit(changes[intPos].single,
+        description: NullabilityFixDescription.addRequired(null, '_f', 'i'),
+        fixReasons: {
+          FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+        });
   }
 
   Future<void> test_fix_reason_add_required_method() async {
-    await analyze('class C { _f({int/*!*/ i) {} }');
+    var content = 'class C { _f({int/*!*/ i) {} }';
+    await analyze(content);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description,
-            NullabilityFixDescription.addRequired('C', '_f', 'i'));
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var intPos = content.indexOf('int');
+    var commentPos = content.indexOf('/*');
+    expect(changes.keys, unorderedEquals([intPos, commentPos]));
+    assertEdit(changes[intPos].single,
+        description: NullabilityFixDescription.addRequired('C', '_f', 'i'),
+        fixReasons: {
+          FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+        });
   }
 
   Future<void> test_fix_reason_discard_condition() async {
-    await analyze('''
+    var content = '''
 _f(int/*!*/ i) {
   if (i != null) {
     return i;
   }
 }
-''');
+''';
+    await analyze(content, warnOnWeakCode: false);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardCondition);
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var commentPos = content.indexOf('/*');
+    var ifPos = content.indexOf('if');
+    var afterReturnPos = content.indexOf('i;') + 2;
+    expect(changes.keys, unorderedEquals([commentPos, ifPos, afterReturnPos]));
+    var expectedFixReasons = {
+      FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+    };
+    assertEdit(changes[ifPos].single,
+        description: NullabilityFixDescription.discardCondition,
+        fixReasons: expectedFixReasons);
+    assertEdit(changes[afterReturnPos].single,
+        description: NullabilityFixDescription.discardCondition,
+        fixReasons: expectedFixReasons);
   }
 
   Future<void> test_fix_reason_discard_condition_no_block() async {
-    await analyze('''
+    var content = '''
 _f(int/*!*/ i) {
   if (i != null) return i;
 }
-''');
+''';
+    await analyze(content, warnOnWeakCode: false);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardCondition);
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var commentPos = content.indexOf('/*');
+    var ifPos = content.indexOf('if');
+    expect(changes.keys, unorderedEquals([commentPos, ifPos]));
+    assertEdit(changes[ifPos].single,
+        description: NullabilityFixDescription.discardCondition,
+        fixReasons: {
+          FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+        });
   }
 
   Future<void> test_fix_reason_discard_else() async {
-    await analyze('''
+    var content = '''
 _f(int/*!*/ i) {
   if (i != null) {
     return i;
@@ -288,47 +299,46 @@
     return 'null';
   }
 }
-''');
+''';
+    await analyze(content, warnOnWeakCode: false);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, hasLength(2));
-    // Change #1: drop the if-condition.
-    var dropCondition = changes[findNode.statement('if').offset].single;
-    expect(dropCondition.isDeletion, true);
-    expect(dropCondition.info.description,
-        NullabilityFixDescription.discardCondition);
-    expect(dropCondition.info.fixReasons.single,
-        same(explicitTypeNullability[intAnnotation]));
-    // Change #2: drop the else.
-    var dropElse = changes[findNode.statement('return i').end].single;
-    expect(dropElse.isDeletion, true);
-    expect(dropElse.info.description, NullabilityFixDescription.discardElse);
-    expect(dropElse.info.fixReasons.single,
-        same(explicitTypeNullability[intAnnotation]));
+    var commentPos = content.indexOf('/*');
+    var ifPos = content.indexOf('if');
+    var afterReturnPos = content.indexOf('i;') + 2;
+    expect(changes.keys, unorderedEquals([commentPos, ifPos, afterReturnPos]));
+    var expectedFixReasons = {
+      FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+    };
+    assertEdit(changes[ifPos].single,
+        description: NullabilityFixDescription.discardCondition,
+        fixReasons: expectedFixReasons);
+    assertEdit(changes[afterReturnPos].single,
+        description: NullabilityFixDescription.discardElse,
+        fixReasons: expectedFixReasons);
   }
 
   Future<void> test_fix_reason_discard_else_empty_then() async {
-    await analyze('''
+    var content = '''
 _f(int/*!*/ i) {
   if (i != null) {} else {
     return 'null';
   }
 }
-''');
+''';
+    await analyze(content, warnOnWeakCode: false);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardIf);
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var commentPos = content.indexOf('/*');
+    var bodyPos = content.indexOf('i) {') + 4;
+    expect(changes.keys, unorderedEquals([commentPos, bodyPos]));
+    assertEdit(changes[bodyPos].single,
+        description: NullabilityFixDescription.discardIf,
+        fixReasons: {
+          FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+        });
   }
 
   Future<void> test_fix_reason_discard_then() async {
-    await analyze('''
+    var content = '''
 _f(int/*!*/ i) {
   if (i == null) {
     return 'null';
@@ -336,39 +346,42 @@
     return i;
   }
 }
-''');
+''';
+    await analyze(content, warnOnWeakCode: false);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardThen);
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var commentPos = content.indexOf('/*');
+    var ifPos = content.indexOf('if');
+    var afterReturnPos = content.indexOf('i;') + 2;
+    expect(changes.keys, unorderedEquals([commentPos, ifPos, afterReturnPos]));
+    var expectedFixReasons = {
+      FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+    };
+    assertEdit(changes[ifPos].single,
+        description: NullabilityFixDescription.discardThen,
+        fixReasons: expectedFixReasons);
+    assertEdit(changes[afterReturnPos].single,
+        description: NullabilityFixDescription.discardThen,
+        fixReasons: expectedFixReasons);
   }
 
   Future<void> test_fix_reason_discard_then_no_else() async {
-    await analyze('''
+    var content = '''
 _f(int/*!*/ i) {
   if (i == null) {
     return 'null';
   }
 }
-''');
+''';
+    await analyze(content, warnOnWeakCode: false);
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardIf);
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    var commentPos = content.indexOf('/*');
+    var bodyPos = content.indexOf('i) {') + 4;
+    expect(changes.keys, unorderedEquals([commentPos, bodyPos]));
+    assertEdit(changes[bodyPos].single,
+        description: NullabilityFixDescription.discardIf,
+        fixReasons: {
+          FixReasonTarget.root: same(explicitTypeNullability[intAnnotation])
+        });
   }
 
   Future<void> test_fix_reason_edge() async {
@@ -393,7 +406,7 @@
     expect(info.description, NullabilityFixDescription.checkExpression);
     var reasons = info.fixReasons;
     expect(reasons, hasLength(1));
-    var edge = reasons[0] as EdgeInfo;
+    var edge = reasons[FixReasonTarget.root] as EdgeInfo;
     expect(edge.sourceNode,
         same(explicitTypeNullability[findNode.typeAnnotation('int y')]));
     expect(edge.destinationNode,
@@ -417,34 +430,31 @@
     expect(info.description, NullabilityFixDescription.makeTypeNullable('int'));
     var reasons = info.fixReasons;
     expect(reasons, hasLength(1));
-    expect(reasons.single, same(explicitTypeNullability[intAnnotation]));
+    expect(reasons[FixReasonTarget.root],
+        same(explicitTypeNullability[intAnnotation]));
   }
 
   Future<void> test_fix_reason_remove_question_from_question_dot() async {
-    await analyze('_f(int/*!*/ i) => i?.isEven;');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.removeNullAwareness);
-        expect(info.fixReasons, isEmpty);
-      }
-    }
+    var content = '_f(int/*!*/ i) => i?.isEven;';
+    await analyze(content, warnOnWeakCode: false);
+    var commentPos = content.indexOf('/*');
+    var questionDotPos = content.indexOf('?.');
+    expect(changes.keys, unorderedEquals([commentPos, questionDotPos]));
+    assertEdit(changes[questionDotPos].single,
+        description: NullabilityFixDescription.removeNullAwareness,
+        fixReasons: isEmpty);
   }
 
   Future<void>
       test_fix_reason_remove_question_from_question_dot_method() async {
-    await analyze('_f(int/*!*/ i) => i?.abs();');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.removeNullAwareness);
-        expect(info.fixReasons, isEmpty);
-      }
-    }
+    var content = '_f(int/*!*/ i) => i?.abs();';
+    await analyze(content, warnOnWeakCode: false);
+    var commentPos = content.indexOf('/*');
+    var questionDotPos = content.indexOf('?.');
+    expect(changes.keys, unorderedEquals([commentPos, questionDotPos]));
+    assertEdit(changes[questionDotPos].single,
+        description: NullabilityFixDescription.removeNullAwareness,
+        fixReasons: isEmpty);
   }
 
   Future<void> test_fix_reason_remove_unnecessary_cast() async {
@@ -489,7 +499,7 @@
         var info = edit.info;
         expect(info.description,
             NullabilityFixDescription.addRequired(null, '_f', 'i'));
-        expect(info.fixReasons.single,
+        expect(info.fixReasons[FixReasonTarget.root],
             same(explicitTypeNullability[intAnnotation]));
       }
     }
@@ -991,8 +1001,8 @@
             .node;
     expect(
         edges.where((e) =>
-            e.sourceNode == derivedParamArgNode &&
-            e.destinationNode == baseParamArgNode),
+            e.sourceNode == baseParamArgNode &&
+            e.destinationNode == derivedParamArgNode),
         hasLength(1));
   }
 
diff --git a/pkg/nnbd_migration/test/isolate_server_test.dart b/pkg/nnbd_migration/test/isolate_server_test.dart
new file mode 100644
index 0000000..c352204
--- /dev/null
+++ b/pkg/nnbd_migration/test/isolate_server_test.dart
@@ -0,0 +1,264 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:isolate';
+
+import 'package:analysis_server_client/protocol.dart';
+import 'package:async/src/stream_sink_transformer.dart';
+import 'package:nnbd_migration/isolate_server.dart';
+import 'package:stream_channel/isolate_channel.dart';
+import 'package:stream_channel/src/stream_channel_transformer.dart';
+import 'package:stream_channel/stream_channel.dart';
+import 'package:test/test.dart';
+
+void main() {
+  FakeIsolate isolate;
+  FakeIsolateChannel isolateChannel;
+  Server server;
+
+  setUp(() async {
+    isolate = FakeIsolate();
+    isolateChannel = FakeIsolateChannel();
+    server = Server(isolate: isolate, isolateChannel: isolateChannel);
+  });
+
+  group('listenToOutput', () {
+    test('good', () async {
+      isolateChannel.stream = _goodMessage();
+
+      final future = server.send('blahMethod', null);
+      server.listenToOutput();
+
+      final response = await future;
+      expect(response['foo'], 'bar');
+    });
+
+    test('error', () async {
+      isolateChannel.stream = _badMessage();
+
+      final future = server.send('blahMethod', null);
+      future.catchError((e) {
+        expect(e, const TypeMatcher<RequestError>());
+        final error = e as RequestError;
+        expect(error.code, RequestErrorCode.UNKNOWN_REQUEST);
+        expect(error.message, 'something went wrong');
+        expect(error.stackTrace, 'some long stack trace');
+      });
+      server.listenToOutput();
+    });
+
+    test('event', () async {
+      isolateChannel.stream = _eventMessage();
+
+      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');
+        completer.complete();
+      }
+
+      server.send('blahMethod', null);
+      server.listenToOutput(notificationProcessor: eventHandler);
+      await completer.future;
+    });
+  });
+
+  group('stop', () {
+    test('ok', () async {
+      final fakeOut = StreamController<List<int>>();
+      isolateChannel.stream = fakeOut.stream;
+      // ignore: unawaited_futures
+      isolateChannel.fakeIn.controller.stream.first.then((_) {
+        var encoded = json.encode({'id': '0'});
+        fakeOut.add(utf8.encoder.convert('$encoded\n'));
+      });
+      server.isolateExited.complete();
+      server.listenToOutput();
+      await server.stop(timeLimit: const Duration(milliseconds: 1));
+      expect(isolate.killed, isFalse);
+    });
+    test('stopped', () async {
+      final fakeOut = StreamController<List<int>>();
+      isolateChannel.stream = fakeOut.stream;
+
+      server.isolateExited.complete();
+      server.listenToOutput();
+      await server.stop(timeLimit: const Duration(milliseconds: 1));
+      expect(isolate.killed, isFalse);
+    });
+    test('kill', () async {
+      final fakeOut = StreamController<List<int>>();
+      isolateChannel.stream = fakeOut.stream;
+
+      server.listenToOutput();
+      await server.stop(timeLimit: const Duration(milliseconds: 10));
+      expect(isolate.killed, isTrue);
+    });
+  });
+}
+
+final _badErrorMessage = {
+  'code': 'UNKNOWN_REQUEST',
+  'message': 'something went wrong',
+  'stackTrace': 'some long stack trace'
+};
+
+Stream<List<int>> _badMessage() async* {
+  yield utf8.encoder.convert('Observatory listening on foo bar\n');
+  final sampleJson = {
+    'id': '0',
+    'error': _badErrorMessage,
+  };
+  yield utf8.encoder.convert(json.encode(sampleJson));
+}
+
+Stream<List<int>> _eventMessage() async* {
+  yield utf8.encoder.convert('Observatory listening on foo bar\n');
+  final sampleJson = {
+    'event': 'fooEvent',
+    'params': {'foo': 'bar', 'baz': 'bang'}
+  };
+  yield utf8.encoder.convert(json.encode(sampleJson));
+}
+
+Stream<List<int>> _goodMessage() async* {
+  yield utf8.encoder.convert('Observatory listening on foo bar\n');
+  final sampleJson = {
+    'id': '0',
+    'result': {'foo': 'bar'}
+  };
+  yield utf8.encoder.convert(json.encode(sampleJson));
+}
+
+class FakeIsolate implements Isolate {
+  bool killed = false;
+
+  @override
+  void addErrorListener(SendPort port) => throw UnimplementedError();
+
+  @override
+  void addOnExitListener(SendPort port, {Object response}) =>
+      throw UnimplementedError();
+
+  @override
+  SendPort get controlPort => throw UnimplementedError();
+
+  @override
+  String get debugName => throw UnimplementedError();
+
+  @override
+  Stream get errors => throw UnimplementedError();
+
+  @override
+  Capability get pauseCapability => throw UnimplementedError();
+
+  @override
+  void ping(SendPort port,
+          {Object response, int priority = Isolate.immediate}) =>
+      throw UnimplementedError();
+
+  @override
+  void removeErrorListener(SendPort port) => throw UnimplementedError();
+
+  @override
+  void removeOnExitListener(SendPort port) => throw UnimplementedError();
+
+  @override
+  void resume(Capability capability) => throw UnimplementedError();
+
+  @override
+  Capability get terminateCapability => throw UnimplementedError();
+
+  @override
+  void kill({int priority = Isolate.beforeNextEvent}) {
+    killed = true;
+  }
+
+  @override
+  Capability pause([Capability resumeCapability]) => throw UnimplementedError();
+
+  @override
+  void setErrorsFatal(bool errorsAreFatal) => throw UnimplementedError();
+}
+
+class FakeIsolateChannel<T> implements IsolateChannel<T> {
+  FakeIsolateInput fakeIn = FakeIsolateInput();
+
+  @override
+  StreamChannel<S> cast<S>() => throw UnimplementedError();
+
+  @override
+  StreamChannel<T> changeSink(
+          StreamSink<T> Function(StreamSink<T> sink) change) =>
+      throw UnimplementedError();
+
+  @override
+  StreamChannel<T> changeStream(Stream<T> Function(Stream<T> stream) change) =>
+      throw UnimplementedError();
+
+  @override
+  void pipe(StreamChannel<T> other) => throw UnimplementedError();
+
+  @override
+  StreamSink<T> get sink => fakeIn as StreamSink<T>;
+
+  @override
+  Stream<T> stream;
+
+  @override
+  StreamChannel<S> transform<S>(StreamChannelTransformer<S, T> transformer) =>
+      throw UnimplementedError();
+
+  @override
+  StreamChannel<T> transformSink(StreamSinkTransformer<T, T> transformer) =>
+      throw UnimplementedError();
+
+  @override
+  StreamChannel<T> transformStream(StreamTransformer<T, T> transformer) =>
+      throw UnimplementedError();
+}
+
+class FakeIsolateInput 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]) {}
+
+  @override
+  Future addStream(Stream<List<int>> stream) => null;
+
+  @override
+  Future close() => null;
+
+  @override
+  Future flush() => null;
+
+  @override
+  void write(Object obj) {}
+
+  @override
+  void writeAll(Iterable objects, [String separator = '']) {}
+
+  @override
+  void writeCharCode(int charCode) {}
+
+  @override
+  void writeln([Object obj = '']) {}
+}
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
new file mode 100644
index 0000000..cd3a4b4
--- /dev/null
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -0,0 +1,493 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart' as mock_sdk;
+import 'package:cli_util/cli_logging.dart';
+import 'package:http/http.dart' as http;
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/migration_cli.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(_MigrationCliTestPosix);
+    defineReflectiveTests(_MigrationCliTestWindows);
+  });
+}
+
+class _MigrationCli extends MigrationCli {
+  Future<void> Function() _runWhilePreviewServerActive;
+
+  _MigrationCli(_MigrationCliTestBase test)
+      : super(
+            binaryName: 'nnbd_migration',
+            loggerFactory: (isVerbose) => test.logger = _TestLogger(isVerbose),
+            defaultSdkPathOverride:
+                test.resourceProvider.convertPath(mock_sdk.sdkRoot),
+            resourceProvider: test.resourceProvider);
+
+  @override
+  Future<void> blockUntilSignalInterrupt() async {
+    if (_runWhilePreviewServerActive == null) {
+      fail('Preview server not expected to have been started');
+    }
+    await _runWhilePreviewServerActive.call();
+    _runWhilePreviewServerActive = null;
+  }
+
+  Future<void> runWithPreviewServer(
+      List<String> args, Future<void> callback()) async {
+    _runWhilePreviewServerActive = callback;
+    await run(args);
+    if (_runWhilePreviewServerActive != null) {
+      fail('Preview server never started');
+    }
+  }
+}
+
+abstract class _MigrationCliTestBase {
+  void set logger(_TestLogger logger);
+
+  MemoryResourceProvider get resourceProvider;
+}
+
+mixin _MigrationCliTestMethods on _MigrationCliTestBase {
+  @override
+  /*late*/ _TestLogger logger;
+
+  final hasVerboseHelpMessage = contains('for verbose help output');
+
+  final hasUsageText = contains('Usage: nnbd_migration');
+
+  String assertErrorExit(MigrationCli cli, {bool withUsage = true}) {
+    expect(cli.exitCode, isNotNull);
+    expect(cli.exitCode, isNot(0));
+    var stderrText = logger.stderrBuffer.toString();
+    expect(stderrText, withUsage ? hasUsageText : isNot(hasUsageText));
+    expect(stderrText,
+        withUsage ? hasVerboseHelpMessage : isNot(hasVerboseHelpMessage));
+    return stderrText;
+  }
+
+  Future<String> assertParseArgsFailure(List<String> args) async {
+    var cli = _createCli();
+    await cli.run(args);
+    var stderrText = assertErrorExit(cli);
+    expect(stderrText, isNot(contains('Exception')));
+    return stderrText;
+  }
+
+  CommandLineOptions assertParseArgsSuccess(List<String> args) {
+    var cli = _createCli();
+    cli.parseCommandLineArgs(args);
+    expect(cli.exitCode, isNull);
+    var options = cli.options;
+    return options;
+  }
+
+  Future assertPreviewServerResponsive(String url) async {
+    var response = await http.get(url);
+    expect(response.statusCode, 200);
+  }
+
+  void assertProjectContents(String projectDir, Map<String, String> expected) {
+    for (var entry in expected.entries) {
+      var relativePathPosix = entry.key;
+      assert(!path.posix.isAbsolute(relativePathPosix));
+      var filePath = resourceProvider.pathContext
+          .join(projectDir, resourceProvider.convertPath(relativePathPosix));
+      expect(
+          resourceProvider.getFile(filePath).readAsStringSync(), entry.value);
+    }
+  }
+
+  String createProjectDir(Map<String, String> contents) {
+    var projectPathPosix = '/test_project';
+    for (var entry in contents.entries) {
+      var relativePathPosix = entry.key;
+      assert(!path.posix.isAbsolute(relativePathPosix));
+      var filePathPosix = path.posix.join(projectPathPosix, relativePathPosix);
+      resourceProvider.newFile(
+          resourceProvider.convertPath(filePathPosix), entry.value);
+    }
+    return resourceProvider.convertPath(projectPathPosix);
+  }
+
+  Future<void> runWithPreviewServer(_MigrationCli cli, List<String> args,
+      Future<void> Function(String) callback) async {
+    String url;
+    await cli.runWithPreviewServer(args, () async {
+      // Server should be running now
+      url = RegExp('http://.*', multiLine: true)
+          .stringMatch(logger.stdoutBuffer.toString());
+      await callback(url);
+    });
+    // Server should be stopped now
+    expect(http.get(url), throwsA(anything));
+  }
+
+  Map<String, String> simpleProject({bool migrated: false, String sourceText}) {
+    return {
+      'pubspec.yaml': '''
+name: test
+environment:
+  sdk: '${migrated ? '>=2.9.0 <2.10.0' : '>=2.6.0 <3.0.0'}'
+''',
+      'lib/test.dart': sourceText ??
+          '''
+int${migrated ? '?' : ''} f() => null;
+'''
+    };
+  }
+
+  void tearDown() {
+    NonNullableFix.shutdownAllServers();
+  }
+
+  test_default_logger() {
+    // When running normally, we don't override the logger; make sure it has a
+    // non-null default so that there won't be a crash.
+    expect(MigrationCli(binaryName: 'nnbd_migration').logger, isNotNull);
+  }
+
+  test_detect_old_sdk() async {
+    var cli = _createCli();
+    // Alter the mock SDK, changing the signature of Object.operator== to match
+    // the signature that was present prior to NNBD.  (This is what the
+    // migration tool uses to detect an old SDK).
+    var coreLib = resourceProvider.getFile(
+        resourceProvider.convertPath('${mock_sdk.sdkRoot}/lib/core/core.dart'));
+    var oldCoreLibText = coreLib.readAsStringSync();
+    var newCoreLibText = oldCoreLibText.replaceAll(
+        'external bool operator ==(Object other)',
+        'external bool operator ==(dynamic other)');
+    expect(newCoreLibText, isNot(oldCoreLibText));
+    coreLib.writeAsStringSync(newCoreLibText);
+    var projectDir = await createProjectDir(simpleProject());
+    await cli.run([projectDir]);
+    assertErrorExit(cli, withUsage: false);
+    var output = logger.stdoutBuffer.toString();
+    expect(
+        output,
+        contains(
+            'Bad state: Analysis seems to have an SDK without NNBD enabled'));
+  }
+
+  test_flag_apply_changes_default() {
+    expect(assertParseArgsSuccess([]).applyChanges, isFalse);
+  }
+
+  test_flag_apply_changes_disable() async {
+    // "--no-apply-changes" is not an option.
+    await assertParseArgsFailure(['--no-apply-changes']);
+  }
+
+  test_flag_apply_changes_enable() {
+    expect(
+        assertParseArgsSuccess(['--no-web-preview', '--apply-changes'])
+            .applyChanges,
+        isTrue);
+  }
+
+  test_flag_apply_changes_incompatible_with_web_preview() async {
+    expect(await assertParseArgsFailure(['--web-preview', '--apply-changes']),
+        contains('--apply-changes requires --no-web-preview'));
+  }
+
+  test_flag_help() async {
+    var helpText = await _getHelpText(verbose: false);
+    expect(helpText, hasUsageText);
+    expect(helpText, hasVerboseHelpMessage);
+  }
+
+  test_flag_help_verbose() async {
+    var helpText = await _getHelpText(verbose: true);
+    expect(helpText, hasUsageText);
+    expect(helpText, isNot(hasVerboseHelpMessage));
+  }
+
+  test_flag_ignore_errors_default() {
+    expect(assertParseArgsSuccess([]).ignoreErrors, isFalse);
+  }
+
+  test_flag_ignore_errors_disable() async {
+    await assertParseArgsFailure(['--no-ignore-errors']);
+  }
+
+  test_flag_ignore_errors_enable() {
+    expect(assertParseArgsSuccess(['--ignore-errors']).ignoreErrors, isTrue);
+  }
+
+  test_flag_web_preview_default() {
+    expect(assertParseArgsSuccess([]).webPreview, isTrue);
+  }
+
+  test_flag_web_preview_disable() {
+    expect(assertParseArgsSuccess(['--no-web-preview']).webPreview, isFalse);
+  }
+
+  test_flag_web_preview_enable() {
+    expect(assertParseArgsSuccess(['--web-preview']).webPreview, isTrue);
+  }
+
+  test_lifecycle_apply_changes() async {
+    var projectContents = simpleProject();
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli();
+    await cli.run(['--no-web-preview', '--apply-changes', projectDir]);
+    // Check that a summary was printed
+    expect(logger.stdoutBuffer.toString(), contains('Applying changes'));
+    // And that it refers to test.dart and pubspec.yaml
+    expect(logger.stdoutBuffer.toString(), contains('test.dart'));
+    expect(logger.stdoutBuffer.toString(), contains('pubspec.yaml'));
+    // And that it does not tell the user they can rerun with `--apply-changes`
+    expect(logger.stdoutBuffer.toString(), isNot(contains('--apply-changes')));
+    // Changes should have been made
+    assertProjectContents(projectDir, simpleProject(migrated: true));
+  }
+
+  test_lifecycle_ignore_errors_disable() async {
+    var projectContents = simpleProject(sourceText: '''
+int f() => null
+''');
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli();
+    await cli.run([projectDir]);
+    assertErrorExit(cli, withUsage: false);
+    var output = logger.stdoutBuffer.toString();
+    expect(output, contains('1 analysis issue found'));
+    var sep = resourceProvider.pathContext.separator;
+    expect(
+        output,
+        contains("error • Expected to find ';' at lib${sep}test.dart:1:12 • "
+            "(expected_token)"));
+    expect(
+        output,
+        contains(
+            'analysis errors will result in erroneous migration suggestions'));
+    expect(output, contains('Please fix the analysis issues'));
+  }
+
+  test_lifecycle_ignore_errors_enable() async {
+    var projectContents = simpleProject(sourceText: '''
+int? f() => null
+''');
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli();
+    await runWithPreviewServer(cli, ['--ignore-errors', projectDir],
+        (url) async {
+      var output = logger.stdoutBuffer.toString();
+      expect(output, isNot(contains('No analysis issues found')));
+      expect(
+          output,
+          contains('Continuing with migration suggestions due to the use of '
+              '--ignore-errors.'));
+      await assertPreviewServerResponsive(url);
+    });
+  }
+
+  test_lifecycle_no_preview() async {
+    var projectContents = simpleProject();
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli();
+    await cli.run(['--no-web-preview', projectDir]);
+    // Check that a summary was printed
+    expect(logger.stdoutBuffer.toString(), contains('Summary'));
+    // And that it refers to test.dart and pubspec.yaml
+    expect(logger.stdoutBuffer.toString(), contains('test.dart'));
+    expect(logger.stdoutBuffer.toString(), contains('pubspec.yaml'));
+    // And that it tells the user they can rerun with `--apply-changes`
+    expect(logger.stdoutBuffer.toString(), contains('--apply-changes'));
+    // No changes should have been made
+    assertProjectContents(projectDir, projectContents);
+  }
+
+  test_lifecycle_preview() async {
+    var projectContents = simpleProject();
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli();
+    await runWithPreviewServer(cli, [projectDir], (url) async {
+      expect(
+          logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+      await assertPreviewServerResponsive(url);
+    });
+    // No changes should have been made.
+    assertProjectContents(projectDir, projectContents);
+  }
+
+  test_lifecycle_preview_extra_forward_slash() async {
+    var projectDir = await createProjectDir(simpleProject());
+    var cli = _createCli();
+    await runWithPreviewServer(cli, [projectDir], (url) async {
+      var uri = Uri.parse(url);
+      await assertPreviewServerResponsive(
+          uri.replace(path: uri.path + '/').toString());
+    });
+  }
+
+  test_lifecycle_uri_error() async {
+    var projectContents = simpleProject(sourceText: '''
+import 'package:does_not/exist.dart';
+int f() => null;
+''');
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli();
+    await cli.run([projectDir]);
+    assertErrorExit(cli, withUsage: false);
+    var output = logger.stdoutBuffer.toString();
+    expect(output, contains('1 analysis issue found'));
+    expect(output, contains('uri_does_not_exist'));
+    expect(
+        output,
+        contains(
+            'analysis errors will result in erroneous migration suggestions'));
+    expect(output,
+        contains('Unresolved URIs found.  Did you forget to run "pub get"?'));
+    expect(output, contains('Please fix the analysis issues'));
+  }
+
+  test_migrate_path_none() {
+    expect(assertParseArgsSuccess([]).directory, Directory.current.path);
+  }
+
+  test_migrate_path_one() {
+    expect(assertParseArgsSuccess(['foo']).directory, 'foo');
+  }
+
+  test_migrate_path_two() async {
+    var cli = _createCli();
+    await cli.run(['foo', 'bar']);
+    var stderrText = assertErrorExit(cli);
+    expect(stderrText, contains('No more than one path may be specified'));
+  }
+
+  test_option_preview_port() {
+    expect(
+        assertParseArgsSuccess(['--preview-port', '4040']).previewPort, 4040);
+  }
+
+  test_option_preview_port_default() {
+    expect(assertParseArgsSuccess([]).previewPort, isNull);
+  }
+
+  test_option_preview_port_format_error() async {
+    expect(await assertParseArgsFailure(['--preview-port', 'abc']),
+        contains('Invalid value for --preview-port'));
+  }
+
+  test_option_sdk() {
+    var path = Uri.parse('file:///foo/bar/baz').toFilePath();
+    expect(assertParseArgsSuccess(['--sdk-path', path]).sdkPath, same(path));
+  }
+
+  test_option_sdk_default() {
+    var cli = MigrationCli(binaryName: 'nnbd_migration');
+    cli.parseCommandLineArgs([]);
+    expect(
+        File(path.join(cli.options.sdkPath, 'version')).existsSync(), isTrue);
+  }
+
+  test_option_sdk_hidden() async {
+    var optionName = '--sdk-path';
+    expect(await _getHelpText(verbose: false), isNot(contains(optionName)));
+    expect(await _getHelpText(verbose: true), contains(optionName));
+  }
+
+  test_option_unrecognized() async {
+    expect(
+        await assertParseArgsFailure(['--this-option-does-not-exist']),
+        contains(
+            'Could not find an option named "this-option-does-not-exist"'));
+  }
+
+  test_uses_physical_resource_provider_by_default() {
+    var cli = MigrationCli(binaryName: 'nnbd_migration');
+    expect(cli.resourceProvider, same(PhysicalResourceProvider.INSTANCE));
+  }
+
+  _MigrationCli _createCli() {
+    mock_sdk.MockSdk(resourceProvider: resourceProvider);
+    return _MigrationCli(this);
+  }
+
+  Future<String> _getHelpText({@required bool verbose}) async {
+    var cli = _createCli();
+    await cli
+        .run(['--${CommandLineOptions.helpFlag}', if (verbose) '--verbose']);
+    expect(cli.exitCode, 0);
+    var helpText = logger.stderrBuffer.toString();
+    return helpText;
+  }
+}
+
+@reflectiveTest
+class _MigrationCliTestPosix extends _MigrationCliTestBase
+    with _MigrationCliTestMethods {
+  @override
+  final resourceProvider;
+
+  _MigrationCliTestPosix()
+      : resourceProvider = MemoryResourceProvider(
+            context: path.style == path.Style.posix ? null : path.posix);
+}
+
+@reflectiveTest
+class _MigrationCliTestWindows extends _MigrationCliTestBase
+    with _MigrationCliTestMethods {
+  @override
+  final resourceProvider;
+
+  _MigrationCliTestWindows()
+      : resourceProvider = MemoryResourceProvider(
+            context: path.style == path.Style.windows
+                ? null
+                : path.Context(style: path.Style.windows, current: 'C:\\'));
+}
+
+/// TODO(paulberry): move into cli_util
+class _TestLogger implements Logger {
+  final stderrBuffer = StringBuffer();
+
+  final stdoutBuffer = StringBuffer();
+
+  final bool isVerbose;
+
+  _TestLogger(this.isVerbose);
+
+  @override
+  Ansi get ansi => Ansi(false);
+
+  @override
+  void flush() {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  Progress progress(String message) {
+    return SimpleProgress(this, message);
+  }
+
+  @override
+  void stderr(String message) {
+    stderrBuffer.writeln(message);
+  }
+
+  @override
+  void stdout(String message) {
+    stdoutBuffer.writeln(message);
+  }
+
+  @override
+  void trace(String message) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+}
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 1224e07..c91a11c 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -193,15 +193,20 @@
     return {for (var edge in getEdges(anyNode, graph.never)) edge.sourceNode};
   }
 
+  /// Asserts that a dummy edge exists from [source] to always.
+  NullabilityEdge assertDummyEdge(Object source) =>
+      assertEdge(source, graph.always, hard: false, checkable: false);
+
   /// Asserts that an edge exists with a node matching [source] and a node
   /// matching [destination], and with the given [hard]ness and [guards].
   ///
   /// [source] and [destination] are converted to [NodeMatcher] objects if they
   /// aren't already.  In practice this means that the caller can pass in either
-  //  /// a [NodeMatcher] or a [NullabilityNode].
+  /// a [NodeMatcher] or a [NullabilityNode].
   NullabilityEdge assertEdge(Object source, Object destination,
       {@required bool hard,
       bool checkable = true,
+      bool isSetupAssignment = false,
       Object guards = isEmpty,
       Object codeReference}) {
     var edges = getEdges(source, destination);
@@ -213,6 +218,7 @@
       var edge = edges[0];
       expect(edge.isHard, hard);
       expect(edge.isCheckable, checkable);
+      expect(edge.isSetupAssignment, isSetupAssignment);
       expect(edge.guards, guards);
       if (codeReference != null) {
         expect(edge.codeReference, codeReference);
@@ -292,8 +298,6 @@
 
   final _expressionChecks = <Expression, ExpressionChecksOrigin>{};
 
-  final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{};
-
   InstrumentedVariables(NullabilityGraph graph, TypeProvider typeProvider)
       : super(graph, typeProvider);
 
@@ -309,11 +313,6 @@
   DecoratedType decoratedExpressionType(Expression expression) =>
       _decoratedExpressionTypes[_normalizeExpression(expression)];
 
-  /// Gets the [NullabilityNode] associated with the possibility that
-  /// [parameter] may be optional.
-  NullabilityNode possiblyOptionalParameter(DefaultFormalParameter parameter) =>
-      _possiblyOptional[parameter];
-
   @override
   void recordConditionalDiscard(
       Source source, AstNode node, ConditionalDiscard conditionalDiscard) {
@@ -333,13 +332,6 @@
     _expressionChecks[_normalizeExpression(expression)] = origin;
   }
 
-  @override
-  void recordPossiblyOptional(
-      Source source, DefaultFormalParameter parameter, NullabilityNode node) {
-    _possiblyOptional[parameter] = node;
-    super.recordPossiblyOptional(source, parameter, node);
-  }
-
   /// Unwraps any parentheses surrounding [expression].
   Expression _normalizeExpression(Expression expression) {
     while (expression is ParenthesizedExpression) {
@@ -422,10 +414,6 @@
         .having((cr) => cr.function, 'function', function);
   }
 
-  NullabilityNode possiblyOptionalParameter(String text) {
-    return variables.possiblyOptionalParameter(findNode.defaultParameter(text));
-  }
-
   void setUp() {
     DecoratedTypeParameterBounds.current = decoratedTypeParameterBounds;
     super.setUp();
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index 33013e5..adbd403 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -1716,25 +1716,33 @@
   Future<void> test_variableDeclaration_late_hint_after_metadata() async {
     await analyze('@deprecated /*late*/ int i;');
     expect(
-        variables.isLateHinted(
+        variables.getLateHint(
             testSource, findNode.variableDeclarationList('int i')),
-        true);
+        isNotNull);
   }
 
   Future<void> test_variableDeclaration_late_hint_multiple_comments() async {
     await analyze('/*other*/ /*late*/ int i;');
     expect(
-        variables.isLateHinted(
+        variables.getLateHint(
             testSource, findNode.variableDeclarationList('int i')),
-        true);
+        isNotNull);
   }
 
   Future<void> test_variableDeclaration_late_hint_simple() async {
     await analyze('/*late*/ int i;');
     expect(
-        variables.isLateHinted(
+        variables.getLateHint(
             testSource, findNode.variableDeclarationList('int i')),
-        true);
+        isNotNull);
+  }
+
+  Future<void> test_variableDeclaration_late_hint_with_spaces() async {
+    await analyze('/* late */ int i;');
+    expect(
+        variables.getLateHint(
+            testSource, findNode.variableDeclarationList('int i')),
+        isNotNull);
   }
 
   Future<void> test_variableDeclaration_type_simple() async {
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
new file mode 100644
index 0000000..cfce5a6
--- /dev/null
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -0,0 +1,261 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    hide NavigationTarget;
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/migration_state.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../front_end/nnbd_migration_test_base.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PreviewSiteTest);
+    defineReflectiveTests(PreviewSiteWithEngineTest);
+  });
+}
+
+@reflectiveTest
+class PreviewSiteTest with ResourceProviderMixin, PreviewSiteTestMixin {
+  @override
+  Future<void> performEdit(String path, int offset, String replacement) {
+    final pathUri = Uri.file(path).path;
+    return site
+        .performEdit(Uri.parse('localhost://$pathUri?offset=$offset&end=$offset'
+            '&replacement=${Uri.encodeComponent(replacement)}'));
+  }
+
+  void setUp() {
+    reranPaths = null;
+    dartfixListener = DartFixListener(null);
+    resourceProvider = MemoryResourceProvider();
+    final migrationInfo = MigrationInfo({}, {}, null, null);
+    state = MigrationState(null, null, dartfixListener, null);
+    state.pathMapper = PathMapper(resourceProvider);
+    state.migrationInfo = migrationInfo;
+    site = PreviewSite(state, ([paths]) async {
+      reranPaths = paths;
+      return state;
+    });
+  }
+
+  void test_apply_regress41391() async {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    final analysisOptionsPath = convertPath('/analysis_options.yaml');
+    final analysisOptions = getFile(analysisOptionsPath);
+    analysisOptions.writeAsStringSync('analyzer:');
+    final content = 'void main() {}';
+    file.writeAsStringSync(content);
+    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
+    // Add a source change for analysis_options, which has no UnitInfo.
+    dartfixListener.addSourceChange(
+        'enable experiment',
+        Location(analysisOptionsPath, 9, 0, 1, 9),
+        SourceChange('enable experiment', edits: [
+          SourceFileEdit(analysisOptionsPath, 0, edits: [
+            SourceEdit(9, 0, '\n  enable-experiment:\n  - non-nullable')
+          ])
+        ]));
+    // This should not crash.
+    site.performApply();
+    expect(analysisOptions.readAsStringSync(), '''
+analyzer:
+  enable-experiment:
+  - non-nullable''');
+    expect(state.hasBeenApplied, true);
+  }
+
+  void test_applyChangesEmpty() {
+    final file = getFile('/test.dart');
+    file.writeAsStringSync('void main() {}');
+    site.performApply();
+    expect(file.readAsStringSync(), 'void main() {}');
+    expect(state.hasBeenApplied, true);
+  }
+
+  void test_applyChangesTwiceThrows() {
+    site.performApply();
+    expect(site.performApply, throwsA(isA<StateError>()));
+  }
+
+  void test_applyMigration_sanityCheck_dontApply() async {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    site.unitInfoMap[path] = UnitInfo(path)
+      ..diskContent = '// different content';
+    final currentContent = 'void main() {}';
+    file.writeAsStringSync(currentContent);
+    dartfixListener.addSourceChange(
+        'test change',
+        Location(path, 10, 0, 1, 10),
+        SourceChange('test change', edits: [
+          SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')])
+        ]));
+    expect(() => site.performApply(), throwsA(isA<StateError>()));
+    expect(file.readAsStringSync(), currentContent);
+    expect(state.hasBeenApplied, false);
+  }
+
+  void test_applyMultipleChanges() {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    final content = 'void main() {}';
+    file.writeAsStringSync(content);
+    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
+    dartfixListener.addSourceChange(
+        'test change',
+        Location(path, 10, 0, 1, 10),
+        SourceChange('test change', edits: [
+          SourceFileEdit(path, 0, edits: [
+            SourceEdit(10, 0, 'List args'),
+            SourceEdit(13, 0, '\n  print(args);\n')
+          ])
+        ]));
+    site.performApply();
+    expect(file.readAsStringSync(), '''
+void main(List args) {
+  print(args);
+}''');
+    expect(state.hasBeenApplied, true);
+  }
+
+  void test_applySingleChange() {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    final content = 'void main() {}';
+    file.writeAsStringSync(content);
+    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
+    dartfixListener.addSourceChange(
+        'test change',
+        Location(path, 10, 0, 1, 10),
+        SourceChange('test change', edits: [
+          SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')])
+        ]));
+    site.performApply();
+    expect(file.readAsStringSync(), 'void main(List args) {}');
+    expect(state.hasBeenApplied, true);
+  }
+
+  void test_performEdit() {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    final content = 'int foo() {}';
+    final unitInfo = UnitInfo(path)
+      ..diskContent = content
+      ..content = content
+      ..diskChangesOffsetMapper = OffsetMapper.identity;
+    site.unitInfoMap[path] = unitInfo;
+    file.writeAsStringSync(content);
+    performEdit(path, 3, '/*?*/');
+    expect(file.readAsStringSync(), 'int/*?*/ foo() {}');
+    expect(state.hasBeenApplied, false);
+    expect(state.needsRerun, true);
+    expect(reranPaths, null);
+    expect(unitInfo.content, 'int/*?*/ foo() {}');
+  }
+
+  void test_performEdit_sanityCheck_dontApply() {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    site.unitInfoMap[path] = UnitInfo(path)
+      ..diskContent = '// different content';
+    final currentContent = 'void main() {}';
+    file.writeAsStringSync(currentContent);
+    expect(() => performEdit(path, 0, 'foo'), throwsA(isA<StateError>()));
+    expect(file.readAsStringSync(), currentContent);
+    expect(state.hasBeenApplied, false);
+  }
+}
+
+mixin PreviewSiteTestMixin {
+  PreviewSite site;
+  DartFixListener dartfixListener;
+  MigrationState state;
+  List<String> reranPaths;
+
+  Future<void> performEdit(String path, int offset, String replacement) {
+    final pathUri = Uri.file(path).path;
+    return site
+        .performEdit(Uri.parse('localhost://$pathUri?offset=$offset&end=$offset'
+            '&replacement=${Uri.encodeComponent(replacement)}'));
+  }
+}
+
+@reflectiveTest
+class PreviewSiteWithEngineTest extends NnbdMigrationTestBase
+    with ResourceProviderMixin, PreviewSiteTestMixin {
+  @override
+  void setUp() {
+    super.setUp();
+    reranPaths = null;
+    dartfixListener = DartFixListener(null);
+    final migrationInfo = MigrationInfo({}, {}, null, null);
+    state = MigrationState(null, null, dartfixListener, null);
+    state.pathMapper = PathMapper(resourceProvider);
+    state.migrationInfo = migrationInfo;
+    site = PreviewSite(state, ([paths]) async {
+      reranPaths = paths;
+      return state;
+    });
+  }
+
+  void test_performEdit_multiple() async {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    final content = r'''
+int x;
+int y = x;
+''';
+    file.writeAsStringSync(content);
+    final migratedContent = '''
+int? x;
+int? y = x;
+''';
+    final unitInfo = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    site.unitInfoMap[path] = unitInfo;
+    final firstEditOffset = unitInfo.regions[0].edits[0].offset;
+    performEdit(path, firstEditOffset, '/*?*/');
+    final secondEditOffset = unitInfo.regions[1].edits[0].offset;
+    performEdit(path, secondEditOffset, '/*?*/');
+    expect(file.readAsStringSync(), '''
+int/*?*/ x;
+int/*?*/ y = x;
+''');
+    expect(unitInfo.content, '''
+int/*?*/? x;
+int/*?*/? y = x;
+''');
+    assertRegion(
+        region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
+    assertRegion(
+        region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
+    final targets = List<NavigationTarget>.from(unitInfo.targets);
+    assertInTargets(
+        targets: targets,
+        offset: unitInfo.content.indexOf('x'),
+        offsetMapper: unitInfo.offsetMapper);
+    assertInTargets(
+        targets: targets,
+        offset: unitInfo.content.indexOf('y'),
+        offsetMapper: unitInfo.offsetMapper);
+    var trace = unitInfo.regions[1].traces[0];
+    assertTraceEntry(unitInfo, trace.entries[0], null,
+        unitInfo.content.indexOf('int/*?*/? y'), contains('explicit type'));
+    assertTraceEntry(unitInfo, trace.entries[1], 'y',
+        unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
+    expect(state.hasBeenApplied, false);
+    expect(state.needsRerun, true);
+    expect(reranPaths, null);
+  }
+}
diff --git a/pkg/analysis_server/test/src/edit/preview/test_all.dart b/pkg/nnbd_migration/test/preview/test_all.dart
similarity index 100%
rename from pkg/analysis_server/test/src/edit/preview/test_all.dart
rename to pkg/nnbd_migration/test/preview/test_all.dart
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index 76a9844..291ba60 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -18,9 +18,13 @@
 import 'fantasyland/test_all.dart' as fantasyland;
 import 'fix_aggregator_test.dart' as fix_aggregator_test;
 import 'fix_builder_test.dart' as fix_builder_test;
+import 'fix_reason_target_test.dart' as fix_reason_target_test;
+import 'front_end/test_all.dart' as front_end;
 import 'instrumentation_test.dart' as instrumentation_test;
+import 'isolate_server_test.dart' as isolate_server_test;
 import 'node_builder_test.dart' as node_builder_test;
 import 'nullability_node_test.dart' as nullability_node_test;
+import 'preview/test_all.dart' as preview;
 import 'utilities/test_all.dart' as utilities;
 import 'variables_test.dart' as variables;
 
@@ -37,9 +41,13 @@
     fantasyland.main();
     fix_aggregator_test.main();
     fix_builder_test.main();
+    fix_reason_target_test.main();
+    front_end.main();
     instrumentation_test.main();
+    isolate_server_test.main();
     node_builder_test.main();
     nullability_node_test.main();
+    preview.main();
     utilities.main();
     variables.main();
   });
diff --git a/pkg/nnbd_migration/tool/codegen/check_generated_test.dart b/pkg/nnbd_migration/tool/codegen/check_generated_test.dart
new file mode 100644
index 0000000..9a251ab
--- /dev/null
+++ b/pkg/nnbd_migration/tool/codegen/check_generated_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import 'generate_resources.dart' as generate_resources;
+
+/// Validate that the
+/// pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+/// file was regenerated after changing upstream dependencies.
+void main() async {
+  test('description', () {
+    generate_resources.verifyResourcesGDartGenerated(failVerification: fail);
+  });
+}
diff --git a/pkg/nnbd_migration/tool/codegen/generate_resources.dart b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
new file mode 100644
index 0000000..21ed8fb
--- /dev/null
+++ b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
@@ -0,0 +1,263 @@
+// 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 script generates the
+// lib/src/front_end/resources/resources.g.dart file from the contents
+// of the lib/src/front_end/resources directory.
+
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math' as math;
+
+import 'package:args/args.dart';
+import 'package:crypto/crypto.dart';
+import 'package:path/path.dart' as path;
+
+void main(List<String> args) async {
+  var argParser = ArgParser()
+    ..addFlag('verify', negatable: false)
+    ..addFlag('dev', negatable: false)
+    ..addFlag('help', negatable: false);
+  var argResults = argParser.parse(args);
+  if (argResults['help'] == true) {
+    fail('''
+usage: dart pkg/nnbd_migration/tool/codegen/generate_resources.dart [--verify]
+
+Run with no args to generate web resources for the NNBD migration preview tool.
+Run with '--verify' to validate that the web resource have been regenerated.
+''');
+  }
+
+  if (FileSystemEntity.isFileSync(
+      path.join('tool', 'codegen', 'generate_resources.dart'))) {
+    // We're running from the project root - cd up two directories.
+    Directory.current = Directory.current.parent.parent;
+  } else if (!FileSystemEntity.isDirectorySync(
+      path.join('pkg', 'nnbd_migration'))) {
+    fail('Please run this tool from the root of the sdk repo.');
+  }
+
+  bool verify = argResults['verify'] as bool;
+  bool dev = argResults['dev'] as bool;
+
+  if (verify) {
+    verifyResourcesGDartGenerated();
+  } else {
+    await compileWebFrontEnd(devMode: dev);
+
+    print('');
+
+    createResourcesGDart();
+  }
+}
+
+final File dartSources = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
+    'front_end', 'web', 'migration.dart'));
+
+final javascriptOutput = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
+    'front_end', 'resources', 'migration.js'));
+
+final Directory resourceDir = Directory(
+    path.join('pkg', 'nnbd_migration', 'lib', 'src', 'front_end', 'resources'));
+
+final File resourcesFile = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
+    'front_end', 'resources', 'resources.g.dart'));
+
+final List<String> resourceTypes = [
+  '.css',
+  '.html',
+  '.js',
+];
+
+String base64Encode(List<int> bytes) {
+  var encoded = base64.encode(bytes);
+
+  // Logic to cut lines into 80-character chunks.
+  var lines = <String>[];
+  var index = 0;
+
+  while (index < encoded.length) {
+    var line = encoded.substring(index, math.min(index + 80, encoded.length));
+    lines.add(line);
+    index += line.length;
+  }
+
+  return lines.join('\n');
+}
+
+void compileWebFrontEnd({bool devMode = false}) async {
+  var sdkBinDir = path.dirname(Platform.resolvedExecutable);
+  var dart2jsPath = path.join(sdkBinDir, 'dart2js');
+
+  // dart2js -m -o output source
+  var process = await Process.start(dart2jsPath, [
+    devMode ? '-O1' : '-m',
+    '--no-frequency-based-minification',
+    '-o',
+    javascriptOutput.path,
+    dartSources.path,
+  ]);
+  process.stdout.listen((List<int> data) => stdout.add(data));
+  process.stderr.listen((List<int> data) => stderr.add(data));
+  var exitCode = await process.exitCode;
+
+  if (exitCode != 0) {
+    fail('Failed compiling ${dartSources.path}.');
+  }
+}
+
+void createResourcesGDart() {
+  var content =
+      generateResourceFile(sortDir(resourceDir.listSync()).where((entity) {
+    var name = path.basename(entity.path);
+    return entity is File && resourceTypes.contains(path.extension(name));
+  }).cast<File>());
+
+  // write the content
+  resourcesFile.writeAsStringSync(content);
+}
+
+void fail(String message) {
+  stderr.writeln(message);
+  exit(1);
+}
+
+/// Fail the script, and print out a message indicating how to regenerate the
+/// resources file.
+void failGenerate(String message) {
+  stderr.writeln('$message.');
+  stderr.writeln();
+  stderr.writeln('''
+To re-generate lib/src/front_end/resources/resources.g.dart, run:
+
+  dart pkg/nnbd_migration/tool/codegen/generate_resources.dart
+''');
+  exit(1);
+}
+
+String generateResourceFile(Iterable<File> resources) {
+  var filePath = path.relative(Platform.script.toFilePath());
+  var buf = StringBuffer('''
+// 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 is generated; don't edit it directly.
+//
+// See $filePath for how
+// to edit the source content and for re-generation instructions.
+
+import 'dart:convert' as convert;
+''');
+
+  for (var resource in resources) {
+    var name = path.basename(resource.path).replaceAll('.', '_');
+    print('adding $name...');
+
+    buf.writeln();
+    buf.writeln('String get $name {');
+    buf.writeln('  return _$name ??= _decode(_${name}_base64);');
+    buf.writeln('}');
+  }
+
+  buf.writeln(r'''
+
+String _decode(String data) {
+  data = data.replaceAll('\n', '').trim();
+  return String.fromCharCodes(convert.base64Decode(data));
+}''');
+
+  for (var resource in resources) {
+    var name = path.basename(resource.path).replaceAll('.', '_');
+    var source = resource.readAsStringSync();
+
+    var delimiter = "'''";
+
+    buf.writeln();
+    buf.writeln('String _$name;');
+    if (name == path.basename(javascriptOutput.path).replaceAll('.', '_')) {
+      // Write out the crc for the dart code.
+      var sourceCode = StringBuffer();
+      // collect the dart source code
+      for (var entity in sortDir(dartSources.parent.listSync())) {
+        if (entity.path.endsWith('.dart')) {
+          sourceCode.write((entity as File).readAsStringSync());
+        }
+      }
+      buf.writeln(
+          "// migration_dart md5 is '${md5String(sourceCode.toString())}'");
+    } else {
+      // highlight_css md5 is 'fb012626bafd286510d32da815dae448'
+      buf.writeln("// $name md5 is '${md5String(source)}'");
+    }
+    buf.writeln('String _${name}_base64 = $delimiter');
+    buf.writeln(base64Encode(source.codeUnits));
+    buf.writeln('$delimiter;');
+  }
+
+  return buf.toString();
+}
+
+String md5String(String str) {
+  return md5.convert(str.codeUnits).toString();
+}
+
+List<FileSystemEntity> sortDir(Iterable<FileSystemEntity> entities) {
+  var result = entities.toList();
+  result.sort((a, b) => a.path.compareTo(b.path));
+  return result;
+}
+
+void verifyResourcesGDartGenerated({
+  VerificationFunction failVerification = failGenerate,
+}) {
+  print('Verifying that ${path.basename(resourcesFile.path)} is up-to-date...');
+
+  // Find the hashes for the last generated version of resources.g.dart.
+  var resourceHashes = <String, String>{};
+  // highlight_css md5 is 'fb012626bafd286510d32da815dae448'
+  var hashPattern = RegExp(r"// (\S+) md5 is '(\S+)'");
+  for (var match in hashPattern.allMatches(resourcesFile.readAsStringSync())) {
+    resourceHashes[match.group(1)] = match.group(2);
+  }
+
+  // For all resources (modulo compiled JS ones), verify the hash.
+  for (var entity in sortDir(resourceDir.listSync())) {
+    var name = path.basename(entity.path);
+    if (!resourceTypes.contains(path.extension(name))) {
+      continue;
+    }
+
+    if (name == 'migration.js') {
+      // skip the compiled js
+      continue;
+    }
+
+    var key = name.replaceAll('.', '_');
+    if (!resourceHashes.containsKey(key)) {
+      failVerification('No entry on resources.g.dart for $name');
+    } else {
+      var hash = md5String((entity as File).readAsStringSync());
+      if (hash != resourceHashes[key]) {
+        failVerification('$name not up to date in resources.g.dart');
+      }
+    }
+  }
+
+  // verify the compiled dart code
+  var sourceCode = StringBuffer();
+  for (var entity in sortDir(dartSources.parent.listSync())) {
+    if (entity.path.endsWith('.dart')) {
+      sourceCode.write((entity as File).readAsStringSync());
+    }
+  }
+  var hash = md5String(sourceCode.toString());
+  if (hash != resourceHashes['migration_dart']) {
+    failVerification('Compiled javascript not up to date in resources.g.dart');
+  }
+
+  print('Generated resources up to date.');
+}
+
+typedef VerificationFunction = void Function(String);
diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart
index 8731cef..21d4337 100644
--- a/pkg/nnbd_migration/tool/trial_migration.dart
+++ b/pkg/nnbd_migration/tool/trial_migration.dart
@@ -101,9 +101,13 @@
       'seconds');
   print('${listener.numTypesMadeNullable} types made nullable');
   print('${listener.numNullChecksAdded} null checks added');
+  print('${listener.numVariablesMarkedLate} variables marked late');
+  print('${listener.numInsertedCasts} casts inserted');
+  print('${listener.numInsertedParenthesis} parenthesis groupings inserted');
   print('${listener.numMetaImportsAdded} meta imports added');
   print('${listener.numRequiredAnnotationsAdded} required annotations added');
   print('${listener.numDeadCodeSegmentsFound} dead code segments found');
+  print('and ${listener.numOtherEdits} other edits not categorized');
   print('${listener.numExceptions} exceptions in '
       '${listener.groupedExceptions.length} categories');
 
@@ -125,25 +129,6 @@
   }
 }
 
-class ExceptionCategory {
-  final String topOfStack;
-  final List<MapEntry<String, int>> exceptionCountPerPackage;
-
-  ExceptionCategory(this.topOfStack, Map<String, int> exceptions)
-      : this.exceptionCountPerPackage = exceptions.entries.toList()
-          ..sort((e1, e2) => e2.value.compareTo(e1.value));
-
-  int get count => exceptionCountPerPackage.length;
-
-  List<String> get packageNames =>
-      [for (var entry in exceptionCountPerPackage) entry.key];
-
-  Iterable<String> get packageNamesAndCounts =>
-      exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');
-
-  String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
-}
-
 ArgResults parseArguments(List<String> args) {
   ArgParser argParser = ArgParser();
   ArgResults parsedArgs;
@@ -241,6 +226,25 @@
       'SDK at ${sdk.sdkPath} not compiled with --nnbd, use --sdk option');
 }
 
+class ExceptionCategory {
+  final String topOfStack;
+  final List<MapEntry<String, int>> exceptionCountPerPackage;
+
+  ExceptionCategory(this.topOfStack, Map<String, int> exceptions)
+      : this.exceptionCountPerPackage = exceptions.entries.toList()
+          ..sort((e1, e2) => e2.value.compareTo(e1.value));
+
+  int get count => exceptionCountPerPackage.length;
+
+  List<String> get packageNames =>
+      [for (var entry in exceptionCountPerPackage) entry.key];
+
+  Iterable<String> get packageNamesAndCounts =>
+      exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');
+
+  String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
+}
+
 class _Listener implements NullabilityMigrationListener {
   /// Set this to `true` to cause just the exception nodes to be printed when
   /// `_Listener.categoryOfInterest` is non-null.  Set this to `false` to cause
@@ -258,6 +262,12 @@
 
   int numTypesMadeNullable = 0;
 
+  int numVariablesMarkedLate = 0;
+
+  int numInsertedCasts = 0;
+
+  int numInsertedParenthesis = 0;
+
   int numNullChecksAdded = 0;
 
   int numMetaImportsAdded = 0;
@@ -266,31 +276,50 @@
 
   int numDeadCodeSegmentsFound = 0;
 
+  int numOtherEdits = 0;
+
   String currentPackage;
 
   _Listener(this.categoryOfInterest, {this.printExceptionNodeOnly = false});
 
   @override
   void addEdit(Source source, SourceEdit edit) {
+    if (edit.replacement == '') {
+      return;
+    }
+
+    if (edit.replacement.contains('!')) {
+      ++numNullChecksAdded;
+    }
+
+    if (edit.replacement.contains('(')) {
+      ++numInsertedParenthesis;
+    }
+
     if (edit.replacement == '?' && edit.length == 0) {
       ++numTypesMadeNullable;
-    } else if (edit.replacement == '!' && edit.length == 0) {
-      ++numNullChecksAdded;
     } else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
         edit.length == 0) {
       ++numMetaImportsAdded;
     } else if (edit.replacement == 'required ' && edit.length == 0) {
       ++numRequiredAnnotationsAdded;
+    } else if (edit.replacement == 'late ' && edit.length == 0) {
+      ++numVariablesMarkedLate;
+    } else if (edit.replacement.startsWith(' as ') && edit.length == 0) {
+      ++numInsertedCasts;
     } else if ((edit.replacement == '/* ' ||
             edit.replacement == ' /*' ||
             edit.replacement == '; /*') &&
         edit.length == 0) {
       ++numDeadCodeSegmentsFound;
-    } else if ((edit.replacement == '*/ ' || edit.replacement == ' */') &&
+    } else if ((edit.replacement == '*/ ' ||
+            edit.replacement == ' */' ||
+            edit.replacement == ')' ||
+            edit.replacement == '!' ||
+            edit.replacement == '(') &&
         edit.length == 0) {
-      // Already counted
     } else {
-      print('addEdit($source, $edit)');
+      numOtherEdits++;
     }
   }
 
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 18134be..b49a9be 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -24,6 +24,8 @@
 analyzer/test/src/summary/resynthesize_kernel_test: Slow, Pass
 analyzer/test/src/task/strong/checker_test: Slow, Pass
 analyzer_plugin/test/plugin/folding_mixin_test: Slow, Pass
+dartdev/test/commands/analyze_test: Slow, Pass
+dartdev/test/commands/help_test: Slow, Pass
 dev_compiler/test/modular/*: Slow, Pass
 dev_compiler/test/options/*: Skip # test needs fixes
 dev_compiler/test/sourcemap/*: SkipByDesign # Skip sourcemap tests
@@ -81,6 +83,7 @@
 modular_test/test/validate_pipeline_test: Slow, Pass
 modular_test/test/validate_suite_test: Slow, Pass
 nnbd_migration/test/*: SkipByDesign # Uses mirrors
+nnbd_migration/tool/*: SkipByDesign # Only meant to run on vm
 smith/test/*: SkipByDesign # Only meant to run on vm
 status_file/test/normalize_test: SkipByDesign # Uses dart:io
 status_file/test/parse_and_normalize_test: SkipByDesign # Uses dart:io
@@ -117,6 +120,7 @@
 analyzer/test/src/task/strong/inferred_type_test: Slow, Pass
 analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test: Slow, Pass
 analyzer_plugin/test/src/utilities/completion/optype_test: Slow, Pass
+dartdev/test/*: Slow, Pass
 mutation_observer: Skip # Skip tests on the VM if the package depends on dart:html
 
 [ $runtime != vm ]
diff --git a/pkg/smith/lib/builder.dart b/pkg/smith/lib/builder.dart
index 17b2e4e..673b0a9 100644
--- a/pkg/smith/lib/builder.dart
+++ b/pkg/smith/lib/builder.dart
@@ -97,11 +97,12 @@
   final System system;
   final Mode mode;
   final Architecture arch;
+  final Sanitizer sanitizer;
   final Runtime runtime;
   final List<Configuration> testedConfigurations;
 
   Builder(this.name, this.description, this.steps, this.system, this.mode,
-      this.arch, this.runtime, this.testedConfigurations);
+      this.arch, this.sanitizer, this.runtime, this.testedConfigurations);
 
   /// Create a [Builder] from its name, a list of 'step templates', the
   /// supported named configurations and a description.
@@ -115,6 +116,7 @@
     var systemName = _findPart(builderParts, System.names);
     var modeName = _findPart(builderParts, Mode.names);
     var archName = _findPart(builderParts, Architecture.names);
+    var sanitizerName = _findPart(builderParts, Sanitizer.names);
     var runtimeName = _findPart(builderParts, Runtime.names);
     var parsedSteps = steps
         .map((step) => Step.parse(
@@ -123,6 +125,7 @@
               "system": systemName,
               "mode": modeName,
               "arch": archName,
+              "sanitizer": sanitizerName,
               "runtime": runtimeName,
             },
             configurations))
@@ -135,6 +138,7 @@
         _findIfNotNull(System.find, systemName),
         _findIfNotNull(Mode.find, modeName),
         _findIfNotNull(Architecture.find, archName),
+        _findIfNotNull(Sanitizer.find, sanitizerName),
         _findIfNotNull(Runtime.find, runtimeName),
         testedConfigurations);
   }
@@ -157,7 +161,7 @@
 /// Replace the use of supported variable names with the their value given
 /// in [values] and throws an exception if an unsupported variable name is used.
 String _expandVariables(String string, Map<String, String> values) {
-  for (var variable in ["system", "mode", "arch", "runtime"]) {
+  for (var variable in ["system", "mode", "arch", "sanitizer", "runtime"]) {
     string = _tryReplace(string, variable, values[variable]);
   }
   return string;
diff --git a/pkg/telemetry/lib/crash_reporting.dart b/pkg/telemetry/lib/crash_reporting.dart
index 1590da8..7b4b958 100644
--- a/pkg/telemetry/lib/crash_reporting.dart
+++ b/pkg/telemetry/lib/crash_reporting.dart
@@ -18,9 +18,11 @@
 /// Crash backend host.
 const String _crashServerHost = 'clients2.google.com';
 
-// This should be one of 'report' or 'staging_report'.
-/// Path to the crash servlet.
-const String _crashEndpointPath = '/cr/staging_report';
+/// Path to the staging crash servlet.
+const String _crashEndpointPathStaging = '/cr/staging_report';
+
+/// Path to the prod crash servlet.
+const String _crashEndpointPathProd = '/cr/report';
 
 /// The field corresponding to the multipart/form-data file attachment where
 /// crash backend expects to find the Dart stack trace.
@@ -36,8 +38,7 @@
 ///
 /// Clients shouldn't extend, mixin or implement this class.
 class CrashReportSender {
-  static final Uri _baseUri = new Uri(
-      scheme: 'https', host: _crashServerHost, path: _crashEndpointPath);
+  final Uri _baseUri;
 
   static const int _maxReportsToSend = 1000;
 
@@ -50,12 +51,30 @@
   int _reportsSent = 0;
   int _skippedReports = 0;
 
-  /// Create a new [CrashReportSender].
-  CrashReportSender(
+  CrashReportSender._(
     this.crashProductId,
     this.shouldSend, {
     http.Client httpClient,
-  }) : _httpClient = httpClient ?? new http.Client();
+    String endpointPath = _crashEndpointPathStaging,
+  })  : _httpClient = httpClient ?? new http.Client(),
+        _baseUri = new Uri(
+            scheme: 'https', host: _crashServerHost, path: endpointPath);
+
+  /// Create a new [CrashReportSender] connected to the staging endpoint.
+  CrashReportSender.staging(
+    String crashProductId,
+    EnablementCallback shouldSend, {
+    http.Client httpClient,
+  }) : this._(crashProductId, shouldSend,
+            httpClient: httpClient, endpointPath: _crashEndpointPathStaging);
+
+  /// Create a new [CrashReportSender] connected to the prod endpoint.
+  CrashReportSender.prod(
+    String crashProductId,
+    EnablementCallback shouldSend, {
+    http.Client httpClient,
+  }) : this._(crashProductId, shouldSend,
+            httpClient: httpClient, endpointPath: _crashEndpointPathProd);
 
   /// Sends one crash report.
   ///
diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart
index be93424..440eee9 100644
--- a/pkg/telemetry/test/crash_reporting_test.dart
+++ b/pkg/telemetry/test/crash_reporting_test.dart
@@ -31,7 +31,7 @@
     };
 
     test('general', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -43,7 +43,7 @@
     });
 
     test('reportsSent', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -59,7 +59,7 @@
     });
 
     test('contains message', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -73,7 +73,7 @@
     });
 
     test('has attachments', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -94,7 +94,7 @@
     });
 
     test('has ptime', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 60d3a92..279de73 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -232,7 +232,7 @@
   };
 
   if ($isNnbd) {
-    sdk.dart.strictSubtypeChecks($isNnbdStrong);
+    sdk.dart.nullSafety($isNnbdStrong);
   }
 
   dartMainRunner(function testMainWrapper() {
diff --git a/pkg/test_runner/lib/src/co19_test_config.dart b/pkg/test_runner/lib/src/co19_test_config.dart
index 912545a..9a6337f 100644
--- a/pkg/test_runner/lib/src/co19_test_config.dart
+++ b/pkg/test_runner/lib/src/co19_test_config.dart
@@ -7,7 +7,7 @@
 import 'test_suite.dart';
 
 class Co19TestSuite extends StandardTestSuite {
-  static final _testRegExp = RegExp(r"t[0-9]{2}.dart$");
+  static final _testRegExp = RegExp(r"t[0-9]{2,3}.dart$");
 
   Co19TestSuite(TestConfiguration configuration, String selector)
       : super(configuration, selector, Path("tests/$selector/src"), [
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index f57b8ed..fe588a6 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -1092,6 +1092,8 @@
 
     var dillFile = tempKernelFile(tempDir);
 
+    var isProductMode = _configuration.configuration.mode == Mode.product;
+
     var causalAsyncStacks = !arguments.any(noCausalAsyncStacksRegExp.hasMatch);
 
     var args = [
@@ -1104,6 +1106,7 @@
           name.startsWith('-D') ||
           name.startsWith('--packages=') ||
           name.startsWith('--enable-experiment=')),
+      '-Ddart.vm.product=$isProductMode',
       '-Ddart.developer.causal_async_stacks=$causalAsyncStacks',
       if (_enableAsserts ||
           arguments.contains('--enable-asserts') ||
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index b5cf4ea..239ffcd 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -39,6 +39,7 @@
       this.silentFailures,
       this.printTiming,
       this.printReport,
+      this.reportFailures,
       this.reportInJson,
       this.resetBrowser,
       this.skipCompilation,
@@ -89,6 +90,7 @@
   final bool silentFailures;
   final bool printTiming;
   final bool printReport;
+  final bool reportFailures;
   final bool reportInJson;
   final bool resetBrowser;
   final bool skipCompilation;
@@ -496,12 +498,11 @@
   static const silent = Progress._('silent');
   static const status = Progress._('status');
   static const buildbot = Progress._('buildbot');
-  static const diff = Progress._('diff');
 
   static final List<String> names = _all.keys.toList();
 
   static final _all = Map<String, Progress>.fromIterable(
-      [compact, color, line, verbose, silent, status, buildbot, diff],
+      [compact, color, line, verbose, silent, status, buildbot],
       key: (progress) => (progress as Progress).name);
 
   static Progress find(String name) {
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 80224dd..648bd24 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -202,7 +202,7 @@
         '''Progress indication mode.
 
 Allowed values are:
-compact, color, line, verbose, silent, status, buildbot, diff''',
+compact, color, line, verbose, silent, status, buildbot''',
         abbr: 'p',
         values: Progress.names,
         defaultsTo: Progress.compact.name,
@@ -211,6 +211,8 @@
     _Option.bool('report',
         'Print a summary report of the number of tests, by expectation.',
         hide: true),
+    _Option.bool('report_failures', 'Print a summary of the tests that failed.',
+        hide: true),
     _Option.int('tasks', 'The number of parallel tasks to run.',
         abbr: 'j', defaultsTo: Platform.numberOfProcessors),
     _Option.int('shards',
@@ -366,6 +368,7 @@
     'progress',
     'repeat',
     'report',
+    'report_failures',
     'safari',
     'shard',
     'shards',
@@ -612,9 +615,8 @@
     // Only one value in the configuration map is mutable:
     if (selectors.containsKey('observatory_ui')) {
       if (selectors.length == 1) {
-        configuration['packages'] = Repository.uri
-            .resolve('runtime/observatory/.packages')
-            .toFilePath();
+        configuration['packages'] =
+            Repository.uri.resolve('.packages').toFilePath();
       } else {
         // Make a new configuration whose selectors map only contains
         // observatory_ui, and remove observatory_ui from the original
@@ -627,9 +629,8 @@
         selectors.remove('observatory_ui');
 
         // Set the packages flag.
-        observatoryConfiguration['packages'] = Repository.uri
-            .resolve('runtime/observatory/.packages')
-            .toFilePath();
+        observatoryConfiguration['packages'] =
+            Repository.uri.resolve('.packages').toFilePath();
 
         return [
           ..._expandConfigurations(configuration, selectors),
@@ -726,6 +727,7 @@
           silentFailures: data["silent_failures"] as bool,
           printTiming: data["time"] as bool,
           printReport: data["report"] as bool,
+          reportFailures: data["report_failures"] as bool,
           reportInJson: data["report_in_json"] as bool,
           resetBrowser: data["reset_browser_configuration"] as bool,
           skipCompilation: data["skip_compilation"] as bool,
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 7fe448c..477c73c 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -257,6 +257,9 @@
     if (isReload) {
       multiplier *= 2;
     }
+    if (_configuration.sanitizer != Sanitizer.none) {
+      multiplier *= 2;
+    }
     return multiplier;
   }
 }
diff --git a/pkg/test_runner/lib/src/summary_report.dart b/pkg/test_runner/lib/src/summary_report.dart
index bde80df..81aef69 100644
--- a/pkg/test_runner/lib/src/summary_report.dart
+++ b/pkg/test_runner/lib/src/summary_report.dart
@@ -6,6 +6,7 @@
 
 import "package:status_file/expectation.dart";
 
+import "terminal.dart";
 import "test_case.dart";
 
 final summaryReport = SummaryReport();
@@ -125,6 +126,6 @@
 
   void printReport() {
     if (_total == 0) return;
-    print(report);
+    Terminal.print(report);
   }
 }
diff --git a/pkg/test_runner/lib/src/terminal.dart b/pkg/test_runner/lib/src/terminal.dart
new file mode 100644
index 0000000..a96c846
--- /dev/null
+++ b/pkg/test_runner/lib/src/terminal.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+// TODO(rnystrom): Move all print calls to go through this. Unify with DebugLog.
+/// Interface for the test runner printing output to the user.
+///
+/// It mainly exists to gracefully handle the inline progress indicator:
+///
+///     [00:08 | 100% | +  139 | -    3]
+///
+/// That does not print a newline at the end, but subsequent output should
+/// insert the newline before writing itself. This tracks whether that needs to
+/// be done.
+class Terminal {
+  static bool _needsNewline = false;
+
+  /// Prints [obj] to its own line.
+  ///
+  /// If this is called after a call to [writeLine], prints a newline first to
+  /// end that earlier line.
+  static void print(Object obj) {
+    finishLine();
+    stdout.writeln(obj);
+  }
+
+  /// Overwrites the current line with [obj].
+  ///
+  /// Does not output a newline at the end.
+  static void writeLine(Object obj) {
+    stdout.write('\r$obj');
+    _needsNewline = true;
+  }
+
+  /// If the last output was from [writeLine], finishes it by writing a newline.
+  static void finishLine() {
+    if (_needsNewline) stdout.writeln();
+    _needsNewline = false;
+  }
+}
diff --git a/pkg/test_runner/lib/src/test_configurations.dart b/pkg/test_runner/lib/src/test_configurations.dart
index cce2e8d..4a77be1 100644
--- a/pkg/test_runner/lib/src/test_configurations.dart
+++ b/pkg/test_runner/lib/src/test_configurations.dart
@@ -12,6 +12,7 @@
 import 'configuration.dart';
 import 'path.dart';
 import 'process_queue.dart';
+import 'terminal.dart';
 import 'test_progress.dart';
 import 'test_suite.dart';
 import 'utils.dart';
@@ -55,7 +56,7 @@
   // Extract global options from first configuration.
   var firstConf = configurations[0];
   var maxProcesses = firstConf.taskCount;
-  var progressIndicator = firstConf.progress;
+  var progress = firstConf.progress;
   BuildbotProgressIndicator.stepName = firstConf.stepName;
   var verbose = firstConf.isVerbose;
   var printTiming = firstConf.printTiming;
@@ -69,11 +70,13 @@
   // Print the configurations being run by this execution of
   // test.dart. However, don't do it if the silent progress indicator
   // is used.
-  if (progressIndicator != Progress.silent) {
-    print('Test configuration${configurations.length > 1 ? 's' : ''}:');
+  if (progress != Progress.silent) {
+    Terminal.print(
+        'Test configuration${configurations.length > 1 ? 's' : ''}:');
     for (var configuration in configurations) {
-      print("    ${configuration.configuration}");
-      print("Suites tested: ${configuration.selectors.keys.join(", ")}");
+      Terminal.print("    ${configuration.configuration}");
+      Terminal.print(
+          "Suites tested: ${configuration.selectors.keys.join(", ")}");
     }
   }
 
@@ -86,7 +89,8 @@
   if (configurations.length > 1 &&
       (configurations[0].testServerPort != 0 ||
           configurations[0].testServerCrossOriginPort != 0)) {
-    print("If the http server ports are specified, only one configuration"
+    Terminal.print(
+        "If the http server ports are specified, only one configuration"
         " may be run at a time");
     exit(1);
   }
@@ -154,9 +158,9 @@
   // we return from running here and just print.
   if (firstConf.listStatusFiles) {
     for (var suite in testSuites) {
-      print(suite.suiteName);
+      Terminal.print(suite.suiteName);
       for (var statusFile in suite.statusFilePaths.toSet()) {
-        print("\t$statusFile");
+        Terminal.print("\t$statusFile");
       }
     }
     return;
@@ -176,41 +180,41 @@
   var eventListener = <EventListener>[];
 
   // We don't print progress if we list tests.
-  if (progressIndicator != Progress.silent && !listTests) {
-    var printFailures = true;
+  if (progress != Progress.silent && !listTests) {
     var formatter = Formatter.normal;
-    if (progressIndicator == Progress.color) {
-      progressIndicator = Progress.compact;
+    if (progress == Progress.color) {
+      progress = Progress.compact;
       formatter = Formatter.color;
     }
-    if (progressIndicator == Progress.diff) {
-      progressIndicator = Progress.compact;
-      formatter = Formatter.color;
-      printFailures = false;
-      eventListener.add(StatusFileUpdatePrinter());
-    }
-    if (firstConf.silentFailures) {
-      printFailures = false;
-    }
+
     eventListener.add(SummaryPrinter());
-    if (printFailures) {
-      // The buildbot has it's own failure summary since it needs to wrap it
-      // into '@@@'-annotated sections.
-      var printFailureSummary = progressIndicator != Progress.buildbot;
-      eventListener.add(TestFailurePrinter(printFailureSummary, formatter));
+    if (!firstConf.silentFailures) {
+      eventListener.add(TestFailurePrinter(formatter));
     }
+
     if (firstConf.printPassingStdout) {
       eventListener.add(PassingStdoutPrinter(formatter));
     }
-    eventListener.add(ProgressIndicator.fromProgress(
-        progressIndicator, startTime, formatter));
+
+    var indicator =
+        ProgressIndicator.fromProgress(progress, startTime, formatter);
+    if (indicator != null) eventListener.add(indicator);
+
     if (printTiming) {
       eventListener.add(TimingPrinter(startTime));
     }
+
     eventListener.add(SkippedCompilationsPrinter());
-    if (progressIndicator == Progress.status) {
+
+    if (progress == Progress.status) {
       eventListener.add(TimedProgressPrinter());
     }
+
+    if (firstConf.reportFailures) {
+      eventListener.add(FailedTestsPrinter());
+    }
+
+    eventListener.add(ResultCountPrinter(formatter));
   }
 
   if (firstConf.writeResults) {
diff --git a/pkg/test_runner/lib/src/test_progress.dart b/pkg/test_runner/lib/src/test_progress.dart
index 8fbc394..7faf841 100644
--- a/pkg/test_runner/lib/src/test_progress.dart
+++ b/pkg/test_runner/lib/src/test_progress.dart
@@ -13,6 +13,7 @@
 import 'configuration.dart';
 import 'path.dart';
 import 'summary_report.dart';
+import 'terminal.dart';
 import 'test_case.dart';
 import 'utils.dart';
 
@@ -81,9 +82,10 @@
 
   void callback(Timer timer) {
     if (_allKnown) {
-      print('$_numCompleted out of $_numTests completed');
+      Terminal.print('$_numCompleted out of $_numTests completed');
     }
-    print("Tests running for ${(interval * timer.tick).inMinutes} minutes");
+    Terminal.print(
+        "Tests running for ${(interval * timer.tick).inMinutes} minutes");
   }
 
   void testAdded() => _numTests++;
@@ -104,10 +106,11 @@
     if (test.lastCommandOutput.result(test) == Expectation.ignore) {
       countIgnored++;
       if (countIgnored > maxIgnored) {
-        print("\nMore than $maxIgnored tests were ignored due to flakes in");
-        print("the test infrastructure. Notify dart-engprod@.");
-        print("Output of the last ignored test was:");
-        print(_buildFailureOutput(test));
+        Terminal.print(
+            "\nMore than $maxIgnored tests were ignored due to flakes in");
+        Terminal.print("the test infrastructure. Notify dart-engprod@.");
+        Terminal.print("Output of the last ignored test was:");
+        Terminal.print(_buildFailureOutput(test));
         exit(1);
       }
     }
@@ -115,7 +118,7 @@
 
   void allDone() {
     if (countIgnored > 0) {
-      print("Ignored $countIgnored tests due to flaky infrastructure");
+      Terminal.print("Ignored $countIgnored tests due to flaky infrastructure");
     }
   }
 }
@@ -184,14 +187,14 @@
           unexpectedCrashesFile.writeStringSync(
               "${test.displayName},$pid,${binaries.join(',')}\n");
         } catch (e) {
-          print('Failed to add crash to unexpected-crashes list: $e');
+          Terminal.print('Failed to add crash to unexpected-crashes list: $e');
         } finally {
           try {
             if (unexpectedCrashesFile != null) {
               unexpectedCrashesFile.closeSync();
             }
           } catch (e) {
-            print('Failed to close unexpected-crashes file: $e');
+            Terminal.print('Failed to close unexpected-crashes file: $e');
           }
         }
       }
@@ -206,8 +209,8 @@
 
   void allTestsKnown() {
     if (jsonOnly) {
-      print("JSON:");
-      print(jsonEncode(summaryReport.values));
+      Terminal.print("JSON:");
+      Terminal.print(jsonEncode(summaryReport.values));
     } else {
       summaryReport.printReport();
     }
@@ -232,7 +235,7 @@
 
   void allDone() {
     var d = DateTime.now().difference(_startTime);
-    print('\n--- Total time: ${_timeString(d)} ---');
+    Terminal.print('\n--- Total time: ${_timeString(d)} ---');
     var outputs = _commandOutputs.toList();
     outputs.sort((a, b) {
       return b.time.inMilliseconds - a.time.inMilliseconds;
@@ -246,75 +249,13 @@
         return "${testCase.configurationString}/${testCase.displayName}";
       }).join(', ');
 
-      print('${commandOutput.time} - '
+      Terminal.print('${commandOutput.time} - '
           '${command.displayName} - '
           '$testCasesDescription');
     }
   }
 }
 
-class StatusFileUpdatePrinter extends EventListener {
-  final Map<String, List<String>> statusToConfigs = {};
-
-  void done(TestCase test) {
-    if (test.unexpectedOutput) {
-      _printFailureOutput(test);
-    }
-  }
-
-  void allDone() {
-    _printFailureSummary();
-  }
-
-  void _printFailureOutput(TestCase test) {
-    var status = '${test.displayName}: ${test.result}';
-    var configs = statusToConfigs.putIfAbsent(status, () => <String>[]);
-    configs.add(test.configurationString);
-    if (test.lastCommandOutput.hasTimedOut) {
-      print('\n${test.displayName} timed out on ${test.configurationString}');
-    }
-  }
-
-  String _extractRuntime(String configuration) {
-    // Extract runtime from a configuration, for example,
-    // 'none-vm-checked release_ia32'.
-    var runtime = configuration.split(' ')[0].split('-');
-    return '${runtime[0]}-${runtime[1]}';
-  }
-
-  void _printFailureSummary() {
-    var groupedStatuses = <String, List<String>>{};
-    statusToConfigs.forEach((status, configs) {
-      var runtimeToConfiguration = <String, List<String>>{};
-      for (var config in configs) {
-        var runtime = _extractRuntime(config);
-        runtimeToConfiguration
-            .putIfAbsent(runtime, () => <String>[])
-            .add(config);
-      }
-
-      runtimeToConfiguration.forEach((runtime, runtimeConfigs) {
-        runtimeConfigs.sort((a, b) => a.compareTo(b));
-        var statuses = groupedStatuses.putIfAbsent(
-            '$runtime: $runtimeConfigs', () => <String>[]);
-        statuses.add(status);
-      });
-    });
-
-    if (groupedStatuses.isEmpty) return;
-
-    print('\n\nNecessary status file updates:');
-    groupedStatuses.forEach((String config, List<String> statuses) {
-      print('');
-      print('$config:');
-      statuses.sort((a, b) => a.compareTo(b));
-      for (var status in statuses) {
-        print('  $status');
-      }
-    });
-  }
-}
-
 class SkippedCompilationsPrinter extends EventListener {
   int _skippedCompilations = 0;
 
@@ -326,64 +267,84 @@
 
   void allDone() {
     if (_skippedCompilations > 0) {
-      print('\n$_skippedCompilations compilations were skipped because '
+      Terminal.print(
+          '\n$_skippedCompilations compilations were skipped because '
           'the previous output was already up to date.\n');
     }
   }
 }
 
-class LineProgressIndicator extends EventListener {
+class TestFailurePrinter extends EventListener {
+  final Formatter _formatter;
+
+  TestFailurePrinter([this._formatter = Formatter.normal]);
+
   void done(TestCase test) {
-    var status = 'pass';
-    if (test.unexpectedOutput) {
-      status = 'fail';
+    if (!test.unexpectedOutput) return;
+    for (var line in _buildFailureOutput(test, _formatter)) {
+      Terminal.print(line);
     }
-    print('Done ${test.configurationString} ${test.displayName}: $status');
   }
 }
 
-class TestFailurePrinter extends EventListener {
-  final bool _printSummary;
+/// Prints a one-line summary of passed and failed tests.
+class ResultCountPrinter extends EventListener {
   final Formatter _formatter;
-  final _failureSummary = <String>[];
   int _failedTests = 0;
   int _passedTests = 0;
 
-  TestFailurePrinter(this._printSummary, [this._formatter = Formatter.normal]);
+  ResultCountPrinter(this._formatter);
 
   void done(TestCase test) {
     if (test.unexpectedOutput) {
       _failedTests++;
-      var lines = _buildFailureOutput(test, _formatter);
-      for (var line in lines) {
-        print(line);
-      }
-      print('');
-      if (_printSummary) {
-        _failureSummary.addAll(lines);
-        _failureSummary.add('');
-      }
     } else {
       _passedTests++;
     }
   }
 
   void allDone() {
-    if (!_printSummary || _failureSummary.isEmpty) return;
+    var suffix = _passedTests != 1 ? 's' : '';
+    var passed =
+        '${_formatter.passed(_passedTests.toString())} test$suffix passed';
 
-    // Don't bother showing the summary if it's longer than the number of lines
-    // of successful test output. The benefit of the summary is that it saves
-    // you from scrolling past lots of passed tests to find the few failures.
-    // If most of the output *is* failures, showing them *twice* just makes it
-    // worse.
-    if (_passedTests <= _failureSummary.length) return;
-
-    print('\n=== Failure summary:\n');
-    for (var line in _failureSummary) {
-      print(line);
+    String summary;
+    if (_failedTests == 0) {
+      summary = 'All $passed';
+    } else {
+      summary = '$passed, ${_formatter.failed(_failedTests.toString())} failed';
     }
-    print('');
-    print(_buildSummaryEnd(_formatter, _failedTests));
+
+    var marker = _formatter.section('===');
+    Terminal.print('\n$marker $summary $marker');
+  }
+}
+
+/// Prints a list of the tests that failed.
+class FailedTestsPrinter extends EventListener {
+  final List<TestCase> _failedTests = [];
+
+  FailedTestsPrinter();
+
+  void done(TestCase test) {
+    if (test.unexpectedOutput) {
+      _failedTests.add(test);
+    }
+  }
+
+  void allDone() {
+    if (_failedTests.isEmpty) return;
+
+    Terminal.print('');
+    Terminal.print('=== Failed tests ===');
+    for (var test in _failedTests) {
+      var result = test.realResult.toString();
+      if (test.realExpected != Expectation.pass) {
+        result += ' (expected ${test.realExpected})';
+      }
+
+      Terminal.print('${test.displayName}: $result');
+    }
   }
 }
 
@@ -403,7 +364,7 @@
         commandOutput.describe(test, test.configuration.progress, output);
       }
       for (var line in lines) {
-        print(line);
+        Terminal.print(line);
       }
     }
   }
@@ -411,7 +372,7 @@
   void allDone() {}
 }
 
-class ProgressIndicator extends EventListener {
+abstract class ProgressIndicator extends EventListener {
   final DateTime _startTime;
   int _foundTests = 0;
   int _passedTests = 0;
@@ -426,11 +387,10 @@
       case Progress.compact:
         return CompactProgressIndicator(startTime, formatter);
       case Progress.line:
-        return LineProgressIndicator();
       case Progress.verbose:
-        return VerboseProgressIndicator(startTime);
+        return LineProgressIndicator(startTime);
       case Progress.status:
-        return ProgressIndicator(startTime);
+        return null;
       case Progress.buildbot:
         return BuildbotProgressIndicator(startTime);
     }
@@ -455,25 +415,13 @@
     _allTestsKnown = true;
   }
 
-  void _printDoneProgress(TestCase test) {}
+  void _printDoneProgress(TestCase test);
 
-  int _completedTests() => _passedTests + _failedTests;
+  int get _completedTests => _passedTests + _failedTests;
 }
 
 abstract class CompactIndicator extends ProgressIndicator {
   CompactIndicator(DateTime startTime) : super(startTime);
-
-  void allDone() {
-    if (_failedTests > 0) {
-      // We may have printed many failure logs, so reprint the summary data.
-      _printProgress();
-    }
-    print('');
-  }
-
-  void _printDoneProgress(TestCase test) => _printProgress();
-
-  void _printProgress();
 }
 
 class CompactProgressIndicator extends CompactIndicator {
@@ -482,8 +430,8 @@
   CompactProgressIndicator(DateTime startTime, this._formatter)
       : super(startTime);
 
-  void _printProgress() {
-    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
+  void _printDoneProgress(TestCase testCase) {
+    var percent = ((_completedTests / _foundTests) * 100).toInt().toString();
     var progressPadded = (_allTestsKnown ? percent : '--').padLeft(3);
     var passedPadded = _passedTests.toString().padLeft(5);
     var failedPadded = _failedTests.toString().padLeft(5);
@@ -491,58 +439,48 @@
     var progressLine = '\r[${_timeString(elapsed)} | $progressPadded% | '
         '+${_formatter.passed(passedPadded)} | '
         '-${_formatter.failed(failedPadded)}]';
-    stdout.write(progressLine);
+    Terminal.writeLine(progressLine);
+  }
+
+  void allDone() {
+    Terminal.finishLine();
   }
 }
 
-class VerboseProgressIndicator extends ProgressIndicator {
-  VerboseProgressIndicator(DateTime startTime) : super(startTime);
+class LineProgressIndicator extends ProgressIndicator {
+  LineProgressIndicator(DateTime startTime) : super(startTime);
 
   void _printDoneProgress(TestCase test) {
     var status = 'pass';
     if (test.unexpectedOutput) {
       status = 'fail';
     }
-    print('Done ${test.configurationString} ${test.displayName}: $status');
+    Terminal.print(
+        'Done ${test.configurationString} ${test.displayName}: $status');
   }
 }
 
 class BuildbotProgressIndicator extends ProgressIndicator {
   static String stepName;
-  final _failureSummary = <String>[];
 
   BuildbotProgressIndicator(DateTime startTime) : super(startTime);
 
-  void done(TestCase test) {
-    super.done(test);
-    if (test.unexpectedOutput) {
-      _failureSummary.addAll(_buildFailureOutput(test));
-    }
-  }
-
   void _printDoneProgress(TestCase test) {
     var status = 'pass';
     if (test.unexpectedOutput) {
       status = 'fail';
     }
-    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
-    print('Done ${test.configurationString} ${test.displayName}: $status');
-    print('@@@STEP_CLEAR@@@');
-    print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@');
+    var percent = ((_completedTests / _foundTests) * 100).toInt().toString();
+    Terminal.print(
+        'Done ${test.configurationString} ${test.displayName}: $status');
+    Terminal.print('@@@STEP_CLEAR@@@');
+    Terminal.print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@');
   }
 
   void allDone() {
-    if (!_failureSummary.isEmpty) {
-      print('@@@STEP_FAILURE@@@');
-      if (stepName != null) {
-        print('@@@BUILD_STEP $stepName failures@@@');
-      }
-      for (var line in _failureSummary) {
-        print(line);
-      }
-      print('');
-    }
-    print(_buildSummaryEnd(Formatter.normal, _failedTests));
+    if (_failedTests == 0) return;
+    Terminal.print('@@@STEP_FAILURE@@@');
+    if (stepName != null) Terminal.print('@@@BUILD_STEP $stepName failures@@@');
   }
 }
 
@@ -692,16 +630,6 @@
   output.write(arguments.map(escapeCommandLineArgument).join(' '));
 }
 
-String _buildSummaryEnd(Formatter formatter, int failedTests) {
-  if (failedTests == 0) {
-    return formatter.passed('\n===\n=== All tests succeeded\n===\n');
-  } else {
-    var pluralSuffix = failedTests != 1 ? 's' : '';
-    return formatter
-        .failed('\n===\n=== $failedTests test$pluralSuffix failed\n===\n');
-  }
-}
-
 /// Writes a results.json file with a line for each test.
 /// Each line is a json map with the test name and result and expected result.
 class ResultWriter extends EventListener {
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index b0cb187..6ac30e0 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -583,6 +583,8 @@
       _enqueueStandardTest(testFile, expectationSet, onTest);
     } else if (configuration.runtime.isBrowser) {
       _enqueueBrowserTest(testFile, expectationSet, onTest);
+    } else if (suiteName == 'service') {
+      _enqueueServiceTest(testFile, expectationSet, onTest);
     } else {
       _enqueueStandardTest(testFile, expectationSet, onTest);
     }
@@ -616,6 +618,45 @@
     }
   }
 
+  void _enqueueServiceTest(
+      TestFile testFile, Set<Expectation> expectations, TestCaseEvent onTest) {
+    var commonArguments = _commonArgumentsFromFile(testFile);
+
+    var vmOptionsList = getVmOptions(testFile);
+    assert(!vmOptionsList.isEmpty);
+
+    bool emitDdsTest = false;
+    for (int i = 0; i < 2; ++i) {
+      for (var vmOptionsVariant = 0;
+          vmOptionsVariant < vmOptionsList.length;
+          vmOptionsVariant++) {
+        var vmOptions = vmOptionsList[vmOptionsVariant];
+        var allVmOptions = vmOptions;
+        if (!extraVmOptions.isEmpty) {
+          allVmOptions = vmOptions.toList()..addAll(extraVmOptions);
+        }
+        if (emitDdsTest) {
+          allVmOptions.add('-DUSE_DDS=true');
+        }
+        var isCrashExpected = expectations.contains(Expectation.crash);
+        var commands = _makeCommands(
+            testFile,
+            vmOptionsVariant + (vmOptionsList.length * i),
+            allVmOptions,
+            commonArguments,
+            isCrashExpected);
+        var variantTestName =
+            testFile.name + '/${emitDdsTest ? 'dds' : 'service'}';
+        if (vmOptionsList.length > 1) {
+          variantTestName = "${testFile.name}_$vmOptionsVariant";
+        }
+
+        _addTestCase(testFile, variantTestName, commands, expectations, onTest);
+      }
+      emitDdsTest = true;
+    }
+  }
+
   List<Command> _makeCommands(TestFile testFile, int vmOptionsVariant,
       List<String> vmOptions, List<String> args, bool isCrashExpected) {
     var commands = <Command>[];
diff --git a/pkg/test_runner/tool/update_static_error_tests.dart b/pkg/test_runner/tool/update_static_error_tests.dart
index 56ad830..fcdd01d 100644
--- a/pkg/test_runner/tool/update_static_error_tests.dart
+++ b/pkg/test_runner/tool/update_static_error_tests.dart
@@ -165,14 +165,24 @@
   var errors = <StaticError>[];
   if (insertAnalyzer) {
     stdout.write("\r${file.path} (Running analyzer...)");
-    errors.addAll(await runAnalyzer(file.absolute.path, options));
+    var fileErrors = await runAnalyzer(file.absolute.path, options);
+    if (fileErrors == null) {
+      print("Error: failed to update ${file.path}");
+    } else {
+      errors.addAll(fileErrors);
+    }
   }
 
   if (insertCfe) {
     // Clear the previous line.
     stdout.write("\r${file.path}                      ");
     stdout.write("\r${file.path} (Running CFE...)");
-    errors.addAll(await runCfe(file.absolute.path, options));
+    var fileErrors = await runCfe(file.absolute.path, options);
+    if (fileErrors == null) {
+      print("Error: failed to update ${file.path}");
+    } else {
+      errors.addAll(fileErrors);
+    }
   }
 
   errors = StaticError.simplify(errors);
@@ -203,6 +213,15 @@
         "--format=machine",
         path,
       ]);
+
+  // Analyzer returns 3 when it detects errors, 2 when it detects
+  // warnings and --fatal-warnings is enabled, 1 when it detects
+  // hints and --fatal-hints or --fatal-infos are enabled.
+  if (result.exitCode < 0 || result.exitCode > 3) {
+    print("Analyzer run failed: ${result.stdout}\n${result.stderr}");
+    return null;
+  }
+
   var errors = <StaticError>[];
   AnalysisCommandOutput.parseErrors(result.stderr as String, errors);
   return errors;
@@ -223,9 +242,16 @@
     path,
   ]);
 
-  // TODO(karlklose): handle exit codes != 0. This can happen if the dart
-  // executable is not compatible with the kernel package version.
-
+  // Running the above command may generate a dill file next to the test, which
+  // we don't want, so delete it if present.
+  var file = File("$path.dill");
+  if (await file.exists()) {
+    await file.delete();
+  }
+  if (result.exitCode != 0) {
+    print("CFE run failed: ${result.stdout}\n${result.stderr}");
+    return null;
+  }
   var errors = <StaticError>[];
   FastaCommandOutput.parseErrors(result.stdout as String, errors);
   return errors;
diff --git a/pkg/testing/lib/src/analyze.dart b/pkg/testing/lib/src/analyze.dart
index f9a23ee..fd4d17f 100644
--- a/pkg/testing/lib/src/analyze.dart
+++ b/pkg/testing/lib/src/analyze.dart
@@ -137,8 +137,8 @@
     return kind == null
         ? "Malformed output from dartanalyzer:\n$message"
         : "${uri.toFilePath()}:$line:$startColumn: "
-        "${kind == 'INFO' ? 'warning: hint' : kind.toLowerCase()}:\n"
-        "[$code] $message";
+            "${kind == 'INFO' ? 'warning: hint' : kind.toLowerCase()}:\n"
+            "[$code] $message";
   }
 }
 
@@ -169,10 +169,18 @@
   } catch (e) {
     topLevel = Uri.base.toFilePath(windows: false);
   }
+  if (Platform.isWindows) {
+    // We need lowercase comparison on Windows to match C:/path with c:/path
+    topLevel = topLevel.toLowerCase();
+  }
 
   String toFilePath(Uri uri) {
     String path = uri.toFilePath(windows: false);
-    return path.startsWith(topLevel) ? path.substring(topLevel.length) : path;
+    return (Platform.isWindows
+            ? path.toLowerCase().startsWith(topLevel)
+            : path.startsWith(topLevel))
+        ? path.substring(topLevel.length)
+        : path;
   }
 
   Set<String> filesToAnalyze = new Set<String>();
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 050407d..a0bd437 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -28,8 +28,10 @@
 import 'dart:typed_data' show Uint8List;
 
 import 'package:build_integration/file_system/multi_root.dart';
+import 'package:front_end/src/api_prototype/experimental_flags.dart';
 import 'package:front_end/src/api_prototype/front_end.dart' as fe
     show CompilerResult;
+import 'package:front_end/src/api_prototype/language_version.dart';
 import 'package:front_end/src/api_prototype/memory_file_system.dart';
 import 'package:front_end/src/api_unstable/vm.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
@@ -77,13 +79,30 @@
 
 bool allowDartInternalImport = false;
 
+// Null Safety command line options
+//
+// Note: The values of these constants must match the
+// values of flag null_safety in ../../../../runtime/vm/flag_list.h.
+// 0 - No null_safety option specified on the command line.
+// 1 - '--no-null-safety' specified on the command line.
+// 2 - '--null-safety' option specified on the command line.
+const int kNullSafetyOptionUnspecified = 0;
+const int kNullSafetyOptionWeak = 1;
+const int kNullSafetyOptionStrong = 2;
+
+Future<void> autoDetectNullSafetyMode(
+    Uri script, CompilerOptions options) async {
+  var isLegacy = await uriUsesLegacyLanguageVersion(script, options);
+  options.nnbdMode = isLegacy ? NnbdMode.Weak : NnbdMode.Strong;
+}
+
 abstract class Compiler {
   final int isolateId;
   final FileSystem fileSystem;
   final Uri platformKernelPath;
   final bool suppressWarnings;
   final bool enableAsserts;
-  final bool nullSafety;
+  final int nullSafety;
   final List<String> experimentalFlags;
   final bool bytecode;
   final String packageConfig;
@@ -100,7 +119,7 @@
   Compiler(this.isolateId, this.fileSystem, this.platformKernelPath,
       {this.suppressWarnings: false,
       this.enableAsserts: false,
-      this.nullSafety: false,
+      this.nullSafety: kNullSafetyOptionUnspecified,
       this.experimentalFlags: null,
       this.bytecode: false,
       this.supportCodeCoverage: false,
@@ -139,7 +158,9 @@
           parseExperimentalArguments(expFlags),
           onError: (msg) => errors.add(msg))
       ..environmentDefines = new EnvironmentMap()
-      ..nnbdMode = nullSafety ? NnbdMode.Strong : NnbdMode.Weak
+      ..nnbdMode = (nullSafety == kNullSafetyOptionStrong)
+          ? NnbdMode.Strong
+          : NnbdMode.Weak
       ..onDiagnostic = (DiagnosticMessage message) {
         bool printMessage;
         switch (message.severity) {
@@ -294,7 +315,7 @@
       int isolateId, FileSystem fileSystem, Uri platformKernelPath,
       {bool suppressWarnings: false,
       bool enableAsserts: false,
-      bool nullSafety: false,
+      int nullSafety: kNullSafetyOptionUnspecified,
       List<String> experimentalFlags: null,
       bool bytecode: false,
       String packageConfig: null})
@@ -334,6 +355,10 @@
   @override
   Future<CompilerResult> compileInternal(Uri script) async {
     if (generator == null) {
+      if ((nullSafety == kNullSafetyOptionUnspecified) &&
+          options.experimentalFlags[ExperimentalFlag.nonNullable]) {
+        await autoDetectNullSafetyMode(script, options);
+      }
       generator = new IncrementalCompiler(options, script);
     }
     errors.clear();
@@ -381,7 +406,7 @@
       {this.requireMain: false,
       bool suppressWarnings: false,
       bool enableAsserts: false,
-      bool nullSafety: false,
+      int nullSafety: kNullSafetyOptionUnspecified,
       List<String> experimentalFlags: null,
       bool bytecode: false,
       String packageConfig: null})
@@ -395,6 +420,10 @@
 
   @override
   Future<CompilerResult> compileInternal(Uri script) async {
+    if ((nullSafety == kNullSafetyOptionUnspecified) &&
+        options.experimentalFlags[ExperimentalFlag.nonNullable]) {
+      await autoDetectNullSafetyMode(script, options);
+    }
     fe.CompilerResult compilerResult = requireMain
         ? await kernelForProgram(script, options)
         : await kernelForModule([script], options);
@@ -423,7 +452,7 @@
     List sourceFiles, Uri platformKernelPath, List<int> platformKernel,
     {bool suppressWarnings: false,
     bool enableAsserts: false,
-    bool nullSafety: false,
+    int nullSafety: kNullSafetyOptionUnspecified,
     List<String> experimentalFlags: null,
     bool bytecode: false,
     String packageConfig: null,
@@ -691,6 +720,7 @@
           prepend = ", ";
           if (sb.length > 256) break;
         }
+        sb.write("]");
         partToString = sb.toString();
       } else {
         partToString = part.toString();
@@ -724,7 +754,7 @@
   final Uri script =
       inputFileUri != null ? Uri.base.resolve(inputFileUri) : null;
   final bool incremental = request[4];
-  final bool nullSafety = request[5];
+  final int nullSafety = request[5];
   final int isolateId = request[6];
   final List sourceFiles = request[7];
   final bool suppressWarnings = request[8];
@@ -954,7 +984,7 @@
     scriptUri,
     platformKernelPath,
     false /* incremental */,
-    false /* null safety */,
+    kNullSafetyOptionUnspecified /* null safety */,
     1 /* isolateId chosen randomly */,
     [] /* source files */,
     false /* suppress warnings */,
diff --git a/pkg/vm/lib/bytecode/declarations.dart b/pkg/vm/lib/bytecode/declarations.dart
index 273e443..c30f096 100644
--- a/pkg/vm/lib/bytecode/declarations.dart
+++ b/pkg/vm/lib/bytecode/declarations.dart
@@ -781,6 +781,7 @@
   static const isCovariantFlag = 1 << 0;
   static const isGenericCovariantImplFlag = 1 << 1;
   static const isFinalFlag = 1 << 2;
+  static const isRequiredFlag = 1 << 3;
 
   final ObjectHandle name;
   final ObjectHandle type;
@@ -971,6 +972,7 @@
   static const isSyncStarFlag = 1 << 6;
   static const isDebuggableFlag = 1 << 7;
   static const hasAttributesFlag = 1 << 8;
+  static const hasParameterFlagsFlag = 1 << 9;
 
   int flags;
   final ObjectHandle parent;
@@ -981,6 +983,7 @@
   final int numRequiredParams;
   final int numNamedParams;
   final List<NameAndType> parameters;
+  final List<int> parameterFlags;
   final ObjectHandle returnType;
   ObjectHandle attributes;
   ClosureCode code;
@@ -995,6 +998,7 @@
       this.numRequiredParams,
       this.numNamedParams,
       this.parameters,
+      this.parameterFlags,
       this.returnType,
       [this.attributes]);
 
@@ -1027,6 +1031,12 @@
       writer.writePackedObject(param.name);
       writer.writePackedObject(param.type);
     }
+    if ((flags & hasParameterFlagsFlag) != 0) {
+      writer.writePackedUInt30(parameterFlags.length);
+      for (var pf in parameterFlags) {
+        writer.writePackedUInt30(pf);
+      }
+    }
     writer.writePackedObject(returnType);
     if ((flags & hasAttributesFlag) != 0) {
       writer.writePackedObject(attributes);
@@ -1069,6 +1079,14 @@
         numParams,
         (_) => new NameAndType(
             reader.readPackedObject(), reader.readPackedObject()));
+    List<int> parameterFlags;
+    if ((flags & hasParameterFlagsFlag) != 0) {
+      final int numParameterFlags = reader.readPackedUInt30();
+      new List<int>.generate(
+          numParameterFlags, (_) => reader.readPackedUInt30());
+    } else {
+      parameterFlags = const <int>[];
+    }
     final returnType = reader.readPackedObject();
     final attributes =
         ((flags & hasAttributesFlag) != 0) ? reader.readPackedObject() : null;
@@ -1082,6 +1100,7 @@
         numRequiredParams,
         numNamedParams,
         parameters,
+        parameterFlags,
         returnType,
         attributes);
   }
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 60fd7d8..6a2d435 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -869,6 +869,9 @@
       if (variable.isFinal) {
         flags |= ParameterDeclaration.isFinalFlag;
       }
+      if (variable.isRequired) {
+        flags |= ParameterDeclaration.isRequiredFlag;
+      }
       return flags;
     }
 
@@ -2661,6 +2664,11 @@
       flags |= ClosureDeclaration.hasTypeParamsFlag;
     }
 
+    final List<int> parameterFlags = getParameterFlags(function);
+    if (parameterFlags != null) {
+      flags |= ClosureDeclaration.hasParameterFlagsFlag;
+    }
+
     return new ClosureDeclaration(
         flags,
         objectTable.getHandle(parent),
@@ -2671,6 +2679,7 @@
         function.requiredParameterCount,
         function.namedParameters.length,
         parameters,
+        parameterFlags,
         objectTable.getHandle(function.returnType));
   }
 
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 10eeeaa..841f84b 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -78,12 +78,14 @@
 
   _combinePendingDeltas(bool includePlatform) {
     Procedure mainMethod;
+    NonNullableByDefaultCompiledMode compilationMode;
     Map<Uri, Library> combined = <Uri, Library>{};
     Map<Uri, Source> uriToSource = new Map<Uri, Source>();
     for (Component delta in _pendingDeltas) {
       if (delta.mainMethod != null) {
         mainMethod = delta.mainMethod;
       }
+      compilationMode = delta.mode;
       uriToSource.addAll(delta.uriToSource);
       for (Library library in delta.libraries) {
         bool isPlatform =
@@ -96,7 +98,7 @@
     // TODO(vegorov) this needs to merge metadata repositories from deltas.
     return new Component(
         libraries: combined.values.toList(), uriToSource: uriToSource)
-      ..mainMethod = mainMethod;
+      ..setMainMethodAndMode(mainMethod?.reference, true, compilationMode);
   }
 
   CoreTypes getCoreTypes() => _generator.getCoreTypes();
@@ -131,7 +133,8 @@
     _lastKnownGood = new Component(
       libraries: combined.values.toList(),
       uriToSource: uriToSource,
-    )..mainMethod = candidate.mainMethod;
+    )..setMainMethodAndMode(
+        candidate.mainMethod?.reference, true, candidate.mode);
     for (final repo in candidate.metadata.values) {
       _lastKnownGood.addMetadataRepository(repo);
     }
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index e9bb876..834750e 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -78,6 +78,8 @@
   args.addOption('depfile', help: 'Path to output Ninja depfile');
   args.addFlag('link-platform',
       help: 'Include platform into resulting kernel file.', defaultsTo: true);
+  args.addFlag('minimal-kernel',
+      help: 'Produce minimal tree-shaken kernel file.', defaultsTo: false);
   args.addFlag('embed-sources',
       help: 'Embed source files in the generated kernel component',
       defaultsTo: true);
@@ -94,6 +96,9 @@
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: true);
+  args.addFlag('tree-shake-write-only-fields',
+      help: 'Enable tree shaking of fields which are only written in AOT mode.',
+      defaultsTo: false);
   args.addFlag('protobuf-tree-shaker',
       help: 'Enable protobuf tree shaker transformation in AOT mode.',
       defaultsTo: false);
@@ -167,6 +172,8 @@
   final bool nullSafety = options['null-safety'];
   final bool useProtobufTreeShaker = options['protobuf-tree-shaker'];
   final bool splitOutputByPackages = options['split-output-by-packages'];
+  final bool minimalKernel = options['minimal-kernel'];
+  final bool treeShakeWriteOnlyFields = options['tree-shake-write-only-fields'];
   final List<String> experimentalFlags = options['enable-experiment'];
   final Map<String, String> environmentDefines = {};
 
@@ -242,7 +249,9 @@
       genBytecode: genBytecode,
       bytecodeOptions: bytecodeOptions,
       dropAST: dropAST && !splitOutputByPackages,
-      useProtobufTreeShaker: useProtobufTreeShaker);
+      useProtobufTreeShaker: useProtobufTreeShaker,
+      minimalKernel: minimalKernel,
+      treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
 
   errorPrinter.printCompilationMessages();
 
@@ -255,7 +264,10 @@
   }
 
   final IOSink sink = new File(outputFileName).openWrite();
-  final BinaryPrinter printer = new BinaryPrinter(sink);
+  final BinaryPrinter printer = new BinaryPrinter(sink,
+      libraryFilter: minimalKernel
+          ? ((lib) => !results.loadedLibraries.contains(lib))
+          : null);
   printer.writeComponentFile(results.component);
   await sink.close();
 
@@ -314,7 +326,9 @@
     bool genBytecode: false,
     BytecodeOptions bytecodeOptions,
     bool dropAST: false,
-    bool useProtobufTreeShaker: false}) async {
+    bool useProtobufTreeShaker: false,
+    bool minimalKernel: false,
+    bool treeShakeWriteOnlyFields: false}) async {
   // Replace error handler to detect if there are compilation errors.
   final errorDetector =
       new ErrorDetector(previousErrorHandler: options.onDiagnostic);
@@ -325,21 +339,33 @@
 
   CompilerResult compilerResult = await kernelForProgram(source, options);
   Component component = compilerResult?.component;
-  final compiledSources = component?.uriToSource?.keys;
+  Iterable<Uri> compiledSources = component?.uriToSource?.keys;
 
   Set<Library> loadedLibraries = createLoadedLibrariesSet(
       compilerResult?.loadedComponents, compilerResult?.sdkComponent,
       includePlatform: includePlatform);
 
   // Run global transformations only if component is correct.
-  if (aot && component != null) {
+  if ((aot || minimalKernel) && component != null) {
     await runGlobalTransformations(
         options.target,
         component,
         useGlobalTypeFlowAnalysis,
         enableAsserts,
         useProtobufTreeShaker,
-        errorDetector);
+        errorDetector,
+        minimalKernel: minimalKernel,
+        treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
+
+    if (minimalKernel) {
+      // compiledSources is component.uriToSource.keys.
+      // Make a copy of compiledSources to detach it from
+      // component.uriToSource which is cleared below.
+      compiledSources = compiledSources.toList();
+
+      component.metadata.clear();
+      component.uriToSource.clear();
+    }
   }
 
   if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
@@ -404,7 +430,9 @@
     bool useGlobalTypeFlowAnalysis,
     bool enableAsserts,
     bool useProtobufTreeShaker,
-    ErrorDetector errorDetector) async {
+    ErrorDetector errorDetector,
+    {bool minimalKernel: false,
+    bool treeShakeWriteOnlyFields: false}) async {
   if (errorDetector.hasCompilationErrors) return;
 
   final coreTypes = new CoreTypes(component);
@@ -422,7 +450,9 @@
   unreachable_code_elimination.transformComponent(component, enableAsserts);
 
   if (useGlobalTypeFlowAnalysis) {
-    globalTypeFlow.transformComponent(target, coreTypes, component);
+    globalTypeFlow.transformComponent(target, coreTypes, component,
+        treeShakeSignatures: !minimalKernel,
+        treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
   } else {
     devirtualization.transformComponent(coreTypes, component);
     no_dynamic_invocations_annotator.transformComponent(component);
@@ -436,7 +466,9 @@
     protobuf_tree_shaker.removeUnusedProtoReferences(
         component, coreTypes, null);
 
-    globalTypeFlow.transformComponent(target, coreTypes, component);
+    globalTypeFlow.transformComponent(target, coreTypes, component,
+        treeShakeSignatures: !minimalKernel,
+        treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
   }
 
   // TODO(35069): avoid recomputing CSA by reading it from the platform files.
@@ -730,12 +762,13 @@
 
   final mainMethod = component.mainMethod;
   final problemsAsJson = component.problemsAsJson;
-  component.mainMethod = null;
+  final compilationMode = component.mode;
+  component.setMainMethodAndMode(null, true, compilationMode);
   component.problemsAsJson = null;
   for (String package in packages.keys) {
     await action(package, packages[package]);
   }
-  component.mainMethod = mainMethod;
+  component.setMainMethodAndMode(mainMethod?.reference, true, compilationMode);
   component.problemsAsJson = problemsAsJson;
 
   if (!mainFirst) {
diff --git a/pkg/vm/lib/metadata/table_selector.dart b/pkg/vm/lib/metadata/table_selector.dart
index 938d5c5..e692529 100644
--- a/pkg/vm/lib/metadata/table_selector.dart
+++ b/pkg/vm/lib/metadata/table_selector.dart
@@ -9,22 +9,32 @@
 // Information associated with a selector, used by the dispatch table generator.
 class TableSelectorInfo {
   static const int kCalledOnNullBit = 1 << 0;
-  static const int kCallCountShift = 1;
+  static const int kTornOffBit = 1 << 1;
 
   int callCount;
-  bool calledOnNull;
+  int flags;
+
+  bool get calledOnNull => (flags & kCalledOnNullBit) != 0;
+  set calledOnNull(bool value) {
+    flags = value ? (flags | kCalledOnNullBit) : (flags & ~kCalledOnNullBit);
+  }
+
+  bool get tornOff => (flags & kTornOffBit) != 0;
+  set tornOff(bool value) {
+    flags = value ? (flags | kTornOffBit) : (flags & ~kTornOffBit);
+  }
 
   TableSelectorInfo()
       : callCount = 0,
-        calledOnNull = false;
+        flags = 0;
 
   TableSelectorInfo.readFromBinary(BinarySource source)
       : callCount = source.readUInt(),
-        calledOnNull = source.readByte() != 0;
+        flags = source.readByte();
 
   void writeToBinary(BinarySink sink) {
     sink.writeUInt30(callCount);
-    sink.writeByte(calledOnNull ? 1 : 0);
+    sink.writeByte(flags);
   }
 }
 
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index d95c679..cc259c5 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -61,10 +61,10 @@
       ChangedStructureNotifier changedStructureNotifier}) {
     super.performPreConstantEvaluationTransformations(
         component, coreTypes, libraries, diagnosticReporter,
-        logger: logger);
+        logger: logger, changedStructureNotifier: changedStructureNotifier);
     if (flags.trackWidgetCreation) {
       if (_widgetTracker == null) {
-        _widgetTracker = WidgetCreatorTracker();
+        _widgetTracker = WidgetCreatorTracker(changedStructureNotifier);
       }
       _widgetTracker.transform(component, libraries);
     }
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index c7cdbc3..033258f 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -119,7 +119,7 @@
       ChangedStructureNotifier changedStructureNotifier}) {
     super.performPreConstantEvaluationTransformations(
         component, coreTypes, libraries, diagnosticReporter,
-        logger: logger);
+        logger: logger, changedStructureNotifier: changedStructureNotifier);
     _patchVmConstants(coreTypes);
   }
 
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
index 43c9179..acbfa39 100644
--- a/pkg/vm/lib/transformations/devirtualization.dart
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -57,9 +57,14 @@
       return false;
     }
 
-    if (arguments.named.isNotEmpty) {
+    if (arguments.named.isNotEmpty || func.namedParameters.isNotEmpty) {
       final names = arguments.named.map((v) => v.name).toSet();
-      names.removeAll(func.namedParameters.map((v) => v.name));
+      for (var param in func.namedParameters) {
+        final passed = names.remove(param.name);
+        if (param.isRequired && !passed) {
+          return false;
+        }
+      }
       if (names.isNotEmpty) {
         return false;
       }
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index ee3028d..cecc5a0 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -67,9 +67,15 @@
   final LibraryIndex index =
       LibraryIndex(component, const ["dart:ffi", "dart:core"]);
   if (!index.containsLibrary("dart:ffi")) {
+    // TODO: This check doesn't make sense: "dart:ffi" is always loaded/created
+    // for the VM target.
     // If dart:ffi is not loaded, do not do the transformation.
     return ReplacedMembers({}, {});
   }
+  if (index.tryGetClass('dart:ffi', 'NativeFunction') == null) {
+    // If dart:ffi is not loaded (for real): do not do the transformation.
+    return ReplacedMembers({}, {});
+  }
   final transformer = new _FfiDefinitionTransformer(index, coreTypes, hierarchy,
       diagnosticReporter, referenceFromIndex, changedStructureNotifier);
   libraries.forEach(transformer.visitLibrary);
@@ -128,7 +134,7 @@
     if (fieldsValid) {
       final structSize = _replaceFields(node, indexedClass);
       _replaceSizeOfMethod(node, structSize, indexedClass);
-      changedStructureNotifier?.forClass(node);
+      changedStructureNotifier?.registerClassMemberChange(node);
     }
 
     return node;
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 9ac20c8..aec594f 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -38,9 +38,15 @@
     ReferenceFromIndex referenceFromIndex) {
   final index = new LibraryIndex(component, ["dart:ffi"]);
   if (!index.containsLibrary("dart:ffi")) {
+    // TODO: This check doesn't make sense: "dart:ffi" is always loaded/created
+    // for the VM target.
     // If dart:ffi is not loaded, do not do the transformation.
     return;
   }
+  if (index.tryGetClass('dart:ffi', 'NativeFunction') == null) {
+    // If dart:ffi is not loaded (for real): do not do the transformation.
+    return;
+  }
   final transformer = new _FfiUseSiteTransformer(
       index,
       coreTypes,
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
index fcf8224..f9bf6b9 100644
--- a/pkg/vm/lib/transformations/mixin_deduplication.dart
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -9,15 +9,17 @@
 /// De-duplication of identical mixin applications.
 void transformComponent(Component component) {
   final deduplicateMixins = new DeduplicateMixinsTransformer();
-  final interfaceTargetResolver = InterfaceTargetResolver(deduplicateMixins);
+  final referenceUpdater = ReferenceUpdater(deduplicateMixins);
 
   // Deduplicate mixins and re-resolve super initializers.
   // (this is a shallow transformation)
   component.libraries.forEach(deduplicateMixins.visitLibrary);
 
-  // Do a deep transformation to re-resolve all interface targets that point to
-  // members of removed mixin application classes.
-
+  // Do a deep transformation to update references to the removed mixin
+  // application classes in the interface targets and types.
+  //
+  // Interface targets pointing to members of removed mixin application
+  // classes are re-resolved at the remaining mixin applications.
   // This is necessary iff the component was assembled from individual modular
   // kernel compilations:
   //
@@ -30,7 +32,11 @@
   // TODO(dartbug.com/39375): Remove this extra O(N) pass over the AST if the
   // CFE decides to consistently let the interface target point to the mixin
   // class (instead of mixin application).
-  component.libraries.forEach(interfaceTargetResolver.visitLibrary);
+  //
+  // Types could also contain references to removed mixin applications due to
+  // LUB algorithm in CFE (calculating static type of a conditional expression)
+  // and type inference which can spread types and produce derived types.
+  component.libraries.forEach(referenceUpdater.visitLibrary);
 }
 
 class _DeduplicateMixinKey {
@@ -140,46 +146,55 @@
       throw 'Unexpected node ${node.runtimeType}: $node';
 }
 
-/// Rewrites interface targets to point to the deduplicated mixin application
-/// class.
-class InterfaceTargetResolver extends RecursiveVisitor<TreeNode> {
+/// Rewrites references to the deduplicated mixin application
+/// classes. Updates interface targets and types.
+class ReferenceUpdater extends RecursiveVisitor<void> {
   final DeduplicateMixinsTransformer transformer;
+  final _visitedConstants = new Set<Constant>.identity();
 
-  InterfaceTargetResolver(this.transformer);
+  ReferenceUpdater(this.transformer);
 
-  defaultTreeNode(TreeNode node) {
-    node.visitChildren(this);
-    return node;
+  @override
+  visitLibrary(Library node) {
+    super.visitLibrary(node);
+    // Avoid accumulating too many constants in case of huge programs.
+    _visitedConstants.clear();
   }
 
+  @override
   visitPropertyGet(PropertyGet node) {
     node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
-    return super.visitPropertyGet(node);
+    super.visitPropertyGet(node);
   }
 
+  @override
   visitPropertySet(PropertySet node) {
     node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
-    return super.visitPropertySet(node);
+    super.visitPropertySet(node);
   }
 
+  @override
   visitMethodInvocation(MethodInvocation node) {
     node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
-    return super.visitMethodInvocation(node);
+    super.visitMethodInvocation(node);
   }
 
+  @override
   visitSuperPropertyGet(SuperPropertyGet node) {
     node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
-    return super.visitSuperPropertyGet(node);
+    super.visitSuperPropertyGet(node);
   }
 
+  @override
   visitSuperPropertySet(SuperPropertySet node) {
     node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
-    return super.visitSuperPropertySet(node);
+    super.visitSuperPropertySet(node);
   }
 
+  @override
   visitSuperMethodInvocation(SuperMethodInvocation node) {
     node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
-    return super.visitSuperMethodInvocation(node);
+    super.visitSuperMethodInvocation(node);
   }
 
   Member _resolveNewInterfaceTarget(Member m) {
@@ -205,6 +220,45 @@
       throw 'Hit unexpected interface target which is not a Field/Procedure';
     }
   }
+
+  @override
+  visitInterfaceType(InterfaceType node) {
+    node.className = _updateClassReference(node.className);
+    super.visitInterfaceType(node);
+  }
+
+  Reference _updateClassReference(Reference classRef) {
+    final Class c = classRef.asClass;
+    if (c != null && c.isAnonymousMixin) {
+      final Class replacement = transformer._duplicatedMixins[c];
+      if (replacement != null) {
+        return replacement.reference;
+      }
+    }
+    return classRef;
+  }
+
+  @override
+  defaultConstantReference(Constant node) {
+    // By default, RecursiveVisitor stops at constants. We need to go deeper
+    // into constants in order to update types which are only referenced from
+    // constants. However, constants are DAGs and not trees, so visiting
+    // the same constant multiple times should be avoided to prevent
+    // exponential running time.
+    if (_visitedConstants.add(node)) {
+      node.accept(this);
+    }
+  }
+
+  @override
+  visitClassReference(Class node) {
+    // Safeguard against any possible leaked uses of anonymous mixin
+    // applications which are not updated.
+    if (node.isAnonymousMixin && transformer._duplicatedMixins[node] != null) {
+      throw 'Unexpected reference to removed mixin application $node';
+    }
+    super.visitClassReference(node);
+  }
 }
 
 /// Corrects forwarding constructors inserted by mixin resolution after
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 651e5f5..ebabe3f 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -191,12 +191,17 @@
       case CallKind.PropertyGet:
         assertx(args.values.length == firstParamIndex);
         assertx(args.names.isEmpty);
+        fieldValue.isGetterUsed = true;
         return fieldValue.getValue(
             typeFlowAnalysis, field.isStatic ? null : args.values[0]);
 
       case CallKind.PropertySet:
+      case CallKind.SetFieldInConstructor:
         assertx(args.values.length == firstParamIndex + 1);
         assertx(args.names.isEmpty);
+        if (selector.callKind == CallKind.PropertySet) {
+          fieldValue.isSetterUsed = true;
+        }
         final Type setterArg = args.values[firstParamIndex];
         fieldValue.setValue(
             setterArg, typeFlowAnalysis, field.isStatic ? null : args.receiver);
@@ -206,6 +211,7 @@
         // Call via field.
         // TODO(alexmarkov): support function types and use inferred type
         // to get more precise return type.
+        fieldValue.isGetterUsed = true;
         final receiver = fieldValue.getValue(
             typeFlowAnalysis, field.isStatic ? null : args.values[0]);
         if (receiver != const EmptyType()) {
@@ -230,6 +236,9 @@
           // does not throw exception.
           initializerResult = new Type.nullable(initializerResult);
         }
+        if (kPrintTrace) {
+          tracePrint("Result of ${field} initializer: $initializerResult");
+        }
         fieldValue.setValue(initializerResult, typeFlowAnalysis,
             field.isStatic ? null : args.receiver);
         fieldValue.isInitialized = true;
@@ -772,6 +781,12 @@
   /// Flag indicating if field initializer was executed.
   bool isInitialized = false;
 
+  /// Flag indicating if field getter was executed.
+  bool isGetterUsed = false;
+
+  /// Flag indicating if field setter was executed.
+  bool isSetterUsed = false;
+
   _FieldValue(this.field, this.typeGuardSummary, TypesBuilder typesBuilder)
       : staticType = typesBuilder.fromStaticType(field.type, true) {
     if (field.initializer == null && _isDefaultValueOfFieldObservable()) {
@@ -989,7 +1004,7 @@
     result = new List<Type>(flattenedTypeArgs.length);
     for (int i = 0; i < flattenedTypeArgs.length; ++i) {
       final translated = closedTypeTranslator.translate(flattenedTypeArgs[i]);
-      assertx(translated is RuntimeType || translated is AnyType);
+      assertx(translated is RuntimeType || translated is UnknownType);
       result[i] = translated;
     }
     cachedFlattenedTypeArgsForNonGeneric[klass] = result;
@@ -1393,6 +1408,26 @@
     return false;
   }
 
+  /// Returns true if analysis found that getter corresponding to the given
+  /// [field] could be executed.
+  bool isFieldGetterUsed(Field field) {
+    final fieldValue = _fieldValues[field];
+    if (fieldValue != null) {
+      return fieldValue.isGetterUsed;
+    }
+    return false;
+  }
+
+  /// Returns true if analysis found that setter corresponding to the given
+  /// [field] could be executed.
+  bool isFieldSetterUsed(Field field) {
+    final fieldValue = _fieldValues[field];
+    if (fieldValue != null) {
+      return fieldValue.isSetterUsed;
+    }
+    return false;
+  }
+
   bool isClassAllocated(Class c) => hierarchyCache.allocatedClasses.contains(c);
 
   Call callSite(TreeNode node) => summaryCollector.callSites[node];
@@ -1400,6 +1435,8 @@
   TypeCheck explicitCast(AsExpression cast) =>
       summaryCollector.explicitCasts[cast];
 
+  NarrowNotNull nullTest(TreeNode node) => summaryCollector.nullTests[node];
+
   Type fieldType(Field field) => _fieldValues[field]?.value;
 
   Args<Type> argumentTypes(Member member) => _summaries[member]?.argumentTypes;
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index 06b20ec..55ff9ef 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -16,7 +16,8 @@
   Method, // x.foo(..) or foo()
   PropertyGet, // ... x.foo ...
   PropertySet, // x.foo = ...
-  FieldInitializer,
+  FieldInitializer, // run initializer of a field
+  SetFieldInConstructor, // foo = ... in initializer list in a constructor
 }
 
 /// [Selector] encapsulates the way of calling (at the call site).
@@ -55,6 +56,7 @@
         return member.getterType;
       case CallKind.PropertySet:
       case CallKind.FieldInitializer:
+      case CallKind.SetFieldInConstructor:
         return const BottomType();
     }
     return null;
@@ -72,7 +74,8 @@
       case CallKind.PropertySet:
         return (member is Field) || ((member is Procedure) && member.isSetter);
       case CallKind.FieldInitializer:
-        return (member is Field);
+      case CallKind.SetFieldInConstructor:
+        return member is Field;
     }
     return false;
   }
@@ -84,6 +87,7 @@
       case CallKind.PropertyGet:
         return 'get ';
       case CallKind.PropertySet:
+      case CallKind.SetFieldInConstructor:
         return 'set ';
       case CallKind.FieldInitializer:
         return 'init ';
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index 17f01c6..8e66c3e 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -134,6 +134,49 @@
       arg.getComputedType(computedTypes).intersection(type, typeHierarchy);
 }
 
+/// A flavor of [Narrow] statement which narrows argument
+/// to a non-nullable type and records if argument can be
+/// null or not null.
+class NarrowNotNull extends Narrow {
+  static const int canBeNullFlag = 1 << 0;
+  static const int canBeNotNullFlag = 1 << 1;
+  int _flags = 0;
+
+  NarrowNotNull(TypeExpr arg) : super(arg, const AnyType());
+
+  // Shared NarrowNotNull instances which are used when the outcome is
+  // known at summary creation time.
+  static final NarrowNotNull alwaysNotNull = NarrowNotNull(null)
+    .._flags = canBeNotNullFlag;
+  static final NarrowNotNull alwaysNull = NarrowNotNull(null)
+    .._flags = canBeNullFlag;
+  static final NarrowNotNull unknown = NarrowNotNull(null)
+    .._flags = canBeNullFlag | canBeNotNullFlag;
+
+  bool get isAlwaysNull => (_flags & canBeNotNullFlag) == 0;
+  bool get isAlwaysNotNull => (_flags & canBeNullFlag) == 0;
+
+  Type handleArgument(Type argType) {
+    if (argType is NullableType) {
+      final baseType = argType.baseType;
+      if (baseType is EmptyType) {
+        _flags |= canBeNullFlag;
+      } else {
+        _flags |= (canBeNullFlag | canBeNotNullFlag);
+      }
+      return baseType;
+    } else {
+      _flags |= canBeNotNullFlag;
+      return argType;
+    }
+  }
+
+  @override
+  Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+          CallHandler callHandler) =>
+      handleArgument(arg.getComputedType(computedTypes));
+}
+
 /// Joins values from multiple sources. Its type is a union of [values].
 class Join extends Statement {
   final String _name;
@@ -339,7 +382,7 @@
 
     void extractType(ConcreteType c) {
       if (c.typeArgs == null) {
-        extractedType = const AnyType();
+        extractedType = const UnknownType();
       } else {
         final interfaceOffset = typeHierarchy.genericInterfaceOffsetFor(
             c.cls.classNode, referenceClass);
@@ -364,12 +407,12 @@
             }
           }
         } else {
-          assertx(typeArg is AnyType);
+          assertx(typeArg is UnknownType);
         }
         if (extractedType == null || extracted == extractedType) {
           extractedType = extracted;
         } else {
-          extractedType = const AnyType();
+          extractedType = const UnknownType();
         }
       }
     }
@@ -381,7 +424,7 @@
       argType.types.forEach(extractType);
     }
 
-    return extractedType ?? const AnyType();
+    return extractedType ?? const UnknownType();
   }
 }
 
@@ -414,7 +457,7 @@
     final types = new List<Type>(flattenedTypeArgs.length);
     for (int i = 0; i < types.length; ++i) {
       final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
-      assertx(computed is RuntimeType || computed is AnyType);
+      assertx(computed is RuntimeType || computed is UnknownType);
       if (computed is RuntimeType) hasRuntimeType = true;
       types[i] = computed;
     }
@@ -424,7 +467,7 @@
 
 // Similar to "CreateConcreteType", but creates a "RuntimeType" rather than a
 // "ConcreteType". Unlike a "ConcreteType", none of the type arguments can be
-// missing ("AnyType").
+// missing ("UnknownType").
 class CreateRuntimeType extends Statement {
   final Class klass;
   final Nullability nullability;
@@ -446,8 +489,8 @@
     final types = new List<RuntimeType>(flattenedTypeArgs.length);
     for (int i = 0; i < types.length; ++i) {
       final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
-      assertx(computed is RuntimeType || computed is AnyType);
-      if (computed is AnyType) return const AnyType();
+      assertx(computed is RuntimeType || computed is UnknownType);
+      if (computed is UnknownType) return const UnknownType();
       types[i] = computed;
     }
     return new RuntimeType(new InterfaceType(klass, nullability), types);
@@ -501,11 +544,11 @@
     Type argType = arg.getComputedType(computedTypes);
     Type checkType = type.getComputedType(computedTypes);
     // TODO(sjindel/tfa): Narrow the result if possible.
-    assertx(checkType is AnyType || checkType is RuntimeType);
+    assertx(checkType is UnknownType || checkType is RuntimeType);
 
     bool canSkip = true; // Can this check be skipped on this invocation.
 
-    if (checkType is AnyType) {
+    if (checkType is UnknownType) {
       // If we don't know what the RHS of the check is going to be, we can't
       // guarantee that it will pass.
       canSkip = false;
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index f0cf458..b95602b 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -65,7 +65,7 @@
     }
 
     for (Statement st in statements) {
-      if (st is Call || st is TypeCheck) {
+      if (st is Call || st is TypeCheck || st is NarrowNotNull) {
         _normalizeExpr(st, false);
       } else if (st is Use) {
         _normalizeExpr(st.arg, true);
@@ -114,6 +114,14 @@
               }
             }
           }
+        } else if (st is NarrowNotNull) {
+          // This pattern may appear after approximations during summary
+          // normalization, so it's not enough to handle it in
+          // _makeNarrowNotNull.
+          final arg = st.arg;
+          if (arg is Type) {
+            return st.handleArgument(arg);
+          }
         } else if (st is Narrow) {
           // This pattern may appear after approximations during summary
           // normalization (so it's not enough to handle it in _makeNarrow).
@@ -517,6 +525,7 @@
   final Map<TreeNode, Call> callSites = <TreeNode, Call>{};
   final Map<AsExpression, TypeCheck> explicitCasts =
       <AsExpression, TypeCheck>{};
+  final Map<TreeNode, NarrowNotNull> nullTests = <TreeNode, NarrowNotNull>{};
   final _FallthroughDetector _fallthroughDetector = new _FallthroughDetector();
   final Set<Name> _nullMethodsAndGetters = <Name>{};
   final Set<Name> _nullSetters = <Name>{};
@@ -584,7 +593,8 @@
 
   Summary createSummary(Member member,
       {fieldSummaryType: FieldSummaryType.kInitializer}) {
-    debugPrint("===== ${member} =====");
+    debugPrint(
+        "===== ${member}${fieldSummaryType == FieldSummaryType.kFieldGuard ? " (guard)" : ""} =====");
     assertx(!member.isAbstract);
 
     _staticTypeContext = new StaticTypeContext(member, _environment);
@@ -779,7 +789,7 @@
 
     final numTypeParameters = numTypeParams(member);
     for (int i = 0; i < numTypeParameters; ++i) {
-      args.add(const AnyType());
+      args.add(const UnknownType());
     }
 
     if (hasReceiverArg(member)) {
@@ -816,6 +826,7 @@
         break;
 
       case CallKind.PropertySet:
+      case CallKind.SetFieldInConstructor:
         args.add(new Type.nullableAny());
         break;
 
@@ -1102,6 +1113,37 @@
     return _makeNarrow(arg, _typesBuilder.fromStaticType(type, canBeNull));
   }
 
+  TypeExpr _makeNarrowNotNull(TreeNode node, TypeExpr arg) {
+    assertx(node is NullCheck ||
+        node is MethodInvocation && isComparisonWithNull(node));
+    if (arg is NarrowNotNull) {
+      nullTests[node] = arg;
+      return arg;
+    } else if (arg is Narrow) {
+      if (arg.type is! NullableType) {
+        nullTests[node] = NarrowNotNull.alwaysNotNull;
+        return arg;
+      }
+    } else if (arg is Type) {
+      if (arg is NullableType) {
+        final baseType = arg.baseType;
+        if (baseType is EmptyType) {
+          nullTests[node] = NarrowNotNull.alwaysNull;
+        } else {
+          nullTests[node] = NarrowNotNull.unknown;
+        }
+        return baseType;
+      } else {
+        nullTests[node] = NarrowNotNull.alwaysNotNull;
+        return arg;
+      }
+    }
+    final narrow = NarrowNotNull(arg);
+    nullTests[node] = narrow;
+    _summary.add(narrow);
+    return narrow;
+  }
+
   // Add an artificial use of given expression in order to make it possible to
   // infer its type even if it is not used in a summary.
   void _addUse(TypeExpr arg) {
@@ -1301,13 +1343,16 @@
           node.arguments.named.isEmpty);
       final lhs = node.receiver as VariableGet;
       final rhs = node.arguments.positional.single;
-      if (rhs is NullLiteral) {
+      if (isNullLiteral(rhs)) {
         // 'x == null', where x is a variable.
-        _addUse(_visit(node));
+        final expr = _visit(lhs);
+        _makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
+            Args<TypeExpr>([expr, _nullType]));
+        final narrowedNotNull = _makeNarrowNotNull(node, expr);
         final int varIndex = _variablesInfo.varIndex[lhs.variable];
         if (_variableCells[varIndex] == null) {
           trueState[varIndex] = _nullType;
-          falseState[varIndex] = _makeNarrow(_visit(lhs), const AnyType());
+          falseState[varIndex] = narrowedNotNull;
         }
         _variableValues = null;
         return;
@@ -1361,6 +1406,10 @@
     }
   }
 
+  Procedure _cachedUnsafeCast;
+  Procedure get unsafeCast => _cachedUnsafeCast ??= _environment.coreTypes.index
+      .getTopLevelMember('dart:_internal', 'unsafeCast');
+
   @override
   defaultTreeNode(TreeNode node) =>
       throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
@@ -1383,7 +1432,7 @@
   @override
   TypeExpr visitNullCheck(NullCheck node) {
     final operandNode = node.operand;
-    final TypeExpr result = _makeNarrow(_visit(operandNode), const AnyType());
+    final TypeExpr result = _makeNarrowNotNull(node, _visit(operandNode));
     if (operandNode is VariableGet) {
       final int varIndex = _variablesInfo.varIndex[operandNode.variable];
       if (_variableCells[varIndex] == null) {
@@ -1566,6 +1615,13 @@
 
   @override
   TypeExpr visitMethodInvocation(MethodInvocation node) {
+    if (isComparisonWithNull(node)) {
+      final arg = _visit(getArgumentOfComparisonWithNull(node));
+      _makeNarrowNotNull(node, arg);
+      _makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
+          Args<TypeExpr>([arg, _nullType]));
+      return _boolType;
+    }
     final receiverNode = node.receiver;
     final receiver = _visit(receiverNode);
     final args = _visitArguments(receiver, node.arguments);
@@ -1579,10 +1635,6 @@
     TypeExpr result;
     if (target == null) {
       if (node.name.name == '==') {
-        assertx(args.values.length == 2);
-        if ((args.values[0] == _nullType) || (args.values[1] == _nullType)) {
-          return _boolType;
-        }
         _makeCall(node, new DynamicSelector(CallKind.Method, node.name), args);
         return new Type.nullable(_boolType);
       }
@@ -1752,7 +1804,17 @@
         passTypeArguments: node.target.isFactory);
     final target = node.target;
     assertx((target is! Field) && !target.isGetter && !target.isSetter);
-    return _makeCall(node, new DirectSelector(target), args);
+    TypeExpr result = _makeCall(node, new DirectSelector(target), args);
+    if (target == unsafeCast) {
+      // Async transformation inserts unsafeCasts to make sure
+      // kernel is correctly typed. Instead of using the result of unsafeCast
+      // (which is an opaque native function), we can use its argument narrowed
+      // by the casted type.
+      final arg = args.values.single;
+      result = _makeNarrow(
+          arg, _typesBuilder.fromStaticType(node.arguments.types.single, true));
+    }
+    return result;
   }
 
   @override
@@ -2087,8 +2149,11 @@
   TypeExpr visitFieldInitializer(FieldInitializer node) {
     final value = _visit(node.value);
     final args = new Args<TypeExpr>([_receiver, value]);
-    _makeCall(node,
-        new DirectSelector(node.field, callKind: CallKind.PropertySet), args);
+    _makeCall(
+        node,
+        new DirectSelector(node.field,
+            callKind: CallKind.SetFieldInConstructor),
+        args);
     return null;
   }
 
@@ -2175,16 +2240,16 @@
     final flattenedTypeExprs = new List<TypeExpr>(flattenedTypeArgs.length);
 
     bool createConcreteType = true;
-    bool allAnyType = true;
+    bool allUnknown = true;
     for (int i = 0; i < flattenedTypeArgs.length; ++i) {
       final typeExpr =
           translate(substitution.substituteType(flattenedTypeArgs[i]));
-      if (typeExpr != const AnyType()) allAnyType = false;
+      if (typeExpr is! UnknownType) allUnknown = false;
       if (typeExpr is Statement) createConcreteType = false;
       flattenedTypeExprs[i] = typeExpr;
     }
 
-    if (allAnyType) return type;
+    if (allUnknown) return type;
 
     if (createConcreteType) {
       return new ConcreteType(
@@ -2199,7 +2264,7 @@
   // Creates a TypeExpr representing the set of types which can flow through a
   // given DartType.
   //
-  // Will return AnyType, RuntimeType or Statement.
+  // Will return UnknownType, RuntimeType or Statement.
   TypeExpr translate(DartType type) {
     final cached = typesCache[type];
     if (cached != null) return cached;
@@ -2209,18 +2274,19 @@
     //   class A<T> extends Comparable<A<T>> {}
     //
     // Creating the factored type arguments of A will lead to an infinite loop.
-    // We break such loops by inserting an 'AnyType' in place of the currently
+    // We break such loops by inserting an 'UnknownType' in place of the currently
     // processed type, ensuring we try to build 'A<T>' in the process of
     // building 'A<T>'.
-    typesCache[type] = const AnyType();
+    typesCache[type] = const UnknownType();
     final result = type.accept(this);
-    assertx(result is AnyType || result is RuntimeType || result is Statement);
+    assertx(
+        result is UnknownType || result is RuntimeType || result is Statement);
     typesCache[type] = result;
     return result;
   }
 
   @override
-  TypeExpr defaultDartType(DartType node) => const AnyType();
+  TypeExpr defaultDartType(DartType node) => const UnknownType();
 
   @override
   TypeExpr visitDynamicType(DynamicType type) => new RuntimeType(type, null);
@@ -2248,7 +2314,7 @@
     for (var i = 0; i < flattenedTypeArgs.length; ++i) {
       final typeExpr =
           translate(substitution.substituteType(flattenedTypeArgs[i]));
-      if (typeExpr == const AnyType()) return const AnyType();
+      if (typeExpr == const UnknownType()) return const UnknownType();
       if (typeExpr is! RuntimeType) createRuntimeType = false;
       flattenedTypeExprs[i] = typeExpr;
     }
@@ -2271,7 +2337,7 @@
       final result = functionTypeVariables[type.parameter];
       if (result != null) return result;
     }
-    if (type.parameter.parent is! Class) return const AnyType();
+    if (type.parameter.parent is! Class) return const UnknownType();
     final interfaceClass = type.parameter.parent as Class;
     assertx(receiver != null);
     // Undetermined nullability is equivalent to nonNullable when
diff --git a/pkg/vm/lib/transformations/type_flow/table_selector.dart b/pkg/vm/lib/transformations/type_flow/table_selector.dart
index 2533d48..571f190 100644
--- a/pkg/vm/lib/transformations/type_flow/table_selector.dart
+++ b/pkg/vm/lib/transformations/type_flow/table_selector.dart
@@ -60,16 +60,22 @@
     throw "Unexpected member kind '${member.runtimeType}'";
   }
 
-  void registerCall(int selectorId, bool calledOnNull) {
-    metadata.selectors[selectorId].callCount++;
-    metadata.selectors[selectorId].calledOnNull |= calledOnNull;
-  }
-
   void registerMethodOrSetterCall(Member member, bool calledOnNull) {
-    registerCall(methodOrSetterSelectorId(member), calledOnNull);
+    final TableSelectorInfo selector =
+        metadata.selectors[methodOrSetterSelectorId(member)];
+    selector.callCount++;
+    selector.calledOnNull |= calledOnNull;
   }
 
   void registerGetterCall(Member member, bool calledOnNull) {
-    registerCall(getterSelectorId(member), calledOnNull);
+    final TableSelectorInfo selector =
+        metadata.selectors[getterSelectorId(member)];
+    selector.callCount++;
+    selector.calledOnNull |= calledOnNull;
+    if (member is Procedure && member.kind == ProcedureKind.Method) {
+      final TableSelectorInfo methodSelector =
+          metadata.selectors[methodOrSetterSelectorId(member)];
+      methodSelector.tornOff = true;
+    }
   }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 296bc42..65d3abc 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -38,7 +38,9 @@
 /// Assumes strong mode and closed world.
 Component transformComponent(
     Target target, CoreTypes coreTypes, Component component,
-    {PragmaAnnotationParser matcher, bool treeShakeSignatures: true}) {
+    {PragmaAnnotationParser matcher,
+    bool treeShakeSignatures: true,
+    bool treeShakeWriteOnlyFields: true}) {
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
   final hierarchy = new ClassHierarchy(component, coreTypes,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
@@ -72,17 +74,20 @@
   final transformsStopWatch = new Stopwatch()..start();
 
   final treeShaker = new TreeShaker(component, typeFlowAnalysis,
-      treeShakeSignatures: treeShakeSignatures)
-    ..transformComponent(component);
+      treeShakeSignatures: treeShakeSignatures,
+      treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
+  treeShaker.transformComponent(component);
 
-  new TFADevirtualization(component, typeFlowAnalysis, hierarchy)
+  new TFADevirtualization(
+          component, typeFlowAnalysis, hierarchy, treeShaker.fieldMorpher)
       .visitComponent(component);
 
   final unboxingInfo = new UnboxingInfoManager(typeFlowAnalysis);
 
   _makePartition(component, typeFlowAnalysis, unboxingInfo);
 
-  new AnnotateKernel(component, typeFlowAnalysis, unboxingInfo)
+  new AnnotateKernel(
+          component, typeFlowAnalysis, treeShaker.fieldMorpher, unboxingInfo)
       .visitComponent(component);
 
   treeShaker.finalizeSignatures();
@@ -100,9 +105,10 @@
 /// Devirtualization based on results of type flow analysis.
 class TFADevirtualization extends Devirtualization {
   final TypeFlowAnalysis _typeFlowAnalysis;
+  final FieldMorpher fieldMorpher;
 
-  TFADevirtualization(
-      Component component, this._typeFlowAnalysis, ClassHierarchy hierarchy)
+  TFADevirtualization(Component component, this._typeFlowAnalysis,
+      ClassHierarchy hierarchy, this.fieldMorpher)
       : super(_typeFlowAnalysis.environment.coreTypes, component, hierarchy);
 
   @override
@@ -110,7 +116,8 @@
       {bool setter = false}) {
     final callSite = _typeFlowAnalysis.callSite(node);
     if (callSite != null) {
-      final Member singleTarget = callSite.monomorphicTarget;
+      final Member singleTarget = fieldMorpher
+          .getMorphedMember(callSite.monomorphicTarget, isSetter: setter);
       if (singleTarget != null) {
         return new DirectCallMetadata(
             singleTarget, callSite.isNullableReceiver);
@@ -123,6 +130,7 @@
 /// Annotates kernel AST with metadata using results of type flow analysis.
 class AnnotateKernel extends RecursiveVisitor<Null> {
   final TypeFlowAnalysis _typeFlowAnalysis;
+  final FieldMorpher fieldMorpher;
   final DirectCallMetadataRepository _directCallMetadataRepository;
   final InferredTypeMetadataRepository _inferredTypeMetadata;
   final UnreachableNodeMetadataRepository _unreachableNodeMetadata;
@@ -134,8 +142,8 @@
   final Class _intClass;
   Constant _nullConstant;
 
-  AnnotateKernel(
-      Component component, this._typeFlowAnalysis, this._unboxingInfo)
+  AnnotateKernel(Component component, this._typeFlowAnalysis, this.fieldMorpher,
+      this._unboxingInfo)
       : _directCallMetadataRepository =
             component.metadata[DirectCallMetadataRepository.repositoryTag],
         _inferredTypeMetadata = new InferredTypeMetadataRepository(),
@@ -190,7 +198,8 @@
     if (type is ConcreteType && type.typeArgs != null) {
       typeArgs = type.typeArgs
           .take(type.numImmediateTypeArgs)
-          .map((t) => t is AnyType ? null : (t as RuntimeType).representedType)
+          .map((t) =>
+              t is UnknownType ? null : (t as RuntimeType).representedType)
           .toList();
     }
 
@@ -256,7 +265,7 @@
 
     // If the call is not marked as 'isResultUsed', the 'resultType' will
     // not be observed (i.e., it will always be EmptyType). This is the
-    // case even if the result acutally might be used but is not used by
+    // case even if the result actually might be used but is not used by
     // the summary, e.g. if the result is an argument to a closure call.
     // Therefore, we need to pass in 'NullableType(AnyType)' as the
     // inferred result type here (since we don't know what it actually
@@ -327,7 +336,8 @@
 
         // TODO(alexmarkov): figure out how to pass receiver type.
       }
-    } else if (!member.isAbstract) {
+    } else if (!member.isAbstract &&
+        !fieldMorpher.isExtraMemberWithReachableBody(member)) {
       _setUnreachable(member);
     } else if (member is! Field) {
       final unboxingInfoMetadata =
@@ -356,14 +366,15 @@
     // interface target, and table dispatch calls need selector IDs for all
     // interface targets.
     if (member.isInstanceMember) {
+      final original = fieldMorpher.getOriginalMember(member);
       final attrs = new ProcedureAttributesMetadata(
           methodOrSetterCalledDynamically:
-              _typeFlowAnalysis.isCalledDynamically(member),
+              _typeFlowAnalysis.isCalledDynamically(original),
           getterCalledDynamically:
-              _typeFlowAnalysis.isGetterCalledDynamically(member),
-          hasThisUses: _typeFlowAnalysis.isCalledViaThis(member),
-          hasNonThisUses: _typeFlowAnalysis.isCalledNotViaThis(member),
-          hasTearOffUses: _typeFlowAnalysis.isTearOffTaken(member),
+              _typeFlowAnalysis.isGetterCalledDynamically(original),
+          hasThisUses: _typeFlowAnalysis.isCalledViaThis(original),
+          hasNonThisUses: _typeFlowAnalysis.isCalledNotViaThis(original),
+          hasTearOffUses: _typeFlowAnalysis.isTearOffTaken(original),
           methodOrSetterSelectorId:
               _tableSelectorAssigner.methodOrSetterSelectorId(member),
           getterSelectorId: _tableSelectorAssigner.getterSelectorId(member));
@@ -557,11 +568,13 @@
 ///
 class TreeShaker {
   final TypeFlowAnalysis typeFlowAnalysis;
+  final bool treeShakeWriteOnlyFields;
   final Set<Class> _usedClasses = new Set<Class>();
   final Set<Class> _classesUsedInType = new Set<Class>();
   final Set<Member> _usedMembers = new Set<Member>();
   final Set<Extension> _usedExtensions = new Set<Extension>();
   final Set<Typedef> _usedTypedefs = new Set<Typedef>();
+  FieldMorpher fieldMorpher;
   _TreeShakerTypeVisitor typeVisitor;
   _TreeShakerConstantVisitor constantVisitor;
   _TreeShakerPass1 _pass1;
@@ -569,7 +582,8 @@
   _SignatureShaker _signatureShaker;
 
   TreeShaker(Component component, this.typeFlowAnalysis,
-      {bool treeShakeSignatures: true}) {
+      {bool treeShakeSignatures: true, this.treeShakeWriteOnlyFields: true}) {
+    fieldMorpher = new FieldMorpher(this);
     typeVisitor = new _TreeShakerTypeVisitor(this);
     constantVisitor = new _TreeShakerConstantVisitor(this, typeVisitor);
     _pass1 = new _TreeShakerPass1(this);
@@ -594,13 +608,28 @@
   bool isClassAllocated(Class c) => typeFlowAnalysis.isClassAllocated(c);
   bool isMemberUsed(Member m) => _usedMembers.contains(m);
   bool isExtensionUsed(Extension e) => _usedExtensions.contains(e);
-  bool isMemberBodyReachable(Member m) => typeFlowAnalysis.isMemberUsed(m);
+  bool isMemberBodyReachable(Member m) =>
+      typeFlowAnalysis.isMemberUsed(m) ||
+      fieldMorpher.isExtraMemberWithReachableBody(m);
   bool isFieldInitializerReachable(Field f) =>
       typeFlowAnalysis.isFieldInitializerUsed(f);
+  bool isFieldGetterReachable(Field f) => typeFlowAnalysis.isFieldGetterUsed(f);
+  bool isFieldSetterReachable(Field f) => typeFlowAnalysis.isFieldSetterUsed(f);
   bool isMemberReferencedFromNativeCode(Member m) =>
       typeFlowAnalysis.nativeCodeOracle.isMemberReferencedFromNativeCode(m);
   bool isTypedefUsed(Typedef t) => _usedTypedefs.contains(t);
 
+  bool retainField(Field f) =>
+      isMemberBodyReachable(f) &&
+          (!treeShakeWriteOnlyFields ||
+              isFieldGetterReachable(f) ||
+              (!f.isStatic &&
+                  f.initializer != null &&
+                  isFieldInitializerReachable(f) &&
+                  mayHaveSideEffects(f.initializer)) ||
+              (f.isLate && f.isFinal)) ||
+      isMemberReferencedFromNativeCode(f);
+
   void addClassUsedInType(Class c) {
     if (_classesUsedInType.add(c)) {
       if (kPrintDebug) {
@@ -636,9 +665,15 @@
       } else if (m is Procedure) {
         func = m.function;
         if (m.forwardingStubSuperTarget != null) {
+          m.forwardingStubSuperTarget = fieldMorpher.adjustInstanceCallTarget(
+              m.forwardingStubSuperTarget,
+              isSetter: m.isSetter);
           addUsedMember(m.forwardingStubSuperTarget);
         }
         if (m.forwardingStubInterfaceTarget != null) {
+          m.forwardingStubInterfaceTarget = fieldMorpher
+              .adjustInstanceCallTarget(m.forwardingStubInterfaceTarget,
+                  isSetter: m.isSetter);
           addUsedMember(m.forwardingStubInterfaceTarget);
         }
       } else if (m is Constructor) {
@@ -691,6 +726,86 @@
   }
 }
 
+class FieldMorpher {
+  final TreeShaker shaker;
+  final Set<Member> _extraMembersWithReachableBody = <Member>{};
+  final Map<Field, Member> _gettersForRemovedFields = <Field, Member>{};
+  final Map<Field, Member> _settersForRemovedFields = <Field, Member>{};
+  final Map<Member, Field> _removedFields = <Member, Field>{};
+
+  FieldMorpher(this.shaker);
+
+  Member _createAccessorForRemovedField(Field field, bool isSetter) {
+    assertx(!field.isStatic);
+    assertx(!shaker.retainField(field));
+    Procedure accessor;
+    if (isSetter) {
+      final isAbstract = !shaker.isFieldSetterReachable(field);
+      final parameter = new VariableDeclaration('value', type: field.type)
+        ..isCovariant = field.isCovariant
+        ..isGenericCovariantImpl = field.isGenericCovariantImpl
+        ..fileOffset = field.fileOffset;
+      accessor = new Procedure(
+          field.name,
+          ProcedureKind.Setter,
+          new FunctionNode(null,
+              positionalParameters: [parameter], returnType: const VoidType())
+            ..fileOffset = field.fileOffset,
+          isAbstract: isAbstract,
+          fileUri: field.fileUri);
+      if (!isAbstract) {
+        _extraMembersWithReachableBody.add(accessor);
+      }
+    } else {
+      accessor = new Procedure(field.name, ProcedureKind.Getter,
+          new FunctionNode(null, returnType: field.type),
+          isAbstract: true, fileUri: field.fileUri);
+    }
+    accessor.fileOffset = field.fileOffset;
+    field.enclosingClass.addMember(accessor);
+    _removedFields[accessor] = field;
+    shaker.addUsedMember(accessor);
+    return accessor;
+  }
+
+  /// Return a replacement for an instance call target.
+  /// If necessary, creates a getter or setter as a replacement if target is a
+  /// field which is going to be removed by the tree shaker.
+  /// This method is used during tree shaker pass 1.
+  Member adjustInstanceCallTarget(Member target, {bool isSetter = false}) {
+    if (target is Field && !shaker.retainField(target)) {
+      final targets =
+          isSetter ? _settersForRemovedFields : _gettersForRemovedFields;
+      return targets[target] ??=
+          _createAccessorForRemovedField(target, isSetter);
+    }
+    return target;
+  }
+
+  bool isExtraMemberWithReachableBody(Member member) =>
+      _extraMembersWithReachableBody.contains(member);
+
+  /// Return a member which replaced [target] in instance calls.
+  /// This method can be used after tree shaking to discover replacement.
+  Member getMorphedMember(Member target, {bool isSetter = false}) {
+    if (target == null) {
+      return null;
+    }
+    final targets =
+        isSetter ? _settersForRemovedFields : _gettersForRemovedFields;
+    return targets[target] ?? target;
+  }
+
+  /// Return original member which was replaced by [target] in instance calls.
+  /// This method can be used after tree shaking.
+  Member getOriginalMember(Member target) {
+    if (target == null) {
+      return null;
+    }
+    return _removedFields[target] ?? target;
+  }
+}
+
 /// Visits Dart types and collects all classes and typedefs used in types.
 /// This visitor is used during pass 1 of tree shaking. It is a separate
 /// visitor because [Transformer] does not provide a way to traverse types.
@@ -741,6 +856,7 @@
 /// transforms unreachable calls into 'throw' expressions.
 class _TreeShakerPass1 extends Transformer {
   final TreeShaker shaker;
+  final FieldMorpher fieldMorpher;
   final TypeEnvironment environment;
   final List<Initializer> additionalInitializers = [];
   Procedure _unsafeCast;
@@ -758,7 +874,8 @@
   }
 
   _TreeShakerPass1(this.shaker)
-      : environment = shaker.typeFlowAnalysis.environment;
+      : fieldMorpher = shaker.fieldMorpher,
+        environment = shaker.typeFlowAnalysis.environment;
 
   void transform(Component component) {
     component.transformChildren(this);
@@ -787,8 +904,18 @@
     return expr is Throw;
   }
 
+  TreeNode _evaluateArguments(List<Expression> args, Expression result) {
+    Expression node = result;
+    for (var arg in args.reversed) {
+      if (mayHaveSideEffects(arg)) {
+        node = Let(VariableDeclaration(null, initializer: arg), node);
+      }
+    }
+    return node;
+  }
+
   TreeNode _makeUnreachableCall(List<Expression> args) {
-    TreeNode node;
+    Expression node;
     final int last = args.indexWhere(_isThrowExpression);
     if (last >= 0) {
       // One of the arguments is a Throw expression.
@@ -797,14 +924,11 @@
       args = args.sublist(0, last);
       Statistics.throwExpressionsPruned++;
     } else {
-      node = new Throw(new StringLiteral(
+      node = Throw(StringLiteral(
           'Attempt to execute code removed by Dart AOT compiler (TFA)'));
     }
-    for (var arg in args.reversed) {
-      node = new Let(new VariableDeclaration(null, initializer: arg), node);
-    }
     Statistics.callsDropped++;
-    return node;
+    return _evaluateArguments(args, node);
   }
 
   TreeNode _makeUnreachableInitializer(List<Expression> args) {
@@ -812,6 +936,9 @@
         new VariableDeclaration(null, initializer: _makeUnreachableCall(args)));
   }
 
+  NarrowNotNull _getNullTest(TreeNode node) =>
+      shaker.typeFlowAnalysis.nullTest(node);
+
   TreeNode _visitAssertNode(TreeNode node) {
     if (kRemoveAsserts) {
       return null;
@@ -893,7 +1020,7 @@
 
   @override
   TreeNode visitField(Field node) {
-    if (shaker.isMemberBodyReachable(node)) {
+    if (shaker.retainField(node)) {
       if (kPrintTrace) {
         tracePrint("Visiting $node");
       }
@@ -905,12 +1032,10 @@
           node.initializer = _makeUnreachableCall([])..parent = node;
         }
       }
-    } else if (shaker.isMemberReferencedFromNativeCode(node)) {
-      // Preserve members referenced from native code to satisfy lookups, even
-      // if they are not reachable. An instance member could be added via
-      // native code entry point but still unreachable if no instances of
-      // its enclosing class are allocated.
-      shaker.addUsedMember(node);
+    } else if (shaker.isFieldSetterReachable(node) && !node.isStatic) {
+      // Make sure setter is created to replace the field even if field is not
+      // used as an instance call target.
+      fieldMorpher.adjustInstanceCallTarget(node, isSetter: true);
     }
     return node;
   }
@@ -921,12 +1046,21 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall(
           _flattenArguments(node.arguments, receiver: node.receiver));
-    } else {
-      if (node.interfaceTarget != null) {
-        shaker.addUsedMember(node.interfaceTarget);
-      }
-      return node;
     }
+    if (isComparisonWithNull(node)) {
+      final nullTest = _getNullTest(node);
+      if (nullTest.isAlwaysNull || nullTest.isAlwaysNotNull) {
+        return _evaluateArguments(
+            _flattenArguments(node.arguments, receiver: node.receiver),
+            BoolLiteral(nullTest.isAlwaysNull));
+      }
+    }
+    node.interfaceTarget =
+        fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+    if (node.interfaceTarget != null) {
+      shaker.addUsedMember(node.interfaceTarget);
+    }
+    return node;
   }
 
   @override
@@ -935,6 +1069,8 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([node.receiver]);
     } else {
+      node.interfaceTarget =
+          fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
       if (node.interfaceTarget != null) {
         shaker.addUsedMember(node.interfaceTarget);
       }
@@ -948,6 +1084,8 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([node.receiver, node.value]);
     } else {
+      node.interfaceTarget = fieldMorpher
+          .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
       if (node.interfaceTarget != null) {
         shaker.addUsedMember(node.interfaceTarget);
       }
@@ -961,6 +1099,8 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall(_flattenArguments(node.arguments));
     } else {
+      node.interfaceTarget =
+          fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
       if (node.interfaceTarget != null) {
         shaker.addUsedMember(node.interfaceTarget);
       }
@@ -974,6 +1114,8 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([]);
     } else {
+      node.interfaceTarget =
+          fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
       if (node.interfaceTarget != null) {
         shaker.addUsedMember(node.interfaceTarget);
       }
@@ -987,6 +1129,8 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([node.value]);
     } else {
+      node.interfaceTarget = fieldMorpher
+          .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
       if (node.interfaceTarget != null) {
         shaker.addUsedMember(node.interfaceTarget);
       }
@@ -1116,7 +1260,11 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([node.value]);
     } else {
-      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      final target = node.target;
+      assertx(shaker.isMemberBodyReachable(target), details: node);
+      if (target is Field && !shaker.retainField(target)) {
+        return node.value;
+      }
       return node;
     }
   }
@@ -1128,7 +1276,7 @@
       return _makeUnreachableCall(
           _flattenArguments(node.arguments, receiver: node.receiver));
     } else {
-      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      assertx(shaker.isMemberBodyReachable(node.target), details: node);
       return node;
     }
   }
@@ -1139,7 +1287,10 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([node.receiver]);
     } else {
-      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      final target = node.target;
+      assertx(shaker.isMemberBodyReachable(target), details: node);
+      assertx(target is! Field || shaker.isFieldGetterReachable(target),
+          details: node);
       return node;
     }
   }
@@ -1150,7 +1301,9 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall([node.receiver, node.value]);
     } else {
-      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      assertx(shaker.isMemberBodyReachable(node.target), details: node);
+      node.target =
+          fieldMorpher.adjustInstanceCallTarget(node.target, isSetter: true);
       return node;
     }
   }
@@ -1202,12 +1355,20 @@
   }
 
   @override
-  visitFieldInitializer(FieldInitializer node) {
+  TreeNode visitFieldInitializer(FieldInitializer node) {
     node.transformChildren(this);
     if (_isUnreachable(node)) {
       return _makeUnreachableInitializer([node.value]);
     } else {
       assertx(shaker.isMemberBodyReachable(node.field), details: node.field);
+      if (!shaker.retainField(node.field)) {
+        if (mayHaveSideEffects(node.value)) {
+          return LocalInitializer(
+              VariableDeclaration(null, initializer: node.value));
+        } else {
+          return null;
+        }
+      }
       return node;
     }
   }
@@ -1238,6 +1399,19 @@
     return node;
   }
 
+  @override
+  TreeNode visitNullCheck(NullCheck node) {
+    node.transformChildren(this);
+    final nullTest = _getNullTest(node);
+    if (nullTest.isAlwaysNotNull) {
+      return StaticInvocation(
+          unsafeCast,
+          Arguments([node.operand],
+              types: [node.getStaticType(staticTypeContext)]));
+    }
+    return node;
+  }
+
   Procedure get unsafeCast {
     _unsafeCast ??= shaker.typeFlowAnalysis.environment.coreTypes.index
         .getTopLevelMember('dart:_internal', 'unsafeCast');
@@ -1586,3 +1760,26 @@
     constant.type.accept(typeVisitor);
   }
 }
+
+bool mayHaveSideEffects(Expression node) {
+  if (node is BasicLiteral ||
+      node is ConstantExpression ||
+      node is ThisExpression) {
+    return false;
+  }
+  if (node is VariableGet && !node.variable.isLate) {
+    return false;
+  }
+  if (node is StaticGet) {
+    final target = node.target;
+    if (target is Field && !target.isLate) {
+      final initializer = target.initializer;
+      if (initializer == null ||
+          initializer is BasicLiteral ||
+          initializer is ConstantExpression) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 771f18c..dceb628 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -93,7 +93,7 @@
       if (bound is TypeParameterType) {
         result = const AnyType();
       } else {
-        return fromStaticType(bound, canBeNull);
+        result = fromStaticType(bound, canBeNull);
       }
     } else {
       throw 'Unexpected type ${type.runtimeType} $type';
@@ -101,7 +101,7 @@
     if (nullSafety && type.nullability == Nullability.nonNullable) {
       canBeNull = false;
     }
-    if (canBeNull) {
+    if (canBeNull && result is! NullableType) {
       result = new Type.nullable(result);
     }
     return result;
@@ -186,6 +186,7 @@
 /// Order of precedence between types for evaluation of union/intersection.
 enum TypeOrder {
   RuntimeType,
+  Unknown,
   Empty,
   Nullable,
   Any,
@@ -293,7 +294,6 @@
 
 /// Type representing any instance except `null`.
 /// Semantically equivalent to ConeType of Object, but more efficient.
-/// Can also represent a set of types, the set of all types.
 class AnyType extends Type {
   const AnyType();
 
@@ -612,7 +612,7 @@
   int _hashCode;
 
   // May be null if there are no type arguments constraints. The type arguments
-  // should represent type sets, i.e. `AnyType` or `RuntimeType`. The type
+  // should represent type sets, i.e. `UnknownType` or `RuntimeType`. The type
   // arguments vector is factored against the generic interfaces implemented by
   // the class (see [TypeHierarchy.flattenedTypeArgumentsFor]).
   //
@@ -693,11 +693,13 @@
           runtimeType.numImmediateTypeArgs);
 
       for (int i = 0; i < runtimeType.numImmediateTypeArgs; ++i) {
-        if (usableTypeArgs[i + interfaceOffset] == const AnyType())
+        final ta = usableTypeArgs[i + interfaceOffset];
+        if (ta is UnknownType) {
           return false;
-        assertx(usableTypeArgs[i + interfaceOffset] is RuntimeType);
-        if (!usableTypeArgs[i + interfaceOffset]
-            .isSubtypeOfRuntimeType(typeHierarchy, runtimeType.typeArgs[i])) {
+        }
+        assertx(ta is RuntimeType);
+        if (!ta.isSubtypeOfRuntimeType(
+            typeHierarchy, runtimeType.typeArgs[i])) {
           return false;
         }
       }
@@ -864,7 +866,7 @@
 //   class A<T> extends Comparable<A<T>> {}
 //
 // To avoid these cycles, we approximate generic super-bounded types (the second
-// case), so the representation for 'A<String>' would be simply 'AnyType'.
+// case), so the representation for 'A<String>' would be simply 'UnknownType'.
 // However, approximating non-generic types like 'int' and 'num' (the first
 // case) would be too coarse, so we leave an null 'typeArgs' field for these
 // types. As a result, when doing an 'isSubtypeOfRuntimeType' against
@@ -963,11 +965,11 @@
   Type union(Type other, TypeHierarchy typeHierarchy) =>
       throw "ERROR: RuntimeType does not support union.";
 
-  // This only works between "type-set" representations ('AnyType' and
+  // This only works between "type-set" representations ('UnknownType' and
   // 'RuntimeType') and is used when merging type arguments.
   @override
   Type intersection(Type other, TypeHierarchy typeHierarchy) {
-    if (other is AnyType) {
+    if (other is UnknownType) {
       return this;
     } else if (other is RuntimeType) {
       return this == other ? this : const EmptyType();
@@ -1043,3 +1045,52 @@
     return true;
   }
 }
+
+/// Type which is not known at compile time.
+/// It is used as the right-hand-side of type tests.
+class UnknownType extends Type {
+  const UnknownType();
+
+  @override
+  int get hashCode => 1019;
+
+  @override
+  bool operator ==(other) => (other is UnknownType);
+
+  @override
+  String toString() => "UNKNOWN";
+
+  @override
+  int get order => TypeOrder.Unknown.index;
+
+  @override
+  bool isSubtypeOf(TypeHierarchy typeHierarchy, Class cls) =>
+      throw "ERROR: UnknownType does not support isSubtypeOf.";
+
+  @override
+  Type union(Type other, TypeHierarchy typeHierarchy) {
+    if (other is UnknownType || other is RuntimeType) {
+      return this;
+    }
+    throw "ERROR: UnknownType does not support union with ${other.runtimeType}";
+  }
+
+  // This only works between "type-set" representations ('UnknownType' and
+  // 'RuntimeType') and is used when merging type arguments.
+  @override
+  Type intersection(Type other, TypeHierarchy typeHierarchy) {
+    if (other is UnknownType || other is RuntimeType) {
+      return other;
+    }
+    throw "ERROR: UnknownType does not support intersection with ${other.runtimeType}";
+  }
+
+  bool isSubtypeOfRuntimeType(TypeHierarchy typeHierarchy, RuntimeType other) {
+    final rhs = other._type;
+    return (rhs is DynamicType) ||
+        (rhs is VoidType) ||
+        (rhs is InterfaceType &&
+            rhs.classNode == typeHierarchy.coreTypes.objectClass &&
+            rhs.nullability != Nullability.nonNullable);
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index 1bd903f..07f6454 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -6,16 +6,7 @@
 /// analysis.
 library vm.transformations.type_flow.utils;
 
-import 'package:kernel/ast.dart'
-    show
-        Class,
-        Constructor,
-        DartType,
-        FunctionNode,
-        Member,
-        Nullability,
-        Procedure,
-        VariableDeclaration;
+import 'package:kernel/ast.dart';
 
 const bool kPrintTrace =
     const bool.fromEnvironment('global.type.flow.print.trace');
@@ -268,3 +259,23 @@
 extension NullabilitySuffix on Nullability {
   String get suffix => nullabilitySuffix[this];
 }
+
+bool isNullLiteral(Expression expr) =>
+    expr is NullLiteral ||
+    (expr is ConstantExpression && expr.constant is NullConstant);
+
+Expression getArgumentOfComparisonWithNull(MethodInvocation node) {
+  if (node.name.name == '==') {
+    final lhs = node.receiver;
+    final rhs = node.arguments.positional.single;
+    if (isNullLiteral(lhs)) {
+      return rhs;
+    } else if (isNullLiteral(rhs)) {
+      return lhs;
+    }
+  }
+  return null;
+}
+
+bool isComparisonWithNull(MethodInvocation node) =>
+    getArgumentOfComparisonWithNull(node) != null;
diff --git a/pkg/vm/pubspec.yaml b/pkg/vm/pubspec.yaml
index ef74ee0..27d6379 100644
--- a/pkg/vm/pubspec.yaml
+++ b/pkg/vm/pubspec.yaml
@@ -3,6 +3,9 @@
 # version: do-not-upload
 description: VM specific Dart code and helper scripts
 
+environment:
+  sdk: "^2.7.0"
+
 dependencies:
   build_integration:
     path: ../build_integration
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index 4a7fb0c..6233aa5 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -145,11 +145,11 @@
 
 In order to re-generate expectations run tests with -D$kUpdateExpectations=true VM option:
 
-  tools/test.py -m release --vm-options -D$kUpdateExpectations=true pkg/vm
+  tools/test.py -m release --vm-options -D$kUpdateExpectations=true pkg/vm/
 
 In order to dump actual results into .actual files run tests with -D$kDumpActualResult=true VM option:
 
-  tools/test.py -m release --vm-options -D$kDumpActualResult=true pkg/vm
+  tools/test.py -m release --vm-options -D$kDumpActualResult=true pkg/vm/
 
 """);
     }
diff --git a/pkg/vm/test/kernel_front_end_test.dart b/pkg/vm/test/kernel_front_end_test.dart
index ec3e8b0..6aef35e 100644
--- a/pkg/vm/test/kernel_front_end_test.dart
+++ b/pkg/vm/test/kernel_front_end_test.dart
@@ -48,7 +48,7 @@
       outputDill(),
       '$sdkDir/$mainScript',
     ]);
-  });
+  }, timeout: Timeout.none);
 
   test('compile-multi-root', () async {
     await testCompile([
@@ -64,7 +64,7 @@
       outputDill(),
       'test-filesystem-scheme:///$mainScript',
     ]);
-  });
+  }, timeout: Timeout.none);
 
   test('compile-multi-root-with-package-uri-main', () async {
     await testCompile([
@@ -80,7 +80,7 @@
       outputDill(),
       '$mainScriptPackageUri',
     ]);
-  });
+  }, timeout: Timeout.none);
 
   test('compile-package-split', () async {
     await testCompile([
@@ -93,7 +93,7 @@
       '--split-output-by-packages',
       '$sdkDir/$mainScript',
     ]);
-  });
+  }, timeout: Timeout.none);
 
   test('compile-bytecode', () async {
     await testCompile([
@@ -107,7 +107,7 @@
       '--drop-ast',
       '$sdkDir/$mainScript',
     ]);
-  });
+  }, timeout: Timeout.none);
 
   test('compile-bytecode-package-split', () async {
     await testCompile([
@@ -122,5 +122,5 @@
       '--split-output-by-packages',
       '$sdkDir/$mainScript',
     ]);
-  });
+  }, timeout: Timeout.none);
 }
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index d015481..73d3434 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -61,7 +61,7 @@
   [27] = Reserved
   [28] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [29] = Reserved
-  [30] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [30] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [31] = Reserved
   [32] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [33] = Reserved
@@ -135,7 +135,7 @@
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          CP#30, 2
+  InterfaceCall        CP#30, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -284,7 +284,7 @@
   Push                 r0
   LoadContextVar       0, 1
   Push                 r6
-  DynamicCall          CP#24, 2
+  InterfaceCall        CP#24, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -316,7 +316,7 @@
   [21] = Reserved
   [22] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [23] = Reserved
-  [24] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [24] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [25] = Reserved
   [26] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [27] = Reserved
@@ -440,7 +440,7 @@
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          CP#26, 2
+  InterfaceCall        CP#26, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -474,7 +474,7 @@
   [23] = Reserved
   [24] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [25] = Reserved
-  [26] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [26] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [27] = Reserved
   [28] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [29] = Reserved
@@ -662,7 +662,7 @@
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          CP#34, 2
+  InterfaceCall        CP#34, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -704,7 +704,7 @@
   [31] = Reserved
   [32] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [33] = Reserved
-  [34] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [34] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [35] = Reserved
   [36] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [37] = Reserved
@@ -1014,7 +1014,7 @@
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 17
-  DynamicCall          CP#32, 2
+  InterfaceCall        CP#32, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -1054,7 +1054,7 @@
   [29] = Reserved
   [30] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [31] = Reserved
-  [32] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [32] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [33] = Reserved
   [34] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [35] = Reserved
@@ -1543,7 +1543,7 @@
   [27] = Reserved
   [28] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [29] = Reserved
-  [30] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [30] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [31] = Reserved
   [32] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [33] = Reserved
@@ -1609,7 +1609,7 @@
   LoadContextVar       1, 1
   Push                 r0
   LoadContextVar       1, 8
-  DynamicCall          CP#30, 2
+  InterfaceCall        CP#30, 2
   Drop1
   Push                 r0
   LoadContextVar       1, 1
@@ -1833,7 +1833,7 @@
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          CP#28, 2
+  InterfaceCall        CP#28, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -1869,7 +1869,7 @@
   [25] = Reserved
   [26] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [27] = Reserved
-  [28] = DynamicCall 'start', ArgDesc num-args 2, num-type-args 0, names []
+  [28] = InterfaceCall 'dart:async::_AsyncAwaitCompleter::start', ArgDesc num-args 2, num-type-args 0, names []
   [29] = Reserved
   [30] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
   [31] = Reserved
@@ -2000,8 +2000,8 @@
     final dart.async::_AsyncAwaitCompleter<dart.core::Null?>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::Null?>();
     dart.async::FutureOr<dart.core::Null?>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -2015,21 +2015,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   };
   static method foo() → dart.async::Future<dart.core::int*>* /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dart.core::int*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::int*>();
     dart.async::FutureOr<dart.core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
@@ -2042,21 +2042,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method simpleAsyncAwait(dart.async::Future<dart.core::int*>* a, dart.async::Future<dart.core::int*>* b) → dart.async::Future<dart.core::int*>* /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dart.core::int*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::int*>();
     dart.async::FutureOr<dart.core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -2074,21 +2074,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method loops(dart.core::List<dart.core::int*>* list) → dart.async::Future<dart.core::int*>* /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dart.core::int*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::int*>();
     dart.async::FutureOr<dart.core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -2101,7 +2101,7 @@
           dart.core::int* sum = 0;
           for (dart.core::int* i = 0; i.{dart.core::num::<}(10); i = i.{dart.core::num::+}(1)) {
             {
-              dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(list).{dart.core::Iterable::iterator};
+              dart.core::Iterator<dart.core::int*>* :sync-for-iterator = list.{dart.core::Iterable::iterator};
               for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
                 dart.core::int* j = :sync-for-iterator.{dart.core::Iterator::current};
                 {
@@ -2122,21 +2122,21 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method tryCatchRethrow(dart.async::Future<dart.core::int*>* a, dart.async::Future<dart.core::int*>* b, dart.async::Future<dart.core::int*>* c) → dart.async::Future<dart.core::int*>* /* originally async */ {
     final dart.async::_AsyncAwaitCompleter<dart.core::int*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::int*>();
     dart.async::FutureOr<dart.core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -2180,13 +2180,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method closure(dart.async::Future<dart.core::int*>* a) → dynamic {
@@ -2195,8 +2195,8 @@
       final dart.async::_AsyncAwaitCompleter<dart.core::int*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::int*>();
       dart.async::FutureOr<dart.core::int*>* :return_value;
       dynamic :async_stack_trace;
-      dynamic :async_op_then;
-      dynamic :async_op_error;
+      (dynamic) →* dynamic :async_op_then;
+      (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
       dart.core::int* :await_jump_var = 0;
       dynamic :await_ctx_var;
       dynamic :saved_try_context_var0;
@@ -2220,13 +2220,13 @@
           dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
           return;
         }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
           :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
         }
       :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
       :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
       :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-      :async_completer.start(:async_op);
+      :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
       return :async_completer.{dart.async::Completer::future};
     }
     return nested;
@@ -2235,8 +2235,8 @@
     final dart.async::_AsyncAwaitCompleter<dart.core::int*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::int*>();
     dart.async::FutureOr<dart.core::int*>* :return_value;
     dynamic :async_stack_trace;
-    dynamic :async_op_then;
-    dynamic :async_op_error;
+    (dynamic) →* dynamic :async_op_then;
+    (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
     dynamic :saved_try_context_var0;
@@ -2254,13 +2254,13 @@
         dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
         return;
       }
-      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      on dynamic catch(dynamic :exception, dart.core::StackTrace* :stack_trace) {
         :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.start(:async_op);
+    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
     return :async_completer.{dart.async::Completer::future};
   }
   static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index de90a1d..675d337d 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -1835,7 +1835,7 @@
     }
     method testForInLoop(dart.core::List<dart.core::int*>* list) → void {
       {
-        dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(list).{dart.core::Iterable::iterator};
+        dart.core::Iterator<dart.core::int*>* :sync-for-iterator = list.{dart.core::Iterable::iterator};
         for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
           dart.core::int* i = :sync-for-iterator.{dart.core::Iterator::current};
           {
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index cb40ac2..524ae14 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -385,7 +385,7 @@
   static method test_for_in(dart.core::List<dart.core::int*>* list) → dart.core::int* {
     dart.core::int* sum = 0;
     {
-      dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(list).{dart.core::Iterable::iterator};
+      dart.core::Iterator<dart.core::int*>* :sync-for-iterator = list.{dart.core::Iterable::iterator};
       for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
         dart.core::int* e = :sync-for-iterator.{dart.core::Iterator::current};
         {
@@ -399,7 +399,7 @@
     dart.core::int* sum = 0;
     dart.core::int* e = 42;
     {
-      dart.core::Iterator<dart.core::int*>* :sync-for-iterator = dart._internal::unsafeCast<dart.core::Iterable<dart.core::int*>*>(list).{dart.core::Iterable::iterator};
+      dart.core::Iterator<dart.core::int*>* :sync-for-iterator = list.{dart.core::Iterable::iterator};
       for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
         final dart.core::int* #t3 = :sync-for-iterator.{dart.core::Iterator::current};
         {
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 8c81f4d..b78c771 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -625,8 +625,13 @@
 Bytecode {
   Entry                2
   CheckFunctionTypeArgs 1, r0
+  JumpIfNotZeroTypeArgs L1
+  Push                 FP[-8]
+  LoadTypeArgumentsField CP#0
+  PopLocal             r0
+L1:
   CheckStack           0
-  JumpIfUnchecked      L1
+  JumpIfUnchecked      L2
   Push                 FP[-8]
   LoadTypeArgumentsField CP#0
   Push                 r0
@@ -642,7 +647,7 @@
   PushConstant         CP#4
   AssertAssignable     0, CP#5
   Drop1
-L1:
+L2:
   Push                 FP[-6]
   PushConstant         CP#6
   PushNull
@@ -660,6 +665,7 @@
 }
 Parameter flags: [0, 1, 2]
 Forwarding stub target: CP#11
+Default function type arguments: CP#12
 ConstantPool {
   [0] = TypeArgumentsField #lib::H
   [1] = Type #lib::H::foo7::TypeParam/0
@@ -673,6 +679,7 @@
   [9] = DirectCall '#lib::G::foo7', ArgDesc num-args 4, num-type-args 1, names []
   [10] = Reserved
   [11] = ObjectRef #lib::G::foo7
+  [12] = ObjectRef < #lib::H::TypeParam/0 >
 }
 
 
@@ -745,7 +752,7 @@
       : super #lib::G::•()
       ;
     method foo8<generic-covariant-impl Q extends #lib::H::T* = #lib::H::T*>(#lib::H::foo8::Q* a, covariant dart.core::int* b, generic-covariant-impl #lib::H::T* c) → void {}
-    forwarding-stub method foo7<generic-covariant-impl Q extends #lib::H::T*>(#lib::H::foo7::Q* a, covariant dart.core::num* b, generic-covariant-impl #lib::H::T* c) → void
+    forwarding-stub method foo7<generic-covariant-impl Q extends #lib::H::T* = #lib::H::T*>(#lib::H::foo7::Q* a, covariant dart.core::num* b, generic-covariant-impl #lib::H::T* c) → void
       return super.{#lib::G::foo7}<#lib::H::foo7::Q*>(a, b, c);
   }
   static field dart.core::List<dart.core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
index b13924f..9bea26d 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
@@ -116,11 +116,11 @@
 %z = _Parameter #2 [_T ANY?]
 t3* = _Call [num::==] (%x, _T (dart.core::_Smi, 5))
 t4* = _Call [String::==] (%y, _T (dart.core::_OneByteString, hi))
-t5* = _Call [Object::==] (%z, _T {}?)
-t6 = _Call direct [foo] (_T (dart.core::_Smi, 5))
-t7 = _Call direct [foo] (_T (dart.core::_OneByteString, hi))
-t8 = _Narrow (%z to _T ANY)
-t9 = _Call direct [foo] (t8)
+t5 = _Call direct [Object::==] (%z, _T {}?)
+t6 = _Narrow (%z to _T ANY)
+t7 = _Call direct [foo] (_T (dart.core::_Smi, 5))
+t8 = _Call direct [foo] (_T (dart.core::_OneByteString, hi))
+t9 = _Call direct [foo] (t6)
 RESULT: _T {}?
 ------------ if8 ------------
 %x = _Parameter #0 [_T ANY?]
@@ -191,14 +191,13 @@
 t0 = _Call direct [C1::] (_T (#lib::C1))
 t1 = _Call direct [C2::] (_T (#lib::C2))
 t2 = _Call direct [foo] (_T (#lib::C2))
-t3* = _Call direct [unsafeCast] (_T (dart.core::_GrowableList<DynamicType(dynamic)?>))
-t4* = _Call get [Iterable::iterator] (t3)
-t5* = _Call [Iterator::moveNext] (t4)
-t6 = _Narrow (t4 to _T ANY)
-t7 = _Call get [Iterator::current] (t6)
+t3* = _Call get [Iterable::iterator] (_T (dart.core::_GrowableList<DynamicType(dynamic)?>))
+t4* = _Call [Iterator::moveNext] (t3)
+t5 = _Narrow (t3 to _T ANY)
+t6 = _Call get [Iterator::current] (t5)
 x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C2), _T (#lib::C3))
-t9 = _Call direct [foo] (x_0)
-t10 = _Call direct [C3::] (_T (#lib::C3))
+t8 = _Call direct [foo] (x_0)
+t9 = _Call direct [C3::] (_T (#lib::C3))
 RESULT: x_0
 ------------ loop5 ------------
 t0 = _Call direct [C1::] (_T (#lib::C1))
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart
new file mode 100644
index 0000000..9af419c
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  Future<dynamic> bar(x) async => print(x);
+}
+
+class B {}
+
+dynamic foo() => new A();
+Future<dynamic> baz() async => new B();
+
+main() async {
+  await foo().bar(await baz());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
new file mode 100644
index 0000000..17ce2e4
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
@@ -0,0 +1,103 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "dart:_internal" as _in;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method bar(dynamic x) → asy::Future<dynamic>* /* originally async */ {
+    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    asy::FutureOr<dynamic>* :return_value;
+    dynamic :async_stack_trace;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+    core::int* :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print(x);
+          break #L1;
+        }
+        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
+        [@vm.direct-call.metadata=_AsyncAwaitCompleter::completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    [@vm.direct-call.metadata=_AsyncAwaitCompleter::start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+    return [@vm.direct-call.metadata=_AsyncAwaitCompleter::future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+  }
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B*
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic
+  return new self::A::•();
+static method baz() → asy::Future<dynamic>* /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>* :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+  core::int* :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = new self::B::•();
+        break #L2;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
+      [@vm.direct-call.metadata=_AsyncAwaitCompleter::completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  [@vm.direct-call.metadata=_AsyncAwaitCompleter::start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return [@vm.direct-call.metadata=_AsyncAwaitCompleter::future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>* :return_value;
+  dynamic :async_stack_trace;
+  (dynamic) →* dynamic :async_op_then;
+  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+  core::int* :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :async_temporary_0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        :async_temporary_0 = [@vm.inferred-type.metadata=#lib::A] self::foo();
+        [yield] let dynamic #t1 = asy::_awaitHelper([@vm.inferred-type.metadata=dart.async::_Future] self::baz(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t2 = asy::_awaitHelper([@vm.direct-call.metadata=A::bar??] [@vm.inferred-type.metadata=dart.async::_Future (receiver not int)] _in::unsafeCast<dynamic>(:async_temporary_0).bar(:result), :async_op_then, :async_op_error, :async_op) in null;
+        :result;
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, core::StackTrace* :stack_trace) {
+      [@vm.direct-call.metadata=_AsyncAwaitCompleter::completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  [@vm.direct-call.metadata=_AsyncAwaitCompleter::start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+  return [@vm.direct-call.metadata=_AsyncAwaitCompleter::future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
index 9ae4ab1..e6599fe 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -15,7 +15,7 @@
 [@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1] [@vm.unboxing-info.metadata=(b)->d]  operator []([@vm.inferred-type.metadata=!] core::int* i) → core::double*
     return [@vm.direct-call.metadata=_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}([@vm.direct-call.metadata=_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset}));
 [@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2]  operator []=([@vm.inferred-type.metadata=dart.core::_OneByteString] core::int* i, core::double* value) → void {
-    let dynamic #t1 = [@vm.direct-call.metadata=_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = i in let dynamic #t3 = [@vm.direct-call.metadata=_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset} in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+    let dynamic #t1 = [@vm.direct-call.metadata=_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = [@vm.direct-call.metadata=_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset} in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3] [@vm.unboxing-info.metadata=(b)->d]  operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector* a) → core::double* {
     core::double* result = 0.0;
@@ -27,7 +27,7 @@
 [@vm.inferred-type.metadata=#lib::_Vector?]static field self::_Vector* v = new self::_Vector::•(10);
 [@vm.inferred-type.metadata=dart.core::_Double?]static field core::double* x = 0.0;
 static method main(core::List<core::String*>* args) → dynamic {
-  core::Stopwatch* timer = let final core::Stopwatch* #t4 = new core::Stopwatch::•() in let final void #t5 = [@vm.direct-call.metadata=Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t4.{core::Stopwatch::start}() in #t4;
+  core::Stopwatch* timer = let final core::Stopwatch* #t3 = new core::Stopwatch::•() in let final void #t4 = [@vm.direct-call.metadata=Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t3.{core::Stopwatch::start}() in #t3;
   for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
     self::x = [@vm.direct-call.metadata=_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=dart.core::_Double?] self::x.{core::double::+}([@vm.direct-call.metadata=_Vector::*??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=#lib::_Vector?] self::v.{self::_Vector::*}([@vm.inferred-type.metadata=#lib::_Vector?] self::v));
   }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
new file mode 100644
index 0000000..1d5fb04
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests elimination of null checks.
+// This test requires non-nullable experiment.
+
+// @dart = 2.9
+
+class A {
+  String? nonNullable;
+  String? nullable;
+  String? alwaysNull;
+  A({this.nonNullable, this.nullable, this.alwaysNull});
+}
+
+testNonNullable(A a) => a.nonNullable!;
+testNullable(A a) => a.nullable!;
+testAlwaysNull(A a) => a.alwaysNull!;
+
+unused() => A(nonNullable: null, alwaysNull: 'abc');
+
+A staticField = A(nonNullable: 'hi', nullable: 'bye');
+
+void main() {
+  final list = [
+    A(nonNullable: 'foo', nullable: null, alwaysNull: null),
+    staticField,
+  ];
+  for (A a in list) {
+    testNonNullable(a);
+    testNullable(a);
+    testAlwaysNull(a);
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
new file mode 100644
index 0000000..c69020d9
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
@@ -0,0 +1,34 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class A extends core::Object {
+[@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::String? nonNullable;
+[@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::String? nullable;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::String? alwaysNull;
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String? nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String? nullable, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::String? alwaysNull = #C1}) → self::A
+    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
+    ;
+}
+[@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = let core::String #arg1 = "hi" in let core::String #arg2 = "bye" in new self::A::•(#arg1, #arg2);
+static method testNonNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+  return _in::unsafeCast<core::String>([@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable});
+static method testNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+  return [@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}!;
+static method testAlwaysNull([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+  return [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}!;
+static method main() → void {
+  final core::List<self::A> list = <self::A>[let core::String #arg1 = "foo" in let core::Null? #arg2 = null in let core::Null? #arg3 = null in new self::A::•(#arg1, #arg2, alwaysNull: #arg3), self::staticField];
+  {
+    core::Iterator<self::A*> :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A*)>] list.{core::Iterable::iterator};
+    for (; [@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      self::A a = [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
+      {
+        self::testNonNullable(a);
+        self::testNullable(a);
+        self::testAlwaysNull(a);
+      }
+    }
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
new file mode 100644
index 0000000..98488d3
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests elimination of null tests.
+
+class A {
+  String nonNullable;
+  String nullable;
+  String alwaysNull;
+  A({this.nonNullable, this.nullable, this.alwaysNull});
+}
+
+testNonNullableIf1(A a) {
+  if (a.nonNullable == null) {
+    print('null');
+  }
+}
+
+testNullableIf1(A a) {
+  if (a.nullable == null) {
+    print('null');
+  }
+}
+
+testAlwaysNullIf1(A a) {
+  if (a.alwaysNull == null) {
+    print('null');
+  }
+}
+
+testNonNullableIf2(A a) {
+  if (a.nonNullable != null && someCondition()) {
+    print('not null');
+  }
+}
+
+testNullableIf2(A a) {
+  if (a.nullable != null && someCondition()) {
+    print('not null');
+  }
+}
+
+testAlwaysNullIf2(A a) {
+  if (a.alwaysNull != null && someCondition()) {
+    print('not null');
+  }
+}
+
+testNonNullableCondExpr(A a) => a.nonNullable != null ? 'not null' : 'null';
+testNullableCondExpr(A a) => a.nullable != null ? 'not null' : 'null';
+testAlwaysNullCondExpr(A a) => a.alwaysNull != null ? 'not null' : 'null';
+
+someCondition() => int.parse("1") == 1;
+unused() => A(nonNullable: null, alwaysNull: 'abc');
+
+A staticField = A(nonNullable: 'hi', nullable: 'bye');
+
+void main() {
+  final list = [
+    A(nonNullable: 'foo', nullable: null, alwaysNull: null),
+    staticField,
+  ];
+  for (A a in list) {
+    testNonNullableIf1(a);
+    testNullableIf1(a);
+    testAlwaysNullIf1(a);
+    testNonNullableIf2(a);
+    testNullableIf2(a);
+    testAlwaysNullIf2(a);
+    testNonNullableCondExpr(a);
+    testNullableCondExpr(a);
+    testAlwaysNullCondExpr(a);
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
new file mode 100644
index 0000000..89327df
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
@@ -0,0 +1,72 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class A extends core::Object {
+[@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::String* nonNullable;
+[@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::String* nullable;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::String* alwaysNull;
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String* nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String* nullable, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::String* alwaysNull = #C1}) → self::A*
+    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
+    ;
+}
+[@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = let core::String* #arg1 = "hi" in let core::String* #arg2 = "bye" in new self::A::•(#arg1, #arg2);
+static method testNonNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(let dynamic #t1 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) {
+    core::print("null");
+  }
+}
+static method testNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if([@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null)) {
+    core::print("null");
+  }
+}
+static method testAlwaysNullIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(let dynamic #t2 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) {
+    core::print("null");
+  }
+}
+static method testNonNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(!(let dynamic #t3 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+    core::print("not null");
+  }
+}
+static method testNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(![@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+    core::print("not null");
+  }
+}
+static method testAlwaysNullIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(!(let dynamic #t4 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+    core::print("not null");
+  }
+}
+static method testNonNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+  return !(let dynamic #t5 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) ?{core::String*} "not null" : "null";
+static method testNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+  return ![@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) ?{core::String*} "not null" : "null";
+static method testAlwaysNullCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+  return !(let dynamic #t6 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) ?{core::String*} "not null" : "null";
+static method someCondition() → dynamic
+  return [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1);
+static method main() → void {
+  final core::List<self::A*>* list = <self::A*>[let core::String* #arg1 = "foo" in let core::Null? #arg2 = null in let core::Null? #arg3 = null in new self::A::•(#arg1, #arg2, alwaysNull: #arg3), self::staticField];
+  {
+    core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A*)>] list.{core::Iterable::iterator};
+    for (; [@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      self::A* a = [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
+      {
+        self::testNonNullableIf1(a);
+        self::testNullableIf1(a);
+        self::testAlwaysNullIf1(a);
+        self::testNonNullableIf2(a);
+        self::testNullableIf2(a);
+        self::testAlwaysNullIf2(a);
+        self::testNonNullableCondExpr(a);
+        self::testNullableCondExpr(a);
+        self::testAlwaysNullCondExpr(a);
+      }
+    }
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart
new file mode 100644
index 0000000..b60f24c5
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/41452.
+// Tests handling of null initializer of covariant field.
+// This test requires non-nullable experiment and NNBD strong mode.
+
+// @dart = 2.9
+
+class _SplayTreeNode<Node extends _SplayTreeNode<Node>> {
+  Node? left;
+  _SplayTreeNode();
+}
+
+class _SplayTreeMapNode<V> extends _SplayTreeNode<_SplayTreeMapNode<V>> {
+  _SplayTreeMapNode();
+}
+
+class _SplayTree<Node extends _SplayTreeNode<Node>> {
+  Node? _root;
+
+  add(Node n) {
+    Node? root = _root;
+    if (root == null) return;
+    print(root.left); // Should be inferred as nullable.
+  }
+}
+
+class SplayTreeMap<V> extends _SplayTree<_SplayTreeMapNode<V>> {
+  _SplayTreeMapNode<V>? _root = _SplayTreeMapNode<V>();
+}
+
+void main() {
+  SplayTreeMap().add(_SplayTreeMapNode());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
new file mode 100644
index 0000000..31685ef
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
@@ -0,0 +1,36 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class _SplayTreeNode<Node extends self::_SplayTreeNode<self::_SplayTreeNode::Node> = self::_SplayTreeNode<dynamic>> extends core::Object {
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  generic-covariant-impl field self::_SplayTreeNode::Node? left = null;
+  constructor •() → self::_SplayTreeNode<self::_SplayTreeNode::Node>
+    : super core::Object::•()
+    ;
+}
+class _SplayTreeMapNode<V extends core::Object? = dynamic> extends self::_SplayTreeNode<self::_SplayTreeMapNode<self::_SplayTreeMapNode::V%>> {
+  constructor •() → self::_SplayTreeMapNode<self::_SplayTreeMapNode::V%>
+    : super self::_SplayTreeNode::•()
+    ;
+}
+abstract class _SplayTree<Node extends self::_SplayTreeNode<self::_SplayTree::Node> = self::_SplayTreeNode<dynamic>> extends core::Object {
+  synthetic constructor •() → self::_SplayTree<self::_SplayTree::Node>
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method add(generic-covariant-impl self::_SplayTree::Node n) → dynamic {
+    self::_SplayTree::Node? root = [@vm.direct-call.metadata=SplayTreeMap::_root] [@vm.inferred-type.metadata=#lib::_SplayTreeMapNode] this.{self::_SplayTree::_root};
+    if(false)
+      return;
+    core::print([@vm.direct-call.metadata=_SplayTreeNode::left] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] root{self::_SplayTree::Node}.{self::_SplayTreeNode::left});
+  }
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  abstract get /*isNullableByDefault*/ _root() → self::_SplayTree::Node?;
+}
+class SplayTreeMap<V extends core::Object? = dynamic> extends self::_SplayTree<self::_SplayTreeMapNode<self::SplayTreeMap::V%>> {
+[@vm.inferred-type.metadata=#lib::_SplayTreeMapNode] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:5]  generic-covariant-impl field self::_SplayTreeMapNode<self::SplayTreeMap::V%>? _root = new self::_SplayTreeMapNode::•<self::SplayTreeMap::V%>();
+  synthetic constructor •() → self::SplayTreeMap<self::SplayTreeMap::V%>
+    : super self::_SplayTree::•()
+    ;
+}
+static method main() → void {
+  [@vm.call-site-attributes.metadata=receiverType:InterfaceType(SplayTreeMap<dynamic>)] [@vm.direct-call.metadata=_SplayTree::add] new self::SplayTreeMap::•<dynamic>().{self::_SplayTree::add}(new self::_SplayTreeMapNode::•<dynamic>());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index b39b249..00c3bcf 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -19,7 +19,7 @@
   synthetic constructor •() → self::A1*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, [@vm.inferred-type.metadata=int?] dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = #C1]) → void {
     [@vm.direct-call.metadata=A1::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1*>(a5);
   }
 }
@@ -42,7 +42,7 @@
   synthetic constructor •() → self::A2*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, [@vm.inferred-type.metadata=int?] dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
     [@vm.direct-call.metadata=A2::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A2::foo} = a6;
   }
 }
@@ -75,7 +75,7 @@
   synthetic constructor •() → self::A3*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, [@vm.inferred-type.metadata=int?] dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
     [@vm.direct-call.metadata=A3::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A3::foo} = a7;
   }
 }
@@ -98,7 +98,7 @@
   synthetic constructor •() → self::A4*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method call([dynamic a1 = #C1, dynamic a2 = #C1, [@vm.inferred-type.metadata=int?] dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
     [@vm.direct-call.metadata=A4::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A4::foo} = a8;
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart
index 4fd9f27..710cf8f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart
@@ -5,7 +5,7 @@
 // Tests elimination of type casts.
 // This test requires non-nullable experiment.
 
-// @dart = 2.8
+// @dart = 2.9
 
 class A<T> {}
 
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart
index 8855bf4..588f620 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart
@@ -5,7 +5,7 @@
 // Tests elimination of type casts.
 // This test requires non-nullable experiment and NNBD strong mode.
 
-// @dart = 2.8
+// @dart = 2.9
 
 class A<T> {}
 
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
index 47a15c4..0ed46d3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
@@ -14,7 +14,7 @@
 [@vm.inferred-type.metadata=#lib::B?]static field self::I* ii = new self::B::•();
 static method bar([@vm.inferred-type.metadata=#lib::B?] self::I* i) → void {
   if(i is self::A*) {
-    let dynamic #t1 = i{self::A*} in let dynamic #t2 = 42 in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+    throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
   }
 }
 static method main(core::List<core::String*>* args) → dynamic {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
index 079f6e9..3ba876c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
@@ -2,8 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-abstract class A extends core::Object {
-}
 class B extends core::Object {
   constructor •() → self::B*
     : super core::Object::•() {
@@ -16,8 +14,7 @@
     : super core::Object::•()
     ;
 }
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field self::A* field = throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
 static method main() → void {
-  self::field = null;
+  null;
   [@vm.direct-call.metadata=C::instanceField] [@vm.inferred-type.metadata=!? (skip check)] new self::C::•().{self::C::instanceField} = null;
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart
new file mode 100644
index 0000000..af6a9b8
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for tree shaking of write-only fields.
+
+import "package:expect/expect.dart";
+
+foo() {}
+
+class A {
+  // Should be removed.
+  var unused1;
+
+  // Should be removed.
+  var unused2 = 42;
+
+  // Not removed due to a non-trivial initializer.
+  var unused3 = foo();
+}
+
+class B {
+  // Should be removed.
+  var unused4;
+
+  // Should be removed.
+  var unused5;
+
+  B(this.unused4) : unused5 = foo();
+}
+
+class C<T> {
+  // Should be replaced with setter.
+  T bar;
+}
+
+class D implements C<int> {
+  // Should be replaced with setter.
+  int bar;
+}
+
+class E {
+  // Should be replaced with getter.
+  final int bar;
+
+  E(this.bar);
+}
+
+class F implements E {
+  int get bar => 42;
+}
+
+class G {
+  // Not removed because used in a constant.
+  final int bazz;
+
+  const G(this.bazz);
+}
+
+class H {
+  // Should be replaced with setter.
+  int unused6;
+}
+
+class I extends H {
+  foo() {
+    super.unused6 = 3;
+  }
+}
+
+// Should be removed.
+int unusedStatic7 = foo();
+
+void main() {
+  new A();
+  new B('hi');
+
+  C<num> c = new D();
+  Expect.throws(() {
+    c.bar = 3.14;
+  });
+
+  E e = new F();
+  Expect.equals(42, e.bar);
+
+  Expect.isTrue(!identical(const G(1), const G(2)));
+
+  new I().foo();
+
+  unusedStatic7 = 5;
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
new file mode 100644
index 0000000..db8220b
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
@@ -0,0 +1,68 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class A extends core::Object {
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field dynamic unused3 = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::foo();
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString (value: hi)] dynamic unused4) → self::B*
+    : dynamic #t1 = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::foo(), super core::Object::•()
+    ;
+}
+abstract class C<T extends core::Object* = dynamic> extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3]  abstract set bar(generic-covariant-impl self::C::T* value) → void;
+}
+class D extends core::Object implements self::C<core::int*> {
+  synthetic constructor •() → self::D*
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3]  set bar(generic-covariant-impl core::int* value) → void;
+}
+abstract class E extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  abstract get bar() → core::int*;
+}
+class F extends core::Object implements self::E {
+  synthetic constructor •() → self::F*
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  get bar() → core::int*
+    return 42;
+}
+class G extends core::Object /*hasConstConstructor*/  {
+[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  final field core::int* bazz;
+}
+abstract class H extends core::Object {
+  synthetic constructor •() → self::H*
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7]  set unused6(core::int* value) → void;
+}
+class I extends self::H {
+  synthetic constructor •() → self::I*
+    : super self::H::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9]  method foo() → dynamic {
+    super.{self::H::unused6} = 3;
+  }
+}
+static method foo() → dynamic {}
+static method main() → void {
+  new self::A::•();
+  new self::B::•("hi");
+  self::C<core::num*>* c = new self::D::•();
+  exp::Expect::throws<dynamic>(() → core::Null? {
+    [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<num*>*)] [@vm.direct-call.metadata=D::bar] c.{self::C::bar} = 3.14;
+  });
+  self::E* e = new self::F::•();
+  exp::Expect::equals(42, [@vm.direct-call.metadata=F::bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar});
+  exp::Expect::isTrue(![@vm.inferred-type.metadata=dart.core::bool] core::identical(#C2, #C4));
+  [@vm.direct-call.metadata=I::foo] [@vm.inferred-type.metadata=!? (skip check)] new self::I::•().{self::I::foo}();
+  5;
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart
new file mode 100644
index 0000000..bcc6ec4
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for tree shaking of write-only late fields.
+// This test requires non-nullable experiment.
+
+// @dart = 2.9
+
+foo() {}
+
+class A {
+  // Should be replaced with setter.
+  late int x;
+
+  use() {
+    x = 3;
+  }
+}
+
+class B {
+  // Should be retained.
+  late final int x;
+
+  use() {
+    x = 3;
+  }
+}
+
+// Should be removed.
+late int staticLateA;
+
+// Should be retained.
+late final int staticLateB;
+
+void main() {
+  new A().use();
+  new B().use();
+
+  staticLateA = 4;
+  staticLateB = 4;
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
new file mode 100644
index 0000000..fd4556d
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
@@ -0,0 +1,29 @@
+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 use() → dynamic {
+    [@vm.direct-call.metadata=A::x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A::x} = 3;
+  }
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3]  set /*isNullableByDefault*/ x(core::int value) → void;
+}
+class B extends core::Object {
+[@vm.inferred-type.metadata=dart.core::_Smi?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  late final [setter] field core::int x;
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method use() → dynamic {
+    [@vm.direct-call.metadata=B::x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::B::x} = 3;
+  }
+}
+[@vm.inferred-type.metadata=dart.core::_Smi?]late static final field core::int staticLateB;
+static method main() → void {
+  [@vm.direct-call.metadata=A::use] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::use}();
+  [@vm.direct-call.metadata=B::use] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::use}();
+  4;
+  self::staticLateB = 4;
+}
diff --git a/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect b/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect
index acdab7a..04ae51a 100644
--- a/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect
+++ b/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect
@@ -1,7 +1,6 @@
 library #lib;
 import self as self;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 class TestAssertInitializer extends core::Object {
   constructor •() → self::TestAssertInitializer*
@@ -58,7 +57,7 @@
   for (; ; ) {
   }
   {
-    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int*>[1, 2]).{core::Iterable::iterator};
+    core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2].{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       core::int* i = :sync-for-iterator.{core::Iterator::current};
     }
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index 326a854..b76c8bb 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -36,6 +36,9 @@
     --no-tfa | \
     --gen-bytecode | \
     --no-gen-bytecode | \
+    --bytecode-options=* | \
+    --minimal-kernel | \
+    --no-embed-sources | \
     -D* )
     GEN_KERNEL_OPTIONS+=("$arg")
     ;;
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index cbe9222..9a99196 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,19 @@
 # Changelog
 
+## next
+- Update to version `3.33.0` of the spec.
+- Add static error code constants to `RPCError`.
+- Update the toString() method or `RPCError` and add a toMap() method.
+
+## 4.0.2
+- Fixed issue where RPC format did not conform to the JSON-RPC 2.0
+  specification.
+- Added `getClassList` RPC.
+
+## 4.0.1
+- Improved documentation.
+- Fixed analysis issues.
+
 ## 4.0.0
 - **breaking**: RPCs which can return a `Sentinel` will now throw a `SentinelException`
   if a `Sential` is received as a response.
diff --git a/pkg/vm_service/java/.gitignore b/pkg/vm_service/java/.gitignore
index ae0cc5a..ebfb5c7 100644
--- a/pkg/vm_service/java/.gitignore
+++ b/pkg/vm_service/java/.gitignore
@@ -10,6 +10,7 @@
 src/org/dartlang/vm/service/consumer/EvaluateInFrameConsumer.java
 src/org/dartlang/vm/service/consumer/FlagListConsumer.java
 src/org/dartlang/vm/service/consumer/GetAllocationProfileConsumer.java
+src/org/dartlang/vm/service/consumer/GetClassListConsumer.java
 src/org/dartlang/vm/service/consumer/GetCpuSamplesConsumer.java
 src/org/dartlang/vm/service/consumer/GetInboundReferencesConsumer.java
 src/org/dartlang/vm/service/consumer/GetInstancesConsumer.java
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index 4394db5..47ae094 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.30
+version=3.33
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 03d939e..d9ce8d7 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -28,7 +28,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.30.0';
+const String vmServiceVersion = '3.33.0';
 
 /// @optional
 const String optional = 'optional';
@@ -194,6 +194,7 @@
   'evaluate': const ['InstanceRef', 'ErrorRef'],
   'evaluateInFrame': const ['InstanceRef', 'ErrorRef'],
   'getAllocationProfile': const ['AllocationProfile'],
+  'getClassList': const ['ClassList'],
   'getClientName': const ['ClientName'],
   'getCpuSamples': const ['CpuSamples'],
   'getFlagList': const ['FlagList'],
@@ -497,6 +498,18 @@
   Future<AllocationProfile> getAllocationProfile(String isolateId,
       {bool reset, bool gc});
 
+  /// The `getClassList` RPC is used to retrieve a `ClassList` containing all
+  /// classes for an isolate based on the isolate's `isolateId`.
+  ///
+  /// If `isolateId` refers to an isolate which has exited, then the `Collected`
+  /// [Sentinel] is returned.
+  ///
+  /// See [ClassList].
+  ///
+  /// This method will throw a [SentinelException] in the case a [Sentinel] is
+  /// returned.
+  Future<ClassList> getClassList(String isolateId);
+
   /// The `getClientName` RPC is used to retrieve the name associated with the
   /// currently connected VM service client. If no name was previously set
   /// through the [setClientName] RPC, a default name will be returned.
@@ -1183,7 +1196,8 @@
       }
       var method = request['method'] as String;
       if (method == null) {
-        throw RPCError(null, -32600, 'Invalid Request', request);
+        throw RPCError(
+            null, RPCError.kInvalidRequest, 'Invalid Request', request);
       }
       var params = request['params'] as Map;
       Response response;
@@ -1257,6 +1271,11 @@
             gc: params['gc'],
           );
           break;
+        case 'getClassList':
+          response = await _serviceImplementation.getClassList(
+            params['isolateId'],
+          );
+          break;
         case 'getClientName':
           response = await _serviceImplementation.getClientName();
           break;
@@ -1445,9 +1464,12 @@
           var id = params['streamId'];
           var existing = _streamSubscriptions.remove(id);
           if (existing == null) {
-            throw RPCError('streamCancel', 104, 'Stream not subscribed', {
-              'details': "The stream '$id' is not subscribed",
-            });
+            throw RPCError.withDetails(
+              'streamCancel',
+              104,
+              'Stream not subscribed',
+              details: "The stream '$id' is not subscribed",
+            );
           }
           await existing.cancel();
           response = Success();
@@ -1455,9 +1477,12 @@
         case 'streamListen':
           var id = params['streamId'];
           if (_streamSubscriptions.containsKey(id)) {
-            throw RPCError('streamListen', 103, 'Stream already subscribed', {
-              'details': "The stream '$id' is already subscribed",
-            });
+            throw RPCError.withDetails(
+              'streamListen',
+              103,
+              'Stream already subscribed',
+              details: "The stream '$id' is already subscribed",
+            );
           }
 
           var stream = id == 'Service'
@@ -1493,7 +1518,8 @@
             response = await _serviceImplementation.callServiceExtension(method,
                 isolateId: isolateId, args: args);
           } else {
-            throw RPCError(method, -32601, 'Method not found', request);
+            throw RPCError(
+                method, RPCError.kMethodNotFound, 'Method not found', request);
           }
       }
       if (response == null) {
@@ -1506,8 +1532,12 @@
       });
     } catch (e, st) {
       var error = e is RPCError
-          ? {'code': e.code, 'data': e.data, 'message': e.message}
-          : {'code': -32603, 'message': '$e\n$st'};
+          ? e.toMap()
+          : {
+              'code': RPCError.kInternalError,
+              'message': '${request['method']}: $e',
+              'data': {'details': '$st'},
+            };
       _responseSink.add({
         'jsonrpc': '2.0',
         'id': request['id'],
@@ -1703,6 +1733,10 @@
       });
 
   @override
+  Future<ClassList> getClassList(String isolateId) =>
+      _call('getClassList', {'isolateId': isolateId});
+
+  @override
   Future<ClientName> getClientName() => _call('getClientName');
 
   @override
@@ -1941,8 +1975,8 @@
     _streamSub.cancel();
     _completers.forEach((id, c) {
       final method = _methodCalls[id];
-      return c.completeError(
-          RPCError(method, -32000, 'Service connection disposed'));
+      return c.completeError(RPCError(
+          method, RPCError.kServerError, 'Service connection disposed'));
     });
     _completers.clear();
     if (_disposeHandler != null) {
@@ -1955,13 +1989,17 @@
 
   Future get onDone => _onDoneCompleter.future;
 
-  Future<T> _call<T>(String method, [Map args]) {
+  Future<T> _call<T>(String method, [Map args = const {}]) {
     String id = '${++_id}';
     Completer<T> completer = Completer<T>();
     _completers[id] = completer;
     _methodCalls[id] = method;
-    Map m = {'id': id, 'method': method};
-    if (args != null) m['params'] = args;
+    Map m = {
+      'jsonrpc': '2.0',
+      'id': id,
+      'method': method,
+      'params': args,
+    };
     String message = jsonEncode(m);
     _onSend.add(message);
     _writeMessage(message);
@@ -2057,7 +2095,7 @@
   }
 
   Future _processRequest(Map<String, dynamic> json) async {
-    final Map m = await _routeRequest(json['method'], json['params']);
+    final Map m = await _routeRequest(json['method'], json['params'] ?? {});
     m['id'] = json['id'];
     m['jsonrpc'] = '2.0';
     String message = jsonEncode(m);
@@ -2067,7 +2105,7 @@
 
   Future _processNotification(Map<String, dynamic> json) async {
     final String method = json['method'];
-    final Map params = json['params'];
+    final Map params = json['params'] ?? {};
     if (method == 'streamNotify') {
       String streamId = params['streamId'];
       _getEventController(streamId)
@@ -2078,23 +2116,22 @@
   }
 
   Future<Map> _routeRequest(String method, Map params) async {
+    if (!_services.containsKey(method)) {
+      RPCError error = RPCError(
+          method, RPCError.kMethodNotFound, 'method not found \'$method\'');
+      return {'error': error.toMap()};
+    }
+
     try {
-      if (_services.containsKey(method)) {
-        return await _services[method](params);
-      }
-      return {
-        'error': {
-          'code': -32601, // Method not found
-          'message': 'Method not found \'$method\''
-        }
-      };
+      return await _services[method](params);
     } catch (e, st) {
-      return {
-        'error': {
-          'code': -32000, // SERVER ERROR
-          'message': 'Unexpected Server Error $e\n$st'
-        }
-      };
+      RPCError error = RPCError.withDetails(
+        method,
+        RPCError.kServerError,
+        '$e',
+        details: '$st',
+      );
+      return {'error': error.toMap()};
     }
   }
 }
@@ -2102,6 +2139,21 @@
 typedef DisposeHandler = Future Function();
 
 class RPCError implements Exception {
+  /// Application specific error codes.
+  static const int kServerError = -32000;
+
+  /// The JSON sent is not a valid Request object.
+  static const int kInvalidRequest = -32600;
+
+  /// The method does not exist or is not available.
+  static const int kMethodNotFound = -32601;
+
+  /// Invalid method parameter(s), such as a mismatched type.
+  static const int kInvalidParams = -32602;
+
+  /// Internal JSON-RPC error.
+  static const int kInternalError = -32603;
+
   static RPCError parse(String callingMethod, dynamic json) {
     return RPCError(callingMethod, json['code'], json['message'], json['data']);
   }
@@ -2113,13 +2165,34 @@
 
   RPCError(this.callingMethod, this.code, this.message, [this.data]);
 
+  RPCError.withDetails(this.callingMethod, this.code, this.message,
+      {Object details})
+      : data = details == null ? null : <String, dynamic>{} {
+    if (details != null) {
+      data['details'] = details;
+    }
+  }
+
   String get details => data == null ? null : data['details'];
 
+  /// Return a map representation of this error suitable for converstion to
+  /// json.
+  Map<String, dynamic> toMap() {
+    Map<String, dynamic> map = {
+      'code': code,
+      'message': message,
+    };
+    if (data != null) {
+      map['data'] = data;
+    }
+    return map;
+  }
+
   String toString() {
     if (details == null) {
-      return '${message} (${code}) from ${callingMethod}()';
+      return '$callingMethod: ($code) $message';
     } else {
-      return '${message} (${code}) from ${callingMethod}():\n${details}';
+      return '$callingMethod: ($code) $message\n$details';
     }
   }
 }
@@ -3514,7 +3587,6 @@
   /// The status (success or failure) related to the event. This is provided for
   /// the event kinds:
   ///  - IsolateReloaded
-  ///  - IsolateSpawn
   @optional
   String status;
 
@@ -6352,7 +6424,9 @@
   static Timeline parse(Map<String, dynamic> json) =>
       json == null ? null : Timeline._fromJson(json);
 
-  /// A list of timeline events.
+  /// A list of timeline events. No order is guarenteed for these events; in
+  /// particular, these events may be unordered with respect to their
+  /// timestamps.
   List<TimelineEvent> traceEvents;
 
   /// The start of the period of time in which traceEvents were collected.
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index 366bd74..45a7871 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
 description: >-
   A library to communicate with a service implementing the Dart VM
   service protocol.
-version: 4.0.0
+version: 4.0.2
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/pkg/vm_service/test/common/test_helper.dart b/pkg/vm_service/test/common/test_helper.dart
index 186e2e3..2851672 100644
--- a/pkg/vm_service/test/common/test_helper.dart
+++ b/pkg/vm_service/test/common/test_helper.dart
@@ -289,29 +289,34 @@
 
     final name = _getTestUri().pathSegments.last;
 
-    test(name, () async {
-      // Run vm tests.
-      if (vmTests != null) {
-        var testIndex = 1;
-        var totalTests = vmTests.length;
-        for (var t in vmTests) {
-          print('$name [$testIndex/$totalTests]');
-          await t(vm);
-          testIndex++;
+    test(
+      name,
+      () async {
+        // Run vm tests.
+        if (vmTests != null) {
+          var testIndex = 1;
+          var totalTests = vmTests.length;
+          for (var t in vmTests) {
+            print('$name [$testIndex/$totalTests]');
+            await t(vm);
+            testIndex++;
+          }
         }
-      }
 
-      // Run isolate tests.
-      if (isolateTests != null) {
-        var testIndex = 1;
-        var totalTests = isolateTests.length;
-        for (var t in isolateTests) {
-          print('$name [$testIndex/$totalTests]');
-          await t(vm, isolate);
-          testIndex++;
+        // Run isolate tests.
+        if (isolateTests != null) {
+          var testIndex = 1;
+          var totalTests = isolateTests.length;
+          for (var t in isolateTests) {
+            print('$name [$testIndex/$totalTests]');
+            await t(vm, isolate);
+            testIndex++;
+          }
         }
-      }
-    }, retry: 3);
+      },
+      retry: 0,
+      timeout: Timeout.none,
+    );
 
     tearDown(() {
       print('All service tests completed successfully.');
diff --git a/pkg/vm_service/test/server_test.dart b/pkg/vm_service/test/server_test.dart
index d0ed5b0..ab0347c 100644
--- a/pkg/vm_service/test/server_test.dart
+++ b/pkg/vm_service/test/server_test.dart
@@ -193,7 +193,7 @@
       expect(
           responsesController.stream.map((response) => '$response'),
           emits(startsWith(
-              '{jsonrpc: 2.0, id: 1, error: {code: -32603, message: UnimplementedError')));
+              '{jsonrpc: 2.0, id: 1, error: {code: -32603, message: getVersion: UnimplementedError')));
       requestsController.add(request);
     });
   });
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 0e85f27..68b7daa 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -104,8 +104,8 @@
     _streamSub.cancel();
     _completers.forEach((id, c) {
       final method = _methodCalls[id];
-      return c.completeError(
-          RPCError(method, -32000, 'Service connection disposed'));
+      return c.completeError(RPCError(
+          method, RPCError.kServerError, 'Service connection disposed'));
     });
     _completers.clear();
     if (_disposeHandler != null) {
@@ -118,13 +118,12 @@
 
   Future get onDone => _onDoneCompleter.future;
 
-  Future<T> _call<T>(String method, [Map args]) {
+  Future<T> _call<T>(String method, [Map args = const {}]) {
     String id = '${++_id}';
     Completer<T> completer = Completer<T>();
     _completers[id] = completer;
     _methodCalls[id] = method;
-    Map m = {'id': id, 'method': method};
-    if (args != null) m['params'] = args;
+    Map m = {'jsonrpc': '2.0', 'id': id, 'method': method, 'params': args,};
     String message = jsonEncode(m);
     _onSend.add(message);
     _writeMessage(message);
@@ -221,7 +220,7 @@
   }
 
   Future _processRequest(Map<String, dynamic> json) async {
-    final Map m = await _routeRequest(json['method'], json['params']);
+    final Map m = await _routeRequest(json['method'], json['params'] ?? {});
     m['id'] = json['id'];
     m['jsonrpc'] = '2.0';
     String message = jsonEncode(m);
@@ -231,7 +230,7 @@
 
   Future _processNotification(Map<String, dynamic> json) async {
     final String method = json['method'];
-    final Map params = json['params'];
+    final Map params = json['params'] ?? {};
     if (method == 'streamNotify') {
       String streamId = params['streamId'];
       _getEventController(streamId).add(createServiceObject(params['event'], const ['Event']));
@@ -241,23 +240,18 @@
   }
 
   Future<Map> _routeRequest(String method, Map params) async{
+    if (!_services.containsKey(method)) {
+      RPCError error = RPCError(
+          method, RPCError.kMethodNotFound, 'method not found \'$method\'');
+      return {'error': error.toMap()};
+    }
+
     try {
-      if (_services.containsKey(method)) {
-        return await _services[method](params);
-      }
-      return {
-        'error': {
-          'code': -32601, // Method not found
-          'message': 'Method not found \'$method\''
-        }
-      };
+      return await _services[method](params);
     } catch (e, st) {
-      return {
-        'error': {
-          'code': -32000, // SERVER ERROR
-          'message': 'Unexpected Server Error $e\n$st'
-        }
-      };
+      RPCError error = RPCError.withDetails(
+        method, RPCError.kServerError, '$e', details: '$st',);
+      return {'error': error.toMap()};
     }
   }
 ''';
@@ -268,6 +262,21 @@
 typedef DisposeHandler = Future Function();
 
 class RPCError implements Exception {
+  /// Application specific error codes.
+  static const int kServerError = -32000;
+
+  /// The JSON sent is not a valid Request object.
+  static const int kInvalidRequest = -32600;
+
+  /// The method does not exist or is not available.
+  static const int kMethodNotFound = -32601;
+
+  /// Invalid method parameter(s), such as a mismatched type.
+  static const int kInvalidParams = -32602;
+
+  /// Internal JSON-RPC error.
+  static const int kInternalError = -32603;
+
   static RPCError parse(String callingMethod, dynamic json) {
     return RPCError(callingMethod, json['code'], json['message'], json['data']);
   }
@@ -279,13 +288,34 @@
 
   RPCError(this.callingMethod, this.code, this.message, [this.data]);
 
+  RPCError.withDetails(this.callingMethod, this.code, this.message,
+      {Object details})
+      : data = details == null ? null : <String, dynamic>{} {
+    if (details != null) {
+      data['details'] = details;
+    }
+  }
+
   String get details => data == null ? null : data['details'];
 
+  /// Return a map representation of this error suitable for converstion to
+  /// json.
+  Map<String, dynamic> toMap() {
+    Map<String, dynamic> map = {
+      'code': code,
+      'message': message,
+    };
+    if (data != null) {
+      map['data'] = data;
+    }
+    return map;
+  }
+
   String toString() {
     if (details == null) {
-      return '${message} (${code}) from ${callingMethod}()';
+      return '$callingMethod: ($code) $message';
     } else {
-      return '${message} (${code}) from ${callingMethod}():\n${details}';
+      return '$callingMethod: ($code) $message\n$details';
     }
   }
 }
@@ -338,9 +368,10 @@
 final _streamListenCaseImpl = '''
 var id = params['streamId'];
 if (_streamSubscriptions.containsKey(id)) {
-  throw RPCError('streamListen', 103, 'Stream already subscribed', {
-      'details': "The stream '\$id' is already subscribed",
-    });
+  throw RPCError.withDetails(
+    'streamListen', 103, 'Stream already subscribed',
+    details: "The stream '\$id' is already subscribed",
+  );
 }
 
 var stream = id == 'Service'
@@ -362,9 +393,10 @@
 var id = params['streamId'];
 var existing = _streamSubscriptions.remove(id);
 if (existing == null) {
-  throw RPCError('streamCancel', 104, 'Stream not subscribed', {
-      'details': "The stream '\$id' is not subscribed",
-    });
+  throw RPCError.withDetails(
+    'streamCancel', 104, 'Stream not subscribed',
+    details: "The stream '\$id' is not subscribed",
+  );
 }
 await existing.cancel();
 response = Success();''';
@@ -664,7 +696,8 @@
         }
         var method = request['method'] as String;
         if (method == null) {
-          throw RPCError(null, -32600, 'Invalid Request', request);
+          throw RPCError(
+            null, RPCError.kInvalidRequest, 'Invalid Request', request);
         }
         var params = request['params'] as Map;
         Response response;
@@ -729,7 +762,7 @@
           response = await _serviceImplementation.callServiceExtension(method,
               isolateId: isolateId, args: args);
         } else {
-          throw RPCError(method, -32601, 'Method not found', request);
+          throw RPCError(method, RPCError.kMethodNotFound, 'Method not found', request);
         }
 ''');
     // Terminate the switch
@@ -754,8 +787,12 @@
     gen.write(r'''
       } catch (e, st) {
         var error = e is RPCError
-            ? {'code': e.code, 'data': e.data, 'message': e.message}
-            : {'code': -32603, 'message': '$e\n$st'};
+            ? e.toMap()
+            : {
+                'code': RPCError.kInternalError,
+                'message': '${request['method']}: $e',
+                'data': {'details': '$st'},
+              };
         _responseSink.add({
           'jsonrpc': '2.0',
           'id': request['id'],
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 88b27a9..c7d66dc 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -236,6 +236,7 @@
     "vm:libdart_lib",
     "vm:libdart_vm",
   ]
+  compiler_lib = "vm:libdart_compiler"
   extra_configs = [ ":dart_shared_lib" ]
   include_dirs = [ "." ]
   public_configs = [ ":dart_public_config" ]
diff --git a/runtime/bin/dartdev_utils.cc b/runtime/bin/dartdev_utils.cc
index 4708e1e..3f14bc4 100644
--- a/runtime/bin/dartdev_utils.cc
+++ b/runtime/bin/dartdev_utils.cc
@@ -14,13 +14,10 @@
 namespace dart {
 namespace bin {
 
-// TODO(bkonyi): re-enable after 2.8 release.
-const bool kDartDevEnabled = false;
-
 bool DartDevUtils::ShouldParseCommand(const char* script_uri) {
   // If script_uri is not a file path or of a known URI scheme, we can assume
   // that this is a DartDev command.
-  return (kDartDevEnabled && !File::ExistsUri(nullptr, script_uri) &&
+  return (!File::ExistsUri(nullptr, script_uri) &&
           (strncmp(script_uri, "http://", 7) != 0) &&
           (strncmp(script_uri, "https://", 8) != 0) &&
           (strncmp(script_uri, "file://", 7) != 0) &&
@@ -30,12 +27,11 @@
 
 bool DartDevUtils::TryResolveDartDevSnapshotPath(char** script_name) {
   // |dir_prefix| includes the last path seperator.
-  auto dir_prefix = std::unique_ptr<char, void (*)(void*)>(
-      EXEUtils::GetDirectoryPrefixFromExeName(), free);
+  auto dir_prefix = EXEUtils::GetDirectoryPrefixFromExeName();
 
   // First assume we're in dart-sdk/bin.
   char* snapshot_path =
-      Utils::SCreate("%s/snapshots/dartdev.dart.snapshot", dir_prefix.get());
+      Utils::SCreate("%ssnapshots/dartdev.dart.snapshot", dir_prefix.get());
   if (File::Exists(nullptr, snapshot_path)) {
     *script_name = snapshot_path;
     return true;
@@ -44,8 +40,7 @@
 
   // If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
   // directories. Try to use a snapshot from a previously built SDK.
-  snapshot_path = Utils::SCreate(
-      "%s/dart-sdk/bin/snapshots/dartdev.dart.snapshot", dir_prefix.get());
+  snapshot_path = Utils::SCreate("%sdartdev.dart.snapshot", dir_prefix.get());
   if (File::Exists(nullptr, snapshot_path)) {
     *script_name = snapshot_path;
     return true;
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index be84119..71d0437 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -704,6 +704,10 @@
   return NewDartExceptionWithMessage(kCoreLibURL, "ArgumentError", message);
 }
 
+Dart_Handle DartUtils::NewDartFormatException(const char* message) {
+  return NewDartExceptionWithMessage(kCoreLibURL, "FormatException", message);
+}
+
 Dart_Handle DartUtils::NewDartUnsupportedError(const char* message) {
   return NewDartExceptionWithMessage(kCoreLibURL, "UnsupportedError", message);
 }
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index a0744ab..5a405f3 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -175,6 +175,7 @@
                                                  const char* exception_name,
                                                  const char* message);
   static Dart_Handle NewDartArgumentError(const char* message);
+  static Dart_Handle NewDartFormatException(const char* message);
   static Dart_Handle NewDartUnsupportedError(const char* message);
   static Dart_Handle NewDartIOException(const char* exception_name,
                                         const char* message,
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index f700d50..39dec0c 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -113,8 +113,7 @@
   }
 
   // |dir_prefix| includes the last path seperator.
-  auto dir_prefix = std::unique_ptr<char, void (*)(void*)>(
-      EXEUtils::GetDirectoryPrefixFromExeName(), free);
+  auto dir_prefix = EXEUtils::GetDirectoryPrefixFromExeName();
 
   if (target_abi_version != Options::kAbiVersionUnset) {
     kernel_service_dill_ = nullptr;
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 6b3ce66..cb6f882 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -453,7 +453,7 @@
     size_t len = strlen(arg);
     Dart_CObject* io_buffer = CObject::NewIOBuffer(len);
     uint8_t* data = io_buffer->value.as_external_typed_data.data;
-    strncpy(reinterpret_cast<char*>(data), arg, len);
+    memmove(reinterpret_cast<char*>(data), arg, len);
 
     CObjectExternalUint8Array* external_array =
         new CObjectExternalUint8Array(io_buffer);
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index 8c963c4..8394deb 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -161,7 +161,12 @@
   MutexLocker ml(&mutex_);
   // Do not ask for POLLERR and POLLHUP explicitly as they are
   // triggered anyway.
-  uint32_t events = POLLRDHUP;
+  uint32_t events = 0;
+  // Do not subscribe to read closed events when kCloseEvent has already been
+  // sent to the Dart thread.
+  if (close_events_enabled_) {
+    events |= POLLRDHUP;
+  }
   if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) {
     events |= POLLIN;
   }
@@ -253,19 +258,39 @@
   return events;
 }
 
+// This function controls the simulation of edge-triggering. It is responsible
+// for removing events from the event mask when they should be supressed, and
+// for supressing future events. Events are unsupressed by their respective
+// operations by the Dart thread on the socket---that is, where the
+// *_events_enabled_ flags are set to true.
 intptr_t IOHandle::ToggleEvents(intptr_t event_mask) {
   MutexLocker ml(&mutex_);
+  // If write events are disabled, then remove the kOutEvent bit from the
+  // event mask.
   if (!write_events_enabled_) {
-    LOG_INFO("IOHandle::ToggleEvents: fd = %ld de-asserting write\n", fd_);
+    LOG_INFO(
+        "IOHandle::ToggleEvents: fd = %ld "
+        "de-asserting kOutEvent\n",
+        fd_);
     event_mask = event_mask & ~(1 << kOutEvent);
   }
+  // If the kOutEvent bit is set, then supress future write events until the
+  // Dart thread writes.
   if ((event_mask & (1 << kOutEvent)) != 0) {
-    LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting write and disabling\n",
-             fd_);
+    LOG_INFO(
+        "IOHandle::ToggleEvents: fd = %ld "
+        "asserting kOutEvent and disabling\n",
+        fd_);
     write_events_enabled_ = false;
   }
+
+  // If read events are disabled, then remove the kInEvent bit from the event
+  // mask.
   if (!read_events_enabled_) {
-    LOG_INFO("IOHandle::ToggleEvents: fd=%ld de-asserting read\n", fd_);
+    LOG_INFO(
+        "IOHandle::ToggleEvents: fd = %ld "
+        "de-asserting kInEvent\n",
+        fd_);
     event_mask = event_mask & ~(1 << kInEvent);
   }
   // We may get In events without available bytes, so we must make sure there
@@ -283,11 +308,43 @@
   //
   // As a detail, negative available bytes (errors) are handled specially; see
   // IOHandle::AvailableBytes for more information.
-  if ((event_mask & (1 << kInEvent)) != 0 &&
-      FDUtils::AvailableBytes(fd_) != 0) {
-    LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting read and disabling\n",
-             fd_);
-    read_events_enabled_ = false;
+  if ((event_mask & (1 << kInEvent)) != 0) {
+    if (FDUtils::AvailableBytes(fd_) != 0) {
+      LOG_INFO(
+          "IOHandle::ToggleEvents: fd = %ld "
+          "asserting kInEvent and disabling with bytes available\n",
+          fd_);
+      read_events_enabled_ = false;
+    }
+    // Also supress future read events if we get a kCloseEvent. This is to
+    // account for POLLIN being set by Fuchsia when the socket is read-closed.
+    if ((event_mask & (1 << kCloseEvent)) != 0) {
+      LOG_INFO(
+          "IOHandle::ToggleEvents: fd = %ld "
+          "asserting kInEvent and disabling due to a close event\n",
+          fd_);
+      read_events_enabled_ = false;
+    }
+  }
+
+  // If the close events are disabled, then remove the kCloseEvent bit from the
+  // event mask.
+  if (!close_events_enabled_) {
+    LOG_INFO(
+        "IOHandle::ToggleEvents: fd = %ld "
+        "de-asserting kCloseEvent\n",
+        fd_);
+    event_mask = event_mask & ~(1 << kCloseEvent);
+  }
+  // If the kCloseEvent bit is set, then supress future close events, they will
+  // be ignored by the Dart thread. See _NativeSocket.multiplex in
+  // socket_patch.dart.
+  if ((event_mask & (1 << kCloseEvent)) != 0) {
+    LOG_INFO(
+        "IOHandle::ToggleEvents: fd = %ld "
+        "asserting kCloseEvent and disabling\n",
+        fd_);
+    close_events_enabled_ = false;
   }
   return event_mask;
 }
diff --git a/runtime/bin/eventhandler_fuchsia.h b/runtime/bin/eventhandler_fuchsia.h
index 07acef97..0011f26 100644
--- a/runtime/bin/eventhandler_fuchsia.h
+++ b/runtime/bin/eventhandler_fuchsia.h
@@ -34,6 +34,7 @@
         mutex_(),
         write_events_enabled_(true),
         read_events_enabled_(true),
+        close_events_enabled_(true),
         fd_(fd),
         handle_(ZX_HANDLE_INVALID),
         wait_key_(0),
@@ -73,6 +74,8 @@
   Mutex mutex_;
   bool write_events_enabled_;
   bool read_events_enabled_;
+  bool close_events_enabled_;
+
   // Bytes remaining to be read from the socket. Read events should only be
   // re-enabled when this drops to zero.
   intptr_t available_bytes_;
diff --git a/runtime/bin/exe_utils.cc b/runtime/bin/exe_utils.cc
index 81568ab..d9333dc 100644
--- a/runtime/bin/exe_utils.cc
+++ b/runtime/bin/exe_utils.cc
@@ -12,7 +12,60 @@
 namespace dart {
 namespace bin {
 
-char* EXEUtils::GetDirectoryPrefixFromExeName() {
+static bool StartsWithPathSeparator(const char* path,
+                                    const char* sep,
+                                    intptr_t sep_length) {
+  return (strncmp(path, sep, sep_length) == 0
+#if defined(HOST_OS_WINDOWS)
+          // TODO(aam): GetExecutableName doesn't work reliably on Windows,
+          || *path == '/'
+#endif
+  );
+}
+
+// Returns the directory portion of a given path.
+//
+// If dir is NULL, the result must be freed by the caller. Otherwise, the
+// result is copied into dir.
+static char* GetDirectoryFromPath(const char* path, char* dir) {
+  const char* sep = File::PathSeparator();
+  const intptr_t sep_length = strlen(sep);
+  intptr_t path_len = strlen(path);
+
+  for (intptr_t i = path_len - 1; i >= 0; --i) {
+    const char* str = path + i;
+    if (StartsWithPathSeparator(str, sep, sep_length)) {
+      if (dir != nullptr) {
+        strncpy(dir, path, i);
+        dir[i] = '\0';
+        return dir;
+      } else {
+        return Utils::StrNDup(path, i + 1);
+      }
+    }
+  }
+  return nullptr;
+}
+
+// Returns the file portion of a given path. Returned string is either
+// `path` if no path separators are found or `path + separator_loc + sep_length`
+// if a separator is found.
+static const char* GetFileNameFromPath(const char* path) {
+  const char* sep = File::PathSeparator();
+  const intptr_t sep_length = strlen(sep);
+  intptr_t path_len = strlen(path);
+
+  for (intptr_t i = path_len - 1; i >= 0; --i) {
+    const char* str = path + i;
+    if (StartsWithPathSeparator(str, sep, sep_length)) {
+      return str + sep_length;
+    }
+  }
+  // No path separators, assume that path is a file name.
+  return path;
+}
+
+Utils::CStringUniquePtr EXEUtils::GetDirectoryPrefixFromExeName() {
   const char* name = nullptr;
   const int kTargetSize = 4096;
   char target[kTargetSize];
@@ -25,42 +78,36 @@
   if (name == nullptr) {
     name = Platform::GetExecutableName();
     target_size = strlen(name);
+    ASSERT(target_size < kTargetSize);
   }
   Namespace* namespc = Namespace::Create(Namespace::Default());
-
-  // We might run into symlinks of symlinks, so make sure we follow the
-  // links all the way. See https://github.com/dart-lang/sdk/issues/41057 for
-  // an example where this happens with brew on MacOS.
-  bool followedSymlink = false;
-  while (File::GetType(namespc, name, false) == File::kIsLink) {
-    // Resolve the link without creating Dart scope String.
-    name = File::LinkTarget(namespc, name, target, kTargetSize);
-    if (name == NULL) {
-      return strdup("");
-    }
-    followedSymlink = true;
-  }
-  if (followedSymlink) {
+  if (File::GetType(namespc, name, false) == File::kIsLink) {
+    char dir_path[kTargetSize];
+    // cwd is currently wherever we launched from, so set the cwd to the
+    // directory of the symlink while we try and resolve it. If we don't
+    // do this, we won't be able to properly resolve relative paths.
+    auto initial_dir_path =
+        Utils::CreateCStringUniquePtr(Directory::CurrentNoScope());
+    // We might run into symlinks of symlinks, so make sure we follow the
+    // links all the way. See https://github.com/dart-lang/sdk/issues/41057 for
+    // an example where this happens with brew on MacOS.
+    do {
+      Directory::SetCurrent(namespc, GetDirectoryFromPath(name, dir_path));
+      // Resolve the link without creating Dart scope String.
+      name = File::LinkTarget(namespc, GetFileNameFromPath(name), target,
+                              kTargetSize);
+      if (name == nullptr) {
+        return Utils::CreateCStringUniquePtr(strdup(""));
+      }
+    } while (File::GetType(namespc, name, false) == File::kIsLink);
     target_size = strlen(name);
+
+    // Reset cwd to the original value.
+    Directory::SetCurrent(namespc, initial_dir_path.get());
   }
   namespc->Release();
-  const char* sep = File::PathSeparator();
-  const intptr_t sep_length = strlen(sep);
-
-  for (intptr_t i = target_size - 1; i >= 0; --i) {
-    const char* str = name + i;
-    if (strncmp(str, sep, sep_length) == 0
-#if defined(HOST_OS_WINDOWS)
-        // TODO(aam): GetExecutableName doesn't work reliably on Windows,
-        // the code below is a workaround for that (we would be using
-        // just single Platform::Separator instead of both slashes if it did).
-        || *str == '/'
-#endif
-    ) {
-      return Utils::StrNDup(name, i + 1);
-    }
-  }
-  return strdup("");
+  char* result = GetDirectoryFromPath(name, nullptr);
+  return Utils::CreateCStringUniquePtr(result == nullptr ? strdup("") : result);
 }
 
 }  // namespace bin
diff --git a/runtime/bin/exe_utils.h b/runtime/bin/exe_utils.h
index 42d27fe..0c3eafb 100644
--- a/runtime/bin/exe_utils.h
+++ b/runtime/bin/exe_utils.h
@@ -10,6 +10,7 @@
 
 #include "include/dart_api.h"
 #include "platform/globals.h"
+#include "platform/utils.h"
 
 namespace dart {
 namespace bin {
@@ -17,7 +18,7 @@
 class EXEUtils {
  public:
   // Returns the path to the directory the current executable resides in.
-  static char* GetDirectoryPrefixFromExeName();
+  static Utils::CStringUniquePtr GetDirectoryPrefixFromExeName();
 
  private:
   DISALLOW_COPY_AND_ASSIGN(EXEUtils);
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
index 292b978..c7eb4db 100644
--- a/runtime/bin/filter.cc
+++ b/runtime/bin/filter.cc
@@ -240,7 +240,8 @@
   intptr_t read = filter->Processed(
       filter->processed_buffer(), filter->processed_buffer_size(), flush, end);
   if (read < 0) {
-    Dart_ThrowException(DartUtils::NewInternalError("Filter error, bad data"));
+    Dart_ThrowException(
+        DartUtils::NewDartFormatException("Filter error, bad data"));
   } else if (read == 0) {
     Dart_SetReturnValue(args, Dart_Null());
   } else {
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 568fa5f..eb40122 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -670,7 +670,7 @@
   }
 
   auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
-      new IsolateGroupData(nullptr, nullptr, nullptr, nullptr, false));
+      new IsolateGroupData(nullptr, nullptr, nullptr, false));
   Dart_Isolate isolate;
   char* error = NULL;
 
diff --git a/runtime/bin/isolate_data.cc b/runtime/bin/isolate_data.cc
index 3bf497c..1547975 100644
--- a/runtime/bin/isolate_data.cc
+++ b/runtime/bin/isolate_data.cc
@@ -10,21 +10,16 @@
 namespace bin {
 
 IsolateGroupData::IsolateGroupData(const char* url,
-                                   const char* package_root,
                                    const char* packages_file,
                                    AppSnapshot* app_snapshot,
                                    bool isolate_run_app_snapshot)
     : script_url((url != NULL) ? strdup(url) : NULL),
-      package_root(NULL),
       app_snapshot_(app_snapshot),
       resolved_packages_config_(NULL),
       kernel_buffer_(NULL),
       kernel_buffer_size_(0),
       isolate_run_app_snapshot_(isolate_run_app_snapshot) {
-  if (package_root != NULL) {
-    ASSERT(packages_file == NULL);
-    package_root = strdup(package_root);
-  } else if (packages_file != NULL) {
+  if (packages_file != NULL) {
     packages_file_ = strdup(packages_file);
   }
 }
@@ -32,8 +27,6 @@
 IsolateGroupData::~IsolateGroupData() {
   free(script_url);
   script_url = NULL;
-  free(package_root);
-  package_root = NULL;
   free(packages_file_);
   packages_file_ = NULL;
   free(resolved_packages_config_);
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index c4523a1..6dae87a 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -34,14 +34,12 @@
 class IsolateGroupData {
  public:
   IsolateGroupData(const char* url,
-                   const char* package_root,
                    const char* packages_file,
                    AppSnapshot* app_snapshot,
                    bool isolate_run_app_snapshot);
   ~IsolateGroupData();
 
   char* script_url;
-  char* package_root;
 
   const std::shared_ptr<uint8_t>& kernel_buffer() const {
     return kernel_buffer_;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index ac3baa5..06b9109 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -180,7 +180,7 @@
 
   // Prepare builtin and other core libraries for use to resolve URIs.
   // Set up various closures, e.g: printing, timers etc.
-  // Set up 'package root' for URI resolution.
+  // Set up package configuration for URI resolution.
   result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading());
   if (Dart_IsError(result)) return result;
 
@@ -417,7 +417,6 @@
 // For now we only support the kernel isolate coming up from an
 // application snapshot or from a .dill file.
 static Dart_Isolate CreateAndSetupKernelIsolate(const char* script_uri,
-                                                const char* package_root,
                                                 const char* packages_config,
                                                 Dart_IsolateFlags* flags,
                                                 char** error,
@@ -459,9 +458,8 @@
     app_snapshot->SetBuffers(
         &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
         &isolate_snapshot_data, &isolate_snapshot_instructions);
-    isolate_group_data =
-        new IsolateGroupData(uri, package_root, packages_config, app_snapshot,
-                             isolate_run_app_snapshot);
+    isolate_group_data = new IsolateGroupData(
+        uri, packages_config, app_snapshot, isolate_run_app_snapshot);
     isolate_data = new IsolateData(isolate_group_data);
     isolate = Dart_CreateIsolateGroup(
         DART_KERNEL_ISOLATE_NAME, DART_KERNEL_ISOLATE_NAME,
@@ -479,8 +477,8 @@
     intptr_t kernel_service_buffer_size = 0;
     dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
     ASSERT(kernel_service_buffer != NULL);
-    isolate_group_data = new IsolateGroupData(
-        uri, package_root, packages_config, nullptr, isolate_run_app_snapshot);
+    isolate_group_data = new IsolateGroupData(uri, packages_config, nullptr,
+                                              isolate_run_app_snapshot);
     isolate_group_data->SetKernelBufferUnowned(
         const_cast<uint8_t*>(kernel_service_buffer),
         kernel_service_buffer_size);
@@ -508,7 +506,6 @@
 // For now we only support the service isolate coming up from sources
 // which are compiled by the VM parser.
 static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
-                                                 const char* package_root,
                                                  const char* packages_config,
                                                  Dart_IsolateFlags* flags,
                                                  char** error,
@@ -516,8 +513,8 @@
 #if !defined(PRODUCT)
   ASSERT(script_uri != NULL);
   Dart_Isolate isolate = NULL;
-  auto isolate_group_data = new IsolateGroupData(
-      script_uri, package_root, packages_config, nullptr, false);
+  auto isolate_group_data =
+      new IsolateGroupData(script_uri, packages_config, nullptr, false);
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   // AOT: All isolates start from the app snapshot.
@@ -580,7 +577,6 @@
     bool is_main_isolate,
     const char* script_uri,
     const char* name,
-    const char* package_root,
     const char* packages_config,
     Dart_IsolateFlags* flags,
     void* callback_data,
@@ -637,9 +633,8 @@
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-  auto isolate_group_data =
-      new IsolateGroupData(script_uri, package_root, packages_config,
-                           app_snapshot, isolate_run_app_snapshot);
+  auto isolate_group_data = new IsolateGroupData(
+      script_uri, packages_config, app_snapshot, isolate_run_app_snapshot);
   if (kernel_buffer != NULL) {
     if (parent_kernel_buffer) {
       isolate_group_data->SetKernelBufferAlreadyOwned(
@@ -716,28 +711,22 @@
   // The VM should never call the isolate helper with a NULL flags.
   ASSERT(flags != NULL);
   ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
-  if ((package_root != NULL) && (package_config != NULL)) {
-    *error = strdup(
-        "Invalid arguments - Cannot simultaneously specify "
-        "package root and package map.");
-    return NULL;
-  }
-
+  ASSERT(package_root == nullptr);
   int exit_code = 0;
 #if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
   if (strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0) {
-    return CreateAndSetupKernelIsolate(script_uri, package_root, package_config,
-                                       flags, error, &exit_code);
+    return CreateAndSetupKernelIsolate(script_uri, package_config, flags, error,
+                                       &exit_code);
   }
 #endif  // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
   if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
-    return CreateAndSetupServiceIsolate(
-        script_uri, package_root, package_config, flags, error, &exit_code);
+    return CreateAndSetupServiceIsolate(script_uri, package_config, flags,
+                                        error, &exit_code);
   }
   bool is_main_isolate = false;
   return CreateIsolateGroupAndSetupHelper(is_main_isolate, script_uri, main,
-                                          package_root, package_config, flags,
-                                          callback_data, error, &exit_code);
+                                          package_config, flags, callback_data,
+                                          error, &exit_code);
 }
 
 static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
@@ -845,10 +834,15 @@
   Dart_IsolateFlags flags;
   Dart_IsolateFlagsInitialize(&flags);
 
+  if (Options::package_root() != nullptr) {
+    Syslog::PrintErr(
+        "Warning: The --package-root option is deprecated (was: %s)\n",
+        Options::package_root());
+  }
+
   Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
-      is_main_isolate, script_name, "main", Options::package_root(),
-      Options::packages_file(), &flags, NULL /* callback_data */, &error,
-      &exit_code);
+      is_main_isolate, script_name, "main", Options::packages_file(), &flags,
+      NULL /* callback_data */, &error, &exit_code);
 
   if (isolate == NULL) {
     Syslog::PrintErr("%s\n", error);
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 71a9b42..0f04e7d 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -152,7 +152,7 @@
 "      --warn-on-pause-with-no-debugger\n"
 "  This set is subject to change.\n"
 "  Please see these options (--help --verbose) for further documentation.\n"
-"--write-service-info=<file_name>\n"
+"--write-service-info=<file_uri>\n"
 "  Outputs information necessary to connect to the VM service to the\n"
 "  specified file in JSON format. Useful for clients which are unable to\n"
 "  listen to stdout for the Observatory listening message.\n"
@@ -187,7 +187,7 @@
 "      --warn-on-pause-with-no-debugger\n"
 "  This set is subject to change.\n"
 "  Please see these options for further documentation.\n"
-"--write-service-info=<file_name>\n"
+"--write-service-info=<file_uri>\n"
 "  Outputs information necessary to connect to the VM service to the\n"
 "  specified file in JSON format. Useful for clients which are unable to\n"
 "  listen to stdout for the Observatory listening message.\n"
@@ -442,10 +442,11 @@
 
   // Get the script name.
   if (i < argc) {
-    // If the script name isn't a valid file or a URL, this might be a DartDev
-    // command. Try to find the DartDev snapshot so we can forward the command
-    // and its arguments.
-    if (!DartDevUtils::ShouldParseCommand(argv[i])) {
+    if (Options::disable_dart_dev() ||
+        !DartDevUtils::ShouldParseCommand(argv[i])) {
+      // If the script name isn't a valid file or a URL, this might be a DartDev
+      // command. Try to find the DartDev snapshot so we can forward the command
+      // and its arguments.
       *script_name = strdup(argv[i]);
       i++;
     } else if (!DartDevUtils::TryResolveDartDevSnapshotPath(script_name)) {
@@ -454,6 +455,13 @@
           argv[i]);
       Platform::Exit(kErrorExitCode);
     }
+  } else if (!Options::disable_dart_dev() &&
+             ((Options::help_option() && !Options::verbose_option()) ||
+              (argc == 1)) &&
+             DartDevUtils::TryResolveDartDevSnapshotPath(script_name)) {
+    // Let DartDev handle the default help message.
+    dart_options->AddArgument("help");
+    return 0;
   } else {
     return -1;
   }
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 3fe9f74..6493349 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -46,7 +46,8 @@
   V(disable_exit, exit_disabled)                                               \
   V(preview_dart_2, nop_option)                                                \
   V(suppress_core_dump, suppress_core_dump)                                    \
-  V(enable_service_port_fallback, enable_service_port_fallback)
+  V(enable_service_port_fallback, enable_service_port_fallback)                \
+  V(disable_dart_dev, disable_dart_dev)
 
 // Boolean flags that have a short form.
 #define SHORT_BOOL_OPTIONS_LIST(V)                                             \
diff --git a/runtime/bin/process.h b/runtime/bin/process.h
index a1aa3b9..34fc299 100644
--- a/runtime/bin/process.h
+++ b/runtime/bin/process.h
@@ -147,6 +147,7 @@
   // isolate. When 'port' is ILLEGAL_PORT, this clears all signal handlers for
   // 'signal' for all Isolates.
   static void ClearSignalHandler(intptr_t signal, Dart_Port port);
+  static void ClearSignalHandlerByFd(intptr_t fd, Dart_Port port);
   static void ClearAllSignalHandlers();
 
   static Dart_Handle GetProcessIdNativeField(Dart_Handle process,
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index 2a01538..10082b98 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -1063,6 +1063,39 @@
   }
 }
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  bool unlisten = true;
+  intptr_t signal = -1;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        remove = true;
+        signal = handler->signal();
+      } else {
+        unlisten = false;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (unlisten && (signal != -1)) {
+    struct sigaction act = {};
+    act.sa_handler = SIG_DFL;
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+  }
+}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 009560b..8805d09 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -818,6 +818,8 @@
 
 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {}
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 0f4106e..fac361f 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -1015,7 +1015,7 @@
     for (int i = 0; i < kSignalsCount; i++) {
       sigaddset(&act.sa_mask, kSignals[i]);
     }
-    int status = sigaction(signal, &act, NULL);
+    int status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
     if (status < 0) {
       int err = errno;
       close(fds[0]);
@@ -1055,7 +1055,40 @@
   if (unlisten) {
     struct sigaction act = {};
     act.sa_handler = SIG_DFL;
-    sigaction(signal, &act, NULL);
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+  }
+}
+
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  bool unlisten = true;
+  intptr_t signal = -1;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        remove = true;
+        signal = handler->signal();
+      } else {
+        unlisten = false;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (unlisten && (signal != -1)) {
+    struct sigaction act = {};
+    act.sa_handler = SIG_DFL;
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
   }
 }
 
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index df67348..3583a284 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -1095,6 +1095,39 @@
   }
 }
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  bool unlisten = true;
+  intptr_t signal = -1;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        remove = true;
+        signal = handler->signal();
+      } else {
+        unlisten = false;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (unlisten && (signal != -1)) {
+    struct sigaction act = {};
+    act.sa_handler = SIG_DFL;
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+  }
+}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index 5648867..dd11341 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -9,6 +9,7 @@
 
 #include <process.h>  // NOLINT
 #include <psapi.h>    // NOLINT
+#include <vector>
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
@@ -531,14 +532,13 @@
         if (!init_proc_thread_attr_list(attribute_list_, 1, 0, &size)) {
           return CleanupAndReturnError();
         }
-        static const int kNumInheritedHandles = 3;
-        HANDLE inherited_handles[kNumInheritedHandles] = {
-            stdin_handles_[kReadHandle], stdout_handles_[kWriteHandle],
-            stderr_handles_[kWriteHandle]};
+        inherited_handles_ = {stdin_handles_[kReadHandle],
+                              stdout_handles_[kWriteHandle],
+                              stderr_handles_[kWriteHandle]};
         if (!update_proc_thread_attr(
                 attribute_list_, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
-                inherited_handles, kNumInheritedHandles * sizeof(HANDLE), NULL,
-                NULL)) {
+                inherited_handles_.data(),
+                inherited_handles_.size() * sizeof(HANDLE), NULL, NULL)) {
           return CleanupAndReturnError();
         }
         startup_info.lpAttributeList = attribute_list_;
@@ -664,6 +664,7 @@
   const wchar_t* system_working_directory_;
   wchar_t* command_line_;
   wchar_t* environment_block_;
+  std::vector<HANDLE> inherited_handles_;
   LPPROC_THREAD_ATTRIBUTE_LIST attribute_list_;
 
   const char* path_;
@@ -1055,6 +1056,33 @@
   }
 }
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        FileHandle* file_handle = reinterpret_cast<FileHandle*>(handler->fd());
+        file_handle->Release();
+        remove = true;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (signal_handlers == NULL) {
+    USE(SetConsoleCtrlHandler(SignalHandler, false));
+  }
+}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 5e44275..c7b4df6 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -101,7 +101,6 @@
   }
 
 static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
-                                                 const char* package_root,
                                                  const char* packages_config,
                                                  Dart_IsolateFlags* flags,
                                                  char** error) {
@@ -117,7 +116,7 @@
   ASSERT(script_uri != nullptr);
   Dart_Isolate isolate = nullptr;
   auto isolate_group_data = new bin::IsolateGroupData(
-      script_uri, package_root, packages_config, /*app_snapshot=*/nullptr,
+      script_uri, packages_config, /*app_snapshot=*/nullptr,
       /*isolate_run_app_snapshot=*/false);
 
   const uint8_t* kernel_buffer = nullptr;
@@ -169,9 +168,10 @@
                                           void* data,
                                           char** error) {
   ASSERT(script_uri != nullptr);
+  ASSERT(package_root == nullptr);
   if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
-    return CreateAndSetupServiceIsolate(script_uri, package_root,
-                                        packages_config, flags, error);
+    return CreateAndSetupServiceIsolate(script_uri, packages_config, flags,
+                                        error);
   }
   const bool is_kernel_isolate =
       strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0;
@@ -200,9 +200,8 @@
     app_snapshot->SetBuffers(
         &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
         &isolate_snapshot_data, &isolate_snapshot_instructions);
-    isolate_group_data =
-        new bin::IsolateGroupData(script_uri, package_root, packages_config,
-                                  app_snapshot, app_snapshot != nullptr);
+    isolate_group_data = new bin::IsolateGroupData(
+        script_uri, packages_config, app_snapshot, app_snapshot != nullptr);
     isolate = Dart_CreateIsolateGroup(
         DART_KERNEL_ISOLATE_NAME, DART_KERNEL_ISOLATE_NAME,
         isolate_snapshot_data, isolate_snapshot_instructions, flags,
@@ -229,8 +228,8 @@
     bin::dfe.LoadKernelService(&kernel_service_buffer,
                                &kernel_service_buffer_size);
     ASSERT(kernel_service_buffer != nullptr);
-    isolate_group_data = new bin::IsolateGroupData(
-        script_uri, package_root, packages_config, nullptr, false);
+    isolate_group_data =
+        new bin::IsolateGroupData(script_uri, packages_config, nullptr, false);
     isolate_group_data->SetKernelBufferUnowned(
         const_cast<uint8_t*>(kernel_service_buffer),
         kernel_service_buffer_size);
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 46bcef0..1017655 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -1258,7 +1258,7 @@
                                   void* data) {
   Socket* socket = reinterpret_cast<Socket*>(data);
   if (socket->fd() >= 0) {
-    Process::ClearSignalHandler(socket->fd(), socket->isolate_port());
+    Process::ClearSignalHandlerByFd(socket->fd(), socket->isolate_port());
     const int64_t flags = 1 << kCloseCommand;
     socket->Retain();
     EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
diff --git a/runtime/configs.gni b/runtime/configs.gni
index 04d8998..971d242 100644
--- a/runtime/configs.gni
+++ b/runtime/configs.gni
@@ -65,56 +65,67 @@
     suffix = "_jit"
     configs = _jit_config
     snapshot = true
+    compiler = true
   },
   {
     suffix = "_jit_product"
     configs = _jit_product_config
     snapshot = true
+    compiler = true
   },
   {
     suffix = "_precompiled_runtime"
     configs = _precompiled_runtime_config
     snapshot = true
+    compiler = false
   },
   {
     suffix = "_precompiled_runtime_product"
     configs = _precompiled_runtime_product_config
     snapshot = true
+    compiler = false
   },
   {
     suffix = "_precompiler"
     configs = _precompiler_config
     snapshot = false
+    compiler = true
   },
   {
     suffix = "_precompiler_product"
     configs = _precompiler_product_config
     snapshot = false
+    compiler = true
   },
   {
     suffix = "_precompiler_fuchsia"
     configs = _precompiler_fuchsia_config
     snapshot = false
+    compiler = true
   },
   {
     suffix = "_precompiler_product_fuchsia"
     configs = _precompiler_product_fuchsia_config
     snapshot = false
+    compiler = true
   },
   {
     suffix = "_precompiler_host_targeting_host"
     configs = _precompiler_host_targeting_host_config
     snapshot = false
+    compiler = true
   },
   {
     suffix = "_precompiler_product_host_targeting_host"
     configs = _precompiler_product_host_targeting_host_config
     snapshot = false
+    compiler = true
   },
   {
     suffix = "_libfuzzer"
     configs = _libfuzzer_config
     snapshot = true
+    compiler = true
   },
 ]
 
@@ -177,6 +188,13 @@
       foreach(dep, configurable_deps) {
         configured_deps += [ "${dep}${conf.suffix}" ]
       }
+      if (defined(compiler_lib)) {
+        if (conf.compiler) {
+          configured_deps += [ "${compiler_lib}${conf.suffix}" ]
+        } else {
+          not_needed([ "compiler_lib" ])
+        }
+      }
       deps = configured_deps + extra_deps
       if (conf.snapshot) {
         if (defined(snapshot_sources)) {
@@ -190,3 +208,47 @@
     }
   }
 }
+
+template("library_for_all_configs_with_compiler") {
+  assert(defined(invoker.target_type))
+  extra_configs = []
+  if (defined(invoker.extra_configs)) {
+    extra_configs += invoker.extra_configs
+  }
+  configurable_deps = []
+  if (defined(invoker.configurable_deps)) {
+    configurable_deps += invoker.configurable_deps
+  }
+  extra_deps = []
+  if (defined(invoker.extra_deps)) {
+    extra_deps += invoker.extra_deps
+  }
+  foreach(conf, _all_configs) {
+    if (conf.compiler) {
+      target(invoker.target_type, "${target_name}${conf.suffix}") {
+        forward_variables_from(invoker,
+                               "*",
+                               [
+                                 "extra_configs",
+                                 "extra_deps",
+                                 "configurable_deps",
+                               ])
+        configs += conf.configs + extra_configs
+        configured_deps = []
+        foreach(dep, configurable_deps) {
+          configured_deps += [ "${dep}${conf.suffix}" ]
+        }
+        deps = configured_deps + extra_deps
+        if (conf.snapshot) {
+          if (defined(snapshot_sources)) {
+            sources += snapshot_sources
+          }
+        } else {
+          if (defined(snapshot_sources)) {
+            not_needed([ "snapshot_sources" ])
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/runtime/docs/gc.md b/runtime/docs/gc.md
index 70c58ea..8e6d463 100644
--- a/runtime/docs/gc.md
+++ b/runtime/docs/gc.md
@@ -27,6 +27,10 @@
 
 See [Cheney's algorithm](https://en.wikipedia.org/wiki/Cheney's_algorithm).
 
+## 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.
+
 ## Mark-Sweep
 
 All objects have a bit in their header called the mark bit. At the start of a collection cycle, all objects have this bit clear.
@@ -51,6 +55,8 @@
 
 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. 
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index b01cedc..e5ad04f 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -530,7 +530,6 @@
   bool load_vmservice_library;
   bool unsafe_trust_strong_mode_types;
   bool copy_parent_code;
-  bool null_safety;
 } Dart_IsolateFlags;
 
 /**
@@ -571,10 +570,7 @@
  *   eventually run.  This is provided for advisory purposes only to
  *   improve debugging messages.  The main function is not invoked by
  *   this function.
- * \param package_root The package root path for this isolate to resolve
- *   package imports against. Only one of package_root and package_map
- *   parameters is non-NULL. If neither parameter is passed the package
- *   resolution of the parent isolate should be used.
+ * \param package_root Ignored.
  * \param package_map The package map for this isolate to resolve package
  *   imports against. The array contains alternating keys and values,
  *   terminated by a NULL key. Only one of package_root and package_map
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 6370714..471e41b 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -67,7 +67,7 @@
   return Double::New(left / right);
 }
 
-static RawInteger* DoubleToInteger(double val, const char* error_msg) {
+static IntegerPtr DoubleToInteger(double val, const char* error_msg) {
   if (isinf(val) || isnan(val)) {
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, String::Handle(String::New(error_msg)));
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index 2bf8799..8d9fb8d 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -13,7 +13,7 @@
 
 // Scan the stack until we hit the first function in the _AssertionError
 // class. We then return the next frame's script taking inlining into account.
-static RawScript* FindScript(DartFrameIterator* iterator) {
+static ScriptPtr FindScript(DartFrameIterator* iterator) {
 #if defined(DART_PRECOMPILED_RUNTIME)
   // The precompiled runtime faces two issues in recovering the correct
   // assertion text. First, the precompiled runtime does not include
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 47ead67..d4c6c43 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -8,11 +8,7 @@
 #include "vm/bootstrap_natives.h"
 #include "vm/class_finalizer.h"
 #include "vm/class_id.h"
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/ffi/call.h"
-#include "vm/compiler/ffi/callback.h"
 #include "vm/compiler/ffi/native_type.h"
-#include "vm/compiler/jit/compiler.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
 #include "vm/log.h"
@@ -22,6 +18,13 @@
 #include "vm/object_store.h"
 #include "vm/symbols.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/ffi/call.h"
+#include "vm/compiler/ffi/callback.h"
+#include "vm/compiler/jit/compiler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // The following functions are runtime checks on type arguments.
@@ -30,14 +33,13 @@
 // throw ArgumentExceptions.
 
 static bool IsPointerType(const AbstractType& type) {
-  return RawObject::IsFfiPointerClassId(type.type_class_id());
+  return IsFfiPointerClassId(type.type_class_id());
 }
 
 static void CheckSized(const AbstractType& type_arg) {
   const classid_t type_cid = type_arg.type_class_id();
-  if (RawObject::IsFfiNativeTypeTypeClassId(type_cid) ||
-      RawObject::IsFfiTypeVoidClassId(type_cid) ||
-      RawObject::IsFfiTypeNativeFunctionClassId(type_cid)) {
+  if (IsFfiNativeTypeTypeClassId(type_cid) || IsFfiTypeVoidClassId(type_cid) ||
+      IsFfiTypeNativeFunctionClassId(type_cid)) {
     const String& error = String::Handle(String::NewFormatted(
         "%s does not have a predefined size (@unsized). "
         "Unsized NativeTypes do not support [sizeOf] because their size "
@@ -69,12 +71,12 @@
   return Double::Cast(instance);
 }
 
-// Calcuate the size of a native type.
+// Calculate the size of a native type.
 //
 // You must check [IsConcreteNativeType] and [CheckSized] first to verify that
 // this type has a defined size.
 static size_t SizeOf(const AbstractType& type, Zone* zone) {
-  if (RawObject::IsFfiTypeClassId(type.type_class_id())) {
+  if (IsFfiTypeClassId(type.type_class_id())) {
     return compiler::ffi::NativeType::FromAbstractType(type, zone)
         .SizeInBytes();
   } else {
@@ -101,10 +103,10 @@
   return Integer::New(pointer.NativeAddress());
 }
 
-static RawObject* LoadValueNumeric(Zone* zone,
-                                   const Pointer& target,
-                                   classid_t type_cid,
-                                   const Integer& offset) {
+static ObjectPtr LoadValueNumeric(Zone* zone,
+                                  const Pointer& target,
+                                  classid_t type_cid,
+                                  const Integer& offset) {
   // TODO(36370): Make representation consistent with kUnboxedFfiIntPtr.
   const size_t address =
       target.NativeAddress() + static_cast<intptr_t>(offset.AsInt64Value());
@@ -162,9 +164,9 @@
   return Pointer::New(type_arg, *reinterpret_cast<uword*>(address));
 }
 
-static RawObject* LoadValueStruct(Zone* zone,
-                                  const Pointer& target,
-                                  const AbstractType& instance_type_arg) {
+static ObjectPtr LoadValueStruct(Zone* zone,
+                                 const Pointer& target,
+                                 const AbstractType& instance_type_arg) {
   // Result is a struct class -- find <class name>.#fromPointer
   // constructor and call it.
   const Class& cls = Class::Handle(zone, instance_type_arg.type_class());
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 502fe47..ed2c547 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -51,8 +51,8 @@
         const Context& context_a = Context::Handle(zone, receiver.context());
         const Context& context_b =
             Context::Handle(zone, other_closure.context());
-        RawObject* receiver_a = context_a.At(0);
-        RawObject* receiver_b = context_b.At(0);
+        ObjectPtr receiver_a = context_a.At(0);
+        ObjectPtr receiver_b = context_b.At(0);
         if ((receiver_a == receiver_b) &&
             ((func_a.raw() == func_b.raw()) ||
              ((func_a.name() == func_b.name()) &&
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index c66299f..bdf51ec 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -158,7 +158,7 @@
   return Bool::Get(left.CompareWith(right) == 0).raw();
 }
 
-static RawInteger* ParseInteger(const String& value) {
+static IntegerPtr ParseInteger(const String& value) {
   // Used by both Integer_parse and Integer_fromEnvironment.
   if (value.IsOneByteString()) {
     // Quick conversion for unpadded integers in strings.
@@ -202,9 +202,9 @@
   return default_value.raw();
 }
 
-static RawInteger* ShiftOperationHelper(Token::Kind kind,
-                                        const Integer& value,
-                                        const Integer& amount) {
+static IntegerPtr ShiftOperationHelper(Token::Kind kind,
+                                       const Integer& value,
+                                       const Integer& amount) {
   if (amount.AsInt64Value() < 0) {
     Exceptions::ThrowArgumentError(amount);
   }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 465c84f..7833f4a 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -15,6 +15,7 @@
 #include "vm/dart_api_message.h"
 #include "vm/dart_entry.h"
 #include "vm/exceptions.h"
+#include "vm/hash_table.h"
 #include "vm/lockers.h"
 #include "vm/longjump.h"
 #include "vm/message_handler.h"
@@ -108,6 +109,151 @@
   return Object::null();
 }
 
+class ObjectPtrSetTraitsLayout {
+ public:
+  static bool ReportStats() { return false; }
+  static const char* Name() { return "RawObjectPtrSetTraits"; }
+
+  static bool IsMatch(const ObjectPtr a, const ObjectPtr b) { return a == b; }
+
+  static uword Hash(const ObjectPtr obj) { return static_cast<uword>(obj); }
+};
+
+static ObjectPtr ValidateMessageObject(Zone* zone,
+                                       Isolate* isolate,
+                                       const Object& obj) {
+  TIMELINE_DURATION(Thread::Current(), Isolate, "ValidateMessageObject");
+
+  class SendMessageValidator : public ObjectPointerVisitor {
+   public:
+    SendMessageValidator(IsolateGroup* isolate_group,
+                         WeakTable* visited,
+                         MallocGrowableArray<ObjectPtr>* const working_set)
+        : ObjectPointerVisitor(isolate_group),
+          visited_(visited),
+          working_set_(working_set) {}
+
+   private:
+    void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
+      for (ObjectPtr* raw = from; raw <= to; raw++) {
+        if (!(*raw)->IsHeapObject() || (*raw)->ptr()->IsCanonical()) {
+          continue;
+        }
+        if (visited_->GetValueExclusive(*raw) == 1) {
+          continue;
+        }
+        visited_->SetValueExclusive(*raw, 1);
+        working_set_->Add(*raw);
+      }
+    }
+
+    WeakTable* visited_;
+    MallocGrowableArray<ObjectPtr>* const working_set_;
+  };
+  if (!obj.raw()->IsHeapObject() || obj.raw()->ptr()->IsCanonical()) {
+    return obj.raw();
+  }
+  ClassTable* class_table = isolate->class_table();
+
+  Class& klass = Class::Handle(zone);
+  Closure& closure = Closure::Handle(zone);
+
+  MallocGrowableArray<ObjectPtr> working_set;
+  std::unique_ptr<WeakTable> visited(new WeakTable());
+
+  NoSafepointScope no_safepoint;
+  SendMessageValidator visitor(isolate->group(), visited.get(), &working_set);
+
+  visited->SetValueExclusive(obj.raw(), 1);
+  working_set.Add(obj.raw());
+
+  while (!working_set.is_empty()) {
+    ObjectPtr raw = working_set.RemoveLast();
+
+    if (visited->GetValueExclusive(raw) > 0) {
+      continue;
+    }
+    visited->SetValueExclusive(raw, 1);
+
+    const intptr_t cid = raw->GetClassId();
+    switch (cid) {
+      // List below matches the one in raw_object_snapshot.cc
+#define MESSAGE_SNAPSHOT_ILLEGAL(type)                                         \
+  case k##type##Cid:                                                           \
+    return Exceptions::CreateUnhandledException(                               \
+        zone, Exceptions::kArgumentValue,                                      \
+        "Illegal argument in isolate message : (object is a " #type ")");
+
+      MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
+      MESSAGE_SNAPSHOT_ILLEGAL(MirrorReference);
+      MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
+      MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
+      MESSAGE_SNAPSHOT_ILLEGAL(RegExp);
+      MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
+      MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
+
+      case kClosureCid: {
+        closure = Closure::RawCast(raw);
+        FunctionPtr func = closure.function();
+        // We only allow closure of top level methods or static functions in a
+        // class to be sent in isolate messages.
+        if (!Function::IsImplicitStaticClosureFunction(func)) {
+          return Exceptions::CreateUnhandledException(
+              zone, Exceptions::kArgumentValue, "Closures are not allowed");
+        }
+        break;
+      }
+      default:
+        if (cid >= kNumPredefinedCids) {
+          klass = class_table->At(cid);
+          if (klass.num_native_fields() != 0) {
+            return Exceptions::CreateUnhandledException(
+                zone, Exceptions::kArgumentValue,
+                "Objects that extend NativeWrapper are not allowed");
+          }
+        }
+    }
+    raw->ptr()->VisitPointers(&visitor);
+  }
+  isolate->set_forward_table_new(nullptr);
+  return obj.raw();
+}
+
+DEFINE_NATIVE_ENTRY(SendPortImpl_sendAndExitInternal_, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
+  if (!PortMap::IsReceiverInThisIsolateGroup(port.Id(), isolate->group())) {
+    const auto& error =
+        String::Handle(String::New("sendAndExit is only supported across "
+                                   "isolates spawned via spawnFunction."));
+    Exceptions::ThrowArgumentError(error);
+    UNREACHABLE();
+  }
+
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
+
+  Object& validated_result = Object::Handle(zone);
+  Object& msg_obj = Object::Handle(zone, obj.raw());
+  validated_result = ValidateMessageObject(zone, isolate, msg_obj);
+  if (validated_result.IsUnhandledException()) {
+    Exceptions::PropagateError(Error::Cast(validated_result));
+    UNREACHABLE();
+  }
+  PersistentHandle* handle =
+      isolate->group()->api_state()->AllocatePersistentHandle();
+  handle->set_raw(msg_obj);
+  isolate->bequeath(std::unique_ptr<Bequest>(new Bequest(handle, port.Id())));
+  // TODO(aam): Ensure there are no dart api calls after this point as we want
+  // to ensure that validated message won't get tampered with.
+  Isolate::KillIfExists(isolate, Isolate::LibMsgId::kKillMsg);
+  // Drain interrupts before running so any IMMEDIATE operations on the current
+  // isolate happen synchronously.
+  const Error& error = Error::Handle(thread->HandleInterrupts());
+  RELEASE_ASSERT(error.IsUnwindError());
+  Exceptions::PropagateError(error);
+  // We will never execute dart code again in this isolate.
+  return Object::null();
+}
+
 static void ThrowIsolateSpawnException(const String& message) {
   const Array& args = Array::Handle(Array::New(1));
   args.SetAt(0, message);
@@ -167,7 +313,11 @@
         return;
       }
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+      isolate = CreateWithinExistingIsolateGroupAOT(group, name, &error);
+#else
       isolate = CreateWithinExistingIsolateGroup(group, name, &error);
+#endif
       parent_isolate_->DecrementSpawnCount();
       parent_isolate_ = nullptr;
       if (isolate == nullptr) {
@@ -240,7 +390,7 @@
   return result;
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 11) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 10) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2));
@@ -249,9 +399,8 @@
   GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5));
   GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6));
   GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7));
-  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(8));
-  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(9));
-  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(10));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8));
+  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(9));
 
   if (closure.IsClosure()) {
     Function& func = Function::Handle();
@@ -332,26 +481,19 @@
   return result;
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 13) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 12) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
-
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
-
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
   GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
   GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
-
   GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7));
   GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8));
-
   GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
-
-  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
-  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
-
-  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(12));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(10));
+  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(11));
 
   if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) {
     const Array& args = Array::Handle(Array::New(1));
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index b4a5bfd..b1e7513 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -74,7 +74,7 @@
 }
 
 // Returns the typed-data array store in '_Random._state' field.
-static RawTypedData* GetRandomStateArray(const Instance& receiver) {
+static TypedDataPtr GetRandomStateArray(const Instance& receiver) {
   const Class& random_class = Class::Handle(receiver.clazz());
   const Field& state_field =
       Field::Handle(random_class.LookupFieldAllowPrivate(Symbols::_state()));
@@ -107,7 +107,7 @@
   return Object::null();
 }
 
-RawTypedData* CreateRandomState(Zone* zone, uint64_t seed) {
+TypedDataPtr CreateRandomState(Zone* zone, uint64_t seed) {
   const TypedData& result =
       TypedData::Handle(zone, TypedData::New(kTypedDataUint32ArrayCid, 2));
   result.SetUint32(0, static_cast<uint32_t>(seed));
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index e931966..b8a123e 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -21,14 +21,14 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
 #define RETURN_OR_PROPAGATE(expr)                                              \
-  RawObject* result = expr;                                                    \
-  if (RawObject::IsErrorClassId(result->GetClassIdMayBeSmi())) {               \
+  ObjectPtr result = expr;                                                     \
+  if (IsErrorClassId(result->GetClassIdMayBeSmi())) {                          \
     Exceptions::PropagateError(Error::Handle(Error::RawCast(result)));         \
   }                                                                            \
   return result;
 
-static RawInstance* CreateMirror(const String& mirror_class_name,
-                                 const Array& constructor_arguments) {
+static InstancePtr CreateMirror(const String& mirror_class_name,
+                                const Array& constructor_arguments) {
   const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary());
   const String& constructor_name = Symbols::DotUnder();
 
@@ -90,8 +90,8 @@
   func.EnsureHasCode();
 }
 
-static RawInstance* CreateParameterMirrorList(const Function& func,
-                                              const Instance& owner_mirror) {
+static InstancePtr CreateParameterMirrorList(const Function& func,
+                                             const Instance& owner_mirror) {
   HANDLESCOPE(Thread::Current());
   const intptr_t implicit_param_count = func.NumImplicitParameters();
   const intptr_t non_implicit_param_count =
@@ -184,8 +184,8 @@
   return results.raw();
 }
 
-static RawInstance* CreateTypeVariableMirror(const TypeParameter& param,
-                                             const Instance& owner_mirror) {
+static InstancePtr CreateTypeVariableMirror(const TypeParameter& param,
+                                            const Instance& owner_mirror) {
   const Array& args = Array::Handle(Array::New(3));
   args.SetAt(0, param);
   args.SetAt(1, String::Handle(param.name()));
@@ -195,7 +195,7 @@
 
 // We create a list in native code and let Dart code create the type mirror
 // object and the ordered map.
-static RawInstance* CreateTypeVariableList(const Class& cls) {
+static InstancePtr CreateTypeVariableList(const Class& cls) {
   const TypeArguments& args = TypeArguments::Handle(cls.type_parameters());
   if (args.IsNull()) {
     return Object::empty_array().raw();
@@ -214,10 +214,10 @@
   return result.raw();
 }
 
-static RawInstance* CreateTypedefMirror(const Class& cls,
-                                        const AbstractType& type,
-                                        const Bool& is_declaration,
-                                        const Instance& owner_mirror) {
+static InstancePtr CreateTypedefMirror(const Class& cls,
+                                       const AbstractType& type,
+                                       const Bool& is_declaration,
+                                       const Instance& owner_mirror) {
   const Array& args = Array::Handle(Array::New(6));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
   args.SetAt(1, type);
@@ -228,7 +228,7 @@
   return CreateMirror(Symbols::_TypedefMirror(), args);
 }
 
-static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) {
+static InstancePtr CreateFunctionTypeMirror(const AbstractType& type) {
   ASSERT(type.IsFunctionType());
   const Class& cls = Class::Handle(Type::Cast(type).type_class());
   const Function& func = Function::Handle(Type::Cast(type).signature());
@@ -239,9 +239,9 @@
   return CreateMirror(Symbols::_FunctionTypeMirror(), args);
 }
 
-static RawInstance* CreateMethodMirror(const Function& func,
-                                       const Instance& owner_mirror,
-                                       const AbstractType& instantiator) {
+static InstancePtr CreateMethodMirror(const Function& func,
+                                      const Instance& owner_mirror,
+                                      const AbstractType& instantiator) {
   const Array& args = Array::Handle(Array::New(6));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func)));
 
@@ -259,7 +259,7 @@
       (static_cast<intptr_t>(func.IsGetterFunction()) << Mirrors::kGetter);
   kind_flags |=
       (static_cast<intptr_t>(func.IsSetterFunction()) << Mirrors::kSetter);
-  bool is_ctor = (func.kind() == RawFunction::kConstructor);
+  bool is_ctor = (func.kind() == FunctionLayout::kConstructor);
   kind_flags |= (static_cast<intptr_t>(is_ctor) << Mirrors::kConstructor);
   kind_flags |= (static_cast<intptr_t>(is_ctor && func.is_const())
                  << Mirrors::kConstCtor);
@@ -281,8 +281,8 @@
   return CreateMirror(Symbols::_MethodMirror(), args);
 }
 
-static RawInstance* CreateVariableMirror(const Field& field,
-                                         const Instance& owner_mirror) {
+static InstancePtr CreateVariableMirror(const Field& field,
+                                        const Instance& owner_mirror) {
   const MirrorReference& field_ref =
       MirrorReference::Handle(MirrorReference::New(field));
 
@@ -301,10 +301,10 @@
   return CreateMirror(Symbols::_VariableMirror(), args);
 }
 
-static RawInstance* CreateClassMirror(const Class& cls,
-                                      const AbstractType& type,
-                                      const Bool& is_declaration,
-                                      const Instance& owner_mirror) {
+static InstancePtr CreateClassMirror(const Class& cls,
+                                     const AbstractType& type,
+                                     const Bool& is_declaration,
+                                     const Instance& owner_mirror) {
   if (type.IsTypeRef()) {
     AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
     ASSERT(!ref_type.IsTypeRef());
@@ -351,7 +351,7 @@
   return false;
 }
 
-static RawInstance* CreateLibraryMirror(Thread* thread, const Library& lib) {
+static InstancePtr CreateLibraryMirror(Thread* thread, const Library& lib) {
   Zone* zone = thread->zone();
   ASSERT(!lib.IsNull());
   const Array& args = Array::Handle(zone, Array::New(3));
@@ -368,24 +368,24 @@
   return CreateMirror(Symbols::_LibraryMirror(), args);
 }
 
-static RawInstance* CreateCombinatorMirror(const Object& identifiers,
-                                           bool is_show) {
+static InstancePtr CreateCombinatorMirror(const Object& identifiers,
+                                          bool is_show) {
   const Array& args = Array::Handle(Array::New(2));
   args.SetAt(0, identifiers);
   args.SetAt(1, Bool::Get(is_show));
   return CreateMirror(Symbols::_CombinatorMirror(), args);
 }
 
-static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
-                                                  const Instance& importer,
-                                                  const Library& importee,
-                                                  const Array& show_names,
-                                                  const Array& hide_names,
-                                                  const Object& metadata,
-                                                  const LibraryPrefix& prefix,
-                                                  const String& prefix_name,
-                                                  const bool is_import,
-                                                  const bool is_deferred) {
+static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
+                                                 const Instance& importer,
+                                                 const Library& importee,
+                                                 const Array& show_names,
+                                                 const Array& hide_names,
+                                                 const Object& metadata,
+                                                 const LibraryPrefix& prefix,
+                                                 const String& prefix_name,
+                                                 const bool is_import,
+                                                 const bool is_deferred) {
   const Instance& importee_mirror =
       Instance::Handle(CreateLibraryMirror(thread, importee));
   if (importee_mirror.IsNull()) {
@@ -427,12 +427,12 @@
   return CreateMirror(Symbols::_LibraryDependencyMirror(), args);
 }
 
-static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
-                                                  const Instance& importer,
-                                                  const Namespace& ns,
-                                                  const LibraryPrefix& prefix,
-                                                  const bool is_import,
-                                                  const bool is_deferred) {
+static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
+                                                 const Instance& importer,
+                                                 const Namespace& ns,
+                                                 const LibraryPrefix& prefix,
+                                                 const bool is_import,
+                                                 const bool is_deferred) {
   const Library& importee = Library::Handle(ns.library());
   const Array& show_names = Array::Handle(ns.show_names());
   const Array& hide_names = Array::Handle(ns.hide_names());
@@ -453,7 +453,7 @@
                                        prefix_name, is_import, is_deferred);
 }
 
-static RawGrowableObjectArray* CreateBytecodeLibraryDependencies(
+static GrowableObjectArrayPtr CreateBytecodeLibraryDependencies(
     Thread* thread,
     const Library& lib,
     const Instance& lib_mirror) {
@@ -597,7 +597,7 @@
   return deps.raw();
 }
 
-static RawInstance* CreateTypeMirror(const AbstractType& type) {
+static InstancePtr CreateTypeMirror(const AbstractType& type) {
   if (type.IsTypeRef()) {
     AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
     ASSERT(!ref_type.IsTypeRef());
@@ -652,7 +652,7 @@
   return Instance::null();
 }
 
-static RawInstance* CreateIsolateMirror() {
+static InstancePtr CreateIsolateMirror() {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   const String& debug_name = String::Handle(String::New(isolate->name()));
@@ -697,8 +697,8 @@
 #endif
 }
 
-static RawAbstractType* InstantiateType(const AbstractType& type,
-                                        const AbstractType& instantiator) {
+static AbstractTypePtr InstantiateType(const AbstractType& type,
+                                       const AbstractType& instantiator) {
   // Generic function type parameters are not reified, but mapped to dynamic,
   // i.e. all function type parameters are free with a null vector.
   ASSERT(type.IsFinalized());
@@ -1112,9 +1112,9 @@
   for (intptr_t i = 0; i < num_functions; i++) {
     func ^= functions.At(i);
     if (func.is_reflectable() &&
-        (func.kind() == RawFunction::kRegularFunction ||
-         func.kind() == RawFunction::kGetterFunction ||
-         func.kind() == RawFunction::kSetterFunction)) {
+        (func.kind() == FunctionLayout::kRegularFunction ||
+         func.kind() == FunctionLayout::kGetterFunction ||
+         func.kind() == FunctionLayout::kSetterFunction)) {
       member_mirror =
           CreateMethodMirror(func, owner_mirror, owner_instantiator);
       member_mirrors.Add(member_mirror);
@@ -1147,7 +1147,7 @@
   Function& func = Function::Handle();
   for (intptr_t i = 0; i < num_functions; i++) {
     func ^= functions.At(i);
-    if (func.is_reflectable() && func.kind() == RawFunction::kConstructor) {
+    if (func.is_reflectable() && func.kind() == FunctionLayout::kConstructor) {
       constructor_mirror =
           CreateMethodMirror(func, owner_mirror, owner_instantiator);
       constructor_mirrors.Add(constructor_mirror);
@@ -1200,9 +1200,9 @@
     } else if (entry.IsFunction()) {
       const Function& func = Function::Cast(entry);
       if (func.is_reflectable() &&
-          (func.kind() == RawFunction::kRegularFunction ||
-           func.kind() == RawFunction::kGetterFunction ||
-           func.kind() == RawFunction::kSetterFunction)) {
+          (func.kind() == FunctionLayout::kRegularFunction ||
+           func.kind() == FunctionLayout::kGetterFunction ||
+           func.kind() == FunctionLayout::kSetterFunction)) {
         member_mirror =
             CreateMethodMirror(func, owner_mirror, AbstractType::Handle());
         member_mirrors.Add(member_mirror);
@@ -1443,7 +1443,7 @@
       Function::Handle(klass.LookupFunction(internal_constructor_name));
 
   if (lookup_constructor.IsNull() ||
-      (lookup_constructor.kind() != RawFunction::kConstructor) ||
+      (lookup_constructor.kind() != FunctionLayout::kConstructor) ||
       !lookup_constructor.is_reflectable()) {
     ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
                       external_constructor_name, explicit_args, arg_names,
@@ -1640,9 +1640,9 @@
   return func.GetSource();
 }
 
-static RawInstance* CreateSourceLocation(const String& uri,
-                                         intptr_t line,
-                                         intptr_t column) {
+static InstancePtr CreateSourceLocation(const String& uri,
+                                        intptr_t line,
+                                        intptr_t column) {
   const Array& args = Array::Handle(Array::New(3));
   args.SetAt(0, uri);
   args.SetAt(1, Smi::Handle(Smi::New(line)));
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index a41c8fa..bc22233 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -93,10 +93,10 @@
   const intptr_t right_cid = right.GetClassId();
 
   if (left_cid != right_cid) {
-    if (RawObject::IsIntegerClassId(left_cid)) {
-      return Bool::Get(RawObject::IsIntegerClassId(right_cid)).raw();
-    } else if (RawObject::IsStringClassId(right_cid)) {
-      return Bool::Get(RawObject::IsStringClassId(right_cid)).raw();
+    if (IsIntegerClassId(left_cid)) {
+      return Bool::Get(IsIntegerClassId(right_cid)).raw();
+    } else if (IsStringClassId(right_cid)) {
+      return Bool::Get(IsStringClassId(right_cid)).raw();
     } else {
       return Bool::False().raw();
     }
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index eb4237c..57aa72a 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -8,10 +8,13 @@
 #include "vm/native_entry.h"
 #include "vm/object.h"
 #include "vm/regexp_assembler_bytecode.h"
-#include "vm/regexp_assembler_ir.h"
 #include "vm/regexp_parser.h"
 #include "vm/thread.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/regexp_assembler_ir.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DEFINE_NATIVE_ENTRY(RegExp_factory, 0, 6) {
@@ -110,9 +113,9 @@
   return Object::null();
 }
 
-static RawObject* ExecuteMatch(Zone* zone,
-                               NativeArguments* arguments,
-                               bool sticky) {
+static ObjectPtr ExecuteMatch(Zone* zone,
+                              NativeArguments* arguments,
+                              bool sticky) {
   const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(String, subject, arguments->NativeArgAt(1));
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index dfe1f585..c2d8657 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -18,8 +18,8 @@
 
 static const intptr_t kDefaultStackAllocation = 8;
 
-static RawStackTrace* CurrentSyncStackTraceLazy(Thread* thread,
-                                                intptr_t skip_frames = 1) {
+static StackTracePtr CurrentSyncStackTraceLazy(Thread* thread,
+                                               intptr_t skip_frames = 1) {
   Zone* zone = thread->zone();
 
   const auto& code_array = GrowableObjectArray::ZoneHandle(
@@ -39,8 +39,8 @@
   return StackTrace::New(code_array_fixed, pc_offset_array_fixed);
 }
 
-static RawStackTrace* CurrentSyncStackTrace(Thread* thread,
-                                            intptr_t skip_frames = 1) {
+static StackTracePtr CurrentSyncStackTrace(Thread* thread,
+                                           intptr_t skip_frames = 1) {
   Zone* zone = thread->zone();
   const Function& null_function = Function::ZoneHandle(zone);
 
@@ -63,7 +63,7 @@
   return StackTrace::New(code_array, pc_offset_array);
 }
 
-static RawStackTrace* CurrentStackTrace(
+static StackTracePtr CurrentStackTrace(
     Thread* thread,
     bool for_async_function,
     intptr_t skip_frames = 1,
@@ -128,7 +128,7 @@
   return result.raw();
 }
 
-RawStackTrace* GetStackTraceForException() {
+StackTracePtr GetStackTraceForException() {
   Thread* thread = Thread::Current();
   return CurrentStackTrace(thread, false, 0);
 }
diff --git a/runtime/lib/stacktrace.h b/runtime/lib/stacktrace.h
index c482070..9c8abae 100644
--- a/runtime/lib/stacktrace.h
+++ b/runtime/lib/stacktrace.h
@@ -5,10 +5,11 @@
 #ifndef RUNTIME_LIB_STACKTRACE_H_
 #define RUNTIME_LIB_STACKTRACE_H_
 
+#include "vm/tagged_pointer.h"
+
 namespace dart {
 
 class StackTrace;
-class RawStackTrace;
 
 // Creates a StackTrace object from the current stack.  Skips the
 // first skip_frames Dart frames.
@@ -18,7 +19,7 @@
 const StackTrace& GetCurrentStackTrace(int skip_frames);
 
 // Creates a StackTrace object to be attached to an exception.
-RawStackTrace* GetStackTraceForException();
+StackTracePtr GetStackTraceForException();
 
 }  // namespace dart
 
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 947ba4f..71ae8a6 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -362,8 +362,7 @@
     }
     String& string = String::Handle(OneByteString::New(length, space));
     for (int i = 0; i < length; i++) {
-      intptr_t value =
-          Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+      intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
       OneByteString::SetCharAt(string, i, value);
     }
     return string.raw();
@@ -376,8 +375,7 @@
     }
     String& string = String::Handle(OneByteString::New(length, space));
     for (int i = 0; i < length; i++) {
-      intptr_t value =
-          Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+      intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
       OneByteString::SetCharAt(string, i, value);
     }
     return string.raw();
@@ -430,7 +428,7 @@
       Exceptions::ThrowArgumentError(end_obj);
     }
     return TwoByteString::New(array, start * sizeof(uint16_t), length, space);
-  } else if (RawObject::IsTypedDataViewClassId(list.GetClassId())) {
+  } else if (IsTypedDataViewClassId(list.GetClassId())) {
     const auto& view = TypedDataView::Cast(list);
     const intptr_t cid = list.GetClassId();
     if (cid != kTypedDataUint16ArrayViewCid) {
@@ -458,8 +456,7 @@
     const String& string =
         String::Handle(zone, TwoByteString::New(length, space));
     for (int i = 0; i < length; i++) {
-      intptr_t value =
-          Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+      intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
       TwoByteString::SetCharAt(string, i, value);
     }
     return string.raw();
@@ -471,8 +468,7 @@
     const String& string =
         String::Handle(zone, TwoByteString::New(length, space));
     for (int i = 0; i < length; i++) {
-      intptr_t value =
-          Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+      intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
       TwoByteString::SetCharAt(string, i, value);
     }
     return string.raw();
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 4980516..2e3cf1c 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -85,12 +85,12 @@
 }
 
 template <typename DstType, typename SrcType>
-static RawBool* CopyData(const Instance& dst,
-                         const Instance& src,
-                         const Smi& dst_start,
-                         const Smi& src_start,
-                         const Smi& length,
-                         bool clamped) {
+static BoolPtr CopyData(const Instance& dst,
+                        const Instance& src,
+                        const Smi& dst_start,
+                        const Smi& src_start,
+                        const Smi& length,
+                        bool clamped) {
   const DstType& dst_array = DstType::Cast(dst);
   const SrcType& src_array = SrcType::Cast(src);
   const intptr_t dst_offset_in_bytes = dst_start.Value();
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 1d3484d..95e16c4 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -415,38 +415,4 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 0, 2) {
-#ifndef PRODUCT
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, result, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, token, arguments->NativeArgAt(1));
-
-  if (result.IsSendPort()) {
-    Dart_Port id = SendPort::Cast(result).Id();
-    Isolate* isolate = PortMap::GetIsolate(id);
-    if (isolate != NULL) {
-      ServiceEvent spawn_event(isolate, ServiceEvent::kIsolateSpawn);
-      spawn_event.set_spawn_token(&token);
-      Service::HandleEvent(&spawn_event);
-    } else {
-      // There is no isolate at the control port anymore.  Must have
-      // died already.
-      ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn);
-      const String& error = String::Handle(
-          String::New("spawned isolate exited before notification completed"));
-      spawn_event.set_spawn_token(&token);
-      spawn_event.set_spawn_error(&error);
-      Service::HandleEvent(&spawn_event);
-    }
-  } else {
-    // The isolate failed to spawn.
-    ASSERT(result.IsString());
-    ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn);
-    spawn_event.set_spawn_token(&token);
-    spawn_event.set_spawn_error(&String::Cast(result));
-    Service::HandleEvent(&spawn_event);
-  }
-#endif  // PRODUCT
-  return Object::null();
-}
-
 }  // namespace dart
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
index eca0ff7..639c72a 100644
--- a/runtime/lib/wasm.cc
+++ b/runtime/lib/wasm.cc
@@ -133,7 +133,7 @@
   }
 }
 
-static RawObject* ToDartObject(wasmer_value_t ret) {
+static ObjectPtr ToDartObject(wasmer_value_t ret) {
   switch (ret.tag) {
     case wasmer_value_tag::WASM_I32:
       return Integer::New(ret.value.I32);
@@ -165,7 +165,7 @@
   }
 }
 
-RawExternalTypedData* WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
+ExternalTypedDataPtr WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
   uint8_t* data = wasmer_memory_data(memory);
   uint32_t size = wasmer_memory_data_length(memory);
   return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, size);
@@ -191,7 +191,7 @@
   }
 }
 
-RawString* DescribeModule(const wasmer_module_t* module) {
+StringPtr DescribeModule(const wasmer_module_t* module) {
   std::stringstream desc;
 
   desc << "Imports:\n";
diff --git a/runtime/observatory/.packages b/runtime/observatory/.packages
deleted file mode 100644
index 29f9ce2..0000000
--- a/runtime/observatory/.packages
+++ /dev/null
@@ -1,37 +0,0 @@
-browser:../../third_party/observatory_pub_packages/packages/browser/lib
-charted:../../third_party/observatory_pub_packages/packages/charted/lib
-collection:../../third_party/observatory_pub_packages/packages/collection/lib
-intl:../../third_party/observatory_pub_packages/packages/intl/lib
-logging:../../third_party/observatory_pub_packages/packages/logging/lib
-meta:../../third_party/observatory_pub_packages/packages/meta/lib
-observable:../../third_party/observatory_pub_packages/packages/observable/lib
-path:../../third_party/observatory_pub_packages/packages/path/lib
-quiver:../../third_party/observatory_pub_packages/packages/quiver/lib
-stack_trace:../../third_party/observatory_pub_packages/packages/stack_trace/lib
-usage:../../third_party/observatory_pub_packages/packages/usage/lib
-observatory:lib
-
-# Testing only
-async:../../third_party/pkg/async/lib
-boolean_selector:../../third_party/pkg/boolean_selector/lib
-charcode:../../third_party/pkg/charcode/lib
-dart_internal:../../pkg/dart_internal/lib
-expect:../../pkg/expect/lib
-http:../../third_party/pkg/http/lib
-http_parser:../../third_party/pkg/http_parser/lib
-matcher:../../third_party/pkg/matcher/lib
-package_config:../../third_party/pkg_tested/package_config/lib
-pedantic:../../third_party/pkg/pedantic/lib
-pool:../../third_party/pkg/pool/lib
-pub_semver:../../third_party/pkg/pub_semver/lib
-source_map_stack_trace:../../third_party/pkg/source_map_stack_trace/lib
-source_maps:../../third_party/pkg/source_maps/lib
-source_span:../../third_party/pkg/source_span/lib
-stream_channel:../../third_party/pkg/stream_channel/lib
-string_scanner:../../third_party/pkg/string_scanner/lib
-term_glyph:../../third_party/pkg/term_glyph/lib
-test:../../third_party/pkg/test/pkgs/test/lib
-test_api:../../third_party/pkg/test/pkgs/test_api/lib
-test_core:../../third_party/pkg/test/pkgs/test_core/lib
-typed_data:../../third_party/pkg/typed_data/lib
-observatory_test_package:tests/service/observatory_test_package
diff --git a/runtime/observatory/BUILD.gn b/runtime/observatory/BUILD.gn
index b47dce6..1762e1a 100644
--- a/runtime/observatory/BUILD.gn
+++ b/runtime/observatory/BUILD.gn
@@ -13,7 +13,7 @@
 
   # dart2js produces a .deps file, but it is not in a format that is understood
   # by ninja, so we explicitly list all the sources here.
-  inputs = [ ".packages" ] + observatory_sources
+  inputs = [ "../../.packages" ] + observatory_sources
 
   output = "$target_gen_dir/observatory/web/main.dart.js"
   outputs = [ output ]
@@ -36,7 +36,7 @@
     "-DOBS_VER=${version_string}",
     "-o",
     rebase_path(output),
-    "--packages=" + rebase_path(".packages"),
+    "--packages=" + rebase_path("../../.packages"),
   ]
   if (is_debug) {
     args += [ "--enable-asserts" ]
@@ -113,42 +113,6 @@
   },
 ]
 
-# All the contents of third_party/observatory_pub_packages should be
-# accounted for here. Uncommented entries are those packages that have
-# files that pass the observatory_ignore_patterns filters.
-observatory_pub_packages = [
-  "browser",
-  "charted",
-  "intl",
-
-  # Dependent packages that have no files that pass the above filter.
-  # "collection",
-  # "logging",
-  # "matcher",
-  # "meta",
-  # "observable",
-  # "path",
-  # "quiver",
-  # "stack_trace",
-  # "usage",
-
-  # Only needed for testing.
-  # "unittest",
-]
-
-foreach(package, observatory_pub_packages) {
-  copy_tree_specs += [
-    {
-      target = "copy_${package}_package"
-      visibility = [ ":deploy_observatory" ]
-      source =
-          "../../third_party/observatory_pub_packages/packages/$package/lib"
-      dest = "$target_out_dir/observatory/deployed/web/packages/$package"
-      ignore_patterns = observatory_ignore_string
-    },
-  ]
-}
-
 # This is not a rule, rather, it generates rules with names of the form:
 #   "copy_$package_package" for the packages in observatory_pub_packages.
 copy_trees("copy_observatory_packages") {
@@ -167,9 +131,6 @@
 
 group("deploy_observatory") {
   deps = [
-    ":copy_browser_package",
-    ":copy_charted_package",
-    ":copy_intl_package",
     ":copy_main_dart_js",
     ":copy_observatory_package",
     ":copy_web_package",
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index 66ff984..f074891 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -131,7 +131,7 @@
     _notifyDisconnect(reason);
   }
 
-  Future<Map> invokeRpcRaw(String method, Map params) {
+  Future<Map> invokeRpcRaw(String method, Map params) async {
     if (!_hasInitiatedConnect) {
       _hasInitiatedConnect = true;
       try {
@@ -145,7 +145,7 @@
     }
     if (_disconnected.isCompleted) {
       // This connection was closed already.
-      var exception = new NetworkRpcException('WebSocket closed');
+      var exception = new NetworkRpcException(await onDisconnect);
       return new Future.error(exception);
     }
     String serial = (_requestSerial++).toString();
@@ -318,8 +318,12 @@
         'params': {'id': serial, 'query': request.method}
       });
     } else {
-      message = json.encode(
-          {'id': serial, 'method': request.method, 'params': request.params});
+      message = json.encode({
+        'jsonrpc': '2.0',
+        'id': serial,
+        'method': request.method,
+        'params': request.params
+      });
     }
     if (request.method != 'getTagProfile' &&
         request.method != 'getIsolateMetric' &&
diff --git a/runtime/observatory/lib/src/elements/allocation_profile.dart b/runtime/observatory/lib/src/elements/allocation_profile.dart
index d589289..7770d15 100644
--- a/runtime/observatory/lib/src/elements/allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/allocation_profile.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 import 'dart:html';
-import 'package:charted/charted.dart';
-import "package:charted/charts/charts.dart";
 import 'package:observatory/models.dart' as M;
 import 'package:observatory/src/elements/class_ref.dart';
 import 'package:observatory/src/elements/containers/virtual_collection.dart';
@@ -159,12 +157,6 @@
           ..children = <Element>[new HeadingElement.h2()..text = 'Loading...']
       ]);
     } else {
-      final newChartHost = new DivElement()..classes = ['host'];
-      final newChartLegend = new DivElement()..classes = ['legend'];
-      final oldChartHost = new DivElement()..classes = ['host'];
-      final oldChartLegend = new DivElement()..classes = ['legend'];
-      final totalChartHost = new DivElement()..classes = ['host'];
-      final totalChartLegend = new DivElement()..classes = ['legend'];
       children.addAll([
         new DivElement()
           ..classes = ['content-centered-big']
@@ -206,10 +198,6 @@
                       new DivElement()
                         ..classes = ['memberList']
                         ..children = _createSpaceMembers(_profile.newSpace),
-                      new BRElement(),
-                      new DivElement()
-                        ..classes = ['chart']
-                        ..children = <Element>[newChartLegend, newChartHost]
                     ],
             new DivElement()
               ..classes = ['heap-space', 'left']
@@ -225,10 +213,6 @@
                       new DivElement()
                         ..classes = ['memberList']
                         ..children = _createSpaceMembers(_profile.oldSpace),
-                      new BRElement(),
-                      new DivElement()
-                        ..classes = ['chart']
-                        ..children = <Element>[oldChartLegend, oldChartHost]
                     ],
             new DivElement()
               ..classes = ['heap-space', 'left']
@@ -244,10 +228,6 @@
                       new DivElement()
                         ..classes = ['memberList']
                         ..children = _createSpaceMembers(_profile.totalSpace),
-                      new BRElement(),
-                      new DivElement()
-                        ..classes = ['chart']
-                        ..children = <Element>[totalChartLegend, totalChartHost]
                     ],
             new ButtonElement()
               ..classes = ['compact']
@@ -270,9 +250,6 @@
                 .element
           ]
       ]);
-      _renderGraph(newChartHost, newChartLegend, _profile.newSpace);
-      _renderGraph(oldChartHost, oldChartLegend, _profile.oldSpace);
-      _renderGraph(totalChartHost, totalChartLegend, _profile.totalSpace);
     }
   }
 
@@ -544,31 +521,6 @@
     ];
   }
 
-  static final _columns = [
-    new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING),
-    new ChartColumnSpec(label: 'Size', formatter: (v) => v.toString())
-  ];
-
-  static void _renderGraph(Element host, Element legend, M.HeapSpace space) {
-    final series = [
-      new ChartSeries("Work", [1], new PieChartRenderer(sortDataByValue: false))
-    ];
-    final rect = host.getBoundingClientRect();
-    final minSize = new Rect.size(rect.width, rect.height);
-    final config = new ChartConfig(series, [0])
-      ..minimumSize = minSize
-      ..legend = new ChartLegend(legend, showValues: true);
-    final data = new ChartData(_columns, <List>[
-      ['Used', space.used],
-      ['Free', space.capacity - space.used],
-      ['External', space.external]
-    ]);
-
-    new LayoutArea(host, data, config,
-        state: new ChartState(), autoUpdate: true)
-      ..draw();
-  }
-
   Future _refresh({bool gc: false, bool reset: false}) async {
     _profile = null;
     _r.dirty();
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 83c3182..30c51f8 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -29,7 +29,7 @@
     VirtualTreeElement.tag
   ]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<ClassTreeElement> _r;
 
   Stream<RenderedEvent<ClassTreeElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index 255ea65..f8c0756 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -479,11 +479,7 @@
 }
 
 .allocation-profile .collection {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  top: 560px;
+  height: 100%;
 }
 
 .allocation-profile .collection.expanded {
@@ -1535,7 +1531,7 @@
 }
 
 .isolate-shared-summary > .summary {
-  height: 300px;
+  height: 350px;
   position: relative;
 }
 .isolate-shared-summary .menu {
diff --git a/runtime/observatory/lib/src/elements/error_view.dart b/runtime/observatory/lib/src/elements/error_view.dart
index 010f4cc..71114f4 100644
--- a/runtime/observatory/lib/src/elements/error_view.dart
+++ b/runtime/observatory/lib/src/elements/error_view.dart
@@ -22,7 +22,7 @@
         ViewFooterElement.tag
       ]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<ErrorViewElement> _r;
 
   Stream<RenderedEvent<ErrorViewElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/flag_list.dart b/runtime/observatory/lib/src/elements/flag_list.dart
index 7aa02fd..0d0e090 100644
--- a/runtime/observatory/lib/src/elements/flag_list.dart
+++ b/runtime/observatory/lib/src/elements/flag_list.dart
@@ -28,7 +28,7 @@
     ViewFooterElement.tag,
   ]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<FlagListElement> _r;
 
   Stream<RenderedEvent<FlagListElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/general_error.dart b/runtime/observatory/lib/src/elements/general_error.dart
index f94872b..bc07f6a 100644
--- a/runtime/observatory/lib/src/elements/general_error.dart
+++ b/runtime/observatory/lib/src/elements/general_error.dart
@@ -17,7 +17,7 @@
   static const tag = const Tag<GeneralErrorElement>('general-error',
       dependencies: const [NavTopMenuElement.tag, NavNotifyElement.tag]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<GeneralErrorElement> _r;
 
   Stream<RenderedEvent<GeneralErrorElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
index 8cdd325..3c68990 100644
--- a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
+++ b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
@@ -4,8 +4,6 @@
 
 import 'dart:html';
 import 'dart:async';
-import 'package:charted/charted.dart';
-import "package:charted/charts/charts.dart";
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
@@ -46,34 +44,25 @@
     _subscription.cancel();
   }
 
-  static final _columns = [
-    new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING),
-    new ChartColumnSpec(label: 'Percent', formatter: (v) => v.toString())
-  ];
-
   void render() {
-    final _series = [
-      new ChartSeries(
-          "Work", const [1], new PieChartRenderer(sortDataByValue: false))
-    ];
-    final areaHost = new DivElement()..classes = ['host'];
-    final legendHost = new DivElement()..classes = ['legend'];
-    children = <Element>[areaHost, legendHost];
-    final rect = areaHost.getBoundingClientRect();
-    final minSize = new Rect.size(rect.width, rect.height);
-    final config = new ChartConfig(_series, const [0])
-      ..minimumSize = minSize
-      ..legend = new ChartLegend(legendHost, showValues: true);
-    final data = new ChartData(
-        _columns,
-        _counters.keys
-            .map((key) => [key, double.parse(_counters[key].split('%')[0])])
-            .toList());
+    var members = <Element>[];
+    _counters.forEach((key, value) {
+      members.add(new DivElement()
+        ..classes = ['memberItem']
+        ..children = <Element>[
+          new DivElement()
+            ..classes = ['memberName']
+            ..text = key,
+          new DivElement()
+            ..classes = ['memberValue']
+            ..text = value,
+        ]);
+    });
 
-    new LayoutArea(areaHost, data, config,
-        state: new ChartState(), autoUpdate: false)
-      ..addChartBehavior(new Hovercard())
-      ..addChartBehavior(new AxisLabelTooltip())
-      ..draw();
+    children = <Element>[
+      new DivElement()
+        ..classes = ['memberList']
+        ..children = members
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate_reconnect.dart b/runtime/observatory/lib/src/elements/isolate_reconnect.dart
index bf72f2f..8031aa3 100644
--- a/runtime/observatory/lib/src/elements/isolate_reconnect.dart
+++ b/runtime/observatory/lib/src/elements/isolate_reconnect.dart
@@ -23,7 +23,7 @@
         ViewFooterElement.tag
       ]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<IsolateReconnectElement> _r;
 
   Stream<RenderedEvent<IsolateReconnectElement>> get onRendered =>
       _r.onRendered;
diff --git a/runtime/observatory/lib/src/elements/metric/graph.dart b/runtime/observatory/lib/src/elements/metric/graph.dart
index 24406a2..b143895 100644
--- a/runtime/observatory/lib/src/elements/metric/graph.dart
+++ b/runtime/observatory/lib/src/elements/metric/graph.dart
@@ -5,7 +5,6 @@
 import 'dart:html';
 import 'dart:async';
 import 'package:observatory/models.dart' as M;
-import 'package:charted/charted.dart';
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
@@ -55,11 +54,6 @@
     _timer.cancel();
   }
 
-  final _columns = [
-    new ChartColumnSpec(label: 'Time', type: ChartColumnSpec.TYPE_TIMESTAMP),
-    new ChartColumnSpec(label: 'Value', formatter: (v) => v.toString())
-  ];
-
   void render() {
     final min = _metrics.getMinValue(_isolate, _metric);
     final max = _metrics.getMaxValue(_isolate, _metric);
@@ -117,18 +111,9 @@
                       ..text = '$max'
                   ]
         ],
-      new DivElement()
-        ..classes = ['graph']
-        ..children = <Element>[host]
     ];
     if (rows.length <= 1) {
       return;
     }
-    final rect = host.getBoundingClientRect();
-    var series = new ChartSeries("one", [1], new LineChartRenderer());
-    var config = new ChartConfig([series], [0]);
-    config.minimumSize = new Rect(rect.width, rect.height);
-    final data = new ChartData(_columns, rows);
-    new CartesianArea(host, data, config, state: new ChartState()).draw();
   }
 }
diff --git a/runtime/observatory/lib/src/elements/nav/class_menu.dart b/runtime/observatory/lib/src/elements/nav/class_menu.dart
index c388eb3..f0dd55d 100644
--- a/runtime/observatory/lib/src/elements/nav/class_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/class_menu.dart
@@ -13,7 +13,7 @@
 class NavClassMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavClassMenuElement>('nav-class-menu');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavClassMenuElement> _r;
 
   Stream<RenderedEvent<NavClassMenuElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/isolate_menu.dart b/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
index 9b94daf..65cbca9 100644
--- a/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
@@ -15,7 +15,7 @@
   static const tag = const Tag<NavIsolateMenuElement>('nav-isolate-menu',
       dependencies: const [NavMenuItemElement.tag]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavIsolateMenuElement> _r;
 
   Stream<RenderedEvent<NavIsolateMenuElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/library_menu.dart b/runtime/observatory/lib/src/elements/nav/library_menu.dart
index 2ef6f15..e5705d4 100644
--- a/runtime/observatory/lib/src/elements/nav/library_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/library_menu.dart
@@ -13,7 +13,7 @@
 class NavLibraryMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavLibraryMenuElement>('nav-library-menu');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavLibraryMenuElement> _r;
 
   Stream<RenderedEvent<NavLibraryMenuElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/menu_item.dart b/runtime/observatory/lib/src/elements/nav/menu_item.dart
index 5df68a9..5de1b94 100644
--- a/runtime/observatory/lib/src/elements/nav/menu_item.dart
+++ b/runtime/observatory/lib/src/elements/nav/menu_item.dart
@@ -10,7 +10,7 @@
 class NavMenuItemElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavMenuItemElement>('nav-menu-item');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavMenuItemElement> _r;
 
   Stream<RenderedEvent<NavMenuItemElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/notify.dart b/runtime/observatory/lib/src/elements/nav/notify.dart
index a33d800..07ba4e0 100644
--- a/runtime/observatory/lib/src/elements/nav/notify.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify.dart
@@ -17,7 +17,7 @@
         NavNotifyExceptionElement.tag
       ]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavNotifyElement> _r;
 
   Stream<RenderedEvent<NavNotifyElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/notify_event.dart b/runtime/observatory/lib/src/elements/nav/notify_event.dart
index fc9defc..5fa52d6 100644
--- a/runtime/observatory/lib/src/elements/nav/notify_event.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify_event.dart
@@ -17,7 +17,7 @@
 class NavNotifyEventElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavNotifyEventElement>('nav-event');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavNotifyEventElement> _r;
 
   Stream<RenderedEvent<NavNotifyEventElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/notify_exception.dart b/runtime/observatory/lib/src/elements/nav/notify_exception.dart
index 9a746f0..4100ef6 100644
--- a/runtime/observatory/lib/src/elements/nav/notify_exception.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify_exception.dart
@@ -19,7 +19,7 @@
 class NavNotifyExceptionElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavNotifyExceptionElement>('nav-exception');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavNotifyExceptionElement> _r;
 
   Stream<RenderedEvent<NavNotifyExceptionElement>> get onRendered =>
       _r.onRendered;
diff --git a/runtime/observatory/lib/src/elements/nav/refresh.dart b/runtime/observatory/lib/src/elements/nav/refresh.dart
index 1d918fb..445d53b 100644
--- a/runtime/observatory/lib/src/elements/nav/refresh.dart
+++ b/runtime/observatory/lib/src/elements/nav/refresh.dart
@@ -15,7 +15,7 @@
 class NavRefreshElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavRefreshElement>('nav-refresh');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavRefreshElement> _r;
 
   Stream<RenderedEvent<NavRefreshElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/reload.dart b/runtime/observatory/lib/src/elements/nav/reload.dart
index b6d1a5c..da6813b 100644
--- a/runtime/observatory/lib/src/elements/nav/reload.dart
+++ b/runtime/observatory/lib/src/elements/nav/reload.dart
@@ -18,7 +18,7 @@
 class NavReloadElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavReloadElement>('nav-reload');
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavReloadElement> _r;
 
   Stream<RenderedEvent<NavReloadElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/top_menu.dart b/runtime/observatory/lib/src/elements/nav/top_menu.dart
index eb8cf97..3415fde 100644
--- a/runtime/observatory/lib/src/elements/nav/top_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/top_menu.dart
@@ -14,7 +14,7 @@
   static const tag = const Tag<NavTopMenuElement>('nav-top-menu',
       dependencies: const [NavMenuItemElement.tag]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavTopMenuElement> _r;
 
   Stream<RenderedEvent<NavTopMenuElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/nav/vm_menu.dart b/runtime/observatory/lib/src/elements/nav/vm_menu.dart
index 38fbdf7..0216a01 100644
--- a/runtime/observatory/lib/src/elements/nav/vm_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/vm_menu.dart
@@ -15,7 +15,7 @@
   static const tag = const Tag<NavVMMenuElement>('nav-vm-menu',
       dependencies: const [NavMenuItemElement.tag]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<NavVMMenuElement> _r;
 
   Stream<RenderedEvent<NavVMMenuElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 9c5ca8f..032072b 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -19,7 +19,7 @@
 class ScriptInsetElement extends CustomElement implements Renderable {
   static const tag = const Tag<ScriptInsetElement>('script-inset');
 
-  RenderingScheduler _r;
+  RenderingScheduler<ScriptInsetElement> _r;
 
   Stream<RenderedEvent<ScriptInsetElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/script_ref.dart b/runtime/observatory/lib/src/elements/script_ref.dart
index f5acf04..91f8e68 100644
--- a/runtime/observatory/lib/src/elements/script_ref.dart
+++ b/runtime/observatory/lib/src/elements/script_ref.dart
@@ -14,7 +14,7 @@
 class ScriptRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ScriptRefElement>('script-ref');
 
-  RenderingScheduler _r;
+  RenderingScheduler<ScriptRefElement> _r;
 
   Stream<RenderedEvent<ScriptRefElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/source_inset.dart b/runtime/observatory/lib/src/elements/source_inset.dart
index 42d3d2b..9e3b78d 100644
--- a/runtime/observatory/lib/src/elements/source_inset.dart
+++ b/runtime/observatory/lib/src/elements/source_inset.dart
@@ -14,7 +14,7 @@
 class SourceInsetElement extends CustomElement implements Renderable {
   static const tag = const Tag<SourceInsetElement>('source-inset');
 
-  RenderingScheduler _r;
+  RenderingScheduler<SourceInsetElement> _r;
 
   Stream<RenderedEvent<SourceInsetElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
index d19c726..b05ac57 100644
--- a/runtime/observatory/lib/src/elements/source_link.dart
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -16,7 +16,7 @@
 class SourceLinkElement extends CustomElement implements Renderable {
   static const tag = const Tag<SourceLinkElement>('source-link');
 
-  RenderingScheduler _r;
+  RenderingScheduler<SourceLinkElement> _r;
 
   Stream<RenderedEvent<SourceLinkElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/view_footer.dart b/runtime/observatory/lib/src/elements/view_footer.dart
index d401bde..2115632 100644
--- a/runtime/observatory/lib/src/elements/view_footer.dart
+++ b/runtime/observatory/lib/src/elements/view_footer.dart
@@ -12,7 +12,7 @@
 class ViewFooterElement extends CustomElement implements Renderable {
   static const tag = const Tag<ViewFooterElement>('view-footer');
 
-  RenderingScheduler _r;
+  RenderingScheduler<ViewFooterElement> _r;
 
   Stream<RenderedEvent<ViewFooterElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index 576aa76..926b2c9 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -25,7 +25,7 @@
     VMConnectTargetElement.tag
   ]);
 
-  RenderingScheduler _r;
+  RenderingScheduler<VMConnectElement> _r;
 
   Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered;
 
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 1e4bf9f..738766a 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -2206,6 +2206,8 @@
   static const kExtension = 'Extension';
   static const kServiceRegistered = 'ServiceRegistered';
   static const kServiceUnregistered = 'ServiceUnregistered';
+  static const kDartDevelopmentServiceConnected =
+      'DartDevelopmentServiceConnected';
 
   ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner);
 
@@ -2242,6 +2244,8 @@
   String method;
   String service;
   String alias;
+  String message;
+  Uri uri;
 
   bool lastChunk;
 
@@ -2345,6 +2349,12 @@
     if (map['newValue'] != null) {
       newValue = map['newValue'];
     }
+    if (map['message'] != null) {
+      message = map['message'];
+    }
+    if (map['uri'] != null) {
+      uri = Uri.parse(map['uri']);
+    }
   }
 
   String toString() {
diff --git a/runtime/observatory/tests/service/break_on_default_constructor_test.dart b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
index bc504c74..d968ca2 100644
--- a/runtime/observatory/tests/service/break_on_default_constructor_test.dart
+++ b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
@@ -66,7 +66,7 @@
       fail("Expected to find function");
     }
 
-    isolate.resume();
+    await isolate.resume();
   }
 ];
 
diff --git a/runtime/observatory/tests/service/client_name_rpc_test.dart b/runtime/observatory/tests/service/client_name_rpc_test.dart
index 41cbe4f..92aa4c9 100644
--- a/runtime/observatory/tests/service/client_name_rpc_test.dart
+++ b/runtime/observatory/tests/service/client_name_rpc_test.dart
@@ -63,4 +63,7 @@
   },
 ];
 
-main(args) async => runVMTests(args, tests);
+main(args) async => runVMTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/client_resume_approvals_approve_then_disconnect_test.dart b/runtime/observatory/tests/service/client_resume_approvals_approve_then_disconnect_test.dart
index 427706f..439f170 100644
--- a/runtime/observatory/tests/service/client_resume_approvals_approve_then_disconnect_test.dart
+++ b/runtime/observatory/tests/service/client_resume_approvals_approve_then_disconnect_test.dart
@@ -60,5 +60,10 @@
   hasStoppedAtExit,
 ];
 
-Future<void> main(args) => runIsolateTests(args, test,
-    testeeConcurrent: fooBar, pause_on_start: true, pause_on_exit: true);
+Future<void> main(args) => runIsolateTests(
+      args,
+      test,
+      testeeConcurrent: fooBar,
+      pause_on_start: true,
+      pause_on_exit: true,
+    );
diff --git a/runtime/observatory/tests/service/client_resume_approvals_disconnect_test.dart b/runtime/observatory/tests/service/client_resume_approvals_disconnect_test.dart
index 9d23522..d82317a 100644
--- a/runtime/observatory/tests/service/client_resume_approvals_disconnect_test.dart
+++ b/runtime/observatory/tests/service/client_resume_approvals_disconnect_test.dart
@@ -58,5 +58,10 @@
   hasStoppedAtExit,
 ];
 
-Future<void> main(args) => runIsolateTests(args, test,
-    testeeConcurrent: fooBar, pause_on_start: true, pause_on_exit: true);
+Future<void> main(args) => runIsolateTests(
+      args,
+      test,
+      testeeConcurrent: fooBar,
+      pause_on_start: true,
+      pause_on_exit: true,
+    );
diff --git a/runtime/observatory/tests/service/client_resume_approvals_identical_names_test.dart b/runtime/observatory/tests/service/client_resume_approvals_identical_names_test.dart
index d3a09a9..dbcc14a 100644
--- a/runtime/observatory/tests/service/client_resume_approvals_identical_names_test.dart
+++ b/runtime/observatory/tests/service/client_resume_approvals_identical_names_test.dart
@@ -40,5 +40,10 @@
   hasStoppedAtExit,
 ];
 
-Future<void> main(args) => runIsolateTests(args, sameClientNamesTest,
-    testeeConcurrent: fooBar, pause_on_start: true, pause_on_exit: true);
+Future<void> main(args) => runIsolateTests(
+      args,
+      sameClientNamesTest,
+      testeeConcurrent: fooBar,
+      pause_on_start: true,
+      pause_on_exit: true,
+    );
diff --git a/runtime/observatory/tests/service/client_resume_approvals_multiple_names_test.dart b/runtime/observatory/tests/service/client_resume_approvals_multiple_names_test.dart
index 5f26a9c..88d217d 100644
--- a/runtime/observatory/tests/service/client_resume_approvals_multiple_names_test.dart
+++ b/runtime/observatory/tests/service/client_resume_approvals_multiple_names_test.dart
@@ -58,5 +58,10 @@
   },
 ];
 
-Future<void> main(args) => runIsolateTests(args, multipleClientNamesTest,
-    testeeConcurrent: fooBar, pause_on_start: true, pause_on_exit: true);
+Future<void> main(args) => runIsolateTests(
+      args,
+      multipleClientNamesTest,
+      testeeConcurrent: fooBar,
+      pause_on_start: true,
+      pause_on_exit: true,
+    );
diff --git a/runtime/observatory/tests/service/client_resume_approvals_name_change_test.dart b/runtime/observatory/tests/service/client_resume_approvals_name_change_test.dart
index 3d33112..0e1374e 100644
--- a/runtime/observatory/tests/service/client_resume_approvals_name_change_test.dart
+++ b/runtime/observatory/tests/service/client_resume_approvals_name_change_test.dart
@@ -51,5 +51,10 @@
   hasStoppedAtExit,
 ];
 
-Future<void> main(args) => runIsolateTests(args, nameChangeTest,
-    testeeConcurrent: fooBar, pause_on_start: true, pause_on_exit: true);
+Future<void> main(args) => runIsolateTests(
+      args,
+      nameChangeTest,
+      testeeConcurrent: fooBar,
+      pause_on_start: true,
+      pause_on_exit: true,
+    );
diff --git a/runtime/observatory/tests/service/client_resume_approvals_reload_test.dart b/runtime/observatory/tests/service/client_resume_approvals_reload_test.dart
index 250d349..08fdc10 100644
--- a/runtime/observatory/tests/service/client_resume_approvals_reload_test.dart
+++ b/runtime/observatory/tests/service/client_resume_approvals_reload_test.dart
@@ -60,5 +60,9 @@
   },
 ];
 
-Future<void> main(args) => runIsolateTests(args, hotReloadTest,
-    testeeConcurrent: fooBar, pause_on_start: true);
+Future<void> main(args) => runIsolateTests(
+      args,
+      hotReloadTest,
+      testeeConcurrent: fooBar,
+      pause_on_start: true,
+    );
diff --git a/runtime/observatory/tests/service/contexts_test.dart b/runtime/observatory/tests/service/contexts_test.dart
index ad17f38..33021a1 100644
--- a/runtime/observatory/tests/service/contexts_test.dart
+++ b/runtime/observatory/tests/service/contexts_test.dart
@@ -8,7 +8,15 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
-var cleanBlock, copyingBlock, fullBlock, fullBlockWithChain;
+// Make sure these variables are not removed by the tree shaker.
+@pragma("vm:entry-point")
+var cleanBlock;
+@pragma("vm:entry-point")
+var copyingBlock;
+@pragma("vm:entry-point")
+var fullBlock;
+@pragma("vm:entry-point")
+var fullBlockWithChain;
 
 Function genCleanBlock() {
   block(x) => x;
diff --git a/runtime/observatory/tests/service/dev_fs_spawn_test.dart b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
deleted file mode 100644
index 4e76990..0000000
--- a/runtime/observatory/tests/service/dev_fs_spawn_test.dart
+++ /dev/null
@@ -1,213 +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:async';
-import 'dart:convert';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-var tests = <VMTest>[
-  (VM vm) async {
-    // Create a new fs.
-    var fsName = 'scratch';
-    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('FileSystem'));
-    expect(result['name'], equals('scratch'));
-    expect(result['uri'], new isInstanceOf<String>());
-    var fsUri = result['uri'];
-
-    // Spawn a script with a bad uri and make sure that the error is
-    // delivered asynchronously.
-    Completer completer = new Completer();
-    var sub;
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('someSpawnToken'));
-        expect(event.spawnError,
-            startsWith('IsolateSpawnException: Unable to spawn isolate: '));
-        expect(event.isolate, isNull);
-        completer.complete();
-        sub.cancel();
-      }
-    });
-
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'someSpawnToken',
-      'uri': '${fsUri}doesnotexist.dart',
-    });
-    expect(result['type'], equals('Success'));
-    await completer.future;
-
-    // Delete the fs.
-    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('Success'));
-  },
-  (VM vm) async {
-    // Create a new fs.
-    var fsName = 'scratch';
-    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('FileSystem'));
-    expect(result['name'], equals('scratch'));
-    expect(result['uri'], new isInstanceOf<String>());
-    var fsUri = result['uri'];
-
-    var filePaths = [
-      'devfs_file0.dart',
-      'devfs_file1.dart',
-      'devfs_file2.dart'
-    ];
-    var scripts = [
-      '''
-import 'dart:developer';
-proofOfLife() => 'I live!';
-main() {
-  print('HELLO WORLD 1');
-  debugger();
-}
-''',
-      '''
-import 'dart:developer';
-var globalArgs;
-proofOfLife() => 'I live, \${globalArgs}!';
-main(args) {
-  globalArgs = args;
-  print('HELLO WORLD 2');
-  debugger();
-}
-''',
-      '''
-import 'dart:developer';
-var globalArgs;
-var globalMsg;
-proofOfLife() => 'I live, \${globalArgs}, \${globalMsg}!';
-main(args, msg) {
-  globalArgs = args;
-  globalMsg = msg;
-  print('HELLO WORLD 3');
-  debugger();
-}
-''',
-    ];
-
-    // Write three scripts to the fs.
-    for (int i = 0; i < 3; i++) {
-      var fileContents = base64Encode(utf8.encode(scripts[i]));
-      result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
-        'fsName': fsName,
-        'path': filePaths[i],
-        'fileContents': fileContents
-      });
-      expect(result['type'], equals('Success'));
-    }
-
-    // Spawn the script with no arguments or message and make sure
-    // that we are notified.
-    Completer completer = new Completer();
-    var sub;
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('mySpawnToken0'));
-        expect(event.isolate, isNotNull);
-        expect(event.isolate.name, equals('main'));
-        completer.complete(event.isolate);
-        sub.cancel();
-      }
-    });
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'mySpawnToken0',
-      'uri': '${fsUri}${filePaths[0]}',
-    });
-    expect(result['type'], equals('Success'));
-    var spawnedIsolate = await completer.future;
-
-    // Wait for the spawned isolate to hit a breakpoint.
-    await spawnedIsolate.load();
-    await hasStoppedAtBreakpoint(spawnedIsolate);
-
-    // Make sure that we are running code from the spawned isolate.
-    var instance = (await spawnedIsolate.rootLibrary.evaluate('proofOfLife()'))
-        as Instance;
-    expect(instance.type, equals('Instance'));
-    expect(instance.kind, equals(M.InstanceKind.string));
-    expect(instance.valueAsString, equals('I live!'));
-
-    // Spawn the script with arguments.
-    completer = new Completer();
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('mySpawnToken1'));
-        expect(event.isolate, isNotNull);
-        expect(event.isolate.name, equals('main'));
-        completer.complete(event.isolate);
-        sub.cancel();
-      }
-    });
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'mySpawnToken1',
-      'uri': '${fsUri}${filePaths[1]}',
-      'args': <String>['one', 'two', 'three']
-    });
-    expect(result['type'], equals('Success'));
-    spawnedIsolate = await completer.future;
-
-    // Wait for the spawned isolate to hit a breakpoint.
-    await spawnedIsolate.load();
-    await hasStoppedAtBreakpoint(spawnedIsolate);
-
-    // Make sure that we are running code from the spawned isolate.
-    instance = (await spawnedIsolate.rootLibrary.evaluate('proofOfLife()'))
-        as Instance;
-    expect(instance.type, equals('Instance'));
-    expect(instance.kind, equals(M.InstanceKind.string));
-    expect(instance.valueAsString, equals('I live, [one, two, three]!'));
-
-    // Spawn the script with arguments and message
-    completer = new Completer();
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('mySpawnToken2'));
-        expect(event.isolate, isNotNull);
-        expect(event.isolate.name, equals('main'));
-        completer.complete(event.isolate);
-        sub.cancel();
-      }
-    });
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'mySpawnToken2',
-      'uri': '${fsUri}${filePaths[2]}',
-      'args': ['A', 'B', 'C'],
-      'message': 'test'
-    });
-    expect(result['type'], equals('Success'));
-    spawnedIsolate = await completer.future;
-
-    // Wait for the spawned isolate to hit a breakpoint.
-    await spawnedIsolate.load();
-    await hasStoppedAtBreakpoint(spawnedIsolate);
-
-    // Make sure that we are running code from the spawned isolate.
-    instance = (await spawnedIsolate.rootLibrary.evaluate('proofOfLife()'))
-        as Instance;
-    expect(instance.type, equals('Instance'));
-    expect(instance.kind, equals(M.InstanceKind.string));
-    expect(instance.valueAsString, equals('I live, [A, B, C], test!'));
-
-    // Delete the fs.
-    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('Success'));
-  },
-];
-
-main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/dominator_tree_vm_test.dart b/runtime/observatory/tests/service/dominator_tree_vm_test.dart
index ebb9c77..3fb617b 100644
--- a/runtime/observatory/tests/service/dominator_tree_vm_test.dart
+++ b/runtime/observatory/tests/service/dominator_tree_vm_test.dart
@@ -12,62 +12,86 @@
 
 // small example from [Lenguaer & Tarjan 1979]
 class R {
+  // All fields are marked with @pragma("vm:entry-point")
+  // in order to make sure they are not removed by the tree shaker
+  // even though they are never read.
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
+  @pragma("vm:entry-point")
   var z;
 }
 
 class A {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class B {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
+  @pragma("vm:entry-point")
   var z;
 }
 
 class C {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class D {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class E {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class F {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class G {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class H {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class I {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class J {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class K {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class L {
+  @pragma("vm:entry-point")
   var x;
 }
 
diff --git a/runtime/observatory/tests/service/dominator_tree_vm_with_double_field_test.dart b/runtime/observatory/tests/service/dominator_tree_vm_with_double_field_test.dart
index 858f10a..eee07b2 100644
--- a/runtime/observatory/tests/service/dominator_tree_vm_with_double_field_test.dart
+++ b/runtime/observatory/tests/service/dominator_tree_vm_with_double_field_test.dart
@@ -22,62 +22,86 @@
 // small example from [Lenguaer & Tarjan 1979]
 class R {
   final double fld = getDoubleWithHeapObjectTag();
+  // Fields are marked with @pragma("vm:entry-point")
+  // in order to make sure they are not removed by the tree shaker
+  // even though they are never read.
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
+  @pragma("vm:entry-point")
   var z;
 }
 
 class A {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class B {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
+  @pragma("vm:entry-point")
   var z;
 }
 
 class C {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class D {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class E {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class F {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class G {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class H {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class I {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class J {
+  @pragma("vm:entry-point")
   var x;
 }
 
 class K {
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
 class L {
+  @pragma("vm:entry-point")
   var x;
 }
 
diff --git a/runtime/observatory/tests/service/enable_service_port_fallback_positive_test.dart b/runtime/observatory/tests/service/enable_service_port_fallback_positive_test.dart
index ca25d5f..bbac574 100644
--- a/runtime/observatory/tests/service/enable_service_port_fallback_positive_test.dart
+++ b/runtime/observatory/tests/service/enable_service_port_fallback_positive_test.dart
@@ -21,11 +21,15 @@
 
 main(args) async {
   selectedPort = await _getUnusedPort();
-  await runVMTests(args, tests,
-      enable_service_port_fallback: true,
-      // Choose a port number that should always be open.
-      port: selectedPort,
-      extraArgs: []);
+  await runVMTests(
+    args, tests,
+    enable_service_port_fallback: true,
+    // Choose a port number that should always be open.
+    port: selectedPort,
+    extraArgs: [],
+    // TODO(bkonyi): investigate failure.
+    enableDds: false,
+  );
 }
 
 Future<int> _getUnusedPort() async {
diff --git a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
index 2778167..91f015d 100644
--- a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
@@ -135,7 +135,8 @@
               'id': request['id'],
               'error': {
                 'code': errorCode + iteration,
-                'data': {errorKey + end: errorValue + end}
+                'data': {errorKey + end: errorValue + end},
+                'message': 'error message',
               }
             });
       }).toList();
@@ -164,4 +165,7 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/external_service_disappear_test.dart b/runtime/observatory/tests/service/external_service_disappear_test.dart
index eafe5a6..fec1d31 100644
--- a/runtime/observatory/tests/service/external_service_disappear_test.dart
+++ b/runtime/observatory/tests/service/external_service_disappear_test.dart
@@ -89,4 +89,7 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
index 3b1e695..2a659a1 100644
--- a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
@@ -83,4 +83,7 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/external_service_registration_test.dart b/runtime/observatory/tests/service/external_service_registration_test.dart
index 2ec0d95..469facb 100644
--- a/runtime/observatory/tests/service/external_service_registration_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_test.dart
@@ -123,4 +123,7 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
index 333c24e..008c221 100644
--- a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
@@ -103,4 +103,7 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
index 97917b3..a7cee78 100644
--- a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
@@ -110,7 +110,8 @@
         'id': request['id'],
         'error': {
           'code': errorCode + iteration,
-          'data': {errorKey + end: errorValue + end}
+          'data': {errorKey + end: errorValue + end},
+          'message': 'error message',
         }
       });
 
@@ -126,4 +127,7 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+    );
diff --git a/runtime/observatory/tests/service/get_client_name_rpc_test.dart b/runtime/observatory/tests/service/get_client_name_rpc_test.dart
index d503a91..25b7828 100644
--- a/runtime/observatory/tests/service/get_client_name_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_client_name_rpc_test.dart
@@ -37,4 +37,8 @@
   },
 ];
 
-Future<void> main(args) => runIsolateTests(args, test, testeeBefore: fooBar);
+Future<void> main(args) => runIsolateTests(
+      args,
+      test,
+      testeeBefore: fooBar,
+    );
diff --git a/runtime/observatory/tests/service/get_instances_rpc_test.dart b/runtime/observatory/tests/service/get_instances_rpc_test.dart
index 0f234be..696f521 100644
--- a/runtime/observatory/tests/service/get_instances_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_instances_rpc_test.dart
@@ -9,7 +9,10 @@
 
 class _TestClass {
   _TestClass(this.x, this.y);
+  // Make sure these fields are not removed by the tree shaker.
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
diff --git a/runtime/observatory/tests/service/get_retained_size_rpc_test.dart b/runtime/observatory/tests/service/get_retained_size_rpc_test.dart
index 7060f13..3241ce5 100644
--- a/runtime/observatory/tests/service/get_retained_size_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retained_size_rpc_test.dart
@@ -9,10 +9,14 @@
 
 class _TestClass {
   _TestClass(this.x, this.y);
+  // Make sure these fields are not removed by the tree shaker.
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
+@pragma("vm:entry-point")
 var myVar;
 
 @pragma("vm:entry-point")
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 78cacc0..1a036e5 100644
--- a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
@@ -9,7 +9,10 @@
 
 class _TestClass {
   _TestClass();
+  // Make sure these fields are not removed by the tree shaker.
+  @pragma("vm:entry-point")
   var x;
+  @pragma("vm:entry-point")
   var y;
 }
 
@@ -193,7 +196,7 @@
       'limit': 100,
     };
     var result = await isolate.invokeRpcNoUpgrade('getRetainingPath', params);
-    expect(result['gcRootType'], 'object store');
+    expect(result['gcRootType'], 'isolate_object store');
     expect(result['elements'].length, 0);
   },
 ];
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index caaa488..3dc33db 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 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(30));
+    expect(result['minor'], equals(33));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/inbound_references_test.dart b/runtime/observatory/tests/service/inbound_references_test.dart
index 4c1e496..267f1b1 100644
--- a/runtime/observatory/tests/service/inbound_references_test.dart
+++ b/runtime/observatory/tests/service/inbound_references_test.dart
@@ -9,6 +9,8 @@
 import 'test_helper.dart';
 
 class Node {
+  // Make sure this field is not removed by the tree shaker.
+  @pragma("vm:entry-point")
   var edge;
 }
 
diff --git a/runtime/observatory/tests/service/instance_field_order_rpc_test.dart b/runtime/observatory/tests/service/instance_field_order_rpc_test.dart
index 9ff16e4..b1a3c38 100644
--- a/runtime/observatory/tests/service/instance_field_order_rpc_test.dart
+++ b/runtime/observatory/tests/service/instance_field_order_rpc_test.dart
@@ -9,12 +9,17 @@
 import 'test_helper.dart';
 
 class Super {
+  // Make sure these fields are not removed by the tree shaker.
+  @pragma("vm:entry-point")
   var z = 1;
+  @pragma("vm:entry-point")
   var y = 2;
 }
 
 class Sub extends Super {
+  @pragma("vm:entry-point")
   var y = 3;
+  @pragma("vm:entry-point")
   var x = 4;
 }
 
diff --git a/runtime/observatory/tests/service/invoke_test.dart b/runtime/observatory/tests/service/invoke_test.dart
index 8a9ebb7..4d198a7 100644
--- a/runtime/observatory/tests/service/invoke_test.dart
+++ b/runtime/observatory/tests/service/invoke_test.dart
@@ -11,13 +11,17 @@
 libraryFunction() => "foobar1";
 
 class Klass {
+  @pragma('vm:entry-point')
   static classFunction(x) => "foobar2" + x;
+  @pragma('vm:entry-point')
   instanceFunction(x, y) => "foobar3" + x + y;
 }
 
 var instance;
 
+@pragma('vm:entry-point')
 var apple;
+@pragma('vm:entry-point')
 var banana;
 
 void testFunction() {
@@ -27,11 +31,22 @@
   debugger();
 }
 
+@pragma('vm:entry-point')
+void foo() {
+  print('foobar');
+}
+
+@pragma('vm:entry-point')
+void invokeFunction(Function func) {
+  func();
+}
+
 var tests = <IsolateTest>[
   hasStoppedAtBreakpoint,
   (Isolate isolate) async {
     Library lib = isolate.rootLibrary;
     await lib.load();
+    final fooFunc = lib.functions.singleWhere((func) => func.name == "foo");
     Class cls = lib.classes.singleWhere((cls) => cls.name == "Klass");
     Field field =
         lib.variables.singleWhere((field) => field.name == "instance");
@@ -66,30 +81,43 @@
     expect(result.valueAsString, equals('foobar3applebanana'));
 
     // Wrong arity.
-    await expectError(() => isolate.invokeRpc("invoke", {
-          "targetId": instance.id,
-          "selector": "instanceFunction",
-          "argumentIds": [apple.id]
-        }));
+    await expectError(
+        () => isolate.invokeRpc("invoke", {
+              "targetId": instance.id,
+              "selector": "instanceFunction",
+              "argumentIds": [apple.id]
+            }),
+        ServerRpcException.kExpressionCompilationError);
+
+    // Non-instance argument.
+    await expectError(
+        () => isolate.invokeRpc("invoke", {
+              "targetId": lib.id,
+              "selector": "invokeFunction",
+              "argumentIds": [fooFunc.id]
+            }),
+        ServerRpcException.kInvalidParams);
 
     // No such target.
-    await expectError(() => isolate.invokeRpc("invoke", {
-          "targetId": instance.id,
-          "selector": "functionDoesNotExist",
-          "argumentIds": [apple.id]
-        }));
+    await expectError(
+        () => isolate.invokeRpc("invoke", {
+              "targetId": instance.id,
+              "selector": "functionDoesNotExist",
+              "argumentIds": [apple.id]
+            }),
+        ServerRpcException.kExpressionCompilationError);
   },
   resumeIsolate,
 ];
 
-expectError(func) async {
+expectError(func, code) async {
   bool gotException = false;
   dynamic result;
   try {
     result = await func();
     expect(result.type, equals('Error')); // dart1 semantics
   } on ServerRpcException catch (e) {
-    expect(e.code, equals(ServerRpcException.kExpressionCompilationError));
+    expect(e.code, code);
     gotException = true;
   }
   if (result?.type != 'Error') {
diff --git a/runtime/observatory/tests/service/malformed_test.dart b/runtime/observatory/tests/service/malformed_test.dart
index 5fff3fd..9e277c8 100644
--- a/runtime/observatory/tests/service/malformed_test.dart
+++ b/runtime/observatory/tests/service/malformed_test.dart
@@ -37,4 +37,11 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests);
+main(args) => runIsolateTests(
+      args,
+      tests,
+      // This test hangs with DDS as package:json_rpc_2 can't parse the JSON
+      // response and is unable to determine the request ID, so the malformed
+      // JSON request will never complete.
+      enableDds: false,
+    );
diff --git a/runtime/observatory/tests/service/network_profiling_test.dart b/runtime/observatory/tests/service/network_profiling_test.dart
index c02b278..4da5995 100644
--- a/runtime/observatory/tests/service/network_profiling_test.dart
+++ b/runtime/observatory/tests/service/network_profiling_test.dart
@@ -7,8 +7,11 @@
 import 'dart:developer';
 import 'dart:io' as io;
 import 'dart:isolate';
+
+import 'package:expect/expect.dart';
 import 'package:observatory/service_io.dart';
 import 'package:test/test.dart';
+
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
@@ -115,6 +118,9 @@
     expect(stats.length, 3);
     stats.forEach((socket) {
       expect(socket['address'], contains(localhost));
+      Expect.type<int>(socket['startTime']);
+      Expect.type<int>(socket['id']);
+      Expect.type<int>(socket['port']);
       if (socket['socketType'] == 'tcp') {
         expect(socket['writeBytes'], content.length);
         expect(socket.containsKey('lastWriteTime'), true);
diff --git a/runtime/observatory/tests/service/object_graph_vm_test.dart b/runtime/observatory/tests/service/object_graph_vm_test.dart
index 852c823..9414709 100644
--- a/runtime/observatory/tests/service/object_graph_vm_test.dart
+++ b/runtime/observatory/tests/service/object_graph_vm_test.dart
@@ -9,7 +9,10 @@
 import 'test_helper.dart';
 
 class Foo {
+  // Make sure these fields are not removed by the tree shaker.
+  @pragma("vm:entry-point")
   dynamic left;
+  @pragma("vm:entry-point")
   dynamic right;
 }
 
diff --git a/runtime/observatory/tests/service/observatory_assets_test.dart b/runtime/observatory/tests/service/observatory_assets_test.dart
index 4b8f8e2..a78f448 100644
--- a/runtime/observatory/tests/service/observatory_assets_test.dart
+++ b/runtime/observatory/tests/service/observatory_assets_test.dart
@@ -22,4 +22,8 @@
   }
 ];
 
-main(args) async => runVMTests(args, tests);
+main(args) async => runVMTests(
+      args, tests,
+      // TODO(bkonyi): DDS doesn't forward Observatory assets properly yet.
+      enableDds: false,
+    );
diff --git a/runtime/observatory/tests/service/observatory_test_package/pubspec.yaml b/runtime/observatory/tests/service/observatory_test_package/pubspec.yaml
new file mode 100644
index 0000000..db61a01f
--- /dev/null
+++ b/runtime/observatory/tests/service/observatory_test_package/pubspec.yaml
@@ -0,0 +1,4 @@
+name: observatory_test_package
+publish_to: none
+environment:
+  sdk: '^2.7.0'
diff --git a/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart b/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart
index 1d3a8bf..cb4b288 100644
--- a/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart
+++ b/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart
@@ -101,12 +101,16 @@
   },
 ];
 
-main(args) => runIsolateTests(args, tests,
-        testeeConcurrent: testMain,
-        pause_on_start: true,
-        pause_on_exit: true,
-        verbose_vm: true,
-        extraArgs: [
-          '--trace-service',
-          '--trace-service-verbose',
-        ]);
+main(args) => runIsolateTests(
+      args, tests,
+      testeeConcurrent: testMain,
+      pause_on_start: true,
+      pause_on_exit: true,
+      verbose_vm: true,
+      extraArgs: [
+        '--trace-service',
+        '--trace-service-verbose',
+      ],
+      // TODO(bkonyi): investigate failure.
+      enableDds: false,
+    );
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart
index 850177a..6f98284 100644
--- a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart
+++ b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart
@@ -61,7 +61,13 @@
   }
 ];
 
-main(args) => runIsolateTests(args, tests,
-    pause_on_unhandled_exceptions: true,
-    testeeConcurrent: testeeMain,
-    extraArgs: extraDebuggingArgs);
+main(args) => runIsolateTests(
+      args,
+      tests,
+      pause_on_unhandled_exceptions: true,
+      testeeConcurrent: testeeMain,
+      extraArgs: extraDebuggingArgs,
+      // TODO(bkonyi): causes ASSERT in debug mode, unrelated to DDS.
+      // See https://github.com/dart-lang/sdk/issues/41379.
+      enableDds: false,
+    );
diff --git a/runtime/observatory/tests/service/process_service_test.dart b/runtime/observatory/tests/service/process_service_test.dart
index 02e71fc..ced9326 100644
--- a/runtime/observatory/tests/service/process_service_test.dart
+++ b/runtime/observatory/tests/service/process_service_test.dart
@@ -19,7 +19,11 @@
 Future setupProcesses() async {
   var dir = await io.Directory.systemTemp.createTemp('file_service');
 
-  var args = ['--pause_isolates_on_start', io.Platform.script.toFilePath()];
+  var args = [
+    ...io.Platform.executableArguments,
+    '--pause_isolates_on_start',
+    io.Platform.script.toFilePath(),
+  ];
   var process1;
   var process2;
   var process3;
@@ -57,7 +61,8 @@
             await stdin.drain();
           }
           ''');
-      process3 = await io.Process.start(dartJITBinary, [codeFilePath]);
+      process3 = await io.Process.start(
+          dartJITBinary, [...io.Platform.executableArguments, codeFilePath]);
     } catch (e) {
       closeDown();
       throw e;
diff --git a/runtime/observatory/tests/service/reachable_size_test.dart b/runtime/observatory/tests/service/reachable_size_test.dart
index 6bc92f5..bca88d8 100644
--- a/runtime/observatory/tests/service/reachable_size_test.dart
+++ b/runtime/observatory/tests/service/reachable_size_test.dart
@@ -9,7 +9,11 @@
 import 'service_test_common.dart';
 
 class Pair {
-  var x, y;
+  // Make sure these fields are not removed by the tree shaker.
+  @pragma("vm:entry-point")
+  var x;
+  @pragma("vm:entry-point")
+  var y;
 }
 
 var p1;
diff --git a/runtime/observatory/tests/service/regexp_function_test.dart b/runtime/observatory/tests/service/regexp_function_test.dart
index a44cb5b..d11abe0 100644
--- a/runtime/observatory/tests/service/regexp_function_test.dart
+++ b/runtime/observatory/tests/service/regexp_function_test.dart
@@ -9,7 +9,10 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+// Make sure these variables are not removed by the tree shaker.
+@pragma("vm:entry-point")
 var regex0;
+@pragma("vm:entry-point")
 var regex;
 
 void script() {
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 20cc72a..cf5797a 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -29,6 +29,7 @@
 *: SkipByDesign
 
 [ $system == windows ]
+*: Slow
 async_generator_breakpoint_test: Skip # Issue 29145
 dev_fs_http_put_weird_char_test: Skip # Windows disallows carriage returns in paths
 dev_fs_weird_char_test: Skip # Windows disallows question mark in paths
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 0d3d961..026478e 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -30,8 +30,8 @@
 rewind_test: SkipByDesign # No incremental compiler available.
 
 [ $compiler == dartkp ]
-add_breakpoint_rpc_kernel_test: RuntimeError
-async_generator_breakpoint_test: RuntimeError
+add_breakpoint_rpc_kernel_test: SkipByDesign
+async_generator_breakpoint_test: SkipByDesign
 async_next_regession_18877_test: Skip, Timeout
 async_next_test: Skip, Timeout
 async_scope_test: Skip, Timeout
@@ -43,49 +43,49 @@
 async_step_out_test: Skip, Timeout
 awaiter_async_stack_contents_2_test: Skip, Timeout
 awaiter_async_stack_contents_test: Skip, Timeout
-bad_reload_test: RuntimeError
-break_on_activation_test: RuntimeError
+bad_reload_test: SkipByDesign
+break_on_activation_test: SkipByDesign
 break_on_async_function_test: Skip, Timeout
-break_on_default_constructor_test: RuntimeError
+break_on_default_constructor_test: SkipByDesign
 break_on_function_test: Skip, Timeout
-breakpoint_async_break_test: RuntimeError
-breakpoint_in_package_parts_class_file_uri_test: RuntimeError
-breakpoint_in_package_parts_class_test: RuntimeError
-breakpoint_in_parts_class_test: RuntimeError
-breakpoint_non_debuggable_library_test: RuntimeError
-breakpoint_on_if_null_1_test: RuntimeError
-breakpoint_on_if_null_2_test: RuntimeError
-breakpoint_on_if_null_3_test: RuntimeError
-breakpoint_on_if_null_4_test: RuntimeError
-breakpoint_partfile_test: RuntimeError
+breakpoint_async_break_test: SkipByDesign
+breakpoint_in_package_parts_class_file_uri_test: SkipByDesign
+breakpoint_in_package_parts_class_test: SkipByDesign
+breakpoint_in_parts_class_test: SkipByDesign
+breakpoint_non_debuggable_library_test: SkipByDesign
+breakpoint_on_if_null_1_test: SkipByDesign
+breakpoint_on_if_null_2_test: SkipByDesign
+breakpoint_on_if_null_3_test: SkipByDesign
+breakpoint_on_if_null_4_test: SkipByDesign
+breakpoint_partfile_test: SkipByDesign
 breakpoint_two_args_checked_test: Skip, Timeout
-breakpoints_with_mixin_test: RuntimeError # Debugger is disabled in AOT mode.
+breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
 capture_stdio_test: Skip, Timeout
 causal_async_stack_contents_test: Skip, Timeout
 causal_async_stack_presence_test: Skip, Timeout
 causal_async_star_stack_contents_test: Skip, Timeout
 causal_async_star_stack_presence_test: Skip, Timeout
-client_resume_approvals_reload_test: RuntimeError # Compiler is disabled in AOT mode.
-code_test: RuntimeError
-column_breakpoint_test: RuntimeError
-complex_reload_test: RuntimeError
+client_resume_approvals_reload_test: SkipByDesign # Compiler is disabled in AOT mode.
+code_test: SkipByDesign
+column_breakpoint_test: SkipByDesign
+complex_reload_test: SkipByDesign
 coverage_const_field_async_closure_test: Skip, Timeout
 coverage_leaf_function_test: Skip, Timeout
 coverage_optimized_function_test: Skip, Timeout
-debugger_inspect_test: RuntimeError
+debugger_inspect_test: SkipByDesign
 debugger_location_second_test: Skip, Timeout
 debugger_location_test: Skip, Timeout
 debugging_inlined_finally_test: Skip, Timeout
-debugging_test: RuntimeError
-dev_fs_spawn_test: RuntimeError
+debugging_test: SkipByDesign
+dev_fs_spawn_test: SkipByDesign
 developer_extension_test: Skip, Timeout
 developer_service_get_isolate_id_test: Skip, Timeout
-eval_internal_class_test: RuntimeError
+eval_internal_class_test: SkipByDesign
 eval_regression_flutter20255_test: Skip, Timeout
 eval_test: Skip, Timeout
 evaluate_activation_in_method_class_test: Skip, Timeout
-evaluate_activation_test: RuntimeError
-evaluate_async_closure_test: RuntimeError
+evaluate_activation_test: SkipByDesign
+evaluate_async_closure_test: SkipByDesign
 evaluate_class_type_parameters_test: Skip, Timeout
 evaluate_function_type_parameters_test: Skip, Timeout
 evaluate_in_async_activation_test: Skip, Timeout
@@ -93,22 +93,22 @@
 evaluate_in_frame_rpc_test: Skip, Timeout
 evaluate_in_frame_with_scope_test: Skip, Timeout
 evaluate_in_sync_star_activation_test: Skip, Timeout
-evaluate_with_escaping_closure_test: RuntimeError
-evaluate_with_scope_test: RuntimeError
-field_script_test: RuntimeError
+evaluate_with_escaping_closure_test: SkipByDesign
+evaluate_with_scope_test: SkipByDesign
+field_script_test: SkipByDesign
 get_allocation_samples_test: Skip, Timeout
 get_isolate_after_language_error_test: CompileTimeError
-get_object_rpc_test: RuntimeError
+get_object_rpc_test: SkipByDesign
 get_source_report_test: Skip, Timeout
 get_source_report_with_mixin_test: Skip, Timeout
 get_stack_rpc_test: Skip, Timeout
-implicit_getter_setter_test: RuntimeError
+implicit_getter_setter_test: SkipByDesign
 invoke_test: Skip, Timeout
-isolate_lifecycle_test: RuntimeError
-issue_25465_test: RuntimeError
+isolate_lifecycle_test: SkipByDesign
+issue_25465_test: SkipByDesign
 issue_27238_test: Skip, Timeout
 issue_27287_test: Skip, Timeout
-issue_30555_test: RuntimeError
+issue_30555_test: SkipByDesign
 kill_paused_test: Skip, Timeout
 library_dependency_test: CompileTimeError
 local_variable_declaration_test: Skip, Timeout
@@ -116,68 +116,68 @@
 mirror_references_test: CompileTimeError
 mixin_break_test: Skip, Timeout
 network_profiling_test: Skip, Timeout
-next_through_assign_call_test: RuntimeError
-next_through_assign_int_test: RuntimeError
-next_through_await_for_test: RuntimeError
-next_through_call_on_field_in_class_test: RuntimeError
-next_through_call_on_field_test: RuntimeError
-next_through_call_on_static_field_in_class_test: RuntimeError
-next_through_catch_test: RuntimeError
-next_through_closure_test: RuntimeError
-next_through_create_list_and_map_test: RuntimeError
-next_through_for_each_loop_test: RuntimeError
-next_through_for_loop_with_break_and_continue_test: RuntimeError
-next_through_function_expression_test: RuntimeError
-next_through_implicit_call_test: RuntimeError
-next_through_is_and_as_test: RuntimeError
-next_through_multi_catch_test: RuntimeError
-next_through_new_test: RuntimeError
-next_through_operator_bracket_on_super_test: RuntimeError
-next_through_operator_bracket_on_this_test: RuntimeError
-next_through_operator_bracket_test: RuntimeError
-next_through_simple_async_test: RuntimeError
-next_through_simple_async_with_returns_test: RuntimeError
-next_through_simple_linear_2_test: RuntimeError
-next_through_simple_linear_test: RuntimeError
+next_through_assign_call_test: SkipByDesign
+next_through_assign_int_test: SkipByDesign
+next_through_await_for_test: SkipByDesign
+next_through_call_on_field_in_class_test: SkipByDesign
+next_through_call_on_field_test: SkipByDesign
+next_through_call_on_static_field_in_class_test: SkipByDesign
+next_through_catch_test: SkipByDesign
+next_through_closure_test: SkipByDesign
+next_through_create_list_and_map_test: SkipByDesign
+next_through_for_each_loop_test: SkipByDesign
+next_through_for_loop_with_break_and_continue_test: SkipByDesign
+next_through_function_expression_test: SkipByDesign
+next_through_implicit_call_test: SkipByDesign
+next_through_is_and_as_test: SkipByDesign
+next_through_multi_catch_test: SkipByDesign
+next_through_new_test: SkipByDesign
+next_through_operator_bracket_on_super_test: SkipByDesign
+next_through_operator_bracket_on_this_test: SkipByDesign
+next_through_operator_bracket_test: SkipByDesign
+next_through_simple_async_test: SkipByDesign
+next_through_simple_async_with_returns_test: SkipByDesign
+next_through_simple_linear_2_test: SkipByDesign
+next_through_simple_linear_test: SkipByDesign
 parameters_in_scope_at_entry_test: Skip, Timeout
 pause_idle_isolate_test: Skip, Timeout
-pause_on_exceptions_test: RuntimeError
-pause_on_start_then_step_test: RuntimeError
-pause_on_unhandled_async_exceptions2_test: RuntimeError
-pause_on_unhandled_async_exceptions3_test: RuntimeError
-pause_on_unhandled_async_exceptions_test: RuntimeError
-pause_on_unhandled_exceptions_test: RuntimeError
+pause_on_exceptions_test: SkipByDesign
+pause_on_start_then_step_test: SkipByDesign
+pause_on_unhandled_async_exceptions2_test: SkipByDesign
+pause_on_unhandled_async_exceptions3_test: SkipByDesign
+pause_on_unhandled_async_exceptions_test: SkipByDesign
+pause_on_unhandled_exceptions_test: SkipByDesign
 positive_token_pos_test: Skip, Timeout
-regress_28443_test: RuntimeError
-regress_28980_test: RuntimeError
+regress_28443_test: SkipByDesign
+regress_28980_test: SkipByDesign
 regress_34841_test: Skip, Timeout
 reload_sources_test: Skip, Timeout
 rewind_optimized_out_test: Skip, Timeout
 rewind_test: Skip, Timeout
 set_library_debuggable_test: Skip, Timeout
-simple_reload_test: RuntimeError
-steal_breakpoint_test: RuntimeError
+simple_reload_test: SkipByDesign
+steal_breakpoint_test: SkipByDesign
 step_into_async_no_await_test: Skip, Timeout
 step_over_await_test: Skip, Timeout
-step_test: RuntimeError
-step_through_arithmetic_test: RuntimeError
-step_through_constructor_calls_test: RuntimeError
-step_through_constructor_test: RuntimeError
-step_through_for_each_sync_star_2_test: RuntimeError
-step_through_for_each_sync_star_test: RuntimeError
-step_through_function_2_test: RuntimeError
-step_through_function_test: RuntimeError
-step_through_getter_test: RuntimeError
-step_through_mixin_from_sdk_test: RuntimeError
-step_through_property_get_test: RuntimeError
-step_through_property_set_test: RuntimeError
-step_through_setter_test: RuntimeError
-step_through_switch_test: RuntimeError
-step_through_switch_with_continue_test: RuntimeError
+step_test: SkipByDesign
+step_through_arithmetic_test: SkipByDesign
+step_through_constructor_calls_test: SkipByDesign
+step_through_constructor_test: SkipByDesign
+step_through_for_each_sync_star_2_test: SkipByDesign
+step_through_for_each_sync_star_test: SkipByDesign
+step_through_function_2_test: SkipByDesign
+step_through_function_test: SkipByDesign
+step_through_getter_test: SkipByDesign
+step_through_mixin_from_sdk_test: SkipByDesign
+step_through_property_get_test: SkipByDesign
+step_through_property_set_test: SkipByDesign
+step_through_setter_test: SkipByDesign
+step_through_switch_test: SkipByDesign
+step_through_switch_with_continue_test: SkipByDesign
 valid_source_locations_test: Skip, Timeout
 vm_timeline_flags_test: Skip, Timeout
 weak_properties_test: CompileTimeError
-yield_positions_with_finally_test: RuntimeError
+yield_positions_with_finally_test: SkipByDesign
 
 [ $fasta ]
 get_isolate_after_language_error_test: CompileTimeError
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
index 85df4f6..673f589 100644
--- a/runtime/observatory/tests/service/service_test_common.dart
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:io' show Platform;
+import 'package:dds/dds.dart';
 import 'package:observatory/models.dart' as M;
 import 'package:observatory/service_common.dart';
 import 'package:observatory/service_io.dart';
@@ -13,6 +14,7 @@
 
 typedef Future IsolateTest(Isolate isolate);
 typedef Future VMTest(VM vm);
+typedef Future DDSTest(VM vm, DartDevelopmentService dds);
 typedef void ServiceEventHandler(ServiceEvent event);
 
 Map<String, StreamSubscription> streamSubscriptions = {};
diff --git a/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart b/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
index 1a5c8fd..1e2753e 100644
--- a/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
+++ b/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
@@ -54,30 +54,6 @@
     }
     expect(caughtException, isTrue);
   },
-
-  // illegal (dart:_*) library.
-  (Isolate isolate) async {
-    await isolate.load();
-    Library dartInternal = isolate.libraries
-        .firstWhere((Library library) => library.uri == 'dart:_internal');
-    var params = {
-      'libraryId': dartInternal.id,
-      'isDebuggable': false,
-    };
-    bool caughtException;
-    try {
-      await isolate.invokeRpcNoUpgrade('setLibraryDebuggable', params);
-      expect(false, isTrue, reason: 'Unreachable');
-    } on ServerRpcException catch (e) {
-      caughtException = true;
-      expect(e.code, equals(ServerRpcException.kInvalidParams));
-      expect(
-          e.message,
-          "setLibraryDebuggable: "
-          "illegal 'libraryId' parameter: ${dartInternal.id}");
-    }
-    expect(caughtException, isTrue);
-  },
 ];
 
 main(args) async => runIsolateTests(args, tests);
diff --git a/runtime/observatory/tests/service/stream_subscription_test.dart b/runtime/observatory/tests/service/stream_subscription_test.dart
new file mode 100644
index 0000000..56f8420
--- /dev/null
+++ b/runtime/observatory/tests/service/stream_subscription_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'test_helper.dart';
+
+Future streamListen(VM vm, String streamId) async =>
+    await vm.invokeRpcNoUpgrade(
+      'streamListen',
+      {
+        'streamId': streamId,
+      },
+    );
+
+Future streamCancel(VM vm, String streamId) async =>
+    await vm.invokeRpcNoUpgrade(
+      'streamCancel',
+      {
+        'streamId': streamId,
+      },
+    );
+
+var tests = <VMTest>[
+  // Check double subscription fails.
+  (VM vm) async {
+    await streamListen(vm, '_Echo');
+    try {
+      await streamListen(vm, '_Echo');
+      fail('Subscribed to stream twice');
+    } on ServerRpcException catch (e) {
+      expect(e.message, 'Stream already subscribed');
+    }
+  },
+  // Check double cancellation fails.
+  (VM vm) async {
+    await streamCancel(vm, '_Echo');
+    try {
+      await streamCancel(vm, '_Echo');
+      fail('Double cancellation of stream successful');
+    } on ServerRpcException catch (e) {
+      expect(e.message, 'Stream not subscribed');
+    }
+  },
+  // Check subscription to invalid stream fails.
+  (VM vm) async {
+    try {
+      await streamListen(vm, 'Foo');
+      fail('Subscribed to invalid stream');
+    } on ServerRpcException catch (e) {
+      expect(e.message, "streamListen: invalid 'streamId' parameter: Foo");
+    }
+  }
+];
+
+main(args) => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 1dd5989..a63bc14 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -7,15 +7,19 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'package:dds/dds.dart';
 import 'package:observatory/service_io.dart';
 import 'package:test/test.dart';
 import 'service_test_common.dart';
-export 'service_test_common.dart' show IsolateTest, VMTest;
+export 'service_test_common.dart' show DDSTest, IsolateTest, VMTest;
 
 /// Whether to use causal async stacks (if not we use lazy async stacks).
 const bool useCausalAsyncStacks =
     const bool.fromEnvironment('dart.developer.causal_async_stacks');
 
+/// Determines whether DDS is enabled for this test run.
+const bool useDds = const bool.fromEnvironment('USE_DDS');
+
 /// The extra arguments to use
 const List<String> extraDebuggingArgs = useCausalAsyncStacks
     ? const ['--causal-async-stacks', '--no-lazy-async-stacks']
@@ -97,6 +101,8 @@
 class _ServiceTesteeLauncher {
   Process process;
   final List<String> args;
+  Future<void> get exited => _processCompleter.future;
+  final _processCompleter = Completer<void>();
   bool killedByTester = false;
 
   _ServiceTesteeLauncher() : args = [Platform.script.toFilePath()] {}
@@ -286,6 +292,7 @@
           throw "Testee exited with $exitCode";
         }
         print("** Process exited");
+        _processCompleter.complete();
       });
 
       // Wait for the blank line which signals that we're ready to run.
@@ -295,9 +302,16 @@
       }
       final content = await serviceInfoFile.readAsString();
       final infoJson = json.decode(content);
-      uri = Uri.parse(infoJson['uri']);
+      String rawUri = infoJson['uri'];
+
+      // If rawUri ends with a /, Uri.parse will include an empty string as the
+      // last path segment. Make sure it's not there to ensure we have a
+      // consistent Uri.
+      if (rawUri.endsWith('/')) {
+        rawUri = rawUri.substring(0, rawUri.length - 1);
+      }
+      uri = Uri.parse(rawUri);
       completer.complete(uri);
-      print('** Signaled to run test queries on $uri');
     });
     return completer.future;
   }
@@ -314,7 +328,7 @@
 
 void setupAddresses(Uri serverAddress) {
   serviceWebsocketAddress =
-      'ws://${serverAddress.authority}${serverAddress.path}ws';
+      'ws://${serverAddress.authority}${serverAddress.path}/ws';
   serviceHttpAddress = 'http://${serverAddress.authority}${serverAddress.path}';
 }
 
@@ -323,86 +337,135 @@
     List<String> mainArgs,
     List<String> extraArgs,
     List<String> executableArgs,
-    List<VMTest> vmTests,
+    List<DDSTest> ddsTests,
     List<IsolateTest> isolateTests,
+    List<VMTest> vmTests,
     bool pause_on_start: false,
     bool pause_on_exit: false,
     bool verbose_vm: false,
     bool pause_on_unhandled_exceptions: false,
     bool enable_service_port_fallback: false,
     bool testeeControlsServer: false,
+    bool enableDds: true,
     int port = 0,
   }) {
     if (executableArgs == null) {
       executableArgs = Platform.executableArguments;
     }
-
-    final process = new _ServiceTesteeLauncher();
-    final name = Platform.script.pathSegments.last;
+    DartDevelopmentService dds;
     WebSocketVM vm;
-    setUp(() async {
-      await process
-          .launch(
-              pause_on_start,
-              pause_on_exit,
-              pause_on_unhandled_exceptions,
-              enable_service_port_fallback,
-              testeeControlsServer,
-              port,
-              extraArgs,
-              executableArgs)
-          .then((Uri serverAddress) async {
-        if (mainArgs.contains("--gdb")) {
-          final pid = process.process.pid;
-          final wait = new Duration(seconds: 10);
-          print("Testee has pid $pid, waiting $wait before continuing");
-          sleep(wait);
-        }
-        setupAddresses(serverAddress);
-        vm = new WebSocketVM(new WebSocketVMTarget(serviceWebsocketAddress));
-        print('Loading VM...');
-        await vm.load();
-        print('Done loading VM');
-      });
-    });
+    _ServiceTesteeLauncher process;
+    bool testsDone = false;
 
-    test(
-      name,
-      () async {
-        // Run vm tests.
-        if (vmTests != null) {
-          int testIndex = 1;
-          final totalTests = vmTests.length;
-          for (var test in vmTests) {
-            vm.verbose = verbose_vm;
-            print('Running $name [$testIndex/$totalTests]');
-            testIndex++;
-            await test(vm);
-          }
+    ignoreLateException(Function f) async {
+      try {
+        await f();
+      } catch (error, stackTrace) {
+        if (testsDone) {
+          print('Ignoring late exception during process exit:\n'
+              '$error\n$stackTrace');
+        } else {
+          rethrow;
         }
+      }
+    }
 
-        // Run isolate tests.
-        if (isolateTests != null) {
-          final isolate = await getFirstIsolate(vm);
-          int testIndex = 1;
-          final totalTests = isolateTests.length;
-          for (var test in isolateTests) {
-            vm.verbose = verbose_vm;
-            print('Running $name [$testIndex/$totalTests]');
-            testIndex++;
-            await test(isolate);
-          }
-        }
-      },
-      retry: 0,
-      // Some service tests run fairly long (e.g., valid_source_locations_test).
-      timeout: Timeout.none,
+    setUp(
+      () => ignoreLateException(
+        () async {
+          process = _ServiceTesteeLauncher();
+          await process
+              .launch(
+                  pause_on_start,
+                  pause_on_exit,
+                  pause_on_unhandled_exceptions,
+                  enable_service_port_fallback,
+                  testeeControlsServer,
+                  port,
+                  extraArgs,
+                  executableArgs)
+              .then((Uri serverAddress) async {
+            if (mainArgs.contains("--gdb")) {
+              final pid = process.process.pid;
+              final wait = new Duration(seconds: 10);
+              print("Testee has pid $pid, waiting $wait before continuing");
+              sleep(wait);
+            }
+            if (useDds) {
+              dds = await DartDevelopmentService.startDartDevelopmentService(
+                  serverAddress);
+              setupAddresses(dds.uri);
+            } else {
+              setupAddresses(serverAddress);
+            }
+            print('** Signaled to run test queries on $serviceHttpAddress'
+                ' (${useDds ? "DDS" : "VM Service"})');
+            vm =
+                new WebSocketVM(new WebSocketVMTarget(serviceWebsocketAddress));
+            print('Loading VM...');
+            await vm.load();
+            print('Done loading VM');
+          });
+        },
+      ),
     );
 
-    tearDown(() {
-      print('All service tests completed successfully.');
-      process.requestExit();
-    });
+    tearDown(
+      () => ignoreLateException(
+        () async {
+          if (useDds) {
+            await dds.shutdown();
+          }
+          process.requestExit();
+        },
+      ),
+    );
+
+    final name = Platform.script.pathSegments.last;
+    runTest(String name) {
+      test(
+        '$name (${useDds ? 'DDS' : 'VM Service'})',
+        () => ignoreLateException(
+          () async {
+            // Run vm tests.
+            if (vmTests != null) {
+              int testIndex = 1;
+              final totalTests = vmTests.length;
+              for (var test in vmTests) {
+                vm.verbose = verbose_vm;
+                print('Running $name [$testIndex/$totalTests]');
+                testIndex++;
+                await test(vm);
+              }
+            }
+
+            // Run isolate tests.
+            if (isolateTests != null) {
+              final isolate = await getFirstIsolate(vm);
+              int testIndex = 1;
+              final totalTests = isolateTests.length;
+              for (var test in isolateTests) {
+                vm.verbose = verbose_vm;
+                print('Running $name [$testIndex/$totalTests]');
+                testIndex++;
+                await test(isolate);
+              }
+            }
+
+            print('All service tests completed successfully.');
+            testsDone = true;
+          },
+        ),
+        // Some service tests run fairly long (e.g., valid_source_locations_test).
+        timeout: Timeout.none,
+      );
+    }
+
+    if ((useDds && !enableDds) || (!useDds && ddsTests != null)) {
+      print('Skipping DDS run for $name');
+      return;
+    }
+    runTest(name);
   }
 
   Future<Isolate> getFirstIsolate(WebSocketVM vm) async {
@@ -460,6 +523,7 @@
     bool verbose_vm: false,
     bool pause_on_unhandled_exceptions: false,
     bool testeeControlsServer: false,
+    bool enableDds: true,
     List<String> extraArgs}) async {
   assert(!pause_on_start || testeeBefore == null);
   if (_isTestee()) {
@@ -477,7 +541,8 @@
         pause_on_exit: pause_on_exit,
         verbose_vm: verbose_vm,
         pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
-        testeeControlsServer: testeeControlsServer);
+        testeeControlsServer: testeeControlsServer,
+        enableDds: enableDds);
   }
 }
 
@@ -517,7 +582,7 @@
   }
 }
 
-/// Runs [tests] in sequence, each of which should take an [Isolate] and
+/// Runs [tests] in sequence, each of which should take a [VM] and
 /// return a [Future]. Code for setting up state can run before and/or
 /// concurrently with the tests. Uses [mainArgs] to determine whether
 /// to run tests or testee in this invocation of the script.
@@ -529,6 +594,46 @@
     bool verbose_vm: false,
     bool pause_on_unhandled_exceptions: false,
     bool enable_service_port_fallback: false,
+    bool enableDds: true,
+    int port = 0,
+    List<String> extraArgs,
+    List<String> executableArgs}) async {
+  if (_isTestee()) {
+    new _ServiceTesteeRunner().run(
+        testeeBefore: testeeBefore,
+        testeeConcurrent: testeeConcurrent,
+        pause_on_start: pause_on_start,
+        pause_on_exit: pause_on_exit);
+  } else {
+    new _ServiceTesterRunner().run(
+      mainArgs: mainArgs,
+      extraArgs: extraArgs,
+      executableArgs: executableArgs,
+      vmTests: tests,
+      pause_on_start: pause_on_start,
+      pause_on_exit: pause_on_exit,
+      verbose_vm: verbose_vm,
+      pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
+      enable_service_port_fallback: enable_service_port_fallback,
+      enableDds: enableDds,
+      port: port,
+    );
+  }
+}
+
+/// Runs [tests] in sequence, each of which should take a [VM] and
+/// [DartDevelopmentService] and return a [Future]. Code for setting up state
+/// can run before and/or concurrently with the tests. Uses [mainArgs] to
+/// determine whether to run tests or testee in this invocation of the
+/// script.
+Future runDDSTests(List<String> mainArgs, List<DDSTest> tests,
+    {testeeBefore(),
+    testeeConcurrent(),
+    bool pause_on_start: false,
+    bool pause_on_exit: false,
+    bool verbose_vm: false,
+    bool pause_on_unhandled_exceptions: false,
+    bool enable_service_port_fallback: false,
     int port = 0,
     List<String> extraArgs,
     List<String> executableArgs}) async {
@@ -543,12 +648,13 @@
       mainArgs: mainArgs,
       extraArgs: extraArgs,
       executableArgs: executableArgs,
-      vmTests: tests,
+      ddsTests: tests,
       pause_on_start: pause_on_start,
       pause_on_exit: pause_on_exit,
       verbose_vm: verbose_vm,
       pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
       enable_service_port_fallback: enable_service_port_fallback,
+      enableDds: true,
       port: port,
     );
   }
diff --git a/runtime/observatory/tests/service/verify_http_timeline_test.dart b/runtime/observatory/tests/service/verify_http_timeline_test.dart
index a555b11..22fae9b 100644
--- a/runtime/observatory/tests/service/verify_http_timeline_test.dart
+++ b/runtime/observatory/tests/service/verify_http_timeline_test.dart
@@ -62,7 +62,7 @@
 }
 
 Future<HttpServer> startServer() async {
-  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8011);
+  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
   server.listen((request) async {
     final response = request.response;
     randomlyAddCookie(response);
diff --git a/runtime/observatory/tests/service/vm_service_dds_test.dart b/runtime/observatory/tests/service/vm_service_dds_test.dart
new file mode 100644
index 0000000..457245d
--- /dev/null
+++ b/runtime/observatory/tests/service/vm_service_dds_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:dds/dds.dart';
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'test_helper.dart';
+
+final tests = <DDSTest>[
+  (VM vm, DartDevelopmentService dds) async {
+    final client = WebSocketVM(
+      WebSocketVMTarget(
+        dds.remoteVmServiceWsUri.toString(),
+      ),
+    );
+    expect(client.wasOrIsConnected, false);
+    try {
+      await client.load();
+      fail(
+          'When DDS is connected, direct connections to the VM service should fail.');
+    } on NetworkRpcException catch (e) {
+      expect(e.message, 'WebSocket closed due to error');
+    }
+    expect(client.wasOrIsConnected, false);
+  }
+];
+
+main(args) async => runDDSTests(args, tests);
diff --git a/runtime/observatory/tests/service/vm_timeline_events_test.dart b/runtime/observatory/tests/service/vm_timeline_events_test.dart
index 1b77ed1..a47bcf2 100644
--- a/runtime/observatory/tests/service/vm_timeline_events_test.dart
+++ b/runtime/observatory/tests/service/vm_timeline_events_test.dart
@@ -9,10 +9,14 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
-primeDartTimeline() {
+primeDartTimeline() async {
   while (true) {
     Timeline.startSync('apple');
     Timeline.finishSync();
+    // Give the VM a chance to send the timeline events. This test is
+    // significantly slower if we loop without yielding control after each
+    // iteration.
+    await Future.delayed(const Duration(milliseconds: 1));
   }
 }
 
@@ -22,8 +26,8 @@
   return events.where(filter).toList();
 }
 
-Completer completer = new Completer();
-int eventCount = 0;
+Completer completer;
+int eventCount;
 
 onTimelineEvent(ServiceEvent event) {
   eventCount++;
@@ -35,6 +39,11 @@
 
 var tests = <IsolateTest>[
   (Isolate isolate) async {
+    // Clear global state.
+    eventCount = 0;
+    completer = Completer<void>();
+  },
+  (Isolate isolate) async {
     // Subscribe to the Timeline stream.
     await subscribeToStream(isolate.vm, VM.kTimelineStream, onTimelineEvent);
   },
diff --git a/runtime/observatory/web/index.html b/runtime/observatory/web/index.html
index 6369746..161e866 100644
--- a/runtime/observatory/web/index.html
+++ b/runtime/observatory/web/index.html
@@ -3,7 +3,6 @@
 <head>
   <meta charset="utf-8">
   <title>Dart VM Observatory</title>
-  <link rel="stylesheet" href="packages/charted/charts/themes/quantum_theme.css">
   <link rel="stylesheet" href="packages/observatory/src/elements/css/shared.css">
   <script defer src="main.dart.js"></script>
 </head>
diff --git a/runtime/observatory/web/third_party/trace_viewer_full.html b/runtime/observatory/web/third_party/trace_viewer_full.html
index a6966b4..d815ec5 100644
--- a/runtime/observatory/web/third_party/trace_viewer_full.html
+++ b/runtime/observatory/web/third_party/trace_viewer_full.html
@@ -3,6 +3,8 @@
   <head i18n-values="dir:textdirection;">
   <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
   <meta http-equiv="origin-trial" content="AnYuQDtUf6OrWCmR9Okd67JhWVTbmnRedvPi1TEvAxac8+1p6o9q08FoDO6oCbLD0xEqev+SkZFiIhFSzlY9HgUAAABxeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXVzZXJjb250ZW50LmNvbTo0NDMiLCJmZWF0dXJlIjoiV2ViQ29tcG9uZW50c1YwIiwiZXhwaXJ5IjoxNjA0NjE0NTM4LCJpc1N1YmRvbWFpbiI6dHJ1ZX0=">
+  <meta http-equiv="origin-trial" content="AkFXw3wHnOs/XXYqFXpc3diDLrRFd9PTgGs/gs43haZmngI/u1g8L4bDnSKLZkB6fecjmjTwcAMQFCpWMAoHSQEAAAB8eyJvcmlnaW4iOiJodHRwczovL2Nocm9taXVtLWJ1aWxkLXN0YXRzLmFwcHNwb3QuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJDb21wb25lbnRzVjAiLCJleHBpcnkiOjE2MTIyMjM5OTksImlzU3ViZG9tYWluIjp0cnVlfQ==">
+  <meta http-equiv="origin-trial" content="AtQY4wpX9+nj+Vn27cTgygzIPbtB2WoAoMQR5jK9mCm/H2gRIDH6MmGVAaziv9XnYTDKjhBnQYtecbTiIHCQiAIAAACEeyJvcmlnaW4iOiJodHRwczovL2Nocm9taXVtLWJ1aWxkLXN0YXRzLXN0YWdpbmcuYXBwc3BvdC5jb206NDQzIiwiZmVhdHVyZSI6IldlYkNvbXBvbmVudHNWMCIsImV4cGlyeSI6MTYxMjIyMzk5OSwiaXNTdWJkb21haW4iOnRydWV9">
 <template id="overlay-template">
   <style>
     overlay-mask {
@@ -4832,7 +4834,7 @@
 for(const rendererHelper of Object.values(this.rendererHelpers)){this.chromeBounds_.addRange(rendererHelper.process.bounds);}
 if(this.gpuHelper){this.chromeBounds_.addRange(this.gpuHelper.process.bounds);}}
 if(this.chromeBounds_.isEmpty){return undefined;}
-return this.chromeBounds_;},get telemetryHelper(){return this.telemetryHelper_;}};return{ChromeModelHelper,};});'use strict';tr.exportTo('tr.e.cc',function(){const AsyncSlice=tr.model.AsyncSlice;const EventSet=tr.model.EventSet;const UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';const ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';const BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';const END_COMP_NAME='INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT';const LEGACY_END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';const MAIN_RENDERER_THREAD_NAME='CrRendererMain';const COMPOSITOR_THREAD_NAME='Compositor';const POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';const IPC_FLOW_EVENT='disabled-by-default-ipc.flow';const INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent){this.determineModernTypeName_();}}
+return this.chromeBounds_;},get telemetryHelper(){return this.telemetryHelper_;}};return{ChromeModelHelper,};});'use strict';tr.exportTo('tr.e.cc',function(){const AsyncSlice=tr.model.AsyncSlice;const EventSet=tr.model.EventSet;const UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';const ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';const BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';const END_COMP_NAME='INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT';const LEGACY_END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';const MAIN_RENDERER_THREAD_NAME='CrRendererMain';const COMPOSITOR_THREAD_NAME='Compositor';const OLD_IPC_FLOW_EVENT='disabled-by-default-ipc.flow';const OLD_POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';const NEW_POSTTASK_FLOW_EVENT='toplevel.flow';const INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent){this.determineModernTypeName_();}}
 InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_){this.determineLegacyTypeName_();}
 return this.typeName_;},checkTypeName_(){if(!this.typeName_){throw new Error('Unable to determine typeName');}
 let found=false;for(const typeName in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[typeName]){found=true;break;}}
@@ -4844,14 +4846,14 @@
 const rendererHelpers=modelHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(let i=0;i<pids.length;i++){const pid=pids[i];const rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread){return rendererHelper;}}
 return undefined;},addEntireSliceHierarchy(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents(flowEvents){const slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);const newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1){slices.push(newSource);}},this);const lastFlowEvent=flowEvents[flowEvents.length-1];const lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1){slices.push(lastSource);}
 return slices;},belongToOtherInputs(slice,flowEvents){let fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1){fromOtherInputs=true;}}},this);},this);return fromOtherInputs;},triggerOtherInputs(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0){return false;}
-const flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice){return false;}
+const flow=event.outFlowEvents[0];const isPostTask=flow.category===NEW_POSTTASK_FLOW_EVENT||flow.category===OLD_POSTTASK_FLOW_EVENT;if(!isPostTask||!flow.endSlice){return false;}
 const endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents)){return true;}
 return false;},followSubsequentSlices(event,queue,visited,flowEvents){let stopFollowing=false;let inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)return;if(slice.title==='TaskQueueManager::RunTask')return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame'){return;}
 if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))return;}
 if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))return;}
 if(slice.title==='InputRouterImpl::ProcessInputEventAck'){inputAck=true;}
 if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent'){stopFollowing=true;}
-this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);const nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw(beginImplFrame,visited){const pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){const nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start){return a.start-b.start;}
+this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===NEW_POSTTASK_FLOW_EVENT||outflow.category===OLD_POSTTASK_FLOW_EVENT||outflow.category===OLD_IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);const nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw(beginImplFrame,visited){const pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){const nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start){return a.start-b.start;}
 return a.guid-b.guid;});},addRasterizationEvents(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads){return;}
 const rasterWorkerThreads=rendererHelper.rasterWorkerThreads;const prepareTileId=prepareTiles.args.prepare_tiles_id;const pendingEventQueue=[];if(sortedRasterizerSlices.length===0){this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);}
 let numFinishedTasks=0;const RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';const IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';const FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(let i=0;i<sortedRasterizerSlices.length;i++){const task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepareTileId){this.addEntireSliceHierarchy(task.mostTopLevelSlice);}}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)break;}}}
@@ -5173,7 +5175,7 @@
 for(let i=0;i<this.asyncSliceGroup.length;i++){categoriesDict[this.asyncSliceGroup.slices[i].category]=true;}
 if(this.samples_){for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}}},autoCloseOpenSlices(){this.sliceGroup.autoCloseOpenSlices();this.asyncSliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland(){if(this.kernelSliceGroup.length>0){const newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(sample=>sample.thread===this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
 (this.name?', name: '+this.name:'');},getSettingsKey(){if(!this.name)return undefined;const parentKey=this.parent.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},getProcess(){return this.parent;},indexOfTimeSlice(timeSlice){const i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)return undefined;return i;},sumOverToplevelSlicesInRange(range,func){let sum=0;tr.b.iterateOverIntersectingIntervals(this.sliceGroup.topLevelSlices,slice=>slice.start,slice=>slice.end,range.min,range.max,slice=>{let fractionOfSliceInsideRangeOfInterest=1;if(slice.duration>0){const intersection=range.findIntersection(slice.range);fractionOfSliceInsideRangeOfInterest=intersection.duration/slice.duration;}
-sum+=func(slice)*fractionOfSliceInsideRangeOfInterest;});return sum;},getCpuTimeForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>slice.cpuDuration||0);},getNumToplevelSlicesForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>1);},getSchedulingStatsForRange(start,end){const stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const overlapStart=Math.max(threadTimeSlice.start,start);const overlapEnd=Math.min(threadTimeSlice.end,end);const schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
+sum+=func(slice)*fractionOfSliceInsideRangeOfInterest;});return sum;},getCpuTimeForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>slice.cpuDuration||0);},getNumToplevelSlicesForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>1);},getWallTimeForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>slice.duration||0);},getSchedulingStatsForRange(start,end){const stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const overlapStart=Math.max(threadTimeSlice.start,start);const overlapEnd=Math.min(threadTimeSlice.end,end);const schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
 tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;},get type(){const re=/^[^0-9|\/]+/;const matches=re.exec(this.name);if(matches&&matches[0])return matches[0];throw new Error('Could not determine thread type for thread name '+
 this.name);}};Thread.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp)return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)return tmp;if(x.name!==undefined){if(y.name!==undefined){tmp=x.name.localeCompare(y.name);}else{tmp=-1;}}else if(y.name!==undefined){tmp=1;}
 if(tmp)return tmp;return x.tid-y.tid;};return{Thread,};});'use strict';tr.exportTo('tr.model',function(){const Thread=tr.model.Thread;const Counter=tr.model.Counter;function ProcessBase(model){if(!model){throw new Error('Must provide a model');}
@@ -8291,7 +8293,7 @@
 if(slice.title==='RenderAccessibilityImpl::SendLocationChanges'){renderAccessibilityLocationsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}}}
 for(const browserHelper of Object.values(chromeHelper.browserHelpers)){const mainThread=browserHelper.mainThread;if(mainThread===undefined)continue;for(const slice of mainThread.getDescendantEvents()){if(slice.title==='BrowserAccessibilityManager::OnAccessibilityEvents'){browserAccessibilityEventsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}}}
 histograms.addHistogram(browserAccessibilityEventsHist);histograms.addHistogram(renderAccessibilityEventsHist);histograms.addHistogram(renderAccessibilityLocationsHist);}
-tr.metrics.MetricRegistry.register(accessibilityMetric);return{accessibilityMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MESSAGE_LOOP_EVENT_NAME='Startup.BrowserMessageLoopStartTimeFromMainEntry3';const CONTENT_START_EVENT_NAME='content::Start';const NAVIGATION_EVENT_NAME='Navigation StartToCommit';const FIRST_CONTENTFUL_PAINT_EVENT_NAME='firstContentfulPaint';function androidStartupMetric(histograms,model){let messageLoopStartEvents=[];let navigationEvents=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;for(const helper of chromeHelper.browserHelpers){for(const ev of helper.mainThread.asyncSliceGroup.childEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}}}
+tr.metrics.MetricRegistry.register(accessibilityMetric);return{accessibilityMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MESSAGE_LOOP_EVENT_NAME='Startup.BrowserMessageLoopStartTime';const CONTENT_START_EVENT_NAME='content::Start';const NAVIGATION_EVENT_NAME='Navigation StartToCommit';const FIRST_CONTENTFUL_PAINT_EVENT_NAME='firstContentfulPaint';function androidStartupMetric(histograms,model){let messageLoopStartEvents=[];let navigationEvents=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;for(const helper of chromeHelper.browserHelpers){for(const ev of helper.mainThread.asyncSliceGroup.childEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}}}
 let contentStartEvents=[];let firstContentfulPaintEvents=[];const rendererHelpers=chromeHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(!rendererHelper.mainThread)continue;for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title===FIRST_CONTENTFUL_PAINT_EVENT_NAME){firstContentfulPaintEvents.push(ev);break;}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}}
 let totalBrowserStarts=messageLoopStartEvents.length;let totalContentStartEvents=contentStartEvents.length;let totalFcpEvents=firstContentfulPaintEvents.length;let totalNavigations=navigationEvents.length;if(totalFcpEvents!==totalBrowserStarts||totalNavigations!==totalBrowserStarts||totalContentStartEvents!==totalBrowserStarts||totalBrowserStarts===0){messageLoopStartEvents=[];contentStartEvents=[];navigationEvents=[];firstContentfulPaintEvents=[];for(const proc of Object.values(model.processes)){for(const ev of proc.getDescendantEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}
 for(const ev of proc.getDescendantEvents()){if(ev.title===FIRST_CONTENTFUL_PAINT_EVENT_NAME){firstContentfulPaintEvents.push(ev);break;}}}
@@ -8385,28 +8387,32 @@
 while(right.lastIndex<points.length){const distanceUntilNextPoint=Math.min(left.distanceUntilNextPoint,right.distanceUntilNextPoint);const position1=left.position;const value1=right.cummulativePause-left.cummulativePause;left.advance(distanceUntilNextPoint);right.advance(distanceUntilNextPoint);if(distanceUntilNextPoint>0){const position2=left.position;const value2=right.cummulativePause-left.cummulativePause;mu.push(position1,1.0-value1/timeWindow,position2,1.0-value2/timeWindow);}}
 return mu;}
 function addMutatorUtilization(metricName,eventFilter,timeWindows,rendererHelpers,histograms){const histogramMap=new Map();for(const timeWindow of timeWindows){const summaryOptions={avg:false,count:false,max:false,min:true,std:false,sum:false};const description=`The minimum mutator utilization in ${timeWindow}ms time window`;const histogram=histograms.createHistogram(`${metricName}-${timeWindow}ms_window`,tr.b.Unit.byName.normalizedPercentage_biggerIsBetter,[],{summaryOptions,description});histogramMap.set(timeWindow,histogram);}
-for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const pauses=[];for(const event of rendererHelper.mainThread.sliceGroup.childEvents()){if(eventFilter(event)&&event.end>event.start){pauses.push({start:event.start,end:event.end});}}
+for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;if(rendererHelper.mainThread===undefined)continue;const pauses=[];for(const event of rendererHelper.mainThread.sliceGroup.childEvents()){if(eventFilter(event)&&event.end>event.start){pauses.push({start:event.start,end:event.end});}}
 pauses.sort((a,b)=>a.start-b.start);const start=rendererHelper.mainThread.bounds.min;const end=rendererHelper.mainThread.bounds.max;for(const timeWindow of timeWindows){const mu=mutatorUtilization(start,end,timeWindow,pauses);histogramMap.get(timeWindow).addSample(mu.min);}}}
-return{addMutatorUtilization,findParent,forcedGCEventName,filterEvents,groupAndProcessEvents,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMarkCompactorSummaryEvent,isMarkCompactorMarkingSummaryEvent,isMemoryMarkCompactorEvent,isNotForcedMarkCompactorEvent,isNotForcedTopGarbageCollectionEvent,isNotForcedSubGarbageCollectionEvent,isScavengerEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,isV8RCSEvent,isCompileRCSCategory,isCompileOptimizeRCSCategory,isCompileUnoptimizeRCSCategory,isCompileParseRCSCategory,mutatorUtilization,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,topGarbageCollectionEventNames,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_TOP_UNIFIED_GC_MARKING_EVENTS={'BlinkGC.UnifiedMarkingStep':'blink-gc-unified-marking-by-v8'};const BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS=Object.assign({'BlinkGC.AtomicPauseMarkEpilogue':'blink-gc-atomic-pause-mark-epilogue','BlinkGC.AtomicPauseMarkPrologue':'blink-gc-atomic-pause-mark-prologue','BlinkGC.AtomicPauseMarkRoots':'blink-gc-atomic-pause-mark-roots','BlinkGC.AtomicPauseMarkTransitiveClosure':'blink-gc-atomic-pause-mark-transitive-closure','BlinkGC.IncrementalMarkingStartMarking':'blink-gc-incremental-start','BlinkGC.IncrementalMarkingStep':'blink-gc-incremental-step',},BLINK_TOP_UNIFIED_GC_MARKING_EVENTS);const BLINK_TOP_GC_BACKGROUND_MARKING_EVENTS={'BlinkGC.ConcurrentMarkingStep':'blink-gc-mark-task-background'};const BLINK_TOP_GC_ROOTS_MARKING_EVENTS=['BlinkGC.VisitRoots'];const BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.IncrementalMarkingStep','BlinkGC.UnifiedMarkingStep'];const BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS={'BlinkGC.CompleteSweep':'blink-gc-complete-sweep','BlinkGC.LazySweepInIdle':'blink-gc-sweep-task-foreground','BlinkGC.LazySweepOnAllocation':'blink-gc-sweep-allocation'};const BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS={'BlinkGC.ConcurrentSweepingStep':'blink-gc-sweep-task-background'};const BLINK_TOP_GC_EVENTS=Object.assign({'BlinkGC.AtomicPauseSweepAndCompact':'blink-gc-atomic-pause-sweep-and-compact',},BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS,BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS);const ATOMIC_PAUSE_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.AtomicPauseSweepAndCompact'];function blinkGarbageCollectionEventName(event){return BLINK_TOP_GC_EVENTS[event.title];}
-function blinkGarbageCollectionEventNames(){return Object.values(BLINK_TOP_GC_EVENTS);}
+return{addMutatorUtilization,findParent,forcedGCEventName,filterEvents,groupAndProcessEvents,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMarkCompactorSummaryEvent,isMarkCompactorMarkingSummaryEvent,isMemoryMarkCompactorEvent,isNotForcedMarkCompactorEvent,isNotForcedTopGarbageCollectionEvent,isNotForcedSubGarbageCollectionEvent,isScavengerEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,isV8RCSEvent,isCompileRCSCategory,isCompileOptimizeRCSCategory,isCompileUnoptimizeRCSCategory,isCompileParseRCSCategory,mutatorUtilization,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,topGarbageCollectionEventNames,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP={'BlinkGC.AtomicPauseMarkEpilogue':'blink-gc-atomic-pause-mark-epilogue','BlinkGC.AtomicPauseMarkPrologue':'blink-gc-atomic-pause-mark-prologue','BlinkGC.AtomicPauseMarkRoots':'blink-gc-atomic-pause-mark-roots','BlinkGC.IncrementalMarkingStartMarking':'blink-gc-incremental-start','BlinkGC.IncrementalMarkingStep':'blink-gc-incremental-step','BlinkGC.UnifiedMarkingStep':'blink-gc-unified-marking-by-v8','BlinkGC.CompleteSweep':'blink-gc-complete-sweep','BlinkGC.LazySweepInIdle':'blink-gc-sweep-task-foreground','BlinkGC.LazySweepOnAllocation':'blink-gc-sweep-allocation','BlinkGC.AtomicPauseSweepAndCompact':'blink-gc-atomic-pause-sweep-and-compact'};const BLINK_TOP_GC_ROOTS_MARKING_EVENTS=['BlinkGC.VisitRoots'];const BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure'];const BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.IncrementalMarkingStep','BlinkGC.UnifiedMarkingStep'];const BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.IncrementalMarkingStartMarking',].concat(BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS);const BLINK_TOP_GC_BACKGROUND_MARKING_EVENTS=['BlinkGC.ConcurrentMarkingStep'];const BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS=['BlinkGC.CompleteSweep','BlinkGC.LazySweepInIdle','BlinkGC.LazySweepOnAllocation'];const BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS=['BlinkGC.ConcurrentSweepingStep'];const BLINK_TOP_GC_EVENTS=Object.keys(BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP).concat(BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS);const ATOMIC_PAUSE_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.AtomicPauseSweepAndCompact'];function blinkGarbageCollectionEventName(event){return BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP[event.title];}
+function blinkGarbageCollectionEventNames(){return Object.values(BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP);}
 function isNonForcedEvent(event){return(!event.args||!event.args.forced)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
-function isNonForcedBlinkGarbageCollectionEvent(event){return event.title in BLINK_TOP_GC_EVENTS&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionEvent(event){return BLINK_TOP_GC_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
+function isNonForcedNonAggregatedBlinkGarbageCollectionEvent(event){return event.title in BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP&&isNonForcedEvent(event);}
 function isNonForcedBlinkGarbageCollectionAtomicPauseEvent(event){return ATOMIC_PAUSE_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
 function isNonForcedBlinkGarbageCollectionRootsMarkingEvent(event){return BLINK_TOP_GC_ROOTS_MARKING_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
 function
 isNonForcedBlinkGarbageCollectionMarkingTransitiveColsureEvent(event){return BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
-function isNonForcedBlinkGarbageCollectionForegroundMarkingEvent(event){return event.title in BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS&&isNonForcedEvent(event);}
-function isNonForcedBlinkGarbageCollectionBackgroundMarkingEvent(event){return event.title in BLINK_TOP_GC_BACKGROUND_MARKING_EVENTS&&isNonForcedEvent(event);}
-function isNonForcedBlinkGarbageCollectionForegroundSweepingEvent(event){return event.title in BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS&&isNonForcedEvent(event);}
-function isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent(event){return event.title in BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS&&isNonForcedEvent(event);}
+function
+isNonForcedBlinkGarbageCollectionAtomicPauseTransitiveColsureEvent(event){return BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionForegroundMarkingEvent(event){return BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionBackgroundMarkingEvent(event){return BLINK_TOP_GC_BACKGROUND_MARKING_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionForegroundSweepingEvent(event){return BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent(event){return BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
 function isNonNestedNonForcedBlinkGarbageCollectionEvent(event){return isNonForcedBlinkGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isGarbageCollectionEvent);}
-function blinkGcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addDurationOfAtomicPause(histograms,model);addTotalDurationOfTopEvents(histograms,model);addTotalDurationOfBlinkAndV8TopEvents(histograms,model);addTotalDurationOfRootsMarking(histograms,model);addTotalDurationOfMarkingTransitiveClosure(histograms,model);addTotalDurationOfForegroundMarking(histograms,model);addTotalDurationOfBackgroundMarking(histograms,model);addTotalDurationOfForegroundSweeping(histograms,model);addTotalDurationOfBackgroundSweeping(histograms,model);}
+function blinkGcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addDurationOfAtomicPause(histograms,model);addDurationOfAtomicPauseTransitiveClosure(histograms,model);addTotalDurationOfTopEvents(histograms,model);addTotalDurationOfBlinkAndV8TopEvents(histograms,model);addTotalDurationOfRootsMarking(histograms,model);addTotalDurationOfMarkingTransitiveClosure(histograms,model);addTotalDurationOfForegroundMarking(histograms,model);addTotalDurationOfBackgroundMarking(histograms,model);addTotalDurationOfForegroundSweeping(histograms,model);addTotalDurationOfBackgroundSweeping(histograms,model);}
 tr.metrics.MetricRegistry.register(blinkGcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
 function createNumericForTotalEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:false,count:true,max:false,min:false,std:false,sum:true,percentile:[0.90]});return n;}
 function createNumericForUnifiedEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:false,count:true,max:true,min:false,std:false,sum:true,percentile:[0.90]});return n;}
-function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedNonAggregatedBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
 histograms.addHistogram(cpuDuration);},blinkGarbageCollectionEventNames());}
 function addDurationOfAtomicPause(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionAtomicPauseEvent,event=>event.args.epoch,function(group,events){const cpuDuration=createNumericForTopEventTime('blink-gc-atomic-pause');cpuDuration.addSample(events.reduce((acc,current)=>acc+current.cpuDuration,0));histograms.addHistogram(cpuDuration);});}
+function addDurationOfAtomicPauseTransitiveClosure(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionAtomicPauseTransitiveColsureEvent,event=>event.args.epoch,function(group,events){const cpuDuration=createNumericForTopEventTime('blink-gc-atomic-pause-mark-transitive-closure');cpuDuration.addSample(events.reduce((acc,current)=>acc+current.cpuDuration,0));histograms.addHistogram(cpuDuration);});}
 function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
 histograms.addHistogram(cpuDuration);},['blink-gc-total']);}
 function addTotalDurationOfRootsMarking(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionRootsMarkingEvent,event=>'blink-gc-mark-roots',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
@@ -8493,13 +8499,13 @@
 if(isOther)yield'other';}
 function isSubset_(regexps1,regexps2){for(const r1 of regexps1){if(regexps2.find(r2=>r2.toString()===r1.toString())===undefined){return false;}}
 return true;}
-function addCpuUtilizationHistograms(histograms,model,segments,shouldNormalize,segmentCostFunc,histogramNameFunc,description,unit){if(!unit)unit=tr.b.Unit.byName.unitlessNumber;const histogramMap=new Map();for(const category of ALL_CATEGORIES){const histogram=histograms.createHistogram(histogramNameFunc(category),unit,[],{binBoundaries:tr.v.HistogramBinBoundaries.createExponential(1,50,20),description,summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histogramMap.set(category,histogram);}
+function addCpuUtilizationHistograms(histograms,model,segments,segmentCostFunc,histogramNameFunc,description,unit){if(!unit)unit=tr.b.Unit.byName.unitlessNumber;const histogramMap=new Map();for(const category of ALL_CATEGORIES){const histogram=histograms.createHistogram(histogramNameFunc(category),unit,[],{binBoundaries:tr.v.HistogramBinBoundaries.createExponential(1,50,20),description,summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histogramMap.set(category,histogram);}
 for(const[category,regexps]of CATEGORY_THREAD_MAP){const relatedCategories=new tr.v.d.RelatedNameMap();const histogram=histogramMap.get(category);for(const[otherCategory,otherRegexps]of CATEGORY_THREAD_MAP){if(otherCategory===category)continue;if(category!=='all'&&!isSubset_(otherRegexps,regexps))continue;const otherHistogram=histogramMap.get(otherCategory);relatedCategories.set(otherCategory,otherHistogram.name);}
 if([...relatedCategories.values()].length>0){histogram.diagnostics.set('breakdown',relatedCategories);}}
 for(const segment of segments){const threadValues=new Map();for(const thread of model.getAllThreads()){addValueToMap_(threadValues,thread.name||UNKNOWN_THREAD_NAME,segmentCostFunc(thread,segment));}
 const categoryValues=new Map();const breakdowns=new Map();for(const[threadName,coresPerSec]of threadValues){for(const category of getCategories_(threadName)){addValueToMap_(categoryValues,category,coresPerSec);if(!categoryShouldHaveBreakdown(category))continue;if(!breakdowns.has(category)){breakdowns.set(category,new tr.v.d.Breakdown());}
 breakdowns.get(category).set(threadName,coresPerSec);}}
-for(const category of ALL_CATEGORIES){let value=categoryValues.get(category)||0;if(shouldNormalize)value/=segment.duration;const diagnostics=new tr.v.d.DiagnosticMap();const breakdown=breakdowns.get(category);if(breakdown)diagnostics.set('breakdown',breakdown);const histogram=histogramMap.get(category);histogram.addSample(value,diagnostics);}}}
+for(const category of ALL_CATEGORIES){const value=categoryValues.get(category)||0;const diagnostics=new tr.v.d.DiagnosticMap();const breakdown=breakdowns.get(category);if(breakdown)diagnostics.set('breakdown',breakdown);const histogram=histogramMap.get(category);histogram.addSample(value,diagnostics);}}}
 const SUMMARY_OPTIONS={percentile:[0.90,0.95],ci:[0.95],};return{addCpuUtilizationHistograms,SUMMARY_OPTIONS,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const PRESENT_EVENT='Display::FrameDisplayed';const DISPLAY_EVENT='BenchmarkInstrumentation::DisplayRenderingStats';const DRM_EVENT='DrmEventFlipComplete';const SURFACE_FLINGER_EVENT='vsync_before';const COMPOSITOR_FRAME_PRESENTED_EVENT='FramePresented';const MIN_FRAME_LENGTH=0.5;const MIN_FRAME_COUNT=10;const PAUSE_THRESHOLD=20;const ASH_ENVIRONMENT='ash';const BROWSER_ENVIRONMENT='browser';class FrameEvent{constructor(event){this.event_=event;}
 get eventStart(){return this.event_.start;}
 get frameStart(){if(this.event_.title!==DRM_EVENT)return this.event_.start;const data=this.event_.args.data;const TIME=tr.b.UnitScale.TIME;return tr.b.convertUnit(data['vblank.tv_sec'],TIME.SEC,TIME.MILLI_SEC)+
@@ -8526,8 +8532,9 @@
 function computeFrameSegments_(events,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const frameEvents=events.map(e=>new FrameEvent(e));const frameSegments=[];for(const segment of segments){const filtered=segment.boundsRange.filterArray(frameEvents,x=>x.eventStart);if(filtered.length<minFrameCount)continue;for(let i=1;i<filtered.length;i++){const duration=filtered[i].frameStart-filtered[i-1].frameStart;frameSegments.push(new FrameSegment(filtered[i-1],duration));}}
 return frameSegments;}
 function addBasicFrameTimeHistograms_(histograms,frameSegments,prefix){const frameTimes=(frameSegments.length===0)?[0]:frameSegments.map(x=>x.duration);histograms.createHistogram(`${prefix}frame_times`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,frameTimes,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,50,20),description:'Raw frame times.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histograms.createHistogram(`${prefix}percentage_smooth`,tr.b.Unit.byName.unitlessNumber_biggerIsBetter,100*tr.b.math.Statistics.sum(frameTimes,(x=>(x<17?1:0)))/frameTimes.length,{description:'Percentage of frames that were hitting 60 FPS.',summaryOptions:{},});}
-function addFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const events=getDisplayCompositorPresentationEvents_(modelHelper);if(!events)return;addFrameTimeHistogramsHelper(histograms,model,segments,events,'',true,minFrameCount);const eventsExp=getDisplayCompositorPresentationEventsExp_(modelHelper);if(eventsExp&&eventsExp.length>0){addFrameTimeHistogramsHelper(histograms,model,segments,eventsExp,'exp_',minFrameCount);}}
-function addFrameTimeHistogramsHelper(histograms,model,segments,events,prefix,addCpuMetrics,minFrameCount){const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,prefix+'');if(addCpuMetrics){tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,false,(thread,segment)=>thread.getCpuTimeForRange(segment.boundsRange),category=>`thread_${category}_cpu_time_per_frame`,'CPU cores of a thread group per frame',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,false,(thread,segment)=>thread.getNumToplevelSlicesForRange(segment.boundsRange),category=>`tasks_per_frame_${category}`,'Number of tasks of a thread group per frame',tr.b.Unit.byName.unitlessNumber_smallerIsBetter);}
+function addFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const events=getDisplayCompositorPresentationEvents_(modelHelper);if(!events)return;addFrameTimeHistogramsHelper(histograms,model,segments,events,'',true,minFrameCount);const eventsExp=getDisplayCompositorPresentationEventsExp_(modelHelper);if(eventsExp&&eventsExp.length>0){addFrameTimeHistogramsHelper(histograms,model,segments,eventsExp,'exp_',false,minFrameCount);}}
+function addFrameTimeHistogramsHelper(histograms,model,segments,events,prefix,addCpuMetrics,minFrameCount){const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,prefix+'');if(addCpuMetrics){tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,(thread,segment)=>thread.getCpuTimeForRange(segment.boundsRange),category=>`thread_${category}_cpu_time_per_frame`,'CPU cores of a thread group per frame',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,(thread,segment)=>thread.getNumToplevelSlicesForRange(segment.boundsRange),category=>`tasks_per_frame_${category}`,'Number of tasks of a thread group per frame',tr.b.Unit.byName.unitlessNumber_smallerIsBetter);let totalWallTime=0;let totalCpuTime=0;for(const segment of frameSegments){for(const thread of model.getAllThreads()){totalCpuTime+=thread.getCpuTimeForRange(segment.boundsRange);totalWallTime+=thread.getWallTimeForRange(segment.boundsRange);}}
+histograms.createHistogram('cpu_wall_time_ratio',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,totalCpuTime/totalWallTime,{description:'Ratio of total cpu-time vs. wall-time.',summaryOptions:{},});}
 const refreshPeriod=getRefreshPeriod(model,frameSegments.map(fs=>fs.boundsRange));frameSegments.forEach(fs=>fs.updateLength(refreshPeriod));const validFrames=frameSegments.filter(fs=>fs.length>=MIN_FRAME_LENGTH);const totalFrameDuration=tr.b.math.Statistics.sum(frameSegments,fs=>fs.duration);addJankCountHistograms(histograms,validFrames,prefix);const frameLengths=validFrames.map(frame=>frame.length);histograms.createHistogram(prefix+'frame_lengths',tr.b.Unit.byName.unitlessNumber_smallerIsBetter,frameLengths,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,5,20),summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,description:'Frame times in vsyncs.'});histograms.createHistogram(prefix+'avg_surface_fps',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,frameLengths.length/tr.b.convertUnit(totalFrameDuration,tr.b.UnitScale.TIME.MILLI_SEC,tr.b.UnitScale.TIME.SEC),{description:'Average frames per second.',summaryOptions:{},});}
 function addUIFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const events=getUIPresentationEvents_(model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper));if(events.length===0)return;const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,'ui_');}
 function addJankCountHistograms(histograms,validFrames,prefix){const jankEvents=[];for(let i=1;i<validFrames.length;i++){const change=Math.round((validFrames[i].length-validFrames[i-1].length));if(change>0&&change<PAUSE_THRESHOLD){jankEvents.push(validFrames[i].event);}}
@@ -8575,7 +8582,7 @@
 return{addQueueingDurationHistograms,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const GESTURE_EVENT='SyntheticGestureController::running';function renderingMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;let segments=chromeHelper.telemetryHelper.irSegments;if(segments.length===0){segments=chromeHelper.telemetryHelper.animationSegments;}
 if(segments.length>0){tr.metrics.rendering.addFrameTimeHistograms(histograms,model,segments);tr.metrics.rendering.addImageDecodeTimeHistograms(histograms,model,segments);tr.metrics.rendering.addPipelineHistograms(histograms,model,segments);tr.metrics.rendering.addPixelsHistograms(histograms,model,segments);tr.metrics.rendering.addQueueingDurationHistograms(histograms,model,segments);}
 const uiSegments=chromeHelper.telemetryHelper.uiSegments;if(uiSegments.length>0){tr.metrics.rendering.addUIFrameTimeHistograms(histograms,model,chromeHelper.telemetryHelper.uiSegments);}}
-tr.metrics.MetricRegistry.register(renderingMetric,{requiredCategories:['benchmark','toplevel'],});return{renderingMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_smallerIsBetter=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const EventFinderUtils=tr.e.chrome.EventFinderUtils;const METRIC_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(80e3,30);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function reportedByPageMetric(histograms,model){const timeToViewable=histograms.createHistogram('reported_by_page:time_to_viewable',timeDurationInMs_smallerIsBetter,[],{binBoundaries:METRIC_BOUNDARIES,description:'Time from navigation start'+'to telemetry:reported_by_page:viewable',summaryOptions:SUMMARY_OPTIONS,});const timeToInteractive=histograms.createHistogram('reported_by_page:time_to_interactive',timeDurationInMs_smallerIsBetter,[],{binBoundaries:METRIC_BOUNDARIES,description:'Time from navigation start '+'to telemetry:reported_by_page:interactive',summaryOptions:SUMMARY_OPTIONS,});const benchmarkTime=histograms.createHistogram('reported_by_page:benchmark_time',timeDurationInMs_smallerIsBetter,[],{binBoundaries:METRIC_BOUNDARIES,description:'Time from telemetry:reported_by_page:benchmark_begin '+'to telemetry:reported_by_page:benchmark_end',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;measureUserTime(rendererHelper,'navigationStart','telemetry:reported_by_page:viewable',timeToViewable);measureUserTime(rendererHelper,'navigationStart','telemetry:reported_by_page:interactive',timeToInteractive);measureUserTime(rendererHelper,'telemetry:reported_by_page:benchmark_begin','telemetry:reported_by_page:benchmark_end',benchmarkTime);}}
+tr.metrics.MetricRegistry.register(renderingMetric,{requiredCategories:['benchmark','toplevel'],});return{renderingMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_smallerIsBetter=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const EventFinderUtils=tr.e.chrome.EventFinderUtils;const METRIC_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(80e3,30);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function reportedByPageMetric(histograms,model){const timeToViewable=histograms.createHistogram('reported_by_page:time_to_viewable',timeDurationInMs_smallerIsBetter,[],{binBoundaries:METRIC_BOUNDARIES,description:'Time from navigation start'+'to telemetry:reported_by_page:viewable',summaryOptions:SUMMARY_OPTIONS,});const timeToInteractive=histograms.createHistogram('reported_by_page:time_to_interactive',timeDurationInMs_smallerIsBetter,[],{binBoundaries:METRIC_BOUNDARIES,description:'Time from navigation start '+'to telemetry:reported_by_page:interactive',summaryOptions:SUMMARY_OPTIONS,});const benchmarkTime=histograms.createHistogram('reported_by_page:benchmark_time',timeDurationInMs_smallerIsBetter,[],{binBoundaries:METRIC_BOUNDARIES,description:'Time from telemetry:reported_by_page:benchmark_begin '+'to telemetry:reported_by_page:benchmark_end',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;if(rendererHelper.mainThread===undefined)continue;measureUserTime(rendererHelper,'navigationStart','telemetry:reported_by_page:viewable',timeToViewable);measureUserTime(rendererHelper,'navigationStart','telemetry:reported_by_page:interactive',timeToInteractive);measureUserTime(rendererHelper,'telemetry:reported_by_page:benchmark_begin','telemetry:reported_by_page:benchmark_end',benchmarkTime);}}
 function measureUserTime(rendererHelper,startName,endName,histogram){const startEventByNavId=new Map();for(const event of rendererHelper.mainThread.sliceGroup.childEvents()){const navId=getNavigationId(event);if(!navId)continue;if(EventFinderUtils.hasCategoryAndName(event,'blink.user_timing',startName)){startEventByNavId.set(navId,event);}
 if(EventFinderUtils.hasCategoryAndName(event,'blink.user_timing',endName)){if(!startEventByNavId.has(navId)){throw Error(`Missing ${startName} for ${endName} at {event.start}`);}
 const range=tr.b.math.Range.fromExplicitRange(startEventByNavId.get(navId).start,event.start);histogram.addSample(range.duration);startEventByNavId.delete(navId);}}}
@@ -8683,7 +8690,7 @@
 return targetEvents;}
 function getMostRecentValidEvent(rendererHelper,category,title){const targetEvents=findAllEvents(rendererHelper,category,title);let validEvent;for(const targetEvent of targetEvents){if(rendererHelper.isTelemetryInternalEvent(targetEvent))continue;if(validEvent===undefined){validEvent=targetEvent;}else{if(validEvent.start<targetEvent.start){validEvent=targetEvent;}}}
 return validEvent;}
-function getFirstViewportReadySamples(rendererHelper,navIdToNavStartEvents){const samples=[];const pcEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','pc');if(pcEvent===undefined)return samples;if(rendererHelper.isTelemetryInternalEvent(pcEvent))return samples;const navigationStartEvent=navIdToNavStartEvents.get(pcEvent.args.data.navigationId);if(navigationStartEvent===undefined)return samples;const navStartToEventRange=tr.b.math.Range.fromExplicitRange(navigationStartEvent.start,pcEvent.start);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,navStartToEventRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToEventRange);samples.push({value:navStartToEventRange.duration,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),Start:new RelatedEventSet(navigationStartEvent),End:new RelatedEventSet(pcEvent)}});return samples;}
+function getFirstViewportReadySamples(rendererHelper,navIdToNavStartEvents){const samples=[];const pcEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','pc');if(pcEvent===undefined)return samples;if(rendererHelper.isTelemetryInternalEvent(pcEvent))return samples;const navigationStartEvent=navIdToNavStartEvents.get(pcEvent.args.data.navigationId);if(navigationStartEvent===undefined)return samples;const navStartToEventRange=tr.b.math.Range.fromExplicitRange(navigationStartEvent.start,pcEvent.start);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,navStartToEventRange);if(rendererHelper.mainThread===undefined)return samples;const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToEventRange);samples.push({value:navStartToEventRange.duration,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),Start:new RelatedEventSet(navigationStartEvent),End:new RelatedEventSet(pcEvent)}});return samples;}
 function getAboveTheFoldLoadedToVisibleSamples(rendererHelper){const samples=[];const pcEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','pc');const visibleEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','visible');if(pcEvent!==undefined&&visibleEvent!==undefined){samples.push({value:Math.max(0.0,pcEvent.start-visibleEvent.start),diagnostics:{Start:new RelatedEventSet(visibleEvent),End:new RelatedEventSet(pcEvent)}});}
 return samples;}
 function findTimeToXEntries(category,eventName,rendererHelper,frameToNavStartEvents,navIdToNavStartEvents){const targetEvents=findAllEvents(rendererHelper,category,eventName);const entries=[];for(const targetEvent of targetEvents){if(rendererHelper.isTelemetryInternalEvent(targetEvent))continue;const frameIdRef=targetEvent.args.frame;const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,targetEvent.start);if(snapshot===undefined||!snapshot.args.isLoadingMainFrame)continue;const url=snapshot.args.documentLoaderURL;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(url))continue;let navigationStartEvent;if(targetEvent.args.data===undefined||targetEvent.args.data.navigationId===undefined){navigationStartEvent=EventFinderUtils.findLastEventStartingOnOrBeforeTimestamp(frameToNavStartEvents.get(frameIdRef)||[],targetEvent.start);}else{navigationStartEvent=navIdToNavStartEvents.get(targetEvent.args.data.navigationId);}
@@ -8836,7 +8843,7 @@
 function addExpectedQueueingTimeMetric_(eqtName,getEventTimes,isCpuTime,rendererHelpers,histograms,model){function getTasks(rendererHelper){const tasks=[];for(const slice of
 tr.e.chrome.EventFinderUtils.findToplevelSchedulerTasks(rendererHelper.mainThread)){const times=getEventTimes(slice);if(times.duration>0&&!containsForcedGC_(slice)){tasks.push({start:times.start,end:times.start+times.duration});}}
 return tasks;}
-const totalHistogram=getOrCreateHistogram_(histograms,`total:${WINDOW_SIZE_MS}ms_window:${eqtName}`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer');for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;if(rendererHelper.mainThread.bounds.duration<WINDOW_SIZE_MS)continue;const tasks=getTasks(rendererHelper);const totalBreakdown=getV8Contribution_(eqtName,getEventTimes,isCpuTime,totalHistogram,histograms,rendererHelper,model);totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks),{v8:totalBreakdown});}}
+const totalHistogram=getOrCreateHistogram_(histograms,`total:${WINDOW_SIZE_MS}ms_window:${eqtName}`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer');for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;if(rendererHelper.mainThread===undefined)continue;if(rendererHelper.mainThread.bounds.duration<WINDOW_SIZE_MS)continue;const tasks=getTasks(rendererHelper);const totalBreakdown=getV8Contribution_(eqtName,getEventTimes,isCpuTime,totalHistogram,histograms,rendererHelper,model);totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks),{v8:totalBreakdown});}}
 function getV8Contribution_(eqtName,getEventTimes,isCpuTime,totalEqtHistogram,histograms,rendererHelper,model){if(!model.categories.includes('v8'))return null;const totalBreakdown=new tr.v.d.Breakdown();const eventNamesWithTaskExtractors=getV8EventNamesWithTaskExtractors_(getEventTimes);if(!isCpuTime){const taskExtractorsUsingRCS=getV8EventNamesWithTaskExtractorsUsingRCS_(getEventTimes);for(const[eventName,getTasks]of taskExtractorsUsingRCS){eventNamesWithTaskExtractors.set(eventName,getTasks);}}
 let totalNames=totalEqtHistogram.diagnostics.get('v8');if(!totalNames){totalNames=new tr.v.d.RelatedNameMap();totalEqtHistogram.diagnostics.set('v8',totalNames);}
 for(const[eventName,getTasks]of eventNamesWithTaskExtractors){const totalHistogram=getOrCreateHistogram_(histograms,`total:${WINDOW_SIZE_MS}ms_window:${eqtName}:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer. It is computed as the maximum EQT in'+` a ${WINDOW_SIZE_MS}ms sliding window after shrinking top-level`+` tasks to contain only ${eventName} subevents`);const tasks=getTasks(rendererHelper);const totalSample=tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks);totalHistogram.addSample(totalSample);totalBreakdown.set(eventName,totalSample);totalNames.set(eventName,totalHistogram.name);}
@@ -9008,13 +9015,11 @@
 function splitOneRangeIntoPerSecondRanges(startTime,endTime){const results=[];for(let i=0;startTime+(i+1)*1000<=endTime;i+=1){const start=i*1000;const end=(i+1)*1000;results.push({start,end,});}
 return results;}
 function getNavigationInfos(model){const navigationInfos=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
-const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];navigationInfos.push({navigationStart:expectation.navigationStart,rendererHelper,url:expectation.url});}
+const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];if(rendererHelper.mainThread===undefined)continue;navigationInfos.push({navigationStart:expectation.navigationStart,rendererHelper,url:expectation.url});}
 navigationInfos.forEach((navInfo,i)=>{if(i===navigationInfos.length-1){navInfo.navigationEndTime=model.bounds.max;}else{navInfo.navigationEndTime=navigationInfos[i+1].navigationStart.start;}});return navigationInfos;}
-function getRendererHelpers(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const rendererHelpers=[];for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;rendererHelpers.push(rendererHelper);}
-return rendererHelpers;}
 function getWallTimeBreakdownTree(rendererHelper,start,end){const startEndRange=tr.b.math.Range.fromExplicitRange(start,end);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,startEndRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,startEndRange);return breakdownTree;}
 function getCpuTimeBreakdownTree(rendererHelper,start,end){const startEndRange=tr.b.math.Range.fromExplicitRange(start,end);const breakdownTree=tr.metrics.sh.generateCpuTimeBreakdownTree(rendererHelper.mainThread,startEndRange);return breakdownTree;}
-function persecondMetric(histograms,model){const rendererHelpers=getRendererHelpers(model);const navigationInfos=getNavigationInfos(model);if(navigationInfos.length===0){return;}
+function persecondMetric(histograms,model){const navigationInfos=getNavigationInfos(model);if(navigationInfos.length===0){return;}
 navigationInfos.forEach(navInfo=>{const navigationStart=navInfo.navigationStart.start;const navigationEnd=navInfo.navigationEndTime;const startEndPairs=splitOneRangeIntoPerSecondRanges(navigationStart,navigationEnd);const breakdownList=startEndPairs.map(p=>{const wallHistogramName=`wall_${p.start}_to_${p.end}`;const wallHistogramDescription=`Wall-clock time ${p.start} to ${p.end} breakdown`;const cpuHistogramName=`cpu_${p.start}_to_${p.end}`;const cpuHistogramDescription=`CPU time ${p.start} to ${p.end} breakdown`;const pid=navInfo.rendererHelper.pid;const breakdownTree=getWallTimeBreakdownTree(navInfo.rendererHelper,navigationStart+p.start,navigationStart+p.end);const cpuBreakdownTree=getCpuTimeBreakdownTree(navInfo.rendererHelper,navigationStart+p.start,navigationStart+p.end);const diagnostics={'Navigation infos':new tr.v.d.GenericSet([{url:navInfo.url,pid:navInfo.rendererHelper.pid,navStart:navigationStart,frameIdRef:navInfo.navigationStart.args.frame}]),'breakdown':tr.metrics.sh.createBreakdownDiagnostic(breakdownTree),};return Object.assign(p,{breakdownTree,cpuBreakdownTree,wallHistogramName,wallHistogramDescription,cpuHistogramName,cpuHistogramDescription,diagnostics,});});breakdownList.forEach(p=>{if(!histograms.getHistogramNamed(p.wallHistogramName)){histograms.createHistogram(p.wallHistogramName,timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:p.wallHistogramDescription,summaryOptions:SUMMARY_OPTIONS,});}
 const wallHistogram=histograms.getHistogramNamed(p.wallHistogramName);addSamplesToHistogram(p,p.breakdownTree,wallHistogram,histograms,p.diagnostics);if(!histograms.getHistogramNamed(p.cpuHistogramName)){histograms.createHistogram(p.cpuHistogramName,timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:p.cpuHistogramDescription,summaryOptions:SUMMARY_OPTIONS,});}
 const cpuHistogram=histograms.getHistogramNamed(p.cpuHistogramName);addSamplesToHistogram(p,p.cpuBreakdownTree,cpuHistogram,histograms,p.diagnostics);});});}
@@ -9817,27 +9822,27 @@
 return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
 this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
 TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!==this.goalFocalPointY;},canTakeOverFor(existingAnimation){return false;},takeOverFor(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.scaleX=lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalFocalPointY);}
-target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};const MAX_OVERSIZE_MULTIPLE=3.0;const REDRAW_SLOP=(MAX_OVERSIZE_MULTIPLE-1)/2;const DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';Polymer.dom(this).appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.offsetY_=0;this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);window.addEventListener('resize',this.windowResized_.bind(this));this.addEventListener('scroll',this.scrollChanged_.bind(this));},get canvas(){return this.canvas_;},context(){return this.ctx_;},viewportChange_(){this.invalidate();},windowResized_(){this.invalidate();},scrollChanged_(){if(this.updateOffsetY_()){this.invalidate();}},invalidate(){if(this.rafPending_)return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);const typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(const idx in typesToDraw){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
-this.children[i].drawTrack(typesToDraw[idx]);}}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};const MAX_OVERSIZE_MULTIPLE=3.0;const REDRAW_SLOP=(MAX_OVERSIZE_MULTIPLE-1)/2;const DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';Polymer.dom(this).appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.offsetY_=0;this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);window.addEventListener('resize',this.windowResized_.bind(this));this.addEventListener('scroll',this.scrollChanged_.bind(this));},get canvas(){return this.canvas_;},context(){return this.ctx_;},viewportChange_(){this.invalidate();},windowResized_(){this.invalidate();},scrollChanged_(){if(this.updateOffsetY_()){this.invalidate();}},invalidate(){if(this.rafPending_)return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);const typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];const children=this.children;for(const idx in typesToDraw){for(let i=0;i<children.length;++i){if(!(children[i]instanceof tr.ui.tracks.Track)){continue;}
+children[i].drawTrack(typesToDraw[idx]);}}
 const pixelRatio=window.devicePixelRatio||1;const bounds=this.canvas_.getBoundingClientRect();const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);const viewHeight=bounds.height*pixelRatio;this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld,viewHeight);},updateOffsetY_(){const maxYDelta=window.innerHeight*REDRAW_SLOP;let newOffset=this.scrollTop-maxYDelta;if(Math.abs(newOffset-this.offsetY_)<=maxYDelta)return false;const maxOffset=this.scrollHeight-
 this.canvas_.getBoundingClientRect().height;newOffset=Math.max(0,Math.min(newOffset,maxOffset));if(newOffset!==this.offsetY_){this.offsetY_=newOffset;return true;}
 return false;},updateCanvasSizeIfNeeded_(){const visibleChildTracks=Array.from(this.children).filter(this.visibleFilter_);if(visibleChildTracks.length===0){return;}
 const thisBounds=this.getBoundingClientRect();const firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();const lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();const innerWidth=firstChildTrackBounds.width-
 tr.ui.b.constants.HEADING_WIDTH;const innerHeight=Math.min(lastChildTrackBounds.bottom-firstChildTrackBounds.top,Math.floor(window.innerHeight*MAX_OVERSIZE_MULTIPLE));const pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!==innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
 if(this.canvas_.height!==innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}
-if(this.canvas_.top!==this.offsetY_){this.canvas_.top=this.offsetY_;this.canvas_.style.top=this.offsetY_+'px';}},visibleFilter_(element){if(!(element instanceof tr.ui.tracks.Track))return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
-const trackClientRect=this.children[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
-this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer,DrawType,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);}
+if(this.canvas_.top!==this.offsetY_){this.canvas_.top=this.offsetY_;this.canvas_.style.top=this.offsetY_+'px';}},visibleFilter_(element){if(!(element instanceof tr.ui.tracks.Track))return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const children=this.children;for(let i=0;i<children.length;++i){if(!(children[i]instanceof tr.ui.tracks.Track)){continue;}
+const trackClientRect=children[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){const children=this.children;for(let i=0;i<children.length;++i){if(!(children[i]instanceof tr.ui.tracks.Track)){continue;}
+children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer,DrawType,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);}
 ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){const modelItem=this.modelItem_;if(modelItem===undefined){return SelectionState.NONE;}
 return modelItem.selectionState;}};return{ProxySelectableItem,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld,viewHeight){if(this.items_===undefined)return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const dumpRadiusView=this.dumpRadiusView;const itemRadiusWorld=dt.xViewVectorToWorld(height);const items=this.items_;const loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);const oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';const drawItems=function(selected){for(let i=loI;i<items.length;++i){const item=items[i];const x=item.start;if(x-itemRadiusWorld>viewRWorld)break;if(item.selected!==selected)continue;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
 ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap(eventToTrackMap){if(this.items_===undefined)return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)return;const itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.items_===undefined)return;const index=this.items_.findIndex(item=>item.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex>=0&&newIndex<this.items_.length){this.items_[newIndex].addToSelection(selection);return true;}
 return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)return;const item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;}
 LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack,LetterDot,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
-this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Task=tr.b.Task;const ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach(){Polymer.dom(this).textContent='';},get tracks_(){const tracks=[];for(let i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track){tracks.push(this.children[i]);}}
-return tracks;},drawTrack(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(const track of this.tracks_){track.addEventsToTrackMap(eventToTrackMap);}},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.tracks_.length;i++){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const task=new Task();for(let i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);};}(i),this);}
-return task;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Task=tr.b.Task;const ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach(){Polymer.dom(this).textContent='';},get tracks_(){const tracks=[];const children=this.children;for(let i=0;i<children.length;i++){if(children[i]instanceof tr.ui.tracks.Track){tracks.push(children[i]);}}
+return tracks;},drawTrack(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){const tracks=this.tracks_;for(let i=0;i<tracks.length;i++){const trackClientRect=tracks[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){tracks[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(const track of this.tracks_){track.addEventsToTrackMap(eventToTrackMap);}},addAllEventsMatchingFilterToSelection(filter,selection){const tracks=this.tracks_;for(let i=0;i<tracks.length;i++){tracks[i].addAllEventsMatchingFilterToSelection(filter,selection);}},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const task=new Task();const tracks=this.tracks_;for(let i=0;i<tracks.length;i++){task.subTask(function(i){return function(){tracks[i].addAllEventsMatchingFilterToSelection(filter,selection);};}(i),this);}
+return task;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const tracks=this.tracks_;for(let i=0;i<tracks.length;i++){const trackClientRect=tracks[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){tracks[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
 tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_(){this.tracks_.forEach(function(track){Polymer.dom(this).removeChild(track);},this);}};return{ContainerTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.dotLetter=undefined;this.yBase=opt_yBase;}
 ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype,};return{ChartPoint,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const ChartSeriesType={LINE:0,AREA:1};const DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,solidSelectedDots:false,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5,stepGraph:true};const LAST_POINT_WIDTH=16;const DOT_LETTER_RADIUS_PX=7;const DOT_LETTER_RADIUS_PADDING_PX=0.5;const DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX=3;const DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX=1.5;const DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX=1;const DOT_LETTER_FONT_WEIGHT=400;const DOT_LETTER_FONT_SIZE_PX=9;const DOT_LETTER_FONT='Arial';const ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,seriesYAxis,opt_renderingConfig){this.points=points;this.seriesYAxis=seriesYAxis;this.useRenderingConfig_(opt_renderingConfig);}
 ChartSeries.prototype={useRenderingConfig_(opt_renderingConfig){const config=opt_renderingConfig||{};for(const[key,defaultValue]of
@@ -9946,9 +9951,9 @@
 return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){const numSeries=counter.series.length;const totals=counter.totals;const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const chartSeries=counter.series.map(function(series,seriesIndex){const chartPoints=series.samples.map(function(sample,sampleIndex){const total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,seriesYAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const startCompare=function(x,y){return x.start-y.start;};const FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
 FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.currentSubRowsWithHeadings_=undefined;this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.currentSubRowsWithHeadings_=undefined;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},setPrebuiltSubRows(groupingSource,subRowsWithHeadings){this.itemsToGroup_=undefined;this.groupingSource_=groupingSource;this.currentSubRowsWithHeadings_=subRowsWithHeadings;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateHeadingAndTooltip_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateHeadingAndTooltip_();},get subRows(){return this.currentSubRowsWithHeadings_.map(elem=>elem.row);},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_(e){if(this.subRows.length<=1)return;this.expanded=!this.expanded;if(this.groupingSource_){const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
 e.stopPropagation();},updateExpandedStateFromGroupingSource_(){if(this.groupingSource_){const numSubRows=this.subRows.length;const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){let defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
-this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_(){const minH=Math.max(2,Math.ceil(18/this.children.length));const h=(this.expanded_?18:minH)+'px';for(let i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0){this.children[i].arrowVisible=true;}
-this.children[i].expanded=this.expanded;}
-if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);this.detach();if(this.currentSubRowsWithHeadings_===undefined){if(this.itemsToGroup_===undefined){return;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_(){const children=this.children;const minH=Math.max(2,Math.ceil(18/children.length));const h=(this.expanded_?18:minH)+'px';for(let i=0;i<children.length;i++){children[i].height=h;if(i===0){children[i].arrowVisible=true;}
+children[i].expanded=this.expanded;}
+if(children.length===1){children[0].expanded=true;children[0].arrowVisible=false;}},updateContents_(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);this.detach();if(this.currentSubRowsWithHeadings_===undefined){if(this.itemsToGroup_===undefined){return;}
 const subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRowsWithHeadings_=subRows.map(row=>{return{row,heading:undefined};});}
 if(this.currentSubRowsWithHeadings_===undefined||this.currentSubRowsWithHeadings_.length===0){return;}
 const addSubTrackEx=(items,opt_heading)=>{const track=this.addSubTrack_(items);if(opt_heading!==undefined){track.heading=opt_heading;}
@@ -10001,8 +10006,8 @@
 if(this.hasVisibleContent){this.items=this.buildMemoryLetterDots_(this.lowMemoryEvents_);}},get hasVisibleContent(){return!!this.lowMemoryEvents_&&this.lowMemoryEvents_.length!==0;},buildMemoryLetterDots_(memoryEvents){return memoryEvents.map(memoryEvent=>new tr.ui.tracks.LetterDot(memoryEvent,'K',ColorScheme.getColorIdForReservedName('background_memory_dump'),memoryEvent.start));},};return{MemoryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{ProcessMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:{if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0){break;}
 const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;}
 case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
-tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_(){const ctx=this.context();const canvasBounds=ctx.canvas.getBoundingClientRect();const pixelRatio=window.devicePixelRatio||1;let draw=false;ctx.fillStyle='#eee';for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack)){continue;}
-draw=!draw;if(!draw)continue;const bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_(){const processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){const pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;Polymer.dom(this).appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_(){const ctx=this.context();const canvasBounds=ctx.canvas.getBoundingClientRect();const pixelRatio=window.devicePixelRatio||1;const children=this.children;let draw=false;ctx.fillStyle='#eee';for(let i=0;i<children.length;++i){if(!(children[i]instanceof tr.ui.tracks.Track)||(children[i]instanceof tr.ui.tracks.SpacingTrack)){continue;}
+draw=!draw;if(!draw)continue;const bounds=children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_(){const processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){const pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;Polymer.dom(this).appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
 const instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.VSYNC_HIGHLIGHT_ALPHA=0.1;ModelTrack.VSYNC_DENSITY_TRANSPARENT=0.20;ModelTrack.VSYNC_DENSITY_OPAQUE=0.10;ModelTrack.VSYNC_DENSITY_RANGE=ModelTrack.VSYNC_DENSITY_TRANSPARENT-ModelTrack.VSYNC_DENSITY_OPAQUE;ModelTrack.generateStripes_=function(times,minTime,maxTime){if(times.length===0)return[];const lowIndex=tr.b.findLowIndexInSortedArray(times,(x=>x),minTime);let highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
 const stripes=[];for(let i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){const left=i<lowIndex?minTime:times[i];const right=i+1>highIndex?maxTime:times[i+1];stripes.push(tr.b.math.Range.fromExplicitRange(left,right));}
 return stripes;};ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('model-track');this.upperMode_=false;this.annotationViews_=[];this.vSyncTimes_=[];},get processViews(){return Polymer.dom(this).querySelectorAll('.process-track-base');},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_(){Polymer.dom(this).textContent='';if(!this.model_)return;if(this.upperMode_){this.updateContentsForUpperMode_();}else{this.updateContentsForLowerMode_();}},updateContentsForUpperMode_(){},updateContentsForLowerMode_(){if(this.model_.userModel.expectations.length>1){const mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;Polymer.dom(this).appendChild(mrt);}
@@ -10108,7 +10113,7 @@
 Polymer.dom(this).removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range===undefined){throw new Error('Must not be undefined');}
 this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready(){const mod=tr.isMac?'cmd ':'ctrl';const spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(let i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready(){this.preferredTimeDisplayMode_=undefined;},attached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';const POLYFILL_WARNING_MESSAGE='Trace Viewer is running with WebComponentsV0 polyfill, and some '+'features may be broken. As a workaround, you may try running chrome '+'with "--enable-blink-features=ShadowDOMV0,CustomElementsV0,HTMLImports" '+'flag. See crbug.com/1036492.';Polymer({is:'tr-ui-timeline-view',created(){this.trackViewContainer_=undefined;this.queuedModel_=undefined;this.builtPromise_=undefined;this.doneBuilding_=undefined;},attached(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}
 if(this.queuedModel_)this.updateContents_();});},ready(){this.tabIndex=0;this.polyfillWarnedOnce_=false;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');Polymer.dom(this.rightControls).appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
-this.flowEventFilter_=this.$.flow_event_filter_dropdown;this.processFilter_=this.$.process_filter_dropdown;this.optionsDropdown_=this.$.view_options_dropdown;this.selectedFlowEvents_=new Set();this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},warnPolyfill(){if(this.polyfillWarnedOnce_)return;this.polyfillWarnedOnce_=true;const polyfillWarningsEl=Polymer.dom(this.root).querySelector('#polyfill-warning');polyfillWarningsEl.addMessage(POLYFILL_WARNING_MESSAGE,[{buttonText:'Hide',onClick:()=>polyfillWarningsEl.clearMessages()}]);},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
+this.flowEventFilter_=this.$.flow_event_filter_dropdown;this.processFilter_=this.$.process_filter_dropdown;this.optionsDropdown_=this.$.view_options_dropdown;this.selectedFlowEvents_=new Set();this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},warnPolyfill(){if(this.polyfillWarnedOnce_)return;console.warn(POLYFILL_WARNING_MESSAGE);this.polyfillWarnedOnce_=true;if(!window.__hideTraceViewerPolyfillWarning){const polyfillWarningsEl=Polymer.dom(this.root).querySelector('#polyfill-warning');polyfillWarningsEl.addMessage(POLYFILL_WARNING_MESSAGE,[{buttonText:'Hide',onClick:()=>polyfillWarningsEl.clearMessages()}]);}},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
 let faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined){faviconData=tr.ui.b.FaviconsByHue.blue;}
 let link=Polymer.dom(document.head).querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';Polymer.dom(document.head).appendChild(link);}
 link.href=faviconData;},get selectedFlowEvents(){return this.selectedFlowEvents_;},set selectedFlowEvents(selectedFlowEvents){this.selectedFlowEvents_=selectedFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_(){const helpButtonEl=this.$.view_help_button;const dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.visible=false;dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));function onClick(e){dlg.visible=!dlg.visible;e.stopPropagation();}
diff --git a/runtime/platform/BUILD.gn b/runtime/platform/BUILD.gn
index 9a2905c..012421d 100644
--- a/runtime/platform/BUILD.gn
+++ b/runtime/platform/BUILD.gn
@@ -5,9 +5,22 @@
 import("../configs.gni")
 import("platform_sources.gni")
 
+if (is_fuchsia) {
+  import("//build/fuchsia/sdk.gni")
+}
+
 library_for_all_configs("libdart_platform") {
   target_type = "source_set"
   public_configs = [ "../vm:libdart_vm_config" ]
   sources = platform_sources
   include_dirs = [ ".." ]
+  extra_deps = []
+
+  if (is_fuchsia) {
+    if (using_fuchsia_sdk) {
+      extra_deps += [ "$fuchsia_sdk_root/pkg:sys_cpp" ]
+    } else {
+      extra_deps += [ "//sdk/lib/sys/cpp" ]
+    }
+  }
 }
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 22e85f4..ac995f4 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -252,14 +252,6 @@
 #endif
 
 #ifdef _MSC_VER
-#define DART_FLATTEN
-#elif __GNUC__
-#define DART_FLATTEN __attribute__((flatten))
-#else
-#error Automatic compiler detection failed.
-#endif
-
-#ifdef _MSC_VER
 #elif __GNUC__
 #define DART_HAS_COMPUTED_GOTO 1
 #else
@@ -621,9 +613,8 @@
 // type to another thus avoiding the warning.
 template <class D, class S>
 inline D bit_cast(const S& source) {
-  // Compile time assertion: sizeof(D) == sizeof(S). A compile error
-  // here means your D and S have different sizes.
-  DART_UNUSED typedef char VerifySizesAreEqual[sizeof(D) == sizeof(S) ? 1 : -1];
+  static_assert(sizeof(D) == sizeof(S),
+                "Source and destination must have the same size");
 
   D destination;
   // This use of memcpy is safe: source and destination cannot overlap.
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 93a5a23..6635fc3 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -364,6 +364,7 @@
 
   template <typename T>
   DART_FORCE_INLINE static bool TestBit(T mask, intptr_t position) {
+    ASSERT(position < static_cast<intptr_t>(sizeof(T) * kBitsPerByte));
     return ((mask >> position) & 1) != 0;
   }
 
diff --git a/runtime/platform/utils_fuchsia.cc b/runtime/platform/utils_fuchsia.cc
index 04e813a..22d2800 100644
--- a/runtime/platform/utils_fuchsia.cc
+++ b/runtime/platform/utils_fuchsia.cc
@@ -5,7 +5,11 @@
 #include "platform/globals.h"
 #if defined(HOST_OS_FUCHSIA)
 
+#include <memory>
+
+#include "lib/sys/cpp/component_context.h"
 #include "platform/utils.h"
+#include "platform/utils_fuchsia.h"
 
 namespace dart {
 
@@ -33,6 +37,12 @@
   return retval;
 }
 
+sys::ComponentContext* ComponentContext() {
+  static std::unique_ptr<sys::ComponentContext> context =
+      sys::ComponentContext::CreateAndServeOutgoingDirectory();
+  return context.get();
+}
+
 }  // namespace dart
 
 #endif  // defined(HOST_OS_FUCHSIA)
diff --git a/runtime/platform/utils_fuchsia.h b/runtime/platform/utils_fuchsia.h
index 7cb3812..4b2064e 100644
--- a/runtime/platform/utils_fuchsia.h
+++ b/runtime/platform/utils_fuchsia.h
@@ -7,6 +7,13 @@
 
 #include <endian.h>
 
+namespace sys {
+
+// From Fuchsia SDK.
+class ComponentContext;
+
+}  // namespace sys
+
 namespace dart {
 
 inline uint16_t Utils::HostToBigEndian16(uint16_t value) {
@@ -40,6 +47,16 @@
   return buffer;
 }
 
+// Returns the singleton component context for this process.
+//
+// The returned pointer is never null.  The caller must not take ownership of
+// the context.
+//
+// The context is a singleton as it can be meaningfully instantiated only once
+// during the lifetime of the program.  If you use this function, you MUST NOT
+// call sys::ComponentContext::Create().
+sys::ComponentContext* ComponentContext();
+
 }  // namespace dart
 
 #endif  // RUNTIME_PLATFORM_UTILS_FUCHSIA_H_
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
new file mode 100644
index 0000000..11c1a33
--- /dev/null
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_lazy_debug.so --lazy-async-stacks --no-causal-async-stacks
+
+import 'dart:async';
+import 'dart:io';
+
+import 'utils.dart';
+
+Future<void> main(List<String> args) async {
+  // We won't have access to the debugging info file on Android.
+  if (Platform.isAndroid) return;
+
+  await doTestsLazy('async_lazy_debug.so');
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
new file mode 100644
index 0000000..f65de84
--- /dev/null
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_no_causal_debug.so --no-causal-async-stacks --no-lazy-async-stacks
+
+import 'dart:async';
+import 'dart:io';
+
+import 'utils.dart';
+
+Future<void> main(List<String> args) async {
+  // We won't have access to the debugging info file on Android.
+  if (Platform.isAndroid) return;
+
+  await doTestsNoCausalNoLazy('async_no_causal_debug.so');
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart
new file mode 100644
index 0000000..cdb783a
--- /dev/null
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_causal_debug.so --causal-async-stacks --no-lazy-async-stacks
+
+import 'dart:async';
+import 'dart:io';
+
+import 'utils.dart';
+
+Future<void> main(List<String> args) async {
+  // We won't have access to the debugging info file on Android.
+  if (Platform.isAndroid) return;
+
+  await doTestsCausal('async_causal_debug.so');
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 118ce14..a7df656 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
-import 'dart:math';
-import 'dart:typed_data';
 
 import 'package:path/path.dart' as path;
 import 'package:expect/expect.dart';
+import 'package:native_stack_traces/native_stack_traces.dart';
 
 // Test functions:
 
@@ -151,38 +151,85 @@
 
 // Helpers:
 
-void assertStack(List<String> expects, StackTrace stackTrace) {
-  final List<String> frames = stackTrace.toString().split('\n');
-  if (frames.length < expects.length) {
-    print('Actual stack:');
-    print(stackTrace.toString());
-    Expect.fail('Expected ${expects.length} frames, found ${frames.length}!');
+// We want lines that either start with a frame index or an async gap marker.
+final _lineRE = RegExp(r'^(?:#(?<number>\d+)|<asynchronous suspension>)');
+
+void assertStack(List<String> expects, StackTrace stackTrace,
+    [String debugInfoFilename]) async {
+  final original = await Stream.value(stackTrace.toString())
+      .transform(const LineSplitter())
+      .toList();
+  var frames = original;
+
+  // Use the DWARF stack decoder if we're running in --dwarf-stack-traces mode
+  // and in precompiled mode (otherwise --dwarf-stack-traces has no effect).
+  final decodeTrace = frames.first.startsWith('Warning:');
+  if (decodeTrace) {
+    Expect.isNotNull(debugInfoFilename);
+    final dwarf = Dwarf.fromFile(debugInfoFilename);
+    frames = await Stream.fromIterable(original)
+        .transform(DwarfStackTraceDecoder(dwarf))
+        .where(_lineRE.hasMatch)
+        .toList();
   }
+
+  void printFrameInformation() {
+    print('RegExps for expected stack:');
+    expects.forEach((s) => print('"${s}"'));
+    print('');
+    if (decodeTrace) {
+      print('Non-symbolic actual stack:');
+      original.forEach(print);
+      print('');
+    }
+    print('Actual stack:');
+    frames.forEach(print);
+    print('');
+  }
+
   for (int i = 0; i < expects.length; i++) {
     try {
-      Expect.isTrue(RegExp(expects[i]).hasMatch(frames[i]));
-    } on ExpectException catch (e) {
+      Expect.isTrue(i < frames.length,
+          'Expected at least ${expects.length} frames, found ${frames.length}');
+    } on ExpectException {
       // On failed expect, print full stack for reference.
-      print('Actual stack:');
-      print(stackTrace.toString());
+      printFrameInformation();
+      print('Expected line ${i + 1} to be ${expects[i]} but was missing');
+      rethrow;
+    }
+    try {
+      Expect.isTrue(RegExp(expects[i]).hasMatch(frames[i]));
+    } on ExpectException {
+      // On failed expect, print full stack for reference.
+      printFrameInformation();
       print('Expected line ${i + 1} to be `${expects[i]}` '
           'but was `${frames[i]}`');
       rethrow;
     }
   }
+
+  try {
+    Expect.equals(expects.length, frames.length);
+  } on ExpectException {
+    // On failed expect, print full stack for reference.
+    printFrameInformation();
+    rethrow;
+  }
 }
 
-Future<void> doTestAwait(Future f(), List<String> expectedStack) async {
+Future<void> doTestAwait(Future f(), List<String> expectedStack,
+    [String debugInfoFilename]) async {
   // Caller catches exception.
   try {
     await f();
     Expect.fail('No exception thrown!');
   } on String catch (e, s) {
-    assertStack(expectedStack, s);
+    assertStack(expectedStack, s, debugInfoFilename);
   }
 }
 
-Future<void> doTestAwaitThen(Future f(), List<String> expectedStack) async {
+Future<void> doTestAwaitThen(Future f(), List<String> expectedStack,
+    [String debugInfoFilename]) async {
   // Caller catches but a then is set.
   try {
     await f().then((e) {
@@ -190,18 +237,18 @@
     });
     Expect.fail('No exception thrown!');
   } on String catch (e, s) {
-    assertStack(expectedStack, s);
+    assertStack(expectedStack, s, debugInfoFilename);
   }
 }
 
-Future<void> doTestAwaitCatchError(
-    Future f(), List<String> expectedStack) async {
+Future<void> doTestAwaitCatchError(Future f(), List<String> expectedStack,
+    [String debugInfoFilename]) async {
   // Caller doesn't catch, but we have a catchError set.
   StackTrace stackTrace;
   await f().catchError((e, s) {
     stackTrace = s;
   });
-  assertStack(expectedStack, stackTrace);
+  assertStack(expectedStack, stackTrace, debugInfoFilename);
 }
 
 // ----
@@ -209,7 +256,7 @@
 // ----
 
 // For: --causal-async-stacks
-Future<void> doTestsCausal() async {
+Future<void> doTestsCausal([String debugInfoFilename]) async {
   final allYieldExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
     r'^#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -228,8 +275,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       allYield,
       allYieldExpected +
@@ -240,8 +287,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       allYield,
       allYieldExpected +
@@ -252,8 +299,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final noYieldsExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -271,8 +318,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       noYields,
       noYieldsExpected +
@@ -283,8 +330,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       noYields,
       noYieldsExpected +
@@ -295,8 +342,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final mixedYieldsExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -316,8 +363,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       mixedYields,
       mixedYieldsExpected +
@@ -328,8 +375,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       mixedYields,
       mixedYieldsExpected +
@@ -340,8 +387,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final syncSuffixExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -361,8 +408,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       syncSuffix,
       syncSuffixExpected +
@@ -373,8 +420,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       syncSuffix,
       syncSuffixExpected +
@@ -385,8 +432,8 @@
             r'^#6      main ',
             r'^#7      _startIsolate.<anonymous closure> ',
             r'^#8      _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final nonAsyncNoStackExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -397,16 +444,18 @@
     r'^#4      Future._propagateToListeners.handleValueCallback ',
     r'^#5      Future._propagateToListeners ',
     r'^#6      Future._completeWithValue ',
-    r'^#7      Future._asyncComplete.<anonymous closure> ',
+    r'^#7      Future._asyncCompleteWithValue.<anonymous closure> ',
     r'^#8      _microtaskLoop ',
     r'^#9      _startMicrotaskLoop ',
     r'^#10     _runPendingImmediateCallback ',
     r'^#11     _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(nonAsyncNoStack, nonAsyncNoStackExpected);
-  await doTestAwaitThen(nonAsyncNoStack, nonAsyncNoStackExpected);
-  await doTestAwaitCatchError(nonAsyncNoStack, nonAsyncNoStackExpected);
+  await doTestAwait(
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+  await doTestAwaitThen(
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+  await doTestAwaitCatchError(
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
 
   final asyncStarThrowSyncExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -424,8 +473,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       awaitEveryAsyncStarThrowSync,
       asyncStarThrowSyncExpected +
@@ -436,8 +485,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       awaitEveryAsyncStarThrowSync,
       asyncStarThrowSyncExpected +
@@ -448,8 +497,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final asyncStarThrowAsyncExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -468,8 +517,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       awaitEveryAsyncStarThrowAsync,
       asyncStarThrowAsyncExpected +
@@ -480,8 +529,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       awaitEveryAsyncStarThrowAsync,
       asyncStarThrowAsyncExpected +
@@ -492,8 +541,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final listenAsyncStartExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -512,8 +561,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       listenAsyncStarThrowAsync,
       listenAsyncStartExpected +
@@ -524,8 +573,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       listenAsyncStarThrowAsync,
       listenAsyncStartExpected +
@@ -536,8 +585,8 @@
             r'^#5      main \(.+\)$',
             r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   final customErrorZoneExpected = const <String>[
     r'#0      throwSync \(.*/utils.dart:16(:3)?\)$',
     r'#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -563,8 +612,8 @@
             r'#12     main \(.+\)$',
             r'#13     _startIsolate.<anonymous closure> ',
             r'#14     _RawReceivePortImpl._handleMessage ',
-            r'$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       customErrorZone,
       customErrorZoneExpected +
@@ -575,8 +624,8 @@
             r'#12     main \(.+\)$',
             r'#13     _startIsolate.<anonymous closure> ',
             r'#14     _RawReceivePortImpl._handleMessage ',
-            r'$'
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       customErrorZone,
       customErrorZoneExpected +
@@ -587,12 +636,12 @@
             r'#12     main \(.+\)$',
             r'#13     _startIsolate.<anonymous closure> ',
             r'#14     _RawReceivePortImpl._handleMessage ',
-            r'$'
-          ]);
+          ],
+      debugInfoFilename);
 }
 
 // For: --no-causal-async-stacks --no-lazy-async-stacks
-Future<void> doTestsNoCausalNoLazy() async {
+Future<void> doTestsNoCausalNoLazy([String debugInfoFilename]) async {
   final allYieldExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
     r'^#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -606,11 +655,10 @@
     r'^#8      _startMicrotaskLoop ',
     r'^#9      _runPendingImmediateCallback ',
     r'^#10     _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(allYield, allYieldExpected);
-  await doTestAwaitThen(allYield, allYieldExpected);
-  await doTestAwaitCatchError(allYield, allYieldExpected);
+  await doTestAwait(allYield, allYieldExpected, debugInfoFilename);
+  await doTestAwaitThen(allYield, allYieldExpected, debugInfoFilename);
+  await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename);
 
   final noYieldsExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -673,8 +721,8 @@
             r'^#51     _startMicrotaskLoop ',
             r'^#52     _runPendingImmediateCallback ',
             r'^#53     _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       noYields,
       noYieldsExpected +
@@ -719,8 +767,8 @@
             r'^#46     _startMicrotaskLoop ',
             r'^#47     _runPendingImmediateCallback ',
             r'^#48     _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       noYields,
       noYieldsExpected +
@@ -765,8 +813,8 @@
             r'^#46     _startMicrotaskLoop ',
             r'^#47     _runPendingImmediateCallback ',
             r'^#48     _RawReceivePortImpl._handleMessage ',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final mixedYieldsExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -780,11 +828,11 @@
     r'^#7      _startMicrotaskLoop ',
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(mixedYields, mixedYieldsExpected);
-  await doTestAwaitThen(mixedYields, mixedYieldsExpected);
-  await doTestAwaitCatchError(mixedYields, mixedYieldsExpected);
+  await doTestAwait(mixedYields, mixedYieldsExpected, debugInfoFilename);
+  await doTestAwaitThen(mixedYields, mixedYieldsExpected, debugInfoFilename);
+  await doTestAwaitCatchError(
+      mixedYields, mixedYieldsExpected, debugInfoFilename);
 
   final syncSuffixExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -798,11 +846,11 @@
     r'^#7      _startMicrotaskLoop ',
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(syncSuffix, syncSuffixExpected);
-  await doTestAwaitThen(syncSuffix, syncSuffixExpected);
-  await doTestAwaitCatchError(syncSuffix, syncSuffixExpected);
+  await doTestAwait(syncSuffix, syncSuffixExpected, debugInfoFilename);
+  await doTestAwaitThen(syncSuffix, syncSuffixExpected, debugInfoFilename);
+  await doTestAwaitCatchError(
+      syncSuffix, syncSuffixExpected, debugInfoFilename);
 
   final nonAsyncNoStackExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -816,11 +864,13 @@
     r'^#7      _startMicrotaskLoop ',
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(nonAsyncNoStack, nonAsyncNoStackExpected);
-  await doTestAwaitThen(nonAsyncNoStack, nonAsyncNoStackExpected);
-  await doTestAwaitCatchError(nonAsyncNoStack, nonAsyncNoStackExpected);
+  await doTestAwait(
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+  await doTestAwaitThen(
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+  await doTestAwaitCatchError(
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
 
   final asyncStarThrowSyncExpected = const <String>[
     r'^#0      throwSync \(.+/utils.dart:16(:3)?\)$',
@@ -835,13 +885,13 @@
     r'^#8      _startMicrotaskLoop \(.+\)$',
     r'^#9      _runPendingImmediateCallback \(.+\)$',
     r'^#10     _RawReceivePortImpl._handleMessage \(.+\)$',
-    r'^$',
   ];
-  await doTestAwait(awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
-  await doTestAwaitThen(
-      awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
+  await doTestAwait(awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected,
+      debugInfoFilename);
+  await doTestAwaitThen(awaitEveryAsyncStarThrowSync,
+      asyncStarThrowSyncExpected, debugInfoFilename);
+  await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync,
+      asyncStarThrowSyncExpected, debugInfoFilename);
 
   final asyncStarThrowAsyncExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -855,13 +905,13 @@
     r'^#7      _startMicrotaskLoop ',
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
-  await doTestAwaitThen(
-      awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
+  await doTestAwait(awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected,
+      debugInfoFilename);
+  await doTestAwaitThen(awaitEveryAsyncStarThrowAsync,
+      asyncStarThrowAsyncExpected, debugInfoFilename);
+  await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync,
+      asyncStarThrowAsyncExpected, debugInfoFilename);
 
   final listenAsyncStartExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -875,12 +925,13 @@
     r'^#7      _startMicrotaskLoop ',
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
-    r'^$',
   ];
-  await doTestAwait(listenAsyncStarThrowAsync, listenAsyncStartExpected);
-  await doTestAwaitThen(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+  await doTestAwait(
+      listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+  await doTestAwaitThen(
+      listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
   await doTestAwaitCatchError(
-      listenAsyncStarThrowAsync, listenAsyncStartExpected);
+      listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
 
   final customErrorZoneExpected = const <String>[
     r'#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -899,15 +950,17 @@
     r'#13     _startMicrotaskLoop ',
     r'#14     _runPendingImmediateCallback ',
     r'#15     _RawReceivePortImpl._handleMessage ',
-    r'$',
   ];
-  await doTestAwait(customErrorZone, customErrorZoneExpected);
-  await doTestAwaitThen(customErrorZone, customErrorZoneExpected);
-  await doTestAwaitCatchError(customErrorZone, customErrorZoneExpected);
+  await doTestAwait(
+      customErrorZone, customErrorZoneExpected, debugInfoFilename);
+  await doTestAwaitThen(
+      customErrorZone, customErrorZoneExpected, debugInfoFilename);
+  await doTestAwaitCatchError(
+      customErrorZone, customErrorZoneExpected, debugInfoFilename);
 }
 
 // For: --lazy-async-stacks
-Future<void> doTestsLazy() async {
+Future<void> doTestsLazy([String debugInfoFilename]) async {
   final allYieldExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
     r'^#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -927,22 +980,17 @@
             r'^<asynchronous suspension>$',
             r'^#6      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       allYield,
       allYieldExpected +
           const <String>[
             r'^#4      doTestAwaitThen.<anonymous closure> ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
-  await doTestAwaitCatchError(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
+  await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename);
 
   final noYieldsExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -959,8 +1007,8 @@
             r'^<asynchronous suspension>$',
             r'^#6      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       noYields,
       noYieldsExpected +
@@ -970,8 +1018,8 @@
             r'^<asynchronous suspension>$',
             r'^#6      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
       noYields,
       noYieldsExpected +
@@ -981,8 +1029,8 @@
             r'^<asynchronous suspension>$',
             r'^#6      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
 
   final mixedYieldsExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1002,22 +1050,18 @@
             r'^<asynchronous suspension>$',
             r'^#5      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       mixedYields,
       mixedYieldsExpected +
           const <String>[
             r'^#3      doTestAwaitThen.<anonymous closure> ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^$',
-          ]);
+      mixedYields, mixedYieldsExpected, debugInfoFilename);
 
   final syncSuffixExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1037,22 +1081,18 @@
             r'^<asynchronous suspension>$',
             r'^#5      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       syncSuffix,
       syncSuffixExpected +
           const <String>[
             r'^#3      doTestAwaitThen.<anonymous closure> ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^$',
-          ]);
+      syncSuffix, syncSuffixExpected, debugInfoFilename);
 
   final nonAsyncNoStackExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1072,22 +1112,18 @@
             r'^<asynchronous suspension>$',
             r'^#5      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       nonAsyncNoStack,
       nonAsyncNoStackExpected +
           const <String>[
             r'^#3      doTestAwaitThen.<anonymous closure> ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitCatchError(
-      nonAsyncNoStack,
-      nonAsyncNoStackExpected +
-          const <String>[
-            r'^$',
-          ]);
+      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
 
   final asyncStarThrowSyncExpected = const <String>[
     r'^#0      throwSync \(.+/utils.dart:16(:3)?\)$',
@@ -1106,22 +1142,18 @@
             r'^<asynchronous suspension>$',
             r'^#5      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       awaitEveryAsyncStarThrowSync,
       asyncStarThrowSyncExpected +
           const <String>[
             r'^#3      doTestAwaitThen.<anonymous closure> ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
+  await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync,
+      asyncStarThrowSyncExpected, debugInfoFilename);
 
   final asyncStarThrowAsyncExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1141,22 +1173,18 @@
             r'^<asynchronous suspension>$',
             r'^#5      main ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
   await doTestAwaitThen(
       awaitEveryAsyncStarThrowAsync,
       asyncStarThrowAsyncExpected +
           const <String>[
             r'^#3      doTestAwaitThen.<anonymous closure> ',
             r'^<asynchronous suspension>$',
-            r'^$',
-          ]);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^$',
-          ]);
+          ],
+      debugInfoFilename);
+  await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync,
+      asyncStarThrowAsyncExpected, debugInfoFilename);
 
   final listenAsyncStartExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1165,12 +1193,13 @@
     r'^<asynchronous suspension>$',
     r'^#2      listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
     r'^<asynchronous suspension>$',
-    r'^$',
   ];
-  await doTestAwait(listenAsyncStarThrowAsync, listenAsyncStartExpected);
-  await doTestAwaitThen(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+  await doTestAwait(
+      listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+  await doTestAwaitThen(
+      listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
   await doTestAwaitCatchError(
-      listenAsyncStarThrowAsync, listenAsyncStartExpected);
+      listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
 
   final customErrorZoneExpected = const <String>[
     r'#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -1182,9 +1211,11 @@
     r'<asynchronous suspension>$',
     r'#4      customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$',
     r'<asynchronous suspension>$',
-    r'^$',
   ];
-  await doTestAwait(customErrorZone, customErrorZoneExpected);
-  await doTestAwaitThen(customErrorZone, customErrorZoneExpected);
-  await doTestAwaitCatchError(customErrorZone, customErrorZoneExpected);
+  await doTestAwait(
+      customErrorZone, customErrorZoneExpected, debugInfoFilename);
+  await doTestAwaitThen(
+      customErrorZone, customErrorZoneExpected, debugInfoFilename);
+  await doTestAwaitCatchError(
+      customErrorZone, customErrorZoneExpected, debugInfoFilename);
 }
diff --git a/runtime/tests/vm/dart/minimal_kernel_bytecode_test.dart b/runtime/tests/vm/dart/minimal_kernel_bytecode_test.dart
new file mode 100644
index 0000000..417f129
--- /dev/null
+++ b/runtime/tests/vm/dart/minimal_kernel_bytecode_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// OtherResources=minimal_kernel_script.dart
+
+// Tests that dill file produced with --minimal-kernel --gen-bytecode
+// options works as expected.
+
+import 'minimal_kernel_test.dart' as test;
+
+main() async {
+  await test.compileAndRunMinimalDillTest(['--gen-bytecode']);
+}
diff --git a/runtime/tests/vm/dart/minimal_kernel_script.dart b/runtime/tests/vm/dart/minimal_kernel_script.dart
new file mode 100644
index 0000000..ea3070c
--- /dev/null
+++ b/runtime/tests/vm/dart/minimal_kernel_script.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:convert";
+
+main(List<String> args) {
+  final String encoded = base64.encode(args[0].codeUnits);
+  print(String.fromCharCodes(base64.decode(encoded)));
+}
diff --git a/runtime/tests/vm/dart/minimal_kernel_test.dart b/runtime/tests/vm/dart/minimal_kernel_test.dart
new file mode 100644
index 0000000..0c7722c
--- /dev/null
+++ b/runtime/tests/vm/dart/minimal_kernel_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// OtherResources=minimal_kernel_script.dart
+
+// Tests that dill file produced with --minimal-kernel option
+// works as expected.
+
+import 'dart:io' show Platform;
+
+import 'package:path/path.dart' as path;
+import 'snapshot_test_helper.dart';
+
+compileAndRunMinimalDillTest(List<String> extraCompilationArgs) async {
+  final testScriptUri = Platform.script.resolve('minimal_kernel_script.dart');
+  final message = 'Round_trip_message';
+
+  await withTempDir((String temp) async {
+    final minimalDillPath = path.join(temp, 'minimal.dill');
+    await runGenKernel('BUILD MINIMAL DILL FILE', [
+      '--minimal-kernel',
+      '--no-link-platform',
+      ...extraCompilationArgs,
+      '--output=$minimalDillPath',
+      testScriptUri.toFilePath(),
+    ]);
+
+    final result =
+        await runDart('RUN FROM MINIMAL DILL FILE', [minimalDillPath, message]);
+    expectOutput(message, result);
+  });
+}
+
+main() async {
+  await compileAndRunMinimalDillTest([]);
+}
diff --git a/runtime/tests/vm/dart/non_smi_receiver_assert_assignable_test.dart b/runtime/tests/vm/dart/non_smi_receiver_assert_assignable_test.dart
new file mode 100644
index 0000000..b6b5814
--- /dev/null
+++ b/runtime/tests/vm/dart/non_smi_receiver_assert_assignable_test.dart
@@ -0,0 +1,22 @@
+class A {}
+
+class B extends A {}
+
+final bool kTrue = int.parse('1') == 1;
+
+final dynamic smiValue = kTrue == 1 ? 1 : 'a';
+final A barValue = kTrue ? B() : A();
+
+main() {
+  // Inlined AssertAssignable has to perform Smi check on LoadClassId.
+  smiValue as String;
+
+  // Inlined AssertAssignable can omit Smi check on LoadClassId.
+  barValue as B;
+
+  foo<int>(1);
+  foo<String>('a');
+}
+
+@pragma('vm:never-inline')
+T foo<T>(dynamic arg) => arg as T;
diff --git a/runtime/tests/vm/dart/sendandexit_test.dart b/runtime/tests/vm/dart/sendandexit_test.dart
new file mode 100644
index 0000000..f1fb1db
--- /dev/null
+++ b/runtime/tests/vm/dart/sendandexit_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--enable-isolate-groups
+//
+// Validates functionality of sendAndExit.
+
+import 'dart:_internal' show sendAndExit;
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:nativewrappers';
+
+import "package:expect/expect.dart";
+
+doNothingWorker(data) {}
+
+spawnWorker(worker, data) async {
+  Completer completer = Completer();
+  runZoned(() async {
+    final isolate = await Isolate.spawn(worker, [data]);
+    completer.complete(isolate);
+  }, onError: (e, st) => completer.complete(e));
+  return await completer.future;
+}
+
+verifyCantSendAnonymousClosure() async {
+  final result = await spawnWorker(doNothingWorker, () {});
+  Expect.equals(
+      "Invalid argument(s): Illegal argument in isolate message :"
+      " (object is a closure - Function '<anonymous closure>': static.)",
+      result.toString());
+}
+
+class NativeWrapperClass extends NativeFieldWrapperClass1 {}
+
+verifyCantSendNative() async {
+  final result = await spawnWorker(doNothingWorker, NativeWrapperClass());
+  Expect.isTrue(result.toString().startsWith("Invalid argument(s): "
+      "Illegal argument in isolate message : "
+      "(object extends NativeWrapper"));
+}
+
+verifyCantSendRegexp() async {
+  var receivePort = ReceivePort();
+  final result = await spawnWorker(doNothingWorker, receivePort);
+  Expect.equals(
+      "Invalid argument(s): Illegal argument in isolate message : "
+      "(object is a ReceivePort)",
+      result.toString());
+  receivePort.close();
+}
+
+class Message {
+  SendPort sendPort;
+  Function closure;
+
+  Message(this.sendPort, this.closure);
+}
+
+add(a, b) => a + b;
+
+worker(Message message) async {
+  final port = new ReceivePort();
+  final inbox = new StreamIterator<dynamic>(port);
+  message.sendPort.send(message.closure(2, 3));
+  port.close();
+}
+
+verifyCanSendStaticMethod() async {
+  final port = ReceivePort();
+  final inbox = StreamIterator<dynamic>(port);
+  final isolate = await Isolate.spawn(worker, Message(port.sendPort, add));
+
+  await inbox.moveNext();
+  Expect.equals(inbox.current, 5);
+  port.close();
+}
+
+verifyExitMessageIsPostedLast() async {
+  final port = ReceivePort();
+  final inbox = new StreamIterator<dynamic>(port);
+  final isolate = await Isolate.spawn(worker, Message(port.sendPort, add),
+      onExit: port.sendPort);
+
+  final receivedData = Completer<dynamic>();
+  final isolateExited = Completer<bool>();
+  port.listen((dynamic resultData) {
+    if (receivedData.isCompleted) {
+      Expect.equals(
+          resultData, null); // exit message comes after data is receivedData
+      isolateExited.complete(true);
+    } else {
+      receivedData.complete(resultData);
+    }
+  });
+  Expect.equals(await isolateExited.future, true);
+  Expect.equals(await receivedData.future, 5);
+  port.close();
+}
+
+main() async {
+  await verifyCantSendAnonymousClosure();
+  await verifyCantSendNative();
+  await verifyCantSendRegexp();
+  await verifyCanSendStaticMethod();
+  await verifyExitMessageIsPostedLast();
+}
diff --git a/runtime/tests/vm/dart/snapshot_test_helper.dart b/runtime/tests/vm/dart/snapshot_test_helper.dart
index 8ffd309..a66c247 100644
--- a/runtime/tests/vm/dart/snapshot_test_helper.dart
+++ b/runtime/tests/vm/dart/snapshot_test_helper.dart
@@ -14,6 +14,8 @@
   final ProcessResult processResult;
 
   Result(this.cmdline, this.processResult);
+
+  String get output => processResult.stdout.trim();
 }
 
 void reportError(Result result, String msg) {
@@ -36,7 +38,7 @@
 }
 
 void expectOutput(String what, Result result) {
-  if (result.processResult.stdout.trim() != what) {
+  if (result.output != what) {
     reportError(result, 'Expected test to print \'${what}\' to stdout');
   }
 }
diff --git a/runtime/tests/vm/dart/splay_test.dart b/runtime/tests/vm/dart/splay_test.dart
index a91c853..eae1cbb 100644
--- a/runtime/tests/vm/dart/splay_test.dart
+++ b/runtime/tests/vm/dart/splay_test.dart
@@ -19,6 +19,10 @@
 // VMOptions=--concurrent_mark --concurrent_sweep
 // VMOptions=--concurrent_mark --use_compactor
 // VMOptions=--concurrent_mark --use_compactor --force_evacuation
+// VMOptions=--scavenger_tasks=0
+// VMOptions=--scavenger_tasks=1
+// VMOptions=--scavenger_tasks=2
+// VMOptions=--scavenger_tasks=3
 // VMOptions=--verify_before_gc
 // VMOptions=--verify_after_gc
 // VMOptions=--verify_before_gc --verify_after_gc
diff --git a/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart b/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
index 6b115e1..00c7f4f 100644
--- a/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
+++ b/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
@@ -54,15 +54,21 @@
     // Run the AOT compiler with/without Dwarf stack traces.
     final scriptDwarfSnapshot = path.join(tempDir, 'dwarf.so');
     final scriptNonDwarfSnapshot = path.join(tempDir, 'non_dwarf.so');
+    final scriptDwarfDebugInfo = path.join(tempDir, 'debug_info.so');
     await Future.wait(<Future>[
       run(genSnapshot, <String>[
-        '--dwarf-stack-traces',
+        // We test --dwarf-stack-traces-mode, not --dwarf-stack-traces, because
+        // the latter is a handler that sets the former and also may change
+        // other flags. This way, we limit the difference between the two
+        // snapshots and also directly test the flag saved as a VM global flag.
+        '--dwarf-stack-traces-mode',
+        '--save-debugging-info=$scriptDwarfDebugInfo',
         '--snapshot-kind=app-aot-elf',
         '--elf=$scriptDwarfSnapshot',
         scriptDill,
       ]),
       run(genSnapshot, <String>[
-        '--no-dwarf-stack-traces',
+        '--no-dwarf-stack-traces-mode',
         '--snapshot-kind=app-aot-elf',
         '--elf=$scriptNonDwarfSnapshot',
         scriptDill,
@@ -70,27 +76,25 @@
     ]);
 
     // Run the resulting Dwarf-AOT compiled script.
-    final dwarfOut1 = await runError(aotRuntime, <String>[
-      '--dwarf-stack-traces',
+    final dwarfTrace1 = await runError(aotRuntime, <String>[
+      '--dwarf-stack-traces-mode',
       scriptDwarfSnapshot,
       scriptDill,
     ]);
-    final dwarfTrace1 = cleanStacktrace(dwarfOut1);
-    final dwarfOut2 = await runError(aotRuntime, <String>[
-      '--no-dwarf-stack-traces',
+    final dwarfTrace2 = await runError(aotRuntime, <String>[
+      '--no-dwarf-stack-traces-mode',
       scriptDwarfSnapshot,
       scriptDill,
     ]);
-    final dwarfTrace2 = cleanStacktrace(dwarfOut2);
 
     // Run the resulting non-Dwarf-AOT compiled script.
     final nonDwarfTrace1 = await runError(aotRuntime, <String>[
-      '--dwarf-stack-traces',
+      '--dwarf-stack-traces-mode',
       scriptNonDwarfSnapshot,
       scriptDill,
     ]);
     final nonDwarfTrace2 = await runError(aotRuntime, <String>[
-      '--no-dwarf-stack-traces',
+      '--no-dwarf-stack-traces-mode',
       scriptNonDwarfSnapshot,
       scriptDill,
     ]);
@@ -104,10 +108,35 @@
     // out of the stack trace, those should be equal.
     Expect.deepEquals(
         collectPCOffsets(dwarfTrace1), collectPCOffsets(dwarfTrace2));
+
+    // Check that translating the DWARF stack trace (without internal frames)
+    // matches the symbolic stack trace.
+    final dwarf = Dwarf.fromFile(scriptDwarfDebugInfo);
+    assert(dwarf != null);
+    final translatedDwarfTrace1 = await Stream.fromIterable(dwarfTrace1)
+        .transform(DwarfStackTraceDecoder(dwarf))
+        .toList();
+
+    final translatedStackFrames = onlySymbolicFrameLines(translatedDwarfTrace1);
+    final originalStackFrames = onlySymbolicFrameLines(nonDwarfTrace1);
+
+    print('Stack frames from translated non-symbolic stack trace:');
+    translatedStackFrames.forEach(print);
+    print('');
+
+    print('Stack frames from original symbolic stack trace:');
+    originalStackFrames.forEach(print);
+    print('');
+
+    Expect.isTrue(translatedStackFrames.length > 0);
+    Expect.isTrue(originalStackFrames.length > 0);
+
+    Expect.deepEquals(translatedStackFrames, originalStackFrames);
   });
 }
 
-Iterable<String> cleanStacktrace(Iterable<String> lines) {
-  // For DWARF stack traces, the pid/tid, if output, will vary over runs.
-  return lines.where((line) => !line.startsWith('pid'));
+final _symbolicFrameRE = RegExp(r'^#\d+\s+');
+
+Iterable<String> onlySymbolicFrameLines(Iterable<String> lines) {
+  return lines.where((line) => _symbolicFrameRE.hasMatch(line));
 }
diff --git a/runtime/tests/vm/dart/use_flag_test_helper.dart b/runtime/tests/vm/dart/use_flag_test_helper.dart
index c6fa872..fe9c511 100644
--- a/runtime/tests/vm/dart/use_flag_test_helper.dart
+++ b/runtime/tests/vm/dart/use_flag_test_helper.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:expect/expect.dart';
@@ -152,7 +153,9 @@
   Expect.isTrue(result.stdout.isNotEmpty);
   Expect.isTrue(result.stderr.isEmpty);
 
-  return result.stdout.split(RegExp(r'[\r\n]'));
+  return await Stream.value(result.stdout as String)
+      .transform(const LineSplitter())
+      .toList();
 }
 
 Future<Iterable<String>> runError(String executable, List<String> args) async {
@@ -164,7 +167,9 @@
   Expect.isTrue(result.stdout.isEmpty);
   Expect.isTrue(result.stderr.isNotEmpty);
 
-  return result.stderr.split(RegExp(r'[\r\n]'));
+  return await Stream.value(result.stderr as String)
+      .transform(const LineSplitter())
+      .toList();
 }
 
 const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';
diff --git a/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart b/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart
index b46d695..e098c5a 100644
--- a/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart
+++ b/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart
@@ -110,20 +110,20 @@
     // Stripped output should not change when --save-debugging-info is used.
     compareSnapshots(scriptStrippedOnlySnapshot, scriptStrippedSnapshot);
 
-    final stackTraceWithTerminators = strippedTrace.map((String s) => s + "\n");
-    print("\nOriginal stack trace:");
-    print(stackTraceWithTerminators.join());
+    print('');
+    print("Original stack trace:");
+    strippedTrace.forEach(print);
 
     final debugDwarf = Dwarf.fromFile(scriptDebuggingInfo);
     final wholeDwarf = Dwarf.fromFile(scriptWholeSnapshot);
 
-    final fromDebug = await Stream.fromIterable(stackTraceWithTerminators)
+    final fromDebug = await Stream.fromIterable(strippedTrace)
         .transform(DwarfStackTraceDecoder(debugDwarf))
         .toList();
     print("\nStack trace converted using separate debugging info:");
     print(fromDebug.join());
 
-    final fromWhole = await Stream.fromIterable(stackTraceWithTerminators)
+    final fromWhole = await Stream.fromIterable(strippedTrace)
         .transform(DwarfStackTraceDecoder(wholeDwarf))
         .toList();
     print("\nStack trace converted using unstripped ELF file:");
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index c22bccd..7011e5b 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -13,6 +13,8 @@
 cc/IsolateReload_PendingUnqualifiedCall_StaticToInstance: Fail # Issue 32981
 dart/data_uri_import_test/none: SkipByDesign
 dart/emit_aot_size_info_flag_test: Pass, Slow # Spawns several subprocesses
+dart/minimal_kernel_bytecode_test: Pass, Slow # Spawns several subprocesses
+dart/minimal_kernel_test: Pass, Slow # Spawns several subprocesses
 dart/slow_path_shared_stub_test: Pass, Slow # Uses --shared-slow-path-triggers-gc flag.
 dart/snapshot_version_test: Skip # This test is a Dart1 test (script snapshot)
 dart/stack_overflow_shared_test: Pass, Slow # Uses --shared-slow-path-triggers-gc flag.
@@ -26,12 +28,17 @@
 dart/bytecode_with_ast_in_aot_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
 
 [ $builder_tag == obfuscated ]
-dart/causal_stacks/*: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/async_throws_stack_lazy_test: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/async_throws_stack_no_causal_test: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/async_throws_stack_test: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/sync_async_start_pkg_test_test: SkipByDesign # Asserts exact stacktrace output.
 
 [ $builder_tag == optimization_counter_threshold ]
 cc/*: Skip # Many tests want see unoptimized code running
 dart/appjit*: SkipByDesign # Test needs to a particular opt-counter value
 dart/kernel_determinism_test: SkipSlow
+dart/minimal_kernel_bytecode_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
+dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
 
 [ $builder_tag == tsan ]
 dart/appjit_cha_deopt_test: SkipSlow
@@ -57,6 +64,8 @@
 cc/VerifyExplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
 cc/VerifyImplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
 dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
+dart/minimal_kernel_bytecode_test: SkipSlow # gen_kernel is too slow in debug mode
+dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow in debug mode
 dart/spawn_shutdown_test: Pass, Slow # VM Shutdown test, It can take some time for all the isolates to shutdown in a Debug build.
 
 [ $mode == product ]
@@ -117,6 +126,8 @@
 dart/appjit*: SkipByDesign # Test needs to run from source
 dart/bytecode_and_ast_mix_test: SkipByDesign # Test needs to run from source
 dart/kernel_determinism_test: SkipByDesign # Test needs to run from source
+dart/minimal_kernel_bytecode_test: SkipByDesign # Test needs to run from source
+dart/minimal_kernel_test: SkipByDesign # Test needs to run from source
 dart/snapshot_depfile_test: SkipByDesign # Test needs to run from source
 
 [ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
@@ -176,6 +187,8 @@
 [ ($arch == simarm || $arch == simarm64) && ($compiler == dartk || $compiler == dartkb) ]
 dart/appjit*: SkipSlow # DFE too slow
 dart/data_uri_spawn_test: Skip # Please triage.
+dart/minimal_kernel_bytecode_test: SkipSlow # gen_kernel is too slow on simulated architectures
+dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
 dart/snapshot_version_test: RuntimeError # Please triage.
 
 [ $hot_reload || $hot_reload_rollback ]
@@ -274,6 +287,8 @@
 dart/compilation_trace_test: Pass, Slow
 dart/disassemble_determinism_test: SkipSlow # Runs expensive fibonacci(32) computation in 2 subprocesses
 dart/issue_31959_31960_test: SkipSlow
+dart/minimal_kernel_bytecode_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
+dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart/print_flow_graph_determinism_test: SkipSlow
 dart/slow_path_shared_stub_test: SkipSlow # Too slow with --shared-slow-path-triggers-gc flag and not relevant outside precompiled.
 dart/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index bac066b..7ab44f4 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -71,7 +71,10 @@
     if (using_fuchsia_sdk) {
       extra_deps += [
         "$fuchsia_sdk_root/fidl:fuchsia.deprecatedtimezone",
+        "$fuchsia_sdk_root/pkg:inspect",
+        "$fuchsia_sdk_root/pkg:inspect_service_cpp",
         "$fuchsia_sdk_root/pkg:sys_cpp",
+        "$fuchsia_sdk_root/pkg:sys_inspect_cpp",
         "$fuchsia_sdk_root/pkg:trace-engine",
       ]
     } else {
@@ -90,11 +93,33 @@
                                   "*_test.cc",
                                   "*_test.h",
                                 ])
-  sources = vm_sources + rebase_path(compiler_sources, ".", "./compiler/") +
+  sources = vm_sources + rebase_path(compiler_api_sources, ".", "./compiler/") +
+            rebase_path(disassembler_sources, ".", "./compiler/") +
             rebase_path(heap_sources, ".", "./heap/")
   include_dirs = [ ".." ]
 }
 
+library_for_all_configs_with_compiler("libdart_compiler") {
+  target_type = "source_set"
+  public_configs = [ ":libdart_vm_config" ]
+  set_sources_assignment_filter([
+                                  "*_test.cc",
+                                  "*_test.h",
+                                ])
+  sources = rebase_path(compiler_sources, ".", "./compiler/")
+  include_dirs = [ ".." ]
+  if (is_fuchsia) {
+    if (using_fuchsia_sdk) {
+      extra_deps = [ "$fuchsia_sdk_root/pkg:trace-engine" ]
+    } else {
+      extra_deps = [
+        "//zircon/public/lib/fbl",
+        "//zircon/public/lib/trace-engine",
+      ]
+    }
+  }
+}
+
 library_for_all_configs("libdart_lib") {
   target_type = "source_set"
   if (is_fuchsia) {
diff --git a/runtime/vm/bitmap_test.cc b/runtime/vm/bitmap_test.cc
index e8f6418..2c7f3d9 100644
--- a/runtime/vm/bitmap_test.cc
+++ b/runtime/vm/bitmap_test.cc
@@ -16,7 +16,7 @@
 static const uint32_t kTestPcOffset = 0x4;
 static const intptr_t kTestSpillSlotBitCount = 0;
 
-static RawCompressedStackMaps* MapsFromBuilder(BitmapBuilder* bmap) {
+static CompressedStackMapsPtr MapsFromBuilder(BitmapBuilder* bmap) {
   CompressedStackMapsBuilder builder;
   builder.AddEntry(kTestPcOffset, bmap, kTestSpillSlotBitCount);
   return builder.Finalize();
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 67ff960..1065295 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -90,9 +90,9 @@
   ClassFinalizer::LoadClassMembers(cls);
 }
 
-static RawError* BootstrapFromKernel(Thread* thread,
-                                     const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_size) {
+static ErrorPtr BootstrapFromKernel(Thread* thread,
+                                    const uint8_t* kernel_buffer,
+                                    intptr_t kernel_buffer_size) {
   Zone* zone = thread->zone();
   const char* error = nullptr;
   std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
@@ -140,8 +140,8 @@
   return Error::null();
 }
 
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_size) {
+ErrorPtr Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+                                    intptr_t kernel_buffer_size) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -167,8 +167,8 @@
   return BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_size);
 }
 #else
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_size) {
+ErrorPtr Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+                                    intptr_t kernel_buffer_size) {
   UNREACHABLE();
   return Error::null();
 }
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 895f9d1..e9c3bd9 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -7,11 +7,11 @@
 
 #include "include/dart_api.h"
 #include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
 // Forward declarations.
-class RawError;
 namespace kernel {
 class Program;
 }
@@ -24,8 +24,8 @@
   // bootstrapping.
   // The caller of this function is responsible for managing the kernel
   // program's memory.
-  static RawError* DoBootstrapping(const uint8_t* kernel_buffer,
-                                   intptr_t kernel_buffer_size);
+  static ErrorPtr DoBootstrapping(const uint8_t* kernel_buffer,
+                                  intptr_t kernel_buffer_size);
 
   static void SetupNativeResolver();
   static bool IsBootstrapResolver(Dart_NativeEntryResolver resolver);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 8f3b762..aab5d58 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -58,6 +58,7 @@
   V(SendPortImpl_get_id, 1)                                                    \
   V(SendPortImpl_get_hashcode, 1)                                              \
   V(SendPortImpl_sendInternal_, 2)                                             \
+  V(SendPortImpl_sendAndExitInternal_, 2)                                      \
   V(Smi_bitAndFromSmi, 2)                                                      \
   V(Smi_bitNegate, 1)                                                          \
   V(Smi_bitLength, 1)                                                          \
@@ -316,8 +317,8 @@
   V(Int32x4_setFlagZ, 2)                                                       \
   V(Int32x4_setFlagW, 2)                                                       \
   V(Int32x4_select, 3)                                                         \
-  V(Isolate_spawnFunction, 11)                                                 \
-  V(Isolate_spawnUri, 13)                                                      \
+  V(Isolate_spawnFunction, 10)                                                 \
+  V(Isolate_spawnUri, 12)                                                      \
   V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0)                         \
   V(Isolate_getCurrentRootUriStr, 0)                                           \
   V(Isolate_sendOOB, 2)                                                        \
@@ -370,7 +371,6 @@
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
   V(VMService_DecodeAssets, 1)                                                 \
-  V(VMService_spawnUriNotify, 2)                                               \
   V(Ffi_loadInt8, 2)                                                           \
   V(Ffi_loadInt16, 2)                                                          \
   V(Ffi_loadInt32, 2)                                                          \
@@ -487,8 +487,8 @@
   static const uint8_t* Symbol(Dart_NativeFunction* nf);
 
 #define DECLARE_BOOTSTRAP_NATIVE(name, ignored)                                \
-  static RawObject* DN_##name(Thread* thread, Zone* zone,                      \
-                              NativeArguments* arguments);
+  static ObjectPtr DN_##name(Thread* thread, Zone* zone,                       \
+                             NativeArguments* arguments);
 
   BOOTSTRAP_NATIVE_LIST(DECLARE_BOOTSTRAP_NATIVE)
 #if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/bss_relocs.cc b/runtime/vm/bss_relocs.cc
index 12809a7..7df4242 100644
--- a/runtime/vm/bss_relocs.cc
+++ b/runtime/vm/bss_relocs.cc
@@ -8,16 +8,23 @@
 
 namespace dart {
 
-void BSS::Initialize(Thread* current, uword* bss_start) {
-  std::atomic<uword>* slot =
-      reinterpret_cast<std::atomic<uword>*>(&bss_start[BSS::RelocationIndex(
-          BSS::Relocation::DRT_GetThreadForNativeCallback)]);
+static void InitializeBSSEntry(BSS::Relocation relocation,
+                               uword function_address,
+                               uword* bss_start) {
+  std::atomic<uword>* slot = reinterpret_cast<std::atomic<uword>*>(
+      &bss_start[BSS::RelocationIndex(relocation)]);
   uword old_value = slot->load(std::memory_order_relaxed);
-  uword new_value = reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback);
+  uword new_value = function_address;
   if (!slot->compare_exchange_strong(old_value, new_value,
                                      std::memory_order_relaxed)) {
     RELEASE_ASSERT(old_value == new_value);
   }
 }
 
+void BSS::Initialize(Thread* current, uword* bss_start) {
+  InitializeBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback,
+                     reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback),
+                     bss_start);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 857e1f4..cfe2a4d 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -668,10 +668,10 @@
   }
 }
 
-RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
-                                              const AbstractType& type,
-                                              FinalizationKind finalization,
-                                              PendingTypes* pending_types) {
+AbstractTypePtr ClassFinalizer::FinalizeType(const Class& cls,
+                                             const AbstractType& type,
+                                             FinalizationKind finalization,
+                                             PendingTypes* pending_types) {
   // Only the 'root' type of the graph can be canonicalized, after all depending
   // types have been bound checked.
   ASSERT((pending_types == NULL) || (finalization < kCanonicalize));
@@ -1186,7 +1186,7 @@
   }
 }
 
-RawError* ClassFinalizer::LoadClassMembers(const Class& cls) {
+ErrorPtr ClassFinalizer::LoadClassMembers(const Class& cls) {
   ASSERT(Thread::Current()->IsMutatorThread());
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
@@ -1474,21 +1474,21 @@
     return old_to_new_cids_[cid];
   }
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     if (obj->IsClass()) {
-      RawClass* cls = Class::RawCast(obj);
+      ClassPtr cls = Class::RawCast(obj);
       cls->ptr()->id_ = Map(cls->ptr()->id_);
     } else if (obj->IsField()) {
-      RawField* field = Field::RawCast(obj);
+      FieldPtr field = Field::RawCast(obj);
       field->ptr()->guarded_cid_ = Map(field->ptr()->guarded_cid_);
       field->ptr()->is_nullable_ = Map(field->ptr()->is_nullable_);
     } else if (obj->IsTypeParameter()) {
-      RawTypeParameter* param = TypeParameter::RawCast(obj);
+      TypeParameterPtr param = TypeParameter::RawCast(obj);
       param->ptr()->parameterized_class_id_ =
           Map(param->ptr()->parameterized_class_id_);
     } else if (obj->IsType()) {
-      RawType* type = Type::RawCast(obj);
-      RawObject* id = type->ptr()->type_class_id_;
+      TypePtr type = Type::RawCast(obj);
+      ObjectPtr id = type->ptr()->type_class_id_;
       if (!id->IsHeapObject()) {
         type->ptr()->type_class_id_ =
             Smi::New(Map(Smi::Value(Smi::RawCast(id))));
@@ -1499,7 +1499,7 @@
       if (old_cid != new_cid) {
         // Don't touch objects that are unchanged. In particular, Instructions,
         // which are write-protected.
-        obj->SetClassId(new_cid);
+        obj->ptr()->SetClassId(new_cid);
       }
     }
   }
@@ -1519,7 +1519,7 @@
     // The [HeapIterationScope] also safepoints all threads.
     HeapIterationScope his(T);
 
-    IG->class_table()->Remap(old_to_new_cid);
+    IG->shared_class_table()->Remap(old_to_new_cid);
     IG->ForEachIsolate(
         [&](Isolate* I) {
           I->set_remapping_cids(true);
@@ -1558,30 +1558,30 @@
 // In the Dart VM heap the following instances directly use cids for the
 // computation of canonical hash codes:
 //
-//    * RawType (due to RawType::type_class_id_)
-//    * RawTypeParameter (due to RawTypeParameter::parameterized_class_id_)
+//    * RawType (due to TypeLayout::type_class_id_)
+//    * RawTypeParameter (due to TypeParameterLayout::parameterized_class_id_)
 //
 // The following instances use cids for the computation of canonical hash codes
 // indirectly:
 //
-//    * RawTypeRef (due to RawTypeRef::type_->type_class_id)
-//    * RawType (due to RawType::signature_'s result/parameter types)
+//    * RawTypeRef (due to TypeRefLayout::type_->type_class_id)
+//    * RawType (due to TypeLayout::signature_'s result/parameter types)
 //    * RawTypeArguments (due to type references)
 //    * RawInstance (due to instance fields)
 //    * RawArray (due to type arguments & array entries)
 //
 // Caching of the canonical hash codes happens for:
 //
-//    * RawType::hash_
-//    * RawTypeParameter::hash_
-//    * RawTypeArguments::hash_
+//    * TypeLayout::hash_
+//    * TypeParameterLayout::hash_
+//    * TypeArgumentsLayout::hash_
 //    * RawInstance (weak table)
 //    * RawArray (weak table)
 //
 // No caching of canonical hash codes (i.e. it gets re-computed every time)
 // happens for:
 //
-//    * RawTypeRef (computed via RawTypeRef::type_->type_class_id)
+//    * RawTypeRef (computed via TypeRefLayout::type_->type_class_id)
 //
 // Usages of canonical hash codes are:
 //
@@ -1596,7 +1596,7 @@
         type_(Type::Handle(zone)),
         type_args_(TypeArguments::Handle(zone)) {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     if (obj->IsTypeParameter()) {
       type_param_ ^= obj;
       type_param_.SetHash(0);
@@ -1699,8 +1699,27 @@
     }
   }
 
-  class ClearCodeFunctionVisitor : public FunctionVisitor {
-    void Visit(const Function& function) {
+  auto const thread = Thread::Current();
+  auto const isolate = thread->isolate();
+  StackZone stack_zone(thread);
+  HANDLESCOPE(thread);
+  auto const zone = thread->zone();
+
+  class ClearCodeVisitor : public FunctionVisitor {
+   public:
+    ClearCodeVisitor(Zone* zone, bool force)
+        : force_(force),
+          bytecode_(Bytecode::Handle(zone)),
+          pool_(ObjectPool::Handle(zone)),
+          entry_(Object::Handle(zone)) {}
+
+    void VisitClass(const Class& cls) {
+      if (force_ || cls.id() >= kNumPredefinedCids) {
+        cls.DisableAllocationStub();
+      }
+    }
+
+    void VisitFunction(const Function& function) {
       bytecode_ = function.bytecode();
       if (!bytecode_.IsNull()) {
         pool_ = bytecode_.object_pool();
@@ -1720,41 +1739,27 @@
       function.ClearICDataArray();
     }
 
-    Bytecode& bytecode_ = Bytecode::Handle();
-    ObjectPool& pool_ = ObjectPool::Handle();
-    Object& entry_ = Object::Handle();
-  };
-  ClearCodeFunctionVisitor function_visitor;
-  ProgramVisitor::VisitFunctions(&function_visitor);
-
-  class ClearCodeClassVisitor : public ClassVisitor {
-   public:
-    explicit ClearCodeClassVisitor(bool force) : force_(force) {}
-
-    void Visit(const Class& cls) {
-      if (force_ || cls.id() >= kNumPredefinedCids) {
-        cls.DisableAllocationStub();
-      }
-    }
-
    private:
-    bool force_;
+    const bool force_;
+    Bytecode& bytecode_;
+    ObjectPool& pool_;
+    Object& entry_;
   };
-  ClearCodeClassVisitor class_visitor(including_nonchanging_cids);
-  ProgramVisitor::VisitClasses(&class_visitor);
+
+  ClearCodeVisitor visitor(zone, including_nonchanging_cids);
+  ProgramVisitor::WalkProgram(zone, isolate, &visitor);
 
   // Apart from normal function code and allocation stubs we have two global
   // code objects to clear.
   if (including_nonchanging_cids) {
-    auto thread = Thread::Current();
-    auto object_store = thread->isolate()->object_store();
-    auto& null_code = Code::Handle(thread->zone());
+    auto object_store = isolate->object_store();
+    auto& null_code = Code::Handle(zone);
     object_store->set_build_method_extractor_code(null_code);
 
-    auto& miss_function = Function::Handle(
-        thread->zone(), object_store->megamorphic_miss_function());
+    auto& miss_function =
+        Function::Handle(zone, object_store->megamorphic_call_miss_function());
     miss_function.ClearCode();
-    object_store->SetMegamorphicMissHandler(null_code, miss_function);
+    object_store->SetMegamorphicCallMissHandler(null_code, miss_function);
   }
 #endif  // !DART_PRECOMPILED_RUNTIME
 }
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index f580aaf..b970fa1 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -27,7 +27,7 @@
 
   // Finalize given type while parsing class cls.
   // Also canonicalize and bound check type if applicable.
-  static RawAbstractType* FinalizeType(
+  static AbstractTypePtr FinalizeType(
       const Class& cls,
       const AbstractType& type,
       FinalizationKind finalization = kCanonicalize,
@@ -69,7 +69,7 @@
   // and fields of the class.
   //
   // Returns Error::null() if there is no loading error.
-  static RawError* LoadClassMembers(const Class& cls);
+  static ErrorPtr LoadClassMembers(const Class& cls);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // Verify that the classes have been properly prefinalized. This is
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 7768c44..29a708a 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -9,7 +9,7 @@
 
 namespace dart {
 
-static RawClass* CreateTestClass(const char* name) {
+static ClassPtr CreateTestClass(const char* name) {
   const String& class_name =
       String::Handle(Symbols::New(Thread::Current(), name));
   const Script& script = Script::Handle();
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index a5d003c..40f6897 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -10,6 +10,8 @@
 // Note: we assume that all builds of Dart VM use exactly the same class ids
 // for these classes.
 
+#include "platform/assert.h"
+
 namespace dart {
 
 #define CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                           \
@@ -41,6 +43,7 @@
   V(SingleTargetCache)                                                         \
   V(UnlinkedCall)                                                              \
   V(MonomorphicSmiableCall)                                                    \
+  V(CallSiteData)                                                              \
   V(ICData)                                                                    \
   V(MegamorphicCache)                                                          \
   V(SubtypeTestCache)                                                          \
@@ -175,7 +178,7 @@
   V(Object)                                                                    \
   CLASS_LIST_NO_OBJECT(V)
 
-enum ClassId {
+enum ClassId : intptr_t {
   // Illegal class id.
   kIllegalCid = 0,
 
@@ -226,6 +229,238 @@
 const int kTypedDataCidRemainderView = 1;
 const int kTypedDataCidRemainderExternal = 2;
 
+// Class Id predicates.
+
+bool IsErrorClassId(intptr_t index);
+bool IsNumberClassId(intptr_t index);
+bool IsIntegerClassId(intptr_t index);
+bool IsStringClassId(intptr_t index);
+bool IsOneByteStringClassId(intptr_t index);
+bool IsTwoByteStringClassId(intptr_t index);
+bool IsExternalStringClassId(intptr_t index);
+bool IsBuiltinListClassId(intptr_t index);
+bool IsTypedDataBaseClassId(intptr_t index);
+bool IsTypedDataClassId(intptr_t index);
+bool IsTypedDataViewClassId(intptr_t index);
+bool IsExternalTypedDataClassId(intptr_t index);
+bool IsFfiNativeTypeTypeClassId(intptr_t index);
+bool IsFfiPointerClassId(intptr_t index);
+bool IsFfiTypeClassId(intptr_t index);
+bool IsFfiTypeIntClassId(intptr_t index);
+bool IsFfiTypeDoubleClassId(intptr_t index);
+bool IsFfiTypeVoidClassId(intptr_t index);
+bool IsFfiTypeNativeFunctionClassId(intptr_t index);
+bool IsFfiDynamicLibraryClassId(intptr_t index);
+bool IsFfiClassId(intptr_t index);
+bool IsInternalVMdefinedClassId(intptr_t index);
+bool IsVariableSizeClassId(intptr_t index);
+bool IsImplicitFieldClassId(intptr_t index);
+intptr_t NumberOfTypedDataClasses();
+
+inline bool IsErrorClassId(intptr_t index) {
+  // Make sure this function is updated when new Error types are added.
+  COMPILE_ASSERT(
+      kApiErrorCid == kErrorCid + 1 && kLanguageErrorCid == kErrorCid + 2 &&
+      kUnhandledExceptionCid == kErrorCid + 3 &&
+      kUnwindErrorCid == kErrorCid + 4 && kInstanceCid == kErrorCid + 5);
+  return (index >= kErrorCid && index < kInstanceCid);
+}
+
+inline bool IsNumberClassId(intptr_t index) {
+  // Make sure this function is updated when new Number types are added.
+  COMPILE_ASSERT(kIntegerCid == kNumberCid + 1 && kSmiCid == kNumberCid + 2 &&
+                 kMintCid == kNumberCid + 3 && kDoubleCid == kNumberCid + 4);
+  return (index >= kNumberCid && index <= kDoubleCid);
+}
+
+inline bool IsIntegerClassId(intptr_t index) {
+  // Make sure this function is updated when new Integer types are added.
+  COMPILE_ASSERT(kSmiCid == kIntegerCid + 1 && kMintCid == kIntegerCid + 2);
+  return (index >= kIntegerCid && index <= kMintCid);
+}
+
+inline bool IsStringClassId(intptr_t index) {
+  // Make sure this function is updated when new StringCid types are added.
+  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
+                 kTwoByteStringCid == kStringCid + 2 &&
+                 kExternalOneByteStringCid == kStringCid + 3 &&
+                 kExternalTwoByteStringCid == kStringCid + 4);
+  return (index >= kStringCid && index <= kExternalTwoByteStringCid);
+}
+
+inline bool IsOneByteStringClassId(intptr_t index) {
+  // Make sure this function is updated when new StringCid types are added.
+  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
+                 kTwoByteStringCid == kStringCid + 2 &&
+                 kExternalOneByteStringCid == kStringCid + 3 &&
+                 kExternalTwoByteStringCid == kStringCid + 4);
+  return (index == kOneByteStringCid || index == kExternalOneByteStringCid);
+}
+
+inline bool IsTwoByteStringClassId(intptr_t index) {
+  // Make sure this function is updated when new StringCid types are added.
+  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
+                 kTwoByteStringCid == kStringCid + 2 &&
+                 kExternalOneByteStringCid == kStringCid + 3 &&
+                 kExternalTwoByteStringCid == kStringCid + 4);
+  return (index == kTwoByteStringCid || index == kExternalTwoByteStringCid);
+}
+
+inline bool IsExternalStringClassId(intptr_t index) {
+  // Make sure this function is updated when new StringCid types are added.
+  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
+                 kTwoByteStringCid == kStringCid + 2 &&
+                 kExternalOneByteStringCid == kStringCid + 3 &&
+                 kExternalTwoByteStringCid == kStringCid + 4);
+  return (index == kExternalOneByteStringCid ||
+          index == kExternalTwoByteStringCid);
+}
+
+inline bool IsBuiltinListClassId(intptr_t index) {
+  // Make sure this function is updated when new builtin List types are added.
+  COMPILE_ASSERT(kImmutableArrayCid == kArrayCid + 1);
+  return ((index >= kArrayCid && index <= kImmutableArrayCid) ||
+          (index == kGrowableObjectArrayCid) || IsTypedDataBaseClassId(index) ||
+          (index == kByteBufferCid));
+}
+
+inline bool IsTypedDataBaseClassId(intptr_t index) {
+  // Make sure this is updated when new TypedData types are added.
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 == kTypedDataUint8ArrayCid);
+  return index >= kTypedDataInt8ArrayCid && index < kByteDataViewCid;
+}
+
+inline bool IsTypedDataClassId(intptr_t index) {
+  // Make sure this is updated when new TypedData types are added.
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 == kTypedDataUint8ArrayCid);
+  return IsTypedDataBaseClassId(index) && ((index - kTypedDataInt8ArrayCid) %
+                                           3) == kTypedDataCidRemainderInternal;
+}
+
+inline bool IsTypedDataViewClassId(intptr_t index) {
+  // Make sure this is updated when new TypedData types are added.
+  COMPILE_ASSERT(kTypedDataInt8ArrayViewCid + 3 == kTypedDataUint8ArrayViewCid);
+
+  const bool is_byte_data_view = index == kByteDataViewCid;
+  return is_byte_data_view ||
+         (IsTypedDataBaseClassId(index) &&
+          ((index - kTypedDataInt8ArrayCid) % 3) == kTypedDataCidRemainderView);
+}
+
+inline bool IsExternalTypedDataClassId(intptr_t index) {
+  // Make sure this is updated when new TypedData types are added.
+  COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid + 3 ==
+                 kExternalTypedDataUint8ArrayCid);
+
+  return IsTypedDataBaseClassId(index) && ((index - kTypedDataInt8ArrayCid) %
+                                           3) == kTypedDataCidRemainderExternal;
+}
+
+inline bool IsFfiNativeTypeTypeClassId(intptr_t index) {
+  return index == kFfiNativeTypeCid;
+}
+
+inline bool IsFfiTypeClassId(intptr_t index) {
+  // Make sure this is updated when new Ffi types are added.
+  COMPILE_ASSERT(kFfiNativeFunctionCid == kFfiPointerCid + 1 &&
+                 kFfiInt8Cid == kFfiPointerCid + 2 &&
+                 kFfiInt16Cid == kFfiPointerCid + 3 &&
+                 kFfiInt32Cid == kFfiPointerCid + 4 &&
+                 kFfiInt64Cid == kFfiPointerCid + 5 &&
+                 kFfiUint8Cid == kFfiPointerCid + 6 &&
+                 kFfiUint16Cid == kFfiPointerCid + 7 &&
+                 kFfiUint32Cid == kFfiPointerCid + 8 &&
+                 kFfiUint64Cid == kFfiPointerCid + 9 &&
+                 kFfiIntPtrCid == kFfiPointerCid + 10 &&
+                 kFfiFloatCid == kFfiPointerCid + 11 &&
+                 kFfiDoubleCid == kFfiPointerCid + 12 &&
+                 kFfiVoidCid == kFfiPointerCid + 13);
+  return (index >= kFfiPointerCid && index <= kFfiVoidCid);
+}
+
+inline bool IsFfiTypeIntClassId(intptr_t index) {
+  return (index >= kFfiInt8Cid && index <= kFfiIntPtrCid);
+}
+
+inline bool IsFfiTypeDoubleClassId(intptr_t index) {
+  return (index >= kFfiFloatCid && index <= kFfiDoubleCid);
+}
+
+inline bool IsFfiPointerClassId(intptr_t index) {
+  return index == kFfiPointerCid;
+}
+
+inline bool IsFfiTypeVoidClassId(intptr_t index) {
+  return index == kFfiVoidCid;
+}
+
+inline bool IsFfiTypeNativeFunctionClassId(intptr_t index) {
+  return index == kFfiNativeFunctionCid;
+}
+
+inline bool IsFfiClassId(intptr_t index) {
+  return (index >= kFfiPointerCid && index <= kFfiVoidCid);
+}
+
+inline bool IsFfiDynamicLibraryClassId(intptr_t index) {
+  return index == kFfiDynamicLibraryCid;
+}
+
+inline bool IsInternalVMdefinedClassId(intptr_t index) {
+  return ((index < kNumPredefinedCids) && !IsImplicitFieldClassId(index));
+}
+
+inline bool IsVariableSizeClassId(intptr_t index) {
+  return (index == kArrayCid) || (index == kImmutableArrayCid) ||
+         IsOneByteStringClassId(index) || IsTwoByteStringClassId(index) ||
+         IsTypedDataClassId(index) || (index == kContextCid) ||
+         (index == kTypeArgumentsCid) || (index == kInstructionsCid) ||
+         (index == kInstructionsSectionCid) || (index == kObjectPoolCid) ||
+         (index == kPcDescriptorsCid) || (index == kCodeSourceMapCid) ||
+         (index == kCompressedStackMapsCid) ||
+         (index == kLocalVarDescriptorsCid) ||
+         (index == kExceptionHandlersCid) || (index == kCodeCid) ||
+         (index == kContextScopeCid) || (index == kInstanceCid) ||
+         (index == kRegExpCid);
+}
+
+// This is a set of classes that are not Dart classes whose representation
+// is defined by the VM but are used in the VM code by computing the
+// implicit field offsets of the various fields in the dart object.
+inline bool IsImplicitFieldClassId(intptr_t index) {
+  return index == kByteBufferCid;
+}
+
+inline intptr_t NumberOfTypedDataClasses() {
+  // Make sure this is updated when new TypedData types are added.
+
+  // Ensure that each typed data type comes in internal/view/external variants
+  // next to each other.
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 == kTypedDataInt8ArrayViewCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 == kExternalTypedDataInt8ArrayCid);
+
+  // Ensure the order of the typed data members in 3-step.
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 * 3 == kTypedDataUint8ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 * 3 ==
+                 kTypedDataUint8ClampedArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 * 3 == kTypedDataInt16ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 4 * 3 == kTypedDataUint16ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 5 * 3 == kTypedDataInt32ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 6 * 3 == kTypedDataUint32ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 7 * 3 == kTypedDataInt64ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 8 * 3 == kTypedDataUint64ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 9 * 3 == kTypedDataFloat32ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 10 * 3 == kTypedDataFloat64ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 11 * 3 ==
+                 kTypedDataFloat32x4ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 12 * 3 == kTypedDataInt32x4ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 13 * 3 ==
+                 kTypedDataFloat64x2ArrayCid);
+  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 14 * 3 == kByteDataViewCid);
+  COMPILE_ASSERT(kByteBufferCid + 1 == kNullCid);
+  return (kNullCid - kTypedDataInt8ArrayCid);
+}
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CLASS_ID_H_
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index d19460a..c458acb 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -31,7 +31,8 @@
         calloc(capacity_, sizeof(RelaxedAtomic<intptr_t>))));
   } else {
     // Duplicate the class table from the VM isolate.
-    auto vm_shared_class_table = Dart::vm_isolate()->group()->class_table();
+    auto vm_shared_class_table =
+        Dart::vm_isolate()->group()->shared_class_table();
     capacity_ = vm_shared_class_table->capacity_;
     // Note that [calloc] will zero-initialize the memory.
     RelaxedAtomic<intptr_t>* table = reinterpret_cast<RelaxedAtomic<intptr_t>*>(
@@ -46,7 +47,6 @@
     table[kForwardingCorpse] = vm_shared_class_table->SizeAt(kForwardingCorpse);
     table[kDynamicCid] = vm_shared_class_table->SizeAt(kDynamicCid);
     table[kVoidCid] = vm_shared_class_table->SizeAt(kVoidCid);
-    table[kNeverCid] = vm_shared_class_table->SizeAt(kNeverCid);
     table_.store(table);
   }
 #if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
@@ -71,24 +71,34 @@
   NOT_IN_PRODUCT(free(trace_allocation_table_.load()));
 }
 
+void ClassTable::set_table(ClassPtr* table) {
+  Isolate* isolate = Isolate::Current();
+  ASSERT(isolate != nullptr);
+  table_.store(table);
+  isolate->set_cached_class_table_table(table);
+}
+
 ClassTable::ClassTable(SharedClassTable* shared_class_table)
     : top_(kNumPredefinedCids),
       capacity_(0),
       table_(NULL),
-      old_class_tables_(new MallocGrowableArray<RawClass**>()),
+      old_class_tables_(new MallocGrowableArray<ClassPtr*>()),
       shared_class_table_(shared_class_table) {
   if (Dart::vm_isolate() == NULL) {
     ASSERT(kInitialCapacity >= kNumPredefinedCids);
     capacity_ = kInitialCapacity;
     // Note that [calloc] will zero-initialize the memory.
-    table_.store(static_cast<RawClass**>(calloc(capacity_, sizeof(RawClass*))));
+    // Don't use set_table because caller is supposed to set up isolates
+    // cached copy when constructing ClassTable. Isolate::Current might not
+    // be available at this point yet.
+    table_.store(static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr))));
   } else {
     // Duplicate the class table from the VM isolate.
     ClassTable* vm_class_table = Dart::vm_isolate()->class_table();
     capacity_ = vm_class_table->capacity_;
     // Note that [calloc] will zero-initialize the memory.
-    RawClass** table =
-        static_cast<RawClass**>(calloc(capacity_, sizeof(RawClass*)));
+    ClassPtr* table =
+        static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr)));
     // The following cids don't have a corresponding class object in Dart code.
     // We therefore need to initialize them eagerly.
     for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
@@ -99,7 +109,9 @@
     table[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
     table[kDynamicCid] = vm_class_table->At(kDynamicCid);
     table[kVoidCid] = vm_class_table->At(kVoidCid);
-    table[kNeverCid] = vm_class_table->At(kNeverCid);
+    // Don't use set_table because caller is supposed to set up isolates
+    // cached copy when constructing ClassTable. Isolate::Current might not
+    // be available at this point yet.
     table_.store(table);
   }
 }
@@ -112,7 +124,7 @@
   free(table_.load());
 }
 
-void ClassTable::AddOldTable(RawClass** old_class_table) {
+void ClassTable::AddOldTable(ClassPtr* old_class_table) {
   ASSERT(Thread::Current()->IsMutatorThread());
   old_class_tables_->Add(old_class_table);
 }
@@ -212,13 +224,21 @@
   ASSERT(new_capacity > capacity_);
 
   auto old_table = table_.load();
-  auto new_table = static_cast<RawClass**>(
-      malloc(new_capacity * sizeof(RawClass*)));  // NOLINT
-  memmove(new_table, old_table, capacity_ * sizeof(RawClass*));
-  memset(new_table + capacity_, 0,
-         (new_capacity - capacity_) * sizeof(RawClass*));
+  auto new_table = static_cast<ClassPtr*>(
+      malloc(new_capacity * sizeof(ClassPtr)));  // NOLINT
+  intptr_t i;
+  for (i = 0; i < capacity_; i++) {
+    // Don't use memmove, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_table[i] = old_table[i];
+  }
+  for (; i < new_capacity; i++) {
+    // Don't use memset, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_table[i] = 0;
+  }
   old_class_tables_->Add(old_table);
-  table_.store(new_table);
+  set_table(new_table);
 
   capacity_ = new_capacity;
 }
@@ -246,17 +266,32 @@
       reinterpret_cast<RelaxedAtomic<intptr_t>*>(
           malloc(new_capacity * sizeof(RelaxedAtomic<intptr_t>)));  // NOLINT
 
-  memmove(new_table, old_table, capacity_ * sizeof(intptr_t));
-  memset(new_table + capacity_, 0,
-         (new_capacity - capacity_) * sizeof(intptr_t));
+  intptr_t i;
+  for (i = 0; i < capacity_; i++) {
+    // Don't use memmove, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_table[i] = old_table[i];
+  }
+  for (; i < new_capacity; i++) {
+    // Don't use memset, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_table[i] = 0;
+  }
 
 #if !defined(PRODUCT)
   auto old_trace_table = trace_allocation_table_.load();
   auto new_trace_table =
       static_cast<uint8_t*>(malloc(new_capacity * sizeof(uint8_t)));  // NOLINT
-  memmove(new_trace_table, old_trace_table, capacity_ * sizeof(uint8_t));
-  memset(new_trace_table + capacity_, 0,
-         (new_capacity - capacity_) * sizeof(uint8_t));
+  for (i = 0; i < capacity_; i++) {
+    // Don't use memmove, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_trace_table[i] = old_trace_table[i];
+  }
+  for (; i < new_capacity; i++) {
+    // Don't use memset, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_trace_table[i] = 0;
+  }
 #endif
 
   old_tables_->Add(old_table);
@@ -265,13 +300,20 @@
   NOT_IN_PRODUCT(trace_allocation_table_.store(new_trace_table));
 
 #if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
+  auto old_unboxed_fields_map = unboxed_fields_map_;
   auto new_unboxed_fields_map = static_cast<UnboxedFieldBitmap*>(
       malloc(new_capacity * sizeof(UnboxedFieldBitmap)));
-  memmove(new_unboxed_fields_map, unboxed_fields_map_,
-          capacity_ * sizeof(UnboxedFieldBitmap));
-  memset(new_unboxed_fields_map + capacity_, 0,
-         (new_capacity - capacity_) * sizeof(UnboxedFieldBitmap));
-  old_tables_->Add(unboxed_fields_map_);
+  for (i = 0; i < capacity_; i++) {
+    // Don't use memmove, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_unboxed_fields_map[i] = old_unboxed_fields_map[i];
+  }
+  for (; i < new_capacity; i++) {
+    // Don't use memset, which changes this from a relaxed atomic operation
+    // to a non-atomic operation.
+    new_unboxed_fields_map[i] = UnboxedFieldBitmap(0);
+  }
+  old_tables_->Add(old_unboxed_fields_map);
   unboxed_fields_map_ = new_unboxed_fields_map;
 #endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
 
@@ -293,9 +335,9 @@
 void ClassTable::Remap(intptr_t* old_to_new_cid) {
   ASSERT(Thread::Current()->IsAtSafepoint());
   const intptr_t num_cids = NumCids();
-  std::unique_ptr<RawClass*[]> cls_by_old_cid(new RawClass*[num_cids]);
+  std::unique_ptr<ClassPtr[]> cls_by_old_cid(new ClassPtr[num_cids]);
   auto* table = table_.load();
-  memmove(cls_by_old_cid.get(), table, sizeof(RawClass*) * num_cids);
+  memmove(cls_by_old_cid.get(), table, sizeof(ClassPtr) * num_cids);
   for (intptr_t i = 0; i < num_cids; i++) {
     table[old_to_new_cid[i]] = cls_by_old_cid[i];
   }
@@ -330,8 +372,8 @@
   visitor->set_gc_root_type("class table");
   if (top_ != 0) {
     auto* table = table_.load();
-    RawObject** from = reinterpret_cast<RawObject**>(&table[0]);
-    RawObject** to = reinterpret_cast<RawObject**>(&table[top_ - 1]);
+    ObjectPtr* from = reinterpret_cast<ObjectPtr*>(&table[0]);
+    ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&table[top_ - 1]);
     visitor->VisitPointers(from, to);
   }
   visitor->clear_gc_root_type();
@@ -371,14 +413,14 @@
       continue;
     }
     cls = At(i);
-    if (cls.raw() != reinterpret_cast<RawClass*>(0)) {
+    if (cls.raw() != nullptr) {
       name = cls.Name();
       OS::PrintErr("%" Pd ": %s\n", i, name.ToCString());
     }
   }
 }
 
-void ClassTable::SetAt(intptr_t index, RawClass* raw_cls) {
+void ClassTable::SetAt(intptr_t index, ClassPtr raw_cls) {
   // This is called by snapshot reader and class finalizer.
   ASSERT(index < capacity_);
   const intptr_t size =
@@ -403,7 +445,7 @@
 }
 
 bool SharedClassTable::ShouldUpdateSizeForClassId(intptr_t cid) {
-  return !RawObject::IsVariableSizeClassId(cid);
+  return !IsVariableSizeClassId(cid);
 }
 
 intptr_t SharedClassTable::ClassOffsetFor(intptr_t cid) {
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index eb5a431..6bb42d2 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -15,6 +15,7 @@
 #include "vm/class_id.h"
 #include "vm/flags.h"
 #include "vm/globals.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
@@ -30,7 +31,6 @@
 template <typename T>
 class MallocGrowableArray;
 class ObjectPointerVisitor;
-class RawClass;
 
 // Wraps a 64-bit integer to represent the bitmap of unboxed fields
 // stored in the shared class table.
@@ -42,9 +42,11 @@
   UnboxedFieldBitmap& operator=(const UnboxedFieldBitmap&) = default;
 
   DART_FORCE_INLINE bool Get(intptr_t position) const {
+    if (position >= Length()) return false;
     return Utils::TestBit(bitmap_, position);
   }
   DART_FORCE_INLINE void Set(intptr_t position) {
+    ASSERT(position < Length());
     bitmap_ |= Utils::Bit<decltype(bitmap_)>(position);
   }
   DART_FORCE_INLINE uint64_t Value() const { return bitmap_; }
@@ -134,14 +136,24 @@
     const intptr_t num_cids = NumCids();
     const intptr_t bytes = sizeof(intptr_t) * num_cids;
     auto size_table = static_cast<intptr_t*>(malloc(bytes));
-    memmove(size_table, table_.load(), sizeof(intptr_t) * num_cids);
+    auto table = table_.load();
+    for (intptr_t i = 0; i < num_cids; i++) {
+      // Don't use memmove, which changes this from a relaxed atomic operation
+      // to a non-atomic operation.
+      size_table[i] = table[i];
+    }
     *copy_num_cids = num_cids;
     *copy = size_table;
   }
 
   void ResetBeforeHotReload() {
     // The [IsolateReloadContext] is now source-of-truth for GC.
-    memset(table_.load(), 0, sizeof(intptr_t) * top_);
+    auto table = table_.load();
+    for (intptr_t i = 0; i < top_; i++) {
+      // Don't use memset, which changes this from a relaxed atomic operation
+      // to a non-atomic operation.
+      table[i] = 0;
+    }
   }
 
   void ResetAfterHotReload(intptr_t* old_table,
@@ -151,7 +163,12 @@
     // return, so we restore size information for all classes.
     if (is_rollback) {
       SetNumCids(num_old_cids);
-      memmove(table_.load(), old_table, sizeof(intptr_t) * num_old_cids);
+      auto table = table_.load();
+      for (intptr_t i = 0; i < num_old_cids; i++) {
+        // Don't use memmove, which changes this from a relaxed atomic operation
+        // to a non-atomic operation.
+        table[i] = old_table[i];
+      }
     }
 
     // Can't free this table immediately as another thread (e.g., concurrent
@@ -241,13 +258,18 @@
 
   SharedClassTable* shared_class_table() const { return shared_class_table_; }
 
-  void CopyBeforeHotReload(RawClass*** copy, intptr_t* copy_num_cids) {
+  void CopyBeforeHotReload(ClassPtr** copy, intptr_t* copy_num_cids) {
     // The [IsolateReloadContext] will need to maintain a copy of the old class
     // table until instances have been morphed.
     const intptr_t num_cids = NumCids();
-    const intptr_t bytes = sizeof(RawClass*) * num_cids;
-    auto class_table = static_cast<RawClass**>(malloc(bytes));
-    memmove(class_table, table_.load(), sizeof(RawClass*) * num_cids);
+    const intptr_t bytes = sizeof(ClassPtr) * num_cids;
+    auto class_table = static_cast<ClassPtr*>(malloc(bytes));
+    auto table = table_.load();
+    for (intptr_t i = 0; i < num_cids; i++) {
+      // Don't use memmove, which changes this from a relaxed atomic operation
+      // to a non-atomic operation.
+      class_table[i] = table[i];
+    }
     *copy_num_cids = num_cids;
     *copy = class_table;
   }
@@ -260,14 +282,19 @@
     // here).
   }
 
-  void ResetAfterHotReload(RawClass** old_table,
+  void ResetAfterHotReload(ClassPtr* old_table,
                            intptr_t num_old_cids,
                            bool is_rollback) {
     // The [IsolateReloadContext] is no longer source-of-truth for GC after we
     // return, so we restore size information for all classes.
     if (is_rollback) {
       SetNumCids(num_old_cids);
-      memmove(table_.load(), old_table, sizeof(RawClass*) * num_old_cids);
+      auto table = table_.load();
+      for (intptr_t i = 0; i < num_old_cids; i++) {
+        // Don't use memmove, which changes this from a relaxed atomic operation
+        // to a non-atomic operation.
+        table[i] = old_table[i];
+      }
     } else {
       CopySizesFromClassObjects();
     }
@@ -280,7 +307,7 @@
   }
 
   // Thread-safe.
-  RawClass* At(intptr_t index) const {
+  ClassPtr At(intptr_t index) const {
     ASSERT(IsValidIndex(index));
     return table_.load()[index];
   }
@@ -289,7 +316,7 @@
     return shared_class_table_->SizeAt(index);
   }
 
-  void SetAt(intptr_t index, RawClass* raw_cls);
+  void SetAt(intptr_t index, ClassPtr raw_cls);
 
   bool IsValidIndex(intptr_t index) const {
     return shared_class_table_->IsValidIndex(index);
@@ -328,17 +355,9 @@
 
   void Print();
 
-  // Used by the generated code.
-  static intptr_t table_offset() { return OFFSET_OF(ClassTable, table_); }
-
-  // Used by the generated code.
-  static intptr_t shared_class_table_offset() {
-    return OFFSET_OF(ClassTable, shared_class_table_);
-  }
-
 #ifndef PRODUCT
   // Describes layout of heap stats for code generation. See offset_extractor.cc
-  struct ArrayLayout {
+  struct ArrayTraits {
     static intptr_t elements_start_offset() { return 0; }
 
     static constexpr intptr_t kElementSize = sizeof(uint8_t);
@@ -360,23 +379,28 @@
   friend class MarkingWeakVisitor;
   friend class Scavenger;
   friend class ScavengerWeakVisitor;
+  friend class Dart;
   friend Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
                                                    const char* name,
                                                    char** error);
+  friend class Isolate;  // for table()
   static const int kInitialCapacity = SharedClassTable::kInitialCapacity;
   static const int kCapacityIncrement = SharedClassTable::kCapacityIncrement;
 
-  void AddOldTable(RawClass** old_table);
+  void AddOldTable(ClassPtr* old_table);
 
   void Grow(intptr_t index);
 
+  ClassPtr* table() { return table_.load(); }
+  void set_table(ClassPtr* table);
+
   intptr_t top_;
   intptr_t capacity_;
 
   // Copy-on-write is used for table_, with old copies stored in
   // old_class_tables_.
-  AcqRelAtomic<RawClass**> table_;
-  MallocGrowableArray<RawClass**>* old_class_tables_;
+  AcqRelAtomic<ClassPtr*> table_;
+  MallocGrowableArray<ClassPtr*>* old_class_tables_;
   SharedClassTable* shared_class_table_;
 
   DISALLOW_COPY_AND_ASSIGN(ClassTable);
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 0c70edb..16baa7a 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -2,6 +2,8 @@
 // for 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 <memory>
+
 #include "vm/clustered_snapshot.h"
 
 #include "platform/assert.h"
@@ -9,10 +11,8 @@
 #include "vm/bss_relocs.h"
 #include "vm/class_id.h"
 #include "vm/code_observers.h"
+#include "vm/compiler/api/print_filter.h"
 #include "vm/compiler/assembler/disassembler.h"
-#include "vm/compiler/backend/code_statistics.h"
-#include "vm/compiler/backend/il_printer.h"
-#include "vm/compiler/relocation.h"
 #include "vm/dart.h"
 #include "vm/dispatch_table.h"
 #include "vm/flag_list.h"
@@ -28,6 +28,12 @@
 #include "vm/timeline.h"
 #include "vm/version.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/backend/code_statistics.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/relocation.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -48,7 +54,7 @@
 
 static void RelocateCodeObjects(
     bool is_vm,
-    GrowableArray<RawCode*>* code_objects,
+    GrowableArray<CodePtr>* code_objects,
     GrowableArray<ImageWriterCommand>* image_writer_commands) {
   auto thread = Thread::Current();
   auto isolate = is_vm ? Dart::vm_isolate() : thread->isolate();
@@ -57,48 +63,48 @@
   CodeRelocator::Relocate(thread, code_objects, image_writer_commands, is_vm);
 }
 
-class RawCodeKeyValueTrait {
+class CodePtrKeyValueTrait {
  public:
   // Typedefs needed for the DirectChainedHashMap template.
-  typedef const RawCode* Key;
-  typedef const RawCode* Value;
-  typedef const RawCode* Pair;
+  typedef const CodePtr Key;
+  typedef const CodePtr Value;
+  typedef CodePtr Pair;
 
   static Key KeyOf(Pair kv) { return kv; }
   static Value ValueOf(Pair kv) { return kv; }
   static inline intptr_t Hashcode(Key key) {
-    return reinterpret_cast<intptr_t>(key);
+    return static_cast<intptr_t>(key);
   }
 
   static inline bool IsKeyEqual(Pair pair, Key key) { return pair == key; }
 };
 
-typedef DirectChainedHashMap<RawCodeKeyValueTrait> RawCodeSet;
+typedef DirectChainedHashMap<CodePtrKeyValueTrait> RawCodeSet;
 
 #endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
 
-static RawObject* AllocateUninitialized(PageSpace* old_space, intptr_t size) {
+static ObjectPtr AllocateUninitialized(PageSpace* old_space, intptr_t size) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
   uword address = old_space->TryAllocateDataBumpLocked(size);
   if (address == 0) {
     OUT_OF_MEMORY();
   }
-  return RawObject::FromAddr(address);
+  return ObjectLayout::FromAddr(address);
 }
 
-void Deserializer::InitializeHeader(RawObject* raw,
+void Deserializer::InitializeHeader(ObjectPtr raw,
                                     intptr_t class_id,
                                     intptr_t size,
                                     bool is_canonical) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
   uint32_t tags = 0;
-  tags = RawObject::ClassIdTag::update(class_id, tags);
-  tags = RawObject::SizeTag::update(size, tags);
-  tags = RawObject::CanonicalBit::update(is_canonical, tags);
-  tags = RawObject::OldBit::update(true, tags);
-  tags = RawObject::OldAndNotMarkedBit::update(true, tags);
-  tags = RawObject::OldAndNotRememberedBit::update(true, tags);
-  tags = RawObject::NewBit::update(false, tags);
+  tags = ObjectLayout::ClassIdTag::update(class_id, tags);
+  tags = ObjectLayout::SizeTag::update(size, tags);
+  tags = ObjectLayout::CanonicalBit::update(is_canonical, tags);
+  tags = ObjectLayout::OldBit::update(true, tags);
+  tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
+  tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+  tags = ObjectLayout::NewBit::update(false, tags);
   raw->ptr()->tags_ = tags;
 #if defined(HASH_IN_OBJECT_HEADER)
   raw->ptr()->hash_ = 0;
@@ -115,11 +121,10 @@
   intptr_t stop_data = serializer->GetDataSize();
   intptr_t stop_objects = serializer->next_ref_index();
   if (FLAG_print_cluster_information) {
-    const int hex_size = kWordSize * 2;
-    OS::PrintErr("Snapshot 0x%0*.*" Px " (%" Pd "), ", hex_size, hex_size,
-                 start_size, stop_size - start_size);
-    OS::PrintErr("Data 0x%0*.*" Px " (%" Pd "): ", hex_size, hex_size,
-                 start_data, stop_data - start_data);
+    OS::PrintErr("Snapshot 0x%" Pp " (%" Pd "), ", start_size,
+                 stop_size - start_size);
+    OS::PrintErr("Data 0x%" Pp " (%" Pd "): ", start_data,
+                 stop_data - start_data);
     OS::PrintErr("Alloc %s (%" Pd ")\n", name(), stop_objects - start_objects);
   }
   size_ += (stop_size - start_size) + (stop_data - start_data);
@@ -131,9 +136,8 @@
   WriteFill(serializer);
   intptr_t stop = serializer->bytes_written();
   if (FLAG_print_cluster_information) {
-    const int hex_size = kWordSize * 2;
-    OS::PrintErr("Snapshot 0x%0*.*" Px " (%" Pd "): Fill %s\n", hex_size,
-                 hex_size, start, stop - start, name());
+    OS::PrintErr("Snapshot 0x%" Pp " (%" Pd "): Fill %s\n", start, stop - start,
+                 name());
   }
   size_ += (stop - start);
 }
@@ -146,10 +150,12 @@
         objects_(num_cids) {}
   ~ClassSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawClass* cls = Class::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ClassPtr cls = Class::RawCast(object);
     intptr_t class_id = cls->ptr()->id_;
 
+    // Classes expected to be dropped by the precompiler should not be traced.
+    ASSERT(class_id != kIllegalCid);
     if (class_id < kNumPredefinedCids) {
       // These classes are allocated by Object::Init or Object::InitOnce, so the
       // deserializer must find them in the class table instead of allocating
@@ -167,7 +173,7 @@
     intptr_t count = predefined_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawClass* cls = predefined_[i];
+      ClassPtr cls = predefined_[i];
       s->AssignRef(cls);
       AutoTraceObject(cls);
       intptr_t class_id = cls->ptr()->id_;
@@ -176,7 +182,7 @@
     count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawClass* cls = objects_[i];
+      ClassPtr cls = objects_[i];
       s->AssignRef(cls);
     }
   }
@@ -192,7 +198,7 @@
     }
   }
 
-  void WriteClass(Serializer* s, RawClass* cls) {
+  void WriteClass(Serializer* s, ClassPtr cls) {
     AutoTraceObjectName(cls, cls->ptr()->name_);
     WriteFromTo(cls);
     intptr_t class_id = cls->ptr()->id_;
@@ -200,6 +206,9 @@
       s->UnexpectedObject(cls, "Class with illegal cid");
     }
     s->WriteCid(class_id);
+    if (s->kind() == Snapshot::kFull && RequireLegacyErasureOfConstants(cls)) {
+      s->UnexpectedObject(cls, "Class with non mode agnostic constants");
+    }
     if (s->kind() != Snapshot::kFullAOT) {
       s->Write<uint32_t>(cls->ptr()->binary_declaration_);
     }
@@ -220,13 +229,14 @@
   }
 
  private:
-  GrowableArray<RawClass*> predefined_;
-  GrowableArray<RawClass*> objects_;
+  GrowableArray<ClassPtr> predefined_;
+  GrowableArray<ClassPtr> objects_;
 
   UnboxedFieldBitmap CalculateTargetUnboxedFieldsBitmap(Serializer* s,
                                                         intptr_t class_id) {
     const auto unboxed_fields_bitmap_host =
-        s->isolate()->group()->class_table()->GetUnboxedFieldsMapAt(class_id);
+        s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
+            class_id);
 
     UnboxedFieldBitmap unboxed_fields_bitmap;
     if (unboxed_fields_bitmap_host.IsEmpty() ||
@@ -254,6 +264,20 @@
 
     return unboxed_fields_bitmap;
   }
+
+  bool RequireLegacyErasureOfConstants(ClassPtr cls) {
+    // Do not generate a core snapshot containing constants that would require
+    // a legacy erasure of their types if loaded in an isolate running in weak
+    // mode.
+    if (cls->ptr()->host_type_arguments_field_offset_in_words_ ==
+            Class::kNoTypeArguments ||
+        cls->ptr()->constants_ == Object::empty_array().raw()) {
+      return false;
+    }
+    Zone* zone = Thread::Current()->zone();
+    const Class& clazz = Class::Handle(zone, cls);
+    return clazz.RequireLegacyErasureOfConstants(zone);
+  }
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -270,8 +294,8 @@
     for (intptr_t i = 0; i < count; i++) {
       intptr_t class_id = d->ReadCid();
       ASSERT(table->HasValidClassAt(class_id));
-      RawClass* cls = table->At(class_id);
-      ASSERT(cls != NULL);
+      ClassPtr cls = table->At(class_id);
+      ASSERT(cls != nullptr);
       d->AssignRef(cls);
     }
     predefined_stop_index_ = d->next_index();
@@ -289,7 +313,7 @@
 
     for (intptr_t id = predefined_start_index_; id < predefined_stop_index_;
          id++) {
-      RawClass* cls = reinterpret_cast<RawClass*>(d->Ref(id));
+      ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
       ReadFromTo(cls);
       intptr_t class_id = d->ReadCid();
       cls->ptr()->id_ = class_id;
@@ -298,7 +322,7 @@
         cls->ptr()->binary_declaration_ = d->Read<uint32_t>();
       }
 #endif
-      if (!RawObject::IsInternalVMdefinedClassId(class_id)) {
+      if (!IsInternalVMdefinedClassId(class_id)) {
         cls->ptr()->host_instance_size_in_words_ = d->Read<int32_t>();
         cls->ptr()->host_next_field_offset_in_words_ = d->Read<int32_t>();
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -330,9 +354,9 @@
       }
     }
 
-    auto shared_class_table = d->isolate()->group()->class_table();
+    auto shared_class_table = d->isolate()->group()->shared_class_table();
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawClass* cls = reinterpret_cast<RawClass*>(d->Ref(id));
+      ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
       Deserializer::InitializeHeader(cls, kClassCid, Class::InstanceSize());
       ReadFromTo(cls);
 
@@ -384,8 +408,8 @@
   TypeArgumentsSerializationCluster() : SerializationCluster("TypeArguments") {}
   ~TypeArgumentsSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawTypeArguments* type_args = TypeArguments::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    TypeArgumentsPtr type_args = TypeArguments::RawCast(object);
     objects_.Add(type_args);
 
     s->Push(type_args->ptr()->instantiations_);
@@ -400,7 +424,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawTypeArguments* type_args = objects_[i];
+      TypeArgumentsPtr type_args = objects_[i];
       s->AssignRef(type_args);
       AutoTraceObject(type_args);
       const intptr_t length = Smi::Value(type_args->ptr()->length_);
@@ -411,11 +435,11 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawTypeArguments* type_args = objects_[i];
+      TypeArgumentsPtr type_args = objects_[i];
       AutoTraceObject(type_args);
       const intptr_t length = Smi::Value(type_args->ptr()->length_);
       s->WriteUnsigned(length);
-      s->Write<bool>(type_args->IsCanonical());
+      s->Write<bool>(type_args->ptr()->IsCanonical());
       intptr_t hash = Smi::Value(type_args->ptr()->hash_);
       s->Write<int32_t>(hash);
       const intptr_t nullability = Smi::Value(type_args->ptr()->nullability_);
@@ -428,7 +452,7 @@
   }
 
  private:
-  GrowableArray<RawTypeArguments*> objects_;
+  GrowableArray<TypeArgumentsPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -451,8 +475,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawTypeArguments* type_args =
-          reinterpret_cast<RawTypeArguments*>(d->Ref(id));
+      TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
@@ -461,11 +484,10 @@
       type_args->ptr()->length_ = Smi::New(length);
       type_args->ptr()->hash_ = Smi::New(d->Read<int32_t>());
       type_args->ptr()->nullability_ = Smi::New(d->ReadUnsigned());
-      type_args->ptr()->instantiations_ =
-          reinterpret_cast<RawArray*>(d->ReadRef());
+      type_args->ptr()->instantiations_ = static_cast<ArrayPtr>(d->ReadRef());
       for (intptr_t j = 0; j < length; j++) {
         type_args->ptr()->types()[j] =
-            reinterpret_cast<RawAbstractType*>(d->ReadRef());
+            static_cast<AbstractTypePtr>(d->ReadRef());
       }
     }
   }
@@ -477,8 +499,8 @@
   PatchClassSerializationCluster() : SerializationCluster("PatchClass") {}
   ~PatchClassSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawPatchClass* cls = PatchClass::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    PatchClassPtr cls = PatchClass::RawCast(object);
     objects_.Add(cls);
     PushFromTo(cls);
   }
@@ -488,7 +510,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawPatchClass* cls = objects_[i];
+      PatchClassPtr cls = objects_[i];
       s->AssignRef(cls);
     }
   }
@@ -496,7 +518,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawPatchClass* cls = objects_[i];
+      PatchClassPtr cls = objects_[i];
       AutoTraceObject(cls);
       WriteFromTo(cls);
       if (s->kind() != Snapshot::kFullAOT) {
@@ -506,7 +528,7 @@
   }
 
  private:
-  GrowableArray<RawPatchClass*> objects_;
+  GrowableArray<PatchClassPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -528,7 +550,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawPatchClass* cls = reinterpret_cast<RawPatchClass*>(d->Ref(id));
+      PatchClassPtr cls = static_cast<PatchClassPtr>(d->Ref(id));
       Deserializer::InitializeHeader(cls, kPatchClassCid,
                                      PatchClass::InstanceSize());
       ReadFromTo(cls);
@@ -547,9 +569,9 @@
   FunctionSerializationCluster() : SerializationCluster("Function") {}
   ~FunctionSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
+  void Trace(Serializer* s, ObjectPtr object) {
     Snapshot::Kind kind = s->kind();
-    RawFunction* func = Function::RawCast(object);
+    FunctionPtr func = Function::RawCast(object);
     objects_.Add(func);
 
     PushFromTo(func);
@@ -570,7 +592,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawFunction* func = objects_[i];
+      FunctionPtr func = objects_[i];
       s->AssignRef(func);
     }
   }
@@ -579,7 +601,7 @@
     Snapshot::Kind kind = s->kind();
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawFunction* func = objects_[i];
+      FunctionPtr func = objects_[i];
       AutoTraceObjectName(func, func->ptr()->name_);
       WriteFromTo(func);
       if (kind == Snapshot::kFull) {
@@ -605,7 +627,7 @@
   }
 
  private:
-  GrowableArray<RawFunction*> objects_;
+  GrowableArray<FunctionPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -628,23 +650,23 @@
     Snapshot::Kind kind = d->kind();
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawFunction* func = reinterpret_cast<RawFunction*>(d->Ref(id));
+      FunctionPtr func = static_cast<FunctionPtr>(d->Ref(id));
       Deserializer::InitializeHeader(func, kFunctionCid,
                                      Function::InstanceSize());
       ReadFromTo(func);
 
       if (kind == Snapshot::kFull) {
         NOT_IN_PRECOMPILED(func->ptr()->bytecode_ =
-                               reinterpret_cast<RawBytecode*>(d->ReadRef()));
+                               static_cast<BytecodePtr>(d->ReadRef()));
       } else if (kind == Snapshot::kFullAOT) {
-        func->ptr()->code_ = reinterpret_cast<RawCode*>(d->ReadRef());
+        func->ptr()->code_ = static_cast<CodePtr>(d->ReadRef());
       } else if (kind == Snapshot::kFullJIT) {
         NOT_IN_PRECOMPILED(func->ptr()->unoptimized_code_ =
-                               reinterpret_cast<RawCode*>(d->ReadRef()));
+                               static_cast<CodePtr>(d->ReadRef()));
         NOT_IN_PRECOMPILED(func->ptr()->bytecode_ =
-                               reinterpret_cast<RawBytecode*>(d->ReadRef()));
-        func->ptr()->code_ = reinterpret_cast<RawCode*>(d->ReadRef());
-        func->ptr()->ic_data_array_ = reinterpret_cast<RawArray*>(d->ReadRef());
+                               static_cast<BytecodePtr>(d->ReadRef()));
+        func->ptr()->code_ = static_cast<CodePtr>(d->ReadRef());
+        func->ptr()->ic_data_array_ = static_cast<ArrayPtr>(d->ReadRef());
       }
 
 #if defined(DEBUG)
@@ -720,8 +742,8 @@
   ClosureDataSerializationCluster() : SerializationCluster("ClosureData") {}
   ~ClosureDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawClosureData* data = ClosureData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ClosureDataPtr data = ClosureData::RawCast(object);
     objects_.Add(data);
 
     if (s->kind() != Snapshot::kFullAOT) {
@@ -737,7 +759,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawClosureData* data = objects_[i];
+      ClosureDataPtr data = objects_[i];
       s->AssignRef(data);
     }
   }
@@ -745,7 +767,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawClosureData* data = objects_[i];
+      ClosureDataPtr data = objects_[i];
       AutoTraceObject(data);
       if (s->kind() != Snapshot::kFullAOT) {
         WriteField(data, context_scope_);
@@ -757,7 +779,7 @@
   }
 
  private:
-  GrowableArray<RawClosureData*> objects_;
+  GrowableArray<ClosureDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -779,18 +801,18 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawClosureData* data = reinterpret_cast<RawClosureData*>(d->Ref(id));
+      ClosureDataPtr data = static_cast<ClosureDataPtr>(d->Ref(id));
       Deserializer::InitializeHeader(data, kClosureDataCid,
                                      ClosureData::InstanceSize());
       if (d->kind() == Snapshot::kFullAOT) {
         data->ptr()->context_scope_ = ContextScope::null();
       } else {
         data->ptr()->context_scope_ =
-            static_cast<RawContextScope*>(d->ReadRef());
+            static_cast<ContextScopePtr>(d->ReadRef());
       }
-      data->ptr()->parent_function_ = static_cast<RawFunction*>(d->ReadRef());
-      data->ptr()->signature_type_ = static_cast<RawType*>(d->ReadRef());
-      data->ptr()->closure_ = static_cast<RawInstance*>(d->ReadRef());
+      data->ptr()->parent_function_ = static_cast<FunctionPtr>(d->ReadRef());
+      data->ptr()->signature_type_ = static_cast<TypePtr>(d->ReadRef());
+      data->ptr()->closure_ = static_cast<InstancePtr>(d->ReadRef());
     }
   }
 };
@@ -801,8 +823,8 @@
   SignatureDataSerializationCluster() : SerializationCluster("SignatureData") {}
   ~SignatureDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawSignatureData* data = SignatureData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    SignatureDataPtr data = SignatureData::RawCast(object);
     objects_.Add(data);
     PushFromTo(data);
   }
@@ -812,7 +834,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawSignatureData* data = objects_[i];
+      SignatureDataPtr data = objects_[i];
       s->AssignRef(data);
     }
   }
@@ -820,14 +842,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawSignatureData* data = objects_[i];
+      SignatureDataPtr data = objects_[i];
       AutoTraceObject(data);
       WriteFromTo(data);
     }
   }
 
  private:
-  GrowableArray<RawSignatureData*> objects_;
+  GrowableArray<SignatureDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -849,7 +871,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawSignatureData* data = reinterpret_cast<RawSignatureData*>(d->Ref(id));
+      SignatureDataPtr data = static_cast<SignatureDataPtr>(d->Ref(id));
       Deserializer::InitializeHeader(data, kSignatureDataCid,
                                      SignatureData::InstanceSize());
       ReadFromTo(data);
@@ -864,8 +886,8 @@
       : SerializationCluster("FfiTrampolineData") {}
   ~FfiTrampolineDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawFfiTrampolineData* data = FfiTrampolineData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    FfiTrampolineDataPtr data = FfiTrampolineData::RawCast(object);
     objects_.Add(data);
     PushFromTo(data);
   }
@@ -882,7 +904,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawFfiTrampolineData* const data = objects_[i];
+      FfiTrampolineDataPtr const data = objects_[i];
       AutoTraceObject(data);
       WriteFromTo(data);
 
@@ -896,7 +918,7 @@
   }
 
  private:
-  GrowableArray<RawFfiTrampolineData*> objects_;
+  GrowableArray<FfiTrampolineDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -918,8 +940,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawFfiTrampolineData* data =
-          reinterpret_cast<RawFfiTrampolineData*>(d->Ref(id));
+      FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(d->Ref(id));
       Deserializer::InitializeHeader(data, kFfiTrampolineDataCid,
                                      FfiTrampolineData::InstanceSize());
       ReadFromTo(data);
@@ -936,8 +957,8 @@
       : SerializationCluster("RedirectionData") {}
   ~RedirectionDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawRedirectionData* data = RedirectionData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    RedirectionDataPtr data = RedirectionData::RawCast(object);
     objects_.Add(data);
     PushFromTo(data);
   }
@@ -947,7 +968,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawRedirectionData* data = objects_[i];
+      RedirectionDataPtr data = objects_[i];
       s->AssignRef(data);
     }
   }
@@ -955,14 +976,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawRedirectionData* data = objects_[i];
+      RedirectionDataPtr data = objects_[i];
       AutoTraceObject(data);
       WriteFromTo(data);
     }
   }
 
  private:
-  GrowableArray<RawRedirectionData*> objects_;
+  GrowableArray<RedirectionDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -984,8 +1005,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawRedirectionData* data =
-          reinterpret_cast<RawRedirectionData*>(d->Ref(id));
+      RedirectionDataPtr data = static_cast<RedirectionDataPtr>(d->Ref(id));
       Deserializer::InitializeHeader(data, kRedirectionDataCid,
                                      RedirectionData::InstanceSize());
       ReadFromTo(data);
@@ -999,8 +1019,8 @@
   FieldSerializationCluster() : SerializationCluster("Field") {}
   ~FieldSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawField* field = Field::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    FieldPtr field = Field::RawCast(object);
     objects_.Add(field);
 
     Snapshot::Kind kind = s->kind();
@@ -1012,11 +1032,7 @@
     s->Push(field->ptr()->initializer_function_);
 
     if (kind != Snapshot::kFullAOT) {
-      // Write out the saved initial values
       s->Push(field->ptr()->saved_initial_value_);
-    }
-    if (kind != Snapshot::kFullAOT) {
-      // Write out the guarded list length.
       s->Push(field->ptr()->guarded_list_length_);
     }
     if (kind == Snapshot::kFullJIT) {
@@ -1030,7 +1046,8 @@
           kind == Snapshot::kFullAOT ||
           // Do not reset const fields.
           Field::ConstBit::decode(field->ptr()->kind_bits_)) {
-        s->Push(s->field_table()->At(field->ptr()->host_offset_or_field_id_));
+        s->Push(s->field_table()->At(
+            Smi::Value(field->ptr()->host_offset_or_field_id_)));
       } else {
         // Otherwise, for static fields we write out the initial static value.
         s->Push(field->ptr()->saved_initial_value_);
@@ -1045,7 +1062,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawField* field = objects_[i];
+      FieldPtr field = objects_[i];
       s->AssignRef(field);
     }
   }
@@ -1054,7 +1071,7 @@
     Snapshot::Kind kind = s->kind();
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawField* field = objects_[i];
+      FieldPtr field = objects_[i];
       AutoTraceObjectName(field, field->ptr()->name_);
 
       WriteField(field, name_);
@@ -1064,9 +1081,6 @@
       WriteField(field, initializer_function_);
       if (kind != Snapshot::kFullAOT) {
         WriteField(field, saved_initial_value_);
-      }
-      if (kind != Snapshot::kFullAOT) {
-        // Write out the guarded list length.
         WriteField(field, guarded_list_length_);
       }
       if (kind == Snapshot::kFullJIT) {
@@ -1079,9 +1093,7 @@
         s->WriteCid(field->ptr()->guarded_cid_);
         s->WriteCid(field->ptr()->is_nullable_);
         s->Write<int8_t>(field->ptr()->static_type_exactness_state_);
-#if !defined(DART_PRECOMPILED_RUNTIME)
         s->Write<uint32_t>(field->ptr()->binary_declaration_);
-#endif
       }
       s->Write<uint16_t>(field->ptr()->kind_bits_);
 
@@ -1090,18 +1102,17 @@
         if (
             // For precompiled static fields, the value was already reset and
             // initializer_ now contains a Function.
-            // WriteField(field, value_.static_value_);
             kind == Snapshot::kFullAOT ||
             // Do not reset const fields.
             Field::ConstBit::decode(field->ptr()->kind_bits_)) {
-          WriteFieldValue(
-              "static value",
-              s->field_table()->At(field->ptr()->host_offset_or_field_id_));
+          WriteFieldValue("static value",
+                          s->field_table()->At(Smi::Value(
+                              field->ptr()->host_offset_or_field_id_)));
         } else {
           // Otherwise, for static fields we write out the initial static value.
           WriteFieldValue("static value", field->ptr()->saved_initial_value_);
         }
-        s->WriteUnsigned(field->ptr()->host_offset_or_field_id_);
+        s->WriteUnsigned(Smi::Value(field->ptr()->host_offset_or_field_id_));
       } else {
         WriteFieldValue("offset", Smi::New(Field::TargetOffsetOf(field)));
       }
@@ -1109,7 +1120,7 @@
   }
 
  private:
-  GrowableArray<RawField*> objects_;
+  GrowableArray<FieldPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1132,10 +1143,20 @@
     Snapshot::Kind kind = d->kind();
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawField* field = reinterpret_cast<RawField*>(d->Ref(id));
+      FieldPtr field = static_cast<FieldPtr>(d->Ref(id));
       Deserializer::InitializeHeader(field, kFieldCid, Field::InstanceSize());
       ReadFromTo(field);
       if (kind != Snapshot::kFullAOT) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+        field->ptr()->saved_initial_value_ =
+            static_cast<InstancePtr>(d->ReadRef());
+#endif
+        field->ptr()->guarded_list_length_ = static_cast<SmiPtr>(d->ReadRef());
+      }
+      if (kind == Snapshot::kFullJIT) {
+        field->ptr()->dependent_code_ = static_cast<ArrayPtr>(d->ReadRef());
+      }
+      if (kind != Snapshot::kFullAOT) {
         field->ptr()->token_pos_ = d->ReadTokenPosition();
         field->ptr()->end_token_pos_ = d->ReadTokenPosition();
         field->ptr()->guarded_cid_ = d->ReadCid();
@@ -1147,17 +1168,17 @@
       }
       field->ptr()->kind_bits_ = d->Read<uint16_t>();
 
-      RawObject* value_or_offset = d->ReadRef();
+      ObjectPtr value_or_offset = d->ReadRef();
       if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
         intptr_t field_id = d->ReadUnsigned();
-        d->field_table()->SetAt(
-            field_id, reinterpret_cast<RawInstance*>(value_or_offset));
-        field->ptr()->host_offset_or_field_id_ = field_id;
+        d->field_table()->SetAt(field_id,
+                                static_cast<InstancePtr>(value_or_offset));
+        field->ptr()->host_offset_or_field_id_ = Smi::New(field_id);
       } else {
-        field->ptr()->host_offset_or_field_id_ =
-            Smi::Value(Smi::RawCast(value_or_offset));
+        field->ptr()->host_offset_or_field_id_ = Smi::RawCast(value_or_offset);
 #if !defined(DART_PRECOMPILED_RUNTIME)
-        field->ptr()->target_offset_ = field->ptr()->host_offset_or_field_id_;
+        field->ptr()->target_offset_ =
+            Smi::Value(field->ptr()->host_offset_or_field_id_);
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
       }
     }
@@ -1182,6 +1203,10 @@
         field.InitializeGuardedListLengthInObjectOffset();
       }
     }
+
+    Isolate* isolate = Isolate::Current();
+    isolate->set_saved_initial_field_table(
+        std::shared_ptr<FieldTable>(isolate->field_table()->Clone()));
   }
 };
 
@@ -1191,8 +1216,8 @@
   ScriptSerializationCluster() : SerializationCluster("Script") {}
   ~ScriptSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawScript* script = Script::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ScriptPtr script = Script::RawCast(object);
     objects_.Add(script);
     PushFromTo(script);
   }
@@ -1202,7 +1227,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawScript* script = objects_[i];
+      ScriptPtr script = objects_[i];
       s->AssignRef(script);
     }
   }
@@ -1210,7 +1235,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawScript* script = objects_[i];
+      ScriptPtr script = objects_[i];
       AutoTraceObjectName(script, script->ptr()->url_);
       WriteFromTo(script);
       s->Write<int32_t>(script->ptr()->line_offset_);
@@ -1221,7 +1246,7 @@
   }
 
  private:
-  GrowableArray<RawScript*> objects_;
+  GrowableArray<ScriptPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1242,7 +1267,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawScript* script = reinterpret_cast<RawScript*>(d->Ref(id));
+      ScriptPtr script = static_cast<ScriptPtr>(d->Ref(id));
       Deserializer::InitializeHeader(script, kScriptCid,
                                      Script::InstanceSize());
       ReadFromTo(script);
@@ -1261,8 +1286,8 @@
   LibrarySerializationCluster() : SerializationCluster("Library") {}
   ~LibrarySerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawLibrary* lib = Library::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    LibraryPtr lib = Library::RawCast(object);
     objects_.Add(lib);
     PushFromTo(lib);
   }
@@ -1272,7 +1297,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawLibrary* lib = objects_[i];
+      LibraryPtr lib = objects_[i];
       s->AssignRef(lib);
     }
   }
@@ -1280,7 +1305,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawLibrary* lib = objects_[i];
+      LibraryPtr lib = objects_[i];
       AutoTraceObjectName(lib, lib->ptr()->url_);
       WriteFromTo(lib);
       s->Write<int32_t>(lib->ptr()->index_);
@@ -1294,7 +1319,7 @@
   }
 
  private:
-  GrowableArray<RawLibrary*> objects_;
+  GrowableArray<LibraryPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1315,7 +1340,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawLibrary* lib = reinterpret_cast<RawLibrary*>(d->Ref(id));
+      LibraryPtr lib = static_cast<LibraryPtr>(d->Ref(id));
       Deserializer::InitializeHeader(lib, kLibraryCid, Library::InstanceSize());
       ReadFromTo(lib);
       lib->ptr()->native_entry_resolver_ = NULL;
@@ -1324,7 +1349,7 @@
       lib->ptr()->num_imports_ = d->Read<uint16_t>();
       lib->ptr()->load_state_ = d->Read<int8_t>();
       lib->ptr()->flags_ =
-          RawLibrary::InFullSnapshotBit::update(true, d->Read<uint8_t>());
+          LibraryLayout::InFullSnapshotBit::update(true, d->Read<uint8_t>());
 #if !defined(DART_PRECOMPILED_RUNTIME)
       if (d->kind() != Snapshot::kFullAOT) {
         lib->ptr()->binary_declaration_ = d->Read<uint32_t>();
@@ -1340,8 +1365,8 @@
   NamespaceSerializationCluster() : SerializationCluster("Namespace") {}
   ~NamespaceSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawNamespace* ns = Namespace::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    NamespacePtr ns = Namespace::RawCast(object);
     objects_.Add(ns);
     PushFromTo(ns);
   }
@@ -1351,7 +1376,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawNamespace* ns = objects_[i];
+      NamespacePtr ns = objects_[i];
       s->AssignRef(ns);
     }
   }
@@ -1359,14 +1384,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawNamespace* ns = objects_[i];
+      NamespacePtr ns = objects_[i];
       AutoTraceObject(ns);
       WriteFromTo(ns);
     }
   }
 
  private:
-  GrowableArray<RawNamespace*> objects_;
+  GrowableArray<NamespacePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1387,7 +1412,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawNamespace* ns = reinterpret_cast<RawNamespace*>(d->Ref(id));
+      NamespacePtr ns = static_cast<NamespacePtr>(d->Ref(id));
       Deserializer::InitializeHeader(ns, kNamespaceCid,
                                      Namespace::InstanceSize());
       ReadFromTo(ns);
@@ -1403,8 +1428,8 @@
       : SerializationCluster("KernelProgramInfo") {}
   ~KernelProgramInfoSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawKernelProgramInfo* info = KernelProgramInfo::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    KernelProgramInfoPtr info = KernelProgramInfo::RawCast(object);
     objects_.Add(info);
     PushFromTo(info);
   }
@@ -1414,7 +1439,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawKernelProgramInfo* info = objects_[i];
+      KernelProgramInfoPtr info = objects_[i];
       s->AssignRef(info);
     }
   }
@@ -1422,7 +1447,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawKernelProgramInfo* info = objects_[i];
+      KernelProgramInfoPtr info = objects_[i];
       AutoTraceObject(info);
       WriteFromTo(info);
       s->Write<uint32_t>(info->ptr()->kernel_binary_version_);
@@ -1430,7 +1455,7 @@
   }
 
  private:
-  GrowableArray<RawKernelProgramInfo*> objects_;
+  GrowableArray<KernelProgramInfoPtr> objects_;
 };
 
 // Since KernelProgramInfo objects are not written into full AOT snapshots,
@@ -1453,8 +1478,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawKernelProgramInfo* info =
-          reinterpret_cast<RawKernelProgramInfo*>(d->Ref(id));
+      KernelProgramInfoPtr info = static_cast<KernelProgramInfoPtr>(d->Ref(id));
       Deserializer::InitializeHeader(info, kKernelProgramInfoCid,
                                      KernelProgramInfo::InstanceSize());
       ReadFromTo(info);
@@ -1480,8 +1504,8 @@
   CodeSerializationCluster() : SerializationCluster("Code") {}
   ~CodeSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawCode* code = Code::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    CodePtr code = Code::RawCast(object);
     objects_.Add(code);
 
     if (!(s->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
@@ -1492,13 +1516,30 @@
     s->Push(code->ptr()->pc_descriptors_);
     s->Push(code->ptr()->catch_entry_);
     s->Push(code->ptr()->compressed_stackmaps_);
-    if (!FLAG_dwarf_stack_traces) {
+    if (!FLAG_precompiled_mode || !FLAG_dwarf_stack_traces_mode) {
       s->Push(code->ptr()->inlined_id_to_function_);
       s->Push(code->ptr()->code_source_map_);
     }
     if (s->kind() == Snapshot::kFullJIT) {
       s->Push(code->ptr()->deopt_info_array_);
       s->Push(code->ptr()->static_calls_target_table_);
+    } else if (s->kind() == Snapshot::kFullAOT) {
+#if defined(DART_PRECOMPILER)
+      auto const calls_array = code->ptr()->static_calls_target_table_;
+      if (calls_array != Array::null()) {
+        // Some Code entries in the static calls target table may only be
+        // accessible via here, so push the Code objects.
+        auto const length = Smi::Value(calls_array->ptr()->length_);
+        for (intptr_t i = 0; i < length; i++) {
+          auto const object = calls_array->ptr()->data()[i];
+          if (object->IsHeapObject() && object->IsCode()) {
+            s->Push(object);
+          }
+        }
+      }
+#else
+      UNREACHABLE();
+#endif
     }
 #if !defined(PRODUCT)
     s->Push(code->ptr()->return_address_metadata_);
@@ -1513,7 +1554,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawCode* code = objects_[i];
+      CodePtr code = objects_[i];
       s->AssignRef(code);
     }
   }
@@ -1522,7 +1563,7 @@
     Snapshot::Kind kind = s->kind();
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawCode* code = objects_[i];
+      CodePtr code = objects_[i];
       AutoTraceObject(code);
 
       intptr_t pointer_offsets_length =
@@ -1556,7 +1597,7 @@
                  code->ptr()->object_pool_ != ObjectPool::null()) {
         // If we are writing V8 snapshot profile then attribute references
         // going through the object pool to the code object itself.
-        RawObjectPool* pool = code->ptr()->object_pool_;
+        ObjectPoolPtr pool = code->ptr()->object_pool_;
 
         for (intptr_t i = 0; i < pool->ptr()->length_; i++) {
           uint8_t bits = pool->ptr()->entry_bits()[i];
@@ -1572,7 +1613,7 @@
       WriteField(code, pc_descriptors_);
       WriteField(code, catch_entry_);
       WriteField(code, compressed_stackmaps_);
-      if (FLAG_dwarf_stack_traces) {
+      if (FLAG_precompiled_mode && FLAG_dwarf_stack_traces_mode) {
         WriteFieldValue(inlined_id_to_function_, Array::null());
         WriteFieldValue(code_source_map_, CodeSourceMap::null());
       } else {
@@ -1593,10 +1634,10 @@
     }
   }
 
-  GrowableArray<RawCode*>* discovered_objects() { return &objects_; }
+  GrowableArray<CodePtr>* discovered_objects() { return &objects_; }
 
  private:
-  GrowableArray<RawCode*> objects_;
+  GrowableArray<CodePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1614,10 +1655,10 @@
     // [Code]'s instructions will be located in memory.
     const bool build_code_order =
         FLAG_precompiled_mode && FLAG_use_bare_instructions;
-    RawArray* code_order = nullptr;
+    ArrayPtr code_order = nullptr;
     const intptr_t code_order_length = d->code_order_length();
     if (build_code_order) {
-      code_order = static_cast<RawArray*>(AllocateUninitialized(
+      code_order = static_cast<ArrayPtr>(AllocateUninitialized(
           old_space, Array::InstanceSize(code_order_length)));
       Deserializer::InitializeHeader(code_order, kArrayCid,
                                      Array::InstanceSize(code_order_length),
@@ -1644,7 +1685,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      auto const code = reinterpret_cast<RawCode*>(d->Ref(id));
+      auto const code = static_cast<CodePtr>(d->Ref(id));
       Deserializer::InitializeHeader(code, kCodeCid, Code::InstanceSize(0));
 
       d->ReadInstructions(code, id, start_index_);
@@ -1652,30 +1693,28 @@
       // There would be a single global pool if this is a full AOT snapshot
       // with bare instructions.
       if (!(d->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
-        code->ptr()->object_pool_ =
-            reinterpret_cast<RawObjectPool*>(d->ReadRef());
+        code->ptr()->object_pool_ = static_cast<ObjectPoolPtr>(d->ReadRef());
       } else {
         code->ptr()->object_pool_ = ObjectPool::null();
       }
       code->ptr()->owner_ = d->ReadRef();
       code->ptr()->exception_handlers_ =
-          reinterpret_cast<RawExceptionHandlers*>(d->ReadRef());
+          static_cast<ExceptionHandlersPtr>(d->ReadRef());
       code->ptr()->pc_descriptors_ =
-          reinterpret_cast<RawPcDescriptors*>(d->ReadRef());
+          static_cast<PcDescriptorsPtr>(d->ReadRef());
       code->ptr()->catch_entry_ = d->ReadRef();
       code->ptr()->compressed_stackmaps_ =
-          reinterpret_cast<RawCompressedStackMaps*>(d->ReadRef());
+          static_cast<CompressedStackMapsPtr>(d->ReadRef());
       code->ptr()->inlined_id_to_function_ =
-          reinterpret_cast<RawArray*>(d->ReadRef());
+          static_cast<ArrayPtr>(d->ReadRef());
       code->ptr()->code_source_map_ =
-          reinterpret_cast<RawCodeSourceMap*>(d->ReadRef());
+          static_cast<CodeSourceMapPtr>(d->ReadRef());
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
       if (d->kind() == Snapshot::kFullJIT) {
-        code->ptr()->deopt_info_array_ =
-            reinterpret_cast<RawArray*>(d->ReadRef());
+        code->ptr()->deopt_info_array_ = static_cast<ArrayPtr>(d->ReadRef());
         code->ptr()->static_calls_target_table_ =
-            reinterpret_cast<RawArray*>(d->ReadRef());
+            static_cast<ArrayPtr>(d->ReadRef());
       }
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1683,7 +1722,7 @@
       code->ptr()->return_address_metadata_ = d->ReadRef();
       code->ptr()->var_descriptors_ = LocalVarDescriptors::null();
       code->ptr()->comments_ = FLAG_code_comments
-                                   ? reinterpret_cast<RawArray*>(d->ReadRef())
+                                   ? static_cast<ArrayPtr>(d->ReadRef())
                                    : Array::null();
       code->ptr()->compile_timestamp_ = 0;
 #endif
@@ -1710,7 +1749,7 @@
       if (owner.IsFunction()) {
         if ((FLAG_disassemble ||
              (code.is_optimized() && FLAG_disassemble_optimized)) &&
-            FlowGraphPrinter::ShouldPrint(Function::Cast(owner))) {
+            compiler::PrintFilter::ShouldPrint(Function::Cast(owner))) {
           Disassembler::DisassembleCode(Function::Cast(owner), code,
                                         code.is_optimized());
         }
@@ -1728,8 +1767,8 @@
   BytecodeSerializationCluster() : SerializationCluster("Bytecode") {}
   virtual ~BytecodeSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawBytecode* bytecode = Bytecode::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    BytecodePtr bytecode = Bytecode::RawCast(object);
     objects_.Add(bytecode);
     PushFromTo(bytecode);
   }
@@ -1739,7 +1778,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawBytecode* bytecode = objects_[i];
+      BytecodePtr bytecode = objects_[i];
       s->AssignRef(bytecode);
     }
   }
@@ -1748,7 +1787,7 @@
     ASSERT(s->kind() != Snapshot::kFullAOT);
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawBytecode* bytecode = objects_[i];
+      BytecodePtr bytecode = objects_[i];
       s->Write<int32_t>(bytecode->ptr()->instructions_size_);
       WriteFromTo(bytecode);
       s->Write<int32_t>(bytecode->ptr()->instructions_binary_offset_);
@@ -1758,7 +1797,7 @@
   }
 
  private:
-  GrowableArray<RawBytecode*> objects_;
+  GrowableArray<BytecodePtr> objects_;
 };
 
 class BytecodeDeserializationCluster : public DeserializationCluster {
@@ -1780,7 +1819,7 @@
     ASSERT(d->kind() != Snapshot::kFullAOT);
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
+      BytecodePtr bytecode = static_cast<BytecodePtr>(d->Ref(id));
       Deserializer::InitializeHeader(bytecode, kBytecodeCid,
                                      Bytecode::InstanceSize());
       bytecode->ptr()->instructions_ = 0;
@@ -1810,8 +1849,8 @@
   ObjectPoolSerializationCluster() : SerializationCluster("ObjectPool") {}
   ~ObjectPoolSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawObjectPool* pool = ObjectPool::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ObjectPoolPtr pool = ObjectPool::RawCast(object);
     objects_.Add(pool);
 
     const intptr_t length = pool->ptr()->length_;
@@ -1830,7 +1869,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawObjectPool* pool = objects_[i];
+      ObjectPoolPtr pool = objects_[i];
       s->AssignRef(pool);
       AutoTraceObject(pool);
       const intptr_t length = pool->ptr()->length_;
@@ -1841,14 +1880,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawObjectPool* pool = objects_[i];
+      ObjectPoolPtr pool = objects_[i];
       AutoTraceObject(pool);
       const intptr_t length = pool->ptr()->length_;
       s->WriteUnsigned(length);
       uint8_t* entry_bits = pool->ptr()->entry_bits();
       for (intptr_t j = 0; j < length; j++) {
         s->Write<uint8_t>(entry_bits[j]);
-        RawObjectPool::Entry& entry = pool->ptr()->data()[j];
+        ObjectPoolLayout::Entry& entry = pool->ptr()->data()[j];
         switch (ObjectPool::TypeBits::decode(entry_bits[j])) {
           case ObjectPool::EntryType::kTaggedObject: {
             if ((entry.raw_obj_ == StubCode::CallNoScopeNative().raw()) ||
@@ -1867,8 +1906,8 @@
             break;
           }
           case ObjectPool::EntryType::kNativeEntryData: {
-            RawObject* raw = entry.raw_obj_;
-            RawTypedData* raw_data = reinterpret_cast<RawTypedData*>(raw);
+            ObjectPtr raw = entry.raw_obj_;
+            TypedDataPtr raw_data = static_cast<TypedDataPtr>(raw);
             // kNativeEntryData object pool entries are for linking natives for
             // the interpreter. Before writing these entries into the snapshot,
             // we need to unlink them by nulling out the 'trampoline' and
@@ -1895,7 +1934,7 @@
   }
 
  private:
-  GrowableArray<RawObjectPool*> objects_;
+  GrowableArray<ObjectPoolPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -1919,14 +1958,14 @@
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id += 1) {
       const intptr_t length = d->ReadUnsigned();
-      RawObjectPool* pool = reinterpret_cast<RawObjectPool*>(d->Ref(id + 0));
+      ObjectPoolPtr pool = static_cast<ObjectPoolPtr>(d->Ref(id + 0));
       Deserializer::InitializeHeader(pool, kObjectPoolCid,
                                      ObjectPool::InstanceSize(length));
       pool->ptr()->length_ = length;
       for (intptr_t j = 0; j < length; j++) {
         const uint8_t entry_bits = d->Read<uint8_t>();
         pool->ptr()->entry_bits()[j] = entry_bits;
-        RawObjectPool::Entry& entry = pool->ptr()->data()[j];
+        ObjectPoolLayout::Entry& entry = pool->ptr()->data()[j];
         switch (ObjectPool::TypeBits::decode(entry_bits)) {
           case ObjectPool::EntryType::kNativeEntryData:
           case ObjectPool::EntryType::kTaggedObject:
@@ -1961,7 +2000,7 @@
         canonical_wsr_map_(zone) {}
   ~WeakSerializationReferenceSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
+  void Trace(Serializer* s, ObjectPtr object) {
     ASSERT(s->kind() == Snapshot::kFullAOT);
     // Make sure we don't trace again after choosing canonical WSRs.
     ASSERT(!have_canonicalized_wsrs_);
@@ -2048,14 +2087,14 @@
   // Returns whether a WSR should be dropped due to its target being reachable
   // via strong references. WSRs only wrap heap objects, so we can just retrieve
   // the object ID from the heap directly.
-  bool ShouldDrop(RawWeakSerializationReference* ref) const {
+  bool ShouldDrop(WeakSerializationReferencePtr ref) const {
     auto const target = WeakSerializationReference::TargetOf(ref);
     return Serializer::IsReachableReference(heap_->GetObjectId(target));
   }
 
   Heap* const heap_;
-  GrowableArray<RawWeakSerializationReference*> objects_;
-  GrowableArray<RawWeakSerializationReference*> canonical_wsrs_;
+  GrowableArray<WeakSerializationReferencePtr> objects_;
+  GrowableArray<WeakSerializationReferencePtr> canonical_wsrs_;
   IntMap<intptr_t> canonical_wsr_map_;
   bool have_canonicalized_wsrs_ = false;
 };
@@ -2084,8 +2123,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      auto const ref =
-          reinterpret_cast<RawWeakSerializationReference*>(d->Ref(id));
+      auto const ref = static_cast<WeakSerializationReferencePtr>(d->Ref(id));
       Deserializer::InitializeHeader(
           ref, kWeakSerializationReferenceCid,
           WeakSerializationReference::InstanceSize());
@@ -2101,8 +2139,8 @@
   PcDescriptorsSerializationCluster() : SerializationCluster("PcDescriptors") {}
   ~PcDescriptorsSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    PcDescriptorsPtr desc = PcDescriptors::RawCast(object);
     objects_.Add(desc);
   }
 
@@ -2111,7 +2149,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawPcDescriptors* desc = objects_[i];
+      PcDescriptorsPtr desc = objects_[i];
       s->AssignRef(desc);
       AutoTraceObject(desc);
       const intptr_t length = desc->ptr()->length_;
@@ -2122,7 +2160,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawPcDescriptors* desc = objects_[i];
+      PcDescriptorsPtr desc = objects_[i];
       AutoTraceObject(desc);
       const intptr_t length = desc->ptr()->length_;
       s->WriteUnsigned(length);
@@ -2132,7 +2170,7 @@
   }
 
  private:
-  GrowableArray<RawPcDescriptors*> objects_;
+  GrowableArray<PcDescriptorsPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2156,7 +2194,7 @@
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id += 1) {
       const intptr_t length = d->ReadUnsigned();
-      RawPcDescriptors* desc = reinterpret_cast<RawPcDescriptors*>(d->Ref(id));
+      PcDescriptorsPtr desc = static_cast<PcDescriptorsPtr>(d->Ref(id));
       Deserializer::InitializeHeader(desc, kPcDescriptorsCid,
                                      PcDescriptors::InstanceSize(length));
       desc->ptr()->length_ = length;
@@ -2177,12 +2215,12 @@
         type_(type) {}
   ~RODataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
+  void Trace(Serializer* s, ObjectPtr object) {
     // A string's hash must already be computed when we write it because it
     // will be loaded into read-only memory. Extra bytes due to allocation
     // rounding need to be deterministically set for reliable deduplication in
     // shared images.
-    if (object->InVMIsolateHeap() ||
+    if (object->ptr()->InVMIsolateHeap() ||
         s->isolate()->heap()->old_space()->IsObjectFromImagePages(object)) {
       // This object is already read-only.
     } else {
@@ -2199,7 +2237,7 @@
     s->WriteUnsigned(count);
     uint32_t running_offset = 0;
     for (intptr_t i = 0; i < count; i++) {
-      RawObject* object = objects_[i];
+      ObjectPtr object = objects_[i];
       s->AssignRef(object);
       if (cid_ == kOneByteStringCid || cid_ == kTwoByteStringCid) {
         s->TraceStartWritingObject(type_, object, String::RawCast(object));
@@ -2224,7 +2262,7 @@
 
  private:
   const intptr_t cid_;
-  GrowableArray<RawObject*> objects_;
+  GrowableArray<ObjectPtr> objects_;
   const char* const type_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
@@ -2255,8 +2293,8 @@
       : SerializationCluster("ExceptionHandlers") {}
   ~ExceptionHandlersSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawExceptionHandlers* handlers = ExceptionHandlers::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ExceptionHandlersPtr handlers = ExceptionHandlers::RawCast(object);
     objects_.Add(handlers);
 
     s->Push(handlers->ptr()->handled_types_data_);
@@ -2267,7 +2305,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawExceptionHandlers* handlers = objects_[i];
+      ExceptionHandlersPtr handlers = objects_[i];
       s->AssignRef(handlers);
       AutoTraceObject(handlers);
       const intptr_t length = handlers->ptr()->num_entries_;
@@ -2278,7 +2316,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawExceptionHandlers* handlers = objects_[i];
+      ExceptionHandlersPtr handlers = objects_[i];
       AutoTraceObject(handlers);
       const intptr_t length = handlers->ptr()->num_entries_;
       s->WriteUnsigned(length);
@@ -2295,7 +2333,7 @@
   }
 
  private:
-  GrowableArray<RawExceptionHandlers*> objects_;
+  GrowableArray<ExceptionHandlersPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2318,14 +2356,14 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawExceptionHandlers* handlers =
-          reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
+      ExceptionHandlersPtr handlers =
+          static_cast<ExceptionHandlersPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
                                      ExceptionHandlers::InstanceSize(length));
       handlers->ptr()->num_entries_ = length;
       handlers->ptr()->handled_types_data_ =
-          reinterpret_cast<RawArray*>(d->ReadRef());
+          static_cast<ArrayPtr>(d->ReadRef());
       for (intptr_t j = 0; j < length; j++) {
         ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
         info.handler_pc_offset = d->Read<uint32_t>();
@@ -2344,8 +2382,8 @@
   ContextSerializationCluster() : SerializationCluster("Context") {}
   ~ContextSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawContext* context = Context::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ContextPtr context = Context::RawCast(object);
     objects_.Add(context);
 
     s->Push(context->ptr()->parent_);
@@ -2360,7 +2398,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawContext* context = objects_[i];
+      ContextPtr context = objects_[i];
       s->AssignRef(context);
       AutoTraceObject(context);
       const intptr_t length = context->ptr()->num_variables_;
@@ -2371,7 +2409,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawContext* context = objects_[i];
+      ContextPtr context = objects_[i];
       AutoTraceObject(context);
       const intptr_t length = context->ptr()->num_variables_;
       s->WriteUnsigned(length);
@@ -2383,7 +2421,7 @@
   }
 
  private:
-  GrowableArray<RawContext*> objects_;
+  GrowableArray<ContextPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2406,12 +2444,12 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
+      ContextPtr context = static_cast<ContextPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(context, kContextCid,
                                      Context::InstanceSize(length));
       context->ptr()->num_variables_ = length;
-      context->ptr()->parent_ = reinterpret_cast<RawContext*>(d->ReadRef());
+      context->ptr()->parent_ = static_cast<ContextPtr>(d->ReadRef());
       for (intptr_t j = 0; j < length; j++) {
         context->ptr()->data()[j] = d->ReadRef();
       }
@@ -2425,8 +2463,8 @@
   ContextScopeSerializationCluster() : SerializationCluster("ContextScope") {}
   ~ContextScopeSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawContextScope* scope = ContextScope::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ContextScopePtr scope = ContextScope::RawCast(object);
     objects_.Add(scope);
 
     const intptr_t length = scope->ptr()->num_variables_;
@@ -2438,7 +2476,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawContextScope* scope = objects_[i];
+      ContextScopePtr scope = objects_[i];
       s->AssignRef(scope);
       AutoTraceObject(scope);
       const intptr_t length = scope->ptr()->num_variables_;
@@ -2449,7 +2487,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawContextScope* scope = objects_[i];
+      ContextScopePtr scope = objects_[i];
       AutoTraceObject(scope);
       const intptr_t length = scope->ptr()->num_variables_;
       s->WriteUnsigned(length);
@@ -2459,7 +2497,7 @@
   }
 
  private:
-  GrowableArray<RawContextScope*> objects_;
+  GrowableArray<ContextScopePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2482,7 +2520,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
+      ContextScopePtr scope = static_cast<ContextScopePtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(scope, kContextScopeCid,
                                      ContextScope::InstanceSize(length));
@@ -2500,8 +2538,8 @@
       : SerializationCluster("ParameterTypeCheck") {}
   ~ParameterTypeCheckSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawParameterTypeCheck* unlinked = ParameterTypeCheck::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ParameterTypeCheckPtr unlinked = ParameterTypeCheck::RawCast(object);
     objects_.Add(unlinked);
     PushFromTo(unlinked);
   }
@@ -2511,7 +2549,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawParameterTypeCheck* check = objects_[i];
+      ParameterTypeCheckPtr check = objects_[i];
       s->AssignRef(check);
     }
   }
@@ -2519,14 +2557,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawParameterTypeCheck* check = objects_[i];
+      ParameterTypeCheckPtr check = objects_[i];
       s->Write<intptr_t>(check->ptr()->index_);
       WriteFromTo(check);
     }
   }
 
  private:
-  GrowableArray<RawParameterTypeCheck*> objects_;
+  GrowableArray<ParameterTypeCheckPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2548,8 +2586,8 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawParameterTypeCheck* check =
-          reinterpret_cast<RawParameterTypeCheck*>(d->Ref(id));
+      ParameterTypeCheckPtr check =
+          static_cast<ParameterTypeCheckPtr>(d->Ref(id));
       Deserializer::InitializeHeader(check, kParameterTypeCheckCid,
                                      ParameterTypeCheck::InstanceSize());
       check->ptr()->index_ = d->Read<intptr_t>();
@@ -2564,8 +2602,8 @@
   UnlinkedCallSerializationCluster() : SerializationCluster("UnlinkedCall") {}
   ~UnlinkedCallSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawUnlinkedCall* unlinked = UnlinkedCall::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    UnlinkedCallPtr unlinked = UnlinkedCall::RawCast(object);
     objects_.Add(unlinked);
     PushFromTo(unlinked);
   }
@@ -2575,7 +2613,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawUnlinkedCall* unlinked = objects_[i];
+      UnlinkedCallPtr unlinked = objects_[i];
       s->AssignRef(unlinked);
     }
   }
@@ -2583,7 +2621,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawUnlinkedCall* unlinked = objects_[i];
+      UnlinkedCallPtr unlinked = objects_[i];
       AutoTraceObjectName(unlinked, unlinked->ptr()->target_name_);
       WriteFromTo(unlinked);
       s->Write<bool>(unlinked->ptr()->can_patch_to_monomorphic_);
@@ -2591,7 +2629,7 @@
   }
 
  private:
-  GrowableArray<RawUnlinkedCall*> objects_;
+  GrowableArray<UnlinkedCallPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2613,8 +2651,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawUnlinkedCall* unlinked =
-          reinterpret_cast<RawUnlinkedCall*>(d->Ref(id));
+      UnlinkedCallPtr unlinked = static_cast<UnlinkedCallPtr>(d->Ref(id));
       Deserializer::InitializeHeader(unlinked, kUnlinkedCallCid,
                                      UnlinkedCall::InstanceSize());
       ReadFromTo(unlinked);
@@ -2629,8 +2666,8 @@
   ICDataSerializationCluster() : SerializationCluster("ICData") {}
   ~ICDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawICData* ic = ICData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ICDataPtr ic = ICData::RawCast(object);
     objects_.Add(ic);
     PushFromTo(ic);
   }
@@ -2640,7 +2677,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawICData* ic = objects_[i];
+      ICDataPtr ic = objects_[i];
       s->AssignRef(ic);
     }
   }
@@ -2649,7 +2686,7 @@
     Snapshot::Kind kind = s->kind();
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawICData* ic = objects_[i];
+      ICDataPtr ic = objects_[i];
       AutoTraceObjectName(ic, ic->ptr()->target_name_);
       WriteFromTo(ic);
       if (kind != Snapshot::kFullAOT) {
@@ -2660,7 +2697,7 @@
   }
 
  private:
-  GrowableArray<RawICData*> objects_;
+  GrowableArray<ICDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2681,7 +2718,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawICData* ic = reinterpret_cast<RawICData*>(d->Ref(id));
+      ICDataPtr ic = static_cast<ICDataPtr>(d->Ref(id));
       Deserializer::InitializeHeader(ic, kICDataCid, ICData::InstanceSize());
       ReadFromTo(ic);
       NOT_IN_PRECOMPILED(ic->ptr()->deopt_id_ = d->Read<int32_t>());
@@ -2697,8 +2734,8 @@
       : SerializationCluster("MegamorphicCache") {}
   ~MegamorphicCacheSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawMegamorphicCache* cache = MegamorphicCache::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    MegamorphicCachePtr cache = MegamorphicCache::RawCast(object);
     objects_.Add(cache);
     PushFromTo(cache);
   }
@@ -2708,7 +2745,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawMegamorphicCache* cache = objects_[i];
+      MegamorphicCachePtr cache = objects_[i];
       s->AssignRef(cache);
     }
   }
@@ -2716,7 +2753,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawMegamorphicCache* cache = objects_[i];
+      MegamorphicCachePtr cache = objects_[i];
       AutoTraceObjectName(cache, cache->ptr()->target_name_);
       WriteFromTo(cache);
       s->Write<int32_t>(cache->ptr()->filled_entry_count_);
@@ -2724,7 +2761,7 @@
   }
 
  private:
-  GrowableArray<RawMegamorphicCache*> objects_;
+  GrowableArray<MegamorphicCachePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2746,8 +2783,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawMegamorphicCache* cache =
-          reinterpret_cast<RawMegamorphicCache*>(d->Ref(id));
+      MegamorphicCachePtr cache = static_cast<MegamorphicCachePtr>(d->Ref(id));
       Deserializer::InitializeHeader(cache, kMegamorphicCacheCid,
                                      MegamorphicCache::InstanceSize());
       ReadFromTo(cache);
@@ -2789,8 +2825,8 @@
       : SerializationCluster("SubtypeTestCache") {}
   ~SubtypeTestCacheSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawSubtypeTestCache* cache = SubtypeTestCache::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    SubtypeTestCachePtr cache = SubtypeTestCache::RawCast(object);
     objects_.Add(cache);
     s->Push(cache->ptr()->cache_);
   }
@@ -2800,7 +2836,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawSubtypeTestCache* cache = objects_[i];
+      SubtypeTestCachePtr cache = objects_[i];
       s->AssignRef(cache);
     }
   }
@@ -2808,14 +2844,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawSubtypeTestCache* cache = objects_[i];
+      SubtypeTestCachePtr cache = objects_[i];
       AutoTraceObject(cache);
       WriteField(cache, cache_);
     }
   }
 
  private:
-  GrowableArray<RawSubtypeTestCache*> objects_;
+  GrowableArray<SubtypeTestCachePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2837,11 +2873,10 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawSubtypeTestCache* cache =
-          reinterpret_cast<RawSubtypeTestCache*>(d->Ref(id));
+      SubtypeTestCachePtr cache = static_cast<SubtypeTestCachePtr>(d->Ref(id));
       Deserializer::InitializeHeader(cache, kSubtypeTestCacheCid,
                                      SubtypeTestCache::InstanceSize());
-      cache->ptr()->cache_ = reinterpret_cast<RawArray*>(d->ReadRef());
+      cache->ptr()->cache_ = static_cast<ArrayPtr>(d->ReadRef());
     }
   }
 };
@@ -2852,8 +2887,8 @@
   LanguageErrorSerializationCluster() : SerializationCluster("LanguageError") {}
   ~LanguageErrorSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawLanguageError* error = LanguageError::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    LanguageErrorPtr error = LanguageError::RawCast(object);
     objects_.Add(error);
     PushFromTo(error);
   }
@@ -2863,7 +2898,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawLanguageError* error = objects_[i];
+      LanguageErrorPtr error = objects_[i];
       s->AssignRef(error);
     }
   }
@@ -2871,7 +2906,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawLanguageError* error = objects_[i];
+      LanguageErrorPtr error = objects_[i];
       AutoTraceObject(error);
       WriteFromTo(error);
       s->WriteTokenPosition(error->ptr()->token_pos_);
@@ -2881,7 +2916,7 @@
   }
 
  private:
-  GrowableArray<RawLanguageError*> objects_;
+  GrowableArray<LanguageErrorPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2903,7 +2938,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawLanguageError* error = reinterpret_cast<RawLanguageError*>(d->Ref(id));
+      LanguageErrorPtr error = static_cast<LanguageErrorPtr>(d->Ref(id));
       Deserializer::InitializeHeader(error, kLanguageErrorCid,
                                      LanguageError::InstanceSize());
       ReadFromTo(error);
@@ -2921,8 +2956,8 @@
       : SerializationCluster("UnhandledException") {}
   ~UnhandledExceptionSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawUnhandledException* exception = UnhandledException::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    UnhandledExceptionPtr exception = UnhandledException::RawCast(object);
     objects_.Add(exception);
     PushFromTo(exception);
   }
@@ -2932,7 +2967,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawUnhandledException* exception = objects_[i];
+      UnhandledExceptionPtr exception = objects_[i];
       s->AssignRef(exception);
     }
   }
@@ -2940,14 +2975,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawUnhandledException* exception = objects_[i];
+      UnhandledExceptionPtr exception = objects_[i];
       AutoTraceObject(exception);
       WriteFromTo(exception);
     }
   }
 
  private:
-  GrowableArray<RawUnhandledException*> objects_;
+  GrowableArray<UnhandledExceptionPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -2969,8 +3004,8 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawUnhandledException* exception =
-          reinterpret_cast<RawUnhandledException*>(d->Ref(id));
+      UnhandledExceptionPtr exception =
+          static_cast<UnhandledExceptionPtr>(d->Ref(id));
       Deserializer::InitializeHeader(exception, kUnhandledExceptionCid,
                                      UnhandledException::InstanceSize());
       ReadFromTo(exception);
@@ -2983,7 +3018,7 @@
  public:
   explicit InstanceSerializationCluster(intptr_t cid)
       : SerializationCluster("Instance"), cid_(cid) {
-    RawClass* cls = Isolate::Current()->class_table()->At(cid);
+    ClassPtr cls = Isolate::Current()->class_table()->At(cid);
     host_next_field_offset_in_words_ =
         cls->ptr()->host_next_field_offset_in_words_;
     ASSERT(host_next_field_offset_in_words_ > 0);
@@ -2997,18 +3032,19 @@
   }
   ~InstanceSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawInstance* instance = Instance::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    InstancePtr instance = Instance::RawCast(object);
     objects_.Add(instance);
     const intptr_t next_field_offset = host_next_field_offset_in_words_
                                        << kWordSizeLog2;
     const auto unboxed_fields_bitmap =
-        s->isolate()->group()->class_table()->GetUnboxedFieldsMapAt(cid_);
+        s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
+            cid_);
     intptr_t offset = Instance::NextFieldOffset();
     while (offset < next_field_offset) {
       // Skips unboxed fields
       if (!unboxed_fields_bitmap.Get(offset / kWordSize)) {
-        RawObject* raw_obj = *reinterpret_cast<RawObject**>(
+        ObjectPtr raw_obj = *reinterpret_cast<ObjectPtr*>(
             reinterpret_cast<uword>(instance->ptr()) + offset);
         s->Push(raw_obj);
       }
@@ -3029,7 +3065,7 @@
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
 
     for (intptr_t i = 0; i < count; i++) {
-      RawInstance* instance = objects_[i];
+      InstancePtr instance = objects_[i];
       s->AssignRef(instance);
     }
   }
@@ -3039,11 +3075,12 @@
                                  << kWordSizeLog2;
     const intptr_t count = objects_.length();
     const auto unboxed_fields_bitmap =
-        s->isolate()->group()->class_table()->GetUnboxedFieldsMapAt(cid_);
+        s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
+            cid_);
     for (intptr_t i = 0; i < count; i++) {
-      RawInstance* instance = objects_[i];
+      InstancePtr instance = objects_[i];
       AutoTraceObject(instance);
-      s->Write<bool>(instance->IsCanonical());
+      s->Write<bool>(instance->ptr()->IsCanonical());
       intptr_t offset = Instance::NextFieldOffset();
       while (offset < next_field_offset) {
         if (unboxed_fields_bitmap.Get(offset / kWordSize)) {
@@ -3052,7 +3089,7 @@
               reinterpret_cast<uword>(instance->ptr()) + offset);
           s->WriteWordWith32BitWrites(value);
         } else {
-          RawObject* raw_obj = *reinterpret_cast<RawObject**>(
+          ObjectPtr raw_obj = *reinterpret_cast<ObjectPtr*>(
               reinterpret_cast<uword>(instance->ptr()) + offset);
           s->WriteElementRef(raw_obj, offset);
         }
@@ -3068,7 +3105,7 @@
   intptr_t target_next_field_offset_in_words_;
   intptr_t target_instance_size_in_words_;
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
-  GrowableArray<RawInstance*> objects_;
+  GrowableArray<InstancePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3097,9 +3134,10 @@
         Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
 
     const auto unboxed_fields_bitmap =
-        d->isolate()->group()->class_table()->GetUnboxedFieldsMapAt(cid_);
+        d->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
+            cid_);
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawInstance* instance = reinterpret_cast<RawInstance*>(d->Ref(id));
+      InstancePtr instance = static_cast<InstancePtr>(d->Ref(id));
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(instance, cid_, instance_size,
                                      is_canonical);
@@ -3111,14 +3149,14 @@
           // Reads 32 bits of the unboxed value at a time
           *p = d->ReadWordWith32BitReads();
         } else {
-          RawObject** p = reinterpret_cast<RawObject**>(
+          ObjectPtr* p = reinterpret_cast<ObjectPtr*>(
               reinterpret_cast<uword>(instance->ptr()) + offset);
           *p = d->ReadRef();
         }
         offset += kWordSize;
       }
       if (offset < instance_size) {
-        RawObject** p = reinterpret_cast<RawObject**>(
+        ObjectPtr* p = reinterpret_cast<ObjectPtr*>(
             reinterpret_cast<uword>(instance->ptr()) + offset);
         *p = Object::null();
         offset += kWordSize;
@@ -3139,8 +3177,8 @@
   LibraryPrefixSerializationCluster() : SerializationCluster("LibraryPrefix") {}
   ~LibraryPrefixSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawLibraryPrefix* prefix = LibraryPrefix::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    LibraryPrefixPtr prefix = LibraryPrefix::RawCast(object);
     objects_.Add(prefix);
     PushFromTo(prefix);
   }
@@ -3150,7 +3188,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawLibraryPrefix* prefix = objects_[i];
+      LibraryPrefixPtr prefix = objects_[i];
       s->AssignRef(prefix);
     }
   }
@@ -3158,7 +3196,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawLibraryPrefix* prefix = objects_[i];
+      LibraryPrefixPtr prefix = objects_[i];
       AutoTraceObject(prefix);
       WriteFromTo(prefix);
       s->Write<uint16_t>(prefix->ptr()->num_imports_);
@@ -3167,7 +3205,7 @@
   }
 
  private:
-  GrowableArray<RawLibraryPrefix*> objects_;
+  GrowableArray<LibraryPrefixPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3189,8 +3227,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawLibraryPrefix* prefix =
-          reinterpret_cast<RawLibraryPrefix*>(d->Ref(id));
+      LibraryPrefixPtr prefix = static_cast<LibraryPrefixPtr>(d->Ref(id));
       Deserializer::InitializeHeader(prefix, kLibraryPrefixCid,
                                      LibraryPrefix::InstanceSize());
       ReadFromTo(prefix);
@@ -3206,9 +3243,9 @@
   TypeSerializationCluster() : SerializationCluster("Type") {}
   ~TypeSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawType* type = Type::RawCast(object);
-    if (type->IsCanonical()) {
+  void Trace(Serializer* s, ObjectPtr object) {
+    TypePtr type = Type::RawCast(object);
+    if (type->ptr()->IsCanonical()) {
       canonical_objects_.Add(type);
     } else {
       objects_.Add(type);
@@ -3221,8 +3258,8 @@
       UNREACHABLE();
     }
 
-    RawSmi* raw_type_class_id = Smi::RawCast(type->ptr()->type_class_id_);
-    RawClass* type_class =
+    SmiPtr raw_type_class_id = Smi::RawCast(type->ptr()->type_class_id_);
+    ClassPtr type_class =
         s->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
     s->Push(type_class);
   }
@@ -3232,13 +3269,13 @@
     intptr_t count = canonical_objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawType* type = canonical_objects_[i];
+      TypePtr type = canonical_objects_[i];
       s->AssignRef(type);
     }
     count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawType* type = objects_[i];
+      TypePtr type = objects_[i];
       s->AssignRef(type);
     }
   }
@@ -3246,7 +3283,7 @@
   void WriteFill(Serializer* s) {
     intptr_t count = canonical_objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawType* type = canonical_objects_[i];
+      TypePtr type = canonical_objects_[i];
       AutoTraceObject(type);
       WriteFromTo(type);
       s->WriteTokenPosition(type->ptr()->token_pos_);
@@ -3258,7 +3295,7 @@
     }
     count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawType* type = objects_[i];
+      TypePtr type = objects_[i];
       AutoTraceObject(type);
       WriteFromTo(type);
       s->WriteTokenPosition(type->ptr()->token_pos_);
@@ -3271,8 +3308,8 @@
   }
 
  private:
-  GrowableArray<RawType*> canonical_objects_;
-  GrowableArray<RawType*> objects_;
+  GrowableArray<TypePtr> canonical_objects_;
+  GrowableArray<TypePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3301,7 +3338,7 @@
   void ReadFill(Deserializer* d) {
     for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
          id++) {
-      RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
+      TypePtr type = static_cast<TypePtr>(d->Ref(id));
       bool is_canonical = true;
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
                                      is_canonical);
@@ -3313,7 +3350,7 @@
     }
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
+      TypePtr type = static_cast<TypePtr>(d->Ref(id));
       bool is_canonical = false;
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
                                      is_canonical);
@@ -3367,8 +3404,8 @@
   TypeRefSerializationCluster() : SerializationCluster("TypeRef") {}
   ~TypeRefSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawTypeRef* type = TypeRef::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    TypeRefPtr type = TypeRef::RawCast(object);
     objects_.Add(type);
     PushFromTo(type);
   }
@@ -3378,7 +3415,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawTypeRef* type = objects_[i];
+      TypeRefPtr type = objects_[i];
       s->AssignRef(type);
     }
   }
@@ -3386,14 +3423,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawTypeRef* type = objects_[i];
+      TypeRefPtr type = objects_[i];
       AutoTraceObject(type);
       WriteFromTo(type);
     }
   }
 
  private:
-  GrowableArray<RawTypeRef*> objects_;
+  GrowableArray<TypeRefPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3414,7 +3451,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawTypeRef* type = reinterpret_cast<RawTypeRef*>(d->Ref(id));
+      TypeRefPtr type = static_cast<TypeRefPtr>(d->Ref(id));
       Deserializer::InitializeHeader(type, kTypeRefCid,
                                      TypeRef::InstanceSize());
       ReadFromTo(type);
@@ -3449,10 +3486,10 @@
 
   ~TypeParameterSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawTypeParameter* type = TypeParameter::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    TypeParameterPtr type = TypeParameter::RawCast(object);
     objects_.Add(type);
-    ASSERT(!type->IsCanonical());
+    ASSERT(!type->ptr()->IsCanonical());
     PushFromTo(type);
   }
 
@@ -3461,7 +3498,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawTypeParameter* type = objects_[i];
+      TypeParameterPtr type = objects_[i];
       s->AssignRef(type);
     }
   }
@@ -3469,7 +3506,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawTypeParameter* type = objects_[i];
+      TypeParameterPtr type = objects_[i];
       AutoTraceObject(type);
       WriteFromTo(type);
       s->Write<int32_t>(type->ptr()->parameterized_class_id_);
@@ -3484,7 +3521,7 @@
   }
 
  private:
-  GrowableArray<RawTypeParameter*> objects_;
+  GrowableArray<TypeParameterPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3506,7 +3543,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawTypeParameter* type = reinterpret_cast<RawTypeParameter*>(d->Ref(id));
+      TypeParameterPtr type = static_cast<TypeParameterPtr>(d->Ref(id));
       Deserializer::InitializeHeader(type, kTypeParameterCid,
                                      TypeParameter::InstanceSize());
       ReadFromTo(type);
@@ -3546,8 +3583,8 @@
   ClosureSerializationCluster() : SerializationCluster("Closure") {}
   ~ClosureSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawClosure* closure = Closure::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ClosurePtr closure = Closure::RawCast(object);
     objects_.Add(closure);
     PushFromTo(closure);
   }
@@ -3557,7 +3594,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawClosure* closure = objects_[i];
+      ClosurePtr closure = objects_[i];
       s->AssignRef(closure);
     }
   }
@@ -3565,15 +3602,15 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawClosure* closure = objects_[i];
+      ClosurePtr closure = objects_[i];
       AutoTraceObject(closure);
-      s->Write<bool>(closure->IsCanonical());
+      s->Write<bool>(closure->ptr()->IsCanonical());
       WriteFromTo(closure);
     }
   }
 
  private:
-  GrowableArray<RawClosure*> objects_;
+  GrowableArray<ClosurePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3594,7 +3631,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawClosure* closure = reinterpret_cast<RawClosure*>(d->Ref(id));
+      ClosurePtr closure = static_cast<ClosurePtr>(d->Ref(id));
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(closure, kClosureCid,
                                      Closure::InstanceSize(), is_canonical);
@@ -3609,12 +3646,12 @@
   MintSerializationCluster() : SerializationCluster("int") {}
   ~MintSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
+  void Trace(Serializer* s, ObjectPtr object) {
     if (!object->IsHeapObject()) {
-      RawSmi* smi = Smi::RawCast(object);
+      SmiPtr smi = Smi::RawCast(object);
       smis_.Add(smi);
     } else {
-      RawMint* mint = Mint::RawCast(object);
+      MintPtr mint = Mint::RawCast(object);
       mints_.Add(mint);
     }
   }
@@ -3624,17 +3661,17 @@
 
     s->WriteUnsigned(smis_.length() + mints_.length());
     for (intptr_t i = 0; i < smis_.length(); i++) {
-      RawSmi* smi = smis_[i];
+      SmiPtr smi = smis_[i];
       s->AssignRef(smi);
       AutoTraceObject(smi);
       s->Write<bool>(true);
       s->Write<int64_t>(Smi::Value(smi));
     }
     for (intptr_t i = 0; i < mints_.length(); i++) {
-      RawMint* mint = mints_[i];
+      MintPtr mint = mints_[i];
       s->AssignRef(mint);
       AutoTraceObject(mint);
-      s->Write<bool>(mint->IsCanonical());
+      s->Write<bool>(mint->ptr()->IsCanonical());
       s->Write<int64_t>(mint->ptr()->value_);
     }
   }
@@ -3642,8 +3679,8 @@
   void WriteFill(Serializer* s) {}
 
  private:
-  GrowableArray<RawSmi*> smis_;
-  GrowableArray<RawMint*> mints_;
+  GrowableArray<SmiPtr> smis_;
+  GrowableArray<MintPtr> mints_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3663,7 +3700,7 @@
       if (Smi::IsValid(value)) {
         d->AssignRef(Smi::New(value));
       } else {
-        RawMint* mint = static_cast<RawMint*>(
+        MintPtr mint = static_cast<MintPtr>(
             AllocateUninitialized(old_space, Mint::InstanceSize()));
         Deserializer::InitializeHeader(mint, kMintCid, Mint::InstanceSize(),
                                        is_canonical);
@@ -3696,8 +3733,8 @@
   DoubleSerializationCluster() : SerializationCluster("double") {}
   ~DoubleSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawDouble* dbl = Double::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    DoublePtr dbl = Double::RawCast(object);
     objects_.Add(dbl);
   }
 
@@ -3706,7 +3743,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawDouble* dbl = objects_[i];
+      DoublePtr dbl = objects_[i];
       s->AssignRef(dbl);
     }
   }
@@ -3714,15 +3751,15 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawDouble* dbl = objects_[i];
+      DoublePtr dbl = objects_[i];
       AutoTraceObject(dbl);
-      s->Write<bool>(dbl->IsCanonical());
+      s->Write<bool>(dbl->ptr()->IsCanonical());
       s->Write<double>(dbl->ptr()->value_);
     }
   }
 
  private:
-  GrowableArray<RawDouble*> objects_;
+  GrowableArray<DoublePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3743,7 +3780,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawDouble* dbl = reinterpret_cast<RawDouble*>(d->Ref(id));
+      DoublePtr dbl = static_cast<DoublePtr>(d->Ref(id));
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(dbl, kDoubleCid, Double::InstanceSize(),
                                      is_canonical);
@@ -3759,8 +3796,8 @@
       : SerializationCluster("GrowableObjectArray") {}
   ~GrowableObjectArraySerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawGrowableObjectArray* array = GrowableObjectArray::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    GrowableObjectArrayPtr array = GrowableObjectArray::RawCast(object);
     objects_.Add(array);
     PushFromTo(array);
   }
@@ -3770,7 +3807,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawGrowableObjectArray* array = objects_[i];
+      GrowableObjectArrayPtr array = objects_[i];
       s->AssignRef(array);
     }
   }
@@ -3778,15 +3815,15 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawGrowableObjectArray* array = objects_[i];
+      GrowableObjectArrayPtr array = objects_[i];
       AutoTraceObject(array);
-      s->Write<bool>(array->IsCanonical());
+      s->Write<bool>(array->ptr()->IsCanonical());
       WriteFromTo(array);
     }
   }
 
  private:
-  GrowableArray<RawGrowableObjectArray*> objects_;
+  GrowableArray<GrowableObjectArrayPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3809,8 +3846,8 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawGrowableObjectArray* list =
-          reinterpret_cast<RawGrowableObjectArray*>(d->Ref(id));
+      GrowableObjectArrayPtr list =
+          static_cast<GrowableObjectArrayPtr>(d->Ref(id));
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(list, kGrowableObjectArrayCid,
                                      GrowableObjectArray::InstanceSize(),
@@ -3827,8 +3864,8 @@
       : SerializationCluster("TypedData"), cid_(cid) {}
   ~TypedDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawTypedData* data = TypedData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    TypedDataPtr data = TypedData::RawCast(object);
     objects_.Add(data);
   }
 
@@ -3837,7 +3874,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawTypedData* data = objects_[i];
+      TypedDataPtr data = objects_[i];
       s->AssignRef(data);
       AutoTraceObject(data);
       const intptr_t length = Smi::Value(data->ptr()->length_);
@@ -3849,11 +3886,11 @@
     const intptr_t count = objects_.length();
     intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
     for (intptr_t i = 0; i < count; i++) {
-      RawTypedData* data = objects_[i];
+      TypedDataPtr data = objects_[i];
       AutoTraceObject(data);
       const intptr_t length = Smi::Value(data->ptr()->length_);
       s->WriteUnsigned(length);
-      s->Write<bool>(data->IsCanonical());
+      s->Write<bool>(data->ptr()->IsCanonical());
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
       s->WriteBytes(cdata, length * element_size);
     }
@@ -3861,7 +3898,7 @@
 
  private:
   const intptr_t cid_;
-  GrowableArray<RawTypedData*> objects_;
+  GrowableArray<TypedDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3887,14 +3924,14 @@
     intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
+      TypedDataPtr data = static_cast<TypedDataPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       const intptr_t length_in_bytes = length * element_size;
       Deserializer::InitializeHeader(
           data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
       data->ptr()->length_ = Smi::New(length);
-      data->RecomputeDataField();
+      data->ptr()->RecomputeDataField();
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
       d->ReadBytes(cdata, length_in_bytes);
     }
@@ -3911,8 +3948,8 @@
       : SerializationCluster("TypedDataView"), cid_(cid) {}
   ~TypedDataViewSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawTypedDataView* view = TypedDataView::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    TypedDataViewPtr view = TypedDataView::RawCast(object);
     objects_.Add(view);
 
     PushFromTo(view);
@@ -3923,7 +3960,7 @@
     s->WriteCid(cid_);
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawTypedDataView* view = objects_[i];
+      TypedDataViewPtr view = objects_[i];
       s->AssignRef(view);
     }
   }
@@ -3931,16 +3968,16 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawTypedDataView* view = objects_[i];
+      TypedDataViewPtr view = objects_[i];
       AutoTraceObject(view);
-      s->Write<bool>(view->IsCanonical());
+      s->Write<bool>(view->ptr()->IsCanonical());
       WriteFromTo(view);
     }
   }
 
  private:
   const intptr_t cid_;
-  GrowableArray<RawTypedDataView*> objects_;
+  GrowableArray<TypedDataViewPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -3962,7 +3999,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawTypedDataView* view = reinterpret_cast<RawTypedDataView*>(d->Ref(id));
+      TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
       const bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(view, cid_, TypedDataView::InstanceSize(),
                                      is_canonical);
@@ -3989,10 +4026,10 @@
       : SerializationCluster("ExternalTypedData"), cid_(cid) {}
   ~ExternalTypedDataSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawExternalTypedData* data = ExternalTypedData::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ExternalTypedDataPtr data = ExternalTypedData::RawCast(object);
     objects_.Add(data);
-    ASSERT(!data->IsCanonical());
+    ASSERT(!data->ptr()->IsCanonical());
   }
 
   void WriteAlloc(Serializer* s) {
@@ -4000,7 +4037,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawExternalTypedData* data = objects_[i];
+      ExternalTypedDataPtr data = objects_[i];
       s->AssignRef(data);
     }
   }
@@ -4009,7 +4046,7 @@
     const intptr_t count = objects_.length();
     intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
     for (intptr_t i = 0; i < count; i++) {
-      RawExternalTypedData* data = objects_[i];
+      ExternalTypedDataPtr data = objects_[i];
       AutoTraceObject(data);
       const intptr_t length = Smi::Value(data->ptr()->length_);
       s->WriteUnsigned(length);
@@ -4021,7 +4058,7 @@
 
  private:
   const intptr_t cid_;
-  GrowableArray<RawExternalTypedData*> objects_;
+  GrowableArray<ExternalTypedDataPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4045,8 +4082,7 @@
     intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawExternalTypedData* data =
-          reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
+      ExternalTypedDataPtr data = static_cast<ExternalTypedDataPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(data, cid_,
                                      ExternalTypedData::InstanceSize());
@@ -4068,8 +4104,8 @@
   StackTraceSerializationCluster() : SerializationCluster("StackTrace") {}
   ~StackTraceSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawStackTrace* trace = StackTrace::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    StackTracePtr trace = StackTrace::RawCast(object);
     objects_.Add(trace);
     PushFromTo(trace);
   }
@@ -4079,7 +4115,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawStackTrace* trace = objects_[i];
+      StackTracePtr trace = objects_[i];
       s->AssignRef(trace);
     }
   }
@@ -4087,14 +4123,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawStackTrace* trace = objects_[i];
+      StackTracePtr trace = objects_[i];
       AutoTraceObject(trace);
       WriteFromTo(trace);
     }
   }
 
  private:
-  GrowableArray<RawStackTrace*> objects_;
+  GrowableArray<StackTracePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4116,7 +4152,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawStackTrace* trace = reinterpret_cast<RawStackTrace*>(d->Ref(id));
+      StackTracePtr trace = static_cast<StackTracePtr>(d->Ref(id));
       Deserializer::InitializeHeader(trace, kStackTraceCid,
                                      StackTrace::InstanceSize());
       ReadFromTo(trace);
@@ -4130,8 +4166,8 @@
   RegExpSerializationCluster() : SerializationCluster("RegExp") {}
   ~RegExpSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawRegExp* regexp = RegExp::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    RegExpPtr regexp = RegExp::RawCast(object);
     objects_.Add(regexp);
     PushFromTo(regexp);
   }
@@ -4141,7 +4177,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawRegExp* regexp = objects_[i];
+      RegExpPtr regexp = objects_[i];
       s->AssignRef(regexp);
     }
   }
@@ -4149,7 +4185,7 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawRegExp* regexp = objects_[i];
+      RegExpPtr regexp = objects_[i];
       AutoTraceObject(regexp);
       WriteFromTo(regexp);
       s->Write<int32_t>(regexp->ptr()->num_one_byte_registers_);
@@ -4159,7 +4195,7 @@
   }
 
  private:
-  GrowableArray<RawRegExp*> objects_;
+  GrowableArray<RegExpPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4180,7 +4216,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawRegExp* regexp = reinterpret_cast<RawRegExp*>(d->Ref(id));
+      RegExpPtr regexp = static_cast<RegExpPtr>(d->Ref(id));
       Deserializer::InitializeHeader(regexp, kRegExpCid,
                                      RegExp::InstanceSize());
       ReadFromTo(regexp);
@@ -4197,8 +4233,8 @@
   WeakPropertySerializationCluster() : SerializationCluster("WeakProperty") {}
   ~WeakPropertySerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawWeakProperty* property = WeakProperty::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    WeakPropertyPtr property = WeakProperty::RawCast(object);
     objects_.Add(property);
     PushFromTo(property);
   }
@@ -4208,7 +4244,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawWeakProperty* property = objects_[i];
+      WeakPropertyPtr property = objects_[i];
       s->AssignRef(property);
     }
   }
@@ -4216,14 +4252,14 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawWeakProperty* property = objects_[i];
+      WeakPropertyPtr property = objects_[i];
       AutoTraceObject(property);
       WriteFromTo(property);
     }
   }
 
  private:
-  GrowableArray<RawWeakProperty*> objects_;
+  GrowableArray<WeakPropertyPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4245,8 +4281,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawWeakProperty* property =
-          reinterpret_cast<RawWeakProperty*>(d->Ref(id));
+      WeakPropertyPtr property = static_cast<WeakPropertyPtr>(d->Ref(id));
       Deserializer::InitializeHeader(property, kWeakPropertyCid,
                                      WeakProperty::InstanceSize());
       ReadFromTo(property);
@@ -4260,19 +4295,19 @@
   LinkedHashMapSerializationCluster() : SerializationCluster("LinkedHashMap") {}
   ~LinkedHashMapSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawLinkedHashMap* map = LinkedHashMap::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    LinkedHashMapPtr map = LinkedHashMap::RawCast(object);
     objects_.Add(map);
 
     s->Push(map->ptr()->type_arguments_);
 
     intptr_t used_data = Smi::Value(map->ptr()->used_data_);
-    RawArray* data_array = map->ptr()->data_;
-    RawObject** data_elements = data_array->ptr()->data();
+    ArrayPtr data_array = map->ptr()->data_;
+    ObjectPtr* data_elements = data_array->ptr()->data();
     for (intptr_t i = 0; i < used_data; i += 2) {
-      RawObject* key = data_elements[i];
+      ObjectPtr key = data_elements[i];
       if (key != data_array) {
-        RawObject* value = data_elements[i + 1];
+        ObjectPtr value = data_elements[i + 1];
         s->Push(key);
         s->Push(value);
       }
@@ -4284,7 +4319,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawLinkedHashMap* map = objects_[i];
+      LinkedHashMapPtr map = objects_[i];
       s->AssignRef(map);
     }
   }
@@ -4292,9 +4327,9 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawLinkedHashMap* map = objects_[i];
+      LinkedHashMapPtr map = objects_[i];
       AutoTraceObject(map);
-      s->Write<bool>(map->IsCanonical());
+      s->Write<bool>(map->ptr()->IsCanonical());
 
       WriteField(map, type_arguments_);
 
@@ -4305,12 +4340,12 @@
       // Write out the number of (not deleted) key/value pairs that will follow.
       s->Write<int32_t>((used_data >> 1) - deleted_keys);
 
-      RawArray* data_array = map->ptr()->data_;
-      RawObject** data_elements = data_array->ptr()->data();
+      ArrayPtr data_array = map->ptr()->data_;
+      ObjectPtr* data_elements = data_array->ptr()->data();
       for (intptr_t i = 0; i < used_data; i += 2) {
-        RawObject* key = data_elements[i];
+        ObjectPtr key = data_elements[i];
         if (key != data_array) {
-          RawObject* value = data_elements[i + 1];
+          ObjectPtr value = data_elements[i + 1];
           s->WriteElementRef(key, i);
           s->WriteElementRef(value, i + 1);
         }
@@ -4319,7 +4354,7 @@
   }
 
  private:
-  GrowableArray<RawLinkedHashMap*> objects_;
+  GrowableArray<LinkedHashMapPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4343,13 +4378,12 @@
     PageSpace* old_space = d->heap()->old_space();
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawLinkedHashMap* map = reinterpret_cast<RawLinkedHashMap*>(d->Ref(id));
+      LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d->Ref(id));
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(
           map, kLinkedHashMapCid, LinkedHashMap::InstanceSize(), is_canonical);
 
-      map->ptr()->type_arguments_ =
-          reinterpret_cast<RawTypeArguments*>(d->ReadRef());
+      map->ptr()->type_arguments_ = static_cast<TypeArgumentsPtr>(d->ReadRef());
 
       // TODO(rmacnak): Reserve ref ids and co-allocate in ReadAlloc.
       intptr_t pairs = d->Read<int32_t>();
@@ -4358,7 +4392,7 @@
           Utils::RoundUpToPowerOfTwo(used_data),
           static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
 
-      RawArray* data = reinterpret_cast<RawArray*>(
+      ArrayPtr data = static_cast<ArrayPtr>(
           AllocateUninitialized(old_space, Array::InstanceSize(data_size)));
       data->ptr()->type_arguments_ = TypeArguments::null();
       data->ptr()->length_ = Smi::New(data_size);
@@ -4386,8 +4420,8 @@
       : SerializationCluster("Array"), cid_(cid) {}
   ~ArraySerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawArray* array = Array::RawCast(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    ArrayPtr array = Array::RawCast(object);
     objects_.Add(array);
 
     s->Push(array->ptr()->type_arguments_);
@@ -4402,7 +4436,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawArray* array = objects_[i];
+      ArrayPtr array = objects_[i];
       s->AssignRef(array);
       AutoTraceObject(array);
       const intptr_t length = Smi::Value(array->ptr()->length_);
@@ -4413,11 +4447,11 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawArray* array = objects_[i];
+      ArrayPtr array = objects_[i];
       AutoTraceObject(array);
       const intptr_t length = Smi::Value(array->ptr()->length_);
       s->WriteUnsigned(length);
-      s->Write<bool>(array->IsCanonical());
+      s->Write<bool>(array->ptr()->IsCanonical());
       WriteField(array, type_arguments_);
       for (intptr_t j = 0; j < length; j++) {
         s->WriteElementRef(array->ptr()->data()[j], j);
@@ -4427,7 +4461,7 @@
 
  private:
   intptr_t cid_;
-  GrowableArray<RawArray*> objects_;
+  GrowableArray<ArrayPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4450,13 +4484,13 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
+      ArrayPtr array = static_cast<ArrayPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
                                      is_canonical);
       array->ptr()->type_arguments_ =
-          reinterpret_cast<RawTypeArguments*>(d->ReadRef());
+          static_cast<TypeArgumentsPtr>(d->ReadRef());
       array->ptr()->length_ = Smi::New(length);
       for (intptr_t j = 0; j < length; j++) {
         array->ptr()->data()[j] = d->ReadRef();
@@ -4474,8 +4508,8 @@
   OneByteStringSerializationCluster() : SerializationCluster("OneByteString") {}
   ~OneByteStringSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawOneByteString* str = reinterpret_cast<RawOneByteString*>(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    OneByteStringPtr str = static_cast<OneByteStringPtr>(object);
     objects_.Add(str);
   }
 
@@ -4484,7 +4518,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawOneByteString* str = objects_[i];
+      OneByteStringPtr str = objects_[i];
       s->AssignRef(str);
       AutoTraceObject(str);
       const intptr_t length = Smi::Value(str->ptr()->length_);
@@ -4495,11 +4529,11 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawOneByteString* str = objects_[i];
+      OneByteStringPtr str = objects_[i];
       AutoTraceObject(str);
       const intptr_t length = Smi::Value(str->ptr()->length_);
       s->WriteUnsigned(length);
-      s->Write<bool>(str->IsCanonical());
+      s->Write<bool>(str->ptr()->IsCanonical());
       intptr_t hash = String::GetCachedHash(str);
       s->Write<int32_t>(hash);
       s->WriteBytes(str->ptr()->data(), length);
@@ -4507,7 +4541,7 @@
   }
 
  private:
-  GrowableArray<RawOneByteString*> objects_;
+  GrowableArray<OneByteStringPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4530,7 +4564,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
+      OneByteStringPtr str = static_cast<OneByteStringPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(str, kOneByteStringCid,
@@ -4551,8 +4585,8 @@
   TwoByteStringSerializationCluster() : SerializationCluster("TwoByteString") {}
   ~TwoByteStringSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) {
-    RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(object);
+  void Trace(Serializer* s, ObjectPtr object) {
+    TwoByteStringPtr str = static_cast<TwoByteStringPtr>(object);
     objects_.Add(str);
   }
 
@@ -4561,7 +4595,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
-      RawTwoByteString* str = objects_[i];
+      TwoByteStringPtr str = objects_[i];
       s->AssignRef(str);
       AutoTraceObject(str);
       const intptr_t length = Smi::Value(str->ptr()->length_);
@@ -4572,11 +4606,11 @@
   void WriteFill(Serializer* s) {
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      RawTwoByteString* str = objects_[i];
+      TwoByteStringPtr str = objects_[i];
       AutoTraceObject(str);
       const intptr_t length = Smi::Value(str->ptr()->length_);
       s->WriteUnsigned(length);
-      s->Write<bool>(str->IsCanonical());
+      s->Write<bool>(str->ptr()->IsCanonical());
       intptr_t hash = String::GetCachedHash(str);
       s->Write<int32_t>(hash);
       s->WriteBytes(reinterpret_cast<uint8_t*>(str->ptr()->data()), length * 2);
@@ -4584,7 +4618,7 @@
   }
 
  private:
-  GrowableArray<RawTwoByteString*> objects_;
+  GrowableArray<TwoByteStringPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -4607,7 +4641,7 @@
 
   void ReadFill(Deserializer* d) {
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
+      TwoByteStringPtr str = static_cast<TwoByteStringPtr>(d->Ref(id));
       const intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(str, kTwoByteStringCid,
@@ -4633,7 +4667,7 @@
   }
   ~FakeSerializationCluster() {}
 
-  void Trace(Serializer* s, RawObject* object) { UNREACHABLE(); }
+  void Trace(Serializer* s, ObjectPtr object) { UNREACHABLE(); }
   void WriteAlloc(Serializer* s) { UNREACHABLE(); }
   void WriteFill(Serializer* s) { UNREACHABLE(); }
 };
@@ -4691,8 +4725,8 @@
 }
 
 void Serializer::TraceStartWritingObject(const char* type,
-                                         RawObject* obj,
-                                         RawString* name) {
+                                         ObjectPtr obj,
+                                         StringPtr name) {
   if (profile_writer_ == nullptr) return;
 
   intptr_t cid = -1;
@@ -4758,13 +4792,13 @@
     Push(isolate()->class_table()->At(cid));
     return new (Z) InstanceSerializationCluster(cid);
   }
-  if (RawObject::IsTypedDataViewClassId(cid)) {
+  if (IsTypedDataViewClassId(cid)) {
     return new (Z) TypedDataViewSerializationCluster(cid);
   }
-  if (RawObject::IsExternalTypedDataClassId(cid)) {
+  if (IsExternalTypedDataClassId(cid)) {
     return new (Z) ExternalTypedDataSerializationCluster(cid);
   }
-  if (RawObject::IsTypedDataClassId(cid)) {
+  if (IsTypedDataClassId(cid)) {
     return new (Z) TypedDataSerializationCluster(cid);
   }
 
@@ -4878,9 +4912,9 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-void Serializer::WriteInstructions(RawInstructions* instr,
+void Serializer::WriteInstructions(InstructionsPtr instr,
                                    uint32_t unchecked_offset,
-                                   RawCode* code,
+                                   CodePtr code,
                                    intptr_t index) {
   ASSERT(code != Code::null());
 
@@ -4960,7 +4994,7 @@
   }
 }
 
-uint32_t Serializer::GetDataOffset(RawObject* object) const {
+uint32_t Serializer::GetDataOffset(ObjectPtr object) const {
   return image_writer_->GetDataOffsetFor(object);
 }
 
@@ -4971,9 +5005,9 @@
   return image_writer_->data_size();
 }
 
-void Serializer::Push(RawObject* object) {
+void Serializer::Push(ObjectPtr object) {
   if (!object->IsHeapObject()) {
-    RawSmi* smi = Smi::RawCast(object);
+    SmiPtr smi = Smi::RawCast(object);
     if (smi_ids_.Lookup(smi) == NULL) {
       SmiObjectIdPair pair;
       pair.smi_ = smi;
@@ -5016,7 +5050,7 @@
   }
 }
 
-void Serializer::Trace(RawObject* object) {
+void Serializer::Trace(ObjectPtr object) {
   intptr_t cid;
   if (!object->IsHeapObject()) {
     // Smis are merged into the Mint cluster because Smis for the writer might
@@ -5047,27 +5081,27 @@
 #endif
 }
 
-void Serializer::UnexpectedObject(RawObject* raw_object, const char* message) {
+void Serializer::UnexpectedObject(ObjectPtr raw_object, const char* message) {
   // Exit the no safepoint scope so we can allocate while printing.
   while (thread()->no_safepoint_scope_depth() > 0) {
     thread()->DecrementNoSafepointScopeDepth();
   }
   Object& object = Object::Handle(raw_object);
   OS::PrintErr("Unexpected object (%s, %s): 0x%" Px " %s\n", message,
-               Snapshot::KindToCString(kind_),
-               reinterpret_cast<uword>(object.raw()), object.ToCString());
+               Snapshot::KindToCString(kind_), static_cast<uword>(object.raw()),
+               object.ToCString());
 #if defined(SNAPSHOT_BACKTRACE)
   while (!object.IsNull()) {
     object = ParentOf(object);
     OS::PrintErr("referenced by 0x%" Px " %s\n",
-                 reinterpret_cast<uword>(object.raw()), object.ToCString());
+                 static_cast<uword>(object.raw()), object.ToCString());
   }
 #endif
   OS::Abort();
 }
 
 #if defined(SNAPSHOT_BACKTRACE)
-RawObject* Serializer::ParentOf(const Object& object) {
+ObjectPtr Serializer::ParentOf(const Object& object) {
   for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
     if (parent_pairs_[i]->raw() == object.raw()) {
       return parent_pairs_[i + 1]->raw();
@@ -5122,18 +5156,18 @@
     // We permute the code objects in the [CodeSerializationCluster] so they
     // will arrive in the order in which the [Code]'s instructions will be in
     // memory at AOT runtime.
-    GrowableArray<RawCode*> code_order;
+    GrowableArray<CodePtr> code_order;
     RawCodeSet code_set;
     for (auto& command : writer_commands) {
       if (command.op == ImageWriterCommand::InsertInstructionOfCode) {
-        RawCode* code = command.insert_instruction_of_code.code;
+        CodePtr code = command.insert_instruction_of_code.code;
         ASSERT(!code_set.HasKey(code));
         code_set.Insert(code);
         code_order.Add(code);
         code_order_length++;
       }
     }
-    for (RawCode* code : *code_objects) {
+    for (CodePtr code : *code_objects) {
       if (!code_set.HasKey(code)) {
         code_set.Insert(code);
         code_order.Add(code);
@@ -5270,8 +5304,8 @@
   ASSERT(first_code_id <= compiler::target::kWordMax);
   WriteUnsigned(first_code_id);
 
-  RawCode* previous_code = nullptr;
-  RawCode* recent[kDispatchTableRecentCount] = {nullptr};
+  CodePtr previous_code = nullptr;
+  CodePtr recent[kDispatchTableRecentCount] = {nullptr};
   intptr_t recent_index = 0;
   intptr_t repeat_count = 0;
   for (intptr_t i = 0; i < table_length; i++) {
@@ -5394,7 +5428,6 @@
   AddBaseObject(Object::zero_array().raw(), "Array", "<zero_array>");
   AddBaseObject(Object::dynamic_type().raw(), "Type", "<dynamic type>");
   AddBaseObject(Object::void_type().raw(), "Type", "<void type>");
-  AddBaseObject(Object::never_type().raw(), "Type", "<never type>");
   AddBaseObject(Object::empty_type_arguments().raw(), "TypeArguments", "[]");
   AddBaseObject(Bool::True().raw(), "bool", "true");
   AddBaseObject(Bool::False().raw(), "bool", "false");
@@ -5440,15 +5473,14 @@
 
   ClassTable* table = isolate()->class_table();
   for (intptr_t cid = kClassCid; cid < kInstanceCid; cid++) {
-    // Error has no class object.
-    if (cid != kErrorCid) {
+    // Error, CallSiteData has no class object.
+    if (cid != kErrorCid && cid != kCallSiteDataCid) {
       ASSERT(table->HasValidClassAt(cid));
       AddBaseObject(table->At(cid), "Class");
     }
   }
   AddBaseObject(table->At(kDynamicCid), "Class");
   AddBaseObject(table->At(kVoidCid), "Class");
-  AddBaseObject(table->At(kNeverCid), "Class");
 
   if (!Snapshot::IncludesCode(kind_)) {
     for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
@@ -5502,7 +5534,7 @@
 #undef DECLARE_OBJECT_STORE_FIELD
 };
 
-void Serializer::WriteIsolateSnapshot(intptr_t num_base_objects,
+void Serializer::WriteProgramSnapshot(intptr_t num_base_objects,
                                       ObjectStore* object_store) {
   NoSafepointScope no_safepoint;
 
@@ -5513,15 +5545,15 @@
       AddBaseObject(base_objects.At(i));
     }
   } else {
-    // Base objects carried over from WriteVMIsolateSnapshot.
+    // Base objects carried over from WriteVMSnapshot.
     num_base_objects_ += num_base_objects;
     next_ref_index_ += num_base_objects;
   }
 
   // Push roots.
-  RawObject** from = object_store->from();
-  RawObject** to = object_store->to_snapshot(kind_);
-  for (RawObject** p = from; p <= to; p++) {
+  ObjectPtr* from = object_store->from();
+  ObjectPtr* to = object_store->to_snapshot(kind_);
+  for (ObjectPtr* p = from; p <= to; p++) {
     Push(*p);
   }
 
@@ -5545,7 +5577,7 @@
   Serialize();
 
   // Write roots.
-  for (RawObject** p = from; p <= to; p++) {
+  for (ObjectPtr* p = from; p <= to; p++) {
     WriteRootRef(*p, kObjectStoreFieldNames[p - from]);
   }
 
@@ -5602,7 +5634,7 @@
       kind_(kind),
       stream_(buffer, size),
       image_reader_(NULL),
-      refs_(NULL),
+      refs_(nullptr),
       next_ref_index_(1),
       clusters_(NULL),
       field_table_(thread->isolate()->field_table()) {
@@ -5624,13 +5656,13 @@
   if (cid >= kNumPredefinedCids || cid == kInstanceCid) {
     return new (Z) InstanceDeserializationCluster(cid);
   }
-  if (RawObject::IsTypedDataViewClassId(cid)) {
+  if (IsTypedDataViewClassId(cid)) {
     return new (Z) TypedDataViewDeserializationCluster(cid);
   }
-  if (RawObject::IsExternalTypedDataClassId(cid)) {
+  if (IsExternalTypedDataClassId(cid)) {
     return new (Z) ExternalTypedDataDeserializationCluster(cid);
   }
-  if (RawObject::IsTypedDataClassId(cid)) {
+  if (IsTypedDataClassId(cid)) {
     return new (Z) TypedDataDeserializationCluster(cid);
   }
 
@@ -5794,11 +5826,11 @@
   }
   ASSERT(repeat_count == 0);
 
-  I->set_dispatch_table(table);
+  I->group()->set_dispatch_table(table);
 #endif
 }
 
-RawApiError* Deserializer::VerifyImageAlignment() {
+ApiErrorPtr Deserializer::VerifyImageAlignment() {
   if (image_reader_ != nullptr) {
     return image_reader_->VerifyAlignment();
   }
@@ -5903,7 +5935,7 @@
   return strdup(message);
 }
 
-RawApiError* FullSnapshotReader::ConvertToApiError(char* message) {
+ApiErrorPtr FullSnapshotReader::ConvertToApiError(char* message) {
   // This can also fail while bringing up the VM isolate, so make sure to
   // allocate the error message in old space.
   const String& msg = String::Handle(String::New(message, Heap::kOld));
@@ -5914,7 +5946,7 @@
   return ApiError::New(msg, Heap::kOld);
 }
 
-void Deserializer::ReadInstructions(RawCode* code,
+void Deserializer::ReadInstructions(CodePtr code,
                                     intptr_t index,
                                     intptr_t start_index) {
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -5929,7 +5961,7 @@
       // object. Thus, retrieve the instructions-related information from there.
       ASSERT((index - start_index) >= code_order_length());
       const uint32_t source_id = (bare_offset >> 1) + start_index;
-      auto const source = reinterpret_cast<RawCode*>(Ref(source_id));
+      auto const source = static_cast<CodePtr>(Ref(source_id));
       code->ptr()->entry_point_ = source->ptr()->entry_point_;
       code->ptr()->unchecked_entry_point_ =
           source->ptr()->unchecked_entry_point_;
@@ -5971,7 +6003,7 @@
     ASSERT((index - start_index) < code_order_length());
     const uword curr_payload_start = Code::PayloadStartOf(code);
     if (index > start_index) {
-      auto const prev = reinterpret_cast<RawCode*>(Ref(index - 1));
+      auto const prev = static_cast<CodePtr>(Ref(index - 1));
       const uword prev_payload_start = Code::PayloadStartOf(prev);
       prev->ptr()->instructions_length_ =
           curr_payload_start - prev_payload_start;
@@ -5988,7 +6020,7 @@
 #endif
 
   const uint32_t offset = Read<uint32_t>();
-  RawInstructions* instr = image_reader_->GetInstructionsAt(offset);
+  InstructionsPtr instr = image_reader_->GetInstructionsAt(offset);
   uint32_t unchecked_offset = ReadUnsigned();
 
   code->ptr()->instructions_ = instr;
@@ -6006,7 +6038,7 @@
   Code::InitializeCachedEntryPointsFrom(code, instr, unchecked_offset);
 }
 
-RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
+ObjectPtr Deserializer::GetObjectAt(uint32_t offset) const {
   return image_reader_->GetObjectAt(offset);
 }
 
@@ -6056,13 +6088,16 @@
 class HeapLocker : public StackResource {
  public:
   HeapLocker(Thread* thread, PageSpace* page_space)
-      : StackResource(thread), page_space_(page_space) {
-    page_space_->AcquireDataLock();
+      : StackResource(thread),
+        page_space_(page_space),
+        freelist_(page_space->DataFreeList()) {
+    page_space_->AcquireLock(freelist_);
   }
-  ~HeapLocker() { page_space_->ReleaseDataLock(); }
+  ~HeapLocker() { page_space_->ReleaseLock(freelist_); }
 
  private:
   PageSpace* page_space_;
+  FreeList* freelist_;
 };
 
 void Deserializer::AddVMIsolateBaseObjects() {
@@ -6076,7 +6111,6 @@
   AddBaseObject(Object::zero_array().raw());
   AddBaseObject(Object::dynamic_type().raw());
   AddBaseObject(Object::void_type().raw());
-  AddBaseObject(Object::never_type().raw());
   AddBaseObject(Object::empty_type_arguments().raw());
   AddBaseObject(Bool::True().raw());
   AddBaseObject(Bool::False().raw());
@@ -6107,15 +6141,14 @@
 
   ClassTable* table = isolate()->class_table();
   for (intptr_t cid = kClassCid; cid <= kUnwindErrorCid; cid++) {
-    // Error has no class object.
-    if (cid != kErrorCid) {
+    // Error, CallSiteData has no class object.
+    if (cid != kErrorCid && cid != kCallSiteDataCid) {
       ASSERT(table->HasValidClassAt(cid));
       AddBaseObject(table->At(cid));
     }
   }
   AddBaseObject(table->At(kDynamicCid));
   AddBaseObject(table->At(kVoidCid));
-  AddBaseObject(table->At(kNeverCid));
 
   if (!Snapshot::IncludesCode(kind_)) {
     for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
@@ -6174,7 +6207,7 @@
   }
 }
 
-void Deserializer::ReadIsolateSnapshot(ObjectStore* object_store) {
+void Deserializer::ReadProgramSnapshot(ObjectStore* object_store) {
   Array& refs = Array::Handle();
   Prepare();
 
@@ -6191,9 +6224,9 @@
     Deserialize();
 
     // Read roots.
-    RawObject** from = object_store->from();
-    RawObject** to = object_store->to_snapshot(kind_);
-    for (RawObject** p = from; p <= to; p++) {
+    ObjectPtr* from = object_store->from();
+    ObjectPtr* to = object_store->to_snapshot(kind_);
+    for (ObjectPtr* p = from; p <= to; p++) {
       *p = ReadRef();
     }
 
@@ -6212,8 +6245,8 @@
   thread()->isolate()->class_table()->CopySizesFromClassObjects();
   heap_->old_space()->EvaluateAfterLoading();
 
-#if defined(DEBUG)
   Isolate* isolate = thread()->isolate();
+#if defined(DEBUG)
   isolate->ValidateClassTable();
   isolate->heap()->Verify();
 #endif
@@ -6221,13 +6254,12 @@
   for (intptr_t i = 0; i < num_clusters_; i++) {
     clusters_[i]->PostLoad(refs, kind_, zone_);
   }
-  object_store->PostLoad();
+  isolate->isolate_object_store()->PreallocateObjects();
 
   // Setup native resolver for bootstrap impl.
   Bootstrap::SetupNativeResolver();
 }
 
-
 #if !defined(DART_PRECOMPILED_RUNTIME)
 FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
                                        uint8_t** vm_snapshot_data_buffer,
@@ -6302,8 +6334,8 @@
   return num_objects;
 }
 
-void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
-  TIMELINE_DURATION(thread(), Isolate, "WriteIsolateSnapshot");
+void FullSnapshotWriter::WriteProgramSnapshot(intptr_t num_base_objects) {
+  TIMELINE_DURATION(thread(), Isolate, "WriteProgramSnapshot");
 
   Serializer serializer(thread(), kind_, isolate_snapshot_data_buffer_, alloc_,
                         kInitialSize, isolate_image_writer_, /*vm=*/false,
@@ -6312,17 +6344,17 @@
   ASSERT(object_store != NULL);
 
   // These type arguments must always be retained.
-  ASSERT(object_store->type_argument_int()->IsCanonical());
-  ASSERT(object_store->type_argument_double()->IsCanonical());
-  ASSERT(object_store->type_argument_string()->IsCanonical());
-  ASSERT(object_store->type_argument_string_dynamic()->IsCanonical());
-  ASSERT(object_store->type_argument_string_string()->IsCanonical());
+  ASSERT(object_store->type_argument_int()->ptr()->IsCanonical());
+  ASSERT(object_store->type_argument_double()->ptr()->IsCanonical());
+  ASSERT(object_store->type_argument_string()->ptr()->IsCanonical());
+  ASSERT(object_store->type_argument_string_dynamic()->ptr()->IsCanonical());
+  ASSERT(object_store->type_argument_string_string()->ptr()->IsCanonical());
 
   serializer.ReserveHeader();
   serializer.WriteVersionAndFeatures(false);
   // Isolate snapshot roots are:
   // - the object store
-  serializer.WriteIsolateSnapshot(num_base_objects, object_store);
+  serializer.WriteProgramSnapshot(num_base_objects, object_store);
   serializer.FillHeader(serializer.kind());
   clustered_isolate_size_ = serializer.bytes_written();
 
@@ -6353,7 +6385,7 @@
   }
 
   if (isolate_snapshot_data_buffer() != NULL) {
-    WriteIsolateSnapshot(num_base_objects);
+    WriteProgramSnapshot(num_base_objects);
   }
 
   if (FLAG_print_snapshot_sizes) {
@@ -6485,7 +6517,7 @@
   return nullptr;
 }
 
-RawApiError* FullSnapshotReader::ReadVMSnapshot() {
+ApiErrorPtr FullSnapshotReader::ReadVMSnapshot() {
   SnapshotHeaderReader header_reader(kind_, buffer_, size_);
 
   intptr_t offset = 0;
@@ -6497,7 +6529,7 @@
 
   Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
                             instructions_image_, offset);
-  RawApiError* api_error = deserializer.VerifyImageAlignment();
+  ApiErrorPtr api_error = deserializer.VerifyImageAlignment();
   if (api_error != ApiError::null()) {
     return api_error;
   }
@@ -6516,7 +6548,7 @@
   return ApiError::null();
 }
 
-RawApiError* FullSnapshotReader::ReadIsolateSnapshot() {
+ApiErrorPtr FullSnapshotReader::ReadProgramSnapshot() {
   SnapshotHeaderReader header_reader(kind_, buffer_, size_);
   intptr_t offset = 0;
   char* error =
@@ -6527,7 +6559,7 @@
 
   Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
                             instructions_image_, offset);
-  RawApiError* api_error = deserializer.VerifyImageAlignment();
+  ApiErrorPtr api_error = deserializer.VerifyImageAlignment();
   if (api_error != ApiError::null()) {
     return api_error;
   }
@@ -6542,13 +6574,13 @@
   }
 
   auto object_store = thread_->isolate()->object_store();
-  deserializer.ReadIsolateSnapshot(object_store);
+  deserializer.ReadProgramSnapshot(object_store);
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   if (FLAG_use_bare_instructions) {
     // By default, every switchable call site will put (ic_data, code) into the
     // object pool.  The [code] is initialized (at AOT compile-time) to be a
-    // [StubCode::UnlinkedCall].
+    // [StubCode::SwitchableCallMiss].
     //
     // In --use-bare-instruction we reduce the extra indirection via the [code]
     // object and store instead (ic_data, entrypoint) in the object pool.
@@ -6563,9 +6595,15 @@
     for (intptr_t i = 0; i < pool.Length(); i++) {
       if (pool.TypeAt(i) == ObjectPool::EntryType::kTaggedObject) {
         entry = pool.ObjectAt(i);
-        if (entry.raw() == StubCode::UnlinkedCall().raw()) {
+        if (entry.raw() == StubCode::SwitchableCallMiss().raw()) {
           smi = Smi::FromAlignedAddress(
-              StubCode::UnlinkedCall().MonomorphicEntryPoint());
+              StubCode::SwitchableCallMiss().MonomorphicEntryPoint());
+          pool.SetTypeAt(i, ObjectPool::EntryType::kImmediate,
+                         ObjectPool::Patchability::kPatchable);
+          pool.SetObjectAt(i, smi);
+        } else if (entry.raw() == StubCode::MegamorphicCall().raw()) {
+          smi = Smi::FromAlignedAddress(
+              StubCode::MegamorphicCall().MonomorphicEntryPoint());
           pool.SetTypeAt(i, ObjectPool::EntryType::kImmediate,
                          ObjectPool::Patchability::kPatchable);
           pool.SetObjectAt(i, smi);
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index 791c1cf..d9d4123 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -57,7 +57,7 @@
   virtual ~SerializationCluster() {}
 
   // Add [object] to the cluster and push its outgoing references.
-  virtual void Trace(Serializer* serializer, RawObject* object) = 0;
+  virtual void Trace(Serializer* serializer, ObjectPtr object) = 0;
 
   // Write the cluster type and information needed to allocate the cluster's
   // objects. For fixed sized objects, this is just the object count. For
@@ -104,8 +104,8 @@
 
 class SmiObjectIdPair {
  public:
-  SmiObjectIdPair() : smi_(NULL), id_(0) {}
-  RawSmi* smi_;
+  SmiObjectIdPair() : smi_(nullptr), id_(0) {}
+  SmiPtr smi_;
   intptr_t id_;
 
   bool operator==(const SmiObjectIdPair& other) const {
@@ -115,7 +115,7 @@
 
 class SmiObjectIdPairTrait {
  public:
-  typedef RawSmi* Key;
+  typedef SmiPtr Key;
   typedef intptr_t Value;
   typedef SmiObjectIdPair Pair;
 
@@ -157,12 +157,12 @@
   }
 
   intptr_t WriteVMSnapshot(const Array& symbols);
-  void WriteIsolateSnapshot(intptr_t num_base_objects,
+  void WriteProgramSnapshot(intptr_t num_base_objects,
                             ObjectStore* object_store);
 
   void AddVMIsolateBaseObjects();
 
-  void AddBaseObject(RawObject* base_object,
+  void AddBaseObject(ObjectPtr base_object,
                      const char* type = nullptr,
                      const char* name = nullptr) {
     intptr_t ref = AssignRef(base_object);
@@ -181,7 +181,7 @@
     }
   }
 
-  intptr_t AssignRef(RawObject* object) {
+  intptr_t AssignRef(ObjectPtr object) {
     ASSERT(IsAllocatedReference(next_ref_index_));
     if (object->IsHeapObject()) {
       // The object id weak table holds image offsets for Instructions instead
@@ -190,7 +190,7 @@
       heap_->SetObjectId(object, next_ref_index_);
       ASSERT(heap_->GetObjectId(object) == next_ref_index_);
     } else {
-      RawSmi* smi = Smi::RawCast(object);
+      SmiPtr smi = Smi::RawCast(object);
       SmiObjectIdPair* existing_pair = smi_ids_.Lookup(smi);
       if (existing_pair != NULL) {
         ASSERT(existing_pair->id_ == kUnallocatedReference);
@@ -205,15 +205,15 @@
     return next_ref_index_++;
   }
 
-  void Push(RawObject* object);
+  void Push(ObjectPtr object);
 
   void AddUntracedRef() { num_written_objects_++; }
 
-  void Trace(RawObject* object);
+  void Trace(ObjectPtr object);
 
-  void UnexpectedObject(RawObject* object, const char* message);
+  void UnexpectedObject(ObjectPtr object, const char* message);
 #if defined(SNAPSHOT_BACKTRACE)
-  RawObject* ParentOf(const Object& object);
+  ObjectPtr ParentOf(const Object& object);
 #endif
 
   SerializationCluster* NewClusterForClass(intptr_t cid);
@@ -240,9 +240,7 @@
   WriteStream* stream() { return &stream_; }
   intptr_t bytes_written() { return stream_.bytes_written(); }
 
-  void TraceStartWritingObject(const char* type,
-                               RawObject* obj,
-                               RawString* name);
+  void TraceStartWritingObject(const char* type, ObjectPtr obj, StringPtr name);
   void TraceEndWritingObject();
 
   // Writes raw data to the stream (basic type).
@@ -263,7 +261,7 @@
   }
   void Align(intptr_t alignment) { stream_.Align(alignment); }
 
-  void WriteRootRef(RawObject* object, const char* name = nullptr) {
+  void WriteRootRef(ObjectPtr object, const char* name = nullptr) {
     intptr_t id = WriteRefId(object);
     WriteUnsigned(id);
     if (profile_writer_ != nullptr) {
@@ -271,7 +269,7 @@
     }
   }
 
-  void WriteElementRef(RawObject* object, intptr_t index) {
+  void WriteElementRef(ObjectPtr object, intptr_t index) {
     intptr_t id = WriteRefId(object);
     WriteUnsigned(id);
     if (profile_writer_ != nullptr) {
@@ -289,7 +287,7 @@
   // explicitly connected in the heap, for example an object referenced
   // by the global object pool is in reality referenced by the code which
   // caused this reference to be added to the global object pool.
-  void AttributeElementRef(RawObject* object, intptr_t index) {
+  void AttributeElementRef(ObjectPtr object, intptr_t index) {
     intptr_t id = WriteRefId(object);
     if (profile_writer_ != nullptr) {
       profile_writer_->AttributeReferenceTo(
@@ -300,7 +298,7 @@
     }
   }
 
-  void WritePropertyRef(RawObject* object, const char* property) {
+  void WritePropertyRef(ObjectPtr object, const char* property) {
     intptr_t id = WriteRefId(object);
     WriteUnsigned(id);
     if (profile_writer_ != nullptr) {
@@ -312,7 +310,7 @@
     }
   }
 
-  void WriteOffsetRef(RawObject* object, intptr_t offset) {
+  void WriteOffsetRef(ObjectPtr object, intptr_t offset) {
     intptr_t id = WriteRefId(object);
     WriteUnsigned(id);
     if (profile_writer_ != nullptr) {
@@ -335,20 +333,20 @@
   }
 
   template <typename T, typename... P>
-  void WriteFromTo(T* obj, P&&... args) {
-    RawObject** from = obj->from();
-    RawObject** to = obj->to_snapshot(kind(), args...);
-    for (RawObject** p = from; p <= to; p++) {
-      WriteOffsetRef(*p, (p - reinterpret_cast<RawObject**>(obj->ptr())) *
-                             sizeof(RawObject*));
+  void WriteFromTo(T obj, P&&... args) {
+    ObjectPtr* from = obj->ptr()->from();
+    ObjectPtr* to = obj->ptr()->to_snapshot(kind(), args...);
+    for (ObjectPtr* p = from; p <= to; p++) {
+      WriteOffsetRef(*p, (p - reinterpret_cast<ObjectPtr*>(obj->ptr())) *
+                             sizeof(ObjectPtr));
     }
   }
 
   template <typename T, typename... P>
-  void PushFromTo(T* obj, P&&... args) {
-    RawObject** from = obj->from();
-    RawObject** to = obj->to_snapshot(kind(), args...);
-    for (RawObject** p = from; p <= to; p++) {
+  void PushFromTo(T obj, P&&... args) {
+    ObjectPtr* from = obj->ptr()->from();
+    ObjectPtr* to = obj->ptr()->to_snapshot(kind(), args...);
+    for (ObjectPtr* p = from; p <= to; p++) {
       Push(*p);
     }
   }
@@ -358,15 +356,15 @@
   }
 
   void WriteCid(intptr_t cid) {
-    COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32);
+    COMPILE_ASSERT(ObjectLayout::kClassIdTagSize <= 32);
     Write<int32_t>(cid);
   }
 
-  void WriteInstructions(RawInstructions* instr,
+  void WriteInstructions(InstructionsPtr instr,
                          uint32_t unchecked_offset,
-                         RawCode* code,
+                         CodePtr code,
                          intptr_t index);
-  uint32_t GetDataOffset(RawObject* object) const;
+  uint32_t GetDataOffset(ObjectPtr object) const;
   void TraceDataOffset(uint32_t offset);
   intptr_t GetDataSize() const;
 
@@ -383,9 +381,9 @@
   // Returns the reference ID for the object. Fails for objects that have not
   // been allocated a reference ID yet, so should be used only after all
   // WriteAlloc calls.
-  intptr_t WriteRefId(RawObject* object) {
+  intptr_t WriteRefId(ObjectPtr object) {
     if (!object->IsHeapObject()) {
-      RawSmi* smi = Smi::RawCast(object);
+      SmiPtr smi = Smi::RawCast(object);
       auto const id = smi_ids_.Lookup(smi)->id_;
       if (IsAllocatedReference(id)) return id;
       FATAL("Missing ref");
@@ -423,7 +421,7 @@
   WriteStream stream_;
   ImageWriter* image_writer_;
   SerializationCluster** clusters_by_cid_;
-  GrowableArray<RawObject*> stack_;
+  GrowableArray<ObjectPtr> stack_;
   intptr_t num_cids_;
   intptr_t num_base_objects_;
   intptr_t num_written_objects_;
@@ -438,7 +436,7 @@
 
   V8SnapshotProfileWriter* profile_writer_ = nullptr;
   struct ProfilingObject {
-    RawObject* object_ = nullptr;
+    ObjectPtr object_ = nullptr;
     intptr_t id_ = 0;
     intptr_t stream_start_ = 0;
     intptr_t cid_ = -1;
@@ -446,7 +444,7 @@
   OffsetsTable* offsets_table_ = nullptr;
 
 #if defined(SNAPSHOT_BACKTRACE)
-  RawObject* current_parent_;
+  ObjectPtr current_parent_;
   GrowableArray<Object*> parent_pairs_;
 #endif
 
@@ -474,8 +472,8 @@
 struct SerializerWritingObjectScope {
   SerializerWritingObjectScope(Serializer* serializer,
                                const char* type,
-                               RawObject* object,
-                               RawString* name)
+                               ObjectPtr object,
+                               StringPtr name)
       : serializer_(serializer) {
     serializer_->TraceStartWritingObject(type, object, name);
   }
@@ -537,14 +535,14 @@
   //
   // Returns ApiError::null() on success and an ApiError with an an appropriate
   // message otherwise.
-  RawApiError* VerifyImageAlignment();
+  ApiErrorPtr VerifyImageAlignment();
 
-  void ReadIsolateSnapshot(ObjectStore* object_store);
+  void ReadProgramSnapshot(ObjectStore* object_store);
   void ReadVMSnapshot();
 
   void AddVMIsolateBaseObjects();
 
-  static void InitializeHeader(RawObject* raw,
+  static void InitializeHeader(ObjectPtr raw,
                                intptr_t cid,
                                intptr_t size,
                                bool is_canonical = false);
@@ -568,35 +566,35 @@
   void Advance(intptr_t value) { stream_.Advance(value); }
   void Align(intptr_t alignment) { stream_.Align(alignment); }
 
-  void AddBaseObject(RawObject* base_object) { AssignRef(base_object); }
+  void AddBaseObject(ObjectPtr base_object) { AssignRef(base_object); }
 
-  void AssignRef(RawObject* object) {
+  void AssignRef(ObjectPtr object) {
     ASSERT(next_ref_index_ <= num_objects_);
     refs_->ptr()->data()[next_ref_index_] = object;
     next_ref_index_++;
   }
 
-  RawObject* Ref(intptr_t index) const {
+  ObjectPtr Ref(intptr_t index) const {
     ASSERT(index > 0);
     ASSERT(index <= num_objects_);
     return refs_->ptr()->data()[index];
   }
 
-  RawObject* ReadRef() { return Ref(ReadUnsigned()); }
+  ObjectPtr ReadRef() { return Ref(ReadUnsigned()); }
 
   template <typename T, typename... P>
-  void ReadFromTo(T* obj, P&&... params) {
-    RawObject** from = obj->from();
-    RawObject** to_snapshot = obj->to_snapshot(kind(), params...);
-    RawObject** to = obj->to(params...);
-    for (RawObject** p = from; p <= to_snapshot; p++) {
+  void ReadFromTo(T obj, P&&... params) {
+    ObjectPtr* from = obj->ptr()->from();
+    ObjectPtr* to_snapshot = obj->ptr()->to_snapshot(kind(), params...);
+    ObjectPtr* to = obj->ptr()->to(params...);
+    for (ObjectPtr* 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 (RawObject** p = to_snapshot + 1; p <= to; p++) {
+    for (ObjectPtr* p = to_snapshot + 1; p <= to; p++) {
       *p = Object::null();
     }
   }
@@ -606,12 +604,12 @@
   }
 
   intptr_t ReadCid() {
-    COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32);
+    COMPILE_ASSERT(ObjectLayout::kClassIdTagSize <= 32);
     return Read<int32_t>();
   }
 
-  void ReadInstructions(RawCode* code, intptr_t index, intptr_t start_index);
-  RawObject* GetObjectAt(uint32_t offset) const;
+  void ReadInstructions(CodePtr code, intptr_t index, intptr_t start_index);
+  ObjectPtr GetObjectAt(uint32_t offset) const;
 
   void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); }
 
@@ -652,7 +650,7 @@
   intptr_t num_objects_;
   intptr_t num_clusters_;
   intptr_t code_order_length_ = 0;
-  RawArray* refs_;
+  ArrayPtr refs_;
   intptr_t next_ref_index_;
   DeserializationCluster** clusters_;
   FieldTable* field_table_;
@@ -682,7 +680,7 @@
   Isolate* isolate() const { return thread_->isolate(); }
   Heap* heap() const { return isolate()->heap(); }
 
-  // Writes a full snapshot of the Isolate.
+  // Writes a full snapshot of the program(VM isolate, regular isolate group).
   void WriteFullSnapshot();
 
   intptr_t VmIsolateSnapshotSize() const { return vm_isolate_snapshot_size_; }
@@ -692,8 +690,8 @@
   // Writes a snapshot of the VM Isolate.
   intptr_t WriteVMSnapshot();
 
-  // Writes a full snapshot of a regular Dart Isolate.
-  void WriteIsolateSnapshot(intptr_t num_base_objects);
+  // Writes a full snapshot of regular Dart isolate group.
+  void WriteProgramSnapshot(intptr_t num_base_objects);
 
   Thread* thread_;
   Snapshot::Kind kind_;
@@ -723,11 +721,11 @@
                      Thread* thread);
   ~FullSnapshotReader() {}
 
-  RawApiError* ReadVMSnapshot();
-  RawApiError* ReadIsolateSnapshot();
+  ApiErrorPtr ReadVMSnapshot();
+  ApiErrorPtr ReadProgramSnapshot();
 
  private:
-  RawApiError* ConvertToApiError(char* message);
+  ApiErrorPtr ConvertToApiError(char* message);
 
   Snapshot::Kind kind_;
   Thread* thread_;
diff --git a/runtime/vm/code_comments.cc b/runtime/vm/code_comments.cc
index 74f8458..d1344d3 100644
--- a/runtime/vm/code_comments.cc
+++ b/runtime/vm/code_comments.cc
@@ -1,14 +1,13 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+#if !defined(DART_PRECOMPILED_RUNTIME) &&                                      \
+    (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
 
 #include "vm/code_comments.h"
 
 namespace dart {
 
-#if !defined(DART_PRECOMPILED_RUNTIME) &&                                      \
-    (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
-
 const Code::Comments& CreateCommentsFrom(compiler::Assembler* assembler) {
   const auto& comments = assembler->comments();
   Code::Comments& result = Code::Comments::New(comments.length());
@@ -21,7 +20,6 @@
   return result;
 }
 
+}  // namespace dart
 #endif  // !defined(DART_PRECOMPILED_RUNTIME) &&                               \
         // (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
-
-}  // namespace dart
diff --git a/runtime/vm/code_comments.h b/runtime/vm/code_comments.h
index 9c86524..18f0e75 100644
--- a/runtime/vm/code_comments.h
+++ b/runtime/vm/code_comments.h
@@ -5,15 +5,15 @@
 #ifndef RUNTIME_VM_CODE_COMMENTS_H_
 #define RUNTIME_VM_CODE_COMMENTS_H_
 
+#if !defined(DART_PRECOMPILED_RUNTIME) &&                                      \
+    (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
+
 #include "vm/code_observers.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/object.h"
 
 namespace dart {
 
-#if !defined(DART_PRECOMPILED_RUNTIME) &&                                      \
-    (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
-
 class CodeCommentsWrapper final : public CodeComments {
  public:
   explicit CodeCommentsWrapper(const Code::Comments& comments)
@@ -37,9 +37,9 @@
 
 const Code::Comments& CreateCommentsFrom(compiler::Assembler* assembler);
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME) &&                               \
-        // (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
 
 }  // namespace dart
 
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) &&                               \
+        // (!defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER))
 #endif  // RUNTIME_VM_CODE_COMMENTS_H_
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index 5136d03..1a5a5f2 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -4,14 +4,14 @@
 
 #include "vm/code_descriptors.h"
 
-#include "vm/compiler/compiler_state.h"
+#include "vm/compiler/api/deopt_id.h"
 #include "vm/log.h"
 #include "vm/object_store.h"
 #include "vm/zone_text_buffer.h"
 
 namespace dart {
 
-void DescriptorList::AddDescriptor(RawPcDescriptors::Kind kind,
+void DescriptorList::AddDescriptor(PcDescriptorsLayout::Kind kind,
                                    intptr_t pc_offset,
                                    intptr_t deopt_id,
                                    TokenPosition token_pos,
@@ -20,19 +20,20 @@
   // yield index 0 is reserved for normal entry.
   RELEASE_ASSERT(yield_index != 0);
 
-  ASSERT((kind == RawPcDescriptors::kRuntimeCall) ||
-         (kind == RawPcDescriptors::kBSSRelocation) ||
-         (kind == RawPcDescriptors::kOther) ||
-         (yield_index != RawPcDescriptors::kInvalidYieldIndex) ||
+  ASSERT((kind == PcDescriptorsLayout::kRuntimeCall) ||
+         (kind == PcDescriptorsLayout::kBSSRelocation) ||
+         (kind == PcDescriptorsLayout::kOther) ||
+         (yield_index != PcDescriptorsLayout::kInvalidYieldIndex) ||
          (deopt_id != DeoptId::kNone));
 
   // When precompiling, we only use pc descriptors for exceptions,
   // relocations and yield indices.
   if (!FLAG_precompiled_mode || try_index != -1 ||
-      yield_index != RawPcDescriptors::kInvalidYieldIndex ||
-      kind == RawPcDescriptors::kBSSRelocation) {
+      yield_index != PcDescriptorsLayout::kInvalidYieldIndex ||
+      kind == PcDescriptorsLayout::kBSSRelocation) {
     const int32_t kind_and_metadata =
-        RawPcDescriptors::KindAndMetadata::Encode(kind, try_index, yield_index);
+        PcDescriptorsLayout::KindAndMetadata::Encode(kind, try_index,
+                                                     yield_index);
 
     PcDescriptors::EncodeInteger(&encoded_data_, kind_and_metadata);
     PcDescriptors::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
@@ -48,7 +49,7 @@
   }
 }
 
-RawPcDescriptors* DescriptorList::FinalizePcDescriptors(uword entry_point) {
+PcDescriptorsPtr DescriptorList::FinalizePcDescriptors(uword entry_point) {
   if (encoded_data_.length() == 0) {
     return Object::empty_descriptors().raw();
   }
@@ -82,7 +83,7 @@
   last_pc_offset_ = pc_offset;
 }
 
-RawCompressedStackMaps* CompressedStackMapsBuilder::Finalize() const {
+CompressedStackMapsPtr CompressedStackMapsBuilder::Finalize() const {
   if (encoded_bytes_.length() == 0) return CompressedStackMaps::null();
   return CompressedStackMaps::NewInlined(encoded_bytes_);
 }
@@ -248,7 +249,7 @@
   return ToCString(Thread::Current()->zone());
 }
 
-RawExceptionHandlers* ExceptionHandlerList::FinalizeExceptionHandlers(
+ExceptionHandlersPtr ExceptionHandlerList::FinalizeExceptionHandlers(
     uword entry_point) const {
   intptr_t num_handlers = Length();
   if (num_handlers == 0) {
@@ -360,7 +361,7 @@
   }
 }
 
-RawTypedData* CatchEntryMovesMapBuilder::FinalizeCatchEntryMovesMap() {
+TypedDataPtr CatchEntryMovesMapBuilder::FinalizeCatchEntryMovesMap() {
   TypedData& td = TypedData::Handle(TypedData::New(
       kTypedDataInt8ArrayCid, stream_.bytes_written(), Heap::kOld));
   NoSafepointScope no_safepoint;
@@ -518,12 +519,12 @@
   BufferAdvancePC(pc_offset - buffered_pc_offset_);
 }
 
-void CodeSourceMapBuilder::NoteDescriptor(RawPcDescriptors::Kind kind,
+void CodeSourceMapBuilder::NoteDescriptor(PcDescriptorsLayout::Kind kind,
                                           int32_t pc_offset,
                                           TokenPosition pos) {
   const uint8_t kCanThrow =
-      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall |
-      RawPcDescriptors::kRuntimeCall | RawPcDescriptors::kOther;
+      PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall |
+      PcDescriptorsLayout::kRuntimeCall | PcDescriptorsLayout::kOther;
   if ((kind & kCanThrow) != 0) {
     BufferChangePosition(pos);
     BufferAdvancePC(pc_offset - buffered_pc_offset_);
@@ -552,14 +553,14 @@
   return inlined_functions_.Length() - 1;
 }
 
-RawArray* CodeSourceMapBuilder::InliningIdToFunction() {
+ArrayPtr CodeSourceMapBuilder::InliningIdToFunction() {
   if (inlined_functions_.Length() == 0) {
     return Object::empty_array().raw();
   }
   return Array::MakeFixedLength(inlined_functions_);
 }
 
-RawCodeSourceMap* CodeSourceMapBuilder::Finalize() {
+CodeSourceMapPtr CodeSourceMapBuilder::Finalize() {
   if (!stack_traces_only_) {
     FlushBuffer();
   }
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index be33407..4ad6723 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -26,14 +26,14 @@
 
   ~DescriptorList() {}
 
-  void AddDescriptor(RawPcDescriptors::Kind kind,
+  void AddDescriptor(PcDescriptorsLayout::Kind kind,
                      intptr_t pc_offset,
                      intptr_t deopt_id,
                      TokenPosition token_pos,
                      intptr_t try_index,
                      intptr_t yield_index);
 
-  RawPcDescriptors* FinalizePcDescriptors(uword entry_point);
+  PcDescriptorsPtr FinalizePcDescriptors(uword entry_point);
 
  private:
   GrowableArray<uint8_t> encoded_data_;
@@ -55,7 +55,7 @@
                 BitmapBuilder* bitmap,
                 intptr_t spill_slot_bit_count);
 
-  RawCompressedStackMaps* Finalize() const;
+  CompressedStackMapsPtr Finalize() const;
 
  private:
   intptr_t last_pc_offset_ = 0;
@@ -199,7 +199,7 @@
     return false;
   }
 
-  RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) const;
+  ExceptionHandlersPtr FinalizeExceptionHandlers(uword entry_point) const;
 
  private:
   GrowableArray<struct HandlerDesc> list_;
@@ -215,7 +215,7 @@
   void NewMapping(intptr_t pc_offset);
   void Append(const CatchEntryMove& move);
   void EndMapping();
-  RawTypedData* FinalizeCatchEntryMovesMap();
+  TypedDataPtr FinalizeCatchEntryMovesMap();
 
  private:
   class TrieNode;
@@ -263,13 +263,13 @@
   void StartInliningInterval(int32_t pc_offset, intptr_t inline_id);
   void BeginCodeSourceRange(int32_t pc_offset);
   void EndCodeSourceRange(int32_t pc_offset, TokenPosition pos);
-  void NoteDescriptor(RawPcDescriptors::Kind kind,
+  void NoteDescriptor(PcDescriptorsLayout::Kind kind,
                       int32_t pc_offset,
                       TokenPosition pos);
   void NoteNullCheck(int32_t pc_offset, TokenPosition pos, intptr_t name_index);
 
-  RawArray* InliningIdToFunction();
-  RawCodeSourceMap* Finalize();
+  ArrayPtr InliningIdToFunction();
+  CodeSourceMapPtr Finalize();
 
  private:
   intptr_t GetFunctionId(intptr_t inline_id);
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 8d5a376..512537e 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -96,7 +96,8 @@
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   int call_count = 0;
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kUnoptStaticCall);
+  PcDescriptors::Iterator iter(descriptors,
+                               PcDescriptorsLayout::kUnoptStaticCall);
   CompressedStackMapsBuilder compressed_maps_builder;
   while (iter.MoveNext()) {
     compressed_maps_builder.AddEntry(iter.PcOffset(), stack_bitmap, 0);
@@ -142,7 +143,7 @@
       sizeof(token_positions) / sizeof(token_positions[0]);
 
   for (intptr_t i = 0; i < num_token_positions; i++) {
-    descriptors->AddDescriptor(RawPcDescriptors::kRuntimeCall, 0, 0,
+    descriptors->AddDescriptor(PcDescriptorsLayout::kRuntimeCall, 0, 0,
                                TokenPosition(token_positions[i]), 0, 1);
   }
 
@@ -151,7 +152,7 @@
 
   ASSERT(!finalized_descriptors.IsNull());
   PcDescriptors::Iterator it(finalized_descriptors,
-                             RawPcDescriptors::kRuntimeCall);
+                             PcDescriptorsLayout::kRuntimeCall);
 
   intptr_t i = 0;
   while (it.MoveNext()) {
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index fa5c521..ba7ff04 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -14,10 +14,6 @@
 // Forward declaration.
 class Code;
 class ICData;
-class RawArray;
-class RawCode;
-class RawFunction;
-class RawObject;
 
 #if defined(TARGET_ARCH_IA32)
 // Stack-allocated class to create a scope where the specified region
@@ -47,13 +43,13 @@
 
   // Return the target address of the static call before return_address
   // in given code.
-  static RawCode* GetStaticCallTargetAt(uword return_address, const Code& code);
+  static CodePtr GetStaticCallTargetAt(uword return_address, const Code& code);
 
   // Get instance call information. Returns the call target and sets the output
   // parameter data if non-NULL.
-  static RawCode* GetInstanceCallAt(uword return_address,
-                                    const Code& caller_code,
-                                    Object* data);
+  static CodePtr GetInstanceCallAt(uword return_address,
+                                   const Code& caller_code,
+                                   Object* data);
 
   // Change the state of an instance call by patching the corresponding object
   // pool entries (non-IA32) or instructions (IA32).
@@ -61,12 +57,17 @@
                                   const Code& caller_code,
                                   const Object& data,
                                   const Code& target);
+  static void PatchInstanceCallAtWithMutatorsStopped(Thread* thread,
+                                                     uword return_address,
+                                                     const Code& caller_code,
+                                                     const Object& data,
+                                                     const Code& target);
 
   // Return target of an unoptimized static call and its ICData object
   // (calls target via a stub).
-  static RawFunction* GetUnoptimizedStaticCallAt(uword return_address,
-                                                 const Code& code,
-                                                 ICData* ic_data);
+  static FunctionPtr GetUnoptimizedStaticCallAt(uword return_address,
+                                                const Code& code,
+                                                ICData* ic_data);
 
   static void InsertDeoptimizationCallAt(uword start);
 
@@ -78,14 +79,19 @@
                                     const Code& caller_code,
                                     const Object& data,
                                     const Code& target);
-  static RawObject* GetSwitchableCallDataAt(uword return_address,
-                                            const Code& caller_code);
-  static RawCode* GetSwitchableCallTargetAt(uword return_address,
-                                            const Code& caller_code);
+  static void PatchSwitchableCallAtWithMutatorsStopped(Thread* thread,
+                                                       uword return_address,
+                                                       const Code& caller_code,
+                                                       const Object& data,
+                                                       const Code& target);
+  static ObjectPtr GetSwitchableCallDataAt(uword return_address,
+                                           const Code& caller_code);
+  static CodePtr GetSwitchableCallTargetAt(uword return_address,
+                                           const Code& caller_code);
 
-  static RawCode* GetNativeCallAt(uword return_address,
-                                  const Code& caller_code,
-                                  NativeFunction* target);
+  static CodePtr GetNativeCallAt(uword return_address,
+                                 const Code& caller_code,
+                                 NativeFunction* target);
 
   static void PatchNativeCallAt(uword return_address,
                                 const Code& caller_code,
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 024a6ab..38729b1 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -7,14 +7,13 @@
 
 #include "vm/code_patcher.h"
 
-#include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
 namespace dart {
 
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
-                                            const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+                                           const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
   CallPattern call(return_address, code);
   return call.TargetCode();
@@ -32,9 +31,9 @@
   UNREACHABLE();
 }
 
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
-                                        const Code& caller_code,
-                                        Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+                                       const Code& caller_code,
+                                       Object* data) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   ICCallPattern call(return_address, caller_code);
   if (data != NULL) {
@@ -47,15 +46,28 @@
                                       const Code& caller_code,
                                       const Object& data,
                                       const Code& target) {
+  auto thread = Thread::Current();
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchInstanceCallAtWithMutatorsStopped(thread, return_address, caller_code,
+                                           data, target);
+  });
+}
+
+void CodePatcher::PatchInstanceCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   ICCallPattern call(return_address, caller_code);
   call.SetData(data);
   call.SetTargetCode(target);
 }
 
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
-                                                     const Code& caller_code,
-                                                     ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+                                                    const Code& caller_code,
+                                                    ICData* ic_data_result) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   ICCallPattern static_call(return_address, caller_code);
   ICData& ic_data = ICData::Handle();
@@ -70,6 +82,20 @@
                                         const Code& caller_code,
                                         const Object& data,
                                         const Code& target) {
+  auto thread = Thread::Current();
+  // Ensure all threads are suspended as we update data and target pair.
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchSwitchableCallAtWithMutatorsStopped(thread, return_address,
+                                             caller_code, data, target);
+  });
+}
+
+void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCallPattern call(return_address, caller_code);
@@ -82,8 +108,8 @@
   }
 }
 
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
-                                                const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                               const Code& caller_code) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCallPattern call(return_address, caller_code);
@@ -94,8 +120,8 @@
   }
 }
 
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
-                                                const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                               const Code& caller_code) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCallPattern call(return_address, caller_code);
@@ -110,15 +136,17 @@
                                     const Code& code,
                                     NativeFunction target,
                                     const Code& trampoline) {
-  ASSERT(code.ContainsInstructionAt(return_address));
-  NativeCallPattern call(return_address, code);
-  call.set_target(trampoline);
-  call.set_native_function(target);
+  Thread::Current()->isolate_group()->RunWithStoppedMutators([&]() {
+    ASSERT(code.ContainsInstructionAt(return_address));
+    NativeCallPattern call(return_address, code);
+    call.set_target(trampoline);
+    call.set_native_function(target);
+  });
 }
 
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
-                                      const Code& code,
-                                      NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+                                     const Code& code,
+                                     NativeFunction* target) {
   ASSERT(code.ContainsInstructionAt(return_address));
   NativeCallPattern call(return_address, code);
   *target = call.native_function();
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index ce3c4dc..824274a 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -24,8 +24,8 @@
 
   intptr_t pp_index() const { return index_; }
 
-  RawCode* Target() const {
-    return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(pp_index()));
+  CodePtr Target() const {
+    return static_cast<CodePtr>(object_pool_.ObjectAt(pp_index()));
   }
 
   void SetTarget(const Code& target) const {
@@ -42,8 +42,8 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(PoolPointerCall);
 };
 
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
-                                            const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+                                           const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
   PoolPointerCall call(return_address, code);
   return call.Target();
@@ -67,9 +67,9 @@
   UNREACHABLE();
 }
 
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
-                                        const Code& caller_code,
-                                        Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+                                       const Code& caller_code,
+                                       Object* data) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   ICCallPattern call(return_address, caller_code);
   if (data != NULL) {
@@ -82,15 +82,28 @@
                                       const Code& caller_code,
                                       const Object& data,
                                       const Code& target) {
+  auto thread = Thread::Current();
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchInstanceCallAtWithMutatorsStopped(thread, return_address, caller_code,
+                                           data, target);
+  });
+}
+
+void CodePatcher::PatchInstanceCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   ICCallPattern call(return_address, caller_code);
   call.SetData(data);
   call.SetTargetCode(target);
 }
 
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
-                                                     const Code& code,
-                                                     ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+                                                    const Code& code,
+                                                    ICData* ic_data_result) {
   ASSERT(code.ContainsInstructionAt(return_address));
   ICCallPattern static_call(return_address, code);
   ICData& ic_data = ICData::Handle();
@@ -105,6 +118,20 @@
                                         const Code& caller_code,
                                         const Object& data,
                                         const Code& target) {
+  auto thread = Thread::Current();
+  // Ensure all threads are suspended as we update data and target pair.
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchSwitchableCallAtWithMutatorsStopped(thread, return_address,
+                                             caller_code, data, target);
+  });
+}
+
+void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCallPattern call(return_address, caller_code);
@@ -117,8 +144,8 @@
   }
 }
 
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
-                                                const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                               const Code& caller_code) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCallPattern call(return_address, caller_code);
@@ -129,8 +156,8 @@
   }
 }
 
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
-                                                const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                               const Code& caller_code) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCallPattern call(return_address, caller_code);
@@ -145,15 +172,17 @@
                                     const Code& caller_code,
                                     NativeFunction target,
                                     const Code& trampoline) {
-  ASSERT(caller_code.ContainsInstructionAt(return_address));
-  NativeCallPattern call(return_address, caller_code);
-  call.set_target(trampoline);
-  call.set_native_function(target);
+  Thread::Current()->isolate_group()->RunWithStoppedMutators([&]() {
+    ASSERT(caller_code.ContainsInstructionAt(return_address));
+    NativeCallPattern call(return_address, caller_code);
+    call.set_target(trampoline);
+    call.set_native_function(target);
+  });
 }
 
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
-                                      const Code& caller_code,
-                                      NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+                                     const Code& caller_code,
+                                     NativeFunction* target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   NativeCallPattern call(return_address, caller_code);
   *target = call.native_function();
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index de240e2..135452e 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::Handle(Symbols::New(thread, "callerFunction"));
   const Function& function = Function::Handle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 2e31dc8..96c34e6 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::Handle(Symbols::New(thread, "callerFunction"));
   const Function& function = Function::Handle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 7e97f67..3c886ba 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -6,8 +6,6 @@
 #if defined(TARGET_ARCH_IA32)
 
 #include "vm/code_patcher.h"
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/instructions.h"
@@ -28,8 +26,8 @@
     ASSERT(IsValid());
   }
 
-  RawObject* ic_data() const {
-    return *reinterpret_cast<RawObject**>(start_ + 1);
+  ObjectPtr ic_data() const {
+    return *reinterpret_cast<ObjectPtr*>(start_ + 1);
   }
 
   static const int kMovInstructionSize = 5;
@@ -91,20 +89,20 @@
 #endif  // DEBUG
   }
 
-  RawObject* data() const { return *reinterpret_cast<RawObject**>(start_ + 1); }
+  ObjectPtr data() const { return *reinterpret_cast<ObjectPtr*>(start_ + 1); }
   void set_data(const Object& data) const {
     uword* cache_addr = reinterpret_cast<uword*>(start_ + 1);
-    uword imm = reinterpret_cast<uword>(data.raw());
+    uword imm = static_cast<uword>(data.raw());
     *cache_addr = imm;
   }
 
-  RawCode* target() const {
+  CodePtr target() const {
     const uword imm = *reinterpret_cast<uword*>(start_ + 6);
-    return reinterpret_cast<RawCode*>(imm);
+    return static_cast<CodePtr>(imm);
   }
   void set_target(const Code& target) const {
     uword* target_addr = reinterpret_cast<uword*>(start_ + 6);
-    uword imm = reinterpret_cast<uword>(target.raw());
+    uword imm = static_cast<uword>(target.raw());
     *target_addr = imm;
   }
 
@@ -144,14 +142,14 @@
     return (code_bytes[0] == 0xBF) && (code_bytes[5] == 0xFF);
   }
 
-  RawCode* target() const {
+  CodePtr target() const {
     const uword imm = *reinterpret_cast<uword*>(start_ + 1);
-    return reinterpret_cast<RawCode*>(imm);
+    return static_cast<CodePtr>(imm);
   }
 
   void set_target(const Code& target) const {
     uword* target_addr = reinterpret_cast<uword*>(start_ + 1);
-    uword imm = reinterpret_cast<uword>(target.raw());
+    uword imm = static_cast<uword>(target.raw());
     *target_addr = imm;
     CPU::FlushICache(start_ + 1, sizeof(imm));
   }
@@ -171,8 +169,8 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
 };
 
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
-                                            const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+                                           const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
   StaticCall call(return_address);
   return call.target();
@@ -196,9 +194,9 @@
   UNREACHABLE();
 }
 
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
-                                        const Code& caller_code,
-                                        Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+                                       const Code& caller_code,
+                                       Object* data) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   InstanceCall call(return_address);
   if (data != NULL) {
@@ -212,21 +210,31 @@
                                       const Object& data,
                                       const Code& target) {
   auto thread = Thread::Current();
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchInstanceCallAtWithMutatorsStopped(thread, return_address, caller_code,
+                                           data, target);
+  });
+}
+
+void CodePatcher::PatchInstanceCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   auto zone = thread->zone();
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   const Instructions& instrs =
       Instructions::Handle(zone, caller_code.instructions());
-  thread->isolate_group()->RunWithStoppedMutators([&]() {
-    WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
-    InstanceCall call(return_address);
-    call.set_data(data);
-    call.set_target(target);
-  });
+  WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
+  InstanceCall call(return_address);
+  call.set_data(data);
+  call.set_target(target);
 }
 
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
-                                                     const Code& caller_code,
-                                                     ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+                                                    const Code& caller_code,
+                                                    ICData* ic_data_result) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   UnoptimizedStaticCall static_call(return_address);
   ICData& ic_data = ICData::Handle();
@@ -245,15 +253,25 @@
   UNREACHABLE();
 }
 
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
-                                                const Code& caller_code) {
+void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
+  // Switchable instance calls only generated for precompilation.
+  UNREACHABLE();
+}
+
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                               const Code& caller_code) {
   // Switchable instance calls only generated for precompilation.
   UNREACHABLE();
   return Code::null();
 }
 
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
-                                                const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                               const Code& caller_code) {
   // Switchable instance calls only generated for precompilation.
   UNREACHABLE();
   return Object::null();
@@ -266,9 +284,9 @@
   UNREACHABLE();
 }
 
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
-                                      const Code& caller_code,
-                                      NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+                                     const Code& caller_code,
+                                     NativeFunction* target) {
   UNREACHABLE();
   return NULL;
 }
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index 8aa1cd6..812f485 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::Handle(Symbols::New(thread, "callerFunction"));
   const Function& function = Function::Handle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index e67d187..d9062a4 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -6,8 +6,6 @@
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/code_patcher.h"
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/instructions.h"
@@ -77,7 +75,7 @@
 
   intptr_t argument_index() const { return argument_index_; }
 
-  RawCode* target() const {
+  CodePtr target() const {
     Code& code = Code::Handle();
     code ^= object_pool_.ObjectAt(code_index_);
     return code.raw();
@@ -130,7 +128,7 @@
 #endif  // DEBUG
   }
 
-  RawObject* data() const { return object_pool_.ObjectAt(argument_index()); }
+  ObjectPtr data() const { return object_pool_.ObjectAt(argument_index()); }
   void set_data(const Object& data) const {
     ASSERT(data.IsArray() || data.IsICData() || data.IsMegamorphicCache());
     object_pool_.SetObjectAt(argument_index(), data);
@@ -151,7 +149,7 @@
 #endif  // DEBUG
   }
 
-  RawObject* ic_data() const { return object_pool_.ObjectAt(argument_index()); }
+  ObjectPtr ic_data() const { return object_pool_.ObjectAt(argument_index()); }
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall);
@@ -196,7 +194,7 @@
     ASSERT(Object::Handle(object_pool_.ObjectAt(code_index_)).IsCode());
   }
 
-  RawCode* Target() const {
+  CodePtr Target() const {
     Code& code = Code::Handle();
     code ^= object_pool_.ObjectAt(code_index_);
     return code.raw();
@@ -230,7 +228,7 @@
   intptr_t data_index() const { return data_index_; }
   intptr_t target_index() const { return target_index_; }
 
-  RawObject* data() const { return object_pool_.ObjectAt(data_index()); }
+  ObjectPtr data() const { return object_pool_.ObjectAt(data_index()); }
 
   void SetData(const Object& data) const {
     ASSERT(!Object::Handle(object_pool_.ObjectAt(data_index())).IsCode());
@@ -323,8 +321,8 @@
     // No need to flush the instruction cache, since the code is not modified.
   }
 
-  RawCode* target() const {
-    return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_index()));
+  CodePtr target() const {
+    return static_cast<CodePtr>(object_pool_.ObjectAt(target_index()));
   }
 };
 
@@ -397,13 +395,13 @@
     object_pool_.SetRawValueAt(target_index(), target.MonomorphicEntryPoint());
   }
 
-  RawCode* target() const {
+  CodePtr target() const {
     const uword pc = object_pool_.RawValueAt(target_index());
-    auto rct = Isolate::Current()->reverse_pc_lookup_cache();
+    auto rct = IsolateGroup::Current()->reverse_pc_lookup_cache();
     if (rct->Contains(pc)) {
       return rct->Lookup(pc);
     }
-    rct = Dart::vm_isolate()->reverse_pc_lookup_cache();
+    rct = Dart::vm_isolate()->group()->reverse_pc_lookup_cache();
     if (rct->Contains(pc)) {
       return rct->Lookup(pc);
     }
@@ -411,8 +409,8 @@
   }
 };
 
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
-                                            const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+                                           const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
   PoolPointerCall call(return_address, code);
   return call.Target();
@@ -432,9 +430,9 @@
   call.SetTarget(new_target);
 }
 
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
-                                        const Code& caller_code,
-                                        Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+                                       const Code& caller_code,
+                                       Object* data) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   InstanceCall call(return_address, caller_code);
   if (data != NULL) {
@@ -447,6 +445,19 @@
                                       const Code& caller_code,
                                       const Object& data,
                                       const Code& target) {
+  auto thread = Thread::Current();
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchInstanceCallAtWithMutatorsStopped(thread, return_address, caller_code,
+                                           data, target);
+  });
+}
+
+void CodePatcher::PatchInstanceCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   InstanceCall call(return_address, caller_code);
   call.set_data(data);
@@ -457,9 +468,9 @@
   UNREACHABLE();
 }
 
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
-                                                     const Code& caller_code,
-                                                     ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+                                                    const Code& caller_code,
+                                                    ICData* ic_data_result) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   UnoptimizedStaticCall static_call(return_address, caller_code);
   ICData& ic_data = ICData::Handle();
@@ -474,6 +485,20 @@
                                         const Code& caller_code,
                                         const Object& data,
                                         const Code& target) {
+  auto thread = Thread::Current();
+  // Ensure all threads are suspended as we update data and target pair.
+  thread->isolate_group()->RunWithStoppedMutators([&]() {
+    PatchSwitchableCallAtWithMutatorsStopped(thread, return_address,
+                                             caller_code, data, target);
+  });
+}
+
+void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+    Thread* thread,
+    uword return_address,
+    const Code& caller_code,
+    const Object& data,
+    const Code& target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCall call(return_address, caller_code);
@@ -486,8 +511,8 @@
   }
 }
 
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
-                                                const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                               const Code& caller_code) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCall call(return_address, caller_code);
@@ -498,8 +523,8 @@
   }
 }
 
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
-                                                const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                               const Code& caller_code) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     BareSwitchableCall call(return_address, caller_code);
@@ -514,15 +539,17 @@
                                     const Code& caller_code,
                                     NativeFunction target,
                                     const Code& trampoline) {
-  ASSERT(caller_code.ContainsInstructionAt(return_address));
-  NativeCall call(return_address, caller_code);
-  call.set_target(trampoline);
-  call.set_native_function(target);
+  Thread::Current()->isolate_group()->RunWithStoppedMutators([&]() {
+    ASSERT(caller_code.ContainsInstructionAt(return_address));
+    NativeCall call(return_address, caller_code);
+    call.set_target(trampoline);
+    call.set_native_function(target);
+  });
 }
 
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
-                                      const Code& caller_code,
-                                      NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+                                     const Code& caller_code,
+                                     NativeFunction* target) {
   ASSERT(caller_code.ContainsInstructionAt(return_address));
   NativeCall call(return_address, caller_code);
   *target = call.native_function();
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index e838880..d00b53c 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::Handle(Symbols::New(thread, "callerFunction"));
   const Function& function = Function::Handle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index 28ad54a..174c252 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -27,7 +27,7 @@
       lib_(Library::Handle(zone)),
       uri_(String::Handle(zone)) {}
 
-void CompilationTraceSaver::Visit(const Function& function) {
+void CompilationTraceSaver::VisitFunction(const Function& function) {
   if (!function.HasCode()) {
     return;  // Not compiled.
   }
@@ -79,8 +79,7 @@
   return NULL;
 }
 
-RawObject* CompilationTraceLoader::CompileTrace(uint8_t* buffer,
-                                                intptr_t size) {
+ObjectPtr CompilationTraceLoader::CompileTrace(uint8_t* buffer, intptr_t size) {
   // First compile functions named in the trace.
   char* cursor = reinterpret_cast<char*>(buffer);
   char* limit = cursor + size;
@@ -125,7 +124,7 @@
     arguments_descriptor = ArgumentsDescriptor::NewBoxed(kTypeArgsLen, argc);
     dispatcher = closure_class.GetInvocationDispatcher(
         Symbols::Call(), arguments_descriptor,
-        RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */);
+        FunctionLayout::kInvokeFieldDispatcher, true /* create_if_absent */);
     error_ = CompileFunction(dispatcher);
     if (error_.IsError()) {
       return error_.raw();
@@ -160,9 +159,9 @@
 //    compile the getter, create its method extractor and compile that.
 //  - If looking for a getter and we only have a const field, evaluate the const
 //    field.
-RawObject* CompilationTraceLoader::CompileTriple(const char* uri_cstr,
-                                                 const char* cls_cstr,
-                                                 const char* func_cstr) {
+ObjectPtr CompilationTraceLoader::CompileTriple(const char* uri_cstr,
+                                                const char* cls_cstr,
+                                                const char* func_cstr) {
   uri_ = Symbols::New(thread_, uri_cstr);
   class_name_ = Symbols::New(thread_, cls_cstr);
   function_name_ = Symbols::New(thread_, func_cstr);
@@ -363,7 +362,7 @@
   return Object::null();
 }
 
-RawObject* CompilationTraceLoader::CompileFunction(const Function& function) {
+ObjectPtr CompilationTraceLoader::CompileFunction(const Function& function) {
   if (function.is_abstract() || function.HasCode()) {
     return Object::null();
   }
@@ -505,7 +504,7 @@
   }
 }
 
-void TypeFeedbackSaver::Visit(const Function& function) {
+void TypeFeedbackSaver::VisitFunction(const Function& function) {
   if (!function.HasCode()) {
     return;  // Not compiled.
   }
@@ -612,7 +611,7 @@
   delete[] cid_map_;
 }
 
-RawObject* TypeFeedbackLoader::LoadFeedback(ReadStream* stream) {
+ObjectPtr TypeFeedbackLoader::LoadFeedback(ReadStream* stream) {
   stream_ = stream;
 
   error_ = CheckHeader();
@@ -656,7 +655,7 @@
   return Error::null();
 }
 
-RawObject* TypeFeedbackLoader::CheckHeader() {
+ObjectPtr TypeFeedbackLoader::CheckHeader() {
   const char* expected_version = Version::SnapshotString();
   ASSERT(expected_version != NULL);
   const intptr_t version_len = strlen(expected_version);
@@ -710,7 +709,7 @@
   return Error::null();
 }
 
-RawObject* TypeFeedbackLoader::LoadClasses() {
+ObjectPtr TypeFeedbackLoader::LoadClasses() {
   num_cids_ = ReadInt();
 
   cid_map_ = new intptr_t[num_cids_];
@@ -731,7 +730,7 @@
   return Error::null();
 }
 
-RawObject* TypeFeedbackLoader::LoadFields() {
+ObjectPtr TypeFeedbackLoader::LoadFields() {
   for (intptr_t cid = kNumPredefinedCids; cid < num_cids_; cid++) {
     cls_ = ReadClassByName();
     bool skip = cls_.IsNull();
@@ -799,7 +798,7 @@
   return Error::null();
 }
 
-RawObject* TypeFeedbackLoader::LoadFunction() {
+ObjectPtr TypeFeedbackLoader::LoadFunction() {
   bool skip = false;
 
   cls_ = ReadClassByName();
@@ -813,7 +812,7 @@
   }
 
   func_name_ = ReadString();  // Without private mangling.
-  RawFunction::Kind kind = static_cast<RawFunction::Kind>(ReadInt());
+  FunctionLayout::Kind kind = static_cast<FunctionLayout::Kind>(ReadInt());
   intptr_t token_pos = ReadInt();
   intptr_t usage = ReadInt();
   intptr_t inlining_depth = ReadInt();
@@ -923,8 +922,8 @@
   return Error::null();
 }
 
-RawFunction* TypeFeedbackLoader::FindFunction(RawFunction::Kind kind,
-                                              intptr_t token_pos) {
+FunctionPtr TypeFeedbackLoader::FindFunction(FunctionLayout::Kind kind,
+                                             intptr_t token_pos) {
   if (cls_name_.Equals(Symbols::TopLevel())) {
     func_ = lib_.LookupFunctionAllowPrivate(func_name_);
   } else {
@@ -933,7 +932,7 @@
 
   if (!func_.IsNull()) {
     // Found regular method.
-  } else if (kind == RawFunction::kMethodExtractor) {
+  } else if (kind == FunctionLayout::kMethodExtractor) {
     ASSERT(Field::IsGetterName(func_name_));
     // Without private mangling:
     String& name = String::Handle(zone_, Field::NameFromGetter(func_name_));
@@ -945,7 +944,7 @@
     } else {
       func_ = Function::null();
     }
-  } else if (kind == RawFunction::kDynamicInvocationForwarder) {
+  } else if (kind == FunctionLayout::kDynamicInvocationForwarder) {
     // Without private mangling:
     String& name = String::Handle(
         zone_, Function::DemangleDynamicInvocationForwarderName(func_name_));
@@ -957,7 +956,7 @@
     } else {
       func_ = Function::null();
     }
-  } else if (kind == RawFunction::kClosureFunction) {
+  } else if (kind == FunctionLayout::kClosureFunction) {
     // Note this lookup relies on parent functions appearing before child
     // functions in the serialized feedback, so the parent will have already
     // been unoptimized compilated and the child function created and added to
@@ -984,7 +983,7 @@
   }
 
   if (!func_.IsNull()) {
-    if (kind == RawFunction::kImplicitClosureFunction) {
+    if (kind == FunctionLayout::kImplicitClosureFunction) {
       func_ = func_.ImplicitClosureFunction();
     }
     if (func_.is_abstract() || (func_.kind() != kind)) {
@@ -995,7 +994,7 @@
   return func_.raw();
 }
 
-RawClass* TypeFeedbackLoader::ReadClassByName() {
+ClassPtr TypeFeedbackLoader::ReadClassByName() {
   uri_ = ReadString();
   cls_name_ = ReadString();
 
@@ -1021,7 +1020,7 @@
   return cls_.raw();
 }
 
-RawString* TypeFeedbackLoader::ReadString() {
+StringPtr TypeFeedbackLoader::ReadString() {
   intptr_t len = stream_->ReadUnsigned();
   const char* cstr =
       reinterpret_cast<const char*>(stream_->AddressOfCurrentPosition());
diff --git a/runtime/vm/compilation_trace.h b/runtime/vm/compilation_trace.h
index e3a8fbd..cf26611 100644
--- a/runtime/vm/compilation_trace.h
+++ b/runtime/vm/compilation_trace.h
@@ -15,7 +15,7 @@
 class CompilationTraceSaver : public FunctionVisitor {
  public:
   explicit CompilationTraceSaver(Zone* zone);
-  void Visit(const Function& function);
+  void VisitFunction(const Function& function);
 
   void StealBuffer(uint8_t** buffer, intptr_t* buffer_length) {
     *buffer = reinterpret_cast<uint8_t*>(buf_.buffer());
@@ -35,13 +35,13 @@
  public:
   explicit CompilationTraceLoader(Thread* thread);
 
-  RawObject* CompileTrace(uint8_t* buffer, intptr_t buffer_length);
+  ObjectPtr CompileTrace(uint8_t* buffer, intptr_t buffer_length);
 
  private:
-  RawObject* CompileTriple(const char* uri_cstr,
-                           const char* cls_cstr,
-                           const char* func_cstr);
-  RawObject* CompileFunction(const Function& function);
+  ObjectPtr CompileTriple(const char* uri_cstr,
+                          const char* cls_cstr,
+                          const char* func_cstr);
+  ObjectPtr CompileFunction(const Function& function);
   void SpeculateInstanceCallTargets(const Function& function);
 
   Thread* thread_;
@@ -72,7 +72,7 @@
   void WriteHeader();
   void SaveClasses();
   void SaveFields();
-  void Visit(const Function& function);
+  void VisitFunction(const Function& function);
 
  private:
   void WriteClassByName(const Class& cls);
@@ -95,17 +95,17 @@
   explicit TypeFeedbackLoader(Thread* thread);
   ~TypeFeedbackLoader();
 
-  RawObject* LoadFeedback(ReadStream* stream);
+  ObjectPtr LoadFeedback(ReadStream* stream);
 
  private:
-  RawObject* CheckHeader();
-  RawObject* LoadClasses();
-  RawObject* LoadFields();
-  RawObject* LoadFunction();
-  RawFunction* FindFunction(RawFunction::Kind kind, intptr_t token_pos);
+  ObjectPtr CheckHeader();
+  ObjectPtr LoadClasses();
+  ObjectPtr LoadFields();
+  ObjectPtr LoadFunction();
+  FunctionPtr FindFunction(FunctionLayout::Kind kind, intptr_t token_pos);
 
-  RawClass* ReadClassByName();
-  RawString* ReadString();
+  ClassPtr ReadClassByName();
+  StringPtr ReadString();
   intptr_t ReadInt() { return stream_->Read<int32_t>(); }
 
   Thread* thread_;
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 78e6edd..4da0354 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -851,7 +851,7 @@
 
   if (has_one_target) {
     const Function& target = targets.FirstTarget();
-    RawFunction::Kind function_kind = target.kind();
+    FunctionLayout::Kind function_kind = target.kind();
     if (flow_graph()->CheckForInstanceCall(instr, function_kind) ==
         FlowGraph::ToCheck::kNoCheck) {
       StaticCallInstr* call = StaticCallInstr::FromCall(
@@ -1300,9 +1300,28 @@
   }
 }
 
-void AotCallSpecializer::TryReplaceWithDispatchTableCall(
+const Function& AotCallSpecializer::InterfaceTargetForTableDispatch(
     InstanceCallBaseInstr* call) {
   const Function& interface_target = call->interface_target();
+  if (!interface_target.IsNull()) {
+    return interface_target;
+  }
+
+  // Dynamic call or tearoff.
+  const Function& tearoff_interface_target = call->tearoff_interface_target();
+  if (!tearoff_interface_target.IsNull()) {
+    // Tearoff.
+    return Function::ZoneHandle(
+        Z, tearoff_interface_target.GetMethodExtractor(call->function_name()));
+  }
+
+  // Dynamic call.
+  return Function::null_function();
+}
+
+void AotCallSpecializer::TryReplaceWithDispatchTableCall(
+    InstanceCallBaseInstr* call) {
+  const Function& interface_target = InterfaceTargetForTableDispatch(call);
   if (interface_target.IsNull()) {
     // Dynamic call.
     return;
@@ -1333,7 +1352,7 @@
   InsertBefore(call, load_cid, call->env(), FlowGraph::kValue);
 
   auto dispatch_table_call = DispatchTableCallInstr::FromCall(
-      Z, call, new (Z) Value(load_cid), selector);
+      Z, call, new (Z) Value(load_cid), interface_target, selector);
   call->ReplaceWith(dispatch_table_call, current_iterator());
 }
 
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.h b/runtime/vm/compiler/aot/aot_call_specializer.h
index 44ea0c2..fd23ebf 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.h
+++ b/runtime/vm/compiler/aot/aot_call_specializer.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_AOT_AOT_CALL_SPECIALIZER_H_
 #define RUNTIME_VM_COMPILER_AOT_AOT_CALL_SPECIALIZER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/call_specializer.h"
 
 namespace dart {
@@ -52,6 +56,7 @@
   // If a call can be dispatched through the global dispatch table, replace
   // it by a dispatch table call.
   void TryReplaceWithDispatchTableCall(InstanceCallBaseInstr* call);
+  const Function& InterfaceTargetForTableDispatch(InstanceCallBaseInstr* call);
 
   // Try to replace a call with a more specialized instruction working on
   // integers (e.g. BinaryInt64OpInstr, CheckedSmiComparisonInstr,
diff --git a/runtime/vm/compiler/aot/dispatch_table_generator.cc b/runtime/vm/compiler/aot/dispatch_table_generator.cc
index 99a21ed..af7a1e1 100644
--- a/runtime/vm/compiler/aot/dispatch_table_generator.cc
+++ b/runtime/vm/compiler/aot/dispatch_table_generator.cc
@@ -366,7 +366,8 @@
   kernel::ProcedureAttributesMetadata metadata;
   metadata = kernel::ProcedureAttributesOf(interface_target, Z);
   return interface_target.IsGetterFunction() ||
-                 interface_target.IsImplicitGetterFunction()
+                 interface_target.IsImplicitGetterFunction() ||
+                 interface_target.IsMethodExtractor()
              ? metadata.getter_selector_id
              : metadata.method_or_setter_selector_id;
 }
@@ -381,10 +382,12 @@
   return selector;
 }
 
-void SelectorMap::AddSelector(int32_t call_count, bool called_on_null) {
+void SelectorMap::AddSelector(int32_t call_count,
+                              bool called_on_null,
+                              bool torn_off) {
   const int32_t added_sid = selectors_.length();
   selectors_.Add(TableSelector(added_sid, call_count, kInvalidSelectorOffset,
-                               called_on_null));
+                               called_on_null, torn_off));
 }
 
 void SelectorMap::SetSelectorProperties(int32_t sid,
@@ -421,7 +424,8 @@
   RELEASE_ASSERT(metadata != nullptr);
   for (intptr_t i = 0; i < metadata->selectors.length(); i++) {
     const kernel::TableSelectorInfo* info = &metadata->selectors[i];
-    selector_map_.AddSelector(info->call_count, info->called_on_null);
+    selector_map_.AddSelector(info->call_count, info->called_on_null,
+                              info->torn_off);
   }
 }
 
@@ -562,13 +566,29 @@
             const int32_t sid = selector_map_.SelectorId(function);
 
             if (sid != SelectorMap::kInvalidSelectorId) {
-              // Make a function handle that survives until the table is built.
-              auto& function_handle = Function::ZoneHandle(Z, function.raw());
+              auto MakeIntervals = [&](const Function& function, int32_t sid) {
+                // A function handle that survives until the table is built.
+                auto& function_handle = Function::ZoneHandle(Z, function.raw());
 
-              for (intptr_t i = 0; i < subclasss_cid_ranges.length(); i++) {
-                Interval& subclass_cid_range = subclasss_cid_ranges[i];
-                selector_rows[sid].DefineSelectorImplementationForInterval(
-                    cid, depth, subclass_cid_range, &function_handle);
+                for (intptr_t i = 0; i < subclasss_cid_ranges.length(); i++) {
+                  Interval& subclass_cid_range = subclasss_cid_ranges[i];
+                  selector_rows[sid].DefineSelectorImplementationForInterval(
+                      cid, depth, subclass_cid_range, &function_handle);
+                }
+              };
+              MakeIntervals(function, sid);
+
+              if (selector_map_.selectors_[sid].torn_off) {
+                const String& method_name = String::Handle(Z, function.name());
+                const String& getter_name =
+                    String::Handle(Z, Field::GetterName(method_name));
+                const Function& tearoff = Function::Handle(
+                    Z, function.GetMethodExtractor(getter_name));
+                const int32_t tearoff_sid = selector_map_.SelectorId(tearoff);
+
+                if (tearoff_sid != SelectorMap::kInvalidSelectorId) {
+                  MakeIntervals(tearoff, tearoff_sid);
+                }
               }
             }
           }
@@ -637,7 +657,7 @@
   table_size_ = fitter.TableSize();
 }
 
-RawArray* DispatchTableGenerator::BuildCodeArray() {
+ArrayPtr DispatchTableGenerator::BuildCodeArray() {
   auto& entries = Array::Handle(zone_, Array::New(table_size_, Heap::kOld));
   for (intptr_t i = 0; i < table_rows_.length(); i++) {
     table_rows_[i]->FillTable(classes_, entries);
diff --git a/runtime/vm/compiler/aot/dispatch_table_generator.h b/runtime/vm/compiler/aot/dispatch_table_generator.h
index 830e122..20b6ca3 100644
--- a/runtime/vm/compiler/aot/dispatch_table_generator.h
+++ b/runtime/vm/compiler/aot/dispatch_table_generator.h
@@ -5,11 +5,13 @@
 #ifndef RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
 #define RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 #include "vm/object.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 
 class ClassTable;
@@ -23,11 +25,13 @@
   TableSelector(int32_t _id,
                 int32_t _call_count,
                 int32_t _offset,
-                bool _called_on_null)
+                bool _called_on_null,
+                bool _torn_off)
       : id(_id),
         call_count(_call_count),
         offset(_offset),
-        called_on_null(_called_on_null) {}
+        called_on_null(_called_on_null),
+        torn_off(_torn_off) {}
 
   bool IsUsed() const { return call_count > 0; }
 
@@ -40,6 +44,8 @@
   int32_t offset;
   // Are there any call sites with this selector where the receiver may be null?
   bool called_on_null;
+  // Is this method ever torn off, i.e. is its method extractor accessed?
+  bool torn_off;
   // Is the selector part of the interface on Null (same as Object)?
   bool on_null_interface = false;
   // Do any targets of this selector assume that an args descriptor is passed?
@@ -61,7 +67,7 @@
 
   int32_t SelectorId(const Function& interface_target) const;
 
-  void AddSelector(int32_t call_count, bool called_on_null);
+  void AddSelector(int32_t call_count, bool called_on_null, bool torn_off);
   void SetSelectorProperties(int32_t sid,
                              bool on_null_interface,
                              bool requires_args_descriptor);
@@ -87,7 +93,7 @@
 
   // Build up an array of Code objects, used to serialize the information
   // deserialized as a DispatchTable at runtime.
-  RawArray* BuildCodeArray();
+  ArrayPtr BuildCodeArray();
 
  private:
   void ReadTableSelectorInfo();
@@ -109,6 +115,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 #endif  // RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 2bf294a..f63bf47 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -4,8 +4,6 @@
 
 #include "vm/compiler/aot/precompiler.h"
 
-#ifndef DART_PRECOMPILED_RUNTIME
-
 #include "platform/unicode.h"
 #include "vm/class_finalizer.h"
 #include "vm/code_patcher.h"
@@ -136,7 +134,7 @@
   Thread::Current()->long_jump_base()->Jump(1, error);
 }
 
-RawError* Precompiler::CompileAll() {
+ErrorPtr Precompiler::CompileAll() {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Precompiler precompiler(Thread::Current());
@@ -282,73 +280,22 @@
         global_object_pool_builder()->Reset();
         stub_pool.CopyInto(global_object_pool_builder());
 
-        // We have two global code objects we need to re-generate with the new
-        // global object pool, namely the
-        //   - megamorphic miss handler code and the
-        //   - build method extractor code
-        MegamorphicCacheTable::ReInitMissHandlerCode(
-            isolate_, global_object_pool_builder());
-
+        // We have various stubs we would like to generate inside the isolate,
+        // to ensure the rest of the AOT compilation will use the
+        // isolate-specific stubs (callable via pc-relative calls).
         auto& stub_code = Code::Handle();
-
+#define DO(member, name)                                                       \
+  stub_code = StubCode::BuildIsolateSpecific##name##Stub(                      \
+      global_object_pool_builder());                                           \
+  I->object_store()->set_##member(stub_code);
+        OBJECT_STORE_STUB_CODE_LIST(DO)
+#undef DO
         stub_code =
             StubCode::GetBuildMethodExtractorStub(global_object_pool_builder());
         I->object_store()->set_build_method_extractor_code(stub_code);
 
-        stub_code = StubCode::BuildIsolateSpecificDispatchTableNullErrorStub(
-            global_object_pool_builder());
-        I->object_store()->set_dispatch_table_null_error_stub(stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificNullErrorSharedWithFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_null_error_stub_with_fpu_regs_stub(stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificNullErrorSharedWithoutFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_null_error_stub_without_fpu_regs_stub(stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificNullArgErrorSharedWithFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_null_arg_error_stub_with_fpu_regs_stub(
-            stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificNullArgErrorSharedWithoutFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_null_arg_error_stub_without_fpu_regs_stub(
-            stub_code);
-
-        stub_code = StubCode::BuildIsolateSpecificAllocateMintWithFPURegsStub(
-            global_object_pool_builder());
-        I->object_store()->set_allocate_mint_with_fpu_regs_stub(stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificAllocateMintWithoutFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_allocate_mint_without_fpu_regs_stub(stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificStackOverflowSharedWithFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_stack_overflow_stub_with_fpu_regs_stub(
-            stub_code);
-
-        stub_code =
-            StubCode::BuildIsolateSpecificStackOverflowSharedWithoutFPURegsStub(
-                global_object_pool_builder());
-        I->object_store()->set_stack_overflow_stub_without_fpu_regs_stub(
-            stub_code);
-
-        stub_code = StubCode::BuildIsolateSpecificWriteBarrierWrappersStub(
-            global_object_pool_builder());
-        I->object_store()->set_write_barrier_wrappers_stub(stub_code);
-
-        stub_code = StubCode::BuildIsolateSpecificArrayWriteBarrierStub(
-            global_object_pool_builder());
-        I->object_store()->set_array_write_barrier_stub(stub_code);
+        MegamorphicCacheTable::ReInitMissHandlerCode(
+            isolate_, global_object_pool_builder());
       }
 
       CollectDynamicFunctionNames();
@@ -404,42 +351,38 @@
           // We don't want the Array backing for any mappings in the snapshot,
           // only the pools themselves.
           I->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, I->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, I->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);
+          }
         }
       }
 
       TraceForRetainedFunctions();
-
-      if (FLAG_use_bare_instructions && FLAG_use_table_dispatch) {
-        // Build the entries used to serialize the dispatch table before
-        // dropping functions, as we may clear references to Code objects.
-        const auto& entries =
-            Array::Handle(Z, dispatch_table_generator_->BuildCodeArray());
-        I->object_store()->set_dispatch_table_code_entries(entries);
-        // Delete the dispatch table generator to ensure there's no attempt
-        // to add new entries after this point.
-        delete dispatch_table_generator_;
-        dispatch_table_generator_ = nullptr;
-        if (!FLAG_retain_dispatched_functions && FLAG_trace_precompiler) {
-          FunctionSet printed(
-              HashTables::New<FunctionSet>(/*initial_capacity=*/1024));
-          auto& code = Code::Handle(Z);
-          auto& function = Function::Handle(Z);
-          for (intptr_t i = 0; i < entries.Length(); i++) {
-            code = Code::RawCast(entries.At(i));
-            if (code.IsNull()) continue;
-            if (!code.IsFunctionCode()) continue;
-            function = code.function();
-            ASSERT(!function.IsNull());
-            if (printed.ContainsKey(function)) continue;
-            if (functions_to_retain_.ContainsKey(function)) continue;
-            THR_Print(
-                "Dispatch table references code for function to drop: %s\n",
-                function.ToLibNamePrefixedQualifiedCString());
-            printed.Insert(function);
-          }
-          printed.Release();
-        }
-      }
+      FinalizeDispatchTable();
+      ReplaceFunctionPCRelativeCallEntries();
 
       DropFunctions();
       DropFields();
@@ -484,7 +427,7 @@
              non_visited.ToFullyQualifiedCString());
     }
 #endif
-    ProgramVisitor::Dedup();
+    ProgramVisitor::Dedup(T);
 
     zone_ = NULL;
   }
@@ -519,7 +462,7 @@
    public:
     explicit ConstructorVisitor(Precompiler* precompiler, Zone* zone)
         : precompiler_(precompiler), zone_(zone) {}
-    void Visit(const Function& function) {
+    void VisitFunction(const Function& function) {
       if (!function.IsGenerativeConstructor()) return;
       if (function.HasCode()) {
         // Const constructors may have been visited before. Recompile them here
@@ -538,8 +481,8 @@
   };
 
   HANDLESCOPE(T);
-  ConstructorVisitor visitor(this, zone_);
-  ProgramVisitor::VisitFunctions(&visitor);
+  ConstructorVisitor visitor(this, Z);
+  ProgramVisitor::WalkProgram(Z, I, &visitor);
 }
 
 void Precompiler::AddRoots() {
@@ -665,7 +608,7 @@
             if (subcls.is_allocated()) {
               // Add dispatcher to cls.
               dispatcher = subcls.GetInvocationDispatcher(
-                  field_name, args_desc, RawFunction::kInvokeFieldDispatcher,
+                  field_name, args_desc, FunctionLayout::kInvokeFieldDispatcher,
                   /* create_if_absent = */ true);
               if (FLAG_trace_precompiler) {
                 THR_Print("Added invoke-field-dispatcher for %s to %s\n",
@@ -733,9 +676,11 @@
   for (auto& view : static_calls) {
     entry = view.Get<Code::kSCallTableFunctionTarget>();
     if (entry.IsFunction()) {
-      AddFunction(Function::Cast(entry));
+      AddFunction(Function::Cast(entry), FLAG_retain_function_objects);
+      ASSERT(view.Get<Code::kSCallTableCodeOrTypeTarget>() == Code::null());
+      continue;
     }
-    entry = view.Get<Code::kSCallTableCodeTarget>();
+    entry = view.Get<Code::kSCallTableCodeOrTypeTarget>();
     if (entry.IsCode() && Code::Cast(entry).IsAllocationStubCode()) {
       cls ^= Code::Cast(entry).owner();
       AddInstantiatedClass(cls);
@@ -861,7 +806,7 @@
   }
   Code& code = Code::Handle(Z, function.CurrentCode());
   if (code.IsNull()) {
-    ASSERT(function.kind() == RawFunction::kSignatureFunction);
+    ASSERT(function.kind() == FunctionLayout::kSignatureFunction);
   } else {
     const ExceptionHandlers& handlers =
         ExceptionHandlers::Handle(Z, code.exception_handlers());
@@ -917,6 +862,9 @@
     const AbstractType& type =
         AbstractType::Handle(Z, TypeParameter::Cast(abstype).bound());
     AddType(type);
+    const auto& function = Function::Handle(
+        Z, TypeParameter::Cast(abstype).parameterized_function());
+    AddTypesOf(function);
     const Class& cls =
         Class::Handle(Z, TypeParameter::Cast(abstype).parameterized_class());
     AddTypesOf(cls);
@@ -946,6 +894,11 @@
     return;
   }
 
+  if (instance.raw() == Object::sentinel().raw() ||
+      instance.raw() == Object::transition_sentinel().raw()) {
+    return;
+  }
+
   const Class& cls = Class::Handle(Z, instance.clazz());
   AddInstantiatedClass(cls);
 
@@ -987,8 +940,8 @@
           precompiler_(precompiler),
           subinstance_(Object::Handle()) {}
 
-    virtual void VisitPointers(RawObject** first, RawObject** last) {
-      for (RawObject** current = first; current <= last; current++) {
+    virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+      for (ObjectPtr* current = first; current <= last; current++) {
         subinstance_ = *current;
         if (subinstance_.IsInstance()) {
           precompiler_->AddConstObject(Instance::Cast(subinstance_));
@@ -1003,16 +956,17 @@
   };
 
   ConstObjectVisitor visitor(this, I);
-  instance.raw()->VisitPointers(&visitor);
+  instance.raw()->ptr()->VisitPointers(&visitor);
 }
 
 void Precompiler::AddClosureCall(const Array& arguments_descriptor) {
   const Class& cache_class =
       Class::Handle(Z, I->object_store()->closure_class());
-  const Function& dispatcher = Function::Handle(
-      Z, cache_class.GetInvocationDispatcher(
-             Symbols::Call(), arguments_descriptor,
-             RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */));
+  const Function& dispatcher =
+      Function::Handle(Z, cache_class.GetInvocationDispatcher(
+                              Symbols::Call(), arguments_descriptor,
+                              FunctionLayout::kInvokeFieldDispatcher,
+                              true /* create_if_absent */));
   AddFunction(dispatcher);
 }
 
@@ -1023,66 +977,22 @@
 
   if (field.is_static()) {
     const Object& value = Object::Handle(Z, field.StaticValue());
-    if (value.IsInstance()) {
+    // Should not be in the middle of initialization while precompiling.
+    ASSERT(value.raw() != Object::transition_sentinel().raw());
+
+    if (value.raw() != Object::sentinel().raw() &&
+        value.raw() != Object::null()) {
+      ASSERT(value.IsInstance());
       AddConstObject(Instance::Cast(value));
     }
-
-    if (field.has_nontrivial_initializer()) {
-      // Should not be in the middle of initialization while precompiling.
-      ASSERT(value.raw() != Object::transition_sentinel().raw());
-
-      if (!field.HasInitializerFunction() ||
-          !Function::Handle(Z, field.InitializerFunction()).HasCode()) {
-        if (FLAG_trace_precompiler) {
-          THR_Print("Precompiling initializer for %s\n", field.ToCString());
-        }
-        const intptr_t gop_offset =
-            FLAG_use_bare_instructions
-                ? global_object_pool_builder()->CurrentLength()
-                : 0;
-        ASSERT(Dart::vm_snapshot_kind() != Snapshot::kFullAOT);
-        const Function& initializer =
-            Function::Handle(Z, CompileStaticInitializer(field));
-        ASSERT(!initializer.IsNull());
-        field.SetInitializerFunction(initializer);
-        AddCalleesOf(initializer, gop_offset);
-      }
-    }
-  }
-}
-
-RawFunction* Precompiler::CompileStaticInitializer(const Field& field) {
-  ASSERT(field.is_static());
-  Thread* thread = Thread::Current();
-  StackZone stack_zone(thread);
-  Zone* zone = stack_zone.GetZone();
-  ASSERT(Error::Handle(zone, thread->sticky_error()).IsNull());
-
-  const Function& initializer_fun =
-      Function::ZoneHandle(zone, field.EnsureInitializerFunction());
-  ParsedFunction* parsed_function =
-      new (zone) ParsedFunction(thread, initializer_fun);
-
-  DartCompilationPipeline pipeline;
-  PrecompileParsedFunctionHelper helper(Precompiler::Instance(),
-                                        parsed_function,
-                                        /* optimized = */ true);
-  if (!helper.Compile(&pipeline)) {
-    Error& error = Error::Handle(zone, thread->sticky_error());
-    ASSERT(!error.IsNull());
-    Jump(error);
-    UNREACHABLE();
   }
 
-  if ((FLAG_disassemble || FLAG_disassemble_optimized) &&
-      FlowGraphPrinter::ShouldPrint(parsed_function->function())) {
-    Code& code = Code::Handle(parsed_function->function().CurrentCode());
-    Disassembler::DisassembleCode(parsed_function->function(), code,
-                                  /* optimized = */ true);
+  if (field.has_nontrivial_initializer() &&
+      (field.is_static() || field.is_late())) {
+    const Function& initializer =
+        Function::ZoneHandle(Z, field.EnsureInitializerFunction());
+    AddFunction(initializer);
   }
-
-  ASSERT(Error::Handle(zone, thread->sticky_error()).IsNull());
-  return parsed_function->function().raw();
 }
 
 bool Precompiler::MustRetainFunction(const Function& function) {
@@ -1272,7 +1182,7 @@
 
           if ((type == EntryPointPragma::kAlways ||
                type == EntryPointPragma::kGetterOnly) &&
-              function.kind() != RawFunction::kConstructor &&
+              function.kind() != FunctionLayout::kConstructor &&
               !function.IsSetterFunction()) {
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
@@ -1282,7 +1192,7 @@
             AddInstantiatedClass(cls);
           }
         }
-        if (function.kind() == RawFunction::kImplicitGetter &&
+        if (function.kind() == FunctionLayout::kImplicitGetter &&
             !implicit_getters.IsNull()) {
           for (intptr_t i = 0; i < implicit_getters.Length(); ++i) {
             field ^= implicit_getters.At(i);
@@ -1291,7 +1201,7 @@
             }
           }
         }
-        if (function.kind() == RawFunction::kImplicitSetter &&
+        if (function.kind() == FunctionLayout::kImplicitSetter &&
             !implicit_setters.IsNull()) {
           for (intptr_t i = 0; i < implicit_setters.Length(); ++i) {
             field ^= implicit_setters.At(i);
@@ -1300,7 +1210,7 @@
             }
           }
         }
-        if (function.kind() == RawFunction::kImplicitStaticGetter &&
+        if (function.kind() == FunctionLayout::kImplicitStaticGetter &&
             !implicit_static_getters.IsNull()) {
           for (intptr_t i = 0; i < implicit_static_getters.Length(); ++i) {
             field ^= implicit_static_getters.At(i);
@@ -1352,7 +1262,7 @@
           AddFunction(function);
         }
         if (IsHitByTableSelector(function)) {
-          AddFunction(function, FLAG_retain_dispatched_functions);
+          AddFunction(function, FLAG_retain_function_objects);
         }
 
         bool found_metadata = false;
@@ -1372,7 +1282,7 @@
           if (IsSent(selector3)) {
             AddFunction(function);
           }
-        } else if (function.kind() == RawFunction::kRegularFunction) {
+        } else if (function.kind() == FunctionLayout::kRegularFunction) {
           selector2 = Field::LookupGetterSymbol(selector);
           if (IsSent(selector2)) {
             metadata = kernel::ProcedureAttributesOf(function, Z);
@@ -1391,12 +1301,12 @@
           }
         }
 
-        if (function.kind() == RawFunction::kImplicitSetter ||
-            function.kind() == RawFunction::kSetterFunction ||
-            function.kind() == RawFunction::kRegularFunction) {
+        if (function.kind() == FunctionLayout::kImplicitSetter ||
+            function.kind() == FunctionLayout::kSetterFunction ||
+            function.kind() == FunctionLayout::kRegularFunction) {
           selector2 = Function::CreateDynamicInvocationForwarderName(selector);
           if (IsSent(selector2)) {
-            if (function.kind() == RawFunction::kImplicitSetter) {
+            if (function.kind() == FunctionLayout::kImplicitSetter) {
               field = function.accessor_field();
               metadata = kernel::ProcedureAttributesOf(field, Z);
             } else if (!found_metadata) {
@@ -1424,7 +1334,7 @@
            String::Cast(a).Equals(String::Cast(b));
   }
   static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); }
-  static RawObject* NewKey(const String& str) { return str.raw(); }
+  static ObjectPtr NewKey(const String& str) { return str.raw(); }
 };
 
 typedef UnorderedHashMap<NameFunctionsTraits> Table;
@@ -1576,6 +1486,85 @@
   }
 }
 
+void Precompiler::FinalizeDispatchTable() {
+  if (!FLAG_use_bare_instructions || !FLAG_use_table_dispatch) return;
+  // Build the entries used to serialize the dispatch table before
+  // dropping functions, as we may clear references to Code objects.
+  const auto& entries =
+      Array::Handle(Z, dispatch_table_generator_->BuildCodeArray());
+  I->object_store()->set_dispatch_table_code_entries(entries);
+  // Delete the dispatch table generator to ensure there's no attempt
+  // to add new entries after this point.
+  delete dispatch_table_generator_;
+  dispatch_table_generator_ = nullptr;
+
+  if (FLAG_retain_function_objects || !FLAG_trace_precompiler) return;
+
+  FunctionSet printed(HashTables::New<FunctionSet>(/*initial_capacity=*/1024));
+  auto& code = Code::Handle(Z);
+  auto& function = Function::Handle(Z);
+  for (intptr_t i = 0; i < entries.Length(); i++) {
+    code = Code::RawCast(entries.At(i));
+    if (code.IsNull()) continue;
+    if (!code.IsFunctionCode()) continue;
+    function = code.function();
+    ASSERT(!function.IsNull());
+    if (printed.ContainsKey(function)) continue;
+    if (functions_to_retain_.ContainsKey(function)) continue;
+    THR_Print("Dispatch table references code for function to drop: %s\n",
+              function.ToLibNamePrefixedQualifiedCString());
+    printed.Insert(function);
+  }
+  printed.Release();
+}
+
+void Precompiler::ReplaceFunctionPCRelativeCallEntries() {
+  class StaticCallTableEntryFixer : public CodeVisitor {
+   public:
+    explicit StaticCallTableEntryFixer(Zone* zone)
+        : table_(Array::Handle(zone)),
+          kind_and_offset_(Smi::Handle(zone)),
+          target_function_(Function::Handle(zone)),
+          target_code_(Code::Handle(zone)) {}
+
+    void VisitCode(const Code& code) {
+      if (!code.IsFunctionCode()) return;
+      table_ = code.static_calls_target_table();
+      StaticCallsTable static_calls(table_);
+      for (auto& view : static_calls) {
+        kind_and_offset_ = view.Get<Code::kSCallTableKindAndOffset>();
+        auto const kind = Code::KindField::decode(kind_and_offset_.Value());
+        if (kind != Code::kPcRelativeCall) continue;
+
+        target_function_ = view.Get<Code::kSCallTableFunctionTarget>();
+        if (target_function_.IsNull()) continue;
+
+        ASSERT(view.Get<Code::kSCallTableCodeOrTypeTarget>() == Code::null());
+        ASSERT(target_function_.HasCode());
+        target_code_ = target_function_.CurrentCode();
+        ASSERT(!target_code_.IsStubCode());
+        view.Set<Code::kSCallTableCodeOrTypeTarget>(target_code_);
+        view.Set<Code::kSCallTableFunctionTarget>(Object::null_function());
+        if (FLAG_trace_precompiler) {
+          THR_Print("Updated static call entry to %s in \"%s\"\n",
+                    target_function_.ToFullyQualifiedCString(),
+                    code.ToCString());
+        }
+      }
+    }
+
+   private:
+    Array& table_;
+    Smi& kind_and_offset_;
+    Function& target_function_;
+    Code& target_code_;
+  };
+
+  HANDLESCOPE(T);
+  StaticCallTableEntryFixer visitor(Z);
+  ProgramVisitor::WalkProgram(Z, I, &visitor);
+}
+
 void Precompiler::DropFunctions() {
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
@@ -1722,7 +1711,7 @@
                               GrowableHandlePtrArray<const AbstractType>* types)
           : type_(AbstractType::Handle(zone)), types_(types) {}
 
-      void VisitObject(RawObject* obj) {
+      void VisitObject(ObjectPtr obj) {
         if (obj->GetClassId() == kTypeCid || obj->GetClassId() == kTypeRefCid) {
           type_ ^= obj;
           types_->Add(type_);
@@ -2054,7 +2043,6 @@
 void Precompiler::DropClasses() {
   Class& cls = Class::Handle(Z);
   Array& constants = Array::Handle(Z);
-  const Script& null_script = Script::Handle(Z);
 
   // We are about to remove classes from the class table. For this to be safe,
   // there must be no instances of these classes on the heap, not even
@@ -2097,7 +2085,6 @@
 
     class_table->Unregister(cid);
     cls.set_id(kIllegalCid);  // We check this when serializing.
-    cls.set_script(null_script);
   }
 }
 
@@ -2108,7 +2095,6 @@
       Library::Handle(Z, I->object_store()->root_library());
   Library& lib = Library::Handle(Z);
   Class& toplevel_class = Class::Handle(Z);
-  const Script& null_script = Script::Handle(Z);
 
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
     lib ^= libraries_.At(i);
@@ -2146,7 +2132,6 @@
 
       I->class_table()->Unregister(toplevel_class.id());
       toplevel_class.set_id(kIllegalCid);  // We check this when serializing.
-      toplevel_class.set_script(null_script);
 
       dropped_library_count_++;
       lib.set_index(-1);
@@ -2173,7 +2158,7 @@
 typedef UnorderedHashSet<CodeKeyTraits> CodeSet;
 
 #if defined(DEBUG)
-RawFunction* Precompiler::FindUnvisitedRetainedFunction() {
+FunctionPtr Precompiler::FindUnvisitedRetainedFunction() {
   class CodeChecker : public CodeVisitor {
    public:
     CodeChecker()
@@ -2182,14 +2167,14 @@
 
     const CodeSet& visited() const { return visited_code_; }
 
-    void Visit(const Code& code) { visited_code_.Insert(code); }
+    void VisitCode(const Code& code) { visited_code_.Insert(code); }
 
    private:
     CodeSet visited_code_;
   };
 
   CodeChecker visitor;
-  ProgramVisitor::VisitCode(&visitor);
+  ProgramVisitor::WalkProgram(Z, I, &visitor);
   const CodeSet& visited = visitor.visited();
 
   FunctionSet::Iterator it(&functions_to_retain_);
@@ -2216,7 +2201,7 @@
                               GrowableHandlePtrArray<const Script>* scripts)
         : script_(Script::Handle(zone)), scripts_(scripts) {}
 
-    void VisitObject(RawObject* obj) {
+    void VisitObject(ObjectPtr obj) {
       if (obj->GetClassId() == kScriptCid) {
         script_ ^= obj;
         scripts_->Add(Script::Cast(script_));
@@ -2579,10 +2564,10 @@
   return is_compiled;
 }
 
-static RawError* PrecompileFunctionHelper(Precompiler* precompiler,
-                                          CompilationPipeline* pipeline,
-                                          const Function& function,
-                                          bool optimized) {
+static ErrorPtr PrecompileFunctionHelper(Precompiler* precompiler,
+                                         CompilationPipeline* pipeline,
+                                         const Function& function,
+                                         bool optimized) {
   // Check that we optimize, except if the function is not optimizable.
   ASSERT(CompilerState::Current().is_aot());
   ASSERT(!function.IsOptimizable() || optimized);
@@ -2654,10 +2639,10 @@
   return Error::null();
 }
 
-RawError* Precompiler::CompileFunction(Precompiler* precompiler,
-                                       Thread* thread,
-                                       Zone* zone,
-                                       const Function& function) {
+ErrorPtr Precompiler::CompileFunction(Precompiler* precompiler,
+                                      Thread* thread,
+                                      Zone* zone,
+                                      const Function& function) {
   VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
   TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
 
@@ -2796,8 +2781,8 @@
   PreventRenaming("_NamespaceImpl");
 }
 
-RawString* Obfuscator::ObfuscationState::RenameImpl(const String& name,
-                                                    bool atomic) {
+StringPtr Obfuscator::ObfuscationState::RenameImpl(const String& name,
+                                                   bool atomic) {
   ASSERT(name.IsSymbol());
 
   renamed_ ^= renames_.GetOrNull(name);
@@ -2873,7 +2858,7 @@
   }
 }
 
-RawString* Obfuscator::ObfuscationState::NewAtomicRename(
+StringPtr Obfuscator::ObfuscationState::NewAtomicRename(
     bool should_be_private) {
   do {
     NextName();
@@ -2885,8 +2870,8 @@
   return renamed_.raw();
 }
 
-RawString* Obfuscator::ObfuscationState::BuildRename(const String& name,
-                                                     bool atomic) {
+StringPtr Obfuscator::ObfuscationState::BuildRename(const String& name,
+                                                    bool atomic) {
   if (atomic) {
     return NewAtomicRename(name.CharAt(0) == '_');
   }
@@ -3102,5 +3087,3 @@
 #endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
 
 }  // namespace dart
-
-#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 36a600d..c4135c4 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_AOT_PRECOMPILER_H_
 #define RUNTIME_VM_COMPILER_AOT_PRECOMPILER_H_
 
-#ifndef DART_PRECOMPILED_RUNTIME
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/allocation.h"
 #include "vm/compiler/aot/dispatch_table_generator.h"
@@ -23,7 +25,6 @@
 class Field;
 class Function;
 class GrowableObjectArray;
-class RawError;
 class SequenceNode;
 class String;
 class ParsedJSONObject;
@@ -190,14 +191,12 @@
 
 class Precompiler : public ValueObject {
  public:
-  static RawError* CompileAll();
+  static ErrorPtr CompileAll();
 
-  static RawError* CompileFunction(Precompiler* precompiler,
-                                   Thread* thread,
-                                   Zone* zone,
-                                   const Function& function);
-
-  static RawFunction* CompileStaticInitializer(const Field& field);
+  static ErrorPtr CompileFunction(Precompiler* precompiler,
+                                  Thread* thread,
+                                  Zone* zone,
+                                  const Function& function);
 
   // Returns true if get:runtimeType is not overloaded by any class.
   bool get_runtime_type_is_unique() const {
@@ -257,6 +256,8 @@
   void AttachOptimizedTypeTestingStub();
 
   void TraceForRetainedFunctions();
+  void FinalizeDispatchTable();
+  void ReplaceFunctionPCRelativeCallEntries();
   void DropFunctions();
   void DropFields();
   void TraceTypesFromRetainedClasses();
@@ -267,7 +268,7 @@
   void DropClasses();
   void DropLibraries();
 
-  DEBUG_ONLY(RawFunction* FindUnvisitedRetainedFunction());
+  DEBUG_ONLY(FunctionPtr FindUnvisitedRetainedFunction());
 
   void Obfuscate();
 
@@ -346,7 +347,7 @@
       return String::Cast(obj).Hash();
     }
   }
-  static RawObject* NewKey(const Function& function) { return function.raw(); }
+  static ObjectPtr NewKey(const Function& function) { return function.raw(); }
 };
 
 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
@@ -404,7 +405,7 @@
   //
   // This method is guaranteed to return the same value for the same
   // input and it always preserves leading '_' even for atomic renames.
-  RawString* Rename(const String& name, bool atomic = false) {
+  StringPtr Rename(const String& name, bool atomic = false) {
     if (state_ == NULL) {
       return name.raw();
     }
@@ -442,13 +443,13 @@
   static const intptr_t kSavedStateRenamesIndex = 1;
   static const intptr_t kSavedStateSize = 2;
 
-  static RawArray* GetRenamesFromSavedState(const Array& saved_state) {
+  static ArrayPtr GetRenamesFromSavedState(const Array& saved_state) {
     Array& renames = Array::Handle();
     renames ^= saved_state.At(kSavedStateRenamesIndex);
     return renames.raw();
   }
 
-  static RawString* GetNameFromSavedState(const Array& saved_state) {
+  static StringPtr GetNameFromSavedState(const Array& saved_state) {
     String& name = String::Handle();
     name ^= saved_state.At(kSavedStateNameIndex);
     return name.raw();
@@ -492,7 +493,7 @@
     //
     // This method is guaranteed to return the same value for the same
     // input.
-    RawString* RenameImpl(const String& name, bool atomic);
+    StringPtr RenameImpl(const String& name, bool atomic);
 
     // Register an identity (name -> name) mapping in the renaming map.
     //
@@ -509,11 +510,11 @@
     // For non-atomic renames BuildRename ensures that private mangled
     // identifiers (_ident@key) are renamed consistently with non-mangled
     // counterparts (_ident).
-    RawString* BuildRename(const String& name, bool atomic);
+    StringPtr BuildRename(const String& name, bool atomic);
 
     // Generate a new rename. If |should_be_private| is set to true
     // then we prefix returned identifier with '_'.
-    RawString* NewAtomicRename(bool should_be_private);
+    StringPtr NewAtomicRename(bool should_be_private);
 
     // Update next_ to generate the next free rename.
     void NextName();
@@ -547,7 +548,7 @@
   Obfuscator(Thread* thread, const String& private_key) {}
   ~Obfuscator() {}
 
-  RawString* Rename(const String& name, bool atomic = false) {
+  StringPtr Rename(const String& name, bool atomic = false) {
     return name.raw();
   }
 
@@ -561,6 +562,4 @@
 
 }  // namespace dart
 
-#endif  // DART_PRECOMPILED_RUNTIME
-
 #endif  // RUNTIME_VM_COMPILER_AOT_PRECOMPILER_H_
diff --git a/runtime/vm/compiler/api/deopt_id.h b/runtime/vm/compiler/api/deopt_id.h
new file mode 100644
index 0000000..c203e45
--- /dev/null
+++ b/runtime/vm/compiler/api/deopt_id.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_COMPILER_API_DEOPT_ID_H_
+#define RUNTIME_VM_COMPILER_API_DEOPT_ID_H_
+
+#include "platform/allocation.h"
+
+namespace dart {
+
+// Deoptimization Id logic.
+//
+// Deoptimization ids are used to refer to deoptimization points, at which
+// control can enter unoptimized code from the optimized version of the code.
+//
+// Note: any instruction that does a call has two deoptimization points,
+// one before the call and one after the call - so that we could deoptimize
+// to either before or after the call depending on whether the same call
+// already occured in the optimized code (and potentially produced
+// observable side-effects) or not.
+//
+// To simplify implementation we always allocate two deopt ids (one for before
+// point and one for the after point).
+class DeoptId : public AllStatic {
+ public:
+  static constexpr intptr_t kNone = -1;
+
+  static inline intptr_t Next(intptr_t deopt_id) { return deopt_id + kStep; }
+
+  static inline intptr_t ToDeoptAfter(intptr_t deopt_id) {
+    ASSERT(IsDeoptBefore(deopt_id));
+    return deopt_id + kAfterOffset;
+  }
+
+  static inline bool IsDeoptBefore(intptr_t deopt_id) {
+    return (deopt_id % kStep) == kBeforeOffset;
+  }
+
+  static inline bool IsDeoptAfter(intptr_t deopt_id) {
+    return (deopt_id % kStep) == kAfterOffset;
+  }
+
+ private:
+  static constexpr intptr_t kStep = 2;
+  static constexpr intptr_t kBeforeOffset = 0;
+  static constexpr intptr_t kAfterOffset = 1;
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_API_DEOPT_ID_H_
diff --git a/runtime/vm/compiler/api/print_filter.cc b/runtime/vm/compiler/api/print_filter.cc
new file mode 100644
index 0000000..ee2a06f
--- /dev/null
+++ b/runtime/vm/compiler/api/print_filter.cc
@@ -0,0 +1,70 @@
+// 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.
+#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
+
+#include "vm/compiler/api/print_filter.h"
+
+#include "vm/flags.h"
+#include "vm/object.h"
+
+namespace dart {
+
+DEFINE_FLAG(charp,
+            print_flow_graph_filter,
+            NULL,
+            "Print only IR of functions with matching names");
+
+namespace compiler {
+
+// Checks whether function's name matches the given filter, which is
+// a comma-separated list of strings.
+static bool PassesFilter(const char* filter, const Function& function) {
+  if (filter == NULL) {
+    return true;
+  }
+
+  char* save_ptr;  // Needed for strtok_r.
+  const char* scrubbed_name =
+      String::Handle(function.QualifiedScrubbedName()).ToCString();
+  const char* function_name = function.ToFullyQualifiedCString();
+  intptr_t function_name_len = strlen(function_name);
+
+  intptr_t len = strlen(filter) + 1;  // Length with \0.
+  char* filter_buffer = new char[len];
+  strncpy(filter_buffer, filter, len);  // strtok modifies arg 1.
+  char* token = strtok_r(filter_buffer, ",", &save_ptr);
+  bool found = false;
+  while (token != NULL) {
+    if ((strstr(function_name, token) != NULL) ||
+        (strstr(scrubbed_name, token) != NULL)) {
+      found = true;
+      break;
+    }
+    const intptr_t token_len = strlen(token);
+    if (token[token_len - 1] == '%') {
+      if (function_name_len > token_len) {
+        const char* suffix =
+            function_name + (function_name_len - token_len + 1);
+        if (strncmp(suffix, token, token_len - 1) == 0) {
+          found = true;
+          break;
+        }
+      }
+    }
+    token = strtok_r(NULL, ",", &save_ptr);
+  }
+  delete[] filter_buffer;
+
+  return found;
+}
+
+bool PrintFilter::ShouldPrint(const Function& function) {
+  return PassesFilter(FLAG_print_flow_graph_filter, function);
+}
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
diff --git a/runtime/vm/compiler/api/print_filter.h b/runtime/vm/compiler/api/print_filter.h
new file mode 100644
index 0000000..1eea14a
--- /dev/null
+++ b/runtime/vm/compiler/api/print_filter.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_COMPILER_API_PRINT_FILTER_H_
+#define RUNTIME_VM_COMPILER_API_PRINT_FILTER_H_
+#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
+
+#include "platform/allocation.h"
+
+namespace dart {
+
+class Function;
+
+namespace compiler {
+
+class PrintFilter : public AllStatic {
+ public:
+  static bool ShouldPrint(const Function& function);
+};
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
+#endif  // RUNTIME_VM_COMPILER_API_PRINT_FILTER_H_
diff --git a/runtime/vm/compiler/api/type_check_mode.h b/runtime/vm/compiler/api/type_check_mode.h
new file mode 100644
index 0000000..7710607
--- /dev/null
+++ b/runtime/vm/compiler/api/type_check_mode.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_COMPILER_API_TYPE_CHECK_MODE_H_
+#define RUNTIME_VM_COMPILER_API_TYPE_CHECK_MODE_H_
+
+namespace dart {
+
+// Invocation mode for TypeCheck runtime entry that describes
+// where we are calling it from.
+enum TypeCheckMode {
+  // TypeCheck is invoked from LazySpecializeTypeTest stub.
+  // It should replace stub on the type with a specialized version.
+  kTypeCheckFromLazySpecializeStub,
+
+  // TypeCheck is invoked from the SlowTypeTest stub.
+  // This means that cache can be lazily created (if needed)
+  // and dst_name can be fetched from the pool.
+  kTypeCheckFromSlowStub,
+
+  // TypeCheck is invoked from normal inline AssertAssignable.
+  // Both cache and dst_name must be already populated.
+  kTypeCheckFromInline
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_API_TYPE_CHECK_MODE_H_
diff --git a/runtime/vm/compiler/asm_intrinsifier.cc b/runtime/vm/compiler/asm_intrinsifier.cc
index 0886fe4..3e3957f 100644
--- a/runtime/vm/compiler/asm_intrinsifier.cc
+++ b/runtime/vm/compiler/asm_intrinsifier.cc
@@ -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.
 // Class for intrinsifying functions.
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
 #include "vm/compiler/asm_intrinsifier.h"
@@ -36,5 +33,3 @@
 
 }  // namespace compiler
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/asm_intrinsifier.h b/runtime/vm/compiler/asm_intrinsifier.h
index 59b3f63..01fd20d 100644
--- a/runtime/vm/compiler/asm_intrinsifier.h
+++ b/runtime/vm/compiler/asm_intrinsifier.h
@@ -6,6 +6,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASM_INTRINSIFIER_H_
 #define RUNTIME_VM_COMPILER_ASM_INTRINSIFIER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/compiler/recognized_methods_list.h"
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 6fe378e..531400e 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM)
 
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
@@ -127,10 +127,10 @@
   /* R1: new object end address. */                                            \
   /* R2: allocation size. */                                                   \
   {                                                                            \
-    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);            \
+    __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);         \
     __ mov(R3,                                                                 \
            Operand(R2, LSL,                                                    \
-                   target::RawObject::kTagBitsSizeTagPos -                     \
+                   target::ObjectLayout::kTagBitsSizeTagPos -                  \
                        target::ObjectAlignment::kObjectAlignmentLog2),         \
            LS);                                                                \
     __ mov(R3, Operand(0), HI);                                                \
@@ -1583,21 +1583,24 @@
   __ b(&not_double, NE);
 
   __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0, target::Isolate::object_store_offset());
+  __ LoadFromOffset(kWord, R0, R0,
+                    target::Isolate::cached_object_store_offset());
   __ LoadFromOffset(kWord, R0, R0, target::ObjectStore::double_type_offset());
   __ Ret();
 
   __ Bind(&not_double);
   JumpIfNotInteger(assembler, R1, R0, &not_integer);
   __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0, target::Isolate::object_store_offset());
+  __ LoadFromOffset(kWord, R0, R0,
+                    target::Isolate::cached_object_store_offset());
   __ LoadFromOffset(kWord, R0, R0, target::ObjectStore::int_type_offset());
   __ Ret();
 
   __ Bind(&not_integer);
   JumpIfNotString(assembler, R1, R0, &use_declaration_type);
   __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0, target::Isolate::object_store_offset());
+  __ LoadFromOffset(kWord, R0, R0,
+                    target::Isolate::cached_object_store_offset());
   __ LoadFromOffset(kWord, R0, R0, target::ObjectStore::string_type_offset());
   __ Ret();
 
@@ -2057,10 +2060,10 @@
   // R1: new object end address.
   // R2: allocation size.
   {
-    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+    const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
                            target::ObjectAlignment::kObjectAlignmentLog2;
 
-    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+    __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
     __ mov(R3, Operand(R2, LSL, shift), LS);
     __ mov(R3, Operand(0), HI);
 
@@ -2345,4 +2348,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index db838ee..82c487d 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM64)
 
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
@@ -149,9 +149,9 @@
   /* R1: new object end address. */                                            \
   /* R2: allocation size. */                                                   \
   {                                                                            \
-    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);            \
+    __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);         \
     __ LslImmediate(R2, R2,                                                    \
-                    target::RawObject::kTagBitsSizeTagPos -                    \
+                    target::ObjectLayout::kTagBitsSizeTagPos -                 \
                         target::ObjectAlignment::kObjectAlignmentLog2);        \
     __ csel(R2, ZR, R2, HI);                                                   \
                                                                                \
@@ -1648,21 +1648,21 @@
   __ b(&not_double, NE);
 
   __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::object_store_offset());
+  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::double_type_offset());
   __ ret();
 
   __ Bind(&not_double);
   JumpIfNotInteger(assembler, R1, R0, &not_integer);
   __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::object_store_offset());
+  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::int_type_offset());
   __ ret();
 
   __ Bind(&not_integer);
   JumpIfNotString(assembler, R1, R0, &use_declaration_type);
   __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::object_store_offset());
+  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::string_type_offset());
   __ ret();
 
@@ -2131,10 +2131,10 @@
   // R1: new object end address.
   // R2: allocation size.
   {
-    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+    const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
                            target::ObjectAlignment::kObjectAlignmentLog2;
 
-    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+    __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
     __ LslImmediate(R2, R2, shift);
     __ csel(R2, R2, ZR, LS);
 
@@ -2418,4 +2418,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index c4fb55b..45627cb 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -9,7 +9,7 @@
 // Dart method was intrinsified.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_IA32)
 
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
@@ -135,9 +135,9 @@
   /* EDI: allocation size. */                                                  \
   {                                                                            \
     Label size_tag_overflow, done;                                             \
-    __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));            \
+    __ cmpl(EDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));         \
     __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);                     \
-    __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -             \
+    __ shll(EDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -          \
                            target::ObjectAlignment::kObjectAlignmentLog2));    \
     __ jmp(&done, Assembler::kNearJump);                                       \
                                                                                \
@@ -1682,7 +1682,7 @@
   __ j(NOT_EQUAL, &not_double);
 
   __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::object_store_offset()));
+  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::double_type_offset()));
   __ ret();
 
@@ -1692,7 +1692,7 @@
   JumpIfNotInteger(assembler, EAX, &not_integer);
 
   __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::object_store_offset()));
+  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::int_type_offset()));
   __ ret();
 
@@ -1703,7 +1703,7 @@
   JumpIfNotString(assembler, EAX, &use_declaration_type);
 
   __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::object_store_offset()));
+  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::string_type_offset()));
   __ ret();
 
@@ -2075,9 +2075,9 @@
   // EDI: allocation size.
   {
     Label size_tag_overflow, done;
-    __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ cmpl(EDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
     __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+    __ shll(EDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
                            target::ObjectAlignment::kObjectAlignmentLog2));
     __ jmp(&done, Assembler::kNearJump);
 
@@ -2355,4 +2355,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 09b3e10..1305a35 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_X64)
 
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
@@ -137,9 +137,9 @@
   /* R13: scratch register. */                                                 \
   {                                                                            \
     Label size_tag_overflow, done;                                             \
-    __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));            \
+    __ cmpq(RDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));         \
     __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);                     \
-    __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -             \
+    __ shlq(RDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -          \
                            target::ObjectAlignment::kObjectAlignmentLog2));    \
     __ jmp(&done, Assembler::kNearJump);                                       \
                                                                                \
@@ -1594,7 +1594,7 @@
   __ j(NOT_EQUAL, &not_double);
 
   __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::object_store_offset()));
+  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::double_type_offset()));
   __ ret();
 
@@ -1604,7 +1604,7 @@
   JumpIfNotInteger(assembler, RAX, &not_integer);
 
   __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::object_store_offset()));
+  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::int_type_offset()));
   __ ret();
 
@@ -1615,7 +1615,7 @@
   JumpIfNotString(assembler, RAX, &use_declaration_type);
 
   __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::object_store_offset()));
+  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::string_type_offset()));
   __ ret();
 
@@ -2105,9 +2105,9 @@
   // RDI: allocation size.
   {
     Label size_tag_overflow, done;
-    __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ cmpq(RDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
     __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+    __ shlq(RDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
                            target::ObjectAlignment::kObjectAlignmentLog2));
     __ jmp(&done, Assembler::kNearJump);
 
@@ -2386,4 +2386,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/compiler/assembler/assembler.h b/runtime/vm/compiler/assembler/assembler.h
index f702109..336640a 100644
--- a/runtime/vm/compiler/assembler/assembler.h
+++ b/runtime/vm/compiler/assembler/assembler.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
 #define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_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/assembler/object_pool_builder.h"
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index a6ba5bd..df568a3 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // NOLINT
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM)
 
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
@@ -1592,7 +1592,6 @@
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
   ASSERT(IsOriginalObject(object));
-  ASSERT(!target::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
   }
@@ -1608,24 +1607,31 @@
                                  bool is_unique,
                                  Register pp) {
   ASSERT(IsOriginalObject(object));
-  intptr_t offset = 0;
-  if (target::CanLoadFromThread(object, &offset)) {
-    // Load common VM constants from the thread. This works also in places where
-    // no constant pool is set up (e.g. intrinsic code).
-    ldr(rd, Address(THR, offset), cond);
-  } else if (target::IsSmi(object)) {
-    // Relocation doesn't apply to Smis.
-    LoadImmediate(rd, target::ToRawSmi(object), cond);
-  } else if (CanLoadFromObjectPool(object)) {
-    // Make sure that class CallPattern is able to decode this load from the
-    // object pool.
-    const auto index = is_unique ? object_pool_builder().AddObject(object)
-                                 : object_pool_builder().FindObject(object);
-    const int32_t offset = target::ObjectPool::element_offset(index);
-    LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond);
-  } else {
-    UNREACHABLE();
+  // `is_unique == true` effectively means object has to be patchable.
+  if (!is_unique) {
+    intptr_t offset = 0;
+    if (target::CanLoadFromThread(object, &offset)) {
+      // Load common VM constants from the thread. This works also in places
+      // where no constant pool is set up (e.g. intrinsic code).
+      ldr(rd, Address(THR, offset), cond);
+      return;
+    }
+    if (target::IsSmi(object)) {
+      // Relocation doesn't apply to Smis.
+      LoadImmediate(rd, target::ToRawSmi(object), cond);
+      return;
+    }
   }
+  if (!CanLoadFromObjectPool(object)) {
+    UNREACHABLE();
+    return;
+  }
+  // Make sure that class CallPattern is able to decode this load from the
+  // object pool.
+  const auto index = is_unique ? object_pool_builder().AddObject(object)
+                               : object_pool_builder().FindObject(object);
+  const int32_t offset = target::ObjectPool::element_offset(index);
+  LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond);
 }
 
 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) {
@@ -1735,7 +1741,7 @@
   //    in progress
   // If so, call the WriteBarrier stub, which will either add object to the
   // store buffer (case 1) or add value to the marking stack (case 2).
-  // Compare RawObject::StorePointer.
+  // Compare ObjectLayout::StorePointer.
   Label done;
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
@@ -1743,7 +1749,7 @@
   if (!lr_reserved) Push(LR);
   ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
   ldrb(LR, FieldAddress(value, target::Object::tags_offset()));
-  and_(TMP, LR, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+  and_(TMP, LR, Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
   ldr(LR, Address(THR, target::Thread::write_barrier_mask_offset()));
   tst(TMP, Operand(LR));
   if (value != kWriteBarrierValueReg) {
@@ -1799,7 +1805,7 @@
   //    in progress
   // If so, call the WriteBarrier stub, which will either add object to the
   // store buffer (case 1) or add value to the marking stack (case 2).
-  // Compare RawObject::StorePointer.
+  // Compare ObjectLayout::StorePointer.
   Label done;
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
@@ -1807,7 +1813,7 @@
   if (!lr_reserved) Push(LR);
   ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
   ldrb(LR, FieldAddress(value, target::Object::tags_offset()));
-  and_(TMP, LR, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+  and_(TMP, LR, Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
   ldr(LR, Address(THR, target::Thread::write_barrier_mask_offset()));
   tst(TMP, Operand(LR));
 
@@ -1847,7 +1853,7 @@
   StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
 
   ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
-  tst(TMP, Operand(1 << target::RawObject::kOldAndNotRememberedBit));
+  tst(TMP, Operand(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   b(&done, ZERO);
 
   Stop("Store buffer update is required");
@@ -1967,20 +1973,39 @@
   str(value, dest);
 }
 
+void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
+  ASSERT(sizeof(classid_t) == sizeof(uint16_t));
+  Lsr(result, tags, Operand(target::ObjectLayout::kClassIdTagPos), AL);
+}
+
+void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
+  ASSERT(target::ObjectLayout::kSizeTagPos == 8);
+  ASSERT(target::ObjectLayout::kSizeTagSize == 8);
+  Lsr(result, tags,
+      Operand(target::ObjectLayout::kSizeTagPos -
+              target::ObjectAlignment::kObjectAlignmentLog2),
+      AL);
+  AndImmediate(result, result,
+               (Utils::NBitMask(target::ObjectLayout::kSizeTagSize)
+                << target::ObjectAlignment::kObjectAlignmentLog2));
+}
+
 void Assembler::LoadClassId(Register result, Register object, Condition cond) {
-  ASSERT(target::RawObject::kClassIdTagPos == 16);
-  ASSERT(target::RawObject::kClassIdTagSize == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
       target::Object::tags_offset() +
-      target::RawObject::kClassIdTagPos / kBitsPerByte;
+      target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
   ldrh(result, FieldAddress(object, class_id_offset), cond);
 }
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
 
-  const intptr_t table_offset = target::Isolate::class_table_offset() +
-                                target::ClassTable::table_offset();
+  const intptr_t table_offset =
+      target::Isolate::cached_class_table_table_offset();
 
   LoadIsolate(result);
   LoadFromOffset(kWord, result, result, table_offset);
@@ -2727,27 +2752,6 @@
   blx(IP);
 }
 
-void Assembler::CallNullErrorShared(bool save_fpu_registers) {
-  uword entry_point_offset =
-      save_fpu_registers
-          ? target::Thread::null_error_shared_with_fpu_regs_entry_point_offset()
-          : target::Thread::
-                null_error_shared_without_fpu_regs_entry_point_offset();
-  ldr(LR, Address(THR, entry_point_offset));
-  blx(LR);
-}
-
-void Assembler::CallNullArgErrorShared(bool save_fpu_registers) {
-  const uword entry_point_offset =
-      save_fpu_registers
-          ? target::Thread::
-                null_arg_error_shared_with_fpu_regs_entry_point_offset()
-          : target::Thread::
-                null_arg_error_shared_without_fpu_regs_entry_point_offset();
-  ldr(LR, Address(THR, entry_point_offset));
-  blx(LR);
-}
-
 void Assembler::BranchLinkWithEquivalence(const Code& target,
                                           const Object& equivalence,
                                           CodeEntryKind entry_kind) {
@@ -3459,7 +3463,7 @@
   LoadClassIdMayBeSmi(IP, R0);
   add(R2, R2, Operand(target::ToRawSmi(1)));
   cmp(R1, Operand(IP, LSL, 1));
-  Branch(Address(THR, target::Thread::monomorphic_miss_entry_offset()), NE);
+  Branch(Address(THR, target::Thread::switchable_call_miss_entry_offset()), NE);
   str(R2, FieldAddress(R9, count_offset));
   LoadImmediate(R4, 0);  // GC-safe for OptimizeInvokedFunction.
 
@@ -3488,7 +3492,7 @@
 
   LoadClassId(IP, R0);
   cmp(R9, Operand(IP, LSL, 1));
-  Branch(Address(THR, target::Thread::monomorphic_miss_entry_offset()), NE);
+  Branch(Address(THR, target::Thread::switchable_call_miss_entry_offset()), NE);
 
   // Fall through to unchecked entry.
   ASSERT_EQUAL(CodeSize() - start,
@@ -3525,8 +3529,7 @@
   ASSERT(cid > 0);
 
   const intptr_t shared_table_offset =
-      target::Isolate::class_table_offset() +
-      target::ClassTable::shared_class_table_offset();
+      target::Isolate::shared_class_table_offset();
   const intptr_t table_offset =
       target::SharedClassTable::class_heap_stats_table_offset();
   const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
@@ -3636,6 +3639,17 @@
   pattern.set_distance(offset_into_target);
 }
 
+void Assembler::GenerateUnRelocatedPcRelativeTailCall(
+    Condition cond,
+    intptr_t offset_into_target) {
+  // Emit "b <offset>".
+  EmitType5(cond, 0x686868, /*link=*/false);
+
+  PcRelativeTailCallPattern pattern(buffer_.contents() + buffer_.Size() -
+                                    PcRelativeTailCallPattern::kLengthInBytes);
+  pattern.set_distance(offset_into_target);
+}
+
 Address Assembler::ElementAddressForIntIndex(bool is_load,
                                              bool is_external,
                                              intptr_t cid,
@@ -3741,6 +3755,15 @@
   }
 }
 
+void Assembler::LoadFieldAddressForRegOffset(Register address,
+                                             Register instance,
+                                             Register offset_in_words_as_smi) {
+  add(address, instance,
+      Operand(offset_in_words_as_smi, LSL,
+              target::kWordSizeLog2 - kSmiTagShift));
+  AddImmediate(address, -kHeapObjectTag);
+}
+
 void Assembler::LoadHalfWordUnaligned(Register dst,
                                       Register addr,
                                       Register tmp) {
@@ -3791,4 +3814,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 5f8ee9c..ebaaf28 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_ARM_H_
 #define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_ARM_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
 #error Do not include assembler_arm.h directly; use assembler.h instead.
 #endif
@@ -589,8 +593,6 @@
            B4 | (imm16 & 0xf);
   }
 
-  static uword GetBreakInstructionFiller() { return BkptEncoding(0); }
-
   // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
   void vmovsr(SRegister sn, Register rt, Condition cond = AL);
   void vmovrs(Register rt, SRegister sn, Condition cond = AL);
@@ -735,10 +737,6 @@
                   CodeEntryKind entry_kind = CodeEntryKind::kNormal);
   void BranchLinkToRuntime();
 
-  void CallNullErrorShared(bool save_fpu_registers);
-
-  void CallNullArgErrorShared(bool save_fpu_registers);
-
   // Branch and link to an entry address. Call sequence can be patched.
   void BranchLinkPatchable(const Code& code,
                            CodeEntryKind entry_kind = CodeEntryKind::kNormal);
@@ -753,6 +751,11 @@
   // Branch and link to [base + offset]. Call sequence is never patched.
   void BranchLinkOffset(Register base, int32_t offset);
 
+  void Call(Address target) {
+    ldr(LR, target);
+    blx(LR);
+  }
+
   // Add signed immediate value to rd. May clobber IP.
   void AddImmediate(Register rd, int32_t value, Condition cond = AL) {
     AddImmediate(rd, rd, value, cond);
@@ -820,7 +823,7 @@
   void LoadWordFromPoolOffset(Register rd,
                               int32_t offset,
                               Register pp,
-                              Condition cond);
+                              Condition cond = AL);
 
   void LoadObject(Register rd, const Object& object, Condition cond = AL);
   void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL);
@@ -900,6 +903,9 @@
   // Stores a Smi value into a heap object field that always contains a Smi.
   void StoreIntoSmiField(const Address& dest, Register value);
 
+  void ExtractClassIdFromTags(Register result, Register tags);
+  void ExtractInstanceSizeFromTags(Register result, Register tags);
+
   void LoadClassId(Register result, Register object, Condition cond = AL);
   void LoadClassById(Register result, Register class_id);
   void CompareClassId(Register object, intptr_t class_id, Register scratch);
@@ -1165,6 +1171,10 @@
                                      Register array,
                                      Register index);
 
+  void LoadFieldAddressForRegOffset(Register address,
+                                    Register instance,
+                                    Register offset_in_words_as_smi);
+
   void LoadHalfWordUnaligned(Register dst, Register addr, Register tmp);
   void LoadHalfWordUnsignedUnaligned(Register dst, Register addr, Register tmp);
   void StoreHalfWordUnaligned(Register src, Register addr, Register tmp);
@@ -1192,13 +1202,13 @@
                         Register temp1,
                         Register temp2);
 
-  // This emits an PC-relative call of the form "blr <offset>".  The offset
-  // is not yet known and needs therefore relocation to the right place before
-  // the code can be used.
+  // This emits an PC-relative call of the form "blr.<cond> <offset>".  The
+  // offset is not yet known and needs therefore relocation to the right place
+  // before the code can be used.
   //
   // The neccessary information for the "linker" (i.e. the relocation
-  // information) is stored in [RawCode::static_calls_target_table_]: an entry
-  // of the form
+  // information) is stored in [CodeLayout::static_calls_target_table_]: an
+  // entry of the form
   //
   //   (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
   //
@@ -1210,6 +1220,12 @@
   void GenerateUnRelocatedPcRelativeCall(Condition cond = AL,
                                          intptr_t offset_into_target = 0);
 
+  // This emits an PC-relative tail call of the form "b.<cond> <offset>".
+  //
+  // See also above for the pc-relative call.
+  void GenerateUnRelocatedPcRelativeTailCall(Condition cond = AL,
+                                             intptr_t offset_into_target = 0);
+
   // Emit data (e.g encoded instruction or immediate) in instruction stream.
   void Emit(int32_t value);
 
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index ddfa229..c0cadfd 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // NOLINT
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM64)
 
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
@@ -430,7 +430,6 @@
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
   ASSERT(IsOriginalObject(object));
-  ASSERT(!target::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
   }
@@ -464,20 +463,36 @@
                                  const Object& object,
                                  bool is_unique) {
   ASSERT(IsOriginalObject(object));
-  word offset = 0;
-  if (IsSameObject(compiler::NullObject(), object)) {
-    mov(dst, NULL_REG);
-  } else if (target::CanLoadFromThread(object, &offset)) {
-    ldr(dst, Address(THR, offset));
-  } else if (CanLoadFromObjectPool(object)) {
+  // `is_unique == true` effectively means object has to be patchable.
+  // (even if the object is null)
+  if (!is_unique) {
+    if (IsSameObject(compiler::NullObject(), object)) {
+      mov(dst, NULL_REG);
+      return;
+    }
+    if (IsSameObject(CastHandle<Object>(compiler::TrueObject()), object)) {
+      AddImmediate(dst, NULL_REG, kTrueOffsetFromNull);
+      return;
+    }
+    if (IsSameObject(CastHandle<Object>(compiler::FalseObject()), object)) {
+      AddImmediate(dst, NULL_REG, kFalseOffsetFromNull);
+      return;
+    }
+    word offset = 0;
+    if (target::CanLoadFromThread(object, &offset)) {
+      ldr(dst, Address(THR, offset));
+      return;
+    }
+  }
+  if (CanLoadFromObjectPool(object)) {
     const int32_t offset = target::ObjectPool::element_offset(
         is_unique ? object_pool_builder().AddObject(object)
                   : object_pool_builder().FindObject(object));
     LoadWordFromPoolOffset(dst, offset);
-  } else {
-    ASSERT(target::IsSmi(object));
-    LoadImmediate(dst, target::ToRawSmi(object));
+    return;
   }
+  ASSERT(target::IsSmi(object));
+  LoadImmediate(dst, target::ToRawSmi(object));
 }
 
 void Assembler::LoadObject(Register dst, const Object& object) {
@@ -636,27 +651,6 @@
   blr(TMP);
 }
 
-void Assembler::CallNullErrorShared(bool save_fpu_registers) {
-  uword entry_point_offset =
-      save_fpu_registers
-          ? target::Thread::null_error_shared_with_fpu_regs_entry_point_offset()
-          : target::Thread::
-                null_error_shared_without_fpu_regs_entry_point_offset();
-  ldr(LR, Address(THR, entry_point_offset));
-  blr(LR);
-}
-
-void Assembler::CallNullArgErrorShared(bool save_fpu_registers) {
-  const uword entry_point_offset =
-      save_fpu_registers
-          ? target::Thread::
-                null_arg_error_shared_with_fpu_regs_entry_point_offset()
-          : target::Thread::
-                null_arg_error_shared_without_fpu_regs_entry_point_offset();
-  ldr(LR, Address(THR, entry_point_offset));
-  blr(LR);
-}
-
 void Assembler::AddImmediate(Register dest, Register rn, int64_t imm) {
   Operand op;
   if (imm == 0) {
@@ -988,14 +982,15 @@
   //    in progress
   // If so, call the WriteBarrier stub, which will either add object to the
   // store buffer (case 1) or add value to the marking stack (case 2).
-  // Compare RawObject::StorePointer.
+  // Compare ObjectLayout::StorePointer.
   Label done;
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
   }
   ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
   ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
-  and_(TMP, TMP2, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+  and_(TMP, TMP2,
+       Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
   tst(TMP, Operand(BARRIER_MASK));
   b(&done, ZERO);
 
@@ -1049,14 +1044,15 @@
   //    in progress
   // If so, call the WriteBarrier stub, which will either add object to the
   // store buffer (case 1) or add value to the marking stack (case 2).
-  // Compare RawObject::StorePointer.
+  // Compare ObjectLayout::StorePointer.
   Label done;
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
   }
   ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
   ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
-  and_(TMP, TMP2, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+  and_(TMP, TMP2,
+       Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
   tst(TMP, Operand(BARRIER_MASK));
   b(&done, ZERO);
   if (!lr_reserved) Push(LR);
@@ -1082,7 +1078,7 @@
   StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
 
   ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
-  tsti(TMP, Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+  tsti(TMP, Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   b(&done, ZERO);
 
   Stop("Store buffer update is required");
@@ -1133,12 +1129,27 @@
   str(value, dest);
 }
 
+void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
+  ASSERT(sizeof(classid_t) == sizeof(uint16_t));
+  LsrImmediate(result, tags, target::ObjectLayout::kClassIdTagPos, kWord);
+}
+
+void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
+  ASSERT(target::ObjectLayout::kSizeTagPos == 8);
+  ASSERT(target::ObjectLayout::kSizeTagSize == 8);
+  ubfx(result, tags, target::ObjectLayout::kSizeTagPos,
+       target::ObjectLayout::kSizeTagSize);
+  LslImmediate(result, result, target::ObjectAlignment::kObjectAlignmentLog2);
+}
+
 void Assembler::LoadClassId(Register result, Register object) {
-  ASSERT(target::RawObject::kClassIdTagPos == 16);
-  ASSERT(target::RawObject::kClassIdTagSize == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
       target::Object::tags_offset() +
-      target::RawObject::kClassIdTagPos / kBitsPerByte;
+      target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
   LoadFromOffset(result, object, class_id_offset - kHeapObjectTag,
                  kUnsignedHalfword);
 }
@@ -1146,8 +1157,8 @@
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
 
-  const intptr_t table_offset = target::Isolate::class_table_offset() +
-                                target::ClassTable::table_offset();
+  const intptr_t table_offset =
+      target::Isolate::cached_class_table_table_offset();
 
   LoadIsolate(result);
   LoadFromOffset(result, result, table_offset);
@@ -1270,10 +1281,10 @@
 // register within our generated code to avoid the alignment requirement.
 // Note that Fuchsia does not have signal handlers.
 
-void Assembler::SetupDartSP() {
+void Assembler::SetupDartSP(intptr_t reserve /* = 4096 */) {
   mov(SP, CSP);
   // The caller doesn't have a Thread available. Just kick CSP forward a bit.
-  AddImmediate(CSP, CSP, -4096);
+  AddImmediate(CSP, CSP, -Utils::RoundUp(reserve, 16));
 }
 
 void Assembler::SetupCSPFromThread(Register thr) {
@@ -1549,7 +1560,7 @@
 
   Label immediate, miss;
   Bind(&miss);
-  ldr(IP0, Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  ldr(IP0, Address(THR, target::Thread::switchable_call_miss_entry_offset()));
   br(IP0);
 
   Comment("MonomorphicCheckedEntry");
@@ -1567,7 +1578,7 @@
   cmp(R1, Operand(IP0, LSL, 1));
   b(&miss, NE);
   str(R2, FieldAddress(R5, count_offset));
-  LoadImmediate(R4, 0);  // GC-safe for OptimizeInvokedFunction.
+  LoadImmediate(R4, 0);  // GC-safe for OptimizeInvokedFunction
 
   // Fall through to unchecked entry.
   ASSERT_EQUAL(CodeSize() - start,
@@ -1587,7 +1598,7 @@
 
   Label immediate, miss;
   Bind(&miss);
-  ldr(IP0, Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  ldr(IP0, Address(THR, target::Thread::switchable_call_miss_entry_offset()));
   br(IP0);
 
   Comment("MonomorphicCheckedEntry");
@@ -1622,8 +1633,7 @@
   ASSERT(cid > 0);
 
   const intptr_t shared_table_offset =
-      target::Isolate::class_table_offset() +
-      target::ClassTable::shared_class_table_offset();
+      target::Isolate::shared_class_table_offset();
   const intptr_t table_offset =
       target::SharedClassTable::class_heap_stats_table_offset();
   const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
@@ -1737,6 +1747,15 @@
   pattern.set_distance(offset_into_target);
 }
 
+void Assembler::GenerateUnRelocatedPcRelativeTailCall(
+    intptr_t offset_into_target) {
+  // Emit "b <offset>".
+  EmitUnconditionalBranchOp(B, 0);
+  PcRelativeTailCallPattern pattern(buffer_.contents() + buffer_.Size() -
+                                    PcRelativeTailCallPattern::kLengthInBytes);
+  pattern.set_distance(offset_into_target);
+}
+
 Address Assembler::ElementAddressForIntIndex(bool is_external,
                                              intptr_t cid,
                                              intptr_t index_scale,
@@ -1821,6 +1840,15 @@
   }
 }
 
+void Assembler::LoadFieldAddressForRegOffset(Register address,
+                                             Register instance,
+                                             Register offset_in_words_as_smi) {
+  add(address, instance,
+      Operand(offset_in_words_as_smi, LSL,
+              target::kWordSizeLog2 - kSmiTagShift));
+  AddImmediate(address, -kHeapObjectTag);
+}
+
 void Assembler::PushRegisters(const RegisterSet& regs) {
   const intptr_t fpu_regs_count = regs.FpuRegisterCount();
   if (fpu_regs_count > 0) {
@@ -1967,4 +1995,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index d83aa8e..1b30517 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_ARM64_H_
 #define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_ARM64_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
 #error Do not include assembler_arm64.h directly; use assembler.h instead.
 #endif
@@ -468,7 +472,7 @@
   void Drop(intptr_t stack_elements) {
     ASSERT(stack_elements >= 0);
     if (stack_elements > 0) {
-      add(SP, SP, Operand(stack_elements * target::kWordSize));
+      AddImmediate(SP, SP, stack_elements * target::kWordSize);
     }
   }
 
@@ -1034,11 +1038,6 @@
   // Breakpoint.
   void brk(uint16_t imm) { EmitExceptionGenOp(BRK, imm); }
 
-  static uword GetBreakInstructionFiller() {
-    const intptr_t encoding = ExceptionGenOpEncoding(BRK, 0);
-    return encoding << 32 | encoding;
-  }
-
   // Double floating point.
   bool fmovdi(VRegister vd, double immd) {
     int64_t imm64 = bit_cast<int64_t, double>(immd);
@@ -1406,10 +1405,6 @@
   }
   void BranchLinkToRuntime();
 
-  void CallNullErrorShared(bool save_fpu_registers);
-
-  void CallNullArgErrorShared(bool save_fpu_registers);
-
   // Emit a call that shares its object pool entries with other calls
   // that have the same equivalence marker.
   void BranchLinkWithEquivalence(
@@ -1417,6 +1412,11 @@
       const Object& equivalence,
       CodeEntryKind entry_kind = CodeEntryKind::kNormal);
 
+  void Call(Address target) {
+    ldr(LR, target);
+    blr(LR);
+  }
+
   void AddImmediate(Register dest, int64_t imm) {
     AddImmediate(dest, dest, imm);
   }
@@ -1571,6 +1571,9 @@
   }
   void CompareObject(Register reg, const Object& object);
 
+  void ExtractClassIdFromTags(Register result, Register tags);
+  void ExtractInstanceSizeFromTags(Register result, Register tags);
+
   void LoadClassId(Register result, Register object);
   void LoadClassById(Register result, Register class_id);
   void CompareClassId(Register object,
@@ -1580,7 +1583,8 @@
   void LoadClassIdMayBeSmi(Register result, Register object);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
-  void SetupDartSP();
+  // Reserve specifies how much space to reserve for the Dart stack.
+  void SetupDartSP(intptr_t reserve = 4096);
   void SetupCSPFromThread(Register thr);
   void RestoreCSP();
 
@@ -1657,8 +1661,8 @@
   // the code can be used.
   //
   // The neccessary information for the "linker" (i.e. the relocation
-  // information) is stored in [RawCode::static_calls_target_table_]: an entry
-  // of the form
+  // information) is stored in [CodeLayout::static_calls_target_table_]: an
+  // entry of the form
   //
   //   (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
   //
@@ -1669,6 +1673,11 @@
   // function.
   void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target = 0);
 
+  // This emits an PC-relative tail call of the form "b <offset>".
+  //
+  // See also above for the pc-relative call.
+  void GenerateUnRelocatedPcRelativeTailCall(intptr_t offset_into_target = 0);
+
   Address ElementAddressForIntIndex(bool is_external,
                                     intptr_t cid,
                                     intptr_t index_scale,
@@ -1708,6 +1717,10 @@
                                         Register array,
                                         Register index);
 
+  void LoadFieldAddressForRegOffset(Register address,
+                                    Register instance,
+                                    Register offset_in_words_as_smi);
+
   // Returns object data offset for address calculation; for heap objects also
   // accounts for the tag.
   static int32_t HeapDataOffset(bool is_external, intptr_t cid) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index 11c255f..e133f9f 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -2551,7 +2551,8 @@
 }
 
 ASSEMBLER_TEST_RUN(LoadObjectNull, test) {
-  EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<RawObject*>());
+  EXPECT_EQ(static_cast<uword>(Object::null()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 // PushObject null.
@@ -2566,7 +2567,8 @@
 }
 
 ASSEMBLER_TEST_RUN(PushObjectNull, test) {
-  EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<RawObject*>());
+  EXPECT_EQ(static_cast<uword>(Object::null()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 // CompareObject null.
@@ -2584,7 +2586,8 @@
 }
 
 ASSEMBLER_TEST_RUN(CompareObjectNull, test) {
-  EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<RawObject*>());
+  EXPECT_EQ(static_cast<uword>(Bool::True().raw()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
@@ -2597,7 +2600,8 @@
 }
 
 ASSEMBLER_TEST_RUN(LoadObjectTrue, test) {
-  EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<RawObject*>());
+  EXPECT_EQ(static_cast<uword>(Bool::True().raw()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
@@ -2610,7 +2614,8 @@
 }
 
 ASSEMBLER_TEST_RUN(LoadObjectFalse, test) {
-  EXPECT_EQ(Bool::False().raw(), test->InvokeWithCodeAndThread<RawObject*>());
+  EXPECT_EQ(static_cast<uword>(Bool::False().raw()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 ASSEMBLER_TEST_GENERATE(CSelTrue, assembler) {
@@ -4556,6 +4561,29 @@
   __ ret();
 }
 
+// Push numbers from kMaxPushedNumber to 0 to the stack then drop top
+// kMaxPushedNumber elements. This should leave just kMaxPushedNumber on the
+// stack.
+const intptr_t kMaxPushedNumber = 913;
+
+ASSEMBLER_TEST_GENERATE(Drop, assembler) {
+  __ SetupDartSP((kMaxPushedNumber + 1) * target::kWordSize);
+  for (intptr_t i = kMaxPushedNumber; i >= 0; i--) {
+    __ PushImmediate(i);
+  }
+  __ Drop(kMaxPushedNumber);
+  __ PopRegister(R0);
+  __ RestoreCSP();
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Drop, test) {
+  EXPECT(test != NULL);
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxPushedNumber,
+            EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
 }  // namespace compiler
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/assembler/assembler_base.cc b/runtime/vm/compiler/assembler/assembler_base.cc
index 7ad426d..9f00096 100644
--- a/runtime/vm/compiler/assembler/assembler_base.cc
+++ b/runtime/vm/compiler/assembler/assembler_base.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/assembler/assembler_base.h"
 
 #include "platform/utils.h"
@@ -389,5 +387,3 @@
 }  // namespace compiler
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index 11f587c..419ec7d 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_BASE_H_
 #define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_BASE_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/assembler/object_pool_builder.h"
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 3f5872f..cd735a8 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -14,15 +14,11 @@
 
 namespace dart {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 DECLARE_FLAG(bool, inline_alloc);
 DECLARE_FLAG(bool, use_slow_path);
-#endif
 
 namespace compiler {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 class DirectCallRelocation : public AssemblerFixup {
  public:
   void Process(const MemoryRegion& region, intptr_t position) {
@@ -1938,7 +1934,7 @@
   StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
 
   testb(FieldAddress(object, target::Object::tags_offset()),
-        Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+        Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   j(ZERO, &done, Assembler::kNearJump);
 
   Stop("Store buffer update is required");
@@ -2123,7 +2119,7 @@
   intptr_t start = CodeSize();
   Label have_cid, miss;
   Bind(&miss);
-  jmp(Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  jmp(Address(THR, target::Thread::switchable_call_miss_entry_offset()));
 
   Comment("MonomorphicCheckedEntry");
   ASSERT(CodeSize() - start ==
@@ -2409,8 +2405,7 @@
   Address state_address(kNoRegister, 0);
 
   const intptr_t shared_table_offset =
-      target::Isolate::class_table_offset() +
-      target::ClassTable::shared_class_table_offset();
+      target::Isolate::shared_class_table_offset();
   const intptr_t table_offset =
       target::SharedClassTable::class_heap_stats_table_offset();
   const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
@@ -2627,19 +2622,19 @@
 }
 
 void Assembler::LoadClassId(Register result, Register object) {
-  ASSERT(target::RawObject::kClassIdTagPos == 16);
-  ASSERT(target::RawObject::kClassIdTagSize == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
       target::Object::tags_offset() +
-      target::RawObject::kClassIdTagPos / kBitsPerByte;
+      target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
   movzxw(result, FieldAddress(object, class_id_offset));
 }
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
 
-  const intptr_t table_offset = target::Isolate::class_table_offset() +
-                                target::ClassTable::table_offset();
+  const intptr_t table_offset =
+      target::Isolate::cached_class_table_table_offset();
   LoadIsolate(result);
   movl(result, Address(result, table_offset));
   movl(result, Address(result, class_id, TIMES_4, 0));
@@ -2657,11 +2652,11 @@
                                      Register scratch,
                                      Label* is_smi) {
   ASSERT(kSmiTagShift == 1);
-  ASSERT(target::RawObject::kClassIdTagPos == 16);
-  ASSERT(target::RawObject::kClassIdTagSize == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
       target::Object::tags_offset() +
-      target::RawObject::kClassIdTagPos / kBitsPerByte;
+      target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
 
   // Untag optimistically. Tag bit is shifted into the CARRY.
   SmiUntag(object);
@@ -2687,8 +2682,8 @@
     Bind(&join);
   } else {
     ASSERT(result != object);
-    static const intptr_t kSmiCidSource = kSmiCid
-                                          << target::RawObject::kClassIdTagPos;
+    static const intptr_t kSmiCidSource =
+        kSmiCid << target::ObjectLayout::kClassIdTagPos;
 
     // Make a dummy "Object" whose cid is kSmiCid.
     movl(result, Immediate(reinterpret_cast<int32_t>(&kSmiCidSource) + 1));
@@ -2795,8 +2790,6 @@
   }
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 }  // namespace compiler
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index cf87f74..f11a048 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_IA32_H_
 #define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_IA32_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
 #error Do not include assembler_ia32.h directly; use assembler.h instead.
 #endif
@@ -549,8 +553,6 @@
   void int3();
   void hlt();
 
-  static uword GetBreakInstructionFiller() { return 0xCCCCCCCC; }
-
   void j(Condition condition, Label* label, bool near = kFarJump);
   void j(Condition condition, const ExternalLabel* label);
 
@@ -602,6 +604,10 @@
 
   void LoadIsolate(Register dst);
 
+  void LoadUniqueObject(Register dst, const Object& object) {
+    LoadObject(dst, object, /*movable_referent=*/true);
+  }
+
   void LoadObject(Register dst,
                   const Object& object,
                   bool movable_referent = false);
@@ -705,9 +711,7 @@
             CodeEntryKind entry_kind = CodeEntryKind::kNormal);
   void CallToRuntime();
 
-  void CallNullErrorShared(bool save_fpu_registers) { UNREACHABLE(); }
-
-  void CallNullArgErrorShared(bool save_fpu_registers) { UNREACHABLE(); }
+  void Call(Address target) { call(target); }
 
   void Jmp(const Code& code);
   void J(Condition condition, const Code& code);
@@ -744,6 +748,13 @@
                                            Register index,
                                            intptr_t extra_disp = 0);
 
+  void LoadFieldAddressForRegOffset(Register address,
+                                    Register instance,
+                                    Register offset_in_words_as_smi) {
+    static_assert(kSmiTagShift == 1, "adjust scale factor");
+    leal(address, FieldAddress(instance, offset_in_words_as_smi, TIMES_2, 0));
+  }
+
   static Address VMTagAddress() {
     return Address(THR, target::Thread::vm_tag_offset());
   }
diff --git a/runtime/vm/compiler/assembler/assembler_test.cc b/runtime/vm/compiler/assembler/assembler_test.cc
index 7a7b54a..02f6b59 100644
--- a/runtime/vm/compiler/assembler/assembler_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_test.cc
@@ -17,8 +17,8 @@
 
 ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
 #define TEST_CODE(value, growable_array, thread)                               \
-  test->Invoke<void, RawObject*, RawObject*, Thread*>(value, growable_array,   \
-                                                      thread)
+  test->Invoke<void, ObjectPtr, ObjectPtr, Thread*>(value, growable_array,     \
+                                                    thread)
 
   const Array& old_array = Array::Handle(Array::New(3, Heap::kOld));
   const Array& new_array = Array::Handle(Array::New(3, Heap::kNew));
@@ -38,7 +38,7 @@
   for (int i = -128; i < 128; i++) {
     smi = Smi::New(i);
     TEST_CODE(smi.raw(), grow_old_array.raw(), thread);
-    EXPECT(reinterpret_cast<RawArray*>(smi.raw()) == grow_old_array.data());
+    EXPECT(static_cast<ArrayPtr>(smi.raw()) == grow_old_array.data());
     EXPECT(!thread->StoreBufferContains(grow_old_array.raw()));
   }
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 604fcc3..ef5a397 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -14,17 +14,13 @@
 
 namespace dart {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 DECLARE_FLAG(bool, precompiled_mode);
 DECLARE_FLAG(bool, use_slow_path);
-#endif
 
 namespace compiler {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 Assembler::Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches)
     : AssemblerBase(object_pool_builder), constant_pool_allowed_(false) {
@@ -100,25 +96,6 @@
   call(Address(THR, target::Thread::call_to_runtime_entry_point_offset()));
 }
 
-void Assembler::CallNullErrorShared(bool save_fpu_registers) {
-  uword entry_point_offset =
-      save_fpu_registers
-          ? target::Thread::null_error_shared_with_fpu_regs_entry_point_offset()
-          : target::Thread::
-                null_error_shared_without_fpu_regs_entry_point_offset();
-  call(Address(THR, entry_point_offset));
-}
-
-void Assembler::CallNullArgErrorShared(bool save_fpu_registers) {
-  const uword entry_point_offset =
-      save_fpu_registers
-          ? target::Thread::
-                null_arg_error_shared_with_fpu_regs_entry_point_offset()
-          : target::Thread::
-                null_arg_error_shared_without_fpu_regs_entry_point_offset();
-  call(Address(THR, entry_point_offset));
-}
-
 void Assembler::pushq(Register reg) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitRegisterREX(reg, REX_NONE);
@@ -1208,7 +1185,6 @@
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
   ASSERT(IsOriginalObject(object));
-  ASSERT(!target::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
   }
@@ -1243,18 +1219,23 @@
                                  bool is_unique) {
   ASSERT(IsOriginalObject(object));
 
-  intptr_t offset_from_thread;
-  if (target::CanLoadFromThread(object, &offset_from_thread)) {
-    movq(dst, Address(THR, offset_from_thread));
-  } else if (CanLoadFromObjectPool(object)) {
-    const intptr_t idx = is_unique ? object_pool_builder().AddObject(object)
-                                   : object_pool_builder().FindObject(object);
-    const int32_t offset = target::ObjectPool::element_offset(idx);
-    LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
-  } else {
-    ASSERT(target::IsSmi(object));
-    LoadImmediate(dst, Immediate(target::ToRawSmi(object)));
+  // `is_unique == true` effectively means object has to be patchable.
+  if (!is_unique) {
+    intptr_t offset;
+    if (target::CanLoadFromThread(object, &offset)) {
+      movq(dst, Address(THR, offset));
+      return;
+    }
   }
+  if (CanLoadFromObjectPool(object)) {
+    const int32_t offset = target::ObjectPool::element_offset(
+        is_unique ? object_pool_builder().AddObject(object)
+                  : object_pool_builder().FindObject(object));
+    LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
+    return;
+  }
+  ASSERT(target::IsSmi(object));
+  LoadImmediate(dst, Immediate(target::ToRawSmi(object)));
 }
 
 void Assembler::LoadObject(Register dst, const Object& object) {
@@ -1393,14 +1374,14 @@
   //    in progress
   // If so, call the WriteBarrier stub, which will either add object to the
   // store buffer (case 1) or add value to the marking stack (case 2).
-  // Compare RawObject::StorePointer.
+  // Compare ObjectLayout::StorePointer.
   Label done;
   if (can_be_smi == kValueCanBeSmi) {
     testq(value, Immediate(kSmiTagMask));
     j(ZERO, &done, kNearJump);
   }
   movb(TMP, FieldAddress(object, target::Object::tags_offset()));
-  shrl(TMP, Immediate(target::RawObject::kBarrierOverlapShift));
+  shrl(TMP, Immediate(target::ObjectLayout::kBarrierOverlapShift));
   andl(TMP, Address(THR, target::Thread::write_barrier_mask_offset()));
   testb(FieldAddress(value, target::Object::tags_offset()), TMP);
   j(ZERO, &done, kNearJump);
@@ -1445,14 +1426,14 @@
   //    in progress
   // If so, call the WriteBarrier stub, which will either add object to the
   // store buffer (case 1) or add value to the marking stack (case 2).
-  // Compare RawObject::StorePointer.
+  // Compare ObjectLayout::StorePointer.
   Label done;
   if (can_be_smi == kValueCanBeSmi) {
     testq(value, Immediate(kSmiTagMask));
     j(ZERO, &done, kNearJump);
   }
   movb(TMP, FieldAddress(object, target::Object::tags_offset()));
-  shrl(TMP, Immediate(target::RawObject::kBarrierOverlapShift));
+  shrl(TMP, Immediate(target::ObjectLayout::kBarrierOverlapShift));
   andl(TMP, Address(THR, target::Thread::write_barrier_mask_offset()));
   testb(FieldAddress(value, target::Object::tags_offset()), TMP);
   j(ZERO, &done, kNearJump);
@@ -1480,7 +1461,7 @@
   StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
 
   testb(FieldAddress(object, target::Object::tags_offset()),
-        Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+        Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   j(ZERO, &done, Assembler::kNearJump);
 
   Stop("Store buffer update is required");
@@ -1801,7 +1782,7 @@
   intptr_t start = CodeSize();
   Label have_cid, miss;
   Bind(&miss);
-  jmp(Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  jmp(Address(THR, target::Thread::switchable_call_miss_entry_offset()));
 
   // Ensure the monomorphic entry is 2-byte aligned (so GC can see them if we
   // store them in ICData / MegamorphicCache arrays)
@@ -1829,12 +1810,14 @@
   ASSERT(((CodeSize() - start) & kSmiTagMask) == kSmiTag);
 }
 
+// RBX - input: class id smi
+// RDX - input: receiver object
 void Assembler::MonomorphicCheckedEntryAOT() {
   has_monomorphic_entry_ = true;
   intptr_t start = CodeSize();
   Label have_cid, miss;
   Bind(&miss);
-  jmp(Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  jmp(Address(THR, target::Thread::switchable_call_miss_entry_offset()));
 
   // Ensure the monomorphic entry is 2-byte aligned (so GC can see them if we
   // store them in ICData / MegamorphicCache arrays)
@@ -1877,8 +1860,7 @@
                                      bool near_jump) {
   ASSERT(cid > 0);
   const intptr_t shared_table_offset =
-      target::Isolate::class_table_offset() +
-      target::ClassTable::shared_class_table_offset();
+      target::Isolate::shared_class_table_offset();
   const intptr_t table_offset =
       target::SharedClassTable::class_heap_stats_table_offset();
   const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
@@ -1983,6 +1965,17 @@
   pattern.set_distance(offset_into_target);
 }
 
+void Assembler::GenerateUnRelocatedPcRelativeTailCall(
+    intptr_t offset_into_target) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  buffer_.Emit<uint8_t>(0xe9);
+  buffer_.Emit<int32_t>(0);
+
+  PcRelativeCallPattern pattern(buffer_.contents() + buffer_.Size() -
+                                PcRelativeCallPattern::kLengthInBytes);
+  pattern.set_distance(offset_into_target);
+}
+
 void Assembler::Align(int alignment, intptr_t offset) {
   ASSERT(Utils::IsPowerOfTwo(alignment));
   intptr_t pos = offset + buffer_.GetPosition();
@@ -2110,20 +2103,39 @@
   EmitOperand(rm, Operand(operand));
 }
 
+void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
+  ASSERT(sizeof(classid_t) == sizeof(uint16_t));
+  movl(result, tags);
+  shrl(result, Immediate(target::ObjectLayout::kClassIdTagPos));
+}
+
+void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
+  ASSERT(target::ObjectLayout::kSizeTagPos == 8);
+  ASSERT(target::ObjectLayout::kSizeTagSize == 8);
+  movzxw(result, tags);
+  shrl(result, Immediate(target::ObjectLayout::kSizeTagPos -
+                         target::ObjectAlignment::kObjectAlignmentLog2));
+  AndImmediate(result,
+               Immediate(Utils::NBitMask(target::ObjectLayout::kSizeTagSize)
+                         << target::ObjectAlignment::kObjectAlignmentLog2));
+}
+
 void Assembler::LoadClassId(Register result, Register object) {
-  ASSERT(target::RawObject::kClassIdTagPos == 16);
-  ASSERT(target::RawObject::kClassIdTagSize == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
   ASSERT(sizeof(classid_t) == sizeof(uint16_t));
   const intptr_t class_id_offset =
       target::Object::tags_offset() +
-      target::RawObject::kClassIdTagPos / kBitsPerByte;
+      target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
   movzxw(result, FieldAddress(object, class_id_offset));
 }
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
-  const intptr_t table_offset = target::Isolate::class_table_offset() +
-                                target::ClassTable::table_offset();
+  const intptr_t table_offset =
+      target::Isolate::cached_class_table_table_offset();
 
   LoadIsolate(result);
   movq(result, Address(result, table_offset));
@@ -2142,12 +2154,12 @@
                                      intptr_t class_id,
                                      Label* is_smi) {
   ASSERT(kSmiTagShift == 1);
-  ASSERT(target::RawObject::kClassIdTagPos == 16);
-  ASSERT(target::RawObject::kClassIdTagSize == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+  ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
   ASSERT(sizeof(classid_t) == sizeof(uint16_t));
   const intptr_t class_id_offset =
       target::Object::tags_offset() +
-      target::RawObject::kClassIdTagPos / kBitsPerByte;
+      target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
 
   // Untag optimistically. Tag bit is shifted into the CARRY.
   SmiUntag(object);
@@ -2283,8 +2295,6 @@
   }
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 }  // namespace compiler
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 4508fd9..b24b9eb 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_X64_H_
 #define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_X64_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
 #error Do not include assembler_x64.h directly; use assembler.h instead.
 #endif
@@ -642,8 +646,6 @@
   // 'size' indicates size in bytes and must be in the range 1..8.
   void nop(int size = 1);
 
-  static uword GetBreakInstructionFiller() { return 0xCCCCCCCCCCCCCCCC; }
-
   void j(Condition condition, Label* label, bool near = kFarJump);
   void jmp(Register reg) { EmitUnaryL(reg, 0xFF, 4); }
   void jmp(const Address& address) { EmitUnaryL(address, 0xFF, 4); }
@@ -725,16 +727,14 @@
   void Call(const Code& stub_entry);
   void CallToRuntime();
 
-  void CallNullErrorShared(bool save_fpu_registers);
-
-  void CallNullArgErrorShared(bool save_fpu_registers);
-
   // Emit a call that shares its object pool entries with other calls
   // that have the same equivalence marker.
   void CallWithEquivalence(const Code& code,
                            const Object& equivalence,
                            CodeEntryKind entry_kind = CodeEntryKind::kNormal);
 
+  void Call(Address target) { call(target); }
+
   // Unaware of write barrier (use StoreInto* methods for storing to objects).
   // TODO(koda): Add StackAddress/HeapAddress types to prevent misuse.
   void StoreObject(const Address& dst, const Object& obj);
@@ -819,6 +819,9 @@
   // if platform ABI requires that. Does not restore RSP after the call itself.
   void CallCFunction(Register reg);
 
+  void ExtractClassIdFromTags(Register result, Register tags);
+  void ExtractInstanceSizeFromTags(Register result, Register tags);
+
   // Loading and comparing classes of objects.
   void LoadClassId(Register result, Register object);
   void LoadClassById(Register result, Register class_id);
@@ -944,8 +947,8 @@
   // before the code can be used.
   //
   // The neccessary information for the "linker" (i.e. the relocation
-  // information) is stored in [RawCode::static_calls_target_table_]: an entry
-  // of the form
+  // information) is stored in [CodeLayout::static_calls_target_table_]: an
+  // entry of the form
   //
   //   (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
   //
@@ -956,6 +959,11 @@
   // function.
   void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target = 0);
 
+  // This emits an PC-relative tail call of the form "jmp *[rip+<offset>]".
+  //
+  // See also above for the pc-relative call.
+  void GenerateUnRelocatedPcRelativeTailCall(intptr_t offset_into_target = 0);
+
   // Debugging and bringup support.
   void Breakpoint() override { int3(); }
 
@@ -971,6 +979,13 @@
                                            Register array,
                                            Register index);
 
+  void LoadFieldAddressForRegOffset(Register address,
+                                    Register instance,
+                                    Register offset_in_words_as_smi) {
+    static_assert(kSmiTagShift == 1, "adjust scale factor");
+    leaq(address, FieldAddress(instance, offset_in_words_as_smi, TIMES_4, 0));
+  }
+
   static Address VMTagAddress();
 
   // On some other platforms, we draw a distinction between safe and unsafe
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index e43229b..45d4f99 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -5,8 +5,6 @@
 #include "vm/compiler/assembler/disassembler.h"
 
 #include "vm/code_patcher.h"
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/il_printer.h"
 #include "vm/deopt_instructions.h"
 #include "vm/globals.h"
 #include "vm/instructions.h"
@@ -18,7 +16,10 @@
 
 #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 DECLARE_FLAG(bool, trace_inlining_intervals);
+#endif
+
 DEFINE_FLAG(bool, trace_source_positions, false, "Source position diagnostics");
 
 void DisassembleToStdout::ConsumeInstruction(char* hex_buffer,
@@ -231,7 +232,7 @@
   Object& obj = Object::Handle(zone);
   for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) {
     const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
-    obj = *reinterpret_cast<RawObject**>(addr);
+    obj = *reinterpret_cast<ObjectPtr*>(addr);
     THR_Print(" %d : %#" Px " '%s'\n", code.GetPointerOffsetAt(i), addr,
               obj.ToCString());
   }
@@ -240,7 +241,7 @@
   ASSERT(code.pointer_offsets_length() == 0);
 #endif
 
-  if (FLAG_use_bare_instructions) {
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     THR_Print("(No object pool for bare instructions.)\n");
   } else {
     const ObjectPool& object_pool =
@@ -300,20 +301,20 @@
     String& var_name = String::Handle(zone);
     for (intptr_t i = 0; i < var_desc_length; i++) {
       var_name = var_descriptors.GetName(i);
-      RawLocalVarDescriptors::VarInfo var_info;
+      LocalVarDescriptorsLayout::VarInfo var_info;
       var_descriptors.GetInfo(i, &var_info);
       const int8_t kind = var_info.kind();
-      if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
+      if (kind == LocalVarDescriptorsLayout::kSavedCurrentContext) {
         THR_Print("  saved current CTX reg offset %d\n", var_info.index());
       } else {
-        if (kind == RawLocalVarDescriptors::kContextLevel) {
+        if (kind == LocalVarDescriptorsLayout::kContextLevel) {
           THR_Print("  context level %d scope %d", var_info.index(),
                     var_info.scope_id);
-        } else if (kind == RawLocalVarDescriptors::kStackVar) {
+        } else if (kind == LocalVarDescriptorsLayout::kStackVar) {
           THR_Print("  stack var '%s' offset %d", var_name.ToCString(),
                     var_info.index());
         } else {
-          ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+          ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
           THR_Print("  context var '%s' level %d offset %d",
                     var_name.ToCString(), var_info.scope_id, var_info.index());
         }
@@ -368,13 +369,22 @@
     auto& cls = Class::Handle(zone);
     auto& kind_type_and_offset = Smi::Handle(zone);
     auto& function = Function::Handle(zone);
+    auto& object = Object::Handle(zone);
     auto& code = Code::Handle(zone);
+    auto& dst_type = AbstractType::Handle(zone);
     if (!table.IsNull()) {
       StaticCallsTable static_calls(table);
       for (auto& call : static_calls) {
         kind_type_and_offset = call.Get<Code::kSCallTableKindAndOffset>();
         function = call.Get<Code::kSCallTableFunctionTarget>();
-        code = call.Get<Code::kSCallTableCodeTarget>();
+        object = call.Get<Code::kSCallTableCodeOrTypeTarget>();
+
+        dst_type = AbstractType::null();
+        if (object.IsAbstractType()) {
+          dst_type = AbstractType::Cast(object).raw();
+        } else if (object.IsCode()) {
+          code = Code::Cast(object).raw();
+        }
 
         auto kind = Code::KindField::decode(kind_type_and_offset.Value());
         auto offset = Code::OffsetField::decode(kind_type_and_offset.Value());
@@ -388,13 +398,22 @@
           case Code::kPcRelativeCall:
             skind = "pc-relative-call";
             break;
+          case Code::kPcRelativeTTSCall:
+            skind = "pc-relative-tts-call";
+            break;
+          case Code::kPcRelativeTailCall:
+            skind = "pc-relative-tail-call";
+            break;
           case Code::kCallViaCode:
             skind = "call-via-code";
             break;
           default:
             UNREACHABLE();
         }
-        if (function.IsNull()) {
+        if (!dst_type.IsNull()) {
+          THR_Print("  0x%" Px ": type testing stub %s, (%s)%s\n",
+                    base + offset, dst_type.ToCString(), skind, s_entry_point);
+        } else if (function.IsNull()) {
           cls ^= code.owner();
           if (cls.IsNull()) {
             THR_Print("  0x%" Px ": %s, (%s)%s\n", base + offset,
@@ -413,9 +432,12 @@
   }
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   if (optimized && FLAG_trace_inlining_intervals) {
     code.DumpInlineIntervals();
   }
+#endif
+
   if (FLAG_trace_source_positions) {
     code.DumpSourcePositions();
   }
@@ -436,7 +458,7 @@
   code.Disassemble(&formatter);
   THR_Print("}\n");
   const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool());
-  if (FLAG_use_bare_instructions) {
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     THR_Print("(No object pool for bare instructions.)\n");
   } else if (!object_pool.IsNull()) {
     object_pool.DebugPrint();
diff --git a/runtime/vm/compiler/assembler/disassembler.h b/runtime/vm/compiler/assembler/disassembler.h
index 861051d..4a86177 100644
--- a/runtime/vm/compiler/assembler/disassembler.h
+++ b/runtime/vm/compiler/assembler/disassembler.h
@@ -6,11 +6,14 @@
 #define RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_H_
 
 #include "vm/allocation.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/globals.h"
 #include "vm/log.h"
 #include "vm/object.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // Forward declaration.
diff --git a/runtime/vm/compiler/assembler/disassembler_x86.cc b/runtime/vm/compiler/assembler/disassembler_x86.cc
index b51f464..93f3129 100644
--- a/runtime/vm/compiler/assembler/disassembler_x86.cc
+++ b/runtime/vm/compiler/assembler/disassembler_x86.cc
@@ -11,6 +11,7 @@
 
 #include "platform/utils.h"
 #include "vm/allocation.h"
+#include "vm/constants_x86.h"
 #include "vm/heap/heap.h"
 #include "vm/instructions.h"
 #include "vm/os.h"
@@ -1994,7 +1995,7 @@
     for (intptr_t i = 0; i < offsets_length; i++) {
       uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
       if ((pc <= addr) && (addr < (pc + instruction_length))) {
-        *object = &Object::Handle(*reinterpret_cast<RawObject**>(addr));
+        *object = &Object::Handle(*reinterpret_cast<ObjectPtr*>(addr));
         break;
       }
     }
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index afca0e8..311b0ab 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 
@@ -57,7 +61,7 @@
 
     ReturnInstr* instr = new ReturnInstr(
         TokenPos(), value, CompilerState::Current().GetNextDeoptId(),
-        RawPcDescriptors::kInvalidYieldIndex, representation);
+        PcDescriptorsLayout::kInvalidYieldIndex, representation);
     AddInstruction(instr);
     entry_->set_last_instruction(instr);
   }
diff --git a/runtime/vm/compiler/backend/block_scheduler.cc b/runtime/vm/compiler/backend/block_scheduler.cc
index 0d84725..9807a19 100644
--- a/runtime/vm/compiler/backend/block_scheduler.cc
+++ b/runtime/vm/compiler/backend/block_scheduler.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/block_scheduler.h"
 
 #include "vm/allocation.h"
@@ -304,5 +302,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/block_scheduler.h b/runtime/vm/compiler/backend/block_scheduler.h
index 4bcdf15..305cbf3 100644
--- a/runtime/vm/compiler/backend/block_scheduler.h
+++ b/runtime/vm/compiler/backend/block_scheduler.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_BLOCK_SCHEDULER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_BLOCK_SCHEDULER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 
 namespace dart {
diff --git a/runtime/vm/compiler/backend/branch_optimizer.cc b/runtime/vm/compiler/backend/branch_optimizer.cc
index 1f9e9f3..3c58635 100644
--- a/runtime/vm/compiler/backend/branch_optimizer.cc
+++ b/runtime/vm/compiler/backend/branch_optimizer.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/branch_optimizer.h"
 
 #include "vm/compiler/backend/flow_graph.h"
@@ -349,5 +347,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/branch_optimizer.h b/runtime/vm/compiler/backend/branch_optimizer.h
index 8d8136d..ca91b16 100644
--- a/runtime/vm/compiler/backend/branch_optimizer.h
+++ b/runtime/vm/compiler/backend/branch_optimizer.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_BRANCH_OPTIMIZER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_BRANCH_OPTIMIZER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 
 namespace dart {
diff --git a/runtime/vm/compiler/backend/code_statistics.h b/runtime/vm/compiler/backend/code_statistics.h
index cfc4cd95e..75d3274 100644
--- a/runtime/vm/compiler/backend/code_statistics.h
+++ b/runtime/vm/compiler/backend/code_statistics.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_CODE_STATISTICS_H_
 #define RUNTIME_VM_COMPILER_BACKEND_CODE_STATISTICS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/il.h"
 #include "vm/object.h"
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index f068bf0..f72eb52 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_COMPILE_TYPE_H_
 #define RUNTIME_VM_COMPILER_BACKEND_COMPILE_TYPE_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/class_id.h"
 #include "vm/compiler/runtime_api.h"
@@ -106,8 +110,10 @@
     return CompileType(is_nullable, cid, nullptr);
   }
 
-  // Create a new CompileType representing given abstract type. By default
-  // values as assumed to be nullable.
+  // Create a new CompileType representing given abstract type.
+  // By default nullability of values is determined by type.
+  // CompileType can be further constrained to non-nullable values by
+  // passing kNonNullable as an optional parameter.
   static CompileType FromAbstractType(const AbstractType& type,
                                       bool is_nullable = kNullable);
 
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index b11bcf1..00dbb2d 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/constant_propagator.h"
 
 #include "vm/bit_vector.h"
@@ -330,11 +328,50 @@
   unwrapped_phis_->Add(phi->ssa_temp_index());
 }
 
+ConstantPropagator::PhiInfo* ConstantPropagator::GetPhiInfo(PhiInstr* phi) {
+  if (phi->HasPassSpecificId(CompilerPass::kConstantPropagation)) {
+    const intptr_t id =
+        phi->GetPassSpecificId(CompilerPass::kConstantPropagation);
+    // Note: id might have been assigned by the previous round of constant
+    // propagation, so we need to verify it before using it.
+    if (id < phis_.length() && phis_[id].phi == phi) {
+      return &phis_[id];
+    }
+  }
+
+  phi->SetPassSpecificId(CompilerPass::kConstantPropagation, phis_.length());
+  phis_.Add({phi, 0});
+  return &phis_.Last();
+}
+
 // --------------------------------------------------------------------------
 // Analysis of definitions.  Compute the constant value.  If it has changed
 // and the definition has input uses, add the definition to the definition
 // worklist so that the used can be processed.
 void ConstantPropagator::VisitPhi(PhiInstr* instr) {
+  // Detect convergence issues by checking if visit count for this phi
+  // is too high. We should only visit this phi once for every predecessor
+  // becoming reachable, once for every input changing its constant value and
+  // once for an unwrapped redundant phi becoming non-redundant.
+  // Inputs can only change their constant value at most three times: from
+  // non-constant to unknown to specific constant to non-constant. The first
+  // link (non-constant to ...) can happen when we run the second round of
+  // constant propagation - some instructions can have non-constant assigned to
+  // them at the end of the previous constant propagation.
+  auto info = GetPhiInfo(instr);
+  info->visit_count++;
+  const intptr_t kMaxVisitsExpected = 5 * instr->InputCount();
+  if (info->visit_count > kMaxVisitsExpected) {
+    OS::PrintErr(
+        "ConstantPropagation pass is failing to converge on graph for %s\n",
+        graph_->parsed_function().function().ToCString());
+    OS::PrintErr("Phi %s was visited %" Pd " times\n", instr->ToCString(),
+                 info->visit_count);
+    NOT_IN_PRODUCT(
+        FlowGraphPrinter::PrintGraph("Constant Propagation", graph_));
+    FATAL("Aborting due to non-covergence.");
+  }
+
   // Compute the join over all the reachable predecessor values.
   JoinEntryInstr* block = instr->block();
   Object& value = Object::ZoneHandle(Z, Unknown());
@@ -557,7 +594,11 @@
       const intptr_t right_cid = instr->right()->Type()->ToCid();
       // If exact classes (cids) are known and they differ, the result
       // of strict compare can be computed.
+      // The only exception is comparison with special sentinel value
+      // (used for lazy initialization) which can be compared to a
+      // value of any type. Sentinel value has kNeverCid.
       if ((left_cid != kDynamicCid) && (right_cid != kDynamicCid) &&
+          (left_cid != kNeverCid) && (right_cid != kNeverCid) &&
           (left_cid != right_cid)) {
         const bool result = (instr->kind() != Token::kEQ_STRICT);
         SetValue(instr, Bool::Get(result));
@@ -627,7 +668,7 @@
   Definition* left_defn = instr->left()->definition();
   Definition* right_defn = instr->right()->definition();
 
-  if (RawObject::IsIntegerClassId(instr->operation_cid())) {
+  if (IsIntegerClassId(instr->operation_cid())) {
     // Fold x == x, and x != x to true/false for numbers comparisons.
     Definition* unwrapped_left_defn = UnwrapPhi(left_defn);
     Definition* unwrapped_right_defn = UnwrapPhi(right_defn);
@@ -703,7 +744,7 @@
     const intptr_t ch_code = Smi::Cast(o).Value();
     ASSERT(ch_code >= 0);
     if (ch_code < Symbols::kMaxOneCharCodeSymbol) {
-      RawString** table = Symbols::PredefinedAddress();
+      StringPtr* table = Symbols::PredefinedAddress();
       SetValue(instr, String::ZoneHandle(Z, table[ch_code]));
     } else {
       SetValue(instr, non_constant_);
@@ -815,7 +856,7 @@
   const Object& value = def->constant_value();
   const AbstractType& checked_type = instr->type();
   // If the checked type is a top type, the result is always true.
-  if (checked_type.IsTopType()) {
+  if (checked_type.IsTopTypeForInstanceOf()) {
     SetValue(instr, Bool::True());
   } else if (IsNonConstant(value)) {
     intptr_t value_cid = instr->value()->definition()->Type()->ToCid();
@@ -1635,5 +1676,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/constant_propagator.h b/runtime/vm/compiler/backend/constant_propagator.h
index 991c622..d0dca7d 100644
--- a/runtime/vm/compiler/backend/constant_propagator.h
+++ b/runtime/vm/compiler/backend/constant_propagator.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
 #define RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 
@@ -32,7 +36,7 @@
   static void OptimizeBranches(FlowGraph* graph);
 
   // Used to initialize the abstract value of definitions.
-  static RawObject* Unknown() { return Object::unknown_constant().raw(); }
+  static ObjectPtr Unknown() { return Object::unknown_constant().raw(); }
 
  private:
   void Analyze();
@@ -71,7 +75,18 @@
 
 #define DECLARE_VISIT(type, attrs) virtual void Visit##type(type##Instr* instr);
   FOR_EACH_INSTRUCTION(DECLARE_VISIT)
+
 #undef DECLARE_VISIT
+  // Structure tracking visit counts for phis. Used to detect infinite loops.
+  struct PhiInfo {
+    PhiInstr* phi;
+    intptr_t visit_count;
+  };
+
+  // Returns PhiInfo associated with the given phi. Note that this
+  // pointer can be invalidated by subsequent call to GetPhiInfo and
+  // thus should not be stored anywhere.
+  PhiInfo* GetPhiInfo(PhiInstr* phi);
 
   Isolate* isolate() const { return graph_->isolate(); }
 
@@ -94,6 +109,10 @@
   // changes even if that does not change constant value of the phi.
   BitVector* unwrapped_phis_;
 
+  // List of visited phis indexed by their id (stored as pass specific id on
+  // a phi instruction).
+  GrowableArray<PhiInfo> phis_;
+
   // Worklists of blocks and definitions.
   GrowableArray<BlockEntryInstr*> block_worklist_;
   DefinitionWorklist definition_worklist_;
diff --git a/runtime/vm/compiler/backend/constant_propagator_test.cc b/runtime/vm/compiler/backend/constant_propagator_test.cc
new file mode 100644
index 0000000..40db6b4
--- /dev/null
+++ b/runtime/vm/compiler/backend/constant_propagator_test.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/backend/constant_propagator.h"
+
+#include "vm/compiler/backend/block_builder.h"
+#include "vm/compiler/backend/il_test_helper.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+// Test issue https://github.com/flutter/flutter/issues/53903.
+//
+// If graph contains a cyclic phi which participates in an EqualityCompare
+// or StrictCompare with its input like phi(x, ...) == x then constant
+// propagation might fail to converge by constantly revisiting this phi and
+// its uses (which includes comparison and the phi itself).
+ISOLATE_UNIT_TEST_CASE(ConstantPropagation_PhiUnwrappingAndConvergence) {
+  using compiler::BlockBuilder;
+  CompilerState S(thread, /*is_aot=*/false);
+  FlowGraphBuilderHelper H;
+
+  // We are going to build the following graph:
+  //
+  // B0[graph_entry]
+  // B1[function_entry]:
+  //   v0 <- Constant(0)
+  //   goto B2
+  // B2:
+  //   v1 <- phi(v0, v1)
+  //   v2 <- EqualityCompare(v1 == v0)
+  //   if v2 == true then B4 else B3
+  // B3:
+  //   goto B2
+  // B4:
+  //   Return(v1)
+
+  PhiInstr* v1;
+  ConstantInstr* v0 = H.IntConstant(0);
+  auto b1 = H.flow_graph()->graph_entry()->normal_entry();
+  auto b2 = H.JoinEntry();
+  auto b3 = H.TargetEntry();
+  auto b4 = H.TargetEntry();
+
+  {
+    BlockBuilder builder(H.flow_graph(), b1);
+    builder.AddInstruction(new GotoInstr(b2, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), b2);
+    v1 = H.Phi(b2, {{b1, v0}, {b3, FlowGraphBuilderHelper::kPhiSelfReference}});
+    builder.AddPhi(v1);
+    auto v2 = builder.AddDefinition(new EqualityCompareInstr(
+        TokenPosition::kNoSource, Token::kEQ, new Value(v1), new Value(v0),
+        kSmiCid, S.GetNextDeoptId()));
+    builder.AddBranch(
+        new StrictCompareInstr(
+            TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(v2),
+            new Value(H.flow_graph()->GetConstant(Bool::True())),
+            /*needs_number_check=*/false, S.GetNextDeoptId()),
+        b4, b3);
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), b3);
+    builder.AddInstruction(new GotoInstr(b2, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), b4);
+    builder.AddReturn(new Value(v1));
+  }
+
+  H.FinishGraph();
+
+  // Graph transformations will attempt to copy deopt information from
+  // branches and block entries which we did not assign.
+  // To disable copying we mark graph to disable LICM.
+  H.flow_graph()->disallow_licm();
+
+  ConstantPropagator::Optimize(H.flow_graph());
+
+  auto& blocks = H.flow_graph()->reverse_postorder();
+  EXPECT_EQ(2, blocks.length());
+  EXPECT_PROPERTY(blocks[0], it.IsGraphEntry());
+  EXPECT_PROPERTY(blocks[1], it.IsFunctionEntry());
+  EXPECT_PROPERTY(blocks[1]->next(), it.IsReturn());
+  EXPECT_PROPERTY(blocks[1]->next()->AsReturn(),
+                  it.value()->definition() == v0);
+}
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/backend/evaluator.cc b/runtime/vm/compiler/backend/evaluator.cc
index f6adab3..8bb0c3d 100644
--- a/runtime/vm/compiler/backend/evaluator.cc
+++ b/runtime/vm/compiler/backend/evaluator.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/evaluator.h"
 
 namespace dart {
@@ -33,9 +31,9 @@
   }
 }
 
-static RawInteger* BinaryIntegerEvaluateRaw(const Integer& left,
-                                            const Integer& right,
-                                            Token::Kind token_kind) {
+static IntegerPtr BinaryIntegerEvaluateRaw(const Integer& left,
+                                           const Integer& right,
+                                           Token::Kind token_kind) {
   switch (token_kind) {
     case Token::kTRUNCDIV:
       FALL_THROUGH;
@@ -73,9 +71,9 @@
   return Integer::null();
 }
 
-static RawInteger* UnaryIntegerEvaluateRaw(const Integer& value,
-                                           Token::Kind token_kind,
-                                           Zone* zone) {
+static IntegerPtr UnaryIntegerEvaluateRaw(const Integer& value,
+                                          Token::Kind token_kind,
+                                          Zone* zone) {
   switch (token_kind) {
     case Token::kNEGATE:
       return value.ArithmeticOp(Token::kMUL, Smi::Handle(zone, Smi::New(-1)),
@@ -112,12 +110,12 @@
   }
 }
 
-RawInteger* Evaluator::BinaryIntegerEvaluate(const Object& left,
-                                             const Object& right,
-                                             Token::Kind token_kind,
-                                             bool is_truncating,
-                                             Representation representation,
-                                             Thread* thread) {
+IntegerPtr Evaluator::BinaryIntegerEvaluate(const Object& left,
+                                            const Object& right,
+                                            Token::Kind token_kind,
+                                            bool is_truncating,
+                                            Representation representation,
+                                            Thread* thread) {
   if (!left.IsInteger() || !right.IsInteger()) {
     return Integer::null();
   }
@@ -150,10 +148,10 @@
   return result.raw();
 }
 
-RawInteger* Evaluator::UnaryIntegerEvaluate(const Object& value,
-                                            Token::Kind token_kind,
-                                            Representation representation,
-                                            Thread* thread) {
+IntegerPtr Evaluator::UnaryIntegerEvaluate(const Object& value,
+                                           Token::Kind token_kind,
+                                           Representation representation,
+                                           Thread* thread) {
   if (!value.IsInteger()) {
     return Integer::null();
   }
@@ -237,5 +235,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/evaluator.h b/runtime/vm/compiler/backend/evaluator.h
index 8c8e814..e1ab8ea 100644
--- a/runtime/vm/compiler/backend/evaluator.h
+++ b/runtime/vm/compiler/backend/evaluator.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_EVALUATOR_H_
 #define RUNTIME_VM_COMPILER_BACKEND_EVALUATOR_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
@@ -20,19 +24,19 @@
 
   // Evaluates a binary integer operation and returns a pointer to a
   // canonicalized RawInteger.
-  static RawInteger* BinaryIntegerEvaluate(const Object& left,
-                                           const Object& right,
-                                           Token::Kind token_kind,
-                                           bool is_truncating,
-                                           Representation representation,
-                                           Thread* thread);
+  static IntegerPtr BinaryIntegerEvaluate(const Object& left,
+                                          const Object& right,
+                                          Token::Kind token_kind,
+                                          bool is_truncating,
+                                          Representation representation,
+                                          Thread* thread);
 
   // Evaluates a unary integer operation and returns a pointer to a
   // canonicalized RawInteger.
-  static RawInteger* UnaryIntegerEvaluate(const Object& value,
-                                          Token::Kind token_kind,
-                                          Representation representation,
-                                          Thread* thread);
+  static IntegerPtr UnaryIntegerEvaluate(const Object& value,
+                                         Token::Kind token_kind,
+                                         Representation representation,
+                                         Thread* thread);
 
   // Evaluates a binary double operation and returns the result.
   static double EvaluateDoubleOp(const double left,
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 266cb14..c930e71 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/flow_graph.h"
 
 #include "vm/bit_vector.h"
@@ -412,7 +410,7 @@
 
 FlowGraph::ToCheck FlowGraph::CheckForInstanceCall(
     InstanceCallInstr* call,
-    RawFunction::Kind kind) const {
+    FunctionLayout::Kind kind) const {
   if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
     // Even if class or function are private, lazy class finalization
     // may later add overriding methods.
@@ -474,7 +472,7 @@
   }
 
   const String& method_name =
-      (kind == RawFunction::kMethodExtractor)
+      (kind == FunctionLayout::kMethodExtractor)
           ? String::Handle(zone(), Field::NameFromGetter(call->function_name()))
           : call->function_name();
 
@@ -1236,8 +1234,10 @@
                                   GrowableArray<Definition*>* env) {
   Environment* deopt_env =
       Environment::From(zone(), *env, num_direct_parameters_, parsed_function_);
-  if (instr->IsClosureCall()) {
-    // Trim extra input of ClosureCall instruction.
+  if (instr->IsClosureCall() || instr->IsInitInstanceField()) {
+    // Trim extra inputs of ClosureCall and InitInstanceField instructions.
+    // Inputs of those instructions are not pushed onto the stack at the
+    // point where deoptimization can occur.
     deopt_env =
         deopt_env->DeepCopy(zone(), deopt_env->Length() - instr->InputCount() +
                                         instr->ArgumentCount());
@@ -1621,6 +1621,12 @@
       } else if (auto check = instruction->AsCheckNull()) {
         check->ReplaceUsesWith(check->value()->definition());
         check->ClearSSATempIndex();
+      } else if (auto check = instruction->AsAssertAssignable()) {
+        check->ReplaceUsesWith(check->value()->definition());
+        check->ClearSSATempIndex();
+      } else if (auto check = instruction->AsAssertBoolean()) {
+        check->ReplaceUsesWith(check->value()->definition());
+        check->ClearSSATempIndex();
       }
     }
   }
@@ -2378,10 +2384,18 @@
        block_it.Advance()) {
     for (ForwardInstructionIterator instr_it(block_it.Current());
          !instr_it.Done(); instr_it.Advance()) {
-      RedefinitionInstr* redefinition = instr_it.Current()->AsRedefinition();
-      if (redefinition != NULL) {
-        Definition* original = redefinition->value()->definition();
-        RenameDominatedUses(original, redefinition, redefinition);
+      Definition* definition = instr_it.Current()->AsDefinition();
+      // CheckArrayBound instructions have their own mechanism for ensuring
+      // proper dependencies, so we don't rewrite those here.
+      if (definition != nullptr && !definition->IsCheckArrayBound()) {
+        Value* redefined = definition->RedefinedValue();
+        if (redefined != nullptr) {
+          if (!definition->HasSSATemp()) {
+            AllocateSSAIndexes(definition);
+          }
+          Definition* original = redefined->definition();
+          RenameDominatedUses(original, definition, definition);
+        }
       }
     }
   }
@@ -2689,5 +2703,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 03a2239..0a9d929 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_H_
 #define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/bit_vector.h"
 #include "vm/compiler/backend/il.h"
 #include "vm/growable_array.h"
@@ -156,11 +160,10 @@
   }
 
   intptr_t CurrentContextEnvIndex() const {
-#if !defined(DART_PRECOMPILED_RUNTIME)
     if (function().HasBytecode()) {
       return -1;
     }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
     return EnvIndex(parsed_function().current_context_var());
   }
 
@@ -233,7 +236,7 @@
   // Return value indicates that the call needs no check at all,
   // just a null check, or a full class check.
   ToCheck CheckForInstanceCall(InstanceCallInstr* call,
-                               RawFunction::Kind kind) const;
+                               FunctionLayout::Kind kind) const;
 
   Thread* thread() const { return thread_; }
   Zone* zone() const { return thread()->zone(); }
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 7814dd1..5b753ce 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 #if defined(DEBUG)
 
 #include "vm/compiler/backend/flow_graph_checker.h"
@@ -474,4 +473,3 @@
 }  // namespace dart
 
 #endif  // defined(DEBUG)
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.h b/runtime/vm/compiler/backend/flow_graph_checker.h
index c86fab8..0079d98 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.h
+++ b/runtime/vm/compiler/backend/flow_graph_checker.h
@@ -5,7 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #if defined(DEBUG)
 
 #include "vm/compiler/backend/flow_graph.h"
@@ -69,6 +72,5 @@
 }  // namespace dart
 
 #endif  // defined(DEBUG)
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #endif  // RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index ef80744..a00b77c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -44,8 +44,6 @@
 
 DEFINE_FLAG(bool, enable_peephole, true, "Enable peephole optimization");
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 DEFINE_FLAG(bool,
             enable_simd_inline,
             true,
@@ -254,7 +252,7 @@
 
 void FlowGraphCompiler::InsertBSSRelocation(BSS::Relocation reloc) {
   const intptr_t offset = assembler()->InsertAlignedRelocation(reloc);
-  AddDescriptor(RawPcDescriptors::kBSSRelocation, /*pc_offset=*/offset,
+  AddDescriptor(PcDescriptorsLayout::kBSSRelocation, /*pc_offset=*/offset,
                 /*deopt_id=*/DeoptId::kNone, TokenPosition::kNoSource,
                 /*try_index=*/-1);
 }
@@ -458,7 +456,7 @@
 
 void FlowGraphCompiler::EmitCallsiteMetadata(TokenPosition token_pos,
                                              intptr_t deopt_id,
-                                             RawPcDescriptors::Kind kind,
+                                             PcDescriptorsLayout::Kind kind,
                                              LocationSummary* locs,
                                              Environment* env) {
   AddCurrentDescriptor(kind, deopt_id, token_pos);
@@ -473,14 +471,15 @@
     } else {
       // Add deoptimization continuation point after the call and before the
       // arguments are removed.
-      AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+      AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+                           token_pos);
     }
   }
 }
 
 void FlowGraphCompiler::EmitYieldPositionMetadata(TokenPosition token_pos,
                                                   intptr_t yield_index) {
-  AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+  AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
                 DeoptId::kNone, token_pos, CurrentTryIndex(), yield_index);
 }
 
@@ -490,7 +489,7 @@
       // Instructions that can be deoptimization targets need to record kDeopt
       // PcDescriptor corresponding to their deopt id. GotoInstr records its
       // own so that it can control the placement.
-      AddCurrentDescriptor(RawPcDescriptors::kDeopt, instr->deopt_id(),
+      AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, instr->deopt_id(),
                            instr->token_pos());
     }
     AllocateRegistersLocally(instr);
@@ -734,7 +733,7 @@
   exception_handlers_list_->SetNeedsStackTrace(try_index);
 }
 
-void FlowGraphCompiler::AddDescriptor(RawPcDescriptors::Kind kind,
+void FlowGraphCompiler::AddDescriptor(PcDescriptorsLayout::Kind kind,
                                       intptr_t pc_offset,
                                       intptr_t deopt_id,
                                       TokenPosition token_pos,
@@ -742,13 +741,13 @@
                                       intptr_t yield_index) {
   code_source_map_builder_->NoteDescriptor(kind, pc_offset, token_pos);
   // Don't emit deopt-descriptors in AOT mode.
-  if (FLAG_precompiled_mode && (kind == RawPcDescriptors::kDeopt)) return;
+  if (FLAG_precompiled_mode && (kind == PcDescriptorsLayout::kDeopt)) return;
   pc_descriptors_list_->AddDescriptor(kind, pc_offset, deopt_id, token_pos,
                                       try_index, yield_index);
 }
 
 // Uses current pc position and try-index.
-void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind,
+void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptorsLayout::Kind kind,
                                              intptr_t deopt_id,
                                              TokenPosition token_pos) {
   AddDescriptor(kind, assembler()->CodeSize(), deopt_id, token_pos,
@@ -757,16 +756,17 @@
 
 void FlowGraphCompiler::AddNullCheck(TokenPosition token_pos,
                                      const String& name) {
-  // If we have DWARF stack traces enabled, the AOT runtime is unable to obtain
-  // the pool index at runtime. There is therefore no reason to put the name
-  // into the pool in the first place.
+#if defined(DART_PRECOMPILER)
+  // If we are generating an AOT snapshot and have DWARF stack traces enabled,
+  // the AOT runtime is unable to obtain the pool index at runtime. Therefore,
+  // there is no reason to put the name into the pool in the first place.
   // TODO(dartbug.com/40605): Move this info to the pc descriptors.
-  if (!FLAG_dwarf_stack_traces) {
-    const intptr_t name_index =
-        assembler()->object_pool_builder().FindObject(name);
-    code_source_map_builder_->NoteNullCheck(assembler()->CodeSize(), token_pos,
-                                            name_index);
-  }
+  if (FLAG_precompiled_mode && FLAG_dwarf_stack_traces_mode) return;
+#endif
+  const intptr_t name_index =
+      assembler()->object_pool_builder().FindObject(name);
+  code_source_map_builder_->NoteNullCheck(assembler()->CodeSize(), token_pos,
+                                          name_index);
 }
 
 void FlowGraphCompiler::AddPcRelativeCallTarget(const Function& function,
@@ -775,17 +775,34 @@
   const auto entry_point = entry_kind == Code::EntryKind::kUnchecked
                                ? Code::kUncheckedEntry
                                : Code::kDefaultEntry;
-  static_calls_target_table_.Add(
-      new (zone()) StaticCallsStruct(Code::kPcRelativeCall, entry_point,
-                                     assembler()->CodeSize(), &function, NULL));
+  static_calls_target_table_.Add(new (zone()) StaticCallsStruct(
+      Code::kPcRelativeCall, entry_point, assembler()->CodeSize(), &function,
+      nullptr, nullptr));
 }
 
 void FlowGraphCompiler::AddPcRelativeCallStubTarget(const Code& stub_code) {
   ASSERT(stub_code.IsZoneHandle() || stub_code.IsReadOnlyHandle());
   ASSERT(!stub_code.IsNull());
   static_calls_target_table_.Add(new (zone()) StaticCallsStruct(
-      Code::kPcRelativeCall, Code::kDefaultEntry, assembler()->CodeSize(), NULL,
-      &stub_code));
+      Code::kPcRelativeCall, Code::kDefaultEntry, assembler()->CodeSize(),
+      nullptr, &stub_code, nullptr));
+}
+
+void FlowGraphCompiler::AddPcRelativeTailCallStubTarget(const Code& stub_code) {
+  ASSERT(stub_code.IsZoneHandle() || stub_code.IsReadOnlyHandle());
+  ASSERT(!stub_code.IsNull());
+  static_calls_target_table_.Add(new (zone()) StaticCallsStruct(
+      Code::kPcRelativeTailCall, Code::kDefaultEntry, assembler()->CodeSize(),
+      nullptr, &stub_code, nullptr));
+}
+
+void FlowGraphCompiler::AddPcRelativeTTSCallTypeTarget(
+    const AbstractType& dst_type) {
+  ASSERT(dst_type.IsZoneHandle() || dst_type.IsReadOnlyHandle());
+  ASSERT(!dst_type.IsNull());
+  static_calls_target_table_.Add(new (zone()) StaticCallsStruct(
+      Code::kPcRelativeTTSCall, Code::kDefaultEntry, assembler()->CodeSize(),
+      nullptr, nullptr, &dst_type));
 }
 
 void FlowGraphCompiler::AddStaticCallTarget(const Function& func,
@@ -795,14 +812,15 @@
                                ? Code::kUncheckedEntry
                                : Code::kDefaultEntry;
   static_calls_target_table_.Add(new (zone()) StaticCallsStruct(
-      Code::kCallViaCode, entry_point, assembler()->CodeSize(), &func, NULL));
+      Code::kCallViaCode, entry_point, assembler()->CodeSize(), &func, nullptr,
+      nullptr));
 }
 
 void FlowGraphCompiler::AddStubCallTarget(const Code& code) {
   ASSERT(code.IsZoneHandle() || code.IsReadOnlyHandle());
-  static_calls_target_table_.Add(
-      new (zone()) StaticCallsStruct(Code::kCallViaCode, Code::kDefaultEntry,
-                                     assembler()->CodeSize(), NULL, &code));
+  static_calls_target_table_.Add(new (zone()) StaticCallsStruct(
+      Code::kCallViaCode, Code::kDefaultEntry, assembler()->CodeSize(), nullptr,
+      &code, nullptr));
 }
 
 void FlowGraphCompiler::AddDispatchTableCallTarget(
@@ -1106,7 +1124,7 @@
   code.set_pc_descriptors(descriptors);
 }
 
-RawArray* FlowGraphCompiler::CreateDeoptInfo(compiler::Assembler* assembler) {
+ArrayPtr FlowGraphCompiler::CreateDeoptInfo(compiler::Assembler* assembler) {
   // No deopt information if we precompile (no deoptimization allowed).
   if (FLAG_precompiled_mode) {
     return Array::empty_array().raw();
@@ -1168,8 +1186,8 @@
     // descriptor for IrregexpFunction.
     ASSERT(parsed_function().scope() == nullptr);
     var_descs = LocalVarDescriptors::New(1);
-    RawLocalVarDescriptors::VarInfo info;
-    info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
+    LocalVarDescriptorsLayout::VarInfo info;
+    info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
     info.scope_id = 0;
     info.begin_pos = TokenPosition::kMinSource;
     info.end_pos = TokenPosition::kMinSource;
@@ -1212,11 +1230,17 @@
     view.Set<Code::kSCallTableKindAndOffset>(kind_type_and_offset);
     const Object* target = nullptr;
     if (entry->function != nullptr) {
-      view.Set<Code::kSCallTableFunctionTarget>(*calls[i]->function);
+      target = entry->function;
+      view.Set<Code::kSCallTableFunctionTarget>(*entry->function);
     }
-    if (entry->code != NULL) {
+    if (entry->code != nullptr) {
       ASSERT(target == nullptr);
-      view.Set<Code::kSCallTableCodeTarget>(*calls[i]->code);
+      target = entry->code;
+      view.Set<Code::kSCallTableCodeOrTypeTarget>(*entry->code);
+    }
+    if (entry->dst_type != nullptr) {
+      ASSERT(target == nullptr);
+      view.Set<Code::kSCallTableCodeOrTypeTarget>(*entry->dst_type);
     }
   }
   code.set_static_calls_target_table(targets);
@@ -1262,7 +1286,7 @@
     // there are no checks necessary in any case and we can therefore intrinsify
     // them even in checked mode and strong mode.
     switch (parsed_function().function().kind()) {
-      case RawFunction::kImplicitGetter: {
+      case FunctionLayout::kImplicitGetter: {
         Field& field = Field::Handle(function().accessor_field());
         ASSERT(!field.IsNull());
 #if defined(DEBUG)
@@ -1285,7 +1309,7 @@
         }
         return false;
       }
-      case RawFunction::kImplicitSetter: {
+      case FunctionLayout::kImplicitSetter: {
         if (!isolate()->argument_type_checks()) {
           Field& field = Field::Handle(function().accessor_field());
           ASSERT(!field.IsNull());
@@ -1306,7 +1330,7 @@
         break;
       }
 #if !defined(TARGET_ARCH_IA32)
-      case RawFunction::kMethodExtractor: {
+      case FunctionLayout::kMethodExtractor: {
         auto& extracted_method = Function::ZoneHandle(
             parsed_function().function().extracted_method_closure());
         auto& klass = Class::Handle(extracted_method.Owner());
@@ -1346,22 +1370,14 @@
   return complete;
 }
 
-void FlowGraphCompiler::GenerateCallWithDeopt(TokenPosition token_pos,
-                                              intptr_t deopt_id,
-                                              const Code& stub,
-                                              RawPcDescriptors::Kind kind,
-                                              LocationSummary* locs) {
-  GenerateCall(token_pos, stub, kind, locs);
-  if (!FLAG_precompiled_mode) {
-    const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id);
-    if (is_optimizing()) {
-      AddDeoptIndexAtCall(deopt_id_after);
-    } else {
-      // Add deoptimization continuation point after the call and before the
-      // arguments are removed.
-      AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
-    }
-  }
+void FlowGraphCompiler::GenerateStubCall(TokenPosition token_pos,
+                                         const Code& stub,
+                                         PcDescriptorsLayout::Kind kind,
+                                         LocationSummary* locs,
+                                         intptr_t deopt_id,
+                                         Environment* env) {
+  EmitCallToStub(stub);
+  EmitCallsiteMetadata(token_pos, deopt_id, kind, locs, env);
 }
 
 static const Code& StubEntryFor(const ICData& ic_data, bool optimized) {
@@ -1459,7 +1475,7 @@
               ->raw();
       call_ic_data = call_ic_data.Original();
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRewind, deopt_id, token_pos);
     EmitUnoptimizedStaticCall(args_info.size_with_type_args, deopt_id,
                               token_pos, locs, call_ic_data, entry_kind);
   }
@@ -2071,8 +2087,8 @@
   if (class_id < 0) return false;
   if (class_id >= isolate->class_table()->NumCids()) return false;
 
-  RawClass* raw_class = isolate->class_table()->At(class_id);
-  if (raw_class == NULL) return false;
+  ClassPtr raw_class = isolate->class_table()->At(class_id);
+  if (raw_class == nullptr) return false;
   Class& cls = Class::Handle(zone, raw_class);
   if (cls.IsNull()) return false;
   if (!cls.is_finalized()) return false;
@@ -2188,7 +2204,7 @@
     // Do not use the code from the function, but let the code be patched so
     // that we can record the outgoing edges to other code.
     const Function& function = *targets.TargetAt(smi_case)->target;
-    GenerateStaticDartCall(deopt_id, token_index, RawPcDescriptors::kOther,
+    GenerateStaticDartCall(deopt_id, token_index, PcDescriptorsLayout::kOther,
                            locs, function, entry_kind);
     __ Drop(args_info.size_with_type_args);
     if (match_found != NULL) {
@@ -2238,7 +2254,7 @@
     // Do not use the code from the function, but let the code be patched so
     // that we can record the outgoing edges to other code.
     const Function& function = *targets.TargetAt(i)->target;
-    GenerateStaticDartCall(deopt_id, token_index, RawPcDescriptors::kOther,
+    GenerateStaticDartCall(deopt_id, token_index, PcDescriptorsLayout::kOther,
                            locs, function, entry_kind);
     __ Drop(args_info.size_with_type_args);
     if (!is_last_check || add_megamorphic_call) {
@@ -2325,7 +2341,7 @@
   // test instead of a 6-type test.
   AbstractType& bound = AbstractType::Handle(zone(), type_param.bound());
   bound = bound.UnwrapFutureOr();
-  return !bound.IsTopType() && !bound.IsObjectType() &&
+  return !bound.IsTopTypeForSubtyping() && !bound.IsObjectType() &&
                  !bound.IsFunctionType() && !bound.IsDartFunctionType() &&
                  bound.IsType()
              ? kTestTypeFourArgs
@@ -2333,6 +2349,7 @@
 }
 
 void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
+    CompileType* receiver_type,
     const AbstractType& dst_type,
     const String& dst_name,
     const Register dst_type_reg_to_call,
@@ -2351,14 +2368,17 @@
   if (int_type.IsSubtypeOf(dst_type, Heap::kOld)) {
     __ BranchIfSmi(TypeTestABI::kInstanceReg, done);
     is_non_smi = true;
+  } else if (receiver_type->IsNotSmi()) {
+    is_non_smi = true;
   }
 
   // We use two type registers iff the dst type is a type parameter.
   // We "dereference" the type parameter for the TTS call but leave the type
   // parameter in the TypeTestABI::kDstTypeReg for fallback into
   // SubtypeTestCache.
-  ASSERT(dst_type.IsTypeParameter() ==
-         (TypeTestABI::kDstTypeReg != dst_type_reg_to_call));
+  ASSERT(dst_type_reg_to_call == kNoRegister ||
+         (dst_type.IsTypeParameter() ==
+          (TypeTestABI::kDstTypeReg != dst_type_reg_to_call)));
 
   // We can handle certain types very efficiently on the call site (with a
   // bailout to the normal stub, which will do a runtime call).
@@ -2519,29 +2539,26 @@
       instruction()->UseSharedSlowPathStub(compiler->is_optimizing());
   const bool live_fpu_registers =
       instruction()->locs()->live_registers()->FpuRegisterCount() > 0;
-  ASSERT(!use_shared_stub || num_args_ == 0);
   __ Bind(entry_label());
   EmitCodeAtSlowPathEntry(compiler);
   LocationSummary* locs = instruction()->locs();
   // Save registers as they are needed for lazy deopt / exception handling.
-  if (!use_shared_stub) {
-    compiler->SaveLiveRegisters(locs);
-  }
-  intptr_t i = 0;
-  if (num_args_ % 2 != 0) {
-    __ PushRegister(locs->in(i).reg());
-    ++i;
-  }
-  for (; i < num_args_; i += 2) {
-    __ PushRegisterPair(locs->in(i + 1).reg(), locs->in(i).reg());
-  }
   if (use_shared_stub) {
     EmitSharedStubCall(compiler, live_fpu_registers);
   } else {
+    compiler->SaveLiveRegisters(locs);
+    intptr_t i = 0;
+    if (num_args_ % 2 != 0) {
+      __ PushRegister(locs->in(i).reg());
+      ++i;
+    }
+    for (; i < num_args_; i += 2) {
+      __ PushRegisterPair(locs->in(i + 1).reg(), locs->in(i).reg());
+    }
     __ CallRuntime(runtime_entry_, num_args_);
   }
   const intptr_t deopt_id = instruction()->deopt_id();
-  compiler->AddDescriptor(RawPcDescriptors::kOther,
+  compiler->AddDescriptor(PcDescriptorsLayout::kOther,
                           compiler->assembler()->CodeSize(), deopt_id,
                           instruction()->token_pos(), try_index_);
   AddMetadataForRuntimeCall(compiler);
@@ -2788,6 +2805,5 @@
 }
 
 #undef __
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 0c16478..62a91c6 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_COMPILER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_COMPILER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <functional>
 
 #include "vm/allocation.h"
@@ -177,9 +181,9 @@
   }
   virtual ~CompilerDeoptInfo() {}
 
-  RawTypedData* CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                DeoptInfoBuilder* builder,
-                                const Array& deopt_table);
+  TypedDataPtr CreateDeoptInfo(FlowGraphCompiler* compiler,
+                               DeoptInfoBuilder* builder,
+                               const Array& deopt_table);
 
   // No code needs to be generated.
   virtual void GenerateCode(FlowGraphCompiler* compiler, intptr_t stub_ix) {}
@@ -348,6 +352,21 @@
   }
 };
 
+class RangeErrorSlowPath : public ThrowErrorSlowPathCode {
+ public:
+  static const intptr_t kNumberOfArguments = 0;
+
+  RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
+      : ThrowErrorSlowPathCode(instruction,
+                               kRangeErrorRuntimeEntry,
+                               kNumberOfArguments,
+                               try_index) {}
+  virtual const char* name() { return "check bound"; }
+
+  virtual void EmitSharedStubCall(FlowGraphCompiler* compielr,
+                                  bool save_fpu_registers);
+};
+
 class FlowGraphCompiler : public ValueObject {
  private:
   class BlockInfo : public ZoneAllocated {
@@ -441,6 +460,7 @@
   bool is_optimizing() const { return is_optimizing_; }
 
   void InsertBSSRelocation(BSS::Relocation reloc);
+  void LoadBSSEntry(BSS::Relocation relocation, Register dst, Register tmp);
 
   // The function was fully intrinsified, so the body is unreachable.
   //
@@ -548,7 +568,8 @@
                      Representation src_type,
                      TemporaryRegisterAllocator* temp);
 
-  void GenerateAssertAssignable(TokenPosition token_pos,
+  void GenerateAssertAssignable(CompileType* receiver_type,
+                                TokenPosition token_pos,
                                 intptr_t deopt_id,
                                 const AbstractType& dst_type,
                                 const String& dst_name,
@@ -559,13 +580,15 @@
   static bool ShouldUseTypeTestingStubFor(bool optimizing,
                                           const AbstractType& type);
 
-  void GenerateAssertAssignableViaTypeTestingStub(TokenPosition token_pos,
+  void GenerateAssertAssignableViaTypeTestingStub(CompileType* receiver_type,
+                                                  TokenPosition token_pos,
                                                   intptr_t deopt_id,
                                                   const AbstractType& dst_type,
                                                   const String& dst_name,
                                                   LocationSummary* locs);
 
   void GenerateAssertAssignableViaTypeTestingStub(
+      CompileType* receiver_type,
       const AbstractType& dst_type,
       const String& dst_name,
       const Register dst_type_reg_to_call,
@@ -578,33 +601,29 @@
                            intptr_t argument_count,
                            LocationSummary* locs);
 
-  void GenerateCall(TokenPosition token_pos,
-                    const Code& stub,
-                    RawPcDescriptors::Kind kind,
-                    LocationSummary* locs);
-
-  void GenerateCallWithDeopt(TokenPosition token_pos,
-                             intptr_t deopt_id,
-                             const Code& stub,
-                             RawPcDescriptors::Kind kind,
-                             LocationSummary* locs);
+  void GenerateStubCall(TokenPosition token_pos,
+                        const Code& stub,
+                        PcDescriptorsLayout::Kind kind,
+                        LocationSummary* locs,
+                        intptr_t deopt_id = DeoptId::kNone,
+                        Environment* env = nullptr);
 
   void GeneratePatchableCall(TokenPosition token_pos,
                              const Code& stub,
-                             RawPcDescriptors::Kind kind,
+                             PcDescriptorsLayout::Kind kind,
                              LocationSummary* locs);
 
   void GenerateDartCall(intptr_t deopt_id,
                         TokenPosition token_pos,
                         const Code& stub,
-                        RawPcDescriptors::Kind kind,
+                        PcDescriptorsLayout::Kind kind,
                         LocationSummary* locs,
                         Code::EntryKind entry_kind = Code::EntryKind::kNormal);
 
   void GenerateStaticDartCall(
       intptr_t deopt_id,
       TokenPosition token_pos,
-      RawPcDescriptors::Kind kind,
+      PcDescriptorsLayout::Kind kind,
       LocationSummary* locs,
       const Function& target,
       Code::EntryKind entry_kind = Code::EntryKind::kNormal);
@@ -744,6 +763,7 @@
                                       bool needs_number_check,
                                       TokenPosition token_pos,
                                       intptr_t deopt_id);
+  Condition EmitBoolTest(Register value, BranchLabels labels, bool invert);
 
   bool NeedsEdgeCounter(BlockEntryInstr* block);
 
@@ -752,6 +772,9 @@
   void RecordCatchEntryMoves(Environment* env = NULL,
                              intptr_t try_index = kInvalidTryIndex);
 
+  void EmitCallToStub(const Code& stub);
+  void EmitTailCallToStub(const Code& stub);
+
   // Emits the following metadata for the current PC:
   //
   //   * Attaches current try index
@@ -763,7 +786,7 @@
   // `pending_deoptimization_env`.
   void EmitCallsiteMetadata(TokenPosition token_pos,
                             intptr_t deopt_id,
-                            RawPcDescriptors::Kind kind,
+                            PcDescriptorsLayout::Kind kind,
                             LocationSummary* locs,
                             Environment* env = nullptr);
 
@@ -801,16 +824,16 @@
                            const Array& handler_types,
                            bool needs_stacktrace);
   void SetNeedsStackTrace(intptr_t try_index);
-  void AddCurrentDescriptor(RawPcDescriptors::Kind kind,
+  void AddCurrentDescriptor(PcDescriptorsLayout::Kind kind,
                             intptr_t deopt_id,
                             TokenPosition token_pos);
   void AddDescriptor(
-      RawPcDescriptors::Kind kind,
+      PcDescriptorsLayout::Kind kind,
       intptr_t pc_offset,
       intptr_t deopt_id,
       TokenPosition token_pos,
       intptr_t try_index,
-      intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+      intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
 
   // Add NullCheck information for the current PC.
   void AddNullCheck(TokenPosition token_pos, const String& name);
@@ -829,7 +852,7 @@
 
   void FinalizeExceptionHandlers(const Code& code);
   void FinalizePcDescriptors(const Code& code);
-  RawArray* CreateDeoptInfo(compiler::Assembler* assembler);
+  ArrayPtr CreateDeoptInfo(compiler::Assembler* assembler);
   void FinalizeStackMaps(const Code& code);
   void FinalizeVarDescriptors(const Code& code);
   void FinalizeCatchEntryMovesMap(const Code& code);
@@ -907,9 +930,9 @@
   void AddStubCallTarget(const Code& code);
   void AddDispatchTableCallTarget(const compiler::TableSelector* selector);
 
-  RawArray* edge_counters_array() const { return edge_counters_array_.raw(); }
+  ArrayPtr edge_counters_array() const { return edge_counters_array_.raw(); }
 
-  RawArray* InliningIdToFunction() const;
+  ArrayPtr InliningIdToFunction() const;
 
   void BeginCodeSourceRange();
   void EndCodeSourceRange(TokenPosition token_pos);
@@ -943,6 +966,7 @@
   friend class CheckStackOverflowSlowPath;  // For pending_deoptimization_env_.
   friend class CheckedSmiSlowPath;          // Same.
   friend class CheckedSmiComparisonSlowPath;  // Same.
+  friend class InitInstanceFieldInstr;        // Same.
 
   // Architecture specific implementation of simple native moves.
   void EmitNativeMoveArchitecture(const compiler::ffi::NativeLocation& dst,
@@ -954,6 +978,8 @@
   void AddPcRelativeCallTarget(const Function& function,
                                Code::EntryKind entry_kind);
   void AddPcRelativeCallStubTarget(const Code& stub_code);
+  void AddPcRelativeTailCallStubTarget(const Code& stub_code);
+  void AddPcRelativeTTSCallTypeTarget(const AbstractType& type);
   void AddStaticCallTarget(const Function& function,
                            Code::EntryKind entry_kind);
 
@@ -1004,13 +1030,13 @@
                      compiler::Label* is_instance_lbl,
                      compiler::Label* is_not_instance_lbl);
 
-  RawSubtypeTestCache* GenerateInlineInstanceof(
+  SubtypeTestCachePtr GenerateInlineInstanceof(
       TokenPosition token_pos,
       const AbstractType& type,
       compiler::Label* is_instance_lbl,
       compiler::Label* is_not_instance_lbl);
 
-  RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest(
+  SubtypeTestCachePtr GenerateInstantiatedTypeWithArgumentsTest(
       TokenPosition token_pos,
       const AbstractType& dst_type,
       compiler::Label* is_instance_lbl,
@@ -1022,19 +1048,19 @@
       compiler::Label* is_instance_lbl,
       compiler::Label* is_not_instance_lbl);
 
-  RawSubtypeTestCache* GenerateUninstantiatedTypeTest(
+  SubtypeTestCachePtr GenerateUninstantiatedTypeTest(
       TokenPosition token_pos,
       const AbstractType& dst_type,
       compiler::Label* is_instance_lbl,
       compiler::Label* is_not_instance_label);
 
-  RawSubtypeTestCache* GenerateFunctionTypeTest(
+  SubtypeTestCachePtr GenerateFunctionTypeTest(
       TokenPosition token_pos,
       const AbstractType& dst_type,
       compiler::Label* is_instance_lbl,
       compiler::Label* is_not_instance_label);
 
-  RawSubtypeTestCache* GenerateSubtype1TestCacheLookup(
+  SubtypeTestCachePtr GenerateSubtype1TestCacheLookup(
       TokenPosition token_pos,
       const Class& type_class,
       compiler::Label* is_instance_lbl,
@@ -1051,7 +1077,7 @@
   TypeTestStubKind GetTypeTestStubKindForTypeParameter(
       const TypeParameter& type_param);
 
-  RawSubtypeTestCache* GenerateCallSubtypeTestStub(
+  SubtypeTestCachePtr GenerateCallSubtypeTestStub(
       TypeTestStubKind test_kind,
       Register instance_reg,
       Register instantiator_type_arguments_reg,
@@ -1131,21 +1157,27 @@
     Code::CallKind call_kind;
     Code::CallEntryPoint entry_point;
     const intptr_t offset;
-    const Function* function;  // Can be NULL.
-    const Code* code;          // Can be NULL.
+    const Function* function;      // Can be nullptr.
+    const Code* code;              // Can be nullptr.
+    const AbstractType* dst_type;  // Can be nullptr.
     StaticCallsStruct(Code::CallKind call_kind,
                       Code::CallEntryPoint entry_point,
                       intptr_t offset_arg,
                       const Function* function_arg,
-                      const Code* code_arg)
+                      const Code* code_arg,
+                      const AbstractType* dst_type)
         : call_kind(call_kind),
           entry_point(entry_point),
           offset(offset_arg),
           function(function_arg),
-          code(code_arg) {
-      ASSERT((function == NULL) || function->IsZoneHandle());
-      ASSERT((code == NULL) || code->IsZoneHandle() ||
+          code(code_arg),
+          dst_type(dst_type) {
+      ASSERT(function == nullptr || function->IsZoneHandle());
+      ASSERT(code == nullptr || code->IsZoneHandle() ||
              code->IsReadOnlyHandle());
+      ASSERT(dst_type == nullptr || dst_type->IsZoneHandle() ||
+             dst_type->IsReadOnlyHandle());
+      ASSERT(code == nullptr || dst_type == nullptr);
     }
 
    private:
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index c32f5d1..58b1ee1 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM)
 
 #include "vm/compiler/backend/flow_graph_compiler.h"
 
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/jit/compiler.h"
@@ -98,9 +99,9 @@
   intrinsic_mode_ = false;
 }
 
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder,
-                                                 const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+                                                DeoptInfoBuilder* builder,
+                                                const Array& deopt_table) {
   if (deopt_env_ == NULL) {
     ++builder->current_info_number_;
     return TypedData::null();
@@ -214,8 +215,11 @@
   compiler::Label fall_through;
   __ CompareObject(bool_register, Object::null_object());
   __ b(&fall_through, EQ);
-  __ CompareObject(bool_register, Bool::True());
-  __ b(is_true, EQ);
+  BranchLabels labels = {is_true, is_false, &fall_through};
+  Condition true_condition =
+      EmitBoolTest(bool_register, labels, /*invert=*/false);
+  ASSERT(true_condition != kInvalidCondition);
+  __ b(is_true, true_condition);
   __ b(is_false);
   __ Bind(&fall_through);
 }
@@ -224,7 +228,7 @@
 // R2: instantiator type arguments (if used).
 // R1: function type arguments (if used).
 // R3: type test cache.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
     TypeTestStubKind test_kind,
     Register instance_reg,
     Register instantiator_type_arguments_reg,
@@ -270,7 +274,7 @@
 // be completed.
 // R0: instance being type checked (preserved).
 // Clobbers R1, R2.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
     TokenPosition token_pos,
     const AbstractType& type,
@@ -314,7 +318,7 @@
   if (type_arguments.Length() == 1) {
     const AbstractType& tp_argument =
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopType()) {
+    if (tp_argument.IsTopTypeForSubtyping()) {
       // Instance class test only necessary.
       return GenerateSubtype1TestCacheLookup(
           token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -413,7 +417,7 @@
 // TODO(srdjan): Implement a quicker subtype check, as type test
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
     TokenPosition token_pos,
     const Class& type_class,
     compiler::Label* is_instance_lbl,
@@ -428,13 +432,17 @@
   __ LoadClassId(R2, TypeTestABI::kInstanceReg);
   __ LoadClassById(R1, R2);
   // R1: instance class.
-  // Check immediate superclass equality.
-  __ ldr(R2, compiler::FieldAddress(
-                 R1, compiler::target::Class::super_type_offset()));
-  __ ldr(R2, compiler::FieldAddress(
-                 R2, compiler::target::Type::type_class_id_offset()));
-  __ CompareImmediate(R2, Smi::RawValue(type_class.id()));
-  __ b(is_instance_lbl, EQ);
+  // Check immediate superclass equality. If type_class is Object, then testing
+  // supertype may yield a wrong result for Null in NNBD strong mode (because
+  // Null also extends Object).
+  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
+    __ ldr(R2, compiler::FieldAddress(
+                   R1, compiler::target::Class::super_type_offset()));
+    __ ldr(R2, compiler::FieldAddress(
+                   R2, compiler::target::Type::type_class_id_offset()));
+    __ CompareImmediate(R2, Smi::RawValue(type_class.id()));
+    __ b(is_instance_lbl, EQ);
+  }
 
   const Register kInstantiatorTypeArgumentsReg = kNoRegister;
   const Register kFunctionTypeArgumentsReg = kNoRegister;
@@ -447,7 +455,7 @@
 
 // Generates inlined check if 'type' is a type parameter or type itself
 // R0: instance (preserved).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -532,7 +540,7 @@
 // Generates function type check.
 //
 // See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -565,7 +573,7 @@
 // Note that this inlined code must be followed by the runtime_call code, as it
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -618,7 +626,7 @@
                                            const AbstractType& type,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopType());  // Already checked.
+  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
   static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
                     TypeTestABI::kInstantiatorTypeArgumentsReg,
                 "Should be ordered to push arguments with one instruction");
@@ -657,18 +665,10 @@
     __ ldm(IA, SP,
            (1 << TypeTestABI::kFunctionTypeArgumentsReg) |
                (1 << TypeTestABI::kInstantiatorTypeArgumentsReg));
-    __ PushObject(Object::null_object());  // Make room for the result.
-    __ Push(TypeTestABI::kInstanceReg);    // Push the instance.
-    __ PushObject(type);                   // Push the type.
-    __ PushList((1 << TypeTestABI::kInstantiatorTypeArgumentsReg) |
-                (1 << TypeTestABI::kFunctionTypeArgumentsReg));
-    __ LoadUniqueObject(R0, test_cache);
-    __ Push(R0);
-    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
-    // Pop the parameters supplied to the runtime entry. The result of the
-    // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
-    __ Pop(R0);
+    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
+    GenerateStubCall(token_pos, StubCode::InstanceOf(),
+                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
     __ b(&done);
   }
   __ Bind(&is_not_instance);
@@ -694,7 +694,8 @@
 // - object in R0 for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(CompileType* receiver_type,
+                                                 TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
@@ -703,11 +704,11 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(!dst_type.IsTopTypeForAssignability());
+  ASSERT(!dst_type.IsTopTypeForSubtyping());
 
   if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
-    GenerateAssertAssignableViaTypeTestingStub(token_pos, deopt_id, dst_type,
-                                               dst_name, locs);
+    GenerateAssertAssignableViaTypeTestingStub(
+        receiver_type, token_pos, deopt_id, dst_type, dst_name, locs);
   } else {
     compiler::Label is_assignable_fast, is_assignable, runtime_call;
 
@@ -756,19 +757,28 @@
 }
 
 void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
+    CompileType* receiver_type,
     TokenPosition token_pos,
     intptr_t deopt_id,
     const AbstractType& dst_type,
     const String& dst_name,
     LocationSummary* locs) {
+  // If the dst_type is instantiated we know the target TTS stub at
+  // compile-time and can therefore use a pc-relative call.
+  const bool use_pc_relative_call = dst_type.IsInstantiated() &&
+                                    FLAG_precompiled_mode &&
+                                    FLAG_use_bare_instructions;
+
   const Register kRegToCall =
-      dst_type.IsTypeParameter() ? R9 : TypeTestABI::kDstTypeReg;
+      use_pc_relative_call
+          ? kNoRegister
+          : (dst_type.IsTypeParameter() ? R9 : TypeTestABI::kDstTypeReg);
   const Register kScratchReg = R4;
 
   compiler::Label done;
 
-  GenerateAssertAssignableViaTypeTestingStub(dst_type, dst_name, kRegToCall,
-                                             kScratchReg, &done);
+  GenerateAssertAssignableViaTypeTestingStub(receiver_type, dst_type, dst_name,
+                                             kRegToCall, kScratchReg, &done);
 
   // We use 2 consecutive entries in the pool for the subtype cache and the
   // destination name.  The second entry, namely [dst_name] seems to be unused,
@@ -786,15 +796,20 @@
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
-  __ LoadField(
-      R9,
-      compiler::FieldAddress(
-          kRegToCall,
-          compiler::target::AbstractType::type_test_stub_entry_point_offset()));
-  __ LoadWordFromPoolOffset(TypeTestABI::kSubtypeTestCacheReg,
-                            sub_type_cache_offset, PP, AL);
-  __ blx(R9);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  if (use_pc_relative_call) {
+    __ LoadWordFromPoolOffset(TypeTestABI::kSubtypeTestCacheReg,
+                              sub_type_cache_offset, PP);
+    __ GenerateUnRelocatedPcRelativeCall();
+    AddPcRelativeTTSCallTypeTarget(dst_type);
+  } else {
+    __ LoadField(R9, compiler::FieldAddress(
+                         kRegToCall, compiler::target::AbstractType::
+                                         type_test_stub_entry_point_offset()));
+    __ LoadWordFromPoolOffset(TypeTestABI::kSubtypeTestCacheReg,
+                              sub_type_cache_offset, PP);
+    __ blx(R9);
+  }
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
   __ Bind(&done);
 }
 
@@ -968,26 +983,40 @@
   }
 }
 
-void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
-                                     const Code& stub,
-                                     RawPcDescriptors::Kind kind,
-                                     LocationSummary* locs) {
+void FlowGraphCompiler::EmitCallToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
       !stub.InVMIsolateHeap()) {
     __ GenerateUnRelocatedPcRelativeCall();
     AddPcRelativeCallStubTarget(stub);
-    EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
   } else {
-    ASSERT(!stub.IsNull());
     __ BranchLink(stub);
-    EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
+    AddStubCallTarget(stub);
+  }
+}
+
+void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
+      !stub.InVMIsolateHeap()) {
+    __ LeaveDartFrame();
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+#if defined(DEBUG)
+    __ Breakpoint();
+#endif
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ LeaveDartFrame();
+    __ ldr(PC, compiler::FieldAddress(
+                   CODE_REG, compiler::target::Code::entry_point_offset()));
     AddStubCallTarget(stub);
   }
 }
 
 void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
                                               const Code& stub,
-                                              RawPcDescriptors::Kind kind,
+                                              PcDescriptorsLayout::Kind kind,
                                               LocationSummary* locs) {
   __ BranchLinkPatchable(stub);
   EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
@@ -996,7 +1025,7 @@
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
                                          TokenPosition token_pos,
                                          const Code& stub,
-                                         RawPcDescriptors::Kind kind,
+                                         PcDescriptorsLayout::Kind kind,
                                          LocationSummary* locs,
                                          Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
@@ -1006,7 +1035,7 @@
 
 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
                                                TokenPosition token_pos,
-                                               RawPcDescriptors::Kind kind,
+                                               PcDescriptorsLayout::Kind kind,
                                                LocationSummary* locs,
                                                const Function& target,
                                                Code::EntryKind entry_kind) {
@@ -1034,7 +1063,7 @@
                                             intptr_t argument_count,
                                             LocationSummary* locs) {
   __ CallRuntime(entry, argument_count);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
 }
 
 void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) {
@@ -1080,8 +1109,8 @@
   __ LoadFromOffset(kWord, R0, SP,
                     (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
   __ LoadUniqueObject(R9, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
-                   entry_kind);
+  GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+                   locs, entry_kind);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
 
@@ -1105,7 +1134,7 @@
           : Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
   __ ldr(LR, compiler::FieldAddress(CODE_REG, entry_point_offset));
   __ blx(LR);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
 
@@ -1128,13 +1157,29 @@
   // Load receiver into R0.
   __ LoadFromOffset(kWord, R0, SP,
                     (args_desc.Count() - 1) * compiler::target::kWordSize);
-  __ LoadObject(R9, cache);
-  __ ldr(
-      LR,
-      compiler::Address(
-          THR,
-          compiler::target::Thread::megamorphic_call_checked_entry_offset()));
-  __ blx(LR);
+  // Use same code pattern as instance call so it can be parsed by code patcher.
+  if (FLAG_precompiled_mode) {
+    if (FLAG_use_bare_instructions) {
+      // The AOT runtime will replace the slot in the object pool with the
+      // entrypoint address - see clustered_snapshot.cc.
+      __ LoadUniqueObject(LR, StubCode::MegamorphicCall());
+    } else {
+      __ LoadUniqueObject(CODE_REG, StubCode::MegamorphicCall());
+      __ ldr(LR, compiler::FieldAddress(
+                     CODE_REG, compiler::target::Code::entry_point_offset(
+                                   Code::EntryKind::kMonomorphic)));
+    }
+    __ LoadUniqueObject(R9, cache);
+    __ blx(LR);
+
+  } else {
+    __ LoadUniqueObject(R9, cache);
+    __ LoadUniqueObject(CODE_REG, StubCode::MegamorphicCall());
+    __ ldr(LR, compiler::FieldAddress(
+                   CODE_REG,
+                   Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
+    __ blx(LR);
+  }
 
   RecordSafepoint(locs, slow_path_argument_count);
   const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id);
@@ -1144,16 +1189,19 @@
     if (try_index == kInvalidTryIndex) {
       try_index = CurrentTryIndex();
     }
-    AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+    AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
                   DeoptId::kNone, token_pos, try_index);
   } else if (is_optimizing()) {
-    AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+                         token_pos);
     AddDeoptIndexAtCall(deopt_id_after);
   } else {
-    AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+                         token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
-    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+                         token_pos);
   }
   RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.SizeWithTypeArgs());
@@ -1169,7 +1217,7 @@
   ASSERT(entry_kind == Code::EntryKind::kNormal ||
          entry_kind == Code::EntryKind::kUnchecked);
   ASSERT(ic_data.NumArgsTested() == 1);
-  const Code& initial_stub = StubCode::UnlinkedCall();
+  const Code& initial_stub = StubCode::SwitchableCallMiss();
   const char* switchable_call_mode = "smiable";
   if (!receiver_can_be_smi) {
     switchable_call_mode = "non-smi";
@@ -1199,7 +1247,7 @@
   __ LoadUniqueObject(R9, data);
   __ blx(LR);
 
-  EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
+  EmitCallsiteMetadata(token_pos, DeoptId::kNone, PcDescriptorsLayout::kOther,
                        locs);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
@@ -1215,7 +1263,7 @@
       StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
   __ LoadObject(R9, ic_data);
   GenerateDartCall(deopt_id, token_pos, stub,
-                   RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+                   PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
   __ Drop(size_with_type_args);
 }
 
@@ -1238,7 +1286,7 @@
   }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
-  GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+  GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
                          function, entry_kind);
   __ Drop(size_with_type_args);
 }
@@ -1285,7 +1333,8 @@
     } else {
       __ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmp, we need Z computed).
     __ Drop(1);   // Discard constant.
     __ Pop(reg);  // Restore 'reg'.
@@ -1308,7 +1357,8 @@
     } else {
       __ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmp, we need Z computed).
     __ Pop(right);
     __ Pop(left);
@@ -1318,6 +1368,15 @@
   return EQ;
 }
 
+Condition FlowGraphCompiler::EmitBoolTest(Register value,
+                                          BranchLabels labels,
+                                          bool invert) {
+  __ Comment("BoolTest");
+  __ tst(value,
+         compiler::Operand(compiler::target::ObjectAlignment::kBoolValueMask));
+  return invert ? NE : EQ;
+}
+
 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
 // FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
@@ -1663,6 +1722,31 @@
   }
 }
 
+void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
+                                     Register dst,
+                                     Register tmp) {
+  compiler::Label skip_reloc;
+  __ b(&skip_reloc);
+  InsertBSSRelocation(relocation);
+  __ Bind(&skip_reloc);
+
+  // For historical reasons, the PC on ARM points 8 bytes (two instructions)
+  // past the current instruction.
+  __ sub(tmp, PC,
+         compiler::Operand(Instr::kPCReadOffset + compiler::target::kWordSize));
+
+  // tmp holds the address of the relocation.
+  __ ldr(dst, compiler::Address(tmp));
+
+  // dst holds the relocation itself: tmp - bss_start.
+  // tmp = tmp + (bss_start - tmp) = bss_start
+  __ add(tmp, tmp, compiler::Operand(dst));
+
+  // tmp holds the start of the BSS section.
+  // Load the "get-thread" routine: *bss_start.
+  __ ldr(dst, compiler::Address(tmp));
+}
+
 #undef __
 #define __ compiler_->assembler()->
 
@@ -1830,4 +1914,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 20cc37d..60bad9af 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM64)
 
 #include "vm/compiler/backend/flow_graph_compiler.h"
 
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/jit/compiler.h"
@@ -92,9 +93,9 @@
   intrinsic_mode_ = false;
 }
 
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder,
-                                                 const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+                                                DeoptInfoBuilder* builder,
+                                                const Array& deopt_table) {
   if (deopt_env_ == NULL) {
     ++builder->current_info_number_;
     return TypedData::null();
@@ -206,16 +207,17 @@
   compiler::Label fall_through;
   __ CompareObject(bool_register, Object::null_object());
   __ b(&fall_through, EQ);
-  __ CompareObject(bool_register, Bool::True());
-  __ b(is_true, EQ);
-  __ b(is_false);
+  BranchLabels labels = {is_true, is_false, &fall_through};
+  Condition true_condition =
+      EmitBoolTest(bool_register, labels, /*invert=*/false);
+  ASSERT(true_condition == kInvalidCondition);
   __ Bind(&fall_through);
 }
 
 // R0: instance (must be preserved).
 // R2: instantiator type arguments (if used).
 // R1: function type arguments (if used).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
     TypeTestStubKind test_kind,
     Register instance_reg,
     Register instantiator_type_arguments_reg,
@@ -261,7 +263,7 @@
 // be completed.
 // R0: instance being type checked (preserved).
 // Clobbers R1, R2.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
     TokenPosition token_pos,
     const AbstractType& type,
@@ -302,7 +304,7 @@
   if (type_arguments.Length() == 1) {
     const AbstractType& tp_argument =
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopType()) {
+    if (tp_argument.IsTopTypeForSubtyping()) {
       // Instance class test only necessary.
       return GenerateSubtype1TestCacheLookup(
           token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -399,7 +401,7 @@
 // TODO(srdjan): Implement a quicker subtype check, as type test
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
     TokenPosition token_pos,
     const Class& type_class,
     compiler::Label* is_instance_lbl,
@@ -414,11 +416,15 @@
   __ LoadClassId(TMP, TypeTestABI::kInstanceReg);
   __ LoadClassById(R1, TMP);
   // R1: instance class.
-  // Check immediate superclass equality.
-  __ LoadFieldFromOffset(R2, R1, Class::super_type_offset());
-  __ LoadFieldFromOffset(R2, R2, Type::type_class_id_offset());
-  __ CompareImmediate(R2, Smi::RawValue(type_class.id()));
-  __ b(is_instance_lbl, EQ);
+  // Check immediate superclass equality. If type_class is Object, then testing
+  // supertype may yield a wrong result for Null in NNBD strong mode (because
+  // Null also extends Object).
+  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
+    __ LoadFieldFromOffset(R2, R1, Class::super_type_offset());
+    __ LoadFieldFromOffset(R2, R2, Type::type_class_id_offset());
+    __ CompareImmediate(R2, Smi::RawValue(type_class.id()));
+    __ b(is_instance_lbl, EQ);
+  }
 
   const Register kInstantiatorTypeArgumentsReg = kNoRegister;
   const Register kFunctionTypeArgumentsReg = kNoRegister;
@@ -431,7 +437,7 @@
 
 // Generates inlined check if 'type' is a type parameter or type itself
 // R0: instance (preserved).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -509,7 +515,7 @@
 // Generates function type check.
 //
 // See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -539,7 +545,7 @@
 // Note that this inlined code must be followed by the runtime_call code, as it
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -592,7 +598,7 @@
                                            const AbstractType& type,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopType());  // Already checked.
+  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
   __ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
               TypeTestABI::kInstantiatorTypeArgumentsReg);
 
@@ -625,19 +631,10 @@
     __ ldp(TypeTestABI::kFunctionTypeArgumentsReg,
            TypeTestABI::kInstantiatorTypeArgumentsReg,
            compiler::Address(SP, 0 * kWordSize, compiler::Address::PairOffset));
-    __ PushPair(TypeTestABI::kInstanceReg,
-                NULL_REG);      // Make room for the result and
-                                // push the instance.
-    __ LoadObject(TMP, type);   // Push the type.
-
-    __ PushPair(TypeTestABI::kInstantiatorTypeArgumentsReg, TMP);
-    __ LoadUniqueObject(R0, test_cache);
-    __ PushPair(R0, TypeTestABI::kFunctionTypeArgumentsReg);
-    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
-    // Pop the parameters supplied to the runtime entry. The result of the
-    // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
-    __ Pop(R0);
+    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
+    GenerateStubCall(token_pos, StubCode::InstanceOf(),
+                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
     __ b(&done);
   }
   __ Bind(&is_not_instance);
@@ -663,7 +660,8 @@
 // - object in R0 for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(CompileType* receiver_type,
+                                                 TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
@@ -672,11 +670,11 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(!dst_type.IsTopTypeForAssignability());
+  ASSERT(!dst_type.IsTopTypeForSubtyping());
 
   if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
-    GenerateAssertAssignableViaTypeTestingStub(token_pos, deopt_id, dst_type,
-                                               dst_name, locs);
+    GenerateAssertAssignableViaTypeTestingStub(
+        receiver_type, token_pos, deopt_id, dst_type, dst_name, locs);
   } else {
     compiler::Label is_assignable_fast, is_assignable, runtime_call;
 
@@ -721,19 +719,28 @@
 }
 
 void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
+    CompileType* receiver_type,
     TokenPosition token_pos,
     intptr_t deopt_id,
     const AbstractType& dst_type,
     const String& dst_name,
     LocationSummary* locs) {
+  // If the dst_type is instantiated we know the target TTS stub at
+  // compile-time and can therefore use a pc-relative call.
+  const bool use_pc_relative_call = dst_type.IsInstantiated() &&
+                                    FLAG_precompiled_mode &&
+                                    FLAG_use_bare_instructions;
+
   const Register kRegToCall =
-      dst_type.IsTypeParameter() ? R9 : TypeTestABI::kDstTypeReg;
+      use_pc_relative_call
+          ? kNoRegister
+          : (dst_type.IsTypeParameter() ? R9 : TypeTestABI::kDstTypeReg);
   const Register kScratchReg = R4;
 
   compiler::Label done;
 
-  GenerateAssertAssignableViaTypeTestingStub(dst_type, dst_name, kRegToCall,
-                                             kScratchReg, &done);
+  GenerateAssertAssignableViaTypeTestingStub(receiver_type, dst_type, dst_name,
+                                             kRegToCall, kScratchReg, &done);
 
   // We use 2 consecutive entries in the pool for the subtype cache and the
   // destination name.  The second entry, namely [dst_name] seems to be unused,
@@ -750,13 +757,20 @@
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
-  __ LoadField(
-      R9, compiler::FieldAddress(
-              kRegToCall, AbstractType::type_test_stub_entry_point_offset()));
-  __ LoadWordFromPoolOffset(TypeTestABI::kSubtypeTestCacheReg,
-                            sub_type_cache_offset);
-  __ blr(R9);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  if (use_pc_relative_call) {
+    __ LoadWordFromPoolOffset(TypeTestABI::kSubtypeTestCacheReg,
+                              sub_type_cache_offset);
+    __ GenerateUnRelocatedPcRelativeCall();
+    AddPcRelativeTTSCallTypeTarget(dst_type);
+  } else {
+    __ LoadField(
+        R9, compiler::FieldAddress(
+                kRegToCall, AbstractType::type_test_stub_entry_point_offset()));
+    __ LoadWordFromPoolOffset(TypeTestABI::kSubtypeTestCacheReg,
+                              sub_type_cache_offset);
+    __ blr(R9);
+  }
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
   __ Bind(&done);
 }
 
@@ -929,26 +943,41 @@
   }
 }
 
-void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
-                                     const Code& stub,
-                                     RawPcDescriptors::Kind kind,
-                                     LocationSummary* locs) {
+void FlowGraphCompiler::EmitCallToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
       !stub.InVMIsolateHeap()) {
     __ GenerateUnRelocatedPcRelativeCall();
     AddPcRelativeCallStubTarget(stub);
-    EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
   } else {
-    ASSERT(!stub.IsNull());
     __ BranchLink(stub);
-    EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
+    AddStubCallTarget(stub);
+  }
+}
+
+void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
+      !stub.InVMIsolateHeap()) {
+    __ LeaveDartFrame();
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+#if defined(DEBUG)
+    __ Breakpoint();
+#endif
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ LeaveDartFrame();
+    __ ldr(TMP, compiler::FieldAddress(
+                    CODE_REG, compiler::target::Code::entry_point_offset()));
+    __ br(TMP);
     AddStubCallTarget(stub);
   }
 }
 
 void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
                                               const Code& stub,
-                                              RawPcDescriptors::Kind kind,
+                                              PcDescriptorsLayout::Kind kind,
                                               LocationSummary* locs) {
   __ BranchLinkPatchable(stub);
   EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
@@ -957,7 +986,7 @@
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
                                          TokenPosition token_pos,
                                          const Code& stub,
-                                         RawPcDescriptors::Kind kind,
+                                         PcDescriptorsLayout::Kind kind,
                                          LocationSummary* locs,
                                          Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
@@ -967,7 +996,7 @@
 
 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
                                                TokenPosition token_pos,
-                                               RawPcDescriptors::Kind kind,
+                                               PcDescriptorsLayout::Kind kind,
                                                LocationSummary* locs,
                                                const Function& target,
                                                Code::EntryKind entry_kind) {
@@ -995,7 +1024,7 @@
                                             intptr_t argument_count,
                                             LocationSummary* locs) {
   __ CallRuntime(entry, argument_count);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
 }
 
 void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) {
@@ -1031,8 +1060,8 @@
   __ LoadObject(R6, parsed_function().function());
   __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
   __ LoadUniqueObject(R5, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
-                   entry_kind);
+  GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+                   locs, entry_kind);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
 
@@ -1062,7 +1091,7 @@
           : Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
   __ ldr(LR, compiler::FieldAddress(CODE_REG, entry_point_offset));
   __ blr(LR);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
 
@@ -1085,9 +1114,25 @@
   // Load receiver into R0.
   __ LoadFromOffset(R0, SP, (args_desc.Count() - 1) * kWordSize);
 
-  __ LoadObject(R5, cache);
-  __ ldr(LR, compiler::Address(
-                 THR, Thread::megamorphic_call_checked_entry_offset()));
+  // Use same code pattern as instance call so it can be parsed by code patcher.
+  compiler::ObjectPoolBuilder& op = __ object_pool_builder();
+  const intptr_t data_index =
+      op.AddObject(cache, ObjectPool::Patchability::kPatchable);
+  const intptr_t stub_index = op.AddObject(
+      StubCode::MegamorphicCall(), ObjectPool::Patchability::kPatchable);
+  ASSERT((data_index + 1) == stub_index);
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    // The AOT runtime will replace the slot in the object pool with the
+    // entrypoint address - see clustered_snapshot.cc.
+    __ LoadDoubleWordFromPoolOffset(R5, LR,
+                                    ObjectPool::element_offset(data_index));
+  } else {
+    __ LoadDoubleWordFromPoolOffset(R5, CODE_REG,
+                                    ObjectPool::element_offset(data_index));
+    __ ldr(LR, compiler::FieldAddress(
+                   CODE_REG,
+                   Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
+  }
   __ blr(LR);
 
   RecordSafepoint(locs, slow_path_argument_count);
@@ -1098,16 +1143,19 @@
     if (try_index == kInvalidTryIndex) {
       try_index = CurrentTryIndex();
     }
-    AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+    AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
                   DeoptId::kNone, token_pos, try_index);
   } else if (is_optimizing()) {
-    AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+                         token_pos);
     AddDeoptIndexAtCall(deopt_id_after);
   } else {
-    AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+                         token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
-    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+                         token_pos);
   }
   RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.SizeWithTypeArgs());
@@ -1121,7 +1169,7 @@
                                             bool receiver_can_be_smi) {
   ASSERT(CanCallDart());
   ASSERT(ic_data.NumArgsTested() == 1);
-  const Code& initial_stub = StubCode::UnlinkedCall();
+  const Code& initial_stub = StubCode::SwitchableCallMiss();
   const char* switchable_call_mode = "smiable";
   if (!receiver_can_be_smi) {
     switchable_call_mode = "non-smi";
@@ -1133,6 +1181,9 @@
   compiler::ObjectPoolBuilder& op = __ object_pool_builder();
 
   __ Comment("InstanceCallAOT (%s)", switchable_call_mode);
+  // Clear argument descriptor to keep gc happy when it gets pushed on to
+  // the stack.
+  __ LoadImmediate(R4, 0);
   __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
 
   const intptr_t data_index =
@@ -1159,7 +1210,7 @@
   }
   __ blr(LR);
 
-  EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
+  EmitCallsiteMetadata(token_pos, DeoptId::kNone, PcDescriptorsLayout::kOther,
                        locs);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
@@ -1175,7 +1226,7 @@
       StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
   __ LoadObject(R5, ic_data);
   GenerateDartCall(deopt_id, token_pos, stub,
-                   RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+                   PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
   __ Drop(size_with_type_args);
 }
 
@@ -1198,7 +1249,7 @@
   }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
-  GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+  GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
                          function, entry_kind);
   __ Drop(size_with_type_args);
 }
@@ -1234,7 +1285,8 @@
     } else {
       __ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmp, we need Z computed).
     // Discard constant.
     // Restore 'reg'.
@@ -1257,7 +1309,8 @@
     } else {
       __ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmp, we need Z computed).
     __ PopPair(right, left);
   } else {
@@ -1266,6 +1319,36 @@
   return EQ;
 }
 
+Condition FlowGraphCompiler::EmitBoolTest(Register value,
+                                          BranchLabels labels,
+                                          bool invert) {
+  __ Comment("BoolTest");
+  if (labels.true_label == nullptr || labels.false_label == nullptr) {
+    __ tsti(value, compiler::Immediate(
+                       compiler::target::ObjectAlignment::kBoolValueMask));
+    return invert ? NE : EQ;
+  }
+  const intptr_t bool_bit =
+      compiler::target::ObjectAlignment::kBoolValueBitPosition;
+  if (labels.fall_through == labels.false_label) {
+    if (invert) {
+      __ tbnz(labels.true_label, value, bool_bit);
+    } else {
+      __ tbz(labels.true_label, value, bool_bit);
+    }
+  } else {
+    if (invert) {
+      __ tbz(labels.false_label, value, bool_bit);
+    } else {
+      __ tbnz(labels.false_label, value, bool_bit);
+    }
+    if (labels.fall_through != labels.true_label) {
+      __ b(labels.true_label);
+    }
+  }
+  return kInvalidCondition;
+}
+
 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
 // FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
@@ -1580,6 +1663,28 @@
   }
 }
 
+void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
+                                     Register dst,
+                                     Register tmp) {
+  compiler::Label skip_reloc;
+  __ b(&skip_reloc);
+  InsertBSSRelocation(relocation);
+  __ Bind(&skip_reloc);
+
+  __ adr(tmp, compiler::Immediate(-compiler::target::kWordSize));
+
+  // tmp holds the address of the relocation.
+  __ ldr(dst, compiler::Address(tmp));
+
+  // dst holds the relocation itself: tmp - bss_start.
+  // tmp = tmp + (bss_start - tmp) = bss_start
+  __ add(tmp, tmp, compiler::Operand(dst));
+
+  // tmp holds the start of the BSS section.
+  // Load the "get-thread" routine: *bss_start.
+  __ ldr(dst, compiler::Address(tmp));
+}
+
 #undef __
 #define __ compiler_->assembler()->
 
@@ -1731,4 +1836,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index d362feb..9fbb02c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_IA32)
 
 #include "vm/compiler/backend/flow_graph_compiler.h"
 
 #include "vm/code_patcher.h"
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"
@@ -70,9 +71,9 @@
   intrinsic_mode_ = false;
 }
 
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder,
-                                                 const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+                                                DeoptInfoBuilder* builder,
+                                                const Array& deopt_table) {
   if (deopt_env_ == NULL) {
     ++builder->current_info_number_;
     return TypedData::null();
@@ -181,18 +182,21 @@
                                            compiler::Label* is_true,
                                            compiler::Label* is_false) {
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      compiler::Immediate(static_cast<intptr_t>(Object::null()));
   compiler::Label fall_through;
   __ cmpl(bool_register, raw_null);
   __ j(EQUAL, &fall_through, compiler::Assembler::kNearJump);
-  __ CompareObject(bool_register, Bool::True());
-  __ j(EQUAL, is_true);
+  BranchLabels labels = {is_true, is_false, &fall_through};
+  Condition true_condition =
+      EmitBoolTest(bool_register, labels, /*invert=*/false);
+  ASSERT(true_condition != kInvalidCondition);
+  __ j(true_condition, is_true);
   __ jmp(is_false);
   __ Bind(&fall_through);
 }
 
 // Clobbers ECX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
     TypeTestStubKind test_kind,
     Register instance_reg,
     Register instantiator_type_arguments_reg,
@@ -203,7 +207,7 @@
   const SubtypeTestCache& type_test_cache =
       SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      compiler::Immediate(static_cast<intptr_t>(Object::null()));
   __ LoadObject(temp_reg, type_test_cache);
   __ pushl(temp_reg);      // Subtype test cache.
   __ pushl(instance_reg);  // Instance.
@@ -245,7 +249,7 @@
 // be completed.
 // EAX: instance (must survive).
 // Clobbers ECX, EDI.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
     TokenPosition token_pos,
     const AbstractType& type,
@@ -289,7 +293,7 @@
   if (type_arguments.Length() == 1) {
     const AbstractType& tp_argument =
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopType()) {
+    if (tp_argument.IsTopTypeForSubtyping()) {
       // Instance class test only necessary.
       return GenerateSubtype1TestCacheLookup(
           token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -386,7 +390,7 @@
 // TODO(srdjan): Implement a quicker subtype check, as type test
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
     TokenPosition token_pos,
     const Class& type_class,
     compiler::Label* is_instance_lbl,
@@ -401,11 +405,15 @@
   __ LoadClassId(EDI, TypeTestABI::kInstanceReg);
   __ LoadClassById(ECX, EDI);
   // ECX: instance class.
-  // Check immediate superclass equality.
-  __ movl(EDI, compiler::FieldAddress(ECX, Class::super_type_offset()));
-  __ movl(EDI, compiler::FieldAddress(EDI, Type::type_class_id_offset()));
-  __ cmpl(EDI, compiler::Immediate(Smi::RawValue(type_class.id())));
-  __ j(EQUAL, is_instance_lbl);
+  // Check immediate superclass equality. If type_class is Object, then testing
+  // supertype may yield a wrong result for Null in NNBD strong mode (because
+  // Null also extends Object).
+  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
+    __ movl(EDI, compiler::FieldAddress(ECX, Class::super_type_offset()));
+    __ movl(EDI, compiler::FieldAddress(EDI, Type::type_class_id_offset()));
+    __ cmpl(EDI, compiler::Immediate(Smi::RawValue(type_class.id())));
+    __ j(EQUAL, is_instance_lbl);
+  }
 
   const Register kInstantiatorTypeArgumentsReg = kNoRegister;
   const Register kFunctionTypeArgumentsReg = kNoRegister;
@@ -419,7 +427,7 @@
 // Generates inlined check if 'type' is a type parameter or type itself
 // EAX: instance (preserved).
 // Clobbers EDX, EDI, ECX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -430,7 +438,7 @@
   ASSERT(!type.IsFunctionType());
   // Skip check if destination is a dynamic type.
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      compiler::Immediate(static_cast<intptr_t>(Object::null()));
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
 
@@ -506,7 +514,7 @@
 // Generates function type check.
 //
 // See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -536,7 +544,7 @@
 // Note that this inlined code must be followed by the runtime_call code, as it
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -589,13 +597,13 @@
                                            const AbstractType& type,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopType());  // Already checked.
+  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
 
   __ pushl(EDX);  // Store instantiator type arguments.
   __ pushl(ECX);  // Store function type arguments.
 
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::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.
@@ -662,7 +670,8 @@
 // - object in EAX for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(CompileType* receiver_type,
+                                                 TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
@@ -671,7 +680,7 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(!dst_type.IsTopTypeForAssignability());
+  ASSERT(!dst_type.IsTopTypeForSubtyping());
 
   __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
   __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
@@ -679,7 +688,7 @@
   compiler::Label is_assignable, runtime_call;
   if (Instance::NullIsAssignableTo(dst_type)) {
     const compiler::Immediate& raw_null =
-        compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+        compiler::Immediate(static_cast<intptr_t>(Object::null()));
     __ cmpl(EAX, raw_null);
     __ j(EQUAL, &is_assignable);
   }
@@ -753,7 +762,7 @@
   __ movl(EBX, compiler::Address(ESP, 1 * kWordSize));  // Value.
   __ StoreIntoObject(EAX, compiler::FieldAddress(EAX, offset), EBX);
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      compiler::Immediate(static_cast<intptr_t>(Object::null()));
   __ movl(EAX, raw_null);
   __ ret();
 }
@@ -810,7 +819,7 @@
     __ Comment("Initialize spill slots");
     if (num_locals > 1 || (num_locals == 1 && args_desc_slot == -1)) {
       const compiler::Immediate& raw_null =
-          compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+          compiler::Immediate(static_cast<intptr_t>(Object::null()));
       __ movl(EAX, raw_null);
     }
     for (intptr_t i = 0; i < num_locals; ++i) {
@@ -842,19 +851,15 @@
   }
 }
 
-void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
-                                     const Code& stub,
-                                     RawPcDescriptors::Kind kind,
-                                     LocationSummary* locs) {
+void FlowGraphCompiler::EmitCallToStub(const Code& stub) {
   __ Call(stub);
-  EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
   AddStubCallTarget(stub);
 }
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
                                          TokenPosition token_pos,
                                          const Code& stub,
-                                         RawPcDescriptors::Kind kind,
+                                         PcDescriptorsLayout::Kind kind,
                                          LocationSummary* locs,
                                          Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
@@ -864,7 +869,7 @@
 
 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
                                                TokenPosition token_pos,
-                                               RawPcDescriptors::Kind kind,
+                                               PcDescriptorsLayout::Kind kind,
                                                LocationSummary* locs,
                                                const Function& target,
                                                Code::EntryKind entry_kind) {
@@ -881,7 +886,7 @@
                                             intptr_t argument_count,
                                             LocationSummary* locs) {
   __ CallRuntime(entry, argument_count);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
 }
 
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
@@ -895,7 +900,7 @@
       StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
   __ LoadObject(ECX, ic_data);
   GenerateDartCall(deopt_id, token_pos, stub,
-                   RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+                   PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
   __ Drop(size_with_type_args);
 }
 
@@ -931,8 +936,8 @@
   __ movl(EBX, compiler::Address(
                    ESP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
   __ LoadObject(ECX, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
-                   entry_kind);
+  GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+                   locs, entry_kind);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
 
@@ -956,7 +961,7 @@
           ? Code::entry_point_offset(Code::EntryKind::kMonomorphic)
           : Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
   __ call(compiler::FieldAddress(CODE_REG, entry_point_offset));
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
   __ Drop(ic_data.SizeWithTypeArgs());
 }
 
@@ -978,11 +983,12 @@
   __ Comment("MegamorphicCall");
   // Load receiver into EBX.
   __ movl(EBX, compiler::Address(ESP, (args_desc.Count() - 1) * kWordSize));
-  __ LoadObject(ECX, cache);
-  __ call(
-      compiler::Address(THR, Thread::megamorphic_call_checked_entry_offset()));
+  __ LoadObject(ECX, cache, true);
+  __ LoadObject(CODE_REG, StubCode::MegamorphicCall(), true);
+  __ call(compiler::FieldAddress(
+      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
 
-  AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+  AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone, token_pos);
   RecordSafepoint(locs, slow_path_argument_count);
   const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id);
   // Precompilation not implemented on ia32 platform.
@@ -992,7 +998,8 @@
   } else {
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
-    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+                         token_pos);
   }
   RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.SizeWithTypeArgs());
@@ -1024,7 +1031,7 @@
   }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
-  GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+  GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
                          function, entry_kind);
   __ Drop(size_with_type_args);
 }
@@ -1059,7 +1066,8 @@
     } else {
       __ Call(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmpl, we need ZF computed).
     __ popl(reg);  // Discard constant.
     __ popl(reg);  // Restore 'reg'.
@@ -1082,7 +1090,8 @@
     } else {
       __ Call(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmpl, we need ZF computed).
     __ popl(right);
     __ popl(left);
@@ -1092,6 +1101,15 @@
   return EQUAL;
 }
 
+Condition FlowGraphCompiler::EmitBoolTest(Register value,
+                                          BranchLabels labels,
+                                          bool invert) {
+  __ Comment("BoolTest");
+  __ testl(value, compiler::Immediate(
+                      compiler::target::ObjectAlignment::kBoolValueMask));
+  return invert ? NOT_EQUAL : EQUAL;
+}
+
 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
 // FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
@@ -1587,4 +1605,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index f1f0c6b..091b51f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_X64)
 
 #include "vm/compiler/backend/flow_graph_compiler.h"
 
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/ffi/native_location.h"
@@ -93,9 +94,9 @@
   intrinsic_mode_ = false;
 }
 
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder,
-                                                 const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+                                                DeoptInfoBuilder* builder,
+                                                const Array& deopt_table) {
   if (deopt_env_ == NULL) {
     ++builder->current_info_number_;
     return TypedData::null();
@@ -207,8 +208,11 @@
   compiler::Label fall_through;
   __ CompareObject(bool_register, Object::null_object());
   __ j(EQUAL, &fall_through, compiler::Assembler::kNearJump);
-  __ CompareObject(bool_register, Bool::True());
-  __ j(EQUAL, is_true);
+  BranchLabels labels = {is_true, is_false, &fall_through};
+  Condition true_condition =
+      EmitBoolTest(bool_register, labels, /*invert=*/false);
+  ASSERT(true_condition != kInvalidCondition);
+  __ j(true_condition, is_true);
   __ jmp(is_false);
   __ Bind(&fall_through);
 }
@@ -222,7 +226,7 @@
 //   - RCX : function type arguments (if necessary).
 //
 // Preserves RAX/RCX/RDX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
     TypeTestStubKind test_kind,
     Register instance_reg,
     Register instantiator_type_arguments_reg,
@@ -267,7 +271,7 @@
 // be completed.
 // RAX: instance (must survive).
 // Clobbers R10.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
     TokenPosition token_pos,
     const AbstractType& type,
@@ -312,7 +316,7 @@
   if (type_arguments.Length() == 1) {
     const AbstractType& tp_argument =
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopType()) {
+    if (tp_argument.IsTopTypeForSubtyping()) {
       // Instance class test only necessary.
       return GenerateSubtype1TestCacheLookup(
           token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -418,7 +422,7 @@
 // TODO(srdjan): Implement a quicker subtype check, as type test
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
     TokenPosition token_pos,
     const Class& type_class,
     compiler::Label* is_instance_lbl,
@@ -433,11 +437,16 @@
   __ LoadClassId(TMP, TypeTestABI::kInstanceReg);
   __ LoadClassById(R10, TMP);
   // R10: instance class.
-  // Check immediate superclass equality.
-  __ movq(R13, compiler::FieldAddress(R10, Class::super_type_offset()));
-  __ movq(R13, compiler::FieldAddress(R13, Type::type_class_id_offset()));
-  __ CompareImmediate(R13, compiler::Immediate(Smi::RawValue(type_class.id())));
-  __ j(EQUAL, is_instance_lbl);
+  // Check immediate superclass equality. If type_class is Object, then testing
+  // supertype may yield a wrong result for Null in NNBD strong mode (because
+  // Null also extends Object).
+  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
+    __ movq(R13, compiler::FieldAddress(R10, Class::super_type_offset()));
+    __ movq(R13, compiler::FieldAddress(R13, Type::type_class_id_offset()));
+    __ CompareImmediate(R13,
+                        compiler::Immediate(Smi::RawValue(type_class.id())));
+    __ j(EQUAL, is_instance_lbl);
+  }
 
   const Register kInstantiatorTypeArgumentsReg = kNoRegister;
   const Register kFunctionTypeArgumentsReg = kNoRegister;
@@ -456,7 +465,7 @@
 //   - RCX : function type arguments (if necessary).
 //
 // Preserves RAX/RCX/RDX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -531,7 +540,7 @@
 // Generates function type check.
 //
 // See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -558,7 +567,7 @@
 // Note that this inlined code must be followed by the runtime_call code, as it
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
     TokenPosition token_pos,
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
@@ -611,7 +620,7 @@
                                            const AbstractType& type,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopType());  // Already checked.
+  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
 
   compiler::Label is_instance, is_not_instance;
   // 'null' is an instance of Null, Object*, Never*, void, and dynamic.
@@ -638,19 +647,11 @@
   // 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.
-    __ pushq(TypeTestABI::kInstanceReg);   // Push the instance.
-    __ PushObject(type);                   // Push the type.
-    __ pushq(TypeTestABI::kInstantiatorTypeArgumentsReg);
-    __ pushq(TypeTestABI::kFunctionTypeArgumentsReg);
-    __ LoadUniqueObject(RAX, test_cache);
-    __ pushq(RAX);
-    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
-    // Pop the parameters supplied to the runtime entry. The result of the
-    // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
-    __ popq(RAX);
+    // Generate Runtime call.
+    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
+    GenerateStubCall(token_pos, StubCode::InstanceOf(),
+                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
     __ jmp(&done, compiler::Assembler::kNearJump);
   }
   __ Bind(&is_not_instance);
@@ -674,7 +675,8 @@
 // - object in RAX for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(CompileType* receiver_type,
+                                                 TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
@@ -683,11 +685,11 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(!dst_type.IsTopTypeForAssignability());
+  ASSERT(!dst_type.IsTopTypeForSubtyping());
 
   if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
-    GenerateAssertAssignableViaTypeTestingStub(token_pos, deopt_id, dst_type,
-                                               dst_name, locs);
+    GenerateAssertAssignableViaTypeTestingStub(
+        receiver_type, token_pos, deopt_id, dst_type, dst_name, locs);
   } else {
     compiler::Label is_assignable, runtime_call;
 
@@ -722,19 +724,26 @@
 }
 
 void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
+    CompileType* receiver_type,
     TokenPosition token_pos,
     intptr_t deopt_id,
     const AbstractType& dst_type,
     const String& dst_name,
     LocationSummary* locs) {
+  // If the dst_type is instantiated we know the target TTS stub at
+  // compile-time and can therefore use a pc-relative call.
+  const bool use_pc_relative_call = dst_type.IsInstantiated() &&
+                                    FLAG_precompiled_mode &&
+                                    FLAG_use_bare_instructions;
+  const Register kScratchReg =
+      dst_type.IsTypeParameter() ? RSI : TypeTestABI::kDstTypeReg;
+
+  const Register kRegToCall = use_pc_relative_call ? kNoRegister : kScratchReg;
+
   compiler::Label done;
 
-  const Register kRegToCall =
-      dst_type.IsTypeParameter() ? RSI : TypeTestABI::kDstTypeReg;
-  const Register kScratchReg = kRegToCall;
-
-  GenerateAssertAssignableViaTypeTestingStub(dst_type, dst_name, kRegToCall,
-                                             kScratchReg, &done);
+  GenerateAssertAssignableViaTypeTestingStub(receiver_type, dst_type, dst_name,
+                                             kRegToCall, kScratchReg, &done);
 
   // We use 2 consecutive entries in the pool for the subtype cache and the
   // destination name.  The second entry, namely [dst_name] seems to be unused,
@@ -753,9 +762,14 @@
 
   __ movq(TypeTestABI::kSubtypeTestCacheReg,
           compiler::Address(PP, sub_type_cache_offset));
-  __ call(compiler::FieldAddress(
-      kRegToCall, AbstractType::type_test_stub_entry_point_offset()));
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  if (use_pc_relative_call) {
+    __ GenerateUnRelocatedPcRelativeCall();
+    AddPcRelativeTTSCallTypeTarget(dst_type);
+  } else {
+    __ call(compiler::FieldAddress(
+        kRegToCall, AbstractType::type_test_stub_entry_point_offset()));
+  }
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
   __ Bind(&done);
 }
 
@@ -931,26 +945,40 @@
   }
 }
 
-void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
-                                     const Code& stub,
-                                     RawPcDescriptors::Kind kind,
-                                     LocationSummary* locs) {
+void FlowGraphCompiler::EmitCallToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
       !stub.InVMIsolateHeap()) {
     __ GenerateUnRelocatedPcRelativeCall();
     AddPcRelativeCallStubTarget(stub);
-    EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
   } else {
-    ASSERT(!stub.IsNull());
     __ Call(stub);
-    EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
+    AddStubCallTarget(stub);
+  }
+}
+
+void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
+      !stub.InVMIsolateHeap()) {
+    __ LeaveDartFrame();
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+#if defined(DEBUG)
+    __ Breakpoint();
+#endif
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ LeaveDartFrame();
+    __ jmp(compiler::FieldAddress(
+        CODE_REG, compiler::target::Code::entry_point_offset()));
     AddStubCallTarget(stub);
   }
 }
 
 void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
                                               const Code& stub,
-                                              RawPcDescriptors::Kind kind,
+                                              PcDescriptorsLayout::Kind kind,
                                               LocationSummary* locs) {
   __ CallPatchable(stub);
   EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
@@ -959,7 +987,7 @@
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
                                          TokenPosition token_pos,
                                          const Code& stub,
-                                         RawPcDescriptors::Kind kind,
+                                         PcDescriptorsLayout::Kind kind,
                                          LocationSummary* locs,
                                          Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
@@ -969,7 +997,7 @@
 
 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
                                                TokenPosition token_pos,
-                                               RawPcDescriptors::Kind kind,
+                                               PcDescriptorsLayout::Kind kind,
                                                LocationSummary* locs,
                                                const Function& target,
                                                Code::EntryKind entry_kind) {
@@ -997,7 +1025,7 @@
                                             intptr_t argument_count,
                                             LocationSummary* locs) {
   __ CallRuntime(entry, argument_count);
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
 }
 
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
@@ -1011,7 +1039,7 @@
       StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
   __ LoadObject(RBX, ic_data);
   GenerateDartCall(deopt_id, token_pos, stub,
-                   RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+                   PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
   __ Drop(size_with_type_args, RCX);
 }
 
@@ -1048,8 +1076,8 @@
   __ movq(RDX, compiler::Address(
                    RSP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
   __ LoadUniqueObject(RBX, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
-                   entry_kind);
+  GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+                   locs, entry_kind);
   __ Drop(ic_data.SizeWithTypeArgs(), RCX);
 }
 
@@ -1073,7 +1101,7 @@
           ? Code::entry_point_offset(Code::EntryKind::kMonomorphic)
           : Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
   __ call(compiler::FieldAddress(CODE_REG, entry_point_offset));
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
   __ Drop(ic_data.SizeWithTypeArgs(), RCX);
 }
 
@@ -1094,9 +1122,27 @@
   __ Comment("MegamorphicCall");
   // Load receiver into RDX.
   __ movq(RDX, compiler::Address(RSP, (args_desc.Count() - 1) * kWordSize));
-  __ LoadObject(RBX, cache);
-  __ call(
-      compiler::Address(THR, Thread::megamorphic_call_checked_entry_offset()));
+
+  // Use same code pattern as instance call so it can be parsed by code patcher.
+  if (FLAG_precompiled_mode) {
+    if (FLAG_use_bare_instructions) {
+      // The AOT runtime will replace the slot in the object pool with the
+      // entrypoint address - see clustered_snapshot.cc.
+      __ LoadUniqueObject(RCX, StubCode::MegamorphicCall());
+    } else {
+      __ LoadUniqueObject(CODE_REG, StubCode::MegamorphicCall());
+      __ movq(RCX, compiler::FieldAddress(CODE_REG,
+                                          Code::entry_point_offset(
+                                              Code::EntryKind::kMonomorphic)));
+    }
+    __ LoadUniqueObject(RBX, cache);
+    __ call(RCX);
+  } else {
+    __ LoadUniqueObject(RBX, cache);
+    __ LoadUniqueObject(CODE_REG, StubCode::MegamorphicCall());
+    __ call(compiler::FieldAddress(
+        CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
+  }
 
   RecordSafepoint(locs, slow_path_argument_count);
   const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id);
@@ -1106,16 +1152,19 @@
     if (try_index == kInvalidTryIndex) {
       try_index = CurrentTryIndex();
     }
-    AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+    AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
                   DeoptId::kNone, token_pos, try_index);
   } else if (is_optimizing()) {
-    AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+                         token_pos);
     AddDeoptIndexAtCall(deopt_id_after);
   } else {
-    AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+                         token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
-    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+                         token_pos);
   }
   RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.SizeWithTypeArgs(), RCX);
@@ -1131,7 +1180,7 @@
   ASSERT(entry_kind == Code::EntryKind::kNormal ||
          entry_kind == Code::EntryKind::kUnchecked);
   ASSERT(ic_data.NumArgsTested() == 1);
-  const Code& initial_stub = StubCode::UnlinkedCall();
+  const Code& initial_stub = StubCode::SwitchableCallMiss();
   const char* switchable_call_mode = "smiable";
   if (!receiver_can_be_smi) {
     switchable_call_mode = "non-smi";
@@ -1158,7 +1207,7 @@
   __ LoadUniqueObject(RBX, data);
   __ call(RCX);
 
-  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
   __ Drop(ic_data.SizeWithTypeArgs(), RCX);
 }
 
@@ -1181,7 +1230,7 @@
   }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
-  GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+  GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
                          function, entry_kind);
   __ Drop(size_with_type_args, RCX);
 }
@@ -1225,7 +1274,8 @@
     } else {
       __ CallPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmpq, we need ZF computed).
     __ popq(reg);  // Discard constant.
     __ popq(reg);  // Restore 'reg'.
@@ -1248,7 +1298,8 @@
     } else {
       __ CallPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
     }
-    AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+    AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+                         token_pos);
     // Stub returns result in flags (result of a cmpq, we need ZF computed).
     __ popq(right);
     __ popq(left);
@@ -1258,6 +1309,15 @@
   return EQUAL;
 }
 
+Condition FlowGraphCompiler::EmitBoolTest(Register value,
+                                          BranchLabels labels,
+                                          bool invert) {
+  __ Comment("BoolTest");
+  __ testq(value, compiler::Immediate(
+                      compiler::target::ObjectAlignment::kBoolValueMask));
+  return invert ? NOT_EQUAL : EQUAL;
+}
+
 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
 // FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
@@ -1586,6 +1646,32 @@
   }
 }
 
+void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
+                                     Register dst,
+                                     Register tmp) {
+  compiler::Label skip_reloc;
+  __ jmp(&skip_reloc);
+  InsertBSSRelocation(relocation);
+  const intptr_t reloc_end = __ CodeSize();
+  __ Bind(&skip_reloc);
+
+  const intptr_t kLeaqLength = 7;
+  __ leaq(dst, compiler::Address::AddressRIPRelative(
+                   -kLeaqLength - compiler::target::kWordSize));
+  ASSERT((__ CodeSize() - reloc_end) == kLeaqLength);
+
+  // dst holds the address of the relocation.
+  __ movq(tmp, compiler::Address(dst, 0));
+
+  // tmp holds the relocation itself: dst - bss_start.
+  // dst = dst + (bss_start - dst) = bss_start
+  __ addq(dst, tmp);
+
+  // dst holds the start of the BSS section.
+  // Load the routine.
+  __ movq(dst, compiler::Address(dst, 0));
+}
+
 #undef __
 #define __ compiler_->assembler()->
 
@@ -1719,4 +1805,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 80958c4..a37b4ef 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/il.h"
 
 #include "vm/bit_vector.h"
@@ -515,6 +513,10 @@
   return value();
 }
 
+Value* AssertBooleanInstr::RedefinedValue() const {
+  return value();
+}
+
 Value* CheckBoundBase::RedefinedValue() const {
   return index();
 }
@@ -2629,8 +2631,7 @@
 }
 
 bool LoadFieldInstr::IsFixedLengthArrayCid(intptr_t cid) {
-  if (RawObject::IsTypedDataClassId(cid) ||
-      RawObject::IsExternalTypedDataClassId(cid)) {
+  if (IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid)) {
     return true;
   }
 
@@ -2948,7 +2949,7 @@
     instantiator_type_arguments()->BindTo(flow_graph->constant_null());
     function_type_arguments()->BindTo(flow_graph->constant_null());
 
-    if (new_dst_type.IsTopTypeForAssignability() ||
+    if (new_dst_type.IsTopTypeForSubtyping() ||
         (FLAG_eliminate_type_checks &&
          value()->Type()->IsAssignableTo(new_dst_type))) {
       return value()->definition();
@@ -3245,8 +3246,8 @@
   const AbstractType& unwrapped_type =
       AbstractType::Handle(type->ToAbstractType()->UnwrapFutureOr());
   // Note that type 'Number' is a subtype of itself.
-  return unwrapped_type.IsTopType() || unwrapped_type.IsObjectType() ||
-         unwrapped_type.IsTypeParameter() ||
+  return unwrapped_type.IsTopTypeForSubtyping() ||
+         unwrapped_type.IsObjectType() || unwrapped_type.IsTypeParameter() ||
          unwrapped_type.IsSubtypeOf(Type::Handle(Type::Number()), Heap::kOld);
 }
 
@@ -3871,7 +3872,7 @@
 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ Bind(compiler->GetJumpLabel(this));
   if (!compiler->is_optimizing()) {
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -3898,7 +3899,7 @@
     // The deoptimization descriptor points after the edge counter code for
     // uniformity with ARM, where we can reuse pattern matching code that
     // matches backwards from the end of the pattern.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -3972,7 +3973,7 @@
     // The deoptimization descriptor points after the edge counter code for
     // uniformity with ARM, where we can reuse pattern matching code that
     // matches backwards from the end of the pattern.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -4059,26 +4060,171 @@
       compiler::target::Thread::field_table_values_offset();
   const intptr_t field_offset = compiler::target::FieldTable::OffsetOf(field());
 
+  auto object_store = compiler->isolate()->object_store();
+  const auto& init_static_field_stub = Code::ZoneHandle(
+      compiler->zone(), object_store->init_static_field_stub());
+
   const Register temp = InitStaticFieldABI::kFieldReg;
   __ LoadMemoryValue(temp, THR, static_cast<int32_t>(field_table_offset));
   __ LoadMemoryValue(temp, temp, static_cast<int32_t>(field_offset));
 
   compiler::Label call_runtime, no_call;
   __ CompareObject(temp, Object::sentinel());
-  __ BranchIf(EQUAL, &call_runtime);
 
-  __ CompareObject(temp, Object::transition_sentinel());
+  if (!field().is_late()) {
+    __ BranchIf(EQUAL, &call_runtime);
+    __ CompareObject(temp, Object::transition_sentinel());
+  }
+
   __ BranchIf(NOT_EQUAL, &no_call);
 
   __ Bind(&call_runtime);
   __ LoadObject(InitStaticFieldABI::kFieldReg,
                 Field::ZoneHandle(field().Original()));
-  compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
-                                  StubCode::InitStaticField(),
-                                  /*kind=*/RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), init_static_field_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs(),
+                             deopt_id());
   __ Bind(&no_call);
 }
 
+LocationSummary* InitInstanceFieldInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  auto const locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_in(0,
+               Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
+  return locs;
+}
+
+void InitInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register temp = InitInstanceFieldABI::kFieldReg;
+
+  __ LoadField(temp, compiler::FieldAddress(InitInstanceFieldABI::kInstanceReg,
+                                            field().TargetOffset()));
+
+  compiler::Label no_call;
+  __ CompareObject(temp, Object::sentinel());
+  __ BranchIf(NOT_EQUAL, &no_call);
+
+  __ LoadObject(InitInstanceFieldABI::kFieldReg,
+                Field::ZoneHandle(field().Original()));
+
+  auto object_store = compiler->isolate()->object_store();
+  auto& stub = Code::ZoneHandle(compiler->zone());
+  if (field().needs_load_guard()) {
+    stub = object_store->init_instance_field_stub();
+  } else if (field().is_late()) {
+    if (!field().has_nontrivial_initializer()) {
+      // Common stub calls runtime which will throw an exception.
+      stub = object_store->init_instance_field_stub();
+    } else {
+      // Stubs for late field initialization call initializer
+      // function directly, so make sure one is created.
+      field().EnsureInitializerFunction();
+
+      if (field().is_final()) {
+        stub = object_store->init_late_final_instance_field_stub();
+      } else {
+        stub = object_store->init_late_instance_field_stub();
+      }
+    }
+  } else {
+    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(token_pos(), stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs(),
+                             deopt_id());
+  __ Bind(&no_call);
+}
+
+LocationSummary* ThrowInstr::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(ThrowABI::kExceptionReg));
+  return summary;
+}
+
+void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  auto object_store = compiler->isolate()->object_store();
+  const auto& throw_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->throw_stub());
+
+  compiler->GenerateStubCall(token_pos(), throw_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs(),
+                             deopt_id());
+  // Issue(dartbug.com/41353): Right now we have to emit an extra breakpoint
+  // instruction: The ThrowInstr will terminate the current block. The very
+  // next machine code instruction might get a pc descriptor attached with a
+  // different try-index. If we removed this breakpoint instruction, the
+  // runtime might associated this call with the try-index of the next
+  // instruction.
+  __ Breakpoint();
+}
+
+LocationSummary* ReThrowInstr::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::kCall);
+  summary->set_in(0, Location::RegisterLocation(ReThrowABI::kExceptionReg));
+  summary->set_in(1, Location::RegisterLocation(ReThrowABI::kStackTraceReg));
+  return summary;
+}
+
+void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  auto object_store = compiler->isolate()->object_store();
+  const auto& re_throw_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->re_throw_stub());
+
+  compiler->SetNeedsStackTrace(catch_try_index());
+  compiler->GenerateStubCall(token_pos(), re_throw_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs(),
+                             deopt_id());
+  // Issue(dartbug.com/41353): Right now we have to emit an extra breakpoint
+  // instruction: The ThrowInstr will terminate the current block. The very
+  // next machine code instruction might get a pc descriptor attached with a
+  // different try-index. If we removed this breakpoint instruction, the
+  // runtime might associated this call with the try-index of the next
+  // instruction.
+  __ Breakpoint();
+}
+
+LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
+                                                         bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_in(0, Location::RegisterLocation(AssertBooleanABI::kObjectReg));
+  locs->set_out(0, Location::RegisterLocation(AssertBooleanABI::kObjectReg));
+  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()->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(token_pos(), assert_boolean_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
 LocationSummary* PhiInstr::MakeLocationSummary(Zone* zone,
                                                bool optimizing) const {
   UNREACHABLE();
@@ -4290,6 +4436,50 @@
   SetInputAt(1, right);
 }
 
+Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                 BranchLabels labels) {
+  Location left = locs()->in(0);
+  Location right = locs()->in(1);
+  ASSERT(!left.IsConstant() || !right.IsConstant());
+  Condition true_condition;
+  if (left.IsConstant()) {
+    if (TryEmitBoolTest(compiler, labels, 1, left.constant(),
+                        &true_condition)) {
+      return true_condition;
+    }
+    true_condition = EmitComparisonCodeRegConstant(
+        compiler, labels, right.reg(), left.constant());
+  } else if (right.IsConstant()) {
+    if (TryEmitBoolTest(compiler, labels, 0, right.constant(),
+                        &true_condition)) {
+      return true_condition;
+    }
+    true_condition = EmitComparisonCodeRegConstant(compiler, labels, left.reg(),
+                                                   right.constant());
+  } else {
+    true_condition = compiler->EmitEqualityRegRegCompare(
+        left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id());
+  }
+  return true_condition != kInvalidCondition && (kind() != Token::kEQ_STRICT)
+             ? InvertCondition(true_condition)
+             : true_condition;
+}
+
+bool StrictCompareInstr::TryEmitBoolTest(FlowGraphCompiler* compiler,
+                                         BranchLabels labels,
+                                         intptr_t input_index,
+                                         const Object& obj,
+                                         Condition* true_condition_out) {
+  CompileType* input_type = InputAt(input_index)->Type();
+  if (input_type->ToCid() == kBoolCid && obj.GetClassId() == kBoolCid) {
+    bool invert = (kind() != Token::kEQ_STRICT) ^ !Bool::Cast(obj).value();
+    *true_condition_out =
+        compiler->EmitBoolTest(locs()->in(input_index).reg(), labels, invert);
+    return true;
+  }
+  return false;
+}
+
 LocationSummary* LoadClassIdInstr::MakeLocationSummary(Zone* zone,
                                                        bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -4321,7 +4511,7 @@
   return MakeCallSummary(zone, this);
 }
 
-static RawCode* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
+static CodePtr TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
   if (!FLAG_two_args_smi_icd) {
     return Code::null();
   }
@@ -4428,7 +4618,7 @@
     }
   } else {
     // Unoptimized code.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kRewind, deopt_id(),
                                    token_pos());
     bool is_smi_two_args_op = false;
     const Code& stub =
@@ -4454,7 +4644,7 @@
   return Library::IsPrivateCoreLibName(function_name(), name);
 }
 
-RawFunction* InstanceCallBaseInstr::ResolveForReceiverClass(
+FunctionPtr InstanceCallBaseInstr::ResolveForReceiverClass(
     const Class& cls,
     bool allow_add /* = true */) {
   const Array& args_desc_array = Array::Handle(GetArgumentsDescriptor());
@@ -4524,6 +4714,7 @@
     Zone* zone,
     const InstanceCallBaseInstr* call,
     Value* cid,
+    const Function& interface_target,
     const compiler::TableSelector* selector) {
   InputsArray* args = new (zone) InputsArray(zone, call->ArgumentCount() + 1);
   for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
@@ -4531,7 +4722,7 @@
   }
   args->Add(cid);
   auto dispatch_table_call = new (zone) DispatchTableCallInstr(
-      call->token_pos(), call->interface_target(), selector, args,
+      call->token_pos(), interface_target, selector, args,
       call->type_args_len(), call->argument_names());
   if (call->has_inlining_id()) {
     dispatch_table_call->set_inlining_id(call->inlining_id());
@@ -4550,7 +4741,7 @@
   compiler->EmitDispatchTableCall(cid_reg, selector()->offset,
                                   arguments_descriptor);
   compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
-                                 RawPcDescriptors::kOther, locs());
+                                 PcDescriptorsLayout::kOther, locs());
   if (selector()->called_on_null && !selector()->on_null_interface) {
     Value* receiver = ArgumentValueAt(FirstArgIndex());
     if (receiver->Type()->is_nullable()) {
@@ -4681,7 +4872,7 @@
       total_call_count(), !receiver_is_not_smi());
 }
 
-RawType* PolymorphicInstanceCallInstr::ComputeRuntimeType(
+TypePtr PolymorphicInstanceCallInstr::ComputeRuntimeType(
     const CallTargets& targets) {
   bool is_string = true;
   bool is_integer = true;
@@ -4694,8 +4885,8 @@
     const intptr_t start = targets[i].cid_start;
     const intptr_t end = targets[i].cid_end;
     for (intptr_t cid = start; cid <= end; cid++) {
-      is_string = is_string && RawObject::IsStringClassId(cid);
-      is_integer = is_integer && RawObject::IsIntegerClassId(cid);
+      is_string = is_string && IsStringClassId(cid);
+      is_integer = is_integer && IsIntegerClassId(cid);
       is_double = is_double && (cid == kDoubleCid);
     }
   }
@@ -4859,8 +5050,8 @@
 }
 
 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  compiler->GenerateAssertAssignable(token_pos(), deopt_id(), dst_type(),
-                                     dst_name(), locs());
+  compiler->GenerateAssertAssignable(value()->Type(), token_pos(), deopt_id(),
+                                     dst_type(), dst_name(), locs());
   ASSERT(locs()->in(0).reg() == locs()->out(0).reg());
 }
 
@@ -4939,25 +5130,13 @@
   const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  locs->set_in(kLengthPos, Location::RequiresRegister());
-  locs->set_in(kIndexPos, Location::RequiresRegister());
+      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSharedSlowPath);
+  locs->set_in(kLengthPos,
+               Location::RegisterLocation(RangeErrorABI::kLengthReg));
+  locs->set_in(kIndexPos, Location::RegisterLocation(RangeErrorABI::kIndexReg));
   return locs;
 }
 
-class RangeErrorSlowPath : public ThrowErrorSlowPathCode {
- public:
-  static const intptr_t kNumberOfArguments = 2;
-
-  RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
-      : ThrowErrorSlowPathCode(instruction,
-                               kRangeErrorRuntimeEntry,
-                               kNumberOfArguments,
-                               try_index) {}
-
-  virtual const char* name() { return "check bound"; }
-};
-
 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   RangeErrorSlowPath* slow_path =
       new RangeErrorSlowPath(this, compiler->CurrentTryIndex());
@@ -4991,6 +5170,51 @@
   compiler->AddNullCheck(check_null->token_pos(), check_null->function_name());
 }
 
+void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
+                                           bool save_fpu_registers) {
+#if defined(TARGET_ARCH_IA32)
+  UNREACHABLE();
+#else
+  auto object_store = compiler->isolate()->object_store();
+  const auto& stub = Code::ZoneHandle(
+      compiler->zone(),
+      save_fpu_registers
+          ? object_store->null_error_stub_with_fpu_regs_stub()
+          : object_store->null_error_stub_without_fpu_regs_stub());
+  compiler->EmitCallToStub(stub);
+#endif
+}
+
+void NullArgErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
+                                              bool save_fpu_registers) {
+#if defined(TARGET_ARCH_IA32)
+  UNREACHABLE();
+#else
+  auto object_store = compiler->isolate()->object_store();
+  const auto& stub = Code::ZoneHandle(
+      compiler->zone(),
+      save_fpu_registers
+          ? object_store->null_arg_error_stub_with_fpu_regs_stub()
+          : object_store->null_arg_error_stub_without_fpu_regs_stub());
+  compiler->EmitCallToStub(stub);
+#endif
+}
+
+void RangeErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
+                                            bool save_fpu_registers) {
+#if defined(TARGET_ARCH_IA32)
+  UNREACHABLE();
+#else
+  auto object_store = compiler->isolate()->object_store();
+  const auto& stub = Code::ZoneHandle(
+      compiler->zone(),
+      save_fpu_registers
+          ? object_store->range_error_stub_with_fpu_regs_stub()
+          : object_store->range_error_stub_without_fpu_regs_stub());
+  compiler->EmitCallToStub(stub);
+#endif
+}
+
 void UnboxInstr::EmitLoadFromBoxWithDeopt(FlowGraphCompiler* compiler) {
   const intptr_t box_cid = BoxCid();
   const Register box = locs()->in(0).reg();
@@ -5305,9 +5529,8 @@
 }
 
 intptr_t CheckArrayBoundInstr::LengthOffsetFor(intptr_t class_id) {
-  if (RawObject::IsTypedDataClassId(class_id) ||
-      RawObject::IsTypedDataViewClassId(class_id) ||
-      RawObject::IsExternalTypedDataClassId(class_id)) {
+  if (IsTypedDataClassId(class_id) || IsTypedDataViewClassId(class_id) ||
+      IsExternalTypedDataClassId(class_id)) {
     return compiler::target::TypedDataBase::length_offset();
   }
 
@@ -5953,5 +6176,3 @@
 #undef __
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 1139d7c..63a8bf0 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_IL_H_
 #define RUNTIME_VM_COMPILER_BACKEND_IL_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <memory>
 #include <utility>
 
@@ -13,6 +17,7 @@
 #include "vm/compiler/backend/compile_type.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/backend/slot.h"
+#include "vm/compiler/compiler_pass.h"
 #include "vm/compiler/compiler_state.h"
 #include "vm/compiler/ffi/marshaller.h"
 #include "vm/compiler/ffi/native_calling_convention.h"
@@ -768,7 +773,6 @@
 
   explicit Instruction(intptr_t deopt_id = DeoptId::kNone)
       : deopt_id_(deopt_id),
-        lifetime_position_(kNoPlaceId),
         previous_(NULL),
         next_(NULL),
         env_(NULL),
@@ -963,8 +967,21 @@
   void RemoveEnvironment();
   void ReplaceInEnvironment(Definition* current, Definition* replacement);
 
-  intptr_t lifetime_position() const { return lifetime_position_; }
-  void set_lifetime_position(intptr_t pos) { lifetime_position_ = pos; }
+  // 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 {
+    return (PassSpecificId::DecodePass(pass_specific_id_) == pass)
+               ? PassSpecificId::DecodeId(pass_specific_id_)
+               : PassSpecificId::kNoId;
+  }
+  void SetPassSpecificId(CompilerPass::Id pass, intptr_t id) {
+    pass_specific_id_ = PassSpecificId::Encode(pass, id);
+  }
+  bool HasPassSpecificId(CompilerPass::Id pass) const {
+    return (PassSpecificId::DecodePass(pass_specific_id_) == pass) &&
+           (PassSpecificId::DecodeId(pass_specific_id_) !=
+            PassSpecificId::kNoId);
+  }
 
   bool HasUnmatchedInputRepresentations() const;
 
@@ -1039,11 +1056,6 @@
   // Get the block entry for this instruction.
   virtual BlockEntryInstr* GetBlock();
 
-  // Place identifiers used by the load optimization pass.
-  intptr_t place_id() const { return place_id_; }
-  void set_place_id(intptr_t place_id) { place_id_ = place_id; }
-  bool HasPlaceId() const { return place_id_ != kNoPlaceId; }
-
   intptr_t inlining_id() const { return inlining_id_; }
   void set_inlining_id(intptr_t value) {
     ASSERT(value >= 0);
@@ -1141,13 +1153,28 @@
 
   virtual void RawSetInputAt(intptr_t i, Value* value) = 0;
 
-  enum { kNoPlaceId = -1 };
+  class PassSpecificId {
+   public:
+    static intptr_t Encode(CompilerPass::Id pass, intptr_t id) {
+      return (id << kPassBits) | pass;
+    }
+
+    static CompilerPass::Id DecodePass(intptr_t value) {
+      return static_cast<CompilerPass::Id>(value & Utils::NBitMask(kPassBits));
+    }
+
+    static intptr_t DecodeId(intptr_t value) { return (value >> kPassBits); }
+
+    static constexpr intptr_t kNoId = -1;
+
+   private:
+    static constexpr intptr_t kPassBits = 8;
+    static_assert(CompilerPass::kNumPasses <= (1 << kPassBits),
+                  "Pass Id does not fit into the bit field");
+  };
 
   intptr_t deopt_id_;
-  union {
-    intptr_t lifetime_position_;  // Position used by register allocator.
-    intptr_t place_id_;
-  };
+  intptr_t pass_specific_id_ = PassSpecificId::kNoId;
   Instruction* previous_;
   Instruction* next_;
   Environment* env_;
@@ -2770,7 +2797,7 @@
   ReturnInstr(TokenPosition token_pos,
               Value* value,
               intptr_t deopt_id,
-              intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex,
+              intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex,
               Representation representation = kTagged)
       : TemplateInstruction(deopt_id),
         token_pos_(token_pos),
@@ -3587,6 +3614,8 @@
 
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
+  virtual Value* RedefinedValue() const;
+
   PRINT_OPERANDS_TO_SUPPORT
 
  private:
@@ -3664,7 +3693,7 @@
                                (type_args_len > 0 ? 1 : 0)),
         argument_names(argument_names) {}
 
-  RawArray* ToArgumentsDescriptor() const {
+  ArrayPtr ToArgumentsDescriptor() const {
     return ArgumentsDescriptor::New(type_args_len, count_without_type_args,
                                     size_without_type_args, argument_names);
   }
@@ -3697,15 +3726,7 @@
     }
   }
 
-  RawString* Selector() {
-    if (auto static_call = this->AsStaticCall()) {
-      return static_call->function().name();
-    } else if (auto instance_call = this->AsInstanceCall()) {
-      return instance_call->function_name().raw();
-    } else {
-      UNREACHABLE();
-    }
-  }
+  inline StringPtr Selector();
 
   virtual bool MayThrow() const { return true; }
   virtual bool CanCallDart() const { return true; }
@@ -3754,7 +3775,7 @@
   intptr_t type_args_len() const { return type_args_len_; }
   const Array& argument_names() const { return argument_names_; }
   virtual TokenPosition token_pos() const { return token_pos_; }
-  RawArray* GetArgumentsDescriptor() const {
+  ArrayPtr GetArgumentsDescriptor() const {
     return ArgumentsDescriptor::New(
         type_args_len(), ArgumentCountWithoutTypeArgs(),
         ArgumentsSizeWithoutTypeArgs(), argument_names());
@@ -3825,7 +3846,8 @@
                         const Array& argument_names,
                         const ICData* ic_data,
                         intptr_t deopt_id,
-                        const Function& interface_target)
+                        const Function& interface_target,
+                        const Function& tearoff_interface_target)
       : TemplateDartCall(deopt_id,
                          type_args_len,
                          argument_names,
@@ -3835,10 +3857,12 @@
         function_name_(function_name),
         token_kind_(token_kind),
         interface_target_(interface_target),
+        tearoff_interface_target_(tearoff_interface_target),
         result_type_(nullptr),
         has_unique_selector_(false) {
     ASSERT(function_name.IsNotTemporaryScopedHandle());
     ASSERT(interface_target.IsNotTemporaryScopedHandle());
+    ASSERT(tearoff_interface_target.IsNotTemporaryScopedHandle());
     ASSERT(!arguments->is_empty());
     ASSERT(Token::IsBinaryOperator(token_kind) ||
            Token::IsEqualityOperator(token_kind) ||
@@ -3861,6 +3885,9 @@
   const String& function_name() const { return function_name_; }
   Token::Kind token_kind() const { return token_kind_; }
   const Function& interface_target() const { return interface_target_; }
+  const Function& tearoff_interface_target() const {
+    return tearoff_interface_target_;
+  }
 
   bool has_unique_selector() const { return has_unique_selector_; }
   void set_has_unique_selector(bool b) { has_unique_selector_ = b; }
@@ -3892,7 +3919,7 @@
     return result_type_->ToCid();
   }
 
-  RawFunction* ResolveForReceiverClass(const Class& cls, bool allow_add = true);
+  FunctionPtr ResolveForReceiverClass(const Class& cls, bool allow_add = true);
 
   Code::EntryKind entry_kind() const { return entry_kind_; }
   void set_entry_kind(Code::EntryKind value) { entry_kind_ = value; }
@@ -3939,6 +3966,7 @@
   const String& function_name_;
   const Token::Kind token_kind_;  // Binary op, unary op, kGET or kILLEGAL.
   const Function& interface_target_;
+  const Function& tearoff_interface_target_;
   CompileType* result_type_;  // Inferred result type.
   bool has_unique_selector_;
   Code::EntryKind entry_kind_ = Code::EntryKind::kNormal;
@@ -3959,7 +3987,8 @@
       intptr_t checked_argument_count,
       const ZoneGrowableArray<const ICData*>& ic_data_array,
       intptr_t deopt_id,
-      const Function& interface_target = Function::null_function())
+      const Function& interface_target = Function::null_function(),
+      const Function& tearoff_interface_target = Function::null_function())
       : InstanceCallBaseInstr(
             token_pos,
             function_name,
@@ -3969,7 +3998,8 @@
             argument_names,
             GetICData(ic_data_array, deopt_id, /*is_static_call=*/false),
             deopt_id,
-            interface_target),
+            interface_target,
+            tearoff_interface_target),
         checked_argument_count_(checked_argument_count) {}
 
   InstanceCallInstr(
@@ -3981,7 +4011,8 @@
       const Array& argument_names,
       intptr_t checked_argument_count,
       intptr_t deopt_id,
-      const Function& interface_target = Function::null_function())
+      const Function& interface_target = Function::null_function(),
+      const Function& tearoff_interface_target = Function::null_function())
       : InstanceCallBaseInstr(token_pos,
                               function_name,
                               token_kind,
@@ -3990,7 +4021,8 @@
                               argument_names,
                               /*ic_data=*/nullptr,
                               deopt_id,
-                              interface_target),
+                              interface_target,
+                              tearoff_interface_target),
         checked_argument_count_(checked_argument_count) {}
 
   DECLARE_INSTRUCTION(InstanceCall)
@@ -4045,7 +4077,8 @@
     auto new_call = new (zone) PolymorphicInstanceCallInstr(
         call->token_pos(), call->function_name(), call->token_kind(), args,
         call->type_args_len(), call->argument_names(), call->ic_data(),
-        call->deopt_id(), call->interface_target(), targets, complete);
+        call->deopt_id(), call->interface_target(),
+        call->tearoff_interface_target(), targets, complete);
     if (call->has_inlining_id()) {
       new_call->set_inlining_id(call->inlining_id());
     }
@@ -4083,7 +4116,7 @@
 
   virtual Definition* Canonicalize(FlowGraph* graph);
 
-  static RawType* ComputeRuntimeType(const CallTargets& targets);
+  static TypePtr ComputeRuntimeType(const CallTargets& targets);
 
   PRINT_OPERANDS_TO_SUPPORT
   ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
@@ -4098,6 +4131,7 @@
                                const ICData* ic_data,
                                intptr_t deopt_id,
                                const Function& interface_target,
+                               const Function& tearoff_interface_target,
                                const CallTargets& targets,
                                bool complete)
       : InstanceCallBaseInstr(token_pos,
@@ -4108,7 +4142,8 @@
                               argument_names,
                               ic_data,
                               deopt_id,
-                              interface_target),
+                              interface_target,
+                              tearoff_interface_target),
         targets_(targets),
         complete_(complete) {
     ASSERT(targets.length() != 0);
@@ -4151,6 +4186,7 @@
       Zone* zone,
       const InstanceCallBaseInstr* call,
       Value* cid,
+      const Function& interface_target,
       const compiler::TableSelector* selector);
 
   DECLARE_INSTRUCTION(DispatchTableCall)
@@ -4226,6 +4262,16 @@
   ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT;
 
  private:
+  Condition EmitComparisonCodeRegConstant(FlowGraphCompiler* compiler,
+                                          BranchLabels labels,
+                                          Register reg,
+                                          const Object& obj);
+  bool TryEmitBoolTest(FlowGraphCompiler* compiler,
+                       BranchLabels labels,
+                       intptr_t input_index,
+                       const Object& obj,
+                       Condition* condition_out);
+
   // True if the comparison must check for double or Mint and
   // use value comparison instead.
   bool needs_number_check_;
@@ -4970,7 +5016,7 @@
 class DebugStepCheckInstr : public TemplateInstruction<0, NoThrow> {
  public:
   DebugStepCheckInstr(TokenPosition token_pos,
-                      RawPcDescriptors::Kind stub_kind,
+                      PcDescriptorsLayout::Kind stub_kind,
                       intptr_t deopt_id)
       : TemplateInstruction<0, NoThrow>(deopt_id),
         token_pos_(token_pos),
@@ -4987,7 +5033,7 @@
 
  private:
   const TokenPosition token_pos_;
-  const RawPcDescriptors::Kind stub_kind_;
+  const PcDescriptorsLayout::Kind stub_kind_;
 
   DISALLOW_COPY_AND_ASSIGN(DebugStepCheckInstr);
 };
@@ -5200,7 +5246,7 @@
 
 // For a field of static type G<T0, ..., Tn> and a stored value of runtime
 // type T checks that type arguments of T at G exactly match <T0, ..., Tn>
-// and updates guarded state (RawField::static_type_exactness_state_)
+// and updates guarded state (FieldLayout::static_type_exactness_state_)
 // accordingly.
 //
 // See StaticTypeExactnessState for more information.
@@ -5385,7 +5431,7 @@
         element_count_(element_count),
         representation_(kTagged) {
     ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
-    ASSERT(RawObject::IsStringClassId(class_id));
+    ASSERT(IsStringClassId(class_id));
     SetInputAt(0, str);
     SetInputAt(1, index);
   }
@@ -5792,13 +5838,8 @@
   virtual bool HasUnknownSideEffects() const { return false; }
 
   virtual bool WillAllocateNewOrRemembered() const {
-    return WillAllocateNewOrRemembered(num_context_variables_);
-  }
-
-  static bool WillAllocateNewOrRemembered(intptr_t num_context_variables) {
-    if (!Context::IsValidLength(num_context_variables)) return false;
-    return Heap::IsAllocatableInNewSpace(
-        Context::InstanceSize(num_context_variables));
+    return compiler::target::WillAllocateNewOrRememberedContext(
+        num_context_variables_);
   }
 
   virtual AliasIdentity Identity() const { return identity_; }
@@ -5953,12 +5994,8 @@
     if (!num_elements()->BindsToConstant()) return false;
     const Object& length = num_elements()->BoundConstant();
     if (!length.IsSmi()) return false;
-    return WillAllocateNewOrRemembered(Smi::Cast(length).Value());
-  }
-
-  static bool WillAllocateNewOrRemembered(const intptr_t length) {
-    if (!Array::IsValidLength(length)) return false;
-    return !Array::UseCardMarkingForAllocation(length);
+    return compiler::target::WillAllocateNewOrRememberedArray(
+        Smi::Cast(length).Value());
   }
 
  private:
@@ -6279,13 +6316,8 @@
   virtual bool HasUnknownSideEffects() const { return false; }
 
   virtual bool WillAllocateNewOrRemembered() const {
-    return WillAllocateNewOrRemembered(context_slots().length());
-  }
-
-  static bool WillAllocateNewOrRemembered(intptr_t num_context_variables) {
-    if (!Context::IsValidLength(num_context_variables)) return false;
-    return Heap::IsAllocatableInNewSpace(
-        Context::InstanceSize(num_context_variables));
+    return compiler::target::WillAllocateNewOrRememberedContext(
+        context_slots().length());
   }
 
   PRINT_OPERANDS_TO_SUPPORT
@@ -6316,6 +6348,11 @@
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
+  virtual bool AllowsCSE() const { return true; }
+  virtual bool AttributesEqual(Instruction* other) const {
+    return other->AsInitInstanceField()->field().raw() == field().raw();
+  }
+
  private:
   const Field& field_;
 
@@ -6340,6 +6377,13 @@
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
+  // Two InitStaticField instructions can be canonicalized into one
+  // instruction if both are initializing the same field.
+  virtual bool AllowsCSE() const { return true; }
+  virtual bool AttributesEqual(Instruction* other) const {
+    return other->AsInitStaticField()->field().raw() == field().raw();
+  }
+
  private:
   const Field& field_;
 
@@ -8314,7 +8358,7 @@
   bool IsArgumentCheck() const { return exception_type_ == kArgumentError; }
   ExceptionType exception_type() const { return exception_type_; }
 
-  bool UseSharedSlowPathStub(bool is_optimizing) const {
+  virtual bool UseSharedSlowPathStub(bool is_optimizing) const {
     return SlowPathSharingSupported(is_optimizing);
   }
 
@@ -8474,6 +8518,10 @@
 
   virtual bool MayThrow() const { return true; }
 
+  virtual bool UseSharedSlowPathStub(bool is_optimizing) const {
+    return SlowPathSharingSupported(is_optimizing);
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr);
 };
@@ -9140,6 +9188,17 @@
   }                                                                            \
   void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
 
+template <intptr_t kExtraInputs>
+StringPtr TemplateDartCall<kExtraInputs>::Selector() {
+  if (auto static_call = this->AsStaticCall()) {
+    return static_call->function().name();
+  } else if (auto instance_call = this->AsInstanceCall()) {
+    return instance_call->function_name().raw();
+  } else {
+    UNREACHABLE();
+  }
+}
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_BACKEND_IL_H_
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index a765a18..59da8b5 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM)
 
 #include "vm/compiler/backend/il.h"
 
@@ -145,10 +145,7 @@
                (NoLocation,
                 Fixed<Register, ARGS_DESC_REG>,
                 Temp<Register> temp)) {
-  __ LoadObject(CODE_REG, instr->code());
-  __ LeaveDartFrame();  // The arguments are still on the stack.
-  __ Branch(compiler::FieldAddress(
-      CODE_REG, compiler::target::Code::entry_point_offset()));
+  compiler->EmitTailCallToStub(instr->code());
 
   // Even though the TailCallInstr will be the last instruction in a basic
   // block, the flow graph compiler will emit native code for other blocks after
@@ -386,7 +383,7 @@
   __ Bind(&stack_ok);
 #endif
   ASSERT(__ constant_pool_allowed());
-  if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
     compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
   }
   __ LeaveDartFrameAndReturn();  // Disallows constant pool use.
@@ -395,38 +392,6 @@
   __ set_constant_pool_allowed(true);
 }
 
-static Condition NegateCondition(Condition condition) {
-  switch (condition) {
-    case EQ:
-      return NE;
-    case NE:
-      return EQ;
-    case LT:
-      return GE;
-    case LE:
-      return GT;
-    case GT:
-      return LE;
-    case GE:
-      return LT;
-    case CC:
-      return CS;
-    case LS:
-      return HI;
-    case HI:
-      return LS;
-    case CS:
-      return CC;
-    case VC:
-      return VS;
-    case VS:
-      return VC;
-    default:
-      UNREACHABLE();
-      return EQ;
-  }
-}
-
 // Detect pattern when one value is zero and another is a power of 2.
 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
   return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
@@ -464,7 +429,7 @@
   if (is_power_of_two_kind) {
     if (true_value == 0) {
       // We need to have zero in result on true_condition.
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   } else {
     if (true_value == 0) {
@@ -473,7 +438,7 @@
       true_value = false_value;
       false_value = temp;
     } else {
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   }
 
@@ -539,7 +504,7 @@
   }
   __ blx(R2);
   compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
-                                 RawPcDescriptors::kOther, locs());
+                                 PcDescriptorsLayout::kOther, locs());
   __ Drop(argument_count);
 }
 
@@ -741,48 +706,6 @@
   return summary;
 }
 
-LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
-                                                         bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(R0));
-  locs->set_out(0, Location::RegisterLocation(R0));
-  return locs;
-}
-
-static void EmitAssertBoolean(Register reg,
-                              TokenPosition token_pos,
-                              intptr_t deopt_id,
-                              LocationSummary* locs,
-                              FlowGraphCompiler* compiler) {
-  // Check that the type of the value is allowed in conditional context.
-  // Call the runtime if the object is not bool::true or bool::false.
-  ASSERT(locs->always_calls());
-  compiler::Label done;
-
-  __ CompareObject(reg, Object::null_instance());
-  __ b(&done, NE);
-
-  __ Push(reg);  // Push the source object.
-  compiler->GenerateRuntimeCall(token_pos, deopt_id,
-                                kNonBoolTypeErrorRuntimeEntry, 1, locs);
-  // We should never return here.
-#if defined(DEBUG)
-  __ bkpt(0);
-#endif
-  __ Bind(&done);
-}
-
-void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register obj = locs()->in(0).reg();
-  const Register result = locs()->out(0).reg();
-
-  EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
-  ASSERT(obj == result);
-}
-
 static Condition TokenKindToSmiCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -895,7 +818,7 @@
     __ b(labels.true_label, true_condition);
   } else {
     // If the next block is not the false successor we will branch to it.
-    Condition false_condition = NegateCondition(true_condition);
+    Condition false_condition = InvertCondition(true_condition);
     __ b(labels.false_label, false_condition);
 
     // Fall through or jump to the true successor.
@@ -1231,10 +1154,10 @@
                          : compiler::ObjectPoolBuilderEntry::kNotPatchable);
   if (link_lazily()) {
     compiler->GeneratePatchableCall(token_pos(), *stub,
-                                    RawPcDescriptors::kOther, locs());
+                                    PcDescriptorsLayout::kOther, locs());
   } else {
-    compiler->GenerateCall(token_pos(), *stub, RawPcDescriptors::kOther,
-                           locs());
+    compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
+                               locs());
   }
   __ Pop(result);
 
@@ -1273,7 +1196,7 @@
   // instruction. Therefore we emit the metadata here, 8 bytes (2 instructions)
   // after the original mov.
   compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
-                                 RawPcDescriptors::Kind::kOther, locs());
+                                 PcDescriptorsLayout::Kind::kOther, locs());
 
   // Update information in the thread object and enter a safepoint.
   if (CanExecuteGeneratedCodeInSafepoint()) {
@@ -1422,28 +1345,8 @@
   // Load the thread object. If we were called by a trampoline, the thread is
   // already loaded.
   if (FLAG_precompiled_mode) {
-    compiler::Label skip_reloc;
-    __ b(&skip_reloc);
-    compiler->InsertBSSRelocation(
-        BSS::Relocation::DRT_GetThreadForNativeCallback);
-    __ Bind(&skip_reloc);
-
-    // For historical reasons, the PC on ARM points 8 bytes (two instructions)
-    // past the current instruction.
-    __ sub(
-        R0, PC,
-        compiler::Operand(Instr::kPCReadOffset + compiler::target::kWordSize));
-
-    // R0 holds the address of the relocation.
-    __ ldr(R1, compiler::Address(R0));
-
-    // R1 holds the relocation itself: R0 - bss_start.
-    // R0 = R0 + (bss_start - R0) = bss_start
-    __ add(R0, R0, compiler::Operand(R1));
-
-    // R0 holds the start of the BSS section.
-    // Load the "get-thread" routine: *bss_start.
-    __ ldr(R1, compiler::Address(R0));
+    compiler->LoadBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback, R1,
+                           R0);
   } else if (!NativeCallbackTrampolines::Enabled()) {
     // In JIT mode, we can just paste the address of the runtime entry into the
     // generated code directly. This is not a problem since we don't save
@@ -2394,9 +2297,12 @@
         }
       }
       __ b(fail, NE);
+    } else if (value_cid == field_cid) {
+      // This would normaly be caught by Canonicalize, but RemoveRedefinitions
+      // may sometimes produce the situation after the last Canonicalize pass.
     } else {
       // Both value's and field's class id is known.
-      ASSERT((value_cid != field_cid) && (value_cid != nullability));
+      ASSERT(value_cid != nullability);
       __ b(fail);
     }
   }
@@ -2523,8 +2429,8 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
-                           stub, RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(TokenPosition::kNoSource,  // No token position.
+                               stub, PcDescriptorsLayout::kOther, locs);
     __ MoveRegister(result_, R0);
     compiler->RestoreLiveRegisters(locs);
     __ b(exit_label());
@@ -3067,7 +2973,7 @@
   // data area to be initialized.
   // R8: null
   if (num_elements > 0) {
-    const intptr_t array_size = instance_size - sizeof(RawArray);
+    const intptr_t array_size = instance_size - sizeof(ArrayLayout);
     __ LoadObject(R8, Object::null_object());
     if (num_elements >= 2) {
       __ mov(R9, compiler::Operand(R8));
@@ -3077,7 +2983,7 @@
       __ LoadImmediate(R9, 0x1);
 #endif  // DEBUG
     }
-    __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
+    __ AddImmediate(R6, R0, sizeof(ArrayLayout) - kHeapObjectTag);
     if (array_size < (kInlineArraySize * compiler::target::kWordSize)) {
       __ InitializeFieldsNoBarrierUnrolled(
           R0, R6, 0, num_elements * compiler::target::kWordSize, R8, R9);
@@ -3124,9 +3030,12 @@
       return;
     }
   }
-  compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
-                                  StubCode::AllocateArray(),
-                                  RawPcDescriptors::kOther, locs());
+
+  auto object_store = compiler->isolate()->object_store();
+  const auto& allocate_array_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->allocate_array_stub());
+  compiler->GenerateStubCall(token_pos(), allocate_array_stub,
+                             PcDescriptorsLayout::kOther, locs(), deopt_id());
   ASSERT(locs()->out(0).reg() == kResultReg);
 }
 
@@ -3389,8 +3298,8 @@
   // Lookup cache in stub before calling runtime.
   __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
                 type_arguments());
-  compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
-                         locs());
+  compiler->GenerateStubCall(token_pos(), GetStub(),
+                             PcDescriptorsLayout::kOther, locs());
   __ Bind(&type_arguments_instantiated);
 }
 
@@ -3425,10 +3334,13 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto object_store = compiler->isolate()->object_store();
+    const auto& allocate_context_stub = Code::ZoneHandle(
+        compiler->zone(), object_store->allocate_context_stub());
     __ LoadImmediate(R1, instruction()->num_context_variables());
-    compiler->GenerateCall(instruction()->token_pos(),
-                           StubCode::AllocateContext(),
-                           RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(instruction()->token_pos(),
+                               allocate_context_stub,
+                               PcDescriptorsLayout::kOther, locs);
     ASSERT(instruction()->locs()->out(0).reg() == R0);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ b(exit_label());
@@ -3473,38 +3385,12 @@
   ASSERT(locs()->temp(0).reg() == R1);
   ASSERT(locs()->out(0).reg() == R0);
 
+  auto object_store = compiler->isolate()->object_store();
+  const auto& allocate_context_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
   __ LoadImmediate(R1, num_context_variables());
-  compiler->GenerateCall(token_pos(), StubCode::AllocateContext(),
-                         RawPcDescriptors::kOther, locs());
-}
-
-LocationSummary* InitInstanceFieldInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(R0));
-  locs->set_temp(0, Location::RegisterLocation(R1));
-  return locs;
-}
-
-void InitInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register instance = locs()->in(0).reg();
-  Register temp = locs()->temp(0).reg();
-  compiler::Label no_call;
-
-  __ ldr(temp, compiler::FieldAddress(instance, field().TargetOffset()));
-  __ CompareObject(temp, Object::sentinel());
-  __ b(&no_call, NE);
-
-  __ PushObject(Object::null_object());  // Make room for (unused) result.
-  __ Push(instance);
-  __ PushObject(Field::ZoneHandle(field().Original()));
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
-                                kInitInstanceFieldRuntimeEntry, 2, locs());
-  __ Drop(3);  // Remove arguments and result placeholder.
-  __ Bind(&no_call);
+  compiler->GenerateStubCall(token_pos(), allocate_context_stub,
+                             PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3522,8 +3408,11 @@
   ASSERT(locs()->in(0).reg() == R4);
   ASSERT(locs()->out(0).reg() == R0);
 
-  compiler->GenerateCall(token_pos(), StubCode::CloneContext(),
-                         /*kind=*/RawPcDescriptors::kOther, locs());
+  auto object_store = compiler->isolate()->object_store();
+  const auto& clone_context_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
+  compiler->GenerateStubCall(token_pos(), clone_context_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3544,7 +3433,7 @@
     if (compiler->is_optimizing()) {
       compiler->AddDeoptIndexAtCall(deopt_id);
     } else {
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
                                      TokenPosition::kNoSource);
     }
   }
@@ -3631,7 +3520,7 @@
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
       compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
-          RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
+          PcDescriptorsLayout::kOther, compiler->assembler()->CodeSize(),
           instruction()->deopt_id(), instruction()->token_pos(),
           compiler->CurrentTryIndex());
     } else {
@@ -3643,7 +3532,7 @@
     if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
         instruction()->in_loop()) {
       // In unoptimized code, record loop stack checks as possible OSR entries.
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
                                      instruction()->deopt_id(),
                                      TokenPosition::kNoSource);
     }
@@ -3686,7 +3575,7 @@
     // the stub above).
     auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
     compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
-                                   RawPcDescriptors::kOther, locs(),
+                                   PcDescriptorsLayout::kOther, locs(),
                                    extended_env);
     return;
   }
@@ -4086,7 +3975,7 @@
   ASSERT(true_condition != kInvalidCondition);
   Register result = locs()->out(0).reg();
   __ LoadObject(result, Bool::True(), true_condition);
-  __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
+  __ LoadObject(result, Bool::False(), InvertCondition(true_condition));
   __ Bind(slow_path->exit_label());
 }
 #undef EMIT_SMI_CHECK
@@ -4871,6 +4760,7 @@
               !Isolate::Current()
                    ->object_store()
                    ->allocate_mint_with_fpu_regs_stub()
+                   ->ptr()
                    ->InVMIsolateHeap())
                  ? LocationSummary::kCallOnSharedSlowPath
                  : LocationSummary::kCallOnSlowPath));
@@ -4907,7 +4797,7 @@
   if (compiler->intrinsic_mode()) {
     __ TryAllocate(compiler->mint_class(),
                    compiler->intrinsic_slow_path_label(), out_reg, tmp);
-  } else {
+  } else if (locs()->call_on_shared_slow_path()) {
     auto object_store = compiler->isolate()->object_store();
     const bool live_fpu_regs = locs()->live_registers()->FpuRegisterCount() > 0;
     const auto& stub = Code::ZoneHandle(
@@ -4915,24 +4805,13 @@
         live_fpu_regs ? object_store->allocate_mint_with_fpu_regs_stub()
                       : object_store->allocate_mint_without_fpu_regs_stub());
 
-    if (locs()->call_on_shared_slow_path()) {
-      // BoxInt64Instr uses shared slow path only if stub can be reached
-      // via PC-relative call.
-      ASSERT(FLAG_use_bare_instructions);
-      ASSERT(!stub.InVMIsolateHeap());
-      __ GenerateUnRelocatedPcRelativeCall();
-      compiler->AddPcRelativeCallStubTarget(stub);
-
-      ASSERT(!locs()->live_registers()->ContainsRegister(R0));
-
-      auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
-      compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
-                                     RawPcDescriptors::kOther, locs(),
-                                     extended_env);
-    } else {
-      BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
-                                      out_reg, tmp);
-    }
+    ASSERT(!locs()->live_registers()->ContainsRegister(R0));
+    auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
+    compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                               locs(), DeoptId::kNone, extended_env);
+  } else {
+    BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
+                                    out_reg, tmp);
   }
 
   __ StoreToOffset(kWord, value_lo, out_reg,
@@ -6494,7 +6373,7 @@
     // the stub above).
     auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
     compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
-                                   RawPcDescriptors::kOther, locs(),
+                                   PcDescriptorsLayout::kOther, locs(),
                                    extended_env);
     CheckNullInstr::AddMetadataForRuntimeCall(this, compiler);
     return;
@@ -6511,16 +6390,6 @@
   __ BranchIf(EQUAL, slow_path->entry_label());
 }
 
-void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                           bool save_fpu_registers) {
-  compiler->assembler()->CallNullErrorShared(save_fpu_registers);
-}
-
-void NullArgErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                              bool save_fpu_registers) {
-  compiler->assembler()->CallNullArgErrorShared(save_fpu_registers);
-}
-
 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -7379,44 +7248,6 @@
   }
 }
 
-LocationSummary* ThrowInstr::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));
-  return summary;
-}
-
-void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  __ Push(exception_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1,
-                                locs());
-  __ bkpt(0);
-}
-
-LocationSummary* ReThrowInstr::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::kCall);
-  summary->set_in(0, Location::RegisterLocation(R0));
-  summary->set_in(1, Location::RegisterLocation(R1));
-  return summary;
-}
-
-void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  const Register stacktrace_reg = locs()->in(1).reg();
-  compiler->SetNeedsStackTrace(catch_try_index());
-  __ Push(exception_reg);
-  __ Push(stacktrace_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry,
-                                2, locs());
-  __ bkpt(0);
-}
-
 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const {
   return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
 }
@@ -7450,7 +7281,7 @@
     }
     // Add a deoptimization descriptor for deoptimizing instructions that
     // may be inserted before this instruction.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -7535,29 +7366,13 @@
   return locs;
 }
 
-Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
-                                                 BranchLabels labels) {
-  Location left = locs()->in(0);
-  Location right = locs()->in(1);
-  ASSERT(!left.IsConstant() || !right.IsConstant());
-  Condition true_condition;
-  if (left.IsConstant()) {
-    true_condition = compiler->EmitEqualityRegConstCompare(
-        right.reg(), left.constant(), needs_number_check(), token_pos(),
-        deopt_id_);
-  } else if (right.IsConstant()) {
-    true_condition = compiler->EmitEqualityRegConstCompare(
-        left.reg(), right.constant(), needs_number_check(), token_pos(),
-        deopt_id_);
-  } else {
-    true_condition = compiler->EmitEqualityRegRegCompare(
-        left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
-  }
-  if (kind() != Token::kEQ_STRICT) {
-    ASSERT(kind() == Token::kNE_STRICT);
-    true_condition = NegateCondition(true_condition);
-  }
-  return true_condition;
+Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
+    FlowGraphCompiler* compiler,
+    BranchLabels labels,
+    Register reg,
+    const Object& obj) {
+  return compiler->EmitEqualityRegConstCompare(reg, obj, needs_number_check(),
+                                               token_pos(), deopt_id());
 }
 
 void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -7582,7 +7397,7 @@
     // a condition we can avoid the branch and use conditional loads.
     ASSERT(true_condition != kInvalidCondition);
     __ LoadObject(result, Bool::True(), true_condition);
-    __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
+    __ LoadObject(result, Bool::False(), InvertCondition(true_condition));
   }
 }
 
@@ -7602,12 +7417,18 @@
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register value = locs()->in(0).reg();
+  const Register input = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
 
-  __ LoadObject(result, Bool::True());
-  __ cmp(result, compiler::Operand(value));
-  __ LoadObject(result, Bool::False(), EQ);
+  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);
+  }
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -7634,7 +7455,8 @@
   }
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
-  compiler->GenerateCall(token_pos(), stub, RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                             locs());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -7650,4 +7472,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 2c73987..8b5b9e8 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM64)
 
 #include "vm/compiler/backend/il.h"
 
@@ -125,10 +125,7 @@
                (NoLocation,
                 Fixed<Register, ARGS_DESC_REG>,
                 Temp<Register> temp)) {
-  __ LoadObject(CODE_REG, instr->code());
-  __ LeaveDartFrame();  // The arguments are still on the stack.
-  __ ldr(temp, compiler::FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ br(temp);
+  compiler->EmitTailCallToStub(instr->code());
 
   // Even though the TailCallInstr will be the last instruction in a basic
   // block, the flow graph compiler will emit native code for other blocks after
@@ -286,7 +283,7 @@
   __ Bind(&stack_ok);
 #endif
   ASSERT(__ constant_pool_allowed());
-  if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
     compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
   }
   __ LeaveDartFrame();  // Disallows constant pool use.
@@ -296,38 +293,6 @@
   __ set_constant_pool_allowed(true);
 }
 
-static Condition NegateCondition(Condition condition) {
-  switch (condition) {
-    case EQ:
-      return NE;
-    case NE:
-      return EQ;
-    case LT:
-      return GE;
-    case LE:
-      return GT;
-    case GT:
-      return LE;
-    case GE:
-      return LT;
-    case CC:
-      return CS;
-    case LS:
-      return HI;
-    case HI:
-      return LS;
-    case CS:
-      return CC;
-    case VS:
-      return VC;
-    case VC:
-      return VS;
-    default:
-      UNREACHABLE();
-      return EQ;
-  }
-}
-
 // Detect pattern when one value is zero and another is a power of 2.
 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
   return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
@@ -362,7 +327,7 @@
   if (is_power_of_two_kind) {
     if (true_value == 0) {
       // We need to have zero in result on true_condition.
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   } else {
     if (true_value == 0) {
@@ -371,7 +336,7 @@
       true_value = false_value;
       false_value = temp;
     } else {
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   }
 
@@ -435,7 +400,7 @@
   }
   __ blr(R2);
   compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
-                                 RawPcDescriptors::kOther, locs());
+                                 PcDescriptorsLayout::kOther, locs());
   __ Drop(argument_count);
 }
 
@@ -632,48 +597,6 @@
   return summary;
 }
 
-LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
-                                                         bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(R0));
-  locs->set_out(0, Location::RegisterLocation(R0));
-  return locs;
-}
-
-static void EmitAssertBoolean(Register reg,
-                              TokenPosition token_pos,
-                              intptr_t deopt_id,
-                              LocationSummary* locs,
-                              FlowGraphCompiler* compiler) {
-  // Check that the type of the value is allowed in conditional context.
-  // Call the runtime if the object is not bool::true or bool::false.
-  ASSERT(locs->always_calls());
-  compiler::Label done;
-
-  __ CompareObject(reg, Object::null_instance());
-  __ b(&done, NE);
-
-  __ Push(reg);  // Push the source object.
-  compiler->GenerateRuntimeCall(token_pos, deopt_id,
-                                kNonBoolTypeErrorRuntimeEntry, 1, locs);
-  // We should never return here.
-#if defined(DEBUG)
-  __ brk(0);
-#endif
-  __ Bind(&done);
-}
-
-void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register obj = locs()->in(0).reg();
-  const Register result = locs()->out(0).reg();
-
-  EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
-  ASSERT(obj == result);
-}
-
 static Condition TokenKindToSmiCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -730,7 +653,7 @@
     __ b(labels.true_label, true_condition);
   } else {
     // If the next block is not the false successor we will branch to it.
-    Condition false_condition = NegateCondition(true_condition);
+    Condition false_condition = InvertCondition(true_condition);
     __ b(labels.false_label, false_condition);
 
     // Fall through or jump to the true successor.
@@ -762,7 +685,7 @@
     __ GenerateXCbzTbz(reg, true_condition, labels.true_label);
   } else {
     // If the next block is not the false successor we will branch to it.
-    Condition false_condition = NegateCondition(true_condition);
+    Condition false_condition = InvertCondition(true_condition);
     __ GenerateXCbzTbz(reg, false_condition, labels.false_label);
 
     // Fall through or jump to the true successor.
@@ -914,7 +837,7 @@
   Location right = locs()->in(1);
   if (right.IsConstant()) {
     ASSERT(right.constant().IsSmi());
-    const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw());
+    const int64_t imm = static_cast<int64_t>(right.constant().raw());
     __ TestImmediate(left, imm);
   } else {
     __ tst(left, compiler::Operand(right.reg()));
@@ -1057,10 +980,10 @@
                                    : ObjectPool::Patchability::kNotPatchable);
   if (link_lazily()) {
     compiler->GeneratePatchableCall(token_pos(), *stub,
-                                    RawPcDescriptors::kOther, locs());
+                                    PcDescriptorsLayout::kOther, locs());
   } else {
-    compiler->GenerateCall(token_pos(), *stub, RawPcDescriptors::kOther,
-                           locs());
+    compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
+                               locs());
   }
   __ Pop(result);
 
@@ -1094,7 +1017,7 @@
   // instruction.
   __ adr(temp, compiler::Immediate(Instr::kInstrSize));
   compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
-                                 RawPcDescriptors::Kind::kOther, locs());
+                                 PcDescriptorsLayout::Kind::kOther, locs());
 
   __ StoreToOffset(temp, FPREG, kSavedCallerPcSlotFromFp * kWordSize);
 
@@ -1250,24 +1173,8 @@
   // Load the thread object. If we were called by a trampoline, the thread is
   // already loaded.
   if (FLAG_precompiled_mode) {
-    compiler::Label skip_reloc;
-    __ b(&skip_reloc);
-    compiler->InsertBSSRelocation(
-        BSS::Relocation::DRT_GetThreadForNativeCallback);
-    __ Bind(&skip_reloc);
-
-    __ adr(R0, compiler::Immediate(-compiler::target::kWordSize));
-
-    // R0 holds the address of the relocation.
-    __ ldr(R1, compiler::Address(R0));
-
-    // R1 holds the relocation itself: R0 - bss_start.
-    // R0 = R0 + (bss_start - R0) = bss_start
-    __ add(R0, R0, compiler::Operand(R1));
-
-    // R0 holds the start of the BSS section.
-    // Load the "get-thread" routine: *bss_start.
-    __ ldr(R1, compiler::Address(R0));
+    compiler->LoadBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback, R1,
+                           R0);
   } else if (!NativeCallbackTrampolines::Enabled()) {
     // In JIT mode, we can just paste the address of the runtime entry into the
     // generated code directly. This is not a problem since we don't save
@@ -1805,7 +1712,7 @@
 
   switch (class_id()) {
     case kArrayCid:
-      ASSERT(!ShouldEmitStoreBarrier());   // Specially treated above.
+      ASSERT(!ShouldEmitStoreBarrier());  // Specially treated above.
       if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
         __ StoreIntoObjectNoBarrier(array, element_address, constant);
@@ -2066,9 +1973,12 @@
       }
 
       __ b(fail, NE);
+    } else if (value_cid == field_cid) {
+      // This would normaly be caught by Canonicalize, but RemoveRedefinitions
+      // may sometimes produce the situation after the last Canonicalize pass.
     } else {
       // Both value's and field's class id is known.
-      ASSERT((value_cid != field_cid) && (value_cid != nullability));
+      ASSERT(value_cid != nullability);
       __ b(fail);
     }
   }
@@ -2181,8 +2091,8 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
-                           stub, RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(TokenPosition::kNoSource,  // No token position.
+                               stub, PcDescriptorsLayout::kOther, locs);
     __ MoveRegister(result_, R0);
     compiler->RestoreLiveRegisters(locs);
     __ b(exit_label());
@@ -2579,9 +2489,9 @@
   // data area to be initialized.
   // R6: null
   if (num_elements > 0) {
-    const intptr_t array_size = instance_size - sizeof(RawArray);
+    const intptr_t array_size = instance_size - sizeof(ArrayLayout);
     __ LoadObject(R6, Object::null_object());
-    __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag);
+    __ AddImmediate(R8, R0, sizeof(ArrayLayout) - kHeapObjectTag);
     if (array_size < (kInlineArraySize * kWordSize)) {
       intptr_t current_offset = 0;
       while (current_offset < array_size) {
@@ -2636,9 +2546,11 @@
       return;
     }
   }
-  compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
-                                  StubCode::AllocateArray(),
-                                  RawPcDescriptors::kOther, locs());
+  auto object_store = compiler->isolate()->object_store();
+  const auto& allocate_array_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->allocate_array_stub());
+  compiler->GenerateStubCall(token_pos(), allocate_array_stub,
+                             PcDescriptorsLayout::kOther, locs(), deopt_id());
   ASSERT(locs()->out(0).reg() == kResultReg);
 }
 
@@ -2879,8 +2791,8 @@
   // Lookup cache in stub before calling runtime.
   __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
                 type_arguments());
-  compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
-                         locs());
+  compiler->GenerateStubCall(token_pos(), GetStub(),
+                             PcDescriptorsLayout::kOther, locs());
   __ Bind(&type_arguments_instantiated);
 }
 
@@ -2915,10 +2827,14 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto object_store = compiler->isolate()->object_store();
+    const auto& allocate_context_stub = Code::ZoneHandle(
+        compiler->zone(), object_store->allocate_context_stub());
+
     __ LoadImmediate(R1, instruction()->num_context_variables());
-    compiler->GenerateCall(instruction()->token_pos(),
-                           StubCode::AllocateContext(),
-                           RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(instruction()->token_pos(),
+                               allocate_context_stub,
+                               PcDescriptorsLayout::kOther, locs);
     ASSERT(instruction()->locs()->out(0).reg() == R0);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ b(exit_label());
@@ -2963,37 +2879,12 @@
   ASSERT(locs()->temp(0).reg() == R1);
   ASSERT(locs()->out(0).reg() == R0);
 
+  auto object_store = compiler->isolate()->object_store();
+  const auto& allocate_context_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
   __ LoadImmediate(R1, num_context_variables());
-  compiler->GenerateCall(token_pos(), StubCode::AllocateContext(),
-                         RawPcDescriptors::kOther, locs());
-}
-
-LocationSummary* InitInstanceFieldInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(R0));
-  locs->set_temp(0, Location::RegisterLocation(R1));
-  return locs;
-}
-
-void InitInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register instance = locs()->in(0).reg();
-  Register temp = locs()->temp(0).reg();
-  compiler::Label no_call;
-
-  __ ldr(temp, compiler::FieldAddress(instance, field().TargetOffset()));
-  __ CompareObject(temp, Object::sentinel());
-  __ b(&no_call, NE);
-
-  __ PushPair(instance, ZR);  // Make room for (unused) result.
-  __ PushObject(Field::ZoneHandle(field().Original()));
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
-                                kInitInstanceFieldRuntimeEntry, 2, locs());
-  __ Drop(3);  // Remove arguments and result placeholder.
-  __ Bind(&no_call);
+  compiler->GenerateStubCall(token_pos(), allocate_context_stub,
+                             PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3011,8 +2902,11 @@
   ASSERT(locs()->in(0).reg() == R5);
   ASSERT(locs()->out(0).reg() == R0);
 
-  compiler->GenerateCall(token_pos(), StubCode::CloneContext(),
-                         /*kind=*/RawPcDescriptors::kOther, locs());
+  auto object_store = compiler->isolate()->object_store();
+  const auto& clone_context_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
+  compiler->GenerateStubCall(token_pos(), clone_context_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3033,7 +2927,7 @@
     if (compiler->is_optimizing()) {
       compiler->AddDeoptIndexAtCall(deopt_id);
     } else {
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
                                      TokenPosition::kNoSource);
     }
   }
@@ -3132,7 +3026,7 @@
       compiler->RecordSafepoint(locs, kNumSlowPathArgs);
       compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
-          RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
+          PcDescriptorsLayout::kOther, compiler->assembler()->CodeSize(),
           instruction()->deopt_id(), instruction()->token_pos(),
           compiler->CurrentTryIndex());
     } else {
@@ -3144,7 +3038,7 @@
     if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
         instruction()->in_loop()) {
       // In unoptimized code, record loop stack checks as possible OSR entries.
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
                                      instruction()->deopt_id(),
                                      TokenPosition::kNoSource);
     }
@@ -3241,8 +3135,7 @@
       const bool right_needs_check =
           !RangeUtils::IsWithin(right_range, 0, max_right - 1);
       if (right_needs_check) {
-        __ CompareImmediate(right,
-                            reinterpret_cast<int64_t>(Smi::New(max_right)));
+        __ CompareImmediate(right, static_cast<int64_t>(Smi::New(max_right)));
         __ b(deopt, CS);
       }
       __ SmiUntag(TMP, right);
@@ -3261,8 +3154,7 @@
         __ b(deopt, MI);
       }
 
-      __ CompareImmediate(right,
-                          reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
       __ csel(result, ZR, result, CS);
       __ SmiUntag(TMP, right);
       __ lslv(TMP, left, TMP);
@@ -3274,8 +3166,7 @@
   } else {
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
-      __ CompareImmediate(right,
-                          reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
       __ b(deopt, CS);
     }
     // Left is not a constant.
@@ -3399,8 +3290,7 @@
     case Token::kSHL:
       ASSERT(result != left);
       ASSERT(result != right);
-      __ CompareImmediate(right,
-                          reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
       __ b(slow_path->entry_label(), CS);
 
       __ SmiUntag(TMP, right);
@@ -3412,8 +3302,7 @@
     case Token::kSHR:
       ASSERT(result != left);
       ASSERT(result != right);
-      __ CompareImmediate(right,
-                          reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
       __ b(slow_path->entry_label(), CS);
 
       __ SmiUntag(result, right);
@@ -3632,7 +3521,7 @@
   if (locs()->in(1).IsConstant()) {
     const Object& constant = locs()->in(1).constant();
     ASSERT(constant.IsSmi());
-    const int64_t imm = reinterpret_cast<int64_t>(constant.raw());
+    const int64_t imm = static_cast<int64_t>(constant.raw());
     switch (op_kind()) {
       case Token::kADD: {
         if (deopt == NULL) {
@@ -4062,10 +3951,12 @@
   const bool stubs_in_vm_isolate = (Isolate::Current()
                                         ->object_store()
                                         ->allocate_mint_with_fpu_regs_stub()
+                                        ->ptr()
                                         ->InVMIsolateHeap() ||
                                     Isolate::Current()
                                         ->object_store()
                                         ->allocate_mint_without_fpu_regs_stub()
+                                        ->ptr()
                                         ->InVMIsolateHeap());
   const bool shared_slow_path_call = SlowPathSharingSupported(opt) &&
                                      FLAG_use_bare_instructions &&
@@ -4117,19 +4008,11 @@
           compiler->zone(),
           live_fpu_regs ? object_store->allocate_mint_with_fpu_regs_stub()
                         : object_store->allocate_mint_without_fpu_regs_stub());
-      // BoxInt64Instr uses shared slow path only if stub can be reached
-      // via PC-relative call.
-      ASSERT(FLAG_use_bare_instructions);
-      ASSERT(!stub.InVMIsolateHeap());
-      __ GenerateUnRelocatedPcRelativeCall();
-      compiler->AddPcRelativeCallStubTarget(stub);
 
       ASSERT(!locs()->live_registers()->ContainsRegister(R0));
-
       auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
-      compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
-                                     RawPcDescriptors::kOther, locs(),
-                                     extended_env);
+      compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                                 locs(), DeoptId::kNone, extended_env);
     } else {
       BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
                                       out, temp);
@@ -5466,50 +5349,6 @@
   __ BranchIf(EQUAL, slow_path->entry_label());
 }
 
-void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                           bool save_fpu_registers) {
-  auto check_null = instruction()->AsCheckNull();
-  auto locs = check_null->locs();
-  const bool using_shared_stub = locs->call_on_shared_slow_path();
-
-  const bool live_fpu_regs = locs->live_registers()->FpuRegisterCount() > 0;
-  auto object_store = compiler->isolate()->object_store();
-  const auto& stub = Code::ZoneHandle(
-      compiler->zone(),
-      live_fpu_regs ? object_store->null_error_stub_with_fpu_regs_stub()
-                    : object_store->null_error_stub_without_fpu_regs_stub());
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
-      using_shared_stub && !stub.InVMIsolateHeap()) {
-    compiler->assembler()->GenerateUnRelocatedPcRelativeCall();
-    compiler->AddPcRelativeCallStubTarget(stub);
-    return;
-  }
-
-  compiler->assembler()->CallNullErrorShared(save_fpu_registers);
-}
-
-void NullArgErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                              bool save_fpu_registers) {
-  auto check_null = instruction()->AsCheckNull();
-  auto locs = check_null->locs();
-
-  const bool live_fpu_regs = locs->live_registers()->FpuRegisterCount() > 0;
-  auto object_store = compiler->isolate()->object_store();
-  const auto& stub = Code::ZoneHandle(
-      compiler->zone(),
-      live_fpu_regs
-          ? object_store->null_arg_error_stub_with_fpu_regs_stub()
-          : object_store->null_arg_error_stub_without_fpu_regs_stub());
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
-      !stub.InVMIsolateHeap()) {
-    compiler->assembler()->GenerateUnRelocatedPcRelativeCall();
-    compiler->AddPcRelativeCallStubTarget(stub);
-    return;
-  }
-
-  compiler->assembler()->CallNullArgErrorShared(save_fpu_registers);
-}
-
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -5551,7 +5390,7 @@
   if (index_loc.IsConstant()) {
     const Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
-    __ CompareImmediate(length, reinterpret_cast<int64_t>(index.raw()));
+    __ CompareImmediate(length, static_cast<int64_t>(index.raw()));
     __ b(deopt, LS);
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
@@ -5563,7 +5402,7 @@
       __ tst(index, compiler::Operand(index));
       __ b(deopt, MI);
     } else {
-      __ CompareImmediate(index, reinterpret_cast<int64_t>(length.raw()));
+      __ CompareImmediate(index, static_cast<int64_t>(length.raw()));
       __ b(deopt, CS);
     }
   } else {
@@ -6359,44 +6198,6 @@
   }
 }
 
-LocationSummary* ThrowInstr::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));
-  return summary;
-}
-
-void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  __ Push(exception_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1,
-                                locs());
-  __ brk(0);
-}
-
-LocationSummary* ReThrowInstr::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::kCall);
-  summary->set_in(0, Location::RegisterLocation(R0));
-  summary->set_in(1, Location::RegisterLocation(R1));
-  return summary;
-}
-
-void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  const Register stacktrace_reg = locs()->in(1).reg();
-  compiler->SetNeedsStackTrace(catch_try_index());
-  __ Push(exception_reg);
-  __ Push(stacktrace_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry,
-                                2, locs());
-  __ brk(0);
-}
-
 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const {
   return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
 }
@@ -6430,7 +6231,7 @@
     }
     // Add a deoptimization descriptor for deoptimizing instructions that
     // may be inserted before this instruction.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -6506,47 +6307,20 @@
   return locs;
 }
 
-static Condition EmitComparisonCodeRegConstant(FlowGraphCompiler* compiler,
-                                               Token::Kind kind,
-                                               BranchLabels labels,
-                                               Register reg,
-                                               const Object& obj,
-                                               bool needs_number_check,
-                                               TokenPosition token_pos,
-                                               intptr_t deopt_id) {
-  Condition orig_cond = (kind == Token::kEQ_STRICT) ? EQ : NE;
-  if (!needs_number_check && compiler::target::IsSmi(obj) &&
+Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
+    FlowGraphCompiler* compiler,
+    BranchLabels labels,
+    Register reg,
+    const Object& obj) {
+  Condition orig_cond = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  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);
     return kInvalidCondition;
   } else {
-    Condition true_condition = compiler->EmitEqualityRegConstCompare(
-        reg, obj, needs_number_check, token_pos, deopt_id);
-    return (kind != Token::kEQ_STRICT) ? NegateCondition(true_condition)
-                                       : true_condition;
-  }
-}
-
-Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
-                                                 BranchLabels labels) {
-  Location left = locs()->in(0);
-  Location right = locs()->in(1);
-  ASSERT(!left.IsConstant() || !right.IsConstant());
-  Condition true_condition;
-  if (left.IsConstant()) {
-    return EmitComparisonCodeRegConstant(compiler, kind(), labels, right.reg(),
-                                         left.constant(), needs_number_check(),
-                                         token_pos(), deopt_id_);
-  } else if (right.IsConstant()) {
-    return EmitComparisonCodeRegConstant(compiler, kind(), labels, left.reg(),
-                                         right.constant(), needs_number_check(),
-                                         token_pos(), deopt_id_);
-  } else {
-    true_condition = compiler->EmitEqualityRegRegCompare(
-        left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
-    return (kind() != Token::kEQ_STRICT) ? NegateCondition(true_condition)
-                                         : true_condition;
+    return compiler->EmitEqualityRegConstCompare(reg, obj, needs_number_check(),
+                                                 token_pos(), deopt_id());
   }
 }
 
@@ -6585,13 +6359,19 @@
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register value = locs()->in(0).reg();
+  const Register input = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
 
-  __ LoadObject(result, Bool::True());
-  __ LoadObject(TMP, Bool::False());
-  __ CompareRegisters(result, value);
-  __ csel(result, TMP, result, EQ);
+  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);
+  }
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -6618,7 +6398,8 @@
   }
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
-  compiler->GenerateCall(token_pos(), stub, RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                             locs());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -6634,4 +6415,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
index 9901da4..98c044d 100644
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ b/runtime/vm/compiler/backend/il_deserializer.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/il_deserializer.h"
 
 #include "vm/compiler/backend/il_serializer.h"
@@ -800,10 +798,6 @@
 
   if (inst == nullptr) return nullptr;
   if (env != nullptr) env->DeepCopyTo(zone(), inst);
-  if (auto const lifetime_sexp =
-          CheckInteger(list->ExtraLookupValue("lifetime_position"))) {
-    inst->set_lifetime_position(lifetime_sexp->value());
-  }
   return inst;
 }
 
@@ -1019,10 +1013,10 @@
 DebugStepCheckInstr* FlowGraphDeserializer::DeserializeDebugStepCheck(
     SExpList* sexp,
     const InstrInfo& info) {
-  auto kind = RawPcDescriptors::kAnyKind;
+  auto kind = PcDescriptorsLayout::kAnyKind;
   if (auto const kind_sexp = CheckSymbol(Retrieve(sexp, "stub_kind"))) {
-    if (!RawPcDescriptors::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "not a valid RawPcDescriptors::Kind name");
+    if (!PcDescriptorsLayout::ParseKind(kind_sexp->value(), &kind)) {
+      StoreError(kind_sexp, "not a valid PcDescriptorsLayout::Kind name");
       return nullptr;
     }
   }
@@ -1044,9 +1038,14 @@
     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.
@@ -1054,6 +1053,8 @@
     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;
@@ -1077,7 +1078,7 @@
   auto const inst = new (zone()) InstanceCallInstr(
       info.token_pos, function_name, token_kind, call_info.inputs,
       call_info.type_args_len, call_info.argument_names, checked_arg_count,
-      info.deopt_id, interface_target);
+      info.deopt_id, interface_target, tearoff_interface_target);
 
   if (call_info.result_type != nullptr) {
     inst->SetResultType(zone(), *call_info.result_type);
@@ -1640,13 +1641,13 @@
   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"))) {
-    RawFunction::Kind kind;
-    if (!RawFunction::ParseKind(kind_sexp->value(), &kind)) {
+    FunctionLayout::Kind kind;
+    if (!FunctionLayout::ParseKind(kind_sexp->value(), &kind)) {
       StoreError(kind_sexp, "unexpected function kind");
       return false;
     }
     if (function.kind() != kind) {
-      auto const kind_str = RawFunction::KindToCString(function.kind());
+      auto const kind_str = FunctionLayout::KindToCString(function.kind());
       StoreError(list, "retrieved function has kind %s", kind_str);
       return false;
     }
@@ -2489,5 +2490,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/il_deserializer.h b/runtime/vm/compiler/backend/il_deserializer.h
index 9e8d40b..3959d37 100644
--- a/runtime/vm/compiler/backend/il_deserializer.h
+++ b/runtime/vm/compiler/backend/il_deserializer.h
@@ -5,6 +5,10 @@
 #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"
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 07851c4..addc43e 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -4,7 +4,7 @@
 
 #include "platform/globals.h"
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_IA32)
 
 #include "vm/compiler/backend/il.h"
 
@@ -140,7 +140,7 @@
   __ int3();
   __ Bind(&done);
 #endif
-  if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
     compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
   }
   __ LeaveFrame();
@@ -324,7 +324,7 @@
     } else {
       if (compiler::Assembler::IsSafeSmi(value_) || value_.IsNull()) {
         __ movl(LocationToStackSlotAddress(destination),
-                compiler::Immediate(reinterpret_cast<int32_t>(value_.raw())));
+                compiler::Immediate(static_cast<int32_t>(value_.raw())));
       } else {
         __ pushl(EAX);
         __ LoadObjectSafely(EAX, value_);
@@ -387,48 +387,6 @@
   return summary;
 }
 
-LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
-                                                         bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(EAX));
-  locs->set_out(0, Location::RegisterLocation(EAX));
-  return locs;
-}
-
-static void EmitAssertBoolean(Register reg,
-                              TokenPosition token_pos,
-                              intptr_t deopt_id,
-                              LocationSummary* locs,
-                              FlowGraphCompiler* compiler) {
-  // Check that the type of the value is allowed in conditional context.
-  // Call the runtime if the object is not bool::true or bool::false.
-  ASSERT(locs->always_calls());
-  compiler::Label done;
-
-  __ CompareObject(reg, Object::null_instance());
-  __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-
-  __ pushl(reg);  // Push the source object.
-  compiler->GenerateRuntimeCall(token_pos, deopt_id,
-                                kNonBoolTypeErrorRuntimeEntry, 1, locs);
-  // We should never return here.
-#if defined(DEBUG)
-  __ int3();
-#endif
-  __ Bind(&done);
-}
-
-void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register obj = locs()->in(0).reg();
-  Register result = locs()->out(0).reg();
-
-  EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
-  ASSERT(obj == result);
-}
-
 static Condition TokenKindToSmiCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -536,38 +494,6 @@
   }
 }
 
-static Condition NegateCondition(Condition condition) {
-  switch (condition) {
-    case EQUAL:
-      return NOT_EQUAL;
-    case NOT_EQUAL:
-      return EQUAL;
-    case LESS:
-      return GREATER_EQUAL;
-    case LESS_EQUAL:
-      return GREATER;
-    case GREATER:
-      return LESS_EQUAL;
-    case GREATER_EQUAL:
-      return LESS;
-    case BELOW:
-      return ABOVE_EQUAL;
-    case BELOW_EQUAL:
-      return ABOVE;
-    case ABOVE:
-      return BELOW_EQUAL;
-    case ABOVE_EQUAL:
-      return BELOW;
-    case PARITY_ODD:
-      return PARITY_EVEN;
-    case PARITY_EVEN:
-      return PARITY_ODD;
-    default:
-      UNIMPLEMENTED();
-      return EQUAL;
-  }
-}
-
 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
                                   Condition true_condition,
                                   BranchLabels labels) {
@@ -576,7 +502,7 @@
     __ j(true_condition, labels.true_label);
   } else {
     // If the next block is not the false successor, branch to it.
-    Condition false_condition = NegateCondition(true_condition);
+    Condition false_condition = InvertCondition(true_condition);
     __ j(false_condition, labels.false_label);
 
     // Fall through or jump to the true successor.
@@ -746,7 +672,7 @@
   compiler::Label is_true, is_false;
   BranchLabels labels = {&is_true, &is_false, &is_false};
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != INVALID_CONDITION) {
+  if (true_condition != kInvalidCondition) {
     EmitBranchOnCondition(compiler, true_condition, labels);
   }
 
@@ -764,7 +690,7 @@
                                      BranchInstr* branch) {
   BranchLabels labels = compiler->CreateBranchLabels(branch);
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != INVALID_CONDITION) {
+  if (true_condition != kInvalidCondition) {
     EmitBranchOnCondition(compiler, true_condition, labels);
   }
 }
@@ -787,7 +713,7 @@
   Location right = locs()->in(1);
   if (right.IsConstant()) {
     ASSERT(right.constant().IsSmi());
-    const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
+    const int32_t imm = static_cast<int32_t>(right.constant().raw());
     __ testl(left, compiler::Immediate(imm));
   } else {
     __ testl(left, right.reg());
@@ -848,7 +774,7 @@
   }
   // Dummy result as this method already did the jump, there's no need
   // for the caller to branch on a condition.
-  return INVALID_CONDITION;
+  return kInvalidCondition;
 }
 
 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
@@ -930,7 +856,8 @@
   const compiler::ExternalLabel label(
       reinterpret_cast<uword>(native_c_function()));
   __ movl(ECX, compiler::Immediate(label.address()));
-  compiler->GenerateCall(token_pos(), *stub, RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
+                             locs());
 
   __ popl(result);
 
@@ -966,7 +893,7 @@
   compiler::Label get_pc;
   __ call(&get_pc);
   compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
-                                 RawPcDescriptors::Kind::kOther, locs());
+                                 PcDescriptorsLayout::Kind::kOther, locs());
   __ Bind(&get_pc);
   __ popl(temp);
   __ movl(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), temp);
@@ -1802,14 +1729,17 @@
           __ cmpl(value_cid_reg, compiler::Immediate(kNullCid));
         } else {
           const compiler::Immediate& raw_null =
-              compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+              compiler::Immediate(static_cast<intptr_t>(Object::null()));
           __ cmpl(value_reg, raw_null);
         }
       }
       __ j(NOT_EQUAL, fail);
+    } else if (value_cid == field_cid) {
+      // This would normaly be caught by Canonicalize, but RemoveRedefinitions
+      // may sometimes produce the situation after the last Canonicalize pass.
     } else {
       // Both value's and field's class id is known.
-      ASSERT((value_cid != field_cid) && (value_cid != nullability));
+      ASSERT(value_cid != nullability);
       __ jmp(fail);
     }
   }
@@ -1922,8 +1852,8 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(TokenPosition::kNoSource, stub,
-                           RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(TokenPosition::kNoSource, stub,
+                               PcDescriptorsLayout::kOther, locs);
     __ MoveRegister(result_, EAX);
     compiler->RestoreLiveRegisters(locs);
     __ jmp(exit_label());
@@ -1994,7 +1924,7 @@
                              Register temp) {
   compiler::Label done;
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      compiler::Immediate(static_cast<intptr_t>(Object::null()));
   __ movl(box_reg, compiler::FieldAddress(instance_reg, offset));
   __ cmpl(box_reg, raw_null);
   __ j(NOT_EQUAL, &done);
@@ -2297,10 +2227,10 @@
   // EDI: iterator which initially points to the start of the variable
   // data area to be initialized.
   if (num_elements > 0) {
-    const intptr_t array_size = instance_size - sizeof(RawArray);
+    const intptr_t array_size = instance_size - sizeof(ArrayLayout);
     const compiler::Immediate& raw_null =
-        compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ leal(EDI, compiler::FieldAddress(EAX, sizeof(RawArray)));
+        compiler::Immediate(static_cast<intptr_t>(Object::null()));
+    __ leal(EDI, compiler::FieldAddress(EAX, sizeof(ArrayLayout)));
     if (array_size < (kInlineArraySize * kWordSize)) {
       intptr_t current_offset = 0;
       __ movl(EBX, raw_null);
@@ -2351,9 +2281,8 @@
   }
 
   __ Bind(&slow_path);
-  compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
-                                  StubCode::AllocateArray(),
-                                  RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), StubCode::AllocateArray(),
+                             PcDescriptorsLayout::kOther, locs(), deopt_id());
   __ Bind(&done);
   ASSERT(locs()->out(0).reg() == kResultReg);
 }
@@ -2564,8 +2493,8 @@
   // Lookup cache in stub before calling runtime.
   __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
                 type_arguments());
-  compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
-                         locs());
+  compiler->GenerateStubCall(token_pos(), GetStub(),
+                             PcDescriptorsLayout::kOther, locs());
   __ Bind(&type_arguments_instantiated);
 }
 
@@ -2600,9 +2529,9 @@
     compiler->SaveLiveRegisters(locs);
 
     __ movl(EDX, compiler::Immediate(instruction()->num_context_variables()));
-    compiler->GenerateCall(instruction()->token_pos(),
-                           StubCode::AllocateContext(),
-                           RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(instruction()->token_pos(),
+                               StubCode::AllocateContext(),
+                               PcDescriptorsLayout::kOther, locs);
     ASSERT(instruction()->locs()->out(0).reg() == EAX);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ jmp(exit_label());
@@ -2649,38 +2578,8 @@
   ASSERT(locs()->out(0).reg() == EAX);
 
   __ movl(EDX, compiler::Immediate(num_context_variables()));
-  compiler->GenerateCall(token_pos(), StubCode::AllocateContext(),
-                         RawPcDescriptors::kOther, locs());
-}
-
-LocationSummary* InitInstanceFieldInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(EAX));
-  locs->set_temp(0, Location::RegisterLocation(ECX));
-  return locs;
-}
-
-void InitInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register instance = locs()->in(0).reg();
-  Register temp = locs()->temp(0).reg();
-
-  compiler::Label no_call;
-
-  __ movl(temp, compiler::FieldAddress(instance, field().TargetOffset()));
-  __ CompareObject(temp, Object::sentinel());
-  __ j(NOT_EQUAL, &no_call, compiler::Assembler::kNearJump);
-
-  __ pushl(compiler::Immediate(0));  // Make room for (unused) result.
-  __ pushl(instance);
-  __ PushObject(Field::ZoneHandle(field().Original()));
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
-                                kInitInstanceFieldRuntimeEntry, 2, locs());
-  __ Drop(3);  // Remove arguments and unused result.
-  __ Bind(&no_call);
+  compiler->GenerateStubCall(token_pos(), StubCode::AllocateContext(),
+                             PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -2698,8 +2597,8 @@
   ASSERT(locs()->in(0).reg() == ECX);
   ASSERT(locs()->out(0).reg() == EAX);
 
-  compiler->GenerateCall(token_pos(), StubCode::CloneContext(),
-                         /*kind=*/RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), StubCode::CloneContext(),
+                             /*kind=*/PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -2720,7 +2619,7 @@
     if (compiler->is_optimizing()) {
       compiler->AddDeoptIndexAtCall(deopt_id);
     } else {
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
                                      TokenPosition::kNoSource);
     }
   }
@@ -2794,7 +2693,7 @@
     if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
         instruction()->in_loop()) {
       // In unoptimized code, record loop stack checks as possible OSR entries.
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
                                      instruction()->deopt_id(),
                                      TokenPosition::kNoSource);
     }
@@ -2894,8 +2793,8 @@
       const bool right_needs_check =
           !RangeUtils::IsWithin(right_range, 0, max_right - 1);
       if (right_needs_check) {
-        __ cmpl(right, compiler::Immediate(
-                           reinterpret_cast<int32_t>(Smi::New(max_right))));
+        __ cmpl(right,
+                compiler::Immediate(static_cast<int32_t>(Smi::New(max_right))));
         __ j(ABOVE_EQUAL, deopt);
       }
       __ SmiUntag(right);
@@ -2915,8 +2814,8 @@
         __ j(NEGATIVE, deopt);
       }
       compiler::Label done, is_not_zero;
-      __ cmpl(right, compiler::Immediate(
-                         reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
+      __ cmpl(right,
+              compiler::Immediate(static_cast<int32_t>(Smi::New(Smi::kBits))));
       __ j(BELOW, &is_not_zero, compiler::Assembler::kNearJump);
       __ xorl(left, left);
       __ jmp(&done, compiler::Assembler::kNearJump);
@@ -2931,8 +2830,8 @@
   } else {
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
-      __ cmpl(right, compiler::Immediate(
-                         reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
+      __ cmpl(right,
+              compiler::Immediate(static_cast<int32_t>(Smi::New(Smi::kBits))));
       __ j(ABOVE_EQUAL, deopt);
     }
     // Left is not a constant.
@@ -5261,7 +5160,7 @@
 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler,
                                     compiler::Label* deopt) {
   const compiler::Immediate& raw_null =
-      compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      compiler::Immediate(static_cast<intptr_t>(Object::null()));
   __ cmpl(locs()->in(0).reg(), raw_null);
   ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
   Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL;
@@ -5353,18 +5252,6 @@
   __ BranchIf(EQUAL, slow_path->entry_label());
 }
 
-void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                           bool save_fpu_registers) {
-  // We only generate shared spilling stub calls for AOT configurations.
-  UNREACHABLE();
-}
-
-void NullArgErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                              bool save_fpu_registers) {
-  // We only generate shared spilling stub calls for AOT configurations.
-  UNREACHABLE();
-}
-
 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -5438,20 +5325,17 @@
       __ testl(index, index);
       __ j(NEGATIVE, deopt);
     } else {
-      __ cmpl(index,
-              compiler::Immediate(reinterpret_cast<int32_t>(length.raw())));
+      __ cmpl(index, compiler::Immediate(static_cast<int32_t>(length.raw())));
       __ j(ABOVE_EQUAL, deopt);
     }
   } else if (index_loc.IsConstant()) {
     const Smi& index = Smi::Cast(index_loc.constant());
     if (length_loc.IsStackSlot()) {
       const compiler::Address& length = LocationToStackSlotAddress(length_loc);
-      __ cmpl(length,
-              compiler::Immediate(reinterpret_cast<int32_t>(index.raw())));
+      __ cmpl(length, compiler::Immediate(static_cast<int32_t>(index.raw())));
     } else {
       Register length = length_loc.reg();
-      __ cmpl(length,
-              compiler::Immediate(reinterpret_cast<int32_t>(index.raw())));
+      __ cmpl(length, compiler::Immediate(static_cast<int32_t>(index.raw())));
     }
     __ j(BELOW_EQUAL, deopt);
   } else if (length_loc.IsStackSlot()) {
@@ -6164,44 +6048,6 @@
   }
 }
 
-LocationSummary* ThrowInstr::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(EAX));
-  return summary;
-}
-
-void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  __ pushl(exception_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1,
-                                locs());
-  __ int3();
-}
-
-LocationSummary* ReThrowInstr::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::kCall);
-  summary->set_in(0, Location::RegisterLocation(EAX));
-  summary->set_in(1, Location::RegisterLocation(EDX));
-  return summary;
-}
-
-void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  const Register stacktrace_reg = locs()->in(1).reg();
-  compiler->SetNeedsStackTrace(catch_try_index());
-  __ pushl(exception_reg);
-  __ pushl(stacktrace_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry,
-                                2, locs());
-  __ int3();
-}
-
 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const {
   return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
 }
@@ -6235,7 +6081,7 @@
     }
     // Add a deoptimization descriptor for deoptimizing instructions that
     // may be inserted before this instruction.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -6312,29 +6158,13 @@
   return locs;
 }
 
-Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
-                                                 BranchLabels labels) {
-  Location left = locs()->in(0);
-  Location right = locs()->in(1);
-  ASSERT(!left.IsConstant() || !right.IsConstant());
-  Condition true_condition;
-  if (left.IsConstant()) {
-    true_condition = compiler->EmitEqualityRegConstCompare(
-        right.reg(), left.constant(), needs_number_check(), token_pos(),
-        deopt_id_);
-  } else if (right.IsConstant()) {
-    true_condition = compiler->EmitEqualityRegConstCompare(
-        left.reg(), right.constant(), needs_number_check(), token_pos(),
-        deopt_id_);
-  } else {
-    true_condition = compiler->EmitEqualityRegRegCompare(
-        left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
-  }
-  if (kind() != Token::kEQ_STRICT) {
-    ASSERT(kind() == Token::kNE_STRICT);
-    true_condition = NegateCondition(true_condition);
-  }
-  return true_condition;
+Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
+    FlowGraphCompiler* compiler,
+    BranchLabels labels,
+    Register reg,
+    const Object& obj) {
+  return compiler->EmitEqualityRegConstCompare(reg, obj, needs_number_check(),
+                                               token_pos(), deopt_id());
 }
 
 // Detect pattern when one value is zero and another is a power of 2.
@@ -6364,7 +6194,7 @@
   // the labels or returning an invalid condition.
   BranchLabels labels = {NULL, NULL, NULL};
   Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != INVALID_CONDITION);
+  ASSERT(true_condition != kInvalidCondition);
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
@@ -6374,7 +6204,7 @@
   if (is_power_of_two_kind) {
     if (true_value == 0) {
       // We need to have zero in EDX on true_condition.
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   } else {
     if (true_value == 0) {
@@ -6383,7 +6213,7 @@
       true_value = false_value;
       false_value = temp;
     } else {
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   }
 
@@ -6439,26 +6269,36 @@
   __ xorl(ECX, ECX);
   __ call(EBX);
   compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
-                                 RawPcDescriptors::kOther, locs());
+                                 PcDescriptorsLayout::kOther, locs());
   __ Drop(argument_count);
 }
 
 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
-  return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
+  return LocationSummary::Make(zone, 1,
+                               value()->Type()->ToCid() == kBoolCid
+                                   ? Location::SameAsFirstInput()
+                                   : Location::RequiresRegister(),
                                LocationSummary::kNoCall);
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register value = locs()->in(0).reg();
+  Register input = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
 
-  compiler::Label done;
-  __ LoadObject(result, Bool::True());
-  __ CompareRegisters(result, value);
-  __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-  __ LoadObject(result, Bool::False());
-  __ Bind(&done);
+  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);
+  }
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -6478,7 +6318,8 @@
 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
-  compiler->GenerateCall(token_pos(), stub, RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                             locs());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -6496,4 +6337,4 @@
 
 #undef __
 
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 7903b2e..83dda2b 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -4,7 +4,9 @@
 
 #include "vm/compiler/backend/il_printer.h"
 
+#include "vm/compiler/api/print_filter.h"
 #include "vm/compiler/backend/il.h"
+#include "vm/compiler/backend/linearscan.h"
 #include "vm/compiler/backend/range_analysis.h"
 #include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/os.h"
@@ -14,60 +16,6 @@
 
 #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
 
-DEFINE_FLAG(charp,
-            print_flow_graph_filter,
-            NULL,
-            "Print only IR of functions with matching names");
-
-// Checks whether function's name matches the given filter, which is
-// a comma-separated list of strings.
-bool FlowGraphPrinter::PassesFilter(const char* filter,
-                                    const Function& function) {
-  if (filter == NULL) {
-    return true;
-  }
-
-  char* save_ptr;  // Needed for strtok_r.
-  const char* scrubbed_name =
-      String::Handle(function.QualifiedScrubbedName()).ToCString();
-  const char* function_name = function.ToFullyQualifiedCString();
-  intptr_t function_name_len = strlen(function_name);
-
-  intptr_t len = strlen(filter) + 1;  // Length with \0.
-  char* filter_buffer = new char[len];
-  strncpy(filter_buffer, filter, len);  // strtok modifies arg 1.
-  char* token = strtok_r(filter_buffer, ",", &save_ptr);
-  bool found = false;
-  while (token != NULL) {
-    if ((strstr(function_name, token) != NULL) ||
-        (strstr(scrubbed_name, token) != NULL)) {
-      found = true;
-      break;
-    }
-    const intptr_t token_len = strlen(token);
-    if (token[token_len - 1] == '%') {
-      if (function_name_len > token_len) {
-        const char* suffix =
-            function_name + (function_name_len - token_len + 1);
-        if (strncmp(suffix, token, token_len - 1) == 0) {
-          found = true;
-          break;
-        }
-      }
-    }
-    token = strtok_r(NULL, ",", &save_ptr);
-  }
-  delete[] filter_buffer;
-
-  return found;
-}
-
-bool FlowGraphPrinter::ShouldPrint(const Function& function) {
-  return PassesFilter(FLAG_print_flow_graph_filter, function);
-}
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 DEFINE_FLAG(bool,
             display_sorted_ic_data,
             false,
@@ -76,6 +24,10 @@
 
 DECLARE_FLAG(bool, trace_inlining_intervals);
 
+bool FlowGraphPrinter::ShouldPrint(const Function& function) {
+  return compiler::PrintFilter::ShouldPrint(function);
+}
+
 void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
   LogBlock lb;
   THR_Print("*** BEGIN CFG\n%s\n", phase);
@@ -123,8 +75,8 @@
   if (print_locations && (instr->HasLocs())) {
     instr->locs()->PrintTo(&f);
   }
-  if (instr->lifetime_position() != -1) {
-    THR_Print("%3" Pd ": ", instr->lifetime_position());
+  if (FlowGraphAllocator::HasLifetimePosition(instr)) {
+    THR_Print("%3" Pd ": ", FlowGraphAllocator::GetLifetimePosition(instr));
   }
   if (!instr->IsBlockEntry()) THR_Print("    ");
   THR_Print("%s", str);
@@ -1073,7 +1025,7 @@
 
 void ReturnInstr::PrintOperandsTo(BufferFormatter* f) const {
   Instruction::PrintOperandsTo(f);
-  if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
     f->Print(", yield_index = %" Pd "", yield_index());
   }
 }
@@ -1224,12 +1176,8 @@
   return Thread::Current()->zone()->MakeCopyOfString(buffer);
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 #else  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 const char* Instruction::ToCString() const {
   return DebugName();
 }
@@ -1266,8 +1214,6 @@
   return false;
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 #endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_printer.h b/runtime/vm/compiler/backend/il_printer.h
index 32cc84a..96268c8 100644
--- a/runtime/vm/compiler/backend/il_printer.h
+++ b/runtime/vm/compiler/backend/il_printer.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_IL_PRINTER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_IL_PRINTER_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/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
@@ -54,8 +58,6 @@
 
   static bool ShouldPrint(const Function& function);
 
-  static bool PassesFilter(const char* filter, const Function& function);
-
  private:
   const Function& function_;
   const GrowableArray<BlockEntryInstr*>& block_order_;
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index f2e5cf9..3708c8f 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/il_serializer.h"
 
 #include "vm/compiler/backend/flow_graph.h"
@@ -590,9 +588,9 @@
       AddExtraSymbol(sexp, "native_name", tmp_string_.ToCString());
     }
   }
-  if (func.kind() != RawFunction::Kind::kRegularFunction ||
+  if (func.kind() != FunctionLayout::Kind::kRegularFunction ||
       FLAG_verbose_flow_graph_serialization) {
-    AddExtraSymbol(sexp, "kind", RawFunction::KindToCString(func.kind()));
+    AddExtraSymbol(sexp, "kind", FunctionLayout::KindToCString(func.kind()));
   }
   function_type_args_ = func.type_parameters();
   if (auto const ta_sexp = NonEmptyTypeArgumentsToSExp(function_type_args_)) {
@@ -835,9 +833,6 @@
   if (!token_pos().IsNoSource()) {
     s->AddExtraInteger(sexp, "token_pos", token_pos().value());
   }
-  if (lifetime_position() != kNoPlaceId) {
-    s->AddExtraInteger(sexp, "lifetime_position", lifetime_position());
-  }
 }
 
 SExpression* Range::ToSExpression(FlowGraphSerializer* s) {
@@ -1066,9 +1061,9 @@
     SExpList* sexp,
     FlowGraphSerializer* s) const {
   Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (stub_kind_ != RawPcDescriptors::kAnyKind ||
+  if (stub_kind_ != PcDescriptorsLayout::kAnyKind ||
       FLAG_verbose_flow_graph_serialization) {
-    auto const stub_kind_name = RawPcDescriptors::KindToCString(stub_kind_);
+    auto const stub_kind_name = PcDescriptorsLayout::KindToCString(stub_kind_);
     ASSERT(stub_kind_name != nullptr);
     s->AddExtraSymbol(sexp, "stub_kind", stub_kind_name);
   }
@@ -1232,17 +1227,22 @@
     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()) {
+    if (!interface_target().IsNull() || !tearoff_interface_target().IsNull()) {
       s->AddExtraSymbol(sexp, "function_name", "null");
     }
   } else {
     if (interface_target().IsNull() ||
-        function_name().raw() != interface_target().name()) {
+        (function_name().raw() != interface_target().name() &&
+         function_name().raw() != tearoff_interface_target().name())) {
       s->AddExtraString(sexp, "function_name", function_name().ToCString());
     }
   }
@@ -1487,5 +1487,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
index 0e02cd2..8a65fad3 100644
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ b/runtime/vm/compiler/backend/il_serializer.h
@@ -5,6 +5,10 @@
 #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"
 
@@ -144,7 +148,7 @@
       return a.raw() == b.raw();
     }
     static uword Hash(const Object& obj) {
-      if (obj.IsSmi()) return reinterpret_cast<uword>(obj.raw());
+      if (obj.IsSmi()) return static_cast<uword>(obj.raw());
       if (obj.IsInstance()) return Instance::Cast(obj).CanonicalizeHash();
       return obj.GetClassId();
     }
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index f689b65..3148b0d 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -21,9 +21,11 @@
 
 namespace dart {
 
-RawLibrary* LoadTestScript(const char* script,
-                           Dart_NativeEntryResolver resolver,
-                           const char* lib_uri) {
+Definition* const FlowGraphBuilderHelper::kPhiSelfReference = nullptr;
+
+LibraryPtr LoadTestScript(const char* script,
+                          Dart_NativeEntryResolver resolver,
+                          const char* lib_uri) {
   Dart_Handle api_lib;
   {
     TransitionVMToNative transition(Thread::Current());
@@ -36,7 +38,7 @@
   return lib.raw();
 }
 
-RawFunction* GetFunction(const Library& lib, const char* name) {
+FunctionPtr GetFunction(const Library& lib, const char* name) {
   Thread* thread = Thread::Current();
   const auto& func = Function::Handle(lib.LookupFunctionAllowPrivate(
       String::Handle(Symbols::New(thread, name))));
@@ -44,7 +46,7 @@
   return func.raw();
 }
 
-RawClass* GetClass(const Library& lib, const char* name) {
+ClassPtr GetClass(const Library& lib, const char* name) {
   Thread* thread = Thread::Current();
   const auto& cls = Class::Handle(
       lib.LookupClassAllowPrivate(String::Handle(Symbols::New(thread, name))));
@@ -52,15 +54,15 @@
   return cls.raw();
 }
 
-RawTypeParameter* GetClassTypeParameter(const Class& klass, const char* name) {
+TypeParameterPtr GetClassTypeParameter(const Class& klass, const char* name) {
   const auto& param = TypeParameter::Handle(
       klass.LookupTypeParameter(String::Handle(String::New(name))));
   EXPECT(!param.IsNull());
   return param.raw();
 }
 
-RawTypeParameter* GetFunctionTypeParameter(const Function& fun,
-                                           const char* name) {
+TypeParameterPtr GetFunctionTypeParameter(const Function& fun,
+                                          const char* name) {
   intptr_t fun_level = 0;
   const auto& param = TypeParameter::Handle(
       fun.LookupTypeParameter(String::Handle(String::New(name)), &fun_level));
@@ -68,7 +70,7 @@
   return param.raw();
 }
 
-RawObject* Invoke(const Library& lib, const char* name) {
+ObjectPtr Invoke(const Library& lib, const char* name) {
   // These tests rely on running unoptimized code to collect type feedback. The
   // interpreter does not collect type feedback for interface calls, so set
   // compilation threshold to 0 in order to compile invoked function
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 9655791..1d8a121 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -50,20 +50,18 @@
 class FlowGraph;
 class Function;
 class Library;
-class RawFunction;
-class RawLibrary;
 
-RawLibrary* LoadTestScript(const char* script,
-                           Dart_NativeEntryResolver resolver = nullptr,
-                           const char* lib_uri = RESOLVED_USER_TEST_URI);
+LibraryPtr LoadTestScript(const char* script,
+                          Dart_NativeEntryResolver resolver = nullptr,
+                          const char* lib_uri = RESOLVED_USER_TEST_URI);
 
-RawFunction* GetFunction(const Library& lib, const char* name);
-RawClass* GetClass(const Library& lib, const char* name);
-RawTypeParameter* GetClassTypeParameter(const Class& klass, const char* name);
-RawTypeParameter* GetFunctionTypeParameter(const Function& fun,
-                                           const char* name);
+FunctionPtr GetFunction(const Library& lib, const char* name);
+ClassPtr GetClass(const Library& lib, const char* name);
+TypeParameterPtr GetClassTypeParameter(const Class& klass, const char* name);
+TypeParameterPtr GetFunctionTypeParameter(const Function& fun,
+                                          const char* name);
 
-RawObject* Invoke(const Library& lib, const char* name);
+ObjectPtr Invoke(const Library& lib, const char* name);
 
 class TestPipeline : public ValueObject {
  public:
@@ -253,17 +251,20 @@
     return flow_graph_.GetConstant(Double::Handle(Double::NewCanonical(value)));
   }
 
+  static Definition* const kPhiSelfReference;
+
   PhiInstr* Phi(JoinEntryInstr* join,
                 std::initializer_list<std::pair<BlockEntryInstr*, Definition*>>
-                    incomming) {
-    auto phi = new PhiInstr(join, incomming.size());
-    for (size_t i = 0; i < incomming.size(); i++) {
+                    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 : incomming) {
-      pending_phis_.Add({phi, pair.first, pair.second});
+    for (auto pair : incoming) {
+      pending_phis_.Add({phi, pair.first,
+                         pair.second == kPhiSelfReference ? phi : pair.second});
     }
     return phi;
   }
@@ -288,7 +289,7 @@
   static FlowGraph& MakeDummyGraph(Thread* thread) {
     const Function& func = Function::ZoneHandle(Function::New(
         String::Handle(Symbols::New(thread, "dummy")),
-        RawFunction::kRegularFunction,
+        FunctionLayout::kRegularFunction,
         /*is_static=*/true,
         /*is_const=*/false,
         /*is_abstract=*/false,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index ddb0a2f..19ddebf 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_X64)
 
 #include "vm/compiler/backend/il.h"
 
@@ -118,9 +118,7 @@
 }
 
 DEFINE_BACKEND(TailCall, (NoLocation, Fixed<Register, ARGS_DESC_REG>)) {
-  __ LoadObject(CODE_REG, instr->code());
-  __ LeaveDartFrame();  // The arguments are still on the stack.
-  __ jmp(compiler::FieldAddress(CODE_REG, Code::entry_point_offset()));
+  compiler->EmitTailCallToStub(instr->code());
 
   // Even though the TailCallInstr will be the last instruction in a basic
   // block, the flow graph compiler will emit native code for other blocks after
@@ -221,7 +219,7 @@
   __ Bind(&done);
 #endif
   ASSERT(__ constant_pool_allowed());
-  if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
     compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
   }
   __ LeaveDartFrame();  // Disallows constant pool use.
@@ -280,38 +278,6 @@
   __ set_constant_pool_allowed(true);
 }
 
-static Condition NegateCondition(Condition condition) {
-  switch (condition) {
-    case EQUAL:
-      return NOT_EQUAL;
-    case NOT_EQUAL:
-      return EQUAL;
-    case LESS:
-      return GREATER_EQUAL;
-    case LESS_EQUAL:
-      return GREATER;
-    case GREATER:
-      return LESS_EQUAL;
-    case GREATER_EQUAL:
-      return LESS;
-    case BELOW:
-      return ABOVE_EQUAL;
-    case BELOW_EQUAL:
-      return ABOVE;
-    case ABOVE:
-      return BELOW_EQUAL;
-    case ABOVE_EQUAL:
-      return BELOW;
-    case PARITY_EVEN:
-      return PARITY_ODD;
-    case PARITY_ODD:
-      return PARITY_EVEN;
-    default:
-      UNIMPLEMENTED();
-      return EQUAL;
-  }
-}
-
 // Detect pattern when one value is zero and another is a power of 2.
 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
   return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
@@ -339,7 +305,7 @@
   // the labels or returning an invalid condition.
   BranchLabels labels = {NULL, NULL, NULL};
   Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != INVALID_CONDITION);
+  ASSERT(true_condition != kInvalidCondition);
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
@@ -349,7 +315,7 @@
   if (is_power_of_two_kind) {
     if (true_value == 0) {
       // We need to have zero in RDX on true_condition.
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   } else {
     if (true_value == 0) {
@@ -358,7 +324,7 @@
       true_value = false_value;
       false_value = temp;
     } else {
-      true_condition = NegateCondition(true_condition);
+      true_condition = InvertCondition(true_condition);
     }
   }
 
@@ -587,48 +553,6 @@
   return summary;
 }
 
-LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
-                                                         bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(RAX));
-  locs->set_out(0, Location::RegisterLocation(RAX));
-  return locs;
-}
-
-static void EmitAssertBoolean(Register reg,
-                              TokenPosition token_pos,
-                              intptr_t deopt_id,
-                              LocationSummary* locs,
-                              FlowGraphCompiler* compiler) {
-  // Check that the type of the value is allowed in conditional context.
-  // Call the runtime if the object is not bool::true or bool::false.
-  ASSERT(locs->always_calls());
-  compiler::Label done;
-
-  __ CompareObject(reg, Object::null_instance());
-  __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-
-  __ pushq(reg);  // Push the source object.
-  compiler->GenerateRuntimeCall(token_pos, deopt_id,
-                                kNonBoolTypeErrorRuntimeEntry, 1, locs);
-  // We should never return here.
-#if defined(DEBUG)
-  __ int3();
-#endif
-  __ Bind(&done);
-}
-
-void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register obj = locs()->in(0).reg();
-  Register result = locs()->out(0).reg();
-
-  EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
-  ASSERT(obj == result);
-}
-
 static Condition TokenKindToIntCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -733,7 +657,7 @@
     __ j(true_condition, labels.true_label);
   } else {
     // If the next block is not the false successor, branch to it.
-    Condition false_condition = NegateCondition(true_condition);
+    Condition false_condition = InvertCondition(true_condition);
     __ j(false_condition, labels.false_label);
 
     // Fall through or jump to the true successor.
@@ -830,7 +754,7 @@
   compiler::Label is_true, is_false;
   BranchLabels labels = {&is_true, &is_false, &is_false};
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != INVALID_CONDITION) {
+  if (true_condition != kInvalidCondition) {
     EmitBranchOnCondition(compiler, true_condition, labels);
   }
 
@@ -848,7 +772,7 @@
                                      BranchInstr* branch) {
   BranchLabels labels = compiler->CreateBranchLabels(branch);
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != INVALID_CONDITION) {
+  if (true_condition != kInvalidCondition) {
     EmitBranchOnCondition(compiler, true_condition, labels);
   }
 }
@@ -871,7 +795,7 @@
   Location right = locs()->in(1);
   if (right.IsConstant()) {
     ASSERT(right.constant().IsSmi());
-    const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw());
+    const int64_t imm = static_cast<int64_t>(right.constant().raw());
     __ TestImmediate(left_reg, compiler::Immediate(imm));
   } else {
     __ testq(left_reg, right.reg());
@@ -932,7 +856,7 @@
   }
   // Dummy result as this method already did the jump, there's no need
   // for the caller to branch on a condition.
-  return INVALID_CONDITION;
+  return kInvalidCondition;
 }
 
 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
@@ -996,7 +920,7 @@
     __ LoadNativeEntry(RBX, &label,
                        compiler::ObjectPoolBuilderEntry::kPatchable);
     compiler->GeneratePatchableCall(token_pos(), *stub,
-                                    RawPcDescriptors::kOther, locs());
+                                    PcDescriptorsLayout::kOther, locs());
   } else {
     if (is_bootstrap_native()) {
       stub = &StubCode::CallBootstrapNative();
@@ -1009,8 +933,8 @@
         reinterpret_cast<uword>(native_c_function()));
     __ LoadNativeEntry(RBX, &label,
                        compiler::ObjectPoolBuilderEntry::kNotPatchable);
-    compiler->GenerateCall(token_pos(), *stub, RawPcDescriptors::kOther,
-                           locs());
+    compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
+                               locs());
   }
   __ popq(result);
 
@@ -1047,7 +971,7 @@
   // 'movq'.
   __ leaq(TMP, compiler::Address::AddressRIPRelative(0));
   compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
-                                 RawPcDescriptors::Kind::kOther, locs());
+                                 PcDescriptorsLayout::Kind::kOther, locs());
   __ movq(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), TMP);
 
   if (CanExecuteGeneratedCodeInSafepoint()) {
@@ -1146,28 +1070,8 @@
 
   // Load the address of DLRT_GetThreadForNativeCallback without using Thread.
   if (FLAG_precompiled_mode) {
-    compiler::Label skip_reloc;
-    __ jmp(&skip_reloc);
-    compiler->InsertBSSRelocation(
-        BSS::Relocation::DRT_GetThreadForNativeCallback);
-    const intptr_t reloc_end = __ CodeSize();
-    __ Bind(&skip_reloc);
-
-    const intptr_t kLeaqLength = 7;
-    __ leaq(RAX, compiler::Address::AddressRIPRelative(
-                     -kLeaqLength - compiler::target::kWordSize));
-    ASSERT((__ CodeSize() - reloc_end) == kLeaqLength);
-
-    // RAX holds the address of the relocation.
-    __ movq(RCX, compiler::Address(RAX, 0));
-
-    // RCX holds the relocation itself: RAX - bss_start.
-    // RAX = RAX + (bss_start - RAX) = bss_start
-    __ addq(RAX, RCX);
-
-    // RAX holds the start of the BSS section.
-    // Load the "get-thread" routine: *bss_start.
-    __ movq(RAX, compiler::Address(RAX, 0));
+    compiler->LoadBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback, RAX,
+                           RCX);
   } else if (!NativeCallbackTrampolines::Enabled()) {
     // In JIT mode, we can just paste the address of the runtime entry into the
     // generated code directly. This is not a problem since we don't save
@@ -1376,8 +1280,8 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
-                           stub, RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(TokenPosition::kNoSource,  // No token position.
+                               stub, PcDescriptorsLayout::kOther, locs);
     __ MoveRegister(result_, RAX);
     compiler->RestoreLiveRegisters(locs);
     __ jmp(exit_label());
@@ -2004,9 +1908,12 @@
       }
 
       __ j(NOT_EQUAL, fail);
+    } else if (value_cid == field_cid) {
+      // This would normaly be caught by Canonicalize, but RemoveRedefinitions
+      // may sometimes produce the situation after the last Canonicalize pass.
     } else {
       // Both value's and field's class id is known.
-      ASSERT((value_cid != field_cid) && (value_cid != nullability));
+      ASSERT(value_cid != nullability);
       __ jmp(fail);
     }
   }
@@ -2558,9 +2465,9 @@
   // RDI: iterator which initially points to the start of the variable
   // data area to be initialized.
   if (num_elements > 0) {
-    const intptr_t array_size = instance_size - sizeof(RawArray);
+    const intptr_t array_size = instance_size - sizeof(ArrayLayout);
     __ LoadObject(R12, Object::null_object());
-    __ leaq(RDI, compiler::FieldAddress(RAX, sizeof(RawArray)));
+    __ leaq(RDI, compiler::FieldAddress(RAX, sizeof(ArrayLayout)));
     if (array_size < (kInlineArraySize * kWordSize)) {
       intptr_t current_offset = 0;
       while (current_offset < array_size) {
@@ -2618,9 +2525,11 @@
   }
 
   __ Bind(&slow_path);
-  compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
-                                  StubCode::AllocateArray(),
-                                  RawPcDescriptors::kOther, locs());
+  auto object_store = compiler->isolate()->object_store();
+  const auto& allocate_array_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->allocate_array_stub());
+  compiler->GenerateStubCall(token_pos(), allocate_array_stub,
+                             PcDescriptorsLayout::kOther, locs(), deopt_id());
   __ Bind(&done);
   ASSERT(locs()->out(0).reg() == kResultReg);
 }
@@ -2871,8 +2780,8 @@
   }
   __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
                 type_arguments());
-  compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
-                         locs());
+  compiler->GenerateStubCall(token_pos(), GetStub(),
+                             PcDescriptorsLayout::kOther, locs());
   __ Bind(&type_arguments_instantiated);
 }
 
@@ -2906,11 +2815,15 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto object_store = compiler->isolate()->object_store();
+    const auto& allocate_context_stub = Code::ZoneHandle(
+        compiler->zone(), object_store->allocate_context_stub());
+
     __ LoadImmediate(
         R10, compiler::Immediate(instruction()->num_context_variables()));
-    compiler->GenerateCall(instruction()->token_pos(),
-                           StubCode::AllocateContext(),
-                           RawPcDescriptors::kOther, locs);
+    compiler->GenerateStubCall(instruction()->token_pos(),
+                               allocate_context_stub,
+                               PcDescriptorsLayout::kOther, locs);
     ASSERT(instruction()->locs()->out(0).reg() == RAX);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ jmp(exit_label());
@@ -2955,39 +2868,13 @@
   ASSERT(locs()->temp(0).reg() == R10);
   ASSERT(locs()->out(0).reg() == RAX);
 
+  auto object_store = compiler->isolate()->object_store();
+  const auto& allocate_context_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
+
   __ LoadImmediate(R10, compiler::Immediate(num_context_variables()));
-  compiler->GenerateCall(token_pos(), StubCode::AllocateContext(),
-                         RawPcDescriptors::kOther, locs());
-}
-
-LocationSummary* InitInstanceFieldInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(RAX));
-  locs->set_temp(0, Location::RegisterLocation(RCX));
-  return locs;
-}
-
-void InitInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register instance = locs()->in(0).reg();
-  Register temp = locs()->temp(0).reg();
-
-  compiler::Label no_call;
-
-  __ movq(temp, compiler::FieldAddress(instance, field().TargetOffset()));
-  __ CompareObject(temp, Object::sentinel());
-  __ j(NOT_EQUAL, &no_call, compiler::Assembler::kNearJump);
-
-  __ pushq(compiler::Immediate(0));  // Make room for (unused) result.
-  __ pushq(instance);
-  __ PushObject(Field::ZoneHandle(field().Original()));
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
-                                kInitInstanceFieldRuntimeEntry, 2, locs());
-  __ Drop(3);  // Remove arguments and unused result.
-  __ Bind(&no_call);
+  compiler->GenerateStubCall(token_pos(), allocate_context_stub,
+                             PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3005,8 +2892,11 @@
   ASSERT(locs()->in(0).reg() == R9);
   ASSERT(locs()->out(0).reg() == RAX);
 
-  compiler->GenerateCall(token_pos(), StubCode::CloneContext(),
-                         /*kind=*/RawPcDescriptors::kOther, locs());
+  auto object_store = compiler->isolate()->object_store();
+  const auto& clone_context_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
+  compiler->GenerateStubCall(token_pos(), clone_context_stub,
+                             /*kind=*/PcDescriptorsLayout::kOther, locs());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3027,7 +2917,7 @@
     if (compiler->is_optimizing()) {
       compiler->AddDeoptIndexAtCall(deopt_id);
     } else {
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
                                      TokenPosition::kNoSource);
     }
   }
@@ -3110,7 +3000,7 @@
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
       compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
-          RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
+          PcDescriptorsLayout::kOther, compiler->assembler()->CodeSize(),
           instruction()->deopt_id(), instruction()->token_pos(),
           compiler->CurrentTryIndex());
     } else {
@@ -3122,7 +3012,7 @@
     if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
         instruction()->in_loop()) {
       // In unoptimized code, record loop stack checks as possible OSR entries.
-      compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+      compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
                                      instruction()->deopt_id(),
                                      TokenPosition::kNoSource);
     }
@@ -3225,8 +3115,8 @@
           !RangeUtils::IsWithin(right_range, 0, max_right - 1);
       if (right_needs_check) {
         __ CompareImmediate(
-            right, compiler::Immediate(
-                       reinterpret_cast<int64_t>(Smi::New(max_right))));
+            right,
+            compiler::Immediate(static_cast<int64_t>(Smi::New(max_right))));
         __ j(ABOVE_EQUAL, deopt);
       }
       __ SmiUntag(right);
@@ -3250,7 +3140,7 @@
       compiler::Label done, is_not_zero;
       __ CompareImmediate(
           right,
-          compiler::Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+          compiler::Immediate(static_cast<int64_t>(Smi::New(Smi::kBits))));
       __ j(BELOW, &is_not_zero, compiler::Assembler::kNearJump);
       __ xorq(left, left);
       __ jmp(&done, compiler::Assembler::kNearJump);
@@ -3267,7 +3157,7 @@
       ASSERT(shift_left->CanDeoptimize());
       __ CompareImmediate(
           right,
-          compiler::Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+          compiler::Immediate(static_cast<int64_t>(Smi::New(Smi::kBits))));
       __ j(ABOVE_EQUAL, deopt);
     }
     // Left is not a constant.
@@ -3561,7 +3451,7 @@
   compiler->AddSlowPathCode(slow_path);
   EMIT_SMI_CHECK;
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != INVALID_CONDITION);
+  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.
@@ -3582,7 +3472,7 @@
   compiler->AddSlowPathCode(slow_path);
   EMIT_SMI_CHECK;
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != INVALID_CONDITION);
+  ASSERT(true_condition != kInvalidCondition);
   EmitBranchOnCondition(compiler, true_condition, labels);
   Register result = locs()->out(0).reg();
   __ Bind(false_label);
@@ -3599,8 +3489,7 @@
 
 static bool CanBeImmediate(const Object& constant) {
   return constant.IsSmi() &&
-         compiler::Immediate(reinterpret_cast<int64_t>(constant.raw()))
-             .is_int32();
+         compiler::Immediate(static_cast<int64_t>(constant.raw())).is_int32();
 }
 
 static bool IsSmiValue(const Object& constant, intptr_t value) {
@@ -3709,7 +3598,7 @@
   if (locs()->in(1).IsConstant()) {
     const Object& constant = locs()->in(1).constant();
     ASSERT(constant.IsSmi());
-    const int64_t imm = reinterpret_cast<int64_t>(constant.raw());
+    const int64_t imm = static_cast<int64_t>(constant.raw());
     switch (op_kind()) {
       case Token::kADD: {
         __ AddImmediate(left, compiler::Immediate(imm));
@@ -5626,16 +5515,6 @@
   __ BranchIf(EQUAL, slow_path->entry_label());
 }
 
-void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                           bool save_fpu_registers) {
-  compiler->assembler()->CallNullErrorShared(save_fpu_registers);
-}
-
-void NullArgErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
-                                              bool save_fpu_registers) {
-  compiler->assembler()->CallNullArgErrorShared(save_fpu_registers);
-}
-
 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -5676,8 +5555,8 @@
       compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnknown);
   BranchLabels labels = {&if_true, if_false, &if_true};
   Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
-  if (true_condition != INVALID_CONDITION) {
-    __ j(NegateCondition(true_condition), if_false);
+  if (true_condition != kInvalidCondition) {
+    __ j(InvertCondition(true_condition), if_false);
   }
   __ Bind(&if_true);
 }
@@ -5716,8 +5595,8 @@
   if (index_loc.IsConstant()) {
     Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
-    __ CompareImmediate(
-        length, compiler::Immediate(reinterpret_cast<int64_t>(index.raw())));
+    __ CompareImmediate(length,
+                        compiler::Immediate(static_cast<int64_t>(index.raw())));
     __ j(BELOW_EQUAL, deopt);
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
@@ -5730,7 +5609,7 @@
       __ j(NEGATIVE, deopt);
     } else {
       __ CompareImmediate(
-          index, compiler::Immediate(reinterpret_cast<int64_t>(length.raw())));
+          index, compiler::Immediate(static_cast<int64_t>(length.raw())));
       __ j(ABOVE_EQUAL, deopt);
     }
   } else {
@@ -6581,44 +6460,6 @@
   }
 }
 
-LocationSummary* ThrowInstr::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(RAX));
-  return summary;
-}
-
-void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  __ pushq(exception_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1,
-                                locs());
-  __ int3();
-}
-
-LocationSummary* ReThrowInstr::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::kCall);
-  summary->set_in(0, Location::RegisterLocation(RAX));
-  summary->set_in(1, Location::RegisterLocation(RDX));
-  return summary;
-}
-
-void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register exception_reg = locs()->in(0).reg();
-  const Register stacktrace_reg = locs()->in(1).reg();
-  compiler->SetNeedsStackTrace(catch_try_index());
-  __ pushq(exception_reg);
-  __ pushq(stacktrace_reg);
-  compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry,
-                                2, locs());
-  __ int3();
-}
-
 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const {
   return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
 }
@@ -6652,7 +6493,7 @@
     }
     // Add a deoptimization descriptor for deoptimizing instructions that
     // may be inserted before this instruction.
-    compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+    compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
                                    TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
@@ -6728,29 +6569,13 @@
   return locs;
 }
 
-Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
-                                                 BranchLabels labels) {
-  Location left = locs()->in(0);
-  Location right = locs()->in(1);
-  ASSERT(!left.IsConstant() || !right.IsConstant());
-  Condition true_condition;
-  if (left.IsConstant()) {
-    true_condition = compiler->EmitEqualityRegConstCompare(
-        right.reg(), left.constant(), needs_number_check(), token_pos(),
-        deopt_id_);
-  } else if (right.IsConstant()) {
-    true_condition = compiler->EmitEqualityRegConstCompare(
-        left.reg(), right.constant(), needs_number_check(), token_pos(),
-        deopt_id_);
-  } else {
-    true_condition = compiler->EmitEqualityRegRegCompare(
-        left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
-  }
-  if (kind() != Token::kEQ_STRICT) {
-    ASSERT(kind() == Token::kNE_STRICT);
-    true_condition = NegateCondition(true_condition);
-  }
-  return true_condition;
+Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
+    FlowGraphCompiler* compiler,
+    BranchLabels labels,
+    Register reg,
+    const Object& obj) {
+  return compiler->EmitEqualityRegConstCompare(reg, obj, needs_number_check(),
+                                               token_pos(), deopt_id());
 }
 
 LocationSummary* DispatchTableCallInstr::MakeLocationSummary(Zone* zone,
@@ -6799,26 +6624,36 @@
   }
   __ call(RCX);
   compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
-                                 RawPcDescriptors::kOther, locs());
+                                 PcDescriptorsLayout::kOther, locs());
   __ Drop(argument_count);
 }
 
 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
-  return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
+  return LocationSummary::Make(zone, 1,
+                               value()->Type()->ToCid() == kBoolCid
+                                   ? Location::SameAsFirstInput()
+                                   : Location::RequiresRegister(),
                                LocationSummary::kNoCall);
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register value = locs()->in(0).reg();
+  Register input = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
 
-  compiler::Label done;
-  __ LoadObject(result, Bool::True());
-  __ CompareRegisters(result, value);
-  __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-  __ LoadObject(result, Bool::False());
-  __ Bind(&done);
+  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);
+  }
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -6845,7 +6680,8 @@
   }
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
-  compiler->GenerateCall(token_pos(), stub, RawPcDescriptors::kOther, locs());
+  compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                             locs());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -6863,4 +6699,4 @@
 
 #undef __
 
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index c124196..169d57d 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/inliner.h"
 
 #include "vm/compiler/aot/aot_call_specializer.h"
@@ -2287,7 +2285,7 @@
   // replace them with inline FG before inlining introduces any superfluous
   // AssertAssignable instructions.
   if (function.IsDispatcherOrImplicitAccessor() &&
-      !(function.kind() == RawFunction::kDynamicInvocationForwarder &&
+      !(function.kind() == FunctionLayout::kDynamicInvocationForwarder &&
         function.IsRecognized())) {
     // Smaller or same size as the call.
     return true;
@@ -2300,7 +2298,7 @@
 
   if (function.IsGetterFunction() || function.IsSetterFunction() ||
       IsInlineableOperator(function) ||
-      (function.kind() == RawFunction::kConstructor)) {
+      (function.kind() == FunctionLayout::kConstructor)) {
     const intptr_t count = function.optimized_instruction_count();
     if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) {
       return true;
@@ -2427,7 +2425,7 @@
     // Load from the data from backing store which is a fixed-length array.
     *array = elements;
     array_cid = kArrayCid;
-  } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+  } else if (IsExternalTypedDataClassId(array_cid)) {
     LoadUntaggedInstr* elements = new (Z)
         LoadUntaggedInstr(new (Z) Value(*array),
                           compiler::target::TypedDataBase::data_field_offset());
@@ -2628,9 +2626,8 @@
 
   // Check if store barrier is needed. Byte arrays don't need a store barrier.
   StoreBarrierType needs_store_barrier =
-      (RawObject::IsTypedDataClassId(array_cid) ||
-       RawObject::IsTypedDataViewClassId(array_cid) ||
-       RawObject::IsExternalTypedDataClassId(array_cid))
+      (IsTypedDataClassId(array_cid) || IsTypedDataViewClassId(array_cid) ||
+       IsExternalTypedDataClassId(array_cid))
           ? kNoStoreBarrier
           : kEmitStoreBarrier;
 
@@ -2895,8 +2892,7 @@
                                          intptr_t array_cid,
                                          Definition** array,
                                          Instruction** cursor) {
-  if (array_cid == kDynamicCid ||
-      RawObject::IsExternalTypedDataClassId(array_cid)) {
+  if (array_cid == kDynamicCid || IsExternalTypedDataClassId(array_cid)) {
     // Internal or External typed data: load untagged.
     auto elements = new (Z)
         LoadUntaggedInstr(new (Z) Value(*array),
@@ -2905,7 +2901,7 @@
     *array = elements;
   } else {
     // Internal typed data: no action.
-    ASSERT(RawObject::IsTypedDataClassId(array_cid));
+    ASSERT(IsTypedDataClassId(array_cid));
   }
 }
 
@@ -4193,11 +4189,11 @@
       Type& type = Type::ZoneHandle(Z);
       if (receiver_cid == kDynamicCid) {
         return false;
-      } else if (RawObject::IsStringClassId(receiver_cid)) {
+      } else if (IsStringClassId(receiver_cid)) {
         type = Type::StringType();
       } else if (receiver_cid == kDoubleCid) {
         type = Type::Double();
-      } else if (RawObject::IsIntegerClassId(receiver_cid)) {
+      } else if (IsIntegerClassId(receiver_cid)) {
         type = Type::IntType();
       } else if (receiver_cid != kClosureCid) {
         const Class& cls = Class::Handle(
@@ -4267,5 +4263,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/inliner.h b/runtime/vm/compiler/backend/inliner.h
index 5aa3c1a..c31a954 100644
--- a/runtime/vm/compiler/backend/inliner.h
+++ b/runtime/vm/compiler/backend/inliner.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_INLINER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_INLINER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/growable_array.h"
 #include "vm/token_position.h"
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 402954d..2aa6944 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/linearscan.h"
 
 #include "vm/bit_vector.h"
@@ -682,15 +680,15 @@
       range->set_assigned_location(loc);
       AssignSafepoints(defn, range);
       range->finger()->Initialize(range);
-      SplitInitialDefinitionAt(range, block->lifetime_position() + 1);
+      SplitInitialDefinitionAt(range, GetLifetimePosition(block) + 1);
       ConvertAllUses(range);
 
       // We have exception/stacktrace in a register and need to
       // ensure this register is not available for register allocation during
       // the [CatchBlockEntry] to ensure it's not overwritten.
       if (loc.IsRegister()) {
-        BlockLocation(loc, block->lifetime_position(),
-                      block->lifetime_position() + 1);
+        BlockLocation(loc, GetLifetimePosition(block),
+                      GetLifetimePosition(block) + 1);
       }
       return;
     }
@@ -745,12 +743,12 @@
     range->set_assigned_location(loc);
     if (loc.IsRegister()) {
       AssignSafepoints(defn, range);
-      if (range->End() > (block->lifetime_position() + 2)) {
-        SplitInitialDefinitionAt(range, block->lifetime_position() + 2);
+      if (range->End() > (GetLifetimePosition(block) + 2)) {
+        SplitInitialDefinitionAt(range, GetLifetimePosition(block) + 2);
       }
       ConvertAllUses(range);
-      BlockLocation(loc, block->lifetime_position(),
-                    block->lifetime_position() + 2);
+      BlockLocation(loc, GetLifetimePosition(block),
+                    GetLifetimePosition(block) + 2);
       return;
     }
   } else {
@@ -837,7 +835,7 @@
   ParallelMoveInstr* parallel_move = goto_instr->parallel_move();
 
   // All uses are recorded at the position of parallel move preceding goto.
-  const intptr_t pos = goto_instr->lifetime_position();
+  const intptr_t pos = GetLifetimePosition(goto_instr);
 
   JoinEntryInstr* join = goto_instr->successor();
   ASSERT(join != NULL);
@@ -975,7 +973,7 @@
     }
 
     const intptr_t block_start_pos = block->start_pos();
-    const intptr_t use_pos = current->lifetime_position() + 1;
+    const intptr_t use_pos = GetLifetimePosition(current) + 1;
 
     Location* locations = flow_graph_.zone()->Alloc<Location>(env->Length());
 
@@ -1306,7 +1304,7 @@
     }
   }
 
-  const intptr_t pos = current->lifetime_position();
+  const intptr_t pos = GetLifetimePosition(current);
   ASSERT(IsInstructionStartPosition(pos));
 
   ASSERT(locs->input_count() == current->InputCount());
@@ -1524,11 +1522,12 @@
   ASSERT(pos > 0);
   Instruction* prev = instr->previous();
   ParallelMoveInstr* move = prev->AsParallelMove();
-  if ((move == NULL) || (move->lifetime_position() != pos)) {
+  if ((move == NULL) ||
+      (FlowGraphAllocator::GetLifetimePosition(move) != pos)) {
     move = new ParallelMoveInstr();
     prev->LinkTo(move);
     move->LinkTo(instr);
-    move->set_lifetime_position(pos);
+    FlowGraphAllocator::SetLifetimePosition(move, pos);
   }
   return move;
 }
@@ -1536,7 +1535,8 @@
 static ParallelMoveInstr* CreateParallelMoveAfter(Instruction* instr,
                                                   intptr_t pos) {
   Instruction* next = instr->next();
-  if (next->IsParallelMove() && (next->lifetime_position() == pos)) {
+  if (next->IsParallelMove() &&
+      (FlowGraphAllocator::GetLifetimePosition(next) == pos)) {
     return next->AsParallelMove();
   }
   return CreateParallelMoveBefore(next, pos);
@@ -1558,7 +1558,7 @@
     instructions_.Add(block);
     block_entries_.Add(block);
     block->set_start_pos(pos);
-    block->set_lifetime_position(pos);
+    SetLifetimePosition(block, pos);
     pos += 2;
 
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
@@ -1567,7 +1567,7 @@
       if (!current->IsParallelMove()) {
         instructions_.Add(current);
         block_entries_.Add(block);
-        current->set_lifetime_position(pos);
+        SetLifetimePosition(current, pos);
         pos += 2;
       }
     }
@@ -1832,7 +1832,7 @@
   BlockEntryInstr* split_block_entry = BlockEntryAt(to);
   ASSERT(split_block_entry == InstructionAt(to)->GetBlock());
 
-  if (from < split_block_entry->lifetime_position()) {
+  if (from < GetLifetimePosition(split_block_entry)) {
     // Interval [from, to) spans multiple blocks.
 
     // If the last block is inside a loop, prefer splitting at the outermost
@@ -1863,16 +1863,16 @@
       }
     }
     while ((loop_info != nullptr) &&
-           (from < loop_info->header()->lifetime_position())) {
+           (from < GetLifetimePosition(loop_info->header()))) {
       split_block_entry = loop_info->header();
       loop_info = loop_info->outer();
       TRACE_ALLOC(THR_Print("  move back to loop header B%" Pd " at %" Pd "\n",
                             split_block_entry->block_id(),
-                            split_block_entry->lifetime_position()));
+                            GetLifetimePosition(split_block_entry)));
     }
 
     // Split at block's start.
-    split_pos = split_block_entry->lifetime_position();
+    split_pos = GetLifetimePosition(split_block_entry);
   } else {
     // Interval [from, to) is contained inside a single block.
 
@@ -2587,7 +2587,7 @@
       continue;
     }
 
-    const intptr_t pos = safepoint_instr->lifetime_position();
+    const intptr_t pos = GetLifetimePosition(safepoint_instr);
     if (range->End() <= pos) break;
 
     if (range->Contains(pos)) {
@@ -2989,5 +2989,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/linearscan.h b/runtime/vm/compiler/backend/linearscan.h
index 541bd2c..740e489 100644
--- a/runtime/vm/compiler/backend/linearscan.h
+++ b/runtime/vm/compiler/backend/linearscan.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_LINEARSCAN_H_
 #define RUNTIME_VM_COMPILER_BACKEND_LINEARSCAN_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 #include "vm/growable_array.h"
@@ -63,6 +67,20 @@
   // Map a virtual register number to its live range.
   LiveRange* GetLiveRange(intptr_t vreg);
 
+  DART_FORCE_INLINE static void SetLifetimePosition(Instruction* instr,
+                                                    intptr_t pos) {
+    instr->SetPassSpecificId(CompilerPass::kAllocateRegisters, pos);
+  }
+
+  DART_FORCE_INLINE static bool HasLifetimePosition(Instruction* instr) {
+    return instr->HasPassSpecificId(CompilerPass::kAllocateRegisters);
+  }
+
+  DART_FORCE_INLINE static intptr_t GetLifetimePosition(
+      const Instruction* instr) {
+    return instr->GetPassSpecificId(CompilerPass::kAllocateRegisters);
+  }
+
  private:
   void CollectRepresentations();
 
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index 2153fac..f5853c2 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/locations.h"
 
 #include "vm/compiler/assembler/assembler.h"
@@ -394,5 +392,3 @@
 #endif
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index 117092a..a270ad8 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_H_
 #define RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/bitfield.h"
 #include "vm/bitmap.h"
diff --git a/runtime/vm/compiler/backend/locations_helpers.h b/runtime/vm/compiler/backend/locations_helpers.h
index 5e7969a..6b62e40 100644
--- a/runtime/vm/compiler/backend/locations_helpers.h
+++ b/runtime/vm/compiler/backend/locations_helpers.h
@@ -43,6 +43,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_H_
 #define RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/locations.h"
 
 namespace dart {
diff --git a/runtime/vm/compiler/backend/locations_helpers_arm.h b/runtime/vm/compiler/backend/locations_helpers_arm.h
index 6eecc9f..4a651cc 100644
--- a/runtime/vm/compiler/backend/locations_helpers_arm.h
+++ b/runtime/vm/compiler/backend/locations_helpers_arm.h
@@ -9,6 +9,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_ARM_H_
 #define RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_ARM_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // QRegisterView is a wrapper around QRegister that provides helpers for
diff --git a/runtime/vm/compiler/backend/loops.cc b/runtime/vm/compiler/backend/loops.cc
index b8edbc0..21a4a77 100644
--- a/runtime/vm/compiler/backend/loops.cc
+++ b/runtime/vm/compiler/backend/loops.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/loops.h"
 
 #include "vm/bit_vector.h"
@@ -1192,5 +1190,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/loops.h b/runtime/vm/compiler/backend/loops.h
index 26875ab..704508b 100644
--- a/runtime/vm/compiler/backend/loops.h
+++ b/runtime/vm/compiler/backend/loops.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_LOOPS_H_
 #define RUNTIME_VM_COMPILER_BACKEND_LOOPS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <utility>
 
 #include "vm/allocation.h"
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 7ab4dc2..b960558 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/range_analysis.h"
 
 #include "vm/bit_vector.h"
@@ -2771,7 +2769,7 @@
 }
 
 void LoadCodeUnitsInstr::InferRange(RangeAnalysis* analysis, Range* range) {
-  ASSERT(RawObject::IsStringClassId(class_id()));
+  ASSERT(IsStringClassId(class_id()));
   RangeBoundary zero = RangeBoundary::FromConstant(0);
   // Take the number of loaded characters into account when determining the
   // range of the result.
@@ -3045,5 +3043,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/range_analysis.h b/runtime/vm/compiler/backend/range_analysis.h
index 720103b..0ed4936 100644
--- a/runtime/vm/compiler/backend/range_analysis.h
+++ b/runtime/vm/compiler/backend/range_analysis.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_RANGE_ANALYSIS_H_
 #define RUNTIME_VM_COMPILER_BACKEND_RANGE_ANALYSIS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 0559662..45c4b24 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/redundancy_elimination.h"
 
 #include "vm/bit_vector.h"
@@ -1245,6 +1243,18 @@
   return phi_moves;
 }
 
+DART_FORCE_INLINE static void SetPlaceId(Instruction* instr, intptr_t id) {
+  instr->SetPassSpecificId(CompilerPass::kCSE, id);
+}
+
+DART_FORCE_INLINE static intptr_t GetPlaceId(const Instruction* instr) {
+  return instr->GetPassSpecificId(CompilerPass::kCSE);
+}
+
+DART_FORCE_INLINE static bool HasPlaceId(const Instruction* instr) {
+  return instr->HasPassSpecificId(CompilerPass::kCSE);
+}
+
 enum CSEMode { kOptimizeLoads, kOptimizeStores };
 
 static AliasedSet* NumberPlaces(
@@ -1282,7 +1292,7 @@
         }
       }
 
-      instr->set_place_id(result->id());
+      SetPlaceId(instr, result->id());
     }
   }
 
@@ -1309,8 +1319,8 @@
                                 intptr_t loop_header_index,
                                 Instruction* instr) {
   return IsLoadEliminationCandidate(instr) && (sets != NULL) &&
-         instr->HasPlaceId() && ((*sets)[loop_header_index] != NULL) &&
-         (*sets)[loop_header_index]->Contains(instr->place_id());
+         HasPlaceId(instr) &&
+         (*sets)[loop_header_index]->Contains(GetPlaceId(instr));
 }
 
 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) {
@@ -1659,7 +1669,7 @@
             // instruction that still points to the old place with a more
             // generic alias.
             const intptr_t old_alias_id = aliased_set_->LookupAliasId(
-                aliased_set_->places()[instr->place_id()]->ToAlias());
+                aliased_set_->places()[GetPlaceId(instr)]->ToAlias());
             killed = aliased_set_->GetKilledSet(old_alias_id);
           }
 
@@ -1678,7 +1688,7 @@
                   if (FLAG_trace_optimization) {
                     THR_Print("Removing redundant store to place %" Pd
                               " in block B%" Pd "\n",
-                              instr->place_id(), block->block_id());
+                              GetPlaceId(instr), block->block_id());
                   }
                   instr_it.RemoveCurrentFromGraph();
                   continue;
@@ -1711,8 +1721,8 @@
           // load forwarding.
           const Place* canonical = aliased_set_->LookupCanonical(&place);
           if ((canonical != NULL) &&
-              (canonical->id() != instr->AsDefinition()->place_id())) {
-            instr->AsDefinition()->set_place_id(canonical->id());
+              (canonical->id() != GetPlaceId(instr->AsDefinition()))) {
+            SetPlaceId(instr->AsDefinition(), canonical->id());
           }
         }
 
@@ -1751,11 +1761,11 @@
             intptr_t place_id = 0;
             if (auto load = use->instruction()->AsLoadField()) {
               slot = &load->slot();
-              place_id = load->place_id();
+              place_id = GetPlaceId(load);
             } else if (auto store =
                            use->instruction()->AsStoreInstanceField()) {
               slot = &store->slot();
-              place_id = store->place_id();
+              place_id = GetPlaceId(store);
             }
 
             if (slot != nullptr) {
@@ -1789,7 +1799,7 @@
           continue;
         }
 
-        const intptr_t place_id = defn->place_id();
+        const intptr_t place_id = GetPlaceId(defn);
         if (gen->Contains(place_id)) {
           // This is a locally redundant load.
           ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL));
@@ -1965,7 +1975,7 @@
               (in_[preorder_number]->Contains(place_id))) {
             PhiInstr* phi = new (Z)
                 PhiInstr(block->AsJoinEntry(), block->PredecessorCount());
-            phi->set_place_id(place_id);
+            SetPlaceId(phi, place_id);
             pending_phis.Add(phi);
             in_value = phi;
           }
@@ -2103,14 +2113,14 @@
     // Incoming values are different. Phi is required to merge.
     PhiInstr* phi =
         new (Z) PhiInstr(block->AsJoinEntry(), block->PredecessorCount());
-    phi->set_place_id(place_id);
+    SetPlaceId(phi, place_id);
     FillPhiInputs(phi);
     return phi;
   }
 
   void FillPhiInputs(PhiInstr* phi) {
     BlockEntryInstr* block = phi->GetBlock();
-    const intptr_t place_id = phi->place_id();
+    const intptr_t place_id = GetPlaceId(phi);
 
     for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
       BlockEntryInstr* pred = block->PredecessorAt(i);
@@ -2154,9 +2164,9 @@
 
       for (intptr_t i = 0; i < loads->length(); i++) {
         Definition* load = (*loads)[i];
-        if (!in->Contains(load->place_id())) continue;  // No incoming value.
+        if (!in->Contains(GetPlaceId(load))) continue;  // No incoming value.
 
-        Definition* replacement = MergeIncomingValues(block, load->place_id());
+        Definition* replacement = MergeIncomingValues(block, GetPlaceId(load));
         ASSERT(replacement != NULL);
 
         // Sets of outgoing values are not linked into use lists so
@@ -2606,17 +2616,17 @@
 
         // Handle stores.
         if (is_store) {
-          if (kill->Contains(instr->place_id())) {
-            if (!live_in->Contains(instr->place_id()) &&
+          if (kill->Contains(GetPlaceId(instr))) {
+            if (!live_in->Contains(GetPlaceId(instr)) &&
                 CanEliminateStore(instr)) {
               if (FLAG_trace_optimization) {
                 THR_Print("Removing dead store to place %" Pd " in block B%" Pd
                           "\n",
-                          instr->place_id(), block->block_id());
+                          GetPlaceId(instr), block->block_id());
               }
               instr_it.RemoveCurrentFromGraph();
             }
-          } else if (!live_in->Contains(instr->place_id())) {
+          } else if (!live_in->Contains(GetPlaceId(instr))) {
             // Mark this store as down-ward exposed: They are the only
             // candidates for the global store elimination.
             if (exposed_stores == NULL) {
@@ -2628,8 +2638,8 @@
             exposed_stores->Add(instr);
           }
           // Interfering stores kill only loads from the same place.
-          kill->Add(instr->place_id());
-          live_in->Remove(instr->place_id());
+          kill->Add(GetPlaceId(instr));
+          live_in->Remove(GetPlaceId(instr));
           continue;
         }
 
@@ -2690,11 +2700,11 @@
         }
         // Eliminate a downward exposed store if the corresponding place is not
         // in live-out.
-        if (!live_out->Contains(instr->place_id()) &&
+        if (!live_out->Contains(GetPlaceId(instr)) &&
             CanEliminateStore(instr)) {
           if (FLAG_trace_optimization) {
             THR_Print("Removing dead store to place %" Pd " block B%" Pd "\n",
-                      instr->place_id(), block->block_id());
+                      GetPlaceId(instr), block->block_id());
           }
           instr->RemoveFromGraph(/* ignored */ false);
         }
@@ -3316,6 +3326,18 @@
     EliminateDeadParameters();
   }
 
+  static intptr_t GetParameterId(const Instruction* instr) {
+    return instr->GetPassSpecificId(CompilerPass::kTryCatchOptimization);
+  }
+
+  static void SetParameterId(Instruction* instr, intptr_t id) {
+    instr->SetPassSpecificId(CompilerPass::kTryCatchOptimization, id);
+  }
+
+  static bool HasParameterId(Instruction* instr) {
+    return instr->HasPassSpecificId(CompilerPass::kTryCatchOptimization);
+  }
+
   // Assign sequential ids to each ParameterInstr in each CatchEntryBlock.
   // Collect reverse mapping from try indexes to corresponding catches.
   void NumberCatchEntryParameters() {
@@ -3324,7 +3346,7 @@
           *catch_entry->initial_definitions();
       for (auto idef : idefs) {
         if (idef->IsParameter()) {
-          idef->set_place_id(parameter_info_.length());
+          SetParameterId(idef, parameter_info_.length());
           parameter_info_.Add(new ParameterInfo(idef->AsParameter()));
         }
       }
@@ -3363,14 +3385,14 @@
             // already present in the list.
             bool found = false;
             for (auto other_defn :
-                 parameter_info_[param->place_id()]->incoming) {
+                 parameter_info_[GetParameterId(param)]->incoming) {
               if (other_defn == defn) {
                 found = true;
                 break;
               }
             }
             if (!found) {
-              parameter_info_[param->place_id()]->incoming.Add(defn);
+              parameter_info_[GetParameterId(param)]->incoming.Add(defn);
             }
           }
         }
@@ -3410,7 +3432,7 @@
     while (!worklist_.IsEmpty()) {
       Definition* defn = worklist_.RemoveLast();
       if (ParameterInstr* param = defn->AsParameter()) {
-        auto s = parameter_info_[param->place_id()];
+        auto s = parameter_info_[GetParameterId(param)];
         for (auto input : s->incoming) {
           MarkLive(input);
         }
@@ -3431,8 +3453,8 @@
         worklist_.Add(phi);
       }
     } else if (ParameterInstr* param = defn->AsParameter()) {
-      if (param->place_id() != -1) {
-        auto input_s = parameter_info_[param->place_id()];
+      if (HasParameterId(param)) {
+        auto input_s = parameter_info_[GetParameterId(param)];
         if (!input_s->alive) {
           input_s->alive = true;
           worklist_.Add(param);
@@ -3466,7 +3488,7 @@
 
         for (intptr_t env_idx = 0; env_idx < idefs.length(); ++env_idx) {
           if (ParameterInstr* param = idefs[env_idx]->AsParameter()) {
-            if (!parameter_info_[param->place_id()]->alive) {
+            if (!parameter_info_[GetParameterId(param)]->alive) {
               env->ValueAt(env_idx)->BindToEnvironment(
                   flow_graph_->constant_null());
             }
@@ -3816,5 +3838,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.h b/runtime/vm/compiler/backend/redundancy_elimination.h
index fd9b9c8..84fc7d2 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.h
+++ b/runtime/vm/compiler/backend/redundancy_elimination.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_REDUNDANCY_ELIMINATION_H_
 #define RUNTIME_VM_COMPILER_BACKEND_REDUNDANCY_ELIMINATION_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 7164e20..2fb3b16 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -954,4 +954,44 @@
   EXPECT_EQ(1, aft_stores);
 }
 
+ISOLATE_UNIT_TEST_CASE(CSE_RedundantInitStaticField) {
+  const char* kScript = R"(
+    int getX() => 2;
+    int x = getX();
+
+    foo() => x + x;
+
+    main() {
+      foo();
+    }
+  )";
+
+  // Make sure InitStaticField is not removed because
+  // field is already initialized.
+  SetFlagScope<bool> sfs(&FLAG_fields_may_be_reset, true);
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  Invoke(root_library, "main");
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  TestPipeline pipeline(function, CompilerPass::kJIT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+  ASSERT(flow_graph != nullptr);
+
+  auto entry = flow_graph->graph_entry()->normal_entry();
+  EXPECT(entry != nullptr);
+
+  ILMatcher cursor(flow_graph, entry);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMatchAndMoveFunctionEntry,
+      kMatchAndMoveCheckStackOverflow,
+      kMatchAndMoveInitStaticField,
+      kMatchAndMoveLoadStaticField,
+      kMatchAndMoveCheckSmi,
+      kMoveParallelMoves,
+      kMatchAndMoveBinarySmiOp,
+      kMoveParallelMoves,
+      kMatchReturn,
+  }));
+}
+
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/sexpression.cc b/runtime/vm/compiler/backend/sexpression.cc
index 8b33ea5..12006b4 100644
--- a/runtime/vm/compiler/backend/sexpression.cc
+++ b/runtime/vm/compiler/backend/sexpression.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/sexpression.h"
 
 #include <ctype.h>
@@ -687,5 +685,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/sexpression.h b/runtime/vm/compiler/backend/sexpression.h
index 461e3eb..40b79a3 100644
--- a/runtime/vm/compiler/backend/sexpression.h
+++ b/runtime/vm/compiler/backend/sexpression.h
@@ -5,6 +5,10 @@
 #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"
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 43d3989..b54bc57 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -4,8 +4,6 @@
 
 #include "vm/compiler/backend/slot.h"
 
-#ifndef DART_PRECOMPILED_RUNTIME
-
 #include "vm/compiler/compiler_state.h"
 #include "vm/hash_map.h"
 #include "vm/parser.h"
@@ -120,9 +118,8 @@
 
 // Note: should only be called with cids of array-like classes.
 const Slot& Slot::GetLengthFieldForArrayCid(intptr_t array_cid) {
-  if (RawObject::IsExternalTypedDataClassId(array_cid) ||
-      RawObject::IsTypedDataClassId(array_cid) ||
-      RawObject::IsTypedDataViewClassId(array_cid)) {
+  if (IsExternalTypedDataClassId(array_cid) || IsTypedDataClassId(array_cid) ||
+      IsTypedDataViewClassId(array_cid)) {
     return GetNativeSlot(Kind::kTypedDataBase_length);
   }
   switch (array_cid) {
@@ -195,6 +192,11 @@
     }
   }
 
+  AbstractType& type = AbstractType::ZoneHandle(zone, field.type());
+  if (type.IsStrictlyNonNullable()) {
+    is_nullable = false;
+  }
+
   bool used_guarded_state = false;
   if (field.guarded_cid() != kIllegalCid &&
       field.guarded_cid() != kDynamicCid) {
@@ -210,8 +212,6 @@
     }
   }
 
-  AbstractType& type = AbstractType::ZoneHandle(zone, field.type());
-
   if (field.needs_load_guard()) {
     // Should be kept in sync with LoadStaticFieldInstr::ComputeType.
     type = Type::DynamicType();
@@ -224,11 +224,6 @@
     is_nullable = false;
   }
 
-  if (field.is_late()) {
-    // TODO(dartbug.com/40796): Extend CompileType to handle lateness.
-    is_nullable = true;
-  }
-
   const Slot& slot = SlotCache::Instance(thread).Canonicalize(Slot(
       Kind::kDartField,
       IsImmutableBit::encode((field.is_final() && !field.is_late()) ||
@@ -320,5 +315,3 @@
 }
 
 }  // namespace dart
-
-#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 6f6faa8..2da369a 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -24,6 +24,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_SLOT_H_
 #define RUNTIME_VM_COMPILER_BACKEND_SLOT_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/compile_type.h"
 #include "vm/thread.h"
 
@@ -49,31 +53,31 @@
 //
 // Note: native slots are expected to be non-nullable.
 #define NATIVE_SLOTS_LIST(V)                                                   \
-  V(Array, RawArray, length, Smi, FINAL)                                       \
-  V(Context, RawContext, parent, Context, FINAL)                               \
-  V(Closure, RawClosure, instantiator_type_arguments, TypeArguments, FINAL)    \
-  V(Closure, RawClosure, delayed_type_arguments, TypeArguments, FINAL)         \
-  V(Closure, RawClosure, function_type_arguments, TypeArguments, FINAL)        \
-  V(Closure, RawClosure, function, Function, FINAL)                            \
-  V(Closure, RawClosure, context, Context, FINAL)                              \
-  V(Closure, RawClosure, hash, Context, VAR)                                   \
-  V(GrowableObjectArray, RawGrowableObjectArray, length, Smi, VAR)             \
-  V(GrowableObjectArray, RawGrowableObjectArray, data, Array, VAR)             \
-  V(TypedDataBase, RawTypedDataBase, length, Smi, FINAL)                       \
-  V(TypedDataView, RawTypedDataView, offset_in_bytes, Smi, FINAL)              \
-  V(TypedDataView, RawTypedDataView, data, Dynamic, FINAL)                     \
-  V(String, RawString, length, Smi, FINAL)                                     \
-  V(LinkedHashMap, RawLinkedHashMap, index, TypedDataUint32Array, VAR)         \
-  V(LinkedHashMap, RawLinkedHashMap, data, Array, VAR)                         \
-  V(LinkedHashMap, RawLinkedHashMap, hash_mask, Smi, VAR)                      \
-  V(LinkedHashMap, RawLinkedHashMap, used_data, Smi, VAR)                      \
-  V(LinkedHashMap, RawLinkedHashMap, deleted_keys, Smi, VAR)                   \
-  V(ArgumentsDescriptor, RawArray, type_args_len, Smi, FINAL)                  \
-  V(ArgumentsDescriptor, RawArray, positional_count, Smi, FINAL)               \
-  V(ArgumentsDescriptor, RawArray, count, Smi, FINAL)                          \
-  V(ArgumentsDescriptor, RawArray, size, Smi, FINAL)                           \
-  V(PointerBase, RawPointerBase, data_field, Dynamic, FINAL)                   \
-  V(Type, RawType, arguments, TypeArguments, FINAL)
+  V(Array, ArrayLayout, length, Smi, FINAL)                                    \
+  V(Context, ContextLayout, parent, Context, FINAL)                            \
+  V(Closure, ClosureLayout, instantiator_type_arguments, TypeArguments, FINAL) \
+  V(Closure, ClosureLayout, delayed_type_arguments, TypeArguments, FINAL)      \
+  V(Closure, ClosureLayout, function_type_arguments, TypeArguments, FINAL)     \
+  V(Closure, ClosureLayout, function, Function, FINAL)                         \
+  V(Closure, ClosureLayout, context, Context, FINAL)                           \
+  V(Closure, ClosureLayout, hash, Context, VAR)                                \
+  V(GrowableObjectArray, GrowableObjectArrayLayout, length, Smi, VAR)          \
+  V(GrowableObjectArray, GrowableObjectArrayLayout, data, Array, VAR)          \
+  V(TypedDataBase, TypedDataBaseLayout, length, Smi, FINAL)                    \
+  V(TypedDataView, TypedDataViewLayout, offset_in_bytes, Smi, FINAL)           \
+  V(TypedDataView, TypedDataViewLayout, data, Dynamic, FINAL)                  \
+  V(String, StringLayout, length, Smi, FINAL)                                  \
+  V(LinkedHashMap, LinkedHashMapLayout, index, TypedDataUint32Array, VAR)      \
+  V(LinkedHashMap, LinkedHashMapLayout, data, Array, VAR)                      \
+  V(LinkedHashMap, LinkedHashMapLayout, hash_mask, Smi, VAR)                   \
+  V(LinkedHashMap, LinkedHashMapLayout, used_data, Smi, VAR)                   \
+  V(LinkedHashMap, LinkedHashMapLayout, deleted_keys, Smi, VAR)                \
+  V(ArgumentsDescriptor, ArrayLayout, type_args_len, Smi, FINAL)               \
+  V(ArgumentsDescriptor, ArrayLayout, positional_count, Smi, FINAL)            \
+  V(ArgumentsDescriptor, ArrayLayout, count, Smi, FINAL)                       \
+  V(ArgumentsDescriptor, ArrayLayout, size, Smi, FINAL)                        \
+  V(PointerBase, PointerBaseLayout, data_field, Dynamic, FINAL)                \
+  V(Type, TypeLayout, arguments, TypeArguments, FINAL)
 
 // Slot is an abstraction that describes an readable (and possibly writeable)
 // location within an object.
diff --git a/runtime/vm/compiler/backend/slot_test.cc b/runtime/vm/compiler/backend/slot_test.cc
index 7dea9b7..a506698 100644
--- a/runtime/vm/compiler/backend/slot_test.cc
+++ b/runtime/vm/compiler/backend/slot_test.cc
@@ -48,8 +48,8 @@
 
   const Function& dummy_function = Function::ZoneHandle(
       Function::New(String::Handle(Symbols::New(thread, "foo")),
-                    RawFunction::kRegularFunction, false, false, false, false,
-                    false, dummy_class, TokenPosition::kMinSource));
+                    FunctionLayout::kRegularFunction, false, false, false,
+                    false, false, dummy_class, TokenPosition::kMinSource));
 
   const Field& field = Field::Handle(
       Field::New(String::Handle(Symbols::New(thread, "field")),
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 629c9b0..81d0f03 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/backend/type_propagator.h"
 
 #include "platform/text_buffer.h"
@@ -370,6 +368,11 @@
             new (zone()) CompileType(instr->ComputeType()));
 }
 
+void FlowGraphTypePropagator::VisitAssertBoolean(AssertBooleanInstr* instr) {
+  SetTypeOf(instr->value()->definition(),
+            new (zone()) CompileType(CompileType::Bool()));
+}
+
 void FlowGraphTypePropagator::VisitAssertSubtype(AssertSubtypeInstr* instr) {}
 
 void FlowGraphTypePropagator::VisitBranch(BranchInstr* instr) {
@@ -413,7 +416,7 @@
       type = &(instance_of->type());
       left = instance_of->value()->definition();
     }
-    if (!type->IsTopType()) {
+    if (!type->IsTopTypeForInstanceOf()) {
       const bool is_nullable = (type->IsNullable() || type->IsTypeParameter() ||
                                 (type->IsNeverType() && type->IsLegacy()))
                                    ? CompileType::kNullable
@@ -640,7 +643,8 @@
 
 CompileType CompileType::FromAbstractType(const AbstractType& type,
                                           bool is_nullable) {
-  return CompileType(is_nullable, kIllegalCid, &type);
+  return CompileType(is_nullable && !type.IsStrictlyNonNullable(), kIllegalCid,
+                     &type);
 }
 
 CompileType CompileType::FromCid(intptr_t cid) {
@@ -672,7 +676,7 @@
 }
 
 CompileType CompileType::NullableInt() {
-  return FromAbstractType(Type::ZoneHandle(Type::IntType()), kNullable);
+  return FromAbstractType(Type::ZoneHandle(Type::NullableIntType()), kNullable);
 }
 
 CompileType CompileType::Smi() {
@@ -684,7 +688,7 @@
 }
 
 CompileType CompileType::NullableDouble() {
-  return FromAbstractType(Type::ZoneHandle(Type::Double()), kNullable);
+  return FromAbstractType(Type::ZoneHandle(Type::NullableDouble()), kNullable);
 }
 
 CompileType CompileType::String() {
@@ -800,7 +804,7 @@
 }
 
 bool CompileType::IsSubtypeOf(const AbstractType& other) {
-  if (other.IsTopType()) {
+  if (other.IsTopTypeForSubtyping()) {
     return true;
   }
 
@@ -812,7 +816,7 @@
 }
 
 bool CompileType::IsAssignableTo(const AbstractType& other) {
-  if (other.IsTopTypeForAssignability()) {
+  if (other.IsTopTypeForSubtyping()) {
     return true;
   }
   if (IsNone()) {
@@ -825,7 +829,7 @@
 }
 
 bool CompileType::IsInstanceOf(const AbstractType& other) {
-  if (other.IsTopType()) {
+  if (other.IsTopTypeForInstanceOf()) {
     return true;
   }
   if (IsNone() || !other.IsInstantiated()) {
@@ -1053,7 +1057,7 @@
         graph_entry->parsed_function().RawParameterVariable(0)->type();
     if (type.IsObjectType() || type.IsNullType()) {
       // Receiver can be null.
-      return CompileType::FromAbstractType(type, CompileType::kNullable);
+      return CompileType::FromAbstractType(type);
     }
 
     // Receiver can't be null but can be an instance of a subclass.
@@ -1391,10 +1395,10 @@
     TraceStrongModeType(this, *abstract_type);
   }
   ASSERT(field.is_static());
-  if (field.is_final() && !FLAG_fields_may_be_reset) {
+  const bool is_initialized = IsFieldInitialized() && !FLAG_fields_may_be_reset;
+  if (field.is_final() && is_initialized) {
     const Instance& obj = Instance::Handle(field.StaticValue());
-    if ((obj.raw() != Object::sentinel().raw()) &&
-        (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) {
+    if (!obj.IsNull()) {
       is_nullable = CompileType::kNonNullable;
       cid = obj.GetClassId();
       abstract_type = nullptr;  // Cid is known, calculate abstract type lazily.
@@ -1411,10 +1415,6 @@
     DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload());
     return CompileType::Dynamic();
   }
-  if (field.is_late()) {
-    // TODO(dartbug.com/40796): Extend CompileType to handle lateness.
-    is_nullable = CompileType::kNullable;
-  }
   return CompileType(is_nullable, cid, abstract_type);
 }
 
@@ -1748,5 +1748,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/type_propagator.h b/runtime/vm/compiler/backend/type_propagator.h
index d59acf7..5c27420 100644
--- a/runtime/vm/compiler/backend/type_propagator.h
+++ b/runtime/vm/compiler/backend/type_propagator.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_TYPE_PROPAGATOR_H_
 #define RUNTIME_VM_COMPILER_BACKEND_TYPE_PROPAGATOR_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 
@@ -33,6 +37,7 @@
   virtual void VisitCheckNull(CheckNullInstr* instr);
   virtual void VisitGuardFieldClass(GuardFieldClassInstr* instr);
   virtual void VisitAssertAssignable(AssertAssignableInstr* instr);
+  virtual void VisitAssertBoolean(AssertBooleanInstr* instr);
   virtual void VisitAssertSubtype(AssertSubtypeInstr* instr);
   virtual void VisitInstanceCall(InstanceCallInstr* instr);
   virtual void VisitPolymorphicInstanceCall(
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index b68ee83..aacaf44 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -171,7 +171,7 @@
 
   const Function& target_func = Function::ZoneHandle(Function::New(
       String::Handle(Symbols::New(thread, "dummy2")),
-      RawFunction::kRegularFunction,
+      FunctionLayout::kRegularFunction,
       /*is_static=*/true,
       /*is_const=*/false,
       /*is_abstract=*/false,
diff --git a/runtime/vm/compiler/backend/typed_data_aot_test.cc b/runtime/vm/compiler/backend/typed_data_aot_test.cc
index 5b0a62d..fd0870f 100644
--- a/runtime/vm/compiler/backend/typed_data_aot_test.cc
+++ b/runtime/vm/compiler/backend/typed_data_aot_test.cc
@@ -191,11 +191,8 @@
   char function_name[1024];
   auto& lib = Library::Handle();
   auto& function = Function::Handle();
-  auto& view = TypedDataView::Handle();
-  auto& arguments = Array::Handle();
-  auto& result = Object::Handle();
 
-  auto run_reverse_list = [&](const char* name, const TypedDataBase& data) {
+  auto check_il = [&](const char* name) {
     // Fill in the template with the [name].
     Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name);
     Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///reverse-%s.dart",
@@ -213,98 +210,19 @@
     // Ensure the IL matches what we expect.
     ILMatcher cursor(flow_graph, entry);
     EXPECT(cursor.TryMatch(expected_il));
-
-    // Compile the graph and attach the code.
-    pipeline.CompileGraphAndAttachFunction();
-
-    // Class ids are numbered from internal/view/external.
-    const classid_t view_cid = data.GetClassId() + 1;
-    ASSERT(RawObject::IsTypedDataViewClassId(view_cid));
-
-    // First and last element are not in the view, i.e.
-    //    view[0:view.length()-1] = data[1:data.length()-2]
-    const intptr_t length_in_bytes =
-        (data.LengthInBytes() - 2 * data.ElementSizeInBytes());
-    view = TypedDataView::New(view_cid, data, data.ElementSizeInBytes(),
-                              length_in_bytes / data.ElementSizeInBytes());
-    ASSERT(data.ElementType() == view.ElementType());
-
-    arguments = Array::New(1);
-    arguments.SetAt(0, view);
-    result = DartEntry::InvokeFunction(function, arguments);
-    EXPECT(result.IsNull());
-
-    // Ensure we didn't deoptimize to unoptimized code.
-    EXPECT(function.unoptimized_code() == Code::null());
   };
 
-  const auto& uint8_list =
-      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16));
-  const auto& uint8c_list =
-      TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16));
-  const auto& int16_list =
-      TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16));
-  const auto& uint16_list =
-      TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16));
-  const auto& int32_list =
-      TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16));
-  const auto& uint32_list =
-      TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16));
-  const auto& int64_list =
-      TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16));
-  const auto& uint64_list =
-      TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16));
-  const auto& float32_list =
-      TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16));
-  const auto& float64_list =
-      TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16));
-  const auto& int8_list =
-      TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16));
-  for (intptr_t i = 0; i < 16; ++i) {
-    int8_list.SetInt8(i, i);
-    uint8_list.SetUint8(i, i);
-    uint8c_list.SetUint8(i, i);
-    int16_list.SetInt16(2 * i, i);
-    uint16_list.SetUint16(2 * i, i);
-    int32_list.SetInt32(4 * i, i);
-    uint32_list.SetUint32(4 * i, i);
-    int64_list.SetInt64(8 * i, i);
-    uint64_list.SetUint64(8 * i, i);
-    float32_list.SetFloat32(4 * i, i + 0.5);
-    float64_list.SetFloat64(8 * i, i + 0.7);
-  }
-  run_reverse_list("Uint8List", int8_list);
-  run_reverse_list("Int8List", uint8_list);
-  run_reverse_list("Uint8ClampedList", uint8c_list);
-  run_reverse_list("Int16List", int16_list);
-  run_reverse_list("Uint16List", uint16_list);
-  run_reverse_list("Int32List", int32_list);
-  run_reverse_list("Uint32List", uint32_list);
-  run_reverse_list("Int64List", int64_list);
-  run_reverse_list("Uint64List", uint64_list);
-  run_reverse_list("Float32List", float32_list);
-  run_reverse_list("Float64List", float64_list);
-  for (intptr_t i = 0; i < 16; ++i) {
-    // Only the values in the view are reversed.
-    const bool in_view = i >= 1 && i < 15;
-
-    const int64_t expected_value = in_view ? (16 - i - 1) : i;
-    const uint64_t expected_uvalue = in_view ? (16 - i - 1) : i;
-    const float expected_fvalue = (in_view ? (16 - i - 1) : i) + 0.5;
-    const double expected_dvalue = (in_view ? (16 - i - 1) : i) + 0.7;
-
-    EXPECT(int8_list.GetInt8(i) == expected_value);
-    EXPECT(uint8_list.GetUint8(i) == expected_uvalue);
-    EXPECT(uint8c_list.GetUint8(i) == expected_uvalue);
-    EXPECT(int16_list.GetInt16(2 * i) == expected_value);
-    EXPECT(uint16_list.GetUint16(2 * i) == expected_uvalue);
-    EXPECT(int32_list.GetInt32(4 * i) == expected_value);
-    EXPECT(uint32_list.GetUint32(4 * i) == expected_uvalue);
-    EXPECT(int64_list.GetInt64(8 * i) == expected_value);
-    EXPECT(uint64_list.GetUint64(8 * i) == expected_uvalue);
-    EXPECT(float32_list.GetFloat32(4 * i) == expected_fvalue);
-    EXPECT(float64_list.GetFloat64(8 * i) == expected_dvalue);
-  }
+  check_il("Uint8List");
+  check_il("Int8List");
+  check_il("Uint8ClampedList");
+  check_il("Int16List");
+  check_il("Uint16List");
+  check_il("Int32List");
+  check_il("Uint32List");
+  check_il("Int64List");
+  check_il("Uint64List");
+  check_il("Float32List");
+  check_il("Float64List");
 }
 
 // This test asserts that we get errors if receiver, index or value are null.
diff --git a/runtime/vm/compiler/backend/yield_position_test.cc b/runtime/vm/compiler/backend/yield_position_test.cc
index 7707468..a32bb74 100644
--- a/runtime/vm/compiler/backend/yield_position_test.cc
+++ b/runtime/vm/compiler/backend/yield_position_test.cc
@@ -26,7 +26,7 @@
     while (!it.Done()) {
       if (auto return_instr = it.Current()->AsReturn()) {
         if (return_instr->yield_index() !=
-            RawPcDescriptors::kInvalidYieldIndex) {
+            PcDescriptorsLayout::kInvalidYieldIndex) {
           ASSERT(return_instr->yield_index() > 0);
           array->Add(
               Pair(return_instr->yield_index(), return_instr->token_pos()));
@@ -42,9 +42,9 @@
 static YieldPoints* GetYieldPointsFromCode(const Code& code) {
   auto array = new YieldPoints();
   const auto& pc_descriptor = PcDescriptors::Handle(code.pc_descriptors());
-  PcDescriptors::Iterator it(pc_descriptor, RawPcDescriptors::kOther);
+  PcDescriptors::Iterator it(pc_descriptor, PcDescriptorsLayout::kOther);
   while (it.MoveNext()) {
-    if (it.YieldIndex() != RawPcDescriptors::kInvalidYieldIndex) {
+    if (it.YieldIndex() != PcDescriptorsLayout::kInvalidYieldIndex) {
       array->Add(Pair(it.YieldIndex(), it.TokenPos()));
     }
   }
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index e074143..750c41d 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -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.
 
-#ifndef DART_PRECOMPILED_RUNTIME
 #include "vm/compiler/call_specializer.h"
 
 #include "vm/compiler/backend/flow_graph_compiler.h"
@@ -742,16 +741,12 @@
   if (field.needs_load_guard()) {
     return false;
   }
-  if (field.is_late()) {
-    // TODO(http://dartbug.com/40447): Inline implicit getters for late fields.
-    return false;
-  }
   if (should_clone_fields_) {
     field = field.CloneFromOriginal();
   }
 
-  switch (
-      flow_graph()->CheckForInstanceCall(call, RawFunction::kImplicitGetter)) {
+  switch (flow_graph()->CheckForInstanceCall(call,
+                                             FunctionLayout::kImplicitGetter)) {
     case FlowGraph::ToCheck::kCheckNull:
       AddCheckNull(call->Receiver(), call->function_name(), call->deopt_id(),
                    call->env(), call);
@@ -771,9 +766,19 @@
 
 void CallSpecializer::InlineImplicitInstanceGetter(Definition* call,
                                                    const Field& field) {
+  ASSERT(field.is_instance());
+  Definition* receiver = call->ArgumentAt(0);
+
+  if (field.NeedsInitializationCheckOnLoad()) {
+    InsertBefore(call,
+                 new (Z) InitInstanceFieldInstr(new (Z) Value(receiver), field,
+                                                call->deopt_id()),
+                 call->env(), FlowGraph::kEffect);
+  }
+
   const Slot& slot = Slot::Get(field, &flow_graph()->parsed_function());
-  LoadFieldInstr* load = new (Z) LoadFieldInstr(
-      new (Z) Value(call->ArgumentAt(0)), slot, call->token_pos());
+  LoadFieldInstr* load =
+      new (Z) LoadFieldInstr(new (Z) Value(receiver), slot, call->token_pos());
 
   // Discard the environment from the original instruction because the load
   // can't deoptimize.
@@ -796,7 +801,7 @@
     return false;
   }
   const Function& target = targets.FirstTarget();
-  if (target.kind() != RawFunction::kImplicitSetter) {
+  if (target.kind() != FunctionLayout::kImplicitSetter) {
     // Non-implicit setter are inlined like normal method calls.
     return false;
   }
@@ -806,8 +811,8 @@
     field = field.CloneFromOriginal();
   }
 
-  switch (
-      flow_graph()->CheckForInstanceCall(instr, RawFunction::kImplicitSetter)) {
+  switch (flow_graph()->CheckForInstanceCall(instr,
+                                             FunctionLayout::kImplicitSetter)) {
     case FlowGraph::ToCheck::kCheckNull:
       AddCheckNull(instr->Receiver(), instr->function_name(), instr->deopt_id(),
                    instr->env(), instr);
@@ -862,7 +867,7 @@
 
   // Build an AssertAssignable if necessary.
   const AbstractType& dst_type = AbstractType::ZoneHandle(zone(), field.type());
-  if (I->argument_type_checks() && !dst_type.IsTopTypeForAssignability()) {
+  if (I->argument_type_checks() && !dst_type.IsTopTypeForSubtyping()) {
     // Compute if we need to type check the value. Always type check if
     // at a dynamic invocation.
     bool needs_check = true;
@@ -957,7 +962,7 @@
     return false;
   }
   const Function& target = targets.FirstTarget();
-  if (target.kind() != RawFunction::kImplicitGetter) {
+  if (target.kind() != FunctionLayout::kImplicitGetter) {
     // Non-implicit getters are inlined like normal methods by conventional
     // inlining in FlowGraphInliner.
     return false;
@@ -1064,7 +1069,7 @@
 // (ic_data.NumberOfChecks() * 2) entries
 // An instance-of test returning all same results can be converted to a class
 // check.
-RawBool* CallSpecializer::InstanceOfAsBool(
+BoolPtr CallSpecializer::InstanceOfAsBool(
     const ICData& ic_data,
     const AbstractType& type,
     ZoneGrowableArray<intptr_t>* results) const {
@@ -1110,7 +1115,8 @@
       const AbstractType& unwrapped_type =
           AbstractType::Handle(type.UnwrapFutureOr());
       ASSERT(unwrapped_type.IsInstantiated());
-      is_subtype = unwrapped_type.IsTopType() || unwrapped_type.IsNullable() ||
+      is_subtype = unwrapped_type.IsTopTypeForInstanceOf() ||
+                   unwrapped_type.IsNullable() ||
                    (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType());
     } else {
       is_subtype =
@@ -1178,7 +1184,8 @@
       return false;
     }
   }
-  if (type.IsNullable() || type.IsTopType() || type.IsNeverType()) {
+  if (type.IsNullable() || type.IsTopTypeForInstanceOf() ||
+      type.IsNeverType()) {
     // A class id check is not sufficient, since a null instance also satisfies
     // the test against a nullable type.
     // TODO(regis): Add a null check in addition to the class id check?
@@ -1534,9 +1541,8 @@
     // instances of the [implementor_].
     if (implementor_.is_finalized()) {
       const classid_t cid = implementor_.id();
-      if (!RawObject::IsTypedDataClassId(cid) &&
-          !RawObject::IsTypedDataViewClassId(cid) &&
-          !RawObject::IsExternalTypedDataClassId(cid)) {
+      if (!IsTypedDataClassId(cid) && !IsTypedDataViewClassId(cid) &&
+          !IsExternalTypedDataClassId(cid)) {
         return true;
       }
     }
@@ -1794,4 +1800,3 @@
 }
 
 }  // namespace dart
-#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h
index da606b0..5bb2cb7 100644
--- a/runtime/vm/compiler/call_specializer.h
+++ b/runtime/vm/compiler/call_specializer.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_CALL_SPECIALIZER_H_
 #define RUNTIME_VM_COMPILER_CALL_SPECIALIZER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 
@@ -155,9 +159,9 @@
 
   bool TryInlineImplicitInstanceGetter(InstanceCallInstr* call);
 
-  RawBool* InstanceOfAsBool(const ICData& ic_data,
-                            const AbstractType& type,
-                            ZoneGrowableArray<intptr_t>* results) const;
+  BoolPtr InstanceOfAsBool(const ICData& ic_data,
+                           const AbstractType& type,
+                           ZoneGrowableArray<intptr_t>* results) const;
 
   bool TryOptimizeInstanceOfUsingStaticTypes(InstanceCallInstr* call,
                                              const AbstractType& type);
diff --git a/runtime/vm/compiler/cha.cc b/runtime/vm/compiler/cha.cc
index 53e2480..b7307f6 100644
--- a/runtime/vm/compiler/cha.cc
+++ b/runtime/vm/compiler/cha.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/cha.h"
 #include "vm/class_table.h"
 #include "vm/flags.h"
@@ -173,5 +171,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/cha.h b/runtime/vm/compiler/cha.h
index c132f10..dd1d5b3 100644
--- a/runtime/vm/compiler/cha.h
+++ b/runtime/vm/compiler/cha.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_CHA_H_
 #define RUNTIME_VM_COMPILER_CHA_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/growable_array.h"
 #include "vm/thread.h"
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index ed13b59..9bef093 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -4,8 +4,6 @@
 
 #include "vm/compiler/compiler_pass.h"
 
-#ifndef DART_PRECOMPILED_RUNTIME
-
 #include "vm/compiler/backend/block_scheduler.h"
 #include "vm/compiler/backend/branch_optimizer.h"
 #include "vm/compiler/backend/constant_propagator.h"
@@ -575,5 +573,3 @@
 })
 
 }  // namespace dart
-
-#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index f3333b91..ffda7a6 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_COMPILER_PASS_H_
 #define RUNTIME_VM_COMPILER_COMPILER_PASS_H_
 
-#ifndef DART_PRECOMPILED_RUNTIME
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include <initializer_list>
 
@@ -115,7 +117,7 @@
   };
 
 #define ADD_ONE(name) +1
-  static const intptr_t kNumPasses = 0 COMPILER_PASS_LIST(ADD_ONE);
+  static constexpr intptr_t kNumPasses = 0 COMPILER_PASS_LIST(ADD_ONE);
 #undef ADD_ONE
 
   CompilerPass(Id id, const char* name) : name_(name), flags_(0) {
@@ -201,6 +203,4 @@
 
 }  // namespace dart
 
-#endif
-
 #endif  // RUNTIME_VM_COMPILER_COMPILER_PASS_H_
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index fe2e471..9445dfb 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -28,13 +28,6 @@
   "assembler/assembler_ia32.h",
   "assembler/assembler_x64.cc",
   "assembler/assembler_x64.h",
-  "assembler/disassembler.cc",
-  "assembler/disassembler.h",
-  "assembler/disassembler_arm.cc",
-  "assembler/disassembler_arm64.cc",
-  "assembler/disassembler_kbc.cc",
-  "assembler/disassembler_kbc.h",
-  "assembler/disassembler_x86.cc",
   "assembler/object_pool_builder.h",
   "backend/block_builder.h",
   "backend/block_scheduler.cc",
@@ -112,8 +105,6 @@
   "ffi/native_calling_convention.h",
   "ffi/native_location.cc",
   "ffi/native_location.h",
-  "ffi/native_type.cc",
-  "ffi/native_type.h",
   "ffi/recognized_method.cc",
   "ffi/recognized_method.h",
   "frontend/base_flow_graph_builder.cc",
@@ -150,8 +141,6 @@
   "graph_intrinsifier_x64.cc",
   "intrinsifier.cc",
   "intrinsifier.h",
-  "jit/compiler.cc",
-  "jit/compiler.h",
   "jit/jit_call_specializer.cc",
   "jit/jit_call_specializer.h",
   "method_recognizer.cc",
@@ -159,14 +148,15 @@
   "recognized_methods_list.h",
   "relocation.cc",
   "relocation.h",
-  "runtime_api.cc",
-  "runtime_api.h",
   "stub_code_compiler.cc",
   "stub_code_compiler.h",
   "stub_code_compiler_arm.cc",
   "stub_code_compiler_arm64.cc",
   "stub_code_compiler_ia32.cc",
   "stub_code_compiler_x64.cc",
+  "type_testing_stubs_arm.cc",
+  "type_testing_stubs_arm64.cc",
+  "type_testing_stubs_x64.cc",
   "write_barrier_elimination.cc",
   "write_barrier_elimination.h",
 ]
@@ -179,6 +169,7 @@
   "assembler/assembler_x64_test.cc",
   "assembler/disassembler_test.cc",
   "backend/bce_test.cc",
+  "backend/constant_propagator_test.cc",
   "backend/il_test.cc",
   "backend/il_test_helper.h",
   "backend/il_test_helper.cc",
@@ -196,3 +187,26 @@
   "cha_test.cc",
   "write_barrier_elimination_test.cc",
 ]
+
+compiler_api_sources = [
+  "api/deopt_id.h",
+  "api/print_filter.cc",
+  "api/print_filter.h",
+  "api/type_check_mode.h",
+  "ffi/native_type.cc",
+  "ffi/native_type.h",
+  "jit/compiler.cc",
+  "jit/compiler.h",
+  "runtime_api.cc",
+  "runtime_api.h",
+]
+
+disassembler_sources = [
+  "assembler/disassembler.cc",
+  "assembler/disassembler.h",
+  "assembler/disassembler_arm.cc",
+  "assembler/disassembler_arm64.cc",
+  "assembler/disassembler_kbc.cc",
+  "assembler/disassembler_kbc.h",
+  "assembler/disassembler_x86.cc",
+]
diff --git a/runtime/vm/compiler/compiler_state.cc b/runtime/vm/compiler/compiler_state.cc
index 47407f5..cdf77e6 100644
--- a/runtime/vm/compiler/compiler_state.cc
+++ b/runtime/vm/compiler/compiler_state.cc
@@ -3,12 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/compiler/compiler_state.h"
-#include "vm/growable_array.h"
-
-#ifndef DART_PRECOMPILED_RUNTIME
 
 #include <functional>
 
+#include "vm/compiler/backend/slot.h"
+#include "vm/growable_array.h"
 #include "vm/scopes.h"
 
 namespace dart {
@@ -72,5 +71,3 @@
 }
 
 }  // namespace dart
-
-#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/compiler_state.h b/runtime/vm/compiler/compiler_state.h
index 4b3a590..9baaceb 100644
--- a/runtime/vm/compiler/compiler_state.h
+++ b/runtime/vm/compiler/compiler_state.h
@@ -5,6 +5,11 @@
 #ifndef RUNTIME_VM_COMPILER_COMPILER_STATE_H_
 #define RUNTIME_VM_COMPILER_COMPILER_STATE_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/api/deopt_id.h"
 #include "vm/compiler/cha.h"
 #include "vm/heap/safepoint.h"
 #include "vm/thread.h"
@@ -16,44 +21,6 @@
 class SlotCache;
 class Slot;
 
-// Deoptimization Id logic.
-//
-// Deoptimization ids are used to refer to deoptimization points, at which
-// control can enter unoptimized code from the optimized version of the code.
-//
-// Note: any instruction that does a call has two deoptimization points,
-// one before the call and one after the call - so that we could deoptimize
-// to either before or after the call depending on whether the same call
-// already occured in the optimized code (and potentially produced
-// observable side-effects) or not.
-//
-// To simplify implementation we always allocate two deopt ids (one for before
-// point and one for the after point).
-class DeoptId : public AllStatic {
- public:
-  static constexpr intptr_t kNone = -1;
-
-  static inline intptr_t Next(intptr_t deopt_id) { return deopt_id + kStep; }
-
-  static inline intptr_t ToDeoptAfter(intptr_t deopt_id) {
-    ASSERT(IsDeoptBefore(deopt_id));
-    return deopt_id + kAfterOffset;
-  }
-
-  static inline bool IsDeoptBefore(intptr_t deopt_id) {
-    return (deopt_id % kStep) == kBeforeOffset;
-  }
-
-  static inline bool IsDeoptAfter(intptr_t deopt_id) {
-    return (deopt_id % kStep) == kAfterOffset;
-  }
-
- private:
-  static constexpr intptr_t kStep = 2;
-  static constexpr intptr_t kBeforeOffset = 0;
-  static constexpr intptr_t kAfterOffset = 1;
-};
-
 // Global compiler state attached to the thread.
 class CompilerState : public ThreadStackResource {
  public:
diff --git a/runtime/vm/compiler/ffi/abi.h b/runtime/vm/compiler/ffi/abi.h
index 623374f..fb6f937 100644
--- a/runtime/vm/compiler/ffi/abi.h
+++ b/runtime/vm/compiler/ffi/abi.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_ABI_H_
 #define RUNTIME_VM_COMPILER_FFI_ABI_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <platform/globals.h>
 
 namespace dart {
diff --git a/runtime/vm/compiler/ffi/call.cc b/runtime/vm/compiler/ffi/call.cc
index b13af64..5cb1598 100644
--- a/runtime/vm/compiler/ffi/call.cc
+++ b/runtime/vm/compiler/ffi/call.cc
@@ -12,18 +12,16 @@
 
 namespace ffi {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 // TODO(dartbug.com/36607): Cache the trampolines.
-RawFunction* TrampolineFunction(const Function& dart_signature,
-                                const Function& c_signature) {
+FunctionPtr TrampolineFunction(const Function& dart_signature,
+                               const Function& c_signature) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline"));
   const Library& lib = Library::Handle(zone, Library::FfiLibrary());
   const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
   Function& function =
-      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+      Function::Handle(zone, Function::New(name, FunctionLayout::kFfiTrampoline,
                                            /*is_static=*/true,
                                            /*is_const=*/false,
                                            /*is_abstract=*/false,
@@ -55,8 +53,6 @@
   return function.raw();
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/call.h b/runtime/vm/compiler/ffi/call.h
index 3680481..050b1d8 100644
--- a/runtime/vm/compiler/ffi/call.h
+++ b/runtime/vm/compiler/ffi/call.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_CALL_H_
 #define RUNTIME_VM_COMPILER_FFI_CALL_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <platform/globals.h>
 
 #include "vm/raw_object.h"
@@ -15,8 +19,8 @@
 
 namespace ffi {
 
-RawFunction* TrampolineFunction(const Function& dart_signature,
-                                const Function& c_signature);
+FunctionPtr TrampolineFunction(const Function& dart_signature,
+                               const Function& c_signature);
 
 }  // namespace ffi
 
diff --git a/runtime/vm/compiler/ffi/callback.cc b/runtime/vm/compiler/ffi/callback.cc
index 94abfb8..8d1fe95 100644
--- a/runtime/vm/compiler/ffi/callback.cc
+++ b/runtime/vm/compiler/ffi/callback.cc
@@ -12,11 +12,9 @@
 
 namespace ffi {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
-RawFunction* NativeCallbackFunction(const Function& c_signature,
-                                    const Function& dart_target,
-                                    const Instance& exceptional_return) {
+FunctionPtr NativeCallbackFunction(const Function& c_signature,
+                                   const Function& dart_target,
+                                   const Instance& exceptional_return) {
   Thread* const thread = Thread::Current();
   const int32_t callback_id = thread->AllocateFfiCallbackId();
 
@@ -30,7 +28,7 @@
   const Library& lib = Library::Handle(zone, Library::FfiLibrary());
   const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
   const Function& function =
-      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+      Function::Handle(zone, Function::New(name, FunctionLayout::kFfiTrampoline,
                                            /*is_static=*/true,
                                            /*is_const=*/false,
                                            /*is_abstract=*/false,
@@ -66,8 +64,6 @@
   return function.raw();
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/callback.h b/runtime/vm/compiler/ffi/callback.h
index ff432e6..265143e 100644
--- a/runtime/vm/compiler/ffi/callback.h
+++ b/runtime/vm/compiler/ffi/callback.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_CALLBACK_H_
 #define RUNTIME_VM_COMPILER_FFI_CALLBACK_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <platform/globals.h>
 
 #include "vm/raw_object.h"
@@ -15,9 +19,9 @@
 
 namespace ffi {
 
-RawFunction* NativeCallbackFunction(const Function& c_signature,
-                                    const Function& dart_target,
-                                    const Instance& exceptional_return);
+FunctionPtr NativeCallbackFunction(const Function& c_signature,
+                                   const Function& dart_target,
+                                   const Instance& exceptional_return);
 
 }  // namespace ffi
 
diff --git a/runtime/vm/compiler/ffi/frame_rebase.cc b/runtime/vm/compiler/ffi/frame_rebase.cc
index cc12a56..ee035ac 100644
--- a/runtime/vm/compiler/ffi/frame_rebase.cc
+++ b/runtime/vm/compiler/ffi/frame_rebase.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/ffi/frame_rebase.h"
 
 namespace dart {
@@ -47,5 +45,3 @@
 }  // namespace compiler
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/ffi/frame_rebase.h b/runtime/vm/compiler/ffi/frame_rebase.h
index 33d8683..ba58a5c 100644
--- a/runtime/vm/compiler/ffi/frame_rebase.h
+++ b/runtime/vm/compiler/ffi/frame_rebase.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_FRAME_REBASE_H_
 #define RUNTIME_VM_COMPILER_FFI_FRAME_REBASE_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/ffi/native_location.h"
 #include "vm/compiler/ffi/native_type.h"
diff --git a/runtime/vm/compiler/ffi/marshaller.cc b/runtime/vm/compiler/ffi/marshaller.cc
index 53d1e21..009e031 100644
--- a/runtime/vm/compiler/ffi/marshaller.cc
+++ b/runtime/vm/compiler/ffi/marshaller.cc
@@ -17,8 +17,6 @@
 
 namespace ffi {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 Location CallMarshaller::LocInFfiCall(intptr_t arg_index) const {
   if (arg_index == kResultIndex) {
     return Location(arg_index).AsLocation();
@@ -154,8 +152,6 @@
           CallbackArgumentTranslator::TranslateArgumentLocations(arg_locs_,
                                                                  zone_)) {}
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/marshaller.h b/runtime/vm/compiler/ffi/marshaller.h
index 19009bb..d8d4647 100644
--- a/runtime/vm/compiler/ffi/marshaller.h
+++ b/runtime/vm/compiler/ffi/marshaller.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
 #define RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <platform/globals.h>
 
 #include "vm/compiler/backend/locations.h"
@@ -70,7 +74,7 @@
            kFfiVoidCid;
   }
 
-  RawString* function_name() const { return dart_signature_.name(); }
+  StringPtr function_name() const { return dart_signature_.name(); }
 
  protected:
   BaseMarshaller(Zone* zone, const Function& dart_signature)
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc
index 13b01f3..56e4690 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.cc
+++ b/runtime/vm/compiler/ffi/native_calling_convention.cc
@@ -16,8 +16,6 @@
 
 namespace ffi {
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 // Argument #0 is the function pointer.
 const intptr_t kNativeParamsStartAt = 1;
 
@@ -133,6 +131,7 @@
   }
 
   Register AllocateCpuRegister() {
+    RELEASE_ASSERT(cpu_regs_used >= 0);  // Avoids -Werror=array-bounds in GCC.
     ASSERT(cpu_regs_used < CallingConventions::kNumArgRegs);
 
     const auto result = CallingConventions::ArgumentRegisters[cpu_regs_used];
@@ -281,7 +280,7 @@
   return c_signature_.num_fixed_parameters() - kNativeParamsStartAt;
 }
 
-RawAbstractType* NativeCallingConvention::CType(intptr_t arg_index) const {
+AbstractTypePtr NativeCallingConvention::CType(intptr_t arg_index) const {
   if (arg_index == kResultIndex) {
     return c_signature_.result_type();
   }
@@ -303,8 +302,6 @@
   return Utils::RoundUp(max_height_in_bytes, compiler::target::kWordSize);
 }
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.h b/runtime/vm/compiler/ffi/native_calling_convention.h
index 459be7f..5eae152 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.h
+++ b/runtime/vm/compiler/ffi/native_calling_convention.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_CALLING_CONVENTION_H_
 #define RUNTIME_VM_COMPILER_FFI_NATIVE_CALLING_CONVENTION_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <platform/globals.h>
 
 #include "vm/compiler/backend/locations.h"
@@ -38,7 +42,7 @@
   // The C Type (expressed in a Dart Type) of the argument at `arg_index`.
   //
   // Excluding the #0 argument which is the function pointer.
-  RawAbstractType* CType(intptr_t arg_index) const;
+  AbstractTypePtr CType(intptr_t arg_index) const;
 
   // The location of the argument at `arg_index`.
   const NativeLocation& Location(intptr_t arg_index) const {
diff --git a/runtime/vm/compiler/ffi/native_location.cc b/runtime/vm/compiler/ffi/native_location.cc
index 918f341..0c7fb16 100644
--- a/runtime/vm/compiler/ffi/native_location.cc
+++ b/runtime/vm/compiler/ffi/native_location.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/ffi/native_location.h"
 
 #include "vm/compiler/backend/il_printer.h"
@@ -307,6 +305,7 @@
     case kSingleFpuReg:
       return DRegisterOf(fpu_s_reg());
   }
+  UNREACHABLE();
 }
 
 SRegister NativeFpuRegistersLocation::fpu_as_s_reg() const {
@@ -318,6 +317,7 @@
     case kSingleFpuReg:
       return fpu_s_reg();
   }
+  UNREACHABLE();
 }
 
 bool NativeFpuRegistersLocation::IsLowestBits() const {
@@ -340,5 +340,3 @@
 }  // namespace compiler
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/ffi/native_location.h b/runtime/vm/compiler/ffi/native_location.h
index a50872f..7db24e6 100644
--- a/runtime/vm/compiler/ffi/native_location.h
+++ b/runtime/vm/compiler/ffi/native_location.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_LOCATION_H_
 #define RUNTIME_VM_COMPILER_FFI_NATIVE_LOCATION_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/ffi/native_type.h"
 #include "vm/growable_array.h"
diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc
index e69380c..d06d73f 100644
--- a/runtime/vm/compiler/ffi/native_type.cc
+++ b/runtime/vm/compiler/ffi/native_type.cc
@@ -6,10 +6,13 @@
 
 #include "platform/assert.h"
 #include "platform/globals.h"
-#include "vm/compiler/backend/locations.h"
 #include "vm/compiler/runtime_api.h"
 #include "vm/object.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/backend/locations.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 namespace compiler {
@@ -100,8 +103,9 @@
     case kAlignedToValueSize:
       // iOS on arm64 only aligns to size.
       return SizeInBytes();
+    default:
+      UNREACHABLE();
   }
-  UNREACHABLE();
 }
 
 intptr_t NativeFundamentalType::AlignmentInBytesField() const {
@@ -117,10 +121,12 @@
       }
       return SizeInBytes();
     }
+    default:
+      UNREACHABLE();
   }
-  UNREACHABLE();
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 bool NativeFundamentalType::IsExpressibleAsRepresentation() const {
   switch (representation_) {
     case kInt8:
@@ -163,6 +169,7 @@
       UNREACHABLE();
   }
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 bool NativeFundamentalType::Equals(const NativeType& other) const {
   if (!other.IsFundamental()) {
@@ -242,6 +249,7 @@
   return NativeType::FromTypedDataClassId(type.type_class_id(), zone);
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 static FundamentalType fundamental_rep(Representation rep) {
   switch (rep) {
     case kUnboxedDouble:
@@ -264,6 +272,7 @@
                                                              Zone* zone) {
   return *new (zone) NativeFundamentalType(fundamental_rep(rep));
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 const char* NativeType::ToCString() const {
   char buffer[1024];
diff --git a/runtime/vm/compiler/ffi/native_type.h b/runtime/vm/compiler/ffi/native_type.h
index ddd6941..0eee4de 100644
--- a/runtime/vm/compiler/ffi/native_type.h
+++ b/runtime/vm/compiler/ffi/native_type.h
@@ -9,11 +9,16 @@
 
 #include "platform/assert.h"
 #include "vm/allocation.h"
-#include "vm/compiler/backend/locations.h"
 #include "vm/compiler/runtime_api.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/backend/locations.h"
+#endif
+
 namespace dart {
 
+class BufferFormatter;
+
 namespace compiler {
 
 namespace ffi {
@@ -31,7 +36,7 @@
 // * tagged
 // * untagged
 //
-// Instead, NativeTypes support representations not supprted in Dart's unboxed
+// Instead, NativeTypes support representations not supported in Dart's unboxed
 // Representations, such as:
 // * Fundamental types (https://en.cppreference.com/w/cpp/language/types):
 //   * int8_t
@@ -48,8 +53,11 @@
  public:
   static NativeType& FromAbstractType(const AbstractType& type, Zone* zone);
   static NativeType& FromTypedDataClassId(classid_t class_id, Zone* zone);
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
   static NativeFundamentalType& FromUnboxedRepresentation(Representation rep,
                                                           Zone* zone);
+#endif
 
   virtual bool IsFundamental() const { return false; }
   const NativeFundamentalType& AsFundamental() const;
@@ -71,6 +79,7 @@
   // The alignment in bytes of this representation as member of a composite.
   virtual intptr_t AlignmentInBytesField() const = 0;
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   // NativeTypes which are available as unboxed Representations.
   virtual bool IsExpressibleAsRepresentation() const { return false; }
 
@@ -82,6 +91,7 @@
     const auto& widened = WidenTo4Bytes(zone_);
     return widened.AsRepresentation();
   }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   virtual bool Equals(const NativeType& other) const { UNREACHABLE(); }
 
@@ -135,8 +145,10 @@
   virtual intptr_t AlignmentInBytesStack() const;
   virtual intptr_t AlignmentInBytesField() const;
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   virtual bool IsExpressibleAsRepresentation() const;
   virtual Representation AsRepresentation() const;
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   virtual bool Equals(const NativeType& other) const;
   virtual NativeFundamentalType& Split(intptr_t part, Zone* zone) const;
diff --git a/runtime/vm/compiler/ffi/recognized_method.h b/runtime/vm/compiler/ffi/recognized_method.h
index 0bd7dab..8cbfca8 100644
--- a/runtime/vm/compiler/ffi/recognized_method.h
+++ b/runtime/vm/compiler/ffi/recognized_method.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_RECOGNIZED_METHOD_H_
 #define RUNTIME_VM_COMPILER_FFI_RECOGNIZED_METHOD_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <platform/globals.h>
 
 #include "vm/compiler/method_recognizer.h"
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index c306430..67faab3 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -11,8 +11,6 @@
 #include "vm/growable_array.h"
 #include "vm/object_store.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -823,7 +821,8 @@
   JoinEntryInstr* nsm = BuildJoinEntry();
 
   Fragment failing(nsm);
-  const Code& nsm_handler = StubCode::CallClosureNoSuchMethod();
+  const Code& nsm_handler = Code::ZoneHandle(
+      Z, I->object_store()->call_closure_no_such_method_stub());
   failing += LoadArgDescriptor();
   failing += TailCall(nsm_handler);
 
@@ -972,7 +971,7 @@
   return Fragment();
 #else
   return Fragment(new (Z) DebugStepCheckInstr(
-      position, RawPcDescriptors::kRuntimeCall, GetNextDeoptId()));
+      position, PcDescriptorsLayout::kRuntimeCall, GetNextDeoptId()));
 #endif
 }
 
@@ -1145,5 +1144,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 8fed8b0..e4ebf61 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -5,14 +5,16 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_BASE_FLOW_GRAPH_BUILDER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_BASE_FLOW_GRAPH_BUILDER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include <initializer_list>
 
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/il.h"
 #include "vm/object.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 
 class InlineExitCollector;
@@ -275,8 +277,9 @@
                          bool negate = false);
   Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry,
                                TargetEntryInstr** otherwise_entry);
-  Fragment Return(TokenPosition position,
-                  intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+  Fragment Return(
+      TokenPosition position,
+      intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
   Fragment CheckStackOverflow(TokenPosition position,
                               intptr_t stack_depth,
                               intptr_t loop_depth);
@@ -451,5 +454,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_BASE_FLOW_GRAPH_BUILDER_H_
diff --git a/runtime/vm/compiler/frontend/bytecode_fingerprints.cc b/runtime/vm/compiler/frontend/bytecode_fingerprints.cc
index 8a42a1e..78d621e 100644
--- a/runtime/vm/compiler/frontend/bytecode_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/bytecode_fingerprints.cc
@@ -8,8 +8,6 @@
 #include "vm/constants_kbc.h"
 #include "vm/hash.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -207,5 +205,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_fingerprints.h b/runtime/vm/compiler/frontend/bytecode_fingerprints.h
index ea79a92..78dbcff 100644
--- a/runtime/vm/compiler/frontend/bytecode_fingerprints.h
+++ b/runtime/vm/compiler/frontend/bytecode_fingerprints.h
@@ -5,11 +5,13 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "platform/allocation.h"
 #include "vm/object.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -21,5 +23,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 1d16d3b..23dcf66 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -13,8 +13,6 @@
 #include "vm/stack_frame.h"
 #include "vm/stack_frame_kbc.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #define B (flow_graph_builder_)
 #define Z (zone_)
 
@@ -1639,7 +1637,7 @@
   BuildDebugStepCheck();
   LoadStackSlots(1);
   ASSERT(code_.is_open());
-  intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex;
+  intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex;
   if (function().IsAsyncClosure() || function().IsAsyncGenClosure()) {
     if (pc_ == last_yield_point_pc_) {
       // The return might actually be a yield point, if so we need to attach the
@@ -1960,7 +1958,7 @@
                                                intptr_t pc) {
   const uword pc_offset =
       KernelBytecode::BytecodePcToOffset(pc, /* is_return_address = */ true);
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   intptr_t try_index = kInvalidTryIndex;
   while (iter.MoveNext()) {
     const intptr_t current_try_index = iter.TryIndex();
@@ -2052,7 +2050,7 @@
     pc += (KernelBytecode::Next(instr) - instr);
   }
 
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     const intptr_t start_pc = KernelBytecode::OffsetToBytecodePc(
         iter.PcOffset(), /* is_return_address = */ true);
@@ -2348,5 +2346,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index 822a55e..c98d743 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -5,13 +5,15 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/il.h"
 #include "vm/compiler/frontend/base_flow_graph_builder.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"  // For InferredTypeMetadata
 #include "vm/constants_kbc.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -247,5 +249,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index d0381e0..9295cb6 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -24,8 +24,6 @@
 #include "vm/stack_frame_kbc.h"
 #include "vm/timeline.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #define Z (zone_)
 #define H (translation_helper_)
 #define I (translation_helper_.isolate())
@@ -125,7 +123,7 @@
   return true;
 }
 
-RawLibrary* BytecodeMetadataHelper::GetMainLibrary() {
+LibraryPtr BytecodeMetadataHelper::GetMainLibrary() {
   const intptr_t md_offset = GetComponentMetadataPayloadOffset();
   if (md_offset < 0) {
     return Library::null();
@@ -143,8 +141,8 @@
   return bytecode_reader.ReadMain();
 }
 
-RawArray* BytecodeMetadataHelper::GetBytecodeComponent() {
-  RawArray* array = translation_helper_.GetBytecodeComponent();
+ArrayPtr BytecodeMetadataHelper::GetBytecodeComponent() {
+  ArrayPtr array = translation_helper_.GetBytecodeComponent();
   if (array == Array::null()) {
     array = ReadBytecodeComponent();
     ASSERT(array != Array::null());
@@ -152,7 +150,7 @@
   return array;
 }
 
-RawArray* BytecodeMetadataHelper::ReadBytecodeComponent() {
+ArrayPtr BytecodeMetadataHelper::ReadBytecodeComponent() {
   const intptr_t md_offset = GetComponentMetadataPayloadOffset();
   if (md_offset < 0) {
     return Array::null();
@@ -211,10 +209,15 @@
     intptr_t num_params = reader_.ReadUInt();
     ASSERT(num_params ==
            function.NumParameters() - function.NumImplicitParameters());
-    for (intptr_t i = 0; i < num_params; ++i) {
-      reader_.ReadUInt();
+    for (intptr_t i = function.NumImplicitParameters();
+         i < function.NumParameters(); ++i) {
+      const intptr_t flags = reader_.ReadUInt();
+      if ((flags & Parameter::kIsRequiredFlag) != 0) {
+        function.SetIsRequiredAt(i);
+      }
     }
   }
+  function.TruncateUnusedParameterFlags();
   if (has_forwarding_stub_target) {
     reader_.ReadUInt();
   }
@@ -340,9 +343,8 @@
   return -1;
 }
 
-RawArray* BytecodeReaderHelper::CreateForwarderChecks(
-    const Function& function) {
-  ASSERT(function.kind() != RawFunction::kDynamicInvocationForwarder);
+ArrayPtr BytecodeReaderHelper::CreateForwarderChecks(const Function& function) {
+  ASSERT(function.kind() != FunctionLayout::kDynamicInvocationForwarder);
   ASSERT(function.is_declared_in_bytecode());
 
   TypeArguments& default_args = TypeArguments::Handle(Z);
@@ -393,7 +395,8 @@
     for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) {
       type_param ^= type_params.TypeAt(i);
       bound = type_param.bound();
-      if (!bound.IsTopType() && !type_param.IsGenericCovariantImpl()) {
+      if (!bound.IsTopTypeForSubtyping() &&
+          !type_param.IsGenericCovariantImpl()) {
         name = type_param.name();
         ASSERT(type_param.IsFinalized());
         check = ParameterTypeCheck::New();
@@ -419,7 +422,7 @@
   const bool has_optional_parameters = function.HasOptionalParameters();
   for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
     type = function.ParameterTypeAt(i);
-    if (!type.IsTopTypeForAssignability() &&
+    if (!type.IsTopTypeForSubtyping() &&
         !is_generic_covariant_impl.Contains(i) && !is_covariant.Contains(i)) {
       name = function.ParameterNameAt(i);
       intptr_t index;
@@ -459,13 +462,14 @@
   const int kIsSyncStarFlag = 1 << 6;
   const int kIsDebuggableFlag = 1 << 7;
   const int kHasAttributesFlag = 1 << 8;
+  const int kHasParameterFlagsFlag = 1 << 9;
 
   const intptr_t flags = reader_.ReadUInt();
 
   Object& parent = Object::Handle(Z, ReadObject());
   if (!parent.IsFunction()) {
     ASSERT(parent.IsField());
-    ASSERT(function.kind() == RawFunction::kFieldInitializer);
+    ASSERT(function.kind() == FunctionLayout::kFieldInitializer);
     // Closure in a static field initializer, so use current function as parent.
     parent = function.raw();
   }
@@ -487,13 +491,13 @@
   closure.set_end_token_pos(end_position);
 
   if ((flags & kIsSyncStarFlag) != 0) {
-    closure.set_modifier(RawFunction::kSyncGen);
+    closure.set_modifier(FunctionLayout::kSyncGen);
   } else if ((flags & kIsAsyncFlag) != 0) {
-    closure.set_modifier(RawFunction::kAsync);
+    closure.set_modifier(FunctionLayout::kAsync);
     closure.set_is_inlinable(!FLAG_causal_async_stacks &&
                              !FLAG_lazy_async_stacks);
   } else if ((flags & kIsAsyncStarFlag) != 0) {
-    closure.set_modifier(RawFunction::kAsyncGen);
+    closure.set_modifier(FunctionLayout::kAsyncGen);
     closure.set_is_inlinable(!FLAG_causal_async_stacks &&
                              !FLAG_lazy_async_stacks);
   }
@@ -505,12 +509,12 @@
   closures_->SetAt(closureIndex, closure);
 
   Type& signature_type = Type::Handle(
-      Z, ReadFunctionSignature(closure,
-                               (flags & kHasOptionalPositionalParamsFlag) != 0,
-                               (flags & kHasOptionalNamedParamsFlag) != 0,
-                               (flags & kHasTypeParamsFlag) != 0,
-                               /* has_positional_param_names = */ true,
-                               Nullability::kNonNullable));
+      Z, ReadFunctionSignature(
+             closure, (flags & kHasOptionalPositionalParamsFlag) != 0,
+             (flags & kHasOptionalNamedParamsFlag) != 0,
+             (flags & kHasTypeParamsFlag) != 0,
+             /* has_positional_param_names = */ true,
+             (flags & kHasParameterFlagsFlag) != 0, Nullability::kNonNullable));
 
   closure.SetSignatureType(signature_type);
 
@@ -550,12 +554,13 @@
   return false;
 }
 
-RawType* BytecodeReaderHelper::ReadFunctionSignature(
+TypePtr BytecodeReaderHelper::ReadFunctionSignature(
     const Function& func,
     bool has_optional_positional_params,
     bool has_optional_named_params,
     bool has_type_params,
     bool has_positional_param_names,
+    bool has_parameter_flags,
     Nullability nullability) {
   FunctionTypeScope function_type_scope(this);
 
@@ -577,8 +582,9 @@
   const Array& parameter_types =
       Array::Handle(Z, Array::New(num_params, Heap::kOld));
   func.set_parameter_types(parameter_types);
-  const Array& parameter_names =
-      Array::Handle(Z, Array::New(num_params, Heap::kOld));
+  const Array& parameter_names = Array::Handle(
+      Z, Array::New(Function::NameArrayLengthIncludingFlags(num_params),
+                    Heap::kOld));
   func.set_parameter_names(parameter_names);
 
   intptr_t i = 0;
@@ -599,6 +605,16 @@
     type ^= ReadObject();
     parameter_types.SetAt(i, type);
   }
+  if (has_parameter_flags) {
+    intptr_t num_flags = reader_.ReadUInt();
+    for (intptr_t i = 0; i < num_flags; ++i) {
+      intptr_t flag = reader_.ReadUInt();
+      if ((flag & Parameter::kIsRequiredFlag) != 0) {
+        func.SetIsRequiredAt(kImplicitClosureParam + i);
+      }
+    }
+  }
+  func.TruncateUnusedParameterFlags();
 
   type ^= ReadObject();
   func.set_result_type(type);
@@ -939,7 +955,7 @@
   return obj_count - 1;
 }
 
-RawBytecode* BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) {
+BytecodePtr BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) {
 #if defined(SUPPORT_TIMELINE)
   TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
                     "BytecodeReaderHelper::ReadBytecode");
@@ -1000,14 +1016,14 @@
         handler_type ^= pool.ObjectAt(type_index);
         handler_types.SetAt(i, handler_type);
       }
-      pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, start_pc,
-                                         DeoptId::kNone,
-                                         TokenPosition::kNoSource, try_index,
-                                         RawPcDescriptors::kInvalidYieldIndex);
-      pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, end_pc,
-                                         DeoptId::kNone,
-                                         TokenPosition::kNoSource, try_index,
-                                         RawPcDescriptors::kInvalidYieldIndex);
+      pc_descriptors_list->AddDescriptor(
+          PcDescriptorsLayout::kOther, start_pc, DeoptId::kNone,
+          TokenPosition::kNoSource, try_index,
+          PcDescriptorsLayout::kInvalidYieldIndex);
+      pc_descriptors_list->AddDescriptor(
+          PcDescriptorsLayout::kOther, end_pc, DeoptId::kNone,
+          TokenPosition::kNoSource, try_index,
+          PcDescriptorsLayout::kInvalidYieldIndex);
 
       // The exception handler keeps a zone handle of the types array, rather
       // than a raw pointer. Do not share the handle across iterations to avoid
@@ -1051,8 +1067,8 @@
       bytecode_component_->GetLocalVariablesOffset() + offset);
 }
 
-RawTypedData* BytecodeReaderHelper::NativeEntry(const Function& function,
-                                                const String& external_name) {
+TypedDataPtr BytecodeReaderHelper::NativeEntry(const Function& function,
+                                               const String& external_name) {
   MethodRecognizer::Kind kind = function.recognized_kind();
   // This list of recognized methods must be kept in sync with the list of
   // methods handled specially by the NativeCall bytecode in the interpreter.
@@ -1130,7 +1146,7 @@
   return NativeEntryData::New(kind, trampoline, native_function, argc_tag);
 }
 
-RawArray* BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
+ArrayPtr BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
   ASSERT(Thread::Current()->IsMutatorThread());
 
   AlternativeReadingScope alt(&reader_, md_offset);
@@ -1263,14 +1279,14 @@
   }
 }
 
-RawObject* BytecodeReaderHelper::ReadObject() {
+ObjectPtr BytecodeReaderHelper::ReadObject() {
   uint32_t header = reader_.ReadUInt();
   if ((header & kReferenceBit) != 0) {
     intptr_t index = header >> kIndexShift;
     if (index == 0) {
       return Object::null();
     }
-    RawObject* obj = bytecode_component_->GetObject(index);
+    ObjectPtr obj = bytecode_component_->GetObject(index);
     if (obj->IsHeapObject()) {
       return obj;
     }
@@ -1294,8 +1310,8 @@
   return ReadObjectContents(header);
 }
 
-RawString* BytecodeReaderHelper::ConstructorName(const Class& cls,
-                                                 const String& name) {
+StringPtr BytecodeReaderHelper::ConstructorName(const Class& cls,
+                                                const String& name) {
   GrowableHandlePtrArray<const String> pieces(Z, 3);
   pieces.Add(String::Handle(Z, cls.Name()));
   pieces.Add(Symbols::Dot());
@@ -1303,7 +1319,7 @@
   return Symbols::FromConcatAll(thread_, pieces);
 }
 
-RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
+ObjectPtr BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
   ASSERT(((header & kReferenceBit) == 0));
 
   // Must be in sync with enum ObjectKind in
@@ -1354,7 +1370,7 @@
       break;
     case kLibrary: {
       String& uri = String::CheckedHandle(Z, ReadObject());
-      RawLibrary* library = Library::LookupLibrary(thread_, uri);
+      LibraryPtr library = Library::LookupLibrary(thread_, uri);
       if (library == Library::null()) {
         // We do not register expression evaluation libraries with the VM:
         // The expression evaluation functions should be GC-able as soon as
@@ -1380,13 +1396,13 @@
       const String& class_name = String::CheckedHandle(Z, ReadObject());
       if (class_name.raw() == Symbols::Empty().raw()) {
         NoSafepointScope no_safepoint_scope(thread_);
-        RawClass* cls = library.toplevel_class();
+        ClassPtr cls = library.toplevel_class();
         if (cls == Class::null()) {
           FATAL1("Unable to find toplevel class %s", library.ToCString());
         }
         return cls;
       }
-      RawClass* cls = library.LookupLocalClass(class_name);
+      ClassPtr cls = library.LookupLocalClass(class_name);
       if (cls == Class::null()) {
         if (IsExpressionEvaluationLibrary(library)) {
           return H.GetExpressionEvaluationRealClass();
@@ -1409,7 +1425,7 @@
       const Class& cls = Class::CheckedHandle(Z, ReadObject());
       String& name = String::CheckedHandle(Z, ReadObject());
       if ((flags & kFlagIsField) != 0) {
-        RawField* field = cls.LookupField(name);
+        FieldPtr field = cls.LookupField(name);
         if (field == Field::null()) {
 #if !defined(PRODUCT)
           ASSERT(Isolate::Current()->HasAttemptedReload());
@@ -1432,7 +1448,7 @@
             cls.raw() == scoped_function_class_.raw()) {
           return scoped_function_.raw();
         }
-        RawFunction* function = cls.LookupFunction(name);
+        FunctionPtr function = cls.LookupFunction(name);
         if (function == Function::null()) {
           // When requesting a getter, also return method extractors.
           if (Field::IsGetterName(name)) {
@@ -1540,7 +1556,7 @@
   return Object::null();
 }
 
-RawObject* BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
+ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
   // Must be in sync with enum ConstTag in
   // pkg/vm/lib/bytecode/object_table.dart.
   enum ConstTag {
@@ -1653,8 +1669,8 @@
   return Object::null();
 }
 
-RawObject* BytecodeReaderHelper::ReadType(intptr_t tag,
-                                          Nullability nullability) {
+ObjectPtr BytecodeReaderHelper::ReadType(intptr_t tag,
+                                         Nullability nullability) {
   // Must be in sync with enum TypeTag in
   // pkg/vm/lib/bytecode/object_table.dart.
   enum TypeTag {
@@ -1685,7 +1701,8 @@
     case kVoid:
       return AbstractType::void_type().raw();
     case kNever:
-      return AbstractType::never_type().ToNullability(nullability, Heap::kOld);
+      return Type::Handle(Z, Type::NeverType())
+          .ToNullability(nullability, Heap::kOld);
     case kSimpleType: {
       const Class& cls = Class::CheckedHandle(Z, ReadObject());
       if (!cls.is_declaration_loaded()) {
@@ -1802,7 +1819,8 @@
           signature_function, (flags & kFlagHasOptionalPositionalParams) != 0,
           (flags & kFlagHasOptionalNamedParams) != 0,
           (flags & kFlagHasTypeParams) != 0,
-          /* has_positional_param_names = */ false, nullability);
+          /* has_positional_param_names = */ false,
+          /* has_parameter_flags */ false, nullability);
     }
     default:
       UNREACHABLE();
@@ -1810,7 +1828,7 @@
   return Object::null();
 }
 
-RawString* BytecodeReaderHelper::ReadString(bool is_canonical) {
+StringPtr BytecodeReaderHelper::ReadString(bool is_canonical) {
   const int kFlagTwoByteString = 1;
   const int kHeaderFields = 2;
   const int kUInt32Size = 4;
@@ -1860,8 +1878,8 @@
   }
 }
 
-RawScript* BytecodeReaderHelper::ReadSourceFile(const String& uri,
-                                                intptr_t offset) {
+ScriptPtr BytecodeReaderHelper::ReadSourceFile(const String& uri,
+                                               intptr_t offset) {
   // SourceFile flags, must be in sync with SourceFile constants in
   // pkg/vm/lib/bytecode/declarations.dart.
   const int kHasLineStartsFlag = 1 << 0;
@@ -1903,7 +1921,7 @@
   return script.raw();
 }
 
-RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments() {
+TypeArgumentsPtr BytecodeReaderHelper::ReadTypeArguments() {
   const bool is_recursive = reading_type_arguments_of_recursive_type_;
   reading_type_arguments_of_recursive_type_ = false;
   const intptr_t length = reader_.ReadUInt();
@@ -2054,14 +2072,7 @@
     field.set_is_extension_member(is_extension_member);
     field.set_has_initializer(has_initializer);
 
-    if (has_nontrivial_initializer) {
-      if (field.is_late()) {
-        // Late fields are initialized to Object::sentinel, which is a flavor of
-        // null. So we need to record that store so that the field guard doesn't
-        // prematurely optimise out the late field's sentinel checking logic.
-        field.RecordStore(Object::null_object());
-      }
-    } else {
+    if (!has_nontrivial_initializer) {
       value ^= ReadObject();
       if (is_static) {
         if (field.is_late() && !has_initializer) {
@@ -2097,8 +2108,8 @@
     if ((flags & kHasGetterFlag) != 0) {
       name ^= ReadObject();
       function = Function::New(name,
-                               is_static ? RawFunction::kImplicitStaticGetter
-                                         : RawFunction::kImplicitGetter,
+                               is_static ? FunctionLayout::kImplicitStaticGetter
+                                         : FunctionLayout::kImplicitGetter,
                                is_static, is_const,
                                false,  // is_abstract
                                false,  // is_external
@@ -2121,7 +2132,7 @@
       ASSERT(is_late || ((!is_static) && (!is_final)));
       ASSERT(!is_const);
       name ^= ReadObject();
-      function = Function::New(name, RawFunction::kImplicitSetter, is_static,
+      function = Function::New(name, FunctionLayout::kImplicitSetter, is_static,
                                false,  // is_const
                                false,  // is_abstract
                                false,  // is_external
@@ -2190,8 +2201,8 @@
   }
 }
 
-RawPatchClass* BytecodeReaderHelper::GetPatchClass(const Class& cls,
-                                                   const Script& script) {
+PatchClassPtr BytecodeReaderHelper::GetPatchClass(const Class& cls,
+                                                  const Script& script) {
   if (patch_class_ != nullptr && patch_class_->patched_class() == cls.raw() &&
       patch_class_->script() == script.raw()) {
     return patch_class_->raw();
@@ -2275,13 +2286,13 @@
       end_position = reader_.ReadPosition();
     }
 
-    RawFunction::Kind kind = RawFunction::kRegularFunction;
+    FunctionLayout::Kind kind = FunctionLayout::kRegularFunction;
     if ((flags & kIsGetterFlag) != 0) {
-      kind = RawFunction::kGetterFunction;
+      kind = FunctionLayout::kGetterFunction;
     } else if ((flags & kIsSetterFlag) != 0) {
-      kind = RawFunction::kSetterFunction;
+      kind = FunctionLayout::kSetterFunction;
     } else if ((flags & (kIsConstructorFlag | kIsFactoryFlag)) != 0) {
-      kind = RawFunction::kConstructor;
+      kind = FunctionLayout::kConstructor;
       name = ConstructorName(cls, name);
     }
 
@@ -2316,17 +2327,17 @@
     }
 
     if ((flags & kIsSyncStarFlag) != 0) {
-      function.set_modifier(RawFunction::kSyncGen);
+      function.set_modifier(FunctionLayout::kSyncGen);
       function.set_is_visible(!FLAG_causal_async_stacks &&
                               !FLAG_lazy_async_stacks);
     } else if ((flags & kIsAsyncFlag) != 0) {
-      function.set_modifier(RawFunction::kAsync);
+      function.set_modifier(FunctionLayout::kAsync);
       function.set_is_inlinable(!FLAG_causal_async_stacks &&
                                 !FLAG_lazy_async_stacks);
       function.set_is_visible(!FLAG_causal_async_stacks &&
                               !FLAG_lazy_async_stacks);
     } else if ((flags & kIsAsyncStarFlag) != 0) {
-      function.set_modifier(RawFunction::kAsyncGen);
+      function.set_modifier(FunctionLayout::kAsyncGen);
       function.set_is_inlinable(!FLAG_causal_async_stacks &&
                                 !FLAG_lazy_async_stacks);
       function.set_is_visible(!FLAG_causal_async_stacks &&
@@ -2354,7 +2365,8 @@
     parameter_types = Array::New(num_params, Heap::kOld);
     function.set_parameter_types(parameter_types);
 
-    parameter_names = Array::New(num_params, Heap::kOld);
+    parameter_names = Array::New(
+        Function::NameArrayLengthIncludingFlags(num_params), Heap::kOld);
     function.set_parameter_names(parameter_names);
 
     intptr_t param_index = 0;
@@ -2831,7 +2843,7 @@
   }
 }
 
-RawObject* BytecodeReaderHelper::BuildParameterDescriptor(
+ObjectPtr BytecodeReaderHelper::BuildParameterDescriptor(
     const Function& function) {
   ASSERT(function.is_declared_in_bytecode());
 
@@ -2956,20 +2968,20 @@
     const Function& function) {
   // Handle function kinds which don't have a user-defined body first.
   switch (function.kind()) {
-    case RawFunction::kImplicitClosureFunction:
+    case FunctionLayout::kImplicitClosureFunction:
       ParseForwarderFunction(parsed_function, function,
                              Function::Handle(Z, function.parent_function()));
       return;
-    case RawFunction::kDynamicInvocationForwarder:
+    case FunctionLayout::kDynamicInvocationForwarder:
       ParseForwarderFunction(parsed_function, function,
                              Function::Handle(Z, function.ForwardingTarget()));
       return;
-    case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitSetter:
-    case RawFunction::kMethodExtractor:
+    case FunctionLayout::kImplicitGetter:
+    case FunctionLayout::kImplicitSetter:
+    case FunctionLayout::kMethodExtractor:
       BytecodeScopeBuilder(parsed_function).BuildScopes();
       return;
-    case RawFunction::kImplicitStaticGetter: {
+    case FunctionLayout::kImplicitStaticGetter: {
       if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
         break;
       } else {
@@ -2977,18 +2989,18 @@
         return;
       }
     }
-    case RawFunction::kRegularFunction:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kClosureFunction:
-    case RawFunction::kConstructor:
-    case RawFunction::kFieldInitializer:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kConstructor:
+    case FunctionLayout::kFieldInitializer:
       break;
-    case RawFunction::kNoSuchMethodDispatcher:
-    case RawFunction::kInvokeFieldDispatcher:
-    case RawFunction::kSignatureFunction:
-    case RawFunction::kIrregexpFunction:
-    case RawFunction::kFfiTrampoline:
+    case FunctionLayout::kNoSuchMethodDispatcher:
+    case FunctionLayout::kInvokeFieldDispatcher:
+    case FunctionLayout::kSignatureFunction:
+    case FunctionLayout::kIrregexpFunction:
+    case FunctionLayout::kFfiTrampoline:
       UNREACHABLE();
       break;
   }
@@ -3064,6 +3076,11 @@
       bool is_covariant = (flags & Parameter::kIsCovariantFlag) != 0;
       bool is_generic_covariant_impl =
           (flags & Parameter::kIsGenericCovariantImplFlag) != 0;
+      bool is_required = (flags & Parameter::kIsRequiredFlag) != 0;
+
+      if (is_required) {
+        function.SetIsRequiredAt(num_implicit_params + i);
+      }
 
       LocalVariable* variable =
           parsed_function->ParameterVariable(num_implicit_params + i);
@@ -3155,7 +3172,7 @@
   }
 }
 
-RawLibrary* BytecodeReaderHelper::ReadMain() {
+LibraryPtr BytecodeReaderHelper::ReadMain() {
   return Library::RawCast(ReadObject());
 }
 
@@ -3243,32 +3260,32 @@
   data_.SetAt(kNumFields + index, obj);
 }
 
-RawObject* BytecodeComponentData::GetObject(intptr_t index) const {
+ObjectPtr BytecodeComponentData::GetObject(intptr_t index) const {
   return data_.At(kNumFields + index);
 }
 
-RawArray* BytecodeComponentData::New(Zone* zone,
-                                     intptr_t version,
-                                     intptr_t num_objects,
-                                     intptr_t strings_header_offset,
-                                     intptr_t strings_contents_offset,
-                                     intptr_t object_offsets_offset,
-                                     intptr_t objects_contents_offset,
-                                     intptr_t main_offset,
-                                     intptr_t num_libraries,
-                                     intptr_t library_index_offset,
-                                     intptr_t libraries_offset,
-                                     intptr_t num_classes,
-                                     intptr_t classes_offset,
-                                     intptr_t members_offset,
-                                     intptr_t num_codes,
-                                     intptr_t codes_offset,
-                                     intptr_t source_positions_offset,
-                                     intptr_t source_files_offset,
-                                     intptr_t line_starts_offset,
-                                     intptr_t local_variables_offset,
-                                     intptr_t annotations_offset,
-                                     Heap::Space space) {
+ArrayPtr BytecodeComponentData::New(Zone* zone,
+                                    intptr_t version,
+                                    intptr_t num_objects,
+                                    intptr_t strings_header_offset,
+                                    intptr_t strings_contents_offset,
+                                    intptr_t object_offsets_offset,
+                                    intptr_t objects_contents_offset,
+                                    intptr_t main_offset,
+                                    intptr_t num_libraries,
+                                    intptr_t library_index_offset,
+                                    intptr_t libraries_offset,
+                                    intptr_t num_classes,
+                                    intptr_t classes_offset,
+                                    intptr_t members_offset,
+                                    intptr_t num_codes,
+                                    intptr_t codes_offset,
+                                    intptr_t source_positions_offset,
+                                    intptr_t source_files_offset,
+                                    intptr_t line_starts_offset,
+                                    intptr_t local_variables_offset,
+                                    intptr_t annotations_offset,
+                                    Heap::Space space) {
   const Array& data =
       Array::Handle(zone, Array::New(kNumFields + num_objects, space));
   Smi& smi_handle = Smi::Handle(zone);
@@ -3336,8 +3353,8 @@
   return data.raw();
 }
 
-RawError* BytecodeReader::ReadFunctionBytecode(Thread* thread,
-                                               const Function& function) {
+ErrorPtr BytecodeReader::ReadFunctionBytecode(Thread* thread,
+                                              const Function& function) {
   ASSERT(!FLAG_precompiled_mode);
   ASSERT(!function.HasBytecode());
   ASSERT(thread->sticky_error() == Error::null());
@@ -3365,31 +3382,31 @@
     auto& bytecode = Bytecode::Handle(zone);
 
     switch (function.kind()) {
-      case RawFunction::kImplicitGetter:
+      case FunctionLayout::kImplicitGetter:
         bytecode = Object::implicit_getter_bytecode().raw();
         break;
-      case RawFunction::kImplicitSetter:
+      case FunctionLayout::kImplicitSetter:
         bytecode = Object::implicit_setter_bytecode().raw();
         break;
-      case RawFunction::kImplicitStaticGetter:
+      case FunctionLayout::kImplicitStaticGetter:
         if (!IsStaticFieldGetterGeneratedAsInitializer(function, zone)) {
           bytecode = Object::implicit_static_getter_bytecode().raw();
         }
         break;
-      case RawFunction::kMethodExtractor:
+      case FunctionLayout::kMethodExtractor:
         bytecode = Object::method_extractor_bytecode().raw();
         break;
-      case RawFunction::kInvokeFieldDispatcher:
+      case FunctionLayout::kInvokeFieldDispatcher:
         if (Class::Handle(zone, function.Owner()).id() == kClosureCid) {
           bytecode = Object::invoke_closure_bytecode().raw();
         } else {
           bytecode = Object::invoke_field_bytecode().raw();
         }
         break;
-      case RawFunction::kNoSuchMethodDispatcher:
+      case FunctionLayout::kNoSuchMethodDispatcher:
         bytecode = Object::nsm_dispatcher_bytecode().raw();
         break;
-      case RawFunction::kDynamicInvocationForwarder: {
+      case FunctionLayout::kDynamicInvocationForwarder: {
         const Function& target =
             Function::Handle(zone, function.ForwardingTarget());
         if (!target.HasBytecode()) {
@@ -3460,7 +3477,7 @@
   }
 }
 
-RawObject* BytecodeReader::ReadAnnotation(const Field& annotation_field) {
+ObjectPtr BytecodeReader::ReadAnnotation(const Field& annotation_field) {
   ASSERT(annotation_field.is_declared_in_bytecode());
 
   Thread* thread = Thread::Current();
@@ -3485,8 +3502,8 @@
   return bytecode_reader.ReadObject();
 }
 
-RawArray* BytecodeReader::ReadExtendedAnnotations(const Field& annotation_field,
-                                                  intptr_t count) {
+ArrayPtr BytecodeReader::ReadExtendedAnnotations(const Field& annotation_field,
+                                                 intptr_t count) {
   ASSERT(annotation_field.is_declared_in_bytecode());
 
   Thread* thread = Thread::Current();
@@ -3591,8 +3608,8 @@
   bytecode_reader.ReadMembers(cls, discard_fields);
 }
 
-RawObject* BytecodeReader::GetBytecodeAttribute(const Object& key,
-                                                const String& name) {
+ObjectPtr BytecodeReader::GetBytecodeAttribute(const Object& key,
+                                               const String& name) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const auto* object_store = thread->isolate()->object_store();
@@ -3631,7 +3648,7 @@
 }
 
 #if !defined(PRODUCT)
-RawLocalVarDescriptors* BytecodeReader::ComputeLocalVarDescriptors(
+LocalVarDescriptorsPtr BytecodeReader::ComputeLocalVarDescriptors(
     Zone* zone,
     const Function& function,
     const Bytecode& bytecode) {
@@ -3649,14 +3666,14 @@
     const auto& parent_vars = LocalVarDescriptors::Handle(
         zone, parent_bytecode.GetLocalVarDescriptors());
     for (intptr_t i = 0; i < parent_vars.Length(); ++i) {
-      RawLocalVarDescriptors::VarInfo var_info;
+      LocalVarDescriptorsLayout::VarInfo var_info;
       parent_vars.GetInfo(i, &var_info);
       // Include parent's context variable if variable's scope
       // intersects with the local function range.
       // It is not enough to check if local function is declared within the
       // scope of variable, because in case of async functions closure has
       // the same range as original function.
-      if (var_info.kind() == RawLocalVarDescriptors::kContextVar &&
+      if (var_info.kind() == LocalVarDescriptorsLayout::kContextVar &&
           ((var_info.begin_pos <= function.token_pos() &&
             function.token_pos() <= var_info.end_pos) ||
            (function.token_pos() <= var_info.begin_pos &&
@@ -3681,11 +3698,11 @@
           LocalVarDescriptorsBuilder::VarDesc desc;
           desc.name = &String::Handle(zone, local_vars.Name());
           if (local_vars.IsCaptured()) {
-            desc.info.set_kind(RawLocalVarDescriptors::kContextVar);
+            desc.info.set_kind(LocalVarDescriptorsLayout::kContextVar);
             desc.info.scope_id = context_level;
             desc.info.set_index(local_vars.Index());
           } else {
-            desc.info.set_kind(RawLocalVarDescriptors::kStackVar);
+            desc.info.set_kind(LocalVarDescriptorsLayout::kStackVar);
             desc.info.scope_id = scope_id;
             if (local_vars.Index() < 0) {
               // Parameter
@@ -3705,7 +3722,7 @@
           const intptr_t context_variable_index = -local_vars.Index();
           LocalVarDescriptorsBuilder::VarDesc desc;
           desc.name = &Symbols::CurrentContextVar();
-          desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
+          desc.info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
           desc.info.scope_id = 0;
           desc.info.declaration_pos = TokenPosition::kMinSource;
           desc.info.begin_pos = TokenPosition::kMinSource;
@@ -3723,7 +3740,7 @@
 
 bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
                                                Zone* zone) {
-  ASSERT(function.kind() == RawFunction::kImplicitStaticGetter);
+  ASSERT(function.kind() == FunctionLayout::kImplicitStaticGetter);
 
   const auto& field = Field::Handle(zone, function.accessor_field());
   return field.is_declared_in_bytecode() && field.is_const() &&
@@ -3732,5 +3749,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 2afd9dd..ee8444f 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -5,12 +5,14 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 #include "vm/constants_kbc.h"
 #include "vm/object.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -40,10 +42,10 @@
                                          intptr_t* p_num_classes,
                                          intptr_t* p_num_procedures);
 
-  RawLibrary* GetMainLibrary();
+  LibraryPtr GetMainLibrary();
 
-  RawArray* GetBytecodeComponent();
-  RawArray* ReadBytecodeComponent();
+  ArrayPtr GetBytecodeComponent();
+  ArrayPtr ReadBytecodeComponent();
 
  private:
   ActiveClass* const active_class_;
@@ -62,7 +64,7 @@
 
   void ReadCode(const Function& function, intptr_t code_offset);
 
-  RawArray* CreateForwarderChecks(const Function& function);
+  ArrayPtr CreateForwarderChecks(const Function& function);
 
   void ReadMembers(const Class& cls, bool discard_fields);
 
@@ -79,9 +81,9 @@
   void ParseBytecodeFunction(ParsedFunction* parsed_function,
                              const Function& function);
 
-  RawLibrary* ReadMain();
+  LibraryPtr ReadMain();
 
-  RawArray* ReadBytecodeComponent(intptr_t md_offset);
+  ArrayPtr ReadBytecodeComponent(intptr_t md_offset);
   void ResetObjects();
 
   // Fills in [is_covariant] and [is_generic_covariant_impl] vectors
@@ -96,10 +98,10 @@
 
   // Returns an flattened array of tuples {isFinal, defaultValue, metadata},
   // or an Error.
-  RawObject* BuildParameterDescriptor(const Function& function);
+  ObjectPtr BuildParameterDescriptor(const Function& function);
 
   // Read bytecode PackedObject.
-  RawObject* ReadObject();
+  ObjectPtr ReadObject();
 
  private:
   // These constants should match corresponding constants in class ObjectHandle
@@ -145,6 +147,7 @@
     static const int kIsCovariantFlag = 1 << 0;
     static const int kIsGenericCovariantImplFlag = 1 << 1;
     static const int kIsFinalFlag = 1 << 2;
+    static const int kIsRequiredFlag = 1 << 3;
   };
 
   class FunctionTypeScope : public ValueObject {
@@ -190,12 +193,13 @@
   };
 
   void ReadClosureDeclaration(const Function& function, intptr_t closureIndex);
-  RawType* ReadFunctionSignature(const Function& func,
-                                 bool has_optional_positional_params,
-                                 bool has_optional_named_params,
-                                 bool has_type_params,
-                                 bool has_positional_param_names,
-                                 Nullability nullability);
+  TypePtr ReadFunctionSignature(const Function& func,
+                                bool has_optional_positional_params,
+                                bool has_optional_named_params,
+                                bool has_type_params,
+                                bool has_positional_param_names,
+                                bool has_parameter_flags,
+                                Nullability nullability);
   void ReadTypeParametersDeclaration(const Class& parameterized_class,
                                      const Function& parameterized_function);
 
@@ -206,22 +210,22 @@
                             const ObjectPool& pool,
                             intptr_t start_index);
 
-  RawBytecode* ReadBytecode(const ObjectPool& pool);
+  BytecodePtr ReadBytecode(const ObjectPool& pool);
   void ReadExceptionsTable(const Bytecode& bytecode, bool has_exceptions_table);
   void ReadSourcePositions(const Bytecode& bytecode, bool has_source_positions);
   void ReadLocalVariables(const Bytecode& bytecode, bool has_local_variables);
-  RawTypedData* NativeEntry(const Function& function,
-                            const String& external_name);
-  RawString* ConstructorName(const Class& cls, const String& name);
+  TypedDataPtr NativeEntry(const Function& function,
+                           const String& external_name);
+  StringPtr ConstructorName(const Class& cls, const String& name);
 
-  RawObject* ReadObjectContents(uint32_t header);
-  RawObject* ReadConstObject(intptr_t tag);
-  RawObject* ReadType(intptr_t tag, Nullability nullability);
-  RawString* ReadString(bool is_canonical = true);
-  RawScript* ReadSourceFile(const String& uri, intptr_t offset);
-  RawTypeArguments* ReadTypeArguments();
+  ObjectPtr ReadObjectContents(uint32_t header);
+  ObjectPtr ReadConstObject(intptr_t tag);
+  ObjectPtr ReadType(intptr_t tag, Nullability nullability);
+  StringPtr ReadString(bool is_canonical = true);
+  ScriptPtr ReadSourceFile(const String& uri, intptr_t offset);
+  TypeArgumentsPtr ReadTypeArguments();
   void ReadAttributes(const Object& key);
-  RawPatchClass* GetPatchClass(const Class& cls, const Script& script);
+  PatchClassPtr GetPatchClass(const Class& cls, const Script& script);
   void ParseForwarderFunction(ParsedFunction* parsed_function,
                               const Function& function,
                               const Function& target);
@@ -308,32 +312,32 @@
   intptr_t GetLocalVariablesOffset() const;
   intptr_t GetAnnotationsOffset() const;
   void SetObject(intptr_t index, const Object& obj) const;
-  RawObject* GetObject(intptr_t index) const;
+  ObjectPtr GetObject(intptr_t index) const;
 
   bool IsNull() const { return data_.IsNull(); }
 
-  static RawArray* New(Zone* zone,
-                       intptr_t version,
-                       intptr_t num_objects,
-                       intptr_t strings_header_offset,
-                       intptr_t strings_contents_offset,
-                       intptr_t object_offsets_offset,
-                       intptr_t objects_contents_offset,
-                       intptr_t main_offset,
-                       intptr_t num_libraries,
-                       intptr_t library_index_offset,
-                       intptr_t libraries_offset,
-                       intptr_t num_classes,
-                       intptr_t classes_offset,
-                       intptr_t members_offset,
-                       intptr_t num_codes,
-                       intptr_t codes_offset,
-                       intptr_t source_positions_offset,
-                       intptr_t source_files_offset,
-                       intptr_t line_starts_offset,
-                       intptr_t local_variables_offset,
-                       intptr_t annotations_offset,
-                       Heap::Space space);
+  static ArrayPtr New(Zone* zone,
+                      intptr_t version,
+                      intptr_t num_objects,
+                      intptr_t strings_header_offset,
+                      intptr_t strings_contents_offset,
+                      intptr_t object_offsets_offset,
+                      intptr_t objects_contents_offset,
+                      intptr_t main_offset,
+                      intptr_t num_libraries,
+                      intptr_t library_index_offset,
+                      intptr_t libraries_offset,
+                      intptr_t num_classes,
+                      intptr_t classes_offset,
+                      intptr_t members_offset,
+                      intptr_t num_codes,
+                      intptr_t codes_offset,
+                      intptr_t source_positions_offset,
+                      intptr_t source_files_offset,
+                      intptr_t line_starts_offset,
+                      intptr_t local_variables_offset,
+                      intptr_t annotations_offset,
+                      Heap::Space space);
 
  private:
   Array& data_;
@@ -343,14 +347,14 @@
  public:
   // Reads bytecode for the given function and sets its bytecode field.
   // Returns error (if any), or null.
-  static RawError* ReadFunctionBytecode(Thread* thread,
-                                        const Function& function);
+  static ErrorPtr ReadFunctionBytecode(Thread* thread,
+                                       const Function& function);
 
   // Read annotations for the given annotation field.
-  static RawObject* ReadAnnotation(const Field& annotation_field);
+  static ObjectPtr ReadAnnotation(const Field& annotation_field);
   // Read the |count| annotations following given annotation field.
-  static RawArray* ReadExtendedAnnotations(const Field& annotation_field,
-                                           intptr_t count);
+  static ArrayPtr ReadExtendedAnnotations(const Field& annotation_field,
+                                          intptr_t count);
 
   static void ResetObjectTable(const KernelProgramInfo& info);
 
@@ -364,11 +368,11 @@
   static void FinishClassLoading(const Class& cls);
 
   // Value of attribute [name] of Function/Field [key].
-  static RawObject* GetBytecodeAttribute(const Object& key, const String& name);
+  static ObjectPtr GetBytecodeAttribute(const Object& key, const String& name);
 
 #if !defined(PRODUCT)
   // Compute local variable descriptors for [function] with [bytecode].
-  static RawLocalVarDescriptors* ComputeLocalVarDescriptors(
+  static LocalVarDescriptorsPtr ComputeLocalVarDescriptors(
       Zone* zone,
       const Function& function,
       const Bytecode& bytecode);
@@ -528,11 +532,11 @@
     ASSERT(IsVariableDeclaration() || IsContextVariable());
     return cur_index_;
   }
-  RawString* Name() const {
+  StringPtr Name() const {
     ASSERT(IsVariableDeclaration());
     return String::RawCast(object_pool_.ObjectAt(cur_name_));
   }
-  RawAbstractType* Type() const {
+  AbstractTypePtr Type() const {
     ASSERT(IsVariableDeclaration());
     return AbstractType::RawCast(object_pool_.ObjectAt(cur_type_));
   }
@@ -582,5 +586,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
diff --git a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
index bd0b3ec..bc1a30b 100644
--- a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
@@ -6,8 +6,6 @@
 
 #include "vm/compiler/frontend/bytecode_reader.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -63,7 +61,7 @@
   parsed_function_->set_scope(scope_);
 
   switch (function.kind()) {
-    case RawFunction::kImplicitClosureFunction: {
+    case FunctionLayout::kImplicitClosureFunction: {
       ASSERT(function.NumImplicitParameters() == 1);
 
       LocalVariable* closure_parameter = MakeVariable(
@@ -78,8 +76,8 @@
       break;
     }
 
-    case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitSetter: {
+    case FunctionLayout::kImplicitGetter:
+    case FunctionLayout::kImplicitSetter: {
       const bool is_setter = function.IsImplicitSetterFunction();
       const bool is_method = !function.IsStaticFunction();
       const Field& field = Field::Handle(Z, function.accessor_field());
@@ -107,25 +105,14 @@
             }
           }
         }
-      } else {
-        if (field.is_late()) {
-          // LoadLateField uses expression_temp_var.
-          needs_expr_temp = true;
-        }
       }
       break;
     }
-    case RawFunction::kImplicitStaticGetter: {
+    case FunctionLayout::kImplicitStaticGetter: {
       ASSERT(!IsStaticFieldGetterGeneratedAsInitializer(function, Z));
-      const Field& field = Field::Handle(Z, function.accessor_field());
-      const bool lib_is_nnbd = function.nnbd_mode() == NNBDMode::kOptedInLib;
-      if (field.is_late() || lib_is_nnbd) {
-        // LoadLateField uses expression_temp_var.
-        needs_expr_temp = true;
-      }
       break;
     }
-    case RawFunction::kDynamicInvocationForwarder: {
+    case FunctionLayout::kDynamicInvocationForwarder: {
       // Create [this] variable.
       MakeReceiverVariable(/* is_parameter = */ true);
 
@@ -135,7 +122,7 @@
       AddParameters(function, LocalVariable::kDoTypeCheck);
       break;
     }
-    case RawFunction::kMethodExtractor: {
+    case FunctionLayout::kMethodExtractor: {
       // Add a receiver parameter.  Though it is captured, we emit code to
       // explicitly copy it to a fixed offset in a freshly-allocated context
       // instead of using the generic code for regular functions.
@@ -195,5 +182,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_scope_builder.h b/runtime/vm/compiler/frontend/bytecode_scope_builder.h
index 4436565..8f96b87 100644
--- a/runtime/vm/compiler/frontend/bytecode_scope_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_scope_builder.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_SCOPE_BUILDER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_SCOPE_BUILDER_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/object.h"
 #include "vm/parser.h"  // For ParsedFunction.
@@ -36,5 +38,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_SCOPE_BUILDER_H_
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index 23a30d3..cb0c693 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -4,8 +4,6 @@
 
 #include "vm/compiler/frontend/constant_reader.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -21,7 +19,7 @@
       script_(helper->script()),
       result_(Instance::Handle(zone_)) {}
 
-RawInstance* ConstantReader::ReadConstantExpression() {
+InstancePtr ConstantReader::ReadConstantExpression() {
   Tag tag = helper_->ReadTag();  // read tag.
   switch (tag) {
     case kConstantExpression:
@@ -46,7 +44,7 @@
   return result_.raw();
 }
 
-RawObject* ConstantReader::ReadAnnotations() {
+ObjectPtr ConstantReader::ReadAnnotations() {
   intptr_t list_length = helper_->ReadListLength();  // read list length.
   const Array& metadata_values =
       Array::Handle(Z, Array::New(list_length, H.allocation_space()));
@@ -59,7 +57,7 @@
   return metadata_values.raw();
 }
 
-RawInstance* ConstantReader::ReadConstant(intptr_t constant_offset) {
+InstancePtr ConstantReader::ReadConstant(intptr_t constant_offset) {
   ASSERT(!H.constants().IsNull());
   ASSERT(!H.constants_table().IsNull());  // raw bytes
 
@@ -102,7 +100,7 @@
   return false;
 }
 
-RawInstance* ConstantReader::ReadConstantInternal(intptr_t constant_offset) {
+InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_offset) {
   // Get reader directly into raw bytes of constant table.
   bool null_safety = H.thread()->isolate()->null_safety();
   KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
@@ -328,5 +326,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/constant_reader.h b/runtime/vm/compiler/frontend/constant_reader.h
index c5a7574..871b7f0 100644
--- a/runtime/vm/compiler/frontend/constant_reader.h
+++ b/runtime/vm/compiler/frontend/constant_reader.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_CONSTANT_READER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_CONSTANT_READER_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 #include "vm/hash_table.h"
@@ -21,8 +23,8 @@
 
   virtual ~ConstantReader() {}
 
-  RawInstance* ReadConstantExpression();
-  RawObject* ReadAnnotations();
+  InstancePtr ReadConstantExpression();
+  ObjectPtr ReadAnnotations();
 
   // Peeks to see if constant at the given offset will evaluate to
   // instance of the given clazz.
@@ -30,10 +32,10 @@
 
   // Reads a constant at the given offset (possibly by recursing
   // into sub-constants).
-  RawInstance* ReadConstant(intptr_t constant_offset);
+  InstancePtr ReadConstant(intptr_t constant_offset);
 
  private:
-  RawInstance* ReadConstantInternal(intptr_t constant_offset);
+  InstancePtr ReadConstantInternal(intptr_t constant_offset);
 
   KernelReaderHelper* helper_;
   Zone* zone_;
@@ -65,12 +67,12 @@
   static uword Hash(const intptr_t key) {
     return HashValue(Smi::Value(KeyAsSmi(key)));
   }
-  static RawObject* NewKey(const intptr_t key) { return KeyAsSmi(key); }
+  static ObjectPtr NewKey(const intptr_t key) { return KeyAsSmi(key); }
 
  private:
   static uword HashValue(intptr_t pos) { return pos % (Smi::kMaxValue - 13); }
 
-  static RawSmi* KeyAsSmi(const intptr_t key) {
+  static SmiPtr KeyAsSmi(const intptr_t key) {
     ASSERT(key >= 0);
     return Smi::New(key);
   }
@@ -80,5 +82,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_CONSTANT_READER_H_
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 9d8855f..4a13620 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -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.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/frontend/flow_graph_builder.h"
 
 #include "vm/compiler/backend/branch_optimizer.h"
@@ -390,5 +388,3 @@
 }
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.h b/runtime/vm/compiler/frontend/flow_graph_builder.h
index 71e573c..f2d5364 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_FLOW_GRAPH_BUILDER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_FLOW_GRAPH_BUILDER_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/globals.h"
 #include "vm/allocation.h"
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index b0dd414..3079ccf 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -13,8 +13,6 @@
 #include "vm/object_store.h"
 #include "vm/stack_frame.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 
 DECLARE_FLAG(bool, enable_interpreter);
@@ -56,6 +54,7 @@
     body += Constant(
         Instance::ZoneHandle(Z, constant_reader_.ReadConstantExpression()));
   } else {
+    body += SetupCapturedParameters(parsed_function()->function());
     body += BuildExpression();  // read initializer.
   }
   body += Return(TokenPosition::kNoSource);
@@ -1090,22 +1089,22 @@
     bytecode_metadata_helper_.ParseBytecodeFunction(parsed_function());
 
     switch (function.kind()) {
-      case RawFunction::kImplicitClosureFunction:
+      case FunctionLayout::kImplicitClosureFunction:
         return B->BuildGraphOfImplicitClosureFunction(function);
-      case RawFunction::kImplicitGetter:
-      case RawFunction::kImplicitSetter:
+      case FunctionLayout::kImplicitGetter:
+      case FunctionLayout::kImplicitSetter:
         return B->BuildGraphOfFieldAccessor(function);
-      case RawFunction::kImplicitStaticGetter: {
+      case FunctionLayout::kImplicitStaticGetter: {
         if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
           break;
         }
         return B->BuildGraphOfFieldAccessor(function);
       }
-      case RawFunction::kDynamicInvocationForwarder:
+      case FunctionLayout::kDynamicInvocationForwarder:
         return B->BuildGraphOfDynamicInvocationForwarder(function);
-      case RawFunction::kMethodExtractor:
+      case FunctionLayout::kMethodExtractor:
         return B->BuildGraphOfMethodExtractor(function);
-      case RawFunction::kNoSuchMethodDispatcher:
+      case FunctionLayout::kNoSuchMethodDispatcher:
         return B->BuildGraphOfNoSuchMethodDispatcher(function);
       default:
         break;
@@ -1128,51 +1127,51 @@
   // Certain special functions could have a VM-internal bytecode
   // attached to them.
   ASSERT((!function.HasBytecode()) ||
-         (function.kind() == RawFunction::kImplicitGetter) ||
-         (function.kind() == RawFunction::kImplicitSetter) ||
-         (function.kind() == RawFunction::kImplicitStaticGetter) ||
-         (function.kind() == RawFunction::kMethodExtractor) ||
-         (function.kind() == RawFunction::kInvokeFieldDispatcher) ||
-         (function.kind() == RawFunction::kNoSuchMethodDispatcher));
+         (function.kind() == FunctionLayout::kImplicitGetter) ||
+         (function.kind() == FunctionLayout::kImplicitSetter) ||
+         (function.kind() == FunctionLayout::kImplicitStaticGetter) ||
+         (function.kind() == FunctionLayout::kMethodExtractor) ||
+         (function.kind() == FunctionLayout::kInvokeFieldDispatcher) ||
+         (function.kind() == FunctionLayout::kNoSuchMethodDispatcher));
 
   ParseKernelASTFunction();
 
   switch (function.kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kClosureFunction:
-    case RawFunction::kConstructor: {
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kConstructor: {
       if (B->IsRecognizedMethodForFlowGraph(function)) {
         return B->BuildGraphOfRecognizedMethod(function);
       }
       return BuildGraphOfFunction(function.IsGenerativeConstructor());
     }
-    case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitStaticGetter:
-    case RawFunction::kImplicitSetter: {
+    case FunctionLayout::kImplicitGetter:
+    case FunctionLayout::kImplicitStaticGetter:
+    case FunctionLayout::kImplicitSetter: {
       const Field& field = Field::Handle(Z, function.accessor_field());
       if (field.is_const() && field.IsUninitialized()) {
         EvaluateConstFieldValue(field);
       }
       return B->BuildGraphOfFieldAccessor(function);
     }
-    case RawFunction::kFieldInitializer:
+    case FunctionLayout::kFieldInitializer:
       return BuildGraphOfFieldInitializer();
-    case RawFunction::kDynamicInvocationForwarder:
+    case FunctionLayout::kDynamicInvocationForwarder:
       return B->BuildGraphOfDynamicInvocationForwarder(function);
-    case RawFunction::kMethodExtractor:
+    case FunctionLayout::kMethodExtractor:
       return flow_graph_builder_->BuildGraphOfMethodExtractor(function);
-    case RawFunction::kNoSuchMethodDispatcher:
+    case FunctionLayout::kNoSuchMethodDispatcher:
       return flow_graph_builder_->BuildGraphOfNoSuchMethodDispatcher(function);
-    case RawFunction::kInvokeFieldDispatcher:
+    case FunctionLayout::kInvokeFieldDispatcher:
       return flow_graph_builder_->BuildGraphOfInvokeFieldDispatcher(function);
-    case RawFunction::kImplicitClosureFunction:
+    case FunctionLayout::kImplicitClosureFunction:
       return flow_graph_builder_->BuildGraphOfImplicitClosureFunction(function);
-    case RawFunction::kFfiTrampoline:
+    case FunctionLayout::kFfiTrampoline:
       return flow_graph_builder_->BuildGraphOfFfiTrampoline(function);
-    case RawFunction::kSignatureFunction:
-    case RawFunction::kIrregexpFunction:
+    case FunctionLayout::kSignatureFunction:
+    case FunctionLayout::kIrregexpFunction:
       break;
   }
   UNREACHABLE();
@@ -1189,13 +1188,13 @@
 
   // Mark forwarding stubs.
   switch (function.kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kImplicitClosureFunction:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kClosureFunction:
-    case RawFunction::kConstructor:
-    case RawFunction::kDynamicInvocationForwarder:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kImplicitClosureFunction:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kConstructor:
+    case FunctionLayout::kDynamicInvocationForwarder:
       ReadForwardingStubTarget(function);
       break;
     default:
@@ -1205,34 +1204,34 @@
   set_scopes(parsed_function()->EnsureKernelScopes());
 
   switch (function.kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kClosureFunction:
-    case RawFunction::kConstructor:
-    case RawFunction::kImplicitClosureFunction:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kConstructor:
+    case FunctionLayout::kImplicitClosureFunction:
       ReadUntilFunctionNode();
       SetupDefaultParameterValues();
       ReadDefaultFunctionTypeArguments(function);
       break;
-    case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitStaticGetter:
-    case RawFunction::kImplicitSetter:
-    case RawFunction::kFieldInitializer:
-    case RawFunction::kMethodExtractor:
-    case RawFunction::kNoSuchMethodDispatcher:
-    case RawFunction::kInvokeFieldDispatcher:
-    case RawFunction::kFfiTrampoline:
+    case FunctionLayout::kImplicitGetter:
+    case FunctionLayout::kImplicitStaticGetter:
+    case FunctionLayout::kImplicitSetter:
+    case FunctionLayout::kFieldInitializer:
+    case FunctionLayout::kMethodExtractor:
+    case FunctionLayout::kNoSuchMethodDispatcher:
+    case FunctionLayout::kInvokeFieldDispatcher:
+    case FunctionLayout::kFfiTrampoline:
       break;
-    case RawFunction::kDynamicInvocationForwarder:
+    case FunctionLayout::kDynamicInvocationForwarder:
       if (PeekTag() != kField) {
         ReadUntilFunctionNode();
         SetupDefaultParameterValues();
         ReadDefaultFunctionTypeArguments(function);
       }
       break;
-    case RawFunction::kSignatureFunction:
-    case RawFunction::kIrregexpFunction:
+    case FunctionLayout::kSignatureFunction:
+    case FunctionLayout::kIrregexpFunction:
       UNREACHABLE();
       break;
   }
@@ -1716,16 +1715,23 @@
                                         clear_the_temp);
 }
 
-static void BadArity() {
+static void BadArity(const Script& script,
+                     TokenPosition position,
+                     const String& error_message) {
 #ifndef PRODUCT
   // TODO(https://github.com/dart-lang/sdk/issues/37517): Should emit code to
   // throw a NoSuchMethodError.
-  ASSERT(Isolate::Current()->HasAttemptedReload());
-  Report::LongJump(LanguageError::Handle(LanguageError::New(String::Handle(
-      String::New("Unimplemented handling of static target arity change")))));
-#else
-  UNREACHABLE();
+  // Correct arity is checked at compile time by CFE. However, an isolate reload
+  // after an arity change may lead here.
+  // Using strong mode with a mix of opted in and opted out libraries may
+  // also result in this error undetected by CFE.
+  Isolate* isolate = Isolate::Current();
+  ASSERT(isolate->HasAttemptedReload() || isolate->null_safety());
+  Report::MessageF(Report::kError, script, position, Report::AtLocation,
+                   "Static call with invalid arguments: %s",
+                   error_message.ToCString());
 #endif
+  UNREACHABLE();
 }
 
 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
@@ -1734,7 +1740,7 @@
                                                ICData::RebindRule rebind_rule) {
   String& error_message = String::Handle();
   if (!target.AreValidArgumentCounts(0, argument_count, 0, &error_message)) {
-    BadArity();
+    BadArity(script_, position, error_message);
   }
   return flow_graph_builder_->StaticCall(position, target, argument_count,
                                          rebind_rule);
@@ -1752,7 +1758,7 @@
   String& error_message = String::Handle();
   if (!target.AreValidArguments(type_args_count, argument_count, argument_names,
                                 &error_message)) {
-    BadArity();
+    BadArity(script_, position, error_message);
   }
   return flow_graph_builder_->StaticCall(
       position, target, argument_count, argument_names, rebind_rule,
@@ -1766,9 +1772,9 @@
     intptr_t argument_count,
     intptr_t checked_argument_count) {
   const intptr_t kTypeArgsLen = 0;
-  return flow_graph_builder_->InstanceCall(
-      position, name, kind, kTypeArgsLen, argument_count, Array::null_array(),
-      checked_argument_count, Function::null_function());
+  return flow_graph_builder_->InstanceCall(position, name, kind, kTypeArgsLen,
+                                           argument_count, Array::null_array(),
+                                           checked_argument_count);
 }
 
 Fragment StreamingFlowGraphBuilder::InstanceCall(
@@ -1780,14 +1786,15 @@
     const Array& argument_names,
     intptr_t checked_argument_count,
     const Function& interface_target,
+    const Function& tearoff_interface_target,
     const InferredTypeMetadata* result_type,
     bool use_unchecked_entry,
     const CallSiteAttributesMetadata* call_site_attrs,
     bool receiver_is_not_smi) {
   return flow_graph_builder_->InstanceCall(
       position, name, kind, type_args_len, argument_count, argument_names,
-      checked_argument_count, interface_target, result_type,
-      use_unchecked_entry, call_site_attrs, receiver_is_not_smi);
+      checked_argument_count, interface_target, tearoff_interface_target,
+      result_type, use_unchecked_entry, call_site_attrs, receiver_is_not_smi);
 }
 
 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) {
@@ -2332,6 +2339,7 @@
   const String& getter_name = ReadNameAsGetterName();  // read name.
 
   const Function* interface_target = &Function::null_function();
+  const Function* tearoff_interface_target = &Function::null_function();
   const NameIndex itarget_name =
       ReadCanonicalNameReference();  // read interface_target_reference.
   if (!H.IsRoot(itarget_name) &&
@@ -2340,6 +2348,10 @@
         Z,
         H.LookupMethodByMember(itarget_name, H.DartGetterName(itarget_name)));
     ASSERT(getter_name.raw() == interface_target->name());
+  } else if (!H.IsRoot(itarget_name) && H.IsMethod(itarget_name)) {
+    tearoff_interface_target = &Function::ZoneHandle(
+        Z,
+        H.LookupMethodByMember(itarget_name, H.DartMethodName(itarget_name)));
   }
 
   if (direct_call.check_receiver_for_null_) {
@@ -2354,9 +2366,10 @@
   } else {
     const intptr_t kTypeArgsLen = 0;
     const intptr_t kNumArgsChecked = 1;
-    instructions += InstanceCall(
-        position, getter_name, Token::kGET, kTypeArgsLen, 1,
-        Array::null_array(), kNumArgsChecked, *interface_target, &result_type);
+    instructions +=
+        InstanceCall(position, getter_name, Token::kGET, kTypeArgsLen, 1,
+                     Array::null_array(), kNumArgsChecked, *interface_target,
+                     *tearoff_interface_target, &result_type);
   }
 
   if (direct_call.check_receiver_for_null_) {
@@ -2447,6 +2460,7 @@
     instructions += InstanceCall(
         position, *mangled_name, Token::kSET, kTypeArgsLen, 2,
         Array::null_array(), kNumArgsChecked, *interface_target,
+        Function::null_function(),
         /*result_type=*/nullptr,
         /*use_unchecked_entry=*/is_unchecked_call, &call_site_attributes);
   }
@@ -3032,11 +3046,12 @@
                    argument_names, ICData::kNoRebind, &result_type,
                    type_args_len, /*use_unchecked_entry=*/is_unchecked_call);
   } else {
-    instructions += InstanceCall(
-        position, *mangled_name, token_kind, type_args_len, argument_count,
-        argument_names, checked_argument_count, *interface_target, &result_type,
-        /*use_unchecked_entry=*/is_unchecked_call, &call_site_attributes,
-        result_type.ReceiverNotInt());
+    instructions +=
+        InstanceCall(position, *mangled_name, token_kind, type_args_len,
+                     argument_count, argument_names, checked_argument_count,
+                     *interface_target, Function::null_function(), &result_type,
+                     /*use_unchecked_entry=*/is_unchecked_call,
+                     &call_site_attributes, result_type.ReceiverNotInt());
   }
 
   // Drop temporaries preserving result on the top of the stack.
@@ -3358,7 +3373,8 @@
   instructions +=
       BuildArguments(&argument_names, NULL /* arg count */,
                      NULL /* positional arg count */);  // read arguments.
-  ASSERT(target.AreValidArguments(type_args_len, argument_count, argument_names,
+  ASSERT(!special_case ||
+         target.AreValidArguments(type_args_len, argument_count, argument_names,
                                   NULL));
 
   // Special case identical(x, y) call.
@@ -3655,7 +3671,7 @@
 
   // The VM does not like an instanceOf call with a dynamic type. We need to
   // special case this situation by detecting a top type.
-  if (type.IsTopType()) {
+  if (type.IsTopTypeForInstanceOf()) {
     // Evaluate the expression on the left but ignore its result.
     instructions += Drop();
 
@@ -3702,7 +3718,7 @@
   Fragment instructions = BuildExpression();  // read operand.
 
   const AbstractType& type = T.BuildType();  // read type.
-  if (type.IsInstantiated() && type.IsTopTypeForAssignability()) {
+  if (type.IsInstantiated() && type.IsTopTypeForSubtyping()) {
     // We already evaluated the operand on the left and just leave it there as
     // the result of the `obj as dynamic` expression.
   } else {
@@ -4490,9 +4506,8 @@
           Z, klass.LookupConstructorAllowPrivate(String::ZoneHandle(
                  Z, Symbols::FromConcatAll(H.thread(), pieces))));
       ASSERT(!constructor.IsNull());
-      const String& url = H.DartString(
-          parsed_function()->function().ToLibNamePrefixedQualifiedCString(),
-          Heap::kOld);
+      const String& url = H.DartSymbolPlain(
+          parsed_function()->function().ToLibNamePrefixedQualifiedCString());
 
       // Create instance of _FallThroughError
       body_fragment += AllocateObject(TokenPosition::kNoSource, klass, 0);
@@ -5089,8 +5104,8 @@
       // NOTE: This is not TokenPosition in the general sense!
       if (!closure_owner_.IsNull()) {
         function = Function::NewClosureFunctionWithKind(
-            RawFunction::kClosureFunction, *name, parsed_function()->function(),
-            position, closure_owner_);
+            FunctionLayout::kClosureFunction, *name,
+            parsed_function()->function(), position, closure_owner_);
       } else {
         function = Function::NewClosureFunction(
             *name, parsed_function()->function(), position);
@@ -5100,14 +5115,14 @@
                                  FunctionNodeHelper::kSync);
       switch (function_node_helper.dart_async_marker_) {
         case FunctionNodeHelper::kSyncStar:
-          function.set_modifier(RawFunction::kSyncGen);
+          function.set_modifier(FunctionLayout::kSyncGen);
           break;
         case FunctionNodeHelper::kAsync:
-          function.set_modifier(RawFunction::kAsync);
+          function.set_modifier(FunctionLayout::kAsync);
           function.set_is_inlinable(!FLAG_causal_async_stacks);
           break;
         case FunctionNodeHelper::kAsyncStar:
-          function.set_modifier(RawFunction::kAsyncGen);
+          function.set_modifier(FunctionLayout::kAsyncGen);
           function.set_is_inlinable(!FLAG_causal_async_stacks);
           break;
         default:
@@ -5270,5 +5285,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index d782e5d..fbba4d6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_KERNEL_BINARY_FLOWGRAPH_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_BINARY_FLOWGRAPH_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/constant_reader.h"
@@ -159,8 +161,9 @@
   void InlineBailout(const char* reason);
   Fragment DebugStepCheck(TokenPosition position);
   Fragment LoadLocal(LocalVariable* variable);
-  Fragment Return(TokenPosition position,
-                  intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+  Fragment Return(
+      TokenPosition position,
+      intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
   Fragment EvaluateAssertion();
   Fragment RethrowException(TokenPosition position, int catch_try_index);
   Fragment ThrowNoSuchMethodError();
@@ -198,6 +201,7 @@
       const Array& argument_names,
       intptr_t checked_argument_count,
       const Function& interface_target,
+      const Function& tearoff_interface_target,
       const InferredTypeMetadata* result_type = nullptr,
       bool use_unchecked_entry = false,
       const CallSiteAttributesMetadata* call_site_attrs = nullptr,
@@ -382,5 +386,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_BINARY_FLOWGRAPH_H_
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 4247dae..b20ba94 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -5,8 +5,6 @@
 #include "vm/compiler/frontend/kernel_fingerprints.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #define H (translation_helper_)
 #define I Isolate::Current()
 
@@ -880,5 +878,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.h b/runtime/vm/compiler/frontend/kernel_fingerprints.h
index 601a488a..588d51f 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.h
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.h
@@ -5,11 +5,13 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_KERNEL_FINGERPRINTS_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_FINGERPRINTS_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "platform/allocation.h"
 #include "vm/object.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -23,5 +25,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_FINGERPRINTS_H_
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 375dc2f..de87175 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -24,8 +24,6 @@
 #include "vm/resolver.h"
 #include "vm/stack_frame.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -334,16 +332,17 @@
     const Array& argument_names,
     intptr_t checked_argument_count,
     const Function& interface_target,
+    const Function& tearoff_interface_target,
     const InferredTypeMetadata* result_type,
     bool use_unchecked_entry,
     const CallSiteAttributesMetadata* call_site_attrs,
     bool receiver_is_not_smi) {
   const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
   InputsArray* arguments = GetArguments(total_count);
-  InstanceCallInstr* call = new (Z)
-      InstanceCallInstr(position, name, kind, arguments, type_args_len,
-                        argument_names, checked_argument_count, ic_data_array_,
-                        GetNextDeoptId(), interface_target);
+  InstanceCallInstr* call = new (Z) InstanceCallInstr(
+      position, name, kind, arguments, type_args_len, argument_names,
+      checked_argument_count, ic_data_array_, GetNextDeoptId(),
+      interface_target, tearoff_interface_target);
   if ((result_type != NULL) && !result_type->IsTrivial()) {
     call->SetResultType(Z, result_type->ToCompileType(Z));
   }
@@ -436,69 +435,6 @@
   }
 }
 
-Fragment FlowGraphBuilder::LoadLateField(const Field& field,
-                                         LocalVariable* instance) {
-  Fragment instructions;
-  TargetEntryInstr *is_uninitialized, *is_initialized;
-  const TokenPosition position = field.token_pos();
-  const bool is_static = field.is_static();
-
-  // Check whether the field has been initialized already.
-  if (is_static) {
-    instructions += LoadStaticField(field);
-  } else {
-    instructions += LoadLocal(instance);
-    instructions += LoadField(field);
-  }
-
-  LocalVariable* temp = parsed_function_->expression_temp_var();
-  instructions += StoreLocal(position, temp);
-  instructions += Constant(Object::sentinel());
-  instructions += BranchIfStrictEqual(&is_uninitialized, &is_initialized);
-
-  JoinEntryInstr* join = BuildJoinEntry();
-
-  if (field.has_initializer()) {
-    // has_nontrivial_initializer is required for EnsureInitializerFunction. The
-    // trivial initializer case is treated as a normal field.
-    ASSERT(field.has_nontrivial_initializer());
-
-    // If the field isn't initialized, call the initializer and set the field.
-    Function& init_function =
-        Function::ZoneHandle(Z, field.EnsureInitializerFunction());
-    Fragment initialize(is_uninitialized);
-    if (is_static) {
-      initialize += StaticCall(position, init_function,
-                               /* argument_count = */ 0, ICData::kNoRebind);
-    } else {
-      initialize += LoadLocal(instance);
-      initialize += StaticCall(position, init_function,
-                               /* argument_count = */ 1, ICData::kNoRebind);
-    }
-    initialize += StoreLocal(position, temp);
-    initialize += Drop();
-    initialize += StoreLateField(field, instance, temp);
-    initialize += Goto(join);
-  } else {
-    // The field has no initializer, so throw a LateInitializationError.
-    Fragment initialize(is_uninitialized);
-    initialize += ThrowLateInitializationError(
-        position, String::ZoneHandle(Z, field.name()));
-    initialize += Goto(join);
-  }
-
-  {
-    // Already initialized, so there's nothing to do.
-    Fragment already_initialized(is_initialized);
-    already_initialized += Goto(join);
-  }
-
-  // Now that the field has been initialized, load it.
-  instructions = Fragment(instructions.entry, join);
-  instructions += LoadLocal(temp);
-  return instructions;
-}
-
 Fragment FlowGraphBuilder::ThrowLateInitializationError(TokenPosition position,
                                                         const String& name) {
   const Class& klass = Class::ZoneHandle(
@@ -574,7 +510,7 @@
 
 Fragment FlowGraphBuilder::InitInstanceField(const Field& field) {
   ASSERT(field.is_instance());
-  ASSERT(field.needs_load_guard());
+  ASSERT(field.NeedsInitializationCheckOnLoad());
   InitInstanceFieldInstr* init = new (Z)
       InitInstanceFieldInstr(Pop(), MayCloneField(field), GetNextDeoptId());
   return Fragment(init);
@@ -1601,7 +1537,7 @@
   if (!I->should_emit_strong_mode_checks()) {
     return Fragment();
   }
-  if (!dst_type.IsTopTypeForAssignability()) {
+  if (!dst_type.IsTopTypeForSubtyping()) {
     LocalVariable* top_of_stack = MakeTemporary();
     instructions += LoadLocal(top_of_stack);
     instructions += AssertAssignableLoadTypeArguments(TokenPosition::kNoSource,
@@ -1692,7 +1628,7 @@
     type_param ^= type_parameters.TypeAt(i);
 
     bound = type_param.bound();
-    if (bound.IsTopType()) {
+    if (bound.IsTopTypeForSubtyping()) {
       continue;
     }
 
@@ -1749,7 +1685,7 @@
           &AbstractType::ZoneHandle(Z, forwarding_target->ParameterTypeAt(i));
     }
 
-    if (target_type->IsTopTypeForAssignability()) continue;
+    if (target_type->IsTopTypeForSubtyping()) continue;
 
     const bool is_covariant = param->is_explicit_covariant_parameter();
     Fragment* checks = is_covariant ? explicit_checks : implicit_checks;
@@ -1786,8 +1722,7 @@
   return instruction_cursor;
 }
 
-RawArray* FlowGraphBuilder::GetOptionalParameterNames(
-    const Function& function) {
+ArrayPtr FlowGraphBuilder::GetOptionalParameterNames(const Function& function) {
   if (!function.HasOptionalNamedParameters()) {
     return Array::null();
   }
@@ -2030,8 +1965,7 @@
     const intptr_t kTypeArgsLen = 0;
     const intptr_t kNumArgsChecked = 1;
     body += InstanceCall(TokenPosition::kMinSource, getter_name, Token::kGET,
-                         kTypeArgsLen, 1, Array::null_array(), kNumArgsChecked,
-                         Function::null_function());
+                         kTypeArgsLen, 1, Array::null_array(), kNumArgsChecked);
   }
 
   // Push all arguments onto the stack.
@@ -2051,8 +1985,7 @@
     const intptr_t kNumArgsChecked = 1;
     body += InstanceCall(TokenPosition::kMinSource, Symbols::Call(),
                          Token::kILLEGAL, descriptor.TypeArgsLen(),
-                         descriptor.Count(), argument_names, kNumArgsChecked,
-                         Function::null_function());
+                         descriptor.Count(), argument_names, kNumArgsChecked);
   }
 
   body += Return(TokenPosition::kNoSource);
@@ -2312,7 +2245,7 @@
     body += InstanceCall(
         TokenPosition::kNoSource, Symbols::NoSuchMethod(), Token::kILLEGAL,
         /*type_args_len=*/0, /*argument_count=*/2, Array::null_array(),
-        /*checked_argument_count=*/1, Function::null_function());
+        /*checked_argument_count=*/1);
   }
   body += StoreLocal(TokenPosition::kNoSource, result);
   body += Drop();
@@ -2321,7 +2254,7 @@
   body += Drop();  // argument count
 
   AbstractType& return_type = AbstractType::Handle(function.result_type());
-  if (!return_type.IsTopTypeForAssignability()) {
+  if (!return_type.IsTopTypeForSubtyping()) {
     body += AssertAssignableLoadTypeArguments(TokenPosition::kNoSource,
                                               return_type, Symbols::Empty());
   }
@@ -2586,9 +2519,6 @@
     field = function.accessor_field();
   }
 
-  const Class& owner = Class::ZoneHandle(Z, field.Owner());
-  const bool lib_is_nnbd = Library::ZoneHandle(Z, owner.library()).is_nnbd();
-
   graph_entry_ =
       new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);
 
@@ -2630,24 +2560,22 @@
     }
     body += NullConstant();
   } else if (is_method) {
+    ASSERT(!field.needs_load_guard()
+                NOT_IN_PRODUCT(|| I->HasAttemptedReload()));
+    if (field.NeedsInitializationCheckOnLoad()) {
+      body += LoadLocal(parsed_function_->ParameterVariable(0));
+      body += InitInstanceField(field);
+    }
+
+    body += LoadLocal(parsed_function_->ParameterVariable(0));
+    body += LoadField(field);
     if (field.needs_load_guard()) {
 #if defined(PRODUCT)
       UNREACHABLE();
 #else
-      ASSERT(Isolate::Current()->HasAttemptedReload());
-      body += LoadLocal(parsed_function_->ParameterVariable(0));
-      body += InitInstanceField(field);
-
-      body += LoadLocal(parsed_function_->ParameterVariable(0));
-      body += LoadField(field);
       body += CheckAssignable(AbstractType::Handle(Z, field.type()),
                               Symbols::FunctionResult());
 #endif
-    } else if (field.is_late() && !field.has_trivial_initializer()) {
-      body += LoadLateField(field, parsed_function_->ParameterVariable(0));
-    } else {
-      body += LoadLocal(parsed_function_->ParameterVariable(0));
-      body += LoadField(field);
     }
   } else if (field.is_const()) {
     // If the parser needs to know the value of an uninitialized constant field
@@ -2659,18 +2587,17 @@
     ASSERT(!field.IsUninitialized());
     body += Constant(Instance::ZoneHandle(Z, field.StaticValue()));
   } else {
-    // The field always has an initializer because static fields without
-    // initializers are initialized eagerly and do not have implicit getters.
-    if (lib_is_nnbd) {
-      // In NNBD mode, static fields act like late fields regardless of whether
-      // they're marked late. The only behavioural difference is in compile
-      // errors that are handled by the front end.
-      body += LoadLateField(field, /* instance = */ nullptr);
-    } else {
-      ASSERT(field.has_nontrivial_initializer());
-      body += InitStaticField(field);
-      body += LoadStaticField(field);
-    }
+    // Static fields
+    //  - with trivial initializer
+    //  - without initializer if they are not late
+    // are initialized eagerly and do not have implicit getters.
+    // Static fields with non-trivial initializer need getter to perform
+    // lazy initialization. Late fields without initializer need getter
+    // to make sure they are already initialized.
+    ASSERT(field.has_nontrivial_initializer() ||
+           (field.is_late() && !field.has_initializer()));
+    body += InitStaticField(field);
+    body += LoadStaticField(field);
     if (field.needs_load_guard()) {
 #if defined(PRODUCT)
       UNREACHABLE();
@@ -3036,5 +2963,3 @@
 }  // namespace kernel
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index a61c5b1..f6f08e5 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TO_IL_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TO_IL_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/growable_array.h"
 #include "vm/hash_map.h"
@@ -68,7 +70,7 @@
                                  PrologueInfo* prologue_info);
 
   // Return names of optional named parameters of [function].
-  RawArray* GetOptionalParameterNames(const Function& function);
+  ArrayPtr GetOptionalParameterNames(const Function& function);
 
   // Generate fragment which pushes all explicit parameters of [function].
   Fragment PushExplicitParameters(
@@ -122,7 +124,8 @@
       intptr_t argument_count,
       const Array& argument_names,
       intptr_t checked_argument_count,
-      const Function& interface_target,
+      const Function& interface_target = Function::null_function(),
+      const Function& tearoff_interface_target = Function::null_function(),
       const InferredTypeMetadata* result_type = nullptr,
       bool use_unchecked_entry = false,
       const CallSiteAttributesMetadata* call_site_attrs = nullptr,
@@ -133,16 +136,16 @@
   Fragment ThrowException(TokenPosition position);
   Fragment RethrowException(TokenPosition position, int catch_try_index);
   Fragment LoadLocal(LocalVariable* variable);
-  Fragment LoadLateField(const Field& field, LocalVariable* instance);
   Fragment StoreLateField(const Field& field,
                           LocalVariable* instance,
                           LocalVariable* setter_value);
   Fragment InitInstanceField(const Field& field);
   Fragment InitStaticField(const Field& field);
   Fragment NativeCall(const String* name, const Function* function);
-  Fragment Return(TokenPosition position,
-                  bool omit_result_type_check = false,
-                  intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+  Fragment Return(
+      TokenPosition position,
+      bool omit_result_type_check = false,
+      intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
   void SetResultTypeForStaticCall(StaticCallInstr* call,
                                   const Function& target,
                                   intptr_t argument_count,
@@ -669,5 +672,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TO_IL_H_
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 6b311fb..80d6d2c 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -14,8 +14,6 @@
 #include "vm/parser.h"  // for ParsedFunction
 #include "vm/symbols.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #define Z (zone_)
 #define H (translation_helper_)
 #define T (type_translator_)
@@ -88,7 +86,7 @@
   SetKernelProgramInfo(info);
 }
 
-RawGrowableObjectArray* TranslationHelper::EnsurePotentialPragmaFunctions() {
+GrowableObjectArrayPtr TranslationHelper::EnsurePotentialPragmaFunctions() {
   auto& funcs =
       GrowableObjectArray::Handle(Z, info_.potential_pragma_functions());
   if (funcs.IsNull()) {
@@ -106,7 +104,7 @@
   potential_extension_libraries_->Add(library);
 }
 
-RawGrowableObjectArray* TranslationHelper::GetPotentialExtensionLibraries() {
+GrowableObjectArrayPtr TranslationHelper::GetPotentialExtensionLibraries() {
   if (potential_extension_libraries_ != nullptr) {
     GrowableObjectArray* result = potential_extension_libraries_;
     potential_extension_libraries_ = nullptr;
@@ -339,11 +337,11 @@
   return enclosing;
 }
 
-RawInstance* TranslationHelper::Canonicalize(const Instance& instance) {
+InstancePtr TranslationHelper::Canonicalize(const Instance& instance) {
   if (instance.IsNull()) return instance.raw();
 
   const char* error_str = NULL;
-  RawInstance* result = instance.CheckAndCanonicalize(thread(), &error_str);
+  InstancePtr result = instance.CheckAndCanonicalize(thread(), &error_str);
   if (result == Object::null()) {
     ReportError("Invalid const object %s", error_str);
   }
@@ -535,7 +533,7 @@
   }
 }
 
-RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary(
+LibraryPtr TranslationHelper::LookupLibraryByKernelLibrary(
     NameIndex kernel_library) {
   // We only use the string and don't rely on having any particular parent.
   // This ASSERT is just a sanity check.
@@ -543,7 +541,7 @@
          IsAdministrative(CanonicalNameParent(kernel_library)));
   {
     name_index_handle_ = Smi::New(kernel_library);
-    RawLibrary* raw_lib = info_.LookupLibrary(thread_, name_index_handle_);
+    LibraryPtr raw_lib = info_.LookupLibrary(thread_, name_index_handle_);
     NoSafepointScope no_safepoint_scope(thread_);
     if (raw_lib != Library::null()) {
       return raw_lib;
@@ -560,11 +558,11 @@
   return info_.InsertLibrary(thread_, name_index_handle_, library);
 }
 
-RawClass* TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
+ClassPtr TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
   ASSERT(IsClass(kernel_class));
   {
     name_index_handle_ = Smi::New(kernel_class);
-    RawClass* raw_class = info_.LookupClass(thread_, name_index_handle_);
+    ClassPtr raw_class = info_.LookupClass(thread_, name_index_handle_);
     NoSafepointScope no_safepoint_scope(thread_);
     if (raw_class != Class::null()) {
       return raw_class;
@@ -587,7 +585,7 @@
   return info_.InsertClass(thread_, name_index_handle_, klass);
 }
 
-RawField* TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
+FieldPtr TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
   ASSERT(IsField(kernel_field));
   NameIndex enclosing = EnclosingName(kernel_field);
 
@@ -608,7 +606,7 @@
   return field.raw();
 }
 
-RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure(
+FunctionPtr TranslationHelper::LookupStaticMethodByKernelProcedure(
     NameIndex procedure) {
   const String& procedure_name = DartProcedureName(procedure);
 
@@ -635,7 +633,7 @@
   }
 }
 
-RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+FunctionPtr TranslationHelper::LookupConstructorByKernelConstructor(
     NameIndex constructor) {
   ASSERT(IsConstructor(constructor));
   Class& klass =
@@ -644,7 +642,7 @@
   return LookupConstructorByKernelConstructor(klass, constructor);
 }
 
-RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+FunctionPtr TranslationHelper::LookupConstructorByKernelConstructor(
     const Class& owner,
     NameIndex constructor) {
   ASSERT(IsConstructor(constructor));
@@ -654,7 +652,7 @@
   return function.raw();
 }
 
-RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+FunctionPtr TranslationHelper::LookupConstructorByKernelConstructor(
     const Class& owner,
     StringIndex constructor_name) {
   GrowableHandlePtrArray<const String> pieces(Z, 3);
@@ -665,14 +663,13 @@
 
   String& new_name =
       String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces));
-  RawFunction* function = owner.LookupConstructorAllowPrivate(new_name);
+  FunctionPtr function = owner.LookupConstructorAllowPrivate(new_name);
   ASSERT(function != Object::null());
   return function;
 }
 
-RawFunction* TranslationHelper::LookupMethodByMember(
-    NameIndex target,
-    const String& method_name) {
+FunctionPtr TranslationHelper::LookupMethodByMember(NameIndex target,
+                                                    const String& method_name) {
   NameIndex kernel_class = EnclosingName(target);
   Class& klass = Class::Handle(Z, LookupClassByKernelClass(kernel_class));
 
@@ -689,12 +686,12 @@
   return function.raw();
 }
 
-RawFunction* TranslationHelper::LookupDynamicFunction(const Class& klass,
-                                                      const String& name) {
+FunctionPtr TranslationHelper::LookupDynamicFunction(const Class& klass,
+                                                     const String& name) {
   // Search the superclass chain for the selector.
   Class& iterate_klass = Class::Handle(Z, klass.raw());
   while (!iterate_klass.IsNull()) {
-    RawFunction* function =
+    FunctionPtr function =
         iterate_klass.LookupDynamicFunctionAllowPrivate(name);
     if (function != Object::null()) {
       return function;
@@ -1856,7 +1853,9 @@
 void TableSelectorMetadataHelper::ReadTableSelectorInfo(
     TableSelectorInfo* info) {
   info->call_count = helper_->ReadUInt();
-  info->called_on_null = helper_->ReadByte() != 0;
+  uint8_t flags = helper_->ReadByte();
+  info->called_on_null = (flags & kCalledOnNullBit) != 0;
+  info->torn_off = (flags & kTornOffBit) != 0;
 }
 
 UnboxingInfoMetadataHelper::UnboxingInfoMetadataHelper(
@@ -2654,14 +2653,33 @@
   return position;
 }
 
+intptr_t KernelReaderHelper::SourceTableFieldCountFromFirstLibraryOffset() {
+  // translation_helper_.info() might not be initialized at this point so we
+  // can't use translation_helper_.info().kernel_binary_version().
+  SetOffset(KernelFormatVersionOffset);
+  uint32_t formatVersion = reader_.ReadUInt32();
+  intptr_t count_from_first_library_offset =
+      SourceTableFieldCountFromFirstLibraryOffsetPre41;
+  static_assert(kMinSupportedKernelFormatVersion < 41, "cleanup this code");
+  if (formatVersion >= 41) {
+    count_from_first_library_offset =
+        SourceTableFieldCountFromFirstLibraryOffset41Plus;
+  }
+  return count_from_first_library_offset;
+}
+
 intptr_t KernelReaderHelper::SourceTableSize() {
   AlternativeReadingScope alt(&reader_);
   intptr_t library_count = reader_.ReadFromIndexNoReset(
       reader_.size(), LibraryCountFieldCountFromEnd, 1, 0);
+
+  const intptr_t count_from_first_library_offset =
+      SourceTableFieldCountFromFirstLibraryOffset();
+
   intptr_t source_table_offset = reader_.ReadFromIndexNoReset(
       reader_.size(),
       LibraryCountFieldCountFromEnd + 1 + library_count + 1 +
-          SourceTableFieldCountFromFirstLibraryOffset,
+          count_from_first_library_offset,
       1, 0);
   SetOffset(source_table_offset);  // read source table offset.
   return reader_.ReadUInt32();     // read source table size.
@@ -2671,10 +2689,14 @@
   AlternativeReadingScope alt(&reader_);
   intptr_t library_count = reader_.ReadFromIndexNoReset(
       reader_.size(), LibraryCountFieldCountFromEnd, 1, 0);
+
+  const intptr_t count_from_first_library_offset =
+      SourceTableFieldCountFromFirstLibraryOffset();
+
   intptr_t source_table_offset = reader_.ReadFromIndexNoReset(
       reader_.size(),
       LibraryCountFieldCountFromEnd + 1 + library_count + 1 +
-          SourceTableFieldCountFromFirstLibraryOffset,
+          count_from_first_library_offset,
       1, 0);
   intptr_t next_field_offset = reader_.ReadUInt32();
   SetOffset(source_table_offset);
@@ -2703,7 +2725,7 @@
   }
 }
 
-RawTypedData* KernelReaderHelper::GetLineStartsFor(intptr_t index) {
+TypedDataPtr KernelReaderHelper::GetLineStartsFor(intptr_t index) {
   // Line starts are delta encoded. So get the max delta first so that we
   // can store them as tighly as possible.
   AlternativeReadingScope alt(&reader_);
@@ -2862,9 +2884,11 @@
       break;
     case kNeverType: {
       const Nullability nullability = helper_->ReadNullability();
-      result_ = Object::never_type().ToNullability(nullability, Heap::kOld);
-      if (apply_legacy_erasure_ && result_.IsNeverType()) {
+      if (apply_legacy_erasure_) {
         result_ = I->object_store()->null_type();
+      } else {
+        result_ = Type::Handle(Z, I->object_store()->never_type())
+                      .ToNullability(nullability, Heap::kOld);
       }
       break;
     }
@@ -3314,9 +3338,7 @@
     type = klass.DeclarationType();
   } else {
     type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
-                     klass.token_pos(),
-                     Dart::non_nullable_flag() ? Nullability::kNonNullable
-                                               : Nullability::kLegacy);
+                     klass.token_pos(), Nullability::kNonNullable);
   }
   return type;
 }
@@ -3502,5 +3524,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 4597fb6..e6f25bf 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -5,13 +5,15 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TRANSLATION_HELPER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TRANSLATION_HELPER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/backend/il.h"  // For CompileType.
 #include "vm/kernel.h"
 #include "vm/kernel_binary.h"
 #include "vm/object.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -71,10 +73,10 @@
 
   KernelProgramInfo& info() { return info_; }
 
-  RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
+  GrowableObjectArrayPtr EnsurePotentialPragmaFunctions();
 
   void AddPotentialExtensionLibrary(const Library& library);
-  RawGrowableObjectArray* GetPotentialExtensionLibraries();
+  GrowableObjectArrayPtr GetPotentialExtensionLibraries();
 
   void SetKernelProgramInfo(const KernelProgramInfo& info);
   const KernelProgramInfo& GetKernelProgramInfo() const { return info_; }
@@ -111,7 +113,7 @@
   // of the enclosing class or library.
   NameIndex EnclosingName(NameIndex name);
 
-  RawInstance* Canonicalize(const Instance& instance);
+  InstancePtr Canonicalize(const Instance& instance);
 
   const String& DartString(const char* content) {
     return DartString(content, allocation_space_);
@@ -157,20 +159,19 @@
   // A subclass overrides these when reading in the Kernel program in order to
   // support recursive type expressions (e.g. for "implements X" ...
   // annotations).
-  virtual RawLibrary* LookupLibraryByKernelLibrary(NameIndex library);
-  virtual RawClass* LookupClassByKernelClass(NameIndex klass);
+  virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
+  virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
 
-  RawField* LookupFieldByKernelField(NameIndex field);
-  RawFunction* LookupStaticMethodByKernelProcedure(NameIndex procedure);
-  RawFunction* LookupConstructorByKernelConstructor(NameIndex constructor);
-  RawFunction* LookupConstructorByKernelConstructor(const Class& owner,
-                                                    NameIndex constructor);
-  RawFunction* LookupConstructorByKernelConstructor(
+  FieldPtr LookupFieldByKernelField(NameIndex field);
+  FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure);
+  FunctionPtr LookupConstructorByKernelConstructor(NameIndex constructor);
+  FunctionPtr LookupConstructorByKernelConstructor(const Class& owner,
+                                                   NameIndex constructor);
+  FunctionPtr LookupConstructorByKernelConstructor(
       const Class& owner,
       StringIndex constructor_name);
-  RawFunction* LookupMethodByMember(NameIndex target,
-                                    const String& method_name);
-  RawFunction* LookupDynamicFunction(const Class& klass, const String& name);
+  FunctionPtr LookupMethodByMember(NameIndex target, const String& method_name);
+  FunctionPtr LookupDynamicFunction(const Class& klass, const String& name);
 
   Type& GetDeclarationType(const Class& klass);
 
@@ -191,7 +192,7 @@
                    const char* format,
                    ...) PRINTF_ATTRIBUTE(5, 6);
 
-  RawArray* GetBytecodeComponent() const { return info_.bytecode_component(); }
+  ArrayPtr GetBytecodeComponent() const { return info_.bytecode_component(); }
   void SetBytecodeComponent(const Array& bytecode_component) {
     info_.set_bytecode_component(bytecode_component);
   }
@@ -211,7 +212,7 @@
     ASSERT(!real_class.IsNull());
     expression_evaluation_real_class_ = &Class::Handle(zone_, real_class.raw());
   }
-  RawClass* GetExpressionEvaluationRealClass() {
+  ClassPtr GetExpressionEvaluationRealClass() {
     ASSERT(expression_evaluation_real_class_ != nullptr);
     return expression_evaluation_real_class_->raw();
   }
@@ -958,7 +959,9 @@
   CompileType ToCompileType(Zone* zone) const {
     if (IsInt() && cid == kDynamicCid) {
       return CompileType::FromAbstractType(
-          Type::ZoneHandle(zone, Type::IntType()), IsNullable());
+          Type::ZoneHandle(
+              zone, (IsNullable() ? Type::NullableIntType() : Type::IntType())),
+          IsNullable());
     } else {
       return CompileType::CreateNullable(IsNullable(), cid);
     }
@@ -1052,6 +1055,7 @@
 struct TableSelectorInfo {
   int call_count = 0;
   bool called_on_null = true;
+  bool torn_off = true;
 };
 
 // Collection of table selector information for all selectors in the program.
@@ -1077,8 +1081,8 @@
   TableSelectorMetadata* GetTableSelectorMetadata(Zone* zone);
 
  private:
-  static const int32_t kCalledOnNullBit = 1 << 0;
-  static const int32_t kCallCountShift = 1;
+  static const uint8_t kCalledOnNullBit = 1 << 0;
+  static const uint8_t kTornOffBit = 1 << 1;
 
   void ReadTableSelectorInfo(TableSelectorInfo* info);
 
@@ -1218,11 +1222,12 @@
   Nullability ReadNullability();
   Variance ReadVariance();
 
+  intptr_t SourceTableFieldCountFromFirstLibraryOffset();
   intptr_t SourceTableSize();
   intptr_t GetOffsetForSourceInfo(intptr_t index);
   String& SourceTableUriFor(intptr_t index);
   const String& GetSourceFor(intptr_t index);
-  RawTypedData* GetLineStartsFor(intptr_t index);
+  TypedDataPtr GetLineStartsFor(intptr_t index);
   String& SourceTableImportUriFor(intptr_t index, uint32_t binaryVersion);
 
   Zone* zone_;
@@ -1280,12 +1285,12 @@
 
   bool MemberIsProcedure() {
     ASSERT(member != NULL);
-    RawFunction::Kind function_kind = member->kind();
-    return function_kind == RawFunction::kRegularFunction ||
-           function_kind == RawFunction::kGetterFunction ||
-           function_kind == RawFunction::kSetterFunction ||
-           function_kind == RawFunction::kMethodExtractor ||
-           function_kind == RawFunction::kDynamicInvocationForwarder ||
+    FunctionLayout::Kind function_kind = member->kind();
+    return function_kind == FunctionLayout::kRegularFunction ||
+           function_kind == FunctionLayout::kGetterFunction ||
+           function_kind == FunctionLayout::kSetterFunction ||
+           function_kind == FunctionLayout::kMethodExtractor ||
+           function_kind == FunctionLayout::kDynamicInvocationForwarder ||
            member->IsFactory();
   }
 
@@ -1502,5 +1507,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TRANSLATION_HELPER_H_
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 71fff65..ea3375b 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -15,7 +15,6 @@
 #include "vm/resolver.h"
 #include "vm/stack_frame.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 namespace dart {
 namespace kernel {
 
@@ -530,5 +529,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index 3f58e13..cef094c 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/frontend/base_flow_graph_builder.h"
 
@@ -75,7 +77,7 @@
     }
 
     ASSERT(parsed_function_->function().kind() ==
-           RawFunction::kNoSuchMethodDispatcher);
+           FunctionLayout::kNoSuchMethodDispatcher);
     return Instance::null_instance();
   }
 
@@ -90,5 +92,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_PROLOGUE_BUILDER_H_
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 1d7e9c8..78903ef 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -7,8 +7,6 @@
 #include "vm/compiler/backend/il.h"  // For CompileType.
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 namespace kernel {
 
@@ -148,12 +146,12 @@
           function.kernel_offset());
 
   switch (function.kind()) {
-    case RawFunction::kClosureFunction:
-    case RawFunction::kImplicitClosureFunction:
-    case RawFunction::kRegularFunction:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kConstructor: {
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kImplicitClosureFunction:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kConstructor: {
       const Tag tag = helper_.PeekTag();
       helper_.ReadUntilFunctionNode();
       function_node_helper.ReadUntilExcluding(
@@ -273,8 +271,8 @@
       }
       break;
     }
-    case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitSetter: {
+    case FunctionLayout::kImplicitGetter:
+    case FunctionLayout::kImplicitSetter: {
       ASSERT(helper_.PeekTag() == kField);
       const bool is_setter = function.IsImplicitSetterFunction();
       const bool is_method = !function.IsStaticFunction();
@@ -317,32 +315,21 @@
                 LocalVariable::kTypeCheckedByCaller);
           }
         }
-      } else {
-        if (field.is_late()) {
-          // LoadLateField uses expression_temp_var.
-          needs_expr_temp_ = true;
-        }
       }
       break;
     }
-    case RawFunction::kImplicitStaticGetter: {
+    case FunctionLayout::kImplicitStaticGetter: {
       ASSERT(helper_.PeekTag() == kField);
       ASSERT(function.IsStaticFunction());
-      const auto& field = Field::Handle(Z, function.accessor_field());
       // In addition to static field initializers, scopes/local variables
       // are needed for implicit getters of static const fields, in order to
       // be able to evaluate their initializers in constant evaluator.
       if (Field::Handle(Z, function.accessor_field()).is_const()) {
         VisitNode();
       }
-      const bool lib_is_nnbd = function.nnbd_mode() == NNBDMode::kOptedInLib;
-      if (field.is_late() || lib_is_nnbd) {
-        // LoadLateField uses expression_temp_var.
-        needs_expr_temp_ = true;
-      }
       break;
     }
-    case RawFunction::kFieldInitializer: {
+    case FunctionLayout::kFieldInitializer: {
       ASSERT(helper_.PeekTag() == kField);
       if (!function.is_static()) {
         Class& klass = Class::Handle(Z, function.Owner());
@@ -356,7 +343,7 @@
       VisitNode();
       break;
     }
-    case RawFunction::kDynamicInvocationForwarder: {
+    case FunctionLayout::kDynamicInvocationForwarder: {
       if (helper_.PeekTag() == kField) {
 #ifdef DEBUG
         String& name = String::Handle(Z, function.name());
@@ -397,7 +384,7 @@
       }
       break;
     }
-    case RawFunction::kMethodExtractor: {
+    case FunctionLayout::kMethodExtractor: {
       // Add a receiver parameter.  Though it is captured, we emit code to
       // explicitly copy it to a fixed offset in a freshly-allocated context
       // instead of using the generic code for regular functions.
@@ -411,9 +398,9 @@
       parsed_function_->set_receiver_var(variable);
       break;
     }
-    case RawFunction::kNoSuchMethodDispatcher:
-    case RawFunction::kInvokeFieldDispatcher:
-    case RawFunction::kFfiTrampoline:
+    case FunctionLayout::kNoSuchMethodDispatcher:
+    case FunctionLayout::kInvokeFieldDispatcher:
+    case FunctionLayout::kFfiTrampoline:
       for (intptr_t i = 0; i < function.NumParameters(); ++i) {
         LocalVariable* variable = MakeVariable(
             TokenPosition::kNoSource, TokenPosition::kNoSource,
@@ -436,8 +423,8 @@
         --depth_.catch_;
       }
       break;
-    case RawFunction::kSignatureFunction:
-    case RawFunction::kIrregexpFunction:
+    case FunctionLayout::kSignatureFunction:
+    case FunctionLayout::kIrregexpFunction:
       UNREACHABLE();
   }
   if (needs_expr_temp_) {
@@ -1864,5 +1851,3 @@
 
 }  // namespace kernel
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/scope_builder.h b/runtime/vm/compiler/frontend/scope_builder.h
index 391f971..4f53fbd 100644
--- a/runtime/vm/compiler/frontend/scope_builder.h
+++ b/runtime/vm/compiler/frontend/scope_builder.h
@@ -5,7 +5,9 @@
 #ifndef RUNTIME_VM_COMPILER_FRONTEND_SCOPE_BUILDER_H_
 #define RUNTIME_VM_COMPILER_FRONTEND_SCOPE_BUILDER_H_
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/frontend/constant_reader.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
@@ -237,5 +239,4 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_SCOPE_BUILDER_H_
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index af792ff..3a42c2d 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -3,8 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 // Class for intrinsifying functions.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/graph_intrinsifier.h"
 #include "vm/compiler/backend/block_builder.h"
 #include "vm/compiler/backend/flow_graph.h"
@@ -189,7 +187,7 @@
   index = PrepareIndexedOp(flow_graph, &builder, array, index,
                            Slot::GetLengthFieldForArrayCid(array_cid));
 
-  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+  if (IsExternalTypedDataClassId(array_cid)) {
     array = builder.AddDefinition(new LoadUntaggedInstr(
         new Value(array), target::TypedDataBase::data_field_offset()));
   }
@@ -369,13 +367,13 @@
       UNREACHABLE();
   }
 
-  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+  if (IsExternalTypedDataClassId(array_cid)) {
     array = builder.AddDefinition(new LoadUntaggedInstr(
         new Value(array), target::TypedDataBase::data_field_offset()));
   }
   // No store barrier.
-  ASSERT(RawObject::IsExternalTypedDataClassId(array_cid) ||
-         RawObject::IsTypedDataClassId(array_cid));
+  ASSERT(IsExternalTypedDataClassId(array_cid) ||
+         IsTypedDataClassId(array_cid));
   builder.AddInstruction(new StoreIndexedInstr(
       new Value(array), new Value(index), new Value(value), kNoStoreBarrier,
       /*index_unboxed=*/false,
@@ -1074,5 +1072,3 @@
 
 }  // namespace compiler
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/graph_intrinsifier.h b/runtime/vm/compiler/graph_intrinsifier.h
index 3e398f1..c122b5c 100644
--- a/runtime/vm/compiler/graph_intrinsifier.h
+++ b/runtime/vm/compiler/graph_intrinsifier.h
@@ -6,6 +6,10 @@
 #ifndef RUNTIME_VM_COMPILER_GRAPH_INTRINSIFIER_H_
 #define RUNTIME_VM_COMPILER_GRAPH_INTRINSIFIER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/compiler/recognized_methods_list.h"
 
diff --git a/runtime/vm/compiler/graph_intrinsifier_arm.cc b/runtime/vm/compiler/graph_intrinsifier_arm.cc
index 39b30c2..cc8dc4c 100644
--- a/runtime/vm/compiler/graph_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_arm.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM)
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/graph_intrinsifier.h"
@@ -42,4 +42,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/graph_intrinsifier_arm64.cc b/runtime/vm/compiler/graph_intrinsifier_arm64.cc
index 0dc98a7..9bd2ae5 100644
--- a/runtime/vm/compiler/graph_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_arm64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM64)
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/graph_intrinsifier.h"
@@ -47,4 +47,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/graph_intrinsifier_ia32.cc b/runtime/vm/compiler/graph_intrinsifier_ia32.cc
index e89c176..6e29ff5 100644
--- a/runtime/vm/compiler/graph_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_ia32.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_IA32)
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/graph_intrinsifier.h"
@@ -34,4 +34,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/graph_intrinsifier_x64.cc b/runtime/vm/compiler/graph_intrinsifier_x64.cc
index 46a8004..58c02b2 100644
--- a/runtime/vm/compiler/graph_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_x64.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_X64)
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/graph_intrinsifier.h"
@@ -42,4 +42,4 @@
 }  // namespace compiler
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 73daa5b..7c6d764 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -3,8 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 // Class for intrinsifying functions.
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/intrinsifier.h"
 
 #include "vm/compiler/assembler/assembler.h"
@@ -76,7 +74,6 @@
   return true;
 }
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 struct IntrinsicDesc {
   const char* class_name;
   const char* function_name;
@@ -172,7 +169,6 @@
   }
 #undef SETUP_FUNCTION
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 // Returns true if fall-through code can be omitted.
 bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
@@ -238,5 +234,3 @@
 
 }  // namespace compiler
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/intrinsifier.h b/runtime/vm/compiler/intrinsifier.h
index 3aa9148..f8895a4 100644
--- a/runtime/vm/compiler/intrinsifier.h
+++ b/runtime/vm/compiler/intrinsifier.h
@@ -6,6 +6,10 @@
 #ifndef RUNTIME_VM_COMPILER_INTRINSIFIER_H_
 #define RUNTIME_VM_COMPILER_INTRINSIFIER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/compiler/asm_intrinsifier.h"
 #include "vm/compiler/graph_intrinsifier.h"
@@ -26,9 +30,8 @@
  public:
   static bool Intrinsify(const ParsedFunction& parsed_function,
                          FlowGraphCompiler* compiler);
-#if !defined(DART_PRECOMPILED_RUNTIME)
+
   static void InitializeState();
-#endif
 
  private:
   static bool CanIntrinsify(const Function& function);
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index ea9e245..1364dd0 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -4,9 +4,9 @@
 
 #include "vm/compiler/jit/compiler.h"
 
-#include "vm/compiler/assembler/assembler.h"
-
+#if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/code_patcher.h"
+#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/compiler/backend/block_scheduler.h"
 #include "vm/compiler/backend/branch_optimizer.h"
@@ -45,6 +45,7 @@
 #include "vm/thread_registry.h"
 #include "vm/timeline.h"
 #include "vm/timer.h"
+#endif
 
 namespace dart {
 
@@ -322,7 +323,7 @@
         osr_id_(osr_id),
         thread_(Thread::Current()) {}
 
-  RawCode* Compile(CompilationPipeline* pipeline);
+  CodePtr Compile(CompilationPipeline* pipeline);
 
  private:
   ParsedFunction* parsed_function() const { return parsed_function_; }
@@ -330,9 +331,9 @@
   intptr_t osr_id() const { return osr_id_; }
   Thread* thread() const { return thread_; }
   Isolate* isolate() const { return thread_->isolate(); }
-  RawCode* FinalizeCompilation(compiler::Assembler* assembler,
-                               FlowGraphCompiler* graph_compiler,
-                               FlowGraph* flow_graph);
+  CodePtr FinalizeCompilation(compiler::Assembler* assembler,
+                              FlowGraphCompiler* graph_compiler,
+                              FlowGraph* flow_graph);
   void CheckIfBackgroundCompilerIsBeingStopped(bool optimizing_compiler);
 
   ParsedFunction* parsed_function_;
@@ -343,7 +344,7 @@
   DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
 };
 
-RawCode* CompileParsedFunctionHelper::FinalizeCompilation(
+CodePtr CompileParsedFunctionHelper::FinalizeCompilation(
     compiler::Assembler* assembler,
     FlowGraphCompiler* graph_compiler,
     FlowGraph* flow_graph) {
@@ -501,7 +502,7 @@
 // Return null if bailed out.
 // If optimized_result_code is not NULL then it is caller's responsibility
 // to install code.
-RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
+CodePtr CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
   ASSERT(!FLAG_precompiled_mode);
   const Function& function = parsed_function()->function();
   if (optimized() && !function.IsOptimizable()) {
@@ -711,10 +712,10 @@
   return result->raw();
 }
 
-static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline,
-                                        const Function& function,
-                                        volatile bool optimized,
-                                        intptr_t osr_id) {
+static ObjectPtr CompileFunctionHelper(CompilationPipeline* pipeline,
+                                       const Function& function,
+                                       volatile bool optimized,
+                                       intptr_t osr_id) {
   ASSERT(!FLAG_precompiled_mode);
   ASSERT(!optimized || function.WasCompiled() || function.ForceOptimize());
   ASSERT(function.is_background_optimizable() ||
@@ -859,7 +860,7 @@
   return Object::null();
 }
 
-RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
+ObjectPtr Compiler::CompileFunction(Thread* thread, const Function& function) {
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
   RELEASE_ASSERT(!FLAG_precompiled_mode);
 #endif
@@ -889,8 +890,8 @@
   return CompileFunctionHelper(pipeline, function, optimized, kNoOSRDeoptId);
 }
 
-RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
-                                          const Function& function) {
+ErrorPtr Compiler::EnsureUnoptimizedCode(Thread* thread,
+                                         const Function& function) {
   ASSERT(!function.ForceOptimize());
   if (function.unoptimized_code() != Object::null()) {
     return Error::null();
@@ -921,9 +922,9 @@
   return Error::null();
 }
 
-RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
-                                              const Function& function,
-                                              intptr_t osr_id) {
+ObjectPtr Compiler::CompileOptimizedFunction(Thread* thread,
+                                             const Function& function,
+                                             intptr_t osr_id) {
   VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId);
 #if defined(SUPPORT_TIMELINE)
   const char* event_name;
@@ -997,7 +998,7 @@
   }
 }
 
-RawError* Compiler::CompileAllFunctions(const Class& cls) {
+ErrorPtr Compiler::CompileAllFunctions(const Class& cls) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Object& result = Object::Handle(zone);
@@ -1019,7 +1020,7 @@
   return Error::null();
 }
 
-RawError* Compiler::ReadAllBytecode(const Class& cls) {
+ErrorPtr Compiler::ReadAllBytecode(const Class& cls) {
   Thread* thread = Thread::Current();
   ASSERT(thread->IsMutatorThread());
   Zone* zone = thread->zone();
@@ -1033,7 +1034,7 @@
     ASSERT(!func.IsNull());
     if (func.IsBytecodeAllowed(zone) && !func.HasBytecode() &&
         !func.HasCode()) {
-      RawError* error =
+      ErrorPtr error =
           kernel::BytecodeReader::ReadFunctionBytecode(thread, func);
       if (error != Error::null()) {
         return error;
@@ -1074,19 +1075,17 @@
     function_ = Function::null();
   }
 
-  RawFunction* Function() const { return function_; }
+  FunctionPtr Function() const { return function_; }
 
   void set_next(QueueElement* elem) { next_ = elem; }
   QueueElement* next() const { return next_; }
 
-  RawObject* function() const { return function_; }
-  RawObject** function_ptr() {
-    return reinterpret_cast<RawObject**>(&function_);
-  }
+  ObjectPtr function() const { return function_; }
+  ObjectPtr* function_ptr() { return reinterpret_cast<ObjectPtr*>(&function_); }
 
  private:
   QueueElement* next_;
-  RawFunction* function_;
+  FunctionPtr function_;
 
   DISALLOW_COPY_AND_ASSIGN(QueueElement);
 };
@@ -1125,7 +1124,7 @@
 
   QueueElement* Peek() const { return first_; }
 
-  RawFunction* PeekFunction() const {
+  FunctionPtr PeekFunction() const {
     QueueElement* e = Peek();
     if (e == NULL) {
       return Function::null();
@@ -1365,20 +1364,20 @@
   return false;
 }
 
-RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
+ObjectPtr Compiler::CompileFunction(Thread* thread, const Function& function) {
   FATAL1("Attempt to compile function %s", function.ToCString());
   return Error::null();
 }
 
-RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
-                                          const Function& function) {
+ErrorPtr Compiler::EnsureUnoptimizedCode(Thread* thread,
+                                         const Function& function) {
   FATAL1("Attempt to compile function %s", function.ToCString());
   return Error::null();
 }
 
-RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
-                                              const Function& function,
-                                              intptr_t osr_id) {
+ObjectPtr Compiler::CompileOptimizedFunction(Thread* thread,
+                                             const Function& function,
+                                             intptr_t osr_id) {
   FATAL1("Attempt to compile function %s", function.ToCString());
   return Error::null();
 }
@@ -1387,7 +1386,7 @@
   UNREACHABLE();
 }
 
-RawError* Compiler::CompileAllFunctions(const Class& cls) {
+ErrorPtr Compiler::CompileAllFunctions(const Class& cls) {
   FATAL1("Attempt to compile class %s", cls.ToCString());
   return Error::null();
 }
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h
index a810124..29029df 100644
--- a/runtime/vm/compiler/jit/compiler.h
+++ b/runtime/vm/compiler/jit/compiler.h
@@ -6,7 +6,7 @@
 #define RUNTIME_VM_COMPILER_JIT_COMPILER_H_
 
 #include "vm/allocation.h"
-#include "vm/compiler/compiler_state.h"
+#include "vm/compiler/api/deopt_id.h"
 #include "vm/growable_array.h"
 #include "vm/runtime_entry.h"
 #include "vm/thread_pool.h"
@@ -24,7 +24,6 @@
 class Library;
 class ParsedFunction;
 class QueueElement;
-class RawInstance;
 class Script;
 class SequenceNode;
 
@@ -82,13 +81,13 @@
   //
   // Returns the raw code object if compilation succeeds.  Otherwise returns a
   // RawError.  Also installs the generated code on the function.
-  static RawObject* CompileFunction(Thread* thread, const Function& function);
+  static ObjectPtr CompileFunction(Thread* thread, const Function& function);
 
   // Generates unoptimized code if not present, current code is unchanged.
   // Bytecode is considered unoptimized code.
   // TODO(regis): Revisit when deoptimizing mixed bytecode and jitted code.
-  static RawError* EnsureUnoptimizedCode(Thread* thread,
-                                         const Function& function);
+  static ErrorPtr EnsureUnoptimizedCode(Thread* thread,
+                                        const Function& function);
 
   // Generates optimized code for function.
   //
@@ -96,9 +95,9 @@
   // there is a compilation error.  If optimization fails, but there is no
   // error, returns null.  Any generated code is installed unless we are in
   // OSR mode.
-  static RawObject* CompileOptimizedFunction(Thread* thread,
-                                             const Function& function,
-                                             intptr_t osr_id = kNoOSRDeoptId);
+  static ObjectPtr CompileOptimizedFunction(Thread* thread,
+                                            const Function& function,
+                                            intptr_t osr_id = kNoOSRDeoptId);
 
   // Generates local var descriptors and sets it in 'code'. Do not call if the
   // local var descriptor already exists.
@@ -107,10 +106,10 @@
   // Eagerly compiles all functions in a class.
   //
   // Returns Error::null() if there is no compilation error.
-  static RawError* CompileAllFunctions(const Class& cls);
+  static ErrorPtr CompileAllFunctions(const Class& cls);
 
   // Eagerly read all bytecode.
-  static RawError* ReadAllBytecode(const Class& cls);
+  static ErrorPtr ReadAllBytecode(const Class& cls);
 
   // Notify the compiler that background (optimized) compilation has failed
   // because the mutator thread changed the state (e.g., deoptimization,
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc
index cfff542..688084b 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.cc
+++ b/runtime/vm/compiler/jit/jit_call_specializer.cc
@@ -1,7 +1,6 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-#ifndef DART_PRECOMPILED_RUNTIME
 #include "vm/compiler/jit/jit_call_specializer.h"
 
 #include "vm/bit_vector.h"
@@ -279,4 +278,3 @@
 }
 
 }  // namespace dart
-#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.h b/runtime/vm/compiler/jit/jit_call_specializer.h
index ea35fa9..8c743ed 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.h
+++ b/runtime/vm/compiler/jit/jit_call_specializer.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_JIT_JIT_CALL_SPECIALIZER_H_
 #define RUNTIME_VM_COMPILER_JIT_JIT_CALL_SPECIALIZER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/compiler/call_specializer.h"
 
 namespace dart {
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 99d186f..9fb302e 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -194,7 +194,6 @@
   return "?";
 }
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 void MethodRecognizer::InitializeState() {
   GrowableArray<Library*> libs(3);
   Libraries(&libs);
@@ -257,7 +256,6 @@
   libs->Add(&Library::ZoneHandle(Library::AsyncLibrary()));
   libs->Add(&Library::ZoneHandle(Library::FfiLibrary()));
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 Token::Kind MethodTokenRecognizer::RecognizeTokenKind(const String& name_) {
   Thread* thread = Thread::Current();
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index 1cf5d5b..30b0443 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -16,8 +16,6 @@
 class Function;
 class Library;
 class Object;
-class RawFunction;
-class RawGrowableObjectArray;
 class String;
 class Zone;
 
@@ -55,12 +53,10 @@
   static intptr_t MethodKindToReceiverCid(Kind kind);
   static const char* KindToCString(Kind kind);
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
   static void InitializeState();
 
  private:
   static void Libraries(GrowableArray<Library*>* libs);
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 };
 
 // Recognizes token corresponding to a method name.
@@ -69,13 +65,11 @@
   static Token::Kind RecognizeTokenKind(const String& name);
 };
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 #define CHECK_FINGERPRINT2(f, p0, p1, fp)                                      \
   ASSERT(f.CheckSourceFingerprint(#p0 ", " #p1, fp))
 
 #define CHECK_FINGERPRINT3(f, p0, p1, p2, fp)                                  \
   ASSERT(f.CheckSourceFingerprint(#p0 ", " #p1 ", " #p2, fp))
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 // Class that recognizes factories and returns corresponding result cid.
 class FactoryRecognizer : public AllStatic {
diff --git a/runtime/vm/compiler/offsets_extractor.cc b/runtime/vm/compiler/offsets_extractor.cc
index 5e82260..fc507f0 100644
--- a/runtime/vm/compiler/offsets_extractor.cc
+++ b/runtime/vm/compiler/offsets_extractor.cc
@@ -47,10 +47,10 @@
 #define PRINT_ARRAY_LAYOUT(Class, Name)                                        \
   std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
                "_elements_start_offset = "                                     \
-            << Class::ArrayLayout::elements_start_offset() << ";\n";           \
+            << Class::ArrayTraits::elements_start_offset() << ";\n";           \
   std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
                "_element_size = "                                              \
-            << Class::ArrayLayout::kElementSize << ";\n";
+            << Class::ArrayTraits::kElementSize << ";\n";
 
 #define PRINT_ARRAY_STRUCTFIELD_OFFSET(Class, Name, ElementOffsetName,         \
                                        FieldOffset)
@@ -92,10 +92,10 @@
 #define PRINT_ARRAY_LAYOUT(Class, Name)                                        \
   std::cout << "static constexpr dart::compiler::target::word " #Class         \
                "_elements_start_offset = "                                     \
-            << Class::ArrayLayout::elements_start_offset() << ";\n";           \
+            << Class::ArrayTraits::elements_start_offset() << ";\n";           \
   std::cout << "static constexpr dart::compiler::target::word " #Class         \
                "_element_size = "                                              \
-            << Class::ArrayLayout::kElementSize << ";\n";
+            << Class::ArrayTraits::kElementSize << ";\n";
 
 #define PRINT_ARRAY_STRUCTFIELD_OFFSET(Class, Name, ElementOffsetName,         \
                                        FieldOffset)
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index 48bf5a7..c32196be 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -28,9 +28,10 @@
     kObjectAlignment);
 
 CodeRelocator::CodeRelocator(Thread* thread,
-                             GrowableArray<RawCode*>* code_objects,
+                             GrowableArray<CodePtr>* code_objects,
                              GrowableArray<ImageWriterCommand>* commands)
     : StackResource(thread),
+      thread_(thread),
       code_objects_(code_objects),
       commands_(commands),
       kind_type_and_offset_(Smi::Handle(thread->zone())),
@@ -103,7 +104,7 @@
 }
 
 void CodeRelocator::FindInstructionAndCallLimits() {
-  Zone* zone = Thread::Current()->zone();
+  auto zone = thread_->zone();
   auto& current_caller = Code::Handle(zone);
   auto& call_targets = Array::Handle(zone);
 
@@ -131,30 +132,28 @@
         if (kind == Code::kCallViaCode) {
           continue;
         }
-        num_calls++;
 
-        target_ = call.Get<Code::kSCallTableFunctionTarget>();
-        if (target_.IsFunction()) {
-          auto& fun = Function::Cast(target_);
-          ASSERT(fun.HasCode());
-          destination_ = fun.CurrentCode();
-          ASSERT(!destination_.IsStubCode());
-        } else {
-          target_ = call.Get<Code::kSCallTableCodeTarget>();
-          ASSERT(target_.IsCode());
-          destination_ = Code::Cast(target_).raw();
-        }
+        destination_ = GetTarget(call);
+        num_calls++;
 
         // A call site can decide to jump not to the beginning of a function but
         // rather jump into it at a certain (positive) offset.
         int32_t offset_into_target = 0;
-        const intptr_t call_instruction_offset =
-            return_pc_offset - PcRelativeCallPattern::kLengthInBytes;
-        {
+        if (kind == Code::kPcRelativeCall || kind == Code::kPcRelativeTTSCall) {
+          const intptr_t call_instruction_offset =
+              return_pc_offset - PcRelativeCallPattern::kLengthInBytes;
           PcRelativeCallPattern call(current_caller.PayloadStart() +
                                      call_instruction_offset);
           ASSERT(call.IsValid());
           offset_into_target = call.distance();
+        } else {
+          ASSERT(kind == Code::kPcRelativeTailCall);
+          const intptr_t call_instruction_offset =
+              return_pc_offset - PcRelativeTailCallPattern::kLengthInBytes;
+          PcRelativeTailCallPattern call(current_caller.PayloadStart() +
+                                         call_instruction_offset);
+          ASSERT(call.IsValid());
+          offset_into_target = call.distance();
         }
 
         const uword destination_payload = destination_.PayloadStart();
@@ -176,8 +175,8 @@
   }
 }
 
-bool CodeRelocator::AddInstructionsToText(RawCode* code) {
-  RawInstructions* instructions = Code::InstructionsOf(code);
+bool CodeRelocator::AddInstructionsToText(CodePtr code) {
+  InstructionsPtr instructions = Code::InstructionsOf(code);
 
   // If two [Code] objects point to the same [Instructions] object, we'll just
   // use the first one (they are equivalent for all practical purposes).
@@ -221,7 +220,7 @@
   return nullptr;
 }
 
-void CodeRelocator::AddTrampolineToText(RawInstructions* destination,
+void CodeRelocator::AddTrampolineToText(InstructionsPtr destination,
                                         uint8_t* trampoline_bytes,
                                         intptr_t trampoline_length) {
   commands_->Add(ImageWriterCommand(next_text_offset_, trampoline_bytes,
@@ -248,27 +247,29 @@
       continue;
     }
 
-    target_ = call.Get<Code::kSCallTableFunctionTarget>();
-    if (target_.IsFunction()) {
-      auto& fun = Function::Cast(target_);
-      ASSERT(fun.HasCode());
-      destination_ = fun.CurrentCode();
-      ASSERT(!destination_.IsStubCode());
-    } else {
-      target_ = call.Get<Code::kSCallTableCodeTarget>();
-      ASSERT(target_.IsCode());
-      destination_ = Code::Cast(target_).raw();
-    }
+    destination_ = GetTarget(call);
 
     // A call site can decide to jump not to the beginning of a function but
     // rather jump into it at a certain offset.
     int32_t offset_into_target = 0;
-    const intptr_t call_instruction_offset =
-        return_pc_offset - PcRelativeCallPattern::kLengthInBytes;
-    {
+    bool is_tail_call;
+    intptr_t call_instruction_offset;
+    if (kind == Code::kPcRelativeCall || kind == Code::kPcRelativeTTSCall) {
+      call_instruction_offset =
+          return_pc_offset - PcRelativeCallPattern::kLengthInBytes;
       PcRelativeCallPattern call(code.PayloadStart() + call_instruction_offset);
       ASSERT(call.IsValid());
       offset_into_target = call.distance();
+      is_tail_call = false;
+    } else {
+      ASSERT(kind == Code::kPcRelativeTailCall);
+      call_instruction_offset =
+          return_pc_offset - PcRelativeTailCallPattern::kLengthInBytes;
+      PcRelativeTailCallPattern call(code.PayloadStart() +
+                                     call_instruction_offset);
+      ASSERT(call.IsValid());
+      offset_into_target = call.distance();
+      is_tail_call = true;
     }
 
     const uword destination_payload = destination_.PayloadStart();
@@ -283,7 +284,7 @@
 
     UnresolvedCall unresolved_call(code.raw(), call_instruction_offset,
                                    text_offset, destination_.raw(),
-                                   offset_into_target);
+                                   offset_into_target, is_tail_call);
     if (!TryResolveBackwardsCall(&unresolved_call)) {
       EnqueueUnresolvedCall(new UnresolvedCall(unresolved_call));
     }
@@ -295,7 +296,7 @@
   all_unresolved_calls_.Append(unresolved_call);
 
   // Add it to callers of destination.
-  RawInstructions* destination = Code::InstructionsOf(unresolved_call->callee);
+  InstructionsPtr destination = Code::InstructionsOf(unresolved_call->callee);
   if (!unresolved_calls_by_destination_.HasKey(destination)) {
     unresolved_calls_by_destination_.Insert(
         {destination, new SameDestinationUnresolvedCallsList()});
@@ -329,7 +330,7 @@
 }
 
 void CodeRelocator::ResolveUnresolvedCallsTargeting(
-    const RawInstructions* instructions) {
+    const InstructionsPtr instructions) {
   if (unresolved_calls_by_destination_.HasKey(instructions)) {
     SameDestinationUnresolvedCallsList* calls =
         unresolved_calls_by_destination_.LookupValue(instructions);
@@ -373,10 +374,17 @@
     if (FLAG_write_protect_code) {
       addr -= HeapPage::Of(Code::InstructionsOf(caller))->AliasOffset();
     }
-    PcRelativeCallPattern call(addr);
-    ASSERT(call.IsValid());
-    call.set_distance(static_cast<int32_t>(distance));
-    ASSERT(call.distance() == distance);
+    if (unresolved_call->is_tail_call) {
+      PcRelativeTailCallPattern call(addr);
+      ASSERT(call.IsValid());
+      call.set_distance(static_cast<int32_t>(distance));
+      ASSERT(call.distance() == distance);
+    } else {
+      PcRelativeCallPattern call(addr);
+      ASSERT(call.IsValid());
+      call.set_distance(static_cast<int32_t>(distance));
+      ASSERT(call.distance() == distance);
+    }
   }
 
   unresolved_call->caller = nullptr;
@@ -405,8 +413,58 @@
                                        intptr_t target_text_offset) {
   const auto forward_distance =
       target_text_offset - unresolved_call->text_offset;
-  return PcRelativeCallPattern::kLowerCallingRange < forward_distance &&
-         forward_distance < PcRelativeCallPattern::kUpperCallingRange;
+  if (unresolved_call->is_tail_call) {
+    return PcRelativeTailCallPattern::kLowerCallingRange < forward_distance &&
+           forward_distance < PcRelativeTailCallPattern::kUpperCallingRange;
+  } else {
+    return PcRelativeCallPattern::kLowerCallingRange < forward_distance &&
+           forward_distance < PcRelativeCallPattern::kUpperCallingRange;
+  }
+}
+
+CodePtr CodeRelocator::GetTarget(const StaticCallsTableEntry& call) {
+  // The precompiler should have already replaced all function entries
+  // with code entries.
+  ASSERT(call.Get<Code::kSCallTableFunctionTarget>() == Function::null());
+
+  target_ = call.Get<Code::kSCallTableCodeOrTypeTarget>();
+  if (target_.IsAbstractType()) {
+    target_ = AbstractType::Cast(target_).type_test_stub();
+    destination_ = Code::Cast(target_).raw();
+
+    // The AssertAssignableInstr will emit pc-relative calls to the TTS iff
+    // dst_type is instantiated. If we happened to not install an optimized
+    // TTS but rather a default one, it will live in the vm-isolate (to
+    // which we cannot make pc-relative calls).
+    // Though we have "equivalent" isolate-specific stubs we can use as
+    // targets instead.
+    //
+    // (We could make the AOT compiler install isolate-specific stubs
+    // into the types directly, but that does not work for types which
+    // live in the "vm-isolate" - such as `Type::dynamic_type()`).
+    if (destination_.InVMIsolateHeap()) {
+      auto object_store = thread_->isolate()->object_store();
+      if (destination_.raw() == StubCode::DefaultTypeTest().raw()) {
+        destination_ = object_store->default_tts_stub();
+      } else if (destination_.raw() ==
+                 StubCode::DefaultNullableTypeTest().raw()) {
+        destination_ = object_store->default_nullable_tts_stub();
+      } else if (destination_.raw() == StubCode::TopTypeTypeTest().raw()) {
+        destination_ = object_store->top_type_tts_stub();
+      } else if (destination_.raw() == StubCode::UnreachableTypeTest().raw()) {
+        destination_ = object_store->unreachable_tts_stub();
+      } else if (destination_.raw() == StubCode::SlowTypeTest().raw()) {
+        destination_ = object_store->slow_tts_stub();
+      } else {
+        UNREACHABLE();
+      }
+    }
+  } else {
+    ASSERT(target_.IsCode());
+    destination_ = Code::Cast(target_).raw();
+  }
+  ASSERT(!destination_.InVMIsolateHeap());
+  return destination_.raw();
 }
 
 static void MarkAsFreeListElement(uint8_t* trampoline_bytes,
@@ -414,15 +472,15 @@
   uint32_t tags = 0;
 #if defined(IS_SIMARM_X64)
   // Account for difference in kObjectAlignment between host and target.
-  tags = RawObject::SizeTag::update(trampoline_length * 2, tags);
+  tags = ObjectLayout::SizeTag::update(trampoline_length * 2, tags);
 #else
-  tags = RawObject::SizeTag::update(trampoline_length, tags);
+  tags = ObjectLayout::SizeTag::update(trampoline_length, tags);
 #endif
-  tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
-  tags = RawObject::OldBit::update(true, tags);
-  tags = RawObject::OldAndNotMarkedBit::update(true, tags);
-  tags = RawObject::OldAndNotRememberedBit::update(true, tags);
-  tags = RawObject::NewBit::update(false, tags);
+  tags = ObjectLayout::ClassIdTag::update(kFreeListElement, tags);
+  tags = ObjectLayout::OldBit::update(true, tags);
+  tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
+  tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+  tags = ObjectLayout::NewBit::update(false, tags);
 
   auto header_word = reinterpret_cast<uintptr_t*>(trampoline_bytes);
   *header_word = tags;
@@ -505,9 +563,8 @@
   }
 }
 
-intptr_t CodeRelocator::FindDestinationInText(
-    const RawInstructions* destination,
-    intptr_t offset_into_target) {
+intptr_t CodeRelocator::FindDestinationInText(const InstructionsPtr destination,
+                                              intptr_t offset_into_target) {
   auto const destination_offset = text_offsets_.LookupValue(destination);
   return destination_offset + AdjustPayloadOffset(offset_into_target);
 }
diff --git a/runtime/vm/compiler/relocation.h b/runtime/vm/compiler/relocation.h
index 2022f81..e9b6d44 100644
--- a/runtime/vm/compiler/relocation.h
+++ b/runtime/vm/compiler/relocation.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_RELOCATION_H_
 #define RUNTIME_VM_COMPILER_RELOCATION_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/image_snapshot.h"
 #include "vm/intrusive_dlist.h"
@@ -21,16 +25,18 @@
 class UnresolvedCall : public IntrusiveDListEntry<UnresolvedCall>,
                        public IntrusiveDListEntry<UnresolvedCall, 2> {
  public:
-  UnresolvedCall(RawCode* caller,
+  UnresolvedCall(CodePtr caller,
                  intptr_t call_offset,
                  intptr_t text_offset,
-                 RawCode* callee,
-                 intptr_t offset_into_target)
+                 CodePtr callee,
+                 intptr_t offset_into_target,
+                 bool is_tail_call)
       : caller(caller),
         call_offset(call_offset),
         text_offset(text_offset),
         callee(callee),
-        offset_into_target(offset_into_target) {}
+        offset_into_target(offset_into_target),
+        is_tail_call(is_tail_call) {}
 
   UnresolvedCall(const UnresolvedCall& other)
       : IntrusiveDListEntry<UnresolvedCall>(),
@@ -39,18 +45,22 @@
         call_offset(other.call_offset),
         text_offset(other.text_offset),
         callee(other.callee),
-        offset_into_target(other.offset_into_target) {}
+        offset_into_target(other.offset_into_target),
+        is_tail_call(other.is_tail_call) {}
 
-  // The caller which has an unresolved call.
-  RawCode* caller;
+  // The caller which has an unresolved call (will be null'ed out when
+  // resolved).
+  CodePtr caller;
   // The offset from the payload of the calling code which performs the call.
-  intptr_t call_offset;
+  const intptr_t call_offset;
   // The offset in the .text segment where the call happens.
-  intptr_t text_offset;
-  // The target of the forward call.
-  RawCode* callee;
+  const intptr_t text_offset;
+  // The target of the forward call (will be null'ed out when resolved).
+  CodePtr callee;
   // The extra offset into the target.
-  intptr_t offset_into_target;
+  const intptr_t offset_into_target;
+  // Whether this is a tail call.
+  const bool is_tail_call;
 };
 
 // A list of all unresolved calls.
@@ -68,7 +78,7 @@
 // instead (which will tail-call the destination).
 class UnresolvedTrampoline : public IntrusiveDListEntry<UnresolvedTrampoline> {
  public:
-  UnresolvedTrampoline(RawCode* callee,
+  UnresolvedTrampoline(CodePtr callee,
                        intptr_t offset_into_target,
                        uint8_t* trampoline_bytes,
                        intptr_t text_offset)
@@ -78,7 +88,7 @@
         text_offset(text_offset) {}
 
   // The target of the forward call.
-  RawCode* callee;
+  CodePtr callee;
   // The extra offset into the target.
   intptr_t offset_into_target;
 
@@ -94,21 +104,21 @@
 class InstructionsMapTraits {
  public:
   struct Pair {
-    RawInstructions* instructions;
+    InstructionsPtr instructions;
     ValueType value;
 
     Pair() : instructions(nullptr), value(kNoValue) {}
-    Pair(RawInstructions* i, const ValueType& value)
+    Pair(InstructionsPtr i, const ValueType& value)
         : instructions(i), value(value) {}
   };
 
-  typedef const RawInstructions* Key;
+  typedef const InstructionsPtr Key;
   typedef const ValueType Value;
 
   static Key KeyOf(Pair kv) { return kv.instructions; }
   static ValueType ValueOf(Pair kv) { return kv.value; }
   static inline intptr_t Hashcode(Key key) {
-    return reinterpret_cast<intptr_t>(key);
+    return static_cast<intptr_t>(key);
   }
   static inline bool IsKeyEqual(Pair pair, Key key) {
     return pair.instructions == key;
@@ -137,7 +147,7 @@
   // Populates the image writer command array which must be used later to write
   // the ".text" segment.
   static void Relocate(Thread* thread,
-                       GrowableArray<RawCode*>* code_objects,
+                       GrowableArray<CodePtr>* code_objects,
                        GrowableArray<ImageWriterCommand>* commands,
                        bool is_vm_isolate) {
     CodeRelocator relocator(thread, code_objects, commands);
@@ -146,20 +156,20 @@
 
  private:
   CodeRelocator(Thread* thread,
-                GrowableArray<RawCode*>* code_objects,
+                GrowableArray<CodePtr>* code_objects,
                 GrowableArray<ImageWriterCommand>* commands);
 
   void Relocate(bool is_vm_isolate);
 
   void FindInstructionAndCallLimits();
 
-  bool AddInstructionsToText(RawCode* code);
+  bool AddInstructionsToText(CodePtr code);
   void ScanCallTargets(const Code& code,
                        const Array& call_targets,
                        intptr_t code_text_offset);
 
   UnresolvedTrampoline* FindTrampolineFor(UnresolvedCall* unresolved_call);
-  void AddTrampolineToText(RawInstructions* destination,
+  void AddTrampolineToText(InstructionsPtr destination,
                            uint8_t* trampoline_bytes,
                            intptr_t trampoline_length);
 
@@ -167,7 +177,7 @@
   void EnqueueUnresolvedTrampoline(UnresolvedTrampoline* unresolved_trampoline);
 
   bool TryResolveBackwardsCall(UnresolvedCall* unresolved_call);
-  void ResolveUnresolvedCallsTargeting(const RawInstructions* instructions);
+  void ResolveUnresolvedCallsTargeting(const InstructionsPtr instructions);
   void ResolveCall(UnresolvedCall* unresolved_call);
   void ResolveCallToDestination(UnresolvedCall* unresolved_call,
                                 intptr_t destination_text);
@@ -175,7 +185,7 @@
 
   void BuildTrampolinesForAlmostOutOfRangeCalls();
 
-  intptr_t FindDestinationInText(const RawInstructions* destination,
+  intptr_t FindDestinationInText(const InstructionsPtr destination,
                                  intptr_t offset_into_target);
 
   static intptr_t AdjustPayloadOffset(intptr_t payload_offset);
@@ -183,11 +193,14 @@
   bool IsTargetInRangeFor(UnresolvedCall* unresolved_call,
                           intptr_t target_text_offset);
 
+  CodePtr GetTarget(const StaticCallsTableEntry& entry);
+
   // The code relocation happens during AOT snapshot writing and operates on raw
   // objects. No allocations can be done.
   NoSafepointScope no_savepoint_scope_;
+  Thread* thread_;
 
-  const GrowableArray<RawCode*>* code_objects_;
+  const GrowableArray<CodePtr>* code_objects_;
   GrowableArray<ImageWriterCommand>* commands_;
 
   // The size of largest instructions object in bytes.
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 0fe7674..ca41bd5 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -4,6 +4,20 @@
 
 #include "vm/compiler/runtime_api.h"
 
+#include "vm/object.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/runtime_offsets_list.h"
+#include "vm/dart_entry.h"
+#include "vm/longjump.h"
+#include "vm/native_arguments.h"
+#include "vm/native_entry.h"
+#include "vm/object_store.h"
+#include "vm/runtime_entry.h"
+#include "vm/symbols.h"
+#include "vm/timeline.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 namespace compiler {
 namespace target {
@@ -14,23 +28,23 @@
   return Utils::IsInt(kSmiBits + 1, v);
 }
 
+bool WillAllocateNewOrRememberedContext(intptr_t num_context_variables) {
+  if (!dart::Context::IsValidLength(num_context_variables)) return false;
+  return dart::Heap::IsAllocatableInNewSpace(
+      dart::Context::InstanceSize(num_context_variables));
+}
+
+bool WillAllocateNewOrRememberedArray(intptr_t length) {
+  if (!dart::Array::IsValidLength(length)) return false;
+  return !dart::Array::UseCardMarkingForAllocation(length);
+}
+
 }  // namespace target
 }  // namespace compiler
 }  // namespace dart
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
-#include "vm/compiler/runtime_offsets_list.h"
-#include "vm/dart_entry.h"
-#include "vm/longjump.h"
-#include "vm/native_arguments.h"
-#include "vm/native_entry.h"
-#include "vm/object.h"
-#include "vm/object_store.h"
-#include "vm/runtime_entry.h"
-#include "vm/symbols.h"
-#include "vm/timeline.h"
-
 namespace dart {
 namespace compiler {
 
@@ -113,6 +127,10 @@
   return Object::null_object();
 }
 
+const Object& SentinelObject() {
+  return Object::sentinel();
+}
+
 const Bool& TrueObject() {
   return dart::Bool::True();
 }
@@ -252,44 +270,54 @@
   return (offset / kWordSize) * dart::kWordSize;
 }
 
+bool SizeFitsInSizeTag(uword instance_size) {
+  return dart::ObjectLayout::SizeTag::SizeFits(
+      TranslateOffsetInWordsToHost(instance_size));
+}
+
 uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
-  return dart::RawObject::SizeTag::encode(
+  return dart::ObjectLayout::SizeTag::encode(
              TranslateOffsetInWordsToHost(instance_size)) |
-         dart::RawObject::ClassIdTag::encode(cid) |
-         dart::RawObject::NewBit::encode(true);
+         dart::ObjectLayout::ClassIdTag::encode(cid) |
+         dart::ObjectLayout::NewBit::encode(true);
 }
 
 word Object::tags_offset() {
   return 0;
 }
 
-const word RawObject::kCardRememberedBit = dart::RawObject::kCardRememberedBit;
+const word ObjectLayout::kCardRememberedBit =
+    dart::ObjectLayout::kCardRememberedBit;
 
-const word RawObject::kOldAndNotRememberedBit =
-    dart::RawObject::kOldAndNotRememberedBit;
+const word ObjectLayout::kOldAndNotRememberedBit =
+    dart::ObjectLayout::kOldAndNotRememberedBit;
 
-const word RawObject::kOldAndNotMarkedBit =
-    dart::RawObject::kOldAndNotMarkedBit;
+const word ObjectLayout::kOldAndNotMarkedBit =
+    dart::ObjectLayout::kOldAndNotMarkedBit;
 
-const word RawObject::kClassIdTagPos = dart::RawObject::kClassIdTagPos;
+const word ObjectLayout::kSizeTagPos = dart::ObjectLayout::kSizeTagPos;
 
-const word RawObject::kClassIdTagSize = dart::RawObject::kClassIdTagSize;
+const word ObjectLayout::kSizeTagSize = dart::ObjectLayout::kSizeTagSize;
 
-const word RawObject::kSizeTagMaxSizeTag =
-    dart::RawObject::SizeTag::kMaxSizeTagInUnitsOfAlignment *
+const word ObjectLayout::kClassIdTagPos = dart::ObjectLayout::kClassIdTagPos;
+
+const word ObjectLayout::kClassIdTagSize = dart::ObjectLayout::kClassIdTagSize;
+
+const word ObjectLayout::kSizeTagMaxSizeTag =
+    dart::ObjectLayout::SizeTag::kMaxSizeTagInUnitsOfAlignment *
     ObjectAlignment::kObjectAlignment;
 
-const word RawObject::kTagBitsSizeTagPos =
-    dart::RawObject::TagBits::kSizeTagPos;
+const word ObjectLayout::kTagBitsSizeTagPos =
+    dart::ObjectLayout::TagBits::kSizeTagPos;
 
-const word RawAbstractType::kTypeStateFinalizedInstantiated =
-    dart::RawAbstractType::kFinalizedInstantiated;
+const word AbstractTypeLayout::kTypeStateFinalizedInstantiated =
+    dart::AbstractTypeLayout::kFinalizedInstantiated;
 
-const word RawObject::kBarrierOverlapShift =
-    dart::RawObject::kBarrierOverlapShift;
+const word ObjectLayout::kBarrierOverlapShift =
+    dart::ObjectLayout::kBarrierOverlapShift;
 
-bool RawObject::IsTypedDataClassId(intptr_t cid) {
-  return dart::RawObject::IsTypedDataClassId(cid);
+bool IsTypedDataClassId(intptr_t cid) {
+  return dart::IsTypedDataClassId(cid);
 }
 
 const word Class::kNoTypeArguments = dart::Class::kNoTypeArguments;
@@ -347,7 +375,7 @@
       }
   }
   FATAL3("Unsupported class for size translation: %s (id=%" Pd
-         ", kNumPredefinedCids=%d)\n",
+         ", kNumPredefinedCids=%" Pd ")\n",
          handle.ToCString(), handle.id(), kNumPredefinedCids);
   return -1;
 }
@@ -379,12 +407,12 @@
 }
 
 word Instance::DataOffsetFor(intptr_t cid) {
-  if (dart::RawObject::IsExternalTypedDataClassId(cid) ||
-      dart::RawObject::IsExternalStringClassId(cid)) {
+  if (dart::IsExternalTypedDataClassId(cid) ||
+      dart::IsExternalStringClassId(cid)) {
     // Elements start at offset 0 of the external data.
     return 0;
   }
-  if (dart::RawObject::IsTypedDataClassId(cid)) {
+  if (dart::IsTypedDataClassId(cid)) {
     return TypedData::data_offset();
   }
   switch (cid) {
@@ -402,9 +430,8 @@
 }
 
 word Instance::ElementSizeFor(intptr_t cid) {
-  if (dart::RawObject::IsExternalTypedDataClassId(cid) ||
-      dart::RawObject::IsTypedDataClassId(cid) ||
-      dart::RawObject::IsTypedDataViewClassId(cid)) {
+  if (dart::IsExternalTypedDataClassId(cid) || dart::IsTypedDataClassId(cid) ||
+      dart::IsTypedDataViewClassId(cid)) {
     return dart::TypedDataBase::ElementSizeInBytes(cid);
   }
   switch (cid) {
@@ -595,7 +622,7 @@
 
 word ToRawSmi(const dart::Object& a) {
   RELEASE_ASSERT(IsSmi(a));
-  return static_cast<word>(reinterpret_cast<intptr_t>(a.raw()));
+  return static_cast<word>(static_cast<intptr_t>(a.raw()));
 }
 
 word ToRawSmi(intptr_t value) {
@@ -623,7 +650,7 @@
   static_assert(kHostWordSize == kWordSize,
                 "Can't embed raw pointers to runtime objects when host and "
                 "target word sizes are different");
-  return reinterpret_cast<word>(a.raw());
+  return static_cast<word>(a.raw());
 }
 #endif  // defined(TARGET_ARCH_IA32)
 
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 1ac43ce..3e024c0 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -40,7 +40,7 @@
 class Zone;
 
 #define DO(clazz)                                                              \
-  class Raw##clazz;                                                            \
+  class clazz##Layout;                                                         \
   class clazz;
 CLASS_LIST_FOR_HANDLES(DO)
 #undef DO
@@ -96,6 +96,7 @@
 //
 
 const Object& NullObject();
+const Object& SentinelObject();
 const Bool& TrueObject();
 const Bool& FalseObject();
 const Object& EmptyTypeArguments();
@@ -313,6 +314,9 @@
   return frame_layout.FrameSlotForVariable(variable) * kWordSize;
 }
 
+// Check whether instance_size is small enough to be encoded in the size tag.
+bool SizeFitsInSizeTag(uword instance_size);
+
 // Encode tag word for a heap allocated object with the given class id and
 // size.
 //
@@ -359,17 +363,23 @@
 word ToRawPointer(const dart::Object& a);
 #endif  // defined(TARGET_ARCH_IA32)
 
+bool WillAllocateNewOrRememberedContext(intptr_t num_context_variables);
+
+bool WillAllocateNewOrRememberedArray(intptr_t length);
+
 //
 // Target specific offsets and constants.
 //
 // Currently we use the same names for classes, constants and getters to make
 // migration easier.
 
-class RawObject : public AllStatic {
+class ObjectLayout : public AllStatic {
  public:
   static const word kCardRememberedBit;
   static const word kOldAndNotRememberedBit;
   static const word kOldAndNotMarkedBit;
+  static const word kSizeTagPos;
+  static const word kSizeTagSize;
   static const word kClassIdTagPos;
   static const word kClassIdTagSize;
   static const word kSizeTagMaxSizeTag;
@@ -379,7 +389,7 @@
   static bool IsTypedDataClassId(intptr_t cid);
 };
 
-class RawAbstractType : public AllStatic {
+class AbstractTypeLayout : public AllStatic {
  public:
   static const word kTypeStateFinalizedInstantiated;
 };
@@ -409,7 +419,7 @@
 
   static word super_type_offset();
 
-  // The offset of the RawObject::num_type_arguments_ field in bytes.
+  // The offset of the ObjectLayout::num_type_arguments_ field in bytes.
   static word num_type_arguments_offset();
 
   // The value used if no type arguments vector is present.
@@ -457,10 +467,14 @@
   static word NextFieldOffset();
 };
 
+class CallSiteData : public AllStatic {
+ public:
+  static word arguments_descriptor_offset();
+};
+
 class ICData : public AllStatic {
  public:
   static word owner_offset();
-  static word arguments_descriptor_offset();
   static word entries_offset();
   static word receivers_static_type_offset();
   static word state_bits_offset();
@@ -482,7 +496,6 @@
   static const word kSpreadFactor;
   static word mask_offset();
   static word buckets_offset();
-  static word arguments_descriptor_offset();
   static word InstanceSize();
   static word NextFieldOffset();
 };
@@ -952,16 +965,16 @@
   static word field_table_values_offset();
   static word store_buffer_block_offset();
   static word call_to_runtime_entry_point_offset();
-  static word null_error_shared_with_fpu_regs_entry_point_offset();
-  static word null_error_shared_without_fpu_regs_entry_point_offset();
-  static word null_arg_error_shared_with_fpu_regs_entry_point_offset();
-  static word null_arg_error_shared_without_fpu_regs_entry_point_offset();
   static word write_barrier_mask_offset();
-  static word monomorphic_miss_entry_offset();
+  static word switchable_call_miss_entry_offset();
   static word write_barrier_wrappers_thread_offset(Register regno);
   static word array_write_barrier_entry_point_offset();
   static word allocate_mint_with_fpu_regs_entry_point_offset();
   static word allocate_mint_without_fpu_regs_entry_point_offset();
+  static word allocate_object_entry_point_offset();
+  static word allocate_object_parameterized_entry_point_offset();
+  static word allocate_object_slow_entry_point_offset();
+  static word slow_type_test_entry_point_offset();
   static word write_barrier_entry_point_offset();
   static word vm_tag_offset();
   static uword vm_tag_compiled_id();
@@ -989,7 +1002,7 @@
   static word fix_callers_target_code_offset();
   static word fix_allocation_stub_code_offset();
 
-  static word monomorphic_miss_stub_offset();
+  static word switchable_call_miss_stub_offset();
   static word lazy_specialize_type_test_stub_offset();
   static word slow_type_test_stub_offset();
   static word call_to_runtime_stub_offset();
@@ -1000,6 +1013,8 @@
   static word null_error_shared_with_fpu_regs_stub_offset();
   static word null_arg_error_shared_without_fpu_regs_stub_offset();
   static word null_arg_error_shared_with_fpu_regs_stub_offset();
+  static word range_error_shared_without_fpu_regs_stub_offset();
+  static word range_error_shared_with_fpu_regs_stub_offset();
   static word stack_overflow_shared_without_fpu_regs_entry_point_offset();
   static word stack_overflow_shared_without_fpu_regs_stub_offset();
   static word stack_overflow_shared_with_fpu_regs_entry_point_offset();
@@ -1008,6 +1023,9 @@
   static word lazy_deopt_from_throw_stub_offset();
   static word allocate_mint_with_fpu_regs_stub_offset();
   static word allocate_mint_without_fpu_regs_stub_offset();
+  static word allocate_object_stub_offset();
+  static word allocate_object_parameterized_stub_offset();
+  static word allocate_object_slow_stub_offset();
   static word optimize_stub_offset();
   static word deoptimize_stub_offset();
   static word enter_safepoint_stub_offset();
@@ -1059,11 +1077,12 @@
 
 class Isolate : public AllStatic {
  public:
-  static word object_store_offset();
+  static word cached_object_store_offset();
   static word default_tag_offset();
   static word current_tag_offset();
   static word user_tag_offset();
-  static word class_table_offset();
+  static word cached_class_table_table_offset();
+  static word shared_class_table_offset();
   static word ic_miss_code_offset();
 #if !defined(PRODUCT)
   static word single_step_offset();
@@ -1077,8 +1096,6 @@
 
 class ClassTable : public AllStatic {
  public:
-  static word table_offset();
-  static word shared_class_table_offset();
 #if !defined(PRODUCT)
   static word ClassOffsetFor(intptr_t cid);
   static word SharedTableOffsetFor();
@@ -1229,8 +1246,9 @@
   static word guarded_list_length_in_object_offset_offset();
   static word guarded_list_length_offset();
   static word is_nullable_offset();
-  static word static_value_offset();
   static word kind_bits_offset();
+  static word initializer_function_offset();
+  static word host_offset_or_field_id_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 c825f44..a575006 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -81,9 +81,6 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
-static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
@@ -107,13 +104,17 @@
     ExternalTwoByteString_external_data_offset = 12;
 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_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 52;
+    Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+    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 = 44;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     4, 8};
@@ -128,21 +129,25 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 12;
-static constexpr dart::compiler::target::word ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word ICData_entries_offset = 12;
 static constexpr dart::compiler::target::word ICData_owner_offset = 20;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 60;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 32;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 48;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -157,11 +162,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    4;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 8;
+    12;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     4;
@@ -170,10 +173,10 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    116;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+    128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    140;
+    156;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -192,76 +195,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 336;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    668;
+    692;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    672;
+    696;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 228;
+    Thread_array_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 252;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 168;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 256;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 172;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 192;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 296;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 288;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 232;
+    Thread_call_to_runtime_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 704;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 728;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    276;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 188;
+    304;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 220;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    280;
+    308;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    192;
+    224;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    316;
+    348;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 312;
+    Thread_double_negate_address_offset = 344;
 static constexpr dart::compiler::target::word Thread_end_offset = 56;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 212;
+    Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    688;
+    712;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 216;
+    Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 220;
+    Thread_call_native_through_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 284;
+    Thread_call_native_through_safepoint_entry_point_offset = 312;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 136;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 132;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 328;
+    Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 324;
+    Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    320;
+    352;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 332;
+    Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    676;
+    700;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 300;
+    Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
@@ -270,60 +285,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 196;
+    Thread_lazy_deopt_from_return_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 200;
+    Thread_lazy_deopt_from_throw_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 208;
+    Thread_lazy_specialize_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 84;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 268;
+    Thread_megamorphic_call_checked_entry_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 272;
+    Thread_switchable_call_miss_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 184;
+    Thread_switchable_call_miss_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 292;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 240;
+    Thread_no_scope_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 248;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 236;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 244;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 304;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 680;
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 704;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 684;
+    Thread_saved_shadow_call_stack_offset = 708;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    692;
+    716;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 204;
+    Thread_slow_type_test_stub_offset = 236;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 316;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     60;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 64;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 264;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 180;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 260;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 176;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 196;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     80;
 static constexpr dart::compiler::target::word
@@ -336,10 +349,10 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     124;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 224;
+    Thread_write_barrier_entry_point_offset = 256;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 696;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -377,7 +390,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        636, 640, 644, 648, 652, -1, 656, -1, 660, 664, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -549,9 +562,6 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 184;
 static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
-static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
@@ -575,13 +585,17 @@
     ExternalTwoByteString_external_data_offset = 16;
 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_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 96;
 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;
+    56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
@@ -596,21 +610,25 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word ICData_owner_offset = 40;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 120;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 96;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -625,11 +643,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 32;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    8;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
+    24;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 32;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     8;
@@ -638,10 +654,10 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    232;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+    256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    280;
+    312;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -661,76 +677,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 656;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1344;
+    1392;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1352;
+    1400;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 440;
+    Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 448;
+    Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1416;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1464;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    536;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 360;
+    592;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    544;
+    600;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    368;
+    432;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    616;
+    680;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 608;
+    Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 408;
+    Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1384;
+    1432;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 416;
+    Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 424;
+    Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 552;
+    Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 640;
+    Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 632;
+    Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    624;
+    688;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 648;
+    Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1360;
+    1408;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 584;
+    Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -739,60 +767,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 376;
+    Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 384;
+    Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 400;
+    Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 520;
+    Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 528;
+    Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 352;
+    Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 592;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1368;
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1416;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1376;
+    Thread_saved_shadow_call_stack_offset = 1424;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1392;
+    1440;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 392;
+    Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     120;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     160;
 static constexpr dart::compiler::target::word
@@ -805,11 +831,11 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     232;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 432;
+    Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1400;
+    1448;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -848,8 +874,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, -1,   -1,   1288, 1296,
-        1304, 1312, 1320, -1,   1328, 1336, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -880,7 +906,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
 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 = 152;
@@ -1020,9 +1046,6 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
-static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
@@ -1046,13 +1069,17 @@
     ExternalTwoByteString_external_data_offset = 12;
 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_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 52;
+    Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+    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 = 44;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     4, 8};
@@ -1067,21 +1094,25 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 12;
-static constexpr dart::compiler::target::word ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word ICData_entries_offset = 12;
 static constexpr dart::compiler::target::word ICData_owner_offset = 20;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 60;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 32;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 48;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -1096,11 +1127,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    4;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 8;
+    12;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     4;
@@ -1109,10 +1138,10 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    116;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+    128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    140;
+    156;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -1131,76 +1160,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 336;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    636;
+    660;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    640;
+    664;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 228;
+    Thread_array_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 252;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 168;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 256;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 172;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 192;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 296;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 288;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 232;
+    Thread_call_to_runtime_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 672;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 696;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    276;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 188;
+    304;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 220;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    280;
+    308;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    192;
+    224;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    316;
+    348;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 312;
+    Thread_double_negate_address_offset = 344;
 static constexpr dart::compiler::target::word Thread_end_offset = 56;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 212;
+    Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    656;
+    680;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 216;
+    Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 220;
+    Thread_call_native_through_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 284;
+    Thread_call_native_through_safepoint_entry_point_offset = 312;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 136;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 132;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 328;
+    Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 324;
+    Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    320;
+    352;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 332;
+    Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    644;
+    668;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 300;
+    Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
@@ -1209,60 +1250,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 196;
+    Thread_lazy_deopt_from_return_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 200;
+    Thread_lazy_deopt_from_throw_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 208;
+    Thread_lazy_specialize_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 84;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 268;
+    Thread_megamorphic_call_checked_entry_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 272;
+    Thread_switchable_call_miss_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 184;
+    Thread_switchable_call_miss_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 292;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 240;
+    Thread_no_scope_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 248;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 236;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 244;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 304;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 648;
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 672;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 652;
+    Thread_saved_shadow_call_stack_offset = 676;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    660;
+    684;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 204;
+    Thread_slow_type_test_stub_offset = 236;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 316;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     60;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 64;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 264;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 180;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 260;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 176;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 196;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     80;
 static constexpr dart::compiler::target::word
@@ -1275,10 +1314,10 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     124;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 224;
+    Thread_write_barrier_entry_point_offset = 256;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 664;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -1485,9 +1524,6 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 184;
 static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
-static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
@@ -1511,13 +1547,17 @@
     ExternalTwoByteString_external_data_offset = 16;
 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_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 96;
 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;
+    56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
@@ -1532,21 +1572,25 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word ICData_owner_offset = 40;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 120;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 96;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -1561,11 +1605,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 32;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    8;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
+    24;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 32;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     8;
@@ -1574,10 +1616,10 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    232;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+    256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    280;
+    312;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -1597,76 +1639,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 656;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1416;
+    1464;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1424;
+    1472;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 440;
+    Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 448;
+    Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1536;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    536;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 360;
+    592;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    544;
+    600;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    368;
+    432;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    616;
+    680;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 608;
+    Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 408;
+    Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1456;
+    1504;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 416;
+    Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 424;
+    Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 552;
+    Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 640;
+    Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 632;
+    Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    624;
+    688;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 648;
+    Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1432;
+    1480;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 584;
+    Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -1675,60 +1729,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 376;
+    Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 384;
+    Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 400;
+    Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 520;
+    Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 528;
+    Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 352;
+    Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 592;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1440;
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1448;
+    Thread_saved_shadow_call_stack_offset = 1496;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1464;
+    1512;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 392;
+    Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     120;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     160;
 static constexpr dart::compiler::target::word
@@ -1741,11 +1793,11 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     232;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 432;
+    Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1472;
+    1520;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -1784,9 +1836,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328, 1336,
-        1344, 1352, 1360, 1368, -1,   -1,   -1,   -1,   1376, 1384, -1,
-        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -1817,7 +1869,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
 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 = 152;
@@ -1958,9 +2010,6 @@
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
-static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -1983,13 +2032,17 @@
     ExternalTwoByteString_external_data_offset = 12;
 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_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 52;
+    Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+    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 = 44;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     4, 8};
@@ -2004,20 +2057,24 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 12;
-static constexpr dart::compiler::target::word ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word ICData_entries_offset = 12;
 static constexpr dart::compiler::target::word ICData_owner_offset = 20;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 32;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -2032,11 +2089,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    4;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 8;
+    12;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     4;
@@ -2045,10 +2100,10 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    116;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+    128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    140;
+    156;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -2067,76 +2122,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 336;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    668;
+    692;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    672;
+    696;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 228;
+    Thread_array_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 252;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 168;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 256;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 172;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 192;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 296;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 288;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 232;
+    Thread_call_to_runtime_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 704;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 728;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    276;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 188;
+    304;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 220;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    280;
+    308;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    192;
+    224;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    316;
+    348;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 312;
+    Thread_double_negate_address_offset = 344;
 static constexpr dart::compiler::target::word Thread_end_offset = 56;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 212;
+    Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    688;
+    712;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 216;
+    Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 220;
+    Thread_call_native_through_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 284;
+    Thread_call_native_through_safepoint_entry_point_offset = 312;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 136;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 132;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 328;
+    Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 324;
+    Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    320;
+    352;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 332;
+    Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    676;
+    700;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 300;
+    Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
@@ -2145,60 +2212,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 196;
+    Thread_lazy_deopt_from_return_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 200;
+    Thread_lazy_deopt_from_throw_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 208;
+    Thread_lazy_specialize_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 84;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 268;
+    Thread_megamorphic_call_checked_entry_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 272;
+    Thread_switchable_call_miss_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 184;
+    Thread_switchable_call_miss_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 292;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 240;
+    Thread_no_scope_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 248;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 236;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 244;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 304;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 680;
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 704;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 684;
+    Thread_saved_shadow_call_stack_offset = 708;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    692;
+    716;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 204;
+    Thread_slow_type_test_stub_offset = 236;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 316;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     60;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 64;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 264;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 180;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 260;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 176;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 196;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     80;
 static constexpr dart::compiler::target::word
@@ -2211,10 +2276,10 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     124;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 224;
+    Thread_write_barrier_entry_point_offset = 256;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 696;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -2249,7 +2314,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        636, 640, 644, 648, 652, -1, 656, -1, 660, 664, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -2420,9 +2485,6 @@
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 184;
-static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -2445,13 +2507,17 @@
     ExternalTwoByteString_external_data_offset = 16;
 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_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 96;
 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;
+    56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
@@ -2466,20 +2532,24 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word ICData_owner_offset = 40;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 64;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -2494,11 +2564,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 32;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    8;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
+    24;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 32;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     8;
@@ -2507,10 +2575,10 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    232;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+    256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    280;
+    312;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -2530,76 +2598,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 656;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1344;
+    1392;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1352;
+    1400;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 440;
+    Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 448;
+    Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1416;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1464;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    536;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 360;
+    592;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    544;
+    600;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    368;
+    432;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    616;
+    680;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 608;
+    Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 408;
+    Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1384;
+    1432;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 416;
+    Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 424;
+    Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 552;
+    Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 640;
+    Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 632;
+    Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    624;
+    688;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 648;
+    Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1360;
+    1408;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 584;
+    Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -2608,60 +2688,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 376;
+    Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 384;
+    Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 400;
+    Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 520;
+    Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 528;
+    Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 352;
+    Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 592;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1368;
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1416;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1376;
+    Thread_saved_shadow_call_stack_offset = 1424;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1392;
+    1440;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 392;
+    Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     120;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     160;
 static constexpr dart::compiler::target::word
@@ -2674,11 +2752,11 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     232;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 432;
+    Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1400;
+    1448;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -2714,8 +2792,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, -1,   -1,   1288, 1296,
-        1304, 1312, 1320, -1,   1328, 1336, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -2746,7 +2824,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
 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 = 152;
@@ -2885,9 +2963,6 @@
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
-static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -2910,13 +2985,17 @@
     ExternalTwoByteString_external_data_offset = 12;
 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_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 52;
+    Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+    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 = 44;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     4, 8};
@@ -2931,20 +3010,24 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 12;
-static constexpr dart::compiler::target::word ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word ICData_entries_offset = 12;
 static constexpr dart::compiler::target::word ICData_owner_offset = 20;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 32;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -2959,11 +3042,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    4;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 8;
+    12;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     4;
@@ -2972,10 +3053,10 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    116;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+    128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    140;
+    156;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -2994,76 +3075,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 336;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    636;
+    660;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    640;
+    664;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 228;
+    Thread_array_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 252;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 168;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 256;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 172;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 192;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 296;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 288;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 232;
+    Thread_call_to_runtime_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 672;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 696;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    276;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 188;
+    304;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 220;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    280;
+    308;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    192;
+    224;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    316;
+    348;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 312;
+    Thread_double_negate_address_offset = 344;
 static constexpr dart::compiler::target::word Thread_end_offset = 56;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 212;
+    Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    656;
+    680;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 216;
+    Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 220;
+    Thread_call_native_through_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 284;
+    Thread_call_native_through_safepoint_entry_point_offset = 312;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 136;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 132;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 328;
+    Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 324;
+    Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    320;
+    352;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 332;
+    Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    644;
+    668;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 300;
+    Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
@@ -3072,60 +3165,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 196;
+    Thread_lazy_deopt_from_return_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 200;
+    Thread_lazy_deopt_from_throw_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 208;
+    Thread_lazy_specialize_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 84;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 268;
+    Thread_megamorphic_call_checked_entry_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 272;
+    Thread_switchable_call_miss_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 184;
+    Thread_switchable_call_miss_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 292;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 240;
+    Thread_no_scope_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 248;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 236;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 244;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 304;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 648;
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 672;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 652;
+    Thread_saved_shadow_call_stack_offset = 676;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    660;
+    684;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 204;
+    Thread_slow_type_test_stub_offset = 236;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 316;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     60;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 64;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 264;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 180;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 260;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 176;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 196;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     80;
 static constexpr dart::compiler::target::word
@@ -3138,10 +3229,10 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     124;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 224;
+    Thread_write_barrier_entry_point_offset = 256;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 664;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -3344,9 +3435,6 @@
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 184;
-static constexpr dart::compiler::target::word
-    ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -3369,13 +3457,17 @@
     ExternalTwoByteString_external_data_offset = 16;
 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_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+    Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 96;
 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;
+    56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
@@ -3390,20 +3482,24 @@
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word HeapPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word
+    CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
-static constexpr dart::compiler::target::word
-    ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word ICData_owner_offset = 40;
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
+static constexpr dart::compiler::target::word
+    Isolate_cached_object_store_offset = 64;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -3418,11 +3514,9 @@
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
-static constexpr dart::compiler::target::word
-    MegamorphicCache_arguments_descriptor_offset = 32;
 static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
-    8;
-static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
+    24;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 32;
 static constexpr dart::compiler::target::word Mint_value_offset = 8;
 static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
     8;
@@ -3431,10 +3525,10 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    232;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+    256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    280;
+    312;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -3454,76 +3548,88 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 656;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1416;
+    1464;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1424;
+    1472;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 440;
+    Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 448;
+    Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1536;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    536;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 360;
+    592;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424;
 static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    544;
+    600;
 static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    368;
+    432;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    616;
+    680;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 608;
+    Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 408;
+    Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1456;
+    1504;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 416;
+    Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 424;
+    Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 552;
+    Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 640;
+    Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 632;
+    Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    624;
+    688;
 static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 648;
+    Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1432;
+    1480;
 static constexpr dart::compiler::target::word
-    Thread_interpret_call_entry_point_offset = 584;
+    Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -3532,60 +3638,58 @@
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 376;
+    Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 384;
+    Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 400;
+    Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 520;
+    Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_entry_offset = 528;
+    Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_monomorphic_miss_stub_offset = 352;
+    Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 592;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1440;
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1448;
+    Thread_saved_shadow_call_stack_offset = 1496;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1464;
+    1512;
 static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 392;
+    Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
     120;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     160;
 static constexpr dart::compiler::target::word
@@ -3598,11 +3702,11 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
     232;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 432;
+    Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1472;
+    1520;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -3638,9 +3742,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328, 1336,
-        1344, 1352, 1360, 1368, -1,   -1,   -1,   -1,   1376, 1384, -1,
-        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -3671,7 +3775,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
 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 = 152;
@@ -3820,9 +3924,6 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
-    AOT_ClassTable_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 8;
-static constexpr dart::compiler::target::word
     AOT_SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
@@ -3847,6 +3948,10 @@
     AOT_ExternalTwoByteString_external_data_offset = 12;
 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 = 16;
+static constexpr dart::compiler::target::word
+    AOT_Field_host_offset_or_field_id_offset = 20;
 static constexpr dart::compiler::target::word AOT_Function_code_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {4, 8};
@@ -3860,23 +3965,25 @@
     AOT_GrowableObjectArray_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
     20;
+static constexpr dart::compiler::target::word
+    AOT_CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 12;
 static constexpr dart::compiler::target::word
-    AOT_ICData_arguments_descriptor_offset = 12;
-static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 4;
-static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
-    36;
+    AOT_Isolate_shared_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_class_table_table_offset = 40;
 static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
     20;
 static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
     24;
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     28;
-static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
-    32;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_object_store_offset = 32;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    60;
+    48;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     16;
@@ -3895,11 +4002,9 @@
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
     4;
 static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_arguments_descriptor_offset = 16;
-static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_buckets_offset = 4;
+    AOT_MegamorphicCache_buckets_offset = 12;
 static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
-    8;
+    16;
 static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_argc_tag_offset = 4;
@@ -3910,11 +4015,11 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 116;
+    AOT_ObjectStore_double_type_offset = 128;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    60;
+    68;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 140;
+    AOT_ObjectStore_string_type_offset = 156;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word
@@ -3938,79 +4043,91 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 336;
+    AOT_Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 668;
+    AOT_Thread_active_exception_offset = 692;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 672;
+    AOT_Thread_active_stacktrace_offset = 696;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 228;
+    AOT_Thread_array_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 252;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 168;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 256;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 172;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_stub_offset = 192;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 96;
 static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 296;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
     120;
 static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 116;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 288;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 320;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 232;
+    AOT_Thread_call_to_runtime_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 148;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    704;
+    728;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    276;
+    304;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    188;
+    220;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 280;
+    AOT_Thread_deoptimize_entry_offset = 308;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 192;
+    AOT_Thread_deoptimize_stub_offset = 224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 316;
+    AOT_Thread_double_abs_address_offset = 348;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 312;
+    AOT_Thread_double_negate_address_offset = 344;
 static constexpr dart::compiler::target::word AOT_Thread_end_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 212;
+    AOT_Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 688;
+    AOT_Thread_execution_state_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 216;
+    AOT_Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 220;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 284;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 312;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_allocation_stub_code_offset = 136;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_callers_target_code_offset = 132;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 328;
+    AOT_Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 324;
+    AOT_Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 320;
+    AOT_Thread_float_not_address_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 332;
+    AOT_Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 676;
+    AOT_Thread_global_object_pool_offset = 700;
 static constexpr dart::compiler::target::word
-    AOT_Thread_interpret_call_entry_point_offset = 300;
+    AOT_Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
@@ -4019,48 +4136,46 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 196;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 200;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 208;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
     AOT_Thread_marking_stack_block_offset = 84;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 268;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_entry_offset = 272;
+    AOT_Thread_switchable_call_miss_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_stub_offset = 184;
+    AOT_Thread_switchable_call_miss_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 292;
-static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 240;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 248;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 236;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 244;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
     112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 304;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 680;
+    AOT_Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 684;
+    AOT_Thread_saved_shadow_call_stack_offset = 708;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 692;
+    AOT_Thread_safepoint_state_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 204;
+    AOT_Thread_slow_type_test_stub_offset = 236;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_entry_point_offset = 316;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
     36;
 static constexpr dart::compiler::target::word
@@ -4068,13 +4183,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_stack_overflow_flags_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 264;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 180;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 260;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 176;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 196;
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 80;
 static constexpr dart::compiler::target::word
@@ -4088,11 +4203,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_code_offset = 124;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 224;
+    AOT_Thread_write_barrier_entry_point_offset = 256;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_mask_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    696;
+    720;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4137,7 +4252,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        636, 640, 644, 648, 652, -1, 656, -1, 660, 664, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
@@ -4332,9 +4447,6 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 184;
 static constexpr dart::compiler::target::word
-    AOT_ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
-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;
 static constexpr dart::compiler::target::word
@@ -4359,6 +4471,10 @@
     AOT_ExternalTwoByteString_external_data_offset = 16;
 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;
+static constexpr dart::compiler::target::word
+    AOT_Field_host_offset_or_field_id_offset = 40;
 static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
@@ -4372,23 +4488,25 @@
     AOT_GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
     40;
+static constexpr dart::compiler::target::word
+    AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
-static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
-    72;
+    AOT_Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
     40;
 static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
     48;
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
-static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
-    64;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_object_store_offset = 64;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    120;
+    96;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -4407,11 +4525,9 @@
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
-static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_buckets_offset = 8;
+    AOT_MegamorphicCache_buckets_offset = 24;
 static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
-    16;
+    32;
 static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_argc_tag_offset = 8;
@@ -4422,11 +4538,11 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 232;
+    AOT_ObjectStore_double_type_offset = 256;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    120;
+    136;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 280;
+    AOT_ObjectStore_string_type_offset = 312;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -4450,79 +4566,91 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 656;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1344;
+    AOT_Thread_active_exception_offset = 1392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1352;
+    AOT_Thread_active_stacktrace_offset = 1400;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 440;
+    AOT_Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
     224;
 static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 448;
+    AOT_Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 280;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1416;
+    1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    536;
+    592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    360;
+    424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 544;
+    AOT_Thread_deoptimize_entry_offset = 600;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 368;
+    AOT_Thread_deoptimize_stub_offset = 432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 616;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 608;
+    AOT_Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 408;
+    AOT_Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1384;
+    AOT_Thread_execution_state_offset = 1432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 416;
+    AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 424;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 552;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 640;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 632;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 624;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 648;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1360;
+    AOT_Thread_global_object_pool_offset = 1408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_interpret_call_entry_point_offset = 584;
+    AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -4531,49 +4659,47 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 376;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 384;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 400;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     AOT_Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 520;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_entry_offset = 528;
+    AOT_Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_stub_offset = 352;
+    AOT_Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
     208;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 592;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1368;
+    1416;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1376;
+    AOT_Thread_saved_shadow_call_stack_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1392;
+    AOT_Thread_safepoint_state_offset = 1440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 392;
+    AOT_Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
     72;
 static constexpr dart::compiler::target::word
@@ -4581,13 +4707,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 160;
 static constexpr dart::compiler::target::word
@@ -4601,11 +4727,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 432;
+    AOT_Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_mask_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1400;
+    1448;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4650,8 +4776,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, -1,   -1,   1288, 1296,
-        1304, 1312, 1320, -1,   1328, 1336, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
@@ -4850,9 +4976,6 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 184;
 static constexpr dart::compiler::target::word
-    AOT_ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
-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;
 static constexpr dart::compiler::target::word
@@ -4877,6 +5000,10 @@
     AOT_ExternalTwoByteString_external_data_offset = 16;
 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;
+static constexpr dart::compiler::target::word
+    AOT_Field_host_offset_or_field_id_offset = 40;
 static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
@@ -4890,23 +5017,25 @@
     AOT_GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
     40;
+static constexpr dart::compiler::target::word
+    AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
-static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
-    72;
+    AOT_Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
     40;
 static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
     48;
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
-static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
-    64;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_object_store_offset = 64;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    120;
+    96;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -4925,11 +5054,9 @@
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
-static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_buckets_offset = 8;
+    AOT_MegamorphicCache_buckets_offset = 24;
 static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
-    16;
+    32;
 static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_argc_tag_offset = 8;
@@ -4940,11 +5067,11 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 232;
+    AOT_ObjectStore_double_type_offset = 256;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    120;
+    136;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 280;
+    AOT_ObjectStore_string_type_offset = 312;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -4968,79 +5095,91 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 656;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1416;
+    AOT_Thread_active_exception_offset = 1464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1424;
+    AOT_Thread_active_stacktrace_offset = 1472;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 440;
+    AOT_Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
     224;
 static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 448;
+    AOT_Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 280;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1488;
+    1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    536;
+    592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    360;
+    424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 544;
+    AOT_Thread_deoptimize_entry_offset = 600;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 368;
+    AOT_Thread_deoptimize_stub_offset = 432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 616;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 608;
+    AOT_Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 408;
+    AOT_Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1456;
+    AOT_Thread_execution_state_offset = 1504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 416;
+    AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 424;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 552;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 640;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 632;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 624;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 648;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1432;
+    AOT_Thread_global_object_pool_offset = 1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_interpret_call_entry_point_offset = 584;
+    AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -5049,49 +5188,47 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 376;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 384;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 400;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     AOT_Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 520;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_entry_offset = 528;
+    AOT_Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_stub_offset = 352;
+    AOT_Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
     208;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 592;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1440;
+    1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1448;
+    AOT_Thread_saved_shadow_call_stack_offset = 1496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1464;
+    AOT_Thread_safepoint_state_offset = 1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 392;
+    AOT_Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
     72;
 static constexpr dart::compiler::target::word
@@ -5099,13 +5236,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 160;
 static constexpr dart::compiler::target::word
@@ -5119,11 +5256,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 432;
+    AOT_Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_mask_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1472;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5168,9 +5305,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328, 1336,
-        1344, 1352, 1360, 1368, -1,   -1,   -1,   -1,   1376, 1384, -1,
-        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
@@ -5367,9 +5504,6 @@
 static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
-static constexpr dart::compiler::target::word
-    AOT_ClassTable_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 8;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 12;
@@ -5393,6 +5527,10 @@
     AOT_ExternalTwoByteString_external_data_offset = 12;
 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 = 16;
+static constexpr dart::compiler::target::word
+    AOT_Field_host_offset_or_field_id_offset = 20;
 static constexpr dart::compiler::target::word AOT_Function_code_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {4, 8};
@@ -5406,21 +5544,23 @@
     AOT_GrowableObjectArray_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
     20;
+static constexpr dart::compiler::target::word
+    AOT_CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 12;
 static constexpr dart::compiler::target::word
-    AOT_ICData_arguments_descriptor_offset = 12;
-static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 4;
-static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
-    36;
+    AOT_Isolate_shared_class_table_offset = 36;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_class_table_table_offset = 40;
 static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
     20;
 static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
     24;
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     28;
-static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
-    32;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_object_store_offset = 32;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     16;
@@ -5439,11 +5579,9 @@
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
     4;
 static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_arguments_descriptor_offset = 16;
-static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_buckets_offset = 4;
+    AOT_MegamorphicCache_buckets_offset = 12;
 static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
-    8;
+    16;
 static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_argc_tag_offset = 4;
@@ -5454,11 +5592,11 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 116;
+    AOT_ObjectStore_double_type_offset = 128;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    60;
+    68;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 140;
+    AOT_ObjectStore_string_type_offset = 156;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word
@@ -5482,79 +5620,91 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 336;
+    AOT_Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 668;
+    AOT_Thread_active_exception_offset = 692;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 672;
+    AOT_Thread_active_stacktrace_offset = 696;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 228;
+    AOT_Thread_array_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 252;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 168;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 256;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 172;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_stub_offset = 192;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 96;
 static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 296;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
     120;
 static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 116;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 288;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 320;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 232;
+    AOT_Thread_call_to_runtime_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 148;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    704;
+    728;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    276;
+    304;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    188;
+    220;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 280;
+    AOT_Thread_deoptimize_entry_offset = 308;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 192;
+    AOT_Thread_deoptimize_stub_offset = 224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 316;
+    AOT_Thread_double_abs_address_offset = 348;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 312;
+    AOT_Thread_double_negate_address_offset = 344;
 static constexpr dart::compiler::target::word AOT_Thread_end_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 212;
+    AOT_Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 688;
+    AOT_Thread_execution_state_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 216;
+    AOT_Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 220;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 284;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 312;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_allocation_stub_code_offset = 136;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_callers_target_code_offset = 132;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 328;
+    AOT_Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 324;
+    AOT_Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 320;
+    AOT_Thread_float_not_address_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 332;
+    AOT_Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 676;
+    AOT_Thread_global_object_pool_offset = 700;
 static constexpr dart::compiler::target::word
-    AOT_Thread_interpret_call_entry_point_offset = 300;
+    AOT_Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
@@ -5563,48 +5713,46 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 196;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 200;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 208;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
     AOT_Thread_marking_stack_block_offset = 84;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 268;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_entry_offset = 272;
+    AOT_Thread_switchable_call_miss_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_stub_offset = 184;
+    AOT_Thread_switchable_call_miss_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 292;
-static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 240;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 248;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 236;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 244;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
     112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 304;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 680;
+    AOT_Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 684;
+    AOT_Thread_saved_shadow_call_stack_offset = 708;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 692;
+    AOT_Thread_safepoint_state_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 204;
+    AOT_Thread_slow_type_test_stub_offset = 236;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_entry_point_offset = 316;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
     36;
 static constexpr dart::compiler::target::word
@@ -5612,13 +5760,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_stack_overflow_flags_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 264;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 180;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 260;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 176;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 196;
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 80;
 static constexpr dart::compiler::target::word
@@ -5632,11 +5780,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_code_offset = 124;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 224;
+    AOT_Thread_write_barrier_entry_point_offset = 256;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_mask_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    696;
+    720;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5678,7 +5826,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        636, 640, 644, 648, 652, -1, 656, -1, 660, 664, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
@@ -5872,9 +6020,6 @@
 static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -5898,6 +6043,10 @@
     AOT_ExternalTwoByteString_external_data_offset = 16;
 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;
+static constexpr dart::compiler::target::word
+    AOT_Field_host_offset_or_field_id_offset = 40;
 static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
@@ -5911,21 +6060,23 @@
     AOT_GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
     40;
+static constexpr dart::compiler::target::word
+    AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
-static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
-    72;
+    AOT_Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
     40;
 static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
     48;
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
-static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
-    64;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_object_store_offset = 64;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -5944,11 +6095,9 @@
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
-static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_buckets_offset = 8;
+    AOT_MegamorphicCache_buckets_offset = 24;
 static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
-    16;
+    32;
 static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_argc_tag_offset = 8;
@@ -5959,11 +6108,11 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 232;
+    AOT_ObjectStore_double_type_offset = 256;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    120;
+    136;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 280;
+    AOT_ObjectStore_string_type_offset = 312;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -5987,79 +6136,91 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 656;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1344;
+    AOT_Thread_active_exception_offset = 1392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1352;
+    AOT_Thread_active_stacktrace_offset = 1400;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 440;
+    AOT_Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
     224;
 static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 448;
+    AOT_Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 280;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1416;
+    1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    536;
+    592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    360;
+    424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 544;
+    AOT_Thread_deoptimize_entry_offset = 600;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 368;
+    AOT_Thread_deoptimize_stub_offset = 432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 616;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 608;
+    AOT_Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 408;
+    AOT_Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1384;
+    AOT_Thread_execution_state_offset = 1432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 416;
+    AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 424;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 552;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 640;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 632;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 624;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 648;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1360;
+    AOT_Thread_global_object_pool_offset = 1408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_interpret_call_entry_point_offset = 584;
+    AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -6068,49 +6229,47 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 376;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 384;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 400;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     AOT_Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 520;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_entry_offset = 528;
+    AOT_Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_stub_offset = 352;
+    AOT_Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
     208;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 592;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1368;
+    1416;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1376;
+    AOT_Thread_saved_shadow_call_stack_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1392;
+    AOT_Thread_safepoint_state_offset = 1440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 392;
+    AOT_Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
     72;
 static constexpr dart::compiler::target::word
@@ -6118,13 +6277,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 160;
 static constexpr dart::compiler::target::word
@@ -6138,11 +6297,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 432;
+    AOT_Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_mask_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1400;
+    1448;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6184,8 +6343,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, -1,   -1,   1288, 1296,
-        1304, 1312, 1320, -1,   1328, 1336, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
@@ -6383,9 +6542,6 @@
 static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_ClassTable_shared_class_table_offset = 32;
-static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -6409,6 +6565,10 @@
     AOT_ExternalTwoByteString_external_data_offset = 16;
 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;
+static constexpr dart::compiler::target::word
+    AOT_Field_host_offset_or_field_id_offset = 40;
 static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
@@ -6422,21 +6582,23 @@
     AOT_GrowableObjectArray_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
     40;
+static constexpr dart::compiler::target::word
+    AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_ICData_arguments_descriptor_offset = 24;
-static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
-static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
-    72;
+    AOT_Isolate_shared_class_table_offset = 72;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_class_table_table_offset = 80;
 static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
     40;
 static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
     48;
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
-static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
-    64;
+static constexpr dart::compiler::target::word
+    AOT_Isolate_cached_object_store_offset = 64;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -6455,11 +6617,9 @@
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
-static constexpr dart::compiler::target::word
-    AOT_MegamorphicCache_buckets_offset = 8;
+    AOT_MegamorphicCache_buckets_offset = 24;
 static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
-    16;
+    32;
 static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_argc_tag_offset = 8;
@@ -6470,11 +6630,11 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 232;
+    AOT_ObjectStore_double_type_offset = 256;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    120;
+    136;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 280;
+    AOT_ObjectStore_string_type_offset = 312;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -6498,79 +6658,91 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 656;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1416;
+    AOT_Thread_active_exception_offset = 1464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1424;
+    AOT_Thread_active_stacktrace_offset = 1472;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 440;
+    AOT_Thread_array_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 488;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 496;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_parameterized_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_object_slow_stub_offset = 368;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 576;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
     224;
 static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 560;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 448;
+    AOT_Thread_call_to_runtime_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 280;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1488;
+    1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    536;
+    592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    360;
+    424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 544;
+    AOT_Thread_deoptimize_entry_offset = 600;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 368;
+    AOT_Thread_deoptimize_stub_offset = 432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 616;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 608;
+    AOT_Thread_double_negate_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 408;
+    AOT_Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1456;
+    AOT_Thread_execution_state_offset = 1504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 416;
+    AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 424;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 552;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 608;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_allocation_stub_code_offset = 256;
 static constexpr dart::compiler::target::word
     AOT_Thread_fix_callers_target_code_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 640;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 632;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 624;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 648;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1432;
+    AOT_Thread_global_object_pool_offset = 1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_interpret_call_entry_point_offset = 584;
+    AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -6579,49 +6751,47 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 376;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 384;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 400;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
     AOT_Thread_marking_stack_block_offset = 168;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 520;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_entry_offset = 528;
+    AOT_Thread_switchable_call_miss_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_monomorphic_miss_stub_offset = 352;
+    AOT_Thread_switchable_call_miss_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 568;
-static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 464;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 480;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 456;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word
     AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 472;
-static constexpr dart::compiler::target::word
     AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
     208;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 592;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1440;
+    1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1448;
+    AOT_Thread_saved_shadow_call_stack_offset = 1496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1464;
+    AOT_Thread_safepoint_state_offset = 1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 392;
+    AOT_Thread_slow_type_test_stub_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_entry_point_offset = 616;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
     72;
 static constexpr dart::compiler::target::word
@@ -6629,13 +6799,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_stack_overflow_flags_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 512;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 344;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 504;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 336;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 376;
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 160;
 static constexpr dart::compiler::target::word
@@ -6649,11 +6819,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 432;
+    AOT_Thread_write_barrier_entry_point_offset = 496;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_mask_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1472;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6695,9 +6865,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328, 1336,
-        1344, 1352, 1360, 1368, -1,   -1,   -1,   -1,   1376, 1384, -1,
-        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 0ec3d1f..5371356 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -66,8 +66,6 @@
   FIELD(Class, num_type_arguments_offset)                                      \
   FIELD(Class, super_type_offset)                                              \
   FIELD(Class, host_type_arguments_field_offset_in_words_offset)               \
-  FIELD(ClassTable, shared_class_table_offset)                                 \
-  FIELD(ClassTable, table_offset)                                              \
   NOT_IN_PRODUCT(FIELD(SharedClassTable, class_heap_stats_table_offset))       \
   FIELD(Closure, context_offset)                                               \
   FIELD(Closure, delayed_type_arguments_offset)                                \
@@ -85,6 +83,8 @@
   FIELD(ExternalTwoByteString, external_data_offset)                           \
   FIELD(Float32x4, value_offset)                                               \
   FIELD(Float64x2, value_offset)                                               \
+  FIELD(Field, initializer_function_offset)                                    \
+  FIELD(Field, host_offset_or_field_id_offset)                                 \
   PRECOMP_NO_CHECK(FIELD(Field, guarded_cid_offset))                           \
   PRECOMP_NO_CHECK(FIELD(Field, guarded_list_length_in_object_offset_offset))  \
   PRECOMP_NO_CHECK(FIELD(Field, guarded_list_length_offset))                   \
@@ -99,18 +99,19 @@
   FIELD(GrowableObjectArray, length_offset)                                    \
   FIELD(GrowableObjectArray, type_arguments_offset)                            \
   FIELD(HeapPage, card_table_offset)                                           \
+  FIELD(CallSiteData, arguments_descriptor_offset)                             \
   FIELD(ICData, NumArgsTestedMask)                                             \
   FIELD(ICData, NumArgsTestedShift)                                            \
-  FIELD(ICData, arguments_descriptor_offset)                                   \
   FIELD(ICData, entries_offset)                                                \
   PRECOMP_NO_CHECK(FIELD(ICData, owner_offset))                                \
   PRECOMP_NO_CHECK(FIELD(ICData, state_bits_offset))                           \
   NOT_IN_PRECOMPILED_RUNTIME(FIELD(ICData, receivers_static_type_offset))      \
-  FIELD(Isolate, class_table_offset)                                           \
+  FIELD(Isolate, shared_class_table_offset)                                    \
+  FIELD(Isolate, cached_class_table_table_offset)                              \
   FIELD(Isolate, current_tag_offset)                                           \
   FIELD(Isolate, default_tag_offset)                                           \
   FIELD(Isolate, ic_miss_code_offset)                                          \
-  FIELD(Isolate, object_store_offset)                                          \
+  FIELD(Isolate, cached_object_store_offset)                                   \
   NOT_IN_PRODUCT(FIELD(Isolate, single_step_offset))                           \
   FIELD(Isolate, user_tag_offset)                                              \
   FIELD(LinkedHashMap, data_offset)                                            \
@@ -121,7 +122,6 @@
   FIELD(LinkedHashMap, used_data_offset)                                       \
   FIELD(MarkingStackBlock, pointers_offset)                                    \
   FIELD(MarkingStackBlock, top_offset)                                         \
-  FIELD(MegamorphicCache, arguments_descriptor_offset)                         \
   FIELD(MegamorphicCache, buckets_offset)                                      \
   FIELD(MegamorphicCache, mask_offset)                                         \
   FIELD(Mint, value_offset)                                                    \
@@ -153,6 +153,12 @@
   FIELD(Thread, allocate_mint_with_fpu_regs_stub_offset)                       \
   FIELD(Thread, allocate_mint_without_fpu_regs_entry_point_offset)             \
   FIELD(Thread, allocate_mint_without_fpu_regs_stub_offset)                    \
+  FIELD(Thread, allocate_object_entry_point_offset)                            \
+  FIELD(Thread, allocate_object_stub_offset)                                   \
+  FIELD(Thread, allocate_object_parameterized_entry_point_offset)              \
+  FIELD(Thread, allocate_object_parameterized_stub_offset)                     \
+  FIELD(Thread, allocate_object_slow_entry_point_offset)                       \
+  FIELD(Thread, allocate_object_slow_stub_offset)                              \
   FIELD(Thread, async_stack_trace_offset)                                      \
   FIELD(Thread, auto_scope_native_wrapper_entry_point_offset)                  \
   FIELD(Thread, bool_false_offset)                                             \
@@ -191,24 +197,23 @@
   FIELD(Thread, lazy_specialize_type_test_stub_offset)                         \
   FIELD(Thread, marking_stack_block_offset)                                    \
   FIELD(Thread, megamorphic_call_checked_entry_offset)                         \
-  FIELD(Thread, monomorphic_miss_entry_offset)                                 \
-  FIELD(Thread, monomorphic_miss_stub_offset)                                  \
+  FIELD(Thread, switchable_call_miss_entry_offset)                             \
+  FIELD(Thread, switchable_call_miss_stub_offset)                              \
   FIELD(Thread, no_scope_native_wrapper_entry_point_offset)                    \
-  FIELD(Thread, null_error_shared_with_fpu_regs_entry_point_offset)            \
   FIELD(Thread, null_error_shared_with_fpu_regs_stub_offset)                   \
-  FIELD(Thread, null_arg_error_shared_with_fpu_regs_entry_point_offset)        \
   FIELD(Thread, null_arg_error_shared_with_fpu_regs_stub_offset)               \
+  FIELD(Thread, range_error_shared_with_fpu_regs_stub_offset)                  \
                                                                                \
-  FIELD(Thread, null_error_shared_without_fpu_regs_entry_point_offset)         \
   FIELD(Thread, null_error_shared_without_fpu_regs_stub_offset)                \
-  FIELD(Thread, null_arg_error_shared_without_fpu_regs_entry_point_offset)     \
   FIELD(Thread, null_arg_error_shared_without_fpu_regs_stub_offset)            \
+  FIELD(Thread, range_error_shared_without_fpu_regs_stub_offset)               \
   FIELD(Thread, object_null_offset)                                            \
   FIELD(Thread, predefined_symbols_address_offset)                             \
   FIELD(Thread, resume_pc_offset)                                              \
   FIELD(Thread, saved_shadow_call_stack_offset)                                \
   FIELD(Thread, safepoint_state_offset)                                        \
   FIELD(Thread, slow_type_test_stub_offset)                                    \
+  FIELD(Thread, slow_type_test_entry_point_offset)                             \
   FIELD(Thread, stack_limit_offset)                                            \
   FIELD(Thread, saved_stack_limit_offset)                                      \
   FIELD(Thread, stack_overflow_flags_offset)                                   \
@@ -257,89 +262,89 @@
       kNumberOfCpuRegisters - 1,                                               \
       [](Register reg) { return (kDartAvailableCpuRegs & (1 << reg)) != 0; })) \
                                                                                \
-  SIZEOF(ApiError, InstanceSize, RawApiError)                                  \
-  SIZEOF(Array, InstanceSize, RawArray)                                        \
-  SIZEOF(Array, header_size, RawArray)                                         \
-  SIZEOF(Bool, InstanceSize, RawBool)                                          \
-  SIZEOF(Bytecode, InstanceSize, RawBytecode)                                  \
-  SIZEOF(Capability, InstanceSize, RawCapability)                              \
-  SIZEOF(Class, InstanceSize, RawClass)                                        \
-  SIZEOF(Closure, InstanceSize, RawClosure)                                    \
-  SIZEOF(ClosureData, InstanceSize, RawClosureData)                            \
-  SIZEOF(Code, InstanceSize, RawCode)                                          \
-  SIZEOF(CodeSourceMap, InstanceSize, RawCodeSourceMap)                        \
-  SIZEOF(CompressedStackMaps, InstanceSize, RawCompressedStackMaps)            \
-  SIZEOF(CompressedStackMaps, HeaderSize, RawCompressedStackMaps)              \
-  SIZEOF(Context, InstanceSize, RawContext)                                    \
-  SIZEOF(Context, header_size, RawContext)                                     \
-  SIZEOF(ContextScope, InstanceSize, RawContextScope)                          \
-  SIZEOF(Double, InstanceSize, RawDouble)                                      \
-  SIZEOF(DynamicLibrary, InstanceSize, RawDynamicLibrary)                      \
-  SIZEOF(ExceptionHandlers, InstanceSize, RawExceptionHandlers)                \
-  SIZEOF(ExternalOneByteString, InstanceSize, RawExternalOneByteString)        \
-  SIZEOF(ExternalTwoByteString, InstanceSize, RawExternalTwoByteString)        \
-  SIZEOF(ExternalTypedData, InstanceSize, RawExternalTypedData)                \
-  SIZEOF(FfiTrampolineData, InstanceSize, RawFfiTrampolineData)                \
-  SIZEOF(Field, InstanceSize, RawField)                                        \
-  SIZEOF(Float32x4, InstanceSize, RawFloat32x4)                                \
-  SIZEOF(Float64x2, InstanceSize, RawFloat64x2)                                \
-  SIZEOF(Function, InstanceSize, RawFunction)                                  \
-  SIZEOF(FutureOr, InstanceSize, RawFutureOr)                                  \
-  SIZEOF(GrowableObjectArray, InstanceSize, RawGrowableObjectArray)            \
-  SIZEOF(ICData, InstanceSize, RawICData)                                      \
-  SIZEOF(Instance, InstanceSize, RawInstance)                                  \
-  SIZEOF(Instructions, InstanceSize, RawInstructions)                          \
-  SIZEOF(Instructions, UnalignedHeaderSize, RawInstructions)                   \
-  SIZEOF(InstructionsSection, InstanceSize, RawInstructionsSection)            \
-  SIZEOF(InstructionsSection, UnalignedHeaderSize, RawInstructionsSection)     \
-  SIZEOF(Int32x4, InstanceSize, RawInt32x4)                                    \
-  SIZEOF(Integer, InstanceSize, RawInteger)                                    \
-  SIZEOF(KernelProgramInfo, InstanceSize, RawKernelProgramInfo)                \
-  SIZEOF(LanguageError, InstanceSize, RawLanguageError)                        \
-  SIZEOF(Library, InstanceSize, RawLibrary)                                    \
-  SIZEOF(LibraryPrefix, InstanceSize, RawLibraryPrefix)                        \
-  SIZEOF(LinkedHashMap, InstanceSize, RawLinkedHashMap)                        \
-  SIZEOF(LocalVarDescriptors, InstanceSize, RawLocalVarDescriptors)            \
-  SIZEOF(MegamorphicCache, InstanceSize, RawMegamorphicCache)                  \
-  SIZEOF(Mint, InstanceSize, RawMint)                                          \
-  SIZEOF(MirrorReference, InstanceSize, RawMirrorReference)                    \
-  SIZEOF(MonomorphicSmiableCall, InstanceSize, RawMonomorphicSmiableCall)      \
-  SIZEOF(Namespace, InstanceSize, RawNamespace)                                \
+  SIZEOF(ApiError, InstanceSize, ApiErrorLayout)                               \
+  SIZEOF(Array, InstanceSize, ArrayLayout)                                     \
+  SIZEOF(Array, header_size, ArrayLayout)                                      \
+  SIZEOF(Bool, InstanceSize, BoolLayout)                                       \
+  SIZEOF(Bytecode, InstanceSize, BytecodeLayout)                               \
+  SIZEOF(Capability, InstanceSize, CapabilityLayout)                           \
+  SIZEOF(Class, InstanceSize, ClassLayout)                                     \
+  SIZEOF(Closure, InstanceSize, ClosureLayout)                                 \
+  SIZEOF(ClosureData, InstanceSize, ClosureDataLayout)                         \
+  SIZEOF(Code, InstanceSize, CodeLayout)                                       \
+  SIZEOF(CodeSourceMap, InstanceSize, CodeSourceMapLayout)                     \
+  SIZEOF(CompressedStackMaps, InstanceSize, CompressedStackMapsLayout)         \
+  SIZEOF(CompressedStackMaps, HeaderSize, CompressedStackMapsLayout)           \
+  SIZEOF(Context, InstanceSize, ContextLayout)                                 \
+  SIZEOF(Context, header_size, ContextLayout)                                  \
+  SIZEOF(ContextScope, InstanceSize, ContextScopeLayout)                       \
+  SIZEOF(Double, InstanceSize, DoubleLayout)                                   \
+  SIZEOF(DynamicLibrary, InstanceSize, DynamicLibraryLayout)                   \
+  SIZEOF(ExceptionHandlers, InstanceSize, ExceptionHandlersLayout)             \
+  SIZEOF(ExternalOneByteString, InstanceSize, ExternalOneByteStringLayout)     \
+  SIZEOF(ExternalTwoByteString, InstanceSize, ExternalTwoByteStringLayout)     \
+  SIZEOF(ExternalTypedData, InstanceSize, ExternalTypedDataLayout)             \
+  SIZEOF(FfiTrampolineData, InstanceSize, FfiTrampolineDataLayout)             \
+  SIZEOF(Field, InstanceSize, FieldLayout)                                     \
+  SIZEOF(Float32x4, InstanceSize, Float32x4Layout)                             \
+  SIZEOF(Float64x2, InstanceSize, Float64x2Layout)                             \
+  SIZEOF(Function, InstanceSize, FunctionLayout)                               \
+  SIZEOF(FutureOr, InstanceSize, FutureOrLayout)                               \
+  SIZEOF(GrowableObjectArray, InstanceSize, GrowableObjectArrayLayout)         \
+  SIZEOF(ICData, InstanceSize, ICDataLayout)                                   \
+  SIZEOF(Instance, InstanceSize, InstanceLayout)                               \
+  SIZEOF(Instructions, InstanceSize, InstructionsLayout)                       \
+  SIZEOF(Instructions, UnalignedHeaderSize, InstructionsLayout)                \
+  SIZEOF(InstructionsSection, InstanceSize, InstructionsSectionLayout)         \
+  SIZEOF(InstructionsSection, UnalignedHeaderSize, InstructionsSectionLayout)  \
+  SIZEOF(Int32x4, InstanceSize, Int32x4Layout)                                 \
+  SIZEOF(Integer, InstanceSize, IntegerLayout)                                 \
+  SIZEOF(KernelProgramInfo, InstanceSize, KernelProgramInfoLayout)             \
+  SIZEOF(LanguageError, InstanceSize, LanguageErrorLayout)                     \
+  SIZEOF(Library, InstanceSize, LibraryLayout)                                 \
+  SIZEOF(LibraryPrefix, InstanceSize, LibraryPrefixLayout)                     \
+  SIZEOF(LinkedHashMap, InstanceSize, LinkedHashMapLayout)                     \
+  SIZEOF(LocalVarDescriptors, InstanceSize, LocalVarDescriptorsLayout)         \
+  SIZEOF(MegamorphicCache, InstanceSize, MegamorphicCacheLayout)               \
+  SIZEOF(Mint, InstanceSize, MintLayout)                                       \
+  SIZEOF(MirrorReference, InstanceSize, MirrorReferenceLayout)                 \
+  SIZEOF(MonomorphicSmiableCall, InstanceSize, MonomorphicSmiableCallLayout)   \
+  SIZEOF(Namespace, InstanceSize, NamespaceLayout)                             \
   SIZEOF(NativeArguments, StructSize, NativeArguments)                         \
-  SIZEOF(Number, InstanceSize, RawNumber)                                      \
-  SIZEOF(Object, InstanceSize, RawObject)                                      \
-  SIZEOF(ObjectPool, InstanceSize, RawObjectPool)                              \
-  SIZEOF(OneByteString, InstanceSize, RawOneByteString)                        \
-  SIZEOF(ParameterTypeCheck, InstanceSize, RawParameterTypeCheck)              \
-  SIZEOF(PatchClass, InstanceSize, RawPatchClass)                              \
-  SIZEOF(PcDescriptors, InstanceSize, RawPcDescriptors)                        \
-  SIZEOF(Pointer, InstanceSize, RawPointer)                                    \
-  SIZEOF(ReceivePort, InstanceSize, RawReceivePort)                            \
-  SIZEOF(RedirectionData, InstanceSize, RawRedirectionData)                    \
-  SIZEOF(RegExp, InstanceSize, RawRegExp)                                      \
-  SIZEOF(Script, InstanceSize, RawScript)                                      \
-  SIZEOF(SendPort, InstanceSize, RawSendPort)                                  \
-  SIZEOF(SignatureData, InstanceSize, RawSignatureData)                        \
-  SIZEOF(SingleTargetCache, InstanceSize, RawSingleTargetCache)                \
-  SIZEOF(Smi, InstanceSize, RawSmi)                                            \
-  SIZEOF(StackTrace, InstanceSize, RawStackTrace)                              \
-  SIZEOF(String, InstanceSize, RawString)                                      \
-  SIZEOF(SubtypeTestCache, InstanceSize, RawSubtypeTestCache)                  \
-  SIZEOF(TransferableTypedData, InstanceSize, RawTransferableTypedData)        \
-  SIZEOF(TwoByteString, InstanceSize, RawTwoByteString)                        \
-  SIZEOF(Type, InstanceSize, RawType)                                          \
-  SIZEOF(TypeArguments, InstanceSize, RawTypeArguments)                        \
-  SIZEOF(TypeParameter, InstanceSize, RawTypeParameter)                        \
-  SIZEOF(TypeRef, InstanceSize, RawTypeRef)                                    \
-  SIZEOF(TypedData, InstanceSize, RawTypedData)                                \
-  SIZEOF(TypedDataBase, InstanceSize, RawTypedDataBase)                        \
-  SIZEOF(TypedDataView, InstanceSize, RawTypedDataView)                        \
-  SIZEOF(UnhandledException, InstanceSize, RawUnhandledException)              \
-  SIZEOF(UnlinkedCall, InstanceSize, RawUnlinkedCall)                          \
-  SIZEOF(UnwindError, InstanceSize, RawUnwindError)                            \
-  SIZEOF(UserTag, InstanceSize, RawUserTag)                                    \
-  SIZEOF(WeakProperty, InstanceSize, RawWeakProperty)                          \
+  SIZEOF(Number, InstanceSize, NumberLayout)                                   \
+  SIZEOF(Object, InstanceSize, ObjectLayout)                                   \
+  SIZEOF(ObjectPool, InstanceSize, ObjectPoolLayout)                           \
+  SIZEOF(OneByteString, InstanceSize, OneByteStringLayout)                     \
+  SIZEOF(ParameterTypeCheck, InstanceSize, ParameterTypeCheckLayout)           \
+  SIZEOF(PatchClass, InstanceSize, PatchClassLayout)                           \
+  SIZEOF(PcDescriptors, InstanceSize, PcDescriptorsLayout)                     \
+  SIZEOF(Pointer, InstanceSize, PointerLayout)                                 \
+  SIZEOF(ReceivePort, InstanceSize, ReceivePortLayout)                         \
+  SIZEOF(RedirectionData, InstanceSize, RedirectionDataLayout)                 \
+  SIZEOF(RegExp, InstanceSize, RegExpLayout)                                   \
+  SIZEOF(Script, InstanceSize, ScriptLayout)                                   \
+  SIZEOF(SendPort, InstanceSize, SendPortLayout)                               \
+  SIZEOF(SignatureData, InstanceSize, SignatureDataLayout)                     \
+  SIZEOF(SingleTargetCache, InstanceSize, SingleTargetCacheLayout)             \
+  SIZEOF(Smi, InstanceSize, SmiLayout)                                         \
+  SIZEOF(StackTrace, InstanceSize, StackTraceLayout)                           \
+  SIZEOF(String, InstanceSize, StringLayout)                                   \
+  SIZEOF(SubtypeTestCache, InstanceSize, SubtypeTestCacheLayout)               \
+  SIZEOF(TransferableTypedData, InstanceSize, TransferableTypedDataLayout)     \
+  SIZEOF(TwoByteString, InstanceSize, TwoByteStringLayout)                     \
+  SIZEOF(Type, InstanceSize, TypeLayout)                                       \
+  SIZEOF(TypeArguments, InstanceSize, TypeArgumentsLayout)                     \
+  SIZEOF(TypeParameter, InstanceSize, TypeParameterLayout)                     \
+  SIZEOF(TypeRef, InstanceSize, TypeRefLayout)                                 \
+  SIZEOF(TypedData, InstanceSize, TypedDataLayout)                             \
+  SIZEOF(TypedDataBase, InstanceSize, TypedDataBaseLayout)                     \
+  SIZEOF(TypedDataView, InstanceSize, TypedDataViewLayout)                     \
+  SIZEOF(UnhandledException, InstanceSize, UnhandledExceptionLayout)           \
+  SIZEOF(UnlinkedCall, InstanceSize, UnlinkedCallLayout)                       \
+  SIZEOF(UnwindError, InstanceSize, UnwindErrorLayout)                         \
+  SIZEOF(UserTag, InstanceSize, UserTagLayout)                                 \
+  SIZEOF(WeakProperty, InstanceSize, WeakPropertyLayout)                       \
   SIZEOF(WeakSerializationReference, InstanceSize,                             \
-         RawWeakSerializationReference)
+         WeakSerializationReferenceLayout)
 
 #endif  // RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_LIST_H_
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 3e6c845..27a2839 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -9,8 +9,6 @@
 
 #include "vm/compiler/stub_code_compiler.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
 #include "vm/compiler/assembler/assembler.h"
 
 #define __ assembler->
@@ -29,8 +27,123 @@
   __ Ret();
 }
 
+void StubCodeCompiler::GenerateInitInstanceFieldStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for (unused) result.
+  __ PushRegister(InitInstanceFieldABI::kInstanceReg);
+  __ PushRegister(InitInstanceFieldABI::kFieldReg);
+  __ CallRuntime(kInitInstanceFieldRuntimeEntry, /*argument_count=*/2);
+  __ Drop(3);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateInitLateInstanceFieldStub(Assembler* assembler,
+                                                         bool is_final) {
+  __ EnterStubFrame();
+  // Save for later.
+  __ PushRegisterPair(InitInstanceFieldABI::kInstanceReg,
+                      InitInstanceFieldABI::kFieldReg);
+
+  // Call initializer function.
+  __ PushRegister(InitInstanceFieldABI::kInstanceReg);
+
+  const Register kFunctionReg = InitLateInstanceFieldInternalRegs::kFunctionReg;
+  const Register kInitializerResultReg =
+      InitLateInstanceFieldInternalRegs::kInitializerResultReg;
+  const Register kInstanceReg = InitLateInstanceFieldInternalRegs::kInstanceReg;
+  const Register kFieldReg = InitLateInstanceFieldInternalRegs::kFieldReg;
+  const Register kAddressReg = InitLateInstanceFieldInternalRegs::kAddressReg;
+  const Register kScratchReg = InitLateInstanceFieldInternalRegs::kScratchReg;
+
+  __ LoadField(kFunctionReg,
+               FieldAddress(InitInstanceFieldABI::kFieldReg,
+                            target::Field::initializer_function_offset()));
+  if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
+    __ LoadField(CODE_REG,
+                 FieldAddress(kFunctionReg, target::Function::code_offset()));
+  }
+  __ Call(FieldAddress(kFunctionReg, target::Function::entry_point_offset()));
+  __ Drop(1);  // Drop argument.
+
+  __ PopRegisterPair(kInstanceReg, kFieldReg);
+  __ LoadField(
+      kScratchReg,
+      FieldAddress(kFieldReg, target::Field::host_offset_or_field_id_offset()));
+  __ LoadFieldAddressForRegOffset(kAddressReg, kInstanceReg, kScratchReg);
+
+  Label throw_exception;
+  if (is_final) {
+    __ LoadMemoryValue(kScratchReg, kAddressReg, 0);
+    __ CompareObject(kScratchReg, SentinelObject());
+    __ BranchIf(NOT_EQUAL, &throw_exception);
+  }
+
+  __ StoreIntoObject(kInstanceReg, Address(kAddressReg, 0),
+                     kInitializerResultReg);
+
+  __ LeaveStubFrame();
+  __ Ret();
+
+  if (is_final) {
+    __ Bind(&throw_exception);
+    __ PushObject(NullObject());  // Make room for (unused) result.
+    __ PushRegister(kFieldReg);
+    __ CallRuntime(kLateInitializationErrorRuntimeEntry,
+                   /*argument_count=*/1);
+    __ Breakpoint();
+  }
+}
+
+void StubCodeCompiler::GenerateInitLateInstanceFieldStub(Assembler* assembler) {
+  GenerateInitLateInstanceFieldStub(assembler, /*is_final=*/false);
+}
+
+void StubCodeCompiler::GenerateInitLateFinalInstanceFieldStub(
+    Assembler* assembler) {
+  GenerateInitLateInstanceFieldStub(assembler, /*is_final=*/true);
+}
+
+void StubCodeCompiler::GenerateThrowStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for (unused) result.
+  __ PushRegister(ThrowABI::kExceptionReg);
+  __ CallRuntime(kThrowRuntimeEntry, /*argument_count=*/1);
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateReThrowStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for (unused) result.
+  __ PushRegister(ReThrowABI::kExceptionReg);
+  __ PushRegister(ReThrowABI::kStackTraceReg);
+  __ CallRuntime(kReThrowRuntimeEntry, /*argument_count=*/2);
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateAssertBooleanStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for (unused) result.
+  __ PushRegister(AssertBooleanABI::kObjectReg);
+  __ CallRuntime(kNonBoolTypeErrorRuntimeEntry, /*argument_count=*/1);
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateInstanceOfStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for the result.
+  __ PushRegister(TypeTestABI::kInstanceReg);
+  __ PushRegister(TypeTestABI::kDstTypeReg);
+  __ PushRegister(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ PushRegister(TypeTestABI::kFunctionTypeArgumentsReg);
+  __ PushRegister(TypeTestABI::kSubtypeTestCacheReg);
+  __ CallRuntime(kInstanceofRuntimeEntry, /*argument_count=*/5);
+  __ Drop(5);
+  __ PopRegister(TypeTestABI::kResultReg);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
 }  // namespace compiler
 
 }  // namespace dart
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
index a856c0d..6c4f4a3 100644
--- a/runtime/vm/compiler/stub_code_compiler.h
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -5,18 +5,47 @@
 #ifndef RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
 #define RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/compiler/runtime_api.h"
 #include "vm/constants.h"
+#include "vm/growable_array.h"
 #include "vm/stub_code_list.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
+// Forward declarations.
+class Code;
+
 namespace compiler {
 
 // Forward declarations.
 class Assembler;
 
+// Represents an unresolved PC-relative Call/TailCall.
+class UnresolvedPcRelativeCall : public ZoneAllocated {
+ public:
+  UnresolvedPcRelativeCall(intptr_t offset,
+                           const dart::Code& target,
+                           bool is_tail_call)
+      : offset_(offset), target_(target), is_tail_call_(is_tail_call) {}
+
+  intptr_t offset() const { return offset_; }
+  const dart::Code& target() const { return target_; }
+  bool is_tail_call() const { return is_tail_call_; }
+
+ private:
+  const intptr_t offset_;
+  const dart::Code& target_;
+  const bool is_tail_call_;
+};
+
+using UnresolvedPcRelativeCalls = GrowableArray<UnresolvedPcRelativeCall*>;
+
 class StubCodeCompiler : public AllStatic {
  public:
 #if !defined(TARGET_ARCH_IA32)
@@ -26,15 +55,22 @@
       const Object& context_allocation_stub);
 #endif
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+  static ArrayPtr BuildStaticCallsTable(
+      Zone* zone,
+      compiler::UnresolvedPcRelativeCalls* unresolved_calls);
+
 #define STUB_CODE_GENERATE(name)                                               \
   static void Generate##name##Stub(Assembler* assembler);
   VM_STUB_CODE_LIST(STUB_CODE_GENERATE)
 #undef STUB_CODE_GENERATE
 
-  static void GenerateMegamorphicMissStub(Assembler* assembler);
-  static void GenerateAllocationStubForClass(Assembler* assembler,
-                                             const Class& cls);
+  static void GenerateMegamorphicCallMissStub(Assembler* assembler);
+  static void GenerateAllocationStubForClass(
+      Assembler* assembler,
+      UnresolvedPcRelativeCalls* unresolved_calls,
+      const Class& cls,
+      const dart::Code& allocate_object,
+      const dart::Code& allocat_object_parametrized);
 
   enum Optimized {
     kUnoptimized,
@@ -90,30 +126,17 @@
   static void GenerateJITCallbackTrampolines(Assembler* assembler,
                                              intptr_t next_callback_id);
 
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+ private:
+  // Common function for generating InitLateInstanceField and
+  // InitLateFinalInstanceField stubs.
+  static void GenerateInitLateInstanceFieldStub(Assembler* assembler,
+                                                bool is_final);
 };
 
 }  // namespace compiler
 
 enum DeoptStubKind { kLazyDeoptFromReturn, kLazyDeoptFromThrow, kEagerDeopt };
 
-// Invocation mode for TypeCheck runtime entry that describes
-// where we are calling it from.
-enum TypeCheckMode {
-  // TypeCheck is invoked from LazySpecializeTypeTest stub.
-  // It should replace stub on the type with a specialized version.
-  kTypeCheckFromLazySpecializeStub,
-
-  // TypeCheck is invoked from the SlowTypeTest stub.
-  // This means that cache can be lazily created (if needed)
-  // and dst_name can be fetched from the pool.
-  kTypeCheckFromSlowStub,
-
-  // TypeCheck is invoked from normal inline AssertAssignable.
-  // Both cache and dst_name must be already populated.
-  kTypeCheckFromInline
-};
-
 // Zap value used to indicate unused CODE_REG in deopt.
 static const uword kZapCodeReg = 0xf1f1f1f1;
 
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 490f4c1..6ce6f66 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -12,10 +12,11 @@
 
 #include "vm/compiler/stub_code_compiler.h"
 
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM)
 
 #include "vm/class_id.h"
 #include "vm/code_entry_kind.h"
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/constants.h"
@@ -156,12 +157,14 @@
   __ Ret();
 }
 
-void GenerateSharedStub(Assembler* assembler,
-                        bool save_fpu_registers,
-                        const RuntimeEntry* target,
-                        intptr_t self_code_stub_offset_from_thread,
-                        bool allow_return,
-                        bool store_runtime_result_in_r0 = false) {
+void GenerateSharedStub(
+    Assembler* assembler,
+    bool save_fpu_registers,
+    const RuntimeEntry* target,
+    intptr_t self_code_stub_offset_from_thread,
+    bool allow_return,
+    bool store_runtime_result_in_r0 = false,
+    std::initializer_list<Register> runtime_call_arguments = {}) {
   // If the target CPU does not support VFP the caller should always use the
   // non-FPU stub.
   if (save_fpu_registers && !TargetCPUFeatures::vfp_supported()) {
@@ -190,16 +193,19 @@
     __ Push(LR);
   }
 
-  __ CallRuntime(*target, /*argument_count=*/0);
-
-  if (store_runtime_result_in_r0) {
-    __ Pop(R0);
+  for (Register argument_reg : runtime_call_arguments) {
+    __ PushRegister(argument_reg);
   }
-
+  __ CallRuntime(*target, /*argument_count=*/runtime_call_arguments.size());
   if (!allow_return) {
     __ Breakpoint();
     return;
   }
+
+  __ Drop(runtime_call_arguments.size());
+  if (store_runtime_result_in_r0) {
+    __ Pop(R0);
+  }
   __ LeaveStubFrame();
   if (store_runtime_result_in_r0) {
     // Stores the runtime result in stack where R0 was pushed ( R0 is the very
@@ -483,7 +489,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kNullErrorRuntimeEntry,
       target::Thread::null_error_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
@@ -491,7 +497,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kNullErrorRuntimeEntry,
       target::Thread::null_error_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullArgErrorSharedWithoutFPURegsStub(
@@ -499,7 +505,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kArgumentNullErrorRuntimeEntry,
       target::Thread::null_arg_error_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullArgErrorSharedWithFPURegsStub(
@@ -507,7 +513,27 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kArgumentNullErrorRuntimeEntry,
       target::Thread::null_arg_error_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kRangeErrorRuntimeEntry,
+      target::Thread::range_error_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/false,
+      /*store_runtime_result_in_r0=*/false,
+      {RangeErrorABI::kLengthReg, RangeErrorABI::kIndexReg});
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kRangeErrorRuntimeEntry,
+      target::Thread::range_error_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/false,
+      /*store_runtime_result_in_r0=*/false,
+      {RangeErrorABI::kLengthReg, RangeErrorABI::kIndexReg});
 }
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
@@ -515,7 +541,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
       target::Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
+      /*allow_return=*/true, {});
 }
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
@@ -523,7 +549,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kStackOverflowRuntimeEntry,
       target::Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
+      /*allow_return=*/true, {});
 }
 
 // Input parameters:
@@ -964,14 +990,13 @@
   __ Ret();
 }
 
-static void GenerateDispatcherCode(Assembler* assembler,
-                                   Label* call_target_function) {
-  __ Comment("NoSuchMethodDispatch");
-  // When lazily generated invocation dispatchers are disabled, the
-  // miss-handler may return null.
-  __ CompareObject(R0, NullObject());
-  __ b(call_target_function, NE);
+// R9: ICData/MegamorphicCache
+static void GenerateNoSuchMethodDispatcherBody(Assembler* assembler) {
   __ EnterStubFrame();
+
+  __ ldr(R4,
+         FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
+
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::size_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
@@ -1000,43 +1025,23 @@
   __ Ret();
 }
 
-void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ EnterStubFrame();
+static void GenerateDispatcherCode(Assembler* assembler,
+                                   Label* call_target_function) {
+  __ Comment("NoSuchMethodDispatch");
+  // When lazily generated invocation dispatchers are disabled, the
+  // miss-handler may return null.
+  __ CompareObject(R0, NullObject());
+  __ b(call_target_function, NE);
 
-  // Load the receiver.
-  __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::size_offset()));
-  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
-                             target::kWordSize));
+  GenerateNoSuchMethodDispatcherBody(assembler);
+}
 
-  // Preserve IC data and arguments descriptor.
-  __ PushList((1 << R4) | (1 << R9));
-
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // result slot
-  __ Push(R8);  // receiver
-  __ Push(R9);  // ICData
-  __ Push(R4);  // arguments descriptor
-  __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
-  // Remove arguments.
-  __ Drop(3);
-  __ Pop(R0);  // Get result into R0 (target function).
-
-  // Restore IC data and arguments descriptor.
-  __ PopList((1 << R4) | (1 << R9));
-
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-
-  if (!FLAG_lazy_dispatchers) {
-    Label call_target_function;
-    GenerateDispatcherCode(assembler, &call_target_function);
-    __ Bind(&call_target_function);
-  }
-
-  // Tail-call to target function.
-  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
-  __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+// Input:
+//   R4 - arguments descriptor
+//   R9 - icdata/megamorphic_cache
+void StubCodeCompiler::GenerateNoSuchMethodDispatcherStub(
+    Assembler* assembler) {
+  GenerateNoSuchMethodDispatcherBody(assembler);
 }
 
 // Called for inline allocation of arrays.
@@ -1102,10 +1107,10 @@
     // R3: new object end address.
     // R9: allocation size.
     {
-      const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+      const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
                              target::ObjectAlignment::kObjectAlignmentLog2;
 
-      __ CompareImmediate(R9, target::RawObject::kSizeTagMaxSizeTag);
+      __ CompareImmediate(R9, target::ObjectLayout::kSizeTagMaxSizeTag);
       __ mov(R8, Operand(R9, LSL, shift), LS);
       __ mov(R8, Operand(0), HI);
 
@@ -1169,7 +1174,7 @@
 }
 
 // Called for allocation of Mint.
-void StubCodeCompiler::GenerateAllocateMintWithFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
   if (!FLAG_use_slow_path) {
@@ -1184,11 +1189,11 @@
                      &kAllocateMintRuntimeEntry,
                      target::Thread::allocate_mint_with_fpu_regs_stub_offset(),
                      /*allow_return=*/true,
-                     /*store_runtime_result_in_r0=*/true);
+                     /*store_runtime_result_in_r0=*/true, {});
 }
 
 // Called for allocation of Mint.
-void StubCodeCompiler::GenerateAllocateMintWithoutFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
   if (!FLAG_use_slow_path) {
@@ -1203,7 +1208,7 @@
       assembler, /*save_fpu_registers=*/false, &kAllocateMintRuntimeEntry,
       target::Thread::allocate_mint_without_fpu_regs_stub_offset(),
       /*allow_return=*/true,
-      /*store_runtime_result_in_r0=*/true);
+      /*store_runtime_result_in_r0=*/true, {});
 }
 
 // Called when invoking Dart code from C++ (VM code).
@@ -1344,9 +1349,11 @@
 //   R3 : current thread.
 void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
     Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
+  if (FLAG_precompiled_mode) {
+    __ Stop("Not using interpreter");
+    return;
+  }
+
   __ Push(LR);  // Marker for the profiler.
   __ EnterFrame((1 << FP) | (1 << LR), 0);
 
@@ -1477,7 +1484,6 @@
   __ LeaveFrame((1 << FP) | (1 << LR));
   __ Drop(1);
   __ Ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // Helper to generate space allocation of context stub.
@@ -1529,9 +1535,9 @@
   // R1: number of context variables.
   // R2: object size.
   // R3: next object start.
-  const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+  const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
                          target::ObjectAlignment::kObjectAlignmentLog2;
-  __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+  __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
   // If no size tag overflow, shift R2 left, else set R2 to zero.
   __ mov(R9, Operand(R2, LSL, shift), LS);
   __ mov(R9, Operand(0), HI);
@@ -1727,13 +1733,13 @@
 
   if (cards) {
     __ ldr(TMP, FieldAddress(R1, target::Object::tags_offset()));
-    __ tst(TMP, Operand(1 << target::RawObject::kCardRememberedBit));
+    __ tst(TMP, Operand(1 << target::ObjectLayout::kCardRememberedBit));
     __ b(&remember_card, NOT_ZERO);
   } else {
 #if defined(DEBUG)
     Label ok;
     __ ldr(TMP, FieldAddress(R1, target::Object::tags_offset()));
-    __ tst(TMP, Operand(1 << target::RawObject::kCardRememberedBit));
+    __ tst(TMP, Operand(1 << target::ObjectLayout::kCardRememberedBit));
     __ b(&ok, ZERO);
     __ Stop("Wrong barrier");
     __ Bind(&ok);
@@ -1750,7 +1756,7 @@
   Label retry;
   __ Bind(&retry);
   __ ldrex(R2, R3);
-  __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotRememberedBit));
+  __ bic(R2, R2, Operand(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   __ strex(R4, R2, R3);
   __ cmp(R4, Operand(1));
   __ b(&retry, EQ);
@@ -1798,9 +1804,9 @@
   // R3: Untagged address of header word (ldrex/strex do not support offsets).
   __ Bind(&marking_retry);
   __ ldrex(R2, R3);
-  __ tst(R2, Operand(1 << target::RawObject::kOldAndNotMarkedBit));
+  __ tst(R2, Operand(1 << target::ObjectLayout::kOldAndNotMarkedBit));
   __ b(&lost_race, ZERO);
-  __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotMarkedBit));
+  __ bic(R2, R2, Operand(1 << target::ObjectLayout::kOldAndNotMarkedBit));
   __ strex(R4, R2, R3);
   __ cmp(R4, Operand(1));
   __ b(&marking_retry, EQ);
@@ -1883,109 +1889,224 @@
       Address(THR, target::Thread::array_write_barrier_code_offset()), true);
 }
 
+static void GenerateAllocateObjectHelper(Assembler* assembler,
+                                         bool is_cls_parameterized) {
+  const Register kInstanceReg = R0;
+  // R1
+  const Register kTagsReg = R2;
+  // kAllocationStubTypeArgumentsReg = R3
+
+  {
+    Label slow_case;
+
+    const Register kNewTopReg = R8;
+
+    // Bump allocation.
+    {
+      const Register kEndReg = R1;
+      const Register kInstanceSizeReg = R9;
+
+      __ ExtractInstanceSizeFromTags(kInstanceSizeReg, kTagsReg);
+
+      // Load two words from Thread::top: top and end.
+      // kInstanceReg: potential next object start.
+      __ ldrd(kInstanceReg, kEndReg, THR, target::Thread::top_offset());
+
+      __ add(kNewTopReg, kInstanceReg, Operand(kInstanceSizeReg));
+
+      __ CompareRegisters(kEndReg, kNewTopReg);
+      __ b(&slow_case, UNSIGNED_LESS_EQUAL);
+
+      // Successfully allocated the object, now update top to point to
+      // next object start and store the class in the class field of object.
+      __ str(kNewTopReg, Address(THR, target::Thread::top_offset()));
+    }  //  kEndReg = R1, kInstanceSizeReg = R9
+
+    // Tags.
+    __ str(kTagsReg, Address(kInstanceReg, target::Object::tags_offset()));
+
+    // Initialize the remaining words of the object.
+    {
+      const Register kFieldReg = R1;
+      const Register kNullReg = R9;
+
+      __ LoadObject(kNullReg, NullObject());
+
+      __ AddImmediate(kFieldReg, kInstanceReg,
+                      target::Instance::first_field_offset());
+      Label done, init_loop;
+      __ Bind(&init_loop);
+      __ CompareRegisters(kFieldReg, kNewTopReg);
+      __ b(&done, UNSIGNED_GREATER_EQUAL);
+      __ str(kNullReg,
+             Address(kFieldReg, target::kWordSize, Address::PostIndex));
+      __ b(&init_loop);
+
+      __ Bind(&done);
+    }  // kFieldReg = R1, kNullReg = R9
+
+    // Store parameterized type.
+    if (is_cls_parameterized) {
+      Label not_parameterized_case;
+
+      const Register kClsIdReg = R2;
+      const Register kTypeOffestReg = R9;
+
+      __ ExtractClassIdFromTags(kClsIdReg, kTagsReg);
+
+      // Load class' type_arguments_field offset in words.
+      __ LoadClassById(kTypeOffestReg, kClsIdReg);
+      __ ldr(
+          kTypeOffestReg,
+          FieldAddress(kTypeOffestReg,
+                       target::Class::
+                           host_type_arguments_field_offset_in_words_offset()));
+
+      // Set the type arguments in the new object.
+      __ StoreIntoObjectNoBarrier(
+          kInstanceReg,
+          Address(kInstanceReg, kTypeOffestReg, LSL, target::kWordSizeLog2),
+          kAllocationStubTypeArgumentsReg);
+
+      __ Bind(&not_parameterized_case);
+    }  // kClsIdReg = R1, kTypeOffestReg = R9
+
+    __ AddImmediate(kInstanceReg, kInstanceReg, kHeapObjectTag);
+
+    __ Ret();
+
+    __ Bind(&slow_case);
+  }  // kNewTopReg = R8
+
+  // Fall back on slow case:
+  {
+    const Register kStubReg = R8;
+
+    if (!is_cls_parameterized) {
+      __ LoadObject(kAllocationStubTypeArgumentsReg, NullObject());
+    }
+
+    // Tail call to generic allocation stub.
+    __ ldr(kStubReg,
+           Address(THR,
+                   target::Thread::allocate_object_slow_entry_point_offset()));
+    __ bx(kStubReg);
+  }  // kStubReg = R8
+}
+
+// Called for inline allocation of objects (any class).
+void StubCodeCompiler::GenerateAllocateObjectStub(Assembler* assembler) {
+  GenerateAllocateObjectHelper(assembler, /*is_cls_parameterized=*/false);
+}
+
+void StubCodeCompiler::GenerateAllocateObjectParameterizedStub(
+    Assembler* assembler) {
+  GenerateAllocateObjectHelper(assembler, /*is_cls_parameterized=*/true);
+}
+
+void StubCodeCompiler::GenerateAllocateObjectSlowStub(Assembler* assembler) {
+  const Register kInstanceReg = R0;
+  const Register kClsReg = R1;
+  const Register kTagsReg = R2;
+  // kAllocationStubTypeArgumentsReg = R3
+
+  if (!FLAG_use_bare_instructions) {
+    __ ldr(CODE_REG,
+           Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  }
+
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+
+  __ ExtractClassIdFromTags(kInstanceReg, kTagsReg);
+  __ LoadClassById(kClsReg, kInstanceReg);
+
+  __ LoadObject(kInstanceReg, NullObject());
+
+  // Pushes result slot, then parameter class.
+  __ PushRegisterPair(kClsReg, kInstanceReg);
+
+  // Should be Object::null() if class is non-parameterized.
+  __ Push(kAllocationStubTypeArgumentsReg);
+
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);
+
+  // Load result off the stack into result register.
+  __ ldr(kInstanceReg, Address(SP, 2 * target::kWordSize));
+
+  // Write-barrier elimination is enabled for [cls] and we therefore need to
+  // ensure that the object is in new-space or has remembered bit set.
+  EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+
+  __ LeaveDartFrameAndReturn();
+}
+
 // Called for inline allocation of objects.
-// Input parameters:
-//   LR : return address.
-//   kAllocationStubTypeArgumentsReg (R3): type arguments object
-//                                         (only if class is parameterized).
-void StubCodeCompiler::GenerateAllocationStubForClass(Assembler* assembler,
-                                                      const Class& cls) {
+void StubCodeCompiler::GenerateAllocationStubForClass(
+    Assembler* assembler,
+    UnresolvedPcRelativeCalls* unresolved_calls,
+    const Class& cls,
+    const Code& allocate_object,
+    const Code& allocat_object_parametrized) {
+  classid_t cls_id = target::Class::GetId(cls);
+  ASSERT(cls_id != kIllegalCid);
+
+  RELEASE_ASSERT(AllocateObjectInstr::WillAllocateNewOrRemembered(cls));
+
   // The generated code is different if the class is parameterized.
   const bool is_cls_parameterized = target::Class::NumTypeArguments(cls) > 0;
   ASSERT(!is_cls_parameterized || target::Class::TypeArgumentsFieldOffset(
                                       cls) != target::Class::kNoTypeArguments);
 
-  const Register kNullReg = R8;
-  const Register kOtherNullReg = R9;
-  const Register kTypeArgumentsReg = kAllocationStubTypeArgumentsReg;
-  const Register kInstanceReg = R0;
-  const Register kEndReg = R1;
-  const Register kEndOfInstanceReg = R2;
-  static_assert(kAllocationStubTypeArgumentsReg == R3,
-                "Adjust register allocation in the AllocationStub");
-
-  // kInlineInstanceSize is a constant used as a threshold for determining
-  // when the object initialization should be done as a loop or as
-  // straight line code.
-  const int kInlineInstanceSize = 12;
   const intptr_t instance_size = target::Class::GetInstanceSize(cls);
   ASSERT(instance_size > 0);
-  ASSERT(instance_size % target::ObjectAlignment::kObjectAlignment == 0);
+  RELEASE_ASSERT(target::Heap::IsAllocatableInNewSpace(instance_size));
 
-  __ LoadObject(kNullReg, NullObject());
+  const uint32_t tags =
+      target::MakeTagWordForNewSpaceObject(cls_id, instance_size);
+
+  // Note: Keep in sync with helper function.
+  // kInstanceReg = R0
+  const Register kTagsReg = R2;
+  // kAllocationStubTypeArgumentsReg = R3
+
+  __ LoadImmediate(kTagsReg, tags);
+
   if (!FLAG_use_slow_path && FLAG_inline_alloc &&
-      target::Heap::IsAllocatableInNewSpace(instance_size) &&
-      !target::Class::TraceAllocation(cls)) {
-    Label slow_case;
-
-    // Allocate the object and update top to point to
-    // next object start and initialize the allocated object.
-
-    RELEASE_ASSERT((target::Thread::top_offset() + target::kWordSize) ==
-                   target::Thread::end_offset());
-    __ ldrd(kInstanceReg, kEndReg, THR, target::Thread::top_offset());
-    __ AddImmediate(kEndOfInstanceReg, kInstanceReg, instance_size);
-    __ cmp(kEndOfInstanceReg, Operand(kEndReg));
-    __ b(&slow_case, CS);  // Unsigned higher or equal.
-
-    __ str(kEndOfInstanceReg, Address(THR, target::Thread::top_offset()));
-
-    // Set the tags.
-    ASSERT(target::Class::GetId(cls) != kIllegalCid);
-    const uint32_t tags = target::MakeTagWordForNewSpaceObject(
-        target::Class::GetId(cls), instance_size);
-
-    __ LoadImmediate(R1, tags);
-    __ str(R1, Address(kInstanceReg, target::Object::tags_offset()));
-    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
-
-    // First try inlining the initialization without a loop.
-    if (instance_size < (kInlineInstanceSize * target::kWordSize)) {
-      intptr_t begin_offset =
-          target::Instance::first_field_offset() - kHeapObjectTag;
-      intptr_t end_offset = instance_size - kHeapObjectTag;
-      if ((end_offset - begin_offset) >= (2 * target::kWordSize)) {
-        __ mov(kOtherNullReg, Operand(kNullReg));
-      }
-      __ InitializeFieldsNoBarrierUnrolled(kInstanceReg, kInstanceReg,
-                                           begin_offset, end_offset, kNullReg,
-                                           kOtherNullReg);
-    } else {
-      __ add(R1, kInstanceReg,
-             Operand(target::Instance::first_field_offset() - kHeapObjectTag));
-      __ mov(kOtherNullReg, Operand(kNullReg));
-      __ InitializeFieldsNoBarrier(kInstanceReg, R1, kEndOfInstanceReg,
-                                   kNullReg, kOtherNullReg);
-    }
+      !target::Class::TraceAllocation(cls) &&
+      target::SizeFitsInSizeTag(instance_size)) {
     if (is_cls_parameterized) {
-      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
-      __ StoreIntoObjectNoBarrier(
-          kInstanceReg, FieldAddress(kInstanceReg, offset), kTypeArgumentsReg);
+      if (!IsSameObject(NullObject(),
+                        CastHandle<Object>(allocat_object_parametrized))) {
+        __ GenerateUnRelocatedPcRelativeTailCall();
+        unresolved_calls->Add(new UnresolvedPcRelativeCall(
+            __ CodeSize(), allocat_object_parametrized, /*is_tail_call=*/true));
+      } else {
+        __ ldr(PC,
+               Address(THR,
+                       target::Thread::
+                           allocate_object_parameterized_entry_point_offset()));
+      }
+    } else {
+      if (!IsSameObject(NullObject(), CastHandle<Object>(allocate_object))) {
+        __ GenerateUnRelocatedPcRelativeTailCall();
+        unresolved_calls->Add(new UnresolvedPcRelativeCall(
+            __ CodeSize(), allocate_object, /*is_tail_call=*/true));
+      } else {
+        __ ldr(
+            PC,
+            Address(THR, target::Thread::allocate_object_entry_point_offset()));
+      }
     }
-
-    __ Ret();
-    __ Bind(&slow_case);
+  } else {
+    if (!is_cls_parameterized) {
+      __ LoadObject(kAllocationStubTypeArgumentsReg, NullObject());
+    }
+    __ ldr(PC,
+           Address(THR,
+                   target::Thread::allocate_object_slow_entry_point_offset()));
   }
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();  // Uses pool pointer to pass cls to runtime.
-  __ LoadObject(R1, CastHandle<Object>(cls));
-  __ PushList(1 << kNullReg | 1 << R1);  // Pushes cls, result slot.
-  __ Push(is_cls_parameterized ? kTypeArgumentsReg : kNullReg);
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ ldr(
-      kInstanceReg,
-      Address(SP,
-              2 * target::kWordSize));  // Pop result (newly allocated object).
-
-  ASSERT(kInstanceReg == R0);
-  if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
-    // Write-barrier elimination is enabled for [cls] and we therefore need to
-    // ensure that the object is in new-space or has remembered bit set.
-    EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
-  }
-
-  __ LeaveDartFrameAndReturn();  // Restores correct SP.
 }
 
 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
@@ -2226,7 +2347,8 @@
 
   if (type == kInstanceCall) {
     __ LoadTaggedClassIdMayBeSmi(R0, R0);
-    __ ldr(R4, FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+    __ ldr(R4, FieldAddress(
+                   R9, target::CallSiteData::arguments_descriptor_offset()));
     if (num_args == 2) {
       __ ldr(R1, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
       __ sub(R1, R1, Operand(target::ToRawSmi(2)));
@@ -2235,7 +2357,8 @@
     }
   } else {
     // Load arguments descriptor into R4.
-    __ ldr(R4, FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+    __ ldr(R4, FieldAddress(
+                   R9, target::CallSiteData::arguments_descriptor_offset()));
 
     // Get the receiver's class ID (first read number of arguments from
     // arguments descriptor array and then access the receiver from the stack).
@@ -2527,7 +2650,8 @@
   }
 
   // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+  __ ldr(R4,
+         FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
 
   // Get function and call it, if possible.
   __ LoadFromOffset(kWord, R0, R8, target_offset);
@@ -2580,7 +2704,7 @@
   __ LeaveStubFrame();
 
   // When using the interpreter, the function's code may now point to the
-  // InterpretCall stub. Make sure R0, R4, and R9 are preserved.
+  // InterpretCall stub. Make sure R0, R4 and R9 are preserved.
   __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
   __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
 }
@@ -2589,9 +2713,10 @@
 // R4: Arguments descriptor.
 // R0: Function.
 void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter")
-#else
+  if (FLAG_precompiled_mode) {
+    __ Stop("Not using interpreter");
+    return;
+  }
   __ EnterStubFrame();
 
 #if defined(DEBUG)
@@ -2657,7 +2782,6 @@
 
   __ LeaveStubFrame();
   __ Ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // R9: Contains an ICData.
@@ -3031,6 +3155,10 @@
 void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
   Label done, call_runtime;
 
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ ldr(CODE_REG,
+           Address(THR, target::Thread::slow_type_test_stub_offset()));
+  }
   __ EnterStubFrame();
 
   // If the subtype-cache is null, it needs to be lazily-created by the runtime.
@@ -3049,7 +3177,7 @@
   __ ldrb(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
                              target::Type::type_state_offset()));
   __ cmp(kTmp,
-         Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+         Operand(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is a function type.
@@ -3315,8 +3443,9 @@
 //  R0: receiver
 //  R9: MegamorphicCache (preserved)
 // Passed to target:
-//  CODE_REG: target Code
+//  R0: function
 //  R4: arguments descriptor
+//  CODE_REG: target Code
 void StubCodeCompiler::GenerateMegamorphicCallStub(Assembler* assembler) {
   __ LoadTaggedClassIdMayBeSmi(R0, R0);
   // R0: receiver cid as Smi.
@@ -3327,7 +3456,7 @@
 
   // Compute the table index.
   ASSERT(target::MegamorphicCache::kSpreadFactor == 7);
-  // Use reverse substract to multiply with 7 == 8 - 1.
+  // Use reverse subtract to multiply with 7 == 8 - 1.
   __ rsb(R3, R0, Operand(R0, LSL, 3));
   // R3: probe.
   Label loop;
@@ -3350,16 +3479,16 @@
   // be invoked as a normal Dart function.
   const auto target_address = FieldAddress(IP, base + target::kWordSize);
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(
-               R9, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ ldr(
+        ARGS_DESC_REG,
+        FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
     __ Branch(target_address);
   } else {
     __ ldr(R0, target_address);
     __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(
-               R9, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ ldr(
+        ARGS_DESC_REG,
+        FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
     __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
   }
 
@@ -3377,7 +3506,8 @@
 void StubCodeCompiler::GenerateICCallThroughCodeStub(Assembler* assembler) {
   Label loop, found, miss;
   __ ldr(R8, FieldAddress(R9, target::ICData::entries_offset()));
-  __ ldr(R4, FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+  __ ldr(R4,
+         FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
   __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
   // R8: first IC entry
   __ LoadTaggedClassIdMayBeSmi(R1, R0);
@@ -3437,7 +3567,7 @@
         R2, R3, R9,
         target::MonomorphicSmiableCall::expected_cid_offset() - kHeapObjectTag);
     __ cmp(R2, Operand(IP));
-    __ Branch(Address(THR, target::Thread::monomorphic_miss_entry_offset()),
+    __ Branch(Address(THR, target::Thread::switchable_call_miss_entry_offset()),
               NE);
     __ bx(R3);
   } else {
@@ -3446,35 +3576,56 @@
             target::MonomorphicSmiableCall::target_offset() - kHeapObjectTag);
     __ mov(CODE_REG, Operand(R2));
     __ cmp(R3, Operand(IP));
-    __ Branch(Address(THR, target::Thread::monomorphic_miss_entry_offset()),
+    __ Branch(Address(THR, target::Thread::switchable_call_miss_entry_offset()),
               NE);
     __ LoadField(IP, FieldAddress(R2, target::Code::entry_point_offset()));
     __ bx(IP);
   }
 }
 
-// Called from switchable IC calls.
-//  R0: receiver
-//  R9: UnlinkedCall
-void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
+static void CallSwitchableCallMissRuntimeEntry(Assembler* assembler,
+                                               Register receiver_reg) {
   __ LoadImmediate(IP, 0);
   __ Push(IP);  // Result slot
   __ Push(IP);  // Arg0: stub out
-  __ Push(R0);  // Arg1: Receiver
-  __ Push(R9);  // Arg2: UnlinkedCall
-  __ CallRuntime(kUnlinkedCallRuntimeEntry, 3);
-  __ Drop(2);
+  __ Push(receiver_reg);  // Arg1: Receiver
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
+  __ Pop(R0);        // Get the receiver
   __ Pop(CODE_REG);  // result = stub
   __ Pop(R9);        // result = IC
+}
 
-  __ Pop(R0);  // Restore receiver.
+// Called from switchable IC calls.
+//  R0: receiver
+void StubCodeCompiler::GenerateSwitchableCallMissStub(Assembler* assembler) {
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::switchable_call_miss_stub_offset()));
+  __ EnterStubFrame();
+  CallSwitchableCallMissRuntimeEntry(assembler, /*receiver_reg=*/R0);
   __ LeaveStubFrame();
 
   __ Branch(FieldAddress(
-      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kMonomorphic)));
+      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kNormal)));
+}
+
+// Called from megamorphic call sites and from megamorphic miss handlers.
+//  R9: ICData/MegamorphicCache
+void StubCodeCompiler::GenerateMegamorphicCallMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  // Load argument descriptor from ICData/MegamorphicCache.
+  __ ldr(R4,
+         FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
+
+  // Load the receiver.
+  __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::size_offset()));
+  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
+  __ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
+                             target::kWordSize));
+  CallSwitchableCallMissRuntimeEntry(assembler, /*receiver_reg=*/R8);
+  __ LeaveStubFrame();
+
+  __ Branch(FieldAddress(
+      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kNormal)));
 }
 
 // Called from switchable IC calls.
@@ -3501,42 +3652,7 @@
 
   __ Bind(&miss);
   __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Result slot
-  __ Push(IP);  // Arg0: stub out
-  __ Push(R0);  // Arg1: Receiver
-  __ CallRuntime(kSingleTargetMissRuntimeEntry, 2);
-  __ Drop(1);
-  __ Pop(CODE_REG);  // result = stub
-  __ Pop(R9);        // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ Branch(FieldAddress(
-      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kMonomorphic)));
-}
-
-// Called from the monomorphic checked entry.
-//  R0: receiver
-void StubCodeCompiler::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ ldr(CODE_REG,
-         Address(THR, target::Thread::monomorphic_miss_stub_offset()));
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Result slot
-  __ Push(IP);  // Arg0: stub out
-  __ Push(R0);  // Arg1: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 2);
-  __ Drop(1);
-  __ Pop(CODE_REG);  // result = stub
-  __ Pop(R9);        // result = IC
-
-  __ Pop(R0);  // Restore receiver.
+  CallSwitchableCallMissRuntimeEntry(assembler, /*receiver_reg=*/R0);
   __ LeaveStubFrame();
 
   __ Branch(FieldAddress(
@@ -3661,4 +3777,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index a477f9e..5ff469e 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -11,10 +11,11 @@
 
 #include "vm/compiler/stub_code_compiler.h"
 
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_ARM64)
 
 #include "vm/class_id.h"
 #include "vm/code_entry_kind.h"
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/constants.h"
@@ -175,12 +176,14 @@
   __ ret();
 }
 
-void GenerateSharedStub(Assembler* assembler,
-                        bool save_fpu_registers,
-                        const RuntimeEntry* target,
-                        intptr_t self_code_stub_offset_from_thread,
-                        bool allow_return,
-                        bool store_runtime_result_in_r0 = false) {
+void GenerateSharedStub(
+    Assembler* assembler,
+    bool save_fpu_registers,
+    const RuntimeEntry* target,
+    intptr_t self_code_stub_offset_from_thread,
+    bool allow_return,
+    bool store_runtime_result_in_r0 = false,
+    std::initializer_list<Register> runtime_call_arguments = {}) {
   // We want the saved registers to appear like part of the caller's frame, so
   // we push them before calling EnterStubFrame.
   RegisterSet all_registers;
@@ -199,15 +202,19 @@
     // Push an even value so it will not be seen as a pointer
     __ Push(LR);
   }
-  __ CallRuntime(*target, /*argument_count=*/0);
-
-  if (store_runtime_result_in_r0) {
-    __ Pop(R0);
+  for (Register argument_reg : runtime_call_arguments) {
+    __ PushRegister(argument_reg);
   }
+  __ CallRuntime(*target, /*argument_count=*/runtime_call_arguments.size());
   if (!allow_return) {
     __ Breakpoint();
     return;
   }
+
+  __ Drop(runtime_call_arguments.size());
+  if (store_runtime_result_in_r0) {
+    __ Pop(R0);
+  }
   __ LeaveStubFrame();
   if (store_runtime_result_in_r0) {
     // Stores the runtime result in stack where R0 was pushed ( R0 is the very
@@ -533,7 +540,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kNullErrorRuntimeEntry,
       target::Thread::null_error_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
@@ -541,7 +548,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kNullErrorRuntimeEntry,
       target::Thread::null_error_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullArgErrorSharedWithoutFPURegsStub(
@@ -549,7 +556,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kArgumentNullErrorRuntimeEntry,
       target::Thread::null_arg_error_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullArgErrorSharedWithFPURegsStub(
@@ -557,7 +564,27 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kArgumentNullErrorRuntimeEntry,
       target::Thread::null_arg_error_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kRangeErrorRuntimeEntry,
+      target::Thread::range_error_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/false,
+      /*store_runtime_result_in_r0=*/false,
+      {RangeErrorABI::kLengthReg, RangeErrorABI::kIndexReg});
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kRangeErrorRuntimeEntry,
+      target::Thread::range_error_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/false,
+      /*store_runtime_result_in_r0=*/false,
+      {RangeErrorABI::kLengthReg, RangeErrorABI::kIndexReg});
 }
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
@@ -565,7 +592,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
       target::Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
+      /*allow_return=*/true, {});
 }
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
@@ -573,7 +600,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kStackOverflowRuntimeEntry,
       target::Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
+      /*allow_return=*/true, {});
 }
 
 void StubCodeCompiler::GeneratePrintStopMessageStub(Assembler* assembler) {
@@ -1027,15 +1054,13 @@
   __ ret();
 }
 
-static void GenerateDispatcherCode(Assembler* assembler,
-                                   Label* call_target_function) {
-  __ Comment("NoSuchMethodDispatch");
-  // When lazily generated invocation dispatchers are disabled, the
-  // miss-handler may return null.
-  __ CompareObject(R0, NullObject());
-  __ b(call_target_function, NE);
+// R5: ICData/MegamorphicCache
+static void GenerateNoSuchMethodDispatcherBody(Assembler* assembler) {
   __ EnterStubFrame();
 
+  __ ldr(R4,
+         FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
+
   // Load the receiver.
   __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::size_offset());
   __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
@@ -1063,49 +1088,23 @@
   __ ret();
 }
 
-void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ EnterStubFrame();
+static void GenerateDispatcherCode(Assembler* assembler,
+                                   Label* call_target_function) {
+  __ Comment("NoSuchMethodDispatch");
+  // When lazily generated invocation dispatchers are disabled, the
+  // miss-handler may return null.
+  __ CompareObject(R0, NullObject());
+  __ b(call_target_function, NE);
 
-  // Load the receiver.
-  __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::size_offset());
-  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
-  __ LoadFromOffset(R6, TMP,
-                    target::frame_layout.param_end_from_fp * target::kWordSize);
+  GenerateNoSuchMethodDispatcherBody(assembler);
+}
 
-  // Preserve IC data and arguments descriptor.
-  __ Push(R5);
-  __ Push(R4);
-
-  // Push space for the return value.
-  // Push the receiver.
-  // Push IC data object.
-  // Push arguments descriptor array.
-  __ Push(ZR);
-  __ Push(R6);
-  __ Push(R5);
-  __ Push(R4);
-  __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
-  // Remove arguments.
-  __ Drop(3);
-  __ Pop(R0);  // Get result into R0 (target function).
-
-  // Restore IC data and arguments descriptor.
-  __ Pop(R4);
-  __ Pop(R5);
-
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-
-  if (!FLAG_lazy_dispatchers) {
-    Label call_target_function;
-    GenerateDispatcherCode(assembler, &call_target_function);
-    __ Bind(&call_target_function);
-  }
-
-  // Tail-call to target function.
-  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
-  __ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset());
-  __ br(R2);
+// Input:
+//   R4 - arguments descriptor
+//   R5 - icdata/megamorphic_cache
+void StubCodeCompiler::GenerateNoSuchMethodDispatcherStub(
+    Assembler* assembler) {
+  GenerateNoSuchMethodDispatcherBody(assembler);
 }
 
 // Called for inline allocation of arrays.
@@ -1192,9 +1191,9 @@
     // R2: array length as Smi.
     // R3: array size.
     // R7: new object end address.
-    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+    const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
                            target::ObjectAlignment::kObjectAlignmentLog2;
-    __ CompareImmediate(R3, target::RawObject::kSizeTagMaxSizeTag);
+    __ CompareImmediate(R3, target::ObjectLayout::kSizeTagMaxSizeTag);
     // If no size tag overflow, shift R1 left, else set R1 to zero.
     __ LslImmediate(TMP, R3, shift);
     __ csel(R1, TMP, R1, LS);
@@ -1257,7 +1256,7 @@
   __ ret();
 }
 
-void StubCodeCompiler::GenerateAllocateMintWithFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
   if (!FLAG_use_slow_path) {
@@ -1272,10 +1271,10 @@
                      &kAllocateMintRuntimeEntry,
                      target::Thread::allocate_mint_with_fpu_regs_stub_offset(),
                      /*allow_return=*/true,
-                     /*store_runtime_result_in_r0=*/true);
+                     /*store_runtime_result_in_r0=*/true, {});
 }
 
-void StubCodeCompiler::GenerateAllocateMintWithoutFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
   if (!FLAG_use_slow_path) {
@@ -1290,7 +1289,7 @@
       assembler, /*save_fpu_registers=*/false, &kAllocateMintRuntimeEntry,
       target::Thread::allocate_mint_without_fpu_regs_stub_offset(),
       /*allow_return=*/true,
-      /*store_runtime_result_in_r0=*/true);
+      /*store_runtime_result_in_r0=*/true, {});
 }
 
 // Called when invoking Dart code from C++ (VM code).
@@ -1447,9 +1446,11 @@
 //   R3 : current thread.
 void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
     Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
+  if (FLAG_precompiled_mode) {
+    __ Stop("Not using interpreter");
+    return;
+  }
+
   // Copy the C stack pointer (CSP/R31) into the stack pointer we'll actually
   // use to access the stack (SP/R15) and set the C stack pointer to near the
   // stack limit, loaded from the Thread held in R3, to prevent signal handlers
@@ -1577,7 +1578,6 @@
   __ Drop(1);
   __ RestoreCSP();
   __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // Helper to generate space allocation of context stub.
@@ -1628,9 +1628,9 @@
   // R0: new object.
   // R1: number of context variables.
   // R2: object size.
-  const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+  const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
                          target::ObjectAlignment::kObjectAlignmentLog2;
-  __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+  __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
   // If no size tag overflow, shift R2 left, else set R2 to zero.
   __ LslImmediate(TMP, R2, shift);
   __ csel(R2, TMP, R2, LS);
@@ -1830,12 +1830,12 @@
 
   if (cards) {
     __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
-    __ tbnz(&remember_card, TMP, target::RawObject::kCardRememberedBit);
+    __ tbnz(&remember_card, TMP, target::ObjectLayout::kCardRememberedBit);
   } else {
 #if defined(DEBUG)
     Label ok;
     __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
-    __ tbz(&ok, TMP, target::RawObject::kCardRememberedBit);
+    __ tbz(&ok, TMP, target::ObjectLayout::kCardRememberedBit);
     __ Stop("Wrong barrier");
     __ Bind(&ok);
 #endif
@@ -1855,7 +1855,8 @@
   Label retry;
   __ Bind(&retry);
   __ ldxr(R2, R3, kWord);
-  __ AndImmediate(R2, R2, ~(1 << target::RawObject::kOldAndNotRememberedBit));
+  __ AndImmediate(R2, R2,
+                  ~(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   __ stxr(R4, R2, R3, kWord);
   __ cbnz(&retry, R4);
 
@@ -1910,8 +1911,8 @@
   // R3: Untagged address of header word (ldxr/stxr do not support offsets).
   __ Bind(&marking_retry);
   __ ldxr(R2, R3, kWord);
-  __ tbz(&lost_race, R2, target::RawObject::kOldAndNotMarkedBit);
-  __ AndImmediate(R2, R2, ~(1 << target::RawObject::kOldAndNotMarkedBit));
+  __ tbz(&lost_race, R2, target::ObjectLayout::kOldAndNotMarkedBit);
+  __ AndImmediate(R2, R2, ~(1 << target::ObjectLayout::kOldAndNotMarkedBit));
   __ stxr(R4, R2, R3, kWord);
   __ cbnz(&marking_retry, R4);
 
@@ -1996,98 +1997,220 @@
       Address(THR, target::Thread::array_write_barrier_code_offset()), true);
 }
 
+static void GenerateAllocateObjectHelper(Assembler* assembler,
+                                         bool is_cls_parameterized) {
+  const Register kInstanceReg = R0;
+  // kAllocationStubTypeArgumentsReg = R1
+  const Register kTagsReg = R2;
+
+  {
+    Label slow_case;
+
+    const Register kNewTopReg = R3;
+
+    // Bump allocation.
+    {
+      const Register kInstanceSizeReg = R4;
+      const Register kEndReg = R5;
+
+      __ ExtractInstanceSizeFromTags(kInstanceSizeReg, kTagsReg);
+
+      // Load two words from Thread::top: top and end.
+      // kInstanceReg: potential next object start.
+      __ ldp(kInstanceReg, kEndReg,
+             Address(THR, target::Thread::top_offset(), Address::PairOffset));
+
+      __ add(kNewTopReg, kInstanceReg, Operand(kInstanceSizeReg));
+
+      __ CompareRegisters(kEndReg, kNewTopReg);
+      __ b(&slow_case, UNSIGNED_LESS_EQUAL);
+
+      // Successfully allocated the object, now update top to point to
+      // next object start and store the class in the class field of object.
+      __ str(kNewTopReg, Address(THR, target::Thread::top_offset()));
+    }  // kInstanceSizeReg = R4, kEndReg = R5
+
+    // Tags.
+    __ str(kTagsReg, Address(kInstanceReg, target::Object::tags_offset()));
+
+    // Initialize the remaining words of the object.
+    {
+      const Register kFieldReg = R4;
+
+      __ AddImmediate(kFieldReg, kInstanceReg,
+                      target::Instance::first_field_offset());
+      Label done, init_loop;
+      __ Bind(&init_loop);
+      __ CompareRegisters(kFieldReg, kNewTopReg);
+      __ b(&done, UNSIGNED_GREATER_EQUAL);
+      __ str(NULL_REG,
+             Address(kFieldReg, target::kWordSize, Address::PostIndex));
+      __ b(&init_loop);
+
+      __ Bind(&done);
+    }  // kFieldReg = R4
+
+    if (is_cls_parameterized) {
+      Label not_parameterized_case;
+
+      const Register kClsIdReg = R4;
+      const Register kTypeOffestReg = R5;
+
+      __ ExtractClassIdFromTags(kClsIdReg, kTagsReg);
+
+      // Load class' type_arguments_field offset in words.
+      __ LoadClassById(kTypeOffestReg, kClsIdReg);
+      __ ldr(
+          kTypeOffestReg,
+          FieldAddress(kTypeOffestReg,
+                       target::Class::
+                           host_type_arguments_field_offset_in_words_offset()),
+          kWord);
+
+      // Set the type arguments in the new object.
+      __ StoreIntoObjectNoBarrier(
+          kInstanceReg,
+          Address(kInstanceReg, kTypeOffestReg, UXTX, Address::Scaled),
+          kAllocationStubTypeArgumentsReg);
+
+      __ Bind(&not_parameterized_case);
+    }  // kClsIdReg = R4, kTypeOffestReg = R5
+
+    __ AddImmediate(kInstanceReg, kInstanceReg, kHeapObjectTag);
+
+    __ ret();
+
+    __ Bind(&slow_case);
+  }  // kNewTopReg = R3
+
+  // Fall back on slow case:
+  if (!is_cls_parameterized) {
+    __ mov(kAllocationStubTypeArgumentsReg, NULL_REG);
+  }
+  // Tail call to generic allocation stub.
+  __ ldr(
+      R3,
+      Address(THR, target::Thread::allocate_object_slow_entry_point_offset()));
+  __ br(R3);
+}
+
+// Called for inline allocation of objects (any class).
+void StubCodeCompiler::GenerateAllocateObjectStub(Assembler* assembler) {
+  GenerateAllocateObjectHelper(assembler, /*is_cls_parameterized=*/false);
+}
+
+void StubCodeCompiler::GenerateAllocateObjectParameterizedStub(
+    Assembler* assembler) {
+  GenerateAllocateObjectHelper(assembler, /*is_cls_parameterized=*/true);
+}
+
+void StubCodeCompiler::GenerateAllocateObjectSlowStub(Assembler* assembler) {
+  const Register kInstanceReg = R0;
+  // kAllocationStubTypeArgumentsReg = R1
+  const Register kTagsToClsIdReg = R2;
+
+  if (!FLAG_use_bare_instructions) {
+    __ ldr(CODE_REG,
+           Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  }
+
+  __ ExtractClassIdFromTags(kTagsToClsIdReg, kTagsToClsIdReg);
+
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+
+  __ LoadClassById(R0, kTagsToClsIdReg);
+  __ PushPair(R0, NULL_REG);  // Pushes result slot, then class object.
+
+  // Should be Object::null() if class is non-parameterized.
+  __ Push(kAllocationStubTypeArgumentsReg);
+
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);
+
+  // Load result off the stack into result register.
+  __ ldr(kInstanceReg, Address(SP, 2 * target::kWordSize));
+
+  // Write-barrier elimination is enabled for [cls] and we therefore need to
+  // ensure that the object is in new-space or has remembered bit set.
+  EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+
+  __ LeaveStubFrame();
+
+  __ ret();
+}
+
 // Called for inline allocation of objects.
-// Input parameters:
-//   LR : return address.
-//   kAllocationStubTypeArgumentsReg (R1): type arguments object
-//                                         (only if class is parameterized).
-void StubCodeCompiler::GenerateAllocationStubForClass(Assembler* assembler,
-                                                      const Class& cls) {
+void StubCodeCompiler::GenerateAllocationStubForClass(
+    Assembler* assembler,
+    UnresolvedPcRelativeCalls* unresolved_calls,
+    const Class& cls,
+    const Code& allocate_object,
+    const Code& allocat_object_parametrized) {
+  static_assert(kAllocationStubTypeArgumentsReg == R1,
+                "Adjust register allocation in the AllocationStub");
+
+  classid_t cls_id = target::Class::GetId(cls);
+  ASSERT(cls_id != kIllegalCid);
+
+  RELEASE_ASSERT(AllocateObjectInstr::WillAllocateNewOrRemembered(cls));
+
   // The generated code is different if the class is parameterized.
   const bool is_cls_parameterized = target::Class::NumTypeArguments(cls) > 0;
   ASSERT(!is_cls_parameterized || target::Class::TypeArgumentsFieldOffset(
                                       cls) != target::Class::kNoTypeArguments);
 
-  const Register kTypeArgumentsReg = kAllocationStubTypeArgumentsReg;
-  const Register kInstanceReg = R0;
-  const Register kNullReg = R3;
-  const Register kTempReg = R4;
-  const Register kTopReg = R5;
-  static_assert(kAllocationStubTypeArgumentsReg == R1,
-                "Adjust register allocation in the AllocationStub");
-
-  // kInlineInstanceSize is a constant used as a threshold for determining
-  // when the object initialization should be done as a loop or as
-  // straight line code.
-  const int kInlineInstanceSize = 12;
   const intptr_t instance_size = target::Class::GetInstanceSize(cls);
   ASSERT(instance_size > 0);
+  RELEASE_ASSERT(target::Heap::IsAllocatableInNewSpace(instance_size));
 
-  __ LoadObject(kNullReg, NullObject());
-  if (FLAG_inline_alloc &&
-      target::Heap::IsAllocatableInNewSpace(instance_size) &&
-      !target::Class::TraceAllocation(cls)) {
-    Label slow_case;
-    // Allocate the object & initialize header word.
-    __ TryAllocate(cls, &slow_case, kInstanceReg, kTopReg,
-                   /*tag_result=*/false);
+  const uint32_t tags =
+      target::MakeTagWordForNewSpaceObject(cls_id, instance_size);
 
-    // Initialize the remaining words of the object.
-    if (instance_size < (kInlineInstanceSize * target::kWordSize)) {
-      intptr_t current_offset = target::Instance::first_field_offset();
-      while ((current_offset + target::kWordSize) < instance_size) {
-        __ stp(kNullReg, kNullReg,
-               Address(kInstanceReg, current_offset, Address::PairOffset));
-        current_offset += 2 * target::kWordSize;
-      }
-      while (current_offset < instance_size) {
-        __ str(kNullReg, Address(kInstanceReg, current_offset));
-        current_offset += target::kWordSize;
+  // Note: Keep in sync with helper function.
+  // kInstanceReg = R0
+  // kAllocationStubTypeArgumentsReg = R1
+  const Register kTagsReg = R2;
+
+  __ LoadImmediate(kTagsReg, tags);
+
+  if (!FLAG_use_slow_path && FLAG_inline_alloc &&
+      !target::Class::TraceAllocation(cls) &&
+      target::SizeFitsInSizeTag(instance_size)) {
+    if (is_cls_parameterized) {
+      if (!IsSameObject(NullObject(),
+                        CastHandle<Object>(allocat_object_parametrized))) {
+        __ GenerateUnRelocatedPcRelativeTailCall();
+        unresolved_calls->Add(new UnresolvedPcRelativeCall(
+            __ CodeSize(), allocat_object_parametrized, /*is_tail_call=*/true));
+      } else {
+        __ ldr(R4,
+               Address(THR,
+                       target::Thread::
+                           allocate_object_parameterized_entry_point_offset()));
+        __ br(R4);
       }
     } else {
-      __ AddImmediate(kTempReg, kInstanceReg,
-                      target::Instance::first_field_offset());
-      Label done, init_loop;
-      __ Bind(&init_loop);
-      __ CompareRegisters(kTempReg, kTopReg);
-      __ b(&done, CS);
-      __ str(kNullReg,
-             Address(kTempReg, target::kWordSize, Address::PostIndex));
-      __ b(&init_loop);
-
-      __ Bind(&done);
+      if (!IsSameObject(NullObject(), CastHandle<Object>(allocate_object))) {
+        __ GenerateUnRelocatedPcRelativeTailCall();
+        unresolved_calls->Add(new UnresolvedPcRelativeCall(
+            __ CodeSize(), allocate_object, /*is_tail_call=*/true));
+      } else {
+        __ ldr(
+            R4,
+            Address(THR, target::Thread::allocate_object_entry_point_offset()));
+        __ br(R4);
+      }
     }
-    if (is_cls_parameterized) {
-      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
-      __ StoreToOffset(kTypeArgumentsReg, kInstanceReg, offset);
+  } else {
+    if (!is_cls_parameterized) {
+      __ LoadObject(kAllocationStubTypeArgumentsReg, NullObject());
     }
-    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
-    __ ret();
-
-    __ Bind(&slow_case);
+    __ ldr(R4,
+           Address(THR,
+                   target::Thread::allocate_object_slow_entry_point_offset()));
+    __ br(R4);
   }
-
-  // If is_cls_parameterized:
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();  // Uses pool pointer to pass cls to runtime.
-  __ LoadObject(R0, CastHandle<Object>(cls));
-  __ PushPair(R0, kNullReg);  // Pushes cls, result slot.
-  __ Push(is_cls_parameterized ? kTypeArgumentsReg : kNullReg);
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ ldr(
-      kInstanceReg,
-      Address(SP,
-              2 * target::kWordSize));  // Pop result (newly allocated object).
-
-  ASSERT(kInstanceReg == R0);
-  if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
-    // Write-barrier elimination is enabled for [cls] and we therefore need to
-    // ensure that the object is in new-space or has remembered bit set.
-    EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
-  }
-  __ LeaveStubFrame();  // Restores correct SP.
-  __ ret();
 }
 
 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
@@ -2336,7 +2459,7 @@
   if (type == kInstanceCall) {
     __ LoadTaggedClassIdMayBeSmi(R0, R0);
     __ LoadFieldFromOffset(R4, R5,
-                           target::ICData::arguments_descriptor_offset());
+                           target::CallSiteData::arguments_descriptor_offset());
     if (num_args == 2) {
       __ LoadFieldFromOffset(R7, R4,
                              target::ArgumentsDescriptor::count_offset());
@@ -2348,7 +2471,7 @@
     }
   } else {
     __ LoadFieldFromOffset(R4, R5,
-                           target::ICData::arguments_descriptor_offset());
+                           target::CallSiteData::arguments_descriptor_offset());
     // Get the receiver's class ID (first read number of arguments from
     // arguments descriptor array and then access the receiver from the stack).
     __ LoadFieldFromOffset(R7, R4, target::ArgumentsDescriptor::count_offset());
@@ -2650,7 +2773,8 @@
   }
 
   // Load arguments descriptor into R4.
-  __ LoadFieldFromOffset(R4, R5, target::ICData::arguments_descriptor_offset());
+  __ LoadFieldFromOffset(R4, R5,
+                         target::CallSiteData::arguments_descriptor_offset());
 
   // Get function and call it, if possible.
   __ LoadFromOffset(R0, R6, target_offset);
@@ -2719,9 +2843,11 @@
 // R4: Arguments descriptor.
 // R0: Function.
 void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter")
-#else
+  if (FLAG_precompiled_mode) {
+    __ Stop("Not using interpreter");
+    return;
+  }
+
   __ SetPrologueOffset();
   __ EnterStubFrame();
 
@@ -2797,7 +2923,6 @@
 
   __ LeaveStubFrame();
   __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // R5: Contains an ICData.
@@ -3154,6 +3279,10 @@
 void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
   Label done, call_runtime;
 
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ ldr(CODE_REG,
+           Address(THR, target::Thread::slow_type_test_stub_offset()));
+  }
   __ EnterStubFrame();
 
   // If the subtype-cache is null, it needs to be lazily-created by the runtime.
@@ -3174,7 +3303,7 @@
       FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
       kByte);
   __ cmp(kTmp,
-         Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+         Operand(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is a function type.
@@ -3414,12 +3543,14 @@
   __ ret();
 }
 
-// Called from megamorphic calls.
-//  R0: receiver
+// Called from megamorphic call sites.
+//  R0: receiver (passed to target)
 //  R5: MegamorphicCache (preserved)
 // Passed to target:
+//  R0: receiver
 //  CODE_REG: target Code
 //  R4: arguments descriptor
+//  R5: MegamorphicCache
 void StubCodeCompiler::GenerateMegamorphicCallStub(Assembler* assembler) {
   // Jump if receiver is a smi.
   Label smi_case;
@@ -3466,15 +3597,15 @@
   const auto target_address = FieldAddress(TMP, base + target::kWordSize);
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     __ ldr(R1, target_address);
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(
-               R5, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ ldr(
+        ARGS_DESC_REG,
+        FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
   } else {
     __ ldr(R0, target_address);
     __ ldr(R1, FieldAddress(R0, target::Function::entry_point_offset()));
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(
-               R5, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ ldr(
+        ARGS_DESC_REG,
+        FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
     __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
   }
   __ br(R1);
@@ -3495,10 +3626,14 @@
   __ b(&cid_loaded);
 }
 
+// Input:
+//   R0 - receiver
+//   R5 - icdata
 void StubCodeCompiler::GenerateICCallThroughCodeStub(Assembler* assembler) {
   Label loop, found, miss;
   __ ldr(R8, FieldAddress(R5, target::ICData::entries_offset()));
-  __ ldr(R4, FieldAddress(R5, target::ICData::arguments_descriptor_offset()));
+  __ ldr(R4,
+         FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
   __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
   // R8: first IC entry
   __ LoadTaggedClassIdMayBeSmi(R1, R0);
@@ -3573,23 +3708,24 @@
   }
 
   __ Bind(&miss);
-  __ ldr(IP0, Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  __ ldr(IP0,
+         Address(THR, target::Thread::switchable_call_miss_entry_offset()));
   __ br(IP0);
 }
 
 // Called from switchable IC calls.
 //  R0: receiver
-//  R5: SingleTargetCache
-void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
+void StubCodeCompiler::GenerateSwitchableCallMissStub(Assembler* assembler) {
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::switchable_call_miss_stub_offset()));
   __ EnterStubFrame();
   __ Push(R0);  // Preserve receiver.
 
   __ Push(ZR);  // Result slot.
   __ Push(ZR);  // Arg0: stub out.
   __ Push(R0);  // Arg1: Receiver
-  __ Push(R5);  // Arg2: UnlinkedCall
-  __ CallRuntime(kUnlinkedCallRuntimeEntry, 3);
-  __ Drop(2);
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
+  __ Drop(1);
   __ Pop(CODE_REG);  // result = stub
   __ Pop(R5);        // result = IC
 
@@ -3597,7 +3733,39 @@
   __ LeaveStubFrame();
 
   __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
-                                        CodeEntryKind::kMonomorphic)));
+                                        CodeEntryKind::kNormal)));
+  __ br(R1);
+}
+
+// Called from megamorphic call sites and from megamorphic miss handlers.
+//  R5: ICData/MegamorphicCache
+void StubCodeCompiler::GenerateMegamorphicCallMissStub(Assembler* assembler) {
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::switchable_call_miss_stub_offset()));
+  __ EnterStubFrame();
+  __ ldr(R4,
+         FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
+
+  // Load the receiver.
+  __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::size_offset());
+  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
+  __ LoadFromOffset(R6, TMP,
+                    target::frame_layout.param_end_from_fp * target::kWordSize);
+  __ Push(R6);  // Preserver receiver
+
+  __ Push(ZR);  // Result slot.
+  __ Push(ZR);  // Arg0: stub out.
+  __ Push(R6);  // Arg1: Receiver
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
+  __ Drop(1);
+  __ Pop(CODE_REG);  // result = stub
+  __ Pop(R5);        // result = IC
+
+  __ Pop(R0);  // Restore receiver into R0
+  __ LeaveStubFrame();
+
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                        CodeEntryKind::kNormal)));
   __ br(R1);
 }
 
@@ -3631,31 +3799,7 @@
   __ Push(ZR);  // Result slot.
   __ Push(ZR);  // Arg0: Stub out.
   __ Push(R0);  // Arg1: Receiver
-  __ CallRuntime(kSingleTargetMissRuntimeEntry, 2);
-  __ Drop(1);
-  __ Pop(CODE_REG);  // result = stub
-  __ Pop(R5);        // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
-                                        CodeEntryKind::kMonomorphic)));
-  __ br(R1);
-}
-
-// Called from the monomorphic checked entry.
-//  R0: receiver
-void StubCodeCompiler::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ ldr(CODE_REG,
-         Address(THR, target::Thread::monomorphic_miss_stub_offset()));
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ Push(ZR);  // Result slot.
-  __ Push(ZR);  // Arg0: stub out
-  __ Push(R0);  // Arg1: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 2);
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
   __ Drop(1);
   __ Pop(CODE_REG);  // result = stub
   __ Pop(R5);        // result = IC
@@ -3772,4 +3916,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 328a17a..73db068 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -11,10 +11,11 @@
 
 #include "vm/compiler/stub_code_compiler.h"
 
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_IA32)
 
 #include "vm/class_id.h"
 #include "vm/code_entry_kind.h"
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/constants.h"
@@ -313,6 +314,15 @@
     Assembler* assembler) {
   __ Breakpoint();
 }
+void StubCodeCompiler::GenerateRangeErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  __ Breakpoint();
+}
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
     Assembler* assembler) {
@@ -701,15 +711,11 @@
   __ ret();
 }
 
-static void GenerateDispatcherCode(Assembler* assembler,
-                                   Label* call_target_function) {
-  __ Comment("NoSuchMethodDispatch");
-  // When lazily generated invocation dispatchers are disabled, the
-  // miss-handler may return null.
-  const Immediate& raw_null = Immediate(target::ToRawPointer(NullObject()));
-  __ cmpl(EAX, raw_null);
-  __ j(NOT_EQUAL, call_target_function);
+static void GenerateNoSuchMethodDispatcherCode(Assembler* assembler) {
   __ EnterStubFrame();
+  __ movl(EDX, FieldAddress(
+                   ECX, target::CallSiteData::arguments_descriptor_offset()));
+
   // Load the receiver.
   __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::size_offset()));
   __ movl(EAX,
@@ -740,39 +746,20 @@
   __ ret();
 }
 
-void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  // Load the receiver into EAX.  The argument count in the arguments
-  // descriptor in EDX is a smi.
-  __ movl(EAX, FieldAddress(EDX, target::ArgumentsDescriptor::size_offset()));
-  // Two words (saved fp, stub's pc marker) in the stack above the return
-  // address.
-  __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * target::kWordSize));
-  // Preserve IC data and arguments descriptor.
-  __ pushl(ECX);
-  __ pushl(EDX);
+static void GenerateDispatcherCode(Assembler* assembler,
+                                   Label* call_target_function) {
+  __ Comment("NoSuchMethodDispatch");
+  // When lazily generated invocation dispatchers are disabled, the
+  // miss-handler may return null.
+  const Immediate& raw_null = Immediate(target::ToRawPointer(NullObject()));
+  __ cmpl(EAX, raw_null);
+  __ j(NOT_EQUAL, call_target_function);
+  GenerateNoSuchMethodDispatcherCode(assembler);
+}
 
-  __ pushl(Immediate(0));  // Space for the result of the runtime call.
-  __ pushl(EAX);           // Pass receiver.
-  __ pushl(ECX);           // Pass IC data.
-  __ pushl(EDX);           // Pass arguments descriptor.
-  __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
-  // Discard arguments.
-  __ popl(EAX);
-  __ popl(EAX);
-  __ popl(EAX);
-  __ popl(EAX);  // Return value from the runtime call (function).
-  __ popl(EDX);  // Restore arguments descriptor.
-  __ popl(ECX);  // Restore IC data.
-  __ LeaveFrame();
-
-  if (!FLAG_lazy_dispatchers) {
-    Label call_target_function;
-    GenerateDispatcherCode(assembler, &call_target_function);
-    __ Bind(&call_target_function);
-  }
-
-  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
+void StubCodeCompiler::GenerateNoSuchMethodDispatcherStub(
+    Assembler* assembler) {
+  GenerateNoSuchMethodDispatcherCode(assembler);
 }
 
 // Called for inline allocation of arrays.
@@ -844,9 +831,9 @@
     {
       Label size_tag_overflow, done;
       __ movl(EDI, EBX);
-      __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+      __ cmpl(EDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
       __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-      __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+      __ shll(EDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
                              target::ObjectAlignment::kObjectAlignmentLog2));
       __ jmp(&done, Assembler::kNearJump);
 
@@ -1222,9 +1209,9 @@
       Label size_tag_overflow, done;
       __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
       __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
-      __ cmpl(EBX, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+      __ cmpl(EBX, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
       __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-      __ shll(EBX, Immediate(target::RawObject::kTagBitsSizeTagPos -
+      __ shll(EBX, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
                              target::ObjectAlignment::kObjectAlignmentLog2));
       __ jmp(&done);
 
@@ -1414,7 +1401,7 @@
   // Spilled: EAX, ECX
   // EDX: Address being stored
   __ movl(EAX, FieldAddress(EDX, target::Object::tags_offset()));
-  __ testl(EAX, Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+  __ testl(EAX, Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
   __ j(NOT_EQUAL, &add_to_buffer, Assembler::kNearJump);
   __ popl(ECX);
   __ popl(EAX);
@@ -1427,12 +1414,12 @@
 
   if (cards) {
     // Check if this object is using remembered cards.
-    __ testl(EAX, Immediate(1 << target::RawObject::kCardRememberedBit));
+    __ testl(EAX, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
     __ j(NOT_EQUAL, &remember_card, Assembler::kFarJump);  // Unlikely.
   } else {
 #if defined(DEBUG)
     Label ok;
-    __ testl(EAX, Immediate(1 << target::RawObject::kCardRememberedBit));
+    __ testl(EAX, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
     __ j(ZERO, &ok, Assembler::kFarJump);  // Unlikely.
     __ Stop("Wrong barrier");
     __ Bind(&ok);
@@ -1442,7 +1429,7 @@
   // lock+andl is an atomic read-modify-write.
   __ lock();
   __ andl(FieldAddress(EDX, target::Object::tags_offset()),
-          Immediate(~(1 << target::RawObject::kOldAndNotRememberedBit)));
+          Immediate(~(1 << target::ObjectLayout::kOldAndNotRememberedBit)));
 
   // Load the StoreBuffer block out of the thread. Then load top_ out of the
   // StoreBufferBlock and add the address to the pointers_.
@@ -1528,6 +1515,19 @@
       Address(THR, target::Thread::array_write_barrier_code_offset()), true);
 }
 
+void StubCodeCompiler::GenerateAllocateObjectStub(Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateAllocateObjectParameterizedStub(
+    Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateAllocateObjectSlowStub(Assembler* assembler) {
+  __ int3();
+}
+
 // Called for inline allocation of objects.
 // Input parameters:
 //   ESP : points to return address.
@@ -1536,8 +1536,12 @@
 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers.
 // Returns patch_code_pc offset where patching code for disabling the stub
 // has been generated (similar to regularly generated Dart code).
-void StubCodeCompiler::GenerateAllocationStubForClass(Assembler* assembler,
-                                                      const Class& cls) {
+void StubCodeCompiler::GenerateAllocationStubForClass(
+    Assembler* assembler,
+    UnresolvedPcRelativeCalls* unresolved_calls,
+    const Class& cls,
+    const Code& allocate_object,
+    const Code& allocat_object_parametrized) {
   const Immediate& raw_null = Immediate(target::ToRawPointer(NullObject()));
   // The generated code is different if the class is parameterized.
   const bool is_cls_parameterized = target::Class::NumTypeArguments(cls) > 0;
@@ -1889,8 +1893,8 @@
   __ Comment("Extract ICData initial values and receiver cid");
   // ECX: IC data object (preserved).
   // Load arguments descriptor into EDX.
-  __ movl(EDX,
-          FieldAddress(ECX, target::ICData::arguments_descriptor_offset()));
+  __ movl(EDX, FieldAddress(
+                   ECX, target::CallSiteData::arguments_descriptor_offset()));
   // Loop that checks if there is an IC data match.
   Label loop, found, miss;
   // ECX: IC data object (preserved).
@@ -2042,12 +2046,12 @@
   __ Stop("Unimplemented");
 }
 
-void StubCodeCompiler::GenerateAllocateMintWithFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   __ Stop("Unimplemented");
 }
 
-void StubCodeCompiler::GenerateAllocateMintWithoutFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   __ Stop("Unimplemented");
 }
@@ -2168,8 +2172,8 @@
   }
 
   // Load arguments descriptor into EDX.
-  __ movl(EDX,
-          FieldAddress(ECX, target::ICData::arguments_descriptor_offset()));
+  __ movl(EDX, FieldAddress(
+                   ECX, target::CallSiteData::arguments_descriptor_offset()));
 
   // Get function and call it, if possible.
   __ movl(EAX, Address(EBX, target_offset));
@@ -2792,7 +2796,7 @@
 }
 
 // Called from megamorphic calls.
-//  EBX: receiver
+//  EBX: receiver (passed to target)
 //  ECX: target::MegamorphicCache (preserved)
 // Passed to target:
 //  EBX: target entry point
@@ -2810,6 +2814,7 @@
 
   Label cid_loaded;
   __ Bind(&cid_loaded);
+  __ pushl(EBX);  // save receiver
   __ movl(EBX, FieldAddress(ECX, target::MegamorphicCache::mask_offset()));
   __ movl(EDI, FieldAddress(ECX, target::MegamorphicCache::buckets_offset()));
   // EDI: cache buckets array.
@@ -2841,9 +2846,9 @@
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, base + target::kWordSize));
-  __ movl(EDX,
-          FieldAddress(
-              ECX, target::MegamorphicCache::arguments_descriptor_offset()));
+  __ movl(EDX, FieldAddress(
+                   ECX, target::CallSiteData::arguments_descriptor_offset()));
+  __ popl(EBX);  // restore receiver
   __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 
   __ Bind(&probe_failed);
@@ -2871,22 +2876,18 @@
   __ int3();  // AOT only.
 }
 
-void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
-  __ int3();  // AOT only.
-}
-
-void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
-  __ int3();  // AOT only.
-}
-
-void StubCodeCompiler::GenerateMonomorphicMissStub(Assembler* assembler) {
+// Called from switchable IC calls.
+//  EBX: receiver
+void StubCodeCompiler::GenerateSwitchableCallMissStub(Assembler* assembler) {
+  __ movl(CODE_REG,
+          Address(THR, target::Thread::switchable_call_miss_stub_offset()));
   __ EnterStubFrame();
   __ pushl(EBX);  // Preserve receiver.
 
   __ pushl(Immediate(0));  // Result slot.
-  __ pushl(Immediate(0));  // Arg0: stub out
+  __ pushl(Immediate(0));  // Arg0: stub out.
   __ pushl(EBX);           // Arg1: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 2);
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
   __ popl(ECX);
   __ popl(CODE_REG);  // result = stub
   __ popl(ECX);       // result = IC
@@ -2895,10 +2896,23 @@
   __ LeaveFrame();
 
   __ movl(EAX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
-                                          CodeEntryKind::kMonomorphic)));
+                                          CodeEntryKind::kNormal)));
   __ jmp(EAX);
 }
 
+// Called from megamorphic call sites and from megamorphic miss handlers.
+//  EBX: receiver
+//  EDX: arguments descriptor(or zero if invoked from unlinked/monomorphic call)
+void StubCodeCompiler::GenerateMegamorphicCallMissStub(Assembler* assembler) {
+  // On ia32 there is no need to load receiver from the actual arguments using
+  // arg descriptor because (unlike on arm, arm64) receiver is always available.
+  GenerateSwitchableCallMissStub(assembler);
+}
+
+void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
+  __ int3();  // AOT only.
+}
+
 void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
     Assembler* assembler) {
   __ int3();  // Marker stub.
@@ -3015,4 +3029,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 8bcf076..0e7f495 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -13,10 +13,11 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/stub_code_compiler.h"
 
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(TARGET_ARCH_X64)
 
 #include "vm/class_id.h"
 #include "vm/code_entry_kind.h"
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/constants.h"
 #include "vm/instructions.h"
@@ -154,11 +155,13 @@
   __ ret();
 }
 
-void GenerateSharedStub(Assembler* assembler,
-                        bool save_fpu_registers,
-                        const RuntimeEntry* target,
-                        intptr_t self_code_stub_offset_from_thread,
-                        bool allow_return) {
+void GenerateSharedStub(
+    Assembler* assembler,
+    bool save_fpu_registers,
+    const RuntimeEntry* target,
+    intptr_t self_code_stub_offset_from_thread,
+    bool allow_return,
+    std::initializer_list<Register> runtime_call_arguments) {
   // We want the saved registers to appear like part of the caller's frame, so
   // we push them before calling EnterStubFrame.
   __ PushRegisters(kDartAvailableCpuRegs,
@@ -181,11 +184,15 @@
   __ movq(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
 
   __ EnterStubFrame();
-  __ CallRuntime(*target, /*argument_count=*/0);
+  for (Register argument_reg : runtime_call_arguments) {
+    __ PushRegister(argument_reg);
+  }
+  __ CallRuntime(*target, /*argument_count=*/runtime_call_arguments.size());
   if (!allow_return) {
     __ Breakpoint();
     return;
   }
+  __ Drop(runtime_call_arguments.size());
   __ LeaveStubFrame();
 
   // Drop "official" return address -- we can just use the one stored above the
@@ -467,7 +474,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kNullErrorRuntimeEntry,
       target::Thread::null_error_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
@@ -475,7 +482,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kNullErrorRuntimeEntry,
       target::Thread::null_error_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullArgErrorSharedWithoutFPURegsStub(
@@ -483,7 +490,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kArgumentNullErrorRuntimeEntry,
       target::Thread::null_arg_error_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
 }
 
 void StubCodeCompiler::GenerateNullArgErrorSharedWithFPURegsStub(
@@ -491,7 +498,25 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kArgumentNullErrorRuntimeEntry,
       target::Thread::null_arg_error_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/false);
+      /*allow_return=*/false, {});
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kRangeErrorRuntimeEntry,
+      target::Thread::range_error_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/false,
+      {RangeErrorABI::kLengthReg, RangeErrorABI::kIndexReg});
+}
+
+void StubCodeCompiler::GenerateRangeErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kRangeErrorRuntimeEntry,
+      target::Thread::range_error_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/false,
+      {RangeErrorABI::kLengthReg, RangeErrorABI::kIndexReg});
 }
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
@@ -499,7 +524,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
       target::Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
+      /*allow_return=*/true, {});
 }
 
 void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
@@ -507,7 +532,7 @@
   GenerateSharedStub(
       assembler, /*save_fpu_registers=*/true, &kStackOverflowRuntimeEntry,
       target::Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
+      /*allow_return=*/true, {});
 }
 
 // Input parameters:
@@ -946,21 +971,13 @@
   __ ret();
 }
 
-static void GenerateDispatcherCode(Assembler* assembler,
-                                   Label* call_target_function) {
-  __ Comment("NoSuchMethodDispatch");
-  // When lazily generated invocation dispatchers are disabled, the
-  // miss-handler may return null.
-  __ CompareObject(RAX, NullObject());
-  __ j(NOT_EQUAL, call_target_function);
-  __ EnterStubFrame();
-  // Load the receiver.
-  __ movq(RDI, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
-  __ movq(RAX,
-          Address(RBP, RDI, TIMES_HALF_WORD_SIZE,
-                  target::frame_layout.param_end_from_fp * target::kWordSize));
+// Input:
+//   RBX - icdata/megamorphic_cache
+//   RDI - arguments descriptor size
+static void GenerateNoSuchMethodDispatcherBody(Assembler* assembler,
+                                               Register receiver_reg) {
   __ pushq(Immediate(0));  // Setup space on stack for result.
-  __ pushq(RAX);           // Receiver.
+  __ pushq(receiver_reg);  // Receiver.
   __ pushq(RBX);           // ICData/MegamorphicCache.
   __ pushq(R10);           // Arguments descriptor array.
 
@@ -984,43 +1001,39 @@
   __ ret();
 }
 
-void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  // Load the receiver into RAX.  The argument count in the arguments
-  // descriptor in R10 is a smi.
-  __ movq(RAX, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
-  // Three words (saved pp, saved fp, stub's pc marker)
-  // in the stack above the return address.
-  __ movq(RAX,
-          Address(RSP, RAX, TIMES_4,
-                  target::frame_layout.saved_below_pc() * target::kWordSize));
-  // Preserve IC data and arguments descriptor.
-  __ pushq(RBX);
-  __ pushq(R10);
+// Input:
+//   RBX - icdata/megamorphic_cache
+//   R10 - argument descriptor
+static void GenerateDispatcherCode(Assembler* assembler,
+                                   Label* call_target_function) {
+  __ Comment("NoSuchMethodDispatch");
+  // When lazily generated invocation dispatchers are disabled, the
+  // miss-handler may return null.
+  __ CompareObject(RAX, NullObject());
+  __ j(NOT_EQUAL, call_target_function);
 
-  // Space for the result of the runtime call.
-  __ pushq(Immediate(0));
-  __ pushq(RDX);  // Receiver.
-  __ pushq(RBX);  // IC data.
-  __ pushq(R10);  // Arguments descriptor.
-  __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
-  // Discard arguments.
-  __ popq(RAX);
-  __ popq(RAX);
-  __ popq(RAX);
-  __ popq(RAX);  // Return value from the runtime call (function).
-  __ popq(R10);  // Restore arguments descriptor.
-  __ popq(RBX);  // Restore IC data.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  if (!FLAG_lazy_dispatchers) {
-    Label call_target_function;
-    GenerateDispatcherCode(assembler, &call_target_function);
-    __ Bind(&call_target_function);
-  }
-  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
-  __ jmp(RCX);
+  __ EnterStubFrame();
+  // Load the receiver.
+  __ movq(RDI, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
+  __ movq(RAX,
+          Address(RBP, RDI, TIMES_HALF_WORD_SIZE,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+
+  GenerateNoSuchMethodDispatcherBody(assembler, /*receiver_reg=*/RAX);
+}
+
+// Input:
+//   RBX - icdata/megamorphic_cache
+//   RDX - receiver
+void StubCodeCompiler::GenerateNoSuchMethodDispatcherStub(
+    Assembler* assembler) {
+  __ EnterStubFrame();
+
+  __ movq(R10, FieldAddress(
+                   RBX, target::CallSiteData::arguments_descriptor_offset()));
+  __ movq(RDI, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
+
+  GenerateNoSuchMethodDispatcherBody(assembler, /*receiver_reg=*/RDX);
 }
 
 // Called for inline allocation of arrays.
@@ -1086,9 +1099,9 @@
     // RDI: allocation size.
     {
       Label size_tag_overflow, done;
-      __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+      __ cmpq(RDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
       __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-      __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+      __ shlq(RDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
                              target::ObjectAlignment::kObjectAlignmentLog2));
       __ jmp(&done, Assembler::kNearJump);
 
@@ -1161,12 +1174,12 @@
   __ ret();
 }
 
-void StubCodeCompiler::GenerateAllocateMintWithFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   __ Stop("Unimplemented");
 }
 
-void StubCodeCompiler::GenerateAllocateMintWithoutFPURegsStub(
+void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   __ Stop("Unimplemented");
 }
@@ -1325,9 +1338,11 @@
 //   RCX : current thread.
 void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
     Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
+  if (FLAG_precompiled_mode) {
+    __ Stop("Not using interpreter");
+    return;
+  }
+
   __ pushq(Address(RSP, 0));  // Marker for the profiler.
   __ EnterFrame(0);
 
@@ -1471,7 +1486,6 @@
   __ popq(RCX);
 
   __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // Helper to generate space allocation of context stub.
@@ -1525,9 +1539,9 @@
     Label size_tag_overflow, done;
     __ leaq(R13, Address(R10, TIMES_8, fixed_size_plus_alignment_padding));
     __ andq(R13, Immediate(-target::ObjectAlignment::kObjectAlignment));
-    __ cmpq(R13, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ cmpq(R13, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
     __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shlq(R13, Immediate(target::RawObject::kTagBitsSizeTagPos -
+    __ shlq(R13, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
                            target::ObjectAlignment::kObjectAlignmentLog2));
     __ jmp(&done);
 
@@ -1726,13 +1740,13 @@
 
   if (cards) {
     __ movl(TMP, FieldAddress(RDX, target::Object::tags_offset()));
-    __ testl(TMP, Immediate(1 << target::RawObject::kCardRememberedBit));
+    __ testl(TMP, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
     __ j(NOT_ZERO, &remember_card, Assembler::kFarJump);
   } else {
 #if defined(DEBUG)
     Label ok;
     __ movl(TMP, FieldAddress(RDX, target::Object::tags_offset()));
-    __ testl(TMP, Immediate(1 << target::RawObject::kCardRememberedBit));
+    __ testl(TMP, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
     __ j(ZERO, &ok, Assembler::kFarJump);
     __ Stop("Wrong barrier");
     __ Bind(&ok);
@@ -1747,7 +1761,7 @@
   // lock+andl is an atomic read-modify-write.
   __ lock();
   __ andl(FieldAddress(RDX, target::Object::tags_offset()),
-          Immediate(~(1 << target::RawObject::kOldAndNotRememberedBit)));
+          Immediate(~(1 << target::ObjectLayout::kOldAndNotRememberedBit)));
 
   // Save registers being destroyed.
   __ pushq(RAX);
@@ -1799,9 +1813,9 @@
   __ movl(RAX, FieldAddress(TMP, target::Object::tags_offset()));
   __ Bind(&retry);
   __ movl(RCX, RAX);
-  __ testl(RCX, Immediate(1 << target::RawObject::kOldAndNotMarkedBit));
+  __ testl(RCX, Immediate(1 << target::ObjectLayout::kOldAndNotMarkedBit));
   __ j(ZERO, &lost_race);  // Marked by another thread.
-  __ andl(RCX, Immediate(~(1 << target::RawObject::kOldAndNotMarkedBit)));
+  __ andl(RCX, Immediate(~(1 << target::ObjectLayout::kOldAndNotMarkedBit)));
   __ LockCmpxchgl(FieldAddress(TMP, target::Object::tags_offset()), RCX);
   __ j(NOT_EQUAL, &retry, Assembler::kNearJump);
 
@@ -1880,138 +1894,226 @@
       Address(THR, target::Thread::array_write_barrier_code_offset()), true);
 }
 
-// Called for inline allocation of objects.
-// Input parameters:
-//   RSP : points to return address.
-//   kAllocationStubTypeArgumentsReg (RDX) : type arguments object
-//                                           (only if class is parameterized).
-void StubCodeCompiler::GenerateAllocationStubForClass(Assembler* assembler,
-                                                      const Class& cls) {
-  // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized = target::Class::NumTypeArguments(cls) > 0;
-  ASSERT(!is_cls_parameterized || target::Class::TypeArgumentsFieldOffset(
-                                      cls) != target::Class::kNoTypeArguments);
-  // kInlineInstanceSize is a constant used as a threshold for determining
-  // when the object initialization should be done as a loop or as
-  // straight line code.
-  const int kInlineInstanceSize = 12;  // In words.
-  const intptr_t instance_size = target::Class::GetInstanceSize(cls);
-  ASSERT(instance_size > 0);
-  __ LoadObject(R9, NullObject());
+static void GenerateAllocateObjectHelper(Assembler* assembler,
+                                         bool is_cls_parameterized) {
+  // Note: Keep in sync with calling function.
+  // kAllocationStubTypeArgumentsReg = RDX
+  const Register kTagsReg = R8;
 
-  // RDX: instantiated type arguments (if is_cls_parameterized).
-  static_assert(kAllocationStubTypeArgumentsReg == RDX,
-                "Adjust register allocation in the AllocationStub");
-
-  if (!FLAG_use_slow_path && FLAG_inline_alloc &&
-      target::Heap::IsAllocatableInNewSpace(instance_size) &&
-      !target::Class::TraceAllocation(cls)) {
+  {
     Label slow_case;
+    const Register kNewTopReg = R9;
+
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
-    // RDX: instantiated type arguments (if is_cls_parameterized).
-    __ movq(RAX, Address(THR, target::Thread::top_offset()));
-    __ leaq(RBX, Address(RAX, instance_size));
-    // Check if the allocation fits into the remaining space.
-    // RAX: potential new object start.
-    // RBX: potential next object start.
-    __ cmpq(RBX, Address(THR, target::Thread::end_offset()));
-    __ j(ABOVE_EQUAL, &slow_case);
+    {
+      const Register kInstanceSizeReg = RSI;
 
-    __ movq(Address(THR, target::Thread::top_offset()), RBX);
+      __ ExtractInstanceSizeFromTags(kInstanceSizeReg, kTagsReg);
 
-    // RAX: new object start (untagged).
-    // RBX: next object start.
-    // RDX: new object type arguments (if is_cls_parameterized).
+      __ movq(RAX, Address(THR, target::Thread::top_offset()));
+      __ leaq(kNewTopReg, Address(RAX, kInstanceSizeReg, TIMES_1, 0));
+      // Check if the allocation fits into the remaining space.
+      __ cmpq(kNewTopReg, Address(THR, target::Thread::end_offset()));
+      __ j(ABOVE_EQUAL, &slow_case);
+
+      __ movq(Address(THR, target::Thread::top_offset()), kNewTopReg);
+    }  // kInstanceSizeReg = RSI
+
     // Set the tags.
-    ASSERT(target::Class::GetId(cls) != kIllegalCid);
-    const uint32_t tags = target::MakeTagWordForNewSpaceObject(
-        target::Class::GetId(cls), instance_size);
     // 64 bit store also zeros the identity hash field.
-    __ movq(Address(RAX, target::Object::tags_offset()), Immediate(tags));
+    __ movq(Address(RAX, target::Object::tags_offset()), kTagsReg);
+
     __ addq(RAX, Immediate(kHeapObjectTag));
 
     // Initialize the remaining words of the object.
-    // RAX: new object (tagged).
-    // RBX: next object start.
-    // RDX: new object type arguments (if is_cls_parameterized).
-    // R9: raw null.
-    // First try inlining the initialization without a loop.
-    if (instance_size < (kInlineInstanceSize * target::kWordSize)) {
-      // Check if the object contains any non-header fields.
-      // Small objects are initialized using a consecutive set of writes.
-      for (intptr_t current_offset = target::Instance::first_field_offset();
-           current_offset < instance_size;
-           current_offset += target::kWordSize) {
-        __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, current_offset), R9);
-      }
-    } else {
-      __ leaq(RCX, FieldAddress(RAX, target::Instance::first_field_offset()));
+    {
+      const Register kNextFieldReg = RDI;
+      __ leaq(kNextFieldReg,
+              FieldAddress(RAX, target::Instance::first_field_offset()));
+
+      const Register kNullReg = R10;
+      __ LoadObject(kNullReg, NullObject());
+
       // Loop until the whole object is initialized.
-      // RAX: new object (tagged).
-      // RBX: next object start.
-      // RCX: next word to be initialized.
-      // RDX: new object type arguments (if is_cls_parameterized).
       Label init_loop;
       Label done;
       __ Bind(&init_loop);
-      __ cmpq(RCX, RBX);
+      __ cmpq(kNextFieldReg, kNewTopReg);
 #if defined(DEBUG)
       static const bool kJumpLength = Assembler::kFarJump;
 #else
       static const bool kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
       __ j(ABOVE_EQUAL, &done, kJumpLength);
-      __ StoreIntoObjectNoBarrier(RAX, Address(RCX, 0), R9);
-      __ addq(RCX, Immediate(target::kWordSize));
+      __ StoreIntoObjectNoBarrier(RAX, Address(kNextFieldReg, 0), kNullReg);
+      __ addq(kNextFieldReg, Immediate(target::kWordSize));
       __ jmp(&init_loop, Assembler::kNearJump);
       __ Bind(&done);
-    }
+    }  // kNextFieldReg = RDI, kNullReg = R10
+
     if (is_cls_parameterized) {
-      // RAX: new object (tagged).
-      // RDX: new object type arguments.
+      Label not_parameterized_case;
+
+      const Register kClsIdReg = R9;
+      const Register kTypeOffsetReg = RDI;
+
+      __ ExtractClassIdFromTags(kClsIdReg, kTagsReg);
+
+      // Load class' type_arguments_field offset in words.
+      __ LoadClassById(kTypeOffsetReg, kClsIdReg);
+      __ movl(
+          kTypeOffsetReg,
+          FieldAddress(kTypeOffsetReg,
+                       target::Class::
+                           host_type_arguments_field_offset_in_words_offset()));
+
       // Set the type arguments in the new object.
-      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
-      __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, offset),
-                                  kAllocationStubTypeArgumentsReg);
-    }
-    // Done allocating and initializing the instance.
-    // RAX: new object (tagged).
+      __ StoreIntoObject(RAX, FieldAddress(RAX, kTypeOffsetReg, TIMES_8, 0),
+                         kAllocationStubTypeArgumentsReg);
+
+      __ Bind(&not_parameterized_case);
+    }  // kTypeOffsetReg = RDI;
+
     __ ret();
 
     __ Bind(&slow_case);
-  }
-  // If is_cls_parameterized:
-  // RDX: new object type arguments.
-  // Create a stub frame.
-  __ EnterStubFrame();  // Uses PP to access class object.
+  }  // kNewTopReg = R9;
 
-  __ pushq(R9);  // Setup space on stack for return value.
-  __ PushObject(
-      CastHandle<Object>(cls));  // Push class of object to be allocated.
-  if (is_cls_parameterized) {
-    // Push type arguments of object to be allocated.
-    __ pushq(kAllocationStubTypeArgumentsReg);
-  } else {
-    __ pushq(R9);  // Push null type arguments.
+  // Fall back on slow case:
+  if (!is_cls_parameterized) {
+    __ LoadObject(kAllocationStubTypeArgumentsReg, NullObject());
   }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
+  // Tail call to generic allocation stub.
+  __ jmp(
+      Address(THR, target::Thread::allocate_object_slow_entry_point_offset()));
+}
+
+// Called for inline allocation of objects (any class).
+void StubCodeCompiler::GenerateAllocateObjectStub(Assembler* assembler) {
+  GenerateAllocateObjectHelper(assembler, /*is_cls_parameterized=*/false);
+}
+
+void StubCodeCompiler::GenerateAllocateObjectParameterizedStub(
+    Assembler* assembler) {
+  GenerateAllocateObjectHelper(assembler, /*is_cls_parameterized=*/true);
+}
+
+void StubCodeCompiler::GenerateAllocateObjectSlowStub(Assembler* assembler) {
+  // Note: Keep in sync with calling stub.
+  // kAllocationStubTypeArgumentsReg = RDX
+  const Register kTagsToClsIdReg = R8;
+
+  if (!FLAG_use_bare_instructions) {
+    __ movq(CODE_REG,
+            Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  }
+
+  __ ExtractClassIdFromTags(kTagsToClsIdReg, kTagsToClsIdReg);
+
+  // Create a stub frame.
+  // Ensure constant pool is allowed so we can e.g. load class object.
+  __ EnterStubFrame();
+
+  // Setup space on stack for return value.
+  __ LoadObject(RAX, NullObject());
+  __ pushq(RAX);
+
+  // Push class of object to be allocated.
+  __ LoadClassById(RAX, kTagsToClsIdReg);
+  __ pushq(RAX);
+
+  // Must be Object::null() if non-parameterized class.
+  __ pushq(kAllocationStubTypeArgumentsReg);
+
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);
+
   __ popq(RAX);  // Pop argument (type arguments of object).
   __ popq(RAX);  // Pop argument (class of object).
   __ popq(RAX);  // Pop result (newly allocated object).
 
-  if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
-    // Write-barrier elimination is enabled for [cls] and we therefore need to
-    // ensure that the object is in new-space or has remembered bit set.
-    EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
-  }
+  // Write-barrier elimination is enabled for [cls] and we therefore need to
+  // ensure that the object is in new-space or has remembered bit set.
+  EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
 
   // RAX: new object
   // Restore the frame pointer.
   __ LeaveStubFrame();
+
   __ ret();
 }
 
+// Called for inline allocation of objects.
+void StubCodeCompiler::GenerateAllocationStubForClass(
+    Assembler* assembler,
+    UnresolvedPcRelativeCalls* unresolved_calls,
+    const Class& cls,
+    const Code& allocate_object,
+    const Code& allocat_object_parametrized) {
+  static_assert(kAllocationStubTypeArgumentsReg == RDX,
+                "Adjust register allocation in the AllocationStub");
+
+  classid_t cls_id = target::Class::GetId(cls);
+  ASSERT(cls_id != kIllegalCid);
+
+  RELEASE_ASSERT(AllocateObjectInstr::WillAllocateNewOrRemembered(cls));
+
+  const intptr_t cls_type_arg_field_offset =
+      target::Class::TypeArgumentsFieldOffset(cls);
+
+  // The generated code is different if the class is parameterized.
+  const bool is_cls_parameterized = target::Class::NumTypeArguments(cls) > 0;
+  ASSERT(!is_cls_parameterized ||
+         cls_type_arg_field_offset != target::Class::kNoTypeArguments);
+
+  const intptr_t instance_size = target::Class::GetInstanceSize(cls);
+  ASSERT(instance_size > 0);
+  // User-defined classes should always be allocatable in new space.
+  RELEASE_ASSERT(target::Heap::IsAllocatableInNewSpace(instance_size));
+
+  const uint32_t tags =
+      target::MakeTagWordForNewSpaceObject(cls_id, instance_size);
+
+  // Note: Keep in sync with helper function.
+  // kAllocationStubTypeArgumentsReg = RDX
+  const Register kTagsReg = R8;
+
+  __ movq(kTagsReg, Immediate(tags));
+
+  // Load the appropriate generic alloc. stub.
+  if (!FLAG_use_slow_path && FLAG_inline_alloc &&
+      !target::Class::TraceAllocation(cls) &&
+      target::SizeFitsInSizeTag(instance_size)) {
+    if (is_cls_parameterized) {
+      if (!IsSameObject(NullObject(),
+                        CastHandle<Object>(allocat_object_parametrized))) {
+        __ GenerateUnRelocatedPcRelativeTailCall();
+        unresolved_calls->Add(new UnresolvedPcRelativeCall(
+            __ CodeSize(), allocat_object_parametrized, /*is_tail_call=*/true));
+      } else {
+        __ jmp(Address(THR,
+                       target::Thread::
+                           allocate_object_parameterized_entry_point_offset()));
+      }
+    } else {
+      if (!IsSameObject(NullObject(), CastHandle<Object>(allocate_object))) {
+        __ GenerateUnRelocatedPcRelativeTailCall();
+        unresolved_calls->Add(new UnresolvedPcRelativeCall(
+            __ CodeSize(), allocate_object, /*is_tail_call=*/true));
+      } else {
+        __ jmp(
+            Address(THR, target::Thread::allocate_object_entry_point_offset()));
+      }
+    }
+  } else {
+    if (!is_cls_parameterized) {
+      __ LoadObject(kAllocationStubTypeArgumentsReg, NullObject());
+    }
+    __ jmp(Address(THR,
+                   target::Thread::allocate_object_slow_entry_point_offset()));
+  }
+}
+
 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
 // from the entry code of a dart function after an error in passed argument
 // name or number is detected.
@@ -2253,8 +2355,8 @@
 
   if (type == kInstanceCall) {
     __ LoadTaggedClassIdMayBeSmi(RAX, RDX);
-    __ movq(R10,
-            FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+    __ movq(R10, FieldAddress(
+                     RBX, target::CallSiteData::arguments_descriptor_offset()));
     if (num_args == 2) {
       __ movq(RCX,
               FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
@@ -2262,8 +2364,8 @@
       __ LoadTaggedClassIdMayBeSmi(RCX, R9);
     }
   } else {
-    __ movq(R10,
-            FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+    __ movq(R10, FieldAddress(
+                     RBX, target::CallSiteData::arguments_descriptor_offset()));
     __ movq(RCX,
             FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
     __ movq(RDX, Address(RSP, RCX, TIMES_4, 0));
@@ -2372,7 +2474,7 @@
     __ j(EQUAL, &call_target_function_through_unchecked_entry);
 
     // Check trivial exactness.
-    // Note: RawICData::receivers_static_type_ is guaranteed to be not null
+    // Note: ICDataLayout::receivers_static_type_ is guaranteed to be not null
     // because we only emit calls to this stub when it is not null.
     __ movq(RCX,
             FieldAddress(RBX, target::ICData::receivers_static_type_offset()));
@@ -2593,8 +2695,8 @@
   }
 
   // Load arguments descriptor into R10.
-  __ movq(R10,
-          FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+  __ movq(R10, FieldAddress(
+                   RBX, target::CallSiteData::arguments_descriptor_offset()));
 
   // Get function and call it, if possible.
   __ movq(RAX, Address(R12, target_offset));
@@ -2660,9 +2762,11 @@
 // R10: Arguments descriptor.
 // RAX: Function.
 void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
+  if (FLAG_precompiled_mode) {
+    __ Stop("Not using interpreter");
+    return;
+  }
+
   __ EnterStubFrame();
 
 #if defined(DEBUG)
@@ -2732,7 +2836,6 @@
 
   __ LeaveStubFrame();
   __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // RBX: Contains an ICData.
@@ -3104,6 +3207,10 @@
 void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
   Label done, call_runtime;
 
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ movq(CODE_REG,
+            Address(THR, target::Thread::slow_type_test_stub_offset()));
+  }
   __ EnterStubFrame();
 
   // If the subtype-cache is null, it needs to be lazily-created by the runtime.
@@ -3121,7 +3228,7 @@
   // Check whether this [Type] is instantiated/uninstantiated.
   __ cmpb(
       FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
-      Immediate(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+      Immediate(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is a function type.
@@ -3359,7 +3466,7 @@
 }
 
 // Called from megamorphic calls.
-//  RDX: receiver
+//  RDX: receiver (passed to target)
 //  RBX: target::MegamorphicCache (preserved)
 // Passed to target:
 //  CODE_REG: target Code
@@ -3409,15 +3516,13 @@
   const auto target_address =
       FieldAddress(RDI, RCX, TIMES_8, base + target::kWordSize);
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ movq(R10,
-            FieldAddress(
-                RBX, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ movq(R10, FieldAddress(
+                     RBX, target::CallSiteData::arguments_descriptor_offset()));
     __ jmp(target_address);
   } else {
     __ movq(RAX, target_address);
-    __ movq(R10,
-            FieldAddress(
-                RBX, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ 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()));
     __ jmp(RCX);
@@ -3439,11 +3544,14 @@
   __ jmp(&cid_loaded);
 }
 
+// Input:
+//  RBX - icdata
+//  RDX - receiver object
 void StubCodeCompiler::GenerateICCallThroughCodeStub(Assembler* assembler) {
   Label loop, found, miss;
   __ movq(R13, FieldAddress(RBX, target::ICData::entries_offset()));
-  __ movq(R10,
-          FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+  __ movq(R10, FieldAddress(
+                   RBX, target::CallSiteData::arguments_descriptor_offset()));
   __ leaq(R13, FieldAddress(R13, target::Array::data_offset()));
   // R13: first IC entry
   __ LoadTaggedClassIdMayBeSmi(RAX, RDX);
@@ -3505,21 +3613,21 @@
   }
 
   __ Bind(&miss);
-  __ jmp(Address(THR, target::Thread::monomorphic_miss_entry_offset()));
+  __ jmp(Address(THR, target::Thread::switchable_call_miss_entry_offset()));
 }
 
+// Called from switchable IC calls.
 //  RDX: receiver
-//  RBX: UnlinkedCall
-void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
+void StubCodeCompiler::GenerateSwitchableCallMissStub(Assembler* assembler) {
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::switchable_call_miss_stub_offset()));
   __ EnterStubFrame();
   __ pushq(RDX);  // Preserve receiver.
 
   __ pushq(Immediate(0));  // Result slot.
   __ pushq(Immediate(0));  // Arg0: stub out.
   __ pushq(RDX);           // Arg1: Receiver
-  __ pushq(RBX);           // Arg2: UnlinkedCall
-  __ CallRuntime(kUnlinkedCallRuntimeEntry, 3);
-  __ popq(RBX);
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
   __ popq(RBX);
   __ popq(CODE_REG);  // result = stub
   __ popq(RBX);       // result = IC
@@ -3528,10 +3636,19 @@
   __ LeaveStubFrame();
 
   __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
-                                          CodeEntryKind::kMonomorphic)));
+                                          CodeEntryKind::kNormal)));
   __ jmp(RCX);
 }
 
+// Called from megamorphic call sites and from megamorphic miss handlers.
+//  RDX: receiver
+//  R10: arguments descriptor
+void StubCodeCompiler::GenerateMegamorphicCallMissStub(Assembler* assembler) {
+  // On x64 there is no need to load receiver from the actual arguments using
+  // arg descriptor because (unlike on arm, arm64) receiver is always available.
+  GenerateSwitchableCallMissStub(assembler);
+}
+
 // Called from switchable IC calls.
 //  RDX: receiver
 //  RBX: SingleTargetCache
@@ -3561,31 +3678,7 @@
   __ pushq(Immediate(0));  // Result slot.
   __ pushq(Immediate(0));  // Arg0: stub out
   __ pushq(RDX);           // Arg1: Receiver
-  __ CallRuntime(kSingleTargetMissRuntimeEntry, 2);
-  __ popq(RBX);
-  __ popq(CODE_REG);  // result = stub
-  __ popq(RBX);       // result = IC
-
-  __ popq(RDX);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
-                                          CodeEntryKind::kMonomorphic)));
-  __ jmp(RCX);
-}
-
-// Called from the monomorphic checked entry.
-//  RDX: receiver
-void StubCodeCompiler::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ movq(CODE_REG,
-          Address(THR, target::Thread::monomorphic_miss_stub_offset()));
-  __ EnterStubFrame();
-  __ pushq(RDX);  // Preserve receiver.
-
-  __ pushq(Immediate(0));  // Result slot.
-  __ pushq(Immediate(0));  // Arg0: stub out.
-  __ pushq(RDX);           // Arg1: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 2);
+  __ CallRuntime(kSwitchableCallMissRuntimeEntry, 2);
   __ popq(RBX);
   __ popq(CODE_REG);  // result = stub
   __ popq(RBX);       // result = IC
@@ -3711,4 +3804,4 @@
 
 }  // namespace dart
 
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/compiler/type_testing_stubs_arm.cc b/runtime/vm/compiler/type_testing_stubs_arm.cc
new file mode 100644
index 0000000..ed1ace2
--- /dev/null
+++ b/runtime/vm/compiler/type_testing_stubs_arm.cc
@@ -0,0 +1,37 @@
+// 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/globals.h"
+
+#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/type_testing_stubs.h"
+
+#define __ assembler->
+
+namespace dart {
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+    compiler::Assembler* assembler,
+    compiler::UnresolvedPcRelativeCalls* unresolved_calls,
+    const Code& slow_type_test_stub,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
+  if (!compiler::IsSameObject(
+          compiler::NullObject(),
+          compiler::CastHandle<Object>(slow_type_test_stub))) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    unresolved_calls->Add(new compiler::UnresolvedPcRelativeCall(
+        __ CodeSize(), slow_type_test_stub, /*is_tail_call=*/true));
+  } else {
+    __ Branch(compiler::Address(
+        THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
+  }
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/type_testing_stubs_arm64.cc b/runtime/vm/compiler/type_testing_stubs_arm64.cc
new file mode 100644
index 0000000..0540b01
--- /dev/null
+++ b/runtime/vm/compiler/type_testing_stubs_arm64.cc
@@ -0,0 +1,40 @@
+// 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/globals.h"
+
+#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/type_testing_stubs.h"
+
+#define __ assembler->
+
+namespace dart {
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+    compiler::Assembler* assembler,
+    compiler::UnresolvedPcRelativeCalls* unresolved_calls,
+    const Code& slow_type_test_stub,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
+  if (!compiler::IsSameObject(
+          compiler::NullObject(),
+          compiler::CastHandle<Object>(slow_type_test_stub))) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    unresolved_calls->Add(new compiler::UnresolvedPcRelativeCall(
+        __ CodeSize(), slow_type_test_stub, /*is_tail_call=*/true));
+  } else {
+    __ ldr(TMP,
+           compiler::Address(
+               THR,
+               compiler::target::Thread::slow_type_test_entry_point_offset()));
+    __ br(TMP);
+  }
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/type_testing_stubs_x64.cc b/runtime/vm/compiler/type_testing_stubs_x64.cc
new file mode 100644
index 0000000..f7a974c
--- /dev/null
+++ b/runtime/vm/compiler/type_testing_stubs_x64.cc
@@ -0,0 +1,37 @@
+// 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/globals.h"
+
+#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/type_testing_stubs.h"
+
+#define __ assembler->
+
+namespace dart {
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+    compiler::Assembler* assembler,
+    compiler::UnresolvedPcRelativeCalls* unresolved_calls,
+    const Code& slow_type_test_stub,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
+  if (!compiler::IsSameObject(
+          compiler::NullObject(),
+          compiler::CastHandle<Object>(slow_type_test_stub))) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    unresolved_calls->Add(new compiler::UnresolvedPcRelativeCall(
+        __ CodeSize(), slow_type_test_stub, /*is_tail_call=*/true));
+  } else {
+    __ jmp(compiler::Address(
+        THR, compiler::target::Thread::slow_type_test_entry_point_offset()));
+  }
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/write_barrier_elimination.cc b/runtime/vm/compiler/write_barrier_elimination.cc
index 162f8e1..8dc6b3c 100644
--- a/runtime/vm/compiler/write_barrier_elimination.cc
+++ b/runtime/vm/compiler/write_barrier_elimination.cc
@@ -331,8 +331,8 @@
 
 #define FOR_EACH_NATIVE_SLOT(class, underlying_type, field, type, modifiers)   \
   case Slot::Kind::k##class##_##field:                                         \
-    return std::is_base_of<RawInstance, underlying_type>::value ||             \
-           std::is_base_of<RawContext, underlying_type>::value;
+    return std::is_base_of<InstanceLayout, underlying_type>::value ||          \
+           std::is_base_of<ContextLayout, underlying_type>::value;
 
       NATIVE_SLOTS_LIST(FOR_EACH_NATIVE_SLOT)
 #undef FOR_EACH_NATIVE_SLOT
diff --git a/runtime/vm/compiler/write_barrier_elimination.h b/runtime/vm/compiler/write_barrier_elimination.h
index 88109e7..b4d200f 100644
--- a/runtime/vm/compiler/write_barrier_elimination.h
+++ b/runtime/vm/compiler/write_barrier_elimination.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_COMPILER_WRITE_BARRIER_ELIMINATION_H_
 #define RUNTIME_VM_COMPILER_WRITE_BARRIER_ELIMINATION_H_
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+#error "AOT runtime should not use compiler sources (including header files)"
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 class FlowGraph;
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 2ea85b1..e7b6d31 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -220,7 +220,7 @@
   if (!KernelIsolate::IsRunning()) {
     UNREACHABLE();
   } else {
-    RawLibrary* raw_library = Library::RawCast(Api::UnwrapHandle(lib));
+    LibraryPtr raw_library = Library::RawCast(Api::UnwrapHandle(lib));
     Library& lib_handle = Library::ZoneHandle(raw_library);
 
     Dart_KernelCompilationResult compilation_result =
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 8015373..e58b312 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -71,7 +71,7 @@
   R3 = 3,
   R4 = 4,
   R5 = 5,  // PP
-  R6 = 6,
+  R6 = 6,  // CODE
   R7 = 7,  // iOS FP
   R8 = 8,
   R9 = 9,
@@ -331,6 +331,9 @@
       (1 << kInstanceReg) | (1 << kDstTypeReg) |
       (1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
       (1 << kSubtypeTestCacheReg);
+
+  // For call to InstanceOfStub.
+  static const Register kResultReg = R0;
 };
 
 // Registers used inside the implementation of type testing stubs.
@@ -347,6 +350,44 @@
   static const Register kFieldReg = R0;
 };
 
+// ABI for InitInstanceFieldStub.
+struct InitInstanceFieldABI {
+  static const Register kInstanceReg = R0;
+  static const Register kFieldReg = R1;
+};
+
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+  static const Register kFunctionReg = R0;
+  static const Register kInitializerResultReg = R0;
+  static const Register kInstanceReg = R1;
+  static const Register kFieldReg = R2;
+  static const Register kAddressReg = R3;
+  static const Register kScratchReg = R4;
+};
+
+// ABI for ThrowStub.
+struct ThrowABI {
+  static const Register kExceptionReg = R0;
+};
+
+// ABI for ReThrowStub.
+struct ReThrowABI {
+  static const Register kExceptionReg = R0;
+  static const Register kStackTraceReg = R1;
+};
+
+// ABI for AssertBooleanStub.
+struct AssertBooleanABI {
+  static const Register kObjectReg = R0;
+};
+
+// ABI for RangeErrorStub.
+struct RangeErrorABI {
+  static const Register kLengthReg = R0;
+  static const Register kIndexReg = R1;
+};
+
 // TODO(regis): Add ABIs for type testing stubs and is-type test stubs instead
 // of reusing the constants of the instantiation stubs ABI.
 
@@ -487,6 +528,20 @@
   kInvalidCondition = 16
 };
 
+static inline Condition InvertCondition(Condition c) {
+  COMPILE_ASSERT((EQ ^ NE) == 1);
+  COMPILE_ASSERT((CS ^ CC) == 1);
+  COMPILE_ASSERT((MI ^ PL) == 1);
+  COMPILE_ASSERT((VS ^ VC) == 1);
+  COMPILE_ASSERT((HI ^ LS) == 1);
+  COMPILE_ASSERT((GE ^ LT) == 1);
+  COMPILE_ASSERT((GT ^ LE) == 1);
+  ASSERT(c != AL);
+  ASSERT(c != kSpecialCondition);
+  ASSERT(c != kInvalidCondition);
+  return static_cast<Condition>(c ^ 1);
+}
+
 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
 // as defined in section A3.4
 enum Opcode {
@@ -902,6 +957,8 @@
 float ReciprocalSqrtEstimate(float op);
 float ReciprocalSqrtStep(float op1, float op2);
 
+constexpr uword kBreakInstructionFiller = 0xE1200070;  // bkpt #0
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CONSTANTS_ARM_H_
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 69dab7e..c4f8f4b 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -163,6 +163,9 @@
       (1 << kInstanceReg) | (1 << kDstTypeReg) |
       (1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
       (1 << kSubtypeTestCacheReg);
+
+  // For call to InstanceOfStub.
+  static const Register kResultReg = R0;
 };
 
 // Registers used inside the implementation of type testing stubs.
@@ -179,6 +182,44 @@
   static const Register kFieldReg = R0;
 };
 
+// ABI for InitInstanceFieldStub.
+struct InitInstanceFieldABI {
+  static const Register kInstanceReg = R0;
+  static const Register kFieldReg = R1;
+};
+
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+  static const Register kFunctionReg = R0;
+  static const Register kInitializerResultReg = R0;
+  static const Register kInstanceReg = R1;
+  static const Register kFieldReg = R2;
+  static const Register kAddressReg = R3;
+  static const Register kScratchReg = R4;
+};
+
+// ABI for ThrowStub.
+struct ThrowABI {
+  static const Register kExceptionReg = R0;
+};
+
+// ABI for ReThrowStub.
+struct ReThrowABI {
+  static const Register kExceptionReg = R0;
+  static const Register kStackTraceReg = R1;
+};
+
+// ABI for AssertBooleanStub.
+struct AssertBooleanABI {
+  static const Register kObjectReg = R0;
+};
+
+// ABI for RangeErrorStub.
+struct RangeErrorABI {
+  static const Register kLengthReg = R0;
+  static const Register kIndexReg = R1;
+};
+
 // TODO(regis): Add ABIs for type testing stubs and is-type test stubs instead
 // of reusing the constants of the instantiation stubs ABI.
 
@@ -338,8 +379,19 @@
 };
 
 static inline Condition InvertCondition(Condition c) {
-  const int32_t i = static_cast<int32_t>(c) ^ 0x1;
-  return static_cast<Condition>(i);
+  COMPILE_ASSERT((EQ ^ NE) == 1);
+  COMPILE_ASSERT((CS ^ CC) == 1);
+  COMPILE_ASSERT((MI ^ PL) == 1);
+  COMPILE_ASSERT((VS ^ VC) == 1);
+  COMPILE_ASSERT((HI ^ LS) == 1);
+  COMPILE_ASSERT((GE ^ LT) == 1);
+  COMPILE_ASSERT((GT ^ LE) == 1);
+  COMPILE_ASSERT((AL ^ NV) == 1);
+  // Although the NV condition is not valid for branches, it is used internally
+  // in the assembler in the implementation of far branches, so we have to
+  // allow AL and NV here. See EmitConditionalBranch.
+  ASSERT(c != kInvalidCondition);
+  return static_cast<Condition>(c ^ 1);
 }
 
 enum Bits {
@@ -1284,6 +1336,8 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
 };
 
+const uword kBreakInstructionFiller = 0xD4200000D4200000L;  // brk #0; brk #0
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CONSTANTS_ARM64_H_
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 00e1e97..cfa49ee 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -109,6 +109,11 @@
   static const Register kDstTypeReg = EBX;
   static const Register kInstantiatorTypeArgumentsReg = EDX;
   static const Register kFunctionTypeArgumentsReg = ECX;
+  static const Register kSubtypeTestCacheReg =
+      EDI;  // On ia32 we don't use CODE_REG.
+
+  // For call to InstanceOfStub.
+  static const Register kResultReg = kNoRegister;
 };
 
 // ABI for InitStaticFieldStub.
@@ -116,6 +121,44 @@
   static const Register kFieldReg = EAX;
 };
 
+// ABI for InitInstanceFieldStub.
+struct InitInstanceFieldABI {
+  static const Register kInstanceReg = EAX;
+  static const Register kFieldReg = EBX;
+};
+
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+  static const Register kFunctionReg = EAX;
+  static const Register kInitializerResultReg = EAX;
+  static const Register kInstanceReg = EBX;
+  static const Register kFieldReg = EDX;
+  static const Register kAddressReg = ECX;
+  static const Register kScratchReg = EDI;
+};
+
+// ABI for ThrowStub.
+struct ThrowABI {
+  static const Register kExceptionReg = EAX;
+};
+
+// ABI for ReThrowStub.
+struct ReThrowABI {
+  static const Register kExceptionReg = EAX;
+  static const Register kStackTraceReg = EBX;
+};
+
+// ABI for AssertBooleanStub.
+struct AssertBooleanABI {
+  static const Register kObjectReg = EAX;
+};
+
+// ABI for RangeErrorStub.
+struct RangeErrorABI {
+  static const Register kLengthReg = EAX;
+  static const Register kIndexReg = EBX;
+};
+
 typedef uint32_t RegList;
 const RegList kAllCpuRegistersList = 0xFF;
 
@@ -214,6 +257,8 @@
   static constexpr ExtensionStrategy kArgumentStackExtension = kExtendedTo4;
 };
 
+const uword kBreakInstructionFiller = 0xCCCCCCCC;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CONSTANTS_IA32_H_
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index d29a0d4..7f99877 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -153,6 +153,9 @@
       (1 << kInstanceReg) | (1 << kDstTypeReg) |
       (1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
       (1 << kSubtypeTestCacheReg);
+
+  // For call to InstanceOfStub.
+  static const Register kResultReg = RAX;
 };
 
 // ABI for InitStaticFieldStub.
@@ -160,6 +163,44 @@
   static const Register kFieldReg = RAX;
 };
 
+// ABI for InitInstanceFieldStub.
+struct InitInstanceFieldABI {
+  static const Register kInstanceReg = RAX;
+  static const Register kFieldReg = RBX;
+};
+
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+  static const Register kFunctionReg = RAX;
+  static const Register kInitializerResultReg = RAX;
+  static const Register kInstanceReg = RBX;
+  static const Register kFieldReg = RDX;
+  static const Register kAddressReg = RCX;
+  static const Register kScratchReg = RSI;
+};
+
+// ABI for ThrowStub.
+struct ThrowABI {
+  static const Register kExceptionReg = RAX;
+};
+
+// ABI for ReThrowStub.
+struct ReThrowABI {
+  static const Register kExceptionReg = RAX;
+  static const Register kStackTraceReg = RBX;
+};
+
+// ABI for AssertBooleanStub.
+struct AssertBooleanABI {
+  static const Register kObjectReg = RAX;
+};
+
+// ABI for RangeErrorStub.
+struct RangeErrorABI {
+  static const Register kLengthReg = RAX;
+  static const Register kIndexReg = RBX;
+};
+
 // Registers used inside the implementation of type testing stubs.
 struct TTSInternalRegs {
   static const Register kInstanceTypeArgumentsReg = RSI;
@@ -377,6 +418,8 @@
 // becomes important to us.
 const int MAX_NOP_SIZE = 8;
 
+const uword kBreakInstructionFiller = 0xCCCCCCCCCCCCCCCCL;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CONSTANTS_X64_H_
diff --git a/runtime/vm/constants_x86.h b/runtime/vm/constants_x86.h
index 917c41b..dd77690 100644
--- a/runtime/vm/constants_x86.h
+++ b/runtime/vm/constants_x86.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_CONSTANTS_X86_H_
 #define RUNTIME_VM_CONSTANTS_X86_H_
 
+#include "platform/assert.h"
+
 namespace dart {
 
 enum Condition {
@@ -44,9 +46,22 @@
   UNSIGNED_GREATER = ABOVE,
   UNSIGNED_GREATER_EQUAL = ABOVE_EQUAL,
 
-  INVALID_CONDITION = 16
+  kInvalidCondition = 16
 };
 
+static inline Condition InvertCondition(Condition c) {
+  COMPILE_ASSERT((OVERFLOW ^ NO_OVERFLOW) == 1);
+  COMPILE_ASSERT((BELOW ^ ABOVE_EQUAL) == 1);
+  COMPILE_ASSERT((EQUAL ^ NOT_EQUAL) == 1);
+  COMPILE_ASSERT((BELOW_EQUAL ^ ABOVE) == 1);
+  COMPILE_ASSERT((SIGN ^ NOT_SIGN) == 1);
+  COMPILE_ASSERT((PARITY_EVEN ^ PARITY_ODD) == 1);
+  COMPILE_ASSERT((LESS ^ GREATER_EQUAL) == 1);
+  COMPILE_ASSERT((LESS_EQUAL ^ GREATER) == 1);
+  ASSERT(c != kInvalidCondition);
+  return static_cast<Condition>(c ^ 1);
+}
+
 #define X86_ZERO_OPERAND_1_BYTE_INSTRUCTIONS(F)                                \
   F(ret, 0xC3)                                                                 \
   F(leave, 0xC9)                                                               \
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 6ab6eee..c9dcdc5 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -8,7 +8,6 @@
 #include "vm/cpu.h"
 #include "vm/cpu_arm.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/cpuinfo.h"
 #include "vm/heap/heap.h"
 #include "vm/isolate.h"
diff --git a/runtime/vm/cpu_x64.cc b/runtime/vm/cpu_x64.cc
index c892d85..7f5981c 100644
--- a/runtime/vm/cpu_x64.cc
+++ b/runtime/vm/cpu_x64.cc
@@ -8,7 +8,6 @@
 #include "vm/cpu.h"
 #include "vm/cpu_x64.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants.h"
 #include "vm/cpuinfo.h"
 #include "vm/heap/heap.h"
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 77f7ea6..08ae076 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -69,7 +69,6 @@
 Dart_FileWriteCallback Dart::file_write_callback_ = NULL;
 Dart_FileCloseCallback Dart::file_close_callback_ = NULL;
 Dart_EntropySource Dart::entropy_source_callback_ = NULL;
-bool Dart::non_nullable_flag_ = false;
 
 // Structure for managing read-only global handles allocation used for
 // creating global read-only handles that are pre created and initialized
@@ -109,9 +108,9 @@
 
 #define CHECK_FIELD(Class, Name) CHECK_OFFSET(Class::Name(), Class##_##Name)
 #define CHECK_ARRAY(Class, Name)                                               \
-  CHECK_OFFSET(Class::ArrayLayout::elements_start_offset(),                    \
+  CHECK_OFFSET(Class::ArrayTraits::elements_start_offset(),                    \
                Class##_elements_start_offset)                                  \
-  CHECK_OFFSET(Class::ArrayLayout::kElementSize, Class##_element_size)
+  CHECK_OFFSET(Class::ArrayTraits::kElementSize, Class##_element_size)
 #define CHECK_ARRAY_STRUCTFIELD(Class, Name, ElementOffsetName, FieldOffset)
 
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -235,9 +234,6 @@
     ASSERT(Flags::Initialized());
     const bool is_vm_isolate = true;
 
-    // Cache value of "non-nullable" experimental flag.
-    set_non_nullable_flag(KernelIsolate::GetExperimentalFlag("non-nullable"));
-
     // Setup default flags for the VM isolate.
     Dart_IsolateFlags api_flags;
     Isolate::FlagsInitialize(&api_flags);
@@ -248,7 +244,9 @@
     std::unique_ptr<IsolateGroupSource> source(
         new IsolateGroupSource(nullptr, kVmIsolateName, vm_isolate_snapshot,
                                instructions_snapshot, nullptr, -1, api_flags));
-    auto group = new IsolateGroup(std::move(source), /*embedder_data=*/nullptr);
+    // ObjectStore should be created later, after null objects are initialized.
+    auto group = new IsolateGroup(std::move(source), /*embedder_data=*/nullptr,
+                                  /*object_store=*/nullptr);
     group->CreateHeap(/*is_vm_isolate=*/true,
                       /*is_service_or_kernel_isolate=*/false);
     IsolateGroup::RegisterIsolateGroup(group);
@@ -264,8 +262,11 @@
     ASSERT(T != NULL);
     StackZone zone(T);
     HandleScope handle_scope(T);
-    Object::InitNull(vm_isolate_);
-    ObjectStore::Init(vm_isolate_);
+    Object::InitNullAndBool(vm_isolate_);
+    vm_isolate_->set_object_store(new ObjectStore());
+    vm_isolate_->isolate_object_store()->Init();
+    vm_isolate_->isolate_group_->object_store_ =
+        vm_isolate_->object_store_shared_ptr_;
     TargetCPUFeatures::Init();
     Object::Init(vm_isolate_);
     ArgumentsDescriptor::Init();
@@ -311,7 +312,7 @@
         return strdup(error.ToErrorCString());
       }
 
-      ReversePcLookupCache::BuildAndAttachToIsolate(vm_isolate_);
+      ReversePcLookupCache::BuildAndAttachToIsolateGroup(vm_isolate_->group());
 
       Object::FinishInit(vm_isolate_);
 #if defined(SUPPORT_TIMELINE)
@@ -565,6 +566,22 @@
   delete predefined_handles_;
   predefined_handles_ = NULL;
 
+  // Set the VM isolate as current isolate.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
+                 UptimeMillis());
+  }
+
+  // If Dart_Cleanup() is called on a thread which hasn't invoked any Dart API
+  // functions before, entering the "vm-isolate" will cause lazy creation of a
+  // OSThread (which is attached to the current thread via TLS).
+  //
+  // If we run in PRODUCT mode this lazy creation of OSThread can happen here,
+  // which is why disabling the OSThread creation has to come after entering the
+  // "vm-isolate".
+  const bool result = Thread::EnterIsolate(vm_isolate_);
+  ASSERT(result);
+
   // Disable creation of any new OSThread structures which means no more new
   // threads can do an EnterIsolate. This must come after isolate shutdown
   // because new threads may need to be spawned to shutdown the isolates.
@@ -577,14 +594,6 @@
   }
   OSThread::DisableOSThreadCreation();
 
-  // Set the VM isolate as current isolate.
-  if (FLAG_trace_shutdown) {
-    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
-                 UptimeMillis());
-  }
-  bool result = Thread::EnterIsolate(vm_isolate_);
-  ASSERT(result);
-
   ShutdownIsolate();
   vm_isolate_ = NULL;
   ASSERT(Isolate::IsolateListLength() == 0);
@@ -653,25 +662,34 @@
   return Snapshot::IsFull(isolate_kind);
 }
 
-RawError* Dart::InitializeIsolate(const uint8_t* snapshot_data,
-                                  const uint8_t* snapshot_instructions,
-                                  const uint8_t* kernel_buffer,
-                                  intptr_t kernel_buffer_size,
-                                  void* isolate_data) {
-  // Initialize the new isolate.
-  Thread* T = Thread::Current();
-  Isolate* I = T->isolate();
-#if defined(SUPPORT_TIMELINE)
-  TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
-                             "InitializeIsolate");
-  tbes.SetNumArguments(1);
-  tbes.CopyArgument(0, "isolateName", I->name());
-#endif
-  ASSERT(I != NULL);
-  StackZone zone(T);
-  HandleScope handle_scope(T);
-  ObjectStore::Init(I);
+#if defined(DART_PRECOMPILED_RUNTIME)
+static bool CloneIntoChildIsolateAOT(Thread* T,
+                                     Isolate* I,
+                                     IsolateGroup* source_isolate_group) {
+  // In AOT we speed up isolate spawning by copying donor's isolate structure.
+  Isolate* donor_isolate = source_isolate_group != nullptr
+                               ? source_isolate_group->FirstIsolate()
+                               : nullptr;
+  if (donor_isolate == nullptr) {
+    return false;
+  }
+  I->isolate_object_store()->Init();
+  I->isolate_object_store()->PreallocateObjects();
+  // Initialize field_table with initial values.
+  I->set_field_table(T, donor_isolate->saved_initial_field_table()->Clone());
+  I->set_saved_initial_field_table(
+      donor_isolate->saved_initial_field_table_shareable());
 
+  return true;
+}
+#endif
+
+ErrorPtr Dart::InitIsolateFromSnapshot(Thread* T,
+                                       Isolate* I,
+                                       const uint8_t* snapshot_data,
+                                       const uint8_t* snapshot_instructions,
+                                       const uint8_t* kernel_buffer,
+                                       intptr_t kernel_buffer_size) {
   Error& error = Error::Handle(T->zone());
   error = Object::Init(I, kernel_buffer, kernel_buffer_size);
   if (!error.IsNull()) {
@@ -681,8 +699,8 @@
     // Read the snapshot and setup the initial state.
 #if defined(SUPPORT_TIMELINE)
     TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
-                               "ReadIsolateSnapshot");
-#endif
+                               "ReadProgramSnapshot");
+#endif  // defined(SUPPORT_TIMELINE)
     // TODO(turnidge): Remove once length is not part of the snapshot.
     const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
     if (snapshot == NULL) {
@@ -700,12 +718,12 @@
       OS::PrintErr("Size of isolate snapshot = %" Pd "\n", snapshot->length());
     }
     FullSnapshotReader reader(snapshot, snapshot_instructions, T);
-    const Error& error = Error::Handle(reader.ReadIsolateSnapshot());
+    const Error& error = Error::Handle(reader.ReadProgramSnapshot());
     if (!error.IsNull()) {
       return error.raw();
     }
 
-    ReversePcLookupCache::BuildAndAttachToIsolate(I);
+    ReversePcLookupCache::BuildAndAttachToIsolateGroup(I->group());
 
 #if defined(SUPPORT_TIMELINE)
     if (tbes.enabled()) {
@@ -714,7 +732,7 @@
       tbes.FormatArgument(1, "heapSize", "%" Pd64,
                           I->heap()->UsedInWords(Heap::kOld) * kWordSize);
     }
-#endif  // !defined(PRODUCT)
+#endif  // defined(SUPPORT_TIMELINE)
     if (FLAG_trace_isolates) {
       I->heap()->PrintSizes();
       MegamorphicCacheTable::PrintSizes(I);
@@ -727,60 +745,103 @@
     }
   }
 
+  return Error::null();
+}
+
+#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->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->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.buf());
+}
+#endif
+
+ErrorPtr Dart::InitializeIsolate(const uint8_t* snapshot_data,
+                                 const uint8_t* snapshot_instructions,
+                                 const uint8_t* kernel_buffer,
+                                 intptr_t kernel_buffer_size,
+                                 IsolateGroup* source_isolate_group,
+                                 void* isolate_data) {
+  // Initialize the new isolate.
+  Thread* T = Thread::Current();
+  Isolate* I = T->isolate();
+#if defined(SUPPORT_TIMELINE)
+  TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
+                             "InitializeIsolate");
+  tbes.SetNumArguments(1);
+  tbes.CopyArgument(0, "isolateName", I->name());
+#endif
+  ASSERT(I != NULL);
+  StackZone zone(T);
+  HandleScope handle_scope(T);
+  bool was_child_cloned_into_existing_isolate = false;
+#if defined(DART_PRECOMPILED_RUNTIME)
+  if (CloneIntoChildIsolateAOT(T, I, source_isolate_group)) {
+    was_child_cloned_into_existing_isolate = true;
+  } else {
+#endif
+    const Error& error = Error::Handle(
+        InitIsolateFromSnapshot(T, I, snapshot_data, snapshot_instructions,
+                                kernel_buffer, kernel_buffer_size));
+    if (!error.IsNull()) {
+      return error.raw();
+    }
+#if defined(DART_PRECOMPILED_RUNTIME)
+  }
+#endif
+
   Object::VerifyBuiltinVtables();
   DEBUG_ONLY(I->heap()->Verify(kForbidMarked));
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   // AOT: The megamorphic miss function and code come from the snapshot.
-  ASSERT(I->object_store()->megamorphic_miss_code() != Code::null());
+  ASSERT(I->object_store()->megamorphic_call_miss_code() != Code::null());
   ASSERT(I->object_store()->build_method_extractor_code() != Code::null());
   if (FLAG_print_llvm_constant_pool) {
-    StackZone printing_zone(T);
-    HandleScope printing_scope(T);
-    TextBuffer b(1000);
-    const auto& constants =
-        GrowableObjectArray::Handle(I->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->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.buf());
+    PrintLLVMConstantPool(T, I);
   }
 #else
-  // JIT: The megamorphic miss function and code come from the snapshot in JIT
-  // app snapshot, otherwise create them.
-  if (I->object_store()->megamorphic_miss_code() == Code::null()) {
+  // JIT: The megamorphic call miss function and code come from the snapshot in
+  // JIT app snapshot, otherwise create them.
+  if (I->object_store()->megamorphic_call_miss_code() == Code::null()) {
     MegamorphicCacheTable::InitMissHandler(I);
   }
 #if !defined(TARGET_ARCH_IA32)
@@ -791,18 +852,23 @@
 #endif
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-  const Code& miss_code =
-      Code::Handle(I->object_store()->megamorphic_miss_code());
-  I->set_ic_miss_code(miss_code);
+  I->set_ic_miss_code(StubCode::SwitchableCallMiss());
 
   if ((snapshot_data == NULL) || (kernel_buffer != NULL)) {
-    const Error& error = Error::Handle(I->object_store()->PreallocateObjects());
+    Error& error = Error::Handle();
+    error ^= I->object_store()->PreallocateObjects();
+    if (!error.IsNull()) {
+      return error.raw();
+    }
+    error ^= I->isolate_object_store()->PreallocateObjects();
     if (!error.IsNull()) {
       return error.raw();
     }
   }
 
-  I->heap()->InitGrowthControl();
+  if (!was_child_cloned_into_existing_isolate) {
+    I->heap()->InitGrowthControl();
+  }
   I->set_init_callback_data(isolate_data);
   if (FLAG_print_class_table) {
     I->class_table()->Print();
@@ -908,12 +974,21 @@
 #error What architecture?
 #endif
 
-    ADD_ISOLATE_FLAG(null_safety, null_safety, FLAG_null_safety);
+    if (isolate != NULL) {
+      if (isolate->null_safety()) {
+        buffer.AddString(" null-safety");
+      } else {
+        buffer.AddString(" no-null-safety");
+      }
+    } else {
+      if (FLAG_null_safety == kNullSafetyOptionStrong) {
+        buffer.AddString(" null-safety");
+      } else {
+        buffer.AddString(" no-null-safety");
+      }
+    }
   }
 
-  if (Dart::non_nullable_flag()) {
-    buffer.AddString(" nnbd-experiment");
-  }
 #undef ADD_ISOLATE_FLAG
 #undef ADD_D
 #undef ADD_C
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 0c7b6e8..6fa528d 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -15,7 +15,6 @@
 class DebugInfo;
 class Isolate;
 class LocalHandle;
-class RawError;
 class ReadOnlyHandles;
 class ThreadPool;
 namespace kernel {
@@ -55,11 +54,18 @@
   // from SDK library sources.  If the snapshot_buffer is non-NULL,
   // initialize from a snapshot or a Kernel binary depending on the value of
   // from_kernel.  Otherwise, initialize from sources.
-  static RawError* InitializeIsolate(const uint8_t* snapshot_data,
-                                     const uint8_t* snapshot_instructions,
-                                     const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_size,
-                                     void* data);
+  static ErrorPtr InitializeIsolate(const uint8_t* snapshot_data,
+                                    const uint8_t* snapshot_instructions,
+                                    const uint8_t* kernel_buffer,
+                                    intptr_t kernel_buffer_size,
+                                    IsolateGroup* source_isolate_group,
+                                    void* data);
+  static ErrorPtr InitIsolateFromSnapshot(Thread* T,
+                                          Isolate* I,
+                                          const uint8_t* snapshot_data,
+                                          const uint8_t* snapshot_instructions,
+                                          const uint8_t* kernel_buffer,
+                                          intptr_t kernel_buffer_size);
   static void RunShutdownCallback();
   static void ShutdownIsolate(Isolate* isolate);
   static void ShutdownIsolate();
@@ -125,10 +131,6 @@
     return entropy_source_callback_;
   }
 
-  // TODO(dartbug.com/40342): Delete these functions.
-  static void set_non_nullable_flag(bool value) { non_nullable_flag_ = value; }
-  static bool non_nullable_flag() { return true; }
-
  private:
   static constexpr const char* kVmIsolateName = "vm-isolate";
 
@@ -147,7 +149,6 @@
   static Dart_FileWriteCallback file_write_callback_;
   static Dart_FileCloseCallback file_close_callback_;
   static Dart_EntropySource entropy_source_callback_;
-  static bool non_nullable_flag_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 468a3b1..91d3d63 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -22,11 +22,7 @@
 #include "vm/debugger.h"
 #include "vm/dwarf.h"
 #include "vm/elf.h"
-#if !defined(DART_PRECOMPILED_RUNTIME)
-#include "vm/kernel_loader.h"
-#endif
 #include "platform/unicode.h"
-#include "vm/compiler/aot/precompiler.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
 #include "vm/growable_array.h"
@@ -59,6 +55,11 @@
 #include "vm/uri.h"
 #include "vm/version.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/aot/precompiler.h"
+#include "vm/kernel_loader.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // Facilitate quick access to the current zone once we have the current thread.
@@ -83,7 +84,7 @@
 
 #define CHECK_ERROR_HANDLE(error)                                              \
   {                                                                            \
-    RawError* err = (error);                                                   \
+    ErrorPtr err = (error);                                                    \
     if (err != Error::null()) {                                                \
       return Api::NewHandle(T, err);                                           \
     }                                                                          \
@@ -114,7 +115,7 @@
         funcHandle_(Function::Handle(thread->zone())),
         typeHandle_(AbstractType::Handle(thread->zone())) {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     if (obj->IsFunction()) {
       funcHandle_ ^= obj;
       classHandle_ ^= funcHandle_.Owner();
@@ -144,7 +145,7 @@
 };
 #endif  // #if defined(DEBUG).
 
-static RawInstance* GetListInstance(Zone* zone, const Object& obj) {
+static InstancePtr GetListInstance(Zone* zone, const Object& obj) {
   if (obj.IsInstance()) {
     ObjectStore* object_store = Isolate::Current()->object_store();
     Type& list_rare_type =
@@ -168,7 +169,7 @@
   return Instance::null();
 }
 
-static RawInstance* GetMapInstance(Zone* zone, const Object& obj) {
+static InstancePtr GetMapInstance(Zone* zone, const Object& obj) {
   if (obj.IsInstance()) {
     ObjectStore* object_store = Isolate::Current()->object_store();
     Type& map_rare_type =
@@ -221,7 +222,7 @@
   REUSABLE_OBJECT_HANDLESCOPE(thread);
   Object& obj = thread->ObjectHandle();
   obj = arguments->NativeArgAt(arg_index);
-  if (RawObject::IsStringClassId(obj.GetClassId())) {
+  if (IsStringClassId(obj.GetClassId())) {
     ASSERT(thread->api_top_scope() != NULL);
     *str = Api::NewHandle(thread, obj.raw());
     return true;
@@ -293,7 +294,7 @@
                        current_func, field_count, num_fields);
 }
 
-static RawObject* Send0Arg(const Instance& receiver, const String& selector) {
+static ObjectPtr Send0Arg(const Instance& receiver, const String& selector) {
   const intptr_t kTypeArgsLen = 0;
   const intptr_t kNumArgs = 1;
   ArgumentsDescriptor args_desc(
@@ -308,9 +309,9 @@
   return DartEntry::InvokeFunction(function, args);
 }
 
-static RawObject* Send1Arg(const Instance& receiver,
-                           const String& selector,
-                           const Instance& argument) {
+static ObjectPtr Send1Arg(const Instance& receiver,
+                          const String& selector,
+                          const Instance& argument) {
   const intptr_t kTypeArgsLen = 0;
   const intptr_t kNumArgs = 2;
   ArgumentsDescriptor args_desc(
@@ -345,7 +346,7 @@
   }
 }
 
-Dart_Handle Api::InitNewHandle(Thread* thread, RawObject* raw) {
+Dart_Handle Api::InitNewHandle(Thread* thread, ObjectPtr raw) {
   LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
   ASSERT(local_handles != NULL);
   LocalHandle* ref = local_handles->AllocateHandle();
@@ -353,7 +354,7 @@
   return ref->apiHandle();
 }
 
-Dart_Handle Api::NewHandle(Thread* thread, RawObject* raw) {
+Dart_Handle Api::NewHandle(Thread* thread, ObjectPtr raw) {
   if (raw == Object::null()) {
     return Null();
   }
@@ -367,7 +368,7 @@
   return InitNewHandle(thread, raw);
 }
 
-RawObject* Api::UnwrapHandle(Dart_Handle object) {
+ObjectPtr Api::UnwrapHandle(Dart_Handle object) {
 #if defined(DEBUG)
   Thread* thread = Thread::Current();
   ASSERT(thread->execution_state() == Thread::kThreadInVM);
@@ -519,8 +520,8 @@
   ASSERT(api_native_key_ != kUnsetThreadLocalKey);
 }
 
-static Dart_Handle InitNewReadOnlyApiHandle(RawObject* raw) {
-  ASSERT(raw->InVMIsolateHeap());
+static Dart_Handle InitNewReadOnlyApiHandle(ObjectPtr raw) {
+  ASSERT(raw->ptr()->InVMIsolateHeap());
   LocalHandle* ref = Dart::AllocateReadOnlyApiHandle();
   ref->set_raw(raw);
   return ref->apiHandle();
@@ -557,14 +558,14 @@
                               int arg_index,
                               void** peer) {
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
   if (!raw_obj->IsHeapObject()) {
     return false;
   }
   intptr_t cid = raw_obj->GetClassId();
   if (cid == kExternalOneByteStringCid) {
-    RawExternalOneByteString* raw_string =
-        reinterpret_cast<RawExternalOneByteString*>(raw_obj);
+    ExternalOneByteStringPtr raw_string =
+        static_cast<ExternalOneByteStringPtr>(raw_obj);
     *peer = raw_string->ptr()->peer_;
     return true;
   }
@@ -574,8 +575,8 @@
     return (*peer != 0);
   }
   if (cid == kExternalTwoByteStringCid) {
-    RawExternalTwoByteString* raw_string =
-        reinterpret_cast<RawExternalTwoByteString*>(raw_obj);
+    ExternalTwoByteStringPtr raw_string =
+        static_cast<ExternalTwoByteStringPtr>(raw_obj);
     *peer = raw_string->ptr()->peer_;
     return true;
   }
@@ -584,13 +585,13 @@
 
 bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = arguments->NativeArg0();
+  ObjectPtr raw_obj = arguments->NativeArg0();
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
     if (cid >= kNumPredefinedCids) {
       ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
-      RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
-          RawObject::ToAddr(raw_obj) + sizeof(RawObject));
+      TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
+          ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
       if (native_fields == TypedData::null()) {
         *value = 0;
       } else {
@@ -606,7 +607,7 @@
                                    int arg_index,
                                    bool* value) {
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
     if (cid == kBoolCid) {
@@ -625,16 +626,16 @@
                                    int arg_index,
                                    int64_t* value) {
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
     if (cid == kMintCid) {
-      *value = reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_;
+      *value = static_cast<MintPtr>(raw_obj)->ptr()->value_;
       return true;
     }
     return false;
   }
-  *value = Smi::Value(reinterpret_cast<RawSmi*>(raw_obj));
+  *value = Smi::Value(static_cast<SmiPtr>(raw_obj));
   return true;
 }
 
@@ -642,21 +643,21 @@
                                   int arg_index,
                                   double* value) {
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
     if (cid == kDoubleCid) {
-      *value = reinterpret_cast<RawDouble*>(raw_obj)->ptr()->value_;
+      *value = static_cast<DoublePtr>(raw_obj)->ptr()->value_;
       return true;
     }
     if (cid == kMintCid) {
-      *value = static_cast<double>(
-          reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_);
+      *value =
+          static_cast<double>(static_cast<MintPtr>(raw_obj)->ptr()->value_);
       return true;
     }
     return false;
   }
-  *value = static_cast<double>(Smi::Value(reinterpret_cast<RawSmi*>(raw_obj)));
+  *value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
   return true;
 }
 
@@ -665,12 +666,12 @@
                                     int num_fields,
                                     intptr_t* field_values) {
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+  ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
     if (cid >= kNumPredefinedCids) {
-      RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
-          RawObject::ToAddr(raw_obj) + sizeof(RawObject));
+      TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
+          ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
       if (native_fields == TypedData::null()) {
         memset(field_values, 0, (num_fields * sizeof(field_values[0])));
       } else if (num_fields == Smi::Value(native_fields->ptr()->length_)) {
@@ -864,7 +865,7 @@
     // that GC won't touch the raw error object before creating a valid
     // handle for it in the surviving zone.
     NoSafepointScope no_safepoint;
-    RawError* raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
+    ErrorPtr raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
     thread->UnwindScopes(thread->top_exit_frame_info());
     // Note that thread's zone is different here than at the beginning of this
     // function.
@@ -1141,10 +1142,10 @@
     // Api Handles when an error is encountered.
     T->EnterApiScope();
     const Error& error_obj = Error::Handle(
-        Z, Dart::InitializeIsolate(source->snapshot_data,
-                                   source->snapshot_instructions,
-                                   source->kernel_buffer,
-                                   source->kernel_buffer_size, isolate_data));
+        Z, Dart::InitializeIsolate(
+               source->snapshot_data, source->snapshot_instructions,
+               source->kernel_buffer, source->kernel_buffer_size,
+               is_new_group ? nullptr : group, isolate_data));
     if (error_obj.IsNull()) {
 #if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
       if (FLAG_check_function_fingerprints && source->kernel_buffer == NULL) {
@@ -1193,9 +1194,33 @@
   return false;
 }
 
+Isolate* CreateWithinExistingIsolateGroupAOT(IsolateGroup* group,
+                                             const char* name,
+                                             char** error) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  API_TIMELINE_DURATION(Thread::Current());
+  CHECK_NO_ISOLATE(Isolate::Current());
+
+  auto spawning_group = group;
+
+  Isolate* isolate = reinterpret_cast<Isolate*>(
+      CreateIsolate(spawning_group, /*is_new_group=*/false, name,
+                    /*isolate_data=*/nullptr, error));
+  if (isolate == nullptr) return nullptr;
+
+  auto source = spawning_group->source();
+  ASSERT(isolate->source() == source);
+
+  return isolate;
+#else
+  UNREACHABLE();
+#endif
+}
+
 Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
                                           const char* name,
                                           char** error) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
   API_TIMELINE_DURATION(Thread::Current());
   CHECK_NO_ISOLATE(Isolate::Current());
 
@@ -1218,9 +1243,6 @@
   ASSERT(isolate->source() == source);
 
   if (source->script_kernel_buffer != nullptr) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-    UNREACHABLE();
-#else
     Dart_EnterScope();
     {
       Thread* T = Thread::Current();
@@ -1250,7 +1272,6 @@
       isolate->object_store()->set_root_library(Library::Cast(tmp));
     }
     Dart_ExitScope();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
   }
 
   // If we are running in AppJIT training mode we'll have to remap class ids.
@@ -1321,7 +1342,9 @@
 
         isolate->isolate_group_ = group;
         group->RegisterIsolateLocked(isolate);
-        isolate->class_table()->shared_class_table_ = group->class_table();
+        isolate->class_table()->shared_class_table_ =
+            group->shared_class_table();
+        isolate->set_shared_class_table(group->shared_class_table());
 
         // Even though the mutator thread was descheduled, it will still
         // retain its [Thread] structure with valid isolate/isolate_group
@@ -1353,6 +1376,9 @@
   ASSERT(Thread::Current()->isolate_group() == isolate->group());
 
   return isolate;
+#else
+  UNREACHABLE();
+#endif
 }
 
 DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags* flags) {
@@ -1985,7 +2011,7 @@
     const Error* error;
     {
       NoSafepointScope no_safepoint;
-      RawError* raw_error = Error::Cast(result).raw();
+      ErrorPtr raw_error = Error::Cast(result).raw();
       T->UnwindScopes(T->top_exit_frame_info());
       error = &Error::Handle(T->zone(), raw_error);
     }
@@ -2002,7 +2028,7 @@
     const Error* error;
     {
       NoSafepointScope no_safepoint;
-      RawError* raw_error = T->StealStickyError();
+      ErrorPtr raw_error = T->StealStickyError();
       T->UnwindScopes(T->top_exit_frame_info());
       error = &Error::Handle(T->zone(), raw_error);
     }
@@ -2058,7 +2084,7 @@
   }
 
   // Smis and null can be sent without serialization.
-  RawObject* raw_obj = Api::UnwrapHandle(handle);
+  ObjectPtr raw_obj = Api::UnwrapHandle(handle);
   if (ApiObjectConverter::CanConvert(raw_obj)) {
     return PortMap::PostMessage(
         Message::New(port_id, raw_obj, Message::kNormalPriority));
@@ -2243,14 +2269,14 @@
   Thread* thread = Thread::Current();
   CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
-  return RawObject::IsNumberClassId(Api::ClassId(object));
+  return IsNumberClassId(Api::ClassId(object));
 }
 
 DART_EXPORT bool Dart_IsInteger(Dart_Handle object) {
   Thread* thread = Thread::Current();
   CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
-  return RawObject::IsIntegerClassId(Api::ClassId(object));
+  return IsIntegerClassId(Api::ClassId(object));
 }
 
 DART_EXPORT bool Dart_IsDouble(Dart_Handle object) {
@@ -2271,26 +2297,26 @@
   Thread* thread = Thread::Current();
   CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
-  return RawObject::IsStringClassId(Api::ClassId(object));
+  return IsStringClassId(Api::ClassId(object));
 }
 
 DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) {
   Thread* thread = Thread::Current();
   CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
-  return RawObject::IsOneByteStringClassId(Api::ClassId(object));
+  return IsOneByteStringClassId(Api::ClassId(object));
 }
 
 DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) {
   Thread* thread = Thread::Current();
   CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
-  return RawObject::IsExternalStringClassId(Api::ClassId(object));
+  return IsExternalStringClassId(Api::ClassId(object));
 }
 
 DART_EXPORT bool Dart_IsList(Dart_Handle object) {
   DARTSCOPE(Thread::Current());
-  if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) {
+  if (IsBuiltinListClassId(Api::ClassId(object))) {
     return true;
   }
 
@@ -2363,9 +2389,8 @@
   CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
   intptr_t cid = Api::ClassId(handle);
-  return RawObject::IsTypedDataClassId(cid) ||
-         RawObject::IsExternalTypedDataClassId(cid) ||
-         RawObject::IsTypedDataViewClassId(cid);
+  return IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid) ||
+         IsTypedDataViewClassId(cid);
 }
 
 DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle) {
@@ -2446,7 +2471,7 @@
     RETURN_TYPE_ERROR(Z, function, Function);
   }
   if (func.IsNonImplicitClosureFunction()) {
-    RawFunction* parent_function = func.parent_function();
+    FunctionPtr parent_function = func.parent_function();
     return Api::NewHandle(T, parent_function);
   }
   const Class& owner = Class::Handle(Z, func.Owner());
@@ -2490,7 +2515,7 @@
 
   ASSERT(ClassFinalizer::AllClassesFinalized());
 
-  RawFunction* rf = Closure::Cast(closure_obj).function();
+  FunctionPtr rf = Closure::Cast(closure_obj).function();
   return Api::NewHandle(T, rf);
 }
 
@@ -2582,7 +2607,7 @@
   CHECK_CALLBACK_STATE(T);
   API_TIMELINE_DURATION(T);
   const String& str_obj = String::Handle(Z, String::New(str));
-  RawInteger* integer = Integer::New(str_obj);
+  IntegerPtr integer = Integer::New(str_obj);
   if (integer == Integer::null()) {
     return Api::NewError("%s: Cannot create Dart integer from string %s",
                          CURRENT_FUNC, str);
@@ -2708,7 +2733,7 @@
     return Api::NewError("function_name must refer to a static method.");
   }
 
-  if (func.kind() != RawFunction::kRegularFunction) {
+  if (func.kind() != FunctionLayout::kRegularFunction) {
     return Api::NewError(
         "function_name must be the name of a regular function.");
   }
@@ -2996,7 +3021,7 @@
   return Dart_NewListOf(Dart_CoreType_Dynamic, length);
 }
 
-static RawTypeArguments* TypeArgumentsForElementType(
+static TypeArgumentsPtr TypeArgumentsForElementType(
     ObjectStore* store,
     Dart_CoreType_Id element_type_id) {
   switch (element_type_id) {
@@ -3296,13 +3321,13 @@
   }
 }
 
-static RawObject* ResolveConstructor(const char* current_func,
-                                     const Class& cls,
-                                     const String& class_name,
-                                     const String& dotted_name,
-                                     int num_args);
+static ObjectPtr ResolveConstructor(const char* current_func,
+                                    const Class& cls,
+                                    const String& class_name,
+                                    const String& dotted_name,
+                                    int num_args);
 
-static RawObject* ThrowArgumentError(const char* exception_message) {
+static ObjectPtr ThrowArgumentError(const char* exception_message) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   // Lookup the class ArgumentError in dart:core.
@@ -3353,7 +3378,7 @@
   const Instance* saved_exception;
   {
     NoSafepointScope no_safepoint;
-    RawInstance* raw_exception = exception.raw();
+    InstancePtr raw_exception = exception.raw();
     thread->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
@@ -3420,7 +3445,7 @@
       return CopyBytes(external_array, offset, native_array, length);
     }
   }
-  if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) {
+  if (IsTypedDataViewClassId(obj.GetClassId())) {
     const auto& view = TypedDataView::Cast(obj);
     if (view.ElementSizeInBytes() == 1) {
       const intptr_t view_length = Smi::Value(view.length());
@@ -3706,8 +3731,7 @@
   API_TIMELINE_DURATION(thread);
   TransitionNativeToVM transition(thread);
   intptr_t class_id = Api::ClassId(object);
-  if (RawObject::IsTypedDataClassId(class_id) ||
-      RawObject::IsTypedDataViewClassId(class_id)) {
+  if (IsTypedDataClassId(class_id) || IsTypedDataViewClassId(class_id)) {
     return GetType(class_id);
   }
   return Dart_TypedData_kInvalid;
@@ -3719,10 +3743,10 @@
   API_TIMELINE_DURATION(thread);
   TransitionNativeToVM transition(thread);
   intptr_t class_id = Api::ClassId(object);
-  if (RawObject::IsExternalTypedDataClassId(class_id)) {
+  if (IsExternalTypedDataClassId(class_id)) {
     return GetType(class_id);
   }
-  if (RawObject::IsTypedDataViewClassId(class_id)) {
+  if (IsTypedDataViewClassId(class_id)) {
     // Check if data object of the view is external.
     Zone* zone = thread->zone();
     const auto& view_obj = Api::UnwrapTypedDataViewHandle(zone, object);
@@ -3735,9 +3759,9 @@
   return Dart_TypedData_kInvalid;
 }
 
-static RawObject* GetByteDataConstructor(Thread* thread,
-                                         const String& constructor_name,
-                                         intptr_t num_args) {
+static ObjectPtr GetByteDataConstructor(Thread* thread,
+                                        const String& constructor_name,
+                                        intptr_t num_args) {
   const Library& lib =
       Library::Handle(thread->isolate()->object_store()->typed_data_library());
   ASSERT(!lib.IsNull());
@@ -3958,10 +3982,10 @@
   return Api::Null();
 }
 
-static RawObject* GetByteBufferConstructor(Thread* thread,
-                                           const String& class_name,
-                                           const String& constructor_name,
-                                           intptr_t num_args) {
+static ObjectPtr GetByteBufferConstructor(Thread* thread,
+                                          const String& class_name,
+                                          const String& constructor_name,
+                                          intptr_t num_args) {
   const Library& lib =
       Library::Handle(thread->isolate()->object_store()->typed_data_library());
   ASSERT(!lib.IsNull());
@@ -3975,9 +3999,8 @@
 DART_EXPORT Dart_Handle Dart_NewByteBuffer(Dart_Handle typed_data) {
   DARTSCOPE(Thread::Current());
   intptr_t class_id = Api::ClassId(typed_data);
-  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
-      !RawObject::IsTypedDataViewClassId(class_id) &&
-      !RawObject::IsTypedDataClassId(class_id)) {
+  if (!IsExternalTypedDataClassId(class_id) &&
+      !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id)) {
     RETURN_TYPE_ERROR(Z, typed_data, 'TypedData');
   }
   Object& result = Object::Handle(Z);
@@ -4040,9 +4063,8 @@
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   intptr_t class_id = Api::ClassId(object);
-  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
-      !RawObject::IsTypedDataViewClassId(class_id) &&
-      !RawObject::IsTypedDataClassId(class_id)) {
+  if (!IsExternalTypedDataClassId(class_id) &&
+      !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id)) {
     RETURN_TYPE_ERROR(Z, object, 'TypedData');
   }
   if (type == NULL) {
@@ -4062,7 +4084,7 @@
   bool external = false;
   T->IncrementNoSafepointScopeDepth();
   START_NO_CALLBACK_SCOPE(T);
-  if (RawObject::IsExternalTypedDataClassId(class_id)) {
+  if (IsExternalTypedDataClassId(class_id)) {
     const ExternalTypedData& obj =
         Api::UnwrapExternalTypedDataHandle(Z, object);
     ASSERT(!obj.IsNull());
@@ -4070,14 +4092,14 @@
     size_in_bytes = length * ExternalTypedData::ElementSizeInBytes(class_id);
     data_tmp = obj.DataAddr(0);
     external = true;
-  } else if (RawObject::IsTypedDataClassId(class_id)) {
+  } else if (IsTypedDataClassId(class_id)) {
     const TypedData& obj = Api::UnwrapTypedDataHandle(Z, object);
     ASSERT(!obj.IsNull());
     length = obj.Length();
     size_in_bytes = length * TypedData::ElementSizeInBytes(class_id);
     data_tmp = obj.DataAddr(0);
   } else {
-    ASSERT(RawObject::IsTypedDataViewClassId(class_id));
+    ASSERT(IsTypedDataViewClassId(class_id));
     const auto& view_obj = Api::UnwrapTypedDataViewHandle(Z, object);
     ASSERT(!view_obj.IsNull());
     Smi& val = Smi::Handle();
@@ -4125,9 +4147,8 @@
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   intptr_t class_id = Api::ClassId(object);
-  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
-      !RawObject::IsTypedDataViewClassId(class_id) &&
-      !RawObject::IsTypedDataClassId(class_id)) {
+  if (!IsExternalTypedDataClassId(class_id) &&
+      !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id)) {
     RETURN_TYPE_ERROR(Z, object, 'TypedData');
   }
   T->DecrementNoSafepointScopeDepth();
@@ -4163,11 +4184,11 @@
 
 // ---  Invoking Constructors, Methods, and Field accessors ---
 
-static RawObject* ResolveConstructor(const char* current_func,
-                                     const Class& cls,
-                                     const String& class_name,
-                                     const String& constr_name,
-                                     int num_args) {
+static ObjectPtr ResolveConstructor(const char* current_func,
+                                    const Class& cls,
+                                    const String& class_name,
+                                    const String& constr_name,
+                                    int num_args) {
   // The constructor must be present in the interface.
   const Function& constructor =
       Function::Handle(cls.LookupFunctionAllowPrivate(constr_name));
@@ -4202,7 +4223,7 @@
         current_func, constr_name.ToCString(), error_message.ToCString()));
     return ApiError::New(message);
   }
-  RawError* error = constructor.VerifyCallEntryPoint();
+  ErrorPtr error = constructor.VerifyCallEntryPoint();
   if (error != Error::null()) return error;
   return constructor.raw();
 }
@@ -4344,7 +4365,7 @@
   return Api::NewHandle(T, new_object.raw());
 }
 
-static RawInstance* AllocateObject(Thread* thread, const Class& cls) {
+static InstancePtr AllocateObject(Thread* thread, const Class& cls) {
   if (!cls.is_fields_marked_nullable()) {
     // Mark all fields as nullable.
     Zone* zone = thread->zone();
@@ -4820,7 +4841,7 @@
   const Instance* saved_exception;
   {
     NoSafepointScope no_safepoint;
-    RawInstance* raw_exception =
+    InstancePtr raw_exception =
         Api::UnwrapInstanceHandle(zone, exception).raw();
     thread->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
@@ -4858,9 +4879,9 @@
   const StackTrace* saved_stacktrace;
   {
     NoSafepointScope no_safepoint;
-    RawInstance* raw_exception =
+    InstancePtr raw_exception =
         Api::UnwrapInstanceHandle(zone, exception).raw();
-    RawStackTrace* raw_stacktrace =
+    StackTracePtr raw_stacktrace =
         Api::UnwrapStackTraceHandle(zone, stacktrace).raw();
     thread->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
@@ -5221,7 +5242,7 @@
 }
 
 // --- Environment ---
-RawString* Api::GetEnvironmentValue(Thread* thread, const String& name) {
+StringPtr Api::GetEnvironmentValue(Thread* thread, const String& name) {
   String& result = String::Handle(CallEnvironmentCallback(thread, name));
   if (result.IsNull()) {
     // Every 'dart:X' library introduces an environment variable
@@ -5283,7 +5304,7 @@
   return result.raw();
 }
 
-RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) {
+StringPtr Api::CallEnvironmentCallback(Thread* thread, const String& name) {
   Isolate* isolate = thread->isolate();
   Dart_EnvironmentCallback callback = isolate->environment_callback();
   if (callback != NULL) {
@@ -5414,6 +5435,18 @@
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
+  if (I->is_service_isolate() || I->is_kernel_isolate()) {
+    // For now the service isolate and kernel isolate will be running in
+    // weak mode and we assert for that here.
+    ASSERT(!I->null_safety());
+  } else {
+    // If null safety is not specified on the command line we use the value
+    // from the dill file that the CFE has computed based on how it was invoked.
+    if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
+      I->set_null_safety(program->compilation_mode() ==
+                         NNBDCompiledMode::kStrong);
+    }
+  }
   const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
   program.reset();
 
@@ -5714,6 +5747,7 @@
   DARTSCOPE(Thread::Current());
   API_TIMELINE_DURATION(T);
   StackZone zone(T);
+  Isolate* I = T->isolate();
 
   CHECK_CALLBACK_STATE(T);
 
@@ -5730,6 +5764,18 @@
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
+  if (I->is_service_isolate() || I->is_kernel_isolate()) {
+    // For now the service isolate and kernel isolate will be running in
+    // weak mode and we assert for that here.
+    ASSERT(!I->null_safety());
+  } else {
+    // If null safety is not specified on the command line we use the value
+    // from the dill file that the CFE has computed based on how it was invoked.
+    if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
+      I->set_null_safety(program->compilation_mode() ==
+                         NNBDCompiledMode::kStrong);
+    }
+  }
   const Object& result =
       kernel::KernelLoader::LoadEntireProgram(program.get(), false);
   program.reset();
@@ -5882,7 +5928,7 @@
   }
   {
     NoSafepointScope no_safepoint;
-    RawObject* raw_obj = obj.raw();
+    ObjectPtr raw_obj = obj.raw();
     *peer = thread->isolate()->heap()->GetPeer(raw_obj);
   }
   return Api::Success();
@@ -5902,7 +5948,7 @@
   }
   {
     NoSafepointScope no_safepoint;
-    RawObject* raw_obj = obj.raw();
+    ObjectPtr raw_obj = obj.raw();
     thread->isolate()->heap()->SetPeer(raw_obj, peer);
   }
   return Api::Success();
@@ -6270,7 +6316,7 @@
   CHECK_NULL(buffer);
   CHECK_NULL(buffer_length);
   CompilationTraceSaver saver(thread->zone());
-  ProgramVisitor::VisitFunctions(&saver);
+  ProgramVisitor::WalkProgram(thread->zone(), thread->isolate(), &saver);
   saver.StealBuffer(buffer, buffer_length);
   return Api::Success();
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
@@ -6292,7 +6338,7 @@
   saver.WriteHeader();
   saver.SaveClasses();
   saver.SaveFields();
-  ProgramVisitor::VisitFunctions(&saver);
+  ProgramVisitor::WalkProgram(thread->zone(), thread->isolate(), &saver);
   *buffer_length = stream.bytes_written();
 
   return Api::Success();
@@ -6501,6 +6547,12 @@
   // loader. See also Elf::WriteProgramTable().
   const intptr_t bss_base =
       elf->AddBSSData("_kDartBSSData", sizeof(compiler::target::uword));
+  // Add the BSS section to the separately saved debugging information, even
+  // though there will be no code in it to relocate, since it precedes the
+  // .text sections and thus affects their virtual addresses.
+  if (debug_dwarf != nullptr) {
+    debug_elf->AddBSSData("_kDartBSSData", sizeof(compiler::target::uword));
+  }
 
   BlobImageWriter vm_image_writer(T, &vm_snapshot_instructions_buffer,
                                   ApiReallocate, kInitialSize, debug_dwarf,
@@ -6612,7 +6664,7 @@
   BackgroundCompiler::Stop(I);
   DropRegExpMatchCode(Z);
 
-  ProgramVisitor::Dedup();
+  ProgramVisitor::Dedup(T);
   Symbols::Compact();
 
   TIMELINE_DURATION(T, Isolate, "WriteCoreJITSnapshot");
@@ -6688,7 +6740,7 @@
   BackgroundCompiler::Stop(I);
   DropRegExpMatchCode(Z);
 
-  ProgramVisitor::Dedup();
+  ProgramVisitor::Dedup(T);
   Symbols::Compact();
 
   if (FLAG_dump_tables) {
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 65ed764..80f0462 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -156,10 +156,10 @@
   };
 
   // Creates a new local handle.
-  static Dart_Handle NewHandle(Thread* thread, RawObject* raw);
+  static Dart_Handle NewHandle(Thread* thread, ObjectPtr raw);
 
   // Unwraps the raw object from the handle.
-  static RawObject* UnwrapHandle(Dart_Handle object);
+  static ObjectPtr UnwrapHandle(Dart_Handle object);
 
 // Unwraps a raw Type from the handle.  The handle will be null if
 // the object was not of the requested Type.
@@ -198,7 +198,7 @@
   static bool IsSmi(Dart_Handle handle) {
     // Important: we do not require current thread to be in VM state because
     // we do not dereference the handle.
-    RawObject* raw = *(reinterpret_cast<RawObject**>(handle));
+    ObjectPtr raw = *(reinterpret_cast<ObjectPtr*>(handle));
     return !raw->IsHeapObject();
   }
 
@@ -206,8 +206,8 @@
   static intptr_t SmiValue(Dart_Handle handle) {
     // Important: we do not require current thread to be in VM state because
     // we do not dereference the handle.
-    RawObject* value = *(reinterpret_cast<RawObject**>(handle));
-    return Smi::Value(static_cast<RawSmi*>(value));
+    ObjectPtr value = *(reinterpret_cast<ObjectPtr*>(handle));
+    return Smi::Value(static_cast<SmiPtr>(value));
   }
 
   // Returns true if the handle holds a Dart Instance.
@@ -220,11 +220,11 @@
 
   // Returns true if the handle holds an Error.
   static bool IsError(Dart_Handle handle) {
-    return RawObject::IsErrorClassId(ClassId(handle));
+    return IsErrorClassId(ClassId(handle));
   }
 
   static intptr_t ClassId(Dart_Handle handle) {
-    RawObject* raw = UnwrapHandle(handle);
+    ObjectPtr raw = UnwrapHandle(handle);
     if (!raw->IsHeapObject()) {
       return kSmiCid;
     }
@@ -305,7 +305,7 @@
   static void SetWeakHandleReturnValue(NativeArguments* args,
                                        Dart_WeakPersistentHandle retval);
 
-  static RawString* GetEnvironmentValue(Thread* thread, const String& name);
+  static StringPtr GetEnvironmentValue(Thread* thread, const String& name);
 
   static bool IsFfiEnabled() {
 #if defined(TAGET_OS_FUCHSIA)
@@ -316,9 +316,9 @@
   }
 
  private:
-  static Dart_Handle InitNewHandle(Thread* thread, RawObject* raw);
+  static Dart_Handle InitNewHandle(Thread* thread, ObjectPtr raw);
 
-  static RawString* CallEnvironmentCallback(Thread* thread, const String& name);
+  static StringPtr CallEnvironmentCallback(Thread* thread, const String& name);
 
   // Thread local key used by the API. Currently holds the current
   // ApiNativeScope if any.
@@ -353,6 +353,9 @@
 Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
                                           const char* name,
                                           char** error);
+Isolate* CreateWithinExistingIsolateGroupAOT(IsolateGroup* group,
+                                             const char* name,
+                                             char** error);
 
 }  // namespace dart.
 
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index c82582f..4f1551d 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3373,6 +3373,7 @@
     weak2 = Dart_NewWeakPersistentHandle(obj, NULL, kWeak2ExternalSize,
                                          NopCallback);
     EXPECT_VALID(AsHandle(strong_ref));
+    EXPECT_VALID(AsHandle(weak2));
     Dart_ExitScope();
   }
   {
@@ -4495,7 +4496,7 @@
   // (1 + 2) * kWordSize + size of object header.
   // We check to make sure the instance size computed by the VM matches
   // our expectations.
-  intptr_t header_size = sizeof(RawObject);
+  intptr_t header_size = sizeof(ObjectLayout);
   EXPECT_EQ(
       Utils::RoundUp(((1 + 2) * kWordSize) + header_size, kObjectAlignment),
       cls.host_instance_size());
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 6ac1947..639270c 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -15,7 +15,8 @@
 static const int kNumInitialReferences = 4;
 
 ApiMessageReader::ApiMessageReader(Message* msg)
-    : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(msg->raw_obj())
+    : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(
+                                    static_cast<uword>(msg->raw_obj()))
                               : msg->snapshot(),
                  msg->snapshot_length()),
       zone_(NULL),
@@ -49,8 +50,8 @@
     // Read the object out of the message.
     return ReadObject();
   } else {
-    const RawObject* raw_obj =
-        reinterpret_cast<const RawObject*>(CurrentBufferAddress());
+    const ObjectPtr raw_obj = static_cast<const ObjectPtr>(
+        reinterpret_cast<uword>(CurrentBufferAddress()));
     ASSERT(ApiObjectConverter::CanConvert(raw_obj));
     Dart_CObject* cobj =
         reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject)));
@@ -185,11 +186,11 @@
 }
 
 Dart_CObject* ApiMessageReader::AllocateDartCObjectVmIsolateObj(intptr_t id) {
-  RawObject* raw = VmIsolateSnapshotObject(id);
+  ObjectPtr raw = VmIsolateSnapshotObject(id);
   intptr_t cid = raw->GetClassId();
   switch (cid) {
     case kOneByteStringCid: {
-      RawOneByteString* raw_str = reinterpret_cast<RawOneByteString*>(raw);
+      OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
       const char* str = reinterpret_cast<const char*>(raw_str->ptr()->data());
       ASSERT(str != NULL);
       Dart_CObject* object = NULL;
@@ -207,7 +208,7 @@
     }
 
     case kMintCid: {
-      const Mint& obj = Mint::Handle(reinterpret_cast<RawMint*>(raw));
+      const Mint& obj = Mint::Handle(static_cast<MintPtr>(raw));
       int64_t value64 = obj.value();
       if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) {
         return GetCanonicalMintObject(Dart_CObject_kInt32, value64);
@@ -323,9 +324,9 @@
   return backward_references_.length() + kMaxPredefinedObjectIds;
 }
 
-Dart_CObject* ApiMessageReader::CreateDartCObjectString(RawObject* raw) {
-  ASSERT(RawObject::IsOneByteStringClassId(raw->GetClassId()));
-  RawOneByteString* raw_str = reinterpret_cast<RawOneByteString*>(raw);
+Dart_CObject* ApiMessageReader::CreateDartCObjectString(ObjectPtr raw) {
+  ASSERT(IsOneByteStringClassId(raw->GetClassId()));
+  OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
   intptr_t len = Smi::Value(raw_str->ptr()->length_);
   Dart_CObject* object = AllocateDartCObjectString(len);
   char* p = object->value.as_string;
@@ -848,7 +849,7 @@
 
 void ApiMessageWriter::WriteSmi(int64_t value) {
   ASSERT(Smi::IsValid(value));
-  Write<RawObject*>(Smi::New(static_cast<intptr_t>(value)));
+  Write<ObjectPtr>(Smi::New(static_cast<intptr_t>(value)));
 }
 
 void ApiMessageWriter::WriteNullObject() {
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index 92a9a85..aa80031 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -128,11 +128,11 @@
     return reinterpret_cast<Dart_CObject_Internal*>(object);
   }
 
-  RawObject* VmIsolateSnapshotObject(intptr_t index) const {
+  ObjectPtr VmIsolateSnapshotObject(intptr_t index) const {
     return Object::vm_isolate_snapshot_object_table().At(index);
   }
 
-  Dart_CObject* CreateDartCObjectString(RawObject* raw);
+  Dart_CObject* CreateDartCObjectString(ObjectPtr raw);
   Dart_CObject* GetCanonicalMintObject(Dart_CObject_Type type, int64_t value64);
 
   uint8_t* allocator(intptr_t size) {
@@ -203,13 +203,13 @@
 // as well.
 class ApiObjectConverter : public AllStatic {
  public:
-  static bool CanConvert(const RawObject* raw_obj) {
+  static bool CanConvert(const ObjectPtr raw_obj) {
     return !raw_obj->IsHeapObject() || (raw_obj == Object::null());
   }
 
-  static bool Convert(const RawObject* raw_obj, Dart_CObject* c_obj) {
+  static bool Convert(const ObjectPtr raw_obj, Dart_CObject* c_obj) {
     if (!raw_obj->IsHeapObject()) {
-      ConvertSmi(reinterpret_cast<const RawSmi*>(raw_obj), c_obj);
+      ConvertSmi(static_cast<const SmiPtr>(raw_obj), c_obj);
     } else if (raw_obj == Object::null()) {
       ConvertNull(c_obj);
     } else {
@@ -219,7 +219,7 @@
   }
 
  private:
-  static void ConvertSmi(const RawSmi* raw_smi, Dart_CObject* c_obj) {
+  static void ConvertSmi(const SmiPtr raw_smi, Dart_CObject* c_obj) {
     ASSERT(!raw_smi->IsHeapObject());
     intptr_t value = Smi::Value(raw_smi);
     if (Utils::IsInt(31, value)) {
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index 3e48e72..a986121 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -127,8 +127,8 @@
 class LocalHandle {
  public:
   // Accessors.
-  RawObject* raw() const { return raw_; }
-  void set_raw(RawObject* raw) { raw_ = raw; }
+  ObjectPtr raw() const { return raw_; }
+  void set_raw(ObjectPtr raw) { raw_ = raw; }
   static intptr_t raw_offset() { return OFFSET_OF(LocalHandle, raw_); }
 
   Dart_Handle apiHandle() { return reinterpret_cast<Dart_Handle>(this); }
@@ -137,7 +137,7 @@
   LocalHandle() {}
   ~LocalHandle() {}
 
-  RawObject* raw_;
+  ObjectPtr raw_;
   DISALLOW_ALLOCATION();  // Allocated through AllocateHandle methods.
   DISALLOW_COPY_AND_ASSIGN(LocalHandle);
 };
@@ -151,11 +151,11 @@
 class PersistentHandle {
  public:
   // Accessors.
-  RawObject* raw() const { return raw_; }
-  void set_raw(RawObject* ref) { raw_ = ref; }
+  ObjectPtr raw() const { return raw_; }
+  void set_raw(ObjectPtr ref) { raw_ = ref; }
   void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
   void set_raw(const Object& object) { raw_ = object.raw(); }
-  RawObject** raw_addr() { return &raw_; }
+  ObjectPtr* raw_addr() { return &raw_; }
   Dart_PersistentHandle apiHandle() {
     return reinterpret_cast<Dart_PersistentHandle>(this);
   }
@@ -172,14 +172,16 @@
 
   // Overload the raw_ field as a next pointer when adding freed
   // handles to the free list.
-  PersistentHandle* Next() { return reinterpret_cast<PersistentHandle*>(raw_); }
+  PersistentHandle* Next() {
+    return reinterpret_cast<PersistentHandle*>(static_cast<uword>(raw_));
+  }
   void SetNext(PersistentHandle* free_list) {
-    raw_ = reinterpret_cast<RawObject*>(free_list);
+    raw_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
     ASSERT(!raw_->IsHeapObject());
   }
   void FreeHandle(PersistentHandle* free_list) { SetNext(free_list); }
 
-  RawObject* raw_;
+  ObjectPtr raw_;
   DISALLOW_ALLOCATION();  // Allocated through AllocateHandle methods.
   DISALLOW_COPY_AND_ASSIGN(PersistentHandle);
 };
@@ -196,8 +198,8 @@
       intptr_t external_size);
 
   // Accessors.
-  RawObject* raw() const { return raw_; }
-  RawObject** raw_addr() { return &raw_; }
+  ObjectPtr raw() const { return raw_; }
+  ObjectPtr* raw_addr() { return &raw_; }
   static intptr_t raw_offset() {
     return OFFSET_OF(FinalizablePersistentHandle, raw_);
   }
@@ -265,7 +267,7 @@
   friend class FinalizablePersistentHandles;
 
   FinalizablePersistentHandle()
-      : raw_(NULL), peer_(NULL), external_data_(0), callback_(NULL) {}
+      : raw_(nullptr), peer_(NULL), external_data_(0), callback_(NULL) {}
   ~FinalizablePersistentHandle() {}
 
   static void Finalize(IsolateGroup* isolate_group,
@@ -274,10 +276,11 @@
   // Overload the raw_ field as a next pointer when adding freed
   // handles to the free list.
   FinalizablePersistentHandle* Next() {
-    return reinterpret_cast<FinalizablePersistentHandle*>(raw_);
+    return reinterpret_cast<FinalizablePersistentHandle*>(
+        static_cast<uword>(raw_));
   }
   void SetNext(FinalizablePersistentHandle* free_list) {
-    raw_ = reinterpret_cast<RawObject*>(free_list);
+    raw_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
     ASSERT(!raw_->IsHeapObject());
   }
   void FreeHandle(FinalizablePersistentHandle* free_list) {
@@ -292,7 +295,7 @@
     callback_ = NULL;
   }
 
-  void set_raw(RawObject* raw) { raw_ = raw; }
+  void set_raw(ObjectPtr raw) { raw_ = raw; }
   void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
   void set_raw(const Object& object) { raw_ = object.raw(); }
 
@@ -327,7 +330,7 @@
     return raw_->IsSmiOrOldObject() ? Heap::kOld : Heap::kNew;
   }
 
-  RawObject* raw_;
+  ObjectPtr raw_;
   void* peer_;
   uword external_data_;
   Dart_WeakPersistentHandleFinalizer callback_;
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 42d53be..bb992b5 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -6,8 +6,6 @@
 
 #include "platform/safe_stack.h"
 #include "vm/class_finalizer.h"
-#include "vm/compiler/frontend/bytecode_reader.h"
-#include "vm/compiler/jit/compiler.h"
 #include "vm/debugger.h"
 #include "vm/dispatch_table.h"
 #include "vm/heap/safepoint.h"
@@ -19,16 +17,21 @@
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/frontend/bytecode_reader.h"
+#include "vm/compiler/jit/compiler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DECLARE_FLAG(bool, enable_interpreter);
 DECLARE_FLAG(bool, precompiled_mode);
 
 // A cache of VM heap allocated arguments descriptors.
-RawArray* ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
+ArrayPtr ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
 
-RawObject* DartEntry::InvokeFunction(const Function& function,
-                                     const Array& arguments) {
+ObjectPtr DartEntry::InvokeFunction(const Function& function,
+                                    const Array& arguments) {
   ASSERT(Thread::Current()->IsMutatorThread());
   const int kTypeArgsLen = 0;  // No support to pass type args to generic func.
   const Array& arguments_descriptor = Array::Handle(
@@ -96,10 +99,10 @@
   LongJumpScope* saved_long_jump_base_;
 };
 
-RawObject* DartEntry::InvokeFunction(const Function& function,
-                                     const Array& arguments,
-                                     const Array& arguments_descriptor,
-                                     uword current_sp) {
+ObjectPtr DartEntry::InvokeFunction(const Function& function,
+                                    const Array& arguments,
+                                    const Array& arguments_descriptor,
+                                    uword current_sp) {
   // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation
   // and never start the VM service isolate. So we should never end up invoking
   // any dart code in the Dart 2.0 AOT compiler.
@@ -133,7 +136,7 @@
   if (!function.HasCode()) {
     if (FLAG_enable_interpreter && function.IsBytecodeAllowed(zone)) {
       if (!function.HasBytecode()) {
-        RawError* error =
+        ErrorPtr error =
             kernel::BytecodeReader::ReadFunctionBytecode(thread, function);
         if (error != Error::null()) {
           return error;
@@ -168,11 +171,21 @@
   return InvokeCode(code, arguments_descriptor, arguments, thread);
 }
 
+extern "C" {
+// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct
+// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is
+// passed/returned different from a pointer.
+typedef uword /*ObjectPtr*/ (*invokestub)(const Code& target_code,
+                                          const Array& arguments_descriptor,
+                                          const Array& arguments,
+                                          Thread* thread);
+}
+
 NO_SANITIZE_SAFE_STACK
-RawObject* DartEntry::InvokeCode(const Code& code,
-                                 const Array& arguments_descriptor,
-                                 const Array& arguments,
-                                 Thread* thread) {
+ObjectPtr DartEntry::InvokeCode(const Code& code,
+                                const Array& arguments_descriptor,
+                                const Array& arguments,
+                                Thread* thread) {
   ASSERT(!code.IsNull());
   ASSERT(thread->no_callback_scope_depth() == 0);
 
@@ -181,17 +194,18 @@
   SuspendLongJumpScope suspend_long_jump_scope(thread);
   TransitionToGenerated transition(thread);
 #if defined(USING_SIMULATOR)
-  return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
+  return bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
       reinterpret_cast<intptr_t>(entrypoint), reinterpret_cast<intptr_t>(&code),
       reinterpret_cast<intptr_t>(&arguments_descriptor),
       reinterpret_cast<intptr_t>(&arguments),
       reinterpret_cast<intptr_t>(thread)));
 #else
-  return entrypoint(code, arguments_descriptor, arguments, thread);
+  return static_cast<ObjectPtr>(
+      entrypoint(code, arguments_descriptor, arguments, thread));
 #endif
 }
 
-RawObject* DartEntry::InvokeClosure(const Array& arguments) {
+ObjectPtr DartEntry::InvokeClosure(const Array& arguments) {
   const int kTypeArgsLen = 0;  // No support to pass type args to generic func.
 
   // Closures always have boxed parameters
@@ -200,8 +214,8 @@
   return InvokeClosure(arguments, arguments_descriptor);
 }
 
-RawObject* DartEntry::InvokeClosure(const Array& arguments,
-                                    const Array& arguments_descriptor) {
+ObjectPtr DartEntry::InvokeClosure(const Array& arguments,
+                                   const Array& arguments_descriptor) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const ArgumentsDescriptor args_desc(arguments_descriptor);
@@ -266,10 +280,10 @@
                             arguments_descriptor);
 }
 
-RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver,
-                                         const String& target_name,
-                                         const Array& arguments,
-                                         const Array& arguments_descriptor) {
+ObjectPtr DartEntry::InvokeNoSuchMethod(const Instance& receiver,
+                                        const String& target_name,
+                                        const Array& arguments,
+                                        const Array& arguments_descriptor) {
   const ArgumentsDescriptor args_desc(arguments_descriptor);
   ASSERT(receiver.raw() == arguments.At(args_desc.FirstArgIndex()));
   // Allocate an Invocation object.
@@ -337,7 +351,7 @@
   return Smi::Value(Smi::RawCast(array_.At(kPositionalCountIndex)));
 }
 
-RawString* ArgumentsDescriptor::NameAt(intptr_t index) const {
+StringPtr ArgumentsDescriptor::NameAt(intptr_t index) const {
   const intptr_t offset =
       kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
   String& result = String::Handle();
@@ -356,7 +370,7 @@
   return NameAt(index) == other.raw();
 }
 
-RawArray* ArgumentsDescriptor::GetArgumentNames() const {
+ArrayPtr ArgumentsDescriptor::GetArgumentNames() const {
   const intptr_t num_named_args = NamedCount();
   if (num_named_args == 0) {
     return Array::null();
@@ -376,11 +390,11 @@
   return names.raw();
 }
 
-RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
-                                   intptr_t num_arguments,
-                                   intptr_t size_arguments,
-                                   const Array& optional_arguments_names,
-                                   Heap::Space space) {
+ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
+                                  intptr_t num_arguments,
+                                  intptr_t size_arguments,
+                                  const Array& optional_arguments_names,
+                                  Heap::Space space) {
   const intptr_t num_named_args =
       optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
   if (num_named_args == 0) {
@@ -450,10 +464,10 @@
   return descriptor.raw();
 }
 
-RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
-                                   intptr_t num_arguments,
-                                   intptr_t size_arguments,
-                                   Heap::Space space) {
+ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
+                                  intptr_t num_arguments,
+                                  intptr_t size_arguments,
+                                  Heap::Space space) {
   ASSERT(type_args_len >= 0);
   ASSERT(num_arguments >= 0);
 
@@ -465,11 +479,11 @@
                       space);
 }
 
-RawArray* ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
-                                            intptr_t num_arguments,
-                                            intptr_t size_arguments,
-                                            bool canonicalize,
-                                            Heap::Space space) {
+ArrayPtr ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
+                                           intptr_t num_arguments,
+                                           intptr_t size_arguments,
+                                           bool canonicalize,
+                                           Heap::Space space) {
   // Build the arguments descriptor array, which consists of the length of the
   // type argument vector, total argument count; the positional argument count;
   // and a terminating null to simplify iterating in generated code.
@@ -523,10 +537,10 @@
   }
 }
 
-RawObject* DartLibraryCalls::InstanceCreate(const Library& lib,
-                                            const String& class_name,
-                                            const String& constructor_name,
-                                            const Array& arguments) {
+ObjectPtr DartLibraryCalls::InstanceCreate(const Library& lib,
+                                           const String& class_name,
+                                           const String& constructor_name,
+                                           const Array& arguments) {
   const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
   ASSERT(!cls.IsNull());
   // For now, we only support a non-parameterized or raw type.
@@ -555,7 +569,7 @@
   return exception_object.raw();
 }
 
-RawObject* DartLibraryCalls::ToString(const Instance& receiver) {
+ObjectPtr DartLibraryCalls::ToString(const Instance& receiver) {
   const int kTypeArgsLen = 0;
   const int kNumArguments = 1;  // Receiver.
   ArgumentsDescriptor args_desc(Array::Handle(
@@ -571,7 +585,7 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::HashCode(const Instance& receiver) {
+ObjectPtr DartLibraryCalls::HashCode(const Instance& receiver) {
   const int kTypeArgsLen = 0;
   const int kNumArguments = 1;  // Receiver.
   ArgumentsDescriptor args_desc(Array::Handle(
@@ -587,8 +601,8 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::Equals(const Instance& left,
-                                    const Instance& right) {
+ObjectPtr DartLibraryCalls::Equals(const Instance& left,
+                                   const Instance& right) {
   const int kTypeArgsLen = 0;
   const int kNumArguments = 2;
   ArgumentsDescriptor args_desc(Array::Handle(
@@ -607,7 +621,7 @@
 }
 
 // On success, returns a RawInstance.  On failure, a RawError.
-RawObject* DartLibraryCalls::IdentityHashCode(const Instance& object) {
+ObjectPtr DartLibraryCalls::IdentityHashCode(const Instance& object) {
   const int kNumArguments = 1;
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -624,7 +638,7 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::LookupHandler(Dart_Port port_id) {
+ObjectPtr DartLibraryCalls::LookupHandler(Dart_Port port_id) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Function& function = Function::Handle(
@@ -651,8 +665,8 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::HandleMessage(const Object& handler,
-                                           const Instance& message) {
+ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
+                                          const Instance& message) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -690,7 +704,7 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::DrainMicrotaskQueue() {
+ObjectPtr DartLibraryCalls::DrainMicrotaskQueue() {
   Zone* zone = Thread::Current()->zone();
   Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
   ASSERT(!isolate_lib.IsNull());
@@ -703,7 +717,7 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::EnsureScheduleImmediate() {
+ObjectPtr DartLibraryCalls::EnsureScheduleImmediate() {
   Zone* zone = Thread::Current()->zone();
   const Library& async_lib = Library::Handle(zone, Library::AsyncLibrary());
   ASSERT(!async_lib.IsNull());
@@ -717,9 +731,9 @@
   return result.raw();
 }
 
-RawObject* DartLibraryCalls::MapSetAt(const Instance& map,
-                                      const Instance& key,
-                                      const Instance& value) {
+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(
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index e93c991..9ab0115 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -20,10 +20,6 @@
 class Integer;
 class Library;
 class Object;
-class RawArray;
-class RawInstance;
-class RawObject;
-class RawString;
 class String;
 
 // An arguments descriptor array consists of the type argument vector length (0
@@ -45,11 +41,11 @@
   intptr_t SizeWithTypeArgs() const { return FirstArgIndex() + Size(); }
   intptr_t PositionalCount() const;  // Excluding type arguments vector.
   intptr_t NamedCount() const { return Count() - PositionalCount(); }
-  RawString* NameAt(intptr_t i) const;
+  StringPtr NameAt(intptr_t i) const;
   intptr_t PositionAt(intptr_t i) const;
   bool MatchesNameAt(intptr_t i, const String& other) const;
   // Returns array of argument names in the arguments order.
-  RawArray* GetArgumentNames() const;
+  ArrayPtr GetArgumentNames() const;
 
   // Generated code support.
   static intptr_t type_args_len_offset() {
@@ -78,10 +74,10 @@
   // Right now this is for example the case for all closure functions.
   // Functions marked as entry-points may also be created by NewUnboxed because
   // we rely that TFA will mark the arguments as nullable for such cases.
-  static RawArray* NewBoxed(intptr_t type_args_len,
-                            intptr_t num_arguments,
-                            const Array& optional_arguments_names,
-                            Heap::Space space = Heap::kOld) {
+  static ArrayPtr NewBoxed(intptr_t type_args_len,
+                           intptr_t num_arguments,
+                           const Array& optional_arguments_names,
+                           Heap::Space space = Heap::kOld) {
     return New(type_args_len, num_arguments, num_arguments,
                optional_arguments_names, space);
   }
@@ -91,19 +87,19 @@
   // positional and the remaining ones are named optional arguments.
   // The presence of a type argument vector as first argument (not counted in
   // num_arguments) is indicated by a non-zero type_args_len.
-  static RawArray* New(intptr_t type_args_len,
-                       intptr_t num_arguments,
-                       intptr_t size_arguments,
-                       const Array& optional_arguments_names,
-                       Heap::Space space = Heap::kOld);
+  static ArrayPtr New(intptr_t type_args_len,
+                      intptr_t num_arguments,
+                      intptr_t size_arguments,
+                      const Array& optional_arguments_names,
+                      Heap::Space space = Heap::kOld);
 
   // Constructs an argument descriptor where all arguments are boxed and
   // therefore number of parameters equals parameter size.
   //
   // Right now this is for example the case for all closure functions.
-  static RawArray* NewBoxed(intptr_t type_args_len,
-                            intptr_t num_arguments,
-                            Heap::Space space = Heap::kOld) {
+  static ArrayPtr NewBoxed(intptr_t type_args_len,
+                           intptr_t num_arguments,
+                           Heap::Space space = Heap::kOld) {
     return New(type_args_len, num_arguments, num_arguments, space);
   }
 
@@ -111,10 +107,10 @@
   // arguments. All arguments are positional. The presence of a type argument
   // vector as first argument (not counted in num_arguments) is indicated
   // by a non-zero type_args_len.
-  static RawArray* New(intptr_t type_args_len,
-                       intptr_t num_arguments,
-                       intptr_t size_arguments,
-                       Heap::Space space = Heap::kOld);
+  static ArrayPtr New(intptr_t type_args_len,
+                      intptr_t num_arguments,
+                      intptr_t size_arguments,
+                      Heap::Space space = Heap::kOld);
 
   // Initialize the preallocated fixed length arguments descriptors cache.
   static void Init();
@@ -152,11 +148,11 @@
     return kFirstNamedEntryIndex + (kNamedEntrySize * num_named_arguments) + 1;
   }
 
-  static RawArray* NewNonCached(intptr_t type_args_len,
-                                intptr_t num_arguments,
-                                intptr_t size_arguments,
-                                bool canonicalize,
-                                Heap::Space space);
+  static ArrayPtr NewNonCached(intptr_t type_args_len,
+                               intptr_t num_arguments,
+                               intptr_t size_arguments,
+                               bool canonicalize,
+                               Heap::Space space);
 
   // Used by Simulator to parse argument descriptors.
   static intptr_t name_index(intptr_t index) {
@@ -170,7 +166,7 @@
   const Array& array_;
 
   // A cache of VM heap allocated arguments descriptors.
-  static RawArray* cached_args_descriptors_[kCachedDescriptorCount];
+  static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount];
 
   friend class SnapshotReader;
   friend class SnapshotWriter;
@@ -187,30 +183,24 @@
 // and invoke them from C++.
 class DartEntry : public AllStatic {
  public:
-  // On success, returns a RawInstance.  On failure, a RawError.
-  typedef RawObject* (*invokestub)(const Code& target_code,
-                                   const Array& arguments_descriptor,
-                                   const Array& arguments,
-                                   Thread* thread);
-
   // Invokes the specified instance function or static function.
   // The first argument of an instance function is the receiver.
   // On success, returns a RawInstance.  On failure, a RawError.
   // This is used when there is no type argument vector and
   // no named arguments in the call.
-  static RawObject* InvokeFunction(const Function& function,
-                                   const Array& arguments);
+  static ObjectPtr InvokeFunction(const Function& function,
+                                  const Array& arguments);
 
   // Invokes the specified code as if it was a Dart function.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeCode(const Code& code,
-                               const Array& arguments_descriptor,
-                               const Array& arguments,
-                               Thread* thread);
+  static ObjectPtr InvokeCode(const Code& code,
+                              const Array& arguments_descriptor,
+                              const Array& arguments,
+                              Thread* thread);
 
   // Invokes the specified instance, static, or closure function.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeFunction(
+  static ObjectPtr InvokeFunction(
       const Function& function,
       const Array& arguments,
       const Array& arguments_descriptor,
@@ -220,19 +210,19 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   // This is used when there is no type argument vector and
   // no named arguments in the call.
-  static RawObject* InvokeClosure(const Array& arguments);
+  static ObjectPtr InvokeClosure(const Array& arguments);
 
   // Invokes the closure object given as the first argument.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeClosure(const Array& arguments,
-                                  const Array& arguments_descriptor);
+  static ObjectPtr InvokeClosure(const Array& arguments,
+                                 const Array& arguments_descriptor);
 
   // Invokes the noSuchMethod instance function on the receiver.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeNoSuchMethod(const Instance& receiver,
-                                       const String& target_name,
-                                       const Array& arguments,
-                                       const Array& arguments_descriptor);
+  static ObjectPtr InvokeNoSuchMethod(const Instance& receiver,
+                                      const String& target_name,
+                                      const Array& arguments,
+                                      const Array& arguments_descriptor);
 };
 
 // Utility functions to call from VM into Dart bootstrap libraries.
@@ -240,44 +230,44 @@
 class DartLibraryCalls : public AllStatic {
  public:
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InstanceCreate(const Library& library,
-                                   const String& exception_name,
-                                   const String& constructor_name,
-                                   const Array& arguments);
+  static ObjectPtr InstanceCreate(const Library& library,
+                                  const String& exception_name,
+                                  const String& constructor_name,
+                                  const Array& arguments);
 
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* ToString(const Instance& receiver);
+  static ObjectPtr ToString(const Instance& receiver);
 
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* HashCode(const Instance& receiver);
+  static ObjectPtr HashCode(const Instance& receiver);
 
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* Equals(const Instance& left, const Instance& right);
+  static ObjectPtr Equals(const Instance& left, const Instance& right);
 
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* IdentityHashCode(const Instance& object);
+  static ObjectPtr IdentityHashCode(const Instance& object);
 
   // Returns the handler if one has been registered for this port id.
-  static RawObject* LookupHandler(Dart_Port port_id);
+  static ObjectPtr LookupHandler(Dart_Port port_id);
 
   // Returns null on success, a RawError on failure.
-  static RawObject* HandleMessage(const Object& handler,
-                                  const Instance& dart_message);
+  static ObjectPtr HandleMessage(const Object& handler,
+                                 const Instance& dart_message);
 
   // Returns null on success, a RawError on failure.
-  static RawObject* DrainMicrotaskQueue();
+  static ObjectPtr DrainMicrotaskQueue();
 
   // Ensures that the isolate's _pendingImmediateCallback is set to
   // _startMicrotaskLoop from dart:async.
   // Returns null on success, a RawError on failure.
-  static RawObject* EnsureScheduleImmediate();
+  static ObjectPtr EnsureScheduleImmediate();
 
   // map[key] = value;
   //
   // Returns null on success, a RawError on failure.
-  static RawObject* MapSetAt(const Instance& map,
-                             const Instance& key,
-                             const Instance& value);
+  static ObjectPtr MapSetAt(const Instance& map,
+                            const Instance& key,
+                            const Instance& value);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 77c74bc..d34cdbe 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -120,11 +120,11 @@
   }
 
  private:
-  int16_t Read16() { return Read16(kEndByteMarker); }
+  uint16_t Read16() { return Read16(kEndByteMarker); }
 
-  int32_t Read32() { return Read32(kEndByteMarker); }
+  uint32_t Read32() { return Read32(kEndByteMarker); }
 
-  int64_t Read64() { return Read64(kEndByteMarker); }
+  uint64_t Read64() { return Read64(kEndByteMarker); }
 
   template <typename T>
   T Read(uint8_t end_byte_marker) {
@@ -147,153 +147,153 @@
     return r | ((static_cast<T>(b) - end_byte_marker) << s);
   }
 
-  int16_t Read16(uint8_t end_byte_marker) {
+  uint16_t Read16(uint8_t end_byte_marker) {
     const uint8_t* c = current_;
     ASSERT(c < end_);
     uint8_t b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return static_cast<int16_t>(b) - end_byte_marker;
+      return static_cast<uint16_t>(b) - end_byte_marker;
     }
-    int16_t r = 0;
-    r |= static_cast<int16_t>(b);
+    uint16_t r = 0;
+    r |= static_cast<uint16_t>(b);
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int16_t>(b) - end_byte_marker) << 7);
+      return r | ((static_cast<uint16_t>(b) - end_byte_marker) << 7);
     }
 
-    r |= static_cast<int16_t>(b) << 7;
+    r |= static_cast<uint16_t>(b) << 7;
     ASSERT(c < end_);
     b = *c++;
     ASSERT(b > kMaxUnsignedDataPerByte);
     current_ = c;
-    return r | ((static_cast<int16_t>(b) - end_byte_marker) << 14);
+    return r | ((static_cast<uint16_t>(b) - end_byte_marker) << 14);
   }
 
-  int32_t Read32(uint8_t end_byte_marker) {
+  uint32_t Read32(uint8_t end_byte_marker) {
     const uint8_t* c = current_;
     ASSERT(c < end_);
     uint8_t b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return static_cast<int32_t>(b) - end_byte_marker;
+      return static_cast<uint32_t>(b) - end_byte_marker;
     }
 
-    int32_t r = 0;
-    r |= static_cast<int32_t>(b);
+    uint32_t r = 0;
+    r |= static_cast<uint32_t>(b);
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int32_t>(b) - end_byte_marker) << 7);
+      return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 7);
     }
 
-    r |= static_cast<int32_t>(b) << 7;
+    r |= static_cast<uint32_t>(b) << 7;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int32_t>(b) - end_byte_marker) << 14);
+      return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 14);
     }
 
-    r |= static_cast<int32_t>(b) << 14;
+    r |= static_cast<uint32_t>(b) << 14;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int32_t>(b) - end_byte_marker) << 21);
+      return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 21);
     }
 
-    r |= static_cast<int32_t>(b) << 21;
+    r |= static_cast<uint32_t>(b) << 21;
     ASSERT(c < end_);
     b = *c++;
     ASSERT(b > kMaxUnsignedDataPerByte);
     current_ = c;
-    return r | ((static_cast<int32_t>(b) - end_byte_marker) << 28);
+    return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 28);
   }
 
-  int64_t Read64(uint8_t end_byte_marker) {
+  uint64_t Read64(uint8_t end_byte_marker) {
     const uint8_t* c = current_;
     ASSERT(c < end_);
     uint8_t b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return static_cast<int64_t>(b) - end_byte_marker;
+      return static_cast<uint64_t>(b) - end_byte_marker;
     }
-    int64_t r = 0;
+    uint64_t r = 0;
 
-    r |= static_cast<int64_t>(b);
+    r |= static_cast<uint64_t>(b);
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 7);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 7);
     }
 
-    r |= static_cast<int64_t>(b) << 7;
+    r |= static_cast<uint64_t>(b) << 7;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 14);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 14);
     }
 
-    r |= static_cast<int64_t>(b) << 14;
+    r |= static_cast<uint64_t>(b) << 14;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 21);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 21);
     }
 
-    r |= static_cast<int64_t>(b) << 21;
+    r |= static_cast<uint64_t>(b) << 21;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 28);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 28);
     }
 
-    r |= static_cast<int64_t>(b) << 28;
+    r |= static_cast<uint64_t>(b) << 28;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 35);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 35);
     }
 
-    r |= static_cast<int64_t>(b) << 35;
+    r |= static_cast<uint64_t>(b) << 35;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 42);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 42);
     }
 
-    r |= static_cast<int64_t>(b) << 42;
+    r |= static_cast<uint64_t>(b) << 42;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 49);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 49);
     }
 
-    r |= static_cast<int64_t>(b) << 49;
+    r |= static_cast<uint64_t>(b) << 49;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 56);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 56);
     }
 
-    r |= static_cast<int64_t>(b) << 56;
+    r |= static_cast<uint64_t>(b) << 56;
     ASSERT(c < end_);
     b = *c++;
     ASSERT(b > kMaxUnsignedDataPerByte);
     current_ = c;
-    return r | ((static_cast<int64_t>(b) - end_byte_marker) << 63);
+    return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 63);
   }
 
   uint8_t ReadByte() {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index d121a55..0050f4f 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -8,13 +8,13 @@
 
 #include "platform/address_sanitizer.h"
 
+#include "vm/code_descriptors.h"
 #include "vm/code_patcher.h"
+#include "vm/compiler/api/deopt_id.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
-#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_entry.h"
-#include "vm/deopt_instructions.h"
 #include "vm/flags.h"
 #include "vm/globals.h"
 #include "vm/interpreter.h"
@@ -41,6 +41,11 @@
 #include "vm/token_position.h"
 #include "vm/visitor.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/frontend/bytecode_reader.h"
+#include "vm/deopt_instructions.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DEFINE_FLAG(bool,
@@ -145,13 +150,13 @@
 }
 
 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&closure_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&closure_));
 }
 
 void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&script_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&url_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&function_));
 
   Breakpoint* bpt = conditions_;
   while (bpt != NULL) {
@@ -178,9 +183,9 @@
 }
 
 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&bytecode_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_value_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&code_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&bytecode_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_value_));
 }
 
 ActivationFrame::ActivationFrame(uword pc,
@@ -328,15 +333,15 @@
   Service::HandleEvent(event);
 }
 
-RawError* Debugger::PauseInterrupted() {
+ErrorPtr Debugger::PauseInterrupted() {
   return PauseRequest(ServiceEvent::kPauseInterrupted);
 }
 
-RawError* Debugger::PausePostRequest() {
+ErrorPtr Debugger::PausePostRequest() {
   return PauseRequest(ServiceEvent::kPausePostRequest);
 }
 
-RawError* Debugger::PauseRequest(ServiceEvent::EventKind kind) {
+ErrorPtr Debugger::PauseRequest(ServiceEvent::EventKind kind) {
   if (ignore_breakpoints_ || IsPaused()) {
     // We don't let the isolate get interrupted if we are already
     // paused or ignoring breakpoints.
@@ -356,7 +361,7 @@
 
   // If any error occurred while in the debug message loop, return it here.
   NoSafepointScope no_safepoint;
-  RawError* error = Thread::Current()->StealStickyError();
+  ErrorPtr error = Thread::Current()->StealStickyError();
   ASSERT((error == Error::null()) || error->IsUnwindError());
   return error;
 }
@@ -459,14 +464,14 @@
 
 static bool IsImplicitFunction(const Function& func) {
   switch (func.kind()) {
-    case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitSetter:
-    case RawFunction::kImplicitStaticGetter:
-    case RawFunction::kFieldInitializer:
-    case RawFunction::kMethodExtractor:
-    case RawFunction::kNoSuchMethodDispatcher:
-    case RawFunction::kInvokeFieldDispatcher:
-    case RawFunction::kIrregexpFunction:
+    case FunctionLayout::kImplicitGetter:
+    case FunctionLayout::kImplicitSetter:
+    case FunctionLayout::kImplicitStaticGetter:
+    case FunctionLayout::kFieldInitializer:
+    case FunctionLayout::kMethodExtractor:
+    case FunctionLayout::kNoSuchMethodDispatcher:
+    case FunctionLayout::kInvokeFieldDispatcher:
+    case FunctionLayout::kIrregexpFunction:
       return true;
     default:
       if (func.token_pos() == func.end_token_pos()) {
@@ -605,20 +610,20 @@
   return IsCalleeFrameOf(other_fp, fp()) ? kCallee : kCaller;
 }
 
-RawString* ActivationFrame::QualifiedFunctionName() {
+StringPtr ActivationFrame::QualifiedFunctionName() {
   return String::New(Debugger::QualifiedFunctionName(function()));
 }
 
-RawString* ActivationFrame::SourceUrl() {
+StringPtr ActivationFrame::SourceUrl() {
   const Script& script = Script::Handle(SourceScript());
   return script.url();
 }
 
-RawScript* ActivationFrame::SourceScript() {
+ScriptPtr ActivationFrame::SourceScript() {
   return function().script();
 }
 
-RawLibrary* ActivationFrame::Library() {
+LibraryPtr ActivationFrame::Library() {
   const Class& cls = Class::Handle(function().origin());
   return cls.library();
 }
@@ -643,7 +648,7 @@
     }
     token_pos_ = TokenPosition::kNoSource;
     GetPcDescriptors();
-    PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
+    PcDescriptors::Iterator iter(pc_desc_, PcDescriptorsLayout::kAnyKind);
     const uword pc_offset = pc_ - code().PayloadStart();
     while (iter.MoveNext()) {
       if (iter.PcOffset() == pc_offset) {
@@ -801,10 +806,10 @@
       intptr_t var_desc_len = var_descriptors_.Length();
       bool found = false;
       for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
-        RawLocalVarDescriptors::VarInfo var_info;
+        LocalVarDescriptorsLayout::VarInfo var_info;
         var_descriptors_.GetInfo(cur_idx, &var_info);
         const int8_t kind = var_info.kind();
-        if ((kind == RawLocalVarDescriptors::kContextLevel) &&
+        if ((kind == LocalVarDescriptorsLayout::kContextLevel) &&
             (deopt_id >= var_info.begin_pos.value()) &&
             (deopt_id <= var_info.end_pos.value())) {
           context_level_ = var_info.index();
@@ -821,7 +826,7 @@
   return context_level_;
 }
 
-RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) {
+ObjectPtr ActivationFrame::GetAsyncContextVariable(const String& name) {
   if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) {
     return Object::null();
   }
@@ -830,18 +835,18 @@
   intptr_t ctxt_slot = -1;
   intptr_t var_desc_len = var_descriptors_.Length();
   for (intptr_t i = 0; i < var_desc_len; i++) {
-    RawLocalVarDescriptors::VarInfo var_info;
+    LocalVarDescriptorsLayout::VarInfo var_info;
     var_descriptors_.GetInfo(i, &var_info);
     if (var_descriptors_.GetName(i) == name.raw()) {
       const int8_t kind = var_info.kind();
       if (!live_frame_) {
-        ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+        ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
       }
       const auto variable_index = VariableIndex(var_info.index());
-      if (kind == RawLocalVarDescriptors::kStackVar) {
+      if (kind == LocalVarDescriptorsLayout::kStackVar) {
         return GetStackVar(variable_index);
       } else {
-        ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+        ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
         // Variable descriptors constructed from bytecode have all variables of
         // enclosing functions, even shadowed by the current function.
         // Pick the variable with the highest context level.
@@ -868,11 +873,11 @@
   return Object::null();
 }
 
-RawObject* ActivationFrame::GetAsyncCompleter() {
+ObjectPtr ActivationFrame::GetAsyncCompleter() {
   return GetAsyncContextVariable(Symbols::AsyncCompleter());
 }
 
-RawObject* ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
+ObjectPtr ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
   DEBUG_ASSERT(Thread::Current()->TopErrorHandlerIsExitFrame());
 
   Object& future = Object::Handle();
@@ -899,11 +904,11 @@
   return Instance::Cast(future).GetField(awaiter_field);
 }
 
-RawObject* ActivationFrame::GetAsyncStreamControllerStream() {
+ObjectPtr ActivationFrame::GetAsyncStreamControllerStream() {
   return GetAsyncContextVariable(Symbols::ControllerStream());
 }
 
-RawObject* ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
+ObjectPtr ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
     const Object& stream) {
   const Class& stream_cls = Class::Handle(stream.clazz());
   ASSERT(!stream_cls.IsNull());
@@ -914,7 +919,7 @@
   return Instance::Cast(stream).GetField(awaiter_field);
 }
 
-RawObject* ActivationFrame::GetAsyncAwaiter() {
+ObjectPtr ActivationFrame::GetAsyncAwaiter() {
   const Object& async_stream_controller_stream =
       Object::Handle(GetAsyncStreamControllerStream());
   if (!async_stream_controller_stream.IsNull()) {
@@ -928,7 +933,7 @@
   return Object::null();
 }
 
-RawObject* ActivationFrame::GetCausalStack() {
+ObjectPtr ActivationFrame::GetCausalStack() {
   return GetAsyncContextVariable(Symbols::AsyncStackTraceVar());
 }
 
@@ -987,11 +992,11 @@
   intptr_t var_desc_len = var_descriptors_.Length();
   intptr_t await_jump_var = -1;
   for (intptr_t i = 0; i < var_desc_len; i++) {
-    RawLocalVarDescriptors::VarInfo var_info;
+    LocalVarDescriptorsLayout::VarInfo var_info;
     var_descriptors_.GetInfo(i, &var_info);
     const int8_t kind = var_info.kind();
     if (var_descriptors_.GetName(i) == Symbols::AwaitJumpVar().raw()) {
-      ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+      ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
       ASSERT(!ctx_.IsNull());
       // Variable descriptors constructed from bytecode have all variables of
       // enclosing functions, even shadowed by the current function.
@@ -1060,7 +1065,7 @@
   const auto& pc_descriptors =
       PcDescriptors::Handle(zone, code().pc_descriptors());
   ASSERT(!pc_descriptors.IsNull());
-  PcDescriptors::Iterator it(pc_descriptors, RawPcDescriptors::kOther);
+  PcDescriptors::Iterator it(pc_descriptors, PcDescriptorsLayout::kOther);
   while (it.MoveNext()) {
     if (it.YieldIndex() == await_jump_var) {
       try_index_ = it.TryIndex();
@@ -1096,10 +1101,10 @@
   intptr_t var_desc_len = var_descriptors_.Length();
   Object& obj = Object::Handle();
   for (intptr_t i = 0; i < var_desc_len; i++) {
-    RawLocalVarDescriptors::VarInfo var_info;
+    LocalVarDescriptorsLayout::VarInfo var_info;
     var_descriptors_.GetInfo(i, &var_info);
     const int8_t kind = var_info.kind();
-    if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
+    if (kind == LocalVarDescriptorsLayout::kSavedCurrentContext) {
       if (FLAG_trace_debugger_stacktrace) {
         OS::PrintErr("\tFound saved current ctx at index %d\n",
                      var_info.index());
@@ -1123,7 +1128,7 @@
   return ctx_;
 }
 
-RawObject* ActivationFrame::GetAsyncOperation() {
+ObjectPtr ActivationFrame::GetAsyncOperation() {
   if (function().name() == Symbols::AsyncOperation().raw()) {
     return GetParameter(0);
   }
@@ -1163,16 +1168,16 @@
   intptr_t var_desc_len = var_descriptors_.Length();
   for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
     ASSERT(var_names.length() == desc_indices_.length());
-    RawLocalVarDescriptors::VarInfo var_info;
+    LocalVarDescriptorsLayout::VarInfo var_info;
     var_descriptors_.GetInfo(cur_idx, &var_info);
     const int8_t kind = var_info.kind();
-    if ((kind != RawLocalVarDescriptors::kStackVar) &&
-        (kind != RawLocalVarDescriptors::kContextVar)) {
+    if ((kind != LocalVarDescriptorsLayout::kStackVar) &&
+        (kind != LocalVarDescriptorsLayout::kContextVar)) {
       continue;
     }
     if ((var_info.begin_pos <= activation_token_pos) &&
         (activation_token_pos <= var_info.end_pos)) {
-      if ((kind == RawLocalVarDescriptors::kContextVar) &&
+      if ((kind == LocalVarDescriptorsLayout::kContextVar) &&
           (ContextLevel() < var_info.scope_id)) {
         // The variable is textually in scope but the context level
         // at the activation frame's PC is lower than the context
@@ -1193,7 +1198,7 @@
           // Found two local variables with the same name. Now determine
           // which one is shadowed.
           name_match_found = true;
-          RawLocalVarDescriptors::VarInfo i_var_info;
+          LocalVarDescriptorsLayout::VarInfo i_var_info;
           var_descriptors_.GetInfo(desc_indices_[i], &i_var_info);
           if (i_var_info.begin_pos < var_info.begin_pos) {
             // The variable we found earlier is in an outer scope
@@ -1225,12 +1230,12 @@
   return desc_indices_.length();
 }
 
-DART_FORCE_INLINE static RawObject* GetVariableValue(uword addr) {
-  return *reinterpret_cast<RawObject**>(addr);
+DART_FORCE_INLINE static ObjectPtr GetVariableValue(uword addr) {
+  return *reinterpret_cast<ObjectPtr*>(addr);
 }
 
 // Caution: GetParameter only works for fixed parameters.
-RawObject* ActivationFrame::GetParameter(intptr_t index) {
+ObjectPtr ActivationFrame::GetParameter(intptr_t index) {
   intptr_t num_parameters = function().num_fixed_parameters();
   ASSERT(0 <= index && index < num_parameters);
 
@@ -1259,12 +1264,12 @@
   }
 }
 
-RawObject* ActivationFrame::GetClosure() {
+ObjectPtr ActivationFrame::GetClosure() {
   ASSERT(function().IsClosureFunction());
   return GetParameter(0);
 }
 
-RawObject* ActivationFrame::GetStackVar(VariableIndex variable_index) {
+ObjectPtr ActivationFrame::GetStackVar(VariableIndex variable_index) {
   if (IsInterpreted()) {
     intptr_t slot_index = -variable_index.value();
     if (slot_index < 0) {
@@ -1359,7 +1364,7 @@
 
   *name = var_descriptors_.GetName(desc_index);
 
-  RawLocalVarDescriptors::VarInfo var_info;
+  LocalVarDescriptorsLayout::VarInfo var_info;
   var_descriptors_.GetInfo(desc_index, &var_info);
   ASSERT(declaration_token_pos != NULL);
   *declaration_token_pos = var_info.declaration_pos;
@@ -1370,25 +1375,25 @@
   ASSERT(value != NULL);
   const int8_t kind = var_info.kind();
   const auto variable_index = VariableIndex(var_info.index());
-  if (kind == RawLocalVarDescriptors::kStackVar) {
+  if (kind == LocalVarDescriptorsLayout::kStackVar) {
     *value = GetStackVar(variable_index);
   } else {
-    ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+    ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
     *value = GetContextVar(var_info.scope_id, variable_index.value());
   }
 }
 
-RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level,
-                                          intptr_t ctx_slot) {
+ObjectPtr ActivationFrame::GetContextVar(intptr_t var_ctx_level,
+                                         intptr_t ctx_slot) {
   // The context level at the PC/token index of this activation frame.
   intptr_t frame_ctx_level = ContextLevel();
 
   return GetRelativeContextVar(var_ctx_level, ctx_slot, frame_ctx_level);
 }
 
-RawObject* ActivationFrame::GetRelativeContextVar(intptr_t var_ctx_level,
-                                                  intptr_t ctx_slot,
-                                                  intptr_t frame_ctx_level) {
+ObjectPtr ActivationFrame::GetRelativeContextVar(intptr_t var_ctx_level,
+                                                 intptr_t ctx_slot,
+                                                 intptr_t frame_ctx_level) {
   const Context& ctx = GetSavedCurrentContext();
 
   // It's possible that ctx was optimized out as no locals were captured by the
@@ -1423,7 +1428,7 @@
   }
 }
 
-RawArray* ActivationFrame::GetLocalVariables() {
+ArrayPtr ActivationFrame::GetLocalVariables() {
   GetDescIndices();
   intptr_t num_variables = desc_indices_.length();
   String& var_name = String::Handle();
@@ -1438,7 +1443,7 @@
   return list.raw();
 }
 
-RawObject* ActivationFrame::GetReceiver() {
+ObjectPtr ActivationFrame::GetReceiver() {
   GetDescIndices();
   intptr_t num_variables = desc_indices_.length();
   String& var_name = String::Handle();
@@ -1461,7 +1466,7 @@
   return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_');
 }
 
-RawObject* ActivationFrame::EvaluateCompiledExpression(
+ObjectPtr ActivationFrame::EvaluateCompiledExpression(
     const ExternalTypedData& kernel_buffer,
     const Array& type_definitions,
     const Array& arguments,
@@ -1483,7 +1488,7 @@
   }
 }
 
-RawTypeArguments* ActivationFrame::BuildParameters(
+TypeArgumentsPtr ActivationFrame::BuildParameters(
     const GrowableObjectArray& param_names,
     const GrowableObjectArray& param_values,
     const GrowableObjectArray& type_params_names) {
@@ -1715,14 +1720,14 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
-                               RawPcDescriptors::kUnoptStaticCall |
-                               RawPcDescriptors::kRuntimeCall;
+const uint8_t kSafepointKind = PcDescriptorsLayout::kIcCall |
+                               PcDescriptorsLayout::kUnoptStaticCall |
+                               PcDescriptorsLayout::kRuntimeCall;
 
 CodeBreakpoint::CodeBreakpoint(const Code& code,
                                TokenPosition token_pos,
                                uword pc,
-                               RawPcDescriptors::Kind kind)
+                               PcDescriptorsLayout::Kind kind)
     : code_(code.raw()),
       bytecode_(Bytecode::null()),
       token_pos_(token_pos),
@@ -1750,7 +1755,7 @@
       is_enabled_(false),
       bpt_location_(NULL),
       next_(NULL),
-      breakpoint_kind_(RawPcDescriptors::kAnyKind),
+      breakpoint_kind_(PcDescriptorsLayout::kAnyKind),
       saved_value_(Code::null()) {
   ASSERT(!bytecode.IsNull());
   ASSERT(FLAG_enable_interpreter);
@@ -1768,11 +1773,11 @@
   pc_ = 0ul;
   bpt_location_ = NULL;
   next_ = NULL;
-  breakpoint_kind_ = RawPcDescriptors::kOther;
+  breakpoint_kind_ = PcDescriptorsLayout::kOther;
 #endif
 }
 
-RawFunction* CodeBreakpoint::function() const {
+FunctionPtr CodeBreakpoint::function() const {
   if (IsInterpreted()) {
     ASSERT(Bytecode::Handle(bytecode_).function() != Function::null());
     return Bytecode::Handle(bytecode_).function();
@@ -1781,12 +1786,12 @@
   }
 }
 
-RawScript* CodeBreakpoint::SourceCode() {
+ScriptPtr CodeBreakpoint::SourceCode() {
   const Function& func = Function::Handle(this->function());
   return func.script();
 }
 
-RawString* CodeBreakpoint::SourceUrl() {
+StringPtr CodeBreakpoint::SourceUrl() {
   const Script& script = Script::Handle(SourceCode());
   return script.url();
 }
@@ -2081,9 +2086,9 @@
   return activation;
 }
 
-RawArray* Debugger::DeoptimizeToArray(Thread* thread,
-                                      StackFrame* frame,
-                                      const Code& code) {
+ArrayPtr Debugger::DeoptimizeToArray(Thread* thread,
+                                     StackFrame* frame,
+                                     const Code& code) {
   ASSERT(code.is_optimized() && !code.is_force_optimized());
   Isolate* isolate = thread->isolate();
   // Create the DeoptContext for this deoptimization.
@@ -3231,7 +3236,7 @@
     ASSERT(!code.IsNull());
     PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
     uword lowest_pc_offset = kUwordMax;
-    RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind;
+    PcDescriptorsLayout::Kind lowest_kind = PcDescriptorsLayout::kAnyKind;
     // Find the safe point with the lowest compiled code address
     // that maps to the token position of the source breakpoint.
     PcDescriptors::Iterator iter(desc, kSafepointKind);
@@ -3872,7 +3877,7 @@
     cbpt->VisitObjectPointers(visitor);
     cbpt = cbpt->next();
   }
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&top_frame_awaiter_));
 }
 
 void Debugger::Pause(ServiceEvent* event) {
@@ -4135,12 +4140,12 @@
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   PcDescriptors::Iterator iter(
-      descriptors, RawPcDescriptors::kRewind | RawPcDescriptors::kIcCall |
-                       RawPcDescriptors::kUnoptStaticCall);
+      descriptors, PcDescriptorsLayout::kRewind | PcDescriptorsLayout::kIcCall |
+                       PcDescriptorsLayout::kUnoptStaticCall);
   intptr_t rewind_deopt_id = -1;
   uword rewind_pc = 0;
   while (iter.MoveNext()) {
-    if (iter.Kind() == RawPcDescriptors::kRewind) {
+    if (iter.Kind() == PcDescriptorsLayout::kRewind) {
       // Remember the last rewind so we don't need to iterator twice.
       rewind_pc = code.PayloadStart() + iter.PcOffset();
       rewind_deopt_id = iter.DeoptId();
@@ -4430,10 +4435,10 @@
       return false;
     }
     const TokenPosition looking_for = top_frame->TokenPos();
-    PcDescriptors::Iterator it(pc_descriptors, RawPcDescriptors::kOther);
+    PcDescriptors::Iterator it(pc_descriptors, PcDescriptorsLayout::kOther);
     while (it.MoveNext()) {
       if (it.TokenPos() == looking_for &&
-          it.YieldIndex() != RawPcDescriptors::kInvalidYieldIndex) {
+          it.YieldIndex() != PcDescriptorsLayout::kInvalidYieldIndex) {
         return true;
       }
     }
@@ -4441,7 +4446,7 @@
   return false;
 }
 
-RawError* Debugger::PauseStepping() {
+ErrorPtr Debugger::PauseStepping() {
   ASSERT(isolate_->single_step());
   // Don't pause recursively.
   if (IsPaused()) {
@@ -4557,7 +4562,7 @@
   return Thread::Current()->StealStickyError();
 }
 
-RawError* Debugger::PauseBreakpoint() {
+ErrorPtr Debugger::PauseBreakpoint() {
   // We ignore this breakpoint when the VM is executing code invoked
   // by the debugger to evaluate variables values, or when we see a nested
   // breakpoint or exception event.
@@ -4712,8 +4717,8 @@
 
 // Return innermost closure contained in 'function' that contains
 // the given token position.
-RawFunction* Debugger::FindInnermostClosure(const Function& function,
-                                            TokenPosition token_pos) {
+FunctionPtr Debugger::FindInnermostClosure(const Function& function,
+                                           TokenPosition token_pos) {
   Zone* zone = Thread::Current()->zone();
   const Script& outer_origin = Script::Handle(zone, function.script());
   const GrowableObjectArray& closures = GrowableObjectArray::Handle(
@@ -5010,7 +5015,7 @@
   return NULL;
 }
 
-RawCode* Debugger::GetPatchedStubAddress(uword breakpoint_address) {
+CodePtr Debugger::GetPatchedStubAddress(uword breakpoint_address) {
   CodeBreakpoint* cbpt = GetCodeBreakpoint(breakpoint_address);
   if (cbpt != NULL) {
     return cbpt->OrigStubAddress();
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 9536669..2a5bd90 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -58,7 +58,7 @@
   bool IsRepeated() const { return kind_ == kRepeated; }
   bool IsSingleShot() const { return kind_ == kSingleShot; }
   bool IsPerClosure() const { return kind_ == kPerClosure; }
-  RawInstance* closure() const { return closure_; }
+  InstancePtr closure() const { return closure_; }
 
   void SetIsRepeated() {
     ASSERT(kind_ == kNone);
@@ -97,7 +97,7 @@
   intptr_t id_;
   ConditionKind kind_;
   Breakpoint* next_;
-  RawInstance* closure_;
+  InstancePtr closure_;
   BreakpointLocation* bpt_location_;
   bool is_synthetic_async_;
 
@@ -131,12 +131,12 @@
 
   ~BreakpointLocation();
 
-  RawFunction* function() const { return function_; }
+  FunctionPtr function() const { return function_; }
   TokenPosition token_pos() const { return token_pos_; }
   TokenPosition end_token_pos() const { return end_token_pos_; }
 
-  RawScript* script() const { return script_; }
-  RawString* url() const { return url_; }
+  ScriptPtr script() const { return script_; }
+  StringPtr url() const { return url_; }
 
   intptr_t requested_line_number() const { return requested_line_number_; }
   intptr_t requested_column_number() const { return requested_column_number_; }
@@ -174,8 +174,8 @@
   Breakpoint* breakpoints() const { return this->conditions_; }
   void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
 
-  RawScript* script_;
-  RawString* url_;
+  ScriptPtr script_;
+  StringPtr url_;
   TokenPosition token_pos_;
   TokenPosition end_token_pos_;
   BreakpointLocation* next_;
@@ -184,7 +184,7 @@
   intptr_t requested_column_number_;
 
   // Valid for resolved breakpoints:
-  RawFunction* function_;
+  FunctionPtr function_;
   TokenPosition bytecode_token_pos_;
   TokenPosition code_token_pos_;
 
@@ -200,16 +200,16 @@
   CodeBreakpoint(const Code& code,
                  TokenPosition token_pos,
                  uword pc,
-                 RawPcDescriptors::Kind kind);
+                 PcDescriptorsLayout::Kind kind);
   CodeBreakpoint(const Bytecode& bytecode, TokenPosition token_pos, uword pc);
   ~CodeBreakpoint();
 
-  RawFunction* function() const;
+  FunctionPtr function() const;
   uword pc() const { return pc_; }
   TokenPosition token_pos() const { return token_pos_; }
 
-  RawScript* SourceCode();
-  RawString* SourceUrl();
+  ScriptPtr SourceCode();
+  StringPtr SourceUrl();
   intptr_t LineNumber();
 
   void Enable();
@@ -217,7 +217,7 @@
   bool IsEnabled() const { return is_enabled_; }
   bool IsInterpreted() const { return bytecode_ != Bytecode::null(); }
 
-  RawCode* OrigStubAddress() const;
+  CodePtr OrigStubAddress() const;
 
  private:
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
@@ -233,8 +233,8 @@
   void SetBytecodeBreakpoint();
   void UnsetBytecodeBreakpoint();
 
-  RawCode* code_;
-  RawBytecode* bytecode_;
+  CodePtr code_;
+  BytecodePtr bytecode_;
   TokenPosition token_pos_;
   uword pc_;
   intptr_t line_number_;
@@ -243,8 +243,8 @@
   BreakpointLocation* bpt_location_;
   CodeBreakpoint* next_;
 
-  RawPcDescriptors::Kind breakpoint_kind_;
-  RawCode* saved_value_;
+  PcDescriptorsLayout::Kind breakpoint_kind_;
+  CodePtr saved_value_;
 
   friend class Debugger;
   DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint);
@@ -309,10 +309,10 @@
 
   Relation CompareTo(uword other_fp, bool other_is_interpreted) const;
 
-  RawString* QualifiedFunctionName();
-  RawString* SourceUrl();
-  RawScript* SourceScript();
-  RawLibrary* Library();
+  StringPtr QualifiedFunctionName();
+  StringPtr SourceUrl();
+  ScriptPtr SourceScript();
+  LibraryPtr Library();
   TokenPosition TokenPos();
   intptr_t LineNumber();
   intptr_t ColumnNumber();
@@ -340,28 +340,28 @@
                   TokenPosition* visible_end_token_pos,
                   Object* value);
 
-  RawArray* GetLocalVariables();
-  RawObject* GetParameter(intptr_t index);
-  RawObject* GetClosure();
-  RawObject* GetReceiver();
+  ArrayPtr GetLocalVariables();
+  ObjectPtr GetParameter(intptr_t index);
+  ObjectPtr GetClosure();
+  ObjectPtr GetReceiver();
 
   const Context& GetSavedCurrentContext();
-  RawObject* GetAsyncOperation();
+  ObjectPtr GetAsyncOperation();
 
-  RawTypeArguments* BuildParameters(
+  TypeArgumentsPtr BuildParameters(
       const GrowableObjectArray& param_names,
       const GrowableObjectArray& param_values,
       const GrowableObjectArray& type_params_names);
 
-  RawObject* EvaluateCompiledExpression(const ExternalTypedData& kernel_data,
-                                        const Array& arguments,
-                                        const Array& type_definitions,
-                                        const TypeArguments& type_arguments);
+  ObjectPtr EvaluateCompiledExpression(const ExternalTypedData& kernel_data,
+                                       const Array& arguments,
+                                       const Array& type_definitions,
+                                       const TypeArguments& type_arguments);
 
   void PrintToJSONObject(JSONObject* jsobj);
 
-  RawObject* GetAsyncAwaiter();
-  RawObject* GetCausalStack();
+  ObjectPtr GetAsyncAwaiter();
+  ObjectPtr GetCausalStack();
 
   bool HandlesException(const Instance& exc_obj);
 
@@ -381,11 +381,11 @@
   void GetVarDescriptors();
   void GetDescIndices();
 
-  RawObject* GetAsyncContextVariable(const String& name);
-  RawObject* GetAsyncStreamControllerStreamAwaiter(const Object& stream);
-  RawObject* GetAsyncStreamControllerStream();
-  RawObject* GetAsyncCompleterAwaiter(const Object& completer);
-  RawObject* GetAsyncCompleter();
+  ObjectPtr GetAsyncContextVariable(const String& name);
+  ObjectPtr GetAsyncStreamControllerStreamAwaiter(const Object& stream);
+  ObjectPtr GetAsyncStreamControllerStream();
+  ObjectPtr GetAsyncCompleterAwaiter(const Object& completer);
+  ObjectPtr GetAsyncCompleter();
   intptr_t GetAwaitJumpVariable();
   void ExtractTokenPositionFromAsyncClosure();
 
@@ -407,11 +407,11 @@
     }
   }
 
-  RawObject* GetStackVar(VariableIndex var_index);
-  RawObject* GetRelativeContextVar(intptr_t ctxt_level,
-                                   intptr_t slot_index,
-                                   intptr_t frame_ctx_level);
-  RawObject* GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
+  ObjectPtr GetStackVar(VariableIndex var_index);
+  ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
+                                  intptr_t slot_index,
+                                  intptr_t frame_ctx_level);
+  ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
 
   uword pc_;
   uword fp_;
@@ -602,16 +602,16 @@
   static const char* QualifiedFunctionName(const Function& func);
 
   // Pause execution for a breakpoint.  Called from generated code.
-  RawError* PauseBreakpoint();
+  ErrorPtr PauseBreakpoint();
 
   // Pause execution due to stepping.  Called from generated code.
-  RawError* PauseStepping();
+  ErrorPtr PauseStepping();
 
   // Pause execution due to isolate interrupt.
-  RawError* PauseInterrupted();
+  ErrorPtr PauseInterrupted();
 
   // Pause after a reload request.
-  RawError* PausePostRequest();
+  ErrorPtr PausePostRequest();
 
   // Pause execution due to an uncaught exception.
   void PauseException(const Instance& exc);
@@ -620,7 +620,7 @@
   // Dart.
   void PauseDeveloper(const String& msg);
 
-  RawCode* GetPatchedStubAddress(uword breakpoint_address);
+  CodePtr GetPatchedStubAddress(uword breakpoint_address);
 
   void PrintBreakpointsToJSONArray(JSONArray* jsarr) const;
   void PrintSettingsToJSONObject(JSONObject* jsobj) const;
@@ -636,7 +636,7 @@
   static DebuggerStackTrace* CollectAwaiterReturnStackTrace();
 
  private:
-  RawError* PauseRequest(ServiceEvent::EventKind kind);
+  ErrorPtr PauseRequest(ServiceEvent::EventKind kind);
 
   // Finds the breakpoint we hit at |location|.
   Breakpoint* FindHitBreakpoint(BreakpointLocation* location,
@@ -661,8 +661,8 @@
                    TokenPosition token_pos,
                    TokenPosition last_token_pos,
                    Function* best_fit);
-  RawFunction* FindInnermostClosure(const Function& function,
-                                    TokenPosition token_pos);
+  FunctionPtr FindInnermostClosure(const Function& function,
+                                   TokenPosition token_pos);
   TokenPosition ResolveBreakpointPos(bool in_bytecode,
                                      const Function& func,
                                      TokenPosition requested_token_pos,
@@ -728,9 +728,9 @@
       StackFrame* frame,
       const Bytecode& bytecode,
       ActivationFrame::Kind kind = ActivationFrame::kRegular);
-  static RawArray* DeoptimizeToArray(Thread* thread,
-                                     StackFrame* frame,
-                                     const Code& code);
+  static ArrayPtr DeoptimizeToArray(Thread* thread,
+                                    StackFrame* frame,
+                                    const Code& code);
   TokenPosition FindExactTokenPosition(const Script& script,
                                        TokenPosition start_of_line,
                                        intptr_t column_number);
@@ -828,7 +828,7 @@
   // Used to track the current async/async* function.
   uword async_stepping_fp_;
   bool interpreted_async_stepping_;
-  RawObject* top_frame_awaiter_;
+  ObjectPtr top_frame_awaiter_;
 
   // If we step while at a breakpoint, we would hit the same pc twice.
   // We use this field to let us skip the next single-step after a
diff --git a/runtime/vm/debugger_arm.cc b/runtime/vm/debugger_arm.cc
index 15d95ba..9862592 100644
--- a/runtime/vm/debugger_arm.cc
+++ b/runtime/vm/debugger_arm.cc
@@ -15,7 +15,7 @@
 
 #ifndef PRODUCT
 
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
 
@@ -23,13 +23,13 @@
   ASSERT(!is_enabled_);
   Code& stub_target = Code::Handle();
   switch (breakpoint_kind_) {
-    case RawPcDescriptors::kIcCall:
+    case PcDescriptorsLayout::kIcCall:
       stub_target = StubCode::ICCallBreakpoint().raw();
       break;
-    case RawPcDescriptors::kUnoptStaticCall:
+    case PcDescriptorsLayout::kUnoptStaticCall:
       stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
       break;
-    case RawPcDescriptors::kRuntimeCall:
+    case PcDescriptorsLayout::kRuntimeCall:
       stub_target = StubCode::RuntimeCallBreakpoint().raw();
       break;
     default:
@@ -45,9 +45,9 @@
   ASSERT(is_enabled_);
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
-    case RawPcDescriptors::kIcCall:
-    case RawPcDescriptors::kUnoptStaticCall:
-    case RawPcDescriptors::kRuntimeCall: {
+    case PcDescriptorsLayout::kIcCall:
+    case PcDescriptorsLayout::kUnoptStaticCall:
+    case PcDescriptorsLayout::kRuntimeCall: {
       CodePatcher::PatchStaticCallAt(pc_, code, Code::Handle(saved_value_));
       break;
     }
diff --git a/runtime/vm/debugger_arm64.cc b/runtime/vm/debugger_arm64.cc
index e9748ca..dc132f8 100644
--- a/runtime/vm/debugger_arm64.cc
+++ b/runtime/vm/debugger_arm64.cc
@@ -15,7 +15,7 @@
 
 #ifndef PRODUCT
 
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
 
@@ -23,20 +23,20 @@
   ASSERT(!is_enabled_);
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
-    case RawPcDescriptors::kIcCall: {
+    case PcDescriptorsLayout::kIcCall: {
       Object& data = Object::Handle();
       saved_value_ = CodePatcher::GetInstanceCallAt(pc_, code, &data);
       CodePatcher::PatchInstanceCallAt(pc_, code, data,
                                        StubCode::ICCallBreakpoint());
       break;
     }
-    case RawPcDescriptors::kUnoptStaticCall: {
+    case PcDescriptorsLayout::kUnoptStaticCall: {
       saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
       CodePatcher::PatchPoolPointerCallAt(
           pc_, code, StubCode::UnoptStaticCallBreakpoint());
       break;
     }
-    case RawPcDescriptors::kRuntimeCall: {
+    case PcDescriptorsLayout::kRuntimeCall: {
       saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
       CodePatcher::PatchPoolPointerCallAt(pc_, code,
                                           StubCode::RuntimeCallBreakpoint());
@@ -52,15 +52,15 @@
   ASSERT(is_enabled_);
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
-    case RawPcDescriptors::kIcCall: {
+    case PcDescriptorsLayout::kIcCall: {
       Object& data = Object::Handle();
       CodePatcher::GetInstanceCallAt(pc_, code, &data);
       CodePatcher::PatchInstanceCallAt(pc_, code, data,
                                        Code::Handle(saved_value_));
       break;
     }
-    case RawPcDescriptors::kUnoptStaticCall:
-    case RawPcDescriptors::kRuntimeCall: {
+    case PcDescriptorsLayout::kUnoptStaticCall:
+    case PcDescriptorsLayout::kRuntimeCall: {
       CodePatcher::PatchPoolPointerCallAt(pc_, code,
                                           Code::Handle(saved_value_));
       break;
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index 8b1eb8a..d580561 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -19,7 +19,7 @@
 
 #ifndef PRODUCT
 
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
 
@@ -33,15 +33,15 @@
   thread->isolate_group()->RunWithStoppedMutators([&]() {
     WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
     switch (breakpoint_kind_) {
-      case RawPcDescriptors::kIcCall: {
+      case PcDescriptorsLayout::kIcCall: {
         stub_target = StubCode::ICCallBreakpoint().raw();
         break;
       }
-      case RawPcDescriptors::kUnoptStaticCall: {
+      case PcDescriptorsLayout::kUnoptStaticCall: {
         stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
         break;
       }
-      case RawPcDescriptors::kRuntimeCall: {
+      case PcDescriptorsLayout::kRuntimeCall: {
         saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
         stub_target = StubCode::RuntimeCallBreakpoint().raw();
         break;
@@ -64,9 +64,9 @@
   thread->isolate_group()->RunWithStoppedMutators([&]() {
     WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
     switch (breakpoint_kind_) {
-      case RawPcDescriptors::kIcCall:
-      case RawPcDescriptors::kUnoptStaticCall:
-      case RawPcDescriptors::kRuntimeCall: {
+      case PcDescriptorsLayout::kIcCall:
+      case PcDescriptorsLayout::kUnoptStaticCall:
+      case PcDescriptorsLayout::kRuntimeCall: {
         CodePatcher::PatchStaticCallAt(pc_, code, Code::Handle(saved_value_));
         break;
       }
diff --git a/runtime/vm/debugger_x64.cc b/runtime/vm/debugger_x64.cc
index 883880f..dfb07df 100644
--- a/runtime/vm/debugger_x64.cc
+++ b/runtime/vm/debugger_x64.cc
@@ -8,7 +8,6 @@
 #include "vm/debugger.h"
 
 #include "vm/code_patcher.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/cpu.h"
 #include "vm/instructions.h"
 #include "vm/stub_code.h"
@@ -17,7 +16,7 @@
 
 #ifndef PRODUCT
 
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
 
@@ -25,13 +24,13 @@
   ASSERT(!is_enabled_);
   Code& stub_target = Code::Handle();
   switch (breakpoint_kind_) {
-    case RawPcDescriptors::kIcCall:
+    case PcDescriptorsLayout::kIcCall:
       stub_target = StubCode::ICCallBreakpoint().raw();
       break;
-    case RawPcDescriptors::kUnoptStaticCall:
+    case PcDescriptorsLayout::kUnoptStaticCall:
       stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
       break;
-    case RawPcDescriptors::kRuntimeCall:
+    case PcDescriptorsLayout::kRuntimeCall:
       stub_target = StubCode::RuntimeCallBreakpoint().raw();
       break;
     default:
@@ -47,9 +46,9 @@
   ASSERT(is_enabled_);
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
-    case RawPcDescriptors::kIcCall:
-    case RawPcDescriptors::kUnoptStaticCall:
-    case RawPcDescriptors::kRuntimeCall: {
+    case PcDescriptorsLayout::kIcCall:
+    case PcDescriptorsLayout::kUnoptStaticCall:
+    case PcDescriptorsLayout::kRuntimeCall: {
       CodePatcher::PatchPoolPointerCallAt(pc_, code,
                                           Code::Handle(saved_value_));
       break;
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index 2072c77..8e4b4c8 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -18,7 +18,7 @@
 DECLARE_FLAG(bool, trace_deoptimization_verbose);
 
 void DeferredDouble::Materialize(DeoptContext* deopt_context) {
-  RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
+  DoublePtr* double_slot = reinterpret_cast<DoublePtr*>(slot());
   *double_slot = Double::New(value());
 
   if (FLAG_trace_deoptimization_verbose) {
@@ -28,7 +28,7 @@
 }
 
 void DeferredMint::Materialize(DeoptContext* deopt_context) {
-  RawMint** mint_slot = reinterpret_cast<RawMint**>(slot());
+  MintPtr* mint_slot = reinterpret_cast<MintPtr*>(slot());
   ASSERT(!Smi::IsValid(value()));
   Mint& mint = Mint::Handle();
   mint ^= Integer::New(value());
@@ -41,43 +41,43 @@
 }
 
 void DeferredFloat32x4::Materialize(DeoptContext* deopt_context) {
-  RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot());
-  RawFloat32x4* raw_float32x4 = Float32x4::New(value());
+  Float32x4Ptr* float32x4_slot = reinterpret_cast<Float32x4Ptr*>(slot());
+  Float32x4Ptr raw_float32x4 = Float32x4::New(value());
   *float32x4_slot = raw_float32x4;
 
   if (FLAG_trace_deoptimization_verbose) {
-    float x = raw_float32x4->x();
-    float y = raw_float32x4->y();
-    float z = raw_float32x4->z();
-    float w = raw_float32x4->w();
+    float x = raw_float32x4->ptr()->x();
+    float y = raw_float32x4->ptr()->y();
+    float z = raw_float32x4->ptr()->z();
+    float w = raw_float32x4->ptr()->w();
     OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n",
                  reinterpret_cast<uword>(slot()), x, y, z, w);
   }
 }
 
 void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) {
-  RawFloat64x2** float64x2_slot = reinterpret_cast<RawFloat64x2**>(slot());
-  RawFloat64x2* raw_float64x2 = Float64x2::New(value());
+  Float64x2Ptr* float64x2_slot = reinterpret_cast<Float64x2Ptr*>(slot());
+  Float64x2Ptr raw_float64x2 = Float64x2::New(value());
   *float64x2_slot = raw_float64x2;
 
   if (FLAG_trace_deoptimization_verbose) {
-    double x = raw_float64x2->x();
-    double y = raw_float64x2->y();
+    double x = raw_float64x2->ptr()->x();
+    double y = raw_float64x2->ptr()->y();
     OS::PrintErr("materializing Float64x2 at %" Px ": %g,%g\n",
                  reinterpret_cast<uword>(slot()), x, y);
   }
 }
 
 void DeferredInt32x4::Materialize(DeoptContext* deopt_context) {
-  RawInt32x4** int32x4_slot = reinterpret_cast<RawInt32x4**>(slot());
-  RawInt32x4* raw_int32x4 = Int32x4::New(value());
+  Int32x4Ptr* int32x4_slot = reinterpret_cast<Int32x4Ptr*>(slot());
+  Int32x4Ptr raw_int32x4 = Int32x4::New(value());
   *int32x4_slot = raw_int32x4;
 
   if (FLAG_trace_deoptimization_verbose) {
-    uint32_t x = raw_int32x4->x();
-    uint32_t y = raw_int32x4->y();
-    uint32_t z = raw_int32x4->z();
-    uint32_t w = raw_int32x4->w();
+    uint32_t x = raw_int32x4->ptr()->x();
+    uint32_t y = raw_int32x4->ptr()->y();
+    uint32_t z = raw_int32x4->ptr()->z();
+    uint32_t w = raw_int32x4->ptr()->w();
     OS::PrintErr("materializing Int32x4 at %" Px ": %x,%x,%x,%x\n",
                  reinterpret_cast<uword>(slot()), x, y, z, w);
   }
@@ -107,7 +107,7 @@
   const Code& code = Code::Handle(zone, function.unoptimized_code());
 
   uword continue_at_pc =
-      code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kDeopt);
+      code.GetPcForDeoptId(deopt_id_, PcDescriptorsLayout::kDeopt);
   if (continue_at_pc == 0) {
     FATAL2("Can't locate continuation PC for deoptid %" Pd " within %s\n",
            deopt_id_, function.ToFullyQualifiedCString());
@@ -120,7 +120,7 @@
                  reinterpret_cast<uword>(slot()), continue_at_pc);
   }
 
-  uword pc = code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kIcCall);
+  uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptorsLayout::kIcCall);
   if (pc != 0) {
     // If the deoptimization happened at an IC call, update the IC data
     // to avoid repeated deoptimization at the same site next time around.
@@ -160,7 +160,7 @@
   const Code& code = Code::Handle(zone, function.unoptimized_code());
   ASSERT(!code.IsNull());
   ASSERT(function.HasCode());
-  *reinterpret_cast<RawObject**>(dest_addr) = code.raw();
+  *reinterpret_cast<ObjectPtr*>(dest_addr) = code.raw();
 
   if (FLAG_trace_deoptimization_verbose) {
     THR_Print("materializing pc marker at 0x%" Px ": %s, %s\n",
@@ -205,11 +205,11 @@
   if (FLAG_trace_deoptimization_verbose) {
     OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n",
                  reinterpret_cast<uword>(slot()),
-                 reinterpret_cast<uword>(code.GetObjectPool()));
+                 static_cast<uword>(code.GetObjectPool()));
   }
 }
 
-RawObject* DeferredObject::object() {
+ObjectPtr DeferredObject::object() {
   if (object_ == NULL) {
     Create();
   }
diff --git a/runtime/vm/deferred_objects.h b/runtime/vm/deferred_objects.h
index a46be13..f50c09a 100644
--- a/runtime/vm/deferred_objects.h
+++ b/runtime/vm/deferred_objects.h
@@ -6,13 +6,12 @@
 #define RUNTIME_VM_DEFERRED_OBJECTS_H_
 
 #include "platform/globals.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
 // Forward declarations.
 class Object;
-class RawObject;
-class RawObject;
 class DeoptContext;
 
 // Used by the deoptimization infrastructure to defer allocation of
@@ -21,17 +20,17 @@
 // the materialized object.
 class DeferredSlot {
  public:
-  DeferredSlot(RawObject** slot, DeferredSlot* next)
+  DeferredSlot(ObjectPtr* slot, DeferredSlot* next)
       : slot_(slot), next_(next) {}
   virtual ~DeferredSlot() {}
 
-  RawObject** slot() const { return slot_; }
+  ObjectPtr* slot() const { return slot_; }
   DeferredSlot* next() const { return next_; }
 
   virtual void Materialize(DeoptContext* deopt_context) = 0;
 
  private:
-  RawObject** const slot_;
+  ObjectPtr* const slot_;
   DeferredSlot* const next_;
 
   DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
@@ -39,7 +38,7 @@
 
 class DeferredDouble : public DeferredSlot {
  public:
-  DeferredDouble(double value, RawObject** slot, DeferredSlot* next)
+  DeferredDouble(double value, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), value_(value) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -54,7 +53,7 @@
 
 class DeferredMint : public DeferredSlot {
  public:
-  DeferredMint(int64_t value, RawObject** slot, DeferredSlot* next)
+  DeferredMint(int64_t value, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), value_(value) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -69,7 +68,7 @@
 
 class DeferredFloat32x4 : public DeferredSlot {
  public:
-  DeferredFloat32x4(simd128_value_t value, RawObject** slot, DeferredSlot* next)
+  DeferredFloat32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), value_(value) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -84,7 +83,7 @@
 
 class DeferredFloat64x2 : public DeferredSlot {
  public:
-  DeferredFloat64x2(simd128_value_t value, RawObject** slot, DeferredSlot* next)
+  DeferredFloat64x2(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), value_(value) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -99,7 +98,7 @@
 
 class DeferredInt32x4 : public DeferredSlot {
  public:
-  DeferredInt32x4(simd128_value_t value, RawObject** slot, DeferredSlot* next)
+  DeferredInt32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), value_(value) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -117,7 +116,7 @@
 // Object itself is described and materialized by DeferredObject.
 class DeferredObjectRef : public DeferredSlot {
  public:
-  DeferredObjectRef(intptr_t index, RawObject** slot, DeferredSlot* next)
+  DeferredObjectRef(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), index_(index) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -134,7 +133,7 @@
  public:
   DeferredRetAddr(intptr_t index,
                   intptr_t deopt_id,
-                  RawObject** slot,
+                  ObjectPtr* slot,
                   DeferredSlot* next)
       : DeferredSlot(slot, next), index_(index), deopt_id_(deopt_id) {}
 
@@ -151,7 +150,7 @@
 
 class DeferredPcMarker : public DeferredSlot {
  public:
-  DeferredPcMarker(intptr_t index, RawObject** slot, DeferredSlot* next)
+  DeferredPcMarker(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), index_(index) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -166,7 +165,7 @@
 
 class DeferredPp : public DeferredSlot {
  public:
-  DeferredPp(intptr_t index, RawObject** slot, DeferredSlot* next)
+  DeferredPp(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
       : DeferredSlot(slot, next), index_(index) {}
 
   virtual void Materialize(DeoptContext* deopt_context);
@@ -187,14 +186,14 @@
  public:
   DeferredObject(intptr_t field_count, intptr_t* args)
       : field_count_(field_count),
-        args_(reinterpret_cast<RawObject**>(args)),
+        args_(reinterpret_cast<ObjectPtr*>(args)),
         object_(NULL) {}
 
   intptr_t ArgumentCount() const {
     return kFieldsStartIndex + kFieldEntrySize * field_count_;
   }
 
-  RawObject* object();
+  ObjectPtr object();
 
   // Fill object with actual field values.
   void Fill();
@@ -218,19 +217,17 @@
   // a graph which can contain cycles.
   void Create();
 
-  RawObject* GetArg(intptr_t index) const {
-    return args_[index];
-  }
+  ObjectPtr GetArg(intptr_t index) const { return args_[index]; }
 
-  RawObject* GetClass() const { return GetArg(kClassIndex); }
+  ObjectPtr GetClass() const { return GetArg(kClassIndex); }
 
-  RawObject* GetLength() const { return GetArg(kLengthIndex); }
+  ObjectPtr GetLength() const { return GetArg(kLengthIndex); }
 
-  RawObject* GetFieldOffset(intptr_t index) const {
+  ObjectPtr GetFieldOffset(intptr_t index) const {
     return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kOffsetIndex);
   }
 
-  RawObject* GetValue(intptr_t index) const {
+  ObjectPtr GetValue(intptr_t index) const {
     return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kValueIndex);
   }
 
@@ -240,7 +237,7 @@
   // Pointer to the first materialization argument on the stack.
   // The first argument is Class of the instance to materialize followed by
   // Field, value pairs.
-  RawObject** args_;
+  ObjectPtr* args_;
 
   // Object materialized from this description.
   const Object* object_;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 3057977..360929b 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -179,15 +179,15 @@
 }
 
 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&code_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&object_pool_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&deopt_info_));
 
   // Visit any object pointers on the destination stack.
   if (dest_frame_is_allocated_) {
     for (intptr_t i = 0; i < dest_frame_size_; i++) {
       if (dest_frame_[i] != 0) {
-        visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i]));
+        visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&dest_frame_[i]));
       }
     }
   }
@@ -301,7 +301,7 @@
     if (!objects_only || IsObjectInstruction(instr->kind())) {
       instr->Execute(this, to_addr);
     } else {
-      *reinterpret_cast<RawObject**>(to_addr) = Object::null();
+      *reinterpret_cast<ObjectPtr*>(to_addr) = Object::null();
     }
   }
 
@@ -397,12 +397,12 @@
   return deopt_arg_count;
 }
 
-RawArray* DeoptContext::DestFrameAsArray() {
+ArrayPtr DeoptContext::DestFrameAsArray() {
   ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_);
   const Array& dest_array = Array::Handle(zone(), Array::New(dest_frame_size_));
   PassiveObject& obj = PassiveObject::Handle(zone());
   for (intptr_t i = 0; i < dest_frame_size_; i++) {
-    obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
+    obj = static_cast<ObjectPtr>(dest_frame_[i]);
     dest_array.SetAt(i, obj);
   }
   return dest_array.raw();
@@ -475,7 +475,7 @@
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     const PassiveObject& obj = PassiveObject::Handle(
         deopt_context->zone(), deopt_context->ObjectAt(object_table_index_));
-    *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
+    *reinterpret_cast<ObjectPtr*>(dest_addr) = obj.raw();
   }
 
   CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
@@ -534,7 +534,7 @@
     } else {
       *dest_addr = Smi::RawValue(0);
       deopt_context->DeferMintMaterialization(
-          value, reinterpret_cast<RawMint**>(dest_addr));
+          value, reinterpret_cast<MintPtr*>(dest_addr));
     }
   }
 
@@ -653,7 +653,7 @@
     *dest_addr = Smi::RawValue(0);
     deopt_context->DeferMaterialization(
         source_.Value<Type>(deopt_context),
-        reinterpret_cast<RawObjectType**>(dest_addr));
+        reinterpret_cast<RawObjectType*>(dest_addr));
   }
 
   CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
@@ -671,24 +671,24 @@
 typedef DeoptFpuInstr<DeoptInstr::kDouble,
                       CatchEntryMove::SourceKind::kDoubleSlot,
                       double,
-                      RawDouble>
+                      DoublePtr>
     DeoptDoubleInstr;
 
 // Simd128 types.
 typedef DeoptFpuInstr<DeoptInstr::kFloat32x4,
                       CatchEntryMove::SourceKind::kFloat32x4Slot,
                       simd128_value_t,
-                      RawFloat32x4>
+                      Float32x4Ptr>
     DeoptFloat32x4Instr;
 typedef DeoptFpuInstr<DeoptInstr::kFloat64x2,
                       CatchEntryMove::SourceKind::kFloat64x2Slot,
                       simd128_value_t,
-                      RawFloat64x2>
+                      Float64x2Ptr>
     DeoptFloat64x2Instr;
 typedef DeoptFpuInstr<DeoptInstr::kInt32x4,
                       CatchEntryMove::SourceKind::kInt32x4Slot,
                       simd128_value_t,
-                      RawInt32x4>
+                      Int32x4Ptr>
     DeoptInt32x4Instr;
 
 // Deoptimization instruction creating a PC marker for the code of
@@ -712,7 +712,7 @@
     Function& function = Function::Handle(deopt_context->zone());
     function ^= deopt_context->ObjectAt(object_table_index_);
     if (function.IsNull()) {
-      *reinterpret_cast<RawObject**>(dest_addr) =
+      *reinterpret_cast<ObjectPtr*>(dest_addr) =
           deopt_context->is_lazy_deopt()
               ? StubCode::DeoptimizeLazyFromReturn().raw()
               : StubCode::Deoptimize().raw();
@@ -724,7 +724,7 @@
     // marker until we can recreate that Code object during deferred
     // materialization to maintain the invariant that Dart frames always have
     // a pc marker.
-    *reinterpret_cast<RawObject**>(dest_addr) =
+    *reinterpret_cast<ObjectPtr*>(dest_addr) =
         StubCode::FrameAwaitingMaterialization().raw();
     deopt_context->DeferPcMarkerMaterialization(object_table_index_, dest_addr);
   }
@@ -755,7 +755,7 @@
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     *dest_addr = Smi::RawValue(0);
     deopt_context->DeferPpMaterialization(
-        object_table_index_, reinterpret_cast<RawObject**>(dest_addr));
+        object_table_index_, reinterpret_cast<ObjectPtr*>(dest_addr));
   }
 
  private:
@@ -831,7 +831,7 @@
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    *reinterpret_cast<SmiPtr*>(dest_addr) = Smi::New(0);
     deopt_context->DeferMaterializedObjectRef(index_, dest_addr);
   }
 
@@ -892,7 +892,7 @@
   *code = function.unoptimized_code();
   ASSERT(!code->IsNull());
   uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(),
-                                    RawPcDescriptors::kDeopt);
+                                    PcDescriptorsLayout::kDeopt);
   ASSERT(res != 0);
   return res;
 }
@@ -1237,7 +1237,7 @@
   return Thread::Current()->zone()->Realloc<uint8_t>(ptr, old_size, new_size);
 }
 
-RawTypedData* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
+TypedDataPtr DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
   intptr_t length = instructions_.length();
 
   // Count the number of instructions that are a shared suffix of some deopt
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 926ea1b..0c40fa9 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -4,10 +4,10 @@
 
 #ifndef RUNTIME_VM_DEOPT_INSTRUCTIONS_H_
 #define RUNTIME_VM_DEOPT_INSTRUCTIONS_H_
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/allocation.h"
 #include "vm/code_descriptors.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/deferred_objects.h"
@@ -19,6 +19,7 @@
 
 namespace dart {
 
+class Location;
 class Value;
 class MaterializeObjectInstr;
 class StackFrame;
@@ -69,7 +70,7 @@
   intptr_t GetCallerFp() const;
   void SetCallerFp(intptr_t callers_fp);
 
-  RawObject* ObjectAt(intptr_t index) const {
+  ObjectPtr ObjectAt(intptr_t index) const {
     const ObjectPool& object_pool = ObjectPool::Handle(object_pool_);
     return object_pool.ObjectAt(index);
   }
@@ -123,7 +124,7 @@
   intptr_t source_frame_size() const { return source_frame_size_; }
   intptr_t dest_frame_size() const { return dest_frame_size_; }
 
-  RawCode* code() const { return code_; }
+  CodePtr code() const { return code_; }
 
   bool is_lazy_deopt() const { return is_lazy_deopt_; }
 
@@ -134,7 +135,7 @@
     return (deopt_flags_ & flag) != 0;
   }
 
-  RawTypedData* deopt_info() const { return deopt_info_; }
+  TypedDataPtr deopt_info() const { return deopt_info_; }
 
   // Fills the destination frame but defers materialization of
   // objects.
@@ -149,53 +150,53 @@
   // artificial arguments used during deoptimization.
   intptr_t MaterializeDeferredObjects();
 
-  RawArray* DestFrameAsArray();
+  ArrayPtr DestFrameAsArray();
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
   void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
     deferred_slots_ = new DeferredObjectRef(
-        idx, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        idx, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
-  void DeferMaterialization(double value, RawDouble** slot) {
+  void DeferMaterialization(double value, DoublePtr* slot) {
     deferred_slots_ = new DeferredDouble(
-        value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
-  void DeferMintMaterialization(int64_t value, RawMint** slot) {
+  void DeferMintMaterialization(int64_t value, MintPtr* slot) {
     deferred_slots_ = new DeferredMint(
-        value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
-  void DeferMaterialization(simd128_value_t value, RawFloat32x4** slot) {
+  void DeferMaterialization(simd128_value_t value, Float32x4Ptr* slot) {
     deferred_slots_ = new DeferredFloat32x4(
-        value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
-  void DeferMaterialization(simd128_value_t value, RawFloat64x2** slot) {
+  void DeferMaterialization(simd128_value_t value, Float64x2Ptr* slot) {
     deferred_slots_ = new DeferredFloat64x2(
-        value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
-  void DeferMaterialization(simd128_value_t value, RawInt32x4** slot) {
+  void DeferMaterialization(simd128_value_t value, Int32x4Ptr* slot) {
     deferred_slots_ = new DeferredInt32x4(
-        value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
   void DeferRetAddrMaterialization(intptr_t index,
                                    intptr_t deopt_id,
                                    intptr_t* slot) {
     deferred_slots_ = new DeferredRetAddr(
-        index, deopt_id, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        index, deopt_id, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
   void DeferPcMarkerMaterialization(intptr_t index, intptr_t* slot) {
     deferred_slots_ = new DeferredPcMarker(
-        index, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+        index, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
   }
 
-  void DeferPpMaterialization(intptr_t index, RawObject** slot) {
+  void DeferPpMaterialization(intptr_t index, ObjectPtr* slot) {
     deferred_slots_ = new DeferredPp(index, slot, deferred_slots_);
   }
 
@@ -228,9 +229,9 @@
 
   intptr_t DeferredObjectsCount() const { return deferred_objects_count_; }
 
-  RawCode* code_;
-  RawObjectPool* object_pool_;
-  RawTypedData* deopt_info_;
+  CodePtr code_;
+  ObjectPoolPtr object_pool_;
+  TypedDataPtr deopt_info_;
   bool dest_frame_is_allocated_;
   intptr_t* dest_frame_;
   intptr_t dest_frame_size_;
@@ -387,7 +388,8 @@
       : source_index_(source_index) {}
 
   RegisterSource(Kind kind, intptr_t index)
-      : source_index_(KindField::encode(kind) | RawIndexField::encode(index)) {}
+      : source_index_(KindField::encode(kind) |
+                      IndexFieldLayout::encode(index)) {}
 
   template <typename T>
   T Value(DeoptContext* context) const {
@@ -417,13 +419,13 @@
 
  private:
   class KindField : public BitField<intptr_t, intptr_t, 0, 1> {};
-  class RawIndexField
+  class IndexFieldLayout
       : public BitField<intptr_t, intptr_t, 1, kBitsPerWord - 1> {};
 
   bool is_register() const {
     return KindField::decode(source_index_) == kRegister;
   }
-  intptr_t raw_index() const { return RawIndexField::decode(source_index_); }
+  intptr_t raw_index() const { return IndexFieldLayout::decode(source_index_); }
 
   RegisterType reg() const { return static_cast<RegisterType>(raw_index()); }
 
@@ -479,7 +481,7 @@
   // Returns the index of the next stack slot. Used for verification.
   intptr_t EmitMaterializationArguments(intptr_t dest_index);
 
-  RawTypedData* CreateDeoptInfo(const Array& deopt_table);
+  TypedDataPtr CreateDeoptInfo(const Array& deopt_table);
 
   // Mark the actual start of the frame description after all materialization
   // instructions were emitted. Used for verification purposes.
@@ -558,8 +560,8 @@
                        TypedData* info,
                        Smi* reason_and_flags);
 
-  static RawSmi* EncodeReasonAndFlags(ICData::DeoptReasonId reason,
-                                      uint32_t flags) {
+  static SmiPtr EncodeReasonAndFlags(ICData::DeoptReasonId reason,
+                                     uint32_t flags) {
     return Smi::New(ReasonField::encode(reason) | FlagsField::encode(flags));
   }
 
@@ -615,4 +617,5 @@
 
 }  // namespace dart
 
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_DEOPT_INSTRUCTIONS_H_
diff --git a/runtime/vm/double_conversion.cc b/runtime/vm/double_conversion.cc
index b3784ab..7357658 100644
--- a/runtime/vm/double_conversion.cc
+++ b/runtime/vm/double_conversion.cc
@@ -50,7 +50,7 @@
   ASSERT(result == buffer);
 }
 
-RawString* DoubleToStringAsFixed(double d, int fraction_digits) {
+StringPtr DoubleToStringAsFixed(double d, int fraction_digits) {
   static const int kMinFractionDigits = 0;
   static const int kMaxFractionDigits = 20;
   static const int kMaxDigitsBeforePoint = 20;
@@ -91,7 +91,7 @@
   return String::New(builder.Finalize());
 }
 
-RawString* DoubleToStringAsExponential(double d, int fraction_digits) {
+StringPtr DoubleToStringAsExponential(double d, int fraction_digits) {
   static const int kMinFractionDigits = -1;  // -1 represents shortest mode.
   static const int kMaxFractionDigits = 20;
   static const int kConversionFlags =
@@ -122,7 +122,7 @@
   return String::New(builder.Finalize());
 }
 
-RawString* DoubleToStringAsPrecision(double d, int precision) {
+StringPtr DoubleToStringAsPrecision(double d, int precision) {
   static const int kMinPrecisionDigits = 1;
   static const int kMaxPrecisionDigits = 21;
   static const int kMaxLeadingPaddingZeroes = 6;
diff --git a/runtime/vm/double_conversion.h b/runtime/vm/double_conversion.h
index 8793649..27a8172 100644
--- a/runtime/vm/double_conversion.h
+++ b/runtime/vm/double_conversion.h
@@ -18,9 +18,9 @@
 };
 
 void DoubleToCString(double d, char* buffer, int buffer_size);
-RawString* DoubleToStringAsFixed(double d, int fraction_digits);
-RawString* DoubleToStringAsExponential(double d, int fraction_digits);
-RawString* DoubleToStringAsPrecision(double d, int precision);
+StringPtr DoubleToStringAsFixed(double d, int fraction_digits);
+StringPtr DoubleToStringAsExponential(double d, int fraction_digits);
+StringPtr DoubleToStringAsPrecision(double d, int precision);
 
 bool CStringToDouble(const char* str, intptr_t length, double* result);
 
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 9654d8e..a90dfa2 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -87,36 +87,49 @@
   intptr_t section_info = 0;
   intptr_t section_entry_size = 0;
 
+  static constexpr intptr_t kInitValue = -1;
+
 #define FOR_EACH_SECTION_LINEAR_FIELD(M)                                       \
-  M(section_name, intptr_t, -1)                                                \
-  M(section_index, intptr_t, -1)                                               \
-  M(file_offset, intptr_t, -1)
+  M(section_name, intptr_t, kInitValue)                                        \
+  M(section_index, intptr_t, kInitValue)                                       \
+  M(file_offset, intptr_t, kInitValue)
 
   FOR_EACH_SECTION_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);
 
-  virtual intptr_t FileSize() = 0;
+  virtual intptr_t FileSize() const = 0;
 
   // Loader view.
   const intptr_t segment_type;
   const intptr_t segment_flags;
 
-#define FOR_EACH_SEGMENT_LINEAR_FIELD(M) M(memory_offset, intptr_t, -1)
+#define FOR_EACH_SEGMENT_LINEAR_FIELD(M) M(memory_offset, intptr_t, kInitValue)
 
   FOR_EACH_SEGMENT_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);
 
-  virtual intptr_t MemorySize() = 0;
+  virtual intptr_t MemorySize() const = 0;
 
   // Other methods.
+  bool IsSegment() const { return segment_type != 0; }
+  // Returns whether new content can be added to a section.
+  bool HasBeenFinalized() const {
+    if (IsSegment()) {
+      // The contents of a segment must not change after the segment is added
+      // (when its memory offset is calculated).
+      return memory_offset_ != kInitValue;
+    } else {
+      // Sections with an in-memory segment can have new content added until
+      // we calculate file offsets.
+      return file_offset_ != kInitValue;
+    }
+  }
+
   virtual void Write(Elf* stream) = 0;
 
-  void WriteSegmentEntry(Elf* stream, bool dynamic = false) {
-    // This should never be used on either the reserved 0-filled section or
-    // on sections without a segment.
+  void WriteSegmentEntry(Elf* stream) {
+    // This should never be used on sections without a segment.
     ASSERT(MemorySize() > 0);
-    // dynamic should only be true if this section is the dynamic table.
-    ASSERT(!dynamic || section_type == elf::SHT_DYNAMIC);
 #if defined(TARGET_ARCH_IS_32_BIT)
-    stream->WriteWord(dynamic ? elf::PT_DYNAMIC : segment_type);
+    stream->WriteWord(segment_type);
     stream->WriteOff(file_offset());
     stream->WriteAddr(memory_offset());  // Virtual address.
     stream->WriteAddr(memory_offset());  // Physical address, not used.
@@ -125,7 +138,7 @@
     stream->WriteWord(segment_flags);
     stream->WriteWord(alignment);
 #else
-    stream->WriteWord(dynamic ? elf::PT_DYNAMIC : segment_type);
+    stream->WriteWord(segment_type);
     stream->WriteWord(segment_flags);
     stream->WriteOff(file_offset());
     stream->WriteAddr(memory_offset());  // Virtual address.
@@ -198,8 +211,7 @@
 #undef DEFINE_LINEAR_FIELD_METHODS
 
 // Represents the first entry in the section table, which should only contain
-// zero values. Only used for WriteSectionEntry and should never actually appear
-// in sections_.
+// zero values and does not correspond to a memory segment.
 class ReservedSection : public Section {
  public:
   ReservedSection()
@@ -213,9 +225,9 @@
     set_file_offset(0);
   }
 
-  intptr_t FileSize() { return 0; }
-  intptr_t MemorySize() { return 0; }
-  void Write(Elf* stream) { UNREACHABLE(); }
+  intptr_t FileSize() const { return 0; }
+  intptr_t MemorySize() const { return 0; }
+  void Write(Elf* stream) {}
 };
 
 class BlobSection : public Section {
@@ -248,8 +260,8 @@
                     memsz,
                     alignment) {}
 
-  intptr_t FileSize() { return file_size_; }
-  intptr_t MemorySize() { return memory_size_; }
+  intptr_t FileSize() const { return file_size_; }
+  intptr_t MemorySize() const { return memory_size_; }
 
   virtual void Write(Elf* stream) = 0;
 
@@ -258,11 +270,11 @@
   const intptr_t memory_size_;
 };
 
-// A section for representing the program header segment in the program header
-// table. Only used for WriteSegmentEntry.
-class ProgramTable : public BlobSection {
+// A segment for representing the program header table self-reference in the
+// program header table. There is no corresponding section for this segment.
+class ProgramTableSelfSegment : public BlobSection {
  public:
-  ProgramTable(intptr_t offset, intptr_t size)
+  ProgramTableSelfSegment(intptr_t offset, intptr_t size)
       : BlobSection(/*type=*/0,
                     /*segment_type=*/elf::PT_PHDR,
                     /*allocate=*/true,
@@ -274,13 +286,12 @@
     set_memory_offset(offset);
   }
 
-  // This should never actually be added to sections_ or segments_.
   void Write(Elf* stream) { UNREACHABLE(); }
 };
 
-// A section for representing the program header table load segment in the
-// program header table. Only used for WriteSegmentEntry.
-class ProgramTableLoad : public BlobSection {
+// A segment for representing the program header table load segment in the
+// program header table. There is no corresponding section for this segment.
+class ProgramTableLoadSegment : public BlobSection {
  public:
   // The Android dynamic linker in Jelly Bean incorrectly assumes that all
   // non-writable segments are continguous. Since the BSS segment comes directly
@@ -290,7 +301,7 @@
   //
   // The bug is here:
   //   https://github.com/aosp-mirror/platform_bionic/blob/94963af28e445384e19775a838a29e6a71708179/linker/linker.c#L1991-L2001
-  explicit ProgramTableLoad(intptr_t size)
+  explicit ProgramTableLoadSegment(intptr_t size)
       : BlobSection(/*type=*/0,
                     /*allocate=*/true,
                     /*executable=*/false,
@@ -301,7 +312,6 @@
     set_memory_offset(0);
   }
 
-  // This should never actually be added to sections_ or segments_.
   void Write(Elf* stream) { UNREACHABLE(); }
 };
 
@@ -353,8 +363,8 @@
     text_indices_.Insert({"", 1});
   }
 
-  intptr_t FileSize() { return text_.length(); }
-  intptr_t MemorySize() { return dynamic_ ? FileSize() : 0; }
+  intptr_t FileSize() const { return text_.length(); }
+  intptr_t MemorySize() const { return dynamic_ ? FileSize() : 0; }
 
   void Write(Elf* stream) {
     stream->WriteBytes(reinterpret_cast<const uint8_t*>(text_.buffer()),
@@ -435,8 +445,8 @@
     section_info = 1;  // One "local" symbol, the reserved first entry.
   }
 
-  intptr_t FileSize() { return Length() * kElfSymbolTableEntrySize; }
-  intptr_t MemorySize() { return dynamic_ ? FileSize() : 0; }
+  intptr_t FileSize() const { return Length() * kElfSymbolTableEntrySize; }
+  intptr_t MemorySize() const { return dynamic_ ? FileSize() : 0; }
 
   void Write(Elf* stream) {
     for (intptr_t i = 0; i < Length(); i++) {
@@ -503,8 +513,8 @@
     }
   }
 
-  intptr_t FileSize() { return 4 * (nbucket_ + nchain_ + 2); }
-  intptr_t MemorySize() { return FileSize(); }
+  intptr_t FileSize() const { return 4 * (nbucket_ + nchain_ + 2); }
+  intptr_t MemorySize() const { return FileSize(); }
 
   void Write(Elf* stream) {
     stream->WriteWord(nbucket_);
@@ -543,8 +553,10 @@
     AddEntry(elf::DT_NULL, 0);
   }
 
-  intptr_t FileSize() { return entries_.length() * kElfDynamicTableEntrySize; }
-  intptr_t MemorySize() { return FileSize(); }
+  intptr_t FileSize() const {
+    return entries_.length() * kElfDynamicTableEntrySize;
+  }
+  intptr_t MemorySize() const { return FileSize(); }
 
   void Write(Elf* stream) {
     for (intptr_t i = 0; i < entries_.length(); i++) {
@@ -578,12 +590,23 @@
   GrowableArray<Entry*> entries_;
 };
 
-// The first section must be written out and contains only zeros.
-static const intptr_t kNumInvalidSections = 1;
+// A segment for representing the dynamic table segment in the program header
+// table. There is no corresponding section for this segment.
+class DynamicSegment : public BlobSection {
+ public:
+  explicit DynamicSegment(DynamicTable* dynamic)
+      : BlobSection(dynamic->section_type,
+                    /*segment_type=*/elf::PT_DYNAMIC,
+                    /*allocate=*/true,
+                    /*executable=*/false,
+                    /*writable=*/true,
+                    /*filesz=*/dynamic->FileSize(),
+                    /*memsz=*/dynamic->MemorySize()) {
+    set_memory_offset(dynamic->memory_offset());
+  }
 
-// Extra segments put in the program table that aren't reified in
-// Elf::segments_.
-static const intptr_t kNumImplicitSegments = 3;
+  void Write(Elf* stream) { UNREACHABLE(); }
+};
 
 static const intptr_t kProgramTableSegmentSize = Elf::kPageSize;
 
@@ -596,14 +619,22 @@
       memory_offset_(kProgramTableSegmentSize) {
   // Assumed by various offset logic in this file.
   ASSERT(stream_->position() == 0);
+  // The first section in the section header table is always a reserved
+  // entry containing only 0 values.
+  sections_.Add(new (zone_) ReservedSection());
+  // Go ahead and add the section header string table, since it doesn't have
+  // an in-memory segment and so can be added to until we compute file offsets.
+  AddSection(shstrtab_, ".shstrtab");
 }
 
 void Elf::AddSection(Section* section, const char* name) {
-  ASSERT(shstrtab_ != nullptr);
+  ASSERT(section_table_file_size_ < 0);
+  ASSERT(!shstrtab_->HasBeenFinalized());
   section->set_section_name(shstrtab_->AddString(name));
-  section->set_section_index(sections_.length() + kNumInvalidSections);
+  section->set_section_index(sections_.length());
   sections_.Add(section);
   if (section->MemorySize() > 0) {
+    ASSERT(program_table_file_size_ < 0);
     memory_offset_ = Utils::RoundUp(memory_offset_, section->alignment);
     section->set_memory_offset(memory_offset_);
     segments_.Add(section);
@@ -612,17 +643,10 @@
   }
 }
 
-intptr_t Elf::NextMemoryOffset() const {
-  return memory_offset_;
-}
-
-intptr_t Elf::NextSectionIndex() const {
-  return sections_.length() + kNumInvalidSections;
-}
-
 intptr_t Elf::AddSectionSymbol(const Section* section,
                                const char* name,
                                intptr_t size) {
+  ASSERT(!dynstrtab_->HasBeenFinalized() && !dynsym_->HasBeenFinalized());
   auto const name_index = dynstrtab_->AddString(name);
   auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
   auto const section_index = section->section_index();
@@ -656,10 +680,15 @@
   // symbols in unstripped ELF files.
   if (strtab_ == nullptr) {
     ASSERT(symtab_ == nullptr);
+    ASSERT(section_table_file_size_ < 0);
     strtab_ = new (zone_) StringTable(/* allocate= */ false);
+    AddSection(strtab_, ".strtab");
     symtab_ = new (zone_) SymbolTable(/*dynamic=*/false);
+    AddSection(symtab_, ".symtab");
+    symtab_->section_link = strtab_->section_index();
   }
 
+  ASSERT(!strtab_->HasBeenFinalized() && !symtab_->HasBeenFinalized());
   auto const name_index = strtab_->AddString(name);
   auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
   Symbol* symbol =
@@ -699,6 +728,8 @@
 }
 
 void Elf::Finalize() {
+  // Unlike the static tables, we must wait until finalization to add the
+  // dynamic tables, as adding them marks them as finalized.
   AddSection(dynstrtab_, ".dynstr");
   AddSection(dynsym_, ".dynsym");
   dynsym_->section_link = dynstrtab_->section_index();
@@ -706,45 +737,81 @@
   auto const hash = new (zone_) SymbolHashTable(dynstrtab_, dynsym_);
   AddSection(hash, ".hash");
 
-  if (symtab_ != nullptr) {
-    ASSERT(strtab_ != nullptr);
-    AddSection(strtab_, ".strtab");
-    AddSection(symtab_, ".symtab");
-    symtab_->section_link = strtab_->section_index();
-  }
-
   dynamic_ = new (zone_) DynamicTable(dynstrtab_, dynsym_, hash);
   AddSection(dynamic_, ".dynamic");
 
-  AddSection(shstrtab_, ".shstrtab");
+  // Also add a PT_DYNAMIC segment for the dynamic symbol table.
+  dynamic_segment_ = new (zone_) DynamicSegment(dynamic_);
+  segments_.Add(dynamic_segment_);
 
+  // At this point, all sections and user-defined segments have been added. Add
+  // any program table-specific segments and then calculate file offsets for all
+  // sections and segments.
+  FinalizeProgramTable();
   ComputeFileOffsets();
 
+  // Finally, write the ELF file contents.
   WriteHeader();
   WriteProgramTable();
   WriteSections();
   WriteSectionTable();
 }
 
-void Elf::ComputeFileOffsets() {
-  intptr_t file_offset = kElfHeaderSize;
+void Elf::FinalizeProgramTable() {
+  ASSERT(program_table_file_size_ < 0);
 
-  program_table_file_offset_ = file_offset;
+  program_table_file_offset_ = kElfHeaderSize;
+
+  // There are two segments we need the size of the program table to create, so
+  // calculate it as if those two segments were already in place.
   program_table_file_size_ =
-      (segments_.length() + kNumImplicitSegments) * kElfProgramTableEntrySize;
-  file_offset += program_table_file_size_;
+      (2 + segments_.length()) * kElfProgramTableEntrySize;
 
-  for (intptr_t i = 0; i < sections_.length(); i++) {
+  // We pre-allocated the virtual memory space for the program table itself.
+  // Check that we didn't generate too many segments. Currently we generate a
+  // fixed num of segments based on the four pieces of a snapshot, but if we
+  // use more in the future we'll likely need to do something more compilated
+  // to generate DWARF without knowing a piece's virtual address in advance.
+  auto const program_table_segment_size =
+      program_table_file_offset_ + program_table_file_size_;
+  RELEASE_ASSERT(program_table_segment_size < kProgramTableSegmentSize);
+
+  // Self-reference to program header table. Required by Android but not by
+  // Linux. Must appear before any PT_LOAD entries.
+  segments_.InsertAt(
+      0, new (zone_) ProgramTableSelfSegment(program_table_file_offset_,
+                                             program_table_file_size_));
+
+  // Segment for loading the initial part of the ELF file, including the
+  // program header table. Required by Android but not by Linux.
+  segments_.InsertAt(
+      1, new (zone_) ProgramTableLoadSegment(program_table_segment_size));
+}
+
+void Elf::ComputeFileOffsets() {
+  // We calculate the size and offset of the program header table during
+  // finalization.
+  ASSERT(program_table_file_offset_ > 0 && program_table_file_size_ > 0);
+  intptr_t file_offset = program_table_file_offset_ + program_table_file_size_;
+
+  // The first (reserved) section's file offset is set to 0 during construction,
+  // so skip it.
+  ASSERT(sections_.length() >= 1 && sections_[0]->section_type == 0);
+  // The others are output to the file in order after the program header table.
+  for (intptr_t i = 1; i < sections_.length(); i++) {
     Section* section = sections_[i];
     file_offset = Utils::RoundUp(file_offset, section->alignment);
     section->set_file_offset(file_offset);
     file_offset += section->FileSize();
   }
 
+  // Make the dynamic segment's file offset the same as the dynamic table now
+  // that it's been calculated for the latter.
+  dynamic_segment_->set_file_offset(dynamic_->file_offset());
+
   file_offset = Utils::RoundUp(file_offset, kElfSectionTableAlignment);
   section_table_file_offset_ = file_offset;
-  section_table_file_size_ =
-      (sections_.length() + kNumInvalidSections) * kElfSectionTableEntrySize;
+  section_table_file_size_ = sections_.length() * kElfSectionTableEntrySize;
   file_offset += section_table_file_size_;
 }
 
@@ -802,9 +869,9 @@
 
   WriteHalf(kElfHeaderSize);
   WriteHalf(kElfProgramTableEntrySize);
-  WriteHalf(segments_.length() + kNumImplicitSegments);
+  WriteHalf(segments_.length());
   WriteHalf(kElfSectionTableEntrySize);
-  WriteHalf(sections_.length() + kNumInvalidSections);
+  WriteHalf(sections_.length());
   WriteHalf(shstrtab_->section_index());
 
   ASSERT(stream_->position() == kElfHeaderSize);
@@ -813,41 +880,6 @@
 void Elf::WriteProgramTable() {
   ASSERT(stream_->position() == program_table_file_offset_);
 
-  // Self-reference to program header table. Required by Android but not by
-  // Linux. Must appear before any PT_LOAD entries.
-  {
-    ProgramTable program_table(program_table_file_offset_,
-                               program_table_file_size_);
-
-    ASSERT(kNumImplicitSegments == 3);
-    const intptr_t start = stream_->position();
-    program_table.WriteSegmentEntry(this);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfProgramTableEntrySize);
-  }
-  // Load for self-reference to program header table. Required by Android but
-  // not by Linux.
-  {
-    // We pre-allocated the virtual memory space for the program table itself.
-    // Check that we didn't generate too many segments. Currently we generate a
-    // fixed num of segments based on the four pieces of a snapshot, but if we
-    // use more in the future we'll likely need to do something more compilated
-    // to generate DWARF without knowing a piece's virtual address in advance.
-    auto const program_table_segment_size =
-        program_table_file_offset_ + program_table_file_size_;
-    RELEASE_ASSERT(program_table_segment_size < kProgramTableSegmentSize);
-
-    // We create a section that, when printed as a segment, contains the
-    // appropriate info for the program table.
-    ProgramTableLoad program_table_load(program_table_segment_size);
-
-    ASSERT(kNumImplicitSegments == 3);
-    const intptr_t start = stream_->position();
-    program_table_load.WriteSegmentEntry(this);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfProgramTableEntrySize);
-  }
-
   for (intptr_t i = 0; i < segments_.length(); i++) {
     Section* section = segments_[i];
     const intptr_t start = stream_->position();
@@ -855,16 +887,6 @@
     const intptr_t end = stream_->position();
     ASSERT((end - start) == kElfProgramTableEntrySize);
   }
-
-  // Special case: the dynamic section requires both LOAD and DYNAMIC program
-  // header table entries.
-  {
-    ASSERT(kNumImplicitSegments == 3);
-    const intptr_t start = stream_->position();
-    dynamic_->WriteSegmentEntry(this, /*dynamic=*/true);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfProgramTableEntrySize);
-  }
 }
 
 void Elf::WriteSectionTable() {
@@ -872,16 +894,6 @@
 
   ASSERT(stream_->position() == section_table_file_offset_);
 
-  {
-    // The first entry in the section table is reserved and must be all zeros.
-    ASSERT(kNumInvalidSections == 1);
-    const intptr_t start = stream_->position();
-    ReservedSection reserved;
-    reserved.WriteSectionEntry(this);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfSectionTableEntrySize);
-  }
-
   for (intptr_t i = 0; i < sections_.length(); i++) {
     Section* section = sections_[i];
     const intptr_t start = stream_->position();
@@ -892,7 +904,10 @@
 }
 
 void Elf::WriteSections() {
-  for (intptr_t i = 0; i < sections_.length(); i++) {
+  // Skip the reserved first section, as its alignment is 0 and it does not
+  // contain any contents.
+  ASSERT(sections_[0]->alignment == 0 && sections_[0]->section_type == 0);
+  for (intptr_t i = 1; i < sections_.length(); i++) {
     Section* section = sections_[i];
     stream_->Align(section->alignment);
     ASSERT(stream_->position() == section->file_offset());
diff --git a/runtime/vm/elf.h b/runtime/vm/elf.h
index 4cd877a..1adad3a 100644
--- a/runtime/vm/elf.h
+++ b/runtime/vm/elf.h
@@ -13,6 +13,7 @@
 
 namespace dart {
 
+class DynamicSegment;
 class DynamicTable;
 class Section;
 class StringTable;
@@ -25,8 +26,8 @@
 
   static const intptr_t kPageSize = 4096;
 
-  intptr_t NextMemoryOffset() const;
-  intptr_t NextSectionIndex() const;
+  intptr_t NextMemoryOffset() const { return memory_offset_; }
+  intptr_t NextSectionIndex() const { return sections_.length(); }
   intptr_t AddText(const char* name, const uint8_t* bytes, intptr_t size);
   intptr_t AddROData(const char* name, const uint8_t* bytes, intptr_t size);
   intptr_t AddBSSData(const char* name, intptr_t size);
@@ -69,6 +70,7 @@
                             const char* name,
                             intptr_t size);
 
+  void FinalizeProgramTable();
   void ComputeFileOffsets();
   void WriteHeader();
   void WriteSectionTable();
@@ -86,6 +88,7 @@
 
   // Can only be created once the dynamic symbol table is complete.
   DynamicTable* dynamic_ = nullptr;
+  DynamicSegment* dynamic_segment_ = nullptr;
 
   // The static tables are lazily created when static symbols are added.
   StringTable* strtab_ = nullptr;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 6ed1a09..3bcb484 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -69,8 +69,9 @@
       : stacktrace_(StackTrace::Cast(stacktrace)),
         cur_index_(0),
         dropped_frames_(0) {
-    ASSERT(stacktrace_.raw() ==
-           Isolate::Current()->object_store()->preallocated_stack_trace());
+    ASSERT(
+        stacktrace_.raw() ==
+        Isolate::Current()->isolate_object_store()->preallocated_stack_trace());
   }
   ~PreallocatedStackTraceBuilder() {}
 
@@ -360,8 +361,8 @@
     return reinterpret_cast<T*>(fp + frame_slot * kWordSize);
   }
 
-  static RawObject** TaggedSlotAt(uword fp, int stack_slot) {
-    return SlotAt<RawObject*>(fp, stack_slot);
+  static ObjectPtr* TaggedSlotAt(uword fp, int stack_slot) {
+    return SlotAt<ObjectPtr>(fp, stack_slot);
   }
 
   typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader;
@@ -597,7 +598,7 @@
 
 #if defined(DEBUG)
           // Ensure the frame references optimized code.
-          RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
+          ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
               frame_pointer + runtime_frame_layout.code_from_fp * kWordSize));
           Code& code = Code::Handle(Code::RawCast(pc_marker));
           ASSERT(code.is_optimized() && !code.is_force_optimized());
@@ -738,7 +739,7 @@
   UNREACHABLE();
 }
 
-static RawField* LookupStackTraceField(const Instance& instance) {
+static FieldPtr LookupStackTraceField(const Instance& instance) {
   if (instance.GetClassId() < kNumPredefinedCids) {
     // 'class Error' is not a predefined class.
     return Field::null();
@@ -770,7 +771,7 @@
   return Field::null();
 }
 
-RawStackTrace* Exceptions::CurrentStackTrace() {
+StackTracePtr Exceptions::CurrentStackTrace() {
   return GetStackTraceForException();
 }
 
@@ -815,11 +816,12 @@
       ASSERT(incoming_exception.raw() ==
              isolate->object_store()->out_of_memory());
       const UnhandledException& error = UnhandledException::Handle(
-          zone, isolate->object_store()->preallocated_unhandled_exception());
+          zone,
+          isolate->isolate_object_store()->preallocated_unhandled_exception());
       thread->long_jump_base()->Jump(1, error);
       UNREACHABLE();
     }
-    stacktrace = isolate->object_store()->preallocated_stack_trace();
+    stacktrace = isolate->isolate_object_store()->preallocated_stack_trace();
     PreallocatedStackTraceBuilder frame_builder(stacktrace);
     ASSERT(existing_stacktrace.IsNull() ||
            (existing_stacktrace.raw() == stacktrace.raw()));
@@ -889,7 +891,7 @@
 
 // Return the script of the Dart function that called the native entry or the
 // runtime entry. The frame iterator points to the callee.
-RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) {
+ScriptPtr Exceptions::GetCallerScript(DartFrameIterator* iterator) {
   StackFrame* caller_frame = iterator->NextFrame();
   ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
   const Function& caller = Function::Handle(caller_frame->LookupDartFunction());
@@ -904,7 +906,7 @@
 // Allocate a new instance of the given class name.
 // TODO(hausner): Rename this NewCoreInstance to call out the fact that
 // the class name is resolved in the core library implicitly?
-RawInstance* Exceptions::NewInstance(const char* class_name) {
+InstancePtr Exceptions::NewInstance(const char* class_name) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const String& cls_name =
@@ -1120,7 +1122,13 @@
   Exceptions::ThrowByType(Exceptions::kCompileTimeError, args);
 }
 
-RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
+void Exceptions::ThrowLateInitializationError(const String& name) {
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, name);
+  Exceptions::ThrowByType(Exceptions::kLateInitializationError, args);
+}
+
+ObjectPtr Exceptions::Create(ExceptionType type, const Array& arguments) {
   Library& library = Library::Handle();
   const String* class_name = NULL;
   const String* constructor_name = &Symbols::Dot();
@@ -1207,6 +1215,10 @@
       library = Library::CoreLibrary();
       class_name = &Symbols::_CompileTimeError();
       break;
+    case kLateInitializationError:
+      library = Library::CoreLibrary();
+      class_name = &Symbols::LateInitializationError();
+      break;
   }
 
   Thread* thread = Thread::Current();
@@ -1215,4 +1227,16 @@
                                           *constructor_name, arguments);
 }
 
+UnhandledExceptionPtr Exceptions::CreateUnhandledException(Zone* zone,
+                                                           ExceptionType type,
+                                                           const char* msg) {
+  const String& error_str = String::Handle(zone, String::New(msg));
+  const Array& args = Array::Handle(zone, Array::New(1));
+  args.SetAt(0, error_str);
+
+  Object& result = Object::Handle(zone, Exceptions::Create(type, args));
+  const StackTrace& stacktrace = StackTrace::Handle(zone);
+  return UnhandledException::New(Instance::Cast(result), stacktrace);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 40bc68a..430d7a9 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -7,6 +7,7 @@
 
 #include "vm/allocation.h"
 #include "vm/bitfield.h"
+#include "vm/tagged_pointer.h"
 #include "vm/token_position.h"
 
 namespace dart {
@@ -19,10 +20,6 @@
 class LanguageError;
 class Instance;
 class Integer;
-class RawInstance;
-class RawObject;
-class RawScript;
-class RawStackTrace;
 class ReadStream;
 class WriteStream;
 class String;
@@ -41,9 +38,9 @@
   DART_NORETURN static void PropagateToEntry(const Error& error);
 
   // Helpers to create and throw errors.
-  static RawStackTrace* CurrentStackTrace();
-  static RawScript* GetCallerScript(DartFrameIterator* iterator);
-  static RawInstance* NewInstance(const char* class_name);
+  static StackTracePtr CurrentStackTrace();
+  static ScriptPtr GetCallerScript(DartFrameIterator* iterator);
+  static InstancePtr NewInstance(const char* class_name);
   static void CreateAndThrowTypeError(TokenPosition location,
                                       const AbstractType& src_type,
                                       const AbstractType& dst_type,
@@ -70,6 +67,7 @@
     kAbstractClassInstantiation,
     kCyclicInitializationError,
     kCompileTimeError,
+    kLateInitializationError,
   };
 
   DART_NORETURN static void ThrowByType(ExceptionType type,
@@ -85,10 +83,17 @@
                                             intptr_t expected_to);
   DART_NORETURN static void ThrowUnsupportedError(const char* msg);
   DART_NORETURN static void ThrowCompileTimeError(const LanguageError& error);
+  DART_NORETURN static void ThrowLateInitializationError(const String& name);
 
   // Returns a RawInstance if the exception is successfully created,
   // otherwise returns a RawError.
-  static RawObject* Create(ExceptionType type, const Array& arguments);
+  static ObjectPtr Create(ExceptionType type, const Array& arguments);
+
+  // Returns RawUnhandledException that wraps exception of type [type] with
+  // [msg] as a single argument.
+  static UnhandledExceptionPtr CreateUnhandledException(Zone* zone,
+                                                        ExceptionType type,
+                                                        const char* msg);
 
   DART_NORETURN static void JumpToFrame(Thread* thread,
                                         uword program_counter,
diff --git a/runtime/vm/ffi_callback_trampolines.cc b/runtime/vm/ffi_callback_trampolines.cc
index 6475a3d..4bf926e 100644
--- a/runtime/vm/ffi_callback_trampolines.cc
+++ b/runtime/vm/ffi_callback_trampolines.cc
@@ -3,11 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/ffi_callback_trampolines.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/code_comments.h"
 #include "vm/code_observers.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/exceptions.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
diff --git a/runtime/vm/ffi_callback_trampolines.h b/runtime/vm/ffi_callback_trampolines.h
index 7328828..26143be 100644
--- a/runtime/vm/ffi_callback_trampolines.h
+++ b/runtime/vm/ffi_callback_trampolines.h
@@ -1,15 +1,17 @@
 // 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_FFI_CALLBACK_TRAMPOLINES_H_
+#define RUNTIME_VM_FFI_CALLBACK_TRAMPOLINES_H_
 
 #include "platform/allocation.h"
 #include "platform/growable_array.h"
-#include "vm/compiler/stub_code_compiler.h"
 #include "vm/flag_list.h"
 #include "vm/virtual_memory.h"
 
-#ifndef RUNTIME_VM_FFI_CALLBACK_TRAMPOLINES_H_
-#define RUNTIME_VM_FFI_CALLBACK_TRAMPOLINES_H_
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/stub_code_compiler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
diff --git a/runtime/vm/field_table.cc b/runtime/vm/field_table.cc
index 5a248c1..495d7a0 100644
--- a/runtime/vm/field_table.cc
+++ b/runtime/vm/field_table.cc
@@ -29,7 +29,7 @@
 }
 
 intptr_t FieldTable::FieldOffsetFor(intptr_t field_id) {
-  return field_id * sizeof(RawInstance*);  // NOLINT
+  return field_id * sizeof(InstancePtr);  // NOLINT
 }
 
 void FieldTable::Register(const Field& field) {
@@ -62,7 +62,7 @@
   free_head_ = field_id;
 }
 
-void FieldTable::SetAt(intptr_t index, RawInstance* raw_instance) {
+void FieldTable::SetAt(intptr_t index, InstancePtr raw_instance) {
   ASSERT(index < capacity_);
   table_[index] = raw_instance;
 }
@@ -82,12 +82,18 @@
 void FieldTable::Grow(intptr_t new_capacity) {
   ASSERT(new_capacity > capacity_);
 
-  auto new_table = static_cast<RawInstance**>(
-      malloc(new_capacity * sizeof(RawInstance*)));  // NOLINT
-  memmove(new_table, table_, top_ * sizeof(RawInstance*));
-  memset(new_table + top_, 0, (new_capacity - top_) * sizeof(RawInstance*));
+  auto old_table = table_;
+  auto new_table = static_cast<InstancePtr*>(
+      malloc(new_capacity * sizeof(InstancePtr)));  // NOLINT
+  intptr_t i;
+  for (i = 0; i < top_; i++) {
+    new_table[i] = old_table[i];
+  }
+  for (; i < new_capacity; i++) {
+    new_table[i] = InstancePtr();
+  }
   capacity_ = new_capacity;
-  old_tables_->Add(table_);
+  old_tables_->Add(old_table);
   // Ensure that new_table_ is populated before it is published
   // via store to table_.
   std::atomic_thread_fence(std::memory_order_release);
@@ -95,11 +101,28 @@
   Thread::Current()->field_table_values_ = table_;
 }
 
+FieldTable* FieldTable::Clone() {
+  FieldTable* clone = new FieldTable();
+  auto new_table = static_cast<InstancePtr*>(
+      malloc(capacity_ * sizeof(InstancePtr)));  // NOLINT
+  memmove(new_table, table_, top_ * sizeof(InstancePtr));
+  ASSERT(clone->table_ == nullptr);
+  clone->table_ = new_table;
+  clone->capacity_ = capacity_;
+  clone->top_ = top_;
+  return clone;
+}
+
 void FieldTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  // GC might try to visit field table before it's isolate done setting it up.
+  if (table_ == nullptr) {
+    return;
+  }
+
   ASSERT(visitor != NULL);
   visitor->set_gc_root_type("static fields table");
-  visitor->VisitPointers(reinterpret_cast<RawObject**>(&table_[0]),
-                         reinterpret_cast<RawObject**>(&table_[top_ - 1]));
+  visitor->VisitPointers(reinterpret_cast<ObjectPtr*>(&table_[0]),
+                         reinterpret_cast<ObjectPtr*>(&table_[top_ - 1]));
   visitor->clear_gc_root_type();
 }
 
diff --git a/runtime/vm/field_table.h b/runtime/vm/field_table.h
index e89c733..b4c8f23 100644
--- a/runtime/vm/field_table.h
+++ b/runtime/vm/field_table.h
@@ -12,11 +12,11 @@
 #include "vm/class_id.h"
 #include "vm/globals.h"
 #include "vm/growable_array.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
 class Field;
-class RawInstance;
 
 class FieldTable {
  public:
@@ -25,14 +25,14 @@
         capacity_(0),
         free_head_(-1),
         table_(nullptr),
-        old_tables_(new MallocGrowableArray<RawInstance**>()) {}
+        old_tables_(new MallocGrowableArray<InstancePtr*>()) {}
 
   ~FieldTable();
 
   intptr_t NumFieldIds() const { return top_; }
   intptr_t Capacity() const { return capacity_; }
 
-  RawInstance** table() { return table_; }
+  InstancePtr* table() { return table_; }
 
   void FreeOldTables();
 
@@ -49,11 +49,13 @@
   // to an existing static field value.
   void Free(intptr_t index);
 
-  RawInstance* At(intptr_t index) const {
+  InstancePtr At(intptr_t index) const {
     ASSERT(IsValidIndex(index));
     return table_[index];
   }
-  void SetAt(intptr_t index, RawInstance* raw_instance);
+  void SetAt(intptr_t index, InstancePtr raw_instance);
+
+  FieldTable* Clone();
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
@@ -75,10 +77,10 @@
   // element, last element contains -1.
   intptr_t free_head_;
 
-  RawInstance** table_;
+  InstancePtr* table_;
   // When table_ grows and have to reallocated, keep the old one here
   // so it will get freed when its are no longer in use.
-  MallocGrowableArray<RawInstance**>* old_tables_;
+  MallocGrowableArray<InstancePtr*>* old_tables_;
 
   DISALLOW_COPY_AND_ASSIGN(FieldTable);
 };
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 310aa8a..8fdc0de 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -59,9 +59,8 @@
 // The syntax used is the same as that for FLAG_LIST below, as these flags are
 // automatically included in FLAG_LIST.
 #define VM_GLOBAL_FLAG_LIST(P, R, C, D)                                        \
-  P(dwarf_stack_traces, bool, false,                                           \
-    "Emit DWARF line number and inlining info"                                 \
-    "in dylib snapshots and don't symbolize stack traces.")                    \
+  P(dwarf_stack_traces_mode, bool, false,                                      \
+    "Use --[no-]dwarf-stack-traces instead.")                                  \
   P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks")        \
   P(lazy_async_stacks, bool, false, "Reconstruct async stacks from listeners") \
   P(use_bare_instructions, bool, true, "Enable bare instructions mode.")       \
@@ -143,6 +142,9 @@
   P(link_natives_lazily, bool, false, "Link native calls lazily")              \
   R(log_marker_tasks, false, bool, false,                                      \
     "Log debugging information for old gen GC marking tasks.")                 \
+  P(scavenger_tasks, int, 2,                                                   \
+    "The number of tasks to spawn during scavenging (0 means "                 \
+    "perform all marking on main thread).")                                    \
   P(marker_tasks, int, 2,                                                      \
     "The number of tasks to spawn during old gen GC marking (0 means "         \
     "perform all marking on main thread).")                                    \
@@ -189,12 +191,10 @@
   P(reorder_basic_blocks, bool, true, "Reorder basic blocks")                  \
   C(stress_async_stacks, false, false, bool, false,                            \
     "Stress test async stack traces")                                          \
-  P(null_safety, bool, false,                                                  \
-    "Respect the nullability of types in casts and instance checks.")          \
   P(use_table_dispatch, bool, true, "Enable dispatch table based calls.")      \
-  P(retain_dispatched_functions, bool, !USING_PRODUCT,                         \
-    "Serialize function objects for code in the dispatch table even if "       \
-    "not needed in the precompiled runtime")                                   \
+  P(retain_function_objects, bool, true,                                       \
+    "Serialize function objects for all code objects even if not otherwise "   \
+    "needed in the precompiled runtime.")                                      \
   P(enable_isolate_groups, bool, false, "Enable isolate group support.")       \
   P(show_invisible_frames, bool, false,                                        \
     "Show invisible frames in stack traces.")                                  \
diff --git a/runtime/vm/gdb_helpers.cc b/runtime/vm/gdb_helpers.cc
index 1260263..f75c89a 100644
--- a/runtime/vm/gdb_helpers.cc
+++ b/runtime/vm/gdb_helpers.cc
@@ -12,12 +12,12 @@
 #if !defined(PRODUCT)
 
 DART_EXPORT
-void _printRawObject(RawObject* object) {
+void _printRawObject(ObjectPtr object) {
   OS::PrintErr("%s\n", Object::Handle(object).ToCString());
 }
 
 DART_EXPORT
-Object* _handle(RawObject* object) {
+Object* _handle(ObjectPtr object) {
   return &Object::Handle(object);
 }
 
@@ -57,15 +57,15 @@
 // Must be called with the current interpreter fp, sp, and pc.
 // Note that sp[0] is not modified, but sp[1] will be trashed.
 DART_EXPORT
-void _printInterpreterStackTrace(RawObject** fp,
-                                 RawObject** sp,
+void _printInterpreterStackTrace(ObjectPtr* fp,
+                                 ObjectPtr* sp,
                                  const KBCInstr* pc) {
   Thread* thread = Thread::Current();
   sp[1] = Function::null();
   sp[2] = Bytecode::null();
-  sp[3] = reinterpret_cast<RawObject*>(reinterpret_cast<uword>(pc));
-  sp[4] = reinterpret_cast<RawObject*>(fp);
-  RawObject** exit_fp = sp + 1 + kKBCDartFrameFixedSize;
+  sp[3] = static_cast<ObjectPtr>(reinterpret_cast<uword>(pc));
+  sp[4] = static_cast<ObjectPtr>(reinterpret_cast<uword>(fp));
+  ObjectPtr* exit_fp = sp + 1 + kKBCDartFrameFixedSize;
   thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp));
   thread->set_execution_state(Thread::kThreadInVM);
   _printDartStackTrace();
@@ -78,8 +78,8 @@
   PrintObjectPointersVisitor()
       : ObjectPointerVisitor(IsolateGroup::Current()) {}
 
-  void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** p = first; p <= last; p++) {
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* p = first; p <= last; p++) {
       Object& obj = Object::Handle(*p);
       OS::PrintErr("%p: %s\n", p, obj.ToCString());
     }
diff --git a/runtime/vm/guard_field_test.cc b/runtime/vm/guard_field_test.cc
index be010ce..3334ea1 100644
--- a/runtime/vm/guard_field_test.cc
+++ b/runtime/vm/guard_field_test.cc
@@ -10,10 +10,10 @@
 
 namespace dart {
 
-RawField* LookupField(Dart_Handle library,
-                      const char* class_name,
-                      const char* field_name) {
-  RawLibrary* raw_library = Library::RawCast(Api::UnwrapHandle(library));
+FieldPtr LookupField(Dart_Handle library,
+                     const char* class_name,
+                     const char* field_name) {
+  LibraryPtr raw_library = Library::RawCast(Api::UnwrapHandle(library));
   Library& lib = Library::ZoneHandle(raw_library);
   const String& classname =
       String::Handle(Symbols::New(Thread::Current(), class_name));
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index 2b3de59..28ec9cc 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -207,6 +207,7 @@
 
   friend class HandleScope;
   friend class Dart;
+  friend class IsolateObjectStore;
   friend class ObjectStore;
   friend class ThreadState;
   DISALLOW_ALLOCATION();
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index 3bbd19f..f4033dc 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -290,7 +290,7 @@
   ASSERT(visitor != NULL);
   for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) {
     visitor->VisitPointer(
-        reinterpret_cast<RawObject**>(&data_[i + kOffsetOfRawPtr / kWordSize]));
+        reinterpret_cast<ObjectPtr*>(&data_[i + kOffsetOfRawPtr / kWordSize]));
   }
 }
 
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index a59fd9a..b558abe 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -85,7 +85,7 @@
         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, RawArray* data)
+  HashTable(Zone* zone, ArrayPtr data)
       : key_handle_(&Object::Handle(zone)),
         smi_handle_(&Smi::Handle(zone)),
         data_(&Array::Handle(zone, data)),
@@ -252,11 +252,11 @@
     return InternalGetKey(entry) == DeletedMarker().raw();
   }
 
-  RawObject* GetKey(intptr_t entry) const {
+  ObjectPtr GetKey(intptr_t entry) const {
     ASSERT(IsOccupied(entry));
     return InternalGetKey(entry);
   }
-  RawObject* GetPayload(intptr_t entry, intptr_t component) const {
+  ObjectPtr GetPayload(intptr_t entry, intptr_t component) const {
     ASSERT(IsOccupied(entry));
     return data_->At(PayloadIndex(entry, component));
   }
@@ -307,7 +307,7 @@
   }
   void UpdateCollisions(intptr_t collisions) const {
     if (KeyTraits::ReportStats()) {
-      if (data_->raw()->InVMIsolateHeap()) {
+      if (data_->raw()->ptr()->InVMIsolateHeap()) {
         return;
       }
       AdjustSmiValueAt(kNumProbesIndex, collisions + 1);
@@ -370,7 +370,7 @@
     return KeyIndex(entry) + 1 + component;
   }
 
-  RawObject* InternalGetKey(intptr_t entry) const {
+  ObjectPtr InternalGetKey(intptr_t entry) const {
     return data_->At(KeyIndex(entry));
   }
 
@@ -408,9 +408,9 @@
  public:
   typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable;
   static const intptr_t kPayloadSize = kUserPayloadSize;
-  explicit UnorderedHashTable(RawArray* data)
+  explicit UnorderedHashTable(ArrayPtr data)
       : BaseTable(Thread::Current()->zone(), data) {}
-  UnorderedHashTable(Zone* zone, RawArray* data) : BaseTable(zone, data) {}
+  UnorderedHashTable(Zone* zone, ArrayPtr data) : BaseTable(zone, data) {}
   UnorderedHashTable(Object* key, Smi* value, Array* data)
       : BaseTable(key, value, data) {}
   // Note: Does not check for concurrent modification.
@@ -441,8 +441,8 @@
  public:
   // Allocates and initializes a table.
   template <typename Table>
-  static RawArray* New(intptr_t initial_capacity,
-                       Heap::Space space = Heap::kNew) {
+  static ArrayPtr New(intptr_t initial_capacity,
+                      Heap::Space space = Heap::kNew) {
     Table table(
         Thread::Current()->zone(),
         Array::New(Table::ArrayLengthForNumOccupied(initial_capacity), space));
@@ -451,7 +451,7 @@
   }
 
   template <typename Table>
-  static RawArray* New(const Array& array) {
+  static ArrayPtr New(const Array& array) {
     Table table(Thread::Current()->zone(), array.raw());
     table.Initialize();
     return table.Release().raw();
@@ -512,7 +512,7 @@
 
   // Serializes a table by concatenating its entries as an array.
   template <typename Table>
-  static RawArray* ToArray(const Table& table, bool include_payload) {
+  static ArrayPtr ToArray(const Table& table, bool include_payload) {
     const intptr_t entry_size = include_payload ? (1 + Table::kPayloadSize) : 1;
     Array& result = Array::Handle(Array::New(table.NumOccupied() * entry_size));
     typename Table::Iterator it(&table);
@@ -536,13 +536,13 @@
 template <typename BaseIterTable>
 class HashMap : public BaseIterTable {
  public:
-  explicit HashMap(RawArray* data)
+  explicit HashMap(ArrayPtr data)
       : BaseIterTable(Thread::Current()->zone(), data) {}
-  HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
+  HashMap(Zone* zone, ArrayPtr data) : BaseIterTable(zone, data) {}
   HashMap(Object* key, Smi* value, Array* data)
       : BaseIterTable(key, value, data) {}
   template <typename Key>
-  RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
+  ObjectPtr GetOrNull(const Key& key, bool* present = NULL) const {
     intptr_t entry = BaseIterTable::FindKey(key);
     if (present != NULL) {
       *present = (entry != -1);
@@ -550,7 +550,7 @@
     return (entry == -1) ? Object::null() : BaseIterTable::GetPayload(entry, 0);
   }
   template <typename Key>
-  RawObject* GetOrDie(const Key& key) const {
+  ObjectPtr GetOrDie(const Key& key) const {
     intptr_t entry = BaseIterTable::FindKey(key);
     if (entry == -1) UNREACHABLE();
     return BaseIterTable::GetPayload(entry, 0);
@@ -574,8 +574,8 @@
   }
   // If 'key' is not present, maps it to 'value_if_absent'. Returns the final
   // value in the map.
-  RawObject* InsertOrGetValue(const Object& key,
-                              const Object& value_if_absent) const {
+  ObjectPtr InsertOrGetValue(const Object& key,
+                             const Object& value_if_absent) const {
     EnsureCapacity();
     intptr_t entry = -1;
     if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -588,8 +588,8 @@
   }
   // Like InsertOrGetValue, but calls NewKey to allocate a key object if needed.
   template <typename Key>
-  RawObject* InsertNewOrGetValue(const Key& key,
-                                 const Object& value_if_absent) const {
+  ObjectPtr InsertNewOrGetValue(const Key& key,
+                                const Object& value_if_absent) const {
     EnsureCapacity();
     intptr_t entry = -1;
     if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -627,9 +627,9 @@
 class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > {
  public:
   typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap;
-  explicit UnorderedHashMap(RawArray* data)
+  explicit UnorderedHashMap(ArrayPtr data)
       : BaseMap(Thread::Current()->zone(), data) {}
-  UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
+  UnorderedHashMap(Zone* zone, ArrayPtr data) : BaseMap(zone, data) {}
   UnorderedHashMap(Object* key, Smi* value, Array* data)
       : BaseMap(key, value, data) {}
 };
@@ -637,9 +637,9 @@
 template <typename BaseIterTable>
 class HashSet : public BaseIterTable {
  public:
-  explicit HashSet(RawArray* data)
+  explicit HashSet(ArrayPtr data)
       : BaseIterTable(Thread::Current()->zone(), data) {}
-  HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
+  HashSet(Zone* zone, ArrayPtr data) : BaseIterTable(zone, data) {}
   HashSet(Object* key, Smi* value, Array* data)
       : BaseIterTable(key, value, data) {}
   bool Insert(const Object& key) {
@@ -654,7 +654,7 @@
 
   // If 'key' is not present, insert and return it. Else, return the existing
   // key in the set (useful for canonicalization).
-  RawObject* InsertOrGet(const Object& key) const {
+  ObjectPtr InsertOrGet(const Object& key) const {
     EnsureCapacity();
     intptr_t entry = -1;
     if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -667,7 +667,7 @@
 
   // Like InsertOrGet, but calls NewKey to allocate a key object if needed.
   template <typename Key>
-  RawObject* InsertNewOrGet(const Key& key) const {
+  ObjectPtr InsertNewOrGet(const Key& key) const {
     EnsureCapacity();
     intptr_t entry = -1;
     if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -681,7 +681,7 @@
   }
 
   template <typename Key>
-  RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
+  ObjectPtr GetOrNull(const Key& key, bool* present = NULL) const {
     intptr_t entry = BaseIterTable::FindKey(key);
     if (present != NULL) {
       *present = (entry != -1);
@@ -713,11 +713,11 @@
 class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
  public:
   typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
-  explicit UnorderedHashSet(RawArray* data)
+  explicit UnorderedHashSet(ArrayPtr data)
       : BaseSet(Thread::Current()->zone(), data) {
     ASSERT(data != Array::null());
   }
-  UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
+  UnorderedHashSet(Zone* zone, ArrayPtr data) : BaseSet(zone, data) {}
   UnorderedHashSet(Object* key, Smi* value, Array* data)
       : BaseSet(key, value, data) {}
 
diff --git a/runtime/vm/hash_table_test.cc b/runtime/vm/hash_table_test.cc
index aeb8d55..6549de2 100644
--- a/runtime/vm/hash_table_test.cc
+++ b/runtime/vm/hash_table_test.cc
@@ -32,7 +32,7 @@
            String::Cast(a).Equals(String::Cast(b));
   }
   static uword Hash(const Object& obj) { return String::Cast(obj).Length(); }
-  static RawObject* NewKey(const char* key) { return String::New(key); }
+  static ObjectPtr NewKey(const char* key) { return String::New(key); }
 };
 
 template <typename Table>
diff --git a/runtime/vm/heap/become.cc b/runtime/vm/heap/become.cc
index 5f5ffba..2799db6 100644
--- a/runtime/vm/heap/become.cc
+++ b/runtime/vm/heap/become.cc
@@ -24,16 +24,16 @@
   ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr);
 
   uint32_t tags = 0;
-  tags = RawObject::SizeTag::update(size, tags);
-  tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags);
+  tags = ObjectLayout::SizeTag::update(size, tags);
+  tags = ObjectLayout::ClassIdTag::update(kForwardingCorpse, tags);
   bool is_old = (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
-  tags = RawObject::OldBit::update(is_old, tags);
-  tags = RawObject::OldAndNotMarkedBit::update(is_old, tags);
-  tags = RawObject::OldAndNotRememberedBit::update(is_old, tags);
-  tags = RawObject::NewBit::update(!is_old, tags);
+  tags = ObjectLayout::OldBit::update(is_old, tags);
+  tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, tags);
+  tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, tags);
+  tags = ObjectLayout::NewBit::update(!is_old, tags);
 
   result->tags_ = tags;
-  if (size > RawObject::SizeTag::kMaxSizeTag) {
+  if (size > ObjectLayout::SizeTag::kMaxSizeTag) {
     *result->SizeAddress() = size;
   }
   result->set_target(Object::null());
@@ -48,21 +48,21 @@
 // Free list elements are used as a marker for forwarding objects. This is
 // safe because we cannot reach free list elements from live objects. Ideally
 // forwarding objects would have their own class id. See TODO below.
-static bool IsForwardingObject(RawObject* object) {
+static bool IsForwardingObject(ObjectPtr object) {
   return object->IsHeapObject() && object->IsForwardingCorpse();
 }
 
-static RawObject* GetForwardedObject(RawObject* object) {
+static ObjectPtr GetForwardedObject(ObjectPtr object) {
   ASSERT(IsForwardingObject(object));
-  uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag;
+  uword addr = static_cast<uword>(object) - kHeapObjectTag;
   ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
   return forwarder->target();
 }
 
-static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
-  const intptr_t size_before = before_obj->HeapSize();
+static void ForwardObjectTo(ObjectPtr before_obj, ObjectPtr after_obj) {
+  const intptr_t size_before = before_obj->ptr()->HeapSize();
 
-  uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
+  uword corpse_addr = static_cast<uword>(before_obj) - kHeapObjectTag;
   ForwardingCorpse* forwarder =
       ForwardingCorpse::AsForwarder(corpse_addr, size_before);
   forwarder->set_target(after_obj);
@@ -70,7 +70,7 @@
     FATAL("become: ForwardObjectTo failure.");
   }
   // Still need to be able to iterate over the forwarding corpse.
-  const intptr_t size_after = before_obj->HeapSize();
+  const intptr_t size_after = before_obj->ptr()->HeapSize();
   if (size_before != size_after) {
     FATAL("become: Before and after sizes do not match.");
   }
@@ -81,25 +81,25 @@
   explicit ForwardPointersVisitor(Thread* thread)
       : ObjectPointerVisitor(thread->isolate_group()),
         thread_(thread),
-        visiting_object_(NULL) {}
+        visiting_object_(nullptr) {}
 
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** p = first; p <= last; p++) {
-      RawObject* old_target = *p;
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* p = first; p <= last; p++) {
+      ObjectPtr old_target = *p;
       if (IsForwardingObject(old_target)) {
-        RawObject* new_target = GetForwardedObject(old_target);
-        if (visiting_object_ == NULL) {
+        ObjectPtr new_target = GetForwardedObject(old_target);
+        if (visiting_object_ == nullptr) {
           *p = new_target;
         } else {
-          visiting_object_->StorePointer(p, new_target);
+          visiting_object_->ptr()->StorePointer(p, new_target);
         }
       }
     }
   }
 
-  void VisitingObject(RawObject* obj) {
+  void VisitingObject(ObjectPtr obj) {
     visiting_object_ = obj;
-    if ((obj != NULL) && obj->IsOldObject() && obj->IsRemembered()) {
+    if ((obj != nullptr) && obj->IsOldObject() && obj->ptr()->IsRemembered()) {
       ASSERT(!obj->IsForwardingCorpse());
       ASSERT(!obj->IsFreeListElement());
       thread_->StoreBufferAddObjectGC(obj);
@@ -108,7 +108,7 @@
 
  private:
   Thread* thread_;
-  RawObject* visiting_object_;
+  ObjectPtr visiting_object_;
 
   DISALLOW_COPY_AND_ASSIGN(ForwardPointersVisitor);
 };
@@ -118,9 +118,9 @@
   explicit ForwardHeapPointersVisitor(ForwardPointersVisitor* pointer_visitor)
       : pointer_visitor_(pointer_visitor) {}
 
-  virtual void VisitObject(RawObject* obj) {
+  virtual void VisitObject(ObjectPtr obj) {
     pointer_visitor_->VisitingObject(obj);
-    obj->VisitPointers(pointer_visitor_);
+    obj->ptr()->VisitPointers(pointer_visitor_);
   }
 
  private:
@@ -182,25 +182,25 @@
   ForwardObjectTo(instance.raw(), instance.raw());
 }
 
-static bool IsDummyObject(RawObject* object) {
+static bool IsDummyObject(ObjectPtr object) {
   if (!object->IsForwardingCorpse()) return false;
   return GetForwardedObject(object) == object;
 }
 
-void Become::CrashDump(RawObject* before_obj, RawObject* after_obj) {
+void Become::CrashDump(ObjectPtr before_obj, ObjectPtr after_obj) {
   OS::PrintErr("DETECTED FATAL ISSUE IN BECOME MAPPINGS\n");
 
-  OS::PrintErr("BEFORE ADDRESS: %p\n", before_obj);
+  OS::PrintErr("BEFORE ADDRESS: %#" Px "\n", static_cast<uword>(before_obj));
   OS::PrintErr("BEFORE IS HEAP OBJECT: %s\n",
                before_obj->IsHeapObject() ? "YES" : "NO");
   OS::PrintErr("BEFORE IN VMISOLATE HEAP OBJECT: %s\n",
-               before_obj->InVMIsolateHeap() ? "YES" : "NO");
+               before_obj->ptr()->InVMIsolateHeap() ? "YES" : "NO");
 
-  OS::PrintErr("AFTER ADDRESS: %p\n", after_obj);
+  OS::PrintErr("AFTER ADDRESS: %#" Px "\n", static_cast<uword>(after_obj));
   OS::PrintErr("AFTER IS HEAP OBJECT: %s\n",
                after_obj->IsHeapObject() ? "YES" : "NO");
   OS::PrintErr("AFTER IN VMISOLATE HEAP OBJECT: %s\n",
-               after_obj->InVMIsolateHeap() ? "YES" : "NO");
+               after_obj->ptr()->InVMIsolateHeap() ? "YES" : "NO");
 
   if (before_obj->IsHeapObject()) {
     OS::PrintErr("BEFORE OBJECT CLASS ID=%" Pd "\n", before_obj->GetClassId());
@@ -225,8 +225,8 @@
   // Setup forwarding pointers.
   ASSERT(before.Length() == after.Length());
   for (intptr_t i = 0; i < before.Length(); i++) {
-    RawObject* before_obj = before.At(i);
-    RawObject* after_obj = after.At(i);
+    ObjectPtr before_obj = before.At(i);
+    ObjectPtr after_obj = after.At(i);
 
     if (before_obj == after_obj) {
       FATAL("become: Cannot self-forward");
@@ -239,7 +239,7 @@
       CrashDump(before_obj, after_obj);
       FATAL("become: Cannot become immediates");
     }
-    if (before_obj->InVMIsolateHeap()) {
+    if (before_obj->ptr()->InVMIsolateHeap()) {
       CrashDump(before_obj, after_obj);
       FATAL("become: Cannot forward VM heap objects");
     }
diff --git a/runtime/vm/heap/become.h b/runtime/vm/heap/become.h
index 5e98eba..ef76a45 100644
--- a/runtime/vm/heap/become.h
+++ b/runtime/vm/heap/become.h
@@ -23,11 +23,11 @@
 // representation as a FreeListElement.
 class ForwardingCorpse {
  public:
-  RawObject* target() const { return target_; }
-  void set_target(RawObject* target) { target_ = target; }
+  ObjectPtr target() const { return target_; }
+  void set_target(ObjectPtr target) { target_ = target; }
 
   intptr_t HeapSize() {
-    intptr_t size = RawObject::SizeTag::decode(tags_);
+    intptr_t size = ObjectLayout::SizeTag::decode(tags_);
     if (size != 0) return size;
     return *SizeAddress();
   }
@@ -57,7 +57,7 @@
 #if defined(HASH_IN_OBJECT_HEADER)
   uint32_t hash_;
 #endif
-  RawObject* target_;
+  ObjectPtr target_;
 
   // Returns the address of the embedded size.
   intptr_t* SizeAddress() const {
@@ -91,7 +91,7 @@
   // forwarding objects' targets.
   static void FollowForwardingPointers(Thread* thread);
 
-  static void CrashDump(RawObject* before_obj, RawObject* after_obj);
+  static void CrashDump(ObjectPtr before_obj, ObjectPtr after_obj);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 90555f5..fbea2f8 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -279,10 +279,10 @@
       // 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
       // the inner pointer.
-      if (RawObject::IsTypedDataClassId(cid)) {
-        raw_view->RecomputeDataFieldForInternalTypedData();
+      if (IsTypedDataClassId(cid)) {
+        raw_view->ptr()->RecomputeDataFieldForInternalTypedData();
       } else {
-        ASSERT(RawObject::IsExternalTypedDataClassId(cid));
+        ASSERT(IsExternalTypedDataClassId(cid));
       }
     }
   }
@@ -470,9 +470,9 @@
   intptr_t block_dead_size = 0;
   uword current = first_object;
   while (current < block_end) {
-    RawObject* obj = RawObject::FromAddr(current);
-    intptr_t size = obj->HeapSize();
-    if (obj->IsMarked()) {
+    ObjectPtr obj = ObjectLayout::FromAddr(current);
+    intptr_t size = obj->ptr()->HeapSize();
+    if (obj->ptr()->IsMarked()) {
       forwarding_block->RecordLive(current, size);
       ASSERT(static_cast<intptr_t>(forwarding_block->Lookup(current)) ==
              block_live_size);
@@ -500,9 +500,9 @@
 
   uword old_addr = first_object;
   while (old_addr < block_end) {
-    RawObject* old_obj = RawObject::FromAddr(old_addr);
-    intptr_t size = old_obj->HeapSize();
-    if (old_obj->IsMarked()) {
+    ObjectPtr old_obj = ObjectLayout::FromAddr(old_addr);
+    intptr_t size = old_obj->ptr()->HeapSize();
+    if (old_obj->ptr()->IsMarked()) {
       uword new_addr = forwarding_block->Lookup(old_addr);
       if (new_addr != free_current_) {
         // The only situation where these two don't match is if we are moving
@@ -521,7 +521,7 @@
         free_end_ = free_page_->object_end();
         ASSERT(free_current_ == new_addr);
       }
-      RawObject* new_obj = RawObject::FromAddr(new_addr);
+      ObjectPtr new_obj = ObjectLayout::FromAddr(new_addr);
 
       // Fast path for no movement. There's often a large block of objects at
       // the beginning that don't move.
@@ -530,12 +530,12 @@
         memmove(reinterpret_cast<void*>(new_addr),
                 reinterpret_cast<void*>(old_addr), size);
 
-        if (RawObject::IsTypedDataClassId(new_obj->GetClassId())) {
-          reinterpret_cast<RawTypedData*>(new_obj)->RecomputeDataField();
+        if (IsTypedDataClassId(new_obj->GetClassId())) {
+          static_cast<TypedDataPtr>(new_obj)->ptr()->RecomputeDataField();
         }
       }
-      new_obj->ClearMarkBit();
-      new_obj->VisitPointers(compactor_);
+      new_obj->ptr()->ClearMarkBit();
+      new_obj->ptr()->VisitPointers(compactor_);
 
       ASSERT(free_current_ == new_addr);
       free_current_ += size;
@@ -592,13 +592,13 @@
 }
 
 DART_FORCE_INLINE
-void GCCompactor::ForwardPointer(RawObject** ptr) {
-  RawObject* old_target = *ptr;
+void GCCompactor::ForwardPointer(ObjectPtr* ptr) {
+  ObjectPtr old_target = *ptr;
   if (old_target->IsSmiOrNewObject()) {
     return;  // Not moved.
   }
 
-  uword old_addr = RawObject::ToAddr(old_target);
+  uword old_addr = ObjectLayout::ToAddr(old_target);
   for (intptr_t i = 0; i < kMaxImagePages; i++) {
     if ((old_addr - image_page_ranges_[i].base) < image_page_ranges_[i].size) {
       return;  // Not moved (unaligned image page).
@@ -611,19 +611,19 @@
     return;  // Not moved (VM isolate, large page, code page).
   }
 
-  RawObject* new_target =
-      RawObject::FromAddr(forwarding_page->Lookup(old_addr));
+  ObjectPtr new_target =
+      ObjectLayout::FromAddr(forwarding_page->Lookup(old_addr));
   ASSERT(!new_target->IsSmiOrNewObject());
   *ptr = new_target;
 }
 
-void GCCompactor::VisitTypedDataViewPointers(RawTypedDataView* view,
-                                             RawObject** first,
-                                             RawObject** last) {
+void GCCompactor::VisitTypedDataViewPointers(TypedDataViewPtr view,
+                                             ObjectPtr* first,
+                                             ObjectPtr* last) {
   // First we forward all fields of the typed data view.
-  RawObject* old_backing = view->ptr()->typed_data_;
+  ObjectPtr old_backing = view->ptr()->typed_data_;
   VisitPointers(first, last);
-  RawObject* new_backing = view->ptr()->typed_data_;
+  ObjectPtr new_backing = view->ptr()->typed_data_;
 
   const bool backing_moved = old_backing != new_backing;
   if (backing_moved) {
@@ -644,8 +644,8 @@
     // The backing store didn't move, we therefore don't need to update the
     // inner pointer.
     if (view->ptr()->data_ == 0) {
-      ASSERT(ValueFromRawSmi(view->ptr()->offset_in_bytes_) == 0 &&
-             ValueFromRawSmi(view->ptr()->length_) == 0 &&
+      ASSERT(RawSmiValue(view->ptr()->offset_in_bytes_) == 0 &&
+             RawSmiValue(view->ptr()->length_) == 0 &&
              view->ptr()->typed_data_ == Object::null());
     }
   }
@@ -653,8 +653,8 @@
 
 // N.B.: This pointer visitor is not idempotent. We must take care to visit
 // each pointer exactly once.
-void GCCompactor::VisitPointers(RawObject** first, RawObject** last) {
-  for (RawObject** ptr = first; ptr <= last; ptr++) {
+void GCCompactor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+  for (ObjectPtr* ptr = first; ptr <= last; ptr++) {
     ForwardPointer(ptr);
   }
 }
diff --git a/runtime/vm/heap/compactor.h b/runtime/vm/heap/compactor.h
index cd6b29c..e657f84 100644
--- a/runtime/vm/heap/compactor.h
+++ b/runtime/vm/heap/compactor.h
@@ -18,7 +18,6 @@
 class FreeList;
 class Heap;
 class HeapPage;
-class RawObject;
 
 // Implements a sliding compactor.
 class GCCompactor : public ValueObject,
@@ -38,11 +37,11 @@
 
   void SetupImagePageBoundaries();
   void ForwardStackPointers();
-  void ForwardPointer(RawObject** ptr);
-  void VisitTypedDataViewPointers(RawTypedDataView* view,
-                                  RawObject** first,
-                                  RawObject** last);
-  void VisitPointers(RawObject** first, RawObject** last);
+  void ForwardPointer(ObjectPtr* ptr);
+  void VisitTypedDataViewPointers(TypedDataViewPtr view,
+                                  ObjectPtr* first,
+                                  ObjectPtr* last);
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last);
   void VisitHandle(uword addr);
 
   Heap* heap_;
@@ -59,7 +58,7 @@
   // The typed data views whose inner pointer must be updated after sliding is
   // complete.
   Mutex typed_data_view_mutex_;
-  MallocGrowableArray<RawTypedDataView*> typed_data_views_;
+  MallocGrowableArray<TypedDataViewPtr> typed_data_views_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index d08ec12..3570378 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -22,20 +22,20 @@
   FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);
 
   uint32_t tags = 0;
-  tags = RawObject::SizeTag::update(size, tags);
-  tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
+  tags = ObjectLayout::SizeTag::update(size, tags);
+  tags = ObjectLayout::ClassIdTag::update(kFreeListElement, tags);
   ASSERT((addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset);
-  tags = RawObject::OldBit::update(true, tags);
-  tags = RawObject::OldAndNotMarkedBit::update(true, tags);
-  tags = RawObject::OldAndNotRememberedBit::update(true, tags);
-  tags = RawObject::NewBit::update(false, tags);
+  tags = ObjectLayout::OldBit::update(true, tags);
+  tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
+  tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+  tags = ObjectLayout::NewBit::update(false, tags);
   result->tags_ = tags;
 #if defined(HASH_IN_OBJECT_HEADER)
   // Clearing this is mostly for neatness. The identityHashCode
   // of free list entries is not used.
   result->hash_ = 0;
 #endif
-  if (size > RawObject::SizeTag::kMaxSizeTag) {
+  if (size > ObjectLayout::SizeTag::kMaxSizeTag) {
     *result->SizeAddress() = size;
   }
   result->set_next(NULL);
@@ -51,11 +51,10 @@
 
 intptr_t FreeListElement::HeaderSizeFor(intptr_t size) {
   if (size == 0) return 0;
-  return ((size > RawObject::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize;
+  return ((size > ObjectLayout::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize;
 }
 
-FreeList::FreeList()
-    : mutex_(), freelist_search_budget_(kInitialFreeListSearchBudget) {
+FreeList::FreeList() : mutex_() {
   Reset();
 }
 
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index 7c885cf..1187ff3 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -29,7 +29,7 @@
   void set_next(FreeListElement* next) { next_ = next; }
 
   intptr_t HeapSize() {
-    intptr_t size = RawObject::SizeTag::decode(tags_);
+    intptr_t size = ObjectLayout::SizeTag::decode(tags_);
     if (size != 0) return size;
     return *SizeAddress();
   }
@@ -117,6 +117,46 @@
     return 0;
   }
 
+  uword TryAllocateBumpLocked(intptr_t size) {
+    ASSERT(mutex_.IsOwnedByCurrentThread());
+    uword result = top_;
+    uword new_top = result + size;
+    if (new_top <= end_) {
+      top_ = new_top;
+      unaccounted_size_ += size;
+      return result;
+    }
+    return 0;
+  }
+  intptr_t TakeUnaccountedSizeLocked() {
+    ASSERT(mutex_.IsOwnedByCurrentThread());
+    intptr_t result = unaccounted_size_;
+    unaccounted_size_ = 0;
+    return result;
+  }
+
+  // Ensures HeapPage::VisitObjects can successful walk over a partially
+  // allocated bump region.
+  void MakeIterable() {
+    if (top_ < end_) {
+      FreeListElement::AsElement(top_, end_ - top_);
+    }
+  }
+  // Returns the bump region to the free list.
+  void AbandonBumpAllocation() {
+    if (top_ < end_) {
+      Free(top_, end_ - top_);
+      top_ = 0;
+      end_ = 0;
+    }
+  }
+
+  uword top() const { return top_; }
+  uword end() const { return end_; }
+  void set_top(uword value) { top_ = value; }
+  void set_end(uword value) { end_ = value; }
+  void AddUnaccountedSize(intptr_t size) { unaccounted_size_ += size; }
+
   void MergeOtherFreelist(FreeList* freelist, bool is_protected);
 
  private:
@@ -161,6 +201,15 @@
   void PrintSmall() const;
   void PrintLarge() const;
 
+  // Bump pointer region.
+  uword top_ = 0;
+  uword end_ = 0;
+
+  // Allocated from the bump pointer region, but not yet added to
+  // PageSpace::usage_. Used to avoid expensive atomic adds during parallel
+  // scavenge.
+  intptr_t unaccounted_size_ = 0;
+
   // Lock protecting the free list data structures.
   mutable Mutex mutex_;
 
@@ -168,7 +217,7 @@
 
   FreeListElement* free_lists_[kNumLists + 1];
 
-  intptr_t freelist_search_budget_;
+  intptr_t freelist_search_budget_ = kInitialFreeListSearchBudget;
 
   // The largest available small size in bytes, or negative if there is none.
   intptr_t last_free_small_size_;
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 59abade..79a159d 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -87,15 +87,16 @@
   if (LIKELY(addr != 0)) {
     return addr;
   }
+  if (new_space_.GrowthControlState()) {
+    // This call to CollectGarbage might end up "reusing" a collection spawned
+    // from a different thread and will be racing to allocate the requested
+    // memory with other threads being released after the collection.
+    CollectGarbage(kNew);
 
-  // This call to CollectGarbage might end up "reusing" a collection spawned
-  // from a different thread and will be racing to allocate the requested
-  // memory with other threads being released after the collection.
-  CollectGarbage(kNew);
-
-  addr = new_space_.TryAllocate(thread, size);
-  if (LIKELY(addr != 0)) {
-    return addr;
+    addr = new_space_.TryAllocate(thread, size);
+    if (LIKELY(addr != 0)) {
+      return addr;
+    }
   }
 
   // It is possible a GC doesn't clear enough space.
@@ -211,12 +212,12 @@
   return old_space_.DataContains(addr);
 }
 
-void Heap::VisitObjects(ObjectVisitor* visitor) const {
+void Heap::VisitObjects(ObjectVisitor* visitor) {
   new_space_.VisitObjects(visitor);
   old_space_.VisitObjects(visitor);
 }
 
-void Heap::VisitObjectsNoImagePages(ObjectVisitor* visitor) const {
+void Heap::VisitObjectsNoImagePages(ObjectVisitor* visitor) {
   new_space_.VisitObjects(visitor);
   old_space_.VisitObjectsNoImagePages(visitor);
 }
@@ -317,31 +318,31 @@
   isolate_group()->VisitStackPointers(visitor, validate_frames);
 }
 
-void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
+void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   new_space_.VisitObjectPointers(visitor);
   old_space_.VisitObjectPointers(visitor);
 }
 
-RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
+InstructionsPtr Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
   // Only executable pages can have RawInstructions objects.
-  RawObject* raw_obj = old_space_.FindObject(visitor, HeapPage::kExecutable);
+  ObjectPtr raw_obj = old_space_.FindObject(visitor, HeapPage::kExecutable);
   ASSERT((raw_obj == Object::null()) ||
          (raw_obj->GetClassId() == kInstructionsCid));
-  return reinterpret_cast<RawInstructions*>(raw_obj);
+  return static_cast<InstructionsPtr>(raw_obj);
 }
 
-RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const {
+ObjectPtr Heap::FindOldObject(FindObjectVisitor* visitor) const {
   return old_space_.FindObject(visitor, HeapPage::kData);
 }
 
-RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const {
+ObjectPtr Heap::FindNewObject(FindObjectVisitor* visitor) {
   return new_space_.FindObject(visitor);
 }
 
-RawObject* Heap::FindObject(FindObjectVisitor* visitor) const {
+ObjectPtr Heap::FindObject(FindObjectVisitor* visitor) {
   // The visitor must not allocate from the heap.
   NoSafepointScope no_safepoint_scope;
-  RawObject* raw_obj = FindNewObject(visitor);
+  ObjectPtr raw_obj = FindNewObject(visitor);
   if (raw_obj != Object::null()) {
     return raw_obj;
   }
@@ -651,14 +652,17 @@
 }
 
 void Heap::InitGrowthControl() {
+  new_space_.InitGrowthControl();
   old_space_.InitGrowthControl();
 }
 
 void Heap::SetGrowthControlState(bool state) {
+  new_space_.SetGrowthControlState(state);
   old_space_.SetGrowthControlState(state);
 }
 
 bool Heap::GrowthControlState() {
+  ASSERT(new_space_.GrowthControlState() == old_space_.GrowthControlState());
   return old_space_.GrowthControlState();
 }
 
@@ -698,7 +702,7 @@
 
 void Heap::CollectOnNthAllocation(intptr_t num_allocations) {
   // Prevent generated code from using the TLAB fast path on next allocation.
-  new_space_.AbandonRemainingTLAB(Thread::Current());
+  new_space_.AbandonRemainingTLABForDebugging(Thread::Current());
   gc_on_nth_allocation_ = num_allocations;
 }
 
@@ -720,19 +724,23 @@
 
 void Heap::CollectForDebugging() {
   if (gc_on_nth_allocation_ == kNoForcedGarbageCollection) return;
+  if (Thread::Current()->IsAtSafepoint()) {
+    // CollectAllGarbage is not supported when we are at a safepoint.
+    // Allocating when at a safepoint is not a common case.
+    return;
+  }
   gc_on_nth_allocation_--;
   if (gc_on_nth_allocation_ == 0) {
     CollectAllGarbage(kDebugging);
     gc_on_nth_allocation_ = kNoForcedGarbageCollection;
   } else {
     // Prevent generated code from using the TLAB fast path on next allocation.
-    new_space_.AbandonRemainingTLAB(Thread::Current());
+    new_space_.AbandonRemainingTLABForDebugging(Thread::Current());
   }
 }
 
-ObjectSet* Heap::CreateAllocatedObjectSet(
-    Zone* zone,
-    MarkExpectation mark_expectation) const {
+ObjectSet* Heap::CreateAllocatedObjectSet(Zone* zone,
+                                          MarkExpectation mark_expectation) {
   ObjectSet* allocated_set = new (zone) ObjectSet(zone);
 
   this->AddRegionsToObjectSet(allocated_set);
@@ -759,16 +767,14 @@
   return allocated_set;
 }
 
-bool Heap::Verify(MarkExpectation mark_expectation) const {
+bool Heap::Verify(MarkExpectation mark_expectation) {
   HeapIterationScope heap_iteration_scope(Thread::Current());
   return VerifyGC(mark_expectation);
 }
 
-bool Heap::VerifyGC(MarkExpectation mark_expectation) const {
-  StackZone stack_zone(Thread::Current());
-
-  // Change the new space's top_ with the more up-to-date thread's view of top_
-  new_space_.MakeNewSpaceIterable();
+bool Heap::VerifyGC(MarkExpectation mark_expectation) {
+  auto thread = Thread::Current();
+  StackZone stack_zone(thread);
 
   ObjectSet* allocated_set =
       CreateAllocatedObjectSet(stack_zone.GetZone(), mark_expectation);
@@ -862,6 +868,8 @@
       return "low memory";
     case kDebugging:
       return "debugging";
+    case kSendAndExit:
+      return "send_and_exit";
     default:
       UNREACHABLE();
       return "";
@@ -882,7 +890,7 @@
   old_weak_tables_[kObjectIds]->Reset();
 }
 
-intptr_t Heap::GetWeakEntry(RawObject* raw_obj, WeakSelector sel) const {
+intptr_t Heap::GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const {
   if (raw_obj->IsNewObject()) {
     return new_weak_tables_[sel]->GetValue(raw_obj);
   }
@@ -890,7 +898,7 @@
   return old_weak_tables_[sel]->GetValue(raw_obj);
 }
 
-void Heap::SetWeakEntry(RawObject* raw_obj, WeakSelector sel, intptr_t val) {
+void Heap::SetWeakEntry(ObjectPtr raw_obj, WeakSelector sel, intptr_t val) {
   if (raw_obj->IsNewObject()) {
     new_weak_tables_[sel]->SetValue(raw_obj, val);
   } else {
@@ -899,8 +907,7 @@
   }
 }
 
-void Heap::ForwardWeakEntries(RawObject* before_object,
-                              RawObject* after_object) {
+void Heap::ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object) {
   const auto before_space =
       before_object->IsNewObject() ? Heap::kNew : Heap::kOld;
   const auto after_space =
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 34ab784..49ee780 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -55,15 +55,16 @@
   };
 
   enum GCReason {
-    kNewSpace,   // New space is full.
-    kPromotion,  // Old space limit crossed after a scavenge.
-    kOldSpace,   // Old space limit crossed.
-    kFinalize,   // Concurrent marking finished.
-    kFull,       // Heap::CollectAllGarbage
-    kExternal,   // Dart_NewWeakPersistentHandle
-    kIdle,       // Dart_NotifyIdle
-    kLowMemory,  // Dart_NotifyLowMemory
-    kDebugging,  // service request, etc.
+    kNewSpace,     // New space is full.
+    kPromotion,    // Old space limit crossed after a scavenge.
+    kOldSpace,     // Old space limit crossed.
+    kFinalize,     // Concurrent marking finished.
+    kFull,         // Heap::CollectAllGarbage
+    kExternal,     // Dart_NewWeakPersistentHandle
+    kIdle,         // Dart_NotifyIdle
+    kLowMemory,    // Dart_NotifyLowMemory
+    kDebugging,    // service request, etc.
+    kSendAndExit,  // SendPort.sendAndExit
   };
 
   // Pattern for unused new space and swept old space.
@@ -114,10 +115,10 @@
   // The 'visitor' function should return false if the object is not found,
   // traversal through the heap space continues.
   // Returns null object if nothing is found.
-  RawInstructions* FindObjectInCodeSpace(FindObjectVisitor* visitor) const;
-  RawObject* FindOldObject(FindObjectVisitor* visitor) const;
-  RawObject* FindNewObject(FindObjectVisitor* visitor) const;
-  RawObject* FindObject(FindObjectVisitor* visitor) const;
+  InstructionsPtr FindObjectInCodeSpace(FindObjectVisitor* visitor) const;
+  ObjectPtr FindOldObject(FindObjectVisitor* visitor) const;
+  ObjectPtr FindNewObject(FindObjectVisitor* visitor);
+  ObjectPtr FindObject(FindObjectVisitor* visitor);
 
   void NotifyIdle(int64_t deadline);
   void NotifyLowMemory();
@@ -173,7 +174,7 @@
   static const char* RegionName(Space space);
 
   // Verify that all pointers in the heap point to the heap.
-  bool Verify(MarkExpectation mark_expectation = kForbidMarked) const;
+  bool Verify(MarkExpectation mark_expectation = kForbidMarked);
 
   // Print heap sizes.
   void PrintSizes() const;
@@ -192,16 +193,16 @@
   intptr_t Collections(Space space) const;
 
   ObjectSet* CreateAllocatedObjectSet(Zone* zone,
-                                      MarkExpectation mark_expectation) const;
+                                      MarkExpectation mark_expectation);
 
   static const char* GCTypeToString(GCType type);
   static const char* GCReasonToString(GCReason reason);
 
   // Associate a peer with an object.  A non-existent peer is equal to NULL.
-  void SetPeer(RawObject* raw_obj, void* peer) {
+  void SetPeer(ObjectPtr raw_obj, void* peer) {
     SetWeakEntry(raw_obj, kPeers, reinterpret_cast<intptr_t>(peer));
   }
-  void* GetPeer(RawObject* raw_obj) const {
+  void* GetPeer(ObjectPtr raw_obj) const {
     return reinterpret_cast<void*>(GetWeakEntry(raw_obj, kPeers));
   }
   int64_t PeerCount() const;
@@ -209,37 +210,37 @@
 #if !defined(HASH_IN_OBJECT_HEADER)
   // Associate an identity hashCode with an object. An non-existent hashCode
   // is equal to 0.
-  void SetHash(RawObject* raw_obj, intptr_t hash) {
+  void SetHash(ObjectPtr raw_obj, intptr_t hash) {
     SetWeakEntry(raw_obj, kIdentityHashes, hash);
   }
-  intptr_t GetHash(RawObject* raw_obj) const {
+  intptr_t GetHash(ObjectPtr raw_obj) const {
     return GetWeakEntry(raw_obj, kIdentityHashes);
   }
 #endif
 
-  void SetCanonicalHash(RawObject* raw_obj, intptr_t hash) {
+  void SetCanonicalHash(ObjectPtr raw_obj, intptr_t hash) {
     SetWeakEntry(raw_obj, kCanonicalHashes, hash);
   }
-  intptr_t GetCanonicalHash(RawObject* raw_obj) const {
+  intptr_t GetCanonicalHash(ObjectPtr raw_obj) const {
     return GetWeakEntry(raw_obj, kCanonicalHashes);
   }
   void ResetCanonicalHashTable();
 
   // Associate an id with an object (used when serializing an object).
   // A non-existant id is equal to 0.
-  void SetObjectId(RawObject* raw_obj, intptr_t object_id) {
+  void SetObjectId(ObjectPtr raw_obj, intptr_t object_id) {
     ASSERT(Thread::Current()->IsMutatorThread());
     SetWeakEntry(raw_obj, kObjectIds, object_id);
   }
-  intptr_t GetObjectId(RawObject* raw_obj) const {
+  intptr_t GetObjectId(ObjectPtr raw_obj) const {
     ASSERT(Thread::Current()->IsMutatorThread());
     return GetWeakEntry(raw_obj, kObjectIds);
   }
   void ResetObjectIdTable();
 
   // Used by the GC algorithms to propagate weak entries.
-  intptr_t GetWeakEntry(RawObject* raw_obj, WeakSelector sel) const;
-  void SetWeakEntry(RawObject* raw_obj, WeakSelector sel, intptr_t val);
+  intptr_t GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const;
+  void SetWeakEntry(ObjectPtr raw_obj, WeakSelector sel, intptr_t val);
 
   WeakTable* GetWeakTable(Space space, WeakSelector selector) const {
     if (space == kNew) {
@@ -257,7 +258,7 @@
     }
   }
 
-  void ForwardWeakEntries(RawObject* before_object, RawObject* after_object);
+  void ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object);
   void ForwardWeakTables(ObjectPointerVisitor* visitor);
 
   // Stats collection.
@@ -352,17 +353,17 @@
 
   // Visit all pointers. Caller must ensure concurrent sweeper is not running,
   // and the visitor must not allocate.
-  void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
+  void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
   // Visit all objects, including FreeListElement "objects". Caller must ensure
   // concurrent sweeper is not running, and the visitor must not allocate.
-  void VisitObjects(ObjectVisitor* visitor) const;
-  void VisitObjectsNoImagePages(ObjectVisitor* visitor) const;
+  void VisitObjects(ObjectVisitor* visitor);
+  void VisitObjectsNoImagePages(ObjectVisitor* visitor);
   void VisitObjectsImagePages(ObjectVisitor* visitor) const;
 
   // Like Verify, but does not wait for concurrent sweeper, so caller must
   // ensure thread-safety.
-  bool VerifyGC(MarkExpectation mark_expectation = kForbidMarked) const;
+  bool VerifyGC(MarkExpectation mark_expectation = kForbidMarked);
 
   // Helper functions for garbage collection.
   void CollectNewSpaceGarbage(Thread* thread, GCReason reason);
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index 948d6f3..33c8500 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -2,14 +2,22 @@
 // for 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 <map>
+#include <memory>
+#include <set>
+#include <string>
+
 #include "platform/globals.h"
 
 #include "platform/assert.h"
+#include "vm/class_finalizer.h"
 #include "vm/dart_api_impl.h"
 #include "vm/globals.h"
 #include "vm/heap/become.h"
 #include "vm/heap/heap.h"
+#include "vm/message_handler.h"
 #include "vm/object_graph.h"
+#include "vm/port.h"
 #include "vm/symbols.h"
 #include "vm/unit_test.h"
 
@@ -82,7 +90,7 @@
 }
 
 #ifndef PRODUCT
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
   const Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
@@ -200,24 +208,24 @@
 
 class FindOnly : public FindObjectVisitor {
  public:
-  explicit FindOnly(RawObject* target) : target_(target) {
+  explicit FindOnly(ObjectPtr target) : target_(target) {
 #if defined(DEBUG)
     EXPECT_GT(Thread::Current()->no_safepoint_scope_depth(), 0);
 #endif
   }
   virtual ~FindOnly() {}
 
-  virtual bool FindObject(RawObject* obj) const { return obj == target_; }
+  virtual bool FindObject(ObjectPtr obj) const { return obj == target_; }
 
  private:
-  RawObject* target_;
+  ObjectPtr target_;
 };
 
 class FindNothing : public FindObjectVisitor {
  public:
   FindNothing() {}
   virtual ~FindNothing() {}
-  virtual bool FindObject(RawObject* obj) const { return false; }
+  virtual bool FindObject(ObjectPtr obj) const { return false; }
 };
 
 ISOLATE_UNIT_TEST_CASE(FindObject) {
@@ -249,11 +257,11 @@
   GCTestHelper::WaitForGCTasks();
 
   Heap* heap = Thread::Current()->isolate()->heap();
-  EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
+  EXPECT(heap->Contains(ObjectLayout::ToAddr(obj.raw())));
   heap->WriteProtect(true);
-  EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
+  EXPECT(heap->Contains(ObjectLayout::ToAddr(obj.raw())));
   heap->WriteProtect(false);
-  EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
+  EXPECT(heap->Contains(ObjectLayout::ToAddr(obj.raw())));
 }
 
 void TestBecomeForward(Heap::Space before_space, Heap::Space after_space) {
@@ -325,8 +333,8 @@
   const Array& after_obj = Array::Handle(Array::New(1, Heap::kOld));
   before_obj.SetAt(0, new_element);
   after_obj.SetAt(0, old_element);
-  EXPECT(before_obj.raw()->IsRemembered());
-  EXPECT(!after_obj.raw()->IsRemembered());
+  EXPECT(before_obj.raw()->ptr()->IsRemembered());
+  EXPECT(!after_obj.raw()->ptr()->IsRemembered());
 
   EXPECT(before_obj.raw() != after_obj.raw());
 
@@ -338,7 +346,7 @@
   Become::ElementsForwardIdentity(before, after);
 
   EXPECT(before_obj.raw() == after_obj.raw());
-  EXPECT(!after_obj.raw()->IsRemembered());
+  EXPECT(!after_obj.raw()->ptr()->IsRemembered());
 
   GCTestHelper::CollectAllGarbage();
 
@@ -607,6 +615,131 @@
   }
 };
 
+class MergeIsolatesHeapsHandler : public MessageHandler {
+ public:
+  explicit MergeIsolatesHeapsHandler(Isolate* owner)
+      : msg_(Utils::CreateCStringUniquePtr(nullptr)), owner_(owner) {}
+
+  const char* name() const { return "merge-isolates-heaps-handler"; }
+
+  ~MergeIsolatesHeapsHandler() { PortMap::ClosePorts(this); }
+
+  MessageStatus HandleMessage(std::unique_ptr<Message> message) {
+    // Parse the message.
+    Object& response_obj = Object::Handle();
+    if (message->IsRaw()) {
+      response_obj = message->raw_obj();
+    } else if (message->IsBequest()) {
+      Bequest* bequest = message->bequest();
+      PersistentHandle* handle = bequest->handle();
+      // Object in the receiving isolate's heap.
+      EXPECT(isolate()->heap()->Contains(ObjectLayout::ToAddr(handle->raw())));
+      response_obj = handle->raw();
+      isolate()->group()->api_state()->FreePersistentHandle(handle);
+    } else {
+      Thread* thread = Thread::Current();
+      MessageSnapshotReader reader(message.get(), thread);
+      response_obj = reader.ReadObject();
+    }
+    if (response_obj.IsString()) {
+      String& response = String::Handle();
+      response ^= response_obj.raw();
+      msg_.reset(strdup(response.ToCString()));
+    } else {
+      ASSERT(response_obj.IsArray());
+      Array& response_array = Array::Handle();
+      response_array ^= response_obj.raw();
+      ASSERT(response_array.Length() == 1);
+      ExternalTypedData& response = ExternalTypedData::Handle();
+      response ^= response_array.At(0);
+      msg_.reset(strdup(reinterpret_cast<char*>(response.DataAddr(0))));
+    }
+
+    return kOK;
+  }
+
+  const char* msg() const { return msg_.get(); }
+
+  virtual Isolate* isolate() const { return owner_; }
+
+ private:
+  Utils::CStringUniquePtr msg_;
+  Isolate* owner_;
+};
+
+VM_UNIT_TEST_CASE(CleanupBequestNeverReceived) {
+  const char* TEST_MESSAGE = "hello, world";
+  Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
+  EXPECT_EQ(parent, Dart_CurrentIsolate());
+  {
+    MergeIsolatesHeapsHandler handler(Isolate::Current());
+    Dart_Port port_id = PortMap::CreatePort(&handler);
+    EXPECT_EQ(PortMap::GetIsolate(port_id), Isolate::Current());
+    Dart_ExitIsolate();
+
+    Dart_Isolate worker = TestCase::CreateTestIsolateInGroup("worker", parent);
+    EXPECT_EQ(worker, Dart_CurrentIsolate());
+    {
+      Thread* thread = Thread::Current();
+      TransitionNativeToVM transition(thread);
+      StackZone zone(thread);
+      HANDLESCOPE(thread);
+
+      String& string = String::Handle(String::New(TEST_MESSAGE));
+      PersistentHandle* handle =
+          Isolate::Current()->group()->api_state()->AllocatePersistentHandle();
+      handle->set_raw(string.raw());
+
+      reinterpret_cast<Isolate*>(worker)->bequeath(
+          std::unique_ptr<Bequest>(new Bequest(handle, port_id)));
+    }
+  }
+  Dart_ShutdownIsolate();
+  Dart_EnterIsolate(parent);
+  Dart_ShutdownIsolate();
+}
+
+VM_UNIT_TEST_CASE(ReceivesSendAndExitMessage) {
+  const char* TEST_MESSAGE = "hello, world";
+  Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
+  EXPECT_EQ(parent, Dart_CurrentIsolate());
+  MergeIsolatesHeapsHandler handler(Isolate::Current());
+  Dart_Port port_id = PortMap::CreatePort(&handler);
+  EXPECT_EQ(PortMap::GetIsolate(port_id), Isolate::Current());
+  Dart_ExitIsolate();
+
+  Dart_Isolate worker = TestCase::CreateTestIsolateInGroup("worker", parent);
+  EXPECT_EQ(worker, Dart_CurrentIsolate());
+  {
+    Thread* thread = Thread::Current();
+    TransitionNativeToVM transition(thread);
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+
+    String& string = String::Handle(String::New(TEST_MESSAGE));
+
+    PersistentHandle* handle =
+        Isolate::Current()->group()->api_state()->AllocatePersistentHandle();
+    handle->set_raw(string.raw());
+
+    reinterpret_cast<Isolate*>(worker)->bequeath(
+        std::unique_ptr<Bequest>(new Bequest(handle, port_id)));
+  }
+
+  Dart_ShutdownIsolate();
+  Dart_EnterIsolate(parent);
+  {
+    Thread* thread = Thread::Current();
+    TransitionNativeToVM transition(thread);
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+
+    EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
+  }
+  EXPECT_STREQ(handler.msg(), TEST_MESSAGE);
+  Dart_ShutdownIsolate();
+}
+
 ISOLATE_UNIT_TEST_CASE(ExternalAllocationStats) {
   Isolate* isolate = thread->isolate();
   Heap* heap = thread->heap();
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 994a268..44a7031 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -22,65 +22,6 @@
 
 namespace dart {
 
-class MarkerWorkList : public ValueObject {
- public:
-  explicit MarkerWorkList(MarkingStack* marking_stack)
-      : marking_stack_(marking_stack) {
-    work_ = marking_stack_->PopEmptyBlock();
-  }
-
-  ~MarkerWorkList() {
-    ASSERT(work_ == NULL);
-    ASSERT(marking_stack_ == NULL);
-  }
-
-  // Returns NULL if no more work was found.
-  RawObject* Pop() {
-    ASSERT(work_ != NULL);
-    if (work_->IsEmpty()) {
-      // TODO(koda): Track over/underflow events and use in heuristics to
-      // distribute work and prevent degenerate flip-flopping.
-      MarkingStack::Block* new_work = marking_stack_->PopNonEmptyBlock();
-      if (new_work == NULL) {
-        return NULL;
-      }
-      marking_stack_->PushBlock(work_);
-      work_ = new_work;
-      // Generated code appends to marking stacks; tell MemorySanitizer.
-      MSAN_UNPOISON(work_, sizeof(*work_));
-    }
-    return work_->Pop();
-  }
-
-  void Push(RawObject* raw_obj) {
-    if (work_->IsFull()) {
-      // TODO(koda): Track over/underflow events and use in heuristics to
-      // distribute work and prevent degenerate flip-flopping.
-      marking_stack_->PushBlock(work_);
-      work_ = marking_stack_->PopEmptyBlock();
-    }
-    work_->Push(raw_obj);
-  }
-
-  void Finalize() {
-    ASSERT(work_->IsEmpty());
-    marking_stack_->PushBlock(work_);
-    work_ = NULL;
-    // Fail fast on attempts to mark after finalizing.
-    marking_stack_ = NULL;
-  }
-
-  void AbandonWork() {
-    marking_stack_->PushBlock(work_);
-    work_ = NULL;
-    marking_stack_ = NULL;
-  }
-
- private:
-  MarkingStack::Block* work_;
-  MarkingStack* marking_stack_;
-};
-
 template <bool sync>
 class MarkingVisitorBase : public ObjectPointerVisitor {
  public:
@@ -93,7 +34,7 @@
         page_space_(page_space),
         work_list_(marking_stack),
         deferred_work_list_(deferred_marking_stack),
-        delayed_weak_properties_(NULL),
+        delayed_weak_properties_(nullptr),
         marked_bytes_(0),
         marked_micros_(0) {
     ASSERT(thread_->isolate_group() == isolate_group);
@@ -106,37 +47,38 @@
 
   bool ProcessPendingWeakProperties() {
     bool marked = false;
-    RawWeakProperty* cur_weak = delayed_weak_properties_;
-    delayed_weak_properties_ = NULL;
-    while (cur_weak != NULL) {
+    WeakPropertyPtr cur_weak = delayed_weak_properties_;
+    delayed_weak_properties_ = nullptr;
+    while (cur_weak != nullptr) {
       uword next_weak = cur_weak->ptr()->next_;
-      RawObject* raw_key = cur_weak->ptr()->key_;
+      ObjectPtr raw_key = cur_weak->ptr()->key_;
       // Reset the next pointer in the weak property.
       cur_weak->ptr()->next_ = 0;
-      if (raw_key->IsMarked()) {
-        RawObject* raw_val = cur_weak->ptr()->value_;
-        marked = marked || (raw_val->IsHeapObject() && !raw_val->IsMarked());
+      if (raw_key->ptr()->IsMarked()) {
+        ObjectPtr raw_val = cur_weak->ptr()->value_;
+        marked =
+            marked || (raw_val->IsHeapObject() && !raw_val->ptr()->IsMarked());
 
         // The key is marked so we make sure to properly visit all pointers
         // originating from this weak property.
-        cur_weak->VisitPointersNonvirtual(this);
+        cur_weak->ptr()->VisitPointersNonvirtual(this);
       } else {
         // Requeue this weak property to be handled later.
         EnqueueWeakProperty(cur_weak);
       }
       // Advance to next weak property in the queue.
-      cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+      cur_weak = static_cast<WeakPropertyPtr>(next_weak);
     }
     return marked;
   }
 
   void DrainMarkingStack() {
-    RawObject* raw_obj = work_list_.Pop();
-    if ((raw_obj == NULL) && ProcessPendingWeakProperties()) {
+    ObjectPtr raw_obj = work_list_.Pop();
+    if ((raw_obj == nullptr) && ProcessPendingWeakProperties()) {
       raw_obj = work_list_.Pop();
     }
 
-    if (raw_obj == NULL) {
+    if (raw_obj == nullptr) {
       return;
     }
 
@@ -147,15 +89,15 @@
 
         intptr_t size;
         if (class_id != kWeakPropertyCid) {
-          size = raw_obj->VisitPointersNonvirtual(this);
+          size = raw_obj->ptr()->VisitPointersNonvirtual(this);
         } else {
-          RawWeakProperty* raw_weak = static_cast<RawWeakProperty*>(raw_obj);
+          WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
           size = ProcessWeakProperty(raw_weak, /* did_mark */ true);
         }
         marked_bytes_ += size;
 
         raw_obj = work_list_.Pop();
-      } while (raw_obj != NULL);
+      } while (raw_obj != nullptr);
 
       // Marking stack is empty.
       ProcessPendingWeakProperties();
@@ -163,7 +105,7 @@
       // Check whether any further work was pushed either by other markers or
       // by the handling of weak properties.
       raw_obj = work_list_.Pop();
-    } while (raw_obj != NULL);
+    } while (raw_obj != nullptr);
   }
 
   // Races: The concurrent marker is racing with the mutator, but this race is
@@ -178,51 +120,51 @@
   // we don't do any in-place unboxing like V8), any value we read from the slot
   // is safe.
   NO_SANITIZE_THREAD
-  RawObject* LoadPointerIgnoreRace(RawObject** ptr) { return *ptr; }
+  ObjectPtr LoadPointerIgnoreRace(ObjectPtr* ptr) { return *ptr; }
 
-  void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; current++) {
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* current = first; current <= last; current++) {
       MarkObject(LoadPointerIgnoreRace(current));
     }
   }
 
-  void EnqueueWeakProperty(RawWeakProperty* raw_weak) {
+  void EnqueueWeakProperty(WeakPropertyPtr raw_weak) {
     ASSERT(raw_weak->IsHeapObject());
     ASSERT(raw_weak->IsOldObject());
     ASSERT(raw_weak->IsWeakProperty());
-    ASSERT(raw_weak->IsMarked());
+    ASSERT(raw_weak->ptr()->IsMarked());
     ASSERT(raw_weak->ptr()->next_ == 0);
-    raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+    raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
     delayed_weak_properties_ = raw_weak;
   }
 
-  intptr_t ProcessWeakProperty(RawWeakProperty* raw_weak, bool did_mark) {
+  intptr_t ProcessWeakProperty(WeakPropertyPtr raw_weak, bool did_mark) {
     // The fate of the weak property is determined by its key.
-    RawObject* raw_key = LoadPointerIgnoreRace(&raw_weak->ptr()->key_);
+    ObjectPtr raw_key = LoadPointerIgnoreRace(&raw_weak->ptr()->key_);
     if (raw_key->IsHeapObject() && raw_key->IsOldObject() &&
-        !raw_key->IsMarked()) {
+        !raw_key->ptr()->IsMarked()) {
       // Key was white. Enqueue the weak property.
       if (did_mark) {
         EnqueueWeakProperty(raw_weak);
       }
-      return raw_weak->HeapSize();
+      return raw_weak->ptr()->HeapSize();
     }
     // Key is gray or black. Make the weak property black.
-    return raw_weak->VisitPointersNonvirtual(this);
+    return raw_weak->ptr()->VisitPointersNonvirtual(this);
   }
 
   void ProcessDeferredMarking() {
-    RawObject* raw_obj;
-    while ((raw_obj = deferred_work_list_.Pop()) != NULL) {
+    ObjectPtr raw_obj;
+    while ((raw_obj = deferred_work_list_.Pop()) != nullptr) {
       ASSERT(raw_obj->IsHeapObject() && raw_obj->IsOldObject());
       // N.B. We are scanning the object even if it is already marked.
       bool did_mark = TryAcquireMarkBit(raw_obj);
       const intptr_t class_id = raw_obj->GetClassId();
       intptr_t size;
       if (class_id != kWeakPropertyCid) {
-        size = raw_obj->VisitPointersNonvirtual(this);
+        size = raw_obj->ptr()->VisitPointersNonvirtual(this);
       } else {
-        RawWeakProperty* raw_weak = static_cast<RawWeakProperty*>(raw_obj);
+        WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
         size = ProcessWeakProperty(raw_weak, did_mark);
       }
       // Add the size only if we win the marking race to prevent
@@ -242,17 +184,17 @@
   void Finalize() {
     work_list_.Finalize();
     // Clear pending weak properties.
-    RawWeakProperty* cur_weak = delayed_weak_properties_;
-    delayed_weak_properties_ = NULL;
+    WeakPropertyPtr cur_weak = delayed_weak_properties_;
+    delayed_weak_properties_ = nullptr;
     intptr_t weak_properties_cleared = 0;
-    while (cur_weak != NULL) {
+    while (cur_weak != nullptr) {
       uword next_weak = cur_weak->ptr()->next_;
       cur_weak->ptr()->next_ = 0;
-      RELEASE_ASSERT(!cur_weak->ptr()->key_->IsMarked());
+      RELEASE_ASSERT(!cur_weak->ptr()->key_->ptr()->IsMarked());
       WeakProperty::Clear(cur_weak);
       weak_properties_cleared++;
       // Advance to next weak property in the queue.
-      cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+      cur_weak = static_cast<WeakPropertyPtr>(next_weak);
     }
   }
 
@@ -262,30 +204,30 @@
   }
 
  private:
-  void PushMarked(RawObject* raw_obj) {
+  void PushMarked(ObjectPtr raw_obj) {
     ASSERT(raw_obj->IsHeapObject());
     ASSERT(raw_obj->IsOldObject());
 
     // Push the marked object on the marking stack.
-    ASSERT(raw_obj->IsMarked());
+    ASSERT(raw_obj->ptr()->IsMarked());
     work_list_.Push(raw_obj);
   }
 
-  static bool TryAcquireMarkBit(RawObject* raw_obj) {
+  static bool TryAcquireMarkBit(ObjectPtr raw_obj) {
     if (FLAG_write_protect_code && raw_obj->IsInstructions()) {
       // A non-writable alias mapping may exist for instruction pages.
       raw_obj = HeapPage::ToWritable(raw_obj);
     }
     if (!sync) {
-      raw_obj->SetMarkBitUnsynchronized();
+      raw_obj->ptr()->SetMarkBitUnsynchronized();
       return true;
     } else {
-      return raw_obj->TryAcquireMarkBit();
+      return raw_obj->ptr()->TryAcquireMarkBit();
     }
   }
 
   DART_FORCE_INLINE
-  void MarkObject(RawObject* raw_obj) {
+  void MarkObject(ObjectPtr raw_obj) {
     // Fast exit if the raw object is immediate or in new space. No memory
     // access.
     if (raw_obj->IsSmiOrNewObject()) {
@@ -298,7 +240,7 @@
     // change in the value.
     // Doing this before checking for an Instructions object avoids
     // unnecessary queueing of pre-marked objects.
-    if (raw_obj->IsMarked()) {
+    if (raw_obj->ptr()->IsMarked()) {
       return;
     }
 
@@ -324,7 +266,7 @@
   PageSpace* page_space_;
   MarkerWorkList work_list_;
   MarkerWorkList deferred_work_list_;
-  RawWeakProperty* delayed_weak_properties_;
+  WeakPropertyPtr delayed_weak_properties_;
   uintptr_t marked_bytes_;
   int64_t marked_micros_;
 
@@ -334,7 +276,7 @@
 typedef MarkingVisitorBase<false> UnsyncMarkingVisitor;
 typedef MarkingVisitorBase<true> SyncMarkingVisitor;
 
-static bool IsUnreachable(const RawObject* raw_obj) {
+static bool IsUnreachable(const ObjectPtr raw_obj) {
   if (!raw_obj->IsHeapObject()) {
     return false;
   }
@@ -344,19 +286,19 @@
   if (!raw_obj->IsOldObject()) {
     return false;
   }
-  return !raw_obj->IsMarked();
+  return !raw_obj->ptr()->IsMarked();
 }
 
 class MarkingWeakVisitor : public HandleVisitor {
  public:
   explicit MarkingWeakVisitor(Thread* thread)
       : HandleVisitor(thread),
-        class_table_(thread->isolate_group()->class_table()) {}
+        class_table_(thread->isolate_group()->shared_class_table()) {}
 
   void VisitHandle(uword addr) {
     FinalizablePersistentHandle* handle =
         reinterpret_cast<FinalizablePersistentHandle*>(addr);
-    RawObject* raw_obj = handle->raw();
+    ObjectPtr raw_obj = handle->raw();
     if (IsUnreachable(raw_obj)) {
       handle->UpdateUnreachable(thread()->isolate_group());
     }
@@ -482,9 +424,9 @@
     intptr_t size = table->size();
     for (intptr_t i = 0; i < size; i++) {
       if (table->IsValidEntryAtExclusive(i)) {
-        RawObject* raw_obj = table->ObjectAtExclusive(i);
+        ObjectPtr raw_obj = table->ObjectAtExclusive(i);
         ASSERT(raw_obj->IsHeapObject());
-        if (!raw_obj->IsMarked()) {
+        if (!raw_obj->ptr()->IsMarked()) {
           table->InvalidateAtExclusive(i);
         }
       }
@@ -496,17 +438,17 @@
   TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessRememberedSet");
   // Filter collected objects from the remembered set.
   StoreBuffer* store_buffer = isolate_group_->store_buffer();
-  StoreBufferBlock* reading = store_buffer->Blocks();
+  StoreBufferBlock* reading = store_buffer->TakeBlocks();
   StoreBufferBlock* writing = store_buffer->PopNonFullBlock();
   while (reading != NULL) {
     StoreBufferBlock* next = reading->next();
     // Generated code appends to store buffers; tell MemorySanitizer.
     MSAN_UNPOISON(reading, sizeof(*reading));
     while (!reading->IsEmpty()) {
-      RawObject* raw_object = reading->Pop();
+      ObjectPtr raw_object = reading->Pop();
       ASSERT(!raw_object->IsForwardingCorpse());
-      ASSERT(raw_object->IsRemembered());
-      if (raw_object->IsMarked()) {
+      ASSERT(raw_object->ptr()->IsRemembered());
+      if (raw_object->ptr()->IsMarked()) {
         writing->Push(raw_object);
         if (writing->IsFull()) {
           store_buffer->PushBlock(writing, StoreBuffer::kIgnoreThreshold);
@@ -527,11 +469,11 @@
   explicit ObjectIdRingClearPointerVisitor(IsolateGroup* isolate_group)
       : ObjectPointerVisitor(isolate_group) {}
 
-  void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; current++) {
-      RawObject* raw_obj = *current;
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* current = first; current <= last; current++) {
+      ObjectPtr raw_obj = *current;
       ASSERT(raw_obj->IsHeapObject());
-      if (raw_obj->IsOldObject() && !raw_obj->IsMarked()) {
+      if (raw_obj->IsOldObject() && !raw_obj->ptr()->IsMarked()) {
         // Object has become garbage. Replace it will null.
         *current = Object::null();
       }
@@ -543,13 +485,7 @@
 #ifndef PRODUCT
   TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessObjectIdTable");
   ObjectIdRingClearPointerVisitor visitor(isolate_group_);
-  isolate_group_->ForEachIsolate(
-      [&](Isolate* isolate) {
-        ObjectIdRing* ring = isolate->object_id_ring();
-        ASSERT(ring != NULL);
-        ring->VisitPointers(&visitor);
-      },
-      /*at_safepoint=*/true);
+  isolate_group_->VisitObjectIdRingPointers(&visitor);
 #endif  // !PRODUCT
 }
 
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index a4ad4c0b..7f78a58 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -17,7 +17,6 @@
 class IsolateGroup;
 class ObjectPointerVisitor;
 class PageSpace;
-class RawWeakProperty;
 template <bool sync>
 class MarkingVisitorBase;
 class Thread;
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 0461261..1c6444c 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -97,9 +97,9 @@
   uword obj_addr = object_start();
   uword end_addr = object_end();
   while (obj_addr < end_addr) {
-    RawObject* raw_obj = RawObject::FromAddr(obj_addr);
+    ObjectPtr raw_obj = ObjectLayout::FromAddr(obj_addr);
     visitor->VisitObject(raw_obj);
-    obj_addr += raw_obj->HeapSize();
+    obj_addr += raw_obj->ptr()->HeapSize();
   }
   ASSERT(obj_addr == end_addr);
 }
@@ -111,14 +111,15 @@
   uword obj_addr = object_start();
   uword end_addr = object_end();
   while (obj_addr < end_addr) {
-    RawObject* raw_obj = RawObject::FromAddr(obj_addr);
-    obj_addr += raw_obj->VisitPointers(visitor);
+    ObjectPtr raw_obj = ObjectLayout::FromAddr(obj_addr);
+    obj_addr += raw_obj->ptr()->VisitPointers(visitor);
   }
   ASSERT(obj_addr == end_addr);
 }
 
 void HeapPage::VisitRememberedCards(ObjectPointerVisitor* visitor) {
-  ASSERT(Thread::Current()->IsAtSafepoint());
+  ASSERT(Thread::Current()->IsAtSafepoint() ||
+         (Thread::Current()->task_kind() == Thread::kScavengerTask));
   NoSafepointScope no_safepoint;
 
   if (card_table_ == NULL) {
@@ -127,19 +128,19 @@
 
   bool table_is_empty = false;
 
-  RawArray* obj = static_cast<RawArray*>(RawObject::FromAddr(object_start()));
+  ArrayPtr obj = static_cast<ArrayPtr>(ObjectLayout::FromAddr(object_start()));
   ASSERT(obj->IsArray());
-  ASSERT(obj->IsCardRemembered());
-  RawObject** obj_from = obj->from();
-  RawObject** obj_to = obj->to(Smi::Value(obj->ptr()->length_));
+  ASSERT(obj->ptr()->IsCardRemembered());
+  ObjectPtr* obj_from = obj->ptr()->from();
+  ObjectPtr* obj_to = obj->ptr()->to(Smi::Value(obj->ptr()->length_));
 
   const intptr_t size = card_table_size();
   for (intptr_t i = 0; i < size; i++) {
     if (card_table_[i] != 0) {
-      RawObject** card_from =
-          reinterpret_cast<RawObject**>(this) + (i << kSlotsPerCardLog2);
-      RawObject** card_to = reinterpret_cast<RawObject**>(card_from) +
-                            (1 << kSlotsPerCardLog2) - 1;
+      ObjectPtr* card_from =
+          reinterpret_cast<ObjectPtr*>(this) + (i << kSlotsPerCardLog2);
+      ObjectPtr* card_to = reinterpret_cast<ObjectPtr*>(card_from) +
+                           (1 << kSlotsPerCardLog2) - 1;
       // Minus 1 because to is inclusive.
 
       if (card_from < obj_from) {
@@ -155,7 +156,7 @@
       visitor->VisitPointers(card_from, card_to);
 
       bool has_new_target = false;
-      for (RawObject** slot = card_from; slot <= card_to; slot++) {
+      for (ObjectPtr* slot = card_from; slot <= card_to; slot++) {
         if ((*slot)->IsNewObjectMayBeSmi()) {
           has_new_target = true;
           break;
@@ -177,15 +178,15 @@
   }
 }
 
-RawObject* HeapPage::FindObject(FindObjectVisitor* visitor) const {
+ObjectPtr HeapPage::FindObject(FindObjectVisitor* visitor) const {
   uword obj_addr = object_start();
   uword end_addr = object_end();
   if (visitor->VisitRange(obj_addr, end_addr)) {
     while (obj_addr < end_addr) {
-      RawObject* raw_obj = RawObject::FromAddr(obj_addr);
-      uword next_obj_addr = obj_addr + raw_obj->HeapSize();
+      ObjectPtr raw_obj = ObjectLayout::FromAddr(obj_addr);
+      uword next_obj_addr = obj_addr + raw_obj->ptr()->HeapSize();
       if (visitor->VisitRange(obj_addr, next_obj_addr) &&
-          raw_obj->FindObject(visitor)) {
+          raw_obj->ptr()->FindObject(visitor)) {
         return raw_obj;  // Found object, return it.
       }
       obj_addr = next_obj_addr;
@@ -218,11 +219,10 @@
 static const intptr_t kConservativeInitialMarkSpeed = 20;
 
 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words)
-    : freelist_(),
-      heap_(heap),
+    : heap_(heap),
+      num_freelists_(Utils::Maximum(FLAG_scavenger_tasks, 1) + 1),
+      freelists_(new FreeList[num_freelists_]),
       pages_lock_(),
-      bump_top_(0),
-      bump_end_(0),
       max_capacity_in_words_(max_capacity_in_words),
       usage_(),
       allocated_black_in_words_(0),
@@ -245,6 +245,10 @@
   // We aren't holding the lock but no one can reference us yet.
   UpdateMaxCapacityLocked();
   UpdateMaxUsed();
+
+  for (intptr_t i = 0; i < num_freelists_; i++) {
+    freelists_[i].Reset();
+  }
 }
 
 PageSpace::~PageSpace() {
@@ -259,6 +263,7 @@
   FreePages(large_pages_);
   FreePages(image_pages_);
   ASSERT(marker_ == NULL);
+  delete[] freelists_;
 }
 
 intptr_t PageSpace::LargePageSizeInWordsFor(intptr_t size) {
@@ -458,6 +463,7 @@
 }
 
 uword PageSpace::TryAllocateInFreshPage(intptr_t size,
+                                        FreeList* freelist,
                                         HeapPage::PageType type,
                                         GrowthPolicy growth_policy,
                                         bool is_locked) {
@@ -485,9 +491,9 @@
     intptr_t free_size = page->object_end() - free_start;
     if (free_size > 0) {
       if (is_locked) {
-        freelist_[type].FreeLocked(free_start, free_size);
+        freelist->FreeLocked(free_start, free_size);
       } else {
-        freelist_[type].Free(free_start, free_size);
+        freelist->Free(free_start, free_size);
       }
     }
   }
@@ -524,6 +530,7 @@
 }
 
 uword PageSpace::TryAllocateInternal(intptr_t size,
+                                     FreeList* freelist,
                                      HeapPage::PageType type,
                                      GrowthPolicy growth_policy,
                                      bool is_protected,
@@ -533,12 +540,13 @@
   uword result = 0;
   if (Heap::IsAllocatableViaFreeLists(size)) {
     if (is_locked) {
-      result = freelist_[type].TryAllocateLocked(size, is_protected);
+      result = freelist->TryAllocateLocked(size, is_protected);
     } else {
-      result = freelist_[type].TryAllocate(size, is_protected);
+      result = freelist->TryAllocate(size, is_protected);
     }
     if (result == 0) {
-      result = TryAllocateInFreshPage(size, type, growth_policy, is_locked);
+      result = TryAllocateInFreshPage(size, freelist, type, growth_policy,
+                                      is_locked);
       // usage_ is updated by the call above.
     } else {
       usage_.used_in_words += (size >> kWordSizeLog2);
@@ -551,20 +559,16 @@
   return result;
 }
 
-void PageSpace::AcquireDataLock() {
-  freelist_[HeapPage::kData].mutex()->Lock();
+void PageSpace::AcquireLock(FreeList* freelist) {
+  freelist->mutex()->Lock();
 }
 
-void PageSpace::ReleaseDataLock() {
-  freelist_[HeapPage::kData].mutex()->Unlock();
+void PageSpace::ReleaseLock(FreeList* freelist) {
+  intptr_t size = freelist->TakeUnaccountedSizeLocked();
+  usage_.used_in_words += (size >> kWordSizeLog2);
+  freelist->mutex()->Unlock();
 }
 
-#if defined(DEBUG)
-bool PageSpace::CurrentThreadOwnsDataLock() {
-  return freelist_[HeapPage::kData].mutex()->IsOwnedByCurrentThread();
-}
-#endif
-
 void PageSpace::AllocateExternal(intptr_t cid, intptr_t size) {
   intptr_t size_in_words = size >> kWordSizeLog2;
   usage_.external_in_words += size_in_words;
@@ -681,16 +685,14 @@
   // Assert not called from concurrent sweeper task.
   // TODO(koda): Use thread/task identity when implemented.
   ASSERT(IsolateGroup::Current()->heap() != NULL);
-  if (bump_top_ < bump_end_) {
-    FreeListElement::AsElement(bump_top_, bump_end_ - bump_top_);
+  for (intptr_t i = 0; i < num_freelists_; i++) {
+    freelists_[i].MakeIterable();
   }
 }
 
 void PageSpace::AbandonBumpAllocation() {
-  if (bump_top_ < bump_end_) {
-    freelist_[HeapPage::kData].Free(bump_top_, bump_end_ - bump_top_);
-    bump_top_ = 0;
-    bump_end_ = 0;
+  for (intptr_t i = 0; i < num_freelists_; i++) {
+    freelists_[i].AbandonBumpAllocation();
   }
 }
 
@@ -808,7 +810,8 @@
 }
 
 void PageSpace::VisitRememberedCards(ObjectPointerVisitor* visitor) const {
-  ASSERT(Thread::Current()->IsAtSafepoint());
+  ASSERT(Thread::Current()->IsAtSafepoint() ||
+         (Thread::Current()->task_kind() == Thread::kScavengerTask));
 
   // Wait for the sweeper to finish mutating the large page list.
   MonitorLocker ml(tasks_lock());
@@ -816,17 +819,30 @@
     ml.Wait();  // No safepoint check.
   }
 
-  for (HeapPage* page = large_pages_; page != nullptr; page = page->next()) {
+  // Large pages may be added concurrently due to promotion in another scavenge
+  // worker, so terminate the traversal when we hit the tail we saw while
+  // holding the pages lock, instead of at NULL, otherwise we are racing when we
+  // read HeapPage::next_ and HeapPage::remembered_cards_.
+  HeapPage* page;
+  HeapPage* tail;
+  {
+    MutexLocker ml(&pages_lock_);
+    page = large_pages_;
+    tail = large_pages_tail_;
+  }
+  while (page != nullptr) {
     page->VisitRememberedCards(visitor);
+    if (page == tail) break;
+    page = page->next();
   }
 }
 
-RawObject* PageSpace::FindObject(FindObjectVisitor* visitor,
-                                 HeapPage::PageType type) const {
+ObjectPtr PageSpace::FindObject(FindObjectVisitor* visitor,
+                                HeapPage::PageType type) const {
   if (type == HeapPage::kExecutable) {
     // Fast path executable pages.
     for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
-      RawObject* obj = it.page()->FindObject(visitor);
+      ObjectPtr obj = it.page()->FindObject(visitor);
       if (obj != Object::null()) {
         return obj;
       }
@@ -836,7 +852,7 @@
 
   for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
     if (it.page()->type() == type) {
-      RawObject* obj = it.page()->FindObject(visitor);
+      ObjectPtr obj = it.page()->FindObject(visitor);
       if (obj != Object::null()) {
         return obj;
       }
@@ -886,8 +902,8 @@
 class HeapMapAsJSONVisitor : public ObjectVisitor {
  public:
   explicit HeapMapAsJSONVisitor(JSONArray* array) : array_(array) {}
-  virtual void VisitObject(RawObject* obj) {
-    array_->AddValue(obj->HeapSize() / kObjectAlignment);
+  virtual void VisitObject(ObjectPtr obj) {
+    array_->AddValue(obj->ptr()->HeapSize() / kObjectAlignment);
     array_->AddValue(obj->GetClassId());
   }
 
@@ -1097,7 +1113,7 @@
   const int64_t start = OS::GetCurrentMonotonicMicros();
 
   // Perform various cleanup that relies on no tasks interfering.
-  isolate_group->class_table()->FreeOldTables();
+  isolate_group->shared_class_table()->FreeOldTables();
   isolate_group->ForEachIsolate(
       [&](Isolate* isolate) { isolate->field_table()->FreeOldTables(); },
       /*at_safepoint=*/true);
@@ -1105,10 +1121,10 @@
   NoSafepointScope no_safepoints;
 
   if (FLAG_print_free_list_before_gc) {
-    OS::PrintErr("Data Freelist (before GC):\n");
-    freelist_[HeapPage::kData].Print();
-    OS::PrintErr("Executable Freelist (before GC):\n");
-    freelist_[HeapPage::kExecutable].Print();
+    for (intptr_t i = 0; i < num_freelists_; i++) {
+      OS::PrintErr("Before GC: Freelist %" Pd "\n", i);
+      freelists_[i].Print();
+    }
   }
 
   if (FLAG_verify_before_gc) {
@@ -1149,8 +1165,9 @@
   // Abandon the remainder of the bump allocation block.
   AbandonBumpAllocation();
   // Reset the freelists and setup sweeping.
-  freelist_[HeapPage::kData].Reset();
-  freelist_[HeapPage::kExecutable].Reset();
+  for (intptr_t i = 0; i < num_freelists_; i++) {
+    freelists_[i].Reset();
+  }
 
   int64_t mid2 = OS::GetCurrentMonotonicMicros();
   int64_t mid3 = 0;
@@ -1169,7 +1186,7 @@
     GCSweeper sweeper;
     HeapPage* prev_page = NULL;
     HeapPage* page = exec_pages_;
-    FreeList* freelist = &freelist_[HeapPage::kExecutable];
+    FreeList* freelist = &freelists_[HeapPage::kExecutable];
     MutexLocker ml(freelist->mutex());
     while (page != NULL) {
       HeapPage* next_page = page->next();
@@ -1215,10 +1232,10 @@
   heap_->RecordTime(kSweepLargePages, end - mid3);
 
   if (FLAG_print_free_list_after_gc) {
-    OS::PrintErr("Data Freelist (after GC):\n");
-    freelist_[HeapPage::kData].Print();
-    OS::PrintErr("Executable Freelist (after GC):\n");
-    freelist_[HeapPage::kExecutable].Print();
+    for (intptr_t i = 0; i < num_freelists_; i++) {
+      OS::PrintErr("After GC: Freelist %" Pd "\n", i);
+      freelists_[i].Print();
+    }
   }
 
   UpdateMaxUsed();
@@ -1251,14 +1268,21 @@
   TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "Sweep");
 
   GCSweeper sweeper;
+
+  intptr_t shard = 0;
+  const intptr_t num_shards = Utils::Maximum(FLAG_scavenger_tasks, 1);
+  for (intptr_t i = 0; i < num_shards; i++) {
+    DataFreeList(i)->mutex()->Lock();
+  }
+
   HeapPage* prev_page = nullptr;
   HeapPage* page = pages_;
-  FreeList* freelist = &freelist_[HeapPage::kData];
-  MutexLocker ml(freelist_->mutex());
   while (page != nullptr) {
     HeapPage* next_page = page->next();
     ASSERT(page->type() == HeapPage::kData);
-    bool page_in_use = sweeper.SweepPage(page, freelist, true /*is_locked*/);
+    shard = (shard + 1) % num_shards;
+    bool page_in_use =
+        sweeper.SweepPage(page, DataFreeList(shard), true /*is_locked*/);
     if (page_in_use) {
       prev_page = page;
     } else {
@@ -1268,6 +1292,10 @@
     page = next_page;
   }
 
+  for (intptr_t i = 0; i < num_shards; i++) {
+    DataFreeList(i)->mutex()->Unlock();
+  }
+
   if (FLAG_verify_after_gc) {
     OS::PrintErr("Verifying after sweeping...");
     heap_->VerifyGC(kForbidMarked);
@@ -1278,13 +1306,13 @@
 void PageSpace::ConcurrentSweep(IsolateGroup* isolate_group) {
   // Start the concurrent sweeper task now.
   GCSweeper::SweepConcurrent(isolate_group, pages_, pages_tail_, large_pages_,
-                             large_pages_tail_, &freelist_[HeapPage::kData]);
+                             large_pages_tail_, &freelists_[HeapPage::kData]);
 }
 
 void PageSpace::Compact(Thread* thread) {
   thread->isolate_group()->set_compaction_in_progress(true);
   GCCompactor compactor(thread, heap_);
-  compactor.Compact(pages_, &freelist_[HeapPage::kData], &pages_lock_);
+  compactor.Compact(pages_, &freelists_[HeapPage::kData], &pages_lock_);
   thread->isolate_group()->set_compaction_in_progress(false);
 
   if (FLAG_verify_after_gc) {
@@ -1294,63 +1322,57 @@
   }
 }
 
-uword PageSpace::TryAllocateDataBumpLocked(intptr_t size) {
+uword PageSpace::TryAllocateDataBumpLocked(FreeList* freelist, intptr_t size) {
   ASSERT(size >= kObjectAlignment);
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
-  intptr_t remaining = bump_end_ - bump_top_;
+
+  intptr_t remaining = freelist->end() - freelist->top();
   if (UNLIKELY(remaining < size)) {
     // Checking this first would be logical, but needlessly slow.
     if (!Heap::IsAllocatableViaFreeLists(size)) {
-      return TryAllocateDataLocked(size, kForceGrowth);
+      return TryAllocateDataLocked(freelist, size, kForceGrowth);
     }
-    FreeListElement* block =
-        freelist_[HeapPage::kData].TryAllocateLargeLocked(size);
+    FreeListElement* block = freelist->TryAllocateLargeLocked(size);
     if (block == NULL) {
       // Allocating from a new page (if growth policy allows) will have the
       // side-effect of populating the freelist with a large block. The next
       // bump allocation request will have a chance to consume that block.
       // TODO(koda): Could take freelist lock just once instead of twice.
-      return TryAllocateInFreshPage(size, HeapPage::kData, kForceGrowth,
-                                    true /* is_locked*/);
+      return TryAllocateInFreshPage(size, freelist, HeapPage::kData,
+                                    kForceGrowth, true /* is_locked*/);
     }
     intptr_t block_size = block->HeapSize();
     if (remaining > 0) {
-      freelist_[HeapPage::kData].FreeLocked(bump_top_, remaining);
+      freelist->FreeLocked(freelist->top(), remaining);
     }
-    bump_top_ = reinterpret_cast<uword>(block);
-    bump_end_ = bump_top_ + block_size;
+    freelist->set_top(reinterpret_cast<uword>(block));
+    freelist->set_end(freelist->top() + block_size);
     remaining = block_size;
   }
   ASSERT(remaining >= size);
-  uword result = bump_top_;
-  bump_top_ += size;
+  uword result = freelist->top();
+  freelist->set_top(result + size);
 
-  // No need for atomic operation: This is either running during a scavenge or
-  // isolate snapshot loading. Note that operator+= is atomic.
-  usage_.used_in_words = usage_.used_in_words + (size >> kWordSizeLog2);
+  freelist->AddUnaccountedSize(size);
 
 // Note: Remaining block is unwalkable until MakeIterable is called.
 #ifdef DEBUG
-  if (bump_top_ < bump_end_) {
+  if (freelist->top() < freelist->end()) {
     // Fail fast if we try to walk the remaining block.
     COMPILE_ASSERT(kIllegalCid == 0);
-    *reinterpret_cast<uword*>(bump_top_) = 0;
+    *reinterpret_cast<uword*>(freelist->top()) = 0;
   }
 #endif  // DEBUG
   return result;
 }
 
-DART_FLATTEN
-uword PageSpace::TryAllocatePromoLocked(intptr_t size) {
-  FreeList* freelist = &freelist_[HeapPage::kData];
+uword PageSpace::TryAllocatePromoLockedSlow(FreeList* freelist, intptr_t size) {
   uword result = freelist->TryAllocateSmallLocked(size);
   if (result != 0) {
-    // No need for atomic operation: we're at a safepoint. Note that
-    // operator+= is atomic.
-    usage_.used_in_words = usage_.used_in_words + (size >> kWordSizeLog2);
+    freelist->AddUnaccountedSize(size);
     return result;
   }
-  return TryAllocateDataBumpLocked(size);
+  return TryAllocateDataBumpLocked(freelist, size);
 }
 
 void PageSpace::SetupImagePage(void* pointer, uword size, bool is_executable) {
@@ -1383,8 +1405,8 @@
   image_pages_ = page;
 }
 
-bool PageSpace::IsObjectFromImagePages(dart::RawObject* object) {
-  uword object_addr = RawObject::ToAddr(object);
+bool PageSpace::IsObjectFromImagePages(dart::ObjectPtr object) {
+  uword object_addr = ObjectLayout::ToAddr(object);
   HeapPage* image_page = image_pages_;
   while (image_page != nullptr) {
     if (image_page->Contains(object_addr)) {
@@ -1438,18 +1460,19 @@
 void PageSpace::MergeOtherPageSpace(PageSpace* other) {
   other->AbandonBumpAllocation();
 
-  ASSERT(other->bump_top_ == 0 && other->bump_end_ == 0);
   ASSERT(other->tasks_ == 0);
   ASSERT(other->concurrent_marker_tasks_ == 0);
   ASSERT(other->phase_ == kDone);
   DEBUG_ASSERT(other->iterating_thread_ == nullptr);
   ASSERT(other->marker_ == nullptr);
 
-  for (intptr_t i = 0; i < HeapPage::kNumPageTypes; ++i) {
+  for (intptr_t i = 0; i < num_freelists_; ++i) {
+    ASSERT(other->freelists_[i].top() == 0);
+    ASSERT(other->freelists_[i].end() == 0);
     const bool is_protected =
         FLAG_write_protect_code && i == HeapPage::kExecutable;
-    freelist_[i].MergeOtherFreelist(&other->freelist_[i], is_protected);
-    other->freelist_[i].Reset();
+    freelists_[i].MergeOtherFreelist(&other->freelists_[i], is_protected);
+    other->freelists_[i].Reset();
   }
 
   // The freelist locks will be taken in MergeOtherFreelist above, and the
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index d51e697..6460ae0 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -39,7 +39,7 @@
 // A page containing old generation objects.
 class HeapPage {
  public:
-  enum PageType { kData = 0, kExecutable, kNumPageTypes };
+  enum PageType { kExecutable = 0, kData };
 
   HeapPage* next() const { return next_; }
   void set_next(HeapPage* next) { next_ = next; }
@@ -65,7 +65,7 @@
   void VisitObjects(ObjectVisitor* visitor) const;
   void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
 
-  RawObject* FindObject(FindObjectVisitor* visitor) const;
+  ObjectPtr FindObject(FindObjectVisitor* visitor) const;
 
   void WriteProtect(bool read_only);
 
@@ -76,11 +76,10 @@
   // Warning: This does not work for objects on image pages because image pages
   // are not aligned. However, it works for objects on large pages, because
   // only one object is allocated per large page.
-  static HeapPage* Of(RawObject* obj) {
+  static HeapPage* Of(ObjectPtr obj) {
     ASSERT(obj->IsHeapObject());
     ASSERT(obj->IsOldObject());
-    return reinterpret_cast<HeapPage*>(reinterpret_cast<uword>(obj) &
-                                       kPageMask);
+    return reinterpret_cast<HeapPage*>(static_cast<uword>(obj) & kPageMask);
   }
 
   // Warning: This does not work for addresses on image pages or on large pages.
@@ -89,16 +88,16 @@
   }
 
   // Warning: This does not work for objects on image pages.
-  static RawObject* ToExecutable(RawObject* obj) {
+  static ObjectPtr ToExecutable(ObjectPtr obj) {
     HeapPage* page = Of(obj);
     VirtualMemory* memory = page->memory_;
     const intptr_t alias_offset = memory->AliasOffset();
     if (alias_offset == 0) {
       return obj;  // Not aliased.
     }
-    uword addr = RawObject::ToAddr(obj);
+    uword addr = ObjectLayout::ToAddr(obj);
     if (memory->Contains(addr)) {
-      return RawObject::FromAddr(addr + alias_offset);
+      return ObjectLayout::FromAddr(addr + alias_offset);
     }
     // obj is executable.
     ASSERT(memory->ContainsAlias(addr));
@@ -106,16 +105,16 @@
   }
 
   // Warning: This does not work for objects on image pages.
-  static RawObject* ToWritable(RawObject* obj) {
+  static ObjectPtr ToWritable(ObjectPtr obj) {
     HeapPage* page = Of(obj);
     VirtualMemory* memory = page->memory_;
     const intptr_t alias_offset = memory->AliasOffset();
     if (alias_offset == 0) {
       return obj;  // Not aliased.
     }
-    uword addr = RawObject::ToAddr(obj);
+    uword addr = ObjectLayout::ToAddr(obj);
     if (memory->ContainsAlias(addr)) {
-      return RawObject::FromAddr(addr - alias_offset);
+      return ObjectLayout::FromAddr(addr - alias_offset);
     }
     // obj is writable.
     ASSERT(memory->Contains(addr));
@@ -134,7 +133,7 @@
     return OFFSET_OF(HeapPage, card_table_);
   }
 
-  void RememberCard(RawObject* const* slot) {
+  void RememberCard(ObjectPtr const* slot) {
     ASSERT(Contains(reinterpret_cast<uword>(slot)));
     if (card_table_ == NULL) {
       card_table_ = reinterpret_cast<uint8_t*>(
@@ -303,8 +302,8 @@
     bool is_protected =
         (type == HeapPage::kExecutable) && FLAG_write_protect_code;
     bool is_locked = false;
-    return TryAllocateInternal(size, type, growth_policy, is_protected,
-                               is_locked);
+    return TryAllocateInternal(size, &freelists_[type], type, growth_policy,
+                               is_protected, is_locked);
   }
 
   bool NeedsGarbageCollection() const {
@@ -362,8 +361,8 @@
 
   void VisitRememberedCards(ObjectPointerVisitor* visitor) const;
 
-  RawObject* FindObject(FindObjectVisitor* visitor,
-                        HeapPage::PageType type) const;
+  ObjectPtr FindObject(FindObjectVisitor* visitor,
+                       HeapPage::PageType type) const;
 
   // Collect the garbage in the page space using mark-sweep or mark-compact.
   void CollectGarbage(bool compact, bool finalize);
@@ -415,16 +414,18 @@
   void FreeExternal(intptr_t size);
 
   // Bulk data allocation.
-  void AcquireDataLock();
-  void ReleaseDataLock();
-#if defined(DEBUG)
-  bool CurrentThreadOwnsDataLock();
-#endif
+  FreeList* DataFreeList(intptr_t i = 0) {
+    return &freelists_[HeapPage::kData + i];
+  }
+  void AcquireLock(FreeList* freelist);
+  void ReleaseLock(FreeList* freelist);
 
-  uword TryAllocateDataLocked(intptr_t size, GrowthPolicy growth_policy) {
+  uword TryAllocateDataLocked(FreeList* freelist,
+                              intptr_t size,
+                              GrowthPolicy growth_policy) {
     bool is_protected = false;
     bool is_locked = true;
-    return TryAllocateInternal(size, HeapPage::kData, growth_policy,
+    return TryAllocateInternal(size, freelist, HeapPage::kData, growth_policy,
                                is_protected, is_locked);
   }
 
@@ -443,9 +444,19 @@
   void set_phase(Phase val) { phase_ = val; }
 
   // Attempt to allocate from bump block rather than normal freelist.
-  uword TryAllocateDataBumpLocked(intptr_t size);
-  // Prefer small freelist blocks, then chip away at the bump block.
-  uword TryAllocatePromoLocked(intptr_t size);
+  uword TryAllocateDataBumpLocked(intptr_t size) {
+    return TryAllocateDataBumpLocked(&freelists_[HeapPage::kData], size);
+  }
+  uword TryAllocateDataBumpLocked(FreeList* freelist, intptr_t size);
+  DART_FORCE_INLINE
+  uword TryAllocatePromoLocked(FreeList* freelist, intptr_t size) {
+    uword result = freelist->TryAllocateBumpLocked(size);
+    if (result != 0) {
+      return result;
+    }
+    return TryAllocatePromoLockedSlow(freelist, size);
+  }
+  uword TryAllocatePromoLockedSlow(FreeList* freelist, intptr_t size);
 
   void SetupImagePage(void* pointer, uword size, bool is_executable);
 
@@ -459,7 +470,7 @@
     enable_concurrent_mark_ = enable_concurrent_mark;
   }
 
-  bool IsObjectFromImagePages(RawObject* object);
+  bool IsObjectFromImagePages(ObjectPtr object);
 
   void MergeOtherPageSpace(PageSpace* other);
 
@@ -481,11 +492,13 @@
   };
 
   uword TryAllocateInternal(intptr_t size,
+                            FreeList* freelist,
                             HeapPage::PageType type,
                             GrowthPolicy growth_policy,
                             bool is_protected,
                             bool is_locked);
   uword TryAllocateInFreshPage(intptr_t size,
+                               FreeList* freelist,
                                HeapPage::PageType type,
                                GrowthPolicy growth_policy,
                                bool is_locked);
@@ -535,9 +548,15 @@
             (increase_in_words <= free_capacity_in_words));
   }
 
-  FreeList freelist_[HeapPage::kNumPageTypes];
+  Heap* const heap_;
 
-  Heap* heap_;
+  // One list for executable pages at freelists_[HeapPage::kExecutable].
+  // FLAG_scavenger_tasks count of lists for data pages starting at
+  // freelists_[HeapPage::kData]. The sweeper inserts into the data page
+  // freelists round-robin. The scavenger workers each use one of the data
+  // page freelists without locking.
+  const intptr_t num_freelists_;
+  FreeList* freelists_;
 
   // Use ExclusivePageIterator for safe access to these.
   mutable Mutex pages_lock_;
@@ -549,11 +568,6 @@
   HeapPage* large_pages_tail_ = nullptr;
   HeapPage* image_pages_ = nullptr;
 
-  // A block of memory in a data page, managed by bump allocation. The remainder
-  // is kept formatted as a FreeListElement, but is not in any freelist.
-  uword bump_top_;
-  uword bump_end_;
-
   // Various sizes being tracked for this generation.
   intptr_t max_capacity_in_words_;
 
diff --git a/runtime/vm/heap/pointer_block.cc b/runtime/vm/heap/pointer_block.cc
index 69bc1f5..2814465 100644
--- a/runtime/vm/heap/pointer_block.cc
+++ b/runtime/vm/heap/pointer_block.cc
@@ -69,7 +69,7 @@
 }
 
 template <int BlockSize>
-typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::Blocks() {
+typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::TakeBlocks() {
   MutexLocker ml(&mutex_);
   while (!partial_.IsEmpty()) {
     full_.Push(partial_.Pop());
diff --git a/runtime/vm/heap/pointer_block.h b/runtime/vm/heap/pointer_block.h
index b5fa276..73cf03b 100644
--- a/runtime/vm/heap/pointer_block.h
+++ b/runtime/vm/heap/pointer_block.h
@@ -8,15 +8,15 @@
 #include "platform/assert.h"
 #include "vm/globals.h"
 #include "vm/os_thread.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
 // Forward declarations.
 class Isolate;
-class RawObject;
 class ObjectPointerVisitor;
 
-// A set of RawObject*. Must be emptied before destruction (using Pop/Reset).
+// A set of ObjectPtr. Must be emptied before destruction (using Pop/Reset).
 template <int Size>
 class PointerBlock {
  public:
@@ -24,7 +24,7 @@
 
   void Reset() {
     top_ = 0;
-    next_ = NULL;
+    next_ = nullptr;
   }
 
   PointerBlock<Size>* next() const { return next_; }
@@ -33,18 +33,18 @@
   bool IsFull() const { return Count() == kSize; }
   bool IsEmpty() const { return Count() == 0; }
 
-  void Push(RawObject* obj) {
+  void Push(ObjectPtr obj) {
     ASSERT(!IsFull());
     pointers_[top_++] = obj;
   }
 
-  RawObject* Pop() {
+  ObjectPtr Pop() {
     ASSERT(!IsEmpty());
     return pointers_[--top_];
   }
 
 #if defined(TESTING)
-  bool Contains(RawObject* obj) const {
+  bool Contains(ObjectPtr obj) const {
     // Generated code appends to store buffers; tell MemorySanitizer.
     MSAN_UNPOISON(this, sizeof(*this));
     for (intptr_t i = 0; i < Count(); i++) {
@@ -64,14 +64,14 @@
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
  private:
-  PointerBlock() : next_(NULL), top_(0) {}
+  PointerBlock() : next_(nullptr), top_(0) {}
   ~PointerBlock() {
     ASSERT(IsEmpty());  // Guard against unintentionally discarding pointers.
   }
 
   PointerBlock<Size>* next_;
   int32_t top_;
-  RawObject* pointers_[kSize];
+  ObjectPtr pointers_[kSize];
 
   template <int>
   friend class BlockStack;
@@ -100,7 +100,7 @@
   Block* PopNonEmptyBlock();
 
   // Pops and returns all non-empty blocks as a linked list (owned by caller).
-  Block* Blocks();
+  Block* TakeBlocks();
 
   // Discards the contents of all non-empty blocks.
   void Reset();
@@ -110,12 +110,12 @@
  protected:
   class List {
    public:
-    List() : head_(NULL), length_(0) {}
+    List() : head_(nullptr), length_(0) {}
     ~List();
     void Push(Block* block);
     Block* Pop();
     intptr_t length() const { return length_; }
-    bool IsEmpty() const { return head_ == NULL; }
+    bool IsEmpty() const { return head_ == nullptr; }
     Block* PopAll();
     Block* Peek() { return head_; }
 
@@ -144,6 +144,74 @@
   DISALLOW_COPY_AND_ASSIGN(BlockStack);
 };
 
+template <typename Stack>
+class BlockWorkList : public ValueObject {
+ public:
+  typedef typename Stack::Block Block;
+
+  explicit BlockWorkList(Stack* stack) : stack_(stack) {
+    work_ = stack_->PopEmptyBlock();
+  }
+
+  ~BlockWorkList() {
+    ASSERT(work_ == nullptr);
+    ASSERT(stack_ == nullptr);
+  }
+
+  // Returns nullptr if no more work was found.
+  ObjectPtr Pop() {
+    ASSERT(work_ != nullptr);
+    if (work_->IsEmpty()) {
+      // TODO(koda): Track over/underflow events and use in heuristics to
+      // distribute work and prevent degenerate flip-flopping.
+      Block* new_work = stack_->PopNonEmptyBlock();
+      if (new_work == nullptr) {
+        return nullptr;
+      }
+      stack_->PushBlock(work_);
+      work_ = new_work;
+      // Generated code appends to marking stacks; tell MemorySanitizer.
+      MSAN_UNPOISON(work_, sizeof(*work_));
+    }
+    return work_->Pop();
+  }
+
+  void Push(ObjectPtr raw_obj) {
+    if (work_->IsFull()) {
+      // TODO(koda): Track over/underflow events and use in heuristics to
+      // distribute work and prevent degenerate flip-flopping.
+      stack_->PushBlock(work_);
+      work_ = stack_->PopEmptyBlock();
+    }
+    work_->Push(raw_obj);
+  }
+
+  void Finalize() {
+    ASSERT(work_->IsEmpty());
+    stack_->PushBlock(work_);
+    work_ = nullptr;
+    // Fail fast on attempts to mark after finalizing.
+    stack_ = nullptr;
+  }
+
+  void AbandonWork() {
+    stack_->PushBlock(work_);
+    work_ = nullptr;
+    stack_ = nullptr;
+  }
+
+  bool IsEmpty() {
+    if (!work_->IsEmpty()) {
+      return false;
+    }
+    return stack_->IsEmpty();
+  }
+
+ private:
+  Block* work_;
+  Stack* stack_;
+};
+
 static const int kStoreBufferBlockSize = 1024;
 class StoreBuffer : public BlockStack<kStoreBufferBlockSize> {
  public:
@@ -176,6 +244,19 @@
 };
 
 typedef MarkingStack::Block MarkingStackBlock;
+typedef BlockWorkList<MarkingStack> MarkerWorkList;
+
+static const int kPromotionStackBlockSize = 64;
+class PromotionStack : public BlockStack<kPromotionStackBlockSize> {
+ public:
+  // Adds and transfers ownership of the block to the buffer.
+  void PushBlock(Block* block) {
+    BlockStack<Block::kSize>::PushBlockImpl(block);
+  }
+};
+
+typedef PromotionStack::Block PromotionStackBlock;
+typedef BlockWorkList<PromotionStack> PromotionWorkList;
 
 }  // namespace dart
 
diff --git a/runtime/vm/heap/safepoint.h b/runtime/vm/heap/safepoint.h
index 8615b53..7c3dde1 100644
--- a/runtime/vm/heap/safepoint.h
+++ b/runtime/vm/heap/safepoint.h
@@ -51,6 +51,8 @@
 
   void BlockForSafepoint(Thread* T);
 
+  bool IsOwnedByTheThread(Thread* thread) { return owner_ == thread; }
+
  private:
   void SafepointThreads(Thread* T);
   void ResumeThreads(Thread* T);
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 3de0aa3..26056f2 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -18,6 +18,7 @@
 #include "vm/object_id_ring.h"
 #include "vm/object_set.h"
 #include "vm/stack_frame.h"
+#include "vm/thread_barrier.h"
 #include "vm/thread_registry.h"
 #include "vm/timeline.h"
 #include "vm/visitor.h"
@@ -35,11 +36,11 @@
             "Grow new gen when less than this percentage is garbage.");
 DEFINE_FLAG(int, new_gen_growth_factor, 2, "Grow new gen by this factor.");
 
-// Scavenger uses RawObject::kMarkBit to distinguish forwarded and non-forwarded
-// objects. The kMarkBit does not intersect with the target address because of
-// object alignment.
+// Scavenger uses ObjectLayout::kMarkBit to distinguish forwarded and
+// non-forwarded objects. The kMarkBit does not intersect with the target
+// address because of object alignment.
 enum {
-  kForwardingMask = 1 << RawObject::kOldAndNotMarkedBit,
+  kForwardingMask = 1 << ObjectLayout::kOldAndNotMarkedBit,
   kNotForwarded = 0,
   kForwarded = kForwardingMask,
 };
@@ -55,12 +56,19 @@
   return header & ~kForwardingMask;
 }
 
-static inline void ForwardTo(uword original, uword target) {
+static inline uword ForwardingHeader(uword target) {
   // Make sure forwarding can be encoded.
   ASSERT((target & kForwardingMask) == 0);
-  *reinterpret_cast<uword*>(original) = target | kForwarded;
+  return target | kForwarded;
 }
 
+// Races: The first word in the copied region is a header word that may be
+// updated by the scavenger worker in another thread, so we might copy either
+// the original object header or an installed forwarding pointer. This race is
+// harmless because if we copy the installed forwarding pointer, the scavenge
+// worker in the current thread will abandon this copy. We do not mark the loads
+// here as relaxed so the C++ compiler still has the freedom to reorder them.
+NO_SANITIZE_THREAD
 static inline void objcpy(void* dst, const void* src, size_t size) {
   // A memcopy specialized for objects. We can assume:
   //  - dst and src do not overlap
@@ -86,42 +94,182 @@
   } while (size > 0);
 }
 
-class ScavengerVisitor : public ObjectPointerVisitor {
+static const intptr_t kNewPageSize = 512 * KB;
+static const intptr_t kNewPageSizeInWords = kNewPageSize / kWordSize;
+static const intptr_t kNewPageMask = ~(kNewPageSize - 1);
+
+// A page containing new generation objects.
+class NewPage {
  public:
-  explicit ScavengerVisitor(IsolateGroup* isolate_group,
-                            Scavenger* scavenger,
-                            SemiSpace* from)
+  static NewPage* Allocate();
+  void Deallocate();
+
+  uword start() const { return memory_->start(); }
+  uword end() const { return memory_->end(); }
+  bool Contains(uword addr) const { return memory_->Contains(addr); }
+  void WriteProtect(bool read_only) {
+    memory_->Protect(read_only ? VirtualMemory::kReadOnly
+                               : VirtualMemory::kReadWrite);
+  }
+
+  NewPage* next() const { return next_; }
+  void set_next(NewPage* next) { next_ = next; }
+
+  Thread* owner() const { return owner_; }
+
+  uword object_start() const { return start() + ObjectStartOffset(); }
+  uword object_end() const { return owner_ != nullptr ? owner_->top() : top_; }
+  void VisitObjects(ObjectVisitor* visitor) const {
+    uword addr = object_start();
+    uword end = object_end();
+    while (addr < end) {
+      ObjectPtr obj = ObjectLayout::FromAddr(addr);
+      visitor->VisitObject(obj);
+      addr += obj->ptr()->HeapSize();
+    }
+  }
+  void VisitObjectPointers(ObjectPointerVisitor* visitor) const {
+    uword addr = object_start();
+    uword end = object_end();
+    while (addr < end) {
+      ObjectPtr obj = ObjectLayout::FromAddr(addr);
+      intptr_t size = obj->ptr()->VisitPointers(visitor);
+      addr += size;
+    }
+  }
+
+  static intptr_t ObjectStartOffset() {
+    return Utils::RoundUp(sizeof(NewPage), kObjectAlignment) +
+           kNewObjectAlignmentOffset;
+  }
+
+  static NewPage* Of(ObjectPtr obj) {
+    ASSERT(obj->IsHeapObject());
+    ASSERT(obj->IsNewObject());
+    return Of(static_cast<uword>(obj));
+  }
+  static NewPage* Of(uword addr) {
+    return reinterpret_cast<NewPage*>(addr & kNewPageMask);
+  }
+
+  // Remember the limit to which objects have been copied.
+  void RecordSurvivors() { survivor_end_ = object_end(); }
+
+  // Move survivor end to the end of the to_ space, making all surviving
+  // objects candidates for promotion next time.
+  void EarlyTenure() { survivor_end_ = end_; }
+
+  uword promo_candidate_words() const {
+    return (survivor_end_ - object_start()) / kWordSize;
+  }
+
+  void Acquire(Thread* thread) {
+    ASSERT(owner_ == nullptr);
+    owner_ = thread;
+    thread->set_top(top_);
+    thread->set_end(end_);
+  }
+  void Release(Thread* thread) {
+    ASSERT(owner_ == thread);
+    owner_ = nullptr;
+    top_ = thread->top();
+    thread->set_top(0);
+    thread->set_end(0);
+  }
+  void Release() {
+    if (owner_ != nullptr) {
+      Release(owner_);
+    }
+  }
+
+  uword TryAllocateGC(intptr_t size) {
+    ASSERT(owner_ == nullptr);
+    uword result = top_;
+    uword new_top = result + size;
+    if (LIKELY(new_top < end_)) {
+      top_ = new_top;
+      return result;
+    }
+    return 0;
+  }
+
+  void Unallocate(uword addr, intptr_t size) {
+    ASSERT((addr + size) == top_);
+    top_ -= size;
+  }
+
+  bool IsSurvivor(uword raw_addr) const { return raw_addr < survivor_end_; }
+  bool IsResolved() const { return top_ == resolved_top_; }
+
+ private:
+  VirtualMemory* memory_;
+  NewPage* next_;
+
+  // The thread using this page for allocation, otherwise NULL.
+  Thread* owner_;
+
+  // The address of the next allocation. If owner is non-NULL, this value is
+  // stale and the current value is at owner->top_. Called "NEXT" in the
+  // original Cheney paper.
+  uword top_;
+
+  // The address after the last allocatable byte in this page.
+  uword end_;
+
+  // Objects below this address have survived a scavenge.
+  uword survivor_end_;
+
+  // A pointer to the first unprocessed object. Resolution completes when this
+  // value meets the allocation top. Called "SCAN" in the original Cheney paper.
+  uword resolved_top_;
+
+  template <bool>
+  friend class ScavengerVisitorBase;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(NewPage);
+};
+
+template <bool parallel>
+class ScavengerVisitorBase : public ObjectPointerVisitor {
+ public:
+  explicit ScavengerVisitorBase(IsolateGroup* isolate_group,
+                                Scavenger* scavenger,
+                                SemiSpace* from,
+                                FreeList* freelist,
+                                PromotionStack* promotion_stack)
       : ObjectPointerVisitor(isolate_group),
-        thread_(Thread::Current()),
+        thread_(nullptr),
         scavenger_(scavenger),
         from_(from),
-        heap_(scavenger->heap_),
         page_space_(scavenger->heap_->old_space()),
+        freelist_(freelist),
         bytes_promoted_(0),
-        visiting_old_object_(NULL) {}
+        visiting_old_object_(nullptr),
+        promoted_list_(promotion_stack) {}
 
-  virtual void VisitTypedDataViewPointers(RawTypedDataView* view,
-                                          RawObject** first,
-                                          RawObject** last) {
+  virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
+                                          ObjectPtr* first,
+                                          ObjectPtr* last) {
     // First we forward all fields of the typed data view.
     VisitPointers(first, last);
 
     if (view->ptr()->data_ == nullptr) {
-      ASSERT(ValueFromRawSmi(view->ptr()->offset_in_bytes_) == 0 &&
-             ValueFromRawSmi(view->ptr()->length_) == 0);
+      ASSERT(RawSmiValue(view->ptr()->offset_in_bytes_) == 0 &&
+             RawSmiValue(view->ptr()->length_) == 0);
       return;
     }
 
     // Validate 'this' is a typed data view.
     const uword view_header =
-        *reinterpret_cast<uword*>(RawObject::ToAddr(view));
+        *reinterpret_cast<uword*>(ObjectLayout::ToAddr(view));
     ASSERT(!IsForwarding(view_header) || view->IsOldObject());
-    ASSERT(RawObject::IsTypedDataViewClassId(view->GetClassIdMayBeSmi()));
+    ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()));
 
     // Validate that the backing store is not a forwarding word.
-    RawTypedDataBase* td = view->ptr()->typed_data_;
+    TypedDataBasePtr td = view->ptr()->typed_data_;
     ASSERT(td->IsHeapObject());
-    const uword td_header = *reinterpret_cast<uword*>(RawObject::ToAddr(td));
+    const uword td_header = *reinterpret_cast<uword*>(ObjectLayout::ToAddr(td));
     ASSERT(!IsForwarding(td_header) || td->IsOldObject());
 
     // We can always obtain the class id from the forwarded backing store.
@@ -129,166 +277,274 @@
 
     // If we have external typed data we can simply return since the backing
     // store lives in C-heap and will not move.
-    if (RawObject::IsExternalTypedDataClassId(cid)) {
+    if (IsExternalTypedDataClassId(cid)) {
       return;
     }
 
     // Now we update the inner pointer.
-    ASSERT(RawObject::IsTypedDataClassId(cid));
-    view->RecomputeDataFieldForInternalTypedData();
+    ASSERT(IsTypedDataClassId(cid));
+    view->ptr()->RecomputeDataFieldForInternalTypedData();
   }
 
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
     ASSERT(Utils::IsAligned(first, sizeof(*first)));
     ASSERT(Utils::IsAligned(last, sizeof(*last)));
-    for (RawObject** current = first; current <= last; current++) {
+    for (ObjectPtr* current = first; current <= last; current++) {
       ScavengePointer(current);
     }
   }
 
-  void VisitingOldObject(RawObject* obj) {
-    ASSERT((obj == NULL) || obj->IsOldObject());
+  void VisitingOldObject(ObjectPtr obj) {
+    ASSERT((obj == nullptr) || obj->IsOldObject());
     visiting_old_object_ = obj;
-    if (obj != NULL) {
+    if (obj != nullptr) {
       // Card update happens in HeapPage::VisitRememberedCards.
-      ASSERT(!obj->IsCardRemembered());
+      ASSERT(!obj->ptr()->IsCardRemembered());
     }
   }
 
   intptr_t bytes_promoted() const { return bytes_promoted_; }
 
+  void ProcessRoots() {
+    thread_ = Thread::Current();
+    page_space_->AcquireLock(freelist_);
+    scavenger_->IterateRoots(this);
+  }
+
+  void ProcessSurvivors() {
+    // Iterate until all work has been drained.
+    do {
+      ProcessToSpace();
+      ProcessPromotedList();
+    } while (HasWork());
+  }
+
+  void ProcessAll() {
+    do {
+      ProcessSurvivors();
+      ProcessWeakProperties();
+    } while (HasWork());
+  }
+
+  inline void ProcessWeakProperties();
+
+  bool HasWork() {
+    return (scan_ != tail_) || (scan_ != nullptr && !scan_->IsResolved()) ||
+           !promoted_list_.IsEmpty();
+  }
+
+  void Finalize() {
+    ASSERT(!HasWork());
+
+    for (NewPage* page = head_; page != nullptr; page = page->next()) {
+      ASSERT(page->IsResolved());
+      page->RecordSurvivors();
+    }
+
+    promoted_list_.Finalize();
+
+    MournWeakProperties();
+
+    page_space_->ReleaseLock(freelist_);
+    thread_ = nullptr;
+  }
+
+  NewPage* head() const { return head_; }
+  NewPage* tail() const { return tail_; }
+
  private:
-  void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
+  void UpdateStoreBuffer(ObjectPtr* p, ObjectPtr obj) {
     ASSERT(obj->IsHeapObject());
     // If the newly written object is not a new object, drop it immediately.
-    if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) {
+    if (!obj->IsNewObject() || visiting_old_object_->ptr()->IsRemembered()) {
       return;
     }
-    visiting_old_object_->SetRememberedBit();
+    visiting_old_object_->ptr()->SetRememberedBit();
     thread_->StoreBufferAddObjectGC(visiting_old_object_);
   }
 
   DART_FORCE_INLINE
-  void ScavengePointer(RawObject** p) {
+  void ScavengePointer(ObjectPtr* p) {
     // ScavengePointer cannot be called recursively.
-    RawObject* raw_obj = *p;
+    ObjectPtr raw_obj = *p;
 
     if (raw_obj->IsSmiOrOldObject()) {
       return;
     }
 
-    uword raw_addr = RawObject::ToAddr(raw_obj);
+    uword raw_addr = ObjectLayout::ToAddr(raw_obj);
     // The scavenger is only expects objects located in the from space.
     ASSERT(from_->Contains(raw_addr));
     // Read the header word of the object and determine if the object has
     // already been copied.
-    uword header = *reinterpret_cast<uword*>(raw_addr);
+    uword header = reinterpret_cast<std::atomic<uword>*>(raw_addr)->load(
+        std::memory_order_relaxed);
     uword new_addr = 0;
     if (IsForwarding(header)) {
       // Get the new location of the object.
       new_addr = ForwardedAddr(header);
     } else {
-      intptr_t size = raw_obj->HeapSize();
+      intptr_t size = raw_obj->ptr()->HeapSize(header);
       // Check whether object should be promoted.
-      if (scavenger_->survivor_end_ <= raw_addr) {
+      if (!NewPage::Of(raw_obj)->IsSurvivor(raw_addr)) {
         // Not a survivor of a previous scavenge. Just copy the object into the
         // to space.
-        new_addr = scavenger_->AllocateGC(size);
-      } else {
-        // TODO(iposva): Experiment with less aggressive promotion. For example
-        // a coin toss determines if an object is promoted or whether it should
-        // survive in this generation.
-        //
+        new_addr = TryAllocateCopy(size);
+      }
+      if (new_addr == 0) {
         // This object is a survivor of a previous scavenge. Attempt to promote
-        // the object.
-        new_addr = page_space_->TryAllocatePromoLocked(size);
-        if (new_addr != 0) {
+        // the object. (Or, unlikely, to-space was exhausted by fragmentation.)
+        new_addr = page_space_->TryAllocatePromoLocked(freelist_, size);
+        if (LIKELY(new_addr != 0)) {
           // If promotion succeeded then we need to remember it so that it can
           // be traversed later.
-          scavenger_->PushToPromotedStack(new_addr);
+          promoted_list_.Push(ObjectLayout::FromAddr(new_addr));
           bytes_promoted_ += size;
         } else {
           // Promotion did not succeed. Copy into the to space instead.
           scavenger_->failed_to_promote_ = true;
-          new_addr = scavenger_->AllocateGC(size);
+          new_addr = TryAllocateCopy(size);
+          // To-space was exhausted by fragmentation and old-space could not
+          // grow.
+          if (UNLIKELY(new_addr == 0)) {
+            FATAL("Failed to allocate during scavenge");
+          }
         }
       }
-      // During a scavenge we always succeed to at least copy all of the
-      // current objects to the to space.
       ASSERT(new_addr != 0);
       // Copy the object to the new location.
       objcpy(reinterpret_cast<void*>(new_addr),
              reinterpret_cast<void*>(raw_addr), size);
 
-      RawObject* new_obj = RawObject::FromAddr(new_addr);
+      ObjectPtr new_obj = ObjectLayout::FromAddr(new_addr);
       if (new_obj->IsOldObject()) {
         // Promoted: update age/barrier tags.
-        uint32_t tags = new_obj->ptr()->tags_;
-        tags = RawObject::OldBit::update(true, tags);
-        tags = RawObject::OldAndNotRememberedBit::update(true, tags);
-        tags = RawObject::NewBit::update(false, tags);
+        uint32_t tags = static_cast<uint32_t>(header);
+        tags = ObjectLayout::OldBit::update(true, tags);
+        tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+        tags = ObjectLayout::NewBit::update(false, tags);
         // Setting the forwarding pointer below will make this tenured object
         // visible to the concurrent marker, but we haven't visited its slots
         // yet. We mark the object here to prevent the concurrent marker from
         // adding it to the mark stack and visiting its unprocessed slots. We
         // push it to the mark stack after forwarding its slots.
-        tags =
-            RawObject::OldAndNotMarkedBit::update(!thread_->is_marking(), tags);
+        tags = ObjectLayout::OldAndNotMarkedBit::update(!thread_->is_marking(),
+                                                        tags);
         new_obj->ptr()->tags_ = tags;
       }
 
-      if (RawObject::IsTypedDataClassId(new_obj->GetClassId())) {
-        reinterpret_cast<RawTypedData*>(new_obj)->RecomputeDataField();
+      intptr_t cid = ObjectLayout::ClassIdTag::decode(header);
+      if (IsTypedDataClassId(cid)) {
+        static_cast<TypedDataPtr>(new_obj)->ptr()->RecomputeDataField();
       }
 
-      // Remember forwarding address.
-      ForwardTo(raw_addr, new_addr);
+      // Try to install forwarding address.
+      uword forwarding_header = ForwardingHeader(new_addr);
+      if (!InstallForwardingPointer(raw_addr, &header, forwarding_header)) {
+        ASSERT(IsForwarding(header));
+        if (new_obj->IsOldObject()) {
+          // Abandon as a free list element.
+          FreeListElement::AsElement(new_addr, size);
+          bytes_promoted_ -= size;
+        } else {
+          // Undo to-space allocation.
+          tail_->Unallocate(new_addr, size);
+        }
+        // Use the winner's forwarding target.
+        new_addr = ForwardedAddr(header);
+      }
     }
+
     // Update the reference.
-    RawObject* new_obj = RawObject::FromAddr(new_addr);
-    if (new_obj->IsOldObject()) {
+    ObjectPtr new_obj = ObjectLayout::FromAddr(new_addr);
+    if (!new_obj->IsNewObject()) {
       // Setting the mark bit above must not be ordered after a publishing store
       // 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<RawObject*>*>(p)->store(
+      reinterpret_cast<std::atomic<ObjectPtr>*>(p)->store(
           new_obj, std::memory_order_release);
     } else {
       *p = new_obj;
     }
     // Update the store buffer as needed.
-    if (visiting_old_object_ != NULL) {
+    if (visiting_old_object_ != nullptr) {
       UpdateStoreBuffer(p, new_obj);
     }
   }
 
+  DART_FORCE_INLINE
+  bool InstallForwardingPointer(uword addr,
+                                uword* old_header,
+                                uword new_header) {
+    if (parallel) {
+      return reinterpret_cast<std::atomic<uword>*>(addr)
+          ->compare_exchange_strong(*old_header, new_header,
+                                    std::memory_order_relaxed);
+    } else {
+      *reinterpret_cast<uword*>(addr) = new_header;
+      return true;
+    }
+  }
+
+  DART_FORCE_INLINE
+  uword TryAllocateCopy(intptr_t size) {
+    ASSERT(Utils::IsAligned(size, kObjectAlignment));
+    // TODO(rmacnak): Allocate one to start?
+    if (tail_ != nullptr) {
+      uword result = tail_->top_;
+      ASSERT((result & kObjectAlignmentMask) == kNewObjectAlignmentOffset);
+      uword new_top = result + size;
+      if (LIKELY(new_top <= tail_->end_)) {
+        tail_->top_ = new_top;
+        return result;
+      }
+    }
+    return TryAllocateCopySlow(size);
+  }
+
+  DART_NOINLINE inline uword TryAllocateCopySlow(intptr_t size);
+
+  inline void ProcessToSpace();
+  DART_FORCE_INLINE intptr_t ProcessCopied(ObjectPtr raw_obj);
+  inline void ProcessPromotedList();
+  inline void EnqueueWeakProperty(WeakPropertyPtr raw_weak);
+  inline void MournWeakProperties();
+
   Thread* thread_;
   Scavenger* scavenger_;
   SemiSpace* from_;
-  Heap* heap_;
   PageSpace* page_space_;
-  RawWeakProperty* delayed_weak_properties_;
+  FreeList* freelist_;
   intptr_t bytes_promoted_;
-  RawObject* visiting_old_object_;
+  ObjectPtr visiting_old_object_;
 
-  friend class Scavenger;
+  PromotionWorkList promoted_list_;
+  WeakPropertyPtr delayed_weak_properties_ = nullptr;
 
-  DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
+  NewPage* head_ = nullptr;
+  NewPage* tail_ = nullptr;  // Allocating from here.
+  NewPage* scan_ = nullptr;  // Resolving from here.
+
+  DISALLOW_COPY_AND_ASSIGN(ScavengerVisitorBase);
 };
 
+typedef ScavengerVisitorBase<false> SerialScavengerVisitor;
+typedef ScavengerVisitorBase<true> ParallelScavengerVisitor;
+
 class ScavengerWeakVisitor : public HandleVisitor {
  public:
   ScavengerWeakVisitor(Thread* thread, Scavenger* scavenger)
       : HandleVisitor(thread),
         scavenger_(scavenger),
-        class_table_(thread->isolate_group()->class_table()) {
+        class_table_(thread->isolate_group()->shared_class_table()) {
     ASSERT(scavenger->heap_->isolate_group() == thread->isolate_group());
   }
 
   void VisitHandle(uword addr) {
     FinalizablePersistentHandle* handle =
         reinterpret_cast<FinalizablePersistentHandle*>(addr);
-    RawObject** p = handle->raw_addr();
+    ObjectPtr* p = handle->raw_addr();
     if (scavenger_->IsUnreachable(p)) {
       handle->UpdateUnreachable(thread()->isolate_group());
     } else {
@@ -303,97 +559,250 @@
   DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor);
 };
 
-SemiSpace::SemiSpace(VirtualMemory* reserved)
-    : reserved_(reserved), region_(NULL, 0) {
-  if (reserved != NULL) {
-    region_ = MemoryRegion(reserved_->address(), reserved_->size());
+class ParallelScavengerTask : public ThreadPool::Task {
+ public:
+  ParallelScavengerTask(IsolateGroup* isolate_group,
+                        ThreadBarrier* barrier,
+                        ParallelScavengerVisitor* visitor,
+                        RelaxedAtomic<uintptr_t>* num_busy)
+      : isolate_group_(isolate_group),
+        barrier_(barrier),
+        visitor_(visitor),
+        num_busy_(num_busy) {}
+
+  virtual void Run() {
+    bool result = Thread::EnterIsolateGroupAsHelper(
+        isolate_group_, Thread::kScavengerTask, /*bypass_safepoint=*/true);
+    ASSERT(result);
+
+    RunEnteredIsolateGroup();
+
+    Thread::ExitIsolateGroupAsHelper(/*bypass_safepoint=*/true);
+
+    // This task is done. Notify the original thread.
+    barrier_->Exit();
   }
-}
+
+  void RunEnteredIsolateGroup() {
+    TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ParallelScavenge");
+
+    visitor_->ProcessRoots();
+
+    // Phase 1: Copying.
+    bool more_to_scavenge = false;
+    do {
+      do {
+        visitor_->ProcessSurvivors();
+
+        // I can't find more work right now. If no other task is busy,
+        // then there will never be more work (NB: 1 is *before* decrement).
+        if (num_busy_->fetch_sub(1u) == 1) break;
+
+        // Wait for some work to appear.
+        // TODO(iposva): Replace busy-waiting with a solution using Monitor,
+        // and redraw the boundaries between stack/visitor/task as needed.
+        while (!visitor_->HasWork() && num_busy_->load() > 0) {
+        }
+
+        // If no tasks are busy, there will never be more work.
+        if (num_busy_->load() == 0) break;
+
+        // I saw some work; get busy and compete for it.
+        num_busy_->fetch_add(1u);
+      } while (true);
+      // Wait for all scavengers to stop.
+      barrier_->Sync();
+#if defined(DEBUG)
+      ASSERT(num_busy_->load() == 0);
+      // Caveat: must not allow any marker to continue past the barrier
+      // before we checked num_busy, otherwise one of them might rush
+      // ahead and increment it.
+      barrier_->Sync();
+#endif
+      // Check if we have any pending properties with marked keys.
+      // Those might have been marked by another marker.
+      visitor_->ProcessWeakProperties();
+      more_to_scavenge = visitor_->HasWork();
+      if (more_to_scavenge) {
+        // We have more work to do. Notify others.
+        num_busy_->fetch_add(1u);
+      }
+
+      // Wait for all other scavengers to finish processing their pending
+      // weak properties and decide if they need to continue marking.
+      // Caveat: we need two barriers here to make this decision in lock step
+      // between all scavengers and the main thread.
+      barrier_->Sync();
+      if (!more_to_scavenge && (num_busy_->load() > 0)) {
+        // All scavengers continue to mark as long as any single marker has
+        // some work to do.
+        num_busy_->fetch_add(1u);
+        more_to_scavenge = true;
+      }
+      barrier_->Sync();
+    } while (more_to_scavenge);
+
+    // Phase 2: Weak processing, statistics.
+    visitor_->Finalize();
+    barrier_->Sync();
+  }
+
+ private:
+  IsolateGroup* isolate_group_;
+  ThreadBarrier* barrier_;
+  ParallelScavengerVisitor* visitor_;
+  RelaxedAtomic<uintptr_t>* num_busy_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParallelScavengerTask);
+};
+
+SemiSpace::SemiSpace(intptr_t max_capacity_in_words)
+    : max_capacity_in_words_(max_capacity_in_words), head_(nullptr) {}
 
 SemiSpace::~SemiSpace() {
-  delete reserved_;
+  NewPage* page = head_;
+  while (page != nullptr) {
+    NewPage* next = page->next();
+    page->Deallocate();
+    page = next;
+  }
 }
 
-Mutex* SemiSpace::mutex_ = NULL;
-SemiSpace* SemiSpace::cache_ = NULL;
+// TODO(rmacnak): Unify this with old-space pages, and possibly zone segments.
+// This cache needs to be at least as big as FLAG_new_gen_semi_max_size or
+// munmap will noticably impact performance.
+static constexpr intptr_t kPageCacheCapacity = 8 * kWordSize;
+static Mutex* page_cache_mutex = nullptr;
+static VirtualMemory* page_cache[kPageCacheCapacity] = {nullptr};
+static intptr_t page_cache_size = 0;
 
 void SemiSpace::Init() {
-  if (mutex_ == NULL) {
-    mutex_ = new Mutex();
-  }
-  ASSERT(mutex_ != NULL);
+  ASSERT(page_cache_mutex == nullptr);
+  page_cache_mutex = new Mutex(NOT_IN_PRODUCT("page_cache_mutex"));
 }
 
 void SemiSpace::Cleanup() {
-  MutexLocker locker(mutex_);
-  delete cache_;
-  cache_ = NULL;
+  {
+    MutexLocker ml(page_cache_mutex);
+    ASSERT(page_cache_size >= 0);
+    ASSERT(page_cache_size <= kPageCacheCapacity);
+    while (page_cache_size > 0) {
+      delete page_cache[--page_cache_size];
+    }
+  }
+  delete page_cache_mutex;
+  page_cache_mutex = nullptr;
 }
 
-SemiSpace* SemiSpace::New(intptr_t size_in_words, const char* name) {
-  SemiSpace* result = nullptr;
+NewPage* NewPage::Allocate() {
+  const intptr_t size = kNewPageSize;
+  VirtualMemory* memory = nullptr;
   {
-    MutexLocker locker(mutex_);
-    // TODO(koda): Cache one entry per size.
-    if (cache_ != nullptr && cache_->size_in_words() == size_in_words) {
-      result = cache_;
-      cache_ = nullptr;
+    MutexLocker ml(page_cache_mutex);
+    ASSERT(page_cache_size >= 0);
+    ASSERT(page_cache_size <= kPageCacheCapacity);
+    if (page_cache_size > 0) {
+      memory = page_cache[--page_cache_size];
     }
   }
-  if (result != nullptr) {
-#ifdef DEBUG
-    result->reserved_->Protect(VirtualMemory::kReadWrite);
-#endif
-    // Initialized by generated code.
-    MSAN_UNPOISON(result->reserved_->address(), size_in_words << kWordSizeLog2);
-    return result;
+  if (memory == nullptr) {
+    const intptr_t alignment = kNewPageSize;
+    const bool is_executable = false;
+    const char* const name = Heap::RegionName(Heap::kNew);
+    memory =
+        VirtualMemory::AllocateAligned(size, alignment, is_executable, name);
+  }
+  if (memory == nullptr) {
+    // TODO(koda): We could try to recover (collect old space, wait for another
+    // isolate to finish scavenge, etc.).
+    OUT_OF_MEMORY();
   }
 
-  if (size_in_words == 0) {
-    return new SemiSpace(nullptr);
-  } else {
-    intptr_t size_in_bytes = size_in_words << kWordSizeLog2;
-    const bool kExecutable = false;
-    VirtualMemory* memory =
-        VirtualMemory::Allocate(size_in_bytes, kExecutable, name);
-    if (memory == nullptr) {
-      // TODO(koda): If cache_ is not empty, we could try to delete it.
-      return nullptr;
-    }
 #if defined(DEBUG)
-    memset(memory->address(), Heap::kZapByte, size_in_bytes);
-#endif  // defined(DEBUG)
-    // Initialized by generated code.
-    MSAN_UNPOISON(memory->address(), size_in_bytes);
-    return new SemiSpace(memory);
-  }
+  memset(memory->address(), Heap::kZapByte, size);
+#endif
+  // Initialized by generated code.
+  MSAN_UNPOISON(memory->address(), size);
+
+  NewPage* result = reinterpret_cast<NewPage*>(memory->address());
+  result->memory_ = memory;
+  result->next_ = nullptr;
+  result->owner_ = nullptr;
+  uword top = result->object_start();
+  result->top_ = top;
+  result->end_ = memory->end() - kNewObjectAlignmentOffset;
+  result->survivor_end_ = top;
+  result->resolved_top_ = top;
+
+  LSAN_REGISTER_ROOT_REGION(result, sizeof(*result));
+
+  return result;
 }
 
-void SemiSpace::Delete() {
-  if (reserved_ != nullptr) {
-    const intptr_t size_in_bytes = size_in_words() << kWordSizeLog2;
-#ifdef DEBUG
-    memset(reserved_->address(), Heap::kZapByte, size_in_bytes);
-    reserved_->Protect(VirtualMemory::kNoAccess);
-#endif
-    MSAN_POISON(reserved_->address(), size_in_bytes);
-  }
-  SemiSpace* old_cache = nullptr;
+void NewPage::Deallocate() {
+  LSAN_UNREGISTER_ROOT_REGION(this, sizeof(*this));
+
+  VirtualMemory* memory = memory_;
   {
-    MutexLocker locker(mutex_);
-    old_cache = cache_;
-    cache_ = this;
+    MutexLocker ml(page_cache_mutex);
+    ASSERT(page_cache_size >= 0);
+    ASSERT(page_cache_size <= kPageCacheCapacity);
+    if (page_cache_size < kPageCacheCapacity) {
+      intptr_t size = memory->size();
+#if defined(DEBUG)
+      memset(memory->address(), Heap::kZapByte, size);
+#endif
+      MSAN_POISON(memory->address(), size);
+      page_cache[page_cache_size++] = memory;
+      memory = nullptr;
+    }
   }
-  delete old_cache;
+  delete memory;
+}
+
+NewPage* SemiSpace::TryAllocatePageLocked(bool link) {
+  if (capacity_in_words_ >= max_capacity_in_words_) {
+    return nullptr;  // Full.
+  }
+  NewPage* page = NewPage::Allocate();
+  capacity_in_words_ += kNewPageSizeInWords;
+  if (link) {
+    if (head_ == nullptr) {
+      head_ = tail_ = page;
+    } else {
+      tail_->set_next(page);
+      tail_ = page;
+    }
+  }
+  return page;
+}
+
+bool SemiSpace::Contains(uword addr) const {
+  for (NewPage* page = head_; page != nullptr; page = page->next()) {
+    if (page->Contains(addr)) return true;
+  }
+  return false;
 }
 
 void SemiSpace::WriteProtect(bool read_only) {
-  if (reserved_ != NULL) {
-    reserved_->Protect(read_only ? VirtualMemory::kReadOnly
-                                 : VirtualMemory::kReadWrite);
+  for (NewPage* page = head_; page != nullptr; page = page->next()) {
+    page->WriteProtect(read_only);
   }
 }
 
+void SemiSpace::AddList(NewPage* head, NewPage* tail) {
+  if (head == nullptr) {
+    return;
+  }
+  if (head_ == nullptr) {
+    head_ = head;
+    tail_ = tail;
+    return;
+  }
+  tail_->set_next(head);
+  tail_ = tail;
+}
+
 // The initial estimate of how many words we can scavenge per microsecond (usage
 // before / scavenge time). This is a conservative value observed running
 // Flutter on a Nexus 4. After the first scavenge, we instead use a value based
@@ -404,7 +813,6 @@
     : heap_(heap),
       max_semi_capacity_in_words_(max_semi_capacity_in_words),
       scavenging_(false),
-      delayed_weak_properties_(NULL),
       gc_time_micros_(0),
       collections_(0),
       scavenge_words_per_micro_(kConservativeInitialScavengeSpeed),
@@ -419,17 +827,7 @@
   const intptr_t initial_semi_capacity_in_words = Utils::Minimum(
       max_semi_capacity_in_words, FLAG_new_gen_semi_initial_size * MBInWords);
 
-  const char* name = Heap::RegionName(Heap::kNew);
-  to_ = SemiSpace::New(initial_semi_capacity_in_words, name);
-  if (to_ == NULL) {
-    OUT_OF_MEMORY();
-  }
-  // Setup local fields.
-  top_ = FirstObjectStart();
-  resolved_top_ = top_;
-  end_ = to_->end();
-
-  survivor_end_ = FirstObjectStart();
+  to_ = new SemiSpace(initial_semi_capacity_in_words);
   idle_scavenge_threshold_in_words_ = initial_semi_capacity_in_words;
 
   UpdateMaxHeapCapacity();
@@ -438,7 +836,7 @@
 
 Scavenger::~Scavenger() {
   ASSERT(!scavenging_);
-  to_->Delete();
+  delete to_;
 }
 
 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const {
@@ -460,11 +858,11 @@
       : ObjectPointerVisitor(IsolateGroup::Current()),
         in_store_buffer_(in_store_buffer) {}
 
-  void VisitPointers(RawObject** from, RawObject** to) {
-    for (RawObject** ptr = from; ptr <= to; ptr++) {
-      RawObject* raw_obj = *ptr;
-      RELEASE_ASSERT(!raw_obj->IsCardRemembered());
-      RELEASE_ASSERT(raw_obj->IsRemembered());
+  void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
+    for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
+      ObjectPtr raw_obj = *ptr;
+      RELEASE_ASSERT(!raw_obj->ptr()->IsCardRemembered());
+      RELEASE_ASSERT(raw_obj->ptr()->IsRemembered());
       RELEASE_ASSERT(raw_obj->IsOldObject());
       in_store_buffer_->Add(raw_obj);
     }
@@ -483,36 +881,37 @@
         in_store_buffer_(in_store_buffer),
         to_(to) {}
 
-  void VisitObject(RawObject* raw_obj) {
+  void VisitObject(ObjectPtr raw_obj) {
     if (raw_obj->IsPseudoObject()) return;
     RELEASE_ASSERT(raw_obj->IsOldObject());
 
-    if (raw_obj->IsCardRemembered()) {
-      RELEASE_ASSERT(!raw_obj->IsRemembered());
+    if (raw_obj->ptr()->IsCardRemembered()) {
+      RELEASE_ASSERT(!raw_obj->ptr()->IsRemembered());
       // TODO(rmacnak): Verify card tables.
       return;
     }
 
-    RELEASE_ASSERT(raw_obj->IsRemembered() ==
+    RELEASE_ASSERT(raw_obj->ptr()->IsRemembered() ==
                    in_store_buffer_->Contains(raw_obj));
 
     visiting_ = raw_obj;
-    is_remembered_ = raw_obj->IsRemembered();
-    raw_obj->VisitPointers(this);
+    is_remembered_ = raw_obj->ptr()->IsRemembered();
+    raw_obj->ptr()->VisitPointers(this);
   }
 
-  void VisitPointers(RawObject** from, RawObject** to) {
-    for (RawObject** ptr = from; ptr <= to; ptr++) {
-      RawObject* raw_obj = *ptr;
+  void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
+    for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
+      ObjectPtr raw_obj = *ptr;
       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
         if (!is_remembered_) {
           FATAL3(
-              "Old object %p references new object %p, 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",
-              visiting_, raw_obj, ptr);
+              "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(RawObject::ToAddr(raw_obj)));
+        RELEASE_ASSERT(to_->Contains(ObjectLayout::ToAddr(raw_obj)));
       }
     }
   }
@@ -520,7 +919,7 @@
  private:
   const ObjectSet* const in_store_buffer_;
   const SemiSpace* const to_;
-  RawObject* visiting_;
+  ObjectPtr visiting_;
   bool is_remembered_;
 };
 
@@ -543,8 +942,10 @@
   }
 }
 
-SemiSpace* Scavenger::Prologue(IsolateGroup* isolate_group) {
-  isolate_group->ReleaseStoreBuffers();
+SemiSpace* Scavenger::Prologue() {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "Prologue");
+
+  heap_->isolate_group()->ReleaseStoreBuffers();
 
   if (FLAG_verify_store_buffer) {
     OS::PrintErr("Verifying remembered set before Scavenge...");
@@ -553,37 +954,36 @@
     OS::PrintErr(" done.\n");
   }
 
+  // Need to stash the old remembered set before any worker begins adding to the
+  // new remembered set.
+  blocks_ = heap_->isolate_group()->store_buffer()->TakeBlocks();
+
   // Flip the two semi-spaces so that to_ is always the space for allocating
   // objects.
   SemiSpace* from = to_;
 
-  const char* name = Heap::RegionName(Heap::kNew);
-  to_ = SemiSpace::New(NewSizeInWords(from->size_in_words()), name);
-  if (to_ == NULL) {
-    // TODO(koda): We could try to recover (collect old space, wait for another
-    // isolate to finish scavenge, etc.).
-    OUT_OF_MEMORY();
-  }
+  to_ = new SemiSpace(NewSizeInWords(from->max_capacity_in_words()));
   UpdateMaxHeapCapacity();
-  top_ = FirstObjectStart();
-  resolved_top_ = top_;
-  end_ = to_->end();
 
   return from;
 }
 
-void Scavenger::Epilogue(IsolateGroup* isolate_group, SemiSpace* from) {
+void Scavenger::Epilogue(SemiSpace* from) {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "Epilogue");
+
   // All objects in the to space have been copied from the from space at this
   // moment.
 
   // Ensure the mutator thread will fail the next allocation. This will force
   // mutator to allocate a new TLAB
-  isolate_group->ForEachIsolate(
+#if defined(DEBUG)
+  heap_->isolate_group()->ForEachIsolate(
       [&](Isolate* isolate) {
         Thread* mutator_thread = isolate->mutator_thread();
-        ASSERT((mutator_thread == NULL) || (!mutator_thread->HasActiveTLAB()));
+        ASSERT(mutator_thread == nullptr || mutator_thread->top() == 0);
       },
       /*at_safepoint=*/true);
+#endif  // DEBUG
 
   double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
   if (stats_history_.Size() >= 2) {
@@ -591,14 +991,8 @@
     avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction();
     avg_frac /= 1.0 + 0.5;  // Normalize.
   }
-  if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) {
-    // Remember the limit to which objects have been copied.
-    survivor_end_ = top_;
-  } else {
-    // Move survivor end to the end of the to_ space, making all surviving
-    // objects candidates for promotion next time.
-    survivor_end_ = end_;
-  }
+
+  early_tenure_ = avg_frac >= (FLAG_early_tenuring_threshold / 100.0);
 
   // Update estimate of scavenger speed. This statistic assumes survivorship
   // rates don't change much.
@@ -646,7 +1040,7 @@
     // a program to hit a store buffer overflow a bit sooner than it might
     // otherwise, since overflow is measured in blocks. Store buffer overflows
     // are very rare.
-    isolate_group->ReleaseStoreBuffers();
+    heap_->isolate_group()->ReleaseStoreBuffers();
 
     OS::PrintErr("Verifying remembered set after Scavenge...");
     heap_->WaitForSweeperTasksAtSafepoint(Thread::Current());
@@ -654,7 +1048,7 @@
     OS::PrintErr(" done.\n");
   }
 
-  from->Delete();
+  delete from;
   UpdateMaxHeapUsage();
   if (heap_ != NULL) {
     heap_->UpdateGlobalMaxUsed();
@@ -677,11 +1071,21 @@
   return estimated_scavenge_completion <= deadline;
 }
 
-void Scavenger::IterateStoreBuffers(IsolateGroup* isolate_group,
-                                    ScavengerVisitor* visitor) {
+void Scavenger::IterateIsolateRoots(ObjectPointerVisitor* visitor) {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "IterateIsolateRoots");
+  heap_->isolate_group()->VisitObjectPointers(
+      visitor, ValidationPolicy::kDontValidateFrames);
+}
+
+template <bool parallel>
+void Scavenger::IterateStoreBuffers(ScavengerVisitorBase<parallel>* visitor) {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "IterateStoreBuffers");
+
   // Iterating through the store buffers.
   // Grab the deduplication sets out of the isolate's consolidated store buffer.
-  StoreBufferBlock* pending = isolate_group->store_buffer()->Blocks();
+  StoreBuffer* store_buffer = heap_->isolate_group()->store_buffer();
+  StoreBufferBlock* pending = blocks_;
+  blocks_ = nullptr;
   intptr_t total_count = 0;
   while (pending != NULL) {
     StoreBufferBlock* next = pending->next();
@@ -690,161 +1094,177 @@
     intptr_t count = pending->Count();
     total_count += count;
     while (!pending->IsEmpty()) {
-      RawObject* raw_object = pending->Pop();
+      ObjectPtr raw_object = pending->Pop();
       ASSERT(!raw_object->IsForwardingCorpse());
-      ASSERT(raw_object->IsRemembered());
-      raw_object->ClearRememberedBit();
+      ASSERT(raw_object->ptr()->IsRemembered());
+      raw_object->ptr()->ClearRememberedBit();
       visitor->VisitingOldObject(raw_object);
-      raw_object->VisitPointersNonvirtual(visitor);
+      // Note that this treats old-space WeakProperties as strong. A dead key
+      // won't be reclaimed until after the key is promoted.
+      raw_object->ptr()->VisitPointersNonvirtual(visitor);
     }
     pending->Reset();
     // Return the emptied block for recycling (no need to check threshold).
-    isolate_group->store_buffer()->PushBlock(pending,
-                                             StoreBuffer::kIgnoreThreshold);
+    store_buffer->PushBlock(pending, StoreBuffer::kIgnoreThreshold);
     pending = next;
   }
-
+  // Done iterating through old objects remembered in the store buffers.
   visitor->VisitingOldObject(NULL);
-  heap_->old_space()->VisitRememberedCards(visitor);
 
   heap_->RecordData(kStoreBufferEntries, total_count);
   heap_->RecordData(kDataUnused1, 0);
   heap_->RecordData(kDataUnused2, 0);
-  // Done iterating through old objects remembered in the store buffers.
+}
+
+template <bool parallel>
+void Scavenger::IterateRememberedCards(
+    ScavengerVisitorBase<parallel>* visitor) {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "IterateRememberedCards");
+  heap_->old_space()->VisitRememberedCards(visitor);
   visitor->VisitingOldObject(NULL);
 }
 
-void Scavenger::IterateObjectIdTable(IsolateGroup* isolate_group,
-                                     ScavengerVisitor* visitor) {
+void Scavenger::IterateObjectIdTable(ObjectPointerVisitor* visitor) {
 #ifndef PRODUCT
-  isolate_group->ForEachIsolate(
-      [&](Isolate* isolate) {
-        isolate->object_id_ring()->VisitPointers(visitor);
-      },
-      /*at_safepoint=*/true);
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "IterateObjectIdTable");
+  heap_->isolate_group()->VisitObjectIdRingPointers(visitor);
 #endif  // !PRODUCT
 }
 
-void Scavenger::IterateRoots(IsolateGroup* isolate_group,
-                             ScavengerVisitor* visitor) {
-#ifdef SUPPORT_TIMELINE
-  Thread* thread = Thread::Current();
-#endif
-  int64_t start = OS::GetCurrentMonotonicMicros();
-  {
-    TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessRoots");
-    isolate_group->VisitObjectPointers(visitor,
-                                       ValidationPolicy::kDontValidateFrames);
+enum RootSlices {
+  kIsolate = 0,
+  kObjectIdRing,
+  kCards,
+  kStoreBuffer,
+  kNumRootSlices,
+};
+
+template <bool parallel>
+void Scavenger::IterateRoots(ScavengerVisitorBase<parallel>* visitor) {
+  for (;;) {
+    intptr_t slice = root_slices_started_.fetch_add(1);
+    if (slice >= kNumRootSlices) {
+      return;  // No more slices.
+    }
+
+    switch (slice) {
+      case kIsolate:
+        IterateIsolateRoots(visitor);
+        break;
+      case kObjectIdRing:
+        IterateObjectIdTable(visitor);
+        break;
+      case kCards:
+        IterateRememberedCards(visitor);
+        break;
+      case kStoreBuffer:
+        IterateStoreBuffers(visitor);
+        break;
+      default:
+        UNREACHABLE();
+    }
   }
-  int64_t middle = OS::GetCurrentMonotonicMicros();
-  {
-    TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessRememberedSet");
-    IterateStoreBuffers(isolate_group, visitor);
-  }
-  IterateObjectIdTable(isolate_group, visitor);
-  int64_t end = OS::GetCurrentMonotonicMicros();
-  heap_->RecordData(kToKBAfterStoreBuffer, RoundWordsToKB(UsedInWords()));
-  heap_->RecordTime(kVisitIsolateRoots, middle - start);
-  heap_->RecordTime(kIterateStoreBuffers, end - middle);
-  heap_->RecordTime(kDummyScavengeTime, 0);
 }
 
-bool Scavenger::IsUnreachable(RawObject** p) {
-  RawObject* raw_obj = *p;
+bool Scavenger::IsUnreachable(ObjectPtr* p) {
+  ObjectPtr raw_obj = *p;
   if (!raw_obj->IsHeapObject()) {
     return false;
   }
   if (!raw_obj->IsNewObject()) {
     return false;
   }
-  uword raw_addr = RawObject::ToAddr(raw_obj);
+  uword raw_addr = ObjectLayout::ToAddr(raw_obj);
   if (to_->Contains(raw_addr)) {
     return false;
   }
   uword header = *reinterpret_cast<uword*>(raw_addr);
   if (IsForwarding(header)) {
     uword new_addr = ForwardedAddr(header);
-    *p = RawObject::FromAddr(new_addr);
+    *p = ObjectLayout::FromAddr(new_addr);
     return false;
   }
   return true;
 }
 
-void Scavenger::IterateWeakRoots(IsolateGroup* isolate_group,
-                                 HandleVisitor* visitor) {
-  isolate_group->VisitWeakPersistentHandles(visitor);
+void Scavenger::MournWeakHandles() {
+  Thread* thread = Thread::Current();
+  TIMELINE_FUNCTION_GC_DURATION(thread, "MournWeakHandles");
+  ScavengerWeakVisitor weak_visitor(thread, this);
+  heap_->isolate_group()->VisitWeakPersistentHandles(&weak_visitor);
 }
 
-void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
-  Thread* thread = Thread::Current();
+template <bool parallel>
+void ScavengerVisitorBase<parallel>::ProcessToSpace() {
+  while (scan_ != nullptr) {
+    uword resolved_top = scan_->resolved_top_;
+    while (resolved_top < scan_->top_) {
+      ObjectPtr raw_obj = ObjectLayout::FromAddr(resolved_top);
+      resolved_top += ProcessCopied(raw_obj);
+    }
+    scan_->resolved_top_ = resolved_top;
 
-  // Iterate until all work has been drained.
-  while ((resolved_top_ < top_) || PromotedStackHasMore()) {
-    while (resolved_top_ < top_) {
-      RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
-      intptr_t class_id = raw_obj->GetClassId();
-      intptr_t size;
-      if (class_id != kWeakPropertyCid) {
-        size = raw_obj->VisitPointersNonvirtual(visitor);
-      } else {
-        RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
-        size = ProcessWeakProperty(raw_weak, visitor);
-      }
-      resolved_top_ += size;
+    NewPage* next = scan_->next();
+    if (next == nullptr) {
+      // Don't update scan_. More objects may yet be copied to this TLAB.
+      return;
     }
-    {
-      // Visit all the promoted objects and update/scavenge their internal
-      // pointers. Potentially this adds more objects to the to space.
-      while (PromotedStackHasMore()) {
-        RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
-        // Resolve or copy all objects referred to by the current object. This
-        // can potentially push more objects on this stack as well as add more
-        // objects to be resolved in the to space.
-        ASSERT(!raw_object->IsRemembered());
-        visitor->VisitingOldObject(raw_object);
-        raw_object->VisitPointersNonvirtual(visitor);
-        if (raw_object->IsMarked()) {
-          // Complete our promise from ScavengePointer. Note that marker cannot
-          // visit this object until it pops a block from the mark stack, which
-          // involves a memory fence from the mutex, so even on architectures
-          // with a relaxed memory model, the marker will see the fully
-          // forwarded contents of this object.
-          thread->MarkingStackAddObject(raw_object);
-        }
-      }
-      visitor->VisitingOldObject(NULL);
+    scan_ = next;
+  }
+}
+
+template <bool parallel>
+void ScavengerVisitorBase<parallel>::ProcessPromotedList() {
+  ObjectPtr raw_object;
+  while ((raw_object = promoted_list_.Pop()) != nullptr) {
+    // Resolve or copy all objects referred to by the current object. This
+    // can potentially push more objects on this stack as well as add more
+    // objects to be resolved in the to space.
+    ASSERT(!raw_object->ptr()->IsRemembered());
+    VisitingOldObject(raw_object);
+    raw_object->ptr()->VisitPointersNonvirtual(this);
+    if (raw_object->ptr()->IsMarked()) {
+      // Complete our promise from ScavengePointer. Note that marker cannot
+      // visit this object until it pops a block from the mark stack, which
+      // involves a memory fence from the mutex, so even on architectures
+      // with a relaxed memory model, the marker will see the fully
+      // forwarded contents of this object.
+      thread_->MarkingStackAddObject(raw_object);
     }
-    {
-      // Finished this round of scavenging. Process the pending weak properties
-      // for which the keys have become reachable. Potentially this adds more
-      // objects to the to space.
-      RawWeakProperty* cur_weak = delayed_weak_properties_;
-      delayed_weak_properties_ = NULL;
-      while (cur_weak != NULL) {
-        uword next_weak = cur_weak->ptr()->next_;
-        // Promoted weak properties are not enqueued. So we can guarantee that
-        // we do not need to think about store barriers here.
-        ASSERT(cur_weak->IsNewObject());
-        RawObject* raw_key = cur_weak->ptr()->key_;
-        ASSERT(raw_key->IsHeapObject());
-        // Key still points into from space even if the object has been
-        // promoted to old space by now. The key will be updated accordingly
-        // below when VisitPointers is run.
-        ASSERT(raw_key->IsNewObject());
-        uword raw_addr = RawObject::ToAddr(raw_key);
-        ASSERT(visitor->from_->Contains(raw_addr));
-        uword header = *reinterpret_cast<uword*>(raw_addr);
-        // Reset the next pointer in the weak property.
-        cur_weak->ptr()->next_ = 0;
-        if (IsForwarding(header)) {
-          cur_weak->VisitPointersNonvirtual(visitor);
-        } else {
-          EnqueueWeakProperty(cur_weak);
-        }
-        // Advance to next weak property in the queue.
-        cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
-      }
+  }
+  VisitingOldObject(NULL);
+}
+
+template <bool parallel>
+void ScavengerVisitorBase<parallel>::ProcessWeakProperties() {
+  // Finished this round of scavenging. Process the pending weak properties
+  // for which the keys have become reachable. Potentially this adds more
+  // objects to the to space.
+  WeakPropertyPtr cur_weak = delayed_weak_properties_;
+  delayed_weak_properties_ = nullptr;
+  while (cur_weak != nullptr) {
+    uword next_weak = cur_weak->ptr()->next_;
+    // Promoted weak properties are not enqueued. So we can guarantee that
+    // we do not need to think about store barriers here.
+    ASSERT(cur_weak->IsNewObject());
+    ObjectPtr raw_key = cur_weak->ptr()->key_;
+    ASSERT(raw_key->IsHeapObject());
+    // Key still points into from space even if the object has been
+    // promoted to old space by now. The key will be updated accordingly
+    // below when VisitPointers is run.
+    ASSERT(raw_key->IsNewObject());
+    uword raw_addr = ObjectLayout::ToAddr(raw_key);
+    ASSERT(from_->Contains(raw_addr));
+    uword header = *reinterpret_cast<uword*>(raw_addr);
+    // Reset the next pointer in the weak property.
+    cur_weak->ptr()->next_ = 0;
+    if (IsForwarding(header)) {
+      cur_weak->ptr()->VisitPointersNonvirtual(this);
+    } else {
+      EnqueueWeakProperty(cur_weak);
     }
+    // Advance to next weak property in the queue.
+    cur_weak = static_cast<WeakPropertyPtr>(next_weak);
   }
 }
 
@@ -858,8 +1278,8 @@
   ASSERT(heap_ != NULL);
   auto isolate_group = heap_->isolate_group();
   ASSERT(isolate_group != NULL);
-  isolate_group->GetHeapNewCapacityMaxMetric()->SetValue(to_->size_in_words() *
-                                                         kWordSize);
+  isolate_group->GetHeapNewCapacityMaxMetric()->SetValue(
+      to_->max_capacity_in_words() * kWordSize);
 #endif  // !defined(PRODUCT)
 }
 
@@ -877,51 +1297,59 @@
 #endif  // !defined(PRODUCT)
 }
 
-void Scavenger::EnqueueWeakProperty(RawWeakProperty* raw_weak) {
+template <bool parallel>
+void ScavengerVisitorBase<parallel>::EnqueueWeakProperty(
+    WeakPropertyPtr raw_weak) {
   ASSERT(raw_weak->IsHeapObject());
   ASSERT(raw_weak->IsNewObject());
   ASSERT(raw_weak->IsWeakProperty());
 #if defined(DEBUG)
-  uword raw_addr = RawObject::ToAddr(raw_weak);
+  uword raw_addr = ObjectLayout::ToAddr(raw_weak);
   uword header = *reinterpret_cast<uword*>(raw_addr);
   ASSERT(!IsForwarding(header));
 #endif  // defined(DEBUG)
   ASSERT(raw_weak->ptr()->next_ == 0);
-  raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+  raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
   delayed_weak_properties_ = raw_weak;
 }
 
-uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
-                                     ScavengerVisitor* visitor) {
-  // The fate of the weak property is determined by its key.
-  RawObject* raw_key = raw_weak->ptr()->key_;
-  if (raw_key->IsHeapObject() && raw_key->IsNewObject()) {
-    uword raw_addr = RawObject::ToAddr(raw_key);
-    uword header = *reinterpret_cast<uword*>(raw_addr);
-    if (!IsForwarding(header)) {
-      // Key is white.  Enqueue the weak property.
-      EnqueueWeakProperty(raw_weak);
-      return raw_weak->HeapSize();
+template <bool parallel>
+intptr_t ScavengerVisitorBase<parallel>::ProcessCopied(ObjectPtr raw_obj) {
+  intptr_t class_id = raw_obj->GetClassId();
+  if (UNLIKELY(class_id == kWeakPropertyCid)) {
+    WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
+    // The fate of the weak property is determined by its key.
+    ObjectPtr raw_key = raw_weak->ptr()->key_;
+    if (raw_key->IsHeapObject() && raw_key->IsNewObject()) {
+      uword raw_addr = ObjectLayout::ToAddr(raw_key);
+      uword header = *reinterpret_cast<uword*>(raw_addr);
+      if (!IsForwarding(header)) {
+        // Key is white.  Enqueue the weak property.
+        EnqueueWeakProperty(raw_weak);
+        return raw_weak->ptr()->HeapSize();
+      }
     }
+    // Key is gray or black.  Make the weak property black.
   }
-  // Key is gray or black.  Make the weak property black.
-  return raw_weak->VisitPointersNonvirtual(visitor);
+  return raw_obj->ptr()->VisitPointersNonvirtual(this);
 }
 
-void Scavenger::ProcessWeakReferences() {
+void Scavenger::MournWeakTables() {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "MournWeakTables");
+
   auto rehash_weak_table = [](WeakTable* table, WeakTable* replacement_new,
                               WeakTable* replacement_old) {
     intptr_t size = table->size();
     for (intptr_t i = 0; i < size; i++) {
       if (table->IsValidEntryAtExclusive(i)) {
-        RawObject* raw_obj = table->ObjectAtExclusive(i);
+        ObjectPtr raw_obj = table->ObjectAtExclusive(i);
         ASSERT(raw_obj->IsHeapObject());
-        uword raw_addr = RawObject::ToAddr(raw_obj);
+        uword raw_addr = ObjectLayout::ToAddr(raw_obj);
         uword header = *reinterpret_cast<uword*>(raw_addr);
         if (IsForwarding(header)) {
           // The object has survived.  Preserve its record.
           uword new_addr = ForwardedAddr(header);
-          raw_obj = RawObject::FromAddr(new_addr);
+          raw_obj = ObjectLayout::FromAddr(new_addr);
           auto replacement =
               raw_obj->IsNewObject() ? replacement_new : replacement_old;
           replacement->SetValueExclusive(raw_obj, table->ValueAtExclusive(i));
@@ -958,198 +1386,163 @@
         }
       },
       /*at_safepoint=*/true);
+}
 
+template <bool parallel>
+void ScavengerVisitorBase<parallel>::MournWeakProperties() {
   // The queued weak properties at this point do not refer to reachable keys,
   // so we clear their key and value fields.
-  {
-    RawWeakProperty* cur_weak = delayed_weak_properties_;
-    delayed_weak_properties_ = NULL;
-    while (cur_weak != NULL) {
-      uword next_weak = cur_weak->ptr()->next_;
-      // Reset the next pointer in the weak property.
-      cur_weak->ptr()->next_ = 0;
+  WeakPropertyPtr cur_weak = delayed_weak_properties_;
+  delayed_weak_properties_ = nullptr;
+  while (cur_weak != nullptr) {
+    uword next_weak = cur_weak->ptr()->next_;
+    // Reset the next pointer in the weak property.
+    cur_weak->ptr()->next_ = 0;
 
 #if defined(DEBUG)
-      RawObject* raw_key = cur_weak->ptr()->key_;
-      uword raw_addr = RawObject::ToAddr(raw_key);
-      uword header = *reinterpret_cast<uword*>(raw_addr);
-      ASSERT(!IsForwarding(header));
-      ASSERT(raw_key->IsHeapObject());
-      ASSERT(raw_key->IsNewObject());  // Key still points into from space.
-#endif                                 // defined(DEBUG)
+    ObjectPtr raw_key = cur_weak->ptr()->key_;
+    uword raw_addr = ObjectLayout::ToAddr(raw_key);
+    uword header = *reinterpret_cast<uword*>(raw_addr);
+    ASSERT(!IsForwarding(header));
+    ASSERT(raw_key->IsHeapObject());
+    ASSERT(raw_key->IsNewObject());  // Key still points into from space.
+#endif                               // defined(DEBUG)
 
-      WeakProperty::Clear(cur_weak);
+    WeakProperty::Clear(cur_weak);
 
-      // Advance to next weak property in the queue.
-      cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
-    }
+    // Advance to next weak property in the queue.
+    cur_weak = static_cast<WeakPropertyPtr>(next_weak);
   }
 }
 
-void Scavenger::MakeNewSpaceIterable() const {
-  ASSERT(Thread::Current()->IsAtSafepoint() ||
-         (Thread::Current()->task_kind() == Thread::kMarkerTask) ||
-         (Thread::Current()->task_kind() == Thread::kCompactorTask));
-  auto isolate_group = heap_->isolate_group();
-  MonitorLocker ml(isolate_group->threads_lock(), false);
-  Thread* current = heap_->isolate_group()->thread_registry()->active_list();
-  while (current != NULL) {
-    if (current->HasActiveTLAB()) {
-      heap_->new_space()->MakeTLABIterable(current);
-    }
-    current = current->next();
-  }
-  isolate_group->ForEachIsolate(
-      [&](Isolate* isolate) {
-        Thread* mutator_thread = isolate->mutator_thread();
-        if (mutator_thread != NULL) {
-          heap_->new_space()->MakeTLABIterable(mutator_thread);
-        }
-      },
-      /*at_safepoint=*/true);
-}
-
-void Scavenger::AbandonTLABsLocked(IsolateGroup* isolate_group) {
-  ASSERT(Thread::Current()->IsAtSafepoint());
-  MonitorLocker ml(isolate_group->threads_lock(), false);
-  Thread* current = isolate_group->thread_registry()->active_list();
-  while (current != NULL) {
-    AbandonRemainingTLABLocked(current);
-    current = current->next();
-  }
-  isolate_group->ForEachIsolate(
-      [&](Isolate* isolate) {
-        Thread* mutator_thread = isolate->mutator_thread();
-        if (mutator_thread != NULL) {
-          AbandonRemainingTLABLocked(mutator_thread);
-        }
-      },
-      /*at_safepoint=*/true);
-}
-
 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
   ASSERT(Thread::Current()->IsAtSafepoint() ||
          (Thread::Current()->task_kind() == Thread::kMarkerTask) ||
          (Thread::Current()->task_kind() == Thread::kCompactorTask));
-  MakeNewSpaceIterable();
-  uword cur = FirstObjectStart();
-  while (cur < top_) {
-    RawObject* raw_obj = RawObject::FromAddr(cur);
-    cur += raw_obj->VisitPointers(visitor);
+  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+    page->VisitObjectPointers(visitor);
   }
 }
 
 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
   ASSERT(Thread::Current()->IsAtSafepoint() ||
          (Thread::Current()->task_kind() == Thread::kMarkerTask));
-  MakeNewSpaceIterable();
-  uword cur = FirstObjectStart();
-  while (cur < top_) {
-    RawObject* raw_obj = RawObject::FromAddr(cur);
-    visitor->VisitObject(raw_obj);
-    cur += raw_obj->HeapSize();
+  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+    page->VisitObjects(visitor);
   }
 }
 
 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
-  set->AddRegion(to_->start(), to_->end());
+  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+    set->AddRegion(page->start(), page->end());
+  }
 }
 
-RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const {
+ObjectPtr Scavenger::FindObject(FindObjectVisitor* visitor) {
   ASSERT(!scavenging_);
-  MakeNewSpaceIterable();
-  uword cur = FirstObjectStart();
-  if (visitor->VisitRange(cur, top_)) {
-    while (cur < top_) {
-      RawObject* raw_obj = RawObject::FromAddr(cur);
-      uword next = cur + raw_obj->HeapSize();
-      if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
+  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+    uword cur = page->object_start();
+    if (!visitor->VisitRange(cur, page->object_end())) continue;
+    while (cur < page->object_end()) {
+      ObjectPtr raw_obj = ObjectLayout::FromAddr(cur);
+      uword next = cur + raw_obj->ptr()->HeapSize();
+      if (visitor->VisitRange(cur, next) &&
+          raw_obj->ptr()->FindObject(visitor)) {
         return raw_obj;  // Found object, return it.
       }
       cur = next;
     }
-    ASSERT(cur == top_);
+    ASSERT(cur == page->object_end());
   }
   return Object::null();
 }
 
-void Scavenger::TryAllocateNewTLAB(Thread* thread) {
+void Scavenger::TryAllocateNewTLAB(Thread* thread, intptr_t min_size) {
   ASSERT(heap_ != Dart::vm_isolate()->heap());
   ASSERT(!scavenging_);
+
+  AbandonRemainingTLAB(thread);
+
   MutexLocker ml(&space_lock_);
-  AbandonRemainingTLABLocked(thread);
-  uword result = top_;
-  intptr_t remaining = end_ - top_;
-  intptr_t size = kTLABSize;
-  if (remaining < size) {
-    // Grab whatever is remaining
-    size = Utils::RoundDown(remaining, kObjectAlignment);
+  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+    if (page->owner() != nullptr) continue;
+    intptr_t available = page->end() - page->object_end();
+    if (available >= min_size) {
+      page->Acquire(thread);
+      return;
+    }
   }
-  ASSERT(Utils::IsAligned(size, kObjectAlignment));
-  if (size == 0) {
+
+  NewPage* page = to_->TryAllocatePageLocked(true);
+  if (page == nullptr) {
     return;
   }
-  ASSERT(to_->Contains(result));
-  ASSERT((result & kObjectAlignmentMask) == kNewObjectAlignmentOffset);
-  top_ += size;
-  ASSERT(to_->Contains(top_) || (top_ == to_->end()));
-  ASSERT(result < top_);
-  thread->set_top(result);
-  thread->set_end(top_);
+  page->Acquire(thread);
 }
 
-void Scavenger::MakeTLABIterable(Thread* thread) {
-  uword start = thread->top();
-  uword end = thread->end();
-  ASSERT(end >= start);
-  intptr_t size = end - start;
-  ASSERT(Utils::IsAligned(size, kObjectAlignment));
-  if (size >= kObjectAlignment) {
-    // ForwardingCorpse(forwarding to default null) will work as filler.
-    ForwardingCorpse::AsForwarder(start, size);
-    ASSERT(RawObject::FromAddr(start)->HeapSize() == size);
+void Scavenger::AbandonRemainingTLABForDebugging(Thread* thread) {
+  // Allocate any remaining space so the TLAB won't be reused. Write a filler
+  // object so it remains iterable.
+  uword top = thread->top();
+  intptr_t size = thread->end() - thread->top();
+  if (size > 0) {
+    thread->set_top(top + size);
+    ForwardingCorpse::AsForwarder(top, size);
   }
+
+  AbandonRemainingTLAB(thread);
 }
 
 void Scavenger::AbandonRemainingTLAB(Thread* thread) {
-  MakeTLABIterable(thread);
-  AddAbandonedInBytes(thread->end() - thread->top());
-  thread->set_top(0);
-  thread->set_end(0);
+  if (thread->top() == 0) return;
+  NewPage* page = NewPage::Of(thread->top() - 1);
+  {
+    MutexLocker ml(&space_lock_);
+    page->Release(thread);
+  }
+  ASSERT(thread->top() == 0);
 }
 
-void Scavenger::AbandonRemainingTLABLocked(Thread* thread) {
-  MakeTLABIterable(thread);
-  AddAbandonedInBytesLocked(thread->end() - thread->top());
-  thread->set_top(0);
-  thread->set_end(0);
+template <bool parallel>
+uword ScavengerVisitorBase<parallel>::TryAllocateCopySlow(intptr_t size) {
+  NewPage* page;
+  {
+    MutexLocker ml(&scavenger_->space_lock_);
+    page = scavenger_->to_->TryAllocatePageLocked(false);
+  }
+  if (page == nullptr) {
+    return 0;
+  }
+
+  if (head_ == nullptr) {
+    head_ = scan_ = page;
+  } else {
+    ASSERT(scan_ != nullptr);
+    tail_->set_next(page);
+  }
+  tail_ = page;
+
+  return tail_->TryAllocateGC(size);
 }
 
 void Scavenger::Scavenge() {
-  auto isolate_group = heap_->isolate_group();
+  int64_t start = OS::GetCurrentMonotonicMicros();
+
   // Ensure that all threads for this isolate are at a safepoint (either stopped
   // or in native code). If two threads are racing at this point, the loser
   // will continue with its scavenge after waiting for the winner to complete.
   // TODO(koda): Consider moving SafepointThreads into allocation failure/retry
   // logic to avoid needless collections.
-
-  int64_t start = OS::GetCurrentMonotonicMicros();
-
   Thread* thread = Thread::Current();
   SafepointOperationScope safepoint_scope(thread);
 
+  int64_t safe_point = OS::GetCurrentMonotonicMicros();
+  heap_->RecordTime(kSafePoint, safe_point - start);
+
   // Scavenging is not reentrant. Make sure that is the case.
   ASSERT(!scavenging_);
   scavenging_ = true;
 
-  failed_to_promote_ = false;
-
-  PageSpace* page_space = heap_->old_space();
-  NoSafepointScope no_safepoints;
-
-  int64_t safe_point = OS::GetCurrentMonotonicMicros();
-  heap_->RecordTime(kSafePoint, safe_point - start);
-
   if (FLAG_verify_before_gc) {
     OS::PrintErr("Verifying before Scavenge...");
     heap_->WaitForSweeperTasksAtSafepoint(thread);
@@ -1158,48 +1551,38 @@
   }
 
   // Prepare for a scavenge.
-  AbandonTLABsLocked(isolate_group);
-  intptr_t abandoned_bytes = GetAndResetAbandonedInBytes();
-
+  failed_to_promote_ = false;
+  root_slices_started_ = 0;
+  intptr_t abandoned_bytes = 0;  // TODO(rmacnak): Count fragmentation?
   SpaceUsage usage_before = GetCurrentUsage();
-  intptr_t promo_candidate_words =
-      (survivor_end_ - FirstObjectStart()) / kWordSize;
-  SemiSpace* from = Prologue(isolate_group);
-  // The API prologue/epilogue may create/destroy zones, so we must not
-  // depend on zone allocations surviving beyond the epilogue callback.
-  {
-    StackZone zone(thread);
-    // Setup the visitor and run the scavenge.
-    ScavengerVisitor visitor(isolate_group, this, from);
-    page_space->AcquireDataLock();
-    IterateRoots(isolate_group, &visitor);
-    int64_t iterate_roots = OS::GetCurrentMonotonicMicros();
-    {
-      TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessToSpace");
-      ProcessToSpace(&visitor);
+  intptr_t promo_candidate_words = 0;
+  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+    page->Release();
+    if (early_tenure_) {
+      page->EarlyTenure();
     }
-    int64_t process_to_space = OS::GetCurrentMonotonicMicros();
-    {
-      TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessWeakHandles");
-      ScavengerWeakVisitor weak_visitor(thread, this);
-      IterateWeakRoots(isolate_group, &weak_visitor);
-    }
-    ProcessWeakReferences();
-    page_space->ReleaseDataLock();
-
-    // Restore write-barrier assumptions.
-    isolate_group->RememberLiveTemporaries();
-
-    // Scavenge finished. Run accounting.
-    int64_t end = OS::GetCurrentMonotonicMicros();
-    heap_->RecordTime(kProcessToSpace, process_to_space - iterate_roots);
-    heap_->RecordTime(kIterateWeaks, end - process_to_space);
-    stats_history_.Add(ScavengeStats(start, end, usage_before,
-                                     GetCurrentUsage(), promo_candidate_words,
-                                     visitor.bytes_promoted() >> kWordSizeLog2,
-                                     abandoned_bytes >> kWordSizeLog2));
+    promo_candidate_words += page->promo_candidate_words();
   }
-  Epilogue(isolate_group, from);
+  SemiSpace* from = Prologue();
+
+  intptr_t bytes_promoted;
+  if (FLAG_scavenger_tasks == 0) {
+    bytes_promoted = SerialScavenge(from);
+  } else {
+    bytes_promoted = ParallelScavenge(from);
+  }
+  MournWeakHandles();
+  MournWeakTables();
+
+  // Restore write-barrier assumptions.
+  heap_->isolate_group()->RememberLiveTemporaries();
+
+  // Scavenge finished. Run accounting.
+  int64_t end = OS::GetCurrentMonotonicMicros();
+  stats_history_.Add(ScavengeStats(
+      start, end, usage_before, GetCurrentUsage(), promo_candidate_words,
+      bytes_promoted >> kWordSizeLog2, abandoned_bytes >> kWordSizeLog2));
+  Epilogue(from);
 
   if (FLAG_verify_after_gc) {
     OS::PrintErr("Verifying after Scavenge...");
@@ -1213,6 +1596,59 @@
   scavenging_ = false;
 }
 
+intptr_t Scavenger::SerialScavenge(SemiSpace* from) {
+  FreeList* freelist = heap_->old_space()->DataFreeList(0);
+  SerialScavengerVisitor visitor(heap_->isolate_group(), this, from, freelist,
+                                 &promotion_stack_);
+  visitor.ProcessRoots();
+  {
+    TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessToSpace");
+    visitor.ProcessAll();
+  }
+  visitor.Finalize();
+
+  to_->AddList(visitor.head(), visitor.tail());
+  return visitor.bytes_promoted();
+}
+
+intptr_t Scavenger::ParallelScavenge(SemiSpace* from) {
+  intptr_t bytes_promoted = 0;
+  const intptr_t num_tasks = FLAG_scavenger_tasks;
+  ASSERT(num_tasks > 0);
+
+  ThreadBarrier barrier(num_tasks, heap_->barrier(), heap_->barrier_done());
+  RelaxedAtomic<uintptr_t> num_busy = num_tasks;
+
+  ParallelScavengerVisitor** visitors =
+      new ParallelScavengerVisitor*[num_tasks];
+  for (intptr_t i = 0; i < num_tasks; i++) {
+    FreeList* freelist = heap_->old_space()->DataFreeList(i);
+    visitors[i] = new ParallelScavengerVisitor(
+        heap_->isolate_group(), this, from, freelist, &promotion_stack_);
+    if (i < (num_tasks - 1)) {
+      // Begin scavenging on a helper thread.
+      bool result = Dart::thread_pool()->Run<ParallelScavengerTask>(
+          heap_->isolate_group(), &barrier, visitors[i], &num_busy);
+      ASSERT(result);
+    } else {
+      // Last worker is the main thread.
+      ParallelScavengerTask task(heap_->isolate_group(), &barrier, visitors[i],
+                                 &num_busy);
+      task.RunEnteredIsolateGroup();
+      barrier.Exit();
+    }
+  }
+
+  for (intptr_t i = 0; i < num_tasks; i++) {
+    to_->AddList(visitors[i]->head(), visitors[i]->tail());
+    bytes_promoted += visitors[i]->bytes_promoted();
+    delete visitors[i];
+  }
+
+  delete[] visitors;
+  return bytes_promoted;
+}
+
 void Scavenger::WriteProtect(bool read_only) {
   ASSERT(!scavenging_);
   to_->WriteProtect(read_only);
@@ -1266,7 +1702,7 @@
   SafepointOperationScope scope(Thread::Current());
 
   // Forces the next scavenge to promote all the objects in the new space.
-  survivor_end_ = top_;
+  early_tenure_ = true;
 
   Scavenge();
 
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 9dacdd3..56baac3 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -7,6 +7,7 @@
 
 #include "platform/assert.h"
 #include "platform/utils.h"
+
 #include "vm/dart.h"
 #include "vm/flags.h"
 #include "vm/globals.h"
@@ -23,46 +24,40 @@
 class Heap;
 class Isolate;
 class JSONObject;
+class NewPage;
 class ObjectSet;
-class ScavengerVisitor;
+template <bool parallel>
+class ScavengerVisitorBase;
 
-// Wrapper around VirtualMemory that adds caching and handles the empty case.
 class SemiSpace {
  public:
   static void Init();
   static void Cleanup();
 
-  // Get a space of the given size. Returns NULL on out of memory. If size is 0,
-  // returns an empty space: pointer(), start() and end() all return NULL.
-  // The name parameter may be NULL. If non-NULL it is ued to give the OS a name
-  // for the underlying virtual memory region.
-  static SemiSpace* New(intptr_t size_in_words, const char* name);
-
-  // Hand back an unused space.
-  void Delete();
-
-  void* pointer() const { return region_.pointer(); }
-  uword start() const { return region_.start(); }
-  uword end() const { return region_.end(); }
-  intptr_t size_in_words() const {
-    return static_cast<intptr_t>(region_.size()) >> kWordSizeLog2;
-  }
-  bool Contains(uword address) const { return region_.Contains(address); }
-
-  // Set write protection mode for this space. The space must not be protected
-  // when Delete is called.
-  // TODO(koda): Remember protection mode in VirtualMemory and assert this.
-  void WriteProtect(bool read_only);
-
- private:
-  explicit SemiSpace(VirtualMemory* reserved);
+  explicit SemiSpace(intptr_t max_capacity_in_words);
   ~SemiSpace();
 
-  VirtualMemory* reserved_;  // NULL for an empty space.
-  MemoryRegion region_;
+  NewPage* TryAllocatePageLocked(bool link);
 
-  static SemiSpace* cache_;
-  static Mutex* mutex_;
+  bool Contains(uword addr) const;
+  void WriteProtect(bool read_only);
+
+  intptr_t capacity_in_words() const { return capacity_in_words_; }
+  intptr_t max_capacity_in_words() const { return max_capacity_in_words_; }
+
+  NewPage* head() const { return head_; }
+
+  void AddList(NewPage* head, NewPage* tail);
+
+ private:
+  // Size of NewPages in this semi-space.
+  intptr_t capacity_in_words_ = 0;
+
+  // Size of NewPages before we trigger a scavenge.
+  intptr_t max_capacity_in_words_;
+
+  NewPage* head_ = nullptr;
+  NewPage* tail_ = nullptr;
 };
 
 // Statistics for a particular scavenge.
@@ -127,35 +122,18 @@
   // be part of the surviving objects.
   bool Contains(uword addr) const { return to_->Contains(addr); }
 
-  RawObject* FindObject(FindObjectVisitor* visitor) const;
+  ObjectPtr FindObject(FindObjectVisitor* visitor);
 
   uword TryAllocate(Thread* thread, intptr_t size) {
     uword addr = TryAllocateFromTLAB(thread, size);
     if (LIKELY(addr != 0)) {
       return addr;
     }
-    TryAllocateNewTLAB(thread);
+    TryAllocateNewTLAB(thread, size);
     return TryAllocateFromTLAB(thread, size);
   }
-  void MakeTLABIterable(Thread* thread);
   void AbandonRemainingTLAB(Thread* thread);
-
-  uword AllocateGC(intptr_t size) {
-    ASSERT(Utils::IsAligned(size, kObjectAlignment));
-    ASSERT(heap_ != Dart::vm_isolate()->heap());
-    ASSERT(scavenging_);
-    uword result = top_;
-    intptr_t remaining = end_ - top_;
-
-    // This allocation happens only in GC and only when copying objects to
-    // the new to_ space. It must succeed.
-    ASSERT(size <= remaining);
-    ASSERT(to_->Contains(result));
-    ASSERT((result & kObjectAlignmentMask) == kNewObjectAlignmentOffset);
-    top_ += size;
-    ASSERT((to_->Contains(top_)) || (top_ == to_->end()));
-    return result;
-  }
+  void AbandonRemainingTLABForDebugging(Thread* thread);
 
   // Collect the garbage in this scavenger.
   void Scavenge();
@@ -163,32 +141,11 @@
   // Promote all live objects.
   void Evacuate();
 
-  uword top() { return top_; }
-  uword end() { return end_; }
-
-  void set_top(uword value) { top_ = value; }
-  void set_end(uword value) {
-    ASSERT(to_->end() == value);
-    end_ = value;
-  }
-
-  // Report (TLAB) abandoned bytes that should be taken account when
-  // deciding whether to grow new space or not.
-  void AddAbandonedInBytes(intptr_t value) {
-    MutexLocker ml(&space_lock_);
-    AddAbandonedInBytesLocked(value);
-  }
-  int64_t GetAndResetAbandonedInBytes() {
-    int64_t result = abandoned_;
-    abandoned_ = 0;
-    return result;
-  }
-
   int64_t UsedInWords() const {
     MutexLocker ml(&space_lock_);
-    return (top_ - FirstObjectStart()) >> kWordSizeLog2;
+    return to_->capacity_in_words();
   }
-  int64_t CapacityInWords() const { return to_->size_in_words(); }
+  int64_t CapacityInWords() const { return to_->max_capacity_in_words(); }
   int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; }
   SpaceUsage GetCurrentUsage() const {
     SpaceUsage usage;
@@ -222,12 +179,22 @@
   void AllocateExternal(intptr_t cid, intptr_t size);
   void FreeExternal(intptr_t size);
 
-  void MakeNewSpaceIterable() const;
+  void MakeNewSpaceIterable();
   int64_t FreeSpaceInWords(Isolate* isolate) const;
 
- private:
-  static const intptr_t kTLABSize = 512 * KB;
+  void InitGrowthControl() {
+    growth_control_ = true;
+  }
 
+  void SetGrowthControlState(bool state) {
+    growth_control_ = state;
+  }
+
+  bool GrowthControlState() { return growth_control_; }
+
+  bool scavenging() const { return scavenging_; }
+
+ private:
   // Ids for time and data records in Heap::GCStats.
   enum {
     // Time
@@ -247,103 +214,58 @@
   uword TryAllocateFromTLAB(Thread* thread, intptr_t size) {
     ASSERT(Utils::IsAligned(size, kObjectAlignment));
     ASSERT(heap_ != Dart::vm_isolate()->heap());
-    uword top = thread->top();
-    uword end = thread->end();
-    uword result = top;
-    intptr_t remaining = end - top;
+
+    const uword result = thread->top();
+    const intptr_t remaining = thread->end() - result;
     if (UNLIKELY(remaining < size)) {
       return 0;
     }
+
     ASSERT(to_->Contains(result));
     ASSERT((result & kObjectAlignmentMask) == kNewObjectAlignmentOffset);
-    top += size;
-    ASSERT((to_->Contains(top)) || (top == to_->end()));
-    thread->set_top(top);
+    thread->set_top(result + size);
     return result;
   }
-  void TryAllocateNewTLAB(Thread* thread);
-  void AddAbandonedInBytesLocked(intptr_t value) { abandoned_ += value; }
-  void AbandonRemainingTLABLocked(Thread* thread);
-  void AbandonTLABsLocked(IsolateGroup* isolate_group);
+  void TryAllocateNewTLAB(Thread* thread, intptr_t size);
 
-  uword FirstObjectStart() const {
-    return to_->start() + kNewObjectAlignmentOffset;
-  }
-  SemiSpace* Prologue(IsolateGroup* isolate_group);
-  void IterateStoreBuffers(IsolateGroup* isolate_group,
-                           ScavengerVisitor* visitor);
-  void IterateObjectIdTable(IsolateGroup* isolate_group,
-                            ScavengerVisitor* visitor);
-  void IterateRoots(IsolateGroup* isolate_group, ScavengerVisitor* visitor);
-  void IterateWeakProperties(IsolateGroup* isolate_group,
-                             ScavengerVisitor* visitor);
-  void IterateWeakReferences(IsolateGroup* isolate_group,
-                             ScavengerVisitor* visitor);
-  void IterateWeakRoots(IsolateGroup* isolate_group, HandleVisitor* visitor);
-  void ProcessToSpace(ScavengerVisitor* visitor);
-  void EnqueueWeakProperty(RawWeakProperty* raw_weak);
-  uword ProcessWeakProperty(RawWeakProperty* raw_weak,
-                            ScavengerVisitor* visitor);
-  void Epilogue(IsolateGroup* isolate_group, SemiSpace* from);
+  SemiSpace* Prologue();
+  intptr_t ParallelScavenge(SemiSpace* from);
+  intptr_t SerialScavenge(SemiSpace* from);
+  void IterateIsolateRoots(ObjectPointerVisitor* visitor);
+  template <bool parallel>
+  void IterateStoreBuffers(ScavengerVisitorBase<parallel>* visitor);
+  template <bool parallel>
+  void IterateRememberedCards(ScavengerVisitorBase<parallel>* visitor);
+  void IterateObjectIdTable(ObjectPointerVisitor* visitor);
+  template <bool parallel>
+  void IterateRoots(ScavengerVisitorBase<parallel>* visitor);
+  void MournWeakHandles();
+  void Epilogue(SemiSpace* from);
 
-  bool IsUnreachable(RawObject** p);
+  bool IsUnreachable(ObjectPtr* p);
 
   void VerifyStoreBuffers();
 
-  // During a scavenge we need to remember the promoted objects.
-  // This is implemented as a stack of objects at the end of the to space. As
-  // object sizes are always greater than sizeof(uword) and promoted objects do
-  // not consume space in the to space they leave enough room for this stack.
-  void PushToPromotedStack(uword addr) {
-    ASSERT(scavenging_);
-    end_ -= sizeof(addr);
-    ASSERT(end_ > top_);
-    *reinterpret_cast<uword*>(end_) = addr;
-  }
-  uword PopFromPromotedStack() {
-    ASSERT(scavenging_);
-    uword result = *reinterpret_cast<uword*>(end_);
-    end_ += sizeof(result);
-    ASSERT(end_ <= to_->end());
-    return result;
-  }
-  bool PromotedStackHasMore() const {
-    ASSERT(scavenging_);
-    return end_ < to_->end();
-  }
-
   void UpdateMaxHeapCapacity();
   void UpdateMaxHeapUsage();
 
-  void ProcessWeakReferences();
+  void MournWeakTables();
 
   intptr_t NewSizeInWords(intptr_t old_size_in_words) const;
 
-  uword top_;
-  uword end_;
+  Heap* heap_;
 
   SemiSpace* to_;
 
-  Heap* heap_;
-
-  // A pointer to the first unscanned object.  Scanning completes when
-  // this value meets the allocation top.
-  uword resolved_top_;
-
-  // Objects below this address have survived a scavenge.
-  uword survivor_end_;
-
-  // Abandoned (TLAB) bytes that need to be accounted for when deciding
-  // whether to grow newspace or not.
-  intptr_t abandoned_ = 0;
+  PromotionStack promotion_stack_;
 
   intptr_t max_semi_capacity_in_words_;
 
   // Keep track whether a scavenge is currently running.
   bool scavenging_;
-
-  // Keep track of pending weak properties discovered while scagenging.
-  RawWeakProperty* delayed_weak_properties_;
+  bool early_tenure_ = false;
+  RelaxedAtomic<intptr_t> root_slices_started_;
+  StoreBufferBlock* blocks_;
 
   int64_t gc_time_micros_;
   intptr_t collections_;
@@ -358,10 +280,13 @@
 
   bool failed_to_promote_;
 
+  bool growth_control_;
+
   // Protects new space during the allocation of new TLABs
   mutable Mutex space_lock_;
 
-  friend class ScavengerVisitor;
+  template <bool>
+  friend class ScavengerVisitorBase;
   friend class ScavengerWeakVisitor;
 
   DISALLOW_COPY_AND_ASSIGN(Scavenger);
diff --git a/runtime/vm/heap/scavenger_test.cc b/runtime/vm/heap/scavenger_test.cc
index 64b2a31..8d405eb 100644
--- a/runtime/vm/heap/scavenger_test.cc
+++ b/runtime/vm/heap/scavenger_test.cc
@@ -13,14 +13,14 @@
 class FailingObjectVisitor : public ObjectVisitor {
  public:
   FailingObjectVisitor() {}
-  virtual void VisitObject(RawObject* obj) { EXPECT(false); }
+  virtual void VisitObject(ObjectPtr obj) { EXPECT(false); }
 };
 
 // Expects to visit no objects (since the space should be empty).
 class FailingObjectPointerVisitor : public ObjectPointerVisitor {
  public:
   FailingObjectPointerVisitor() : ObjectPointerVisitor(NULL) {}
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
     EXPECT(false);
   }
 };
@@ -29,7 +29,7 @@
 class FailingFindObjectVisitor : public FindObjectVisitor {
  public:
   FailingFindObjectVisitor() {}
-  virtual bool FindObject(RawObject* obj) const {
+  virtual bool FindObject(ObjectPtr obj) const {
     EXPECT(false);
     return false;
   }
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index 405357d..5581e45 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -4,7 +4,6 @@
 
 #include "vm/heap/sweeper.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/globals.h"
 #include "vm/heap/freelist.h"
 #include "vm/heap/heap.h"
@@ -29,31 +28,30 @@
 
   while (current < end) {
     intptr_t obj_size;
-    RawObject* raw_obj = RawObject::FromAddr(current);
+    ObjectPtr raw_obj = ObjectLayout::FromAddr(current);
     ASSERT(HeapPage::Of(raw_obj) == page);
-    if (raw_obj->IsMarked()) {
+    if (raw_obj->ptr()->IsMarked()) {
       // Found marked object. Clear the mark bit and update swept bytes.
-      raw_obj->ClearMarkBit();
-      obj_size = raw_obj->HeapSize();
+      raw_obj->ptr()->ClearMarkBit();
+      obj_size = raw_obj->ptr()->HeapSize();
       used_in_bytes += obj_size;
     } else {
-      uword free_end = current + raw_obj->HeapSize();
+      uword free_end = current + raw_obj->ptr()->HeapSize();
       while (free_end < end) {
-        RawObject* next_obj = RawObject::FromAddr(free_end);
-        if (next_obj->IsMarked()) {
+        ObjectPtr next_obj = ObjectLayout::FromAddr(free_end);
+        if (next_obj->ptr()->IsMarked()) {
           // Reached the end of the free block.
           break;
         }
         // Expand the free block by the size of this object.
-        free_end += next_obj->HeapSize();
+        free_end += next_obj->ptr()->HeapSize();
       }
       obj_size = free_end - current;
       if (is_executable) {
         uword cursor = current;
         uword end = current + obj_size;
         while (cursor < end) {
-          *reinterpret_cast<uword*>(cursor) =
-              compiler::Assembler::GetBreakInstructionFiller();
+          *reinterpret_cast<uword*>(cursor) = kBreakInstructionFiller;
           cursor += kWordSize;
         }
       } else {
@@ -82,21 +80,21 @@
   ASSERT(!page->is_image_page());
 
   intptr_t words_to_end = 0;
-  RawObject* raw_obj = RawObject::FromAddr(page->object_start());
+  ObjectPtr raw_obj = ObjectLayout::FromAddr(page->object_start());
   ASSERT(HeapPage::Of(raw_obj) == page);
-  if (raw_obj->IsMarked()) {
-    raw_obj->ClearMarkBit();
-    words_to_end = (raw_obj->HeapSize() >> kWordSizeLog2);
+  if (raw_obj->ptr()->IsMarked()) {
+    raw_obj->ptr()->ClearMarkBit();
+    words_to_end = (raw_obj->ptr()->HeapSize() >> kWordSizeLog2);
   }
 #ifdef DEBUG
   // Array::MakeFixedLength creates trailing filler objects,
   // but they are always unreachable. Verify that they are not marked.
-  uword current = RawObject::ToAddr(raw_obj) + raw_obj->HeapSize();
+  uword current = ObjectLayout::ToAddr(raw_obj) + raw_obj->ptr()->HeapSize();
   uword end = page->object_end();
   while (current < end) {
-    RawObject* cur_obj = RawObject::FromAddr(current);
-    ASSERT(!cur_obj->IsMarked());
-    intptr_t obj_size = cur_obj->HeapSize();
+    ObjectPtr cur_obj = ObjectLayout::FromAddr(current);
+    ASSERT(!cur_obj->ptr()->IsMarked());
+    intptr_t obj_size = cur_obj->ptr()->HeapSize();
     memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size);
     current += obj_size;
   }
@@ -111,20 +109,17 @@
                         HeapPage* first,
                         HeapPage* last,
                         HeapPage* large_first,
-                        HeapPage* large_last,
-                        FreeList* freelist)
+                        HeapPage* large_last)
       : task_isolate_group_(isolate_group),
         old_space_(old_space),
         first_(first),
         last_(last),
         large_first_(large_first),
-        large_last_(large_last),
-        freelist_(freelist) {
+        large_last_(large_last) {
     ASSERT(task_isolate_group_ != NULL);
     ASSERT(first_ != NULL);
     ASSERT(old_space_ != NULL);
     ASSERT(last_ != NULL);
-    ASSERT(freelist_ != NULL);
     MonitorLocker ml(old_space_->tasks_lock());
     old_space_->set_tasks(old_space_->tasks() + 1);
     old_space_->set_phase(PageSpace::kSweepingLarge);
@@ -169,6 +164,8 @@
         ml.NotifyAll();
       }
 
+      intptr_t shard = 0;
+      const intptr_t num_shards = Utils::Maximum(FLAG_scavenger_tasks, 1);
       page = first_;
       prev_page = NULL;
       while (page != NULL) {
@@ -181,7 +178,9 @@
           next_page = page->next();
         }
         ASSERT(page->type() == HeapPage::kData);
-        bool page_in_use = sweeper.SweepPage(page, freelist_, false);
+        shard = (shard + 1) % num_shards;
+        bool page_in_use =
+            sweeper.SweepPage(page, old_space_->DataFreeList(shard), false);
         if (page_in_use) {
           prev_page = page;
         } else {
@@ -215,7 +214,6 @@
   HeapPage* last_;
   HeapPage* large_first_;
   HeapPage* large_last_;
-  FreeList* freelist_;
 };
 
 void GCSweeper::SweepConcurrent(IsolateGroup* isolate_group,
@@ -226,7 +224,7 @@
                                 FreeList* freelist) {
   bool result = Dart::thread_pool()->Run<ConcurrentSweeperTask>(
       isolate_group, isolate_group->heap()->old_space(), first, last,
-      large_first, large_last, freelist);
+      large_first, large_last);
   ASSERT(result);
 }
 
diff --git a/runtime/vm/heap/verifier.cc b/runtime/vm/heap/verifier.cc
index 12762ec..777cf33 100644
--- a/runtime/vm/heap/verifier.cc
+++ b/runtime/vm/heap/verifier.cc
@@ -16,24 +16,24 @@
 
 namespace dart {
 
-void VerifyObjectVisitor::VisitObject(RawObject* raw_obj) {
+void VerifyObjectVisitor::VisitObject(ObjectPtr raw_obj) {
   if (raw_obj->IsHeapObject()) {
-    uword raw_addr = RawObject::ToAddr(raw_obj);
+    uword raw_addr = ObjectLayout::ToAddr(raw_obj);
     if (raw_obj->IsFreeListElement() || raw_obj->IsForwardingCorpse()) {
-      if (raw_obj->IsOldObject() && raw_obj->IsMarked()) {
+      if (raw_obj->IsOldObject() && raw_obj->ptr()->IsMarked()) {
         FATAL1("Marked free list element encountered %#" Px "\n", raw_addr);
       }
     } else {
       switch (mark_expectation_) {
         case kForbidMarked:
-          if (raw_obj->IsOldObject() && raw_obj->IsMarked()) {
+          if (raw_obj->IsOldObject() && raw_obj->ptr()->IsMarked()) {
             FATAL1("Marked object encountered %#" Px "\n", raw_addr);
           }
           break;
         case kAllowMarked:
           break;
         case kRequireMarked:
-          if (raw_obj->IsOldObject() && !raw_obj->IsMarked()) {
+          if (raw_obj->IsOldObject() && !raw_obj->ptr()->IsMarked()) {
             FATAL1("Unmarked object encountered %#" Px "\n", raw_addr);
           }
           break;
@@ -44,16 +44,16 @@
   raw_obj->Validate(isolate_group_);
 }
 
-void VerifyPointersVisitor::VisitPointers(RawObject** first, RawObject** last) {
-  for (RawObject** current = first; current <= last; current++) {
-    RawObject* raw_obj = *current;
+void VerifyPointersVisitor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+  for (ObjectPtr* current = first; current <= last; current++) {
+    ObjectPtr raw_obj = *current;
     if (raw_obj->IsHeapObject()) {
       if (!allocated_set_->Contains(raw_obj)) {
         if (raw_obj->IsInstructions() &&
             allocated_set_->Contains(HeapPage::ToWritable(raw_obj))) {
           continue;
         }
-        uword raw_addr = RawObject::ToAddr(raw_obj);
+        uword raw_addr = ObjectLayout::ToAddr(raw_obj);
         FATAL1("Invalid object pointer encountered %#" Px "\n", raw_addr);
       }
     }
@@ -63,7 +63,7 @@
 void VerifyWeakPointersVisitor::VisitHandle(uword addr) {
   FinalizablePersistentHandle* handle =
       reinterpret_cast<FinalizablePersistentHandle*>(addr);
-  RawObject* raw_obj = handle->raw();
+  ObjectPtr raw_obj = handle->raw();
   visitor_->VisitPointer(&raw_obj);
 }
 
@@ -88,7 +88,7 @@
 VerifyCanonicalVisitor::VerifyCanonicalVisitor(Thread* thread)
     : thread_(thread), instanceHandle_(Instance::Handle(thread->zone())) {}
 
-void VerifyCanonicalVisitor::VisitObject(RawObject* obj) {
+void VerifyCanonicalVisitor::VisitObject(ObjectPtr obj) {
   // TODO(dartbug.com/36097): The heap walk can encounter canonical objects of
   // other isolates. We should either scan live objects from the roots of each
   // individual isolate, or wait until we are ready to share constants across
@@ -96,7 +96,7 @@
   if (!FLAG_enable_isolate_groups) {
     if ((obj->GetClassId() >= kInstanceCid) &&
         (obj->GetClassId() != kTypeArgumentsCid)) {
-      if (obj->IsCanonical()) {
+      if (obj->ptr()->IsCanonical()) {
         instanceHandle_ ^= obj;
         const bool is_canonical = instanceHandle_.CheckIsCanonical(thread_);
         if (!is_canonical) {
diff --git a/runtime/vm/heap/verifier.h b/runtime/vm/heap/verifier.h
index ae13e90..3733125 100644
--- a/runtime/vm/heap/verifier.h
+++ b/runtime/vm/heap/verifier.h
@@ -17,7 +17,6 @@
 // Forward declarations.
 class IsolateGroup;
 class ObjectSet;
-class RawObject;
 
 enum MarkExpectation { kForbidMarked, kAllowMarked, kRequireMarked };
 
@@ -30,7 +29,7 @@
         allocated_set_(allocated_set),
         mark_expectation_(mark_expectation) {}
 
-  virtual void VisitObject(RawObject* obj);
+  virtual void VisitObject(ObjectPtr obj);
 
  private:
   IsolateGroup* isolate_group_;
@@ -48,7 +47,7 @@
                                  ObjectSet* allocated_set)
       : ObjectPointerVisitor(isolate_group), allocated_set_(allocated_set) {}
 
-  virtual void VisitPointers(RawObject** first, RawObject** last);
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last);
 
   static void VerifyPointers(MarkExpectation mark_expectation = kForbidMarked);
 
@@ -77,7 +76,7 @@
 class VerifyCanonicalVisitor : public ObjectVisitor {
  public:
   explicit VerifyCanonicalVisitor(Thread* thread);
-  virtual void VisitObject(RawObject* obj);
+  virtual void VisitObject(ObjectPtr obj);
 
  private:
   Thread* thread_;
diff --git a/runtime/vm/heap/weak_table.cc b/runtime/vm/heap/weak_table.cc
index b4cf28d..159ed5a 100644
--- a/runtime/vm/heap/weak_table.cc
+++ b/runtime/vm/heap/weak_table.cc
@@ -29,18 +29,18 @@
   return result;
 }
 
-void WeakTable::SetValueExclusive(RawObject* key, intptr_t val) {
+void WeakTable::SetValueExclusive(ObjectPtr key, intptr_t val) {
   intptr_t mask = size() - 1;
   intptr_t idx = Hash(key) & mask;
   intptr_t empty_idx = -1;
-  RawObject* obj = ObjectAtExclusive(idx);
+  ObjectPtr obj = ObjectAtExclusive(idx);
 
-  while (obj != NULL) {
+  while (obj != nullptr) {
     if (obj == key) {
       SetValueAt(idx, val);
       return;
     } else if ((empty_idx < 0) &&
-               (reinterpret_cast<intptr_t>(obj) == kDeletedEntry)) {
+               (static_cast<intptr_t>(obj) == kDeletedEntry)) {
       empty_idx = idx;  // Insert at this location if not found.
     }
     idx = (idx + 1) & mask;
@@ -109,16 +109,16 @@
   for (intptr_t i = 0; i < old_size; i++) {
     if (IsValidEntryAtExclusive(i)) {
       // Find the new hash location for this entry.
-      RawObject* key = ObjectAtExclusive(i);
+      ObjectPtr key = ObjectAtExclusive(i);
       intptr_t idx = Hash(key) & mask;
-      RawObject* obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
-      while (obj != NULL) {
+      ObjectPtr obj = static_cast<ObjectPtr>(new_data[ObjectIndex(idx)]);
+      while (obj != nullptr) {
         ASSERT(obj != key);  // Duplicate entry is not expected.
         idx = (idx + 1) & mask;
-        obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
+        obj = static_cast<ObjectPtr>(new_data[ObjectIndex(idx)]);
       }
 
-      new_data[ObjectIndex(idx)] = reinterpret_cast<intptr_t>(key);
+      new_data[ObjectIndex(idx)] = static_cast<intptr_t>(key);
       new_data[ValueIndex(idx)] = ValueAtExclusive(i);
       set_used(used() + 1);
     }
@@ -135,7 +135,7 @@
 void WeakTable::MergeOtherWeakTable(WeakTable* other) {
   for (intptr_t i = 0; i < other->size(); i++) {
     if (other->IsValidEntryAtExclusive(i)) {
-      SetValue(other->ObjectAtExclusive(i), ValueIndex(i));
+      SetValueExclusive(other->ObjectAtExclusive(i), ValueIndex(i));
     }
   }
 }
diff --git a/runtime/vm/heap/weak_table.h b/runtime/vm/heap/weak_table.h
index 051051f..6fc01f3 100644
--- a/runtime/vm/heap/weak_table.h
+++ b/runtime/vm/heap/weak_table.h
@@ -49,12 +49,12 @@
 
   // The following methods can be called concurrently and are guarded by a lock.
 
-  intptr_t GetValue(RawObject* key) {
+  intptr_t GetValue(ObjectPtr key) {
     MutexLocker ml(&mutex_);
     return GetValueExclusive(key);
   }
 
-  void SetValue(RawObject* key, intptr_t val) {
+  void SetValue(ObjectPtr key, intptr_t val) {
     MutexLocker ml(&mutex_);
     return SetValueExclusive(key, val);
   }
@@ -66,9 +66,9 @@
 
   bool IsValidEntryAtExclusive(intptr_t i) const {
     ASSERT((ValueAtExclusive(i) == 0 &&
-            (ObjectAtExclusive(i) == NULL ||
+            (ObjectAtExclusive(i) == nullptr ||
              data_[ObjectIndex(i)] == kDeletedEntry)) ||
-           (ValueAtExclusive(i) != 0 && ObjectAtExclusive(i) != NULL &&
+           (ValueAtExclusive(i) != 0 && ObjectAtExclusive(i) != nullptr &&
             data_[ObjectIndex(i)] != kDeletedEntry));
     return (data_[ValueIndex(i)] != 0);
   }
@@ -78,10 +78,10 @@
     SetValueAt(i, 0);
   }
 
-  RawObject* ObjectAtExclusive(intptr_t i) const {
+  ObjectPtr ObjectAtExclusive(intptr_t i) const {
     ASSERT(i >= 0);
     ASSERT(i < size());
-    return reinterpret_cast<RawObject*>(data_[ObjectIndex(i)]);
+    return static_cast<ObjectPtr>(data_[ObjectIndex(i)]);
   }
 
   intptr_t ValueAtExclusive(intptr_t i) const {
@@ -90,13 +90,13 @@
     return data_[ValueIndex(i)];
   }
 
-  void SetValueExclusive(RawObject* key, intptr_t val);
+  void SetValueExclusive(ObjectPtr key, intptr_t val);
 
-  intptr_t GetValueExclusive(RawObject* key) const {
+  intptr_t GetValueExclusive(ObjectPtr key) const {
     intptr_t mask = size() - 1;
     intptr_t idx = Hash(key) & mask;
-    RawObject* obj = ObjectAtExclusive(idx);
-    while (obj != NULL) {
+    ObjectPtr obj = ObjectAtExclusive(idx);
+    while (obj != nullptr) {
       if (obj == key) {
         return ValueAtExclusive(idx);
       }
@@ -109,11 +109,11 @@
 
   // Removes and returns the value associated with |key|. Returns 0 if there is
   // no value associated with |key|.
-  intptr_t RemoveValueExclusive(RawObject* key) {
+  intptr_t RemoveValueExclusive(ObjectPtr key) {
     intptr_t mask = size() - 1;
     intptr_t idx = Hash(key) & mask;
-    RawObject* obj = ObjectAtExclusive(idx);
-    while (obj != NULL) {
+    ObjectPtr obj = ObjectAtExclusive(idx);
+    while (obj != nullptr) {
       if (obj == key) {
         intptr_t result = ValueAtExclusive(idx);
         InvalidateAtExclusive(idx);
@@ -166,16 +166,16 @@
 
   intptr_t ValueIndex(intptr_t i) const { return index(i) + kValueOffset; }
 
-  RawObject** ObjectPointerAt(intptr_t i) const {
+  ObjectPtr* ObjectPointerAt(intptr_t i) const {
     ASSERT(i >= 0);
     ASSERT(i < size());
-    return reinterpret_cast<RawObject**>(&data_[ObjectIndex(i)]);
+    return reinterpret_cast<ObjectPtr*>(&data_[ObjectIndex(i)]);
   }
 
-  void SetObjectAt(intptr_t i, RawObject* key) {
+  void SetObjectAt(intptr_t i, ObjectPtr key) {
     ASSERT(i >= 0);
     ASSERT(i < size());
-    data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key);
+    data_[ObjectIndex(i)] = static_cast<intptr_t>(key);
   }
 
   void SetValueAt(intptr_t i, intptr_t val) {
@@ -191,8 +191,8 @@
 
   void Rehash();
 
-  static intptr_t Hash(RawObject* key) {
-    return reinterpret_cast<uintptr_t>(key) * 92821;
+  static intptr_t Hash(ObjectPtr key) {
+    return static_cast<uintptr_t>(key) * 92821;
   }
 
   Mutex mutex_;
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index e61fd02..566f596 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -4,9 +4,9 @@
 
 #include "vm/image_snapshot.h"
 
+#include "include/dart_api.h"
 #include "platform/assert.h"
 #include "vm/class_id.h"
-#include "vm/compiler/backend/code_statistics.h"
 #include "vm/compiler/runtime_api.h"
 #include "vm/dwarf.h"
 #include "vm/elf.h"
@@ -22,6 +22,10 @@
 #include "vm/timeline.h"
 #include "vm/type_testing_stubs.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/backend/code_statistics.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 #if defined(DART_PRECOMPILER)
@@ -37,11 +41,11 @@
 #endif
 
 intptr_t ObjectOffsetTrait::Hashcode(Key key) {
-  RawObject* obj = key;
+  ObjectPtr obj = key;
   ASSERT(!obj->IsSmi());
 
-  uword body = RawObject::ToAddr(obj) + sizeof(RawObject);
-  uword end = RawObject::ToAddr(obj) + obj->HeapSize();
+  uword body = ObjectLayout::ToAddr(obj) + sizeof(ObjectLayout);
+  uword end = ObjectLayout::ToAddr(obj) + obj->ptr()->HeapSize();
 
   uint32_t hash = obj->GetClassId();
   // Don't include the header. Objects in the image are pre-marked, but objects
@@ -54,8 +58,8 @@
 }
 
 bool ObjectOffsetTrait::IsKeyEqual(Pair pair, Key key) {
-  RawObject* a = pair.object;
-  RawObject* b = key;
+  ObjectPtr a = pair.object;
+  ObjectPtr b = key;
   ASSERT(!a->IsSmi());
   ASSERT(!b->IsSmi());
 
@@ -63,16 +67,16 @@
     return false;
   }
 
-  intptr_t heap_size = a->HeapSize();
-  if (b->HeapSize() != heap_size) {
+  intptr_t heap_size = a->ptr()->HeapSize();
+  if (b->ptr()->HeapSize() != heap_size) {
     return false;
   }
 
   // Don't include the header. Objects in the image are pre-marked, but objects
   // in the current isolate are not.
-  uword body_a = RawObject::ToAddr(a) + sizeof(RawObject);
-  uword body_b = RawObject::ToAddr(b) + sizeof(RawObject);
-  uword body_size = heap_size - sizeof(RawObject);
+  uword body_a = ObjectLayout::ToAddr(a) + sizeof(ObjectLayout);
+  uword body_b = ObjectLayout::ToAddr(b) + sizeof(ObjectLayout);
+  uword body_size = heap_size - sizeof(ObjectLayout);
   return 0 == memcmp(reinterpret_cast<const void*>(body_a),
                      reinterpret_cast<const void*>(body_b), body_size);
 }
@@ -99,8 +103,8 @@
       ASSERT((initial_offset + inst.expected_offset) == next_text_offset_);
       switch (inst.op) {
         case ImageWriterCommand::InsertInstructionOfCode: {
-          RawCode* code = inst.insert_instruction_of_code.code;
-          RawInstructions* instructions = Code::InstructionsOf(code);
+          CodePtr code = inst.insert_instruction_of_code.code;
+          InstructionsPtr instructions = Code::InstructionsOf(code);
           const intptr_t offset = next_text_offset_;
           instructions_.Add(InstructionsData(instructions, code, offset));
           next_text_offset_ += SizeInSnapshot(instructions);
@@ -124,8 +128,8 @@
   }
 }
 
-int32_t ImageWriter::GetTextOffsetFor(RawInstructions* instructions,
-                                      RawCode* code) {
+int32_t ImageWriter::GetTextOffsetFor(InstructionsPtr instructions,
+                                      CodePtr code) {
   intptr_t offset = heap_->GetObjectId(instructions);
   if (offset != 0) {
     return offset;
@@ -140,7 +144,7 @@
   return offset;
 }
 
-static intptr_t InstructionsSizeInSnapshot(RawInstructions* raw) {
+static intptr_t InstructionsSizeInSnapshot(InstructionsPtr raw) {
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     // Currently, we align bare instruction payloads on 4 byte boundaries.
     //
@@ -155,7 +159,7 @@
       compiler::target::Instructions::HeaderSize() + Instructions::Size(raw),
       compiler::target::ObjectAlignment::kObjectAlignment);
 #else
-  return raw->HeapSize();
+  return raw->ptr()->HeapSize();
 #endif
 }
 
@@ -193,32 +197,32 @@
                         compiler::target::ObjectAlignment::kObjectAlignment);
 }
 
-intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
+intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw_object) {
   const classid_t cid = raw_object->GetClassId();
 
   switch (cid) {
     case kCompressedStackMapsCid: {
-      RawCompressedStackMaps* raw_maps =
-          static_cast<RawCompressedStackMaps*>(raw_object);
+      CompressedStackMapsPtr raw_maps =
+          static_cast<CompressedStackMapsPtr>(raw_object);
       auto const payload_size = CompressedStackMaps::PayloadSizeOf(raw_maps);
       return CompressedStackMapsSizeInSnapshot(payload_size);
     }
     case kOneByteStringCid:
     case kTwoByteStringCid: {
-      RawString* raw_str = static_cast<RawString*>(raw_object);
+      StringPtr raw_str = static_cast<StringPtr>(raw_object);
       return StringSizeInSnapshot(Smi::Value(raw_str->ptr()->length_),
                                   cid == kOneByteStringCid);
     }
     case kCodeSourceMapCid: {
-      RawCodeSourceMap* raw_map = static_cast<RawCodeSourceMap*>(raw_object);
+      CodeSourceMapPtr raw_map = static_cast<CodeSourceMapPtr>(raw_object);
       return CodeSourceMapSizeInSnapshot(raw_map->ptr()->length_);
     }
     case kPcDescriptorsCid: {
-      RawPcDescriptors* raw_desc = static_cast<RawPcDescriptors*>(raw_object);
+      PcDescriptorsPtr raw_desc = static_cast<PcDescriptorsPtr>(raw_object);
       return PcDescriptorsSizeInSnapshot(raw_desc->ptr()->length_);
     }
     case kInstructionsCid: {
-      RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
+      InstructionsPtr raw_insns = static_cast<InstructionsPtr>(raw_object);
       return InstructionsSizeInSnapshot(raw_insns);
     }
     default: {
@@ -229,17 +233,17 @@
   }
 }
 #else   // defined(IS_SIMARM_X64)
-intptr_t ImageWriter::SizeInSnapshot(RawObject* raw) {
+intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw) {
   switch (raw->GetClassId()) {
     case kInstructionsCid:
-      return InstructionsSizeInSnapshot(static_cast<RawInstructions*>(raw));
+      return InstructionsSizeInSnapshot(static_cast<InstructionsPtr>(raw));
     default:
-      return raw->HeapSize();
+      return raw->ptr()->HeapSize();
   }
 }
 #endif  // defined(IS_SIMARM_X64)
 
-uint32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
+uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object) {
   intptr_t snap_size = SizeInSnapshot(raw_object);
   intptr_t offset = next_data_offset_;
   next_data_offset_ += snap_size;
@@ -374,7 +378,7 @@
     if (is_trampoline) continue;
 
     data.insns_ = &Instructions::Handle(zone, data.raw_insns_);
-    ASSERT(data.raw_code_ != NULL);
+    ASSERT(data.raw_code_ != nullptr);
     data.code_ = &Code::Handle(zone, data.raw_code_);
 
     // Reset object id as an isolate snapshot after a VM snapshot will not use
@@ -416,14 +420,15 @@
     AutoTraceImage(obj, section_start, stream);
 
     NoSafepointScope no_safepoint;
-    uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
+    uword start = static_cast<uword>(obj.raw()) - kHeapObjectTag;
 
     // Write object header with the mark and read-only bits set.
     uword marked_tags = obj.raw()->ptr()->tags_;
-    marked_tags = RawObject::OldBit::update(true, marked_tags);
-    marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
-    marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
-    marked_tags = RawObject::NewBit::update(false, marked_tags);
+    marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
+    marked_tags = ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
+    marked_tags =
+        ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
+    marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
 #if defined(HASH_IN_OBJECT_HEADER)
     marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32;
 #endif
@@ -453,9 +458,8 @@
       marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);
 
       stream->WriteTargetWord(marked_tags);
-      stream->WriteTargetWord(
-          reinterpret_cast<uword>(str.raw()->ptr()->length_));
-      stream->WriteTargetWord(reinterpret_cast<uword>(str.raw()->ptr()->hash_));
+      stream->WriteTargetWord(static_cast<uword>(str.raw()->ptr()->length_));
+      stream->WriteTargetWord(static_cast<uword>(str.raw()->ptr()->hash_));
       stream->WriteBytes(
           reinterpret_cast<const void*>(start + String::kSizeofRawString),
           StringPayloadSize(str.Length(), str.IsOneByteString()));
@@ -484,7 +488,7 @@
       FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
     }
 #else   // defined(IS_SIMARM_X64)
-    const uword end = start + obj.raw()->HeapSize();
+    const uword end = start + obj.raw()->ptr()->HeapSize();
 
     stream->WriteWord(marked_tags);
     start += sizeof(uword);
@@ -544,35 +548,14 @@
                                                  const Code& code) {
   if (code.raw() == object_store->build_method_extractor_code()) {
     return "_iso_stub_BuildMethodExtractorStub";
-  } else if (code.raw() == object_store->dispatch_table_null_error_stub()) {
-    return "_iso_stub_DispatchTableNullErrorStub";
-  } else if (code.raw() == object_store->null_error_stub_with_fpu_regs_stub()) {
-    return "_iso_stub_NullErrorSharedWithFPURegsStub";
-  } else if (code.raw() ==
-             object_store->null_error_stub_without_fpu_regs_stub()) {
-    return "_iso_stub_NullErrorSharedWithoutFPURegsStub";
-  } else if (code.raw() ==
-             object_store->null_arg_error_stub_with_fpu_regs_stub()) {
-    return "_iso_stub_NullArgErrorSharedWithFPURegsStub";
-  } else if (code.raw() ==
-             object_store->null_arg_error_stub_without_fpu_regs_stub()) {
-    return "_iso_stub_NullArgErrorSharedWithoutFPURegsStub";
-  } else if (code.raw() == object_store->allocate_mint_with_fpu_regs_stub()) {
-    return "_iso_stub_AllocateMintWithFPURegsStub";
-  } else if (code.raw() ==
-             object_store->allocate_mint_without_fpu_regs_stub()) {
-    return "_iso_stub_AllocateMintWithoutFPURegsStub";
-  } else if (code.raw() ==
-             object_store->stack_overflow_stub_with_fpu_regs_stub()) {
-    return "_iso_stub_StackOverflowStubWithFPURegsStub";
-  } else if (code.raw() ==
-             object_store->stack_overflow_stub_without_fpu_regs_stub()) {
-    return "_iso_stub_StackOverflowStubWithoutFPURegsStub";
-  } else if (code.raw() == object_store->write_barrier_wrappers_stub()) {
-    return "_iso_stub_WriteBarrierWrappersStub";
-  } else if (code.raw() == object_store->array_write_barrier_stub()) {
-    return "_iso_stub_ArrayWriteBarrierStub";
   }
+
+#define DO(member, name)                                                       \
+  if (code.raw() == object_store->member()) {                                  \
+    return "_iso_stub_" #name "Stub";                                          \
+  }
+  OBJECT_STORE_STUB_CODE_LIST(DO)
+#undef DO
   return nullptr;
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -605,7 +588,7 @@
                        code_index);
   } else if (owner_.IsAbstractType()) {
     const char* name = namer_.StubNameForType(AbstractType::Cast(owner_));
-    return OS::SCreate(zone_, "%s%s", prefix, name);
+    return OS::SCreate(zone_, "%s%s_%" Pd, prefix, name, code_index);
   } else if (owner_.IsFunction()) {
     const char* name = Function::Cast(owner_).ToQualifiedCString();
     EnsureAssemblerIdentifier(const_cast<char*>(name));
@@ -642,8 +625,8 @@
   }
 #endif
 
-  const char* instructions_symbol =
-      vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions";
+  const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
+                                       : kIsolateSnapshotInstructionsAsmSymbol;
   assembly_stream_.Print(".text\n");
   assembly_stream_.Print(".globl %s\n", instructions_symbol);
 
@@ -678,12 +661,12 @@
     const intptr_t section_size = image_size - Image::kHeaderSize;
     // Add the RawInstructionsSection header.
     const compiler::target::uword marked_tags =
-        RawObject::OldBit::encode(true) |
-        RawObject::OldAndNotMarkedBit::encode(false) |
-        RawObject::OldAndNotRememberedBit::encode(true) |
-        RawObject::NewBit::encode(false) |
-        RawObject::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
-        RawObject::ClassIdTag::encode(kInstructionsSectionCid);
+        ObjectLayout::OldBit::encode(true) |
+        ObjectLayout::OldAndNotMarkedBit::encode(false) |
+        ObjectLayout::OldAndNotRememberedBit::encode(true) |
+        ObjectLayout::NewBit::encode(false) |
+        ObjectLayout::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
+        ObjectLayout::ClassIdTag::encode(kInstructionsSectionCid);
     WriteWordLiteralText(marked_tags);
     // Calculated using next_text_offset_, which doesn't include post-payload
     // padding to object alignment.
@@ -775,11 +758,12 @@
 
       // Write Instructions with the mark and read-only bits set.
       uword marked_tags = insns.raw_ptr()->tags_;
-      marked_tags = RawObject::OldBit::update(true, marked_tags);
-      marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
+      marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
       marked_tags =
-          RawObject::OldAndNotRememberedBit::update(true, marked_tags);
-      marked_tags = RawObject::NewBit::update(false, marked_tags);
+          ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
+      marked_tags =
+          ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
+      marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
 #if defined(HASH_IN_OBJECT_HEADER)
       // Can't use GetObjectTagsAndHash because the update methods discard the
       // high bits.
@@ -831,7 +815,7 @@
 
 #if defined(DART_PRECOMPILER)
       PcDescriptors::Iterator iterator(descriptors,
-                                       RawPcDescriptors::kBSSRelocation);
+                                       PcDescriptorsLayout::kBSSRelocation);
       uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
 
       // We only generate BSS relocations that are word-sized and at
@@ -870,14 +854,13 @@
                 compiler::target::ObjectAlignment::kObjectAlignment) -
             unaligned_size;
         while (alignment_size > 0) {
-          WriteWordLiteralText(
-              compiler::Assembler::GetBreakInstructionFiller());
+          WriteWordLiteralText(kBreakInstructionFiller);
           alignment_size -= sizeof(compiler::target::uword);
           text_offset += sizeof(compiler::target::uword);
         }
 
         ASSERT(kWordSize != compiler::target::kWordSize ||
-               (text_offset - instr_start) == insns.raw()->HeapSize());
+               (text_offset - instr_start) == insns.raw()->ptr()->HeapSize());
       }
     }
 
@@ -1086,8 +1069,8 @@
 void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
   const bool bare_instruction_payloads =
       FLAG_precompiled_mode && FLAG_use_bare_instructions;
-  const char* instructions_symbol =
-      vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions";
+  const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
+                                       : kIsolateSnapshotInstructionsAsmSymbol;
   auto const zone = Thread::Current()->zone();
 
 #if defined(DART_PRECOMPILER)
@@ -1098,6 +1081,9 @@
   intptr_t debug_segment_base = 0;
   if (debug_dwarf_ != nullptr) {
     debug_segment_base = debug_dwarf_->elf()->NextMemoryOffset();
+    // If we're also generating an ELF snapshot, we want the virtual addresses
+    // in it and the separately saved DWARF information to match.
+    ASSERT(elf_ == nullptr || segment_base == debug_segment_base);
   }
 #endif
 
@@ -1126,12 +1112,12 @@
     const intptr_t section_size = image_size - Image::kHeaderSize;
     // Add the RawInstructionsSection header.
     const compiler::target::uword marked_tags =
-        RawObject::OldBit::encode(true) |
-        RawObject::OldAndNotMarkedBit::encode(false) |
-        RawObject::OldAndNotRememberedBit::encode(true) |
-        RawObject::NewBit::encode(false) |
-        RawObject::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
-        RawObject::ClassIdTag::encode(kInstructionsSectionCid);
+        ObjectLayout::OldBit::encode(true) |
+        ObjectLayout::OldAndNotMarkedBit::encode(false) |
+        ObjectLayout::OldAndNotRememberedBit::encode(true) |
+        ObjectLayout::NewBit::encode(false) |
+        ObjectLayout::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
+        ObjectLayout::ClassIdTag::encode(kInstructionsSectionCid);
     instructions_blob_stream_.WriteTargetWord(marked_tags);
     // Uses next_text_offset_ to avoid any post-payload padding.
     const intptr_t instructions_length =
@@ -1202,10 +1188,11 @@
 
     // Write Instructions with the mark and read-only bits set.
     uword marked_tags = insns.raw_ptr()->tags_;
-    marked_tags = RawObject::OldBit::update(true, marked_tags);
-    marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
-    marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
-    marked_tags = RawObject::NewBit::update(false, marked_tags);
+    marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
+    marked_tags = ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
+    marked_tags =
+        ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
+    marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
 #if defined(HASH_IN_OBJECT_HEADER)
     // Can't use GetObjectTagsAndHash because the update methods discard the
     // high bits.
@@ -1277,7 +1264,7 @@
       descriptors = code.pc_descriptors();
 
       PcDescriptors::Iterator iterator(
-          descriptors, /*kind_mask=*/RawPcDescriptors::kBSSRelocation);
+          descriptors, /*kind_mask=*/PcDescriptorsLayout::kBSSRelocation);
 
       while (iterator.MoveNext()) {
         const intptr_t reloc_offset = iterator.PcOffset();
@@ -1325,9 +1312,9 @@
     ASSERT(segment_base == segment_base2);
   }
   if (debug_dwarf_ != nullptr) {
-    auto const debug_segment_base2 = debug_dwarf_->elf()->AddText(
-        instructions_symbol, instructions_blob_stream_.buffer(),
-        instructions_blob_stream_.bytes_written());
+    auto const debug_segment_base2 =
+        debug_dwarf_->elf()->AddText(instructions_symbol, nullptr,
+                                     instructions_blob_stream_.bytes_written());
     ASSERT(debug_segment_base == debug_segment_base2);
   }
 #endif
@@ -1341,7 +1328,7 @@
   ASSERT(instructions_image != NULL);
 }
 
-RawApiError* ImageReader::VerifyAlignment() const {
+ApiErrorPtr ImageReader::VerifyAlignment() const {
   if (!Utils::IsAligned(data_image_, kObjectAlignment) ||
       !Utils::IsAligned(instructions_image_, kMaxObjectAlignment)) {
     return ApiError::New(
@@ -1363,23 +1350,23 @@
 }
 #endif
 
-RawInstructions* ImageReader::GetInstructionsAt(uint32_t offset) const {
+InstructionsPtr ImageReader::GetInstructionsAt(uint32_t offset) const {
   ASSERT(Utils::IsAligned(offset, kObjectAlignment));
 
-  RawObject* result = RawObject::FromAddr(
+  ObjectPtr result = ObjectLayout::FromAddr(
       reinterpret_cast<uword>(instructions_image_) + offset);
   ASSERT(result->IsInstructions());
-  ASSERT(result->IsMarked());
+  ASSERT(result->ptr()->IsMarked());
 
   return Instructions::RawCast(result);
 }
 
-RawObject* ImageReader::GetObjectAt(uint32_t offset) const {
+ObjectPtr ImageReader::GetObjectAt(uint32_t offset) const {
   ASSERT(Utils::IsAligned(offset, kObjectAlignment));
 
-  RawObject* result =
-      RawObject::FromAddr(reinterpret_cast<uword>(data_image_) + offset);
-  ASSERT(result->IsMarked());
+  ObjectPtr result =
+      ObjectLayout::FromAddr(reinterpret_cast<uword>(data_image_) + offset);
+  ASSERT(result->ptr()->IsMarked());
 
   return result;
 }
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index 3d87113..94a57ca 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -28,10 +28,6 @@
 class Elf;
 class Instructions;
 class Object;
-class RawApiError;
-class RawCode;
-class RawInstructions;
-class RawObject;
 
 class Image : ValueObject {
  public:
@@ -67,12 +63,12 @@
  public:
   ImageReader(const uint8_t* data_image, const uint8_t* instructions_image);
 
-  RawApiError* VerifyAlignment() const;
+  ApiErrorPtr VerifyAlignment() const;
 
   ONLY_IN_PRECOMPILED(uword GetBareInstructionsAt(uint32_t offset) const);
   ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd() const);
-  RawInstructions* GetInstructionsAt(uint32_t offset) const;
-  RawObject* GetObjectAt(uint32_t offset) const;
+  InstructionsPtr GetInstructionsAt(uint32_t offset) const;
+  ObjectPtr GetObjectAt(uint32_t offset) const;
 
  private:
   const uint8_t* data_image_;
@@ -84,16 +80,16 @@
 struct ObjectOffsetPair {
  public:
   ObjectOffsetPair() : ObjectOffsetPair(NULL, 0) {}
-  ObjectOffsetPair(RawObject* obj, int32_t off) : object(obj), offset(off) {}
+  ObjectOffsetPair(ObjectPtr obj, int32_t off) : object(obj), offset(off) {}
 
-  RawObject* object;
+  ObjectPtr object;
   int32_t offset;
 };
 
 class ObjectOffsetTrait {
  public:
   // Typedefs needed for the DirectChainedHashMap template.
-  typedef RawObject* Key;
+  typedef ObjectPtr Key;
   typedef int32_t Value;
   typedef ObjectOffsetPair Pair;
 
@@ -119,7 +115,7 @@
     InsertBytesOfTrampoline,
   };
 
-  ImageWriterCommand(intptr_t expected_offset, RawCode* code)
+  ImageWriterCommand(intptr_t expected_offset, CodePtr code)
       : expected_offset(expected_offset),
         op(ImageWriterCommand::InsertInstructionOfCode),
         insert_instruction_of_code({code}) {}
@@ -138,7 +134,7 @@
   Opcode op;
   union {
     struct {
-      RawCode* code;
+      CodePtr code;
     } insert_instruction_of_code;
     struct {
       uint8_t* buffer;
@@ -172,8 +168,8 @@
            offset_space_ == V8SnapshotProfileWriter::kIsolateData ||
            offset_space_ == V8SnapshotProfileWriter::kIsolateText;
   }
-  int32_t GetTextOffsetFor(RawInstructions* instructions, RawCode* code);
-  uint32_t GetDataOffsetFor(RawObject* raw_object);
+  int32_t GetTextOffsetFor(InstructionsPtr instructions, CodePtr code);
+  uint32_t GetDataOffsetFor(ObjectPtr raw_object);
 
   void Write(WriteStream* clustered_stream, bool vm);
   intptr_t data_size() const { return next_data_offset_; }
@@ -191,7 +187,7 @@
 
   void TraceInstructions(const Instructions& instructions);
 
-  static intptr_t SizeInSnapshot(RawObject* object);
+  static intptr_t SizeInSnapshot(ObjectPtr object);
   static const intptr_t kBareInstructionsAlignment = 4;
 
   static_assert(
@@ -200,9 +196,9 @@
       "Target object alignment is larger than the host object alignment");
 
   // Converts the target object size (in bytes) to an appropriate argument for
-  // RawObject::SizeTag methods on the host machine.
+  // ObjectLayout::SizeTag methods on the host machine.
   //
-  // RawObject::SizeTag expects a size divisible by kObjectAlignment and
+  // ObjectLayout::SizeTag expects a size divisible by kObjectAlignment and
   // checks this in debug mode, but the size on the target machine may not be
   // divisible by the host machine's object alignment if they differ.
   //
@@ -219,8 +215,8 @@
 
   static UNLESS_DEBUG(constexpr) compiler::target::uword
       UpdateObjectSizeForTarget(intptr_t size, uword marked_tags) {
-    return RawObject::SizeTag::update(AdjustObjectSizeForTarget(size),
-                                      marked_tags);
+    return ObjectLayout::SizeTag::update(AdjustObjectSizeForTarget(size),
+                                         marked_tags);
   }
 
   // Returns nullptr if there is no profile writer.
@@ -235,9 +231,7 @@
   void DumpInstructionsSizes();
 
   struct InstructionsData {
-    InstructionsData(RawInstructions* insns,
-                     RawCode* code,
-                     intptr_t text_offset)
+    InstructionsData(InstructionsPtr insns, CodePtr code, intptr_t text_offset)
         : raw_insns_(insns),
           raw_code_(code),
           text_offset_(text_offset),
@@ -254,11 +248,11 @@
           trampoline_length(trampoline_length) {}
 
     union {
-      RawInstructions* raw_insns_;
+      InstructionsPtr raw_insns_;
       const Instructions* insns_;
     };
     union {
-      RawCode* raw_code_;
+      CodePtr raw_code_;
       const Code* code_;
     };
     intptr_t text_offset_;
@@ -268,10 +262,10 @@
   };
 
   struct ObjectData {
-    explicit ObjectData(RawObject* raw_obj) : raw_obj_(raw_obj) {}
+    explicit ObjectData(ObjectPtr raw_obj) : raw_obj_(raw_obj) {}
 
     union {
-      RawObject* raw_obj_;
+      ObjectPtr raw_obj_;
       const Object* obj_;
     };
   };
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 2dab069..465f888 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -8,7 +8,6 @@
 #include "vm/instructions.h"
 #include "vm/instructions_arm.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/object.h"
@@ -65,9 +64,8 @@
   ASSERT(reg == R9);
 }
 
-RawCode* NativeCallPattern::target() const {
-  return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr NativeCallPattern::target() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
 }
 
 void NativeCallPattern::set_target(const Code& new_target) const {
@@ -104,7 +102,7 @@
   } else {
     intptr_t value = 0;
     start = DecodeLoadWordImmediate(end, reg, &value);
-    *obj = reinterpret_cast<RawObject*>(value);
+    *obj = static_cast<ObjectPtr>(value);
   }
   return start;
 }
@@ -260,16 +258,15 @@
   return false;
 }
 
-RawCode* CallPattern::TargetCode() const {
-  return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr CallPattern::TargetCode() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
 }
 
 void CallPattern::SetTargetCode(const Code& target_code) const {
   object_pool_.SetObjectAt(target_code_pool_index_, target_code);
 }
 
-RawObject* ICCallPattern::Data() const {
+ObjectPtr ICCallPattern::Data() const {
   return object_pool_.ObjectAt(data_pool_index_);
 }
 
@@ -278,8 +275,8 @@
   object_pool_.SetObjectAt(data_pool_index_, data);
 }
 
-RawCode* ICCallPattern::TargetCode() const {
-  return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr ICCallPattern::TargetCode() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
 }
 
 void ICCallPattern::SetTargetCode(const Code& target_code) const {
@@ -291,7 +288,7 @@
       data_pool_index_(-1),
       target_pool_index_(-1) {}
 
-RawObject* SwitchableCallPatternBase::data() const {
+ObjectPtr SwitchableCallPatternBase::data() const {
   return object_pool_.ObjectAt(data_pool_index_);
 }
 
@@ -315,8 +312,8 @@
   ASSERT(reg == CODE_REG);
 }
 
-RawCode* SwitchableCallPattern::target() const {
-  return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr SwitchableCallPattern::target() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
 }
 void SwitchableCallPattern::SetTarget(const Code& target) const {
   ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
@@ -339,13 +336,13 @@
   ASSERT(reg == LR);
 }
 
-RawCode* BareSwitchableCallPattern::target() const {
+CodePtr BareSwitchableCallPattern::target() const {
   const uword pc = object_pool_.RawValueAt(target_pool_index_);
-  auto rct = Isolate::Current()->reverse_pc_lookup_cache();
+  auto rct = IsolateGroup::Current()->reverse_pc_lookup_cache();
   if (rct->Contains(pc)) {
     return rct->Lookup(pc);
   }
-  rct = Dart::vm_isolate()->reverse_pc_lookup_cache();
+  rct = Dart::vm_isolate()->group()->reverse_pc_lookup_cache();
   if (rct->Contains(pc)) {
     return rct->Lookup(pc);
   }
@@ -382,8 +379,19 @@
 bool PcRelativeCallPattern::IsValid() const {
   // bl.<cond> <offset>
   const uint32_t word = *reinterpret_cast<uint32_t*>(pc_);
-  const uint32_t branch_link = 0x05;
-  return ((word >> kTypeShift) & ((1 << kTypeBits) - 1)) == branch_link;
+  const uint32_t branch = 0x05;
+  const uword type = ((word >> kTypeShift) & ((1 << kTypeBits) - 1));
+  const uword link = ((word >> kLinkShift) & ((1 << kLinkBits) - 1));
+  return type == branch && link == 1;
+}
+
+bool PcRelativeTailCallPattern::IsValid() const {
+  // b.<cond> <offset>
+  const uint32_t word = *reinterpret_cast<uint32_t*>(pc_);
+  const uint32_t branch = 0x05;
+  const uword type = ((word >> kTypeShift) & ((1 << kTypeBits) - 1));
+  const uword link = ((word >> kLinkShift) & ((1 << kLinkBits) - 1));
+  return type == branch && link == 0;
 }
 
 void PcRelativeTrampolineJumpPattern::Initialize() {
@@ -441,13 +449,23 @@
 
 intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
   // Calls to the type testing stubs look like:
+  //   ldr R9, ...
   //   ldr R3, [PP+idx]
   //   blx R9
+  // or
+  //   ldr R3, [PP+idx]
+  //   blx pc+<offset>
 
   // Ensure the caller of the type testing stub (whose return address is [pc_])
-  // branched via the `blx R9` instruction.
-  ASSERT(*reinterpret_cast<uint32_t*>(pc_ - Instr::kInstrSize) == 0xe12fff39);
-  const uword load_instr_end = pc_ - Instr::kInstrSize;
+  // branched via `blx R9` or a pc-relative call.
+  uword pc = pc_ - Instr::kInstrSize;
+  const uword blx_r9 = 0xe12fff39;
+  if (*reinterpret_cast<uint32_t*>(pc) != blx_r9) {
+    PcRelativeCallPattern pattern(pc);
+    RELEASE_ASSERT(pattern.IsValid());
+  }
+
+  const uword load_instr_end = pc;
 
   Register reg;
   intptr_t pool_index = -1;
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 65bfdb3..1ddbc90 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -11,9 +11,13 @@
 #endif
 
 #include "vm/allocation.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants.h"
 #include "vm/native_function.h"
+#include "vm/tagged_pointer.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
@@ -21,9 +25,7 @@
 class Code;
 class Object;
 class ObjectPool;
-class RawCode;
-class RawICData;
-class RawObject;
+class CodeLayout;
 
 class InstructionPattern : public AllStatic {
  public:
@@ -72,7 +74,7 @@
  public:
   CallPattern(uword pc, const Code& code);
 
-  RawCode* TargetCode() const;
+  CodePtr TargetCode() const;
   void SetTargetCode(const Code& code) const;
 
  private:
@@ -87,10 +89,10 @@
  public:
   ICCallPattern(uword pc, const Code& code);
 
-  RawObject* Data() const;
+  ObjectPtr Data() const;
   void SetData(const Object& data) const;
 
-  RawCode* TargetCode() const;
+  CodePtr TargetCode() const;
   void SetTargetCode(const Code& code) const;
 
  private:
@@ -106,7 +108,7 @@
  public:
   NativeCallPattern(uword pc, const Code& code);
 
-  RawCode* target() const;
+  CodePtr target() const;
   void set_target(const Code& target) const;
 
   NativeFunction native_function() const;
@@ -131,7 +133,7 @@
  public:
   explicit SwitchableCallPatternBase(const Code& code);
 
-  RawObject* data() const;
+  ObjectPtr data() const;
   void SetData(const Object& data) const;
 
  protected:
@@ -151,7 +153,7 @@
  public:
   SwitchableCallPattern(uword pc, const Code& code);
 
-  RawCode* target() const;
+  CodePtr target() const;
   void SetTarget(const Code& target) const;
 
  private:
@@ -166,7 +168,7 @@
  public:
   BareSwitchableCallPattern(uword pc, const Code& code);
 
-  RawCode* target() const;
+  CodePtr target() const;
   void SetTarget(const Code& target) const;
 
  private:
@@ -188,13 +190,13 @@
   const uword pc_;
 };
 
-class PcRelativeCallPattern : public ValueObject {
+class PcRelativeCallPatternBase : public ValueObject {
  public:
   // 24 bit signed integer which will get multiplied by 4.
-  static const intptr_t kLowerCallingRange = -(1 << 25);
+  static const intptr_t kLowerCallingRange = -(1 << 25) + Instr::kPCReadOffset;
   static const intptr_t kUpperCallingRange = (1 << 25) - 1;
 
-  explicit PcRelativeCallPattern(uword pc) : pc_(pc) {}
+  explicit PcRelativeCallPatternBase(uword pc) : pc_(pc) {}
 
   static const int kLengthInBytes = 1 * Instr::kInstrSize;
 
@@ -217,12 +219,25 @@
 #endif
   }
 
-  bool IsValid() const;
-
- private:
+ protected:
   uword pc_;
 };
 
+class PcRelativeCallPattern : public PcRelativeCallPatternBase {
+ public:
+  explicit PcRelativeCallPattern(uword pc) : PcRelativeCallPatternBase(pc) {}
+
+  bool IsValid() const;
+};
+
+class PcRelativeTailCallPattern : public PcRelativeCallPatternBase {
+ public:
+  explicit PcRelativeTailCallPattern(uword pc)
+      : PcRelativeCallPatternBase(pc) {}
+
+  bool IsValid() const;
+};
+
 // Instruction pattern for a tail call to a signed 32-bit PC-relative offset
 //
 // The AOT compiler can emit PC-relative calls. If the destination of such a
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 3e3db82..037e777 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -8,7 +8,6 @@
 #include "vm/instructions.h"
 #include "vm/instructions_arm64.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/object.h"
@@ -66,9 +65,8 @@
   ASSERT(reg == R5);
 }
 
-RawCode* NativeCallPattern::target() const {
-  return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr NativeCallPattern::target() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
 }
 
 void NativeCallPattern::set_target(const Code& target) const {
@@ -109,7 +107,7 @@
     // Case 2.
     intptr_t value = 0;
     start = DecodeLoadWordImmediate(end, reg, &value);
-    *obj = reinterpret_cast<RawObject*>(value);
+    *obj = static_cast<ObjectPtr>(value);
   }
   return start;
 }
@@ -373,9 +371,8 @@
   instr->SetInstructionBits(instr->InstructionBits() | B22);
 }
 
-RawCode* CallPattern::TargetCode() const {
-  return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr CallPattern::TargetCode() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
 }
 
 void CallPattern::SetTargetCode(const Code& target) const {
@@ -383,7 +380,7 @@
   // No need to flush the instruction cache, since the code is not modified.
 }
 
-RawObject* ICCallPattern::Data() const {
+ObjectPtr ICCallPattern::Data() const {
   return object_pool_.ObjectAt(data_pool_index_);
 }
 
@@ -392,8 +389,8 @@
   object_pool_.SetObjectAt(data_pool_index_, data);
 }
 
-RawCode* ICCallPattern::TargetCode() const {
-  return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr ICCallPattern::TargetCode() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
 }
 
 void ICCallPattern::SetTargetCode(const Code& target) const {
@@ -406,7 +403,7 @@
       data_pool_index_(-1),
       target_pool_index_(-1) {}
 
-RawObject* SwitchableCallPatternBase::data() const {
+ObjectPtr SwitchableCallPatternBase::data() const {
   return object_pool_.ObjectAt(data_pool_index_);
 }
 
@@ -432,8 +429,8 @@
   target_pool_index_ = pool_index + 1;
 }
 
-RawCode* SwitchableCallPattern::target() const {
-  return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr SwitchableCallPattern::target() const {
+  return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
 }
 
 void SwitchableCallPattern::SetTarget(const Code& target) const {
@@ -458,13 +455,13 @@
   target_pool_index_ = pool_index + 1;
 }
 
-RawCode* BareSwitchableCallPattern::target() const {
+CodePtr BareSwitchableCallPattern::target() const {
   const uword pc = object_pool_.RawValueAt(target_pool_index_);
-  auto rct = Isolate::Current()->reverse_pc_lookup_cache();
+  auto rct = IsolateGroup::Current()->reverse_pc_lookup_cache();
   if (rct->Contains(pc)) {
     return rct->Lookup(pc);
   }
-  rct = Dart::vm_isolate()->reverse_pc_lookup_cache();
+  rct = Dart::vm_isolate()->group()->reverse_pc_lookup_cache();
   if (rct->Contains(pc)) {
     return rct->Lookup(pc);
   }
@@ -494,6 +491,13 @@
   return (word >> 26) == branch_link;
 }
 
+bool PcRelativeTailCallPattern::IsValid() const {
+  // b <offset>
+  const uint32_t word = *reinterpret_cast<uint32_t*>(pc_);
+  const uint32_t branch_link = 0x5;
+  return (word >> 26) == branch_link;
+}
+
 void PcRelativeTrampolineJumpPattern::Initialize() {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   uint32_t* pattern = reinterpret_cast<uint32_t*>(pattern_start_);
@@ -551,13 +555,23 @@
 
 intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
   // Calls to the type testing stubs look like:
+  //   ldr R9, ...
   //   ldr R3, [PP+idx]
   //   blr R9
+  // or
+  //   ldr R3, [PP+idx]
+  //   blr pc+<offset>
 
   // Ensure the caller of the type testing stub (whose return address is [pc_])
-  // branched via the `blr R9` instruction.
-  ASSERT(*reinterpret_cast<uint32_t*>(pc_ - Instr::kInstrSize) == 0xd63f0120);
-  const uword load_instr_end = pc_ - Instr::kInstrSize;
+  // branched via `blr R9` or a pc-relative call.
+  uword pc = pc_ - Instr::kInstrSize;
+  const uword blr_r9 = 0xd63f0120;
+  if (*reinterpret_cast<uint32_t*>(pc) != blr_r9) {
+    PcRelativeCallPattern pattern(pc);
+    RELEASE_ASSERT(pattern.IsValid());
+  }
+
+  const uword load_instr_end = pc;
 
   Register reg;
   intptr_t pool_index = -1;
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index dfbf7d3..4a8f7e2 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -11,18 +11,20 @@
 #endif
 
 #include "vm/allocation.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants.h"
 #include "vm/native_function.h"
+#include "vm/tagged_pointer.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
 class Code;
 class ICData;
+class Object;
 class ObjectPool;
-class RawCode;
-class RawICData;
-class RawObject;
 
 class InstructionPattern : public AllStatic {
  public:
@@ -82,7 +84,7 @@
  public:
   CallPattern(uword pc, const Code& code);
 
-  RawCode* TargetCode() const;
+  CodePtr TargetCode() const;
   void SetTargetCode(const Code& target) const;
 
  private:
@@ -97,10 +99,10 @@
  public:
   ICCallPattern(uword pc, const Code& caller_code);
 
-  RawObject* Data() const;
+  ObjectPtr Data() const;
   void SetData(const Object& data) const;
 
-  RawCode* TargetCode() const;
+  CodePtr TargetCode() const;
   void SetTargetCode(const Code& target) const;
 
  private:
@@ -116,7 +118,7 @@
  public:
   NativeCallPattern(uword pc, const Code& code);
 
-  RawCode* target() const;
+  CodePtr target() const;
   void set_target(const Code& target) const;
 
   NativeFunction native_function() const;
@@ -141,7 +143,7 @@
  public:
   explicit SwitchableCallPatternBase(const Code& code);
 
-  RawObject* data() const;
+  ObjectPtr data() const;
   void SetData(const Object& data) const;
 
  protected:
@@ -161,7 +163,7 @@
  public:
   SwitchableCallPattern(uword pc, const Code& code);
 
-  RawCode* target() const;
+  CodePtr target() const;
   void SetTarget(const Code& target) const;
 
  private:
@@ -176,7 +178,7 @@
  public:
   BareSwitchableCallPattern(uword pc, const Code& code);
 
-  RawCode* target() const;
+  CodePtr target() const;
   void SetTarget(const Code& target) const;
 
  private:
@@ -198,13 +200,13 @@
   const uword pc_;
 };
 
-class PcRelativeCallPattern : public ValueObject {
+class PcRelativePatternBase : public ValueObject {
  public:
   // 26 bit signed integer which will get multiplied by 4.
   static const intptr_t kLowerCallingRange = -(1 << 27);
   static const intptr_t kUpperCallingRange = (1 << 27) - 1;
 
-  explicit PcRelativeCallPattern(uword pc) : pc_(pc) {}
+  explicit PcRelativePatternBase(uword pc) : pc_(pc) {}
 
   static const int kLengthInBytes = 1 * Instr::kInstrSize;
 
@@ -229,10 +231,24 @@
 
   bool IsValid() const;
 
- private:
+ protected:
   uword pc_;
 };
 
+class PcRelativeCallPattern : public PcRelativePatternBase {
+ public:
+  explicit PcRelativeCallPattern(uword pc) : PcRelativePatternBase(pc) {}
+
+  bool IsValid() const;
+};
+
+class PcRelativeTailCallPattern : public PcRelativePatternBase {
+ public:
+  explicit PcRelativeTailCallPattern(uword pc) : PcRelativePatternBase(pc) {}
+
+  bool IsValid() const;
+};
+
 // Instruction pattern for a tail call to a signed 32-bit PC-relative offset
 //
 // The AOT compiler can emit PC-relative calls. If the destination of such a
diff --git a/runtime/vm/instructions_kbc.cc b/runtime/vm/instructions_kbc.cc
index a8a3608..b427738 100644
--- a/runtime/vm/instructions_kbc.cc
+++ b/runtime/vm/instructions_kbc.cc
@@ -13,7 +13,7 @@
 
 namespace dart {
 
-RawTypedData* KBCNativeCallPattern::GetNativeEntryDataAt(
+TypedDataPtr KBCNativeCallPattern::GetNativeEntryDataAt(
     uword pc,
     const Bytecode& bytecode) {
   ASSERT(bytecode.ContainsInstructionAt(pc));
diff --git a/runtime/vm/instructions_kbc.h b/runtime/vm/instructions_kbc.h
index d210a28..5bfdb11 100644
--- a/runtime/vm/instructions_kbc.h
+++ b/runtime/vm/instructions_kbc.h
@@ -15,7 +15,7 @@
 
 class KBCNativeCallPattern : public AllStatic {
  public:
-  static RawTypedData* GetNativeEntryDataAt(uword pc, const Bytecode& bytecode);
+  static TypedDataPtr GetNativeEntryDataAt(uword pc, const Bytecode& bytecode);
 };
 
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 2225a3e..cbeba5f 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -86,21 +86,37 @@
 }
 
 intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+  static int16_t indirect_call_pattern[] = {
+      0xff, -1 /* 0x53 or 0x56 */, 0x07,  // callq [RBX/RSI + 0x7]
+  };
+  static int16_t direct_call_pattern[] = {
+      0xe8, -1, -1, -1, -1,  // callq [PC + <offset>]
+  };
   static int16_t pattern_disp8[] = {
       0x4d, 0x8b, 0x4f, -1,               // movq R9, [PP + offset]
-      0xff, -1 /* 0x53 or 0x56 */, 0x07,  // callq [RBX/RSI + 0x7]
   };
   static int16_t pattern_disp32[] = {
       0x4d, 0x8b, 0x8f, -1, -1, -1, -1,   // movq R9, [PP + offset]
-      0xff, -1 /* 0x53 or 0x56 */, 0x07,  // callq [RBX/RSI + 0x7]
   };
-  if (MatchesPattern(pc_, pattern_disp8, ARRAY_SIZE(pattern_disp8))) {
-    return IndexFromPPLoadDisp8(pc_ - 4);
-  } else if (MatchesPattern(pc_, pattern_disp32, ARRAY_SIZE(pattern_disp32))) {
-    return IndexFromPPLoadDisp32(pc_ - 7);
+
+  uword pc = pc_;
+  if (MatchesPattern(pc, direct_call_pattern,
+                     ARRAY_SIZE(direct_call_pattern))) {
+    pc -= ARRAY_SIZE(direct_call_pattern);
+  } else if (MatchesPattern(pc, indirect_call_pattern,
+                            ARRAY_SIZE(indirect_call_pattern))) {
+    pc -= ARRAY_SIZE(indirect_call_pattern);
   } else {
     FATAL1("Failed to decode at %" Px, pc_);
   }
+
+  if (MatchesPattern(pc, pattern_disp8, ARRAY_SIZE(pattern_disp8))) {
+    return IndexFromPPLoadDisp8(pc - 1);
+  } else if (MatchesPattern(pc, pattern_disp32, ARRAY_SIZE(pattern_disp32))) {
+    return IndexFromPPLoadDisp32(pc - 4);
+  } else {
+    FATAL1("Failed to decode at %" Px, pc);
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/instructions_x64.h b/runtime/vm/instructions_x64.h
index da8f077..81e69c6 100644
--- a/runtime/vm/instructions_x64.h
+++ b/runtime/vm/instructions_x64.h
@@ -180,6 +180,15 @@
   uword pattern_start_;
 };
 
+class PcRelativeTailCallPattern : public PcRelativeTrampolineJumpPattern {
+ public:
+  static const intptr_t kLowerCallingRange = -(1ul << 31) + kLengthInBytes;
+  static const intptr_t kUpperCallingRange = (1ul << 31) - 1;
+
+  explicit PcRelativeTailCallPattern(uword pc)
+      : PcRelativeTrampolineJumpPattern(pc) {}
+};
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_INSTRUCTIONS_X64_H_
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index cb8c0e3..a48d019 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -10,6 +10,7 @@
 
 #include "vm/interpreter.h"
 
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
@@ -75,7 +76,7 @@
   jmp_buf buffer_;
 
  private:
-  RawObject** fp_;
+  ObjectPtr* fp_;
   Interpreter* interpreter_;
   InterpreterSetjmpBuffer* link_;
 
@@ -85,12 +86,13 @@
   DISALLOW_COPY_AND_ASSIGN(InterpreterSetjmpBuffer);
 };
 
-DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) {
-  return reinterpret_cast<RawObject**>(FP[kKBCSavedCallerFpSlotFromFp]);
+DART_FORCE_INLINE static ObjectPtr* SavedCallerFP(ObjectPtr* FP) {
+  return reinterpret_cast<ObjectPtr*>(
+      static_cast<uword>(FP[kKBCSavedCallerFpSlotFromFp]));
 }
 
-DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP,
-                                                    intptr_t argc) {
+DART_FORCE_INLINE static ObjectPtr* FrameArguments(ObjectPtr* FP,
+                                                   intptr_t argc) {
   return FP - (kKBCDartFrameFixedSize + argc);
 }
 
@@ -99,34 +101,34 @@
 class InterpreterHelpers {
  public:
 #define DEFINE_CASTS(Type)                                                     \
-  DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) {           \
+  DART_FORCE_INLINE static Type##Ptr CastTo##Type(ObjectPtr obj) {             \
     ASSERT((k##Type##Cid == kSmiCid)                                           \
                ? !obj->IsHeapObject()                                          \
                : (k##Type##Cid == kIntegerCid)                                 \
                      ? (!obj->IsHeapObject() || obj->IsMint())                 \
                      : obj->Is##Type());                                       \
-    return reinterpret_cast<Raw##Type*>(obj);                                  \
+    return static_cast<Type##Ptr>(obj);                                        \
   }
   CLASS_LIST(DEFINE_CASTS)
 #undef DEFINE_CASTS
 
-  DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) {
+  DART_FORCE_INLINE static SmiPtr GetClassIdAsSmi(ObjectPtr obj) {
     return Smi::New(obj->IsHeapObject() ? obj->GetClassId()
                                         : static_cast<intptr_t>(kSmiCid));
   }
 
-  DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) {
+  DART_FORCE_INLINE static intptr_t GetClassId(ObjectPtr obj) {
     return obj->IsHeapObject() ? obj->GetClassId()
                                : static_cast<intptr_t>(kSmiCid);
   }
 
-  DART_FORCE_INLINE static RawTypeArguments* GetTypeArguments(
+  DART_FORCE_INLINE static TypeArgumentsPtr GetTypeArguments(
       Thread* thread,
-      RawInstance* instance) {
-    RawClass* instance_class =
+      InstancePtr instance) {
+    ClassPtr instance_class =
         thread->isolate()->class_table()->At(GetClassId(instance));
     return instance_class->ptr()->num_type_arguments_ > 0
-               ? reinterpret_cast<RawTypeArguments**>(instance->ptr())
+               ? reinterpret_cast<TypeArgumentsPtr*>(instance->ptr())
                      [instance_class->ptr()
                           ->host_type_arguments_field_offset_in_words_]
                : TypeArguments::null();
@@ -135,57 +137,56 @@
   // The usage counter is actually a 'hotness' counter.
   // For an instance call, both the usage counters of the caller and of the
   // calle will get incremented, as well as the ICdata counter at the call site.
-  DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) {
+  DART_FORCE_INLINE static void IncrementUsageCounter(FunctionPtr f) {
     f->ptr()->usage_counter_++;
   }
 
-  DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries,
+  DART_FORCE_INLINE static void IncrementICUsageCount(ObjectPtr* entries,
                                                       intptr_t offset,
                                                       intptr_t args_tested) {
     const intptr_t count_offset = ICData::CountIndexFor(args_tested);
     const intptr_t raw_smi_old =
-        reinterpret_cast<intptr_t>(entries[offset + count_offset]);
+        static_cast<intptr_t>(entries[offset + count_offset]);
     const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);
     *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = raw_smi_new;
   }
 
-  DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) {
-    return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) &&
-           (reinterpret_cast<intptr_t>(index) <
-            reinterpret_cast<intptr_t>(length));
+  DART_FORCE_INLINE static bool CheckIndex(SmiPtr index, SmiPtr length) {
+    return !index->IsHeapObject() && (static_cast<intptr_t>(index) >= 0) &&
+           (static_cast<intptr_t>(index) < static_cast<intptr_t>(length));
   }
 
-  DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(RawArray* argdesc) {
-    return Smi::Value(*reinterpret_cast<RawSmi**>(
+  DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(ArrayPtr argdesc) {
+    return Smi::Value(*reinterpret_cast<SmiPtr*>(
         reinterpret_cast<uword>(argdesc->ptr()) +
         Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex)));
   }
 
-  DART_FORCE_INLINE static intptr_t ArgDescArgCount(RawArray* argdesc) {
-    return Smi::Value(*reinterpret_cast<RawSmi**>(
+  DART_FORCE_INLINE static intptr_t ArgDescArgCount(ArrayPtr argdesc) {
+    return Smi::Value(*reinterpret_cast<SmiPtr*>(
         reinterpret_cast<uword>(argdesc->ptr()) +
         Array::element_offset(ArgumentsDescriptor::kCountIndex)));
   }
 
-  DART_FORCE_INLINE static intptr_t ArgDescArgSize(RawArray* argdesc) {
-    return Smi::Value(*reinterpret_cast<RawSmi**>(
+  DART_FORCE_INLINE static intptr_t ArgDescArgSize(ArrayPtr argdesc) {
+    return Smi::Value(*reinterpret_cast<SmiPtr*>(
         reinterpret_cast<uword>(argdesc->ptr()) +
         Array::element_offset(ArgumentsDescriptor::kSizeIndex)));
   }
 
-  DART_FORCE_INLINE static intptr_t ArgDescPosCount(RawArray* argdesc) {
-    return Smi::Value(*reinterpret_cast<RawSmi**>(
+  DART_FORCE_INLINE static intptr_t ArgDescPosCount(ArrayPtr argdesc) {
+    return Smi::Value(*reinterpret_cast<SmiPtr*>(
         reinterpret_cast<uword>(argdesc->ptr()) +
         Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex)));
   }
 
-  DART_FORCE_INLINE static RawBytecode* FrameBytecode(RawObject** FP) {
+  DART_FORCE_INLINE static BytecodePtr FrameBytecode(ObjectPtr* FP) {
     ASSERT(GetClassId(FP[kKBCPcMarkerSlotFromFp]) == kBytecodeCid);
-    return static_cast<RawBytecode*>(FP[kKBCPcMarkerSlotFromFp]);
+    return static_cast<BytecodePtr>(FP[kKBCPcMarkerSlotFromFp]);
   }
 
-  DART_FORCE_INLINE static bool FieldNeedsGuardUpdate(RawField* field,
-                                                      RawObject* value) {
+  DART_FORCE_INLINE static bool FieldNeedsGuardUpdate(FieldPtr field,
+                                                      ObjectPtr value) {
     // The interpreter should never see a cloned field.
     ASSERT(field->ptr()->owner_->GetClassId() != kFieldCid);
 
@@ -231,56 +232,57 @@
     return false;
   }
 
-  DART_FORCE_INLINE static bool IsFinalized(RawClass* cls) {
+  DART_FORCE_INLINE static bool IsFinalized(ClassPtr cls) {
     return Class::ClassFinalizedBits::decode(cls->ptr()->state_bits_) ==
-           RawClass::kFinalized;
+           ClassLayout::kFinalized;
   }
 };
 
-DART_FORCE_INLINE static const KBCInstr* SavedCallerPC(RawObject** FP) {
-  return reinterpret_cast<const KBCInstr*>(FP[kKBCSavedCallerPcSlotFromFp]);
+DART_FORCE_INLINE static const KBCInstr* SavedCallerPC(ObjectPtr* FP) {
+  return reinterpret_cast<const KBCInstr*>(
+      static_cast<uword>(FP[kKBCSavedCallerPcSlotFromFp]));
 }
 
-DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) {
-  RawFunction* function = static_cast<RawFunction*>(FP[kKBCFunctionSlotFromFp]);
+DART_FORCE_INLINE static FunctionPtr FrameFunction(ObjectPtr* FP) {
+  FunctionPtr function = static_cast<FunctionPtr>(FP[kKBCFunctionSlotFromFp]);
   ASSERT(InterpreterHelpers::GetClassId(function) == kFunctionCid ||
          InterpreterHelpers::GetClassId(function) == kNullCid);
   return function;
 }
 
-DART_FORCE_INLINE static RawObject* InitializeHeader(uword addr,
-                                                     intptr_t class_id,
-                                                     intptr_t instance_size) {
+DART_FORCE_INLINE static ObjectPtr InitializeHeader(uword addr,
+                                                    intptr_t class_id,
+                                                    intptr_t instance_size) {
   uint32_t tags = 0;
-  tags = RawObject::ClassIdTag::update(class_id, tags);
-  tags = RawObject::SizeTag::update(instance_size, tags);
-  tags = RawObject::OldBit::update(false, tags);
-  tags = RawObject::OldAndNotMarkedBit::update(false, tags);
-  tags = RawObject::OldAndNotRememberedBit::update(false, tags);
-  tags = RawObject::NewBit::update(true, tags);
+  tags = ObjectLayout::ClassIdTag::update(class_id, tags);
+  tags = ObjectLayout::SizeTag::update(instance_size, tags);
+  tags = ObjectLayout::OldBit::update(false, tags);
+  tags = ObjectLayout::OldAndNotMarkedBit::update(false, tags);
+  tags = ObjectLayout::OldAndNotRememberedBit::update(false, tags);
+  tags = ObjectLayout::NewBit::update(true, tags);
   // Also writes zero in the hash_ field.
   *reinterpret_cast<uword*>(addr + Object::tags_offset()) = tags;
-  return RawObject::FromAddr(addr);
+  return ObjectLayout::FromAddr(addr);
 }
 
 DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
                                           intptr_t class_id,
                                           intptr_t instance_size,
-                                          RawObject** result) {
+                                          ObjectPtr* result) {
   ASSERT(instance_size > 0);
   ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
 
-  const uword start = thread->top();
 #ifndef PRODUCT
-  auto table = thread->isolate_group()->class_table();
+  auto table = thread->isolate_group()->shared_class_table();
   if (UNLIKELY(table->TraceAllocationFor(class_id))) {
     return false;
   }
 #endif
-  const intptr_t remaining = thread->end() - start;
+  const uword top = thread->top();
+  const intptr_t remaining = thread->end() - top;
   if (LIKELY(remaining >= instance_size)) {
-    thread->set_top(start + instance_size);
-    *result = InitializeHeader(start, class_id, instance_size);
+    thread->set_top(top + instance_size);
+    *result = InitializeHeader(top, class_id, instance_size);
     return true;
   }
   return false;
@@ -293,14 +295,13 @@
 }
 
 bool LookupCache::Lookup(intptr_t receiver_cid,
-                         RawString* function_name,
-                         RawArray* arguments_descriptor,
-                         RawFunction** target) const {
+                         StringPtr function_name,
+                         ArrayPtr arguments_descriptor,
+                         FunctionPtr* target) const {
   ASSERT(receiver_cid != kIllegalCid);  // Sentinel value.
 
-  const intptr_t hash = receiver_cid ^
-                        reinterpret_cast<intptr_t>(function_name) ^
-                        reinterpret_cast<intptr_t>(arguments_descriptor);
+  const intptr_t hash = receiver_cid ^ static_cast<intptr_t>(function_name) ^
+                        static_cast<intptr_t>(arguments_descriptor);
   const intptr_t probe1 = hash & kTableMask;
   if (entries_[probe1].receiver_cid == receiver_cid &&
       entries_[probe1].function_name == function_name &&
@@ -321,17 +322,16 @@
 }
 
 void LookupCache::Insert(intptr_t receiver_cid,
-                         RawString* function_name,
-                         RawArray* arguments_descriptor,
-                         RawFunction* target) {
+                         StringPtr function_name,
+                         ArrayPtr arguments_descriptor,
+                         FunctionPtr target) {
   // Otherwise we have to clear the cache or rehash on scavenges too.
   ASSERT(function_name->IsOldObject());
   ASSERT(arguments_descriptor->IsOldObject());
   ASSERT(target->IsOldObject());
 
-  const intptr_t hash = receiver_cid ^
-                        reinterpret_cast<intptr_t>(function_name) ^
-                        reinterpret_cast<intptr_t>(arguments_descriptor);
+  const intptr_t hash = receiver_cid ^ static_cast<intptr_t>(function_name) ^
+                        static_cast<intptr_t>(arguments_descriptor);
   const intptr_t probe1 = hash & kTableMask;
   if (entries_[probe1].receiver_cid == kIllegalCid) {
     entries_[probe1].receiver_cid = receiver_cid;
@@ -357,7 +357,11 @@
 }
 
 Interpreter::Interpreter()
-    : stack_(NULL), fp_(NULL), pp_(NULL), argdesc_(NULL), lookup_cache_() {
+    : stack_(NULL),
+      fp_(NULL),
+      pp_(nullptr),
+      argdesc_(nullptr),
+      lookup_cache_() {
   // Setup interpreter support first. Some of this information is needed to
   // setup the architecture state.
   // We allocate the stack here, the size is computed as the sum of
@@ -501,15 +505,15 @@
 typedef double (*InterpreterLeafFloatRuntimeCall)(double d0, double d1);
 
 void Interpreter::Exit(Thread* thread,
-                       RawObject** base,
-                       RawObject** frame,
+                       ObjectPtr* base,
+                       ObjectPtr* frame,
                        const KBCInstr* pc) {
   frame[0] = Function::null();
   frame[1] = Bytecode::null();
-  frame[2] = reinterpret_cast<RawObject*>(reinterpret_cast<uword>(pc));
-  frame[3] = reinterpret_cast<RawObject*>(base);
+  frame[2] = static_cast<ObjectPtr>(reinterpret_cast<uword>(pc));
+  frame[3] = static_cast<ObjectPtr>(reinterpret_cast<uword>(base));
 
-  RawObject** exit_fp = frame + kKBCDartFrameFixedSize;
+  ObjectPtr* exit_fp = frame + kKBCDartFrameFixedSize;
   thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp));
   fp_ = exit_fp;
 
@@ -525,8 +529,8 @@
 void Interpreter::Unexit(Thread* thread) {
 #if !defined(PRODUCT)
   // For the profiler.
-  RawObject** exit_fp =
-      reinterpret_cast<RawObject**>(thread->top_exit_frame_info());
+  ObjectPtr* exit_fp =
+      reinterpret_cast<ObjectPtr*>(thread->top_exit_frame_info());
   ASSERT(exit_fp != 0);
   pc_ = SavedCallerPC(exit_fp);
   fp_ = SavedCallerFP(exit_fp);
@@ -535,7 +539,7 @@
 }
 
 // Calling into runtime may trigger garbage collection and relocate objects,
-// so all RawObject* pointers become outdated and should not be used across
+// so all ObjectPtr pointers become outdated and should not be used across
 // runtime calls.
 // Note: functions below are marked DART_NOINLINE to recover performance where
 // inlining these functions into the interpreter loop seemed to cause some code
@@ -574,15 +578,25 @@
   }
 }
 
+extern "C" {
+// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct
+// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is
+// passed/returned different from a pointer.
+typedef uword /*ObjectPtr*/ (*invokestub)(uword /*CodePtr*/ code,
+                                          uword /*ArrayPtr*/ argdesc,
+                                          ObjectPtr* arg0,
+                                          Thread* thread);
+}
+
 DART_NOINLINE bool Interpreter::InvokeCompiled(Thread* thread,
-                                               RawFunction* function,
-                                               RawObject** call_base,
-                                               RawObject** call_top,
+                                               FunctionPtr function,
+                                               ObjectPtr* call_base,
+                                               ObjectPtr* call_top,
                                                const KBCInstr** pc,
-                                               RawObject*** FP,
-                                               RawObject*** SP) {
+                                               ObjectPtr** FP,
+                                               ObjectPtr** SP) {
   ASSERT(Function::HasCode(function));
-  RawCode* volatile code = function->ptr()->code_;
+  CodePtr code = function->ptr()->code_;
   ASSERT(code != StubCode::LazyCompile().raw());
   // TODO(regis): Once we share the same stack, try to invoke directly.
 #if defined(DEBUG)
@@ -592,11 +606,9 @@
   }
 #endif
   // On success, returns a RawInstance.  On failure, a RawError.
-  typedef RawObject* (*invokestub)(RawCode * code, RawArray * argdesc,
-                                   RawObject * *arg0, Thread * thread);
   invokestub volatile entrypoint = reinterpret_cast<invokestub>(
       StubCode::InvokeDartCodeFromBytecode().EntryPoint());
-  RawObject* volatile result;
+  ObjectPtr result;
   Exit(thread, *FP, call_top + 1, *pc);
   {
     InterpreterSetjmpBuffer buffer(this);
@@ -608,14 +620,15 @@
       if (!thread->os_thread()->HasStackHeadroom()) {
         thread->SetStackLimit(-1);
       }
-      result = bit_copy<RawObject*, int64_t>(
-          Simulator::Current()->Call(reinterpret_cast<intptr_t>(entrypoint),
-                                     reinterpret_cast<intptr_t>(code),
-                                     reinterpret_cast<intptr_t>(argdesc_),
-                                     reinterpret_cast<intptr_t>(call_base),
-                                     reinterpret_cast<intptr_t>(thread)));
+      result = bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
+          reinterpret_cast<intptr_t>(entrypoint), static_cast<intptr_t>(code),
+          static_cast<intptr_t>(argdesc_),
+          reinterpret_cast<intptr_t>(call_base),
+          reinterpret_cast<intptr_t>(thread)));
 #else
-      result = entrypoint(code, argdesc_, call_base, thread);
+      result = static_cast<ObjectPtr>(entrypoint(static_cast<uword>(code),
+                                                 static_cast<uword>(argdesc_),
+                                                 call_base, thread));
 #endif
       ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId);
       ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
@@ -645,7 +658,7 @@
       }
       UNREACHABLE();
     }
-    if (RawObject::IsErrorClassId(result_cid)) {
+    if (IsErrorClassId(result_cid)) {
       // Unwind to entry frame.
       fp_ = *FP;
       pc_ = SavedCallerPC(fp_);
@@ -663,12 +676,12 @@
 }
 
 DART_FORCE_INLINE bool Interpreter::InvokeBytecode(Thread* thread,
-                                                   RawFunction* function,
-                                                   RawObject** call_base,
-                                                   RawObject** call_top,
+                                                   FunctionPtr function,
+                                                   ObjectPtr* call_base,
+                                                   ObjectPtr* call_top,
                                                    const KBCInstr** pc,
-                                                   RawObject*** FP,
-                                                   RawObject*** SP) {
+                                                   ObjectPtr** FP,
+                                                   ObjectPtr** SP) {
   ASSERT(Function::HasBytecode(function));
 #if defined(DEBUG)
   if (IsTracingExecution()) {
@@ -677,13 +690,14 @@
               Function::Handle(function).ToFullyQualifiedCString());
   }
 #endif
-  RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;
+  ObjectPtr* callee_fp = call_top + kKBCDartFrameFixedSize;
   ASSERT(function == FrameFunction(callee_fp));
-  RawBytecode* bytecode = function->ptr()->bytecode_;
+  BytecodePtr bytecode = function->ptr()->bytecode_;
   callee_fp[kKBCPcMarkerSlotFromFp] = bytecode;
   callee_fp[kKBCSavedCallerPcSlotFromFp] =
-      reinterpret_cast<RawObject*>(reinterpret_cast<uword>(*pc));
-  callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
+      static_cast<ObjectPtr>(reinterpret_cast<uword>(*pc));
+  callee_fp[kKBCSavedCallerFpSlotFromFp] =
+      static_cast<ObjectPtr>(reinterpret_cast<uword>(*FP));
   pp_ = bytecode->ptr()->object_pool_;
   *pc = reinterpret_cast<const KBCInstr*>(bytecode->ptr()->instructions_);
   NOT_IN_PRODUCT(pc_ = *pc);  // For the profiler.
@@ -694,13 +708,13 @@
 }
 
 DART_FORCE_INLINE bool Interpreter::Invoke(Thread* thread,
-                                           RawObject** call_base,
-                                           RawObject** call_top,
+                                           ObjectPtr* call_base,
+                                           ObjectPtr* call_top,
                                            const KBCInstr** pc,
-                                           RawObject*** FP,
-                                           RawObject*** SP) {
-  RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;
-  RawFunction* function = FrameFunction(callee_fp);
+                                           ObjectPtr** FP,
+                                           ObjectPtr** SP) {
+  ObjectPtr* callee_fp = call_top + kKBCDartFrameFixedSize;
+  FunctionPtr function = FrameFunction(callee_fp);
 
   for (;;) {
     if (Function::HasCode(function)) {
@@ -726,12 +740,12 @@
 }
 
 DART_FORCE_INLINE bool Interpreter::InstanceCall(Thread* thread,
-                                                 RawString* target_name,
-                                                 RawObject** call_base,
-                                                 RawObject** top,
+                                                 StringPtr target_name,
+                                                 ObjectPtr* call_base,
+                                                 ObjectPtr* top,
                                                  const KBCInstr** pc,
-                                                 RawObject*** FP,
-                                                 RawObject*** SP) {
+                                                 ObjectPtr** FP,
+                                                 ObjectPtr** SP) {
   const intptr_t type_args_len =
       InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
   const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
@@ -739,7 +753,7 @@
   intptr_t receiver_cid =
       InterpreterHelpers::GetClassId(call_base[receiver_idx]);
 
-  RawFunction* target;
+  FunctionPtr target;
   if (UNLIKELY(!lookup_cache_.Lookup(receiver_cid, target_name, argdesc_,
                                      &target))) {
     // Table lookup miss.
@@ -757,9 +771,9 @@
       return false;
     }
 
-    target = static_cast<RawFunction*>(top[4]);
-    target_name = static_cast<RawString*>(top[2]);
-    argdesc_ = static_cast<RawArray*>(top[3]);
+    target = static_cast<FunctionPtr>(top[4]);
+    target_name = static_cast<StringPtr>(top[2]);
+    argdesc_ = static_cast<ArrayPtr>(top[3]);
     ASSERT(target->IsFunction());
     lookup_cache_.Insert(receiver_cid, target_name, argdesc_, target);
   }
@@ -969,7 +983,7 @@
 #define UNBOX_INT64(value, obj, selector)                                      \
   int64_t value;                                                               \
   {                                                                            \
-    word raw_value = reinterpret_cast<word>(obj);                              \
+    word raw_value = static_cast<word>(obj);                                   \
     if (LIKELY((raw_value & kSmiTagMask) == kSmiTag)) {                        \
       value = raw_value >> kSmiTagShift;                                       \
     } else {                                                                   \
@@ -1045,8 +1059,8 @@
 
 bool Interpreter::CopyParameters(Thread* thread,
                                  const KBCInstr** pc,
-                                 RawObject*** FP,
-                                 RawObject*** SP,
+                                 ObjectPtr** FP,
+                                 ObjectPtr** SP,
                                  const intptr_t num_fixed_params,
                                  const intptr_t num_opt_pos_params,
                                  const intptr_t num_opt_named_params) {
@@ -1064,7 +1078,7 @@
   }
 
   // Copy all passed position arguments.
-  RawObject** first_arg = FrameArguments(*FP, arg_count);
+  ObjectPtr* first_arg = FrameArguments(*FP, arg_count);
   memmove(*FP, first_arg, pos_count * kWordSize);
 
   if (num_opt_named_params != 0) {
@@ -1073,7 +1087,7 @@
     // default values encoded as pairs of LoadConstant instructions that
     // follows the entry point and find matching values via arguments
     // descriptor.
-    RawObject** argdesc_data = argdesc_->ptr()->data();
+    ObjectPtr* argdesc_data = argdesc_->ptr()->data();
 
     intptr_t i = 0;  // argument position
     intptr_t j = 0;  // parameter position
@@ -1087,11 +1101,11 @@
       const uint8_t reg = KernelBytecode::DecodeA(load_name);
       ASSERT(reg == KernelBytecode::DecodeA(load_value));
 
-      RawString* name = static_cast<RawString*>(
+      StringPtr name = static_cast<StringPtr>(
           LOAD_CONSTANT(KernelBytecode::DecodeE(load_name)));
       if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
         // Parameter was passed. Fetch passed value.
-        const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
+        const intptr_t arg_index = Smi::Value(static_cast<SmiPtr>(
             argdesc_data[ArgumentsDescriptor::position_index(i)]));
         (*FP)[reg] = first_arg[arg_index];
         ++i;  // Consume passed argument.
@@ -1159,28 +1173,28 @@
 
 bool Interpreter::AssertAssignable(Thread* thread,
                                    const KBCInstr* pc,
-                                   RawObject** FP,
-                                   RawObject** call_top,
-                                   RawObject** args,
-                                   RawSubtypeTestCache* cache) {
-  RawObject* null_value = Object::null();
+                                   ObjectPtr* FP,
+                                   ObjectPtr* call_top,
+                                   ObjectPtr* args,
+                                   SubtypeTestCachePtr cache) {
+  ObjectPtr null_value = Object::null();
   if (cache != null_value) {
-    RawInstance* instance = static_cast<RawInstance*>(args[0]);
-    RawTypeArguments* instantiator_type_arguments =
-        static_cast<RawTypeArguments*>(args[2]);
-    RawTypeArguments* function_type_arguments =
-        static_cast<RawTypeArguments*>(args[3]);
+    InstancePtr instance = static_cast<InstancePtr>(args[0]);
+    TypeArgumentsPtr instantiator_type_arguments =
+        static_cast<TypeArgumentsPtr>(args[2]);
+    TypeArgumentsPtr function_type_arguments =
+        static_cast<TypeArgumentsPtr>(args[3]);
 
     const intptr_t cid = InterpreterHelpers::GetClassId(instance);
 
-    RawTypeArguments* instance_type_arguments =
-        static_cast<RawTypeArguments*>(null_value);
-    RawObject* instance_cid_or_function;
+    TypeArgumentsPtr instance_type_arguments =
+        static_cast<TypeArgumentsPtr>(null_value);
+    ObjectPtr instance_cid_or_function;
 
-    RawTypeArguments* parent_function_type_arguments;
-    RawTypeArguments* delayed_function_type_arguments;
+    TypeArgumentsPtr parent_function_type_arguments;
+    TypeArgumentsPtr delayed_function_type_arguments;
     if (cid == kClosureCid) {
-      RawClosure* closure = static_cast<RawClosure*>(instance);
+      ClosurePtr closure = static_cast<ClosurePtr>(instance);
       instance_type_arguments = closure->ptr()->instantiator_type_arguments_;
       parent_function_type_arguments = closure->ptr()->function_type_arguments_;
       delayed_function_type_arguments = closure->ptr()->delayed_type_arguments_;
@@ -1188,21 +1202,21 @@
     } else {
       instance_cid_or_function = Smi::New(cid);
 
-      RawClass* instance_class = thread->isolate()->class_table()->At(cid);
+      ClassPtr instance_class = thread->isolate()->class_table()->At(cid);
       if (instance_class->ptr()->num_type_arguments_ < 0) {
         goto AssertAssignableCallRuntime;
       } else if (instance_class->ptr()->num_type_arguments_ > 0) {
-        instance_type_arguments = reinterpret_cast<RawTypeArguments**>(
+        instance_type_arguments = reinterpret_cast<TypeArgumentsPtr*>(
             instance->ptr())[instance_class->ptr()
                                  ->host_type_arguments_field_offset_in_words_];
       }
       parent_function_type_arguments =
-          static_cast<RawTypeArguments*>(null_value);
+          static_cast<TypeArgumentsPtr>(null_value);
       delayed_function_type_arguments =
-          static_cast<RawTypeArguments*>(null_value);
+          static_cast<TypeArgumentsPtr>(null_value);
     }
 
-    for (RawObject** entries = cache->ptr()->cache_->ptr()->data();
+    for (ObjectPtr* entries = cache->ptr()->cache_->ptr()->data();
          entries[0] != null_value;
          entries += SubtypeTestCache::kTestEntryLength) {
       if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] ==
@@ -1243,29 +1257,29 @@
 template <bool is_getter>
 bool Interpreter::AssertAssignableField(Thread* thread,
                                         const KBCInstr* pc,
-                                        RawObject** FP,
-                                        RawObject** SP,
-                                        RawInstance* instance,
-                                        RawField* field,
-                                        RawInstance* value) {
-  RawAbstractType* field_type = field->ptr()->type_;
+                                        ObjectPtr* FP,
+                                        ObjectPtr* SP,
+                                        InstancePtr instance,
+                                        FieldPtr field,
+                                        InstancePtr value) {
+  AbstractTypePtr field_type = field->ptr()->type_;
   // Perform type test of value if field type is not one of dynamic, object,
   // or void, and if the value is not null.
   if (field_type->GetClassId() == kTypeCid) {
-    classid_t cid = Smi::Value(reinterpret_cast<RawSmi*>(
-        Type::RawCast(field_type)->ptr()->type_class_id_));
+    classid_t cid = Smi::Value(
+        static_cast<SmiPtr>(Type::RawCast(field_type)->ptr()->type_class_id_));
     // TODO(regis): Revisit shortcut for NNBD.
     if (cid == kDynamicCid || cid == kInstanceCid || cid == kVoidCid) {
       return true;
     }
   }
-  RawObject* null_value = Object::null();
+  ObjectPtr null_value = Object::null();
   if (value == null_value) {
     // TODO(regis): Revisit null shortcut for NNBD.
     return true;
   }
 
-  RawSubtypeTestCache* cache = field->ptr()->type_test_cache_;
+  SubtypeTestCachePtr cache = field->ptr()->type_test_cache_;
   if (UNLIKELY(cache == null_value)) {
     // Allocate new cache.
     SP[1] = instance;    // Preserve.
@@ -1281,10 +1295,10 @@
     }
 
     // Reload objects after the call which may trigger GC.
-    instance = reinterpret_cast<RawInstance*>(SP[1]);
-    field = reinterpret_cast<RawField*>(SP[2]);
-    value = reinterpret_cast<RawInstance*>(SP[3]);
-    cache = reinterpret_cast<RawSubtypeTestCache*>(SP[4]);
+    instance = static_cast<InstancePtr>(SP[1]);
+    field = static_cast<FieldPtr>(SP[2]);
+    value = static_cast<InstancePtr>(SP[3]);
+    cache = static_cast<SubtypeTestCachePtr>(SP[4]);
     field_type = field->ptr()->type_;
     field->ptr()->type_test_cache_ = cache;
   }
@@ -1300,10 +1314,10 @@
                           /* args */ SP + 1, cache);
 }
 
-RawObject* Interpreter::Call(const Function& function,
-                             const Array& arguments_descriptor,
-                             const Array& arguments,
-                             Thread* thread) {
+ObjectPtr Interpreter::Call(const Function& function,
+                            const Array& arguments_descriptor,
+                            const Array& arguments,
+                            Thread* thread) {
   return Call(function.raw(), arguments_descriptor.raw(), arguments.Length(),
               arguments.raw_ptr()->data(), thread);
 }
@@ -1313,12 +1327,12 @@
 DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread,
                                              int64_t value,
                                              const KBCInstr* pc,
-                                             RawObject** FP,
-                                             RawObject** SP) {
+                                             ObjectPtr* FP,
+                                             ObjectPtr* SP) {
   ASSERT(!Smi::IsValid(value));
-  RawMint* result;
+  MintPtr result;
   if (TryAllocate(thread, kMintCid, Mint::InstanceSize(),
-                  reinterpret_cast<RawObject**>(&result))) {
+                  reinterpret_cast<ObjectPtr*>(&result))) {
     result->ptr()->value_ = value;
     SP[0] = result;
     return true;
@@ -1331,7 +1345,7 @@
     if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
       return false;
     }
-    reinterpret_cast<RawMint*>(SP[0])->ptr()->value_ = value;
+    static_cast<MintPtr>(SP[0])->ptr()->value_ = value;
     return true;
   }
 }
@@ -1341,11 +1355,11 @@
 DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread,
                                                double value,
                                                const KBCInstr* pc,
-                                               RawObject** FP,
-                                               RawObject** SP) {
-  RawDouble* result;
+                                               ObjectPtr* FP,
+                                               ObjectPtr* SP) {
+  DoublePtr result;
   if (TryAllocate(thread, kDoubleCid, Double::InstanceSize(),
-                  reinterpret_cast<RawObject**>(&result))) {
+                  reinterpret_cast<ObjectPtr*>(&result))) {
     result->ptr()->value_ = value;
     SP[0] = result;
     return true;
@@ -1368,11 +1382,11 @@
 DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread,
                                                   simd128_value_t value,
                                                   const KBCInstr* pc,
-                                                  RawObject** FP,
-                                                  RawObject** SP) {
-  RawFloat32x4* result;
+                                                  ObjectPtr* FP,
+                                                  ObjectPtr* SP) {
+  Float32x4Ptr result;
   if (TryAllocate(thread, kFloat32x4Cid, Float32x4::InstanceSize(),
-                  reinterpret_cast<RawObject**>(&result))) {
+                  reinterpret_cast<ObjectPtr*>(&result))) {
     value.writeTo(result->ptr()->value_);
     SP[0] = result;
     return true;
@@ -1395,11 +1409,11 @@
 DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread,
                                                   simd128_value_t value,
                                                   const KBCInstr* pc,
-                                                  RawObject** FP,
-                                                  RawObject** SP) {
-  RawFloat64x2* result;
+                                                  ObjectPtr* FP,
+                                                  ObjectPtr* SP) {
+  Float64x2Ptr result;
   if (TryAllocate(thread, kFloat64x2Cid, Float64x2::InstanceSize(),
-                  reinterpret_cast<RawObject**>(&result))) {
+                  reinterpret_cast<ObjectPtr*>(&result))) {
     value.writeTo(result->ptr()->value_);
     SP[0] = result;
     return true;
@@ -1420,17 +1434,17 @@
 // Allocate a _List with the given type arguments and length and put it into
 // SP[0]. Returns false on exception.
 bool Interpreter::AllocateArray(Thread* thread,
-                                RawTypeArguments* type_args,
-                                RawObject* length_object,
+                                TypeArgumentsPtr type_args,
+                                ObjectPtr length_object,
                                 const KBCInstr* pc,
-                                RawObject** FP,
-                                RawObject** SP) {
+                                ObjectPtr* FP,
+                                ObjectPtr* SP) {
   if (LIKELY(!length_object->IsHeapObject())) {
     const intptr_t length = Smi::Value(Smi::RawCast(length_object));
     if (LIKELY(Array::IsValidLength(length))) {
-      RawArray* result;
+      ArrayPtr result;
       if (TryAllocate(thread, kArrayCid, Array::InstanceSize(length),
-                      reinterpret_cast<RawObject**>(&result))) {
+                      reinterpret_cast<ObjectPtr*>(&result))) {
         result->ptr()->type_arguments_ = type_args;
         result->ptr()->length_ = Smi::New(length);
         for (intptr_t i = 0; i < length; i++) {
@@ -1455,15 +1469,15 @@
 bool Interpreter::AllocateContext(Thread* thread,
                                   intptr_t num_context_variables,
                                   const KBCInstr* pc,
-                                  RawObject** FP,
-                                  RawObject** SP) {
-  RawContext* result;
+                                  ObjectPtr* FP,
+                                  ObjectPtr* SP) {
+  ContextPtr result;
   if (TryAllocate(thread, kContextCid,
                   Context::InstanceSize(num_context_variables),
-                  reinterpret_cast<RawObject**>(&result))) {
+                  reinterpret_cast<ObjectPtr*>(&result))) {
     result->ptr()->num_variables_ = num_context_variables;
-    RawObject* null_value = Object::null();
-    result->ptr()->parent_ = static_cast<RawContext*>(null_value);
+    ObjectPtr null_value = Object::null();
+    result->ptr()->parent_ = static_cast<ContextPtr>(null_value);
     for (intptr_t i = 0; i < num_context_variables; i++) {
       result->ptr()->data()[i] = null_value;
     }
@@ -1482,17 +1496,17 @@
 // Returns false on exception.
 bool Interpreter::AllocateClosure(Thread* thread,
                                   const KBCInstr* pc,
-                                  RawObject** FP,
-                                  RawObject** SP) {
+                                  ObjectPtr* FP,
+                                  ObjectPtr* SP) {
   const intptr_t instance_size = Closure::InstanceSize();
-  RawClosure* result;
+  ClosurePtr result;
   if (TryAllocate(thread, kClosureCid, instance_size,
-                  reinterpret_cast<RawObject**>(&result))) {
-    uword start = RawObject::ToAddr(result);
-    RawObject* null_value = Object::null();
-    for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+                  reinterpret_cast<ObjectPtr*>(&result))) {
+    uword start = ObjectLayout::ToAddr(result);
+    ObjectPtr null_value = Object::null();
+    for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size;
          offset += kWordSize) {
-      *reinterpret_cast<RawObject**>(start + offset) = null_value;
+      *reinterpret_cast<ObjectPtr*>(start + offset) = null_value;
     }
     SP[0] = result;
     return true;
@@ -1506,21 +1520,21 @@
   }
 }
 
-RawObject* Interpreter::Call(RawFunction* function,
-                             RawArray* argdesc,
-                             intptr_t argc,
-                             RawObject* const* argv,
-                             Thread* thread) {
+ObjectPtr Interpreter::Call(FunctionPtr function,
+                            ArrayPtr argdesc,
+                            intptr_t argc,
+                            ObjectPtr const* argv,
+                            Thread* thread) {
   // Interpreter state (see constants_kbc.h for high-level overview).
   const KBCInstr* pc;  // Program Counter: points to the next op to execute.
-  RawObject** FP;      // Frame Pointer.
-  RawObject** SP;      // Stack Pointer.
+  ObjectPtr* FP;       // Frame Pointer.
+  ObjectPtr* SP;       // Stack Pointer.
 
   uint32_t op;  // Currently executing op.
 
   bool reentering = fp_ != NULL;
   if (!reentering) {
-    fp_ = reinterpret_cast<RawObject**>(stack_base_);
+    fp_ = reinterpret_cast<ObjectPtr*>(stack_base_);
   }
 #if defined(DEBUG)
   if (IsTracingExecution()) {
@@ -1563,22 +1577,22 @@
 
   // Save outer top_exit_frame_info, current argdesc, and current pp.
   fp_[kKBCExitLinkSlotFromEntryFp] =
-      reinterpret_cast<RawObject*>(thread->top_exit_frame_info());
+      static_cast<ObjectPtr>(thread->top_exit_frame_info());
   thread->set_top_exit_frame_info(0);
-  fp_[kKBCSavedArgDescSlotFromEntryFp] = reinterpret_cast<RawObject*>(argdesc_);
-  fp_[kKBCSavedPpSlotFromEntryFp] = reinterpret_cast<RawObject*>(pp_);
+  fp_[kKBCSavedArgDescSlotFromEntryFp] = static_cast<ObjectPtr>(argdesc_);
+  fp_[kKBCSavedPpSlotFromEntryFp] = static_cast<ObjectPtr>(pp_);
 
   // Copy arguments and setup the Dart frame.
   for (intptr_t i = 0; i < arg_count; i++) {
     fp_[kKBCEntrySavedSlots + i] = argv[argc < 0 ? -i : i];
   }
 
-  RawBytecode* bytecode = function->ptr()->bytecode_;
+  BytecodePtr bytecode = function->ptr()->bytecode_;
   FP[kKBCFunctionSlotFromFp] = function;
   FP[kKBCPcMarkerSlotFromFp] = bytecode;
-  FP[kKBCSavedCallerPcSlotFromFp] =
-      reinterpret_cast<RawObject*>(kEntryFramePcMarker);
-  FP[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_);
+  FP[kKBCSavedCallerPcSlotFromFp] = static_cast<ObjectPtr>(kEntryFramePcMarker);
+  FP[kKBCSavedCallerFpSlotFromFp] =
+      static_cast<ObjectPtr>(reinterpret_cast<uword>(fp_));
 
   // Load argument descriptor.
   argdesc_ = argdesc;
@@ -1601,9 +1615,9 @@
   thread->set_top_resource(NULL);
 
   // Cache some frequently used values in the frame.
-  RawBool* true_value = Bool::True().raw();
-  RawBool* false_value = Bool::False().raw();
-  RawObject* null_value = Object::null();
+  BoolPtr true_value = Bool::True().raw();
+  BoolPtr false_value = Bool::False().raw();
+  ObjectPtr null_value = Object::null();
 
 #ifdef DART_HAS_COMPUTED_GOTO
   static const void* dispatch[] = {
@@ -1699,7 +1713,7 @@
                        NativeArguments(thread, 0, nullptr, nullptr));
       }
     }
-    RawFunction* function = FrameFunction(FP);
+    FunctionPtr function = FrameFunction(FP);
     int32_t counter = ++(function->ptr()->usage_counter_);
     if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 &&
                  counter >= FLAG_compilation_counter_threshold &&
@@ -1744,7 +1758,7 @@
   {
     BYTECODE(InstantiateType, D);
     // Stack: instantiator type args, function type args
-    RawObject* type = LOAD_CONSTANT(rD);
+    ObjectPtr type = LOAD_CONSTANT(rD);
     SP[1] = type;
     SP[2] = SP[-1];
     SP[3] = SP[0];
@@ -1760,21 +1774,21 @@
   {
     BYTECODE(InstantiateTypeArgumentsTOS, A_E);
     // Stack: instantiator type args, function type args
-    RawTypeArguments* type_arguments =
-        static_cast<RawTypeArguments*>(LOAD_CONSTANT(rE));
+    TypeArgumentsPtr type_arguments =
+        static_cast<TypeArgumentsPtr>(LOAD_CONSTANT(rE));
 
-    RawObject* instantiator_type_args = SP[-1];
-    RawObject* function_type_args = SP[0];
+    ObjectPtr instantiator_type_args = SP[-1];
+    ObjectPtr function_type_args = SP[0];
     // If both instantiators are null and if the type argument vector
     // instantiated from null becomes a vector of dynamic, then use null as
     // the type arguments.
     if ((rA == 0) || (null_value != instantiator_type_args) ||
         (null_value != function_type_args)) {
       // First lookup in the cache.
-      RawArray* instantiations = type_arguments->ptr()->instantiations_;
+      ArrayPtr instantiations = type_arguments->ptr()->instantiations_;
       for (intptr_t i = 0;
            instantiations->ptr()->data()[i] !=
-           reinterpret_cast<RawObject*>(TypeArguments::kNoInstantiator);
+           static_cast<ObjectPtr>(TypeArguments::kNoInstantiator);
            i += TypeArguments::Instantiation::kSizeInWords) {
         if ((instantiations->ptr()->data()
                  [i +
@@ -1903,9 +1917,9 @@
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
       *++SP = LOAD_CONSTANT(kidx);
-      RawObject** call_base = SP - argc;
-      RawObject** call_top = SP;
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+      ObjectPtr* call_base = SP - argc;
+      ObjectPtr* call_top = SP;
+      argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
       if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
         HANDLE_EXCEPTION;
       }
@@ -1924,9 +1938,9 @@
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
       *++SP = LOAD_CONSTANT(kidx);
-      RawObject** call_base = SP - argc;
-      RawObject** call_top = SP;
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+      ObjectPtr* call_base = SP - argc;
+      ObjectPtr* call_top = SP;
+      argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
       if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
         HANDLE_EXCEPTION;
       }
@@ -1942,13 +1956,13 @@
       const uint32_t argc = rF;
       const uint32_t kidx = rD;
 
-      RawObject** call_base = SP - argc + 1;
-      RawObject** call_top = SP + 1;
+      ObjectPtr* call_base = SP - argc + 1;
+      ObjectPtr* call_top = SP + 1;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
-      RawString* target_name =
-          static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+      StringPtr target_name =
+          static_cast<FunctionPtr>(LOAD_CONSTANT(kidx))->ptr()->name_;
+      argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
       if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
                         &SP)) {
         HANDLE_EXCEPTION;
@@ -1964,13 +1978,13 @@
       const uint32_t argc = rF;
       const uint32_t kidx = rD;
 
-      RawObject** call_base = SP - argc + 1;
-      RawObject** call_top = SP + 1;
+      ObjectPtr* call_base = SP - argc + 1;
+      ObjectPtr* call_top = SP + 1;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
-      RawString* target_name =
-          static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+      StringPtr target_name =
+          static_cast<FunctionPtr>(LOAD_CONSTANT(kidx))->ptr()->name_;
+      argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
       if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
                         &SP)) {
         HANDLE_EXCEPTION;
@@ -1987,16 +2001,16 @@
       const uint32_t argc = rF;
       const uint32_t kidx = rD;
 
-      RawClosure* receiver = Closure::RawCast(*SP--);
-      RawObject** call_base = SP - argc + 1;
-      RawObject** call_top = SP + 1;
+      ClosurePtr receiver = Closure::RawCast(*SP--);
+      ObjectPtr* call_base = SP - argc + 1;
+      ObjectPtr* call_top = SP + 1;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
       if (UNLIKELY(receiver == null_value)) {
         SP[0] = Symbols::Call().raw();
         goto ThrowNullError;
       }
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx));
+      argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx));
       call_top[0] = receiver->ptr()->function_;
 
       if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
@@ -2014,13 +2028,13 @@
       const uint32_t argc = rF;
       const uint32_t kidx = rD;
 
-      RawObject** call_base = SP - argc + 1;
-      RawObject** call_top = SP + 1;
+      ObjectPtr* call_base = SP - argc + 1;
+      ObjectPtr* call_top = SP + 1;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
-      RawString* target_name =
-          static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+      StringPtr target_name =
+          static_cast<FunctionPtr>(LOAD_CONSTANT(kidx))->ptr()->name_;
+      argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
       if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
                         &SP)) {
         HANDLE_EXCEPTION;
@@ -2037,11 +2051,11 @@
       const uint32_t argc = rF;
       const uint32_t kidx = rD;
 
-      RawObject** call_base = SP - argc + 1;
-      RawObject** call_top = SP + 1;
+      ObjectPtr* call_base = SP - argc + 1;
+      ObjectPtr* call_top = SP + 1;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
-      RawString* target_name = String::RawCast(LOAD_CONSTANT(kidx));
+      StringPtr target_name = String::RawCast(LOAD_CONSTANT(kidx));
       argdesc_ = Array::RawCast(LOAD_CONSTANT(kidx + 1));
       if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
                         &SP)) {
@@ -2054,7 +2068,7 @@
 
   {
     BYTECODE(NativeCall, D);
-    RawTypedData* data = static_cast<RawTypedData*>(LOAD_CONSTANT(rD));
+    TypedDataPtr data = static_cast<TypedDataPtr>(LOAD_CONSTANT(rD));
     MethodRecognizer::Kind kind = NativeEntryData::GetKind(data);
     switch (kind) {
       case MethodRecognizer::kObjectEquals: {
@@ -2063,8 +2077,8 @@
       } break;
       case MethodRecognizer::kStringBaseLength:
       case MethodRecognizer::kStringBaseIsEmpty: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
+        InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+        SP[0] = reinterpret_cast<ObjectPtr*>(
             instance->ptr())[String::length_offset() / kWordSize];
         if (kind == MethodRecognizer::kStringBaseIsEmpty) {
           SP[0] =
@@ -2072,29 +2086,29 @@
         }
       } break;
       case MethodRecognizer::kGrowableArrayLength: {
-        RawGrowableObjectArray* instance =
-            reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+        GrowableObjectArrayPtr instance =
+            static_cast<GrowableObjectArrayPtr>(SP[0]);
         SP[0] = instance->ptr()->length_;
       } break;
       case MethodRecognizer::kObjectArrayLength:
       case MethodRecognizer::kImmutableArrayLength: {
-        RawArray* instance = reinterpret_cast<RawArray*>(SP[0]);
+        ArrayPtr instance = static_cast<ArrayPtr>(SP[0]);
         SP[0] = instance->ptr()->length_;
       } break;
       case MethodRecognizer::kTypedListLength:
       case MethodRecognizer::kTypedListViewLength:
       case MethodRecognizer::kByteDataViewLength: {
-        RawTypedDataBase* instance = reinterpret_cast<RawTypedDataBase*>(SP[0]);
+        TypedDataBasePtr instance = static_cast<TypedDataBasePtr>(SP[0]);
         SP[0] = instance->ptr()->length_;
       } break;
       case MethodRecognizer::kByteDataViewOffsetInBytes:
       case MethodRecognizer::kTypedDataViewOffsetInBytes: {
-        RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+        TypedDataViewPtr instance = static_cast<TypedDataViewPtr>(SP[0]);
         SP[0] = instance->ptr()->offset_in_bytes_;
       } break;
       case MethodRecognizer::kByteDataViewTypedData:
       case MethodRecognizer::kTypedDataViewTypedData: {
-        RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+        TypedDataViewPtr instance = static_cast<TypedDataViewPtr>(SP[0]);
         SP[0] = instance->ptr()->typed_data_;
       } break;
       case MethodRecognizer::kClassIDgetID: {
@@ -2104,8 +2118,8 @@
         SP[0] = Object::null();
       } break;
       case MethodRecognizer::kGrowableArrayCapacity: {
-        RawGrowableObjectArray* instance =
-            reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+        GrowableObjectArrayPtr instance =
+            static_cast<GrowableObjectArrayPtr>(SP[0]);
         SP[0] = instance->ptr()->data_->ptr()->length_;
       } break;
       case MethodRecognizer::kListFactory: {
@@ -2114,8 +2128,8 @@
         //                                            : new _GrowableList<E>(0);
         // }
         if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) {
-          RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
-          RawObject* length = SP[0];
+          TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
+          ObjectPtr length = SP[0];
           SP--;
           if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
             HANDLE_EXCEPTION;
@@ -2140,72 +2154,74 @@
         }
       } break;
       case MethodRecognizer::kObjectArrayAllocate: {
-        RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
-        RawObject* length = SP[0];
+        TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
+        ObjectPtr length = SP[0];
         SP--;
         if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
           HANDLE_EXCEPTION;
         }
       } break;
       case MethodRecognizer::kLinkedHashMap_getIndex: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
+        InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+        SP[0] = reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::index_offset() / kWordSize];
       } break;
       case MethodRecognizer::kLinkedHashMap_setIndex: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
-        instance->StorePointer(reinterpret_cast<RawObject**>(instance->ptr()) +
-                                   LinkedHashMap::index_offset() / kWordSize,
-                               SP[0]);
+        InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
+        instance->ptr()->StorePointer(
+            reinterpret_cast<ObjectPtr*>(instance->ptr()) +
+                LinkedHashMap::index_offset() / kWordSize,
+            SP[0]);
         *--SP = null_value;
       } break;
       case MethodRecognizer::kLinkedHashMap_getData: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
+        InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+        SP[0] = reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::data_offset() / kWordSize];
       } break;
       case MethodRecognizer::kLinkedHashMap_setData: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
-        instance->StorePointer(reinterpret_cast<RawObject**>(instance->ptr()) +
-                                   LinkedHashMap::data_offset() / kWordSize,
-                               SP[0]);
+        InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
+        instance->ptr()->StorePointer(
+            reinterpret_cast<ObjectPtr*>(instance->ptr()) +
+                LinkedHashMap::data_offset() / kWordSize,
+            SP[0]);
         *--SP = null_value;
       } break;
       case MethodRecognizer::kLinkedHashMap_getHashMask: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
+        InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+        SP[0] = reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize];
       } break;
       case MethodRecognizer::kLinkedHashMap_setHashMask: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+        InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
         ASSERT(!SP[0]->IsHeapObject());
-        reinterpret_cast<RawObject**>(
+        reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize] =
             SP[0];
         *--SP = null_value;
       } break;
       case MethodRecognizer::kLinkedHashMap_getUsedData: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
+        InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+        SP[0] = reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize];
       } break;
       case MethodRecognizer::kLinkedHashMap_setUsedData: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+        InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
         ASSERT(!SP[0]->IsHeapObject());
-        reinterpret_cast<RawObject**>(
+        reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize] =
             SP[0];
         *--SP = null_value;
       } break;
       case MethodRecognizer::kLinkedHashMap_getDeletedKeys: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
+        InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+        SP[0] = reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize];
       } break;
       case MethodRecognizer::kLinkedHashMap_setDeletedKeys: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+        InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
         ASSERT(!SP[0]->IsHeapObject());
-        reinterpret_cast<RawObject**>(
+        reinterpret_cast<ObjectPtr*>(
             instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize] =
             SP[0];
         *--SP = null_value;
@@ -2229,8 +2245,8 @@
 
         *++SP = null_value;  // Result slot.
 
-        RawObject** incoming_args = SP - num_arguments;
-        RawObject** return_slot = SP;
+        ObjectPtr* incoming_args = SP - num_arguments;
+        ObjectPtr* return_slot = SP;
         Exit(thread, FP, SP + 1, pc);
         NativeArguments native_args(thread, argc_tag, incoming_args,
                                     return_slot);
@@ -2247,10 +2263,9 @@
   }
 
   {
-    RawObject* result;  // result to return to the caller.
-
     BYTECODE(ReturnTOS, 0);
     DEBUG_CHECK;
+    ObjectPtr result;  // result to return to the caller.
     result = *SP;
     // Restore caller PC.
     pc = SavedCallerPC(FP);
@@ -2258,14 +2273,12 @@
     // Check if it is a fake PC marking the entry frame.
     if (IsEntryFrameMarker(pc)) {
       // Pop entry frame.
-      RawObject** entry_fp = SavedCallerFP(FP);
+      ObjectPtr* entry_fp = SavedCallerFP(FP);
       // Restore exit frame info saved in entry frame.
-      pp_ = reinterpret_cast<RawObjectPool*>(
-          entry_fp[kKBCSavedPpSlotFromEntryFp]);
-      argdesc_ = reinterpret_cast<RawArray*>(
-          entry_fp[kKBCSavedArgDescSlotFromEntryFp]);
-      uword exit_fp =
-          reinterpret_cast<uword>(entry_fp[kKBCExitLinkSlotFromEntryFp]);
+      pp_ = static_cast<ObjectPoolPtr>(entry_fp[kKBCSavedPpSlotFromEntryFp]);
+      argdesc_ =
+          static_cast<ArrayPtr>(entry_fp[kKBCSavedArgDescSlotFromEntryFp]);
+      uword exit_fp = static_cast<uword>(entry_fp[kKBCExitLinkSlotFromEntryFp]);
       thread->set_top_exit_frame_info(exit_fp);
       thread->set_top_resource(top_resource);
       thread->set_vm_tag(vm_tag);
@@ -2310,12 +2323,13 @@
 
   {
     BYTECODE(InitLateField, D);
-    RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
-    RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-    intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+    FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
+    InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+    intptr_t offset_in_words =
+        Smi::Value(field->ptr()->host_offset_or_field_id_);
 
-    instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
+    instance->ptr()->StorePointer(
+        reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words,
         Object::RawCast(Object::sentinel().raw()), thread);
 
     SP -= 1;  // Drop instance.
@@ -2339,18 +2353,18 @@
 
   {
     BYTECODE(StoreStaticTOS, D);
-    RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
-    RawInstance* value = static_cast<RawInstance*>(*SP--);
-    intptr_t field_id = field->ptr()->host_offset_or_field_id_;
+    FieldPtr field = static_cast<FieldPtr>(LOAD_CONSTANT(rD));
+    InstancePtr value = static_cast<InstancePtr>(*SP--);
+    intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
     thread->field_table_values()[field_id] = value;
     DISPATCH();
   }
 
   {
     BYTECODE(LoadStatic, D);
-    RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
-    intptr_t field_id = field->ptr()->host_offset_or_field_id_;
-    RawInstance* value = thread->field_table_values()[field_id];
+    FieldPtr field = static_cast<FieldPtr>(LOAD_CONSTANT(rD));
+    intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
+    InstancePtr value = thread->field_table_values()[field_id];
     ASSERT((value != Object::sentinel().raw()) &&
            (value != Object::transition_sentinel().raw()));
     *++SP = value;
@@ -2359,10 +2373,11 @@
 
   {
     BYTECODE(StoreFieldTOS, D);
-    RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
-    RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
-    RawObject* value = reinterpret_cast<RawObject*>(SP[0]);
-    intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+    FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
+    InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
+    ObjectPtr value = static_cast<ObjectPtr>(SP[0]);
+    intptr_t offset_in_words =
+        Smi::Value(field->ptr()->host_offset_or_field_id_);
 
     if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) {
       SP[1] = 0;  // Unused result of runtime call.
@@ -2377,7 +2392,7 @@
 
       // Reload objects after the call which may trigger GC.
       field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
-      instance = reinterpret_cast<RawInstance*>(SP[-1]);
+      instance = static_cast<InstancePtr>(SP[-1]);
       value = SP[0];
     }
 
@@ -2387,47 +2402,47 @@
     classid_t guarded_cid = field->ptr()->guarded_cid_;
     if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) {
       double raw_value = Double::RawCast(value)->ptr()->value_;
-      ASSERT(*(reinterpret_cast<RawDouble**>(instance->ptr()) +
+      ASSERT(*(reinterpret_cast<DoublePtr*>(instance->ptr()) +
                offset_in_words) == null_value);  // Initializing store.
       if (!AllocateDouble(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
-      RawDouble* box = Double::RawCast(SP[0]);
-      instance = reinterpret_cast<RawInstance*>(SP[-1]);
-      instance->StorePointer(
-          reinterpret_cast<RawDouble**>(instance->ptr()) + offset_in_words, box,
+      DoublePtr box = Double::RawCast(SP[0]);
+      instance = static_cast<InstancePtr>(SP[-1]);
+      instance->ptr()->StorePointer(
+          reinterpret_cast<DoublePtr*>(instance->ptr()) + offset_in_words, box,
           thread);
     } else if (unboxing && (guarded_cid == kFloat32x4Cid) &&
                supports_unboxed_simd128_) {
       simd128_value_t raw_value;
       raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_);
-      ASSERT(*(reinterpret_cast<RawFloat32x4**>(instance->ptr()) +
+      ASSERT(*(reinterpret_cast<Float32x4Ptr*>(instance->ptr()) +
                offset_in_words) == null_value);  // Initializing store.
       if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
-      RawFloat32x4* box = Float32x4::RawCast(SP[0]);
-      instance = reinterpret_cast<RawInstance*>(SP[-1]);
-      instance->StorePointer(
-          reinterpret_cast<RawFloat32x4**>(instance->ptr()) + offset_in_words,
+      Float32x4Ptr box = Float32x4::RawCast(SP[0]);
+      instance = static_cast<InstancePtr>(SP[-1]);
+      instance->ptr()->StorePointer(
+          reinterpret_cast<Float32x4Ptr*>(instance->ptr()) + offset_in_words,
           box, thread);
     } else if (unboxing && (guarded_cid == kFloat64x2Cid) &&
                supports_unboxed_simd128_) {
       simd128_value_t raw_value;
       raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_);
-      ASSERT(*(reinterpret_cast<RawFloat64x2**>(instance->ptr()) +
+      ASSERT(*(reinterpret_cast<Float64x2Ptr*>(instance->ptr()) +
                offset_in_words) == null_value);  // Initializing store.
       if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
-      RawFloat64x2* box = Float64x2::RawCast(SP[0]);
-      instance = reinterpret_cast<RawInstance*>(SP[-1]);
-      instance->StorePointer(
-          reinterpret_cast<RawFloat64x2**>(instance->ptr()) + offset_in_words,
+      Float64x2Ptr box = Float64x2::RawCast(SP[0]);
+      instance = static_cast<InstancePtr>(SP[-1]);
+      instance->ptr()->StorePointer(
+          reinterpret_cast<Float64x2Ptr*>(instance->ptr()) + offset_in_words,
           box, thread);
     } else {
-      instance->StorePointer(
-          reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
+      instance->ptr()->StorePointer(
+          reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words,
           value, thread);
     }
 
@@ -2439,13 +2454,13 @@
     BYTECODE(StoreContextParent, 0);
     const uword offset_in_words =
         static_cast<uword>(Context::parent_offset() / kWordSize);
-    RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
-    RawContext* value = reinterpret_cast<RawContext*>(SP[0]);
+    ContextPtr instance = static_cast<ContextPtr>(SP[-1]);
+    ContextPtr value = static_cast<ContextPtr>(SP[0]);
     SP -= 2;  // Drop instance and value.
 
-    instance->StorePointer(
-        reinterpret_cast<RawContext**>(instance->ptr()) + offset_in_words,
-        value, thread);
+    instance->ptr()->StorePointer(
+        reinterpret_cast<ContextPtr*>(instance->ptr()) + offset_in_words, value,
+        thread);
 
     DISPATCH();
   }
@@ -2454,12 +2469,12 @@
     BYTECODE(StoreContextVar, A_E);
     const uword offset_in_words =
         static_cast<uword>(Context::variable_offset(rE) / kWordSize);
-    RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
-    RawObject* value = reinterpret_cast<RawContext*>(SP[0]);
+    ContextPtr instance = static_cast<ContextPtr>(SP[-1]);
+    ObjectPtr value = static_cast<ContextPtr>(SP[0]);
     SP -= 2;  // Drop instance and value.
     ASSERT(rE < static_cast<uint32_t>(instance->ptr()->num_variables_));
-    instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+    instance->ptr()->StorePointer(
+        reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words, value,
         thread);
 
     DISPATCH();
@@ -2471,7 +2486,7 @@
     // Currently only used to load closure fields, which are not unboxed.
     // If used for general field, code for copying the mutable box must be
     // added.
-    RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
+    FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
     const bool unboxing =
         (field->ptr()->is_nullable_ != kNullCid) &&
         Field::UnboxingCandidateBit::decode(field->ptr()->kind_bits_);
@@ -2479,8 +2494,8 @@
 #endif
     const uword offset_in_words =
         static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
-    RawInstance* instance = static_cast<RawInstance*>(SP[0]);
-    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+    InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+    SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
     DISPATCH();
   }
 
@@ -2488,8 +2503,8 @@
     BYTECODE(LoadTypeArgumentsField, D);
     const uword offset_in_words =
         static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
-    RawInstance* instance = static_cast<RawInstance*>(SP[0]);
-    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+    InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+    SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
     DISPATCH();
   }
 
@@ -2497,8 +2512,8 @@
     BYTECODE(LoadContextParent, 0);
     const uword offset_in_words =
         static_cast<uword>(Context::parent_offset() / kWordSize);
-    RawContext* instance = static_cast<RawContext*>(SP[0]);
-    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+    ContextPtr instance = static_cast<ContextPtr>(SP[0]);
+    SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
     DISPATCH();
   }
 
@@ -2506,9 +2521,9 @@
     BYTECODE(LoadContextVar, A_E);
     const uword offset_in_words =
         static_cast<uword>(Context::variable_offset(rE) / kWordSize);
-    RawContext* instance = static_cast<RawContext*>(SP[0]);
+    ContextPtr instance = static_cast<ContextPtr>(SP[0]);
     ASSERT(rE < static_cast<uint32_t>(instance->ptr()->num_variables_));
-    SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+    SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
     DISPATCH();
   }
 
@@ -2534,17 +2549,17 @@
 
   {
     BYTECODE(Allocate, D);
-    RawClass* cls = Class::RawCast(LOAD_CONSTANT(rD));
+    ClassPtr cls = Class::RawCast(LOAD_CONSTANT(rD));
     if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
       const intptr_t class_id = cls->ptr()->id_;
       const intptr_t instance_size = cls->ptr()->host_instance_size_in_words_
                                      << kWordSizeLog2;
-      RawObject* result;
+      ObjectPtr result;
       if (TryAllocate(thread, class_id, instance_size, &result)) {
-        uword start = RawObject::ToAddr(result);
-        for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+        uword start = ObjectLayout::ToAddr(result);
+        for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size;
              offset += kWordSize) {
-          *reinterpret_cast<RawObject**>(start + offset) = null_value;
+          *reinterpret_cast<ObjectPtr*>(start + offset) = null_value;
         }
         *++SP = result;
         DISPATCH();
@@ -2563,23 +2578,23 @@
 
   {
     BYTECODE(AllocateT, 0);
-    RawClass* cls = Class::RawCast(SP[0]);
-    RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
+    ClassPtr cls = Class::RawCast(SP[0]);
+    TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
     if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
       const intptr_t class_id = cls->ptr()->id_;
       const intptr_t instance_size = cls->ptr()->host_instance_size_in_words_
                                      << kWordSizeLog2;
-      RawObject* result;
+      ObjectPtr result;
       if (TryAllocate(thread, class_id, instance_size, &result)) {
-        uword start = RawObject::ToAddr(result);
-        for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+        uword start = ObjectLayout::ToAddr(result);
+        for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size;
              offset += kWordSize) {
-          *reinterpret_cast<RawObject**>(start + offset) = null_value;
+          *reinterpret_cast<ObjectPtr*>(start + offset) = null_value;
         }
         const intptr_t type_args_offset =
             cls->ptr()->host_type_arguments_field_offset_in_words_
             << kWordSizeLog2;
-        *reinterpret_cast<RawObject**>(start + type_args_offset) = type_args;
+        *reinterpret_cast<ObjectPtr*>(start + type_args_offset) = type_args;
         *--SP = result;
         DISPATCH();
       }
@@ -2596,8 +2611,8 @@
 
   {
     BYTECODE(CreateArrayTOS, 0);
-    RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
-    RawObject* length = SP[0];
+    TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
+    ObjectPtr length = SP[0];
     SP--;
     if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
       HANDLE_EXCEPTION;
@@ -2608,14 +2623,14 @@
   {
     BYTECODE(AssertAssignable, A_E);
     // Stack: instance, type, instantiator type args, function type args, name
-    RawObject** args = SP - 4;
+    ObjectPtr* args = SP - 4;
     const bool may_be_smi = (rA == 1);
     const bool is_smi =
-        ((reinterpret_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag);
+        ((static_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag);
     const bool smi_ok = is_smi && may_be_smi;
     if (!smi_ok && (args[0] != null_value)) {
-      RawSubtypeTestCache* cache =
-          static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rE));
+      SubtypeTestCachePtr cache =
+          static_cast<SubtypeTestCachePtr>(LOAD_CONSTANT(rE));
 
       if (!AssertAssignable(thread, pc, FP, SP, args, cache)) {
         HANDLE_EXCEPTION;
@@ -2628,7 +2643,7 @@
 
   {
     BYTECODE(AssertSubtype, 0);
-    RawObject** args = SP - 4;
+    ObjectPtr* args = SP - 4;
 
     // TODO(kustermann): Implement fast case for common arguments.
 
@@ -2641,7 +2656,7 @@
 
     // This is unused, since the negative case throws an exception.
     SP++;
-    RawObject** result_slot = SP;
+    ObjectPtr* result_slot = SP;
 
     Exit(thread, FP, SP + 1, pc);
     INVOKE_RUNTIME(DRT_SubtypeCheck,
@@ -2655,7 +2670,7 @@
 
   {
     BYTECODE(AssertBoolean, A);
-    RawObject* value = SP[0];
+    ObjectPtr value = SP[0];
     if (rA != 0u) {  // Should we perform type check?
       if ((value == true_value) || (value == false_value)) {
         goto AssertBooleanOk;
@@ -2762,12 +2777,12 @@
   {
     BYTECODE(StoreIndexedTOS, 0);
     SP -= 3;
-    RawArray* array = RAW_CAST(Array, SP[1]);
-    RawSmi* index = RAW_CAST(Smi, SP[2]);
-    RawObject* value = SP[3];
+    ArrayPtr array = RAW_CAST(Array, SP[1]);
+    SmiPtr index = RAW_CAST(Smi, SP[2]);
+    ObjectPtr value = SP[3];
     ASSERT(InterpreterHelpers::CheckIndex(index, array->ptr()->length_));
-    array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
-                        thread);
+    array->ptr()->StorePointer(array->ptr()->data() + Smi::Value(index), value,
+                               thread);
     DISPATCH();
   }
 
@@ -3137,20 +3152,21 @@
   {
     BYTECODE(VMInternal_ImplicitGetter, 0);
 
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kImplicitGetter);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kImplicitGetter);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
     // Field object is cached in function's data_.
-    RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
-    intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+    FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
+    intptr_t offset_in_words =
+        Smi::Value(field->ptr()->host_offset_or_field_id_);
 
     const intptr_t kArgc = 1;
-    RawInstance* instance =
-        reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
-    RawInstance* value =
-        reinterpret_cast<RawInstance**>(instance->ptr())[offset_in_words];
+    InstancePtr instance =
+        static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+    InstancePtr value =
+        reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
 
     if (UNLIKELY(value == Object::sentinel().raw())) {
       SP[1] = 0;  // Result slot.
@@ -3162,10 +3178,10 @@
           NativeArguments(thread, 2, /* argv */ SP + 2, /* ret val */ SP + 1));
 
       function = FrameFunction(FP);
-      instance = reinterpret_cast<RawInstance*>(SP[2]);
-      field = reinterpret_cast<RawField*>(SP[3]);
-      offset_in_words = field->ptr()->host_offset_or_field_id_;
-      value = reinterpret_cast<RawInstance**>(instance->ptr())[offset_in_words];
+      instance = static_cast<InstancePtr>(SP[2]);
+      field = static_cast<FieldPtr>(SP[3]);
+      offset_in_words = Smi::Value(field->ptr()->host_offset_or_field_id_);
+      value = reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
     }
 
     *++SP = value;
@@ -3177,9 +3193,9 @@
         HANDLE_EXCEPTION;
       }
       // Reload objects after the call which may trigger GC.
-      field = reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
-      instance = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
-      value = reinterpret_cast<RawInstance**>(instance->ptr())[offset_in_words];
+      field = static_cast<FieldPtr>(FrameFunction(FP)->ptr()->data_);
+      instance = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+      value = reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
     }
 #endif
 
@@ -3218,28 +3234,28 @@
   {
     BYTECODE(VMInternal_ImplicitSetter, 0);
 
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kImplicitSetter);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kImplicitSetter);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
     // Field object is cached in function's data_.
-    RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
-    intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+    FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
+    intptr_t offset_in_words =
+        Smi::Value(field->ptr()->host_offset_or_field_id_);
     const intptr_t kArgc = 2;
-    RawInstance* instance =
-        reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
-    RawInstance* value =
-        reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[1]);
+    InstancePtr instance =
+        static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+    InstancePtr value = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[1]);
 
     if (!AssertAssignableField<false>(thread, pc, FP, SP, instance, field,
                                       value)) {
       HANDLE_EXCEPTION;
     }
     // Reload objects after the call which may trigger GC.
-    field = reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
-    instance = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
-    value = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[1]);
+    field = static_cast<FieldPtr>(FrameFunction(FP)->ptr()->data_);
+    instance = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+    value = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[1]);
 
     if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) {
       SP[1] = 0;  // Unused result of runtime call.
@@ -3253,9 +3269,9 @@
       }
 
       // Reload objects after the call which may trigger GC.
-      field = reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
-      instance = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
-      value = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[1]);
+      field = static_cast<FieldPtr>(FrameFunction(FP)->ptr()->data_);
+      instance = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+      value = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[1]);
     }
 
     const bool unboxing =
@@ -3264,29 +3280,29 @@
     classid_t guarded_cid = field->ptr()->guarded_cid_;
     if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) {
       double raw_value = Double::RawCast(value)->ptr()->value_;
-      RawDouble* box =
-          *(reinterpret_cast<RawDouble**>(instance->ptr()) + offset_in_words);
+      DoublePtr box =
+          *(reinterpret_cast<DoublePtr*>(instance->ptr()) + offset_in_words);
       ASSERT(box != null_value);  // Non-initializing store.
       box->ptr()->value_ = raw_value;
     } else if (unboxing && (guarded_cid == kFloat32x4Cid) &&
                supports_unboxed_simd128_) {
       simd128_value_t raw_value;
       raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_);
-      RawFloat32x4* box = *(reinterpret_cast<RawFloat32x4**>(instance->ptr()) +
-                            offset_in_words);
+      Float32x4Ptr box =
+          *(reinterpret_cast<Float32x4Ptr*>(instance->ptr()) + offset_in_words);
       ASSERT(box != null_value);  // Non-initializing store.
       raw_value.writeTo(box->ptr()->value_);
     } else if (unboxing && (guarded_cid == kFloat64x2Cid) &&
                supports_unboxed_simd128_) {
       simd128_value_t raw_value;
       raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_);
-      RawFloat64x2* box = *(reinterpret_cast<RawFloat64x2**>(instance->ptr()) +
-                            offset_in_words);
+      Float64x2Ptr box =
+          *(reinterpret_cast<Float64x2Ptr*>(instance->ptr()) + offset_in_words);
       ASSERT(box != null_value);  // Non-initializing store.
       raw_value.writeTo(box->ptr()->value_);
     } else {
-      instance->StorePointer(
-          reinterpret_cast<RawInstance**>(instance->ptr()) + offset_in_words,
+      instance->ptr()->StorePointer(
+          reinterpret_cast<InstancePtr*>(instance->ptr()) + offset_in_words,
           value, thread);
     }
 
@@ -3298,15 +3314,15 @@
   {
     BYTECODE(VMInternal_ImplicitStaticGetter, 0);
 
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kImplicitStaticGetter);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kImplicitStaticGetter);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
     // Field object is cached in function's data_.
-    RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
-    intptr_t field_id = field->ptr()->host_offset_or_field_id_;
-    RawInstance* value = thread->field_table_values()[field_id];
+    FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
+    intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
+    InstancePtr value = thread->field_table_values()[field_id];
     if (value == Object::sentinel().raw() ||
         value == Object::transition_sentinel().raw()) {
       SP[1] = 0;  // Unused result of invoking the initializer.
@@ -3317,9 +3333,9 @@
 
       // Reload objects after the call which may trigger GC.
       function = FrameFunction(FP);
-      field = reinterpret_cast<RawField*>(function->ptr()->data_);
+      field = static_cast<FieldPtr>(function->ptr()->data_);
       // The field is initialized by the runtime call, but not returned.
-      intptr_t field_id = field->ptr()->host_offset_or_field_id_;
+      intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
       value = thread->field_table_values()[field_id];
     }
 
@@ -3328,9 +3344,9 @@
 
 #if !defined(PRODUCT)
     if (UNLIKELY(Field::NeedsLoadGuardBit::decode(field->ptr()->kind_bits_))) {
-      if (!AssertAssignableField<true>(
-              thread, pc, FP, SP, reinterpret_cast<RawInstance*>(null_value),
-              field, value)) {
+      if (!AssertAssignableField<true>(thread, pc, FP, SP,
+                                       static_cast<InstancePtr>(null_value),
+                                       field, value)) {
         HANDLE_EXCEPTION;
       }
     }
@@ -3342,8 +3358,8 @@
   {
     BYTECODE(VMInternal_MethodExtractor, 0);
 
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kMethodExtractor);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kMethodExtractor);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
@@ -3359,21 +3375,22 @@
       HANDLE_EXCEPTION;
     }
 
-    RawContext* context = Context::RawCast(*SP--);
-    RawInstance* instance = Instance::RawCast(FrameArguments(FP, 1)[0]);
-    context->StorePointer(
-        reinterpret_cast<RawInstance**>(&context->ptr()->data()[0]), instance);
+    ContextPtr context = Context::RawCast(*SP--);
+    InstancePtr instance = Instance::RawCast(FrameArguments(FP, 1)[0]);
+    context->ptr()->StorePointer(
+        reinterpret_cast<InstancePtr*>(&context->ptr()->data()[0]), instance);
 
-    RawClosure* closure = Closure::RawCast(*SP);
-    closure->StorePointer(
+    ClosurePtr closure = Closure::RawCast(*SP);
+    closure->ptr()->StorePointer(
         &closure->ptr()->instantiator_type_arguments_,
         InterpreterHelpers::GetTypeArguments(thread, instance));
     // function_type_arguments_ is already null
     closure->ptr()->delayed_type_arguments_ =
         Object::empty_type_arguments().raw();
-    closure->StorePointer(&closure->ptr()->function_,
-                          Function::RawCast(FrameFunction(FP)->ptr()->data_));
-    closure->StorePointer(&closure->ptr()->context_, context);
+    closure->ptr()->StorePointer(
+        &closure->ptr()->function_,
+        Function::RawCast(FrameFunction(FP)->ptr()->data_));
+    closure->ptr()->StorePointer(&closure->ptr()->context_, context);
     // hash_ is already null
 
     DISPATCH();
@@ -3382,8 +3399,8 @@
   {
     BYTECODE(VMInternal_InvokeClosure, 0);
 
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kInvokeFieldDispatcher);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
@@ -3393,7 +3410,7 @@
     const intptr_t argc =
         InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
 
-    RawClosure* receiver =
+    ClosurePtr receiver =
         Closure::RawCast(FrameArguments(FP, argc)[receiver_idx]);
     function = receiver->ptr()->function_;
 
@@ -3404,8 +3421,8 @@
   {
     BYTECODE(VMInternal_InvokeField, 0);
 
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kInvokeFieldDispatcher);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
@@ -3415,7 +3432,7 @@
     const intptr_t argc =
         InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
 
-    RawObject* receiver = FrameArguments(FP, argc)[receiver_idx];
+    ObjectPtr receiver = FrameArguments(FP, argc)[receiver_idx];
 
     // Invoke field getter on receiver.
     {
@@ -3480,8 +3497,8 @@
     }
 
     // Copy arguments into the newly allocated array.
-    RawObject** argv = FrameArguments(FP, argc);
-    RawArray* array = static_cast<RawArray*>(SP[4]);
+    ObjectPtr* argv = FrameArguments(FP, argc);
+    ArrayPtr array = static_cast<ArrayPtr>(SP[4]);
     ASSERT(array->GetClassId() == kArrayCid);
     for (intptr_t i = 0; i < argc; i++) {
       array->ptr()->data()[i] = argv[i];
@@ -3506,16 +3523,17 @@
 
   {
     BYTECODE(VMInternal_ForwardDynamicInvocation, 0);
-    RawFunction* function = FrameFunction(FP);
+    FunctionPtr function = FrameFunction(FP);
     ASSERT(Function::kind(function) ==
-           RawFunction::kDynamicInvocationForwarder);
+           FunctionLayout::kDynamicInvocationForwarder);
 
     BUMP_USAGE_COUNTER_ON_ENTRY(function);
 
-    RawArray* checks = Array::RawCast(function->ptr()->data_);
-    RawFunction* target = Function::RawCast(checks->ptr()->data()[0]);
-    ASSERT(Function::kind(target) != RawFunction::kDynamicInvocationForwarder);
-    RawBytecode* target_bytecode = target->ptr()->bytecode_;
+    ArrayPtr checks = Array::RawCast(function->ptr()->data_);
+    FunctionPtr target = Function::RawCast(checks->ptr()->data()[0]);
+    ASSERT(Function::kind(target) !=
+           FunctionLayout::kDynamicInvocationForwarder);
+    BytecodePtr target_bytecode = target->ptr()->bytecode_;
     ASSERT(target_bytecode != Bytecode::null());
     ASSERT(target_bytecode->IsBytecode());
 
@@ -3543,7 +3561,7 @@
     const intptr_t argc =
         InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
 
-    RawInstance* receiver =
+    InstancePtr receiver =
         Instance::RawCast(FrameArguments(FP, argc)[receiver_idx]);
     SP[5] = InterpreterHelpers::GetTypeArguments(thread, receiver);
 
@@ -3564,7 +3582,7 @@
     }
 
     for (intptr_t i = 2; i < len; i++) {
-      RawParameterTypeCheck* check =
+      ParameterTypeCheckPtr check =
           ParameterTypeCheck::RawCast(checks->ptr()->data()[i]);
 
       if (LIKELY(check->ptr()->index_ != 0)) {
@@ -3610,35 +3628,37 @@
 
   {
     BYTECODE(VMInternal_NoSuchMethodDispatcher, 0);
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kNoSuchMethodDispatcher);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) == FunctionLayout::kNoSuchMethodDispatcher);
     goto NoSuchMethodFromPrologue;
   }
 
   {
     BYTECODE(VMInternal_ImplicitStaticClosure, 0);
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) ==
+           FunctionLayout::kImplicitClosureFunction);
     UNIMPLEMENTED();
     DISPATCH();
   }
 
   {
     BYTECODE(VMInternal_ImplicitInstanceClosure, 0);
-    RawFunction* function = FrameFunction(FP);
-    ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
+    FunctionPtr function = FrameFunction(FP);
+    ASSERT(Function::kind(function) ==
+           FunctionLayout::kImplicitClosureFunction);
     UNIMPLEMENTED();
     DISPATCH();
   }
 
   {
   TailCallSP1:
-    RawFunction* function = Function::RawCast(SP[1]);
+    FunctionPtr function = Function::RawCast(SP[1]);
 
     for (;;) {
       if (Function::HasBytecode(function)) {
         ASSERT(function->IsFunction());
-        RawBytecode* bytecode = function->ptr()->bytecode_;
+        BytecodePtr bytecode = function->ptr()->bytecode_;
         ASSERT(bytecode->IsBytecode());
         FP[kKBCFunctionSlotFromFp] = function;
         FP[kKBCPcMarkerSlotFromFp] = bytecode;
@@ -3654,13 +3674,13 @@
         const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
         const intptr_t argc =
             InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
-        RawObject** argv = FrameArguments(FP, argc);
+        ObjectPtr* argv = FrameArguments(FP, argc);
         for (intptr_t i = 0; i < argc; i++) {
           *++SP = argv[i];
         }
 
-        RawObject** call_base = SP - argc + 1;
-        RawObject** call_top = SP + 1;
+        ObjectPtr* call_base = SP - argc + 1;
+        ObjectPtr* call_top = SP + 1;
         call_top[0] = function;
         if (!InvokeCompiled(thread, function, call_base, call_top, &pc, &FP,
                             &SP)) {
@@ -3691,14 +3711,14 @@
   // Helper used to handle noSuchMethod on closures.
   {
   NoSuchMethodFromPrologue:
-    RawFunction* function = FrameFunction(FP);
+    FunctionPtr function = FrameFunction(FP);
 
     const intptr_t type_args_len =
         InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
     const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
     const intptr_t argc =
         InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
-    RawObject** args = FrameArguments(FP, argc);
+    ObjectPtr* args = FrameArguments(FP, argc);
 
     SP[1] = null_value;
     SP[2] = args[receiver_idx];
@@ -3717,7 +3737,7 @@
       }
 
       // Copy arguments into the newly allocated array.
-      RawArray* array = static_cast<RawArray*>(SP[5]);
+      ArrayPtr array = static_cast<ArrayPtr>(SP[5]);
       ASSERT(array->GetClassId() == kArrayCid);
       for (intptr_t i = 0; i < argc; i++) {
         array->ptr()->data()[i] = args[i];
@@ -3774,10 +3794,9 @@
     FP = fp_;
     pc = pc_;
     if (IsEntryFrameMarker(pc)) {
-      pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]);
-      argdesc_ =
-          reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
-      uword exit_fp = reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
+      pp_ = static_cast<ObjectPoolPtr>(fp_[kKBCSavedPpSlotFromEntryFp]);
+      argdesc_ = static_cast<ArrayPtr>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
+      uword exit_fp = static_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
       thread->set_top_exit_frame_info(exit_fp);
       thread->set_top_resource(top_resource);
       thread->set_vm_tag(vm_tag);
@@ -3817,13 +3836,13 @@
   // in the previous C++ frames.
   StackResource::Unwind(thread);
 
-  fp_ = reinterpret_cast<RawObject**>(fp);
+  fp_ = reinterpret_cast<ObjectPtr*>(fp);
 
   if (pc == StubCode::RunExceptionHandler().EntryPoint()) {
     // The RunExceptionHandler stub is a placeholder.  We implement
     // its behavior here.
-    RawObject* raw_exception = thread->active_exception();
-    RawObject* raw_stacktrace = thread->active_stacktrace();
+    ObjectPtr raw_exception = thread->active_exception();
+    ObjectPtr raw_stacktrace = thread->active_stacktrace();
     ASSERT(raw_exception != Object::null());
     thread->set_active_exception(Object::null_object());
     thread->set_active_stacktrace(Object::null_object());
@@ -3844,8 +3863,8 @@
 }
 
 void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&pp_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&argdesc_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&pp_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&argdesc_));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index 03d913a..bc76fc9 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -10,6 +10,7 @@
 
 #include "vm/compiler/method_recognizer.h"
 #include "vm/constants_kbc.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
@@ -18,17 +19,6 @@
 class InterpreterSetjmpBuffer;
 class Isolate;
 class ObjectPointerVisitor;
-class RawArray;
-class RawField;
-class RawFunction;
-class RawICData;
-class RawImmutableArray;
-class RawInstance;
-class RawObject;
-class RawObjectPool;
-class RawString;
-class RawSubtypeTestCache;
-class RawTypeArguments;
 class Thread;
 
 class LookupCache : public ValueObject {
@@ -41,20 +31,20 @@
 
   void Clear();
   bool Lookup(intptr_t receiver_cid,
-              RawString* function_name,
-              RawArray* arguments_descriptor,
-              RawFunction** target) const;
+              StringPtr function_name,
+              ArrayPtr arguments_descriptor,
+              FunctionPtr* target) const;
   void Insert(intptr_t receiver_cid,
-              RawString* function_name,
-              RawArray* arguments_descriptor,
-              RawFunction* target);
+              StringPtr function_name,
+              ArrayPtr arguments_descriptor,
+              FunctionPtr target);
 
  private:
   struct Entry {
     intptr_t receiver_cid;
-    RawString* function_name;
-    RawArray* arguments_descriptor;
-    RawFunction* target;
+    StringPtr function_name;
+    ArrayPtr arguments_descriptor;
+    FunctionPtr target;
   };
 
   static const intptr_t kNumEntries = 1024;
@@ -69,8 +59,8 @@
 // instruction returning the value in result. Otherwise interpreter proceeds to
 // execute the body of the function.
 typedef bool (*IntrinsicHandler)(Thread* thread,
-                                 RawObject** FP,
-                                 RawObject** result);
+                                 ObjectPtr* FP,
+                                 ObjectPtr* result);
 
 class Interpreter {
  public:
@@ -104,16 +94,16 @@
     return reinterpret_cast<word>(pc) == kEntryFramePcMarker;
   }
 
-  RawObject* Call(const Function& function,
-                  const Array& arguments_descriptor,
-                  const Array& arguments,
-                  Thread* thread);
+  ObjectPtr Call(const Function& function,
+                 const Array& arguments_descriptor,
+                 const Array& arguments,
+                 Thread* thread);
 
-  RawObject* Call(RawFunction* function,
-                  RawArray* argdesc,
-                  intptr_t argc,
-                  RawObject* const* argv,
-                  Thread* thread);
+  ObjectPtr Call(FunctionPtr function,
+                 ArrayPtr argdesc,
+                 intptr_t argc,
+                 ObjectPtr const* argv,
+                 Thread* thread);
 
   void JumpToFrame(uword pc, uword sp, uword fp, Thread* thread);
 
@@ -137,113 +127,113 @@
   uword overflow_stack_limit_;
   uword stack_limit_;
 
-  RawObject** volatile fp_;
+  ObjectPtr* volatile fp_;
   const KBCInstr* volatile pc_;
   DEBUG_ONLY(uint64_t icount_;)
 
   InterpreterSetjmpBuffer* last_setjmp_buffer_;
 
-  RawObjectPool* pp_;  // Pool Pointer.
-  RawArray* argdesc_;  // Arguments Descriptor: used to pass information between
-                       // call instruction and the function entry.
-  RawObject* special_[KernelBytecode::kSpecialIndexCount];
+  ObjectPoolPtr pp_;  // Pool Pointer.
+  ArrayPtr argdesc_;  // Arguments Descriptor: used to pass information between
+                      // call instruction and the function entry.
+  ObjectPtr special_[KernelBytecode::kSpecialIndexCount];
 
   LookupCache lookup_cache_;
 
   void Exit(Thread* thread,
-            RawObject** base,
-            RawObject** exit_frame,
+            ObjectPtr* base,
+            ObjectPtr* exit_frame,
             const KBCInstr* pc);
 
   bool Invoke(Thread* thread,
-              RawObject** call_base,
-              RawObject** call_top,
+              ObjectPtr* call_base,
+              ObjectPtr* call_top,
               const KBCInstr** pc,
-              RawObject*** FP,
-              RawObject*** SP);
+              ObjectPtr** FP,
+              ObjectPtr** SP);
 
   bool InvokeCompiled(Thread* thread,
-                      RawFunction* function,
-                      RawObject** call_base,
-                      RawObject** call_top,
+                      FunctionPtr function,
+                      ObjectPtr* call_base,
+                      ObjectPtr* call_top,
                       const KBCInstr** pc,
-                      RawObject*** FP,
-                      RawObject*** SP);
+                      ObjectPtr** FP,
+                      ObjectPtr** SP);
 
   bool InvokeBytecode(Thread* thread,
-                      RawFunction* function,
-                      RawObject** call_base,
-                      RawObject** call_top,
+                      FunctionPtr function,
+                      ObjectPtr* call_base,
+                      ObjectPtr* call_top,
                       const KBCInstr** pc,
-                      RawObject*** FP,
-                      RawObject*** SP);
+                      ObjectPtr** FP,
+                      ObjectPtr** SP);
 
   bool InstanceCall(Thread* thread,
-                    RawString* target_name,
-                    RawObject** call_base,
-                    RawObject** call_top,
+                    StringPtr target_name,
+                    ObjectPtr* call_base,
+                    ObjectPtr* call_top,
                     const KBCInstr** pc,
-                    RawObject*** FP,
-                    RawObject*** SP);
+                    ObjectPtr** FP,
+                    ObjectPtr** SP);
 
   bool CopyParameters(Thread* thread,
                       const KBCInstr** pc,
-                      RawObject*** FP,
-                      RawObject*** SP,
+                      ObjectPtr** FP,
+                      ObjectPtr** SP,
                       const intptr_t num_fixed_params,
                       const intptr_t num_opt_pos_params,
                       const intptr_t num_opt_named_params);
 
   bool AssertAssignable(Thread* thread,
                         const KBCInstr* pc,
-                        RawObject** FP,
-                        RawObject** call_top,
-                        RawObject** args,
-                        RawSubtypeTestCache* cache);
+                        ObjectPtr* FP,
+                        ObjectPtr* call_top,
+                        ObjectPtr* args,
+                        SubtypeTestCachePtr cache);
   template <bool is_getter>
   bool AssertAssignableField(Thread* thread,
                              const KBCInstr* pc,
-                             RawObject** FP,
-                             RawObject** SP,
-                             RawInstance* instance,
-                             RawField* field,
-                             RawInstance* value);
+                             ObjectPtr* FP,
+                             ObjectPtr* SP,
+                             InstancePtr instance,
+                             FieldPtr field,
+                             InstancePtr value);
 
   bool AllocateMint(Thread* thread,
                     int64_t value,
                     const KBCInstr* pc,
-                    RawObject** FP,
-                    RawObject** SP);
+                    ObjectPtr* FP,
+                    ObjectPtr* SP);
   bool AllocateDouble(Thread* thread,
                       double value,
                       const KBCInstr* pc,
-                      RawObject** FP,
-                      RawObject** SP);
+                      ObjectPtr* FP,
+                      ObjectPtr* SP);
   bool AllocateFloat32x4(Thread* thread,
                          simd128_value_t value,
                          const KBCInstr* pc,
-                         RawObject** FP,
-                         RawObject** SP);
+                         ObjectPtr* FP,
+                         ObjectPtr* SP);
   bool AllocateFloat64x2(Thread* thread,
                          simd128_value_t value,
                          const KBCInstr* pc,
-                         RawObject** FP,
-                         RawObject** SP);
+                         ObjectPtr* FP,
+                         ObjectPtr* SP);
   bool AllocateArray(Thread* thread,
-                     RawTypeArguments* type_args,
-                     RawObject* length,
+                     TypeArgumentsPtr type_args,
+                     ObjectPtr length,
                      const KBCInstr* pc,
-                     RawObject** FP,
-                     RawObject** SP);
+                     ObjectPtr* FP,
+                     ObjectPtr* SP);
   bool AllocateContext(Thread* thread,
                        intptr_t num_variables,
                        const KBCInstr* pc,
-                       RawObject** FP,
-                       RawObject** SP);
+                       ObjectPtr* FP,
+                       ObjectPtr* SP);
   bool AllocateClosure(Thread* thread,
                        const KBCInstr* pc,
-                       RawObject** FP,
-                       RawObject** SP);
+                       ObjectPtr* FP,
+                       ObjectPtr* SP);
 
 #if defined(DEBUG)
   // Returns true if tracing of executed instructions is enabled.
diff --git a/runtime/vm/intrusive_dlist.h b/runtime/vm/intrusive_dlist.h
index 45c4365..43acaee 100644
--- a/runtime/vm/intrusive_dlist.h
+++ b/runtime/vm/intrusive_dlist.h
@@ -108,20 +108,20 @@
     prev_ = nullptr;
   }
 
-  bool IsEmpty() {
+  bool IsEmpty() const {
     bool result = next_ == this;
     ASSERT(result == (prev_ == this));
     return result;
   }
 
-  bool IsLinked() {
+  bool IsLinked() const {
     ASSERT((next_ == nullptr) == (prev_ == nullptr));
     return next_ != nullptr;
   }
 
-  IntrusiveDListEntry<T, N>* Prev() { return prev_; }
+  IntrusiveDListEntry<T, N>* Prev() const { return prev_; }
 
-  IntrusiveDListEntry<T, N>* Next() { return next_; }
+  IntrusiveDListEntry<T, N>* Next() const { return next_; }
 
   friend class IntrusiveDList<T, N>;
 
@@ -143,9 +143,9 @@
              IntrusiveDListEntry<ContainerType, I>* entry)
         : head_(head), entry_(entry) {}
 
-    inline ContainerType* operator->() { return entry_->container(); }
+    inline ContainerType* operator->() const { return entry_->container(); }
 
-    inline ContainerType* operator*() { return entry_->container(); }
+    inline ContainerType* operator*() const { return entry_->container(); }
 
     inline bool operator==(const Iterator<ContainerType, I>& other) const {
       return entry_ == other.entry_;
@@ -180,18 +180,18 @@
 
   // NOTE: This function only checks whether [a] is linked inside *a*
   // [IntrusiveDList].
-  inline bool IsInList(T* a) { return convert(a)->IsLinked(); }
+  inline bool IsInList(T* a) const { return convert(a)->IsLinked(); }
 
   inline void Remove(T* a) { convert(a)->Remove(); }
 
-  inline bool IsEmpty() { return head_.IsEmpty(); }
+  inline bool IsEmpty() const { return head_.IsEmpty(); }
 
-  inline T* First() {
+  inline T* First() const {
     ASSERT(!IsEmpty());
     return head_.Next()->container();
   }
 
-  inline T* Last() {
+  inline T* Last() const {
     ASSERT(!IsEmpty());
     return head_.Prev()->container();
   }
@@ -227,10 +227,34 @@
     return next;
   }
 
+  bool ContainsForDebugging(const T* a) {
+    for (auto entry : *this) {
+      if (entry == a) return true;
+    }
+    return false;
+  }
+
+  void AppendList(IntrusiveDList<T, N>* other) {
+    if (other->IsEmpty()) return;
+
+    auto other_first = other->head_.Next();
+    auto other_last = other->head_.Prev();
+    other->head_.next_ = &other->head_;
+    other->head_.prev_ = &other->head_;
+
+    auto prev = head_.prev_;
+
+    prev->next_ = other_first;
+    other_first->prev_ = prev;
+
+    other_last->next_ = &head_;
+    head_.prev_ = other_last;
+  }
+
  private:
   Entry head_;
 
-  Entry* convert(T* entry) { return static_cast<Entry*>(entry); }
+  Entry* convert(T* entry) const { return static_cast<Entry*>(entry); }
 };
 
 }  // namespace dart.
diff --git a/runtime/vm/intrusive_dlist_test.cc b/runtime/vm/intrusive_dlist_test.cc
index fdf72c0..041791b 100644
--- a/runtime/vm/intrusive_dlist_test.cc
+++ b/runtime/vm/intrusive_dlist_test.cc
@@ -152,4 +152,58 @@
   EXPECT(all.IsEmpty());
 }
 
+UNIT_TEST_CASE(IntrusiveDListAppendListTest) {
+  // Append to empty list.
+  {
+    IntrusiveDList<Item> all;
+    IntrusiveDList<Item> other;
+
+    Item a1(1, 11), a2(2, 12);
+    all.Append(&a1);
+    all.Append(&a2);
+
+    other.AppendList(&all);
+
+    EXPECT(all.IsEmpty());
+    EXPECT(!other.IsEmpty());
+    EXPECT_EQ(&a1, other.First());
+    EXPECT_EQ(&a2, other.Last());
+
+    auto it = other.Begin();
+    EXPECT_EQ(&a1, *it);
+    it = other.Erase(it);
+    EXPECT_EQ(&a2, *it);
+    it = other.Erase(it);
+    EXPECT(it == other.end());
+  }
+  // Append to non-empty list.
+  {
+    IntrusiveDList<Item> all;
+    IntrusiveDList<Item> other;
+
+    Item a1(1, 11), a2(2, 12);
+    all.Append(&a1);
+    all.Append(&a2);
+
+    Item o1(1, 11);
+    other.Append(&o1);
+
+    other.AppendList(&all);
+
+    EXPECT(all.IsEmpty());
+    EXPECT(!other.IsEmpty());
+    EXPECT_EQ(&o1, other.First());
+    EXPECT_EQ(&a2, other.Last());
+
+    auto it = other.Begin();
+    EXPECT_EQ(&o1, *it);
+    it = other.Erase(it);
+    EXPECT_EQ(&a1, *it);
+    it = other.Erase(it);
+    EXPECT_EQ(&a2, *it);
+    it = other.Erase(it);
+    EXPECT(it == other.end());
+  }
+}
+
 }  // namespace dart.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d9d98f0..ccca676 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -79,6 +79,7 @@
     FLAG_background_compilation = false;  // Timing dependent.
     FLAG_concurrent_mark = false;         // Timing dependent.
     FLAG_concurrent_sweep = false;        // Timing dependent.
+    FLAG_scavenger_tasks = 0;             // Timing dependent.
     FLAG_random_seed = 0x44617274;        // "Dart"
   }
 }
@@ -87,6 +88,16 @@
                     deterministic,
                     "Enable deterministic mode.");
 
+int FLAG_null_safety = kNullSafetyOptionUnspecified;
+static void NullSafetyHandler(bool value) {
+  FLAG_null_safety = value ? kNullSafetyOptionStrong : kNullSafetyOptionWeak;
+}
+
+DEFINE_FLAG_HANDLER(
+    NullSafetyHandler,
+    null_safety,
+    "Respect the nullability of types in casts and instance checks.");
+
 // Quick access to the locally defined thread() and isolate() methods.
 #define T (thread())
 #define I (isolate())
@@ -116,7 +127,7 @@
   }
 }
 
-static RawInstance* DeserializeMessage(Thread* thread, Message* message) {
+static InstancePtr DeserializeMessage(Thread* thread, Message* message) {
   if (message == NULL) {
     return Instance::null();
   }
@@ -220,7 +231,8 @@
 };
 
 IsolateGroup::IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
-                           void* embedder_data)
+                           void* embedder_data,
+                           ObjectStore* object_store)
     : embedder_data_(embedder_data),
       isolates_lock_(new SafepointRwLock()),
       isolates_(),
@@ -233,14 +245,37 @@
       thread_registry_(new ThreadRegistry()),
       safepoint_handler_(new SafepointHandler(this)),
       shared_class_table_(new SharedClassTable()),
+      object_store_(object_store),
+#if defined(DART_PRECOMPILED_RUNTIME)
+      class_table_(new ClassTable(shared_class_table_.get())),
+#else
+      class_table_(nullptr),
+#endif
+      symbols_lock_(new SafepointRwLock()),
       store_buffer_(new StoreBuffer()),
-      heap_(nullptr) {
+      heap_(nullptr),
+      saved_unlinked_calls_(Array::null()) {
   {
     WriteRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
     id_ = isolate_group_random_->NextUInt64();
   }
 }
 
+IsolateGroup::IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
+                           void* embedder_data)
+    : IsolateGroup(source,
+                   embedder_data,
+#if !defined(DART_PRECOMPILED_RUNTIME)
+                   // in JIT, with --enable_isolate_groups keep object store
+                   // on isolate, rather than on isolate group
+                   FLAG_enable_isolate_groups ? nullptr :
+#endif
+                                              new ObjectStore()) {
+  if (object_store() != nullptr) {
+    object_store()->InitStubs();
+  }
+}
+
 IsolateGroup::~IsolateGroup() {
   // Finalize any weak persistent handles with a non-null referent.
   FinalizeWeakPersistentHandlesVisitor visitor(this);
@@ -249,6 +284,9 @@
   // Ensure we destroy the heap before the other members.
   heap_ = nullptr;
   ASSERT(marking_stack_ == nullptr);
+
+  delete reverse_pc_lookup_cache_;
+  reverse_pc_lookup_cache_ = nullptr;
 }
 
 void IsolateGroup::RegisterIsolate(Isolate* isolate) {
@@ -336,6 +374,10 @@
   heap_ = std::move(heap);
 }
 
+void IsolateGroup::set_saved_unlinked_calls(const Array& saved_unlinked_calls) {
+  saved_unlinked_calls_ = saved_unlinked_calls.raw();
+}
+
 Thread* IsolateGroup::ScheduleThreadLocked(MonitorLocker* ml,
                                            Thread* existing_mutator_thread,
                                            bool is_vm_isolate,
@@ -398,10 +440,11 @@
                                           Thread* thread,
                                           bool is_mutator,
                                           bool bypass_safepoint) {
+  thread->heap()->new_space()->AbandonRemainingTLAB(thread);
+
   // Clear since GC will not visit the thread once it is unscheduled. Do this
   // under the thread lock to prevent races with the GC visiting thread roots.
   if (!is_mutator) {
-    thread->heap()->new_space()->AbandonRemainingTLAB(thread);
     thread->ClearReusableHandles();
   }
 
@@ -613,6 +656,15 @@
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 }
 
+Bequest::~Bequest() {
+  IsolateGroup* isolate_group = IsolateGroup::Current();
+  CHECK_ISOLATE_GROUP(isolate_group);
+  NoSafepointScope no_safepoint_scope;
+  ApiState* state = isolate_group->api_state();
+  ASSERT(state != nullptr);
+  state->FreePersistentHandle(handle_);
+}
+
 void Isolate::RegisterClass(const Class& cls) {
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   if (group()->IsReloading()) {
@@ -647,7 +699,7 @@
         !class_table()->HasValidClassAt(cid)) {
       continue;
     }
-    if ((cid == kTypeArgumentsCid) || RawObject::IsStringClassId(cid)) {
+    if ((cid == kTypeArgumentsCid) || IsStringClassId(cid)) {
       // TypeArguments and Symbols have special tables for canonical objects
       // that aren't based on address.
       continue;
@@ -693,6 +745,13 @@
       writer.WriteMessage(msg, main_port(), Message::kOOBPriority));
 }
 
+void Isolate::set_object_store(ObjectStore* object_store) {
+  ASSERT(cached_object_store_ == nullptr);
+  object_store_shared_ptr_.reset(object_store);
+  cached_object_store_ = object_store;
+  isolate_object_store_->set_object_store(object_store);
+}
+
 class IsolateMessageHandler : public MessageHandler {
  public:
   explicit IsolateMessageHandler(Isolate* isolate);
@@ -716,7 +775,7 @@
  private:
   // A result of false indicates that the isolate should terminate the
   // processing of further events.
-  RawError* HandleLibMessage(const Array& message);
+  ErrorPtr HandleLibMessage(const Array& message);
 
   MessageStatus ProcessUnhandledException(const Error& result);
   Isolate* isolate_;
@@ -734,7 +793,7 @@
 // Isolate library OOB messages are fixed sized arrays which have the
 // following format:
 // [ OOB dispatch, Isolate library dispatch, <message specific data> ]
-RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
+ErrorPtr IsolateMessageHandler::HandleLibMessage(const Array& message) {
   if (message.Length() < 2) return Error::null();
   Zone* zone = T->zone();
   const Object& type = Object::Handle(zone, message.At(1));
@@ -1000,6 +1059,11 @@
     msg_obj = message->raw_obj();
     // We should only be sending RawObjects that can be converted to CObjects.
     ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
+  } else if (message->IsBequest()) {
+    Bequest* bequest = message->bequest();
+    PersistentHandle* handle = bequest->handle();
+    const Object& obj = Object::Handle(zone, handle->raw());
+    msg_obj = obj.raw();
   } else {
     MessageSnapshotReader reader(message.get(), thread);
     msg_obj = reader.ReadObject();
@@ -1208,7 +1272,7 @@
       // exception.
       if (result.IsUnhandledException()) {
         const UnhandledException& error = UnhandledException::Cast(result);
-        RawInstance* exception = error.exception();
+        InstancePtr exception = error.exception();
         if ((exception == I->object_store()->out_of_memory()) ||
             (exception == I->object_store()->stack_overflow())) {
           // We didn't notify the debugger when the stack was full. Do it now.
@@ -1328,9 +1392,17 @@
       current_tag_(UserTag::null()),
       default_tag_(UserTag::null()),
       ic_miss_code_(Code::null()),
-      class_table_(isolate_group->class_table()),
+      shared_class_table_(isolate_group->shared_class_table()),
       field_table_(new FieldTable()),
       isolate_group_(isolate_group),
+      isolate_object_store_(
+          new IsolateObjectStore(isolate_group->object_store())),
+      object_store_shared_ptr_(isolate_group->object_store_shared_ptr()),
+#if defined(DART_PRECOMPILED_RUNTIME)
+      class_table_(isolate_group->class_table_shared_ptr()),
+#else
+      class_table_(new ClassTable(shared_class_table_)),
+#endif
 #if !defined(DART_PRECOMPILED_RUNTIME)
       native_callback_trampolines_(),
 #endif
@@ -1351,7 +1423,7 @@
       start_time_micros_(OS::GetCurrentMonotonicMicros()),
       random_(),
       mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
-      symbols_mutex_(NOT_IN_PRODUCT("Isolate::symbols_mutex_")),
+      symbols_lock_(new SafepointRwLock()),
       type_canonicalization_mutex_(
           NOT_IN_PRODUCT("Isolate::type_canonicalization_mutex_")),
       constant_canonicalization_mutex_(
@@ -1372,6 +1444,8 @@
       spawn_count_monitor_(),
       handler_info_cache_(),
       catch_entry_moves_cache_() {
+  cached_object_store_ = object_store_shared_ptr_.get();
+  cached_class_table_table_ = class_table_->table();
   FlagsCopyFrom(api_flags);
   SetErrorsFatal(true);
   // TODO(asiva): A Thread is not available here, need to figure out
@@ -1403,12 +1477,6 @@
   // RELEASE_ASSERT(reload_context_ == NULL);
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
-  delete reverse_pc_lookup_cache_;
-  reverse_pc_lookup_cache_ = nullptr;
-
-  delete dispatch_table_;
-  dispatch_table_ = nullptr;
-
   if (FLAG_enable_interpreter) {
     delete background_compiler_;
     background_compiler_ = nullptr;
@@ -1427,7 +1495,6 @@
 #endif  // !defined(PRODUCT)
 
   free(name_);
-  delete object_store_;
   delete field_table_;
 #if defined(USING_SIMULATOR)
   delete simulator_;
@@ -1484,6 +1551,21 @@
                               bool is_vm_isolate) {
   Isolate* result = new Isolate(isolate_group, api_flags);
   result->BuildName(name_prefix);
+  if (!is_vm_isolate) {
+    // vm isolate object store is initialized later, after null instance
+    // is created (in Dart::Init).
+    // Non-vm isolates need to have isolate object store initialized is that
+    // exit_listeners have to be null-initialized as they will be used if
+    // we fail to create isolate below, have to do low level shutdown.
+    if (result->object_store() == nullptr) {
+      // in JIT with --enable-isolate-groups each isolate still
+      // has to have its own object store
+      result->set_object_store(new ObjectStore());
+      result->object_store()->InitStubs();
+    }
+    result->isolate_object_store()->Init();
+  }
+
   ASSERT(result != nullptr);
 
 #if !defined(PRODUCT)
@@ -1526,13 +1608,27 @@
   isolate_group->RegisterIsolate(result);
 
   if (ServiceIsolate::NameEquals(name_prefix)) {
+    // For now the service isolate always runs in weak mode.
+    result->set_null_safety(false);
     ASSERT(!ServiceIsolate::Exists());
     ServiceIsolate::SetServiceIsolate(result);
 #if !defined(DART_PRECOMPILED_RUNTIME)
   } else if (KernelIsolate::NameEquals(name_prefix)) {
+    // For now the kernel isolate always runs in weak mode.
+    result->set_null_safety(false);
     ASSERT(!KernelIsolate::Exists());
     KernelIsolate::SetKernelIsolate(result);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  } else if (FLAG_null_safety != kNullSafetyOptionUnspecified) {
+    // If the null-safety option is specified on the command line then
+    // use the value specified on the command line, if the dill file being
+    // loaded is in a different mode than that specified on the command line
+    // we will get an error during kernel file loading.
+    result->set_null_safety(FLAG_null_safety == kNullSafetyOptionStrong);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  } else if (!KernelIsolate::GetExperimentalFlag("non-nullable")) {
+    result->set_null_safety(false);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   }
 
 #if !defined(PRODUCT)
@@ -1562,9 +1658,9 @@
   return mutator_thread_;
 }
 
-RawObject* Isolate::CallTagHandler(Dart_LibraryTag tag,
-                                   const Object& arg1,
-                                   const Object& arg2) {
+ObjectPtr Isolate::CallTagHandler(Dart_LibraryTag tag,
+                                  const Object& arg1,
+                                  const Object& arg2) {
   Thread* thread = Thread::Current();
   Api::Scope api_scope(thread);
   Dart_Handle api_arg1 = Api::NewHandle(thread, arg1.raw());
@@ -1607,6 +1703,17 @@
   return OS::GetCurrentMonotonicMicros() - start_time_micros_;
 }
 
+Dart_Port Isolate::origin_id() {
+  MutexLocker ml(&origin_id_mutex_);
+  return origin_id_;
+}
+
+void Isolate::set_origin_id(Dart_Port id) {
+  MutexLocker ml(&origin_id_mutex_);
+  ASSERT((id == main_port_ && origin_id_ == 0) || (origin_id_ == main_port_));
+  origin_id_ = id;
+}
+
 bool Isolate::IsPaused() const {
 #if defined(PRODUCT)
   return false;
@@ -1615,7 +1722,7 @@
 #endif  // !defined(PRODUCT)
 }
 
-RawError* Isolate::PausePostRequest() {
+ErrorPtr Isolate::PausePostRequest() {
 #if !defined(PRODUCT)
   if (debugger_ == nullptr) {
     return Error::null();
@@ -1663,7 +1770,7 @@
   RELEASE_ASSERT(isolates_.First() == isolates_.Last());
   RELEASE_ASSERT(isolates_.First() == Isolate::Current());
 
-  auto shared_class_table = IsolateGroup::Current()->class_table();
+  auto shared_class_table = IsolateGroup::Current()->shared_class_table();
   std::shared_ptr<IsolateGroupReloadContext> group_reload_context(
       new IsolateGroupReloadContext(this, shared_class_table, js));
   group_reload_context_ = group_reload_context;
@@ -1696,7 +1803,7 @@
   RELEASE_ASSERT(isolates_.First() == isolates_.Last());
   RELEASE_ASSERT(isolates_.First() == Isolate::Current());
 
-  auto shared_class_table = IsolateGroup::Current()->class_table();
+  auto shared_class_table = IsolateGroup::Current()->shared_class_table();
   std::shared_ptr<IsolateGroupReloadContext> group_reload_context(
       new IsolateGroupReloadContext(this, shared_class_table, js));
   group_reload_context_ = group_reload_context;
@@ -1801,7 +1908,7 @@
       compiler::target::kSmiMax / (6 * kWordSize);
 
   const GrowableObjectArray& caps = GrowableObjectArray::Handle(
-      current_zone(), object_store()->resume_capabilities());
+      current_zone(), isolate_object_store()->resume_capabilities());
   Capability& current = Capability::Handle(current_zone());
   intptr_t insertion_index = -1;
   for (intptr_t i = 0; i < caps.Length(); i++) {
@@ -1830,7 +1937,7 @@
 
 bool Isolate::RemoveResumeCapability(const Capability& capability) {
   const GrowableObjectArray& caps = GrowableObjectArray::Handle(
-      current_zone(), object_store()->resume_capabilities());
+      current_zone(), isolate_object_store()->resume_capabilities());
   Capability& current = Capability::Handle(current_zone());
   for (intptr_t i = 0; i < caps.Length(); i++) {
     current ^= caps.At(i);
@@ -1853,7 +1960,7 @@
       compiler::target::kSmiMax / (12 * kWordSize);
 
   const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
-      current_zone(), object_store()->exit_listeners());
+      current_zone(), isolate_object_store()->exit_listeners());
   SendPort& current = SendPort::Handle(current_zone());
   intptr_t insertion_index = -1;
   for (intptr_t i = 0; i < listeners.Length(); i += 2) {
@@ -1884,7 +1991,7 @@
 
 void Isolate::RemoveExitListener(const SendPort& listener) {
   const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
-      current_zone(), object_store()->exit_listeners());
+      current_zone(), isolate_object_store()->exit_listeners());
   SendPort& current = SendPort::Handle(current_zone());
   for (intptr_t i = 0; i < listeners.Length(); i += 2) {
     current ^= listeners.At(i);
@@ -1900,7 +2007,7 @@
 
 void Isolate::NotifyExitListeners() {
   const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
-      current_zone(), this->object_store()->exit_listeners());
+      current_zone(), isolate_object_store()->exit_listeners());
   if (listeners.IsNull()) return;
 
   SendPort& listener = SendPort::Handle(current_zone());
@@ -1921,7 +2028,7 @@
       compiler::target::kSmiMax / (6 * kWordSize);
 
   const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
-      current_zone(), object_store()->error_listeners());
+      current_zone(), isolate_object_store()->error_listeners());
   SendPort& current = SendPort::Handle(current_zone());
   intptr_t insertion_index = -1;
   for (intptr_t i = 0; i < listeners.Length(); i++) {
@@ -1949,7 +2056,7 @@
 
 void Isolate::RemoveErrorListener(const SendPort& listener) {
   const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
-      current_zone(), object_store()->error_listeners());
+      current_zone(), isolate_object_store()->error_listeners());
   SendPort& current = SendPort::Handle(current_zone());
   for (intptr_t i = 0; i < listeners.Length(); i++) {
     current ^= listeners.At(i);
@@ -1965,7 +2072,7 @@
 bool Isolate::NotifyErrorListeners(const String& msg,
                                    const String& stacktrace) {
   const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
-      current_zone(), this->object_store()->error_listeners());
+      current_zone(), isolate_object_store()->error_listeners());
   if (listeners.IsNull()) return false;
 
   const Array& arr = Array::Handle(current_zone(), Array::New(2));
@@ -2101,7 +2208,7 @@
   Dart::ShutdownIsolate(isolate);
 }
 
-void Isolate::SetStickyError(RawError* sticky_error) {
+void Isolate::SetStickyError(ErrorPtr sticky_error) {
   ASSERT(
       ((sticky_error_ == Error::null()) || (sticky_error == Error::null())) &&
       (sticky_error != sticky_error_));
@@ -2128,8 +2235,8 @@
 // collisions with this simple hash value. However, iterating over
 // all closure functions becomes more difficult, especially when
 // the list/map changes while iterating over it.
-RawFunction* Isolate::LookupClosureFunction(const Function& parent,
-                                            TokenPosition token_pos) const {
+FunctionPtr Isolate::LookupClosureFunction(const Function& parent,
+                                           TokenPosition token_pos) const {
   const GrowableObjectArray& closures =
       GrowableObjectArray::Handle(object_store()->closure_functions());
   ASSERT(!closures.IsNull());
@@ -2157,7 +2264,7 @@
   return -1;
 }
 
-RawFunction* Isolate::ClosureFunctionFromIndex(intptr_t idx) const {
+FunctionPtr Isolate::ClosureFunctionFromIndex(intptr_t idx) const {
   const GrowableObjectArray& closures_array =
       GrowableObjectArray::Handle(object_store()->closure_functions());
   if ((idx < 0) || (idx >= closures_array.Length())) {
@@ -2302,6 +2409,15 @@
 
   // Then, proceed with low-level teardown.
   Isolate::UnMarkIsolateReady(this);
+
+  // Post message before LowLevelShutdown that sends onExit message.
+  // This ensures that exit message comes last.
+  if (bequest_.get() != nullptr) {
+    auto beneficiary = bequest_->beneficiary();
+    PortMap::PostMessage(Message::New(beneficiary, bequest_.release(),
+                                      Message::kNormalPriority));
+  }
+
   LowLevelShutdown();
 
   // Now we can unregister from the thread, invoke cleanup callback, delete the
@@ -2329,12 +2445,6 @@
   // since we're just going to delete it anyway).
   isolate_group->UnregisterIsolate(isolate);
 
-  // Since the death of this isolate is not the death of the heap, we have to
-  // leave the new space iterable (e.g. for old space marking) by abanoning the
-  // TLAB.
-  isolate->group()->heap()->new_space()->AbandonRemainingTLAB(
-      Thread::Current());
-
   // From this point on the isolate doesn't participate in safepointing
   // requests anymore.
   Thread::ExitIsolate();
@@ -2387,43 +2497,49 @@
                                   ValidationPolicy validate_frames) {
   ASSERT(visitor != nullptr);
 
-  // Visit objects in the object store.
-  if (object_store() != nullptr) {
+  // Visit objects in the object store if there is no isolate group object store
+  if (group()->object_store() == nullptr && object_store() != nullptr) {
     object_store()->VisitObjectPointers(visitor);
   }
+  // Visit objects in the isolate object store.
+  if (isolate_object_store() != nullptr) {
+    isolate_object_store()->VisitObjectPointers(visitor);
+  }
 
   // Visit objects in the class table.
   class_table()->VisitObjectPointers(visitor);
 
   // Visit objects in the field table.
   field_table()->VisitObjectPointers(visitor);
+  if (saved_initial_field_table() != nullptr) {
+    saved_initial_field_table()->VisitObjectPointers(visitor);
+  }
 
   visitor->clear_gc_root_type();
   // Visit the objects directly referenced from the isolate structure.
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&current_tag_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&default_tag_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&ic_miss_code_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&tag_table_));
-  visitor->VisitPointer(
-      reinterpret_cast<RawObject**>(&deoptimized_code_array_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&sticky_error_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&current_tag_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&default_tag_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&ic_miss_code_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&tag_table_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&deoptimized_code_array_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
   if (isolate_group_ != nullptr) {
     if (isolate_group_->source()->hot_reload_blobs_ != nullptr) {
-      visitor->VisitPointer(reinterpret_cast<RawObject**>(
+      visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(
           &(isolate_group_->source()->hot_reload_blobs_)));
     }
   }
 #if !defined(PRODUCT)
   visitor->VisitPointer(
-      reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
+      reinterpret_cast<ObjectPtr*>(&pending_service_extension_calls_));
   visitor->VisitPointer(
-      reinterpret_cast<RawObject**>(&registered_service_extension_handlers_));
+      reinterpret_cast<ObjectPtr*>(&registered_service_extension_handlers_));
 #endif  // !defined(PRODUCT)
   // Visit the boxed_field_list_.
   // 'boxed_field_list_' access via mutator and background compilation threads
   // is guarded with a monitor. This means that we can visit it only
   // when at safepoint or the field_list_mutex_ lock has been taken.
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&boxed_field_list_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&boxed_field_list_));
 
   if (background_compiler() != nullptr) {
     background_compiler()->VisitPointers(visitor);
@@ -2497,7 +2613,8 @@
     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::kCompactorTask) ||
+           (Thread::Current()->task_kind() == Thread::kScavengerTask));
     for (Isolate* isolate : isolates_) {
       function(isolate);
     }
@@ -2509,6 +2626,11 @@
   }
 }
 
+Isolate* IsolateGroup::FirstIsolate() const {
+  SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
+  return isolates_.IsEmpty() ? nullptr : isolates_.First();
+}
+
 void IsolateGroup::RunWithStoppedMutators(
     std::function<void()> single_current_mutator,
     std::function<void()> otherwise,
@@ -2520,6 +2642,12 @@
     return;
   }
 
+  if (thread->IsAtSafepoint() &&
+      safepoint_handler()->IsOwnedByTheThread(thread)) {
+    single_current_mutator();
+    return;
+  }
+
   {
     SafepointReadRwLocker ml(thread, isolates_lock_.get());
     const bool only_one_isolate = isolates_.First() == isolates_.Last();
@@ -2543,12 +2671,15 @@
 
 void IsolateGroup::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                        ValidationPolicy validate_frames) {
-  ForEachIsolate(
-      [&](Isolate* isolate) {
-        isolate->VisitObjectPointers(visitor, validate_frames);
-      },
-      /*at_safepoint=*/true);
+  for (Isolate* isolate : isolates_) {
+    isolate->VisitObjectPointers(visitor, validate_frames);
+  }
   api_state()->VisitObjectPointersUnlocked(visitor);
+  // Visit objects in the object store.
+  if (object_store() != nullptr) {
+    object_store()->VisitObjectPointers(visitor);
+  }
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_unlinked_calls_));
   VisitStackPointers(visitor, validate_frames);
 }
 
@@ -2560,20 +2691,25 @@
   // for the mutator threads themselves.
   thread_registry()->VisitObjectPointers(this, visitor, validate_frames);
 
-  ForEachIsolate(
-      [&](Isolate* isolate) {
-        // Visit mutator thread, even if the isolate isn't entered/scheduled
-        // (there might be live API handles to visit).
-        if (isolate->mutator_thread_ != nullptr) {
-          isolate->mutator_thread_->VisitObjectPointers(visitor,
-                                                        validate_frames);
-        }
-      },
-      /*at_safepoint=*/true);
+  for (Isolate* isolate : isolates_) {
+    // Visit mutator thread, even if the isolate isn't entered/scheduled
+    // (there might be live API handles to visit).
+    if (isolate->mutator_thread_ != nullptr) {
+      isolate->mutator_thread_->VisitObjectPointers(visitor, validate_frames);
+    }
+  }
 
   visitor->clear_gc_root_type();
 }
 
+void IsolateGroup::VisitObjectIdRingPointers(ObjectPointerVisitor* visitor) {
+#if !defined(PRODUCT)
+  for (Isolate* isolate : isolates_) {
+    isolate->object_id_ring()->VisitPointers(visitor);
+  }
+#endif  // !defined(PRODUCT)
+}
+
 void IsolateGroup::VisitWeakPersistentHandles(HandleVisitor* visitor) {
   api_state()->VisitWeakHandlesUnlocked(visitor);
 }
@@ -2601,8 +2737,8 @@
                  /*at_safepoint=*/true);
 }
 
-RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) {
-  RawClass* raw_class = nullptr;
+ClassPtr Isolate::GetClassForHeapWalkAt(intptr_t cid) {
+  ClassPtr raw_class = nullptr;
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   if (group()->IsReloading()) {
     raw_class = reload_context()->GetClassForHeapWalkAt(cid);
@@ -2622,10 +2758,10 @@
   if (IsReloading()) {
     return group_reload_context_->GetClassSizeForHeapWalkAt(cid);
   } else {
-    return class_table()->SizeAt(cid);
+    return shared_class_table()->SizeAt(cid);
   }
 #else
-  return class_table()->SizeAt(cid);
+  return shared_class_table()->SizeAt(cid);
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 }
 
@@ -2872,9 +3008,9 @@
   deoptimized_code.Add(code);
 }
 
-RawError* Isolate::StealStickyError() {
+ErrorPtr Isolate::StealStickyError() {
   NoSafepointScope no_safepoint;
-  RawError* return_value = sticky_error_;
+  ErrorPtr return_value = sticky_error_;
   sticky_error_ = Error::null();
   return return_value;
 }
@@ -2905,7 +3041,7 @@
   array.Add(Field::Handle(field.Original()), Heap::kOld);
 }
 
-RawField* Isolate::GetDeoptimizingBoxedField() {
+FieldPtr Isolate::GetDeoptimizingBoxedField() {
   ASSERT(Thread::Current()->IsMutatorThread());
   SafepointMutexLocker ml(&field_list_mutex_);
   if (boxed_field_list_ == GrowableObjectArray::null()) {
@@ -2920,7 +3056,7 @@
 }
 
 #ifndef PRODUCT
-RawError* Isolate::InvokePendingServiceExtensionCalls() {
+ErrorPtr Isolate::InvokePendingServiceExtensionCalls() {
   GrowableObjectArray& calls =
       GrowableObjectArray::Handle(GetAndClearPendingServiceExtensionCalls());
   if (calls.IsNull()) {
@@ -2993,8 +3129,8 @@
   return Error::null();
 }
 
-RawGrowableObjectArray* Isolate::GetAndClearPendingServiceExtensionCalls() {
-  RawGrowableObjectArray* r = pending_service_extension_calls_;
+GrowableObjectArrayPtr Isolate::GetAndClearPendingServiceExtensionCalls() {
+  GrowableObjectArrayPtr r = pending_service_extension_calls_;
   pending_service_extension_calls_ = GrowableObjectArray::null();
   return r;
 }
@@ -3088,7 +3224,7 @@
 // operation atomically in the face of random OOB messages. Do not port
 // to Dart code unless you can ensure that the operations will can be
 // done atomically.
-RawInstance* Isolate::LookupServiceExtensionHandler(const String& name) {
+InstancePtr Isolate::LookupServiceExtensionHandler(const String& name) {
   const GrowableObjectArray& handlers =
       GrowableObjectArray::Handle(registered_service_extension_handlers());
   if (handlers.IsNull()) {
@@ -3551,7 +3687,7 @@
   delete[] debug_name_;
 }
 
-RawObject* IsolateSpawnState::ResolveFunction() {
+ObjectPtr IsolateSpawnState::ResolveFunction() {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -3628,11 +3764,11 @@
   return func.raw();
 }
 
-RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) {
+InstancePtr IsolateSpawnState::BuildArgs(Thread* thread) {
   return DeserializeMessage(thread, serialized_args_.get());
 }
 
-RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
+InstancePtr IsolateSpawnState::BuildMessage(Thread* thread) {
   return DeserializeMessage(thread, serialized_message_.get());
 }
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 621dfd2..0487039 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -19,8 +19,8 @@
 #include "vm/base_isolate.h"
 #include "vm/class_table.h"
 #include "vm/constants_kbc.h"
+#include "vm/dispatch_table.h"
 #include "vm/exceptions.h"
-#include "vm/ffi_callback_trampolines.h"
 #include "vm/field_table.h"
 #include "vm/fixed_cache.h"
 #include "vm/growable_array.h"
@@ -37,6 +37,10 @@
 #include "vm/token_position.h"
 #include "vm/virtual_memory.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/ffi_callback_trampolines.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // Forward declarations.
@@ -46,7 +50,6 @@
 class CodeIndexTable;
 class Debugger;
 class DeoptContext;
-class DispatchTable;
 class ExternalTypedData;
 class HandleScope;
 class HandleVisitor;
@@ -55,6 +58,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class Interpreter;
 #endif
+class IsolateObjectStore;
 class IsolateProfilerData;
 class IsolateReloadContext;
 class IsolateSpawnState;
@@ -67,19 +71,7 @@
 class ObjectIdRing;
 class ObjectPointerVisitor;
 class ObjectStore;
-class RawInstance;
-class RawArray;
-class RawContext;
-class RawDouble;
-class RawError;
-class RawField;
-class RawGrowableObjectArray;
-class RawMint;
-class RawObject;
-class RawInteger;
-class RawFloat32x4;
-class RawInt32x4;
-class RawUserTag;
+class PersistentHandle;
 class ReversePcLookupCache;
 class RwLock;
 class SafepointRwLock;
@@ -97,6 +89,17 @@
 class UserTag;
 class WeakTable;
 
+/*
+ * Possible values of null safety flag
+  0 - not specified
+  1 - weak mode
+  2 - strong mode)
+*/
+constexpr int kNullSafetyOptionUnspecified = 0;
+constexpr int kNullSafetyOptionWeak = 1;
+constexpr int kNullSafetyOptionStrong = 2;
+extern int FLAG_null_safety;
+
 class PendingLazyDeopt {
  public:
   PendingLazyDeopt(uword fp, uword pc) : fp_(fp), pc_(pc) {}
@@ -160,7 +163,6 @@
   V(NONPRODUCT, use_field_guards, UseFieldGuards, use_field_guards,            \
     FLAG_use_field_guards)                                                     \
   V(NONPRODUCT, use_osr, UseOsr, use_osr, FLAG_use_osr)                        \
-  V(PRODUCT, null_safety, NullSafety, null_safety, FLAG_null_safety)           \
   V(PRECOMPILER, obfuscate, Obfuscate, obfuscate, false_by_default)            \
   V(PRODUCT, unsafe_trust_strong_mode_types, UnsafeTrustStrongModeTypes,       \
     unsafe_trust_strong_mode_types,                                            \
@@ -224,7 +226,7 @@
   std::unique_ptr<intptr_t[]> cid_permutation_map;
 
   // List of weak pointers to external typed data for hot reload blobs.
-  RawArray* hot_reload_blobs_;
+  ArrayPtr hot_reload_blobs_;
   intptr_t num_hot_reloads_;
 };
 
@@ -275,6 +277,9 @@
 // Represents an isolate group and is shared among all isolates within a group.
 class IsolateGroup : public IntrusiveDListEntry<IsolateGroup> {
  public:
+  IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
+               void* embedder_data,
+               ObjectStore* object_store);
   IsolateGroup(std::shared_ptr<IsolateGroupSource> source, void* embedder_data);
   ~IsolateGroup();
 
@@ -333,8 +338,18 @@
   }
 #endif  // !defined(PRODUCT)
 
-  SharedClassTable* class_table() const { return shared_class_table_.get(); }
+  DispatchTable* dispatch_table() const { return dispatch_table_.get(); }
+  void set_dispatch_table(DispatchTable* table) {
+    dispatch_table_.reset(table);
+  }
+
+  SharedClassTable* shared_class_table() const {
+    return shared_class_table_.get();
+  }
   StoreBuffer* store_buffer() const { return store_buffer_.get(); }
+  ClassTable* class_table() const { return class_table_.get(); }
+  ObjectStore* object_store() const { return object_store_.get(); }
+  SafepointRwLock* symbols_lock() { return symbols_lock_.get(); }
 
   static inline IsolateGroup* Current() {
     Thread* thread = Thread::Current();
@@ -386,6 +401,7 @@
   // adding/removing isolates, so no locks will be held.
   void ForEachIsolate(std::function<void(Isolate* isolate)> function,
                       bool at_safepoint = false);
+  Isolate* FirstIsolate() const;
 
   // Ensures mutators are stopped during execution of the provided function.
   //
@@ -401,8 +417,9 @@
                               std::function<void()> otherwise,
                               bool use_force_growth_in_otherwise = false);
 
-  void RunWithStoppedMutators(std::function<void()> function) {
-    RunWithStoppedMutators(function, function);
+  void RunWithStoppedMutators(std::function<void()> function,
+                              bool use_force_growth = false) {
+    RunWithStoppedMutators(function, function, use_force_growth);
   }
 
 #ifndef PRODUCT
@@ -468,6 +485,7 @@
                            ValidationPolicy validate_frames);
   void VisitStackPointers(ObjectPointerVisitor* visitor,
                           ValidationPolicy validate_frames);
+  void VisitObjectIdRingPointers(ObjectPointerVisitor* visitor);
   void VisitWeakPersistentHandles(HandleVisitor* visitor);
 
   bool compaction_in_progress() const {
@@ -483,9 +501,26 @@
   void RememberLiveTemporaries();
   void DeferredMarkLiveTemporaries();
 
+  ArrayPtr saved_unlinked_calls() const { return saved_unlinked_calls_; }
+  void set_saved_unlinked_calls(const Array& saved_unlinked_calls);
+
+  // Returns the pc -> code lookup cache object for this isolate.
+  ReversePcLookupCache* reverse_pc_lookup_cache() const {
+    return reverse_pc_lookup_cache_;
+  }
+
+  // Sets the pc -> code lookup cache object for this isolate.
+  void set_reverse_pc_lookup_cache(ReversePcLookupCache* table) {
+    ASSERT(reverse_pc_lookup_cache_ == nullptr);
+    reverse_pc_lookup_cache_ = table;
+  }
+
  private:
+  friend class Dart;  // For `object_store_ = ` in Dart::Init
   friend class Heap;
   friend class StackFrame;  // For `[isolates_].First()`.
+  // For `object_store_shared_ptr()`, `class_table_shared_ptr()`
+  friend class Isolate;
 
 #define ISOLATE_GROUP_FLAG_BITS(V) V(CompactionInProgress)
 
@@ -503,6 +538,13 @@
 
   void set_heap(std::unique_ptr<Heap> value);
 
+  const std::shared_ptr<ClassTable>& class_table_shared_ptr() const {
+    return class_table_;
+  }
+  const std::shared_ptr<ObjectStore>& object_store_shared_ptr() const {
+    return object_store_;
+  }
+
   bool is_vm_isolate_heap_ = false;
   void* embedder_data_ = nullptr;
 
@@ -544,12 +586,38 @@
   uint64_t id_ = 0;
 
   std::unique_ptr<SharedClassTable> shared_class_table_;
+  std::shared_ptr<ObjectStore> object_store_;  // nullptr in JIT mode
+  std::shared_ptr<ClassTable> class_table_;    // nullptr in JIT mode
+  // This symbols_mutex_ on Isolate is only used when IsolateGroup does not
+  // have object_store.
+  std::unique_ptr<SafepointRwLock>
+      symbols_lock_;  // Protects concurrent access to the symbol table.
   std::unique_ptr<StoreBuffer> store_buffer_;
   std::unique_ptr<Heap> heap_;
+  std::unique_ptr<DispatchTable> dispatch_table_;
+  ReversePcLookupCache* reverse_pc_lookup_cache_ = nullptr;
+  ArrayPtr saved_unlinked_calls_;
+
   IdleTimeHandler idle_time_handler_;
   uint32_t isolate_group_flags_ = 0;
 };
 
+// When an isolate sends-and-exits this class represent things that it passed
+// to the beneficiary.
+class Bequest {
+ public:
+  Bequest(PersistentHandle* handle, Dart_Port beneficiary)
+      : handle_(handle), beneficiary_(beneficiary) {}
+  ~Bequest();
+
+  PersistentHandle* handle() { return handle_; }
+  Dart_Port beneficiary() { return beneficiary_; }
+
+ private:
+  PersistentHandle* handle_;
+  Dart_Port beneficiary_;
+};
+
 class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
  public:
   // Keep both these enums in sync with isolate_patch.dart.
@@ -604,15 +672,56 @@
     return group()->safepoint_handler();
   }
 
-  ClassTable* class_table() { return &class_table_; }
-  static intptr_t class_table_offset() {
-    return OFFSET_OF(Isolate, class_table_);
+  ClassTable* class_table() { return class_table_.get(); }
+
+  ClassPtr* cached_class_table_table() { return cached_class_table_table_; }
+  void set_cached_class_table_table(ClassPtr* cached_class_table_table) {
+    cached_class_table_table_ = cached_class_table_table;
+  }
+  static intptr_t cached_class_table_table_offset() {
+    return OFFSET_OF(Isolate, cached_class_table_table_);
   }
 
+  SharedClassTable* shared_class_table() const { return shared_class_table_; }
+  // Used during isolate creation to re-register isolate with right group.
+  void set_shared_class_table(SharedClassTable* table) {
+    shared_class_table_ = table;
+  }
+  // Used by the generated code.
+  static intptr_t shared_class_table_offset() {
+    return OFFSET_OF(Isolate, shared_class_table_);
+  }
+
+  ObjectStore* object_store() const { return object_store_shared_ptr_.get(); }
+  void set_object_store(ObjectStore* object_store);
+  static intptr_t cached_object_store_offset() {
+    return OFFSET_OF(Isolate, cached_object_store_);
+  }
+  SafepointRwLock* symbols_lock() { return symbols_lock_.get(); }
+
   FieldTable* field_table() const { return field_table_; }
+  void set_field_table(Thread* T, FieldTable* field_table) {
+    delete field_table_;
+    field_table_ = field_table;
+    T->field_table_values_ = field_table->table();
+  }
+
+  FieldTable* saved_initial_field_table() const {
+    return saved_initial_field_table_.get();
+  }
+  std::shared_ptr<FieldTable> saved_initial_field_table_shareable() {
+    return saved_initial_field_table_;
+  }
+  void set_saved_initial_field_table(std::shared_ptr<FieldTable> field_table) {
+    saved_initial_field_table_ = field_table;
+  }
+
+  IsolateObjectStore* isolate_object_store() const {
+    return isolate_object_store_.get();
+  }
 
   // Prefers old classes when we are in the middle of a reload.
-  RawClass* GetClassForHeapWalkAt(intptr_t cid);
+  ClassPtr GetClassForHeapWalkAt(intptr_t cid);
 
   static intptr_t ic_miss_code_offset() {
     return OFFSET_OF(Isolate, ic_miss_code_);
@@ -626,6 +735,10 @@
     message_notify_callback_ = value;
   }
 
+  void bequeath(std::unique_ptr<Bequest> bequest) {
+    bequest_ = std::move(bequest);
+  }
+
   IsolateGroupSource* source() const { return isolate_group_->source(); }
   IsolateGroup* group() const { return isolate_group_; }
 
@@ -643,11 +756,8 @@
     ASSERT(main_port_ == 0);  // Only set main port once.
     main_port_ = port;
   }
-  Dart_Port origin_id() const { return origin_id_; }
-  void set_origin_id(Dart_Port id) {
-    ASSERT((id == main_port_ && origin_id_ == 0) || (origin_id_ == main_port_));
-    origin_id_ = id;
-  }
+  Dart_Port origin_id();
+  void set_origin_id(Dart_Port id);
   void set_pause_capability(uint64_t value) { pause_capability_ = value; }
   uint64_t pause_capability() const { return pause_capability_; }
   void set_terminate_capability(uint64_t value) {
@@ -659,12 +769,6 @@
 
   Heap* heap() const { return isolate_group_->heap(); }
 
-  ObjectStore* object_store() const { return object_store_; }
-  void set_object_store(ObjectStore* value) { object_store_ = value; }
-  static intptr_t object_store_offset() {
-    return OFFSET_OF(Isolate, object_store_);
-  }
-
   void set_init_callback_data(void* value) { init_callback_data_ = value; }
   void* init_callback_data() const { return init_callback_data_; }
 
@@ -684,9 +788,9 @@
   bool HasTagHandler() const {
     return group()->library_tag_handler() != nullptr;
   }
-  RawObject* CallTagHandler(Dart_LibraryTag tag,
-                            const Object& arg1,
-                            const Object& arg2);
+  ObjectPtr CallTagHandler(Dart_LibraryTag tag,
+                           const Object& arg1,
+                           const Object& arg2);
 
   void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);
 
@@ -714,7 +818,6 @@
   }
 
   Mutex* mutex() { return &mutex_; }
-  Mutex* symbols_mutex() { return &symbols_mutex_; }
   Mutex* type_canonicalization_mutex() { return &type_canonicalization_mutex_; }
   Mutex* constant_canonicalization_mutex() {
     return &constant_canonicalization_mutex_;
@@ -732,7 +835,6 @@
 
 #if !defined(PRODUCT)
   Debugger* debugger() const {
-    ASSERT(debugger_ != nullptr);
     return debugger_;
   }
 
@@ -916,7 +1018,7 @@
   }
 #endif  // !defined(PRODUCT)
 
-  RawError* PausePostRequest();
+  ErrorPtr PausePostRequest();
 
   uword user_tag() const { return user_tag_; }
   static intptr_t user_tag_offset() { return OFFSET_OF(Isolate, user_tag_); }
@@ -936,28 +1038,28 @@
 
   static intptr_t IsolateListLength();
 
-  RawGrowableObjectArray* tag_table() const { return tag_table_; }
+  GrowableObjectArrayPtr tag_table() const { return tag_table_; }
   void set_tag_table(const GrowableObjectArray& value);
 
-  RawUserTag* current_tag() const { return current_tag_; }
+  UserTagPtr current_tag() const { return current_tag_; }
   void set_current_tag(const UserTag& tag);
 
-  RawUserTag* default_tag() const { return default_tag_; }
+  UserTagPtr default_tag() const { return default_tag_; }
   void set_default_tag(const UserTag& tag);
 
   void set_ic_miss_code(const Code& code);
 
-  RawGrowableObjectArray* deoptimized_code_array() const {
+  GrowableObjectArrayPtr deoptimized_code_array() const {
     return deoptimized_code_array_;
   }
   void set_deoptimized_code_array(const GrowableObjectArray& value);
   void TrackDeoptimizedCode(const Code& code);
 
   // Also sends a paused at exit event over the service protocol.
-  void SetStickyError(RawError* sticky_error);
+  void SetStickyError(ErrorPtr sticky_error);
 
-  RawError* sticky_error() const { return sticky_error_; }
-  DART_WARN_UNUSED_RESULT RawError* StealStickyError();
+  ErrorPtr sticky_error() const { return sticky_error_; }
+  DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();
 
   // In precompilation we finalize all regular classes before compiling.
   bool all_classes_finalized() const {
@@ -978,10 +1080,10 @@
   // deoptimization in the mutator thread.
   void AddDeoptimizingBoxedField(const Field& field);
   // Returns Field::null() if none available in the list.
-  RawField* GetDeoptimizingBoxedField();
+  FieldPtr GetDeoptimizingBoxedField();
 
 #ifndef PRODUCT
-  RawError* InvokePendingServiceExtensionCalls();
+  ErrorPtr InvokePendingServiceExtensionCalls();
   void AppendServiceExtensionCall(const Instance& closure,
                                   const String& method_name,
                                   const Array& parameter_keys,
@@ -990,7 +1092,7 @@
                                   const Instance& id);
   void RegisterServiceExtensionHandler(const String& name,
                                        const Instance& closure);
-  RawInstance* LookupServiceExtensionHandler(const String& name);
+  InstancePtr LookupServiceExtensionHandler(const String& name);
 #endif
 
   static void VisitIsolates(IsolateVisitor* visitor);
@@ -1001,10 +1103,10 @@
 #endif
 
   void AddClosureFunction(const Function& function) const;
-  RawFunction* LookupClosureFunction(const Function& parent,
-                                     TokenPosition token_pos) const;
+  FunctionPtr LookupClosureFunction(const Function& parent,
+                                    TokenPosition token_pos) const;
   intptr_t FindClosureIndex(const Function& needle) const;
-  RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
+  FunctionPtr ClosureFunctionFromIndex(intptr_t idx) const;
 
   bool is_service_isolate() const {
     return IsServiceIsolateBit::decode(isolate_flags_);
@@ -1045,18 +1147,8 @@
   void set_obfuscation_map(const char** map) { obfuscation_map_ = map; }
   const char** obfuscation_map() const { return obfuscation_map_; }
 
-  const DispatchTable* dispatch_table() const { return dispatch_table_; }
-  void set_dispatch_table(DispatchTable* table) { dispatch_table_ = table; }
-
-  // Returns the pc -> code lookup cache object for this isolate.
-  ReversePcLookupCache* reverse_pc_lookup_cache() const {
-    return reverse_pc_lookup_cache_;
-  }
-
-  // Sets the pc -> code lookup cache object for this isolate.
-  void set_reverse_pc_lookup_cache(ReversePcLookupCache* table) {
-    ASSERT(reverse_pc_lookup_cache_ == nullptr);
-    reverse_pc_lookup_cache_ = table;
+  const DispatchTable* dispatch_table() const {
+    return group()->dispatch_table();
   }
 
   // Isolate-specific flag handling.
@@ -1098,6 +1190,24 @@
   }
 #endif  // defined(PRODUCT)
 
+  bool null_safety_not_set() const {
+    return !NullSafetySetBit::decode(isolate_flags_);
+  }
+
+  bool null_safety() const {
+    // TODO(asiva) : We return false when the null safety mode is not yet set
+    // instead of just asserting as some code runs during bootstrapping that
+    // requires the mode to be set. Once all of that is resolved this could
+    // turn into just an assert.
+    if (null_safety_not_set()) return false;
+    ASSERT(!null_safety_not_set());
+    return NullSafetyBit::decode(isolate_flags_);
+  }
+  void set_null_safety(bool null_safety) {
+    isolate_flags_ = NullSafetySetBit::update(true, isolate_flags_);
+    isolate_flags_ = NullSafetyBit::update(null_safety, isolate_flags_);
+  }
+
   // Convenience flag tester indicating whether incoming function arguments
   // should be type checked.
   bool argument_type_checks() const { return should_emit_strong_mode_checks(); }
@@ -1196,12 +1306,12 @@
   void set_user_tag(uword tag) { user_tag_ = tag; }
 
 #if !defined(PRODUCT)
-  RawGrowableObjectArray* GetAndClearPendingServiceExtensionCalls();
-  RawGrowableObjectArray* pending_service_extension_calls() const {
+  GrowableObjectArrayPtr GetAndClearPendingServiceExtensionCalls();
+  GrowableObjectArrayPtr pending_service_extension_calls() const {
     return pending_service_extension_calls_;
   }
   void set_pending_service_extension_calls(const GrowableObjectArray& value);
-  RawGrowableObjectArray* registered_service_extension_handlers() const {
+  GrowableObjectArrayPtr registered_service_extension_handlers() const {
     return registered_service_extension_handlers_;
   }
   void set_registered_service_extension_handlers(
@@ -1227,17 +1337,26 @@
   // We use only word-sized fields to avoid differences in struct packing on the
   // different architectures. See also CheckOffsets in dart.cc.
   uword user_tag_ = 0;
-  RawUserTag* current_tag_;
-  RawUserTag* default_tag_;
-  RawCode* ic_miss_code_;
-  ObjectStore* object_store_ = nullptr;
-  ClassTable class_table_;
+  UserTagPtr current_tag_;
+  UserTagPtr default_tag_;
+  CodePtr ic_miss_code_;
+  // Cached value of object_store_shared_ptr_, here for generated code access
+  ObjectStore* cached_object_store_ = nullptr;
+  SharedClassTable* shared_class_table_ = nullptr;
+  // Cached value of class_table_->table_, here for generated code access
+  ClassPtr* cached_class_table_table_ = nullptr;
   FieldTable* field_table_ = nullptr;
   bool single_step_ = false;
   // End accessed from generated code.
 
   IsolateGroup* isolate_group_;
   IdleTimeHandler idle_time_handler_;
+  std::shared_ptr<FieldTable> saved_initial_field_table_;
+  std::unique_ptr<IsolateObjectStore> isolate_object_store_;
+  // shared in AOT(same pointer as on IsolateGroup), not shared in JIT
+  std::shared_ptr<ObjectStore> object_store_shared_ptr_;
+  // shared in AOT(same pointer as on IsolateGroup), not shared in JIT
+  std::shared_ptr<ClassTable> class_table_;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   NativeCallbackTrampolines native_callback_trampolines_;
@@ -1260,6 +1379,7 @@
   V(Obfuscate)                                                                 \
   V(ShouldLoadVmService)                                                       \
   V(NullSafety)                                                                \
+  V(NullSafetySet)                                                             \
   V(UnsafeTrustStrongModeTypes)
 
   // Isolate specific flags.
@@ -1294,12 +1414,12 @@
   enum {kPendingHandlerIndex = 0, kPendingMethodNameIndex, kPendingKeysIndex,
         kPendingValuesIndex,      kPendingReplyPortIndex,  kPendingIdIndex,
         kPendingEntrySize};
-  RawGrowableObjectArray* pending_service_extension_calls_;
+  GrowableObjectArrayPtr pending_service_extension_calls_;
 
   // We use 2 list entries for each registered extension handler.
   enum {kRegisteredNameIndex = 0, kRegisteredHandlerIndex,
         kRegisteredEntrySize};
-  RawGrowableObjectArray* registered_service_extension_handlers_;
+  GrowableObjectArrayPtr registered_service_extension_handlers_;
 
   // Used to wake the isolate when it is in the pause event loop.
   Monitor* pause_loop_monitor_ = nullptr;
@@ -1325,6 +1445,7 @@
   Dart_Port main_port_ = 0;
   // Isolates created by Isolate.spawn have the same origin id.
   Dart_Port origin_id_ = 0;
+  Mutex origin_id_mutex_;
   uint64_t pause_capability_ = 0;
   uint64_t terminate_capability_ = 0;
   void* init_callback_data_ = nullptr;
@@ -1332,7 +1453,8 @@
   Random random_;
   Simulator* simulator_ = nullptr;
   Mutex mutex_;          // Protects compiler stats.
-  Mutex symbols_mutex_;  // Protects concurrent access to the symbol table.
+  std::unique_ptr<SafepointRwLock>
+      symbols_lock_;  // Protects concurrent access to the symbol table.
   Mutex type_canonicalization_mutex_;      // Protects type canonicalization.
   Mutex constant_canonicalization_mutex_;  // Protects const canonicalization.
   Mutex megamorphic_mutex_;  // Protects the table of megamorphic caches and
@@ -1346,16 +1468,19 @@
   MallocGrowableArray<PendingLazyDeopt>* pending_deopts_;
   DeoptContext* deopt_context_ = nullptr;
 
-  RawGrowableObjectArray* tag_table_;
+  GrowableObjectArrayPtr tag_table_;
 
-  RawGrowableObjectArray* deoptimized_code_array_;
+  GrowableObjectArrayPtr deoptimized_code_array_;
 
-  RawError* sticky_error_;
+  ErrorPtr sticky_error_;
+
+  std::unique_ptr<Bequest> bequest_;
+  Dart_Port beneficiary_ = 0;
 
   // Protect access to boxed_field_list_.
   Mutex field_list_mutex_;
   // List of fields that became boxed and that trigger deoptimization.
-  RawGrowableObjectArray* boxed_field_list_;
+  GrowableObjectArrayPtr boxed_field_list_;
 
   // This guards spawn_count_. An isolate cannot complete shutdown and be
   // destroyed while there are child isolates in the midst of a spawn.
@@ -1369,7 +1494,6 @@
   const char** obfuscation_map_ = nullptr;
 
   DispatchTable* dispatch_table_ = nullptr;
-  ReversePcLookupCache* reverse_pc_lookup_cache_ = nullptr;
 
   // Used during message sending of messages between isolates.
   std::unique_ptr<WeakTable> forward_table_new_;
@@ -1513,9 +1637,9 @@
   bool errors_are_fatal() const { return errors_are_fatal_; }
   Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
 
-  RawObject* ResolveFunction();
-  RawInstance* BuildArgs(Thread* thread);
-  RawInstance* BuildMessage(Thread* thread);
+  ObjectPtr ResolveFunction();
+  InstancePtr BuildArgs(Thread* thread);
+  InstancePtr BuildMessage(Thread* thread);
 
   IsolateGroup* isolate_group() const { return isolate_group_; }
 
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 67d8ad5..6c995de 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -72,7 +72,7 @@
   explicit ObjectLocator(IsolateGroupReloadContext* context)
       : context_(context), count_(0) {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     InstanceMorpher* morpher =
         context_->instance_morpher_by_cid_.LookupValue(obj->GetClassId());
     if (morpher != NULL) {
@@ -186,13 +186,13 @@
       before_(zone, 16),
       after_(zone, 16) {}
 
-void InstanceMorpher::AddObject(RawObject* object) {
+void InstanceMorpher::AddObject(ObjectPtr object) {
   ASSERT(object->GetClassId() == cid_);
   const Instance& instance = Instance::Cast(Object::Handle(Z, object));
   before_.Add(&instance);
 }
 
-RawInstance* InstanceMorpher::Morph(const Instance& instance) const {
+InstancePtr InstanceMorpher::Morph(const Instance& instance) const {
   // Code can reference constants / canonical objects either directly in the
   // instruction stream (ia32) or via an object pool.
   //
@@ -281,13 +281,13 @@
   context->ReportError(error);
 }
 
-RawError* ReasonForCancelling::ToError() {
+ErrorPtr ReasonForCancelling::ToError() {
   // By default create the error returned from ToString.
   const String& message = String::Handle(ToString());
   return LanguageError::New(message);
 }
 
-RawString* ReasonForCancelling::ToString() {
+StringPtr ReasonForCancelling::ToString() {
   UNREACHABLE();
   return NULL;
 }
@@ -314,7 +314,7 @@
   jsobj.AddProperty("message", message.ToCString());
 }
 
-RawError* IsolateGroupReloadContext::error() const {
+ErrorPtr IsolateGroupReloadContext::error() const {
   ASSERT(!reasons_to_cancel_reload_.is_empty());
   // Report the first error to the surroundings.
   return reasons_to_cancel_reload_.At(0)->ToError();
@@ -350,7 +350,7 @@
 
   static uword Hash(const Object& obj) {
     uword class_name_hash = String::HashRawSymbol(Class::Cast(obj).Name());
-    RawLibrary* raw_library = Class::Cast(obj).library();
+    LibraryPtr raw_library = Class::Cast(obj).library();
     if (raw_library == Library::null()) {
       return class_name_hash;
     }
@@ -516,8 +516,8 @@
  private:
   const Error& error_;
 
-  RawError* ToError() { return error_.raw(); }
-  RawString* ToString() {
+  ErrorPtr ToError() { return error_.raw(); }
+  StringPtr ToString() {
     return String::NewFormatted("%s", error_.ToErrorCString());
   }
 };
@@ -688,6 +688,8 @@
     kernel::KernelLoader::FindModifiedLibraries(
         kernel_program.get(), first_isolate_, modified_libs_, force_reload,
         &skip_reload, p_num_received_classes, p_num_received_procedures);
+    modified_libs_transitive_ = new (Z) BitVector(Z, num_old_libs_);
+    BuildModifiedLibrariesClosure(modified_libs_);
 
     ASSERT(num_saved_libs_ == -1);
     num_saved_libs_ = 0;
@@ -746,6 +748,7 @@
   });
   // Renumbering the libraries has invalidated this.
   modified_libs_ = nullptr;
+  modified_libs_transitive_ = nullptr;
 
   if (FLAG_gc_during_reload) {
     // We use kLowMemory to force the GC to compact, which is more likely to
@@ -960,6 +963,108 @@
   return success;
 }
 
+/// Copied in from https://dart-review.googlesource.com/c/sdk/+/77722.
+static void PropagateLibraryModified(
+    const ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by,
+    intptr_t lib_index,
+    BitVector* modified_libs) {
+  ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index];
+  for (intptr_t i = 0; i < dep_libs->length(); i++) {
+    intptr_t dep_lib_index = (*dep_libs)[i];
+    if (!modified_libs->Contains(dep_lib_index)) {
+      modified_libs->Add(dep_lib_index);
+      PropagateLibraryModified(imported_by, dep_lib_index, modified_libs);
+    }
+  }
+}
+
+/// Copied in from https://dart-review.googlesource.com/c/sdk/+/77722.
+void IsolateGroupReloadContext::BuildModifiedLibrariesClosure(
+    BitVector* modified_libs) {
+  const GrowableObjectArray& libs =
+      GrowableObjectArray::Handle(first_isolate_->object_store()->libraries());
+  Library& lib = Library::Handle();
+  intptr_t num_libs = libs.Length();
+
+  // Construct the imported-by graph.
+  ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by = new (zone_)
+      ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>(zone_, num_libs);
+  imported_by->SetLength(num_libs);
+  for (intptr_t i = 0; i < num_libs; i++) {
+    (*imported_by)[i] = new (zone_) ZoneGrowableArray<intptr_t>(zone_, 0);
+  }
+  Array& ports = Array::Handle();
+  Namespace& ns = Namespace::Handle();
+  Library& target = Library::Handle();
+  String& target_url = String::Handle();
+
+  for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) {
+    lib ^= libs.At(lib_idx);
+    ASSERT(lib_idx == lib.index());
+    if (lib.is_dart_scheme()) {
+      // We don't care about imports among dart scheme libraries.
+      continue;
+    }
+
+    // Add imports to the import-by graph.
+    ports = lib.imports();
+    for (intptr_t import_idx = 0; import_idx < ports.Length(); import_idx++) {
+      ns ^= ports.At(import_idx);
+      if (!ns.IsNull()) {
+        target = ns.library();
+        target_url = target.url();
+        if (!target_url.StartsWith(Symbols::DartExtensionScheme())) {
+          (*imported_by)[target.index()]->Add(lib.index());
+        }
+      }
+    }
+
+    // Add exports to the import-by graph.
+    ports = lib.exports();
+    for (intptr_t export_idx = 0; export_idx < ports.Length(); export_idx++) {
+      ns ^= ports.At(export_idx);
+      if (!ns.IsNull()) {
+        target = ns.library();
+        (*imported_by)[target.index()]->Add(lib.index());
+      }
+    }
+
+    // Add prefixed imports to the import-by graph.
+    DictionaryIterator entries(lib);
+    Object& entry = Object::Handle();
+    LibraryPrefix& prefix = LibraryPrefix::Handle();
+    while (entries.HasNext()) {
+      entry = entries.GetNext();
+      if (entry.IsLibraryPrefix()) {
+        prefix ^= entry.raw();
+        ports = prefix.imports();
+        for (intptr_t import_idx = 0; import_idx < ports.Length();
+             import_idx++) {
+          ns ^= ports.At(import_idx);
+          if (!ns.IsNull()) {
+            target = ns.library();
+            (*imported_by)[target.index()]->Add(lib.index());
+          }
+        }
+      }
+    }
+  }
+
+  for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) {
+    lib ^= libs.At(lib_idx);
+    if (lib.is_dart_scheme() || modified_libs_transitive_->Contains(lib_idx)) {
+      // We don't consider dart scheme libraries during reload.  If
+      // the modified libs set already contains this library, then we
+      // have already visited it.
+      continue;
+    }
+    if (modified_libs->Contains(lib_idx)) {
+      modified_libs_transitive_->Add(lib_idx);
+      PropagateLibraryModified(imported_by, lib_idx, modified_libs_transitive_);
+    }
+  }
+}
+
 void IsolateGroupReloadContext::GetRootLibUrl(const char* root_script_url) {
   const auto& old_root_lib =
       Library::Handle(first_isolate_->object_store()->root_library());
@@ -1040,7 +1145,7 @@
   }
 }
 
-RawObject* IsolateReloadContext::ReloadPhase2LoadKernel(
+ObjectPtr IsolateReloadContext::ReloadPhase2LoadKernel(
     kernel::Program* program,
     const String& root_lib_url) {
   Thread* thread = Thread::Current();
@@ -1235,7 +1340,7 @@
 
   // Copy the class table for isolate.
   ClassTable* class_table = I->class_table();
-  RawClass** saved_class_table = nullptr;
+  ClassPtr* saved_class_table = nullptr;
   class_table->CopyBeforeHotReload(&saved_class_table, &saved_num_cids_);
 
   // Copy classes into saved_class_table_ first. Make sure there are no
@@ -1381,6 +1486,9 @@
   Library& lib = Library::Handle();
   UnorderedHashSet<LibraryMapTraits> old_libraries_set(
       old_libraries_set_storage_);
+
+  group_reload_context_->saved_libs_transitive_updated_ = new (Z)
+      BitVector(Z, group_reload_context_->modified_libs_transitive_->length());
   for (intptr_t i = 0; i < libs.Length(); i++) {
     lib ^= libs.At(i);
     if (group_reload_context_->modified_libs_->Contains(i)) {
@@ -1390,6 +1498,11 @@
       // We are preserving this library across the reload, assign its new index
       lib.set_index(new_libs.Length());
       new_libs.Add(lib, Heap::kOld);
+
+      if (group_reload_context_->modified_libs_transitive_->Contains(i)) {
+        // Remember the new index.
+        group_reload_context_->saved_libs_transitive_updated_->Add(lib.index());
+      }
     }
     // Add old library to old libraries set.
     bool already_present = old_libraries_set.Insert(lib);
@@ -1569,7 +1682,10 @@
     for (intptr_t i = 0; i < libs.Length(); i++) {
       lib = Library::RawCast(libs.At(i));
       // Mark the library dirty if it comes after the libraries we saved.
-      library_infos_[i].dirty = i >= group_reload_context_->num_saved_libs_;
+      library_infos_[i].dirty =
+          i >= group_reload_context_->num_saved_libs_ ||
+          group_reload_context_->saved_libs_transitive_updated_->Contains(
+              lib.index());
     }
   }
 }
@@ -1768,8 +1884,8 @@
   }
 }
 
-RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
-  RawClass** class_table = saved_class_table_.load(std::memory_order_acquire);
+ClassPtr IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
+  ClassPtr* class_table = saved_class_table_.load(std::memory_order_acquire);
   if (class_table != NULL) {
     ASSERT(cid > 0);
     ASSERT(cid < saved_num_cids_);
@@ -1791,7 +1907,7 @@
 }
 
 void IsolateReloadContext::DiscardSavedClassTable(bool is_rollback) {
-  RawClass** local_saved_class_table =
+  ClassPtr* local_saved_class_table =
       saved_class_table_.load(std::memory_order_relaxed);
   I->class_table()->ResetAfterHotReload(local_saved_class_table,
                                         saved_num_cids_, is_rollback);
@@ -1813,10 +1929,10 @@
 void IsolateReloadContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   visitor->VisitPointers(from(), to());
 
-  RawClass** saved_class_table =
+  ClassPtr* saved_class_table =
       saved_class_table_.load(std::memory_order_relaxed);
   if (saved_class_table != NULL) {
-    auto class_table = reinterpret_cast<RawObject**>(&(saved_class_table[0]));
+    auto class_table = reinterpret_cast<ObjectPtr*>(&(saved_class_table[0]));
     visitor->VisitPointers(class_table, saved_num_cids_);
   }
 }
@@ -1883,22 +1999,22 @@
         instances_(instances) {}
   virtual ~InvalidationCollector() {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     intptr_t cid = obj->GetClassId();
     if (cid == kFunctionCid) {
       const Function& func =
-          Function::Handle(zone_, static_cast<RawFunction*>(obj));
+          Function::Handle(zone_, static_cast<FunctionPtr>(obj));
       if (!func.ForceOptimize()) {
         // Force-optimized functions cannot deoptimize.
         functions_->Add(&func);
       }
     } else if (cid == kKernelProgramInfoCid) {
       kernel_infos_->Add(&KernelProgramInfo::Handle(
-          zone_, static_cast<RawKernelProgramInfo*>(obj)));
+          zone_, static_cast<KernelProgramInfoPtr>(obj)));
     } else if (cid == kFieldCid) {
-      fields_->Add(&Field::Handle(zone_, static_cast<RawField*>(obj)));
+      fields_->Add(&Field::Handle(zone_, static_cast<FieldPtr>(obj)));
     } else if (cid > kNumPredefinedCids) {
-      instances_->Add(&Instance::Handle(zone_, static_cast<RawInstance*>(obj)));
+      instances_->Add(&Instance::Handle(zone_, static_cast<InstancePtr>(obj)));
     }
   }
 
@@ -2086,11 +2202,8 @@
     Thread* thread = Thread::Current();
     Isolate* isolate = thread->isolate();
     bool null_safety = isolate->null_safety();
+    HANDLESCOPE(thread);
     for (intptr_t i = 0; i < instances.length(); i++) {
-      // This handle scope does run very frequently, but is a net-win by
-      // preventing us from spending too much time in malloc for new handle
-      // blocks.
-      HANDLESCOPE(thread);
       CheckInstance(null_safety, *instances[i]);
     }
   }
@@ -2124,6 +2237,10 @@
     }
     value_ ^= instance.GetField(field);
     if (value_.raw() == Object::sentinel().raw()) {
+      if (field.is_late()) {
+        // Late fields already have lazy initialization logic.
+        return;
+      }
       // Needs guard for initialization.
       ASSERT(!FLAG_identity_reload);
       field.set_needs_load_guard(true);
@@ -2250,8 +2367,7 @@
   RunInvalidationVisitors();
 }
 
-RawClass* IsolateReloadContext::OldClassOrNull(
-    const Class& replacement_or_new) {
+ClassPtr IsolateReloadContext::OldClassOrNull(const Class& replacement_or_new) {
   UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_);
   Class& cls = Class::Handle();
   cls ^= old_classes_set.GetOrNull(replacement_or_new);
@@ -2259,7 +2375,7 @@
   return cls.raw();
 }
 
-RawString* IsolateReloadContext::FindLibraryPrivateKey(
+StringPtr IsolateReloadContext::FindLibraryPrivateKey(
     const Library& replacement_or_new) {
   const Library& old = Library::Handle(OldLibraryOrNull(replacement_or_new));
   if (old.IsNull()) {
@@ -2273,7 +2389,7 @@
   return old.private_key();
 }
 
-RawLibrary* IsolateReloadContext::OldLibraryOrNull(
+LibraryPtr IsolateReloadContext::OldLibraryOrNull(
     const Library& replacement_or_new) {
   UnorderedHashSet<LibraryMapTraits> old_libraries_set(
       old_libraries_set_storage_);
@@ -2291,7 +2407,7 @@
 
 // Attempt to find the pair to |replacement_or_new| with the knowledge that
 // the base url prefix has moved.
-RawLibrary* IsolateReloadContext::OldLibraryOrNullBaseMoved(
+LibraryPtr IsolateReloadContext::OldLibraryOrNullBaseMoved(
     const Library& replacement_or_new) {
   const String& url_prefix =
       String::Handle(group_reload_context_->root_url_prefix_);
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 5bcf2a3..2295441 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -48,11 +48,6 @@
 class ObjectLocator;
 class ObjectPointerVisitor;
 class ObjectStore;
-class RawError;
-class RawGrowableObjectArray;
-class RawLibrary;
-class RawObject;
-class RawString;
 class Script;
 class UpdateClassesVisitor;
 
@@ -74,10 +69,10 @@
   virtual ~InstanceMorpher() {}
 
   // Called on each instance that needs to be morphed.
-  RawInstance* Morph(const Instance& instance) const;
+  InstancePtr Morph(const Instance& instance) const;
 
   // Adds an object to be morphed.
-  void AddObject(RawObject* object);
+  void AddObject(ObjectPtr object);
 
   // Create the morphed objects based on the before() list.
   void CreateMorphedCopies();
@@ -118,11 +113,11 @@
 
   // Conversion to a VM error object.
   // Default implementation calls ToString.
-  virtual RawError* ToError();
+  virtual ErrorPtr ToError();
 
   // Conversion to a string object.
   // Default implementation calls ToError.
-  virtual RawString* ToString();
+  virtual StringPtr ToString();
 
   // Append the reason to JSON array.
   virtual void AppendTo(JSONArray* array);
@@ -165,7 +160,7 @@
   IsolateGroup* isolate_group() const { return isolate_group_; }
   bool reload_aborted() const { return HasReasonsForCancelling(); }
   bool reload_skipped() const { return reload_skipped_; }
-  RawError* error() const;
+  ErrorPtr error() const;
   int64_t start_time_micros() const { return start_time_micros_; }
   int64_t reload_timestamp() const { return reload_timestamp_; }
 
@@ -216,6 +211,7 @@
                         const char* packages_url,
                         const uint8_t** kernel_buffer,
                         intptr_t* kernel_buffer_size);
+  void BuildModifiedLibrariesClosure(BitVector* modified_libs);
   void FindModifiedSources(bool force_reload,
                            Dart_SourceFile** modified_sources,
                            intptr_t* count,
@@ -277,14 +273,20 @@
   // A bit vector indicating which of the original libraries were modified.
   BitVector* modified_libs_ = nullptr;
 
+  // A bit vector indicating which of the original libraries were modified,
+  // or where a transitive dependency was modified.
+  BitVector* modified_libs_transitive_ = nullptr;
+
+  // A bit vector indicating which of the saved libraries that transitively
+  // depend on a modified libary.
+  BitVector* saved_libs_transitive_updated_ = nullptr;
+
   String& root_lib_url_;
-  RawObject** from() {
-    return reinterpret_cast<RawObject**>(&root_url_prefix_);
-  }
-  RawString* root_url_prefix_;
-  RawString* old_root_url_prefix_;
-  RawObject** to() {
-    return reinterpret_cast<RawObject**>(&old_root_url_prefix_);
+  ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&root_url_prefix_); }
+  StringPtr root_url_prefix_;
+  StringPtr old_root_url_prefix_;
+  ObjectPtr* to() {
+    return reinterpret_cast<ObjectPtr*>(&old_root_url_prefix_);
   }
 
   friend class Isolate;
@@ -295,7 +297,7 @@
   friend class ReasonForCancelling;
   friend class IsolateReloadContext;
   friend class IsolateGroup;  // GetClassSizeForHeapWalkAt
-  friend class RawObject;     // GetClassSizeForHeapWalkAt
+  friend class ObjectLayout;  // GetClassSizeForHeapWalkAt
 
   static Dart_FileModifiedCallback file_modified_callback_;
 };
@@ -321,14 +323,14 @@
   bool IsDirty(const Library& lib);
 
   // Prefers old classes when we are in the middle of a reload.
-  RawClass* GetClassForHeapWalkAt(intptr_t cid);
+  ClassPtr GetClassForHeapWalkAt(intptr_t cid);
   void DiscardSavedClassTable(bool is_rollback);
 
   void RegisterClass(const Class& new_cls);
 
   // Finds the library private key for |replacement_or_new| or return null
   // if |replacement_or_new| is new.
-  RawString* FindLibraryPrivateKey(const Library& replacement_or_new);
+  StringPtr FindLibraryPrivateKey(const Library& replacement_or_new);
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
@@ -340,8 +342,8 @@
 
   void ReloadPhase1AllocateStorageMapsAndCheckpoint();
   void CheckpointClasses();
-  RawObject* ReloadPhase2LoadKernel(kernel::Program* program,
-                                    const String& root_lib_url);
+  ObjectPtr ReloadPhase2LoadKernel(kernel::Program* program,
+                                   const String& root_lib_url);
   void ReloadPhase3FinalizeLoading();
   void ReloadPhase4CommitPrepare();
   void ReloadPhase4CommitFinish();
@@ -382,12 +384,12 @@
   std::shared_ptr<IsolateGroupReloadContext> group_reload_context_;
   Isolate* isolate_;
   intptr_t saved_num_cids_ = -1;
-  std::atomic<RawClass**> saved_class_table_;
+  std::atomic<ClassPtr*> saved_class_table_;
   MallocGrowableArray<LibraryInfo> library_infos_;
 
-  RawClass* OldClassOrNull(const Class& replacement_or_new);
-  RawLibrary* OldLibraryOrNull(const Library& replacement_or_new);
-  RawLibrary* OldLibraryOrNullBaseMoved(const Library& replacement_or_new);
+  ClassPtr OldClassOrNull(const Class& replacement_or_new);
+  LibraryPtr OldLibraryOrNull(const Library& replacement_or_new);
+  LibraryPtr OldLibraryOrNullBaseMoved(const Library& replacement_or_new);
 
   void BuildLibraryMapping();
   void BuildRemovedClassesSet();
@@ -401,19 +403,19 @@
   void AddEnumBecomeMapping(const Object& old, const Object& neu);
   void RebuildDirectSubclasses();
 
-  RawObject** from() {
-    return reinterpret_cast<RawObject**>(&old_classes_set_storage_);
+  ObjectPtr* from() {
+    return reinterpret_cast<ObjectPtr*>(&old_classes_set_storage_);
   }
-  RawArray* old_classes_set_storage_;
-  RawArray* class_map_storage_;
-  RawArray* removed_class_set_storage_;
-  RawArray* old_libraries_set_storage_;
-  RawArray* library_map_storage_;
-  RawArray* become_map_storage_;
-  RawGrowableObjectArray* become_enum_mappings_;
-  RawLibrary* saved_root_library_;
-  RawGrowableObjectArray* saved_libraries_;
-  RawObject** to() { return reinterpret_cast<RawObject**>(&saved_libraries_); }
+  ArrayPtr old_classes_set_storage_;
+  ArrayPtr class_map_storage_;
+  ArrayPtr removed_class_set_storage_;
+  ArrayPtr old_libraries_set_storage_;
+  ArrayPtr library_map_storage_;
+  ArrayPtr become_map_storage_;
+  GrowableObjectArrayPtr become_enum_mappings_;
+  LibraryPtr saved_root_library_;
+  GrowableObjectArrayPtr saved_libraries_;
+  ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&saved_libraries_); }
 
   friend class Isolate;
   friend class Class;  // AddStaticFieldMapping, AddEnumBecomeMapping.
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index ed39f1a..5f16ca6 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -4002,7 +4002,7 @@
   }
   virtual ~FindNoInstancesOfClass() {}
 
-  virtual bool FindObject(RawObject* obj) const {
+  virtual bool FindObject(ObjectPtr obj) const {
     return obj->GetClassId() == cid_;
   }
 
@@ -4516,7 +4516,7 @@
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
   EXPECT_ERROR(SimpleInvokeError(lib, "main"),
-               "Unimplemented handling of static target arity change");
+               "Static call with invalid arguments");
 }
 
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 07035fe..bae68b3 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -453,17 +453,17 @@
   return parameter_keys_->Length();
 }
 
-RawObject* JSONStream::GetObjectParameterKey(intptr_t i) const {
+ObjectPtr JSONStream::GetObjectParameterKey(intptr_t i) const {
   ASSERT((i >= 0) && (i < NumObjectParameters()));
   return parameter_keys_->At(i);
 }
 
-RawObject* JSONStream::GetObjectParameterValue(intptr_t i) const {
+ObjectPtr JSONStream::GetObjectParameterValue(intptr_t i) const {
   ASSERT((i >= 0) && (i < NumObjectParameters()));
   return parameter_values_->At(i);
 }
 
-RawObject* JSONStream::LookupObjectParam(const char* c_key) const {
+ObjectPtr JSONStream::LookupObjectParam(const char* c_key) const {
   const String& key = String::Handle(String::New(c_key));
   Object& test = Object::Handle();
   const intptr_t num_object_parameters = NumObjectParameters();
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index f0ee450..89907d4d 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -108,9 +108,9 @@
   Dart_Port reply_port() const { return reply_port_; }
 
   intptr_t NumObjectParameters() const;
-  RawObject* GetObjectParameterKey(intptr_t i) const;
-  RawObject* GetObjectParameterValue(intptr_t i) const;
-  RawObject* LookupObjectParam(const char* key) const;
+  ObjectPtr GetObjectParameterKey(intptr_t i) const;
+  ObjectPtr GetObjectParameterValue(intptr_t i) const;
+  ObjectPtr LookupObjectParam(const char* key) const;
 
   intptr_t num_params() const { return num_params_; }
   const char* GetParamKey(intptr_t i) const { return param_keys_[i]; }
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 1c1c752..d6663e3 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/kernel.h"
 
 #include "vm/bit_vector.h"
@@ -14,7 +16,6 @@
 #include "vm/parser.h"  // For Parser::kParameter* constants.
 #include "vm/stack_frame.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 namespace kernel {
@@ -204,7 +205,7 @@
  * possibly contain duplicate and unsorted data at the end.
  * Otherwise (when sublist doesn't exist in list) return new empty array.
  */
-static RawArray* AsSortedDuplicateFreeArray(GrowableArray<intptr_t>* source) {
+static ArrayPtr AsSortedDuplicateFreeArray(GrowableArray<intptr_t>* source) {
   intptr_t size = source->length();
   if (size == 0) {
     return Object::empty_array().raw();
@@ -299,7 +300,7 @@
       object = pool.ObjectAt(i);
       if (object.IsFunction()) {
         closure ^= object.raw();
-        if (closure.kind() == RawFunction::kClosureFunction &&
+        if (closure.kind() == FunctionLayout::kClosureFunction &&
             closure.IsLocalFunction()) {
           CollectTokenPosition(closure.token_pos(), token_positions);
           CollectTokenPosition(closure.end_token_pos(), token_positions);
@@ -491,8 +492,8 @@
                            data_program_offset),
         constant_reader_(this, active_class) {}
 
-  RawObject* EvaluateMetadata(intptr_t kernel_offset,
-                              bool is_annotations_offset) {
+  ObjectPtr EvaluateMetadata(intptr_t kernel_offset,
+                             bool is_annotations_offset) {
     SetOffset(kernel_offset);
 
     // Library and LibraryDependency objects do not have a tag in kernel binary.
@@ -527,8 +528,8 @@
   DISALLOW_COPY_AND_ASSIGN(MetadataEvaluator);
 };
 
-RawObject* EvaluateMetadata(const Field& metadata_field,
-                            bool is_annotations_offset) {
+ObjectPtr EvaluateMetadata(const Field& metadata_field,
+                           bool is_annotations_offset) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Thread* thread = Thread::Current();
@@ -569,7 +570,7 @@
                            data_program_offset),
         constant_reader_(this, active_class) {}
 
-  RawObject* BuildParameterDescriptor(const Function& function);
+  ObjectPtr BuildParameterDescriptor(const Function& function);
 
  private:
   ConstantReader constant_reader_;
@@ -577,7 +578,7 @@
   DISALLOW_COPY_AND_ASSIGN(ParameterDescriptorBuilder);
 };
 
-RawObject* ParameterDescriptorBuilder::BuildParameterDescriptor(
+ObjectPtr ParameterDescriptorBuilder::BuildParameterDescriptor(
     const Function& function) {
   SetOffset(function.kernel_offset());
   ReadUntilFunctionNode();
@@ -637,7 +638,7 @@
   return param_descriptor.raw();
 }
 
-RawObject* BuildParameterDescriptor(const Function& function) {
+ObjectPtr BuildParameterDescriptor(const Function& function) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Thread* thread = Thread::Current();
@@ -756,7 +757,8 @@
     for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) {
       type_param ^= type_params.TypeAt(i);
       bound = type_param.bound();
-      if (!bound.IsTopType() && !type_param.IsGenericCovariantImpl()) {
+      if (!bound.IsTopTypeForSubtyping() &&
+          !type_param.IsGenericCovariantImpl()) {
         return true;
       }
     }
@@ -770,7 +772,7 @@
   auto& type = AbstractType::Handle(zone);
   for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
     type = function.ParameterTypeAt(i);
-    if (!type.IsTopTypeForAssignability() &&
+    if (!type.IsTopTypeForSubtyping() &&
         !is_generic_covariant_impl.Contains(i) && !is_covariant.Contains(i)) {
       return true;
     }
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index e68ef66..f612540 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -93,6 +93,7 @@
   const uint8_t* kernel_data() { return kernel_data_; }
   intptr_t kernel_data_size() { return kernel_data_size_; }
   intptr_t library_count() { return library_count_; }
+  NNBDCompiledMode compilation_mode() const { return compilation_mode_; }
 
  private:
   Program() : typed_data_(NULL), kernel_data_(NULL), kernel_data_size_(-1) {}
@@ -100,6 +101,7 @@
   bool single_program_;
   uint32_t binary_version_;
   NameIndex main_method_reference_;  // Procedure.
+  NNBDCompiledMode compilation_mode_;
   intptr_t library_count_;
 
   // The offset from the start of the binary to the start of the source table.
@@ -195,9 +197,9 @@
 
 void CollectTokenPositionsFor(const Script& script);
 
-RawObject* EvaluateMetadata(const Field& metadata_field,
-                            bool is_annotations_offset);
-RawObject* BuildParameterDescriptor(const Function& function);
+ObjectPtr EvaluateMetadata(const Field& metadata_field,
+                           bool is_annotations_offset);
+ObjectPtr BuildParameterDescriptor(const Function& function);
 
 // Fills in [is_covariant] and [is_generic_covariant_impl] vectors
 // according to covariance attributes of [function] parameters.
@@ -217,7 +219,7 @@
 // Returns a list of ParameterTypeChecks needed by a dynamic invocation
 // forwarder that targets [function]. Indices in these checks correspond to
 // bytecode frame indices.
-RawArray* CollectDynamicInvocationChecks(const Function& function);
+ArrayPtr CollectDynamicInvocationChecks(const Function& function);
 
 ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
                                                   Zone* zone);
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index fe02d0b..d0431aa 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -3,15 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
+#include "vm/kernel_binary.h"
+
 #include <memory>
 
-#include "vm/kernel_binary.h"
 #include "platform/globals.h"
 #include "vm/compiler/frontend/kernel_to_il.h"
 #include "vm/dart_api_impl.h"
 #include "vm/flags.h"
 #include "vm/growable_array.h"
 #include "vm/kernel.h"
+#include "vm/object.h"
 #include "vm/os.h"
 
 namespace dart {
@@ -31,7 +33,7 @@
   return "Unknown";
 }
 
-RawTypedData* Reader::ReadLineStartsData(intptr_t line_start_count) {
+TypedDataPtr Reader::ReadLineStartsData(intptr_t line_start_count) {
   TypedData& line_starts_data = TypedData::Handle(
       TypedData::New(kTypedDataInt8ArrayCid, line_start_count, Heap::kOld));
 
@@ -85,7 +87,7 @@
 
 std::unique_ptr<Program> Program::ReadFrom(Reader* reader, const char** error) {
   if (reader->size() < 60) {
-    // A kernel file currently contains at least the following:
+    // A kernel file (v41) currently contains at least the following:
     //   * Magic number (32)
     //   * Kernel version (32)
     //   * List of problems (8)
@@ -94,9 +96,9 @@
     //   * Metadata length (32)
     //   * Length of string table (8)
     //   * Length of constant table (8)
-    //   * Component index (10 * 32)
+    //   * Component index (11 * 32)
     //
-    // so is at least 60 bytes.
+    // so is at least 64 bytes.
     // (Technically it will also contain an empty entry in both source map and
     // string table, taking up another 8 bytes.)
     if (error != nullptr) {
@@ -150,10 +152,17 @@
   // Read backwards at the end.
   program->library_count_ = reader->ReadFromIndexNoReset(
       reader->size_, LibraryCountFieldCountFromEnd, 1, 0);
+  static_assert(kMinSupportedKernelFormatVersion < 41, "cleanup this code");
+  intptr_t count_from_first_library_offset =
+      SourceTableFieldCountFromFirstLibraryOffsetPre41;
+  if (formatVersion >= 41) {
+    count_from_first_library_offset =
+        SourceTableFieldCountFromFirstLibraryOffset41Plus;
+  }
   program->source_table_offset_ = reader->ReadFromIndexNoReset(
       reader->size_,
       LibraryCountFieldCountFromEnd + 1 + program->library_count_ + 1 +
-          SourceTableFieldCountFromFirstLibraryOffset,
+          count_from_first_library_offset,
       1, 0);
   program->name_table_offset_ = reader->ReadUInt32();
   program->metadata_payloads_offset_ = reader->ReadUInt32();
@@ -162,6 +171,13 @@
   program->constant_table_offset_ = reader->ReadUInt32();
 
   program->main_method_reference_ = NameIndex(reader->ReadUInt32() - 1);
+  if (formatVersion >= 41) {
+    NNBDCompiledMode compilation_mode =
+        static_cast<NNBDCompiledMode>(reader->ReadUInt32());
+    program->compilation_mode_ = compilation_mode;
+  } else {
+    program->compilation_mode_ = NNBDCompiledMode::kDisabled;
+  }
 
   return program;
 }
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 43c3700..af2d8ba 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
 
 // Both version numbers are inclusive.
 static const uint32_t kMinSupportedKernelFormatVersion = 29;
-static const uint32_t kMaxSupportedKernelFormatVersion = 40;
+static const uint32_t kMaxSupportedKernelFormatVersion = 42;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -199,7 +199,9 @@
 
 static const int SpecializedIntLiteralBias = 3;
 static const int LibraryCountFieldCountFromEnd = 1;
-static const int SourceTableFieldCountFromFirstLibraryOffset = 6;
+static const int KernelFormatVersionOffset = 4;
+static const int SourceTableFieldCountFromFirstLibraryOffsetPre41 = 6;
+static const int SourceTableFieldCountFromFirstLibraryOffset41Plus = 7;
 
 static const int HeaderSize = 8;  // 'magic', 'formatVersion'.
 
@@ -413,7 +415,7 @@
   const uint8_t* raw_buffer() const { return raw_buffer_; }
   void set_raw_buffer(const uint8_t* raw_buffer) { raw_buffer_ = raw_buffer; }
 
-  RawExternalTypedData* ExternalDataFromTo(intptr_t start, intptr_t end) {
+  ExternalTypedDataPtr ExternalDataFromTo(intptr_t start, intptr_t end) {
     return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid,
                                   const_cast<uint8_t*>(buffer() + start),
                                   end - start, Heap::kOld);
@@ -424,7 +426,7 @@
     return &buffer()[offset];
   }
 
-  RawTypedData* ReadLineStartsData(intptr_t line_start_count);
+  TypedDataPtr ReadLineStartsData(intptr_t line_start_count);
 
  private:
   const uint8_t* buffer() const {
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index a326820..a67d70a 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -93,7 +93,6 @@
 #if !defined(DART_PRECOMPILER)
     api_flags.use_osr = true;
 #endif
-    api_flags.null_safety = false;
 
     isolate = reinterpret_cast<Isolate*>(
         create_group_callback(KernelIsolate::kName, KernelIsolate::kName, NULL,
@@ -759,9 +758,8 @@
         isolate != NULL ? isolate->asserts() : FLAG_enable_asserts;
 
     Dart_CObject null_safety;
-    null_safety.type = Dart_CObject_kBool;
-    null_safety.value.as_bool =
-        isolate != NULL ? isolate->null_safety() : FLAG_null_safety;
+    null_safety.type = Dart_CObject_kInt32;
+    null_safety.value.as_int32 = FLAG_null_safety;
 
     intptr_t num_experimental_flags = experimental_flags->length();
     Dart_CObject** experimental_flags_array =
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 0b07be9..7bfd7d7 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1,6 +1,7 @@
 // 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.
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/kernel_loader.h"
 
@@ -23,7 +24,6 @@
 #include "vm/symbols.h"
 #include "vm/thread.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 namespace dart {
 namespace kernel {
 
@@ -115,7 +115,7 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleExpressionConverter);
 };
 
-RawArray* KernelLoader::MakeFieldsArray() {
+ArrayPtr KernelLoader::MakeFieldsArray() {
   const intptr_t len = fields_.length();
   const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
   for (intptr_t i = 0; i < len; i++) {
@@ -124,7 +124,7 @@
   return res.raw();
 }
 
-RawArray* KernelLoader::MakeFunctionsArray() {
+ArrayPtr KernelLoader::MakeFunctionsArray() {
   const intptr_t len = functions_.length();
   const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
   for (intptr_t i = 0; i < len; i++) {
@@ -133,12 +133,12 @@
   return res.raw();
 }
 
-RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary(
+LibraryPtr BuildingTranslationHelper::LookupLibraryByKernelLibrary(
     NameIndex library) {
   return loader_->LookupLibrary(library);
 }
 
-RawClass* BuildingTranslationHelper::LookupClassByKernelClass(NameIndex klass) {
+ClassPtr BuildingTranslationHelper::LookupClassByKernelClass(NameIndex klass) {
 #if defined(DEBUG)
   LibraryLookupHandleScope library_lookup_handle_scope(library_lookup_handle_);
 #endif  // defined(DEBUG)
@@ -337,9 +337,9 @@
   subprogram_file_starts->Reverse();
 }
 
-RawString* KernelLoader::FindSourceForScript(const uint8_t* kernel_buffer,
-                                             intptr_t kernel_buffer_length,
-                                             const String& uri) {
+StringPtr KernelLoader::FindSourceForScript(const uint8_t* kernel_buffer,
+                                            intptr_t kernel_buffer_length,
+                                            const String& uri) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   TranslationHelper translation_helper(thread);
@@ -566,7 +566,7 @@
   kernel_program_info_.set_potential_natives(potential_natives_);
 }
 
-RawString* KernelLoader::DetectExternalNameCtor() {
+StringPtr KernelLoader::DetectExternalNameCtor() {
   helper_.ReadTag();
   helper_.ReadPosition();
   NameIndex annotation_class = H.EnclosingName(
@@ -721,7 +721,7 @@
 #endif
 }
 
-RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
+ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) {
   ASSERT(kernel_program_info_.constants() == Array::null());
 
   if (!program_->is_single_program()) {
@@ -793,7 +793,7 @@
   }
 }
 
-RawObject* KernelLoader::LoadExpressionEvaluationFunction(
+ObjectPtr KernelLoader::LoadExpressionEvaluationFunction(
     const String& library_url,
     const String& klass) {
   // Find the original context, i.e. library/class, in which the evaluation will
@@ -986,7 +986,7 @@
   field.set_has_nontrivial_initializer(false);
 }
 
-RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
+LibraryPtr KernelLoader::LoadLibrary(intptr_t index) {
   if (!program_->is_single_program()) {
     FATAL(
         "Trying to load a concatenated dill file at a time where that is "
@@ -1675,7 +1675,7 @@
     }
 
     Function& function = Function::ZoneHandle(
-        Z, Function::New(name, RawFunction::kConstructor,
+        Z, Function::New(name, FunctionLayout::kConstructor,
                          false,  // is_static
                          constructor_helper.IsConst(),
                          false,  // is_abstract
@@ -1939,7 +1939,7 @@
   procedure_helper.SetJustRead(ProcedureHelper::kAnnotations);
   const Object& script_class =
       ClassForScriptAt(owner, procedure_helper.source_uri_index_);
-  RawFunction::Kind kind = GetFunctionType(procedure_helper.kind_);
+  FunctionLayout::Kind kind = GetFunctionType(procedure_helper.kind_);
 
   // We do not register expression evaluation libraries with the VM:
   // The expression evaluation functions should be GC-able as soon as
@@ -2006,19 +2006,19 @@
 
   switch (function_node_helper.dart_async_marker_) {
     case FunctionNodeHelper::kSyncStar:
-      function.set_modifier(RawFunction::kSyncGen);
+      function.set_modifier(FunctionLayout::kSyncGen);
       function.set_is_visible(!FLAG_causal_async_stacks &&
                               !FLAG_lazy_async_stacks);
       break;
     case FunctionNodeHelper::kAsync:
-      function.set_modifier(RawFunction::kAsync);
+      function.set_modifier(FunctionLayout::kAsync);
       function.set_is_inlinable(!FLAG_causal_async_stacks &&
                                 !FLAG_lazy_async_stacks);
       function.set_is_visible(!FLAG_causal_async_stacks &&
                               !FLAG_lazy_async_stacks);
       break;
     case FunctionNodeHelper::kAsyncStar:
-      function.set_modifier(RawFunction::kAsyncGen);
+      function.set_modifier(FunctionLayout::kAsyncGen);
       function.set_is_inlinable(!FLAG_causal_async_stacks &&
                                 !FLAG_lazy_async_stacks);
       function.set_is_visible(!FLAG_causal_async_stacks &&
@@ -2088,8 +2088,8 @@
   return klass;
 }
 
-RawScript* KernelLoader::LoadScriptAt(intptr_t index,
-                                      UriToSourceTable* uri_to_source_table) {
+ScriptPtr KernelLoader::LoadScriptAt(intptr_t index,
+                                     UriToSourceTable* uri_to_source_table) {
   const String& uri_string = helper_.SourceTableUriFor(index);
   const String& import_uri_string =
       helper_.SourceTableImportUriFor(index, program_->binary_version());
@@ -2182,13 +2182,6 @@
   }
   ASSERT(field.NeedsGetter());
 
-  if (field.is_late() && field.has_nontrivial_initializer()) {
-    // Late fields are initialized to Object::sentinel, which is a flavor of
-    // null. So we need to record that store so that the field guard doesn't
-    // prematurely optimise out the late field's sentinel checking logic.
-    field.RecordStore(Object::null_object());
-  }
-
   const String& getter_name = H.DartGetterName(field_helper->canonical_name_);
   const Object& script_class =
       ClassForScriptAt(klass, field_helper->source_uri_index_);
@@ -2196,8 +2189,8 @@
       Z,
       Function::New(
           getter_name,
-          field_helper->IsStatic() ? RawFunction::kImplicitStaticGetter
-                                   : RawFunction::kImplicitGetter,
+          field_helper->IsStatic() ? FunctionLayout::kImplicitStaticGetter
+                                   : FunctionLayout::kImplicitGetter,
           field_helper->IsStatic(),
           // The functions created by the parser have is_const for static fields
           // that are const (not just final) and they have is_const for
@@ -2223,7 +2216,7 @@
     ASSERT(!field_helper->IsConst());
     const String& setter_name = H.DartSetterName(field_helper->canonical_name_);
     Function& setter = Function::ZoneHandle(
-        Z, Function::New(setter_name, RawFunction::kImplicitSetter,
+        Z, Function::New(setter_name, FunctionLayout::kImplicitSetter,
                          field_helper->IsStatic(),
                          false,  // is_const
                          false,  // is_abstract
@@ -2241,8 +2234,8 @@
   }
 }
 
-RawLibrary* KernelLoader::LookupLibraryOrNull(NameIndex library) {
-  RawLibrary* result;
+LibraryPtr KernelLoader::LookupLibraryOrNull(NameIndex library) {
+  LibraryPtr result;
   name_index_handle_ = Smi::New(library);
   {
     result = kernel_program_info_.LookupLibrary(thread_, name_index_handle_);
@@ -2265,10 +2258,10 @@
                                             handle);
 }
 
-RawLibrary* KernelLoader::LookupLibrary(NameIndex library) {
+LibraryPtr KernelLoader::LookupLibrary(NameIndex library) {
   name_index_handle_ = Smi::New(library);
   {
-    RawLibrary* result =
+    LibraryPtr result =
         kernel_program_info_.LookupLibrary(thread_, name_index_handle_);
     NoSafepointScope no_safepoint_scope(thread_);
     if (result != Library::null()) {
@@ -2299,14 +2292,14 @@
                                             handle);
 }
 
-RawLibrary* KernelLoader::LookupLibraryFromClass(NameIndex klass) {
+LibraryPtr KernelLoader::LookupLibraryFromClass(NameIndex klass) {
   return LookupLibrary(H.CanonicalNameParent(klass));
 }
 
-RawClass* KernelLoader::LookupClass(const Library& library, NameIndex klass) {
+ClassPtr KernelLoader::LookupClass(const Library& library, NameIndex klass) {
   name_index_handle_ = Smi::New(klass);
   {
-    RawClass* raw_class =
+    ClassPtr raw_class =
         kernel_program_info_.LookupClass(thread_, name_index_handle_);
     NoSafepointScope no_safepoint_scope(thread_);
     if (raw_class != Class::null()) {
@@ -2338,23 +2331,23 @@
   return handle.raw();
 }
 
-RawFunction::Kind KernelLoader::GetFunctionType(
+FunctionLayout::Kind KernelLoader::GetFunctionType(
     ProcedureHelper::Kind procedure_kind) {
   intptr_t lookuptable[] = {
-      RawFunction::kRegularFunction,  // Procedure::kMethod
-      RawFunction::kGetterFunction,   // Procedure::kGetter
-      RawFunction::kSetterFunction,   // Procedure::kSetter
-      RawFunction::kRegularFunction,  // Procedure::kOperator
-      RawFunction::kConstructor,      // Procedure::kFactory
+      FunctionLayout::kRegularFunction,  // Procedure::kMethod
+      FunctionLayout::kGetterFunction,   // Procedure::kGetter
+      FunctionLayout::kSetterFunction,   // Procedure::kSetter
+      FunctionLayout::kRegularFunction,  // Procedure::kOperator
+      FunctionLayout::kConstructor,      // Procedure::kFactory
   };
   intptr_t kind = static_cast<int>(procedure_kind);
   ASSERT(0 <= kind && kind <= ProcedureHelper::kFactory);
-  return static_cast<RawFunction::Kind>(lookuptable[kind]);
+  return static_cast<FunctionLayout::Kind>(lookuptable[kind]);
 }
 
-RawFunction* CreateFieldInitializerFunction(Thread* thread,
-                                            Zone* zone,
-                                            const Field& field) {
+FunctionPtr CreateFieldInitializerFunction(Thread* thread,
+                                           Zone* zone,
+                                           const Field& field) {
   ASSERT(field.InitializerFunction() == Function::null());
 
   String& init_name = String::Handle(zone, field.name());
@@ -2379,7 +2372,7 @@
 
   // Create a static initializer.
   const Function& initializer_fun = Function::Handle(
-      zone, Function::New(init_name, RawFunction::kFieldInitializer,
+      zone, Function::New(init_name, FunctionLayout::kFieldInitializer,
                           field.is_static(),  // is_static
                           false,              // is_const
                           false,              // is_abstract
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 3298101..8e79898 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -31,8 +31,8 @@
         library_lookup_handle_(Library::Handle(thread->zone())) {}
   virtual ~BuildingTranslationHelper() {}
 
-  virtual RawLibrary* LookupLibraryByKernelLibrary(NameIndex library);
-  virtual RawClass* LookupClassByKernelClass(NameIndex klass);
+  virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
+  virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
 
  private:
   KernelLoader* loader_;
@@ -188,15 +188,15 @@
 
   // Returns the library containing the main procedure, null if there
   // was no main procedure, or a failure object if there was an error.
-  RawObject* LoadProgram(bool process_pending_classes = true);
+  ObjectPtr LoadProgram(bool process_pending_classes = true);
 
   // Load given library.
   void LoadLibrary(const Library& library);
 
   // Returns the function which will evaluate the expression, or a failure
   // object if there was an error.
-  RawObject* LoadExpressionEvaluationFunction(const String& library_url,
-                                              const String& klass);
+  ObjectPtr LoadExpressionEvaluationFunction(const String& library_url,
+                                             const String& klass);
 
   // Finds all libraries that have been modified in this incremental
   // version of the kernel program file.
@@ -212,9 +212,9 @@
                                     intptr_t* p_num_classes,
                                     intptr_t* p_num_procedures);
 
-  static RawString* FindSourceForScript(const uint8_t* kernel_buffer,
-                                        intptr_t kernel_buffer_length,
-                                        const String& url);
+  static StringPtr FindSourceForScript(const uint8_t* kernel_buffer,
+                                       intptr_t kernel_buffer_length,
+                                       const String& url);
 
   void FinishTopLevelClassLoading(const Class& toplevel_class,
                                   const Library& library,
@@ -228,7 +228,7 @@
   // Check for the presence of a (possibly const) constructor for the
   // 'ExternalName' class. If found, returns the name parameter to the
   // constructor.
-  RawString* DetectExternalNameCtor();
+  StringPtr DetectExternalNameCtor();
 
   // Check for the presence of a (possibly const) constructor for the 'pragma'
   // class. Returns whether it was found (no details about the type of pragma).
@@ -255,7 +255,7 @@
   void InitializeFields(
       DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
 
-  RawLibrary* LoadLibrary(intptr_t index);
+  LibraryPtr LoadLibrary(intptr_t index);
 
   const String& LibraryUri(intptr_t library_index) {
     return translation_helper_.DartSymbolPlain(
@@ -316,10 +316,10 @@
                      bool in_class,
                      intptr_t procedure_end);
 
-  RawArray* MakeFieldsArray();
-  RawArray* MakeFunctionsArray();
+  ArrayPtr MakeFieldsArray();
+  ArrayPtr MakeFunctionsArray();
 
-  RawScript* LoadScriptAt(
+  ScriptPtr LoadScriptAt(
       intptr_t index,
       DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
 
@@ -327,7 +327,7 @@
   // for klass whose script corresponds to the uri index.
   // Otherwise return klass.
   const Object& ClassForScriptAt(const Class& klass, intptr_t source_uri_index);
-  RawScript* ScriptAt(intptr_t source_uri_index) {
+  ScriptPtr ScriptAt(intptr_t source_uri_index) {
     return kernel_program_info_.ScriptAt(source_uri_index);
   }
 
@@ -339,12 +339,12 @@
   void LoadLibraryImportsAndExports(Library* library,
                                     const Class& toplevel_class);
 
-  RawLibrary* LookupLibraryOrNull(NameIndex library);
-  RawLibrary* LookupLibrary(NameIndex library);
-  RawLibrary* LookupLibraryFromClass(NameIndex klass);
-  RawClass* LookupClass(const Library& library, NameIndex klass);
+  LibraryPtr LookupLibraryOrNull(NameIndex library);
+  LibraryPtr LookupLibrary(NameIndex library);
+  LibraryPtr LookupLibraryFromClass(NameIndex klass);
+  ClassPtr LookupClass(const Library& library, NameIndex klass);
 
-  RawFunction::Kind GetFunctionType(ProcedureHelper::Kind procedure_kind);
+  FunctionLayout::Kind GetFunctionType(ProcedureHelper::Kind procedure_kind);
 
   void EnsureExternalClassIsLookedUp() {
     if (external_name_class_.IsNull()) {
@@ -456,9 +456,9 @@
   DISALLOW_COPY_AND_ASSIGN(KernelLoader);
 };
 
-RawFunction* CreateFieldInitializerFunction(Thread* thread,
-                                            Zone* zone,
-                                            const Field& field);
+FunctionPtr CreateFieldInitializerFunction(Thread* thread,
+                                           Zone* zone,
+                                           const Field& field);
 
 }  // namespace kernel
 }  // namespace dart
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index 16c6d93..df163dc 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -191,6 +191,22 @@
   DISALLOW_COPY_AND_ASSIGN(MonitorLocker);
 };
 
+// Leaves the given monitor during the scope of the object.
+class MonitorLeaveScope : public ValueObject {
+ public:
+  explicit MonitorLeaveScope(MonitorLocker* monitor)
+      : monitor_locker_(monitor) {
+    monitor_locker_->Exit();
+  }
+
+  virtual ~MonitorLeaveScope() { monitor_locker_->Enter(); }
+
+ private:
+  MonitorLocker* const monitor_locker_;
+
+  DISALLOW_COPY_AND_ASSIGN(MonitorLeaveScope);
+};
+
 /*
  * Safepoint mutex locker :
  * This locker abstraction should be used when the enclosing code could
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 19deb0a..439cccc 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -13,9 +13,9 @@
 
 namespace dart {
 
-RawMegamorphicCache* MegamorphicCacheTable::Lookup(Thread* thread,
-                                                   const String& name,
-                                                   const Array& descriptor) {
+MegamorphicCachePtr MegamorphicCacheTable::Lookup(Thread* thread,
+                                                  const String& name,
+                                                  const Array& descriptor) {
   Isolate* isolate = thread->isolate();
   // Multiple compilation threads could access this lookup.
   SafepointMutexLocker ml(isolate->megamorphic_mutex());
@@ -44,10 +44,10 @@
   return cache.raw();
 }
 
-RawFunction* MegamorphicCacheTable::miss_handler(Isolate* isolate) {
-  ASSERT(isolate->object_store()->megamorphic_miss_function() !=
+FunctionPtr MegamorphicCacheTable::miss_handler(Isolate* isolate) {
+  ASSERT(isolate->object_store()->megamorphic_call_miss_function() !=
          Function::null());
-  return isolate->object_store()->megamorphic_miss_function();
+  return isolate->object_store()->megamorphic_call_miss_function();
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -56,8 +56,8 @@
   // normal Dart function.
   compiler::ObjectPoolBuilder object_pool_builder;
   const Code& code = Code::Handle(StubCode::Generate(
-      "_stub_MegamorphicMiss", &object_pool_builder,
-      compiler::StubCodeCompiler::GenerateMegamorphicMissStub));
+      "_stub_MegamorphicCallMiss", &object_pool_builder,
+      compiler::StubCodeCompiler::GenerateMegamorphicCallMissStub));
 
   const auto& object_pool =
       ObjectPool::Handle(ObjectPool::NewFromBuilder(object_pool_builder));
@@ -69,14 +69,14 @@
   code.set_exception_handlers(Object::empty_exception_handlers());
   const Class& cls =
       Class::Handle(Type::Handle(Type::DartFunctionType()).type_class());
-  const Function& function = Function::Handle(
-      Function::New(Symbols::MegamorphicMiss(), RawFunction::kRegularFunction,
-                    true,   // Static, but called as a method.
-                    false,  // Not const.
-                    false,  // Not abstract.
-                    false,  // Not external.
-                    false,  // Not native.
-                    cls, TokenPosition::kNoSource));
+  const Function& function = Function::Handle(Function::New(
+      Symbols::MegamorphicCallMiss(), FunctionLayout::kRegularFunction,
+      true,   // Static, but called as a method.
+      false,  // Not const.
+      false,  // Not abstract.
+      false,  // Not external.
+      false,  // Not native.
+      cls, TokenPosition::kNoSource));
   function.set_result_type(Type::Handle(Type::DynamicType()));
   function.set_is_debuggable(false);
   function.set_is_visible(false);
@@ -84,9 +84,9 @@
   // For inclusion in Snapshot::kFullJIT.
   function.set_unoptimized_code(code);
 
-  ASSERT(isolate->object_store()->megamorphic_miss_function() ==
+  ASSERT(isolate->object_store()->megamorphic_call_miss_function() ==
          Function::null());
-  isolate->object_store()->SetMegamorphicMissHandler(code, function);
+  isolate->object_store()->SetMegamorphicCallMissHandler(code, function);
 }
 
 void MegamorphicCacheTable::ReInitMissHandlerCode(
@@ -95,14 +95,15 @@
   ASSERT(FLAG_precompiled_mode && FLAG_use_bare_instructions);
 
   const Code& code = Code::Handle(StubCode::Generate(
-      "_stub_MegamorphicMiss", wrapper,
-      compiler::StubCodeCompiler::GenerateMegamorphicMissStub));
+      "_stub_MegamorphicCallMiss", wrapper,
+      compiler::StubCodeCompiler::GenerateMegamorphicCallMissStub));
   code.set_exception_handlers(Object::empty_exception_handlers());
 
   auto object_store = isolate->object_store();
-  auto& function = Function::Handle(object_store->megamorphic_miss_function());
+  auto& function =
+      Function::Handle(object_store->megamorphic_call_miss_function());
   function.AttachCode(code);
-  object_store->SetMegamorphicMissHandler(code, function);
+  object_store->SetMegamorphicCallMissHandler(code, function);
 }
 
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/megamorphic_cache_table.h b/runtime/vm/megamorphic_cache_table.h
index 6b68c6c..fb714a3 100644
--- a/runtime/vm/megamorphic_cache_table.h
+++ b/runtime/vm/megamorphic_cache_table.h
@@ -6,6 +6,7 @@
 #define RUNTIME_VM_MEGAMORPHIC_CACHE_TABLE_H_
 
 #include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
@@ -17,17 +18,12 @@
 class Function;
 class Isolate;
 class ObjectPointerVisitor;
-class RawArray;
-class RawFunction;
-class RawCode;
-class RawMegamorphicCache;
-class RawString;
 class String;
 class Thread;
 
 class MegamorphicCacheTable : public AllStatic {
  public:
-  static RawFunction* miss_handler(Isolate* isolate);
+  static FunctionPtr miss_handler(Isolate* isolate);
   NOT_IN_PRECOMPILED(static void InitMissHandler(Isolate* isolate));
 
   // Re-initializes the megamorphic miss handler function in the object store.
@@ -39,9 +35,9 @@
       static void ReInitMissHandlerCode(Isolate* isolate,
                                         compiler::ObjectPoolBuilder* wrapper));
 
-  static RawMegamorphicCache* Lookup(Thread* thread,
-                                     const String& name,
-                                     const Array& descriptor);
+  static MegamorphicCachePtr Lookup(Thread* thread,
+                                    const String& name,
+                                    const Array& descriptor);
 
   static void PrintSizes(Isolate* isolate);
 };
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 59c1917..b4d4c69 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -24,38 +24,57 @@
     : next_(NULL),
       dest_port_(dest_port),
       delivery_failure_port_(delivery_failure_port),
-      snapshot_(snapshot),
+      payload_(snapshot),
       snapshot_length_(snapshot_length),
       finalizable_data_(finalizable_data),
       priority_(priority) {
   ASSERT((priority == kNormalPriority) ||
          (delivery_failure_port == kIllegalPort));
-  ASSERT(!IsRaw());
+  ASSERT(IsSnapshot());
 }
 
 Message::Message(Dart_Port dest_port,
-                 RawObject* raw_obj,
+                 ObjectPtr raw_obj,
                  Priority priority,
                  Dart_Port delivery_failure_port)
     : next_(NULL),
       dest_port_(dest_port),
       delivery_failure_port_(delivery_failure_port),
-      snapshot_(reinterpret_cast<uint8_t*>(raw_obj)),
+      payload_(raw_obj),
       snapshot_length_(0),
       finalizable_data_(NULL),
       priority_(priority) {
-  ASSERT(!raw_obj->IsHeapObject() || raw_obj->InVMIsolateHeap());
+  ASSERT(!raw_obj->IsHeapObject() || raw_obj->ptr()->InVMIsolateHeap());
   ASSERT((priority == kNormalPriority) ||
          (delivery_failure_port == kIllegalPort));
   ASSERT(IsRaw());
 }
 
+Message::Message(Dart_Port dest_port,
+                 Bequest* bequest,
+                 Priority priority,
+                 Dart_Port delivery_failure_port)
+    : next_(nullptr),
+      dest_port_(dest_port),
+      delivery_failure_port_(delivery_failure_port),
+      payload_(bequest),
+      snapshot_length_(-1),
+      finalizable_data_(nullptr),
+      priority_(priority) {
+  ASSERT((priority == kNormalPriority) ||
+         (delivery_failure_port == kIllegalPort));
+  ASSERT(IsBequest());
+}
+
 Message::~Message() {
   ASSERT(delivery_failure_port_ == kIllegalPort);
-  if (!IsRaw()) {
-    free(snapshot_);
+  if (IsSnapshot()) {
+    free(payload_.snapshot_);
   }
   delete finalizable_data_;
+  if (IsBequest()) {
+    delete (payload_.bequest_);
+  }
 }
 
 bool Message::RedirectToDeliveryFailurePort() {
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 6694940..d29e7fb 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -12,14 +12,19 @@
 #include "vm/allocation.h"
 #include "vm/finalizable_data.h"
 #include "vm/globals.h"
+#include "vm/tagged_pointer.h"
 
 // Duplicated from dart_api.h to avoid including the whole header.
 typedef int64_t Dart_Port;
 
 namespace dart {
 
+class Bequest;
 class JSONStream;
-class RawObject;
+class PersistentHandle;
+class HeapPage;
+class WeakTable;
+class FreeList;
 
 class Message {
  public:
@@ -58,7 +63,12 @@
   // Message objects can also carry RawObject pointers for Smis and objects in
   // the VM heap. This is indicated by setting the len_ field to 0.
   Message(Dart_Port dest_port,
-          RawObject* raw_obj,
+          ObjectPtr raw_obj,
+          Priority priority,
+          Dart_Port delivery_failure_port = kIllegalPort);
+
+  Message(Dart_Port dest_port,
+          Bequest* bequest,
           Priority priority,
           Dart_Port delivery_failure_port = kIllegalPort);
 
@@ -72,8 +82,8 @@
   Dart_Port dest_port() const { return dest_port_; }
 
   uint8_t* snapshot() const {
-    ASSERT(!IsRaw());
-    return snapshot_;
+    ASSERT(IsSnapshot());
+    return payload_.snapshot_;
   }
   intptr_t snapshot_length() const { return snapshot_length_; }
 
@@ -87,14 +97,25 @@
     return size;
   }
 
-  RawObject* raw_obj() const {
+  ObjectPtr raw_obj() const {
     ASSERT(IsRaw());
-    return reinterpret_cast<RawObject*>(snapshot_);
+    return payload_.raw_obj_;
+  }
+  Bequest* bequest() const {
+    ASSERT(IsBequest());
+    return payload_.bequest_;
   }
   Priority priority() const { return priority_; }
 
+  // A message processed at any interrupt point (stack overflow check) instead
+  // of at the top of the message loop. Control messages from dart:isolate or
+  // vm-service requests.
   bool IsOOB() const { return priority_ == Message::kOOBPriority; }
+  bool IsSnapshot() const { return !IsRaw() && !IsBequest(); }
+  // A message whose object is an immortal object from the vm-isolate's heap.
   bool IsRaw() const { return snapshot_length_ == 0; }
+  // A message sent from sendAndExit.
+  bool IsBequest() const { return snapshot_length_ == -1; }
 
   bool RedirectToDeliveryFailurePort();
 
@@ -114,7 +135,15 @@
   Message* next_;
   Dart_Port dest_port_;
   Dart_Port delivery_failure_port_;
-  uint8_t* snapshot_;
+  union Payload {
+    Payload(uint8_t* snapshot) : snapshot_(snapshot) {}
+    Payload(ObjectPtr raw_obj) : raw_obj_(raw_obj) {}
+    Payload(Bequest* bequest) : bequest_(bequest) {}
+
+    uint8_t* snapshot_;
+    ObjectPtr raw_obj_;
+    Bequest* bequest_;
+  } payload_;
   intptr_t snapshot_length_;
   MessageFinalizableData* finalizable_data_;
   Priority priority_;
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index 133f8bf..19b5101 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -11,6 +11,7 @@
 #include "vm/lockers.h"
 #include "vm/message.h"
 #include "vm/os_thread.h"
+#include "vm/port_set.h"
 #include "vm/thread_pool.h"
 
 namespace dart {
@@ -211,6 +212,8 @@
   friend class MessageHandlerTestPeer;
   friend class MessageHandlerTask;
 
+  struct PortSetEntry : public PortSet<PortSetEntry>::Entry {};
+
   // Called by MessageHandlerTask to process our task queue.
   void TaskCallback();
 
@@ -248,6 +251,8 @@
   // thread.
   bool oob_message_handling_allowed_;
   bool paused_for_messages_;
+  PortSet<PortSetEntry>
+      ports_;  // Only accessed by [PortMap], protected by [PortMap]s lock.
   intptr_t live_ports_;  // The number of open ports, including control ports.
   intptr_t paused_;      // The number of pause messages received.
 #if !defined(PRODUCT)
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 67a3599..18fdad6 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -16,7 +16,6 @@
 // Forward declarations.
 class BootstrapNatives;
 class Object;
-class RawObject;
 class Simulator;
 class Thread;
 
@@ -83,11 +82,11 @@
   // Includes type arguments vector.
   int ArgCount() const { return ArgcBits::decode(argc_tag_); }
 
-  RawObject* ArgAt(int index) const {
+  ObjectPtr ArgAt(int index) const {
     ASSERT((index >= 0) && (index < ArgCount()));
-    RawObject** arg_ptr =
+    ObjectPtr* arg_ptr =
         &(argv_[ReverseArgOrderBit::decode(argc_tag_) ? index : -index]);
-    // Tell MemorySanitizer the RawObject* was initialized (by generated code).
+    // Tell MemorySanitizer the ObjectPtr was initialized (by generated code).
     MSAN_UNPOISON(arg_ptr, kWordSize);
     return *arg_ptr;
   }
@@ -95,7 +94,7 @@
   void SetArgAt(int index, const Object& value) const {
     ASSERT(thread_->execution_state() == Thread::kThreadInVM);
     ASSERT((index >= 0) && (index < ArgCount()));
-    RawObject** arg_ptr =
+    ObjectPtr* arg_ptr =
         &(argv_[ReverseArgOrderBit::decode(argc_tag_) ? index : -index]);
     *arg_ptr = value.raw();
   }
@@ -106,7 +105,7 @@
     return ArgCount() - NumHiddenArgs(function_bits);
   }
 
-  RawObject* NativeArg0() const {
+  ObjectPtr NativeArg0() const {
     int function_bits = FunctionBits::decode(argc_tag_);
     if ((function_bits & (kClosureFunctionBit | kInstanceFunctionBit)) ==
         (kClosureFunctionBit | kInstanceFunctionBit)) {
@@ -121,7 +120,7 @@
     return ArgAt(NumHiddenArgs(function_bits));
   }
 
-  RawObject* NativeArgAt(int index) const {
+  ObjectPtr NativeArgAt(int index) const {
     ASSERT((index >= 0) && (index < NativeArgCount()));
     if (index == 0) {
       return NativeArg0();
@@ -131,7 +130,7 @@
     return ArgAt(actual_index);
   }
 
-  RawTypeArguments* NativeTypeArgs() const {
+  TypeArgumentsPtr NativeTypeArgs() const {
     ASSERT(ToGenericFunction());
     return TypeArguments::RawCast(ArgAt(0));
   }
@@ -148,7 +147,7 @@
     return 0;
   }
 
-  RawAbstractType* NativeTypeArgAt(int index) const {
+  AbstractTypePtr NativeTypeArgAt(int index) const {
     ASSERT((index >= 0) && (index < NativeTypeArgCount()));
     TypeArguments& type_args = TypeArguments::Handle(NativeTypeArgs());
     if (type_args.IsNull()) {
@@ -163,7 +162,7 @@
     *retval_ = value.raw();
   }
 
-  RawObject* ReturnValue() const {
+  ObjectPtr ReturnValue() const {
     // Tell MemorySanitizer the retval_ was initialized (by generated code).
     MSAN_UNPOISON(retval_, kWordSize);
     return *retval_;
@@ -242,8 +241,8 @@
   // on the stack.
   NativeArguments(Thread* thread,
                   int argc_tag,
-                  RawObject** argv,
-                  RawObject** retval)
+                  ObjectPtr* argv,
+                  ObjectPtr* retval)
       : thread_(thread),
         argc_tag_(ReverseArgOrderBit::update(true, argc_tag)),
         argv_(argv),
@@ -253,7 +252,7 @@
   // exceedingly careful when we use it.  If there are any other side
   // effects in the statement that may cause GC, it could lead to
   // bugs.
-  void SetReturnUnsafe(RawObject* value) const {
+  void SetReturnUnsafe(ObjectPtr value) const {
     ASSERT(thread_->execution_state() == Thread::kThreadInVM);
     *retval_ = value;
   }
@@ -290,8 +289,8 @@
 
   Thread* thread_;      // Current thread pointer.
   intptr_t argc_tag_;   // Encodes argument count and invoked native call type.
-  RawObject** argv_;    // Pointer to an array of arguments to runtime call.
-  RawObject** retval_;  // Pointer to the return value area.
+  ObjectPtr* argv_;     // Pointer to an array of arguments to runtime call.
+  ObjectPtr* retval_;   // Pointer to the return value area.
 };
 
 }  // namespace dart
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index 3690222..44f3d91b 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -91,9 +91,8 @@
 }
 
 bool NativeEntry::ReturnValueIsError(NativeArguments* arguments) {
-  RawObject* retval = arguments->ReturnValue();
-  return (retval->IsHeapObject() &&
-          RawObject::IsErrorClassId(retval->GetClassId()));
+  ObjectPtr retval = arguments->ReturnValue();
+  return (retval->IsHeapObject() && IsErrorClassId(retval->GetClassId()));
 }
 
 void NativeEntry::PropagateErrors(NativeArguments* arguments) {
@@ -137,7 +136,7 @@
     // Be careful holding return_value_unsafe without a handle here.
     // A return of Object::sentinel means the return value has already
     // been set.
-    RawObject* return_value_unsafe = reinterpret_cast<BootstrapNativeFunction>(
+    ObjectPtr return_value_unsafe = reinterpret_cast<BootstrapNativeFunction>(
         func)(thread, zone.GetZone(), arguments);
     if (return_value_unsafe != Object::sentinel().raw()) {
       ASSERT(return_value_unsafe->IsDartInstance());
@@ -310,9 +309,14 @@
       const Code& current_trampoline =
           Code::Handle(zone, CodePatcher::GetNativeCallAt(
                                  caller_frame->pc(), code, &current_function));
+      // Some other isolate(with code being shared in AOT) might have updated
+      // target function/trampoline already.
       ASSERT(current_function ==
-             reinterpret_cast<NativeFunction>(LinkNativeCall));
-      ASSERT(current_trampoline.raw() == StubCode::CallBootstrapNative().raw());
+                 reinterpret_cast<NativeFunction>(LinkNativeCall) ||
+             current_function == target_function);
+      ASSERT(current_trampoline.raw() ==
+                 StubCode::CallBootstrapNative().raw() ||
+             current_function == target_function);
     }
 #endif
 
@@ -372,7 +376,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
 // Note: not GC safe. Use with care.
-NativeEntryData::Payload* NativeEntryData::FromTypedArray(RawTypedData* data) {
+NativeEntryData::Payload* NativeEntryData::FromTypedArray(TypedDataPtr data) {
   return reinterpret_cast<Payload*>(data->ptr()->data());
 }
 
@@ -384,7 +388,7 @@
   FromTypedArray(data_.raw())->kind = value;
 }
 
-MethodRecognizer::Kind NativeEntryData::GetKind(RawTypedData* data) {
+MethodRecognizer::Kind NativeEntryData::GetKind(TypedDataPtr data) {
   return FromTypedArray(data)->kind;
 }
 
@@ -396,7 +400,7 @@
   FromTypedArray(data_.raw())->trampoline = value;
 }
 
-NativeFunctionWrapper NativeEntryData::GetTrampoline(RawTypedData* data) {
+NativeFunctionWrapper NativeEntryData::GetTrampoline(TypedDataPtr data) {
   return FromTypedArray(data)->trampoline;
 }
 
@@ -408,7 +412,7 @@
   FromTypedArray(data_.raw())->native_function = value;
 }
 
-NativeFunction NativeEntryData::GetNativeFunction(RawTypedData* data) {
+NativeFunction NativeEntryData::GetNativeFunction(TypedDataPtr data) {
   return FromTypedArray(data)->native_function;
 }
 
@@ -420,14 +424,14 @@
   FromTypedArray(data_.raw())->argc_tag = value;
 }
 
-intptr_t NativeEntryData::GetArgcTag(RawTypedData* data) {
+intptr_t NativeEntryData::GetArgcTag(TypedDataPtr data) {
   return FromTypedArray(data)->argc_tag;
 }
 
-RawTypedData* NativeEntryData::New(MethodRecognizer::Kind kind,
-                                   NativeFunctionWrapper trampoline,
-                                   NativeFunction native_function,
-                                   intptr_t argc_tag) {
+TypedDataPtr NativeEntryData::New(MethodRecognizer::Kind kind,
+                                  NativeFunctionWrapper trampoline,
+                                  NativeFunction native_function,
+                                  intptr_t argc_tag) {
   const TypedData& data = TypedData::Handle(
       TypedData::New(kTypedDataUint8ArrayCid, sizeof(Payload), Heap::kOld));
   NativeEntryData native_entry(data);
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index d9d4264..fae4261 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -33,25 +33,25 @@
   } while (0)
 #endif
 
-typedef RawObject* (*BootstrapNativeFunction)(Thread* thread,
-                                              Zone* zone,
-                                              NativeArguments* arguments);
+typedef ObjectPtr (*BootstrapNativeFunction)(Thread* thread,
+                                             Zone* zone,
+                                             NativeArguments* arguments);
 
 #define NATIVE_ENTRY_FUNCTION(name) BootstrapNatives::DN_##name
 
 #define DEFINE_NATIVE_ENTRY(name, type_argument_count, argument_count)         \
-  static RawObject* DN_Helper##name(Isolate* isolate, Thread* thread,          \
-                                    Zone* zone, NativeArguments* arguments);   \
-  RawObject* NATIVE_ENTRY_FUNCTION(name)(Thread * thread, Zone * zone,         \
-                                         NativeArguments * arguments) {        \
+  static ObjectPtr DN_Helper##name(Isolate* isolate, Thread* thread,           \
+                                   Zone* zone, NativeArguments* arguments);    \
+  ObjectPtr NATIVE_ENTRY_FUNCTION(name)(Thread * thread, Zone * zone,          \
+                                        NativeArguments * arguments) {         \
     TRACE_NATIVE_CALL("%s", "" #name);                                         \
     ASSERT(arguments->NativeArgCount() == argument_count);                     \
     /* Note: a longer type arguments vector may be passed */                   \
     ASSERT(arguments->NativeTypeArgCount() >= type_argument_count);            \
     return DN_Helper##name(thread->isolate(), thread, zone, arguments);        \
   }                                                                            \
-  static RawObject* DN_Helper##name(Isolate* isolate, Thread* thread,          \
-                                    Zone* zone, NativeArguments* arguments)
+  static ObjectPtr DN_Helper##name(Isolate* isolate, Thread* thread,           \
+                                   Zone* zone, NativeArguments* arguments)
 
 // Helpers that throw an argument exception.
 void DartNativeThrowTypeArgumentCountException(int num_type_args,
@@ -140,24 +140,24 @@
 
   MethodRecognizer::Kind kind() const;
   void set_kind(MethodRecognizer::Kind value) const;
-  static MethodRecognizer::Kind GetKind(RawTypedData* data);
+  static MethodRecognizer::Kind GetKind(TypedDataPtr data);
 
   NativeFunctionWrapper trampoline() const;
   void set_trampoline(NativeFunctionWrapper value) const;
-  static NativeFunctionWrapper GetTrampoline(RawTypedData* data);
+  static NativeFunctionWrapper GetTrampoline(TypedDataPtr data);
 
   NativeFunction native_function() const;
   void set_native_function(NativeFunction value) const;
-  static NativeFunction GetNativeFunction(RawTypedData* data);
+  static NativeFunction GetNativeFunction(TypedDataPtr data);
 
   intptr_t argc_tag() const;
   void set_argc_tag(intptr_t value) const;
-  static intptr_t GetArgcTag(RawTypedData* data);
+  static intptr_t GetArgcTag(TypedDataPtr data);
 
-  static RawTypedData* New(MethodRecognizer::Kind kind,
-                           NativeFunctionWrapper trampoline,
-                           NativeFunction native_function,
-                           intptr_t argc_tag);
+  static TypedDataPtr New(MethodRecognizer::Kind kind,
+                          NativeFunctionWrapper trampoline,
+                          NativeFunction native_function,
+                          intptr_t argc_tag);
 
  private:
   struct Payload {
@@ -167,7 +167,7 @@
     MethodRecognizer::Kind kind;
   };
 
-  static Payload* FromTypedArray(RawTypedData* data);
+  static Payload* FromTypedArray(TypedDataPtr data);
 
   const TypedData& data_;
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b51f1c1..7bac01c 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -13,17 +13,10 @@
 #include "vm/bootstrap.h"
 #include "vm/class_finalizer.h"
 #include "vm/code_comments.h"
+#include "vm/code_descriptors.h"
 #include "vm/code_observers.h"
-#include "vm/compiler/aot/precompiler.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
-#include "vm/compiler/compiler_state.h"
-#include "vm/compiler/frontend/bytecode_fingerprints.h"
-#include "vm/compiler/frontend/bytecode_reader.h"
-#include "vm/compiler/frontend/kernel_fingerprints.h"
-#include "vm/compiler/frontend/kernel_translation_helper.h"
-#include "vm/compiler/intrinsifier.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/cpu.h"
 #include "vm/dart.h"
@@ -40,6 +33,7 @@
 #include "vm/heap/become.h"
 #include "vm/heap/heap.h"
 #include "vm/heap/weak_code.h"
+#include "vm/image_snapshot.h"
 #include "vm/isolate_reload.h"
 #include "vm/kernel.h"
 #include "vm/kernel_binary.h"
@@ -63,6 +57,18 @@
 #include "vm/type_testing_stubs.h"
 #include "vm/zone_text_buffer.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/aot/precompiler.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/code_statistics.h"
+#include "vm/compiler/compiler_state.h"
+#include "vm/compiler/frontend/bytecode_fingerprints.h"
+#include "vm/compiler/frontend/bytecode_reader.h"
+#include "vm/compiler/frontend/kernel_fingerprints.h"
+#include "vm/compiler/frontend/kernel_translation_helper.h"
+#include "vm/compiler/intrinsifier.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DEFINE_FLAG(int,
@@ -101,9 +107,9 @@
 static const intptr_t kInitPrefixLength = strlen(kInitPrefix);
 
 // A cache of VM heap allocated preinitialized empty ic data entry arrays.
-RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount];
+ArrayPtr ICData::cached_icdata_arrays_[kCachedICDataArrayCount];
 // A VM heap allocated preinitialized empty subtype entry array.
-RawArray* SubtypeTestCache::cached_array_;
+ArrayPtr SubtypeTestCache::cached_array_;
 
 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {};
 
@@ -112,11 +118,11 @@
 #if defined(RAW_NULL)
 #error RAW_NULL should not be defined.
 #endif
-#define RAW_NULL kHeapObjectTag
+#define RAW_NULL static_cast<uword>(kHeapObjectTag)
 
 #define CHECK_ERROR(error)                                                     \
   {                                                                            \
-    RawError* err = (error);                                                   \
+    ErrorPtr err = (error);                                                    \
     if (err != Error::null()) {                                                \
       return err;                                                              \
     }                                                                          \
@@ -127,62 +133,50 @@
 SHARED_READONLY_HANDLES_LIST(DEFINE_SHARED_READONLY_HANDLE)
 #undef DEFINE_SHARED_READONLY_HANDLE
 
-RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL);
-RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::never_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::redirection_data_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::ffi_trampoline_data_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::field_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::script_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::library_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::kernel_program_info_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::instructions_section_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::code_source_map_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::compressed_stackmaps_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::var_descriptors_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::exception_handlers_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::dyncalltypecheck_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::singletargetcache_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::monomorphicsmiablecall_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::megamorphic_cache_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::subtypetestcache_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unhandled_exception_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::weak_serialization_reference_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
+ObjectPtr Object::null_ = static_cast<ObjectPtr>(RAW_NULL);
+BoolPtr Object::true_ = static_cast<BoolPtr>(RAW_NULL);
+BoolPtr Object::false_ = static_cast<BoolPtr>(RAW_NULL);
+ClassPtr Object::class_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::dynamic_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::void_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::type_arguments_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::patch_class_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::function_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::closure_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::signature_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::redirection_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::ffi_trampoline_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::field_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::script_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::library_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::namespace_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::kernel_program_info_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::code_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::bytecode_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::instructions_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::instructions_section_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::object_pool_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::pc_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::code_source_map_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::compressed_stackmaps_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::var_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::exception_handlers_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::context_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::context_scope_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::dyncalltypecheck_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::singletargetcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::unlinkedcall_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::monomorphicsmiablecall_class_ =
+    static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::icdata_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::megamorphic_cache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::subtypetestcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::api_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::language_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::unhandled_exception_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::unwind_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::weak_serialization_reference_class_ =
+    static_cast<ClassPtr>(RAW_NULL);
 
 const double MegamorphicCache::kLoadFactor = 0.50;
 
@@ -194,7 +188,7 @@
 }
 
 // Remove private keys, but retain getter/setter/constructor/mixin manglings.
-RawString* String::RemovePrivateKey(const String& name) {
+StringPtr String::RemovePrivateKey(const String& name) {
   ASSERT(name.IsOneByteString());
   GrowableArray<uint8_t> without_key(name.Length());
   intptr_t i = 0;
@@ -392,8 +386,8 @@
   return printer.buffer();
 }
 
-RawString* String::ScrubNameRetainPrivate(const String& name,
-                                          bool is_extension) {
+StringPtr String::ScrubNameRetainPrivate(const String& name,
+                                         bool is_extension) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   intptr_t len = name.Length();
   intptr_t start = 0;
@@ -519,7 +513,7 @@
   return '\0';
 }
 
-static RawBytecode* CreateVMInternalBytecode(KernelBytecode::Opcode opcode) {
+static BytecodePtr CreateVMInternalBytecode(KernelBytecode::Opcode opcode) {
   const KBCInstr* instructions = nullptr;
   intptr_t instructions_size = 0;
 
@@ -534,7 +528,7 @@
   return bytecode.raw();
 }
 
-void Object::InitNull(Isolate* isolate) {
+void Object::InitNullAndBool(Isolate* isolate) {
   // Should only be run by the vm isolate.
   ASSERT(isolate == Dart::vm_isolate());
 
@@ -548,10 +542,46 @@
   // clear the object.
   {
     uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld);
-    null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag);
+    null_ = static_cast<InstancePtr>(address + kHeapObjectTag);
     // The call below is using 'null_' to initialize itself.
     InitializeObject(address, kNullCid, Instance::InstanceSize());
   }
+
+  // Allocate and initialize the bool instances.
+  // These must be allocated such that at kBoolValueBitPosition, the address
+  // of true is 0 and the address of false is 1, and their addresses are
+  // otherwise identical.
+  {
+    // Allocate a dummy bool object to give true the desired alignment.
+    uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
+    InitializeObject(address, kBoolCid, Bool::InstanceSize());
+  }
+  {
+    // Allocate true.
+    uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
+    true_ = static_cast<BoolPtr>(address + kHeapObjectTag);
+    InitializeObject(address, kBoolCid, Bool::InstanceSize());
+    true_->ptr()->value_ = true;
+    true_->ptr()->SetCanonical();
+  }
+  {
+    // Allocate false.
+    uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
+    false_ = static_cast<BoolPtr>(address + kHeapObjectTag);
+    InitializeObject(address, kBoolCid, Bool::InstanceSize());
+    false_->ptr()->value_ = false;
+    false_->ptr()->SetCanonical();
+  }
+
+  // Check that the objects have been allocated at appropriate addresses.
+  ASSERT(static_cast<uword>(true_) ==
+         static_cast<uword>(null_) + kTrueOffsetFromNull);
+  ASSERT(static_cast<uword>(false_) ==
+         static_cast<uword>(null_) + kFalseOffsetFromNull);
+  ASSERT((static_cast<uword>(true_) & kBoolValueMask) == 0);
+  ASSERT((static_cast<uword>(false_) & kBoolValueMask) != 0);
+  ASSERT(static_cast<uword>(false_) ==
+         (static_cast<uword>(true_) | kBoolValueMask));
 }
 
 void Object::InitVtables() {
@@ -671,6 +701,8 @@
   *empty_type_arguments_ = TypeArguments::null();
   *null_abstract_type_ = AbstractType::null();
   *null_compressed_stack_maps_ = CompressedStackMaps::null();
+  *bool_true_ = true_;
+  *bool_false_ = false_;
 
   // Initialize the empty and zero array handles to null_ in order to be able to
   // check if the empty and zero arrays were allocated (RAW_NULL is not
@@ -684,7 +716,7 @@
   {
     intptr_t size = Class::InstanceSize();
     uword address = heap->Allocate(size, Heap::kOld);
-    class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag);
+    class_class_ = static_cast<ClassPtr>(address + kHeapObjectTag);
     InitializeObject(address, Class::kClassId, size);
 
     Class fake;
@@ -717,6 +749,14 @@
   cls.set_num_type_arguments(0);
   isolate->object_store()->set_null_class(cls);
 
+  // Allocate and initialize Never class.
+  cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
+  cls.set_num_type_arguments(0);
+  cls.set_is_finalized();
+  cls.set_is_declaration_loaded();
+  cls.set_is_type_finalized();
+  isolate->object_store()->set_never_class(cls);
+
   // Allocate and initialize the free list element class.
   cls =
       Class::New<FreeListElement::FakeInstance,
@@ -735,21 +775,21 @@
   cls.set_is_declaration_loaded();
   cls.set_is_type_finalized();
 
-  // Allocate and initialize the sentinel values of Null class.
+  // Allocate and initialize the sentinel values.
   {
     *sentinel_ ^=
-        Object::Allocate(kNullCid, Instance::InstanceSize(), Heap::kOld);
+        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
 
     *transition_sentinel_ ^=
-        Object::Allocate(kNullCid, Instance::InstanceSize(), Heap::kOld);
+        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
   }
 
   // Allocate and initialize optimizing compiler constants.
   {
     *unknown_constant_ ^=
-        Object::Allocate(kNullCid, Instance::InstanceSize(), Heap::kOld);
+        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
     *non_constant_ ^=
-        Object::Allocate(kNullCid, Instance::InstanceSize(), Heap::kOld);
+        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
   }
 
   // Allocate the remaining VM internal classes.
@@ -904,8 +944,8 @@
   {
     uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
     InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0));
-    Array::initializeHandle(
-        empty_array_, reinterpret_cast<RawArray*>(address + kHeapObjectTag));
+    Array::initializeHandle(empty_array_,
+                            static_cast<ArrayPtr>(address + kHeapObjectTag));
     empty_array_->StoreSmi(&empty_array_->raw_ptr()->length_, Smi::New(0));
     empty_array_->SetCanonical();
   }
@@ -915,8 +955,8 @@
   {
     uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
     InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1));
-    Array::initializeHandle(
-        zero_array_, reinterpret_cast<RawArray*>(address + kHeapObjectTag));
+    Array::initializeHandle(zero_array_,
+                            static_cast<ArrayPtr>(address + kHeapObjectTag));
     zero_array_->StoreSmi(&zero_array_->raw_ptr()->length_, Smi::New(1));
     smi = Smi::New(0);
     zero_array_->SetAt(0, smi);
@@ -929,7 +969,7 @@
     InitializeObject(address, kContextScopeCid, ContextScope::InstanceSize(0));
     ContextScope::initializeHandle(
         empty_context_scope_,
-        reinterpret_cast<RawContextScope*>(address + kHeapObjectTag));
+        static_cast<ContextScopePtr>(address + kHeapObjectTag));
     empty_context_scope_->StoreNonPointer(
         &empty_context_scope_->raw_ptr()->num_variables_, 0);
     empty_context_scope_->StoreNonPointer(
@@ -943,7 +983,7 @@
     InitializeObject(address, kObjectPoolCid, ObjectPool::InstanceSize(0));
     ObjectPool::initializeHandle(
         empty_object_pool_,
-        reinterpret_cast<RawObjectPool*>(address + kHeapObjectTag));
+        static_cast<ObjectPoolPtr>(address + kHeapObjectTag));
     empty_object_pool_->StoreNonPointer(&empty_object_pool_->raw_ptr()->length_,
                                         0);
     empty_object_pool_->SetCanonical();
@@ -956,7 +996,7 @@
                      PcDescriptors::InstanceSize(0));
     PcDescriptors::initializeHandle(
         empty_descriptors_,
-        reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag));
+        static_cast<PcDescriptorsPtr>(address + kHeapObjectTag));
     empty_descriptors_->StoreNonPointer(&empty_descriptors_->raw_ptr()->length_,
                                         0);
     empty_descriptors_->SetCanonical();
@@ -970,7 +1010,7 @@
                      LocalVarDescriptors::InstanceSize(0));
     LocalVarDescriptors::initializeHandle(
         empty_var_descriptors_,
-        reinterpret_cast<RawLocalVarDescriptors*>(address + kHeapObjectTag));
+        static_cast<LocalVarDescriptorsPtr>(address + kHeapObjectTag));
     empty_var_descriptors_->StoreNonPointer(
         &empty_var_descriptors_->raw_ptr()->num_entries_, 0);
     empty_var_descriptors_->SetCanonical();
@@ -986,7 +1026,7 @@
                      ExceptionHandlers::InstanceSize(0));
     ExceptionHandlers::initializeHandle(
         empty_exception_handlers_,
-        reinterpret_cast<RawExceptionHandlers*>(address + kHeapObjectTag));
+        static_cast<ExceptionHandlersPtr>(address + kHeapObjectTag));
     empty_exception_handlers_->StoreNonPointer(
         &empty_exception_handlers_->raw_ptr()->num_entries_, 0);
     empty_exception_handlers_->SetCanonical();
@@ -999,7 +1039,7 @@
                      TypeArguments::InstanceSize(0));
     TypeArguments::initializeHandle(
         empty_type_arguments_,
-        reinterpret_cast<RawTypeArguments*>(address + kHeapObjectTag));
+        static_cast<TypeArgumentsPtr>(address + kHeapObjectTag));
     empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->length_,
                                     Smi::New(0));
     empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->hash_,
@@ -1026,13 +1066,6 @@
   cls.set_is_type_finalized();
   void_class_ = cls.raw();
 
-  cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
-  cls.set_num_type_arguments(0);
-  cls.set_is_finalized();
-  cls.set_is_declaration_loaded();
-  cls.set_is_type_finalized();
-  never_class_ = cls.raw();
-
   cls = Class::New<Type, RTN::Type>(isolate);
   cls.set_is_finalized();
   cls.set_is_declaration_loaded();
@@ -1052,9 +1085,6 @@
   void_type_->ComputeHash();
   void_type_->SetCanonical();
 
-  cls = never_class_;
-  *never_type_ = Type::NewNonParameterizedType(cls);
-
   // Since TypeArguments objects are passed as function arguments, make them
   // behave as Dart instances, although they are just VM objects.
   // Note that we cannot set the super type to ObjectType, which does not live
@@ -1064,11 +1094,8 @@
   cls.SetFields(Object::empty_array());
   cls.SetFunctions(Object::empty_array());
 
-  // Allocate and initialize singleton true and false boolean objects.
   cls = Class::New<Bool, RTN::Bool>(isolate);
   isolate->object_store()->set_bool_class(cls);
-  *bool_true_ = Bool::New(true);
-  *bool_false_ = Bool::New(false);
 
   *smi_illegal_cid_ = Smi::New(kIllegalCid);
   *smi_zero_ = Smi::New(0);
@@ -1207,7 +1234,7 @@
 
 void Object::FinishInit(Isolate* isolate) {
   // The type testing stubs we initialize in AbstractType objects for the
-  // canonical type of kDynamicCid/kVoidCid/kNeverCid need to be set in this
+  // canonical type of kDynamicCid/kVoidCid need to be set in this
   // method, which is called after StubCode::InitOnce().
   Code& code = Code::Handle();
 
@@ -1216,52 +1243,50 @@
 
   code = TypeTestingStubGenerator::DefaultCodeForType(*void_type_);
   void_type_->SetTypeTestingStub(code);
-
-  code = TypeTestingStubGenerator::DefaultCodeForType(*never_type_);
-  never_type_->SetTypeTestingStub(code);
 }
 
 void Object::Cleanup() {
-  null_ = reinterpret_cast<RawObject*>(RAW_NULL);
-  class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  never_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  redirection_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  ffi_trampoline_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  field_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  script_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  library_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  kernel_program_info_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  instructions_section_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  code_source_map_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  compressed_stackmaps_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  var_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  exception_handlers_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  dyncalltypecheck_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  singletargetcache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  monomorphicsmiablecall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  megamorphic_cache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  subtypetestcache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  unhandled_exception_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
+  null_ = static_cast<ObjectPtr>(RAW_NULL);
+  true_ = static_cast<BoolPtr>(RAW_NULL);
+  false_ = static_cast<BoolPtr>(RAW_NULL);
+  class_class_ = static_cast<ClassPtr>(RAW_NULL);
+  dynamic_class_ = static_cast<ClassPtr>(RAW_NULL);
+  void_class_ = static_cast<ClassPtr>(RAW_NULL);
+  type_arguments_class_ = static_cast<ClassPtr>(RAW_NULL);
+  patch_class_class_ = static_cast<ClassPtr>(RAW_NULL);
+  function_class_ = static_cast<ClassPtr>(RAW_NULL);
+  closure_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+  signature_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+  redirection_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+  ffi_trampoline_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+  field_class_ = static_cast<ClassPtr>(RAW_NULL);
+  script_class_ = static_cast<ClassPtr>(RAW_NULL);
+  library_class_ = static_cast<ClassPtr>(RAW_NULL);
+  namespace_class_ = static_cast<ClassPtr>(RAW_NULL);
+  kernel_program_info_class_ = static_cast<ClassPtr>(RAW_NULL);
+  code_class_ = static_cast<ClassPtr>(RAW_NULL);
+  bytecode_class_ = static_cast<ClassPtr>(RAW_NULL);
+  instructions_class_ = static_cast<ClassPtr>(RAW_NULL);
+  instructions_section_class_ = static_cast<ClassPtr>(RAW_NULL);
+  object_pool_class_ = static_cast<ClassPtr>(RAW_NULL);
+  pc_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+  code_source_map_class_ = static_cast<ClassPtr>(RAW_NULL);
+  compressed_stackmaps_class_ = static_cast<ClassPtr>(RAW_NULL);
+  var_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+  exception_handlers_class_ = static_cast<ClassPtr>(RAW_NULL);
+  context_class_ = static_cast<ClassPtr>(RAW_NULL);
+  context_scope_class_ = static_cast<ClassPtr>(RAW_NULL);
+  dyncalltypecheck_class_ = static_cast<ClassPtr>(RAW_NULL);
+  singletargetcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+  unlinkedcall_class_ = static_cast<ClassPtr>(RAW_NULL);
+  monomorphicsmiablecall_class_ = static_cast<ClassPtr>(RAW_NULL);
+  icdata_class_ = static_cast<ClassPtr>(RAW_NULL);
+  megamorphic_cache_class_ = static_cast<ClassPtr>(RAW_NULL);
+  subtypetestcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+  api_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+  language_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+  unhandled_exception_class_ = static_cast<ClassPtr>(RAW_NULL);
+  unwind_error_class_ = static_cast<ClassPtr>(RAW_NULL);
 }
 
 // An object visitor which will mark all visited objects. This is used to
@@ -1277,13 +1302,13 @@
   {
   }
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     // Free list elements should never be marked.
-    ASSERT(!obj->IsMarked());
+    ASSERT(!obj->ptr()->IsMarked());
     // No forwarding corpses in the VM isolate.
     ASSERT(!obj->IsForwardingCorpse());
     if (!obj->IsFreeListElement()) {
-      obj->SetMarkBitUnsynchronized();
+      obj->ptr()->SetMarkBitUnsynchronized();
       Object::FinalizeReadOnlyObject(obj);
 #if defined(HASH_IN_OBJECT_HEADER)
       // These objects end up in the read-only VM isolate which is shared
@@ -1329,7 +1354,6 @@
   SET_CLASS_NAME(class, Class);
   SET_CLASS_NAME(dynamic, Dynamic);
   SET_CLASS_NAME(void, Void);
-  SET_CLASS_NAME(never, Never);
   SET_CLASS_NAME(type_arguments, TypeArguments);
   SET_CLASS_NAME(patch_class, PatchClass);
   SET_CLASS_NAME(function, Function);
@@ -1366,12 +1390,13 @@
   SET_CLASS_NAME(unhandled_exception, UnhandledException);
   SET_CLASS_NAME(unwind_error, UnwindError);
 
-  // Set up names for object array and one byte string class which are
-  // pre-allocated in the vm isolate also.
+  // Set up names for classes which are also pre-allocated in the vm isolate.
   cls = isolate->object_store()->array_class();
   cls.set_name(Symbols::_List());
   cls = isolate->object_store()->one_byte_string_class();
   cls.set_name(Symbols::OneByteString());
+  cls = isolate->object_store()->never_class();
+  cls.set_name(Symbols::Never());
 
   // Set up names for the pseudo-classes for free list elements and forwarding
   // corpses. Mainly this makes VM debugging easier.
@@ -1393,62 +1418,62 @@
   }
 }
 
-void Object::FinalizeReadOnlyObject(RawObject* object) {
+void Object::FinalizeReadOnlyObject(ObjectPtr object) {
   NoSafepointScope no_safepoint;
   intptr_t cid = object->GetClassId();
   if (cid == kOneByteStringCid) {
-    RawOneByteString* str = static_cast<RawOneByteString*>(object);
+    OneByteStringPtr str = static_cast<OneByteStringPtr>(object);
     if (String::GetCachedHash(str) == 0) {
       intptr_t hash = String::Hash(str);
       String::SetCachedHash(str, hash);
     }
     intptr_t size = OneByteString::UnroundedSize(str);
-    ASSERT(size <= str->HeapSize());
-    memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
-           str->HeapSize() - size);
+    ASSERT(size <= str->ptr()->HeapSize());
+    memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(str) + size), 0,
+           str->ptr()->HeapSize() - size);
   } else if (cid == kTwoByteStringCid) {
-    RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
+    TwoByteStringPtr str = static_cast<TwoByteStringPtr>(object);
     if (String::GetCachedHash(str) == 0) {
       intptr_t hash = String::Hash(str);
       String::SetCachedHash(str, hash);
     }
     ASSERT(String::GetCachedHash(str) != 0);
     intptr_t size = TwoByteString::UnroundedSize(str);
-    ASSERT(size <= str->HeapSize());
-    memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
-           str->HeapSize() - size);
+    ASSERT(size <= str->ptr()->HeapSize());
+    memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(str) + size), 0,
+           str->ptr()->HeapSize() - size);
   } else if (cid == kExternalOneByteStringCid) {
-    RawExternalOneByteString* str =
-        static_cast<RawExternalOneByteString*>(object);
+    ExternalOneByteStringPtr str =
+        static_cast<ExternalOneByteStringPtr>(object);
     if (String::GetCachedHash(str) == 0) {
       intptr_t hash = String::Hash(str);
       String::SetCachedHash(str, hash);
     }
   } else if (cid == kExternalTwoByteStringCid) {
-    RawExternalTwoByteString* str =
-        static_cast<RawExternalTwoByteString*>(object);
+    ExternalTwoByteStringPtr str =
+        static_cast<ExternalTwoByteStringPtr>(object);
     if (String::GetCachedHash(str) == 0) {
       intptr_t hash = String::Hash(str);
       String::SetCachedHash(str, hash);
     }
   } else if (cid == kCodeSourceMapCid) {
-    RawCodeSourceMap* map = CodeSourceMap::RawCast(object);
+    CodeSourceMapPtr map = CodeSourceMap::RawCast(object);
     intptr_t size = CodeSourceMap::UnroundedSize(map);
-    ASSERT(size <= map->HeapSize());
-    memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
-           map->HeapSize() - size);
+    ASSERT(size <= map->ptr()->HeapSize());
+    memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(map) + size), 0,
+           map->ptr()->HeapSize() - size);
   } else if (cid == kCompressedStackMapsCid) {
-    RawCompressedStackMaps* maps = CompressedStackMaps::RawCast(object);
+    CompressedStackMapsPtr maps = CompressedStackMaps::RawCast(object);
     intptr_t size = CompressedStackMaps::UnroundedSize(maps);
-    ASSERT(size <= maps->HeapSize());
-    memset(reinterpret_cast<void*>(RawObject::ToAddr(maps) + size), 0,
-           maps->HeapSize() - size);
+    ASSERT(size <= maps->ptr()->HeapSize());
+    memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(maps) + size), 0,
+           maps->ptr()->HeapSize() - size);
   } else if (cid == kPcDescriptorsCid) {
-    RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+    PcDescriptorsPtr desc = PcDescriptors::RawCast(object);
     intptr_t size = PcDescriptors::UnroundedSize(desc);
-    ASSERT(size <= desc->HeapSize());
-    memset(reinterpret_cast<void*>(RawObject::ToAddr(desc) + size), 0,
-           desc->HeapSize() - size);
+    ASSERT(size <= desc->ptr()->HeapSize());
+    memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(desc) + size), 0,
+           desc->ptr()->HeapSize() - size);
   }
 }
 
@@ -1470,18 +1495,19 @@
   if (original_size > used_size) {
     intptr_t leftover_size = original_size - used_size;
 
-    uword addr = RawObject::ToAddr(obj.raw()) + used_size;
+    uword addr = ObjectLayout::ToAddr(obj.raw()) + used_size;
     if (leftover_size >= TypedData::InstanceSize(0)) {
       // Update the leftover space as a TypedDataInt8Array object.
-      RawTypedData* raw =
-          reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
-      uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
-      new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
+      TypedDataPtr raw =
+          static_cast<TypedDataPtr>(ObjectLayout::FromAddr(addr));
+      uword new_tags =
+          ObjectLayout::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
+      new_tags = ObjectLayout::SizeTag::update(leftover_size, new_tags);
       const bool is_old = obj.raw()->IsOldObject();
-      new_tags = RawObject::OldBit::update(is_old, new_tags);
-      new_tags = RawObject::OldAndNotMarkedBit::update(is_old, new_tags);
-      new_tags = RawObject::OldAndNotRememberedBit::update(is_old, new_tags);
-      new_tags = RawObject::NewBit::update(!is_old, new_tags);
+      new_tags = ObjectLayout::OldBit::update(is_old, new_tags);
+      new_tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, new_tags);
+      new_tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, new_tags);
+      new_tags = ObjectLayout::NewBit::update(!is_old, new_tags);
       // On architectures with a relaxed memory model, the concurrent marker may
       // observe the write of the filler object's header before observing the
       // new array length, and so treat it as a pointer. Ensure it is a Smi so
@@ -1498,19 +1524,19 @@
 
       intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
       ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
-      raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
-      raw->RecomputeDataField();
+      raw->ptr()->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
+      raw->ptr()->RecomputeDataField();
     } else {
       // Update the leftover space as a basic object.
       ASSERT(leftover_size == Object::InstanceSize());
-      RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
-      uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0);
-      new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
+      ObjectPtr raw = static_cast<ObjectPtr>(ObjectLayout::FromAddr(addr));
+      uword new_tags = ObjectLayout::ClassIdTag::update(kInstanceCid, 0);
+      new_tags = ObjectLayout::SizeTag::update(leftover_size, new_tags);
       const bool is_old = obj.raw()->IsOldObject();
-      new_tags = RawObject::OldBit::update(is_old, new_tags);
-      new_tags = RawObject::OldAndNotMarkedBit::update(is_old, new_tags);
-      new_tags = RawObject::OldAndNotRememberedBit::update(is_old, new_tags);
-      new_tags = RawObject::NewBit::update(!is_old, new_tags);
+      new_tags = ObjectLayout::OldBit::update(is_old, new_tags);
+      new_tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, new_tags);
+      new_tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, new_tags);
+      new_tags = ObjectLayout::NewBit::update(!is_old, new_tags);
       // On architectures with a relaxed memory model, the concurrent marker may
       // observe the write of the filler object's header before observing the
       // new array length, and so treat it as a pointer. Ensure it is a Smi so
@@ -1572,9 +1598,9 @@
 //
 // A non-NULL kernel argument indicates (1).
 // A NULL kernel indicates (2) or (3).
-RawError* Object::Init(Isolate* isolate,
-                       const uint8_t* kernel_buffer,
-                       intptr_t kernel_buffer_size) {
+ErrorPtr Object::Init(Isolate* isolate,
+                      const uint8_t* kernel_buffer,
+                      intptr_t kernel_buffer_size) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(isolate == thread->isolate());
@@ -1592,6 +1618,8 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
     // Object::Init version when we are bootstrapping from source or from a
     // Kernel binary.
+    // This will initialize isolate group object_store, shared by all isolates
+    // running in the isolate group.
     ObjectStore* object_store = isolate->object_store();
 
     Class& cls = Class::Handle(zone);
@@ -1603,6 +1631,7 @@
     // All RawArray fields will be initialized to an empty array, therefore
     // initialize array class first.
     cls = Class::New<Array, RTN::Array>(isolate);
+    ASSERT(object_store->array_class() == Class::null());
     object_store->set_array_class(cls);
 
     // VM classes that are parameterized (Array, ImmutableArray,
@@ -1684,10 +1713,9 @@
     // declared number of type parameters is still 0. It will become 1 after
     // patching. The array type allocated below represents the raw type _List
     // and not _List<E> as we could expect. Use with caution.
-    type = Type::New(Class::Handle(zone, cls.raw()),
-                     TypeArguments::Handle(zone), TokenPosition::kNoSource,
-                     Dart::non_nullable_flag() ? Nullability::kNonNullable
-                                               : Nullability::kLegacy);
+    type =
+        Type::New(Class::Handle(zone, cls.raw()), TypeArguments::Handle(zone),
+                  TokenPosition::kNoSource, Nullability::kNonNullable);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
     object_store->set_array_type(type);
@@ -1805,6 +1833,14 @@
     RegisterClass(cls, Symbols::Null(), core_lib);
     pending_classes.Add(cls);
 
+    cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
+    cls.set_num_type_arguments(0);
+    cls.set_is_finalized();
+    cls.set_is_declaration_loaded();
+    cls.set_is_type_finalized();
+    cls.set_name(Symbols::Never());
+    object_store->set_never_class(cls);
+
     ASSERT(!library_prefix_cls.IsNull());
     RegisterPrivateClass(library_prefix_cls, Symbols::_LibraryPrefix(),
                          core_lib);
@@ -2068,6 +2104,8 @@
     object_store->set_legacy_int_type(type);
     type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
     object_store->set_non_nullable_int_type(type);
+    type = type.ToNullability(Nullability::kNullable, Heap::kOld);
+    object_store->set_nullable_int_type(type);
 
     cls = Class::New<Instance, RTN::Instance>(kIllegalCid, isolate,
                                               /*register_class=*/true,
@@ -2082,6 +2120,8 @@
     object_store->set_legacy_double_type(type);
     type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
     object_store->set_non_nullable_double_type(type);
+    type = type.ToNullability(Nullability::kNullable, Heap::kOld);
+    object_store->set_nullable_double_type(type);
 
     name = Symbols::_String().raw();
     cls = Class::New<Instance, RTN::Instance>(kIllegalCid, isolate,
@@ -2140,6 +2180,13 @@
     type = object_store->object_type();
     cls.set_super_type(type);
 
+    cls = object_store->never_class();
+    type = Type::New(cls, Object::null_type_arguments(),
+                     TokenPosition::kNoSource, Nullability::kNonNullable);
+    type.SetIsFinalized();
+    type ^= type.Canonicalize();
+    object_store->set_never_type(type);
+
     // Create and cache commonly used type arguments <int>, <double>,
     // <String>, <String, dynamic> and <String, String>.
     type_args = TypeArguments::New(1);
@@ -2437,6 +2484,9 @@
     cls = Class::New<Instance, RTN::Instance>(kNullCid, isolate);
     object_store->set_null_class(cls);
 
+    cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
+    object_store->set_never_class(cls);
+
     cls = Class::New<Capability, RTN::Capability>(isolate);
     cls = Class::New<ReceivePort, RTN::ReceivePort>(isolate);
     cls = Class::New<SendPort, RTN::SendPort>(isolate);
@@ -2458,16 +2508,16 @@
 
 #if defined(DEBUG)
 bool Object::InVMIsolateHeap() const {
-  if (FLAG_verify_handles && raw()->InVMIsolateHeap()) {
+  if (FLAG_verify_handles && raw()->ptr()->InVMIsolateHeap()) {
     Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
-    uword addr = RawObject::ToAddr(raw());
+    uword addr = ObjectLayout::ToAddr(raw());
     if (!vm_isolate_heap->Contains(addr)) {
       ASSERT(FLAG_write_protect_code);
-      addr = RawObject::ToAddr(HeapPage::ToWritable(raw()));
+      addr = ObjectLayout::ToAddr(HeapPage::ToWritable(raw()));
       ASSERT(vm_isolate_heap->Contains(addr));
     }
   }
-  return raw()->InVMIsolateHeap();
+  return raw()->ptr()->InVMIsolateHeap();
 }
 #endif  // DEBUG
 
@@ -2475,7 +2525,7 @@
   THR_Print("%s\n", ToCString());
 }
 
-RawString* Object::DictionaryName() const {
+StringPtr Object::DictionaryName() const {
   return String::null();
 }
 
@@ -2484,11 +2534,10 @@
   // an 8-byte write from the this loop, but doesn't overwrite that entry with
   // the 4-byte relaxed store of the header below, then reports false data races
   // based on the record of the 8-byte write.
-  uword cur = address + sizeof(RawObject);
+  uword cur = address + sizeof(ObjectLayout);
   uword end = address + size;
   if (class_id == kInstructionsCid) {
-    compiler::target::uword initial_value =
-        compiler::Assembler::GetBreakInstructionFiller();
+    compiler::target::uword initial_value = kBreakInstructionFiller;
     while (cur < end) {
       *reinterpret_cast<compiler::target::uword*>(cur) = initial_value;
       cur += compiler::target::kWordSize;
@@ -2496,7 +2545,7 @@
   } else {
     uword initial_value;
     bool needs_init;
-    if (RawObject::IsTypedDataBaseClassId(class_id)) {
+    if (IsTypedDataBaseClassId(class_id)) {
       initial_value = 0;
       // If the size is greater than both kNewAllocatableSize and
       // kAllocatablePageSize, the object must have been allocated to a new
@@ -2504,7 +2553,7 @@
       needs_init = Heap::IsAllocatableInNewSpace(size) ||
                    Heap::IsAllocatableViaFreeLists(size);
     } else {
-      initial_value = reinterpret_cast<uword>(null_);
+      initial_value = static_cast<uword>(null_);
       needs_init = true;
     }
     if (needs_init) {
@@ -2525,17 +2574,17 @@
   }
   uint32_t tags = 0;
   ASSERT(class_id != kIllegalCid);
-  tags = RawObject::ClassIdTag::update(class_id, tags);
-  tags = RawObject::SizeTag::update(size, tags);
+  tags = ObjectLayout::ClassIdTag::update(class_id, tags);
+  tags = ObjectLayout::SizeTag::update(size, tags);
   const bool is_old =
       (address & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
-  tags = RawObject::OldBit::update(is_old, tags);
-  tags = RawObject::OldAndNotMarkedBit::update(is_old, tags);
-  tags = RawObject::OldAndNotRememberedBit::update(is_old, tags);
-  tags = RawObject::NewBit::update(!is_old, tags);
-  reinterpret_cast<RawObject*>(address)->tags_ = tags;
+  tags = ObjectLayout::OldBit::update(is_old, tags);
+  tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, tags);
+  tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, tags);
+  tags = ObjectLayout::NewBit::update(!is_old, tags);
+  reinterpret_cast<ObjectLayout*>(address)->tags_ = tags;
 #if defined(HASH_IN_OBJECT_HEADER)
-  reinterpret_cast<RawObject*>(address)->hash_ = 0;
+  reinterpret_cast<ObjectLayout*>(address)->hash_ = 0;
 #endif
 }
 
@@ -2549,19 +2598,22 @@
     ASSERT(vtable() == builtin_vtables_[cid]);
     if (FLAG_verify_handles && raw_->IsHeapObject()) {
       Heap* isolate_heap = IsolateGroup::Current()->heap();
-      Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
-      uword addr = RawObject::ToAddr(raw_);
-      if (!isolate_heap->Contains(addr) && !vm_isolate_heap->Contains(addr)) {
-        ASSERT(FLAG_write_protect_code);
-        addr = RawObject::ToAddr(HeapPage::ToWritable(raw_));
-        ASSERT(isolate_heap->Contains(addr) || vm_isolate_heap->Contains(addr));
+      if (!isolate_heap->new_space()->scavenging()) {
+        Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
+        uword addr = ObjectLayout::ToAddr(raw_);
+        if (!isolate_heap->Contains(addr) && !vm_isolate_heap->Contains(addr)) {
+          ASSERT(FLAG_write_protect_code);
+          addr = ObjectLayout::ToAddr(HeapPage::ToWritable(raw_));
+          ASSERT(isolate_heap->Contains(addr) ||
+                 vm_isolate_heap->Contains(addr));
+        }
       }
     }
   }
 #endif
 }
 
-RawObject* 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) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
   Thread* thread = Thread::Current();
   ASSERT(thread->execution_state() == Thread::kThreadInVM);
@@ -2584,21 +2636,21 @@
     }
   }
 #ifndef PRODUCT
-  auto class_table = thread->isolate_group()->class_table();
+  auto class_table = thread->isolate_group()->shared_class_table();
   if (class_table->TraceAllocationFor(cls_id)) {
     Profiler::SampleAllocation(thread, cls_id);
   }
 #endif  // !PRODUCT
   NoSafepointScope no_safepoint;
   InitializeObject(address, cls_id, size);
-  RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
-  ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_));
+  ObjectPtr raw_obj = static_cast<ObjectPtr>(address + kHeapObjectTag);
+  ASSERT(cls_id == ObjectLayout::ClassIdTag::decode(raw_obj->ptr()->tags_));
   if (raw_obj->IsOldObject() && UNLIKELY(thread->is_marking())) {
     // Black allocation. Prevents a data race between the mutator and concurrent
     // marker on ARM and ARM64 (the marker may observe a publishing store of
     // this object before the stores that initialize its slots), and helps the
     // collection to finish sooner.
-    raw_obj->SetMarkBitUnsynchronized();
+    raw_obj->ptr()->SetMarkBitUnsynchronized();
     // Setting the mark bit must not be ordered after a publishing store of this
     // object. Adding a barrier here is cheaper than making every store into the
     // heap a store-release. Compare Scavenger::ScavengePointer.
@@ -2610,26 +2662,26 @@
 
 class WriteBarrierUpdateVisitor : public ObjectPointerVisitor {
  public:
-  explicit WriteBarrierUpdateVisitor(Thread* thread, RawObject* obj)
+  explicit WriteBarrierUpdateVisitor(Thread* thread, ObjectPtr obj)
       : ObjectPointerVisitor(thread->isolate()->group()),
         thread_(thread),
         old_obj_(obj) {
     ASSERT(old_obj_->IsOldObject());
   }
 
-  void VisitPointers(RawObject** from, RawObject** to) {
+  void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
     if (old_obj_->IsArray()) {
-      for (RawObject** slot = from; slot <= to; ++slot) {
-        RawObject* value = *slot;
+      for (ObjectPtr* slot = from; slot <= to; ++slot) {
+        ObjectPtr value = *slot;
         if (value->IsHeapObject()) {
-          old_obj_->CheckArrayPointerStore(slot, value, thread_);
+          old_obj_->ptr()->CheckArrayPointerStore(slot, value, thread_);
         }
       }
     } else {
-      for (RawObject** slot = from; slot <= to; ++slot) {
-        RawObject* value = *slot;
+      for (ObjectPtr* slot = from; slot <= to; ++slot) {
+        ObjectPtr value = *slot;
         if (value->IsHeapObject()) {
-          old_obj_->CheckHeapPointerStore(value, thread_);
+          old_obj_->ptr()->CheckHeapPointerStore(value, thread_);
         }
       }
     }
@@ -2637,7 +2689,7 @@
 
  private:
   Thread* thread_;
-  RawObject* old_obj_;
+  ObjectPtr old_obj_;
 
   DISALLOW_COPY_AND_ASSIGN(WriteBarrierUpdateVisitor);
 };
@@ -2650,15 +2702,15 @@
   return (IsZoneHandle() || IsReadOnlyHandle());
 }
 
-RawObject* Object::Clone(const Object& orig, Heap::Space space) {
+ObjectPtr Object::Clone(const Object& orig, Heap::Space space) {
   const Class& cls = Class::Handle(orig.clazz());
-  intptr_t size = orig.raw()->HeapSize();
-  RawObject* raw_clone = Object::Allocate(cls.id(), size, space);
+  intptr_t size = orig.raw()->ptr()->HeapSize();
+  ObjectPtr raw_clone = Object::Allocate(cls.id(), size, space);
   NoSafepointScope no_safepoint;
   // Copy the body of the original into the clone.
-  uword orig_addr = RawObject::ToAddr(orig.raw());
-  uword clone_addr = RawObject::ToAddr(raw_clone);
-  static const intptr_t kHeaderSizeInBytes = sizeof(RawObject);
+  uword orig_addr = ObjectLayout::ToAddr(orig.raw());
+  uword clone_addr = ObjectLayout::ToAddr(raw_clone);
+  static const intptr_t kHeaderSizeInBytes = sizeof(ObjectLayout);
   memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes),
           reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes),
           size - kHeaderSizeInBytes);
@@ -2669,15 +2721,15 @@
     return raw_clone;
   }
   WriteBarrierUpdateVisitor visitor(Thread::Current(), raw_clone);
-  raw_clone->VisitPointers(&visitor);
+  raw_clone->ptr()->VisitPointers(&visitor);
   return raw_clone;
 }
 
-RawString* Class::Name() const {
+StringPtr Class::Name() const {
   return raw_ptr()->name_;
 }
 
-RawString* Class::ScrubbedName() const {
+StringPtr Class::ScrubbedName() const {
   return Symbols::New(Thread::Current(), ScrubbedNameCString());
 }
 
@@ -2685,7 +2737,7 @@
   return String::ScrubName(String::Handle(Name()));
 }
 
-RawString* Class::UserVisibleName() const {
+StringPtr Class::UserVisibleName() const {
 #if !defined(PRODUCT)
   ASSERT(raw_ptr()->user_name_ != String::null());
   return raw_ptr()->user_name_;
@@ -2702,7 +2754,7 @@
   return GenerateUserVisibleName();  // No caching in PRODUCT, regenerate.
 }
 
-RawClass* Class::Mixin() const {
+ClassPtr Class::Mixin() const {
   if (is_transformed_mixin_application()) {
     const Array& interfaces = Array::Handle(this->interfaces());
     const Type& mixin_type =
@@ -2718,28 +2770,27 @@
 
 bool Class::IsInFullSnapshot() const {
   NoSafepointScope no_safepoint;
-  return RawLibrary::InFullSnapshotBit::decode(
+  return LibraryLayout::InFullSnapshotBit::decode(
       raw_ptr()->library_->ptr()->flags_);
 }
 
-RawAbstractType* Class::RareType() const {
+AbstractTypePtr Class::RareType() const {
   if (!IsGeneric() && !IsClosureClass() && !IsTypedefClass()) {
     return DeclarationType();
   }
   ASSERT(is_declaration_loaded());
   const Type& type = Type::Handle(
       Type::New(*this, Object::null_type_arguments(), TokenPosition::kNoSource,
-                Dart::non_nullable_flag() ? Nullability::kNonNullable
-                                          : Nullability::kLegacy));
+                Nullability::kNonNullable));
   return ClassFinalizer::FinalizeType(*this, type);
 }
 
 template <class FakeObject, class TargetFakeObject>
-RawClass* Class::New(Isolate* isolate, bool register_class) {
+ClassPtr Class::New(Isolate* isolate, bool register_class) {
   ASSERT(Object::class_class() != Class::null());
   Class& result = Class::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -2816,12 +2867,11 @@
                Object::empty_array().raw());
 }
 
-RawArray* Class::OffsetToFieldMap(bool original_classes) const {
-  Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_);
-  if (array.IsNull()) {
+ArrayPtr Class::OffsetToFieldMap(bool original_classes) const {
+  if (raw_ptr()->offset_in_words_to_field_ == Array::null()) {
     ASSERT(is_finalized());
     const intptr_t length = raw_ptr()->host_instance_size_in_words_;
-    array = Array::New(length, Heap::kOld);
+    const Array& array = Array::Handle(Array::New(length, Heap::kOld));
     Class& cls = Class::Handle(this->raw());
     Array& fields = Array::Handle();
     Field& f = Field::Handle();
@@ -2837,7 +2887,7 @@
     }
     StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw());
   }
-  return array.raw();
+  return raw_ptr()->offset_in_words_to_field_;
 }
 
 bool Class::HasInstanceFields() const {
@@ -2946,7 +2996,7 @@
   }
 }
 
-RawFunction* Class::FunctionFromIndex(intptr_t idx) const {
+FunctionPtr Class::FunctionFromIndex(intptr_t idx) const {
   const Array& funcs = Array::Handle(functions());
   if ((idx < 0) || (idx >= funcs.Length())) {
     return Function::null();
@@ -2957,7 +3007,7 @@
   return func.raw();
 }
 
-RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const {
+FunctionPtr Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const {
   const Array& funcs = Array::Handle(functions());
   if ((idx < 0) || (idx >= funcs.Length())) {
     return Function::null();
@@ -3029,7 +3079,7 @@
   return -1;
 }
 
-RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
+FunctionPtr Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
   Thread* thread = Thread::Current();
   REUSABLE_ARRAY_HANDLESCOPE(thread);
   REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -3164,7 +3214,7 @@
   return num_type_args;
 }
 
-RawClass* Class::SuperClass(bool original_classes) const {
+ClassPtr Class::SuperClass(bool original_classes) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -3189,7 +3239,7 @@
   StorePointer(&raw_ptr()->super_type_, value.raw());
 }
 
-RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const {
+TypeParameterPtr Class::LookupTypeParameter(const String& type_name) const {
   ASSERT(!type_name.IsNull());
   Thread* thread = Thread::Current();
   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
@@ -3241,9 +3291,10 @@
     set_num_native_fields(super.num_native_fields());
 
     if (FLAG_precompiled_mode) {
-      host_bitmap =
-          Isolate::Current()->group()->class_table()->GetUnboxedFieldsMapAt(
-              super.id());
+      host_bitmap = Isolate::Current()
+                        ->group()
+                        ->shared_class_table()
+                        ->GetUnboxedFieldsMapAt(super.id());
     }
   }
   // If the super class is parameterized, use the same type_arguments field,
@@ -3282,17 +3333,17 @@
         intptr_t field_size;
         switch (field.guarded_cid()) {
           case kDoubleCid:
-            field_size = sizeof(RawDouble::value_);
+            field_size = sizeof(DoubleLayout::value_);
             break;
           case kFloat32x4Cid:
-            field_size = sizeof(RawFloat32x4::value_);
+            field_size = sizeof(Float32x4Layout::value_);
             break;
           case kFloat64x2Cid:
-            field_size = sizeof(RawFloat64x2::value_);
+            field_size = sizeof(Float64x2Layout::value_);
             break;
           default:
             if (field.is_non_nullable_integer()) {
-              field_size = sizeof(RawMint::value_);
+              field_size = sizeof(MintLayout::value_);
             } else {
               UNREACHABLE();
               field_size = 0;
@@ -3366,13 +3417,13 @@
   entry.Set<Class::kInvocationDispatcherFunction>(dispatcher);
 }
 
-RawFunction* Class::GetInvocationDispatcher(const String& target_name,
-                                            const Array& args_desc,
-                                            RawFunction::Kind kind,
-                                            bool create_if_absent) const {
-  ASSERT(kind == RawFunction::kNoSuchMethodDispatcher ||
-         kind == RawFunction::kInvokeFieldDispatcher ||
-         kind == RawFunction::kDynamicInvocationForwarder);
+FunctionPtr Class::GetInvocationDispatcher(const String& target_name,
+                                           const Array& args_desc,
+                                           FunctionLayout::Kind kind,
+                                           bool create_if_absent) const {
+  ASSERT(kind == FunctionLayout::kNoSuchMethodDispatcher ||
+         kind == FunctionLayout::kInvokeFieldDispatcher ||
+         kind == FunctionLayout::kDynamicInvocationForwarder);
   auto Z = Thread::Current()->zone();
   auto& function = Function::Handle(Z);
   auto& name = String::Handle(Z);
@@ -3400,9 +3451,9 @@
   return function.raw();
 }
 
-RawFunction* Class::CreateInvocationDispatcher(const String& target_name,
-                                               const Array& args_desc,
-                                               RawFunction::Kind kind) const {
+FunctionPtr Class::CreateInvocationDispatcher(const String& target_name,
+                                              const Array& args_desc,
+                                              FunctionLayout::Kind kind) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Function& invocation = Function::Handle(
@@ -3465,7 +3516,7 @@
 // does not have a getter called M but has a method called M then an extractor
 // is created and injected as a getter (under the name get:M) into the class
 // owning method M.
-RawFunction* Function::CreateMethodExtractor(const String& getter_name) const {
+FunctionPtr Function::CreateMethodExtractor(const String& getter_name) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(Field::IsGetterName(getter_name));
@@ -3476,7 +3527,7 @@
   Function& extractor = Function::Handle(
       zone,
       Function::New(String::Handle(zone, Symbols::New(thread, getter_name)),
-                    RawFunction::kMethodExtractor,
+                    FunctionLayout::kMethodExtractor,
                     false,  // Not static.
                     false,  // Not const.
                     is_abstract(),
@@ -3503,7 +3554,7 @@
   return extractor.raw();
 }
 
-RawFunction* Function::GetMethodExtractor(const String& getter_name) const {
+FunctionPtr Function::GetMethodExtractor(const String& getter_name) const {
   ASSERT(Field::IsGetterName(getter_name));
   const Function& closure_function =
       Function::Handle(ImplicitClosureFunction());
@@ -3512,7 +3563,7 @@
   if (result.IsNull()) {
     result = CreateMethodExtractor(getter_name);
   }
-  ASSERT(result.kind() == RawFunction::kMethodExtractor);
+  ASSERT(result.kind() == FunctionLayout::kMethodExtractor);
   return result.raw();
 }
 
@@ -3583,8 +3634,7 @@
   return name.StartsWith(Symbols::DynamicPrefix());
 }
 
-RawString* Function::DemangleDynamicInvocationForwarderName(
-    const String& name) {
+StringPtr Function::DemangleDynamicInvocationForwarderName(const String& name) {
   const intptr_t kDynamicPrefixLength = 4;  // "dyn:"
   ASSERT(Symbols::DynamicPrefix().Length() == kDynamicPrefixLength);
   return Symbols::New(Thread::Current(), name, kDynamicPrefixLength,
@@ -3592,7 +3642,7 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawFunction* Function::CreateDynamicInvocationForwarder(
+FunctionPtr Function::CreateDynamicInvocationForwarder(
     const String& mangled_name) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -3606,7 +3656,7 @@
   forwarder.set_is_native(false);
   // TODO(dartbug.com/37737): Currently, we intentionally keep the recognized
   // kind when creating the dynamic invocation forwarder.
-  forwarder.set_kind(RawFunction::kDynamicInvocationForwarder);
+  forwarder.set_kind(FunctionLayout::kDynamicInvocationForwarder);
   forwarder.set_is_debuggable(false);
 
   // TODO(vegorov) for error reporting reasons it is better to make this
@@ -3633,18 +3683,18 @@
   return forwarder.raw();
 }
 
-RawString* Function::CreateDynamicInvocationForwarderName(const String& name) {
+StringPtr Function::CreateDynamicInvocationForwarderName(const String& name) {
   return Symbols::FromConcat(Thread::Current(), Symbols::DynamicPrefix(), name);
 }
 
-RawFunction* Function::GetDynamicInvocationForwarder(
+FunctionPtr Function::GetDynamicInvocationForwarder(
     const String& mangled_name,
     bool allow_add /* = true */) const {
   ASSERT(IsDynamicInvocationForwarderName(mangled_name));
   const Class& owner = Class::Handle(Owner());
   Function& result = Function::Handle(owner.GetInvocationDispatcher(
       mangled_name, Array::null_array(),
-      RawFunction::kDynamicInvocationForwarder, /*create_if_absent=*/false));
+      FunctionLayout::kDynamicInvocationForwarder, /*create_if_absent=*/false));
 
   if (!result.IsNull()) {
     return result.raw();
@@ -3682,7 +3732,7 @@
   return subtype->IsSubtypeOf(*supertype, Heap::kOld);
 }
 
-RawArray* Class::invocation_dispatcher_cache() const {
+ArrayPtr Class::invocation_dispatcher_cache() const {
   return raw_ptr()->invocation_dispatcher_cache_;
 }
 
@@ -3706,8 +3756,8 @@
       // Sets the new size in the class table.
       isolate->class_table()->SetAt(id(), raw());
       if (FLAG_precompiled_mode) {
-        isolate->group()->class_table()->SetUnboxedFieldsMapAt(id(),
-                                                               host_bitmap);
+        isolate->group()->shared_class_table()->SetUnboxedFieldsMapAt(
+            id(), host_bitmap);
       }
     }
   }
@@ -3802,7 +3852,7 @@
 
 bool Class::TraceAllocation(Isolate* isolate) const {
 #ifndef PRODUCT
-  auto class_table = isolate->group()->class_table();
+  auto class_table = isolate->group()->shared_class_table();
   return class_table->TraceAllocationFor(id());
 #else
   return false;
@@ -3814,7 +3864,7 @@
   Isolate* isolate = Isolate::Current();
   const bool changed = trace_allocation != this->TraceAllocation(isolate);
   if (changed) {
-    auto class_table = isolate->group()->class_table();
+    auto class_table = isolate->group()->shared_class_table();
     class_table->SetTraceAllocationFor(id(), trace_allocation);
     DisableAllocationStub();
   }
@@ -3832,12 +3882,12 @@
 //   i.e., klass.RareType().
 // * For throwing a NSM in a library, we just pass the null instance as
 //   receiver.
-static RawObject* ThrowNoSuchMethod(const Instance& receiver,
-                                    const String& function_name,
-                                    const Array& arguments,
-                                    const Array& argument_names,
-                                    const InvocationMirror::Level level,
-                                    const InvocationMirror::Kind kind) {
+static ObjectPtr ThrowNoSuchMethod(const Instance& receiver,
+                                   const String& function_name,
+                                   const Array& arguments,
+                                   const Array& argument_names,
+                                   const InvocationMirror::Level level,
+                                   const InvocationMirror::Kind kind) {
   const Smi& invocation_type =
       Smi::Handle(Smi::New(InvocationMirror::EncodeType(level, kind)));
 
@@ -3858,10 +3908,10 @@
   return DartEntry::InvokeFunction(throwNew, args);
 }
 
-static RawObject* ThrowTypeError(const TokenPosition token_pos,
-                                 const Instance& src_value,
-                                 const AbstractType& dst_type,
-                                 const String& dst_name) {
+static ObjectPtr ThrowTypeError(const TokenPosition token_pos,
+                                const Instance& src_value,
+                                const AbstractType& dst_type,
+                                const String& dst_name) {
   const Array& args = Array::Handle(Array::New(4));
   const Smi& pos = Smi::Handle(Smi::New(token_pos.value()));
   args.SetAt(0, pos);
@@ -3877,10 +3927,10 @@
   return DartEntry::InvokeFunction(throwNew, args);
 }
 
-RawObject* Class::InvokeGetter(const String& getter_name,
-                               bool throw_nsm_if_absent,
-                               bool respect_reflectable,
-                               bool check_is_entrypoint) const {
+ObjectPtr Class::InvokeGetter(const String& getter_name,
+                              bool throw_nsm_if_absent,
+                              bool respect_reflectable,
+                              bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -3937,10 +3987,10 @@
   return field.StaticValue();
 }
 
-RawObject* Class::InvokeSetter(const String& setter_name,
-                               const Instance& value,
-                               bool respect_reflectable,
-                               bool check_is_entrypoint) const {
+ObjectPtr Class::InvokeSetter(const String& setter_name,
+                              const Instance& value,
+                              bool respect_reflectable,
+                              bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -4006,11 +4056,11 @@
   return value.raw();
 }
 
-RawObject* Class::Invoke(const String& function_name,
-                         const Array& args,
-                         const Array& arg_names,
-                         bool respect_reflectable,
-                         bool check_is_entrypoint) const {
+ObjectPtr Class::Invoke(const String& function_name,
+                        const Array& args,
+                        const Array& arg_names,
+                        bool respect_reflectable,
+                        bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -4061,7 +4111,7 @@
         AbstractType::Handle(zone, RareType()), function_name, args, arg_names,
         InvocationMirror::kStatic, InvocationMirror::kMethod);
   }
-  RawObject* type_error =
+  ObjectPtr type_error =
       function.DoArgumentTypesMatch(args, args_descriptor, type_args);
   if (type_error != Error::null()) {
     return type_error;
@@ -4069,7 +4119,7 @@
   return DartEntry::InvokeFunction(function, args, args_descriptor_array);
 }
 
-static RawObject* EvaluateCompiledExpressionHelper(
+static ObjectPtr EvaluateCompiledExpressionHelper(
     const ExternalTypedData& kernel_buffer,
     const Array& type_definitions,
     const String& library_url,
@@ -4077,7 +4127,7 @@
     const Array& arguments,
     const TypeArguments& type_arguments);
 
-RawObject* Class::EvaluateCompiledExpression(
+ObjectPtr Class::EvaluateCompiledExpression(
     const ExternalTypedData& kernel_buffer,
     const Array& type_definitions,
     const Array& arguments,
@@ -4115,7 +4165,7 @@
 }
 
 // Ensure that top level parsing of the class has been done.
-RawError* Class::EnsureIsFinalized(Thread* thread) const {
+ErrorPtr Class::EnsureIsFinalized(Thread* thread) const {
   ASSERT(!IsNull());
   // Finalized classes have already been parsed.
   if (is_finalized()) {
@@ -4221,11 +4271,11 @@
 }
 
 template <class FakeInstance, class TargetFakeInstance>
-RawClass* Class::NewCommon(intptr_t index) {
+ClassPtr Class::NewCommon(intptr_t index) {
   ASSERT(Object::class_class() != Class::null());
   Class& result = Class::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -4257,10 +4307,10 @@
 }
 
 template <class FakeInstance, class TargetFakeInstance>
-RawClass* Class::New(intptr_t index,
-                     Isolate* isolate,
-                     bool register_class,
-                     bool is_abstract) {
+ClassPtr Class::New(intptr_t index,
+                    Isolate* isolate,
+                    bool register_class,
+                    bool is_abstract) {
   Class& result =
       Class::Handle(NewCommon<FakeInstance, TargetFakeInstance>(index));
   if (is_abstract) {
@@ -4272,11 +4322,11 @@
   return result.raw();
 }
 
-RawClass* Class::New(const Library& lib,
-                     const String& name,
-                     const Script& script,
-                     TokenPosition token_pos,
-                     bool register_class) {
+ClassPtr Class::New(const Library& lib,
+                    const String& name,
+                    const Script& script,
+                    TokenPosition token_pos,
+                    bool register_class) {
   Class& result =
       Class::Handle(NewCommon<Instance, RTN::Instance>(kIllegalCid));
   result.set_library(lib);
@@ -4295,13 +4345,13 @@
   return result.raw();
 }
 
-RawClass* Class::NewInstanceClass() {
+ClassPtr Class::NewInstanceClass() {
   return Class::New<Instance, RTN::Instance>(kIllegalCid, Isolate::Current());
 }
 
-RawClass* Class::NewNativeWrapper(const Library& library,
-                                  const String& name,
-                                  int field_count) {
+ClassPtr Class::NewNativeWrapper(const Library& library,
+                                 const String& name,
+                                 int field_count) {
   Class& cls = Class::Handle(library.LookupClass(name));
   if (cls.IsNull()) {
     cls = New(library, name, Script::Handle(), TokenPosition::kNoSource);
@@ -4311,9 +4361,15 @@
     cls.set_super_type(Type::Handle(Type::ObjectType()));
     // Compute instance size. First word contains a pointer to a properly
     // sized typed array once the first native field has been set.
-    const intptr_t host_instance_size = sizeof(RawInstance) + kWordSize;
+    const intptr_t host_instance_size = sizeof(InstanceLayout) + kWordSize;
+#if defined(PRECOMPILER)
     const intptr_t target_instance_size =
-        sizeof(RawInstance) + compiler::target::kWordSize;
+        compiler::target::Instance::InstanceSize() +
+        compiler::target::kWordSize;
+#else
+    const intptr_t target_instance_size =
+        sizeof(InstanceLayout) + compiler::target::kWordSize;
+#endif
     cls.set_instance_size(
         RoundedAllocationSize(host_instance_size),
         compiler::target::RoundedAllocationSize(target_instance_size));
@@ -4330,7 +4386,7 @@
   }
 }
 
-RawClass* Class::NewStringClass(intptr_t class_id, Isolate* isolate) {
+ClassPtr Class::NewStringClass(intptr_t class_id, Isolate* isolate) {
   intptr_t host_instance_size, target_instance_size;
   if (class_id == kOneByteStringCid) {
     host_instance_size = OneByteString::InstanceSize();
@@ -4363,8 +4419,8 @@
   return result.raw();
 }
 
-RawClass* Class::NewTypedDataClass(intptr_t class_id, Isolate* isolate) {
-  ASSERT(RawObject::IsTypedDataClassId(class_id));
+ClassPtr Class::NewTypedDataClass(intptr_t class_id, Isolate* isolate) {
+  ASSERT(IsTypedDataClassId(class_id));
   const intptr_t host_instance_size = TypedData::InstanceSize();
   const intptr_t target_instance_size =
       compiler::target::RoundedAllocationSize(RTN::TypedData::InstanceSize());
@@ -4381,8 +4437,8 @@
   return result.raw();
 }
 
-RawClass* Class::NewTypedDataViewClass(intptr_t class_id, Isolate* isolate) {
-  ASSERT(RawObject::IsTypedDataViewClassId(class_id));
+ClassPtr Class::NewTypedDataViewClass(intptr_t class_id, Isolate* isolate) {
+  ASSERT(IsTypedDataViewClassId(class_id));
   const intptr_t host_instance_size = TypedDataView::InstanceSize();
   const intptr_t target_instance_size = compiler::target::RoundedAllocationSize(
       RTN::TypedDataView::InstanceSize());
@@ -4400,9 +4456,8 @@
   return result.raw();
 }
 
-RawClass* Class::NewExternalTypedDataClass(intptr_t class_id,
-                                           Isolate* isolate) {
-  ASSERT(RawObject::IsExternalTypedDataClassId(class_id));
+ClassPtr Class::NewExternalTypedDataClass(intptr_t class_id, Isolate* isolate) {
+  ASSERT(IsExternalTypedDataClassId(class_id));
   const intptr_t host_instance_size = ExternalTypedData::InstanceSize();
   const intptr_t target_instance_size = compiler::target::RoundedAllocationSize(
       RTN::ExternalTypedData::InstanceSize());
@@ -4420,8 +4475,8 @@
   return result.raw();
 }
 
-RawClass* Class::NewPointerClass(intptr_t class_id, Isolate* isolate) {
-  ASSERT(RawObject::IsFfiPointerClassId(class_id));
+ClassPtr Class::NewPointerClass(intptr_t class_id, Isolate* isolate) {
+  ASSERT(IsFfiPointerClassId(class_id));
   intptr_t host_instance_size = Pointer::InstanceSize();
   intptr_t target_instance_size =
       compiler::target::RoundedAllocationSize(RTN::Pointer::InstanceSize());
@@ -4661,14 +4716,14 @@
 
 void Class::set_is_declaration_loaded() const {
   ASSERT(!is_declaration_loaded());
-  set_state_bits(ClassLoadingBits::update(RawClass::kDeclarationLoaded,
+  set_state_bits(ClassLoadingBits::update(ClassLayout::kDeclarationLoaded,
                                           raw_ptr()->state_bits_));
 }
 
 void Class::set_is_type_finalized() const {
   ASSERT(is_declaration_loaded());
   ASSERT(!is_type_finalized());
-  set_state_bits(ClassLoadingBits::update(RawClass::kTypeFinalized,
+  set_state_bits(ClassLoadingBits::update(ClassLayout::kTypeFinalized,
                                           raw_ptr()->state_bits_));
 }
 
@@ -4707,13 +4762,13 @@
 
 void Class::set_is_finalized() const {
   ASSERT(!is_finalized());
-  set_state_bits(
-      ClassFinalizedBits::update(RawClass::kFinalized, raw_ptr()->state_bits_));
+  set_state_bits(ClassFinalizedBits::update(ClassLayout::kFinalized,
+                                            raw_ptr()->state_bits_));
 }
 
 void Class::set_is_prefinalized() const {
   ASSERT(!is_finalized());
-  set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized,
+  set_state_bits(ClassFinalizedBits::update(ClassLayout::kPreFinalized,
                                             raw_ptr()->state_bits_));
 }
 
@@ -4775,7 +4830,7 @@
   StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null());
 }
 
-RawArray* Class::constants() const {
+ArrayPtr Class::constants() const {
   return raw_ptr()->constants_;
 }
 
@@ -4793,13 +4848,11 @@
   // non-generic class, the nullability is set to kNonNullable instead of
   // kLegacy when the non-nullable experiment is enabled.
   ASSERT(value.type_class_id() != kNullCid || value.IsNullable());
-  ASSERT(
-      value.type_class_id() == kNullCid ||
-      (Dart::non_nullable_flag() ? value.IsNonNullable() : value.IsLegacy()));
+  ASSERT(value.type_class_id() == kNullCid || value.IsNonNullable());
   StorePointer(&raw_ptr()->declaration_type_, value.raw());
 }
 
-RawType* Class::DeclarationType() const {
+TypePtr Class::DeclarationType() const {
   ASSERT(is_declaration_loaded());
   if (IsNullClass()) {
     return Type::NullType();
@@ -4818,10 +4871,9 @@
   // consistently cache the kLegacy version of a type, unless the non-nullable
   // experiment is enabled, in which case we store the kNonNullable version.
   // In either cases, the exception is type Null which is stored as kNullable.
-  Type& type = Type::Handle(
-      Type::New(*this, TypeArguments::Handle(type_parameters()), token_pos(),
-                Dart::non_nullable_flag() ? Nullability::kNonNullable
-                                          : Nullability::kLegacy));
+  Type& type =
+      Type::Handle(Type::New(*this, TypeArguments::Handle(type_parameters()),
+                             token_pos(), Nullability::kNonNullable));
   type ^= ClassFinalizer::FinalizeType(*this, type);
   set_declaration_type(type);
   return type.raw();
@@ -4931,7 +4983,7 @@
       const AbstractType& other_type_arg =
           AbstractType::Handle(zone, other_type_arguments.TypeAtNullSafe(0));
       // Check if S1 is a top type.
-      if (other_type_arg.IsTopType()) {
+      if (other_type_arg.IsTopTypeForSubtyping()) {
         return true;
       }
       // Check T0 <: Future<S1> when T0 is Future<S0>.
@@ -4972,19 +5024,20 @@
       // Since we do not truncate the type argument vector of a subclass (see
       // below), we only check a subvector of the proper length.
       // Check for covariance.
-      if (other_type_arguments.IsNull() ||
-          other_type_arguments.IsTopTypes(from_index, num_type_params)) {
+      if (other_type_arguments.IsNull()) {
         return true;
       }
-      if (type_arguments.IsNull() ||
-          type_arguments.IsRaw(from_index, num_type_params)) {
-        // Other type can't be more specific than this one because for that
-        // it would have to have all dynamic type arguments which is checked
-        // above.
-        return false;
+      AbstractType& type = AbstractType::Handle(zone);
+      AbstractType& other_type = AbstractType::Handle(zone);
+      for (intptr_t i = 0; i < num_type_params; ++i) {
+        type = type_arguments.TypeAtNullSafe(from_index + i);
+        other_type = other_type_arguments.TypeAt(from_index + i);
+        ASSERT(!type.IsNull() && !other_type.IsNull());
+        if (!type.IsSubtypeOf(other_type, space)) {
+          return false;
+        }
       }
-      return type_arguments.IsSubtypeOf(other_type_arguments, from_index,
-                                        num_type_params, space);
+      return true;
     }
     // Check for 'direct super type' specified in the implements clause
     // and check for transitivity at the same time.
@@ -5039,49 +5092,48 @@
   return Library::IsPrivate(String::Handle(Name()));
 }
 
-RawFunction* Class::LookupDynamicFunction(const String& name) const {
+FunctionPtr Class::LookupDynamicFunction(const String& name) const {
   return LookupFunction(name, kInstance);
 }
 
-RawFunction* Class::LookupDynamicFunctionAllowAbstract(
+FunctionPtr Class::LookupDynamicFunctionAllowAbstract(
     const String& name) const {
   return LookupFunction(name, kInstanceAllowAbstract);
 }
 
-RawFunction* Class::LookupDynamicFunctionAllowPrivate(
-    const String& name) const {
+FunctionPtr Class::LookupDynamicFunctionAllowPrivate(const String& name) const {
   return LookupFunctionAllowPrivate(name, kInstance);
 }
 
-RawFunction* Class::LookupStaticFunction(const String& name) const {
+FunctionPtr Class::LookupStaticFunction(const String& name) const {
   return LookupFunction(name, kStatic);
 }
 
-RawFunction* Class::LookupStaticFunctionAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupStaticFunctionAllowPrivate(const String& name) const {
   return LookupFunctionAllowPrivate(name, kStatic);
 }
 
-RawFunction* Class::LookupConstructor(const String& name) const {
+FunctionPtr Class::LookupConstructor(const String& name) const {
   return LookupFunction(name, kConstructor);
 }
 
-RawFunction* Class::LookupConstructorAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupConstructorAllowPrivate(const String& name) const {
   return LookupFunctionAllowPrivate(name, kConstructor);
 }
 
-RawFunction* Class::LookupFactory(const String& name) const {
+FunctionPtr Class::LookupFactory(const String& name) const {
   return LookupFunction(name, kFactory);
 }
 
-RawFunction* Class::LookupFactoryAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupFactoryAllowPrivate(const String& name) const {
   return LookupFunctionAllowPrivate(name, kFactory);
 }
 
-RawFunction* Class::LookupFunction(const String& name) const {
+FunctionPtr Class::LookupFunction(const String& name) const {
   return LookupFunction(name, kAny);
 }
 
-RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupFunctionAllowPrivate(const String& name) const {
   return LookupFunctionAllowPrivate(name, kAny);
 }
 
@@ -5109,7 +5161,7 @@
   return true;
 }
 
-RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) {
+FunctionPtr Class::CheckFunctionType(const Function& func, MemberKind kind) {
   if ((kind == kInstance) || (kind == kInstanceAllowAbstract)) {
     if (func.IsDynamicFunction(kind == kInstanceAllowAbstract)) {
       return func.raw();
@@ -5134,7 +5186,7 @@
   return Function::null();
 }
 
-RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const {
+FunctionPtr Class::LookupFunction(const String& name, MemberKind kind) const {
   ASSERT(!IsNull());
   Thread* thread = Thread::Current();
   if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5185,8 +5237,8 @@
   return Function::null();
 }
 
-RawFunction* Class::LookupFunctionAllowPrivate(const String& name,
-                                               MemberKind kind) const {
+FunctionPtr Class::LookupFunctionAllowPrivate(const String& name,
+                                              MemberKind kind) const {
   ASSERT(!IsNull());
   Thread* thread = Thread::Current();
   if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5212,17 +5264,17 @@
   return Function::null();
 }
 
-RawFunction* Class::LookupGetterFunction(const String& name) const {
+FunctionPtr Class::LookupGetterFunction(const String& name) const {
   return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name);
 }
 
-RawFunction* Class::LookupSetterFunction(const String& name) const {
+FunctionPtr Class::LookupSetterFunction(const String& name) const {
   return LookupAccessorFunction(kSetterPrefix, kSetterPrefixLength, name);
 }
 
-RawFunction* Class::LookupAccessorFunction(const char* prefix,
-                                           intptr_t prefix_length,
-                                           const String& name) const {
+FunctionPtr Class::LookupAccessorFunction(const char* prefix,
+                                          intptr_t prefix_length,
+                                          const String& name) const {
   ASSERT(!IsNull());
   Thread* thread = Thread::Current();
   if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5248,19 +5300,19 @@
   return Function::null();
 }
 
-RawField* Class::LookupInstanceField(const String& name) const {
+FieldPtr Class::LookupInstanceField(const String& name) const {
   return LookupField(name, kInstance);
 }
 
-RawField* Class::LookupStaticField(const String& name) const {
+FieldPtr Class::LookupStaticField(const String& name) const {
   return LookupField(name, kStatic);
 }
 
-RawField* Class::LookupField(const String& name) const {
+FieldPtr Class::LookupField(const String& name) const {
   return LookupField(name, kAny);
 }
 
-RawField* Class::LookupField(const String& name, MemberKind kind) const {
+FieldPtr Class::LookupField(const String& name, MemberKind kind) const {
   ASSERT(!IsNull());
   Thread* thread = Thread::Current();
   if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5307,8 +5359,8 @@
   return Field::null();
 }
 
-RawField* Class::LookupFieldAllowPrivate(const String& name,
-                                         bool instance_only) const {
+FieldPtr Class::LookupFieldAllowPrivate(const String& name,
+                                        bool instance_only) const {
   ASSERT(!IsNull());
   // Use slow string compare, ignoring privacy name mangling.
   Thread* thread = Thread::Current();
@@ -5338,7 +5390,7 @@
   return Field::null();
 }
 
-RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const {
+FieldPtr Class::LookupInstanceFieldAllowPrivate(const String& name) const {
   Field& field = Field::Handle(LookupFieldAllowPrivate(name, true));
   if (!field.IsNull() && !field.is_static()) {
     return field.raw();
@@ -5346,7 +5398,7 @@
   return Field::null();
 }
 
-RawField* Class::LookupStaticFieldAllowPrivate(const String& name) const {
+FieldPtr Class::LookupStaticFieldAllowPrivate(const String& name) const {
   Field& field = Field::Handle(LookupFieldAllowPrivate(name));
   if (!field.IsNull() && field.is_static()) {
     return field.raw();
@@ -5433,7 +5485,7 @@
     return KeyType::Hash(ObjectType::Cast(key).value());
   }
   static uword Hash(const KeyType& key) { return key.Hash(); }
-  static RawObject* NewKey(const KeyType& obj) {
+  static ObjectPtr NewKey(const KeyType& obj) {
     if (obj.key_ != NULL) {
       return obj.key_->raw();
     } else {
@@ -5448,7 +5500,7 @@
     CanonicalMintSet;
 
 // Returns an instance of Double or Double::null().
-RawDouble* Class::LookupCanonicalDouble(Zone* zone, double value) const {
+DoublePtr Class::LookupCanonicalDouble(Zone* zone, double value) const {
   ASSERT(this->raw() == Isolate::Current()->object_store()->double_class());
   if (this->constants() == Object::empty_array().raw()) return Double::null();
 
@@ -5460,7 +5512,7 @@
 }
 
 // Returns an instance of Mint or Mint::null().
-RawMint* Class::LookupCanonicalMint(Zone* zone, int64_t value) const {
+MintPtr Class::LookupCanonicalMint(Zone* zone, int64_t value) const {
   ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class());
   if (this->constants() == Object::empty_array().raw()) return Mint::null();
 
@@ -5512,14 +5564,14 @@
     return Instance::Cast(key).CanonicalizeHash();
   }
   static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); }
-  static RawObject* NewKey(const CanonicalInstanceKey& obj) {
+  static ObjectPtr NewKey(const CanonicalInstanceKey& obj) {
     return obj.key_.raw();
   }
 };
 typedef UnorderedHashSet<CanonicalInstanceTraits> CanonicalInstancesSet;
 
-RawInstance* Class::LookupCanonicalInstance(Zone* zone,
-                                            const Instance& value) const {
+InstancePtr Class::LookupCanonicalInstance(Zone* zone,
+                                           const Instance& value) const {
   ASSERT(this->raw() == value.clazz());
   ASSERT(is_finalized() || is_prefinalized());
   Instance& canonical_value = Instance::Handle(zone);
@@ -5531,8 +5583,8 @@
   return canonical_value.raw();
 }
 
-RawInstance* Class::InsertCanonicalConstant(Zone* zone,
-                                            const Instance& constant) const {
+InstancePtr Class::InsertCanonicalConstant(Zone* zone,
+                                           const Instance& constant) const {
   ASSERT(this->raw() == constant.clazz());
   Instance& canonical_value = Instance::Handle(zone);
   if (this->constants() == Object::empty_array().raw()) {
@@ -5597,6 +5649,39 @@
   set.Release();
 }
 
+bool Class::RequireLegacyErasureOfConstants(Zone* zone) const {
+  const intptr_t num_type_params = NumTypeParameters();
+  const intptr_t num_type_args = NumTypeArguments();
+  const intptr_t from_index = num_type_args - num_type_params;
+  Instance& constant = Instance::Handle(zone);
+  TypeArguments& type_arguments = TypeArguments::Handle(zone);
+  AbstractType& type = AbstractType::Handle(zone);
+  CanonicalInstancesSet set(zone, constants());
+  CanonicalInstancesSet::Iterator it(&set);
+  while (it.MoveNext()) {
+    constant ^= set.GetKey(it.Current());
+    ASSERT(!constant.IsNull());
+    ASSERT(!constant.IsTypeArguments());
+    ASSERT(!constant.IsType());
+    type_arguments = constant.GetTypeArguments();
+    if (type_arguments.IsNull()) {
+      continue;
+    }
+    for (intptr_t i = 0; i < num_type_params; i++) {
+      type = type_arguments.TypeAt(from_index + i);
+      if (!type.IsLegacy() && !type.IsVoidType() && !type.IsDynamicType() &&
+          !type.IsNullType()) {
+        return true;
+      }
+      // It is not possible for a legacy type to have non-legacy type
+      // arguments or for a legacy function type to have non-legacy parameter
+      // types, non-legacy type parameters, or required named parameters.
+    }
+  }
+  set.Release();
+  return false;
+}
+
 intptr_t TypeArguments::ComputeNullability() const {
   if (IsNull()) return 0;
   const intptr_t num_types = Length();
@@ -5651,10 +5736,10 @@
   return result;
 }
 
-RawTypeArguments* TypeArguments::Prepend(Zone* zone,
-                                         const TypeArguments& other,
-                                         intptr_t other_length,
-                                         intptr_t total_length) const {
+TypeArgumentsPtr TypeArguments::Prepend(Zone* zone,
+                                        const TypeArguments& other,
+                                        intptr_t other_length,
+                                        intptr_t total_length) const {
   if (IsNull() && other.IsNull()) {
     return TypeArguments::null();
   }
@@ -5672,7 +5757,7 @@
   return result.Canonicalize();
 }
 
-RawTypeArguments* TypeArguments::ConcatenateTypeParameters(
+TypeArgumentsPtr TypeArguments::ConcatenateTypeParameters(
     Zone* zone,
     const TypeArguments& other) const {
   ASSERT(!IsNull() && !other.IsNull());
@@ -5692,14 +5777,14 @@
   return result.raw();
 }
 
-RawString* TypeArguments::Name() const {
+StringPtr TypeArguments::Name() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintSubvectorName(0, Length(), kInternalName, &printer);
   return Symbols::New(thread, printer.buffer());
 }
 
-RawString* TypeArguments::UserVisibleName() const {
+StringPtr TypeArguments::UserVisibleName() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintSubvectorName(0, Length(), kUserVisibleName, &printer);
@@ -5801,38 +5886,6 @@
   return true;
 }
 
-bool TypeArguments::IsTopTypes(intptr_t from_index, intptr_t len) const {
-  ASSERT(Length() >= (from_index + len));
-  AbstractType& type = AbstractType::Handle();
-  for (intptr_t i = 0; i < len; i++) {
-    type = TypeAt(from_index + i);
-    if (type.IsNull() || !type.IsTopType()) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool TypeArguments::IsSubtypeOf(const TypeArguments& other,
-                                intptr_t from_index,
-                                intptr_t len,
-                                Heap::Space space) const {
-  ASSERT(Length() >= (from_index + len));
-  ASSERT(!other.IsNull());
-  ASSERT(other.Length() >= (from_index + len));
-  AbstractType& type = AbstractType::Handle();
-  AbstractType& other_type = AbstractType::Handle();
-  for (intptr_t i = 0; i < len; i++) {
-    type = TypeAt(from_index + i);
-    other_type = other.TypeAt(from_index + i);
-    if (type.IsNull() || other_type.IsNull() ||
-        !type.IsSubtypeOf(other_type, space)) {
-      return false;
-    }
-  }
-  return true;
-}
-
 bool TypeArguments::HasInstantiations() const {
   const Array& prior_instantiations = Array::Handle(instantiations());
   ASSERT(prior_instantiations.Length() > 0);  // Always at least a sentinel.
@@ -5852,7 +5905,7 @@
   return num;
 }
 
-RawArray* TypeArguments::instantiations() const {
+ArrayPtr TypeArguments::instantiations() const {
   return raw_ptr()->instantiations_;
 }
 
@@ -5875,12 +5928,12 @@
   return Smi::Value(raw_ptr()->nullability_);
 }
 
-RawAbstractType* TypeArguments::TypeAt(intptr_t index) const {
+AbstractTypePtr TypeArguments::TypeAt(intptr_t index) const {
   ASSERT(!IsNull());
   return *TypeAddr(index);
 }
 
-RawAbstractType* TypeArguments::TypeAtNullSafe(intptr_t index) const {
+AbstractTypePtr TypeArguments::TypeAtNullSafe(intptr_t index) const {
   if (IsNull()) {
     // null vector represents infinite list of dynamics
     return Type::dynamic_type().raw();
@@ -6092,7 +6145,7 @@
   return true;
 }
 
-RawTypeArguments* TypeArguments::InstantiateFrom(
+TypeArgumentsPtr TypeArguments::InstantiateFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     intptr_t num_free_fun_type_params,
@@ -6132,7 +6185,7 @@
   return instantiated_array.raw();
 }
 
-RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom(
+TypeArgumentsPtr TypeArguments::InstantiateAndCanonicalizeFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments) const {
   ASSERT(!IsInstantiated());
@@ -6203,15 +6256,15 @@
   return result.raw();
 }
 
-RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
+TypeArgumentsPtr TypeArguments::New(intptr_t len, Heap::Space space) {
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len);
   }
   TypeArguments& result = TypeArguments::Handle();
   {
-    RawObject* raw = Object::Allocate(TypeArguments::kClassId,
-                                      TypeArguments::InstanceSize(len), space);
+    ObjectPtr raw = Object::Allocate(TypeArguments::kClassId,
+                                     TypeArguments::InstanceSize(len), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
     // Length must be set before we start storing into the array.
@@ -6226,7 +6279,7 @@
   return result.raw();
 }
 
-RawAbstractType* const* TypeArguments::TypeAddr(intptr_t index) const {
+AbstractTypePtr const* TypeArguments::TypeAddr(intptr_t index) const {
   ASSERT((index >= 0) && (index < Length()));
   return &raw_ptr()->types()[index];
 }
@@ -6238,7 +6291,7 @@
   StoreSmi(&raw_ptr()->length_, Smi::New(value));
 }
 
-RawTypeArguments* TypeArguments::Canonicalize(TrailPtr trail) const {
+TypeArgumentsPtr TypeArguments::Canonicalize(TrailPtr trail) const {
   if (IsNull() || IsCanonical()) {
     ASSERT(IsOld());
     return this->raw();
@@ -6343,8 +6396,8 @@
   return OS::SCreate(Thread::Current()->zone(), "PatchClass for %s", cls_name);
 }
 
-RawPatchClass* PatchClass::New(const Class& patched_class,
-                               const Class& origin_class) {
+PatchClassPtr PatchClass::New(const Class& patched_class,
+                              const Class& origin_class) {
   const PatchClass& result = PatchClass::Handle(PatchClass::New());
   result.set_patched_class(patched_class);
   result.set_origin_class(origin_class);
@@ -6353,8 +6406,8 @@
   return result.raw();
 }
 
-RawPatchClass* PatchClass::New(const Class& patched_class,
-                               const Script& script) {
+PatchClassPtr PatchClass::New(const Class& patched_class,
+                              const Script& script) {
   const PatchClass& result = PatchClass::Handle(PatchClass::New());
   result.set_patched_class(patched_class);
   result.set_origin_class(patched_class);
@@ -6363,11 +6416,11 @@
   return result.raw();
 }
 
-RawPatchClass* PatchClass::New() {
+PatchClassPtr PatchClass::New() {
   ASSERT(Object::patch_class_class() != Class::null());
-  RawObject* raw = Object::Allocate(PatchClass::kClassId,
-                                    PatchClass::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawPatchClass*>(raw);
+  ObjectPtr raw = Object::Allocate(PatchClass::kClassId,
+                                   PatchClass::InstanceSize(), Heap::kOld);
+  return static_cast<PatchClassPtr>(raw);
 }
 
 void PatchClass::set_patched_class(const Class& value) const {
@@ -6463,11 +6516,11 @@
     }
   }
   switch (kind()) {
-    case RawFunction::kDynamicInvocationForwarder:
+    case FunctionLayout::kDynamicInvocationForwarder:
       return is_declared_in_bytecode();
-    case RawFunction::kImplicitClosureFunction:
-    case RawFunction::kIrregexpFunction:
-    case RawFunction::kFfiTrampoline:
+    case FunctionLayout::kImplicitClosureFunction:
+    case FunctionLayout::kIrregexpFunction:
+    case FunctionLayout::kFfiTrampoline:
       return false;
     default:
       return true;
@@ -6494,7 +6547,7 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-bool Function::HasCode(RawFunction* function) {
+bool Function::HasCode(FunctionPtr function) {
   NoSafepointScope no_safepoint;
   ASSERT(function->ptr()->code_ != Code::null());
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -6614,7 +6667,7 @@
 #endif
 }
 
-RawContextScope* Function::context_scope() const {
+ContextScopePtr Function::context_scope() const {
   if (IsClosureFunction()) {
     const Object& obj = Object::Handle(raw_ptr()->data_);
     ASSERT(!obj.IsNull());
@@ -6633,7 +6686,7 @@
   UNREACHABLE();
 }
 
-RawInstance* Function::implicit_static_closure() const {
+InstancePtr Function::implicit_static_closure() const {
   if (IsImplicitStaticClosureFunction()) {
     const Object& obj = Object::Handle(raw_ptr()->data_);
     ASSERT(!obj.IsNull());
@@ -6652,7 +6705,7 @@
   UNREACHABLE();
 }
 
-RawScript* Function::eval_script() const {
+ScriptPtr Function::eval_script() const {
   const Object& obj = Object::Handle(raw_ptr()->data_);
   if (obj.IsScript()) {
     return Script::Cast(obj).raw();
@@ -6666,53 +6719,53 @@
   set_data(script);
 }
 
-RawFunction* Function::extracted_method_closure() const {
-  ASSERT(kind() == RawFunction::kMethodExtractor);
+FunctionPtr Function::extracted_method_closure() const {
+  ASSERT(kind() == FunctionLayout::kMethodExtractor);
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(obj.IsFunction());
   return Function::Cast(obj).raw();
 }
 
 void Function::set_extracted_method_closure(const Function& value) const {
-  ASSERT(kind() == RawFunction::kMethodExtractor);
+  ASSERT(kind() == FunctionLayout::kMethodExtractor);
   ASSERT(raw_ptr()->data_ == Object::null());
   set_data(value);
 }
 
-RawArray* Function::saved_args_desc() const {
-  ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
-         kind() == RawFunction::kInvokeFieldDispatcher);
+ArrayPtr Function::saved_args_desc() const {
+  ASSERT(kind() == FunctionLayout::kNoSuchMethodDispatcher ||
+         kind() == FunctionLayout::kInvokeFieldDispatcher);
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(obj.IsArray());
   return Array::Cast(obj).raw();
 }
 
 void Function::set_saved_args_desc(const Array& value) const {
-  ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
-         kind() == RawFunction::kInvokeFieldDispatcher);
+  ASSERT(kind() == FunctionLayout::kNoSuchMethodDispatcher ||
+         kind() == FunctionLayout::kInvokeFieldDispatcher);
   ASSERT(raw_ptr()->data_ == Object::null());
   set_data(value);
 }
 
-RawField* Function::accessor_field() const {
-  ASSERT(kind() == RawFunction::kImplicitGetter ||
-         kind() == RawFunction::kImplicitSetter ||
-         kind() == RawFunction::kImplicitStaticGetter ||
-         kind() == RawFunction::kFieldInitializer);
+FieldPtr Function::accessor_field() const {
+  ASSERT(kind() == FunctionLayout::kImplicitGetter ||
+         kind() == FunctionLayout::kImplicitSetter ||
+         kind() == FunctionLayout::kImplicitStaticGetter ||
+         kind() == FunctionLayout::kFieldInitializer);
   return Field::RawCast(raw_ptr()->data_);
 }
 
 void Function::set_accessor_field(const Field& value) const {
-  ASSERT(kind() == RawFunction::kImplicitGetter ||
-         kind() == RawFunction::kImplicitSetter ||
-         kind() == RawFunction::kImplicitStaticGetter ||
-         kind() == RawFunction::kFieldInitializer);
+  ASSERT(kind() == FunctionLayout::kImplicitGetter ||
+         kind() == FunctionLayout::kImplicitSetter ||
+         kind() == FunctionLayout::kImplicitStaticGetter ||
+         kind() == FunctionLayout::kFieldInitializer);
   // Top level classes may be finalized multiple times.
   ASSERT(raw_ptr()->data_ == Object::null() || raw_ptr()->data_ == value.raw());
   set_data(value);
 }
 
-RawFunction* Function::parent_function() const {
+FunctionPtr Function::parent_function() const {
   if (IsClosureFunction() || IsSignatureFunction()) {
     const Object& obj = Object::Handle(raw_ptr()->data_);
     ASSERT(!obj.IsNull());
@@ -6737,8 +6790,8 @@
 }
 
 // Enclosing outermost function of this local function.
-RawFunction* Function::GetOutermostFunction() const {
-  RawFunction* parent = parent_function();
+FunctionPtr Function::GetOutermostFunction() const {
+  FunctionPtr parent = parent_function();
   if (parent == Object::null()) {
     return raw();
   }
@@ -6766,7 +6819,7 @@
   return false;
 }
 
-RawFunction* Function::implicit_closure_function() const {
+FunctionPtr Function::implicit_closure_function() const {
   if (IsClosureFunction() || IsSignatureFunction() || IsFactory() ||
       IsDispatcherOrImplicitAccessor() || IsFieldInitializer()) {
     return Function::null();
@@ -6804,7 +6857,7 @@
   }
 }
 
-RawType* Function::ExistingSignatureType() const {
+TypePtr Function::ExistingSignatureType() const {
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
   if (IsSignatureFunction()) {
@@ -6824,7 +6877,7 @@
   FfiTrampolineData::Cast(obj).set_c_signature(sig);
 }
 
-RawFunction* Function::FfiCSignature() const {
+FunctionPtr Function::FfiCSignature() const {
   ASSERT(IsFfiTrampoline());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
@@ -6845,7 +6898,7 @@
   FfiTrampolineData::Cast(obj).set_callback_id(value);
 }
 
-RawFunction* Function::FfiCallbackTarget() const {
+FunctionPtr Function::FfiCallbackTarget() const {
   ASSERT(IsFfiTrampoline());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
@@ -6859,7 +6912,7 @@
   FfiTrampolineData::Cast(obj).set_callback_target(target);
 }
 
-RawInstance* Function::FfiCallbackExceptionalReturn() const {
+InstancePtr Function::FfiCallbackExceptionalReturn() const {
   ASSERT(IsFfiTrampoline());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
@@ -6873,7 +6926,7 @@
   FfiTrampolineData::Cast(obj).set_callback_exceptional_return(value);
 }
 
-RawType* Function::SignatureType(Nullability nullability) const {
+TypePtr Function::SignatureType(Nullability nullability) const {
   Type& type = Type::Handle(ExistingSignatureType());
   if (type.IsNull()) {
     // The function type of this function is not yet cached and needs to be
@@ -6937,7 +6990,7 @@
   return true;
 }
 
-RawType* Function::RedirectionType() const {
+TypePtr Function::RedirectionType() const {
   ASSERT(IsRedirectingFactory());
   ASSERT(!is_native());
   const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -6945,8 +6998,8 @@
   return RedirectionData::Cast(obj).type();
 }
 
-const char* Function::KindToCString(RawFunction::Kind kind) {
-  return RawFunction::KindToCString(kind);
+const char* Function::KindToCString(FunctionLayout::Kind kind) {
+  return FunctionLayout::KindToCString(kind);
 }
 
 void Function::SetRedirectionType(const Type& type) const {
@@ -6959,7 +7012,7 @@
   RedirectionData::Cast(obj).set_type(type);
 }
 
-RawString* Function::RedirectionIdentifier() const {
+StringPtr Function::RedirectionIdentifier() const {
   ASSERT(IsRedirectingFactory());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
@@ -6976,7 +7029,7 @@
   RedirectionData::Cast(obj).set_identifier(identifier);
 }
 
-RawFunction* Function::RedirectionTarget() const {
+FunctionPtr Function::RedirectionTarget() const {
   ASSERT(IsRedirectingFactory());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
@@ -6993,15 +7046,15 @@
   RedirectionData::Cast(obj).set_target(target);
 }
 
-RawFunction* Function::ForwardingTarget() const {
-  ASSERT(kind() == RawFunction::kDynamicInvocationForwarder);
+FunctionPtr Function::ForwardingTarget() const {
+  ASSERT(kind() == FunctionLayout::kDynamicInvocationForwarder);
   Array& checks = Array::Handle();
   checks ^= raw_ptr()->data_;
   return Function::RawCast(checks.At(0));
 }
 
 void Function::SetForwardingChecks(const Array& checks) const {
-  ASSERT(kind() == RawFunction::kDynamicInvocationForwarder);
+  ASSERT(kind() == FunctionLayout::kDynamicInvocationForwarder);
   ASSERT(checks.Length() >= 1);
   ASSERT(Object::Handle(checks.At(0)).IsFunction());
   set_data(checks);
@@ -7056,24 +7109,24 @@
   StorePointer(&raw_ptr()->owner_, value.raw());
 }
 
-RawRegExp* Function::regexp() const {
-  ASSERT(kind() == RawFunction::kIrregexpFunction);
+RegExpPtr Function::regexp() const {
+  ASSERT(kind() == FunctionLayout::kIrregexpFunction);
   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
   return RegExp::RawCast(pair.At(0));
 }
 
 class StickySpecialization : public BitField<intptr_t, bool, 0, 1> {};
 class StringSpecializationCid
-    : public BitField<intptr_t, intptr_t, 1, RawObject::kClassIdTagSize> {};
+    : public BitField<intptr_t, intptr_t, 1, ObjectLayout::kClassIdTagSize> {};
 
 intptr_t Function::string_specialization_cid() const {
-  ASSERT(kind() == RawFunction::kIrregexpFunction);
+  ASSERT(kind() == FunctionLayout::kIrregexpFunction);
   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
   return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1))));
 }
 
 bool Function::is_sticky_specialization() const {
-  ASSERT(kind() == RawFunction::kIrregexpFunction);
+  ASSERT(kind() == FunctionLayout::kIrregexpFunction);
   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
   return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1))));
 }
@@ -7081,8 +7134,8 @@
 void Function::SetRegExpData(const RegExp& regexp,
                              intptr_t string_specialization_cid,
                              bool sticky) const {
-  ASSERT(kind() == RawFunction::kIrregexpFunction);
-  ASSERT(RawObject::IsStringClassId(string_specialization_cid));
+  ASSERT(kind() == FunctionLayout::kIrregexpFunction);
+  ASSERT(IsStringClassId(string_specialization_cid));
   ASSERT(raw_ptr()->data_ == Object::null());
   const Array& pair = Array::Handle(Array::New(2, Heap::kOld));
   pair.SetAt(0, regexp);
@@ -7092,7 +7145,7 @@
   set_data(pair);
 }
 
-RawString* Function::native_name() const {
+StringPtr Function::native_name() const {
   ASSERT(is_native());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(obj.IsArray());
@@ -7128,7 +7181,7 @@
   StorePointer(&raw_ptr()->result_type_, value.raw());
 }
 
-RawAbstractType* Function::ParameterTypeAt(intptr_t index) const {
+AbstractTypePtr Function::ParameterTypeAt(intptr_t index) const {
   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
   return AbstractType::RawCast(parameter_types.At(index));
 }
@@ -7137,7 +7190,7 @@
                                   const AbstractType& value) const {
   ASSERT(!value.IsNull());
   // Method extractor parameters are shared and are in the VM heap.
-  ASSERT(kind() != RawFunction::kMethodExtractor);
+  ASSERT(kind() != FunctionLayout::kMethodExtractor);
   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
   parameter_types.SetAt(index, value);
 }
@@ -7146,7 +7199,7 @@
   StorePointer(&raw_ptr()->parameter_types_, value.raw());
 }
 
-RawString* Function::ParameterNameAt(intptr_t index) const {
+StringPtr Function::ParameterNameAt(intptr_t index) const {
   const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
   return String::RawCast(parameter_names.At(index));
 }
@@ -7177,7 +7230,7 @@
 }
 
 bool Function::IsRequiredAt(intptr_t index) const {
-  if (index < num_fixed_parameters()) {
+  if (index < num_fixed_parameters() + NumOptionalPositionalParameters()) {
     return false;
   }
   intptr_t flag_mask;
@@ -7186,7 +7239,7 @@
   if (flag_index >= parameter_names.Length()) {
     return false;
   }
-  RawObject* element = parameter_names.At(flag_index);
+  ObjectPtr element = parameter_names.At(flag_index);
   if (element == Object::null()) {
     return false;
   }
@@ -7200,7 +7253,7 @@
   const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
   ASSERT(flag_index < parameter_names.Length());
   intptr_t flag;
-  RawObject* element = parameter_names.At(flag_index);
+  ObjectPtr element = parameter_names.At(flag_index);
   if (element == Object::null()) {
     flag = 0;
   } else {
@@ -7265,9 +7318,8 @@
   }
 }
 
-RawTypeParameter* Function::LookupTypeParameter(
-    const String& type_name,
-    intptr_t* function_level) const {
+TypeParameterPtr Function::LookupTypeParameter(const String& type_name,
+                                               intptr_t* function_level) const {
   ASSERT(!type_name.IsNull());
   Thread* thread = Thread::Current();
   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
@@ -7305,11 +7357,11 @@
   return TypeParameter::null();
 }
 
-void Function::set_kind(RawFunction::Kind value) const {
+void Function::set_kind(FunctionLayout::Kind value) const {
   set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_));
 }
 
-void Function::set_modifier(RawFunction::AsyncModifier value) const {
+void Function::set_modifier(FunctionLayout::AsyncModifier value) const {
   set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_));
 }
 
@@ -7338,20 +7390,20 @@
 
 void Function::set_num_fixed_parameters(intptr_t value) const {
   ASSERT(value >= 0);
-  ASSERT(Utils::IsUint(RawFunction::kMaxFixedParametersBits, value));
+  ASSERT(Utils::IsUint(FunctionLayout::kMaxFixedParametersBits, value));
   const uint32_t* original = &raw_ptr()->packed_fields_;
-  StoreNonPointer(original, RawFunction::PackedNumFixedParameters::update(
+  StoreNonPointer(original, FunctionLayout::PackedNumFixedParameters::update(
                                 value, *original));
 }
 
 void Function::SetNumOptionalParameters(intptr_t value,
                                         bool are_optional_positional) const {
-  ASSERT(Utils::IsUint(RawFunction::kMaxOptionalParametersBits, value));
+  ASSERT(Utils::IsUint(FunctionLayout::kMaxOptionalParametersBits, value));
   uint32_t packed_fields = raw_ptr()->packed_fields_;
-  packed_fields = RawFunction::PackedHasNamedOptionalParameters::update(
+  packed_fields = FunctionLayout::PackedHasNamedOptionalParameters::update(
       !are_optional_positional, packed_fields);
   packed_fields =
-      RawFunction::PackedNumOptionalParameters::update(value, packed_fields);
+      FunctionLayout::PackedNumOptionalParameters::update(value, packed_fields);
   set_packed_fields(packed_fields);
 }
 
@@ -7384,6 +7436,7 @@
   }
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 bool Function::CanBeInlined() const {
   // Our force-optimized functions cannot deoptimize to an unoptimized frame.
   // If the instructions of the force-optimized function body get moved via
@@ -7394,38 +7447,41 @@
   if (ForceOptimize()) {
     return CompilerState::Current().is_aot();
   }
-#if defined(PRODUCT)
-  return is_inlinable() && !is_external() && !is_generated_body();
-#else
+
+#if !defined(PRODUCT)
   Thread* thread = Thread::Current();
-  return is_inlinable() && !is_external() && !is_generated_body() &&
-         !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone());
-#endif
+  if (thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())) {
+    return false;
+  }
+#endif  // !defined(PRODUCT)
+
+  return is_inlinable() && !is_external() && !is_generated_body();
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 intptr_t Function::NumParameters() const {
   return num_fixed_parameters() + NumOptionalParameters();
 }
 
 intptr_t Function::NumImplicitParameters() const {
-  const RawFunction::Kind k = kind();
-  if (k == RawFunction::kConstructor) {
+  const FunctionLayout::Kind k = kind();
+  if (k == FunctionLayout::kConstructor) {
     // Type arguments for factory; instance for generative constructor.
     return 1;
   }
-  if ((k == RawFunction::kClosureFunction) ||
-      (k == RawFunction::kImplicitClosureFunction) ||
-      (k == RawFunction::kSignatureFunction) ||
-      (k == RawFunction::kFfiTrampoline)) {
+  if ((k == FunctionLayout::kClosureFunction) ||
+      (k == FunctionLayout::kImplicitClosureFunction) ||
+      (k == FunctionLayout::kSignatureFunction) ||
+      (k == FunctionLayout::kFfiTrampoline)) {
     return 1;  // Closure object.
   }
   if (!is_static()) {
     // Closure functions defined inside instance (i.e. non-static) functions are
     // marked as non-static, but they do not have a receiver.
     // Closures are handled above.
-    ASSERT((k != RawFunction::kClosureFunction) &&
-           (k != RawFunction::kImplicitClosureFunction) &&
-           (k != RawFunction::kSignatureFunction));
+    ASSERT((k != FunctionLayout::kClosureFunction) &&
+           (k != FunctionLayout::kImplicitClosureFunction) &&
+           (k != FunctionLayout::kSignatureFunction));
     return 1;  // Receiver.
   }
   return 0;  // No implicit parameters.
@@ -7558,7 +7614,8 @@
   }
   if (isolate->null_safety()) {
     // Verify that all required named parameters are filled.
-    for (intptr_t j = num_positional_args; j < num_parameters; j++) {
+    for (intptr_t j = num_parameters - NumOptionalNamedParameters();
+         j < num_parameters; j++) {
       if (IsRequiredAt(j)) {
         parameter_name = ParameterNameAt(j);
         ASSERT(parameter_name.IsSymbol());
@@ -7588,7 +7645,7 @@
   return true;
 }
 
-RawObject* Function::DoArgumentTypesMatch(
+ObjectPtr Function::DoArgumentTypesMatch(
     const Array& args,
     const ArgumentsDescriptor& args_desc,
     const TypeArguments& instantiator_type_args) const {
@@ -7761,7 +7818,7 @@
   return chars;
 }
 
-RawFunction* Function::InstantiateSignatureFrom(
+FunctionPtr Function::InstantiateSignatureFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     intptr_t num_free_fun_type_params,
@@ -7897,7 +7954,7 @@
                                         Heap::Space space) const {
   const AbstractType& param_type =
       AbstractType::Handle(ParameterTypeAt(parameter_position));
-  if (param_type.IsTopType()) {
+  if (param_type.IsTopTypeForSubtyping()) {
     return true;
   }
   const AbstractType& other_param_type =
@@ -7932,7 +7989,7 @@
       ASSERT(bound.IsFinalized());
       other_bound = other_type_param.bound();
       ASSERT(other_bound.IsFinalized());
-      if (Dart::non_nullable_flag() && kind == TypeEquality::kInSubtypeTest) {
+      if (kind == TypeEquality::kInSubtypeTest) {
         // Bounds that are mutual subtypes are considered equal.
         if (!bound.IsSubtypeOf(other_bound, Heap::kOld) ||
             !other_bound.IsSubtypeOf(bound, Heap::kOld)) {
@@ -7980,7 +8037,7 @@
   const AbstractType& other_res_type =
       AbstractType::Handle(zone, other.result_type());
   // 'void Function()' is a subtype of 'Object Function()'.
-  if (!other_res_type.IsTopType()) {
+  if (!other_res_type.IsTopTypeForSubtyping()) {
     const AbstractType& res_type = AbstractType::Handle(zone, result_type());
     if (!res_type.IsSubtypeOf(other_res_type, space)) {
       return false;
@@ -8027,7 +8084,7 @@
     // Check that for each required named parameter in this function, there's a
     // corresponding required named parameter in the other function.
     String& param_name = other_param_name;
-    for (intptr_t j = num_fixed_params; j < num_params; j++) {
+    for (intptr_t j = num_params - num_opt_named_params; j < num_params; j++) {
       if (IsRequiredAt(j)) {
         param_name = ParameterNameAt(j);
         ASSERT(param_name.IsSymbol());
@@ -8057,32 +8114,32 @@
   return IsGenerativeConstructor() && (token_pos() == end_token_pos());
 }
 
-bool Function::IsImplicitStaticClosureFunction(RawFunction* func) {
+bool Function::IsImplicitStaticClosureFunction(FunctionPtr func) {
   NoSafepointScope no_safepoint;
   uint32_t kind_tag = func->ptr()->kind_tag_;
   return (KindBits::decode(kind_tag) ==
-          RawFunction::kImplicitClosureFunction) &&
+          FunctionLayout::kImplicitClosureFunction) &&
          StaticBit::decode(kind_tag);
 }
 
-RawFunction* Function::New(Heap::Space space) {
+FunctionPtr Function::New(Heap::Space space) {
   ASSERT(Object::function_class() != Class::null());
-  RawObject* raw =
+  ObjectPtr raw =
       Object::Allocate(Function::kClassId, Function::InstanceSize(), space);
-  return reinterpret_cast<RawFunction*>(raw);
+  return static_cast<FunctionPtr>(raw);
 }
 
-RawFunction* Function::New(const String& name,
-                           RawFunction::Kind kind,
-                           bool is_static,
-                           bool is_const,
-                           bool is_abstract,
-                           bool is_external,
-                           bool is_native,
-                           const Object& owner,
-                           TokenPosition token_pos,
-                           Heap::Space space) {
-  ASSERT(!owner.IsNull() || (kind == RawFunction::kSignatureFunction));
+FunctionPtr Function::New(const String& name,
+                          FunctionLayout::Kind kind,
+                          bool is_static,
+                          bool is_const,
+                          bool is_abstract,
+                          bool is_external,
+                          bool is_native,
+                          const Object& owner,
+                          TokenPosition token_pos,
+                          Heap::Space space) {
+  ASSERT(!owner.IsNull() || (kind == FunctionLayout::kSignatureFunction));
   const Function& result = Function::Handle(Function::New(space));
   result.set_kind_tag(0);
   result.set_parameter_types(Object::empty_array());
@@ -8091,7 +8148,7 @@
   result.set_kind_tag(0);  // Ensure determinism of uninitialized bits.
   result.set_kind(kind);
   result.set_recognized_kind(MethodRecognizer::kUnknown);
-  result.set_modifier(RawFunction::kNoModifier);
+  result.set_modifier(FunctionLayout::kNoModifier);
   result.set_is_static(is_static);
   result.set_is_const(is_const);
   result.set_is_abstract(is_abstract);
@@ -8124,16 +8181,16 @@
   result.set_is_inlinable(true);
   result.reset_unboxed_parameters_and_return();
   result.SetInstructionsSafe(StubCode::LazyCompile());
-  if (kind == RawFunction::kClosureFunction ||
-      kind == RawFunction::kImplicitClosureFunction) {
+  if (kind == FunctionLayout::kClosureFunction ||
+      kind == FunctionLayout::kImplicitClosureFunction) {
     ASSERT(space == Heap::kOld);
     const ClosureData& data = ClosureData::Handle(ClosureData::New());
     result.set_data(data);
-  } else if (kind == RawFunction::kSignatureFunction) {
+  } else if (kind == FunctionLayout::kSignatureFunction) {
     const SignatureData& data =
         SignatureData::Handle(SignatureData::New(space));
     result.set_data(data);
-  } else if (kind == RawFunction::kFfiTrampoline) {
+  } else if (kind == FunctionLayout::kFfiTrampoline) {
     const FfiTrampolineData& data =
         FfiTrampolineData::Handle(FfiTrampolineData::New());
     result.set_data(data);
@@ -8152,13 +8209,13 @@
   return result.raw();
 }
 
-RawFunction* Function::NewClosureFunctionWithKind(RawFunction::Kind kind,
-                                                  const String& name,
-                                                  const Function& parent,
-                                                  TokenPosition token_pos,
-                                                  const Object& owner) {
-  ASSERT((kind == RawFunction::kClosureFunction) ||
-         (kind == RawFunction::kImplicitClosureFunction));
+FunctionPtr Function::NewClosureFunctionWithKind(FunctionLayout::Kind kind,
+                                                 const String& name,
+                                                 const Function& parent,
+                                                 TokenPosition token_pos,
+                                                 const Object& owner) {
+  ASSERT((kind == FunctionLayout::kClosureFunction) ||
+         (kind == FunctionLayout::kImplicitClosureFunction));
   ASSERT(!parent.IsNull());
   ASSERT(!owner.IsNull());
   const Function& result = Function::Handle(
@@ -8172,30 +8229,30 @@
   return result.raw();
 }
 
-RawFunction* Function::NewClosureFunction(const String& name,
-                                          const Function& parent,
-                                          TokenPosition token_pos) {
+FunctionPtr Function::NewClosureFunction(const String& name,
+                                         const Function& parent,
+                                         TokenPosition token_pos) {
   // Use the owner defining the parent function and not the class containing it.
   const Object& parent_owner = Object::Handle(parent.RawOwner());
-  return NewClosureFunctionWithKind(RawFunction::kClosureFunction, name, parent,
-                                    token_pos, parent_owner);
-}
-
-RawFunction* Function::NewImplicitClosureFunction(const String& name,
-                                                  const Function& parent,
-                                                  TokenPosition token_pos) {
-  // Use the owner defining the parent function and not the class containing it.
-  const Object& parent_owner = Object::Handle(parent.RawOwner());
-  return NewClosureFunctionWithKind(RawFunction::kImplicitClosureFunction, name,
+  return NewClosureFunctionWithKind(FunctionLayout::kClosureFunction, name,
                                     parent, token_pos, parent_owner);
 }
 
-RawFunction* Function::NewSignatureFunction(const Object& owner,
-                                            const Function& parent,
-                                            TokenPosition token_pos,
-                                            Heap::Space space) {
+FunctionPtr Function::NewImplicitClosureFunction(const String& name,
+                                                 const Function& parent,
+                                                 TokenPosition token_pos) {
+  // Use the owner defining the parent function and not the class containing it.
+  const Object& parent_owner = Object::Handle(parent.RawOwner());
+  return NewClosureFunctionWithKind(FunctionLayout::kImplicitClosureFunction,
+                                    name, parent, token_pos, parent_owner);
+}
+
+FunctionPtr Function::NewSignatureFunction(const Object& owner,
+                                           const Function& parent,
+                                           TokenPosition token_pos,
+                                           Heap::Space space) {
   const Function& result = Function::Handle(Function::New(
-      Symbols::AnonymousSignature(), RawFunction::kSignatureFunction,
+      Symbols::AnonymousSignature(), FunctionLayout::kSignatureFunction,
       /* is_static = */ false,
       /* is_const = */ false,
       /* is_abstract = */ false,
@@ -8210,15 +8267,15 @@
   return result.raw();
 }
 
-RawFunction* Function::NewEvalFunction(const Class& owner,
-                                       const Script& script,
-                                       bool is_static) {
+FunctionPtr Function::NewEvalFunction(const Class& owner,
+                                      const Script& script,
+                                      bool is_static) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const Function& result = Function::Handle(
       zone,
       Function::New(String::Handle(Symbols::New(thread, ":Eval")),
-                    RawFunction::kRegularFunction, is_static,
+                    FunctionLayout::kRegularFunction, is_static,
                     /* is_const = */ false,
                     /* is_abstract = */ false,
                     /* is_external = */ false,
@@ -8238,7 +8295,7 @@
 #endif
 }
 
-RawFunction* Function::ImplicitClosureFunction() const {
+FunctionPtr Function::ImplicitClosureFunction() const {
   // Return the existing implicit closure function if any.
   if (implicit_closure_function() != Function::null()) {
     return implicit_closure_function();
@@ -8323,12 +8380,10 @@
                                     &is_generic_covariant_impl);
 
     Type& object_type = Type::Handle(zone, Type::ObjectType());
-    if (Dart::non_nullable_flag()) {
-      ObjectStore* object_store = Isolate::Current()->object_store();
-      object_type = nnbd_mode() == NNBDMode::kOptedInLib
-                        ? object_store->nullable_object_type()
-                        : object_store->legacy_object_type();
-    }
+    ObjectStore* object_store = Isolate::Current()->object_store();
+    object_type = nnbd_mode() == NNBDMode::kOptedInLib
+                      ? object_store->nullable_object_type()
+                      : object_store->legacy_object_type();
     for (intptr_t i = kClosure; i < num_params; ++i) {
       const intptr_t original_param_index = has_receiver - kClosure + i;
       if (is_covariant.Contains(original_param_index) ||
@@ -8357,14 +8412,14 @@
   }
 }
 
-RawString* Function::Signature() const {
+StringPtr Function::Signature() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintSignature(kInternalName, &printer);
   return Symbols::New(thread, printer.buffer());
 }
 
-RawString* Function::UserVisibleSignature() const {
+StringPtr Function::UserVisibleSignature() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintSignature(kUserVisibleName, &printer);
@@ -8404,7 +8459,7 @@
       printer->AddString("{");
     }
     for (intptr_t i = num_fixed_params; i < num_params; i++) {
-      if (IsRequiredAt(i)) {
+      if (num_opt_named_params > 0 && IsRequiredAt(i)) {
         printer->AddString("required ");
       }
       param_type = ParameterTypeAt(i);
@@ -8429,7 +8484,7 @@
   }
 }
 
-RawInstance* Function::ImplicitStaticClosure() const {
+InstancePtr Function::ImplicitStaticClosure() const {
   ASSERT(IsImplicitStaticClosureFunction());
   if (implicit_static_closure() == Instance::null()) {
     Zone* zone = Thread::Current()->zone();
@@ -8443,7 +8498,7 @@
   return implicit_static_closure();
 }
 
-RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const {
+InstancePtr Function::ImplicitInstanceClosure(const Instance& receiver) const {
   ASSERT(IsImplicitClosureFunction());
   Zone* zone = Thread::Current()->zone();
   const Context& context = Context::Handle(zone, Context::New(1));
@@ -8549,7 +8604,7 @@
   return true;
 }
 
-RawClass* Function::Owner() const {
+ClassPtr Function::Owner() const {
   if (raw_ptr()->owner_ == Object::null()) {
     ASSERT(IsSignatureFunction());
     return Class::null();
@@ -8562,7 +8617,7 @@
   return PatchClass::Cast(obj).patched_class();
 }
 
-RawClass* Function::origin() const {
+ClassPtr Function::origin() const {
   if (raw_ptr()->owner_ == Object::null()) {
     ASSERT(IsSignatureFunction());
     return Class::null();
@@ -8607,7 +8662,7 @@
   set_data(data_field);
 }
 
-RawScript* Function::script() const {
+ScriptPtr Function::script() const {
   // NOTE(turnidge): If you update this function, you probably want to
   // update Class::PatchFieldsAndFunctions() at the same time.
   Object& data = Object::Handle(raw_ptr()->data_);
@@ -8640,7 +8695,7 @@
   return Class::Cast(obj).script();
 }
 
-RawExternalTypedData* Function::KernelData() const {
+ExternalTypedDataPtr Function::KernelData() const {
   Object& data = Object::Handle(raw_ptr()->data_);
   if (data.IsArray()) {
     Object& script = Object::Handle(Array::Cast(data).At(0));
@@ -8709,7 +8764,7 @@
   return String::ScrubName(String::Handle(name()), is_extension_member());
 }
 
-RawString* Function::UserVisibleName() const {
+StringPtr Function::UserVisibleName() const {
   if (FLAG_show_internal_names) {
     return name();
   }
@@ -8718,14 +8773,14 @@
       String::ScrubName(String::Handle(name()), is_extension_member()));
 }
 
-RawString* Function::QualifiedScrubbedName() const {
+StringPtr Function::QualifiedScrubbedName() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintQualifiedName(kScrubbedName, &printer);
   return Symbols::New(thread, printer.buffer());
 }
 
-RawString* Function::QualifiedUserVisibleName() const {
+StringPtr Function::QualifiedUserVisibleName() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintQualifiedName(kUserVisibleName, &printer);
@@ -8767,7 +8822,7 @@
   }
   const Class& cls = Class::Handle(Owner());
   if (!cls.IsTopLevel()) {
-    if (fun.kind() == RawFunction::kConstructor) {
+    if (fun.kind() == FunctionLayout::kConstructor) {
       printer->AddString("new ");
     } else {
       const Class& mixin = Class::Handle(cls.Mixin());
@@ -8781,7 +8836,7 @@
   printer->AddString(fun.UserVisibleNameCString());
 }
 
-RawString* Function::GetSource() const {
+StringPtr Function::GetSource() const {
   if (IsImplicitConstructor() || IsSignatureFunction() || is_synthetic()) {
     // We may need to handle more cases when the restrictions on mixins are
     // relaxed. In particular we might start associating some source with the
@@ -8909,12 +8964,12 @@
 }
 
 void Function::set_ic_data_array(const Array& value) const {
-  StorePointer<RawArray*, std::memory_order_release>(&raw_ptr()->ic_data_array_,
-                                                     value.raw());
+  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->ic_data_array_,
+                                                    value.raw());
 }
 
-RawArray* Function::ic_data_array() const {
-  return LoadPointer<RawArray*, std::memory_order_acquire>(
+ArrayPtr Function::ic_data_array() const {
+  return LoadPointer<ArrayPtr, std::memory_order_acquire>(
       &raw_ptr()->ic_data_array_);
 }
 
@@ -8922,7 +8977,7 @@
   set_ic_data_array(Array::null_array());
 }
 
-RawICData* Function::FindICData(intptr_t deopt_id) const {
+ICDataPtr Function::FindICData(intptr_t deopt_id) const {
   const Array& array = Array::Handle(ic_data_array());
   ICData& ic_data = ICData::Handle();
   for (intptr_t i = 1; i < array.Length(); i++) {
@@ -8958,12 +9013,12 @@
     return true;
   }
 
-  if (Dart::non_nullable_flag()) {
-    // The non-nullable experiment changes the fingerprints, and we only track
-    // one fingerprint set.
-    return true;
-  }
-
+#if 1
+  // The non-nullable experiment changes the fingerprints, we only track
+  // one fingerprint set, until we unfork and settle on a single snapshot
+  // version this check has to be bypassed.
+  // TODO(36376) - Restore checking fingerprints of recognized methods.
+#else
   if (SourceFingerprint() != fp) {
     const bool recalculatingFingerprints = false;
     if (recalculatingFingerprints) {
@@ -8982,10 +9037,11 @@
       return false;
     }
   }
+#endif
   return true;
 }
 
-RawCode* Function::EnsureHasCode() const {
+CodePtr Function::EnsureHasCode() const {
   if (HasCode()) return CurrentCode();
   Thread* thread = Thread::Current();
   ASSERT(thread->IsMutatorThread());
@@ -9028,17 +9084,11 @@
     return true;
   }
 
-  // Method extractors are always called dynamically (for now).
-  // See dartbug.com/40188.
-  if (IsMethodExtractor()) {
-    return true;
-  }
-
   // Use the results of TFA to determine whether this function is ever
   // called dynamically, i.e. using switchable calls.
   kernel::ProcedureAttributesMetadata metadata;
   metadata = kernel::ProcedureAttributesOf(*this, zone);
-  if (IsGetterFunction() || IsImplicitGetterFunction()) {
+  if (IsGetterFunction() || IsImplicitGetterFunction() || IsMethodExtractor()) {
     return metadata.getter_called_dynamically;
   } else {
     return metadata.method_or_setter_called_dynamically;
@@ -9064,47 +9114,47 @@
   const char* kind_str = NULL;
   const char* const_str = is_const() ? " const" : "";
   switch (kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kClosureFunction:
-    case RawFunction::kImplicitClosureFunction:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kImplicitClosureFunction:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
       kind_str = "";
       break;
-    case RawFunction::kSignatureFunction:
+    case FunctionLayout::kSignatureFunction:
       kind_str = " signature";
       break;
-    case RawFunction::kConstructor:
+    case FunctionLayout::kConstructor:
       kind_str = is_static() ? " factory" : " constructor";
       break;
-    case RawFunction::kImplicitGetter:
+    case FunctionLayout::kImplicitGetter:
       kind_str = " getter";
       break;
-    case RawFunction::kImplicitSetter:
+    case FunctionLayout::kImplicitSetter:
       kind_str = " setter";
       break;
-    case RawFunction::kImplicitStaticGetter:
+    case FunctionLayout::kImplicitStaticGetter:
       kind_str = " static-getter";
       break;
-    case RawFunction::kFieldInitializer:
+    case FunctionLayout::kFieldInitializer:
       kind_str = " field-initializer";
       break;
-    case RawFunction::kMethodExtractor:
+    case FunctionLayout::kMethodExtractor:
       kind_str = " method-extractor";
       break;
-    case RawFunction::kNoSuchMethodDispatcher:
+    case FunctionLayout::kNoSuchMethodDispatcher:
       kind_str = " no-such-method-dispatcher";
       break;
-    case RawFunction::kDynamicInvocationForwarder:
+    case FunctionLayout::kDynamicInvocationForwarder:
       kind_str = " dynamic-invocation-forwarder";
       break;
-    case RawFunction::kInvokeFieldDispatcher:
+    case FunctionLayout::kInvokeFieldDispatcher:
       kind_str = " invoke-field-dispatcher";
       break;
-    case RawFunction::kIrregexpFunction:
+    case FunctionLayout::kIrregexpFunction:
       kind_str = " irregexp-function";
       break;
-    case RawFunction::kFfiTrampoline:
+    case FunctionLayout::kFfiTrampoline:
       kind_str = " ffi-trampoline-function";
       break;
     default:
@@ -9134,11 +9184,11 @@
   StorePointer(&raw_ptr()->signature_type_, value.raw());
 }
 
-RawClosureData* ClosureData::New() {
+ClosureDataPtr ClosureData::New() {
   ASSERT(Object::closure_data_class() != Class::null());
-  RawObject* raw = Object::Allocate(ClosureData::kClassId,
-                                    ClosureData::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawClosureData*>(raw);
+  ObjectPtr raw = Object::Allocate(ClosureData::kClassId,
+                                   ClosureData::InstanceSize(), Heap::kOld);
+  return static_cast<ClosureDataPtr>(raw);
 }
 
 const char* ClosureData::ToCString() const {
@@ -9151,10 +9201,10 @@
                      "ClosureData: context_scope: 0x%" Px
                      " parent_function: %s signature_type: %s"
                      " implicit_static_closure: 0x%" Px,
-                     reinterpret_cast<uword>(context_scope()),
+                     static_cast<uword>(context_scope()),
                      parent.IsNull() ? "null" : parent.ToCString(),
                      type.IsNull() ? "null" : type.ToCString(),
-                     reinterpret_cast<uword>(implicit_static_closure()));
+                     static_cast<uword>(implicit_static_closure()));
 }
 
 void SignatureData::set_parent_function(const Function& value) const {
@@ -9165,11 +9215,11 @@
   StorePointer(&raw_ptr()->signature_type_, value.raw());
 }
 
-RawSignatureData* SignatureData::New(Heap::Space space) {
+SignatureDataPtr SignatureData::New(Heap::Space space) {
   ASSERT(Object::signature_data_class() != Class::null());
-  RawObject* raw = Object::Allocate(SignatureData::kClassId,
-                                    SignatureData::InstanceSize(), space);
-  return reinterpret_cast<RawSignatureData*>(raw);
+  ObjectPtr raw = Object::Allocate(SignatureData::kClassId,
+                                   SignatureData::InstanceSize(), space);
+  return static_cast<SignatureDataPtr>(raw);
 }
 
 const char* SignatureData::ToCString() const {
@@ -9197,11 +9247,11 @@
   StorePointer(&raw_ptr()->target_, value.raw());
 }
 
-RawRedirectionData* RedirectionData::New() {
+RedirectionDataPtr RedirectionData::New() {
   ASSERT(Object::redirection_data_class() != Class::null());
-  RawObject* raw = Object::Allocate(
-      RedirectionData::kClassId, RedirectionData::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawRedirectionData*>(raw);
+  ObjectPtr raw = Object::Allocate(RedirectionData::kClassId,
+                                   RedirectionData::InstanceSize(), Heap::kOld);
+  return static_cast<RedirectionDataPtr>(raw);
 }
 
 const char* RedirectionData::ToCString() const {
@@ -9239,12 +9289,12 @@
   StorePointer(&raw_ptr()->callback_exceptional_return_, value.raw());
 }
 
-RawFfiTrampolineData* FfiTrampolineData::New() {
+FfiTrampolineDataPtr FfiTrampolineData::New() {
   ASSERT(Object::ffi_trampoline_data_class() != Class::null());
-  RawObject* raw =
+  ObjectPtr raw =
       Object::Allocate(FfiTrampolineData::kClassId,
                        FfiTrampolineData::InstanceSize(), Heap::kOld);
-  RawFfiTrampolineData* data = reinterpret_cast<RawFfiTrampolineData*>(raw);
+  FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(raw);
   data->ptr()->callback_id_ = 0;
   return data;
 }
@@ -9258,11 +9308,11 @@
       signature_type_name.IsNull() ? "null" : signature_type_name.ToCString());
 }
 
-RawField* Field::CloneFromOriginal() const {
+FieldPtr Field::CloneFromOriginal() const {
   return this->Clone(*this);
 }
 
-RawField* Field::Original() const {
+FieldPtr Field::Original() const {
   if (IsNull()) {
     return Field::null();
   }
@@ -9292,44 +9342,44 @@
 void Field::SetOriginal(const Field& value) const {
   ASSERT(value.IsOriginal());
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
+  StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
 }
 
-RawString* Field::GetterName(const String& field_name) {
+StringPtr Field::GetterName(const String& field_name) {
   return String::Concat(Symbols::GetterPrefix(), field_name);
 }
 
-RawString* Field::GetterSymbol(const String& field_name) {
+StringPtr Field::GetterSymbol(const String& field_name) {
   return Symbols::FromGet(Thread::Current(), field_name);
 }
 
-RawString* Field::LookupGetterSymbol(const String& field_name) {
+StringPtr Field::LookupGetterSymbol(const String& field_name) {
   return Symbols::LookupFromGet(Thread::Current(), field_name);
 }
 
-RawString* Field::SetterName(const String& field_name) {
+StringPtr Field::SetterName(const String& field_name) {
   return String::Concat(Symbols::SetterPrefix(), field_name);
 }
 
-RawString* Field::SetterSymbol(const String& field_name) {
+StringPtr Field::SetterSymbol(const String& field_name) {
   return Symbols::FromSet(Thread::Current(), field_name);
 }
 
-RawString* Field::LookupSetterSymbol(const String& field_name) {
+StringPtr Field::LookupSetterSymbol(const String& field_name) {
   return Symbols::LookupFromSet(Thread::Current(), field_name);
 }
 
-RawString* Field::NameFromGetter(const String& getter_name) {
+StringPtr Field::NameFromGetter(const String& getter_name) {
   return Symbols::New(Thread::Current(), getter_name, kGetterPrefixLength,
                       getter_name.Length() - kGetterPrefixLength);
 }
 
-RawString* Field::NameFromSetter(const String& setter_name) {
+StringPtr Field::NameFromSetter(const String& setter_name) {
   return Symbols::New(Thread::Current(), setter_name, kSetterPrefixLength,
                       setter_name.Length() - kSetterPrefixLength);
 }
 
-RawString* Field::NameFromInit(const String& init_name) {
+StringPtr Field::NameFromInit(const String& init_name) {
   return Symbols::New(Thread::Current(), init_name, kInitPrefixLength,
                       init_name.Length() - kInitPrefixLength);
 }
@@ -9352,7 +9402,7 @@
   StorePointer(&raw_ptr()->name_, value.raw());
 }
 
-RawObject* Field::RawOwner() const {
+ObjectPtr Field::RawOwner() const {
   if (IsOriginal()) {
     return raw_ptr()->owner_;
   } else {
@@ -9363,7 +9413,7 @@
   }
 }
 
-RawClass* Field::Owner() const {
+ClassPtr Field::Owner() const {
   const Field& field = Field::Handle(Original());
   ASSERT(field.IsOriginal());
   const Object& obj = Object::Handle(field.raw_ptr()->owner_);
@@ -9374,7 +9424,7 @@
   return PatchClass::Cast(obj).patched_class();
 }
 
-RawClass* Field::Origin() const {
+ClassPtr Field::Origin() const {
   const Field& field = Field::Handle(Original());
   ASSERT(field.IsOriginal());
   const Object& obj = Object::Handle(field.raw_ptr()->owner_);
@@ -9385,7 +9435,7 @@
   return PatchClass::Cast(obj).origin_class();
 }
 
-RawScript* Field::Script() const {
+ScriptPtr Field::Script() const {
   // NOTE(turnidge): If you update this function, you probably want to
   // update Class::PatchFieldsAndFunctions() at the same time.
   const Field& field = Field::Handle(Original());
@@ -9398,7 +9448,7 @@
   return PatchClass::Cast(obj).script();
 }
 
-RawExternalTypedData* Field::KernelData() const {
+ExternalTypedDataPtr Field::KernelData() const {
   const Object& obj = Object::Handle(this->raw_ptr()->owner_);
   // During background JIT compilation field objects are copied
   // and copy points to the original field via the owner field.
@@ -9447,11 +9497,11 @@
   }
 }
 
-RawField* Field::New() {
+FieldPtr Field::New() {
   ASSERT(Object::field_class() != Class::null());
-  RawObject* raw =
+  ObjectPtr raw =
       Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawField*>(raw);
+  return static_cast<FieldPtr>(raw);
 }
 
 void Field::InitializeNew(const Field& result,
@@ -9519,16 +9569,16 @@
   }
 }
 
-RawField* Field::New(const String& name,
-                     bool is_static,
-                     bool is_final,
-                     bool is_const,
-                     bool is_reflectable,
-                     bool is_late,
-                     const Object& owner,
-                     const AbstractType& type,
-                     TokenPosition token_pos,
-                     TokenPosition end_token_pos) {
+FieldPtr Field::New(const String& name,
+                    bool is_static,
+                    bool is_final,
+                    bool is_const,
+                    bool is_reflectable,
+                    bool is_late,
+                    const Object& owner,
+                    const AbstractType& type,
+                    TokenPosition token_pos,
+                    TokenPosition end_token_pos) {
   ASSERT(!owner.IsNull());
   const Field& result = Field::Handle(Field::New());
   InitializeNew(result, name, is_static, is_final, is_const, is_reflectable,
@@ -9537,13 +9587,13 @@
   return result.raw();
 }
 
-RawField* Field::NewTopLevel(const String& name,
-                             bool is_final,
-                             bool is_const,
-                             bool is_late,
-                             const Object& owner,
-                             TokenPosition token_pos,
-                             TokenPosition end_token_pos) {
+FieldPtr Field::NewTopLevel(const String& name,
+                            bool is_final,
+                            bool is_const,
+                            bool is_late,
+                            const Object& owner,
+                            TokenPosition token_pos,
+                            TokenPosition end_token_pos) {
   ASSERT(!owner.IsNull());
   const Field& result = Field::Handle(Field::New());
   InitializeNew(result, name, true,       /* is_static */
@@ -9552,7 +9602,7 @@
   return result.raw();
 }
 
-RawField* Field::Clone(const Field& original) const {
+FieldPtr Field::Clone(const Field& original) const {
   if (original.IsNull()) {
     return Field::null();
   }
@@ -9576,7 +9626,7 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
-RawString* Field::InitializingExpression() const {
+StringPtr Field::InitializingExpression() const {
   UNREACHABLE();
   return String::null();
 }
@@ -9589,7 +9639,7 @@
   return String::ScrubName(String::Handle(name()), is_extension_member());
 }
 
-RawString* Field::UserVisibleName() const {
+StringPtr Field::UserVisibleName() const {
   if (FLAG_show_internal_names) {
     return name();
   }
@@ -9675,7 +9725,7 @@
 // Build a closure object that gets (or sets) the contents of a static
 // field f and cache the closure in a newly created static field
 // named #f (or #f= in case of a setter).
-RawInstance* Field::AccessorClosure(bool make_setter) const {
+InstancePtr Field::AccessorClosure(bool make_setter) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(is_static());
@@ -9703,15 +9753,15 @@
   return Instance::null();
 }
 
-RawInstance* Field::GetterClosure() const {
+InstancePtr Field::GetterClosure() const {
   return AccessorClosure(false);
 }
 
-RawInstance* Field::SetterClosure() const {
+InstancePtr Field::SetterClosure() const {
   return AccessorClosure(true);
 }
 
-RawArray* Field::dependent_code() const {
+ArrayPtr Field::dependent_code() const {
   return raw_ptr()->dependent_code_;
 }
 
@@ -9784,12 +9834,12 @@
 bool Field::IsUninitialized() const {
   Thread* thread = Thread::Current();
   const FieldTable* field_table = thread->isolate()->field_table();
-  const RawInstance* raw_value = field_table->At(field_id());
+  const InstancePtr raw_value = field_table->At(field_id());
   ASSERT(raw_value != Object::transition_sentinel().raw());
   return raw_value == Object::sentinel().raw();
 }
 
-RawFunction* Field::EnsureInitializerFunction() const {
+FunctionPtr Field::EnsureInitializerFunction() const {
   ASSERT(has_nontrivial_initializer());
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -9814,7 +9864,7 @@
   return raw_ptr()->initializer_function_ != Function::null();
 }
 
-RawError* Field::InitializeInstance(const Instance& instance) const {
+ErrorPtr Field::InitializeInstance(const Instance& instance) const {
   ASSERT(IsOriginal());
   ASSERT(is_instance());
   ASSERT(instance.GetField(*this) == Object::sentinel().raw());
@@ -9828,6 +9878,10 @@
       return Error::Cast(value).raw();
     }
   } else {
+    if (is_late() && !has_initializer()) {
+      Exceptions::ThrowLateInitializationError(String::Handle(name()));
+      UNREACHABLE();
+    }
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
 #else
@@ -9835,25 +9889,47 @@
 #endif
   }
   ASSERT(value.IsNull() || value.IsInstance());
+  if (is_late() && is_final() &&
+      (instance.GetField(*this) != Object::sentinel().raw())) {
+    Exceptions::ThrowLateInitializationError(String::Handle(name()));
+    UNREACHABLE();
+  }
   instance.SetField(*this, value);
   return Error::null();
 }
 
-RawError* Field::InitializeStatic() const {
+ErrorPtr Field::InitializeStatic() const {
   ASSERT(IsOriginal());
   ASSERT(is_static());
   if (StaticValue() == Object::sentinel().raw()) {
-    SetStaticValue(Object::transition_sentinel());
-    const Object& value = Object::Handle(EvaluateInitializer());
-    if (!value.IsNull() && value.IsError()) {
-      SetStaticValue(Object::null_instance());
-      return Error::Cast(value).raw();
+    auto& value = Object::Handle();
+    if (is_late()) {
+      if (!has_initializer()) {
+        Exceptions::ThrowLateInitializationError(String::Handle(name()));
+        UNREACHABLE();
+      }
+      value = EvaluateInitializer();
+      if (value.IsError()) {
+        return Error::Cast(value).raw();
+      }
+      if (is_final() && (StaticValue() != Object::sentinel().raw())) {
+        Exceptions::ThrowLateInitializationError(String::Handle(name()));
+        UNREACHABLE();
+      }
+    } else {
+      SetStaticValue(Object::transition_sentinel());
+      value = EvaluateInitializer();
+      if (value.IsError()) {
+        SetStaticValue(Object::null_instance());
+        return Error::Cast(value).raw();
+      }
     }
     ASSERT(value.IsNull() || value.IsInstance());
     SetStaticValue(value.IsNull() ? Instance::null_instance()
                                   : Instance::Cast(value));
     return Error::null();
   } else if (StaticValue() == Object::transition_sentinel().raw()) {
+    ASSERT(!is_late());
     const Array& ctor_args = Array::Handle(Array::New(1));
     const String& field_name = String::Handle(name());
     ctor_args.SetAt(0, field_name);
@@ -9863,7 +9939,7 @@
   return Error::null();
 }
 
-RawObject* Field::EvaluateInitializer() const {
+ObjectPtr Field::EvaluateInitializer() const {
   Thread* const thread = Thread::Current();
   ASSERT(thread->IsMutatorThread());
   NoOOBMessageScope no_msg_scope(thread);
@@ -9886,9 +9962,8 @@
 }
 
 static intptr_t GetListLengthOffset(intptr_t cid) {
-  if (RawObject::IsTypedDataClassId(cid) ||
-      RawObject::IsTypedDataViewClassId(cid) ||
-      RawObject::IsExternalTypedDataClassId(cid)) {
+  if (IsTypedDataClassId(cid) || IsTypedDataViewClassId(cid) ||
+      IsExternalTypedDataClassId(cid)) {
     return TypedData::length_offset();
   } else if (cid == kArrayCid || cid == kImmutableArrayCid) {
     return Array::length_offset();
@@ -9919,8 +9994,7 @@
       Class::Handle(Isolate::Current()->class_table()->At(guarded_cid()));
   const char* class_name = String::Handle(cls.Name()).ToCString();
 
-  if (RawObject::IsBuiltinListClassId(guarded_cid()) && !is_nullable() &&
-      is_final()) {
+  if (IsBuiltinListClassId(guarded_cid()) && !is_nullable() && is_final()) {
     ASSERT(guarded_list_length() != kUnknownFixedLength);
     if (guarded_list_length() == kNoFixedLength) {
       return zone->PrintToString("<%s [*]%s>", class_name, exactness);
@@ -10343,7 +10417,7 @@
   return raw_ptr()->source_ != String::null();
 }
 
-RawString* Script::Source() const {
+StringPtr Script::Source() const {
   return raw_ptr()->source_;
 }
 
@@ -10375,7 +10449,7 @@
   StoreNonPointer(&raw_ptr()->kernel_script_index_, kernel_script_index);
 }
 
-RawTypedData* Script::kernel_string_offsets() const {
+TypedDataPtr Script::kernel_string_offsets() const {
   KernelProgramInfo& program_info =
       KernelProgramInfo::Handle(kernel_program_info());
   ASSERT(!program_info.IsNull());
@@ -10414,7 +10488,7 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
-RawGrowableObjectArray* Script::GenerateLineNumberArray() const {
+GrowableObjectArrayPtr Script::GenerateLineNumberArray() const {
   Zone* zone = Thread::Current()->zone();
   const GrowableObjectArray& info =
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
@@ -10489,11 +10563,11 @@
   StorePointer(&raw_ptr()->debug_positions_, value.raw());
 }
 
-RawTypedData* Script::line_starts() const {
+TypedDataPtr Script::line_starts() const {
   return raw_ptr()->line_starts_;
 }
 
-RawArray* Script::debug_positions() const {
+ArrayPtr Script::debug_positions() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_);
   if (debug_positions_array.IsNull()) {
@@ -10509,12 +10583,13 @@
 }
 
 void Script::SetLazyLookupSourceAndLineStarts(bool value) const {
-  set_flags(RawScript::LazyLookupSourceAndLineStartsBit::update(
+  set_flags(ScriptLayout::LazyLookupSourceAndLineStartsBit::update(
       value, raw_ptr()->flags_));
 }
 
 bool Script::IsLazyLookupSourceAndLineStarts() const {
-  return RawScript::LazyLookupSourceAndLineStartsBit::decode(raw_ptr()->flags_);
+  return ScriptLayout::LazyLookupSourceAndLineStartsBit::decode(
+      raw_ptr()->flags_);
 }
 
 void Script::set_load_timestamp(int64_t value) const {
@@ -10646,7 +10721,7 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
-RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const {
+StringPtr Script::GetLine(intptr_t line_number, Heap::Space space) const {
   const String& src = String::Handle(Source());
   if (src.IsNull()) {
     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
@@ -10681,7 +10756,7 @@
   }
 }
 
-RawString* Script::GetSnippet(TokenPosition from, TokenPosition to) const {
+StringPtr Script::GetSnippet(TokenPosition from, TokenPosition to) const {
   intptr_t from_line;
   intptr_t from_column;
   intptr_t to_line;
@@ -10691,10 +10766,10 @@
   return GetSnippet(from_line, from_column, to_line, to_column);
 }
 
-RawString* Script::GetSnippet(intptr_t from_line,
-                              intptr_t from_column,
-                              intptr_t to_line,
-                              intptr_t to_column) const {
+StringPtr Script::GetSnippet(intptr_t from_line,
+                             intptr_t from_column,
+                             intptr_t to_line,
+                             intptr_t to_column) const {
   const String& src = String::Handle(Source());
   if (src.IsNull()) {
     return Symbols::OptimizedOut().raw();
@@ -10744,20 +10819,20 @@
   return snippet.raw();
 }
 
-RawScript* Script::New() {
+ScriptPtr Script::New() {
   ASSERT(Object::script_class() != Class::null());
-  RawObject* raw =
+  ObjectPtr raw =
       Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawScript*>(raw);
+  return static_cast<ScriptPtr>(raw);
 }
 
-RawScript* Script::New(const String& url, const String& source) {
+ScriptPtr Script::New(const String& url, const String& source) {
   return Script::New(url, url, source);
 }
 
-RawScript* Script::New(const String& url,
-                       const String& resolved_url,
-                       const String& source) {
+ScriptPtr Script::New(const String& url,
+                      const String& resolved_url,
+                      const String& source) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const Script& result = Script::Handle(zone, Script::New());
@@ -10778,7 +10853,7 @@
   return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString());
 }
 
-RawLibrary* Script::FindLibrary() const {
+LibraryPtr Script::FindLibrary() const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -10806,7 +10881,7 @@
   MoveToNextObject();
 }
 
-RawObject* DictionaryIterator::GetNext() {
+ObjectPtr DictionaryIterator::GetNext() {
   ASSERT(HasNext());
   int ix = next_ix_++;
   MoveToNextObject();
@@ -10831,7 +10906,7 @@
   MoveToNextClass();
 }
 
-RawClass* ClassDictionaryIterator::GetNextClass() {
+ClassPtr ClassDictionaryIterator::GetNextClass() {
   ASSERT(HasNext());
   Class& cls = Class::Handle();
   if (next_ix_ < size_) {
@@ -10862,7 +10937,7 @@
   Advance();
 }
 
-RawLibraryPrefix* LibraryPrefixIterator::GetNext() {
+LibraryPrefixPtr LibraryPrefixIterator::GetNext() {
   ASSERT(HasNext());
   int ix = next_ix_++;
   Object& obj = Object::Handle(array_.At(ix));
@@ -10921,32 +10996,32 @@
 
 void Library::SetLoadInProgress() const {
   // Must not already be in the process of being loaded.
-  ASSERT(raw_ptr()->load_state_ <= RawLibrary::kLoadRequested);
-  StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadInProgress);
+  ASSERT(raw_ptr()->load_state_ <= LibraryLayout::kLoadRequested);
+  StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoadInProgress);
 }
 
 void Library::SetLoadRequested() const {
   // Must not be already loaded.
-  ASSERT(raw_ptr()->load_state_ == RawLibrary::kAllocated);
-  StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadRequested);
+  ASSERT(raw_ptr()->load_state_ == LibraryLayout::kAllocated);
+  StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoadRequested);
 }
 
 void Library::SetLoaded() const {
   // Should not be already loaded or just allocated.
   ASSERT(LoadInProgress() || LoadRequested());
-  StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoaded);
+  StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoaded);
 }
 
-static RawString* MakeClassMetaName(Thread* thread,
-                                    Zone* zone,
-                                    const Class& cls) {
+static StringPtr MakeClassMetaName(Thread* thread,
+                                   Zone* zone,
+                                   const Class& cls) {
   return Symbols::FromConcat(thread, Symbols::At(),
                              String::Handle(zone, cls.Name()));
 }
 
-static RawString* MakeFieldMetaName(Thread* thread,
-                                    Zone* zone,
-                                    const Field& field) {
+static StringPtr MakeFieldMetaName(Thread* thread,
+                                   Zone* zone,
+                                   const Field& field) {
   const String& cname = String::Handle(
       zone,
       MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin())));
@@ -10957,9 +11032,9 @@
   return Symbols::FromConcatAll(thread, pieces);
 }
 
-static RawString* MakeFunctionMetaName(Thread* thread,
-                                       Zone* zone,
-                                       const Function& func) {
+static StringPtr MakeFunctionMetaName(Thread* thread,
+                                      Zone* zone,
+                                      const Function& func) {
   const String& cname = String::Handle(
       zone,
       MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin())));
@@ -10970,9 +11045,9 @@
   return Symbols::FromConcatAll(thread, pieces);
 }
 
-static RawString* MakeTypeParameterMetaName(Thread* thread,
-                                            Zone* zone,
-                                            const TypeParameter& param) {
+static StringPtr MakeTypeParameterMetaName(Thread* thread,
+                                           Zone* zone,
+                                           const TypeParameter& param) {
   const String& cname = String::Handle(
       zone,
       MakeClassMetaName(thread, zone,
@@ -11073,7 +11148,7 @@
               bytecode_offset);
 }
 
-RawString* Library::MakeMetadataName(const Object& obj) const {
+StringPtr Library::MakeMetadataName(const Object& obj) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   if (obj.IsClass()) {
@@ -11091,7 +11166,7 @@
   return String::null();
 }
 
-RawField* Library::GetMetadataField(const String& metaname) const {
+FieldPtr Library::GetMetadataField(const String& metaname) const {
   const GrowableObjectArray& metadata =
       GrowableObjectArray::Handle(this->metadata());
   Field& entry = Field::Handle();
@@ -11124,7 +11199,7 @@
   }
 }
 
-RawObject* Library::GetMetadata(const Object& obj) const {
+ObjectPtr Library::GetMetadata(const Object& obj) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   return Object::empty_array().raw();
 #else
@@ -11172,8 +11247,7 @@
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-RawArray* Library::GetExtendedMetadata(const Object& obj,
-                                       intptr_t count) const {
+ArrayPtr Library::GetExtendedMetadata(const Object& obj, intptr_t count) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   return Object::empty_array().raw();
 #else
@@ -11198,7 +11272,7 @@
            name.CharAt(3) == ':'));
 }
 
-RawObject* Library::ResolveName(const String& name) const {
+ObjectPtr Library::ResolveName(const String& name) const {
   Object& obj = Object::Handle();
   if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) {
     return obj.raw();
@@ -11427,8 +11501,8 @@
 // Lookup a name in the library's re-export namespace.
 // This lookup can occur from two different threads: background compiler and
 // mutator thread.
-RawObject* Library::LookupReExport(const String& name,
-                                   ZoneGrowableArray<intptr_t>* trail) const {
+ObjectPtr Library::LookupReExport(const String& name,
+                                  ZoneGrowableArray<intptr_t>* trail) const {
   if (!HasExports()) {
     return Object::null();
   }
@@ -11466,7 +11540,7 @@
   return obj.raw();
 }
 
-RawObject* Library::LookupEntry(const String& name, intptr_t* index) const {
+ObjectPtr Library::LookupEntry(const String& name, intptr_t* index) const {
   ASSERT(!IsNull());
   Thread* thread = Thread::Current();
   REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -11519,7 +11593,7 @@
   scripts.Add(candidate);
 }
 
-RawArray* Library::LoadedScripts() const {
+ArrayPtr Library::LoadedScripts() const {
   ASSERT(Thread::Current()->IsMutatorThread());
   // We compute the list of loaded scripts lazily. The result is
   // cached in loaded_scripts_.
@@ -11589,8 +11663,8 @@
 
 // TODO(hausner): we might want to add a script dictionary to the
 // library class to make this lookup faster.
-RawScript* Library::LookupScript(const String& url,
-                                 bool useResolvedUri /* = false */) const {
+ScriptPtr Library::LookupScript(const String& url,
+                                bool useResolvedUri /* = false */) const {
   const intptr_t url_length = url.Length();
   if (url_length == 0) {
     return Script::null();
@@ -11640,12 +11714,12 @@
   }
 }
 
-RawObject* Library::LookupLocalObject(const String& name) const {
+ObjectPtr Library::LookupLocalObject(const String& name) const {
   intptr_t index;
   return LookupEntry(name, &index);
 }
 
-RawObject* Library::LookupLocalOrReExportObject(const String& name) const {
+ObjectPtr Library::LookupLocalOrReExportObject(const String& name) const {
   intptr_t index;
   EnsureTopLevelClassIsFinalized();
   const Object& result = Object::Handle(LookupEntry(name, &index));
@@ -11655,7 +11729,7 @@
   return LookupReExport(name);
 }
 
-RawField* Library::LookupFieldAllowPrivate(const String& name) const {
+FieldPtr Library::LookupFieldAllowPrivate(const String& name) const {
   EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
   if (obj.IsField()) {
@@ -11664,7 +11738,7 @@
   return Field::null();
 }
 
-RawField* Library::LookupLocalField(const String& name) const {
+FieldPtr Library::LookupLocalField(const String& name) const {
   EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
   if (obj.IsField()) {
@@ -11673,7 +11747,7 @@
   return Field::null();
 }
 
-RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const {
+FunctionPtr Library::LookupFunctionAllowPrivate(const String& name) const {
   EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
   if (obj.IsFunction()) {
@@ -11682,7 +11756,7 @@
   return Function::null();
 }
 
-RawFunction* Library::LookupLocalFunction(const String& name) const {
+FunctionPtr Library::LookupLocalFunction(const String& name) const {
   EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
   if (obj.IsFunction()) {
@@ -11691,7 +11765,7 @@
   return Function::null();
 }
 
-RawObject* Library::LookupLocalObjectAllowPrivate(const String& name) const {
+ObjectPtr Library::LookupLocalObjectAllowPrivate(const String& name) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Object& obj = Object::Handle(zone, Object::null());
@@ -11703,7 +11777,7 @@
   return obj.raw();
 }
 
-RawObject* Library::LookupObjectAllowPrivate(const String& name) const {
+ObjectPtr Library::LookupObjectAllowPrivate(const String& name) const {
   // First check if name is found in the local scope of the library.
   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
   if (!obj.IsNull()) {
@@ -11719,7 +11793,7 @@
   return LookupImportedObject(name);
 }
 
-RawObject* Library::LookupImportedObject(const String& name) const {
+ObjectPtr Library::LookupImportedObject(const String& name) const {
   Object& obj = Object::Handle();
   Namespace& import = Namespace::Handle();
   Library& import_lib = Library::Handle();
@@ -11780,7 +11854,7 @@
   return found_obj.raw();
 }
 
-RawClass* Library::LookupClass(const String& name) const {
+ClassPtr Library::LookupClass(const String& name) const {
   Object& obj = Object::Handle(LookupLocalObject(name));
   if (obj.IsNull() && !ShouldBePrivate(name)) {
     obj = LookupImportedObject(name);
@@ -11791,7 +11865,7 @@
   return Class::null();
 }
 
-RawClass* Library::LookupLocalClass(const String& name) const {
+ClassPtr Library::LookupLocalClass(const String& name) const {
   Object& obj = Object::Handle(LookupLocalObject(name));
   if (obj.IsClass()) {
     return Class::Cast(obj).raw();
@@ -11799,7 +11873,7 @@
   return Class::null();
 }
 
-RawClass* Library::LookupClassAllowPrivate(const String& name) const {
+ClassPtr Library::LookupClassAllowPrivate(const String& name) const {
   // See if the class is available in this library or in the top level
   // scope of any imported library.
   Zone* zone = Thread::Current()->zone();
@@ -11821,7 +11895,7 @@
 }
 
 // Mixin applications can have multiple private keys from different libraries.
-RawClass* Library::SlowLookupClassAllowMultiPartPrivate(
+ClassPtr Library::SlowLookupClassAllowMultiPartPrivate(
     const String& name) const {
   Array& dict = Array::Handle(dictionary());
   Object& entry = Object::Handle();
@@ -11839,7 +11913,7 @@
   return Class::null();
 }
 
-RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const {
+LibraryPrefixPtr Library::LookupLocalLibraryPrefix(const String& name) const {
   const Object& obj = Object::Handle(LookupLocalObject(name));
   if (obj.IsLibraryPrefix()) {
     return LibraryPrefix::Cast(obj).raw();
@@ -11856,7 +11930,7 @@
   StorePointer(&raw_ptr()->metadata_, value.raw());
 }
 
-RawLibrary* Library::ImportLibraryAt(intptr_t index) const {
+LibraryPtr Library::ImportLibraryAt(intptr_t index) const {
   Namespace& import = Namespace::Handle(ImportAt(index));
   if (import.IsNull()) {
     return Library::null();
@@ -11864,7 +11938,7 @@
   return import.library();
 }
 
-RawNamespace* Library::ImportAt(intptr_t index) const {
+NamespacePtr Library::ImportAt(intptr_t index) const {
   if ((index < 0) || index >= num_imports()) {
     return Namespace::null();
   }
@@ -11939,7 +12013,7 @@
   exports.SetAt(num_exports, ns);
 }
 
-static RawArray* NewDictionary(intptr_t initial_size) {
+static ArrayPtr NewDictionary(intptr_t initial_size) {
   const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld));
   // The last element of the dictionary specifies the number of in use slots.
   dict.SetAt(initial_size, Object::smi_zero());
@@ -11991,22 +12065,20 @@
   StoreNonPointer(&raw_ptr()->num_imports_, 0);
 }
 
-RawLibrary* Library::New() {
+LibraryPtr Library::New() {
   ASSERT(Object::library_class() != Class::null());
-  RawObject* raw =
+  ObjectPtr raw =
       Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawLibrary*>(raw);
+  return static_cast<LibraryPtr>(raw);
 }
 
-RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) {
+LibraryPtr Library::NewLibraryHelper(const String& url, bool import_core_lib) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(thread->IsMutatorThread());
   // Force the url to have a hash code.
   url.Hash();
   const bool dart_scheme = url.StartsWith(Symbols::DartScheme());
-  const bool dart_private_scheme =
-      dart_scheme && url.StartsWith(Symbols::DartSchemePrivate());
   const Library& result = Library::Handle(zone, Library::New());
   result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw());
   result.StorePointer(&result.raw_ptr()->url_, url.raw());
@@ -12014,12 +12086,12 @@
   result.StorePointer(&result.raw_ptr()->exported_names_, Array::null());
   result.StorePointer(&result.raw_ptr()->dictionary_,
                       Object::empty_array().raw());
-  result.StorePointer(&result.raw_ptr()->metadata_,
-                      GrowableObjectArray::New(4, Heap::kOld));
+  GrowableObjectArray& list = GrowableObjectArray::Handle(zone);
+  list = GrowableObjectArray::New(4, Heap::kOld);
+  result.StorePointer(&result.raw_ptr()->metadata_, list.raw());
   result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null());
-  const GrowableObjectArray& scripts = GrowableObjectArray::Handle(zone,
-      GrowableObjectArray::New(Object::empty_array(), Heap::kOld));
-  result.StorePointer(&result.raw_ptr()->used_scripts_, scripts.raw());
+  list = GrowableObjectArray::New(Object::empty_array(), Heap::kOld);
+  result.StorePointer(&result.raw_ptr()->used_scripts_, list.raw());
   result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
   result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw());
   result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null());
@@ -12028,10 +12100,7 @@
   result.set_flags(0);
   result.set_is_in_fullsnapshot(false);
   result.set_is_nnbd(false);
-  if (dart_private_scheme) {
-    // Never debug dart:_ libraries.
-    result.set_debuggable(false);
-  } else if (dart_scheme) {
+  if (dart_scheme) {
     // Only debug dart: libraries if we have been requested to show invisible
     // frames.
     result.set_debuggable(FLAG_show_invisible_frames);
@@ -12043,7 +12112,7 @@
   NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false));
   NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0));
   result.StoreNonPointer(&result.raw_ptr()->load_state_,
-                         RawLibrary::kAllocated);
+                         LibraryLayout::kAllocated);
   result.StoreNonPointer(&result.raw_ptr()->index_, -1);
   result.InitClassDictionary();
   result.InitImportList();
@@ -12059,7 +12128,7 @@
   return result.raw();
 }
 
-RawLibrary* Library::New(const String& url) {
+LibraryPtr Library::New(const String& url) {
   return NewLibraryHelper(url, false);
 }
 
@@ -12080,7 +12149,7 @@
 }
 
 // Invoke the function, or noSuchMethod if it is null.
-static RawObject* InvokeInstanceFunction(
+static ObjectPtr InvokeInstanceFunction(
     const Instance& receiver,
     const Function& function,
     const String& target_name,
@@ -12096,18 +12165,18 @@
     return DartEntry::InvokeNoSuchMethod(receiver, target_name, args,
                                          args_descriptor_array);
   }
-  RawObject* type_error = function.DoArgumentTypesMatch(args, args_descriptor,
-                                                        instantiator_type_args);
+  ObjectPtr type_error = function.DoArgumentTypesMatch(args, args_descriptor,
+                                                       instantiator_type_args);
   if (type_error != Error::null()) {
     return type_error;
   }
   return DartEntry::InvokeFunction(function, args, args_descriptor_array);
 }
 
-RawObject* Library::InvokeGetter(const String& getter_name,
-                                 bool throw_nsm_if_absent,
-                                 bool respect_reflectable,
-                                 bool check_is_entrypoint) const {
+ObjectPtr Library::InvokeGetter(const String& getter_name,
+                                bool throw_nsm_if_absent,
+                                bool respect_reflectable,
+                                bool check_is_entrypoint) const {
   Object& obj = Object::Handle(LookupLocalOrReExportObject(getter_name));
   Function& getter = Function::Handle();
   if (obj.IsField()) {
@@ -12172,10 +12241,10 @@
   return DartEntry::InvokeFunction(getter, Object::empty_array());
 }
 
-RawObject* Library::InvokeSetter(const String& setter_name,
-                                 const Instance& value,
-                                 bool respect_reflectable,
-                                 bool check_is_entrypoint) const {
+ObjectPtr Library::InvokeSetter(const String& setter_name,
+                                const Instance& value,
+                                bool respect_reflectable,
+                                bool check_is_entrypoint) const {
   Object& obj = Object::Handle(LookupLocalOrReExportObject(setter_name));
   const String& internal_setter_name =
       String::Handle(Field::SetterName(setter_name));
@@ -12236,11 +12305,11 @@
   return DartEntry::InvokeFunction(setter, args);
 }
 
-RawObject* Library::Invoke(const String& function_name,
-                           const Array& args,
-                           const Array& arg_names,
-                           bool respect_reflectable,
-                           bool check_is_entrypoint) const {
+ObjectPtr Library::Invoke(const String& function_name,
+                          const Array& args,
+                          const Array& arg_names,
+                          bool respect_reflectable,
+                          bool check_is_entrypoint) const {
   // TODO(regis): Support invocation of generic functions with type arguments.
   const int kTypeArgsLen = 0;
 
@@ -12291,7 +12360,7 @@
         function_name, args, arg_names, InvocationMirror::kTopLevel,
         InvocationMirror::kMethod);
   }
-  RawObject* type_error =
+  ObjectPtr type_error =
       function.DoArgumentTypesMatch(args, args_descriptor, type_args);
   if (type_error != Error::null()) {
     return type_error;
@@ -12299,7 +12368,7 @@
   return DartEntry::InvokeFunction(function, args, args_descriptor_array);
 }
 
-RawObject* Library::EvaluateCompiledExpression(
+ObjectPtr Library::EvaluateCompiledExpression(
     const ExternalTypedData& kernel_buffer,
     const Array& type_definitions,
     const Array& arguments,
@@ -12359,11 +12428,11 @@
 
   static uword Hash(const Object& key) { return String::Cast(key).Hash(); }
 
-  static RawObject* NewKey(const String& str) { return str.raw(); }
+  static ObjectPtr NewKey(const String& str) { return str.raw(); }
 };
 typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap;
 
-static RawObject* EvaluateCompiledExpressionHelper(
+static ObjectPtr EvaluateCompiledExpressionHelper(
     const ExternalTypedData& kernel_buffer,
     const Array& type_definitions,
     const String& library_url,
@@ -12432,7 +12501,7 @@
 }
 
 // Returns library with given url in current isolate, or NULL.
-RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) {
+LibraryPtr Library::LookupLibrary(Thread* thread, const String& url) {
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
   ObjectStore* object_store = isolate->object_store();
@@ -12522,7 +12591,7 @@
   return name.EqualsConcat(member, private_key);
 }
 
-RawClass* Library::LookupCoreClass(const String& class_name) {
+ClassPtr Library::LookupCoreClass(const String& class_name) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
@@ -12537,7 +12606,7 @@
 
 // Cannot handle qualified names properly as it only appends private key to
 // the end (e.g. _Alfa.foo -> _Alfa.foo@...).
-RawString* Library::PrivateName(const String& name) const {
+StringPtr Library::PrivateName(const String& name) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(IsPrivate(name));
@@ -12549,7 +12618,7 @@
   return str.raw();
 }
 
-RawLibrary* Library::GetLibrary(intptr_t index) {
+LibraryPtr Library::GetLibrary(intptr_t index) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -12612,65 +12681,65 @@
   isolate->object_store()->set_libraries_map(map.Release());
 }
 
-RawLibrary* Library::AsyncLibrary() {
+LibraryPtr Library::AsyncLibrary() {
   return Isolate::Current()->object_store()->async_library();
 }
 
-RawLibrary* Library::ConvertLibrary() {
+LibraryPtr Library::ConvertLibrary() {
   return Isolate::Current()->object_store()->convert_library();
 }
 
-RawLibrary* Library::CoreLibrary() {
+LibraryPtr Library::CoreLibrary() {
   return Isolate::Current()->object_store()->core_library();
 }
 
-RawLibrary* Library::CollectionLibrary() {
+LibraryPtr Library::CollectionLibrary() {
   return Isolate::Current()->object_store()->collection_library();
 }
 
-RawLibrary* Library::DeveloperLibrary() {
+LibraryPtr Library::DeveloperLibrary() {
   return Isolate::Current()->object_store()->developer_library();
 }
 
-RawLibrary* Library::FfiLibrary() {
+LibraryPtr Library::FfiLibrary() {
   return Isolate::Current()->object_store()->ffi_library();
 }
 
-RawLibrary* Library::InternalLibrary() {
+LibraryPtr Library::InternalLibrary() {
   return Isolate::Current()->object_store()->_internal_library();
 }
 
-RawLibrary* Library::IsolateLibrary() {
+LibraryPtr Library::IsolateLibrary() {
   return Isolate::Current()->object_store()->isolate_library();
 }
 
-RawLibrary* Library::MathLibrary() {
+LibraryPtr Library::MathLibrary() {
   return Isolate::Current()->object_store()->math_library();
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawLibrary* Library::MirrorsLibrary() {
+LibraryPtr Library::MirrorsLibrary() {
   return Isolate::Current()->object_store()->mirrors_library();
 }
 #endif
 
-RawLibrary* Library::NativeWrappersLibrary() {
+LibraryPtr Library::NativeWrappersLibrary() {
   return Isolate::Current()->object_store()->native_wrappers_library();
 }
 
-RawLibrary* Library::ProfilerLibrary() {
+LibraryPtr Library::ProfilerLibrary() {
   return Isolate::Current()->object_store()->profiler_library();
 }
 
-RawLibrary* Library::TypedDataLibrary() {
+LibraryPtr Library::TypedDataLibrary() {
   return Isolate::Current()->object_store()->typed_data_library();
 }
 
-RawLibrary* Library::VMServiceLibrary() {
+LibraryPtr Library::VMServiceLibrary() {
   return Isolate::Current()->object_store()->_vmservice_library();
 }
 
-RawLibrary* Library::WasmLibrary() {
+LibraryPtr Library::WasmLibrary() {
   return Isolate::Current()->object_store()->wasm_library();
 }
 
@@ -12681,7 +12750,7 @@
                      name.ToCString());
 }
 
-RawLibrary* LibraryPrefix::GetLibrary(int index) const {
+LibraryPtr LibraryPrefix::GetLibrary(int index) const {
   if ((index >= 0) || (index < num_imports())) {
     const Array& imports = Array::Handle(this->imports());
     Namespace& import = Namespace::Handle();
@@ -12710,16 +12779,16 @@
   set_num_imports(num_current_imports + 1);
 }
 
-RawLibraryPrefix* LibraryPrefix::New() {
-  RawObject* raw = Object::Allocate(LibraryPrefix::kClassId,
-                                    LibraryPrefix::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawLibraryPrefix*>(raw);
+LibraryPrefixPtr LibraryPrefix::New() {
+  ObjectPtr raw = Object::Allocate(LibraryPrefix::kClassId,
+                                   LibraryPrefix::InstanceSize(), Heap::kOld);
+  return static_cast<LibraryPrefixPtr>(raw);
 }
 
-RawLibraryPrefix* LibraryPrefix::New(const String& name,
-                                     const Namespace& import,
-                                     bool deferred_load,
-                                     const Library& importer) {
+LibraryPrefixPtr LibraryPrefix::New(const String& name,
+                                    const Namespace& import,
+                                    bool deferred_load,
+                                    const Library& importer) {
   const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New());
   result.set_name(name);
   result.set_num_imports(0);
@@ -12776,7 +12845,7 @@
   set_metadata_field(field);
 }
 
-RawObject* Namespace::GetMetadata() const {
+ObjectPtr Namespace::GetMetadata() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   return Object::empty_array().raw();
 #else
@@ -12855,8 +12924,8 @@
 
 // Look up object with given name in library and filter out hidden
 // names. Also look up getters and setters.
-RawObject* Namespace::Lookup(const String& name,
-                             ZoneGrowableArray<intptr_t>* trail) const {
+ObjectPtr Namespace::Lookup(const String& name,
+                            ZoneGrowableArray<intptr_t>* trail) const {
   Zone* zone = Thread::Current()->zone();
   const Library& lib = Library::Handle(zone, library());
 
@@ -12912,16 +12981,16 @@
   return obj.raw();
 }
 
-RawNamespace* Namespace::New() {
+NamespacePtr Namespace::New() {
   ASSERT(Object::namespace_class() != Class::null());
-  RawObject* raw = Object::Allocate(Namespace::kClassId,
-                                    Namespace::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawNamespace*>(raw);
+  ObjectPtr raw = Object::Allocate(Namespace::kClassId,
+                                   Namespace::InstanceSize(), Heap::kOld);
+  return static_cast<NamespacePtr>(raw);
 }
 
-RawNamespace* Namespace::New(const Library& library,
-                             const Array& show_names,
-                             const Array& hide_names) {
+NamespacePtr Namespace::New(const Library& library,
+                            const Array& show_names,
+                            const Array& hide_names) {
   ASSERT(show_names.IsNull() || (show_names.Length() > 0));
   ASSERT(hide_names.IsNull() || (hide_names.Length() > 0));
   const Namespace& result = Namespace::Handle(Namespace::New());
@@ -12931,14 +13000,14 @@
   return result.raw();
 }
 
-RawKernelProgramInfo* KernelProgramInfo::New() {
-  RawObject* raw =
+KernelProgramInfoPtr KernelProgramInfo::New() {
+  ObjectPtr raw =
       Object::Allocate(KernelProgramInfo::kClassId,
                        KernelProgramInfo::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawKernelProgramInfo*>(raw);
+  return static_cast<KernelProgramInfoPtr>(raw);
 }
 
-RawKernelProgramInfo* KernelProgramInfo::New(
+KernelProgramInfoPtr KernelProgramInfo::New(
     const TypedData& string_offsets,
     const ExternalTypedData& string_data,
     const TypedData& canonical_names,
@@ -12973,9 +13042,9 @@
   return "[KernelProgramInfo]";
 }
 
-RawScript* KernelProgramInfo::ScriptAt(intptr_t index) const {
+ScriptPtr KernelProgramInfo::ScriptAt(intptr_t index) const {
   const Array& all_scripts = Array::Handle(scripts());
-  RawObject* script = all_scripts.At(index);
+  ObjectPtr script = all_scripts.At(index);
   return Script::RawCast(script);
 }
 
@@ -13012,8 +13081,8 @@
 
 typedef UnorderedHashMap<SmiTraits> IntHashMap;
 
-RawLibrary* KernelProgramInfo::LookupLibrary(Thread* thread,
-                                             const Smi& name_index) const {
+LibraryPtr KernelProgramInfo::LookupLibrary(Thread* thread,
+                                            const Smi& name_index) const {
   REUSABLE_ARRAY_HANDLESCOPE(thread);
   REUSABLE_LIBRARY_HANDLESCOPE(thread);
   REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13034,9 +13103,9 @@
   return result.raw();
 }
 
-RawLibrary* KernelProgramInfo::InsertLibrary(Thread* thread,
-                                             const Smi& name_index,
-                                             const Library& lib) const {
+LibraryPtr KernelProgramInfo::InsertLibrary(Thread* thread,
+                                            const Smi& name_index,
+                                            const Library& lib) const {
   REUSABLE_ARRAY_HANDLESCOPE(thread);
   REUSABLE_LIBRARY_HANDLESCOPE(thread);
   REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13061,8 +13130,8 @@
   StorePointer(&raw_ptr()->classes_cache_, cache.raw());
 }
 
-RawClass* KernelProgramInfo::LookupClass(Thread* thread,
-                                         const Smi& name_index) const {
+ClassPtr KernelProgramInfo::LookupClass(Thread* thread,
+                                        const Smi& name_index) const {
   REUSABLE_ARRAY_HANDLESCOPE(thread);
   REUSABLE_CLASS_HANDLESCOPE(thread);
   REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13083,9 +13152,9 @@
   return result.raw();
 }
 
-RawClass* KernelProgramInfo::InsertClass(Thread* thread,
-                                         const Smi& name_index,
-                                         const Class& klass) const {
+ClassPtr KernelProgramInfo::InsertClass(Thread* thread,
+                                        const Smi& name_index,
+                                        const Class& klass) const {
   REUSABLE_ARRAY_HANDLESCOPE(thread);
   REUSABLE_CLASS_HANDLESCOPE(thread);
   REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13111,7 +13180,7 @@
   StorePointer(&raw_ptr()->bytecode_component_, bytecode_component.raw());
 }
 
-RawError* Library::CompileAll(bool ignore_error /* = false */) {
+ErrorPtr Library::CompileAll(bool ignore_error /* = false */) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Error& error = Error::Handle(zone);
@@ -13159,7 +13228,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
-RawError* Library::FinalizeAllClasses() {
+ErrorPtr Library::FinalizeAllClasses() {
   Thread* thread = Thread::Current();
   ASSERT(thread->IsMutatorThread());
   Zone* zone = thread->zone();
@@ -13191,7 +13260,7 @@
   return Error::null();
 }
 
-RawError* Library::ReadAllBytecode() {
+ErrorPtr Library::ReadAllBytecode() {
   Thread* thread = Thread::Current();
   ASSERT(thread->IsMutatorThread());
   Zone* zone = thread->zone();
@@ -13221,9 +13290,9 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 // Return Function::null() if function does not exist in libs.
-RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs,
-                                  const char* class_name,
-                                  const char* function_name) {
+FunctionPtr Library::GetFunction(const GrowableArray<Library*>& libs,
+                                 const char* class_name,
+                                 const char* function_name) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Function& func = Function::Handle(zone);
@@ -13253,7 +13322,7 @@
   return Function::null();
 }
 
-RawObject* Library::GetFunctionClosure(const String& name) const {
+ObjectPtr Library::GetFunctionClosure(const String& name) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Function& func = Function::Handle(zone, LookupFunctionAllowPrivate(name));
@@ -13344,7 +13413,7 @@
 }
 #endif  // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
 
-RawInstructions* Instructions::New(intptr_t size, bool has_monomorphic_entry) {
+InstructionsPtr Instructions::New(intptr_t size, bool has_monomorphic_entry) {
   ASSERT(size >= 0);
   ASSERT(Object::instructions_class() != Class::null());
   if (size < 0 || size > kMaxElements) {
@@ -13354,7 +13423,7 @@
   Instructions& result = Instructions::Handle();
   {
     uword aligned_size = Instructions::InstanceSize(size);
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -13417,7 +13486,7 @@
   return Utils::DecodeSLEB128<intptr_t>(data, Length(), byte_index);
 }
 
-RawObjectPool* ObjectPool::New(intptr_t len) {
+ObjectPoolPtr ObjectPool::New(intptr_t len) {
   ASSERT(Object::object_pool_class() != Class::null());
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
@@ -13426,7 +13495,7 @@
   ObjectPool& result = ObjectPool::Handle();
   {
     uword size = ObjectPool::InstanceSize(len);
-    RawObject* raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -13440,7 +13509,7 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawObjectPool* ObjectPool::NewFromBuilder(
+ObjectPoolPtr ObjectPool::NewFromBuilder(
     const compiler::ObjectPoolBuilder& builder) {
   const intptr_t len = builder.CurrentLength();
   if (len == 0) {
@@ -13537,14 +13606,13 @@
   }
 }
 
-RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) {
+PcDescriptorsPtr PcDescriptors::New(GrowableArray<uint8_t>* data) {
   ASSERT(Object::pc_descriptors_class() != Class::null());
   Thread* thread = Thread::Current();
   PcDescriptors& result = PcDescriptors::Handle(thread->zone());
   {
     uword size = PcDescriptors::InstanceSize(data->length());
-    RawObject* raw =
-        Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(data->length());
@@ -13553,14 +13621,13 @@
   return result.raw();
 }
 
-RawPcDescriptors* PcDescriptors::New(intptr_t length) {
+PcDescriptorsPtr PcDescriptors::New(intptr_t length) {
   ASSERT(Object::pc_descriptors_class() != Class::null());
   Thread* thread = Thread::Current();
   PcDescriptors& result = PcDescriptors::Handle(thread->zone());
   {
     uword size = PcDescriptors::InstanceSize(length);
-    RawObject* raw =
-        Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(length);
@@ -13568,25 +13635,25 @@
   return result.raw();
 }
 
-const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) {
+const char* PcDescriptors::KindAsStr(PcDescriptorsLayout::Kind kind) {
   switch (kind) {
-    case RawPcDescriptors::kDeopt:
+    case PcDescriptorsLayout::kDeopt:
       return "deopt        ";
-    case RawPcDescriptors::kIcCall:
+    case PcDescriptorsLayout::kIcCall:
       return "ic-call      ";
-    case RawPcDescriptors::kUnoptStaticCall:
+    case PcDescriptorsLayout::kUnoptStaticCall:
       return "unopt-call   ";
-    case RawPcDescriptors::kRuntimeCall:
+    case PcDescriptorsLayout::kRuntimeCall:
       return "runtime-call ";
-    case RawPcDescriptors::kOsrEntry:
+    case PcDescriptorsLayout::kOsrEntry:
       return "osr-entry    ";
-    case RawPcDescriptors::kRewind:
+    case PcDescriptorsLayout::kRewind:
       return "rewind       ";
-    case RawPcDescriptors::kBSSRelocation:
+    case PcDescriptorsLayout::kBSSRelocation:
       return "bss reloc    ";
-    case RawPcDescriptors::kOther:
+    case PcDescriptorsLayout::kOther:
       return "other        ";
-    case RawPcDescriptors::kAnyKind:
+    case PcDescriptorsLayout::kAnyKind:
       UNREACHABLE();
       break;
   }
@@ -13615,7 +13682,7 @@
   // First compute the buffer size required.
   intptr_t len = 1;  // Trailing '\0'.
   {
-    Iterator iter(*this, RawPcDescriptors::kAnyKind);
+    Iterator iter(*this, PcDescriptorsLayout::kAnyKind);
     while (iter.MoveNext()) {
       len += Utils::SNPrint(NULL, 0, FORMAT, addr_width, iter.PcOffset(),
                             KindAsStr(iter.Kind()), iter.DeoptId(),
@@ -13627,7 +13694,7 @@
   char* buffer = Thread::Current()->zone()->Alloc<char>(len);
   // Layout the fields in the buffer.
   intptr_t index = 0;
-  Iterator iter(*this, RawPcDescriptors::kAnyKind);
+  Iterator iter(*this, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     index += Utils::SNPrint((buffer + index), (len - index), FORMAT, addr_width,
                             iter.PcOffset(), KindAsStr(iter.Kind()),
@@ -13651,7 +13718,7 @@
   }
   intptr_t max_deopt_id = 0;
   Iterator max_iter(*this,
-                    RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
+                    PcDescriptorsLayout::kDeopt | PcDescriptorsLayout::kIcCall);
   while (max_iter.MoveNext()) {
     if (max_iter.DeoptId() > max_deopt_id) {
       max_deopt_id = max_iter.DeoptId();
@@ -13661,7 +13728,8 @@
   Zone* zone = Thread::Current()->zone();
   BitVector* deopt_ids = new (zone) BitVector(zone, max_deopt_id + 1);
   BitVector* iccall_ids = new (zone) BitVector(zone, max_deopt_id + 1);
-  Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
+  Iterator iter(*this,
+                PcDescriptorsLayout::kDeopt | PcDescriptorsLayout::kIcCall);
   while (iter.MoveNext()) {
     // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind.
     if (DeoptId::IsDeoptAfter(iter.DeoptId())) {
@@ -13670,7 +13738,7 @@
       // lead to issues in the future. Fix that and enable verification.
       continue;
     }
-    if (iter.Kind() == RawPcDescriptors::kDeopt) {
+    if (iter.Kind() == PcDescriptorsLayout::kDeopt) {
       ASSERT(!deopt_ids->Contains(iter.DeoptId()));
       deopt_ids->Add(iter.DeoptId());
     } else {
@@ -13685,14 +13753,13 @@
   StoreNonPointer(&raw_ptr()->length_, value);
 }
 
-RawCodeSourceMap* CodeSourceMap::New(intptr_t length) {
+CodeSourceMapPtr CodeSourceMap::New(intptr_t length) {
   ASSERT(Object::code_source_map_class() != Class::null());
   Thread* thread = Thread::Current();
   CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
   {
     uword size = CodeSourceMap::InstanceSize(length);
-    RawObject* raw =
-        Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(length);
@@ -13713,7 +13780,7 @@
   return FinalizeHash(hash, kHashBits);
 }
 
-RawCompressedStackMaps* CompressedStackMaps::New(
+CompressedStackMapsPtr CompressedStackMaps::New(
     const GrowableArray<uint8_t>& payload,
     bool is_global_table,
     bool uses_global_table) {
@@ -13723,7 +13790,7 @@
   auto& result = CompressedStackMaps::Handle();
 
   const uintptr_t payload_size = payload.length();
-  if (!RawCompressedStackMaps::SizeField::is_valid(payload_size)) {
+  if (!CompressedStackMapsLayout::SizeField::is_valid(payload_size)) {
     FATAL1(
         "Fatal error in CompressedStackMaps::New: "
         "invalid payload size %" Pu "\n",
@@ -13732,16 +13799,16 @@
   {
     // CompressedStackMaps data objects are associated with a code object,
     // allocate them in old generation.
-    RawObject* raw = Object::Allocate(
+    ObjectPtr raw = Object::Allocate(
         CompressedStackMaps::kClassId,
         CompressedStackMaps::InstanceSize(payload_size), Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(
         &result.raw_ptr()->flags_and_size_,
-        RawCompressedStackMaps::GlobalTableBit::encode(is_global_table) |
-            RawCompressedStackMaps::UsesTableBit::encode(uses_global_table) |
-            RawCompressedStackMaps::SizeField::encode(payload_size));
+        CompressedStackMapsLayout::GlobalTableBit::encode(is_global_table) |
+            CompressedStackMapsLayout::UsesTableBit::encode(uses_global_table) |
+            CompressedStackMapsLayout::SizeField::encode(payload_size));
     auto cursor = result.UnsafeMutableNonPointer(result.raw_ptr()->data());
     memcpy(cursor, payload.data(), payload.length());  // NOLINT
   }
@@ -13761,35 +13828,37 @@
   return it.ToCString(zone);
 }
 
-RawString* LocalVarDescriptors::GetName(intptr_t var_index) const {
+StringPtr LocalVarDescriptors::GetName(intptr_t var_index) const {
   ASSERT(var_index < Length());
-  ASSERT(Object::Handle(*raw()->nameAddrAt(var_index)).IsString());
-  return *raw()->nameAddrAt(var_index);
+  ASSERT(Object::Handle(*raw()->ptr()->nameAddrAt(var_index)).IsString());
+  return *raw()->ptr()->nameAddrAt(var_index);
 }
 
-void LocalVarDescriptors::SetVar(intptr_t var_index,
-                                 const String& name,
-                                 RawLocalVarDescriptors::VarInfo* info) const {
+void LocalVarDescriptors::SetVar(
+    intptr_t var_index,
+    const String& name,
+    LocalVarDescriptorsLayout::VarInfo* info) const {
   ASSERT(var_index < Length());
   ASSERT(!name.IsNull());
-  StorePointer(raw()->nameAddrAt(var_index), name.raw());
-  raw()->data()[var_index] = *info;
+  StorePointer(raw()->ptr()->nameAddrAt(var_index), name.raw());
+  raw()->ptr()->data()[var_index] = *info;
 }
 
-void LocalVarDescriptors::GetInfo(intptr_t var_index,
-                                  RawLocalVarDescriptors::VarInfo* info) const {
+void LocalVarDescriptors::GetInfo(
+    intptr_t var_index,
+    LocalVarDescriptorsLayout::VarInfo* info) const {
   ASSERT(var_index < Length());
-  *info = raw()->data()[var_index];
+  *info = raw()->ptr()->data()[var_index];
 }
 
 static int PrintVarInfo(char* buffer,
                         int len,
                         intptr_t i,
                         const String& var_name,
-                        const RawLocalVarDescriptors::VarInfo& info) {
-  const RawLocalVarDescriptors::VarInfoKind kind = info.kind();
+                        const LocalVarDescriptorsLayout::VarInfo& info) {
+  const LocalVarDescriptorsLayout::VarInfoKind kind = info.kind();
   const int32_t index = info.index();
-  if (kind == RawLocalVarDescriptors::kContextLevel) {
+  if (kind == LocalVarDescriptorsLayout::kContextLevel) {
     return Utils::SNPrint(buffer, len,
                           "%2" Pd
                           " %-13s level=%-3d"
@@ -13797,7 +13866,7 @@
                           i, LocalVarDescriptors::KindToCString(kind), index,
                           static_cast<int>(info.begin_pos.value()),
                           static_cast<int>(info.end_pos.value()));
-  } else if (kind == RawLocalVarDescriptors::kContextVar) {
+  } else if (kind == LocalVarDescriptorsLayout::kContextVar) {
     return Utils::SNPrint(
         buffer, len,
         "%2" Pd
@@ -13828,7 +13897,7 @@
   intptr_t len = 1;  // Trailing '\0'.
   String& var_name = String::Handle();
   for (intptr_t i = 0; i < Length(); i++) {
-    RawLocalVarDescriptors::VarInfo info;
+    LocalVarDescriptorsLayout::VarInfo info;
     var_name = GetName(i);
     GetInfo(i, &info);
     len += PrintVarInfo(NULL, 0, i, var_name, info);
@@ -13837,7 +13906,7 @@
   buffer[0] = '\0';
   intptr_t num_chars = 0;
   for (intptr_t i = 0; i < Length(); i++) {
-    RawLocalVarDescriptors::VarInfo info;
+    LocalVarDescriptorsLayout::VarInfo info;
     var_name = GetName(i);
     GetInfo(i, &info);
     num_chars += PrintVarInfo((buffer + num_chars), (len - num_chars), i,
@@ -13847,15 +13916,15 @@
 }
 
 const char* LocalVarDescriptors::KindToCString(
-    RawLocalVarDescriptors::VarInfoKind kind) {
+    LocalVarDescriptorsLayout::VarInfoKind kind) {
   switch (kind) {
-    case RawLocalVarDescriptors::kStackVar:
+    case LocalVarDescriptorsLayout::kStackVar:
       return "StackVar";
-    case RawLocalVarDescriptors::kContextVar:
+    case LocalVarDescriptorsLayout::kContextVar:
       return "ContextVar";
-    case RawLocalVarDescriptors::kContextLevel:
+    case LocalVarDescriptorsLayout::kContextLevel:
       return "ContextLevel";
-    case RawLocalVarDescriptors::kSavedCurrentContext:
+    case LocalVarDescriptorsLayout::kSavedCurrentContext:
       return "CurrentCtx";
     default:
       UNIMPLEMENTED();
@@ -13863,19 +13932,19 @@
   }
 }
 
-RawLocalVarDescriptors* LocalVarDescriptors::New(intptr_t num_variables) {
+LocalVarDescriptorsPtr LocalVarDescriptors::New(intptr_t num_variables) {
   ASSERT(Object::var_descriptors_class() != Class::null());
   if (num_variables < 0 || num_variables > kMaxElements) {
     // This should be caught before we reach here.
     FATAL2(
         "Fatal error in LocalVarDescriptors::New: "
         "invalid num_variables %" Pd ". Maximum is: %d\n",
-        num_variables, RawLocalVarDescriptors::kMaxIndex);
+        num_variables, LocalVarDescriptorsLayout::kMaxIndex);
   }
   LocalVarDescriptors& result = LocalVarDescriptors::Handle();
   {
     uword size = LocalVarDescriptors::InstanceSize(num_variables);
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -13954,7 +14023,7 @@
   handled_types_data.SetAt(try_index, handled_types);
 }
 
-RawArray* ExceptionHandlers::GetHandledTypes(intptr_t try_index) const {
+ArrayPtr ExceptionHandlers::GetHandledTypes(intptr_t try_index) const {
   ASSERT((try_index >= 0) && (try_index < num_entries()));
   Array& array = Array::Handle(raw_ptr()->handled_types_data_);
   array ^= array.At(try_index);
@@ -13965,7 +14034,7 @@
   StorePointer(&raw_ptr()->handled_types_data_, value.raw());
 }
 
-RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) {
+ExceptionHandlersPtr ExceptionHandlers::New(intptr_t num_handlers) {
   ASSERT(Object::exception_handlers_class() != Class::null());
   if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) {
     FATAL1(
@@ -13976,7 +14045,7 @@
   ExceptionHandlers& result = ExceptionHandlers::Handle();
   {
     uword size = ExceptionHandlers::InstanceSize(num_handlers);
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -13989,7 +14058,7 @@
   return result.raw();
 }
 
-RawExceptionHandlers* ExceptionHandlers::New(const Array& handled_types_data) {
+ExceptionHandlersPtr ExceptionHandlers::New(const Array& handled_types_data) {
   ASSERT(Object::exception_handlers_class() != Class::null());
   const intptr_t num_handlers = handled_types_data.Length();
   if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) {
@@ -14001,7 +14070,7 @@
   ExceptionHandlers& result = ExceptionHandlers::Handle();
   {
     uword size = ExceptionHandlers::InstanceSize(num_handlers);
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -14084,10 +14153,10 @@
                              Object::Handle(zone, name()).ToCString());
 }
 
-RawParameterTypeCheck* ParameterTypeCheck::New() {
+ParameterTypeCheckPtr ParameterTypeCheck::New() {
   ParameterTypeCheck& result = ParameterTypeCheck::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ParameterTypeCheck::kClassId,
                          ParameterTypeCheck::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
@@ -14105,11 +14174,11 @@
   return "SingleTargetCache";
 }
 
-RawSingleTargetCache* SingleTargetCache::New() {
+SingleTargetCachePtr SingleTargetCache::New() {
   SingleTargetCache& result = SingleTargetCache::Handle();
   {
     // IC data objects are long living objects, allocate them in old generation.
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(SingleTargetCache::kClassId,
                          SingleTargetCache::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
@@ -14148,7 +14217,7 @@
   return "UnlinkedCall";
 }
 
-RawUnlinkedCall* UnlinkedCall::New() {
+UnlinkedCallPtr UnlinkedCall::New() {
   UnlinkedCall& result = UnlinkedCall::Handle();
   result ^= Object::Allocate(UnlinkedCall::kClassId,
                              UnlinkedCall::InstanceSize(), Heap::kOld);
@@ -14156,8 +14225,8 @@
   return result.raw();
 }
 
-RawMonomorphicSmiableCall* MonomorphicSmiableCall::New(classid_t expected_cid,
-                                                       const Code& target) {
+MonomorphicSmiableCallPtr MonomorphicSmiableCall::New(classid_t expected_cid,
+                                                      const Code& target) {
   auto& result = MonomorphicSmiableCall::Handle();
   result ^=
       Object::Allocate(MonomorphicSmiableCall::kClassId,
@@ -14172,6 +14241,22 @@
   return "MonomorphicSmiableCall";
 }
 
+const char* CallSiteData::ToCString() const {
+  // CallSiteData is an abstract class.  We should never reach here.
+  UNREACHABLE();
+  return "CallSiteData";
+}
+
+void CallSiteData::set_target_name(const String& value) const {
+  ASSERT(!value.IsNull());
+  StorePointer(&raw_ptr()->target_name_, value.raw());
+}
+
+void CallSiteData::set_arguments_descriptor(const Array& value) const {
+  ASSERT(!value.IsNull());
+  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+}
+
 #if !defined(DART_PRECOMPILED_RUNTIME)
 void ICData::SetReceiversStaticType(const AbstractType& type) const {
   StorePointer(&raw_ptr()->receivers_static_type_, type.raw());
@@ -14199,7 +14284,7 @@
       name.ToCString(), num_args, num_checks, type_args_len);
 }
 
-RawFunction* ICData::Owner() const {
+FunctionPtr ICData::Owner() const {
   Object& obj = Object::Handle(raw_ptr()->owner_);
   if (obj.IsNull()) {
     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
@@ -14213,7 +14298,7 @@
   }
 }
 
-RawICData* ICData::Original() const {
+ICDataPtr ICData::Original() const {
   if (IsNull()) {
     return ICData::null();
   }
@@ -14228,21 +14313,11 @@
 void ICData::SetOriginal(const ICData& value) const {
   ASSERT(value.IsOriginal());
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
+  StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
 }
 
 void ICData::set_owner(const Function& value) const {
-  StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
-}
-
-void ICData::set_target_name(const String& value) const {
-  ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->target_name_, value.raw());
-}
-
-void ICData::set_arguments_descriptor(const Array& value) const {
-  ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+  StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
 }
 
 void ICData::set_deopt_id(intptr_t value) const {
@@ -14256,8 +14331,8 @@
 
 void ICData::set_entries(const Array& value) const {
   ASSERT(!value.IsNull());
-  StorePointer<RawArray*, std::memory_order_release>(&raw_ptr()->entries_,
-                                                     value.raw());
+  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->entries_,
+                                                    value.raw());
 }
 
 intptr_t ICData::NumArgsTested() const {
@@ -14660,7 +14735,7 @@
   set_entries(data);
 }
 
-RawArray* ICData::Grow(intptr_t* index) const {
+ArrayPtr ICData::Grow(intptr_t* index) const {
   Array& data = Array::Handle(entries());
   // Last entry in array should be a sentinel and will be the new entry
   // that can be updated after growing.
@@ -14846,11 +14921,11 @@
   ASSERT(!IsSentinelAt(index));
   const intptr_t data_pos = index * TestEntryLength();
   NoSafepointScope no_safepoint;
-  RawArray* raw_data = entries();
+  ArrayPtr raw_data = entries();
   return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos]));
 }
 
-RawFunction* ICData::GetTargetAt(intptr_t index) const {
+FunctionPtr ICData::GetTargetAt(intptr_t index) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
   return nullptr;
@@ -14860,17 +14935,17 @@
   ASSERT(Object::Handle(Array::Handle(entries()).At(data_pos)).IsFunction());
 
   NoSafepointScope no_safepoint;
-  RawArray* raw_data = entries();
-  return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]);
+  ArrayPtr raw_data = entries();
+  return static_cast<FunctionPtr>(raw_data->ptr()->data()[data_pos]);
 #endif
 }
 
-RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const {
+ObjectPtr ICData::GetTargetOrCodeAt(intptr_t index) const {
   const intptr_t data_pos =
       index * TestEntryLength() + TargetIndexFor(NumArgsTested());
 
   NoSafepointScope no_safepoint;
-  RawArray* raw_data = entries();
+  ArrayPtr raw_data = entries();
   return raw_data->ptr()->data()[data_pos];
 }
 
@@ -14953,8 +15028,8 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid,
-                                            const Function& target) const {
+ICDataPtr ICData::AsUnaryClassChecksForCid(intptr_t cid,
+                                           const Function& target) const {
   ASSERT(!IsNull());
   const intptr_t kNumArgsTested = 1;
   ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
@@ -14964,7 +15039,7 @@
   return result.raw();
 }
 
-RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
+ICDataPtr ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
   ASSERT(!IsNull());
   ASSERT(NumArgsTested() > arg_nr);
   if ((arg_nr == 0) && (NumArgsTested() == 1)) {
@@ -15022,7 +15097,7 @@
   return (a->count < b->count) ? 1 : 0;
 }
 
-RawICData* ICData::AsUnaryClassChecksSortedByCount() const {
+ICDataPtr ICData::AsUnaryClassChecksSortedByCount() const {
   ASSERT(!IsNull());
   const intptr_t kNumArgsTested = 1;
   const intptr_t len = NumberOfChecks();
@@ -15074,7 +15149,7 @@
   return result.raw();
 }
 
-RawUnlinkedCall* ICData::AsUnlinkedCall() const {
+UnlinkedCallPtr ICData::AsUnlinkedCall() const {
   ASSERT(NumArgsTested() == 1);
   ASSERT(!is_tracking_exactness());
   const UnlinkedCall& result = UnlinkedCall::Handle(UnlinkedCall::New());
@@ -15133,8 +15208,8 @@
   }
 }
 
-RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
-                                               bool tracking_exactness) {
+ArrayPtr ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
+                                              bool tracking_exactness) {
   // IC data array must be null terminated (sentinel entry).
   const intptr_t len = TestEntryLengthFor(num_args_tested, tracking_exactness);
   const Array& array = Array::Handle(Array::New(len, Heap::kOld));
@@ -15143,8 +15218,8 @@
   return array.raw();
 }
 
-RawArray* ICData::CachedEmptyICDataArray(intptr_t num_args_tested,
-                                         bool tracking_exactness) {
+ArrayPtr ICData::CachedEmptyICDataArray(intptr_t num_args_tested,
+                                        bool tracking_exactness) {
   if (tracking_exactness) {
     ASSERT(num_args_tested == 1);
     return cached_icdata_arrays_[kCachedICDataOneArgWithExactnessTrackingIdx];
@@ -15159,14 +15234,14 @@
 }
 
 // Does not initialize ICData array.
-RawICData* ICData::NewDescriptor(Zone* zone,
-                                 const Function& owner,
-                                 const String& target_name,
-                                 const Array& arguments_descriptor,
-                                 intptr_t deopt_id,
-                                 intptr_t num_args_tested,
-                                 RebindRule rebind_rule,
-                                 const AbstractType& receivers_static_type) {
+ICDataPtr ICData::NewDescriptor(Zone* zone,
+                                const Function& owner,
+                                const String& target_name,
+                                const Array& arguments_descriptor,
+                                intptr_t deopt_id,
+                                intptr_t num_args_tested,
+                                RebindRule rebind_rule,
+                                const AbstractType& receivers_static_type) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // We should only have null owners in the precompiled runtime, if the
   // owning function for a Code object was optimized out.
@@ -15179,7 +15254,7 @@
   ICData& result = ICData::Handle(zone);
   {
     // IC data objects are long living objects, allocate them in old generation.
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -15199,11 +15274,11 @@
   return entries()->IsImmutableArray();
 }
 
-RawICData* ICData::New() {
+ICDataPtr ICData::New() {
   ICData& result = ICData::Handle();
   {
     // IC data objects are long living objects, allocate them in old generation.
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -15213,13 +15288,13 @@
   return result.raw();
 }
 
-RawICData* ICData::New(const Function& owner,
-                       const String& target_name,
-                       const Array& arguments_descriptor,
-                       intptr_t deopt_id,
-                       intptr_t num_args_tested,
-                       RebindRule rebind_rule,
-                       const AbstractType& receivers_static_type) {
+ICDataPtr ICData::New(const Function& owner,
+                      const String& target_name,
+                      const Array& arguments_descriptor,
+                      intptr_t deopt_id,
+                      intptr_t num_args_tested,
+                      RebindRule rebind_rule,
+                      const AbstractType& receivers_static_type) {
   Zone* zone = Thread::Current()->zone();
   const ICData& result = ICData::Handle(
       zone,
@@ -15232,7 +15307,7 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
+ICDataPtr ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
   // See comment in [ICData::Clone] why we access the megamorphic bit first.
   const bool is_megamorphic = from.is_megamorphic();
 
@@ -15247,7 +15322,7 @@
   return result.raw();
 }
 
-RawICData* ICData::Clone(const ICData& from) {
+ICDataPtr ICData::Clone(const ICData& from) {
   Zone* zone = Thread::Current()->zone();
 
   // We have to check the megamorphic bit before accessing the entries of the
@@ -15303,14 +15378,14 @@
          object.raw()->IsHeapObject() && !object.IsWeakSerializationReference();
 }
 
-RawObject* WeakSerializationReference::Wrap(Zone* zone, const Object& target) {
+ObjectPtr WeakSerializationReference::Wrap(Zone* zone, const Object& target) {
   if (!CanWrap(target)) return target.raw();
   ASSERT(Object::weak_serialization_reference_class() != Class::null());
   WeakSerializationReference& result = WeakSerializationReference::Handle(zone);
   {
-    RawObject* raw = Object::Allocate(
-        WeakSerializationReference::kClassId,
-        WeakSerializationReference::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(WeakSerializationReference::kClassId,
+                                     WeakSerializationReference::InstanceSize(),
+                                     Heap::kOld);
     NoSafepointScope no_safepoint;
 
     result ^= raw;
@@ -15354,7 +15429,7 @@
                   Smi::Handle(Smi::New(pc)));
 }
 
-RawString* Code::Comments::CommentAt(intptr_t idx) const {
+StringPtr Code::Comments::CommentAt(intptr_t idx) const {
   return String::RawCast(comments_.At(idx * kNumberOfEntries + kCommentEntry));
 }
 
@@ -15397,7 +15472,7 @@
   return false;
 }
 
-RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const {
+LocalVarDescriptorsPtr Code::GetLocalVarDescriptors() const {
   const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors());
   if (v.IsNull()) {
     ASSERT(!is_optimized());
@@ -15453,7 +15528,7 @@
 #endif
 
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-RawTypedData* Code::catch_entry_moves_maps() const {
+TypedDataPtr Code::catch_entry_moves_maps() const {
   ASSERT(FLAG_precompiled_mode);
   return TypedData::RawCast(raw_ptr()->catch_entry_);
 }
@@ -15494,7 +15569,7 @@
 #endif  // DEBUG
 }
 
-RawObjectPool* Code::GetObjectPool() const {
+ObjectPoolPtr Code::GetObjectPool() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   if (FLAG_use_bare_instructions) {
     return Isolate::Current()->object_store()->global_object_pool();
@@ -15511,9 +15586,9 @@
 #endif
 }
 
-RawTypedData* Code::GetDeoptInfoAtPc(uword pc,
-                                     ICData::DeoptReasonId* deopt_reason,
-                                     uint32_t* deopt_flags) const {
+TypedDataPtr Code::GetDeoptInfoAtPc(uword pc,
+                                    ICData::DeoptReasonId* deopt_reason,
+                                    uint32_t* deopt_flags) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
   return TypedData::null();
@@ -15571,7 +15646,7 @@
   return -1;
 }
 
-RawFunction* Code::GetStaticCallTargetFunctionAt(uword pc) const {
+FunctionPtr Code::GetStaticCallTargetFunctionAt(uword pc) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
   return Function::null();
@@ -15596,7 +15671,7 @@
   StaticCallsTable entries(array);
   ASSERT(code.IsNull() ||
          (code.function() == entries[i].Get<kSCallTableFunctionTarget>()));
-  return entries[i].Set<kSCallTableCodeTarget>(code);
+  return entries[i].Set<kSCallTableCodeOrTypeTarget>(code);
 #endif
 }
 
@@ -15616,7 +15691,7 @@
            (code.function() == entries[i].Get<kSCallTableFunctionTarget>()));
   }
 #endif
-  return entries[i].Set<kSCallTableCodeTarget>(code);
+  return entries[i].Set<kSCallTableCodeOrTypeTarget>(code);
 #endif
 }
 
@@ -15658,7 +15733,7 @@
 #else
   ASSERT(offset >= 0);
   StoreSmi(
-      reinterpret_cast<RawSmi* const*>(&raw_ptr()->return_address_metadata_),
+      reinterpret_cast<SmiPtr const*>(&raw_ptr()->return_address_metadata_),
       Smi::New(offset));
 #endif
 }
@@ -15678,7 +15753,7 @@
 #endif
 }
 
-RawArray* Code::inlined_id_to_function() const {
+ArrayPtr Code::inlined_id_to_function() const {
   return raw_ptr()->inlined_id_to_function_;
 }
 
@@ -15687,7 +15762,7 @@
   StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw());
 }
 
-RawCode* Code::New(intptr_t pointer_offsets_length) {
+CodePtr Code::New(intptr_t pointer_offsets_length) {
   if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n",
@@ -15697,7 +15772,7 @@
   Code& result = Code::Handle();
   {
     uword size = Code::InstanceSize(pointer_offsets_length);
-    RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_pointer_offsets_length(pointer_offsets_length);
@@ -15712,12 +15787,12 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawCode* Code::FinalizeCodeAndNotify(const Function& function,
-                                     FlowGraphCompiler* compiler,
-                                     compiler::Assembler* assembler,
-                                     PoolAttachment pool_attachment,
-                                     bool optimized,
-                                     CodeStatistics* stats) {
+CodePtr Code::FinalizeCodeAndNotify(const Function& function,
+                                    FlowGraphCompiler* compiler,
+                                    compiler::Assembler* assembler,
+                                    PoolAttachment pool_attachment,
+                                    bool optimized,
+                                    CodeStatistics* stats) {
   DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   const auto& code = Code::Handle(
       FinalizeCode(compiler, assembler, pool_attachment, optimized, stats));
@@ -15725,12 +15800,12 @@
   return code.raw();
 }
 
-RawCode* Code::FinalizeCodeAndNotify(const char* name,
-                                     FlowGraphCompiler* compiler,
-                                     compiler::Assembler* assembler,
-                                     PoolAttachment pool_attachment,
-                                     bool optimized,
-                                     CodeStatistics* stats) {
+CodePtr Code::FinalizeCodeAndNotify(const char* name,
+                                    FlowGraphCompiler* compiler,
+                                    compiler::Assembler* assembler,
+                                    PoolAttachment pool_attachment,
+                                    bool optimized,
+                                    CodeStatistics* stats) {
   DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   const auto& code = Code::Handle(
       FinalizeCode(compiler, assembler, pool_attachment, optimized, stats));
@@ -15742,11 +15817,11 @@
 DECLARE_FLAG(charp, write_v8_snapshot_profile_to);
 #endif  // defined(DART_PRECOMPILER)
 
-RawCode* Code::FinalizeCode(FlowGraphCompiler* compiler,
-                            compiler::Assembler* assembler,
-                            PoolAttachment pool_attachment,
-                            bool optimized,
-                            CodeStatistics* stats /* = nullptr */) {
+CodePtr Code::FinalizeCode(FlowGraphCompiler* compiler,
+                           compiler::Assembler* assembler,
+                           PoolAttachment pool_attachment,
+                           bool optimized,
+                           CodeStatistics* stats /* = nullptr */) {
   DEBUG_ASSERT(IsMutatorOrAtSafepoint());
 
   ASSERT(assembler != NULL);
@@ -15812,17 +15887,17 @@
       ASSERT(object->IsOld());
       // N.B. The pointer is embedded in the Instructions object, but visited
       // through the Code object.
-      code.raw()->StorePointer(reinterpret_cast<RawObject**>(addr),
-                               object->raw());
+      code.raw()->ptr()->StorePointer(reinterpret_cast<ObjectPtr*>(addr),
+                                      object->raw());
     }
 
     // Write protect instructions and, if supported by OS, use dual mapping
     // for execution.
     if (FLAG_write_protect_code) {
-      uword address = RawObject::ToAddr(instrs.raw());
+      uword address = ObjectLayout::ToAddr(instrs.raw());
       // Check if a dual mapping exists.
       instrs = Instructions::RawCast(HeapPage::ToExecutable(instrs.raw()));
-      uword exec_address = RawObject::ToAddr(instrs.raw());
+      uword exec_address = ObjectLayout::ToAddr(instrs.raw());
       const bool use_dual_mapping = exec_address != address;
       ASSERT(use_dual_mapping == FLAG_dual_map_code);
 
@@ -15831,14 +15906,14 @@
       // Yet the writable mapping is still turned back from RW to R.
       if (use_dual_mapping) {
         VirtualMemory::Protect(reinterpret_cast<void*>(address),
-                               instrs.raw()->HeapSize(),
+                               instrs.raw()->ptr()->HeapSize(),
                                VirtualMemory::kReadOnly);
         address = exec_address;
       } else {
         // If dual mapping is disabled and we write protect then we have to
         // change the single mapping from RW -> RX.
         VirtualMemory::Protect(reinterpret_cast<void*>(address),
-                               instrs.raw()->HeapSize(),
+                               instrs.raw()->ptr()->HeapSize(),
                                VirtualMemory::kReadExecute);
       }
     }
@@ -15927,34 +16002,34 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
-  return RawCode::ContainsPC(raw_obj, pc_);
+bool Code::SlowFindRawCodeVisitor::FindObject(ObjectPtr raw_obj) const {
+  return CodeLayout::ContainsPC(raw_obj, pc_);
 }
 
-RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
+CodePtr Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
   if (isolate->heap() == NULL) {
     return Code::null();
   }
   HeapIterationScope heap_iteration_scope(Thread::Current());
   SlowFindRawCodeVisitor visitor(pc);
-  RawObject* needle = isolate->heap()->FindOldObject(&visitor);
+  ObjectPtr needle = isolate->heap()->FindOldObject(&visitor);
   if (needle != Code::null()) {
-    return static_cast<RawCode*>(needle);
+    return static_cast<CodePtr>(needle);
   }
   return Code::null();
 }
 
-RawCode* Code::LookupCode(uword pc) {
+CodePtr Code::LookupCode(uword pc) {
   return LookupCodeInIsolate(Isolate::Current(), pc);
 }
 
-RawCode* Code::LookupCodeInVmIsolate(uword pc) {
+CodePtr Code::LookupCodeInVmIsolate(uword pc) {
   return LookupCodeInIsolate(Dart::vm_isolate(), pc);
 }
 
 // Given a pc and a timestamp, lookup the code.
-RawCode* Code::FindCode(uword pc, int64_t timestamp) {
+CodePtr Code::FindCode(uword pc, int64_t timestamp) {
   Code& code = Code::Handle(Code::LookupCode(pc));
   if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
       (code.PayloadStart() == pc)) {
@@ -15973,7 +16048,7 @@
 TokenPosition Code::GetTokenIndexOfPC(uword pc) const {
   uword pc_offset = pc - PayloadStart();
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.TokenPos();
@@ -15983,7 +16058,7 @@
 }
 
 uword Code::GetPcForDeoptId(intptr_t deopt_id,
-                            RawPcDescriptors::Kind kind) const {
+                            PcDescriptorsLayout::Kind kind) const {
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, kind);
   while (iter.MoveNext()) {
@@ -16000,7 +16075,7 @@
 intptr_t Code::GetDeoptIdForOsr(uword pc) const {
   uword pc_offset = pc - PayloadStart();
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kOsrEntry);
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.DeoptId();
@@ -16097,8 +16172,8 @@
                         new_code.UncheckedEntryPointOffset());
 }
 
-void Code::InitializeCachedEntryPointsFrom(RawCode* code,
-                                           RawInstructions* instructions,
+void Code::InitializeCachedEntryPointsFrom(CodePtr code,
+                                           InstructionsPtr instructions,
                                            uint32_t unchecked_offset) {
   NoSafepointScope _;
   const uword entry_point = Instructions::EntryPoint(instructions);
@@ -16141,9 +16216,9 @@
   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
   if (map.IsNull()) {
     ASSERT(!IsFunctionCode() ||
-           (Isolate::Current()->object_store()->megamorphic_miss_code() ==
+           (Isolate::Current()->object_store()->megamorphic_call_miss_code() ==
             this->raw()));
-    return;  // VM stub, allocation stub, or megamorphic miss function.
+    return;  // VM stub, allocation stub, or megamorphic call miss function.
   }
   const Array& id_map = Array::Handle(inlined_id_to_function());
   const Function& root = Function::Handle(function());
@@ -16206,15 +16281,15 @@
 #endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
 }
 
-RawBytecode* Bytecode::New(uword instructions,
-                           intptr_t instructions_size,
-                           intptr_t instructions_offset,
-                           const ObjectPool& object_pool) {
+BytecodePtr Bytecode::New(uword instructions,
+                          intptr_t instructions_size,
+                          intptr_t instructions_offset,
+                          const ObjectPool& object_pool) {
   ASSERT(Object::bytecode_class() != Class::null());
   Bytecode& result = Bytecode::Handle();
   {
     uword size = Bytecode::InstanceSize();
-    RawObject* raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_instructions(instructions);
@@ -16228,7 +16303,7 @@
   return result.raw();
 }
 
-RawExternalTypedData* Bytecode::GetBinary(Zone* zone) const {
+ExternalTypedDataPtr Bytecode::GetBinary(Zone* zone) const {
   const Function& func = Function::Handle(zone, function());
   if (func.IsNull()) {
     return ExternalTypedData::null();
@@ -16269,7 +16344,7 @@
   intptr_t try_index = -1;
   const uword pc_offset = return_address - PayloadStart();
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     // PC descriptors for try blocks in bytecode are generated in pairs,
     // marking start and end of a try block.
@@ -16383,23 +16458,22 @@
   return zone->PrintToString("[Bytecode] %s", function_name);
 }
 
-bool Bytecode::SlowFindRawBytecodeVisitor::FindObject(
-    RawObject* raw_obj) const {
-  return RawBytecode::ContainsPC(raw_obj, pc_);
+bool Bytecode::SlowFindRawBytecodeVisitor::FindObject(ObjectPtr raw_obj) const {
+  return BytecodeLayout::ContainsPC(raw_obj, pc_);
 }
 
-RawBytecode* Bytecode::FindCode(uword pc) {
+BytecodePtr Bytecode::FindCode(uword pc) {
   Thread* thread = Thread::Current();
   HeapIterationScope heap_iteration_scope(thread);
   SlowFindRawBytecodeVisitor visitor(pc);
-  RawObject* needle = thread->heap()->FindOldObject(&visitor);
+  ObjectPtr needle = thread->heap()->FindOldObject(&visitor);
   if (needle != Bytecode::null()) {
-    return static_cast<RawBytecode*>(needle);
+    return static_cast<BytecodePtr>(needle);
   }
   return Bytecode::null();
 }
 
-RawLocalVarDescriptors* Bytecode::GetLocalVarDescriptors() const {
+LocalVarDescriptorsPtr Bytecode::GetLocalVarDescriptors() const {
 #if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
   return LocalVarDescriptors::null();
@@ -16428,7 +16502,7 @@
   return level;
 }
 
-RawContext* Context::New(intptr_t num_variables, Heap::Space space) {
+ContextPtr Context::New(intptr_t num_variables, Heap::Space space) {
   ASSERT(num_variables >= 0);
   ASSERT(Object::context_class() != Class::null());
 
@@ -16439,7 +16513,7 @@
   }
   Context& result = Context::Handle();
   {
-    RawObject* raw = Object::Allocate(
+    ObjectPtr raw = Object::Allocate(
         Context::kClassId, Context::InstanceSize(num_variables), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -16499,7 +16573,7 @@
   THR_Print("}\n");
 }
 
-RawContextScope* ContextScope::New(intptr_t num_variables, bool is_implicit) {
+ContextScopePtr ContextScope::New(intptr_t num_variables, bool is_implicit) {
   ASSERT(Object::context_scope_class() != Class::null());
   if (num_variables < 0 || num_variables > kMaxElements) {
     // This should be caught before we reach here.
@@ -16509,7 +16583,7 @@
   intptr_t size = ContextScope::InstanceSize(num_variables);
   ContextScope& result = ContextScope::Handle();
   {
-    RawObject* raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_num_variables(num_variables);
@@ -16541,7 +16615,7 @@
            Smi::New(declaration_token_pos.value()));
 }
 
-RawString* ContextScope::NameAt(intptr_t scope_index) const {
+StringPtr ContextScope::NameAt(intptr_t scope_index) const {
   return VariableDescAddr(scope_index)->name;
 }
 
@@ -16566,27 +16640,27 @@
 }
 
 bool ContextScope::IsFinalAt(intptr_t scope_index) const {
-  return GetFlagAt(scope_index, RawContextScope::VariableDesc::kIsFinal);
+  return GetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsFinal);
 }
 
 void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const {
-  SetFlagAt(scope_index, RawContextScope::VariableDesc::kIsFinal, is_final);
+  SetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsFinal, is_final);
 }
 
 bool ContextScope::IsLateAt(intptr_t scope_index) const {
-  return GetFlagAt(scope_index, RawContextScope::VariableDesc::kIsLate);
+  return GetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsLate);
 }
 
 void ContextScope::SetIsLateAt(intptr_t scope_index, bool is_late) const {
-  SetFlagAt(scope_index, RawContextScope::VariableDesc::kIsLate, is_late);
+  SetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsLate, is_late);
 }
 
 bool ContextScope::IsConstAt(intptr_t scope_index) const {
-  return GetFlagAt(scope_index, RawContextScope::VariableDesc::kIsConst);
+  return GetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsConst);
 }
 
 void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const {
-  SetFlagAt(scope_index, RawContextScope::VariableDesc::kIsConst, is_const);
+  SetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsConst, is_const);
 }
 
 intptr_t ContextScope::LateInitOffsetAt(intptr_t scope_index) const {
@@ -16599,7 +16673,7 @@
            Smi::New(late_init_offset));
 }
 
-RawAbstractType* ContextScope::TypeAt(intptr_t scope_index) const {
+AbstractTypePtr ContextScope::TypeAt(intptr_t scope_index) const {
   ASSERT(!IsConstAt(scope_index));
   return VariableDescAddr(scope_index)->type;
 }
@@ -16609,7 +16683,7 @@
   StorePointer(&(VariableDescAddr(scope_index)->type), type.raw());
 }
 
-RawInstance* ContextScope::ConstValueAt(intptr_t scope_index) const {
+InstancePtr ContextScope::ConstValueAt(intptr_t scope_index) const {
   ASSERT(IsConstAt(scope_index));
   return VariableDescAddr(scope_index)->value;
 }
@@ -16658,7 +16732,7 @@
   return prev_cstr;
 }
 
-RawArray* MegamorphicCache::buckets() const {
+ArrayPtr MegamorphicCache::buckets() const {
   return raw_ptr()->buckets_;
 }
 
@@ -16685,18 +16759,10 @@
   StoreNonPointer(&raw_ptr()->filled_entry_count_, count);
 }
 
-void MegamorphicCache::set_target_name(const String& value) const {
-  StorePointer(&raw_ptr()->target_name_, value.raw());
-}
-
-void MegamorphicCache::set_arguments_descriptor(const Array& value) const {
-  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
-}
-
-RawMegamorphicCache* MegamorphicCache::New() {
+MegamorphicCachePtr MegamorphicCache::New() {
   MegamorphicCache& result = MegamorphicCache::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(MegamorphicCache::kClassId,
                          MegamorphicCache::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
@@ -16706,11 +16772,11 @@
   return result.raw();
 }
 
-RawMegamorphicCache* MegamorphicCache::New(const String& target_name,
-                                           const Array& arguments_descriptor) {
+MegamorphicCachePtr MegamorphicCache::New(const String& target_name,
+                                          const Array& arguments_descriptor) {
   MegamorphicCache& result = MegamorphicCache::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(MegamorphicCache::kClassId,
                          MegamorphicCache::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
@@ -16802,10 +16868,10 @@
   intptr_t capacity = mask() + 1;
   for (intptr_t i = 0; i < capacity; ++i) {
     const intptr_t target_index = i * kEntryLength + kTargetFunctionIndex;
-    RawObject** slot = &Array::DataOf(buckets())[target_index];
+    ObjectPtr* slot = &Array::DataOf(buckets())[target_index];
     const intptr_t cid = (*slot)->GetClassIdMayBeSmi();
     if (cid == kFunctionCid) {
-      RawCode* code = Function::CurrentCodeOf(Function::RawCast(*slot));
+      CodePtr code = Function::CurrentCodeOf(Function::RawCast(*slot));
       *slot = Smi::FromAlignedAddress(Code::EntryPointOf(code));
     } else {
       ASSERT(cid == kSmiCid);
@@ -16821,13 +16887,13 @@
   cached_array_ = NULL;
 }
 
-RawSubtypeTestCache* SubtypeTestCache::New() {
+SubtypeTestCachePtr SubtypeTestCache::New() {
   ASSERT(Object::subtypetestcache_class() != Class::null());
   SubtypeTestCache& result = SubtypeTestCache::Handle();
   {
     // SubtypeTestCache objects are long living objects, allocate them in the
     // old generation.
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(SubtypeTestCache::kClassId,
                          SubtypeTestCache::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
@@ -16922,14 +16988,14 @@
   return "Error";
 }
 
-RawApiError* ApiError::New() {
+ApiErrorPtr ApiError::New() {
   ASSERT(Object::api_error_class() != Class::null());
-  RawObject* raw = Object::Allocate(ApiError::kClassId,
-                                    ApiError::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawApiError*>(raw);
+  ObjectPtr raw = Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(),
+                                   Heap::kOld);
+  return static_cast<ApiErrorPtr>(raw);
 }
 
-RawApiError* ApiError::New(const String& message, Heap::Space space) {
+ApiErrorPtr ApiError::New(const String& message, Heap::Space space) {
 #ifndef PRODUCT
   if (FLAG_print_stacktrace_at_api_error) {
     OS::PrintErr("ApiError: %s\n", message.ToCString());
@@ -16940,7 +17006,7 @@
   ASSERT(Object::api_error_class() != Class::null());
   ApiError& result = ApiError::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -16962,26 +17028,26 @@
   return "ApiError";
 }
 
-RawLanguageError* LanguageError::New() {
+LanguageErrorPtr LanguageError::New() {
   ASSERT(Object::language_error_class() != Class::null());
-  RawObject* raw = Object::Allocate(LanguageError::kClassId,
-                                    LanguageError::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawLanguageError*>(raw);
+  ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
+                                   LanguageError::InstanceSize(), Heap::kOld);
+  return static_cast<LanguageErrorPtr>(raw);
 }
 
-RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error,
-                                               const Script& script,
-                                               TokenPosition token_pos,
-                                               bool report_after_token,
-                                               Report::Kind kind,
-                                               Heap::Space space,
-                                               const char* format,
-                                               va_list args) {
+LanguageErrorPtr LanguageError::NewFormattedV(const Error& prev_error,
+                                              const Script& script,
+                                              TokenPosition token_pos,
+                                              bool report_after_token,
+                                              Report::Kind kind,
+                                              Heap::Space space,
+                                              const char* format,
+                                              va_list args) {
   ASSERT(Object::language_error_class() != Class::null());
   LanguageError& result = LanguageError::Handle();
   {
-    RawObject* raw = Object::Allocate(LanguageError::kClassId,
-                                      LanguageError::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
+                                     LanguageError::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -16995,17 +17061,17 @@
   return result.raw();
 }
 
-RawLanguageError* LanguageError::NewFormatted(const Error& prev_error,
-                                              const Script& script,
-                                              TokenPosition token_pos,
-                                              bool report_after_token,
-                                              Report::Kind kind,
-                                              Heap::Space space,
-                                              const char* format,
-                                              ...) {
+LanguageErrorPtr LanguageError::NewFormatted(const Error& prev_error,
+                                             const Script& script,
+                                             TokenPosition token_pos,
+                                             bool report_after_token,
+                                             Report::Kind kind,
+                                             Heap::Space space,
+                                             const char* format,
+                                             ...) {
   va_list args;
   va_start(args, format);
-  RawLanguageError* result = LanguageError::NewFormattedV(
+  LanguageErrorPtr result = LanguageError::NewFormattedV(
       prev_error, script, token_pos, report_after_token, kind, space, format,
       args);
   NoSafepointScope no_safepoint;
@@ -17013,14 +17079,14 @@
   return result;
 }
 
-RawLanguageError* LanguageError::New(const String& formatted_message,
-                                     Report::Kind kind,
-                                     Heap::Space space) {
+LanguageErrorPtr LanguageError::New(const String& formatted_message,
+                                    Report::Kind kind,
+                                    Heap::Space space) {
   ASSERT(Object::language_error_class() != Class::null());
   LanguageError& result = LanguageError::Handle();
   {
-    RawObject* raw = Object::Allocate(LanguageError::kClassId,
-                                      LanguageError::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
+                                     LanguageError::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17058,7 +17124,7 @@
   StorePointer(&raw_ptr()->formatted_message_, value.raw());
 }
 
-RawString* LanguageError::FormatMessage() const {
+StringPtr LanguageError::FormatMessage() const {
   if (formatted_message() != String::null()) {
     return formatted_message();
   }
@@ -17086,15 +17152,14 @@
   return "LanguageError";
 }
 
-RawUnhandledException* UnhandledException::New(const Instance& exception,
-                                               const Instance& stacktrace,
-                                               Heap::Space space) {
+UnhandledExceptionPtr UnhandledException::New(const Instance& exception,
+                                              const Instance& stacktrace,
+                                              Heap::Space space) {
   ASSERT(Object::unhandled_exception_class() != Class::null());
   UnhandledException& result = UnhandledException::Handle();
   {
-    RawObject* raw =
-        Object::Allocate(UnhandledException::kClassId,
-                         UnhandledException::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
+                                     UnhandledException::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17103,13 +17168,12 @@
   return result.raw();
 }
 
-RawUnhandledException* UnhandledException::New(Heap::Space space) {
+UnhandledExceptionPtr UnhandledException::New(Heap::Space space) {
   ASSERT(Object::unhandled_exception_class() != Class::null());
   UnhandledException& result = UnhandledException::Handle();
   {
-    RawObject* raw =
-        Object::Allocate(UnhandledException::kClassId,
-                         UnhandledException::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
+                                     UnhandledException::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17161,12 +17225,12 @@
   return "UnhandledException";
 }
 
-RawUnwindError* UnwindError::New(const String& message, Heap::Space space) {
+UnwindErrorPtr UnwindError::New(const String& message, Heap::Space space) {
   ASSERT(Object::unwind_error_class() != Class::null());
   UnwindError& result = UnwindError::Handle();
   {
-    RawObject* raw = Object::Allocate(UnwindError::kClassId,
-                                      UnwindError::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(UnwindError::kClassId,
+                                     UnwindError::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17192,9 +17256,9 @@
   return "UnwindError";
 }
 
-RawObject* Instance::InvokeGetter(const String& getter_name,
-                                  bool respect_reflectable,
-                                  bool check_is_entrypoint) const {
+ObjectPtr Instance::InvokeGetter(const String& getter_name,
+                                 bool respect_reflectable,
+                                 bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -17214,7 +17278,7 @@
     // The getter must correspond to either an entry-point field or a getter
     // method explicitly marked.
     Field& field = Field::Handle(zone);
-    if (function.kind() == RawFunction::kImplicitGetter) {
+    if (function.kind() == FunctionLayout::kImplicitGetter) {
       field = function.accessor_field();
     }
     if (!field.IsNull()) {
@@ -17252,10 +17316,10 @@
                                 type_args);
 }
 
-RawObject* Instance::InvokeSetter(const String& setter_name,
-                                  const Instance& value,
-                                  bool respect_reflectable,
-                                  bool check_is_entrypoint) const {
+ObjectPtr Instance::InvokeSetter(const String& setter_name,
+                                 const Instance& value,
+                                 bool respect_reflectable,
+                                 bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -17275,7 +17339,7 @@
     // The setter must correspond to either an entry-point field or a setter
     // method explicitly marked.
     Field& field = Field::Handle(zone);
-    if (setter.kind() == RawFunction::kImplicitSetter) {
+    if (setter.kind() == FunctionLayout::kImplicitSetter) {
       field = setter.accessor_field();
     }
     if (!field.IsNull()) {
@@ -17299,11 +17363,11 @@
                                 type_args);
 }
 
-RawObject* Instance::Invoke(const String& function_name,
-                            const Array& args,
-                            const Array& arg_names,
-                            bool respect_reflectable,
-                            bool check_is_entrypoint) const {
+ObjectPtr Instance::Invoke(const String& function_name,
+                           const Array& args,
+                           const Array& arg_names,
+                           bool respect_reflectable,
+                           bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Class& klass = Class::Handle(zone, clazz());
@@ -17335,7 +17399,7 @@
       if (check_is_entrypoint) {
         CHECK_ERROR(EntryPointFieldInvocationError(function_name));
       }
-      ASSERT(function.kind() != RawFunction::kMethodExtractor);
+      ASSERT(function.kind() != FunctionLayout::kMethodExtractor);
       // Invoke the getter.
       const int kNumArgs = 1;
       const Array& getter_args = Array::Handle(zone, Array::New(kNumArgs));
@@ -17363,7 +17427,7 @@
                                 type_args);
 }
 
-RawObject* Instance::EvaluateCompiledExpression(
+ObjectPtr Instance::EvaluateCompiledExpression(
     const Class& method_cls,
     const ExternalTypedData& kernel_buffer,
     const Array& type_definitions,
@@ -17385,13 +17449,13 @@
       type_arguments);
 }
 
-RawObject* Instance::HashCode() const {
+ObjectPtr Instance::HashCode() const {
   // TODO(koda): Optimize for all builtin classes and all classes
   // that do not override hashCode.
   return DartLibraryCalls::HashCode(*this);
 }
 
-RawObject* Instance::IdentityHashCode() const {
+ObjectPtr Instance::IdentityHashCode() const {
   return DartLibraryCalls::IdentityHashCode(*this);
 }
 
@@ -17418,8 +17482,8 @@
     uword other_addr = reinterpret_cast<uword>(other.raw_ptr());
     for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
          offset += kWordSize) {
-      if ((*reinterpret_cast<RawObject**>(this_addr + offset)) !=
-          (*reinterpret_cast<RawObject**>(other_addr + offset))) {
+      if ((*reinterpret_cast<ObjectPtr*>(this_addr + offset)) !=
+          (*reinterpret_cast<ObjectPtr*>(other_addr + offset))) {
         return false;
       }
     }
@@ -17444,7 +17508,7 @@
   Instance& member = Instance::Handle();
 
   const auto unboxed_fields_bitmap =
-      thread->isolate()->group()->class_table()->GetUnboxedFieldsMapAt(
+      thread->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
           GetClassId());
 
   for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
@@ -17453,7 +17517,7 @@
       hash =
           CombineHashes(hash, *reinterpret_cast<intptr_t*>(this_addr + offset));
     } else {
-      member ^= *reinterpret_cast<RawObject**>(this_addr + offset);
+      member ^= *reinterpret_cast<ObjectPtr*>(this_addr + offset);
       hash = CombineHashes(hash, member.CanonicalizeHash());
     }
   }
@@ -17470,7 +17534,7 @@
 
   bool has_pointers() const { return has_pointers_; }
 
-  void VisitPointers(RawObject** first, RawObject** last) {
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
     if (first != last) {
       has_pointers_ = true;
     }
@@ -17496,7 +17560,7 @@
     const intptr_t instance_size = SizeFromClass();
     ASSERT(instance_size != 0);
     const auto unboxed_fields_bitmap =
-        thread->isolate()->group()->class_table()->GetUnboxedFieldsMapAt(
+        thread->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
             GetClassId());
     for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
          offset += kWordSize) {
@@ -17524,19 +17588,19 @@
 #if defined(DEBUG)
     // Make sure that we are not missing any fields.
     CheckForPointers has_pointers(Isolate::Current()->group());
-    this->raw()->VisitPointers(&has_pointers);
+    this->raw()->ptr()->VisitPointers(&has_pointers);
     ASSERT(!has_pointers.has_pointers());
 #endif  // DEBUG
   }
   return true;
 }
 
-RawInstance* Instance::CopyShallowToOldSpace(Thread* thread) const {
+InstancePtr Instance::CopyShallowToOldSpace(Thread* thread) const {
   return Instance::RawCast(Object::Clone(*this, Heap::kOld));
 }
 
-RawInstance* Instance::CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const {
+InstancePtr Instance::CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const {
   ASSERT(error_str != NULL);
   ASSERT(*error_str == NULL);
   ASSERT(!IsNull());
@@ -17581,7 +17645,7 @@
 }
 #endif  // DEBUG
 
-RawObject* Instance::GetField(const Field& field) const {
+ObjectPtr Instance::GetField(const Field& field) const {
   if (FLAG_precompiled_mode && field.is_unboxing_candidate()) {
     switch (field.guarded_cid()) {
       case kDoubleCid:
@@ -17636,7 +17700,7 @@
   }
 }
 
-RawAbstractType* Instance::GetType(Heap::Space space) const {
+AbstractTypePtr Instance::GetType(Heap::Space space) const {
   if (IsNull()) {
     return Type::NullType();
   }
@@ -17668,16 +17732,14 @@
       type_arguments = GetTypeArguments();
     }
     type = Type::New(cls, type_arguments, TokenPosition::kNoSource,
-                     Dart::non_nullable_flag() ? Nullability::kNonNullable
-                                               : Nullability::kLegacy,
-                     space);
+                     Nullability::kNonNullable, space);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
   }
   return type.raw();
 }
 
-RawTypeArguments* Instance::GetTypeArguments() const {
+TypeArgumentsPtr Instance::GetTypeArguments() const {
   ASSERT(!IsType());
   const Class& cls = Class::Handle(clazz());
   intptr_t field_offset = cls.host_type_arguments_field_offset();
@@ -17761,7 +17823,9 @@
   ASSERT(other.IsFinalized());
   ASSERT(!other.IsTypeRef());  // Must be dereferenced at compile time.
   if (other.IsNullable()) {
-    // The type will remain nullable after instantiation.
+    // This case includes top types (void, dynamic, Object?).
+    // The uninstantiated nullable type will remain nullable after
+    // instantiation.
     return true;
   }
   if (other.IsFutureOrType()) {
@@ -17781,7 +17845,7 @@
     return Instance::NullIsInstanceOf(type, Object::null_type_arguments(),
                                       Object::null_type_arguments());
   }
-  return other.IsLegacy() && (other.IsTopType() || other.IsNeverType());
+  return other.IsLegacy() && (other.IsObjectType() || other.IsNeverType());
 }
 
 bool Instance::NullIsAssignableTo(const AbstractType& other) {
@@ -17812,10 +17876,9 @@
     const TypeArguments& other_function_type_arguments) const {
   ASSERT(other.IsFinalized());
   ASSERT(!other.IsTypeRef());  // Must be dereferenced at compile time.
-  // Note that Object::sentinel() has Null class, but !IsNull().
   ASSERT(raw() != Object::sentinel().raw());
   // Instance may not have runtimeType dynamic, void, or Never.
-  if (other.IsTopType()) {
+  if (other.IsTopTypeForSubtyping()) {
     return true;
   }
   Thread* thread = Thread::Current();
@@ -17827,7 +17890,8 @@
   }
   const Class& cls = Class::Handle(zone, clazz());
   if (cls.IsClosureClass()) {
-    if (other.IsDartFunctionType() || other.IsDartClosureType()) {
+    if (other.IsDartFunctionType() || other.IsDartClosureType() ||
+        other.IsObjectType()) {
       return true;
     }
     AbstractType& instantiated_other = AbstractType::Handle(zone, other.raw());
@@ -17838,12 +17902,12 @@
       if (instantiated_other.IsTypeRef()) {
         instantiated_other = TypeRef::Cast(instantiated_other).type();
       }
-      if (instantiated_other.IsTopType() ||
+      if (instantiated_other.IsTopTypeForSubtyping() ||
           instantiated_other.IsDartFunctionType()) {
         return true;
       }
     }
-    if (IsFutureOrInstanceOf(zone, instantiated_other)) {
+    if (RuntimeTypeIsSubtypeOfFutureOr(zone, instantiated_other)) {
       return true;
     }
     if (!instantiated_other.IsFunctionType()) {
@@ -17878,7 +17942,7 @@
     if (instantiated_other.IsTypeRef()) {
       instantiated_other = TypeRef::Cast(instantiated_other).type();
     }
-    if (instantiated_other.IsTopType()) {
+    if (instantiated_other.IsTopTypeForSubtyping()) {
       return true;
     }
   }
@@ -17890,7 +17954,7 @@
     if (instantiated_other.IsNullType()) {
       return true;
     }
-    if (IsFutureOrInstanceOf(zone, instantiated_other)) {
+    if (RuntimeTypeIsSubtypeOfFutureOr(zone, instantiated_other)) {
       return true;
     }
     return !instantiated_other.IsNonNullable();
@@ -17901,14 +17965,14 @@
                             instantiated_other, Heap::kOld);
 }
 
-bool Instance::IsFutureOrInstanceOf(Zone* zone,
-                                    const AbstractType& other) const {
+bool Instance::RuntimeTypeIsSubtypeOfFutureOr(Zone* zone,
+                                              const AbstractType& other) const {
   if (other.IsFutureOrType()) {
     const TypeArguments& other_type_arguments =
         TypeArguments::Handle(zone, other.arguments());
     const AbstractType& other_type_arg =
         AbstractType::Handle(zone, other_type_arguments.TypeAtNullSafe(0));
-    if (other_type_arg.IsTopType()) {
+    if (other_type_arg.IsTopTypeForSubtyping()) {
       return true;
     }
     if (Class::Handle(zone, clazz()).IsFutureClass()) {
@@ -17949,8 +18013,7 @@
 
 intptr_t* Instance::NativeFieldsDataAddr() const {
   ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0);
-  RawTypedData* native_fields =
-      reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+  TypedDataPtr native_fields = static_cast<TypedDataPtr>(*NativeFieldsAddr());
   if (native_fields == TypedData::null()) {
     return NULL;
   }
@@ -18008,24 +18071,24 @@
   return false;
 }
 
-RawInstance* Instance::New(const Class& cls, Heap::Space space) {
+InstancePtr Instance::New(const Class& cls, Heap::Space space) {
   Thread* thread = Thread::Current();
   if (cls.EnsureIsFinalized(thread) != Error::null()) {
     return Instance::null();
   }
   intptr_t instance_size = cls.host_instance_size();
   ASSERT(instance_size > 0);
-  RawObject* raw = Object::Allocate(cls.id(), instance_size, space);
-  return reinterpret_cast<RawInstance*>(raw);
+  ObjectPtr raw = Object::Allocate(cls.id(), instance_size, space);
+  return static_cast<InstancePtr>(raw);
 }
 
-RawInstance* Instance::NewFromCidAndSize(SharedClassTable* shared_class_table,
-                                         classid_t cid,
-                                         Heap::Space heap) {
+InstancePtr Instance::NewFromCidAndSize(SharedClassTable* shared_class_table,
+                                        classid_t cid,
+                                        Heap::Space heap) {
   const intptr_t instance_size = shared_class_table->SizeAt(cid);
   ASSERT(instance_size > 0);
-  RawObject* raw = Object::Allocate(cid, instance_size, heap);
-  return reinterpret_cast<RawInstance*>(raw);
+  ObjectPtr raw = Object::Allocate(cid, instance_size, heap);
+  return static_cast<InstancePtr>(raw);
 }
 
 bool Instance::IsValidFieldOffset(intptr_t offset) const {
@@ -18037,9 +18100,8 @@
 }
 
 intptr_t Instance::ElementSizeFor(intptr_t cid) {
-  if (RawObject::IsExternalTypedDataClassId(cid) ||
-      RawObject::IsTypedDataClassId(cid) ||
-      RawObject::IsTypedDataViewClassId(cid)) {
+  if (IsExternalTypedDataClassId(cid) || IsTypedDataClassId(cid) ||
+      IsTypedDataViewClassId(cid)) {
     return TypedDataBase::ElementSizeInBytes(cid);
   }
   switch (cid) {
@@ -18061,12 +18123,11 @@
 }
 
 intptr_t Instance::DataOffsetFor(intptr_t cid) {
-  if (RawObject::IsExternalTypedDataClassId(cid) ||
-      RawObject::IsExternalStringClassId(cid)) {
+  if (IsExternalTypedDataClassId(cid) || IsExternalStringClassId(cid)) {
     // Elements start at offset 0 of the external data.
     return 0;
   }
-  if (RawObject::IsTypedDataClassId(cid)) {
+  if (IsTypedDataClassId(cid)) {
     return TypedData::data_offset();
   }
   switch (cid) {
@@ -18116,13 +18177,13 @@
   return kIllegalCid;
 }
 
-RawClass* AbstractType::type_class() const {
+ClassPtr AbstractType::type_class() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return Class::null();
 }
 
-RawTypeArguments* AbstractType::arguments() const {
+TypeArgumentsPtr AbstractType::arguments() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -18145,7 +18206,33 @@
   return Nullability::kNullable;
 }
 
-RawAbstractType* AbstractType::SetInstantiatedNullability(
+bool AbstractType::IsStrictlyNonNullable() const {
+  // Null can be assigned to legacy and nullable types.
+  if (!IsNonNullable()) {
+    return false;
+  }
+
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+
+  // In weak mode null can be assigned to any type.
+  if (!thread->isolate()->null_safety()) {
+    return false;
+  }
+
+  if (IsTypeParameter()) {
+    const auto& bound =
+        AbstractType::Handle(zone, TypeParameter::Cast(*this).bound());
+    ASSERT(!bound.IsNull());
+    return bound.IsStrictlyNonNullable();
+  }
+  if (IsFutureOrType()) {
+    return AbstractType::Handle(zone, UnwrapFutureOr()).IsStrictlyNonNullable();
+  }
+  return true;
+}
+
+AbstractTypePtr AbstractType::SetInstantiatedNullability(
     const TypeParameter& type_param,
     Heap::Space space) const {
   Nullability result_nullability;
@@ -18182,66 +18269,62 @@
       .SetInstantiatedNullability(type_param, space);
 }
 
-RawAbstractType* AbstractType::NormalizeFutureOrType(Heap::Space space) const {
-  if (Dart::non_nullable_flag()) {
-    if (IsFutureOrType()) {
-      const AbstractType& unwrapped_type =
-          AbstractType::Handle(UnwrapFutureOr());
-      const classid_t cid = unwrapped_type.type_class_id();
-      if (cid == kDynamicCid || cid == kVoidCid) {
+AbstractTypePtr AbstractType::NormalizeFutureOrType(Heap::Space space) const {
+  if (IsFutureOrType()) {
+    const AbstractType& unwrapped_type = AbstractType::Handle(UnwrapFutureOr());
+    const classid_t cid = unwrapped_type.type_class_id();
+    if (cid == kDynamicCid || cid == kVoidCid) {
+      return unwrapped_type.raw();
+    }
+    if (cid == kInstanceCid) {
+      if (IsNonNullable()) {
         return unwrapped_type.raw();
       }
-      if (cid == kInstanceCid) {
-        if (IsNonNullable()) {
-          return unwrapped_type.raw();
-        }
-        if (IsNullable() || unwrapped_type.IsNullable()) {
-          return Type::Cast(unwrapped_type)
-              .ToNullability(Nullability::kNullable, space);
-        }
+      if (IsNullable() || unwrapped_type.IsNullable()) {
         return Type::Cast(unwrapped_type)
-            .ToNullability(Nullability::kLegacy, space);
+            .ToNullability(Nullability::kNullable, space);
       }
-      if (cid == kNeverCid && unwrapped_type.IsNonNullable()) {
-        ObjectStore* object_store = Isolate::Current()->object_store();
-        if (object_store->non_nullable_future_never_type() == Type::null()) {
-          const Class& cls = Class::Handle(object_store->future_class());
-          ASSERT(!cls.IsNull());
-          const TypeArguments& type_args =
-              TypeArguments::Handle(TypeArguments::New(1));
-          type_args.SetTypeAt(0, never_type());
-          Type& type =
-              Type::Handle(Type::New(cls, type_args, TokenPosition::kNoSource,
-                                     Nullability::kNonNullable));
-          type.SetIsFinalized();
-          type ^= type.Canonicalize();
-          object_store->set_non_nullable_future_never_type(type);
-        }
-        const Type& future_never_type =
-            Type::Handle(object_store->non_nullable_future_never_type());
-        return future_never_type.ToNullability(nullability(), space);
+      return Type::Cast(unwrapped_type)
+          .ToNullability(Nullability::kLegacy, space);
+    }
+    if (cid == kNeverCid && unwrapped_type.IsNonNullable()) {
+      ObjectStore* object_store = Isolate::Current()->object_store();
+      if (object_store->non_nullable_future_never_type() == Type::null()) {
+        const Class& cls = Class::Handle(object_store->future_class());
+        ASSERT(!cls.IsNull());
+        const TypeArguments& type_args =
+            TypeArguments::Handle(TypeArguments::New(1));
+        type_args.SetTypeAt(0, Type::Handle(object_store->never_type()));
+        Type& type =
+            Type::Handle(Type::New(cls, type_args, TokenPosition::kNoSource,
+                                   Nullability::kNonNullable));
+        type.SetIsFinalized();
+        type ^= type.Canonicalize();
+        object_store->set_non_nullable_future_never_type(type);
       }
-      if (cid == kNullCid) {
-        ObjectStore* object_store = Isolate::Current()->object_store();
-        if (object_store->nullable_future_null_type() == Type::null()) {
-          const Class& cls = Class::Handle(object_store->future_class());
-          ASSERT(!cls.IsNull());
-          const TypeArguments& type_args =
-              TypeArguments::Handle(TypeArguments::New(1));
-          Type& type = Type::Handle(object_store->null_type());
-          type_args.SetTypeAt(0, type);
-          type = Type::New(cls, type_args, TokenPosition::kNoSource,
-                           Nullability::kNullable);
-          type.SetIsFinalized();
-          type ^= type.Canonicalize();
-          object_store->set_nullable_future_null_type(type);
-        }
-        return object_store->nullable_future_null_type();
+      const Type& future_never_type =
+          Type::Handle(object_store->non_nullable_future_never_type());
+      return future_never_type.ToNullability(nullability(), space);
+    }
+    if (cid == kNullCid) {
+      ObjectStore* object_store = Isolate::Current()->object_store();
+      if (object_store->nullable_future_null_type() == Type::null()) {
+        const Class& cls = Class::Handle(object_store->future_class());
+        ASSERT(!cls.IsNull());
+        const TypeArguments& type_args =
+            TypeArguments::Handle(TypeArguments::New(1));
+        Type& type = Type::Handle(object_store->null_type());
+        type_args.SetTypeAt(0, type);
+        type = Type::New(cls, type_args, TokenPosition::kNoSource,
+                         Nullability::kNullable);
+        type.SetIsFinalized();
+        type ^= type.Canonicalize();
+        object_store->set_nullable_future_null_type(type);
       }
-      if (IsNullable() && unwrapped_type.IsNullable()) {
-        return Type::Cast(*this).ToNullability(Nullability::kNonNullable,
-                                               space);
-      }
+      return object_store->nullable_future_null_type();
+    }
+    if (IsNullable() && unwrapped_type.IsNullable()) {
+      return Type::Cast(*this).ToNullability(Nullability::kNonNullable, space);
     }
   }
   return raw();
@@ -18291,7 +18374,7 @@
   return false;
 }
 
-RawAbstractType* AbstractType::InstantiateFrom(
+AbstractTypePtr AbstractType::InstantiateFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     intptr_t num_free_fun_type_params,
@@ -18302,7 +18385,7 @@
   return NULL;
 }
 
-RawAbstractType* AbstractType::Canonicalize(TrailPtr trail) const {
+AbstractTypePtr AbstractType::Canonicalize(TrailPtr trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -18313,7 +18396,7 @@
   UNREACHABLE();
 }
 
-RawAbstractType* AbstractType::OnlyBuddyInTrail(TrailPtr trail) const {
+AbstractTypePtr AbstractType::OnlyBuddyInTrail(TrailPtr trail) const {
   if (trail == NULL) {
     return AbstractType::null();
   }
@@ -18408,7 +18491,7 @@
   }
 }
 
-RawString* AbstractType::PrintURIs(URIs* uris) {
+StringPtr AbstractType::PrintURIs(URIs* uris) {
   ASSERT(uris != NULL);
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -18449,14 +18532,14 @@
   }
 }
 
-RawString* AbstractType::Name() const {
+StringPtr AbstractType::Name() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintName(kInternalName, &printer);
   return Symbols::New(thread, printer.buffer());
 }
 
-RawString* AbstractType::UserVisibleName() const {
+StringPtr AbstractType::UserVisibleName() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
   PrintName(kUserVisibleName, &printer);
@@ -18544,7 +18627,7 @@
   // the type.
 }
 
-RawString* AbstractType::ClassName() const {
+StringPtr AbstractType::ClassName() const {
   ASSERT(!IsFunctionType());
   return Class::Handle(type_class()).Name();
 }
@@ -18561,8 +18644,7 @@
   return type_class_id() == kNeverCid;
 }
 
-// Caution: IsTopType() does not return true for non-nullable Object.
-bool AbstractType::IsTopType() const {
+bool AbstractType::IsTopTypeForInstanceOf() const {
   const classid_t cid = type_class_id();
   if (cid == kDynamicCid || cid == kVoidCid) {
     return true;
@@ -18572,12 +18654,12 @@
   }
   if (cid == kFutureOrCid) {
     // FutureOr<T> where T is a top type behaves as a top type.
-    return AbstractType::Handle(UnwrapFutureOr()).IsTopType();
+    return AbstractType::Handle(UnwrapFutureOr()).IsTopTypeForInstanceOf();
   }
   return false;
 }
 
-bool AbstractType::IsTopTypeForAssignability() const {
+bool AbstractType::IsTopTypeForSubtyping() const {
   const classid_t cid = type_class_id();
   if (cid == kDynamicCid || cid == kVoidCid) {
     return true;
@@ -18585,11 +18667,11 @@
   if (cid == kInstanceCid) {  // Object type.
     // NNBD weak mode uses LEGACY_SUBTYPE for assignability / 'as' tests,
     // and non-nullable Object is a top type according to LEGACY_SUBTYPE.
-    return !Isolate::Current()->null_safety() || !IsNonNullable();
+    return !IsNonNullable() || !Isolate::Current()->null_safety();
   }
   if (cid == kFutureOrCid) {
     // FutureOr<T> where T is a top type behaves as a top type.
-    return AbstractType::Handle(UnwrapFutureOr()).IsTopTypeForAssignability();
+    return AbstractType::Handle(UnwrapFutureOr()).IsTopTypeForSubtyping();
   }
   return false;
 }
@@ -18642,7 +18724,7 @@
   return HasTypeClass() && type_class_id() == kFfiPointerCid;
 }
 
-RawAbstractType* AbstractType::UnwrapFutureOr() const {
+AbstractTypePtr AbstractType::UnwrapFutureOr() const {
   if (!IsFutureOrType()) {
     return raw();
   }
@@ -18675,7 +18757,7 @@
     return true;
   }
   // Right top type.
-  if (other.IsTopType()) {
+  if (other.IsTopTypeForSubtyping()) {
     return true;
   }
   // Left bottom type.
@@ -18788,7 +18870,7 @@
         TypeArguments::Handle(zone, other.arguments());
     const AbstractType& other_type_arg =
         AbstractType::Handle(zone, other_type_arguments.TypeAtNullSafe(0));
-    if (other_type_arg.IsTopType()) {
+    if (other_type_arg.IsTopTypeForSubtyping()) {
       return true;
     }
     // Retry the IsSubtypeOf check after unwrapping type arg of FutureOr.
@@ -18818,8 +18900,7 @@
   if (stub.IsNull()) {
     // This only happens during bootstrapping when creating Type objects before
     // we have the instructions.
-    ASSERT(type_class_id() == kDynamicCid || type_class_id() == kVoidCid ||
-           type_class_id() == kNeverCid);
+    ASSERT(type_class_id() == kDynamicCid || type_class_id() == kVoidCid);
     StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, 0);
   } else {
     StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, stub.EntryPoint());
@@ -18827,79 +18908,87 @@
   StorePointer(&raw_ptr()->type_test_stub_, stub.raw());
 }
 
-RawType* Type::NullType() {
+TypePtr Type::NullType() {
   return Isolate::Current()->object_store()->null_type();
 }
 
-RawType* Type::DynamicType() {
+TypePtr Type::DynamicType() {
   return Object::dynamic_type().raw();
 }
 
-RawType* Type::VoidType() {
+TypePtr Type::VoidType() {
   return Object::void_type().raw();
 }
 
-RawType* Type::NeverType() {
-  return Object::never_type().raw();
+TypePtr Type::NeverType() {
+  return Isolate::Current()->object_store()->never_type();
 }
 
-RawType* Type::ObjectType() {
+TypePtr Type::ObjectType() {
   return Isolate::Current()->object_store()->object_type();
 }
 
-RawType* Type::BoolType() {
+TypePtr Type::BoolType() {
   return Isolate::Current()->object_store()->bool_type();
 }
 
-RawType* Type::IntType() {
+TypePtr Type::IntType() {
   return Isolate::Current()->object_store()->int_type();
 }
 
-RawType* Type::SmiType() {
+TypePtr Type::NullableIntType() {
+  return Isolate::Current()->object_store()->nullable_int_type();
+}
+
+TypePtr Type::SmiType() {
   return Isolate::Current()->object_store()->smi_type();
 }
 
-RawType* Type::MintType() {
+TypePtr Type::MintType() {
   return Isolate::Current()->object_store()->mint_type();
 }
 
-RawType* Type::Double() {
+TypePtr Type::Double() {
   return Isolate::Current()->object_store()->double_type();
 }
 
-RawType* Type::Float32x4() {
+TypePtr Type::NullableDouble() {
+  return Isolate::Current()->object_store()->nullable_double_type();
+}
+
+TypePtr Type::Float32x4() {
   return Isolate::Current()->object_store()->float32x4_type();
 }
 
-RawType* Type::Float64x2() {
+TypePtr Type::Float64x2() {
   return Isolate::Current()->object_store()->float64x2_type();
 }
 
-RawType* Type::Int32x4() {
+TypePtr Type::Int32x4() {
   return Isolate::Current()->object_store()->int32x4_type();
 }
 
-RawType* Type::Number() {
+TypePtr Type::Number() {
   return Isolate::Current()->object_store()->number_type();
 }
 
-RawType* Type::StringType() {
+TypePtr Type::StringType() {
   return Isolate::Current()->object_store()->string_type();
 }
 
-RawType* Type::ArrayType() {
+TypePtr Type::ArrayType() {
   return Isolate::Current()->object_store()->array_type();
 }
 
-RawType* Type::DartFunctionType() {
+TypePtr Type::DartFunctionType() {
   return Isolate::Current()->object_store()->function_type();
 }
 
-RawType* Type::DartTypeType() {
+TypePtr Type::DartTypeType() {
   return Isolate::Current()->object_store()->type_type();
 }
 
-RawType* Type::NewNonParameterizedType(const Class& type_class) {
+TypePtr Type::NewNonParameterizedType(const Class& type_class) {
   ASSERT(type_class.NumTypeArguments() == 0);
   if (type_class.IsNullClass()) {
     return Type::NullType();
@@ -18916,8 +19005,7 @@
   if (type.IsNull()) {
     type = Type::New(Class::Handle(type_class.raw()),
                      Object::null_type_arguments(), TokenPosition::kNoSource,
-                     Dart::non_nullable_flag() ? Nullability::kNonNullable
-                                               : Nullability::kLegacy);
+                     Nullability::kNonNullable);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
     type_class.set_declaration_type(type);
@@ -18929,24 +19017,24 @@
 void Type::SetIsFinalized() const {
   ASSERT(!IsFinalized());
   if (IsInstantiated()) {
-    set_type_state(RawType::kFinalizedInstantiated);
+    set_type_state(TypeLayout::kFinalizedInstantiated);
   } else {
-    set_type_state(RawType::kFinalizedUninstantiated);
+    set_type_state(TypeLayout::kFinalizedUninstantiated);
   }
 }
 
 void Type::ResetIsFinalized() const {
   ASSERT(IsFinalized());
-  set_type_state(RawType::kBeingFinalized);
+  set_type_state(TypeLayout::kBeingFinalized);
   SetIsFinalized();
 }
 
 void Type::SetIsBeingFinalized() const {
   ASSERT(!IsFinalized() && !IsBeingFinalized());
-  set_type_state(RawType::kBeingFinalized);
+  set_type_state(TypeLayout::kBeingFinalized);
 }
 
-RawType* Type::ToNullability(Nullability value, Heap::Space space) const {
+TypePtr Type::ToNullability(Nullability value, Heap::Space space) const {
   if (nullability() == value) {
     return raw();
   }
@@ -18979,7 +19067,7 @@
   return type.raw();
 }
 
-RawFunction* Type::signature() const {
+FunctionPtr Type::signature() const {
   intptr_t cid = raw_ptr()->signature_->GetClassId();
   if (cid == kNullCid) {
     return Function::null();
@@ -18996,18 +19084,18 @@
   return Smi::Value(raw_ptr()->type_class_id_);
 }
 
-RawClass* Type::type_class() const {
+ClassPtr Type::type_class() const {
   return Isolate::Current()->class_table()->At(type_class_id());
 }
 
 bool Type::IsInstantiated(Genericity genericity,
                           intptr_t num_free_fun_type_params,
                           TrailPtr trail) const {
-  if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
+  if (raw_ptr()->type_state_ == TypeLayout::kFinalizedInstantiated) {
     return true;
   }
   if ((genericity == kAny) && (num_free_fun_type_params == kAllFree) &&
-      (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated)) {
+      (raw_ptr()->type_state_ == TypeLayout::kFinalizedUninstantiated)) {
     return false;
   }
   if (IsFunctionType()) {
@@ -19041,7 +19129,7 @@
                                       num_free_fun_type_params, trail);
 }
 
-RawAbstractType* Type::InstantiateFrom(
+AbstractTypePtr Type::InstantiateFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     intptr_t num_free_fun_type_params,
@@ -19302,13 +19390,10 @@
   if (cls.IsGeneric() || cls.IsClosureClass() || cls.IsTypedefClass()) {
     return false;
   }
-  const Nullability declaration_nullability = Dart::non_nullable_flag()
-                                                  ? Nullability::kNonNullable
-                                                  : Nullability::kLegacy;
-  return nullability() == declaration_nullability;
+  return nullability() == Nullability::kNonNullable;
 }
 
-RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
+AbstractTypePtr Type::Canonicalize(TrailPtr trail) const {
   ASSERT(IsFinalized());
   if (IsCanonical()) {
     ASSERT(TypeArguments::Handle(arguments()).IsOld());
@@ -19337,7 +19422,8 @@
     ASSERT(!cls.IsNullClass() || IsNullable());
     Type& type = Type::Handle(zone, cls.declaration_type());
     if (type.IsNull()) {
-      ASSERT(!cls.raw()->InVMIsolateHeap() || (isolate == Dart::vm_isolate()));
+      ASSERT(!cls.raw()->ptr()->InVMIsolateHeap() ||
+             (isolate == Dart::vm_isolate()));
       // Canonicalize the type arguments of the supertype, if any.
       TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
       type_args = type_args.Canonicalize(trail);
@@ -19481,9 +19567,7 @@
 #endif  // DEBUG
 
 void Type::EnumerateURIs(URIs* uris) const {
-  // N.B. Not all types with kNeverCid answer true to IsNeverType, but none of
-  // them have a URI.
-  if (IsDynamicType() || IsVoidType() || (type_class_id() == kNeverCid)) {
+  if (IsDynamicType() || IsVoidType() || IsNeverType()) {
     return;
   }
   Thread* thread = Thread::Current();
@@ -19541,7 +19625,9 @@
         param_name = sig_fun.ParameterNameAt(i);
         result = CombineHashes(result, param_name.Hash());
       }
+      // Required flag is not hashed, see comment above.
     }
+    // TODO(regis): Missing hash of type parameters.
   }
   result = FinalizeHash(result, kHashBits);
   SetHash(result);
@@ -19558,24 +19644,24 @@
   StorePointer(&raw_ptr()->arguments_, value.raw());
 }
 
-RawType* Type::New(Heap::Space space) {
-  RawObject* raw =
-      Object::Allocate(Type::kClassId, Type::InstanceSize(), space);
-  return reinterpret_cast<RawType*>(raw);
+TypePtr Type::New(Heap::Space space) {
+  ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space);
+  return static_cast<TypePtr>(raw);
 }
 
-RawType* Type::New(const Class& clazz,
-                   const TypeArguments& arguments,
-                   TokenPosition token_pos,
-                   Nullability nullability,
-                   Heap::Space space) {
+TypePtr Type::New(const Class& clazz,
+                  const TypeArguments& arguments,
+                  TokenPosition token_pos,
+                  Nullability nullability,
+                  Heap::Space space) {
   Zone* Z = Thread::Current()->zone();
   const Type& result = Type::Handle(Z, Type::New(space));
   result.set_type_class(clazz);
   result.set_arguments(arguments);
   result.SetHash(0);
   result.set_token_pos(token_pos);
-  result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
+  result.StoreNonPointer(&result.raw_ptr()->type_state_,
+                         TypeLayout::kAllocated);
   result.set_nullability(nullability);
 
   result.SetTypeTestingStub(
@@ -19589,8 +19675,8 @@
 }
 
 void Type::set_type_state(int8_t state) const {
-  ASSERT((state >= RawType::kAllocated) &&
-         (state <= RawType::kFinalizedUninstantiated));
+  ASSERT((state >= TypeLayout::kAllocated) &&
+         (state <= TypeLayout::kFinalizedUninstantiated));
   StoreNonPointer(&raw_ptr()->type_state_, state);
 }
 
@@ -19665,7 +19751,7 @@
   return !ref_type.IsNull() && ref_type.IsEquivalent(other, kind, trail);
 }
 
-RawTypeRef* TypeRef::InstantiateFrom(
+AbstractTypePtr TypeRef::InstantiateFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     intptr_t num_free_fun_type_params,
@@ -19708,7 +19794,7 @@
 // Consider the type Derived, where class Derived extends Base<Derived>.
 // The first type argument of its flattened type argument vector is Derived,
 // represented by a TypeRef pointing to itself.
-RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const {
+AbstractTypePtr TypeRef::Canonicalize(TrailPtr trail) const {
   if (TestAndAddToTrail(&trail)) {
     return raw();
   }
@@ -19756,13 +19842,13 @@
   return FinalizeHash(result, kHashBits);
 }
 
-RawTypeRef* TypeRef::New() {
-  RawObject* raw =
+TypeRefPtr TypeRef::New() {
+  ObjectPtr raw =
       Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawTypeRef*>(raw);
+  return static_cast<TypeRefPtr>(raw);
 }
 
-RawTypeRef* TypeRef::New(const AbstractType& type) {
+TypeRefPtr TypeRef::New(const AbstractType& type) {
   Zone* Z = Thread::Current()->zone();
   const TypeRef& result = TypeRef::Handle(Z, TypeRef::New());
   result.set_type(type);
@@ -19790,11 +19876,11 @@
 
 void TypeParameter::SetIsFinalized() const {
   ASSERT(!IsFinalized());
-  set_flags(RawTypeParameter::FinalizedBit::update(true, raw_ptr()->flags_));
+  set_flags(TypeParameterLayout::FinalizedBit::update(true, raw_ptr()->flags_));
 }
 
 void TypeParameter::SetGenericCovariantImpl(bool value) const {
-  set_flags(RawTypeParameter::GenericCovariantImplBit::update(
+  set_flags(TypeParameterLayout::GenericCovariantImplBit::update(
       value, raw_ptr()->flags_));
 }
 
@@ -19802,12 +19888,12 @@
   StoreNonPointer(&raw_ptr()->nullability_, static_cast<int8_t>(value));
 }
 
-RawTypeParameter* TypeParameter::ToNullability(Nullability value,
-                                               Heap::Space space) const {
+TypeParameterPtr TypeParameter::ToNullability(Nullability value,
+                                              Heap::Space space) const {
   if (nullability() == value) {
     return raw();
   }
-  // Clone type and set new nullability.
+  // Clone type parameter and set new nullability.
   TypeParameter& type_parameter = TypeParameter::Handle();
   type_parameter ^= Object::Clone(*this, space);
   type_parameter.set_nullability(value);
@@ -19920,7 +20006,7 @@
   return raw_ptr()->parameterized_class_id_;
 }
 
-RawClass* TypeParameter::parameterized_class() const {
+ClassPtr TypeParameter::parameterized_class() const {
   classid_t cid = parameterized_class_id();
   if (cid == kFunctionCid) {
     return Class::null();
@@ -19947,7 +20033,7 @@
   StorePointer(&raw_ptr()->bound_, value.raw());
 }
 
-RawAbstractType* TypeParameter::GetFromTypeArguments(
+AbstractTypePtr TypeParameter::GetFromTypeArguments(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments) const {
   ASSERT(IsFinalized());
@@ -19957,7 +20043,7 @@
   return type_args.TypeAtNullSafe(index());
 }
 
-RawAbstractType* TypeParameter::InstantiateFrom(
+AbstractTypePtr TypeParameter::InstantiateFrom(
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     intptr_t num_free_fun_type_params,
@@ -20047,20 +20133,20 @@
   return result;
 }
 
-RawTypeParameter* TypeParameter::New() {
-  RawObject* raw = Object::Allocate(TypeParameter::kClassId,
-                                    TypeParameter::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawTypeParameter*>(raw);
+TypeParameterPtr TypeParameter::New() {
+  ObjectPtr raw = Object::Allocate(TypeParameter::kClassId,
+                                   TypeParameter::InstanceSize(), Heap::kOld);
+  return static_cast<TypeParameterPtr>(raw);
 }
 
-RawTypeParameter* TypeParameter::New(const Class& parameterized_class,
-                                     const Function& parameterized_function,
-                                     intptr_t index,
-                                     const String& name,
-                                     const AbstractType& bound,
-                                     bool is_generic_covariant_impl,
-                                     Nullability nullability,
-                                     TokenPosition token_pos) {
+TypeParameterPtr TypeParameter::New(const Class& parameterized_class,
+                                    const Function& parameterized_function,
+                                    intptr_t index,
+                                    const String& name,
+                                    const AbstractType& bound,
+                                    bool is_generic_covariant_impl,
+                                    Nullability nullability,
+                                    TokenPosition token_pos) {
   ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull());
   Zone* Z = Thread::Current()->zone();
   const TypeParameter& result = TypeParameter::Handle(Z, TypeParameter::New());
@@ -20115,12 +20201,12 @@
   return printer.buffer();
 }
 
-RawInstance* Number::CheckAndCanonicalize(Thread* thread,
-                                          const char** error_str) const {
+InstancePtr Number::CheckAndCanonicalize(Thread* thread,
+                                         const char** error_str) const {
   intptr_t cid = GetClassId();
   switch (cid) {
     case kSmiCid:
-      return reinterpret_cast<RawSmi*>(raw_value());
+      return static_cast<SmiPtr>(raw_value());
     case kMintCid:
       return Mint::NewCanonical(Mint::Cast(*this).value());
     case kDoubleCid:
@@ -20168,7 +20254,7 @@
   return "NULL Integer";
 }
 
-RawInteger* Integer::New(const String& str, Heap::Space space) {
+IntegerPtr Integer::New(const String& str, Heap::Space space) {
   // We are not supposed to have integers represented as two byte strings.
   ASSERT(str.IsOneByteString());
   if (str.IsNull() || (str.Length() == 0)) {
@@ -20183,7 +20269,7 @@
   return Integer::New(value, space);
 }
 
-RawInteger* Integer::NewCanonical(const String& str) {
+IntegerPtr Integer::NewCanonical(const String& str) {
   // We are not supposed to have integers represented as two byte strings.
   ASSERT(str.IsOneByteString());
   int64_t value = 0;
@@ -20195,14 +20281,14 @@
   return NewCanonical(value);
 }
 
-RawInteger* Integer::NewCanonical(int64_t value) {
+IntegerPtr Integer::NewCanonical(int64_t value) {
   if (Smi::IsValid(value)) {
     return Smi::New(static_cast<intptr_t>(value));
   }
   return Mint::NewCanonical(value);
 }
 
-RawInteger* Integer::New(int64_t value, Heap::Space space) {
+IntegerPtr Integer::New(int64_t value, Heap::Space space) {
   const bool is_smi = Smi::IsValid(value);
   if (is_smi) {
     return Smi::New(static_cast<intptr_t>(value));
@@ -20210,7 +20296,7 @@
   return Mint::New(value, space);
 }
 
-RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) {
+IntegerPtr Integer::NewFromUint64(uint64_t value, Heap::Space space) {
   return Integer::New(static_cast<int64_t>(value), space);
 }
 
@@ -20266,7 +20352,7 @@
   return 0;
 }
 
-RawInteger* Integer::AsValidInteger() const {
+IntegerPtr Integer::AsValidInteger() const {
   if (IsSmi()) return raw();
   if (IsMint()) {
     Mint& mint = Mint::Handle();
@@ -20290,9 +20376,9 @@
   }
 }
 
-RawInteger* Integer::ArithmeticOp(Token::Kind operation,
-                                  const Integer& other,
-                                  Heap::Space space) const {
+IntegerPtr Integer::ArithmeticOp(Token::Kind operation,
+                                 const Integer& other,
+                                 Heap::Space space) const {
   // In 32-bit mode, the result of any operation between two Smis will fit in a
   // 32-bit signed result, except the product of two Smis, which will be 64-bit.
   // In 64-bit mode, the result of any operation between two Smis will fit in a
@@ -20372,9 +20458,9 @@
   }
 }
 
-RawInteger* Integer::BitOp(Token::Kind kind,
-                           const Integer& other,
-                           Heap::Space space) const {
+IntegerPtr Integer::BitOp(Token::Kind kind,
+                          const Integer& other,
+                          Heap::Space space) const {
   if (IsSmi() && other.IsSmi()) {
     intptr_t op1_value = Smi::Value(Smi::RawCast(raw()));
     intptr_t op2_value = Smi::Value(Smi::RawCast(other.raw()));
@@ -20411,9 +20497,9 @@
   }
 }
 
-RawInteger* Integer::ShiftOp(Token::Kind kind,
-                             const Integer& other,
-                             Heap::Space space) const {
+IntegerPtr Integer::ShiftOp(Token::Kind kind,
+                            const Integer& other,
+                            Heap::Space space) const {
   int64_t a = AsInt64Value();
   int64_t b = other.AsInt64Value();
   ASSERT(b >= 0);
@@ -20473,7 +20559,7 @@
   return OS::SCreate(Thread::Current()->zone(), "%" Pd "", Value());
 }
 
-RawClass* Smi::Class() {
+ClassPtr Smi::Class() {
   return Isolate::Current()->object_store()->smi_class();
 }
 
@@ -20481,13 +20567,13 @@
   StoreNonPointer(&raw_ptr()->value_, value);
 }
 
-RawMint* Mint::New(int64_t val, Heap::Space space) {
+MintPtr Mint::New(int64_t val, Heap::Space space) {
   // Do not allocate a Mint if Smi would do.
   ASSERT(!Smi::IsValid(val));
   ASSERT(Isolate::Current()->object_store()->mint_class() != Class::null());
   Mint& result = Mint::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -20496,7 +20582,7 @@
   return result.raw();
 }
 
-RawMint* Mint::NewCanonical(int64_t value) {
+MintPtr Mint::NewCanonical(int64_t value) {
   // Do not allocate a Mint if Smi would do.
   ASSERT(!Smi::IsValid(value));
   Thread* thread = Thread::Current();
@@ -20607,11 +20693,11 @@
   return Hash64To32(bit_cast<uint64_t>(value()));
 }
 
-RawDouble* Double::New(double d, Heap::Space space) {
+DoublePtr Double::New(double d, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->double_class() != Class::null());
   Double& result = Double::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Double::kClassId, Double::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -20620,7 +20706,7 @@
   return result.raw();
 }
 
-RawDouble* Double::New(const String& str, Heap::Space space) {
+DoublePtr Double::New(const String& str, Heap::Space space) {
   double double_value;
   if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) {
     return Double::Handle().raw();
@@ -20628,7 +20714,7 @@
   return New(double_value, space);
 }
 
-RawDouble* Double::NewCanonical(double value) {
+DoublePtr Double::NewCanonical(double value) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -20658,7 +20744,7 @@
   }
 }
 
-RawDouble* Double::NewCanonical(const String& str) {
+DoublePtr Double::NewCanonical(const String& str) {
   double double_value;
   if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) {
     return Double::Handle().raw();
@@ -20666,7 +20752,7 @@
   return NewCanonical(double_value);
 }
 
-RawString* Number::ToString(Heap::Space space) const {
+StringPtr Number::ToString(Heap::Space space) const {
   // Refactoring can avoid Zone::Alloc and strlen, but gains are insignificant.
   const char* cstr = ToCString();
   intptr_t len = strlen(cstr);
@@ -20766,28 +20852,26 @@
   return hasher.Finalize(String::kHashBits);
 }
 
-intptr_t String::Hash(RawString* raw) {
+intptr_t String::Hash(StringPtr raw) {
   StringHasher hasher;
   uword length = Smi::Value(raw->ptr()->length_);
   if (raw->IsOneByteString() || raw->IsExternalOneByteString()) {
     const uint8_t* data;
     if (raw->IsOneByteString()) {
-      data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data();
+      data = static_cast<OneByteStringPtr>(raw)->ptr()->data();
     } else {
       ASSERT(raw->IsExternalOneByteString());
-      RawExternalOneByteString* str =
-          reinterpret_cast<RawExternalOneByteString*>(raw);
+      ExternalOneByteStringPtr str = static_cast<ExternalOneByteStringPtr>(raw);
       data = str->ptr()->external_data_;
     }
     return String::Hash(data, length);
   } else {
     const uint16_t* data;
     if (raw->IsTwoByteString()) {
-      data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data();
+      data = static_cast<TwoByteStringPtr>(raw)->ptr()->data();
     } else {
       ASSERT(raw->IsExternalTwoByteString());
-      RawExternalTwoByteString* str =
-          reinterpret_cast<RawExternalTwoByteString*>(raw);
+      ExternalTwoByteStringPtr str = static_cast<ExternalTwoByteStringPtr>(raw);
       data = str->ptr()->external_data_;
     }
     return String::Hash(data, length);
@@ -20817,7 +20901,7 @@
 
 uint16_t String::CharAt(intptr_t index) const {
   intptr_t class_id = raw()->GetClassId();
-  ASSERT(RawObject::IsStringClassId(class_id));
+  ASSERT(IsStringClassId(class_id));
   if (class_id == kOneByteStringCid) {
     return OneByteString::CharAt(*this, index);
   }
@@ -21008,8 +21092,8 @@
   return true;
 }
 
-RawInstance* String::CheckAndCanonicalize(Thread* thread,
-                                          const char** error_str) const {
+InstancePtr String::CheckAndCanonicalize(Thread* thread,
+                                         const char** error_str) const {
   if (IsCanonical()) {
     return this->raw();
   }
@@ -21024,16 +21108,16 @@
 }
 #endif  // DEBUG
 
-RawString* String::New(const char* cstr, Heap::Space space) {
+StringPtr String::New(const char* cstr, Heap::Space space) {
   ASSERT(cstr != NULL);
   intptr_t array_len = strlen(cstr);
   const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr);
   return String::FromUTF8(utf8_array, array_len, space);
 }
 
-RawString* String::FromUTF8(const uint8_t* utf8_array,
-                            intptr_t array_len,
-                            Heap::Space space) {
+StringPtr String::FromUTF8(const uint8_t* utf8_array,
+                           intptr_t array_len,
+                           Heap::Space space) {
   Utf8::Type type;
   intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type);
   if (type == Utf8::kLatin1) {
@@ -21059,15 +21143,15 @@
   return strobj.raw();
 }
 
-RawString* String::FromLatin1(const uint8_t* latin1_array,
-                              intptr_t array_len,
-                              Heap::Space space) {
+StringPtr String::FromLatin1(const uint8_t* latin1_array,
+                             intptr_t array_len,
+                             Heap::Space space) {
   return OneByteString::New(latin1_array, array_len, space);
 }
 
-RawString* String::FromUTF16(const uint16_t* utf16_array,
-                             intptr_t array_len,
-                             Heap::Space space) {
+StringPtr String::FromUTF16(const uint16_t* utf16_array,
+                            intptr_t array_len,
+                            Heap::Space space) {
   bool is_one_byte_string = true;
   for (intptr_t i = 0; i < array_len; ++i) {
     if (!Utf::IsLatin1(utf16_array[i])) {
@@ -21081,9 +21165,9 @@
   return TwoByteString::New(utf16_array, array_len, space);
 }
 
-RawString* String::FromUTF32(const int32_t* utf32_array,
-                             intptr_t array_len,
-                             Heap::Space space) {
+StringPtr String::FromUTF32(const int32_t* utf32_array,
+                            intptr_t array_len,
+                            Heap::Space space) {
   bool is_one_byte_string = true;
   intptr_t utf16_len = array_len;
   for (intptr_t i = 0; i < array_len; ++i) {
@@ -21100,7 +21184,7 @@
   return TwoByteString::New(utf16_len, utf32_array, array_len, space);
 }
 
-RawString* String::New(const String& str, Heap::Space space) {
+StringPtr String::New(const String& str, Heap::Space space) {
   // Currently this just creates a copy of the string in the correct space.
   // Once we have external string support, this will also create a heap copy of
   // the string if necessary. Some optimizations are possible, such as not
@@ -21118,22 +21202,22 @@
   return result.raw();
 }
 
-RawString* String::NewExternal(const uint8_t* characters,
-                               intptr_t len,
-                               void* peer,
-                               intptr_t external_allocation_size,
-                               Dart_WeakPersistentHandleFinalizer callback,
-                               Heap::Space space) {
+StringPtr String::NewExternal(const uint8_t* characters,
+                              intptr_t len,
+                              void* peer,
+                              intptr_t external_allocation_size,
+                              Dart_WeakPersistentHandleFinalizer callback,
+                              Heap::Space space) {
   return ExternalOneByteString::New(characters, len, peer,
                                     external_allocation_size, callback, space);
 }
 
-RawString* String::NewExternal(const uint16_t* characters,
-                               intptr_t len,
-                               void* peer,
-                               intptr_t external_allocation_size,
-                               Dart_WeakPersistentHandleFinalizer callback,
-                               Heap::Space space) {
+StringPtr String::NewExternal(const uint16_t* characters,
+                              intptr_t len,
+                              void* peer,
+                              intptr_t external_allocation_size,
+                              Dart_WeakPersistentHandleFinalizer callback,
+                              Heap::Space space) {
   return ExternalTwoByteString::New(characters, len, peer,
                                     external_allocation_size, callback, space);
 }
@@ -21219,7 +21303,7 @@
   }
 }
 
-RawString* String::EscapeSpecialCharacters(const String& str) {
+StringPtr String::EscapeSpecialCharacters(const String& str) {
   if (str.IsOneByteString()) {
     return OneByteString::EscapeSpecialCharacters(str);
   }
@@ -21316,7 +21400,7 @@
   return cstr;
 }
 
-RawString* String::DecodeIRI(const String& str) {
+StringPtr String::DecodeIRI(const String& str) {
   CodePointIterator cpi(str);
   intptr_t num_escapes = 0;
   intptr_t len = str.Length();
@@ -21372,27 +21456,27 @@
   return FromUTF8(utf8, utf8_len);
 }
 
-RawString* String::NewFormatted(const char* format, ...) {
+StringPtr String::NewFormatted(const char* format, ...) {
   va_list args;
   va_start(args, format);
-  RawString* result = NewFormattedV(format, args);
+  StringPtr result = NewFormattedV(format, args);
   NoSafepointScope no_safepoint;
   va_end(args);
   return result;
 }
 
-RawString* String::NewFormatted(Heap::Space space, const char* format, ...) {
+StringPtr String::NewFormatted(Heap::Space space, const char* format, ...) {
   va_list args;
   va_start(args, format);
-  RawString* result = NewFormattedV(format, args, space);
+  StringPtr result = NewFormattedV(format, args, space);
   NoSafepointScope no_safepoint;
   va_end(args);
   return result;
 }
 
-RawString* String::NewFormattedV(const char* format,
-                                 va_list args,
-                                 Heap::Space space) {
+StringPtr String::NewFormattedV(const char* format,
+                                va_list args,
+                                Heap::Space space) {
   va_list args_copy;
   va_copy(args_copy, args);
   intptr_t len = Utils::VSNPrint(NULL, 0, format, args_copy);
@@ -21405,9 +21489,9 @@
   return String::New(buffer, space);
 }
 
-RawString* String::Concat(const String& str1,
-                          const String& str2,
-                          Heap::Space space) {
+StringPtr String::Concat(const String& str1,
+                         const String& str2,
+                         Heap::Space space) {
   ASSERT(!str1.IsNull() && !str2.IsNull());
   intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize());
   if (char_size == kTwoByteChar) {
@@ -21416,14 +21500,14 @@
   return OneByteString::Concat(str1, str2, space);
 }
 
-RawString* String::ConcatAll(const Array& strings, Heap::Space space) {
+StringPtr String::ConcatAll(const Array& strings, Heap::Space space) {
   return ConcatAllRange(strings, 0, strings.Length(), space);
 }
 
-RawString* String::ConcatAllRange(const Array& strings,
-                                  intptr_t start,
-                                  intptr_t end,
-                                  Heap::Space space) {
+StringPtr String::ConcatAllRange(const Array& strings,
+                                 intptr_t start,
+                                 intptr_t end,
+                                 Heap::Space space) {
   ASSERT(!strings.IsNull());
   ASSERT(start >= 0);
   ASSERT(end <= strings.Length());
@@ -21448,9 +21532,9 @@
   return TwoByteString::ConcatAll(strings, start, end, result_len, space);
 }
 
-RawString* String::SubString(const String& str,
-                             intptr_t begin_index,
-                             Heap::Space space) {
+StringPtr String::SubString(const String& str,
+                            intptr_t begin_index,
+                            Heap::Space space) {
   ASSERT(!str.IsNull());
   if (begin_index >= str.Length()) {
     return String::null();
@@ -21459,11 +21543,11 @@
                            space);
 }
 
-RawString* String::SubString(Thread* thread,
-                             const String& str,
-                             intptr_t begin_index,
-                             intptr_t length,
-                             Heap::Space space) {
+StringPtr String::SubString(Thread* thread,
+                            const String& str,
+                            intptr_t begin_index,
+                            intptr_t length,
+                            Heap::Space space) {
   ASSERT(!str.IsNull());
   ASSERT(begin_index >= 0);
   ASSERT(length >= 0);
@@ -21526,9 +21610,9 @@
                                           callback, external_size);
 }
 
-RawString* String::Transform(int32_t (*mapping)(int32_t ch),
-                             const String& str,
-                             Heap::Space space) {
+StringPtr String::Transform(int32_t (*mapping)(int32_t ch),
+                            const String& str,
+                            Heap::Space space) {
   ASSERT(!str.IsNull());
   bool has_mapping = false;
   int32_t dst_max = 0;
@@ -21551,12 +21635,12 @@
   return TwoByteString::Transform(mapping, str, space);
 }
 
-RawString* String::ToUpperCase(const String& str, Heap::Space space) {
+StringPtr String::ToUpperCase(const String& str, Heap::Space space) {
   // TODO(cshapiro): create a fast-path for OneByteString instances.
   return Transform(CaseMapping::ToUpper, str, space);
 }
 
-RawString* String::ToLowerCase(const String& str, Heap::Space space) {
+StringPtr String::ToLowerCase(const String& str, Heap::Space space) {
   // TODO(cshapiro): create a fast-path for OneByteString instances.
   return Transform(CaseMapping::ToLower, str, space);
 }
@@ -21703,7 +21787,7 @@
   return false;
 }
 
-RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) {
+OneByteStringPtr OneByteString::EscapeSpecialCharacters(const String& str) {
   intptr_t len = str.Length();
   if (len > 0) {
     intptr_t num_escapes = 0;
@@ -21735,7 +21819,7 @@
   return OneByteString::raw(Symbols::Empty());
 }
 
-RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters(
+OneByteStringPtr ExternalOneByteString::EscapeSpecialCharacters(
     const String& str) {
   intptr_t len = str.Length();
   if (len > 0) {
@@ -21768,7 +21852,7 @@
   return OneByteString::raw(Symbols::Empty());
 }
 
-RawOneByteString* OneByteString::New(intptr_t len, Heap::Space space) {
+OneByteStringPtr OneByteString::New(intptr_t len, Heap::Space space) {
   ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
          ((Isolate::Current()->object_store() != NULL) &&
           (Isolate::Current()->object_store()->one_byte_string_class() !=
@@ -21778,21 +21862,21 @@
     FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len);
   }
   {
-    RawObject* raw = Object::Allocate(OneByteString::kClassId,
-                                      OneByteString::InstanceSize(len), space);
+    ObjectPtr raw = Object::Allocate(OneByteString::kClassId,
+                                     OneByteString::InstanceSize(len), space);
     NoSafepointScope no_safepoint;
-    RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw);
-    result->StoreSmi(&(result->ptr()->length_), Smi::New(len));
+    OneByteStringPtr result = static_cast<OneByteStringPtr>(raw);
+    result->ptr()->StoreSmi(&(result->ptr()->length_), Smi::New(len));
 #if !defined(HASH_IN_OBJECT_HEADER)
-    result->StoreSmi(&(result->ptr()->hash_), Smi::New(0));
+    result->ptr()->StoreSmi(&(result->ptr()->hash_), Smi::New(0));
 #endif
     return result;
   }
 }
 
-RawOneByteString* OneByteString::New(const uint8_t* characters,
-                                     intptr_t len,
-                                     Heap::Space space) {
+OneByteStringPtr OneByteString::New(const uint8_t* characters,
+                                    intptr_t len,
+                                    Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(len, space));
   if (len > 0) {
     NoSafepointScope no_safepoint;
@@ -21801,9 +21885,9 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::New(const uint16_t* characters,
-                                     intptr_t len,
-                                     Heap::Space space) {
+OneByteStringPtr OneByteString::New(const uint16_t* characters,
+                                    intptr_t len,
+                                    Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(len, space));
   NoSafepointScope no_safepoint;
   for (intptr_t i = 0; i < len; ++i) {
@@ -21813,9 +21897,9 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::New(const int32_t* characters,
-                                     intptr_t len,
-                                     Heap::Space space) {
+OneByteStringPtr OneByteString::New(const int32_t* characters,
+                                    intptr_t len,
+                                    Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(len, space));
   NoSafepointScope no_safepoint;
   for (intptr_t i = 0; i < len; ++i) {
@@ -21825,17 +21909,17 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::New(const String& str, Heap::Space space) {
+OneByteStringPtr OneByteString::New(const String& str, Heap::Space space) {
   intptr_t len = str.Length();
   const String& result = String::Handle(OneByteString::New(len, space));
   String::Copy(result, 0, str, 0, len);
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::New(const String& other_one_byte_string,
-                                     intptr_t other_start_index,
-                                     intptr_t other_len,
-                                     Heap::Space space) {
+OneByteStringPtr OneByteString::New(const String& other_one_byte_string,
+                                    intptr_t other_start_index,
+                                    intptr_t other_len,
+                                    Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(other_len, space));
   ASSERT(other_one_byte_string.IsOneByteString());
   if (other_len > 0) {
@@ -21847,10 +21931,10 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::New(const TypedData& other_typed_data,
-                                     intptr_t other_start_index,
-                                     intptr_t other_len,
-                                     Heap::Space space) {
+OneByteStringPtr OneByteString::New(const TypedData& other_typed_data,
+                                    intptr_t other_start_index,
+                                    intptr_t other_len,
+                                    Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(other_len, space));
   ASSERT(other_typed_data.ElementSizeInBytes() == 1);
   if (other_len > 0) {
@@ -21861,10 +21945,10 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data,
-                                     intptr_t other_start_index,
-                                     intptr_t other_len,
-                                     Heap::Space space) {
+OneByteStringPtr OneByteString::New(const ExternalTypedData& other_typed_data,
+                                    intptr_t other_start_index,
+                                    intptr_t other_len,
+                                    Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(other_len, space));
   ASSERT(other_typed_data.ElementSizeInBytes() == 1);
   if (other_len > 0) {
@@ -21875,9 +21959,9 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::Concat(const String& str1,
-                                        const String& str2,
-                                        Heap::Space space) {
+OneByteStringPtr OneByteString::Concat(const String& str1,
+                                       const String& str2,
+                                       Heap::Space space) {
   intptr_t len1 = str1.Length();
   intptr_t len2 = str2.Length();
   intptr_t len = len1 + len2;
@@ -21887,11 +21971,11 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::ConcatAll(const Array& strings,
-                                           intptr_t start,
-                                           intptr_t end,
-                                           intptr_t len,
-                                           Heap::Space space) {
+OneByteStringPtr OneByteString::ConcatAll(const Array& strings,
+                                          intptr_t start,
+                                          intptr_t end,
+                                          intptr_t len,
+                                          Heap::Space space) {
   ASSERT(!strings.IsNull());
   ASSERT(start >= 0);
   ASSERT(end <= strings.Length());
@@ -21908,9 +21992,9 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
-                                           const String& str,
-                                           Heap::Space space) {
+OneByteStringPtr OneByteString::Transform(int32_t (*mapping)(int32_t ch),
+                                          const String& str,
+                                          Heap::Space space) {
   ASSERT(!str.IsNull());
   intptr_t len = str.Length();
   const String& result = String::Handle(OneByteString::New(len, space));
@@ -21923,10 +22007,10 @@
   return OneByteString::raw(result);
 }
 
-RawOneByteString* OneByteString::SubStringUnchecked(const String& str,
-                                                    intptr_t begin_index,
-                                                    intptr_t length,
-                                                    Heap::Space space) {
+OneByteStringPtr OneByteString::SubStringUnchecked(const String& str,
+                                                   intptr_t begin_index,
+                                                   intptr_t length,
+                                                   Heap::Space space) {
   ASSERT(!str.IsNull() && str.IsOneByteString());
   ASSERT(begin_index >= 0);
   ASSERT(length >= 0);
@@ -21934,7 +22018,7 @@
     return OneByteString::raw(Symbols::Empty());
   }
   ASSERT(begin_index < str.Length());
-  RawOneByteString* result = OneByteString::New(length, space);
+  OneByteStringPtr result = OneByteString::New(length, space);
   NoSafepointScope no_safepoint;
   if (length > 0) {
     uint8_t* dest = &result->ptr()->data()[0];
@@ -21944,7 +22028,7 @@
   return result;
 }
 
-RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) {
+TwoByteStringPtr TwoByteString::EscapeSpecialCharacters(const String& str) {
   intptr_t len = str.Length();
   if (len > 0) {
     intptr_t num_escapes = 0;
@@ -21976,16 +22060,17 @@
   return TwoByteString::New(0, Heap::kNew);
 }
 
-RawTwoByteString* TwoByteString::New(intptr_t len, Heap::Space space) {
-  ASSERT(Isolate::Current()->object_store()->two_byte_string_class());
+TwoByteStringPtr TwoByteString::New(intptr_t len, Heap::Space space) {
+  ASSERT(Isolate::Current()->object_store()->two_byte_string_class() !=
+         nullptr);
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len);
   }
   String& result = String::Handle();
   {
-    RawObject* raw = Object::Allocate(TwoByteString::kClassId,
-                                      TwoByteString::InstanceSize(len), space);
+    ObjectPtr raw = Object::Allocate(TwoByteString::kClassId,
+                                     TwoByteString::InstanceSize(len), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -21994,9 +22079,9 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array,
-                                     intptr_t array_len,
-                                     Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const uint16_t* utf16_array,
+                                    intptr_t array_len,
+                                    Heap::Space space) {
   ASSERT(array_len > 0);
   const String& result = String::Handle(TwoByteString::New(array_len, space));
   {
@@ -22006,10 +22091,10 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
-                                     const int32_t* utf32_array,
-                                     intptr_t array_len,
-                                     Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(intptr_t utf16_len,
+                                    const int32_t* utf32_array,
+                                    intptr_t array_len,
+                                    Heap::Space space) {
   ASSERT((array_len > 0) && (utf16_len >= array_len));
   const String& result = String::Handle(TwoByteString::New(utf16_len, space));
   {
@@ -22030,17 +22115,17 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::New(const String& str, Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const String& str, Heap::Space space) {
   intptr_t len = str.Length();
   const String& result = String::Handle(TwoByteString::New(len, space));
   String::Copy(result, 0, str, 0, len);
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data,
-                                     intptr_t other_start_index,
-                                     intptr_t other_len,
-                                     Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const TypedData& other_typed_data,
+                                    intptr_t other_start_index,
+                                    intptr_t other_len,
+                                    Heap::Space space) {
   const String& result = String::Handle(TwoByteString::New(other_len, space));
   if (other_len > 0) {
     NoSafepointScope no_safepoint;
@@ -22051,10 +22136,10 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data,
-                                     intptr_t other_start_index,
-                                     intptr_t other_len,
-                                     Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const ExternalTypedData& other_typed_data,
+                                    intptr_t other_start_index,
+                                    intptr_t other_len,
+                                    Heap::Space space) {
   const String& result = String::Handle(TwoByteString::New(other_len, space));
   if (other_len > 0) {
     NoSafepointScope no_safepoint;
@@ -22065,9 +22150,9 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::Concat(const String& str1,
-                                        const String& str2,
-                                        Heap::Space space) {
+TwoByteStringPtr TwoByteString::Concat(const String& str1,
+                                       const String& str2,
+                                       Heap::Space space) {
   intptr_t len1 = str1.Length();
   intptr_t len2 = str2.Length();
   intptr_t len = len1 + len2;
@@ -22077,11 +22162,11 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::ConcatAll(const Array& strings,
-                                           intptr_t start,
-                                           intptr_t end,
-                                           intptr_t len,
-                                           Heap::Space space) {
+TwoByteStringPtr TwoByteString::ConcatAll(const Array& strings,
+                                          intptr_t start,
+                                          intptr_t end,
+                                          intptr_t len,
+                                          Heap::Space space) {
   ASSERT(!strings.IsNull());
   ASSERT(start >= 0);
   ASSERT(end <= strings.Length());
@@ -22098,9 +22183,9 @@
   return TwoByteString::raw(result);
 }
 
-RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
-                                           const String& str,
-                                           Heap::Space space) {
+TwoByteStringPtr TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
+                                          const String& str,
+                                          Heap::Space space) {
   ASSERT(!str.IsNull());
   intptr_t len = str.Length();
   const String& result = String::Handle(TwoByteString::New(len, space));
@@ -22123,7 +22208,7 @@
   return TwoByteString::raw(result);
 }
 
-RawExternalOneByteString* ExternalOneByteString::New(
+ExternalOneByteStringPtr ExternalOneByteString::New(
     const uint8_t* data,
     intptr_t len,
     void* peer,
@@ -22139,7 +22224,7 @@
   }
   String& result = String::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ExternalOneByteString::kClassId,
                          ExternalOneByteString::InstanceSize(), space);
     NoSafepointScope no_safepoint;
@@ -22152,7 +22237,7 @@
   return ExternalOneByteString::raw(result);
 }
 
-RawExternalTwoByteString* ExternalTwoByteString::New(
+ExternalTwoByteStringPtr ExternalTwoByteString::New(
     const uint16_t* data,
     intptr_t len,
     void* peer,
@@ -22168,7 +22253,7 @@
   }
   String& result = String::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(ExternalTwoByteString::kClassId,
                          ExternalTwoByteString::InstanceSize(), space);
     NoSafepointScope no_safepoint;
@@ -22181,13 +22266,13 @@
   return ExternalTwoByteString::raw(result);
 }
 
-RawBool* Bool::New(bool value) {
+BoolPtr Bool::New(bool value) {
   ASSERT(Isolate::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.
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22261,19 +22346,19 @@
   return hash;
 }
 
-RawArray* Array::New(intptr_t len, Heap::Space space) {
+ArrayPtr Array::New(intptr_t len, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->array_class() != Class::null());
-  RawArray* result = New(kClassId, len, space);
+  ArrayPtr result = New(kClassId, len, space);
   if (UseCardMarkingForAllocation(len)) {
     ASSERT(result->IsOldObject());
-    result->SetCardRememberedBitUnsynchronized();
+    result->ptr()->SetCardRememberedBitUnsynchronized();
   }
   return result;
 }
 
-RawArray* Array::New(intptr_t len,
-                     const AbstractType& element_type,
-                     Heap::Space space) {
+ArrayPtr Array::New(intptr_t len,
+                    const AbstractType& element_type,
+                    Heap::Space space) {
   const Array& result = Array::Handle(Array::New(len, space));
   if (!element_type.IsDynamicType()) {
     TypeArguments& type_args = TypeArguments::Handle(TypeArguments::New(1));
@@ -22284,23 +22369,23 @@
   return result.raw();
 }
 
-RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) {
+ArrayPtr Array::New(intptr_t class_id, intptr_t len, Heap::Space space) {
   if (!IsValidLength(len)) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len);
   }
   {
-    RawArray* raw = reinterpret_cast<RawArray*>(
+    ArrayPtr raw = static_cast<ArrayPtr>(
         Object::Allocate(class_id, Array::InstanceSize(len), space));
     NoSafepointScope no_safepoint;
-    raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len));
+    raw->ptr()->StoreSmi(&(raw->ptr()->length_), Smi::New(len));
     return raw;
   }
 }
 
-RawArray* Array::Slice(intptr_t start,
-                       intptr_t count,
-                       bool with_type_argument) const {
+ArrayPtr Array::Slice(intptr_t start,
+                      intptr_t count,
+                      bool with_type_argument) const {
   // TODO(vegorov) introduce an array allocation method that fills newly
   // allocated array with values from the given source array instead of
   // null-initializing all elements.
@@ -22323,7 +22408,7 @@
   do {
     old_tags = tags;
     uint32_t new_tags =
-        RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags);
+        ObjectLayout::ClassIdTag::update(kImmutableArrayCid, old_tags);
     tags = CompareAndSwapTags(old_tags, new_tags);
   } while (tags != old_tags);
 }
@@ -22338,9 +22423,9 @@
   return zone->PrintToString(format, Length());
 }
 
-RawArray* Array::Grow(const Array& source,
-                      intptr_t new_length,
-                      Heap::Space space) {
+ArrayPtr Array::Grow(const Array& source,
+                     intptr_t new_length,
+                     Heap::Space space) {
   Zone* zone = Thread::Current()->zone();
   const Array& result = Array::Handle(zone, Array::New(new_length, space));
   intptr_t len = 0;
@@ -22369,6 +22454,9 @@
 
   intptr_t old_len = array.Length();
   ASSERT(new_len <= old_len);
+  if (old_len == new_len) {
+    return;
+  }
   intptr_t old_size = Array::InstanceSize(old_len);
   intptr_t new_size = Array::InstanceSize(new_len);
 
@@ -22385,23 +22473,23 @@
 
   // Update the size in the header field and length of the array object.
   uint32_t tags = array.raw_ptr()->tags_;
-  ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags));
+  ASSERT(kArrayCid == ObjectLayout::ClassIdTag::decode(tags));
   uint32_t old_tags;
   do {
     old_tags = tags;
-    uint32_t new_tags = RawObject::SizeTag::update(new_size, old_tags);
+    uint32_t new_tags = ObjectLayout::SizeTag::update(new_size, old_tags);
     tags = CompareAndSwapTags(old_tags, new_tags);
   } while (tags != old_tags);
 
   // Between the CAS of the header above and the SetLength below, the array is
   // temporarily in an inconsistent state. The header is considered the
-  // overriding source of object size by RawObject::Size, but the ASSERTs in
-  // RawObject::SizeFromClass must handle this special case.
+  // overriding source of object size by ObjectLayout::Size, but the ASSERTs in
+  // ObjectLayout::SizeFromClass must handle this special case.
   array.SetLengthIgnoreRace(new_len);
 }
 
-RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array,
-                                 bool unique) {
+ArrayPtr Array::MakeFixedLength(const GrowableObjectArray& growable_array,
+                                bool unique) {
   ASSERT(!growable_array.IsNull());
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -22468,10 +22556,10 @@
   return true;
 }
 
-RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) {
+ImmutableArrayPtr ImmutableArray::New(intptr_t len, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->immutable_array_class() !=
          Class::null());
-  return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space));
+  return static_cast<ImmutableArrayPtr>(Array::New(kClassId, len, space));
 }
 
 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const {
@@ -22499,7 +22587,7 @@
   StorePointer(&(raw_ptr()->data_), new_contents.raw());
 }
 
-RawObject* GrowableObjectArray::RemoveLast() const {
+ObjectPtr GrowableObjectArray::RemoveLast() const {
   ASSERT(!IsNull());
   ASSERT(Length() > 0);
   intptr_t index = Length() - 1;
@@ -22510,21 +22598,21 @@
   return obj.raw();
 }
 
-RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity,
-                                                 Heap::Space space) {
-  RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw()
-                                       : Array::New(capacity, space);
+GrowableObjectArrayPtr GrowableObjectArray::New(intptr_t capacity,
+                                                Heap::Space space) {
+  ArrayPtr raw_data = (capacity == 0) ? Object::empty_array().raw()
+                                      : Array::New(capacity, space);
   const Array& data = Array::Handle(raw_data);
   return New(data, space);
 }
 
-RawGrowableObjectArray* GrowableObjectArray::New(const Array& array,
-                                                 Heap::Space space) {
+GrowableObjectArrayPtr GrowableObjectArray::New(const Array& array,
+                                                Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->growable_object_array_class() !=
          Class::null());
   GrowableObjectArray& result = GrowableObjectArray::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(GrowableObjectArray::kClassId,
                          GrowableObjectArray::InstanceSize(), space);
     NoSafepointScope no_safepoint;
@@ -22578,7 +22666,7 @@
   }
 };
 
-RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) {
+LinkedHashMapPtr LinkedHashMap::NewDefault(Heap::Space space) {
   const Array& data = Array::Handle(Array::New(kInitialIndexSize, space));
   const TypedData& index = TypedData::Handle(
       TypedData::New(kTypedDataUint32ArrayCid, kInitialIndexSize, space));
@@ -22589,12 +22677,12 @@
   return LinkedHashMap::New(data, index, kInitialHashMask, 0, 0, space);
 }
 
-RawLinkedHashMap* LinkedHashMap::New(const Array& data,
-                                     const TypedData& index,
-                                     intptr_t hash_mask,
-                                     intptr_t used_data,
-                                     intptr_t deleted_keys,
-                                     Heap::Space space) {
+LinkedHashMapPtr LinkedHashMap::New(const Array& data,
+                                    const TypedData& index,
+                                    intptr_t hash_mask,
+                                    intptr_t used_data,
+                                    intptr_t deleted_keys,
+                                    Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() !=
          Class::null());
   LinkedHashMap& result =
@@ -22607,13 +22695,13 @@
   return result.raw();
 }
 
-RawLinkedHashMap* LinkedHashMap::NewUninitialized(Heap::Space space) {
+LinkedHashMapPtr LinkedHashMap::NewUninitialized(Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() !=
          Class::null());
   LinkedHashMap& result = LinkedHashMap::Handle();
   {
-    RawObject* raw = Object::Allocate(LinkedHashMap::kClassId,
-                                      LinkedHashMap::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(LinkedHashMap::kClassId,
+                                     LinkedHashMap::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -22630,16 +22718,16 @@
   UNREACHABLE();
 }
 
-RawFloat32x4* Float32x4::New(float v0,
-                             float v1,
-                             float v2,
-                             float v3,
-                             Heap::Space space) {
+Float32x4Ptr Float32x4::New(float v0,
+                            float v1,
+                            float v2,
+                            float v3,
+                            Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->float32x4_class() !=
          Class::null());
   Float32x4& result = Float32x4::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22651,12 +22739,12 @@
   return result.raw();
 }
 
-RawFloat32x4* Float32x4::New(simd128_value_t value, Heap::Space space) {
+Float32x4Ptr Float32x4::New(simd128_value_t value, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->float32x4_class() !=
          Class::null());
   Float32x4& result = Float32x4::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22716,15 +22804,15 @@
                      _w);
 }
 
-RawInt32x4* Int32x4::New(int32_t v0,
-                         int32_t v1,
-                         int32_t v2,
-                         int32_t v3,
-                         Heap::Space space) {
+Int32x4Ptr Int32x4::New(int32_t v0,
+                        int32_t v1,
+                        int32_t v2,
+                        int32_t v3,
+                        Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null());
   Int32x4& result = Int32x4::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22736,11 +22824,11 @@
   return result.raw();
 }
 
-RawInt32x4* Int32x4::New(simd128_value_t value, Heap::Space space) {
+Int32x4Ptr Int32x4::New(simd128_value_t value, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null());
   Int32x4& result = Int32x4::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22800,12 +22888,12 @@
                      _y, _z, _w);
 }
 
-RawFloat64x2* Float64x2::New(double value0, double value1, Heap::Space space) {
+Float64x2Ptr Float64x2::New(double value0, double value1, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->float64x2_class() !=
          Class::null());
   Float64x2& result = Float64x2::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22815,12 +22903,12 @@
   return result.raw();
 }
 
-RawFloat64x2* Float64x2::New(simd128_value_t value, Heap::Space space) {
+Float64x2Ptr Float64x2::New(simd128_value_t value, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->float64x2_class() !=
          Class::null());
   Float64x2& result = Float64x2::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22914,16 +23002,16 @@
   return FinalizeHash(hash, kHashBits);
 }
 
-RawTypedData* TypedData::New(intptr_t class_id,
-                             intptr_t len,
-                             Heap::Space space) {
+TypedDataPtr TypedData::New(intptr_t class_id,
+                            intptr_t len,
+                            Heap::Space space) {
   if (len < 0 || len > TypedData::MaxElements(class_id)) {
     FATAL1("Fatal error in TypedData::New: invalid len %" Pd "\n", len);
   }
   TypedData& result = TypedData::Handle();
   {
     const intptr_t length_in_bytes = len * ElementSizeInBytes(class_id);
-    RawObject* raw = Object::Allocate(
+    ObjectPtr raw = Object::Allocate(
         class_id, TypedData::InstanceSize(length_in_bytes), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22951,7 +23039,7 @@
   return dart::AddFinalizer(*this, peer, callback, external_size);
 }
 
-RawExternalTypedData* ExternalTypedData::New(
+ExternalTypedDataPtr ExternalTypedData::New(
     intptr_t class_id,
     uint8_t* data,
     intptr_t len,
@@ -22969,7 +23057,7 @@
 
   ExternalTypedData& result = ExternalTypedData::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -22979,8 +23067,8 @@
   return result.raw();
 }
 
-RawExternalTypedData* ExternalTypedData::NewFinalizeWithFree(uint8_t* data,
-                                                             intptr_t len) {
+ExternalTypedDataPtr ExternalTypedData::NewFinalizeWithFree(uint8_t* data,
+                                                            intptr_t len) {
   ExternalTypedData& result = ExternalTypedData::Handle(ExternalTypedData::New(
       kExternalTypedDataUint8ArrayCid, data, len, Heap::kOld));
   result.AddFinalizer(
@@ -22991,10 +23079,10 @@
   return result.raw();
 }
 
-RawTypedDataView* TypedDataView::New(intptr_t class_id, Heap::Space space) {
+TypedDataViewPtr TypedDataView::New(intptr_t class_id, Heap::Space space) {
   auto& result = TypedDataView::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(class_id, TypedDataView::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -23003,11 +23091,11 @@
   return result.raw();
 }
 
-RawTypedDataView* TypedDataView::New(intptr_t class_id,
-                                     const TypedDataBase& typed_data,
-                                     intptr_t offset_in_bytes,
-                                     intptr_t length,
-                                     Heap::Space space) {
+TypedDataViewPtr TypedDataView::New(intptr_t class_id,
+                                    const TypedDataBase& typed_data,
+                                    intptr_t offset_in_bytes,
+                                    intptr_t length,
+                                    Heap::Space space) {
   auto& result = TypedDataView::Handle(TypedDataView::New(class_id, space));
   result.InitializeWith(typed_data, offset_in_bytes, length);
   return result.raw();
@@ -23028,9 +23116,9 @@
   return "ExternalTypedData";
 }
 
-RawPointer* Pointer::New(const AbstractType& type_arg,
-                         size_t native_address,
-                         Heap::Space space) {
+PointerPtr Pointer::New(const AbstractType& type_arg,
+                        size_t native_address,
+                        Heap::Space space) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -23058,7 +23146,7 @@
                      type_args_name.ToCString(), NativeAddress());
 }
 
-RawDynamicLibrary* DynamicLibrary::New(void* handle, Heap::Space space) {
+DynamicLibraryPtr DynamicLibrary::New(void* handle, Heap::Space space) {
   DynamicLibrary& result = DynamicLibrary::Handle();
   result ^= Object::Allocate(kFfiDynamicLibraryCid,
                              DynamicLibrary::InstanceSize(), space);
@@ -23068,7 +23156,7 @@
 }
 
 bool Pointer::IsPointer(const Instance& obj) {
-  return RawObject::IsFfiPointerClassId(obj.raw()->GetClassId());
+  return IsFfiPointerClassId(obj.raw()->GetClassId());
 }
 
 bool Instance::IsPointer() const {
@@ -23080,11 +23168,11 @@
                      reinterpret_cast<uintptr_t>(GetHandle()));
 }
 
-RawCapability* Capability::New(uint64_t id, Heap::Space space) {
+CapabilityPtr Capability::New(uint64_t id, Heap::Space space) {
   Capability& result = Capability::Handle();
   {
-    RawObject* raw = Object::Allocate(Capability::kClassId,
-                                      Capability::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(Capability::kClassId,
+                                     Capability::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.raw_ptr()->id_, id);
@@ -23096,9 +23184,9 @@
   return "Capability";
 }
 
-RawReceivePort* ReceivePort::New(Dart_Port id,
-                                 bool is_control_port,
-                                 Heap::Space space) {
+ReceivePortPtr ReceivePort::New(Dart_Port id,
+                                bool is_control_port,
+                                Heap::Space space) {
   ASSERT(id != ILLEGAL_PORT);
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -23107,8 +23195,8 @@
 
   ReceivePort& result = ReceivePort::Handle(zone);
   {
-    RawObject* raw = Object::Allocate(ReceivePort::kClassId,
-                                      ReceivePort::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(ReceivePort::kClassId,
+                                     ReceivePort::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw());
@@ -23125,17 +23213,17 @@
   return "ReceivePort";
 }
 
-RawSendPort* SendPort::New(Dart_Port id, Heap::Space space) {
+SendPortPtr SendPort::New(Dart_Port id, Heap::Space space) {
   return New(id, Isolate::Current()->origin_id(), space);
 }
 
-RawSendPort* SendPort::New(Dart_Port id,
-                           Dart_Port origin_id,
-                           Heap::Space space) {
+SendPortPtr SendPort::New(Dart_Port id,
+                          Dart_Port origin_id,
+                          Heap::Space space) {
   ASSERT(id != ILLEGAL_PORT);
   SendPort& result = SendPort::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -23155,15 +23243,15 @@
   delete (reinterpret_cast<TransferableTypedDataPeer*>(peer));
 }
 
-RawTransferableTypedData* TransferableTypedData::New(uint8_t* data,
-                                                     intptr_t length,
-                                                     Heap::Space space) {
+TransferableTypedDataPtr TransferableTypedData::New(uint8_t* data,
+                                                    intptr_t length,
+                                                    Heap::Space space) {
   TransferableTypedDataPeer* peer = new TransferableTypedDataPeer(data, length);
 
   Thread* thread = Thread::Current();
   TransferableTypedData& result = TransferableTypedData::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(TransferableTypedData::kClassId,
                          TransferableTypedData::InstanceSize(), space);
     NoSafepointScope no_safepoint;
@@ -23230,26 +23318,26 @@
   return FinalizeHash(result, String::kHashBits);
 }
 
-RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
-                         const TypeArguments& function_type_arguments,
-                         const Function& function,
-                         const Context& context,
-                         Heap::Space space) {
+ClosurePtr Closure::New(const TypeArguments& instantiator_type_arguments,
+                        const TypeArguments& function_type_arguments,
+                        const Function& function,
+                        const Context& context,
+                        Heap::Space space) {
   return Closure::New(instantiator_type_arguments, function_type_arguments,
                       function.IsGeneric() ? Object::empty_type_arguments()
                                            : Object::null_type_arguments(),
                       function, context, space);
 }
 
-RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
-                         const TypeArguments& function_type_arguments,
-                         const TypeArguments& delayed_type_arguments,
-                         const Function& function,
-                         const Context& context,
-                         Heap::Space space) {
+ClosurePtr Closure::New(const TypeArguments& instantiator_type_arguments,
+                        const TypeArguments& function_type_arguments,
+                        const TypeArguments& delayed_type_arguments,
+                        const Function& function,
+                        const Context& context,
+                        Heap::Space space) {
   Closure& result = Closure::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -23265,13 +23353,13 @@
   return result.raw();
 }
 
-RawClosure* Closure::New() {
-  RawObject* raw =
+ClosurePtr Closure::New() {
+  ObjectPtr raw =
       Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawClosure*>(raw);
+  return static_cast<ClosurePtr>(raw);
 }
 
-RawFunction* Closure::GetInstantiatedSignature(Zone* zone) const {
+FunctionPtr Closure::GetInstantiatedSignature(Zone* zone) const {
   Function& sig_fun = Function::Handle(zone, function());
   TypeArguments& fn_type_args =
       TypeArguments::Handle(zone, function_type_arguments());
@@ -23312,7 +23400,7 @@
   return code_array.Length();
 }
 
-RawObject* StackTrace::CodeAtFrame(intptr_t frame_index) const {
+ObjectPtr StackTrace::CodeAtFrame(intptr_t frame_index) const {
   const Array& code_array = Array::Handle(raw_ptr()->code_array_);
   return code_array.At(frame_index);
 }
@@ -23323,9 +23411,9 @@
   code_array.SetAt(frame_index, code);
 }
 
-RawSmi* StackTrace::PcOffsetAtFrame(intptr_t frame_index) const {
+SmiPtr StackTrace::PcOffsetAtFrame(intptr_t frame_index) const {
   const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_);
-  return reinterpret_cast<RawSmi*>(pc_offset_array.At(frame_index));
+  return static_cast<SmiPtr>(pc_offset_array.At(frame_index));
 }
 
 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index,
@@ -23354,13 +23442,13 @@
   return raw_ptr()->expand_inlined_;
 }
 
-RawStackTrace* StackTrace::New(const Array& code_array,
-                               const Array& pc_offset_array,
-                               Heap::Space space) {
+StackTracePtr StackTrace::New(const Array& code_array,
+                              const Array& pc_offset_array,
+                              Heap::Space space) {
   StackTrace& result = StackTrace::Handle();
   {
-    RawObject* raw = Object::Allocate(StackTrace::kClassId,
-                                      StackTrace::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
+                                     StackTrace::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -23371,15 +23459,15 @@
   return result.raw();
 }
 
-RawStackTrace* StackTrace::New(const Array& code_array,
-                               const Array& pc_offset_array,
-                               const StackTrace& async_link,
-                               bool skip_sync_start_in_parent_stack,
-                               Heap::Space space) {
+StackTracePtr StackTrace::New(const Array& code_array,
+                              const Array& pc_offset_array,
+                              const StackTrace& async_link,
+                              bool skip_sync_start_in_parent_stack,
+                              Heap::Space space) {
   StackTrace& result = StackTrace::Handle();
   {
-    RawObject* raw = Object::Allocate(StackTrace::kClassId,
-                                      StackTrace::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
+                                     StackTrace::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -23391,25 +23479,66 @@
   return result.raw();
 }
 
-static void PrintStackTraceFrame(Zone* zone,
-                                 ZoneTextBuffer* buffer,
-                                 const Function& function,
-                                 TokenPosition token_pos,
-                                 intptr_t frame_index) {
-  auto& script = Script::Handle(zone);
-  const char* function_name;
-  const char* url;
-
-  if (!function.IsNull()) {
-    script = function.script();
-    auto& handle = String::Handle(zone, function.QualifiedUserVisibleName());
-    function_name = handle.ToCString();
-    handle = script.IsNull() ? String::New("Kernel") : script.url();
-    url = handle.ToCString();
+#if defined(DART_PRECOMPILED_RUNTIME)
+static void PrintNonSymbolicStackFrameBody(ZoneTextBuffer* buffer,
+                                           uword call_addr,
+                                           uword isolate_instructions,
+                                           uword vm_instructions) {
+  const word vm_offset = call_addr - vm_instructions;
+  const word isolate_offset = call_addr - isolate_instructions;
+  // Pick the closest instructions section start before the call address.
+  if (vm_offset > 0 && (isolate_offset < 0 || vm_offset < isolate_offset)) {
+    buffer->Printf(" %s+0x%" Px "", kVmSnapshotInstructionsAsmSymbol,
+                   vm_offset);
+  } else if (isolate_offset > 0) {
+    buffer->Printf(" %s+0x%" Px "", kIsolateSnapshotInstructionsAsmSymbol,
+                   isolate_offset);
   } else {
-    function_name = Symbols::OptimizedOut().ToCString();
-    url = function_name;
+    uword dso_base;
+    char* dso_name;
+    if (NativeSymbolResolver::LookupSharedObject(call_addr, &dso_base,
+                                                 &dso_name)) {
+      buffer->Printf(" %s", dso_name);
+      NativeSymbolResolver::FreeSymbolName(dso_name);
+    } else {
+      buffer->Printf(" <unknown>");
+    }
   }
+  buffer->Printf("\n");
+}
+#endif
+
+static void PrintSymbolicStackFrameIndex(ZoneTextBuffer* buffer,
+                                         intptr_t frame_index) {
+  buffer->Printf("#%-6" Pd "", frame_index);
+}
+
+static void PrintSymbolicStackFrameBody(ZoneTextBuffer* buffer,
+                                        const char* function_name,
+                                        const char* url,
+                                        intptr_t line = -1,
+                                        intptr_t column = -1) {
+  buffer->Printf(" %s (%s", function_name, url);
+  if (line >= 0) {
+    buffer->Printf(":%" Pd "", line);
+    if (column >= 0) {
+      buffer->Printf(":%" Pd "", column);
+    }
+  }
+  buffer->Printf(")\n");
+}
+
+static void PrintSymbolicStackFrame(Zone* zone,
+                                    ZoneTextBuffer* buffer,
+                                    const Function& function,
+                                    TokenPosition token_pos,
+                                    intptr_t frame_index) {
+  ASSERT(!function.IsNull());
+  const auto& script = Script::Handle(zone, function.script());
+  auto& handle = String::Handle(zone, function.QualifiedUserVisibleName());
+  auto const function_name = handle.ToCString();
+  handle = script.IsNull() ? String::New("Kernel") : script.url();
+  auto url = handle.ToCString();
 
   // If the URI starts with "data:application/dart;" this is a URI encoded
   // script so we shouldn't print the entire URI because it could be very long.
@@ -23421,35 +23550,19 @@
   intptr_t column = -1;
   if (FLAG_precompiled_mode) {
     line = token_pos.value();
-  } else if (!script.IsNull() && token_pos.IsSourcePosition()) {
+  } else if (token_pos.IsSourcePosition()) {
+    ASSERT(!script.IsNull());
     script.GetTokenLocation(token_pos.SourcePosition(), &line, &column);
   }
 
-  buffer->Printf("#%-6" Pd " %s (%s", frame_index, function_name, url);
-  if (line >= 0) {
-    buffer->Printf(":%" Pd "", line);
-    if (column >= 0) {
-      buffer->Printf(":%" Pd "", column);
-    }
-  }
-  buffer->Printf(")\n");
+  PrintSymbolicStackFrameIndex(buffer, frame_index);
+  PrintSymbolicStackFrameBody(buffer, function_name, url, line, column);
 }
 
-static inline bool ShouldPrintFrame(const Function& function) {
-  // TODO(dartbug.com/41052): Currently, we print frames where the function
-  // object was optimized out in the precompiled runtime, even if the original
-  // function was not visible. We may want to either elide such frames, or
-  // instead store additional information in the WSR that allows us to determine
-  // the original visibility.
-#if defined(DART_PRECOMPILED_RUNTIME)
-  if (function.IsNull()) return true;
-#endif
-  return FLAG_show_invisible_frames || function.is_visible();
-}
-
-const char* StackTrace::ToDartCString(const StackTrace& stack_trace_in) {
-  auto const zone = Thread::Current()->zone();
-  auto& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw());
+const char* StackTrace::ToCString() const {
+  auto const T = Thread::Current();
+  auto const zone = T->zone();
+  auto& stack_trace = StackTrace::Handle(zone, this->raw());
   auto& function = Function::Handle(zone);
   auto& code_object = Object::Handle(zone);
   auto& code = Code::Handle(zone);
@@ -23459,6 +23572,30 @@
   GrowableArray<TokenPosition> inlined_token_positions;
   ZoneTextBuffer buffer(zone, 1024);
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+  auto const isolate_instructions = reinterpret_cast<uword>(
+      T->isolate_group()->source()->snapshot_instructions);
+  auto const vm_instructions = reinterpret_cast<uword>(
+      Dart::vm_isolate()->group()->source()->snapshot_instructions);
+  if (FLAG_dwarf_stack_traces_mode) {
+    // The Dart standard requires the output of StackTrace.toString to include
+    // all pending activations with precise source locations (i.e., to expand
+    // inlined frames and provide line and column numbers).
+    buffer.Printf(
+        "Warning: This VM has been configured to produce stack traces "
+        "that violate the Dart standard.\n");
+    // This prologue imitates Android's debuggerd to make it possible to paste
+    // the stack trace into ndk-stack.
+    buffer.Printf(
+        "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
+    OSThread* thread = OSThread::Current();
+    buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(),
+                  OSThread::ThreadIdToIntPtr(thread->id()), thread->name());
+    buffer.Printf("isolate_instructions: %" Px "", isolate_instructions);
+    buffer.Printf(" vm_instructions: %" Px "\n", vm_instructions);
+  }
+#endif
+
   // Iterate through the stack frames and create C string description
   // for each frame.
   intptr_t frame_index = 0;
@@ -23483,6 +23620,46 @@
         if (code_object.IsCode()) {
           code ^= code_object.raw();
           ASSERT(code.IsFunctionCode());
+          function = code.function();
+          const uword pc = code.PayloadStart() + pc_offset;
+#if defined(DART_PRECOMPILED_RUNTIME)
+          // When printing non-symbolic frames, we normally print call
+          // addresses, not return addresses, by subtracting one from the PC to
+          // get an address within the preceding instruction.
+          //
+          // The one exception is a normal closure registered as a listener on a
+          // future. In this case, the returned pc_offset is 0, as the closure
+          // is invoked with the value of the resolved future. Thus, we must
+          // report the return address, as returning a value before the closure
+          // payload will cause failures to decode the frame using DWARF info.
+          const bool is_future_listener = pc_offset == 0;
+          const uword call_addr = is_future_listener ? pc : pc - 1;
+          if (FLAG_dwarf_stack_traces_mode) {
+            // If we have access to the owning function and it would be
+            // invisible in a symbolic stack trace, don't show this frame.
+            // (We can't do the same for inlined functions, though.)
+            if (!FLAG_show_invisible_frames && !function.IsNull() &&
+                !function.is_visible()) {
+              continue;
+            }
+            // This output is formatted like Android's debuggerd. Note debuggerd
+            // prints call addresses instead of return addresses.
+            buffer.Printf("    #%02" Pd " abs %" Pp "", frame_index, call_addr);
+            PrintNonSymbolicStackFrameBody(
+                &buffer, call_addr, isolate_instructions, vm_instructions);
+            frame_index++;
+            continue;
+          } else if (function.IsNull()) {
+            // We can't print the symbolic information since the owner was not
+            // retained, so instead print the static symbol + offset like the
+            // non-symbolic stack traces.
+            PrintSymbolicStackFrameIndex(&buffer, frame_index);
+            PrintNonSymbolicStackFrameBody(
+                &buffer, call_addr, isolate_instructions, vm_instructions);
+            frame_index++;
+            continue;
+          }
+#endif
           if (code.is_optimized() && stack_trace.expand_inlined()) {
             code.GetInlinedFunctionsAtReturnAddress(
                 pc_offset, &inlined_functions, &inlined_token_positions);
@@ -23490,28 +23667,25 @@
             for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
               const auto& inlined = *inlined_functions[j];
               auto const pos = inlined_token_positions[j];
-              if (ShouldPrintFrame(inlined)) {
-                PrintStackTraceFrame(zone, &buffer, inlined, pos, frame_index);
+              if (FLAG_show_invisible_frames || function.is_visible()) {
+                PrintSymbolicStackFrame(zone, &buffer, inlined, pos,
+                                        frame_index);
                 frame_index++;
               }
             }
-          } else {
-            function = code.function();
-            if (ShouldPrintFrame(function)) {
-              uword pc = code.PayloadStart() + pc_offset;
-              auto const pos = code.GetTokenIndexOfPC(pc);
-              PrintStackTraceFrame(zone, &buffer, function, pos, frame_index);
-              frame_index++;
-            }
+          } else if (FLAG_show_invisible_frames || function.is_visible()) {
+            auto const pos = code.GetTokenIndexOfPC(pc);
+            PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index);
+            frame_index++;
           }
         } else {
           ASSERT(code_object.IsBytecode());
           bytecode ^= code_object.raw();
           function = bytecode.function();
-          if (ShouldPrintFrame(function)) {
+          if (FLAG_show_invisible_frames || function.is_visible()) {
             uword pc = bytecode.PayloadStart() + pc_offset;
             auto const pos = bytecode.GetTokenIndexOfPC(pc);
-            PrintStackTraceFrame(zone, &buffer, function, pos, frame_index);
+            PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index);
             frame_index++;
           }
         }
@@ -23527,111 +23701,24 @@
   return buffer.buffer();
 }
 
-const char* StackTrace::ToDwarfCString(const StackTrace& stack_trace_in) {
-#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
-  auto const T = Thread::Current();
-  auto const zone = T->zone();
-  auto& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw());
-  auto& code = Object::Handle(zone);
-  ZoneTextBuffer buffer(zone, 1024);
+static void DwarfStackTracesHandler(bool value) {
+  FLAG_dwarf_stack_traces_mode = value;
 
-  // The Dart standard requires the output of StackTrace.toString to include
-  // all pending activations with precise source locations (i.e., to expand
-  // inlined frames and provide line and column numbers).
-  buffer.Printf(
-      "Warning: This VM has been configured to produce stack traces "
-      "that violate the Dart standard.\n");
-  // This prologue imitates Android's debuggerd to make it possible to paste
-  // the stack trace into ndk-stack.
-  buffer.Printf(
-      "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
-  OSThread* thread = OSThread::Current();
-  buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(),
-                OSThread::ThreadIdToIntPtr(thread->id()), thread->name());
-  auto const isolate_instructions =
-      T->isolate_group()->source()->snapshot_instructions;
-  auto const vm_instructions =
-      Dart::vm_isolate()->group()->source()->snapshot_instructions;
-  buffer.Printf("isolate_instructions: %" Px "",
-                reinterpret_cast<uintptr_t>(isolate_instructions));
-  buffer.Printf(" vm_instructions: %" Px "\n",
-                reinterpret_cast<uintptr_t>(vm_instructions));
-  intptr_t frame_index = 0;
-  uint32_t frame_skip = 0;
-  do {
-    for (intptr_t i = frame_skip; i < stack_trace.Length(); i++) {
-      code = stack_trace.CodeAtFrame(i);
-      if (code.IsNull()) {
-        // Check for a null function, which indicates a gap in a StackOverflow
-        // or OutOfMemory trace.
-        if ((i < (stack_trace.Length() - 1)) &&
-            (stack_trace.CodeAtFrame(i + 1) != Code::null())) {
-          buffer.AddString("...\n...\n");
-          ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null());
-          // To account for gap frames.
-          frame_index += Smi::Value(stack_trace.PcOffsetAtFrame(i));
-        }
-      } else if (code.raw() == StubCode::AsynchronousGapMarker().raw()) {
-        buffer.AddString("<asynchronous suspension>\n");
-        // The frame immediately after the asynchronous gap marker is the
-        // identical to the frame above the marker. Skip the frame to enhance
-        // the readability of the trace.
-        i++;
-      } else {
-        intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i));
-        // This output is formatted like Android's debuggerd. Note debuggerd
-        // prints call addresses instead of return addresses.
-        uword start = code.IsBytecode() ? Bytecode::Cast(code).PayloadStart()
-                                        : Code::Cast(code).PayloadStart();
-        uword return_addr = start + pc_offset;
-        uword call_addr = return_addr - 1;
-        buffer.Printf("    #%02" Pd " abs %" Pp "", frame_index, call_addr);
-        uword dso_base;
-        char* dso_name;
-        if (NativeSymbolResolver::LookupSharedObject(call_addr, &dso_base,
-                                                     &dso_name)) {
-          uword dso_offset = call_addr - dso_base;
-          buffer.Printf(" virt %" Pp "", dso_offset);
-          uword symbol_start;
-          if (auto const symbol_name = NativeSymbolResolver::LookupSymbolName(
-                  call_addr, &symbol_start)) {
-            uword symbol_offset = call_addr - symbol_start;
-            buffer.Printf(" %s+0x%" Px "", symbol_name, symbol_offset);
-            NativeSymbolResolver::FreeSymbolName(symbol_name);
-          } else {
-            buffer.Printf(" %s", dso_name);
-          }
-          NativeSymbolResolver::FreeSymbolName(dso_name);
-        } else {
-          buffer.Printf(" <unknown>");
-        }
-        buffer.Printf("\n");
-        frame_index++;
-      }
-    }
-    // Follow the link.
-    frame_skip = stack_trace.skip_sync_start_in_parent_stack()
-                     ? StackTrace::kSyncAsyncCroppedFrames
-                     : 0;
-    stack_trace = stack_trace.async_link();
-  } while (!stack_trace.IsNull());
-
-  return buffer.buffer();
-#else
-  UNREACHABLE();
-  return NULL;
-#endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
-}
-
-const char* StackTrace::ToCString() const {
-#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
-  if (FLAG_dwarf_stack_traces) {
-    return ToDwarfCString(*this);
+#if defined(PRODUCT)
+  // We can safely remove function objects in precompiled snapshots if the
+  // runtime will generate DWARF stack traces and we don't have runtime
+  // debugging options like the observatory available.
+  if (value) {
+    FLAG_retain_function_objects = false;
   }
 #endif
-  return ToDartCString(*this);
 }
 
+DEFINE_FLAG_HANDLER(DwarfStackTracesHandler,
+                    dwarf_stack_traces,
+                    "Omit CodeSourceMaps in precompiled snapshots and don't "
+                    "symbolize stack traces in the precompiled runtime.");
+
 void RegExp::set_pattern(const String& pattern) const {
   StorePointer(&raw_ptr()->pattern_, pattern.raw());
 }
@@ -23668,10 +23755,10 @@
   StorePointer(&raw_ptr()->capture_name_map_, array.raw());
 }
 
-RawRegExp* RegExp::New(Heap::Space space) {
+RegExpPtr RegExp::New(Heap::Space space) {
   RegExp& result = RegExp::Handle();
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -23748,12 +23835,12 @@
                      str.ToCString(), flags().ToCString());
 }
 
-RawWeakProperty* WeakProperty::New(Heap::Space space) {
+WeakPropertyPtr WeakProperty::New(Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->weak_property_class() !=
          Class::null());
-  RawObject* raw = Object::Allocate(WeakProperty::kClassId,
-                                    WeakProperty::InstanceSize(), space);
-  RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw);
+  ObjectPtr raw = Object::Allocate(WeakProperty::kClassId,
+                                   WeakProperty::InstanceSize(), space);
+  WeakPropertyPtr result = static_cast<WeakPropertyPtr>(raw);
   result->ptr()->next_ = 0;  // Init the list to NULL.
   return result;
 }
@@ -23762,42 +23849,42 @@
   return "_WeakProperty";
 }
 
-RawAbstractType* MirrorReference::GetAbstractTypeReferent() const {
+AbstractTypePtr MirrorReference::GetAbstractTypeReferent() const {
   ASSERT(Object::Handle(referent()).IsAbstractType());
   return AbstractType::Cast(Object::Handle(referent())).raw();
 }
 
-RawClass* MirrorReference::GetClassReferent() const {
+ClassPtr MirrorReference::GetClassReferent() const {
   ASSERT(Object::Handle(referent()).IsClass());
   return Class::Cast(Object::Handle(referent())).raw();
 }
 
-RawField* MirrorReference::GetFieldReferent() const {
+FieldPtr MirrorReference::GetFieldReferent() const {
   ASSERT(Object::Handle(referent()).IsField());
   return Field::Cast(Object::Handle(referent())).raw();
 }
 
-RawFunction* MirrorReference::GetFunctionReferent() const {
+FunctionPtr MirrorReference::GetFunctionReferent() const {
   ASSERT(Object::Handle(referent()).IsFunction());
   return Function::Cast(Object::Handle(referent())).raw();
 }
 
-RawLibrary* MirrorReference::GetLibraryReferent() const {
+LibraryPtr MirrorReference::GetLibraryReferent() const {
   ASSERT(Object::Handle(referent()).IsLibrary());
   return Library::Cast(Object::Handle(referent())).raw();
 }
 
-RawTypeParameter* MirrorReference::GetTypeParameterReferent() const {
+TypeParameterPtr MirrorReference::GetTypeParameterReferent() const {
   ASSERT(Object::Handle(referent()).IsTypeParameter());
   return TypeParameter::Cast(Object::Handle(referent())).raw();
 }
 
-RawMirrorReference* MirrorReference::New(const Object& referent,
-                                         Heap::Space space) {
+MirrorReferencePtr MirrorReference::New(const Object& referent,
+                                        Heap::Space space) {
   MirrorReference& result = MirrorReference::Handle();
   {
-    RawObject* raw = Object::Allocate(MirrorReference::kClassId,
-                                      MirrorReference::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(MirrorReference::kClassId,
+                                     MirrorReference::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -23815,7 +23902,7 @@
   isolate->set_current_tag(*this);
 }
 
-RawUserTag* UserTag::New(const String& label, Heap::Space space) {
+UserTagPtr UserTag::New(const String& label, Heap::Space space) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
@@ -23834,7 +23921,7 @@
   }
   // No tag with label exists, create and register with isolate tag table.
   {
-    RawObject* raw =
+    ObjectPtr raw =
         Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
@@ -23844,7 +23931,7 @@
   return result.raw();
 }
 
-RawUserTag* UserTag::DefaultTag() {
+UserTagPtr UserTag::DefaultTag() {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -23861,7 +23948,7 @@
   return result.raw();
 }
 
-RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) {
+UserTagPtr UserTag::FindTagInIsolate(Thread* thread, const String& label) {
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
@@ -23915,7 +24002,7 @@
   return tag_table.Length() == UserTags::kMaxUserTags;
 }
 
-RawUserTag* UserTag::FindTagById(uword tag_id) {
+UserTagPtr UserTag::FindTagById(uword tag_id) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -23986,7 +24073,7 @@
 }
 
 DART_WARN_UNUSED_RESULT
-RawError* VerifyEntryPoint(
+ErrorPtr VerifyEntryPoint(
     const Library& lib,
     const Object& member,
     const Object& annotated,
@@ -24046,7 +24133,7 @@
 }
 
 DART_WARN_UNUSED_RESULT
-RawError* EntryPointFieldInvocationError(const String& getter_name) {
+ErrorPtr EntryPointFieldInvocationError(const String& getter_name) {
   if (!FLAG_verify_entry_points) return Error::null();
 
   char const* error = OS::SCreate(
@@ -24061,31 +24148,31 @@
   return ApiError::New(String::Handle(String::New(error)));
 }
 
-RawError* Function::VerifyCallEntryPoint() const {
+ErrorPtr Function::VerifyCallEntryPoint() const {
   if (!FLAG_verify_entry_points) return Error::null();
 
   const Class& cls = Class::Handle(Owner());
   const Library& lib = Library::Handle(cls.library());
   switch (kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kConstructor:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kConstructor:
       return dart::VerifyEntryPoint(lib, *this, *this,
                                     {EntryPointPragma::kCallOnly});
       break;
-    case RawFunction::kGetterFunction:
+    case FunctionLayout::kGetterFunction:
       return dart::VerifyEntryPoint(
           lib, *this, *this,
           {EntryPointPragma::kCallOnly, EntryPointPragma::kGetterOnly});
       break;
-    case RawFunction::kImplicitGetter:
+    case FunctionLayout::kImplicitGetter:
       return dart::VerifyEntryPoint(lib, *this, Field::Handle(accessor_field()),
                                     {EntryPointPragma::kGetterOnly});
       break;
-    case RawFunction::kImplicitSetter:
+    case FunctionLayout::kImplicitSetter:
       return dart::VerifyEntryPoint(lib, *this, Field::Handle(accessor_field()),
                                     {EntryPointPragma::kSetterOnly});
-    case RawFunction::kMethodExtractor:
+    case FunctionLayout::kMethodExtractor:
       return Function::Handle(extracted_method_closure())
           .VerifyClosurizedEntryPoint();
       break;
@@ -24095,14 +24182,14 @@
   }
 }
 
-RawError* Function::VerifyClosurizedEntryPoint() const {
+ErrorPtr Function::VerifyClosurizedEntryPoint() const {
   if (!FLAG_verify_entry_points) return Error::null();
 
   const Class& cls = Class::Handle(Owner());
   const Library& lib = Library::Handle(cls.library());
   switch (kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kImplicitClosureFunction:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kImplicitClosureFunction:
       return dart::VerifyEntryPoint(lib, *this, *this,
                                     {EntryPointPragma::kGetterOnly});
     default:
@@ -24110,14 +24197,14 @@
   }
 }
 
-RawError* Field::VerifyEntryPoint(EntryPointPragma pragma) const {
+ErrorPtr Field::VerifyEntryPoint(EntryPointPragma pragma) const {
   if (!FLAG_verify_entry_points) return Error::null();
   const Class& cls = Class::Handle(Owner());
   const Library& lib = Library::Handle(cls.library());
   return dart::VerifyEntryPoint(lib, *this, *this, {pragma});
 }
 
-RawError* Class::VerifyEntryPoint() const {
+ErrorPtr Class::VerifyEntryPoint() const {
   if (!FLAG_verify_entry_points) return Error::null();
   const Library& lib = Library::Handle(library());
   if (!lib.IsNull()) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index f6f53bb..82779b4 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -80,8 +80,9 @@
 
 #define BASE_OBJECT_IMPLEMENTATION(object, super)                              \
  public: /* NOLINT */                                                          \
-  using RawObjectType = Raw##object;                                           \
-  Raw##object* raw() const { return reinterpret_cast<Raw##object*>(raw_); }    \
+  using ObjectLayoutType = dart::object##Layout;                               \
+  using ObjectPtrType = dart::object##Ptr;                                     \
+  object##Ptr raw() const { return static_cast<object##Ptr>(raw_); }           \
   bool Is##object() const { return true; }                                     \
   DART_NOINLINE static object& Handle() {                                      \
     return HandleImpl(Thread::Current()->zone(), object::null());              \
@@ -89,10 +90,10 @@
   DART_NOINLINE static object& Handle(Zone* zone) {                            \
     return HandleImpl(zone, object::null());                                   \
   }                                                                            \
-  DART_NOINLINE static object& Handle(Raw##object* raw_ptr) {                  \
+  DART_NOINLINE static object& Handle(object##Ptr raw_ptr) {                   \
     return HandleImpl(Thread::Current()->zone(), raw_ptr);                     \
   }                                                                            \
-  DART_NOINLINE static object& Handle(Zone* zone, Raw##object* raw_ptr) {      \
+  DART_NOINLINE static object& Handle(Zone* zone, object##Ptr raw_ptr) {       \
     return HandleImpl(zone, raw_ptr);                                          \
   }                                                                            \
   DART_NOINLINE static object& ZoneHandle() {                                  \
@@ -101,10 +102,10 @@
   DART_NOINLINE static object& ZoneHandle(Zone* zone) {                        \
     return ZoneHandleImpl(zone, object::null());                               \
   }                                                                            \
-  DART_NOINLINE static object& ZoneHandle(Raw##object* raw_ptr) {              \
+  DART_NOINLINE static object& ZoneHandle(object##Ptr raw_ptr) {               \
     return ZoneHandleImpl(Thread::Current()->zone(), raw_ptr);                 \
   }                                                                            \
-  DART_NOINLINE static object& ZoneHandle(Zone* zone, Raw##object* raw_ptr) {  \
+  DART_NOINLINE static object& ZoneHandle(Zone* zone, object##Ptr raw_ptr) {   \
     return ZoneHandleImpl(zone, raw_ptr);                                      \
   }                                                                            \
   DART_NOINLINE static object* ReadOnlyHandle() {                              \
@@ -112,7 +113,7 @@
     initializeHandle(obj, object::null());                                     \
     return obj;                                                                \
   }                                                                            \
-  DART_NOINLINE static object& CheckedHandle(Zone* zone, RawObject* raw_ptr) { \
+  DART_NOINLINE static object& CheckedHandle(Zone* zone, ObjectPtr raw_ptr) {  \
     object* obj = reinterpret_cast<object*>(VMHandles::AllocateHandle(zone));  \
     initializeHandle(obj, raw_ptr);                                            \
     if (!obj->Is##object()) {                                                  \
@@ -122,7 +123,7 @@
     return *obj;                                                               \
   }                                                                            \
   DART_NOINLINE static object& CheckedZoneHandle(Zone* zone,                   \
-                                                 RawObject* raw_ptr) {         \
+                                                 ObjectPtr raw_ptr) {          \
     object* obj =                                                              \
         reinterpret_cast<object*>(VMHandles::AllocateZoneHandle(zone));        \
     initializeHandle(obj, raw_ptr);                                            \
@@ -132,7 +133,7 @@
     }                                                                          \
     return *obj;                                                               \
   }                                                                            \
-  DART_NOINLINE static object& CheckedZoneHandle(RawObject* raw_ptr) {         \
+  DART_NOINLINE static object& CheckedZoneHandle(ObjectPtr raw_ptr) {          \
     return CheckedZoneHandle(Thread::Current()->zone(), raw_ptr);              \
   }                                                                            \
   /* T::Cast cannot be applied to a null Object, because the object vtable */  \
@@ -142,30 +143,30 @@
     ASSERT(obj.Is##object());                                                  \
     return reinterpret_cast<const object&>(obj);                               \
   }                                                                            \
-  static Raw##object* RawCast(RawObject* raw) {                                \
+  static object##Ptr RawCast(ObjectPtr raw) {                                  \
     ASSERT(Object::Handle(raw).IsNull() || Object::Handle(raw).Is##object());  \
-    return reinterpret_cast<Raw##object*>(raw);                                \
+    return static_cast<object##Ptr>(raw);                                      \
   }                                                                            \
-  static Raw##object* null() {                                                 \
-    return reinterpret_cast<Raw##object*>(Object::null());                     \
+  static object##Ptr null() {                                                  \
+    return static_cast<object##Ptr>(Object::null());                           \
   }                                                                            \
   virtual const char* ToCString() const;                                       \
   static const ClassId kClassId = k##object##Cid;                              \
                                                                                \
  private: /* NOLINT */                                                         \
-  static object& HandleImpl(Zone* zone, Raw##object* raw_ptr) {                \
+  static object& HandleImpl(Zone* zone, object##Ptr raw_ptr) {                 \
     object* obj = reinterpret_cast<object*>(VMHandles::AllocateHandle(zone));  \
     initializeHandle(obj, raw_ptr);                                            \
     return *obj;                                                               \
   }                                                                            \
-  static object& ZoneHandleImpl(Zone* zone, Raw##object* raw_ptr) {            \
+  static object& ZoneHandleImpl(Zone* zone, object##Ptr raw_ptr) {             \
     object* obj =                                                              \
         reinterpret_cast<object*>(VMHandles::AllocateZoneHandle(zone));        \
     initializeHandle(obj, raw_ptr);                                            \
     return *obj;                                                               \
   }                                                                            \
   /* Initialize the handle based on the raw_ptr in the presence of null. */    \
-  static void initializeHandle(object* obj, RawObject* raw_ptr) {              \
+  static void initializeHandle(object* obj, ObjectPtr raw_ptr) {               \
     if (raw_ptr != Object::null()) {                                           \
       obj->SetRaw(raw_ptr);                                                    \
     } else {                                                                   \
@@ -181,7 +182,7 @@
  private: /* NOLINT */                                                         \
   void* operator new(size_t size);                                             \
   object(const object& value) = delete;                                        \
-  void operator=(Raw##super* value) = delete;                                  \
+  void operator=(super##Ptr value) = delete;                                   \
   void operator=(const object& value) = delete;                                \
   void operator=(const super& value) = delete;
 
@@ -205,15 +206,15 @@
 #endif                                            // !PRODUCT
 
 #define SNAPSHOT_READER_SUPPORT(object)                                        \
-  static Raw##object* ReadFrom(SnapshotReader* reader, intptr_t object_id,     \
-                               intptr_t tags, Snapshot::Kind,                  \
-                               bool as_reference);                             \
+  static object##Ptr ReadFrom(SnapshotReader* reader, intptr_t object_id,      \
+                              intptr_t tags, Snapshot::Kind,                   \
+                              bool as_reference);                              \
   friend class SnapshotReader;
 
 #define OBJECT_IMPLEMENTATION(object, super)                                   \
  public: /* NOLINT */                                                          \
-  void operator=(Raw##object* value) { initializeHandle(this, value); }        \
-  void operator^=(RawObject* value) {                                          \
+  void operator=(object##Ptr value) { initializeHandle(this, value); }         \
+  void operator^=(ObjectPtr value) {                                           \
     initializeHandle(this, value);                                             \
     ASSERT(IsNull() || Is##object());                                          \
   }                                                                            \
@@ -226,7 +227,7 @@
 
 #define HEAP_OBJECT_IMPLEMENTATION(object, super)                              \
   OBJECT_IMPLEMENTATION(object, super);                                        \
-  const Raw##object* raw_ptr() const {                                         \
+  const object##Layout* raw_ptr() const {                                      \
     ASSERT(raw() != null());                                                   \
     return raw()->ptr();                                                       \
   }                                                                            \
@@ -237,11 +238,11 @@
 // This macro is used to denote types that do not have a sub-type.
 #define FINAL_HEAP_OBJECT_IMPLEMENTATION_HELPER(object, rettype, super)        \
  public: /* NOLINT */                                                          \
-  void operator=(Raw##object* value) {                                         \
+  void operator=(object##Ptr value) {                                          \
     raw_ = value;                                                              \
     CHECK_HANDLE();                                                            \
   }                                                                            \
-  void operator^=(RawObject* value) {                                          \
+  void operator^=(ObjectPtr value) {                                           \
     raw_ = value;                                                              \
     CHECK_HANDLE();                                                            \
   }                                                                            \
@@ -250,7 +251,7 @@
   object() : super() {}                                                        \
   BASE_OBJECT_IMPLEMENTATION(object, super)                                    \
   OBJECT_SERVICE_SUPPORT(object)                                               \
-  const Raw##object* raw_ptr() const {                                         \
+  const object##Layout* raw_ptr() const {                                      \
     ASSERT(raw() != null());                                                   \
     return raw()->ptr();                                                       \
   }                                                                            \
@@ -277,27 +278,29 @@
 
 class Object {
  public:
-  using RawObjectType = RawObject;
-  static RawObject* RawCast(RawObject* obj) { return obj; }
+  using ObjectLayoutType = ObjectLayout;
+  using ObjectPtrType = ObjectPtr;
+
+  static ObjectPtr RawCast(ObjectPtr obj) { return obj; }
 
   virtual ~Object() {}
 
-  RawObject* raw() const { return raw_; }
-  void operator=(RawObject* value) { initializeHandle(this, value); }
+  ObjectPtr raw() const { return raw_; }
+  void operator=(ObjectPtr value) { initializeHandle(this, value); }
 
   uint32_t CompareAndSwapTags(uint32_t old_tags, uint32_t new_tags) const {
     raw()->ptr()->tags_.StrongCAS(old_tags, new_tags);
     return old_tags;
   }
-  bool IsCanonical() const { return raw()->IsCanonical(); }
-  void SetCanonical() const { raw()->SetCanonical(); }
-  void ClearCanonical() const { raw()->ClearCanonical(); }
+  bool IsCanonical() const { return raw()->ptr()->IsCanonical(); }
+  void SetCanonical() const { raw()->ptr()->SetCanonical(); }
+  void ClearCanonical() const { raw()->ptr()->ClearCanonical(); }
   intptr_t GetClassId() const {
     return !raw()->IsHeapObject() ? static_cast<intptr_t>(kSmiCid)
-                                  : raw()->GetClassId();
+                                  : raw()->ptr()->GetClassId();
   }
-  inline RawClass* clazz() const;
-  static intptr_t tags_offset() { return OFFSET_OF(RawObject, tags_); }
+  inline ClassPtr clazz() const;
+  static intptr_t tags_offset() { return OFFSET_OF(ObjectLayout, tags_); }
 
 // Class testers.
 #define DEFINE_CLASS_TESTER(clazz)                                             \
@@ -327,14 +330,14 @@
   // Object::DictionaryName() returns String::null(). Only subclasses
   // of Object that need to be entered in the library and library prefix
   // namespaces need to provide an implementation.
-  virtual RawString* DictionaryName() const;
+  virtual StringPtr DictionaryName() const;
 
   bool IsNew() const { return raw()->IsNewObject(); }
   bool IsOld() const { return raw()->IsOldObject(); }
 #if defined(DEBUG)
   bool InVMIsolateHeap() const;
 #else
-  bool InVMIsolateHeap() const { return raw()->InVMIsolateHeap(); }
+  bool InVMIsolateHeap() const { return raw()->ptr()->InVMIsolateHeap(); }
 #endif  // DEBUG
 
   // Print the object on stdout for debugging.
@@ -348,7 +351,7 @@
 
   bool IsNotTemporaryScopedHandle() const;
 
-  static Object& Handle(Zone* zone, RawObject* raw_ptr) {
+  static Object& Handle(Zone* zone, ObjectPtr raw_ptr) {
     Object* obj = reinterpret_cast<Object*>(VMHandles::AllocateHandle(zone));
     initializeHandle(obj, raw_ptr);
     return *obj;
@@ -363,11 +366,11 @@
 
   static Object& Handle(Zone* zone) { return Handle(zone, null_); }
 
-  static Object& Handle(RawObject* raw_ptr) {
+  static Object& Handle(ObjectPtr raw_ptr) {
     return Handle(Thread::Current()->zone(), raw_ptr);
   }
 
-  static Object& ZoneHandle(Zone* zone, RawObject* raw_ptr) {
+  static Object& ZoneHandle(Zone* zone, ObjectPtr raw_ptr) {
     Object* obj =
         reinterpret_cast<Object*>(VMHandles::AllocateZoneHandle(zone));
     initializeHandle(obj, raw_ptr);
@@ -380,18 +383,18 @@
     return ZoneHandle(Thread::Current()->zone(), null_);
   }
 
-  static Object& ZoneHandle(RawObject* raw_ptr) {
+  static Object& ZoneHandle(ObjectPtr raw_ptr) {
     return ZoneHandle(Thread::Current()->zone(), raw_ptr);
   }
 
-  static RawObject* null() { return null_; }
+  static ObjectPtr null() { return null_; }
 
 #if defined(HASH_IN_OBJECT_HEADER)
-  static uint32_t GetCachedHash(const RawObject* obj) {
+  static uint32_t GetCachedHash(const ObjectPtr obj) {
     return obj->ptr()->hash_;
   }
 
-  static void SetCachedHash(RawObject* obj, uint32_t hash) {
+  static void SetCachedHash(ObjectPtr obj, uint32_t hash) {
     obj->ptr()->hash_ = hash;
   }
 #endif
@@ -448,7 +451,6 @@
   V(Array, vm_isolate_snapshot_object_table)                                   \
   V(Type, dynamic_type)                                                        \
   V(Type, void_type)                                                           \
-  V(Type, never_type)                                                          \
   V(AbstractType, null_abstract_type)
 
 #define DEFINE_SHARED_READONLY_HANDLE_GETTER(Type, name)                       \
@@ -461,90 +463,85 @@
 
   static void set_vm_isolate_snapshot_object_table(const Array& table);
 
-  static RawClass* class_class() { return class_class_; }
-  static RawClass* dynamic_class() { return dynamic_class_; }
-  static RawClass* void_class() { return void_class_; }
-  static RawClass* never_class() { return never_class_; }
-  static RawClass* type_arguments_class() { return type_arguments_class_; }
-  static RawClass* patch_class_class() { return patch_class_class_; }
-  static RawClass* function_class() { return function_class_; }
-  static RawClass* closure_data_class() { return closure_data_class_; }
-  static RawClass* signature_data_class() { return signature_data_class_; }
-  static RawClass* redirection_data_class() { return redirection_data_class_; }
-  static RawClass* ffi_trampoline_data_class() {
+  static ClassPtr class_class() { return class_class_; }
+  static ClassPtr dynamic_class() { return dynamic_class_; }
+  static ClassPtr void_class() { return void_class_; }
+  static ClassPtr type_arguments_class() { return type_arguments_class_; }
+  static ClassPtr patch_class_class() { return patch_class_class_; }
+  static ClassPtr function_class() { return function_class_; }
+  static ClassPtr closure_data_class() { return closure_data_class_; }
+  static ClassPtr signature_data_class() { return signature_data_class_; }
+  static ClassPtr redirection_data_class() { return redirection_data_class_; }
+  static ClassPtr ffi_trampoline_data_class() {
     return ffi_trampoline_data_class_;
   }
-  static RawClass* field_class() { return field_class_; }
-  static RawClass* script_class() { return script_class_; }
-  static RawClass* library_class() { return library_class_; }
-  static RawClass* namespace_class() { return namespace_class_; }
-  static RawClass* kernel_program_info_class() {
+  static ClassPtr field_class() { return field_class_; }
+  static ClassPtr script_class() { return script_class_; }
+  static ClassPtr library_class() { return library_class_; }
+  static ClassPtr namespace_class() { return namespace_class_; }
+  static ClassPtr kernel_program_info_class() {
     return kernel_program_info_class_;
   }
-  static RawClass* code_class() { return code_class_; }
-  static RawClass* bytecode_class() { return bytecode_class_; }
-  static RawClass* instructions_class() { return instructions_class_; }
-  static RawClass* instructions_section_class() {
+  static ClassPtr code_class() { return code_class_; }
+  static ClassPtr bytecode_class() { return bytecode_class_; }
+  static ClassPtr instructions_class() { return instructions_class_; }
+  static ClassPtr instructions_section_class() {
     return instructions_section_class_;
   }
-  static RawClass* object_pool_class() { return object_pool_class_; }
-  static RawClass* pc_descriptors_class() { return pc_descriptors_class_; }
-  static RawClass* code_source_map_class() { return code_source_map_class_; }
-  static RawClass* compressed_stackmaps_class() {
+  static ClassPtr object_pool_class() { return object_pool_class_; }
+  static ClassPtr pc_descriptors_class() { return pc_descriptors_class_; }
+  static ClassPtr code_source_map_class() { return code_source_map_class_; }
+  static ClassPtr compressed_stackmaps_class() {
     return compressed_stackmaps_class_;
   }
-  static RawClass* var_descriptors_class() { return var_descriptors_class_; }
-  static RawClass* exception_handlers_class() {
+  static ClassPtr var_descriptors_class() { return var_descriptors_class_; }
+  static ClassPtr exception_handlers_class() {
     return exception_handlers_class_;
   }
-  static RawClass* deopt_info_class() { return deopt_info_class_; }
-  static RawClass* context_class() { return context_class_; }
-  static RawClass* context_scope_class() { return context_scope_class_; }
-  static RawClass* api_error_class() { return api_error_class_; }
-  static RawClass* language_error_class() { return language_error_class_; }
-  static RawClass* unhandled_exception_class() {
+  static ClassPtr deopt_info_class() { return deopt_info_class_; }
+  static ClassPtr context_class() { return context_class_; }
+  static ClassPtr context_scope_class() { return context_scope_class_; }
+  static ClassPtr api_error_class() { return api_error_class_; }
+  static ClassPtr language_error_class() { return language_error_class_; }
+  static ClassPtr unhandled_exception_class() {
     return unhandled_exception_class_;
   }
-  static RawClass* unwind_error_class() { return unwind_error_class_; }
-  static RawClass* dyncalltypecheck_class() { return dyncalltypecheck_class_; }
-  static RawClass* singletargetcache_class() {
-    return singletargetcache_class_;
-  }
-  static RawClass* unlinkedcall_class() { return unlinkedcall_class_; }
-  static RawClass* monomorphicsmiablecall_class() {
+  static ClassPtr unwind_error_class() { return unwind_error_class_; }
+  static ClassPtr dyncalltypecheck_class() { return dyncalltypecheck_class_; }
+  static ClassPtr singletargetcache_class() { return singletargetcache_class_; }
+  static ClassPtr unlinkedcall_class() { return unlinkedcall_class_; }
+  static ClassPtr monomorphicsmiablecall_class() {
     return monomorphicsmiablecall_class_;
   }
-  static RawClass* icdata_class() { return icdata_class_; }
-  static RawClass* megamorphic_cache_class() {
-    return megamorphic_cache_class_;
-  }
-  static RawClass* subtypetestcache_class() { return subtypetestcache_class_; }
-  static RawClass* weak_serialization_reference_class() {
+  static ClassPtr icdata_class() { return icdata_class_; }
+  static ClassPtr megamorphic_cache_class() { return megamorphic_cache_class_; }
+  static ClassPtr subtypetestcache_class() { return subtypetestcache_class_; }
+  static ClassPtr weak_serialization_reference_class() {
     return weak_serialization_reference_class_;
   }
 
   // Initialize the VM isolate.
-  static void InitNull(Isolate* isolate);
+  static void InitNullAndBool(Isolate* isolate);
   static void Init(Isolate* isolate);
   static void InitVtables();
   static void FinishInit(Isolate* isolate);
   static void FinalizeVMIsolate(Isolate* isolate);
-  static void FinalizeReadOnlyObject(RawObject* object);
+  static void FinalizeReadOnlyObject(ObjectPtr object);
 
   static void Cleanup();
 
   // Initialize a new isolate either from a Kernel IR, from source, or from a
   // snapshot.
-  static RawError* Init(Isolate* isolate,
-                        const uint8_t* kernel_buffer,
-                        intptr_t kernel_buffer_size);
+  static ErrorPtr Init(Isolate* isolate,
+                       const uint8_t* kernel_buffer,
+                       intptr_t kernel_buffer_size);
 
   static void MakeUnusedSpaceTraversable(const Object& obj,
                                          intptr_t original_size,
                                          intptr_t used_size);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawObject));
+    return RoundedAllocationSize(sizeof(ObjectLayout));
   }
 
   template <class FakeObject>
@@ -603,21 +600,21 @@
   // Used for extracting the C++ vtable during bringup.
   Object() : raw_(null_) {}
 
-  uword raw_value() const { return reinterpret_cast<uword>(raw()); }
+  uword raw_value() const { return static_cast<uword>(raw()); }
 
-  inline void SetRaw(RawObject* value);
+  inline void SetRaw(ObjectPtr value);
   void CheckHandle() const;
 
   cpp_vtable vtable() const { return bit_copy<cpp_vtable>(*this); }
   void set_vtable(cpp_vtable value) { *vtable_address() = value; }
 
-  static RawObject* Allocate(intptr_t cls_id, intptr_t size, Heap::Space space);
+  static ObjectPtr Allocate(intptr_t cls_id, intptr_t size, Heap::Space space);
 
   static intptr_t RoundedAllocationSize(intptr_t size) {
     return Utils::RoundUp(size, kObjectAlignment);
   }
 
-  bool Contains(uword addr) const { return raw()->Contains(addr); }
+  bool Contains(uword addr) const { return raw()->ptr()->Contains(addr); }
 
   // Start of field mutator guards.
   //
@@ -627,21 +624,21 @@
 
   template <typename type, std::memory_order order = std::memory_order_relaxed>
   type LoadPointer(type const* addr) const {
-    return raw()->LoadPointer<type, order>(addr);
+    return raw()->ptr()->LoadPointer<type, order>(addr);
   }
 
   template <typename type, std::memory_order order = std::memory_order_relaxed>
   void StorePointer(type const* addr, type value) const {
-    raw()->StorePointer<type, order>(addr, value);
+    raw()->ptr()->StorePointer<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).
-  void StoreSmi(RawSmi* const* addr, RawSmi* value) const {
-    raw()->StoreSmi(addr, value);
+  void StoreSmi(SmiPtr const* addr, SmiPtr value) const {
+    raw()->ptr()->StoreSmi(addr, value);
   }
-  void StoreSmiIgnoreRace(RawSmi* const* addr, RawSmi* value) const {
-    raw()->StoreSmiIgnoreRace(addr, value);
+  void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) const {
+    raw()->ptr()->StoreSmiIgnoreRace(addr, value);
   }
 
   template <typename FieldType>
@@ -654,14 +651,14 @@
   template <typename FieldType, typename ValueType>
   void StoreNonPointer(const FieldType* addr, ValueType value) const {
     // Can't use Contains, as it uses tags_, which is set through this method.
-    ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw()));
+    ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(raw()));
     *const_cast<FieldType*>(addr) = value;
   }
 
   template <typename FieldType, typename ValueType, std::memory_order order>
   void StoreNonPointer(const FieldType* addr, ValueType value) const {
     // Can't use Contains, as it uses tags_, which is set through this method.
-    ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw()));
+    ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(raw()));
     reinterpret_cast<std::atomic<FieldType>*>(const_cast<FieldType*>(addr))
         ->store(value, order);
   }
@@ -692,10 +689,10 @@
 // instantiated with an object pointer type.
 #define STORE_NON_POINTER_ILLEGAL_TYPE(type)                                   \
   template <typename ValueType>                                                \
-  void StoreNonPointer(Raw##type* const* addr, ValueType value) const {        \
+  void StoreNonPointer(type##Ptr const* addr, ValueType value) const {         \
     UnimplementedMethod();                                                     \
   }                                                                            \
-  Raw##type** UnsafeMutableNonPointer(Raw##type* const* addr) const {          \
+  type##Ptr* UnsafeMutableNonPointer(type##Ptr const* addr) const {            \
     UnimplementedMethod();                                                     \
     return NULL;                                                               \
   }
@@ -705,11 +702,11 @@
 #undef STORE_NON_POINTER_ILLEGAL_TYPE
 
   // Allocate an object and copy the body of 'orig'.
-  static RawObject* Clone(const Object& orig, Heap::Space space);
+  static ObjectPtr Clone(const Object& orig, Heap::Space space);
 
   // End of field mutator guards.
 
-  RawObject* raw_;  // The raw object reference.
+  ObjectPtr raw_;  // The raw object reference.
 
  protected:
   void AddCommonObjectProperties(JSONObject* jsobj,
@@ -732,7 +729,7 @@
                                    const Library& lib);
 
   /* Initialize the handle based on the raw_ptr in the presence of null. */
-  static void initializeHandle(Object* obj, RawObject* raw_ptr) {
+  static void initializeHandle(Object* obj, ObjectPtr raw_ptr) {
     if (raw_ptr != Object::null()) {
       obj->SetRaw(raw_ptr);
     } else {
@@ -751,62 +748,61 @@
 
   // The static values below are singletons shared between the different
   // isolates. They are all allocated in the non-GC'd Dart::vm_isolate_.
-  static RawObject* null_;
+  static ObjectPtr null_;
+  static BoolPtr true_;
+  static BoolPtr false_;
 
-  static RawClass* class_class_;           // Class of the Class vm object.
-  static RawClass* dynamic_class_;         // Class of the 'dynamic' type.
-  static RawClass* void_class_;            // Class of the 'void' type.
-  static RawClass* never_class_;           // Class of the 'Never' type.
-  static RawClass* type_arguments_class_;  // Class of TypeArguments vm object.
-  static RawClass* patch_class_class_;     // Class of the PatchClass vm object.
-  static RawClass* function_class_;        // Class of the Function vm object.
-  static RawClass* closure_data_class_;    // Class of ClosureData vm obj.
-  static RawClass* signature_data_class_;  // Class of SignatureData vm obj.
-  static RawClass* redirection_data_class_;  // Class of RedirectionData vm obj.
-  static RawClass* ffi_trampoline_data_class_;  // Class of FfiTrampolineData
-                                                // vm obj.
-  static RawClass* field_class_;                // Class of the Field vm object.
-  static RawClass* script_class_;     // Class of the Script vm object.
-  static RawClass* library_class_;    // Class of the Library vm object.
-  static RawClass* namespace_class_;  // Class of Namespace vm object.
-  static RawClass* kernel_program_info_class_;  // Class of KernelProgramInfo vm
-                                                // object.
-  static RawClass* code_class_;                 // Class of the Code vm object.
-  static RawClass* bytecode_class_;      // Class of the Bytecode vm object.
-  static RawClass* instructions_class_;  // Class of the Instructions vm object.
-  static RawClass*
-      instructions_section_class_;       // Class of InstructionsSection.
-  static RawClass* object_pool_class_;   // Class of the ObjectPool vm object.
-  static RawClass* pc_descriptors_class_;   // Class of PcDescriptors vm object.
-  static RawClass* code_source_map_class_;  // Class of CodeSourceMap vm object.
-  static RawClass*
-      compressed_stackmaps_class_;             // Class of CompressedStackMaps.
-  static RawClass* var_descriptors_class_;     // Class of LocalVarDescriptors.
-  static RawClass* exception_handlers_class_;  // Class of ExceptionHandlers.
-  static RawClass* deopt_info_class_;          // Class of DeoptInfo.
-  static RawClass* context_class_;           // Class of the Context vm object.
-  static RawClass* context_scope_class_;     // Class of ContextScope vm object.
-  static RawClass* dyncalltypecheck_class_;  // Class of ParameterTypeCheck.
-  static RawClass* singletargetcache_class_;  // Class of SingleTargetCache.
-  static RawClass* unlinkedcall_class_;       // Class of UnlinkedCall.
-  static RawClass*
-      monomorphicsmiablecall_class_;  // Class of MonomorphicSmiableCall.
-  static RawClass* icdata_class_;     // Class of ICData.
-  static RawClass* megamorphic_cache_class_;    // Class of MegamorphiCache.
-  static RawClass* subtypetestcache_class_;     // Class of SubtypeTestCache.
-  static RawClass* api_error_class_;            // Class of ApiError.
-  static RawClass* language_error_class_;       // Class of LanguageError.
-  static RawClass* unhandled_exception_class_;  // Class of UnhandledException.
-  static RawClass* unwind_error_class_;         // Class of UnwindError.
+  static ClassPtr class_class_;           // Class of the Class vm object.
+  static ClassPtr dynamic_class_;         // Class of the 'dynamic' type.
+  static ClassPtr void_class_;            // Class of the 'void' type.
+  static ClassPtr type_arguments_class_;  // Class of TypeArguments vm object.
+  static ClassPtr patch_class_class_;     // Class of the PatchClass vm object.
+  static ClassPtr function_class_;        // Class of the Function vm object.
+  static ClassPtr closure_data_class_;    // Class of ClosureData vm obj.
+  static ClassPtr signature_data_class_;  // Class of SignatureData vm obj.
+  static ClassPtr redirection_data_class_;  // Class of RedirectionData vm obj.
+  static ClassPtr ffi_trampoline_data_class_;  // Class of FfiTrampolineData
+                                               // vm obj.
+  static ClassPtr field_class_;                // Class of the Field vm object.
+  static ClassPtr script_class_;               // Class of the Script vm object.
+  static ClassPtr library_class_;    // Class of the Library vm object.
+  static ClassPtr namespace_class_;  // Class of Namespace vm object.
+  static ClassPtr kernel_program_info_class_;  // Class of KernelProgramInfo vm
+                                               // object.
+  static ClassPtr code_class_;                 // Class of the Code vm object.
+  static ClassPtr bytecode_class_;      // Class of the Bytecode vm object.
+  static ClassPtr instructions_class_;  // Class of the Instructions vm object.
+  static ClassPtr instructions_section_class_;  // Class of InstructionsSection.
+  static ClassPtr object_pool_class_;      // Class of the ObjectPool vm object.
+  static ClassPtr pc_descriptors_class_;   // Class of PcDescriptors vm object.
+  static ClassPtr code_source_map_class_;  // Class of CodeSourceMap vm object.
+  static ClassPtr compressed_stackmaps_class_;  // Class of CompressedStackMaps.
+  static ClassPtr var_descriptors_class_;       // Class of LocalVarDescriptors.
+  static ClassPtr exception_handlers_class_;    // Class of ExceptionHandlers.
+  static ClassPtr deopt_info_class_;            // Class of DeoptInfo.
+  static ClassPtr context_class_;            // Class of the Context vm object.
+  static ClassPtr context_scope_class_;      // Class of ContextScope vm object.
+  static ClassPtr dyncalltypecheck_class_;   // Class of ParameterTypeCheck.
+  static ClassPtr singletargetcache_class_;  // Class of SingleTargetCache.
+  static ClassPtr unlinkedcall_class_;       // Class of UnlinkedCall.
+  static ClassPtr
+      monomorphicsmiablecall_class_;         // Class of MonomorphicSmiableCall.
+  static ClassPtr icdata_class_;             // Class of ICData.
+  static ClassPtr megamorphic_cache_class_;  // Class of MegamorphiCache.
+  static ClassPtr subtypetestcache_class_;   // Class of SubtypeTestCache.
+  static ClassPtr api_error_class_;          // Class of ApiError.
+  static ClassPtr language_error_class_;     // Class of LanguageError.
+  static ClassPtr unhandled_exception_class_;  // Class of UnhandledException.
+  static ClassPtr unwind_error_class_;         // Class of UnwindError.
   // Class of WeakSerializationReference.
-  static RawClass* weak_serialization_reference_class_;
+  static ClassPtr weak_serialization_reference_class_;
 
 #define DECLARE_SHARED_READONLY_HANDLE(Type, name) static Type* name##_;
   SHARED_READONLY_HANDLES_LIST(DECLARE_SHARED_READONLY_HANDLE)
 #undef DECLARE_SHARED_READONLY_HANDLE
 
   friend void ClassTable::Register(const Class& cls);
-  friend void RawObject::Validate(IsolateGroup* isolate_group) const;
+  friend void ObjectLayout::Validate(IsolateGroup* isolate_group) const;
   friend class Closure;
   friend class SnapshotReader;
   friend class InstanceDeserializationCluster;
@@ -827,17 +823,17 @@
 
 class PassiveObject : public Object {
  public:
-  void operator=(RawObject* value) { raw_ = value; }
-  void operator^=(RawObject* value) { raw_ = value; }
+  void operator=(ObjectPtr value) { raw_ = value; }
+  void operator^=(ObjectPtr value) { raw_ = value; }
 
-  static PassiveObject& Handle(Zone* zone, RawObject* raw_ptr) {
+  static PassiveObject& Handle(Zone* zone, ObjectPtr raw_ptr) {
     PassiveObject* obj =
         reinterpret_cast<PassiveObject*>(VMHandles::AllocateHandle(zone));
     obj->raw_ = raw_ptr;
     obj->set_vtable(0);
     return *obj;
   }
-  static PassiveObject& Handle(RawObject* raw_ptr) {
+  static PassiveObject& Handle(ObjectPtr raw_ptr) {
     return Handle(Thread::Current()->zone(), raw_ptr);
   }
   static PassiveObject& Handle() {
@@ -846,14 +842,14 @@
   static PassiveObject& Handle(Zone* zone) {
     return Handle(zone, Object::null());
   }
-  static PassiveObject& ZoneHandle(Zone* zone, RawObject* raw_ptr) {
+  static PassiveObject& ZoneHandle(Zone* zone, ObjectPtr raw_ptr) {
     PassiveObject* obj =
         reinterpret_cast<PassiveObject*>(VMHandles::AllocateZoneHandle(zone));
     obj->raw_ = raw_ptr;
     obj->set_vtable(0);
     return *obj;
   }
-  static PassiveObject& ZoneHandle(RawObject* raw_ptr) {
+  static PassiveObject& ZoneHandle(ObjectPtr raw_ptr) {
     return ZoneHandle(Thread::Current()->zone(), raw_ptr);
   }
   static PassiveObject& ZoneHandle() {
@@ -931,10 +927,10 @@
     return host_instance_size();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
   }
-  static intptr_t host_instance_size(RawClass* clazz) {
+  static intptr_t host_instance_size(ClassPtr clazz) {
     return (clazz->ptr()->host_instance_size_in_words_ * kWordSize);
   }
-  static intptr_t target_instance_size(RawClass* clazz) {
+  static intptr_t target_instance_size(ClassPtr clazz) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
     return (clazz->ptr()->target_instance_size_in_words_ *
             compiler::target::kWordSize);
@@ -1003,36 +999,36 @@
   }
 
   static bool is_valid_id(intptr_t value) {
-    return RawObject::ClassIdTag::is_valid(value);
+    return ObjectLayout::ClassIdTag::is_valid(value);
   }
   intptr_t id() const { return raw_ptr()->id_; }
   void set_id(intptr_t value) const {
     ASSERT(is_valid_id(value));
     StoreNonPointer(&raw_ptr()->id_, value);
   }
-  static intptr_t id_offset() { return OFFSET_OF(RawClass, id_); }
+  static intptr_t id_offset() { return OFFSET_OF(ClassLayout, id_); }
   static intptr_t num_type_arguments_offset() {
-    return OFFSET_OF(RawClass, num_type_arguments_);
+    return OFFSET_OF(ClassLayout, num_type_arguments_);
   }
 
-  RawString* Name() const;
-  RawString* ScrubbedName() const;
+  StringPtr Name() const;
+  StringPtr ScrubbedName() const;
   const char* ScrubbedNameCString() const;
-  RawString* UserVisibleName() const;
+  StringPtr UserVisibleName() const;
   const char* UserVisibleNameCString() const;
 
   // The mixin for this class if one exists. Otherwise, returns a raw pointer
   // to this class.
-  RawClass* Mixin() const;
+  ClassPtr Mixin() const;
 
   // The NNBD mode of the library declaring this class.
   NNBDMode nnbd_mode() const;
 
   bool IsInFullSnapshot() const;
 
-  virtual RawString* DictionaryName() const { return Name(); }
+  virtual StringPtr DictionaryName() const { return Name(); }
 
-  RawScript* script() const { return raw_ptr()->script_; }
+  ScriptPtr script() const { return raw_ptr()->script_; }
   void set_script(const Script& value) const;
 
   TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
@@ -1043,7 +1039,7 @@
   int32_t SourceFingerprint() const;
 
   // This class represents a typedef if the signature function is not null.
-  RawFunction* signature_function() const {
+  FunctionPtr signature_function() const {
     return raw_ptr()->signature_function_;
   }
   void set_signature_function(const Function& value) const;
@@ -1051,7 +1047,7 @@
   // Return the Type with type parameters declared by this class filled in with
   // dynamic and type parameters declared in superclasses filled in as declared
   // in superclass clauses.
-  RawAbstractType* RareType() const;
+  AbstractTypePtr RareType() const;
 
   // Return the Type whose arguments are the type parameters declared by this
   // class preceded by the type arguments declared for superclasses, etc.
@@ -1061,18 +1057,18 @@
   // C.DeclarationType() --> C [R, int, R]
   // The declaration type's nullability is either legacy or non-nullable when
   // the non-nullable experiment is enabled.
-  RawType* DeclarationType() const;
+  TypePtr DeclarationType() const;
 
   static intptr_t declaration_type_offset() {
-    return OFFSET_OF(RawClass, declaration_type_);
+    return OFFSET_OF(ClassLayout, declaration_type_);
   }
 
-  RawLibrary* library() const { return raw_ptr()->library_; }
+  LibraryPtr library() const { return raw_ptr()->library_; }
   void set_library(const Library& value) const;
 
   // The type parameters (and their bounds) are specified as an array of
   // TypeParameter.
-  RawTypeArguments* type_parameters() const {
+  TypeArgumentsPtr type_parameters() const {
     ASSERT(is_declaration_loaded());
     return raw_ptr()->type_parameters_;
   }
@@ -1082,12 +1078,12 @@
     return NumTypeParameters(Thread::Current());
   }
   static intptr_t type_parameters_offset() {
-    return OFFSET_OF(RawClass, type_parameters_);
+    return OFFSET_OF(ClassLayout, type_parameters_);
   }
 
   // Return a TypeParameter if the type_name is a type parameter of this class.
   // Return null otherwise.
-  RawTypeParameter* LookupTypeParameter(const String& type_name) const;
+  TypeParameterPtr LookupTypeParameter(const String& type_name) const;
 
   // The type argument vector is flattened and includes the type arguments of
   // the super class.
@@ -1147,49 +1143,49 @@
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
   }
   static intptr_t host_type_arguments_field_offset_in_words_offset() {
-    return OFFSET_OF(RawClass, host_type_arguments_field_offset_in_words_);
+    return OFFSET_OF(ClassLayout, host_type_arguments_field_offset_in_words_);
   }
 
   static intptr_t target_type_arguments_field_offset_in_words_offset() {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-    return OFFSET_OF(RawClass, target_type_arguments_field_offset_in_words_);
+    return OFFSET_OF(ClassLayout, target_type_arguments_field_offset_in_words_);
 #else
     return host_type_arguments_field_offset_in_words_offset();
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
   }
 
   // The super type of this class, Object type if not explicitly specified.
-  RawAbstractType* super_type() const {
+  AbstractTypePtr super_type() const {
     ASSERT(is_declaration_loaded());
     return raw_ptr()->super_type_;
   }
   void set_super_type(const AbstractType& value) const;
   static intptr_t super_type_offset() {
-    return OFFSET_OF(RawClass, super_type_);
+    return OFFSET_OF(ClassLayout, super_type_);
   }
 
   // Asserts that the class of the super type has been resolved.
   // |original_classes| only has an effect when reloading. If true and we
   // are reloading, it will prefer the original classes to the replacement
   // classes.
-  RawClass* SuperClass(bool original_classes = false) const;
+  ClassPtr SuperClass(bool original_classes = false) const;
 
   // Interfaces is an array of Types.
-  RawArray* interfaces() const {
+  ArrayPtr interfaces() const {
     ASSERT(is_declaration_loaded());
     return raw_ptr()->interfaces_;
   }
   void set_interfaces(const Array& value) const;
 
   // Returns the list of classes directly implementing this class.
-  RawGrowableObjectArray* direct_implementors() const {
+  GrowableObjectArrayPtr direct_implementors() const {
     return raw_ptr()->direct_implementors_;
   }
   void AddDirectImplementor(const Class& subclass, bool is_mixin) const;
   void ClearDirectImplementors() const;
 
   // Returns the list of classes having this class as direct superclass.
-  RawGrowableObjectArray* direct_subclasses() const {
+  GrowableObjectArrayPtr direct_subclasses() const {
     return raw_ptr()->direct_subclasses_;
   }
   void AddDirectSubclass(const Class& subclass) const;
@@ -1221,7 +1217,7 @@
 
   // Check if this class represents the 'Closure' class.
   bool IsClosureClass() const { return id() == kClosureCid; }
-  static bool IsClosureClass(RawClass* cls) {
+  static bool IsClosureClass(ClassPtr cls) {
     NoSafepointScope no_safepoint;
     return cls->ptr()->id_ == kClosureCid;
   }
@@ -1229,9 +1225,9 @@
   // Check if this class represents a typedef class.
   bool IsTypedefClass() const { return signature_function() != Object::null(); }
 
-  static bool IsInFullSnapshot(RawClass* cls) {
+  static bool IsInFullSnapshot(ClassPtr cls) {
     NoSafepointScope no_safepoint;
-    return RawLibrary::InFullSnapshotBit::decode(
+    return LibraryLayout::InFullSnapshotBit::decode(
         cls->ptr()->library_->ptr()->flags_);
   }
 
@@ -1249,10 +1245,10 @@
   bool IsPrivate() const;
 
   DART_WARN_UNUSED_RESULT
-  RawError* VerifyEntryPoint() const;
+  ErrorPtr VerifyEntryPoint() const;
 
   // Returns an array of instance and static fields defined by this class.
-  RawArray* fields() const { return raw_ptr()->fields_; }
+  ArrayPtr fields() const { return raw_ptr()->fields_; }
   void SetFields(const Array& value) const;
   void AddField(const Field& field) const;
   void AddFields(const GrowableArray<const Field*>& fields) const;
@@ -1267,56 +1263,58 @@
   // |original_classes| only has an effect when reloading. If true and we
   // are reloading, it will prefer the original classes to the replacement
   // classes.
-  RawArray* OffsetToFieldMap(bool original_classes = false) const;
+  ArrayPtr OffsetToFieldMap(bool original_classes = false) const;
 
   // Returns true if non-static fields are defined.
   bool HasInstanceFields() const;
 
   // TODO(koda): Unite w/ hash table.
-  RawArray* functions() const { return raw_ptr()->functions_; }
+  ArrayPtr functions() const { return raw_ptr()->functions_; }
   void SetFunctions(const Array& value) const;
   void AddFunction(const Function& function) const;
   void RemoveFunction(const Function& function) const;
-  RawFunction* FunctionFromIndex(intptr_t idx) const;
+  FunctionPtr FunctionFromIndex(intptr_t idx) const;
   intptr_t FindImplicitClosureFunctionIndex(const Function& needle) const;
-  RawFunction* ImplicitClosureFunctionFromIndex(intptr_t idx) const;
+  FunctionPtr ImplicitClosureFunctionFromIndex(intptr_t idx) const;
 
-  RawFunction* LookupDynamicFunction(const String& name) const;
-  RawFunction* LookupDynamicFunctionAllowAbstract(const String& name) const;
-  RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const;
-  RawFunction* LookupStaticFunction(const String& name) const;
-  RawFunction* LookupStaticFunctionAllowPrivate(const String& name) const;
-  RawFunction* LookupConstructor(const String& name) const;
-  RawFunction* LookupConstructorAllowPrivate(const String& name) const;
-  RawFunction* LookupFactory(const String& name) const;
-  RawFunction* LookupFactoryAllowPrivate(const String& name) const;
-  RawFunction* LookupFunction(const String& name) const;
-  RawFunction* LookupFunctionAllowPrivate(const String& name) const;
-  RawFunction* LookupGetterFunction(const String& name) const;
-  RawFunction* LookupSetterFunction(const String& name) const;
-  RawField* LookupInstanceField(const String& name) const;
-  RawField* LookupStaticField(const String& name) const;
-  RawField* LookupField(const String& name) const;
-  RawField* LookupFieldAllowPrivate(const String& name,
-                                    bool instance_only = false) const;
-  RawField* LookupInstanceFieldAllowPrivate(const String& name) const;
-  RawField* LookupStaticFieldAllowPrivate(const String& name) const;
+  FunctionPtr LookupDynamicFunction(const String& name) const;
+  FunctionPtr LookupDynamicFunctionAllowAbstract(const String& name) const;
+  FunctionPtr LookupDynamicFunctionAllowPrivate(const String& name) const;
+  FunctionPtr LookupStaticFunction(const String& name) const;
+  FunctionPtr LookupStaticFunctionAllowPrivate(const String& name) const;
+  FunctionPtr LookupConstructor(const String& name) const;
+  FunctionPtr LookupConstructorAllowPrivate(const String& name) const;
+  FunctionPtr LookupFactory(const String& name) const;
+  FunctionPtr LookupFactoryAllowPrivate(const String& name) const;
+  FunctionPtr LookupFunction(const String& name) const;
+  FunctionPtr LookupFunctionAllowPrivate(const String& name) const;
+  FunctionPtr LookupGetterFunction(const String& name) const;
+  FunctionPtr LookupSetterFunction(const String& name) const;
+  FieldPtr LookupInstanceField(const String& name) const;
+  FieldPtr LookupStaticField(const String& name) const;
+  FieldPtr LookupField(const String& name) const;
+  FieldPtr LookupFieldAllowPrivate(const String& name,
+                                   bool instance_only = false) const;
+  FieldPtr LookupInstanceFieldAllowPrivate(const String& name) const;
+  FieldPtr LookupStaticFieldAllowPrivate(const String& name) const;
 
-  RawDouble* LookupCanonicalDouble(Zone* zone, double value) const;
-  RawMint* LookupCanonicalMint(Zone* zone, int64_t value) const;
+  DoublePtr LookupCanonicalDouble(Zone* zone, double value) const;
+  MintPtr LookupCanonicalMint(Zone* zone, int64_t value) const;
 
   // The methods above are more efficient than this generic one.
-  RawInstance* LookupCanonicalInstance(Zone* zone, const Instance& value) const;
+  InstancePtr LookupCanonicalInstance(Zone* zone, const Instance& value) const;
 
-  RawInstance* InsertCanonicalConstant(Zone* zone,
-                                       const Instance& constant) const;
+  InstancePtr InsertCanonicalConstant(Zone* zone,
+                                      const Instance& constant) const;
   void InsertCanonicalDouble(Zone* zone, const Double& constant) const;
   void InsertCanonicalMint(Zone* zone, const Mint& constant) const;
 
   void RehashConstants(Zone* zone) const;
 
+  bool RequireLegacyErasureOfConstants(Zone* zone) const;
+
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawClass));
+    return RoundedAllocationSize(sizeof(ClassLayout));
   }
 
   bool is_implemented() const {
@@ -1329,17 +1327,17 @@
   }
   void set_is_abstract() const;
 
-  RawClass::ClassLoadingState class_loading_state() const {
+  ClassLayout::ClassLoadingState class_loading_state() const {
     return ClassLoadingBits::decode(raw_ptr()->state_bits_);
   }
 
   bool is_declaration_loaded() const {
-    return class_loading_state() >= RawClass::kDeclarationLoaded;
+    return class_loading_state() >= ClassLayout::kDeclarationLoaded;
   }
   void set_is_declaration_loaded() const;
 
   bool is_type_finalized() const {
-    return class_loading_state() >= RawClass::kTypeFinalized;
+    return class_loading_state() >= ClassLayout::kTypeFinalized;
   }
   void set_is_type_finalized() const;
 
@@ -1356,13 +1354,13 @@
 
   bool is_finalized() const {
     return ClassFinalizedBits::decode(raw_ptr()->state_bits_) ==
-           RawClass::kFinalized;
+           ClassLayout::kFinalized;
   }
   void set_is_finalized() const;
 
   bool is_prefinalized() const {
     return ClassFinalizedBits::decode(raw_ptr()->state_bits_) ==
-           RawClass::kPreFinalized;
+           ClassLayout::kPreFinalized;
   }
 
   void set_is_prefinalized() const;
@@ -1399,18 +1397,18 @@
     StoreNonPointer(&raw_ptr()->num_native_fields_, value);
   }
 
-  RawCode* allocation_stub() const { return raw_ptr()->allocation_stub_; }
+  CodePtr allocation_stub() const { return raw_ptr()->allocation_stub_; }
   void set_allocation_stub(const Code& value) const;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   intptr_t binary_declaration_offset() const {
-    return RawClass::BinaryDeclarationOffset::decode(
+    return ClassLayout::BinaryDeclarationOffset::decode(
         raw_ptr()->binary_declaration_);
   }
   void set_binary_declaration_offset(intptr_t value) const {
     ASSERT(value >= 0);
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawClass::BinaryDeclarationOffset::update(
+                    ClassLayout::BinaryDeclarationOffset::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -1455,7 +1453,7 @@
 #if defined(DART_PRECOMPILED_RUNTIME)
     return false;
 #else
-    return RawClass::IsDeclaredInBytecode::decode(
+    return ClassLayout::IsDeclaredInBytecode::decode(
         raw_ptr()->binary_declaration_);
 #endif
   }
@@ -1463,46 +1461,46 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   void set_is_declared_in_bytecode(bool value) const {
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawClass::IsDeclaredInBytecode::update(
+                    ClassLayout::IsDeclaredInBytecode::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   void DisableAllocationStub() const;
 
-  RawArray* constants() const;
+  ArrayPtr constants() const;
   void set_constants(const Array& value) const;
 
   intptr_t FindInvocationDispatcherFunctionIndex(const Function& needle) const;
-  RawFunction* InvocationDispatcherFunctionFromIndex(intptr_t idx) const;
+  FunctionPtr InvocationDispatcherFunctionFromIndex(intptr_t idx) const;
 
-  RawFunction* GetInvocationDispatcher(const String& target_name,
-                                       const Array& args_desc,
-                                       RawFunction::Kind kind,
-                                       bool create_if_absent) const;
+  FunctionPtr GetInvocationDispatcher(const String& target_name,
+                                      const Array& args_desc,
+                                      FunctionLayout::Kind kind,
+                                      bool create_if_absent) const;
 
   void Finalize() const;
 
-  RawObject* Invoke(const String& selector,
-                    const Array& arguments,
-                    const Array& argument_names,
-                    bool respect_reflectable = true,
-                    bool check_is_entrypoint = false) const;
-  RawObject* InvokeGetter(const String& selector,
-                          bool throw_nsm_if_absent,
-                          bool respect_reflectable = true,
-                          bool check_is_entrypoint = false) const;
-  RawObject* InvokeSetter(const String& selector,
-                          const Instance& argument,
-                          bool respect_reflectable = true,
-                          bool check_is_entrypoint = false) const;
+  ObjectPtr Invoke(const String& selector,
+                   const Array& arguments,
+                   const Array& argument_names,
+                   bool respect_reflectable = true,
+                   bool check_is_entrypoint = false) const;
+  ObjectPtr InvokeGetter(const String& selector,
+                         bool throw_nsm_if_absent,
+                         bool respect_reflectable = true,
+                         bool check_is_entrypoint = false) const;
+  ObjectPtr InvokeSetter(const String& selector,
+                         const Instance& argument,
+                         bool respect_reflectable = true,
+                         bool check_is_entrypoint = false) const;
 
   // Evaluate the given expression as if it appeared in a static method of this
   // class and return the resulting value, or an error object if evaluating the
   // expression fails. The method has the formal (type) parameters given in
   // (type_)param_names, and is invoked with the (type)argument values given in
   // (type_)param_values.
-  RawObject* EvaluateCompiledExpression(
+  ObjectPtr EvaluateCompiledExpression(
       const ExternalTypedData& kernel_buffer,
       const Array& type_definitions,
       const Array& param_values,
@@ -1512,37 +1510,37 @@
   // number of type arguments) if it is not loaded yet.
   void EnsureDeclarationLoaded() const;
 
-  RawError* EnsureIsFinalized(Thread* thread) const;
+  ErrorPtr EnsureIsFinalized(Thread* thread) const;
 
   // Allocate a class used for VM internal objects.
   template <class FakeObject, class TargetFakeObject>
-  static RawClass* New(Isolate* isolate, bool register_class = true);
+  static ClassPtr New(Isolate* isolate, bool register_class = true);
 
   // Allocate instance classes.
-  static RawClass* New(const Library& lib,
-                       const String& name,
-                       const Script& script,
-                       TokenPosition token_pos,
-                       bool register_class = true);
-  static RawClass* NewNativeWrapper(const Library& library,
-                                    const String& name,
-                                    int num_fields);
+  static ClassPtr New(const Library& lib,
+                      const String& name,
+                      const Script& script,
+                      TokenPosition token_pos,
+                      bool register_class = true);
+  static ClassPtr NewNativeWrapper(const Library& library,
+                                   const String& name,
+                                   int num_fields);
 
   // Allocate the raw string classes.
-  static RawClass* NewStringClass(intptr_t class_id, Isolate* isolate);
+  static ClassPtr NewStringClass(intptr_t class_id, Isolate* isolate);
 
   // Allocate the raw TypedData classes.
-  static RawClass* NewTypedDataClass(intptr_t class_id, Isolate* isolate);
+  static ClassPtr NewTypedDataClass(intptr_t class_id, Isolate* isolate);
 
   // Allocate the raw TypedDataView/ByteDataView classes.
-  static RawClass* NewTypedDataViewClass(intptr_t class_id, Isolate* isolate);
+  static ClassPtr NewTypedDataViewClass(intptr_t class_id, Isolate* isolate);
 
   // Allocate the raw ExternalTypedData classes.
-  static RawClass* NewExternalTypedDataClass(intptr_t class_id,
-                                             Isolate* isolate);
+  static ClassPtr NewExternalTypedDataClass(intptr_t class_id,
+                                            Isolate* isolate);
 
   // Allocate the raw Pointer classes.
-  static RawClass* NewPointerClass(intptr_t class_id, Isolate* isolate);
+  static ClassPtr NewPointerClass(intptr_t class_id, Isolate* isolate);
 
   // Register code that has used CHA for optimization.
   // TODO(srdjan): Also register kind of CHA optimization (e.g.: leaf class,
@@ -1558,7 +1556,7 @@
   // Return the list of code objects that were compiled using CHA of this class.
   // These code objects will be invalidated if new subclasses of this class
   // are finalized.
-  RawArray* dependent_code() const { return raw_ptr()->dependent_code_; }
+  ArrayPtr dependent_code() const { return raw_ptr()->dependent_code_; }
   void set_dependent_code(const Array& array) const;
 
   bool TraceAllocation(Isolate* isolate) const;
@@ -1580,11 +1578,11 @@
                                const Array& args_desc,
                                const Function& dispatcher) const;
 
-  static int32_t host_instance_size_in_words(const RawClass* cls) {
+  static int32_t host_instance_size_in_words(const ClassPtr cls) {
     return cls->ptr()->host_instance_size_in_words_;
   }
 
-  static int32_t target_instance_size_in_words(const RawClass* cls) {
+  static int32_t target_instance_size_in_words(const ClassPtr cls) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
     return cls->ptr()->target_instance_size_in_words_;
 #else
@@ -1592,11 +1590,11 @@
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
   }
 
-  static int32_t host_next_field_offset_in_words(const RawClass* cls) {
+  static int32_t host_next_field_offset_in_words(const ClassPtr cls) {
     return cls->ptr()->host_next_field_offset_in_words_;
   }
 
-  static int32_t target_next_field_offset_in_words(const RawClass* cls) {
+  static int32_t target_next_field_offset_in_words(const ClassPtr cls) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
     return cls->ptr()->target_next_field_offset_in_words_;
 #else
@@ -1604,13 +1602,12 @@
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
   }
 
-  static int32_t host_type_arguments_field_offset_in_words(
-      const RawClass* cls) {
+  static int32_t host_type_arguments_field_offset_in_words(const ClassPtr cls) {
     return cls->ptr()->host_type_arguments_field_offset_in_words_;
   }
 
   static int32_t target_type_arguments_field_offset_in_words(
-      const RawClass* cls) {
+      const ClassPtr cls) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
     return cls->ptr()->target_type_arguments_field_offset_in_words_;
 #else
@@ -1619,7 +1616,7 @@
   }
 
  private:
-  RawType* declaration_type() const { return raw_ptr()->declaration_type_; }
+  TypePtr declaration_type() const { return raw_ptr()->declaration_type_; }
 
   // Caches the declaration type of this class.
   void set_declaration_type(const Type& type) const;
@@ -1633,7 +1630,7 @@
   bool RequiresInstanceMorphing(const Class& replacement) const;
 
   template <class FakeInstance, class TargetFakeInstance>
-  static RawClass* NewCommon(intptr_t index);
+  static ClassPtr NewCommon(intptr_t index);
 
   enum MemberKind {
     kAny = 0,
@@ -1665,11 +1662,11 @@
   class ConstBit : public BitField<uint32_t, bool, kConstBit, 1> {};
   class ImplementedBit : public BitField<uint32_t, bool, kImplementedBit, 1> {};
   class ClassFinalizedBits : public BitField<uint32_t,
-                                             RawClass::ClassFinalizedState,
+                                             ClassLayout::ClassFinalizedState,
                                              kClassFinalizedPos,
                                              kClassFinalizedSize> {};
   class ClassLoadingBits : public BitField<uint32_t,
-                                           RawClass::ClassLoadingState,
+                                           ClassLayout::ClassLoadingState,
                                            kClassLoadingPos,
                                            kClassLoadingSize> {};
   class AbstractBit : public BitField<uint32_t, bool, kAbstractBit, 1> {};
@@ -1690,11 +1687,11 @@
   const char* GenerateUserVisibleName() const;
   void set_state_bits(intptr_t bits) const;
 
-  RawArray* invocation_dispatcher_cache() const;
+  ArrayPtr invocation_dispatcher_cache() const;
   void set_invocation_dispatcher_cache(const Array& cache) const;
-  RawFunction* CreateInvocationDispatcher(const String& target_name,
-                                          const Array& args_desc,
-                                          RawFunction::Kind kind) const;
+  FunctionPtr CreateInvocationDispatcher(const String& target_name,
+                                         const Array& args_desc,
+                                         FunctionLayout::Kind kind) const;
 
   // Returns the bitmap of unboxed fields
   UnboxedFieldBitmap CalculateFieldOffsets() const;
@@ -1724,25 +1721,25 @@
   // Assigns empty array to all raw class array fields.
   void InitEmptyFields();
 
-  static RawFunction* CheckFunctionType(const Function& func, MemberKind kind);
-  RawFunction* LookupFunction(const String& name, MemberKind kind) const;
-  RawFunction* LookupFunctionAllowPrivate(const String& name,
-                                          MemberKind kind) const;
-  RawField* LookupField(const String& name, MemberKind kind) const;
+  static FunctionPtr CheckFunctionType(const Function& func, MemberKind kind);
+  FunctionPtr LookupFunction(const String& name, MemberKind kind) const;
+  FunctionPtr LookupFunctionAllowPrivate(const String& name,
+                                         MemberKind kind) const;
+  FieldPtr LookupField(const String& name, MemberKind kind) const;
 
-  RawFunction* LookupAccessorFunction(const char* prefix,
-                                      intptr_t prefix_length,
-                                      const String& name) const;
+  FunctionPtr LookupAccessorFunction(const char* prefix,
+                                     intptr_t prefix_length,
+                                     const String& name) const;
 
   // Allocate an instance class which has a VM implementation.
   template <class FakeInstance, class TargetFakeInstance>
-  static RawClass* New(intptr_t id,
-                       Isolate* isolate,
-                       bool register_class = true,
-                       bool is_abstract = false);
+  static ClassPtr New(intptr_t id,
+                      Isolate* isolate,
+                      bool register_class = true,
+                      bool is_abstract = false);
 
   // Helper that calls 'Class::New<Instance>(kIllegalCid)'.
-  static RawClass* NewInstanceClass();
+  static ClassPtr NewInstanceClass();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Class, Object);
   friend class AbstractType;
@@ -1751,7 +1748,7 @@
   friend class Type;
   friend class InterpreterHelpers;
   friend class Intrinsifier;
-  friend class ClassFunctionVisitor;
+  friend class ProgramWalker;
 };
 
 // Classification of type genericity according to type parameter owners.
@@ -1763,10 +1760,10 @@
 
 class PatchClass : public Object {
  public:
-  RawClass* patched_class() const { return raw_ptr()->patched_class_; }
-  RawClass* origin_class() const { return raw_ptr()->origin_class_; }
-  RawScript* script() const { return raw_ptr()->script_; }
-  RawExternalTypedData* library_kernel_data() const {
+  ClassPtr patched_class() const { return raw_ptr()->patched_class_; }
+  ClassPtr origin_class() const { return raw_ptr()->origin_class_; }
+  ScriptPtr script() const { return raw_ptr()->script_; }
+  ExternalTypedDataPtr library_kernel_data() const {
     return raw_ptr()->library_kernel_data_;
   }
   void set_library_kernel_data(const ExternalTypedData& data) const;
@@ -1784,24 +1781,24 @@
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawPatchClass));
+    return RoundedAllocationSize(sizeof(PatchClassLayout));
   }
-  static bool IsInFullSnapshot(RawPatchClass* cls) {
+  static bool IsInFullSnapshot(PatchClassPtr cls) {
     NoSafepointScope no_safepoint;
     return Class::IsInFullSnapshot(cls->ptr()->patched_class_);
   }
 
-  static RawPatchClass* New(const Class& patched_class,
-                            const Class& origin_class);
+  static PatchClassPtr New(const Class& patched_class,
+                           const Class& origin_class);
 
-  static RawPatchClass* New(const Class& patched_class, const Script& source);
+  static PatchClassPtr New(const Class& patched_class, const Script& source);
 
  private:
   void set_patched_class(const Class& value) const;
   void set_origin_class(const Class& value) const;
   void set_script(const Script& value) const;
 
-  static RawPatchClass* New();
+  static PatchClassPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(PatchClass, Object);
   friend class Class;
@@ -1817,25 +1814,25 @@
 
   // The type parameter to whose bound needs to be checked, or null if this is
   // an ordinary parameter check.
-  RawAbstractType* param() const { return raw_ptr()->param_; }
+  AbstractTypePtr param() const { return raw_ptr()->param_; }
   void set_param(const AbstractType& t) const;
 
   // FP[index] assignable to type, OR param is subtype of bound.
-  RawAbstractType* type_or_bound() const { return raw_ptr()->type_or_bound_; }
+  AbstractTypePtr type_or_bound() const { return raw_ptr()->type_or_bound_; }
   void set_type_or_bound(const AbstractType& t) const;
 
   // The parameter or type parameter's name to use in an error message.
-  RawString* name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name_; }
   void set_name(const String& n) const;
 
-  RawSubtypeTestCache* cache() const { return raw_ptr()->cache_; }
+  SubtypeTestCachePtr cache() const { return raw_ptr()->cache_; }
   void set_cache(const SubtypeTestCache& c) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawParameterTypeCheck));
+    return RoundedAllocationSize(sizeof(ParameterTypeCheckLayout));
   }
 
-  static RawParameterTypeCheck* New();
+  static ParameterTypeCheckPtr New();
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck, Object);
@@ -1844,10 +1841,10 @@
 
 class SingleTargetCache : public Object {
  public:
-  RawCode* target() const { return raw_ptr()->target_; }
+  CodePtr target() const { return raw_ptr()->target_; }
   void set_target(const Code& target) const;
   static intptr_t target_offset() {
-    return OFFSET_OF(RawSingleTargetCache, target_);
+    return OFFSET_OF(SingleTargetCacheLayout, target_);
   }
 
 #define DEFINE_NON_POINTER_FIELD_ACCESSORS(type, name)                         \
@@ -1856,7 +1853,7 @@
     StoreNonPointer(&raw_ptr()->name##_, value);                               \
   }                                                                            \
   static intptr_t name##_offset() {                                            \
-    return OFFSET_OF(RawSingleTargetCache, name##_);                           \
+    return OFFSET_OF(SingleTargetCacheLayout, name##_);                        \
   }
 
   DEFINE_NON_POINTER_FIELD_ACCESSORS(uword, entry_point);
@@ -1865,10 +1862,10 @@
 #undef DEFINE_NON_POINTER_FIELD_ACCESSORS
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawSingleTargetCache));
+    return RoundedAllocationSize(sizeof(SingleTargetCacheLayout));
   }
 
-  static RawSingleTargetCache* New();
+  static SingleTargetCachePtr New();
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache, Object);
@@ -1877,26 +1874,26 @@
 
 class MonomorphicSmiableCall : public Object {
  public:
-  RawCode* target() const { return raw_ptr()->target_; }
+  CodePtr target() const { return raw_ptr()->target_; }
   classid_t expected_cid() const { return raw_ptr()->expected_cid_; }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawMonomorphicSmiableCall));
+    return RoundedAllocationSize(sizeof(MonomorphicSmiableCallLayout));
   }
 
-  static RawMonomorphicSmiableCall* New(classid_t expected_cid,
-                                        const Code& target);
+  static MonomorphicSmiableCallPtr New(classid_t expected_cid,
+                                       const Code& target);
 
   static intptr_t expected_cid_offset() {
-    return OFFSET_OF(RawMonomorphicSmiableCall, expected_cid_);
+    return OFFSET_OF(MonomorphicSmiableCallLayout, expected_cid_);
   }
 
   static intptr_t target_offset() {
-    return OFFSET_OF(RawMonomorphicSmiableCall, target_);
+    return OFFSET_OF(MonomorphicSmiableCallLayout, target_);
   }
 
   static intptr_t entrypoint_offset() {
-    return OFFSET_OF(RawMonomorphicSmiableCall, entrypoint_);
+    return OFFSET_OF(MonomorphicSmiableCallLayout, entrypoint_);
   }
 
  private:
@@ -1906,9 +1903,9 @@
 
 class UnlinkedCall : public Object {
  public:
-  RawString* target_name() const { return raw_ptr()->target_name_; }
+  StringPtr target_name() const { return raw_ptr()->target_name_; }
   void set_target_name(const String& target_name) const;
-  RawArray* args_descriptor() const { return raw_ptr()->args_descriptor_; }
+  ArrayPtr args_descriptor() const { return raw_ptr()->args_descriptor_; }
   void set_args_descriptor(const Array& args_descriptor) const;
 
   bool can_patch_to_monomorphic() const {
@@ -1917,38 +1914,59 @@
   void set_can_patch_to_monomorphic(bool value) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawUnlinkedCall));
+    return RoundedAllocationSize(sizeof(UnlinkedCallLayout));
   }
 
   intptr_t Hashcode() const;
   bool Equals(const UnlinkedCall& other) const;
 
-  static RawUnlinkedCall* New();
+  static UnlinkedCallPtr New();
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall, Object);
   friend class Class;
 };
 
+class CallSiteData : public Object {
+ public:
+  StringPtr target_name() const { return raw_ptr()->target_name_; }
+
+  ArrayPtr arguments_descriptor() const { return raw_ptr()->args_descriptor_; }
+
+  static intptr_t target_name_offset() {
+    return OFFSET_OF(CallSiteDataLayout, target_name_);
+  }
+
+  static intptr_t arguments_descriptor_offset() {
+    return OFFSET_OF(CallSiteDataLayout, args_descriptor_);
+  }
+
+ private:
+  void set_target_name(const String& value) const;
+
+  void set_arguments_descriptor(const Array& value) const;
+
+  HEAP_OBJECT_IMPLEMENTATION(CallSiteData, Object)
+
+  friend class ICData;
+  friend class MegamorphicCache;
+};
+
 // Object holding information about an IC: test classes and their
 // corresponding targets. The owner of the ICData can be either the function
 // or the original ICData object. In case of background compilation we
 // copy the ICData in a child object, thus freezing it during background
 // compilation. Code may contain only original ICData objects.
-class ICData : public Object {
+class ICData : public CallSiteData {
  public:
-  RawFunction* Owner() const;
+  FunctionPtr Owner() const;
 
-  RawICData* Original() const;
+  ICDataPtr Original() const;
 
   void SetOriginal(const ICData& value) const;
 
   bool IsOriginal() const { return Original() == this->raw(); }
 
-  RawString* target_name() const { return raw_ptr()->target_name_; }
-
-  RawArray* arguments_descriptor() const { return raw_ptr()->args_descriptor_; }
-
   intptr_t NumArgsTested() const;
 
   intptr_t TypeArgsLen() const;
@@ -1973,7 +1991,7 @@
   bool IsImmutable() const;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  RawAbstractType* receivers_static_type() const {
+  AbstractTypePtr receivers_static_type() const {
     return raw_ptr()->receivers_static_type_;
   }
   void SetReceiversStaticType(const AbstractType& type) const;
@@ -2083,15 +2101,11 @@
   bool NumberOfChecksIs(intptr_t n) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawICData));
-  }
-
-  static intptr_t target_name_offset() {
-    return OFFSET_OF(RawICData, target_name_);
+    return RoundedAllocationSize(sizeof(ICDataLayout));
   }
 
   static intptr_t state_bits_offset() {
-    return OFFSET_OF(RawICData, state_bits_);
+    return OFFSET_OF(ICDataLayout, state_bits_);
   }
 
   static intptr_t NumArgsTestedShift() { return kNumArgsTestedPos; }
@@ -2100,17 +2114,13 @@
     return ((1 << kNumArgsTestedSize) - 1) << kNumArgsTestedPos;
   }
 
-  static intptr_t arguments_descriptor_offset() {
-    return OFFSET_OF(RawICData, args_descriptor_);
-  }
+  static intptr_t entries_offset() { return OFFSET_OF(ICDataLayout, entries_); }
 
-  static intptr_t entries_offset() { return OFFSET_OF(RawICData, entries_); }
-
-  static intptr_t owner_offset() { return OFFSET_OF(RawICData, owner_); }
+  static intptr_t owner_offset() { return OFFSET_OF(ICDataLayout, owner_); }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   static intptr_t receivers_static_type_offset() {
-    return OFFSET_OF(RawICData, receivers_static_type_);
+    return OFFSET_OF(ICDataLayout, receivers_static_type_);
   }
 #endif
 
@@ -2170,9 +2180,9 @@
   intptr_t GetReceiverClassIdAt(intptr_t index) const;
   intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
 
-  RawFunction* GetTargetAt(intptr_t index) const;
+  FunctionPtr GetTargetAt(intptr_t index) const;
 
-  RawObject* GetTargetOrCodeAt(intptr_t index) const;
+  ObjectPtr GetTargetOrCodeAt(intptr_t index) const;
   void SetCodeAt(intptr_t index, const Code& value) const;
   void SetEntryPointAt(intptr_t index, const Smi& value) const;
 
@@ -2184,20 +2194,18 @@
   // Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
   // returns a new ICData object containing only unique arg_nr checks.
   // Returns only used entries.
-  RawICData* AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
-  RawICData* AsUnaryClassChecks() const {
-    return AsUnaryClassChecksForArgNr(0);
-  }
-  RawICData* AsUnaryClassChecksForCid(intptr_t cid,
-                                      const Function& target) const;
+  ICDataPtr AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
+  ICDataPtr AsUnaryClassChecks() const { return AsUnaryClassChecksForArgNr(0); }
+  ICDataPtr AsUnaryClassChecksForCid(intptr_t cid,
+                                     const Function& target) const;
 
   // Returns ICData with aggregated receiver count, sorted by highest count.
   // Smi not first!! (the convention for ICData used in code generation is that
   // Smi check is first)
   // Used for printing and optimizations.
-  RawICData* AsUnaryClassChecksSortedByCount() const;
+  ICDataPtr AsUnaryClassChecksSortedByCount() const;
 
-  RawUnlinkedCall* AsUnlinkedCall() const;
+  UnlinkedCallPtr AsUnlinkedCall() const;
 
   bool HasReceiverClassId(intptr_t class_id) const;
 
@@ -2205,7 +2213,7 @@
   // the receiver type. Receiver type is expected to be a fully
   // instantiated generic (but not a FutureOr).
   // See StaticTypeExactnessState for more information.
-  static RawICData* New(
+  static ICDataPtr New(
       const Function& owner,
       const String& target_name,
       const Array& arguments_descriptor,
@@ -2213,10 +2221,10 @@
       intptr_t num_args_tested,
       RebindRule rebind_rule,
       const AbstractType& receiver_type = Object::null_abstract_type());
-  static RawICData* NewFrom(const ICData& from, intptr_t num_args_tested);
+  static ICDataPtr NewFrom(const ICData& from, intptr_t num_args_tested);
 
   // Generates a new ICData with descriptor and data array copied (deep clone).
-  static RawICData* Clone(const ICData& from);
+  static ICDataPtr Clone(const ICData& from);
 
   static intptr_t TestEntryLengthFor(intptr_t num_args,
                                      bool tracking_exactness);
@@ -2255,8 +2263,8 @@
 
   intptr_t FindCheck(const GrowableArray<intptr_t>& cids) const;
 
-  RawArray* entries() const {
-    return LoadPointer<RawArray*, std::memory_order_acquire>(
+  ArrayPtr entries() const {
+    return LoadPointer<ArrayPtr, std::memory_order_acquire>(
         &raw_ptr()->entries_);
   }
 
@@ -2273,15 +2281,13 @@
  private:
   friend class FlowGraphSerializer;  // For is_megamorphic()
 
-  static RawICData* New();
+  static ICDataPtr New();
 
   // Grows the array and also sets the argument to the index that should be used
   // for the new entry.
-  RawArray* Grow(intptr_t* index) const;
+  ArrayPtr Grow(intptr_t* index) const;
 
   void set_owner(const Function& value) const;
-  void set_target_name(const String& value) const;
-  void set_arguments_descriptor(const Array& value) const;
   void set_deopt_id(intptr_t value) const;
   void SetNumArgsTested(intptr_t value) const;
   void set_entries(const Array& value) const;
@@ -2319,7 +2325,7 @@
   };
 
   COMPILE_ASSERT(kReceiverCannotBeSmiPos + kReceiverCannotBeSmiSize <=
-                 sizeof(RawICData::state_bits_) * kBitsPerWord);
+                 sizeof(ICDataLayout::state_bits_) * kBitsPerWord);
   COMPILE_ASSERT(kNumRebindRules <= (1 << kRebindRuleSize));
 
   class NumArgsTestedBits : public BitField<uint32_t,
@@ -2352,25 +2358,25 @@
 #endif  // DEBUG
 
   intptr_t TestEntryLength() const;
-  static RawArray* NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
-                                                bool tracking_exactness);
-  static RawArray* CachedEmptyICDataArray(intptr_t num_args_tested,
-                                          bool tracking_exactness);
-  static RawICData* NewDescriptor(Zone* zone,
-                                  const Function& owner,
-                                  const String& target_name,
-                                  const Array& arguments_descriptor,
-                                  intptr_t deopt_id,
-                                  intptr_t num_args_tested,
-                                  RebindRule rebind_rule,
-                                  const AbstractType& receiver_type);
+  static ArrayPtr NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
+                                               bool tracking_exactness);
+  static ArrayPtr CachedEmptyICDataArray(intptr_t num_args_tested,
+                                         bool tracking_exactness);
+  static ICDataPtr NewDescriptor(Zone* zone,
+                                 const Function& owner,
+                                 const String& target_name,
+                                 const Array& arguments_descriptor,
+                                 intptr_t deopt_id,
+                                 intptr_t num_args_tested,
+                                 RebindRule rebind_rule,
+                                 const AbstractType& receiver_type);
 
   static void WriteSentinel(const Array& data, intptr_t test_entry_length);
 
   // A cache of VM heap allocated preinitialized empty ic data entry arrays.
-  static RawArray* cached_icdata_arrays_[kCachedICDataArrayCount];
+  static ArrayPtr cached_icdata_arrays_[kCachedICDataArrayCount];
 
-  FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, CallSiteData);
   friend class CallSiteResetter;
   friend class CallTargets;
   friend class Class;
@@ -2402,18 +2408,18 @@
 
 class Function : public Object {
  public:
-  RawString* name() const { return raw_ptr()->name_; }
-  RawString* UserVisibleName() const;  // Same as scrubbed name.
+  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr UserVisibleName() const;  // Same as scrubbed name.
   const char* UserVisibleNameCString() const;
 
   void PrintQualifiedName(NameVisibility name_visibility,
                           ZoneTextBuffer* printer) const;
-  RawString* QualifiedScrubbedName() const;
-  RawString* QualifiedUserVisibleName() const;
+  StringPtr QualifiedScrubbedName() const;
+  StringPtr QualifiedUserVisibleName() const;
 
-  virtual RawString* DictionaryName() const { return name(); }
+  virtual StringPtr DictionaryName() const { return name(); }
 
-  RawString* GetSource() const;
+  StringPtr GetSource() const;
 
   // Return the type of this function's signature. It may not be canonical yet.
   // For example, if this function has a signature of the form
@@ -2422,9 +2428,9 @@
   // function type with uninstantiated type arguments 'T' and 'R' as elements of
   // its type argument vector.
   // A function type is non-nullable by default.
-  RawType* SignatureType(
+  TypePtr SignatureType(
       Nullability nullability = Nullability::kNonNullable) const;
-  RawType* ExistingSignatureType() const;
+  TypePtr ExistingSignatureType() const;
 
   // Update the signature type (with a canonical version).
   void SetSignatureType(const Type& value) const;
@@ -2435,7 +2441,7 @@
 
   // Retrieves the "C signature" function for an FFI trampoline.
   // Can only be used on FFI trampolines.
-  RawFunction* FfiCSignature() const;
+  FunctionPtr FfiCSignature() const;
 
   // Can only be called on FFI trampolines.
   // -1 for Dart -> native calls.
@@ -2446,20 +2452,20 @@
 
   // Can only be called on FFI trampolines.
   // Null for Dart -> native calls.
-  RawFunction* FfiCallbackTarget() const;
+  FunctionPtr FfiCallbackTarget() const;
 
   // Can only be called on FFI trampolines.
   void SetFfiCallbackTarget(const Function& target) const;
 
   // Can only be called on FFI trampolines.
   // Null for Dart -> native calls.
-  RawInstance* FfiCallbackExceptionalReturn() const;
+  InstancePtr FfiCallbackExceptionalReturn() const;
 
   // Can only be called on FFI trampolines.
   void SetFfiCallbackExceptionalReturn(const Instance& value) const;
 
   // Return a new function with instantiated result and parameter types.
-  RawFunction* InstantiateSignatureFrom(
+  FunctionPtr InstantiateSignatureFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments,
       intptr_t num_free_fun_type_params,
@@ -2469,14 +2475,14 @@
   // internal signature of the given function. In this example, T is a type
   // parameter of this function and R is a type parameter of class C, the owner
   // of the function. B and C are not type parameters.
-  RawString* Signature() const;
+  StringPtr Signature() const;
 
   // Build a string of the form '<T>(T, {B b, C c}) => R' representing the
   // user visible signature of the given function. In this example, T is a type
   // parameter of this function and R is a type parameter of class C, the owner
   // of the function. B and C are not type parameters.
   // Implicit parameters are hidden.
-  RawString* UserVisibleSignature() const;
+  StringPtr UserVisibleSignature() const;
 
   void PrintSignature(NameVisibility name_visibility,
                       ZoneTextBuffer* printer) const;
@@ -2490,36 +2496,36 @@
                                 intptr_t num_free_fun_type_params = kAllFree,
                                 TrailPtr trail = NULL) const;
 
-  RawClass* Owner() const;
+  ClassPtr Owner() const;
   void set_owner(const Object& value) const;
-  RawClass* origin() const;
-  RawScript* script() const;
-  RawObject* RawOwner() const { return raw_ptr()->owner_; }
+  ClassPtr origin() const;
+  ScriptPtr script() const;
+  ObjectPtr RawOwner() const { return raw_ptr()->owner_; }
 
   // The NNBD mode of the library declaring this function.
   // TODO(alexmarkov): nnbd_mode() doesn't work for mixins.
   // It should be either removed or fixed.
   NNBDMode nnbd_mode() const { return Class::Handle(origin()).nnbd_mode(); }
 
-  RawRegExp* regexp() const;
+  RegExpPtr regexp() const;
   intptr_t string_specialization_cid() const;
   bool is_sticky_specialization() const;
   void SetRegExpData(const RegExp& regexp,
                      intptr_t string_specialization_cid,
                      bool sticky) const;
 
-  RawString* native_name() const;
+  StringPtr native_name() const;
   void set_native_name(const String& name) const;
 
-  RawAbstractType* result_type() const { return raw_ptr()->result_type_; }
+  AbstractTypePtr result_type() const { return raw_ptr()->result_type_; }
   void set_result_type(const AbstractType& value) const;
 
   // The parameters, starting with NumImplicitParameters() parameters which are
   // only visible to the VM, but not to Dart users.
   // Note that type checks exclude implicit parameters.
-  RawAbstractType* ParameterTypeAt(intptr_t index) const;
+  AbstractTypePtr ParameterTypeAt(intptr_t index) const;
   void SetParameterTypeAt(intptr_t index, const AbstractType& value) const;
-  RawArray* parameter_types() const { return raw_ptr()->parameter_types_; }
+  ArrayPtr parameter_types() const { return raw_ptr()->parameter_types_; }
   void set_parameter_types(const Array& value) const;
 
   // Parameter names are valid for all valid parameter indices, and are not
@@ -2527,9 +2533,9 @@
   // required) they're stored at the end of this array, so the size of this
   // array isn't necessarily NumParameters(), but the first NumParameters()
   // elements are the names.
-  RawString* ParameterNameAt(intptr_t index) const;
+  StringPtr ParameterNameAt(intptr_t index) const;
   void SetParameterNameAt(intptr_t index, const String& value) const;
-  RawArray* parameter_names() const { return raw_ptr()->parameter_names_; }
+  ArrayPtr parameter_names() const { return raw_ptr()->parameter_names_; }
   void set_parameter_names(const Array& value) const;
 
   // The required flags are stored at the end of the parameter_names. The flags
@@ -2548,7 +2554,7 @@
 
   // The type parameters (and their bounds) are specified as an array of
   // TypeParameter.
-  RawTypeArguments* type_parameters() const {
+  TypeArgumentsPtr type_parameters() const {
     return raw_ptr()->type_parameters_;
   }
   void set_type_parameters(const TypeArguments& value) const;
@@ -2572,8 +2578,8 @@
   // function or of one of its parent functions.
   // Unless NULL, adjust function_level accordingly (in and out parameter).
   // Return null otherwise.
-  RawTypeParameter* LookupTypeParameter(const String& type_name,
-                                        intptr_t* function_level) const;
+  TypeParameterPtr LookupTypeParameter(const String& type_name,
+                                       intptr_t* function_level) const;
 
   // Return true if this function declares type parameters.
   bool IsGeneric() const { return NumTypeParameters(Thread::Current()) > 0; }
@@ -2596,7 +2602,7 @@
   // unoptimized version of the code.  If the code contains errors, it calls
   // Exceptions::PropagateError and does not return.  Normally returns the
   // current code, whether it is optimized or unoptimized.
-  RawCode* EnsureHasCode() const;
+  CodePtr EnsureHasCode() const;
 
   // Disables optimized code and switches to unoptimized code (or the lazy
   // compilation stub).
@@ -2607,54 +2613,54 @@
 
   // Return the most recently compiled and installed code for this function.
   // It is not the only Code object that points to this function.
-  RawCode* CurrentCode() const { return CurrentCodeOf(raw()); }
+  CodePtr CurrentCode() const { return CurrentCodeOf(raw()); }
 
   bool SafeToClosurize() const;
 
-  static RawCode* CurrentCodeOf(const RawFunction* function) {
+  static CodePtr CurrentCodeOf(const FunctionPtr function) {
     return function->ptr()->code_;
   }
 
-  RawCode* unoptimized_code() const {
+  CodePtr unoptimized_code() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
-    return static_cast<RawCode*>(Object::null());
+    return static_cast<CodePtr>(Object::null());
 #else
     return raw_ptr()->unoptimized_code_;
 #endif
   }
   void set_unoptimized_code(const Code& value) const;
   bool HasCode() const;
-  static bool HasCode(RawFunction* function);
+  static bool HasCode(FunctionPtr function);
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static inline bool HasBytecode(RawFunction* function);
+  static inline bool HasBytecode(FunctionPtr function);
 #endif
 
-  static intptr_t code_offset() { return OFFSET_OF(RawFunction, code_); }
+  static intptr_t code_offset() { return OFFSET_OF(FunctionLayout, code_); }
 
   static intptr_t result_type_offset() {
-    return OFFSET_OF(RawFunction, result_type_);
+    return OFFSET_OF(FunctionLayout, result_type_);
   }
 
   static intptr_t entry_point_offset(
       CodeEntryKind entry_kind = CodeEntryKind::kNormal) {
     switch (entry_kind) {
       case CodeEntryKind::kNormal:
-        return OFFSET_OF(RawFunction, entry_point_);
+        return OFFSET_OF(FunctionLayout, entry_point_);
       case CodeEntryKind::kUnchecked:
-        return OFFSET_OF(RawFunction, unchecked_entry_point_);
+        return OFFSET_OF(FunctionLayout, unchecked_entry_point_);
       default:
         UNREACHABLE();
     }
   }
 
   static intptr_t unchecked_entry_point_offset() {
-    return OFFSET_OF(RawFunction, unchecked_entry_point_);
+    return OFFSET_OF(FunctionLayout, unchecked_entry_point_);
   }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   bool IsBytecodeAllowed(Zone* zone) const;
   void AttachBytecode(const Bytecode& bytecode) const;
-  RawBytecode* bytecode() const { return raw_ptr()->bytecode_; }
+  BytecodePtr bytecode() const { return raw_ptr()->bytecode_; }
   inline bool HasBytecode() const;
 #else
   inline bool HasBytecode() const { return false; }
@@ -2666,44 +2672,44 @@
   // set in this function.
   bool HasBreakpoint() const;
 
-  RawContextScope* context_scope() const;
+  ContextScopePtr context_scope() const;
   void set_context_scope(const ContextScope& value) const;
 
   // Enclosing function of this local function.
-  RawFunction* parent_function() const;
+  FunctionPtr parent_function() const;
 
   // Enclosing outermost function of this local function.
-  RawFunction* GetOutermostFunction() const;
+  FunctionPtr GetOutermostFunction() const;
 
   void set_extracted_method_closure(const Function& function) const;
-  RawFunction* extracted_method_closure() const;
+  FunctionPtr extracted_method_closure() const;
 
   void set_saved_args_desc(const Array& array) const;
-  RawArray* saved_args_desc() const;
+  ArrayPtr saved_args_desc() const;
 
   void set_accessor_field(const Field& value) const;
-  RawField* accessor_field() const;
+  FieldPtr accessor_field() const;
 
   bool IsMethodExtractor() const {
-    return kind() == RawFunction::kMethodExtractor;
+    return kind() == FunctionLayout::kMethodExtractor;
   }
 
   bool IsNoSuchMethodDispatcher() const {
-    return kind() == RawFunction::kNoSuchMethodDispatcher;
+    return kind() == FunctionLayout::kNoSuchMethodDispatcher;
   }
 
   bool IsInvokeFieldDispatcher() const {
-    return kind() == RawFunction::kInvokeFieldDispatcher;
+    return kind() == FunctionLayout::kInvokeFieldDispatcher;
   }
 
   bool IsDynamicInvocationForwarder() const {
-    return kind() == RawFunction::kDynamicInvocationForwarder;
+    return kind() == FunctionLayout::kDynamicInvocationForwarder;
   }
 
   bool IsImplicitGetterOrSetter() const {
-    return kind() == RawFunction::kImplicitGetter ||
-           kind() == RawFunction::kImplicitSetter ||
-           kind() == RawFunction::kImplicitStaticGetter;
+    return kind() == FunctionLayout::kImplicitGetter ||
+           kind() == FunctionLayout::kImplicitSetter ||
+           kind() == FunctionLayout::kImplicitStaticGetter;
   }
 
   // Returns true iff an implicit closure function has been created
@@ -2715,48 +2721,48 @@
   // Returns the closure function implicitly created for this function.  If none
   // exists yet, create one and remember it.  Implicit closure functions are
   // used in VM Closure instances that represent results of tear-off operations.
-  RawFunction* ImplicitClosureFunction() const;
+  FunctionPtr ImplicitClosureFunction() const;
   void DropUncompiledImplicitClosureFunction() const;
 
   // Return the closure implicitly created for this function.
   // If none exists yet, create one and remember it.
-  RawInstance* ImplicitStaticClosure() const;
+  InstancePtr ImplicitStaticClosure() const;
 
-  RawInstance* ImplicitInstanceClosure(const Instance& receiver) const;
+  InstancePtr ImplicitInstanceClosure(const Instance& receiver) const;
 
   intptr_t ComputeClosureHash() const;
 
   // Redirection information for a redirecting factory.
   bool IsRedirectingFactory() const;
-  RawType* RedirectionType() const;
+  TypePtr RedirectionType() const;
   void SetRedirectionType(const Type& type) const;
-  RawString* RedirectionIdentifier() const;
+  StringPtr RedirectionIdentifier() const;
   void SetRedirectionIdentifier(const String& identifier) const;
-  RawFunction* RedirectionTarget() const;
+  FunctionPtr RedirectionTarget() const;
   void SetRedirectionTarget(const Function& target) const;
 
-  RawFunction* ForwardingTarget() const;
+  FunctionPtr ForwardingTarget() const;
   void SetForwardingChecks(const Array& checks) const;
 
-  RawFunction::Kind kind() const {
+  FunctionLayout::Kind kind() const {
     return KindBits::decode(raw_ptr()->kind_tag_);
   }
-  static RawFunction::Kind kind(RawFunction* function) {
+  static FunctionLayout::Kind kind(FunctionPtr function) {
     return KindBits::decode(function->ptr()->kind_tag_);
   }
 
-  RawFunction::AsyncModifier modifier() const {
+  FunctionLayout::AsyncModifier modifier() const {
     return ModifierBits::decode(raw_ptr()->kind_tag_);
   }
 
-  static const char* KindToCString(RawFunction::Kind kind);
+  static const char* KindToCString(FunctionLayout::Kind kind);
 
   bool IsGenerativeConstructor() const {
-    return (kind() == RawFunction::kConstructor) && !is_static();
+    return (kind() == FunctionLayout::kConstructor) && !is_static();
   }
   bool IsImplicitConstructor() const;
   bool IsFactory() const {
-    return (kind() == RawFunction::kConstructor) && is_static();
+    return (kind() == FunctionLayout::kConstructor) && is_static();
   }
 
   // Whether this function can receive an invocation where the number and names
@@ -2767,7 +2773,7 @@
 
   bool HasThisParameter() const {
     return IsDynamicFunction(/*allow_abstract=*/true) ||
-           IsGenerativeConstructor();
+           IsGenerativeConstructor() || (IsFieldInitializer() && !is_static());
   }
 
   bool IsDynamicFunction(bool allow_abstract = false) const {
@@ -2775,23 +2781,23 @@
       return false;
     }
     switch (kind()) {
-      case RawFunction::kRegularFunction:
-      case RawFunction::kGetterFunction:
-      case RawFunction::kSetterFunction:
-      case RawFunction::kImplicitGetter:
-      case RawFunction::kImplicitSetter:
-      case RawFunction::kMethodExtractor:
-      case RawFunction::kNoSuchMethodDispatcher:
-      case RawFunction::kInvokeFieldDispatcher:
-      case RawFunction::kDynamicInvocationForwarder:
+      case FunctionLayout::kRegularFunction:
+      case FunctionLayout::kGetterFunction:
+      case FunctionLayout::kSetterFunction:
+      case FunctionLayout::kImplicitGetter:
+      case FunctionLayout::kImplicitSetter:
+      case FunctionLayout::kMethodExtractor:
+      case FunctionLayout::kNoSuchMethodDispatcher:
+      case FunctionLayout::kInvokeFieldDispatcher:
+      case FunctionLayout::kDynamicInvocationForwarder:
         return true;
-      case RawFunction::kClosureFunction:
-      case RawFunction::kImplicitClosureFunction:
-      case RawFunction::kSignatureFunction:
-      case RawFunction::kConstructor:
-      case RawFunction::kImplicitStaticGetter:
-      case RawFunction::kFieldInitializer:
-      case RawFunction::kIrregexpFunction:
+      case FunctionLayout::kClosureFunction:
+      case FunctionLayout::kImplicitClosureFunction:
+      case FunctionLayout::kSignatureFunction:
+      case FunctionLayout::kConstructor:
+      case FunctionLayout::kImplicitStaticGetter:
+      case FunctionLayout::kFieldInitializer:
+      case FunctionLayout::kIrregexpFunction:
         return false;
       default:
         UNREACHABLE();
@@ -2803,23 +2809,23 @@
       return false;
     }
     switch (kind()) {
-      case RawFunction::kRegularFunction:
-      case RawFunction::kGetterFunction:
-      case RawFunction::kSetterFunction:
-      case RawFunction::kImplicitGetter:
-      case RawFunction::kImplicitSetter:
-      case RawFunction::kImplicitStaticGetter:
-      case RawFunction::kFieldInitializer:
-      case RawFunction::kIrregexpFunction:
+      case FunctionLayout::kRegularFunction:
+      case FunctionLayout::kGetterFunction:
+      case FunctionLayout::kSetterFunction:
+      case FunctionLayout::kImplicitGetter:
+      case FunctionLayout::kImplicitSetter:
+      case FunctionLayout::kImplicitStaticGetter:
+      case FunctionLayout::kFieldInitializer:
+      case FunctionLayout::kIrregexpFunction:
         return true;
-      case RawFunction::kClosureFunction:
-      case RawFunction::kImplicitClosureFunction:
-      case RawFunction::kSignatureFunction:
-      case RawFunction::kConstructor:
-      case RawFunction::kMethodExtractor:
-      case RawFunction::kNoSuchMethodDispatcher:
-      case RawFunction::kInvokeFieldDispatcher:
-      case RawFunction::kDynamicInvocationForwarder:
+      case FunctionLayout::kClosureFunction:
+      case FunctionLayout::kImplicitClosureFunction:
+      case FunctionLayout::kSignatureFunction:
+      case FunctionLayout::kConstructor:
+      case FunctionLayout::kMethodExtractor:
+      case FunctionLayout::kNoSuchMethodDispatcher:
+      case FunctionLayout::kInvokeFieldDispatcher:
+      case FunctionLayout::kDynamicInvocationForwarder:
         return false;
       default:
         UNREACHABLE();
@@ -2833,7 +2839,7 @@
       return false;
     }
     return IsClosureFunction() ||
-           !(is_static() || (kind() == RawFunction::kConstructor));
+           !(is_static() || (kind() == FunctionLayout::kConstructor));
   }
 
   bool NeedsMonomorphicCheckedEntry(Zone* zone) const;
@@ -2865,7 +2871,7 @@
   }
 
   intptr_t num_fixed_parameters() const {
-    return RawFunction::PackedNumFixedParameters::decode(
+    return FunctionLayout::PackedNumFixedParameters::decode(
         raw_ptr()->packed_fields_);
   }
   void set_num_fixed_parameters(intptr_t value) const;
@@ -2874,19 +2880,19 @@
   void set_packed_fields(uint32_t packed_fields) const;
 
   bool HasOptionalParameters() const {
-    return RawFunction::PackedNumOptionalParameters::decode(
+    return FunctionLayout::PackedNumOptionalParameters::decode(
                raw_ptr()->packed_fields_) > 0;
   }
   bool HasOptionalNamedParameters() const {
     return HasOptionalParameters() &&
-           RawFunction::PackedHasNamedOptionalParameters::decode(
+           FunctionLayout::PackedHasNamedOptionalParameters::decode(
                raw_ptr()->packed_fields_);
   }
   bool HasOptionalPositionalParameters() const {
     return HasOptionalParameters() && !HasOptionalNamedParameters();
   }
   intptr_t NumOptionalParameters() const {
-    return RawFunction::PackedNumOptionalParameters::decode(
+    return FunctionLayout::PackedNumOptionalParameters::decode(
         raw_ptr()->packed_fields_);
   }
   void SetNumOptionalParameters(intptr_t num_optional_parameters,
@@ -2915,7 +2921,9 @@
   void set_##name(type value) const { UNREACHABLE(); }
 #else
 #define DEFINE_GETTERS_AND_SETTERS(return_type, type, name)                    \
-  static intptr_t name##_offset() { return OFFSET_OF(RawFunction, name##_); }  \
+  static intptr_t name##_offset() {                                            \
+    return OFFSET_OF(FunctionLayout, name##_);                                 \
+  }                                                                            \
   return_type name() const { return raw_ptr()->name##_; }                      \
                                                                                \
   void set_##name(type value) const {                                          \
@@ -2929,13 +2937,13 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   intptr_t binary_declaration_offset() const {
-    return RawFunction::BinaryDeclarationOffset::decode(
+    return FunctionLayout::BinaryDeclarationOffset::decode(
         raw_ptr()->binary_declaration_);
   }
   void set_binary_declaration_offset(intptr_t value) const {
     ASSERT(value >= 0);
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawFunction::BinaryDeclarationOffset::update(
+                    FunctionLayout::BinaryDeclarationOffset::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -2980,7 +2988,7 @@
 #if defined(DART_PRECOMPILED_RUNTIME)
     return false;
 #else
-    return RawFunction::IsDeclaredInBytecode::decode(
+    return FunctionLayout::IsDeclaredInBytecode::decode(
         raw_ptr()->binary_declaration_);
 #endif
   }
@@ -2988,7 +2996,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   void set_is_declared_in_bytecode(bool value) const {
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawFunction::IsDeclaredInBytecode::update(
+                    FunctionLayout::IsDeclaredInBytecode::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -3014,7 +3022,7 @@
 
   intptr_t KernelDataProgramOffset() const;
 
-  RawExternalTypedData* KernelData() const;
+  ExternalTypedDataPtr KernelData() const;
 
   bool IsOptimizable() const;
   void SetIsOptimizable(bool value) const;
@@ -3060,7 +3068,7 @@
 
   // Returns a TypeError if the provided arguments don't match the function
   // parameter types, NULL otherwise. Assumes AreValidArguments is called first.
-  RawObject* DoArgumentTypesMatch(
+  ObjectPtr DoArgumentTypesMatch(
       const Array& args,
       const ArgumentsDescriptor& arg_names,
       const TypeArguments& instantiator_type_args) const;
@@ -3085,13 +3093,13 @@
 
   static constexpr intptr_t maximum_unboxed_parameter_count() {
     // Subtracts one that represents the return value
-    return RawFunction::UnboxedParameterBitmap::kCapacity - 1;
+    return FunctionLayout::UnboxedParameterBitmap::kCapacity - 1;
   }
 
   void reset_unboxed_parameters_and_return() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
     StoreNonPointer(&raw_ptr()->unboxed_parameters_info_,
-                    RawFunction::UnboxedParameterBitmap());
+                    FunctionLayout::UnboxedParameterBitmap());
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
   }
 
@@ -3099,7 +3107,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
     ASSERT(index >= 0 && index < maximum_unboxed_parameter_count());
     index++;  // position 0 is reserved for the return value
-    const_cast<RawFunction::UnboxedParameterBitmap*>(
+    const_cast<FunctionLayout::UnboxedParameterBitmap*>(
         &raw_ptr()->unboxed_parameters_info_)
         ->SetUnboxedInteger(index);
 #else
@@ -3111,7 +3119,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
     ASSERT(index >= 0 && index < maximum_unboxed_parameter_count());
     index++;  // position 0 is reserved for the return value
-    const_cast<RawFunction::UnboxedParameterBitmap*>(
+    const_cast<FunctionLayout::UnboxedParameterBitmap*>(
         &raw_ptr()->unboxed_parameters_info_)
         ->SetUnboxedDouble(index);
 
@@ -3122,7 +3130,7 @@
 
   void set_unboxed_integer_return() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-    const_cast<RawFunction::UnboxedParameterBitmap*>(
+    const_cast<FunctionLayout::UnboxedParameterBitmap*>(
         &raw_ptr()->unboxed_parameters_info_)
         ->SetUnboxedInteger(0);
 #else
@@ -3132,7 +3140,7 @@
 
   void set_unboxed_double_return() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-    const_cast<RawFunction::UnboxedParameterBitmap*>(
+    const_cast<FunctionLayout::UnboxedParameterBitmap*>(
         &raw_ptr()->unboxed_parameters_info_)
         ->SetUnboxedDouble(0);
 
@@ -3201,12 +3209,12 @@
 
   bool IsDispatcherOrImplicitAccessor() const {
     switch (kind()) {
-      case RawFunction::kImplicitGetter:
-      case RawFunction::kImplicitSetter:
-      case RawFunction::kImplicitStaticGetter:
-      case RawFunction::kNoSuchMethodDispatcher:
-      case RawFunction::kInvokeFieldDispatcher:
-      case RawFunction::kDynamicInvocationForwarder:
+      case FunctionLayout::kImplicitGetter:
+      case FunctionLayout::kImplicitSetter:
+      case FunctionLayout::kImplicitStaticGetter:
+      case FunctionLayout::kNoSuchMethodDispatcher:
+      case FunctionLayout::kInvokeFieldDispatcher:
+      case FunctionLayout::kDynamicInvocationForwarder:
         return true;
       default:
         return false;
@@ -3215,47 +3223,47 @@
 
   // Returns true if this function represents an explicit getter function.
   bool IsGetterFunction() const {
-    return kind() == RawFunction::kGetterFunction;
+    return kind() == FunctionLayout::kGetterFunction;
   }
 
   // Returns true if this function represents an implicit getter function.
   bool IsImplicitGetterFunction() const {
-    return kind() == RawFunction::kImplicitGetter;
+    return kind() == FunctionLayout::kImplicitGetter;
   }
 
   // Returns true if this function represents an explicit setter function.
   bool IsSetterFunction() const {
-    return kind() == RawFunction::kSetterFunction;
+    return kind() == FunctionLayout::kSetterFunction;
   }
 
   // Returns true if this function represents an implicit setter function.
   bool IsImplicitSetterFunction() const {
-    return kind() == RawFunction::kImplicitSetter;
+    return kind() == FunctionLayout::kImplicitSetter;
   }
 
-  // Returns true if this function represents an the initializer for a static or
+  // Returns true if this function represents an initializer for a static or
   // instance field. The function returns the initial value and the caller is
   // responsible for setting the field.
   bool IsFieldInitializer() const {
-    return kind() == RawFunction::kFieldInitializer;
+    return kind() == FunctionLayout::kFieldInitializer;
   }
 
   // Returns true if this function represents a (possibly implicit) closure
   // function.
   bool IsClosureFunction() const {
-    RawFunction::Kind k = kind();
-    return (k == RawFunction::kClosureFunction) ||
-           (k == RawFunction::kImplicitClosureFunction);
+    FunctionLayout::Kind k = kind();
+    return (k == FunctionLayout::kClosureFunction) ||
+           (k == FunctionLayout::kImplicitClosureFunction);
   }
 
   // Returns true if this function represents a generated irregexp function.
   bool IsIrregexpFunction() const {
-    return kind() == RawFunction::kIrregexpFunction;
+    return kind() == FunctionLayout::kIrregexpFunction;
   }
 
   // Returns true if this function represents an implicit closure function.
   bool IsImplicitClosureFunction() const {
-    return kind() == RawFunction::kImplicitClosureFunction;
+    return kind() == FunctionLayout::kImplicitClosureFunction;
   }
 
   // Returns true if this function represents a non implicit closure function.
@@ -3268,7 +3276,7 @@
   bool IsImplicitStaticClosureFunction() const {
     return IsImplicitClosureFunction() && is_static();
   }
-  static bool IsImplicitStaticClosureFunction(RawFunction* func);
+  static bool IsImplicitStaticClosureFunction(FunctionPtr func);
 
   // Returns true if this function represents an implicit instance closure
   // function.
@@ -3281,20 +3289,22 @@
 
   // Returns true if this function represents a signature function without code.
   bool IsSignatureFunction() const {
-    return kind() == RawFunction::kSignatureFunction;
+    return kind() == FunctionLayout::kSignatureFunction;
   }
-  static bool IsSignatureFunction(RawFunction* function) {
+  static bool IsSignatureFunction(FunctionPtr function) {
     NoSafepointScope no_safepoint;
     return KindBits::decode(function->ptr()->kind_tag_) ==
-           RawFunction::kSignatureFunction;
+           FunctionLayout::kSignatureFunction;
   }
 
   // Returns true if this function represents an ffi trampoline.
-  bool IsFfiTrampoline() const { return kind() == RawFunction::kFfiTrampoline; }
-  static bool IsFfiTrampoline(RawFunction* function) {
+  bool IsFfiTrampoline() const {
+    return kind() == FunctionLayout::kFfiTrampoline;
+  }
+  static bool IsFfiTrampoline(FunctionPtr function) {
     NoSafepointScope no_safepoint;
     return KindBits::decode(function->ptr()->kind_tag_) ==
-           RawFunction::kFfiTrampoline;
+           FunctionLayout::kFfiTrampoline;
   }
 
   bool IsFfiLoad() const {
@@ -3319,7 +3329,7 @@
     return kind == MethodRecognizer::kFfiGetAddress;
   }
 
-  bool IsAsyncFunction() const { return modifier() == RawFunction::kAsync; }
+  bool IsAsyncFunction() const { return modifier() == FunctionLayout::kAsync; }
 
   bool IsAsyncClosure() const {
     return is_generated_body() &&
@@ -3327,10 +3337,12 @@
   }
 
   bool IsGenerator() const {
-    return (modifier() & RawFunction::kGeneratorBit) != 0;
+    return (modifier() & FunctionLayout::kGeneratorBit) != 0;
   }
 
-  bool IsSyncGenerator() const { return modifier() == RawFunction::kSyncGen; }
+  bool IsSyncGenerator() const {
+    return modifier() == FunctionLayout::kSyncGen;
+  }
 
   bool IsSyncGenClosure() const {
     return is_generated_body() &&
@@ -3342,7 +3354,9 @@
            Function::Handle(parent_function()).IsGenerator();
   }
 
-  bool IsAsyncGenerator() const { return modifier() == RawFunction::kAsyncGen; }
+  bool IsAsyncGenerator() const {
+    return modifier() == FunctionLayout::kAsyncGen;
+  }
 
   bool IsAsyncGenClosure() const {
     return is_generated_body() &&
@@ -3350,84 +3364,84 @@
   }
 
   bool IsAsyncOrGenerator() const {
-    return modifier() != RawFunction::kNoModifier;
+    return modifier() != FunctionLayout::kNoModifier;
   }
 
   bool IsTypedDataViewFactory() const {
-    if (is_native() && kind() == RawFunction::kConstructor) {
+    if (is_native() && kind() == FunctionLayout::kConstructor) {
       // This is a native factory constructor.
       const Class& klass = Class::Handle(Owner());
-      return RawObject::IsTypedDataViewClassId(klass.id());
+      return IsTypedDataViewClassId(klass.id());
     }
     return false;
   }
 
   DART_WARN_UNUSED_RESULT
-  RawError* VerifyCallEntryPoint() const;
+  ErrorPtr VerifyCallEntryPoint() const;
 
   DART_WARN_UNUSED_RESULT
-  RawError* VerifyClosurizedEntryPoint() const;
+  ErrorPtr VerifyClosurizedEntryPoint() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawFunction));
+    return RoundedAllocationSize(sizeof(FunctionLayout));
   }
 
-  static RawFunction* New(const String& name,
-                          RawFunction::Kind kind,
-                          bool is_static,
-                          bool is_const,
-                          bool is_abstract,
-                          bool is_external,
-                          bool is_native,
-                          const Object& owner,
-                          TokenPosition token_pos,
-                          Heap::Space space = Heap::kOld);
+  static FunctionPtr New(const String& name,
+                         FunctionLayout::Kind kind,
+                         bool is_static,
+                         bool is_const,
+                         bool is_abstract,
+                         bool is_external,
+                         bool is_native,
+                         const Object& owner,
+                         TokenPosition token_pos,
+                         Heap::Space space = Heap::kOld);
 
   // Allocates a new Function object representing a closure function
   // with given kind - kClosureFunction or kImplicitClosureFunction.
-  static RawFunction* NewClosureFunctionWithKind(RawFunction::Kind kind,
-                                                 const String& name,
-                                                 const Function& parent,
-                                                 TokenPosition token_pos,
-                                                 const Object& owner);
+  static FunctionPtr NewClosureFunctionWithKind(FunctionLayout::Kind kind,
+                                                const String& name,
+                                                const Function& parent,
+                                                TokenPosition token_pos,
+                                                const Object& owner);
 
   // Allocates a new Function object representing a closure function.
-  static RawFunction* NewClosureFunction(const String& name,
-                                         const Function& parent,
-                                         TokenPosition token_pos);
+  static FunctionPtr NewClosureFunction(const String& name,
+                                        const Function& parent,
+                                        TokenPosition token_pos);
 
   // Allocates a new Function object representing an implicit closure function.
-  static RawFunction* NewImplicitClosureFunction(const String& name,
-                                                 const Function& parent,
-                                                 TokenPosition token_pos);
+  static FunctionPtr NewImplicitClosureFunction(const String& name,
+                                                const Function& parent,
+                                                TokenPosition token_pos);
 
   // Allocates a new Function object representing a signature function.
   // The owner is the scope class of the function type.
   // The parent is the enclosing function or null if none.
-  static RawFunction* NewSignatureFunction(const Object& owner,
-                                           const Function& parent,
-                                           TokenPosition token_pos,
-                                           Heap::Space space = Heap::kOld);
+  static FunctionPtr NewSignatureFunction(const Object& owner,
+                                          const Function& parent,
+                                          TokenPosition token_pos,
+                                          Heap::Space space = Heap::kOld);
 
-  static RawFunction* NewEvalFunction(const Class& owner,
-                                      const Script& script,
-                                      bool is_static);
+  static FunctionPtr NewEvalFunction(const Class& owner,
+                                     const Script& script,
+                                     bool is_static);
 
-  RawFunction* CreateMethodExtractor(const String& getter_name) const;
-  RawFunction* GetMethodExtractor(const String& getter_name) const;
+  FunctionPtr CreateMethodExtractor(const String& getter_name) const;
+  FunctionPtr GetMethodExtractor(const String& getter_name) const;
 
   static bool IsDynamicInvocationForwarderName(const String& name);
 
-  static RawString* DemangleDynamicInvocationForwarderName(const String& name);
+  static StringPtr DemangleDynamicInvocationForwarderName(const String& name);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static RawString* CreateDynamicInvocationForwarderName(const String& name);
+  static StringPtr CreateDynamicInvocationForwarderName(const String& name);
 
-  RawFunction* CreateDynamicInvocationForwarder(
+  FunctionPtr CreateDynamicInvocationForwarder(
       const String& mangled_name) const;
 
-  RawFunction* GetDynamicInvocationForwarder(const String& mangled_name,
-                                             bool allow_add = true) const;
+  FunctionPtr GetDynamicInvocationForwarder(const String& mangled_name,
+                                            bool allow_add = true) const;
 #endif
 
   // Slow function, use in asserts to track changes in important library
@@ -3446,14 +3460,14 @@
   void RestoreICDataMap(ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
                         bool clone_ic_data) const;
 
-  RawArray* ic_data_array() const;
+  ArrayPtr ic_data_array() const;
   void ClearICDataArray() const;
-  RawICData* FindICData(intptr_t deopt_id) const;
+  ICDataPtr FindICData(intptr_t deopt_id) const;
 
   // Sets deopt reason in all ICData-s with given deopt_id.
   void SetDeoptReasonForAll(intptr_t deopt_id, ICData::DeoptReasonId reason);
 
-  void set_modifier(RawFunction::AsyncModifier value) const;
+  void set_modifier(FunctionLayout::AsyncModifier value) const;
 
 // 'WasCompiled' is true if the function was compiled once in this
 // VM instantiation. It is independent from presence of type feedback
@@ -3553,22 +3567,22 @@
   //              some functions known to be execute infrequently and functions
   //              which have been de-optimized too many times.
   bool is_optimizable() const {
-    return RawFunction::OptimizableBit::decode(raw_ptr()->packed_fields_);
+    return FunctionLayout::OptimizableBit::decode(raw_ptr()->packed_fields_);
   }
   void set_is_optimizable(bool value) const {
-    set_packed_fields(
-        RawFunction::OptimizableBit::update(value, raw_ptr()->packed_fields_));
+    set_packed_fields(FunctionLayout::OptimizableBit::update(
+        value, raw_ptr()->packed_fields_));
   }
 
   // Indicates whether this function can be optimized on the background compiler
   // thread.
   bool is_background_optimizable() const {
-    return RawFunction::BackgroundOptimizableBit::decode(
+    return FunctionLayout::BackgroundOptimizableBit::decode(
         raw_ptr()->packed_fields_);
   }
 
   void set_is_background_optimizable(bool value) const {
-    set_packed_fields(RawFunction::BackgroundOptimizableBit::update(
+    set_packed_fields(FunctionLayout::BackgroundOptimizableBit::update(
         value, raw_ptr()->packed_fields_));
   }
 
@@ -3595,10 +3609,10 @@
                  (1 << kRecognizedTagSize));
   COMPILE_ASSERT(kNumTagBits <=
                  (kBitsPerByte *
-                  sizeof(static_cast<RawFunction*>(0)->kind_tag_)));
+                  sizeof(static_cast<FunctionLayout*>(nullptr)->kind_tag_)));
 
   class KindBits : public BitField<uint32_t,
-                                   RawFunction::Kind,
+                                   FunctionLayout::Kind,
                                    kKindTagPos,
                                    kKindTagSize> {};
 
@@ -3607,7 +3621,7 @@
                                          kRecognizedTagPos,
                                          kRecognizedTagSize> {};
   class ModifierBits : public BitField<uint32_t,
-                                       RawFunction::AsyncModifier,
+                                       FunctionLayout::AsyncModifier,
                                        kModifierPos,
                                        kModifierSize> {};
 
@@ -3617,18 +3631,18 @@
 #undef DEFINE_BIT
 
   void set_name(const String& value) const;
-  void set_kind(RawFunction::Kind value) const;
+  void set_kind(FunctionLayout::Kind value) const;
   void set_parent_function(const Function& value) const;
-  RawFunction* implicit_closure_function() const;
+  FunctionPtr implicit_closure_function() const;
   void set_implicit_closure_function(const Function& value) const;
-  RawInstance* implicit_static_closure() const;
+  InstancePtr implicit_static_closure() const;
   void set_implicit_static_closure(const Instance& closure) const;
-  RawScript* eval_script() const;
+  ScriptPtr eval_script() const;
   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;
   void set_data(const Object& value) const;
-  static RawFunction* New(Heap::Space space = Heap::kOld);
+  static FunctionPtr New(Heap::Space space = Heap::kOld);
 
   void PrintSignatureParameters(Thread* thread,
                                 Zone* zone,
@@ -3652,9 +3666,9 @@
   friend class Class;
   friend class SnapshotWriter;
   friend class Parser;  // For set_eval_script.
-  // RawFunction::VisitFunctionPointers accesses the private constructor of
+  // FunctionLayout::VisitFunctionPointers accesses the private constructor of
   // Function.
-  friend class RawFunction;
+  friend class FunctionLayout;
   friend class ClassFinalizer;  // To reset parent_function.
   friend class Type;            // To adjust parent_function.
 };
@@ -3662,25 +3676,25 @@
 class ClosureData : public Object {
  public:
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawClosureData));
+    return RoundedAllocationSize(sizeof(ClosureDataLayout));
   }
 
  private:
-  RawContextScope* context_scope() const { return raw_ptr()->context_scope_; }
+  ContextScopePtr context_scope() const { return raw_ptr()->context_scope_; }
   void set_context_scope(const ContextScope& value) const;
 
   // Enclosing function of this local function.
-  RawFunction* parent_function() const { return raw_ptr()->parent_function_; }
+  FunctionPtr parent_function() const { return raw_ptr()->parent_function_; }
   void set_parent_function(const Function& value) const;
 
   // Signature type of this closure function.
-  RawType* signature_type() const { return raw_ptr()->signature_type_; }
+  TypePtr signature_type() const { return raw_ptr()->signature_type_; }
   void set_signature_type(const Type& value) const;
 
-  RawInstance* implicit_static_closure() const { return raw_ptr()->closure_; }
+  InstancePtr implicit_static_closure() const { return raw_ptr()->closure_; }
   void set_implicit_static_closure(const Instance& closure) const;
 
-  static RawClosureData* New();
+  static ClosureDataPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ClosureData, Object);
   friend class Class;
@@ -3691,19 +3705,19 @@
 class SignatureData : public Object {
  public:
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawSignatureData));
+    return RoundedAllocationSize(sizeof(SignatureDataLayout));
   }
 
  private:
   // Enclosing function of this signature function.
-  RawFunction* parent_function() const { return raw_ptr()->parent_function_; }
+  FunctionPtr parent_function() const { return raw_ptr()->parent_function_; }
   void set_parent_function(const Function& value) const;
 
   // Signature type of this signature function.
-  RawType* signature_type() const { return raw_ptr()->signature_type_; }
+  TypePtr signature_type() const { return raw_ptr()->signature_type_; }
   void set_signature_type(const Type& value) const;
 
-  static RawSignatureData* New(Heap::Space space = Heap::kOld);
+  static SignatureDataPtr New(Heap::Space space = Heap::kOld);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(SignatureData, Object);
   friend class Class;
@@ -3714,23 +3728,23 @@
 class RedirectionData : public Object {
  public:
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawRedirectionData));
+    return RoundedAllocationSize(sizeof(RedirectionDataLayout));
   }
 
  private:
   // The type specifies the class and type arguments of the target constructor.
-  RawType* type() const { return raw_ptr()->type_; }
+  TypePtr type() const { return raw_ptr()->type_; }
   void set_type(const Type& value) const;
 
   // The optional identifier specifies a named constructor.
-  RawString* identifier() const { return raw_ptr()->identifier_; }
+  StringPtr identifier() const { return raw_ptr()->identifier_; }
   void set_identifier(const String& value) const;
 
   // The resolved constructor or factory target of the redirection.
-  RawFunction* target() const { return raw_ptr()->target_; }
+  FunctionPtr target() const { return raw_ptr()->target_; }
   void set_target(const Function& value) const;
 
-  static RawRedirectionData* New();
+  static RedirectionDataPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(RedirectionData, Object);
   friend class Class;
@@ -3749,21 +3763,21 @@
 class FfiTrampolineData : public Object {
  public:
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawFfiTrampolineData));
+    return RoundedAllocationSize(sizeof(FfiTrampolineDataLayout));
   }
 
  private:
   // Signature type of this closure function.
-  RawType* signature_type() const { return raw_ptr()->signature_type_; }
+  TypePtr signature_type() const { return raw_ptr()->signature_type_; }
   void set_signature_type(const Type& value) const;
 
-  RawFunction* c_signature() const { return raw_ptr()->c_signature_; }
+  FunctionPtr c_signature() const { return raw_ptr()->c_signature_; }
   void set_c_signature(const Function& value) const;
 
-  RawFunction* callback_target() const { return raw_ptr()->callback_target_; }
+  FunctionPtr callback_target() const { return raw_ptr()->callback_target_; }
   void set_callback_target(const Function& value) const;
 
-  RawInstance* callback_exceptional_return() const {
+  InstancePtr callback_exceptional_return() const {
     return raw_ptr()->callback_exceptional_return_;
   }
   void set_callback_exceptional_return(const Instance& value) const;
@@ -3771,7 +3785,7 @@
   int32_t callback_id() const { return raw_ptr()->callback_id_; }
   void set_callback_id(int32_t value) const;
 
-  static RawFfiTrampolineData* New();
+  static FfiTrampolineDataPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData, Object);
   friend class Class;
@@ -3784,7 +3798,7 @@
   // The field that this field was cloned from, or this field itself if it isn't
   // a clone. The purpose of cloning is that the fields the background compiler
   // sees are consistent.
-  RawField* Original() const;
+  FieldPtr Original() const;
 
   // Set the original field that this field was cloned from.
   void SetOriginal(const Field& value) const;
@@ -3800,12 +3814,12 @@
 
   // Returns a field cloned from 'this'. 'this' is set as the
   // original field of result.
-  RawField* CloneFromOriginal() const;
+  FieldPtr CloneFromOriginal() const;
 
-  RawString* name() const { return raw_ptr()->name_; }
-  RawString* UserVisibleName() const;  // Same as scrubbed name.
+  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr UserVisibleName() const;  // Same as scrubbed name.
   const char* UserVisibleNameCString() const;
-  virtual RawString* DictionaryName() const { return name(); }
+  virtual StringPtr DictionaryName() const { return name(); }
 
   bool is_static() const { return StaticBit::decode(raw_ptr()->kind_bits_); }
   bool is_instance() const { return !is_static(); }
@@ -3869,13 +3883,13 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   intptr_t binary_declaration_offset() const {
-    return RawField::BinaryDeclarationOffset::decode(
+    return FieldLayout::BinaryDeclarationOffset::decode(
         raw_ptr()->binary_declaration_);
   }
   void set_binary_declaration_offset(intptr_t value) const {
     ASSERT(value >= 0);
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawField::BinaryDeclarationOffset::update(
+                    FieldLayout::BinaryDeclarationOffset::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -3920,7 +3934,7 @@
 #if defined(DART_PRECOMPILED_RUNTIME)
     return false;
 #else
-    return RawField::IsDeclaredInBytecode::decode(
+    return FieldLayout::IsDeclaredInBytecode::decode(
         raw_ptr()->binary_declaration_);
 #endif
   }
@@ -3928,14 +3942,14 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   void set_is_declared_in_bytecode(bool value) const {
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawField::IsDeclaredInBytecode::update(
+                    FieldLayout::IsDeclaredInBytecode::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   void InheritBinaryDeclarationFrom(const Field& src) const;
 
-  RawExternalTypedData* KernelData() const;
+  ExternalTypedDataPtr KernelData() const;
 
   intptr_t KernelDataProgramOffset() const;
 
@@ -3944,70 +3958,76 @@
                         intptr_t target_offset_in_bytes) const;
 
   inline intptr_t HostOffset() const;
+  static intptr_t host_offset_or_field_id_offset() {
+    return OFFSET_OF(FieldLayout, host_offset_or_field_id_);
+  }
 
   inline intptr_t TargetOffset() const;
+  static inline intptr_t TargetOffsetOf(FieldPtr field);
 
-  inline RawInstance* StaticValue() const;
+  inline InstancePtr StaticValue() const;
   void SetStaticValue(const Instance& value,
                       bool save_initial_value = false) const;
 
-  intptr_t field_id() const { return raw_ptr()->host_offset_or_field_id_; }
+  inline intptr_t field_id() const;
   inline void set_field_id(intptr_t field_id) const;
 
 #ifndef DART_PRECOMPILED_RUNTIME
-  RawInstance* saved_initial_value() const {
+  InstancePtr saved_initial_value() const {
     return raw_ptr()->saved_initial_value_;
   }
   inline void set_saved_initial_value(const Instance& value) const;
 #endif
 
-  RawClass* Owner() const;
-  RawClass* Origin() const;  // Either mixin class, or same as owner().
-  RawScript* Script() const;
-  RawObject* RawOwner() const;
+  ClassPtr Owner() const;
+  ClassPtr Origin() const;  // Either mixin class, or same as owner().
+  ScriptPtr Script() const;
+  ObjectPtr RawOwner() const;
 
-  RawAbstractType* type() const { return raw_ptr()->type_; }
+  AbstractTypePtr type() const { return raw_ptr()->type_; }
   // Used by class finalizer, otherwise initialized in constructor.
   void SetFieldType(const AbstractType& value) const;
 
   DART_WARN_UNUSED_RESULT
-  RawError* VerifyEntryPoint(EntryPointPragma kind) const;
+  ErrorPtr VerifyEntryPoint(EntryPointPragma kind) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawField));
+    return RoundedAllocationSize(sizeof(FieldLayout));
   }
 
-  static RawField* New(const String& name,
-                       bool is_static,
-                       bool is_final,
-                       bool is_const,
-                       bool is_reflectable,
-                       bool is_late,
-                       const Object& owner,
-                       const AbstractType& type,
-                       TokenPosition token_pos,
-                       TokenPosition end_token_pos);
+  static FieldPtr New(const String& name,
+                      bool is_static,
+                      bool is_final,
+                      bool is_const,
+                      bool is_reflectable,
+                      bool is_late,
+                      const Object& owner,
+                      const AbstractType& type,
+                      TokenPosition token_pos,
+                      TokenPosition end_token_pos);
 
-  static RawField* NewTopLevel(const String& name,
-                               bool is_final,
-                               bool is_const,
-                               bool is_late,
-                               const Object& owner,
-                               TokenPosition token_pos,
-                               TokenPosition end_token_pos);
+  static FieldPtr NewTopLevel(const String& name,
+                              bool is_final,
+                              bool is_const,
+                              bool is_late,
+                              const Object& owner,
+                              TokenPosition token_pos,
+                              TokenPosition end_token_pos);
 
   // Allocate new field object, clone values from this field. The
   // original is specified.
-  RawField* Clone(const Field& original) const;
+  FieldPtr Clone(const Field& original) const;
 
-  static intptr_t kind_bits_offset() { return OFFSET_OF(RawField, kind_bits_); }
+  static intptr_t kind_bits_offset() {
+    return OFFSET_OF(FieldLayout, kind_bits_);
+  }
 
   TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   TokenPosition end_token_pos() const { return raw_ptr()->end_token_pos_; }
 
   int32_t SourceFingerprint() const;
 
-  RawString* InitializingExpression() const;
+  StringPtr InitializingExpression() const;
 
   bool has_nontrivial_initializer() const {
     return HasNontrivialInitializerBit::decode(raw_ptr()->kind_bits_);
@@ -4055,15 +4075,7 @@
   }
 
   static intptr_t static_type_exactness_state_offset() {
-    return OFFSET_OF(RawField, static_type_exactness_state_);
-  }
-
-  static inline intptr_t TargetOffsetOf(const RawField* field) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-    return field->ptr()->target_offset_;
-#else
-    return field->ptr()->host_offset_or_field_id_;
-#endif  //  !defined(DART_PRECOMPILED_RUNTIME)
+    return OFFSET_OF(FieldLayout, static_type_exactness_state_);
   }
 
   // Return class id that any non-null value read from this field is guaranteed
@@ -4091,7 +4103,7 @@
     StoreNonPointer(&raw_ptr()->guarded_cid_, cid);
   }
   static intptr_t guarded_cid_offset() {
-    return OFFSET_OF(RawField, guarded_cid_);
+    return OFFSET_OF(FieldLayout, guarded_cid_);
   }
   // Return the list length that any list stored in this field is guaranteed
   // to have. If length is kUnknownFixedLength the length has not
@@ -4100,12 +4112,12 @@
   intptr_t guarded_list_length() const;
   void set_guarded_list_length(intptr_t list_length) const;
   static intptr_t guarded_list_length_offset() {
-    return OFFSET_OF(RawField, guarded_list_length_);
+    return OFFSET_OF(FieldLayout, guarded_list_length_);
   }
   intptr_t guarded_list_length_in_object_offset() const;
   void set_guarded_list_length_in_object_offset(intptr_t offset) const;
   static intptr_t guarded_list_length_in_object_offset_offset() {
-    return OFFSET_OF(RawField, guarded_list_length_in_object_offset_);
+    return OFFSET_OF(FieldLayout, guarded_list_length_in_object_offset_);
   }
 
   bool needs_length_check() const {
@@ -4117,6 +4129,10 @@
   bool NeedsSetter() const;
   bool NeedsGetter() const;
 
+  bool NeedsInitializationCheckOnLoad() const {
+    return needs_load_guard() || (is_late() && !has_trivial_initializer());
+  }
+
   const char* GuardedPropertiesAsCString() const;
 
   intptr_t UnboxedFieldCid() const { return guarded_cid(); }
@@ -4167,7 +4183,7 @@
     StoreNonPointer(&raw_ptr()->is_nullable_, val ? kNullCid : kIllegalCid);
   }
   static intptr_t is_nullable_offset() {
-    return OFFSET_OF(RawField, is_nullable_);
+    return OFFSET_OF(FieldLayout, is_nullable_);
   }
 
   // Record store of the given value into this field. May trigger
@@ -4180,7 +4196,7 @@
   // assumptions about guarded class id and nullability of this field.
   // These code objects must be deoptimized when field's properties change.
   // Code objects are held weakly via an indirection through WeakProperty.
-  RawArray* dependent_code() const;
+  ArrayPtr dependent_code() const;
   void set_dependent_code(const Array& array) const;
 
   // Add the given code object to the list of dependent ones.
@@ -4196,44 +4212,47 @@
   bool IsUninitialized() const;
 
   // Run initializer and set field value.
-  DART_WARN_UNUSED_RESULT RawError* InitializeInstance(
-      const Instance& instance) const;
-  DART_WARN_UNUSED_RESULT RawError* InitializeStatic() const;
+  DART_WARN_UNUSED_RESULT ErrorPtr
+  InitializeInstance(const Instance& instance) const;
+  DART_WARN_UNUSED_RESULT ErrorPtr InitializeStatic() const;
 
   // Run initializer only.
-  DART_WARN_UNUSED_RESULT RawObject* EvaluateInitializer() const;
+  DART_WARN_UNUSED_RESULT ObjectPtr EvaluateInitializer() const;
 
-  RawFunction* EnsureInitializerFunction() const;
-  RawFunction* InitializerFunction() const {
+  FunctionPtr EnsureInitializerFunction() const;
+  FunctionPtr InitializerFunction() const {
     return raw_ptr()->initializer_function_;
   }
   void SetInitializerFunction(const Function& initializer) const;
   bool HasInitializerFunction() const;
+  static intptr_t initializer_function_offset() {
+    return OFFSET_OF(FieldLayout, initializer_function_);
+  }
 
   // For static fields only. Constructs a closure that gets/sets the
   // field value.
-  RawInstance* GetterClosure() const;
-  RawInstance* SetterClosure() const;
-  RawInstance* AccessorClosure(bool make_setter) const;
+  InstancePtr GetterClosure() const;
+  InstancePtr SetterClosure() const;
+  InstancePtr AccessorClosure(bool make_setter) const;
 
   // Constructs getter and setter names for fields and vice versa.
-  static RawString* GetterName(const String& field_name);
-  static RawString* GetterSymbol(const String& field_name);
+  static StringPtr GetterName(const String& field_name);
+  static StringPtr GetterSymbol(const String& field_name);
   // Returns String::null() if getter symbol does not exist.
-  static RawString* LookupGetterSymbol(const String& field_name);
-  static RawString* SetterName(const String& field_name);
-  static RawString* SetterSymbol(const String& field_name);
+  static StringPtr LookupGetterSymbol(const String& field_name);
+  static StringPtr SetterName(const String& field_name);
+  static StringPtr SetterSymbol(const String& field_name);
   // Returns String::null() if setter symbol does not exist.
-  static RawString* LookupSetterSymbol(const String& field_name);
-  static RawString* NameFromGetter(const String& getter_name);
-  static RawString* NameFromSetter(const String& setter_name);
-  static RawString* NameFromInit(const String& init_name);
+  static StringPtr LookupSetterSymbol(const String& field_name);
+  static StringPtr NameFromGetter(const String& getter_name);
+  static StringPtr NameFromSetter(const String& setter_name);
+  static StringPtr NameFromInit(const String& init_name);
   static bool IsGetterName(const String& function_name);
   static bool IsSetterName(const String& function_name);
   static bool IsInitName(const String& function_name);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  RawSubtypeTestCache* type_test_cache() const {
+  SubtypeTestCachePtr type_test_cache() const {
     return raw_ptr()->type_test_cache_;
   }
   void set_type_test_cache(const SubtypeTestCache& cache) const;
@@ -4339,29 +4358,29 @@
     StoreNonPointer(&raw_ptr()->kind_bits_, value);
   }
 
-  static RawField* New();
+  static FieldPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Field, Object);
   friend class Class;
   friend class HeapProfiler;
-  friend class RawField;
+  friend class FieldLayout;
   friend class FieldSerializationCluster;
   friend class FieldDeserializationCluster;
 };
 
 class Script : public Object {
  public:
-  RawString* url() const { return raw_ptr()->url_; }
+  StringPtr url() const { return raw_ptr()->url_; }
   void set_url(const String& value) const;
 
   // The actual url which was loaded from disk, if provided by the embedder.
-  RawString* resolved_url() const { return raw_ptr()->resolved_url_; }
+  StringPtr resolved_url() const { return raw_ptr()->resolved_url_; }
   bool HasSource() const;
-  RawString* Source() const;
+  StringPtr Source() const;
   bool IsPartOfDartColonLibrary() const;
 
   void LookupSourceAndLineStarts(Zone* zone) const;
-  RawGrowableObjectArray* GenerateLineNumberArray() const;
+  GrowableObjectArrayPtr GenerateLineNumberArray() const;
 
   intptr_t line_offset() const { return raw_ptr()->line_offset_; }
   intptr_t col_offset() const { return raw_ptr()->col_offset_; }
@@ -4369,12 +4388,12 @@
   // The load time in milliseconds since epoch.
   int64_t load_timestamp() const { return raw_ptr()->load_timestamp_; }
 
-  RawArray* compile_time_constants() const {
+  ArrayPtr compile_time_constants() const {
     return raw_ptr()->compile_time_constants_;
   }
   void set_compile_time_constants(const Array& value) const;
 
-  RawKernelProgramInfo* kernel_program_info() const {
+  KernelProgramInfoPtr kernel_program_info() const {
     return raw_ptr()->kernel_program_info_;
   }
   void set_kernel_program_info(const KernelProgramInfo& info) const;
@@ -4384,22 +4403,21 @@
   }
   void set_kernel_script_index(const intptr_t kernel_script_index) const;
 
-  RawTypedData* kernel_string_offsets() const;
+  TypedDataPtr kernel_string_offsets() const;
 
-  RawTypedData* line_starts() const;
+  TypedDataPtr line_starts() const;
 
   void set_line_starts(const TypedData& value) const;
 
   void set_debug_positions(const Array& value) const;
 
-  RawLibrary* FindLibrary() const;
-  RawString* GetLine(intptr_t line_number,
-                     Heap::Space space = Heap::kNew) const;
-  RawString* GetSnippet(TokenPosition from, TokenPosition to) const;
-  RawString* GetSnippet(intptr_t from_line,
-                        intptr_t from_column,
-                        intptr_t to_line,
-                        intptr_t to_column) const;
+  LibraryPtr FindLibrary() const;
+  StringPtr GetLine(intptr_t line_number, Heap::Space space = Heap::kNew) const;
+  StringPtr GetSnippet(TokenPosition from, TokenPosition to) const;
+  StringPtr GetSnippet(intptr_t from_line,
+                       intptr_t from_column,
+                       intptr_t to_line,
+                       intptr_t to_column) const;
 
   void SetLocationOffset(intptr_t line_offset, intptr_t col_offset) const;
 
@@ -4418,14 +4436,14 @@
                         TokenPosition* last_token_index) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawScript));
+    return RoundedAllocationSize(sizeof(ScriptLayout));
   }
 
-  static RawScript* New(const String& url, const String& source);
+  static ScriptPtr New(const String& url, const String& source);
 
-  static RawScript* New(const String& url,
-                        const String& resolved_url,
-                        const String& source);
+  static ScriptPtr New(const String& url,
+                       const String& resolved_url,
+                       const String& source);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   void LoadSourceFromKernel(const uint8_t* kernel_buffer,
@@ -4440,9 +4458,9 @@
   void set_source(const String& value) const;
   void set_flags(uint8_t value) const;
   void set_load_timestamp(int64_t value) const;
-  RawArray* debug_positions() const;
+  ArrayPtr debug_positions() const;
 
-  static RawScript* New();
+  static ScriptPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Script, Object);
   friend class Class;
@@ -4456,7 +4474,7 @@
   bool HasNext() const { return next_ix_ < size_; }
 
   // Returns next non-null raw object.
-  RawObject* GetNext();
+  ObjectPtr GetNext();
 
  private:
   void MoveToNextObject();
@@ -4487,7 +4505,7 @@
   }
 
   // Returns a non-null raw class.
-  RawClass* GetNextClass();
+  ClassPtr GetNextClass();
 
  private:
   void MoveToNextClass();
@@ -4500,7 +4518,7 @@
 class LibraryPrefixIterator : public DictionaryIterator {
  public:
   explicit LibraryPrefixIterator(const Library& library);
-  RawLibraryPrefix* GetNext();
+  LibraryPrefixPtr GetNext();
 
  private:
   void Advance();
@@ -4509,51 +4527,53 @@
 
 class Library : public Object {
  public:
-  RawString* name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name_; }
   void SetName(const String& name) const;
 
-  RawString* url() const { return raw_ptr()->url_; }
-  RawString* private_key() const { return raw_ptr()->private_key_; }
+  StringPtr url() const { return raw_ptr()->url_; }
+  StringPtr private_key() const { return raw_ptr()->private_key_; }
   bool LoadNotStarted() const {
-    return raw_ptr()->load_state_ == RawLibrary::kAllocated;
+    return raw_ptr()->load_state_ == LibraryLayout::kAllocated;
   }
   bool LoadRequested() const {
-    return raw_ptr()->load_state_ == RawLibrary::kLoadRequested;
+    return raw_ptr()->load_state_ == LibraryLayout::kLoadRequested;
   }
   bool LoadInProgress() const {
-    return raw_ptr()->load_state_ == RawLibrary::kLoadInProgress;
+    return raw_ptr()->load_state_ == LibraryLayout::kLoadInProgress;
   }
   void SetLoadRequested() const;
   void SetLoadInProgress() const;
-  bool Loaded() const { return raw_ptr()->load_state_ == RawLibrary::kLoaded; }
+  bool Loaded() const {
+    return raw_ptr()->load_state_ == LibraryLayout::kLoaded;
+  }
   void SetLoaded() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawLibrary));
+    return RoundedAllocationSize(sizeof(LibraryLayout));
   }
 
-  static RawLibrary* New(const String& url);
+  static LibraryPtr New(const String& url);
 
-  RawObject* Invoke(const String& selector,
-                    const Array& arguments,
-                    const Array& argument_names,
-                    bool respect_reflectable = true,
-                    bool check_is_entrypoint = false) const;
-  RawObject* InvokeGetter(const String& selector,
-                          bool throw_nsm_if_absent,
-                          bool respect_reflectable = true,
-                          bool check_is_entrypoint = false) const;
-  RawObject* InvokeSetter(const String& selector,
-                          const Instance& argument,
-                          bool respect_reflectable = true,
-                          bool check_is_entrypoint = false) const;
+  ObjectPtr Invoke(const String& selector,
+                   const Array& arguments,
+                   const Array& argument_names,
+                   bool respect_reflectable = true,
+                   bool check_is_entrypoint = false) const;
+  ObjectPtr InvokeGetter(const String& selector,
+                         bool throw_nsm_if_absent,
+                         bool respect_reflectable = true,
+                         bool check_is_entrypoint = false) const;
+  ObjectPtr InvokeSetter(const String& selector,
+                         const Instance& argument,
+                         bool respect_reflectable = true,
+                         bool check_is_entrypoint = false) const;
 
   // Evaluate the given expression as if it appeared in an top-level method of
   // this library and return the resulting value, or an error object if
   // evaluating the expression fails. The method has the formal (type)
   // parameters given in (type_)param_names, and is invoked with the (type)
   // argument values given in (type_)param_values.
-  RawObject* EvaluateCompiledExpression(
+  ObjectPtr EvaluateCompiledExpression(
       const ExternalTypedData& kernel_buffer,
       const Array& type_definitions,
       const Array& param_values,
@@ -4566,20 +4586,20 @@
   // more regular.
   void AddClass(const Class& cls) const;
   void AddObject(const Object& obj, const String& name) const;
-  RawObject* LookupReExport(const String& name,
-                            ZoneGrowableArray<intptr_t>* visited = NULL) const;
-  RawObject* LookupObjectAllowPrivate(const String& name) const;
-  RawObject* LookupLocalOrReExportObject(const String& name) const;
-  RawObject* LookupImportedObject(const String& name) const;
-  RawClass* LookupClass(const String& name) const;
-  RawClass* LookupClassAllowPrivate(const String& name) const;
-  RawClass* SlowLookupClassAllowMultiPartPrivate(const String& name) const;
-  RawClass* LookupLocalClass(const String& name) const;
-  RawField* LookupFieldAllowPrivate(const String& name) const;
-  RawField* LookupLocalField(const String& name) const;
-  RawFunction* LookupFunctionAllowPrivate(const String& name) const;
-  RawFunction* LookupLocalFunction(const String& name) const;
-  RawLibraryPrefix* LookupLocalLibraryPrefix(const String& name) const;
+  ObjectPtr LookupReExport(const String& name,
+                           ZoneGrowableArray<intptr_t>* visited = NULL) const;
+  ObjectPtr LookupObjectAllowPrivate(const String& name) const;
+  ObjectPtr LookupLocalOrReExportObject(const String& name) const;
+  ObjectPtr LookupImportedObject(const String& name) const;
+  ClassPtr LookupClass(const String& name) const;
+  ClassPtr LookupClassAllowPrivate(const String& name) const;
+  ClassPtr SlowLookupClassAllowMultiPartPrivate(const String& name) const;
+  ClassPtr LookupLocalClass(const String& name) const;
+  FieldPtr LookupFieldAllowPrivate(const String& name) const;
+  FieldPtr LookupLocalField(const String& name) const;
+  FunctionPtr LookupFunctionAllowPrivate(const String& name) const;
+  FunctionPtr LookupLocalFunction(const String& name) const;
+  LibraryPrefixPtr LookupLocalLibraryPrefix(const String& name) const;
 
   // Look up a Script based on a url. If 'useResolvedUri' is not provided or is
   // false, 'url' should have a 'dart:' scheme for Dart core libraries,
@@ -4587,8 +4607,8 @@
   //
   // If 'useResolvedUri' is true, 'url' should have a 'org-dartlang-sdk:' scheme
   // for Dart core libraries and a 'file:' scheme otherwise.
-  RawScript* LookupScript(const String& url, bool useResolvedUri = false) const;
-  RawArray* LoadedScripts() const;
+  ScriptPtr LookupScript(const String& url, bool useResolvedUri = false) const;
+  ArrayPtr LoadedScripts() const;
 
   // Resolve name in the scope of this library. First check the cache
   // of already resolved names for this library. Then look in the
@@ -4597,7 +4617,7 @@
   // If the local dictionary contains no entry for these names,
   // look in the scopes of all libraries that are imported
   // without a library prefix.
-  RawObject* ResolveName(const String& name) const;
+  ObjectPtr ResolveName(const String& name) const;
 
   void AddAnonymousClass(const Class& cls) const;
 
@@ -4625,8 +4645,8 @@
   void CloneMetadataFrom(const Library& from_library,
                          const Function& from_fun,
                          const Function& to_fun) const;
-  RawObject* GetMetadata(const Object& obj) const;
-  RawArray* GetExtendedMetadata(const Object& obj, intptr_t count) const;
+  ObjectPtr GetMetadata(const Object& obj) const;
+  ArrayPtr GetExtendedMetadata(const Object& obj, intptr_t count) const;
 
   // Tries to finds a @pragma annotation on [object].
   //
@@ -4644,32 +4664,32 @@
                          const String& pragma_name,
                          Object* options);
 
-  RawClass* toplevel_class() const { return raw_ptr()->toplevel_class_; }
+  ClassPtr toplevel_class() const { return raw_ptr()->toplevel_class_; }
   void set_toplevel_class(const Class& value) const;
 
-  RawGrowableObjectArray* used_scripts() const {
+  GrowableObjectArrayPtr used_scripts() const {
     return raw_ptr()->used_scripts_;
   }
 
   // Library imports.
-  RawArray* imports() const { return raw_ptr()->imports_; }
-  RawArray* exports() const { return raw_ptr()->exports_; }
+  ArrayPtr imports() const { return raw_ptr()->imports_; }
+  ArrayPtr exports() const { return raw_ptr()->exports_; }
   void AddImport(const Namespace& ns) const;
   intptr_t num_imports() const { return raw_ptr()->num_imports_; }
-  RawNamespace* ImportAt(intptr_t index) const;
-  RawLibrary* ImportLibraryAt(intptr_t index) const;
+  NamespacePtr ImportAt(intptr_t index) const;
+  LibraryPtr ImportLibraryAt(intptr_t index) const;
 
   void DropDependenciesAndCaches() const;
 
   // Resolving native methods for script loaded in the library.
   Dart_NativeEntryResolver native_entry_resolver() const {
-    return raw_ptr()->native_entry_resolver_;
+    return LoadNonPointer(&raw_ptr()->native_entry_resolver_);
   }
   void set_native_entry_resolver(Dart_NativeEntryResolver value) const {
     StoreNonPointer(&raw_ptr()->native_entry_resolver_, value);
   }
   Dart_NativeEntrySymbol native_entry_symbol_resolver() const {
-    return raw_ptr()->native_entry_symbol_resolver_;
+    return LoadNonPointer(&raw_ptr()->native_entry_symbol_resolver_);
   }
   void set_native_entry_symbol_resolver(
       Dart_NativeEntrySymbol native_symbol_resolver) const {
@@ -4678,17 +4698,18 @@
   }
 
   bool is_in_fullsnapshot() const {
-    return RawLibrary::InFullSnapshotBit::decode(raw_ptr()->flags_);
+    return LibraryLayout::InFullSnapshotBit::decode(raw_ptr()->flags_);
   }
   void set_is_in_fullsnapshot(bool value) const {
-    set_flags(RawLibrary::InFullSnapshotBit::update(value, raw_ptr()->flags_));
+    set_flags(
+        LibraryLayout::InFullSnapshotBit::update(value, raw_ptr()->flags_));
   }
 
   bool is_nnbd() const {
-    return RawLibrary::NnbdBit::decode(raw_ptr()->flags_);
+    return LibraryLayout::NnbdBit::decode(raw_ptr()->flags_);
   }
   void set_is_nnbd(bool value) const {
-    set_flags(RawLibrary::NnbdBit::update(value, raw_ptr()->flags_));
+    set_flags(LibraryLayout::NnbdBit::update(value, raw_ptr()->flags_));
   }
 
   NNBDMode nnbd_mode() const {
@@ -4697,14 +4718,14 @@
 
   NNBDCompiledMode nnbd_compiled_mode() const {
     return static_cast<NNBDCompiledMode>(
-        RawLibrary::NnbdCompiledModeBits::decode(raw_ptr()->flags_));
+        LibraryLayout::NnbdCompiledModeBits::decode(raw_ptr()->flags_));
   }
   void set_nnbd_compiled_mode(NNBDCompiledMode value) const {
-    set_flags(RawLibrary::NnbdCompiledModeBits::update(
+    set_flags(LibraryLayout::NnbdCompiledModeBits::update(
         static_cast<uint8_t>(value), raw_ptr()->flags_));
   }
 
-  RawString* PrivateName(const String& name) const;
+  StringPtr PrivateName(const String& name) const;
 
   intptr_t index() const { return raw_ptr()->index_; }
   void set_index(intptr_t value) const {
@@ -4716,17 +4737,17 @@
                                 const GrowableObjectArray& libs);
 
   bool IsDebuggable() const {
-    return RawLibrary::DebuggableBit::decode(raw_ptr()->flags_);
+    return LibraryLayout::DebuggableBit::decode(raw_ptr()->flags_);
   }
   void set_debuggable(bool value) const {
-    set_flags(RawLibrary::DebuggableBit::update(value, raw_ptr()->flags_));
+    set_flags(LibraryLayout::DebuggableBit::update(value, raw_ptr()->flags_));
   }
 
   bool is_dart_scheme() const {
-    return RawLibrary::DartSchemeBit::decode(raw_ptr()->flags_);
+    return LibraryLayout::DartSchemeBit::decode(raw_ptr()->flags_);
   }
   void set_is_dart_scheme(bool value) const {
-    set_flags(RawLibrary::DartSchemeBit::update(value, raw_ptr()->flags_));
+    set_flags(LibraryLayout::DartSchemeBit::update(value, raw_ptr()->flags_));
   }
 
   // Includes 'dart:async', 'dart:typed_data', etc.
@@ -4734,18 +4755,18 @@
 
   inline intptr_t UrlHash() const;
 
-  RawExternalTypedData* kernel_data() const { return raw_ptr()->kernel_data_; }
+  ExternalTypedDataPtr kernel_data() const { return raw_ptr()->kernel_data_; }
   void set_kernel_data(const ExternalTypedData& data) const;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   intptr_t binary_declaration_offset() const {
-    return RawLibrary::BinaryDeclarationOffset::decode(
+    return LibraryLayout::BinaryDeclarationOffset::decode(
         raw_ptr()->binary_declaration_);
   }
   void set_binary_declaration_offset(intptr_t value) const {
     ASSERT(value >= 0);
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawLibrary::BinaryDeclarationOffset::update(
+                    LibraryLayout::BinaryDeclarationOffset::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -4790,7 +4811,7 @@
 #if defined(DART_PRECOMPILED_RUNTIME)
     return false;
 #else
-    return RawLibrary::IsDeclaredInBytecode::decode(
+    return LibraryLayout::IsDeclaredInBytecode::decode(
         raw_ptr()->binary_declaration_);
 #endif
   }
@@ -4798,42 +4819,42 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   void set_is_declared_in_bytecode(bool value) const {
     StoreNonPointer(&raw_ptr()->binary_declaration_,
-                    RawLibrary::IsDeclaredInBytecode::update(
+                    LibraryLayout::IsDeclaredInBytecode::update(
                         value, raw_ptr()->binary_declaration_));
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-  static RawLibrary* LookupLibrary(Thread* thread, const String& url);
-  static RawLibrary* GetLibrary(intptr_t index);
+  static LibraryPtr LookupLibrary(Thread* thread, const String& url);
+  static LibraryPtr GetLibrary(intptr_t index);
 
   static void InitCoreLibrary(Isolate* isolate);
   static void InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel_file);
 
-  static RawLibrary* AsyncLibrary();
-  static RawLibrary* ConvertLibrary();
-  static RawLibrary* CoreLibrary();
-  static RawLibrary* CollectionLibrary();
-  static RawLibrary* DeveloperLibrary();
-  static RawLibrary* FfiLibrary();
-  static RawLibrary* InternalLibrary();
-  static RawLibrary* IsolateLibrary();
-  static RawLibrary* MathLibrary();
+  static LibraryPtr AsyncLibrary();
+  static LibraryPtr ConvertLibrary();
+  static LibraryPtr CoreLibrary();
+  static LibraryPtr CollectionLibrary();
+  static LibraryPtr DeveloperLibrary();
+  static LibraryPtr FfiLibrary();
+  static LibraryPtr InternalLibrary();
+  static LibraryPtr IsolateLibrary();
+  static LibraryPtr MathLibrary();
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static RawLibrary* MirrorsLibrary();
+  static LibraryPtr MirrorsLibrary();
 #endif
-  static RawLibrary* NativeWrappersLibrary();
-  static RawLibrary* ProfilerLibrary();
-  static RawLibrary* TypedDataLibrary();
-  static RawLibrary* VMServiceLibrary();
-  static RawLibrary* WasmLibrary();
+  static LibraryPtr NativeWrappersLibrary();
+  static LibraryPtr ProfilerLibrary();
+  static LibraryPtr TypedDataLibrary();
+  static LibraryPtr VMServiceLibrary();
+  static LibraryPtr WasmLibrary();
 
   // Eagerly compile all classes and functions in the library.
-  static RawError* CompileAll(bool ignore_error = false);
+  static ErrorPtr CompileAll(bool ignore_error = false);
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // Finalize all classes in all libraries.
-  static RawError* FinalizeAllClasses();
+  static ErrorPtr FinalizeAllClasses();
   // Eagerly read all bytecode.
-  static RawError* ReadAllBytecode();
+  static ErrorPtr ReadAllBytecode();
 #endif
 
 #if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
@@ -4852,12 +4873,12 @@
 
   // Lookup class in the core lib which also contains various VM
   // helper methods and classes. Allow look up of private classes.
-  static RawClass* LookupCoreClass(const String& class_name);
+  static ClassPtr LookupCoreClass(const String& class_name);
 
   // Return Function::null() if function does not exist in libs.
-  static RawFunction* GetFunction(const GrowableArray<Library*>& libs,
-                                  const char* class_name,
-                                  const char* function_name);
+  static FunctionPtr GetFunction(const GrowableArray<Library*>& libs,
+                                 const char* class_name,
+                                 const char* function_name);
 
   // Character used to indicate a private identifier.
   static const char kPrivateIdentifierStart = '_';
@@ -4872,7 +4893,7 @@
   // Returns a closure of top level function 'name' in the exported namespace
   // of this library. If a top level function 'name' does not exist we look
   // for a top level getter 'name' that returns a closure.
-  RawObject* GetFunctionClosure(const String& name) const;
+  ObjectPtr GetFunctionClosure(const String& name) const;
 
   // Ensures that all top-level functions and variables (fields) are loaded.
   void EnsureTopLevelClassIsFinalized() const;
@@ -4881,7 +4902,7 @@
   static const int kInitialImportsCapacity = 4;
   static const int kImportsCapacityIncrement = 8;
 
-  static RawLibrary* New();
+  static LibraryPtr New();
 
   // These methods are only used by the Precompiler to obfuscate
   // the name and url.
@@ -4891,13 +4912,13 @@
   void set_num_imports(intptr_t value) const;
   void set_flags(uint8_t flags) const;
   bool HasExports() const;
-  RawArray* loaded_scripts() const { return raw_ptr()->loaded_scripts_; }
-  RawGrowableObjectArray* metadata() const { return raw_ptr()->metadata_; }
+  ArrayPtr loaded_scripts() const { return raw_ptr()->loaded_scripts_; }
+  GrowableObjectArrayPtr metadata() const { return raw_ptr()->metadata_; }
   void set_metadata(const GrowableObjectArray& value) const;
-  RawArray* dictionary() const { return raw_ptr()->dictionary_; }
+  ArrayPtr dictionary() const { return raw_ptr()->dictionary_; }
   void InitClassDictionary() const;
 
-  RawArray* resolved_names() const { return raw_ptr()->resolved_names_; }
+  ArrayPtr resolved_names() const { return raw_ptr()->resolved_names_; }
   bool LookupResolvedNamesCache(const String& name, Object* obj) const;
   void AddToResolvedNamesCache(const String& name, const Object& obj) const;
   void InitResolvedNamesCache() const;
@@ -4905,7 +4926,7 @@
   void InvalidateResolvedName(const String& name) const;
   void InvalidateResolvedNamesCache() const;
 
-  RawArray* exported_names() const { return raw_ptr()->exported_names_; }
+  ArrayPtr exported_names() const { return raw_ptr()->exported_names_; }
   bool LookupExportedNamesCache(const String& name, Object* obj) const;
   void AddToExportedNamesCache(const String& name, const Object& obj) const;
   void InitExportedNamesCache() const;
@@ -4914,15 +4935,15 @@
 
   void InitImportList() const;
   void RehashDictionary(const Array& old_dict, intptr_t new_dict_size) const;
-  static RawLibrary* NewLibraryHelper(const String& url, bool import_core_lib);
-  RawObject* LookupEntry(const String& name, intptr_t* index) const;
-  RawObject* LookupLocalObjectAllowPrivate(const String& name) const;
-  RawObject* LookupLocalObject(const String& name) const;
+  static LibraryPtr NewLibraryHelper(const String& url, bool import_core_lib);
+  ObjectPtr LookupEntry(const String& name, intptr_t* index) const;
+  ObjectPtr LookupLocalObjectAllowPrivate(const String& name) const;
+  ObjectPtr LookupLocalObject(const String& name) const;
 
   void AllocatePrivateKey() const;
 
-  RawString* MakeMetadataName(const Object& obj) const;
-  RawField* GetMetadataField(const String& metaname) const;
+  StringPtr MakeMetadataName(const Object& obj) const;
+  FieldPtr GetMetadataField(const String& metaname) const;
   void AddMetadata(const Object& owner,
                    const String& name,
                    TokenPosition token_pos,
@@ -4946,31 +4967,31 @@
 // the show/hide combinators.
 class Namespace : public Object {
  public:
-  RawLibrary* library() const { return raw_ptr()->library_; }
-  RawArray* show_names() const { return raw_ptr()->show_names_; }
-  RawArray* hide_names() const { return raw_ptr()->hide_names_; }
+  LibraryPtr library() const { return raw_ptr()->library_; }
+  ArrayPtr show_names() const { return raw_ptr()->show_names_; }
+  ArrayPtr hide_names() const { return raw_ptr()->hide_names_; }
 
   void AddMetadata(const Object& owner,
                    TokenPosition token_pos,
                    intptr_t kernel_offset = 0);
-  RawObject* GetMetadata() const;
+  ObjectPtr GetMetadata() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawNamespace));
+    return RoundedAllocationSize(sizeof(NamespaceLayout));
   }
 
   bool HidesName(const String& name) const;
-  RawObject* Lookup(const String& name,
-                    ZoneGrowableArray<intptr_t>* trail = NULL) const;
+  ObjectPtr Lookup(const String& name,
+                   ZoneGrowableArray<intptr_t>* trail = NULL) const;
 
-  static RawNamespace* New(const Library& library,
-                           const Array& show_names,
-                           const Array& hide_names);
+  static NamespacePtr New(const Library& library,
+                          const Array& show_names,
+                          const Array& hide_names);
 
  private:
-  static RawNamespace* New();
+  static NamespacePtr New();
 
-  RawField* metadata_field() const { return raw_ptr()->metadata_field_; }
+  FieldPtr metadata_field() const { return raw_ptr()->metadata_field_; }
   void set_metadata_field(const Field& value) const;
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Namespace, Object);
@@ -4980,46 +5001,46 @@
 
 class KernelProgramInfo : public Object {
  public:
-  static RawKernelProgramInfo* New(const TypedData& string_offsets,
-                                   const ExternalTypedData& string_data,
-                                   const TypedData& canonical_names,
-                                   const ExternalTypedData& metadata_payload,
-                                   const ExternalTypedData& metadata_mappings,
-                                   const ExternalTypedData& constants_table,
-                                   const Array& scripts,
-                                   const Array& libraries_cache,
-                                   const Array& classes_cache,
-                                   const Object& retained_kernel_blob,
-                                   const uint32_t binary_version);
+  static KernelProgramInfoPtr New(const TypedData& string_offsets,
+                                  const ExternalTypedData& string_data,
+                                  const TypedData& canonical_names,
+                                  const ExternalTypedData& metadata_payload,
+                                  const ExternalTypedData& metadata_mappings,
+                                  const ExternalTypedData& constants_table,
+                                  const Array& scripts,
+                                  const Array& libraries_cache,
+                                  const Array& classes_cache,
+                                  const Object& retained_kernel_blob,
+                                  const uint32_t binary_version);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawKernelProgramInfo));
+    return RoundedAllocationSize(sizeof(KernelProgramInfoLayout));
   }
 
-  RawTypedData* string_offsets() const { return raw_ptr()->string_offsets_; }
+  TypedDataPtr string_offsets() const { return raw_ptr()->string_offsets_; }
 
-  RawExternalTypedData* string_data() const { return raw_ptr()->string_data_; }
+  ExternalTypedDataPtr string_data() const { return raw_ptr()->string_data_; }
 
-  RawTypedData* canonical_names() const { return raw_ptr()->canonical_names_; }
+  TypedDataPtr canonical_names() const { return raw_ptr()->canonical_names_; }
 
-  RawExternalTypedData* metadata_payloads() const {
+  ExternalTypedDataPtr metadata_payloads() const {
     return raw_ptr()->metadata_payloads_;
   }
 
-  RawExternalTypedData* metadata_mappings() const {
+  ExternalTypedDataPtr metadata_mappings() const {
     return raw_ptr()->metadata_mappings_;
   }
 
-  RawExternalTypedData* constants_table() const {
+  ExternalTypedDataPtr constants_table() const {
     return raw_ptr()->constants_table_;
   }
 
   void set_constants_table(const ExternalTypedData& value) const;
 
-  RawArray* scripts() const { return raw_ptr()->scripts_; }
+  ArrayPtr scripts() const { return raw_ptr()->scripts_; }
   void set_scripts(const Array& scripts) const;
 
-  RawArray* constants() const { return raw_ptr()->constants_; }
+  ArrayPtr constants() const { return raw_ptr()->constants_; }
   void set_constants(const Array& constants) const;
 
   uint32_t kernel_binary_version() const {
@@ -5032,40 +5053,38 @@
   // (since native names are encoded as constants).
   //
   // This array will hold the functions which might need their native name set.
-  RawGrowableObjectArray* potential_natives() const {
+  GrowableObjectArrayPtr potential_natives() const {
     return raw_ptr()->potential_natives_;
   }
   void set_potential_natives(const GrowableObjectArray& candidates) const;
 
-  RawGrowableObjectArray* potential_pragma_functions() const {
+  GrowableObjectArrayPtr potential_pragma_functions() const {
     return raw_ptr()->potential_pragma_functions_;
   }
   void set_potential_pragma_functions(
       const GrowableObjectArray& candidates) const;
 
-  RawScript* ScriptAt(intptr_t index) const;
+  ScriptPtr ScriptAt(intptr_t index) const;
 
-  RawArray* libraries_cache() const { return raw_ptr()->libraries_cache_; }
+  ArrayPtr libraries_cache() const { return raw_ptr()->libraries_cache_; }
   void set_libraries_cache(const Array& cache) const;
-  RawLibrary* LookupLibrary(Thread* thread, const Smi& name_index) const;
-  RawLibrary* InsertLibrary(Thread* thread,
-                            const Smi& name_index,
-                            const Library& lib) const;
+  LibraryPtr LookupLibrary(Thread* thread, const Smi& name_index) const;
+  LibraryPtr InsertLibrary(Thread* thread,
+                           const Smi& name_index,
+                           const Library& lib) const;
 
-  RawArray* classes_cache() const { return raw_ptr()->classes_cache_; }
+  ArrayPtr classes_cache() const { return raw_ptr()->classes_cache_; }
   void set_classes_cache(const Array& cache) const;
-  RawClass* LookupClass(Thread* thread, const Smi& name_index) const;
-  RawClass* InsertClass(Thread* thread,
-                        const Smi& name_index,
-                        const Class& klass) const;
+  ClassPtr LookupClass(Thread* thread, const Smi& name_index) const;
+  ClassPtr InsertClass(Thread* thread,
+                       const Smi& name_index,
+                       const Class& klass) const;
 
-  RawArray* bytecode_component() const {
-    return raw_ptr()->bytecode_component_;
-  }
+  ArrayPtr bytecode_component() const { return raw_ptr()->bytecode_component_; }
   void set_bytecode_component(const Array& bytecode_component) const;
 
  private:
-  static RawKernelProgramInfo* New();
+  static KernelProgramInfoPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo, Object);
   friend class Class;
@@ -5098,21 +5117,23 @@
     StoreNonPointer(&raw_ptr()->length_, value);
   }
 
-  static intptr_t length_offset() { return OFFSET_OF(RawObjectPool, length_); }
+  static intptr_t length_offset() {
+    return OFFSET_OF(ObjectPoolLayout, length_);
+  }
   static intptr_t data_offset() {
-    return OFFSET_OF_RETURNED_VALUE(RawObjectPool, data);
+    return OFFSET_OF_RETURNED_VALUE(ObjectPoolLayout, data);
   }
   static intptr_t element_offset(intptr_t index) {
-    return OFFSET_OF_RETURNED_VALUE(RawObjectPool, data) +
-           sizeof(RawObjectPool::Entry) * index;
+    return OFFSET_OF_RETURNED_VALUE(ObjectPoolLayout, data) +
+           sizeof(ObjectPoolLayout::Entry) * index;
   }
 
-  struct ArrayLayout {
+  struct ArrayTraits {
     static intptr_t elements_start_offset() {
       return ObjectPool::data_offset();
     }
 
-    static constexpr intptr_t kElementSize = sizeof(RawObjectPool::Entry);
+    static constexpr intptr_t kElementSize = sizeof(ObjectPoolLayout::Entry);
   };
 
   EntryType TypeAt(intptr_t index) const {
@@ -5129,7 +5150,7 @@
     StoreNonPointer(&raw_ptr()->entry_bits()[index], bits);
   }
 
-  RawObject* ObjectAt(intptr_t index) const {
+  ObjectPtr ObjectAt(intptr_t index) const {
     ASSERT((TypeAt(index) == EntryType::kTaggedObject) ||
            (TypeAt(index) == EntryType::kNativeEntryData));
     return EntryAddr(index)->raw_obj_;
@@ -5151,36 +5172,37 @@
   }
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawObjectPool) ==
-           OFFSET_OF_RETURNED_VALUE(RawObjectPool, data));
+    ASSERT(sizeof(ObjectPoolLayout) ==
+           OFFSET_OF_RETURNED_VALUE(ObjectPoolLayout, data));
     return 0;
   }
 
   static const intptr_t kBytesPerElement =
-      sizeof(RawObjectPool::Entry) + sizeof(uint8_t);
+      sizeof(ObjectPoolLayout::Entry) + sizeof(uint8_t);
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
 
   static intptr_t InstanceSize(intptr_t len) {
     // Ensure that variable length data is not adding to the object length.
-    ASSERT(sizeof(RawObjectPool) == (sizeof(RawObject) + (1 * kWordSize)));
+    ASSERT(sizeof(ObjectPoolLayout) ==
+           (sizeof(ObjectLayout) + (1 * kWordSize)));
     ASSERT(0 <= len && len <= kMaxElements);
-    return RoundedAllocationSize(sizeof(RawObjectPool) +
+    return RoundedAllocationSize(sizeof(ObjectPoolLayout) +
                                  (len * kBytesPerElement));
   }
 
-  static RawObjectPool* NewFromBuilder(
+  static ObjectPoolPtr NewFromBuilder(
       const compiler::ObjectPoolBuilder& builder);
-  static RawObjectPool* New(intptr_t len);
+  static ObjectPoolPtr New(intptr_t len);
 
   void CopyInto(compiler::ObjectPoolBuilder* builder) const;
 
-  // Returns the pool index from the offset relative to a tagged RawObjectPool*,
+  // Returns the pool index from the offset relative to a tagged ObjectPoolPtr,
   // adjusting for the tag-bit.
   static intptr_t IndexFromOffset(intptr_t offset) {
     ASSERT(
         Utils::IsAligned(offset + kHeapObjectTag, compiler::target::kWordSize));
     return (offset + kHeapObjectTag - data_offset()) /
-           sizeof(RawObjectPool::Entry);
+           sizeof(ObjectPoolLayout::Entry);
   }
 
   static intptr_t OffsetFromIndex(intptr_t index) {
@@ -5190,7 +5212,7 @@
   void DebugPrint() const;
 
  private:
-  RawObjectPool::Entry const* EntryAddr(intptr_t index) const {
+  ObjectPoolLayout::Entry const* EntryAddr(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
     return &raw_ptr()->data()[index];
   }
@@ -5198,7 +5220,7 @@
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object);
   friend class Class;
   friend class Object;
-  friend class RawObjectPool;
+  friend class ObjectPoolLayout;
 };
 
 class Instructions : public Object {
@@ -5215,21 +5237,21 @@
 
   // Excludes HeaderSize().
   intptr_t Size() const { return SizeBits::decode(raw_ptr()->size_and_flags_); }
-  static intptr_t Size(const RawInstructions* instr) {
+  static intptr_t Size(const InstructionsPtr instr) {
     return SizeBits::decode(instr->ptr()->size_and_flags_);
   }
 
   bool HasMonomorphicEntry() const {
     return FlagsBits::decode(raw_ptr()->size_and_flags_);
   }
-  static bool HasMonomorphicEntry(const RawInstructions* instr) {
+  static bool HasMonomorphicEntry(const InstructionsPtr instr) {
     return FlagsBits::decode(instr->ptr()->size_and_flags_);
   }
 
   uword PayloadStart() const { return PayloadStart(raw()); }
   uword MonomorphicEntryPoint() const { return MonomorphicEntryPoint(raw()); }
   uword EntryPoint() const { return EntryPoint(raw()); }
-  static uword PayloadStart(const RawInstructions* instr) {
+  static uword PayloadStart(const InstructionsPtr instr) {
     return reinterpret_cast<uword>(instr->ptr()) + HeaderSize();
   }
 
@@ -5259,7 +5281,7 @@
 #error Missing entry offsets for current architecture
 #endif
 
-  static uword MonomorphicEntryPoint(const RawInstructions* instr) {
+  static uword MonomorphicEntryPoint(const InstructionsPtr instr) {
     uword entry = PayloadStart(instr);
     if (HasMonomorphicEntry(instr)) {
       entry += !FLAG_precompiled_mode ? kMonomorphicEntryOffsetJIT
@@ -5268,7 +5290,7 @@
     return entry;
   }
 
-  static uword EntryPoint(const RawInstructions* instr) {
+  static uword EntryPoint(const InstructionsPtr instr) {
     uword entry = PayloadStart(instr);
     if (HasMonomorphicEntry(instr)) {
       entry += !FLAG_precompiled_mode ? kPolymorphicEntryOffsetJIT
@@ -5278,12 +5300,12 @@
   }
 
   static const intptr_t kMaxElements =
-      (kMaxInt32 - (sizeof(RawInstructions) + sizeof(RawObject) +
+      (kMaxInt32 - (sizeof(InstructionsLayout) + sizeof(ObjectLayout) +
                     (2 * kMaxObjectAlignment)));
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawInstructions) ==
-           OFFSET_OF_RETURNED_VALUE(RawInstructions, data));
+    ASSERT(sizeof(InstructionsLayout) ==
+           OFFSET_OF_RETURNED_VALUE(InstructionsLayout, data));
     return 0;
   }
 
@@ -5292,19 +5314,19 @@
   }
 
   static intptr_t HeaderSize() {
-    return Utils::RoundUp(sizeof(RawInstructions), kWordSize);
+    return Utils::RoundUp(sizeof(InstructionsLayout), kWordSize);
   }
 
-  static RawInstructions* FromPayloadStart(uword payload_start) {
-    return reinterpret_cast<RawInstructions*>(payload_start - HeaderSize() +
-                                              kHeapObjectTag);
+  static InstructionsPtr FromPayloadStart(uword payload_start) {
+    return static_cast<InstructionsPtr>(payload_start - HeaderSize() +
+                                        kHeapObjectTag);
   }
 
   bool Equals(const Instructions& other) const {
     return Equals(raw(), other.raw());
   }
 
-  static bool Equals(RawInstructions* a, RawInstructions* b) {
+  static bool Equals(InstructionsPtr a, InstructionsPtr b) {
     if (Size(a) != Size(b)) return false;
     NoSafepointScope no_safepoint;
     return memcmp(a->ptr(), b->ptr(), InstanceSize(Size(a))) == 0;
@@ -5329,7 +5351,7 @@
   // only be created using the Code::FinalizeCode method. This method creates
   // the RawInstruction and RawCode objects, sets up the pointer offsets
   // and links the two in a GC safe manner.
-  static RawInstructions* New(intptr_t size, bool has_monomorphic_entry);
+  static InstructionsPtr New(intptr_t size, bool has_monomorphic_entry);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object);
   friend class Class;
@@ -5345,12 +5367,12 @@
  public:
   // Excludes HeaderSize().
   intptr_t Size() const { return raw_ptr()->payload_length_; }
-  static intptr_t Size(const RawInstructionsSection* instr) {
+  static intptr_t Size(const InstructionsSectionPtr instr) {
     return instr->ptr()->payload_length_;
   }
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawInstructionsSection) ==
-           OFFSET_OF_RETURNED_VALUE(RawInstructionsSection, data));
+    ASSERT(sizeof(InstructionsSectionLayout) ==
+           OFFSET_OF_RETURNED_VALUE(InstructionsSectionLayout, data));
     return 0;
   }
 
@@ -5359,7 +5381,7 @@
   }
 
   static intptr_t HeaderSize() {
-    return Utils::RoundUp(sizeof(RawInstructionsSection), kWordSize);
+    return Utils::RoundUp(sizeof(InstructionsSectionLayout), kWordSize);
   }
 
  private:
@@ -5371,34 +5393,35 @@
  public:
   intptr_t Length() const;
 
-  RawString* GetName(intptr_t var_index) const;
+  StringPtr GetName(intptr_t var_index) const;
 
   void SetVar(intptr_t var_index,
               const String& name,
-              RawLocalVarDescriptors::VarInfo* info) const;
+              LocalVarDescriptorsLayout::VarInfo* info) const;
 
-  void GetInfo(intptr_t var_index, RawLocalVarDescriptors::VarInfo* info) const;
+  void GetInfo(intptr_t var_index,
+               LocalVarDescriptorsLayout::VarInfo* info) const;
 
   static const intptr_t kBytesPerElement =
-      sizeof(RawLocalVarDescriptors::VarInfo);
-  static const intptr_t kMaxElements = RawLocalVarDescriptors::kMaxIndex;
+      sizeof(LocalVarDescriptorsLayout::VarInfo);
+  static const intptr_t kMaxElements = LocalVarDescriptorsLayout::kMaxIndex;
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawLocalVarDescriptors) ==
-           OFFSET_OF_RETURNED_VALUE(RawLocalVarDescriptors, names));
+    ASSERT(sizeof(LocalVarDescriptorsLayout) ==
+           OFFSET_OF_RETURNED_VALUE(LocalVarDescriptorsLayout, names));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(0 <= len && len <= kMaxElements);
     return RoundedAllocationSize(
-        sizeof(RawLocalVarDescriptors) +
+        sizeof(LocalVarDescriptorsLayout) +
         (len * kWordSize)  // RawStrings for names.
-        + (len * sizeof(RawLocalVarDescriptors::VarInfo)));
+        + (len * sizeof(LocalVarDescriptorsLayout::VarInfo)));
   }
 
-  static RawLocalVarDescriptors* New(intptr_t num_variables);
+  static LocalVarDescriptorsPtr New(intptr_t num_variables);
 
-  static const char* KindToCString(RawLocalVarDescriptors::VarInfoKind kind);
+  static const char* KindToCString(LocalVarDescriptorsLayout::VarInfoKind kind);
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors, Object);
@@ -5411,15 +5434,15 @@
   static const intptr_t kBytesPerElement = 1;
   static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
 
-  static intptr_t UnroundedSize(RawPcDescriptors* desc) {
+  static intptr_t UnroundedSize(PcDescriptorsPtr desc) {
     return UnroundedSize(desc->ptr()->length_);
   }
   static intptr_t UnroundedSize(intptr_t len) {
-    return sizeof(RawPcDescriptors) + len;
+    return sizeof(PcDescriptorsLayout) + len;
   }
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawPcDescriptors) ==
-           OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data));
+    ASSERT(sizeof(PcDescriptorsLayout) ==
+           OFFSET_OF_RETURNED_VALUE(PcDescriptorsLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
@@ -5427,7 +5450,7 @@
     return RoundedAllocationSize(UnroundedSize(len));
   }
 
-  static RawPcDescriptors* New(GrowableArray<uint8_t>* delta_encoded_data);
+  static PcDescriptorsPtr New(GrowableArray<uint8_t>* delta_encoded_data);
 
   // Verify (assert) assumptions about pc descriptors in debug mode.
   void Verify(const Function& function) const;
@@ -5444,7 +5467,7 @@
 
   // We would have a VisitPointers function here to traverse the
   // pc descriptors table to visit objects if any in the table.
-  // Note: never return a reference to a RawPcDescriptors::PcDescriptorRec
+  // Note: never return a reference to a PcDescriptorsLayout::PcDescriptorRec
   // as the object can move.
   class Iterator : ValueObject {
    public:
@@ -5457,7 +5480,7 @@
           cur_deopt_id_(0),
           cur_token_pos_(0),
           cur_try_index_(0),
-          cur_yield_index_(RawPcDescriptors::kInvalidYieldIndex) {}
+          cur_yield_index_(PcDescriptorsLayout::kInvalidYieldIndex) {}
 
     bool MoveNext() {
       // Moves to record that matches kind_mask_.
@@ -5465,11 +5488,12 @@
         const int32_t kind_and_metadata =
             descriptors_.DecodeInteger(&byte_index_);
         cur_kind_ =
-            RawPcDescriptors::KindAndMetadata::DecodeKind(kind_and_metadata);
-        cur_try_index_ = RawPcDescriptors::KindAndMetadata::DecodeTryIndex(
+            PcDescriptorsLayout::KindAndMetadata::DecodeKind(kind_and_metadata);
+        cur_try_index_ = PcDescriptorsLayout::KindAndMetadata::DecodeTryIndex(
             kind_and_metadata);
-        cur_yield_index_ = RawPcDescriptors::KindAndMetadata::DecodeYieldIndex(
-            kind_and_metadata);
+        cur_yield_index_ =
+            PcDescriptorsLayout::KindAndMetadata::DecodeYieldIndex(
+                kind_and_metadata);
 
         cur_pc_offset_ += descriptors_.DecodeInteger(&byte_index_);
 
@@ -5490,8 +5514,8 @@
     TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); }
     intptr_t TryIndex() const { return cur_try_index_; }
     intptr_t YieldIndex() const { return cur_yield_index_; }
-    RawPcDescriptors::Kind Kind() const {
-      return static_cast<RawPcDescriptors::Kind>(cur_kind_);
+    PcDescriptorsLayout::Kind Kind() const {
+      return static_cast<PcDescriptorsLayout::Kind>(cur_kind_);
     }
 
    private:
@@ -5532,9 +5556,9 @@
   }
 
  private:
-  static const char* KindAsStr(RawPcDescriptors::Kind kind);
+  static const char* KindAsStr(PcDescriptorsLayout::Kind kind);
 
-  static RawPcDescriptors* New(intptr_t length);
+  static PcDescriptorsPtr New(intptr_t length);
 
   void SetLength(intptr_t value) const;
   void CopyData(GrowableArray<uint8_t>* data);
@@ -5549,15 +5573,15 @@
   static const intptr_t kBytesPerElement = 1;
   static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
 
-  static intptr_t UnroundedSize(RawCodeSourceMap* map) {
+  static intptr_t UnroundedSize(CodeSourceMapPtr map) {
     return UnroundedSize(map->ptr()->length_);
   }
   static intptr_t UnroundedSize(intptr_t len) {
-    return sizeof(RawCodeSourceMap) + len;
+    return sizeof(CodeSourceMapLayout) + len;
   }
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawCodeSourceMap) ==
-           OFFSET_OF_RETURNED_VALUE(RawCodeSourceMap, data));
+    ASSERT(sizeof(CodeSourceMapLayout) ==
+           OFFSET_OF_RETURNED_VALUE(CodeSourceMapLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
@@ -5565,7 +5589,7 @@
     return RoundedAllocationSize(UnroundedSize(len));
   }
 
-  static RawCodeSourceMap* New(intptr_t length);
+  static CodeSourceMapPtr New(intptr_t length);
 
   intptr_t Length() const { return raw_ptr()->length_; }
   uint8_t* Data() const {
@@ -5595,8 +5619,8 @@
   static const intptr_t kHashBits = 30;
 
   uintptr_t payload_size() const { return PayloadSizeOf(raw()); }
-  static uintptr_t PayloadSizeOf(const RawCompressedStackMaps* raw) {
-    return RawCompressedStackMaps::SizeField::decode(
+  static uintptr_t PayloadSizeOf(const CompressedStackMapsPtr raw) {
+    return CompressedStackMapsLayout::SizeField::decode(
         raw->ptr()->flags_and_size_);
   }
 
@@ -5614,15 +5638,15 @@
   bool Equals(const CompressedStackMaps* other) const { return Equals(*other); }
   intptr_t Hashcode() const;
 
-  static intptr_t UnroundedSize(RawCompressedStackMaps* maps) {
+  static intptr_t UnroundedSize(CompressedStackMapsPtr maps) {
     return UnroundedSize(CompressedStackMaps::PayloadSizeOf(maps));
   }
   static intptr_t UnroundedSize(intptr_t length) {
-    return sizeof(RawCompressedStackMaps) + length;
+    return sizeof(CompressedStackMapsLayout) + length;
   }
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawCompressedStackMaps) ==
-           OFFSET_OF_RETURNED_VALUE(RawCompressedStackMaps, data));
+    ASSERT(sizeof(CompressedStackMapsLayout) ==
+           OFFSET_OF_RETURNED_VALUE(CompressedStackMapsLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t length) {
@@ -5630,35 +5654,35 @@
   }
 
   bool UsesGlobalTable() const { return !IsNull() && UsesGlobalTable(raw()); }
-  static bool UsesGlobalTable(const RawCompressedStackMaps* raw) {
-    return RawCompressedStackMaps::UsesTableBit::decode(
+  static bool UsesGlobalTable(const CompressedStackMapsPtr raw) {
+    return CompressedStackMapsLayout::UsesTableBit::decode(
         raw->ptr()->flags_and_size_);
   }
 
   bool IsGlobalTable() const { return !IsNull() && IsGlobalTable(raw()); }
-  static bool IsGlobalTable(const RawCompressedStackMaps* raw) {
-    return RawCompressedStackMaps::GlobalTableBit::decode(
+  static bool IsGlobalTable(const CompressedStackMapsPtr raw) {
+    return CompressedStackMapsLayout::GlobalTableBit::decode(
         raw->ptr()->flags_and_size_);
   }
 
-  static RawCompressedStackMaps* NewInlined(
+  static CompressedStackMapsPtr NewInlined(
       const GrowableArray<uint8_t>& bytes) {
     return New(bytes, /*is_global_table=*/false, /*uses_global_table=*/false);
   }
-  static RawCompressedStackMaps* NewUsingTable(
+  static CompressedStackMapsPtr NewUsingTable(
       const GrowableArray<uint8_t>& bytes) {
     return New(bytes, /*is_global_table=*/false, /*uses_global_table=*/true);
   }
 
-  static RawCompressedStackMaps* NewGlobalTable(
+  static CompressedStackMapsPtr NewGlobalTable(
       const GrowableArray<uint8_t>& bytes) {
     return New(bytes, /*is_global_table=*/true, /*uses_global_table=*/false);
   }
 
  private:
-  static RawCompressedStackMaps* New(const GrowableArray<uint8_t>& bytes,
-                                     bool is_global_table,
-                                     bool uses_global_table);
+  static CompressedStackMapsPtr New(const GrowableArray<uint8_t>& bytes,
+                                    bool is_global_table,
+                                    bool uses_global_table);
 
   uint8_t PayloadByte(uintptr_t offset) const {
     ASSERT(offset < payload_size());
@@ -5691,22 +5715,22 @@
                       bool has_catch_all,
                       bool is_generated) const;
 
-  RawArray* GetHandledTypes(intptr_t try_index) const;
+  ArrayPtr GetHandledTypes(intptr_t try_index) const;
   void SetHandledTypes(intptr_t try_index, const Array& handled_types) const;
   bool HasCatchAll(intptr_t try_index) const;
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawExceptionHandlers) ==
-           OFFSET_OF_RETURNED_VALUE(RawExceptionHandlers, data));
+    ASSERT(sizeof(ExceptionHandlersLayout) ==
+           OFFSET_OF_RETURNED_VALUE(ExceptionHandlersLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
-    return RoundedAllocationSize(sizeof(RawExceptionHandlers) +
+    return RoundedAllocationSize(sizeof(ExceptionHandlersLayout) +
                                  (len * sizeof(ExceptionHandlerInfo)));
   }
 
-  static RawExceptionHandlers* New(intptr_t num_handlers);
-  static RawExceptionHandlers* New(const Array& handled_types_data);
+  static ExceptionHandlersPtr New(intptr_t num_handlers);
+  static ExceptionHandlersPtr New(const Array& handled_types_data);
 
   // We would have a VisitPointers function here to traverse the
   // exception handler table to visit objects if any in the table.
@@ -5739,7 +5763,7 @@
 //       Object::null() from target() means the WSR represents a dropped target.
 //
 // Unfortunately a WSR is not a proxy for the original object, so if WSRs may
-// appear as field contents (currently only possible for RawObject* fields),
+// appear as field contents (currently only possible for ObjectPtr fields),
 // then code that accesses that field must handle the case where an WSR has
 // been introduced. Before serialization, Unwrap can be used to take a
 // Object reference or RawObject pointer and remove any WSR wrapping before use.
@@ -5750,8 +5774,8 @@
 //  * Code::owner_
 class WeakSerializationReference : public Object {
  public:
-  RawObject* target() const { return TargetOf(raw()); }
-  static RawObject* TargetOf(const RawWeakSerializationReference* raw) {
+  ObjectPtr target() const { return TargetOf(raw()); }
+  static ObjectPtr TargetOf(const WeakSerializationReferencePtr raw) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     // WSRs in the precompiled runtime only contain some remaining info about
     // their old target, not a reference to the target itself..
@@ -5764,7 +5788,7 @@
   }
 
   classid_t TargetClassId() const { return TargetClassIdOf(raw()); }
-  static classid_t TargetClassIdOf(const RawWeakSerializationReference* raw) {
+  static classid_t TargetClassIdOf(const WeakSerializationReferencePtr raw) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     // No new instances of WSRs are created in the precompiled runtime, so
     // this instance came from deserialization and thus must be the empty WSR.
@@ -5774,23 +5798,23 @@
 #endif
   }
 
-  static RawObject* Unwrap(const Object& obj) { return Unwrap(obj.raw()); }
+  static ObjectPtr Unwrap(const Object& obj) { return Unwrap(obj.raw()); }
   // Gets the underlying object from a WSR, or the original object if it is
   // not one. Notably, Unwrap(Wrap(r)) == r for all raw objects r, whether
   // CanWrap(r) or not. However, this will not hold if a serialization and
   // deserialization step is put between the two calls.
-  static RawObject* Unwrap(RawObject* obj) {
+  static ObjectPtr Unwrap(ObjectPtr obj) {
     if (!obj->IsWeakSerializationReference()) return obj;
-    return TargetOf(reinterpret_cast<RawWeakSerializationReference*>(obj));
+    return TargetOf(static_cast<WeakSerializationReferencePtr>(obj));
   }
 
   // An Unwrap that only unwraps if there's a valid target, otherwise the
   // WSR is returned. Useful for cases where we want to call Object methods
   // like ToCString() on whatever non-null object we can get.
-  static RawObject* UnwrapIfTarget(const Object& obj) {
+  static ObjectPtr UnwrapIfTarget(const Object& obj) {
     return UnwrapIfTarget(obj.raw());
   }
-  static RawObject* UnwrapIfTarget(RawObject* raw) {
+  static ObjectPtr UnwrapIfTarget(ObjectPtr raw) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     // In the precompiled runtime, WSRs never have a target so we always return
     // the argument.
@@ -5812,22 +5836,22 @@
   // whether CanWrap(r) or not. Unlike Unwrap, this is still true even if
   // there is a serialization and deserialization step between the two calls,
   // since that information is saved in the serialized WSR.
-  static classid_t UnwrappedClassIdOf(RawObject* obj) {
+  static classid_t UnwrappedClassIdOf(ObjectPtr obj) {
     if (!obj->IsWeakSerializationReference()) return obj->GetClassId();
     return TargetClassIdOf(WeakSerializationReference::RawCast(obj));
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawWeakSerializationReference));
+    return RoundedAllocationSize(sizeof(WeakSerializationReferenceLayout));
   }
 
 #if defined(DART_PRECOMPILER)
   // Returns true if a new WSR would be created when calling Wrap.
   static bool CanWrap(const Object& object);
 
-  // This returns RawObject*, not RawWeakSerializationReference*, because
+  // This returns ObjectPtr, not WeakSerializationReferencePtr, because
   // target.raw() is returned when CanWrap(target) is false.
-  static RawObject* Wrap(Zone* zone, const Object& target);
+  static ObjectPtr Wrap(Zone* zone, const Object& target);
 #endif
 
  private:
@@ -5838,7 +5862,7 @@
 class Code : public Object {
  public:
   // When dual mapping, this returns the executable view.
-  RawInstructions* active_instructions() const {
+  InstructionsPtr active_instructions() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
     return NULL;
@@ -5848,13 +5872,13 @@
   }
 
   // When dual mapping, these return the executable view.
-  RawInstructions* instructions() const { return raw_ptr()->instructions_; }
-  static RawInstructions* InstructionsOf(const RawCode* code) {
+  InstructionsPtr instructions() const { return raw_ptr()->instructions_; }
+  static InstructionsPtr InstructionsOf(const CodePtr code) {
     return code->ptr()->instructions_;
   }
 
   static intptr_t saved_instructions_offset() {
-    return OFFSET_OF(RawCode, instructions_);
+    return OFFSET_OF(CodeLayout, instructions_);
   }
 
   using EntryKind = CodeEntryKind;
@@ -5865,21 +5889,21 @@
   static intptr_t entry_point_offset(EntryKind kind = EntryKind::kNormal) {
     switch (kind) {
       case EntryKind::kNormal:
-        return OFFSET_OF(RawCode, entry_point_);
+        return OFFSET_OF(CodeLayout, entry_point_);
       case EntryKind::kUnchecked:
-        return OFFSET_OF(RawCode, unchecked_entry_point_);
+        return OFFSET_OF(CodeLayout, unchecked_entry_point_);
       case EntryKind::kMonomorphic:
-        return OFFSET_OF(RawCode, monomorphic_entry_point_);
+        return OFFSET_OF(CodeLayout, monomorphic_entry_point_);
       case EntryKind::kMonomorphicUnchecked:
-        return OFFSET_OF(RawCode, monomorphic_unchecked_entry_point_);
+        return OFFSET_OF(CodeLayout, monomorphic_unchecked_entry_point_);
       default:
         UNREACHABLE();
     }
   }
 
-  RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
+  ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool_; }
   static intptr_t object_pool_offset() {
-    return OFFSET_OF(RawCode, object_pool_);
+    return OFFSET_OF(CodeLayout, object_pool_);
   }
 
   intptr_t pointer_offsets_length() const {
@@ -5890,7 +5914,7 @@
     return OptimizedBit::decode(raw_ptr()->state_bits_);
   }
   void set_is_optimized(bool value) const;
-  static bool IsOptimized(RawCode* code) {
+  static bool IsOptimized(CodePtr code) {
     return Code::OptimizedBit::decode(code->ptr()->state_bits_);
   }
 
@@ -5903,7 +5927,7 @@
   void set_is_alive(bool value) const;
 
   bool HasMonomorphicEntry() const { return HasMonomorphicEntry(raw()); }
-  static bool HasMonomorphicEntry(const RawCode* code) {
+  static bool HasMonomorphicEntry(const CodePtr code) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     return code->ptr()->entry_point_ != code->ptr()->monomorphic_entry_point_;
 #else
@@ -5913,7 +5937,7 @@
 
   // Returns the payload start of [instructions()].
   uword PayloadStart() const { return PayloadStartOf(raw()); }
-  static uword PayloadStartOf(const RawCode* code) {
+  static uword PayloadStartOf(const CodePtr code) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     const uword entry_offset = HasMonomorphicEntry(code)
                                    ? Instructions::kPolymorphicEntryOffsetAOT
@@ -5926,7 +5950,7 @@
 
   // Returns the entry point of [instructions()].
   uword EntryPoint() const { return EntryPointOf(raw()); }
-  static uword EntryPointOf(const RawCode* code) {
+  static uword EntryPointOf(const CodePtr code) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     return code->ptr()->entry_point_;
 #else
@@ -5961,7 +5985,7 @@
 
   // Returns the size of [instructions()].
   intptr_t Size() const { return PayloadSizeOf(raw()); }
-  static intptr_t PayloadSizeOf(const RawCode* code) {
+  static intptr_t PayloadSizeOf(const CodePtr code) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     return code->ptr()->instructions_length_;
 #else
@@ -5969,29 +5993,27 @@
 #endif
   }
 
-  RawObjectPool* GetObjectPool() const;
+  ObjectPoolPtr GetObjectPool() const;
   // Returns whether the given PC address is in [instructions()].
   bool ContainsInstructionAt(uword addr) const {
     return ContainsInstructionAt(raw(), addr);
   }
 
   // Returns whether the given PC address is in [InstructionsOf(code)].
-  static bool ContainsInstructionAt(const RawCode* code, uword pc) {
-    return RawCode::ContainsPC(code, pc);
+  static bool ContainsInstructionAt(const CodePtr code, uword pc) {
+    return CodeLayout::ContainsPC(code, pc);
   }
 
   // Returns true if there is a debugger breakpoint set in this code object.
   bool HasBreakpoint() const;
 
-  RawPcDescriptors* pc_descriptors() const {
-    return raw_ptr()->pc_descriptors_;
-  }
+  PcDescriptorsPtr pc_descriptors() const { return raw_ptr()->pc_descriptors_; }
   void set_pc_descriptors(const PcDescriptors& descriptors) const {
     ASSERT(descriptors.IsOld());
     StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw());
   }
 
-  RawCodeSourceMap* code_source_map() const {
+  CodeSourceMapPtr code_source_map() const {
     return raw_ptr()->code_source_map_;
   }
 
@@ -6001,7 +6023,7 @@
   }
 
   // Array of DeoptInfo objects.
-  RawArray* deopt_info_array() const {
+  ArrayPtr deopt_info_array() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
     return NULL;
@@ -6017,18 +6039,20 @@
 #endif
 
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-  RawTypedData* catch_entry_moves_maps() const;
+  TypedDataPtr catch_entry_moves_maps() const;
   void set_catch_entry_moves_maps(const TypedData& maps) const;
 #endif
 
-  RawCompressedStackMaps* compressed_stackmaps() const {
+  CompressedStackMapsPtr compressed_stackmaps() const {
     return raw_ptr()->compressed_stackmaps_;
   }
   void set_compressed_stackmaps(const CompressedStackMaps& maps) const;
 
   enum CallKind {
     kPcRelativeCall = 1,
-    kCallViaCode = 2,
+    kPcRelativeTTSCall = 2,
+    kPcRelativeTailCall = 3,
+    kCallViaCode = 4,
   };
 
   enum CallEntryPoint {
@@ -6038,7 +6062,7 @@
 
   enum SCallTableEntry {
     kSCallTableKindAndOffset = 0,
-    kSCallTableCodeTarget = 1,
+    kSCallTableCodeOrTypeTarget = 1,
     kSCallTableFunctionTarget = 2,
     kSCallTableEntryLength = 3,
   };
@@ -6048,14 +6072,14 @@
     kNotAttachPool,
   };
 
-  class KindField : public BitField<intptr_t, CallKind, 0, 2> {};
+  class KindField : public BitField<intptr_t, CallKind, 0, 3> {};
   class EntryPointField
       : public BitField<intptr_t, CallEntryPoint, KindField::kNextBit, 1> {};
   class OffsetField
-      : public BitField<intptr_t, intptr_t, EntryPointField::kNextBit, 27> {};
+      : public BitField<intptr_t, intptr_t, EntryPointField::kNextBit, 26> {};
 
   void set_static_calls_target_table(const Array& value) const;
-  RawArray* static_calls_target_table() const {
+  ArrayPtr static_calls_target_table() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
     return NULL;
@@ -6064,12 +6088,12 @@
 #endif
   }
 
-  RawTypedData* GetDeoptInfoAtPc(uword pc,
-                                 ICData::DeoptReasonId* deopt_reason,
-                                 uint32_t* deopt_flags) const;
+  TypedDataPtr GetDeoptInfoAtPc(uword pc,
+                                ICData::DeoptReasonId* deopt_reason,
+                                uint32_t* deopt_flags) const;
 
   // Returns null if there is no static call at 'pc'.
-  RawFunction* GetStaticCallTargetFunctionAt(uword pc) const;
+  FunctionPtr GetStaticCallTargetFunctionAt(uword pc) const;
   // Aborts if there is no static call at 'pc'.
   void SetStaticCallTargetCodeAt(uword pc, const Code& code) const;
   void SetStubCallTargetCodeAt(uword pc, const Code& code) const;
@@ -6086,7 +6110,7 @@
     void SetCommentAt(intptr_t idx, const String& comment);
 
     intptr_t PCOffsetAt(intptr_t idx) const;
-    RawString* CommentAt(intptr_t idx) const;
+    StringPtr CommentAt(intptr_t idx) const;
 
    private:
     explicit Comments(const Array& comments);
@@ -6108,7 +6132,7 @@
   const Comments& comments() const;
   void set_comments(const Comments& comments) const;
 
-  RawObject* return_address_metadata() const {
+  ObjectPtr return_address_metadata() const {
 #if defined(PRODUCT)
     UNREACHABLE();
     return NULL;
@@ -6121,7 +6145,7 @@
   // Returns -1 if no prologue offset is available.
   intptr_t GetPrologueOffset() const;
 
-  RawArray* inlined_id_to_function() const;
+  ArrayPtr inlined_id_to_function() const;
   void set_inlined_id_to_function(const Array& value) const;
 
   // Provides the call stack at the given pc offset, with the top-of-stack in
@@ -6149,7 +6173,7 @@
   void DumpInlineIntervals() const;
   void DumpSourcePositions(bool relative_addresses = false) const;
 
-  RawLocalVarDescriptors* var_descriptors() const {
+  LocalVarDescriptorsPtr var_descriptors() const {
 #if defined(PRODUCT)
     UNREACHABLE();
     return NULL;
@@ -6167,9 +6191,9 @@
   }
 
   // Will compute local var descriptors if necessary.
-  RawLocalVarDescriptors* GetLocalVarDescriptors() const;
+  LocalVarDescriptorsPtr GetLocalVarDescriptors() const;
 
-  RawExceptionHandlers* exception_handlers() const {
+  ExceptionHandlersPtr exception_handlers() const {
     return raw_ptr()->exception_handlers_;
   }
   void set_exception_handlers(const ExceptionHandlers& handlers) const {
@@ -6183,36 +6207,36 @@
   // TODO(turnidge): Consider dropping this function and making
   // everybody use owner().  Currently this function is misused - even
   // while generating the snapshot.
-  RawFunction* function() const {
+  FunctionPtr function() const {
     ASSERT(IsFunctionCode());
     return Function::RawCast(
         WeakSerializationReference::Unwrap(raw_ptr()->owner_));
   }
 
-  RawObject* owner() const { return raw_ptr()->owner_; }
+  ObjectPtr owner() const { return raw_ptr()->owner_; }
   void set_owner(const Object& owner) const;
 
   classid_t OwnerClassId() const { return OwnerClassIdOf(raw()); }
-  static classid_t OwnerClassIdOf(RawCode* raw) {
+  static classid_t OwnerClassIdOf(CodePtr raw) {
     return WeakSerializationReference::UnwrappedClassIdOf(raw->ptr()->owner_);
   }
 
-  static intptr_t owner_offset() { return OFFSET_OF(RawCode, owner_); }
+  static intptr_t owner_offset() { return OFFSET_OF(CodeLayout, owner_); }
 
   // We would have a VisitPointers function here to traverse all the
   // embedded objects in the instructions using pointer_offsets.
 
   static const intptr_t kBytesPerElement =
-      sizeof(reinterpret_cast<RawCode*>(0)->data()[0]);
+      sizeof(reinterpret_cast<CodeLayout*>(0)->data()[0]);
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawCode) == OFFSET_OF_RETURNED_VALUE(RawCode, data));
+    ASSERT(sizeof(CodeLayout) == OFFSET_OF_RETURNED_VALUE(CodeLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(0 <= len && len <= kMaxElements);
-    return RoundedAllocationSize(sizeof(RawCode) + (len * kBytesPerElement));
+    return RoundedAllocationSize(sizeof(CodeLayout) + (len * kBytesPerElement));
   }
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // Finalizes the generated code, by generating various kinds of metadata (e.g.
@@ -6223,11 +6247,11 @@
   // then a new [ObjectPool] will be attached to the code object as well.
   // Otherwise the caller is responsible for doing this via
   // `Object::set_object_pool()`.
-  static RawCode* FinalizeCode(FlowGraphCompiler* compiler,
-                               compiler::Assembler* assembler,
-                               PoolAttachment pool_attachment,
-                               bool optimized,
-                               CodeStatistics* stats);
+  static CodePtr FinalizeCode(FlowGraphCompiler* compiler,
+                              compiler::Assembler* assembler,
+                              PoolAttachment pool_attachment,
+                              bool optimized,
+                              CodeStatistics* stats);
 
   // Notifies all active [CodeObserver]s.
   static void NotifyCodeObservers(const Code& code, bool optimized);
@@ -6239,23 +6263,23 @@
                                   bool optimized);
 
   // Calls [FinalizeCode] and also notifies [CodeObserver]s.
-  static RawCode* FinalizeCodeAndNotify(const Function& function,
-                                        FlowGraphCompiler* compiler,
-                                        compiler::Assembler* assembler,
-                                        PoolAttachment pool_attachment,
-                                        bool optimized = false,
-                                        CodeStatistics* stats = nullptr);
-  static RawCode* FinalizeCodeAndNotify(const char* name,
-                                        FlowGraphCompiler* compiler,
-                                        compiler::Assembler* assembler,
-                                        PoolAttachment pool_attachment,
-                                        bool optimized = false,
-                                        CodeStatistics* stats = nullptr);
+  static CodePtr FinalizeCodeAndNotify(const Function& function,
+                                       FlowGraphCompiler* compiler,
+                                       compiler::Assembler* assembler,
+                                       PoolAttachment pool_attachment,
+                                       bool optimized = false,
+                                       CodeStatistics* stats = nullptr);
+  static CodePtr FinalizeCodeAndNotify(const char* name,
+                                       FlowGraphCompiler* compiler,
+                                       compiler::Assembler* assembler,
+                                       PoolAttachment pool_attachment,
+                                       bool optimized = false,
+                                       CodeStatistics* stats = nullptr);
 
 #endif
-  static RawCode* LookupCode(uword pc);
-  static RawCode* LookupCodeInVmIsolate(uword pc);
-  static RawCode* FindCode(uword pc, int64_t timestamp);
+  static CodePtr LookupCode(uword pc);
+  static CodePtr LookupCodeInVmIsolate(uword pc);
+  static CodePtr FindCode(uword pc, int64_t timestamp);
 
   int32_t GetPointerOffsetAt(int index) const {
     NoSafepointScope no_safepoint;
@@ -6264,7 +6288,8 @@
   TokenPosition GetTokenIndexOfPC(uword pc) const;
 
   // Find pc, return 0 if not found.
-  uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const;
+  uword GetPcForDeoptId(intptr_t deopt_id,
+                        PcDescriptorsLayout::Kind kind) const;
   intptr_t GetDeoptIdForOsr(uword pc) const;
 
   const char* Name() const;
@@ -6294,7 +6319,7 @@
   }
 
   bool IsDisabled() const { return IsDisabled(raw()); }
-  static bool IsDisabled(RawCode* code) {
+  static bool IsDisabled(CodePtr code) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
     return false;
@@ -6303,15 +6328,15 @@
 #endif
   }
 
-  void set_object_pool(RawObjectPool* object_pool) const {
+  void set_object_pool(ObjectPoolPtr object_pool) const {
     StorePointer(&raw_ptr()->object_pool_, object_pool);
   }
 
  private:
   void set_state_bits(intptr_t bits) const;
 
-  friend class RawObject;  // For RawObject::SizeFromClass().
-  friend class RawCode;
+  friend class ObjectLayout;  // For ObjectLayout::SizeFromClass().
+  friend class CodeLayout;
   enum {
     kOptimizedBit = 0,
     kForceOptimizedBit = 1,
@@ -6337,7 +6362,7 @@
     virtual ~SlowFindRawCodeVisitor() {}
 
     // Check if object matches find condition.
-    virtual bool FindObject(RawObject* obj) const;
+    virtual bool FindObject(ObjectPtr obj) const;
 
    private:
     const uword pc_;
@@ -6357,8 +6382,8 @@
 
   // Initializes the cached entrypoint addresses in [code] as calculated
   // from [instructions] and [unchecked_offset].
-  static void InitializeCachedEntryPointsFrom(RawCode* code,
-                                              RawInstructions* instructions,
+  static void InitializeCachedEntryPointsFrom(CodePtr code,
+                                              InstructionsPtr instructions,
                                               uint32_t unchecked_offset);
 
   // Sets [active_instructions_] to [instructions] and updates the cached
@@ -6384,7 +6409,7 @@
   uint32_t UncheckedEntryPointOffset() const {
     return UncheckedEntryPointOffsetOf(raw());
   }
-  static uint32_t UncheckedEntryPointOffsetOf(RawCode* code) {
+  static uint32_t UncheckedEntryPointOffsetOf(CodePtr code) {
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
 #else
@@ -6409,13 +6434,13 @@
   }
 
   intptr_t BinarySearchInSCallTable(uword pc) const;
-  static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc);
+  static CodePtr LookupCodeInIsolate(Isolate* isolate, uword pc);
 
   // New is a private method as RawInstruction and RawCode objects should
   // only be created using the Code::FinalizeCode method. This method creates
   // the RawInstruction and RawCode objects, sets up the pointer offsets
   // and links the two in a GC safe manner.
-  static RawCode* New(intptr_t pointer_offsets_length);
+  static CodePtr New(intptr_t pointer_offsets_length);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object);
   friend class Class;
@@ -6433,7 +6458,7 @@
   friend class ProgramVisitor;         // for set_instructions
   // So that the RawFunction pointer visitor can determine whether code the
   // function points to is optimized.
-  friend class RawFunction;
+  friend class FunctionLayout;
   friend class CallSiteResetter;
   friend class CodeKeyValueTrait;  // for UncheckedEntryPointOffset
 };
@@ -6445,15 +6470,13 @@
   uword PayloadStart() const { return instructions(); }
   intptr_t Size() const { return raw_ptr()->instructions_size_; }
 
-  RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
+  ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool_; }
 
   bool ContainsInstructionAt(uword addr) const {
-    return RawBytecode::ContainsPC(raw(), addr);
+    return BytecodeLayout::ContainsPC(raw(), addr);
   }
 
-  RawPcDescriptors* pc_descriptors() const {
-    return raw_ptr()->pc_descriptors_;
-  }
+  PcDescriptorsPtr pc_descriptors() const { return raw_ptr()->pc_descriptors_; }
   void set_pc_descriptors(const PcDescriptors& descriptors) const {
     ASSERT(descriptors.IsOld());
     StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw());
@@ -6461,7 +6484,7 @@
 
   void Disassemble(DisassemblyFormatter* formatter = NULL) const;
 
-  RawExceptionHandlers* exception_handlers() const {
+  ExceptionHandlersPtr exception_handlers() const {
     return raw_ptr()->exception_handlers_;
   }
   void set_exception_handlers(const ExceptionHandlers& handlers) const {
@@ -6469,7 +6492,7 @@
     StorePointer(&raw_ptr()->exception_handlers_, handlers.raw());
   }
 
-  RawFunction* function() const { return raw_ptr()->function_; }
+  FunctionPtr function() const { return raw_ptr()->function_; }
 
   void set_function(const Function& function) const {
     ASSERT(function.IsOld());
@@ -6477,14 +6500,14 @@
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawBytecode));
+    return RoundedAllocationSize(sizeof(BytecodeLayout));
   }
-  static RawBytecode* New(uword instructions,
-                          intptr_t instructions_size,
-                          intptr_t instructions_offset,
-                          const ObjectPool& object_pool);
+  static BytecodePtr New(uword instructions,
+                         intptr_t instructions_size,
+                         intptr_t instructions_offset,
+                         const ObjectPool& object_pool);
 
-  RawExternalTypedData* GetBinary(Zone* zone) const;
+  ExternalTypedDataPtr GetBinary(Zone* zone) const;
 
   TokenPosition GetTokenIndexOfPC(uword return_address) const;
   intptr_t GetTryIndexAtPc(uword return_address) const;
@@ -6525,7 +6548,7 @@
     return (local_variables_binary_offset() != 0);
   }
 
-  RawLocalVarDescriptors* var_descriptors() const {
+  LocalVarDescriptorsPtr var_descriptors() const {
 #if defined(PRODUCT)
     UNREACHABLE();
     return nullptr;
@@ -6543,7 +6566,7 @@
   }
 
   // Will compute local var descriptors if necessary.
-  RawLocalVarDescriptors* GetLocalVarDescriptors() const;
+  LocalVarDescriptorsPtr GetLocalVarDescriptors() const;
 
   const char* Name() const;
   const char* QualifiedName() const;
@@ -6555,7 +6578,7 @@
     virtual ~SlowFindRawBytecodeVisitor() {}
 
     // Check if object matches find condition.
-    virtual bool FindObject(RawObject* obj) const;
+    virtual bool FindObject(ObjectPtr obj) const;
 
    private:
     const uword pc_;
@@ -6563,7 +6586,7 @@
     DISALLOW_COPY_AND_ASSIGN(SlowFindRawBytecodeVisitor);
   };
 
-  static RawBytecode* FindCode(uword pc);
+  static BytecodePtr FindCode(uword pc);
 
  private:
   void set_instructions(uword instructions) const {
@@ -6577,8 +6600,8 @@
   }
 
   friend class BytecodeDeserializationCluster;
-  friend class RawObject;  // For RawObject::SizeFromClass().
-  friend class RawBytecode;
+  friend class ObjectLayout;  // For ObjectLayout::SizeFromClass().
+  friend class BytecodeLayout;
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Bytecode, Object);
   friend class Class;
@@ -6587,21 +6610,21 @@
 
 class Context : public Object {
  public:
-  RawContext* parent() const { return raw_ptr()->parent_; }
+  ContextPtr parent() const { return raw_ptr()->parent_; }
   void set_parent(const Context& parent) const {
     StorePointer(&raw_ptr()->parent_, parent.raw());
   }
-  static intptr_t parent_offset() { return OFFSET_OF(RawContext, parent_); }
+  static intptr_t parent_offset() { return OFFSET_OF(ContextLayout, parent_); }
 
   intptr_t num_variables() const { return raw_ptr()->num_variables_; }
   static intptr_t num_variables_offset() {
-    return OFFSET_OF(RawContext, num_variables_);
+    return OFFSET_OF(ContextLayout, num_variables_);
   }
-  static intptr_t NumVariables(const RawContext* context) {
+  static intptr_t NumVariables(const ContextPtr context) {
     return context->ptr()->num_variables_;
   }
 
-  RawObject* At(intptr_t context_index) const {
+  ObjectPtr At(intptr_t context_index) const {
     return *ObjectAddr(context_index);
   }
   inline void SetAt(intptr_t context_index, const Object& value) const;
@@ -6618,7 +6641,7 @@
   static const intptr_t kControllerIndex = 1;
 
   static intptr_t variable_offset(intptr_t context_index) {
-    return OFFSET_OF_RETURNED_VALUE(RawContext, data) +
+    return OFFSET_OF_RETURNED_VALUE(ContextLayout, data) +
            (kWordSize * context_index);
   }
 
@@ -6627,20 +6650,21 @@
   }
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawContext) == OFFSET_OF_RETURNED_VALUE(RawContext, data));
+    ASSERT(sizeof(ContextLayout) ==
+           OFFSET_OF_RETURNED_VALUE(ContextLayout, data));
     return 0;
   }
 
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(IsValidLength(len));
-    return RoundedAllocationSize(sizeof(RawContext) + (len * kBytesPerElement));
+    return RoundedAllocationSize(sizeof(ContextLayout) +
+                                 (len * kBytesPerElement));
   }
 
-  static RawContext* New(intptr_t num_variables,
-                         Heap::Space space = Heap::kNew);
+  static ContextPtr New(intptr_t num_variables, Heap::Space space = Heap::kNew);
 
  private:
-  RawObject* const* ObjectAddr(intptr_t context_index) const {
+  ObjectPtr const* ObjectAddr(intptr_t context_index) const {
     ASSERT((context_index >= 0) && (context_index < num_variables()));
     return &raw_ptr()->data()[context_index];
   }
@@ -6675,7 +6699,7 @@
   void SetDeclarationTokenIndexAt(intptr_t scope_index,
                                   TokenPosition declaration_token_pos) const;
 
-  RawString* NameAt(intptr_t scope_index) const;
+  StringPtr NameAt(intptr_t scope_index) const;
   void SetNameAt(intptr_t scope_index, const String& name) const;
 
   void ClearFlagsAt(intptr_t scope_index) const;
@@ -6693,10 +6717,10 @@
   bool IsConstAt(intptr_t scope_index) const;
   void SetIsConstAt(intptr_t scope_index, bool is_const) const;
 
-  RawAbstractType* TypeAt(intptr_t scope_index) const;
+  AbstractTypePtr TypeAt(intptr_t scope_index) const;
   void SetTypeAt(intptr_t scope_index, const AbstractType& type) const;
 
-  RawInstance* ConstValueAt(intptr_t scope_index) const;
+  InstancePtr ConstValueAt(intptr_t scope_index) const;
   void SetConstValueAt(intptr_t scope_index, const Instance& value) const;
 
   intptr_t ContextIndexAt(intptr_t scope_index) const;
@@ -6706,22 +6730,22 @@
   void SetContextLevelAt(intptr_t scope_index, intptr_t context_level) const;
 
   static const intptr_t kBytesPerElement =
-      sizeof(RawContextScope::VariableDesc);
+      sizeof(ContextScopeLayout::VariableDesc);
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawContextScope) ==
-           OFFSET_OF_RETURNED_VALUE(RawContextScope, data));
+    ASSERT(sizeof(ContextScopeLayout) ==
+           OFFSET_OF_RETURNED_VALUE(ContextScopeLayout, data));
     return 0;
   }
 
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(0 <= len && len <= kMaxElements);
-    return RoundedAllocationSize(sizeof(RawContextScope) +
+    return RoundedAllocationSize(sizeof(ContextScopeLayout) +
                                  (len * kBytesPerElement));
   }
 
-  static RawContextScope* New(intptr_t num_variables, bool is_implicit);
+  static ContextScopePtr New(intptr_t num_variables, bool is_implicit);
 
  private:
   void set_num_variables(intptr_t num_variables) const {
@@ -6732,7 +6756,8 @@
     StoreNonPointer(&raw_ptr()->is_implicit_, is_implicit);
   }
 
-  const RawContextScope::VariableDesc* VariableDescAddr(intptr_t index) const {
+  const ContextScopeLayout::VariableDesc* VariableDescAddr(
+      intptr_t index) const {
     ASSERT((index >= 0) && (index < num_variables()));
     return raw_ptr()->VariableDescAddr(index);
   }
@@ -6745,7 +6770,7 @@
   friend class Object;
 };
 
-class MegamorphicCache : public Object {
+class MegamorphicCache : public CallSiteData {
  public:
   static const intptr_t kInitialCapacity = 16;
   static const intptr_t kSpreadFactor = 7;
@@ -6757,51 +6782,44 @@
     kEntryLength,
   };
 
-  RawArray* buckets() const;
+  ArrayPtr buckets() const;
   void set_buckets(const Array& buckets) const;
 
   intptr_t mask() const;
   void set_mask(intptr_t mask) const;
 
-  RawString* target_name() const { return raw_ptr()->target_name_; }
-
-  RawArray* arguments_descriptor() const { return raw_ptr()->args_descriptor_; }
-
   intptr_t filled_entry_count() const;
   void set_filled_entry_count(intptr_t num) const;
 
   static intptr_t buckets_offset() {
-    return OFFSET_OF(RawMegamorphicCache, buckets_);
+    return OFFSET_OF(MegamorphicCacheLayout, buckets_);
   }
   static intptr_t mask_offset() {
-    return OFFSET_OF(RawMegamorphicCache, mask_);
+    return OFFSET_OF(MegamorphicCacheLayout, mask_);
   }
   static intptr_t arguments_descriptor_offset() {
-    return OFFSET_OF(RawMegamorphicCache, args_descriptor_);
+    return OFFSET_OF(MegamorphicCacheLayout, args_descriptor_);
   }
 
-  static RawMegamorphicCache* New(const String& target_name,
-                                  const Array& arguments_descriptor);
+  static MegamorphicCachePtr New(const String& target_name,
+                                 const Array& arguments_descriptor);
 
   void Insert(const Smi& class_id, const Object& target) const;
 
   void SwitchToBareInstructions();
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawMegamorphicCache));
+    return RoundedAllocationSize(sizeof(MegamorphicCacheLayout));
   }
 
-  static RawMegamorphicCache* Clone(const MegamorphicCache& from);
+  static MegamorphicCachePtr Clone(const MegamorphicCache& from);
 
  private:
   friend class Class;
   friend class MegamorphicCacheTable;
   friend class ProgramVisitor;
 
-  static RawMegamorphicCache* New();
-
-  void set_target_name(const String& value) const;
-  void set_arguments_descriptor(const Array& value) const;
+  static MegamorphicCachePtr New();
 
   // The caller must hold Isolate::megamorphic_mutex().
   void EnsureCapacityLocked() const;
@@ -6812,11 +6830,10 @@
                               const Smi& class_id,
                               const Object& target);
 
-  static inline RawObject* GetClassId(const Array& array, intptr_t index);
-  static inline RawObject* GetTargetFunction(const Array& array,
-                                             intptr_t index);
+  static inline ObjectPtr GetClassId(const Array& array, intptr_t index);
+  static inline ObjectPtr GetTargetFunction(const Array& array, intptr_t index);
 
-  FINAL_HEAP_OBJECT_IMPLEMENTATION(MegamorphicCache, Object);
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(MegamorphicCache, CallSiteData);
 };
 
 class SubtypeTestCache : public Object {
@@ -6850,24 +6867,24 @@
                 Bool* test_result) const;
   void Reset() const;
 
-  static RawSubtypeTestCache* New();
+  static SubtypeTestCachePtr New();
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawSubtypeTestCache));
+    return RoundedAllocationSize(sizeof(SubtypeTestCacheLayout));
   }
 
   static intptr_t cache_offset() {
-    return OFFSET_OF(RawSubtypeTestCache, cache_);
+    return OFFSET_OF(SubtypeTestCacheLayout, cache_);
   }
 
   static void Init();
   static void Cleanup();
 
-  RawArray* cache() const { return raw_ptr()->cache_; }
+  ArrayPtr cache() const { return raw_ptr()->cache_; }
 
  private:
   // A VM heap allocated preinitialized empty subtype entry array.
-  static RawArray* cached_array_;
+  static ArrayPtr cached_array_;
 
   void set_cache(const Array& value) const;
 
@@ -6889,21 +6906,20 @@
 
 class ApiError : public Error {
  public:
-  RawString* message() const { return raw_ptr()->message_; }
+  StringPtr message() const { return raw_ptr()->message_; }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawApiError));
+    return RoundedAllocationSize(sizeof(ApiErrorLayout));
   }
 
-  static RawApiError* New(const String& message,
-                          Heap::Space space = Heap::kNew);
+  static ApiErrorPtr New(const String& message, Heap::Space space = Heap::kNew);
 
   virtual const char* ToErrorCString() const;
 
  private:
   void set_message(const String& message) const;
 
-  static RawApiError* New();
+  static ApiErrorPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ApiError, Error);
   friend class Class;
@@ -6916,44 +6932,44 @@
   }
 
   // Build, cache, and return formatted message.
-  RawString* FormatMessage() const;
+  StringPtr FormatMessage() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawLanguageError));
+    return RoundedAllocationSize(sizeof(LanguageErrorLayout));
   }
 
   // A null script means no source and a negative token_pos means no position.
-  static RawLanguageError* NewFormatted(const Error& prev_error,
+  static LanguageErrorPtr NewFormatted(const Error& prev_error,
+                                       const Script& script,
+                                       TokenPosition token_pos,
+                                       bool report_after_token,
+                                       Report::Kind kind,
+                                       Heap::Space space,
+                                       const char* format,
+                                       ...) PRINTF_ATTRIBUTE(7, 8);
+
+  static LanguageErrorPtr NewFormattedV(const Error& prev_error,
                                         const Script& script,
                                         TokenPosition token_pos,
                                         bool report_after_token,
                                         Report::Kind kind,
                                         Heap::Space space,
                                         const char* format,
-                                        ...) PRINTF_ATTRIBUTE(7, 8);
+                                        va_list args);
 
-  static RawLanguageError* NewFormattedV(const Error& prev_error,
-                                         const Script& script,
-                                         TokenPosition token_pos,
-                                         bool report_after_token,
-                                         Report::Kind kind,
-                                         Heap::Space space,
-                                         const char* format,
-                                         va_list args);
-
-  static RawLanguageError* New(const String& formatted_message,
-                               Report::Kind kind = Report::kError,
-                               Heap::Space space = Heap::kNew);
+  static LanguageErrorPtr New(const String& formatted_message,
+                              Report::Kind kind = Report::kError,
+                              Heap::Space space = Heap::kNew);
 
   virtual const char* ToErrorCString() const;
 
   TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
 
  private:
-  RawError* previous_error() const { return raw_ptr()->previous_error_; }
+  ErrorPtr previous_error() const { return raw_ptr()->previous_error_; }
   void set_previous_error(const Error& value) const;
 
-  RawScript* script() const { return raw_ptr()->script_; }
+  ScriptPtr script() const { return raw_ptr()->script_; }
   void set_script(const Script& value) const;
 
   void set_token_pos(TokenPosition value) const;
@@ -6963,13 +6979,13 @@
 
   void set_kind(uint8_t value) const;
 
-  RawString* message() const { return raw_ptr()->message_; }
+  StringPtr message() const { return raw_ptr()->message_; }
   void set_message(const String& value) const;
 
-  RawString* formatted_message() const { return raw_ptr()->formatted_message_; }
+  StringPtr formatted_message() const { return raw_ptr()->formatted_message_; }
   void set_formatted_message(const String& value) const;
 
-  static RawLanguageError* New();
+  static LanguageErrorPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(LanguageError, Error);
   friend class Class;
@@ -6977,28 +6993,28 @@
 
 class UnhandledException : public Error {
  public:
-  RawInstance* exception() const { return raw_ptr()->exception_; }
+  InstancePtr exception() const { return raw_ptr()->exception_; }
   static intptr_t exception_offset() {
-    return OFFSET_OF(RawUnhandledException, exception_);
+    return OFFSET_OF(UnhandledExceptionLayout, exception_);
   }
 
-  RawInstance* stacktrace() const { return raw_ptr()->stacktrace_; }
+  InstancePtr stacktrace() const { return raw_ptr()->stacktrace_; }
   static intptr_t stacktrace_offset() {
-    return OFFSET_OF(RawUnhandledException, stacktrace_);
+    return OFFSET_OF(UnhandledExceptionLayout, stacktrace_);
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawUnhandledException));
+    return RoundedAllocationSize(sizeof(UnhandledExceptionLayout));
   }
 
-  static RawUnhandledException* New(const Instance& exception,
-                                    const Instance& stacktrace,
-                                    Heap::Space space = Heap::kNew);
+  static UnhandledExceptionPtr New(const Instance& exception,
+                                   const Instance& stacktrace,
+                                   Heap::Space space = Heap::kNew);
 
   virtual const char* ToErrorCString() const;
 
  private:
-  static RawUnhandledException* New(Heap::Space space = Heap::kNew);
+  static UnhandledExceptionPtr New(Heap::Space space = Heap::kNew);
 
   void set_exception(const Instance& exception) const;
   void set_stacktrace(const Instance& stacktrace) const;
@@ -7013,14 +7029,14 @@
   bool is_user_initiated() const { return raw_ptr()->is_user_initiated_; }
   void set_is_user_initiated(bool value) const;
 
-  RawString* message() const { return raw_ptr()->message_; }
+  StringPtr message() const { return raw_ptr()->message_; }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawUnwindError));
+    return RoundedAllocationSize(sizeof(UnwindErrorLayout));
   }
 
-  static RawUnwindError* New(const String& message,
-                             Heap::Space space = Heap::kNew);
+  static UnwindErrorPtr New(const String& message,
+                            Heap::Space space = Heap::kNew);
 
   virtual const char* ToErrorCString() const;
 
@@ -7060,30 +7076,30 @@
   // An instance cannot be canonicalized if it still contains non-canonical
   // instances in its fields.
   // Returns error in error_str, pass NULL if an error cannot occur.
-  virtual RawInstance* CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const;
+  virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const;
 
   // Returns true if all fields are OK for canonicalization.
   virtual bool CheckAndCanonicalizeFields(Thread* thread,
                                           const char** error_str) const;
 
-  RawInstance* CopyShallowToOldSpace(Thread* thread) const;
+  InstancePtr CopyShallowToOldSpace(Thread* thread) const;
 
 #if defined(DEBUG)
   // Check if instance is canonical.
   virtual bool CheckIsCanonical(Thread* thread) const;
 #endif  // DEBUG
 
-  RawObject* GetField(const Field& field) const;
+  ObjectPtr GetField(const Field& field) const;
 
   void SetField(const Field& field, const Object& value) const;
 
-  RawAbstractType* GetType(Heap::Space space) const;
+  AbstractTypePtr GetType(Heap::Space space) const;
 
   // Access the arguments of the [Type] of this [Instance].
   // Note: for [Type]s instead of [Instance]s with a [Type] attached, use
   // [arguments()] and [set_arguments()]
-  virtual RawTypeArguments* GetTypeArguments() const;
+  virtual TypeArgumentsPtr GetTypeArguments() const;
   virtual void SetTypeArguments(const TypeArguments& value) const;
 
   // Check if the type of this instance is a subtype of the given other type.
@@ -7103,12 +7119,6 @@
   // [other] is a type parameter in NNBD strong mode).
   static bool NullIsAssignableTo(const AbstractType& other);
 
-  // Returns true if the type of this instance is a subtype of FutureOr<T>
-  // specified by instantiated type 'other'.
-  // Returns false if other type is not a FutureOr.
-  bool IsFutureOrInstanceOf(Zone* zone,
-                            const AbstractType& other) const;
-
   bool IsValidNativeIndex(int index) const {
     return ((index >= 0) && (index < clazz()->ptr()->num_native_fields_));
   }
@@ -7130,25 +7140,25 @@
   // (if not NULL) to call.
   bool IsCallable(Function* function) const;
 
-  RawObject* Invoke(const String& selector,
-                    const Array& arguments,
-                    const Array& argument_names,
-                    bool respect_reflectable = true,
-                    bool check_is_entrypoint = false) const;
-  RawObject* InvokeGetter(const String& selector,
-                          bool respect_reflectable = true,
-                          bool check_is_entrypoint = false) const;
-  RawObject* InvokeSetter(const String& selector,
-                          const Instance& argument,
-                          bool respect_reflectable = true,
-                          bool check_is_entrypoint = false) const;
+  ObjectPtr Invoke(const String& selector,
+                   const Array& arguments,
+                   const Array& argument_names,
+                   bool respect_reflectable = true,
+                   bool check_is_entrypoint = false) const;
+  ObjectPtr InvokeGetter(const String& selector,
+                         bool respect_reflectable = true,
+                         bool check_is_entrypoint = false) const;
+  ObjectPtr InvokeSetter(const String& selector,
+                         const Instance& argument,
+                         bool respect_reflectable = true,
+                         bool check_is_entrypoint = false) const;
 
   // Evaluate the given expression as if it appeared in an instance method of
   // this instance and return the resulting value, or an error object if
   // evaluating the expression fails. The method has the formal (type)
   // parameters given in (type_)param_names, and is invoked with the (type)
   // argument values given in (type_)param_values.
-  RawObject* EvaluateCompiledExpression(
+  ObjectPtr EvaluateCompiledExpression(
       const Class& method_cls,
       const ExternalTypedData& kernel_buffer,
       const Array& type_definitions,
@@ -7156,16 +7166,16 @@
       const TypeArguments& type_param_values) const;
 
   // Equivalent to invoking hashCode on this instance.
-  virtual RawObject* HashCode() const;
+  virtual ObjectPtr HashCode() const;
 
   // Equivalent to invoking identityHashCode with this instance.
-  RawObject* IdentityHashCode() const;
+  ObjectPtr IdentityHashCode() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawInstance));
+    return RoundedAllocationSize(sizeof(InstanceLayout));
   }
 
-  static RawInstance* New(const Class& cls, Heap::Space space = Heap::kNew);
+  static InstancePtr New(const Class& cls, Heap::Space space = Heap::kNew);
 
   // Array/list element address computations.
   static intptr_t DataOffsetFor(intptr_t cid);
@@ -7177,7 +7187,7 @@
   // Pointer handles.
   virtual bool IsPointer() const;
 
-  static intptr_t NextFieldOffset() { return sizeof(RawInstance); }
+  static intptr_t NextFieldOffset() { return sizeof(InstanceLayout); }
 
  protected:
 #ifndef PRODUCT
@@ -7191,21 +7201,27 @@
       const TypeArguments& other_instantiator_type_arguments,
       const TypeArguments& other_function_type_arguments) const;
 
+  // Returns true if the type of this instance is a subtype of FutureOr<T>
+  // specified by instantiated type 'other'.
+  // Returns false if other type is not a FutureOr.
+  bool RuntimeTypeIsSubtypeOfFutureOr(Zone* zone,
+                                      const AbstractType& other) const;
+
   // Return true if the null instance is an instance of other type.
   static bool NullIsInstanceOf(
       const AbstractType& other,
       const TypeArguments& other_instantiator_type_arguments,
       const TypeArguments& other_function_type_arguments);
 
-  RawObject** FieldAddrAtOffset(intptr_t offset) const {
+  ObjectPtr* FieldAddrAtOffset(intptr_t offset) const {
     ASSERT(IsValidFieldOffset(offset));
-    return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset);
+    return reinterpret_cast<ObjectPtr*>(raw_value() - kHeapObjectTag + offset);
   }
-  RawObject** FieldAddr(const Field& field) const {
+  ObjectPtr* FieldAddr(const Field& field) const {
     return FieldAddrAtOffset(field.HostOffset());
   }
-  RawObject** NativeFieldsAddr() const {
-    return FieldAddrAtOffset(sizeof(RawObject));
+  ObjectPtr* NativeFieldsAddr() const {
+    return FieldAddrAtOffset(sizeof(ObjectLayout));
   }
   void SetFieldAtOffset(intptr_t offset, const Object& value) const {
     StorePointer(FieldAddrAtOffset(offset), value.raw());
@@ -7214,19 +7230,19 @@
 
   // The following raw methods are used for morphing.
   // They are needed due to the extraction of the class in IsValidFieldOffset.
-  RawObject** RawFieldAddrAtOffset(intptr_t offset) const {
-    return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset);
+  ObjectPtr* RawFieldAddrAtOffset(intptr_t offset) const {
+    return reinterpret_cast<ObjectPtr*>(raw_value() - kHeapObjectTag + offset);
   }
-  RawObject* RawGetFieldAtOffset(intptr_t offset) const {
+  ObjectPtr RawGetFieldAtOffset(intptr_t offset) const {
     return *RawFieldAddrAtOffset(offset);
   }
   void RawSetFieldAtOffset(intptr_t offset, const Object& value) const {
     StorePointer(RawFieldAddrAtOffset(offset), value.raw());
   }
 
-  static RawInstance* NewFromCidAndSize(SharedClassTable* shared_class_table,
-                                        classid_t cid,
-                                        Heap::Space heap = Heap::kNew);
+  static InstancePtr NewFromCidAndSize(SharedClassTable* shared_class_table,
+                                       classid_t cid,
+                                       Heap::Space heap = Heap::kNew);
 
   // TODO(iposva): Determine if this gets in the way of Smi.
   HEAP_OBJECT_IMPLEMENTATION(Instance, Object);
@@ -7248,26 +7264,26 @@
 
 class LibraryPrefix : public Instance {
  public:
-  RawString* name() const { return raw_ptr()->name_; }
-  virtual RawString* DictionaryName() const { return name(); }
+  StringPtr name() const { return raw_ptr()->name_; }
+  virtual StringPtr DictionaryName() const { return name(); }
 
-  RawArray* imports() const { return raw_ptr()->imports_; }
+  ArrayPtr imports() const { return raw_ptr()->imports_; }
   intptr_t num_imports() const { return raw_ptr()->num_imports_; }
-  RawLibrary* importer() const { return raw_ptr()->importer_; }
+  LibraryPtr importer() const { return raw_ptr()->importer_; }
 
-  RawLibrary* GetLibrary(int index) const;
+  LibraryPtr GetLibrary(int index) const;
   void AddImport(const Namespace& import) const;
 
   bool is_deferred_load() const { return raw_ptr()->is_deferred_load_; }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawLibraryPrefix));
+    return RoundedAllocationSize(sizeof(LibraryPrefixLayout));
   }
 
-  static RawLibraryPrefix* New(const String& name,
-                               const Namespace& import,
-                               bool deferred_load,
-                               const Library& importer);
+  static LibraryPrefixPtr New(const String& name,
+                              const Namespace& import,
+                              bool deferred_load,
+                              const Library& importer);
 
  private:
   static const int kInitialSize = 2;
@@ -7278,7 +7294,7 @@
   void set_num_imports(intptr_t value) const;
   void set_importer(const Library& value) const;
 
-  static RawLibraryPrefix* New();
+  static LibraryPrefixPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix, Instance);
   friend class Class;
@@ -7293,15 +7309,15 @@
   static const intptr_t kHashBits = 30;
 
   intptr_t Length() const;
-  RawAbstractType* TypeAt(intptr_t index) const;
-  RawAbstractType* TypeAtNullSafe(intptr_t index) const;
+  AbstractTypePtr TypeAt(intptr_t index) const;
+  AbstractTypePtr TypeAtNullSafe(intptr_t index) const;
   static intptr_t type_at_offset(intptr_t index) {
-    return OFFSET_OF_RETURNED_VALUE(RawTypeArguments, types) +
+    return OFFSET_OF_RETURNED_VALUE(TypeArgumentsLayout, types) +
            index * kWordSize;
   }
   void SetTypeAt(intptr_t index, const AbstractType& value) const;
 
-  struct ArrayLayout {
+  struct ArrayTraits {
     static intptr_t elements_start_offset() {
       return TypeArguments::type_at_offset(0);
     }
@@ -7331,15 +7347,15 @@
   static const intptr_t kLegacyBits = 2;
   intptr_t nullability() const;
   static intptr_t nullability_offset() {
-    return OFFSET_OF(RawTypeArguments, nullability_);
+    return OFFSET_OF(TypeArgumentsLayout, nullability_);
   }
 
   // The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>".
-  RawString* Name() const;
+  StringPtr Name() const;
 
   // The name of this type argument vector, e.g. "<T, dynamic, List<T>, int>".
   // Names of internal classes are mapped to their public interfaces.
-  RawString* UserVisibleName() const;
+  StringPtr UserVisibleName() const;
 
   // Print the internal or public name of a subvector of this type argument
   // vector, e.g. "<T, dynamic, List<T>, int>".
@@ -7364,26 +7380,14 @@
     return IsDynamicTypes(true, 0, len);
   }
 
-  RawTypeArguments* Prepend(Zone* zone,
-                            const TypeArguments& other,
-                            intptr_t other_length,
-                            intptr_t total_length) const;
+  TypeArgumentsPtr Prepend(Zone* zone,
+                           const TypeArguments& other,
+                           intptr_t other_length,
+                           intptr_t total_length) const;
 
   // Concatenate [this] and [other] vectors of type parameters.
-  RawTypeArguments* ConcatenateTypeParameters(Zone* zone,
-                                              const TypeArguments& other) const;
-
-  // Check if the subvector of length 'len' starting at 'from_index' of this
-  // type argument vector consists solely of DynamicType, (nullable) ObjectType,
-  // or VoidType.
-  bool IsTopTypes(intptr_t from_index, intptr_t len) const;
-
-  // Check the subtype relationship, considering only a subvector of length
-  // 'len' starting at 'from_index'.
-  bool IsSubtypeOf(const TypeArguments& other,
-                   intptr_t from_index,
-                   intptr_t len,
-                   Heap::Space space) const;
+  TypeArgumentsPtr ConcatenateTypeParameters(Zone* zone,
+                                             const TypeArguments& other) const;
 
   // Check if the vectors are equal (they may be null).
   bool Equals(const TypeArguments& other) const {
@@ -7436,13 +7440,13 @@
   // Return true if this vector contains a recursive type argument.
   bool IsRecursive() const;
 
-  virtual RawInstance* CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const {
+  virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const {
     return Canonicalize();
   }
 
   // Canonicalize only if instantiated, otherwise returns 'this'.
-  RawTypeArguments* Canonicalize(TrailPtr trail = NULL) const;
+  TypeArgumentsPtr Canonicalize(TrailPtr trail = NULL) const;
 
   // Add the class name and URI of each type argument of this vector to the uris
   // list and mark ambiguous triplets to be printed.
@@ -7453,7 +7457,7 @@
   // where each reference to a type parameter is replaced with the corresponding
   // type from the various type argument vectors (class instantiator, function,
   // or parent functions via the current context).
-  RawTypeArguments* InstantiateFrom(
+  TypeArgumentsPtr InstantiateFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments,
       intptr_t num_free_fun_type_params,
@@ -7462,7 +7466,7 @@
 
   // Runtime instantiation with canonicalization. Not to be used during type
   // finalization at compile time.
-  RawTypeArguments* InstantiateAndCanonicalizeFrom(
+  TypeArgumentsPtr InstantiateAndCanonicalizeFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments) const;
 
@@ -7489,25 +7493,25 @@
   intptr_t NumInstantiations() const;
 
   static intptr_t instantiations_offset() {
-    return OFFSET_OF(RawTypeArguments, instantiations_);
+    return OFFSET_OF(TypeArgumentsLayout, instantiations_);
   }
 
   static const intptr_t kBytesPerElement = kWordSize;
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawTypeArguments) ==
-           OFFSET_OF_RETURNED_VALUE(RawTypeArguments, types));
+    ASSERT(sizeof(TypeArgumentsLayout) ==
+           OFFSET_OF_RETURNED_VALUE(TypeArgumentsLayout, types));
     return 0;
   }
 
   static intptr_t InstanceSize(intptr_t len) {
     // Ensure that the types() is not adding to the object size, which includes
     // 4 fields: instantiations_, length_, hash_, and nullability_.
-    ASSERT(sizeof(RawTypeArguments) ==
-           (sizeof(RawObject) + (kNumFields * kWordSize)));
+    ASSERT(sizeof(TypeArgumentsLayout) ==
+           (sizeof(ObjectLayout) + (kNumFields * kWordSize)));
     ASSERT(0 <= len && len <= kMaxElements);
-    return RoundedAllocationSize(sizeof(RawTypeArguments) +
+    return RoundedAllocationSize(sizeof(TypeArgumentsLayout) +
                                  (len * kBytesPerElement));
   }
 
@@ -7517,7 +7521,7 @@
   }
   intptr_t Hash() const;
 
-  static RawTypeArguments* New(intptr_t len, Heap::Space space = Heap::kOld);
+  static TypeArgumentsPtr New(intptr_t len, Heap::Space space = Heap::kOld);
 
  private:
   intptr_t ComputeNullability() const;
@@ -7534,9 +7538,9 @@
                       intptr_t from_index,
                       intptr_t len) const;
 
-  RawArray* instantiations() const;
+  ArrayPtr instantiations() const;
   void set_instantiations(const Array& value) const;
-  RawAbstractType* const* TypeAddr(intptr_t index) const;
+  AbstractTypePtr const* TypeAddr(intptr_t index) const;
   void SetLength(intptr_t value) const;
   // Number of fields in the raw object is 4:
   // instantiations_, length_, hash_ and nullability_.
@@ -7566,30 +7570,30 @@
   virtual Nullability nullability() const;
   // Returns true if type has '?' nullability suffix, or it is a
   // built-in type which is always nullable (Null, dynamic or void).
-  virtual bool IsNullable() const {
-    return nullability() == Nullability::kNullable;
-  }
+  bool IsNullable() const { return nullability() == Nullability::kNullable; }
   // Returns true if type does not have any nullability suffix.
   // This function also returns true for type parameters without
   // nullability suffix ("T") which can be instantiated with
   // nullable or legacy types.
-  virtual bool IsNonNullable() const {
+  bool IsNonNullable() const {
     return nullability() == Nullability::kNonNullable;
   }
   // Returns true if type has '*' nullability suffix, i.e.
   // it is from a legacy (opted-out) library.
-  virtual bool IsLegacy() const {
-    return nullability() == Nullability::kLegacy;
-  }
-  virtual RawAbstractType* SetInstantiatedNullability(
+  bool IsLegacy() const { return nullability() == Nullability::kLegacy; }
+  // Returns true if it is guaranteed that null cannot be
+  // assigned to this type.
+  bool IsStrictlyNonNullable() const;
+
+  virtual AbstractTypePtr SetInstantiatedNullability(
       const TypeParameter& type_param,
       Heap::Space space) const;
-  virtual RawAbstractType* NormalizeFutureOrType(Heap::Space space) const;
+  virtual AbstractTypePtr NormalizeFutureOrType(Heap::Space space) const;
 
   virtual bool HasTypeClass() const { return type_class_id() != kIllegalCid; }
   virtual classid_t type_class_id() const;
-  virtual RawClass* type_class() const;
-  virtual RawTypeArguments* arguments() const;
+  virtual ClassPtr type_class() const;
+  virtual TypeArgumentsPtr arguments() const;
   virtual void set_arguments(const TypeArguments& value) const;
   virtual TokenPosition token_pos() const;
   virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -7621,20 +7625,20 @@
   // must remain uninstantiated, because only T is a free variable in this type.
   //
   // Return a new type, or return 'this' if it is already instantiated.
-  virtual RawAbstractType* InstantiateFrom(
+  virtual AbstractTypePtr InstantiateFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments,
       intptr_t num_free_fun_type_params,
       TrailPtr instantiation_trail,
       Heap::Space space) const;
 
-  virtual RawInstance* CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const {
+  virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const {
     return Canonicalize();
   }
 
   // Return the canonical version of this type.
-  virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+  virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const;
 
 #if defined(DEBUG)
   // Check if abstract type is canonical.
@@ -7646,7 +7650,7 @@
 
   // Return the object associated with the receiver in the trail or
   // AbstractType::null() if the receiver is not contained in the trail.
-  RawAbstractType* OnlyBuddyInTrail(TrailPtr trail) const;
+  AbstractTypePtr OnlyBuddyInTrail(TrailPtr trail) const;
 
   // If the trail is null, allocate a trail, add the pair <receiver, buddy> to
   // the trail. The receiver may only be added once with its only buddy.
@@ -7667,18 +7671,18 @@
   static void AddURI(URIs* uris, const String& name, const String& uri);
 
   // Return a formatted string of the uris.
-  static RawString* PrintURIs(URIs* uris);
+  static StringPtr PrintURIs(URIs* uris);
 
   // Returns a C-String (possibly "") representing the nullability of this type.
   // Legacy and undetermined suffixes are only displayed with kInternalName.
   virtual const char* NullabilitySuffix(NameVisibility name_visibility) const;
 
   // The name of this type, including the names of its type arguments, if any.
-  virtual RawString* Name() const;
+  virtual StringPtr Name() const;
 
   // The name of this type, including the names of its type arguments, if any.
   // Names of internal classes are mapped to their public interfaces.
-  virtual RawString* UserVisibleName() const;
+  virtual StringPtr UserVisibleName() const;
 
   // Return the internal or public name of this type, including the names of its
   // type arguments, if any.
@@ -7692,7 +7696,7 @@
 
   // The name of this type's class, i.e. without the type argument names of this
   // type.
-  RawString* ClassName() const;
+  StringPtr ClassName() const;
 
   // Check if this type is a still uninitialized TypeRef.
   bool IsNullTypeRef() const;
@@ -7712,15 +7716,18 @@
   // Check if this type represents the 'Object' type.
   bool IsObjectType() const { return type_class_id() == kInstanceCid; }
 
-  // Check if this type represents a top type.
-  bool IsTopType() const;
+  // Check if this type represents a top type for subtyping,
+  // assignability and 'as' type tests.
+  //
+  // Returns true if
+  //  - any type is a subtype of this type;
+  //  - any value can be assigned to a variable of this type;
+  //  - 'as' type test always succeeds for this type.
+  bool IsTopTypeForSubtyping() const;
 
-  // Check if this type represents a top type with respect to
-  // assignability and 'as' type tests, e.g. returns true if any value can be
-  // assigned to a variable of this type and 'as' type test always succeeds.
-  // Guaranteed to return true for top types according to IsTopType(), but
-  // may also return true for other types (non-nullable Object in weak mode).
-  bool IsTopTypeForAssignability() const;
+  // Check if this type represents a top type for 'is' type tests.
+  // Returns true if 'is' type test always returns true for this type.
+  bool IsTopTypeForInstanceOf() const;
 
   // Check if this type represents the 'bool' type.
   bool IsBoolType() const { return type_class_id() == kBoolCid; }
@@ -7763,7 +7770,7 @@
 
   // Returns the type argument of this (possibly nested) 'FutureOr' type.
   // Returns unmodified type if this type is not a 'FutureOr' type.
-  RawAbstractType* UnwrapFutureOr() const;
+  AbstractTypePtr UnwrapFutureOr() const;
 
   // Check the subtype relationship.
   bool IsSubtypeOf(const AbstractType& other, Heap::Space space) const;
@@ -7777,13 +7784,13 @@
       const TypeArguments& function_type_args);
 
   static intptr_t type_test_stub_entry_point_offset() {
-    return OFFSET_OF(RawAbstractType, type_test_stub_entry_point_);
+    return OFFSET_OF(AbstractTypeLayout, type_test_stub_entry_point_);
   }
 
   uword type_test_stub_entry_point() const {
     return raw_ptr()->type_test_stub_entry_point_;
   }
-  RawCode* type_test_stub() const { return raw_ptr()->type_test_stub_; }
+  CodePtr type_test_stub() const { return raw_ptr()->type_test_stub_; }
 
   void SetTypeTestingStub(const Code& stub) const;
 
@@ -7804,30 +7811,32 @@
 // A Type consists of a class, possibly parameterized with type
 // arguments. Example: C<T1, T2>.
 //
-// Caution: 'RawType*' denotes a 'raw' pointer to a VM object of class Type, as
+// Caution: 'TypePtr' denotes a 'raw' pointer to a VM object of class Type, as
 // opposed to 'Type' denoting a 'handle' to the same object. 'RawType' does not
 // relate to a 'raw type', as opposed to a 'cooked type' or 'rare type'.
 class Type : public AbstractType {
  public:
   static intptr_t type_class_id_offset() {
-    return OFFSET_OF(RawType, type_class_id_);
+    return OFFSET_OF(TypeLayout, type_class_id_);
   }
-  static intptr_t arguments_offset() { return OFFSET_OF(RawType, arguments_); }
+  static intptr_t arguments_offset() {
+    return OFFSET_OF(TypeLayout, arguments_);
+  }
   static intptr_t type_state_offset() {
-    return OFFSET_OF(RawType, type_state_);
+    return OFFSET_OF(TypeLayout, type_state_);
   }
-  static intptr_t hash_offset() { return OFFSET_OF(RawType, hash_); }
+  static intptr_t hash_offset() { return OFFSET_OF(TypeLayout, hash_); }
   static intptr_t nullability_offset() {
-    return OFFSET_OF(RawType, nullability_);
+    return OFFSET_OF(TypeLayout, nullability_);
   }
   virtual bool IsFinalized() const {
-    return (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
-           (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated);
+    return (raw_ptr()->type_state_ == TypeLayout::kFinalizedInstantiated) ||
+           (raw_ptr()->type_state_ == TypeLayout::kFinalizedUninstantiated);
   }
   virtual void SetIsFinalized() const;
   void ResetIsFinalized() const;  // Ignore current state and set again.
   virtual bool IsBeingFinalized() const {
-    return raw_ptr()->type_state_ == RawType::kBeingFinalized;
+    return raw_ptr()->type_state_ == TypeLayout::kBeingFinalized;
   }
   virtual void SetIsBeingFinalized() const;
   virtual bool HasTypeClass() const {
@@ -7837,11 +7846,11 @@
   virtual Nullability nullability() const {
     return static_cast<Nullability>(raw_ptr()->nullability_);
   }
-  RawType* ToNullability(Nullability value, Heap::Space space) const;
+  TypePtr ToNullability(Nullability value, Heap::Space space) const;
   virtual classid_t type_class_id() const;
-  virtual RawClass* type_class() const;
+  virtual ClassPtr type_class() const;
   void set_type_class(const Class& value) const;
-  virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
+  virtual TypeArgumentsPtr arguments() const { return raw_ptr()->arguments_; }
   virtual void set_arguments(const TypeArguments& value) const;
   virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -7860,20 +7869,22 @@
   // the signature fully represents the type and type arguments can be ignored.
   // However, in case of a generic typedef, they document how the typedef class
   // was parameterized to obtain the actual signature.
-  RawFunction* signature() const;
+  FunctionPtr signature() const;
   void set_signature(const Function& value) const;
-  static intptr_t signature_offset() { return OFFSET_OF(RawType, signature_); }
+  static intptr_t signature_offset() {
+    return OFFSET_OF(TypeLayout, signature_);
+  }
 
   virtual bool IsFunctionType() const {
     return signature() != Function::null();
   }
-  virtual RawAbstractType* InstantiateFrom(
+  virtual AbstractTypePtr InstantiateFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments,
       intptr_t num_free_fun_type_params,
       TrailPtr instantiation_trail,
       Heap::Space space) const;
-  virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+  virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const;
 #if defined(DEBUG)
   // Check if type is canonical.
   virtual bool CheckIsCanonical(Thread* thread) const;
@@ -7884,71 +7895,77 @@
   intptr_t ComputeHash() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawType));
+    return RoundedAllocationSize(sizeof(TypeLayout));
   }
 
   // The type of the literal 'null'.
-  static RawType* NullType();
+  static TypePtr NullType();
 
   // The 'dynamic' type.
-  static RawType* DynamicType();
+  static TypePtr DynamicType();
 
   // The 'void' type.
-  static RawType* VoidType();
+  static TypePtr VoidType();
 
   // The 'Never' type.
-  static RawType* NeverType();
+  static TypePtr NeverType();
 
   // The 'Object' type.
-  static RawType* ObjectType();
+  static TypePtr ObjectType();
 
   // The 'bool' type.
-  static RawType* BoolType();
+  static TypePtr BoolType();
 
   // The 'int' type.
-  static RawType* IntType();
+  static TypePtr IntType();
+
+  // The 'int?' type.
+  static TypePtr NullableIntType();
 
   // The 'Smi' type.
-  static RawType* SmiType();
+  static TypePtr SmiType();
 
   // The 'Mint' type.
-  static RawType* MintType();
+  static TypePtr MintType();
 
   // The 'double' type.
-  static RawType* Double();
+  static TypePtr Double();
+
+  // The 'double?' type.
+  static TypePtr NullableDouble();
 
   // The 'Float32x4' type.
-  static RawType* Float32x4();
+  static TypePtr Float32x4();
 
   // The 'Float64x2' type.
-  static RawType* Float64x2();
+  static TypePtr Float64x2();
 
   // The 'Int32x4' type.
-  static RawType* Int32x4();
+  static TypePtr Int32x4();
 
   // The 'num' type.
-  static RawType* Number();
+  static TypePtr Number();
 
   // The 'String' type.
-  static RawType* StringType();
+  static TypePtr StringType();
 
   // The 'Array' type.
-  static RawType* ArrayType();
+  static TypePtr ArrayType();
 
   // The 'Function' type.
-  static RawType* DartFunctionType();
+  static TypePtr DartFunctionType();
 
   // The 'Type' type.
-  static RawType* DartTypeType();
+  static TypePtr DartTypeType();
 
   // The finalized type of the given non-parameterized class.
-  static RawType* NewNonParameterizedType(const Class& type_class);
+  static TypePtr NewNonParameterizedType(const Class& type_class);
 
-  static RawType* New(const Class& clazz,
-                      const TypeArguments& arguments,
-                      TokenPosition token_pos,
-                      Nullability nullability = Nullability::kLegacy,
-                      Heap::Space space = Heap::kOld);
+  static TypePtr New(const Class& clazz,
+                     const TypeArguments& arguments,
+                     TokenPosition token_pos,
+                     Nullability nullability = Nullability::kLegacy,
+                     Heap::Space space = Heap::kOld);
 
  private:
   void SetHash(intptr_t value) const;
@@ -7960,7 +7977,7 @@
     StoreNonPointer(&raw_ptr()->nullability_, static_cast<int8_t>(value));
   }
 
-  static RawType* New(Heap::Space space = Heap::kOld);
+  static TypePtr New(Heap::Space space = Heap::kOld);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
   friend class Class;
@@ -7974,7 +7991,7 @@
 // Note that the cycle always involves type arguments.
 class TypeRef : public AbstractType {
  public:
-  static intptr_t type_offset() { return OFFSET_OF(RawTypeRef, type_); }
+  static intptr_t type_offset() { return OFFSET_OF(TypeRefLayout, type_); }
 
   virtual bool IsFinalized() const {
     const AbstractType& ref_type = AbstractType::Handle(type());
@@ -7993,15 +8010,15 @@
     return (type() != AbstractType::null()) &&
            AbstractType::Handle(type()).HasTypeClass();
   }
-  RawAbstractType* type() const { return raw_ptr()->type_; }
+  AbstractTypePtr type() const { return raw_ptr()->type_; }
   void set_type(const AbstractType& value) const;
   virtual classid_t type_class_id() const {
     return AbstractType::Handle(type()).type_class_id();
   }
-  virtual RawClass* type_class() const {
+  virtual ClassPtr type_class() const {
     return AbstractType::Handle(type()).type_class();
   }
-  virtual RawTypeArguments* arguments() const {
+  virtual TypeArgumentsPtr arguments() const {
     return AbstractType::Handle(type()).arguments();
   }
   virtual TokenPosition token_pos() const {
@@ -8018,13 +8035,13 @@
     const AbstractType& ref_type = AbstractType::Handle(type());
     return !ref_type.IsNull() && ref_type.IsFunctionType();
   }
-  virtual RawTypeRef* InstantiateFrom(
+  virtual AbstractTypePtr InstantiateFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments,
       intptr_t num_free_fun_type_params,
       TrailPtr instantiation_trail,
       Heap::Space space) const;
-  virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+  virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const;
 #if defined(DEBUG)
   // Check if typeref is canonical.
   virtual bool CheckIsCanonical(Thread* thread) const;
@@ -8034,13 +8051,13 @@
   virtual intptr_t Hash() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawTypeRef));
+    return RoundedAllocationSize(sizeof(TypeRefLayout));
   }
 
-  static RawTypeRef* New(const AbstractType& type);
+  static TypeRefPtr New(const AbstractType& type);
 
  private:
-  static RawTypeRef* New();
+  static TypeRefPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeRef, AbstractType);
   friend class Class;
@@ -8059,23 +8076,24 @@
 class TypeParameter : public AbstractType {
  public:
   virtual bool IsFinalized() const {
-    return RawTypeParameter::FinalizedBit::decode(raw_ptr()->flags_);
+    return TypeParameterLayout::FinalizedBit::decode(raw_ptr()->flags_);
   }
   virtual void SetIsFinalized() const;
   virtual bool IsBeingFinalized() const { return false; }
   bool IsGenericCovariantImpl() const {
-    return RawTypeParameter::GenericCovariantImplBit::decode(raw_ptr()->flags_);
+    return TypeParameterLayout::GenericCovariantImplBit::decode(
+        raw_ptr()->flags_);
   }
   void SetGenericCovariantImpl(bool value) const;
   virtual Nullability nullability() const {
     return static_cast<Nullability>(raw_ptr()->nullability_);
   }
-  RawTypeParameter* ToNullability(Nullability value, Heap::Space space) const;
+  TypeParameterPtr ToNullability(Nullability value, Heap::Space space) const;
   virtual bool HasTypeClass() const { return false; }
   virtual classid_t type_class_id() const { return kIllegalCid; }
   classid_t parameterized_class_id() const;
-  RawClass* parameterized_class() const;
-  RawFunction* parameterized_function() const {
+  ClassPtr parameterized_class() const;
+  FunctionPtr parameterized_function() const {
     return raw_ptr()->parameterized_function_;
   }
   bool IsClassTypeParameter() const {
@@ -8084,10 +8102,10 @@
   bool IsFunctionTypeParameter() const {
     return parameterized_function() != Function::null();
   }
-  RawString* name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name_; }
   intptr_t index() const { return raw_ptr()->index_; }
   void set_index(intptr_t value) const;
-  RawAbstractType* bound() const { return raw_ptr()->bound_; }
+  AbstractTypePtr bound() const { return raw_ptr()->bound_; }
   void set_bound(const AbstractType& value) const;
   virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -8097,13 +8115,13 @@
                             TypeEquality kind,
                             TrailPtr trail = NULL) const;
   virtual bool IsRecursive() const { return false; }
-  virtual RawAbstractType* InstantiateFrom(
+  virtual AbstractTypePtr InstantiateFrom(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments,
       intptr_t num_free_fun_type_params,
       TrailPtr instantiation_trail,
       Heap::Space space) const;
-  virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const {
+  virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const {
     return raw();
   }
 #if defined(DEBUG)
@@ -8118,23 +8136,23 @@
   // given [instantiator_type_arguments] and [function_type_arguments].
   // Unlike InstantiateFrom, nullability of type parameter is not applied to
   // the result.
-  RawAbstractType* GetFromTypeArguments(
+  AbstractTypePtr GetFromTypeArguments(
       const TypeArguments& instantiator_type_arguments,
       const TypeArguments& function_type_arguments) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawTypeParameter));
+    return RoundedAllocationSize(sizeof(TypeParameterLayout));
   }
 
   // Only one of parameterized_class and parameterized_function is non-null.
-  static RawTypeParameter* New(const Class& parameterized_class,
-                               const Function& parameterized_function,
-                               intptr_t index,
-                               const String& name,
-                               const AbstractType& bound,
-                               bool is_generic_covariant_impl,
-                               Nullability nullability,
-                               TokenPosition token_pos);
+  static TypeParameterPtr New(const Class& parameterized_class,
+                              const Function& parameterized_function,
+                              intptr_t index,
+                              const String& name,
+                              const AbstractType& bound,
+                              bool is_generic_covariant_impl,
+                              Nullability nullability,
+                              TokenPosition token_pos);
 
  private:
   intptr_t ComputeHash() const;
@@ -8147,7 +8165,7 @@
   void set_flags(uint8_t flags) const;
   void set_nullability(Nullability value) const;
 
-  static RawTypeParameter* New();
+  static TypeParameterPtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
   friend class Class;
@@ -8157,11 +8175,11 @@
 class Number : public Instance {
  public:
   // TODO(iposva): Add more useful Number methods.
-  RawString* ToString(Heap::Space space) const;
+  StringPtr ToString(Heap::Space space) const;
 
   // Numbers are canonicalized differently from other instances/strings.
-  virtual RawInstance* CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const;
+  virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const;
 
 #if defined(DEBUG)
   // Check if number is canonical.
@@ -8176,20 +8194,20 @@
 
 class Integer : public Number {
  public:
-  static RawInteger* New(const String& str, Heap::Space space = Heap::kNew);
+  static IntegerPtr New(const String& str, Heap::Space space = Heap::kNew);
 
   // Creates a new Integer by given uint64_t value.
   // Silently casts value to int64_t with wrap-around if it is greater
   // than kMaxInt64.
-  static RawInteger* NewFromUint64(uint64_t value,
-                                   Heap::Space space = Heap::kNew);
+  static IntegerPtr NewFromUint64(uint64_t value,
+                                  Heap::Space space = Heap::kNew);
 
   // Returns a canonical Integer object allocated in the old gen space.
   // Returns null if integer is out of range.
-  static RawInteger* NewCanonical(const String& str);
-  static RawInteger* NewCanonical(int64_t value);
+  static IntegerPtr NewCanonical(const String& str);
+  static IntegerPtr NewCanonical(int64_t value);
 
-  static RawInteger* New(int64_t value, Heap::Space space = Heap::kNew);
+  static IntegerPtr New(int64_t value, Heap::Space space = Heap::kNew);
 
   // Returns true iff the given uint64_t value is representable as Dart integer.
   static bool IsValueInRange(uint64_t value);
@@ -8203,7 +8221,7 @@
   virtual uint32_t CanonicalizeHash() const { return AsTruncatedUint32Value(); }
   virtual bool Equals(const Instance& other) const;
 
-  virtual RawObject* HashCode() const { return raw(); }
+  virtual ObjectPtr HashCode() const { return raw(); }
 
   virtual bool IsZero() const;
   virtual bool IsNegative() const;
@@ -8222,26 +8240,26 @@
   const char* ToHexCString(Zone* zone) const;
 
   // Return the most compact presentation of an integer.
-  RawInteger* AsValidInteger() const;
+  IntegerPtr AsValidInteger() const;
 
   // Returns null to indicate that a bigint operation is required.
-  RawInteger* ArithmeticOp(Token::Kind operation,
-                           const Integer& other,
-                           Heap::Space space = Heap::kNew) const;
-  RawInteger* BitOp(Token::Kind operation,
-                    const Integer& other,
-                    Heap::Space space = Heap::kNew) const;
-  RawInteger* ShiftOp(Token::Kind operation,
-                      const Integer& other,
-                      Heap::Space space = Heap::kNew) const;
+  IntegerPtr ArithmeticOp(Token::Kind operation,
+                          const Integer& other,
+                          Heap::Space space = Heap::kNew) const;
+  IntegerPtr BitOp(Token::Kind operation,
+                   const Integer& other,
+                   Heap::Space space = Heap::kNew) const;
+  IntegerPtr ShiftOp(Token::Kind operation,
+                     const Integer& other,
+                     Heap::Space space = Heap::kNew) const;
 
-  static int64_t GetInt64Value(const RawInteger* obj) {
-    intptr_t raw_value = reinterpret_cast<intptr_t>(obj);
+  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);
     } else {
       ASSERT(obj->IsMint());
-      return reinterpret_cast<const RawMint*>(obj)->ptr()->value_;
+      return static_cast<const MintPtr>(obj)->ptr()->value_;
     }
   }
 
@@ -8256,7 +8274,7 @@
   static const intptr_t kMaxValue = kSmiMax;
   static const intptr_t kMinValue = kSmiMin;
 
-  intptr_t Value() const { return ValueFromRawSmi(raw()); }
+  intptr_t Value() const { return RawSmiValue(raw()); }
 
   virtual bool Equals(const Instance& other) const;
   virtual bool IsZero() const { return Value() == 0; }
@@ -8272,35 +8290,33 @@
 
   static intptr_t InstanceSize() { return 0; }
 
-  static RawSmi* New(intptr_t value) {
-    RawSmi* raw_smi = reinterpret_cast<RawSmi*>(
+  static SmiPtr New(intptr_t value) {
+    SmiPtr raw_smi = static_cast<SmiPtr>(
         (static_cast<uintptr_t>(value) << kSmiTagShift) | kSmiTag);
-    ASSERT(ValueFromRawSmi(raw_smi) == value);
+    ASSERT(RawSmiValue(raw_smi) == value);
     return raw_smi;
   }
 
-  static RawSmi* FromAlignedAddress(uword address) {
+  static SmiPtr FromAlignedAddress(uword address) {
     ASSERT((address & kSmiTagMask) == kSmiTag);
-    return reinterpret_cast<RawSmi*>(address);
+    return static_cast<SmiPtr>(address);
   }
 
-  static RawClass* Class();
+  static ClassPtr Class();
 
-  static intptr_t Value(const RawSmi* raw_smi) {
-    return ValueFromRawSmi(raw_smi);
-  }
+  static intptr_t Value(const SmiPtr raw_smi) { return RawSmiValue(raw_smi); }
 
   static intptr_t RawValue(intptr_t value) {
-    return reinterpret_cast<intptr_t>(New(value));
+    return static_cast<intptr_t>(New(value));
   }
 
   static bool IsValid(int64_t value) { return compiler::target::IsSmi(value); }
 
-  void operator=(RawSmi* value) {
+  void operator=(SmiPtr value) {
     raw_ = value;
     CHECK_HANDLE();
   }
-  void operator^=(RawObject* value) {
+  void operator^=(ObjectPtr value) {
     raw_ = value;
     CHECK_HANDLE();
   }
@@ -8342,7 +8358,7 @@
       static_cast<int64_t>(DART_2PART_UINT64_C(0x80000000, 00000000));
 
   int64_t value() const { return raw_ptr()->value_; }
-  static intptr_t value_offset() { return OFFSET_OF(RawMint, value_); }
+  static intptr_t value_offset() { return OFFSET_OF(MintLayout, value_); }
 
   virtual bool IsZero() const { return value() == 0; }
   virtual bool IsNegative() const { return value() < 0; }
@@ -8358,16 +8374,16 @@
   virtual int CompareWith(const Integer& other) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawMint));
+    return RoundedAllocationSize(sizeof(MintLayout));
   }
 
  protected:
   // Only Integer::NewXXX is allowed to call Mint::NewXXX directly.
   friend class Integer;
 
-  static RawMint* New(int64_t value, Heap::Space space = Heap::kNew);
+  static MintPtr New(int64_t value, Heap::Space space = Heap::kNew);
 
-  static RawMint* NewCanonical(int64_t value);
+  static MintPtr NewCanonical(int64_t value);
 
  private:
   void set_value(int64_t value) const;
@@ -8388,23 +8404,23 @@
   virtual bool CanonicalizeEquals(const Instance& other) const;
   virtual uint32_t CanonicalizeHash() const;
 
-  static RawDouble* New(double d, Heap::Space space = Heap::kNew);
+  static DoublePtr New(double d, Heap::Space space = Heap::kNew);
 
-  static RawDouble* New(const String& str, Heap::Space space = Heap::kNew);
+  static DoublePtr New(const String& str, Heap::Space space = Heap::kNew);
 
   // Returns a canonical double object allocated in the old gen space.
-  static RawDouble* NewCanonical(double d);
+  static DoublePtr NewCanonical(double d);
 
   // Returns a canonical double object (allocated in the old gen space) or
   // Double::null() if str points to a string that does not convert to a
   // double value.
-  static RawDouble* NewCanonical(const String& str);
+  static DoublePtr NewCanonical(const String& str);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawDouble));
+    return RoundedAllocationSize(sizeof(DoubleLayout));
   }
 
-  static intptr_t value_offset() { return OFFSET_OF(RawDouble, value_); }
+  static intptr_t value_offset() { return OFFSET_OF(DoubleLayout, value_); }
 
  private:
   void set_value(double value) const;
@@ -8429,9 +8445,10 @@
 // simple.  We choose a value that will prevent integer overflow for
 // 2 byte strings, since it is the worst case.
 #if defined(HASH_IN_OBJECT_HEADER)
-  static const intptr_t kSizeofRawString = sizeof(RawInstance) + kWordSize;
+  static const intptr_t kSizeofRawString = sizeof(InstanceLayout) + kWordSize;
 #else
-  static const intptr_t kSizeofRawString = sizeof(RawInstance) + 2 * kWordSize;
+  static const intptr_t kSizeofRawString =
+      sizeof(InstanceLayout) + 2 * kWordSize;
 #endif
   static const intptr_t kMaxElements = kSmiMax / kTwoByteChar;
 
@@ -8465,7 +8482,7 @@
   };
 
   intptr_t Length() const { return Smi::Value(raw_ptr()->length_); }
-  static intptr_t length_offset() { return OFFSET_OF(RawString, length_); }
+  static intptr_t length_offset() { return OFFSET_OF(StringLayout, length_); }
 
   intptr_t Hash() const {
     intptr_t result = GetCachedHash(raw());
@@ -8477,20 +8494,20 @@
     return result;
   }
 
-  static intptr_t Hash(RawString* raw);
+  static intptr_t Hash(StringPtr raw);
 
   bool HasHash() const {
-    ASSERT(Smi::New(0) == NULL);
+    ASSERT(Smi::New(0) == nullptr);
     return GetCachedHash(raw()) != 0;
   }
 
-  static intptr_t hash_offset() { return OFFSET_OF(RawString, hash_); }
+  static intptr_t hash_offset() { return OFFSET_OF(StringLayout, hash_); }
   static intptr_t Hash(const String& str, intptr_t begin_index, intptr_t len);
   static intptr_t Hash(const char* characters, intptr_t len);
   static intptr_t Hash(const uint16_t* characters, intptr_t len);
   static intptr_t Hash(const int32_t* characters, intptr_t len);
-  static intptr_t HashRawSymbol(const RawString* symbol) {
-    ASSERT(symbol->IsCanonical());
+  static intptr_t HashRawSymbol(const StringPtr symbol) {
+    ASSERT(symbol->ptr()->IsCanonical());
     intptr_t result = GetCachedHash(symbol);
     ASSERT(result != 0);
     return result;
@@ -8499,7 +8516,7 @@
   // Returns the hash of str1 + str2.
   static intptr_t HashConcat(const String& str1, const String& str2);
 
-  virtual RawObject* HashCode() const { return Integer::New(Hash()); }
+  virtual ObjectPtr HashCode() const { return Integer::New(Hash()); }
 
   uint16_t CharAt(intptr_t index) const;
 
@@ -8543,15 +8560,15 @@
   bool EndsWith(const String& other) const;
 
   // Strings are canonicalized using the symbol table.
-  virtual RawInstance* CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const;
+  virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const;
 
 #if defined(DEBUG)
   // Check if string is canonical.
   virtual bool CheckIsCanonical(Thread* thread) const;
 #endif  // DEBUG
 
-  bool IsSymbol() const { return raw()->IsCanonical(); }
+  bool IsSymbol() const { return raw()->ptr()->IsCanonical(); }
 
   bool IsOneByteString() const {
     return raw()->GetClassId() == kOneByteStringCid;
@@ -8570,7 +8587,7 @@
   }
 
   bool IsExternal() const {
-    return RawObject::IsExternalStringClassId(raw()->GetClassId());
+    return IsExternalStringClassId(raw()->GetClassId());
   }
 
   void* GetPeer() const;
@@ -8581,48 +8598,48 @@
   // Creates a new String object from a C string that is assumed to contain
   // UTF-8 encoded characters and '\0' is considered a termination character.
   // TODO(7123) - Rename this to FromCString(....).
-  static RawString* New(const char* cstr, Heap::Space space = Heap::kNew);
+  static StringPtr New(const char* cstr, Heap::Space space = Heap::kNew);
 
   // Creates a new String object from an array of UTF-8 encoded characters.
-  static RawString* FromUTF8(const uint8_t* utf8_array,
+  static StringPtr FromUTF8(const uint8_t* utf8_array,
+                            intptr_t array_len,
+                            Heap::Space space = Heap::kNew);
+
+  // Creates a new String object from an array of Latin-1 encoded characters.
+  static StringPtr FromLatin1(const uint8_t* latin1_array,
+                              intptr_t array_len,
+                              Heap::Space space = Heap::kNew);
+
+  // Creates a new String object from an array of UTF-16 encoded characters.
+  static StringPtr FromUTF16(const uint16_t* utf16_array,
                              intptr_t array_len,
                              Heap::Space space = Heap::kNew);
 
-  // Creates a new String object from an array of Latin-1 encoded characters.
-  static RawString* FromLatin1(const uint8_t* latin1_array,
-                               intptr_t array_len,
-                               Heap::Space space = Heap::kNew);
-
-  // Creates a new String object from an array of UTF-16 encoded characters.
-  static RawString* FromUTF16(const uint16_t* utf16_array,
-                              intptr_t array_len,
-                              Heap::Space space = Heap::kNew);
-
   // Creates a new String object from an array of UTF-32 encoded characters.
-  static RawString* FromUTF32(const int32_t* utf32_array,
-                              intptr_t array_len,
-                              Heap::Space space = Heap::kNew);
+  static StringPtr FromUTF32(const int32_t* utf32_array,
+                             intptr_t array_len,
+                             Heap::Space space = Heap::kNew);
 
   // Create a new String object from another Dart String instance.
-  static RawString* New(const String& str, Heap::Space space = Heap::kNew);
+  static StringPtr New(const String& str, Heap::Space space = Heap::kNew);
 
   // Creates a new External String object using the specified array of
   // UTF-8 encoded characters as the external reference.
-  static RawString* NewExternal(const uint8_t* utf8_array,
-                                intptr_t array_len,
-                                void* peer,
-                                intptr_t external_allocation_size,
-                                Dart_WeakPersistentHandleFinalizer callback,
-                                Heap::Space = Heap::kNew);
+  static StringPtr NewExternal(const uint8_t* utf8_array,
+                               intptr_t array_len,
+                               void* peer,
+                               intptr_t external_allocation_size,
+                               Dart_WeakPersistentHandleFinalizer callback,
+                               Heap::Space = Heap::kNew);
 
   // Creates a new External String object using the specified array of
   // UTF-16 encoded characters as the external reference.
-  static RawString* NewExternal(const uint16_t* utf16_array,
-                                intptr_t array_len,
-                                void* peer,
-                                intptr_t external_allocation_size,
-                                Dart_WeakPersistentHandleFinalizer callback,
-                                Heap::Space = Heap::kNew);
+  static StringPtr NewExternal(const uint16_t* utf16_array,
+                               intptr_t array_len,
+                               void* peer,
+                               intptr_t external_allocation_size,
+                               Dart_WeakPersistentHandleFinalizer callback,
+                               Heap::Space = Heap::kNew);
 
   static void Copy(const String& dst,
                    intptr_t dst_offset,
@@ -8638,62 +8655,61 @@
                    intptr_t src_offset,
                    intptr_t len);
 
-  static RawString* EscapeSpecialCharacters(const String& str);
+  static StringPtr EscapeSpecialCharacters(const String& str);
   // Encodes 'str' for use in an Internationalized Resource Identifier (IRI),
   // a generalization of URI (percent-encoding). See RFC 3987.
   static const char* EncodeIRI(const String& str);
   // Returns null if 'str' is not a valid encoding.
-  static RawString* DecodeIRI(const String& str);
-  static RawString* Concat(const String& str1,
-                           const String& str2,
-                           Heap::Space space = Heap::kNew);
-  static RawString* ConcatAll(const Array& strings,
-                              Heap::Space space = Heap::kNew);
+  static StringPtr DecodeIRI(const String& str);
+  static StringPtr Concat(const String& str1,
+                          const String& str2,
+                          Heap::Space space = Heap::kNew);
+  static StringPtr ConcatAll(const Array& strings,
+                             Heap::Space space = Heap::kNew);
   // Concat all strings in 'strings' from 'start' to 'end' (excluding).
-  static RawString* ConcatAllRange(const Array& strings,
-                                   intptr_t start,
-                                   intptr_t end,
-                                   Heap::Space space = Heap::kNew);
+  static StringPtr ConcatAllRange(const Array& strings,
+                                  intptr_t start,
+                                  intptr_t end,
+                                  Heap::Space space = Heap::kNew);
 
-  static RawString* SubString(const String& str,
-                              intptr_t begin_index,
-                              Heap::Space space = Heap::kNew);
-  static RawString* SubString(const String& str,
-                              intptr_t begin_index,
-                              intptr_t length,
-                              Heap::Space space = Heap::kNew) {
+  static StringPtr SubString(const String& str,
+                             intptr_t begin_index,
+                             Heap::Space space = Heap::kNew);
+  static StringPtr SubString(const String& str,
+                             intptr_t begin_index,
+                             intptr_t length,
+                             Heap::Space space = Heap::kNew) {
     return SubString(Thread::Current(), str, begin_index, length, space);
   }
-  static RawString* SubString(Thread* thread,
-                              const String& str,
-                              intptr_t begin_index,
-                              intptr_t length,
-                              Heap::Space space = Heap::kNew);
+  static StringPtr SubString(Thread* thread,
+                             const String& str,
+                             intptr_t begin_index,
+                             intptr_t length,
+                             Heap::Space space = Heap::kNew);
 
-  static RawString* Transform(int32_t (*mapping)(int32_t ch),
-                              const String& str,
-                              Heap::Space space = Heap::kNew);
+  static StringPtr Transform(int32_t (*mapping)(int32_t ch),
+                             const String& str,
+                             Heap::Space space = Heap::kNew);
 
-  static RawString* ToUpperCase(const String& str,
-                                Heap::Space space = Heap::kNew);
-  static RawString* ToLowerCase(const String& str,
-                                Heap::Space space = Heap::kNew);
+  static StringPtr ToUpperCase(const String& str,
+                               Heap::Space space = Heap::kNew);
+  static StringPtr ToLowerCase(const String& str,
+                               Heap::Space space = Heap::kNew);
 
-  static RawString* RemovePrivateKey(const String& name);
+  static StringPtr RemovePrivateKey(const String& name);
 
   static const char* ScrubName(const String& name, bool is_extension = false);
-  static RawString* ScrubNameRetainPrivate(const String& name,
-                                           bool is_extension = false);
+  static StringPtr ScrubNameRetainPrivate(const String& name,
+                                          bool is_extension = false);
 
   static bool EqualsIgnoringPrivateKey(const String& str1, const String& str2);
 
-  static RawString* NewFormatted(const char* format, ...)
-      PRINTF_ATTRIBUTE(1, 2);
-  static RawString* NewFormatted(Heap::Space space, const char* format, ...)
+  static StringPtr NewFormatted(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
+  static StringPtr NewFormatted(Heap::Space space, const char* format, ...)
       PRINTF_ATTRIBUTE(2, 3);
-  static RawString* NewFormattedV(const char* format,
-                                  va_list args,
-                                  Heap::Space space = Heap::kNew);
+  static StringPtr NewFormattedV(const char* format,
+                                 va_list args,
+                                 Heap::Space space = Heap::kNew);
 
   static bool ParseDouble(const String& str,
                           intptr_t start,
@@ -8701,11 +8717,11 @@
                           double* result);
 
 #if !defined(HASH_IN_OBJECT_HEADER)
-  static uint32_t GetCachedHash(const RawString* obj) {
+  static uint32_t GetCachedHash(const StringPtr obj) {
     return Smi::Value(obj->ptr()->hash_);
   }
 
-  static void SetCachedHash(RawString* obj, uintptr_t hash) {
+  static void SetCachedHash(StringPtr obj, uintptr_t hash) {
     obj->ptr()->hash_ = Smi::New(hash);
   }
 #endif
@@ -8745,7 +8761,7 @@
   friend class TwoByteString;
   friend class ExternalOneByteString;
   friend class ExternalTwoByteString;
-  friend class RawOneByteString;
+  friend class OneByteStringLayout;
   friend class RODataSerializationCluster;  // SetHash
   friend class Pass2Visitor;                // Stack "handle"
 };
@@ -8762,28 +8778,28 @@
     NoSafepointScope no_safepoint;
     *CharAddr(str, index) = code_unit;
   }
-  static RawOneByteString* EscapeSpecialCharacters(const String& str);
+  static OneByteStringPtr EscapeSpecialCharacters(const String& str);
   // We use the same maximum elements for all strings.
   static const intptr_t kBytesPerElement = 1;
   static const intptr_t kMaxElements = String::kMaxElements;
 
   static intptr_t data_offset() {
-    return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data);
+    return OFFSET_OF_RETURNED_VALUE(OneByteStringLayout, data);
   }
 
-  static intptr_t UnroundedSize(RawOneByteString* str) {
+  static intptr_t UnroundedSize(OneByteStringPtr str) {
     return UnroundedSize(Smi::Value(str->ptr()->length_));
   }
   static intptr_t UnroundedSize(intptr_t len) {
-    return sizeof(RawOneByteString) + (len * kBytesPerElement);
+    return sizeof(OneByteStringLayout) + (len * kBytesPerElement);
   }
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawOneByteString) ==
-           OFFSET_OF_RETURNED_VALUE(RawOneByteString, data));
+    ASSERT(sizeof(OneByteStringLayout) ==
+           OFFSET_OF_RETURNED_VALUE(OneByteStringLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
-    ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString);
+    ASSERT(sizeof(OneByteStringLayout) == String::kSizeofRawString);
     ASSERT(0 <= len && len <= kMaxElements);
 #if defined(HASH_IN_OBJECT_HEADER)
     // We have to pad zero-length raw strings so that they can be externalized.
@@ -8794,57 +8810,57 @@
     return String::RoundedAllocationSize(UnroundedSize(len));
   }
 
-  static RawOneByteString* New(intptr_t len, Heap::Space space);
-  static RawOneByteString* New(const char* c_string,
-                               Heap::Space space = Heap::kNew) {
+  static OneByteStringPtr New(intptr_t len, Heap::Space space);
+  static OneByteStringPtr New(const char* c_string,
+                              Heap::Space space = Heap::kNew) {
     return New(reinterpret_cast<const uint8_t*>(c_string), strlen(c_string),
                space);
   }
-  static RawOneByteString* New(const uint8_t* characters,
-                               intptr_t len,
-                               Heap::Space space);
-  static RawOneByteString* New(const uint16_t* characters,
-                               intptr_t len,
-                               Heap::Space space);
-  static RawOneByteString* New(const int32_t* characters,
-                               intptr_t len,
-                               Heap::Space space);
-  static RawOneByteString* New(const String& str, Heap::Space space);
+  static OneByteStringPtr New(const uint8_t* characters,
+                              intptr_t len,
+                              Heap::Space space);
+  static OneByteStringPtr New(const uint16_t* characters,
+                              intptr_t len,
+                              Heap::Space space);
+  static OneByteStringPtr New(const int32_t* characters,
+                              intptr_t len,
+                              Heap::Space space);
+  static OneByteStringPtr New(const String& str, Heap::Space space);
   // 'other' must be OneByteString.
-  static RawOneByteString* New(const String& other_one_byte_string,
-                               intptr_t other_start_index,
-                               intptr_t other_len,
-                               Heap::Space space);
+  static OneByteStringPtr New(const String& other_one_byte_string,
+                              intptr_t other_start_index,
+                              intptr_t other_len,
+                              Heap::Space space);
 
-  static RawOneByteString* New(const TypedData& other_typed_data,
-                               intptr_t other_start_index,
-                               intptr_t other_len,
-                               Heap::Space space = Heap::kNew);
+  static OneByteStringPtr New(const TypedData& other_typed_data,
+                              intptr_t other_start_index,
+                              intptr_t other_len,
+                              Heap::Space space = Heap::kNew);
 
-  static RawOneByteString* New(const ExternalTypedData& other_typed_data,
-                               intptr_t other_start_index,
-                               intptr_t other_len,
-                               Heap::Space space = Heap::kNew);
+  static OneByteStringPtr New(const ExternalTypedData& other_typed_data,
+                              intptr_t other_start_index,
+                              intptr_t other_len,
+                              Heap::Space space = Heap::kNew);
 
-  static RawOneByteString* Concat(const String& str1,
-                                  const String& str2,
-                                  Heap::Space space);
-  static RawOneByteString* ConcatAll(const Array& strings,
-                                     intptr_t start,
-                                     intptr_t end,
-                                     intptr_t len,
-                                     Heap::Space space);
+  static OneByteStringPtr Concat(const String& str1,
+                                 const String& str2,
+                                 Heap::Space space);
+  static OneByteStringPtr ConcatAll(const Array& strings,
+                                    intptr_t start,
+                                    intptr_t end,
+                                    intptr_t len,
+                                    Heap::Space space);
 
-  static RawOneByteString* Transform(int32_t (*mapping)(int32_t ch),
-                                     const String& str,
-                                     Heap::Space space);
+  static OneByteStringPtr Transform(int32_t (*mapping)(int32_t ch),
+                                    const String& str,
+                                    Heap::Space space);
 
   // High performance version of substring for one-byte strings.
   // "str" must be OneByteString.
-  static RawOneByteString* SubStringUnchecked(const String& str,
-                                              intptr_t begin_index,
-                                              intptr_t length,
-                                              Heap::Space space);
+  static OneByteStringPtr SubStringUnchecked(const String& str,
+                                             intptr_t begin_index,
+                                             intptr_t length,
+                                             Heap::Space space);
 
   static void SetPeer(const String& str,
                       void* peer,
@@ -8853,17 +8869,17 @@
 
   static const ClassId kClassId = kOneByteStringCid;
 
-  static RawOneByteString* null() {
-    return reinterpret_cast<RawOneByteString*>(Object::null());
+  static OneByteStringPtr null() {
+    return static_cast<OneByteStringPtr>(Object::null());
   }
 
  private:
-  static RawOneByteString* raw(const String& str) {
-    return reinterpret_cast<RawOneByteString*>(str.raw());
+  static OneByteStringPtr raw(const String& str) {
+    return static_cast<OneByteStringPtr>(str.raw());
   }
 
-  static const RawOneByteString* raw_ptr(const String& str) {
-    return reinterpret_cast<const RawOneByteString*>(str.raw_ptr());
+  static const OneByteStringLayout* raw_ptr(const String& str) {
+    return reinterpret_cast<const OneByteStringLayout*>(str.raw_ptr());
   }
 
   static uint8_t* CharAddr(const String& str, intptr_t index) {
@@ -8877,11 +8893,11 @@
     return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[0];
   }
 
-  static RawOneByteString* ReadFrom(SnapshotReader* reader,
-                                    intptr_t object_id,
-                                    intptr_t tags,
-                                    Snapshot::Kind kind,
-                                    bool as_reference);
+  static OneByteStringPtr ReadFrom(SnapshotReader* reader,
+                                   intptr_t object_id,
+                                   intptr_t tags,
+                                   Snapshot::Kind kind,
+                                   bool as_reference);
 
   friend class Class;
   friend class String;
@@ -8905,29 +8921,29 @@
     *CharAddr(str, index) = ch;
   }
 
-  static RawTwoByteString* EscapeSpecialCharacters(const String& str);
+  static TwoByteStringPtr EscapeSpecialCharacters(const String& str);
 
   // We use the same maximum elements for all strings.
   static const intptr_t kBytesPerElement = 2;
   static const intptr_t kMaxElements = String::kMaxElements;
 
   static intptr_t data_offset() {
-    return OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data);
+    return OFFSET_OF_RETURNED_VALUE(TwoByteStringLayout, data);
   }
 
-  static intptr_t UnroundedSize(RawTwoByteString* str) {
+  static intptr_t UnroundedSize(TwoByteStringPtr str) {
     return UnroundedSize(Smi::Value(str->ptr()->length_));
   }
   static intptr_t UnroundedSize(intptr_t len) {
-    return sizeof(RawTwoByteString) + (len * kBytesPerElement);
+    return sizeof(TwoByteStringLayout) + (len * kBytesPerElement);
   }
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawTwoByteString) ==
-           OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data));
+    ASSERT(sizeof(TwoByteStringLayout) ==
+           OFFSET_OF_RETURNED_VALUE(TwoByteStringLayout, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t len) {
-    ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString);
+    ASSERT(sizeof(TwoByteStringLayout) == String::kSizeofRawString);
     ASSERT(0 <= len && len <= kMaxElements);
     // We have to pad zero-length raw strings so that they can be externalized.
     // If we don't pad, then the external string object does not fit in the
@@ -8936,57 +8952,57 @@
     return String::RoundedAllocationSize(UnroundedSize(len));
   }
 
-  static RawTwoByteString* New(intptr_t len, Heap::Space space);
-  static RawTwoByteString* New(const uint16_t* characters,
-                               intptr_t len,
-                               Heap::Space space);
-  static RawTwoByteString* New(intptr_t utf16_len,
-                               const int32_t* characters,
-                               intptr_t len,
-                               Heap::Space space);
-  static RawTwoByteString* New(const String& str, Heap::Space space);
+  static TwoByteStringPtr New(intptr_t len, Heap::Space space);
+  static TwoByteStringPtr New(const uint16_t* characters,
+                              intptr_t len,
+                              Heap::Space space);
+  static TwoByteStringPtr New(intptr_t utf16_len,
+                              const int32_t* characters,
+                              intptr_t len,
+                              Heap::Space space);
+  static TwoByteStringPtr New(const String& str, Heap::Space space);
 
-  static RawTwoByteString* New(const TypedData& other_typed_data,
-                               intptr_t other_start_index,
-                               intptr_t other_len,
-                               Heap::Space space = Heap::kNew);
+  static TwoByteStringPtr New(const TypedData& other_typed_data,
+                              intptr_t other_start_index,
+                              intptr_t other_len,
+                              Heap::Space space = Heap::kNew);
 
-  static RawTwoByteString* New(const ExternalTypedData& other_typed_data,
-                               intptr_t other_start_index,
-                               intptr_t other_len,
-                               Heap::Space space = Heap::kNew);
+  static TwoByteStringPtr New(const ExternalTypedData& other_typed_data,
+                              intptr_t other_start_index,
+                              intptr_t other_len,
+                              Heap::Space space = Heap::kNew);
 
-  static RawTwoByteString* Concat(const String& str1,
-                                  const String& str2,
-                                  Heap::Space space);
-  static RawTwoByteString* ConcatAll(const Array& strings,
-                                     intptr_t start,
-                                     intptr_t end,
-                                     intptr_t len,
-                                     Heap::Space space);
+  static TwoByteStringPtr Concat(const String& str1,
+                                 const String& str2,
+                                 Heap::Space space);
+  static TwoByteStringPtr ConcatAll(const Array& strings,
+                                    intptr_t start,
+                                    intptr_t end,
+                                    intptr_t len,
+                                    Heap::Space space);
 
-  static RawTwoByteString* Transform(int32_t (*mapping)(int32_t ch),
-                                     const String& str,
-                                     Heap::Space space);
+  static TwoByteStringPtr Transform(int32_t (*mapping)(int32_t ch),
+                                    const String& str,
+                                    Heap::Space space);
 
   static void SetPeer(const String& str,
                       void* peer,
                       intptr_t external_allocation_size,
                       Dart_WeakPersistentHandleFinalizer callback);
 
-  static RawTwoByteString* null() {
-    return reinterpret_cast<RawTwoByteString*>(Object::null());
+  static TwoByteStringPtr null() {
+    return static_cast<TwoByteStringPtr>(Object::null());
   }
 
   static const ClassId kClassId = kTwoByteStringCid;
 
  private:
-  static RawTwoByteString* raw(const String& str) {
-    return reinterpret_cast<RawTwoByteString*>(str.raw());
+  static TwoByteStringPtr raw(const String& str) {
+    return static_cast<TwoByteStringPtr>(str.raw());
   }
 
-  static const RawTwoByteString* raw_ptr(const String& str) {
-    return reinterpret_cast<const RawTwoByteString*>(str.raw_ptr());
+  static const TwoByteStringLayout* raw_ptr(const String& str) {
+    return reinterpret_cast<const TwoByteStringLayout*>(str.raw_ptr());
   }
 
   static uint16_t* CharAddr(const String& str, intptr_t index) {
@@ -9002,11 +9018,11 @@
     return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[0];
   }
 
-  static RawTwoByteString* ReadFrom(SnapshotReader* reader,
-                                    intptr_t object_id,
-                                    intptr_t tags,
-                                    Snapshot::Kind kind,
-                                    bool as_reference);
+  static TwoByteStringPtr ReadFrom(SnapshotReader* reader,
+                                   intptr_t object_id,
+                                   intptr_t tags,
+                                   Snapshot::Kind kind,
+                                   bool as_reference);
 
   friend class Class;
   friend class String;
@@ -9024,7 +9040,7 @@
   static void* GetPeer(const String& str) { return raw_ptr(str)->peer_; }
 
   static intptr_t external_data_offset() {
-    return OFFSET_OF(RawExternalOneByteString, external_data_);
+    return OFFSET_OF(ExternalOneByteStringLayout, external_data_);
   }
 
   // We use the same maximum elements for all strings.
@@ -9032,10 +9048,10 @@
   static const intptr_t kMaxElements = String::kMaxElements;
 
   static intptr_t InstanceSize() {
-    return String::RoundedAllocationSize(sizeof(RawExternalOneByteString));
+    return String::RoundedAllocationSize(sizeof(ExternalOneByteStringLayout));
   }
 
-  static RawExternalOneByteString* New(
+  static ExternalOneByteStringPtr New(
       const uint8_t* characters,
       intptr_t len,
       void* peer,
@@ -9043,23 +9059,23 @@
       Dart_WeakPersistentHandleFinalizer callback,
       Heap::Space space);
 
-  static RawExternalOneByteString* null() {
-    return reinterpret_cast<RawExternalOneByteString*>(Object::null());
+  static ExternalOneByteStringPtr null() {
+    return static_cast<ExternalOneByteStringPtr>(Object::null());
   }
 
-  static RawOneByteString* EscapeSpecialCharacters(const String& str);
-  static RawOneByteString* EncodeIRI(const String& str);
-  static RawOneByteString* DecodeIRI(const String& str);
+  static OneByteStringPtr EscapeSpecialCharacters(const String& str);
+  static OneByteStringPtr EncodeIRI(const String& str);
+  static OneByteStringPtr DecodeIRI(const String& str);
 
   static const ClassId kClassId = kExternalOneByteStringCid;
 
  private:
-  static RawExternalOneByteString* raw(const String& str) {
-    return reinterpret_cast<RawExternalOneByteString*>(str.raw());
+  static ExternalOneByteStringPtr raw(const String& str) {
+    return static_cast<ExternalOneByteStringPtr>(str.raw());
   }
 
-  static const RawExternalOneByteString* raw_ptr(const String& str) {
-    return reinterpret_cast<const RawExternalOneByteString*>(str.raw_ptr());
+  static const ExternalOneByteStringLayout* raw_ptr(const String& str) {
+    return reinterpret_cast<const ExternalOneByteStringLayout*>(str.raw_ptr());
   }
 
   static const uint8_t* CharAddr(const String& str, intptr_t index) {
@@ -9087,11 +9103,11 @@
                        Dart_WeakPersistentHandle handle,
                        void* peer);
 
-  static RawExternalOneByteString* ReadFrom(SnapshotReader* reader,
-                                            intptr_t object_id,
-                                            intptr_t tags,
-                                            Snapshot::Kind kind,
-                                            bool as_reference);
+  static ExternalOneByteStringPtr ReadFrom(SnapshotReader* reader,
+                                           intptr_t object_id,
+                                           intptr_t tags,
+                                           Snapshot::Kind kind,
+                                           bool as_reference);
 
   static intptr_t NextFieldOffset() {
     // Indicates this class cannot be extended by dart code.
@@ -9115,7 +9131,7 @@
   static void* GetPeer(const String& str) { return raw_ptr(str)->peer_; }
 
   static intptr_t external_data_offset() {
-    return OFFSET_OF(RawExternalTwoByteString, external_data_);
+    return OFFSET_OF(ExternalTwoByteStringLayout, external_data_);
   }
 
   // We use the same maximum elements for all strings.
@@ -9123,10 +9139,10 @@
   static const intptr_t kMaxElements = String::kMaxElements;
 
   static intptr_t InstanceSize() {
-    return String::RoundedAllocationSize(sizeof(RawExternalTwoByteString));
+    return String::RoundedAllocationSize(sizeof(ExternalTwoByteStringLayout));
   }
 
-  static RawExternalTwoByteString* New(
+  static ExternalTwoByteStringPtr New(
       const uint16_t* characters,
       intptr_t len,
       void* peer,
@@ -9134,19 +9150,19 @@
       Dart_WeakPersistentHandleFinalizer callback,
       Heap::Space space = Heap::kNew);
 
-  static RawExternalTwoByteString* null() {
-    return reinterpret_cast<RawExternalTwoByteString*>(Object::null());
+  static ExternalTwoByteStringPtr null() {
+    return static_cast<ExternalTwoByteStringPtr>(Object::null());
   }
 
   static const ClassId kClassId = kExternalTwoByteStringCid;
 
  private:
-  static RawExternalTwoByteString* raw(const String& str) {
-    return reinterpret_cast<RawExternalTwoByteString*>(str.raw());
+  static ExternalTwoByteStringPtr raw(const String& str) {
+    return static_cast<ExternalTwoByteStringPtr>(str.raw());
   }
 
-  static const RawExternalTwoByteString* raw_ptr(const String& str) {
-    return reinterpret_cast<const RawExternalTwoByteString*>(str.raw_ptr());
+  static const ExternalTwoByteStringLayout* raw_ptr(const String& str) {
+    return reinterpret_cast<const ExternalTwoByteStringLayout*>(str.raw_ptr());
   }
 
   static const uint16_t* CharAddr(const String& str, intptr_t index) {
@@ -9174,11 +9190,11 @@
                        Dart_WeakPersistentHandle handle,
                        void* peer);
 
-  static RawExternalTwoByteString* ReadFrom(SnapshotReader* reader,
-                                            intptr_t object_id,
-                                            intptr_t tags,
-                                            Snapshot::Kind kind,
-                                            bool as_reference);
+  static ExternalTwoByteStringPtr ReadFrom(SnapshotReader* reader,
+                                           intptr_t object_id,
+                                           intptr_t tags,
+                                           Snapshot::Kind kind,
+                                           bool as_reference);
 
   static intptr_t NextFieldOffset() {
     // Indicates this class cannot be extended by dart code.
@@ -9197,7 +9213,7 @@
   bool value() const { return raw_ptr()->value_; }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawBool));
+    return RoundedAllocationSize(sizeof(BoolLayout));
   }
 
   static const Bool& True() { return Object::bool_true(); }
@@ -9218,7 +9234,7 @@
   }
 
   // New should only be called to initialize the two legal bool values.
-  static RawBool* New(bool value);
+  static BoolPtr New(bool value);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Bool, Instance);
   friend class Class;
@@ -9238,25 +9254,25 @@
   }
 
   intptr_t Length() const { return LengthOf(raw()); }
-  static intptr_t LengthOf(const RawArray* array) {
+  static intptr_t LengthOf(const ArrayPtr array) {
     return Smi::Value(array->ptr()->length_);
   }
 
-  static intptr_t length_offset() { return OFFSET_OF(RawArray, length_); }
+  static intptr_t length_offset() { return OFFSET_OF(ArrayLayout, length_); }
   static intptr_t data_offset() {
-    return OFFSET_OF_RETURNED_VALUE(RawArray, data);
+    return OFFSET_OF_RETURNED_VALUE(ArrayLayout, data);
   }
   static intptr_t element_offset(intptr_t index) {
-    return OFFSET_OF_RETURNED_VALUE(RawArray, data) + kWordSize * index;
+    return OFFSET_OF_RETURNED_VALUE(ArrayLayout, data) + kWordSize * index;
   }
 
-  struct ArrayLayout {
+  struct ArrayTraits {
     static intptr_t elements_start_offset() { return Array::data_offset(); }
 
     static constexpr intptr_t kElementSize = kWordSize;
   };
 
-  static bool Equals(RawArray* a, RawArray* b) {
+  static bool Equals(ArrayPtr a, ArrayPtr b) {
     if (a == b) return true;
     if (a->IsRawNull() || b->IsRawNull()) return false;
     if (a->ptr()->length_ != b->ptr()->length_) return false;
@@ -9265,28 +9281,27 @@
     return memcmp(a->ptr()->data(), b->ptr()->data(), kWordSize * length) == 0;
   }
 
-  static RawObject** DataOf(RawArray* array) { return array->ptr()->data(); }
+  static ObjectPtr* DataOf(ArrayPtr array) { return array->ptr()->data(); }
 
-  RawObject* At(intptr_t index) const { return *ObjectAddr(index); }
+  ObjectPtr At(intptr_t index) const { return *ObjectAddr(index); }
   void SetAt(intptr_t index, const Object& value) const {
     // TODO(iposva): Add storing NoSafepointScope.
     StoreArrayPointer(ObjectAddr(index), value.raw());
   }
 
   // Access to the array with acquire release semantics.
-  RawObject* AtAcquire(intptr_t index) const {
-    return LoadPointer<RawObject*, std::memory_order_acquire>(
-        ObjectAddr(index));
+  ObjectPtr AtAcquire(intptr_t index) const {
+    return LoadPointer<ObjectPtr, std::memory_order_acquire>(ObjectAddr(index));
   }
   void SetAtRelease(intptr_t index, const Object& value) const {
     // TODO(iposva): Add storing NoSafepointScope.
-    StoreArrayPointer<RawObject*, std::memory_order_release>(ObjectAddr(index),
-                                                             value.raw());
+    StoreArrayPointer<ObjectPtr, std::memory_order_release>(ObjectAddr(index),
+                                                            value.raw());
   }
 
   bool IsImmutable() const { return raw()->GetClassId() == kImmutableArrayCid; }
 
-  virtual RawTypeArguments* GetTypeArguments() const {
+  virtual TypeArgumentsPtr GetTypeArguments() const {
     return raw_ptr()->type_arguments_;
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
@@ -9307,10 +9322,10 @@
   static const intptr_t kBytesPerElement = kWordSize;
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
   static const intptr_t kMaxNewSpaceElements =
-      (Heap::kNewAllocatableSize - sizeof(RawArray)) / kBytesPerElement;
+      (Heap::kNewAllocatableSize - sizeof(ArrayLayout)) / kBytesPerElement;
 
   static intptr_t type_arguments_offset() {
-    return OFFSET_OF(RawArray, type_arguments_);
+    return OFFSET_OF(ArrayLayout, type_arguments_);
   }
 
   static bool IsValidLength(intptr_t len) {
@@ -9318,15 +9333,16 @@
   }
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawArray) == OFFSET_OF_RETURNED_VALUE(RawArray, data));
+    ASSERT(sizeof(ArrayLayout) == OFFSET_OF_RETURNED_VALUE(ArrayLayout, data));
     return 0;
   }
 
   static intptr_t InstanceSize(intptr_t len) {
     // Ensure that variable length data is not adding to the object length.
-    ASSERT(sizeof(RawArray) == (sizeof(RawInstance) + (2 * kWordSize)));
+    ASSERT(sizeof(ArrayLayout) == (sizeof(InstanceLayout) + (2 * kWordSize)));
     ASSERT(IsValidLength(len));
-    return RoundedAllocationSize(sizeof(RawArray) + (len * kBytesPerElement));
+    return RoundedAllocationSize(sizeof(ArrayLayout) +
+                                 (len * kBytesPerElement));
   }
 
   // Returns true if all elements are OK for canonicalization.
@@ -9337,17 +9353,17 @@
   // to ImmutableArray.
   void MakeImmutable() const;
 
-  static RawArray* New(intptr_t len, Heap::Space space = Heap::kNew);
-  static RawArray* New(intptr_t len,
-                       const AbstractType& element_type,
-                       Heap::Space space = Heap::kNew);
+  static ArrayPtr New(intptr_t len, Heap::Space space = Heap::kNew);
+  static ArrayPtr New(intptr_t len,
+                      const AbstractType& element_type,
+                      Heap::Space space = Heap::kNew);
 
   // Creates and returns a new array with 'new_length'. Copies all elements from
   // 'source' to the new array. 'new_length' must be greater than or equal to
   // 'source.Length()'. 'source' can be null.
-  static RawArray* Grow(const Array& source,
-                        intptr_t new_length,
-                        Heap::Space space = Heap::kNew);
+  static ArrayPtr Grow(const Array& source,
+                       intptr_t new_length,
+                       Heap::Space space = Heap::kNew);
 
   // Truncates the array to a given length. 'new_length' must be less than
   // or equal to 'source.Length()'. The remaining unused part of the array is
@@ -9363,20 +9379,18 @@
   // set to an empty array.
   // If the unique parameter is false, the function is allowed to return
   // a shared Array instance.
-  static RawArray* MakeFixedLength(const GrowableObjectArray& growable_array,
-                                   bool unique = false);
+  static ArrayPtr MakeFixedLength(const GrowableObjectArray& growable_array,
+                                  bool unique = false);
 
-  RawArray* Slice(intptr_t start,
-                  intptr_t count,
-                  bool with_type_argument) const;
+  ArrayPtr Slice(intptr_t start, intptr_t count, bool with_type_argument) const;
 
  protected:
-  static RawArray* New(intptr_t class_id,
-                       intptr_t len,
-                       Heap::Space space = Heap::kNew);
+  static ArrayPtr New(intptr_t class_id,
+                      intptr_t len,
+                      Heap::Space space = Heap::kNew);
 
  private:
-  RawObject* const* ObjectAddr(intptr_t index) const {
+  ObjectPtr const* ObjectAddr(intptr_t index) const {
     // TODO(iposva): Determine if we should throw an exception here.
     ASSERT((index >= 0) && (index < Length()));
     return &raw_ptr()->data()[index];
@@ -9391,17 +9405,17 @@
 
   template <typename type, std::memory_order order = std::memory_order_relaxed>
   void StoreArrayPointer(type const* addr, type value) const {
-    raw()->StoreArrayPointer<type, order>(addr, value);
+    raw()->ptr()->StoreArrayPointer<type, order>(addr, value);
   }
 
   // Store a range of pointers [from, from + count) into [to, to + count).
   // TODO(koda): Use this to fix Object::Clone's broken store buffer logic.
-  void StoreArrayPointers(RawObject* const* to,
-                          RawObject* const* from,
+  void StoreArrayPointers(ObjectPtr const* to,
+                          ObjectPtr const* from,
                           intptr_t count) {
     ASSERT(Contains(reinterpret_cast<uword>(to)));
     if (raw()->IsNewObject()) {
-      memmove(const_cast<RawObject**>(to), from, count * kWordSize);
+      memmove(const_cast<ObjectPtr*>(to), from, count * kWordSize);
     } else {
       for (intptr_t i = 0; i < count; ++i) {
         StoreArrayPointer(&to[i], from[i]);
@@ -9419,13 +9433,13 @@
 
 class ImmutableArray : public AllStatic {
  public:
-  static RawImmutableArray* New(intptr_t len, Heap::Space space = Heap::kNew);
+  static ImmutableArrayPtr New(intptr_t len, Heap::Space space = Heap::kNew);
 
-  static RawImmutableArray* ReadFrom(SnapshotReader* reader,
-                                     intptr_t object_id,
-                                     intptr_t tags,
-                                     Snapshot::Kind kind,
-                                     bool as_reference);
+  static ImmutableArrayPtr ReadFrom(SnapshotReader* reader,
+                                    intptr_t object_id,
+                                    intptr_t tags,
+                                    Snapshot::Kind kind,
+                                    bool as_reference);
 
   static const ClassId kClassId = kImmutableArrayCid;
 
@@ -9441,8 +9455,8 @@
     return -kWordSize;
   }
 
-  static RawImmutableArray* raw(const Array& array) {
-    return reinterpret_cast<RawImmutableArray*>(array.raw());
+  static ImmutableArrayPtr raw(const Array& array) {
+    return static_cast<ImmutableArrayPtr>(array.raw());
   }
 
   friend class Class;
@@ -9465,12 +9479,12 @@
     StoreSmi(&raw_ptr()->length_, Smi::New(value));
   }
 
-  RawArray* data() const { return raw_ptr()->data_; }
+  ArrayPtr data() const { return raw_ptr()->data_; }
   void SetData(const Array& value) const {
     StorePointer(&raw_ptr()->data_, value.raw());
   }
 
-  RawObject* At(intptr_t index) const {
+  ObjectPtr At(intptr_t index) const {
     NoSafepointScope no_safepoint;
     ASSERT(!IsNull());
     ASSERT(index < Length());
@@ -9481,15 +9495,15 @@
     ASSERT(index < Length());
 
     // TODO(iposva): Add storing NoSafepointScope.
-    data()->StoreArrayPointer(ObjectAddr(index), value.raw());
+    data()->ptr()->StoreArrayPointer(ObjectAddr(index), value.raw());
   }
 
   void Add(const Object& value, Heap::Space space = Heap::kNew) const;
 
   void Grow(intptr_t new_capacity, Heap::Space space = Heap::kNew) const;
-  RawObject* RemoveLast() const;
+  ObjectPtr RemoveLast() const;
 
-  virtual RawTypeArguments* GetTypeArguments() const {
+  virtual TypeArgumentsPtr GetTypeArguments() const {
     return raw_ptr()->type_arguments_;
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
@@ -9508,46 +9522,46 @@
   }
 
   // We don't expect a growable object array to be canonicalized.
-  virtual RawInstance* CheckAndCanonicalize(Thread* thread,
-                                            const char** error_str) const {
+  virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+                                           const char** error_str) const {
     UNREACHABLE();
     return Instance::null();
   }
 
   static intptr_t type_arguments_offset() {
-    return OFFSET_OF(RawGrowableObjectArray, type_arguments_);
+    return OFFSET_OF(GrowableObjectArrayLayout, type_arguments_);
   }
 
   static intptr_t length_offset() {
-    return OFFSET_OF(RawGrowableObjectArray, length_);
+    return OFFSET_OF(GrowableObjectArrayLayout, length_);
   }
   static intptr_t data_offset() {
-    return OFFSET_OF(RawGrowableObjectArray, data_);
+    return OFFSET_OF(GrowableObjectArrayLayout, data_);
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawGrowableObjectArray));
+    return RoundedAllocationSize(sizeof(GrowableObjectArrayLayout));
   }
 
-  static RawGrowableObjectArray* New(Heap::Space space = Heap::kNew) {
+  static GrowableObjectArrayPtr New(Heap::Space space = Heap::kNew) {
     return New(kDefaultInitialCapacity, space);
   }
-  static RawGrowableObjectArray* New(intptr_t capacity,
-                                     Heap::Space space = Heap::kNew);
-  static RawGrowableObjectArray* New(const Array& array,
-                                     Heap::Space space = Heap::kNew);
+  static GrowableObjectArrayPtr New(intptr_t capacity,
+                                    Heap::Space space = Heap::kNew);
+  static GrowableObjectArrayPtr New(const Array& array,
+                                    Heap::Space space = Heap::kNew);
 
-  static RawSmi* NoSafepointLength(const RawGrowableObjectArray* array) {
+  static SmiPtr NoSafepointLength(const GrowableObjectArrayPtr array) {
     return array->ptr()->length_;
   }
 
-  static RawArray* NoSafepointData(const RawGrowableObjectArray* array) {
+  static ArrayPtr NoSafepointData(const GrowableObjectArrayPtr array) {
     return array->ptr()->data_;
   }
 
  private:
-  RawArray* DataArray() const { return data()->ptr(); }
-  RawObject** ObjectAddr(intptr_t index) const {
+  ArrayLayout* DataArray() const { return data()->ptr(); }
+  ObjectPtr* ObjectAddr(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
     return &(DataArray()->data()[index]);
   }
@@ -9561,13 +9575,13 @@
 
 class Float32x4 : public Instance {
  public:
-  static RawFloat32x4* New(float value0,
-                           float value1,
-                           float value2,
-                           float value3,
-                           Heap::Space space = Heap::kNew);
-  static RawFloat32x4* New(simd128_value_t value,
-                           Heap::Space space = Heap::kNew);
+  static Float32x4Ptr New(float value0,
+                          float value1,
+                          float value2,
+                          float value3,
+                          Heap::Space space = Heap::kNew);
+  static Float32x4Ptr New(simd128_value_t value,
+                          Heap::Space space = Heap::kNew);
 
   float x() const;
   float y() const;
@@ -9583,10 +9597,10 @@
   void set_value(simd128_value_t value) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawFloat32x4));
+    return RoundedAllocationSize(sizeof(Float32x4Layout));
   }
 
-  static intptr_t value_offset() { return OFFSET_OF(RawFloat32x4, value_); }
+  static intptr_t value_offset() { return OFFSET_OF(Float32x4Layout, value_); }
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Float32x4, Instance);
@@ -9595,12 +9609,12 @@
 
 class Int32x4 : public Instance {
  public:
-  static RawInt32x4* New(int32_t value0,
-                         int32_t value1,
-                         int32_t value2,
-                         int32_t value3,
-                         Heap::Space space = Heap::kNew);
-  static RawInt32x4* New(simd128_value_t value, Heap::Space space = Heap::kNew);
+  static Int32x4Ptr New(int32_t value0,
+                        int32_t value1,
+                        int32_t value2,
+                        int32_t value3,
+                        Heap::Space space = Heap::kNew);
+  static Int32x4Ptr New(simd128_value_t value, Heap::Space space = Heap::kNew);
 
   int32_t x() const;
   int32_t y() const;
@@ -9616,10 +9630,10 @@
   void set_value(simd128_value_t value) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawInt32x4));
+    return RoundedAllocationSize(sizeof(Int32x4Layout));
   }
 
-  static intptr_t value_offset() { return OFFSET_OF(RawInt32x4, value_); }
+  static intptr_t value_offset() { return OFFSET_OF(Int32x4Layout, value_); }
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Int32x4, Instance);
@@ -9628,11 +9642,11 @@
 
 class Float64x2 : public Instance {
  public:
-  static RawFloat64x2* New(double value0,
-                           double value1,
-                           Heap::Space space = Heap::kNew);
-  static RawFloat64x2* New(simd128_value_t value,
-                           Heap::Space space = Heap::kNew);
+  static Float64x2Ptr New(double value0,
+                          double value1,
+                          Heap::Space space = Heap::kNew);
+  static Float64x2Ptr New(simd128_value_t value,
+                          Heap::Space space = Heap::kNew);
 
   double x() const;
   double y() const;
@@ -9644,10 +9658,10 @@
   void set_value(simd128_value_t value) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawFloat64x2));
+    return RoundedAllocationSize(sizeof(Float64x2Layout));
   }
 
-  static intptr_t value_offset() { return OFFSET_OF(RawFloat64x2, value_); }
+  static intptr_t value_offset() { return OFFSET_OF(Float64x2Layout, value_); }
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Float64x2, Instance);
@@ -9657,17 +9671,17 @@
 class PointerBase : public Instance {
  public:
   static intptr_t data_field_offset() {
-    return OFFSET_OF(RawPointerBase, data_);
+    return OFFSET_OF(PointerBaseLayout, data_);
   }
 };
 
 class TypedDataBase : public PointerBase {
  public:
   static intptr_t length_offset() {
-    return OFFSET_OF(RawTypedDataBase, length_);
+    return OFFSET_OF(TypedDataBaseLayout, length_);
   }
 
-  RawSmi* length() const { return raw_ptr()->length_; }
+  SmiPtr length() const { return raw_ptr()->length_; }
 
   intptr_t Length() const {
     ASSERT(!IsNull());
@@ -9693,16 +9707,16 @@
   static TypedDataElementType ElementType(classid_t cid) {
     if (cid == kByteDataViewCid) {
       return kUint8ArrayElement;
-    } else if (RawObject::IsTypedDataClassId(cid)) {
+    } else if (IsTypedDataClassId(cid)) {
       const intptr_t index =
           (cid - kTypedDataInt8ArrayCid - kTypedDataCidRemainderInternal) / 3;
       return static_cast<TypedDataElementType>(index);
-    } else if (RawObject::IsTypedDataViewClassId(cid)) {
+    } else if (IsTypedDataViewClassId(cid)) {
       const intptr_t index =
           (cid - kTypedDataInt8ArrayCid - kTypedDataCidRemainderView) / 3;
       return static_cast<TypedDataElementType>(index);
     } else {
-      ASSERT(RawObject::IsExternalTypedDataClassId(cid));
+      ASSERT(IsExternalTypedDataClassId(cid));
       const intptr_t index =
           (cid - kTypedDataInt8ArrayCid - kTypedDataCidRemainderExternal) / 3;
       return static_cast<TypedDataElementType>(index);
@@ -9779,33 +9793,33 @@
 
 #undef TYPED_GETTER_SETTER
 
-  static intptr_t data_offset() { return RawTypedData::payload_offset(); }
+  static intptr_t data_offset() { return TypedDataLayout::payload_offset(); }
 
   static intptr_t InstanceSize() {
-    ASSERT(sizeof(RawTypedData) ==
-           OFFSET_OF_RETURNED_VALUE(RawTypedData, internal_data));
+    ASSERT(sizeof(TypedDataLayout) ==
+           OFFSET_OF_RETURNED_VALUE(TypedDataLayout, internal_data));
     return 0;
   }
 
   static intptr_t InstanceSize(intptr_t lengthInBytes) {
     ASSERT(0 <= lengthInBytes && lengthInBytes <= kSmiMax);
-    return RoundedAllocationSize(sizeof(RawTypedData) + lengthInBytes);
+    return RoundedAllocationSize(sizeof(TypedDataLayout) + lengthInBytes);
   }
 
   static intptr_t MaxElements(intptr_t class_id) {
-    ASSERT(RawObject::IsTypedDataClassId(class_id));
+    ASSERT(IsTypedDataClassId(class_id));
     return (kSmiMax / ElementSizeInBytes(class_id));
   }
 
   static intptr_t MaxNewSpaceElements(intptr_t class_id) {
-    ASSERT(RawObject::IsTypedDataClassId(class_id));
-    return (Heap::kNewAllocatableSize - sizeof(RawTypedData)) /
+    ASSERT(IsTypedDataClassId(class_id));
+    return (Heap::kNewAllocatableSize - sizeof(TypedDataLayout)) /
            ElementSizeInBytes(class_id);
   }
 
-  static RawTypedData* New(intptr_t class_id,
-                           intptr_t len,
-                           Heap::Space space = Heap::kNew);
+  static TypedDataPtr New(intptr_t class_id,
+                          intptr_t len,
+                          Heap::Space space = Heap::kNew);
 
   template <typename DstType, typename SrcType>
   static void Copy(const DstType& dst,
@@ -9857,11 +9871,11 @@
   static bool IsTypedData(const Instance& obj) {
     ASSERT(!obj.IsNull());
     intptr_t cid = obj.raw()->GetClassId();
-    return RawObject::IsTypedDataClassId(cid);
+    return IsTypedDataClassId(cid);
   }
 
  protected:
-  void RecomputeDataField() { raw()->RecomputeDataField(); }
+  void RecomputeDataField() { raw()->ptr()->RecomputeDataField(); }
 
  private:
   // Provides const access to non-pointer, non-aligned data within the object.
@@ -9918,31 +9932,31 @@
       intptr_t external_size) const;
 
   static intptr_t data_offset() {
-    return OFFSET_OF(RawExternalTypedData, data_);
+    return OFFSET_OF(ExternalTypedDataLayout, data_);
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawExternalTypedData));
+    return RoundedAllocationSize(sizeof(ExternalTypedDataLayout));
   }
 
   static intptr_t MaxElements(intptr_t class_id) {
-    ASSERT(RawObject::IsExternalTypedDataClassId(class_id));
+    ASSERT(IsExternalTypedDataClassId(class_id));
     return (kSmiMax / ElementSizeInBytes(class_id));
   }
 
-  static RawExternalTypedData* New(
+  static ExternalTypedDataPtr New(
       intptr_t class_id,
       uint8_t* data,
       intptr_t len,
       Heap::Space space = Heap::kNew,
       bool perform_eager_msan_initialization_check = true);
 
-  static RawExternalTypedData* NewFinalizeWithFree(uint8_t* data, intptr_t len);
+  static ExternalTypedDataPtr NewFinalizeWithFree(uint8_t* data, intptr_t len);
 
   static bool IsExternalTypedData(const Instance& obj) {
     ASSERT(!obj.IsNull());
     intptr_t cid = obj.raw()->GetClassId();
-    return RawObject::IsExternalTypedDataClassId(cid);
+    return IsExternalTypedDataClassId(cid);
   }
 
  protected:
@@ -9966,50 +9980,48 @@
 
 class TypedDataView : public TypedDataBase {
  public:
-  static RawTypedDataView* New(intptr_t class_id,
-                               Heap::Space space = Heap::kNew);
-  static RawTypedDataView* New(intptr_t class_id,
-                               const TypedDataBase& typed_data,
-                               intptr_t offset_in_bytes,
-                               intptr_t length,
-                               Heap::Space space = Heap::kNew);
+  static TypedDataViewPtr New(intptr_t class_id,
+                              Heap::Space space = Heap::kNew);
+  static TypedDataViewPtr New(intptr_t class_id,
+                              const TypedDataBase& typed_data,
+                              intptr_t offset_in_bytes,
+                              intptr_t length,
+                              Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawTypedDataView));
+    return RoundedAllocationSize(sizeof(TypedDataViewLayout));
   }
 
-  static RawInstance* Data(const TypedDataView& view) {
+  static InstancePtr Data(const TypedDataView& view) {
     return view.typed_data();
   }
 
-  static RawSmi* OffsetInBytes(const TypedDataView& view) {
+  static SmiPtr OffsetInBytes(const TypedDataView& view) {
     return view.offset_in_bytes();
   }
 
   static bool IsExternalTypedDataView(const TypedDataView& view_obj) {
     const auto& data = Instance::Handle(Data(view_obj));
     intptr_t cid = data.raw()->GetClassId();
-    ASSERT(RawObject::IsTypedDataClassId(cid) ||
-           RawObject::IsExternalTypedDataClassId(cid));
-    return RawObject::IsExternalTypedDataClassId(cid);
+    ASSERT(IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid));
+    return IsExternalTypedDataClassId(cid);
   }
 
   static intptr_t data_offset() {
-    return OFFSET_OF(RawTypedDataView, typed_data_);
+    return OFFSET_OF(TypedDataViewLayout, typed_data_);
   }
 
   static intptr_t offset_in_bytes_offset() {
-    return OFFSET_OF(RawTypedDataView, offset_in_bytes_);
+    return OFFSET_OF(TypedDataViewLayout, offset_in_bytes_);
   }
 
-  RawInstance* typed_data() const { return raw_ptr()->typed_data_; }
+  InstancePtr typed_data() const { return raw_ptr()->typed_data_; }
 
   void InitializeWith(const TypedDataBase& typed_data,
                       intptr_t offset_in_bytes,
                       intptr_t length) {
     const classid_t cid = typed_data.GetClassId();
-    ASSERT(RawObject::IsTypedDataClassId(cid) ||
-           RawObject::IsExternalTypedDataClassId(cid));
+    ASSERT(IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid));
     StorePointer(&raw_ptr()->typed_data_, typed_data.raw());
     StoreSmi(&raw_ptr()->length_, Smi::New(length));
     StoreSmi(&raw_ptr()->offset_in_bytes_, Smi::New(offset_in_bytes));
@@ -10018,13 +10030,13 @@
     RecomputeDataField();
   }
 
-  RawSmi* offset_in_bytes() const { return raw_ptr()->offset_in_bytes_; }
+  SmiPtr offset_in_bytes() const { return raw_ptr()->offset_in_bytes_; }
 
  protected:
   virtual uint8_t* Validate(uint8_t* data) const { return data; }
 
  private:
-  void RecomputeDataField() { raw()->RecomputeDataField(); }
+  void RecomputeDataField() { raw()->ptr()->RecomputeDataField(); }
 
   void Clear() {
     StoreSmi(&raw_ptr()->length_, Smi::New(0));
@@ -10042,10 +10054,10 @@
 
 class ByteBuffer : public AllStatic {
  public:
-  static RawInstance* Data(const Instance& view_obj) {
+  static InstancePtr Data(const Instance& view_obj) {
     ASSERT(!view_obj.IsNull());
-    return *reinterpret_cast<RawInstance* const*>(view_obj.raw_ptr() +
-                                                  kDataOffset);
+    return *reinterpret_cast<InstancePtr const*>(view_obj.raw_ptr() +
+                                                 kDataOffset);
   }
 
   static intptr_t NumberOfFields() { return kDataOffset; }
@@ -10060,12 +10072,12 @@
 
 class Pointer : public Instance {
  public:
-  static RawPointer* New(const AbstractType& type_arg,
-                         uword native_address,
-                         Heap::Space space = Heap::kNew);
+  static PointerPtr New(const AbstractType& type_arg,
+                        uword native_address,
+                        Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawPointer));
+    return RoundedAllocationSize(sizeof(PointerLayout));
   }
 
   static bool IsPointer(const Instance& obj);
@@ -10080,15 +10092,15 @@
   }
 
   static intptr_t type_arguments_offset() {
-    return OFFSET_OF(RawPointer, type_arguments_);
+    return OFFSET_OF(PointerLayout, type_arguments_);
   }
 
-  static intptr_t NextFieldOffset() { return sizeof(RawPointer); }
+  static intptr_t NextFieldOffset() { return sizeof(PointerLayout); }
 
   static const intptr_t kNativeTypeArgPos = 0;
 
   // Fetches the NativeType type argument.
-  RawAbstractType* type_argument() const {
+  AbstractTypePtr type_argument() const {
     TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments());
     return type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos);
   }
@@ -10101,16 +10113,16 @@
 
 class DynamicLibrary : public Instance {
  public:
-  static RawDynamicLibrary* New(void* handle, Heap::Space space = Heap::kNew);
+  static DynamicLibraryPtr New(void* handle, Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawDynamicLibrary));
+    return RoundedAllocationSize(sizeof(DynamicLibraryLayout));
   }
 
   static bool IsDynamicLibrary(const Instance& obj) {
     ASSERT(!obj.IsNull());
     intptr_t cid = obj.raw()->GetClassId();
-    return RawObject::IsFfiDynamicLibraryClassId(cid);
+    return IsFfiDynamicLibraryClassId(cid);
   }
 
   void* GetHandle() const {
@@ -10135,19 +10147,19 @@
 class LinkedHashMap : public Instance {
  public:
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawLinkedHashMap));
+    return RoundedAllocationSize(sizeof(LinkedHashMapLayout));
   }
 
   // Allocates a map with some default capacity, just like "new Map()".
-  static RawLinkedHashMap* NewDefault(Heap::Space space = Heap::kNew);
-  static RawLinkedHashMap* New(const Array& data,
-                               const TypedData& index,
-                               intptr_t hash_mask,
-                               intptr_t used_data,
-                               intptr_t deleted_keys,
-                               Heap::Space space = Heap::kNew);
+  static LinkedHashMapPtr NewDefault(Heap::Space space = Heap::kNew);
+  static LinkedHashMapPtr New(const Array& data,
+                              const TypedData& index,
+                              intptr_t hash_mask,
+                              intptr_t used_data,
+                              intptr_t deleted_keys,
+                              Heap::Space space = Heap::kNew);
 
-  virtual RawTypeArguments* GetTypeArguments() const {
+  virtual TypeArgumentsPtr GetTypeArguments() const {
     return raw_ptr()->type_arguments_;
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
@@ -10159,44 +10171,48 @@
     StorePointer(&raw_ptr()->type_arguments_, value.raw());
   }
   static intptr_t type_arguments_offset() {
-    return OFFSET_OF(RawLinkedHashMap, type_arguments_);
+    return OFFSET_OF(LinkedHashMapLayout, type_arguments_);
   }
 
-  RawTypedData* index() const { return raw_ptr()->index_; }
+  TypedDataPtr index() const { return raw_ptr()->index_; }
   void SetIndex(const TypedData& value) const {
     ASSERT(!value.IsNull());
     StorePointer(&raw_ptr()->index_, value.raw());
   }
-  static intptr_t index_offset() { return OFFSET_OF(RawLinkedHashMap, index_); }
+  static intptr_t index_offset() {
+    return OFFSET_OF(LinkedHashMapLayout, index_);
+  }
 
-  RawArray* data() const { return raw_ptr()->data_; }
+  ArrayPtr data() const { return raw_ptr()->data_; }
   void SetData(const Array& value) const {
     StorePointer(&raw_ptr()->data_, value.raw());
   }
-  static intptr_t data_offset() { return OFFSET_OF(RawLinkedHashMap, data_); }
+  static intptr_t data_offset() {
+    return OFFSET_OF(LinkedHashMapLayout, data_);
+  }
 
-  RawSmi* hash_mask() const { return raw_ptr()->hash_mask_; }
+  SmiPtr hash_mask() const { return raw_ptr()->hash_mask_; }
   void SetHashMask(intptr_t value) const {
     StoreSmi(&raw_ptr()->hash_mask_, Smi::New(value));
   }
   static intptr_t hash_mask_offset() {
-    return OFFSET_OF(RawLinkedHashMap, hash_mask_);
+    return OFFSET_OF(LinkedHashMapLayout, hash_mask_);
   }
 
-  RawSmi* used_data() const { return raw_ptr()->used_data_; }
+  SmiPtr used_data() const { return raw_ptr()->used_data_; }
   void SetUsedData(intptr_t value) const {
     StoreSmi(&raw_ptr()->used_data_, Smi::New(value));
   }
   static intptr_t used_data_offset() {
-    return OFFSET_OF(RawLinkedHashMap, used_data_);
+    return OFFSET_OF(LinkedHashMapLayout, used_data_);
   }
 
-  RawSmi* deleted_keys() const { return raw_ptr()->deleted_keys_; }
+  SmiPtr deleted_keys() const { return raw_ptr()->deleted_keys_; }
   void SetDeletedKeys(intptr_t value) const {
     StoreSmi(&raw_ptr()->deleted_keys_, Smi::New(value));
   }
   static intptr_t deleted_keys_offset() {
-    return OFFSET_OF(RawLinkedHashMap, deleted_keys_);
+    return OFFSET_OF(LinkedHashMapLayout, deleted_keys_);
   }
 
   intptr_t Length() const {
@@ -10236,9 +10252,9 @@
       }
     }
 
-    RawObject* CurrentKey() const { return data_.At(offset_); }
+    ObjectPtr CurrentKey() const { return data_.At(offset_); }
 
-    RawObject* CurrentValue() const { return data_.At(offset_ + 1); }
+    ObjectPtr CurrentValue() const { return data_.At(offset_ + 1); }
 
    private:
     const Array& data_;
@@ -10256,7 +10272,7 @@
 
   // Allocate a map, but leave all fields set to null.
   // Used during deserialization (since map might contain itself as key/value).
-  static RawLinkedHashMap* NewUninitialized(Heap::Space space = Heap::kNew);
+  static LinkedHashMapPtr NewUninitialized(Heap::Space space = Heap::kNew);
 
   friend class Class;
   friend class LinkedHashMapDeserializationCluster;
@@ -10264,38 +10280,42 @@
 
 class Closure : public Instance {
  public:
-  RawTypeArguments* instantiator_type_arguments() const {
+  TypeArgumentsPtr instantiator_type_arguments() const {
     return raw_ptr()->instantiator_type_arguments_;
   }
   static intptr_t instantiator_type_arguments_offset() {
-    return OFFSET_OF(RawClosure, instantiator_type_arguments_);
+    return OFFSET_OF(ClosureLayout, instantiator_type_arguments_);
   }
 
-  RawTypeArguments* function_type_arguments() const {
+  TypeArgumentsPtr function_type_arguments() const {
     return raw_ptr()->function_type_arguments_;
   }
   static intptr_t function_type_arguments_offset() {
-    return OFFSET_OF(RawClosure, function_type_arguments_);
+    return OFFSET_OF(ClosureLayout, function_type_arguments_);
   }
 
-  RawTypeArguments* delayed_type_arguments() const {
+  TypeArgumentsPtr delayed_type_arguments() const {
     return raw_ptr()->delayed_type_arguments_;
   }
   static intptr_t delayed_type_arguments_offset() {
-    return OFFSET_OF(RawClosure, delayed_type_arguments_);
+    return OFFSET_OF(ClosureLayout, delayed_type_arguments_);
   }
 
-  RawFunction* function() const { return raw_ptr()->function_; }
-  static intptr_t function_offset() { return OFFSET_OF(RawClosure, function_); }
+  FunctionPtr function() const { return raw_ptr()->function_; }
+  static intptr_t function_offset() {
+    return OFFSET_OF(ClosureLayout, function_);
+  }
 
-  RawContext* context() const { return raw_ptr()->context_; }
-  static intptr_t context_offset() { return OFFSET_OF(RawClosure, context_); }
+  ContextPtr context() const { return raw_ptr()->context_; }
+  static intptr_t context_offset() {
+    return OFFSET_OF(ClosureLayout, context_);
+  }
 
-  RawSmi* hash() const { return raw_ptr()->hash_; }
-  static intptr_t hash_offset() { return OFFSET_OF(RawClosure, hash_); }
+  SmiPtr hash() const { return raw_ptr()->hash_; }
+  static intptr_t hash_offset() { return OFFSET_OF(ClosureLayout, hash_); }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawClosure));
+    return RoundedAllocationSize(sizeof(ClosureLayout));
   }
 
   // Returns true if all elements are OK for canonicalization.
@@ -10309,23 +10329,23 @@
   }
   int64_t ComputeHash() const;
 
-  static RawClosure* New(const TypeArguments& instantiator_type_arguments,
-                         const TypeArguments& function_type_arguments,
-                         const Function& function,
-                         const Context& context,
-                         Heap::Space space = Heap::kNew);
+  static ClosurePtr New(const TypeArguments& instantiator_type_arguments,
+                        const TypeArguments& function_type_arguments,
+                        const Function& function,
+                        const Context& context,
+                        Heap::Space space = Heap::kNew);
 
-  static RawClosure* New(const TypeArguments& instantiator_type_arguments,
-                         const TypeArguments& function_type_arguments,
-                         const TypeArguments& delayed_type_arguments,
-                         const Function& function,
-                         const Context& context,
-                         Heap::Space space = Heap::kNew);
+  static ClosurePtr New(const TypeArguments& instantiator_type_arguments,
+                        const TypeArguments& function_type_arguments,
+                        const TypeArguments& delayed_type_arguments,
+                        const Function& function,
+                        const Context& context,
+                        Heap::Space space = Heap::kNew);
 
-  RawFunction* GetInstantiatedSignature(Zone* zone) const;
+  FunctionPtr GetInstantiatedSignature(Zone* zone) const;
 
  private:
-  static RawClosure* New();
+  static ClosurePtr New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Closure, Instance);
   friend class Class;
@@ -10336,9 +10356,9 @@
   uint64_t Id() const { return raw_ptr()->id_; }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawCapability));
+    return RoundedAllocationSize(sizeof(CapabilityLayout));
   }
-  static RawCapability* New(uint64_t id, Heap::Space space = Heap::kNew);
+  static CapabilityPtr New(uint64_t id, Heap::Space space = Heap::kNew);
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Capability, Instance);
@@ -10347,18 +10367,18 @@
 
 class ReceivePort : public Instance {
  public:
-  RawSendPort* send_port() const { return raw_ptr()->send_port_; }
+  SendPortPtr send_port() const { return raw_ptr()->send_port_; }
   Dart_Port Id() const { return send_port()->ptr()->id_; }
 
-  RawInstance* handler() const { return raw_ptr()->handler_; }
+  InstancePtr handler() const { return raw_ptr()->handler_; }
   void set_handler(const Instance& value) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawReceivePort));
+    return RoundedAllocationSize(sizeof(ReceivePortLayout));
   }
-  static RawReceivePort* New(Dart_Port id,
-                             bool is_control_port,
-                             Heap::Space space = Heap::kNew);
+  static ReceivePortPtr New(Dart_Port id,
+                            bool is_control_port,
+                            Heap::Space space = Heap::kNew);
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ReceivePort, Instance);
@@ -10376,12 +10396,12 @@
   }
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawSendPort));
+    return RoundedAllocationSize(sizeof(SendPortLayout));
   }
-  static RawSendPort* New(Dart_Port id, Heap::Space space = Heap::kNew);
-  static RawSendPort* New(Dart_Port id,
-                          Dart_Port origin_id,
-                          Heap::Space space = Heap::kNew);
+  static SendPortPtr New(Dart_Port id, Heap::Space space = Heap::kNew);
+  static SendPortPtr New(Dart_Port id,
+                         Dart_Port origin_id,
+                         Heap::Space space = Heap::kNew);
 
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(SendPort, Instance);
@@ -10419,12 +10439,12 @@
 
 class TransferableTypedData : public Instance {
  public:
-  static RawTransferableTypedData* New(uint8_t* data,
-                                       intptr_t len,
-                                       Heap::Space space = Heap::kNew);
+  static TransferableTypedDataPtr New(uint8_t* data,
+                                      intptr_t len,
+                                      Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawTransferableTypedData));
+    return RoundedAllocationSize(sizeof(TransferableTypedDataLayout));
   }
 
  private:
@@ -10439,16 +10459,16 @@
 
   intptr_t Length() const;
 
-  RawStackTrace* async_link() const { return raw_ptr()->async_link_; }
+  StackTracePtr async_link() const { return raw_ptr()->async_link_; }
   void set_async_link(const StackTrace& async_link) const;
   void set_expand_inlined(bool value) const;
 
-  RawArray* code_array() const { return raw_ptr()->code_array_; }
-  RawObject* CodeAtFrame(intptr_t frame_index) const;
+  ArrayPtr code_array() const { return raw_ptr()->code_array_; }
+  ObjectPtr CodeAtFrame(intptr_t frame_index) const;
   void SetCodeAtFrame(intptr_t frame_index, const Object& code) const;
 
-  RawArray* pc_offset_array() const { return raw_ptr()->pc_offset_array_; }
-  RawSmi* PcOffsetAtFrame(intptr_t frame_index) const;
+  ArrayPtr pc_offset_array() const { return raw_ptr()->pc_offset_array_; }
+  SmiPtr PcOffsetAtFrame(intptr_t frame_index) const;
   void SetPcOffsetAtFrame(intptr_t frame_index, const Smi& pc_offset) const;
 
   bool skip_sync_start_in_parent_stack() const;
@@ -10469,22 +10489,19 @@
   static constexpr intptr_t kSyncAsyncCroppedFrames = 2;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawStackTrace));
+    return RoundedAllocationSize(sizeof(StackTraceLayout));
   }
-  static RawStackTrace* New(const Array& code_array,
-                            const Array& pc_offset_array,
-                            Heap::Space space = Heap::kNew);
+  static StackTracePtr New(const Array& code_array,
+                           const Array& pc_offset_array,
+                           Heap::Space space = Heap::kNew);
 
-  static RawStackTrace* New(const Array& code_array,
-                            const Array& pc_offset_array,
-                            const StackTrace& async_link,
-                            bool skip_sync_start_in_parent_stack,
-                            Heap::Space space = Heap::kNew);
+  static StackTracePtr New(const Array& code_array,
+                           const Array& pc_offset_array,
+                           const StackTrace& async_link,
+                           bool skip_sync_start_in_parent_stack,
+                           Heap::Space space = Heap::kNew);
 
  private:
-  static const char* ToDartCString(const StackTrace& stack_trace_in);
-  static const char* ToDwarfCString(const StackTrace& stack_trace_in);
-
   void set_code_array(const Array& code_array) const;
   void set_pc_offset_array(const Array& pc_offset_array) const;
   bool expand_inlined() const;
@@ -10575,13 +10592,13 @@
                        : raw_ptr()->num_two_byte_registers_;
   }
 
-  RawString* pattern() const { return raw_ptr()->pattern_; }
-  RawSmi* num_bracket_expressions() const {
+  StringPtr pattern() const { return raw_ptr()->pattern_; }
+  SmiPtr num_bracket_expressions() const {
     return raw_ptr()->num_bracket_expressions_;
   }
-  RawArray* capture_name_map() const { return raw_ptr()->capture_name_map_; }
+  ArrayPtr capture_name_map() const { return raw_ptr()->capture_name_map_; }
 
-  RawTypedData* bytecode(bool is_one_byte, bool sticky) const {
+  TypedDataPtr bytecode(bool is_one_byte, bool sticky) const {
     if (sticky) {
       return is_one_byte ? raw_ptr()->one_byte_sticky_.bytecode_
                          : raw_ptr()->two_byte_sticky_.bytecode_;
@@ -10595,24 +10612,24 @@
     if (sticky) {
       switch (cid) {
         case kOneByteStringCid:
-          return OFFSET_OF(RawRegExp, one_byte_sticky_.function_);
+          return OFFSET_OF(RegExpLayout, one_byte_sticky_.function_);
         case kTwoByteStringCid:
-          return OFFSET_OF(RawRegExp, two_byte_sticky_.function_);
+          return OFFSET_OF(RegExpLayout, two_byte_sticky_.function_);
         case kExternalOneByteStringCid:
-          return OFFSET_OF(RawRegExp, external_one_byte_sticky_function_);
+          return OFFSET_OF(RegExpLayout, external_one_byte_sticky_function_);
         case kExternalTwoByteStringCid:
-          return OFFSET_OF(RawRegExp, external_two_byte_sticky_function_);
+          return OFFSET_OF(RegExpLayout, external_two_byte_sticky_function_);
       }
     } else {
       switch (cid) {
         case kOneByteStringCid:
-          return OFFSET_OF(RawRegExp, one_byte_.function_);
+          return OFFSET_OF(RegExpLayout, one_byte_.function_);
         case kTwoByteStringCid:
-          return OFFSET_OF(RawRegExp, two_byte_.function_);
+          return OFFSET_OF(RegExpLayout, two_byte_.function_);
         case kExternalOneByteStringCid:
-          return OFFSET_OF(RawRegExp, external_one_byte_function_);
+          return OFFSET_OF(RegExpLayout, external_one_byte_function_);
         case kExternalTwoByteStringCid:
-          return OFFSET_OF(RawRegExp, external_two_byte_function_);
+          return OFFSET_OF(RegExpLayout, external_two_byte_function_);
       }
     }
 
@@ -10620,12 +10637,12 @@
     return -1;
   }
 
-  RawFunction** FunctionAddr(intptr_t cid, bool sticky) const {
-    return reinterpret_cast<RawFunction**>(
+  FunctionPtr* FunctionAddr(intptr_t cid, bool sticky) const {
+    return reinterpret_cast<FunctionPtr*>(
         FieldAddrAtOffset(function_offset(cid, sticky)));
   }
 
-  RawFunction* function(intptr_t cid, bool sticky) const {
+  FunctionPtr function(intptr_t cid, bool sticky) const {
     return *FunctionAddr(cid, sticky);
   }
 
@@ -10684,10 +10701,10 @@
   virtual bool CanonicalizeEquals(const Instance& other) const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawRegExp));
+    return RoundedAllocationSize(sizeof(RegExpLayout));
   }
 
-  static RawRegExp* New(Heap::Space space = Heap::kNew);
+  static RegExpPtr New(Heap::Space space = Heap::kNew);
 
  private:
   void set_type(RegExType type) const {
@@ -10703,25 +10720,25 @@
 
 class WeakProperty : public Instance {
  public:
-  RawObject* key() const { return raw_ptr()->key_; }
+  ObjectPtr key() const { return raw_ptr()->key_; }
 
   void set_key(const Object& key) const {
     StorePointer(&raw_ptr()->key_, key.raw());
   }
 
-  RawObject* value() const { return raw_ptr()->value_; }
+  ObjectPtr value() const { return raw_ptr()->value_; }
 
   void set_value(const Object& value) const {
     StorePointer(&raw_ptr()->value_, value.raw());
   }
 
-  static RawWeakProperty* New(Heap::Space space = Heap::kNew);
+  static WeakPropertyPtr New(Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawWeakProperty));
+    return RoundedAllocationSize(sizeof(WeakPropertyLayout));
   }
 
-  static void Clear(RawWeakProperty* raw_weak) {
+  static void Clear(WeakPropertyPtr raw_weak) {
     ASSERT(raw_weak->ptr()->next_ == 0);
     // This action is performed by the GC. No barrier.
     raw_weak->ptr()->key_ = Object::null();
@@ -10735,29 +10752,29 @@
 
 class MirrorReference : public Instance {
  public:
-  RawObject* referent() const { return raw_ptr()->referent_; }
+  ObjectPtr referent() const { return raw_ptr()->referent_; }
 
   void set_referent(const Object& referent) const {
     StorePointer(&raw_ptr()->referent_, referent.raw());
   }
 
-  RawAbstractType* GetAbstractTypeReferent() const;
+  AbstractTypePtr GetAbstractTypeReferent() const;
 
-  RawClass* GetClassReferent() const;
+  ClassPtr GetClassReferent() const;
 
-  RawField* GetFieldReferent() const;
+  FieldPtr GetFieldReferent() const;
 
-  RawFunction* GetFunctionReferent() const;
+  FunctionPtr GetFunctionReferent() const;
 
-  RawLibrary* GetLibraryReferent() const;
+  LibraryPtr GetLibraryReferent() const;
 
-  RawTypeParameter* GetTypeParameterReferent() const;
+  TypeParameterPtr GetTypeParameterReferent() const;
 
-  static RawMirrorReference* New(const Object& referent,
-                                 Heap::Space space = Heap::kNew);
+  static MirrorReferencePtr New(const Object& referent,
+                                Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawMirrorReference));
+    return RoundedAllocationSize(sizeof(MirrorReferenceLayout));
   }
 
  private:
@@ -10773,24 +10790,24 @@
     ASSERT(t < UserTags::kUserTagIdOffset + UserTags::kMaxUserTags);
     StoreNonPointer(&raw_ptr()->tag_, t);
   }
-  static intptr_t tag_offset() { return OFFSET_OF(RawUserTag, tag_); }
+  static intptr_t tag_offset() { return OFFSET_OF(UserTagLayout, tag_); }
 
-  RawString* label() const { return raw_ptr()->label_; }
+  StringPtr label() const { return raw_ptr()->label_; }
 
   void MakeActive() const;
 
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawUserTag));
+    return RoundedAllocationSize(sizeof(UserTagLayout));
   }
 
-  static RawUserTag* New(const String& label, Heap::Space space = Heap::kOld);
-  static RawUserTag* DefaultTag();
+  static UserTagPtr New(const String& label, Heap::Space space = Heap::kOld);
+  static UserTagPtr DefaultTag();
 
   static bool TagTableIsFull(Thread* thread);
-  static RawUserTag* FindTagById(uword tag_id);
+  static UserTagPtr FindTagById(uword tag_id);
 
  private:
-  static RawUserTag* FindTagInIsolate(Thread* thread, const String& label);
+  static UserTagPtr FindTagInIsolate(Thread* thread, const String& label);
   static void AddTagToIsolate(Thread* thread, const UserTag& tag);
 
   void set_label(const String& tag_label) const {
@@ -10805,14 +10822,14 @@
 class FutureOr : public Instance {
  public:
   static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawFutureOr));
+    return RoundedAllocationSize(sizeof(FutureOrLayout));
   }
 
-  virtual RawTypeArguments* GetTypeArguments() const {
+  virtual TypeArgumentsPtr GetTypeArguments() const {
     return raw_ptr()->type_arguments_;
   }
   static intptr_t type_arguments_offset() {
-    return OFFSET_OF(RawFutureOr, type_arguments_);
+    return OFFSET_OF(FutureOrLayout, type_arguments_);
   }
 
  private:
@@ -10822,8 +10839,8 @@
 };
 
 // Breaking cycles and loops.
-RawClass* Object::clazz() const {
-  uword raw_value = reinterpret_cast<uword>(raw_);
+ClassPtr Object::clazz() const {
+  uword raw_value = static_cast<uword>(raw_);
   if ((raw_value & kSmiTagMask) == kSmiTag) {
     return Smi::Class();
   }
@@ -10832,7 +10849,7 @@
 }
 
 DART_FORCE_INLINE
-void Object::SetRaw(RawObject* value) {
+void Object::SetRaw(ObjectPtr value) {
   NoSafepointScope no_safepoint_scope;
   raw_ = value;
   intptr_t cid = value->GetClassIdMayBeSmi();
@@ -10847,12 +10864,16 @@
   if (FLAG_verify_handles && raw_->IsHeapObject()) {
     Isolate* isolate = Isolate::Current();
     Heap* isolate_heap = isolate->heap();
-    Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
-    uword addr = RawObject::ToAddr(raw_);
-    if (!isolate_heap->Contains(addr) && !vm_isolate_heap->Contains(addr)) {
-      ASSERT(FLAG_write_protect_code);
-      addr = RawObject::ToAddr(HeapPage::ToWritable(raw_));
-      ASSERT(isolate_heap->Contains(addr) || vm_isolate_heap->Contains(addr));
+    // TODO(rmacnak): Remove after rewriting StackFrame::VisitObjectPointers
+    // to not use handles.
+    if (!isolate_heap->new_space()->scavenging()) {
+      Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
+      uword addr = ObjectLayout::ToAddr(raw_);
+      if (!isolate_heap->Contains(addr) && !vm_isolate_heap->Contains(addr)) {
+        ASSERT(FLAG_write_protect_code);
+        addr = ObjectLayout::ToAddr(HeapPage::ToWritable(raw_));
+        ASSERT(isolate_heap->Contains(addr) || vm_isolate_heap->Contains(addr));
+      }
     }
   }
 #endif
@@ -10863,14 +10884,14 @@
   return raw_ptr()->bytecode_ != Bytecode::null();
 }
 
-bool Function::HasBytecode(RawFunction* function) {
+bool Function::HasBytecode(FunctionPtr function) {
   return function->ptr()->bytecode_ != Bytecode::null();
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 intptr_t Field::HostOffset() const {
   ASSERT(is_instance());  // Valid only for dart instance fields.
-  return (raw_ptr()->host_offset_or_field_id_ * kWordSize);
+  return (Smi::Value(raw_ptr()->host_offset_or_field_id_) * kWordSize);
 }
 
 intptr_t Field::TargetOffset() const {
@@ -10882,12 +10903,20 @@
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
 }
 
+inline intptr_t Field::TargetOffsetOf(const FieldPtr field) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  return field->ptr()->target_offset_;
+#else
+  return Smi::Value(field->ptr()->host_offset_or_field_id_);
+#endif  //  !defined(DART_PRECOMPILED_RUNTIME)
+}
+
 void Field::SetOffset(intptr_t host_offset_in_bytes,
                       intptr_t target_offset_in_bytes) const {
   ASSERT(is_instance());  // Valid only for dart instance fields.
   ASSERT(kWordSize != 0);
-  StoreNonPointer(&raw_ptr()->host_offset_or_field_id_,
-                  host_offset_in_bytes / kWordSize);
+  StoreSmi(&raw_ptr()->host_offset_or_field_id_,
+           Smi::New(host_offset_in_bytes / kWordSize));
 #if !defined(DART_PRECOMPILED_RUNTIME)
   ASSERT(compiler::target::kWordSize != 0);
   StoreNonPointer(&raw_ptr()->target_offset_,
@@ -10897,16 +10926,20 @@
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
 }
 
-RawInstance* Field::StaticValue() const {
+InstancePtr Field::StaticValue() const {
   ASSERT(is_static());  // Valid only for static dart fields.
   return Isolate::Current()->field_table()->At(
-      raw_ptr()->host_offset_or_field_id_);
+      Smi::Value(raw_ptr()->host_offset_or_field_id_));
+}
+
+inline intptr_t Field::field_id() const {
+  return Smi::Value(raw_ptr()->host_offset_or_field_id_);
 }
 
 void Field::set_field_id(intptr_t field_id) const {
   ASSERT(is_static());
   ASSERT(Thread::Current()->IsMutatorThread());
-  StoreNonPointer(&raw_ptr()->host_offset_or_field_id_, field_id);
+  StoreSmi(&raw_ptr()->host_offset_or_field_id_, Smi::New(field_id));
 }
 
 #ifndef DART_PRECOMPILED_RUNTIME
@@ -10922,8 +10955,7 @@
 intptr_t Instance::GetNativeField(int index) const {
   ASSERT(IsValidNativeIndex(index));
   NoSafepointScope no_safepoint;
-  RawTypedData* native_fields =
-      reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+  TypedDataPtr native_fields = static_cast<TypedDataPtr>(*NativeFieldsAddr());
   if (native_fields == TypedData::null()) {
     return 0;
   }
@@ -10935,8 +10967,7 @@
   NoSafepointScope no_safepoint;
   ASSERT(num_fields == NumNativeFields());
   ASSERT(field_values != NULL);
-  RawTypedData* native_fields =
-      reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+  TypedDataPtr native_fields = static_cast<TypedDataPtr>(*NativeFieldsAddr());
   if (native_fields == TypedData::null()) {
     for (intptr_t i = 0; i < num_fields; i++) {
       field_values[i] = 0;
@@ -10990,12 +11021,12 @@
   array.SetAt((index * kEntryLength) + kTargetFunctionIndex, target);
 }
 
-RawObject* MegamorphicCache::GetClassId(const Array& array, intptr_t index) {
+ObjectPtr MegamorphicCache::GetClassId(const Array& array, intptr_t index) {
   return array.At((index * kEntryLength) + kClassIdIndex);
 }
 
-RawObject* MegamorphicCache::GetTargetFunction(const Array& array,
-                                               intptr_t index) {
+ObjectPtr MegamorphicCache::GetTargetFunction(const Array& array,
+                                              intptr_t index) {
   return array.At((index * kEntryLength) + kTargetFunctionIndex);
 }
 
@@ -11095,7 +11126,7 @@
         : array_(array), index_(index) {}
 
     template <EnumType kElement>
-    typename std::tuple_element<kElement, TupleT>::type::RawObjectType* Get()
+    typename std::tuple_element<kElement, TupleT>::type::ObjectPtrType Get()
         const {
       using object_type = typename std::tuple_element<kElement, TupleT>::type;
       return object_type::RawCast(array_.At(index_ + kElement));
@@ -11170,7 +11201,9 @@
                       std::tuple<String, Array, Function>>;
 
 using StaticCallsTable =
-    ArrayOfTuplesView<Code::SCallTableEntry, std::tuple<Smi, Code, Function>>;
+    ArrayOfTuplesView<Code::SCallTableEntry, std::tuple<Smi, Object, Function>>;
+
+using StaticCallsTableEntry = StaticCallsTable::TupleView;
 
 using SubtypeTestCacheTable = ArrayOfTuplesView<SubtypeTestCache::Entries,
                                                 std::tuple<Object,
@@ -11193,7 +11226,7 @@
                                       Object* reusable_object_handle);
 
 DART_WARN_UNUSED_RESULT
-RawError* EntryPointFieldInvocationError(const String& getter_name);
+ErrorPtr EntryPointFieldInvocationError(const String& getter_name);
 
 }  // namespace dart
 
diff --git a/runtime/vm/object_arm64_test.cc b/runtime/vm/object_arm64_test.cc
index c71002b..640c91b 100644
--- a/runtime/vm/object_arm64_test.cc
+++ b/runtime/vm/object_arm64_test.cc
@@ -46,7 +46,7 @@
 // This is used to test Embedded Smi objects in the instructions.
 void GenerateEmbedSmiInCode(compiler::Assembler* assembler, intptr_t value) {
   const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
-  const int64_t val = reinterpret_cast<int64_t>(smi_object.raw());
+  const int64_t val = static_cast<int64_t>(smi_object.raw());
   __ LoadImmediate(R0, val);
   __ ret();
 }
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index e568c4a..6f028d9 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -51,9 +51,9 @@
   // Marks and pushes. Used to initialize this stack with roots.
   // We can use ObjectIdTable normally used by serializers because it
   // won't be in use while handling a service request (ObjectGraph's only use).
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; ++current) {
-      if ((*current)->IsHeapObject() && !(*current)->InVMIsolateHeap() &&
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* current = first; current <= last; ++current) {
+      if ((*current)->IsHeapObject() && !(*current)->ptr()->InVMIsolateHeap() &&
           object_ids_->GetValueExclusive(*current) == 0) {  // not visited yet
         if (!include_vm_objects_ && !IsUserClass((*current)->GetClassId())) {
           continue;
@@ -78,7 +78,7 @@
         data_.RemoveLast();
         continue;
       }
-      RawObject* obj = node.obj;
+      ObjectPtr obj = node.obj;
       ASSERT(obj->IsHeapObject());
       Node sentinel;
       sentinel.ptr = kSentinel;
@@ -91,7 +91,7 @@
       }
       if (direction == ObjectGraph::Visitor::kProceed) {
         set_gc_root_type(node.gc_root_type);
-        obj->VisitPointers(this);
+        obj->ptr()->VisitPointers(this);
         clear_gc_root_type();
       }
     }
@@ -109,13 +109,13 @@
 
  private:
   struct Node {
-    RawObject** ptr;  // kSentinel for the sentinel node.
-    RawObject* obj;
+    ObjectPtr* ptr;  // kSentinel for the sentinel node.
+    ObjectPtr obj;
     const char* gc_root_type;
   };
 
   bool visit_weak_persistent_handles_ = false;
-  static RawObject** const kSentinel;
+  static ObjectPtr* const kSentinel;
   static const intptr_t kInitialCapacity = 1024;
   static const intptr_t kNoParent = -1;
 
@@ -138,9 +138,9 @@
   DISALLOW_COPY_AND_ASSIGN(Stack);
 };
 
-RawObject** const ObjectGraph::Stack::kSentinel = NULL;
+ObjectPtr* const ObjectGraph::Stack::kSentinel = NULL;
 
-RawObject* ObjectGraph::StackIterator::Get() const {
+ObjectPtr ObjectGraph::StackIterator::Get() const {
   return stack_->data_[index_].obj;
 }
 
@@ -160,17 +160,18 @@
     return -1;
   }
   Stack::Node parent = stack_->data_[parent_index];
-  uword parent_start = RawObject::ToAddr(parent.obj);
+  uword parent_start = ObjectLayout::ToAddr(parent.obj);
   Stack::Node child = stack_->data_[index_];
   ASSERT(child.obj == *child.ptr);
   uword child_ptr_addr = reinterpret_cast<uword>(child.ptr);
   intptr_t offset = child_ptr_addr - parent_start;
-  if (offset > 0 && offset < parent.obj->HeapSize()) {
+  if (offset > 0 && offset < parent.obj->ptr()->HeapSize()) {
     ASSERT(Utils::IsAligned(offset, kWordSize));
     return offset >> kWordSizeLog2;
   } else {
     // Some internal VM objects visit pointers not contained within the parent.
-    // For instance, RawCode::VisitCodePointers visits pointers in instructions.
+    // For instance, CodeLayout::VisitCodePointers visits pointers in
+    // instructions.
     ASSERT(!parent.obj->IsDartInstance());
     return -1;
   }
@@ -199,12 +200,12 @@
         fields = cls.fields();
         for (intptr_t j = 0; j < fields.Length(); j++) {
           field ^= fields.At(j);
-          RawObject* ptr = field.raw();
+          ObjectPtr ptr = field.raw();
           visitor->VisitPointer(&ptr);
         }
       } else if (entry.IsField()) {
         field ^= entry.raw();
-        RawObject* ptr = field.raw();
+        ObjectPtr ptr = field.raw();
         visitor->VisitPointer(&ptr);
       }
     }
@@ -243,7 +244,7 @@
   Stack stack(isolate_group());
   stack.set_visit_weak_persistent_handles(
       visitor->visit_weak_persistent_handles());
-  RawObject* root_raw = root.raw();
+  ObjectPtr root_raw = root.raw();
   stack.VisitPointer(&root_raw);
   stack.TraverseGraph(visitor);
 }
@@ -253,9 +254,9 @@
   InstanceAccumulator(ObjectGraph::Stack* stack, intptr_t class_id)
       : stack_(stack), class_id_(class_id) {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     if (obj->GetClassId() == class_id_) {
-      RawObject* rawobj = obj;
+      ObjectPtr rawobj = obj;
       stack_->VisitPointer(&rawobj);
     }
   }
@@ -282,13 +283,13 @@
  public:
   SizeVisitor() : size_(0) {}
   intptr_t size() const { return size_; }
-  virtual bool ShouldSkip(RawObject* obj) const { return false; }
+  virtual bool ShouldSkip(ObjectPtr obj) const { return false; }
   virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
-    RawObject* obj = it->Get();
+    ObjectPtr obj = it->Get();
     if (ShouldSkip(obj)) {
       return kBacktrack;
     }
-    size_ += obj->HeapSize();
+    size_ += obj->ptr()->HeapSize();
     return kProceed;
   }
 
@@ -299,7 +300,7 @@
 class SizeExcludingObjectVisitor : public SizeVisitor {
  public:
   explicit SizeExcludingObjectVisitor(const Object& skip) : skip_(skip) {}
-  virtual bool ShouldSkip(RawObject* obj) const { return obj == skip_.raw(); }
+  virtual bool ShouldSkip(ObjectPtr obj) const { return obj == skip_.raw(); }
 
  private:
   const Object& skip_;
@@ -308,7 +309,7 @@
 class SizeExcludingClassVisitor : public SizeVisitor {
  public:
   explicit SizeExcludingClassVisitor(intptr_t skip) : skip_(skip) {}
-  virtual bool ShouldSkip(RawObject* obj) const {
+  virtual bool ShouldSkip(ObjectPtr obj) const {
     return obj->GetClassId() == skip_;
   }
 
@@ -355,14 +356,13 @@
 class RetainingPathVisitor : public ObjectGraph::Visitor {
  public:
   // We cannot use a GrowableObjectArray, since we must not trigger GC.
-  RetainingPathVisitor(RawObject* obj, const Array& path)
-      : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) {
-  }
+  RetainingPathVisitor(ObjectPtr obj, const Array& path)
+      : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) {}
 
   intptr_t length() const { return length_; }
   virtual bool visit_weak_persistent_handles() const { return true; }
 
-  bool ShouldSkip(RawObject* obj) {
+  bool ShouldSkip(ObjectPtr obj) {
     // A retaining path through ICData is never the only retaining path,
     // and it is less informative than its alternatives.
     intptr_t cid = obj->GetClassId();
@@ -374,10 +374,10 @@
     }
   }
 
-  bool ShouldStop(RawObject* obj) {
+  bool ShouldStop(ObjectPtr obj) {
     // A static field is considered a root from a language point of view.
     if (obj->IsField()) {
-      const Field& field = Field::Handle(static_cast<RawField*>(obj));
+      const Field& field = Field::Handle(static_cast<FieldPtr>(obj));
       return field.is_static();
     }
     return false;
@@ -385,7 +385,7 @@
 
   void StartList() { was_last_array_ = false; }
 
-  intptr_t HideNDescendant(RawObject* obj) {
+  intptr_t HideNDescendant(ObjectPtr obj) {
     // A GrowableObjectArray overwrites its internal storage.
     // Keeping both of them in the list is redundant.
     if (was_last_array_ && obj->IsGrowableObjectArray()) {
@@ -433,7 +433,7 @@
 
  private:
   Thread* thread_;
-  RawObject* obj_;
+  ObjectPtr obj_;
   const Array& path_;
   intptr_t length_;
   bool was_last_array_;
@@ -444,7 +444,7 @@
   HeapIterationScope iteration_scope(Thread::Current(), true);
   // To break the trivial path, the handle 'obj' is temporarily cleared during
   // the search, but restored before returning.
-  RawObject* raw = obj->raw();
+  ObjectPtr raw = obj->raw();
   *obj = Object::null();
   RetainingPathVisitor visitor(raw, path);
   IterateUserObjects(&visitor);
@@ -460,11 +460,11 @@
  public:
   // We cannot use a GrowableObjectArray, since we must not trigger GC.
   InboundReferencesVisitor(Isolate* isolate,
-                           RawObject* target,
+                           ObjectPtr target,
                            const Array& references,
                            Object* scratch)
       : ObjectPointerVisitor(isolate->group()),
-        source_(NULL),
+        source_(nullptr),
         target_(target),
         references_(references),
         scratch_(scratch),
@@ -474,14 +474,14 @@
 
   intptr_t length() const { return length_; }
 
-  virtual void VisitObject(RawObject* raw_obj) {
+  virtual void VisitObject(ObjectPtr raw_obj) {
     source_ = raw_obj;
-    raw_obj->VisitPointers(this);
+    raw_obj->ptr()->VisitPointers(this);
   }
 
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current_ptr = first; current_ptr <= last; current_ptr++) {
-      RawObject* current_obj = *current_ptr;
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* current_ptr = first; current_ptr <= last; current_ptr++) {
+      ObjectPtr current_obj = *current_ptr;
       if (current_obj == target_) {
         intptr_t obj_index = length_ * 2;
         intptr_t offset_index = obj_index + 1;
@@ -490,16 +490,16 @@
           references_.SetAt(obj_index, *scratch_);
 
           *scratch_ = Smi::New(0);
-          uword source_start = RawObject::ToAddr(source_);
+          uword source_start = ObjectLayout::ToAddr(source_);
           uword current_ptr_addr = reinterpret_cast<uword>(current_ptr);
           intptr_t offset = current_ptr_addr - source_start;
-          if (offset > 0 && offset < source_->HeapSize()) {
+          if (offset > 0 && offset < source_->ptr()->HeapSize()) {
             ASSERT(Utils::IsAligned(offset, kWordSize));
             *scratch_ = Smi::New(offset >> kWordSizeLog2);
           } else {
             // Some internal VM objects visit pointers not contained within the
-            // parent. For instance, RawCode::VisitCodePointers visits pointers
-            // in instructions.
+            // parent. For instance, CodeLayout::VisitCodePointers visits
+            // pointers in instructions.
             ASSERT(!source_->IsDartInstance());
             *scratch_ = Smi::New(-1);
           }
@@ -511,8 +511,8 @@
   }
 
  private:
-  RawObject* source_;
-  RawObject* target_;
+  ObjectPtr source_;
+  ObjectPtr target_;
   const Array& references_;
   Object* scratch_;
   intptr_t length_;
@@ -686,8 +686,8 @@
   }
 }
 
-bool HeapSnapshotWriter::OnImagePage(RawObject* obj) const {
-  const uword addr = RawObject::ToAddr(obj);
+bool HeapSnapshotWriter::OnImagePage(ObjectPtr obj) const {
+  const uword addr = ObjectLayout::ToAddr(obj);
   for (intptr_t i = 0; i < kMaxImagePages; i++) {
     if ((addr - image_page_ranges_[i].base) < image_page_ranges_[i].size) {
       return true;
@@ -696,7 +696,7 @@
   return false;
 }
 
-CountingPage* HeapSnapshotWriter::FindCountingPage(RawObject* obj) const {
+CountingPage* HeapSnapshotWriter::FindCountingPage(ObjectPtr obj) const {
   if (obj->IsOldObject() && !OnImagePage(obj)) {
     // On a regular or large page.
     HeapPage* page = HeapPage::Of(obj);
@@ -707,20 +707,20 @@
   return nullptr;
 }
 
-void HeapSnapshotWriter::AssignObjectId(RawObject* obj) {
+void HeapSnapshotWriter::AssignObjectId(ObjectPtr obj) {
   ASSERT(obj->IsHeapObject());
 
   CountingPage* counting_page = FindCountingPage(obj);
   if (counting_page != nullptr) {
     // Likely: object on an ordinary page.
-    counting_page->Record(RawObject::ToAddr(obj), ++object_count_);
+    counting_page->Record(ObjectLayout::ToAddr(obj), ++object_count_);
   } else {
     // Unlikely: new space object, or object on a large or image page.
     thread()->heap()->SetObjectId(obj, ++object_count_);
   }
 }
 
-intptr_t HeapSnapshotWriter::GetObjectId(RawObject* obj) const {
+intptr_t HeapSnapshotWriter::GetObjectId(ObjectPtr obj) const {
   if (!obj->IsHeapObject()) {
     return 0;
   }
@@ -734,7 +734,7 @@
   intptr_t id;
   if (counting_page != nullptr) {
     // Likely: object on an ordinary page.
-    id = counting_page->Lookup(RawObject::ToAddr(obj));
+    id = counting_page->Lookup(ObjectLayout::ToAddr(obj));
   } else {
     // Unlikely: new space object, or object on a large or image page.
     id = thread()->heap()->GetObjectId(obj);
@@ -765,14 +765,14 @@
         HandleVisitor(Thread::Current()),
         writer_(writer) {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     if (obj->IsPseudoObject()) return;
 
     writer_->AssignObjectId(obj);
-    obj->VisitPointers(this);
+    obj->ptr()->VisitPointers(this);
   }
 
-  void VisitPointers(RawObject** from, RawObject** to) {
+  void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
     intptr_t count = to - from + 1;
     ASSERT(count >= 0);
     writer_->CountReferences(count);
@@ -819,30 +819,30 @@
         isolate_(thread()->isolate()),
         writer_(writer) {}
 
-  void VisitObject(RawObject* obj) {
+  void VisitObject(ObjectPtr obj) {
     if (obj->IsPseudoObject()) return;
 
     intptr_t cid = obj->GetClassId();
     writer_->WriteUnsigned(cid);
-    writer_->WriteUnsigned(discount_sizes_ ? 0 : obj->HeapSize());
+    writer_->WriteUnsigned(discount_sizes_ ? 0 : obj->ptr()->HeapSize());
 
     if (cid == kNullCid) {
       writer_->WriteUnsigned(kNullData);
     } else if (cid == kBoolCid) {
       writer_->WriteUnsigned(kBoolData);
       writer_->WriteUnsigned(
-          static_cast<uintptr_t>(static_cast<RawBool*>(obj)->ptr()->value_));
+          static_cast<uintptr_t>(static_cast<BoolPtr>(obj)->ptr()->value_));
     } else if (cid == kSmiCid) {
       UNREACHABLE();
     } else if (cid == kMintCid) {
       writer_->WriteUnsigned(kIntData);
-      writer_->WriteSigned(static_cast<RawMint*>(obj)->ptr()->value_);
+      writer_->WriteSigned(static_cast<MintPtr>(obj)->ptr()->value_);
     } else if (cid == kDoubleCid) {
       writer_->WriteUnsigned(kDoubleData);
-      writer_->WriteBytes(&(static_cast<RawDouble*>(obj)->ptr()->value_),
+      writer_->WriteBytes(&(static_cast<DoublePtr>(obj)->ptr()->value_),
                           sizeof(double));
     } else if (cid == kOneByteStringCid) {
-      RawOneByteString* str = static_cast<RawOneByteString*>(obj);
+      OneByteStringPtr str = static_cast<OneByteStringPtr>(obj);
       intptr_t len = Smi::Value(str->ptr()->length_);
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kLatin1Data);
@@ -850,8 +850,7 @@
       writer_->WriteUnsigned(trunc_len);
       writer_->WriteBytes(&str->ptr()->data()[0], trunc_len);
     } else if (cid == kExternalOneByteStringCid) {
-      RawExternalOneByteString* str =
-          static_cast<RawExternalOneByteString*>(obj);
+      ExternalOneByteStringPtr str = static_cast<ExternalOneByteStringPtr>(obj);
       intptr_t len = Smi::Value(str->ptr()->length_);
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kLatin1Data);
@@ -859,7 +858,7 @@
       writer_->WriteUnsigned(trunc_len);
       writer_->WriteBytes(&str->ptr()->external_data_[0], trunc_len);
     } else if (cid == kTwoByteStringCid) {
-      RawTwoByteString* str = static_cast<RawTwoByteString*>(obj);
+      TwoByteStringPtr str = static_cast<TwoByteStringPtr>(obj);
       intptr_t len = Smi::Value(str->ptr()->length_);
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kUTF16Data);
@@ -867,8 +866,7 @@
       writer_->WriteUnsigned(trunc_len);
       writer_->WriteBytes(&str->ptr()->data()[0], trunc_len * 2);
     } else if (cid == kExternalTwoByteStringCid) {
-      RawExternalTwoByteString* str =
-          static_cast<RawExternalTwoByteString*>(obj);
+      ExternalTwoByteStringPtr str = static_cast<ExternalTwoByteStringPtr>(obj);
       intptr_t len = Smi::Value(str->ptr()->length_);
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kUTF16Data);
@@ -878,63 +876,63 @@
     } else if (cid == kArrayCid || cid == kImmutableArrayCid) {
       writer_->WriteUnsigned(kLengthData);
       writer_->WriteUnsigned(
-          Smi::Value(static_cast<RawArray*>(obj)->ptr()->length_));
+          Smi::Value(static_cast<ArrayPtr>(obj)->ptr()->length_));
     } else if (cid == kGrowableObjectArrayCid) {
       writer_->WriteUnsigned(kLengthData);
-      writer_->WriteUnsigned(Smi::Value(
-          static_cast<RawGrowableObjectArray*>(obj)->ptr()->length_));
+      writer_->WriteUnsigned(
+          Smi::Value(static_cast<GrowableObjectArrayPtr>(obj)->ptr()->length_));
     } else if (cid == kLinkedHashMapCid) {
       writer_->WriteUnsigned(kLengthData);
       writer_->WriteUnsigned(
-          Smi::Value(static_cast<RawLinkedHashMap*>(obj)->ptr()->used_data_));
+          Smi::Value(static_cast<LinkedHashMapPtr>(obj)->ptr()->used_data_));
     } else if (cid == kObjectPoolCid) {
       writer_->WriteUnsigned(kLengthData);
-      writer_->WriteUnsigned(static_cast<RawObjectPool*>(obj)->ptr()->length_);
-    } else if (RawObject::IsTypedDataClassId(cid)) {
+      writer_->WriteUnsigned(static_cast<ObjectPoolPtr>(obj)->ptr()->length_);
+    } else if (IsTypedDataClassId(cid)) {
       writer_->WriteUnsigned(kLengthData);
       writer_->WriteUnsigned(
-          Smi::Value(static_cast<RawTypedData*>(obj)->ptr()->length_));
-    } else if (RawObject::IsExternalTypedDataClassId(cid)) {
+          Smi::Value(static_cast<TypedDataPtr>(obj)->ptr()->length_));
+    } else if (IsExternalTypedDataClassId(cid)) {
       writer_->WriteUnsigned(kLengthData);
       writer_->WriteUnsigned(
-          Smi::Value(static_cast<RawExternalTypedData*>(obj)->ptr()->length_));
+          Smi::Value(static_cast<ExternalTypedDataPtr>(obj)->ptr()->length_));
     } else if (cid == kFunctionCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<RawFunction*>(obj)->ptr()->name_);
+      ScrubAndWriteUtf8(static_cast<FunctionPtr>(obj)->ptr()->name_);
     } else if (cid == kCodeCid) {
-      RawObject* owner = static_cast<RawCode*>(obj)->ptr()->owner_;
+      ObjectPtr owner = static_cast<CodePtr>(obj)->ptr()->owner_;
       if (owner->IsFunction()) {
         writer_->WriteUnsigned(kNameData);
-        ScrubAndWriteUtf8(static_cast<RawFunction*>(owner)->ptr()->name_);
+        ScrubAndWriteUtf8(static_cast<FunctionPtr>(owner)->ptr()->name_);
       } else if (owner->IsClass()) {
         writer_->WriteUnsigned(kNameData);
-        ScrubAndWriteUtf8(static_cast<RawClass*>(owner)->ptr()->name_);
+        ScrubAndWriteUtf8(static_cast<ClassPtr>(owner)->ptr()->name_);
       } else {
         writer_->WriteUnsigned(kNoData);
       }
     } else if (cid == kFieldCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<RawField*>(obj)->ptr()->name_);
+      ScrubAndWriteUtf8(static_cast<FieldPtr>(obj)->ptr()->name_);
     } else if (cid == kClassCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<RawClass*>(obj)->ptr()->name_);
+      ScrubAndWriteUtf8(static_cast<ClassPtr>(obj)->ptr()->name_);
     } else if (cid == kLibraryCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<RawLibrary*>(obj)->ptr()->url_);
+      ScrubAndWriteUtf8(static_cast<LibraryPtr>(obj)->ptr()->url_);
     } else if (cid == kScriptCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<RawScript*>(obj)->ptr()->url_);
+      ScrubAndWriteUtf8(static_cast<ScriptPtr>(obj)->ptr()->url_);
     } else {
       writer_->WriteUnsigned(kNoData);
     }
 
     DoCount();
-    obj->VisitPointersPrecise(isolate_, this);
+    obj->ptr()->VisitPointersPrecise(isolate_, this);
     DoWrite();
-    obj->VisitPointersPrecise(isolate_, this);
+    obj->ptr()->VisitPointersPrecise(isolate_, this);
   }
 
-  void ScrubAndWriteUtf8(RawString* str) {
+  void ScrubAndWriteUtf8(StringPtr str) {
     if (str == String::null()) {
       writer_->WriteUtf8("null");
     } else {
@@ -958,10 +956,10 @@
     writer_->WriteUnsigned(counted_);
   }
 
-  void VisitPointers(RawObject** from, RawObject** to) {
+  void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
     if (writing_) {
-      for (RawObject** ptr = from; ptr <= to; ptr++) {
-        RawObject* target = *ptr;
+      for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
+        ObjectPtr target = *ptr;
         written_++;
         total_++;
         writer_->WriteUnsigned(writer_->GetObjectId(target));
@@ -1223,9 +1221,9 @@
   memset(old_external_size_.get(), 0, class_count * sizeof(intptr_t));
 }
 
-void CountObjectsVisitor::VisitObject(RawObject* obj) {
+void CountObjectsVisitor::VisitObject(ObjectPtr obj) {
   intptr_t cid = obj->GetClassId();
-  intptr_t size = obj->HeapSize();
+  intptr_t size = obj->ptr()->HeapSize();
   if (obj->IsNewObject()) {
     new_count_[cid] += 1;
     new_size_[cid] += size;
@@ -1238,7 +1236,7 @@
 void CountObjectsVisitor::VisitHandle(uword addr) {
   FinalizablePersistentHandle* handle =
       reinterpret_cast<FinalizablePersistentHandle*>(addr);
-  RawObject* obj = handle->raw();
+  ObjectPtr obj = handle->raw();
   if (!obj->IsHeapObject()) {
     return;
   }
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index f05af3d..9ce858e 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -15,7 +15,6 @@
 
 class Array;
 class Object;
-class RawObject;
 class CountingPage;
 
 #if !defined(PRODUCT)
@@ -32,7 +31,7 @@
   class StackIterator {
    public:
     // The object this iterator currently points to.
-    RawObject* Get() const;
+    ObjectPtr Get() const;
     // Returns false if there is no parent.
     bool MoveToParent();
     // Offset into parent for the pointer to current object. -1 if no parent.
@@ -177,8 +176,8 @@
     WriteBytes(value, len);
   }
 
-  void AssignObjectId(RawObject* obj);
-  intptr_t GetObjectId(RawObject* obj) const;
+  void AssignObjectId(ObjectPtr obj);
+  intptr_t GetObjectId(ObjectPtr obj) const;
   void ClearObjectIds();
   void CountReferences(intptr_t count);
   void CountExternalProperty();
@@ -190,8 +189,8 @@
   static const intptr_t kPreferredChunkSize = MB;
 
   void SetupCountingPages();
-  bool OnImagePage(RawObject* obj) const;
-  CountingPage* FindCountingPage(RawObject* obj) const;
+  bool OnImagePage(ObjectPtr obj) const;
+  CountingPage* FindCountingPage(ObjectPtr obj) const;
 
   void EnsureAvailable(intptr_t needed);
   void Flush(bool last = false);
@@ -222,7 +221,7 @@
   CountObjectsVisitor(Thread* thread, intptr_t class_count);
   ~CountObjectsVisitor() {}
 
-  void VisitObject(RawObject* obj);
+  void VisitObject(ObjectPtr obj);
   void VisitHandle(uword addr);
 
   std::unique_ptr<intptr_t[]> new_count_;
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index b371eb6..a072650 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -14,18 +14,18 @@
  public:
   // Records the number of objects and total size visited, excluding 'skip'
   // and any objects only reachable through 'skip'.
-  CounterVisitor(RawObject* skip, RawObject* expected_parent)
+  CounterVisitor(ObjectPtr skip, ObjectPtr expected_parent)
       : count_(0), size_(0), skip_(skip), expected_parent_(expected_parent) {}
 
   virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
-    RawObject* obj = it->Get();
+    ObjectPtr obj = it->Get();
     if (obj == skip_) {
       EXPECT(it->MoveToParent());
       EXPECT_EQ(expected_parent_, it->Get());
       return kBacktrack;
     }
     ++count_;
-    size_ += obj->HeapSize();
+    size_ += obj->ptr()->HeapSize();
     return kProceed;
   }
 
@@ -35,8 +35,8 @@
  private:
   int count_;
   intptr_t size_;
-  RawObject* skip_;
-  RawObject* expected_parent_;
+  ObjectPtr skip_;
+  ObjectPtr expected_parent_;
 };
 
 ISOLATE_UNIT_TEST_CASE(ObjectGraph) {
@@ -54,14 +54,14 @@
   b.SetAt(0, c);
   b.SetAt(1, d);
   a.SetAt(11, d);
-  intptr_t a_size = a.raw()->HeapSize();
-  intptr_t b_size = b.raw()->HeapSize();
-  intptr_t c_size = c.raw()->HeapSize();
-  intptr_t d_size = d.raw()->HeapSize();
+  intptr_t a_size = a.raw()->ptr()->HeapSize();
+  intptr_t b_size = b.raw()->ptr()->HeapSize();
+  intptr_t c_size = c.raw()->ptr()->HeapSize();
+  intptr_t d_size = d.raw()->ptr()->HeapSize();
   {
     // No more allocation; raw pointers ahead.
     SafepointOperationScope safepoint(thread);
-    RawObject* b_raw = b.raw();
+    ObjectPtr b_raw = b.raw();
     // Clear handles to cut unintended retained paths.
     b = Array::null();
     c = Array::null();
diff --git a/runtime/vm/object_id_ring.cc b/runtime/vm/object_id_ring.cc
index 2652db3..1de2e54 100644
--- a/runtime/vm/object_id_ring.cc
+++ b/runtime/vm/object_id_ring.cc
@@ -18,7 +18,7 @@
   table_ = NULL;
 }
 
-int32_t ObjectIdRing::GetIdForObject(RawObject* object, IdPolicy policy) {
+int32_t ObjectIdRing::GetIdForObject(ObjectPtr object, IdPolicy policy) {
   // We do not allow inserting null because null is how we detect as entry was
   // reclaimed by the GC.
   ASSERT(object != Object::null());
@@ -34,7 +34,7 @@
   return AllocateNewId(object);
 }
 
-int32_t ObjectIdRing::FindExistingIdForObject(RawObject* raw_obj) {
+int32_t ObjectIdRing::FindExistingIdForObject(ObjectPtr raw_obj) {
   for (int32_t i = 0; i < capacity_; i++) {
     if (table_[i] == raw_obj) {
       return IdOfIndex(i);
@@ -43,7 +43,7 @@
   return kInvalidId;
 }
 
-RawObject* ObjectIdRing::GetObjectForId(int32_t id, LookupResult* kind) {
+ObjectPtr ObjectIdRing::GetObjectForId(int32_t id, LookupResult* kind) {
   int32_t index = IndexOfId(id);
   if (index == kInvalidId) {
     *kind = kExpired;
@@ -101,7 +101,7 @@
   if (table_ != NULL) {
     free(table_);
   }
-  table_ = reinterpret_cast<RawObject**>(calloc(capacity_, kWordSize));
+  table_ = reinterpret_cast<ObjectPtr*>(calloc(capacity_, kWordSize));
   for (int32_t i = 0; i < capacity_; i++) {
     table_[i] = Object::null();
   }
@@ -120,7 +120,7 @@
   return r;
 }
 
-int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
+int32_t ObjectIdRing::AllocateNewId(ObjectPtr raw_obj) {
   ASSERT(raw_obj->IsHeapObject());
   int32_t id = NextSerial();
   ASSERT(id != kInvalidId);
diff --git a/runtime/vm/object_id_ring.h b/runtime/vm/object_id_ring.h
index 2fe8090..63fe1a7 100644
--- a/runtime/vm/object_id_ring.h
+++ b/runtime/vm/object_id_ring.h
@@ -6,11 +6,11 @@
 #define RUNTIME_VM_OBJECT_ID_RING_H_
 
 #include "platform/globals.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
 // Forward declarations.
-class RawObject;
 class ObjectPointerVisitor;
 class JSONStream;
 
@@ -44,10 +44,10 @@
 
   // Adds the argument to the ring and returns its id. Note we do not allow
   // adding Object::null().
-  int32_t GetIdForObject(RawObject* raw_obj, IdPolicy policy = kAllocateId);
+  int32_t GetIdForObject(ObjectPtr raw_obj, IdPolicy policy = kAllocateId);
 
   // Returns Object::null() when the result is not kValid.
-  RawObject* GetObjectForId(int32_t id, LookupResult* kind);
+  ObjectPtr GetObjectForId(int32_t id, LookupResult* kind);
 
   void VisitPointers(ObjectPointerVisitor* visitor);
 
@@ -57,19 +57,19 @@
   friend class ObjectIdRingTestHelper;
 
   void SetCapacityAndMaxSerial(int32_t capacity, int32_t max_serial);
-  int32_t FindExistingIdForObject(RawObject* raw_obj);
+  int32_t FindExistingIdForObject(ObjectPtr raw_obj);
 
-  RawObject** table_;
+  ObjectPtr* table_;
   int32_t max_serial_;
   int32_t capacity_;
   int32_t serial_num_;
   bool wrapped_;
 
-  RawObject** table() { return table_; }
+  ObjectPtr* table() { return table_; }
   int32_t table_size() { return capacity_; }
 
   int32_t NextSerial();
-  int32_t AllocateNewId(RawObject* object);
+  int32_t AllocateNewId(ObjectPtr object);
   int32_t IndexOfId(int32_t id);
   int32_t IdOfIndex(int32_t index);
   bool IsValidContiguous(int32_t id);
diff --git a/runtime/vm/object_id_ring_test.cc b/runtime/vm/object_id_ring_test.cc
index 1b70a92..07fa8ea 100644
--- a/runtime/vm/object_id_ring_test.cc
+++ b/runtime/vm/object_id_ring_test.cc
@@ -38,11 +38,11 @@
     EXPECT_EQ(-1, ring->IdOfIndex(index));
   }
 
-  static RawObject* MakeString(const char* s) {
+  static ObjectPtr MakeString(const char* s) {
     return Symbols::New(Thread::Current(), s);
   }
 
-  static void ExpectString(RawObject* obj, const char* s) {
+  static void ExpectString(ObjectPtr obj, const char* s) {
     String& str = String::Handle();
     str ^= obj;
     EXPECT(str.Equals(s));
@@ -142,7 +142,7 @@
 
   {
     TransitionNativeToVM to_vm(thread);
-    RawObject* raw_obj = Api::UnwrapHandle(result);
+    ObjectPtr raw_obj = Api::UnwrapHandle(result);
     // Located in new heap.
     EXPECT(raw_obj->IsNewObject());
     EXPECT_NE(Object::null(), raw_obj);
@@ -157,29 +157,29 @@
     // Get id 0 again.
     EXPECT_EQ(raw_obj_id1,
               ring->GetIdForObject(raw_obj, ObjectIdRing::kReuseId));
-    RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
+    ObjectPtr raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
-    RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
+    ObjectPtr raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
     EXPECT_NE(Object::null(), raw_obj1);
     EXPECT_NE(Object::null(), raw_obj2);
-    EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1));
-    EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2));
+    EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj1));
+    EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj2));
     // Force a scavenge.
     GCTestHelper::CollectNewSpace();
-    RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
+    ObjectPtr raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
-    RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
+    ObjectPtr raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
     EXPECT_NE(Object::null(), raw_object_moved1);
     EXPECT_NE(Object::null(), raw_object_moved2);
-    EXPECT_EQ(RawObject::ToAddr(raw_object_moved1),
-              RawObject::ToAddr(raw_object_moved2));
+    EXPECT_EQ(ObjectLayout::ToAddr(raw_object_moved1),
+              ObjectLayout::ToAddr(raw_object_moved2));
     // Test that objects have moved.
-    EXPECT_NE(RawObject::ToAddr(raw_obj1),
-              RawObject::ToAddr(raw_object_moved1));
-    EXPECT_NE(RawObject::ToAddr(raw_obj2),
-              RawObject::ToAddr(raw_object_moved2));
+    EXPECT_NE(ObjectLayout::ToAddr(raw_obj1),
+              ObjectLayout::ToAddr(raw_object_moved1));
+    EXPECT_NE(ObjectLayout::ToAddr(raw_obj2),
+              ObjectLayout::ToAddr(raw_object_moved2));
     // Test that we still point at the same list.
     moved_handle = Api::NewHandle(thread, raw_object_moved1);
     // Test id reuse.
@@ -207,7 +207,7 @@
     EXPECT(!str.IsNull());
     EXPECT_EQ(3, str.Length());
 
-    RawObject* raw_obj = Object::RawCast(str.raw());
+    ObjectPtr raw_obj = Object::RawCast(str.raw());
     // Verify that it is located in old heap.
     EXPECT(raw_obj->IsOldObject());
     EXPECT_NE(Object::null(), raw_obj);
@@ -215,24 +215,24 @@
     EXPECT_EQ(0, raw_obj_id1);
     raw_obj_id2 = ring->GetIdForObject(raw_obj);
     EXPECT_EQ(1, raw_obj_id2);
-    RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
+    ObjectPtr raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
-    RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
+    ObjectPtr raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
     EXPECT_NE(Object::null(), raw_obj1);
     EXPECT_NE(Object::null(), raw_obj2);
-    EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1));
-    EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2));
+    EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj1));
+    EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj2));
     // Exit scope. Freeing String handle.
   }
   // Force a GC. No reference exist to the old string anymore. It should be
   // collected and the object id ring will now return the null object for
   // those ids.
   GCTestHelper::CollectOldSpace();
-  RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
+  ObjectPtr raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
   EXPECT_EQ(ObjectIdRing::kCollected, kind);
   EXPECT_EQ(Object::null(), raw_object_moved1);
-  RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
+  ObjectPtr raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
   EXPECT_EQ(ObjectIdRing::kCollected, kind);
   EXPECT_EQ(Object::null(), raw_object_moved2);
 }
@@ -247,7 +247,7 @@
   String& obj = String::Handle(String::New("I will expire"));
   intptr_t obj_id = ring->GetIdForObject(obj.raw());
   ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
-  RawObject* obj_lookup = ring->GetObjectForId(obj_id, &kind);
+  ObjectPtr obj_lookup = ring->GetObjectForId(obj_id, &kind);
   EXPECT_EQ(ObjectIdRing::kValid, kind);
   EXPECT_EQ(obj.raw(), obj_lookup);
 
@@ -257,7 +257,7 @@
     new_obj = String::New("Bump");
     intptr_t new_obj_id = ring->GetIdForObject(new_obj.raw());
     ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
-    RawObject* new_obj_lookup = ring->GetObjectForId(new_obj_id, &kind);
+    ObjectPtr new_obj_lookup = ring->GetObjectForId(new_obj_id, &kind);
     EXPECT_EQ(ObjectIdRing::kValid, kind);
     EXPECT_EQ(new_obj.raw(), new_obj_lookup);
   }
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index b3c70c1..669e441 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -73,9 +73,8 @@
   const int32_t* offsets = code.raw_ptr()->data();
   for (intptr_t i = 0; i < offsets_length; i++) {
     int32_t offset = offsets[i];
-    RawObject** object_ptr =
-        reinterpret_cast<RawObject**>(base_address + offset);
-    RawObject* raw_object = *object_ptr;
+    ObjectPtr* object_ptr = reinterpret_cast<ObjectPtr*>(base_address + offset);
+    ObjectPtr raw_object = *object_ptr;
     if (!raw_object->IsHeapObject()) {
       continue;
     }
@@ -127,7 +126,7 @@
   }
   const Function& function = Function::Cast(object_);
 
-  if (function.kind() == RawFunction::kIrregexpFunction) {
+  if (function.kind() == FunctionLayout::kIrregexpFunction) {
     // Regex matchers do not support breakpoints or stepping, and they only call
     // core library functions that cannot change due to reload. As a performance
     // optimization, avoid this matching of ICData to PCs for these functions'
@@ -143,7 +142,7 @@
     // calls.
 #if defined(DEBUG)
     descriptors_ = code.pc_descriptors();
-    PcDescriptors::Iterator iter(descriptors_, RawPcDescriptors::kIcCall);
+    PcDescriptors::Iterator iter(descriptors_, PcDescriptorsLayout::kIcCall);
     while (iter.MoveNext()) {
       FATAL1("%s has IC calls but no ic_data_array\n", object_.ToCString());
     }
@@ -152,7 +151,7 @@
   }
 
   descriptors_ = code.pc_descriptors();
-  PcDescriptors::Iterator iter(descriptors_, RawPcDescriptors::kIcCall);
+  PcDescriptors::Iterator iter(descriptors_, PcDescriptorsLayout::kIcCall);
   while (iter.MoveNext()) {
     uword pc = code.PayloadStart() + iter.PcOffset();
     CodePatcher::GetInstanceCallAt(pc, code, &object_);
@@ -567,7 +566,7 @@
   EnumClassConflict(Zone* zone, const Class& from, const Class& to)
       : ClassReasonForCancelling(zone, from, to) {}
 
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted(
         from_.is_enum_class()
             ? "Enum class cannot be redefined to be a non-enum class: %s"
@@ -581,7 +580,7 @@
   TypedefClassConflict(Zone* zone, const Class& from, const Class& to)
       : ClassReasonForCancelling(zone, from, to) {}
 
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted(
         from_.IsTypedefClass()
             ? "Typedef class cannot be redefined to be a non-typedef class: %s"
@@ -601,9 +600,9 @@
  private:
   const Error& error_;
 
-  RawError* ToError() { return error_.raw(); }
+  ErrorPtr ToError() { return error_.raw(); }
 
-  RawString* ToString() { return String::New(error_.ToErrorCString()); }
+  StringPtr ToString() { return String::New(error_.ToErrorCString()); }
 };
 
 class ConstToNonConstClass : public ClassReasonForCancelling {
@@ -612,7 +611,7 @@
       : ClassReasonForCancelling(zone, from, to) {}
 
  private:
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted("Const class cannot become non-const: %s",
                                 from_.ToCString());
   }
@@ -624,7 +623,7 @@
       : ClassReasonForCancelling(zone, from, to) {}
 
  private:
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted("Const class cannot remove fields: %s",
                                 from_.ToCString());
   }
@@ -636,7 +635,7 @@
       : ClassReasonForCancelling(zone, from, to) {}
 
  private:
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted("Number of native fields changed in %s",
                                 from_.ToCString());
   }
@@ -647,7 +646,7 @@
   TypeParametersChanged(Zone* zone, const Class& from, const Class& to)
       : ClassReasonForCancelling(zone, from, to) {}
 
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted(
         "Limitation: type parameters have changed for %s", from_.ToCString());
   }
@@ -669,7 +668,7 @@
       : ClassReasonForCancelling(zone, from, to) {}
 
  private:
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted(
         "Original class ('%s') is prefinalized and replacement class "
         "('%s') is not ",
@@ -683,7 +682,7 @@
       : ClassReasonForCancelling(zone, from, to) {}
 
  private:
-  RawString* ToString() {
+  StringPtr ToString() {
     return String::NewFormatted("Instance size mismatch between '%s' (%" Pd
                                 ") and replacement "
                                 "'%s' ( %" Pd ")",
@@ -848,7 +847,8 @@
   // Make sure the declaration types argument count matches for the two classes.
   // ex. class A<int,B> {} cannot be replace with class A<B> {}.
   auto group_context = context->group_reload_context();
-  auto shared_class_table = group_context->isolate_group()->class_table();
+  auto shared_class_table =
+      group_context->isolate_group()->shared_class_table();
   if (NumTypeArguments() != replacement.NumTypeArguments()) {
     group_context->AddReasonForCancelling(
         new (context->zone())
@@ -939,7 +939,7 @@
 
     if (rule == ICData::kStatic) {
       ASSERT(old_target_.is_static() ||
-             old_target_.kind() == RawFunction::kConstructor);
+             old_target_.kind() == FunctionLayout::kConstructor);
       // This can be incorrect if the call site was an unqualified invocation.
       new_cls_ = old_target_.Owner();
       new_target_ = new_cls_.LookupFunction(name_);
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 638876c..5b261ca 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -43,7 +43,7 @@
   }
   if (!ref) {
     if (raw()->IsHeapObject()) {
-      jsobj->AddProperty("size", raw()->HeapSize());
+      jsobj->AddProperty("size", raw()->ptr()->HeapSize());
     } else {
       jsobj->AddProperty("size", (intptr_t)0);
     }
@@ -261,7 +261,7 @@
   }
   // Oddball functions (not known to their owner) fall back to use the object
   // id ring. Current known examples are signature functions of closures
-  // and stubs like 'megamorphic_miss'.
+  // and stubs like 'megamorphic_call_miss'.
   jsobj.AddServiceId(f);
 }
 
@@ -326,10 +326,10 @@
   jsobj.AddProperty("_optimizedCallSiteCount", optimized_call_site_count());
   jsobj.AddProperty("_deoptimizations",
                     static_cast<intptr_t>(deoptimization_counter()));
-  if ((kind() == RawFunction::kImplicitGetter) ||
-      (kind() == RawFunction::kImplicitSetter) ||
-      (kind() == RawFunction::kImplicitStaticGetter) ||
-      (kind() == RawFunction::kFieldInitializer)) {
+  if ((kind() == FunctionLayout::kImplicitGetter) ||
+      (kind() == FunctionLayout::kImplicitSetter) ||
+      (kind() == FunctionLayout::kImplicitStaticGetter) ||
+      (kind() == FunctionLayout::kFieldInitializer)) {
     const Field& field = Field::Handle(accessor_field());
     if (!field.IsNull()) {
       jsobj.AddProperty("_field", field);
@@ -619,9 +619,9 @@
       entry = entries.GetNext();
       if (entry.IsFunction()) {
         const Function& func = Function::Cast(entry);
-        if (func.kind() == RawFunction::kRegularFunction ||
-            func.kind() == RawFunction::kGetterFunction ||
-            func.kind() == RawFunction::kSetterFunction) {
+        if (func.kind() == FunctionLayout::kRegularFunction ||
+            func.kind() == FunctionLayout::kGetterFunction ||
+            func.kind() == FunctionLayout::kSetterFunction) {
           jsarr.AddValue(func);
         }
       }
@@ -731,7 +731,7 @@
     return;
   }
   JSONArray members(jsobj, "members");
-  Iterator iter(*this, RawPcDescriptors::kAnyKind);
+  Iterator iter(*this, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     JSONObject descriptor(&members);
     descriptor.AddPropertyF("pcOffset", "%" Px "", iter.PcOffset());
@@ -768,7 +768,7 @@
   JSONArray members(&jsobj, "members");
   String& var_name = String::Handle();
   for (intptr_t i = 0; i < Length(); i++) {
-    RawLocalVarDescriptors::VarInfo info;
+    LocalVarDescriptorsLayout::VarInfo info;
     var_name = GetName(i);
     GetInfo(i, &info);
     JSONObject var(&members);
@@ -824,6 +824,10 @@
   jsobj.AddProperty("_target", Code::Handle(target()));
 }
 
+void CallSiteData::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  UNREACHABLE();
+}
+
 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddCommonObjectProperties(&jsobj, "Object", ref);
diff --git a/runtime/vm/object_set.h b/runtime/vm/object_set.h
index f4f0254..6d8e1ff 100644
--- a/runtime/vm/object_set.h
+++ b/runtime/vm/object_set.h
@@ -63,8 +63,8 @@
     sorted_ = true;
   }
 
-  bool Contains(RawObject* raw_obj) const {
-    uword raw_addr = RawObject::ToAddr(raw_obj);
+  bool Contains(ObjectPtr raw_obj) const {
+    uword raw_addr = ObjectLayout::ToAddr(raw_obj);
     ObjectSetRegion* region;
     if (FindRegion(raw_addr, &region)) {
       return region->ContainsObject(raw_addr);
@@ -72,8 +72,8 @@
     return false;
   }
 
-  void Add(RawObject* raw_obj) {
-    uword raw_addr = RawObject::ToAddr(raw_obj);
+  void Add(ObjectPtr raw_obj) {
+    uword raw_addr = ObjectLayout::ToAddr(raw_obj);
     ObjectSetRegion* region;
     if (FindRegion(raw_addr, &region)) {
       return region->AddObject(raw_addr);
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index b9fbe72..c14a52a 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -10,17 +10,103 @@
 #include "vm/object.h"
 #include "vm/raw_object.h"
 #include "vm/resolver.h"
+#include "vm/stub_code.h"
 #include "vm/symbols.h"
 #include "vm/visitor.h"
 
 namespace dart {
 
+IsolateObjectStore::IsolateObjectStore(ObjectStore* object_store)
+    : object_store_(object_store) {}
+
+IsolateObjectStore::~IsolateObjectStore() {}
+
+void IsolateObjectStore::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  ASSERT(visitor != NULL);
+  visitor->set_gc_root_type("isolate_object store");
+  visitor->VisitPointers(from(), to());
+  visitor->clear_gc_root_type();
+}
+
+void IsolateObjectStore::Init() {
+#define INIT_FIELD(Type, name) name##_ = Type::null();
+  ISOLATE_OBJECT_STORE_FIELD_LIST(INIT_FIELD, INIT_FIELD)
+#undef INIT_FIELD
+
+  for (ObjectPtr* current = from(); current <= to(); current++) {
+    ASSERT(*current == Object::null());
+  }
+}
+
+#ifndef PRODUCT
+void IsolateObjectStore::PrintToJSONObject(JSONObject* jsobj) {
+  jsobj->AddProperty("type", "_IsolateObjectStore");
+
+  {
+    JSONObject fields(jsobj, "fields");
+    Object& value = Object::Handle();
+#define PRINT_OBJECT_STORE_FIELD(type, name)                                   \
+  value = name##_;                                                             \
+  fields.AddProperty(#name "_", value);
+    ISOLATE_OBJECT_STORE_FIELD_LIST(PRINT_OBJECT_STORE_FIELD,
+                                    PRINT_OBJECT_STORE_FIELD);
+#undef PRINT_OBJECT_STORE_FIELD
+  }
+}
+#endif  // !PRODUCT
+
+static UnhandledExceptionPtr CreatePreallocatedUnandledException(
+    Zone* zone,
+    const Object& out_of_memory) {
+  // Allocate pre-allocated unhandled exception object initialized with the
+  // pre-allocated OutOfMemoryError.
+  const UnhandledException& unhandled_exception =
+      UnhandledException::Handle(UnhandledException::New(
+          Instance::Cast(out_of_memory), StackTrace::Handle(zone)));
+  return unhandled_exception.raw();
+}
+
+static StackTracePtr CreatePreallocatedStackTrace(Zone* zone) {
+  const Array& code_array = Array::Handle(
+      zone, Array::New(StackTrace::kPreallocatedStackdepth, Heap::kOld));
+  const Array& pc_offset_array = Array::Handle(
+      zone, Array::New(StackTrace::kPreallocatedStackdepth, Heap::kOld));
+  const StackTrace& stack_trace =
+      StackTrace::Handle(zone, StackTrace::New(code_array, pc_offset_array));
+  // Expansion of inlined functions requires additional memory at run time,
+  // avoid it.
+  stack_trace.set_expand_inlined(false);
+  return stack_trace.raw();
+}
+
+ErrorPtr IsolateObjectStore::PreallocateObjects() {
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
+  ASSERT(isolate != NULL && isolate->isolate_object_store() == this);
+  ASSERT(preallocated_stack_trace() == StackTrace::null());
+  resume_capabilities_ = GrowableObjectArray::New();
+  exit_listeners_ = GrowableObjectArray::New();
+  error_listeners_ = GrowableObjectArray::New();
+
+  // Allocate pre-allocated unhandled exception object initialized with the
+  // pre-allocated OutOfMemoryError.
+  const Object& out_of_memory =
+      Object::Handle(zone, object_store_->out_of_memory());
+  set_preallocated_unhandled_exception(UnhandledException::Handle(
+      CreatePreallocatedUnandledException(zone, out_of_memory)));
+  set_preallocated_stack_trace(
+      StackTrace::Handle(CreatePreallocatedStackTrace(zone)));
+
+  return Error::null();
+}
+
 ObjectStore::ObjectStore() {
 #define INIT_FIELD(Type, name) name##_ = Type::null();
   OBJECT_STORE_FIELD_LIST(INIT_FIELD, INIT_FIELD)
 #undef INIT_FIELD
 
-  for (RawObject** current = from(); current <= to(); current++) {
+  for (ObjectPtr* current = from(); current <= to(); current++) {
     ASSERT(*current == Object::null());
   }
 }
@@ -34,10 +120,10 @@
   visitor->clear_gc_root_type();
 }
 
-void ObjectStore::Init(Isolate* isolate) {
-  ASSERT(isolate->object_store() == NULL);
-  ObjectStore* store = new ObjectStore();
-  isolate->set_object_store(store);
+void ObjectStore::InitStubs() {
+#define DO(member, name) set_##member(StubCode::name());
+  OBJECT_STORE_STUB_CODE_LIST(DO)
+#undef DO
 }
 
 #ifndef PRODUCT
@@ -56,31 +142,31 @@
 }
 #endif  // !PRODUCT
 
-static RawInstance* AllocateObjectByClassName(const Library& library,
-                                              const String& class_name) {
+static InstancePtr AllocateObjectByClassName(const Library& library,
+                                             const String& class_name) {
   const Class& cls = Class::Handle(library.LookupClassAllowPrivate(class_name));
   ASSERT(!cls.IsNull());
   return Instance::New(cls);
 }
 
-RawError* ObjectStore::PreallocateObjects() {
+ErrorPtr ObjectStore::PreallocateObjects() {
   Thread* thread = Thread::Current();
+  IsolateGroup* isolate_group = thread->isolate_group();
   Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-  ASSERT(isolate != NULL && isolate->object_store() == this);
+  // Either we are the object store on isolate group, or isolate group has no
+  // object store and we are the object store on the isolate.
+  ASSERT(isolate_group != NULL && (isolate_group->object_store() == this ||
+                                   (isolate_group->object_store() == nullptr &&
+                                    isolate->object_store() == this)));
+
   if (this->stack_overflow() != Instance::null()) {
     ASSERT(this->out_of_memory() != Instance::null());
-    ASSERT(this->preallocated_stack_trace() != StackTrace::null());
     return Error::null();
   }
   ASSERT(this->stack_overflow() == Instance::null());
   ASSERT(this->out_of_memory() == Instance::null());
-  ASSERT(this->preallocated_stack_trace() == StackTrace::null());
 
   this->closure_functions_ = GrowableObjectArray::New();
-  this->resume_capabilities_ = GrowableObjectArray::New();
-  this->exit_listeners_ = GrowableObjectArray::New();
-  this->error_listeners_ = GrowableObjectArray::New();
 
   Object& result = Object::Handle();
   const Library& library = Library::Handle(Library::CoreLibrary());
@@ -97,28 +183,10 @@
   }
   set_out_of_memory(Instance::Cast(result));
 
-  // Allocate pre-allocated unhandled exception object initialized with the
-  // pre-allocated OutOfMemoryError.
-  const UnhandledException& unhandled_exception =
-      UnhandledException::Handle(UnhandledException::New(
-          Instance::Cast(result), StackTrace::Handle(zone)));
-  set_preallocated_unhandled_exception(unhandled_exception);
-
-  const Array& code_array = Array::Handle(
-      zone, Array::New(StackTrace::kPreallocatedStackdepth, Heap::kOld));
-  const Array& pc_offset_array = Array::Handle(
-      zone, Array::New(StackTrace::kPreallocatedStackdepth, Heap::kOld));
-  const StackTrace& stack_trace =
-      StackTrace::Handle(zone, StackTrace::New(code_array, pc_offset_array));
-  // Expansion of inlined functions requires additional memory at run time,
-  // avoid it.
-  stack_trace.set_expand_inlined(false);
-  set_preallocated_stack_trace(stack_trace);
-
   return Error::null();
 }
 
-RawFunction* ObjectStore::PrivateObjectLookup(const String& name) {
+FunctionPtr ObjectStore::PrivateObjectLookup(const String& name) {
   const Library& core_lib = Library::Handle(core_library());
   const String& mangled = String::ZoneHandle(core_lib.PrivateName(name));
   const Class& cls = Class::Handle(object_class());
@@ -265,10 +333,4 @@
 #endif
 }
 
-void ObjectStore::PostLoad() {
-  resume_capabilities_ = GrowableObjectArray::New();
-  exit_listeners_ = GrowableObjectArray::New();
-  error_listeners_ = GrowableObjectArray::New();
-}
-
 }  // namespace dart
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 04e6e70..b28f776 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -34,6 +34,9 @@
 // TODO(liama): Once NNBD is enabled, *_type will be deleted and all uses will
 // be replaced with *_type_non_nullable. Later, once we drop support for opted
 // out code, *_type_legacy will be deleted.
+//
+// R_ - needs getter only
+// RW - needs getter and setter
 #define OBJECT_STORE_FIELD_LIST(R_, RW)                                        \
   RW(Class, object_class)                                                      \
   RW(Type, object_type)                                                        \
@@ -42,6 +45,8 @@
   RW(Type, nullable_object_type)                                               \
   RW(Class, null_class)                                                        \
   RW(Type, null_type)                                                          \
+  RW(Class, never_class)                                                       \
+  RW(Type, never_type)                                                         \
   RW(Type, function_type)                                                      \
   RW(Type, legacy_function_type)                                               \
   RW(Type, non_nullable_function_type)                                         \
@@ -53,6 +58,7 @@
   RW(Type, int_type)                                                           \
   RW(Type, legacy_int_type)                                                    \
   RW(Type, non_nullable_int_type)                                              \
+  RW(Type, nullable_int_type)                                                  \
   RW(Class, integer_implementation_class)                                      \
   RW(Type, int64_type)                                                         \
   RW(Class, smi_class)                                                         \
@@ -67,6 +73,7 @@
   RW(Type, double_type)                                                        \
   RW(Type, legacy_double_type)                                                 \
   RW(Type, non_nullable_double_type)                                           \
+  RW(Type, nullable_double_type)                                               \
   RW(Type, float32x4_type)                                                     \
   RW(Type, int32x4_type)                                                       \
   RW(Type, float64x2_type)                                                     \
@@ -147,8 +154,6 @@
   RW(GrowableObjectArray, pending_classes)                                     \
   RW(Instance, stack_overflow)                                                 \
   RW(Instance, out_of_memory)                                                  \
-  RW(UnhandledException, preallocated_unhandled_exception)                     \
-  RW(StackTrace, preallocated_stack_trace)                                     \
   RW(Function, lookup_port_handler)                                            \
   RW(Function, handle_message_function)                                        \
   RW(Function, growable_list_factory)                                          \
@@ -161,7 +166,6 @@
   RW(Function, complete_on_async_return)                                       \
   RW(Class, async_star_stream_controller)                                      \
   RW(Array, bytecode_attributes)                                               \
-  RW(Array, saved_unlinked_calls)                                              \
   RW(GrowableObjectArray, llvm_constant_pool)                                  \
   RW(GrowableObjectArray, llvm_function_pool)                                  \
   RW(Array, llvm_constant_hash_table)                                          \
@@ -175,28 +179,155 @@
   RW(Code, null_error_stub_without_fpu_regs_stub)                              \
   RW(Code, null_arg_error_stub_with_fpu_regs_stub)                             \
   RW(Code, null_arg_error_stub_without_fpu_regs_stub)                          \
+  RW(Code, range_error_stub_with_fpu_regs_stub)                                \
+  RW(Code, range_error_stub_without_fpu_regs_stub)                             \
   RW(Code, allocate_mint_with_fpu_regs_stub)                                   \
   RW(Code, allocate_mint_without_fpu_regs_stub)                                \
   RW(Code, stack_overflow_stub_with_fpu_regs_stub)                             \
   RW(Code, stack_overflow_stub_without_fpu_regs_stub)                          \
+  RW(Code, allocate_array_stub)                                                \
+  RW(Code, allocate_context_stub)                                              \
+  RW(Code, allocate_object_stub)                                               \
+  RW(Code, allocate_object_parametrized_stub)                                  \
+  RW(Code, clone_context_stub)                                                 \
   RW(Code, write_barrier_wrappers_stub)                                        \
   RW(Code, array_write_barrier_stub)                                           \
-  R_(Code, megamorphic_miss_code)                                              \
-  R_(Function, megamorphic_miss_function)                                      \
-  R_(GrowableObjectArray, resume_capabilities)                                 \
-  R_(GrowableObjectArray, exit_listeners)                                      \
-  R_(GrowableObjectArray, error_listeners)                                     \
+  RW(Code, throw_stub)                                                         \
+  RW(Code, re_throw_stub)                                                      \
+  RW(Code, assert_boolean_stub)                                                \
+  RW(Code, instance_of_stub)                                                   \
+  RW(Code, init_static_field_stub)                                             \
+  RW(Code, init_instance_field_stub)                                           \
+  RW(Code, init_late_instance_field_stub)                                      \
+  RW(Code, init_late_final_instance_field_stub)                                \
+  RW(Code, call_closure_no_such_method_stub)                                   \
+  RW(Code, default_tts_stub)                                                   \
+  RW(Code, default_nullable_tts_stub)                                          \
+  RW(Code, top_type_tts_stub)                                                  \
+  RW(Code, unreachable_tts_stub)                                               \
+  RW(Code, slow_tts_stub)                                                      \
+  R_(Code, megamorphic_call_miss_code)                                         \
+  R_(Function, megamorphic_call_miss_function)                                 \
   RW(Array, dispatch_table_code_entries)                                       \
   RW(Array, code_order_table)                                                  \
   RW(Array, obfuscation_map)                                                   \
+  RW(Array, saved_initial_field_values)                                        \
   RW(Class, ffi_pointer_class)                                                 \
   RW(Class, ffi_native_type_class)                                             \
   RW(Class, ffi_struct_class)                                                  \
   RW(Object, ffi_as_function_internal)                                         \
+  // Please remember the last entry must be referred in the 'to' function below.
+
+#define OBJECT_STORE_STUB_CODE_LIST(DO)                                        \
+  DO(dispatch_table_null_error_stub, DispatchTableNullError)                   \
+  DO(null_error_stub_with_fpu_regs_stub, NullErrorSharedWithFPURegs)           \
+  DO(null_error_stub_without_fpu_regs_stub, NullErrorSharedWithoutFPURegs)     \
+  DO(null_arg_error_stub_with_fpu_regs_stub, NullArgErrorSharedWithFPURegs)    \
+  DO(null_arg_error_stub_without_fpu_regs_stub,                                \
+     NullArgErrorSharedWithoutFPURegs)                                         \
+  DO(range_error_stub_with_fpu_regs_stub, RangeErrorSharedWithFPURegs)         \
+  DO(range_error_stub_without_fpu_regs_stub, RangeErrorSharedWithoutFPURegs)   \
+  DO(allocate_mint_with_fpu_regs_stub, AllocateMintSharedWithFPURegs)          \
+  DO(allocate_mint_without_fpu_regs_stub, AllocateMintSharedWithoutFPURegs)    \
+  DO(stack_overflow_stub_with_fpu_regs_stub, StackOverflowSharedWithFPURegs)   \
+  DO(stack_overflow_stub_without_fpu_regs_stub,                                \
+     StackOverflowSharedWithoutFPURegs)                                        \
+  DO(allocate_array_stub, AllocateArray)                                       \
+  DO(allocate_context_stub, AllocateContext)                                   \
+  DO(allocate_object_stub, AllocateObject)                                     \
+  DO(allocate_object_parametrized_stub, AllocateObjectParameterized)           \
+  DO(clone_context_stub, CloneContext)                                         \
+  DO(call_closure_no_such_method_stub, CallClosureNoSuchMethod)                \
+  DO(default_tts_stub, DefaultTypeTest)                                        \
+  DO(default_nullable_tts_stub, DefaultNullableTypeTest)                       \
+  DO(top_type_tts_stub, TopTypeTypeTest)                                       \
+  DO(unreachable_tts_stub, UnreachableTypeTest)                                \
+  DO(slow_tts_stub, SlowTypeTest)                                              \
+  DO(write_barrier_wrappers_stub, WriteBarrierWrappers)                        \
+  DO(array_write_barrier_stub, ArrayWriteBarrier)                              \
+  DO(throw_stub, Throw)                                                        \
+  DO(re_throw_stub, ReThrow)                                                   \
+  DO(assert_boolean_stub, AssertBoolean)                                       \
+  DO(init_static_field_stub, InitStaticField)                                  \
+  DO(init_instance_field_stub, InitInstanceField)                              \
+  DO(init_late_instance_field_stub, InitLateInstanceField)                     \
+  DO(init_late_final_instance_field_stub, InitLateFinalInstanceField)          \
+  DO(instance_of_stub, InstanceOf)
+
+#define ISOLATE_OBJECT_STORE_FIELD_LIST(R_, RW)                                \
+  RW(UnhandledException, preallocated_unhandled_exception)                     \
+  RW(StackTrace, preallocated_stack_trace)                                     \
+  R_(GrowableObjectArray, resume_capabilities)                                 \
+  R_(GrowableObjectArray, exit_listeners)                                      \
+  R_(GrowableObjectArray, error_listeners)
 // Please remember the last entry must be referred in the 'to' function below.
 
-// The object store is a per isolate instance which stores references to
-// objects used by the VM.
+class IsolateObjectStore {
+ public:
+  explicit IsolateObjectStore(ObjectStore* object_store);
+  ~IsolateObjectStore();
+
+#define DECLARE_GETTER(Type, name)                                             \
+  Type##Ptr name() const { return name##_; }                                   \
+  static intptr_t name##_offset() {                                            \
+    return OFFSET_OF(IsolateObjectStore, name##_);                             \
+  }
+
+#define DECLARE_GETTER_AND_SETTER(Type, name)                                  \
+  DECLARE_GETTER(Type, name)                                                   \
+  void set_##name(const Type& value) { name##_ = value.raw(); }
+  ISOLATE_OBJECT_STORE_FIELD_LIST(DECLARE_GETTER, DECLARE_GETTER_AND_SETTER)
+#undef DECLARE_GETTER
+#undef DECLARE_GETTER_AND_SETTER
+
+  // Visit all object pointers.
+  void VisitObjectPointers(ObjectPointerVisitor* visitor);
+
+  // Called to initialize objects required by the vm but which invoke
+  // dart code.  If an error occurs the error object is returned otherwise
+  // a null object is returned.
+  ErrorPtr PreallocateObjects();
+
+  void Init();
+  void PostLoad();
+
+  ObjectStore* object_store() const { return object_store_; }
+  void set_object_store(ObjectStore* object_store) {
+    ASSERT(object_store_ == nullptr);
+    object_store_ = object_store;
+  }
+
+  static intptr_t object_store_offset() {
+    return OFFSET_OF(IsolateObjectStore, object_store_);
+  }
+
+#ifndef PRODUCT
+  void PrintToJSONObject(JSONObject* jsobj);
+#endif
+
+ private:
+  // Finds a core library private method in Object.
+  FunctionPtr PrivateObjectLookup(const String& name);
+
+  ObjectPtr* from() {
+    return reinterpret_cast<ObjectPtr*>(&preallocated_unhandled_exception_);
+  }
+#define DECLARE_OBJECT_STORE_FIELD(type, name) type##Ptr name##_;
+  ISOLATE_OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD,
+                                  DECLARE_OBJECT_STORE_FIELD)
+#undef DECLARE_OBJECT_STORE_FIELD
+  ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&error_listeners_); }
+
+  ObjectStore* object_store_;
+
+  friend class Serializer;
+  friend class Deserializer;
+
+  DISALLOW_COPY_AND_ASSIGN(IsolateObjectStore);
+};
+
+// The object store is a per isolate group instance which stores references to
+// objects used by the VM shared by all isolates in a group.
 class ObjectStore {
  public:
   enum BootstrapLibraryId {
@@ -206,10 +337,11 @@
 #undef MAKE_ID
   };
 
+  ObjectStore();
   ~ObjectStore();
 
 #define DECLARE_GETTER(Type, name)                                             \
-  Raw##Type* name() const { return name##_; }                                  \
+  Type##Ptr name() const { return name##_; }                                   \
   static intptr_t name##_offset() { return OFFSET_OF(ObjectStore, name##_); }
 #define DECLARE_GETTER_AND_SETTER(Type, name)                                  \
   DECLARE_GETTER(Type, name)                                                   \
@@ -218,7 +350,7 @@
 #undef DECLARE_GETTER
 #undef DECLARE_GETTER_AND_SETTER
 
-  RawLibrary* bootstrap_library(BootstrapLibraryId index) {
+  LibraryPtr bootstrap_library(BootstrapLibraryId index) {
     switch (index) {
 #define MAKE_CASE(CamelName, name)                                             \
   case k##CamelName:                                                           \
@@ -247,10 +379,10 @@
     }
   }
 
-  void SetMegamorphicMissHandler(const Code& code, const Function& func) {
+  void SetMegamorphicCallMissHandler(const Code& code, const Function& func) {
     // Hold onto the code so it is traced and not detached from the function.
-    megamorphic_miss_code_ = code.raw();
-    megamorphic_miss_function_ = func.raw();
+    megamorphic_call_miss_code_ = code.raw();
+    megamorphic_call_miss_function_ = func.raw();
   }
 
   // Visit all object pointers.
@@ -259,39 +391,35 @@
   // Called to initialize objects required by the vm but which invoke
   // dart code.  If an error occurs the error object is returned otherwise
   // a null object is returned.
-  RawError* PreallocateObjects();
+  ErrorPtr PreallocateObjects();
 
   void InitKnownObjects();
 
-  void PostLoad();
-
-  static void Init(Isolate* isolate);
+  void InitStubs();
 
 #ifndef PRODUCT
   void PrintToJSONObject(JSONObject* jsobj);
 #endif
 
  private:
-  ObjectStore();
-
   // Finds a core library private method in Object.
-  RawFunction* PrivateObjectLookup(const String& name);
+  FunctionPtr PrivateObjectLookup(const String& name);
 
-  RawObject** from() { return reinterpret_cast<RawObject**>(&object_class_); }
-#define DECLARE_OBJECT_STORE_FIELD(type, name) Raw##type* name##_;
+  ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&object_class_); }
+#define DECLARE_OBJECT_STORE_FIELD(type, name) type##Ptr name##_;
   OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD,
                           DECLARE_OBJECT_STORE_FIELD)
 #undef DECLARE_OBJECT_STORE_FIELD
-  RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ffi_as_function_internal_);
+  ObjectPtr* to() {
+    return reinterpret_cast<ObjectPtr*>(&ffi_as_function_internal_);
   }
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFull:
-        return reinterpret_cast<RawObject**>(&global_object_pool_);
+        return reinterpret_cast<ObjectPtr*>(&global_object_pool_);
       case Snapshot::kFullJIT:
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&megamorphic_miss_function_);
+        return reinterpret_cast<ObjectPtr*>(&megamorphic_call_miss_function_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index eeb5264..67fa779 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -30,8 +30,8 @@
 DECLARE_FLAG(bool, dual_map_code);
 DECLARE_FLAG(bool, write_protect_code);
 
-static RawClass* CreateDummyClass(const String& class_name,
-                                  const Script& script) {
+static ClassPtr CreateDummyClass(const String& class_name,
+                                 const Script& script) {
   const Class& cls = Class::Handle(Class::New(
       Library::Handle(), class_name, script, TokenPosition::kNoSource));
   cls.set_is_synthesized_class();  // Dummy class for testing.
@@ -76,13 +76,13 @@
   String& function_name = String::Handle();
   function_name = Symbols::New(thread, "foo");
   function =
-      Function::New(function_name, RawFunction::kRegularFunction, false, false,
-                    false, false, false, cls, TokenPosition::kMinSource);
+      Function::New(function_name, FunctionLayout::kRegularFunction, false,
+                    false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(0, function);
   function_name = Symbols::New(thread, "bar");
   function =
-      Function::New(function_name, RawFunction::kRegularFunction, false, false,
-                    false, false, false, cls, TokenPosition::kMinSource);
+      Function::New(function_name, FunctionLayout::kRegularFunction, false,
+                    false, false, false, false, cls, TokenPosition::kMinSource);
 
   const int kNumFixedParameters = 2;
   const int kNumOptionalParameters = 3;
@@ -94,25 +94,25 @@
 
   function_name = Symbols::New(thread, "baz");
   function =
-      Function::New(function_name, RawFunction::kRegularFunction, false, false,
-                    false, false, false, cls, TokenPosition::kMinSource);
+      Function::New(function_name, FunctionLayout::kRegularFunction, false,
+                    false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(2, function);
 
   function_name = Symbols::New(thread, "Foo");
   function =
-      Function::New(function_name, RawFunction::kRegularFunction, true, false,
-                    false, false, false, cls, TokenPosition::kMinSource);
+      Function::New(function_name, FunctionLayout::kRegularFunction, true,
+                    false, false, false, false, cls, TokenPosition::kMinSource);
 
   functions.SetAt(3, function);
   function_name = Symbols::New(thread, "Bar");
   function =
-      Function::New(function_name, RawFunction::kRegularFunction, true, false,
-                    false, false, false, cls, TokenPosition::kMinSource);
+      Function::New(function_name, FunctionLayout::kRegularFunction, true,
+                    false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(4, function);
   function_name = Symbols::New(thread, "BaZ");
   function =
-      Function::New(function_name, RawFunction::kRegularFunction, true, false,
-                    false, false, false, cls, TokenPosition::kMinSource);
+      Function::New(function_name, FunctionLayout::kRegularFunction, true,
+                    false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(5, function);
 
   // Setup the functions in the class.
@@ -240,7 +240,7 @@
   one_fields.SetAt(0, field);
   one_field_class.SetFields(one_fields);
   one_field_class.Finalize();
-  intptr_t header_size = sizeof(RawObject);
+  intptr_t header_size = sizeof(ObjectLayout);
   EXPECT_EQ(Utils::RoundUp((header_size + (1 * kWordSize)), kObjectAlignment),
             one_field_class.host_instance_size());
   EXPECT_EQ(header_size, field.HostOffset());
@@ -2060,13 +2060,13 @@
   }
   used_size = Array::InstanceSize(array.Length());
   new_array = Array::MakeFixedLength(array);
-  addr = RawObject::ToAddr(new_array.raw());
-  obj = RawObject::FromAddr(addr);
+  addr = ObjectLayout::ToAddr(new_array.raw());
+  obj = ObjectLayout::FromAddr(addr);
   EXPECT(obj.IsArray());
   new_array ^= obj.raw();
   EXPECT_EQ(2, new_array.Length());
   addr += used_size;
-  obj = RawObject::FromAddr(addr);
+  obj = ObjectLayout::FromAddr(addr);
   EXPECT(obj.IsTypedData());
   left_over_array ^= obj.raw();
   EXPECT_EQ(4 * kWordSize - TypedData::InstanceSize(0),
@@ -2083,13 +2083,13 @@
   }
   used_size = Array::InstanceSize(array.Length());
   new_array = Array::MakeFixedLength(array);
-  addr = RawObject::ToAddr(new_array.raw());
-  obj = RawObject::FromAddr(addr);
+  addr = ObjectLayout::ToAddr(new_array.raw());
+  obj = ObjectLayout::FromAddr(addr);
   EXPECT(obj.IsArray());
   new_array ^= obj.raw();
   EXPECT_EQ(3, new_array.Length());
   addr += used_size;
-  obj = RawObject::FromAddr(addr);
+  obj = ObjectLayout::FromAddr(addr);
   if (TypedData::InstanceSize(0) <= 2 * kWordSize) {
     EXPECT(obj.IsTypedData());
     left_over_array ^= obj.raw();
@@ -2109,13 +2109,13 @@
   }
   used_size = Array::InstanceSize(array.Length());
   new_array = Array::MakeFixedLength(array);
-  addr = RawObject::ToAddr(new_array.raw());
-  obj = RawObject::FromAddr(addr);
+  addr = ObjectLayout::ToAddr(new_array.raw());
+  obj = ObjectLayout::FromAddr(addr);
   EXPECT(obj.IsArray());
   new_array ^= obj.raw();
   EXPECT_EQ(1, new_array.Length());
   addr += used_size;
-  obj = RawObject::FromAddr(addr);
+  obj = ObjectLayout::FromAddr(addr);
   EXPECT(obj.IsTypedData());
   left_over_array ^= obj.raw();
   EXPECT_EQ(8 * kWordSize - TypedData::InstanceSize(0),
@@ -2424,7 +2424,7 @@
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New(thread, "foo_papa"));
   parent =
-      Function::New(parent_name, RawFunction::kRegularFunction, false, false,
+      Function::New(parent_name, FunctionLayout::kRegularFunction, false, false,
                     false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(0, parent);
   cls.SetFunctions(functions);
@@ -2483,11 +2483,11 @@
   EXPECT(!str3.IsOneByteString());
 }
 
-static RawLibrary* CreateDummyLibrary(const String& library_name) {
+static LibraryPtr CreateDummyLibrary(const String& library_name) {
   return Library::New(library_name);
 }
 
-static RawFunction* CreateFunction(const char* name) {
+static FunctionPtr CreateFunction(const char* name) {
   Thread* thread = Thread::Current();
   const String& class_name = String::Handle(Symbols::New(thread, "ownerClass"));
   const String& lib_name = String::Handle(Symbols::New(thread, "ownerLibrary"));
@@ -2497,7 +2497,7 @@
   const Library& owner_library = Library::Handle(CreateDummyLibrary(lib_name));
   owner_class.set_library(owner_library);
   const String& function_name = String::ZoneHandle(Symbols::New(thread, name));
-  return Function::New(function_name, RawFunction::kRegularFunction, true,
+  return Function::New(function_name, FunctionLayout::kRegularFunction, true,
                        false, false, false, false, owner_class,
                        TokenPosition::kMinSource);
 }
@@ -2705,18 +2705,18 @@
   DescriptorList* builder = new DescriptorList(0);
 
   // kind, pc_offset, deopt_id, token_pos, try_index, yield_index
-  builder->AddDescriptor(RawPcDescriptors::kOther, 10, 1, TokenPosition(20), 1,
-                         1);
-  builder->AddDescriptor(RawPcDescriptors::kDeopt, 20, 2, TokenPosition(30), 0,
-                         -1);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 30, 3, TokenPosition(40), 1,
-                         10);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 10, 4, TokenPosition(40), 2,
-                         20);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 10, 5, TokenPosition(80), 3,
-                         30);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 80, 6, TokenPosition(150), 3,
-                         30);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 1, TokenPosition(20),
+                         1, 1);
+  builder->AddDescriptor(PcDescriptorsLayout::kDeopt, 20, 2, TokenPosition(30),
+                         0, -1);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 30, 3, TokenPosition(40),
+                         1, 10);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 4, TokenPosition(40),
+                         2, 20);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 5, TokenPosition(80),
+                         3, 30);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 80, 6, TokenPosition(150),
+                         3, 30);
 
   PcDescriptors& descriptors = PcDescriptors::Handle();
   descriptors ^= builder->FinalizePcDescriptors(0);
@@ -2732,7 +2732,7 @@
 
   // Verify the PcDescriptor entries by accessing them.
   const PcDescriptors& pc_descs = PcDescriptors::Handle(code.pc_descriptors());
-  PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(pc_descs, PcDescriptorsLayout::kAnyKind);
 
   EXPECT_EQ(true, iter.MoveNext());
   EXPECT_EQ(1, iter.YieldIndex());
@@ -2740,12 +2740,12 @@
   EXPECT_EQ(1, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(10), iter.PcOffset());
   EXPECT_EQ(1, iter.DeoptId());
-  EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+  EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
   EXPECT_EQ(-1, iter.YieldIndex());
   EXPECT_EQ(30, iter.TokenPos().value());
-  EXPECT_EQ(RawPcDescriptors::kDeopt, iter.Kind());
+  EXPECT_EQ(PcDescriptorsLayout::kDeopt, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
   EXPECT_EQ(10, iter.YieldIndex());
@@ -2766,7 +2766,7 @@
   EXPECT_EQ(3, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(80), iter.PcOffset());
   EXPECT_EQ(150, iter.TokenPos().value());
-  EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+  EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
 
   EXPECT_EQ(false, iter.MoveNext());
 }
@@ -2775,18 +2775,18 @@
   DescriptorList* builder = new DescriptorList(0);
 
   // kind, pc_offset, deopt_id, token_pos, try_index
-  builder->AddDescriptor(RawPcDescriptors::kOther, 100, 1, TokenPosition(200),
-                         1, 10);
-  builder->AddDescriptor(RawPcDescriptors::kDeopt, 200, 2, TokenPosition(300),
-                         0, -1);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 300, 3, TokenPosition(400),
-                         1, 10);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 100, 4, TokenPosition(0), 2,
-                         20);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 100, 5, TokenPosition(800),
-                         3, 30);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 800, 6, TokenPosition(150),
-                         3, 30);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 1,
+                         TokenPosition(200), 1, 10);
+  builder->AddDescriptor(PcDescriptorsLayout::kDeopt, 200, 2,
+                         TokenPosition(300), 0, -1);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 300, 3,
+                         TokenPosition(400), 1, 10);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 4, TokenPosition(0),
+                         2, 20);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 5,
+                         TokenPosition(800), 3, 30);
+  builder->AddDescriptor(PcDescriptorsLayout::kOther, 800, 6,
+                         TokenPosition(150), 3, 30);
 
   PcDescriptors& descriptors = PcDescriptors::Handle();
   descriptors ^= builder->FinalizePcDescriptors(0);
@@ -2802,7 +2802,7 @@
 
   // Verify the PcDescriptor entries by accessing them.
   const PcDescriptors& pc_descs = PcDescriptors::Handle(code.pc_descriptors());
-  PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(pc_descs, PcDescriptorsLayout::kAnyKind);
 
   EXPECT_EQ(true, iter.MoveNext());
   EXPECT_EQ(10, iter.YieldIndex());
@@ -2810,12 +2810,12 @@
   EXPECT_EQ(1, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(100), iter.PcOffset());
   EXPECT_EQ(1, iter.DeoptId());
-  EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+  EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
   EXPECT_EQ(-1, iter.YieldIndex());
   EXPECT_EQ(300, iter.TokenPos().value());
-  EXPECT_EQ(RawPcDescriptors::kDeopt, iter.Kind());
+  EXPECT_EQ(PcDescriptorsLayout::kDeopt, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
   EXPECT_EQ(10, iter.YieldIndex());
@@ -2836,12 +2836,12 @@
   EXPECT_EQ(3, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(800), iter.PcOffset());
   EXPECT_EQ(150, iter.TokenPos().value());
-  EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+  EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
 
   EXPECT_EQ(false, iter.MoveNext());
 }
 
-static RawClass* CreateTestClass(const char* name) {
+static ClassPtr CreateTestClass(const char* name) {
   const String& class_name =
       String::Handle(Symbols::New(Thread::Current(), name));
   const Class& cls =
@@ -2849,7 +2849,7 @@
   return cls.raw();
 }
 
-static RawField* CreateTestField(const char* name) {
+static FieldPtr CreateTestField(const char* name) {
   const Class& cls = Class::Handle(CreateTestClass("global:"));
   const String& field_name =
       String::Handle(Symbols::New(Thread::Current(), name));
@@ -2881,7 +2881,7 @@
   EXPECT(count == 2);
 }
 
-static RawFunction* GetDummyTarget(const char* name) {
+static FunctionPtr GetDummyTarget(const char* name) {
   const String& function_name =
       String::Handle(Symbols::New(Thread::Current(), name));
   const Class& cls =
@@ -2891,9 +2891,9 @@
   const bool is_abstract = false;
   const bool is_external = false;
   const bool is_native = false;
-  return Function::New(function_name, RawFunction::kRegularFunction, is_static,
-                       is_const, is_abstract, is_external, is_native, cls,
-                       TokenPosition::kMinSource);
+  return Function::New(function_name, FunctionLayout::kRegularFunction,
+                       is_static, is_const, is_abstract, is_external, is_native,
+                       cls, TokenPosition::kMinSource);
 }
 
 ISOLATE_UNIT_TEST_CASE(ICData) {
@@ -3622,28 +3622,28 @@
   EXPECT(obj.IsMirrorReference());
 }
 
-static RawFunction* GetFunction(const Class& cls, const char* name) {
+static FunctionPtr GetFunction(const Class& cls, const char* name) {
   const Function& result = Function::Handle(
       cls.LookupDynamicFunction(String::Handle(String::New(name))));
   EXPECT(!result.IsNull());
   return result.raw();
 }
 
-static RawFunction* GetStaticFunction(const Class& cls, const char* name) {
+static FunctionPtr GetStaticFunction(const Class& cls, const char* name) {
   const Function& result = Function::Handle(
       cls.LookupStaticFunction(String::Handle(String::New(name))));
   EXPECT(!result.IsNull());
   return result.raw();
 }
 
-static RawField* GetField(const Class& cls, const char* name) {
+static FieldPtr GetField(const Class& cls, const char* name) {
   const Field& field =
       Field::Handle(cls.LookupField(String::Handle(String::New(name))));
   EXPECT(!field.IsNull());
   return field.raw();
 }
 
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
   const Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
@@ -3661,7 +3661,7 @@
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New(thread, "foo_papa"));
   parent =
-      Function::New(parent_name, RawFunction::kRegularFunction, false, false,
+      Function::New(parent_name, FunctionLayout::kRegularFunction, false, false,
                     false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(0, parent);
   cls.SetFunctions(functions);
@@ -3697,7 +3697,7 @@
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New(thread, "foo_papa"));
   parent =
-      Function::New(parent_name, RawFunction::kRegularFunction, false, false,
+      Function::New(parent_name, FunctionLayout::kRegularFunction, false, false,
                     false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(0, parent);
   cls.SetFunctions(functions);
@@ -3710,7 +3710,7 @@
   Function& invocation_dispatcher = Function::Handle();
   invocation_dispatcher ^= cls.GetInvocationDispatcher(
       invocation_dispatcher_name, args_desc,
-      RawFunction::kNoSuchMethodDispatcher, true /* create_if_absent */);
+      FunctionLayout::kNoSuchMethodDispatcher, true /* create_if_absent */);
   EXPECT(!invocation_dispatcher.IsNull());
   // Get index to function.
   intptr_t invocation_dispatcher_index =
@@ -3987,7 +3987,7 @@
   explicit ObjectAccumulator(GrowableArray<Object*>* objects)
       : objects_(objects) {}
   virtual ~ObjectAccumulator() {}
-  virtual void VisitObject(RawObject* obj) {
+  virtual void VisitObject(ObjectPtr obj) {
     if (obj->IsPseudoObject()) {
       return;  // Cannot be wrapped in handles.
     }
diff --git a/runtime/vm/object_x64_test.cc b/runtime/vm/object_x64_test.cc
index 259305c..e8913ce 100644
--- a/runtime/vm/object_x64_test.cc
+++ b/runtime/vm/object_x64_test.cc
@@ -43,8 +43,7 @@
 // This is used to test Embedded Smi objects in the instructions.
 void GenerateEmbedSmiInCode(compiler::Assembler* assembler, intptr_t value) {
   const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
-  __ movq(RAX,
-          compiler::Immediate(reinterpret_cast<int64_t>(smi_object.raw())));
+  __ movq(RAX, compiler::Immediate(static_cast<int64_t>(smi_object.raw())));
   __ ret();
 }
 
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 05985ab..1d3d4f6 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -12,38 +12,109 @@
 #include <stdint.h>
 
 #include <fuchsia/deprecatedtimezone/cpp/fidl.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/sys/cpp/component_context.h>
 #include <lib/sys/cpp/service_directory.h>
+#include <lib/sys/inspect/cpp/component.h>
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
 #include <zircon/syscalls/object.h>
 #include <zircon/types.h>
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 #include "vm/zone.h"
 
-namespace dart {
+namespace {
 
 // The data directory containing ICU timezone data files.
 static constexpr char kICUTZDataDir[] = "/config/data/tzdata/icu/44/le";
 
+// The status codes for tzdata file open and read.
+enum class TZDataStatus {
+  OK = 0,
+  // The open call for the tzdata file did not succeed.
+  COULD_NOT_OPEN = -1,
+  // The close call (after tzdata was loaded) did not succeed.
+  COULD_NOT_CLOSE = -2,
+};
+
+// Adds a facility for introspecting timezone data errors.  Allows insight into
+// the internal state of the VM even if error reporting facilities fail.
+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", 0)),
+        tz_data_status_(metrics_.CreateInt("tz_data_status", 0)),
+        tz_data_close_status_(metrics_.CreateInt("tz_data_close_status", 0)) {}
+
+  // Sets the last status code for DST offset calls.
+  void SetDSTOffsetStatus(zx_status_t status) {
+    dst_status_.Set(static_cast<int32_t>(status));
+  }
+
+  // Sets the return value of call to InitializeTZData, and the status of the
+  // reported by close() on tzdata files.
+  void SetInitTzData(TZDataStatus value, int32_t status) {
+    tz_data_status_.Set(static_cast<int32_t>(value));
+    tz_data_close_status_.Set(status);
+  }
+
+ 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_;
+
+  // The status of the last GetTimeZoneOffset call.
+  inspect::IntProperty dst_status_;
+
+  // The status of the initialization.
+  inspect::IntProperty tz_data_status_;
+
+  // The return code for the close() call for tzdata files.
+  inspect::IntProperty tz_data_close_status_;
+};
+
+// Initialized on OS:Init(), deinitialized on OS::Cleanup.
+std::unique_ptr<sys::ComponentInspector> component_inspector;
+std::unique_ptr<InspectMetrics> metrics;
+
 // Initializes the source of timezone data if available.  Timezone data file in
 // Fuchsia is at a fixed directory path.  Returns true on success.
 bool InitializeTZData() {
+  ASSERT(metrics != nullptr);
   // Try opening the path to check if present.  No need to verify that it is a
   // directory since ICU loading will return an error if the TZ data path is
   // wrong.
   int fd = openat(AT_FDCWD, kICUTZDataDir, O_RDONLY);
   if (fd < 0) {
+    metrics->SetInitTzData(TZDataStatus::COULD_NOT_OPEN, fd);
     return false;
   }
   // 0 == Not overwriting the env var if already set.
   setenv("ICU_TIMEZONE_FILES_DIR", kICUTZDataDir, 0);
-  if (!close(fd)) {
+  int32_t close_status = close(fd);
+  if (close_status != 0) {
+    metrics->SetInitTzData(TZDataStatus::COULD_NOT_CLOSE, close_status);
     return false;
   }
+  metrics->SetInitTzData(TZDataStatus::OK, 0);
   return true;
 }
 
+}  // namespace
+
+namespace dart {
+
 #ifndef PRODUCT
 
 DEFINE_FLAG(bool,
@@ -74,6 +145,7 @@
                                                  int32_t* dst_offset) {
   zx_status_t status = tz->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000,
                                                     local_offset, dst_offset);
+  metrics->SetDSTOffsetStatus(status);
   if (status != ZX_OK) {
     return status;
   }
@@ -263,12 +335,18 @@
 }
 
 void OS::Init() {
+  sys::ComponentContext* context = dart::ComponentContext();
+  component_inspector = std::make_unique<sys::ComponentInspector>(context);
+  metrics = std::make_unique<InspectMetrics>(component_inspector->inspector());
+
   InitializeTZData();
-  auto services = sys::ServiceDirectory::CreateFromNamespace();
-  services->Connect(tz.NewRequest());
+  context->svc()->Connect(tz.NewRequest());
 }
 
-void OS::Cleanup() {}
+void OS::Cleanup() {
+  metrics = nullptr;
+  component_inspector = nullptr;
+}
 
 void OS::PrepareToAbort() {}
 
diff --git a/runtime/vm/os_test.cc b/runtime/vm/os_test.cc
index 331b3d2..d1b7791 100644
--- a/runtime/vm/os_test.cc
+++ b/runtime/vm/os_test.cc
@@ -26,13 +26,6 @@
   EXPECT_EQ(3, length);
 }
 
-// This test is expected to crash when it runs.
-VM_UNIT_TEST_CASE_WITH_EXPECTATION(SNPrint_BadArgs, "Crash") {
-  int width = kMaxInt32;
-  int num = 7;
-  Utils::SNPrint(NULL, 0, "%*d%*d", width, num, width, num);
-}
-
 VM_UNIT_TEST_CASE(OsFuncs) {
   EXPECT(Utils::IsPowerOfTwo(OS::ActivationFrameAlignment()));
   int procs = OS::NumberOfAvailableProcessors();
diff --git a/runtime/vm/pointer_tagging.h b/runtime/vm/pointer_tagging.h
index 487f3f8..587bffa 100644
--- a/runtime/vm/pointer_tagging.h
+++ b/runtime/vm/pointer_tagging.h
@@ -17,8 +17,6 @@
 
 namespace dart {
 
-class RawSmi;
-
 // Dart VM aligns all objects by 2 words in in the old space and misaligns them
 // in new space. This allows to distinguish new and old pointers by their bits.
 //
@@ -34,6 +32,13 @@
   static constexpr intptr_t kObjectAlignment = 2 * word_size;
   static constexpr intptr_t kObjectAlignmentLog2 = word_size_log2 + 1;
   static constexpr intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
+
+  // Discriminate between true and false based on the alignment bit.
+  static constexpr intptr_t kBoolValueBitPosition = kObjectAlignmentLog2;
+  static constexpr intptr_t kBoolValueMask = 1 << kBoolValueBitPosition;
+
+  static constexpr intptr_t kTrueOffsetFromNull = kObjectAlignment * 2;
+  static constexpr intptr_t kFalseOffsetFromNull = kObjectAlignment * 3;
 };
 
 using HostObjectAlignment = ObjectAlignment<kWordSize, kWordSizeLog2>;
@@ -50,6 +55,13 @@
     HostObjectAlignment::kObjectAlignmentLog2;
 static constexpr intptr_t kObjectAlignmentMask =
     HostObjectAlignment::kObjectAlignmentMask;
+static constexpr intptr_t kBoolValueBitPosition =
+    HostObjectAlignment::kBoolValueBitPosition;
+static constexpr intptr_t kBoolValueMask = HostObjectAlignment::kBoolValueMask;
+static constexpr intptr_t kTrueOffsetFromNull =
+    HostObjectAlignment::kTrueOffsetFromNull;
+static constexpr intptr_t kFalseOffsetFromNull =
+    HostObjectAlignment::kFalseOffsetFromNull;
 
 // The largest value of kObjectAlignment across all configurations.
 static constexpr intptr_t kMaxObjectAlignment = 16;
@@ -72,12 +84,6 @@
   kSmiTagShift = 1,
 };
 
-inline intptr_t ValueFromRawSmi(const RawSmi* raw_value) {
-  const intptr_t value = reinterpret_cast<intptr_t>(raw_value);
-  ASSERT((value & kSmiTagMask) == kSmiTag);
-  return (value >> kSmiTagShift);
-}
-
 }  // namespace dart
 
 #endif  // RUNTIME_VM_POINTER_TAGGING_H_
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 826a8c5..9d5c331 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -17,58 +17,10 @@
 namespace dart {
 
 Mutex* PortMap::mutex_ = NULL;
-PortMap::Entry* PortMap::map_ = NULL;
+PortSet<PortMap::Entry>* PortMap::ports_ = NULL;
 MessageHandler* PortMap::deleted_entry_ = reinterpret_cast<MessageHandler*>(1);
-intptr_t PortMap::capacity_ = 0;
-intptr_t PortMap::used_ = 0;
-intptr_t PortMap::deleted_ = 0;
 Random* PortMap::prng_ = NULL;
 
-intptr_t PortMap::FindPort(Dart_Port port) {
-  // ILLEGAL_PORT (0) is used as a sentinel value in Entry.port. The loop below
-  // could return the index to a deleted port when we are searching for
-  // port id ILLEGAL_PORT. Return -1 immediately to indicate the port
-  // does not exist.
-  if (port == ILLEGAL_PORT) {
-    return -1;
-  }
-  ASSERT(port != ILLEGAL_PORT);
-  intptr_t index = port % capacity_;
-  intptr_t start_index = index;
-  Entry entry = map_[index];
-  while (entry.handler != NULL) {
-    if (entry.port == port) {
-      return index;
-    }
-    index = (index + 1) % capacity_;
-    // Prevent endless loops.
-    ASSERT(index != start_index);
-    entry = map_[index];
-  }
-  return -1;
-}
-
-void PortMap::Rehash(intptr_t new_capacity) {
-  Entry* new_ports = new Entry[new_capacity];
-  memset(new_ports, 0, new_capacity * sizeof(Entry));
-
-  for (intptr_t i = 0; i < capacity_; i++) {
-    Entry entry = map_[i];
-    // Skip free and deleted entries.
-    if (entry.port != 0) {
-      intptr_t new_index = entry.port % new_capacity;
-      while (new_ports[new_index].port != 0) {
-        new_index = (new_index + 1) % new_capacity;
-      }
-      new_ports[new_index] = entry;
-    }
-  }
-  delete[] map_;
-  map_ = new_ports;
-  capacity_ = new_capacity;
-  deleted_ = 0;
-}
-
 const char* PortMap::PortStateString(PortState kind) {
   switch (kind) {
     case kNewPort:
@@ -96,23 +48,34 @@
     // an object pointer as a port id never produces a used port id.
     const Dart_Port kMask2 = 0x3;
     result = (prng_->NextUInt64() & kMask1) | kMask2;
-    ASSERT(!reinterpret_cast<RawObject*>(result)->IsWellFormed());
-  } while (FindPort(result) >= 0);
+
+    // The two special marker ports are used for the hashset implementation and
+    // cannot be used as actual ports.
+    if (result == PortSet<Entry>::kFreePort ||
+        result == PortSet<Entry>::kDeletedPort) {
+      continue;
+    }
+
+    ASSERT(!static_cast<ObjectPtr>(static_cast<uword>(result))->IsWellFormed());
+  } while (ports_->Contains(result));
 
   ASSERT(result != 0);
-  ASSERT(FindPort(result) < 0);
+  ASSERT(!ports_->Contains(result));
   return result;
 }
 
 void PortMap::SetPortState(Dart_Port port, PortState state) {
   MutexLocker ml(mutex_);
-  intptr_t index = FindPort(port);
-  ASSERT(index >= 0);
-  PortState old_state = map_[index].state;
+
+  auto it = ports_->TryLookup(port);
+  ASSERT(it != ports_->end());
+
+  Entry& entry = *it;
+  PortState old_state = entry.state;
   ASSERT(old_state == kNewPort);
-  map_[index].state = state;
+  entry.state = state;
   if (state == kLivePort) {
-    map_[index].handler->increment_live_ports();
+    entry.handler->increment_live_ports();
   }
   if (FLAG_trace_isolates) {
     OS::PrintErr(
@@ -120,19 +83,7 @@
         "\thandler:    %s\n"
         "\tport:       %" Pd64 "\n",
         PortStateString(old_state), PortStateString(state),
-        map_[index].handler->name(), port);
-  }
-}
-
-void PortMap::MaintainInvariants() {
-  intptr_t empty = capacity_ - used_ - deleted_;
-  if (used_ > ((capacity_ / 4) * 3)) {
-    // Grow the port map.
-    Rehash(capacity_ * 2);
-  } else if (empty < deleted_) {
-    // Rehash without growing the table to flush the deleted slots out of the
-    // map.
-    Rehash(capacity_);
+        entry.handler->name(), port);
   }
 }
 
@@ -143,37 +94,19 @@
   handler->CheckAccess();
 #endif
 
+  const Dart_Port port = AllocatePort();
+
+  // The MessageHandler::ports_ is only accessed by [PortMap], it is guarded
+  // by the [PortMap::mutex_] we already hold.
+  MessageHandler::PortSetEntry isolate_entry;
+  isolate_entry.port = port;
+  handler->ports_.Insert(isolate_entry);
+
   Entry entry;
-  entry.port = AllocatePort();
+  entry.port = port;
   entry.handler = handler;
   entry.state = kNewPort;
-
-  // Search for the first unused slot. Make use of the knowledge that here is
-  // currently no port with this id in the port map.
-  ASSERT(FindPort(entry.port) < 0);
-  intptr_t index = entry.port % capacity_;
-  Entry cur = map_[index];
-  // Stop the search at the first found unused (free or deleted) slot.
-  while (cur.port != 0) {
-    index = (index + 1) % capacity_;
-    cur = map_[index];
-  }
-
-  // Insert the newly created port at the index.
-  ASSERT(index >= 0);
-  ASSERT(index < capacity_);
-  ASSERT(map_[index].port == 0);
-  ASSERT((map_[index].handler == NULL) ||
-         (map_[index].handler == deleted_entry_));
-  if (map_[index].handler == deleted_entry_) {
-    // Consuming a deleted entry.
-    deleted_--;
-  }
-  map_[index] = entry;
-
-  // Increment number of used slots and grow if necessary.
-  used_++;
-  MaintainInvariants();
+  ports_->Insert(entry);
 
   if (FLAG_trace_isolates) {
     OS::PrintErr(
@@ -190,31 +123,33 @@
   MessageHandler* handler = NULL;
   {
     MutexLocker ml(mutex_);
-    intptr_t index = FindPort(port);
-    if (index < 0) {
+    auto it = ports_->TryLookup(port);
+    if (it == ports_->end()) {
       return false;
     }
-    ASSERT(index < capacity_);
-    ASSERT(map_[index].port != 0);
-    ASSERT(map_[index].handler != deleted_entry_);
-    ASSERT(map_[index].handler != NULL);
+    Entry entry = *it;
+    handler = entry.handler;
+    ASSERT(handler != nullptr);
 
-    handler = map_[index].handler;
 #if defined(DEBUG)
     handler->CheckAccess();
 #endif
-    // Before releasing the lock mark the slot in the map as deleted. This makes
-    // it possible to release the port map lock before flushing all of its
-    // pending messages below.
-    map_[index].port = 0;
-    map_[index].handler = deleted_entry_;
-    if (map_[index].state == kLivePort) {
+
+    if (entry.state == kLivePort) {
       handler->decrement_live_ports();
     }
 
-    used_--;
-    deleted_++;
-    MaintainInvariants();
+    // Delete the port entry before releasing the lock to avoid holding the lock
+    // while flushing the messages below.
+    it.Delete();
+    ports_->Rebalance();
+
+    // The MessageHandler::ports_ is only accessed by [PortMap], it is guarded
+    // by the [PortMap::mutex_] we already hold.
+    auto isolate_it = handler->ports_.TryLookup(port);
+    ASSERT(isolate_it != handler->ports_.end());
+    isolate_it.Delete();
+    handler->ports_.Rebalance();
   }
   handler->ClosePort(port);
   if (!handler->HasLivePorts() && handler->OwnedByPortMap()) {
@@ -227,19 +162,23 @@
 void PortMap::ClosePorts(MessageHandler* handler) {
   {
     MutexLocker ml(mutex_);
-    for (intptr_t i = 0; i < capacity_; i++) {
-      if (map_[i].handler == handler) {
-        // Mark the slot as deleted.
-        map_[i].port = 0;
-        map_[i].handler = deleted_entry_;
-        if (map_[i].state == kLivePort) {
-          handler->decrement_live_ports();
-        }
-        used_--;
-        deleted_++;
+    // The MessageHandler::ports_ is only accessed by [PortMap], it is guarded
+    // by the [PortMap::mutex_] we already hold.
+    for (auto isolate_it = handler->ports_.begin();
+         isolate_it != handler->ports_.end(); ++isolate_it) {
+      auto it = ports_->TryLookup((*isolate_it).port);
+      ASSERT(it != ports_->end());
+      Entry entry = *it;
+      ASSERT(entry.port == (*isolate_it).port);
+      ASSERT(entry.handler == handler);
+      if (entry.state == kLivePort) {
+        handler->decrement_live_ports();
       }
+      it.Delete();
+      isolate_it.Delete();
     }
-    MaintainInvariants();
+    ASSERT(handler->ports_.IsEmpty());
+    ports_->Rebalance();
   }
   handler->CloseAllPorts();
 }
@@ -247,80 +186,84 @@
 bool PortMap::PostMessage(std::unique_ptr<Message> message,
                           bool before_events) {
   MutexLocker ml(mutex_);
-  intptr_t index = FindPort(message->dest_port());
-  if (index < 0) {
+  auto it = ports_->TryLookup(message->dest_port());
+  if (it == ports_->end()) {
     // Ownership of external data remains with the poster.
     message->DropFinalizers();
     return false;
   }
-  ASSERT(index >= 0);
-  ASSERT(index < capacity_);
-  MessageHandler* handler = map_[index].handler;
-  ASSERT(map_[index].port != 0);
-  ASSERT((handler != NULL) && (handler != deleted_entry_));
+  MessageHandler* handler = (*it).handler;
+  ASSERT(handler != nullptr);
   handler->PostMessage(std::move(message), before_events);
   return true;
 }
 
 bool PortMap::IsLocalPort(Dart_Port id) {
   MutexLocker ml(mutex_);
-  intptr_t index = FindPort(id);
-  if (index < 0) {
+  auto it = ports_->TryLookup(id);
+  if (it == ports_->end()) {
     // Port does not exist.
     return false;
   }
 
-  MessageHandler* handler = map_[index].handler;
+  MessageHandler* handler = (*it).handler;
+  ASSERT(handler != nullptr);
   return handler->IsCurrentIsolate();
 }
 
 Isolate* PortMap::GetIsolate(Dart_Port id) {
   MutexLocker ml(mutex_);
-  intptr_t index = FindPort(id);
-  if (index < 0) {
+  auto it = ports_->TryLookup(id);
+  if (it == ports_->end()) {
     // Port does not exist.
-    return NULL;
+    return nullptr;
   }
 
-  MessageHandler* handler = map_[index].handler;
+  MessageHandler* handler = (*it).handler;
   return handler->isolate();
 }
 
+bool PortMap::IsReceiverInThisIsolateGroup(Dart_Port receiver,
+                                           IsolateGroup* group) {
+  MutexLocker ml(mutex_);
+  auto it = ports_->TryLookup(receiver);
+  if (it == ports_->end()) return false;
+  return (*it).handler->isolate()->group() == group;
+}
+
 void PortMap::Init() {
+  // TODO(bkonyi): don't keep ports_ after Dart_Cleanup.
   if (mutex_ == NULL) {
     mutex_ = new Mutex();
   }
   ASSERT(mutex_ != NULL);
-  prng_ = new Random();
-
-  static const intptr_t kInitialCapacity = 8;
-  // TODO(iposva): Verify whether we want to keep exponentially growing.
-  ASSERT(Utils::IsPowerOfTwo(kInitialCapacity));
-  if (map_ == NULL) {
-    // TODO(bkonyi): don't keep map_ after Dart_Cleanup.
-    map_ = new Entry[kInitialCapacity];
-    capacity_ = kInitialCapacity;
+  if (prng_ == nullptr) {
+    prng_ = new Random();
   }
-  memset(map_, 0, capacity_ * sizeof(Entry));
-  used_ = 0;
-  deleted_ = 0;
+  if (ports_ == nullptr) {
+    ports_ = new PortSet<Entry>();
+  }
 }
 
 void PortMap::Cleanup() {
-  ASSERT(map_ != NULL);
+  ASSERT(ports_ != nullptr);
   ASSERT(prng_ != NULL);
-  for (intptr_t i = 0; i < capacity_; ++i) {
-    auto handler = map_[i].handler;
-    if (handler != NULL && handler != deleted_entry_) {
-      ClosePorts(handler);
-      delete handler;
+  for (auto it = ports_->begin(); it != ports_->end(); ++it) {
+    const auto& entry = *it;
+    ASSERT(entry.handler != nullptr);
+    if (entry.state == kLivePort) {
+      entry.handler->decrement_live_ports();
     }
+    delete entry.handler;
+    it.Delete();
   }
+  ports_->Rebalance();
+
   delete prng_;
   prng_ = NULL;
   // TODO(bkonyi): find out why deleting map_ sometimes causes crashes.
-  // delete[] map_;
-  // map_ = NULL;
+  // delete ports_;
+  // ports_ = nullptr;
 }
 
 void PortMap::PrintPortsForMessageHandler(MessageHandler* handler,
@@ -332,13 +275,13 @@
   {
     JSONArray ports(&jsobj, "ports");
     SafepointMutexLocker ml(mutex_);
-    for (intptr_t i = 0; i < capacity_; i++) {
-      if (map_[i].handler == handler) {
-        if (map_[i].state == kLivePort) {
+    for (auto& entry : *ports_) {
+      if (entry.handler == handler) {
+        if (entry.state == kLivePort) {
           JSONObject port(&ports);
           port.AddProperty("type", "_Port");
-          port.AddPropertyF("name", "Isolate Port (%" Pd64 ")", map_[i].port);
-          msg_handler = DartLibraryCalls::LookupHandler(map_[i].port);
+          port.AddPropertyF("name", "Isolate Port (%" Pd64 ")", entry.port);
+          msg_handler = DartLibraryCalls::LookupHandler(entry.port);
           port.AddProperty("handler", msg_handler);
         }
       }
@@ -350,11 +293,11 @@
 void PortMap::DebugDumpForMessageHandler(MessageHandler* handler) {
   SafepointMutexLocker ml(mutex_);
   Object& msg_handler = Object::Handle();
-  for (intptr_t i = 0; i < capacity_; i++) {
-    if (map_[i].handler == handler) {
-      if (map_[i].state == kLivePort) {
-        OS::PrintErr("Live Port = %" Pd64 "\n", map_[i].port);
-        msg_handler = DartLibraryCalls::LookupHandler(map_[i].port);
+  for (auto& entry : *ports_) {
+    if (entry.handler == handler) {
+      if (entry.state == kLivePort) {
+        OS::PrintErr("Live Port = %" Pd64 "\n", entry.port);
+        msg_handler = DartLibraryCalls::LookupHandler(entry.port);
         OS::PrintErr("Handler = %s\n", msg_handler.ToCString());
       }
     }
diff --git a/runtime/vm/port.h b/runtime/vm/port.h
index 155e3832..0297f1d 100644
--- a/runtime/vm/port.h
+++ b/runtime/vm/port.h
@@ -11,6 +11,7 @@
 #include "vm/allocation.h"
 #include "vm/globals.h"
 #include "vm/json_stream.h"
+#include "vm/port_set.h"
 #include "vm/random.h"
 
 namespace dart {
@@ -57,6 +58,9 @@
   // Returns the owning Isolate for port 'id'.
   static Isolate* GetIsolate(Dart_Port id);
 
+  static bool IsReceiverInThisIsolateGroup(Dart_Port receiver,
+                                           IsolateGroup* group);
+
   static void Init();
   static void Cleanup();
 
@@ -68,15 +72,12 @@
  private:
   friend class dart::PortMapTestPeer;
 
-  // Mapping between port numbers and handlers.
-  //
-  // Free entries have id == 0 and handler == NULL. Deleted entries
-  // have id == 0 and handler == deleted_entry_.
-  typedef struct {
-    Dart_Port port;
+  struct Entry : public PortSet<Entry>::Entry {
+    Entry() : handler(nullptr), state(kNewPort) {}
+
     MessageHandler* handler;
     PortState state;
-  } Entry;
+  };
 
   static const char* PortStateString(PortState state);
 
@@ -86,20 +87,11 @@
   static bool IsActivePort(Dart_Port id);
   static bool IsLivePort(Dart_Port id);
 
-  static intptr_t FindPort(Dart_Port port);
-  static void Rehash(intptr_t new_capacity);
-
-  static void MaintainInvariants();
-
   // Lock protecting access to the port map.
   static Mutex* mutex_;
 
-  // Hashmap of ports.
-  static Entry* map_;
+  static PortSet<Entry>* ports_;
   static MessageHandler* deleted_entry_;
-  static intptr_t capacity_;
-  static intptr_t used_;
-  static intptr_t deleted_;
 
   static Random* prng_;
 };
diff --git a/runtime/vm/port_set.h b/runtime/vm/port_set.h
new file mode 100644
index 0000000..97a2c9a
--- /dev/null
+++ b/runtime/vm/port_set.h
@@ -0,0 +1,235 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_PORT_SET_H_
+#define RUNTIME_VM_PORT_SET_H_
+
+#include "include/dart_api.h"
+
+#include "platform/globals.h"
+#include "platform/utils.h"
+
+namespace dart {
+
+template <typename T /* :public PortSet<T>::Entry */>
+class PortSet {
+ public:
+  static constexpr Dart_Port kFreePort = static_cast<Dart_Port>(0);
+  static constexpr Dart_Port kDeletedPort = static_cast<Dart_Port>(3);
+
+  struct Entry {
+    Entry() : port(kFreePort) {}
+
+    // Free entries have set this to 0.
+    Dart_Port port;
+  };
+
+  class Iterator {
+   public:
+    Iterator(PortSet<T>* ports, intptr_t index) : ports_(ports), index_(index) {
+#if defined(DEBUG)
+      dirty_counter_ = ports_->dirty_counter_;
+#endif
+    }
+
+    DART_FORCE_INLINE T& operator->() const {
+      ASSERT(index_ >= 0 && index_ < ports_->capacity_);
+      DEBUG_ASSERT(!WasModified());
+      return ports_->map_[index_];
+    }
+    DART_FORCE_INLINE T& operator*() const {
+      ASSERT(index_ >= 0 && index_ < ports_->capacity_);
+      DEBUG_ASSERT(!WasModified());
+      return ports_->map_[index_];
+    }
+
+    DART_FORCE_INLINE bool operator==(const Iterator& other) const {
+      DEBUG_ASSERT(!WasModified());
+      return ports_ == other.ports_ && index_ == other.index_;
+    }
+
+    DART_FORCE_INLINE bool operator!=(const Iterator& other) const {
+      DEBUG_ASSERT(!WasModified());
+      return !(*this == other);
+    }
+
+    DART_FORCE_INLINE Iterator& operator++() {
+      DEBUG_ASSERT(!WasModified());
+      index_++;
+      while (index_ < ports_->capacity_) {
+        const Dart_Port port = ports_->map_[index_].port;
+        if (port == kFreePort || port == kDeletedPort) {
+          index_++;
+          continue;
+        } else {
+          break;
+        }
+      }
+      return *this;
+    }
+
+    // The caller must ensure to call [PortSet::Rebalance] once the iterator is
+    // not used anymore.
+    DART_FORCE_INLINE void Delete() {
+      DEBUG_ASSERT(!WasModified());
+      ports_->map_[index_] = T();
+      ports_->map_[index_].port = kDeletedPort;
+      ports_->used_--;
+      ports_->deleted_++;
+    }
+
+   private:
+    friend class PortSet;
+
+#if defined(DEBUG)
+    // Whether the underlying [PortSet] was modified in a way that would render
+    // the iterator unusable.
+    bool WasModified() const {
+      return dirty_counter_ != ports_->dirty_counter_;
+    }
+#endif
+
+    PortSet<T>* ports_;
+    intptr_t index_ = 0;
+#if defined(DEBUG)
+    intptr_t dirty_counter_ = 0;
+#endif
+  };
+
+  PortSet() {
+    static const intptr_t kInitialCapacity = 8;
+    ASSERT(Utils::IsPowerOfTwo(kInitialCapacity));
+    map_ = new T[kInitialCapacity];
+    capacity_ = kInitialCapacity;
+  }
+  ~PortSet() {
+    delete[] map_;
+    map_ = nullptr;
+  }
+
+  bool IsEmpty() const { return used_ == 0; }
+
+  DART_FORCE_INLINE Iterator begin() {
+    for (intptr_t i = 0; i < capacity_; ++i) {
+      auto& entry = map_[i];
+      if (entry.port != kFreePort && entry.port != kDeletedPort) {
+        return Iterator(this, i);
+      }
+    }
+    return end();
+  }
+
+  DART_FORCE_INLINE Iterator end() { return Iterator(this, capacity_); }
+
+  void Insert(const T& entry) {
+    // Search for the first unused slot. Make use of the knowledge that here is
+    // currently no port with this id in the port map.
+    ASSERT(FindIndexOfPort(entry.port) < 0);
+    intptr_t index = entry.port % capacity_;
+    T cur = map_[index];
+
+    // Stop the search at the first found unused (free or deleted) slot.
+    while (cur.port != kFreePort && cur.port != kDeletedPort) {
+      index = (index + 1) % capacity_;
+      cur = map_[index];
+    }
+
+    // Insert the newly created port at the index.
+    ASSERT(map_[index].port == kFreePort || map_[index].port == kDeletedPort);
+    if (map_[index].port == kDeletedPort) {
+      deleted_--;
+    }
+    map_[index] = entry;
+    ASSERT(FindIndexOfPort(entry.port) >= 0);
+
+    // Increment number of used slots and grow if necessary.
+    used_++;
+    MaintainInvariants();
+
+#if defined(DEBUG)
+    dirty_counter_++;
+#endif
+  }
+
+  Iterator TryLookup(Dart_Port port) {
+    const intptr_t index = FindIndexOfPort(port);
+    if (index >= 0) return Iterator(this, index);
+    return Iterator(this, capacity_);
+  }
+
+  bool Contains(Dart_Port port) { return FindIndexOfPort(port) >= 0; }
+
+  // To be called if an iterator was used to delete an entry.
+  void Rebalance() { MaintainInvariants(); }
+
+ private:
+  intptr_t FindIndexOfPort(Dart_Port port) {
+    // ILLEGAL_PORT (0) is used as a sentinel value in Entry.port. The loop
+    // below could return the index to a deleted port when we are searching for
+    // port id ILLEGAL_PORT. Return -1 immediately to indicate the port
+    // does not exist.
+    if (port == ILLEGAL_PORT) {
+      return -1;
+    }
+    ASSERT(port != ILLEGAL_PORT);
+    intptr_t index = port % capacity_;
+    intptr_t start_index = index;
+    T entry = map_[index];
+    while (entry.port != kFreePort) {
+      if (entry.port == port) {
+        return index;
+      }
+      index = (index + 1) % capacity_;
+      // Prevent endless loops.
+      ASSERT(index != start_index);
+      entry = map_[index];
+    }
+    return -1;
+  }
+
+  void MaintainInvariants() {
+    const intptr_t empty = capacity_ - used_ - deleted_;
+    if (used_ > ((capacity_ / 4) * 3)) {
+      // Grow the port map.
+      Rehash(capacity_ * 2);
+    } else if (empty < deleted_) {
+      // Rehash without growing the table to flush the deleted slots out of the
+      // map.
+      Rehash(capacity_);
+    }
+  }
+
+  void Rehash(intptr_t new_capacity) {
+    T* new_ports = new T[new_capacity];
+
+    for (auto entry : *this) {
+      intptr_t new_index = entry.port % new_capacity;
+      while (new_ports[new_index].port != 0) {
+        new_index = (new_index + 1) % new_capacity;
+      }
+      new_ports[new_index] = entry;
+    }
+    delete[] map_;
+    map_ = new_ports;
+    capacity_ = new_capacity;
+    deleted_ = 0;
+
+#if defined(DEBUG)
+    dirty_counter_++;
+#endif
+  }
+
+  T* map_ = nullptr;
+  intptr_t capacity_ = 0;
+  intptr_t used_ = 0;
+  intptr_t deleted_ = 0;
+
+#if defined(DEBUG)
+  intptr_t dirty_counter_ = 0;
+#endif
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_PORT_SET_H_
diff --git a/runtime/vm/port_test.cc b/runtime/vm/port_test.cc
index 6526471..2681b3a 100644
--- a/runtime/vm/port_test.cc
+++ b/runtime/vm/port_test.cc
@@ -16,16 +16,17 @@
  public:
   static bool IsActivePort(Dart_Port port) {
     MutexLocker ml(PortMap::mutex_);
-    return (PortMap::FindPort(port) >= 0);
+    auto it = PortMap::ports_->TryLookup(port);
+    return it != PortMap::ports_->end();
   }
 
   static bool IsLivePort(Dart_Port port) {
     MutexLocker ml(PortMap::mutex_);
-    intptr_t index = PortMap::FindPort(port);
-    if (index < 0) {
+    auto it = PortMap::ports_->TryLookup(port);
+    if (it == PortMap::ports_->end()) {
       return false;
     }
-    return PortMap::map_[index].state == PortMap::kLivePort;
+    return (*it).state == PortMap::kLivePort;
   }
 };
 
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 69eaf42..f4741fd 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -1132,12 +1132,13 @@
     }
   }
 
+  OS::PrintErr("version=%s\n", Version::String());
   OSThread* os_thread = OSThread::Current();
   ASSERT(os_thread != NULL);
   Isolate* isolate = Isolate::Current();
-  const char* name = isolate == NULL ? NULL : isolate->name();
-  OS::PrintErr("version=%s\npid=%" Pd ", thread=%" Pd ", isolate=%s(%p)\n",
-               Version::String(), OS::ProcessId(),
+  const char* name = isolate == NULL ? "(nil)" : isolate->name();
+  OS::PrintErr("pid=%" Pd ", thread=%" Pd ", isolate=%s(%p)\n",
+               static_cast<intptr_t>(OS::ProcessId()),
                OSThread::ThreadIdToIntPtr(os_thread->trace_id()), name,
                isolate);
   const IsolateGroupSource* source =
@@ -1451,7 +1452,7 @@
 
   ~CodeLookupTableBuilder() {}
 
-  void VisitObject(RawObject* raw_obj) {
+  void VisitObject(ObjectPtr raw_obj) {
     if (raw_obj->IsCode()) {
       table_->Add(Code::Handle(Code::RawCast(raw_obj)));
     } else if (raw_obj->IsBytecode()) {
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 49d6814..d63175b 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -456,11 +456,11 @@
 
 class AbstractCode {
  public:
-  explicit AbstractCode(RawObject* code) : code_(Object::Handle(code)) {
+  explicit AbstractCode(ObjectPtr code) : code_(Object::Handle(code)) {
     ASSERT(code_.IsNull() || code_.IsCode() || code_.IsBytecode());
   }
 
-  RawObject* raw() const { return code_.raw(); }
+  ObjectPtr raw() const { return code_.raw(); }
   const Object* handle() const { return &code_; }
 
   uword PayloadStart() const {
@@ -533,7 +533,7 @@
     }
   }
 
-  RawObject* owner() const {
+  ObjectPtr owner() const {
     if (code_.IsCode()) {
       return Code::Cast(code_).owner();
     } else if (code_.IsBytecode()) {
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 7fe9b39..3c91049 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -345,10 +345,9 @@
   if (name == NULL) {
     name_ = NULL;
   }
-  intptr_t len = strlen(name);
-  name_ = Thread::Current()->zone()->Alloc<char>(len + 1);
+  intptr_t len = strlen(name) + 1;
+  name_ = Thread::Current()->zone()->Alloc<char>(len);
   strncpy(name_, name, len);
-  name_[len] = '\0';
 }
 
 void ProfileCode::GenerateAndSetSymbolName(const char* prefix) {
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index f34c24c..0ad1e7f 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -28,8 +28,6 @@
 class JSONStream;
 class ProfileFunctionTable;
 class ProfileCodeTable;
-class RawCode;
-class RawFunction;
 class SampleFilter;
 class ProcessedSample;
 class ProcessedSampleBuffer;
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index d067f5f..fd6751e 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -155,7 +155,7 @@
   delete sample_buffer;
 }
 
-static RawLibrary* LoadTestScript(const char* script) {
+static LibraryPtr LoadTestScript(const char* script) {
   Dart_Handle api_lib;
   {
     TransitionVMToNative transition(Thread::Current());
@@ -167,7 +167,7 @@
   return lib.raw();
 }
 
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
   Thread* thread = Thread::Current();
   const Class& cls = Class::Handle(
       lib.LookupClassAllowPrivate(String::Handle(Symbols::New(thread, name))));
@@ -175,7 +175,7 @@
   return cls.raw();
 }
 
-static RawFunction* GetFunction(const Library& lib, const char* name) {
+static FunctionPtr GetFunction(const Library& lib, const char* name) {
   Thread* thread = Thread::Current();
   const Function& func = Function::Handle(lib.LookupFunctionAllowPrivate(
       String::Handle(Symbols::New(thread, name))));
@@ -464,7 +464,11 @@
       EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
       EXPECT(!walker.Down());
     } else {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT(walker.Down());
       EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
       EXPECT(walker.Down());
@@ -660,7 +664,11 @@
       EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
       EXPECT(!walker.Down());
     } else {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT(walker.Down());
       EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
       EXPECT(walker.Down());
@@ -755,7 +763,11 @@
       EXPECT_EQ(0, walker.CurrentExclusiveTicks());
       EXPECT(!walker.Down());
     } else {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(3, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
       EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
@@ -828,7 +840,11 @@
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
 
     if (!FLAG_enable_interpreter) {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(3, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
     }
@@ -1116,7 +1132,11 @@
 
     EXPECT_SUBSTRING("DRT_AllocateObject", walker.VMTagName());
     if (!FLAG_enable_interpreter) {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT(walker.Down());
     }
     EXPECT_SUBSTRING("foo", walker.CurrentName());
@@ -1480,7 +1500,11 @@
       ProfileStackWalker walker(&profile);
       // We have two code objects: mainA and B.boo.
       EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
       EXPECT_STREQ("[Optimized] B.boo", walker.CurrentName());
@@ -1496,7 +1520,11 @@
       // Inline expansion should show us the complete call chain:
       // mainA -> B.boo -> B.foo -> B.choo.
       EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
       EXPECT_STREQ("B.choo", walker.CurrentName());
@@ -1618,7 +1646,11 @@
 
     // Inline expansion should show us the complete call chain:
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
     EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+    EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
     EXPECT(walker.Down());
     EXPECT_STREQ("maybeAlloc", walker.CurrentName());
     EXPECT(walker.Down());
@@ -1732,7 +1764,11 @@
       EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
       EXPECT(!walker.Down());
     } else {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT(walker.Down());
       EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
       EXPECT(walker.Down());
@@ -1825,7 +1861,11 @@
 
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
     if (!FLAG_enable_interpreter) {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(1, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
     }
@@ -1906,7 +1946,11 @@
 
     // Move down from the root.
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
     EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+    EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
     EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
@@ -1980,7 +2024,11 @@
 
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
     if (!FLAG_enable_interpreter) {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(1, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
     }
@@ -2088,7 +2136,11 @@
     ProfileStackWalker walker(&profile, true);
 
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
     EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+    EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
     EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
@@ -2180,7 +2232,11 @@
 
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
     if (!FLAG_enable_interpreter) {
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
       EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+      EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
       EXPECT_EQ(1, walker.CurrentExclusiveTicks());
       EXPECT(walker.Down());
     }
@@ -2296,7 +2352,11 @@
     ProfileStackWalker walker(&profile, true);
 
     EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
+#if defined(TARGET_ARCH_IA32)  // Alloc. stub not impl. for ia32.
     EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+#else
+    EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName());
+#endif
     EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index d8b80fc..7085853 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -13,149 +13,271 @@
 
 namespace dart {
 
-void ProgramVisitor::VisitClasses(ClassVisitor* visitor) {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-  GrowableObjectArray& libraries =
-      GrowableObjectArray::Handle(zone, isolate->object_store()->libraries());
-  Library& lib = Library::Handle(zone);
-  Class& cls = Class::Handle(zone);
-  Object& entry = Object::Handle(zone);
-  GrowableObjectArray& patches = GrowableObjectArray::Handle(zone);
+class WorklistElement : public ZoneAllocated {
+ public:
+  WorklistElement(Zone* zone, const Object& object)
+      : object_(Object::Handle(zone, object.raw())), next_(nullptr) {}
+
+  ObjectPtr value() const { return object_.raw(); }
+
+  void set_next(WorklistElement* elem) { next_ = elem; }
+  WorklistElement* next() const { return next_; }
+
+ private:
+  const Object& object_;
+  WorklistElement* next_;
+
+  DISALLOW_COPY_AND_ASSIGN(WorklistElement);
+};
+
+// Implements a FIFO queue, using IsEmpty, Add, Remove operations.
+class Worklist : public ValueObject {
+ public:
+  explicit Worklist(Zone* zone)
+      : zone_(zone), first_(nullptr), last_(nullptr) {}
+
+  bool IsEmpty() const { return first_ == nullptr; }
+
+  void Add(const Object& value) {
+    auto element = new (zone_) WorklistElement(zone_, value);
+    if (first_ == nullptr) {
+      first_ = element;
+      ASSERT(last_ == nullptr);
+    } else {
+      ASSERT(last_ != nullptr);
+      last_->set_next(element);
+    }
+    last_ = element;
+    ASSERT(first_ != nullptr && last_ != nullptr);
+  }
+
+  ObjectPtr Remove() {
+    ASSERT(first_ != nullptr);
+    WorklistElement* result = first_;
+    first_ = first_->next();
+    if (first_ == nullptr) {
+      last_ = nullptr;
+    }
+    return result->value();
+  }
+
+ private:
+  Zone* const zone_;
+  WorklistElement* first_;
+  WorklistElement* last_;
+
+  DISALLOW_COPY_AND_ASSIGN(Worklist);
+};
+
+// Walks through the classes, functions, and code for the current program.
+//
+// Uses the heap object ID table to determine whether or not a given object
+// has been visited already.
+class ProgramWalker : public ValueObject {
+ public:
+  ProgramWalker(Zone* zone, Heap* heap, ClassVisitor* visitor)
+      : heap_(heap),
+        visitor_(visitor),
+        worklist_(zone),
+        class_object_(Object::Handle(zone)),
+        class_fields_(Array::Handle(zone)),
+        class_field_(Field::Handle(zone)),
+        class_functions_(Array::Handle(zone)),
+        class_function_(Function::Handle(zone)),
+        class_code_(Code::Handle(zone)),
+        function_code_(Code::Handle(zone)),
+        static_calls_array_(Array::Handle(zone)),
+        static_calls_table_entry_(Object::Handle(zone)),
+        worklist_entry_(Object::Handle(zone)) {}
+
+  ~ProgramWalker() { heap_->ResetObjectIdTable(); }
+
+  // Adds the given object to the worklist if it's an object type that the
+  // visitor can visit.
+  void AddToWorklist(const Object& object) {
+    // We don't visit null, non-heap objects, or objects in the VM heap.
+    if (object.IsNull() || object.IsSmi() || object.InVMIsolateHeap()) return;
+    // Check and set visited, even if we don't end up adding this to the list.
+    if (heap_->GetObjectId(object.raw()) != 0) return;
+    heap_->SetObjectId(object.raw(), 1);
+    if (object.IsClass() ||
+        (object.IsFunction() && visitor_->IsFunctionVisitor()) ||
+        (object.IsCode() && visitor_->IsCodeVisitor())) {
+      worklist_.Add(object);
+    }
+  }
+
+  void VisitWorklist() {
+    while (!worklist_.IsEmpty()) {
+      worklist_entry_ = worklist_.Remove();
+      if (worklist_entry_.IsClass()) {
+        VisitClass(Class::Cast(worklist_entry_));
+      } else if (worklist_entry_.IsFunction()) {
+        VisitFunction(Function::Cast(worklist_entry_));
+      } else if (worklist_entry_.IsCode()) {
+        VisitCode(Code::Cast(worklist_entry_));
+      } else {
+        FATAL1("Got unexpected object %s", worklist_entry_.ToCString());
+      }
+    }
+  }
+
+ private:
+  void VisitClass(const Class& cls) {
+    visitor_->VisitClass(cls);
+
+    if (!visitor_->IsFunctionVisitor()) return;
+
+    class_functions_ = cls.functions();
+    for (intptr_t j = 0; j < class_functions_.Length(); j++) {
+      class_function_ ^= class_functions_.At(j);
+      AddToWorklist(class_function_);
+      if (class_function_.HasImplicitClosureFunction()) {
+        class_function_ = class_function_.ImplicitClosureFunction();
+        AddToWorklist(class_function_);
+      }
+    }
+
+    class_functions_ = cls.invocation_dispatcher_cache();
+    for (intptr_t j = 0; j < class_functions_.Length(); j++) {
+      class_object_ = class_functions_.At(j);
+      if (class_object_.IsFunction()) {
+        class_function_ ^= class_functions_.At(j);
+        AddToWorklist(class_function_);
+      }
+    }
+
+    class_fields_ = cls.fields();
+    for (intptr_t j = 0; j < class_fields_.Length(); j++) {
+      class_field_ ^= class_fields_.At(j);
+      if (class_field_.HasInitializerFunction()) {
+        class_function_ = class_field_.InitializerFunction();
+        AddToWorklist(class_function_);
+      }
+    }
+
+    if (!visitor_->IsCodeVisitor()) return;
+
+    class_code_ = cls.allocation_stub();
+    if (!class_code_.IsNull()) AddToWorklist(class_code_);
+  }
+
+  void VisitFunction(const Function& function) {
+    ASSERT(visitor_->IsFunctionVisitor());
+    visitor_->AsFunctionVisitor()->VisitFunction(function);
+    if (!visitor_->IsCodeVisitor() || !function.HasCode()) return;
+    function_code_ = function.CurrentCode();
+    AddToWorklist(function_code_);
+  }
+
+  void VisitCode(const Code& code) {
+    ASSERT(visitor_->IsCodeVisitor());
+    visitor_->AsCodeVisitor()->VisitCode(code);
+
+    // In the precompiler, some entries in the static calls table may need
+    // to be visited as they may not be reachable from other sources.
+    //
+    // TODO(dartbug.com/41636): Figure out why walking the static calls table
+    // in JIT mode with the DedupInstructions visitor fails, so we can remove
+    // the check for AOT mode.
+    static_calls_array_ = code.static_calls_target_table();
+    if (FLAG_precompiled_mode && !static_calls_array_.IsNull()) {
+      StaticCallsTable static_calls(static_calls_array_);
+      for (auto& view : static_calls) {
+        static_calls_table_entry_ =
+            view.Get<Code::kSCallTableCodeOrTypeTarget>();
+        if (static_calls_table_entry_.IsCode()) {
+          AddToWorklist(Code::Cast(static_calls_table_entry_));
+        }
+      }
+    }
+  }
+
+  Heap* const heap_;
+  ClassVisitor* const visitor_;
+  Worklist worklist_;
+  Object& class_object_;
+  Array& class_fields_;
+  Field& class_field_;
+  Array& class_functions_;
+  Function& class_function_;
+  Code& class_code_;
+  Code& function_code_;
+  Array& static_calls_array_;
+  Object& static_calls_table_entry_;
+  Object& worklist_entry_;
+};
+
+void ProgramVisitor::WalkProgram(Zone* zone,
+                                 Isolate* isolate,
+                                 ClassVisitor* visitor) {
+  auto const object_store = isolate->object_store();
+  auto const heap = isolate->heap();
+  ProgramWalker walker(zone, heap, visitor);
+
+  // Walk through the libraries and patches, looking for visitable objects.
+  const auto& libraries =
+      GrowableObjectArray::Handle(zone, object_store->libraries());
+  auto& lib = Library::Handle(zone);
+  auto& cls = Class::Handle(zone);
+  auto& entry = Object::Handle(zone);
+  auto& patches = GrowableObjectArray::Handle(zone);
 
   for (intptr_t i = 0; i < libraries.Length(); i++) {
     lib ^= libraries.At(i);
     ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
     while (it.HasNext()) {
       cls = it.GetNextClass();
-      visitor->Visit(cls);
+      walker.AddToWorklist(cls);
     }
     patches = lib.used_scripts();
     for (intptr_t j = 0; j < patches.Length(); j++) {
       entry = patches.At(j);
-      if (entry.IsClass()) {
-        visitor->Visit(Class::Cast(entry));
-      }
-    }
-  }
-}
-
-class ClassFunctionVisitor : public ClassVisitor {
- public:
-  ClassFunctionVisitor(Zone* zone, FunctionVisitor* visitor)
-      : visitor_(visitor),
-        functions_(Array::Handle(zone)),
-        function_(Function::Handle(zone)),
-        object_(Object::Handle(zone)),
-        fields_(Array::Handle(zone)),
-        field_(Field::Handle(zone)) {}
-
-  void Visit(const Class& cls) {
-    functions_ = cls.functions();
-    for (intptr_t j = 0; j < functions_.Length(); j++) {
-      function_ ^= functions_.At(j);
-      visitor_->Visit(function_);
-      if (function_.HasImplicitClosureFunction()) {
-        function_ = function_.ImplicitClosureFunction();
-        visitor_->Visit(function_);
-      }
-    }
-
-    functions_ = cls.invocation_dispatcher_cache();
-    for (intptr_t j = 0; j < functions_.Length(); j++) {
-      object_ = functions_.At(j);
-      if (object_.IsFunction()) {
-        function_ ^= functions_.At(j);
-        visitor_->Visit(function_);
-      }
-    }
-
-    fields_ = cls.fields();
-    for (intptr_t j = 0; j < fields_.Length(); j++) {
-      field_ ^= fields_.At(j);
-      if (field_.is_static() && field_.HasInitializerFunction()) {
-        function_ = field_.InitializerFunction();
-        visitor_->Visit(function_);
-      }
+      walker.AddToWorklist(entry);
     }
   }
 
- private:
-  FunctionVisitor* visitor_;
-  Array& functions_;
-  Function& function_;
-  Object& object_;
-  Array& fields_;
-  Field& field_;
-};
-
-void ProgramVisitor::VisitFunctions(FunctionVisitor* visitor) {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-
-  ClassFunctionVisitor class_visitor(zone, visitor);
-  VisitClasses(&class_visitor);
-
-  Function& function = Function::Handle(zone);
-  const GrowableObjectArray& closures = GrowableObjectArray::Handle(
-      zone, isolate->object_store()->closure_functions());
-  ASSERT(!closures.IsNull());
-  for (intptr_t i = 0; i < closures.Length(); i++) {
-    function ^= closures.At(i);
-    visitor->Visit(function);
-    ASSERT(!function.HasImplicitClosureFunction());
-  }
-
-  const auto& global_object_pool = ObjectPool::Handle(
-      zone, isolate->object_store()->global_object_pool());
+  // If there's a global object pool, add any visitable objects.
+  const auto& global_object_pool =
+      ObjectPool::Handle(zone, object_store->global_object_pool());
   if (!global_object_pool.IsNull()) {
     auto& object = Object::Handle(zone);
     for (intptr_t i = 0; i < global_object_pool.Length(); i++) {
       auto const type = global_object_pool.TypeAt(i);
       if (type != ObjectPool::EntryType::kTaggedObject) continue;
       object = global_object_pool.ObjectAt(i);
-      if (!object.IsFunction()) continue;
-      visitor->Visit(Function::Cast(object));
+      walker.AddToWorklist(object);
     }
   }
-}
 
-class FunctionCodeVisitor : public FunctionVisitor {
- public:
-  FunctionCodeVisitor(Zone* zone, CodeVisitor* visitor)
-      : visitor_(visitor), code_(Code::Handle(zone)) {}
-
-  void Visit(const Function& function) {
-    if (!function.HasCode()) return;
-    code_ = function.CurrentCode();
-    visitor_->Visit(code_);
+  if (visitor->IsFunctionVisitor()) {
+    // Function objects not necessarily reachable from classes.
+    auto& function = Function::Handle(zone);
+    const auto& closures =
+        GrowableObjectArray::Handle(zone, object_store->closure_functions());
+    ASSERT(!closures.IsNull());
+    for (intptr_t i = 0; i < closures.Length(); i++) {
+      function ^= closures.At(i);
+      walker.AddToWorklist(function);
+      ASSERT(!function.HasImplicitClosureFunction());
+    }
   }
 
- private:
-  CodeVisitor* const visitor_;
-  Code& code_;
-};
-
-void ProgramVisitor::VisitCode(CodeVisitor* visitor) {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-
-  FunctionCodeVisitor function_visitor(zone, visitor);
-  VisitFunctions(&function_visitor);
-
-  const auto& dispatch_table_entries = Array::Handle(
-      zone, isolate->object_store()->dispatch_table_code_entries());
-  if (!dispatch_table_entries.IsNull()) {
+  if (visitor->IsCodeVisitor()) {
+    // Code objects not necessarily reachable from functions.
     auto& code = Code::Handle(zone);
-    for (intptr_t i = 0; i < dispatch_table_entries.Length(); i++) {
-      code = Code::RawCast(dispatch_table_entries.At(i));
-      if (code.IsNull()) continue;
-      visitor->Visit(code);
+    const auto& dispatch_table_entries =
+        Array::Handle(zone, object_store->dispatch_table_code_entries());
+    if (!dispatch_table_entries.IsNull()) {
+      for (intptr_t i = 0; i < dispatch_table_entries.Length(); i++) {
+        code ^= dispatch_table_entries.At(i);
+        walker.AddToWorklist(code);
+      }
     }
   }
+
+  // Walk the program starting from any roots we added to the worklist.
+  walker.VisitWorklist();
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -168,16 +290,6 @@
   explicit Dedupper(Zone* zone) : zone_(zone), canonical_objects_(zone) {}
   virtual ~Dedupper() {}
 
-  void AddVMBaseObjects() {
-    const auto& object_table = Object::vm_isolate_snapshot_object_table();
-    auto& obj = Object::Handle(zone_);
-    for (intptr_t i = 0; i < object_table.Length(); i++) {
-      obj = object_table.At(i);
-      if (!ShouldAdd(obj)) continue;
-      AddCanonical(T::Cast(obj));
-    }
-  }
-
  protected:
   // Predicate for objects of type T. Must be overridden for class hierarchies
   // like Instance and AbstractType, as it defaults to class ID comparison.
@@ -200,7 +312,17 @@
     canonical_objects_.Insert(&T::ZoneHandle(zone_, obj.raw()));
   }
 
-  typename T::RawObjectType* Dedup(const T& obj) {
+  void AddVMBaseObjects() {
+    const auto& object_table = Object::vm_isolate_snapshot_object_table();
+    auto& obj = Object::Handle(zone_);
+    for (intptr_t i = 0; i < object_table.Length(); i++) {
+      obj = object_table.At(i);
+      if (!ShouldAdd(obj)) continue;
+      AddCanonical(T::Cast(obj));
+    }
+  }
+
+  typename T::ObjectPtrType Dedup(const T& obj) {
     if (ShouldAdd(obj)) {
       if (auto const canonical = canonical_objects_.LookupValue(&obj)) {
         return canonical->raw();
@@ -214,7 +336,7 @@
   DirectChainedHashMap<S> canonical_objects_;
 };
 
-void ProgramVisitor::BindStaticCalls() {
+void ProgramVisitor::BindStaticCalls(Zone* zone, Isolate* isolate) {
   class BindStaticCallsVisitor : public CodeVisitor {
    public:
     explicit BindStaticCallsVisitor(Zone* zone)
@@ -223,8 +345,10 @@
           target_(Object::Handle(zone)),
           target_code_(Code::Handle(zone)) {}
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       table_ = code.static_calls_target_table();
+      if (table_.IsNull()) return;
+
       StaticCallsTable static_calls(table_);
       // We can only remove the target table in precompiled mode, since more
       // calls may be added later otherwise.
@@ -233,14 +357,17 @@
         kind_and_offset_ = view.Get<Code::kSCallTableKindAndOffset>();
         auto const kind = Code::KindField::decode(kind_and_offset_.Value());
         if (kind != Code::kCallViaCode) {
-          ASSERT(!FLAG_precompiled_mode || kind == Code::kPcRelativeCall);
+          ASSERT(kind == Code::kPcRelativeCall ||
+                 kind == Code::kPcRelativeTailCall ||
+                 kind == Code::kPcRelativeTTSCall);
           only_call_via_code = false;
           continue;
         }
 
         target_ = view.Get<Code::kSCallTableFunctionTarget>();
         if (target_.IsNull()) {
-          target_ = view.Get<Code::kSCallTableCodeTarget>();
+          target_ =
+              Code::RawCast(view.Get<Code::kSCallTableCodeOrTypeTarget>());
           ASSERT(!Code::Cast(target_).IsFunctionCode());
           // Allocation stub or AllocateContext or AllocateArray or ...
           continue;
@@ -283,18 +410,13 @@
     Code& target_code_;
   };
 
-  auto const zone = Thread::Current()->zone();
   BindStaticCallsVisitor visitor(zone);
-  ProgramVisitor::VisitCode(&visitor);
+  WalkProgram(zone, isolate, &visitor);
 }
 
 DECLARE_FLAG(charp, write_v8_snapshot_profile_to);
 
-void ProgramVisitor::ShareMegamorphicBuckets() {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-
+void ProgramVisitor::ShareMegamorphicBuckets(Zone* zone, Isolate* isolate) {
   const GrowableObjectArray& table = GrowableObjectArray::Handle(
       zone, isolate->object_store()->megamorphic_cache_table());
   if (table.IsNull()) return;
@@ -424,7 +546,8 @@
 
 typedef DirectChainedHashMap<StackMapEntryKeyIntValueTrait> StackMapEntryIntMap;
 
-void ProgramVisitor::NormalizeAndDedupCompressedStackMaps() {
+void ProgramVisitor::NormalizeAndDedupCompressedStackMaps(Zone* zone,
+                                                          Isolate* isolate) {
   // Walks all the CSMs in Code objects and collects their entry information
   // for consolidation.
   class CollectStackMapEntriesVisitor : public CodeVisitor {
@@ -440,7 +563,7 @@
       ASSERT(old_global_table_.IsNull() || old_global_table_.IsGlobalTable());
     }
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       compressed_stackmaps_ = code.compressed_stackmaps();
       CompressedStackMapsIterator it(compressed_stackmaps_, old_global_table_);
       while (it.MoveNext()) {
@@ -460,7 +583,7 @@
     // Creates a new global table of stack map information. Also adds the
     // offsets of encoded StackMapEntry objects to entry_offsets for use
     // when normalizing CompressedStackMaps.
-    RawCompressedStackMaps* CreateGlobalTable(
+    CompressedStackMapsPtr CreateGlobalTable(
         StackMapEntryIntMap* entry_offsets) {
       ASSERT(entry_offsets->IsEmpty());
       if (collected_entries_.length() == 0) return CompressedStackMaps::null();
@@ -505,18 +628,40 @@
         public Dedupper<CompressedStackMaps,
                         PointerKeyValueTrait<const CompressedStackMaps>> {
    public:
-    NormalizeAndDedupCompressedStackMapsVisitor(
-        Zone* zone,
-        const CompressedStackMaps& global_table,
-        const StackMapEntryIntMap& entry_offsets)
+    NormalizeAndDedupCompressedStackMapsVisitor(Zone* zone, Isolate* isolate)
         : Dedupper(zone),
-          old_global_table_(global_table),
-          entry_offsets_(entry_offsets),
+          old_global_table_(CompressedStackMaps::Handle(
+              zone,
+              isolate->object_store()->canonicalized_stack_map_entries())),
+          entry_offsets_(zone),
           maps_(CompressedStackMaps::Handle(zone)) {
       ASSERT(old_global_table_.IsNull() || old_global_table_.IsGlobalTable());
+      // The stack map normalization and deduplication happens in two phases:
+      //
+      // 1) Visit all CompressedStackMaps (CSM) objects and collect individual
+      // entry info as canonicalized StackMapEntries (SMEs). Also record the
+      // frequency the same entry info was seen across all CSMs in each SME.
+
+      CollectStackMapEntriesVisitor collect_visitor(zone, old_global_table_);
+      WalkProgram(zone, isolate, &collect_visitor);
+
+      // The results of phase 1 are used to create a new global table with
+      // entries sorted by decreasing frequency, so that entries that appear
+      // more often in CSMs have smaller payload offsets (less bytes used in
+      // the LEB128 encoding). The new global table is put into place
+      // immediately, as we already have a handle on the old table.
+
+      const auto& new_global_table = CompressedStackMaps::Handle(
+          zone, collect_visitor.CreateGlobalTable(&entry_offsets_));
+      isolate->object_store()->set_canonicalized_stack_map_entries(
+          new_global_table);
+
+      // 2) Visit all CSMs and replace each with a canonicalized normalized
+      // version that uses the new global table for non-PC offset entry
+      // information. This part is done in VisitCode.
     }
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       maps_ = code.compressed_stackmaps();
       if (maps_.IsNull()) return;
       // First check is to make sure [maps] hasn't already been normalized,
@@ -532,7 +677,7 @@
 
    private:
     // Creates a normalized CSM from the given non-normalized CSM.
-    RawCompressedStackMaps* NormalizeEntries(const CompressedStackMaps& maps) {
+    CompressedStackMapsPtr NormalizeEntries(const CompressedStackMaps& maps) {
       GrowableArray<uint8_t> new_payload;
       CompressedStackMapsIterator it(maps, old_global_table_);
       intptr_t last_offset = 0;
@@ -549,42 +694,12 @@
     }
 
     const CompressedStackMaps& old_global_table_;
-    const StackMapEntryIntMap& entry_offsets_;
+    StackMapEntryIntMap entry_offsets_;
     CompressedStackMaps& maps_;
   };
 
-  // The stack map deduplication happens in two phases:
-  // 1) Visit all CompressedStackMaps (CSM) objects and collect individual entry
-  //    info as canonicalized StackMapEntries (SMEs). Also record the number of
-  //    times the same entry info was seen across all CSMs in each SME.
-  //
-  // The results of phase 1 are used to create a new global table with entries
-  // sorted by decreasing frequency, so that entries that appear more often in
-  // CSMs have smaller payload offsets (less bytes used in the LEB128 encoding).
-  //
-  // 2) Visit all CSMs and replace each with a canonicalized normalized version
-  //    that uses the new global table for non-PC offset entry information.
-  Thread* const t = Thread::Current();
-  StackZone temp_zone(t);
-  HandleScope temp_handles(t);
-  Zone* zone = temp_zone.GetZone();
-  auto object_store = t->isolate()->object_store();
-  const auto& old_global_table = CompressedStackMaps::Handle(
-      zone, object_store->canonicalized_stack_map_entries());
-  CollectStackMapEntriesVisitor collect_visitor(zone, old_global_table);
-  ProgramVisitor::VisitCode(&collect_visitor);
-
-  // We retrieve the new offsets for CSM entries by creating the new global
-  // table now. We go ahead and put it in place, as we already have a handle
-  // on the old table that we can pass to the normalizing visitor.
-  StackMapEntryIntMap entry_offsets(zone);
-  const auto& new_global_table = CompressedStackMaps::Handle(
-      zone, collect_visitor.CreateGlobalTable(&entry_offsets));
-  object_store->set_canonicalized_stack_map_entries(new_global_table);
-
-  NormalizeAndDedupCompressedStackMapsVisitor dedup_visitor(
-      zone, old_global_table, entry_offsets);
-  ProgramVisitor::VisitCode(&dedup_visitor);
+  NormalizeAndDedupCompressedStackMapsVisitor dedup_visitor(zone, isolate);
+  WalkProgram(zone, isolate, &dedup_visitor);
 }
 
 class PcDescriptorsKeyValueTrait {
@@ -605,24 +720,28 @@
   }
 };
 
-void ProgramVisitor::DedupPcDescriptors() {
+void ProgramVisitor::DedupPcDescriptors(Zone* zone, Isolate* isolate) {
   class DedupPcDescriptorsVisitor
       : public CodeVisitor,
-        public Dedupper<PcDescriptors, PcDescriptorsKeyValueTrait>,
-        public FunctionVisitor {
+        public Dedupper<PcDescriptors, PcDescriptorsKeyValueTrait> {
    public:
     explicit DedupPcDescriptorsVisitor(Zone* zone)
         : Dedupper(zone),
           bytecode_(Bytecode::Handle(zone)),
-          pc_descriptor_(PcDescriptors::Handle(zone)) {}
+          pc_descriptor_(PcDescriptors::Handle(zone)) {
+      if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
+        // Prefer existing objects in the VM isolate.
+        AddVMBaseObjects();
+      }
+    }
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       pc_descriptor_ = code.pc_descriptors();
       pc_descriptor_ = Dedup(pc_descriptor_);
       code.set_pc_descriptors(pc_descriptor_);
     }
 
-    void Visit(const Function& function) {
+    void VisitFunction(const Function& function) {
       bytecode_ = function.bytecode();
       if (bytecode_.IsNull()) return;
       if (bytecode_.InVMIsolateHeap()) return;
@@ -636,16 +755,8 @@
     PcDescriptors& pc_descriptor_;
   };
 
-  auto const zone = Thread::Current()->zone();
   DedupPcDescriptorsVisitor visitor(zone);
-  if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
-    // Prefer existing objects in the VM isolate.
-    visitor.AddVMBaseObjects();
-  }
-  // The function iteration handles the bytecode only, leaving code-related
-  // work for the code iteration.
-  ProgramVisitor::VisitFunctions(&visitor);
-  ProgramVisitor::VisitCode(&visitor);
+  WalkProgram(zone, isolate, &visitor);
 }
 
 class TypedDataKeyValueTrait {
@@ -674,7 +785,7 @@
   bool IsCorrectType(const Object& obj) const { return obj.IsTypedData(); }
 };
 
-void ProgramVisitor::DedupDeoptEntries() {
+void ProgramVisitor::DedupDeoptEntries(Zone* zone, Isolate* isolate) {
   class DedupDeoptEntriesVisitor : public CodeVisitor,
                                    public TypedDataDedupper {
    public:
@@ -685,7 +796,7 @@
           offset_(Smi::Handle(zone)),
           reason_and_flags_(Smi::Handle(zone)) {}
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       deopt_table_ = code.deopt_info_array();
       if (deopt_table_.IsNull()) return;
       intptr_t length = DeoptTable::GetLength(deopt_table_);
@@ -707,12 +818,13 @@
     Smi& reason_and_flags_;
   };
 
-  DedupDeoptEntriesVisitor visitor(Thread::Current()->zone());
-  ProgramVisitor::VisitCode(&visitor);
+  if (FLAG_precompiled_mode) return;
+  DedupDeoptEntriesVisitor visitor(zone);
+  WalkProgram(zone, isolate, &visitor);
 }
 
 #if defined(DART_PRECOMPILER)
-void ProgramVisitor::DedupCatchEntryMovesMaps() {
+void ProgramVisitor::DedupCatchEntryMovesMaps(Zone* zone, Isolate* isolate) {
   class DedupCatchEntryMovesMapsVisitor : public CodeVisitor,
                                           public TypedDataDedupper {
    public:
@@ -720,7 +832,7 @@
         : TypedDataDedupper(zone),
           catch_entry_moves_maps_(TypedData::Handle(zone)) {}
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       catch_entry_moves_maps_ = code.catch_entry_moves_maps();
       catch_entry_moves_maps_ = Dedup(catch_entry_moves_maps_);
       code.set_catch_entry_moves_maps(catch_entry_moves_maps_);
@@ -731,8 +843,8 @@
   };
 
   if (!FLAG_precompiled_mode) return;
-  DedupCatchEntryMovesMapsVisitor visitor(Thread::Current()->zone());
-  ProgramVisitor::VisitCode(&visitor);
+  DedupCatchEntryMovesMapsVisitor visitor(zone);
+  WalkProgram(zone, isolate, &visitor);
 }
 
 class UnlinkedCallKeyValueTrait {
@@ -753,15 +865,20 @@
   }
 };
 
-void ProgramVisitor::DedupUnlinkedCalls() {
+void ProgramVisitor::DedupUnlinkedCalls(Zone* zone, Isolate* isolate) {
   class DedupUnlinkedCallsVisitor
       : public CodeVisitor,
         public Dedupper<UnlinkedCall, UnlinkedCallKeyValueTrait> {
    public:
-    explicit DedupUnlinkedCallsVisitor(Zone* zone)
+    explicit DedupUnlinkedCallsVisitor(Zone* zone, Isolate* isolate)
         : Dedupper(zone),
           entry_(Object::Handle(zone)),
-          pool_(ObjectPool::Handle(zone)) {}
+          pool_(ObjectPool::Handle(zone)) {
+      auto& gop = ObjectPool::Handle(
+          zone, isolate->object_store()->global_object_pool());
+      ASSERT_EQUAL(!gop.IsNull(), FLAG_use_bare_instructions);
+      DedupPool(gop);
+    }
 
     void DedupPool(const ObjectPool& pool) {
       if (pool.IsNull()) return;
@@ -776,7 +893,7 @@
       }
     }
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       pool_ = code.object_pool();
       DedupPool(pool_);
     }
@@ -788,16 +905,7 @@
 
   if (!FLAG_precompiled_mode) return;
 
-  auto const t = Thread::Current();
-  auto Z = t->zone();
-  auto const I = t->isolate();
-
-  DedupUnlinkedCallsVisitor deduper(Z);
-  auto& gop = ObjectPool::Handle(Z, I->object_store()->global_object_pool());
-  ASSERT_EQUAL(gop.IsNull(), !FLAG_use_bare_instructions);
-  if (FLAG_use_bare_instructions) {
-    deduper.DedupPool(gop);
-  }
+  DedupUnlinkedCallsVisitor deduper(zone, isolate);
 
   // Note: in bare instructions mode we can still have object pools attached
   // to code objects and these pools need to be deduplicated.
@@ -807,10 +915,10 @@
   // to produce more informative snapshot profile.
   if (!FLAG_use_bare_instructions ||
       FLAG_write_v8_snapshot_profile_to != nullptr) {
-    VisitCode(&deduper);
+    WalkProgram(zone, isolate, &deduper);
   }
 }
-#endif  // !defined(DART_PRECOMPILER)
+#endif  // defined(DART_PRECOMPILER)
 
 class CodeSourceMapKeyValueTrait {
  public:
@@ -834,15 +942,20 @@
   }
 };
 
-void ProgramVisitor::DedupCodeSourceMaps() {
+void ProgramVisitor::DedupCodeSourceMaps(Zone* zone, Isolate* isolate) {
   class DedupCodeSourceMapsVisitor
       : public CodeVisitor,
         public Dedupper<CodeSourceMap, CodeSourceMapKeyValueTrait> {
    public:
     explicit DedupCodeSourceMapsVisitor(Zone* zone)
-        : Dedupper(zone), code_source_map_(CodeSourceMap::Handle(zone)) {}
+        : Dedupper(zone), code_source_map_(CodeSourceMap::Handle(zone)) {
+      if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
+        // Prefer existing objects in the VM isolate.
+        AddVMBaseObjects();
+      }
+    }
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       code_source_map_ = code.code_source_map();
       code_source_map_ = Dedup(code_source_map_);
       code.set_code_source_map(code_source_map_);
@@ -852,13 +965,8 @@
     CodeSourceMap& code_source_map_;
   };
 
-  auto const zone = Thread::Current()->zone();
   DedupCodeSourceMapsVisitor visitor(zone);
-  if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
-    // Prefer existing objects in the VM isolate.
-    visitor.AddVMBaseObjects();
-  }
-  ProgramVisitor::VisitCode(&visitor);
+  WalkProgram(zone, isolate, &visitor);
 }
 
 class ArrayKeyValueTrait {
@@ -887,17 +995,18 @@
   }
 };
 
-void ProgramVisitor::DedupLists() {
+void ProgramVisitor::DedupLists(Zone* zone, Isolate* isolate) {
   class DedupListsVisitor : public CodeVisitor,
-                            public Dedupper<Array, ArrayKeyValueTrait>,
-                            public FunctionVisitor {
+                            public Dedupper<Array, ArrayKeyValueTrait> {
    public:
     explicit DedupListsVisitor(Zone* zone)
         : Dedupper(zone),
           list_(Array::Handle(zone)),
           function_(Function::Handle(zone)) {}
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
+      if (!code.IsFunctionCode()) return;
+
       list_ = code.inlined_id_to_function();
       list_ = Dedup(list_);
       code.set_inlined_id_to_function(list_);
@@ -911,7 +1020,7 @@
       code.set_static_calls_target_table(list_);
     }
 
-    void Visit(const Function& function) {
+    void VisitFunction(const Function& function) {
       list_ = PrepareParameterTypes(function);
       list_ = Dedup(list_);
       function.set_parameter_types(list_);
@@ -924,7 +1033,7 @@
    private:
     bool IsCorrectType(const Object& obj) const { return obj.IsArray(); }
 
-    RawArray* PrepareParameterTypes(const Function& function) {
+    ArrayPtr PrepareParameterTypes(const Function& function) {
       list_ = function.parameter_types();
       // Preserve parameter types in the JIT. Needed in case of recompilation
       // in checked mode, or if available to mirrors, or for copied types to
@@ -942,7 +1051,7 @@
       return list_.raw();
     }
 
-    RawArray* PrepareParameterNames(const Function& function) {
+    ArrayPtr PrepareParameterNames(const Function& function) {
       list_ = function.parameter_names();
       // Preserve parameter names in case of recompilation for the JIT. Also
       // avoid attempting to change read-only VM objects for de-duplication.
@@ -961,9 +1070,8 @@
     Function& function_;
   };
 
-  DedupListsVisitor visitor(Thread::Current()->zone());
-  ProgramVisitor::VisitFunctions(&visitor);
-  ProgramVisitor::VisitCode(&visitor);
+  DedupListsVisitor visitor(zone);
+  WalkProgram(zone, isolate, &visitor);
 }
 
 // Traits for comparing two [Instructions] objects for equality, which is
@@ -1046,9 +1154,9 @@
     return Instructions::Equals(pair->instructions(), key->instructions());
   }
 };
-#endif  // defined(DART_PRECOMPILER)
+#endif
 
-void ProgramVisitor::DedupInstructions() {
+void ProgramVisitor::DedupInstructions(Zone* zone, Isolate* isolate) {
   class DedupInstructionsVisitor
       : public CodeVisitor,
         public Dedupper<Instructions, InstructionsKeyValueTrait>,
@@ -1056,111 +1164,118 @@
    public:
     explicit DedupInstructionsVisitor(Zone* zone)
         : Dedupper(zone),
-          function_(Function::Handle(zone)),
-          instructions_(Instructions::Handle(zone)) {}
+          code_(Code::Handle(zone)),
+          instructions_(Instructions::Handle(zone)) {
+      if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
+        // Prefer existing objects in the VM isolate.
+        Dart::vm_isolate()->heap()->VisitObjectsImagePages(this);
+      }
+    }
 
-    void VisitObject(RawObject* obj) {
+    void VisitObject(ObjectPtr obj) {
       if (!obj->IsInstructions()) return;
       instructions_ = Instructions::RawCast(obj);
       AddCanonical(instructions_);
     }
 
-    void Visit(const Code& code) {
+    void VisitFunction(const Function& function) {
+      if (!function.HasCode()) return;
+      code_ = function.CurrentCode();
+      // This causes the code to be visited once here and once directly in the
+      // ProgramWalker, but as long as the deduplication process is idempotent,
+      // the cached entry points won't change during the second visit.
+      VisitCode(code_);
+      function.SetInstructions(code_);  // Update cached entry point.
+    }
+
+    void VisitCode(const Code& code) {
       instructions_ = code.instructions();
       instructions_ = Dedup(instructions_);
+      code.set_instructions(instructions_);
+      if (code.IsDisabled()) {
+        instructions_ = code.active_instructions();
+        instructions_ = Dedup(instructions_);
+      }
       code.SetActiveInstructions(instructions_,
                                  code.UncheckedEntryPointOffset());
-      code.set_instructions(instructions_);
-      if (!code.IsFunctionCode()) return;
-      function_ = code.function();
-      if (function_.IsNull()) return;
-      function_.SetInstructions(code);  // Update cached entry point.
     }
 
    private:
-    Function& function_;
+    Code& code_;
     Instructions& instructions_;
   };
 
-  DedupInstructionsVisitor visitor(Thread::Current()->zone());
-  if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
-    // Prefer existing objects in the VM isolate.
-    Dart::vm_isolate()->heap()->VisitObjectsImagePages(&visitor);
-  }
-  ProgramVisitor::VisitCode(&visitor);
-}
-
-void ProgramVisitor::DedupInstructionsWithSameMetadata() {
 #if defined(DART_PRECOMPILER)
   class DedupInstructionsWithSameMetadataVisitor
       : public CodeVisitor,
-        public Dedupper<Code, CodeKeyValueTrait>,
-        public ObjectVisitor {
+        public Dedupper<Code, CodeKeyValueTrait> {
    public:
     explicit DedupInstructionsWithSameMetadataVisitor(Zone* zone)
         : Dedupper(zone),
           canonical_(Code::Handle(zone)),
-          function_(Function::Handle(zone)),
+          code_(Code::Handle(zone)),
           instructions_(Instructions::Handle(zone)) {}
 
-    void VisitObject(RawObject* obj) {
-      if (!obj->IsCode()) return;
-      canonical_ = Code::RawCast(obj);
-      AddCanonical(canonical_);
+    void VisitFunction(const Function& function) {
+      if (!function.HasCode()) return;
+      code_ = function.CurrentCode();
+      // This causes the code to be visited once here and once directly in the
+      // ProgramWalker, but as long as the deduplication process is idempotent,
+      // the cached entry points won't change during the second visit.
+      VisitCode(code_);
+      function.SetInstructions(code_);  // Update cached entry point.
     }
 
-    void Visit(const Code& code) {
+    void VisitCode(const Code& code) {
       if (code.IsDisabled()) return;
       canonical_ = Dedup(code);
       instructions_ = canonical_.instructions();
       code.SetActiveInstructions(instructions_,
                                  code.UncheckedEntryPointOffset());
       code.set_instructions(instructions_);
-      if (!code.IsFunctionCode()) return;
-      function_ = code.function();
-      if (function_.IsNull()) return;
-      function_.SetInstructions(code);  // Update cached entry point.
     }
 
    private:
     bool CanCanonicalize(const Code& code) const { return !code.IsDisabled(); }
 
     Code& canonical_;
-    Function& function_;
+    Code& code_;
     Instructions& instructions_;
   };
 
-  DedupInstructionsWithSameMetadataVisitor visitor(Thread::Current()->zone());
-  ProgramVisitor::VisitCode(&visitor);
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    DedupInstructionsWithSameMetadataVisitor visitor(zone);
+    return WalkProgram(zone, isolate, &visitor);
+  }
 #endif  // defined(DART_PRECOMPILER)
+
+  DedupInstructionsVisitor visitor(zone);
+  WalkProgram(zone, isolate, &visitor);
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-void ProgramVisitor::Dedup() {
+void ProgramVisitor::Dedup(Thread* thread) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  Thread* thread = Thread::Current();
+  auto const isolate = thread->isolate();
   StackZone stack_zone(thread);
   HANDLESCOPE(thread);
+  auto const zone = thread->zone();
 
-  BindStaticCalls();
-  ShareMegamorphicBuckets();
-  NormalizeAndDedupCompressedStackMaps();
-  DedupPcDescriptors();
-  NOT_IN_PRECOMPILED(DedupDeoptEntries());
+  BindStaticCalls(zone, isolate);
+  ShareMegamorphicBuckets(zone, isolate);
+  NormalizeAndDedupCompressedStackMaps(zone, isolate);
+  DedupPcDescriptors(zone, isolate);
+  DedupDeoptEntries(zone, isolate);
 #if defined(DART_PRECOMPILER)
-  DedupCatchEntryMovesMaps();
-  DedupUnlinkedCalls();
+  DedupCatchEntryMovesMaps(zone, isolate);
+  DedupUnlinkedCalls(zone, isolate);
 #endif
-  DedupCodeSourceMaps();
-  DedupLists();
+  DedupCodeSourceMaps(zone, isolate);
+  DedupLists(zone, isolate);
 
   // Reduces binary size but obfuscates profiler results.
   if (FLAG_dedup_instructions) {
-    if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-      DedupInstructionsWithSameMetadata();
-    } else {
-      DedupInstructions();
-    }
+    DedupInstructions(zone, isolate);
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
diff --git a/runtime/vm/program_visitor.h b/runtime/vm/program_visitor.h
index 7c7cf0e..e10ffd2 100644
--- a/runtime/vm/program_visitor.h
+++ b/runtime/vm/program_visitor.h
@@ -9,50 +9,109 @@
 
 namespace dart {
 
+// Currently, we have three types of abstract visitors that can be extended and
+// used for program walking:
+//
+// * ClassVisitor, a visitor for classes in the program.
+// * FunctionVisitor, a visitor for functions in the program.
+// * CodeVisitor, a visitor for code objects in the program.
+//
+// To find the functions in a program, we must traverse the classes in the
+// program, and similarly for code objects and functions. Thus, each
+// FunctionVisitor is also a ClassVisitor, and each CodeVisitor is also a
+// FunctionVisitor (and thus a ClassVisitor).
+//
+// Only the most specific visitor method is abstract. Derived visitors have a
+// default empty implementation for base visitor methods to limit boilerplate
+// needed when extending. For example, subclasses of CodeVisitor that only do
+// per-Code work do not need to add empty implementations for VisitClass and
+// VisitFunction.
+//
+// There are no guarantees for the order in which objects of a given type will
+// be visited, but each object will be visited only once. In addition, each
+// object is visited before any visitable sub-objects it contains. For example,
+// this means a FunctionVisitor with a VisitClass implementation that drops
+// methods from a class will not visit the dropped methods unless they are also
+// found via another source of function objects.
+//
+// Note that WalkProgram only visits objects in the isolate heap. Deduplicating
+// visitors that want to use VM objects as canonical when possible should
+// instead add the appropriate VM objects first in their constructor.
+
 class Class;
 class Code;
 class Function;
 
-template <typename T>
-class Visitor : public ValueObject {
+class CodeVisitor;
+class FunctionVisitor;
+
+class ClassVisitor : public ValueObject {
  public:
-  virtual ~Visitor() {}
-  virtual void Visit(const T& obj) = 0;
+  virtual ~ClassVisitor() {}
+
+  virtual bool IsFunctionVisitor() const { return false; }
+  const FunctionVisitor* AsFunctionVisitor() const {
+    return const_cast<FunctionVisitor*>(
+      const_cast<ClassVisitor*>(this)->AsFunctionVisitor());
+  }
+  FunctionVisitor* AsFunctionVisitor() {
+    if (!IsFunctionVisitor()) return nullptr;
+    return reinterpret_cast<FunctionVisitor*>(this);
+  }
+
+  virtual bool IsCodeVisitor() const { return false; }
+  const CodeVisitor* AsCodeVisitor() const {
+    return const_cast<CodeVisitor*>(
+      const_cast<ClassVisitor*>(this)->AsCodeVisitor());
+  }
+  CodeVisitor* AsCodeVisitor() {
+    if (!IsCodeVisitor()) return nullptr;
+    return reinterpret_cast<CodeVisitor*>(this);
+  }
+
+  virtual void VisitClass(const Class& cls) = 0;
 };
 
-using ClassVisitor = Visitor<Class>;
-using CodeVisitor = Visitor<Code>;
-using FunctionVisitor = Visitor<Function>;
+class FunctionVisitor : public ClassVisitor {
+ public:
+  bool IsFunctionVisitor() const { return true; }
+  virtual void VisitClass(const Class& cls) {}
+  virtual void VisitFunction(const Function& function) = 0;
+};
+
+class CodeVisitor : public FunctionVisitor {
+ public:
+  bool IsCodeVisitor() const { return true; }
+  virtual void VisitFunction(const Function& function) {}
+  virtual void VisitCode(const Code& code) = 0;
+};
+
+class Thread;
+class Isolate;
 
 class ProgramVisitor : public AllStatic {
  public:
-  // Currently visits the following code objects:
-  // * Code objects for functions (visited via VisitFunctions) where HasCode()
-  //   is true.
-  // * Code objects for entries in the dispatch table (if applicable).
-  //
-  // Notably, it does not visit any stubs not reachable via these routes.
-  static void VisitCode(CodeVisitor* visitor);
-  static void VisitFunctions(FunctionVisitor* visitor);
-  static void VisitClasses(ClassVisitor* visitor);
+  // Walks all non-null class, function, and code objects in the program as
+  // necessary for the given visitor.
+  static void WalkProgram(Zone* zone, Isolate* isolate, ClassVisitor* visitor);
 
-  static void Dedup();
+  static void Dedup(Thread* thread);
 
  private:
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static void BindStaticCalls();
-  static void ShareMegamorphicBuckets();
-  static void NormalizeAndDedupCompressedStackMaps();
-  static void DedupPcDescriptors();
-  static void DedupDeoptEntries();
+  static void BindStaticCalls(Zone* zone, Isolate* isolate);
+  static void ShareMegamorphicBuckets(Zone* zone, Isolate* isolate);
+  static void NormalizeAndDedupCompressedStackMaps(Zone* zone,
+                                                   Isolate* isolate);
+  static void DedupPcDescriptors(Zone* zone, Isolate* isolate);
+  static void DedupDeoptEntries(Zone* zone, Isolate* isolate);
 #if defined(DART_PRECOMPILER)
-  static void DedupCatchEntryMovesMaps();
-  static void DedupUnlinkedCalls();
+  static void DedupCatchEntryMovesMaps(Zone* zone, Isolate* isolate);
+  static void DedupUnlinkedCalls(Zone* zone, Isolate* isolate);
 #endif
-  static void DedupCodeSourceMaps();
-  static void DedupLists();
-  static void DedupInstructions();
-  static void DedupInstructionsWithSameMetadata();
+  static void DedupCodeSourceMaps(Zone* zone, Isolate* isolate);
+  static void DedupLists(Zone* zone, Isolate* isolate);
+  static void DedupInstructions(Zone* zone, Isolate* isolate);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 };
 
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 2519af7..5611f2c 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -16,7 +16,7 @@
 
 namespace dart {
 
-bool RawObject::InVMIsolateHeap() const {
+bool ObjectLayout::InVMIsolateHeap() const {
   // All "vm-isolate" objects are pre-marked and in old space
   // (see [Object::FinalizeVMIsolate]).
   if (!IsOldObject() || !IsMarked()) return false;
@@ -26,22 +26,26 @@
   return heap->old_space()->ContainsUnsafe(ToAddr(this));
 }
 
-void RawObject::Validate(IsolateGroup* isolate_group) const {
-  if (Object::void_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) {
-    // Validation relies on properly initialized class classes. Skip if the
-    // VM is still being initialized.
-    return;
-  }
+void ObjectPtr::Validate(IsolateGroup* isolate_group) const {
   // All Smi values are valid.
   if (!IsHeapObject()) {
     return;
   }
   // Slightly more readable than a segfault.
-  if (this == reinterpret_cast<RawObject*>(kHeapObjectTag)) {
+  if (tagged_pointer_ == kHeapObjectTag) {
     FATAL("RAW_NULL encountered");
   }
+  ptr()->Validate(isolate_group);
+}
+
+void ObjectLayout::Validate(IsolateGroup* isolate_group) const {
+  if (static_cast<uword>(Object::void_class_) == kHeapObjectTag) {
+    // Validation relies on properly initialized class classes. Skip if the
+    // VM is still being initialized.
+    return;
+  }
   // Validate that the tags_ field is sensible.
-  uint32_t tags = ptr()->tags_;
+  uint32_t tags = tags_;
   if (IsNewObject()) {
     if (!NewBit::decode(tags)) {
       FATAL1("New object missing kNewBit: %x\n", tags);
@@ -64,16 +68,16 @@
     }
   }
   const intptr_t class_id = ClassIdTag::decode(tags);
-  if (!isolate_group->class_table()->IsValidIndex(class_id)) {
+  if (!isolate_group->shared_class_table()->IsValidIndex(class_id)) {
     FATAL1("Invalid class id encountered %" Pd "\n", class_id);
   }
   if (class_id == kNullCid &&
-      isolate_group->class_table()->HasValidClassAt(class_id)) {
+      isolate_group->shared_class_table()->HasValidClassAt(class_id)) {
     // Null class not yet initialized; skip.
     return;
   }
   intptr_t size_from_tags = SizeTag::decode(tags);
-  intptr_t size_from_class = HeapSizeFromClass();
+  intptr_t size_from_class = HeapSizeFromClass(tags);
   if ((size_from_tags != 0) && (size_from_tags != size_from_class)) {
     FATAL3(
         "Inconsistent size encountered "
@@ -85,82 +89,79 @@
 // Can't look at the class object because it can be called during
 // compaction when the class objects are moving. Can use the class
 // id in the header and the sizes in the Class Table.
-intptr_t RawObject::HeapSizeFromClass() const {
-  // Only reasonable to be called on heap objects.
-  ASSERT(IsHeapObject());
-
-  intptr_t class_id = GetClassId();
+// Cannot deference ptr()->tags_. May dereference other parts of the object.
+intptr_t ObjectLayout::HeapSizeFromClass(uint32_t tags) const {
+  intptr_t class_id = ClassIdTag::decode(tags);
   intptr_t instance_size = 0;
   switch (class_id) {
     case kCodeCid: {
-      const RawCode* raw_code = reinterpret_cast<const RawCode*>(this);
+      const CodePtr raw_code = static_cast<const CodePtr>(this);
       intptr_t pointer_offsets_length =
           Code::PtrOffBits::decode(raw_code->ptr()->state_bits_);
       instance_size = Code::InstanceSize(pointer_offsets_length);
       break;
     }
     case kInstructionsCid: {
-      const RawInstructions* raw_instructions =
-          reinterpret_cast<const RawInstructions*>(this);
+      const InstructionsPtr raw_instructions =
+          static_cast<const InstructionsPtr>(this);
       intptr_t instructions_size = Instructions::Size(raw_instructions);
       instance_size = Instructions::InstanceSize(instructions_size);
       break;
     }
     case kInstructionsSectionCid: {
-      const RawInstructionsSection* raw_section =
-          reinterpret_cast<const RawInstructionsSection*>(this);
+      const InstructionsSectionPtr raw_section =
+          static_cast<const InstructionsSectionPtr>(this);
       intptr_t section_size = InstructionsSection::Size(raw_section);
       instance_size = InstructionsSection::InstanceSize(section_size);
       break;
     }
     case kContextCid: {
-      const RawContext* raw_context = reinterpret_cast<const RawContext*>(this);
+      const ContextPtr raw_context = static_cast<const ContextPtr>(this);
       intptr_t num_variables = raw_context->ptr()->num_variables_;
       instance_size = Context::InstanceSize(num_variables);
       break;
     }
     case kContextScopeCid: {
-      const RawContextScope* raw_context_scope =
-          reinterpret_cast<const RawContextScope*>(this);
+      const ContextScopePtr raw_context_scope =
+          static_cast<const ContextScopePtr>(this);
       intptr_t num_variables = raw_context_scope->ptr()->num_variables_;
       instance_size = ContextScope::InstanceSize(num_variables);
       break;
     }
     case kOneByteStringCid: {
-      const RawOneByteString* raw_string =
-          reinterpret_cast<const RawOneByteString*>(this);
+      const OneByteStringPtr raw_string =
+          static_cast<const OneByteStringPtr>(this);
       intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
       instance_size = OneByteString::InstanceSize(string_length);
       break;
     }
     case kTwoByteStringCid: {
-      const RawTwoByteString* raw_string =
-          reinterpret_cast<const RawTwoByteString*>(this);
+      const TwoByteStringPtr raw_string =
+          static_cast<const TwoByteStringPtr>(this);
       intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
       instance_size = TwoByteString::InstanceSize(string_length);
       break;
     }
     case kArrayCid:
     case kImmutableArrayCid: {
-      const RawArray* raw_array = reinterpret_cast<const RawArray*>(this);
+      const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
       intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
       instance_size = Array::InstanceSize(array_length);
       break;
     }
     case kObjectPoolCid: {
-      const RawObjectPool* raw_object_pool =
-          reinterpret_cast<const RawObjectPool*>(this);
+      const ObjectPoolPtr raw_object_pool =
+          static_cast<const ObjectPoolPtr>(this);
       intptr_t len = raw_object_pool->ptr()->length_;
       instance_size = ObjectPool::InstanceSize(len);
       break;
     }
 #define SIZE_FROM_CLASS(clazz) case kTypedData##clazz##Cid:
       CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
-        const RawTypedData* raw_obj =
-            reinterpret_cast<const RawTypedData*>(this);
-        intptr_t cid = raw_obj->GetClassId();
+        const TypedDataPtr raw_obj = static_cast<const TypedDataPtr>(this);
         intptr_t array_len = Smi::Value(raw_obj->ptr()->length_);
-        intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid);
+        intptr_t lengthInBytes =
+            array_len * TypedData::ElementSizeInBytes(class_id);
         instance_size = TypedData::InstanceSize(lengthInBytes);
         break;
       }
@@ -169,55 +170,55 @@
       instance_size = Pointer::InstanceSize();
       break;
     case kTypeArgumentsCid: {
-      const RawTypeArguments* raw_array =
-          reinterpret_cast<const RawTypeArguments*>(this);
+      const TypeArgumentsPtr raw_array =
+          static_cast<const TypeArgumentsPtr>(this);
       intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
       instance_size = TypeArguments::InstanceSize(array_length);
       break;
     }
     case kPcDescriptorsCid: {
-      const RawPcDescriptors* raw_descriptors =
-          reinterpret_cast<const RawPcDescriptors*>(this);
+      const PcDescriptorsPtr raw_descriptors =
+          static_cast<const PcDescriptorsPtr>(this);
       intptr_t length = raw_descriptors->ptr()->length_;
       instance_size = PcDescriptors::InstanceSize(length);
       break;
     }
     case kCodeSourceMapCid: {
-      const RawCodeSourceMap* raw_code_source_map =
-          reinterpret_cast<const RawCodeSourceMap*>(this);
+      const CodeSourceMapPtr raw_code_source_map =
+          static_cast<const CodeSourceMapPtr>(this);
       intptr_t length = raw_code_source_map->ptr()->length_;
       instance_size = CodeSourceMap::InstanceSize(length);
       break;
     }
     case kCompressedStackMapsCid: {
-      const RawCompressedStackMaps* maps =
-          reinterpret_cast<const RawCompressedStackMaps*>(this);
+      const CompressedStackMapsPtr maps =
+          static_cast<const CompressedStackMapsPtr>(this);
       intptr_t length = CompressedStackMaps::PayloadSizeOf(maps);
       instance_size = CompressedStackMaps::InstanceSize(length);
       break;
     }
     case kLocalVarDescriptorsCid: {
-      const RawLocalVarDescriptors* raw_descriptors =
-          reinterpret_cast<const RawLocalVarDescriptors*>(this);
+      const LocalVarDescriptorsPtr raw_descriptors =
+          static_cast<const LocalVarDescriptorsPtr>(this);
       intptr_t num_descriptors = raw_descriptors->ptr()->num_entries_;
       instance_size = LocalVarDescriptors::InstanceSize(num_descriptors);
       break;
     }
     case kExceptionHandlersCid: {
-      const RawExceptionHandlers* raw_handlers =
-          reinterpret_cast<const RawExceptionHandlers*>(this);
+      const ExceptionHandlersPtr raw_handlers =
+          static_cast<const ExceptionHandlersPtr>(this);
       intptr_t num_handlers = raw_handlers->ptr()->num_entries_;
       instance_size = ExceptionHandlers::InstanceSize(num_handlers);
       break;
     }
     case kFreeListElement: {
-      uword addr = RawObject::ToAddr(this);
+      uword addr = ObjectLayout::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
       instance_size = element->HeapSize();
       break;
     }
     case kForwardingCorpse: {
-      uword addr = RawObject::ToAddr(this);
+      uword addr = ObjectLayout::ToAddr(this);
       ForwardingCorpse* element = reinterpret_cast<ForwardingCorpse*>(addr);
       instance_size = element->HeapSize();
       break;
@@ -240,12 +241,12 @@
       const bool use_saved_class_table = false;
 #endif
 
-      auto class_table = isolate_group->class_table();
+      auto class_table = isolate_group->shared_class_table();
       ASSERT(use_saved_class_table || class_table->SizeAt(class_id) > 0);
       if (!class_table->IsValidIndex(class_id) ||
           (!class_table->HasValidClassAt(class_id) && !use_saved_class_table)) {
         FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?",
-               class_id, this, static_cast<uint32_t>(ptr()->tags_));
+               class_id, this, static_cast<uint32_t>(tags));
       }
 #endif  // DEBUG
       instance_size = isolate_group->GetClassSizeForHeapWalkAt(class_id);
@@ -253,7 +254,6 @@
   }
   ASSERT(instance_size != 0);
 #if defined(DEBUG)
-  uint32_t tags = ptr()->tags_;
   intptr_t tags_size = SizeTag::decode(tags);
   if ((class_id == kArrayCid) && (instance_size > tags_size && tags_size > 0)) {
     // TODO(22501): Array::MakeFixedLength could be in the process of shrinking
@@ -262,7 +262,7 @@
     int retries_remaining = 1000;  // ... but not forever.
     do {
       OS::Sleep(1);
-      const RawArray* raw_array = reinterpret_cast<const RawArray*>(this);
+      const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
       intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
       instance_size = Array::InstanceSize(array_length);
     } while ((instance_size > tags_size) && (--retries_remaining > 0));
@@ -275,60 +275,59 @@
   return instance_size;
 }
 
-intptr_t RawObject::VisitPointersPredefined(ObjectPointerVisitor* visitor,
-                                            intptr_t class_id) {
+intptr_t ObjectLayout::VisitPointersPredefined(ObjectPointerVisitor* visitor,
+                                               intptr_t class_id) {
   ASSERT(class_id < kNumPredefinedCids);
 
   intptr_t size = 0;
 
-  // Only reasonable to be called on heap objects.
-  ASSERT(IsHeapObject());
-
   switch (class_id) {
 #define RAW_VISITPOINTERS(clazz)                                               \
   case k##clazz##Cid: {                                                        \
-    Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this);                 \
-    size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor);               \
+    clazz##Ptr raw_obj = static_cast<clazz##Ptr>(this);                        \
+    size = clazz##Layout::Visit##clazz##Pointers(raw_obj, visitor);            \
     break;                                                                     \
   }
     CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS)
 #undef RAW_VISITPOINTERS
 #define RAW_VISITPOINTERS(clazz) case kTypedData##clazz##Cid:
     CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
-      RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(this);
-      size = RawTypedData::VisitTypedDataPointers(raw_obj, visitor);
+      TypedDataPtr raw_obj = static_cast<TypedDataPtr>(this);
+      size = TypedDataLayout::VisitTypedDataPointers(raw_obj, visitor);
       break;
     }
 #undef RAW_VISITPOINTERS
 #define RAW_VISITPOINTERS(clazz) case kExternalTypedData##clazz##Cid:
     CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
-      auto raw_obj = reinterpret_cast<RawExternalTypedData*>(this);
-      size = RawExternalTypedData::VisitExternalTypedDataPointers(raw_obj,
-                                                                  visitor);
+      auto raw_obj = static_cast<ExternalTypedDataPtr>(this);
+      size = ExternalTypedDataLayout::VisitExternalTypedDataPointers(raw_obj,
+                                                                     visitor);
       break;
     }
 #undef RAW_VISITPOINTERS
     case kByteDataViewCid:
 #define RAW_VISITPOINTERS(clazz) case kTypedData##clazz##ViewCid:
       CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
-        auto raw_obj = reinterpret_cast<RawTypedDataView*>(this);
-        size = RawTypedDataView::VisitTypedDataViewPointers(raw_obj, visitor);
+        auto raw_obj = static_cast<TypedDataViewPtr>(this);
+        size =
+            TypedDataViewLayout::VisitTypedDataViewPointers(raw_obj, visitor);
         break;
       }
 #undef RAW_VISITPOINTERS
     case kByteBufferCid: {
-      RawInstance* raw_obj = reinterpret_cast<RawInstance*>(this);
-      size = RawInstance::VisitInstancePointers(raw_obj, visitor);
+      InstancePtr raw_obj = static_cast<InstancePtr>(this);
+      size = InstanceLayout::VisitInstancePointers(raw_obj, visitor);
       break;
     }
     case kFfiPointerCid: {
-      RawPointer* raw_obj = reinterpret_cast<RawPointer*>(this);
-      size = RawPointer::VisitPointerPointers(raw_obj, visitor);
+      PointerPtr raw_obj = static_cast<PointerPtr>(this);
+      size = PointerLayout::VisitPointerPointers(raw_obj, visitor);
       break;
     }
     case kFfiDynamicLibraryCid: {
-      RawDynamicLibrary* raw_obj = reinterpret_cast<RawDynamicLibrary*>(this);
-      size = RawDynamicLibrary::VisitDynamicLibraryPointers(raw_obj, visitor);
+      DynamicLibraryPtr raw_obj = static_cast<DynamicLibraryPtr>(this);
+      size =
+          DynamicLibraryLayout::VisitDynamicLibraryPointers(raw_obj, visitor);
       break;
     }
 #define RAW_VISITPOINTERS(clazz) case kFfi##clazz##Cid:
@@ -346,23 +345,24 @@
       }
 #undef RAW_VISITPOINTERS
     case kFreeListElement: {
-      uword addr = RawObject::ToAddr(this);
+      uword addr = ObjectLayout::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
       size = element->HeapSize();
       break;
     }
     case kForwardingCorpse: {
-      uword addr = RawObject::ToAddr(this);
+      uword addr = ObjectLayout::ToAddr(this);
       ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
       size = forwarder->HeapSize();
       break;
     }
     case kNullCid:
+    case kNeverCid:
       size = HeapSize();
       break;
     default:
       FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?", class_id,
-             this, static_cast<uint32_t>(ptr()->tags_));
+             this, static_cast<uint32_t>(tags_));
       break;
   }
 
@@ -383,8 +383,8 @@
 #endif
 }
 
-void RawObject::VisitPointersPrecise(Isolate* isolate,
-                                     ObjectPointerVisitor* visitor) {
+void ObjectLayout::VisitPointersPrecise(Isolate* isolate,
+                                        ObjectPointerVisitor* visitor) {
   intptr_t class_id = GetClassId();
   if (class_id < kNumPredefinedCids) {
     VisitPointersPredefined(visitor, class_id);
@@ -397,19 +397,19 @@
                                 ->host_next_field_offset_in_words_
                             << kWordSizeLog2;
   ASSERT(next_field_offset > 0);
-  uword obj_addr = RawObject::ToAddr(this);
-  uword from = obj_addr + sizeof(RawObject);
+  uword obj_addr = ObjectLayout::ToAddr(this);
+  uword from = obj_addr + sizeof(ObjectLayout);
   uword to = obj_addr + next_field_offset - kWordSize;
-  const auto first = reinterpret_cast<RawObject**>(from);
-  const auto last = reinterpret_cast<RawObject**>(to);
+  const auto first = reinterpret_cast<ObjectPtr*>(from);
+  const auto last = reinterpret_cast<ObjectPtr*>(to);
 
 #if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
   const auto unboxed_fields_bitmap =
       visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
 
   if (!unboxed_fields_bitmap.IsEmpty()) {
-    intptr_t bit = sizeof(RawObject) / kWordSize;
-    for (RawObject** current = first; current <= last; current++) {
+    intptr_t bit = sizeof(ObjectLayout) / kWordSize;
+    for (ObjectPtr* current = first; current <= last; current++) {
       if (!unboxed_fields_bitmap.Get(bit++)) {
         visitor->VisitPointer(current);
       }
@@ -422,21 +422,21 @@
 #endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
 }
 
-bool RawObject::FindObject(FindObjectVisitor* visitor) {
+bool ObjectLayout::FindObject(FindObjectVisitor* visitor) {
   ASSERT(visitor != NULL);
-  return visitor->FindObject(this);
+  return visitor->FindObject(static_cast<ObjectPtr>(this));
 }
 
 // Most objects are visited with this function. It calls the from() and to()
 // methods on the raw object to get the first and last cells that need
 // visiting.
 #define REGULAR_VISITOR(Type)                                                  \
-  intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj,                \
-                                            ObjectPointerVisitor* visitor) {   \
+  intptr_t Type##Layout::Visit##Type##Pointers(                                \
+      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);                                                 \
-    visitor->VisitPointers(raw_obj->from(), raw_obj->to());                    \
+    visitor->VisitPointers(raw_obj->ptr()->from(), raw_obj->ptr()->to());      \
     return Type::InstanceSize();                                               \
   }
 
@@ -446,25 +446,26 @@
 // Though as opposed to Similar to [REGULAR_VISITOR] this visitor will call the
 // specializd VisitTypedDataViewPointers
 #define TYPED_DATA_VIEW_VISITOR(Type)                                          \
-  intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj,                \
-                                            ObjectPointerVisitor* visitor) {   \
+  intptr_t Type##Layout::Visit##Type##Pointers(                                \
+      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);                                                 \
-    visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->from(),              \
-                                        raw_obj->to());                        \
+    visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->ptr()->from(),       \
+                                        raw_obj->ptr()->to());                 \
     return Type::InstanceSize();                                               \
   }
 
 // For variable length objects. get_length is a code snippet that gets the
 // length of the object, which is passed to InstanceSize and the to() method.
 #define VARIABLE_VISITOR(Type, get_length)                                     \
-  intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj,                \
-                                            ObjectPointerVisitor* visitor) {   \
+  intptr_t Type##Layout::Visit##Type##Pointers(                                \
+      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
     /* Make sure that we got here with the tagged pointer as this. */          \
     ASSERT(raw_obj->IsHeapObject());                                           \
     intptr_t length = get_length;                                              \
-    visitor->VisitPointers(raw_obj->from(), raw_obj->to(length));              \
+    visitor->VisitPointers(raw_obj->ptr()->from(),                             \
+                           raw_obj->ptr()->to(length));                        \
     return Type::InstanceSize(length);                                         \
   }
 
@@ -475,8 +476,8 @@
 
 // For fixed-length objects that don't have any pointers that need visiting.
 #define NULL_VISITOR(Type)                                                     \
-  intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj,                \
-                                            ObjectPointerVisitor* visitor) {   \
+  intptr_t Type##Layout::Visit##Type##Pointers(                                \
+      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
     /* Make sure that we got here with the tagged pointer as this. */          \
     ASSERT(raw_obj->IsHeapObject());                                           \
     ASSERT_NOTHING_TO_VISIT(Type);                                             \
@@ -486,8 +487,8 @@
 // For objects that don't have any pointers that need visiting, but have a
 // variable length.
 #define VARIABLE_NULL_VISITOR(Type, get_length)                                \
-  intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj,                \
-                                            ObjectPointerVisitor* visitor) {   \
+  intptr_t Type##Layout::Visit##Type##Pointers(                                \
+      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
     /* Make sure that we got here with the tagged pointer as this. */          \
     ASSERT(raw_obj->IsHeapObject());                                           \
     ASSERT_NOTHING_TO_VISIT(Type);                                             \
@@ -497,8 +498,8 @@
 
 // For objects that are never instantiated on the heap.
 #define UNREACHABLE_VISITOR(Type)                                              \
-  intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj,                \
-                                            ObjectPointerVisitor* visitor) {   \
+  intptr_t Type##Layout::Visit##Type##Pointers(                                \
+      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
     UNREACHABLE();                                                             \
     return 0;                                                                  \
   }
@@ -575,6 +576,7 @@
 VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->ptr()->length_))
 // Abstract types don't have their visitor called.
 UNREACHABLE_VISITOR(AbstractType)
+UNREACHABLE_VISITOR(CallSiteData)
 UNREACHABLE_VISITOR(TypedDataBase)
 UNREACHABLE_VISITOR(Error)
 UNREACHABLE_VISITOR(Number)
@@ -589,19 +591,19 @@
 REGULAR_VISITOR(WeakSerializationReference)
 #endif
 
-bool RawCode::ContainsPC(const RawObject* raw_obj, uword pc) {
+bool CodeLayout::ContainsPC(const ObjectPtr raw_obj, uword pc) {
   if (!raw_obj->IsCode()) return false;
-  auto const raw_code = static_cast<const RawCode*>(raw_obj);
+  auto const raw_code = static_cast<const CodePtr>(raw_obj);
   const uword start = Code::PayloadStartOf(raw_code);
   const uword size = Code::PayloadSizeOf(raw_code);
   return (pc - start) <= size;  // pc may point just past last instruction.
 }
 
-intptr_t RawCode::VisitCodePointers(RawCode* raw_obj,
-                                    ObjectPointerVisitor* visitor) {
-  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+intptr_t CodeLayout::VisitCodePointers(CodePtr raw_obj,
+                                       ObjectPointerVisitor* visitor) {
+  visitor->VisitPointers(raw_obj->ptr()->from(), raw_obj->ptr()->to());
 
-  RawCode* obj = raw_obj->ptr();
+  CodeLayout* obj = raw_obj->ptr();
   intptr_t length = Code::PtrOffBits::decode(obj->state_bits_);
 #if defined(TARGET_ARCH_IA32)
   // On IA32 only we embed pointers to objects directly in the generated
@@ -611,8 +613,7 @@
     uword entry_point = Code::PayloadStartOf(raw_obj);
     for (intptr_t i = 0; i < length; i++) {
       int32_t offset = obj->data()[i];
-      visitor->VisitPointer(
-          reinterpret_cast<RawObject**>(entry_point + offset));
+      visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(entry_point + offset));
     }
   }
   return Code::InstanceSize(length);
@@ -624,9 +625,9 @@
 #endif
 }
 
-bool RawBytecode::ContainsPC(RawObject* raw_obj, uword pc) {
+bool BytecodeLayout::ContainsPC(ObjectPtr raw_obj, uword pc) {
   if (raw_obj->IsBytecode()) {
-    RawBytecode* raw_bytecode = static_cast<RawBytecode*>(raw_obj);
+    BytecodePtr raw_bytecode = static_cast<BytecodePtr>(raw_obj);
     uword start = raw_bytecode->ptr()->instructions_;
     uword size = raw_bytecode->ptr()->instructions_size_;
     return (pc - start) <= size;  // pc may point past last instruction.
@@ -634,10 +635,11 @@
   return false;
 }
 
-intptr_t RawObjectPool::VisitObjectPoolPointers(RawObjectPool* raw_obj,
-                                                ObjectPointerVisitor* visitor) {
+intptr_t ObjectPoolLayout::VisitObjectPoolPointers(
+    ObjectPoolPtr raw_obj,
+    ObjectPointerVisitor* visitor) {
   const intptr_t length = raw_obj->ptr()->length_;
-  RawObjectPool::Entry* entries = raw_obj->ptr()->data();
+  ObjectPoolLayout::Entry* entries = raw_obj->ptr()->data();
   uint8_t* entry_bits = raw_obj->ptr()->entry_bits();
   for (intptr_t i = 0; i < length; ++i) {
     ObjectPool::EntryType entry_type =
@@ -650,7 +652,7 @@
   return ObjectPool::InstanceSize(length);
 }
 
-bool RawInstructions::ContainsPC(const RawInstructions* raw_instr, uword pc) {
+bool InstructionsLayout::ContainsPC(const InstructionsPtr raw_instr, uword pc) {
   const uword start = Instructions::PayloadStart(raw_instr);
   const uword size = Instructions::Size(raw_instr);
   // We use <= instead of < here because the saved-pc can be outside the
@@ -659,8 +661,8 @@
   return (pc - start) <= size;
 }
 
-intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj,
-                                            ObjectPointerVisitor* visitor) {
+intptr_t InstanceLayout::VisitInstancePointers(InstancePtr raw_obj,
+                                               ObjectPointerVisitor* visitor) {
   // Make sure that we got here with the tagged pointer as this.
   ASSERT(raw_obj->IsHeapObject());
   uint32_t tags = raw_obj->ptr()->tags_;
@@ -671,36 +673,37 @@
   }
 
   // Calculate the first and last raw object pointer fields.
-  uword obj_addr = RawObject::ToAddr(raw_obj);
-  uword from = obj_addr + sizeof(RawObject);
+  uword obj_addr = ObjectLayout::ToAddr(raw_obj);
+  uword from = obj_addr + sizeof(ObjectLayout);
   uword to = obj_addr + instance_size - kWordSize;
-  visitor->VisitPointers(reinterpret_cast<RawObject**>(from),
-                         reinterpret_cast<RawObject**>(to));
+  visitor->VisitPointers(reinterpret_cast<ObjectPtr*>(from),
+                         reinterpret_cast<ObjectPtr*>(to));
   return instance_size;
 }
 
-intptr_t RawImmutableArray::VisitImmutableArrayPointers(
-    RawImmutableArray* raw_obj,
+intptr_t ImmutableArrayLayout::VisitImmutableArrayPointers(
+    ImmutableArrayPtr raw_obj,
     ObjectPointerVisitor* visitor) {
-  return RawArray::VisitArrayPointers(raw_obj, visitor);
+  return ArrayLayout::VisitArrayPointers(raw_obj, visitor);
 }
 
-void RawObject::RememberCard(RawObject* const* slot) {
-  HeapPage::Of(this)->RememberCard(slot);
+void ObjectLayout::RememberCard(ObjectPtr const* slot) {
+  HeapPage::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
 }
 
 DEFINE_LEAF_RUNTIME_ENTRY(void,
                           RememberCard,
                           2,
-                          RawObject* object,
-                          RawObject** slot) {
+                          uword /*ObjectPtr*/ object_in,
+                          ObjectPtr* slot) {
+  ObjectPtr object = static_cast<ObjectPtr>(object_in);
   ASSERT(object->IsOldObject());
-  ASSERT(object->IsCardRemembered());
+  ASSERT(object->ptr()->IsCardRemembered());
   HeapPage::Of(object)->RememberCard(slot);
 }
 END_LEAF_RUNTIME_ENTRY
 
-const char* RawPcDescriptors::KindToCString(Kind k) {
+const char* PcDescriptorsLayout::KindToCString(Kind k) {
   switch (k) {
 #define ENUM_CASE(name, init)                                                  \
   case Kind::k##name:                                                          \
@@ -712,7 +715,7 @@
   }
 }
 
-bool RawPcDescriptors::ParseKind(const char* cstr, Kind* out) {
+bool PcDescriptorsLayout::ParseKind(const char* cstr, Kind* out) {
   ASSERT(cstr != nullptr && out != nullptr);
 #define ENUM_CASE(name, init)                                                  \
   if (strcmp(#name, cstr) == 0) {                                              \
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 10566c2..fd0ddb6 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -19,27 +19,28 @@
 #include "vm/globals.h"
 #include "vm/pointer_tagging.h"
 #include "vm/snapshot.h"
+#include "vm/tagged_pointer.h"
 #include "vm/token.h"
 #include "vm/token_position.h"
 
 namespace dart {
 
 // For now there are no compressed pointers.
-typedef RawObject* RawCompressed;
+typedef ObjectPtr RawCompressed;
 
 // Forward declarations.
 class Isolate;
 class IsolateGroup;
-#define DEFINE_FORWARD_DECLARATION(clazz) class Raw##clazz;
+#define DEFINE_FORWARD_DECLARATION(clazz) class clazz##Layout;
 CLASS_LIST(DEFINE_FORWARD_DECLARATION)
 #undef DEFINE_FORWARD_DECLARATION
 class CodeStatistics;
 
 #define VISIT_FROM(type, first)                                                \
-  type* from() { return reinterpret_cast<type*>(&ptr()->first); }
+  type* from() { return reinterpret_cast<type*>(&first); }
 
 #define VISIT_TO(type, last)                                                   \
-  type* to() { return reinterpret_cast<type*>(&ptr()->last); }
+  type* to() { return reinterpret_cast<type*>(&last); }
 
 #define VISIT_TO_LENGTH(type, last)                                            \
   type* to(intptr_t length) { return reinterpret_cast<type*>(last); }
@@ -47,15 +48,15 @@
 #define VISIT_NOTHING() int NothingToVisit();
 
 #define ASSERT_UNCOMPRESSED(Type)                                              \
-  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Raw##Type, from) == kWordSize)
+  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Type##Layout, from) == kWordSize)
 
 // 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(Raw##Type, from) == kWordSize)
+  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Type##Layout, from) == kWordSize)
 
 #define ASSERT_NOTHING_TO_VISIT(Type)                                          \
-  ASSERT(SIZE_OF_RETURNED_VALUE(Raw##Type, NothingToVisit) == sizeof(int))
+  ASSERT(SIZE_OF_RETURNED_VALUE(Type##Layout, NothingToVisit) == sizeof(int))
 
 enum TypedDataElementType {
 #define V(name) k##name##Element,
@@ -69,7 +70,7 @@
   friend class SnapshotWriter;
 
 #define VISITOR_SUPPORT(object)                                                \
-  static intptr_t Visit##object##Pointers(Raw##object* raw_obj,                \
+  static intptr_t Visit##object##Pointers(object##Ptr raw_obj,                 \
                                           ObjectPointerVisitor* visitor);
 
 #define HEAP_PROFILER_SUPPORT() friend class HeapProfiler;
@@ -78,7 +79,7 @@
  private: /* NOLINT */                                                         \
   VISITOR_SUPPORT(object)                                                      \
   friend class object;                                                         \
-  friend class RawObject;                                                      \
+  friend class ObjectLayout;                                                   \
   friend class Heap;                                                           \
   friend class Interpreter;                                                    \
   friend class InterpreterHelpers;                                             \
@@ -86,17 +87,11 @@
   friend class SimulatorHelpers;                                               \
   friend class OffsetsTable;                                                   \
   DISALLOW_ALLOCATION();                                                       \
-  DISALLOW_IMPLICIT_CONSTRUCTORS(Raw##object)
+  DISALLOW_IMPLICIT_CONSTRUCTORS(object##Layout)
 
-// TODO(koda): Make ptr() return const*, like Object::raw_ptr().
 #define RAW_HEAP_OBJECT_IMPLEMENTATION(object)                                 \
  private:                                                                      \
   RAW_OBJECT_IMPLEMENTATION(object);                                           \
-  Raw##object* ptr() const {                                                   \
-    ASSERT(IsHeapObject());                                                    \
-    return reinterpret_cast<Raw##object*>(reinterpret_cast<uword>(this) -      \
-                                          kHeapObjectTag);                     \
-  }                                                                            \
   SNAPSHOT_WRITER_SUPPORT()                                                    \
   HEAP_PROFILER_SUPPORT()                                                      \
   friend class object##SerializationCluster;                                   \
@@ -108,7 +103,7 @@
 // RawObject is the base class of all raw objects; even though it carries the
 // tags_ field not all raw objects are allocated in the heap and thus cannot
 // be dereferenced (e.g. RawSmi).
-class RawObject {
+class ObjectLayout {
  public:
   // The tags field which is a part of the object header uses the following
   // bit fields for storing tags.
@@ -151,7 +146,7 @@
     typedef intptr_t Type;
 
     static constexpr intptr_t kMaxSizeTagInUnitsOfAlignment =
-        ((1 << RawObject::kSizeTagSize) - 1);
+        ((1 << ObjectLayout::kSizeTagSize) - 1);
     static constexpr intptr_t kMaxSizeTag =
         kMaxSizeTagInUnitsOfAlignment * kObjectAlignment;
 
@@ -167,6 +162,11 @@
       return SizeBits::update(SizeToTagValue(size), tag);
     }
 
+    static UNLESS_DEBUG(constexpr) bool SizeFits(intptr_t size) {
+      DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment));
+      return (size <= kMaxSizeTag);
+    }
+
    private:
     // The actual unscaled bit field used within the tag field.
     class SizeBits
@@ -174,7 +174,7 @@
 
     static UNLESS_DEBUG(constexpr) intptr_t SizeToTagValue(intptr_t size) {
       DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment));
-      return (size > kMaxSizeTag) ? 0 : (size >> kObjectAlignmentLog2);
+      return !SizeFits(size) ? 0 : (size >> kObjectAlignmentLog2);
     }
     static constexpr intptr_t TagValueToSize(intptr_t value) {
       return value << kObjectAlignmentLog2;
@@ -269,166 +269,86 @@
     COMPILE_ASSERT(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t));
   };
 
-  bool IsWellFormed() const {
-    uword value = reinterpret_cast<uword>(this);
-    return (value & kSmiTagMask) == 0 ||
-           Utils::IsAligned(value - kHeapObjectTag, kWordSize);
-  }
-  bool IsHeapObject() const {
-    ASSERT(IsWellFormed());
-    uword value = reinterpret_cast<uword>(this);
-    return (value & kSmiTagMask) == kHeapObjectTag;
-  }
   // Assumes this is a heap object.
   bool IsNewObject() const {
-    ASSERT(IsHeapObject());
     uword addr = reinterpret_cast<uword>(this);
-    return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
-  }
-  bool IsNewObjectMayBeSmi() const {
-    static const uword kNewObjectBits =
-        (kNewObjectAlignmentOffset | kHeapObjectTag);
-    const uword addr = reinterpret_cast<uword>(this);
-    return (addr & kObjectAlignmentMask) == kNewObjectBits;
+    return (addr & kObjectAlignmentMask) == kNewObjectAlignmentOffset;
   }
   // Assumes this is a heap object.
   bool IsOldObject() const {
-    ASSERT(IsHeapObject());
     uword addr = reinterpret_cast<uword>(this);
-    return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
-  }
-
-  // Like !IsHeapObject() || IsOldObject(), but compiles to a single branch.
-  bool IsSmiOrOldObject() const {
-    ASSERT(IsWellFormed());
-    static const uword kNewObjectBits =
-        (kNewObjectAlignmentOffset | kHeapObjectTag);
-    const uword addr = reinterpret_cast<uword>(this);
-    return (addr & kObjectAlignmentMask) != kNewObjectBits;
-  }
-
-  // Like !IsHeapObject() || IsNewObject(), but compiles to a single branch.
-  bool IsSmiOrNewObject() const {
-    ASSERT(IsWellFormed());
-    static const uword kOldObjectBits =
-        (kOldObjectAlignmentOffset | kHeapObjectTag);
-    const uword addr = reinterpret_cast<uword>(this);
-    return (addr & kObjectAlignmentMask) != kOldObjectBits;
+    return (addr & kObjectAlignmentMask) == kOldObjectAlignmentOffset;
   }
 
   // Support for GC marking bit. Marked objects are either grey (not yet
   // visited) or black (already visited).
   bool IsMarked() const {
     ASSERT(IsOldObject());
-    return !ptr()->tags_.Read<OldAndNotMarkedBit>();
+    return !tags_.Read<OldAndNotMarkedBit>();
   }
   void SetMarkBit() {
     ASSERT(IsOldObject());
     ASSERT(!IsMarked());
-    ptr()->tags_.UpdateBool<OldAndNotMarkedBit>(false);
+    tags_.UpdateBool<OldAndNotMarkedBit>(false);
   }
   void SetMarkBitUnsynchronized() {
     ASSERT(IsOldObject());
     ASSERT(!IsMarked());
-    ptr()->tags_.UpdateUnsynchronized<OldAndNotMarkedBit>(false);
+    tags_.UpdateUnsynchronized<OldAndNotMarkedBit>(false);
   }
   void ClearMarkBit() {
     ASSERT(IsOldObject());
     ASSERT(IsMarked());
-    ptr()->tags_.UpdateBool<OldAndNotMarkedBit>(true);
+    tags_.UpdateBool<OldAndNotMarkedBit>(true);
   }
   // Returns false if the bit was already set.
   DART_WARN_UNUSED_RESULT
   bool TryAcquireMarkBit() {
     ASSERT(IsOldObject());
-    return ptr()->tags_.TryClear<OldAndNotMarkedBit>();
+    return tags_.TryClear<OldAndNotMarkedBit>();
   }
 
   // Canonical objects have the property that two canonical objects are
   // logically equal iff they are the same object (pointer equal).
-  bool IsCanonical() const { return ptr()->tags_.Read<CanonicalBit>(); }
-  void SetCanonical() { ptr()->tags_.UpdateBool<CanonicalBit>(true); }
-  void ClearCanonical() { ptr()->tags_.UpdateBool<CanonicalBit>(false); }
+  bool IsCanonical() const { return tags_.Read<CanonicalBit>(); }
+  void SetCanonical() { tags_.UpdateBool<CanonicalBit>(true); }
+  void ClearCanonical() { tags_.UpdateBool<CanonicalBit>(false); }
 
   bool InVMIsolateHeap() const;
 
   // Support for GC remembered bit.
   bool IsRemembered() const {
     ASSERT(IsOldObject());
-    return !ptr()->tags_.Read<OldAndNotRememberedBit>();
+    return !tags_.Read<OldAndNotRememberedBit>();
   }
   void SetRememberedBit() {
     ASSERT(!IsRemembered());
     ASSERT(!IsCardRemembered());
-    ptr()->tags_.UpdateBool<OldAndNotRememberedBit>(false);
+    tags_.UpdateBool<OldAndNotRememberedBit>(false);
   }
   void ClearRememberedBit() {
     ASSERT(IsOldObject());
-    ptr()->tags_.UpdateBool<OldAndNotRememberedBit>(true);
+    tags_.UpdateBool<OldAndNotRememberedBit>(true);
   }
 
   DART_FORCE_INLINE
   void AddToRememberedSet(Thread* thread) {
     ASSERT(!this->IsRemembered());
     this->SetRememberedBit();
-    thread->StoreBufferAddObject(this);
+    thread->StoreBufferAddObject(ObjectPtr(this));
   }
 
-  bool IsCardRemembered() const {
-    return ptr()->tags_.Read<CardRememberedBit>();
-  }
+  bool IsCardRemembered() const { return tags_.Read<CardRememberedBit>(); }
   void SetCardRememberedBitUnsynchronized() {
     ASSERT(!IsRemembered());
     ASSERT(!IsCardRemembered());
-    ptr()->tags_.UpdateUnsynchronized<CardRememberedBit>(true);
+    tags_.UpdateUnsynchronized<CardRememberedBit>(true);
   }
 
-#define DEFINE_IS_CID(clazz)                                                   \
-  bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
-  CLASS_LIST(DEFINE_IS_CID)
-#undef DEFINE_IS_CID
-
-#define DEFINE_IS_CID(clazz)                                                   \
-  bool IsTypedData##clazz() const {                                            \
-    return ((GetClassId() == kTypedData##clazz##Cid));                         \
-  }                                                                            \
-  bool IsTypedDataView##clazz() const {                                        \
-    return ((GetClassId() == kTypedData##clazz##ViewCid));                     \
-  }                                                                            \
-  bool IsExternalTypedData##clazz() const {                                    \
-    return ((GetClassId() == kExternalTypedData##clazz##Cid));                 \
-  }
-  CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
-#undef DEFINE_IS_CID
-
-#define DEFINE_IS_CID(clazz)                                                   \
-  bool IsFfi##clazz() const { return ((GetClassId() == kFfi##clazz##Cid)); }
-  CLASS_LIST_FFI(DEFINE_IS_CID)
-#undef DEFINE_IS_CID
-
-  bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
-  bool IsRawNull() const { return GetClassId() == kNullCid; }
-  bool IsDartInstance() const {
-    return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
-  }
-  bool IsFreeListElement() const {
-    return ((GetClassId() == kFreeListElement));
-  }
-  bool IsForwardingCorpse() const {
-    return ((GetClassId() == kForwardingCorpse));
-  }
-  bool IsPseudoObject() const {
-    return IsFreeListElement() || IsForwardingCorpse();
-  }
-
-  intptr_t GetClassId() const { return ptr()->tags_.Read<ClassIdTag>(); }
-  intptr_t GetClassIdMayBeSmi() const {
-    return IsHeapObject() ? GetClassId() : static_cast<intptr_t>(kSmiCid);
-  }
+  intptr_t GetClassId() const { return tags_.Read<ClassIdTag>(); }
 
   intptr_t HeapSize() const {
-    ASSERT(IsHeapObject());
-    uint32_t tags = ptr()->tags_;
+    uint32_t tags = tags_;
     intptr_t result = SizeTag::decode(tags);
     if (result != 0) {
 #if defined(DEBUG)
@@ -437,23 +357,34 @@
       // leading to inconsistency between HeapSizeFromClass() and
       // SizeTag::decode(tags). We are working around it by reloading tags_ and
       // recomputing size from tags.
-      const intptr_t size_from_class = HeapSizeFromClass();
+      const intptr_t size_from_class = HeapSizeFromClass(tags);
       if ((result > size_from_class) && (GetClassId() == kArrayCid) &&
-          (ptr()->tags_) != tags) {
-        result = SizeTag::decode(ptr()->tags_);
+          (tags_ != tags)) {
+        result = SizeTag::decode(tags_);
       }
       ASSERT(result == size_from_class);
 #endif
       return result;
     }
-    result = HeapSizeFromClass();
+    result = HeapSizeFromClass(tags);
+    ASSERT(result > SizeTag::kMaxSizeTag);
+    return result;
+  }
+
+  // This variant must not deference this->tags_.
+  intptr_t HeapSize(uint32_t tags) const {
+    intptr_t result = SizeTag::decode(tags);
+    if (result != 0) {
+      return result;
+    }
+    result = HeapSizeFromClass(tags);
     ASSERT(result > SizeTag::kMaxSizeTag);
     return result;
   }
 
   bool Contains(uword addr) const {
     intptr_t this_size = HeapSize();
-    uword this_addr = RawObject::ToAddr(this);
+    uword this_addr = ObjectLayout::ToAddr(this);
     return (addr >= this_addr) && (addr < (this_addr + this_size));
   }
 
@@ -473,18 +404,18 @@
     // Calculate the first and last raw object pointer fields.
     intptr_t instance_size = HeapSize();
     uword obj_addr = ToAddr(this);
-    uword from = obj_addr + sizeof(RawObject);
+    uword from = obj_addr + sizeof(ObjectLayout);
     uword to = obj_addr + instance_size - kWordSize;
-    const auto first = reinterpret_cast<RawObject**>(from);
-    const auto last = reinterpret_cast<RawObject**>(to);
+    const auto first = reinterpret_cast<ObjectPtr*>(from);
+    const auto last = reinterpret_cast<ObjectPtr*>(to);
 
 #if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
     const auto unboxed_fields_bitmap =
         visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
 
     if (!unboxed_fields_bitmap.IsEmpty()) {
-      intptr_t bit = sizeof(RawObject) / kWordSize;
-      for (RawObject** current = first; current <= last; current++) {
+      intptr_t bit = sizeof(ObjectLayout) / kWordSize;
+      for (ObjectPtr* current = first; current <= last; current++) {
         if (!unboxed_fields_bitmap.Get(bit++)) {
           visitor->VisitPointer(current);
         }
@@ -511,18 +442,18 @@
     // Calculate the first and last raw object pointer fields.
     intptr_t instance_size = HeapSize();
     uword obj_addr = ToAddr(this);
-    uword from = obj_addr + sizeof(RawObject);
+    uword from = obj_addr + sizeof(ObjectLayout);
     uword to = obj_addr + instance_size - kWordSize;
-    const auto first = reinterpret_cast<RawObject**>(from);
-    const auto last = reinterpret_cast<RawObject**>(to);
+    const auto first = reinterpret_cast<ObjectPtr*>(from);
+    const auto last = reinterpret_cast<ObjectPtr*>(to);
 
 #if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
     const auto unboxed_fields_bitmap =
         visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
 
     if (!unboxed_fields_bitmap.IsEmpty()) {
-      intptr_t bit = sizeof(RawObject) / kWordSize;
-      for (RawObject** current = first; current <= last; current++) {
+      intptr_t bit = sizeof(ObjectLayout) / kWordSize;
+      for (ObjectPtr* current = first; current <= last; current++) {
         if (!unboxed_fields_bitmap.Get(bit++)) {
           visitor->V::VisitPointers(current, current);
         }
@@ -542,48 +473,23 @@
   // rounding up instance sizes up to the allocation unit.
   void VisitPointersPrecise(Isolate* isolate, ObjectPointerVisitor* visitor);
 
-  static RawObject* FromAddr(uword addr) {
+  static ObjectPtr FromAddr(uword addr) {
     // We expect the untagged address here.
     ASSERT((addr & kSmiTagMask) != kHeapObjectTag);
-    return reinterpret_cast<RawObject*>(addr + kHeapObjectTag);
+    return static_cast<ObjectPtr>(addr + kHeapObjectTag);
   }
 
-  static uword ToAddr(const RawObject* raw_obj) {
-    return reinterpret_cast<uword>(raw_obj->ptr());
+  static uword ToAddr(const ObjectLayout* raw_obj) {
+    return reinterpret_cast<uword>(raw_obj);
+  }
+  static uword ToAddr(const ObjectPtr raw_obj) {
+    return static_cast<uword>(raw_obj) - kHeapObjectTag;
   }
 
   static bool IsCanonical(intptr_t value) {
     return CanonicalBit::decode(value);
   }
 
-  // Class Id predicates.
-  static bool IsErrorClassId(intptr_t index);
-  static bool IsNumberClassId(intptr_t index);
-  static bool IsIntegerClassId(intptr_t index);
-  static bool IsStringClassId(intptr_t index);
-  static bool IsOneByteStringClassId(intptr_t index);
-  static bool IsTwoByteStringClassId(intptr_t index);
-  static bool IsExternalStringClassId(intptr_t index);
-  static bool IsBuiltinListClassId(intptr_t index);
-  static bool IsTypedDataBaseClassId(intptr_t index);
-  static bool IsTypedDataClassId(intptr_t index);
-  static bool IsTypedDataViewClassId(intptr_t index);
-  static bool IsExternalTypedDataClassId(intptr_t index);
-  static bool IsFfiNativeTypeTypeClassId(intptr_t index);
-  static bool IsFfiPointerClassId(intptr_t index);
-  static bool IsFfiTypeClassId(intptr_t index);
-  static bool IsFfiTypeIntClassId(intptr_t index);
-  static bool IsFfiTypeDoubleClassId(intptr_t index);
-  static bool IsFfiTypeVoidClassId(intptr_t index);
-  static bool IsFfiTypeNativeFunctionClassId(intptr_t index);
-  static bool IsFfiDynamicLibraryClassId(intptr_t index);
-  static bool IsFfiClassId(intptr_t index);
-  static bool IsInternalVMdefinedClassId(intptr_t index);
-  static bool IsVariableSizeClassId(intptr_t index);
-  static bool IsImplicitFieldClassId(intptr_t index);
-
-  static intptr_t NumberOfTypedDataClasses();
-
  private:
   Tags tags_;  // Various object tags (bits).
 #if defined(HASH_IN_OBJECT_HEADER)
@@ -595,20 +501,13 @@
   uint32_t padding_;
 #endif
 
-  // TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
-  RawObject* ptr() const {
-    ASSERT(IsHeapObject());
-    return reinterpret_cast<RawObject*>(reinterpret_cast<uword>(this) -
-                                        kHeapObjectTag);
-  }
-
   intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
                                    intptr_t class_id);
 
-  intptr_t HeapSizeFromClass() const;
+  intptr_t HeapSizeFromClass(uint32_t tags) const;
 
   void SetClassId(intptr_t new_cid) {
-    ptr()->tags_.UpdateUnsynchronized<ClassIdTag>(new_cid);
+    tags_.UpdateUnsynchronized<ClassIdTag>(new_cid);
   }
 
   // All writes to heap objects should ultimately pass through one of the
@@ -639,8 +538,8 @@
   }
 
   DART_FORCE_INLINE
-  void CheckHeapPointerStore(RawObject* value, Thread* thread) {
-    uint32_t source_tags = this->ptr()->tags_;
+  void CheckHeapPointerStore(ObjectPtr value, Thread* thread) {
+    uint32_t source_tags = this->tags_;
     uint32_t target_tags = value->ptr()->tags_;
     if (((source_tags >> kBarrierOverlapShift) & target_tags &
          thread->write_barrier_mask()) != 0) {
@@ -659,7 +558,7 @@
           return;
         }
 #endif
-        if (value->TryAcquireMarkBit()) {
+        if (value->ptr()->TryAcquireMarkBit()) {
           thread->MarkingStackAddObject(value);
         }
       }
@@ -685,9 +584,9 @@
 
   template <typename type>
   DART_FORCE_INLINE void CheckArrayPointerStore(type const* addr,
-                                                RawObject* value,
+                                                ObjectPtr value,
                                                 Thread* thread) {
-    uint32_t source_tags = this->ptr()->tags_;
+    uint32_t source_tags = this->tags_;
     uint32_t target_tags = value->ptr()->tags_;
     if (((source_tags >> kBarrierOverlapShift) & target_tags &
          thread->write_barrier_mask()) != 0) {
@@ -696,10 +595,10 @@
         // old-and-not-remembered -> new reference.
         ASSERT(!this->IsRemembered());
         if (this->IsCardRemembered()) {
-          RememberCard(reinterpret_cast<RawObject* const*>(addr));
+          RememberCard(reinterpret_cast<ObjectPtr const*>(addr));
         } else {
           this->SetRememberedBit();
-          thread->StoreBufferAddObject(this);
+          thread->StoreBufferAddObject(static_cast<ObjectPtr>(this));
         }
       } else {
         // Incremental barrier: record when a store creates an
@@ -712,7 +611,7 @@
           return;
         }
 #endif
-        if (value->TryAcquireMarkBit()) {
+        if (value->ptr()->TryAcquireMarkBit()) {
           thread->MarkingStackAddObject(value);
         }
       }
@@ -721,21 +620,21 @@
 
   // Use for storing into an explicitly Smi-typed field of an object
   // (i.e., both the previous and new value are Smis).
-  void StoreSmi(RawSmi* const* addr, RawSmi* value) {
+  void StoreSmi(SmiPtr const* addr, SmiPtr value) {
     // Can't use Contains, as array length is initialized through this method.
-    ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(this));
-    *const_cast<RawSmi**>(addr) = value;
+    ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this));
+    *const_cast<SmiPtr*>(addr) = value;
   }
   NO_SANITIZE_THREAD
-  void StoreSmiIgnoreRace(RawSmi* const* addr, RawSmi* value) {
+  void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) {
     // Can't use Contains, as array length is initialized through this method.
-    ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(this));
-    *const_cast<RawSmi**>(addr) = value;
+    ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this));
+    *const_cast<SmiPtr*>(addr) = value;
   }
 
  protected:
   friend class StoreBufferUpdateVisitor;  // RememberCard
-  void RememberCard(RawObject* const* slot);
+  void RememberCard(ObjectPtr const* slot);
 
   friend class Array;
   friend class ByteBuffer;
@@ -759,9 +658,10 @@
   friend class Mint;
   friend class Object;
   friend class OneByteString;  // StoreSmi
-  friend class RawInstance;
+  friend class InstanceLayout;
   friend class Scavenger;
-  friend class ScavengerVisitor;
+  template <bool>
+  friend class ScavengerVisitorBase;
   friend class ImageReader;  // tags_ check
   friend class ImageWriter;
   friend class AssemblyImageWriter;
@@ -781,12 +681,17 @@
   friend class ObjectLocator;
   friend class WriteBarrierUpdateVisitor;  // CheckHeapPointerStore
   friend class OffsetsTable;
+  friend class Object;
 
   DISALLOW_ALLOCATION();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectLayout);
 };
 
-class RawClass : public RawObject {
+inline intptr_t ObjectPtr::GetClassId() const {
+  return ptr()->GetClassId();
+}
+
+class ClassLayout : public ObjectLayout {
  public:
   enum ClassFinalizedState {
     kAllocated = 0,  // Initial state.
@@ -810,35 +715,35 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Class);
 
-  VISIT_FROM(RawObject*, name_);
-  RawString* name_;
-  RawString* user_name_;
-  RawArray* functions_;
-  RawArray* functions_hash_table_;
-  RawArray* fields_;
-  RawArray* offset_in_words_to_field_;
-  RawArray* interfaces_;  // Array of AbstractType.
-  RawScript* script_;
-  RawLibrary* library_;
-  RawTypeArguments* type_parameters_;  // Array of TypeParameter.
-  RawAbstractType* super_type_;
-  RawFunction* signature_function_;  // Associated function for typedef class.
-  RawArray* constants_;        // Canonicalized const instances of this class.
-  RawType* declaration_type_;  // Declaration type for this class.
-  RawArray* invocation_dispatcher_cache_;  // Cache for dispatcher functions.
-  RawCode* allocation_stub_;  // Stub code for allocation of instances.
-  RawGrowableObjectArray* direct_implementors_;  // Array of Class.
-  RawGrowableObjectArray* direct_subclasses_;    // Array of Class.
-  RawArray* dependent_code_;                     // CHA optimized codes.
-  VISIT_TO(RawObject*, dependent_code_);
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  VISIT_FROM(ObjectPtr, name_);
+  StringPtr name_;
+  StringPtr user_name_;
+  ArrayPtr functions_;
+  ArrayPtr functions_hash_table_;
+  ArrayPtr fields_;
+  ArrayPtr offset_in_words_to_field_;
+  ArrayPtr interfaces_;  // Array of AbstractType.
+  ScriptPtr script_;
+  LibraryPtr library_;
+  TypeArgumentsPtr type_parameters_;  // Array of TypeParameter.
+  AbstractTypePtr super_type_;
+  FunctionPtr signature_function_;  // Associated function for typedef class.
+  ArrayPtr constants_;        // Canonicalized const instances of this class.
+  TypePtr declaration_type_;  // Declaration type for this class.
+  ArrayPtr invocation_dispatcher_cache_;  // Cache for dispatcher functions.
+  CodePtr allocation_stub_;  // Stub code for allocation of instances.
+  GrowableObjectArrayPtr direct_implementors_;  // Array of Class.
+  GrowableObjectArrayPtr direct_subclasses_;    // Array of Class.
+  ArrayPtr dependent_code_;                     // CHA optimized codes.
+  VISIT_TO(ObjectPtr, dependent_code_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->allocation_stub_);
+        return reinterpret_cast<ObjectPtr*>(&allocation_stub_);
       case Snapshot::kFull:
-        return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
+        return reinterpret_cast<ObjectPtr*>(&direct_subclasses_);
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
+        return reinterpret_cast<ObjectPtr*>(&dependent_code_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -885,32 +790,32 @@
   friend class Instance;
   friend class Isolate;
   friend class Object;
-  friend class RawInstance;
-  friend class RawInstructions;
-  friend class RawTypeArguments;
+  friend class InstanceLayout;
+  friend class InstructionsLayout;
+  friend class TypeArgumentsLayout;
   friend class SnapshotReader;
   friend class InstanceSerializationCluster;
   friend class CidRewriteVisitor;
 };
 
-class RawPatchClass : public RawObject {
+class PatchClassLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(PatchClass);
 
-  VISIT_FROM(RawObject*, patched_class_);
-  RawClass* patched_class_;
-  RawClass* origin_class_;
-  RawScript* script_;
-  RawExternalTypedData* library_kernel_data_;
-  VISIT_TO(RawObject*, library_kernel_data_);
+  VISIT_FROM(ObjectPtr, patched_class_);
+  ClassPtr patched_class_;
+  ClassPtr origin_class_;
+  ScriptPtr script_;
+  ExternalTypedDataPtr library_kernel_data_;
+  VISIT_TO(ObjectPtr, library_kernel_data_);
 
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->script_);
+        return reinterpret_cast<ObjectPtr*>(&script_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->library_kernel_data_);
+        return reinterpret_cast<ObjectPtr*>(&library_kernel_data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -925,7 +830,7 @@
   friend class Function;
 };
 
-class RawFunction : public RawObject {
+class FunctionLayout : public ObjectLayout {
  public:
   // When you add a new kind, please also update the observatory to account
   // for the new string returned by KindToCString().
@@ -1076,22 +981,22 @@
   uword entry_point_;            // Accessed from generated code.
   uword unchecked_entry_point_;  // Accessed from generated code.
 
-  VISIT_FROM(RawObject*, name_);
-  RawString* name_;
-  RawObject* owner_;  // Class or patch class or mixin class
-                      // where this function is defined.
-  RawAbstractType* result_type_;
-  RawArray* parameter_types_;
-  RawArray* parameter_names_;
-  RawTypeArguments* type_parameters_;  // Array of TypeParameter.
-  RawObject* data_;  // Additional data specific to the function kind. See
-                     // Function::set_data() for details.
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  VISIT_FROM(ObjectPtr, name_);
+  StringPtr name_;
+  ObjectPtr owner_;  // Class or patch class or mixin class
+                     // where this function is defined.
+  AbstractTypePtr result_type_;
+  ArrayPtr parameter_types_;
+  ArrayPtr parameter_names_;
+  TypeArgumentsPtr type_parameters_;  // Array of TypeParameter.
+  ObjectPtr data_;  // Additional data specific to the function kind. See
+                    // Function::set_data() for details.
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->data_);
+        return reinterpret_cast<ObjectPtr*>(&data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1100,18 +1005,18 @@
     UNREACHABLE();
     return NULL;
   }
-  RawArray* ic_data_array_;  // ICData of unoptimized code.
-  RawObject** to_no_code() {
-    return reinterpret_cast<RawObject**>(&ptr()->ic_data_array_);
+  ArrayPtr ic_data_array_;  // ICData of unoptimized code.
+  ObjectPtr* to_no_code() {
+    return reinterpret_cast<ObjectPtr*>(&ic_data_array_);
   }
-  RawCode* code_;  // Currently active code. Accessed from generated code.
-  NOT_IN_PRECOMPILED(RawBytecode* bytecode_);
-  NOT_IN_PRECOMPILED(RawCode* unoptimized_code_);  // Unoptimized code, keep it
-                                                   // after optimization.
+  CodePtr code_;  // Currently active code. Accessed from generated code.
+  NOT_IN_PRECOMPILED(BytecodePtr bytecode_);
+  NOT_IN_PRECOMPILED(CodePtr unoptimized_code_);  // Unoptimized code, keep it
+                                                  // after optimization.
 #if defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(RawObject*, code_);
+  VISIT_TO(ObjectPtr, code_);
 #else
-  VISIT_TO(RawObject*, unoptimized_code_);
+  VISIT_TO(ObjectPtr, unoptimized_code_);
 #endif
 
   NOT_IN_PRECOMPILED(TokenPosition token_pos_);
@@ -1139,7 +1044,7 @@
       PackedNumOptionalParameters;
   static_assert(PackedNumOptionalParameters::kNextBit <=
                     kBitsPerWord * sizeof(decltype(packed_fields_)),
-                "RawFunction::packed_fields_ bitfields don't align.");
+                "FunctionLayout::packed_fields_ bitfields don't align.");
 
 #define JIT_FUNCTION_COUNTERS(F)                                               \
   F(intptr_t, int32_t, usage_counter)                                          \
@@ -1163,61 +1068,61 @@
   NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_);
 };
 
-class RawClosureData : public RawObject {
+class ClosureDataLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(ClosureData);
 
-  VISIT_FROM(RawObject*, context_scope_);
-  RawContextScope* context_scope_;
-  RawFunction* parent_function_;  // Enclosing function of this local function.
-  RawType* signature_type_;
-  RawInstance* closure_;  // Closure object for static implicit closures.
-  VISIT_TO(RawObject*, closure_);
+  VISIT_FROM(ObjectPtr, context_scope_);
+  ContextScopePtr context_scope_;
+  FunctionPtr parent_function_;  // Enclosing function of this local function.
+  TypePtr signature_type_;
+  InstancePtr closure_;  // Closure object for static implicit closures.
+  VISIT_TO(ObjectPtr, closure_);
 
   friend class Function;
 };
 
-class RawSignatureData : public RawObject {
+class SignatureDataLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(SignatureData);
 
-  VISIT_FROM(RawObject*, parent_function_);
-  RawFunction* parent_function_;  // Enclosing function of this sig. function.
-  RawType* signature_type_;
-  VISIT_TO(RawObject*, signature_type_);
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, parent_function_);
+  FunctionPtr parent_function_;  // Enclosing function of this sig. function.
+  TypePtr signature_type_;
+  VISIT_TO(ObjectPtr, signature_type_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class Function;
 };
 
-class RawRedirectionData : public RawObject {
+class RedirectionDataLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(RedirectionData);
 
-  VISIT_FROM(RawObject*, type_);
-  RawType* type_;
-  RawString* identifier_;
-  RawFunction* target_;
-  VISIT_TO(RawObject*, target_);
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, type_);
+  TypePtr type_;
+  StringPtr identifier_;
+  FunctionPtr target_;
+  VISIT_TO(ObjectPtr, target_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawFfiTrampolineData : public RawObject {
+class FfiTrampolineDataLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData);
 
-  VISIT_FROM(RawObject*, signature_type_);
-  RawType* signature_type_;
-  RawFunction* c_signature_;
+  VISIT_FROM(ObjectPtr, signature_type_);
+  TypePtr signature_type_;
+  FunctionPtr c_signature_;
 
   // Target Dart method for callbacks, otherwise null.
-  RawFunction* callback_target_;
+  FunctionPtr callback_target_;
 
   // For callbacks, value to return if Dart target throws an exception.
-  RawInstance* callback_exceptional_return_;
+  InstancePtr callback_exceptional_return_;
 
-  VISIT_TO(RawObject*, callback_exceptional_return_);
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_TO(ObjectPtr, callback_exceptional_return_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // Callback id for callbacks.
   //
@@ -1231,29 +1136,32 @@
   uint32_t callback_id_;
 };
 
-class RawField : public RawObject {
+class FieldLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
 
-  VISIT_FROM(RawObject*, name_);
-  RawString* name_;
-  RawObject* owner_;  // Class or patch class or mixin class
-                      // where this field is defined or original field.
-  RawAbstractType* type_;
-  RawFunction* initializer_function_;  // Static initializer function.
+  VISIT_FROM(ObjectPtr, name_);
+  StringPtr name_;
+  ObjectPtr owner_;  // Class or patch class or mixin class
+                     // where this field is defined or original field.
+  AbstractTypePtr type_;
+  FunctionPtr initializer_function_;  // Static initializer function.
+
+  // - for instance fields: offset in words to the value in the class instance.
+  // - for static fields: index into field_table.
+  SmiPtr host_offset_or_field_id_;
+
   // When generating APPJIT snapshots after running the application it is
   // necessary to save the initial value of static fields so that we can
   // restore the value back to the original initial value.
-  NOT_IN_PRECOMPILED(RawInstance* saved_initial_value_);  // Saved initial value
-  RawSmi* guarded_list_length_;
-  RawArray* dependent_code_;
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  NOT_IN_PRECOMPILED(InstancePtr saved_initial_value_);  // Saved initial value
+  SmiPtr guarded_list_length_;
+  ArrayPtr dependent_code_;
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFull:
-        return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->initializer_function_);
+        return reinterpret_cast<ObjectPtr*>(&initializer_function_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1263,10 +1171,10 @@
     return NULL;
   }
 #if defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(RawObject*, dependent_code_);
+  VISIT_TO(ObjectPtr, dependent_code_);
 #else
-  RawSubtypeTestCache* type_test_cache_;  // For type test in implicit setter.
-  VISIT_TO(RawObject*, type_test_cache_);
+  SubtypeTestCachePtr type_test_cache_;  // For type test in implicit setter.
+  VISIT_TO(ObjectPtr, type_test_cache_);
 #endif
   TokenPosition token_pos_;
   TokenPosition end_token_pos_;
@@ -1292,10 +1200,6 @@
 
   uint16_t kind_bits_;  // static, final, const, has initializer....
 
-  // - for instance fields: offset in words to the value in the class instance.
-  // - for static fields: index into field_table.
-  intptr_t host_offset_or_field_id_;
-
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // for instance fields, the offset in words in the target architecture
   int32_t target_offset_;
@@ -1304,7 +1208,7 @@
   friend class CidRewriteVisitor;
 };
 
-class RawScript : public RawObject {
+class ScriptLayout : public ObjectLayout {
  public:
   enum {
     kLazyLookupSourceAndLineStartsPos = 0,
@@ -1314,22 +1218,22 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Script);
 
-  VISIT_FROM(RawObject*, url_);
-  RawString* url_;
-  RawString* resolved_url_;
-  RawArray* compile_time_constants_;
-  RawTypedData* line_starts_;
-  RawArray* debug_positions_;
-  RawKernelProgramInfo* kernel_program_info_;
-  RawString* source_;
-  VISIT_TO(RawObject*, source_);
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  VISIT_FROM(ObjectPtr, url_);
+  StringPtr url_;
+  StringPtr resolved_url_;
+  ArrayPtr compile_time_constants_;
+  TypedDataPtr line_starts_;
+  ArrayPtr debug_positions_;
+  KernelProgramInfoPtr kernel_program_info_;
+  StringPtr source_;
+  VISIT_TO(ObjectPtr, source_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->url_);
+        return reinterpret_cast<ObjectPtr*>(&url_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->kernel_program_info_);
+        return reinterpret_cast<ObjectPtr*>(&kernel_program_info_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1353,7 +1257,7 @@
   int64_t load_timestamp_;
 };
 
-class RawLibrary : public RawObject {
+class LibraryLayout : public ObjectLayout {
   enum LibraryState {
     kAllocated,       // Initial state.
     kLoadRequested,   // Compiler or script requested load of library.
@@ -1383,24 +1287,24 @@
 
   RAW_HEAP_OBJECT_IMPLEMENTATION(Library);
 
-  VISIT_FROM(RawObject*, name_);
-  RawString* name_;
-  RawString* url_;
-  RawString* private_key_;
-  RawArray* dictionary_;              // Top-level names in this library.
-  RawGrowableObjectArray* metadata_;  // Metadata on classes, methods etc.
-  RawClass* toplevel_class_;          // Class containing top-level elements.
-  RawGrowableObjectArray* used_scripts_;
-  RawArray* imports_;        // List of Namespaces imported without prefix.
-  RawArray* exports_;        // List of re-exported Namespaces.
-  RawExternalTypedData* kernel_data_;
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  VISIT_FROM(ObjectPtr, name_);
+  StringPtr name_;
+  StringPtr url_;
+  StringPtr private_key_;
+  ArrayPtr dictionary_;              // Top-level names in this library.
+  GrowableObjectArrayPtr metadata_;  // Metadata on classes, methods etc.
+  ClassPtr toplevel_class_;          // Class containing top-level elements.
+  GrowableObjectArrayPtr used_scripts_;
+  ArrayPtr imports_;  // List of Namespaces imported without prefix.
+  ArrayPtr exports_;  // List of re-exported Namespaces.
+  ExternalTypedDataPtr kernel_data_;
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->exports_);
+        return reinterpret_cast<ObjectPtr*>(&exports_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->kernel_data_);
+        return reinterpret_cast<ObjectPtr*>(&kernel_data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1409,10 +1313,10 @@
     UNREACHABLE();
     return NULL;
   }
-  RawArray* resolved_names_;  // Cache of resolved names in library scope.
-  RawArray* exported_names_;  // Cache of exported names by library.
-  RawArray* loaded_scripts_;  // Array of scripts loaded in this library.
-  VISIT_TO(RawObject*, loaded_scripts_);
+  ArrayPtr resolved_names_;  // Cache of resolved names in library scope.
+  ArrayPtr exported_names_;  // Cache of exported names by library.
+  ArrayPtr loaded_scripts_;  // Array of scripts loaded in this library.
+  VISIT_TO(ObjectPtr, loaded_scripts_);
 
   Dart_NativeEntryResolver native_entry_resolver_;  // Resolves natives.
   Dart_NativeEntrySymbol native_entry_symbol_resolver_;
@@ -1431,60 +1335,60 @@
   friend class Isolate;
 };
 
-class RawNamespace : public RawObject {
+class NamespaceLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace);
 
-  VISIT_FROM(RawObject*, library_);
-  RawLibrary* library_;       // library with name dictionary.
-  RawArray* show_names_;      // list of names that are exported.
-  RawArray* hide_names_;      // blacklist of names that are not exported.
-  RawField* metadata_field_;  // remembers the token pos of metadata if any,
-                              // and the metadata values if computed.
-  VISIT_TO(RawObject*, metadata_field_);
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, library_);
+  LibraryPtr library_;       // library with name dictionary.
+  ArrayPtr show_names_;      // list of names that are exported.
+  ArrayPtr hide_names_;      // blacklist of names that are not exported.
+  FieldPtr metadata_field_;  // remembers the token pos of metadata if any,
+                             // and the metadata values if computed.
+  VISIT_TO(ObjectPtr, metadata_field_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawKernelProgramInfo : public RawObject {
+class KernelProgramInfoLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo);
 
-  VISIT_FROM(RawObject*, string_offsets_);
-  RawTypedData* string_offsets_;
-  RawExternalTypedData* string_data_;
-  RawTypedData* canonical_names_;
-  RawExternalTypedData* metadata_payloads_;
-  RawExternalTypedData* metadata_mappings_;
-  RawArray* scripts_;
-  RawArray* constants_;
-  RawArray* bytecode_component_;
-  RawGrowableObjectArray* potential_natives_;
-  RawGrowableObjectArray* potential_pragma_functions_;
-  RawExternalTypedData* constants_table_;
-  RawArray* libraries_cache_;
-  RawArray* classes_cache_;
-  RawObject* retained_kernel_blob_;
-  VISIT_TO(RawObject*, retained_kernel_blob_);
+  VISIT_FROM(ObjectPtr, string_offsets_);
+  TypedDataPtr string_offsets_;
+  ExternalTypedDataPtr string_data_;
+  TypedDataPtr canonical_names_;
+  ExternalTypedDataPtr metadata_payloads_;
+  ExternalTypedDataPtr metadata_mappings_;
+  ArrayPtr scripts_;
+  ArrayPtr constants_;
+  ArrayPtr bytecode_component_;
+  GrowableObjectArrayPtr potential_natives_;
+  GrowableObjectArrayPtr potential_pragma_functions_;
+  ExternalTypedDataPtr constants_table_;
+  ArrayPtr libraries_cache_;
+  ArrayPtr classes_cache_;
+  ObjectPtr retained_kernel_blob_;
+  VISIT_TO(ObjectPtr, retained_kernel_blob_);
 
   uint32_t kernel_binary_version_;
 
-  RawObject** to_snapshot(Snapshot::Kind kind) {
-    return reinterpret_cast<RawObject**>(&ptr()->constants_table_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+    return reinterpret_cast<ObjectPtr*>(&constants_table_);
   }
 };
 
-class RawWeakSerializationReference : public RawObject {
+class WeakSerializationReferenceLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(WeakSerializationReference);
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   VISIT_NOTHING();
   classid_t cid_;
 #else
-  VISIT_FROM(RawObject*, target_);
-  RawObject* target_;
-  VISIT_TO(RawObject*, target_);
+  VISIT_FROM(ObjectPtr, target_);
+  ObjectPtr target_;
+  VISIT_TO(ObjectPtr, target_);
 #endif
 };
 
-class RawCode : public RawObject {
+class CodeLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
 
   // When in the precompiled runtime, there is no disabling of Code objects
@@ -1533,39 +1437,39 @@
   uword unchecked_entry_point_;              // Accessed from generated code.
   uword monomorphic_unchecked_entry_point_;  // Accessed from generated code.
 
-  VISIT_FROM(RawObject*, object_pool_);
-  RawObjectPool* object_pool_;     // Accessed from generated code.
-  RawInstructions* instructions_;  // Accessed from generated code.
+  VISIT_FROM(ObjectPtr, object_pool_);
+  ObjectPoolPtr object_pool_;     // Accessed from generated code.
+  InstructionsPtr instructions_;  // Accessed from generated code.
   // If owner_ is Function::null() the owner is a regular stub.
   // If owner_ is a Class the owner is the allocation stub for that class.
   // Else, owner_ is a regular Dart Function.
-  RawObject* owner_;  // Function, Null, or a Class.
-  RawExceptionHandlers* exception_handlers_;
-  RawPcDescriptors* pc_descriptors_;
+  ObjectPtr owner_;  // Function, Null, or a Class.
+  ExceptionHandlersPtr exception_handlers_;
+  PcDescriptorsPtr pc_descriptors_;
   // If FLAG_precompiled_mode, then this field contains
-  //   RawTypedData* catch_entry_moves_maps
+  //   TypedDataPtr catch_entry_moves_maps
   // Otherwise, it is
-  //   RawSmi* num_variables
-  RawObject* catch_entry_;
-  RawCompressedStackMaps* compressed_stackmaps_;
-  RawArray* inlined_id_to_function_;
-  RawCodeSourceMap* code_source_map_;
-  NOT_IN_PRECOMPILED(RawInstructions* active_instructions_);
-  NOT_IN_PRECOMPILED(RawArray* deopt_info_array_);
+  //   SmiPtr num_variables
+  ObjectPtr catch_entry_;
+  CompressedStackMapsPtr compressed_stackmaps_;
+  ArrayPtr inlined_id_to_function_;
+  CodeSourceMapPtr code_source_map_;
+  NOT_IN_PRECOMPILED(InstructionsPtr active_instructions_);
+  NOT_IN_PRECOMPILED(ArrayPtr deopt_info_array_);
   // (code-offset, function, code) triples.
-  NOT_IN_PRECOMPILED(RawArray* static_calls_target_table_);
+  NOT_IN_PRECOMPILED(ArrayPtr static_calls_target_table_);
   // If return_address_metadata_ is a Smi, it is the offset to the prologue.
   // Else, return_address_metadata_ is null.
-  NOT_IN_PRODUCT(RawObject* return_address_metadata_);
-  NOT_IN_PRODUCT(RawLocalVarDescriptors* var_descriptors_);
-  NOT_IN_PRODUCT(RawArray* comments_);
+  NOT_IN_PRODUCT(ObjectPtr return_address_metadata_);
+  NOT_IN_PRODUCT(LocalVarDescriptorsPtr var_descriptors_);
+  NOT_IN_PRODUCT(ArrayPtr comments_);
 
 #if !defined(PRODUCT)
-  VISIT_TO(RawObject*, comments_);
+  VISIT_TO(ObjectPtr, comments_);
 #elif defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(RawObject*, code_source_map_);
+  VISIT_TO(ObjectPtr, code_source_map_);
 #else
-  VISIT_TO(RawObject*, static_calls_target_table_);
+  VISIT_TO(ObjectPtr, static_calls_target_table_);
 #endif
 
   // Compilation timestamp.
@@ -1586,7 +1490,7 @@
   int32_t* data() { OPEN_ARRAY_START(int32_t, int32_t); }
   const int32_t* data() const { OPEN_ARRAY_START(int32_t, int32_t); }
 
-  static bool ContainsPC(const RawObject* raw_obj, uword pc);
+  static bool ContainsPC(const ObjectPtr raw_obj, uword pc);
 
   friend class Function;
   template <bool>
@@ -1597,47 +1501,47 @@
   friend class CallSiteResetter;
 };
 
-class RawBytecode : public RawObject {
+class BytecodeLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Bytecode);
 
   uword instructions_;
   intptr_t instructions_size_;
 
-  VISIT_FROM(RawObject*, object_pool_);
-  RawObjectPool* object_pool_;
-  RawFunction* function_;
-  RawArray* closures_;
-  RawExceptionHandlers* exception_handlers_;
-  RawPcDescriptors* pc_descriptors_;
-  NOT_IN_PRODUCT(RawLocalVarDescriptors* var_descriptors_);
+  VISIT_FROM(ObjectPtr, object_pool_);
+  ObjectPoolPtr object_pool_;
+  FunctionPtr function_;
+  ArrayPtr closures_;
+  ExceptionHandlersPtr exception_handlers_;
+  PcDescriptorsPtr pc_descriptors_;
+  NOT_IN_PRODUCT(LocalVarDescriptorsPtr var_descriptors_);
 #if defined(PRODUCT)
-  VISIT_TO(RawObject*, pc_descriptors_);
+  VISIT_TO(ObjectPtr, pc_descriptors_);
 #else
-  VISIT_TO(RawObject*, var_descriptors_);
+  VISIT_TO(ObjectPtr, var_descriptors_);
 #endif
 
-  RawObject** to_snapshot(Snapshot::Kind kind) {
-    return reinterpret_cast<RawObject**>(&ptr()->pc_descriptors_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+    return reinterpret_cast<ObjectPtr*>(&pc_descriptors_);
   }
 
   int32_t instructions_binary_offset_;
   int32_t source_positions_binary_offset_;
   int32_t local_variables_binary_offset_;
 
-  static bool ContainsPC(RawObject* raw_obj, uword pc);
+  static bool ContainsPC(ObjectPtr raw_obj, uword pc);
 
   friend class Function;
   friend class StackFrame;
 };
 
-class RawObjectPool : public RawObject {
+class ObjectPoolLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ObjectPool);
 
   intptr_t length_;
 
   struct Entry {
     union {
-      RawObject* raw_obj_;
+      ObjectPtr raw_obj_;
       uword raw_value_;
     };
   };
@@ -1655,7 +1559,7 @@
   friend class CodeSerializationCluster;
 };
 
-class RawInstructions : public RawObject {
+class InstructionsLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Instructions);
   VISIT_NOTHING();
 
@@ -1669,10 +1573,10 @@
   // Private helper function used while visiting stack frames. The
   // code which iterates over dart frames is also called during GC and
   // is not allowed to create handles.
-  static bool ContainsPC(const RawInstructions* raw_instr, uword pc);
+  static bool ContainsPC(const InstructionsPtr raw_instr, uword pc);
 
-  friend class RawCode;
-  friend class RawFunction;
+  friend class CodeLayout;
+  friend class FunctionLayout;
   friend class Code;
   friend class StackFrame;
   template <bool>
@@ -1686,7 +1590,7 @@
 
 // Used only to provide memory accounting for the bare instruction payloads
 // we serialize, since they are no longer part of RawInstructions objects.
-class RawInstructionsSection : public RawObject {
+class InstructionsSectionLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(InstructionsSection);
   VISIT_NOTHING();
 
@@ -1697,7 +1601,7 @@
   uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
 };
 
-class RawPcDescriptors : public RawObject {
+class PcDescriptorsLayout : public ObjectLayout {
  public:
 // The macro argument V is passed two arguments, the raw name of the enum value
 // and the initialization expression used within the enum definition.  The uses
@@ -1804,7 +1708,7 @@
 
 // CodeSourceMap encodes a mapping from code PC ranges to source token
 // positions and the stack of inlined functions.
-class RawCodeSourceMap : public RawObject {
+class CodeSourceMapLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap);
   VISIT_NOTHING();
@@ -1824,7 +1728,7 @@
 // RawCompressedStackMaps is a compressed representation of the stack maps
 // for certain PC offsets into a set of instructions, where a stack map is a bit
 // map that marks each live object index starting from the base of the frame.
-class RawCompressedStackMaps : public RawObject {
+class CompressedStackMapsLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(CompressedStackMaps);
   VISIT_NOTHING();
 
@@ -1895,7 +1799,7 @@
   friend class ImageWriter;
 };
 
-class RawLocalVarDescriptors : public RawObject {
+class LocalVarDescriptorsLayout : public ObjectLayout {
  public:
   enum VarInfoKind {
     kStackVar = 1,
@@ -1946,23 +1850,23 @@
   // platforms.
   uword num_entries_;
 
-  VISIT_FROM(RawObject*, names()[0]);
-  RawString** names() {
+  VISIT_FROM(ObjectPtr, names()[0]);
+  StringPtr* names() {
     // Array of [num_entries_] variable names.
-    OPEN_ARRAY_START(RawString*, RawString*);
+    OPEN_ARRAY_START(StringPtr, StringPtr);
   }
-  RawString** nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); }
-  VISIT_TO_LENGTH(RawObject*, nameAddrAt(length - 1));
+  StringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); }
+  VISIT_TO_LENGTH(ObjectPtr, nameAddrAt(length - 1));
 
   // Variable info with [num_entries_] entries.
   VarInfo* data() {
-    return reinterpret_cast<VarInfo*>(nameAddrAt(ptr()->num_entries_));
+    return reinterpret_cast<VarInfo*>(nameAddrAt(num_entries_));
   }
 
   friend class Object;
 };
 
-class RawExceptionHandlers : public RawObject {
+class ExceptionHandlersLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExceptionHandlers);
 
@@ -1971,9 +1875,9 @@
 
   // Array with [num_entries_] entries. Each entry is an array of all handled
   // exception types.
-  VISIT_FROM(RawObject*, handled_types_data_)
-  RawArray* handled_types_data_;
-  VISIT_TO_LENGTH(RawObject*, &ptr()->handled_types_data_);
+  VISIT_FROM(ObjectPtr, handled_types_data_)
+  ArrayPtr handled_types_data_;
+  VISIT_TO_LENGTH(ObjectPtr, &handled_types_data_);
 
   // Exception handler info of length [num_entries_].
   const ExceptionHandlerInfo* data() const {
@@ -1986,130 +1890,138 @@
   friend class Object;
 };
 
-class RawContext : public RawObject {
+class ContextLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Context);
 
   int32_t num_variables_;
 
-  VISIT_FROM(RawObject*, parent_);
-  RawContext* parent_;
+  VISIT_FROM(ObjectPtr, parent_);
+  ContextPtr parent_;
 
   // Variable length data follows here.
-  RawObject** data() { OPEN_ARRAY_START(RawObject*, RawObject*); }
-  RawObject* const* data() const { OPEN_ARRAY_START(RawObject*, RawObject*); }
-  VISIT_TO_LENGTH(RawObject*, &ptr()->data()[length - 1]);
+  ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  VISIT_TO_LENGTH(ObjectPtr, &data()[length - 1]);
 
   friend class Object;
   friend class SnapshotReader;
 };
 
-class RawContextScope : public RawObject {
+class ContextScopeLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ContextScope);
 
   // TODO(iposva): Switch to conventional enum offset based structure to avoid
   // alignment mishaps.
   struct VariableDesc {
-    RawSmi* declaration_token_pos;
-    RawSmi* token_pos;
-    RawString* name;
-    RawSmi* flags;
+    SmiPtr declaration_token_pos;
+    SmiPtr token_pos;
+    StringPtr name;
+    SmiPtr flags;
     static constexpr intptr_t kIsFinal = 0x1;
     static constexpr intptr_t kIsConst = 0x2;
     static constexpr intptr_t kIsLate = 0x4;
-    RawSmi* late_init_offset;
+    SmiPtr late_init_offset;
     union {
-      RawAbstractType* type;
-      RawInstance* value;  // iff is_const is true
+      AbstractTypePtr type;
+      InstancePtr value;  // iff is_const is true
     };
-    RawSmi* context_index;
-    RawSmi* context_level;
+    SmiPtr context_index;
+    SmiPtr context_level;
   };
 
   int32_t num_variables_;
   bool is_implicit_;  // true, if this context scope is for an implicit closure.
 
-  RawObject** from() {
-    VariableDesc* begin = const_cast<VariableDesc*>(ptr()->VariableDescAddr(0));
-    return reinterpret_cast<RawObject**>(begin);
+  ObjectPtr* from() {
+    VariableDesc* begin = const_cast<VariableDesc*>(VariableDescAddr(0));
+    return reinterpret_cast<ObjectPtr*>(begin);
   }
   // Variable length data follows here.
-  RawObject* const* data() const { OPEN_ARRAY_START(RawObject*, RawObject*); }
+  ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
   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]);
   }
-  RawObject** to(intptr_t num_vars) {
-    uword end = reinterpret_cast<uword>(ptr()->VariableDescAddr(num_vars));
+  ObjectPtr* 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<RawObject**>(end - kWordSize);
+    return reinterpret_cast<ObjectPtr*>(end - kWordSize);
   }
-  RawObject** to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
+  ObjectPtr* to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
     return to(num_vars);
   }
 
   friend class Object;
-  friend class RawClosureData;
+  friend class ClosureDataLayout;
   friend class SnapshotReader;
 };
 
-class RawParameterTypeCheck : public RawObject {
+class ParameterTypeCheckLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck);
   intptr_t index_;
-  VISIT_FROM(RawObject*, param_);
-  RawAbstractType* param_;
-  RawAbstractType* type_or_bound_;
-  RawString* name_;
-  RawSubtypeTestCache* cache_;
-  VISIT_TO(RawObject*, cache_);
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, param_);
+  AbstractTypePtr param_;
+  AbstractTypePtr type_or_bound_;
+  StringPtr name_;
+  SubtypeTestCachePtr cache_;
+  VISIT_TO(ObjectPtr, cache_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawSingleTargetCache : public RawObject {
+class SingleTargetCacheLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache);
-  VISIT_FROM(RawObject*, target_);
-  RawCode* target_;
-  VISIT_TO(RawObject*, target_);
+  VISIT_FROM(ObjectPtr, target_);
+  CodePtr target_;
+  VISIT_TO(ObjectPtr, target_);
   uword entry_point_;
   classid_t lower_limit_;
   classid_t upper_limit_;
 };
 
-class RawUnlinkedCall : public RawObject {
+class UnlinkedCallLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall);
-  VISIT_FROM(RawObject*, target_name_);
-  RawString* target_name_;
-  RawArray* args_descriptor_;
-  VISIT_TO(RawObject*, args_descriptor_);
+  VISIT_FROM(ObjectPtr, target_name_);
+  StringPtr target_name_;
+  ArrayPtr args_descriptor_;
+  VISIT_TO(ObjectPtr, args_descriptor_);
   bool can_patch_to_monomorphic_;
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawMonomorphicSmiableCall : public RawObject {
+class MonomorphicSmiableCallLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MonomorphicSmiableCall);
-  VISIT_FROM(RawObject*, target_);
-  RawCode* target_;  // Entrypoint PC in bare mode, Code in non-bare mode.
-  VISIT_TO(RawObject*, target_);
+  VISIT_FROM(ObjectPtr, target_);
+  CodePtr target_;  // Entrypoint PC in bare mode, Code in non-bare mode.
+  VISIT_TO(ObjectPtr, target_);
   uword expected_cid_;
   uword entrypoint_;
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawICData : public RawObject {
-  RAW_HEAP_OBJECT_IMPLEMENTATION(ICData);
+// Abstract base class for RawICData/RawMegamorphicCache
+class CallSiteDataLayout : public ObjectLayout {
+ protected:
+  StringPtr target_name_;  // Name of target function.
+  // arg_descriptor in RawICData and in RawMegamorphicCache should be
+  // in the same position so that NoSuchMethod can access it.
+  ArrayPtr args_descriptor_;  // Arguments descriptor.
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(CallSiteData)
+};
 
-  VISIT_FROM(RawObject*, entries_);
-  RawArray* entries_;          // Contains class-ids, target and count.
-  RawString* target_name_;     // Name of target function.
-  RawArray* args_descriptor_;  // Arguments descriptor.
+class ICDataLayout : public CallSiteDataLayout {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(ICData);
+  VISIT_FROM(ObjectPtr, target_name_);
+  ArrayPtr entries_;  // Contains class-ids, target and count.
   // Static type of the receiver, if instance call and available.
-  NOT_IN_PRECOMPILED(RawAbstractType* receivers_static_type_);
-  RawObject* owner_;  // Parent/calling function or original IC of cloned IC.
-  VISIT_TO(RawObject*, owner_);
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  NOT_IN_PRECOMPILED(AbstractTypePtr receivers_static_type_);
+  ObjectPtr owner_;  // Parent/calling function or original IC of cloned IC.
+  VISIT_TO(ObjectPtr, owner_);
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->args_descriptor_);
+        return reinterpret_cast<ObjectPtr*>(&entries_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
         return to();
@@ -2125,93 +2037,90 @@
   uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons.
 };
 
-class RawMegamorphicCache : public RawObject {
+class MegamorphicCacheLayout : public CallSiteDataLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MegamorphicCache);
-
-  VISIT_FROM(RawObject*, buckets_)
-  RawArray* buckets_;
-  RawSmi* mask_;
-  RawString* target_name_;     // Name of target function.
-  RawArray* args_descriptor_;  // Arguments descriptor.
-  VISIT_TO(RawObject*, args_descriptor_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, target_name_)
+  ArrayPtr buckets_;
+  SmiPtr mask_;
+  VISIT_TO(ObjectPtr, mask_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   int32_t filled_entry_count_;
 };
 
-class RawSubtypeTestCache : public RawObject {
+class SubtypeTestCacheLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(SubtypeTestCache);
-  VISIT_FROM(RawObject*, cache_);
-  RawArray* cache_;
-  VISIT_TO(RawObject*, cache_);
+  VISIT_FROM(ObjectPtr, cache_);
+  ArrayPtr cache_;
+  VISIT_TO(ObjectPtr, cache_);
 };
 
-class RawError : public RawObject {
+class ErrorLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Error);
 };
 
-class RawApiError : public RawError {
+class ApiErrorLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ApiError);
 
-  VISIT_FROM(RawObject*, message_)
-  RawString* message_;
-  VISIT_TO(RawObject*, message_)
+  VISIT_FROM(ObjectPtr, message_)
+  StringPtr message_;
+  VISIT_TO(ObjectPtr, message_)
 };
 
-class RawLanguageError : public RawError {
+class LanguageErrorLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LanguageError);
 
-  VISIT_FROM(RawObject*, previous_error_)
-  RawError* previous_error_;  // May be null.
-  RawScript* script_;
-  RawString* message_;
-  RawString* formatted_message_;  // Incl. previous error's formatted message.
-  VISIT_TO(RawObject*, formatted_message_)
+  VISIT_FROM(ObjectPtr, previous_error_)
+  ErrorPtr previous_error_;  // May be null.
+  ScriptPtr script_;
+  StringPtr message_;
+  StringPtr formatted_message_;  // Incl. previous error's formatted message.
+  VISIT_TO(ObjectPtr, formatted_message_)
   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.
 
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawUnhandledException : public RawError {
+class UnhandledExceptionLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnhandledException);
 
-  VISIT_FROM(RawObject*, exception_)
-  RawInstance* exception_;
-  RawInstance* stacktrace_;
-  VISIT_TO(RawObject*, stacktrace_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, exception_)
+  InstancePtr exception_;
+  InstancePtr stacktrace_;
+  VISIT_TO(ObjectPtr, stacktrace_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawUnwindError : public RawError {
+class UnwindErrorLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnwindError);
 
-  VISIT_FROM(RawObject*, message_)
-  RawString* message_;
-  VISIT_TO(RawObject*, message_)
+  VISIT_FROM(ObjectPtr, message_)
+  StringPtr message_;
+  VISIT_TO(ObjectPtr, message_)
   bool is_user_initiated_;
 };
 
-class RawInstance : public RawObject {
+class InstanceLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Instance);
 };
 
-class RawLibraryPrefix : public RawInstance {
+class LibraryPrefixLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix);
 
-  VISIT_FROM(RawObject*, name_)
-  RawString* name_;           // Library prefix name.
-  RawLibrary* importer_;      // Library which declares this prefix.
-  RawArray* imports_;         // Libraries imported with this prefix.
-  VISIT_TO(RawObject*, imports_)
-  RawObject** to_snapshot(Snapshot::Kind kind) {
+  VISIT_FROM(ObjectPtr, name_)
+  StringPtr name_;       // Library prefix name.
+  LibraryPtr importer_;  // Library which declares this prefix.
+  ArrayPtr imports_;     // Libraries imported with this prefix.
+  VISIT_TO(ObjectPtr, imports_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<RawObject**>(&ptr()->imports_);
+        return reinterpret_cast<ObjectPtr*>(&imports_);
       case Snapshot::kFullAOT:
-        return reinterpret_cast<RawObject**>(&ptr()->importer_);
+        return reinterpret_cast<ObjectPtr*>(&importer_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -2224,33 +2133,33 @@
   bool is_deferred_load_;
 };
 
-class RawTypeArguments : public RawInstance {
+class TypeArgumentsLayout : public InstanceLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeArguments);
 
-  VISIT_FROM(RawObject*, instantiations_)
+  VISIT_FROM(ObjectPtr, instantiations_)
   // The instantiations_ array remains empty for instantiated type arguments.
-  RawArray* instantiations_;  // Of 3-tuple: 2 instantiators, result.
-  RawSmi* length_;
-  RawSmi* hash_;
-  RawSmi* nullability_;
+  ArrayPtr instantiations_;  // Of 3-tuple: 2 instantiators, result.
+  SmiPtr length_;
+  SmiPtr hash_;
+  SmiPtr nullability_;
 
   // Variable length data follows here.
-  RawAbstractType* const* types() const {
-    OPEN_ARRAY_START(RawAbstractType*, RawAbstractType*);
+  AbstractTypePtr const* types() const {
+    OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
   }
-  RawAbstractType** types() {
-    OPEN_ARRAY_START(RawAbstractType*, RawAbstractType*);
+  AbstractTypePtr* types() {
+    OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
   }
-  RawObject** to(intptr_t length) {
-    return reinterpret_cast<RawObject**>(&ptr()->types()[length - 1]);
+  ObjectPtr* to(intptr_t length) {
+    return reinterpret_cast<ObjectPtr*>(&types()[length - 1]);
   }
 
   friend class Object;
   friend class SnapshotReader;
 };
 
-class RawAbstractType : public RawInstance {
+class AbstractTypeLayout : public InstanceLayout {
  public:
   enum TypeState {
     kAllocated,                // Initial state.
@@ -2261,8 +2170,8 @@
 
  protected:
   uword type_test_stub_entry_point_;  // Accessed from generated code.
-  RawCode* type_test_stub_;  // Must be the last field, since subclasses use it
-                             // in their VISIT_FROM.
+  CodePtr type_test_stub_;  // Must be the last field, since subclasses use it
+                            // in their VISIT_FROM.
 
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
@@ -2271,39 +2180,39 @@
   friend class StubCode;
 };
 
-class RawType : public RawAbstractType {
+class TypeLayout : public AbstractTypeLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
-  VISIT_FROM(RawObject*, type_test_stub_)
-  RawSmi* type_class_id_;
-  RawTypeArguments* arguments_;
-  RawSmi* hash_;
+  VISIT_FROM(ObjectPtr, type_test_stub_)
+  SmiPtr type_class_id_;
+  TypeArgumentsPtr arguments_;
+  SmiPtr hash_;
   // This type object represents a function type if its signature field is a
   // non-null function object.
-  RawFunction* signature_;  // If not null, this type is a function type.
-  VISIT_TO(RawObject*, signature_)
+  FunctionPtr signature_;  // If not null, this type is a function type.
+  VISIT_TO(ObjectPtr, signature_)
   TokenPosition token_pos_;
   int8_t type_state_;
   int8_t nullability_;
 
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class CidRewriteVisitor;
-  friend class RawTypeArguments;
+  friend class TypeArgumentsLayout;
 };
 
-class RawTypeRef : public RawAbstractType {
+class TypeRefLayout : public AbstractTypeLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
 
-  VISIT_FROM(RawObject*, type_test_stub_)
-  RawAbstractType* type_;  // The referenced type.
-  VISIT_TO(RawObject*, type_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, type_test_stub_)
+  AbstractTypePtr type_;  // The referenced type.
+  VISIT_TO(ObjectPtr, type_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
-class RawTypeParameter : public RawAbstractType {
+class TypeParameterLayout : public AbstractTypeLayout {
  public:
   enum {
     kFinalizedBit = 0,
@@ -2316,24 +2225,24 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
 
-  VISIT_FROM(RawObject*, type_test_stub_)
-  RawString* name_;
-  RawSmi* hash_;
-  RawAbstractType* bound_;  // ObjectType if no explicit bound specified.
-  RawFunction* parameterized_function_;
-  VISIT_TO(RawObject*, parameterized_function_)
+  VISIT_FROM(ObjectPtr, type_test_stub_)
+  StringPtr name_;
+  SmiPtr hash_;
+  AbstractTypePtr bound_;  // ObjectType if no explicit bound specified.
+  FunctionPtr parameterized_function_;
+  VISIT_TO(ObjectPtr, parameterized_function_)
   classid_t parameterized_class_id_;
   TokenPosition token_pos_;
   int16_t index_;
   uint8_t flags_;
   int8_t nullability_;
 
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class CidRewriteVisitor;
 };
 
-class RawClosure : public RawInstance {
+class ClosureLayout : public InstanceLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Closure);
 
@@ -2343,16 +2252,16 @@
   // The following fields are also declared in the Dart source of class
   // _Closure.
   VISIT_FROM(RawCompressed, instantiator_type_arguments_)
-  RawTypeArguments* instantiator_type_arguments_;
-  RawTypeArguments* function_type_arguments_;
-  RawTypeArguments* delayed_type_arguments_;
-  RawFunction* function_;
-  RawContext* context_;
-  RawSmi* hash_;
+  TypeArgumentsPtr instantiator_type_arguments_;
+  TypeArgumentsPtr function_type_arguments_;
+  TypeArgumentsPtr delayed_type_arguments_;
+  FunctionPtr function_;
+  ContextPtr context_;
+  SmiPtr hash_;
 
   VISIT_TO(RawCompressed, hash_)
 
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // Note that instantiator_type_arguments_, function_type_arguments_ and
   // delayed_type_arguments_ are used to instantiate the signature of function_
@@ -2378,19 +2287,19 @@
   // any type arguments passed directly (or NSM will be invoked instead).
 };
 
-class RawNumber : public RawInstance {
+class NumberLayout : public InstanceLayout {
   RAW_OBJECT_IMPLEMENTATION(Number);
 };
 
-class RawInteger : public RawNumber {
+class IntegerLayout : public NumberLayout {
   RAW_OBJECT_IMPLEMENTATION(Integer);
 };
 
-class RawSmi : public RawInteger {
+class SmiLayout : public IntegerLayout {
   RAW_OBJECT_IMPLEMENTATION(Smi);
 };
 
-class RawMint : public RawInteger {
+class MintLayout : public IntegerLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Mint);
   VISIT_NOTHING();
 
@@ -2401,9 +2310,9 @@
   friend class Integer;
   friend class SnapshotReader;
 };
-COMPILE_ASSERT(sizeof(RawMint) == 16);
+COMPILE_ASSERT(sizeof(MintLayout) == 16);
 
-class RawDouble : public RawNumber {
+class DoubleLayout : public NumberLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Double);
   VISIT_NOTHING();
 
@@ -2413,19 +2322,19 @@
   friend class SnapshotReader;
   friend class Class;
 };
-COMPILE_ASSERT(sizeof(RawDouble) == 16);
+COMPILE_ASSERT(sizeof(DoubleLayout) == 16);
 
-class RawString : public RawInstance {
+class StringLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(String);
 
  protected:
-  VISIT_FROM(RawObject*, length_)
-  RawSmi* length_;
+  VISIT_FROM(ObjectPtr, length_)
+  SmiPtr length_;
 #if !defined(HASH_IN_OBJECT_HEADER)
-  RawSmi* hash_;
-  VISIT_TO(RawObject*, hash_)
+  SmiPtr hash_;
+  VISIT_TO(ObjectPtr, hash_)
 #else
-  VISIT_TO(RawObject*, length_)
+  VISIT_TO(ObjectPtr, length_)
 #endif
 
  private:
@@ -2438,7 +2347,7 @@
   friend class ImageWriter;
 };
 
-class RawOneByteString : public RawString {
+class OneByteStringLayout : public StringLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(OneByteString);
   VISIT_NOTHING();
 
@@ -2452,7 +2361,7 @@
   friend class String;
 };
 
-class RawTwoByteString : public RawString {
+class TwoByteStringLayout : public StringLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(TwoByteString);
   VISIT_NOTHING();
 
@@ -2470,7 +2379,7 @@
 //
 // TypedData extends this with a length field, while Pointer extends this with
 // TypeArguments field.
-class RawPointerBase : public RawInstance {
+class PointerBaseLayout : public InstanceLayout {
  protected:
   // The contents of [data_] depends on what concrete subclass is used:
   //
@@ -2490,31 +2399,31 @@
 };
 
 // Abstract base class for RawTypedData/RawExternalTypedData/RawTypedDataView.
-class RawTypedDataBase : public RawPointerBase {
+class TypedDataBaseLayout : public PointerBaseLayout {
  protected:
   // The length of the view in element sizes (obtainable via
   // [TypedDataBase::ElementSizeInBytes]).
-  RawSmi* length_;
+  SmiPtr length_;
 
  private:
-  friend class RawTypedDataView;
+  friend class TypedDataViewLayout;
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypedDataBase);
 };
 
-class RawTypedData : public RawTypedDataBase {
+class TypedDataLayout : public TypedDataBaseLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypedData);
 
  public:
   static intptr_t payload_offset() {
-    return OFFSET_OF_RETURNED_VALUE(RawTypedData, internal_data);
+    return OFFSET_OF_RETURNED_VALUE(TypedDataLayout, internal_data);
   }
 
   // Recompute [data_] pointer to internal data.
-  void RecomputeDataField() { ptr()->data_ = ptr()->internal_data(); }
+  void RecomputeDataField() { data_ = internal_data(); }
 
  protected:
   VISIT_FROM(RawCompressed, length_)
-  VISIT_TO_LENGTH(RawCompressed, &ptr()->length_)
+  VISIT_TO_LENGTH(RawCompressed, &length_)
 
   // Variable length data follows here.
 
@@ -2537,20 +2446,20 @@
   friend class ObjectPool;
   friend class ObjectPoolDeserializationCluster;
   friend class ObjectPoolSerializationCluster;
-  friend class RawObjectPool;
+  friend class ObjectPoolLayout;
   friend class SnapshotReader;
 };
 
 // All _*ArrayView/_ByteDataView classes share the same layout.
-class RawTypedDataView : public RawTypedDataBase {
+class TypedDataViewLayout : public TypedDataBaseLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypedDataView);
 
  public:
   // Recompute [data_] based on internal/external [typed_data_].
   void RecomputeDataField() {
-    const intptr_t offset_in_bytes = ValueFromRawSmi(ptr()->offset_in_bytes_);
-    uint8_t* payload = ptr()->typed_data_->ptr()->data_;
-    ptr()->data_ = payload + offset_in_bytes;
+    const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+    uint8_t* payload = typed_data_->ptr()->data_;
+    data_ = payload + offset_in_bytes;
   }
 
   // Recopute [data_] based on internal [typed_data_] - needs to be called by GC
@@ -2560,47 +2469,47 @@
   // [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 = ValueFromRawSmi(ptr()->offset_in_bytes_);
+    const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
     uint8_t* payload = reinterpret_cast<uint8_t*>(
-        RawObject::ToAddr(ptr()->typed_data_) + RawTypedData::payload_offset());
-    ptr()->data_ = payload + offset_in_bytes;
+        ObjectLayout::ToAddr(typed_data_) + TypedDataLayout::payload_offset());
+    data_ = payload + offset_in_bytes;
   }
 
   void ValidateInnerPointer() {
-    if (ptr()->typed_data_->GetClassId() == kNullCid) {
+    if (typed_data_->ptr()->GetClassId() == kNullCid) {
       // The view object must have gotten just initialized.
-      if (ptr()->data_ != nullptr ||
-          ValueFromRawSmi(ptr()->offset_in_bytes_) != 0 ||
-          ValueFromRawSmi(ptr()->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 = ValueFromRawSmi(ptr()->offset_in_bytes_);
-      uint8_t* payload = ptr()->typed_data_->ptr()->data_;
-      if ((payload + offset_in_bytes) != ptr()->data_) {
+      const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+      uint8_t* payload = typed_data_->ptr()->data_;
+      if ((payload + offset_in_bytes) != data_) {
         FATAL("RawTypedDataView has invalid inner pointer.");
       }
     }
   }
 
  protected:
-  VISIT_FROM(RawObject*, length_)
-  RawTypedDataBase* typed_data_;
-  RawSmi* offset_in_bytes_;
-  VISIT_TO(RawObject*, offset_in_bytes_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, length_)
+  TypedDataBasePtr typed_data_;
+  SmiPtr offset_in_bytes_;
+  VISIT_TO(ObjectPtr, offset_in_bytes_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class Api;
   friend class Object;
   friend class ObjectPoolDeserializationCluster;
   friend class ObjectPoolSerializationCluster;
-  friend class RawObjectPool;
+  friend class ObjectPoolLayout;
   friend class GCCompactor;
-  friend class ScavengerVisitor;
+  template <bool>
+  friend class ScavengerVisitorBase;
   friend class SnapshotReader;
 };
 
-class RawExternalOneByteString : public RawString {
+class ExternalOneByteStringLayout : public StringLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalOneByteString);
 
   const uint8_t* external_data_;
@@ -2609,7 +2518,7 @@
   friend class String;
 };
 
-class RawExternalTwoByteString : public RawString {
+class ExternalTwoByteStringLayout : public StringLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTwoByteString);
 
   const uint16_t* external_data_;
@@ -2618,34 +2527,37 @@
   friend class String;
 };
 
-class RawBool : public RawInstance {
+class BoolLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Bool);
   VISIT_NOTHING();
 
   bool value_;
+
+  friend class Object;
 };
 
-class RawArray : public RawInstance {
+class ArrayLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Array);
 
   VISIT_FROM(RawCompressed, type_arguments_)
-  RawTypeArguments* type_arguments_;
-  RawSmi* length_;
+  TypeArgumentsPtr type_arguments_;
+  SmiPtr length_;
   // Variable length data follows here.
-  RawObject** data() { OPEN_ARRAY_START(RawObject*, RawObject*); }
-  RawObject* const* data() const { OPEN_ARRAY_START(RawObject*, RawObject*); }
-  VISIT_TO_LENGTH(RawCompressed, &ptr()->data()[length - 1])
+  ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  VISIT_TO_LENGTH(RawCompressed, &data()[length - 1])
 
   friend class LinkedHashMapSerializationCluster;
   friend class LinkedHashMapDeserializationCluster;
+  friend class CodeSerializationCluster;
   friend class CodeDeserializationCluster;
   friend class Deserializer;
-  friend class RawCode;
-  friend class RawImmutableArray;
+  friend class CodeLayout;
+  friend class ImmutableArrayLayout;
   friend class SnapshotReader;
   friend class GrowableObjectArray;
   friend class LinkedHashMap;
-  friend class RawLinkedHashMap;
+  friend class LinkedHashMapLayout;
   friend class Object;
   friend class ICData;            // For high performance access.
   friend class SubtypeTestCache;  // For high performance access.
@@ -2653,41 +2565,41 @@
   friend class HeapPage;
 };
 
-class RawImmutableArray : public RawArray {
+class ImmutableArrayLayout : public ArrayLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ImmutableArray);
 
   friend class SnapshotReader;
 };
 
-class RawGrowableObjectArray : public RawInstance {
+class GrowableObjectArrayLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(GrowableObjectArray);
 
   VISIT_FROM(RawCompressed, type_arguments_)
-  RawTypeArguments* type_arguments_;
-  RawSmi* length_;
-  RawArray* data_;
+  TypeArgumentsPtr type_arguments_;
+  SmiPtr length_;
+  ArrayPtr data_;
   VISIT_TO(RawCompressed, data_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class SnapshotReader;
 };
 
-class RawLinkedHashMap : public RawInstance {
+class LinkedHashMapLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LinkedHashMap);
 
   VISIT_FROM(RawCompressed, type_arguments_)
-  RawTypeArguments* type_arguments_;
-  RawTypedData* index_;
-  RawSmi* hash_mask_;
-  RawArray* data_;
-  RawSmi* used_data_;
-  RawSmi* deleted_keys_;
+  TypeArgumentsPtr type_arguments_;
+  TypedDataPtr index_;
+  SmiPtr hash_mask_;
+  ArrayPtr data_;
+  SmiPtr used_data_;
+  SmiPtr deleted_keys_;
   VISIT_TO(RawCompressed, deleted_keys_)
 
   friend class SnapshotReader;
 };
 
-class RawFloat32x4 : public RawInstance {
+class Float32x4Layout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Float32x4);
   VISIT_NOTHING();
 
@@ -2702,9 +2614,9 @@
   float z() const { return value_[2]; }
   float w() const { return value_[3]; }
 };
-COMPILE_ASSERT(sizeof(RawFloat32x4) == 24);
+COMPILE_ASSERT(sizeof(Float32x4Layout) == 24);
 
-class RawInt32x4 : public RawInstance {
+class Int32x4Layout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Int32x4);
   VISIT_NOTHING();
 
@@ -2718,9 +2630,9 @@
   int32_t z() const { return value_[2]; }
   int32_t w() const { return value_[3]; }
 };
-COMPILE_ASSERT(sizeof(RawInt32x4) == 24);
+COMPILE_ASSERT(sizeof(Int32x4Layout) == 24);
 
-class RawFloat64x2 : public RawInstance {
+class Float64x2Layout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Float64x2);
   VISIT_NOTHING();
 
@@ -2733,7 +2645,7 @@
   double x() const { return value_[0]; }
   double y() const { return value_[1]; }
 };
-COMPILE_ASSERT(sizeof(RawFloat64x2) == 24);
+COMPILE_ASSERT(sizeof(Float64x2Layout) == 24);
 
 // Define an aliases for intptr_t.
 #if defined(ARCH_IS_32_BIT)
@@ -2746,27 +2658,27 @@
 #error Architecture is not 32-bit or 64-bit.
 #endif  // ARCH_IS_32_BIT
 
-class RawExternalTypedData : public RawTypedDataBase {
+class ExternalTypedDataLayout : public TypedDataBaseLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData);
 
  protected:
   VISIT_FROM(RawCompressed, length_)
   VISIT_TO(RawCompressed, length_)
 
-  friend class RawBytecode;
+  friend class BytecodeLayout;
 };
 
-class RawPointer : public RawPointerBase {
+class PointerLayout : public PointerBaseLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
 
   VISIT_FROM(RawCompressed, type_arguments_)
-  RawTypeArguments* type_arguments_;
+  TypeArgumentsPtr type_arguments_;
   VISIT_TO(RawCompressed, type_arguments_)
 
   friend class Pointer;
 };
 
-class RawDynamicLibrary : public RawInstance {
+class DynamicLibraryLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(DynamicLibrary);
   VISIT_NOTHING();
   void* handle_;
@@ -2775,13 +2687,13 @@
 };
 
 // VM implementations of the basic types in the isolate.
-class alignas(8) RawCapability : public RawInstance {
+class alignas(8) CapabilityLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Capability);
   VISIT_NOTHING();
   uint64_t id_;
 };
 
-class alignas(8) RawSendPort : public RawInstance {
+class alignas(8) SendPortLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(SendPort);
   VISIT_NOTHING();
   Dart_Port id_;
@@ -2790,16 +2702,16 @@
   friend class ReceivePort;
 };
 
-class RawReceivePort : public RawInstance {
+class ReceivePortLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ReceivePort);
 
-  VISIT_FROM(RawObject*, send_port_)
-  RawSendPort* send_port_;
-  RawInstance* handler_;
-  VISIT_TO(RawObject*, handler_)
+  VISIT_FROM(ObjectPtr, send_port_)
+  SendPortPtr send_port_;
+  InstancePtr handler_;
+  VISIT_TO(ObjectPtr, handler_)
 };
 
-class RawTransferableTypedData : public RawInstance {
+class TransferableTypedDataLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(TransferableTypedData);
   VISIT_NOTHING();
 };
@@ -2808,15 +2720,15 @@
 // Currently we don't have any interface that this object is supposed
 // to implement so we just support the 'toString' method which
 // converts the stack trace into a string.
-class RawStackTrace : public RawInstance {
+class StackTraceLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(StackTrace);
 
-  VISIT_FROM(RawObject*, async_link_)
-  RawStackTrace* async_link_;  // Link to parent async stack trace.
-  RawArray* code_array_;       // Code object for each frame in the stack trace.
-  RawArray* pc_offset_array_;  // Offset of PC for each frame.
-  VISIT_TO(RawObject*, pc_offset_array_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, async_link_)
+  StackTracePtr async_link_;  // Link to parent async stack trace.
+  ArrayPtr code_array_;       // Code object for each frame in the stack trace.
+  ArrayPtr pc_offset_array_;  // Offset of PC for each frame.
+  VISIT_TO(ObjectPtr, pc_offset_array_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // False for pre-allocated stack trace (used in OOM and Stack overflow).
   bool expand_inlined_;
@@ -2827,35 +2739,35 @@
 };
 
 // VM type for capturing JS regular expressions.
-class RawRegExp : public RawInstance {
+class RegExpLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(RegExp);
 
-  VISIT_FROM(RawObject*, num_bracket_expressions_)
-  RawSmi* num_bracket_expressions_;
-  RawArray* capture_name_map_;
-  RawString* pattern_;  // Pattern to be used for matching.
+  VISIT_FROM(ObjectPtr, num_bracket_expressions_)
+  SmiPtr num_bracket_expressions_;
+  ArrayPtr capture_name_map_;
+  StringPtr pattern_;  // Pattern to be used for matching.
   union {
-    RawFunction* function_;
-    RawTypedData* bytecode_;
+    FunctionPtr function_;
+    TypedDataPtr bytecode_;
   } one_byte_;
   union {
-    RawFunction* function_;
-    RawTypedData* bytecode_;
+    FunctionPtr function_;
+    TypedDataPtr bytecode_;
   } two_byte_;
-  RawFunction* external_one_byte_function_;
-  RawFunction* external_two_byte_function_;
+  FunctionPtr external_one_byte_function_;
+  FunctionPtr external_two_byte_function_;
   union {
-    RawFunction* function_;
-    RawTypedData* bytecode_;
+    FunctionPtr function_;
+    TypedDataPtr bytecode_;
   } one_byte_sticky_;
   union {
-    RawFunction* function_;
-    RawTypedData* bytecode_;
+    FunctionPtr function_;
+    TypedDataPtr bytecode_;
   } two_byte_sticky_;
-  RawFunction* external_one_byte_sticky_function_;
-  RawFunction* external_two_byte_sticky_function_;
-  VISIT_TO(RawObject*, external_two_byte_sticky_function_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  FunctionPtr external_one_byte_sticky_function_;
+  FunctionPtr external_two_byte_sticky_function_;
+  VISIT_TO(ObjectPtr, external_two_byte_sticky_function_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // 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
@@ -2871,14 +2783,14 @@
   int8_t type_flags_;
 };
 
-class RawWeakProperty : public RawInstance {
+class WeakPropertyLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(WeakProperty);
 
-  VISIT_FROM(RawObject*, key_)
-  RawObject* key_;
-  RawObject* value_;
-  VISIT_TO(RawObject*, value_)
-  RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(ObjectPtr, key_)
+  ObjectPtr key_;
+  ObjectPtr value_;
+  VISIT_TO(ObjectPtr, value_)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // Linked list is chaining all pending weak properties.
   // Untyped to make it clear that it is not to be visited by GC.
@@ -2888,26 +2800,27 @@
   template <bool>
   friend class MarkingVisitorBase;
   friend class Scavenger;
-  friend class ScavengerVisitor;
+  template <bool>
+  friend class ScavengerVisitorBase;
 };
 
 // MirrorReferences are used by mirrors to hold reflectees that are VM
 // internal objects, such as libraries, classes, functions or types.
-class RawMirrorReference : public RawInstance {
+class MirrorReferenceLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MirrorReference);
 
-  VISIT_FROM(RawObject*, referent_)
-  RawObject* referent_;
-  VISIT_TO(RawObject*, referent_)
+  VISIT_FROM(ObjectPtr, referent_)
+  ObjectPtr referent_;
+  VISIT_TO(ObjectPtr, referent_)
 };
 
 // UserTag are used by the profiler to track Dart script state.
-class RawUserTag : public RawInstance {
+class UserTagLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UserTag);
 
-  VISIT_FROM(RawObject*, label_)
-  RawString* label_;
-  VISIT_TO(RawObject*, label_)
+  VISIT_FROM(ObjectPtr, label_)
+  StringPtr label_;
+  VISIT_TO(ObjectPtr, label_)
 
   // Isolate unique tag.
   uword tag_;
@@ -2919,224 +2832,16 @@
   uword tag() const { return tag_; }
 };
 
-class RawFutureOr : public RawInstance {
+class FutureOrLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(FutureOr);
 
   VISIT_FROM(RawCompressed, type_arguments_)
-  RawTypeArguments* type_arguments_;
+  TypeArgumentsPtr type_arguments_;
   VISIT_TO(RawCompressed, type_arguments_)
 
   friend class SnapshotReader;
 };
 
-// Class Id predicates.
-
-inline bool RawObject::IsErrorClassId(intptr_t index) {
-  // Make sure this function is updated when new Error types are added.
-  COMPILE_ASSERT(
-      kApiErrorCid == kErrorCid + 1 && kLanguageErrorCid == kErrorCid + 2 &&
-      kUnhandledExceptionCid == kErrorCid + 3 &&
-      kUnwindErrorCid == kErrorCid + 4 && kInstanceCid == kErrorCid + 5);
-  return (index >= kErrorCid && index < kInstanceCid);
-}
-
-inline bool RawObject::IsNumberClassId(intptr_t index) {
-  // Make sure this function is updated when new Number types are added.
-  COMPILE_ASSERT(kIntegerCid == kNumberCid + 1 && kSmiCid == kNumberCid + 2 &&
-                 kMintCid == kNumberCid + 3 && kDoubleCid == kNumberCid + 4);
-  return (index >= kNumberCid && index <= kDoubleCid);
-}
-
-inline bool RawObject::IsIntegerClassId(intptr_t index) {
-  // Make sure this function is updated when new Integer types are added.
-  COMPILE_ASSERT(kSmiCid == kIntegerCid + 1 && kMintCid == kIntegerCid + 2);
-  return (index >= kIntegerCid && index <= kMintCid);
-}
-
-inline bool RawObject::IsStringClassId(intptr_t index) {
-  // Make sure this function is updated when new StringCid types are added.
-  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
-                 kTwoByteStringCid == kStringCid + 2 &&
-                 kExternalOneByteStringCid == kStringCid + 3 &&
-                 kExternalTwoByteStringCid == kStringCid + 4);
-  return (index >= kStringCid && index <= kExternalTwoByteStringCid);
-}
-
-inline bool RawObject::IsOneByteStringClassId(intptr_t index) {
-  // Make sure this function is updated when new StringCid types are added.
-  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
-                 kTwoByteStringCid == kStringCid + 2 &&
-                 kExternalOneByteStringCid == kStringCid + 3 &&
-                 kExternalTwoByteStringCid == kStringCid + 4);
-  return (index == kOneByteStringCid || index == kExternalOneByteStringCid);
-}
-
-inline bool RawObject::IsTwoByteStringClassId(intptr_t index) {
-  // Make sure this function is updated when new StringCid types are added.
-  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
-                 kTwoByteStringCid == kStringCid + 2 &&
-                 kExternalOneByteStringCid == kStringCid + 3 &&
-                 kExternalTwoByteStringCid == kStringCid + 4);
-  return (index == kTwoByteStringCid || index == kExternalTwoByteStringCid);
-}
-
-inline bool RawObject::IsExternalStringClassId(intptr_t index) {
-  // Make sure this function is updated when new StringCid types are added.
-  COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
-                 kTwoByteStringCid == kStringCid + 2 &&
-                 kExternalOneByteStringCid == kStringCid + 3 &&
-                 kExternalTwoByteStringCid == kStringCid + 4);
-  return (index == kExternalOneByteStringCid ||
-          index == kExternalTwoByteStringCid);
-}
-
-inline bool RawObject::IsBuiltinListClassId(intptr_t index) {
-  // Make sure this function is updated when new builtin List types are added.
-  COMPILE_ASSERT(kImmutableArrayCid == kArrayCid + 1);
-  return ((index >= kArrayCid && index <= kImmutableArrayCid) ||
-          (index == kGrowableObjectArrayCid) || IsTypedDataBaseClassId(index) ||
-          (index == kByteBufferCid));
-}
-
-inline bool RawObject::IsTypedDataBaseClassId(intptr_t index) {
-  // Make sure this is updated when new TypedData types are added.
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 == kTypedDataUint8ArrayCid);
-  return index >= kTypedDataInt8ArrayCid && index < kByteDataViewCid;
-}
-
-inline bool RawObject::IsTypedDataClassId(intptr_t index) {
-  // Make sure this is updated when new TypedData types are added.
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 == kTypedDataUint8ArrayCid);
-  return IsTypedDataBaseClassId(index) && ((index - kTypedDataInt8ArrayCid) %
-                                           3) == kTypedDataCidRemainderInternal;
-}
-
-inline bool RawObject::IsTypedDataViewClassId(intptr_t index) {
-  // Make sure this is updated when new TypedData types are added.
-  COMPILE_ASSERT(kTypedDataInt8ArrayViewCid + 3 == kTypedDataUint8ArrayViewCid);
-
-  const bool is_byte_data_view = index == kByteDataViewCid;
-  return is_byte_data_view ||
-         (IsTypedDataBaseClassId(index) &&
-          ((index - kTypedDataInt8ArrayCid) % 3) == kTypedDataCidRemainderView);
-}
-
-inline bool RawObject::IsExternalTypedDataClassId(intptr_t index) {
-  // Make sure this is updated when new TypedData types are added.
-  COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid + 3 ==
-                 kExternalTypedDataUint8ArrayCid);
-
-  return IsTypedDataBaseClassId(index) && ((index - kTypedDataInt8ArrayCid) %
-                                           3) == kTypedDataCidRemainderExternal;
-}
-
-inline bool RawObject::IsFfiNativeTypeTypeClassId(intptr_t index) {
-  return index == kFfiNativeTypeCid;
-}
-
-inline bool RawObject::IsFfiTypeClassId(intptr_t index) {
-  // Make sure this is updated when new Ffi types are added.
-  COMPILE_ASSERT(kFfiNativeFunctionCid == kFfiPointerCid + 1 &&
-                 kFfiInt8Cid == kFfiPointerCid + 2 &&
-                 kFfiInt16Cid == kFfiPointerCid + 3 &&
-                 kFfiInt32Cid == kFfiPointerCid + 4 &&
-                 kFfiInt64Cid == kFfiPointerCid + 5 &&
-                 kFfiUint8Cid == kFfiPointerCid + 6 &&
-                 kFfiUint16Cid == kFfiPointerCid + 7 &&
-                 kFfiUint32Cid == kFfiPointerCid + 8 &&
-                 kFfiUint64Cid == kFfiPointerCid + 9 &&
-                 kFfiIntPtrCid == kFfiPointerCid + 10 &&
-                 kFfiFloatCid == kFfiPointerCid + 11 &&
-                 kFfiDoubleCid == kFfiPointerCid + 12 &&
-                 kFfiVoidCid == kFfiPointerCid + 13);
-  return (index >= kFfiPointerCid && index <= kFfiVoidCid);
-}
-
-inline bool RawObject::IsFfiTypeIntClassId(intptr_t index) {
-  return (index >= kFfiInt8Cid && index <= kFfiIntPtrCid);
-}
-
-inline bool RawObject::IsFfiTypeDoubleClassId(intptr_t index) {
-  return (index >= kFfiFloatCid && index <= kFfiDoubleCid);
-}
-
-inline bool RawObject::IsFfiPointerClassId(intptr_t index) {
-  return index == kFfiPointerCid;
-}
-
-inline bool RawObject::IsFfiTypeVoidClassId(intptr_t index) {
-  return index == kFfiVoidCid;
-}
-
-inline bool RawObject::IsFfiTypeNativeFunctionClassId(intptr_t index) {
-  return index == kFfiNativeFunctionCid;
-}
-
-inline bool RawObject::IsFfiClassId(intptr_t index) {
-  return (index >= kFfiPointerCid && index <= kFfiVoidCid);
-}
-
-inline bool RawObject::IsFfiDynamicLibraryClassId(intptr_t index) {
-  return index == kFfiDynamicLibraryCid;
-}
-
-inline bool RawObject::IsInternalVMdefinedClassId(intptr_t index) {
-  return ((index < kNumPredefinedCids) &&
-          !RawObject::IsImplicitFieldClassId(index));
-}
-
-inline bool RawObject::IsVariableSizeClassId(intptr_t index) {
-  return (index == kArrayCid) || (index == kImmutableArrayCid) ||
-         RawObject::IsOneByteStringClassId(index) ||
-         RawObject::IsTwoByteStringClassId(index) ||
-         RawObject::IsTypedDataClassId(index) || (index == kContextCid) ||
-         (index == kTypeArgumentsCid) || (index == kInstructionsCid) ||
-         (index == kInstructionsSectionCid) || (index == kObjectPoolCid) ||
-         (index == kPcDescriptorsCid) || (index == kCodeSourceMapCid) ||
-         (index == kCompressedStackMapsCid) ||
-         (index == kLocalVarDescriptorsCid) ||
-         (index == kExceptionHandlersCid) || (index == kCodeCid) ||
-         (index == kContextScopeCid) || (index == kInstanceCid) ||
-         (index == kRegExpCid);
-}
-
-// This is a set of classes that are not Dart classes whose representation
-// is defined by the VM but are used in the VM code by computing the
-// implicit field offsets of the various fields in the dart object.
-inline bool RawObject::IsImplicitFieldClassId(intptr_t index) {
-  return index == kByteBufferCid;
-}
-
-inline intptr_t RawObject::NumberOfTypedDataClasses() {
-  // Make sure this is updated when new TypedData types are added.
-
-  // Ensure that each typed data type comes in internal/view/external variants
-  // next to each other.
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 == kTypedDataInt8ArrayViewCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 == kExternalTypedDataInt8ArrayCid);
-
-  // Ensure the order of the typed data members in 3-step.
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 * 3 == kTypedDataUint8ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 * 3 ==
-                 kTypedDataUint8ClampedArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 * 3 == kTypedDataInt16ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 4 * 3 == kTypedDataUint16ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 5 * 3 == kTypedDataInt32ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 6 * 3 == kTypedDataUint32ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 7 * 3 == kTypedDataInt64ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 8 * 3 == kTypedDataUint64ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 9 * 3 == kTypedDataFloat32ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 10 * 3 == kTypedDataFloat64ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 11 * 3 ==
-                 kTypedDataFloat32x4ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 12 * 3 == kTypedDataInt32x4ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 13 * 3 ==
-                 kTypedDataFloat64x2ArrayCid);
-  COMPILE_ASSERT(kTypedDataInt8ArrayCid + 14 * 3 == kByteDataViewCid);
-  COMPILE_ASSERT(kByteBufferCid + 1 == kNullCid);
-  return (kNullCid - kTypedDataInt8ArrayCid);
-}
-
 }  // namespace dart
 
 #endif  // RUNTIME_VM_RAW_OBJECT_H_
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index f68c4a2..13c759b 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -56,6 +56,7 @@
   F(Field, guarded_list_length_)                                               \
   F(Field, dependent_code_)                                                    \
   F(Field, initializer_function_)                                              \
+  F(Field, host_offset_or_field_id_)                                           \
   F(Script, url_)                                                              \
   F(Script, resolved_url_)                                                     \
   F(Script, compile_time_constants_)                                           \
@@ -120,14 +121,12 @@
   F(UnlinkedCall, args_descriptor_)                                            \
   F(MonomorphicSmiableCall, expected_cid_)                                     \
   F(MonomorphicSmiableCall, target_)                                           \
+  F(CallSiteData, target_name_)                                                \
+  F(CallSiteData, args_descriptor_)                                            \
   F(ICData, entries_)                                                          \
-  F(ICData, target_name_)                                                      \
-  F(ICData, args_descriptor_)                                                  \
   F(ICData, owner_)                                                            \
   F(MegamorphicCache, buckets_)                                                \
   F(MegamorphicCache, mask_)                                                   \
-  F(MegamorphicCache, target_name_)                                            \
-  F(MegamorphicCache, args_descriptor_)                                        \
   F(SubtypeTestCache, cache_)                                                  \
   F(ApiError, message_)                                                        \
   F(LanguageError, previous_error_)                                            \
@@ -232,7 +231,8 @@
 }
 
 #define DEFINE_OFFSETS_TABLE_ENTRY(class_name, field_name)                     \
-  {class_name::kClassId, #field_name, OFFSET_OF(Raw##class_name, field_name)},
+  {class_name::kClassId, #field_name,                                          \
+   OFFSET_OF(class_name##Layout, field_name)},
 
 // clang-format off
 OffsetsTable::OffsetsTableEntry OffsetsTable::offsets_table[] = {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 0f2d0c8..2f9a9a6 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -24,7 +24,7 @@
     " port after it exceeds certain size in bytes.");
 
 #define OFFSET_OF_FROM(obj)                                                    \
-  obj.raw()->from() - reinterpret_cast<RawObject**>(obj.raw()->ptr())
+  obj.raw()->from() - reinterpret_cast<ObjectPtr*>(obj.raw()->ptr())
 
 // TODO(18854): Need to assert No GC can happen here, even though
 // allocations may happen.
@@ -35,11 +35,11 @@
     object.StorePointer(((from) + i), reader->PassiveObjectHandle()->raw());   \
   }
 
-RawClass* Class::ReadFrom(SnapshotReader* reader,
-                          intptr_t object_id,
-                          intptr_t tags,
-                          Snapshot::Kind kind,
-                          bool as_reference) {
+ClassPtr Class::ReadFrom(SnapshotReader* reader,
+                         intptr_t object_id,
+                         intptr_t tags,
+                         Snapshot::Kind kind,
+                         bool as_reference) {
   ASSERT(reader != NULL);
 
   Class& cls = Class::ZoneHandle(reader->zone(), Class::null());
@@ -47,10 +47,10 @@
   return cls.raw();
 }
 
-void RawClass::WriteTo(SnapshotWriter* writer,
-                       intptr_t object_id,
-                       Snapshot::Kind kind,
-                       bool as_reference) {
+void ClassLayout::WriteTo(SnapshotWriter* writer,
+                          intptr_t object_id,
+                          Snapshot::Kind kind,
+                          bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -61,7 +61,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   if (writer->can_send_any_object() ||
-      writer->AllowObjectsInDartLibrary(ptr()->library_)) {
+      writer->AllowObjectsInDartLibrary(library_)) {
     writer->WriteClassId(this);
   } else {
     // We do not allow regular dart instances in isolate messages.
@@ -71,11 +71,11 @@
   }
 }
 
-RawType* Type::ReadFrom(SnapshotReader* reader,
-                        intptr_t object_id,
-                        intptr_t tags,
-                        Snapshot::Kind kind,
-                        bool as_reference) {
+TypePtr Type::ReadFrom(SnapshotReader* reader,
+                       intptr_t object_id,
+                       intptr_t tags,
+                       Snapshot::Kind kind,
+                       bool as_reference) {
   ASSERT(reader != NULL);
 
   // Determine if the type class of this type is in the full snapshot.
@@ -83,7 +83,7 @@
 
   // Allocate type object.
   Type& type = Type::ZoneHandle(reader->zone(), Type::New());
-  bool is_canonical = RawObject::IsCanonical(tags);
+  bool is_canonical = ObjectLayout::IsCanonical(tags);
   reader->AddBackRef(object_id, &type, kIsDeserialized);
 
   // Set all non object fields.
@@ -96,7 +96,8 @@
   reader->EnqueueTypePostprocessing(type);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(type, type.raw()->from(), type.raw()->to(), as_reference);
+  READ_OBJECT_FIELDS(type, type.raw()->ptr()->from(), type.raw()->ptr()->to(),
+                     as_reference);
 
   // Read in the type class.
   (*reader->ClassHandle()) =
@@ -115,13 +116,13 @@
   return type.raw();
 }
 
-void RawType::WriteTo(SnapshotWriter* writer,
-                      intptr_t object_id,
-                      Snapshot::Kind kind,
-                      bool as_reference) {
+void TypeLayout::WriteTo(SnapshotWriter* writer,
+                         intptr_t object_id,
+                         Snapshot::Kind kind,
+                         bool as_reference) {
   ASSERT(writer != NULL);
 
-  if (ptr()->signature_ != Function::null()) {
+  if (signature_ != Function::null()) {
     writer->SetWriteException(Exceptions::kArgument,
                               "Illegal argument in isolate message"
                               " : (function types are not supported yet)");
@@ -129,9 +130,9 @@
   }
 
   // Only resolved and finalized types should be written to a snapshot.
-  ASSERT((ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
-         (ptr()->type_state_ == RawType::kFinalizedUninstantiated));
-  ASSERT(ptr()->type_class_id_ != Object::null());
+  ASSERT((type_state_ == TypeLayout::kFinalizedInstantiated) ||
+         (type_state_ == TypeLayout::kFinalizedUninstantiated));
+  ASSERT(type_class_id_ != Object::null());
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -140,14 +141,14 @@
   writer->WriteIndexedObject(kTypeCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  if (ptr()->type_class_id_->IsHeapObject()) {
+  if (type_class_id_->IsHeapObject()) {
     // Type class is still an unresolved class.
     UNREACHABLE();
   }
 
   // Lookup the type class.
-  RawSmi* raw_type_class_id = Smi::RawCast(ptr()->type_class_id_);
-  RawClass* type_class =
+  SmiPtr raw_type_class_id = Smi::RawCast(type_class_id_);
+  ClassPtr type_class =
       writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
 
   // Write out typeclass_is_in_fullsnapshot first as this will
@@ -155,18 +156,18 @@
   intptr_t tags = writer->GetObjectTags(type_class);
   bool typeclass_is_in_fullsnapshot =
       (ClassIdTag::decode(tags) == kClassCid) &&
-      Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(type_class));
+      Class::IsInFullSnapshot(static_cast<ClassPtr>(type_class));
   writer->Write<bool>(typeclass_is_in_fullsnapshot);
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-  const uint8_t combined = (ptr()->type_state_ << 4) | ptr()->nullability_;
-  ASSERT(ptr()->type_state_ == (combined >> 4));
-  ASSERT(ptr()->nullability_ == (combined & 0xf));
+  writer->Write<int32_t>(token_pos_.SnapshotEncode());
+  const uint8_t combined = (type_state_ << 4) | nullability_;
+  ASSERT(type_state_ == (combined >> 4));
+  ASSERT(nullability_ == (combined & 0xf));
   writer->Write<uint8_t>(combined);
 
   // Write out all the object pointer fields.
-  ASSERT(ptr()->type_class_id_ != Object::null());
+  ASSERT(type_class_id_ != Object::null());
   SnapshotWriterVisitor visitor(writer, as_reference);
   visitor.VisitPointers(from(), to());
 
@@ -174,11 +175,11 @@
   writer->WriteObjectImpl(type_class, as_reference);
 }
 
-RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader,
-                              intptr_t object_id,
-                              intptr_t tags,
-                              Snapshot::Kind kind,
-                              bool as_reference) {
+TypeRefPtr TypeRef::ReadFrom(SnapshotReader* reader,
+                             intptr_t object_id,
+                             intptr_t tags,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate type ref object.
@@ -189,8 +190,8 @@
   reader->EnqueueTypePostprocessing(type_ref);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(type_ref, type_ref.raw()->from(), type_ref.raw()->to(),
-                     kAsReference);
+  READ_OBJECT_FIELDS(type_ref, type_ref.raw()->ptr()->from(),
+                     type_ref.raw()->ptr()->to(), kAsReference);
 
   // Fill in the type testing stub.
   Code& code = *reader->CodeHandle();
@@ -200,10 +201,10 @@
   return type_ref.raw();
 }
 
-void RawTypeRef::WriteTo(SnapshotWriter* writer,
-                         intptr_t object_id,
-                         Snapshot::Kind kind,
-                         bool as_reference) {
+void TypeRefLayout::WriteTo(SnapshotWriter* writer,
+                            intptr_t object_id,
+                            Snapshot::Kind kind,
+                            bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -218,11 +219,11 @@
   visitor.VisitPointers(from(), to());
 }
 
-RawTypeParameter* TypeParameter::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+TypeParameterPtr TypeParameter::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate type parameter object.
@@ -242,8 +243,8 @@
   reader->EnqueueTypePostprocessing(type_parameter);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->from(),
-                     type_parameter.raw()->to(), kAsReference);
+  READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->ptr()->from(),
+                     type_parameter.raw()->ptr()->to(), kAsReference);
 
   // Read in the parameterized class.
   (*reader->ClassHandle()) =
@@ -258,14 +259,14 @@
   return type_parameter.raw();
 }
 
-void RawTypeParameter::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void TypeParameterLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   ASSERT(writer != NULL);
 
   // Only finalized type parameters should be written to a snapshot.
-  ASSERT(FinalizedBit::decode(ptr()->flags_));
+  ASSERT(FinalizedBit::decode(flags_));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -275,11 +276,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-  writer->Write<int16_t>(ptr()->index_);
-  const uint8_t combined = (ptr()->flags_ << 4) | ptr()->nullability_;
-  ASSERT(ptr()->flags_ == (combined >> 4));
-  ASSERT(ptr()->nullability_ == (combined & 0xf));
+  writer->Write<int32_t>(token_pos_.SnapshotEncode());
+  writer->Write<int16_t>(index_);
+  const uint8_t combined = (flags_ << 4) | nullability_;
+  ASSERT(flags_ == (combined >> 4));
+  ASSERT(nullability_ == (combined & 0xf));
   writer->Write<uint8_t>(combined);
 
   // Write out all the object pointer fields.
@@ -287,16 +288,16 @@
   visitor.VisitPointers(from(), to());
 
   // Write out the parameterized class.
-  RawClass* param_class =
-      writer->isolate()->class_table()->At(ptr()->parameterized_class_id_);
+  ClassPtr param_class =
+      writer->isolate()->class_table()->At(parameterized_class_id_);
   writer->WriteObjectImpl(param_class, kAsReference);
 }
 
-RawTypeArguments* TypeArguments::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+TypeArgumentsPtr TypeArguments::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   ASSERT(reader != NULL);
 
   // Read the length so that we can determine instance size to allocate.
@@ -304,7 +305,7 @@
 
   TypeArguments& type_arguments =
       TypeArguments::ZoneHandle(reader->zone(), TypeArguments::New(len));
-  bool is_canonical = RawObject::IsCanonical(tags);
+  bool is_canonical = ObjectLayout::IsCanonical(tags);
   reader->AddBackRef(object_id, &type_arguments, kIsDeserialized);
 
   // Set the instantiations field, which is only read from a full snapshot.
@@ -324,10 +325,10 @@
   return type_arguments.raw();
 }
 
-void RawTypeArguments::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void TypeArgumentsLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -338,10 +339,10 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the length field.
-  writer->Write<RawObject*>(ptr()->length_);
+  writer->Write<ObjectPtr>(length_);
 
   // Write out the individual types.
-  intptr_t len = Smi::Value(ptr()->length_);
+  intptr_t len = Smi::Value(length_);
   for (intptr_t i = 0; i < len; i++) {
     // The Dart VM reuses type argument lists across instances in order
     // to reduce memory footprint, this can sometimes lead to a type from
@@ -350,39 +351,39 @@
     // across (isolates spawned using spawnURI) we send them as dynamic.
     if (!writer->can_send_any_object()) {
       // Lookup the type class.
-      RawType* raw_type = Type::RawCast(ptr()->types()[i]);
-      RawSmi* raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id_);
-      RawClass* type_class =
+      TypePtr raw_type = Type::RawCast(types()[i]);
+      SmiPtr raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id_);
+      ClassPtr type_class =
           writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
       if (!writer->AllowObjectsInDartLibrary(type_class->ptr()->library_)) {
         writer->WriteVMIsolateObject(kDynamicType);
       } else {
-        writer->WriteObjectImpl(ptr()->types()[i], as_reference);
+        writer->WriteObjectImpl(types()[i], as_reference);
       }
     } else {
-      writer->WriteObjectImpl(ptr()->types()[i], as_reference);
+      writer->WriteObjectImpl(types()[i], as_reference);
     }
   }
 }
 
-RawClosure* Closure::ReadFrom(SnapshotReader* reader,
-                              intptr_t object_id,
-                              intptr_t tags,
-                              Snapshot::Kind kind,
-                              bool as_reference) {
+ClosurePtr Closure::ReadFrom(SnapshotReader* reader,
+                             intptr_t object_id,
+                             intptr_t tags,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   UNREACHABLE();
   return Closure::null();
 }
 
-void RawClosure::WriteTo(SnapshotWriter* writer,
-                         intptr_t object_id,
-                         Snapshot::Kind kind,
-                         bool as_reference) {
+void ClosureLayout::WriteTo(SnapshotWriter* writer,
+                            intptr_t object_id,
+                            Snapshot::Kind kind,
+                            bool as_reference) {
   ASSERT(writer != NULL);
   ASSERT(kind == Snapshot::kMessage);
 
   // Check if closure is serializable, throw an exception otherwise.
-  RawFunction* func = writer->IsSerializableClosure(this);
+  FunctionPtr func = writer->IsSerializableClosure(ClosurePtr(this));
   if (func != Function::null()) {
     writer->WriteStaticImplicitClosure(object_id, func,
                                        writer->GetObjectTags(this));
@@ -392,11 +393,11 @@
   UNREACHABLE();
 }
 
-RawContext* Context::ReadFrom(SnapshotReader* reader,
-                              intptr_t object_id,
-                              intptr_t tags,
-                              Snapshot::Kind kind,
-                              bool as_reference) {
+ContextPtr Context::ReadFrom(SnapshotReader* reader,
+                             intptr_t object_id,
+                             intptr_t tags,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate context object.
@@ -409,20 +410,21 @@
     // Set all the object fields.
     // TODO(5411462): Need to assert No GC can happen here, even though
     // allocations may happen.
-    intptr_t num_flds = (context.raw()->to(num_vars) - context.raw()->from());
+    intptr_t num_flds =
+        (context.raw()->ptr()->to(num_vars) - context.raw()->ptr()->from());
     for (intptr_t i = 0; i <= num_flds; i++) {
       (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
-      context.StorePointer((context.raw()->from() + i),
+      context.StorePointer((context.raw()->ptr()->from() + i),
                            reader->PassiveObjectHandle()->raw());
     }
   }
   return context.raw();
 }
 
-void RawContext::WriteTo(SnapshotWriter* writer,
-                         intptr_t object_id,
-                         Snapshot::Kind kind,
-                         bool as_reference) {
+void ContextLayout::WriteTo(SnapshotWriter* writer,
+                            intptr_t object_id,
+                            Snapshot::Kind kind,
+                            bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -433,7 +435,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out num of variables in the context.
-  int32_t num_variables = ptr()->num_variables_;
+  const int32_t num_variables = num_variables_;
   writer->Write<int32_t>(num_variables);
   if (num_variables != 0) {
     // Write out all the object pointer fields.
@@ -442,11 +444,11 @@
   }
 }
 
-RawContextScope* ContextScope::ReadFrom(SnapshotReader* reader,
-                                        intptr_t object_id,
-                                        intptr_t tags,
-                                        Snapshot::Kind kind,
-                                        bool as_reference) {
+ContextScopePtr ContextScope::ReadFrom(SnapshotReader* reader,
+                                       intptr_t object_id,
+                                       intptr_t tags,
+                                       Snapshot::Kind kind,
+                                       bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate context object.
@@ -473,15 +475,15 @@
   return NULL;
 }
 
-void RawContextScope::WriteTo(SnapshotWriter* writer,
-                              intptr_t object_id,
-                              Snapshot::Kind kind,
-                              bool as_reference) {
+void ContextScopeLayout::WriteTo(SnapshotWriter* writer,
+                                 intptr_t object_id,
+                                 Snapshot::Kind kind,
+                                 bool as_reference) {
   ASSERT(writer != NULL);
 
-  if (ptr()->is_implicit_) {
-    ASSERT(ptr()->num_variables_ == 1);
-    const VariableDesc* var = ptr()->VariableDescAddr(0);
+  if (is_implicit_) {
+    ASSERT(num_variables_ == 1);
+    const VariableDesc* var = VariableDescAddr(0);
 
     // Write out the serialization header value for this object.
     writer->WriteInlinedObjectHeader(object_id);
@@ -502,26 +504,26 @@
 }
 
 #define MESSAGE_SNAPSHOT_UNREACHABLE(type)                                     \
-  Raw##type* type::ReadFrom(SnapshotReader* reader, intptr_t object_id,        \
-                            intptr_t tags, Snapshot::Kind kind,                \
-                            bool as_reference) {                               \
+  type##Ptr type::ReadFrom(SnapshotReader* reader, intptr_t object_id,         \
+                           intptr_t tags, Snapshot::Kind kind,                 \
+                           bool as_reference) {                                \
     UNREACHABLE();                                                             \
     return type::null();                                                       \
   }                                                                            \
-  void Raw##type::WriteTo(SnapshotWriter* writer, intptr_t object_id,          \
-                          Snapshot::Kind kind, bool as_reference) {            \
+  void type##Layout::WriteTo(SnapshotWriter* writer, intptr_t object_id,       \
+                             Snapshot::Kind kind, bool as_reference) {         \
     UNREACHABLE();                                                             \
   }
 
 #define MESSAGE_SNAPSHOT_ILLEGAL(type)                                         \
-  Raw##type* type::ReadFrom(SnapshotReader* reader, intptr_t object_id,        \
-                            intptr_t tags, Snapshot::Kind kind,                \
-                            bool as_reference) {                               \
+  type##Ptr type::ReadFrom(SnapshotReader* reader, intptr_t object_id,         \
+                           intptr_t tags, Snapshot::Kind kind,                 \
+                           bool as_reference) {                                \
     UNREACHABLE();                                                             \
     return type::null();                                                       \
   }                                                                            \
-  void Raw##type::WriteTo(SnapshotWriter* writer, intptr_t object_id,          \
-                          Snapshot::Kind kind, bool as_reference) {            \
+  void type##Layout::WriteTo(SnapshotWriter* writer, intptr_t object_id,       \
+                             Snapshot::Kind kind, bool as_reference) {         \
     writer->SetWriteException(Exceptions::kArgument,                           \
                               "Illegal argument in isolate message"            \
                               " : (object is a " #type ")");                   \
@@ -539,6 +541,7 @@
 MESSAGE_SNAPSHOT_UNREACHABLE(FfiTrampolineData);
 MESSAGE_SNAPSHOT_UNREACHABLE(Field);
 MESSAGE_SNAPSHOT_UNREACHABLE(Function);
+MESSAGE_SNAPSHOT_UNREACHABLE(CallSiteData);
 MESSAGE_SNAPSHOT_UNREACHABLE(ICData);
 MESSAGE_SNAPSHOT_UNREACHABLE(Instructions);
 MESSAGE_SNAPSHOT_UNREACHABLE(InstructionsSection);
@@ -572,11 +575,11 @@
 MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
 MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
 
-RawApiError* ApiError::ReadFrom(SnapshotReader* reader,
-                                intptr_t object_id,
-                                intptr_t tags,
-                                Snapshot::Kind kind,
-                                bool as_reference) {
+ApiErrorPtr ApiError::ReadFrom(SnapshotReader* reader,
+                               intptr_t object_id,
+                               intptr_t tags,
+                               Snapshot::Kind kind,
+                               bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate ApiError object.
@@ -584,16 +587,16 @@
   reader->AddBackRef(object_id, &api_error, kIsDeserialized);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(api_error, api_error.raw()->from(), api_error.raw()->to(),
-                     kAsReference);
+  READ_OBJECT_FIELDS(api_error, api_error.raw()->ptr()->from(),
+                     api_error.raw()->ptr()->to(), kAsReference);
 
   return api_error.raw();
 }
 
-void RawApiError::WriteTo(SnapshotWriter* writer,
-                          intptr_t object_id,
-                          Snapshot::Kind kind,
-                          bool as_reference) {
+void ApiErrorLayout::WriteTo(SnapshotWriter* writer,
+                             intptr_t object_id,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -608,11 +611,11 @@
   visitor.VisitPointers(from(), to());
 }
 
-RawLanguageError* LanguageError::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+LanguageErrorPtr LanguageError::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate LanguageError object.
@@ -627,16 +630,16 @@
   language_error.set_kind(reader->Read<uint8_t>());
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(language_error, language_error.raw()->from(),
-                     language_error.raw()->to(), kAsReference);
+  READ_OBJECT_FIELDS(language_error, language_error.raw()->ptr()->from(),
+                     language_error.raw()->ptr()->to(), kAsReference);
 
   return language_error.raw();
 }
 
-void RawLanguageError::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void LanguageErrorLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -647,35 +650,35 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-  writer->Write<bool>(ptr()->report_after_token_);
-  writer->Write<uint8_t>(ptr()->kind_);
+  writer->Write<int32_t>(token_pos_.SnapshotEncode());
+  writer->Write<bool>(report_after_token_);
+  writer->Write<uint8_t>(kind_);
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
   visitor.VisitPointers(from(), to());
 }
 
-RawUnhandledException* UnhandledException::ReadFrom(SnapshotReader* reader,
-                                                    intptr_t object_id,
-                                                    intptr_t tags,
-                                                    Snapshot::Kind kind,
-                                                    bool as_reference) {
+UnhandledExceptionPtr UnhandledException::ReadFrom(SnapshotReader* reader,
+                                                   intptr_t object_id,
+                                                   intptr_t tags,
+                                                   Snapshot::Kind kind,
+                                                   bool as_reference) {
   UnhandledException& result =
       UnhandledException::ZoneHandle(reader->zone(), UnhandledException::New());
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(result, result.raw()->from(), result.raw()->to(),
-                     kAsReference);
+  READ_OBJECT_FIELDS(result, result.raw()->ptr()->from(),
+                     result.raw()->ptr()->to(), kAsReference);
 
   return result.raw();
 }
 
-void RawUnhandledException::WriteTo(SnapshotWriter* writer,
-                                    intptr_t object_id,
-                                    Snapshot::Kind kind,
-                                    bool as_reference) {
+void UnhandledExceptionLayout::WriteTo(SnapshotWriter* writer,
+                                       intptr_t object_id,
+                                       Snapshot::Kind kind,
+                                       bool as_reference) {
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
@@ -687,18 +690,18 @@
   visitor.VisitPointers(from(), to());
 }
 
-RawInstance* Instance::ReadFrom(SnapshotReader* reader,
-                                intptr_t object_id,
-                                intptr_t tags,
-                                Snapshot::Kind kind,
-                                bool as_reference) {
+InstancePtr Instance::ReadFrom(SnapshotReader* reader,
+                               intptr_t object_id,
+                               intptr_t tags,
+                               Snapshot::Kind kind,
+                               bool as_reference) {
   ASSERT(reader != NULL);
 
   // 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);
-  if (RawObject::IsCanonical(tags)) {
+  if (ObjectLayout::IsCanonical(tags)) {
     const char* error_str = NULL;
     obj = obj.CheckAndCanonicalize(reader->thread(), &error_str);
     if (error_str != NULL) {
@@ -710,10 +713,10 @@
   return obj.raw();
 }
 
-void RawInstance::WriteTo(SnapshotWriter* writer,
-                          intptr_t object_id,
-                          Snapshot::Kind kind,
-                          bool as_reference) {
+void InstanceLayout::WriteTo(SnapshotWriter* writer,
+                             intptr_t object_id,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -724,11 +727,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 }
 
-RawInteger* Mint::ReadFrom(SnapshotReader* reader,
-                           intptr_t object_id,
-                           intptr_t tags,
-                           Snapshot::Kind kind,
-                           bool as_reference) {
+IntegerPtr Mint::ReadFrom(SnapshotReader* reader,
+                          intptr_t object_id,
+                          intptr_t tags,
+                          Snapshot::Kind kind,
+                          bool as_reference) {
   ASSERT(reader != NULL);
 
   // Read the 64 bit value for the object.
@@ -750,7 +753,7 @@
   // full snapshot). Objects that are only in the script need not be
   // canonicalized as they are already canonical.
   // When reading a message snapshot we always have to canonicalize.
-  if (RawObject::IsCanonical(tags)) {
+  if (ObjectLayout::IsCanonical(tags)) {
     mint = Mint::NewCanonical(value);
     ASSERT(mint.IsCanonical());
   } else {
@@ -760,10 +763,10 @@
   return mint.raw();
 }
 
-void RawMint::WriteTo(SnapshotWriter* writer,
-                      intptr_t object_id,
-                      Snapshot::Kind kind,
-                      bool as_reference) {
+void MintLayout::WriteTo(SnapshotWriter* writer,
+                         intptr_t object_id,
+                         Snapshot::Kind kind,
+                         bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -774,14 +777,14 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the 64 bit value.
-  writer->Write<int64_t>(ptr()->value_);
+  writer->Write<int64_t>(value_);
 }
 
-RawDouble* Double::ReadFrom(SnapshotReader* reader,
-                            intptr_t object_id,
-                            intptr_t tags,
-                            Snapshot::Kind kind,
-                            bool as_reference) {
+DoublePtr Double::ReadFrom(SnapshotReader* reader,
+                           intptr_t object_id,
+                           intptr_t tags,
+                           Snapshot::Kind kind,
+                           bool as_reference) {
   ASSERT(reader != NULL);
   ASSERT(kind != Snapshot::kMessage);
   // Read the double value for the object.
@@ -793,7 +796,7 @@
   // references that are objects from the core library (loaded from a
   // full snapshot). Objects that are only in the script need not be
   // canonicalized as they are already canonical.
-  if (RawObject::IsCanonical(tags)) {
+  if (ObjectLayout::IsCanonical(tags)) {
     dbl = Double::NewCanonical(value);
     ASSERT(dbl.IsCanonical());
   } else {
@@ -803,10 +806,10 @@
   return dbl.raw();
 }
 
-void RawDouble::WriteTo(SnapshotWriter* writer,
-                        intptr_t object_id,
-                        Snapshot::Kind kind,
-                        bool as_reference) {
+void DoubleLayout::WriteTo(SnapshotWriter* writer,
+                           intptr_t object_id,
+                           Snapshot::Kind kind,
+                           bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -817,7 +820,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the double value.
-  writer->WriteDouble(ptr()->value_);
+  writer->WriteDouble(value_);
 }
 
 template <typename StringType, typename CharacterType, typename CallbackType>
@@ -828,7 +831,7 @@
                           CallbackType new_symbol,
                           Snapshot::Kind kind) {
   ASSERT(reader != NULL);
-  if (RawObject::IsCanonical(tags)) {
+  if (ObjectLayout::IsCanonical(tags)) {
     // Set up canonical string object.
     ASSERT(reader != NULL);
     CharacterType* ptr = reader->zone()->Alloc<CharacterType>(len);
@@ -852,11 +855,11 @@
   }
 }
 
-RawOneByteString* OneByteString::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+OneByteStringPtr OneByteString::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   // Read the length so that we can determine instance size to allocate.
   ASSERT(reader != NULL);
   intptr_t len = reader->ReadSmiValue();
@@ -868,11 +871,11 @@
   return raw(str_obj);
 }
 
-RawTwoByteString* TwoByteString::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+TwoByteStringPtr TwoByteString::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   // Read the length so that we can determine instance size to allocate.
   ASSERT(reader != NULL);
   intptr_t len = reader->ReadSmiValue();
@@ -890,7 +893,7 @@
                           Snapshot::Kind kind,
                           intptr_t class_id,
                           intptr_t tags,
-                          RawSmi* length,
+                          SmiPtr length,
                           T* data) {
   ASSERT(writer != NULL);
   intptr_t len = Smi::Value(length);
@@ -903,7 +906,7 @@
   writer->WriteTags(tags);
 
   // Write out the length field.
-  writer->Write<RawObject*>(length);
+  writer->Write<ObjectPtr>(length);
 
   // Write out the string.
   if (len > 0) {
@@ -917,67 +920,63 @@
   }
 }
 
-void RawOneByteString::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void OneByteStringLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   StringWriteTo(writer, object_id, kind, kOneByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_, ptr()->data());
+                writer->GetObjectTags(this), length_, data());
 }
 
-void RawTwoByteString::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void TwoByteStringLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_, ptr()->data());
+                writer->GetObjectTags(this), length_, data());
 }
 
-RawExternalOneByteString* ExternalOneByteString::ReadFrom(
-    SnapshotReader* reader,
-    intptr_t object_id,
-    intptr_t tags,
-    Snapshot::Kind kind,
-    bool as_reference) {
+ExternalOneByteStringPtr ExternalOneByteString::ReadFrom(SnapshotReader* reader,
+                                                         intptr_t object_id,
+                                                         intptr_t tags,
+                                                         Snapshot::Kind kind,
+                                                         bool as_reference) {
   UNREACHABLE();
   return ExternalOneByteString::null();
 }
 
-RawExternalTwoByteString* ExternalTwoByteString::ReadFrom(
-    SnapshotReader* reader,
-    intptr_t object_id,
-    intptr_t tags,
-    Snapshot::Kind kind,
-    bool as_reference) {
+ExternalTwoByteStringPtr ExternalTwoByteString::ReadFrom(SnapshotReader* reader,
+                                                         intptr_t object_id,
+                                                         intptr_t tags,
+                                                         Snapshot::Kind kind,
+                                                         bool as_reference) {
   UNREACHABLE();
   return ExternalTwoByteString::null();
 }
 
-void RawExternalOneByteString::WriteTo(SnapshotWriter* writer,
-                                       intptr_t object_id,
-                                       Snapshot::Kind kind,
-                                       bool as_reference) {
+void ExternalOneByteStringLayout::WriteTo(SnapshotWriter* writer,
+                                          intptr_t object_id,
+                                          Snapshot::Kind kind,
+                                          bool as_reference) {
   // Serialize as a non-external one byte string.
   StringWriteTo(writer, object_id, kind, kOneByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_,
-                ptr()->external_data_);
+                writer->GetObjectTags(this), length_, external_data_);
 }
 
-void RawExternalTwoByteString::WriteTo(SnapshotWriter* writer,
-                                       intptr_t object_id,
-                                       Snapshot::Kind kind,
-                                       bool as_reference) {
+void ExternalTwoByteStringLayout::WriteTo(SnapshotWriter* writer,
+                                          intptr_t object_id,
+                                          Snapshot::Kind kind,
+                                          bool as_reference) {
   // Serialize as a non-external two byte string.
   StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_,
-                ptr()->external_data_);
+                writer->GetObjectTags(this), length_, external_data_);
 }
 
-RawArray* Array::ReadFrom(SnapshotReader* reader,
-                          intptr_t object_id,
-                          intptr_t tags,
-                          Snapshot::Kind kind,
-                          bool as_reference) {
+ArrayPtr Array::ReadFrom(SnapshotReader* reader,
+                         intptr_t object_id,
+                         intptr_t tags,
+                         Snapshot::Kind kind,
+                         bool as_reference) {
   ASSERT(reader != NULL);
 
   // Read the length so that we can determine instance size to allocate.
@@ -996,17 +995,17 @@
   }
   if (!as_reference) {
     // Read all the individual elements for inlined objects.
-    ASSERT(!RawObject::IsCanonical(tags));
+    ASSERT(!ObjectLayout::IsCanonical(tags));
     reader->ArrayReadFrom(object_id, *array, len, tags);
   }
   return array->raw();
 }
 
-RawImmutableArray* ImmutableArray::ReadFrom(SnapshotReader* reader,
-                                            intptr_t object_id,
-                                            intptr_t tags,
-                                            Snapshot::Kind kind,
-                                            bool as_reference) {
+ImmutableArrayPtr ImmutableArray::ReadFrom(SnapshotReader* reader,
+                                           intptr_t object_id,
+                                           intptr_t tags,
+                                           Snapshot::Kind kind,
+                                           bool as_reference) {
   ASSERT(reader != NULL);
 
   // Read the length so that we can determine instance size to allocate.
@@ -1026,7 +1025,7 @@
   if (!as_reference) {
     // Read all the individual elements for inlined objects.
     reader->ArrayReadFrom(object_id, *array, len, tags);
-    if (RawObject::IsCanonical(tags)) {
+    if (ObjectLayout::IsCanonical(tags)) {
       const char* error_str = NULL;
       *array ^= array->CheckAndCanonicalize(reader->thread(), &error_str);
       if (error_str != NULL) {
@@ -1037,30 +1036,29 @@
   return raw(*array);
 }
 
-void RawArray::WriteTo(SnapshotWriter* writer,
-                       intptr_t object_id,
-                       Snapshot::Kind kind,
-                       bool as_reference) {
+void ArrayLayout::WriteTo(SnapshotWriter* writer,
+                          intptr_t object_id,
+                          Snapshot::Kind kind,
+                          bool as_reference) {
   ASSERT(!this->IsCanonical());
   writer->ArrayWriteTo(object_id, kArrayCid, writer->GetObjectTags(this),
-                       ptr()->length_, ptr()->type_arguments_, ptr()->data(),
-                       as_reference);
+                       length_, type_arguments_, data(), as_reference);
 }
 
-void RawImmutableArray::WriteTo(SnapshotWriter* writer,
-                                intptr_t object_id,
-                                Snapshot::Kind kind,
-                                bool as_reference) {
+void ImmutableArrayLayout::WriteTo(SnapshotWriter* writer,
+                                   intptr_t object_id,
+                                   Snapshot::Kind kind,
+                                   bool as_reference) {
   writer->ArrayWriteTo(object_id, kImmutableArrayCid,
-                       writer->GetObjectTags(this), ptr()->length_,
-                       ptr()->type_arguments_, ptr()->data(), as_reference);
+                       writer->GetObjectTags(this), length_, type_arguments_,
+                       data(), as_reference);
 }
 
-RawGrowableObjectArray* GrowableObjectArray::ReadFrom(SnapshotReader* reader,
-                                                      intptr_t object_id,
-                                                      intptr_t tags,
-                                                      Snapshot::Kind kind,
-                                                      bool as_reference) {
+GrowableObjectArrayPtr GrowableObjectArray::ReadFrom(SnapshotReader* reader,
+                                                     intptr_t object_id,
+                                                     intptr_t tags,
+                                                     Snapshot::Kind kind,
+                                                     bool as_reference) {
   ASSERT(reader != NULL);
 
   // Read the length so that we can determine instance size to allocate.
@@ -1084,10 +1082,10 @@
   return array.raw();
 }
 
-void RawGrowableObjectArray::WriteTo(SnapshotWriter* writer,
-                                     intptr_t object_id,
-                                     Snapshot::Kind kind,
-                                     bool as_reference) {
+void GrowableObjectArrayLayout::WriteTo(SnapshotWriter* writer,
+                                        intptr_t object_id,
+                                        Snapshot::Kind kind,
+                                        bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -1098,20 +1096,20 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the type arguments field.
-  writer->WriteObjectImpl(ptr()->type_arguments_, kAsInlinedObject);
+  writer->WriteObjectImpl(type_arguments_, kAsInlinedObject);
 
   // Write out the used length field.
-  writer->Write<RawObject*>(ptr()->length_);
+  writer->Write<ObjectPtr>(length_);
 
   // Write out the Array object.
-  writer->WriteObjectImpl(ptr()->data_, kAsReference);
+  writer->WriteObjectImpl(data_, kAsReference);
 }
 
-RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+LinkedHashMapPtr LinkedHashMap::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   ASSERT(reader != NULL);
 
   LinkedHashMap& map =
@@ -1147,7 +1145,7 @@
   reader->EnqueueRehashingOfMap(map);
 
   // Read the keys and values.
-  bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
+  bool read_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
   for (intptr_t i = 0; i < used_data; i++) {
     *reader->PassiveObjectHandle() = reader->ReadObjectImpl(read_as_reference);
     data.SetAt(i, *reader->PassiveObjectHandle());
@@ -1155,10 +1153,10 @@
   return map.raw();
 }
 
-void RawLinkedHashMap::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void LinkedHashMapLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -1169,43 +1167,43 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the type arguments.
-  writer->WriteObjectImpl(ptr()->type_arguments_, kAsInlinedObject);
+  writer->WriteObjectImpl(type_arguments_, kAsInlinedObject);
 
-  const intptr_t used_data = Smi::Value(ptr()->used_data_);
+  const intptr_t used_data = Smi::Value(used_data_);
   ASSERT((used_data & 1) == 0);  // Keys + values, so must be even.
-  const intptr_t deleted_keys = Smi::Value(ptr()->deleted_keys_);
+  const intptr_t deleted_keys = Smi::Value(deleted_keys_);
 
   // Write out the number of (not deleted) key/value pairs that will follow.
-  writer->Write<RawObject*>(Smi::New((used_data >> 1) - deleted_keys));
+  writer->Write<ObjectPtr>(Smi::New((used_data >> 1) - deleted_keys));
 
   // Write out the keys and values.
   const bool write_as_reference = this->IsCanonical() ? false : true;
-  RawArray* data_array = ptr()->data_;
-  RawObject** data_elements = data_array->ptr()->data();
+  ArrayPtr data_array = data_;
+  ObjectPtr* data_elements = data_array->ptr()->data();
   ASSERT(used_data <= Smi::Value(data_array->ptr()->length_));
 #if defined(DEBUG)
   intptr_t deleted_keys_found = 0;
 #endif  // DEBUG
   for (intptr_t i = 0; i < used_data; i += 2) {
-    RawObject* key = data_elements[i];
+    ObjectPtr key = data_elements[i];
     if (key == data_array) {
 #if defined(DEBUG)
       ++deleted_keys_found;
 #endif  // DEBUG
       continue;
     }
-    RawObject* value = data_elements[i + 1];
+    ObjectPtr value = data_elements[i + 1];
     writer->WriteObjectImpl(key, write_as_reference);
     writer->WriteObjectImpl(value, write_as_reference);
   }
   DEBUG_ASSERT(deleted_keys_found == deleted_keys);
 }
 
-RawFloat32x4* Float32x4::ReadFrom(SnapshotReader* reader,
-                                  intptr_t object_id,
-                                  intptr_t tags,
-                                  Snapshot::Kind kind,
-                                  bool as_reference) {
+Float32x4Ptr Float32x4::ReadFrom(SnapshotReader* reader,
+                                 intptr_t object_id,
+                                 intptr_t tags,
+                                 Snapshot::Kind kind,
+                                 bool as_reference) {
   ASSERT(reader != NULL);
   // Read the values.
   float value0 = reader->Read<float>();
@@ -1220,10 +1218,10 @@
   return simd.raw();
 }
 
-void RawFloat32x4::WriteTo(SnapshotWriter* writer,
-                           intptr_t object_id,
-                           Snapshot::Kind kind,
-                           bool as_reference) {
+void Float32x4Layout::WriteTo(SnapshotWriter* writer,
+                              intptr_t object_id,
+                              Snapshot::Kind kind,
+                              bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -1234,17 +1232,17 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the float values.
-  writer->Write<float>(ptr()->value_[0]);
-  writer->Write<float>(ptr()->value_[1]);
-  writer->Write<float>(ptr()->value_[2]);
-  writer->Write<float>(ptr()->value_[3]);
+  writer->Write<float>(value_[0]);
+  writer->Write<float>(value_[1]);
+  writer->Write<float>(value_[2]);
+  writer->Write<float>(value_[3]);
 }
 
-RawInt32x4* Int32x4::ReadFrom(SnapshotReader* reader,
-                              intptr_t object_id,
-                              intptr_t tags,
-                              Snapshot::Kind kind,
-                              bool as_reference) {
+Int32x4Ptr Int32x4::ReadFrom(SnapshotReader* reader,
+                             intptr_t object_id,
+                             intptr_t tags,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   ASSERT(reader != NULL);
   // Read the values.
   uint32_t value0 = reader->Read<uint32_t>();
@@ -1259,10 +1257,10 @@
   return simd.raw();
 }
 
-void RawInt32x4::WriteTo(SnapshotWriter* writer,
-                         intptr_t object_id,
-                         Snapshot::Kind kind,
-                         bool as_reference) {
+void Int32x4Layout::WriteTo(SnapshotWriter* writer,
+                            intptr_t object_id,
+                            Snapshot::Kind kind,
+                            bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -1273,17 +1271,17 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the mask values.
-  writer->Write<uint32_t>(ptr()->value_[0]);
-  writer->Write<uint32_t>(ptr()->value_[1]);
-  writer->Write<uint32_t>(ptr()->value_[2]);
-  writer->Write<uint32_t>(ptr()->value_[3]);
+  writer->Write<uint32_t>(value_[0]);
+  writer->Write<uint32_t>(value_[1]);
+  writer->Write<uint32_t>(value_[2]);
+  writer->Write<uint32_t>(value_[3]);
 }
 
-RawFloat64x2* Float64x2::ReadFrom(SnapshotReader* reader,
-                                  intptr_t object_id,
-                                  intptr_t tags,
-                                  Snapshot::Kind kind,
-                                  bool as_reference) {
+Float64x2Ptr Float64x2::ReadFrom(SnapshotReader* reader,
+                                 intptr_t object_id,
+                                 intptr_t tags,
+                                 Snapshot::Kind kind,
+                                 bool as_reference) {
   ASSERT(reader != NULL);
   // Read the values.
   double value0 = reader->Read<double>();
@@ -1296,10 +1294,10 @@
   return simd.raw();
 }
 
-void RawFloat64x2::WriteTo(SnapshotWriter* writer,
-                           intptr_t object_id,
-                           Snapshot::Kind kind,
-                           bool as_reference) {
+void Float64x2Layout::WriteTo(SnapshotWriter* writer,
+                              intptr_t object_id,
+                              Snapshot::Kind kind,
+                              bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -1310,18 +1308,18 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the float values.
-  writer->Write<double>(ptr()->value_[0]);
-  writer->Write<double>(ptr()->value_[1]);
+  writer->Write<double>(value_[0]);
+  writer->Write<double>(value_[1]);
 }
 
-RawTypedData* TypedData::ReadFrom(SnapshotReader* reader,
-                                  intptr_t object_id,
-                                  intptr_t tags,
-                                  Snapshot::Kind kind,
-                                  bool as_reference) {
+TypedDataPtr TypedData::ReadFrom(SnapshotReader* reader,
+                                 intptr_t object_id,
+                                 intptr_t tags,
+                                 Snapshot::Kind kind,
+                                 bool as_reference) {
   ASSERT(reader != NULL);
 
-  intptr_t cid = RawObject::ClassIdTag::decode(tags);
+  intptr_t cid = ObjectLayout::ClassIdTag::decode(tags);
   intptr_t len = reader->ReadSmiValue();
   TypedData& result =
       TypedData::ZoneHandle(reader->zone(), TypedData::New(cid, len));
@@ -1340,7 +1338,7 @@
   // as it would already be a canonical object.
   // When reading a script snapshot or a message snapshot we always have
   // to canonicalize the object.
-  if (RawObject::IsCanonical(tags)) {
+  if (ObjectLayout::IsCanonical(tags)) {
     const char* error_str = NULL;
     result ^= result.CheckAndCanonicalize(reader->thread(), &error_str);
     if (error_str != NULL) {
@@ -1352,13 +1350,13 @@
   return result.raw();
 }
 
-RawExternalTypedData* ExternalTypedData::ReadFrom(SnapshotReader* reader,
-                                                  intptr_t object_id,
-                                                  intptr_t tags,
-                                                  Snapshot::Kind kind,
-                                                  bool as_reference) {
+ExternalTypedDataPtr ExternalTypedData::ReadFrom(SnapshotReader* reader,
+                                                 intptr_t object_id,
+                                                 intptr_t tags,
+                                                 Snapshot::Kind kind,
+                                                 bool as_reference) {
   ASSERT(!Snapshot::IsFull(kind));
-  intptr_t cid = RawObject::ClassIdTag::decode(tags);
+  intptr_t cid = ObjectLayout::ClassIdTag::decode(tags);
   intptr_t length = reader->ReadSmiValue();
 
   FinalizableData finalizable_data =
@@ -1380,13 +1378,13 @@
   free(buffer);
 }
 
-void RawTypedData::WriteTo(SnapshotWriter* writer,
-                           intptr_t object_id,
-                           Snapshot::Kind kind,
-                           bool as_reference) {
+void TypedDataLayout::WriteTo(SnapshotWriter* writer,
+                              intptr_t object_id,
+                              Snapshot::Kind kind,
+                              bool as_reference) {
   ASSERT(writer != NULL);
   intptr_t cid = this->GetClassId();
-  intptr_t length = Smi::Value(ptr()->length_);  // In elements.
+  intptr_t length = Smi::Value(length_);  // In elements.
   intptr_t external_cid;
   intptr_t bytes;
   switch (cid) {
@@ -1460,8 +1458,8 @@
     // Write as external.
     writer->WriteIndexedObject(external_cid);
     writer->WriteTags(writer->GetObjectTags(this));
-    writer->Write<RawObject*>(ptr()->length_);
-    uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
+    writer->Write<ObjectPtr>(length_);
+    uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     void* passed_data = malloc(bytes);
     if (passed_data == NULL) {
       OUT_OF_MEMORY();
@@ -1476,20 +1474,20 @@
     // Write as internal.
     writer->WriteIndexedObject(cid);
     writer->WriteTags(writer->GetObjectTags(this));
-    writer->Write<RawObject*>(ptr()->length_);
-    uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
+    writer->Write<ObjectPtr>(length_);
+    uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     writer->Align(Zone::kAlignment);
     writer->WriteBytes(data, bytes);
   }
 }
 
-void RawExternalTypedData::WriteTo(SnapshotWriter* writer,
-                                   intptr_t object_id,
-                                   Snapshot::Kind kind,
-                                   bool as_reference) {
+void ExternalTypedDataLayout::WriteTo(SnapshotWriter* writer,
+                                      intptr_t object_id,
+                                      Snapshot::Kind kind,
+                                      bool as_reference) {
   ASSERT(writer != NULL);
   intptr_t cid = this->GetClassId();
-  intptr_t length = Smi::Value(ptr()->length_);  // In elements.
+  intptr_t length = Smi::Value(length_);  // In elements.
   intptr_t bytes;
   switch (cid) {
     case kExternalTypedDataInt8ArrayCid:
@@ -1545,8 +1543,8 @@
   // Write as external.
   writer->WriteIndexedObject(cid);
   writer->WriteTags(writer->GetObjectTags(this));
-  writer->Write<RawObject*>(ptr()->length_);
-  uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data_);
+  writer->Write<ObjectPtr>(length_);
+  uint8_t* data = reinterpret_cast<uint8_t*>(data_);
   void* passed_data = malloc(bytes);
   if (passed_data == NULL) {
     OUT_OF_MEMORY();
@@ -1559,12 +1557,12 @@
       IsolateMessageTypedDataFinalizer);
 }
 
-void RawTypedDataView::WriteTo(SnapshotWriter* writer,
-                               intptr_t object_id,
-                               Snapshot::Kind kind,
-                               bool as_reference) {
+void TypedDataViewLayout::WriteTo(SnapshotWriter* writer,
+                                  intptr_t object_id,
+                                  Snapshot::Kind kind,
+                                  bool as_reference) {
   // Views have always a backing store.
-  ASSERT(ptr()->typed_data_ != Object::null());
+  ASSERT(typed_data_ != Object::null());
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1574,18 +1572,18 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write members.
-  writer->Write<RawObject*>(ptr()->offset_in_bytes_);
-  writer->Write<RawObject*>(ptr()->length_);
-  writer->WriteObjectImpl(ptr()->typed_data_, as_reference);
+  writer->Write<ObjectPtr>(offset_in_bytes_);
+  writer->Write<ObjectPtr>(length_);
+  writer->WriteObjectImpl(typed_data_, as_reference);
 }
 
-RawTypedDataView* TypedDataView::ReadFrom(SnapshotReader* reader,
-                                          intptr_t object_id,
-                                          intptr_t tags,
-                                          Snapshot::Kind kind,
-                                          bool as_reference) {
+TypedDataViewPtr TypedDataView::ReadFrom(SnapshotReader* reader,
+                                         intptr_t object_id,
+                                         intptr_t tags,
+                                         Snapshot::Kind kind,
+                                         bool as_reference) {
   auto& typed_data = *reader->TypedDataBaseHandle();
-  const classid_t cid = RawObject::ClassIdTag::decode(tags);
+  const classid_t cid = ObjectLayout::ClassIdTag::decode(tags);
 
   auto& view = *reader->TypedDataViewHandle();
   view = TypedDataView::New(cid);
@@ -1599,11 +1597,11 @@
   return view.raw();
 }
 
-RawCapability* Capability::ReadFrom(SnapshotReader* reader,
-                                    intptr_t object_id,
-                                    intptr_t tags,
-                                    Snapshot::Kind kind,
-                                    bool as_reference) {
+CapabilityPtr Capability::ReadFrom(SnapshotReader* reader,
+                                   intptr_t object_id,
+                                   intptr_t tags,
+                                   Snapshot::Kind kind,
+                                   bool as_reference) {
   uint64_t id = reader->Read<uint64_t>();
 
   Capability& result =
@@ -1612,10 +1610,10 @@
   return result.raw();
 }
 
-void RawCapability::WriteTo(SnapshotWriter* writer,
-                            intptr_t object_id,
-                            Snapshot::Kind kind,
-                            bool as_reference) {
+void CapabilityLayout::WriteTo(SnapshotWriter* writer,
+                               intptr_t object_id,
+                               Snapshot::Kind kind,
+                               bool as_reference) {
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
@@ -1623,14 +1621,14 @@
   writer->WriteIndexedObject(kCapabilityCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  writer->Write<uint64_t>(ptr()->id_);
+  writer->Write<uint64_t>(id_);
 }
 
-RawSendPort* SendPort::ReadFrom(SnapshotReader* reader,
-                                intptr_t object_id,
-                                intptr_t tags,
-                                Snapshot::Kind kind,
-                                bool as_reference) {
+SendPortPtr SendPort::ReadFrom(SnapshotReader* reader,
+                               intptr_t object_id,
+                               intptr_t tags,
+                               Snapshot::Kind kind,
+                               bool as_reference) {
   ASSERT(kind == Snapshot::kMessage);
 
   uint64_t id = reader->Read<uint64_t>();
@@ -1642,10 +1640,10 @@
   return result.raw();
 }
 
-void RawSendPort::WriteTo(SnapshotWriter* writer,
-                          intptr_t object_id,
-                          Snapshot::Kind kind,
-                          bool as_reference) {
+void SendPortLayout::WriteTo(SnapshotWriter* writer,
+                             intptr_t object_id,
+                             Snapshot::Kind kind,
+                             bool as_reference) {
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
@@ -1653,16 +1651,15 @@
   writer->WriteIndexedObject(kSendPortCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  writer->Write<uint64_t>(ptr()->id_);
-  writer->Write<uint64_t>(ptr()->origin_id_);
+  writer->Write<uint64_t>(id_);
+  writer->Write<uint64_t>(origin_id_);
 }
 
-RawTransferableTypedData* TransferableTypedData::ReadFrom(
-    SnapshotReader* reader,
-    intptr_t object_id,
-    intptr_t tags,
-    Snapshot::Kind kind,
-    bool as_reference) {
+TransferableTypedDataPtr TransferableTypedData::ReadFrom(SnapshotReader* reader,
+                                                         intptr_t object_id,
+                                                         intptr_t tags,
+                                                         Snapshot::Kind kind,
+                                                         bool as_reference) {
   ASSERT(reader != nullptr);
 
   ASSERT(!Snapshot::IsFull(kind));
@@ -1677,13 +1674,13 @@
   return transferableTypedData.raw();
 }
 
-void RawTransferableTypedData::WriteTo(SnapshotWriter* writer,
-                                       intptr_t object_id,
-                                       Snapshot::Kind kind,
-                                       bool as_reference) {
+void TransferableTypedDataLayout::WriteTo(SnapshotWriter* writer,
+                                          intptr_t object_id,
+                                          Snapshot::Kind kind,
+                                          bool as_reference) {
   ASSERT(writer != nullptr);
   ASSERT(GetClassId() == kTransferableTypedDataCid);
-  void* peer = writer->thread()->heap()->GetPeer(this);
+  void* peer = writer->thread()->heap()->GetPeer(ObjectPtr(this));
   // Assume that object's Peer is only used to track transferrability state.
   ASSERT(peer != nullptr);
   TransferableTypedDataPeer* tpeer =
@@ -1719,11 +1716,11 @@
       });
 }
 
-RawRegExp* RegExp::ReadFrom(SnapshotReader* reader,
-                            intptr_t object_id,
-                            intptr_t tags,
-                            Snapshot::Kind kind,
-                            bool as_reference) {
+RegExpPtr RegExp::ReadFrom(SnapshotReader* reader,
+                           intptr_t object_id,
+                           intptr_t tags,
+                           Snapshot::Kind kind,
+                           bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate RegExp object.
@@ -1755,10 +1752,10 @@
   return regex.raw();
 }
 
-void RawRegExp::WriteTo(SnapshotWriter* writer,
-                        intptr_t object_id,
-                        Snapshot::Kind kind,
-                        bool as_reference) {
+void RegExpLayout::WriteTo(SnapshotWriter* writer,
+                           intptr_t object_id,
+                           Snapshot::Kind kind,
+                           bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
@@ -1769,18 +1766,18 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the other fields.
-  writer->Write<RawObject*>(ptr()->num_bracket_expressions_);
-  writer->WriteObjectImpl(ptr()->pattern_, kAsInlinedObject);
-  writer->Write<int32_t>(ptr()->num_one_byte_registers_);
-  writer->Write<int32_t>(ptr()->num_two_byte_registers_);
-  writer->Write<int8_t>(ptr()->type_flags_);
+  writer->Write<ObjectPtr>(num_bracket_expressions_);
+  writer->WriteObjectImpl(pattern_, kAsInlinedObject);
+  writer->Write<int32_t>(num_one_byte_registers_);
+  writer->Write<int32_t>(num_two_byte_registers_);
+  writer->Write<int8_t>(type_flags_);
 }
 
-RawWeakProperty* WeakProperty::ReadFrom(SnapshotReader* reader,
-                                        intptr_t object_id,
-                                        intptr_t tags,
-                                        Snapshot::Kind kind,
-                                        bool as_reference) {
+WeakPropertyPtr WeakProperty::ReadFrom(SnapshotReader* reader,
+                                       intptr_t object_id,
+                                       intptr_t tags,
+                                       Snapshot::Kind kind,
+                                       bool as_reference) {
   ASSERT(reader != NULL);
 
   // Allocate the weak property object.
@@ -1789,16 +1786,16 @@
   reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(weak_property, weak_property.raw()->from(),
-                     weak_property.raw()->to(), kAsReference);
+  READ_OBJECT_FIELDS(weak_property, weak_property.raw()->ptr()->from(),
+                     weak_property.raw()->ptr()->to(), kAsReference);
 
   return weak_property.raw();
 }
 
-void RawWeakProperty::WriteTo(SnapshotWriter* writer,
-                              intptr_t object_id,
-                              Snapshot::Kind kind,
-                              bool as_reference) {
+void WeakPropertyLayout::WriteTo(SnapshotWriter* writer,
+                                 intptr_t object_id,
+                                 Snapshot::Kind kind,
+                                 bool as_reference) {
   ASSERT(writer != NULL);
 
   // Write out the serialization header value for this object.
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 95567a9..8b3e30f 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -14,12 +14,15 @@
 #include "vm/dart_entry.h"
 #include "vm/regexp_assembler.h"
 #include "vm/regexp_assembler_bytecode.h"
-#include "vm/regexp_assembler_ir.h"
 #include "vm/regexp_ast.h"
 #include "vm/symbols.h"
 #include "vm/thread.h"
 #include "vm/unibrow-inl.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/regexp_assembler_ir.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 #define Z (zone())
 
 namespace dart {
@@ -701,7 +704,7 @@
 
   // Omit flushing the trace. We discard the entire stack frame anyway.
 
-  if (!label()->IsBound()) {
+  if (!label()->is_bound()) {
     // We are completely independent of the trace, since we ignore it,
     // so this code can be used as the generic version.
     assembler->BindBlock(label());
@@ -728,7 +731,7 @@
     return;
   }
   RegExpMacroAssembler* assembler = compiler->macro_assembler();
-  if (!label()->IsBound()) {
+  if (!label()->is_bound()) {
     assembler->BindBlock(label());
   }
   switch (action_) {
@@ -1126,7 +1129,7 @@
   EmitDoubleBoundaryTest(masm, ranges->At(cut_index),
                          ranges->At(cut_index + 1) - 1, &dummy, in_range_label,
                          &dummy);
-  ASSERT(!dummy.IsLinked());
+  ASSERT(!dummy.is_linked());
   // Cut out the single range by rewriting the array.  This creates a new
   // range that is a merger of the two ranges on either side of the one we
   // are cutting out.  The oddity of the labels is preserved.
@@ -1314,7 +1317,7 @@
   GenerateBranches(masm, ranges, start_index, new_end_index, min_char,
                    border - 1, &dummy, even_label, odd_label);
 
-  if (handle_rest.IsLinked()) {
+  if (handle_rest.is_linked()) {
     masm->BindBlock(&handle_rest);
     bool flip = (new_start_index & 1) != (start_index & 1);
     GenerateBranches(masm, ranges, new_start_index, end_index, border, max_char,
@@ -1432,7 +1435,7 @@
 
   RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
   if (trace->is_trivial()) {
-    if (label_.IsBound()) {
+    if (label_.is_bound()) {
       // We are being asked to generate a generic version, but that's already
       // been done so just go to it.
       macro_assembler->GoTo(&label_);
@@ -3352,7 +3355,7 @@
                                            AlternativeGeneration* alt_gen,
                                            intptr_t preload_characters,
                                            bool next_expects_preload) {
-  if (!alt_gen->possible_success.IsLinked()) return;
+  if (!alt_gen->possible_success.is_linked()) return;
 
   RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
   macro_assembler->BindBlock(&alt_gen->possible_success);
@@ -3621,7 +3624,7 @@
   printer.PrintBit("WI", info->follows_word_interest);
   printer.PrintBit("SI", info->follows_start_interest);
   BlockLabel* label = that->label();
-  if (label->IsBound()) printer.PrintPositive("@", label->Position());
+  if (label->is_bound()) printer.PrintPositive("@", label->pos());
   OS::PrintErr(
       "}\"];\n"
       "  a%p -> n%p [style=dashed, color=grey, arrowhead=none];\n",
@@ -5512,7 +5515,7 @@
 
   Function& fn =
       Function::Handle(zone, Function::New(Symbols::ColonMatcher(),
-                                           RawFunction::kIrregexpFunction,
+                                           FunctionLayout::kIrregexpFunction,
                                            true,   // Static.
                                            false,  // Not const.
                                            false,  // Not abstract.
@@ -5549,9 +5552,9 @@
   // The function is compiled lazily during the first call.
 }
 
-RawRegExp* RegExpEngine::CreateRegExp(Thread* thread,
-                                      const String& pattern,
-                                      RegExpFlags flags) {
+RegExpPtr RegExpEngine::CreateRegExp(Thread* thread,
+                                     const String& pattern,
+                                     RegExpFlags flags) {
   Zone* zone = thread->zone();
   const RegExp& regexp = RegExp::Handle(RegExp::New());
 
diff --git a/runtime/vm/regexp.h b/runtime/vm/regexp.h
index 170d412..3fed61b 100644
--- a/runtime/vm/regexp.h
+++ b/runtime/vm/regexp.h
@@ -7,9 +7,6 @@
 
 #include "platform/unicode.h"
 
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/compiler/backend/il.h"
 #include "vm/object.h"
 #include "vm/regexp_assembler.h"
 #include "vm/splay-tree.h"
@@ -1513,9 +1510,9 @@
                                            bool sticky,
                                            Zone* zone);
 
-  static RawRegExp* CreateRegExp(Thread* thread,
-                                 const String& pattern,
-                                 RegExpFlags flags);
+  static RegExpPtr CreateRegExp(Thread* thread,
+                                const String& pattern,
+                                RegExpFlags flags);
 
   static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
 };
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc
index ab242c4..3c2e119 100644
--- a/runtime/vm/regexp_assembler.cc
+++ b/runtime/vm/regexp_assembler.cc
@@ -10,6 +10,7 @@
 
 #include "vm/flags.h"
 #include "vm/regexp.h"
+#include "vm/runtime_entry.h"
 #include "vm/unibrow-inl.h"
 
 namespace dart {
@@ -20,14 +21,14 @@
   OS::PrintErr(format, c);
 }
 
-RawBool* CaseInsensitiveCompareUCS2(RawString* str_raw,
-                                    RawSmi* lhs_index_raw,
-                                    RawSmi* rhs_index_raw,
-                                    RawSmi* length_raw) {
-  const String& str = String::Handle(str_raw);
-  const Smi& lhs_index = Smi::Handle(lhs_index_raw);
-  const Smi& rhs_index = Smi::Handle(rhs_index_raw);
-  const Smi& length = Smi::Handle(length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUCS2(uword /*StringPtr*/ str_raw,
+                                             uword /*SmiPtr*/ lhs_index_raw,
+                                             uword /*SmiPtr*/ rhs_index_raw,
+                                             uword /*SmiPtr*/ length_raw) {
+  const String& str = String::Handle(static_cast<StringPtr>(str_raw));
+  const Smi& lhs_index = Smi::Handle(static_cast<SmiPtr>(lhs_index_raw));
+  const Smi& rhs_index = Smi::Handle(static_cast<SmiPtr>(rhs_index_raw));
+  const Smi& length = Smi::Handle(static_cast<SmiPtr>(length_raw));
 
   // TODO(zerny): Optimize as single instance. V8 has this as an
   // isolate member.
@@ -43,22 +44,22 @@
         int32_t s2[1] = {c2};
         canonicalize.get(c2, '\0', s2);
         if (s1[0] != s2[0]) {
-          return Bool::False().raw();
+          return static_cast<uword>(Bool::False().raw());
         }
       }
     }
   }
-  return Bool::True().raw();
+  return static_cast<uword>(Bool::True().raw());
 }
 
-RawBool* CaseInsensitiveCompareUTF16(RawString* str_raw,
-                                     RawSmi* lhs_index_raw,
-                                     RawSmi* rhs_index_raw,
-                                     RawSmi* length_raw) {
-  const String& str = String::Handle(str_raw);
-  const Smi& lhs_index = Smi::Handle(lhs_index_raw);
-  const Smi& rhs_index = Smi::Handle(rhs_index_raw);
-  const Smi& length = Smi::Handle(length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUTF16(uword /*StringPtr*/ str_raw,
+                                              uword /*SmiPtr*/ lhs_index_raw,
+                                              uword /*SmiPtr*/ rhs_index_raw,
+                                              uword /*SmiPtr*/ length_raw) {
+  const String& str = String::Handle(static_cast<StringPtr>(str_raw));
+  const Smi& lhs_index = Smi::Handle(static_cast<SmiPtr>(lhs_index_raw));
+  const Smi& rhs_index = Smi::Handle(static_cast<SmiPtr>(rhs_index_raw));
+  const Smi& length = Smi::Handle(static_cast<SmiPtr>(length_raw));
 
   for (intptr_t i = 0; i < length.Value(); i++) {
     int32_t c1 = str.CharAt(lhs_index.Value() + i);
@@ -66,7 +67,8 @@
     if (Utf16::IsLeadSurrogate(c1)) {
       // Non-BMP characters do not have case-equivalents in the BMP.
       // Both have to be non-BMP for them to be able to match.
-      if (!Utf16::IsLeadSurrogate(c2)) return Bool::False().raw();
+      if (!Utf16::IsLeadSurrogate(c2))
+        return static_cast<uword>(Bool::False().raw());
       if (i + 1 < length.Value()) {
         uint16_t c1t = str.CharAt(lhs_index.Value() + i + 1);
         uint16_t c2t = str.CharAt(rhs_index.Value() + i + 1);
@@ -79,9 +81,9 @@
     }
     c1 = u_foldCase(c1, U_FOLD_CASE_DEFAULT);
     c2 = u_foldCase(c2, U_FOLD_CASE_DEFAULT);
-    if (c1 != c2) return Bool::False().raw();
+    if (c1 != c2) return static_cast<uword>(Bool::False().raw());
   }
-  return Bool::True().raw();
+  return static_cast<uword>(Bool::True().raw());
 }
 
 DEFINE_RAW_LEAF_RUNTIME_ENTRY(
@@ -96,8 +98,7 @@
     false /* is_float */,
     reinterpret_cast<RuntimeFunction>(&CaseInsensitiveCompareUTF16));
 
-BlockLabel::BlockLabel()
-    : block_(NULL), is_bound_(false), is_linked_(false), pos_(-1) {
+BlockLabel::BlockLabel() {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (!FLAG_interpret_irregexp) {
     // Only needed by the compiled IR backend.
diff --git a/runtime/vm/regexp_assembler.h b/runtime/vm/regexp_assembler.h
index 818f573..d858c48 100644
--- a/runtime/vm/regexp_assembler.h
+++ b/runtime/vm/regexp_assembler.h
@@ -5,87 +5,92 @@
 #ifndef RUNTIME_VM_REGEXP_ASSEMBLER_H_
 #define RUNTIME_VM_REGEXP_ASSEMBLER_H_
 
+#include "vm/object.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/il.h"
-#include "vm/object.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
 // Utility function for the DotPrinter
 void PrintUtf16(uint16_t c);
+
+extern "C" {
 // Compares two-byte strings case insensitively as UCS2.
 // Called from generated RegExp code.
-RawBool* CaseInsensitiveCompareUCS2(RawString* str_raw,
-                                    RawSmi* lhs_index_raw,
-                                    RawSmi* rhs_index_raw,
-                                    RawSmi* length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUCS2(uword /*StringPtr*/ str_raw,
+                                             uword /*SmiPtr*/ lhs_index_raw,
+                                             uword /*SmiPtr*/ rhs_index_raw,
+                                             uword /*SmiPtr*/ length_raw);
 
 // Compares two-byte strings case insensitively as UTF16.
 // Called from generated RegExp code.
-RawBool* CaseInsensitiveCompareUTF16(RawString* str_raw,
-                                     RawSmi* lhs_index_raw,
-                                     RawSmi* rhs_index_raw,
-                                     RawSmi* length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUTF16(uword /*StringPtr*/ str_raw,
+                                              uword /*SmiPtr*/ lhs_index_raw,
+                                              uword /*SmiPtr*/ rhs_index_raw,
+                                              uword /*SmiPtr*/ length_raw);
+}
 
 /// Convenience wrapper around a BlockEntryInstr pointer.
 class BlockLabel : public ValueObject {
   // Used by the IR assembler.
  public:
   BlockLabel();
-
-  JoinEntryInstr* block() const { return block_; }
-
-  bool IsBound() const { return is_bound_; }
-  void SetBound(intptr_t block_id) {
-    ASSERT(!is_bound_);
-    block_->set_block_id(block_id);
-    is_bound_ = true;
-  }
-
-  bool IsLinked() const { return !is_bound_ && is_linked_; }
-  void SetLinked() { is_linked_ = true; }
-
-  intptr_t Position() const {
-    ASSERT(IsBound());
-    return block_->block_id();
-  }
-
- private:
-  JoinEntryInstr* block_;
-
-  bool is_bound_;
-  bool is_linked_;
-
-  // Used by the bytecode assembler.
- public:
   ~BlockLabel() { ASSERT(!is_linked()); }
 
   intptr_t pos() const { return pos_; }
-  bool is_bound() const { return IsBound(); }
-  bool is_linked() const { return IsLinked(); }
+  bool is_bound() const { return is_bound_; }
+  bool is_linked() const { return !is_bound_ && is_linked_; }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  JoinEntryInstr* block() const { return block_; }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   void Unuse() {
-    pos_ = 0;
+    pos_ = -1;
     is_bound_ = false;
     is_linked_ = false;
   }
 
-  void bind_to(intptr_t pos) {
+  void BindTo(intptr_t pos) {
     pos_ = pos;
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    if (block_ != nullptr) block_->set_block_id(pos);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
     is_bound_ = true;
     is_linked_ = false;
     ASSERT(is_bound());
   }
 
-  void link_to(intptr_t pos) {
+  // Used by bytecode assembler to form a linked list out of
+  // forward jumps to an unbound label.
+  void LinkTo(intptr_t pos) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    ASSERT(block_ == nullptr);
+#endif
+    ASSERT(!is_bound_);
     pos_ = pos;
-    is_bound_ = false;
     is_linked_ = true;
-    ASSERT(is_linked());
+  }
+
+  // Used by IR builder to mark block label as used.
+  void SetLinked() {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    ASSERT(block_ != nullptr);
+#endif
+    if (!is_bound_) {
+      is_linked_ = true;
+    }
   }
 
  private:
-  intptr_t pos_;
+  bool is_bound_ = false;
+  bool is_linked_ = false;
+  intptr_t pos_ = -1;
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  JoinEntryInstr* block_ = nullptr;
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 };
 
 class RegExpMacroAssembler : public ZoneAllocated {
diff --git a/runtime/vm/regexp_assembler_bytecode.cc b/runtime/vm/regexp_assembler_bytecode.cc
index c075a86..a7e2ff3 100644
--- a/runtime/vm/regexp_assembler_bytecode.cc
+++ b/runtime/vm/regexp_assembler_bytecode.cc
@@ -44,7 +44,7 @@
       *reinterpret_cast<uint32_t*>(buffer_->data() + fixup) = pc_;
     }
   }
-  l->bind_to(pc_);
+  l->BindTo(pc_);
 }
 
 void BytecodeRegExpMacroAssembler::EmitOrLink(BlockLabel* l) {
@@ -56,7 +56,7 @@
     if (l->is_linked()) {
       pos = l->pos();
     }
-    l->link_to(pc_);
+    l->LinkTo(pc_);
     Emit32(pos);
   }
 }
@@ -390,7 +390,7 @@
   EmitOrLink(on_eq);
 }
 
-RawTypedData* BytecodeRegExpMacroAssembler::GetBytecode() {
+TypedDataPtr BytecodeRegExpMacroAssembler::GetBytecode() {
   BindBlock(&backtrack_);
   Emit(BC_POP_BT, 0);
 
@@ -511,11 +511,11 @@
   return result;
 }
 
-RawInstance* BytecodeRegExpMacroAssembler::Interpret(const RegExp& regexp,
-                                                     const String& subject,
-                                                     const Smi& start_index,
-                                                     bool sticky,
-                                                     Zone* zone) {
+InstancePtr BytecodeRegExpMacroAssembler::Interpret(const RegExp& regexp,
+                                                    const String& subject,
+                                                    const Smi& start_index,
+                                                    bool sticky,
+                                                    Zone* zone) {
   intptr_t required_registers = Prepare(regexp, subject, sticky, zone);
   if (required_registers < 0) {
     // Compiling failed with an exception.
diff --git a/runtime/vm/regexp_assembler_bytecode.h b/runtime/vm/regexp_assembler_bytecode.h
index 59cf68f..cdedaa1 100644
--- a/runtime/vm/regexp_assembler_bytecode.h
+++ b/runtime/vm/regexp_assembler_bytecode.h
@@ -95,7 +95,7 @@
 
   virtual IrregexpImplementation Implementation();
   // virtual Handle<HeapObject> GetCode(Handle<String> source);
-  RawTypedData* GetBytecode();
+  TypedDataPtr GetBytecode();
 
   // New
   virtual bool IsClosed() const {
@@ -107,11 +107,11 @@
   virtual void PrintBlocks() { UNIMPLEMENTED(); }
   /////
 
-  static RawInstance* Interpret(const RegExp& regexp,
-                                const String& str,
-                                const Smi& start_index,
-                                bool is_sticky,
-                                Zone* zone);
+  static InstancePtr Interpret(const RegExp& regexp,
+                               const String& str,
+                               const Smi& start_index,
+                               bool is_sticky,
+                               Zone* zone);
 
  private:
   void Expand();
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 500a52f..116ff0c 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -299,11 +299,11 @@
   return kEnableUnalignedAccesses && !slow_safe();
 }
 
-RawArray* IRRegExpMacroAssembler::Execute(const RegExp& regexp,
-                                          const String& input,
-                                          const Smi& start_offset,
-                                          bool sticky,
-                                          Zone* zone) {
+ArrayPtr IRRegExpMacroAssembler::Execute(const RegExp& regexp,
+                                         const String& input,
+                                         const Smi& start_offset,
+                                         bool sticky,
+                                         Zone* zone) {
   const intptr_t cid = input.GetClassId();
   const Function& fun = Function::Handle(regexp.function(cid, sticky));
   ASSERT(!fun.IsNull());
@@ -682,10 +682,10 @@
 // If the BlockLabel does not yet contain a block, it is created.
 // If there is a current instruction, append a goto to the bound block.
 void IRRegExpMacroAssembler::BindBlock(BlockLabel* label) {
-  ASSERT(!label->IsBound());
+  ASSERT(!label->is_bound());
   ASSERT(label->block()->next() == NULL);
 
-  label->SetBound(block_id_.Alloc());
+  label->BindTo(block_id_.Alloc());
   blocks_.Add(label->block());
 
   if (current_instruction_ != NULL) {
@@ -1752,7 +1752,7 @@
                                                intptr_t characters) {
   // Bind the pattern as the load receiver.
   Value* pattern_val = BindLoadLocal(*string_param_);
-  if (RawObject::IsExternalStringClassId(specialization_cid_)) {
+  if (IsExternalStringClassId(specialization_cid_)) {
     // The data of an external string is stored through one indirection.
     intptr_t external_offset = 0;
     if (specialization_cid_ == kExternalOneByteStringCid) {
diff --git a/runtime/vm/regexp_assembler_ir.h b/runtime/vm/regexp_assembler_ir.h
index fb92f1b..d52128d 100644
--- a/runtime/vm/regexp_assembler_ir.h
+++ b/runtime/vm/regexp_assembler_ir.h
@@ -38,11 +38,11 @@
 
   virtual bool CanReadUnaligned();
 
-  static RawArray* Execute(const RegExp& regexp,
-                           const String& input,
-                           const Smi& start_offset,
-                           bool sticky,
-                           Zone* zone);
+  static ArrayPtr Execute(const RegExp& regexp,
+                          const String& input,
+                          const Smi& start_offset,
+                          bool sticky,
+                          Zone* zone);
 
   virtual bool IsClosed() const { return (current_instruction_ == NULL); }
 
diff --git a/runtime/vm/regexp_interpreter.cc b/runtime/vm/regexp_interpreter.cc
index 2921e3e..111c7fe 100644
--- a/runtime/vm/regexp_interpreter.cc
+++ b/runtime/vm/regexp_interpreter.cc
@@ -36,11 +36,15 @@
                                     bool unicode) {
   Bool& ret = Bool::Handle();
   if (unicode) {
-    ret = CaseInsensitiveCompareUTF16(subject.raw(), Smi::New(from),
-                                      Smi::New(current), Smi::New(len));
+    ret = static_cast<BoolPtr>(CaseInsensitiveCompareUTF16(
+        static_cast<uword>(subject.raw()), static_cast<uword>(Smi::New(from)),
+        static_cast<uword>(Smi::New(current)),
+        static_cast<uword>(Smi::New(len))));
   } else {
-    ret = CaseInsensitiveCompareUCS2(subject.raw(), Smi::New(from),
-                                     Smi::New(current), Smi::New(len));
+    ret = static_cast<BoolPtr>(CaseInsensitiveCompareUCS2(
+        static_cast<uword>(subject.raw()), static_cast<uword>(Smi::New(from)),
+        static_cast<uword>(Smi::New(current)),
+        static_cast<uword>(Smi::New(len))));
   }
   return ret.value();
 }
diff --git a/runtime/vm/regexp_parser.cc b/runtime/vm/regexp_parser.cc
index c9987e3..d7f4235 100644
--- a/runtime/vm/regexp_parser.cc
+++ b/runtime/vm/regexp_parser.cc
@@ -1242,7 +1242,7 @@
   return captures_->At(index - 1);
 }
 
-RawArray* RegExpParser::CreateCaptureNameMap() {
+ArrayPtr RegExpParser::CreateCaptureNameMap() {
   if (named_captures_ == nullptr || named_captures_->is_empty()) {
     return Array::null();
   }
diff --git a/runtime/vm/regexp_parser.h b/runtime/vm/regexp_parser.h
index 63c237a..fd456ba 100644
--- a/runtime/vm/regexp_parser.h
+++ b/runtime/vm/regexp_parser.h
@@ -228,7 +228,7 @@
   // to avoid complicating cases in which references come before the capture.
   void PatchNamedBackReferences();
 
-  RawArray* CreateCaptureNameMap();
+  ArrayPtr CreateCaptureNameMap();
 
   // Returns true iff the pattern contains named captures. May call
   // ScanForCaptures to look ahead at the remaining pattern.
diff --git a/runtime/vm/regexp_test.cc b/runtime/vm/regexp_test.cc
index 5ba4056..01eca0e 100644
--- a/runtime/vm/regexp_test.cc
+++ b/runtime/vm/regexp_test.cc
@@ -12,7 +12,7 @@
 
 namespace dart {
 
-static RawArray* Match(const String& pat, const String& str) {
+static ArrayPtr Match(const String& pat, const String& str) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const RegExp& regexp =
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index 5d0c407..ded367d6 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -17,11 +17,11 @@
 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
 
-RawString* Report::PrependSnippet(Kind kind,
-                                  const Script& script,
-                                  TokenPosition token_pos,
-                                  bool report_after_token,
-                                  const String& message) {
+StringPtr Report::PrependSnippet(Kind kind,
+                                 const Script& script,
+                                 TokenPosition token_pos,
+                                 bool report_after_token,
+                                 const String& message) {
   const char* message_header;
   switch (kind) {
     case kWarning:
diff --git a/runtime/vm/report.h b/runtime/vm/report.h
index 30aaf5c..3af8573 100644
--- a/runtime/vm/report.h
+++ b/runtime/vm/report.h
@@ -6,6 +6,7 @@
 #define RUNTIME_VM_REPORT_H_
 
 #include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
 #include "vm/token_position.h"
 
 namespace dart {
@@ -13,7 +14,6 @@
 // Forward declarations.
 class Error;
 class ICData;
-class RawString;
 class Script;
 class StackFrame;
 class String;
@@ -60,11 +60,11 @@
 
   // Prepend a source snippet to the message.
   // A null script means no source and a negative token_pos means no position.
-  static RawString* PrependSnippet(Kind kind,
-                                   const Script& script,
-                                   TokenPosition token_pos,
-                                   bool report_after_token,
-                                   const String& message);
+  static StringPtr PrependSnippet(Kind kind,
+                                  const Script& script,
+                                  TokenPosition token_pos,
+                                  bool report_after_token,
+                                  const String& message);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Report);
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 2dd5129..d05a03d 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -22,15 +22,15 @@
 // them, since the entry code of such a method does not check for named
 // arguments. The dynamic resolver actually checks that a valid number of named
 // arguments is passed in.
-RawFunction* Resolver::ResolveDynamic(const Instance& receiver,
-                                      const String& function_name,
-                                      const ArgumentsDescriptor& args_desc) {
+FunctionPtr Resolver::ResolveDynamic(const Instance& receiver,
+                                     const String& function_name,
+                                     const ArgumentsDescriptor& args_desc) {
   // Figure out type of receiver first.
   const Class& cls = Class::Handle(receiver.clazz());
   return ResolveDynamicForReceiverClass(cls, function_name, args_desc);
 }
 
-RawFunction* Resolver::ResolveDynamicForReceiverClass(
+FunctionPtr Resolver::ResolveDynamicForReceiverClass(
     const Class& receiver_class,
     const String& function_name,
     const ArgumentsDescriptor& args_desc,
@@ -60,10 +60,10 @@
   return function.raw();
 }
 
-RawFunction* Resolver::ResolveDynamicAnyArgs(Zone* zone,
-                                             const Class& receiver_class,
-                                             const String& function_name,
-                                             bool allow_add) {
+FunctionPtr Resolver::ResolveDynamicAnyArgs(Zone* zone,
+                                            const Class& receiver_class,
+                                            const String& function_name,
+                                            bool allow_add) {
   Class& cls = Class::Handle(zone, receiver_class.raw());
   if (FLAG_trace_resolving) {
     THR_Print("ResolveDynamic '%s' for class %s\n", function_name.ToCString(),
@@ -86,7 +86,8 @@
     while (!cls.IsNull()) {
       function = cls.GetInvocationDispatcher(
           function_name, Array::null_array(),
-          RawFunction::kDynamicInvocationForwarder, /*create_if_absent=*/false);
+          FunctionLayout::kDynamicInvocationForwarder,
+          /*create_if_absent=*/false);
       if (!function.IsNull()) break;
       cls = cls.SuperClass();
     }
@@ -136,12 +137,12 @@
   return function.raw();
 }
 
-RawFunction* Resolver::ResolveStatic(const Library& library,
-                                     const String& class_name,
-                                     const String& function_name,
-                                     intptr_t type_args_len,
-                                     intptr_t num_arguments,
-                                     const Array& argument_names) {
+FunctionPtr Resolver::ResolveStatic(const Library& library,
+                                    const String& class_name,
+                                    const String& function_name,
+                                    intptr_t type_args_len,
+                                    intptr_t num_arguments,
+                                    const Array& argument_names) {
   ASSERT(!library.IsNull());
   Function& function = Function::Handle();
   if (class_name.IsNull() || (class_name.Length() == 0)) {
@@ -184,11 +185,11 @@
   return function.raw();
 }
 
-RawFunction* Resolver::ResolveStatic(const Class& cls,
-                                     const String& function_name,
-                                     intptr_t type_args_len,
-                                     intptr_t num_arguments,
-                                     const Array& argument_names) {
+FunctionPtr Resolver::ResolveStatic(const Class& cls,
+                                    const String& function_name,
+                                    intptr_t type_args_len,
+                                    intptr_t num_arguments,
+                                    const Array& argument_names) {
   ASSERT(!cls.IsNull());
   if (FLAG_trace_resolving) {
     THR_Print("ResolveStatic '%s'\n", function_name.ToCString());
diff --git a/runtime/vm/resolver.h b/runtime/vm/resolver.h
index b96f581..0d9f8a9 100644
--- a/runtime/vm/resolver.h
+++ b/runtime/vm/resolver.h
@@ -6,6 +6,7 @@
 #define RUNTIME_VM_RESOLVER_H_
 
 #include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
@@ -14,7 +15,6 @@
 class Class;
 class Instance;
 class Library;
-class RawFunction;
 class String;
 class ArgumentsDescriptor;
 
@@ -23,22 +23,22 @@
 class Resolver : public AllStatic {
  public:
   // Resolve specified dart instance function.
-  static RawFunction* ResolveDynamic(const Instance& receiver,
-                                     const String& function_name,
-                                     const ArgumentsDescriptor& args_desc);
+  static FunctionPtr ResolveDynamic(const Instance& receiver,
+                                    const String& function_name,
+                                    const ArgumentsDescriptor& args_desc);
 
   // If 'allow_add' is true we may add a function to the class during lookup.
-  static RawFunction* ResolveDynamicForReceiverClass(
+  static FunctionPtr ResolveDynamicForReceiverClass(
       const Class& receiver_class,
       const String& function_name,
       const ArgumentsDescriptor& args_desc,
       bool allow_add = true);
 
   // If 'allow_add' is true we may add a function to the class during lookup.
-  static RawFunction* ResolveDynamicAnyArgs(Zone* zone,
-                                            const Class& receiver_class,
-                                            const String& function_name,
-                                            bool allow_add = true);
+  static FunctionPtr ResolveDynamicAnyArgs(Zone* zone,
+                                           const Class& receiver_class,
+                                           const String& function_name,
+                                           bool allow_add = true);
 
   // Resolve specified dart static function. If library.IsNull, use
   // either application library or core library if no application library
@@ -46,20 +46,20 @@
   // will be resolved by name only.
   // Otherwise null is returned if the number or names of arguments are not
   // valid for the resolved function.
-  static RawFunction* ResolveStatic(const Library& library,
-                                    const String& cls_name,
-                                    const String& function_name,
-                                    intptr_t type_args_len,
-                                    intptr_t num_arguments,
-                                    const Array& argument_names);
+  static FunctionPtr ResolveStatic(const Library& library,
+                                   const String& cls_name,
+                                   const String& function_name,
+                                   intptr_t type_args_len,
+                                   intptr_t num_arguments,
+                                   const Array& argument_names);
 
   // Resolve specified dart static function with specified arity. Only resolves
   // public functions.
-  static RawFunction* ResolveStatic(const Class& cls,
-                                    const String& function_name,
-                                    intptr_t type_args_len,
-                                    intptr_t num_arguments,
-                                    const Array& argument_names);
+  static FunctionPtr ResolveStatic(const Class& cls,
+                                   const String& function_name,
+                                   intptr_t type_args_len,
+                                   intptr_t num_arguments,
+                                   const Array& argument_names);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/reverse_pc_lookup_cache.cc b/runtime/vm/reverse_pc_lookup_cache.cc
index 4757d24..e3d45ae 100644
--- a/runtime/vm/reverse_pc_lookup_cache.cc
+++ b/runtime/vm/reverse_pc_lookup_cache.cc
@@ -10,31 +10,33 @@
 
 #if defined(DART_PRECOMPILED_RUNTIME)
 
-static uword BeginPcFromCode(const RawCode* code) {
+static uword BeginPcFromCode(const CodePtr code) {
   return Code::PayloadStartOf(code);
 }
 
-static uword EndPcFromCode(const RawCode* code) {
+static uword EndPcFromCode(const CodePtr code) {
   return Code::PayloadStartOf(code) + Code::PayloadSizeOf(code);
 }
 
-void ReversePcLookupCache::BuildAndAttachToIsolate(Isolate* isolate) {
-  auto object_store = isolate->object_store();
+void ReversePcLookupCache::BuildAndAttachToIsolateGroup(
+    IsolateGroup* isolate_group) {
+  // This should be called once when the isolate group is created.
+  ASSERT(isolate_group->reverse_pc_lookup_cache() == nullptr);
+
+  auto object_store = isolate_group->object_store();
   auto& array = Array::Handle(object_store->code_order_table());
   if (!array.IsNull()) {
     const intptr_t length = array.Length();
     {
       NoSafepointScope no_safepoint_scope;
 
-      const uword begin =
-          BeginPcFromCode(reinterpret_cast<RawCode*>(array.At(0)));
+      const uword begin = BeginPcFromCode(static_cast<CodePtr>(array.At(0)));
       const uword end =
-          EndPcFromCode(reinterpret_cast<RawCode*>(array.At(length - 1)));
+          EndPcFromCode(static_cast<CodePtr>(array.At(length - 1)));
 
       auto pc_array = new uint32_t[length];
       for (intptr_t i = 0; i < length; i++) {
-        const auto end_pc =
-            EndPcFromCode(reinterpret_cast<RawCode*>(array.At(i)));
+        const auto end_pc = EndPcFromCode(static_cast<CodePtr>(array.At(i)));
         pc_array[i] = end_pc - begin;
       }
 #if defined(DEBUG)
@@ -43,8 +45,8 @@
       }
 #endif  // defined(DEBUG)
       auto cache =
-          new ReversePcLookupCache(isolate, pc_array, length, begin, end);
-      isolate->set_reverse_pc_lookup_cache(cache);
+          new ReversePcLookupCache(isolate_group, pc_array, length, begin, end);
+      isolate_group->set_reverse_pc_lookup_cache(cache);
     }
   }
 }
diff --git a/runtime/vm/reverse_pc_lookup_cache.h b/runtime/vm/reverse_pc_lookup_cache.h
index 7de0bff..d819956 100644
--- a/runtime/vm/reverse_pc_lookup_cache.h
+++ b/runtime/vm/reverse_pc_lookup_cache.h
@@ -43,21 +43,21 @@
 // WARNING: This class cannot do memory allocation or handle allocation!
 class ReversePcLookupCache {
  public:
-  ReversePcLookupCache(Isolate* isolate,
+  ReversePcLookupCache(IsolateGroup* isolate_group,
                        uint32_t* pc_array,
                        intptr_t length,
                        uword first_absolute_pc,
                        uword last_absolute_pc)
-      : isolate_(isolate),
+      : isolate_group_(isolate_group),
         pc_array_(pc_array),
         length_(length),
         first_absolute_pc_(first_absolute_pc),
         last_absolute_pc_(last_absolute_pc) {}
   ~ReversePcLookupCache() { delete[] pc_array_; }
 
-  // Builds a [ReversePcLookupCache] and attaches it to the isolate (if
+  // Builds a [ReversePcLookupCache] and attaches it to the isolate group (if
   // `code_order_table` is non-`null`).
-  static void BuildAndAttachToIsolate(Isolate* isolate);
+  static void BuildAndAttachToIsolateGroup(IsolateGroup* isolate_group);
 
   // Returns `true` if the given [pc] contains can be mapped to a [Code] object
   // using this cache.
@@ -70,7 +70,7 @@
   // If [is_return_address] is true, then the PC may be immediately after the
   // payload, if the last instruction is a call that is guaranteed not to
   // return. Otherwise, the PC must be within the payload.
-  inline RawCode* Lookup(uword pc, bool is_return_address = false) {
+  inline CodePtr Lookup(uword pc, bool is_return_address = false) {
     NoSafepointScope no_safepoint_scope;
 
     intptr_t left = 0;
@@ -98,8 +98,8 @@
       }
     }
 
-    auto code_array = isolate_->object_store()->code_order_table();
-    auto raw_code = reinterpret_cast<RawCode*>(Array::DataOf(code_array)[left]);
+    auto code_array = isolate_group_->object_store()->code_order_table();
+    auto raw_code = static_cast<CodePtr>(Array::DataOf(code_array)[left]);
 
 #if defined(DEBUG)
     ASSERT(raw_code->GetClassIdMayBeSmi() == kCodeCid);
@@ -110,7 +110,7 @@
   }
 
  private:
-  Isolate* isolate_;
+  IsolateGroup* isolate_group_;
   uint32_t* pc_array_;
   intptr_t length_;
   uword first_absolute_pc_;
@@ -124,11 +124,11 @@
   ReversePcLookupCache() {}
   ~ReversePcLookupCache() {}
 
-  static void BuildAndAttachToIsolate(Isolate* isolate) {}
+  static void BuildAndAttachToIsolateGroup(IsolateGroup* isolate_group) {}
 
   inline bool Contains(uword pc) { return false; }
 
-  inline RawCode* Lookup(uword pc, bool is_return_address = false) {
+  inline CodePtr Lookup(uword pc, bool is_return_address = false) {
     UNREACHABLE();
   }
 };
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 1a097cc..ecd35ca 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -4,14 +4,14 @@
 
 #include "vm/runtime_entry.h"
 
+#include "vm/code_descriptors.h"
 #include "vm/code_patcher.h"
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/frontend/bytecode_reader.h"
+#include "vm/compiler/api/deopt_id.h"
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_api_impl.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
-#include "vm/deopt_instructions.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
 #include "vm/heap/verifier.h"
@@ -30,6 +30,10 @@
 #include "vm/thread_registry.h"
 #include "vm/type_testing_stubs.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/deopt_instructions.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DEFINE_FLAG(
@@ -111,8 +115,8 @@
       Class::New(lib, class_name, script, TokenPosition::kNoSource));
   const String& function_name = String::ZoneHandle(Symbols::New(thread, name));
   const Function& function = Function::ZoneHandle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kMinSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kMinSource));
   const Array& functions = Array::Handle(Array::New(1));
   functions.SetAt(0, function);
   owner_class.SetFunctions(functions);
@@ -319,14 +323,15 @@
   }
 }
 
-DEFINE_LEAF_RUNTIME_ENTRY(RawObject*,
+DEFINE_LEAF_RUNTIME_ENTRY(uword /*ObjectPtr*/,
                           AddAllocatedObjectToRememberedSet,
                           2,
-                          RawObject* object,
+                          uword /*ObjectPtr*/ object_in,
                           Thread* thread) {
+  ObjectPtr object = static_cast<ObjectPtr>(object_in);
   // The allocation stubs in will call this leaf method for newly allocated
   // old space objects.
-  RELEASE_ASSERT(object->IsOldObject() && !object->IsRemembered());
+  RELEASE_ASSERT(object->IsOldObject() && !object->ptr()->IsRemembered());
 
   // If we eliminate a generational write barriers on allocations of an object
   // we need to ensure it's either a new-space object or it has been added to
@@ -339,22 +344,19 @@
   // in a long time).
   bool add_to_remembered_set = true;
   if (object->IsArray()) {
-    const intptr_t length =
-        Array::LengthOf(reinterpret_cast<RawArray*>(object));
+    const intptr_t length = Array::LengthOf(static_cast<ArrayPtr>(object));
     add_to_remembered_set =
-        CreateArrayInstr::WillAllocateNewOrRemembered(length);
+        compiler::target::WillAllocateNewOrRememberedArray(length);
   } else if (object->IsContext()) {
     const intptr_t num_context_variables =
-        Context::NumVariables(reinterpret_cast<RawContext*>(object));
+        Context::NumVariables(static_cast<ContextPtr>(object));
     add_to_remembered_set =
-        AllocateContextInstr::WillAllocateNewOrRemembered(
-            num_context_variables) ||
-        AllocateUninitializedContextInstr::WillAllocateNewOrRemembered(
+        compiler::target::WillAllocateNewOrRememberedContext(
             num_context_variables);
   }
 
   if (add_to_remembered_set) {
-    object->AddToRememberedSet(thread);
+    object->ptr()->AddToRememberedSet(thread);
   }
 
   // For incremental write barrier elimination, we need to ensure that the
@@ -364,7 +366,7 @@
     thread->DeferredMarkingStackAddObject(object);
   }
 
-  return object;
+  return static_cast<uword>(object);
 }
 END_LEAF_RUNTIME_ENTRY
 
@@ -416,10 +418,14 @@
   // Code inlined in the caller should have optimized the case where the
   // instantiator can be reused as type argument vector.
   ASSERT(!type_arguments.IsUninstantiatedIdentity());
-  type_arguments = type_arguments.InstantiateAndCanonicalizeFrom(
-      instantiator_type_arguments, function_type_arguments);
-  ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
-  arguments.SetReturn(type_arguments);
+  thread->isolate_group()->RunWithStoppedMutators(
+      [&]() {
+        type_arguments = type_arguments.InstantiateAndCanonicalizeFrom(
+            instantiator_type_arguments, function_type_arguments);
+        ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
+        arguments.SetReturn(type_arguments);
+      },
+      /*use_force_growth=*/true);
 }
 
 // Instantiate type.
@@ -596,6 +602,7 @@
 // This operation is currently very slow (lookup of code is not efficient yet).
 static void UpdateTypeTestCache(
     Zone* zone,
+    Thread* thread,
     const Instance& instance,
     const AbstractType& type,
     const TypeArguments& instantiator_type_arguments,
@@ -639,94 +646,112 @@
       instance_type_arguments = instance.GetTypeArguments();
     }
   }
-  const intptr_t len = new_cache.NumberOfChecks();
-  if (len >= FLAG_max_subtype_cache_entries) {
-    if (FLAG_trace_type_checks) {
-      OS::PrintErr("Not updating subtype test cache as its length reached %d\n",
-                   FLAG_max_subtype_cache_entries);
-    }
-    return;
-  }
+  thread->isolate_group()->RunWithStoppedMutators(
+      [&]() {
+        const intptr_t len = new_cache.NumberOfChecks();
+        if (len >= FLAG_max_subtype_cache_entries) {
+          if (FLAG_trace_type_checks) {
+            OS::PrintErr(
+                "Not updating subtype test cache as its length reached %d\n",
+                FLAG_max_subtype_cache_entries);
+          }
+          return;
+        }
 #if defined(DEBUG)
-  ASSERT(instance_type_arguments.IsNull() ||
-         instance_type_arguments.IsCanonical());
-  ASSERT(instantiator_type_arguments.IsNull() ||
-         instantiator_type_arguments.IsCanonical());
-  ASSERT(function_type_arguments.IsNull() ||
-         function_type_arguments.IsCanonical());
-  ASSERT(instance_parent_function_type_arguments.IsNull() ||
-         instance_parent_function_type_arguments.IsCanonical());
-  ASSERT(instance_delayed_type_arguments.IsNull() ||
-         instance_delayed_type_arguments.IsCanonical());
-  auto& last_instance_class_id_or_function = Object::Handle(zone);
-  auto& last_instance_type_arguments = TypeArguments::Handle(zone);
-  auto& last_instantiator_type_arguments = TypeArguments::Handle(zone);
-  auto& last_function_type_arguments = TypeArguments::Handle(zone);
-  auto& last_instance_parent_function_type_arguments =
-      TypeArguments::Handle(zone);
-  auto& last_instance_delayed_type_arguments = TypeArguments::Handle(zone);
-  Bool& last_result = Bool::Handle(zone);
-  for (intptr_t i = 0; i < len; ++i) {
-    new_cache.GetCheck(
-        i, &last_instance_class_id_or_function, &last_instance_type_arguments,
-        &last_instantiator_type_arguments, &last_function_type_arguments,
-        &last_instance_parent_function_type_arguments,
-        &last_instance_delayed_type_arguments, &last_result);
-    if ((last_instance_class_id_or_function.raw() ==
-         instance_class_id_or_function.raw()) &&
-        (last_instance_type_arguments.raw() == instance_type_arguments.raw()) &&
-        (last_instantiator_type_arguments.raw() ==
-         instantiator_type_arguments.raw()) &&
-        (last_function_type_arguments.raw() == function_type_arguments.raw()) &&
-        (last_instance_parent_function_type_arguments.raw() ==
-         instance_parent_function_type_arguments.raw()) &&
-        (last_instance_delayed_type_arguments.raw() ==
-         instance_delayed_type_arguments.raw())) {
-      OS::PrintErr("  Error in test cache %p ix: %" Pd ",", new_cache.raw(), i);
-      PrintTypeCheck(" duplicate cache entry", instance, type,
-                     instantiator_type_arguments, function_type_arguments,
-                     result);
-      UNREACHABLE();
-      return;
-    }
-  }
+        ASSERT(instance_type_arguments.IsNull() ||
+               instance_type_arguments.IsCanonical());
+        ASSERT(instantiator_type_arguments.IsNull() ||
+               instantiator_type_arguments.IsCanonical());
+        ASSERT(function_type_arguments.IsNull() ||
+               function_type_arguments.IsCanonical());
+        ASSERT(instance_parent_function_type_arguments.IsNull() ||
+               instance_parent_function_type_arguments.IsCanonical());
+        ASSERT(instance_delayed_type_arguments.IsNull() ||
+               instance_delayed_type_arguments.IsCanonical());
+        auto& last_instance_class_id_or_function = Object::Handle(zone);
+        auto& last_instance_type_arguments = TypeArguments::Handle(zone);
+        auto& last_instantiator_type_arguments = TypeArguments::Handle(zone);
+        auto& last_function_type_arguments = TypeArguments::Handle(zone);
+        auto& last_instance_parent_function_type_arguments =
+            TypeArguments::Handle(zone);
+        auto& last_instance_delayed_type_arguments =
+            TypeArguments::Handle(zone);
+        Bool& last_result = Bool::Handle(zone);
+        for (intptr_t i = 0; i < len; ++i) {
+          new_cache.GetCheck(
+              i, &last_instance_class_id_or_function,
+              &last_instance_type_arguments, &last_instantiator_type_arguments,
+              &last_function_type_arguments,
+              &last_instance_parent_function_type_arguments,
+              &last_instance_delayed_type_arguments, &last_result);
+          if ((last_instance_class_id_or_function.raw() ==
+               instance_class_id_or_function.raw()) &&
+              (last_instance_type_arguments.raw() ==
+               instance_type_arguments.raw()) &&
+              (last_instantiator_type_arguments.raw() ==
+               instantiator_type_arguments.raw()) &&
+              (last_function_type_arguments.raw() ==
+               function_type_arguments.raw()) &&
+              (last_instance_parent_function_type_arguments.raw() ==
+               instance_parent_function_type_arguments.raw()) &&
+              (last_instance_delayed_type_arguments.raw() ==
+               instance_delayed_type_arguments.raw())) {
+            // Some other isolate might have updated the cache between entry was
+            // found missing and now.
+            return;
+          }
+        }
 #endif
-  new_cache.AddCheck(instance_class_id_or_function, instance_type_arguments,
-                     instantiator_type_arguments, function_type_arguments,
-                     instance_parent_function_type_arguments,
-                     instance_delayed_type_arguments, result);
-  if (FLAG_trace_type_checks) {
-    AbstractType& test_type = AbstractType::Handle(zone, type.raw());
-    if (!test_type.IsInstantiated()) {
-      test_type = type.InstantiateFrom(instantiator_type_arguments,
-                                       function_type_arguments, kAllFree, NULL,
-                                       Heap::kNew);
-    }
-    const auto& type_class = Class::Handle(zone, test_type.type_class());
-    const auto& instance_class_name =
-        String::Handle(zone, instance_class.Name());
-    OS::PrintErr(
-        "  Updated test cache %p ix: %" Pd
-        " with "
-        "(cid-or-fun: %p, type-args: %p, i-type-args: %p, f-type-args: %p, "
-        "p-type-args: %p, d-type-args: %p, result: %s)\n"
-        "    instance  [class: (%p '%s' cid: %" Pd
-        "),    type-args: %p %s]\n"
-        "    test-type [class: (%p '%s' cid: %" Pd
-        "), i-type-args: %p %s, f-type-args: %p %s]\n",
-        new_cache.raw(), len, instance_class_id_or_function.raw(),
-        instance_type_arguments.raw(), instantiator_type_arguments.raw(),
-        function_type_arguments.raw(),
-        instance_parent_function_type_arguments.raw(),
-        instance_delayed_type_arguments.raw(), result.ToCString(),
-        instance_class.raw(), instance_class_name.ToCString(),
-        instance_class.id(), instance_type_arguments.raw(),
-        instance_type_arguments.ToCString(), type_class.raw(),
-        String::Handle(zone, type_class.Name()).ToCString(), type_class.id(),
-        instantiator_type_arguments.raw(),
-        instantiator_type_arguments.ToCString(), function_type_arguments.raw(),
-        function_type_arguments.ToCString());
-  }
+        new_cache.AddCheck(instance_class_id_or_function,
+                           instance_type_arguments, instantiator_type_arguments,
+                           function_type_arguments,
+                           instance_parent_function_type_arguments,
+                           instance_delayed_type_arguments, result);
+        if (FLAG_trace_type_checks) {
+          AbstractType& test_type = AbstractType::Handle(zone, type.raw());
+          if (!test_type.IsInstantiated()) {
+            test_type = type.InstantiateFrom(instantiator_type_arguments,
+                                             function_type_arguments, kAllFree,
+                                             NULL, Heap::kNew);
+          }
+          const auto& type_class = Class::Handle(zone, test_type.type_class());
+          const auto& instance_class_name =
+              String::Handle(zone, instance_class.Name());
+          OS::PrintErr(
+              "  Updated test cache %#" Px " ix: %" Pd
+              " with (cid-or-fun:"
+              " %#" Px ", type-args: %#" Px ", i-type-args: %#" Px
+              ", "
+              "f-type-args: %#" Px ", p-type-args: %#" Px
+              ", "
+              "d-type-args: %#" Px
+              ", result: %s)\n"
+              "    instance  [class: (%#" Px " '%s' cid: %" Pd
+              "),    type-args: %#" Px
+              " %s]\n"
+              "    test-type [class: (%#" Px " '%s' cid: %" Pd
+              "), i-type-args: %#" Px " %s, f-type-args: %#" Px " %s]\n",
+              static_cast<uword>(new_cache.raw()), len,
+              static_cast<uword>(instance_class_id_or_function.raw()),
+              static_cast<uword>(instance_type_arguments.raw()),
+              static_cast<uword>(instantiator_type_arguments.raw()),
+              static_cast<uword>(function_type_arguments.raw()),
+              static_cast<uword>(instance_parent_function_type_arguments.raw()),
+              static_cast<uword>(instance_delayed_type_arguments.raw()),
+              result.ToCString(), static_cast<uword>(instance_class.raw()),
+              instance_class_name.ToCString(), instance_class.id(),
+              static_cast<uword>(instance_type_arguments.raw()),
+              instance_type_arguments.ToCString(),
+              static_cast<uword>(type_class.raw()),
+              String::Handle(zone, type_class.Name()).ToCString(),
+              type_class.id(),
+              static_cast<uword>(instantiator_type_arguments.raw()),
+              instantiator_type_arguments.ToCString(),
+              static_cast<uword>(function_type_arguments.raw()),
+              function_type_arguments.ToCString());
+        }
+      },
+      /*use_force_growth=*/true);
 }
 
 // Check that the given instance is an instance of the given type.
@@ -756,7 +781,7 @@
     PrintTypeCheck("InstanceOf", instance, type, instantiator_type_arguments,
                    function_type_arguments, result);
   }
-  UpdateTypeTestCache(zone, instance, type, instantiator_type_arguments,
+  UpdateTypeTestCache(zone, thread, instance, type, instantiator_type_arguments,
                       function_type_arguments, result, cache);
   arguments.SetReturn(result);
 }
@@ -920,18 +945,26 @@
       TypeTestingStubCallPattern tts_pattern(caller_frame->pc());
       const intptr_t stc_pool_idx = tts_pattern.GetSubtypeTestCachePoolIndex();
 
-      // The pool entry must be initialized to `null` when we patch it.
-      ASSERT(pool.ObjectAt(stc_pool_idx) == Object::null());
-      cache = SubtypeTestCache::New();
-      pool.SetObjectAt(stc_pool_idx, cache);
+      thread->isolate_group()->RunWithStoppedMutators(
+          [&]() {
+            // If nobody has updated the pool since the check, we are
+            // updating it now.
+            if (pool.ObjectAt(stc_pool_idx) == Object::null()) {
+              cache = SubtypeTestCache::New();
+              pool.SetObjectAt(stc_pool_idx, cache);
+            }
+          },
+          /*use_force_growth=*/true);
 #else
       UNREACHABLE();
 #endif
     }
 
-    UpdateTypeTestCache(zone, src_instance, dst_type,
-                        instantiator_type_arguments, function_type_arguments,
-                        Bool::True(), cache);
+    if (!cache.IsNull()) {  //  we might have lost the race to set up new cache
+      UpdateTypeTestCache(zone, thread, src_instance, dst_type,
+                          instantiator_type_arguments, function_type_arguments,
+                          Bool::True(), cache);
+    }
   }
 
   arguments.SetReturn(src_instance);
@@ -1078,7 +1111,7 @@
   const Function& target_function =
       Function::Handle(receiver_class.GetInvocationDispatcher(
           target_name, arguments_descriptor,
-          RawFunction::kInvokeFieldDispatcher, FLAG_lazy_dispatchers));
+          FunctionLayout::kInvokeFieldDispatcher, FLAG_lazy_dispatchers));
   ASSERT(!target_function.IsNull() || !FLAG_lazy_dispatchers);
   if (FLAG_trace_ic) {
     OS::PrintErr(
@@ -1091,9 +1124,9 @@
 }
 
 // Handle other invocations (implicit closures, noSuchMethod).
-RawFunction* InlineCacheMissHelper(const Class& receiver_class,
-                                   const Array& args_descriptor,
-                                   const String& target_name) {
+FunctionPtr InlineCacheMissHelper(const Class& receiver_class,
+                                  const Array& args_descriptor,
+                                  const String& target_name) {
   // Handle noSuchMethod for dyn:methodName by getting a noSuchMethod dispatcher
   // (or a call-through getter for methodName).
   if (Function::IsDynamicInvocationForwarderName(target_name)) {
@@ -1108,8 +1141,8 @@
     ArgumentsDescriptor desc(args_descriptor);
     const Function& target_function =
         Function::Handle(receiver_class.GetInvocationDispatcher(
-            target_name, args_descriptor, RawFunction::kNoSuchMethodDispatcher,
-            FLAG_lazy_dispatchers));
+            target_name, args_descriptor,
+            FunctionLayout::kNoSuchMethodDispatcher, FLAG_lazy_dispatchers));
     if (FLAG_trace_ic) {
       OS::PrintErr(
           "NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n",
@@ -1221,9 +1254,9 @@
 }
 
 // Perform the subtype and return constant function based on the result.
-static RawFunction* ComputeTypeCheckTarget(const Instance& receiver,
-                                           const AbstractType& type,
-                                           const ArgumentsDescriptor& desc) {
+static FunctionPtr ComputeTypeCheckTarget(const Instance& receiver,
+                                          const AbstractType& type,
+                                          const ArgumentsDescriptor& desc) {
   const bool result = receiver.IsInstanceOf(type, Object::null_type_arguments(),
                                             Object::null_type_arguments());
   const ObjectStore* store = Isolate::Current()->object_store();
@@ -1234,7 +1267,7 @@
   return target.raw();
 }
 
-static RawFunction* InlineCacheMissHandler(
+static FunctionPtr InlineCacheMissHandler(
     const GrowableArray<const Instance*>& args,  // Checked arguments only.
     const ICData& ic_data,
     intptr_t count = 1) {
@@ -1415,7 +1448,6 @@
   arguments.SetReturn(target);
 }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
 static bool IsSingleTarget(Isolate* isolate,
                            Zone* zone,
                            intptr_t lower_cid,
@@ -1438,101 +1470,6 @@
   }
   return true;
 }
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-// Handle a miss of a single target cache.
-//   Arg1: Receiver.
-//   Arg0: Stub out.
-//   Returns: the ICData used to continue with a polymorphic call.
-DEFINE_RUNTIME_ENTRY(SingleTargetMiss, 2) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  UNREACHABLE();
-#else
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(1));
-
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame->IsDartFrame());
-  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  const Function& caller_function =
-      Function::Handle(zone, caller_frame->LookupDartFunction());
-
-  SingleTargetCache& cache = SingleTargetCache::Handle(zone);
-  cache ^=
-      CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code);
-  Code& old_target_code = Code::Handle(zone, cache.target());
-  Function& old_target = Function::Handle(zone);
-  old_target ^= old_target_code.owner();
-
-  // We lost the original ICData when we patched to the monomorphic case.
-  const String& name = String::Handle(zone, old_target.name());
-  ASSERT(!old_target.HasOptionalParameters());
-  ASSERT(!old_target.IsGeneric());
-  const int kTypeArgsLen = 0;
-  // TODO(dartbug.com/33549): Update this code to use the size of the parameters
-  // when supporting calls to non-static methods with unboxed parameters.
-  const Array& descriptor =
-      Array::Handle(zone, ArgumentsDescriptor::NewBoxed(
-                              kTypeArgsLen, old_target.num_fixed_parameters()));
-  const ICData& ic_data =
-      ICData::Handle(zone, ICData::New(caller_function, name, descriptor,
-                                       DeoptId::kNone, 1, /* args_tested */
-                                       ICData::kInstance));
-
-  // Maybe add the new target.
-  Class& cls = Class::Handle(zone, receiver.clazz());
-  ArgumentsDescriptor args_desc(descriptor);
-  Function& target_function = Function::Handle(
-      zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
-  if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(cls, descriptor, name);
-  }
-  if (target_function.IsNull()) {
-    ASSERT(!FLAG_lazy_dispatchers);
-  } else {
-    ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
-  }
-
-  if (old_target.raw() == target_function.raw()) {
-    intptr_t lower, upper, unchecked_lower, unchecked_upper;
-    if (receiver.GetClassId() < cache.lower_limit()) {
-      lower = receiver.GetClassId();
-      unchecked_lower = receiver.GetClassId();
-      upper = cache.upper_limit();
-      unchecked_upper = cache.lower_limit() - 1;
-    } else {
-      lower = cache.lower_limit();
-      unchecked_lower = cache.upper_limit() + 1;
-      upper = receiver.GetClassId();
-      unchecked_upper = receiver.GetClassId();
-    }
-
-    if (IsSingleTarget(isolate, zone, unchecked_lower, unchecked_upper,
-                       target_function, name)) {
-      cache.set_lower_limit(lower);
-      cache.set_upper_limit(upper);
-      // Return the ICData. The single target stub will jump to continue in the
-      // IC call stub.
-      arguments.SetArgAt(0, StubCode::ICCallThroughCode());
-      arguments.SetReturn(ic_data);
-      return;
-    }
-  }
-
-  // Call site is not single target, switch to call using ICData.
-  const Code& stub = StubCode::ICCallThroughCode();
-  CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data,
-                                     stub);
-
-  // Return the ICData. The single target stub will jump to continue in the
-  // IC call stub.
-  arguments.SetArgAt(0, stub);
-  arguments.SetReturn(ic_data);
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-}
-
-#if defined(DART_PRECOMPILED_RUNTIME)
 
 class SavedUnlinkedCallMapKeyEqualsTraits : public AllStatic {
  public:
@@ -1554,80 +1491,123 @@
                              Isolate* isolate,
                              uword frame_pc,
                              const UnlinkedCall& unlinked_call) {
-  auto object_store = isolate->object_store();
-  if (object_store->saved_unlinked_calls() == Array::null()) {
+  IsolateGroup* isolate_group = isolate->group();
+  if (isolate_group->saved_unlinked_calls() == Array::null()) {
     const auto& initial_map =
         Array::Handle(zone, HashTables::New<UnlinkedCallMap>(16, Heap::kOld));
-    object_store->set_saved_unlinked_calls(initial_map);
+    isolate_group->set_saved_unlinked_calls(initial_map);
   }
 
-  UnlinkedCallMap unlinked_call_map(zone, object_store->saved_unlinked_calls());
+  UnlinkedCallMap unlinked_call_map(zone,
+                                    isolate_group->saved_unlinked_calls());
   const auto& pc = Integer::Handle(Integer::NewFromUint64(frame_pc));
-  const bool was_present = unlinked_call_map.UpdateOrInsert(pc, unlinked_call);
-  // We transition at most once out of UnlinkedCall state.
-  RELEASE_ASSERT(!was_present);
-  object_store->set_saved_unlinked_calls(unlinked_call_map.Release());
+  // Some other isolate might have updated unlinked_call_map[pc] too, but
+  // their update should be identical to ours.
+  UnlinkedCall& new_or_old_value = UnlinkedCall::Handle(
+      zone, UnlinkedCall::RawCast(
+                unlinked_call_map.InsertOrGetValue(pc, unlinked_call)));
+  RELEASE_ASSERT(new_or_old_value.raw() == unlinked_call.raw());
+  isolate_group->set_saved_unlinked_calls(unlinked_call_map.Release());
 }
 
-static RawUnlinkedCall* LoadUnlinkedCall(Zone* zone,
-                                         Isolate* isolate,
-                                         uword pc) {
-  auto object_store = isolate->object_store();
-  ASSERT(object_store->saved_unlinked_calls() != Array::null());
+#if defined(DART_PRECOMPILED_RUNTIME)
+static UnlinkedCallPtr LoadUnlinkedCall(Zone* zone,
+                                        Isolate* isolate,
+                                        uword pc,
+                                        bool is_monomorphic_hit) {
+  IsolateGroup* isolate_group = isolate->group();
+  ASSERT(isolate_group->saved_unlinked_calls() != Array::null());
 
-  UnlinkedCallMap unlinked_call_map(zone, object_store->saved_unlinked_calls());
+  UnlinkedCallMap unlinked_call_map(zone,
+                                    isolate_group->saved_unlinked_calls());
+
   const auto& pc_integer = Integer::Handle(Integer::NewFromUint64(pc));
   const auto& unlinked_call = UnlinkedCall::Cast(
       Object::Handle(zone, unlinked_call_map.GetOrDie(pc_integer)));
-  // Since we transition out of the monomorphic state only once, we should not
-  // need the saved unlinked call anymore.
-  unlinked_call_map.Remove(pc_integer);
-  object_store->set_saved_unlinked_calls(unlinked_call_map.Release());
+  // Only remove entry from unlinked_call_map if we are actually transitioning
+  // out of monomorphic state.
+  if (!is_monomorphic_hit) {
+    unlinked_call_map.Remove(pc_integer);
+    isolate_group->set_saved_unlinked_calls(unlinked_call_map.Release());
+  }
 
   return unlinked_call.raw();
 }
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
+#endif
 
-// Handle the first use of an instance call
-//   Arg2: UnlinkedCall.
-//   Arg1: Receiver.
-//   Arg0: Stub out.
-//   Returns: the ICData used to continue with a polymorphic call.
-DEFINE_RUNTIME_ENTRY(UnlinkedCall, 3) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  UNREACHABLE();
-#else
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(1));
-  const UnlinkedCall& unlinked =
-      UnlinkedCall::CheckedHandle(zone, arguments.ArgAt(2));
+class SwitchableCallHandler {
+ public:
+  SwitchableCallHandler(Thread* thread,
+                        const Instance& receiver,
+                        NativeArguments arguments,
+                        StackFrame* caller_frame,
+                        const Code& caller_code,
+                        const Function& caller_function)
+      : isolate_(thread->isolate()),
+        thread_(thread),
+        zone_(thread->zone()),
+        receiver_(receiver),
+        arguments_(arguments),
+        caller_frame_(caller_frame),
+        caller_code_(caller_code),
+        caller_function_(caller_function) {}
 
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame->IsDartFrame());
-  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  const Function& caller_function =
-      Function::Handle(zone, caller_frame->LookupDartFunction());
+  void HandleMiss(const Object& old_data, const Code& old_target);
 
-  const String& name = String::Handle(zone, unlinked.target_name());
-  const Array& descriptor = Array::Handle(zone, unlinked.args_descriptor());
-  const ICData& ic_data =
-      ICData::Handle(zone, ICData::New(caller_function, name, descriptor,
-                                       DeoptId::kNone, 1, /* args_tested */
-                                       ICData::kInstance));
+ private:
+  FunctionPtr ResolveAndAddReceiverCheck(const String& name,
+                                         const Array& descriptor,
+                                         const ICData& ic_data);
+  void DoUnlinkedCall(const UnlinkedCall& unlinked);
+  bool CanExtendSingleTargetRange(const String& name,
+                                  const Function& old_target,
+                                  const Function& target_function,
+                                  intptr_t* lower,
+                                  intptr_t* upper);
+  void DoMonomorphicMiss(const Object& data);
+  void DoSingleTargetMiss(const SingleTargetCache& data);
+  void DoICDataMiss(const ICData& data);
+  void DoMegamorphicMiss(const MegamorphicCache& data);
 
-  Class& cls = Class::Handle(zone, receiver.clazz());
+  Isolate* isolate_;
+  Thread* thread_;
+  Zone* zone_;
+  const Instance& receiver_;
+  NativeArguments arguments_;
+  StackFrame* caller_frame_;
+  const Code& caller_code_;
+  const Function& caller_function_;
+};
+
+FunctionPtr SwitchableCallHandler::ResolveAndAddReceiverCheck(
+    const String& name,
+    const Array& descriptor,
+    const ICData& ic_data) {
   ArgumentsDescriptor args_desc(descriptor);
+  const Class& cls = Class::Handle(zone_, receiver_.clazz());
   Function& target_function = Function::Handle(
-      zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
+      zone_, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
   if (target_function.IsNull()) {
     target_function = InlineCacheMissHelper(cls, descriptor, name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
   } else {
-    ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+    ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
   }
+  return target_function.raw();
+}
+
+void SwitchableCallHandler::DoUnlinkedCall(const UnlinkedCall& unlinked) {
+  const String& name = String::Handle(zone_, unlinked.target_name());
+  const Array& descriptor = Array::Handle(zone_, unlinked.args_descriptor());
+  const ICData& ic_data =
+      ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
+                                        DeoptId::kNone, 1, /* args_tested */
+                                        ICData::kInstance));
+
+  const Function& target_function = Function::Handle(
+      zone_, ResolveAndAddReceiverCheck(name, descriptor, ic_data));
 
   // In AOT bare mode, the PC -> Code mapping is ambiguous, since multiple code
   // objects can have the same deduped instructions and bare frames are compact
@@ -1643,7 +1623,7 @@
   //
   // If not, we'll save the unlinked call object in a map.
   //
-  // See [MonomorphicMiss]
+  // See [DoMonomorphicMiss]
   const bool need_saved_unlinked_call =
       (FLAG_use_bare_instructions && FLAG_dedup_instructions);
 
@@ -1656,13 +1636,11 @@
   //
   // We assume here that generated code never moves.
   if (need_saved_unlinked_call) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-    SaveUnlinkedCall(zone, isolate, caller_frame->pc(), unlinked);
-#else
-    UNREACHABLE();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
+    SaveUnlinkedCall(zone_, isolate_, caller_frame_->pc(), unlinked);
   }
 
+  Object& object = Object::Handle(zone_, ic_data.raw());
+  Code& code = Code::Handle(zone_, StubCode::ICCallThroughCode().raw());
   // If the target function has optional parameters or is generic, it's
   // prologue requires ARGS_DESC_REG to be populated. Yet the switchable calls
   // do not populate that on the call site, which is why we don't transition
@@ -1675,47 +1653,60 @@
       !target_function.IsGeneric()) {
     // Patch to monomorphic call.
     ASSERT(target_function.HasCode());
-    const Code& target_code = Code::Handle(zone, target_function.CurrentCode());
+    const Code& target_code =
+        Code::Handle(zone_, target_function.CurrentCode());
     const Smi& expected_cid =
-        Smi::Handle(zone, Smi::New(receiver.GetClassId()));
+        Smi::Handle(zone_, Smi::New(receiver_.GetClassId()));
 
     if (unlinked.can_patch_to_monomorphic()) {
-      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
-                                         expected_cid, target_code);
+      object = expected_cid.raw();
+      code = target_code.raw();
     } else {
-      const MonomorphicSmiableCall& call = MonomorphicSmiableCall::Handle(
-          zone, MonomorphicSmiableCall::New(expected_cid.Value(), target_code));
-      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, call,
-                                         StubCode::MonomorphicSmiableCheck());
+      object = MonomorphicSmiableCall::New(expected_cid.Value(), target_code);
+      code = StubCode::MonomorphicSmiableCheck().raw();
     }
-
-    // Return the ICData. The miss stub will jump to continue in the IC call
-    // stub.
-    arguments.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments.SetReturn(ic_data);
-    return;
   }
-
-  // Patch to call through stub.
-  const Code& stub = StubCode::ICCallThroughCode();
-  CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data,
-                                     stub);
+  CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+      thread_, caller_frame_->pc(), caller_code_, object, code);
 
   // Return the ICData. The miss stub will jump to continue in the IC lookup
   // stub.
-  arguments.SetArgAt(0, stub);
-  arguments.SetReturn(ic_data);
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
+  arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
+  arguments_.SetReturn(ic_data);
+}
+
+bool SwitchableCallHandler::CanExtendSingleTargetRange(
+    const String& name,
+    const Function& old_target,
+    const Function& target_function,
+    intptr_t* lower,
+    intptr_t* upper) {
+  if (old_target.raw() != target_function.raw()) {
+    return false;
+  }
+  intptr_t unchecked_lower, unchecked_upper;
+  if (receiver_.GetClassId() < *lower) {
+    unchecked_lower = receiver_.GetClassId();
+    unchecked_upper = *lower - 1;
+    *lower = receiver_.GetClassId();
+  } else {
+    unchecked_upper = receiver_.GetClassId();
+    unchecked_lower = *upper + 1;
+    *upper = receiver_.GetClassId();
+  }
+
+  return IsSingleTarget(isolate_, zone_, unchecked_lower, unchecked_upper,
+                        target_function, name);
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-static RawICData* FindICDataForInstanceCall(Zone* zone,
-                                            const Code& code,
-                                            uword pc) {
+static ICDataPtr FindICDataForInstanceCall(Zone* zone,
+                                           const Code& code,
+                                           uword pc) {
   uword pc_offset = pc - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(zone, code.pc_descriptors());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kIcCall);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kIcCall);
   intptr_t deopt_id = -1;
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
@@ -1728,48 +1719,37 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-// Handle a miss of a megamorphic cache.
-//   Arg1: Receiver.
-//   Arg0: continuation Code (out parameter).
-//   Returns: the ICData used to continue with a polymorphic call.
-DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 2) {
+void SwitchableCallHandler::DoMonomorphicMiss(const Object& data) {
 #if defined(DART_PRECOMPILED_RUNTIME)
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(1));
-
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame->IsDartFrame());
-  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  const Function& caller_function =
-      Function::Handle(zone, caller_frame->LookupDartFunction());
-
-  Object& old_data = Object::Handle(
-      CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code));
   classid_t old_expected_cid;
-  Function& old_target = Function::Handle(zone);
-  if (old_data.IsSmi()) {
-    old_expected_cid = Smi::Cast(old_data).Value();
-  } else if (old_data.IsMonomorphicSmiableCall()) {
-    old_expected_cid = MonomorphicSmiableCall::Cast(old_data).expected_cid();
+  Function& old_target = Function::Handle(zone_);
+  if (data.IsSmi()) {
+    old_expected_cid = Smi::Cast(data).Value();
+  } else if (data.IsMonomorphicSmiableCall()) {
+    old_expected_cid = MonomorphicSmiableCall::Cast(data).expected_cid();
     old_target ^=
-        Code::Handle(zone, MonomorphicSmiableCall::Cast(old_data).target())
+        Code::Handle(zone_, MonomorphicSmiableCall::Cast(data).target())
             .owner();
   } else {
     UNREACHABLE();
   }
 
-  String& name = String::Handle(zone);
-  Array& descriptor = Array::Handle(zone);
+  // The site might have just been updated to monomorphic state with same
+  // exact class id, in which case we are staying in monomorphic state.
+  bool is_monomorphic_hit = old_expected_cid == receiver_.GetClassId();
+
+  String& name = String::Handle(zone_);
+  Array& descriptor = Array::Handle(zone_);
   if (FLAG_use_bare_instructions && FLAG_dedup_instructions) {
-    const auto& unlinked_call = UnlinkedCall::Handle(
-        zone, LoadUnlinkedCall(zone, isolate, caller_frame->pc()));
+    const UnlinkedCall& unlinked_call = UnlinkedCall::Handle(
+        zone_, LoadUnlinkedCall(zone_, isolate_, caller_frame_->pc(),
+                                is_monomorphic_hit));
     name = unlinked_call.target_name();
     descriptor = unlinked_call.args_descriptor();
 
     ArgumentsDescriptor args_desc(descriptor);
-    const auto& old_receiver_class =
-        Class::Handle(zone, isolate->class_table()->At(old_expected_cid));
+    const Class& old_receiver_class =
+        Class::Handle(zone_, isolate_->class_table()->At(old_expected_cid));
     old_target = Resolver::ResolveDynamicForReceiverClass(old_receiver_class,
                                                           name, args_desc);
     if (old_target.IsNull()) {
@@ -1784,8 +1764,8 @@
     // optional parameters, see DEFINE_RUNTIME_ENTRY(UnlinkedCall) above).
     if (old_target.IsNull()) {
       const Code& old_target_code =
-          Code::Handle(zone, CodePatcher::GetSwitchableCallTargetAt(
-                                 caller_frame->pc(), caller_code));
+          Code::Handle(zone_, CodePatcher::GetSwitchableCallTargetAt(
+                                  caller_frame_->pc(), caller_code_));
       old_target ^= old_target_code.owner();
     }
 
@@ -1799,202 +1779,311 @@
   }
 
   const ICData& ic_data =
-      ICData::Handle(zone, ICData::New(caller_function, name, descriptor,
-                                       DeoptId::kNone, 1, /* args_tested */
-                                       ICData::kInstance));
+      ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
+                                        DeoptId::kNone, 1, /* args_tested */
+                                        ICData::kInstance));
 
   // Add the first target.
   if (!old_target.IsNull()) {
     ic_data.AddReceiverCheck(old_expected_cid, old_target);
   }
 
-  // Maybe add the new target.
-  ArgumentsDescriptor args_desc(descriptor);
-  const Class& cls = Class::Handle(zone, receiver.clazz());
-  Function& target_function = Function::Handle(
-      zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
-  if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(cls, descriptor, name);
-  }
-  if (target_function.IsNull()) {
-    ASSERT(!FLAG_lazy_dispatchers);
-  } else {
-    ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+  if (is_monomorphic_hit) {
+    // The site just have been updated to monomorphic state with same
+    // exact class id - do nothing in that case: stub will call through ic data.
+    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
+    arguments_.SetReturn(ic_data);
+    return;
   }
 
-  if (old_target.raw() == target_function.raw()) {
-    intptr_t lower, upper;
-    if (old_expected_cid < receiver.GetClassId()) {
-      lower = old_expected_cid;
-      upper = receiver.GetClassId();
-    } else {
-      lower = receiver.GetClassId();
-      upper = old_expected_cid;
-    }
+  const Function& target_function = Function::Handle(
+      zone_, ResolveAndAddReceiverCheck(name, descriptor, ic_data));
 
-    if (IsSingleTarget(isolate, zone, lower, upper, target_function, name)) {
-      const SingleTargetCache& cache =
-          SingleTargetCache::Handle(SingleTargetCache::New());
-      const Code& code = Code::Handle(target_function.CurrentCode());
-      cache.set_target(code);
-      cache.set_entry_point(code.EntryPoint());
-      cache.set_lower_limit(lower);
-      cache.set_upper_limit(upper);
-      const Code& stub = StubCode::SingleTargetCall();
-      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, cache,
-                                         stub);
-      // Return the ICData. The miss stub will jump to continue in the IC call
-      // stub.
-      arguments.SetArgAt(0, StubCode::ICCallThroughCode());
-      arguments.SetReturn(ic_data);
-      return;
-    }
+  intptr_t lower = old_expected_cid;
+  intptr_t upper = old_expected_cid;
+  if (CanExtendSingleTargetRange(name, old_target, target_function, &lower,
+                                 &upper)) {
+    const SingleTargetCache& cache =
+        SingleTargetCache::Handle(SingleTargetCache::New());
+    const Code& code = Code::Handle(target_function.CurrentCode());
+    cache.set_target(code);
+    cache.set_entry_point(code.EntryPoint());
+    cache.set_lower_limit(lower);
+    cache.set_upper_limit(upper);
+    const Code& stub = StubCode::SingleTargetCall();
+    CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+        thread_, caller_frame_->pc(), caller_code_, cache, stub);
+    // Return the ICData. The miss stub will jump to continue in the IC call
+    // stub.
+    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
+    arguments_.SetReturn(ic_data);
+    return;
   }
 
   // Patch to call through stub.
   const Code& stub = StubCode::ICCallThroughCode();
-  CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, ic_data,
-                                     stub);
+  CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+      thread_, caller_frame_->pc(), caller_code_, ic_data, stub);
 
   // Return the ICData. The miss stub will jump to continue in the IC lookup
   // stub.
-  arguments.SetArgAt(0, stub);
-  arguments.SetReturn(ic_data);
+  arguments_.SetArgAt(0, stub);
+  arguments_.SetReturn(ic_data);
 #else   // JIT
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame->IsDartFrame());
-  ASSERT(!caller_frame->is_interpreted());
-  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  ASSERT(!caller_code.is_optimized());
-
   const ICData& ic_data = ICData::Handle(
-      zone, FindICDataForInstanceCall(zone, caller_code, caller_frame->pc()));
+      zone_,
+      FindICDataForInstanceCall(zone_, caller_code_, caller_frame_->pc()));
   RELEASE_ASSERT(!ic_data.IsNull());
 
   ASSERT(ic_data.NumArgsTested() == 1);
   const Code& stub = ic_data.is_tracking_exactness()
                          ? StubCode::OneArgCheckInlineCacheWithExactnessCheck()
                          : StubCode::OneArgCheckInlineCache();
-  CodePatcher::PatchInstanceCallAt(caller_frame->pc(), caller_code, ic_data,
-                                   stub);
+  CodePatcher::PatchInstanceCallAtWithMutatorsStopped(
+      thread_, caller_frame_->pc(), caller_code_, ic_data, stub);
   if (FLAG_trace_ic) {
     OS::PrintErr("Instance call at %" Px
                  " switching to polymorphic dispatch, %s\n",
-                 caller_frame->pc(), ic_data.ToCString());
+                 caller_frame_->pc(), ic_data.ToCString());
   }
 
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(1));
   // ICData can be shared between unoptimized and optimized code, so beware that
   // the new receiver class may have already been added through the optimized
   // code.
-  if (!ic_data.HasReceiverClassId(receiver.GetClassId())) {
+  if (!ic_data.HasReceiverClassId(receiver_.GetClassId())) {
     GrowableArray<const Instance*> args(1);
-    args.Add(&receiver);
+    args.Add(&receiver_);
     // Don't count during insertion because the IC stub we continue through will
     // do an increment.
     intptr_t count = 0;
     InlineCacheMissHandler(args, ic_data, count);
   }
-  arguments.SetArgAt(0, stub);
-  arguments.SetReturn(ic_data);
+  arguments_.SetArgAt(0, stub);
+  arguments_.SetReturn(ic_data);
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-// Handle a miss of a megamorphic cache.
-//   Arg0: Receiver.
-//   Arg1: ICData or MegamorphicCache.
-//   Arg2: Arguments descriptor array.
-//   Returns: target function to call.
-DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
-  const Array& descriptor = Array::CheckedHandle(zone, arguments.ArgAt(2));
-  String& name = String::Handle(zone);
-  if (ic_data_or_cache.IsICData()) {
-    name = ICData::Cast(ic_data_or_cache).target_name();
-  } else {
-    ASSERT(ic_data_or_cache.IsMegamorphicCache());
-    name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+void SwitchableCallHandler::DoSingleTargetMiss(const SingleTargetCache& data) {
+  const Code& old_target_code = Code::Handle(zone_, data.target());
+  const Function& old_target =
+      Function::Handle(zone_, Function::RawCast(old_target_code.owner()));
+
+  // We lost the original ICData when we patched to the monomorphic case.
+  const String& name = String::Handle(zone_, old_target.name());
+  ASSERT(!old_target.HasOptionalParameters());
+  ASSERT(!old_target.IsGeneric());
+  const int kTypeArgsLen = 0;
+  const Array& descriptor = Array::Handle(
+      zone_, ArgumentsDescriptor::NewBoxed(kTypeArgsLen,
+                                           old_target.num_fixed_parameters()));
+  const ICData& ic_data =
+      ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
+                                        DeoptId::kNone, 1, /* args_tested */
+                                        ICData::kInstance));
+
+  const Function& target_function = Function::Handle(
+      zone_, ResolveAndAddReceiverCheck(name, descriptor, ic_data));
+
+  intptr_t lower = data.lower_limit();
+  intptr_t upper = data.upper_limit();
+  if (CanExtendSingleTargetRange(name, old_target, target_function, &lower,
+                                 &upper)) {
+    data.set_lower_limit(lower);
+    data.set_upper_limit(upper);
+    // Return the ICData. The single target stub will jump to continue in the
+    // IC call stub.
+    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
+    arguments_.SetReturn(ic_data);
+    return;
   }
-  Class& cls = Class::Handle(zone, receiver.clazz());
+
+  // Call site is not single target, switch to call using ICData.
+  const Code& stub = StubCode::ICCallThroughCode();
+  CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+      thread_, caller_frame_->pc(), caller_code_, ic_data, stub);
+
+  // Return the ICData. The single target stub will jump to continue in the
+  // IC call stub.
+  arguments_.SetArgAt(0, stub);
+  arguments_.SetReturn(ic_data);
+}
+
+void SwitchableCallHandler::DoICDataMiss(const ICData& ic_data) {
+  const String& name = String::Handle(zone_, ic_data.target_name());
+  const Class& cls = Class::Handle(zone_, receiver_.clazz());
   ASSERT(!cls.IsNull());
+  const Array& descriptor =
+      Array::CheckedHandle(zone_, ic_data.arguments_descriptor());
   ArgumentsDescriptor args_desc(descriptor);
   if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) {
-    OS::PrintErr("Megamorphic IC miss (%s), class=%s, function<%" Pd ">=%s\n",
-                 ic_data_or_cache.IsICData() ? "icdata" : "cache",
+    OS::PrintErr("ICData miss, class=%s, function<%" Pd ">=%s\n",
                  cls.ToCString(), args_desc.TypeArgsLen(), name.ToCString());
   }
   Function& target_function = Function::Handle(
-      zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
+      zone_, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
   if (target_function.IsNull()) {
     target_function = InlineCacheMissHelper(cls, descriptor, name);
     if (target_function.IsNull()) {
       ASSERT(!FLAG_lazy_dispatchers);
-      arguments.SetReturn(target_function);
+      arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
+      arguments_.SetReturn(ic_data);
       return;
     }
   }
 
-  if (ic_data_or_cache.IsICData()) {
-    const ICData& ic_data = ICData::Cast(ic_data_or_cache);
-    const intptr_t number_of_checks = ic_data.NumberOfChecks();
+  const intptr_t number_of_checks = ic_data.NumberOfChecks();
 
-    if ((number_of_checks == 0) &&
-        (!FLAG_precompiled_mode || ic_data.receiver_cannot_be_smi()) &&
-        !target_function.HasOptionalParameters() &&
-        !target_function.IsGeneric()) {
-      // This call site is unlinked: transition to a monomorphic direct call.
-      // Note we cannot do this if the target has optional parameters because
-      // the monomorphic direct call does not load the arguments descriptor.
-      // We cannot do this if we are still in the middle of precompiling because
-      // the monomorphic case hides a live instance selector from the
-      // treeshaker.
-
-      const Code& target_code =
-          Code::Handle(zone, target_function.EnsureHasCode());
-
-      DartFrameIterator iterator(thread,
-                                 StackFrameIterator::kNoCrossThreadIteration);
-      StackFrame* miss_function_frame = iterator.NextFrame();
-      ASSERT(miss_function_frame->IsDartFrame());
-      StackFrame* caller_frame = iterator.NextFrame();
-      ASSERT(caller_frame->IsDartFrame());
-      const Code& caller_code =
-          Code::Handle(zone, caller_frame->LookupDartCode());
-      const Smi& expected_cid =
-          Smi::Handle(zone, Smi::New(receiver.GetClassId()));
-
-      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
-                                         expected_cid, target_code);
-    } else {
-      ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
-      if (number_of_checks > FLAG_max_polymorphic_checks) {
-        // Switch to megamorphic call.
-        const MegamorphicCache& cache = MegamorphicCache::Handle(
-            zone, MegamorphicCacheTable::Lookup(thread, name, descriptor));
-        DartFrameIterator iterator(thread,
-                                   StackFrameIterator::kNoCrossThreadIteration);
-        StackFrame* miss_function_frame = iterator.NextFrame();
-        ASSERT(miss_function_frame->IsDartFrame());
-        StackFrame* caller_frame = iterator.NextFrame();
-        ASSERT(caller_frame->IsDartFrame());
-        const Code& caller_code =
-            Code::Handle(zone, caller_frame->LookupDartCode());
-        const Code& stub = StubCode::MegamorphicCall();
-
-        CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
-                                           cache, stub);
-      }
-    }
+  if ((number_of_checks == 0) &&
+      (!FLAG_precompiled_mode || ic_data.receiver_cannot_be_smi()) &&
+      !target_function.HasOptionalParameters() &&
+      !target_function.IsGeneric()) {
+    // This call site is unlinked: transition to a monomorphic direct call.
+    // Note we cannot do this if the target has optional parameters because
+    // the monomorphic direct call does not load the arguments descriptor.
+    // We cannot do this if we are still in the middle of precompiling because
+    // the monomorphic case hides a live instance selector from the
+    // treeshaker.
+    const Code& target_code =
+        Code::Handle(zone_, target_function.EnsureHasCode());
+    const Smi& expected_cid =
+        Smi::Handle(zone_, Smi::New(receiver_.GetClassId()));
+    CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+        thread_, caller_frame_->pc(), caller_code_, expected_cid, target_code);
+    arguments_.SetArgAt(0, target_code);
+    arguments_.SetReturn(expected_cid);
   } else {
-    const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
-    // Insert function found into cache and return it.
-    const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id()));
-    cache.Insert(class_id, target_function);
+    // IC entry might have been added while we waited to get into runtime.
+    GrowableArray<intptr_t> class_ids(1);
+    class_ids.Add(receiver_.GetClassId());
+    if (ic_data.FindCheck(class_ids) == -1) {
+      ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
+    }
+    if (number_of_checks > FLAG_max_polymorphic_checks) {
+      // Switch to megamorphic call.
+      const MegamorphicCache& cache = MegamorphicCache::Handle(
+          zone_, MegamorphicCacheTable::Lookup(thread_, name, descriptor));
+      const Code& stub = StubCode::MegamorphicCall();
+
+      CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
+          thread_, caller_frame_->pc(), caller_code_, cache, stub);
+      arguments_.SetArgAt(0, stub);
+      arguments_.SetReturn(cache);
+    } else {
+      arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
+      arguments_.SetReturn(ic_data);
+    }
   }
-  arguments.SetReturn(target_function);
+}
+
+void SwitchableCallHandler::DoMegamorphicMiss(const MegamorphicCache& data) {
+  const String& name = String::Handle(zone_, data.target_name());
+  const Class& cls = Class::Handle(zone_, receiver_.clazz());
+  ASSERT(!cls.IsNull());
+  const Array& descriptor =
+      Array::CheckedHandle(zone_, data.arguments_descriptor());
+  ArgumentsDescriptor args_desc(descriptor);
+  if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) {
+    OS::PrintErr("Megamorphic miss, class=%s, function<%" Pd ">=%s\n",
+                 cls.ToCString(), args_desc.TypeArgsLen(), name.ToCString());
+  }
+  Function& target_function = Function::Handle(
+      zone_, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
+  if (target_function.IsNull()) {
+    target_function = InlineCacheMissHelper(cls, descriptor, name);
+    if (target_function.IsNull()) {
+      ASSERT(!FLAG_lazy_dispatchers);
+      arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
+      arguments_.SetReturn(data);
+      return;
+    }
+  }
+
+  // Insert function found into cache.
+  const Smi& class_id = Smi::Handle(zone_, Smi::New(cls.id()));
+  data.Insert(class_id, target_function);
+  arguments_.SetArgAt(0, StubCode::MegamorphicCall());
+  arguments_.SetReturn(data);
+}
+
+void SwitchableCallHandler::HandleMiss(const Object& old_data,
+                                       const Code& old_code) {
+  switch (old_data.GetClassId()) {
+    case kUnlinkedCallCid:
+      ASSERT(old_code.raw() == StubCode::SwitchableCallMiss().raw());
+      DoUnlinkedCall(UnlinkedCall::Cast(old_data));
+      break;
+    case kMonomorphicSmiableCallCid:
+      ASSERT(old_code.raw() == StubCode::MonomorphicSmiableCheck().raw());
+      FALL_THROUGH;
+#if defined(DART_PRECOMPILED_RUNTIME)
+    case kSmiCid:
+#else  // JIT
+    case kArrayCid:
+      // ICData three-element array: Smi(receiver CID), Smi(count),
+      // Function(target). It is the Array from ICData::entries_.
+#endif
+      DoMonomorphicMiss(old_data);
+      break;
+    case kSingleTargetCacheCid:
+      ASSERT(old_code.raw() == StubCode::SingleTargetCall().raw());
+      DoSingleTargetMiss(SingleTargetCache::Cast(old_data));
+      break;
+    case kICDataCid:
+      ASSERT(old_code.raw() == StubCode::ICCallThroughCode().raw());
+      DoICDataMiss(ICData::Cast(old_data));
+      break;
+    case kMegamorphicCacheCid:
+      ASSERT(old_code.raw() == StubCode::MegamorphicCall().raw());
+      DoMegamorphicMiss(MegamorphicCache::Cast(old_data));
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+// Handle the first use of an instance call
+//   Arg1: Receiver.
+//   Arg0: Stub out.
+//   Returns: the ICData used to continue with the call.
+DEFINE_RUNTIME_ENTRY(SwitchableCallMiss, 2) {
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(1));
+
+  StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames, thread,
+                              StackFrameIterator::kNoCrossThreadIteration);
+  StackFrame* exit_frame = iterator.NextFrame();
+  ASSERT(exit_frame->IsExitFrame());
+  StackFrame* miss_handler_frame = iterator.NextFrame();
+  // This runtime entry can be called either from miss stub or from
+  // switchable_call_miss "dart" stub/function set up in
+  // [MegamorphicCacheTable::InitMissHandler].
+  ASSERT(miss_handler_frame->IsStubFrame() ||
+         miss_handler_frame->IsDartFrame());
+  StackFrame* caller_frame = iterator.NextFrame();
+  ASSERT(caller_frame->IsDartFrame());
+  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
+  const Function& caller_function =
+      Function::Handle(zone, caller_frame->LookupDartFunction());
+
+  Object& old_data = Object::Handle(zone);
+  Code& old_code = Code::Handle(zone);
+  thread->isolate_group()->RunWithStoppedMutators(
+      [&]() {
+#if defined(DART_PRECOMPILED_RUNTIME)
+        old_data = CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(),
+                                                        caller_code);
+#if defined(DEBUG)
+        old_code ^= CodePatcher::GetSwitchableCallTargetAt(caller_frame->pc(),
+                                                           caller_code);
+#endif
+#else
+        old_code ^= CodePatcher::GetInstanceCallAt(caller_frame->pc(),
+                                                   caller_code, &old_data);
+#endif
+        SwitchableCallHandler handler(thread, receiver, arguments, caller_frame,
+                                      caller_code, caller_function);
+        handler.HandleMiss(old_data, old_code);
+      },
+      /*use_force_growth=*/true);
 }
 
 // Handles interpreted interface call cache miss.
@@ -2155,8 +2244,8 @@
   const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(3));
 
   String& orig_function_name = String::Handle(zone);
-  if ((function.kind() == RawFunction::kClosureFunction) ||
-      (function.kind() == RawFunction::kImplicitClosureFunction)) {
+  if ((function.kind() == FunctionLayout::kClosureFunction) ||
+      (function.kind() == FunctionLayout::kImplicitClosureFunction)) {
     // For closure the function name is always 'call'. Replace it with the
     // name of the closurized function so that exception contains more
     // relevant information.
@@ -2520,10 +2609,10 @@
                              StackFrameIterator::kNoCrossThreadIteration);
   StackFrame* frame = iterator.NextFrame();
   ASSERT(frame != NULL);
-  OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd
-               " %s\n",
-               frame->pc(), ic_data.raw(), function.usage_counter(),
-               ic_data.NumberOfChecks(), function.ToFullyQualifiedCString());
+  OS::PrintErr(
+      "IC call @%#" Px ": ICData: %#" Px " cnt:%" Pd " nchecks: %" Pd " %s\n",
+      frame->pc(), static_cast<uword>(ic_data.raw()), function.usage_counter(),
+      ic_data.NumberOfChecks(), function.ToFullyQualifiedCString());
 }
 
 // This is called from interpreter when function usage counter reached
@@ -3077,6 +3166,11 @@
   ThrowIfError(result);
 }
 
+DEFINE_RUNTIME_ENTRY(LateInitializationError, 1) {
+  const Field& field = Field::CheckedHandle(zone, arguments.ArgAt(0));
+  Exceptions::ThrowLateInitializationError(String::Handle(field.name()));
+}
+
 // Print the stop message.
 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) {
   OS::PrintErr("Stop message: %s\n", message);
@@ -3167,27 +3261,20 @@
     true /* is_float */,
     reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan)));
 
-uword RuntimeEntry::InterpretCallEntry() {
-  uword entry = reinterpret_cast<uword>(RuntimeEntry::InterpretCall);
-#if defined(USING_SIMULATOR)
-  entry = Simulator::RedirectExternalReference(entry,
-                                               Simulator::kLeafRuntimeCall, 5);
-#endif
-  return entry;
-}
-
 // Interpret a function call. Should be called only for non-jitted functions.
 // argc indicates the number of arguments, including the type arguments.
 // argv points to the first argument.
 // If argc < 0, arguments are passed at decreasing memory addresses from argv.
-RawObject* RuntimeEntry::InterpretCall(RawFunction* function,
-                                       RawArray* argdesc,
-                                       intptr_t argc,
-                                       RawObject** argv,
-                                       Thread* thread) {
+extern "C" uword /*ObjectPtr*/ InterpretCall(uword /*FunctionPtr*/ function_in,
+                                             uword /*ArrayPtr*/ argdesc_in,
+                                             intptr_t argc,
+                                             ObjectPtr* argv,
+                                             Thread* thread) {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
 #else
+  FunctionPtr function = static_cast<FunctionPtr>(function_in);
+  ArrayPtr argdesc = static_cast<ArrayPtr>(argdesc_in);
   ASSERT(FLAG_enable_interpreter);
   Interpreter* interpreter = Interpreter::Current();
 #if defined(DEBUG)
@@ -3203,13 +3290,13 @@
 #endif
   // Tell MemorySanitizer 'argv' is initialized by generated code.
   if (argc < 0) {
-    MSAN_UNPOISON(argv - argc, -argc * sizeof(RawObject*));
+    MSAN_UNPOISON(argv - argc, -argc * sizeof(ObjectPtr));
   } else {
-    MSAN_UNPOISON(argv, argc * sizeof(RawObject*));
+    MSAN_UNPOISON(argv, argc * sizeof(ObjectPtr));
   }
-  RawObject* result = interpreter->Call(function, argdesc, argc, argv, thread);
+  ObjectPtr result = interpreter->Call(function, argdesc, argc, argv, thread);
   DEBUG_ASSERT(thread->top_exit_frame_info() == exit_fp);
-  if (RawObject::IsErrorClassId(result->GetClassIdMayBeSmi())) {
+  if (IsErrorClassId(result->GetClassIdMayBeSmi())) {
     // Must not leak handles in the caller's zone.
     HANDLESCOPE(thread);
     // Protect the result in a handle before transitioning, which may trigger
@@ -3220,10 +3307,19 @@
     TransitionGeneratedToVM transition(thread);
     Exceptions::PropagateError(error);
   }
-  return result;
+  return static_cast<uword>(result);
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
+uword RuntimeEntry::InterpretCallEntry() {
+  uword entry = reinterpret_cast<uword>(InterpretCall);
+#if defined(USING_SIMULATOR)
+  entry = Simulator::RedirectExternalReference(entry,
+                                               Simulator::kLeafRuntimeCall, 5);
+#endif
+  return entry;
+}
+
 extern "C" void DFLRT_EnterSafepoint(NativeArguments __unusable_) {
   CHECK_STACK_ALIGNMENT;
   Thread* thread = Thread::Current();
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index c29e6e4..639cc8e 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -11,6 +11,7 @@
 #endif
 #include "vm/flags.h"
 #include "vm/heap/safepoint.h"
+#include "vm/log.h"
 #include "vm/native_arguments.h"
 #include "vm/runtime_entry_list.h"
 
@@ -57,11 +58,6 @@
                                intptr_t argument_count) const);
 
   static uword InterpretCallEntry();
-  static RawObject* InterpretCall(RawFunction* function,
-                                  RawArray* argdesc,
-                                  intptr_t argc,
-                                  RawObject** argv,
-                                  Thread* thread);
 
  protected:
   NOT_IN_PRECOMPILED(static void CallInternal(const RuntimeEntry* runtime_entry,
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index 8a38f5d..9502b49 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -7,10 +7,13 @@
 
 #include "vm/runtime_entry.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/simulator.h"
 #include "vm/stub_code.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 #define __ assembler->
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index 83ba08d..129dae3 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -7,10 +7,13 @@
 
 #include "vm/runtime_entry.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/simulator.h"
 #include "vm/stub_code.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 #define __ assembler->
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index cd9c4d6..de86028 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -34,7 +34,6 @@
   V(NoSuchMethodFromCallStub)                                                  \
   V(NoSuchMethodFromPrologue)                                                  \
   V(InvokeNoSuchMethod)                                                        \
-  V(MegamorphicCacheMissHandler)                                               \
   V(OptimizeInvokedFunction)                                                   \
   V(TraceICCall)                                                               \
   V(PatchStaticCall)                                                           \
@@ -54,11 +53,13 @@
   V(UpdateFieldCid)                                                            \
   V(InitInstanceField)                                                         \
   V(InitStaticField)                                                           \
+  V(LateInitializationError)                                                   \
   V(CompileFunction)                                                           \
   V(CompileInterpretedFunction)                                                \
-  V(MonomorphicMiss)                                                           \
-  V(SingleTargetMiss)                                                          \
-  V(UnlinkedCall)
+  V(SwitchableCallMiss)
+
+// Note: Leaf runtime function have C linkage, so they cannot pass C++ struct
+// values like ObjectPtr.
 
 #define LEAF_RUNTIME_ENTRY_LIST(V)                                             \
   V(void, PrintStopMessage, const char*)                                       \
@@ -66,9 +67,9 @@
   V(void, DeoptimizeFillFrame, uword)                                          \
   V(void, StoreBufferBlockProcess, Thread*)                                    \
   V(void, MarkingStackBlockProcess, Thread*)                                   \
-  V(void, RememberCard, RawObject*, RawObject**)                               \
-  V(RawObject*, AddAllocatedObjectToRememberedSet, RawObject* object,          \
-    Thread* thread)                                                            \
+  V(void, RememberCard, uword /*ObjectPtr*/, ObjectPtr*)                       \
+  V(uword /*ObjectPtr*/, AddAllocatedObjectToRememberedSet,                    \
+    uword /*ObjectPtr*/ object, Thread* thread)                                \
   V(double, LibcPow, double, double)                                           \
   V(double, DartModulo, double, double)                                        \
   V(double, LibcFloor, double)                                                 \
@@ -82,12 +83,12 @@
   V(double, LibcAsin, double)                                                  \
   V(double, LibcAtan, double)                                                  \
   V(double, LibcAtan2, double, double)                                         \
-  V(RawBool*, CaseInsensitiveCompareUCS2, RawString*, RawSmi*, RawSmi*,        \
-    RawSmi*)                                                                   \
-  V(RawBool*, CaseInsensitiveCompareUTF16, RawString*, RawSmi*, RawSmi*,       \
-    RawSmi*)                                                                   \
+  V(uword /*BoolPtr*/, CaseInsensitiveCompareUCS2, uword /*StringPtr*/,        \
+    uword /*SmiPtr*/, uword /*SmiPtr*/, uword /*SmiPtr*/)                      \
+  V(uword /*BoolPtr*/, CaseInsensitiveCompareUTF16, uword /*StringPtr*/,       \
+    uword /*SmiPtr*/, uword /*SmiPtr*/, uword /*SmiPtr*/)                      \
   V(void, EnterSafepoint)                                                      \
-  V(void, ExitSafepoint)                                                       \
+  V(void, ExitSafepoint)
 
 }  // namespace dart
 
diff --git a/runtime/vm/runtime_entry_x64.cc b/runtime/vm/runtime_entry_x64.cc
index 0ff88f0..caaa2a4 100644
--- a/runtime/vm/runtime_entry_x64.cc
+++ b/runtime/vm/runtime_entry_x64.cc
@@ -7,8 +7,10 @@
 
 #include "vm/runtime_entry.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/stub_code.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index f722603..ca297b7 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -1,14 +1,15 @@
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/scopes.h"
 
+#include "vm/compiler/backend/slot.h"
 #include "vm/object.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
@@ -333,7 +334,7 @@
   return str.CharAt(0) == ':';
 }
 
-RawLocalVarDescriptors* LocalScope::GetVarDescriptors(
+LocalVarDescriptorsPtr LocalScope::GetVarDescriptors(
     const Function& func,
     ZoneGrowableArray<intptr_t>* context_level_array) {
   LocalVarDescriptorsBuilder vars;
@@ -346,9 +347,9 @@
     ASSERT(func.IsLocalFunction());
     for (int i = 0; i < context_scope.num_variables(); i++) {
       String& name = String::Handle(context_scope.NameAt(i));
-      RawLocalVarDescriptors::VarInfoKind kind;
+      LocalVarDescriptorsLayout::VarInfoKind kind;
       if (!IsFilteredIdentifier(name)) {
-        kind = RawLocalVarDescriptors::kContextVar;
+        kind = LocalVarDescriptorsLayout::kContextVar;
       } else {
         continue;
       }
@@ -385,7 +386,7 @@
         // own context before calling a closure function.
         LocalVarDescriptorsBuilder::VarDesc desc;
         desc.name = &var->name();
-        desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
+        desc.info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
         desc.info.scope_id = 0;
         desc.info.declaration_pos = TokenPosition::kMinSource;
         desc.info.begin_pos = TokenPosition::kMinSource;
@@ -397,12 +398,12 @@
         LocalVarDescriptorsBuilder::VarDesc desc;
         desc.name = &var->name();
         if (var->is_captured()) {
-          desc.info.set_kind(RawLocalVarDescriptors::kContextVar);
+          desc.info.set_kind(LocalVarDescriptorsLayout::kContextVar);
           ASSERT(var->owner() != NULL);
           ASSERT(var->owner()->context_level() >= 0);
           desc.info.scope_id = var->owner()->context_level();
         } else {
-          desc.info.set_kind(RawLocalVarDescriptors::kStackVar);
+          desc.info.set_kind(LocalVarDescriptorsLayout::kStackVar);
           desc.info.scope_id = *scope_id;
         }
         desc.info.set_index(var->index().value());
@@ -574,7 +575,7 @@
   return num_captured;
 }
 
-RawContextScope* LocalScope::PreserveOuterScope(
+ContextScopePtr LocalScope::PreserveOuterScope(
     int current_context_level) const {
   // Since code generation for nested functions is postponed until first
   // invocation, the function level of the closure scope can only be 1.
@@ -690,7 +691,7 @@
   }
 }
 
-RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) {
+ContextScopePtr LocalScope::CreateImplicitClosureScope(const Function& func) {
   static const intptr_t kNumCapturedVars = 1;
 
   // Create a ContextScope with space for kNumCapturedVars descriptors.
@@ -759,7 +760,7 @@
 
     VarDesc desc;
     desc.name = &Symbols::Empty();  // No name.
-    desc.info.set_kind(RawLocalVarDescriptors::kContextLevel);
+    desc.info.set_kind(LocalVarDescriptorsLayout::kContextLevel);
     desc.info.scope_id = 0;
     desc.info.begin_pos = TokenPosition(start_deopt_id);
     desc.info.end_pos = TokenPosition(end_deopt_id);
@@ -770,7 +771,7 @@
   }
 }
 
-RawLocalVarDescriptors* LocalVarDescriptorsBuilder::Done() {
+LocalVarDescriptorsPtr LocalVarDescriptorsBuilder::Done() {
   if (vars_.is_empty()) {
     return Object::empty_var_descriptors().raw();
   }
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index d855c43..6d6166f 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -10,7 +10,6 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 #include "vm/allocation.h"
-#include "vm/compiler/backend/slot.h"
 #include "vm/growable_array.h"
 #include "vm/object.h"
 #include "vm/raw_object.h"
@@ -21,6 +20,7 @@
 
 class CompileType;
 class LocalScope;
+class Slot;
 
 // Indices of [LocalVariable]s are abstract and have little todo with the
 // actual frame layout!
@@ -237,7 +237,7 @@
  public:
   struct VarDesc {
     const String* name;
-    RawLocalVarDescriptors::VarInfo info;
+    LocalVarDescriptorsLayout::VarInfo info;
   };
 
   LocalVarDescriptorsBuilder() : vars_(8) {}
@@ -255,7 +255,7 @@
       ZoneGrowableArray<intptr_t>* context_level_array);
 
   // Finish building LocalVarDescriptor object.
-  RawLocalVarDescriptors* Done();
+  LocalVarDescriptorsPtr Done();
 
  private:
   GrowableArray<VarDesc> vars_;
@@ -462,13 +462,13 @@
 
   // Creates variable info for the scope and all its nested scopes.
   // Must be called after AllocateVariables() has been called.
-  RawLocalVarDescriptors* GetVarDescriptors(
+  LocalVarDescriptorsPtr GetVarDescriptors(
       const Function& func,
       ZoneGrowableArray<intptr_t>* context_level_array);
 
   // Create a ContextScope object describing all captured variables referenced
   // from this scope and belonging to outer scopes.
-  RawContextScope* PreserveOuterScope(int current_context_level) const;
+  ContextScopePtr PreserveOuterScope(int current_context_level) const;
 
   // Mark all local variables that are accessible from this scope up to
   // top_scope (included) as captured unless they are marked as forced to stack.
@@ -482,7 +482,7 @@
 
   // Create a ContextScope object which will capture "this" for an implicit
   // closure object.
-  static RawContextScope* CreateImplicitClosureScope(const Function& func);
+  static ContextScopePtr CreateImplicitClosureScope(const Function& func);
 
  private:
   // Allocate the variable in the current context, possibly updating the current
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 2f451ce..fafe51d 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -172,7 +172,7 @@
   }
 }
 
-RawObject* Service::RequestAssets() {
+ObjectPtr Service::RequestAssets() {
   Thread* T = Thread::Current();
   Object& object = Object::Handle();
   {
@@ -223,11 +223,6 @@
                  param, js->LookupParam(param));
 }
 
-static void PrintIllegalParamError(JSONStream* js, const char* param) {
-  js->PrintError(kInvalidParams, "%s: illegal '%s' parameter: %s", js->method(),
-                 param, js->LookupParam(param));
-}
-
 static void PrintUnrecognizedMethodError(JSONStream* js) {
   js->PrintError(kMethodNotFound, NULL);
 }
@@ -420,7 +415,7 @@
   return class_table->IsValidIndex(cid) && class_table->HasValidClassAt(cid);
 }
 
-static RawClass* GetClassForId(Isolate* isolate, intptr_t cid) {
+static ClassPtr GetClassForId(Isolate* isolate, intptr_t cid) {
   ASSERT(isolate == Isolate::Current());
   ASSERT(isolate != NULL);
   ClassTable* class_table = isolate->class_table();
@@ -851,9 +846,9 @@
   js.PostReply();
 }
 
-RawError* Service::InvokeMethod(Isolate* I,
-                                const Array& msg,
-                                bool parameters_are_dart_objects) {
+ErrorPtr Service::InvokeMethod(Isolate* I,
+                               const Array& msg,
+                               bool parameters_are_dart_objects) {
   Thread* T = Thread::Current();
   ASSERT(I == T->isolate());
   ASSERT(I != NULL);
@@ -962,17 +957,17 @@
   }
 }
 
-RawError* Service::HandleRootMessage(const Array& msg_instance) {
+ErrorPtr Service::HandleRootMessage(const Array& msg_instance) {
   Isolate* isolate = Isolate::Current();
   return InvokeMethod(isolate, msg_instance);
 }
 
-RawError* Service::HandleObjectRootMessage(const Array& msg_instance) {
+ErrorPtr Service::HandleObjectRootMessage(const Array& msg_instance) {
   Isolate* isolate = Isolate::Current();
   return InvokeMethod(isolate, msg_instance, true);
 }
 
-RawError* Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
+ErrorPtr Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
   ASSERT(isolate != NULL);
   const Error& error = Error::Handle(InvokeMethod(isolate, msg));
   return MaybePause(isolate, error);
@@ -1668,9 +1663,9 @@
   }
 }
 
-static RawObject* LookupObjectId(Thread* thread,
-                                 const char* arg,
-                                 ObjectIdRing::LookupResult* kind) {
+static ObjectPtr LookupObjectId(Thread* thread,
+                                const char* arg,
+                                ObjectIdRing::LookupResult* kind) {
   *kind = ObjectIdRing::kValid;
   if (strncmp(arg, "int-", 4) == 0) {
     arg += 4;
@@ -1700,9 +1695,9 @@
   return ring->GetObjectForId(id, kind);
 }
 
-static RawObject* LookupHeapObjectLibraries(Isolate* isolate,
-                                            char** parts,
-                                            int num_parts) {
+static ObjectPtr LookupHeapObjectLibraries(Isolate* isolate,
+                                           char** parts,
+                                           int num_parts) {
   // Library ids look like "libraries/35"
   if (num_parts < 2) {
     return Object::sentinel().raw();
@@ -1766,9 +1761,9 @@
   return Object::sentinel().raw();
 }
 
-static RawObject* LookupHeapObjectClasses(Thread* thread,
-                                          char** parts,
-                                          int num_parts) {
+static ObjectPtr LookupHeapObjectClasses(Thread* thread,
+                                         char** parts,
+                                         int num_parts) {
   // Class ids look like: "classes/17"
   if (num_parts < 2) {
     return Object::sentinel().raw();
@@ -1888,9 +1883,9 @@
   return Object::sentinel().raw();
 }
 
-static RawObject* LookupHeapObjectTypeArguments(Thread* thread,
-                                                char** parts,
-                                                int num_parts) {
+static ObjectPtr LookupHeapObjectTypeArguments(Thread* thread,
+                                               char** parts,
+                                               int num_parts) {
   Isolate* isolate = thread->isolate();
   // TypeArguments ids look like: "typearguments/17"
   if (num_parts < 2) {
@@ -1911,9 +1906,9 @@
   return table.At(id);
 }
 
-static RawObject* LookupHeapObjectCode(Isolate* isolate,
-                                       char** parts,
-                                       int num_parts) {
+static ObjectPtr LookupHeapObjectCode(Isolate* isolate,
+                                      char** parts,
+                                      int num_parts) {
   if (num_parts != 2) {
     return Object::sentinel().raw();
   }
@@ -1963,9 +1958,9 @@
   return Object::sentinel().raw();
 }
 
-static RawObject* LookupHeapObjectMessage(Thread* thread,
-                                          char** parts,
-                                          int num_parts) {
+static ObjectPtr LookupHeapObjectMessage(Thread* thread,
+                                         char** parts,
+                                         int num_parts) {
   if (num_parts != 2) {
     return Object::sentinel().raw();
   }
@@ -1987,9 +1982,9 @@
   }
 }
 
-static RawObject* LookupHeapObject(Thread* thread,
-                                   const char* id_original,
-                                   ObjectIdRing::LookupResult* result) {
+static ObjectPtr LookupHeapObject(Thread* thread,
+                                  const char* id_original,
+                                  ObjectIdRing::LookupResult* result) {
   char* id = thread->zone()->MakeCopyOfString(id_original);
 
   // Parse the id by splitting at each '/'.
@@ -2202,7 +2197,7 @@
             slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2);
         jselement.AddProperty("parentListIndex", element_index);
       } else if (element.IsLinkedHashMap()) {
-        map = static_cast<RawLinkedHashMap*>(path.At(i * 2));
+        map = static_cast<LinkedHashMapPtr>(path.At(i * 2));
         map_data = map.data();
         intptr_t element_index =
             slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2);
@@ -2437,6 +2432,12 @@
       ObjectIdRing::LookupResult lookup_result;
       Object& argument = Object::Handle(
           zone, LookupHeapObject(thread, argument_id, &lookup_result));
+      // Invoke only accepts Instance arguments.
+      if (!(argument.IsInstance() || argument.IsNull()) ||
+          ContainsNonInstance(argument)) {
+        PrintInvalidParamError(js, "argumentIds");
+        return true;
+      }
       if (argument.raw() == Object::sentinel().raw()) {
         if (lookup_result == ObjectIdRing::kCollected) {
           PrintSentinel(js, kCollectedSentinel);
@@ -2869,7 +2870,7 @@
     NULL,
 };
 
-RawExternalTypedData* DecodeKernelBuffer(const char* kernel_buffer_base64) {
+ExternalTypedDataPtr DecodeKernelBuffer(const char* kernel_buffer_base64) {
   intptr_t kernel_length;
   uint8_t* kernel_buffer = DecodeBase64(kernel_buffer_base64, &kernel_length);
   return ExternalTypedData::NewFinalizeWithFree(kernel_buffer, kernel_length);
@@ -3020,7 +3021,7 @@
       : cls_(cls), storage_(storage), limit_(limit), count_(0) {}
 
   virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
-    RawObject* raw_obj = it->Get();
+    ObjectPtr raw_obj = it->Get();
     if (raw_obj->IsPseudoObject()) {
       return kProceed;
     }
@@ -3248,7 +3249,7 @@
       BoolParameter::Parse(stream->LookupParam("pause"), false));
 }
 
-RawError* Service::MaybePause(Isolate* isolate, const Error& error) {
+ErrorPtr Service::MaybePause(Isolate* isolate, const Error& error) {
   // Don't pause twice.
   if (!isolate->IsPaused()) {
     if (isolate->should_pause_post_service_request()) {
@@ -3423,7 +3424,7 @@
   return true;
 }
 
-static RawClass* GetMetricsClass(Thread* thread) {
+static ClassPtr GetMetricsClass(Thread* thread) {
   Zone* zone = thread->zone();
   const Library& prof_lib = Library::Handle(zone, Library::DeveloperLibrary());
   ASSERT(!prof_lib.IsNull());
@@ -4318,6 +4319,17 @@
   return true;
 }
 
+static const MethodParameter* get_isolate_object_store_params[] = {
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
+};
+
+static bool GetIsolateObjectStore(Thread* thread, JSONStream* js) {
+  JSONObject jsobj(js);
+  thread->isolate()->isolate_object_store()->PrintToJSONObject(&jsobj);
+  return true;
+}
+
 static const MethodParameter* get_class_list_params[] = {
     RUNNABLE_ISOLATE_PARAMETER, NULL,
 };
@@ -4608,13 +4620,6 @@
       BoolParameter::Parse(js->LookupParam("isDebuggable"), false);
   if (obj.IsLibrary()) {
     const Library& lib = Library::Cast(obj);
-    if (lib.is_dart_scheme()) {
-      const String& url = String::Handle(lib.url());
-      if (url.StartsWith(Symbols::DartSchemePrivate())) {
-        PrintIllegalParamError(js, "libraryId");
-        return true;
-      }
-    }
     lib.set_debuggable(is_debuggable);
     PrintSuccess(js);
     return true;
@@ -4814,6 +4819,8 @@
     get_instances_params },
   { "getIsolate", GetIsolate,
     get_isolate_params },
+  { "_getIsolateObjectStore", GetIsolateObjectStore,
+    get_isolate_object_store_params },
   { "getIsolateGroup", GetIsolateGroup,
     get_isolate_group_params },
   { "getMemoryUsage", GetMemoryUsage,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index fdf87a4..ffdc290 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -10,11 +10,12 @@
 #include "vm/allocation.h"
 #include "vm/object_id_ring.h"
 #include "vm/os_thread.h"
+#include "vm/tagged_pointer.h"
 
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 30
+#define SERVICE_PROTOCOL_MINOR_VERSION 33
 
 class Array;
 class EmbedderServiceHandler;
@@ -27,8 +28,6 @@
 class JSONStream;
 class JSONObject;
 class Object;
-class RawInstance;
-class RawError;
 class ServiceEvent;
 class String;
 
@@ -90,14 +89,14 @@
 class Service : public AllStatic {
  public:
   // Handles a message which is not directed to an isolate.
-  static RawError* HandleRootMessage(const Array& message);
+  static ErrorPtr HandleRootMessage(const Array& message);
 
   // Handles a message which is not directed to an isolate and also
   // expects the parameter keys and values to be actual dart objects.
-  static RawError* HandleObjectRootMessage(const Array& message);
+  static ErrorPtr HandleObjectRootMessage(const Array& message);
 
   // Handles a message which is directed to a particular isolate.
-  static RawError* HandleIsolateMessage(Isolate* isolate, const Array& message);
+  static ErrorPtr HandleIsolateMessage(Isolate* isolate, const Array& message);
 
   static void HandleEvent(ServiceEvent* event);
 
@@ -176,7 +175,7 @@
   static bool ListenStream(const char* stream_id);
   static void CancelStream(const char* stream_id);
 
-  static RawObject* RequestAssets();
+  static ObjectPtr RequestAssets();
 
   static Dart_ServiceStreamListenCallback stream_listen_callback() {
     return stream_listen_callback_;
@@ -206,9 +205,9 @@
   }
 
  private:
-  static RawError* InvokeMethod(Isolate* isolate,
-                                const Array& message,
-                                bool parameters_are_dart_objects = false);
+  static ErrorPtr InvokeMethod(Isolate* isolate,
+                               const Array& message,
+                               bool parameters_are_dart_objects = false);
 
   static void EmbedderHandleMessage(EmbedderServiceHandler* handler,
                                     JSONStream* js);
@@ -233,7 +232,7 @@
                         const char* kind,
                         JSONStream* event);
 
-  static RawError* MaybePause(Isolate* isolate, const Error& error);
+  static ErrorPtr MaybePause(Isolate* isolate, const Error& error);
 
   static EmbedderServiceHandler* isolate_service_handler_head_;
   static EmbedderServiceHandler* root_service_handler_head_;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index c96ab96..b957bc7 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.30
+# Dart VM Service Protocol 3.33
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.30_ of the Dart VM Service Protocol. This
+This document describes of _version 3.33_ 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.
@@ -27,6 +27,7 @@
 - [IDs and Names](#ids-and-names)
 - [Versioning](#versioning)
 - [Private RPCs, Types, and Properties](#private-rpcs-types-and-properties)
+- [Single Client Mode](#single-client-mode)
 - [Public RPCs](#public-rpcs)
   - [addBreakpoint](#addbreakpoint)
   - [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
@@ -405,6 +406,17 @@
 implementation state and will never be appropriate to add to
 the public api.
 
+## Single Client Mode
+
+The VM service allows for an extended feature set via the Dart Development
+Service (DDS) that forward all core VM service RPCs described in this
+document to the true VM service.
+
+When DDS connects to the VM service, the VM service enters single client
+mode and will no longer accept incoming web socket connections. If DDS
+disconnects from the VM service, the VM service will once again start accepting
+incoming web socket connections.
+
 ## Public RPCs
 
 The following is a list of all public RPCs supported by the Service Protocol.
@@ -698,8 +710,25 @@
 If _isolateId_ refers to an isolate which has exited, then the
 _Collected_ [Sentinel](#sentinel) is returned.
 
+### getClassList
+
+```
+ClassList|Sentinel getClassList(string isolateId)
+```
+
+The _getClassList_ RPC is used to retrieve a _ClassList_ containing all
+classes for an isolate based on the isolate's _isolateId_.
+
+If _isolateId_ refers to an isolate which has exited, then the
+_Collected_ [Sentinel](#sentinel) is returned.
+
+See [ClassList](#classlist).
+
 ### getClientName
 
+_**Note**: This method is deprecated and will be removed in v4.0 of the protocol.
+An equivalent can be found in the Dart Development Service (DDS) protocol._
+
 ```
 ClientName getClientName()
 ```
@@ -1175,6 +1204,9 @@
 
 ### requirePermissionToResume
 
+_**Note**: This method is deprecated and will be removed in v4.0 of the protocol.
+An equivalent can be found in the Dart Development Service (DDS) protocol._
+
 ```
 Success requirePermissionToResume(bool onPauseStart [optional],
                                   bool onPauseReload[optional],
@@ -1208,7 +1240,6 @@
   approval for the current pause event, the isolate will be resumed if at
   least one other client has attempted to [resume](#resume) the isolate.
 
-
 ### resume
 
 ```
@@ -1245,6 +1276,9 @@
 
 ### setClientName
 
+_**Note**: This method is deprecated and will be removed in v4.0 of the protocol.
+An equivalent can be found in the Dart Development Service (DDS) protocol._
+
 ```
 Success setClientName(string name)
 ```
@@ -1690,6 +1724,9 @@
 
 ### ClientName
 
+_**Note**: This class is deprecated and will be removed in v4.0 of the protocol.
+An equivalent can be found in the Dart Development Service (DDS) protocol._
+
 ```
 class ClientName extends Response {
   // The name of the currently connected VM service client.
@@ -2006,7 +2043,6 @@
   // The status (success or failure) related to the event.
   // This is provided for the event kinds:
   //   IsolateReloaded
-  //   IsolateSpawn
   string status [optional];
 
   // LogRecord data.
@@ -2135,18 +2171,18 @@
   Inspect,
 
   // Event from dart:developer.postEvent.
-  Extension
+  Extension,
 
   // Event from dart:developer.log.
-  Logging
+  Logging,
 
-   // Notification that a Service has been registered into the Service Protocol
+  // Notification that a Service has been registered into the Service Protocol
   // from another client.
   ServiceRegistered,
 
   // Notification that a Service has been removed from the Service Protocol
   // from another client.
-  ServiceUnregistered
+  ServiceUnregistered,
 }
 ```
 
@@ -3516,7 +3552,7 @@
 
 ```
 class Timeline extends Response {
-  // A list of timeline events.
+  // A list of timeline events. No order is guarenteed for these events; in particular, these events may be unordered with respect to their timestamps.
   TimelineEvent[] traceEvents;
 
   // The start of the period of time in which traceEvents were collected.
@@ -3727,5 +3763,9 @@
 3.28 | TODO(aam): document changes from 3.28
 3.29 | Add `getClientName`, `setClientName`, `requireResumeApproval`
 3.30 | Updated return types of RPCs which require an `isolateId` to allow for `Sentinel` results if the target isolate has shutdown.
+3.31 | Added single client mode, which allows for the Dart Development Service (DDS) to become the sole client of
+the VM service.
+3.32 | Added `getClassList` RPC and `ClassList` object.
+3.33 | Added deprecation notice for `getClientName`, `setClientName`, `requireResumeApproval`, and `ClientName`. These RPCs are moving to the DDS protocol and will be removed in v4.0 of the VM service protocol.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 4233863..a96fd6e 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -69,8 +69,6 @@
       return "ServiceExtensionAdded";
     case kIsolateReload:
       return "IsolateReload";
-    case kIsolateSpawn:
-      return "IsolateSpawn";
     case kPauseStart:
       return "PauseStart";
     case kPauseExit:
@@ -126,7 +124,6 @@
     case kIsolateExit:
     case kIsolateUpdate:
     case kIsolateReload:
-    case kIsolateSpawn:
     case kServiceExtensionAdded:
       return &Service::isolate_stream;
 
@@ -195,16 +192,6 @@
       jsobj.AddProperty("reloadError", *(reload_error()));
     }
   }
-  if (kind() == kIsolateSpawn) {
-    ASSERT(spawn_token() != NULL);
-    jsobj.AddPropertyStr("spawnToken", *(spawn_token()));
-    if (spawn_error_ == NULL) {
-      jsobj.AddProperty("status", "success");
-    } else {
-      jsobj.AddProperty("status", "failure");
-      jsobj.AddPropertyStr("spawnError", *(spawn_error()));
-    }
-  }
   if (kind() == kServiceExtensionAdded) {
     ASSERT(extension_rpc_ != NULL);
     jsobj.AddProperty("extensionRPC", extension_rpc_->ToCString());
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index c60e1d2..f2aedde 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -30,7 +30,6 @@
     kIsolateExit,            // Isolate has exited
     kIsolateUpdate,          // Isolate identity information has changed
     kIsolateReload,          // Result of a reload request
-    kIsolateSpawn,           // Result of an isolate spawn request
     kServiceExtensionAdded,  // A service extension was registered
 
     kPauseStart,  // --pause-isolates-on-start
@@ -155,24 +154,6 @@
     reload_error_ = error;
   }
 
-  const String* spawn_token() const {
-    ASSERT(kind_ == kIsolateSpawn);
-    return spawn_token_;
-  }
-  void set_spawn_token(const String* error) {
-    ASSERT(kind_ == kIsolateSpawn);
-    spawn_token_ = error;
-  }
-
-  const String* spawn_error() const {
-    ASSERT(kind_ == kIsolateSpawn);
-    return spawn_error_;
-  }
-  void set_spawn_error(const String* error) {
-    ASSERT(kind_ == kIsolateSpawn);
-    spawn_error_ = error;
-  }
-
   bool at_async_jump() const { return at_async_jump_; }
   void set_at_async_jump(bool value) { at_async_jump_ = value; }
 
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 7e084ab..5b2aadfe 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -48,9 +48,9 @@
 
 #define VM_SERVICE_METHOD_CALL_FROM_NATIVE 5
 
-static RawArray* MakeServiceControlMessage(Dart_Port port_id,
-                                           intptr_t code,
-                                           const String& name) {
+static ArrayPtr MakeServiceControlMessage(Dart_Port port_id,
+                                          intptr_t code,
+                                          const String& name) {
   const Array& list = Array::Handle(Array::New(4));
   ASSERT(!list.IsNull());
   const Integer& code_int = Integer::Handle(Integer::New(code));
@@ -63,9 +63,9 @@
   return list.raw();
 }
 
-static RawArray* MakeServerControlMessage(const SendPort& sp,
-                                          intptr_t code,
-                                          bool enable = false) {
+static ArrayPtr MakeServerControlMessage(const SendPort& sp,
+                                         intptr_t code,
+                                         bool enable = false) {
   const Array& list = Array::Handle(Array::New(3));
   ASSERT(!list.IsNull());
   list.SetAt(0, Integer::Handle(Integer::New(code)));
@@ -133,7 +133,7 @@
   return isolate != nullptr && isolate == isolate_;
 }
 
-bool ServiceIsolate::IsServiceIsolateDescendant(const Isolate* isolate) {
+bool ServiceIsolate::IsServiceIsolateDescendant(Isolate* isolate) {
   MonitorLocker ml(monitor_);
   return isolate->origin_id() == origin_;
 }
@@ -346,7 +346,6 @@
 
     Dart_IsolateFlags api_flags;
     Isolate::FlagsInitialize(&api_flags);
-    api_flags.null_safety = false;
 
     isolate = reinterpret_cast<Isolate*>(
         create_group_callback(ServiceIsolate::kName, ServiceIsolate::kName,
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index a44b4b9..b8dd6b4 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -26,7 +26,7 @@
   static bool Exists();
   static bool IsRunning();
   static bool IsServiceIsolate(const Isolate* isolate);
-  static bool IsServiceIsolateDescendant(const Isolate* isolate);
+  static bool IsServiceIsolateDescendant(Isolate* isolate);
   static Dart_Port Port();
   static void WaitForServiceIsolateStartup();
 
@@ -97,9 +97,7 @@
   static bool Exists() { return false; }
   static bool IsRunning() { return false; }
   static bool IsServiceIsolate(const Isolate* isolate) { return false; }
-  static bool IsServiceIsolateDescendant(const Isolate* isolate) {
-    return false;
-  }
+  static bool IsServiceIsolateDescendant(Isolate* isolate) { return false; }
   static void Run() {}
   static bool SendIsolateStartupMessage() { return false; }
   static bool SendIsolateShutdownMessage() { return false; }
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 47f6060..11fb555 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -77,7 +77,7 @@
   char* _msg;
 };
 
-static RawArray* Eval(Dart_Handle lib, const char* expr) {
+static ArrayPtr Eval(Dart_Handle lib, const char* expr) {
   const String& dummy_isolate_id = String::Handle(String::New("isolateId"));
   Dart_Handle expr_val;
   {
@@ -103,7 +103,7 @@
   return result.raw();
 }
 
-static RawArray* EvalF(Dart_Handle lib, const char* fmt, ...) {
+static ArrayPtr EvalF(Dart_Handle lib, const char* fmt, ...) {
   va_list args;
   va_start(args, fmt);
   intptr_t len = Utils::VSNPrint(NULL, 0, fmt, args);
@@ -118,14 +118,14 @@
   return Eval(lib, buffer);
 }
 
-static RawFunction* GetFunction(const Class& cls, const char* name) {
+static FunctionPtr GetFunction(const Class& cls, const char* name) {
   const Function& result = Function::Handle(
       cls.LookupDynamicFunction(String::Handle(String::New(name))));
   EXPECT(!result.IsNull());
   return result.raw();
 }
 
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
   const Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 64ba0ee..5ceb7e4 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -13,7 +13,6 @@
 
 #include "vm/simulator.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/constants.h"
 #include "vm/cpu.h"
@@ -231,7 +230,7 @@
   uword pc_offset = pc - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.TokenPos();
@@ -481,8 +480,7 @@
             if (Isolate::Current()->heap()->Contains(value)) {
               OS::PrintErr("%s: \n", arg1);
 #if defined(DEBUG)
-              const Object& obj =
-                  Object::Handle(reinterpret_cast<RawObject*>(value));
+              const Object& obj = Object::Handle(static_cast<ObjectPtr>(value));
               obj.Print();
 #endif  // defined(DEBUG)
             } else {
@@ -1395,8 +1393,8 @@
           ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
           arguments.thread_ = reinterpret_cast<Thread*>(get_register(R0));
           arguments.argc_tag_ = get_register(R1);
-          arguments.argv_ = reinterpret_cast<RawObject**>(get_register(R2));
-          arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
+          arguments.argv_ = reinterpret_cast<ObjectPtr*>(get_register(R2));
+          arguments.retval_ = reinterpret_cast<ObjectPtr*>(get_register(R3));
           SimulatorRuntimeCall target =
               reinterpret_cast<SimulatorRuntimeCall>(external);
           target(arguments);
@@ -3647,7 +3645,7 @@
   int32_t code =
       *reinterpret_cast<int32_t*>(fp + kPcMarkerSlotFromFp * kWordSize);
   int32_t pp = (FLAG_precompiled_mode && FLAG_use_bare_instructions)
-                   ? reinterpret_cast<int32_t>(thread->global_object_pool())
+                   ? static_cast<int32_t>(thread->global_object_pool())
                    : *reinterpret_cast<int32_t*>(
                          (code + Code::object_pool_offset() - kHeapObjectTag));
 
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 8f269b2..a682fb7 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -22,7 +22,6 @@
 
 class Isolate;
 class Mutex;
-class RawObject;
 class SimulatorSetjmpBuffer;
 class Thread;
 
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index b1fef2f..312c12f 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -13,7 +13,6 @@
 
 #include "vm/simulator.h"
 
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/constants.h"
 #include "vm/native_arguments.h"
@@ -259,7 +258,7 @@
   uword pc_offset = pc - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.TokenPos();
@@ -539,8 +538,7 @@
             if (Isolate::Current()->heap()->Contains(value)) {
               OS::PrintErr("%s: \n", arg1);
 #if defined(DEBUG)
-              const Object& obj =
-                  Object::Handle(reinterpret_cast<RawObject*>(value));
+              const Object& obj = Object::Handle(static_cast<ObjectPtr>(value));
               obj.Print();
 #endif  // defined(DEBUG)
             } else {
@@ -3586,7 +3584,7 @@
   int64_t code =
       *reinterpret_cast<int64_t*>(fp + kPcMarkerSlotFromFp * kWordSize);
   int64_t pp = (FLAG_precompiled_mode && FLAG_use_bare_instructions)
-                   ? reinterpret_cast<int64_t>(thread->global_object_pool())
+                   ? static_cast<int64_t>(thread->global_object_pool())
                    : *reinterpret_cast<int64_t*>(
                          code + Code::object_pool_offset() - kHeapObjectTag);
   pp -= kHeapObjectTag;  // In the PP register, the pool pointer is untagged.
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h
index 6663e32..3d00d23 100644
--- a/runtime/vm/simulator_arm64.h
+++ b/runtime/vm/simulator_arm64.h
@@ -22,7 +22,6 @@
 
 class Isolate;
 class Mutex;
-class RawObject;
 class SimulatorSetjmpBuffer;
 class Thread;
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 8968b17..1faa561 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -34,7 +34,7 @@
   // Check if this is a singleton object class which is shared by all isolates.
   return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) ||
           (class_id == kTypeArgumentsCid) ||
-          (class_id >= kNullCid && class_id <= kNeverCid));
+          (class_id >= kNullCid && class_id <= kVoidCid));
 }
 
 static bool IsBootstrapedClassId(intptr_t class_id) {
@@ -42,11 +42,10 @@
   return (class_id == kObjectCid ||
           (class_id >= kInstanceCid && class_id <= kUserTagCid) ||
           class_id == kArrayCid || class_id == kImmutableArrayCid ||
-          RawObject::IsStringClassId(class_id) ||
-          RawObject::IsTypedDataClassId(class_id) ||
-          RawObject::IsExternalTypedDataClassId(class_id) ||
-          RawObject::IsTypedDataViewClassId(class_id) || class_id == kNullCid ||
-          class_id == kTransferableTypedDataCid);
+          IsStringClassId(class_id) || IsTypedDataClassId(class_id) ||
+          IsExternalTypedDataClassId(class_id) ||
+          IsTypedDataViewClassId(class_id) || class_id == kNullCid ||
+          class_id == kNeverCid || class_id == kTransferableTypedDataCid);
 }
 
 static bool IsObjectStoreTypeId(intptr_t index) {
@@ -62,7 +61,7 @@
   // later inline with complete contents.
   return class_id >= kNumPredefinedCids || class_id == kArrayCid ||
          class_id == kImmutableArrayCid || class_id == kObjectPoolCid ||
-         RawObject::IsImplicitFieldClassId(class_id);
+         IsImplicitFieldClassId(class_id);
 }
 
 static intptr_t ClassIdFromObjectId(intptr_t object_id) {
@@ -76,7 +75,7 @@
   return (class_id + kClassIdsOffset);
 }
 
-static RawObject* GetType(ObjectStore* object_store, intptr_t index) {
+static ObjectPtr GetType(ObjectStore* object_store, intptr_t index) {
   switch (index) {
     case kLegacyObjectType:
       return object_store->legacy_object_type();
@@ -84,6 +83,8 @@
       return object_store->nullable_object_type();
     case kNullType:
       return object_store->null_type();
+    case kNeverType:
+      return object_store->never_type();
     case kLegacyFunctionType:
       return object_store->legacy_function_type();
     case kLegacyNumberType:
@@ -151,11 +152,13 @@
 }
 
 static intptr_t GetTypeIndex(ObjectStore* object_store,
-                             const RawObject* raw_type) {
+                             const ObjectPtr raw_type) {
   if (raw_type == object_store->legacy_object_type()) {
     return kLegacyObjectType;
   } else if (raw_type == object_store->null_type()) {
     return kNullType;
+  } else if (raw_type == object_store->never_type()) {
+    return kNeverType;
   } else if (raw_type == object_store->legacy_function_type()) {
     return kLegacyFunctionType;
   } else if (raw_type == object_store->legacy_number_type()) {
@@ -255,9 +258,9 @@
   return snapshot;
 }
 
-RawSmi* BaseReader::ReadAsSmi() {
-  RawSmi* value = Read<RawSmi*>();
-  ASSERT((reinterpret_cast<uword>(value) & kSmiTagMask) == kSmiTag);
+SmiPtr BaseReader::ReadAsSmi() {
+  SmiPtr value = static_cast<SmiPtr>(Read<intptr_t>());
+  ASSERT((static_cast<uword>(value) & kSmiTagMask) == kSmiTag);
   return value;
 }
 
@@ -306,7 +309,7 @@
       types_to_postprocess_(GrowableObjectArray::Handle(zone_)),
       objects_to_rehash_(GrowableObjectArray::Handle(zone_)) {}
 
-RawObject* SnapshotReader::ReadObject() {
+ObjectPtr SnapshotReader::ReadObject() {
   // Setup for long jump in case there is an exception while reading.
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
@@ -362,7 +365,7 @@
   objects_to_rehash_.Add(map);
 }
 
-RawObject* SnapshotReader::RunDelayedRehashingOfMaps() {
+ObjectPtr SnapshotReader::RunDelayedRehashingOfMaps() {
   if (objects_to_rehash_.Length() > 0) {
     const Library& collections_lib =
         Library::Handle(zone_, Library::CollectionLibrary());
@@ -379,7 +382,7 @@
   return Object::null();
 }
 
-RawClass* SnapshotReader::ReadClassId(intptr_t object_id) {
+ClassPtr SnapshotReader::ReadClassId(intptr_t object_id) {
   ASSERT(!Snapshot::IsFull(kind_));
   // Read the class header information and lookup the class.
   intptr_t class_header = Read<int32_t>();
@@ -411,8 +414,8 @@
   return cls.raw();
 }
 
-RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
-                                                     intptr_t class_header) {
+ObjectPtr SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
+                                                    intptr_t class_header) {
   ASSERT(!Snapshot::IsFull(kind_));
 
   // First create a function object and associate it with the specified
@@ -479,7 +482,7 @@
   thread()->long_jump_base()->Jump(1, error);
 }
 
-RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
+ObjectPtr SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
   return Object::vm_isolate_snapshot_object_table().At(index);
 }
 
@@ -487,7 +490,7 @@
   return isolate() == Dart::vm_isolate();
 }
 
-RawObject* SnapshotReader::ReadObjectImpl(bool as_reference) {
+ObjectPtr SnapshotReader::ReadObjectImpl(bool as_reference) {
   int64_t header_value = Read<int64_t>();
   if ((header_value & kSmiTagMask) == kSmiTag) {
     return NewInteger(header_value);
@@ -496,8 +499,8 @@
   return ReadObjectImpl(static_cast<intptr_t>(header_value), as_reference);
 }
 
-RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value,
-                                          bool as_reference) {
+ObjectPtr SnapshotReader::ReadObjectImpl(intptr_t header_value,
+                                         bool as_reference) {
   if (IsVMIsolateObject(header_value)) {
     return ReadVMIsolateObject(header_value);
   }
@@ -513,7 +516,7 @@
   // Read the class header information.
   intptr_t class_header = Read<int32_t>();
   intptr_t tags = ReadTags();
-  bool read_as_reference = as_reference && !RawObject::IsCanonical(tags);
+  bool read_as_reference = as_reference && !ObjectLayout::IsCanonical(tags);
   intptr_t header_id = SerializedHeaderData::decode(class_header);
   if (header_id == kInstanceObjectId) {
     return ReadInstance(object_id, tags, read_as_reference);
@@ -537,7 +540,7 @@
 #define SNAPSHOT_READ(clazz) case kTypedData##clazz##Cid:
 
     CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-      tags = RawObject::ClassIdTag::update(class_id, tags);
+      tags = ObjectLayout::ClassIdTag::update(class_id, tags);
       pobj_ =
           TypedData::ReadFrom(this, object_id, tags, kind_, read_as_reference);
       break;
@@ -546,7 +549,7 @@
 #define SNAPSHOT_READ(clazz) case kExternalTypedData##clazz##Cid:
 
     CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-      tags = RawObject::ClassIdTag::update(class_id, tags);
+      tags = ObjectLayout::ClassIdTag::update(class_id, tags);
       pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, true);
       break;
     }
@@ -555,7 +558,7 @@
 
     case kByteDataViewCid:
       CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-        tags = RawObject::ClassIdTag::update(class_id, tags);
+        tags = ObjectLayout::ClassIdTag::update(class_id, tags);
         pobj_ = TypedDataView::ReadFrom(this, object_id, tags, kind_, true);
         break;
       }
@@ -575,9 +578,9 @@
   objects_to_rehash_.Add(set);
 }
 
-RawObject* SnapshotReader::ReadInstance(intptr_t object_id,
-                                        intptr_t tags,
-                                        bool as_reference) {
+ObjectPtr SnapshotReader::ReadInstance(intptr_t object_id,
+                                       intptr_t tags,
+                                       bool as_reference) {
   // Object is regular dart instance.
   intptr_t instance_size = 0;
   Instance* result = NULL;
@@ -616,12 +619,13 @@
     ASSERT(next_field_offset > 0);
     // Instance::NextFieldOffset() returns the offset of the first field in
     // a Dart object.
-    bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
+    bool read_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
     intptr_t offset = Instance::NextFieldOffset();
     intptr_t result_cid = result->GetClassId();
 
     const auto unboxed_fields =
-        isolate()->group()->class_table()->GetUnboxedFieldsMapAt(result_cid);
+        isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
+            result_cid);
 
     while (offset < next_field_offset) {
       if (unboxed_fields.Get(offset / kWordSize)) {
@@ -651,7 +655,7 @@
       }
       offset += kWordSize;
     }
-    if (RawObject::IsCanonical(tags)) {
+    if (ObjectLayout::IsCanonical(tags)) {
       const char* error_str = NULL;
       *result = result->CheckAndCanonicalize(thread(), &error_str);
       if (error_str != NULL) {
@@ -685,19 +689,7 @@
   return NULL;
 }
 
-class HeapLocker : public StackResource {
- public:
-  HeapLocker(Thread* thread, PageSpace* page_space)
-      : StackResource(thread), page_space_(page_space) {
-    page_space_->AcquireDataLock();
-  }
-  ~HeapLocker() { page_space_->ReleaseDataLock(); }
-
- private:
-  PageSpace* page_space_;
-};
-
-RawApiError* SnapshotReader::VerifyVersionAndFeatures(Isolate* isolate) {
+ApiErrorPtr SnapshotReader::VerifyVersionAndFeatures(Isolate* isolate) {
   // If the version string doesn't match, return an error.
   // Note: New things are allocated only if we're going to return an error.
 
@@ -763,7 +755,7 @@
   return ApiError::null();
 }
 
-RawObject* SnapshotReader::NewInteger(int64_t value) {
+ObjectPtr SnapshotReader::NewInteger(int64_t value) {
   ASSERT((value & kSmiTagMask) == kSmiTag);
   value = value >> kSmiTagShift;
   if (Smi::IsValid(value)) {
@@ -791,7 +783,7 @@
     return obj;                                                                \
   }
 
-RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
+ObjectPtr SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
   intptr_t object_id = GetVMIsolateObjectId(header_value);
 
   // First check if it is one of the singleton objects.
@@ -803,7 +795,6 @@
   READ_VM_SINGLETON_OBJ(kZeroArrayObject, Object::zero_array().raw());
   READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type().raw());
   READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type().raw());
-  READ_VM_SINGLETON_OBJ(kNeverType, Object::never_type().raw());
   READ_VM_SINGLETON_OBJ(kEmptyTypeArguments,
                         Object::empty_type_arguments().raw());
   READ_VM_SINGLETON_OBJ(kTrueValue, Bool::True().raw());
@@ -851,7 +842,7 @@
   return Symbols::GetPredefinedSymbol(object_id);  // return VM symbol.
 }
 
-RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) {
+ObjectPtr SnapshotReader::ReadIndexedObject(intptr_t object_id) {
   intptr_t class_id = ClassIdFromObjectId(object_id);
   if (IsBootstrapedClassId(class_id)) {
     return isolate()->class_table()->At(class_id);  // get singleton class.
@@ -875,7 +866,7 @@
   *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject);
   result.SetTypeArguments(*TypeArgumentsHandle());
 
-  bool as_reference = RawObject::IsCanonical(tags) ? false : true;
+  bool as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
   for (intptr_t i = 0; i < len; i++) {
     *PassiveObjectHandle() = ReadObjectImpl(as_reference);
     result.SetAt(i, *PassiveObjectHandle());
@@ -913,16 +904,20 @@
   ASSERT(forward_list_ != NULL);
 }
 
-void SnapshotWriter::WriteObject(RawObject* rawobj) {
+void SnapshotWriter::WriteObject(ObjectPtr rawobj) {
   WriteObjectImpl(rawobj, kAsInlinedObject);
   WriteForwardedObjects();
 }
 
-uint32_t SnapshotWriter::GetObjectTags(RawObject* raw) {
+uint32_t SnapshotWriter::GetObjectTags(ObjectPtr raw) {
   return raw->ptr()->tags_;
 }
 
-uword SnapshotWriter::GetObjectTagsAndHash(RawObject* raw) {
+uint32_t SnapshotWriter::GetObjectTags(ObjectLayout* raw) {
+  return raw->tags_;
+}
+
+uword SnapshotWriter::GetObjectTagsAndHash(ObjectPtr raw) {
   uword result = raw->ptr()->tags_;
 #if defined(HASH_IN_OBJECT_HEADER)
   result |= static_cast<uword>(raw->ptr()->hash_) << 32;
@@ -940,8 +935,8 @@
 #define VM_OBJECT_WRITE(clazz)                                                 \
   case clazz::kClassId: {                                                      \
     object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized);       \
-    Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj);               \
-    raw_obj->WriteTo(this, object_id, kind(), false);                          \
+    clazz##Ptr raw_obj = static_cast<clazz##Ptr>(rawobj);                      \
+    raw_obj->ptr()->WriteTo(this, object_id, kind(), false);                   \
     return true;                                                               \
   }
 
@@ -951,7 +946,7 @@
     return true;                                                               \
   }
 
-bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
+bool SnapshotWriter::HandleVMIsolateObject(ObjectPtr rawobj) {
   // Check if it is one of the singleton VM objects.
   WRITE_VM_SINGLETON_OBJ(Object::null(), kNullObject);
   WRITE_VM_SINGLETON_OBJ(Object::sentinel().raw(), kSentinelObject);
@@ -961,7 +956,6 @@
   WRITE_VM_SINGLETON_OBJ(Object::zero_array().raw(), kZeroArrayObject);
   WRITE_VM_SINGLETON_OBJ(Object::dynamic_type().raw(), kDynamicType);
   WRITE_VM_SINGLETON_OBJ(Object::void_type().raw(), kVoidType);
-  WRITE_VM_SINGLETON_OBJ(Object::never_type().raw(), kNeverType);
   WRITE_VM_SINGLETON_OBJ(Object::empty_type_arguments().raw(),
                          kEmptyTypeArguments);
   WRITE_VM_SINGLETON_OBJ(Bool::True().raw(), kTrueValue);
@@ -983,7 +977,7 @@
   // all isolates.
   intptr_t id = rawobj->GetClassId();
   if (id == kClassCid) {
-    RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
+    ClassPtr raw_class = static_cast<ClassPtr>(rawobj);
     intptr_t class_id = raw_class->ptr()->id_;
     if (IsSingletonClassId(class_id)) {
       intptr_t object_id = ObjectIdFromClassId(class_id);
@@ -1017,7 +1011,7 @@
     return true;
   } else {
     // We do this check down here, because it's quite expensive.
-    if (!rawobj->InVMIsolateHeap()) {
+    if (!rawobj->ptr()->InVMIsolateHeap()) {
       return false;
     }
 
@@ -1025,8 +1019,8 @@
       VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
       case kTypedDataUint32ArrayCid: {
         object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized);
-        RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj);
-        raw_obj->WriteTo(this, object_id, kind(), false);
+        TypedDataPtr raw_obj = static_cast<TypedDataPtr>(rawobj);
+        raw_obj->ptr()->WriteTo(this, object_id, kind(), false);
         return true;
       }
       default:
@@ -1058,7 +1052,7 @@
 }
 
 intptr_t ForwardList::AddObject(Zone* zone,
-                                RawObject* raw,
+                                ObjectPtr raw,
                                 SerializeState state) {
   NoSafepointScope no_safepoint;
   intptr_t object_id = next_object_id();
@@ -1072,14 +1066,14 @@
   return object_id;
 }
 
-intptr_t ForwardList::FindObject(RawObject* raw) {
+intptr_t ForwardList::FindObject(ObjectPtr raw) {
   NoSafepointScope no_safepoint;
   intptr_t id = GetObjectId(raw);
   ASSERT(id == 0 || NodeForObjectId(id)->obj()->raw() == raw);
   return (id == 0) ? static_cast<intptr_t>(kInvalidIndex) : id;
 }
 
-void ForwardList::SetObjectId(RawObject* object, intptr_t id) {
+void ForwardList::SetObjectId(ObjectPtr object, intptr_t id) {
   if (object->IsNewObject()) {
     isolate()->forward_table_new()->SetValueExclusive(object, id);
   } else {
@@ -1087,7 +1081,7 @@
   }
 }
 
-intptr_t ForwardList::GetObjectId(RawObject* object) {
+intptr_t ForwardList::GetObjectId(ObjectPtr object) {
   if (object->IsNewObject()) {
     return isolate()->forward_table_new()->GetValueExclusive(object);
   } else {
@@ -1095,7 +1089,7 @@
   }
 }
 
-bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) {
+bool SnapshotWriter::CheckAndWritePredefinedObject(ObjectPtr rawobj) {
   // Check if object can be written in one of the following ways:
   // - Smi: the Smi value is written as is (last bit is not tagged).
   // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3)
@@ -1105,7 +1099,7 @@
 
   // First check if it is a Smi (i.e not a heap object).
   if (!rawobj->IsHeapObject()) {
-    Write<int64_t>(reinterpret_cast<intptr_t>(rawobj));
+    Write<int64_t>(static_cast<intptr_t>(rawobj));
     return true;
   }
 
@@ -1113,7 +1107,7 @@
 
   if ((kind_ == Snapshot::kMessage) && (cid == kDoubleCid)) {
     WriteVMIsolateObject(kDoubleObject);
-    RawDouble* rd = reinterpret_cast<RawDouble*>(rawobj);
+    DoublePtr rd = static_cast<DoublePtr>(rawobj);
     WriteDouble(rd->ptr()->value_);
     return true;
   }
@@ -1143,7 +1137,7 @@
   // or a predefined internal VM class in the object store.
   // Check if it is an internal VM class which is in the object store.
   if (cid == kClassCid) {
-    RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
+    ClassPtr raw_class = static_cast<ClassPtr>(rawobj);
     intptr_t class_id = raw_class->ptr()->id_;
     if (IsBootstrapedClassId(class_id)) {
       intptr_t object_id = ObjectIdFromClassId(class_id);
@@ -1162,7 +1156,7 @@
   return false;
 }
 
-void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) {
+void SnapshotWriter::WriteObjectImpl(ObjectPtr raw, bool as_reference) {
   // First check if object can be written as a simple predefined type.
   if (CheckAndWritePredefinedObject(raw)) {
     return;
@@ -1170,7 +1164,7 @@
 
   // When we know that we are dealing with leaf or shallow objects we write
   // these objects inline even when 'as_reference' is true.
-  const bool write_as_reference = as_reference && !raw->IsCanonical();
+  const bool write_as_reference = as_reference && !raw->ptr()->IsCanonical();
   uintptr_t tags = GetObjectTagsAndHash(raw);
 
   // Add object to the forward ref list and mark it so that future references
@@ -1190,24 +1184,23 @@
   WriteMarkedObjectImpl(raw, tags, object_id, write_as_reference);
 }
 
-void SnapshotWriter::WriteMarkedObjectImpl(RawObject* raw,
+void SnapshotWriter::WriteMarkedObjectImpl(ObjectPtr raw,
                                            intptr_t tags,
                                            intptr_t object_id,
                                            bool as_reference) {
   NoSafepointScope no_safepoint;
-  RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
+  ClassPtr cls = class_table_->At(ObjectLayout::ClassIdTag::decode(tags));
   intptr_t class_id = cls->ptr()->id_;
-  ASSERT(class_id == RawObject::ClassIdTag::decode(tags));
-  if (class_id >= kNumPredefinedCids ||
-      RawObject::IsImplicitFieldClassId(class_id)) {
+  ASSERT(class_id == ObjectLayout::ClassIdTag::decode(tags));
+  if (class_id >= kNumPredefinedCids || IsImplicitFieldClassId(class_id)) {
     WriteInstance(raw, cls, tags, object_id, as_reference);
     return;
   }
   switch (class_id) {
 #define SNAPSHOT_WRITE(clazz)                                                  \
   case clazz::kClassId: {                                                      \
-    Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw);                  \
-    raw_obj->WriteTo(this, object_id, kind_, as_reference);                    \
+    clazz##Ptr raw_obj = static_cast<clazz##Ptr>(raw);                         \
+    raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);             \
     return;                                                                    \
   }
 
@@ -1216,17 +1209,16 @@
 #define SNAPSHOT_WRITE(clazz) case kTypedData##clazz##Cid:
 
     CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
-      RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
-      raw_obj->WriteTo(this, object_id, kind_, as_reference);
+      TypedDataPtr raw_obj = static_cast<TypedDataPtr>(raw);
+      raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);
       return;
     }
 #undef SNAPSHOT_WRITE
 #define SNAPSHOT_WRITE(clazz) case kExternalTypedData##clazz##Cid:
 
     CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
-      RawExternalTypedData* raw_obj =
-          reinterpret_cast<RawExternalTypedData*>(raw);
-      raw_obj->WriteTo(this, object_id, kind_, as_reference);
+      ExternalTypedDataPtr raw_obj = static_cast<ExternalTypedDataPtr>(raw);
+      raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);
       return;
     }
 #undef SNAPSHOT_WRITE
@@ -1234,8 +1226,8 @@
 
     case kByteDataViewCid:
       CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
-        auto* raw_obj = reinterpret_cast<RawTypedDataView*>(raw);
-        raw_obj->WriteTo(this, object_id, kind_, as_reference);
+        auto raw_obj = static_cast<TypedDataViewPtr>(raw);
+        raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);
         return;
       }
 #undef SNAPSHOT_WRITE
@@ -1262,10 +1254,10 @@
   explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
       : writer_(writer) {}
 
-  virtual void VisitObject(RawObject* obj) {
+  virtual void VisitObject(ObjectPtr obj) {
     intptr_t object_id = writer_->forward_list_->FindObject(obj);
     ASSERT(object_id != kInvalidIndex);
-    intptr_t tags = MessageWriter::GetObjectTagsAndHash(obj);
+    intptr_t tags = MessageWriter::GetObjectTagsAndHash(ObjectPtr(obj));
     writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject);
   }
 
@@ -1293,7 +1285,7 @@
        ++id) {
     if (!NodeForObjectId(id)->is_serialized()) {
       // Write the object out in the stream.
-      RawObject* raw = NodeForObjectId(id)->obj()->raw();
+      ObjectPtr raw = NodeForObjectId(id)->obj()->raw();
       writer->VisitObject(raw);
 
       // Mark object as serialized.
@@ -1303,20 +1295,20 @@
   first_unprocessed_object_id_ = next_object_id();
 }
 
-void SnapshotWriter::WriteClassId(RawClass* cls) {
+void SnapshotWriter::WriteClassId(ClassLayout* cls) {
   ASSERT(!Snapshot::IsFull(kind_));
-  int class_id = cls->ptr()->id_;
+  int class_id = cls->id_;
   ASSERT(!IsSingletonClassId(class_id) && !IsBootstrapedClassId(class_id));
 
   // Write out the library url and class name.
-  RawLibrary* library = cls->ptr()->library_;
+  LibraryPtr library = cls->library_;
   ASSERT(library != Library::null());
   WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
-  WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
+  WriteObjectImpl(cls->name_, kAsInlinedObject);
 }
 
 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
-                                                RawFunction* func,
+                                                FunctionPtr func,
                                                 intptr_t tags) {
   // Write out the serialization header value for this object.
   WriteInlinedObjectHeader(object_id);
@@ -1328,9 +1320,9 @@
   WriteTags(tags);
 
   // Write out the library url, class name and signature function name.
-  RawClass* cls = GetFunctionOwner(func);
+  ClassPtr cls = GetFunctionOwner(func);
   ASSERT(cls != Class::null());
-  RawLibrary* library = cls->ptr()->library_;
+  LibraryPtr library = cls->ptr()->library_;
   ASSERT(library != Library::null());
   WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
   WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
@@ -1340,9 +1332,9 @@
 void SnapshotWriter::ArrayWriteTo(intptr_t object_id,
                                   intptr_t array_kind,
                                   intptr_t tags,
-                                  RawSmi* length,
-                                  RawTypeArguments* type_arguments,
-                                  RawObject* data[],
+                                  SmiPtr length,
+                                  TypeArgumentsPtr type_arguments,
+                                  ObjectPtr data[],
                                   bool as_reference) {
   if (as_reference) {
     // Write out the serialization header value for this object.
@@ -1353,7 +1345,7 @@
     WriteTags(tags);
 
     // Write out the length field.
-    Write<RawObject*>(length);
+    Write<ObjectPtr>(length);
   } else {
     intptr_t len = Smi::Value(length);
 
@@ -1365,23 +1357,23 @@
     WriteTags(tags);
 
     // Write out the length field.
-    Write<RawObject*>(length);
+    Write<ObjectPtr>(length);
 
     // Write out the type arguments.
     WriteObjectImpl(type_arguments, kAsInlinedObject);
 
     // Write out the individual object ids.
-    bool write_as_reference = RawObject::IsCanonical(tags) ? false : true;
+    bool write_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
     for (intptr_t i = 0; i < len; i++) {
       WriteObjectImpl(data[i], write_as_reference);
     }
   }
 }
 
-RawFunction* SnapshotWriter::IsSerializableClosure(RawClosure* closure) {
+FunctionPtr SnapshotWriter::IsSerializableClosure(ClosurePtr closure) {
   // Extract the function object to check if this closure
   // can be sent in an isolate message.
-  RawFunction* func = closure->ptr()->function_;
+  FunctionPtr func = closure->ptr()->function_;
   // We only allow closure of top level methods or static functions in a
   // class to be sent in isolate messages.
   if (can_send_any_object() &&
@@ -1404,18 +1396,18 @@
   return Function::null();
 }
 
-RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) {
-  RawObject* owner = func->ptr()->owner_;
+ClassPtr SnapshotWriter::GetFunctionOwner(FunctionPtr func) {
+  ObjectPtr owner = func->ptr()->owner_;
   uint32_t tags = GetObjectTags(owner);
-  intptr_t class_id = RawObject::ClassIdTag::decode(tags);
+  intptr_t class_id = ObjectLayout::ClassIdTag::decode(tags);
   if (class_id == kClassCid) {
-    return reinterpret_cast<RawClass*>(owner);
+    return static_cast<ClassPtr>(owner);
   }
   ASSERT(class_id == kPatchClassCid);
-  return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_;
+  return static_cast<PatchClassPtr>(owner)->ptr()->patched_class_;
 }
 
-void SnapshotWriter::CheckForNativeFields(RawClass* cls) {
+void SnapshotWriter::CheckForNativeFields(ClassPtr cls) {
   if (cls->ptr()->num_native_fields_ != 0) {
     // We do not allow objects with native fields in an isolate message.
     HANDLESCOPE(thread());
@@ -1436,12 +1428,12 @@
   thread()->long_jump_base()->Jump(1, Object::snapshot_writer_error());
 }
 
-void SnapshotWriter::WriteInstance(RawObject* raw,
-                                   RawClass* cls,
+void SnapshotWriter::WriteInstance(ObjectPtr raw,
+                                   ClassPtr cls,
                                    intptr_t tags,
                                    intptr_t object_id,
                                    bool as_reference) {
-  // Closure instances are handled by RawClosure::WriteTo().
+  // Closure instances are handled by ClosureLayout::WriteTo().
   ASSERT(!Class::IsClosureClass(cls));
 
   // Check if the instance has native fields and throw an exception if it does.
@@ -1476,13 +1468,13 @@
     WriteObjectImpl(cls, kAsInlinedObject);
 
     const auto unboxed_fields =
-        isolate()->group()->class_table()->GetUnboxedFieldsMapAt(
+        isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
             cls->ptr()->id_);
 
     // Write out all the fields for the object.
     // Instance::NextFieldOffset() returns the offset of the first field in
     // a Dart object.
-    bool write_as_reference = RawObject::IsCanonical(tags) ? false : true;
+    bool write_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
 
     intptr_t offset = Instance::NextFieldOffset();
     while (offset < next_field_offset) {
@@ -1492,7 +1484,7 @@
             reinterpret_cast<uword>(raw->ptr()) + offset);
         WriteWordWith32BitWrites(value);
       } else {
-        RawObject* raw_obj = *reinterpret_cast<RawObject**>(
+        ObjectPtr raw_obj = *reinterpret_cast<ObjectPtr*>(
             reinterpret_cast<uword>(raw->ptr()) + offset);
         WriteObjectImpl(raw_obj, write_as_reference);
       }
@@ -1502,13 +1494,13 @@
   return;
 }
 
-bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) {
+bool SnapshotWriter::AllowObjectsInDartLibrary(LibraryPtr library) {
   return (library == object_store()->collection_library() ||
           library == object_store()->core_library() ||
           library == object_store()->typed_data_library());
 }
 
-intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) {
+intptr_t SnapshotWriter::FindVmSnapshotObject(ObjectPtr rawobj) {
   intptr_t length = Object::vm_isolate_snapshot_object_table().Length();
   for (intptr_t i = 0; i < length; i++) {
     if (Object::vm_isolate_snapshot_object_table().At(i) == rawobj) {
@@ -1522,7 +1514,7 @@
                                     const char* msg) {
   {
     NoSafepointScope no_safepoint;
-    RawError* error = thread()->StealStickyError();
+    ErrorPtr error = thread()->StealStickyError();
     ASSERT(error == Object::snapshot_writer_error().raw());
   }
 
@@ -1552,11 +1544,11 @@
   free(const_cast<char*>(expected_features));
 }
 
-void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) {
+void SnapshotWriterVisitor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
   ASSERT(Utils::IsAligned(first, sizeof(*first)));
   ASSERT(Utils::IsAligned(last, sizeof(*last)));
-  for (RawObject** current = first; current <= last; current++) {
-    RawObject* raw_obj = *current;
+  for (ObjectPtr* current = first; current <= last; current++) {
+    ObjectPtr raw_obj = *current;
     writer_->WriteObjectImpl(raw_obj, as_references_);
   }
 }
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index b890b0b..cb43fc2 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -43,60 +43,6 @@
 class MegamorphicCache;
 class PageSpace;
 class TypedDataView;
-class RawApiError;
-class RawArray;
-class RawCapability;
-class RawClass;
-class RawClosure;
-class RawClosureData;
-class RawCodeSourceMap;
-class RawCompressedStackMaps;
-class RawContext;
-class RawContextScope;
-class RawDouble;
-class RawExceptionHandlers;
-class RawFfiTrampolineData;
-class RawField;
-class RawFloat32x4;
-class RawFloat64x2;
-class RawFunction;
-class RawGrowableObjectArray;
-class RawICData;
-class RawImmutableArray;
-class RawInstructions;
-class RawInt32x4;
-class RawRegExp;
-class RawLanguageError;
-class RawLibrary;
-class RawLibraryPrefix;
-class RawLinkedHashMap;
-class RawLocalVarDescriptors;
-class RawMegamorphicCache;
-class RawMint;
-class RawNamespace;
-class RawObject;
-class RawObjectPool;
-class RawOneByteString;
-class RawPatchClass;
-class RawPcDescriptors;
-class RawReceivePort;
-class RawRedirectionData;
-class RawNativeEntryData;
-class RawScript;
-class RawSignatureData;
-class RawSendPort;
-class RawSmi;
-class RawStackTrace;
-class RawSubtypeTestCache;
-class RawTwoByteString;
-class RawType;
-class RawTypeArguments;
-class RawTypedData;
-class RawTypedDataView;
-class RawTypeParameter;
-class RawTypeRef;
-class RawUnhandledException;
-class RawWeakProperty;
 class String;
 class TypeArguments;
 class TypedData;
@@ -260,7 +206,7 @@
 
   intptr_t PendingBytes() const { return stream_.PendingBytes(); }
 
-  RawSmi* ReadAsSmi();
+  SmiPtr ReadAsSmi();
   intptr_t ReadSmiValue();
 
   // Negative header value indicates VM isolate object id.
@@ -324,7 +270,7 @@
   Snapshot::Kind kind() const { return kind_; }
 
   // Reads an object.
-  RawObject* ReadObject();
+  ObjectPtr ReadObject();
 
   // Add object to backward references.
   void AddBackRef(intptr_t id, Object* obj, DeserializeState state);
@@ -333,9 +279,9 @@
   Object* GetBackRef(intptr_t id);
 
   // Read version number of snapshot and verify.
-  RawApiError* VerifyVersionAndFeatures(Isolate* isolate);
+  ApiErrorPtr VerifyVersionAndFeatures(Isolate* isolate);
 
-  RawObject* NewInteger(int64_t value);
+  ObjectPtr NewInteger(int64_t value);
 
  protected:
   SnapshotReader(const uint8_t* buffer,
@@ -357,24 +303,24 @@
 
   void EnqueueRehashingOfMap(const LinkedHashMap& map);
   void EnqueueRehashingOfSet(const Object& set);
-  RawObject* RunDelayedRehashingOfMaps();
+  ObjectPtr RunDelayedRehashingOfMaps();
 
-  RawClass* ReadClassId(intptr_t object_id);
-  RawObject* ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
+  ClassPtr ReadClassId(intptr_t object_id);
+  ObjectPtr ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
 
   // Implementation to read an object.
-  RawObject* ReadObjectImpl(bool as_reference);
-  RawObject* ReadObjectImpl(intptr_t header, bool as_reference);
+  ObjectPtr ReadObjectImpl(bool as_reference);
+  ObjectPtr ReadObjectImpl(intptr_t header, bool as_reference);
 
   // Read a Dart Instance object.
-  RawObject* ReadInstance(intptr_t object_id, intptr_t tags, bool as_reference);
+  ObjectPtr ReadInstance(intptr_t object_id, intptr_t tags, bool as_reference);
 
   // Read a VM isolate object that was serialized as an Id.
-  RawObject* ReadVMIsolateObject(intptr_t object_id);
+  ObjectPtr ReadVMIsolateObject(intptr_t object_id);
 
   // Read an object that was serialized as an Id (singleton in object store,
   // or an object that was already serialized before).
-  RawObject* ReadIndexedObject(intptr_t object_id);
+  ObjectPtr ReadIndexedObject(intptr_t object_id);
 
   // Decode class id from the header field.
   intptr_t LookupInternalClass(intptr_t class_header);
@@ -388,7 +334,7 @@
 
   void SetReadException(const char* msg);
 
-  RawObject* VmIsolateSnapshotObject(intptr_t index) const;
+  ObjectPtr VmIsolateSnapshotObject(intptr_t index) const;
 
   bool is_vm_isolate() const;
 
@@ -598,10 +544,10 @@
   }
 
   // Returns the id for the added object.
-  intptr_t AddObject(Zone* zone, RawObject* raw, SerializeState state);
+  intptr_t AddObject(Zone* zone, ObjectPtr raw, SerializeState state);
 
   // Returns the id for the object it it exists in the list.
-  intptr_t FindObject(RawObject* raw);
+  intptr_t FindObject(ObjectPtr raw);
 
   // Exhaustively processes all unserialized objects in this list. 'writer' may
   // concurrently add more objects.
@@ -622,8 +568,8 @@
   GrowableArray<Node*> nodes_;
   intptr_t first_unprocessed_object_id_;
 
-  void SetObjectId(RawObject* object, intptr_t id);
-  intptr_t GetObjectId(RawObject* object);
+  void SetObjectId(ObjectPtr object, intptr_t id);
+  intptr_t GetObjectId(ObjectPtr object);
 
   DISALLOW_COPY_AND_ASSIGN(ForwardList);
 };
@@ -647,10 +593,11 @@
   Heap* heap() const { return isolate()->heap(); }
 
   // Serialize an object into the buffer.
-  void WriteObject(RawObject* raw);
+  void WriteObject(ObjectPtr raw);
 
-  static uint32_t GetObjectTags(RawObject* raw);
-  static uword GetObjectTagsAndHash(RawObject* raw);
+  static uint32_t GetObjectTags(ObjectPtr raw);
+  static uint32_t GetObjectTags(ObjectLayout* raw);
+  static uword GetObjectTagsAndHash(ObjectPtr raw);
 
   Exceptions::ExceptionType exception_type() const { return exception_type_; }
   void set_exception_type(Exceptions::ExceptionType type) {
@@ -664,19 +611,19 @@
   // Write a version string for the snapshot.
   void WriteVersionAndFeatures();
 
-  RawFunction* IsSerializableClosure(RawClosure* closure);
+  FunctionPtr IsSerializableClosure(ClosurePtr closure);
 
   void WriteStaticImplicitClosure(intptr_t object_id,
-                                  RawFunction* func,
+                                  FunctionPtr func,
                                   intptr_t tags);
 
  protected:
-  bool CheckAndWritePredefinedObject(RawObject* raw);
-  bool HandleVMIsolateObject(RawObject* raw);
+  bool CheckAndWritePredefinedObject(ObjectPtr raw);
+  bool HandleVMIsolateObject(ObjectPtr raw);
 
-  void WriteClassId(RawClass* cls);
-  void WriteObjectImpl(RawObject* raw, bool as_reference);
-  void WriteMarkedObjectImpl(RawObject* raw,
+  void WriteClassId(ClassLayout* cls);
+  void WriteObjectImpl(ObjectPtr raw, bool as_reference);
+  void WriteMarkedObjectImpl(ObjectPtr raw,
                              intptr_t tags,
                              intptr_t object_id,
                              bool as_reference);
@@ -684,20 +631,20 @@
   void ArrayWriteTo(intptr_t object_id,
                     intptr_t array_kind,
                     intptr_t tags,
-                    RawSmi* length,
-                    RawTypeArguments* type_arguments,
-                    RawObject* data[],
+                    SmiPtr length,
+                    TypeArgumentsPtr type_arguments,
+                    ObjectPtr data[],
                     bool as_reference);
-  RawClass* GetFunctionOwner(RawFunction* func);
-  void CheckForNativeFields(RawClass* cls);
+  ClassPtr GetFunctionOwner(FunctionPtr func);
+  void CheckForNativeFields(ClassPtr cls);
   void SetWriteException(Exceptions::ExceptionType type, const char* msg);
-  void WriteInstance(RawObject* raw,
-                     RawClass* cls,
+  void WriteInstance(ObjectPtr raw,
+                     ClassPtr cls,
                      intptr_t tags,
                      intptr_t object_id,
                      bool as_reference);
-  bool AllowObjectsInDartLibrary(RawLibrary* library);
-  intptr_t FindVmSnapshotObject(RawObject* rawobj);
+  bool AllowObjectsInDartLibrary(LibraryPtr library);
+  intptr_t FindVmSnapshotObject(ObjectPtr rawobj);
 
   ObjectStore* object_store() const { return object_store_; }
 
@@ -711,37 +658,37 @@
   const char* exception_msg_;  // Message associated with exception.
   bool can_send_any_object_;   // True if any Dart instance can be sent.
 
-  friend class RawArray;
-  friend class RawClass;
-  friend class RawClosureData;
-  friend class RawCode;
-  friend class RawContextScope;
-  friend class RawDynamicLibrary;
-  friend class RawExceptionHandlers;
-  friend class RawField;
-  friend class RawFunction;
-  friend class RawGrowableObjectArray;
-  friend class RawImmutableArray;
-  friend class RawInstructions;
-  friend class RawLibrary;
-  friend class RawLinkedHashMap;
-  friend class RawLocalVarDescriptors;
-  friend class RawMirrorReference;
-  friend class RawObjectPool;
-  friend class RawPointer;
-  friend class RawReceivePort;
-  friend class RawRegExp;
-  friend class RawScript;
-  friend class RawStackTrace;
-  friend class RawSubtypeTestCache;
-  friend class RawTransferableTypedData;
-  friend class RawType;
-  friend class RawTypeArguments;
-  friend class RawTypeParameter;
-  friend class RawTypeRef;
-  friend class RawTypedDataView;
-  friend class RawUserTag;
-  friend class RawWeakSerializationReference;
+  friend class ArrayLayout;
+  friend class ClassLayout;
+  friend class ClosureDataLayout;
+  friend class CodeLayout;
+  friend class ContextScopeLayout;
+  friend class DynamicLibraryLayout;
+  friend class ExceptionHandlersLayout;
+  friend class FieldLayout;
+  friend class FunctionLayout;
+  friend class GrowableObjectArrayLayout;
+  friend class ImmutableArrayLayout;
+  friend class InstructionsLayout;
+  friend class LibraryLayout;
+  friend class LinkedHashMapLayout;
+  friend class LocalVarDescriptorsLayout;
+  friend class MirrorReferenceLayout;
+  friend class ObjectPoolLayout;
+  friend class PointerLayout;
+  friend class ReceivePortLayout;
+  friend class RegExpLayout;
+  friend class ScriptLayout;
+  friend class StackTraceLayout;
+  friend class SubtypeTestCacheLayout;
+  friend class TransferableTypedDataLayout;
+  friend class TypeLayout;
+  friend class TypeArgumentsLayout;
+  friend class TypeParameterLayout;
+  friend class TypeRefLayout;
+  friend class TypedDataViewLayout;
+  friend class UserTagLayout;
+  friend class WeakSerializationReferenceLayout;
   friend class SnapshotWriterVisitor;
   friend class WriteInlinedObjectVisitor;
   DISALLOW_COPY_AND_ASSIGN(SnapshotWriter);
@@ -790,7 +737,7 @@
         writer_(writer),
         as_references_(as_references) {}
 
-  virtual void VisitPointers(RawObject** first, RawObject** last);
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last);
 
  private:
   SnapshotWriter* writer_;
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 9e619bd..b0d9974 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -1993,4 +1993,59 @@
   EXPECT(!Dart_IsKernel(buffer, ARRAY_SIZE(buffer)));
 }
 
+VM_UNIT_TEST_CASE(LegacyErasureDetectionInFullSnapshot) {
+  const char* kScriptChars =
+      "class Generic<T> {\n"
+      "  const Generic();\n"
+      "  static const Generic<int> g = const Generic<int>();\n"
+      "  static testMain() => g.runtimeType;\n"
+      "}\n";
+
+  // Start an Isolate, load and execute a script and check if legacy erasure is
+  // required, preventing to write a full snapshot.
+  {
+    TestIsolateScope __test_isolate__;
+
+    // Create a test library and Load up a test script in it.
+    Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+    EXPECT_VALID(lib);
+
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    ASSERT(isolate == __test_isolate__.isolate());
+    TransitionNativeToVM transition(thread);
+    StackZone zone(thread);
+    HandleScope scope(thread);
+
+    Dart_Handle result = Api::CheckAndFinalizePendingClasses(thread);
+    Dart_Handle cls;
+    {
+      TransitionVMToNative to_native(thread);
+      EXPECT_VALID(result);
+
+      // Invoke a function so that the constant is evaluated.
+      cls = Dart_GetClass(TestCase::lib(), NewString("Generic"));
+      result = Dart_Invoke(cls, NewString("testMain"), 0, NULL);
+      EXPECT_VALID(result);
+    }
+    // Verify that legacy erasure is required in strong mode.
+    Type& type = Type::Handle();
+    type ^= Api::UnwrapHandle(cls);  // Dart_GetClass actually returns a Type.
+    const Class& clazz = Class::Handle(type.type_class());
+    const bool required = clazz.RequireLegacyErasureOfConstants(zone.GetZone());
+    EXPECT(required == isolate->null_safety());
+
+    // Verify that snapshot writing succeeds if erasure is not required.
+    if (!required) {
+      // Write snapshot with object content.
+      uint8_t* isolate_snapshot_data_buffer;
+      FullSnapshotWriter writer(
+          Snapshot::kFull, NULL, &isolate_snapshot_data_buffer,
+          &malloc_allocator, NULL, /*image_writer*/ nullptr);
+      writer.WriteFullSnapshot();
+      free(isolate_snapshot_data_buffer);
+    }
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 61505e1..4f5dcec 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -92,14 +92,14 @@
   if (func.ForceOptimize()) return true;
 
   switch (func.kind()) {
-    case RawFunction::kRegularFunction:
-    case RawFunction::kClosureFunction:
-    case RawFunction::kImplicitClosureFunction:
-    case RawFunction::kImplicitStaticGetter:
-    case RawFunction::kFieldInitializer:
-    case RawFunction::kGetterFunction:
-    case RawFunction::kSetterFunction:
-    case RawFunction::kConstructor:
+    case FunctionLayout::kRegularFunction:
+    case FunctionLayout::kClosureFunction:
+    case FunctionLayout::kImplicitClosureFunction:
+    case FunctionLayout::kImplicitStaticGetter:
+    case FunctionLayout::kFieldInitializer:
+    case FunctionLayout::kGetterFunction:
+    case FunctionLayout::kSetterFunction:
+    case FunctionLayout::kConstructor:
       break;
     default:
       return true;
@@ -215,7 +215,7 @@
 
   PcDescriptors::Iterator iter(
       descriptors,
-      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
+      PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall);
   while (iter.MoveNext()) {
     HANDLESCOPE(thread());
     ASSERT(iter.DeoptId() < ic_data_array->length());
@@ -266,7 +266,7 @@
 
   PcDescriptors::Iterator iter(
       descriptors,
-      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
+      PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall);
   while (iter.MoveNext()) {
     HANDLESCOPE(thread());
     ASSERT(iter.DeoptId() < ic_data_array->length());
@@ -360,8 +360,8 @@
     }
   } else {
     const uint8_t kSafepointKind =
-        (RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall |
-         RawPcDescriptors::kRuntimeCall);
+        (PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall |
+         PcDescriptorsLayout::kRuntimeCall);
 
     const PcDescriptors& descriptors =
         PcDescriptors::Handle(zone(), code.pc_descriptors());
@@ -572,7 +572,7 @@
     for (int i = 0; i < functions.Length(); i++) {
       func ^= functions.At(i);
       // Skip getter functions of static const field.
-      if (func.kind() == RawFunction::kImplicitStaticGetter) {
+      if (func.kind() == FunctionLayout::kImplicitStaticGetter) {
         field ^= func.accessor_field();
         if (field.is_const() && field.is_static()) {
           continue;
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index 0187da5..44ae5e1 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -10,7 +10,7 @@
 
 #ifndef PRODUCT
 
-static RawObject* ExecuteScript(const char* script, bool allow_errors = false) {
+static ObjectPtr ExecuteScript(const char* script, bool allow_errors = false) {
   Dart_Handle lib;
   {
     TransitionVMToNative transition(Thread::Current());
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index a795a0c..a073259 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -5,9 +5,8 @@
 #include "vm/stack_frame.h"
 
 #include "platform/memory_sanitizer.h"
-#include "vm/compiler/assembler/assembler.h"
+#include "vm/code_descriptors.h"
 #include "vm/compiler/runtime_api.h"
-#include "vm/deopt_instructions.h"
 #include "vm/heap/become.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
@@ -21,6 +20,10 @@
 #include "vm/stub_code.h"
 #include "vm/visitor.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/deopt_instructions.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DECLARE_FLAG(bool, enable_interpreter);
@@ -103,28 +106,17 @@
 #endif
 }
 
-Isolate* StackFrame::IsolateOfBareInstructionsFrame(bool needed_for_gc) const {
-  Isolate* isolate = Dart::vm_isolate();
-  if (isolate->object_store()->code_order_table() != Object::null()) {
-    auto rct = isolate->reverse_pc_lookup_cache();
-    if (rct->Contains(pc())) return isolate;
+IsolateGroup* StackFrame::IsolateGroupOfBareInstructionsFrame() const {
+  IsolateGroup* isolate_group = Dart::vm_isolate()->group();
+  if (isolate_group->object_store()->code_order_table() != Object::null()) {
+    auto rct = isolate_group->reverse_pc_lookup_cache();
+    if (rct->Contains(pc())) return isolate_group;
   }
 
-  isolate = this->isolate();
-  // The active isolate is null only during GC, in which case it does not matter
-  // which isolate we use for the reverse-pc lookup table, since the metadata
-  // is the same across all isolates.
-  // TODO(dartbug.com/36097): Avoid having the [ReversePcLookupTable]
-  // per-isolate.  Right now we still need it per-isolate for non-GC cases, e.g.
-  // for stack walking code which relies on finding owner functions of code
-  // objects.
-  if (isolate == nullptr) {
-    ASSERT(needed_for_gc);
-    isolate = isolate_group()->isolates_.First();
-  }
-  if (isolate->object_store()->code_order_table() != Object::null()) {
-    auto rct = isolate->reverse_pc_lookup_cache();
-    if (rct->Contains(pc())) return isolate;
+  isolate_group = this->isolate_group();
+  if (isolate_group->object_store()->code_order_table() != Object::null()) {
+    auto rct = isolate_group->reverse_pc_lookup_cache();
+    if (rct->Contains(pc())) return isolate_group;
   }
 
   return nullptr;
@@ -133,9 +125,9 @@
 bool StackFrame::IsBareInstructionsDartFrame() const {
   NoSafepointScope no_safepoint;
 
-  if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/true)) {
+  if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
     Code code;
-    auto rct = isolate->reverse_pc_lookup_cache();
+    auto rct = isolate_group->reverse_pc_lookup_cache();
     code = rct->Lookup(pc(), /*is_return_address=*/true);
 
     auto const cid = code.OwnerClassId();
@@ -148,9 +140,9 @@
 bool StackFrame::IsBareInstructionsStubFrame() const {
   NoSafepointScope no_safepoint;
 
-  if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/true)) {
+  if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
     Code code;
-    auto rct = isolate->reverse_pc_lookup_cache();
+    auto rct = isolate_group->reverse_pc_lookup_cache();
     code = rct->Lookup(pc(), /*is_return_address=*/true);
 
     auto const cid = code.OwnerClassId();
@@ -160,7 +152,7 @@
   return false;
 }
 
-bool StackFrame::IsStubFrame(bool needed_for_gc) const {
+bool StackFrame::IsStubFrame() const {
   if (is_interpreted()) {
     return false;
   }
@@ -176,7 +168,7 @@
   NoSafepointScope no_safepoint;
 #endif
 
-  RawCode* code = GetCodeObject(needed_for_gc);
+  CodePtr code = GetCodeObject();
   ASSERT(code != Object::null());
   auto const cid = Code::OwnerClassIdOf(code);
   ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
@@ -219,12 +211,12 @@
   ASSERT(visitor != NULL);
   // Visit pc marker and saved pool pointer, or, for interpreted frame, code
   // object and function object.
-  RawObject** last_fixed =
-      reinterpret_cast<RawObject**>(fp()) +
+  ObjectPtr* last_fixed =
+      reinterpret_cast<ObjectPtr*>(fp()) +
       (is_interpreted() ? kKBCLastFixedObjectSlotFromFp
                         : runtime_frame_layout.first_object_from_fp);
-  RawObject** first_fixed =
-      reinterpret_cast<RawObject**>(fp()) +
+  ObjectPtr* first_fixed =
+      reinterpret_cast<ObjectPtr*>(fp()) +
       (is_interpreted() ? kKBCFirstObjectSlotFromFp
                         : runtime_frame_layout.last_fixed_object_from_fp);
   if (first_fixed <= last_fixed) {
@@ -238,12 +230,12 @@
 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
   // Visit objects between SP and (FP - callee_save_area).
-  RawObject** first = is_interpreted() ? reinterpret_cast<RawObject**>(fp()) +
-                                             kKBCSavedArgDescSlotFromEntryFp
-                                       : reinterpret_cast<RawObject**>(sp());
-  RawObject** last = is_interpreted() ? reinterpret_cast<RawObject**>(sp())
-                                      : reinterpret_cast<RawObject**>(fp()) +
-                                            kExitLinkSlotFromEntryFp - 1;
+  ObjectPtr* first = is_interpreted() ? reinterpret_cast<ObjectPtr*>(fp()) +
+                                            kKBCSavedArgDescSlotFromEntryFp
+                                      : reinterpret_cast<ObjectPtr*>(sp());
+  ObjectPtr* last = is_interpreted() ? reinterpret_cast<ObjectPtr*>(sp())
+                                     : reinterpret_cast<ObjectPtr*>(fp()) +
+                                           kExitLinkSlotFromEntryFp - 1;
   // There may not be any pointer to visit; in this case, first > last.
   visitor->VisitPointers(first, last);
 }
@@ -259,11 +251,11 @@
   NoSafepointScope no_safepoint;
   Code code;
 
-  if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/true)) {
-    auto const rct = isolate->reverse_pc_lookup_cache();
+  if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
+    auto const rct = isolate_group->reverse_pc_lookup_cache();
     code = rct->Lookup(pc(), /*is_return_address=*/true);
   } else {
-    RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
+    ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
         fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
                                   : runtime_frame_layout.code_from_fp) *
                 kWordSize)));
@@ -302,8 +294,8 @@
       if (is_interpreted()) {
         UNIMPLEMENTED();
       }
-      RawObject** first = reinterpret_cast<RawObject**>(sp());
-      RawObject** last = reinterpret_cast<RawObject**>(
+      ObjectPtr* first = reinterpret_cast<ObjectPtr*>(sp());
+      ObjectPtr* last = reinterpret_cast<ObjectPtr*>(
           fp() + (runtime_frame_layout.first_local_from_fp * kWordSize));
 
       // A stack map is present in the code object, use the stack map to
@@ -341,9 +333,9 @@
       visitor->VisitPointers(first, last);
 
       // Now visit other slots which might be part of the calling convention.
-      first = reinterpret_cast<RawObject**>(
+      first = reinterpret_cast<ObjectPtr*>(
           fp() + ((runtime_frame_layout.first_local_from_fp + 1) * kWordSize));
-      last = reinterpret_cast<RawObject**>(
+      last = reinterpret_cast<ObjectPtr*>(
           fp() + (runtime_frame_layout.first_object_from_fp * kWordSize));
       visitor->VisitPointers(first, last);
       return;
@@ -361,16 +353,16 @@
   // between the first and last included are tagged objects.
   if (is_interpreted()) {
     // Do not visit caller's pc or caller's fp.
-    RawObject** first =
-        reinterpret_cast<RawObject**>(fp()) + kKBCFirstObjectSlotFromFp;
-    RawObject** last =
-        reinterpret_cast<RawObject**>(fp()) + kKBCLastFixedObjectSlotFromFp;
+    ObjectPtr* first =
+        reinterpret_cast<ObjectPtr*>(fp()) + kKBCFirstObjectSlotFromFp;
+    ObjectPtr* last =
+        reinterpret_cast<ObjectPtr*>(fp()) + kKBCLastFixedObjectSlotFromFp;
 
     visitor->VisitPointers(first, last);
   }
-  RawObject** first =
-      reinterpret_cast<RawObject**>(is_interpreted() ? fp() : sp());
-  RawObject** last = reinterpret_cast<RawObject**>(
+  ObjectPtr* first =
+      reinterpret_cast<ObjectPtr*>(is_interpreted() ? fp() : sp());
+  ObjectPtr* last = reinterpret_cast<ObjectPtr*>(
       is_interpreted()
           ? sp()
           : fp() + (runtime_frame_layout.first_object_from_fp * kWordSize));
@@ -378,13 +370,13 @@
   visitor->VisitPointers(first, last);
 }
 
-RawFunction* StackFrame::LookupDartFunction() const {
+FunctionPtr StackFrame::LookupDartFunction() const {
   if (is_interpreted()) {
-    RawObject* result = *(reinterpret_cast<RawFunction**>(
+    ObjectPtr result = *(reinterpret_cast<FunctionPtr*>(
         fp() + kKBCFunctionSlotFromFp * kWordSize));
     ASSERT((result == Object::null()) ||
            (result->GetClassId() == kFunctionCid));
-    return reinterpret_cast<RawFunction*>(result);
+    return static_cast<FunctionPtr>(result);
   }
   const Code& code = Code::Handle(LookupDartCode());
   if (!code.IsNull()) {
@@ -393,7 +385,7 @@
   return Function::null();
 }
 
-RawCode* StackFrame::LookupDartCode() const {
+CodePtr StackFrame::LookupDartCode() const {
 // We add a no gc scope to ensure that the code below does not trigger
 // a GC as we are handling raw object references here. It is possible
 // that the code is called while a GC is in progress, that is ok.
@@ -402,33 +394,33 @@
   // where Thread::Current() is NULL, so we cannot create a NoSafepointScope.
   NoSafepointScope no_safepoint;
 #endif
-  if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/false)) {
-    auto const rct = isolate->reverse_pc_lookup_cache();
+  if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
+    auto const rct = isolate_group->reverse_pc_lookup_cache();
     return rct->Lookup(pc(), /*is_return_address=*/true);
   }
 
-  RawCode* code = GetCodeObject();
+  CodePtr code = GetCodeObject();
   if ((code != Code::null()) && Code::OwnerClassIdOf(code) == kFunctionCid) {
     return code;
   }
   return Code::null();
 }
 
-RawCode* StackFrame::GetCodeObject(bool needed_for_gc) const {
+CodePtr StackFrame::GetCodeObject() const {
   ASSERT(!is_interpreted());
-  if (auto isolate = IsolateOfBareInstructionsFrame(needed_for_gc)) {
-    auto const rct = isolate->reverse_pc_lookup_cache();
+  if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
+    auto const rct = isolate_group->reverse_pc_lookup_cache();
     return rct->Lookup(pc(), /*is_return_address=*/true);
   } else {
-    RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
+    ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
         fp() + runtime_frame_layout.code_from_fp * kWordSize));
     ASSERT((pc_marker == Object::null()) ||
            (pc_marker->GetClassId() == kCodeCid));
-    return reinterpret_cast<RawCode*>(pc_marker);
+    return static_cast<CodePtr>(pc_marker);
   }
 }
 
-RawBytecode* StackFrame::LookupDartBytecode() const {
+BytecodePtr StackFrame::LookupDartBytecode() const {
 // We add a no gc scope to ensure that the code below does not trigger
 // a GC as we are handling raw object references here. It is possible
 // that the code is called while a GC is in progress, that is ok.
@@ -440,13 +432,13 @@
   return GetBytecodeObject();
 }
 
-RawBytecode* StackFrame::GetBytecodeObject() const {
+BytecodePtr StackFrame::GetBytecodeObject() const {
   ASSERT(is_interpreted());
-  RawObject* pc_marker = *(
-      reinterpret_cast<RawObject**>(fp() + kKBCPcMarkerSlotFromFp * kWordSize));
+  ObjectPtr pc_marker = *(
+      reinterpret_cast<ObjectPtr*>(fp() + kKBCPcMarkerSlotFromFp * kWordSize));
   ASSERT((pc_marker == Object::null()) ||
          (pc_marker->GetClassId() == kBytecodeCid));
-  return reinterpret_cast<RawBytecode*>(pc_marker);
+  return static_cast<BytecodePtr>(pc_marker);
 }
 
 bool StackFrame::FindExceptionHandler(Thread* thread,
@@ -496,7 +488,7 @@
     try_index = bytecode.GetTryIndexAtPc(pc());
   } else {
     uword pc_offset = pc() - code.PayloadStart();
-    PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+    PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
     while (iter.MoveNext()) {
       const intptr_t current_try_index = iter.TryIndex();
       if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) {
@@ -533,7 +525,7 @@
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   ASSERT(!descriptors.IsNull());
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return TokenPosition(iter.TokenPos());
@@ -542,8 +534,8 @@
   return TokenPosition::kNoSource;
 }
 
-bool StackFrame::IsValid(bool needed_for_gc) const {
-  if (IsEntryFrame() || IsExitFrame() || IsStubFrame(needed_for_gc)) {
+bool StackFrame::IsValid() const {
+  if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
     return true;
   }
   if (is_interpreted()) {
@@ -847,6 +839,7 @@
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 // Finds the potential offset for the current function's FP if the
 // current frame were to be deoptimized.
 intptr_t InlinedFunctionsIterator::GetDeoptFpOffset() const {
@@ -860,6 +853,7 @@
   UNREACHABLE();
   return 0;
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #if defined(DEBUG)
 void ValidateFrames() {
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index f430e99..1aeaa66 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -28,7 +28,6 @@
 
 // Forward declarations.
 class ObjectPointerVisitor;
-class RawContext;
 class LocalVariable;
 
 extern FrameLayout runtime_frame_layout;
@@ -81,8 +80,8 @@
     pc_ = value;
   }
 
-  void set_pc_marker(RawCode* code) {
-    *reinterpret_cast<RawCode**>(
+  void set_pc_marker(CodePtr code) {
+    *reinterpret_cast<CodePtr*>(
         fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
                                   : runtime_frame_layout.code_from_fp) *
                 kWordSize)) = code;
@@ -94,16 +93,14 @@
   const char* ToCString() const;
 
   // Check validity of a frame, used for assertion purposes.
-  virtual bool IsValid(bool needed_for_gc = false) const;
+  virtual bool IsValid() const;
 
-  // Returns the isolate containing the bare instructions of the current frame.
+  // Returns the isolate group containing the bare instructions of the
+  // current frame.
   //
   // If the frame does not belong to a bare instructions snapshot, it will
   // return nullptr.
-  //
-  // [needed_for_gc] has to be set to `true` if the caller needs only GC
-  // relevant information.
-  Isolate* IsolateOfBareInstructionsFrame(bool needed_for_gc) const;
+  IsolateGroup* IsolateGroupOfBareInstructionsFrame() const;
 
   // Returns true iff the current frame is a bare instructions dart frame.
   bool IsBareInstructionsDartFrame() const;
@@ -112,20 +109,19 @@
   bool IsBareInstructionsStubFrame() const;
 
   // Frame type.
-  virtual bool IsDartFrame(bool validate = true,
-                           bool needed_for_gc = false) const {
-    ASSERT(!validate || IsValid(needed_for_gc));
-    return !(IsEntryFrame() || IsExitFrame() || IsStubFrame(needed_for_gc));
+  virtual bool IsDartFrame(bool validate = true) const {
+    ASSERT(!validate || IsValid());
+    return !(IsEntryFrame() || IsExitFrame() || IsStubFrame());
   }
-  virtual bool IsStubFrame(bool neede_for_gc = false) const;
+  virtual bool IsStubFrame() const;
   virtual bool IsEntryFrame() const { return false; }
   virtual bool IsExitFrame() const { return false; }
 
   virtual bool is_interpreted() const { return is_interpreted_; }
 
-  RawFunction* LookupDartFunction() const;
-  RawCode* LookupDartCode() const;
-  RawBytecode* LookupDartBytecode() const;
+  FunctionPtr LookupDartFunction() const;
+  CodePtr LookupDartCode() const;
+  BytecodePtr LookupDartBytecode() const;
   bool FindExceptionHandler(Thread* thread,
                             uword* handler_pc,
                             bool* needs_stacktrace,
@@ -159,9 +155,8 @@
   Thread* thread() const { return thread_; }
 
  private:
-  RawCode* GetCodeObject(bool needed_for_gc = false) const;
-  RawBytecode* GetBytecodeObject() const;
-
+  CodePtr GetCodeObject() const;
+  BytecodePtr GetBytecodeObject() const;
 
   uword GetCallerFp() const {
     return *(reinterpret_cast<uword*>(
@@ -200,11 +195,9 @@
 // runtime code.
 class ExitFrame : public StackFrame {
  public:
-  bool IsValid(bool needed_for_gc = false) const { return sp() == 0; }
-  bool IsDartFrame(bool validate = true, bool needed_for_gc = false) const {
-    return false;
-  }
-  bool IsStubFrame(bool needed_for_gc = false) const { return false; }
+  bool IsValid() const { return sp() == 0; }
+  bool IsDartFrame(bool validate = true) const { return false; }
+  bool IsStubFrame() const { return false; }
   bool IsExitFrame() const { return true; }
 
   // Visit objects in the frame.
@@ -224,13 +217,11 @@
 // dart code.
 class EntryFrame : public StackFrame {
  public:
-  bool IsValid(bool needed_for_gc = false) const {
+  bool IsValid() const {
     return StubCode::InInvocationStub(pc(), is_interpreted());
   }
-  bool IsDartFrame(bool validate = true, bool needed_for_gc = false) const {
-    return false;
-  }
-  bool IsStubFrame(bool needed_for_gc = false) const { return false; }
+  bool IsDartFrame(bool validate = true) const { return false; }
+  bool IsStubFrame() const { return false; }
   bool IsEntryFrame() const { return true; }
 
   // Visit objects in the frame.
@@ -416,7 +407,7 @@
   bool Done() const { return index_ == -1; }
   void Advance();
 
-  RawFunction* function() const {
+  FunctionPtr function() const {
     ASSERT(!Done());
     return function_.raw();
   }
@@ -426,12 +417,14 @@
     return pc_;
   }
 
-  RawCode* code() const {
+  CodePtr code() const {
     ASSERT(!Done());
     return code_.raw();
   }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   intptr_t GetDeoptFpOffset() const;
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
  private:
   void SetDone() { index_ = -1; }
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index 7643a8c..a9df9e1 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -4,20 +4,23 @@
 
 #include "vm/stack_trace.h"
 
-#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/dart_api_impl.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/frontend/bytecode_reader.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // Keep in sync with
 // sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED.
 const intptr_t kStreamController_StateSubscribed = 1;
 
-RawClosure* FindClosureInFrame(RawObject** last_object_in_caller,
-                               const Function& function,
-                               bool is_interpreted) {
+ClosurePtr FindClosureInFrame(ObjectPtr* last_object_in_caller,
+                              const Function& function,
+                              bool is_interpreted) {
   NoSafepointScope nsp;
 
   // The callee has function signature
@@ -29,7 +32,7 @@
   auto& closure = Closure::Handle();
   for (intptr_t i = 0; i < 4; i++) {
     // KBC builds the stack upwards instead of the usual downwards stack.
-    RawObject* arg = last_object_in_caller[(is_interpreted ? -i : i)];
+    ObjectPtr arg = last_object_in_caller[(is_interpreted ? -i : i)];
     if (arg->IsHeapObject() && arg->GetClassId() == kClosureCid) {
       closure = Closure::RawCast(arg);
       if (closure.function() == function.raw()) {
@@ -46,7 +49,7 @@
 intptr_t GetYieldIndex(const Closure& receiver_closure) {
   const auto& function = Function::Handle(receiver_closure.function());
   if (!function.IsAsyncClosure() && !function.IsAsyncGenClosure()) {
-    return RawPcDescriptors::kInvalidYieldIndex;
+    return PcDescriptorsLayout::kInvalidYieldIndex;
   }
   const auto& await_jump_var =
       Object::Handle(Context::Handle(receiver_closure.context())
@@ -56,10 +59,10 @@
 }
 
 intptr_t FindPcOffset(const PcDescriptors& pc_descs, intptr_t yield_index) {
-  if (yield_index == RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index == PcDescriptorsLayout::kInvalidYieldIndex) {
     return 0;
   }
-  PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
+  PcDescriptors::Iterator iter(pc_descs, PcDescriptorsLayout::kAnyKind);
   while (iter.MoveNext()) {
     if (iter.YieldIndex() == yield_index) {
       return iter.PcOffset();
@@ -70,7 +73,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 intptr_t FindPcOffset(const Bytecode& bytecode, intptr_t yield_index) {
-  if (yield_index == RawPcDescriptors::kInvalidYieldIndex) {
+  if (yield_index == PcDescriptorsLayout::kInvalidYieldIndex) {
     return 0;
   }
   if (!bytecode.HasSourcePositions()) {
@@ -194,7 +197,7 @@
     ASSERT(!state_data_field.IsNull());
   }
 
-  RawClosure* GetCallerInFutureImpl(const Object& future_) {
+  ClosurePtr GetCallerInFutureImpl(const Object& future_) {
     ASSERT(!future_.IsNull());
     ASSERT(future_.GetClassId() == future_impl_class.id());
 
@@ -214,7 +217,7 @@
     return Closure::Cast(callback_).raw();
   }
 
-  RawClosure* FindCallerInAsyncClosure(const Context& receiver_context) {
+  ClosurePtr FindCallerInAsyncClosure(const Context& receiver_context) {
     context_entry_ = receiver_context.At(Context::kAsyncCompleterIndex);
     ASSERT(context_entry_.IsInstance());
     ASSERT(context_entry_.GetClassId() == async_await_completer_class.id());
@@ -224,7 +227,7 @@
     return GetCallerInFutureImpl(future_);
   }
 
-  RawClosure* FindCallerInAsyncGenClosure(const Context& receiver_context) {
+  ClosurePtr FindCallerInAsyncGenClosure(const Context& receiver_context) {
     context_entry_ = receiver_context.At(Context::kControllerIndex);
     ASSERT(context_entry_.IsInstance());
     ASSERT(context_entry_.GetClassId() ==
@@ -274,7 +277,7 @@
     UNREACHABLE();  // If no onData is found we have a bug.
   }
 
-  RawClosure* FindCaller(const Closure& receiver_closure) {
+  ClosurePtr FindCaller(const Closure& receiver_closure) {
     receiver_function_ = receiver_closure.function();
     receiver_context_ = receiver_closure.context();
 
@@ -398,13 +401,15 @@
     if (frame->is_interpreted()) {
       code_array.Add(bytecode);
       const intptr_t pc_offset = frame->pc() - bytecode.PayloadStart();
-      ASSERT(pc_offset >= 0 && pc_offset <= bytecode.Size());
+      ASSERT(pc_offset > 0 && pc_offset <= bytecode.Size());
       offset = Smi::New(pc_offset);
     } else {
       code = frame->LookupDartCode();
       ASSERT(function.raw() == code.function());
       code_array.Add(code);
-      offset = Smi::New(frame->pc() - code.PayloadStart());
+      const intptr_t pc_offset = frame->pc() - code.PayloadStart();
+      ASSERT(pc_offset > 0 && pc_offset <= code.Size());
+      offset = Smi::New(pc_offset);
     }
     pc_offset_array.Add(offset);
     if (on_sync_frames != nullptr) {
@@ -421,8 +426,8 @@
 
       // Next, look up caller's closure on the stack and walk backwards through
       // the yields.
-      RawObject** last_caller_obj = reinterpret_cast<RawObject**>(
-          frame->GetCallerSp());
+      ObjectPtr* last_caller_obj =
+          reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
       closure = FindClosureInFrame(last_caller_obj, function,
                                    frame->is_interpreted());
 
@@ -463,6 +468,8 @@
         } else {
           UNREACHABLE();
         }
+        // Unlike other sources of PC offsets, the offset may be 0 here if we
+        // reach a non-async closure receiving the yielded value.
         ASSERT(offset.Value() >= 0);
         pc_offset_array.Add(offset);
 
@@ -510,12 +517,13 @@
     if (frame->is_interpreted()) {
       bytecode = frame->LookupDartBytecode();
       function = bytecode.function();
+      if (function.IsNull()) continue;
     } else {
       code = frame->LookupDartCode();
       function = code.function();
     }
-    if (function.IsNull()) continue;
-    if (sync_async_gap_frames > 0) {
+    const bool function_is_null = function.IsNull();
+    if (!function_is_null && sync_async_gap_frames > 0) {
       function_name = function.QualifiedScrubbedName();
       if (!CheckAndSkipAsync(&sync_async_gap_frames, function_name)) {
         *sync_async_end = false;
@@ -524,7 +532,7 @@
     } else {
       frame_count++;
     }
-    if (!async_function_is_null &&
+    if (!async_function_is_null && !function_is_null &&
         (async_function.raw() == function.parent_function())) {
       sync_async_gap_frames = kSyncAsyncFrameGap;
     }
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 98f20cf..29906ec 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -7,8 +7,6 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 #include "vm/clustered_snapshot.h"
-#include "vm/compiler/aot/precompiler.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/flags.h"
 #include "vm/heap/safepoint.h"
@@ -18,6 +16,11 @@
 #include "vm/virtual_memory.h"
 #include "vm/visitor.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/aot/precompiler.h"
+#include "vm/compiler/assembler/assembler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 DEFINE_FLAG(bool, disassemble_stubs, false, "Disassemble generated stubs.");
@@ -65,7 +68,7 @@
 #undef STUB_CODE_GENERATE
 #undef STUB_CODE_SET_OBJECT_POOL
 
-RawCode* StubCode::Generate(
+CodePtr StubCode::Generate(
     const char* name,
     compiler::ObjectPoolBuilder* object_pool_builder,
     void (*GenerateStub)(compiler::Assembler* assembler)) {
@@ -124,13 +127,45 @@
   return (pc >= entry) && (pc < (entry + size));
 }
 
-RawCode* StubCode::GetAllocationStubForClass(const Class& cls) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ArrayPtr compiler::StubCodeCompiler::BuildStaticCallsTable(
+    Zone* zone,
+    compiler::UnresolvedPcRelativeCalls* unresolved_calls) {
+  if (unresolved_calls->length() == 0) {
+    return Array::null();
+  }
+  const intptr_t array_length =
+      unresolved_calls->length() * Code::kSCallTableEntryLength;
+  const auto& static_calls_table =
+      Array::Handle(zone, Array::New(array_length, Heap::kOld));
+  StaticCallsTable entries(static_calls_table);
+  auto& kind_type_and_offset = Smi::Handle(zone);
+  for (intptr_t i = 0; i < unresolved_calls->length(); i++) {
+    auto& unresolved_call = (*unresolved_calls)[i];
+    auto call_kind = unresolved_call->is_tail_call() ? Code::kPcRelativeTailCall
+                                                     : Code::kPcRelativeCall;
+    kind_type_and_offset =
+        Smi::New(Code::KindField::encode(call_kind) |
+                 Code::EntryPointField::encode(Code::kDefaultEntry) |
+                 Code::OffsetField::encode(unresolved_call->offset()));
+    auto view = entries[i];
+    view.Set<Code::kSCallTableKindAndOffset>(kind_type_and_offset);
+    view.Set<Code::kSCallTableCodeOrTypeTarget>(unresolved_call->target());
+  }
+  return static_calls_table.raw();
+}
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+CodePtr StubCode::GetAllocationStubForClass(const Class& cls) {
   Thread* thread = Thread::Current();
+  auto object_store = thread->isolate()->object_store();
   Zone* zone = thread->zone();
   const Error& error = Error::Handle(zone, cls.EnsureIsFinalized(thread));
   ASSERT(error.IsNull());
   if (cls.id() == kArrayCid) {
-    return AllocateArray().raw();
+    return object_store->allocate_array_stub();
+  } else if (cls.id() == kContextCid) {
+    return object_store->allocate_context_stub();
   }
   Code& stub = Code::Handle(zone, cls.allocation_stub());
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -148,9 +183,26 @@
             ? Code::PoolAttachment::kNotAttachPool
             : Code::PoolAttachment::kAttachPool;
 
+    auto zone = thread->zone();
+    auto object_store = thread->isolate()->object_store();
+    auto& allocate_object_stub = Code::ZoneHandle(zone);
+    auto& allocate_object_parametrized_stub = Code::ZoneHandle(zone);
+    if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+      allocate_object_stub = object_store->allocate_object_stub();
+      allocate_object_parametrized_stub =
+          object_store->allocate_object_parametrized_stub();
+    }
+
     compiler::Assembler assembler(wrapper);
+    compiler::UnresolvedPcRelativeCalls unresolved_calls;
     const char* name = cls.ToCString();
-    compiler::StubCodeCompiler::GenerateAllocationStubForClass(&assembler, cls);
+    compiler::StubCodeCompiler::GenerateAllocationStubForClass(
+        &assembler, &unresolved_calls, cls, allocate_object_stub,
+        allocate_object_parametrized_stub);
+
+    const auto& static_calls_table =
+        Array::Handle(zone, compiler::StubCodeCompiler::BuildStaticCallsTable(
+                                zone, &unresolved_calls));
 
     auto mutator_fun = [&]() {
       stub = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
@@ -159,6 +211,9 @@
       // Check if background compilation thread has not already added the stub.
       if (cls.allocation_stub() == Code::null()) {
         stub.set_owner(cls);
+        if (!static_calls_table.IsNull()) {
+          stub.set_static_calls_target_table(static_calls_table);
+        }
         cls.set_allocation_stub(stub);
       }
     };
@@ -172,6 +227,9 @@
       stub = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
                                 /*optimized=*/false, /*stats=*/nullptr);
       stub.set_owner(cls);
+      if (!static_calls_table.IsNull()) {
+        stub.set_static_calls_target_table(static_calls_table);
+      }
       cls.set_allocation_stub(stub);
     };
 
@@ -200,7 +258,7 @@
 }
 
 #if !defined(TARGET_ARCH_IA32)
-RawCode* StubCode::GetBuildMethodExtractorStub(
+CodePtr StubCode::GetBuildMethodExtractorStub(
     compiler::ObjectPoolBuilder* pool) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   auto thread = Thread::Current();
@@ -261,6 +319,15 @@
       return entries_[i].name;
     }
   }
+
+  auto object_store = Isolate::Current()->object_store();
+#define DO(member, name)                                                       \
+  if (object_store->member() != Code::null() &&                                \
+      entry_point == Code::EntryPointOf(object_store->member())) {             \
+    return "_iso_stub_" #name "Stub";                                          \
+  }
+  OBJECT_STORE_STUB_CODE_LIST(DO)
+#undef DO
   return nullptr;
 }
 
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index be2ad99..19fd413 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -6,19 +6,21 @@
 #define RUNTIME_VM_STUB_CODE_H_
 
 #include "vm/allocation.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/runtime_api.h"
-#include "vm/compiler/stub_code_compiler.h"
 #include "vm/object.h"
 #include "vm/stub_code_list.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/stub_code_compiler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 // Forward declarations.
 class Code;
 class Isolate;
 class ObjectPointerVisitor;
-class RawCode;
 class SnapshotReader;
 class SnapshotWriter;
 
@@ -59,19 +61,19 @@
   VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR);
 #undef STUB_CODE_ACCESSOR
 
-  static RawCode* GetAllocationStubForClass(const Class& cls);
+  static CodePtr GetAllocationStubForClass(const Class& cls);
 
 #if !defined(TARGET_ARCH_IA32)
-  static RawCode* GetBuildMethodExtractorStub(
-      compiler::ObjectPoolBuilder* pool);
+  static CodePtr GetBuildMethodExtractorStub(compiler::ObjectPoolBuilder* pool);
 #endif
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   // Generate the stub and finalize the generated code into the stub
   // code executable area.
-  static RawCode* Generate(
-      const char* name,
-      compiler::ObjectPoolBuilder* object_pool_builder,
-      void (*GenerateStub)(compiler::Assembler* assembler));
+  static CodePtr Generate(const char* name,
+                          compiler::ObjectPoolBuilder* object_pool_builder,
+                          void (*GenerateStub)(compiler::Assembler* assembler));
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   static const Code& UnoptimizedStaticCallEntry(intptr_t num_args_tested);
 
@@ -87,7 +89,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 #define GENERATE_STUB(name)                                                    \
-  static RawCode* BuildIsolateSpecific##name##Stub(                            \
+  static CodePtr BuildIsolateSpecific##name##Stub(                             \
       compiler::ObjectPoolBuilder* opw) {                                      \
     return StubCode::Generate(                                                 \
         "_iso_stub_" #name, opw,                                               \
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index 76c37f0..0939ef2 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::ZoneHandle(Symbols::New(Thread::Current(), name));
   Function& function = Function::ZoneHandle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index 6c1fcae..ea6a6bc 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::ZoneHandle(Symbols::New(Thread::Current(), name));
   Function& function = Function::ZoneHandle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index e8f412d..b5c4388 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::ZoneHandle(Symbols::New(Thread::Current(), name));
   Function& function = Function::ZoneHandle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kMinSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kMinSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index 3554661..0c188c9 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -19,9 +19,12 @@
   V(ArrayWriteBarrier)                                                         \
   V(PrintStopMessage)                                                          \
   V(AllocateArray)                                                             \
-  V(AllocateMintWithFPURegs)                                                   \
-  V(AllocateMintWithoutFPURegs)                                                \
+  V(AllocateMintSharedWithFPURegs)                                             \
+  V(AllocateMintSharedWithoutFPURegs)                                          \
   V(AllocateContext)                                                           \
+  V(AllocateObject)                                                            \
+  V(AllocateObjectParameterized)                                               \
+  V(AllocateObjectSlow)                                                        \
   V(CloneContext)                                                              \
   V(CallToRuntime)                                                             \
   V(LazyCompile)                                                               \
@@ -35,8 +38,7 @@
   V(InvokeDartCode)                                                            \
   V(InvokeDartCodeFromBytecode)                                                \
   V(DebugStepCheck)                                                            \
-  V(UnlinkedCall)                                                              \
-  V(MonomorphicMiss)                                                           \
+  V(SwitchableCallMiss)                                                        \
   V(MonomorphicSmiableCheck)                                                   \
   V(SingleTargetCall)                                                          \
   V(ICCallThroughCode)                                                         \
@@ -79,6 +81,8 @@
   V(NullErrorSharedWithoutFPURegs)                                             \
   V(NullArgErrorSharedWithFPURegs)                                             \
   V(NullArgErrorSharedWithoutFPURegs)                                          \
+  V(RangeErrorSharedWithFPURegs)                                               \
+  V(RangeErrorSharedWithoutFPURegs)                                            \
   V(StackOverflowSharedWithFPURegs)                                            \
   V(StackOverflowSharedWithoutFPURegs)                                         \
   V(OneArgCheckInlineCacheWithExactnessCheck)                                  \
@@ -87,9 +91,17 @@
   V(ExitSafepoint)                                                             \
   V(CallNativeThroughSafepoint)                                                \
   V(InitStaticField)                                                           \
+  V(InitInstanceField)                                                         \
+  V(InitLateInstanceField)                                                     \
+  V(InitLateFinalInstanceField)                                                \
+  V(Throw)                                                                     \
+  V(ReThrow)                                                                   \
+  V(AssertBoolean)                                                             \
+  V(InstanceOf)                                                                \
   V(InstantiateTypeArguments)                                                  \
   V(InstantiateTypeArgumentsMayShareInstantiatorTA)                            \
-  V(InstantiateTypeArgumentsMayShareFunctionTA)
+  V(InstantiateTypeArgumentsMayShareFunctionTA)                                \
+  V(NoSuchMethodDispatcher)
 
 }  // namespace dart
 
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index 39836c8..b41ec88 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -29,8 +29,8 @@
   const String& function_name =
       String::ZoneHandle(Symbols::New(Thread::Current(), name));
   Function& function = Function::ZoneHandle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 312e23b..04339dd 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -18,7 +18,7 @@
 
 namespace dart {
 
-RawString* Symbols::predefined_[Symbols::kNumberOfOneCharCodeSymbols];
+StringPtr Symbols::predefined_[Symbols::kNumberOfOneCharCodeSymbols];
 String* Symbols::symbol_handles_[Symbols::kMaxPredefinedId];
 
 static const char* names[] = {
@@ -35,15 +35,15 @@
     // clang-format on
 };
 
-RawString* StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) {
+StringPtr StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) {
   return String::FromLatin1(data, len, space);
 }
 
-RawString* StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) {
+StringPtr StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) {
   return String::FromUTF16(data, len, space);
 }
 
-RawString* StringFrom(const int32_t* data, intptr_t len, Heap::Space space) {
+StringPtr StringFrom(const int32_t* data, intptr_t len, Heap::Space space) {
   return String::FromUTF32(data, len, space);
 }
 
@@ -53,7 +53,7 @@
   CharArray(const CharType* data, intptr_t len) : data_(data), len_(len) {
     hash_ = String::Hash(data, len);
   }
-  RawString* ToSymbol() const {
+  StringPtr ToSymbol() const {
     String& result = String::Handle(StringFrom(data_, len_, Heap::kOld));
     result.SetCanonical();
     result.SetHash(hash_);
@@ -83,7 +83,7 @@
       : str_(str), begin_index_(begin_index), len_(length) {
     hash_ = is_all() ? str.Hash() : String::Hash(str, begin_index, length);
   }
-  RawString* ToSymbol() const;
+  StringPtr ToSymbol() const;
   bool Equals(const String& other) const {
     ASSERT(other.HasHash());
     if (other.Hash() != hash_) {
@@ -101,7 +101,7 @@
   intptr_t hash_;
 };
 
-RawString* StringSlice::ToSymbol() const {
+StringPtr StringSlice::ToSymbol() const {
   if (is_all() && str_.IsOld()) {
     str_.SetCanonical();
     return str_.raw();
@@ -118,7 +118,7 @@
  public:
   ConcatString(const String& str1, const String& str2)
       : str1_(str1), str2_(str2), hash_(String::HashConcat(str1, str2)) {}
-  RawString* ToSymbol() const;
+  StringPtr ToSymbol() const;
   bool Equals(const String& other) const {
     ASSERT(other.HasHash());
     if (other.Hash() != hash_) {
@@ -134,7 +134,7 @@
   intptr_t hash_;
 };
 
-RawString* ConcatString::ToSymbol() const {
+StringPtr ConcatString::ToSymbol() const {
   String& result = String::Handle(String::Concat(str1_, str2_, Heap::kOld));
   result.SetCanonical();
   result.SetHash(hash_);
@@ -179,13 +179,11 @@
   static uword Hash(const StringSlice& slice) { return slice.Hash(); }
   static uword Hash(const ConcatString& concat) { return concat.Hash(); }
   template <typename CharType>
-  static RawObject* NewKey(const CharArray<CharType>& array) {
+  static ObjectPtr NewKey(const CharArray<CharType>& array) {
     return array.ToSymbol();
   }
-  static RawObject* NewKey(const StringSlice& slice) {
-    return slice.ToSymbol();
-  }
-  static RawObject* NewKey(const ConcatString& concat) {
+  static ObjectPtr NewKey(const StringSlice& slice) { return slice.ToSymbol(); }
+  static ObjectPtr NewKey(const ConcatString& concat) {
     return concat.ToSymbol();
   }
 };
@@ -242,7 +240,7 @@
     *str = OneByteString::New(&ch, 1, Heap::kOld);
     str->Hash();
     *str ^= table.InsertOrGet(*str);
-    ASSERT(predefined_[c] == NULL);
+    ASSERT(predefined_[c] == nullptr);
     str->SetCanonical();  // Make canonical once entered.
     predefined_[c] = str->raw();
     symbol_handles_[idx] = str;
@@ -331,8 +329,8 @@
           type_args_(type_args),
           zone_(thread->zone()) {}
 
-    void VisitObject(RawObject* obj) {
-      if (obj->IsCanonical()) {
+    void VisitObject(ObjectPtr obj) {
+      if (obj->ptr()->IsCanonical()) {
         if (obj->IsStringInstance()) {
           symbols_->Add(&String::Handle(zone_, String::RawCast(obj)));
         } else if (obj->IsType()) {
@@ -413,15 +411,15 @@
   table.Release();
 }
 
-RawString* Symbols::New(Thread* thread, const char* cstr, intptr_t len) {
+StringPtr Symbols::New(Thread* thread, const char* cstr, intptr_t len) {
   ASSERT((cstr != NULL) && (len >= 0));
   const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr);
   return Symbols::FromUTF8(thread, utf8_array, len);
 }
 
-RawString* Symbols::FromUTF8(Thread* thread,
-                             const uint8_t* utf8_array,
-                             intptr_t array_len) {
+StringPtr Symbols::FromUTF8(Thread* thread,
+                            const uint8_t* utf8_array,
+                            intptr_t array_len) {
   if (array_len == 0 || utf8_array == NULL) {
     return FromLatin1(thread, reinterpret_cast<uint8_t*>(NULL), 0);
   }
@@ -446,27 +444,27 @@
   return FromUTF16(thread, characters, len);
 }
 
-RawString* Symbols::FromLatin1(Thread* thread,
-                               const uint8_t* latin1_array,
-                               intptr_t len) {
+StringPtr Symbols::FromLatin1(Thread* thread,
+                              const uint8_t* latin1_array,
+                              intptr_t len) {
   return NewSymbol(thread, Latin1Array(latin1_array, len));
 }
 
-RawString* Symbols::FromUTF16(Thread* thread,
-                              const uint16_t* utf16_array,
-                              intptr_t len) {
+StringPtr Symbols::FromUTF16(Thread* thread,
+                             const uint16_t* utf16_array,
+                             intptr_t len) {
   return NewSymbol(thread, UTF16Array(utf16_array, len));
 }
 
-RawString* Symbols::FromUTF32(Thread* thread,
-                              const int32_t* utf32_array,
-                              intptr_t len) {
+StringPtr Symbols::FromUTF32(Thread* thread,
+                             const int32_t* utf32_array,
+                             intptr_t len) {
   return NewSymbol(thread, UTF32Array(utf32_array, len));
 }
 
-RawString* Symbols::FromConcat(Thread* thread,
-                               const String& str1,
-                               const String& str2) {
+StringPtr Symbols::FromConcat(Thread* thread,
+                              const String& str1,
+                              const String& str2) {
   if (str1.Length() == 0) {
     return New(thread, str2);
   } else if (str2.Length() == 0) {
@@ -476,22 +474,22 @@
   }
 }
 
-RawString* Symbols::FromGet(Thread* thread, const String& str) {
+StringPtr Symbols::FromGet(Thread* thread, const String& str) {
   return FromConcat(thread, GetterPrefix(), str);
 }
 
-RawString* Symbols::FromSet(Thread* thread, const String& str) {
+StringPtr Symbols::FromSet(Thread* thread, const String& str) {
   return FromConcat(thread, SetterPrefix(), str);
 }
 
-RawString* Symbols::FromDot(Thread* thread, const String& str) {
+StringPtr Symbols::FromDot(Thread* thread, const String& str) {
   return FromConcat(thread, str, Dot());
 }
 
 // TODO(srdjan): If this becomes performance critical code, consider looking
 // up symbol from hash of pieces instead of concatenating them first into
 // a string.
-RawString* Symbols::FromConcatAll(
+StringPtr Symbols::FromConcatAll(
     Thread* thread,
     const GrowableHandlePtrArray<const String>& strs) {
   const intptr_t strs_length = strs.length();
@@ -565,7 +563,7 @@
 
 // StringType can be StringSlice, ConcatString, or {Latin1,UTF16,UTF32}Array.
 template <typename StringType>
-RawString* Symbols::NewSymbol(Thread* thread, const StringType& str) {
+StringPtr Symbols::NewSymbol(Thread* thread, const StringType& str) {
   REUSABLE_OBJECT_HANDLESCOPE(thread);
   REUSABLE_SMI_HANDLESCOPE(thread);
   REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -581,12 +579,31 @@
     table.Release();
   }
   if (symbol.IsNull()) {
+    IsolateGroup* group = thread->isolate_group();
     Isolate* isolate = thread->isolate();
-    SafepointMutexLocker ml(isolate->symbols_mutex());
-    data = isolate->object_store()->symbol_table();
-    SymbolTable table(&key, &value, &data);
-    symbol ^= table.InsertNewOrGet(str);
-    isolate->object_store()->set_symbol_table(table.Release());
+    // in JIT object_store lives on isolate, not on isolate group.
+    ObjectStore* object_store = group->object_store() == nullptr
+                                    ? isolate->object_store()
+                                    : group->object_store();
+    // in AOT no need to worry about background compiler, only about
+    // other mutators.
+#if defined(DART_PRECOMPILED_RUNTIME)
+    group->RunWithStoppedMutators(
+        [&]() {
+#else
+    SafepointRwLock* symbols_lock = group->object_store() == nullptr
+                                        ? isolate->symbols_lock()
+                                        : group->symbols_lock();
+    SafepointWriteRwLocker sl(thread, symbols_lock);
+#endif
+          data = object_store->symbol_table();
+          SymbolTable table(&key, &value, &data);
+          symbol ^= table.InsertNewOrGet(str);
+          object_store->set_symbol_table(table.Release());
+#if defined(DART_PRECOMPILED_RUNTIME)
+        },
+        /*use_force_growth=*/true);
+#endif
   }
   ASSERT(symbol.IsSymbol());
   ASSERT(symbol.HasHash());
@@ -594,7 +611,7 @@
 }
 
 template <typename StringType>
-RawString* Symbols::Lookup(Thread* thread, const StringType& str) {
+StringPtr Symbols::Lookup(Thread* thread, const StringType& str) {
   REUSABLE_OBJECT_HANDLESCOPE(thread);
   REUSABLE_SMI_HANDLESCOPE(thread);
   REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -610,9 +627,21 @@
     table.Release();
   }
   if (symbol.IsNull()) {
+    IsolateGroup* group = thread->isolate_group();
     Isolate* isolate = thread->isolate();
-    SafepointMutexLocker ml(isolate->symbols_mutex());
-    data = isolate->object_store()->symbol_table();
+    // in JIT object_store lives on isolate, not on isolate group.
+    ObjectStore* object_store = group->object_store() == nullptr
+                                    ? isolate->object_store()
+                                    : group->object_store();
+    // in AOT no need to worry about background compiler, only about
+    // other mutators.
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    SafepointRwLock* symbols_lock = group->object_store() == nullptr
+                                        ? isolate->symbols_lock()
+                                        : group->symbols_lock();
+    SafepointReadRwLocker sl(thread, symbols_lock);
+#endif
+    data = object_store->symbol_table();
     SymbolTable table(&key, &value, &data);
     symbol ^= table.GetOrNull(str);
     table.Release();
@@ -622,9 +651,9 @@
   return symbol.raw();
 }
 
-RawString* Symbols::LookupFromConcat(Thread* thread,
-                                     const String& str1,
-                                     const String& str2) {
+StringPtr Symbols::LookupFromConcat(Thread* thread,
+                                    const String& str1,
+                                    const String& str2) {
   if (str1.Length() == 0) {
     return Lookup(thread, str2);
   } else if (str2.Length() == 0) {
@@ -634,44 +663,44 @@
   }
 }
 
-RawString* Symbols::LookupFromGet(Thread* thread, const String& str) {
+StringPtr Symbols::LookupFromGet(Thread* thread, const String& str) {
   return LookupFromConcat(thread, GetterPrefix(), str);
 }
 
-RawString* Symbols::LookupFromSet(Thread* thread, const String& str) {
+StringPtr Symbols::LookupFromSet(Thread* thread, const String& str) {
   return LookupFromConcat(thread, SetterPrefix(), str);
 }
 
-RawString* Symbols::LookupFromDot(Thread* thread, const String& str) {
+StringPtr Symbols::LookupFromDot(Thread* thread, const String& str) {
   return LookupFromConcat(thread, str, Dot());
 }
 
-RawString* Symbols::New(Thread* thread, const String& str) {
+StringPtr Symbols::New(Thread* thread, const String& str) {
   if (str.IsSymbol()) {
     return str.raw();
   }
   return New(thread, str, 0, str.Length());
 }
 
-RawString* Symbols::New(Thread* thread,
-                        const String& str,
-                        intptr_t begin_index,
-                        intptr_t len) {
+StringPtr Symbols::New(Thread* thread,
+                       const String& str,
+                       intptr_t begin_index,
+                       intptr_t len) {
   return NewSymbol(thread, StringSlice(str, begin_index, len));
 }
 
-RawString* Symbols::NewFormatted(Thread* thread, const char* format, ...) {
+StringPtr Symbols::NewFormatted(Thread* thread, const char* format, ...) {
   va_list args;
   va_start(args, format);
-  RawString* result = NewFormattedV(thread, format, args);
+  StringPtr result = NewFormattedV(thread, format, args);
   NoSafepointScope no_safepoint;
   va_end(args);
   return result;
 }
 
-RawString* Symbols::NewFormattedV(Thread* thread,
-                                  const char* format,
-                                  va_list args) {
+StringPtr Symbols::NewFormattedV(Thread* thread,
+                                 const char* format,
+                                 va_list args) {
   va_list args_copy;
   va_copy(args_copy, args);
   intptr_t len = Utils::VSNPrint(NULL, 0, format, args_copy);
@@ -684,7 +713,7 @@
   return Symbols::New(thread, buffer);
 }
 
-RawString* Symbols::FromCharCode(Thread* thread, int32_t char_code) {
+StringPtr Symbols::FromCharCode(Thread* thread, int32_t char_code) {
   if (char_code > kMaxOneCharCodeSymbol) {
     return FromUTF32(thread, &char_code, 1);
   }
@@ -713,7 +742,7 @@
   table.Release();
 }
 
-intptr_t Symbols::LookupPredefinedSymbol(RawObject* obj) {
+intptr_t Symbols::LookupPredefinedSymbol(ObjectPtr obj) {
   for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
     if (symbol_handles_[i]->raw() == obj) {
       return (i + kMaxPredefinedObjectIds);
@@ -722,7 +751,7 @@
   return kInvalidIndex;
 }
 
-RawObject* Symbols::GetPredefinedSymbol(intptr_t object_id) {
+ObjectPtr Symbols::GetPredefinedSymbol(intptr_t object_id) {
   ASSERT(IsPredefinedSymbolId(object_id));
   intptr_t i = (object_id - kMaxPredefinedObjectIds);
   if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index c58f83f..df9470a 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -208,7 +208,7 @@
   V(Map, "Map")                                                                \
   V(MapLiteralFactory, "Map._fromLiteral")                                     \
   V(MegamorphicCache, "MegamorphicCache")                                      \
-  V(MegamorphicMiss, "megamorphic_miss")                                       \
+  V(MegamorphicCallMiss, "megamorphic_call_miss")                              \
   V(MonomorphicSmiableCall, "MonomorphicSmiableCall")                          \
   V(MoveNext, "moveNext")                                                      \
   V(Namespace, "Namespace")                                                    \
@@ -645,62 +645,62 @@
   // Creates a Symbol given a C string that is assumed to contain
   // UTF-8 encoded characters and '\0' is considered a termination character.
   // TODO(7123) - Rename this to FromCString(....).
-  static RawString* New(Thread* thread, const char* cstr) {
+  static StringPtr New(Thread* thread, const char* cstr) {
     return New(thread, cstr, strlen(cstr));
   }
-  static RawString* New(Thread* thread, const char* cstr, intptr_t length);
+  static StringPtr New(Thread* thread, const char* cstr, intptr_t length);
 
   // Creates a new Symbol from an array of UTF-8 encoded characters.
-  static RawString* FromUTF8(Thread* thread,
-                             const uint8_t* utf8_array,
-                             intptr_t len);
+  static StringPtr FromUTF8(Thread* thread,
+                            const uint8_t* utf8_array,
+                            intptr_t len);
 
   // Creates a new Symbol from an array of Latin-1 encoded characters.
-  static RawString* FromLatin1(Thread* thread,
-                               const uint8_t* latin1_array,
-                               intptr_t len);
+  static StringPtr FromLatin1(Thread* thread,
+                              const uint8_t* latin1_array,
+                              intptr_t len);
 
   // Creates a new Symbol from an array of UTF-16 encoded characters.
-  static RawString* FromUTF16(Thread* thread,
-                              const uint16_t* utf16_array,
-                              intptr_t len);
+  static StringPtr FromUTF16(Thread* thread,
+                             const uint16_t* utf16_array,
+                             intptr_t len);
 
   // Creates a new Symbol from an array of UTF-32 encoded characters.
-  static RawString* FromUTF32(Thread* thread,
-                              const int32_t* utf32_array,
-                              intptr_t len);
+  static StringPtr FromUTF32(Thread* thread,
+                             const int32_t* utf32_array,
+                             intptr_t len);
 
-  static RawString* New(Thread* thread, const String& str);
-  static RawString* New(Thread* thread,
-                        const String& str,
-                        intptr_t begin_index,
-                        intptr_t length);
+  static StringPtr New(Thread* thread, const String& str);
+  static StringPtr New(Thread* thread,
+                       const String& str,
+                       intptr_t begin_index,
+                       intptr_t length);
 
-  static RawString* NewFormatted(Thread* thread, const char* format, ...)
+  static StringPtr NewFormatted(Thread* thread, const char* format, ...)
       PRINTF_ATTRIBUTE(2, 3);
-  static RawString* NewFormattedV(Thread* thread,
-                                  const char* format,
-                                  va_list args);
+  static StringPtr NewFormattedV(Thread* thread,
+                                 const char* format,
+                                 va_list args);
 
-  static RawString* FromConcat(Thread* thread,
-                               const String& str1,
-                               const String& str2);
+  static StringPtr FromConcat(Thread* thread,
+                              const String& str1,
+                              const String& str2);
 
-  static RawString* FromConcatAll(
+  static StringPtr FromConcatAll(
       Thread* thread,
       const GrowableHandlePtrArray<const String>& strs);
 
-  static RawString* FromGet(Thread* thread, const String& str);
-  static RawString* FromSet(Thread* thread, const String& str);
-  static RawString* FromDot(Thread* thread, const String& str);
+  static StringPtr FromGet(Thread* thread, const String& str);
+  static StringPtr FromSet(Thread* thread, const String& str);
+  static StringPtr FromDot(Thread* thread, const String& str);
 
   // Returns char* of predefined symbol.
   static const char* Name(SymbolId symbol);
 
-  static RawString* FromCharCode(Thread* thread, int32_t char_code);
+  static StringPtr FromCharCode(Thread* thread, int32_t char_code);
 
-  static RawString** PredefinedAddress() {
-    return reinterpret_cast<RawString**>(&predefined_);
+  static StringPtr* PredefinedAddress() {
+    return reinterpret_cast<StringPtr*>(&predefined_);
   }
 
   static void DumpStats(Isolate* isolate);
@@ -708,16 +708,16 @@
 
   // Returns Symbol::Null if no symbol is found.
   template <typename StringType>
-  static RawString* Lookup(Thread* thread, const StringType& str);
+  static StringPtr Lookup(Thread* thread, const StringType& str);
 
   // Returns Symbol::Null if no symbol is found.
-  static RawString* LookupFromConcat(Thread* thread,
-                                     const String& str1,
-                                     const String& str2);
+  static StringPtr LookupFromConcat(Thread* thread,
+                                    const String& str1,
+                                    const String& str2);
 
-  static RawString* LookupFromGet(Thread* thread, const String& str);
-  static RawString* LookupFromSet(Thread* thread, const String& str);
-  static RawString* LookupFromDot(Thread* thread, const String& str);
+  static StringPtr LookupFromGet(Thread* thread, const String& str);
+  static StringPtr LookupFromSet(Thread* thread, const String& str);
+  static StringPtr LookupFromDot(Thread* thread, const String& str);
 
   static void GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity);
 
@@ -725,10 +725,10 @@
   enum { kInitialVMIsolateSymtabSize = 1024, kInitialSymtabSize = 2048 };
 
   template <typename StringType>
-  static RawString* NewSymbol(Thread* thread, const StringType& str);
+  static StringPtr NewSymbol(Thread* thread, const StringType& str);
 
-  static intptr_t LookupPredefinedSymbol(RawObject* obj);
-  static RawObject* GetPredefinedSymbol(intptr_t object_id);
+  static intptr_t LookupPredefinedSymbol(ObjectPtr obj);
+  static ObjectPtr GetPredefinedSymbol(intptr_t object_id);
   static bool IsPredefinedSymbolId(intptr_t object_id) {
     return (object_id >= kMaxPredefinedObjectIds &&
             object_id < (kMaxPredefinedObjectIds + kMaxPredefinedId));
@@ -737,7 +737,7 @@
   // List of Latin1 characters stored in the vm isolate as symbols
   // in order to make Symbols::FromCharCode fast. This structure is
   // used in generated dart code for direct access to these objects.
-  static RawString* predefined_[kNumberOfOneCharCodeSymbols];
+  static StringPtr predefined_[kNumberOfOneCharCodeSymbols];
 
   // List of handles for predefined symbols.
   static String* symbol_handles_[kMaxPredefinedId];
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
new file mode 100644
index 0000000..9b92514
--- /dev/null
+++ b/runtime/vm/tagged_pointer.h
@@ -0,0 +1,324 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_TAGGED_POINTER_H_
+#define RUNTIME_VM_TAGGED_POINTER_H_
+
+#include "platform/assert.h"
+#include "platform/utils.h"
+#include "vm/class_id.h"
+#include "vm/pointer_tagging.h"
+
+namespace dart {
+
+class IsolateGroup;
+class ObjectLayout;
+
+class ObjectPtr {
+ public:
+  ObjectPtr* operator->() { return this; }
+  const ObjectPtr* operator->() const { return this; }
+  ObjectLayout* ptr() const {
+    return reinterpret_cast<ObjectLayout*>(UntaggedPointer());
+  }
+
+  bool IsWellFormed() const {
+    uword value = tagged_pointer_;
+    return (value & kSmiTagMask) == 0 ||
+           Utils::IsAligned(value - kHeapObjectTag, kWordSize);
+  }
+  bool IsHeapObject() const {
+    ASSERT(IsWellFormed());
+    uword value = tagged_pointer_;
+    return (value & kSmiTagMask) == kHeapObjectTag;
+  }
+  // Assumes this is a heap object.
+  bool IsNewObject() const {
+    ASSERT(IsHeapObject());
+    uword addr = tagged_pointer_;
+    return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
+  }
+  bool IsNewObjectMayBeSmi() const {
+    static const uword kNewObjectBits =
+        (kNewObjectAlignmentOffset | kHeapObjectTag);
+    const uword addr = tagged_pointer_;
+    return (addr & kObjectAlignmentMask) == kNewObjectBits;
+  }
+  // Assumes this is a heap object.
+  bool IsOldObject() const {
+    ASSERT(IsHeapObject());
+    uword addr = tagged_pointer_;
+    return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
+  }
+
+  // Like !IsHeapObject() || IsOldObject(), but compiles to a single branch.
+  bool IsSmiOrOldObject() const {
+    ASSERT(IsWellFormed());
+    static const uword kNewObjectBits =
+        (kNewObjectAlignmentOffset | kHeapObjectTag);
+    const uword addr = tagged_pointer_;
+    return (addr & kObjectAlignmentMask) != kNewObjectBits;
+  }
+
+  // Like !IsHeapObject() || IsNewObject(), but compiles to a single branch.
+  bool IsSmiOrNewObject() const {
+    ASSERT(IsWellFormed());
+    static const uword kOldObjectBits =
+        (kOldObjectAlignmentOffset | kHeapObjectTag);
+    const uword addr = tagged_pointer_;
+    return (addr & kObjectAlignmentMask) != kOldObjectBits;
+  }
+
+#define DEFINE_IS_CID(clazz)                                                   \
+  bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
+  CLASS_LIST(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+#define DEFINE_IS_CID(clazz)                                                   \
+  bool IsTypedData##clazz() const {                                            \
+    return ((GetClassId() == kTypedData##clazz##Cid));                         \
+  }                                                                            \
+  bool IsTypedDataView##clazz() const {                                        \
+    return ((GetClassId() == kTypedData##clazz##ViewCid));                     \
+  }                                                                            \
+  bool IsExternalTypedData##clazz() const {                                    \
+    return ((GetClassId() == kExternalTypedData##clazz##Cid));                 \
+  }
+  CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+#define DEFINE_IS_CID(clazz)                                                   \
+  bool IsFfi##clazz() const { return ((GetClassId() == kFfi##clazz##Cid)); }
+  CLASS_LIST_FFI(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+  bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
+  bool IsRawNull() const { return GetClassId() == kNullCid; }
+  bool IsDartInstance() const {
+    return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
+  }
+  bool IsFreeListElement() const {
+    return ((GetClassId() == kFreeListElement));
+  }
+  bool IsForwardingCorpse() const {
+    return ((GetClassId() == kForwardingCorpse));
+  }
+  bool IsPseudoObject() const {
+    return IsFreeListElement() || IsForwardingCorpse();
+  }
+
+  intptr_t GetClassId() const;
+  intptr_t GetClassIdMayBeSmi() const {
+    return IsHeapObject() ? GetClassId() : static_cast<intptr_t>(kSmiCid);
+  }
+
+  void Validate(IsolateGroup* isolate_group) const;
+
+  bool operator==(const ObjectPtr& other) {
+    return tagged_pointer_ == other.tagged_pointer_;
+  }
+  bool operator!=(const ObjectPtr& other) {
+    return tagged_pointer_ != other.tagged_pointer_;
+  }
+  constexpr bool operator==(const ObjectPtr& other) const {
+    return tagged_pointer_ == other.tagged_pointer_;
+  }
+  constexpr bool operator!=(const ObjectPtr& other) const {
+    return tagged_pointer_ != other.tagged_pointer_;
+  }
+  bool operator==(const nullptr_t& other) { return tagged_pointer_ == 0; }
+  bool operator!=(const nullptr_t& other) { return tagged_pointer_ != 0; }
+  constexpr bool operator==(const nullptr_t& other) const {
+    return tagged_pointer_ == 0;
+  }
+  constexpr bool operator!=(const nullptr_t& other) const {
+    return tagged_pointer_ != 0;
+  }
+
+  // Use explicit null comparisons instead.
+  operator bool() const = delete;
+
+  // The underlying types of int32_t/int64_t and intptr_t are sometimes
+  // different and sometimes the same, depending on the platform. With
+  // only a conversion operator for intptr_t, on 64-bit Mac a static_cast
+  // to int64_t fails because it tries conversion to bool (!) rather than
+  // intptr_t. So we exhaustive define all the valid conversions based on
+  // the underlying types.
+#if INT_MAX == INTPTR_MAX
+  explicit operator int() const {              // NOLINT
+    return static_cast<int>(tagged_pointer_);  // NOLINT
+  }
+#endif
+#if LONG_MAX == INTPTR_MAX
+  explicit operator long() const {              // NOLINT
+    return static_cast<long>(tagged_pointer_);  // NOLINT
+  }
+#endif
+#if LLONG_MAX == INTPTR_MAX
+  explicit operator long long() const {              // NOLINT
+    return static_cast<long long>(tagged_pointer_);  // NOLINT
+  }
+#endif
+#if UINT_MAX == UINTPTR_MAX
+  explicit operator unsigned int() const {              // NOLINT
+    return static_cast<unsigned int>(tagged_pointer_);  // NOLINT
+  }
+#endif
+#if ULONG_MAX == UINTPTR_MAX
+  explicit operator unsigned long() const {              // NOLINT
+    return static_cast<unsigned long>(tagged_pointer_);  // NOLINT
+  }
+#endif
+#if ULLONG_MAX == UINTPTR_MAX
+  explicit operator unsigned long long() const {              // NOLINT
+    return static_cast<unsigned long long>(tagged_pointer_);  // NOLINT
+  }
+#endif
+
+  // Must be trivially copyable for std::atomic.
+  ObjectPtr& operator=(const ObjectPtr& other) = default;
+  constexpr ObjectPtr(const ObjectPtr& other) = default;
+
+  ObjectPtr() : tagged_pointer_(0) {}
+  explicit constexpr ObjectPtr(uword tagged) : tagged_pointer_(tagged) {}
+  explicit constexpr ObjectPtr(intptr_t tagged) : tagged_pointer_(tagged) {}
+  constexpr ObjectPtr(nullptr_t) : tagged_pointer_(0) {}  // NOLINT
+  explicit ObjectPtr(ObjectLayout* heap_object)
+      : tagged_pointer_(reinterpret_cast<uword>(heap_object) + kHeapObjectTag) {
+  }
+
+ protected:
+  uword UntaggedPointer() const {
+    ASSERT(IsHeapObject());
+    return tagged_pointer_ - kHeapObjectTag;
+  }
+
+  uword tagged_pointer_;
+};
+
+// Needed by the printing in the EXPECT macros.
+#if defined(DEBUG) || defined(TESTING)
+inline std::ostream& operator<<(std::ostream& os, const ObjectPtr& obj) {
+  os << reinterpret_cast<void*>(static_cast<uword>(obj));
+  return os;
+}
+#endif
+
+#define DEFINE_TAGGED_POINTER(klass, base)                                     \
+  class klass##Layout;                                                         \
+  class klass##Ptr : public base##Ptr {                                        \
+   public:                                                                     \
+    klass##Ptr* operator->() { return this; }                                  \
+    const klass##Ptr* operator->() const { return this; }                      \
+    klass##Layout* ptr() {                                                     \
+      return reinterpret_cast<klass##Layout*>(UntaggedPointer());              \
+    }                                                                          \
+    /* TODO: Return const pointer */                                           \
+    klass##Layout* ptr() const {                                               \
+      return reinterpret_cast<klass##Layout*>(UntaggedPointer());              \
+    }                                                                          \
+    klass##Ptr& operator=(const klass##Ptr& other) = default;                  \
+    constexpr klass##Ptr(const klass##Ptr& other) = default;                   \
+    explicit constexpr klass##Ptr(const ObjectPtr& other)                      \
+        : base##Ptr(other) {}                                                  \
+    klass##Ptr() : base##Ptr() {}                                              \
+    explicit constexpr klass##Ptr(uword tagged) : base##Ptr(tagged) {}         \
+    explicit constexpr klass##Ptr(intptr_t tagged) : base##Ptr(tagged) {}      \
+    constexpr klass##Ptr(nullptr_t) : base##Ptr(nullptr) {} /* NOLINT */       \
+    explicit klass##Ptr(const ObjectLayout* untagged)                          \
+        : base##Ptr(reinterpret_cast<uword>(untagged) + kHeapObjectTag) {}     \
+  };
+
+DEFINE_TAGGED_POINTER(Class, Object)
+DEFINE_TAGGED_POINTER(PatchClass, Object)
+DEFINE_TAGGED_POINTER(Function, Object)
+DEFINE_TAGGED_POINTER(ClosureData, Object)
+DEFINE_TAGGED_POINTER(SignatureData, Object)
+DEFINE_TAGGED_POINTER(RedirectionData, Object)
+DEFINE_TAGGED_POINTER(FfiTrampolineData, Object)
+DEFINE_TAGGED_POINTER(Field, Object)
+DEFINE_TAGGED_POINTER(Script, Object)
+DEFINE_TAGGED_POINTER(Library, Object)
+DEFINE_TAGGED_POINTER(Namespace, Object)
+DEFINE_TAGGED_POINTER(KernelProgramInfo, Object)
+DEFINE_TAGGED_POINTER(WeakSerializationReference, Object)
+DEFINE_TAGGED_POINTER(Code, Object)
+DEFINE_TAGGED_POINTER(Bytecode, Object)
+DEFINE_TAGGED_POINTER(ObjectPool, Object)
+DEFINE_TAGGED_POINTER(Instructions, Object)
+DEFINE_TAGGED_POINTER(InstructionsSection, Object)
+DEFINE_TAGGED_POINTER(PcDescriptors, Object)
+DEFINE_TAGGED_POINTER(CodeSourceMap, Object)
+DEFINE_TAGGED_POINTER(CompressedStackMaps, Object)
+DEFINE_TAGGED_POINTER(LocalVarDescriptors, Object)
+DEFINE_TAGGED_POINTER(ExceptionHandlers, Object)
+DEFINE_TAGGED_POINTER(Context, Object)
+DEFINE_TAGGED_POINTER(ContextScope, Object)
+DEFINE_TAGGED_POINTER(ParameterTypeCheck, Object)
+DEFINE_TAGGED_POINTER(SingleTargetCache, Object)
+DEFINE_TAGGED_POINTER(UnlinkedCall, Object)
+DEFINE_TAGGED_POINTER(MonomorphicSmiableCall, Object)
+DEFINE_TAGGED_POINTER(CallSiteData, Object)
+DEFINE_TAGGED_POINTER(ICData, CallSiteData)
+DEFINE_TAGGED_POINTER(MegamorphicCache, CallSiteData)
+DEFINE_TAGGED_POINTER(SubtypeTestCache, Object)
+DEFINE_TAGGED_POINTER(Error, Object)
+DEFINE_TAGGED_POINTER(ApiError, Error)
+DEFINE_TAGGED_POINTER(LanguageError, Error)
+DEFINE_TAGGED_POINTER(UnhandledException, Error)
+DEFINE_TAGGED_POINTER(UnwindError, Error)
+DEFINE_TAGGED_POINTER(Instance, Object)
+DEFINE_TAGGED_POINTER(LibraryPrefix, Instance)
+DEFINE_TAGGED_POINTER(TypeArguments, Instance)
+DEFINE_TAGGED_POINTER(AbstractType, Instance)
+DEFINE_TAGGED_POINTER(Type, AbstractType)
+DEFINE_TAGGED_POINTER(TypeRef, AbstractType)
+DEFINE_TAGGED_POINTER(TypeParameter, AbstractType)
+DEFINE_TAGGED_POINTER(Closure, Instance)
+DEFINE_TAGGED_POINTER(Number, Instance)
+DEFINE_TAGGED_POINTER(Integer, Number)
+DEFINE_TAGGED_POINTER(Smi, Integer)
+DEFINE_TAGGED_POINTER(Mint, Integer)
+DEFINE_TAGGED_POINTER(Double, Number)
+DEFINE_TAGGED_POINTER(String, Instance)
+DEFINE_TAGGED_POINTER(OneByteString, String)
+DEFINE_TAGGED_POINTER(TwoByteString, String)
+DEFINE_TAGGED_POINTER(PointerBase, Instance)
+DEFINE_TAGGED_POINTER(TypedDataBase, PointerBase)
+DEFINE_TAGGED_POINTER(TypedData, TypedDataBase)
+DEFINE_TAGGED_POINTER(TypedDataView, TypedDataBase)
+DEFINE_TAGGED_POINTER(ExternalOneByteString, String)
+DEFINE_TAGGED_POINTER(ExternalTwoByteString, String)
+DEFINE_TAGGED_POINTER(Bool, Instance)
+DEFINE_TAGGED_POINTER(Array, Instance)
+DEFINE_TAGGED_POINTER(ImmutableArray, Array)
+DEFINE_TAGGED_POINTER(GrowableObjectArray, Instance)
+DEFINE_TAGGED_POINTER(LinkedHashMap, Instance)
+DEFINE_TAGGED_POINTER(Float32x4, Instance)
+DEFINE_TAGGED_POINTER(Int32x4, Instance)
+DEFINE_TAGGED_POINTER(Float64x2, Instance)
+DEFINE_TAGGED_POINTER(ExternalTypedData, TypedDataBase)
+DEFINE_TAGGED_POINTER(Pointer, PointerBase)
+DEFINE_TAGGED_POINTER(DynamicLibrary, Instance)
+DEFINE_TAGGED_POINTER(Capability, Instance)
+DEFINE_TAGGED_POINTER(SendPort, Instance)
+DEFINE_TAGGED_POINTER(ReceivePort, Instance)
+DEFINE_TAGGED_POINTER(TransferableTypedData, Instance)
+DEFINE_TAGGED_POINTER(StackTrace, Instance)
+DEFINE_TAGGED_POINTER(RegExp, Instance)
+DEFINE_TAGGED_POINTER(WeakProperty, Instance)
+DEFINE_TAGGED_POINTER(MirrorReference, Instance)
+DEFINE_TAGGED_POINTER(UserTag, Instance)
+DEFINE_TAGGED_POINTER(FutureOr, Instance)
+#undef DEFINE_TAGGED_POINTER
+
+inline intptr_t RawSmiValue(const SmiPtr raw_value) {
+  const intptr_t value = static_cast<intptr_t>(raw_value);
+  ASSERT((value & kSmiTagMask) == kSmiTag);
+  return (value >> kSmiTagShift);
+}
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_TAGGED_POINTER_H_
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index c69446c..42c751c 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -5,7 +5,6 @@
 #include "vm/thread.h"
 
 #include "vm/dart_api_state.h"
-#include "vm/ffi_callback_trampolines.h"
 #include "vm/growable_array.h"
 #include "vm/heap/safepoint.h"
 #include "vm/isolate.h"
@@ -25,6 +24,10 @@
 #include "vm/timeline.h"
 #include "vm/zone.h"
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/ffi_callback_trampolines.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 namespace dart {
 
 #if !defined(PRODUCT)
@@ -62,11 +65,9 @@
 Thread::Thread(bool is_vm_isolate)
     : ThreadState(false),
       stack_limit_(0),
-      write_barrier_mask_(RawObject::kGenerationalBarrierMask),
+      write_barrier_mask_(ObjectLayout::kGenerationalBarrierMask),
       isolate_(NULL),
       dispatch_table_array_(NULL),
-      top_(0),
-      end_(0),
       saved_stack_limit_(0),
       stack_overflow_flags_(0),
       heap_(NULL),
@@ -234,7 +235,7 @@
 }
 #endif
 
-RawGrowableObjectArray* Thread::pending_functions() {
+GrowableObjectArrayPtr Thread::pending_functions() {
   if (pending_functions_ == GrowableObjectArray::null()) {
     pending_functions_ = GrowableObjectArray::New(Heap::kOld);
   }
@@ -253,7 +254,7 @@
   active_stacktrace_ = value.raw();
 }
 
-RawError* Thread::sticky_error() const {
+ErrorPtr Thread::sticky_error() const {
   return sticky_error_;
 }
 
@@ -266,9 +267,9 @@
   sticky_error_ = Error::null();
 }
 
-RawError* Thread::StealStickyError() {
+ErrorPtr Thread::StealStickyError() {
   NoSafepointScope no_safepoint;
-  RawError* return_value = sticky_error_;
+  ErrorPtr return_value = sticky_error_;
   sticky_error_ = Error::null();
   return return_value;
 }
@@ -291,7 +292,7 @@
   }
 }
 
-RawStackTrace* Thread::async_stack_trace() const {
+StackTracePtr Thread::async_stack_trace() const {
   return async_stack_trace_;
 }
 
@@ -300,7 +301,7 @@
   async_stack_trace_ = stack_trace.raw();
 }
 
-void Thread::set_raw_async_stack_trace(RawStackTrace* raw_stack_trace) {
+void Thread::set_raw_async_stack_trace(StackTracePtr raw_stack_trace) {
   async_stack_trace_ = raw_stack_trace;
 }
 
@@ -514,7 +515,7 @@
 #endif  // !defined(PRODUCT)
 }
 
-RawError* Thread::HandleInterrupts() {
+ErrorPtr Thread::HandleInterrupts() {
   uword interrupt_bits = GetAndClearInterrupts();
   if ((interrupt_bits & kVMInterrupt) != 0) {
     CheckForSafepoint();
@@ -538,7 +539,7 @@
             isolate()->name());
       }
       NoSafepointScope no_safepoint;
-      RawError* error = Thread::Current()->StealStickyError();
+      ErrorPtr error = Thread::Current()->StealStickyError();
       ASSERT(error->IsUnwindError());
       return error;
     }
@@ -557,7 +558,7 @@
   StoreBufferAcquire();
 }
 
-void Thread::StoreBufferAddObject(RawObject* obj) {
+void Thread::StoreBufferAddObject(ObjectPtr obj) {
   ASSERT(this == Thread::Current());
   store_buffer_block_->Push(obj);
   if (store_buffer_block_->IsFull()) {
@@ -565,7 +566,7 @@
   }
 }
 
-void Thread::StoreBufferAddObjectGC(RawObject* obj) {
+void Thread::StoreBufferAddObjectGC(ObjectPtr obj) {
   store_buffer_block_->Push(obj);
   if (store_buffer_block_->IsFull()) {
     StoreBufferBlockProcess(StoreBuffer::kIgnoreThreshold);
@@ -592,14 +593,14 @@
   DeferredMarkingStackAcquire();
 }
 
-void Thread::MarkingStackAddObject(RawObject* obj) {
+void Thread::MarkingStackAddObject(ObjectPtr obj) {
   marking_stack_block_->Push(obj);
   if (marking_stack_block_->IsFull()) {
     MarkingStackBlockProcess();
   }
 }
 
-void Thread::DeferredMarkingStackAddObject(RawObject* obj) {
+void Thread::DeferredMarkingStackAddObject(ObjectPtr obj) {
   deferred_marking_stack_block_->Push(obj);
   if (deferred_marking_stack_block_->IsFull()) {
     DeferredMarkingStackBlockProcess();
@@ -609,14 +610,14 @@
 void Thread::MarkingStackRelease() {
   MarkingStackBlock* block = marking_stack_block_;
   marking_stack_block_ = NULL;
-  write_barrier_mask_ = RawObject::kGenerationalBarrierMask;
+  write_barrier_mask_ = ObjectLayout::kGenerationalBarrierMask;
   isolate_group()->marking_stack()->PushBlock(block);
 }
 
 void Thread::MarkingStackAcquire() {
   marking_stack_block_ = isolate_group()->marking_stack()->PopEmptyBlock();
-  write_barrier_mask_ =
-      RawObject::kGenerationalBarrierMask | RawObject::kIncrementalBarrierMask;
+  write_barrier_mask_ = ObjectLayout::kGenerationalBarrierMask |
+                        ObjectLayout::kIncrementalBarrierMask;
 }
 
 void Thread::DeferredMarkingStackRelease() {
@@ -679,13 +680,13 @@
   // Visit objects in thread specific handles area.
   reusable_handles_.VisitObjectPointers(visitor);
 
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&pending_functions_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&global_object_pool_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&active_exception_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&active_stacktrace_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&sticky_error_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&async_stack_trace_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&ffi_callback_code_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&pending_functions_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&global_object_pool_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&active_exception_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&active_stacktrace_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&async_stack_trace_));
+  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&ffi_callback_code_));
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (interpreter() != NULL) {
@@ -739,9 +740,9 @@
         current_(Thread::Current()),
         op_(op) {}
 
-  void VisitPointers(RawObject** first, RawObject** last) {
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
     for (; first != last + 1; first++) {
-      RawObject* obj = *first;
+      ObjectPtr obj = *first;
       // Stores into new-space objects don't need a write barrier.
       if (obj->IsSmiOrNewObject()) continue;
 
@@ -756,17 +757,17 @@
       if (!obj->IsDartInstance() && !obj->IsContext()) continue;
 
       // Dart code won't store into canonical instances.
-      if (obj->IsCanonical()) continue;
+      if (obj->ptr()->IsCanonical()) continue;
 
       // Objects in the VM isolate heap are immutable and won't be
       // stored into. Check this condition last because there's no bit
       // in the header for it.
-      if (obj->InVMIsolateHeap()) continue;
+      if (obj->ptr()->InVMIsolateHeap()) continue;
 
       switch (op_) {
         case Thread::RestoreWriteBarrierInvariantOp::kAddToRememberedSet:
-          if (!obj->IsRemembered()) {
-            obj->AddToRememberedSet(current_);
+          if (!obj->ptr()->IsRemembered()) {
+            obj->ptr()->AddToRememberedSet(current_);
           }
           if (current_->is_marking()) {
             current_->DeferredMarkingStackAddObject(obj);
@@ -812,7 +813,7 @@
        frame = frames_iterator.NextFrame()) {
     if (frame->IsExitFrame()) {
       scan_next_dart_frame = true;
-    } else if (frame->IsDartFrame(/*validate=*/false, /*needed_for_gc=*/true)) {
+    } else if (frame->IsDartFrame(/*validate=*/false)) {
       if (scan_next_dart_frame) {
         frame->VisitObjectPointers(&visitor);
       }
@@ -861,7 +862,7 @@
   // [object] is in fact a [Code] object.
   if (object.IsCode()) {
 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value)       \
-  ASSERT((expr)->InVMIsolateHeap());                                           \
+  ASSERT((expr)->ptr()->InVMIsolateHeap());                                    \
   if (object.raw() == expr) {                                                  \
     return Thread::member_name##offset();                                      \
   }
@@ -1136,13 +1137,12 @@
 void Thread::VerifyCallbackIsolate(int32_t callback_id, uword entry) {
   NoSafepointScope _;
 
-  const RawGrowableObjectArray* const array = ffi_callback_code_;
+  const GrowableObjectArrayPtr array = ffi_callback_code_;
   if (array == GrowableObjectArray::null()) {
     FATAL("Cannot invoke callback on incorrect isolate.");
   }
 
-  const RawSmi* const length_smi =
-      GrowableObjectArray::NoSafepointLength(array);
+  const SmiPtr length_smi = GrowableObjectArray::NoSafepointLength(array);
   const intptr_t length = Smi::Value(length_smi);
 
   if (callback_id < 0 || callback_id >= length) {
@@ -1150,11 +1150,10 @@
   }
 
   if (entry != 0) {
-    RawObject** const code_array =
+    ObjectPtr* const code_array =
         Array::DataOf(GrowableObjectArray::NoSafepointData(array));
     // RawCast allocates handles in ASSERTs.
-    const RawCode* const code =
-        reinterpret_cast<RawCode*>(code_array[callback_id]);
+    const CodePtr code = static_cast<CodePtr>(code_array[callback_id]);
     if (!Code::ContainsInstructionAt(code, entry)) {
       FATAL("Cannot invoke callback on incorrect isolate.");
     }
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 1132a6e..d7cde8f 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -51,14 +51,6 @@
 class OSThread;
 class JSONObject;
 class PcDescriptors;
-class RawBool;
-class RawObject;
-class RawCode;
-class RawError;
-class RawGrowableObjectArray;
-class RawObjectPool;
-class RawStackTrace;
-class RawString;
 class RuntimeEntry;
 class Smi;
 class StackResource;
@@ -97,52 +89,66 @@
   V(TypeParameter)
 
 #define CACHED_VM_STUBS_LIST(V)                                                \
-  V(RawCode*, write_barrier_code_, StubCode::WriteBarrier().raw(), NULL)       \
-  V(RawCode*, array_write_barrier_code_, StubCode::ArrayWriteBarrier().raw(),  \
-    NULL)                                                                      \
-  V(RawCode*, fix_callers_target_code_, StubCode::FixCallersTarget().raw(),    \
-    NULL)                                                                      \
-  V(RawCode*, fix_allocation_stub_code_,                                       \
-    StubCode::FixAllocationStubTarget().raw(), NULL)                           \
-  V(RawCode*, invoke_dart_code_stub_, StubCode::InvokeDartCode().raw(), NULL)  \
-  V(RawCode*, invoke_dart_code_from_bytecode_stub_,                            \
-    StubCode::InvokeDartCodeFromBytecode().raw(), NULL)                        \
-  V(RawCode*, call_to_runtime_stub_, StubCode::CallToRuntime().raw(), NULL)    \
-  V(RawCode*, null_error_shared_without_fpu_regs_stub_,                        \
-    StubCode::NullErrorSharedWithoutFPURegs().raw(), NULL)                     \
-  V(RawCode*, null_error_shared_with_fpu_regs_stub_,                           \
-    StubCode::NullErrorSharedWithFPURegs().raw(), NULL)                        \
-  V(RawCode*, null_arg_error_shared_without_fpu_regs_stub_,                    \
+  V(CodePtr, write_barrier_code_, StubCode::WriteBarrier().raw(), nullptr)     \
+  V(CodePtr, array_write_barrier_code_, StubCode::ArrayWriteBarrier().raw(),   \
+    nullptr)                                                                   \
+  V(CodePtr, fix_callers_target_code_, StubCode::FixCallersTarget().raw(),     \
+    nullptr)                                                                   \
+  V(CodePtr, fix_allocation_stub_code_,                                        \
+    StubCode::FixAllocationStubTarget().raw(), nullptr)                        \
+  V(CodePtr, invoke_dart_code_stub_, StubCode::InvokeDartCode().raw(),         \
+    nullptr)                                                                   \
+  V(CodePtr, invoke_dart_code_from_bytecode_stub_,                             \
+    StubCode::InvokeDartCodeFromBytecode().raw(), nullptr)                     \
+  V(CodePtr, call_to_runtime_stub_, StubCode::CallToRuntime().raw(), nullptr)  \
+  V(CodePtr, null_error_shared_without_fpu_regs_stub_,                         \
+    StubCode::NullErrorSharedWithoutFPURegs().raw(), nullptr)                  \
+  V(CodePtr, null_error_shared_with_fpu_regs_stub_,                            \
+    StubCode::NullErrorSharedWithFPURegs().raw(), nullptr)                     \
+  V(CodePtr, null_arg_error_shared_without_fpu_regs_stub_,                     \
     StubCode::NullArgErrorSharedWithoutFPURegs().raw(), nullptr)               \
-  V(RawCode*, null_arg_error_shared_with_fpu_regs_stub_,                       \
+  V(CodePtr, null_arg_error_shared_with_fpu_regs_stub_,                        \
     StubCode::NullArgErrorSharedWithFPURegs().raw(), nullptr)                  \
-  V(RawCode*, allocate_mint_with_fpu_regs_stub_,                               \
-    StubCode::AllocateMintWithFPURegs().raw(), NULL)                           \
-  V(RawCode*, allocate_mint_without_fpu_regs_stub_,                            \
-    StubCode::AllocateMintWithoutFPURegs().raw(), NULL)                        \
-  V(RawCode*, stack_overflow_shared_without_fpu_regs_stub_,                    \
-    StubCode::StackOverflowSharedWithoutFPURegs().raw(), NULL)                 \
-  V(RawCode*, stack_overflow_shared_with_fpu_regs_stub_,                       \
-    StubCode::StackOverflowSharedWithFPURegs().raw(), NULL)                    \
-  V(RawCode*, monomorphic_miss_stub_, StubCode::MonomorphicMiss().raw(), NULL) \
-  V(RawCode*, optimize_stub_, StubCode::OptimizeFunction().raw(), NULL)        \
-  V(RawCode*, deoptimize_stub_, StubCode::Deoptimize().raw(), NULL)            \
-  V(RawCode*, lazy_deopt_from_return_stub_,                                    \
-    StubCode::DeoptimizeLazyFromReturn().raw(), NULL)                          \
-  V(RawCode*, lazy_deopt_from_throw_stub_,                                     \
-    StubCode::DeoptimizeLazyFromThrow().raw(), NULL)                           \
-  V(RawCode*, slow_type_test_stub_, StubCode::SlowTypeTest().raw(), NULL)      \
-  V(RawCode*, lazy_specialize_type_test_stub_,                                 \
-    StubCode::LazySpecializeTypeTest().raw(), NULL)                            \
-  V(RawCode*, enter_safepoint_stub_, StubCode::EnterSafepoint().raw(), NULL)   \
-  V(RawCode*, exit_safepoint_stub_, StubCode::ExitSafepoint().raw(), NULL)     \
-  V(RawCode*, call_native_through_safepoint_stub_,                             \
-    StubCode::CallNativeThroughSafepoint().raw(), NULL)
+  V(CodePtr, range_error_shared_without_fpu_regs_stub_,                        \
+    StubCode::RangeErrorSharedWithoutFPURegs().raw(), nullptr)                 \
+  V(CodePtr, range_error_shared_with_fpu_regs_stub_,                           \
+    StubCode::RangeErrorSharedWithFPURegs().raw(), nullptr)                    \
+  V(CodePtr, allocate_mint_with_fpu_regs_stub_,                                \
+    StubCode::AllocateMintSharedWithFPURegs().raw(), nullptr)                  \
+  V(CodePtr, allocate_mint_without_fpu_regs_stub_,                             \
+    StubCode::AllocateMintSharedWithoutFPURegs().raw(), nullptr)               \
+  V(CodePtr, allocate_object_stub_, StubCode::AllocateObject().raw(), nullptr) \
+  V(CodePtr, allocate_object_parameterized_stub_,                              \
+    StubCode::AllocateObjectParameterized().raw(), nullptr)                    \
+  V(CodePtr, allocate_object_slow_stub_, StubCode::AllocateObjectSlow().raw(), \
+    nullptr)                                                                   \
+  V(CodePtr, stack_overflow_shared_without_fpu_regs_stub_,                     \
+    StubCode::StackOverflowSharedWithoutFPURegs().raw(), nullptr)              \
+  V(CodePtr, stack_overflow_shared_with_fpu_regs_stub_,                        \
+    StubCode::StackOverflowSharedWithFPURegs().raw(), nullptr)                 \
+  V(CodePtr, switchable_call_miss_stub_, StubCode::SwitchableCallMiss().raw(), \
+    nullptr)                                                                   \
+  V(CodePtr, throw_stub_, StubCode::Throw().raw(), nullptr)                    \
+  V(CodePtr, re_throw_stub_, StubCode::Throw().raw(), nullptr)                 \
+  V(CodePtr, assert_boolean_stub_, StubCode::AssertBoolean().raw(), nullptr)   \
+  V(CodePtr, optimize_stub_, StubCode::OptimizeFunction().raw(), nullptr)      \
+  V(CodePtr, deoptimize_stub_, StubCode::Deoptimize().raw(), nullptr)          \
+  V(CodePtr, lazy_deopt_from_return_stub_,                                     \
+    StubCode::DeoptimizeLazyFromReturn().raw(), nullptr)                       \
+  V(CodePtr, lazy_deopt_from_throw_stub_,                                      \
+    StubCode::DeoptimizeLazyFromThrow().raw(), nullptr)                        \
+  V(CodePtr, slow_type_test_stub_, StubCode::SlowTypeTest().raw(), nullptr)    \
+  V(CodePtr, lazy_specialize_type_test_stub_,                                  \
+    StubCode::LazySpecializeTypeTest().raw(), nullptr)                         \
+  V(CodePtr, enter_safepoint_stub_, StubCode::EnterSafepoint().raw(), nullptr) \
+  V(CodePtr, exit_safepoint_stub_, StubCode::ExitSafepoint().raw(), nullptr)   \
+  V(CodePtr, call_native_through_safepoint_stub_,                              \
+    StubCode::CallNativeThroughSafepoint().raw(), nullptr)
 
 #define CACHED_NON_VM_STUB_LIST(V)                                             \
-  V(RawObject*, object_null_, Object::null(), NULL)                            \
-  V(RawBool*, bool_true_, Object::bool_true().raw(), NULL)                     \
-  V(RawBool*, bool_false_, Object::bool_false().raw(), NULL)
+  V(ObjectPtr, object_null_, Object::null(), nullptr)                          \
+  V(BoolPtr, bool_true_, Object::bool_true().raw(), nullptr)                   \
+  V(BoolPtr, bool_false_, Object::bool_false().raw(), nullptr)
 
 // List of VM-global objects/addresses cached in each Thread object.
 // Important: constant false must immediately follow constant true.
@@ -163,30 +169,30 @@
     StubCode::ArrayWriteBarrier().EntryPoint(), 0)                             \
   V(uword, call_to_runtime_entry_point_,                                       \
     StubCode::CallToRuntime().EntryPoint(), 0)                                 \
-  V(uword, null_error_shared_without_fpu_regs_entry_point_,                    \
-    StubCode::NullErrorSharedWithoutFPURegs().EntryPoint(), 0)                 \
-  V(uword, null_error_shared_with_fpu_regs_entry_point_,                       \
-    StubCode::NullErrorSharedWithFPURegs().EntryPoint(), 0)                    \
-  V(uword, null_arg_error_shared_without_fpu_regs_entry_point_,                \
-    StubCode::NullArgErrorSharedWithoutFPURegs().EntryPoint(), 0)              \
-  V(uword, null_arg_error_shared_with_fpu_regs_entry_point_,                   \
-    StubCode::NullArgErrorSharedWithFPURegs().EntryPoint(), 0)                 \
   V(uword, allocate_mint_with_fpu_regs_entry_point_,                           \
-    StubCode::AllocateMintWithFPURegs().EntryPoint(), 0)                       \
+    StubCode::AllocateMintSharedWithFPURegs().EntryPoint(), 0)                 \
   V(uword, allocate_mint_without_fpu_regs_entry_point_,                        \
-    StubCode::AllocateMintWithoutFPURegs().EntryPoint(), 0)                    \
+    StubCode::AllocateMintSharedWithoutFPURegs().EntryPoint(), 0)              \
+  V(uword, allocate_object_entry_point_,                                       \
+    StubCode::AllocateObject().EntryPoint(), 0)                                \
+  V(uword, allocate_object_parameterized_entry_point_,                         \
+    StubCode::AllocateObjectParameterized().EntryPoint(), 0)                   \
+  V(uword, allocate_object_slow_entry_point_,                                  \
+    StubCode::AllocateObjectSlow().EntryPoint(), 0)                            \
   V(uword, stack_overflow_shared_without_fpu_regs_entry_point_,                \
     StubCode::StackOverflowSharedWithoutFPURegs().EntryPoint(), 0)             \
   V(uword, stack_overflow_shared_with_fpu_regs_entry_point_,                   \
     StubCode::StackOverflowSharedWithFPURegs().EntryPoint(), 0)                \
   V(uword, megamorphic_call_checked_entry_,                                    \
     StubCode::MegamorphicCall().EntryPoint(), 0)                               \
-  V(uword, monomorphic_miss_entry_, StubCode::MonomorphicMiss().EntryPoint(),  \
-    0)                                                                         \
+  V(uword, switchable_call_miss_entry_,                                        \
+    StubCode::SwitchableCallMiss().EntryPoint(), 0)                            \
   V(uword, optimize_entry_, StubCode::OptimizeFunction().EntryPoint(), 0)      \
   V(uword, deoptimize_entry_, StubCode::Deoptimize().EntryPoint(), 0)          \
   V(uword, call_native_through_safepoint_entry_point_,                         \
-    StubCode::CallNativeThroughSafepoint().EntryPoint(), 0)
+    StubCode::CallNativeThroughSafepoint().EntryPoint(), 0)                    \
+  V(uword, slow_type_test_entry_point_, StubCode::SlowTypeTest().EntryPoint(), \
+    0)
 
 #define CACHED_ADDRESSES_LIST(V)                                               \
   CACHED_VM_STUBS_ADDRESSES_LIST(V)                                            \
@@ -197,7 +203,7 @@
   V(uword, auto_scope_native_wrapper_entry_point_,                             \
     NativeEntry::AutoScopeNativeCallWrapperEntry(), 0)                         \
   V(uword, interpret_call_entry_point_, RuntimeEntry::InterpretCallEntry(), 0) \
-  V(RawString**, predefined_symbols_address_, Symbols::PredefinedAddress(),    \
+  V(StringPtr*, predefined_symbols_address_, Symbols::PredefinedAddress(),     \
     NULL)                                                                      \
   V(uword, double_nan_address_, reinterpret_cast<uword>(&double_nan_constant), \
     0)                                                                         \
@@ -238,6 +244,7 @@
     kMarkerTask = 0x4,
     kSweeperTask = 0x8,
     kCompactorTask = 0x10,
+    kScavengerTask = 0x20,
   };
   // Converts a TaskKind to its corresponding C-String name.
   static const char* TaskKindToCString(TaskKind kind);
@@ -359,7 +366,7 @@
 
   void ScheduleInterrupts(uword interrupt_bits);
   void ScheduleInterruptsLocked(uword interrupt_bits);
-  RawError* HandleInterrupts();
+  ErrorPtr HandleInterrupts();
   uword GetAndClearInterrupts();
   bool HasScheduledInterrupts() const {
     return (stack_limit_ & kInterruptsMask) != 0;
@@ -454,10 +461,10 @@
     no_callback_scope_depth_ -= 1;
   }
 
-  void StoreBufferAddObject(RawObject* obj);
-  void StoreBufferAddObjectGC(RawObject* obj);
+  void StoreBufferAddObject(ObjectPtr obj);
+  void StoreBufferAddObjectGC(ObjectPtr obj);
 #if defined(TESTING)
-  bool StoreBufferContains(RawObject* obj) const {
+  bool StoreBufferContains(ObjectPtr obj) const {
     return store_buffer_block_->Contains(obj);
   }
 #endif
@@ -467,8 +474,8 @@
   }
 
   bool is_marking() const { return marking_stack_block_ != NULL; }
-  void MarkingStackAddObject(RawObject* obj);
-  void DeferredMarkingStackAddObject(RawObject* obj);
+  void MarkingStackAddObject(ObjectPtr obj);
+  void DeferredMarkingStackAddObject(ObjectPtr obj);
   void MarkingStackBlockProcess();
   void DeferredMarkingStackBlockProcess();
   static intptr_t marking_stack_block_offset() {
@@ -487,14 +494,10 @@
   Heap* heap() const { return heap_; }
   static intptr_t heap_offset() { return OFFSET_OF(Thread, heap_); }
 
-  void set_top(uword value) { top_ = value; }
-  void set_end(uword value) { end_ = value; }
-
-  uword top() { return top_; }
-  uword end() { return end_; }
-
-  bool HasActiveTLAB() { return end_ > 0; }
-
+  uword top() const { return top_; }
+  uword end() const { return end_; }
+  void set_top(uword top) { top_ = top; }
+  void set_end(uword end) { end_ = end; }
   static intptr_t top_offset() { return OFFSET_OF(Thread, top_); }
   static intptr_t end_offset() { return OFFSET_OF(Thread, end_); }
 
@@ -569,8 +572,8 @@
   LEAF_RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD)
 #undef DEFINE_OFFSET_METHOD
 
-  RawObjectPool* global_object_pool() const { return global_object_pool_; }
-  void set_global_object_pool(RawObjectPool* raw_value) {
+  ObjectPoolPtr global_object_pool() const { return global_object_pool_; }
+  void set_global_object_pool(ObjectPoolPtr raw_value) {
     global_object_pool_ = raw_value;
   }
 
@@ -605,7 +608,7 @@
     return OFFSET_OF(Thread, unboxed_int64_runtime_arg_);
   }
 
-  RawGrowableObjectArray* pending_functions();
+  GrowableObjectArrayPtr pending_functions();
   void clear_pending_functions();
 
   static intptr_t global_object_pool_offset() {
@@ -616,13 +619,13 @@
     return OFFSET_OF(Thread, dispatch_table_array_);
   }
 
-  RawObject* active_exception() const { return active_exception_; }
+  ObjectPtr active_exception() const { return active_exception_; }
   void set_active_exception(const Object& value);
   static intptr_t active_exception_offset() {
     return OFFSET_OF(Thread, active_exception_);
   }
 
-  RawObject* active_stacktrace() const { return active_stacktrace_; }
+  ObjectPtr active_stacktrace() const { return active_stacktrace_; }
   void set_active_stacktrace(const Object& value);
   static intptr_t active_stacktrace_offset() {
     return OFFSET_OF(Thread, active_stacktrace_);
@@ -632,14 +635,14 @@
   void set_resume_pc(uword value) { resume_pc_ = value; }
   static uword resume_pc_offset() { return OFFSET_OF(Thread, resume_pc_); }
 
-  RawError* sticky_error() const;
+  ErrorPtr sticky_error() const;
   void set_sticky_error(const Error& value);
   void ClearStickyError();
-  DART_WARN_UNUSED_RESULT RawError* StealStickyError();
+  DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();
 
-  RawStackTrace* async_stack_trace() const;
+  StackTracePtr async_stack_trace() const;
   void set_async_stack_trace(const StackTrace& stack_trace);
-  void set_raw_async_stack_trace(RawStackTrace* raw_stack_trace);
+  void set_raw_async_stack_trace(StackTracePtr raw_stack_trace);
   void clear_async_stack_trace();
   static intptr_t async_stack_trace_offset() {
     return OFFSET_OF(Thread, async_stack_trace_);
@@ -889,21 +892,21 @@
   uword write_barrier_mask_;
   Isolate* isolate_;
   const uword* dispatch_table_array_;
-  uword top_;
-  uword end_;
+  uword top_ = 0;
+  uword end_ = 0;
   // Offsets up to this point can all fit in a byte on X64. All of the above
   // fields are very abundantly accessed from code. Thus, keeping them first
   // is important for code size (although code size on X64 is not a priority).
   uword saved_stack_limit_;
   uword stack_overflow_flags_;
-  RawInstance** field_table_values_;
+  InstancePtr* field_table_values_;
   Heap* heap_;
   uword volatile top_exit_frame_info_;
   StoreBufferBlock* store_buffer_block_;
   MarkingStackBlock* marking_stack_block_;
   MarkingStackBlock* deferred_marking_stack_block_;
   uword volatile vm_tag_;
-  RawStackTrace* async_stack_trace_;
+  StackTracePtr async_stack_trace_;
   // Memory location dedicated for passing unboxed int64 values from
   // generated code to runtime.
   // TODO(dartbug.com/33549): Clean this up when unboxed values
@@ -930,14 +933,14 @@
 #endif
 
   // JumpToExceptionHandler state:
-  RawObject* active_exception_;
-  RawObject* active_stacktrace_;
-  RawObjectPool* global_object_pool_;
+  ObjectPtr active_exception_;
+  ObjectPtr active_stacktrace_;
+  ObjectPoolPtr global_object_pool_;
   uword resume_pc_;
   uword saved_shadow_call_stack_ = 0;
   uword execution_state_;
   std::atomic<uword> safepoint_state_;
-  RawGrowableObjectArray* ffi_callback_code_;
+  GrowableObjectArrayPtr ffi_callback_code_;
 
   // ---- End accessed from generated code. ----
 
@@ -966,16 +969,16 @@
   CompilerState* compiler_state_ = nullptr;
   HierarchyInfo* hierarchy_info_;
   TypeUsageInfo* type_usage_info_;
-  RawGrowableObjectArray* pending_functions_;
+  GrowableObjectArrayPtr pending_functions_;
 
-  RawError* sticky_error_;
+  ErrorPtr sticky_error_;
 
   Random thread_random_;
 
   intptr_t ffi_marshalled_arguments_size_ = 0;
   uint64_t* ffi_marshalled_arguments_;
 
-  RawInstance** field_table_values() const { return field_table_values_; }
+  InstancePtr* field_table_values() const { return field_table_values_; }
 
 // Reusable handles support.
 #define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_;
diff --git a/runtime/vm/thread_pool.cc b/runtime/vm/thread_pool.cc
index 22f62ca..d307f5f 100644
--- a/runtime/vm/thread_pool.cc
+++ b/runtime/vm/thread_pool.cc
@@ -15,341 +15,6 @@
             5000,
             "Free workers when they have been idle for this amount of time.");
 
-ThreadPool::ThreadPool()
-    : shutting_down_(false),
-      all_workers_(NULL),
-      idle_workers_(NULL),
-      count_started_(0),
-      count_stopped_(0),
-      count_running_(0),
-      count_idle_(0),
-      shutting_down_workers_(NULL),
-      join_list_(NULL) {}
-
-ThreadPool::~ThreadPool() {
-  Shutdown();
-}
-
-bool ThreadPool::RunImpl(std::unique_ptr<Task> task) {
-  Worker* worker = NULL;
-  bool new_worker = false;
-  {
-    // We need ThreadPool::mutex_ to access worker lists and other
-    // ThreadPool state.
-    MutexLocker ml(&mutex_);
-    if (shutting_down_) {
-      return false;
-    }
-    if (idle_workers_ == NULL) {
-      worker = new Worker(this);
-      ASSERT(worker != NULL);
-      new_worker = true;
-      count_started_++;
-
-      // Add worker to the all_workers_ list.
-      worker->all_next_ = all_workers_;
-      all_workers_ = worker;
-      worker->owned_ = true;
-      count_running_++;
-    } else {
-      // Get the first worker from the idle worker list.
-      worker = idle_workers_;
-      idle_workers_ = worker->idle_next_;
-      worker->idle_next_ = NULL;
-      count_idle_--;
-      count_running_++;
-    }
-  }
-
-  // Release ThreadPool::mutex_ before calling Worker functions.
-  ASSERT(worker != NULL);
-  worker->SetTask(std::move(task));
-  if (new_worker) {
-    // Call StartThread after we've assigned the first task.
-    worker->StartThread();
-  }
-  return true;
-}
-
-void ThreadPool::Shutdown() {
-  Worker* saved = NULL;
-  {
-    MutexLocker ml(&mutex_);
-    shutting_down_ = true;
-    saved = all_workers_;
-    all_workers_ = NULL;
-    idle_workers_ = NULL;
-
-    Worker* current = saved;
-    while (current != NULL) {
-      Worker* next = current->all_next_;
-      current->idle_next_ = NULL;
-      current->owned_ = false;
-      current = next;
-      count_stopped_++;
-    }
-
-    count_idle_ = 0;
-    count_running_ = 0;
-    ASSERT(count_started_ == count_stopped_);
-  }
-  // Release ThreadPool::mutex_ before calling Worker functions.
-
-  {
-    MonitorLocker eml(&exit_monitor_);
-
-    // First tell all the workers to shut down.
-    Worker* current = saved;
-    OSThread* os_thread = OSThread::Current();
-    ASSERT(os_thread != NULL);
-    ThreadId id = os_thread->id();
-    while (current != NULL) {
-      Worker* next = current->all_next_;
-      ThreadId currentId = current->id();
-      if (currentId != id) {
-        AddWorkerToShutdownList(current);
-      }
-      current->Shutdown();
-      current = next;
-    }
-    saved = NULL;
-
-    // Wait until all workers will exit.
-    while (shutting_down_workers_ != NULL) {
-      // Here, we are waiting for workers to exit. When a worker exits we will
-      // be notified.
-      eml.Wait();
-    }
-  }
-
-  // Extract the join list, and join on the threads.
-  JoinList* list = NULL;
-  {
-    MutexLocker ml(&mutex_);
-    list = join_list_;
-    join_list_ = NULL;
-  }
-
-  // Join non-idle threads.
-  JoinList::Join(&list);
-
-#if defined(DEBUG)
-  {
-    MutexLocker ml(&mutex_);
-    ASSERT(join_list_ == NULL);
-  }
-#endif
-}
-
-bool ThreadPool::IsIdle(Worker* worker) {
-  ASSERT(worker != NULL && worker->owned_);
-  for (Worker* current = idle_workers_; current != NULL;
-       current = current->idle_next_) {
-    if (current == worker) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ThreadPool::RemoveWorkerFromIdleList(Worker* worker) {
-  ASSERT(worker != NULL && worker->owned_);
-  if (idle_workers_ == NULL) {
-    return false;
-  }
-
-  // Special case head of list.
-  if (idle_workers_ == worker) {
-    idle_workers_ = worker->idle_next_;
-    worker->idle_next_ = NULL;
-    return true;
-  }
-
-  for (Worker* current = idle_workers_; current->idle_next_ != NULL;
-       current = current->idle_next_) {
-    if (current->idle_next_ == worker) {
-      current->idle_next_ = worker->idle_next_;
-      worker->idle_next_ = NULL;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ThreadPool::RemoveWorkerFromAllList(Worker* worker) {
-  ASSERT(worker != NULL && worker->owned_);
-  if (all_workers_ == NULL) {
-    return false;
-  }
-
-  // Special case head of list.
-  if (all_workers_ == worker) {
-    all_workers_ = worker->all_next_;
-    worker->all_next_ = NULL;
-    worker->owned_ = false;
-    worker->done_ = true;
-    return true;
-  }
-
-  for (Worker* current = all_workers_; current->all_next_ != NULL;
-       current = current->all_next_) {
-    if (current->all_next_ == worker) {
-      current->all_next_ = worker->all_next_;
-      worker->all_next_ = NULL;
-      worker->owned_ = false;
-      return true;
-    }
-  }
-  return false;
-}
-
-void ThreadPool::SetIdleLocked(Worker* worker) {
-  ASSERT(mutex_.IsOwnedByCurrentThread());
-  ASSERT(worker->owned_ && !IsIdle(worker));
-  worker->idle_next_ = idle_workers_;
-  idle_workers_ = worker;
-  count_idle_++;
-  count_running_--;
-}
-
-void ThreadPool::SetIdleAndReapExited(Worker* worker) {
-  JoinList* list = NULL;
-  {
-    MutexLocker ml(&mutex_);
-    if (shutting_down_) {
-      return;
-    }
-    if (join_list_ == NULL) {
-      // Nothing to join, add to the idle list and return.
-      SetIdleLocked(worker);
-      return;
-    }
-    // There is something to join. Grab the join list, drop the lock, do the
-    // join, then grab the lock again and add to the idle list.
-    list = join_list_;
-    join_list_ = NULL;
-  }
-  JoinList::Join(&list);
-
-  {
-    MutexLocker ml(&mutex_);
-    if (shutting_down_) {
-      return;
-    }
-    SetIdleLocked(worker);
-  }
-}
-
-bool ThreadPool::ReleaseIdleWorker(Worker* worker) {
-  MutexLocker ml(&mutex_);
-  if (shutting_down_) {
-    return false;
-  }
-  // Remove from idle list.
-  if (!RemoveWorkerFromIdleList(worker)) {
-    return false;
-  }
-  // Remove from all list.
-  bool found = RemoveWorkerFromAllList(worker);
-  ASSERT(found);
-
-  // The thread for worker will exit. Add its ThreadId to the join_list_
-  // so that we can join on it at the next opportunity.
-  OSThread* os_thread = OSThread::Current();
-  ASSERT(os_thread != NULL);
-  ThreadJoinId join_id = OSThread::GetCurrentThreadJoinId(os_thread);
-  JoinList::AddLocked(join_id, &join_list_);
-  count_stopped_++;
-  count_idle_--;
-  return true;
-}
-
-// Only call while holding the exit_monitor_
-void ThreadPool::AddWorkerToShutdownList(Worker* worker) {
-  ASSERT(exit_monitor_.IsOwnedByCurrentThread());
-  worker->shutdown_next_ = shutting_down_workers_;
-  shutting_down_workers_ = worker;
-}
-
-// Only call while holding the exit_monitor_
-bool ThreadPool::RemoveWorkerFromShutdownList(Worker* worker) {
-  ASSERT(worker != NULL);
-  ASSERT(shutting_down_workers_ != NULL);
-  ASSERT(exit_monitor_.IsOwnedByCurrentThread());
-
-  // Special case head of list.
-  if (shutting_down_workers_ == worker) {
-    shutting_down_workers_ = worker->shutdown_next_;
-    worker->shutdown_next_ = NULL;
-    return true;
-  }
-
-  for (Worker* current = shutting_down_workers_;
-       current->shutdown_next_ != NULL; current = current->shutdown_next_) {
-    if (current->shutdown_next_ == worker) {
-      current->shutdown_next_ = worker->shutdown_next_;
-      worker->shutdown_next_ = NULL;
-      return true;
-    }
-  }
-  return false;
-}
-
-void ThreadPool::JoinList::AddLocked(ThreadJoinId id, JoinList** list) {
-  *list = new JoinList(id, *list);
-}
-
-void ThreadPool::JoinList::Join(JoinList** list) {
-  while (*list != NULL) {
-    JoinList* current = *list;
-    *list = current->next();
-    OSThread::Join(current->id());
-    delete current;
-  }
-}
-
-ThreadPool::Task::Task() {}
-
-ThreadPool::Task::~Task() {}
-
-ThreadPool::Worker::Worker(ThreadPool* pool)
-    : pool_(pool),
-      task_(nullptr),
-      id_(OSThread::kInvalidThreadId),
-      done_(false),
-      owned_(false),
-      all_next_(NULL),
-      idle_next_(NULL),
-      shutdown_next_(NULL) {}
-
-ThreadId ThreadPool::Worker::id() {
-  MonitorLocker ml(&monitor_);
-  return id_;
-}
-
-void ThreadPool::Worker::StartThread() {
-#if defined(DEBUG)
-  // Must call SetTask before StartThread.
-  {  // NOLINT
-    MonitorLocker ml(&monitor_);
-    ASSERT(task_ != nullptr);
-  }
-#endif
-  int result = OSThread::Start("DartWorker", &Worker::Main,
-                               reinterpret_cast<uword>(this));
-  if (result != 0) {
-    FATAL1("Could not start worker thread: result = %d.", result);
-  }
-}
-
-void ThreadPool::Worker::SetTask(std::unique_ptr<Task> task) {
-  std::atomic_thread_fence(std::memory_order_release);
-  MonitorLocker ml(&monitor_);
-  ASSERT(task_ == nullptr);
-  task_ = std::move(task);
-  ml.Notify();
-}
-
 static int64_t ComputeTimeout(int64_t idle_start) {
   int64_t worker_timeout_micros =
       FLAG_worker_timeout_millis * kMicrosecondsPerMillisecond;
@@ -369,110 +34,217 @@
   }
 }
 
-bool ThreadPool::Worker::Loop() {
-  MonitorLocker ml(&monitor_);
-  int64_t idle_start;
-  while (true) {
-    ASSERT(task_ != nullptr);
-    std::unique_ptr<Task> task = std::move(task_);
+ThreadPool::ThreadPool() : all_workers_dead_(false) {}
 
-    // Release monitor while handling the task.
-    ml.Exit();
-    std::atomic_thread_fence(std::memory_order_acquire);
-    task->Run();
-    ASSERT(Isolate::Current() == NULL);
-    task.reset();
-    ml.Enter();
+ThreadPool::~ThreadPool() {
+  TriggerShutdown();
 
-    ASSERT(task_ == nullptr);
-    if (IsDone()) {
+  // Wait until all workers are dead. Any new death will notify the exit
+  // monitor.
+  {
+    MonitorLocker eml(&exit_monitor_);
+    while (!all_workers_dead_) {
+      eml.Wait();
+    }
+  }
+
+  // Join all dead workers.
+  WorkerList dead_workers_to_join;
+  {
+    MonitorLocker ml(&pool_monitor_);
+    ObtainDeadWorkersLocked(&dead_workers_to_join);
+  }
+  JoinDeadWorkersLocked(&dead_workers_to_join);
+}
+
+bool ThreadPool::RunImpl(std::unique_ptr<Task> task) {
+  Worker* new_worker = nullptr;
+  {
+    MonitorLocker ml(&pool_monitor_);
+    if (shutting_down_) {
       return false;
     }
-    ASSERT(!done_);
-    pool_->SetIdleAndReapExited(this);
-    idle_start = OS::GetCurrentMonotonicMicros();
-    while (true) {
-      Monitor::WaitResult result = ml.WaitMicros(ComputeTimeout(idle_start));
-      if (task_ != nullptr) {
-        // We've found a task.  Process it, regardless of whether the
-        // worker is done_.
+    new_worker = ScheduleTaskLocked(&ml, std::move(task));
+  }
+  if (new_worker != nullptr) {
+    new_worker->StartThread();
+  }
+  return true;
+}
+
+void ThreadPool::WorkerLoop(Worker* worker) {
+  WorkerList dead_workers_to_join;
+
+  while (true) {
+    MonitorLocker ml(&pool_monitor_);
+
+    if (!tasks_.IsEmpty()) {
+      IdleToRunningLocked(worker);
+      while (!tasks_.IsEmpty()) {
+        std::unique_ptr<Task> task(tasks_.RemoveFirst());
+        pending_tasks_--;
+        MonitorLeaveScope mls(&ml);
+        task->Run();
+        ASSERT(Isolate::Current() == nullptr);
+        task.reset();
+      }
+      RunningToIdleLocked(worker);
+    }
+
+    if (shutting_down_) {
+      ObtainDeadWorkersLocked(&dead_workers_to_join);
+      IdleToDeadLocked(worker);
+      break;
+    }
+
+    // Sleep until we get a new task, we time out or we're shutdown.
+    const int64_t idle_start = OS::GetCurrentMonotonicMicros();
+    bool done = false;
+    while (!done) {
+      const auto result = ml.WaitMicros(ComputeTimeout(idle_start));
+
+      // We have to drain all pending tasks.
+      if (!tasks_.IsEmpty()) break;
+
+      if (shutting_down_ || result == Monitor::kTimedOut) {
+        done = true;
         break;
       }
-      if (IsDone()) {
-        return false;
-      }
-      if ((result == Monitor::kTimedOut) && pool_->ReleaseIdleWorker(this)) {
-        return true;
-      }
+    }
+    if (done) {
+      ObtainDeadWorkersLocked(&dead_workers_to_join);
+      IdleToDeadLocked(worker);
+      break;
     }
   }
-  UNREACHABLE();
-  return false;
+
+  // Before we transitioned to dead we obtained the list of previously died dead
+  // workers, which we join here. Since every death of a worker will join
+  // previously died workers, we keep the pending non-joined [dead_workers_] to
+  // effectively 1.
+  JoinDeadWorkersLocked(&dead_workers_to_join);
 }
 
-void ThreadPool::Worker::Shutdown() {
-  MonitorLocker ml(&monitor_);
-  done_ = true;
-  ml.Notify();
-}
+void ThreadPool::TriggerShutdown() {
+  MonitorLocker ml(&pool_monitor_);
 
-// static
-void ThreadPool::Worker::Main(uword args) {
-  Worker* worker = reinterpret_cast<Worker*>(args);
-  OSThread* os_thread = OSThread::Current();
-  ASSERT(os_thread != NULL);
-  ThreadId id = os_thread->id();
-  ThreadPool* pool;
+  // Prevent scheduling of new tasks.
+  shutting_down_ = true;
 
-  {
-    MonitorLocker ml(&worker->monitor_);
-    ASSERT(worker->task_);
-    worker->id_ = id;
-    pool = worker->pool_;
+  if (running_workers_.IsEmpty() && idle_workers_.IsEmpty()) {
+    // All workers have already died.
+    all_workers_dead_ = true;
+  } else {
+    // Tell workers to drain remaining work and then shut down.
+    ml.NotifyAll();
   }
+}
 
-  bool released = worker->Loop();
+void ThreadPool::IdleToRunningLocked(Worker* worker) {
+  ASSERT(idle_workers_.ContainsForDebugging(worker));
+  idle_workers_.Remove(worker);
+  running_workers_.Append(worker);
+  count_idle_--;
+  count_running_++;
+}
 
-  // It should be okay to access these unlocked here in this assert.
-  // worker->all_next_ is retained by the pool for shutdown monitoring.
-  ASSERT(!worker->owned_ && (worker->idle_next_ == NULL));
+void ThreadPool::RunningToIdleLocked(Worker* worker) {
+  ASSERT(tasks_.IsEmpty());
 
-  if (!released) {
-    // This worker is exiting because the thread pool is being shut down.
-    // Inform the thread pool that we are exiting. We remove this worker from
-    // shutting_down_workers_ list because there will be no need for the
-    // ThreadPool to take action for this worker.
-    ThreadJoinId join_id = OSThread::GetCurrentThreadJoinId(os_thread);
-    {
-      MutexLocker ml(&pool->mutex_);
-      JoinList::AddLocked(join_id, &pool->join_list_);
-    }
+  ASSERT(running_workers_.ContainsForDebugging(worker));
+  running_workers_.Remove(worker);
+  idle_workers_.Append(worker);
+  count_running_--;
+  count_idle_++;
+}
 
-// worker->id_ should never be read again, so set to invalid in debug mode
-// for asserts.
-#if defined(DEBUG)
-    {
-      MonitorLocker ml(&worker->monitor_);
-      worker->id_ = OSThread::kInvalidThreadId;
-    }
-#endif
+void ThreadPool::IdleToDeadLocked(Worker* worker) {
+  ASSERT(tasks_.IsEmpty());
 
-    // Remove from the shutdown list, delete, and notify the thread pool.
-    {
-      MonitorLocker eml(&pool->exit_monitor_);
-      pool->RemoveWorkerFromShutdownList(worker);
-      delete worker;
+  ASSERT(idle_workers_.ContainsForDebugging(worker));
+  idle_workers_.Remove(worker);
+  dead_workers_.Append(worker);
+  count_idle_--;
+  count_dead_++;
+
+  // Notify shutdown thread that the worker thread is about to finish.
+  if (shutting_down_) {
+    if (running_workers_.IsEmpty() && idle_workers_.IsEmpty()) {
+      all_workers_dead_ = true;
+      MonitorLocker eml(&exit_monitor_);
       eml.Notify();
     }
-  } else {
-    // This worker is going down because it was idle for too long. This case
-    // is not due to a ThreadPool Shutdown. Thus, we simply delete the worker.
-    // The worker's id is added to the thread pool's join list by
-    // ReleaseIdleWorker, so in the case that the thread pool begins shutting
-    // down immediately after returning from worker->Loop() above, we still
-    // wait for the thread to exit by joining on it in Shutdown().
+  }
+}
+
+void ThreadPool::ObtainDeadWorkersLocked(WorkerList* dead_workers_to_join) {
+  dead_workers_to_join->AppendList(&dead_workers_);
+  ASSERT(dead_workers_.IsEmpty());
+  count_dead_ = 0;
+}
+
+void ThreadPool::JoinDeadWorkersLocked(WorkerList* dead_workers_to_join) {
+  auto it = dead_workers_to_join->begin();
+  while (it != dead_workers_to_join->end()) {
+    Worker* worker = *it;
+    it = dead_workers_to_join->Erase(it);
+
+    OSThread::Join(worker->join_id_);
     delete worker;
   }
+  ASSERT(dead_workers_to_join->IsEmpty());
+}
+
+ThreadPool::Worker* ThreadPool::ScheduleTaskLocked(MonitorLocker* ml,
+                                                   std::unique_ptr<Task> task) {
+  // Enqueue the new task.
+  tasks_.Append(task.release());
+  pending_tasks_++;
+  ASSERT(pending_tasks_ >= 1);
+
+  // Notify existing idle worker (if available).
+  if (count_idle_ >= pending_tasks_) {
+    ASSERT(!idle_workers_.IsEmpty());
+    ml->Notify();
+    return nullptr;
+  }
+
+  // Otherwise start a new worker.
+  auto new_worker = new Worker(this);
+  idle_workers_.Append(new_worker);
+  count_idle_++;
+  return new_worker;
+}
+
+ThreadPool::Worker::Worker(ThreadPool* pool)
+    : pool_(pool), join_id_(OSThread::kInvalidThreadJoinId) {}
+
+void ThreadPool::Worker::StartThread() {
+  int result = OSThread::Start("DartWorker", &Worker::Main,
+                               reinterpret_cast<uword>(this));
+  if (result != 0) {
+    FATAL1("Could not start worker thread: result = %d.", result);
+  }
+}
+
+void ThreadPool::Worker::Main(uword args) {
+  OSThread* os_thread = OSThread::Current();
+  ASSERT(os_thread != nullptr);
+
+  Worker* worker = reinterpret_cast<Worker*>(args);
+  ThreadPool* pool = worker->pool_;
+
+  // Once the worker quits it needs to be joined.
+  worker->join_id_ = OSThread::GetCurrentThreadJoinId(os_thread);
+
+#if defined(DEBUG)
+  {
+    MonitorLocker ml(&pool->pool_monitor_);
+    ASSERT(pool->idle_workers_.ContainsForDebugging(worker));
+  }
+#endif
+
+  pool->WorkerLoop(worker);
 
   // Call the thread exit hook here to notify the embedder that the
   // thread pool thread is exiting.
diff --git a/runtime/vm/thread_pool.h b/runtime/vm/thread_pool.h
index 5a1ff54..08fc19d 100644
--- a/runtime/vm/thread_pool.h
+++ b/runtime/vm/thread_pool.h
@@ -10,19 +10,22 @@
 
 #include "vm/allocation.h"
 #include "vm/globals.h"
+#include "vm/intrusive_dlist.h"
 #include "vm/os_thread.h"
 
 namespace dart {
 
+class MonitorLocker;
+
 class ThreadPool {
  public:
   // Subclasses of Task are able to run on a ThreadPool.
-  class Task {
+  class Task : public IntrusiveDListEntry<Task> {
    protected:
-    Task();
+    Task() {}
 
    public:
-    virtual ~Task();
+    virtual ~Task() {}
 
     // Override this to provide task-specific behavior.
     virtual void Run() = 0;
@@ -32,10 +35,7 @@
   };
 
   ThreadPool();
-
-  // Shuts down this thread pool. Causes workers to terminate
-  // themselves when they are active again.
-  ~ThreadPool();
+  virtual ~ThreadPool();
 
   // Runs a task on the thread pool.
   template <typename T, typename... Args>
@@ -43,110 +43,65 @@
     return RunImpl(std::unique_ptr<Task>(new T(std::forward<Args>(args)...)));
   }
 
-  // Some simple stats.
-  uint64_t workers_running() const { return count_running_; }
-  uint64_t workers_idle() const { return count_idle_; }
-  uint64_t workers_started() const { return count_started_; }
-  uint64_t workers_stopped() const { return count_stopped_; }
+  // Trigger shutdown, prevents scheduling of new tasks.
+  void TriggerShutdown();
+
+  // Exposed for unit test in thread_pool_test.cc
+  uint64_t workers_started() const { return count_idle_ + count_running_; }
+  // Exposed for unit test in thread_pool_test.cc
+  uint64_t workers_stopped() const { return count_dead_; }
 
  private:
-  class Worker {
+  class Worker : public IntrusiveDListEntry<Worker> {
    public:
     explicit Worker(ThreadPool* pool);
 
-    // Sets a task on the worker.
-    void SetTask(std::unique_ptr<Task> task);
-
     // Starts the thread for the worker.  This should only be called
     // after a task has been set by the initial call to SetTask().
     void StartThread();
 
-    // Main loop for a worker. Returns true if worker is removed from thread
-    // lists, false otherwise.
-    bool Loop();
-
-    // Causes worker to terminate eventually.
-    void Shutdown();
-
-    // Get the Worker's thread id.
-    ThreadId id();
-
    private:
     friend class ThreadPool;
 
     // The main entry point for new worker threads.
     static void Main(uword args);
 
-    bool IsDone() const { return done_; }
-
-    // Fields owned by Worker.
-    Monitor monitor_;
+    // Fields initialized during construction or in start of main function of
+    // thread.
     ThreadPool* pool_;
-    std::unique_ptr<Task> task_;
-    ThreadId id_;
-    bool done_;
-
-    // Fields owned by ThreadPool.  Workers should not look at these
-    // directly.  It's like looking at the sun.
-    bool owned_;         // Protected by ThreadPool::mutex_
-    Worker* all_next_;   // Protected by ThreadPool::mutex_
-    Worker* idle_next_;  // Protected by ThreadPool::mutex_
-
-    Worker* shutdown_next_;  // Protected by ThreadPool::exit_monitor
+    ThreadJoinId join_id_;
 
     DISALLOW_COPY_AND_ASSIGN(Worker);
   };
 
-  class JoinList {
-   public:
-    explicit JoinList(ThreadJoinId id, JoinList* next) : id_(id), next_(next) {}
-
-    // The thread pool's mutex_ must be held when calling this.
-    static void AddLocked(ThreadJoinId id, JoinList** list);
-
-    static void Join(JoinList** list);
-
-    ThreadJoinId id() const { return id_; }
-    JoinList* next() const { return next_; }
-
-   private:
-    ThreadJoinId id_;
-    JoinList* next_;
-
-    DISALLOW_COPY_AND_ASSIGN(JoinList);
-  };
+ private:
+  using TaskList = IntrusiveDList<Task>;
+  using WorkerList = IntrusiveDList<Worker>;
 
   bool RunImpl(std::unique_ptr<Task> task);
-  void Shutdown();
+  void WorkerLoop(Worker* worker);
 
-  // Expensive.  Use only in assertions.
-  bool IsIdle(Worker* worker);
+  Worker* ScheduleTaskLocked(MonitorLocker* ml, std::unique_ptr<Task> task);
 
-  bool RemoveWorkerFromIdleList(Worker* worker);
-  bool RemoveWorkerFromAllList(Worker* worker);
+  void IdleToRunningLocked(Worker* worker);
+  void RunningToIdleLocked(Worker* worker);
+  void IdleToDeadLocked(Worker* worker);
+  void ObtainDeadWorkersLocked(WorkerList* dead_workers_to_join);
+  void JoinDeadWorkersLocked(WorkerList* dead_workers_to_join);
 
-  void AddWorkerToShutdownList(Worker* worker);
-  bool RemoveWorkerFromShutdownList(Worker* worker);
-
-  void ReapExitedIdleThreads();
-
-  // Worker operations.
-  void SetIdleLocked(Worker* worker);  // Assumes mutex_ is held.
-  void SetIdleAndReapExited(Worker* worker);
-  bool ReleaseIdleWorker(Worker* worker);
-
-  Mutex mutex_;
-  bool shutting_down_;
-  Worker* all_workers_;
-  Worker* idle_workers_;
-  uint64_t count_started_;
-  uint64_t count_stopped_;
-  uint64_t count_running_;
-  uint64_t count_idle_;
+  Monitor pool_monitor_;
+  bool shutting_down_ = false;
+  uint64_t count_running_ = 0;
+  uint64_t count_idle_ = 0;
+  uint64_t count_dead_ = 0;
+  WorkerList running_workers_;
+  WorkerList idle_workers_;
+  WorkerList dead_workers_;
+  uint64_t pending_tasks_ = 0;
+  TaskList tasks_;
 
   Monitor exit_monitor_;
-  Worker* shutting_down_workers_;
-  JoinList* join_list_;
+  std::atomic<bool> all_workers_dead_;
 
   DISALLOW_COPY_AND_ASSIGN(ThreadPool);
 };
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 70a4da9..3465d48 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -85,8 +85,8 @@
   explicit ObjectCounter(IsolateGroup* isolate_group, const Object* obj)
       : ObjectPointerVisitor(isolate_group), obj_(obj), count_(0) {}
 
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; ++current) {
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+    for (ObjectPtr* current = first; current <= last; ++current) {
       if (*current == obj_->raw()) {
         ++count_;
       }
@@ -465,8 +465,8 @@
   const String& function_name =
       String::ZoneHandle(Symbols::New(Thread::Current(), name));
   Function& function = Function::ZoneHandle(Function::New(
-      function_name, RawFunction::kRegularFunction, true, false, false, false,
-      false, owner_class, TokenPosition::kNoSource));
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, owner_class, TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 48d4884..afbd027 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -1321,13 +1321,13 @@
 }
 
 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
-    : head_(NULL), block_index_(0) {}
+    : head_(nullptr), tail_(nullptr), block_index_(0) {}
 
 TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() {
   TimelineEventBlock* current = head_;
-  head_ = NULL;
+  head_ = tail_ = nullptr;
 
-  while (current != NULL) {
+  while (current != nullptr) {
     TimelineEventBlock* next = current->next();
     delete current;
     current = next;
@@ -1374,45 +1374,30 @@
 
 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() {
   TimelineEventBlock* block = new TimelineEventBlock(block_index_++);
-  block->set_next(head_);
   block->Open();
-  head_ = block;
+  if (head_ == nullptr) {
+    head_ = tail_ = block;
+  } else {
+    tail_->set_next(block);
+    tail_ = block;
+  }
   if (FLAG_trace_timeline) {
     OS::PrintErr("Created new block %p\n", block);
   }
-  return head_;
+  return block;
 }
 
 #ifndef PRODUCT
-static int TimelineEventBlockCompare(TimelineEventBlock* const* a,
-                                     TimelineEventBlock* const* b) {
-  return (*a)->LowerTimeBound() - (*b)->LowerTimeBound();
-}
-
 void TimelineEventEndlessRecorder::PrintJSONEvents(
     JSONArray* events,
     TimelineEventFilter* filter) {
   MutexLocker ml(&lock_);
   ResetTimeTracking();
-  // Collect all interesting blocks.
-  MallocGrowableArray<TimelineEventBlock*> blocks(8);
-  TimelineEventBlock* current = head_;
-  while (current != NULL) {
-    if (filter->IncludeBlock(current)) {
-      blocks.Add(current);
+  for (TimelineEventBlock* current = head_; current != nullptr;
+       current = current->next()) {
+    if (!filter->IncludeBlock(current)) {
+      continue;
     }
-    current = current->next();
-  }
-  // Bail early.
-  if (blocks.length() == 0) {
-    return;
-  }
-  // Sort the interesting blocks so that blocks with earlier events are
-  // outputted first.
-  blocks.Sort(TimelineEventBlockCompare);
-  // Output blocks in sorted order.
-  for (intptr_t block_idx = 0; block_idx < blocks.length(); block_idx++) {
-    current = blocks[block_idx];
     intptr_t length = current->length();
     for (intptr_t i = 0; i < length; i++) {
       TimelineEvent* event = current->At(i);
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 8e4199f..8841258 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -31,7 +31,6 @@
 class Object;
 class ObjectPointerVisitor;
 class Isolate;
-class RawArray;
 class Thread;
 class TimelineEvent;
 class TimelineEventBlock;
@@ -867,6 +866,7 @@
 #endif
 
   TimelineEventBlock* head_;
+  TimelineEventBlock* tail_;
   intptr_t block_index_;
 
   friend class TimelineTestHelper;
diff --git a/runtime/vm/type_table.h b/runtime/vm/type_table.h
index e9c21a2..003e8e8 100644
--- a/runtime/vm/type_table.h
+++ b/runtime/vm/type_table.h
@@ -44,7 +44,7 @@
     return Type::Cast(key).Hash();
   }
   static uword Hash(const CanonicalTypeKey& key) { return key.Hash(); }
-  static RawObject* NewKey(const CanonicalTypeKey& obj) {
+  static ObjectPtr NewKey(const CanonicalTypeKey& obj) {
     return obj.key_.raw();
   }
 };
@@ -85,7 +85,7 @@
     return TypeArguments::Cast(key).Hash();
   }
   static uword Hash(const CanonicalTypeArgumentsKey& key) { return key.Hash(); }
-  static RawObject* NewKey(const CanonicalTypeArgumentsKey& obj) {
+  static ObjectPtr NewKey(const CanonicalTypeArgumentsKey& obj) {
     return obj.key_.raw();
   }
 };
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 45ea803..b07969d 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -4,10 +4,14 @@
 
 #include "vm/type_testing_stubs.h"
 #include "vm/compiler/assembler/disassembler.h"
+#include "vm/object_store.h"
+#include "vm/stub_code.h"
+#include "vm/timeline.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/il_printer.h"
-#include "vm/object_store.h"
-#include "vm/timeline.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #define __ assembler->
 
@@ -24,12 +28,8 @@
 
 const char* TypeTestingStubNamer::StubNameForType(
     const AbstractType& type) const {
-  NoSafepointScope no_safepoint;
-  const uintptr_t address =
-      reinterpret_cast<uintptr_t>(type.raw()) & 0x7fffffff;
   Zone* Z = Thread::Current()->zone();
-  return OS::SCreate(Z, "TypeTestingStub_%s__%" Pd "", StringifyType(type),
-                     address);
+  return OS::SCreate(Z, "TypeTestingStub_%s", StringifyType(type));
 }
 
 const char* TypeTestingStubNamer::StringifyType(
@@ -88,7 +88,7 @@
   return cname;
 }
 
-RawCode* TypeTestingStubGenerator::DefaultCodeForType(
+CodePtr TypeTestingStubGenerator::DefaultCodeForType(
     const AbstractType& type,
     bool lazy_specialize /* = true */) {
   if (type.IsTypeRef()) {
@@ -102,11 +102,11 @@
   if (!StubCode::HasBeenInitialized()) {
     ASSERT(type.IsType());
     const classid_t cid = type.type_class_id();
-    ASSERT(cid == kDynamicCid || cid == kVoidCid || cid == kNeverCid);
+    ASSERT(cid == kDynamicCid || cid == kVoidCid);
     return Code::null();
   }
 
-  if (type.IsTopTypeForAssignability()) {
+  if (type.IsTopTypeForSubtyping()) {
     return StubCode::TopTypeTypeTest().raw();
   }
 
@@ -139,7 +139,7 @@
 TypeTestingStubGenerator::TypeTestingStubGenerator()
     : object_store_(Isolate::Current()->object_store()) {}
 
-RawCode* TypeTestingStubGenerator::OptimizedCodeForType(
+CodePtr TypeTestingStubGenerator::OptimizedCodeForType(
     const AbstractType& type) {
 #if !defined(TARGET_ARCH_IA32)
   ASSERT(StubCode::HasBeenInitialized());
@@ -149,7 +149,7 @@
         type, /*lazy_specialize=*/false);
   }
 
-  if (type.IsTopTypeForAssignability()) {
+  if (type.IsTopTypeForSubtyping()) {
     return StubCode::TopTypeTypeTest().raw();
   }
 
@@ -178,8 +178,9 @@
 #if !defined(TARGET_ARCH_IA32)
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
-RawCode* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
+CodePtr TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
   auto thread = Thread::Current();
+  auto zone = thread->zone();
   HierarchyInfo* hi = thread->hierarchy_info();
   ASSERT(hi != NULL);
 
@@ -191,9 +192,20 @@
   const Class& type_class = Class::Handle(type.type_class());
   ASSERT(!type_class.IsNull());
 
+  auto& slow_tts_stub = Code::ZoneHandle(zone);
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    slow_tts_stub = thread->isolate()->object_store()->slow_tts_stub();
+  }
+
   // To use the already-defined __ Macro !
   compiler::Assembler assembler(nullptr);
-  BuildOptimizedTypeTestStub(&assembler, hi, type, type_class);
+  compiler::UnresolvedPcRelativeCalls unresolved_calls;
+  BuildOptimizedTypeTestStub(&assembler, &unresolved_calls, slow_tts_stub, hi,
+                             type, type_class);
+
+  const auto& static_calls_table =
+      Array::Handle(zone, compiler::StubCodeCompiler::BuildStaticCallsTable(
+                              zone, &unresolved_calls));
 
   const char* name = namer_.StubNameForType(type);
   const auto pool_attachment = FLAG_use_bare_instructions
@@ -204,6 +216,9 @@
   auto install_code_fun = [&]() {
     code = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
                               /*optimized=*/false, /*stats=*/nullptr);
+    if (!static_calls_table.IsNull()) {
+      code.set_static_calls_target_table(static_calls_table);
+    }
   };
 
   // We have to ensure no mutators are running, because:
@@ -240,7 +255,7 @@
     const Type& type,
     const Class& type_class) {
   // These are handled via the TopTypeTypeTestStub!
-  ASSERT(!type.IsTopTypeForAssignability());
+  ASSERT(!type.IsTopTypeForSubtyping());
 
   // Fast case for 'int'.
   if (type.IsIntType()) {
@@ -405,7 +420,7 @@
     const AbstractType& type_arg,
     intptr_t type_param_value_offset_i,
     compiler::Label* check_failed) {
-  if (type_arg.IsTopType()) {
+  if (type_arg.IsTopTypeForSubtyping()) {
     return;
   }
 
@@ -584,6 +599,7 @@
 
 #else  // !defined(TARGET_ARCH_IA32)
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 void RegisterTypeArgumentsUse(const Function& function,
                               TypeUsageInfo* type_usage_info,
                               const Class& klass,
@@ -591,6 +607,7 @@
   // We only have a [TypeUsageInfo] object available durin AOT compilation.
   UNREACHABLE();
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #endif  // !defined(TARGET_ARCH_IA32)
 
@@ -616,7 +633,7 @@
   return *instantiated_type_arguments;
 }
 
-RawAbstractType* TypeArgumentInstantiator::InstantiateType(
+AbstractTypePtr TypeArgumentInstantiator::InstantiateType(
     const AbstractType& type) {
   if (type.IsTypeParameter()) {
     const TypeParameter& parameter = TypeParameter::Cast(type);
@@ -924,7 +941,7 @@
     CollectTypes(GrowableArray<AbstractType*>* types, Zone* zone)
         : types_(types), object_(Object::Handle(zone)), zone_(zone) {}
 
-    void VisitObject(RawObject* object) {
+    void VisitObject(ObjectPtr object) {
       if (object->IsPseudoObject()) {
         // Cannot even be wrapped in handles.
         return;
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
index fa9bb07..f4a64ff 100644
--- a/runtime/vm/type_testing_stubs.h
+++ b/runtime/vm/type_testing_stubs.h
@@ -5,12 +5,16 @@
 #ifndef RUNTIME_VM_TYPE_TESTING_STUBS_H_
 #define RUNTIME_VM_TYPE_TESTING_STUBS_H_
 
+#include "vm/object.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/il.h"
+#include "vm/compiler/stub_code_compiler.h"
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
 
-
 class TypeTestingStubNamer {
  public:
   TypeTestingStubNamer();
@@ -37,8 +41,8 @@
   // During bootstrapping it will return `null` for a whitelisted set of types,
   // otherwise it will return a default stub which tail-calls
   // subtypingtest/runtime code.
-  static RawCode* DefaultCodeForType(const AbstractType& type,
-                                     bool lazy_specialize = true);
+  static CodePtr DefaultCodeForType(const AbstractType& type,
+                                    bool lazy_specialize = true);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   static void SpecializeStubFor(Thread* thread, const AbstractType& type);
@@ -48,16 +52,19 @@
 
   // Creates new stub for [type] (and registers the tuple in object store
   // array) or returns default stub.
-  RawCode* OptimizedCodeForType(const AbstractType& type);
+  CodePtr OptimizedCodeForType(const AbstractType& type);
 
  private:
 #if !defined(TARGET_ARCH_IA32)
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  RawCode* BuildCodeForType(const Type& type);
-  static void BuildOptimizedTypeTestStub(compiler::Assembler* assembler,
-                                         HierarchyInfo* hi,
-                                         const Type& type,
-                                         const Class& type_class);
+  CodePtr BuildCodeForType(const Type& type);
+  static void BuildOptimizedTypeTestStub(
+      compiler::Assembler* assembler,
+      compiler::UnresolvedPcRelativeCalls* unresolved_calls,
+      const Code& slow_type_test_stub,
+      HierarchyInfo* hi,
+      const Type& type,
+      const Class& type_class);
 
   static void BuildOptimizedTypeTestStubFastCases(
       compiler::Assembler* assembler,
@@ -240,7 +247,7 @@
         type_arguments_handles_(zone),
         type_handles_(zone) {}
 
-  RawTypeArguments* Instantiate(
+  TypeArgumentsPtr Instantiate(
       const Class& klass,
       const TypeArguments& type_arguments,
       const TypeArguments& instantiator_type_arguments) {
@@ -253,7 +260,7 @@
       const Class& klass,
       const TypeArguments& type_arguments);
 
-  RawAbstractType* InstantiateType(const AbstractType& type);
+  AbstractTypePtr InstantiateType(const AbstractType& type);
 
   Class& klass_;
   AbstractType& type_;
@@ -369,10 +376,12 @@
   Class& klass_;
 };
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 void RegisterTypeArgumentsUse(const Function& function,
                               TypeUsageInfo* type_usage_info,
                               const Class& klass,
                               Definition* type_arguments);
+#endif
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
diff --git a/runtime/vm/type_testing_stubs_arm.cc b/runtime/vm/type_testing_stubs_arm.cc
deleted file mode 100644
index 6b176ce..0000000
--- a/runtime/vm/type_testing_stubs_arm.cc
+++ /dev/null
@@ -1,31 +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/globals.h"
-
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/type_testing_stubs.h"
-
-#define __ assembler->
-
-namespace dart {
-
-void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
-    compiler::Assembler* assembler,
-    HierarchyInfo* hi,
-    const Type& type,
-    const Class& type_class) {
-  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
-
-  __ ldr(CODE_REG,
-         compiler::Address(
-             THR, compiler::target::Thread::slow_type_test_stub_offset()));
-  __ Branch(compiler::FieldAddress(
-      CODE_REG, compiler::target::Code::entry_point_offset()));
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/type_testing_stubs_arm64.cc b/runtime/vm/type_testing_stubs_arm64.cc
deleted file mode 100644
index bc2df7f..0000000
--- a/runtime/vm/type_testing_stubs_arm64.cc
+++ /dev/null
@@ -1,30 +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/globals.h"
-
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/type_testing_stubs.h"
-
-#define __ assembler->
-
-namespace dart {
-
-void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
-    compiler::Assembler* assembler,
-    HierarchyInfo* hi,
-    const Type& type,
-    const Class& type_class) {
-  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
-
-  __ ldr(CODE_REG,
-         compiler::Address(THR, Thread::slow_type_test_stub_offset()));
-  __ ldr(R9, compiler::FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ br(R9);
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/type_testing_stubs_test.cc b/runtime/vm/type_testing_stubs_test.cc
index fccb41e..57e9459 100644
--- a/runtime/vm/type_testing_stubs_test.cc
+++ b/runtime/vm/type_testing_stubs_test.cc
@@ -47,8 +47,8 @@
   const auto& symbol = String::Handle(
       Symbols::New(thread, OS::SCreate(thread->zone(), "TTSTest")));
   const auto& function = Function::Handle(
-      Function::New(symbol, RawFunction::kRegularFunction, false, false, false,
-                    false, false, klass, TokenPosition::kNoSource));
+      Function::New(symbol, FunctionLayout::kRegularFunction, false, false,
+                    false, false, false, klass, TokenPosition::kNoSource));
   compiler::ObjectPoolBuilder pool_builder;
   const auto& invoke_tts = Code::Handle(
       StubCode::Generate("InvokeTTS", &pool_builder, &GenerateInvokeTTSStub));
diff --git a/runtime/vm/type_testing_stubs_x64.cc b/runtime/vm/type_testing_stubs_x64.cc
deleted file mode 100644
index a942eb0..0000000
--- a/runtime/vm/type_testing_stubs_x64.cc
+++ /dev/null
@@ -1,29 +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/globals.h"
-
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/type_testing_stubs.h"
-
-#define __ assembler->
-
-namespace dart {
-
-void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
-    compiler::Assembler* assembler,
-    HierarchyInfo* hi,
-    const Type& type,
-    const Class& type_class) {
-  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class);
-
-  __ movq(CODE_REG,
-          compiler::Address(THR, Thread::slow_type_test_stub_offset()));
-  __ jmp(compiler::FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index f23e5ee..2db8a7b 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -117,11 +117,12 @@
   Isolate::FlagsInitialize(&api_flags);
   Dart_Isolate isolate = NULL;
   if (len == 0) {
-    isolate =
-        Dart_CreateIsolateGroup(name, NULL, data_buffer, instr_buffer,
-                                &api_flags, group_data, isolate_data, &err);
+    isolate = Dart_CreateIsolateGroup(
+        /*script_uri=*/name, /*name=*/name, data_buffer, instr_buffer,
+        &api_flags, group_data, isolate_data, &err);
   } else {
-    isolate = Dart_CreateIsolateGroupFromKernel(name, NULL, data_buffer, len,
+    isolate = Dart_CreateIsolateGroupFromKernel(/*script_uri=*/name,
+                                                /*name=*/name, data_buffer, len,
                                                 &api_flags, group_data,
                                                 isolate_data, &err);
   }
@@ -157,6 +158,26 @@
   RELEASE_ASSERT(!Dart_IsError(result));
 }
 
+Dart_Isolate TestCase::CreateTestIsolateInGroup(const char* name,
+                                                Dart_Isolate parent,
+                                                void* group_data,
+                                                void* isolate_data) {
+  char* error;
+#if defined(DART_PRECOMPILED_RUNTIME)
+  Isolate* result = CreateWithinExistingIsolateGroupAOT(
+      reinterpret_cast<Isolate*>(parent)->group(), name, &error);
+#else
+  Isolate* result = CreateWithinExistingIsolateGroup(
+      reinterpret_cast<Isolate*>(parent)->group(), name, &error);
+#endif
+  if (error != nullptr) {
+    OS::PrintErr("CreateTestIsolateInGroup failed: %s\n", error);
+    free(error);
+  }
+  EXPECT(result != nullptr);
+  return Api::CastIsolate(result);
+}
+
 struct TestLibEntry {
   const char* url;
   const char* source;
@@ -634,9 +655,9 @@
   const Library& lib = Library::Handle(Library::CoreLibrary());
   const Class& cls = Class::ZoneHandle(
       Class::New(lib, function_name, script, TokenPosition::kMinSource));
-  Function& function = Function::ZoneHandle(
-      Function::New(function_name, RawFunction::kRegularFunction, true, false,
-                    false, false, false, cls, TokenPosition::kMinSource));
+  Function& function = Function::ZoneHandle(Function::New(
+      function_name, FunctionLayout::kRegularFunction, true, false, false,
+      false, false, cls, TokenPosition::kMinSource));
   code_ = Code::FinalizeCodeAndNotify(function, nullptr, assembler_,
                                       Code::PoolAttachment::kAttachPool);
   code_.set_owner(function);
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 7dce889..f576b71 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -361,6 +361,11 @@
   static Dart_Isolate CreateTestIsolate(const char* name = nullptr,
                                         void* isolate_group_data = nullptr,
                                         void* isolate_data = nullptr);
+  static Dart_Isolate CreateTestIsolateInGroup(const char* name,
+                                               Dart_Isolate parent,
+                                               void* group_data = nullptr,
+                                               void* isolate_data = nullptr);
+
   static Dart_Handle library_handler(Dart_LibraryTag tag,
                                      Dart_Handle library,
                                      Dart_Handle url);
@@ -535,8 +540,8 @@
     const bool fp_args = false;
     const bool fp_return = false;
     Simulator::Current()->Call(
-        bit_cast<intptr_t, uword>(entry()), reinterpret_cast<intptr_t>(arg1),
-        reinterpret_cast<intptr_t>(arg2), reinterpret_cast<intptr_t>(arg3), 0,
+        bit_cast<intptr_t, uword>(entry()), static_cast<intptr_t>(arg1),
+        static_cast<intptr_t>(arg2), reinterpret_cast<intptr_t>(arg3), 0,
         fp_return, fp_args);
   }
 #else
diff --git a/runtime/vm/uri.cc b/runtime/vm/uri.cc
index 5e75ef1..74046e9 100644
--- a/runtime/vm/uri.cc
+++ b/runtime/vm/uri.cc
@@ -369,10 +369,7 @@
   buffer[truncated_base_len] = '/';
 
   // Copy the ref_path.
-  strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len);
-
-  // Add the trailing '\0'.
-  buffer[len] = '\0';
+  strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len + 1);
 
   return buffer;
 }
diff --git a/runtime/vm/v8_snapshot_writer.cc b/runtime/vm/v8_snapshot_writer.cc
index 1a79e0c..7d22307 100644
--- a/runtime/vm/v8_snapshot_writer.cc
+++ b/runtime/vm/v8_snapshot_writer.cc
@@ -53,7 +53,7 @@
     info->name = EnsureString(name);
   } else {
     info->name =
-        EnsureString(OS::SCreate(zone_, "Unnamed [%s] %s", type, name));
+        EnsureString(OS::SCreate(zone_, "Unnamed [%s] %s", type, "(nil)"));
   }
 }
 
diff --git a/runtime/vm/visitor.cc b/runtime/vm/visitor.cc
index 8274cc8..145dd06 100644
--- a/runtime/vm/visitor.cc
+++ b/runtime/vm/visitor.cc
@@ -11,6 +11,6 @@
 ObjectPointerVisitor::ObjectPointerVisitor(IsolateGroup* isolate_group)
     : isolate_group_(isolate_group),
       gc_root_type_("unknown"),
-      shared_class_table_(isolate_group->class_table()) {}
+      shared_class_table_(isolate_group->shared_class_table()) {}
 
 }  // namespace dart
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index 2dd68f4..93baf0d 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -15,9 +15,6 @@
 // Forward declarations.
 class Isolate;
 class IsolateGroup;
-class RawObject;
-class RawFunction;
-class RawTypedDataView;
 
 // An object pointer visitor interface.
 class ObjectPointerVisitor {
@@ -30,21 +27,21 @@
   // Visit pointers inside the given typed data [view].
   //
   // Range of pointers to visit 'first' <= pointer <= 'last'.
-  virtual void VisitTypedDataViewPointers(RawTypedDataView* view,
-                                          RawObject** first,
-                                          RawObject** last) {
+  virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
+                                          ObjectPtr* first,
+                                          ObjectPtr* last) {
     VisitPointers(first, last);
   }
 
   // Range of pointers to visit 'first' <= pointer <= 'last'.
-  virtual void VisitPointers(RawObject** first, RawObject** last) = 0;
+  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) = 0;
 
   // len argument is the number of pointers to visit starting from 'p'.
-  void VisitPointers(RawObject** p, intptr_t len) {
+  void VisitPointers(ObjectPtr* p, intptr_t len) {
     VisitPointers(p, (p + len - 1));
   }
 
-  void VisitPointer(RawObject** p) { VisitPointers(p, p); }
+  void VisitPointer(ObjectPtr* p) { VisitPointers(p, p); }
 
   const char* gc_root_type() const { return gc_root_type_; }
   void set_gc_root_type(const char* gc_root_type) {
@@ -75,7 +72,7 @@
   virtual ~ObjectVisitor() {}
 
   // Invoked for each object.
-  virtual void VisitObject(RawObject* obj) = 0;
+  virtual void VisitObject(ObjectPtr obj) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ObjectVisitor);
@@ -95,7 +92,7 @@
   }
 
   // Check if object matches find condition.
-  virtual bool FindObject(RawObject* obj) const = 0;
+  virtual bool FindObject(ObjectPtr obj) const = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FindObjectVisitor);
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index a02d69b..a919b39 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -220,6 +220,7 @@
   "pointer_tagging.h",
   "port.cc",
   "port.h",
+  "port_set.h",
   "proccpuinfo.cc",
   "proccpuinfo.h",
   "profiler.cc",
@@ -343,9 +344,6 @@
   "type_table.h",
   "type_testing_stubs.cc",
   "type_testing_stubs.h",
-  "type_testing_stubs_arm.cc",
-  "type_testing_stubs_arm64.cc",
-  "type_testing_stubs_x64.cc",
   "unibrow-inl.h",
   "unibrow.cc",
   "unibrow.h",
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index b6d3727..7859112 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -40,7 +40,7 @@
   void* alignment_;
 
   // Computes the address of the nth byte in this segment.
-  uword address(int n) { return reinterpret_cast<uword>(this) + n; }
+  uword address(intptr_t n) { return reinterpret_cast<uword>(this) + n; }
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(Segment);
 };
@@ -195,6 +195,7 @@
 #endif
   position_ = initial_buffer_.start();
   limit_ = initial_buffer_.end();
+  small_segment_capacity_ = 0;
   head_ = NULL;
   large_segments_ = NULL;
   previous_ = NULL;
@@ -252,8 +253,22 @@
     return AllocateLargeSegment(size);
   }
 
+  const intptr_t kSuperPageSize = 2 * MB;
+  intptr_t next_size;
+  if (small_segment_capacity_ < kSuperPageSize) {
+    // When the Zone is small, grow linearly to reduce size and use the segment
+    // cache to avoid expensive mmap calls.
+    next_size = kSegmentSize;
+  } else {
+    // When the Zone is large, grow geometrically to avoid Page Table Entry
+    // exhaustion. Using 1.125 ratio.
+    next_size = Utils::RoundUp(small_segment_capacity_ >> 3, kSuperPageSize);
+  }
+  ASSERT(next_size >= kSegmentSize);
+
   // Allocate another segment and chain it up.
-  head_ = Segment::New(kSegmentSize, head_);
+  head_ = Segment::New(next_size, head_);
+  small_segment_capacity_ += next_size;
 
   // Recompute 'position' and 'limit' based on the new head segment.
   uword result = Utils::RoundUp(head_->start(), kAlignment);
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index 7115cc71..548708d 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -155,6 +155,9 @@
   // implementation is in zone.cc.
   class Segment;
 
+  // Total size of all segments in [head_].
+  intptr_t small_segment_capacity_ = 0;
+
   // The current head segment; may be NULL.
   Segment* head_;
 
diff --git a/runtime/vm/zone_text_buffer.h b/runtime/vm/zone_text_buffer.h
index f4e2f31..1b7fef3 100644
--- a/runtime/vm/zone_text_buffer.h
+++ b/runtime/vm/zone_text_buffer.h
@@ -26,7 +26,7 @@
   void AddString(const String& s);
 
   char* buffer() { return buffer_; }
-  intptr_t length() { return length_; }
+  intptr_t length() const { return length_; }
 
   void Clear();
 
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index b343437..8579a96 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -125,7 +125,7 @@
   ],
   [
     "dartdev",
-    "../utils/dartdev",
+    "../utils/dartdev:generate_dartdev_snapshot",
   ],
   [
     "dartdoc",
@@ -170,7 +170,7 @@
   ],
   [
     "dartdev",
-    "../utils/dartdev",
+    "../utils/dartdev:generate_dartdev_snapshot",
   ],
   [
     "dartdevc",
diff --git a/sdk/lib/_http/embedder_config.dart b/sdk/lib/_http/embedder_config.dart
new file mode 100644
index 0000000..fb13bea
--- /dev/null
+++ b/sdk/lib/_http/embedder_config.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.6
+
+part of dart._http;
+
+/// Embedder-specific `dart:_http` configuration.
+
+/// [HttpClient] will disallow HTTP URLs if this value is set to `false`.
+@pragma("vm:entry-point")
+bool _embedderAllowsHttp = true;
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index 6883fbc..e80369c 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -24,6 +24,7 @@
 import 'dart:typed_data';
 
 part 'crypto.dart';
+part 'embedder_config.dart';
 part 'http_date.dart';
 part 'http_headers.dart';
 part 'http_impl.dart';
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 7101ca9..81e60db 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -2266,6 +2266,32 @@
     });
   }
 
+  /// Whether HTTP requests are currently allowed.
+  ///
+  /// If the [Zone] variable `#dart.library.io.allow_http` is set to a boolean,
+  /// it determines whether the HTTP protocol is allowed. If the zone variable
+  /// is set to any other non-null value, HTTP is not allowed.
+  /// Otherwise, if the `dart.library.io.allow_http` environment flag
+  /// is set to `false`, HTTP is not allowed.
+  /// Otherwise, [_embedderAllowsHTTP] determines the result.
+  bool get _isHttpAllowed {
+    final zoneOverride = Zone.current[#dart.library.io.allow_http];
+    if (zoneOverride != null) return true == zoneOverride;
+    bool envOverride =
+        bool.fromEnvironment("dart.library.io.allow_http", defaultValue: true);
+    return envOverride && _embedderAllowsHttp;
+  }
+
+  bool _isLoopback(String host) {
+    if (host.isEmpty) return false;
+    if ("localhost" == host) return true;
+    try {
+      return InternetAddress(host).isLoopback;
+    } on ArgumentError {
+      return false;
+    }
+  }
+
   Future<_HttpClientRequest> _openUrl(String method, Uri uri) {
     if (_closing) {
       throw new StateError("Client is closed");
@@ -2286,7 +2312,12 @@
       }
     }
 
-    bool isSecure = (uri.scheme == "https");
+    bool isSecure = uri.isScheme("https");
+    if (!_isHttpAllowed && !isSecure && !_isLoopback(uri.host)) {
+      throw new StateError(
+          "Insecure HTTP is not allowed by the current platform: $uri");
+    }
+
     int port = uri.port;
     if (port == 0) {
       port =
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index 74582d7..a67011e 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -713,10 +713,10 @@
                     (isUpgrade && isResponse && isUpgradeCode)) {
                   _connectionUpgrade = true;
                 }
-                _headers.add(headerField, tokens[i]);
+                _headers._add(headerField, tokens[i]);
               }
             } else {
-              _headers.add(headerField, headerValue);
+              _headers._add(headerField, headerValue);
             }
             _headerField.clear();
             _headerValue.clear();
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart
index 6b85e67..cdc7370 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart
@@ -500,11 +500,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
index a220dac..dea22f5 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -166,19 +166,20 @@
   static int _keyCount = 0;
 }
 
-Null _kNull(_) => null;
-
 @patch
 class int {
   @patch
   static int parse(String source,
       {int radix, @deprecated int onError(String source)}) {
-    return Primitives.parseInt(source, radix, onError);
+    var value = tryParse(source, radix: radix);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException(source);
   }
 
   @patch
   static int tryParse(String source, {int radix}) {
-    return Primitives.parseInt(source, radix, _kNull);
+    return Primitives.parseInt(source, radix);
   }
 
   @patch
@@ -209,12 +210,15 @@
   @patch
   static double parse(String source,
       [@deprecated double onError(String source)]) {
-    return Primitives.parseDouble(source, onError);
+    var value = tryParse(source);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException('Invalid double', source);
   }
 
   @patch
   static double tryParse(String source) {
-    return Primitives.parseDouble(source, _kNull);
+    return Primitives.parseDouble(source);
   }
 
   @JSExportName('is')
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 48a0969..7c14c7a 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -427,6 +427,11 @@
       InternetAddress address, String host) {
     throw UnsupportedError("InternetAddress._cloneWithNewHost");
   }
+
+  @patch
+  static InternetAddress tryParse(String address) {
+    throw UnsupportedError("InternetAddress.tryParse");
+  }
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
index 04b4f2f..1592218 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
@@ -60,27 +60,29 @@
   var setter = JS('', '#.set', desc);
   if (getter != null) {
     if (setter == null) {
-      var obj = JS(
-          '',
+      var obj = JS<Object>(
+          '!',
           '#.set = { __proto__: #.__proto__, '
               'set [#](x) { return super[#] = x; } }',
           desc,
           to,
           name,
           name);
-      JS('', '#.set = #.set', desc, getOwnPropertyDescriptor(obj, name));
+      JS<Object>(
+          '!', '#.set = #.set', desc, getOwnPropertyDescriptor(obj, name));
     }
   } else if (setter != null) {
     if (getter == null) {
-      var obj = JS(
-          '',
+      var obj = JS<Object>(
+          '!',
           '#.get = { __proto__: #.__proto__, '
               'get [#]() { return super[#]; } }',
           desc,
           to,
           name,
           name);
-      JS('', '#.get = #.get', desc, getOwnPropertyDescriptor(obj, name));
+      JS<Object>(
+          '!', '#.get = #.get', desc, getOwnPropertyDescriptor(obj, name));
     }
   }
   defineProperty(to, name, desc);
@@ -128,6 +130,9 @@
 ///
 /// This normalization should mirror the normalization performed at compile time
 /// in the method named `_normalizeFutureOr()`.
+///
+/// **NOTE** Normalization of FutureOr<T?>? --> FutureOr<T?> is handled in
+/// [nullable].
 normalizeFutureOr(typeConstructor, setBaseClass) {
   // The canonical version of the generic FutureOr type constructor.
   var genericFutureOrType =
@@ -137,20 +142,30 @@
     // Normalize raw FutureOr --> dynamic
     if (JS<bool>('!', '# == void 0', typeArg)) return _dynamic;
 
-    // FutureOr<dynamic|void|Object> --> dynamic|void|Object
-    if (_isTop(typeArg)) return typeArg;
+    // FutureOr<dynamic|void|Object?|Object*|Object> -->
+    //   dynamic|void|Object?|Object*|Object
+    if (_isTop(typeArg) ||
+        _equalType(typeArg, Object) ||
+        (_jsInstanceOf(typeArg, LegacyType) &&
+            JS<bool>('!', '#.type === #', typeArg, Object))) {
+      return typeArg;
+    }
 
-    // FutureOr<Null> --> Future<Null>
-    // NOTE: These are a legacy FutureOr and Future that can be null already.
-    if (typeArg == unwrapType(Null)) {
+    // FutureOr<Never> --> Future<Never>
+    if (_equalType(typeArg, Never)) {
       return JS('!', '#(#)', getGenericClass(Future), typeArg);
     }
+    // FutureOr<Null> --> Future<Null>?
+    if (_equalType(typeArg, Null)) {
+      return nullable(JS('!', '#(#)', getGenericClass(Future), typeArg));
+    }
     // Otherwise, create the FutureOr<T> type as a normal generic type.
     var genericType = JS('!', '#(#)', genericFutureOrType, typeArg);
     // Overwrite the original declaration so that it correctly points back to
     // this method. This ensures that the we can test a type value returned here
     // as a FutureOr because it is equal to 'async.FutureOr` (in the JS).
     JS('!', '#[#] = #', genericType, _originalDeclaration, normalize);
+    JS('!', '#(#)', addTypeCaches, genericType);
     return genericType;
   }
 
@@ -206,16 +221,19 @@
     return value;
   }
   makeGenericType[$_genericTypeCtor] = $typeConstructor;
+  $addTypeCaches(makeGenericType);
   return makeGenericType;
 })()''');
 
 getGenericClass(type) => safeGetOwnProperty(type, _originalDeclaration);
 
+// TODO(markzipan): Make this non-nullable if we can ensure this returns
+// an empty list or if null and the empty list are semantically the same.
 List getGenericArgs(type) =>
-    JS('List', '#', safeGetOwnProperty(type, _typeArguments));
+    JS<List>('', '#', safeGetOwnProperty(type, _typeArguments));
 
 List getGenericArgVariances(type) =>
-    JS('List', '#', safeGetOwnProperty(type, _variances));
+    JS<List>('', '#', safeGetOwnProperty(type, _variances));
 
 void setGenericArgVariances(f, variances) =>
     JS('', '#[#] = #', f, _variances, variances);
@@ -272,7 +290,7 @@
   // Note that it is still possible to call typed JS interop methods on
   // extension types but the calls must be statically typed.
   if (JS('!', '#[#] != null', obj, _extensionType)) return false;
-  return JS('!', '!($obj instanceof $Object)');
+  return !_jsInstanceOf(obj, Object);
 }
 
 /// Get the type of a method from a type using the stored signature
@@ -368,19 +386,19 @@
   }
   // If the extension methods of the parent have been installed on the parent
   // of [jsProto], the methods will be available via prototype inheritance.
-  var dartSupertype = JS('', '#.__proto__', dartType);
+  var dartSupertype = JS<Object>('!', '#.__proto__', dartType);
   if (JS('!', '# !== #', dartSupertype, installedParent)) {
     _installProperties(jsProto, dartSupertype, installedParent);
   }
 
-  var dartProto = JS('', '#.prototype', dartType);
+  var dartProto = JS<Object>('!', '#.prototype', dartType);
   copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto));
 }
 
 void _installPropertiesForObject(jsProto) {
   // core.Object members need to be copied from the non-symbol name to the
   // symbol name.
-  var coreObjProto = JS('', '#.prototype', Object);
+  var coreObjProto = JS<Object>('!', '#.prototype', Object);
   var names = getOwnPropertyNames(coreObjProto);
   for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
     var name = JS<String>('!', '#[#]', names, i);
@@ -399,7 +417,7 @@
 
 final _extensionMap = JS('', 'new Map()');
 
-_applyExtension(jsType, dartExtType) {
+void _applyExtension(jsType, dartExtType) {
   // TODO(vsm): Not all registered js types are real.
   if (jsType == null) return;
   var jsProto = JS('', '#.prototype', jsType);
@@ -474,13 +492,13 @@
 }
 
 /// Like [defineExtensionMethods], but for getter/setter pairs.
-defineExtensionAccessors(type, Iterable memberNames) {
-  var proto = JS('', '#.prototype', type);
+void defineExtensionAccessors(type, Iterable memberNames) {
+  var proto = JS<Object>('!', '#.prototype', type);
   for (var name in memberNames) {
     // Find the member. It should always exist (or we have a compiler bug).
     var member;
     var p = proto;
-    for (;; p = JS('', '#.__proto__', p)) {
+    for (;; p = JS<Object>('!', '#.__proto__', p)) {
       member = getOwnPropertyDescriptor(p, name);
       if (member != null) break;
     }
@@ -534,7 +552,7 @@
   JS(
       '',
       '''#.as = function as_C(obj) {
-    if (obj == null || obj[#]) return obj;
+    if (obj != null && obj[#]) return obj;
     return #(obj, this);
   }''',
       ctor,
@@ -544,8 +562,16 @@
 
 /// Pre-initializes types with empty type caches.
 ///
-/// Required for the null-safe SDK. Stubbed here.
-addTypeCaches(type) => null;
+/// Allows us to perform faster lookups on local caches without having to
+/// filter out the prototype chain. Also allows types to remain relatively
+/// monomorphic, which results in faster execution in V8.
+addTypeCaches(type) {
+  JS('', '#[#] = void 0', type, _cachedLegacy);
+  JS('', '#[#] = void 0', type, _cachedNullable);
+  var subtypeCacheMap = JS<Object>('!', 'new Map()');
+  JS('', '#[#] = #', type, _subtypeCache, subtypeCacheMap);
+  JS('', '#.push(#)', _cacheMaps, subtypeCacheMap);
+}
 
 // TODO(jmesserly): should we do this for all interfaces?
 
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index 699f415..7d69599 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -26,7 +26,28 @@
   throw AssertionErrorImpl(message, fileUri, line, column, conditionSource);
 }
 
-throwCyclicInitializationError([Object field]) {
+final _nullFailedSet = JS('!', 'new Set()');
+// Run-time null safety assertion per:
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
+nullFailed(String fileUri, int line, int column, String variable) {
+  if (strictNullSafety) {
+    throw AssertionErrorImpl(
+        'A null value was passed into a non-nullable parameter $variable',
+        fileUri,
+        line,
+        column,
+        '$variable != null');
+  } else {
+    var key = '$fileUri:$line:$column';
+    if (!JS('!', '#.has(#)', _nullFailedSet, key)) {
+      JS('', '#.add(#)', _nullFailedSet, key);
+      _nullWarn(
+          'A null value was passed into a non-nullable parameter $variable');
+    }
+  }
+}
+
+throwCyclicInitializationError([String field]) {
   throw CyclicInitializationError(field);
 }
 
@@ -34,8 +55,7 @@
   // TODO(vsm): Per spec, we should throw an NSM here.  Technically, we ought
   // to thread through method info, but that uglifies the code and can't
   // actually be queried ... it only affects how the error is printed.
-  throw NoSuchMethodError(
-      null, Symbol('<Unexpected Null Value>'), null, null, null);
+  throw NoSuchMethodError(null, Symbol('<Unexpected Null Value>'), null, null);
 }
 
 castError(obj, expectedType) {
@@ -47,20 +67,21 @@
 String _castErrorMessage(from, to) {
   // If both types are generic classes, see if we can infer generic type
   // arguments for `from` that would allow the subtype relation to work.
-  var fromClass = getGenericClass(from);
-  if (fromClass != null) {
-    var fromTypeFormals = getGenericTypeFormals(fromClass);
-    var fromType = instantiateClass(fromClass, fromTypeFormals);
-    var inferrer = _TypeInferrer(fromTypeFormals);
-    if (inferrer.trySubtypeMatch(fromType, to)) {
-      var inferredTypes = inferrer.getInferredTypes();
-      if (inferredTypes != null) {
-        var inferred = instantiateClass(fromClass, inferredTypes);
-        return "Type '${typeName(from)}' should be '${typeName(inferred)}' "
-            "to implement expected type '${typeName(to)}'.";
-      }
-    }
-  }
+  // TODO(#40326) Fix suggested type or remove this code if no longer needed.
+  // var fromClass = getGenericClass(from);
+  // if (fromClass != null) {
+  //   var fromTypeFormals = getGenericTypeFormals(fromClass);
+  //   var fromType = instantiateClass(fromClass, fromTypeFormals);
+  //   var inferrer = _TypeInferrer(fromTypeFormals);
+  //   if (inferrer.trySubtypeMatch(fromType, to)) {
+  //     var inferredTypes = inferrer.getInferredTypes();
+  //     if (inferredTypes != null) {
+  //       var inferred = instantiateClass(fromClass, inferredTypes);
+  //       return "Type '${typeName(from)}' should be '${typeName(inferred)}' "
+  //           "to implement expected type '${typeName(to)}'.";
+  //     }
+  //   }
+  // }
   return "Expected a value of type '${typeName(to)}', "
       "but got one of type '${typeName(from)}'";
 }
@@ -253,8 +274,9 @@
     String trace = '';
     if (e != null && JS<bool>('!', 'typeof # === "object"', e)) {
       trace = e is NativeError ? e.dartStack() : JS<String>('', '#.stack', e);
-      if (trace != null && stackTraceMapper != null) {
-        trace = stackTraceMapper(trace);
+      var mapper = stackTraceMapper;
+      if (trace != null && mapper != null) {
+        trace = mapper(trace);
       }
     }
     if (trace.isEmpty || _jsObjectMissingTrace != null) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index a89ec92..443711a 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -21,7 +21,7 @@
 
   InvocationImpl(memberName, List<Object> positionalArguments,
       {namedArguments,
-      List typeArguments,
+      List typeArguments = const [],
       this.isMethod = false,
       this.isGetter = false,
       this.isSetter = false,
@@ -30,9 +30,7 @@
             isSetter ? _setterSymbol(memberName) : _dartSymbol(memberName),
         positionalArguments = List.unmodifiable(positionalArguments),
         namedArguments = _namedArgsToSymbols(namedArguments),
-        typeArguments = typeArguments == null
-            ? const []
-            : List.unmodifiable(typeArguments.map(wrapType));
+        typeArguments = List.unmodifiable(typeArguments.map(wrapType));
 
   static Map<Symbol, dynamic> _namedArgsToSymbols(namedArgs) {
     if (namedArgs == null) return const {};
@@ -169,14 +167,33 @@
   // Check if we have invalid named arguments.
   Iterable names;
   var named = type.named;
+  var requiredNamed = type.requiredNamed;
   if (namedActuals != null) {
     names = getOwnPropertyNames(namedActuals);
     for (var name in names) {
-      if (!JS('!', '#.hasOwnProperty(#)', named, name)) {
+      if (!JS<bool>('!', '(#.hasOwnProperty(#) || #.hasOwnProperty(#))', named,
+          name, requiredNamed, name)) {
         return "Dynamic call with unexpected named argument '$name'.";
       }
     }
   }
+  // Verify that all required named parameters are provided an argument.
+  Iterable requiredNames = getOwnPropertyNames(requiredNamed);
+  if (requiredNames.isNotEmpty) {
+    var missingRequired = namedActuals == null
+        ? requiredNames
+        : requiredNames.where((name) =>
+            !JS<bool>('!', '#.hasOwnProperty(#)', namedActuals, name));
+    if (missingRequired.isNotEmpty) {
+      var error = "Dynamic call with missing required named arguments: "
+          "${missingRequired.join(', ')}.";
+      if (!strictNullSafety) {
+        _nullWarn(error);
+      } else {
+        return error;
+      }
+    }
+  }
   // Now that we know the signature matches, we can perform type checks.
   for (var i = 0; i < requiredCount; ++i) {
     JS('', '#[#].as(#[#])', required, i, actuals, i);
@@ -186,7 +203,8 @@
   }
   if (names != null) {
     for (var name in names) {
-      JS('', '#[#].as(#[#])', named, name, namedActuals, name);
+      JS('', '(#[#] || #[#]).as(#[#])', named, name, requiredNamed, name,
+          namedActuals, name);
     }
   }
   return null;
@@ -244,7 +262,9 @@
     return $noSuchMethod(originalTarget, new $InvocationImpl.new(
         $displayName, $args, {
           namedArguments: $named,
-          typeArguments: $typeArgs,
+          // Repeated the default value here to avoid passing null from JS to a
+          // non-nullable argument.
+          typeArguments: $typeArgs || [],
           isMethod: true,
           failureMessage: errorMessage
         }));
@@ -283,7 +303,7 @@
   }
 
   // Apply type arguments
-  if ($ftype instanceof $GenericFunctionType) {
+  if (${_jsInstanceOf(ftype, GenericFunctionType)}) {
     let formalCount = $ftype.formalCount;
 
     if ($typeArgs == null) {
@@ -311,8 +331,8 @@
 dcall(f, args, [@undefined named]) => _checkAndCall(
     f, null, JS('', 'void 0'), null, args, named, JS('', 'f.name'));
 
-dgcall(f, typeArgs, args, [@undefined named]) =>
-    _checkAndCall(f, null, JS('', 'void 0'), typeArgs, args, named, 'call');
+dgcall(f, typeArgs, args, [@undefined named]) => _checkAndCall(f, null,
+    JS('', 'void 0'), typeArgs, args, named, JS('', "f.name || 'call'"));
 
 /// Helper for REPL dynamic invocation variants that make a best effort to
 /// enable accessing private members across library boundaries.
@@ -387,52 +407,74 @@
 dsetindex(obj, index, value) =>
     callMethod(obj, '_set', null, [index, value], null, '[]=');
 
+/// General implementation of the Dart `is` operator.
+///
+/// Some basic cases are handled directly by the `.is` methods that are attached
+/// directly on types, but any query that requires checking subtyping relations
+/// is handled here.
 @notNull
 @JSExportName('is')
 bool instanceOf(obj, type) {
   if (obj == null) {
-    return identical(type, unwrapType(Null)) || _isTop(type);
+    return _equalType(type, Null) ||
+        _isTop(type) ||
+        _jsInstanceOf(type, NullableType);
   }
   return isSubtypeOf(getReifiedType(obj), type);
 }
 
+/// General implementation of the Dart `as` operator.
+///
+/// Some basic cases are handled directly by the `.as` methods that are attached
+/// directly on types, but any query that requires checking subtyping relations
+/// is handled here.
 @JSExportName('as')
 cast(obj, type) {
-  if (obj == null) return obj;
-  var actual = getReifiedType(obj);
-  if (isSubtypeOf(actual, type)) {
+  // We hoist the common case where null is checked against another type here
+  // for better performance.
+  if (obj == null && !strictNullSafety) {
+    // Check the null comparison cache to avoid emitting repeated warnings.
+    _nullWarnOnType(type);
     return obj;
+  } else {
+    var actual = getReifiedType(obj);
+    if (isSubtypeOf(actual, type)) return obj;
   }
+
   return castError(obj, type);
 }
 
 bool test(bool obj) {
-  if (obj == null) _throwBooleanConversionError();
+  if (obj == null) throw BooleanConversionAssertionError();
   return obj;
 }
 
 bool dtest(obj) {
-  if (obj is! bool) booleanConversionFailed(obj);
+  // Only throw an AssertionError in weak mode for compatibility. Strong mode
+  // should throw a TypeError.
+  if (obj is! bool) booleanConversionFailed(strictNullSafety ? obj : test(obj));
   return obj;
 }
 
-void _throwBooleanConversionError() => throw BooleanConversionAssertionError();
-
 void booleanConversionFailed(obj) {
   var actual = typeName(getReifiedType(obj));
   throw TypeErrorImpl("type '$actual' is not a 'bool' in boolean expression");
 }
 
 asInt(obj) {
-  if (obj == null) return null;
-
+  // Note: null (and undefined) will fail this test.
   if (JS('!', 'Math.floor(#) != #', obj, obj)) {
-    castError(obj, JS('', '#', int));
+    if (obj == null && !strictNullSafety) {
+      _nullWarnOnType(JS('', '#', int));
+      return null;
+    } else {
+      castError(obj, JS('', '#', int));
+    }
   }
   return obj;
 }
 
-asNullableInt(obj) => asInt(obj);
+asNullableInt(obj) => obj == null ? null : asInt(obj);
 
 /// Checks that `x` is not null or undefined.
 //
@@ -447,11 +489,25 @@
   return x;
 }
 
-/// No-op without null safety enabled.
-nullCast(x, type) => x;
+/// Checks that `x` is not null or undefined.
+///
+/// Unlike `_notNull`, this throws a `CastError` (under strict checking)
+/// or emits a runtime warning (otherwise).  This is only used by the
+/// compiler when casting from nullable to non-nullable variants of the
+/// same type.
+nullCast(x, type) {
+  if (x == null) {
+    if (!strictNullSafety) {
+      _nullWarnOnType(type);
+    } else {
+      castError(x, type);
+    }
+  }
+  return x;
+}
 
 /// The global constant map table.
-final constantMaps = JS('', 'new Map()');
+final constantMaps = JS<Object>('!', 'new Map()');
 
 // TODO(leafp): This table gets quite large in apps.
 // Keeping the paths is probably expensive.  It would probably
@@ -471,14 +527,14 @@
     map = _lookupNonTerminal(map, JS('', '#[#]', elements, i));
   }
   map = _lookupNonTerminal(map, K);
-  var result = JS('', '#.get(#)', map, V);
+  Map<K, V> result = JS('', '#.get(#)', map, V);
   if (result != null) return result;
   result = ImmutableMap<K, V>.from(elements);
   JS('', '#.set(#, #)', map, V, result);
   return result;
 }
 
-final constantSets = JS('', 'new Map()');
+final constantSets = JS<Object>('!', 'new Map()');
 var _immutableSetConstructor;
 
 // We cannot invoke private class constructors directly in Dart.
@@ -494,7 +550,7 @@
   for (var i = 0; i < count; i++) {
     map = _lookupNonTerminal(map, JS('', '#[#]', elements, i));
   }
-  var result = JS('', '#.get(#)', map, E);
+  Set<E> result = JS('', '#.get(#)', map, E);
   if (result != null) return result;
   result = _createImmutableSet<E>(elements);
   JS('', '#.set(#, #)', map, E, result);
@@ -537,7 +593,7 @@
 /// and value of the field.  The final map is
 /// indexed by runtime type, and contains the canonical
 /// version of the object.
-final constants = JS('', 'new Map()');
+final constants = JS('!', 'new Map()');
 
 ///
 /// Canonicalize a constant object.
@@ -656,7 +712,7 @@
   return obj == null ? Null : JS('', '#[dartx.runtimeType]', obj);
 }
 
-final identityHashCode_ = JS('', 'Symbol("_identityHashCode")');
+final identityHashCode_ = JS<Object>('!', 'Symbol("_identityHashCode")');
 
 /// Adapts a Dart `get iterator` into a JS `[Symbol.iterator]`.
 // TODO(jmesserly): instead of an adaptor, we could compile Dart iterators
@@ -697,8 +753,89 @@
 Future loadLibrary() => Future.value();
 
 /// Defines lazy statics.
-void defineLazy(to, from, bool checkCycles) {
+///
+/// TODO: Remove useOldSemantics when non-null-safe late static field behavior is
+/// deprecated.
+void defineLazy(to, from, bool useOldSemantics) {
   for (var name in getOwnNamesAndSymbols(from)) {
-    defineLazyField(to, name, getOwnPropertyDescriptor(from, name));
+    if (useOldSemantics) {
+      defineLazyFieldOld(to, name, getOwnPropertyDescriptor(from, name));
+    } else {
+      defineLazyField(to, name, getOwnPropertyDescriptor(from, name));
+    }
   }
 }
+
+/// Defines a lazy static field.
+/// After initial get or set, it will replace itself with a value property.
+// TODO(jmesserly): reusing descriptor objects has been shown to improve
+// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
+defineLazyField(to, name, desc) => JS('', '''(() => {
+  const initializer = $desc.get;
+  let init = initializer;
+  let value = null;
+  let executed = false;
+  $desc.get = function() {
+    if (init == null) return value;
+    if (!executed) {
+      // Record the field on first execution so we can reset it later if
+      // needed (hot restart).
+      $_resetFields.push(() => {
+        init = initializer;
+        value = null;
+      });
+      executed = true;
+    }
+    value = init();
+    init = null;
+    return value;
+  };
+  $desc.configurable = true;
+  if ($desc.set != null) {
+    $desc.set = function(x) {
+      init = null;
+      value = x;
+    };
+  }
+  return ${defineProperty(to, name, desc)};
+})()''');
+
+/// Defines a lazy static field with pre-null-safety semantics.
+defineLazyFieldOld(to, name, desc) => JS('', '''(() => {
+  const initializer = $desc.get;
+  let init = initializer;
+  let value = null;
+  $desc.get = function() {
+    if (init == null) return value;
+    let f = init;
+    init = $throwCyclicInitializationError;
+    if (f === init) f($name); // throw cycle error
+
+    // On the first (non-cyclic) execution, record the field so we can reset it
+    // later if needed (hot restart).
+    $_resetFields.push(() => {
+      init = initializer;
+      value = null;
+    });
+
+    // Try to evaluate the field, using try+catch to ensure we implement the
+    // correct Dart error semantics.
+    try {
+      value = f();
+      init = null;
+      return value;
+    } catch (e) {
+      init = null;
+      value = null;
+      throw e;
+    }
+  };
+  $desc.configurable = true;
+  if ($desc.set != null) {
+    $desc.set = function(x) {
+      init = null;
+      value = x;
+    };
+  }
+  return ${defineProperty(to, name, desc)};
+})()''');
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
index a869a3f..4d731ce 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
@@ -71,9 +71,9 @@
 }
 
 // TODO(vsm): How should we encode the runtime type?
-final _runtimeType = JS('', 'Symbol("_runtimeType")');
+final Object _runtimeType = JS('!', 'Symbol("_runtimeType")');
 
-final _moduleName = JS('', 'Symbol("_moduleName")');
+final Object _moduleName = JS('!', 'Symbol("_moduleName")');
 
 getFunctionType(obj) {
   // TODO(vsm): Encode this properly on the function for Dart-generated code.
@@ -90,7 +90,7 @@
   switch (JS<String>('!', 'typeof #', obj)) {
     case "object":
       if (obj == null) return JS('', '#', Null);
-      if (JS('!', '# instanceof #', obj, Object)) {
+      if (_jsInstanceOf(obj, Object)) {
         return JS('', '#.constructor', obj);
       }
       var result = JS('', '#[#]', obj, _extensionType);
@@ -123,7 +123,7 @@
 final _loadedSourceMaps = JS('', 'new Map()');
 
 List<String> getModuleNames() {
-  return JSArray<String>.of(JS('', 'Array.from(#.keys())', _loadedModules));
+  return JS<List<String>>('', 'Array.from(#.keys())', _loadedModules);
 }
 
 String getSourceMap(String moduleName) {
@@ -148,7 +148,7 @@
     // Added for backwards compatibility.
     // package:build_web_compilers currently invokes this without [parts]
     // in its bootstrap code.
-    sourceMap = parts as String;
+    sourceMap = parts;
     parts = JS('', '{}');
   }
   JS('', '#.set(#, #)', _loadedSourceMaps, moduleName, sourceMap);
@@ -171,6 +171,8 @@
   for (var name in modules) {
     // Add libraries from each module.
     var module = getModuleLibraries(name);
+    // TODO(nshahan) Can we optimize this cast and the one below to use
+    // JsArray.of() to be more efficient?
     var libraries = getOwnPropertyNames(module).cast<String>();
     _libraries.addAll(libraries);
     for (var library in libraries) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
index 68eef6d..433393d 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -107,7 +107,7 @@
 })()''');
 
 @JSExportName('global')
-final global_ = JS('', '''
+final Object global_ = JS('', '''
   function () {
     // Find global object.
     var globalState = (typeof window != "undefined") ? window
@@ -172,6 +172,8 @@
 ///
 /// This is used by [hotRestart] to ensure we don't leak types from previous
 /// libraries.
+/// Results made against Null are cached in _nullComparisonSet and must be
+/// cleared separately.
 @notNull
 final List<Object> _cacheMaps = JS('!', '[]');
 
@@ -201,6 +203,7 @@
   _resetFields.clear();
   for (var m in _cacheMaps) JS('', '#.clear()', m);
   _cacheMaps.clear();
+  JS('', '#.clear()', _nullComparisonSet);
   JS('', '#.clear()', constantMaps);
 }
 
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index b3fad43..c1235fd 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -7,6 +7,25 @@
 /// This library defines the representation of runtime types.
 part of dart._runtime;
 
+@notNull
+bool _setNullSafety = false;
+
+@notNull
+bool strictNullSafety = false;
+
+/// Sets the mode of the runtime subtype checks.
+///
+/// Changing the mode after the application has started running is not
+/// supported.
+void nullSafety(bool flag) {
+  if (_setNullSafety) {
+    throw UnsupportedError('The Null Safety mode can only be set once.');
+  }
+
+  strictNullSafety = flag;
+  _setNullSafety = true;
+}
+
 final metadata = JS('', 'Symbol("metadata")');
 
 /// Types in dart are represented internally at runtime as follows.
@@ -63,16 +82,22 @@
 
   @JSExportName('as')
   as_T(object) => cast(object, this);
+
+  DartType() {
+    // Every instance of a DartType requires a set of type caches.
+    JS('', '#(this)', addTypeCaches);
+  }
 }
 
 class DynamicType extends DartType {
   toString() => 'dynamic';
 
+  @notNull
   @JSExportName('is')
   bool is_T(object) => true;
 
   @JSExportName('as')
-  as_T(object) => object;
+  Object as_T(Object object) => object;
 }
 
 @notNull
@@ -84,7 +109,9 @@
 /// function before it is passed to native JS code.
 @NoReifyGeneric()
 F assertInterop<F extends Function>(F f) {
-  assert(_isJsObject(f) || !JS('bool', '# instanceof #.Function', f, global_),
+  assert(
+      _isJsObject(f) ||
+          !JS<bool>('bool', '# instanceof #.Function', f, global_),
       'Dart function requires `allowInterop` to be passed to JavaScript.');
   return f;
 }
@@ -99,7 +126,7 @@
 F tearoffInterop<F extends Function>(F f) {
   // Wrap a JS function with a closure that ensures all function arguments are
   // native JS functions.
-  if (!_isJsObject(f)) return f;
+  if (!_isJsObject(f) || f == null) return f;
   var ret = _assertInteropExpando[f];
   if (ret == null) {
     ret = JS(
@@ -193,8 +220,32 @@
   JS('void', 'console.warn(#)', arg);
 }
 
-var _lazyJSTypes = JS('', 'new Map()');
-var _anonymousJSTypes = JS('', 'new Map()');
+void _nullWarn(arg) {
+  _warn('$arg\n'
+      'This will become a failure when runtime null safety is enabled.');
+}
+
+/// Tracks objects that have been compared against null (i.e., null is Type).
+/// Separating this null set out from _cacheMaps lets us fast-track common
+/// legacy type checks.
+/// TODO: Delete this set when legacy nullability is phased out.
+var _nullComparisonSet = JS<Object>('', 'new Set()');
+
+/// Warn on null cast failures when casting to a particular non-nullable
+/// `type`.  Note, we cache by type to avoid excessive warning messages at
+/// runtime.
+/// TODO(vsm): Consider changing all invocations to pass / cache on location
+/// instead.  That gives more useful feedback to the user.
+void _nullWarnOnType(type) {
+  bool result = JS('', '#.has(#)', _nullComparisonSet, type);
+  if (!result) {
+    JS('', '#.add(#)', _nullComparisonSet, type);
+    _nullWarn("Null is not a subtype of $type.");
+  }
+}
+
+var _lazyJSTypes = JS<Object>('', 'new Map()');
+var _anonymousJSTypes = JS<Object>('', 'new Map()');
 
 lazyJSType(Function() getJSTypeCallback, String name) {
   var ret = JS('', '#.get(#)', _lazyJSTypes, name);
@@ -214,22 +265,163 @@
   return ret;
 }
 
+/// A javascript Symbol used to store a canonical version of T? on T.
+final _cachedNullable = JS('', 'Symbol("cachedNullable")');
+
+/// A javascript Symbol used to store a canonical version of T* on T.
+final _cachedLegacy = JS('', 'Symbol("cachedLegacy")');
+
+/// A javascript Symbol used to store prior subtype checks and their results.
+final _subtypeCache = JS('', 'Symbol("_subtypeCache")');
+
+/// Returns a nullable (question, ?) version of [type].
+///
+/// The resulting type returned in a normalized form based on the rules from the
+/// normalization doc:
+/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
+@notNull
+Object nullable(@notNull Object type) {
+  // Check if a nullable version of this type has already been created.
+  var cached = JS<Object>('', '#[#]', type, _cachedNullable);
+  if (JS<bool>('!', '# !== void 0', cached)) {
+    return cached;
+  }
+
+  // Cache a canonical nullable version of this type on this type.
+  Object cachedType = _computeNullable(type);
+  JS('', '#[#] = #', type, _cachedNullable, cachedType);
+  return cachedType;
+}
+
+Object _computeNullable(@notNull Object type) {
+  // *? normalizes to ?.
+  if (_jsInstanceOf(type, LegacyType)) {
+    return nullable(JS<Object>('!', '#.type', type));
+  }
+  if (_jsInstanceOf(type, NullableType) ||
+      _isTop(type) ||
+      _equalType(type, Null) ||
+      // Normalize FutureOr<T?>? --> FutureOr<T?>
+      // All other runtime FutureOr normalization is in `normalizeFutureOr()`.
+      ((_isFutureOr(type)) &&
+          _jsInstanceOf(
+              JS<Object>('!', '#[0]', getGenericArgs(type)), NullableType))) {
+    return type;
+  }
+  if (_equalType(type, Never)) return unwrapType(Null);
+  return NullableType(JS<Type>('!', '#', type));
+}
+
+/// Returns a legacy (star, *) version of [type].
+///
+/// The resulting type returned in a normalized form based on the rules from the
+/// normalization doc:
+/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
+@notNull
+Object legacy(@notNull Object type) {
+  // Check if a legacy version of this type has already been created.
+  var cached = JS<Object>('', '#[#]', type, _cachedLegacy);
+  if (JS<bool>('!', '# !== void 0', cached)) {
+    return cached;
+  }
+
+  // Cache a canonical legacy version of this type on this type.
+  Object cachedType = _computeLegacy(type);
+  JS('', '#[#] = #', type, _cachedLegacy, cachedType);
+  return cachedType;
+}
+
+Object _computeLegacy(@notNull Object type) {
+  // Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy].
+  if (_jsInstanceOf(type, LegacyType) ||
+      _jsInstanceOf(type, NullableType) ||
+      _isTop(type) ||
+      _equalType(type, Null)) {
+    return type;
+  }
+  return LegacyType(JS<Type>('!', '#', type));
+}
+
+/// A wrapper to identify a nullable (question, ?) type of the form [type]?.
+class NullableType extends DartType {
+  final Type type;
+
+  NullableType(@notNull this.type);
+
+  @override
+  String get name => '$type?';
+
+  @override
+  String toString() => name;
+
+  @JSExportName('is')
+  bool is_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj);
+
+  @JSExportName('as')
+  as_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj)
+      ? obj
+      : cast(obj, this);
+}
+
+/// A wrapper to identify a legacy (star, *) type of the form [type]*.
+class LegacyType extends DartType {
+  final Type type;
+
+  LegacyType(@notNull this.type);
+
+  @override
+  String get name => '$type';
+
+  @override
+  String toString() => name;
+
+  @JSExportName('is')
+  bool is_T(obj) {
+    if (obj == null) {
+      // Object and Never are the only legacy types that should return true if
+      // obj is `null`.
+      return _equalType(type, Object) || _equalType(type, Never);
+    }
+    return JS<bool>('!', '#.is(#)', type, obj);
+  }
+
+  @JSExportName('as')
+  as_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj)
+      ? obj
+      : cast(obj, this);
+}
+
+// TODO(nshahan) Add override optimizations for is and as?
+class NeverType extends DartType {
+  @override
+  toString() => 'Never';
+}
+
+@JSExportName('Never')
+final _never = NeverType();
+
 @JSExportName('dynamic')
 final _dynamic = DynamicType();
 
 class VoidType extends DartType {
   toString() => 'void';
+
+  @notNull
+  @JSExportName('is')
+  bool is_T(object) => true;
+
+  @JSExportName('as')
+  Object as_T(Object object) => object;
 }
 
 @JSExportName('void')
 final void_ = VoidType();
 
+// TODO(nshahan): Cleanup and consolidate NeverType, BottomType, bottom, _never.
 class BottomType extends DartType {
   toString() => 'bottom';
 }
 
-// TODO(vsm): We reify bottom as Null.  We will revisit this with
-// non-nullable types.
 final bottom = unwrapType(Null);
 
 class JSObjectType extends DartType {
@@ -254,19 +446,99 @@
   Type get runtimeType => Type;
 }
 
-/// Given an internal runtime type object, wraps it in a `_Type` object
+/// Given an internal runtime type object [type], wraps it in a `_Type` object
 /// that implements the dart:core Type interface.
-Type wrapType(type) {
+///
+/// [isNormalized] is true when [type] is known to be in a canonicalized
+/// normal form, so the algorithm can directly wrap and return the value.
+Type wrapType(type, [@notNull bool isNormalized = false]) {
   // If we've already wrapped this type once, use the previous wrapper. This
   // way, multiple references to the same type return an identical Type.
   if (JS('!', '#.hasOwnProperty(#)', type, _typeObject)) {
     return JS('', '#[#]', type, _typeObject);
   }
-  var result = _Type(type);
+  var result = isNormalized
+      ? _Type(type)
+      : (_jsInstanceOf(type, LegacyType)
+          ? wrapType(JS<Object>('!', '#.type', type))
+          : _canonicalizeNormalizedTypeObject(type));
   JS('', '#[#] = #', type, _typeObject, result);
   return result;
 }
 
+/// Constructs a normalized version of a type.
+///
+/// Used for type object identity. Normalization requires us to return a
+/// canonicalized version of the input with all legacy wrappers removed.
+Type _canonicalizeNormalizedTypeObject(type) {
+  assert(!_jsInstanceOf(type, LegacyType));
+  // We don't call _canonicalizeNormalizedTypeObject recursively but call wrap
+  // + unwrap to handle legacy types automatically and force caching the
+  // canonicalized type under the _typeObject cache property directly. This
+  // way we ensure we always use the canonical normalized instance for each
+  // type term.
+  Object normalizeHelper(a) => unwrapType(wrapType(a));
+
+  // GenericFunctionTypeIdentifiers are implicitly normalized.
+  if (_jsInstanceOf(type, GenericFunctionTypeIdentifier)) {
+    return wrapType(type, true);
+  }
+  if (_jsInstanceOf(type, FunctionType)) {
+    var normReturnType = normalizeHelper(type.returnType);
+    var normArgs = type.args.map(normalizeHelper).toList();
+    if (JS<bool>('!', '#.Object.keys(#).length === 0', global_, type.named) &&
+        JS<bool>('!', '#.Object.keys(#).length === 0', global_,
+            type.requiredNamed)) {
+      if (type.optionals.isEmpty) {
+        var normType = fnType(normReturnType, normArgs);
+        return wrapType(normType, true);
+      }
+      var normOptionals = type.optionals.map(normalizeHelper).toList();
+      var normType = fnType(normReturnType, normArgs, normOptionals);
+      return wrapType(normType, true);
+    }
+    var normNamed = JS('', '{}');
+    _transformJSObject(type.named, normNamed, normalizeHelper);
+    var normRequiredNamed = JS('', '{}');
+    _transformJSObject(type.requiredNamed, normRequiredNamed, normalizeHelper);
+    var normType =
+        fnType(normReturnType, normArgs, normNamed, normRequiredNamed);
+    return wrapType(normType, true);
+  }
+  if (_jsInstanceOf(type, GenericFunctionType)) {
+    var formals = _getCanonicalTypeFormals(type.typeFormals.length);
+    var normBounds =
+        type.instantiateTypeBounds(formals).map(normalizeHelper).toList();
+    var normFunc = normalizeHelper(type.instantiate(formals)) as FunctionType;
+    // Create a comparison key for structural identity.
+    var typeObjectIdKey = JS('', '[]');
+    JS('', '#.push(...#)', typeObjectIdKey, normBounds);
+    JS('', '#.push(#)', typeObjectIdKey, normFunc);
+    var memoizedId = _memoizeArray(_gFnTypeTypeMap, typeObjectIdKey,
+        () => GenericFunctionTypeIdentifier(formals, normBounds, normFunc));
+    return wrapType(memoizedId, true);
+  }
+  var args = getGenericArgs(type);
+  var normType;
+  if (args == null || args.isEmpty) {
+    normType = type;
+  } else {
+    var genericClass = getGenericClass(type);
+    var normArgs = args.map(normalizeHelper).toList();
+    normType = JS('!', '#(...#)', genericClass, normArgs);
+  }
+  return wrapType(normType, true);
+}
+
+/// Generates new values by applying [transform] to the values of [srcObject],
+/// storing them in [dstObject] with the same key.
+void _transformJSObject(srcObject, dstObject, Function transform) {
+  for (Object key in JS('!', '#.Object.keys(#)', global_, srcObject)) {
+    JS('', '#[#] = #', dstObject, key,
+        transform(JS('', '#[#]', srcObject, key)));
+  }
+}
+
 /// The symbol used to store the cached `Type` object associated with a class.
 final _typeObject = JS('', 'Symbol("typeObject")');
 
@@ -305,6 +577,38 @@
 /// index path (if present) is the canonical function type.
 final List _fnTypeSmallMap = JS('', '[new Map(), new Map(), new Map()]');
 
+/// Memo table for generic function types. The index path consists of the
+/// type parameters' bounds and the underlying function instantiated to its
+/// bounds, subject to the same restrictions mentioned in _fnTypeTypeMap.
+final _gFnTypeTypeMap = JS('', 'new Map()');
+
+/// Pre-initialized type variables used to ensure that generic functions with
+/// the same generic relationship structure but different names canonicalize
+/// correctly.
+final _typeVariablePool = <TypeVariable>[];
+
+/// Returns a canonicalized sequence of type variables of size [count].
+List<TypeVariable> _getCanonicalTypeFormals(int count) {
+  while (count > _typeVariablePool.length) {
+    _fillTypeVariable();
+  }
+  return _typeVariablePool.sublist(0, count);
+}
+
+/// Inserts a new type variable into _typeVariablePool according to a
+/// pre-determined pattern.
+///
+/// The first 26 generics are alphanumerics; the remainder are represented as
+/// T$N, where N increments from 0.
+void _fillTypeVariable() {
+  if (_typeVariablePool.length < 26) {
+    _typeVariablePool
+        .add(TypeVariable(String.fromCharCode(65 + _typeVariablePool.length)));
+  } else {
+    _typeVariablePool.add(TypeVariable('T${_typeVariablePool.length - 26}'));
+  }
+}
+
 @NoReifyGeneric()
 T _memoizeArray<T>(map, arr, T create()) => JS('', '''(() => {
   let len = $arr.length;
@@ -321,8 +625,8 @@
 List _canonicalizeArray(List array, map) =>
     _memoizeArray(map, array, () => array);
 
-// TODO(leafp): This only canonicalizes of the names are
-// emitted in a consistent order.
+// TODO(leafp): This only canonicalizes if the names are emitted
+// in a consistent order.
 _canonicalizeNamed(named, map) => JS('', '''(() => {
   let key = [];
   let names = $getOwnPropertyNames($named);
@@ -346,7 +650,7 @@
  }
  let result = map.get($returnType);
  if (result !== void 0) return result;
- result = ${new FunctionType(returnType, required, [], JS('', '{}'))};
+ result = ${new FunctionType(returnType, required, [], JS('', '{}'), JS('', '{}'))};
  map.set($returnType, result);
  return result;
 })()''');
@@ -357,6 +661,7 @@
   final List optionals;
   // Named arguments native JS Object of the form { namedArgName: namedArgType }
   final named;
+  final requiredNamed;
   String _stringValue;
 
   /// Construct a function type.
@@ -369,35 +674,40 @@
   ///
   /// Note: Generic function subtype checks assume types have been canonicalized
   /// when testing if type bounds are equal.
-  static FunctionType create(returnType, List args, extra) {
-    // Note that if extra is ever passed as an empty array
-    // or an empty map, we can end up with semantically
-    // identical function types that don't canonicalize
-    // to the same object since we won't fall into this
-    // fast path.
-    if (extra == null && JS<bool>('!', '#.length < 3', args)) {
+  static FunctionType create(
+      returnType, List args, optionalArgs, requiredNamedArgs) {
+    // Note that if optionalArgs is ever passed as an empty array or an empty
+    // map, we can end up with semantically identical function types that don't
+    // canonicalize to the same object since we won't fall into this fast path.
+    var noOptionalArgs = optionalArgs == null && requiredNamedArgs == null;
+    if (noOptionalArgs && JS<bool>('!', '#.length < 3', args)) {
       return _createSmall(returnType, args);
     }
     args = _canonicalizeArray(args, _fnTypeArrayArgMap);
-    var keys;
+    var keys = [];
     FunctionType Function() create;
-    if (extra == null) {
+    if (noOptionalArgs) {
       keys = [returnType, args];
-      create = () => FunctionType(returnType, args, [], JS('', '{}'));
-    } else if (JS('!', '# instanceof Array', extra)) {
+      create =
+          () => FunctionType(returnType, args, [], JS('', '{}'), JS('', '{}'));
+    } else if (JS('!', '# instanceof Array', optionalArgs)) {
       var optionals =
-          _canonicalizeArray(JS('', '#', extra), _fnTypeArrayArgMap);
+          _canonicalizeArray(JS('', '#', optionalArgs), _fnTypeArrayArgMap);
       keys = [returnType, args, optionals];
-      create = () => FunctionType(returnType, args, optionals, JS('', '{}'));
+      create = () =>
+          FunctionType(returnType, args, optionals, JS('', '{}'), JS('', '{}'));
     } else {
-      var named = _canonicalizeNamed(extra, _fnTypeNamedArgMap);
-      keys = [returnType, args, named];
-      create = () => FunctionType(returnType, args, [], named);
+      var named = _canonicalizeNamed(optionalArgs, _fnTypeNamedArgMap);
+      var requiredNamed =
+          _canonicalizeNamed(requiredNamedArgs, _fnTypeNamedArgMap);
+      keys = [returnType, args, named, requiredNamed];
+      create = () => FunctionType(returnType, args, [], named, requiredNamed);
     }
     return _memoizeArray(_fnTypeTypeMap, keys, create);
   }
 
-  FunctionType(this.returnType, this.args, this.optionals, this.named);
+  FunctionType(this.returnType, this.args, this.optionals, this.named,
+      this.requiredNamed);
 
   toString() => name;
 
@@ -409,9 +719,10 @@
     return i < n ? args[i] : optionals[i + n];
   }
 
-  Map<String, Object> getNamedParameters() {
+  /// Maps argument names to their canonicalized type.
+  Map<String, Object> _createNameMap(List<Object> names) {
     var result = <String, Object>{};
-    var names = getOwnPropertyNames(named);
+    // TODO: Remove this sort if ordering can be conserved.
     JS('', '#.sort()', names);
     for (var i = 0; JS<bool>('!', '# < #.length', i, names); ++i) {
       String name = JS('!', '#[#]', names, i);
@@ -420,9 +731,16 @@
     return result;
   }
 
+  /// Maps optional named parameter names to their canonicalized type.
+  Map<String, Object> getNamedParameters() =>
+      _createNameMap(getOwnPropertyNames(named).toList());
+
+  /// Maps required named parameter names to their canonicalized type.
+  Map<String, Object> getRequiredNamedParameters() =>
+      _createNameMap(getOwnPropertyNames(requiredNamed).toList());
+
   get name {
     if (_stringValue != null) return _stringValue;
-
     var buffer = '(';
     for (var i = 0; JS<bool>('!', '# < #.length', i, args); ++i) {
       if (i > 0) {
@@ -440,21 +758,33 @@
         buffer += typeName(JS('', '#[#]', optionals, i));
       }
       buffer += ']';
-    } else if (JS('!', 'Object.keys(#).length > 0', named)) {
+    } else if (JS('!', 'Object.keys(#).length > 0 || Object.keys(#).length > 0',
+        named, requiredNamed)) {
       if (JS('!', '#.length > 0', args)) buffer += ', ';
       buffer += '{';
       var names = getOwnPropertyNames(named);
       JS('', '#.sort()', names);
-      for (var i = 0; JS<bool>('!', '# < #.length', i, names); ++i) {
+      for (var i = 0; JS<bool>('!', '# < #.length', i, names); i++) {
         if (i > 0) {
           buffer += ', ';
         }
         var typeNameString = typeName(JS('', '#[#[#]]', named, names, i));
         buffer += '$typeNameString ${JS('', '#[#]', names, i)}';
       }
+      if (JS('!', 'Object.keys(#).length > 0 && #.length > 0', requiredNamed,
+          names)) buffer += ', ';
+      names = getOwnPropertyNames(requiredNamed);
+      JS('', '#.sort()', names);
+      for (var i = 0; JS<bool>('!', '# < #.length', i, names); i++) {
+        if (i > 0) {
+          buffer += ', ';
+        }
+        var typeNameString =
+            typeName(JS('', '#[#[#]]', requiredNamed, names, i));
+        buffer += 'required $typeNameString ${JS('', '#[#]', names, i)}';
+      }
       buffer += '}';
     }
-
     var returnTypeName = typeName(returnType);
     buffer += ') => $returnTypeName';
     _stringValue = buffer;
@@ -474,16 +804,10 @@
 
   @JSExportName('as')
   as_T(obj) {
-    if (obj == null) return obj;
-    if (JS('!', 'typeof # == "function"', obj)) {
-      var actual = JS('', '#[#]', obj, _runtimeType);
-      // If there's no actual type, it's a JS function.
-      // Allow them to subtype all Dart function types.
-      if (actual == null || isSubtypeOf(actual, this)) {
-        return obj;
-      }
-    }
-    return castError(obj, this);
+    if (is_T(obj)) return obj;
+    // TODO(nshahan) This could directly call castError after we no longer allow
+    // a cast of null to succeed in weak mode.
+    return cast(obj, this);
   }
 }
 
@@ -503,20 +827,59 @@
   static const int invariant = 3;
 }
 
+/// Uniquely identifies the runtime type object of a generic function.
+///
+/// We require that all objects stored in this object not have legacy
+/// nullability wrappers.
+class GenericFunctionTypeIdentifier extends AbstractFunctionType {
+  final typeFormals;
+  final typeBounds;
+  final FunctionType function;
+  String _stringValue;
+
+  GenericFunctionTypeIdentifier(
+      this.typeFormals, this.typeBounds, this.function);
+
+  /// Returns the string-representation of the first generic function
+  /// with this runtime type object canonicalization.
+  ///
+  /// Type formal names may not correspond to those of the originating type.
+  /// We should consider auto-generating these to avoid confusion.
+  toString() {
+    if (_stringValue != null) return _stringValue;
+    String s = "<";
+    var typeFormals = this.typeFormals;
+    var typeBounds = this.typeBounds;
+    for (int i = 0, n = typeFormals.length; i < n; i++) {
+      if (i != 0) s += ", ";
+      s += JS<String>('!', '#[#].name', typeFormals, i);
+      var bound = typeBounds[i];
+      if (_equalType(bound, dynamic) ||
+          JS<bool>('!', '# === #', bound, nullable(unwrapType(Object))) ||
+          (!strictNullSafety && _equalType(bound, Object))) {
+        // Do not print the bound when it is a top type. In weak mode the bounds
+        // of Object and Object* will also be elided.
+        continue;
+      }
+      s += " extends $bound";
+    }
+    s += ">" + this.function.toString();
+    return this._stringValue = s;
+  }
+}
+
 class GenericFunctionType extends AbstractFunctionType {
   final _instantiateTypeParts;
   final int formalCount;
   final _instantiateTypeBounds;
-  List<TypeVariable> _typeFormals;
+  final List<TypeVariable> _typeFormals;
 
   GenericFunctionType(instantiateTypeParts, this._instantiateTypeBounds)
       : _instantiateTypeParts = instantiateTypeParts,
-        formalCount = JS('!', '#.length', instantiateTypeParts);
+        formalCount = JS('!', '#.length', instantiateTypeParts),
+        _typeFormals = _typeFormalsFromFunction(instantiateTypeParts);
 
-  List<TypeVariable> get typeFormals {
-    if (_typeFormals != null) return _typeFormals;
-    return _typeFormals = _typeFormalsFromFunction(_instantiateTypeParts);
-  }
+  List<TypeVariable> get typeFormals => _typeFormals;
 
   /// `true` if there are bounds on any of the generic type parameters.
   get hasTypeBounds => _instantiateTypeBounds != null;
@@ -537,20 +900,22 @@
 
   FunctionType instantiate(typeArgs) {
     var parts = JS('', '#.apply(null, #)', _instantiateTypeParts, typeArgs);
-    return FunctionType.create(
-        JS('', '#[0]', parts), JS('', '#[1]', parts), JS('', '#[2]', parts));
+    return FunctionType.create(JS('', '#[0]', parts), JS('', '#[1]', parts),
+        JS('', '#[2]', parts), JS('', '#[3]', parts));
   }
 
-  List instantiateTypeBounds(List typeArgs) {
+  List<Object> instantiateTypeBounds(List typeArgs) {
     if (!hasTypeBounds) {
-      // The Dart 1 spec says omitted type parameters have an upper bound of
-      // Object. However Dart 2 uses `dynamic` for the purpose of instantiate to
-      // bounds, so we use that here.
-      return List.filled(formalCount, _dynamic);
+      // We omit the a bound to represent Object*. Other bounds are explicitly
+      // represented, including Object, Object? and dynamic.
+      // TODO(nshahan) Revisit this representation when more libraries have
+      // migrated to null safety.
+      return List<Object>.filled(formalCount, legacy(unwrapType(Object)));
     }
     // Bounds can be recursive or depend on other type parameters, so we need to
     // apply type arguments and return the resulting bounds.
-    return JS('List', '#.apply(null, #)', _instantiateTypeBounds, typeArgs);
+    return JS<List<Object>>(
+        '!', '#.apply(null, #)', _instantiateTypeBounds, typeArgs);
   }
 
   toString() {
@@ -576,17 +941,37 @@
   /// See the issue for the algorithm description:
   /// <https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397>
   List instantiateDefaultBounds() {
+    /// Returns `true` if the default value for the type bound should be
+    /// `dynamic`.
+    ///
+    /// Dart 2 with null safety uses dynamic as the default value for types
+    /// without explicit bounds.
+    ///
+    /// This is similar to [_isTop] but removes the check for `void` (it can't
+    /// be written as a bound) and adds a check of `Object*` in weak mode.
+    bool defaultsToDynamic(type) {
+      // Technically this is wrong, only implicit bounds of `Object?` and
+      // `Object*` should default to dynamic but code that observes the
+      // difference is rare.
+      if (_equalType(type, dynamic)) return true;
+      if (_jsInstanceOf(type, NullableType) ||
+          (!strictNullSafety && _jsInstanceOf(type, LegacyType))) {
+        return _equalType(JS('!', '#.type', type), Object);
+      }
+      return false;
+    }
+
     var typeFormals = this.typeFormals;
 
     // All type formals
-    var all = HashMap<Object, int>.identity();
+    var all = HashMap<TypeVariable, int>.identity();
     // ground types, by index.
     //
     // For each index, this will be a ground type for the corresponding type
     // formal if known, or it will be the original TypeVariable if we are still
     // solving for it. This array is passed to `instantiateToBounds` as we are
     // progressively solving for type variables.
-    var defaults = List<Object>(typeFormals.length);
+    var defaults = List<Object>.filled(typeFormals.length, null);
     // not ground
     var partials = Map<TypeVariable, Object>.identity();
 
@@ -595,29 +980,33 @@
       var typeFormal = typeFormals[i];
       var bound = typeBounds[i];
       all[typeFormal] = i;
-      if (identical(bound, _dynamic)) {
-        defaults[i] = bound;
+      if (defaultsToDynamic(bound)) {
+        // TODO(nshahan) Persist the actual default values into the runtime so
+        // they can be used here instead of using dynamic for all top types
+        // implicit or explicit.
+        defaults[i] = _dynamic;
       } else {
         defaults[i] = typeFormal;
         partials[typeFormal] = bound;
       }
     }
 
-    bool hasFreeFormal(Object t) {
+    bool hasFreeFormal(t) {
       if (partials.containsKey(t)) return true;
 
+      // Ignore nullability wrappers.
+      if (_jsInstanceOf(t, LegacyType) || _jsInstanceOf(t, NullableType)) {
+        return hasFreeFormal(JS<Object>('!', '#.type', t));
+      }
       // Generic classes and typedefs.
       var typeArgs = getGenericArgs(t);
       if (typeArgs != null) return typeArgs.any(hasFreeFormal);
-
       if (t is GenericFunctionType) {
         return hasFreeFormal(t.instantiate(t.typeFormals));
       }
-
       if (t is FunctionType) {
         return hasFreeFormal(t.returnType) || t.args.any(hasFreeFormal);
       }
-
       return false;
     }
 
@@ -660,8 +1049,10 @@
 
   @JSExportName('as')
   as_T(obj) {
-    if (obj == null || is_T(obj)) return obj;
-    return castError(obj, this);
+    if (is_T(obj)) return obj;
+    // TODO(nshahan) This could directly call castError after we no longer allow
+    // a cast of null to succeed in weak mode.
+    return cast(obj, this);
   }
 }
 
@@ -690,8 +1081,9 @@
 }
 
 /// Create a function type.
-FunctionType fnType(returnType, List args, [@undefined extra]) =>
-    FunctionType.create(returnType, args, extra);
+FunctionType fnType(returnType, List args,
+        [@undefined optional, @undefined requiredNamed]) =>
+    FunctionType.create(returnType, args, optional, requiredNamed);
 
 /// Creates a generic function type from [instantiateFn] and [typeBounds].
 ///
@@ -727,7 +1119,7 @@
   if ($type === void 0) return "undefined type";
   if ($type === null) return "null type";
   // Non-instance types
-  if ($type instanceof $DartType) {
+  if (${_jsInstanceOf(type, DartType)}) {
     return $type.toString();
   }
 
@@ -754,7 +1146,7 @@
 })()''');
 
 /// Returns true if [ft1] <: [ft2].
-_isFunctionSubtype(ft1, ft2) => JS('', '''(() => {
+_isFunctionSubtype(ft1, ft2, @notNull bool strictMode) => JS('', '''(() => {
   let ret1 = $ft1.returnType;
   let ret2 = $ft2.returnType;
 
@@ -766,7 +1158,7 @@
   }
 
   for (let i = 0; i < args1.length; ++i) {
-    if (!$_isSubtype(args2[i], args1[i])) {
+    if (!$_isSubtype(args2[i], args1[i], strictMode)) {
       return false;
     }
   }
@@ -780,21 +1172,44 @@
 
   let j = 0;
   for (let i = args1.length; i < args2.length; ++i, ++j) {
-    if (!$_isSubtype(args2[i], optionals1[j])) {
+    if (!$_isSubtype(args2[i], optionals1[j], strictMode)) {
       return false;
     }
   }
 
   for (let i = 0; i < optionals2.length; ++i, ++j) {
-    if (!$_isSubtype(optionals2[i], optionals1[j])) {
+    if (!$_isSubtype(optionals2[i], optionals1[j], strictMode)) {
       return false;
     }
   }
 
+  // Named parameter invariants:
+  // 1) All named params in the superclass are named params in the subclass.
+  // 2) All required named params in the subclass are required named params
+  //    in the superclass.
+  // 3) With strict null checking disabled, we treat required named params as
+  //    optional named params.
   let named1 = $ft1.named;
+  let requiredNamed1 = $ft1.requiredNamed;
   let named2 = $ft2.named;
+  let requiredNamed2 = $ft2.requiredNamed;
+  if (!strictMode) {
+    // In weak mode, treat required named params as optional named params.
+    named1 = Object.assign({}, named1, requiredNamed1);
+    named2 = Object.assign({}, named2, requiredNamed2);
+    requiredNamed1 = {};
+    requiredNamed2 = {};
+  }
 
-  let names = $getOwnPropertyNames(named2);
+  let names = $getOwnPropertyNames(requiredNamed1);
+  for (let i = 0; i < names.length; ++i) {
+    let name = names[i];
+    let n2 = requiredNamed2[name];
+    if (n2 === void 0) {
+      return false;
+    }
+  }
+  names = $getOwnPropertyNames(named2);
   for (let i = 0; i < names.length; ++i) {
     let name = names[i];
     let n1 = named1[name];
@@ -802,61 +1217,174 @@
     if (n1 === void 0) {
       return false;
     }
-    if (!$_isSubtype(n2, n1)) {
+    if (!$_isSubtype(n2, n1, strictMode)) {
+      return false;
+    }
+  }
+  names = $getOwnPropertyNames(requiredNamed2);
+  for (let i = 0; i < names.length; ++i) {
+    let name = names[i];
+    let n1 = named1[name] || requiredNamed1[name];
+    let n2 = requiredNamed2[name];
+    if (n1 === void 0) {
+      return false;
+    }
+    if (!$_isSubtype(n2, n1, strictMode)) {
       return false;
     }
   }
 
-  return $_isSubtype(ret1, ret2);
+  return $_isSubtype(ret1, ret2, strictMode);
 })()''');
 
 /// Returns true if [t1] <: [t2].
 @notNull
-bool isSubtypeOf(Object t1, Object t2) {
+bool isSubtypeOf(@notNull Object t1, @notNull Object t2) {
   // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
   // dispatched on the type. Can we optimize the subtype relation too?
-  Object map;
-  if (JS('!', '!#.hasOwnProperty(#)', t1, _subtypeCache)) {
-    JS('', '#[#] = # = new Map()', t1, _subtypeCache, map);
-    _cacheMaps.add(map);
-  } else {
-    map = JS('', '#[#]', t1, _subtypeCache);
-    bool result = JS('', '#.get(#)', map, t2);
-    if (JS('!', '# !== void 0', result)) return result;
+  var map = JS<Object>('!', '#[#]', t1, _subtypeCache);
+  bool result = JS('', '#.get(#)', map, t2);
+  if (JS('!', '# !== void 0', result)) return result;
+
+  var validSubtype = _isSubtype(t1, t2, true);
+  if (!validSubtype && !strictNullSafety) {
+    validSubtype = _isSubtype(t1, t2, false);
+    if (validSubtype) {
+      // TODO(nshahan) Need more information to be helpful here.
+      // File and line number that caused the subtype check?
+      // Possibly break into debugger?
+      _nullWarn("$t1 is not a subtype of $t2.");
+    }
   }
-  var result = _isSubtype(t1, t2);
-  JS('', '#.set(#, #)', map, t2, result);
-  return result;
+  JS('', '#.set(#, #)', map, t2, validSubtype);
+  return validSubtype;
 }
 
-final _subtypeCache = JS('', 'Symbol("_subtypeCache")');
-
 @notNull
-bool _isBottom(type) => JS('!', '# == # || # == #', type, bottom, type, Null);
+bool _isBottom(type, @notNull bool strictMode) =>
+    _equalType(type, Never) || (!strictMode && _equalType(type, Null));
 
 @notNull
 bool _isTop(type) {
-  return JS('!', '# == # || # == # || # == #', type, Object, type, dynamic,
-      type, void_);
+  if (_jsInstanceOf(type, NullableType))
+    return JS('!', '#.type === #', type, Object);
+
+  return _equalType(type, dynamic) || JS('!', '# === #', type, void_);
+}
+
+/// Wraps the JavaScript `instanceof` operator returning  `true` if [type] is an
+/// instance of [cls].
+///
+/// This method is equivalent to:
+///
+///    JS<bool>('!', '# instanceof #', type, cls);
+///
+/// but the code is generated by the compiler directly (a low-tech way of
+/// inlining).
+@notNull
+external bool _jsInstanceOf(type, cls);
+
+/// Returns `true` if [type] is [cls].
+///
+/// This method is equivalent to:
+///
+///    JS<bool>('!', '# === #', type, unwrapType(cls));
+///
+/// but the code is generated by the compiler directly (a low-tech way of
+/// inlining).
+@notNull
+external bool _equalType(type, cls);
+
+/// Extracts the type argument as an unwrapped type preserving all forms of
+/// nullability.
+///
+/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For
+/// example `typeRep<Object?>()` emits `dart.nullable(core.Object)` directly.
+@notNull
+external Type typeRep<T>();
+
+/// Extracts the type argument as an unwrapped type and performs a shallow
+/// replacement of the nullability to a legacy type.
+///
+/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For
+/// example `legacyTypeRep<Object>()` emits `dart.legacy(core.Object)` directly.
+@notNull
+external Type legacyTypeRep<T>();
+
+@notNull
+bool _isFutureOr(type) {
+  var genericClass = getGenericClass(type);
+  return JS<bool>('!', '# && # === #', genericClass, genericClass,
+      getGenericClass(FutureOr));
 }
 
 @notNull
-bool _isFutureOr(type) =>
-    identical(getGenericClass(type), getGenericClass(FutureOr));
-
-bool _isSubtype(t1, t2) => JS('', '''(() => {
+bool _isSubtype(t1, t2, @notNull bool strictMode) => JS<bool>('!', '''(() => {
+  if (!$strictMode) {
+    // Strip nullable types when performing check in weak mode.
+    // TODO(nshahan) Investigate stripping off legacy types as well.
+    if (${_jsInstanceOf(t1, NullableType)}) {
+      t1 = t1.type;
+    }
+    if (${_jsInstanceOf(t2, NullableType)}) {
+      t2 = t2.type;
+    }
+  }
   if ($t1 === $t2) {
     return true;
   }
 
-  // Trivially true.
-  if (${_isTop(t2)} || ${_isBottom(t1)}) {
+  // Trivially true, "Right Top" or "Left Bottom".
+  if (${_isTop(t2)} || ${_isBottom(t1, strictMode)}) {
     return true;
   }
 
-  // Trivially false.
-  if (${_isTop(t1)} || ${_isBottom(t2)}) {
-    return false;
+  // "Left Top".
+  if (${_equalType(t1, dynamic)} || $t1 === $void_) {
+    return $_isSubtype($nullable($Object), $t2, $strictMode);
+  }
+
+  // "Right Object".
+  if (${_equalType(t2, Object)}) {
+    // TODO(nshahan) Need to handle type variables.
+    // https://github.com/dart-lang/sdk/issues/38816
+    if (${_isFutureOr(t1)}) {
+      let t1TypeArg = ${getGenericArgs(t1)}[0];
+      return $_isSubtype(t1TypeArg, $Object, $strictMode);
+    }
+
+    if (${_jsInstanceOf(t1, LegacyType)}) {
+      return $_isSubtype(t1.type, t2, $strictMode);
+    }
+
+    if (${_equalType(t1, Null)} || ${_jsInstanceOf(t1, NullableType)}) {
+      // Checks for t1 is dynamic or void already performed in "Left Top" test.
+      return false;
+    }
+    return true;
+  }
+
+  // "Left Null".
+  if (${_equalType(t1, Null)}) {
+    // TODO(nshahan) Need to handle type variables.
+    // https://github.com/dart-lang/sdk/issues/38816
+    if (${_isFutureOr(t2)}) {
+      let t2TypeArg = ${getGenericArgs(t2)}[0];
+      return $_isSubtype($Null, t2TypeArg, $strictMode);
+    }
+
+    return ${_equalType(t2, Null)} || ${_jsInstanceOf(t2, LegacyType)} ||
+        ${_jsInstanceOf(t2, NullableType)};
+  }
+
+  // "Left Legacy".
+  if (${_jsInstanceOf(t1, LegacyType)}) {
+    return $_isSubtype(t1.type, t2, $strictMode);
+  }
+
+  // "Right Legacy".
+  if (${_jsInstanceOf(t2, LegacyType)}) {
+    return $_isSubtype(t1, $nullable(t2.type), $strictMode);
   }
 
   // Handle FutureOr<T> union type.
@@ -867,14 +1395,22 @@
       // FutureOr<A> <: FutureOr<B> iff A <: B
       // TODO(nshahan): Proven to not actually be true and needs cleanup.
       // https://github.com/dart-lang/sdk/issues/38818
-      return $_isSubtype(t1TypeArg, t2TypeArg);
+      return $_isSubtype(t1TypeArg, t2TypeArg, $strictMode);
     }
 
     // given t1 is Future<A> | A, then:
     // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
     let t1Future = ${getGenericClass(Future)}(t1TypeArg);
     // Known to handle the case FutureOr<Null> <: Future<Null>.
-    return $_isSubtype(t1Future, $t2) && $_isSubtype(t1TypeArg, $t2);
+    return $_isSubtype(t1Future, $t2, $strictMode) &&
+        $_isSubtype(t1TypeArg, $t2, $strictMode);
+  }
+
+  // "Left Nullable".
+  if (${_jsInstanceOf(t1, NullableType)}) {
+    // TODO(nshahan) Need to handle type variables.
+    // https://github.com/dart-lang/sdk/issues/38816
+    return $_isSubtype(t1.type, t2, $strictMode) && $_isSubtype($Null, t2, $strictMode);
   }
 
   if ($_isFutureOr($t2)) {
@@ -882,38 +1418,47 @@
     // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
     let t2TypeArg = ${getGenericArgs(t2)}[0];
     let t2Future = ${getGenericClass(Future)}(t2TypeArg);
-    return $_isSubtype($t1, t2Future) || $_isSubtype($t1, t2TypeArg);
+    // TODO(nshahan) Need to handle type variables on the left.
+    // https://github.com/dart-lang/sdk/issues/38816
+    return $_isSubtype($t1, t2Future, $strictMode) || $_isSubtype($t1, t2TypeArg, $strictMode);
+  }
+
+  // "Right Nullable".
+  if (${_jsInstanceOf(t2, NullableType)}) {
+    // TODO(nshahan) Need to handle type variables.
+    // https://github.com/dart-lang/sdk/issues/38816
+    return $_isSubtype(t1, t2.type, $strictMode) || $_isSubtype(t1, $Null, $strictMode);
   }
 
   // "Traditional" name-based subtype check.  Avoid passing
   // function types to the class subtype checks, since we don't
   // currently distinguish between generic typedefs and classes.
-  if (!($t2 instanceof $AbstractFunctionType)) {
+  if (!${_jsInstanceOf(t2, AbstractFunctionType)}) {
     // t2 is an interface type.
 
-    if ($t1 instanceof $AbstractFunctionType) {
+    if (${_jsInstanceOf(t1, AbstractFunctionType)}) {
       // Function types are only subtypes of interface types `Function` (and top
       // types, handled already above).
-      return $t2 === $Function;
+      return ${_equalType(t2, Function)};
     }
 
     // All JS types are subtypes of anonymous JS types.
-    if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) {
+    if ($t1 === $jsobject && ${_jsInstanceOf(t2, AnonymousJSType)}) {
       return true;
     }
 
     // Compare two interface types.
-    return ${_isInterfaceSubtype(t1, t2)};
+    return ${_isInterfaceSubtype(t1, t2, strictMode)};
   }
 
   // Function subtyping.
-  if (!($t1 instanceof $AbstractFunctionType)) {
+  if (!${_jsInstanceOf(t1, AbstractFunctionType)}) {
     return false;
   }
 
   // Handle generic functions.
-  if ($t1 instanceof $GenericFunctionType) {
-    if (!($t2 instanceof $GenericFunctionType)) {
+  if (${_jsInstanceOf(t1, GenericFunctionType)}) {
+    if (!${_jsInstanceOf(t2, GenericFunctionType)}) {
       return false;
     }
 
@@ -947,8 +1492,8 @@
       let t2Bounds = $t2.instantiateTypeBounds(fresh);
       for (let i = 0; i < formalCount; i++) {
         if (t1Bounds[i] != t2Bounds[i]) {
-          if (!($_isSubtype(t1Bounds[i], t2Bounds[i])
-              && $_isSubtype(t2Bounds[i], t1Bounds[i]))) {
+          if (!($_isSubtype(t1Bounds[i], t2Bounds[i], $strictMode)
+              && $_isSubtype(t2Bounds[i], t1Bounds[i], $strictMode))) {
             return false;
           }
         }
@@ -957,35 +1502,35 @@
 
     $t1 = $t1.instantiate(fresh);
     $t2 = $t2.instantiate(fresh);
-  } else if ($t2 instanceof $GenericFunctionType) {
+  } else if (${_jsInstanceOf(t2, GenericFunctionType)}) {
     return false;
   }
 
   // Handle non-generic functions.
-  return ${_isFunctionSubtype(t1, t2)};
+  return ${_isFunctionSubtype(t1, t2, strictMode)};
 })()''');
 
-bool _isInterfaceSubtype(t1, t2) => JS('', '''(() => {
+bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => {
   // If we have lazy JS types, unwrap them.  This will effectively
   // reduce to a prototype check below.
-  if ($t1 instanceof $LazyJSType) $t1 = $t1.rawJSTypeForCheck();
-  if ($t2 instanceof $LazyJSType) $t2 = $t2.rawJSTypeForCheck();
+  if (${_jsInstanceOf(t1, LazyJSType)}) $t1 = $t1.rawJSTypeForCheck();
+  if (${_jsInstanceOf(t2, LazyJSType)}) $t2 = $t2.rawJSTypeForCheck();
 
   if ($t1 === $t2) {
     return true;
   }
-  if ($t1 === $Object) {
+  if (${_equalType(t1, Object)}) {
     return false;
   }
 
   // Classes cannot subtype `Function` or vice versa.
-  if ($t1 === $Function || $t2 === $Function) {
+  if (${_equalType(t1, Function)} || ${_equalType(t2, Function)}) {
     return false;
   }
 
   // If t1 is a JS Object, we may not hit core.Object.
   if ($t1 == null) {
-    return $t2 == $Object || $t2 == $dynamic;
+    return ${_equalType(t2, Object)} || ${_equalType(t2, dynamic)};
   }
 
   // Check if t1 and t2 have the same raw type.  If so, check covariance on
@@ -1003,16 +1548,16 @@
       // When using implicit variance, variances will be undefined and
       // considered covariant.
       if (variances === void 0 || variances[i] == ${Variance.covariant}) {
-        if (!$_isSubtype(typeArguments1[i], typeArguments2[i])) {
+        if (!$_isSubtype(typeArguments1[i], typeArguments2[i], $strictMode)) {
           return false;
         }
       } else if (variances[i] == ${Variance.contravariant}) {
-        if (!$_isSubtype(typeArguments2[i], typeArguments1[i])) {
+        if (!$_isSubtype(typeArguments2[i], typeArguments1[i], $strictMode)) {
           return false;
         }
       } else if (variances[i] == ${Variance.invariant}) {
-        if (!$_isSubtype(typeArguments1[i], typeArguments2[i]) ||
-            !$_isSubtype(typeArguments2[i], typeArguments1[i])) {
+        if (!$_isSubtype(typeArguments1[i], typeArguments2[i], $strictMode) ||
+            !$_isSubtype(typeArguments2[i], typeArguments1[i], $strictMode)) {
           return false;
         }
       }
@@ -1020,13 +1565,13 @@
     return true;
   }
 
-  if ($_isInterfaceSubtype(t1.__proto__, $t2)) {
+  if ($_isInterfaceSubtype(t1.__proto__, $t2, $strictMode)) {
     return true;
   }
 
   // Check mixin.
   let m1 = $getMixin($t1);
-  if (m1 != null && $_isInterfaceSubtype(m1, $t2)) {
+  if (m1 != null && $_isInterfaceSubtype(m1, $t2, $strictMode)) {
     return true;
   }
 
@@ -1034,7 +1579,7 @@
   let getInterfaces = $getImplements($t1);
   if (getInterfaces) {
     for (let i1 of getInterfaces()) {
-      if ($_isInterfaceSubtype(i1, $t2)) {
+      if ($_isInterfaceSubtype(i1, $t2, $strictMode)) {
         return true;
       }
     }
@@ -1047,6 +1592,9 @@
     throw ArgumentError('Cannot extract type of null instance.');
   }
   var type = unwrapType(T);
+  // Get underlying type from nullability wrappers if needed.
+  type = JS<Object>('!', '#.type || #', type, type);
+
   if (type is AbstractFunctionType || _isFutureOr(type)) {
     throw ArgumentError('Cannot extract from non-class type ($type).');
   }
@@ -1076,7 +1624,7 @@
 
   /// Returns the inferred types based on the current constraints.
   List<Object> getInferredTypes() {
-    var result = List<Object>();
+    var result = <Object>[];
     for (var constraint in _typeVariables.values) {
       // Prefer the known bound, if any.
       if (constraint.lower != null) {
@@ -1144,8 +1692,28 @@
         return false;
       }
     }
+
+    // Named parameter invariants:
+    // 1) All named params in the superclass are named params in the subclass.
+    // 2) All required named params in the subclass are required named params
+    //    in the superclass.
+    // 3) With strict null checking disabled, we treat required named params as
+    //    optional named params.
     var supertypeNamed = supertype.getNamedParameters();
+    var supertypeRequiredNamed = supertype.getRequiredNamedParameters();
     var subtypeNamed = supertype.getNamedParameters();
+    var subtypeRequiredNamed = supertype.getRequiredNamedParameters();
+    if (!strictNullSafety) {
+      // In weak mode, treat required named params as optional named params.
+      supertypeNamed = {...supertypeNamed, ...supertypeRequiredNamed};
+      subtypeNamed = {...subtypeNamed, ...subtypeRequiredNamed};
+      supertypeRequiredNamed = {};
+      subtypeRequiredNamed = {};
+    }
+    for (var name in subtypeRequiredNamed.keys) {
+      var supertypeParamType = supertypeRequiredNamed[name];
+      if (supertypeParamType == null) return false;
+    }
     for (var name in supertypeNamed.keys) {
       var subtypeParamType = subtypeNamed[name];
       if (subtypeParamType == null) return false;
@@ -1153,6 +1721,12 @@
         return false;
       }
     }
+    for (var name in supertypeRequiredNamed.keys) {
+      var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name];
+      if (!_isSubtypeMatch(supertypeRequiredNamed[name], subtypeParamType)) {
+        return false;
+      }
+    }
     return true;
   }
 
@@ -1190,8 +1764,6 @@
     return true;
   }
 
-  bool _isNull(Object type) => identical(type, unwrapType(Null));
-
   /// Attempts to match [subtype] as a subtype of [supertype], gathering any
   /// constraints discovered in the process.
   ///
@@ -1201,6 +1773,7 @@
   /// In the case where `false` is returned, some bogus constraints may have
   /// been added to [_protoConstraints].  It is the caller's responsibility to
   /// discard them if necessary.
+  // TODO(#40326) Update to support null safety subtyping algorithm.
   bool _isSubtypeMatch(Object subtype, Object supertype) {
     // A type variable `T` in `L` is a subtype match for any type schema `Q`:
     // - Under constraint `T <: Q`.
@@ -1224,7 +1797,7 @@
     if (_isTop(supertype)) return true;
     // `Null` is a subtype match for any type `Q` under no constraints.
     // Note that nullable types will change this.
-    if (_isNull(subtype)) return true;
+    if (_equalType(subtype, Null)) return true;
 
     // Handle FutureOr<T> union type.
     if (_isFutureOr(subtype)) {
@@ -1244,7 +1817,8 @@
       //   constraints `C0`.
       // - And `P` is a subtype match for `Q` with respect to `L` under
       //   constraints `C1`.
-      var subtypeFuture = JS('!', '#(#)', getGenericClass(Future), subtypeArg);
+      var subtypeFuture =
+          JS<Object>('!', '#(#)', getGenericClass(Future), subtypeArg);
       return _isSubtypeMatch(subtypeFuture, supertype) &&
           _isSubtypeMatch(subtypeArg, supertype);
     }
@@ -1260,7 +1834,7 @@
       //     constraints `C`
       var supertypeArg = getGenericArgs(supertype)[0];
       var supertypeFuture =
-          JS('!', '#(#)', getGenericClass(Future), supertypeArg);
+          JS<Object>('!', '#(#)', getGenericClass(Future), supertypeArg);
       return _isSubtypeMatch(subtype, supertypeFuture) ||
           _isSubtypeMatch(subtype, supertypeArg);
     }
@@ -1330,8 +1904,7 @@
     // TODO(paulberry): implement this case.
     if (subtype is FunctionType) {
       if (supertype is! FunctionType) {
-        if (identical(supertype, unwrapType(Function)) ||
-            identical(supertype, unwrapType(Object))) {
+        if (_equalType(supertype, Function) || _equalType(supertype, Object)) {
           return true;
         } else {
           return false;
@@ -1347,7 +1920,7 @@
   bool _isTop(Object type) =>
       identical(type, _dynamic) ||
       identical(type, void_) ||
-      identical(type, unwrapType(Object));
+      _equalType(type, Object);
 }
 
 /// A constraint on a type parameter that we're inferring.
@@ -1361,12 +1934,13 @@
   Object upper;
 
   void _constrainLower(Object type) {
-    if (lower != null) {
-      if (isSubtypeOf(lower, type)) {
+    var _lower = lower;
+    if (_lower != null) {
+      if (isSubtypeOf(_lower, type)) {
         // nothing to do, existing lower bound is lower than the new one.
         return;
       }
-      if (!isSubtypeOf(type, lower)) {
+      if (!isSubtypeOf(type, _lower)) {
         // Neither bound is lower and we don't have GLB, so use bottom type.
         type = unwrapType(Null);
       }
@@ -1375,12 +1949,13 @@
   }
 
   void _constrainUpper(Object type) {
-    if (upper != null) {
-      if (isSubtypeOf(type, upper)) {
+    var _upper = upper;
+    if (_upper != null) {
+      if (isSubtypeOf(type, _upper)) {
         // nothing to do, existing upper bound is higher than the new one.
         return;
       }
-      if (!isSubtypeOf(upper, type)) {
+      if (!isSubtypeOf(_upper, type)) {
         // Neither bound is higher and we don't have LUB, so use top type.
         type = unwrapType(Object);
       }
@@ -1395,7 +1970,7 @@
 /// contain different generic type arguments.
 Object _getMatchingSupertype(Object subtype, Object supertype) {
   if (identical(subtype, supertype)) return supertype;
-  if (subtype == null || subtype == unwrapType(Object)) return null;
+  if (subtype == null || _equalType(subtype, Object)) return null;
 
   var subclass = getGenericClass(subtype);
   var superclass = getGenericClass(supertype);
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
index 5d5a251..d202ff0 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
@@ -25,13 +25,13 @@
     bool configurable,
     bool writable}) defineAccessor = JS('', 'Object.defineProperty');
 
-final Function(Object, Object) getOwnPropertyDescriptor =
+final dynamic Function(Object, Object) getOwnPropertyDescriptor =
     JS('', 'Object.getOwnPropertyDescriptor');
 
-final Iterable Function(Object) getOwnPropertyNames =
+final List Function(Object) getOwnPropertyNames =
     JS('', 'Object.getOwnPropertyNames');
 
-final Function(Object) getOwnPropertySymbols =
+final List Function(Object) getOwnPropertySymbols =
     JS('', 'Object.getOwnPropertySymbols');
 
 final Function(Object) getPrototypeOf = JS('', 'Object.getPrototypeOf');
@@ -62,49 +62,6 @@
     return JS<Object>('', '#[#]', obj, name);
 }
 
-/// Defines a lazy static field.
-/// After initial get or set, it will replace itself with a value property.
-// TODO(jmesserly): reusing descriptor objects has been shown to improve
-// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
-defineLazyField(to, name, desc) => JS('', '''(() => {
-  const initializer = $desc.get;
-  let init = initializer;
-  let value = null;
-  $desc.get = function() {
-    if (init == null) return value;
-    let f = init;
-    init = $throwCyclicInitializationError;
-    if (f === init) f($name); // throw cycle error
-
-    // On the first (non-cyclic) execution, record the field so we can reset it
-    // later if needed (hot restart).
-    $_resetFields.push(() => {
-      init = initializer;
-      value = null;
-    });
-
-    // Try to evaluate the field, using try+catch to ensure we implement the
-    // correct Dart error semantics.
-    try {
-      value = f();
-      init = null;
-      return value;
-    } catch (e) {
-      init = null;
-      value = null;
-      throw e;
-    }
-  };
-  $desc.configurable = true;
-  if ($desc.set != null) {
-    $desc.set = function(x) {
-      init = null;
-      value = x;
-    };
-  }
-  return ${defineProperty(to, name, desc)};
-})()''');
-
 copyTheseProperties(to, from, names) {
   for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
     var name = JS('', '#[#]', names, i);
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
index d14d9ed..b7d17d0d 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -70,14 +70,7 @@
 }
 
 class Primitives {
-  @NoInline()
-  static int _parseIntError(String source, int handleError(String source)) {
-    if (handleError == null) throw FormatException(source);
-    return handleError(source);
-  }
-
-  static int parseInt(
-      @nullCheck String source, int _radix, int handleError(String source)) {
+  static int parseInt(@nullCheck String source, int _radix) {
     var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
     // TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
     // long as we use it locally and don't expose it to user code.
@@ -89,7 +82,7 @@
       // TODO(sra): It might be that the match failed due to unrecognized U+0085
       // spaces.  We could replace them with U+0020 spaces and try matching
       // again.
-      return _parseIntError(source, handleError);
+      return null;
     }
     String decimalMatch = match[decimalIndex];
     if (_radix == null) {
@@ -101,7 +94,7 @@
         // Cannot fail because we know that the digits are all hex.
         return JS<int>('!', r'parseInt(#, 16)', source);
       }
-      return _parseIntError(source, handleError);
+      return null;
     }
     @notNull
     var radix = _radix;
@@ -138,7 +131,7 @@
       for (int i = 0; i < digitsPart.length; i++) {
         int characterCode = digitsPart.codeUnitAt(i) | 0x20;
         if (characterCode > maxCharCode) {
-          return _parseIntError(source, handleError);
+          return null;
         }
       }
     }
@@ -147,17 +140,7 @@
     return JS<int>('!', r'parseInt(#, #)', source, radix);
   }
 
-  @NoInline()
-  static double _parseDoubleError(
-      String source, double handleError(String source)) {
-    if (handleError == null) {
-      throw FormatException('Invalid double', source);
-    }
-    return handleError(source);
-  }
-
-  static double parseDouble(
-      @nullCheck String source, double handleError(String source)) {
+  static double parseDouble(@nullCheck String source) {
     // Notice that JS parseFloat accepts garbage at the end of the string.
     // Accept only:
     // - [+/-]NaN
@@ -169,15 +152,15 @@
         r'/^\s*[+-]?(?:Infinity|NaN|'
             r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
         source)) {
-      return _parseDoubleError(source, handleError);
+      return null;
     }
-    num result = JS('!', r'parseFloat(#)', source);
+    var result = JS<double>('!', r'parseFloat(#)', source);
     if (result.isNaN) {
       var trimmed = source.trim();
       if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
         return result;
       }
-      return _parseDoubleError(source, handleError);
+      return null;
     }
     return result;
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
index 421fd51..c2dc264 100644
--- a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -494,11 +494,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 2148886..20f023e 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -423,8 +423,11 @@
         ? new JSArray<E>.growable(length)
         : new JSArray<E>.fixed(length);
     if (length != 0 && fill != null) {
+      // TODO(sra): Consider using `Array.fill`.
       for (int i = 0; i < result.length; i++) {
-        result[i] = fill;
+        // Unchecked assignment equivalent to `result[i] = fill`;
+        // `fill` is checked statically at call site.
+        JS('', '#[#] = #', result, i, fill);
       }
     }
     return result;
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 146776c..08405ab 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -427,6 +427,11 @@
       InternetAddress address, String host) {
     throw new UnsupportedError("InternetAddress._cloneWithNewHost");
   }
+
+  @patch
+  static InternetAddress tryParse(String address) {
+    throw new UnsupportedError("InternetAddress.tryParse");
+  }
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 338e8cf..0600bf7 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -416,7 +416,6 @@
     int digitsIndex = 1;
     int hexIndex = 2;
     int decimalIndex = 3;
-    int nonDecimalHexIndex = 4;
     if (match == null) {
       // TODO(sra): It might be that the match failed due to unrecognized U+0085
       // spaces.  We could replace them with U+0020 spaces and try matching
@@ -3552,3 +3551,9 @@
 String testingGetPlatformEnvironmentVariable() {
   return testPlatformEnvironmentVariableValue;
 }
+
+// These are used to indicate that a named parameter is required when lazily
+// retrieving default values via [JsGetName.DEFAULT_VALUES_PROPERTY].
+class _Required {
+  const _Required();
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index 22af777..d89eded 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -991,20 +991,50 @@
 
 /// Specialization for 'as bool?'.
 /// Called from generated code.
-bool /*?*/ _asBoolNullable(object) {
+bool _asBool(object) {
+  if (_isBool(object)) return _Utils.asBool(object);
+  throw _TypeError.forType(object, 'bool');
+}
+
+/// Specialization for 'as bool*'.
+/// Called from generated code.
+bool /*?*/ _asBoolS(object) {
   if (_isBool(object)) return _Utils.asBool(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'bool');
 }
 
-/// Specialization for 'as double?'.
+/// Specialization for 'as bool?'.
 /// Called from generated code.
-double /*?*/ _asDoubleNullable(object) {
+bool /*?*/ _asBoolQ(object) {
+  if (_isBool(object)) return _Utils.asBool(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'bool?');
+}
+
+/// Specialization for 'as double'.
+/// Called from generated code.
+double /*?*/ _asDouble(object) {
+  if (_isNum(object)) return _Utils.asDouble(object);
+  throw _TypeError.forType(object, 'double');
+}
+
+/// Specialization for 'as double*'.
+/// Called from generated code.
+double /*?*/ _asDoubleS(object) {
   if (_isNum(object)) return _Utils.asDouble(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'double');
 }
 
+/// Specialization for 'as double?'.
+/// Called from generated code.
+double /*?*/ _asDoubleQ(object) {
+  if (_isNum(object)) return _Utils.asDouble(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'double?');
+}
+
 /// Specialization for 'is int'.
 /// Called from generated code.
 bool _isInt(object) {
@@ -1012,14 +1042,29 @@
       JS('bool', 'Math.floor(#) === #', object, object);
 }
 
-/// Specialization for 'as int?'.
+/// Specialization for 'as int'.
 /// Called from generated code.
-int /*?*/ _asIntNullable(object) {
+int _asInt(object) {
+  if (_isInt(object)) return _Utils.asInt(object);
+  throw _TypeError.forType(object, 'int');
+}
+
+/// Specialization for 'as int*'.
+/// Called from generated code.
+int /*?*/ _asIntS(object) {
   if (_isInt(object)) return _Utils.asInt(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'int');
 }
 
+/// Specialization for 'as int?'.
+/// Called from generated code.
+int /*?*/ _asIntQ(object) {
+  if (_isInt(object)) return _Utils.asInt(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'int?');
+}
+
 /// Specialization for 'is num' and 'is double'.
 /// Called from generated code.
 bool _isNum(object) {
@@ -1028,26 +1073,56 @@
 
 /// Specialization for 'as num?'.
 /// Called from generated code.
-num /*?*/ _asNumNullable(object) {
+num _asNum(object) {
+  if (_isNum(object)) return _Utils.asNum(object);
+  throw _TypeError.forType(object, 'num');
+}
+
+/// Specialization for 'as num*'.
+/// Called from generated code.
+num /*?*/ _asNumS(object) {
   if (_isNum(object)) return _Utils.asNum(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'num');
 }
 
+/// Specialization for 'as num?'.
+/// Called from generated code.
+num /*?*/ _asNumQ(object) {
+  if (_isNum(object)) return _Utils.asNum(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'num?');
+}
+
 /// Specialization for 'is String'.
 /// Called from generated code.
 bool _isString(object) {
   return JS('bool', 'typeof # == "string"', object);
 }
 
-/// Specialization for 'as String?'.
+/// Specialization for 'as String'.
 /// Called from generated code.
-String /*?*/ _asStringNullable(object) {
+String _asString(object) {
+  if (_isString(object)) return _Utils.asString(object);
+  throw _TypeError.forType(object, 'String');
+}
+
+/// Specialization for 'as String*'.
+/// Called from generated code.
+String /*?*/ _asStringS(object) {
   if (_isString(object)) return _Utils.asString(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'String');
 }
 
+/// Specialization for 'as String?'.
+/// Called from generated code.
+String /*?*/ _asStringQ(object) {
+  if (_isString(object)) return _Utils.asString(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'String?');
+}
+
 String _rtiArrayToString(Object array, List<String> genericContext) {
   String s = '', sep = '';
   for (int i = 0; i < _Utils.arrayLength(array); i++) {
@@ -1081,8 +1156,7 @@
       typeParametersText += typeSep;
       typeParametersText += genericContext[genericContext.length - 1 - i];
       Rti boundRti = _castToRti(_Utils.arrayAt(bounds, i));
-      if (!isTopType(boundRti) &&
-          (!JS_GET_FLAG('LEGACY') || !isObjectType(boundRti))) {
+      if (!isTopType(boundRti)) {
         typeParametersText +=
             ' extends ' + _rtiToString(boundRti, genericContext);
       }
@@ -1609,7 +1683,7 @@
       universe, Rti baseType, String key, bool normalize) {
     if (normalize) {
       int baseKind = Rti._getKind(baseType);
-      if (isTopType(baseType) ||
+      if (isStrongTopType(baseType) ||
           isNullType(baseType) ||
           baseKind == Rti.kindQuestion ||
           baseKind == Rti.kindStar) {
@@ -2485,11 +2559,7 @@
   if (isStrongTopType(s)) return false;
 
   // Left Bottom:
-  if (isLegacy) {
-    if (isNullType(s)) return true;
-  } else {
-    if (sKind == Rti.kindNever) return true;
-  }
+  if (isBottomType(s)) return true;
 
   // Left Type Variable Bound 1:
   bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter;
@@ -2809,7 +2879,10 @@
       kind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(t));
 }
 
-bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t);
+bool isTopType(Rti t) =>
+    isStrongTopType(t) ||
+    isLegacyObjectType(t) ||
+    JS_GET_FLAG('LEGACY') && isObjectType(t);
 
 bool isStrongTopType(Rti t) {
   int kind = Rti._getKind(t);
@@ -2817,10 +2890,12 @@
       kind == Rti.kindVoid ||
       kind == Rti.kindAny ||
       kind == Rti.kindErased ||
-      !JS_GET_FLAG('NNBD') && isObjectType(t) ||
       isNullableObjectType(t);
 }
 
+bool isBottomType(Rti t) =>
+    Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t);
+
 bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object>());
 bool isLegacyObjectType(Rti t) =>
     _Utils.isIdentical(t, LEGACY_TYPE_REF<Object>());
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index 3b35902..62372e7 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -53,6 +53,8 @@
   static const String endNamedGroupString = _rightBraceString;
   static const int nameSeparator = _colon;
   static const String nameSeparatorString = _colonString;
+  static const int requiredNameSeparator = _exclamation;
+  static const String requiredNameSeparatorString = _exclamationString;
 
   static const int genericFunctionTypeParameterIndex = _circumflex;
   static const String genericFunctionTypeParameterIndexString =
@@ -191,6 +193,8 @@
     test("startNamedGroup", startNamedGroup, startNamedGroupString);
     test("endNamedGroup", endNamedGroup, endNamedGroupString);
     test("nameSeparator", nameSeparator, nameSeparatorString);
+    test("requiredNameSeparator", requiredNameSeparator,
+        requiredNameSeparatorString);
     test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
         genericFunctionTypeParameterIndexString);
     test("extensionOp", extensionOp, extensionOpString);
diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
index b79755e..129d1fc 100644
--- a/sdk/lib/_internal/vm/bin/builtin.dart
+++ b/sdk/lib/_internal/vm/bin/builtin.dart
@@ -11,6 +11,7 @@
 import 'dart:collection' hide LinkedList, LinkedListEntry;
 import 'dart:_internal' hide Symbol;
 import 'dart:io';
+import 'dart:convert';
 import 'dart:isolate';
 import 'dart:typed_data';
 
@@ -130,11 +131,12 @@
     _log('Resolving package with uri path: ${uri.path}');
   }
   var resolvedUri;
-  if (_packageError != null) {
+  final error = _packageError;
+  if (error != null) {
     if (_traceLoading) {
-      _log("Resolving package with pending resolution error: $_packageError");
+      _log("Resolving package with pending resolution error: $error");
     }
-    throw _packageError;
+    throw error;
   } else {
     if (packageNameEnd < 0) {
       // Package URIs must have a path after the package name, even if it's
@@ -143,7 +145,7 @@
           "'package:${uri.path}/', not 'package:${uri.path}'";
     }
     var packageName = uri.path.substring(0, packageNameEnd);
-    var mapping = _packageMap[packageName];
+    final mapping = _packageMap[packageName];
     if (_traceLoading) {
       _log("Mapped '$packageName' package to '$mapping'");
     }
@@ -204,281 +206,185 @@
   }
 }
 
-// Handling of packages requests. Finding and parsing of .packages file or
-// packages/ directories.
-const _LF = 0x0A;
-const _CR = 0x0D;
-const _SPACE = 0x20;
-const _HASH = 0x23;
-const _DOT = 0x2E;
-const _COLON = 0x3A;
-const _DEL = 0x7F;
+// The values go from ' ' to DEL and `x` means disallowed.
+const String _invalidPackageNameChars =
+    'x.xx.x.........x..........x.x.xx...........................xxxx.x..........................xxx.x';
 
-const _invalidPackageNameChars = const [
-  true, //  space
-  false, // !
-  true, //  "
-  true, //  #
-  false, // $
-  true, //  %
-  false, // &
-  false, // '
-  false, // (
-  false, // )
-  false, // *
-  false, // +
-  false, // ,
-  false, // -
-  false, // .
-  true, //  /
-  false, // 0
-  false, // 1
-  false, // 2
-  false, // 3
-  false, // 4
-  false, // 5
-  false, // 6
-  false, // 7
-  false, // 8
-  false, // 9
-  true, //  :
-  false, // ;
-  true, //  <
-  false, // =
-  true, //  >
-  true, //  ?
-  false, // @
-  false, // A
-  false, // B
-  false, // C
-  false, // D
-  false, // E
-  false, // F
-  false, // G
-  false, // H
-  false, // I
-  false, // J
-  false, // K
-  false, // L
-  false, // M
-  false, // N
-  false, // O
-  false, // P
-  false, // Q
-  false, // R
-  false, // S
-  false, // T
-  false, // U
-  false, // V
-  false, // W
-  false, // X
-  false, // Y
-  false, // Z
-  true, //  [
-  true, //  \
-  true, //  ]
-  true, //  ^
-  false, // _
-  true, //  `
-  false, // a
-  false, // b
-  false, // c
-  false, // d
-  false, // e
-  false, // f
-  false, // g
-  false, // h
-  false, // i
-  false, // j
-  false, // k
-  false, // l
-  false, // m
-  false, // n
-  false, // o
-  false, // p
-  false, // q
-  false, // r
-  false, // s
-  false, // t
-  false, // u
-  false, // v
-  false, // w
-  false, // x
-  false, // y
-  false, // z
-  true, //  {
-  true, //  |
-  true, //  }
-  false, // ~
-  true, //  DEL
-];
+bool _isValidPackageName(String packageName) {
+  const space = 0x20;
+  const del = 0x7F;
+  const dot = 0x2e;
+  const lowerX = 0x78;
+  for (int i = 0; i < packageName.length; ++i) {
+    final int char = packageName.codeUnitAt(i);
+    if (char < space || del < char) {
+      return false;
+    }
+    final int allowed = _invalidPackageNameChars.codeUnitAt(char - space);
+    assert(allowed == dot || allowed == lowerX);
+    if (allowed == lowerX) {
+      return false;
+    }
+  }
+  return true;
+}
 
-_parsePackagesFile(bool traceLoading, Uri packagesFile, List<int> data) {
+_parsePackagesFile(bool traceLoading, Uri packagesFile, String data) {
   // The first entry contains the location of the identified .packages file
   // instead of a mapping.
-  var result = [packagesFile.toString(), null];
-  var index = 0;
-  var len = data.length;
-  while (index < len) {
-    var start = index;
-    var char = data[index];
-    if ((char == _CR) || (char == _LF)) {
-      // Skipping empty lines.
-      index++;
+  final List result = [packagesFile.toString(), null];
+
+  final lines = LineSplitter.split(data);
+  for (String line in lines) {
+    final hashIndex = line.indexOf('#');
+    if (hashIndex == 0) {
+      continue;
+    }
+    if (hashIndex > 0) {
+      line = line.substring(0, hashIndex);
+    }
+    line = line.trimRight();
+    if (line.isEmpty) {
       continue;
     }
 
-    // Identify split within the line and end of the line.
-    var separator = -1;
-    var end = len;
-    // Verifying validity of package name while scanning the line.
-    var nonDot = false;
-    var invalidPackageName = false;
-
-    // Scan to the end of the line or data.
-    while (index < len) {
-      char = data[index++];
-      // If we have not reached the separator yet, determine whether we are
-      // scanning legal package name characters.
-      if (separator == -1) {
-        if ((char == _COLON)) {
-          // The first colon on a line is the separator between package name and
-          // related URI.
-          separator = index - 1;
-        } else {
-          // Still scanning the package name part. Check for the validity of
-          // the characters.
-          nonDot = nonDot || (char != _DOT);
-          invalidPackageName = invalidPackageName ||
-              (char < _SPACE) ||
-              (char > _DEL) ||
-              _invalidPackageNameChars[char - _SPACE];
-        }
-      }
-      // Identify end of line.
-      if ((char == _CR) || (char == _LF)) {
-        end = index - 1;
-        break;
-      }
+    final colonIndex = line.indexOf(':');
+    if (colonIndex <= 0) {
+      return 'Line in "$packagesFile" should be of the format '
+          '`<package-name>:<path>" but was: "$line"';
+    }
+    final packageName = line.substring(0, colonIndex);
+    if (!_isValidPackageName(packageName)) {
+      return 'Package name in $packagesFile contains disallowed characters ('
+          'was: "$packageName")';
     }
 
-    // No further handling needed for comment lines.
-    if (data[start] == _HASH) {
-      if (traceLoading) {
-        _log("Skipping comment in $packagesFile:\n"
-            "${new String.fromCharCodes(data, start, end)}");
-      }
-      continue;
-    }
-
-    // Check for a badly formatted line, starting with a ':'.
-    if (separator == start) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line starts with ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing package name in $packagesFile:\n"
-          "$line";
-    }
-
-    // Ensure there is a separator on the line.
-    if (separator == -1) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line has no ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing ':' separator in $packagesFile:\n"
-          "$line";
-    }
-
-    var packageName = new String.fromCharCodes(data, start, separator);
-
-    // Check for valid package name.
-    if (invalidPackageName || !nonDot) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Invalid package name $packageName in $packagesFile");
-      }
-      return "Invalid package name '$packageName' in $packagesFile:\n"
-          "$line";
-    }
-
+    String packageUri = line.substring(colonIndex + 1);
     if (traceLoading) {
       _log("packageName: $packageName");
-    }
-    var packageUri = new String.fromCharCodes(data, separator + 1, end);
-    if (traceLoading) {
-      _log("original packageUri: $packageUri");
+      _log("packageUri: $packageUri");
     }
     // Ensure the package uri ends with a /.
-    if (!packageUri.endsWith("/")) {
-      packageUri = "$packageUri/";
+    if (!packageUri.endsWith('/')) {
+      packageUri += '/';
     }
-    packageUri = packagesFile.resolve(packageUri).toString();
+    final resolvedPackageUri = packagesFile.resolve(packageUri).toString();
     if (traceLoading) {
-      _log("mapping: $packageName -> $packageUri");
+      _log("mapping: $packageName -> $resolvedPackageUri");
     }
     result.add(packageName);
-    result.add(packageUri);
+    result.add(resolvedPackageUri);
   }
-
   if (traceLoading) {
     _log("Parsed packages file at $packagesFile. Sending:\n$result");
   }
   return result;
 }
 
-_loadPackagesFile(bool traceLoading, Uri packagesFile) {
-  try {
-    var data = new File.fromUri(packagesFile).readAsBytesSync();
-    if (traceLoading) {
-      _log("Loaded packages file from $packagesFile:\n"
-          "${new String.fromCharCodes(data)}");
-    }
-    return _parsePackagesFile(traceLoading, packagesFile, data);
-  } catch (e, s) {
-    if (traceLoading) {
-      _log("Error loading packages: $e\n$s");
-    }
-    return "Uncaught error ($e) loading packages file.";
+// The .dart_tool/package_config.json format is described in
+//
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+//
+// The returned list has the format:
+//
+//    [0] Location of package_config.json file.
+//    [1] null
+//    [n*2] Name of n-th package
+//    [n*2 + 1] Location of n-th package's sources (as a String)
+//
+List _parsePackageConfig(bool traceLoading, Uri packageConfig, String data) {
+  final Map packageJson = json.decode(data);
+  final version = packageJson['configVersion'];
+  if (version != 2) {
+    throw 'The package configuration file has an unsupported version.';
   }
+  // The first entry contains the location of the identified
+  // .dart_tool/package_config.json file instead of a mapping.
+  final result = <dynamic>[packageConfig.toString(), null];
+  final List packages = packageJson['packages'] ?? [];
+  for (final Map package in packages) {
+    String rootUri = package['rootUri'];
+    if (!rootUri.endsWith('/')) rootUri += '/';
+    final String packageName = package['name'];
+    final String packageUri = package['packageUri'];
+    final Uri resolvedRootUri = packageConfig.resolve(rootUri);
+    final Uri resolvedPackageUri = packageUri != null
+        ? resolvedRootUri.resolve(packageUri)
+        : resolvedRootUri;
+    if (packageUri != null &&
+        !'$resolvedPackageUri'.contains('$resolvedRootUri')) {
+      throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".';
+    }
+    if (!_isValidPackageName(packageName)) {
+      throw 'Package name in $packageConfig contains disallowed characters ('
+          'was: "$packageName")';
+    }
+    result.add(packageName);
+    result.add(resolvedPackageUri.toString());
+    if (traceLoading) {
+      _log('Resolved package "$packageName" to be at $resolvedPackageUri');
+    }
+  }
+  return result;
 }
 
-_findPackagesFile(bool traceLoading, Uri base) {
+_findPackagesConfiguration(bool traceLoading, Uri base) {
   try {
-    // Walk up the directory hierarchy to check for the existence of
-    // .packages files in parent directories and for the existence of a
-    // packages/ directory on the first iteration.
-    var dir = new File.fromUri(base).parent;
-    var prev = null;
-    // Keep searching until we reach the root.
-    while ((prev == null) || (prev.path != dir.path)) {
-      // Check for the existence of a .packages file and if it exists try to
-      // load and parse it.
-      var dirUri = dir.uri;
-      var packagesFile = dirUri.resolve(".packages");
+    // Walk up the directory hierarchy to check for the existence of either one
+    // of
+    //   - .packages (preferred)
+    //   - .dart_tool/package_config.json
+    var currentDir = new File.fromUri(base).parent;
+    while (true) {
+      final dirUri = currentDir.uri;
+
+      // We prefer using `.packages` over `.dart_tool/package_config.json` so
+      // old users of `Isolate.packageConfig` which cannot handle the new format
+      // will continue to work (see https://github.com/dart-lang/sdk/issues/41748).
+      final packagesFile = dirUri.resolve(".packages");
       if (traceLoading) {
         _log("Checking for $packagesFile file.");
       }
-      var exists = new File.fromUri(packagesFile).existsSync();
+      File file = File.fromUri(packagesFile);
+      bool exists = file.existsSync();
       if (traceLoading) {
         _log("$packagesFile exists: $exists");
       }
       if (exists) {
-        return _loadPackagesFile(traceLoading, packagesFile);
+        final String data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded packages file from $packagesFile:\n$data");
+        }
+        return _parsePackagesFile(traceLoading, packagesFile, data);
       }
-      // Move up one level.
-      prev = dir;
-      dir = dir.parent;
+
+      // We fallback to using `.dart_tool/package_config.json` if it exists.
+      final packageConfig = dirUri.resolve(".dart_tool/package_config.json");
+      if (traceLoading) {
+        _log("Checking for $packageConfig file.");
+      }
+      file = File.fromUri(packageConfig);
+      exists = file.existsSync();
+      if (traceLoading) {
+        _log("$packageConfig exists: $exists");
+      }
+      if (exists) {
+        final data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded package config file from $packageConfig:$data\n");
+        }
+        return _parsePackageConfig(traceLoading, packageConfig, data);
+      }
+
+      final parentDir = currentDir.parent;
+      if (dirUri == parentDir.uri) break;
+      currentDir = parentDir;
     }
 
-    // No .packages file was found.
     if (traceLoading) {
-      _log("Could not resolve a package location from $base");
+      _log("Could not resolve a package configuration from $base");
     }
-    return "Could not resolve a package location for base at $base";
+    return "Could not resolve a package configuration for base at $base";
   } catch (e, s) {
     if (traceLoading) {
       _log("Error loading packages: $e\n$s");
@@ -487,29 +393,62 @@
   }
 }
 
-_loadPackagesData(traceLoading, resource) {
-  try {
-    var data = resource.data;
-    var mime = data.mimeType;
-    if (mime != "text/plain") {
-      throw "MIME-type must be text/plain: $mime given.";
+int _indexOfFirstNonWhitespaceCharacter(String data) {
+  // Whitespace characters ignored in JSON spec:
+  // https://tools.ietf.org/html/rfc7159
+  const tab = 0x09;
+  const lf = 0x0A;
+  const cr = 0x0D;
+  const space = 0x20;
+
+  int index = 0;
+  while (index < data.length) {
+    final int char = data.codeUnitAt(index);
+    if (char != lf && char != cr && char != space && char != tab) {
+      break;
     }
-    var charset = data.charset;
-    if ((charset != "utf-8") && (charset != "US-ASCII")) {
-      // The C++ portion of the embedder assumes UTF-8.
-      throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
-    }
-    return _parsePackagesFile(traceLoading, resource, data.contentAsBytes());
-  } catch (e) {
-    return "Uncaught error ($e) loading packages data.";
+    index++;
   }
+  return index;
+}
+
+bool _canBeValidJson(String data) {
+  const int openCurly = 0x7B;
+  final int index = _indexOfFirstNonWhitespaceCharacter(data);
+  return index < data.length && data.codeUnitAt(index) == openCurly;
+}
+
+_parsePackageConfiguration(bool traceLoading, Uri resource, Uint8List bytes) {
+  try {
+    final data = utf8.decode(bytes);
+    if (_canBeValidJson(data)) {
+      return _parsePackageConfig(traceLoading, resource, data);
+    } else {
+      return _parsePackagesFile(traceLoading, resource, data);
+    }
+  } catch (e) {
+    return "The resource '$resource' is neither a valid '.packages' file nor "
+        "a valid '.dart_tool/package_config.json' file.";
+  }
+}
+
+bool _isValidUtf8DataUrl(UriData data) {
+  final mime = data.mimeType;
+  if (mime != "text/plain") {
+    return false;
+  }
+  final charset = data.charset;
+  if (charset != "utf-8" && charset != "US-ASCII") {
+    return false;
+  }
+  return true;
 }
 
 _handlePackagesRequest(bool traceLoading, int tag, Uri resource) {
   try {
     if (tag == -1) {
       if (resource.scheme == '' || resource.scheme == 'file') {
-        return _findPackagesFile(traceLoading, resource);
+        return _findPackagesConfiguration(traceLoading, resource);
       } else {
         return "Unsupported scheme used to locate .packages file:'$resource'.";
       }
@@ -517,19 +456,25 @@
       if (traceLoading) {
         _log("Handling load of packages map: '$resource'.");
       }
+      Uint8List bytes;
       if (resource.scheme == '' || resource.scheme == 'file') {
-        var exists = new File.fromUri(resource).existsSync();
-        if (exists) {
-          return _loadPackagesFile(traceLoading, resource);
-        } else {
-          return "Packages file '$resource' not found.";
+        final file = File.fromUri(resource);
+        if (!file.existsSync()) {
+          return "Packages file '$resource' does not exit.";
         }
+        bytes = file.readAsBytesSync();
       } else if (resource.scheme == 'data') {
-        return _loadPackagesData(traceLoading, resource);
+        final uriData = resource.data;
+        if (!_isValidUtf8DataUrl(uriData)) {
+          return "The data resource '$resource' must have a 'text/plain' mime "
+              "type and a 'utf-8' or 'US-ASCII' charset.";
+        }
+        bytes = uriData.contentAsBytes();
       } else {
         return "Unknown scheme (${resource.scheme}) for package file at "
             "'$resource'.";
       }
+      return _parsePackageConfiguration(traceLoading, resource, bytes);
     } else {
       return "Unknown packages request tag: $tag for '$resource'.";
     }
@@ -580,6 +525,9 @@
 }
 
 // Embedder Entrypoint:
+// The embedder calls this method with the value of the --packages command line
+// option. It can point to a ".packages" or a ".dart_tool/package_config.json"
+// file.
 @pragma("vm:entry-point")
 String _setPackagesMap(String packagesParam) {
   if (!_setupCompleted) {
@@ -677,7 +625,7 @@
     resolvedUri = _resolvePackageUri(packageUri);
   } catch (e, s) {
     if (_traceLoading) {
-      _log("Exception when resolving package URI: $packageUri");
+      _log("Exception when resolving package URI: $packageUri:\n$e\n$s");
     }
     resolvedUri = null;
   }
diff --git a/sdk/lib/_internal/vm/bin/process_patch.dart b/sdk/lib/_internal/vm/bin/process_patch.dart
index 2c5ae51..89e7c14 100644
--- a/sdk/lib/_internal/vm/bin/process_patch.dart
+++ b/sdk/lib/_internal/vm/bin/process_patch.dart
@@ -357,6 +357,9 @@
   }
 
   String _windowsArgumentEscape(String argument) {
+    if (argument.isEmpty) {
+      return '""';
+    }
     var result = argument;
     if (argument.contains('\t') ||
         argument.contains(' ') ||
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index e50d821..94d6903 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -92,6 +92,11 @@
       InternetAddress address, String host) {
     return (address as _InternetAddress)._cloneWithNewHost(host);
   }
+
+  @patch
+  static InternetAddress tryParse(String address) {
+    return _InternetAddress.tryParse(address);
+  }
 }
 
 @patch
@@ -253,6 +258,18 @@
     }
   }
 
+  static _InternetAddress tryParse(String address) {
+    if (address == null) {
+      throw ArgumentError("Invalid internet address $address");
+    }
+    var addressBytes = _parse(address);
+    if (addressBytes == null) return null;
+    var type = addressBytes.length == _IPv4AddrLength
+        ? InternetAddressType.IPv4
+        : InternetAddressType.IPv6;
+    return _InternetAddress(type, address, null, addressBytes);
+  }
+
   factory _InternetAddress.fixed(int id) {
     switch (id) {
       case _addressLoopbackIPv4:
@@ -2156,9 +2173,9 @@
   void set multicastHops(int value) =>
       _socket.setOption(SocketOption._ipMulticastHops, value);
 
-  NetworkInterface get multicastInterface => throw "Not implemented";
+  NetworkInterface get multicastInterface => throw UnimplementedError();
   void set multicastInterface(NetworkInterface value) =>
-      throw "Not implemented";
+      throw UnimplementedError();
 
   bool get broadcastEnabled => _socket.getOption(SocketOption._ipBroadcast);
   void set broadcastEnabled(bool value) =>
diff --git a/sdk/lib/_internal/vm/bin/vmservice_io.dart b/sdk/lib/_internal/vm/bin/vmservice_io.dart
index 7e3146d..06564f5 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_io.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_io.dart
@@ -7,11 +7,8 @@
 library vmservice_io;
 
 import 'dart:async';
-import 'dart:collection';
 import 'dart:convert';
 import 'dart:io';
-import 'dart:isolate';
-import 'dart:typed_data';
 import 'dart:_vmservice';
 
 part 'vmservice_server.dart';
@@ -209,6 +206,11 @@
   }
 }
 
+void webServerAcceptNewWebSocketConnections(bool enable) {
+  _lazyServerBoot();
+  server.acceptNewWebSocketConnections = enable;
+}
+
 Null _clearFuture(_) {
   serverFuture = null;
 }
@@ -254,6 +256,8 @@
   VMServiceEmbedderHooks.listFiles = listFilesCallback;
   VMServiceEmbedderHooks.serverInformation = serverInformationCallback;
   VMServiceEmbedderHooks.webServerControl = webServerControlCallback;
+  VMServiceEmbedderHooks.acceptNewWebSocketConnections =
+      webServerAcceptNewWebSocketConnections;
   // Always instantiate the vmservice object so that the exit message
   // can be delivered and waiting loaders can be cancelled.
   new VMService();
diff --git a/sdk/lib/_internal/vm/bin/vmservice_server.dart b/sdk/lib/_internal/vm/bin/vmservice_server.dart
index 06f39b6..26111d0 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_server.dart
@@ -153,6 +153,7 @@
   final String _serviceInfoFilename;
   HttpServer _server;
   bool get running => _server != null;
+  bool acceptNewWebSocketConnections = true;
   int _port = -1;
 
   /// Returns the server address including the auth token.
@@ -352,11 +353,19 @@
 
     final String path = result;
     if (path == WEBSOCKET_PATH) {
-      WebSocketTransformer.upgrade(request,
-              compression: CompressionOptions.compressionOff)
-          .then((WebSocket webSocket) {
-        new WebSocketClient(webSocket, _service);
-      });
+      if (acceptNewWebSocketConnections) {
+        WebSocketTransformer.upgrade(request,
+                compression: CompressionOptions.compressionOff)
+            .then((WebSocket webSocket) {
+          new WebSocketClient(webSocket, _service);
+        });
+      } else {
+        request.response.statusCode = HttpStatus.forbidden;
+        request.response.write('Cannot connect directly to the VM service as '
+            'a Dart Development Service (DDS) instance has taken control and '
+            'can be found at ${_service.ddsUri}.');
+        request.response.close();
+      }
       return;
     }
 
diff --git a/sdk/lib/_internal/vm/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart
index 7d62432..3c111f4 100644
--- a/sdk/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk/lib/_internal/vm/lib/async_patch.dart
@@ -47,7 +47,7 @@
   }
 
   @pragma("vm:entry-point")
-  void start(f) {
+  void start(void Function() f) {
     f();
     isSync = true;
   }
@@ -58,8 +58,8 @@
 
 // We need to pass the value as first argument and leave the second and third
 // arguments empty (used for error handling).
-// See vm/ast_transformer.cc for usage.
-Function _asyncThenWrapperHelper(continuation) {
+dynamic Function(dynamic) _asyncThenWrapperHelper(
+    dynamic Function(dynamic) continuation) {
   // Any function that is used as an asynchronous callback must be registered
   // in the current Zone. Normally, this is done by the future when a
   // callback is registered (for example with `.then` or `.catchError`). In our
@@ -76,16 +76,18 @@
   // `Future` implementation could potentially invoke the callback with the
   // wrong number of arguments.
   if (Zone.current == Zone.root) return continuation;
-  return Zone.current.registerUnaryCallback(continuation);
+  return Zone.current.registerUnaryCallback<dynamic, dynamic>(continuation);
 }
 
 // We need to pass the exception and stack trace objects as second and third
-// parameter to the continuation.  See vm/ast_transformer.cc for usage.
-Function _asyncErrorWrapperHelper(continuation) {
+// parameter to the continuation.
+dynamic Function(Object, StackTrace) _asyncErrorWrapperHelper(
+    dynamic Function(dynamic, dynamic, StackTrace) continuation) {
   // See comments of `_asyncThenWrapperHelper`.
-  void errorCallback(Object e, StackTrace s) => continuation(null, e, s);
+  dynamic errorCallback(Object e, StackTrace s) => continuation(null, e, s);
   if (Zone.current == Zone.root) return errorCallback;
-  return Zone.current.registerBinaryCallback(errorCallback);
+  return Zone.current
+      .registerBinaryCallback<dynamic, Object, StackTrace>(errorCallback);
 }
 
 /// Registers the [thenCallback] and [errorCallback] on the given [object].
@@ -93,11 +95,14 @@
 /// If [object] is not a future, then it is wrapped into one.
 ///
 /// Returns the result of registering with `.then`.
-Future _awaitHelper(
-    var object, Function thenCallback, Function errorCallback, var awaiter) {
+Future _awaitHelper(var object, dynamic Function(dynamic) thenCallback,
+    dynamic Function(dynamic, StackTrace) errorCallback, Function awaiter) {
+  _Future future;
   if (object is! Future) {
-    object = new _Future().._setValue(object);
-  } else if (object is! _Future) {
+    future = new _Future().._setValue(object);
+  } else if (object is _Future) {
+    future = object;
+  } else {
     return object.then(thenCallback, onError: errorCallback);
   }
   // `object` is a `_Future`.
@@ -108,8 +113,8 @@
   //
   // We can only do this for our internal futures (the default implementation of
   // all futures that are constructed by the `dart:async` library).
-  object._awaiter = awaiter;
-  return object._thenAwait(thenCallback, errorCallback);
+  future._awaiter = awaiter;
+  return future._thenAwait<dynamic>(thenCallback, errorCallback);
 }
 
 // Called as part of the 'await for (...)' construct. Registers the
diff --git a/sdk/lib/_internal/vm/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart
index f1e46cf..33215c7 100644
--- a/sdk/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk/lib/_internal/vm/lib/convert_patch.dart
@@ -1498,267 +1498,17 @@
   }
 }
 
-class _Utf8StringBuffer {
-  static const int INITIAL_CAPACITY = 32;
-  // Partial state encoding.
-  static const int MASK_TWO_BIT = 0x03;
-  static const int MASK_SIZE = MASK_TWO_BIT;
-  static const int SHIFT_MISSING = 2;
-  static const int SHIFT_VALUE = 4;
-  static const int NO_PARTIAL = 0;
-
-  // UTF-8 encoding and limits.
-  static const int MAX_ASCII = 127;
-  static const int MAX_TWO_BYTE = 0x7ff;
-  static const int MAX_THREE_BYTE = 0xffff;
-  static const int MAX_UNICODE = 0X10ffff;
-  static const int MASK_TWO_BYTE = 0x1f;
-  static const int MASK_THREE_BYTE = 0x0f;
-  static const int MASK_FOUR_BYTE = 0x07;
-  static const int MASK_CONTINUE_TAG = 0xC0;
-  static const int MASK_CONTINUE_VALUE = 0x3f;
-  static const int CONTINUE_TAG = 0x80;
-
-  // UTF-16 surrogate encoding.
-  static const int LEAD_SURROGATE = 0xD800;
-  static const int TAIL_SURROGATE = 0xDC00;
-  static const int SHIFT_HIGH_SURROGATE = 10;
-  static const int MASK_LOW_SURROGATE = 0x3ff;
-
-  // The internal buffer starts as Uint8List, but may change to Uint16List
-  // if the string contains non-Latin-1 characters.
-  List<int> buffer = new Uint8List(INITIAL_CAPACITY);
-  // Number of elements in buffer.
-  int length = 0;
-  // Partial decoding state, for cases where an UTF-8 sequences is split
-  // between chunks.
-  int partialState = NO_PARTIAL;
-  // Whether all characters so far have been Latin-1 (and the buffer is
-  // still a Uint8List). Set to false when the first non-Latin-1 character
-  // is encountered, and the buffer is then also converted to a Uint16List.
-  bool isLatin1 = true;
-  // If allowing malformed, invalid UTF-8 sequences are converted to
-  // U+FFFD.
-  bool allowMalformed;
-
-  _Utf8StringBuffer(this.allowMalformed);
-
-  /**
-   * Parse the continuation of a multi-byte UTF-8 sequence.
-   *
-   * Parse [utf8] from [position] to [end]. If the sequence extends beyond
-   * `end`, store the partial state in [partialState], and continue from there
-   * on the next added slice.
-   *
-   * The [size] is the number of expected continuation bytes total,
-   * and [missing] is the number of remaining continuation bytes.
-   * The [size] is used to detect overlong encodings.
-   * The [value] is the value collected so far.
-   *
-   * When called after seeing the first multi-byte marker, the [size] and
-   * [missing] values are always the same, but they may differ if continuing
-   * after a partial sequence.
-   */
-  int addContinuation(
-      List<int> utf8, int position, int end, int size, int missing, int value) {
-    int codeEnd = position + missing;
-    do {
-      if (position == end) {
-        missing = codeEnd - position;
-        partialState =
-            size | (missing << SHIFT_MISSING) | (value << SHIFT_VALUE);
-        return end;
-      }
-      int char = utf8[position];
-      if ((char & MASK_CONTINUE_TAG) != CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          return position;
-        }
-        throw new FormatException(
-            "Expected UTF-8 continuation byte, "
-            "found $char",
-            utf8,
-            position);
-      }
-      value = 64 * value + (char & MASK_CONTINUE_VALUE);
-      position++;
-    } while (position < codeEnd);
-    if (value <= const [0, MAX_ASCII, MAX_TWO_BYTE, MAX_THREE_BYTE][size]) {
-      // Over-long encoding.
-      if (allowMalformed) {
-        value = 0xFFFD;
-      } else {
-        throw new FormatException(
-            "Invalid encoding: U+${value.toRadixString(16).padLeft(4, '0')}"
-            " encoded in ${size + 1} bytes.",
-            utf8,
-            position - 1);
-      }
-    }
-    addCharCode(value);
-    return position;
-  }
-
-  void addCharCode(int char) {
-    assert(char >= 0);
-    assert(char <= MAX_UNICODE);
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        throw new FormatException("Incomplete UTF-8 sequence");
-      }
-    }
-    if (isLatin1 && char > 0xff) {
-      _to16Bit(); // Also grows a little if close to full.
-    }
-    int length = this.length;
-    if (char <= MAX_THREE_BYTE) {
-      if (length == buffer.length) _grow();
-      buffer[length] = char;
-      this.length = length + 1;
-      return;
-    }
-    if (length + 2 > buffer.length) _grow();
-    int bits = char - 0x10000;
-    buffer[length] = LEAD_SURROGATE | (bits >> SHIFT_HIGH_SURROGATE);
-    buffer[length + 1] = TAIL_SURROGATE | (bits & MASK_LOW_SURROGATE);
-    this.length = length + 2;
-  }
-
-  void _to16Bit() {
-    assert(isLatin1);
-    Uint16List newBuffer;
-    if ((length + INITIAL_CAPACITY) * 2 <= buffer.length) {
-      // Reuse existing buffer if it's big enough.
-      newBuffer = new Uint16List.view((buffer as Uint8List).buffer);
-    } else {
-      int newCapacity = buffer.length;
-      if (newCapacity - length < INITIAL_CAPACITY) {
-        newCapacity = length + INITIAL_CAPACITY;
-      }
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-    isLatin1 = false;
-  }
-
-  void _grow() {
-    int newCapacity = buffer.length * 2;
-    List newBuffer;
-    if (isLatin1) {
-      newBuffer = new Uint8List(newCapacity);
-    } else {
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-  }
-
-  void addSlice(List<int> utf8, int position, int end) {
-    assert(position < end);
-    if (partialState > 0) {
-      int continueByteCount = (partialState & MASK_TWO_BIT);
-      int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-      int value = partialState >> SHIFT_VALUE;
-      partialState = NO_PARTIAL;
-      position = addContinuation(
-          utf8, position, end, continueByteCount, missing, value);
-      if (position == end) return;
-    }
-    // Keep index and capacity in local variables while looping over
-    // ASCII characters.
-    int index = length;
-    int capacity = buffer.length;
-    while (position < end) {
-      int char = utf8[position];
-      if (char <= MAX_ASCII) {
-        if (index == capacity) {
-          length = index;
-          _grow();
-          capacity = buffer.length;
-        }
-        buffer[index++] = char;
-        position++;
-        continue;
-      }
-      length = index;
-      if ((char & MASK_CONTINUE_TAG) == CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Unexpected UTF-8 continuation byte", utf8, position);
-        }
-      } else if (char < 0xE0) {
-        // C0-DF
-        // Two-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 1, 1, char & MASK_TWO_BYTE);
-      } else if (char < 0xF0) {
-        // E0-EF
-        // Three-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 2, 2, char & MASK_THREE_BYTE);
-      } else if (char < 0xF8) {
-        // F0-F7
-        // Four-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 3, 3, char & MASK_FOUR_BYTE);
-      } else {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Invalid UTF-8 byte: $char", utf8, position);
-        }
-      }
-      index = length;
-      capacity = buffer.length;
-    }
-    length = index;
-  }
-
-  String toString() {
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        int continueByteCount = (partialState & MASK_TWO_BIT);
-        int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-        int value = partialState >> SHIFT_VALUE;
-        int seenByteCount = continueByteCount - missing + 1;
-        List source = new Uint8List(seenByteCount);
-        while (seenByteCount > 1) {
-          seenByteCount--;
-          source[seenByteCount] = CONTINUE_TAG | (value & MASK_CONTINUE_VALUE);
-          value >>= 6;
-        }
-        source[0] = value | (0x3c0 >> (continueByteCount - 1));
-        throw new FormatException(
-            "Incomplete UTF-8 sequence", source, source.length);
-      }
-    }
-    return new String.fromCharCodes(buffer, 0, length);
-  }
-}
-
 /**
  * Chunked JSON parser that parses UTF-8 chunks.
  */
 class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
-  final bool allowMalformed;
+  final _Utf8Decoder decoder;
   List<int> chunk;
   int chunkEnd;
 
-  _JsonUtf8Parser(_JsonListener listener, this.allowMalformed)
-      : super(listener) {
+  _JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
+      : decoder = new _Utf8Decoder(allowMalformed),
+        super(listener) {
     // Starts out checking for an optional BOM (KWD_BOM, count = 0).
     partialState =
         _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
@@ -1778,21 +1528,24 @@
   }
 
   void beginString() {
-    this.buffer = new _Utf8StringBuffer(allowMalformed);
+    decoder.reset();
+    this.buffer = new StringBuffer();
   }
 
   void addSliceToString(int start, int end) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addSlice(chunk, start, end);
+    final StringBuffer buffer = this.buffer;
+    buffer.write(decoder.convertChunked(chunk, start, end));
   }
 
   void addCharToString(int charCode) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addCharCode(charCode);
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
+    buffer.writeCharCode(charCode);
   }
 
   String endString() {
-    _Utf8StringBuffer buffer = this.buffer;
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
     this.buffer = null;
     return buffer.toString();
   }
@@ -1855,24 +1608,424 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
+class _Utf8Decoder {
+  /// Flags indicating presence of the various kinds of bytes in the input.
+  int _scanFlags = 0;
 
-  // Special case for _Uint8ArrayView.
-  if (units is Uint8List) {
-    if (from >= 0 && to >= 0 && to <= units.length) {
-      for (int i = from; i < to; i++) {
-        final unit = units[i];
-        if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
-      }
-      return to - from;
+  /// How many bytes of the BOM have been read so far. Set to -1 when the BOM
+  /// has been skipped (or was not present).
+  int _bomIndex = 0;
+
+  // Table for the scanning phase, which quickly scans through the input.
+  //
+  // Each input byte is looked up in the table, providing a size and some flags.
+  // The sizes are summed, and the flags are or'ed together.
+  //
+  // The resulting size and flags indicate:
+  // A) How many UTF-16 code units will be emitted by the decoding of this
+  //    input. This can be used to allocate a string of the correct length up
+  //    front.
+  // B) Which decoder and resulting string representation is appropriate. There
+  //    are three cases:
+  //    1) Pure ASCII (flags == 0): The input can simply be put into a
+  //       OneByteString without further decoding.
+  //    2) Latin1 (flags == (flagLatin1 | flagExtension)): The result can be
+  //       represented by a OneByteString, and the decoder can assume that only
+  //       Latin1 characters are present.
+  //    3) Arbitrary input (otherwise): Needs a full-featured decoder. Output
+  //       can be represented by a TwoByteString.
+
+  static const int sizeMask = 0x03;
+  static const int flagsMask = 0x3C;
+
+  static const int flagExtension = 1 << 2;
+  static const int flagLatin1 = 1 << 3;
+  static const int flagNonLatin1 = 1 << 4;
+  static const int flagIllegal = 1 << 5;
+
+  // ASCII     'A' = 64 + (1);
+  // Extension 'D' = 64 + (0 | flagExtension);
+  // Latin1    'I' = 64 + (1 | flagLatin1);
+  // BMP       'Q' = 64 + (1 | flagNonLatin1);
+  // Non-BMP   'R' = 64 + (2 | flagNonLatin1);
+  // Illegal   'a' = 64 + (1 | flagIllegal);
+  // Illegal   'b' = 64 + (2 | flagIllegal);
+  static const String scanTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // 80-9F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // A0-BF
+      "aaIIQQQQQQQQQQQQQQQQQQQQQQQQQQQQ" // C0-DF
+      "QQQQQQQQQQQQQQQQRRRRRbbbbbbbbbbb" // E0-FF
+      ;
+
+  /// Reset the decoder to a state where it is ready to decode a new string but
+  /// will not skip a leading BOM. Used by the fused UTF-8 / JSON decoder.
+  void reset() {
+    _state = initial;
+    _bomIndex = -1;
+  }
+
+  // The VM decoder handles BOM explicitly instead of via the state machine.
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = initial;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
     }
+
+    // Skip initial BOM.
+    start = skipBomSingle(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (_state == accept) {
+      return result;
+    }
+
+    if (!allowMalformed) {
+      if (!isErrorState(_state)) {
+        // Unfinished sequence.
+        _state = errorUnfinished;
+        _charOrIndex = end;
+      }
+      final String message = errorDescription(_state);
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = initial;
+    result = decodeGeneral(bytes, start, end, true);
+    assert(!isErrorState(_state));
+    return result;
   }
 
-  // Fall through to normal case.
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    // Skip initial BOM.
+    start = skipBomChunked(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    // Adjust scan flags and size based on carry-over state.
+    switch (_state) {
+      case IA:
+        break;
+      case X1:
+        flags |= _charOrIndex < (0x100 >> 6) ? flagLatin1 : flagNonLatin1;
+        if (end - start >= 1) {
+          size += _charOrIndex < (0x10000 >> 6) ? 1 : 2;
+        }
+        break;
+      case X2:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) {
+          size += _charOrIndex < (0x10000 >> 12) ? 1 : 2;
+        }
+        break;
+      case TO:
+      case TS:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) size += 1;
+        break;
+      case X3:
+      case QO:
+      case QR:
+        flags |= flagNonLatin1;
+        if (end - start >= 3) size += 2;
+        break;
+    }
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(_state == accept);
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    // Do not include any final, incomplete character in size.
+    int extensionCount = 0;
+    int i = end - 1;
+    while (i >= start && (bytes[i] & 0xC0) == 0x80) {
+      extensionCount++;
+      i--;
+    }
+    if (i >= start && bytes[i] >= ((~0x3F >> extensionCount) & 0xFF)) {
+      size -= bytes[i] >= 0xF0 ? 2 : 1;
+    }
+
+    final int carryOverState = _state;
+    final int carryOverChar = _charOrIndex;
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (!isErrorState(_state)) {
+      return result;
+    }
+    assert(_bomIndex == -1);
+
+    if (!allowMalformed) {
+      final String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = carryOverState;
+    _charOrIndex = carryOverChar;
+    result = decodeGeneral(bytes, start, end, false);
+    assert(!isErrorState(_state));
+    return result;
   }
-  return to - from;
+
+  @pragma("vm:prefer-inline")
+  int skipBomSingle(Uint8List bytes, int start, int end) {
+    if (end - start >= 3 &&
+        bytes[start] == 0xEF &&
+        bytes[start + 1] == 0xBB &&
+        bytes[start + 2] == 0xBF) {
+      return start + 3;
+    }
+    return start;
+  }
+
+  @pragma("vm:prefer-inline")
+  int skipBomChunked(Uint8List bytes, int start, int end) {
+    assert(start <= end);
+    int bomIndex = _bomIndex;
+    // Already skipped?
+    if (bomIndex == -1) return start;
+
+    const bomValues = <int>[0xEF, 0xBB, 0xBF];
+    int i = start;
+    while (bomIndex < 3) {
+      if (i == end) {
+        // Unfinished BOM.
+        _bomIndex = bomIndex;
+        return start;
+      }
+      if (bytes[i++] != bomValues[bomIndex++]) {
+        // No BOM.
+        _bomIndex = -1;
+        return start;
+      }
+    }
+    // Complete BOM.
+    _bomIndex = -1;
+    _state = initial;
+    return i;
+  }
+
+  // Scanning functions to compute the size of the resulting string and flags
+  // (written to _scanFlags) indicating which decoder to use.
+  // TODO(dartbug.com/41702): Intrinsify this function.
+  int scan(Uint8List bytes, int start, int end) {
+    _scanFlags = 0;
+    for (int i = start; i < end; i++) {
+      if (bytes[i] > 127) return i - start + scan2(bytes, i, end);
+    }
+    return end - start;
+  }
+
+  int scan2(Uint8List bytes, int start, int end) {
+    final String scanTable = _Utf8Decoder.scanTable;
+    int size = 0;
+    int flags = 0;
+    for (int i = start; i < end; i++) {
+      int t = scanTable.codeUnitAt(bytes[i]);
+      size += t & sizeMask;
+      flags |= t;
+    }
+    _scanFlags = flags & flagsMask;
+    return size;
+  }
+
+  String decode8(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    // TODO(dartbug.com/41704): Allocate an uninitialized _OneByteString and
+    // write characters to it using _setAt.
+    Uint8List chars = Uint8List(size);
+    int i = start;
+    int j = 0;
+    if (_state == X1) {
+      // Half-way though 2-byte sequence
+      assert(_charOrIndex == 2 || _charOrIndex == 3);
+      final int e = bytes[i++] ^ 0x80;
+      if (e >= 0x40) {
+        _state = errorMissingExtension;
+        _charOrIndex = i - 1;
+        return "";
+      }
+      chars[j++] = (_charOrIndex << 6) | e;
+      _state = accept;
+    }
+    assert(_state == accept);
+    while (i < end) {
+      int byte = bytes[i++];
+      if (byte >= 0x80) {
+        if (byte < 0xC0) {
+          _state = errorUnexpectedExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        assert(byte == 0xC2 || byte == 0xC3);
+        if (i == end) {
+          _state = X1;
+          _charOrIndex = byte & 0x1F;
+          break;
+        }
+        final int e = bytes[i++] ^ 0x80;
+        if (e >= 0x40) {
+          _state = errorMissingExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        byte = (byte << 6) | e;
+      }
+      chars[j++] = byte;
+    }
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
+
+  String decode16(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    // TODO(dartbug.com/41704): Allocate an uninitialized _TwoByteString and
+    // write characters to it using _setAt.
+    Uint16List chars = Uint16List(size);
+    int i = start;
+    int j = 0;
+    int state = _state;
+    int char;
+
+    // First byte
+    assert(!isErrorState(state));
+    final int byte = bytes[i++];
+    final int type = typeTable.codeUnitAt(byte) & typeMask;
+    if (state == accept) {
+      char = byte & (shiftedByteMask >> type);
+      state = transitionTable.codeUnitAt(type);
+    } else {
+      char = (byte & 0x3F) | (_charOrIndex << 6);
+      state = transitionTable.codeUnitAt(state + type);
+    }
+
+    while (i < end) {
+      final int byte = bytes[i++];
+      final int type = typeTable.codeUnitAt(byte) & typeMask;
+      if (state == accept) {
+        if (char >= 0x10000) {
+          assert(char < 0x110000);
+          chars[j++] = 0xD7C0 + (char >> 10);
+          chars[j++] = 0xDC00 + (char & 0x3FF);
+        } else {
+          chars[j++] = char;
+        }
+        char = byte & (shiftedByteMask >> type);
+        state = transitionTable.codeUnitAt(type);
+      } else if (isErrorState(state)) {
+        _state = state;
+        _charOrIndex = i - 2;
+        return "";
+      } else {
+        char = (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+      }
+    }
+
+    // Final write?
+    if (state == accept) {
+      if (char >= 0x10000) {
+        assert(char < 0x110000);
+        chars[j++] = 0xD7C0 + (char >> 10);
+        chars[j++] = 0xDC00 + (char & 0x3FF);
+      } else {
+        chars[j++] = char;
+      }
+    } else if (isErrorState(state)) {
+      _state = state;
+      _charOrIndex = end - 1;
+      return "";
+    }
+
+    _state = state;
+    _charOrIndex = char;
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
 }
diff --git a/sdk/lib/_internal/vm/lib/errors_patch.dart b/sdk/lib/_internal/vm/lib/errors_patch.dart
index c29f052..ee0d608 100644
--- a/sdk/lib/_internal/vm/lib/errors_patch.dart
+++ b/sdk/lib/_internal/vm/lib/errors_patch.dart
@@ -598,6 +598,7 @@
 
 class _LateInitializationError extends Error
     implements LateInitializationError {
+  @pragma("vm:entry-point")
   _LateInitializationError(this._name);
 
   @pragma("vm:entry-point")
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index 515ad8b..76a8a88 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -11,6 +11,7 @@
 
 import "dart:core" hide Symbol;
 
+import "dart:isolate" show SendPort;
 import "dart:typed_data" show Int32List;
 
 /// These are the additional parts of this patch library:
@@ -47,7 +48,6 @@
   // Implementation of package root/map provision.
   static var packageRootString;
   static var packageConfigString;
-  static var packageRootUriFuture;
   static var packageConfigUriFuture;
   static var resolvePackageUriFuture;
 
@@ -130,3 +130,6 @@
 // This is implemented by a recognized method, but in bytecode through a native.
 @pragma('vm:prefer-inline')
 void reachabilityFence(Object object) native "Internal_reachabilityFence";
+
+void sendAndExit(SendPort sendPort, var message)
+    native "SendPortImpl_sendAndExitInternal_";
diff --git a/sdk/lib/_internal/vm/lib/isolate_patch.dart b/sdk/lib/_internal/vm/lib/isolate_patch.dart
index e17c1de..e357b8a 100644
--- a/sdk/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/vm/lib/isolate_patch.dart
@@ -267,21 +267,21 @@
   // The control port (aka the main isolate port) does not handle any messages.
   if (controlPort != null) {
     controlPort.handler = (_) {}; // Nobody home on the control port.
-  }
 
-  if (parentPort != null) {
-    // Build a message to our parent isolate providing access to the
-    // current isolate's control port and capabilities.
-    //
-    // TODO(floitsch): Send an error message if we can't find the entry point.
-    var readyMessage = new List(2);
-    readyMessage[0] = controlPort.sendPort;
-    readyMessage[1] = capabilities;
+    if (parentPort != null) {
+      // Build a message to our parent isolate providing access to the
+      // current isolate's control port and capabilities.
+      //
+      // TODO(floitsch): Send an error message if we can't find the entry point.
+      final readyMessage = List(2);
+      readyMessage[0] = controlPort.sendPort;
+      readyMessage[1] = capabilities;
 
-    // Out of an excess of paranoia we clear the capabilities from the
-    // stack.  Not really necessary.
-    capabilities = null;
-    parentPort.send(readyMessage);
+      // Out of an excess of paranoia we clear the capabilities from the
+      // stack.  Not really necessary.
+      capabilities = null;
+      parentPort.send(readyMessage);
+    }
   }
   assert(capabilities == null);
 
@@ -343,7 +343,6 @@
   }
 
   static bool _packageSupported() =>
-      (VMLibraryHooks.packageRootUriFuture != null) &&
       (VMLibraryHooks.packageConfigUriFuture != null) &&
       (VMLibraryHooks.resolvePackageUriFuture != null);
 
@@ -355,46 +354,33 @@
       SendPort onError,
       String debugName}) async {
     // `paused` isn't handled yet.
-    RawReceivePort readyPort;
+    // Check for the type of `entryPoint` on the spawning isolate to make
+    // error-handling easier.
+    if (entryPoint is! _UnaryFunction) {
+      throw new ArgumentError(entryPoint);
+    }
+    // The VM will invoke [_startIsolate] with entryPoint as argument.
+
+    // We do not inherit the package config settings from the parent isolate,
+    // instead we use the values that were set on the command line.
+    var packageConfig = VMLibraryHooks.packageConfigString;
+    var script = VMLibraryHooks.platformScript;
+    if (script == null) {
+      // We do not have enough information to support spawning the new
+      // isolate.
+      throw new UnsupportedError("Isolate.spawn");
+    }
+    if (script.isScheme("package")) {
+      script = await Isolate.resolvePackageUri(script);
+    }
+
+    final RawReceivePort readyPort = new RawReceivePort();
     try {
-      // Check for the type of `entryPoint` on the spawning isolate to make
-      // error-handling easier.
-      if (entryPoint is! _UnaryFunction) {
-        throw new ArgumentError(entryPoint);
-      }
-      // The VM will invoke [_startIsolate] with entryPoint as argument.
-      readyPort = new RawReceivePort();
-
-      // We do not inherit the package config settings from the parent isolate,
-      // instead we use the values that were set on the command line.
-      var packageConfig = VMLibraryHooks.packageConfigString;
-      var script = VMLibraryHooks.platformScript;
-      if (script == null) {
-        // We do not have enough information to support spawning the new
-        // isolate.
-        throw new UnsupportedError("Isolate.spawn");
-      }
-      if (script.scheme == "package") {
-        script = await Isolate.resolvePackageUri(script);
-      }
-
-      _spawnFunction(
-          readyPort.sendPort,
-          script.toString(),
-          entryPoint,
-          message,
-          paused,
-          errorsAreFatal,
-          onExit,
-          onError,
-          null,
-          packageConfig,
-          debugName);
+      _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+          paused, errorsAreFatal, onExit, onError, packageConfig, debugName);
       return await _spawnCommon(readyPort);
     } catch (e, st) {
-      if (readyPort != null) {
-        readyPort.close();
-      }
+      readyPort.close();
       return await new Future<Isolate>.error(e, st);
     }
   }
@@ -411,7 +397,6 @@
       Uri packageConfig,
       bool automaticPackageResolution: false,
       String debugName}) async {
-    RawReceivePort readyPort;
     if (environment != null) {
       throw new UnimplementedError("environment");
     }
@@ -434,38 +419,30 @@
             "packageRoot and a packageConfig.");
       }
     }
+    // Resolve the uri against the current isolate's root Uri first.
+    final Uri spawnedUri = _rootUri.resolveUri(uri);
+
+    // Inherit this isolate's package resolution setup if not overridden.
+    if (!automaticPackageResolution && packageConfig == null) {
+      if (Isolate._packageSupported()) {
+        packageConfig = await Isolate.packageConfig;
+      }
+    }
+
+    // Ensure to resolve package: URIs being handed in as parameters.
+    if (packageConfig != null) {
+      // Avoid calling resolvePackageUri if not strictly necessary in case
+      // the API is not supported.
+      if (packageConfig.isScheme("package")) {
+        packageConfig = await Isolate.resolvePackageUri(packageConfig);
+      }
+    }
+
+    // The VM will invoke [_startIsolate] and not `main`.
+    final packageConfigString = packageConfig?.toString();
+
+    final RawReceivePort readyPort = new RawReceivePort();
     try {
-      // Resolve the uri against the current isolate's root Uri first.
-      var spawnedUri = _rootUri.resolveUri(uri);
-
-      // Inherit this isolate's package resolution setup if not overridden.
-      if (!automaticPackageResolution &&
-          (packageRoot == null) &&
-          (packageConfig == null)) {
-        if (Isolate._packageSupported()) {
-          packageRoot = await Isolate.packageRoot;
-          packageConfig = await Isolate.packageConfig;
-        }
-      }
-
-      // Ensure to resolve package: URIs being handed in as parameters.
-      if (packageRoot != null) {
-        // `packages/` directory is no longer supported. Force it null.
-        // TODO(mfairhurst) Should this throw an exception?
-        packageRoot = null;
-      } else if (packageConfig != null) {
-        // Avoid calling resolvePackageUri if not strictly necessary in case
-        // the API is not supported.
-        if (packageConfig.scheme == "package") {
-          packageConfig = await Isolate.resolvePackageUri(packageConfig);
-        }
-      }
-
-      // The VM will invoke [_startIsolate] and not `main`.
-      readyPort = new RawReceivePort();
-      var packageRootString = packageRoot?.toString();
-      var packageConfigString = packageConfig?.toString();
-
       _spawnUri(
           readyPort.sendPort,
           spawnedUri.toString(),
@@ -478,20 +455,17 @@
           checked,
           null,
           /* environment */
-          packageRootString,
           packageConfigString,
           debugName);
       return await _spawnCommon(readyPort);
     } catch (e) {
-      if (readyPort != null) {
-        readyPort.close();
-      }
+      readyPort.close();
       rethrow;
     }
   }
 
   static Future<Isolate> _spawnCommon(RawReceivePort readyPort) {
-    Completer completer = new Completer<Isolate>.sync();
+    final completer = new Completer<Isolate>.sync();
     readyPort.handler = (readyMessage) {
       readyPort.close();
       if (readyMessage is List && readyMessage.length == 2) {
@@ -536,7 +510,6 @@
       bool errorsAreFatal,
       SendPort onExit,
       SendPort onError,
-      String packageRoot,
       String packageConfig,
       String debugName) native "Isolate_spawnFunction";
 
@@ -551,7 +524,6 @@
       bool errorsAreFatal,
       bool checked,
       List environment,
-      String packageRoot,
       String packageConfig,
       String debugName) native "Isolate_spawnUri";
 
diff --git a/sdk/lib/_internal/vm/lib/symbol_patch.dart b/sdk/lib/_internal/vm/lib/symbol_patch.dart
index 3671bf7..338b339 100644
--- a/sdk/lib/_internal/vm/lib/symbol_patch.dart
+++ b/sdk/lib/_internal/vm/lib/symbol_patch.dart
@@ -12,7 +12,7 @@
   const Symbol(String name) : this._name = name;
 
   @patch
-  toString() => 'Symbol("${computeUnmangledName(this)}")';
+  String toString() => 'Symbol("${computeUnmangledName(this)}")';
 
   @patch
   static String computeUnmangledName(Symbol symbol) {
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index c7cefce..df685d5 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -551,6 +551,10 @@
       _chainFuture(value);
       return;
     }
+    _asyncCompleteWithValue(value);
+  }
+
+  void _asyncCompleteWithValue(T value) {
     _setPendingComplete();
     _zone.scheduleMicrotask(() {
       _completeWithValue(value);
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index 505ab42..2a8d462 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -641,10 +641,11 @@
     // all the characters in `charOr` and later validate that all characters
     // were ASCII.
     var charOr = 0;
+    final inverseAlphabet = _Base64Decoder._inverseAlphabet;
     for (var i = start; i < end; i++) {
       var char = input.codeUnitAt(i);
       charOr |= char;
-      var code = _inverseAlphabet[char & asciiMask];
+      var code = inverseAlphabet[char & asciiMask];
       if (code >= 0) {
         bits = ((bits << bitsPerCharacter) | code) & 0xFFFFFF;
         count = (count + 1) & 3;
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 5aa14b2..fc55abc 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -535,11 +535,16 @@
   static const int char_0 = 0x30;
   static const int backslash = 0x5c;
   static const int char_b = 0x62;
+  static const int char_d = 0x64;
   static const int char_f = 0x66;
   static const int char_n = 0x6e;
   static const int char_r = 0x72;
   static const int char_t = 0x74;
   static const int char_u = 0x75;
+  static const int surrogateMin = 0xd800;
+  static const int surrogateMask = 0xfc00;
+  static const int surrogateLead = 0xd800;
+  static const int surrogateTrail = 0xdc00;
 
   /// List of objects currently being traversed. Used to detect cycles.
   final List _seen = [];
@@ -573,7 +578,30 @@
     final length = s.length;
     for (var i = 0; i < length; i++) {
       var charCode = s.codeUnitAt(i);
-      if (charCode > backslash) continue;
+      if (charCode > backslash) {
+        if (charCode >= surrogateMin) {
+          // Possible surrogate. Check if it is unpaired.
+          if (((charCode & surrogateMask) == surrogateLead &&
+                  !(i + 1 < length &&
+                      (s.codeUnitAt(i + 1) & surrogateMask) ==
+                          surrogateTrail)) ||
+              ((charCode & surrogateMask) == surrogateTrail &&
+                  !(i - 1 >= 0 &&
+                      (s.codeUnitAt(i - 1) & surrogateMask) ==
+                          surrogateLead))) {
+            // Lone surrogate.
+            if (i > offset) writeStringSlice(s, offset, i);
+            offset = i + 1;
+            writeCharCode(backslash);
+            writeCharCode(char_u);
+            writeCharCode(char_d);
+            writeCharCode(hexDigit((charCode >> 8) & 0xf));
+            writeCharCode(hexDigit((charCode >> 4) & 0xf));
+            writeCharCode(hexDigit(charCode & 0xf));
+          }
+        }
+        continue;
+      }
       if (charCode < 32) {
         if (i > offset) writeStringSlice(s, offset, i);
         offset = i + 1;
@@ -953,16 +981,22 @@
       if (char <= 0x7f) {
         writeByte(char);
       } else {
-        if ((char & 0xFC00) == 0xD800 && i + 1 < end) {
-          // Lead surrogate.
-          var nextChar = string.codeUnitAt(i + 1);
-          if ((nextChar & 0xFC00) == 0xDC00) {
-            // Tail surrogate.
-            char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
-            writeFourByteCharCode(char);
-            i++;
-            continue;
+        if ((char & 0xF800) == 0xD800) {
+          // Surrogate.
+          if (char < 0xDC00 && i + 1 < end) {
+            // Lead surrogate.
+            var nextChar = string.codeUnitAt(i + 1);
+            if ((nextChar & 0xFC00) == 0xDC00) {
+              // Tail surrogate.
+              char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
+              writeFourByteCharCode(char);
+              i++;
+              continue;
+            }
           }
+          // Unpaired surrogate.
+          writeMultiByteCharCode(unicodeReplacementCharacterRune);
+          continue;
         }
         writeMultiByteCharCode(char);
       }
diff --git a/sdk/lib/convert/string_conversion.dart b/sdk/lib/convert/string_conversion.dart
index 086ed79..6c7d965 100644
--- a/sdk/lib/convert/string_conversion.dart
+++ b/sdk/lib/convert/string_conversion.dart
@@ -256,12 +256,13 @@
 class _Utf8StringSinkAdapter extends ByteConversionSink {
   final _Utf8Decoder _decoder;
   final Sink _sink;
+  final StringSink _stringSink;
 
-  _Utf8StringSinkAdapter(this._sink, StringSink stringSink, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringSink, allowMalformed);
+  _Utf8StringSinkAdapter(this._sink, this._stringSink, bool allowMalformed)
+      : _decoder = _Utf8Decoder(allowMalformed);
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_stringSink);
     if (_sink != null) _sink.close();
   }
 
@@ -271,7 +272,7 @@
 
   void addSlice(
       List<int> codeUnits, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(codeUnits, startIndex, endIndex);
+    _stringSink.write(_decoder.convertChunked(codeUnits, startIndex, endIndex));
     if (isLast) close();
   }
 }
@@ -289,11 +290,11 @@
 
   _Utf8ConversionSink._(
       this._chunkedSink, StringBuffer stringBuffer, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringBuffer, allowMalformed),
+      : _decoder = _Utf8Decoder(allowMalformed),
         _buffer = stringBuffer;
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_buffer);
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _buffer.clear();
@@ -308,7 +309,7 @@
   }
 
   void addSlice(List<int> chunk, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(chunk, startIndex, endIndex);
+    _buffer.write(_decoder.convertChunked(chunk, startIndex, endIndex));
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index a614f39..3d08ad7 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -58,12 +58,19 @@
   /// was used to instantiate `this`.
   String decode(List<int> codeUnits, {bool allowMalformed}) {
     allowMalformed ??= _allowMalformed;
-    return Utf8Decoder(allowMalformed: allowMalformed).convert(codeUnits);
+    // Switch between const objects to avoid allocation.
+    Utf8Decoder decoder = allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
+    return decoder.convert(codeUnits);
   }
 
   Utf8Encoder get encoder => const Utf8Encoder();
   Utf8Decoder get decoder {
-    return Utf8Decoder(allowMalformed: _allowMalformed);
+    // Switch between const objects to avoid allocation.
+    return _allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
   }
 }
 
@@ -131,6 +138,13 @@
   /// Allow an implementation to pick the most efficient way of storing bytes.
   static Uint8List _createBuffer(int size) => Uint8List(size);
 
+  /// Write a replacement character (U+FFFD). Used for unpaired surrogates.
+  void _writeReplacementCharacter() {
+    _buffer[_bufferIndex++] = 0xEF;
+    _buffer[_bufferIndex++] = 0xBF;
+    _buffer[_bufferIndex++] = 0xBD;
+  }
+
   /// Tries to combine the given [leadingSurrogate] with the [nextCodeUnit] and
   /// writes it to [_buffer].
   ///
@@ -138,8 +152,8 @@
   /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
   /// surrogate and has not been written yet.
   ///
-  /// It is safe to pass 0 for [nextCodeUnit] in which case only the leading
-  /// surrogate is written.
+  /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement
+  /// character is written to represent the unpaired lead surrogate.
   bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
     if (_isTailSurrogate(nextCodeUnit)) {
       var rune = _combineSurrogatePair(leadingSurrogate, nextCodeUnit);
@@ -153,14 +167,8 @@
       _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
       return true;
     } else {
-      // TODO(floitsch): allow to throw on malformed strings.
-      // Encode the half-surrogate directly into UTF-8. This yields
-      // invalid UTF-8, but we started out with invalid UTF-16.
-
-      // Surrogates are always encoded in 3 bytes in UTF-8.
-      _buffer[_bufferIndex++] = 0xE0 | (leadingSurrogate >> 12);
-      _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f);
-      _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f);
+      // Unpaired lead surrogate.
+      _writeReplacementCharacter();
       return false;
     }
   }
@@ -186,12 +194,16 @@
         if (_bufferIndex >= _buffer.length) break;
         _buffer[_bufferIndex++] = codeUnit;
       } else if (_isLeadSurrogate(codeUnit)) {
-        if (_bufferIndex + 3 >= _buffer.length) break;
+        if (_bufferIndex + 4 > _buffer.length) break;
         // Note that it is safe to read the next code unit. We decremented
         // [end] above when the last valid code unit was a leading surrogate.
         var nextCodeUnit = str.codeUnitAt(stringIndex + 1);
         var wasCombined = _writeSurrogate(codeUnit, nextCodeUnit);
         if (wasCombined) stringIndex++;
+      } else if (_isTailSurrogate(codeUnit)) {
+        if (_bufferIndex + 3 > _buffer.length) break;
+        // Unpaired tail surrogate.
+        _writeReplacementCharacter();
       } else {
         var rune = codeUnit;
         if (rune <= _TWO_BYTE_LIMIT) {
@@ -306,29 +318,7 @@
       return result;
     }
 
-    var length = codeUnits.length;
-    end = RangeError.checkValidRange(start, end, length);
-
-    // Fast case for ASCII strings avoids StringBuffer/_Utf8Decoder.
-    int oneBytes = _scanOneByteCharacters(codeUnits, start, end);
-    StringBuffer buffer;
-    bool isFirstCharacter = true;
-    if (oneBytes > 0) {
-      var firstPart = String.fromCharCodes(codeUnits, start, start + oneBytes);
-      start += oneBytes;
-      if (start == end) {
-        return firstPart;
-      }
-      buffer = StringBuffer(firstPart);
-      isFirstCharacter = false;
-    }
-
-    buffer ??= StringBuffer();
-    var decoder = _Utf8Decoder(buffer, _allowMalformed);
-    decoder._isFirstCharacter = isFirstCharacter;
-    decoder.convert(codeUnits, start, end);
-    decoder.flush(codeUnits, end);
-    return buffer.toString();
+    return _Utf8Decoder(_allowMalformed).convertSingle(codeUnits, start, end);
   }
 
   /// Starts a chunked conversion.
@@ -374,185 +364,314 @@
     0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10) |
     (tail & _SURROGATE_VALUE_MASK);
 
-/// Decodes UTF-8.
-///
-/// The decoder handles chunked input.
-// TODO(floitsch): make this class public.
 class _Utf8Decoder {
-  final bool _allowMalformed;
-  final StringSink _stringSink;
-  bool _isFirstCharacter = true;
-  int _value = 0;
-  int _expectedUnits = 0;
-  int _extraUnits = 0;
+  /// Decode malformed UTF-8 as replacement characters (instead of throwing)?
+  final bool allowMalformed;
 
-  _Utf8Decoder(this._stringSink, this._allowMalformed);
+  /// Decoder DFA state.
+  int _state;
 
-  bool get hasPartialInput => _expectedUnits > 0;
+  /// Partially decoded character. Meaning depends on state. Not used when in
+  /// the initial/accept state. When in an error state, contains the index into
+  /// the input of the error.
+  int _charOrIndex = 0;
 
-  // Limits of one through four byte encodings.
-  static const List<int> _LIMITS = <int>[
-    _ONE_BYTE_LIMIT,
-    _TWO_BYTE_LIMIT,
-    _THREE_BYTE_LIMIT,
-    _FOUR_BYTE_LIMIT
-  ];
+  // State machine for UTF-8 decoding, based on this decoder by Björn Höhrmann:
+  // https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+  //
+  // One iteration in the state machine proceeds as:
+  //
+  // type = typeTable[byte];
+  // char = (state != accept)
+  //     ? (byte & 0x3F) | (char << 6)
+  //     : byte & (shiftedByteMask >> type);
+  // state = transitionTable[state + type];
+  //
+  // After each iteration, if state == accept, char is output as a character.
 
-  void close() {
-    flush();
+  // Mask to and on the type read from the table.
+  static const int typeMask = 0x1F;
+  // Mask shifted right by byte type to mask first byte of sequence.
+  static const int shiftedByteMask = 0xF0FE;
+
+  // Byte types.
+  // 'A' = ASCII, 00-7F
+  // 'B' = 2-byte, C2-DF
+  // 'C' = 3-byte, E1-EC, EE
+  // 'D' = 3-byte (possibly surrogate), ED
+  // 'E' = Illegal, C0-C1, F5+
+  // 'F' = Low extension, 80-8F
+  // 'G' = Mid extension, 90-9F
+  // 'H' = High extension, A0-BA, BC-BE
+  // 'I' = Second byte of BOM, BB
+  // 'J' = Third byte of BOM, BF
+  // 'K' = 3-byte (possibly overlong), E0
+  // 'L' = First byte of BOM, EF
+  // 'M' = 4-byte (possibly out-of-range), F4
+  // 'N' = 4-byte, F1-F3
+  // 'O' = 4-byte (possibly overlong), F0
+  static const String typeTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "FFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGG" // 80-9F
+      "HHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJ" // A0-BF
+      "EEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" // C0-DF
+      "KCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE" // E0-FF
+      ;
+
+  // States (offsets into transition table).
+  static const int IA = 0x00; // Initial / Accept
+  static const int BB = 0x10; // Before BOM
+  static const int AB = 0x20; // After BOM
+  static const int X1 = 0x30; // Expecting one extension byte
+  static const int X2 = 0x3A; // Expecting two extension bytes
+  static const int X3 = 0x44; // Expecting three extension bytes
+  static const int TO = 0x4E; // Possibly overlong 3-byte
+  static const int TS = 0x58; // Possibly surrogate
+  static const int QO = 0x62; // Possibly overlong 4-byte
+  static const int QR = 0x6C; // Possibly out-of-range 4-byte
+  static const int B1 = 0x76; // One byte into BOM
+  static const int B2 = 0x80; // Two bytes into BOM
+  static const int E1 = 0x41; // Error: Missing extension byte
+  static const int E2 = 0x43; // Error: Unexpected extension byte
+  static const int E3 = 0x45; // Error: Invalid byte
+  static const int E4 = 0x47; // Error: Overlong encoding
+  static const int E5 = 0x49; // Error: Out of range
+  static const int E6 = 0x4B; // Error: Surrogate
+  static const int E7 = 0x4D; // Error: Unfinished
+
+  // Character equivalents for states.
+  static const String _IA = '\u0000';
+  static const String _BB = '\u0010';
+  static const String _AB = '\u0020';
+  static const String _X1 = '\u0030';
+  static const String _X2 = '\u003A';
+  static const String _X3 = '\u0044';
+  static const String _TO = '\u004E';
+  static const String _TS = '\u0058';
+  static const String _QO = '\u0062';
+  static const String _QR = '\u006C';
+  static const String _B1 = '\u0076';
+  static const String _B2 = '\u0080';
+  static const String _E1 = '\u0041';
+  static const String _E2 = '\u0043';
+  static const String _E3 = '\u0045';
+  static const String _E4 = '\u0047';
+  static const String _E5 = '\u0049';
+  static const String _E6 = '\u004B';
+  static const String _E7 = '\u004D';
+
+  // Transition table of the state machine. Maps state and byte type
+  // to next state.
+  static const String transitionTable = " "
+      // A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // IA
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_B1$_QR$_X3$_QO " // BB
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // AB
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_IA" // Overlap 5 E1s        X1
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_X1$_X1" // Overlap 5 E1s        X2
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_X2$_X2$_X2$_X2" // Overlap 5 E1s        X3
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_E4$_X1$_X1$_X1" // Overlap 5 E1s        TO
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_E6$_E6$_E6" // Overlap 5 E1s        TS
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_X2$_X2$_X2$_X2" // Overlap 5 E1s        QO
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_E5$_E5$_E5$_E5" // Overlap 5 E1s        QR
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_B2$_X1" // Overlap 5 E1s        B1
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_AB$_E1$_E1$_E1$_E1$_E1" //  B2
+      ;
+
+  // Aliases for states.
+  static const int initial = IA;
+  static const int accept = IA;
+  static const int beforeBom = BB;
+  static const int afterBom = AB;
+  static const int errorMissingExtension = E1;
+  static const int errorUnexpectedExtension = E2;
+  static const int errorInvalid = E3;
+  static const int errorOverlong = E4;
+  static const int errorOutOfRange = E5;
+  static const int errorSurrogate = E6;
+  static const int errorUnfinished = E7;
+
+  static bool isErrorState(int state) => (state & 1) != 0;
+
+  static String errorDescription(int state) {
+    switch (state) {
+      case errorMissingExtension:
+        return "Missing extension byte";
+      case errorUnexpectedExtension:
+        return "Unexpected extension byte";
+      case errorInvalid:
+        return "Invalid UTF-8 byte";
+      case errorOverlong:
+        return "Overlong encoding";
+      case errorOutOfRange:
+        return "Out of unicode range";
+      case errorSurrogate:
+        return "Encoded surrogate";
+      case errorUnfinished:
+        return "Unfinished UTF-8 octet sequence";
+      default:
+        return "";
+    }
+  }
+
+  external _Utf8Decoder(bool allowMalformed);
+
+  external String convertSingle(List<int> codeUnits, int start, int maybeEnd);
+
+  external String convertChunked(List<int> codeUnits, int start, int maybeEnd);
+
+  String convertGeneral(
+      List<int> codeUnits, int start, int maybeEnd, bool single) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    if (start == end) return "";
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    String result = decodeGeneral(bytes, start, end, single);
+    if (isErrorState(_state)) {
+      String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+    return result;
   }
 
   /// Flushes this decoder as if closed.
   ///
   /// This method throws if the input was partial and the decoder was
   /// constructed with `allowMalformed` set to `false`.
-  ///
-  /// The [source] and [offset] of the current position may be provided,
-  /// and are included in the exception if one is thrown.
-  void flush([List<int> source, int offset]) {
-    if (hasPartialInput) {
-      if (!_allowMalformed) {
-        throw FormatException(
-            "Unfinished UTF-8 octet sequence", source, offset);
-      }
-      _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-      _value = 0;
-      _expectedUnits = 0;
-      _extraUnits = 0;
+  void flush(StringSink sink) {
+    final int state = _state;
+    _state = initial;
+    if (state <= afterBom) {
+      return;
+    }
+    // Unfinished sequence.
+    if (allowMalformed) {
+      sink.writeCharCode(unicodeReplacementCharacterRune);
+    } else {
+      throw FormatException(errorDescription(errorUnfinished), null, null);
     }
   }
 
-  void convert(List<int> codeUnits, int startIndex, int endIndex) {
-    var value = _value;
-    var expectedUnits = _expectedUnits;
-    var extraUnits = _extraUnits;
-    _value = 0;
-    _expectedUnits = 0;
-    _extraUnits = 0;
-
-    var i = startIndex;
+  String decodeGeneral(Uint8List bytes, int start, int end, bool single) {
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    int state = _state;
+    int char = _charOrIndex;
+    final StringBuffer buffer = StringBuffer();
+    int i = start;
+    int byte = bytes[i++];
     loop:
     while (true) {
       multibyte:
-      if (expectedUnits > 0) {
-        do {
-          if (i == endIndex) {
-            break loop;
-          }
-          var unit = codeUnits[i];
-          if ((unit & 0xC0) != 0x80) {
-            expectedUnits = 0;
-            if (!_allowMalformed) {
-              throw FormatException(
-                  "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                  codeUnits,
-                  i);
+      while (true) {
+        int type = typeTable.codeUnitAt(byte) & typeMask;
+        char = (state <= afterBom)
+            ? byte & (shiftedByteMask >> type)
+            : (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+        if (state == accept) {
+          buffer.writeCharCode(char);
+          if (i == end) break loop;
+          break multibyte;
+        } else if (isErrorState(state)) {
+          if (allowMalformed) {
+            switch (state) {
+              case errorInvalid:
+              case errorUnexpectedExtension:
+                // A single byte that can't start a sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
+              case errorMissingExtension:
+                // Unfinished sequence followed by a byte that can start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                // Re-parse offending byte.
+                i -= 1;
+                break;
+              default:
+                // Unfinished sequence followed by a byte that can't start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
             }
-            _isFirstCharacter = false;
-            _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-            break multibyte;
+            state = initial;
           } else {
-            value = (value << 6) | (unit & 0x3f);
-            expectedUnits--;
-            i++;
+            _state = state;
+            _charOrIndex = i - 1;
+            return "";
           }
-        } while (expectedUnits > 0);
-        if (value <= _LIMITS[extraUnits - 1]) {
-          // Overly long encoding. The value could be encoded with a shorter
-          // encoding.
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Overlong encoding of 0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          expectedUnits = extraUnits = 0;
-          value = unicodeReplacementCharacterRune;
         }
-        if (value > _FOUR_BYTE_LIMIT) {
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Character outside valid Unicode range: "
-                "0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-        }
-        if (!_isFirstCharacter || value != unicodeBomCharacterRune) {
-          _stringSink.writeCharCode(value);
-        }
-        _isFirstCharacter = false;
+        if (i == end) break loop;
+        byte = bytes[i++];
       }
 
-      while (i < endIndex) {
-        var oneBytes = _scanOneByteCharacters(codeUnits, i, endIndex);
-        if (oneBytes > 0) {
-          _isFirstCharacter = false;
-          assert(i + oneBytes <= endIndex);
-          _stringSink.write(String.fromCharCodes(codeUnits, i, i + oneBytes));
-
-          i += oneBytes;
-          if (i == endIndex) break;
-        }
-        var unit = codeUnits[i++];
-        // TODO(floitsch): the way we test we could potentially allow
-        // units that are too large, if they happen to have the
-        // right bit-pattern. (Same is true for the multibyte loop above).
-        // TODO(floitsch): optimize this loop. See:
-        // https://codereview.chromium.org/22929022/diff/1/sdk/lib/convert/utf.dart?column_width=80
-        if (unit < 0) {
-          // TODO(floitsch): should this be unit <= 0 ?
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}",
-                codeUnits,
-                i - 1);
+      final int markStart = i;
+      byte = bytes[i++];
+      if (byte < 128) {
+        int markEnd = end;
+        while (i < end) {
+          byte = bytes[i++];
+          if (byte >= 128) {
+            markEnd = i - 1;
+            break;
           }
-          _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+        }
+        assert(markStart < markEnd);
+        if (markEnd - markStart < 20) {
+          for (int m = markStart; m < markEnd; m++) {
+            buffer.writeCharCode(bytes[m]);
+          }
         } else {
-          assert(unit > _ONE_BYTE_LIMIT);
-          if ((unit & 0xE0) == 0xC0) {
-            value = unit & 0x1F;
-            expectedUnits = extraUnits = 1;
-            continue loop;
-          }
-          if ((unit & 0xF0) == 0xE0) {
-            value = unit & 0x0F;
-            expectedUnits = extraUnits = 2;
-            continue loop;
-          }
-          // 0xF5, 0xF6 ... 0xFF never appear in valid UTF-8 sequences.
-          if ((unit & 0xF8) == 0xF0 && unit < 0xF5) {
-            value = unit & 0x07;
-            expectedUnits = extraUnits = 3;
-            continue loop;
-          }
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                codeUnits,
-                i - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-          expectedUnits = extraUnits = 0;
-          _isFirstCharacter = false;
-          _stringSink.writeCharCode(value);
+          buffer.write(String.fromCharCodes(bytes, markStart, markEnd));
         }
+        if (markEnd == end) break loop;
       }
-      break loop;
     }
-    if (expectedUnits > 0) {
-      _value = value;
-      _expectedUnits = expectedUnits;
-      _extraUnits = extraUnits;
+
+    if (single && state > afterBom) {
+      // Unfinished sequence.
+      if (allowMalformed) {
+        buffer.writeCharCode(unicodeReplacementCharacterRune);
+      } else {
+        _state = errorUnfinished;
+        _charOrIndex = end;
+        return "";
+      }
     }
+    _state = state;
+    _charOrIndex = char;
+    return buffer.toString();
+  }
+
+  static Uint8List _makeUint8List(List<int> codeUnits, int start, int end) {
+    final int length = end - start;
+    final Uint8List bytes = Uint8List(length);
+    for (int i = 0; i < length; i++) {
+      int b = codeUnits[start + i];
+      if ((b & ~0xFF) != 0) {
+        // Replace invalid byte values by FF, which is also invalid.
+        b = 0xFF;
+      }
+      bytes[i] = b;
+    }
+    return bytes;
   }
 }
-
-// Returns the number of bytes in [units] starting at offset [from] which have
-// the leftmost bit set to 0.
-//
-// To increase performance of this critical method we have a special variant of
-// it implemented in the VM's patch files, which is why we make it external.
-external int _scanOneByteCharacters(List<int> units, int from, int endIndex);
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 8708886..5416d03 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -54,7 +54,7 @@
    * integers, the result is a number with only the bits set that are set in
    * both `this` and [other]
    *
-   * Of both operands are negative, the result is negative, otherwise
+   * If both operands are negative, the result is negative, otherwise
    * the result is non-negative.
    */
   int operator &(int other);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index dd815bc..73f1e6e 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -11778,6 +11778,10 @@
     }
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
   void setAll(int index, Iterable<Element> iterable) {
     throw new UnimplementedError();
   }
@@ -11796,9 +11800,7 @@
 
   Element removeLast() {
     final result = this.last;
-    if (result != null) {
-      _element._removeChild(result);
-    }
+    _element._removeChild(result);
     return result;
   }
 
@@ -36052,7 +36054,8 @@
    * after the operation, and returns `false` if [value] is absent after the
    * operation.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To toggle multiple classes, use
@@ -36086,7 +36089,8 @@
    * If this CssClassSet corresponds to one element. Returns true if [value] was
    * added to the set, otherwise false.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To add multiple classes use
diff --git a/sdk/lib/html/html_common/css_class_set.dart b/sdk/lib/html/html_common/css_class_set.dart
index 486fa31..814829b 100644
--- a/sdk/lib/html/html_common/css_class_set.dart
+++ b/sdk/lib/html/html_common/css_class_set.dart
@@ -110,7 +110,7 @@
     _validateToken(value);
     // TODO - figure out if we need to do any validation here
     // or if the browser natively does enough.
-    return modify((s) => s.add(value));
+    return modify((s) => s.add(value)) ?? false;
   }
 
   /**
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index b3ecbe7..d044b03 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -20,16 +20,17 @@
 import 'dart:core' hide Symbol;
 import 'dart:core' as core;
 import 'dart:math' show Random;
+import 'dart:typed_data' show Uint8List;
 
 part 'async_cast.dart';
 part 'cast.dart';
 part 'errors.dart';
 part 'iterable.dart';
 part 'list.dart';
+part 'linked_list.dart';
 part 'print.dart';
 part 'sort.dart';
 part 'symbol.dart';
-part 'linked_list.dart';
 
 // Powers of 10 up to 10^22 are representable as doubles.
 // Powers of 10 above that are only approximate due to lack of precission.
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index e6b5547..dd45dbd 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -52,7 +52,7 @@
   * operating system.
   */
 @pragma("vm:entry-point")
-class OSError {
+class OSError implements Exception {
   /** Constant used to indicate that no OS error code is available. */
   static const int noErrorCode = -1;
 
diff --git a/sdk/lib/io/network_profiling.dart b/sdk/lib/io/network_profiling.dart
index 8edaeac..f23ed37 100644
--- a/sdk/lib/io/network_profiling.dart
+++ b/sdk/lib/io/network_profiling.dart
@@ -228,8 +228,8 @@
     final map = <String, dynamic>{
       'id': id,
     };
-    _setIfNotNull(map, 'startTime', startTime.toString());
-    _setIfNotNull(map, 'endTime', endTime.toString());
+    _setIfNotNull(map, 'startTime', startTime);
+    _setIfNotNull(map, 'endTime', endTime);
     _setIfNotNull(map, 'address', address);
     _setIfNotNull(map, 'port', port);
     _setIfNotNull(map, 'socketType', socketType);
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 283a30a..c030553 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -215,6 +215,12 @@
    */
   external static InternetAddress _cloneWithNewHost(
       InternetAddress address, String host);
+
+  /// Attempts to parse [address] as a numeric address.
+  ///
+  /// Returns `null` if [address] is not a numeric IPv4 (dotted-decimal
+  /// notation) or IPv6 (hexadecimal representation) address.
+  external static InternetAddress tryParse(String address);
 }
 
 /**
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 6943f13..bfbdaf8 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -49,7 +49,8 @@
 final Map<int, IsolateEmbedderData> isolateEmbedderData =
     new Map<int, IsolateEmbedderData>();
 
-// These must be kept in sync with the declarations in vm/json_stream.h.
+// These must be kept in sync with the declarations in vm/json_stream.h and
+// pkg/dds/lib/src/stream_manager.dart.
 const kParseError = -32700;
 const kInvalidRequest = -32600;
 const kMethodNotFound = -32601;
@@ -178,6 +179,10 @@
 /// Called when we want to [enable] or disable the web server.
 typedef Future<Uri> WebServerControlCallback(bool enable);
 
+/// Called when we want to [enable] or disable new websocket connections to the
+/// server.
+typedef void WebServerAcceptNewWebSocketConnectionsCallback(bool enable);
+
 /// Hooks that are setup by the embedder.
 class VMServiceEmbedderHooks {
   static ServerStartCallback serverStart;
@@ -191,6 +196,8 @@
   static ListFilesCallback listFiles;
   static ServerInformationCallback serverInformation;
   static WebServerControlCallback webServerControl;
+  static WebServerAcceptNewWebSocketConnectionsCallback
+      acceptNewWebSocketConnections;
 }
 
 class _ClientResumePermissions {
@@ -223,6 +230,33 @@
 
   final devfs = new DevFS();
 
+  Uri get ddsUri => _ddsUri;
+  Uri _ddsUri;
+
+  Future<String> _yieldControlToDDS(Message message) async {
+    final acceptNewWebSocketConnections =
+        VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+    if (acceptNewWebSocketConnections == null) {
+      return encodeRpcError(message, kFeatureDisabled,
+          details:
+              'Embedder does not support yielding to a VM service intermediary.');
+    }
+    final uri = message.params['uri'];
+    if (uri == null) {
+      return encodeMissingParamError(message, 'uri');
+    }
+    // DDS can only take control if there is no other clients connected
+    // directly to the VM service.
+    if (clients.length > 1) {
+      return encodeRpcError(message, kFeatureDisabled,
+          details:
+              'Existing VM service clients prevent DDS from taking control.');
+    }
+    acceptNewWebSocketConnections(false);
+    _ddsUri = Uri.parse(uri);
+    return encodeSuccess(message);
+  }
+
   void _clearClientName(Client client) {
     final name = client.name;
     client.name = null;
@@ -361,6 +395,16 @@
     for (var handle in client.serviceHandles.values) {
       handle(null);
     }
+    if (clients.isEmpty) {
+      // If DDS was connected, we are in single client mode and need to
+      // allow for new websocket connections.
+      final acceptNewWebSocketConnections =
+          VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+      if (_ddsUri != null && acceptNewWebSocketConnections != null) {
+        acceptNewWebSocketConnections(true);
+        _ddsUri = null;
+      }
+    }
   }
 
   void _eventMessageHandler(String streamId, Response event) {
@@ -670,45 +714,6 @@
         details: "Unknown service: ${message.method}");
   }
 
-  Future<String> _spawnUri(Message message) async {
-    var token = message.params['token'];
-    if (token == null) {
-      return encodeMissingParamError(message, 'token');
-    }
-    if (token is! String) {
-      return encodeInvalidParamError(message, 'token');
-    }
-    var uri = message.params['uri'];
-    if (uri == null) {
-      return encodeMissingParamError(message, 'uri');
-    }
-    if (uri is! String) {
-      return encodeInvalidParamError(message, 'uri');
-    }
-    var args = message.params['args'];
-    var argsOfString = new List<String>();
-    if (args != null) {
-      if (args is! List) {
-        return encodeInvalidParamError(message, 'args');
-      }
-      for (var arg in args) {
-        if (arg is! String) {
-          return encodeInvalidParamError(message, 'args');
-        }
-        argsOfString.add(arg);
-      }
-    }
-    var msg = message.params['message'];
-
-    Isolate.spawnUri(Uri.parse(uri), argsOfString, msg).then((isolate) {
-      _spawnUriNotify(isolate.controlPort, token);
-    }).catchError((e) {
-      _spawnUriNotify(e.toString(), token);
-    });
-
-    return encodeSuccess(message);
-  }
-
   Future<Response> routeRequest(VMService _, Message message) async {
     final response = await _routeRequestImpl(message);
     if (response == null) {
@@ -724,6 +729,9 @@
       if (message.completed) {
         return await message.response;
       }
+      if (message.method == '_yieldControlToDDS') {
+        return await _yieldControlToDDS(message);
+      }
       if (message.method == 'streamListen') {
         return await _streamListen(message);
       }
@@ -733,9 +741,6 @@
       if (message.method == 'registerService') {
         return await _registerService(message);
       }
-      if (message.method == '_spawnUri') {
-        return await _spawnUri(message);
-      }
       if (message.method == 'setClientName') {
         return _setClientName(message);
       }
@@ -801,6 +806,3 @@
 
 /// Get the bytes to the tar archive.
 Uint8List _requestAssets() native "VMService_RequestAssets";
-
-/// Notify the vm service that an isolate has been spawned via rpc.
-void _spawnUriNotify(obj, String token) native "VMService_spawnUriNotify";
diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn
index b343437..8579a96 100644
--- a/sdk_nnbd/BUILD.gn
+++ b/sdk_nnbd/BUILD.gn
@@ -125,7 +125,7 @@
   ],
   [
     "dartdev",
-    "../utils/dartdev",
+    "../utils/dartdev:generate_dartdev_snapshot",
   ],
   [
     "dartdoc",
@@ -170,7 +170,7 @@
   ],
   [
     "dartdev",
-    "../utils/dartdev",
+    "../utils/dartdev:generate_dartdev_snapshot",
   ],
   [
     "dartdevc",
diff --git a/sdk_nnbd/lib/_http/embedder_config.dart b/sdk_nnbd/lib/_http/embedder_config.dart
new file mode 100644
index 0000000..730bc2dd
--- /dev/null
+++ b/sdk_nnbd/lib/_http/embedder_config.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart._http;
+
+/// Embedder-specific `dart:_http` configuration.
+
+/// [HttpClient] will disallow HTTP URLs if this value is set to `false`.
+@pragma("vm:entry-point")
+bool _embedderAllowsHttp = true;
diff --git a/sdk_nnbd/lib/_http/http.dart b/sdk_nnbd/lib/_http/http.dart
index 551ab65..6db8524 100644
--- a/sdk_nnbd/lib/_http/http.dart
+++ b/sdk_nnbd/lib/_http/http.dart
@@ -23,6 +23,7 @@
 import 'dart:typed_data';
 
 part 'crypto.dart';
+part 'embedder_config.dart';
 part 'http_date.dart';
 part 'http_headers.dart';
 part 'http_impl.dart';
@@ -142,8 +143,7 @@
    *
    * The default value is `null`.
    */
-  String? get serverHeader;
-  void set serverHeader(String? newServerHeader);
+  String? serverHeader;
 
   /**
    * Default set of headers added to all response objects.
@@ -170,8 +170,7 @@
    * The default value is `false` (compression disabled).
    * To enable, set `autoCompress` to `true`.
    */
-  bool get autoCompress;
-  void set autoCompress(bool newAutoCompress);
+  bool autoCompress = false;
 
   /**
    * Gets or sets the timeout used for idle keep-alive connections. If no
@@ -185,8 +184,7 @@
    *
    * To disable, set [idleTimeout] to `null`.
    */
-  Duration? get idleTimeout;
-  void set idleTimeout(Duration? newIdleTimeout);
+  Duration? idleTimeout = const Duration(seconds: 120);
 
   /**
    * Starts listening for HTTP requests on the specified [address] and
@@ -646,22 +644,19 @@
    *
    * The value is negative if there is no content length set.
    */
-  int get contentLength;
-  void set contentLength(int contentLength);
+  int contentLength = -1;
 
   /**
    * Whether the connection is persistent (keep-alive).
    */
-  bool get persistentConnection;
-  void set persistentConnection(bool persistentConnection);
+  late bool persistentConnection;
 
   /**
    * Whether the connection uses chunked transfer encoding.
    *
    * Reflects and modifies the value of the [transferEncodingHeader] header.
    */
-  bool get chunkedTransferEncoding;
-  void set chunkedTransferEncoding(bool chunkedTransferEncoding);
+  late bool chunkedTransferEncoding;
 
   /**
    * The values for the header named [name].
@@ -997,8 +992,7 @@
    * `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`,
    * `{`, and `}`.
    */
-  String get name;
-  void set name(String newName);
+  late String name;
 
   /**
    * The value of the cookie.
@@ -1011,46 +1005,39 @@
    * Cookie values may be wrapped in a single pair of double quotes
    * (U+0022, `"`).
    */
-  String get value;
-  void set value(String newValue);
+  late String value;
 
   /**
    * The time at which the cookie expires.
    */
-  DateTime? get expires;
-  void set expires(DateTime? newExpires);
+  DateTime? expires;
 
   /**
    * The number of seconds until the cookie expires. A zero or negative value
    * means the cookie has expired.
    */
-  int? get maxAge;
-  void set maxAge(int? newMaxAge);
+  int? maxAge;
 
   /**
    * The domain that the cookie applies to.
    */
-  String? get domain;
-  void set domain(String? newDomain);
+  String? domain;
 
   /**
    * The path within the [domain] that the cookie applies to.
    */
-  String? get path;
-  void set path(String? newPath);
+  String? path;
 
   /**
    * Whether to only send this cookie on secure connections.
    */
-  bool get secure;
-  void set secure(bool newSecure);
+  bool secure = false;
 
   /**
    * Whether the cookie is only sent in the HTTP request and is not made
    * available to client side scripts.
    */
-  bool get httpOnly;
-  void set httpOnly(bool newHttpOnly);
+  bool httpOnly = false;
 
   /**
    * Creates a new cookie setting the name and value.
@@ -1279,8 +1266,7 @@
    * the response is not known in advance set the content length to
    * -1, which is also the default if not set.
    */
-  int get contentLength;
-  void set contentLength(int contentLength);
+  int contentLength = -1;
 
   /**
    * The status code of the response.
@@ -1294,8 +1280,7 @@
    * to. Setting the status code after writing to the response body or
    * closing the response will throw a `StateError`.
    */
-  int get statusCode;
-  void set statusCode(int statusCode);
+  int statusCode = HttpStatus.ok;
 
   /**
    * The reason phrase for the response.
@@ -1306,16 +1291,14 @@
    * to. Setting the reason phrase after writing to the response body
    * or closing the response will throw a [StateError].
    */
-  String get reasonPhrase;
-  void set reasonPhrase(String reasonPhrase);
+  late String reasonPhrase;
 
   /**
    * Gets and sets the persistent connection state. The initial value
    * of this property is the persistent connection state from the
    * request.
    */
-  bool get persistentConnection;
-  void set persistentConnection(bool persistentConnection);
+  late bool persistentConnection;
 
   /**
    * Set and get the [deadline] for the response. The deadline is timed from the
@@ -1337,8 +1320,7 @@
    * __Note__: Disabling buffering of the output can result in very poor
    * performance, when writing many small chunks.
    */
-  bool get bufferOutput;
-  void set bufferOutput(bool bufferOutput);
+  bool bufferOutput = true;
 
   /**
    * Returns the response headers.
@@ -1507,8 +1489,7 @@
   /// connections.
   ///
   /// The default value is 15 seconds.
-  Duration get idleTimeout;
-  void set idleTimeout(Duration newIdleTimeout);
+  Duration idleTimeout = const Duration(seconds: 15);
 
   /// Gets and sets the connection timeout.
   ///
@@ -1518,8 +1499,7 @@
   ///
   /// When this is `null`, the OS default timeout is used. The default is
   /// `null`.
-  Duration? get connectionTimeout;
-  void set connectionTimeout(Duration? newConnectionTimeout);
+  Duration? connectionTimeout;
 
   /**
    * Gets and sets the maximum number of live connections, to a single host.
@@ -1531,8 +1511,7 @@
    *
    * Default is `null`.
    */
-  int? get maxConnectionsPerHost;
-  void set maxConnectionsPerHost(int? newMaxConnectionsPerHost);
+  int? maxConnectionsPerHost;
 
   /**
    * Gets and sets whether the body of a response will be automatically
@@ -1560,8 +1539,7 @@
    *
    * Default is `true`.
    */
-  bool get autoUncompress;
-  void set autoUncompress(bool newAutoUncompress);
+  bool autoUncompress = true;
 
   /// Gets and sets the default value of the `User-Agent` header for all requests
   /// generated by this [HttpClient].
@@ -1570,8 +1548,7 @@
   ///
   /// If the userAgent is set to `null`, no default `User-Agent` header will be
   /// added to each request.
-  String? get userAgent;
-  void set userAgent(String? newUserAgent);
+  String? userAgent;
 
   factory HttpClient({SecurityContext? context}) {
     HttpOverrides? overrides = HttpOverrides.current;
@@ -1949,8 +1926,7 @@
    *
    * The default value is `true`.
    */
-  bool get persistentConnection;
-  void set persistentConnection(bool persistentConnection);
+  bool persistentConnection = true;
 
   /**
    * Whether to follow redirects automatically.
@@ -1972,8 +1948,7 @@
    * request(s). However, any body send with the request will not be
    * part of the redirection request(s).
    */
-  bool get followRedirects;
-  void set followRedirects(bool followRedirects);
+  bool followRedirects = true;
 
   /**
    * Set this property to the maximum number of redirects to follow
@@ -1982,8 +1957,7 @@
    *
    * The default value is 5.
    */
-  int get maxRedirects;
-  void set maxRedirects(int maxRedirects);
+  int maxRedirects = 5;
 
   /**
    * The method of the request.
@@ -1999,8 +1973,7 @@
   ///
   /// If the size of the request is not known in advance set content length to
   /// -1, which is also the default.
-  int get contentLength;
-  void set contentLength(int contentLength);
+  int contentLength = -1;
 
   /**
    * Gets or sets if the [HttpClientRequest] should buffer output.
@@ -2010,8 +1983,7 @@
    * __Note__: Disabling buffering of the output can result in very poor
    * performance, when writing many small chunks.
    */
-  bool get bufferOutput;
-  void set bufferOutput(bool bufferOutput);
+  bool bufferOutput = true;
 
   /**
    * Returns the client request headers.
diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart
index 2c50285..cc5e99a 100644
--- a/sdk_nnbd/lib/_http/http_impl.dart
+++ b/sdk_nnbd/lib/_http/http_impl.dart
@@ -1860,7 +1860,8 @@
       // Resume the parser now we have a handler.
       _subscription!.resume();
       return s;
-    }, onError: (e) {
+    });
+    Future<Socket?>.value(_streamFuture).catchError((e) {
       destroy();
     });
     return request;
@@ -2266,6 +2267,32 @@
     });
   }
 
+  /// Whether HTTP requests are currently allowed.
+  ///
+  /// If the [Zone] variable `#dart.library.io.allow_http` is set to a boolean,
+  /// it determines whether the HTTP protocol is allowed. If the zone variable
+  /// is set to any other non-null value, HTTP is not allowed.
+  /// Otherwise, if the `dart.library.io.allow_http` environment flag
+  /// is set to `false`, HTTP is not allowed.
+  /// Otherwise, [_embedderAllowsHttp] determines the result.
+  bool get _isHttpAllowed {
+    final zoneOverride = Zone.current[#dart.library.io.allow_http];
+    if (zoneOverride != null) return true == zoneOverride;
+    bool envOverride =
+        bool.fromEnvironment("dart.library.io.allow_http", defaultValue: true);
+    return envOverride && _embedderAllowsHttp;
+  }
+
+  bool _isLoopback(String host) {
+    if (host.isEmpty) return false;
+    if ("localhost" == host) return true;
+    try {
+      return InternetAddress(host).isLoopback;
+    } on ArgumentError {
+      return false;
+    }
+  }
+
   Future<_HttpClientRequest> _openUrl(String method, Uri uri) {
     if (_closing) {
       throw new StateError("Client is closed");
@@ -2286,7 +2313,12 @@
       }
     }
 
-    bool isSecure = (uri.scheme == "https");
+    bool isSecure = uri.isScheme("https");
+    if (!_isHttpAllowed && !isSecure && !_isLoopback(uri.host)) {
+      throw new StateError(
+          "Insecure HTTP is not allowed by the current platform: $uri");
+    }
+
     int port = uri.port;
     if (port == 0) {
       port =
diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart
index 96891a1..9459789 100644
--- a/sdk_nnbd/lib/_http/http_parser.dart
+++ b/sdk_nnbd/lib/_http/http_parser.dart
@@ -713,10 +713,10 @@
                     (isUpgrade && isResponse && isUpgradeCode)) {
                   _connectionUpgrade = true;
                 }
-                headers.add(headerField, tokens[i]);
+                headers._add(headerField, tokens[i]);
               }
             } else {
-              headers.add(headerField, headerValue);
+              headers._add(headerField, headerValue);
             }
             _headerField.clear();
             _headerValue.clear();
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
index c10f04f..d9709b9 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
@@ -578,30 +578,3 @@
         iterator);
   }
 }
-
-@patch
-abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
-  @patch
-  Node _splayMin(Node node) {
-    var current = node;
-    while (current.left != null) {
-      var left = current.left!;
-      current.left = left.right;
-      left.right = current;
-      current = left as Node;
-    }
-    return current;
-  }
-
-  @patch
-  Node _splayMax(Node node) {
-    var current = node;
-    while (current.right != null) {
-      var right = current.right!;
-      current.right = right.left;
-      right.left = current;
-      current = right as Node;
-    }
-    return current;
-  }
-}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
index a17be68..1b79fe8 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
@@ -496,11 +496,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
index d2c62cf..1d3e398 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -167,19 +167,20 @@
   static int _keyCount = 0;
 }
 
-Null _kNull(_) => null;
-
 @patch
 class int {
   @patch
   static int parse(String source,
       {int? radix, @deprecated int onError(String source)?}) {
-    return Primitives.parseInt(source, radix, onError)!;
+    var value = tryParse(source, radix: radix);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException(source);
   }
 
   @patch
   static int? tryParse(String source, {int? radix}) {
-    return Primitives.parseInt(source, radix, _kNull);
+    return Primitives.parseInt(source, radix);
   }
 
   @patch
@@ -209,12 +210,15 @@
   @patch
   static double parse(String source,
       [@deprecated double onError(String source)?]) {
-    return Primitives.parseDouble(source, onError)!;
+    var value = tryParse(source);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException('Invalid double', source);
   }
 
   @patch
   static double? tryParse(String source) {
-    return Primitives.parseDouble(source, _kNull);
+    return Primitives.parseDouble(source);
   }
 
   @JSExportName('is')
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
index 536b653..2e605a2 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
@@ -11,6 +11,9 @@
 import 'dart:_runtime' as dart;
 
 @patch
+bool typeAcceptsNull<T>() => !dart.strictNullSafety || null is T;
+
+@patch
 class Symbol implements core.Symbol {
   @patch
   const Symbol(String name) : this._name = name;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
index ceee3d4..980adde 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -425,6 +425,11 @@
       InternetAddress address, String host) {
     throw UnsupportedError("InternetAddress._cloneWithNewHost");
   }
+
+  @patch
+  static InternetAddress? tryParse(String address) {
+    throw UnsupportedError("InternetAddress.tryParse");
+  }
 }
 
 @patch
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index 5696d69..ba418a4 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -28,7 +28,7 @@
 // Run-time null safety assertion per:
 // https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
 nullFailed(String? fileUri, int? line, int? column, String? variable) {
-  if (_strictSubtypeChecks) {
+  if (strictNullSafety) {
     throw AssertionErrorImpl(
         'A null value was passed into a non-nullable parameter $variable',
         fileUri,
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index 20555fb..43697c9 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -168,7 +168,7 @@
   var requiredNamed = type.requiredNamed;
   if (namedActuals != null) {
     names = getOwnPropertyNames(namedActuals);
-    for (var name in names!) {
+    for (var name in names) {
       if (!JS<bool>('!', '(#.hasOwnProperty(#) || #.hasOwnProperty(#))', named,
           name, requiredNamed, name)) {
         return "Dynamic call with unexpected named argument '$name'.";
@@ -185,7 +185,7 @@
     if (missingRequired.isNotEmpty) {
       var error = "Dynamic call with missing required named arguments: "
           "${missingRequired.join(', ')}.";
-      if (!_strictSubtypeChecks) {
+      if (!strictNullSafety) {
         _nullWarn(error);
       } else {
         return error;
@@ -430,7 +430,7 @@
 cast(obj, type) {
   // We hoist the common case where null is checked against another type here
   // for better performance.
-  if (obj == null && !_strictSubtypeChecks) {
+  if (obj == null && !strictNullSafety) {
     // Check the null comparison cache to avoid emitting repeated warnings.
     _nullWarnOnType(type);
     return obj;
@@ -443,16 +443,16 @@
 }
 
 bool test(bool? obj) {
-  if (obj == null) _throwBooleanConversionError();
-  return obj!;
-}
-
-bool dtest(obj) {
-  if (obj is! bool) booleanConversionFailed(obj);
+  if (obj == null) throw BooleanConversionAssertionError();
   return obj;
 }
 
-void _throwBooleanConversionError() => throw BooleanConversionAssertionError();
+bool dtest(obj) {
+  // Only throw an AssertionError in weak mode for compatibility. Strong mode
+  // should throw a TypeError.
+  if (obj is! bool) booleanConversionFailed(strictNullSafety ? obj : test(obj));
+  return obj;
+}
 
 void booleanConversionFailed(obj) {
   var actual = typeName(getReifiedType(obj));
@@ -462,7 +462,7 @@
 asInt(obj) {
   // Note: null (and undefined) will fail this test.
   if (JS('!', 'Math.floor(#) != #', obj, obj)) {
-    if (obj == null && !_strictSubtypeChecks) {
+    if (obj == null && !strictNullSafety) {
       _nullWarnOnType(JS('', '#', int));
       return null;
     } else {
@@ -495,7 +495,7 @@
 /// same type.
 nullCast(x, type) {
   if (x == null) {
-    if (!_strictSubtypeChecks) {
+    if (!strictNullSafety) {
       _nullWarnOnType(type);
     } else {
       castError(x, type);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 6bd3820..b985e78 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -6,13 +6,22 @@
 part of dart._runtime;
 
 @notNull
-bool _strictSubtypeChecks = false;
+bool _setNullSafety = false;
+
+@notNull
+bool strictNullSafety = false;
 
 /// Sets the mode of the runtime subtype checks.
 ///
-/// Changing the mode after any calls to dart.isSubtype() is not supported.
-void strictSubtypeChecks(bool flag) {
-  _strictSubtypeChecks = flag;
+/// Changing the mode after the application has started running is not
+/// supported.
+void nullSafety(bool flag) {
+  if (_setNullSafety) {
+    throw UnsupportedError('The Null Safety mode can only be set once.');
+  }
+
+  strictNullSafety = flag;
+  _setNullSafety = true;
 }
 
 final metadata = JS('', 'Symbol("metadata")');
@@ -269,7 +278,7 @@
 /// normalization doc:
 /// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
 @notNull
-Object nullable(type) {
+Object nullable(@notNull Object type) {
   // Check if a nullable version of this type has already been created.
   var cached = JS<Object>('', '#[#]', type, _cachedNullable);
   if (JS<bool>('!', '# !== void 0', cached)) {
@@ -282,7 +291,7 @@
   return cachedType;
 }
 
-Object _computeNullable(type) {
+Object _computeNullable(@notNull Object type) {
   // *? normalizes to ?.
   if (_jsInstanceOf(type, LegacyType)) {
     return nullable(JS<Object>('!', '#.type', type));
@@ -307,7 +316,7 @@
 /// normalization doc:
 /// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
 @notNull
-Object legacy(type) {
+Object legacy(@notNull Object type) {
   // Check if a legacy version of this type has already been created.
   var cached = JS<Object>('', '#[#]', type, _cachedLegacy);
   if (JS<bool>('!', '# !== void 0', cached)) {
@@ -320,7 +329,7 @@
   return cachedType;
 }
 
-Object _computeLegacy(type) {
+Object _computeLegacy(@notNull Object type) {
   // Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy].
   if (_jsInstanceOf(type, LegacyType) ||
       _jsInstanceOf(type, NullableType) ||
@@ -335,7 +344,7 @@
 class NullableType extends DartType {
   final Type type;
 
-  NullableType(this.type);
+  NullableType(@notNull this.type);
 
   @override
   String get name => '$type?';
@@ -356,7 +365,7 @@
 class LegacyType extends DartType {
   final Type type;
 
-  LegacyType(this.type);
+  LegacyType(@notNull this.type);
 
   @override
   String get name => '$type';
@@ -793,15 +802,10 @@
 
   @JSExportName('as')
   as_T(obj) {
-    if (JS('!', 'typeof # == "function"', obj)) {
-      var actual = JS('', '#[#]', obj, _runtimeType);
-      // If there's no actual type, it's a JS function.
-      // Allow them to subtype all Dart function types.
-      if (actual == null || isSubtypeOf(actual, this)) {
-        return obj;
-      }
-    }
-    return castError(obj, this);
+    if (is_T(obj)) return obj;
+    // TODO(nshahan) This could directly call castError after we no longer allow
+    // a cast of null to succeed in weak mode.
+    return cast(obj, this);
   }
 }
 
@@ -850,7 +854,7 @@
       var bound = typeBounds[i];
       if (_equalType(bound, dynamic) ||
           JS<bool>('!', '# === #', bound, nullable(unwrapType(Object))) ||
-          (!_strictSubtypeChecks && _equalType(bound, Object))) {
+          (!strictNullSafety && _equalType(bound, Object))) {
         // Do not print the bound when it is a top type. In weak mode the bounds
         // of Object and Object* will also be elided.
         continue;
@@ -898,17 +902,18 @@
         JS('', '#[2]', parts), JS('', '#[3]', parts));
   }
 
-  List instantiateTypeBounds(List typeArgs) {
+  List<Object> instantiateTypeBounds(List typeArgs) {
     if (!hasTypeBounds) {
-      // We ommit the a bound to represent Object*. Other bounds are explicitly
+      // We omit the a bound to represent Object*. Other bounds are explicitly
       // represented, including Object, Object? and dynamic.
       // TODO(nshahan) Revisit this representation when more libraries have
       // migrated to null safety.
-      return List.filled(formalCount, legacy(unwrapType(Object)));
+      return List<Object>.filled(formalCount, legacy(unwrapType(Object)));
     }
     // Bounds can be recursive or depend on other type parameters, so we need to
     // apply type arguments and return the resulting bounds.
-    return JS('List', '#.apply(null, #)', _instantiateTypeBounds, typeArgs);
+    return JS<List<Object>>(
+        '!', '#.apply(null, #)', _instantiateTypeBounds, typeArgs);
   }
 
   toString() {
@@ -934,10 +939,30 @@
   /// See the issue for the algorithm description:
   /// <https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397>
   List instantiateDefaultBounds() {
+    /// Returns `true` if the default value for the type bound should be
+    /// `dynamic`.
+    ///
+    /// Dart 2 with null safety uses dynamic as the default value for types
+    /// without explicit bounds.
+    ///
+    /// This is similar to [_isTop] but removes the check for `void` (it can't
+    /// be written as a bound) and adds a check of `Object*` in weak mode.
+    bool defaultsToDynamic(type) {
+      // Technically this is wrong, only implicit bounds of `Object?` and
+      // `Object*` should default to dynamic but code that observes the
+      // difference is rare.
+      if (_equalType(type, dynamic)) return true;
+      if (_jsInstanceOf(type, NullableType) ||
+          (!strictNullSafety && _jsInstanceOf(type, LegacyType))) {
+        return _equalType(JS('!', '#.type', type), Object);
+      }
+      return false;
+    }
+
     var typeFormals = this.typeFormals;
 
     // All type formals
-    var all = HashMap<Object, int>.identity();
+    var all = HashMap<TypeVariable, int>.identity();
     // ground types, by index.
     //
     // For each index, this will be a ground type for the corresponding type
@@ -953,8 +978,11 @@
       var typeFormal = typeFormals[i];
       var bound = typeBounds[i];
       all[typeFormal] = i;
-      if (identical(bound, _dynamic)) {
-        defaults[i] = bound;
+      if (defaultsToDynamic(bound)) {
+        // TODO(nshahan) Persist the actual default values into the runtime so
+        // they can be used here instead of using dynamic for all top types
+        // implicit or explicit.
+        defaults[i] = _dynamic;
       } else {
         defaults[i] = typeFormal;
         partials[typeFormal] = bound;
@@ -962,11 +990,12 @@
     }
 
     bool hasFreeFormal(t) {
+      if (partials.containsKey(t)) return true;
+
       // Ignore nullability wrappers.
       if (_jsInstanceOf(t, LegacyType) || _jsInstanceOf(t, NullableType)) {
         return hasFreeFormal(JS<Object>('!', '#.type', t));
       }
-      if (partials.containsKey(t)) return true;
       // Generic classes and typedefs.
       var typeArgs = getGenericArgs(t);
       if (typeArgs != null) return typeArgs.any(hasFreeFormal);
@@ -1019,7 +1048,9 @@
   @JSExportName('as')
   as_T(obj) {
     if (is_T(obj)) return obj;
-    return castError(obj, this);
+    // TODO(nshahan) This could directly call castError after we no longer allow
+    // a cast of null to succeed in weak mode.
+    return cast(obj, this);
   }
 }
 
@@ -1113,7 +1144,7 @@
 })()''');
 
 /// Returns true if [ft1] <: [ft2].
-_isFunctionSubtype(ft1, ft2, bool strictMode) => JS('', '''(() => {
+_isFunctionSubtype(ft1, ft2, @notNull bool strictMode) => JS('', '''(() => {
   let ret1 = $ft1.returnType;
   let ret2 = $ft2.returnType;
 
@@ -1206,7 +1237,7 @@
 
 /// Returns true if [t1] <: [t2].
 @notNull
-bool isSubtypeOf(Object t1, Object t2) {
+bool isSubtypeOf(@notNull Object t1, @notNull Object t2) {
   // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
   // dispatched on the type. Can we optimize the subtype relation too?
   var map = JS<Object>('!', '#[#]', t1, _subtypeCache);
@@ -1214,7 +1245,7 @@
   if (JS('!', '# !== void 0', result)) return result;
 
   var validSubtype = _isSubtype(t1, t2, true);
-  if (!validSubtype && !_strictSubtypeChecks) {
+  if (!validSubtype && !strictNullSafety) {
     validSubtype = _isSubtype(t1, t2, false);
     if (validSubtype) {
       // TODO(nshahan) Need more information to be helpful here.
@@ -1262,6 +1293,22 @@
 @notNull
 external bool _equalType(type, cls);
 
+/// Extracts the type argument as an unwrapped type preserving all forms of
+/// nullability.
+///
+/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For
+/// example `typeRep<Object?>()` emits `dart.nullable(core.Object)` directly.
+@notNull
+external Type typeRep<T>();
+
+/// Extracts the type argument as an unwrapped type and performs a shallow
+/// replacement of the nullability to a legacy type.
+///
+/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For
+/// example `legacyTypeRep<Object>()` emits `dart.legacy(core.Object)` directly.
+@notNull
+external Type legacyTypeRep<T>();
+
 @notNull
 bool _isFutureOr(type) {
   var genericClass = getGenericClass(type);
@@ -1270,7 +1317,7 @@
 }
 
 @notNull
-bool _isSubtype(t1, t2, bool strictMode) => JS<bool>('!', '''(() => {
+bool _isSubtype(t1, t2, @notNull bool strictMode) => JS<bool>('!', '''(() => {
   if (!$strictMode) {
     // Strip nullable types when performing check in weak mode.
     // TODO(nshahan) Investigate stripping off legacy types as well.
@@ -1461,7 +1508,7 @@
   return ${_isFunctionSubtype(t1, t2, strictMode)};
 })()''');
 
-bool _isInterfaceSubtype(t1, t2, strictMode) => JS('', '''(() => {
+bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => {
   // If we have lazy JS types, unwrap them.  This will effectively
   // reduce to a prototype check below.
   if (${_jsInstanceOf(t1, LazyJSType)}) $t1 = $t1.rawJSTypeForCheck();
@@ -1654,7 +1701,7 @@
     var supertypeRequiredNamed = supertype.getRequiredNamedParameters();
     var subtypeNamed = supertype.getNamedParameters();
     var subtypeRequiredNamed = supertype.getRequiredNamedParameters();
-    if (!_strictSubtypeChecks) {
+    if (!strictNullSafety) {
       // In weak mode, treat required named params as optional named params.
       supertypeNamed = {...supertypeNamed, ...supertypeRequiredNamed};
       subtypeNamed = {...subtypeNamed, ...subtypeRequiredNamed};
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
index c92b73d..4538120 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
@@ -294,7 +294,7 @@
         throw ConcurrentModificationError(this);
       }
     }
-    if (matchFound) return match!;
+    if (matchFound) return match as E;
     if (orElse != null) return orElse();
     throw IterableElementError.noElement();
   }
@@ -488,15 +488,15 @@
     return -1;
   }
 
-  int lastIndexOf(Object? element, [int? _startIndex]) {
+  int lastIndexOf(Object? element, [int? startIndex]) {
     @notNull
-    int startIndex = _startIndex ?? this.length - 1;
-    if (startIndex >= this.length) {
-      startIndex = this.length - 1;
-    } else if (startIndex < 0) {
+    int start = startIndex ?? this.length - 1;
+    if (start >= this.length) {
+      start = this.length - 1;
+    } else if (start < 0) {
       return -1;
     }
-    for (int i = startIndex; i >= 0; i--) {
+    for (int i = start; i >= 0; i--) {
       if (this[i] == element) {
         return i;
       }
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
index 6218ba6..11a3a8e 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -68,15 +68,7 @@
 }
 
 class Primitives {
-  @NoInline()
-  static int? _parseIntError(
-      String source, int? Function(String)? handleError) {
-    if (handleError == null) throw FormatException(source);
-    return handleError(source);
-  }
-
-  static int? parseInt(@nullCheck String source, int? _radix,
-      int? Function(String)? handleError) {
+  static int? parseInt(@nullCheck String source, int? _radix) {
     var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
     // TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
     // long as we use it locally and don't expose it to user code.
@@ -88,7 +80,7 @@
       // TODO(sra): It might be that the match failed due to unrecognized U+0085
       // spaces.  We could replace them with U+0020 spaces and try matching
       // again.
-      return _parseIntError(source, handleError);
+      return null;
     }
     String? decimalMatch = match[decimalIndex];
     if (_radix == null) {
@@ -100,7 +92,7 @@
         // Cannot fail because we know that the digits are all hex.
         return JS<int>('!', r'parseInt(#, 16)', source);
       }
-      return _parseIntError(source, handleError);
+      return null;
     }
     @notNull
     var radix = _radix;
@@ -137,7 +129,7 @@
       for (int i = 0; i < digitsPart.length; i++) {
         int characterCode = digitsPart.codeUnitAt(i) | 0x20;
         if (characterCode > maxCharCode) {
-          return _parseIntError(source, handleError);
+          return null;
         }
       }
     }
@@ -146,17 +138,7 @@
     return JS<int>('!', r'parseInt(#, #)', source, radix);
   }
 
-  @NoInline()
-  static double? _parseDoubleError(
-      String source, double? Function(String)? handleError) {
-    if (handleError == null) {
-      throw FormatException('Invalid double', source);
-    }
-    return handleError(source);
-  }
-
-  static double? parseDouble(
-      @nullCheck String source, double? Function(String)? handleError) {
+  static double? parseDouble(@nullCheck String source) {
     // Notice that JS parseFloat accepts garbage at the end of the string.
     // Accept only:
     // - [+/-]NaN
@@ -168,15 +150,15 @@
         r'/^\s*[+-]?(?:Infinity|NaN|'
             r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
         source)) {
-      return _parseDoubleError(source, handleError);
+      return null;
     }
-    double result = JS('!', r'parseFloat(#)', source);
+    var result = JS<double>('!', r'parseFloat(#)', source);
     if (result.isNaN) {
       var trimmed = source.trim();
       if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
         return result;
       }
-      return _parseDoubleError(source, handleError);
+      return null;
     }
     return result;
   }
@@ -190,7 +172,6 @@
     if (timerFrequency != 0) return;
     // Start with low-resolution. We overwrite the fields if we find better.
     timerFrequency = 1000;
-    timerTicks = dateNow;
     if (JS<bool>('!', 'typeof window == "undefined"')) return;
     var jsWindow = JS('var', 'window');
     if (jsWindow == null) return;
@@ -203,7 +184,7 @@
 
   /// 0 frequency indicates the default uninitialized state.
   static int timerFrequency = 0;
-  static late int Function() timerTicks;
+  static int Function() timerTicks = dateNow; // Low-resolution version.
 
   static bool get isD8 {
     return JS(
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
index dfc4707..45ed0c5 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
@@ -196,10 +196,19 @@
   _AsyncAwaitCompleter() : isSync = false;
 
   void complete([FutureOr<T>? value]) {
-    if (!isSync || value is Future<T>) {
-      _future._asyncComplete(value as FutureOr<T>);
+    // All paths require that if value is null, null as T succeeds.
+    value = (value == null) ? value as T : value;
+    if (!isSync) {
+      _future._asyncComplete(value);
+    } else if (value is Future<T>) {
+      assert(!_future._isComplete);
+      _future._chainFuture(value);
     } else {
-      _future._completeWithValue(value as T);
+      // 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.
+      _future._completeWithValue(value as dynamic);
     }
   }
 
@@ -566,9 +575,7 @@
   T? _current = null;
 
   // This is the nested iterator when iterating a yield* of a non-sync iterator.
-  // TODO(32956): In strong-mode, yield* takes an Iterable<T> (possibly checked
-  // with an implicit downcast), so change type to Iterator<T>.
-  Iterator? _nestedIterator = null;
+  Iterator<T>? _nestedIterator = null;
 
   // Stack of suspended state machines when iterating a yield* of a sync*
   // iterator.
@@ -578,8 +585,8 @@
 
   T get current {
     var nested = _nestedIterator;
-    var result = nested != null ? nested.current : _current;
-    return result as T;
+    if (nested == null) return _current as dynamic; // implicit: as T;
+    return nested.current;
   }
 
   _runBody() {
@@ -636,8 +643,12 @@
           JS('', 'throw #', value.value);
         } else {
           assert(state == _IterationMarker.YIELD_STAR);
-          Iterator inner = value.value.iterator;
+          Iterator<T> inner = value.value.iterator;
           if (inner is _SyncStarIterator) {
+            // The test needs to be 'is _SyncStarIterator<T>' for promotion to
+            // work. However, that test is much more expensive, so we use an
+            // unsafe cast.
+            _SyncStarIterator<T> innerSyncStarIterator = JS('', '#', inner);
             // Suspend the current state machine and start acting on behalf of
             // the nested state machine.
             //
@@ -645,7 +656,7 @@
             // suspending the current body when all it will do is step without
             // effect to ITERATION_ENDED.
             (_suspendedBodies ??= []).add(_body);
-            _body = inner._body;
+            _body = innerSyncStarIterator._body;
             continue;
           } else {
             _nestedIterator = inner;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
index 592b8c2..a1d76bf 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -1324,12 +1324,12 @@
     if (_isStringElement(object)) {
       var strings = _strings;
       if (strings == null) return false;
-      _LinkedHashSetCell cell = _getTableEntry(strings, object);
+      _LinkedHashSetCell? cell = _getTableEntry(strings, object);
       return cell != null;
     } else if (_isNumericElement(object)) {
       var nums = _nums;
       if (nums == null) return false;
-      _LinkedHashSetCell cell = _getTableEntry(nums, object);
+      _LinkedHashSetCell? cell = _getTableEntry(nums, object);
       return cell != null;
     } else {
       return _contains(object);
@@ -1474,7 +1474,7 @@
   }
 
   bool _addHashTableEntry(var table, E element) {
-    _LinkedHashSetCell cell = _getTableEntry(table, element);
+    _LinkedHashSetCell? cell = _getTableEntry(table, element);
     if (cell != null) return false;
     _setTableEntry(table, element, _newLinkedCell(element));
     return true;
@@ -1482,7 +1482,7 @@
 
   bool _removeHashTableEntry(var table, Object? element) {
     if (table == null) return false;
-    _LinkedHashSetCell cell = _getTableEntry(table, element);
+    _LinkedHashSetCell? cell = _getTableEntry(table, element);
     if (cell == null) return false;
     _unlinkCell(cell);
     _deleteTableEntry(table, element);
@@ -1714,30 +1714,3 @@
     }
   }
 }
-
-@patch
-abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
-  @patch
-  Node _splayMin(Node node) {
-    Node current = node;
-    while (current.left != null) {
-      Node left = current.left as Node;
-      current.left = left.right;
-      left.right = current;
-      current = left;
-    }
-    return current;
-  }
-
-  @patch
-  Node _splayMax(Node node) {
-    Node current = node;
-    while (current.right != null) {
-      Node right = current.right as Node;
-      current.right = right.left;
-      right.left = current;
-      current = right;
-    }
-    return current;
-  }
-}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
index 44e8ab3..070946a 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -494,11 +494,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
index 10418cf..232cc8d 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
@@ -422,8 +422,11 @@
         ? new JSArray<E>.growable(length)
         : new JSArray<E>.fixed(length);
     if (length != 0 && fill != null) {
+      // TODO(sra): Consider using `Array.fill`.
       for (int i = 0; i < result.length; i++) {
-        result[i] = fill;
+        // Unchecked assignment equivalent to `result[i] = fill`;
+        // `fill` is checked statically at call site.
+        JS('', '#[#] = #', result, i, fill);
       }
     }
     return result;
@@ -483,8 +486,12 @@
   @patch
   factory String.fromCharCodes(Iterable<int> charCodes,
       [int start = 0, int? end]) {
-    if (charCodes is JSArray<int>) {
-      return _stringFromJSArray(charCodes as JSArray<int>, start, end);
+    if (charCodes is JSArray) {
+      // Type promotion doesn't work unless the check is `is JSArray<int>`,
+      // which is more expensive.
+      // TODO(41383): Optimize `is JSArray<int>` rather than do weird 'casts'.
+      JSArray array = JS('JSArray', '#', charCodes);
+      return _stringFromJSArray(array, start, end);
     }
     if (charCodes is NativeUint8List) {
       return _stringFromUint8List(charCodes, start, end);
@@ -497,12 +504,11 @@
     return Primitives.stringFromCharCode(charCode);
   }
 
-  static String _stringFromJSArray(
-      JSArray<int> list, int start, int? endOrNull) {
+  static String _stringFromJSArray(JSArray list, int start, int? endOrNull) {
     int len = list.length;
     int end = RangeError.checkValidRange(start, endOrNull, len);
     if (start > 0 || end < len) {
-      list = list.sublist(start, end) as JSArray<int>;
+      list = JS('JSArray', '#.slice(#, #)', list, start, end);
     }
     return Primitives.stringFromCharCodes(list);
   }
@@ -633,7 +639,7 @@
     return string;
   }
 
-  static String _writeOne(String string, Object obj) {
+  static String _writeOne(String string, Object? obj) {
     return Primitives.stringConcatUnchecked(string, '$obj');
   }
 }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
index 808be98..fc97282 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
@@ -184,7 +184,10 @@
 }
 
 // A JS String or Symbol.
-final JS_INTEROP_INTERCEPTOR_TAG = getIsolateAffinityTag(r'_$dart_js');
+dynamic _JS_INTEROP_INTERCEPTOR_TAG = null;
+get JS_INTEROP_INTERCEPTOR_TAG {
+  return _JS_INTEROP_INTERCEPTOR_TAG ??= getIsolateAffinityTag(r'_$dart_js');
+}
 
 lookupInterceptorByConstructor(constructor) {
   return constructor == null
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
index 8483315..e2922ca 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
@@ -10,6 +10,13 @@
 import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
 
 @patch
+@pragma('dart2js:tryInline')
+bool typeAcceptsNull<T>() {
+  bool isLegacySubtyping = JS_GET_FLAG('LEGACY');
+  return isLegacySubtyping || null is T;
+}
+
+@patch
 class Symbol implements core.Symbol {
   @patch
   const Symbol(String name) : this._name = name;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
index da7ebc7..ab539ed 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
@@ -425,6 +425,11 @@
       InternetAddress address, String host) {
     throw new UnsupportedError("InternetAddress._cloneWithNewHost");
   }
+
+  @patch
+  static InternetAddress? tryParse(String address) {
+    throw UnsupportedError("InternetAddress.tryParse");
+  }
 }
 
 @patch
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
index e7e4332..d131658 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
@@ -361,7 +361,7 @@
         throw new ConcurrentModificationError(this);
       }
     }
-    if (matchFound) return match!;
+    if (matchFound) return match as E;
     if (orElse != null) return orElse();
     throw IterableElementError.noElement();
   }
@@ -428,8 +428,8 @@
     List<E> otherList;
     int otherStart;
     // TODO(floitsch): Make this accept more.
-    if (iterable is List<E>) {
-      otherList = iterable;
+    if (iterable is List) {
+      otherList = JS<List<E>>('', '#', iterable);
       otherStart = skipCount;
     } else {
       otherList = iterable.skip(skipCount).toList(growable: false);
@@ -527,7 +527,7 @@
   }
 
   static int _compareAny(a, b) {
-    return Comparable.compare(a as Comparable, b as Comparable);
+    return Comparable.compare(a, b);
   }
 
   void shuffle([Random? random]) {
@@ -559,15 +559,15 @@
     return -1;
   }
 
-  int lastIndexOf(Object? element, [int? _startIndex]) {
-    int startIndex = _startIndex ?? this.length - 1;
-    if (startIndex < 0) {
+  int lastIndexOf(Object? element, [int? startIndex]) {
+    int start = startIndex ?? this.length - 1;
+    if (start < 0) {
       return -1;
     }
-    if (startIndex >= this.length) {
-      startIndex = this.length - 1;
+    if (start >= this.length) {
+      start = this.length - 1;
     }
-    for (int i = startIndex; i >= 0; i--) {
+    for (int i = start; i >= 0; i--) {
       if (this[i] == element) {
         return i;
       }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
index 0aaa85c..aeca848 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -414,14 +414,13 @@
     int digitsIndex = 1;
     int hexIndex = 2;
     int decimalIndex = 3;
-    int nonDecimalHexIndex = 4;
     if (match == null) {
       // TODO(sra): It might be that the match failed due to unrecognized U+0085
       // spaces.  We could replace them with U+0020 spaces and try matching
       // again.
       return null;
     }
-    String decimalMatch = match[decimalIndex];
+    Object? decimalMatch = match[decimalIndex];
     if (radix == null) {
       if (decimalMatch != null) {
         // Cannot fail because we know that the digits are all decimal.
@@ -661,7 +660,6 @@
     if (timerFrequency != 0) return;
     // Start with low-resolution. We overwrite the fields if we find better.
     timerFrequency = 1000;
-    timerTicks = dateNow;
     if (JS('bool', 'typeof window == "undefined"')) return;
     var window = JS('var', 'window');
     if (window == null) return;
@@ -673,7 +671,7 @@
   }
 
   static int timerFrequency = 0;
-  static late int Function() timerTicks;
+  static int Function() timerTicks = dateNow; // Low-resolution version.
 
   static String? currentUri() {
     requiresPreamble();
@@ -1191,7 +1189,11 @@
       List keys = JS('JSArray', r'Object.keys(#)', defaultValues);
       if (namedArguments == null) {
         for (String key in keys) {
-          arguments.add(JS('var', '#[#]', defaultValues, key));
+          var defaultValue = JS('var', '#[#]', defaultValues, key);
+          if (isRequired(defaultValue)) {
+            return functionNoSuchMethod(function, arguments, namedArguments);
+          }
+          arguments.add(defaultValue);
         }
       } else {
         int used = 0;
@@ -1200,7 +1202,11 @@
             used++;
             arguments.add(namedArguments[key]);
           } else {
-            arguments.add(JS('var', r'#[#]', defaultValues, key));
+            var defaultValue = JS('var', '#[#]', defaultValues, key);
+            if (isRequired(defaultValue)) {
+              return functionNoSuchMethod(function, arguments, namedArguments);
+            }
+            arguments.add(defaultValue);
           }
         }
         if (used != namedArguments.length) {
@@ -3552,3 +3558,12 @@
 String testingGetPlatformEnvironmentVariable() {
   return testPlatformEnvironmentVariableValue;
 }
+
+// These are used to indicate that a named parameter is required when lazily
+// retrieving default values via [JsGetName.DEFAULT_VALUES_PROPERTY].
+class _Required {
+  const _Required();
+}
+
+const kRequiredSentinel = const _Required();
+bool isRequired(Object? value) => identical(kRequiredSentinel, value);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
index f79a5d3..70882d8 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -97,12 +97,12 @@
     if (_isStringKey(key)) {
       var strings = _strings;
       if (strings == null) return null;
-      LinkedHashMapCell cell = _getTableCell(strings, key);
+      LinkedHashMapCell? cell = _getTableCell(strings, key);
       return JS('', '#', cell == null ? null : cell.hashMapCellValue);
     } else if (_isNumericKey(key)) {
       var nums = _nums;
       if (nums == null) return null;
-      LinkedHashMapCell cell = _getTableCell(nums, key);
+      LinkedHashMapCell? cell = _getTableCell(nums, key);
       return JS('', '#', cell == null ? null : cell.hashMapCellValue);
     } else {
       return internalGet(key);
@@ -221,7 +221,7 @@
 
   V? _removeHashTableEntry(var table, Object? key) {
     if (table == null) return null;
-    LinkedHashMapCell cell = _getTableCell(table, key);
+    LinkedHashMapCell? cell = _getTableCell(table, key);
     if (cell == null) return null;
     _unlinkCell(cell);
     _deleteTableEntry(table, key);
@@ -289,7 +289,7 @@
     return JS('int', '# & 0x3ffffff', key.hashCode);
   }
 
-  List<LinkedHashMapCell> _getBucket(var table, var key) {
+  List<LinkedHashMapCell>? _getBucket(var table, var key) {
     var hash = internalComputeHashCode(key);
     return _getTableBucket(table, hash);
   }
@@ -306,11 +306,11 @@
 
   String toString() => MapBase.mapToString(this);
 
-  LinkedHashMapCell _getTableCell(var table, var key) {
+  LinkedHashMapCell? _getTableCell(var table, var key) {
     return JS('var', '#[#]', table, key);
   }
 
-  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
+  List<LinkedHashMapCell>? _getTableBucket(var table, var key) {
     return JS('var', '#[#]', table, key);
   }
 
@@ -324,7 +324,7 @@
   }
 
   bool _containsTableEntry(var table, var key) {
-    LinkedHashMapCell cell = _getTableCell(table, key);
+    LinkedHashMapCell? cell = _getTableCell(table, key);
     return cell != null;
   }
 
@@ -344,12 +344,12 @@
 
 class Es6LinkedHashMap<K, V> extends JsLinkedHashMap<K, V> {
   @override
-  LinkedHashMapCell _getTableCell(var table, var key) {
+  LinkedHashMapCell? _getTableCell(var table, var key) {
     return JS('var', '#.get(#)', table, key);
   }
 
   @override
-  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
+  List<LinkedHashMapCell>? _getTableBucket(var table, var key) {
     return JS('var', '#.get(#)', table, key);
   }
 
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
index 4cbeed7..f5f40b7 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
@@ -159,8 +159,9 @@
   // [initNativeDispatch].
   var interceptorClass = lookupInterceptor(tag);
   if (interceptorClass == null) {
-    tag = alternateTagFunction!(obj, tag);
-    if (tag != null) {
+    String? altTag = alternateTagFunction!(obj, tag);
+    if (altTag != null) {
+      tag = altTag;
       // Fast path for instance and uncached tags again.
       record = propertyGet(dispatchRecordsForInstanceTags, tag);
       if (record != null) return patchInstance(obj, record);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index 40c6a6f..b29e59c 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -35,6 +35,13 @@
 
 import 'dart:_recipe_syntax';
 
+// The top type `Object?` is used throughout this library even when values are
+// not nullable or have narrower types in order to avoid incurring type checks
+// before the type checking infrastructure has been set up.
+// We could use `dynamic`, but this would allow inadvertent implicit downcasts.
+// TODO(fishythefish, dart-lang/language#115): Replace `Object?` with a typedef
+// when possible.
+
 /// An Rti object represents both a type (e.g `Map<int, String>`) and a type
 /// environment (`Map<int, String>` binds `Map.K=int` and `Map.V=String`).
 ///
@@ -51,36 +58,36 @@
   /// JavaScript method for 'as' check. The method is called from generated code,
   /// e.g. `o as T` generates something like `rtiForT._as(o)`.
   @pragma('dart2js:noElision')
-  dynamic _as;
+  Object? _as;
 
   /// JavaScript method for 'is' test.  The method is called from generated
   /// code, e.g. `o is T` generates something like `rtiForT._is(o)`.
   @pragma('dart2js:noElision')
-  dynamic _is;
+  Object? _is;
 
-  static void _setAsCheckFunction(Rti rti, fn) {
+  static void _setAsCheckFunction(Rti rti, Object? fn) {
     rti._as = fn;
   }
 
-  static void _setIsTestFunction(Rti rti, fn) {
+  static void _setIsTestFunction(Rti rti, Object? fn) {
     rti._is = fn;
   }
 
   @pragma('dart2js:tryInline')
-  static bool _asCheck(Rti rti, object) {
+  static bool _asCheck(Rti rti, Object? object) {
     return JS(
         'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_AS), object);
   }
 
   @pragma('dart2js:tryInline')
-  static bool _isCheck(Rti rti, object) {
+  static bool _isCheck(Rti rti, Object? object) {
     return JS(
         'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_IS), object);
   }
 
   /// Method called from generated code to evaluate a type environment recipe in
   /// `this` type environment.
-  Rti _eval(recipe) {
+  Rti _eval(Object? recipe) {
     // TODO(sra): Clone the fast-path of _Universe.evalInEnvironment to here.
     return _rtiEval(this, _Utils.asString(recipe));
   }
@@ -88,12 +95,12 @@
   /// Method called from generated code to extend `this` type environment (an
   /// interface or binding Rti) with function type arguments (a singleton
   /// argument or tuple of arguments).
-  Rti _bind(typeOrTuple) => _rtiBind(this, _castToRti(typeOrTuple));
+  Rti _bind(Object? typeOrTuple) => _rtiBind(this, _Utils.asRti(typeOrTuple));
 
   /// Method called from generated code to extend `this` type (as a singleton
   /// type environment) with function type arguments (a singleton argument or
   /// tuple of arguments).
-  Rti _bind1(Rti typeOrTuple) => _rtiBind1(this, typeOrTuple);
+  Rti _bind1(Object? typeOrTuple) => _rtiBind1(this, _Utils.asRti(typeOrTuple));
 
   // Precomputed derived types. These fields are used to hold derived types that
   // are computed eagerly.
@@ -105,17 +112,17 @@
   /// If kind == kindStar, holds T? where T is the base type.
   /// - This case is lazily initialized during subtype checks.
   @pragma('dart2js:noElision')
-  dynamic _precomputed1;
+  Object? _precomputed1;
 
   static Object? _getPrecomputed1(Rti rti) => rti._precomputed1;
 
-  static void _setPrecomputed1(Rti rti, precomputed) {
+  static void _setPrecomputed1(Rti rti, Object? precomputed) {
     rti._precomputed1 = precomputed;
   }
 
-  static Rti _getQuestionFromStar(universe, Rti rti) {
+  static Rti _getQuestionFromStar(Object? universe, Rti rti) {
     assert(_getKind(rti) == kindStar);
-    Rti? question = _castToRtiOrNull(_getPrecomputed1(rti));
+    Rti? question = _Utils.asRtiOrNull(_getPrecomputed1(rti));
     if (question == null) {
       question =
           _Universe._lookupQuestionRti(universe, _getStarArgument(rti), true);
@@ -124,9 +131,9 @@
     return question;
   }
 
-  static Rti _getFutureFromFutureOr(universe, Rti rti) {
+  static Rti _getFutureFromFutureOr(Object? universe, Rti rti) {
     assert(_getKind(rti) == kindFutureOr);
-    Rti? future = _castToRtiOrNull(_getPrecomputed1(rti));
+    Rti? future = _Utils.asRtiOrNull(_getPrecomputed1(rti));
     if (future == null) {
       future = _Universe._lookupFutureRti(universe, _getFutureOrArgument(rti));
       Rti._setPrecomputed1(rti, future);
@@ -134,19 +141,19 @@
     return future;
   }
 
-  dynamic _precomputed2;
-  dynamic _precomputed3;
-  dynamic _precomputed4;
+  Object? _precomputed2;
+  Object? _precomputed3;
+  Object? _precomputed4;
 
   // Data value used by some tests.
   @pragma('dart2js:noElision')
   Object? _specializedTestResource;
 
-  static Object _getSpecializedTestResource(Rti rti) {
-    return rti._specializedTestResource!;
+  static Object? _getSpecializedTestResource(Rti rti) {
+    return rti._specializedTestResource;
   }
 
-  static void _setSpecializedTestResource(Rti rti, Object value) {
+  static void _setSpecializedTestResource(Rti rti, Object? value) {
     rti._specializedTestResource = value;
   }
 
@@ -164,7 +171,7 @@
   ///
   /// The zero initializer ensures dart2js type analysis considers [_kind] is
   /// non-nullable.
-  Object /*int*/ _kind = 0;
+  Object? /*int*/ _kind = 0;
 
   static int _getKind(Rti rti) => _Utils.asInt(rti._kind);
   static void _setKind(Rti rti, int kind) {
@@ -172,27 +179,27 @@
   }
 
   // Terminal terms.
-  static const kindNever = 1;
-  static const kindDynamic = 2;
-  static const kindVoid = 3; // TODO(sra): Use `dynamic` instead?
-  static const kindAny = 4; // Dart1-style 'dynamic' for JS-interop.
-  static const kindErased = 5;
+  static const int kindNever = 1;
+  static const int kindDynamic = 2;
+  static const int kindVoid = 3; // TODO(sra): Use `dynamic` instead?
+  static const int kindAny = 4; // Dart1-style 'dynamic' for JS-interop.
+  static const int kindErased = 5;
   // Unary terms.
-  static const kindStar = 6;
-  static const kindQuestion = 7;
-  static const kindFutureOr = 8;
+  static const int kindStar = 6;
+  static const int kindQuestion = 7;
+  static const int kindFutureOr = 8;
   // More complex terms.
-  static const kindInterface = 9;
+  static const int kindInterface = 9;
   // A vector of type parameters from enclosing functions and closures.
-  static const kindBinding = 10;
-  static const kindFunction = 11;
-  static const kindGenericFunction = 12;
-  static const kindGenericFunctionParameter = 13;
+  static const int kindBinding = 10;
+  static const int kindFunction = 11;
+  static const int kindGenericFunction = 12;
+  static const int kindGenericFunctionParameter = 13;
 
   static bool _isUnionOfFunctionType(Rti rti) {
     int kind = Rti._getKind(rti);
     if (kind == kindStar || kind == kindQuestion || kind == kindFutureOr) {
-      return _isUnionOfFunctionType(_castToRti(_getPrimary(rti)));
+      return _isUnionOfFunctionType(_Utils.asRti(_getPrimary(rti)));
     }
     return kind == kindFunction || kind == kindGenericFunction;
   }
@@ -206,10 +213,10 @@
   /// - Return type of a function type.
   /// - Underlying function type for a generic function.
   /// - de Bruijn index for a generic function parameter.
-  dynamic _primary;
+  Object? _primary;
 
-  static Object _getPrimary(Rti rti) => rti._primary;
-  static void _setPrimary(Rti rti, value) {
+  static Object? _getPrimary(Rti rti) => rti._primary;
+  static void _setPrimary(Rti rti, Object? value) {
     rti._primary = value;
   }
 
@@ -220,10 +227,10 @@
   ///   kindBinding.
   /// - The [_FunctionParameters] of a function type.
   /// - The type parameter bounds of a generic function.
-  dynamic _rest;
+  Object? _rest;
 
-  static Object _getRest(Rti rti) => rti._rest;
-  static void _setRest(Rti rti, value) {
+  static Object? _getRest(Rti rti) => rti._rest;
+  static void _setRest(Rti rti, Object? value) {
     rti._rest = value;
   }
 
@@ -241,7 +248,7 @@
 
   static Rti _getBindingBase(Rti rti) {
     assert(_getKind(rti) == kindBinding);
-    return _castToRti(_getPrimary(rti));
+    return _Utils.asRti(_getPrimary(rti));
   }
 
   static JSArray _getBindingArguments(Rti rti) {
@@ -251,22 +258,22 @@
 
   static Rti _getStarArgument(Rti rti) {
     assert(_getKind(rti) == kindStar);
-    return _castToRti(_getPrimary(rti));
+    return _Utils.asRti(_getPrimary(rti));
   }
 
   static Rti _getQuestionArgument(Rti rti) {
     assert(_getKind(rti) == kindQuestion);
-    return _castToRti(_getPrimary(rti));
+    return _Utils.asRti(_getPrimary(rti));
   }
 
   static Rti _getFutureOrArgument(Rti rti) {
     assert(_getKind(rti) == kindFutureOr);
-    return _castToRti(_getPrimary(rti));
+    return _Utils.asRti(_getPrimary(rti));
   }
 
   static Rti _getReturnType(Rti rti) {
     assert(_getKind(rti) == kindFunction);
-    return _castToRti(_getPrimary(rti));
+    return _Utils.asRti(_getPrimary(rti));
   }
 
   static _FunctionParameters _getFunctionParameters(Rti rti) {
@@ -276,7 +283,7 @@
 
   static Rti _getGenericFunctionBase(Rti rti) {
     assert(_getKind(rti) == kindGenericFunction);
-    return _castToRti(_getPrimary(rti));
+    return _Utils.asRti(_getPrimary(rti));
   }
 
   static JSArray _getGenericFunctionBounds(Rti rti) {
@@ -301,7 +308,7 @@
   Object? _evalCache;
 
   static Object? _getEvalCache(Rti rti) => rti._evalCache;
-  static void _setEvalCache(Rti rti, value) {
+  static void _setEvalCache(Rti rti, Object? value) {
     rti._evalCache = value;
   }
 
@@ -321,7 +328,7 @@
   Object? _bindCache;
 
   static Object? _getBindCache(Rti rti) => rti._bindCache;
-  static void _setBindCache(Rti rti, value) {
+  static void _setBindCache(Rti rti, Object? value) {
     rti._bindCache = value;
   }
 
@@ -332,7 +339,7 @@
   Object? _canonicalRecipe;
 
   static String _getCanonicalRecipe(Rti rti) {
-    Object? s = rti._canonicalRecipe;
+    var s = rti._canonicalRecipe;
     assert(_Utils.isString(s), 'Missing canonical recipe');
     return _Utils.asString(s);
   }
@@ -343,15 +350,13 @@
 }
 
 class _FunctionParameters {
-  // TODO(fishythefish): Support required named parameters.
-
   static _FunctionParameters allocate() => _FunctionParameters();
 
   Object? _requiredPositional;
   static JSArray _getRequiredPositional(_FunctionParameters parameters) =>
       JS('JSUnmodifiableArray', '#', parameters._requiredPositional);
   static void _setRequiredPositional(
-      _FunctionParameters parameters, Object requiredPositional) {
+      _FunctionParameters parameters, Object? requiredPositional) {
     parameters._requiredPositional = requiredPositional;
   }
 
@@ -359,29 +364,29 @@
   static JSArray _getOptionalPositional(_FunctionParameters parameters) =>
       JS('JSUnmodifiableArray', '#', parameters._optionalPositional);
   static void _setOptionalPositional(
-      _FunctionParameters parameters, Object optionalPositional) {
+      _FunctionParameters parameters, Object? optionalPositional) {
     parameters._optionalPositional = optionalPositional;
   }
 
-  /// These are alternating name/type pairs; that is, the optional named
-  /// parameters of the function
+  /// These are a sequence of name/bool/type triplets that correspond to named
+  /// parameters.
   ///
-  ///   void foo({int bar, double baz})
+  ///   void foo({int bar, required double baz})
   ///
-  /// would be encoded as ["bar", int, "baz", double], where the even indices are
-  /// the name [String]s and the odd indices are the type [Rti]s.
+  /// would be encoded as ["bar", false, int, "baz", true, double], where each
+  /// triplet consists of the name [String], a bool indicating whether or not
+  /// the parameter is required, and the [Rti].
   ///
-  /// Invariant: These pairs are sorted by name in lexicographically ascending order.
-  Object? _optionalNamed;
-  static JSArray _getOptionalNamed(_FunctionParameters parameters) =>
-      JS('JSUnmodifiableArray', '#', parameters._optionalNamed);
-  static void _setOptionalNamed(
-      _FunctionParameters parameters, Object optionalNamed) {
-    parameters._optionalNamed = optionalNamed;
+  /// Invariant: These groups are sorted by name in lexicographically ascending order.
+  Object? _named;
+  static JSArray _getNamed(_FunctionParameters parameters) =>
+      JS('JSUnmodifiableArray', '#', parameters._named);
+  static void _setNamed(_FunctionParameters parameters, Object? named) {
+    parameters._named = named;
   }
 }
 
-Object _theUniverse() => JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE);
+Object? _theUniverse() => JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE);
 
 Rti _rtiEval(Rti environment, String recipe) {
   return _Universe.evalInEnvironment(_theUniverse(), environment, recipe);
@@ -410,7 +415,7 @@
 }
 
 /// Evaluate a type recipe in the environment of an instance.
-Rti evalInInstance(instance, String recipe) {
+Rti evalInInstance(Object? instance, String recipe) {
   return _rtiEval(instanceType(instance), recipe);
 }
 
@@ -440,7 +445,7 @@
   }
   String key = Rti._getCanonicalRecipe(instantiationRti);
   var probe = _Utils.mapGet(cache, key);
-  if (probe != null) return _castToRti(probe);
+  if (probe != null) return _Utils.asRti(probe);
   Rti rti = _substitute(_theUniverse(),
       Rti._getGenericFunctionBase(genericFunctionRti), typeArguments, 0);
   _Utils.mapSet(cache, key, rti);
@@ -459,7 +464,7 @@
 /// In order to do a partial substitution - that is, substituting only some
 /// type parameters rather than all of them - we encode the unsubstituted
 /// positions of the argument list as `undefined` or `null`.
-Rti _substitute(universe, Rti rti, Object typeArguments, int depth) {
+Rti _substitute(Object? universe, Rti rti, Object? typeArguments, int depth) {
   int kind = Rti._getKind(rti);
   switch (kind) {
     case Rti.kindErased:
@@ -469,26 +474,26 @@
     case Rti.kindAny:
       return rti;
     case Rti.kindStar:
-      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti baseType = _Utils.asRti(Rti._getPrimary(rti));
       Rti substitutedBaseType =
           _substitute(universe, baseType, typeArguments, depth);
       if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti;
       return _Universe._lookupStarRti(universe, substitutedBaseType, true);
     case Rti.kindQuestion:
-      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti baseType = _Utils.asRti(Rti._getPrimary(rti));
       Rti substitutedBaseType =
           _substitute(universe, baseType, typeArguments, depth);
       if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti;
       return _Universe._lookupQuestionRti(universe, substitutedBaseType, true);
     case Rti.kindFutureOr:
-      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti baseType = _Utils.asRti(Rti._getPrimary(rti));
       Rti substitutedBaseType =
           _substitute(universe, baseType, typeArguments, depth);
       if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti;
       return _Universe._lookupFutureOrRti(universe, substitutedBaseType, true);
     case Rti.kindInterface:
-      Object interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti);
-      Object substitutedInterfaceTypeArguments = _substituteArray(
+      var interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti);
+      var substitutedInterfaceTypeArguments = _substituteArray(
           universe, interfaceTypeArguments, typeArguments, depth);
       if (_Utils.isIdentical(
           substitutedInterfaceTypeArguments, interfaceTypeArguments))
@@ -498,8 +503,8 @@
     case Rti.kindBinding:
       Rti base = Rti._getBindingBase(rti);
       Rti substitutedBase = _substitute(universe, base, typeArguments, depth);
-      Object arguments = Rti._getBindingArguments(rti);
-      Object substitutedArguments =
+      var arguments = Rti._getBindingArguments(rti);
+      var substitutedArguments =
           _substituteArray(universe, arguments, typeArguments, depth);
       if (_Utils.isIdentical(substitutedBase, base) &&
           _Utils.isIdentical(substitutedArguments, arguments)) return rti;
@@ -519,9 +524,9 @@
       return _Universe._lookupFunctionRti(
           universe, substitutedReturnType, substitutedFunctionParameters);
     case Rti.kindGenericFunction:
-      Object bounds = Rti._getGenericFunctionBounds(rti);
+      var bounds = Rti._getGenericFunctionBounds(rti);
       depth += _Utils.arrayLength(bounds);
-      Object substitutedBounds =
+      var substitutedBounds =
           _substituteArray(universe, bounds, typeArguments, depth);
       Rti base = Rti._getGenericFunctionBase(rti);
       Rti substitutedBase = _substitute(universe, base, typeArguments, depth);
@@ -540,19 +545,19 @@
       // positions of the argument list as `undefined` (which will compare equal
       // to `null`).
       if (argument == null) return rti;
-      return _castToRti(argument);
+      return _Utils.asRti(argument);
     default:
       throw AssertionError('Attempted to substitute unexpected RTI kind $kind');
   }
 }
 
-Object _substituteArray(
-    universe, Object rtiArray, Object typeArguments, int depth) {
+Object? _substituteArray(
+    Object? universe, Object? rtiArray, Object? typeArguments, int depth) {
   bool changed = false;
   int length = _Utils.arrayLength(rtiArray);
-  Object result = JS('', '[]');
+  Object? result = JS('', '[]');
   for (int i = 0; i < length; i++) {
-    Rti rti = _castToRti(_Utils.arrayAt(rtiArray, i));
+    Rti rti = _Utils.asRti(_Utils.arrayAt(rtiArray, i));
     Rti substitutedRti = _substitute(universe, rti, typeArguments, depth);
     if (_Utils.isNotIdentical(substitutedRti, rti)) {
       changed = true;
@@ -562,70 +567,69 @@
   return changed ? result : rtiArray;
 }
 
-Object _substituteNamed(
-    universe, Object namedArray, Object typeArguments, int depth) {
+Object? _substituteNamed(
+    Object? universe, Object? namedArray, Object? typeArguments, int depth) {
   bool changed = false;
   int length = _Utils.arrayLength(namedArray);
-  assert(length.isEven);
-  Object result = JS('', '[]');
-  for (int i = 0; i < length; i += 2) {
+  assert(length % 3 == 0);
+  Object? result = JS('', '[]');
+  for (int i = 0; i < length; i += 3) {
     String name = _Utils.asString(_Utils.arrayAt(namedArray, i));
-    Rti rti = _castToRti(_Utils.arrayAt(namedArray, i + 1));
+    bool isRequired = _Utils.asBool(_Utils.arrayAt(namedArray, i + 1));
+    Rti rti = _Utils.asRti(_Utils.arrayAt(namedArray, i + 2));
     Rti substitutedRti = _substitute(universe, rti, typeArguments, depth);
     if (_Utils.isNotIdentical(substitutedRti, rti)) {
       changed = true;
     }
     _Utils.arrayPush(result, name);
+    _Utils.arrayPush(result, isRequired);
     _Utils.arrayPush(result, substitutedRti);
   }
   return changed ? result : namedArray;
 }
 
-// TODO(fishythefish): Support required named parameters.
-_FunctionParameters _substituteFunctionParameters(universe,
-    _FunctionParameters functionParameters, Object typeArguments, int depth) {
-  Object requiredPositional =
+_FunctionParameters _substituteFunctionParameters(Object? universe,
+    _FunctionParameters functionParameters, Object? typeArguments, int depth) {
+  var requiredPositional =
       _FunctionParameters._getRequiredPositional(functionParameters);
-  Object substitutedRequiredPositional =
+  var substitutedRequiredPositional =
       _substituteArray(universe, requiredPositional, typeArguments, depth);
-  Object optionalPositional =
+  var optionalPositional =
       _FunctionParameters._getOptionalPositional(functionParameters);
-  Object substitutedOptionalPositional =
+  var substitutedOptionalPositional =
       _substituteArray(universe, optionalPositional, typeArguments, depth);
-  Object optionalNamed =
-      _FunctionParameters._getOptionalNamed(functionParameters);
-  Object substitutedOptionalNamed =
-      _substituteNamed(universe, optionalNamed, typeArguments, depth);
+  var named = _FunctionParameters._getNamed(functionParameters);
+  var substitutedNamed =
+      _substituteNamed(universe, named, typeArguments, depth);
   if (_Utils.isIdentical(substitutedRequiredPositional, requiredPositional) &&
       _Utils.isIdentical(substitutedOptionalPositional, optionalPositional) &&
-      _Utils.isIdentical(substitutedOptionalNamed, optionalNamed))
-    return functionParameters;
+      _Utils.isIdentical(substitutedNamed, named)) return functionParameters;
   _FunctionParameters result = _FunctionParameters.allocate();
   _FunctionParameters._setRequiredPositional(
       result, substitutedRequiredPositional);
   _FunctionParameters._setOptionalPositional(
       result, substitutedOptionalPositional);
-  _FunctionParameters._setOptionalNamed(result, substitutedOptionalNamed);
+  _FunctionParameters._setNamed(result, substitutedNamed);
   return result;
 }
 
-bool _isDartObject(object) => _Utils.instanceOf(object,
+bool _isDartObject(Object? object) => _Utils.instanceOf(object,
     JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor));
 
-bool _isClosure(object) => _Utils.instanceOf(object,
+bool _isClosure(Object? object) => _Utils.instanceOf(object,
     JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor));
 
 /// Returns the structural function [Rti] of [closure], or `null`.
 /// [closure] must be a subclass of [Closure].
 /// Called from generated code.
-Rti? closureFunctionType(closure) {
+Rti? closureFunctionType(Object? closure) {
   var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
   var signature = JS('', '#[#]', closure, signatureName);
   if (signature != null) {
     if (JS('bool', 'typeof # == "number"', signature)) {
       return getTypeFromTypesTable(_Utils.asInt(signature));
     }
-    return _castToRti(JS('', '#[#]()', closure, signatureName));
+    return _Utils.asRti(JS('', '#[#]()', closure, signatureName));
   }
   return null;
 }
@@ -635,7 +639,7 @@
 /// [testRti] to choose the appropriate type.
 ///
 /// Called from generated code.
-Rti instanceOrFunctionType(object, Rti testRti) {
+Rti instanceOrFunctionType(Object? object, Rti testRti) {
   if (Rti._isUnionOfFunctionType(testRti)) {
     if (_isClosure(object)) {
       // If [testRti] is e.g. `FutureOr<Action>` (where `Action` is some
@@ -651,7 +655,7 @@
 /// Returns the Rti type of [object].
 /// This is the general entry for obtaining the interface type of any value.
 /// Called from generated code.
-Rti instanceType(object) {
+Rti instanceType(Object? object) {
   // TODO(sra): Add interceptor-based specializations of this method. Inject a
   // _getRti method into (Dart)Object, JSArray, and Interceptor. Then calls to
   // this method can be generated as `getInterceptor(o)._getRti(o)`, allowing
@@ -674,7 +678,7 @@
 
 /// Returns the Rti type of JavaScript Array [object].
 /// Called from generated code.
-Rti _arrayInstanceType(object) {
+Rti _arrayInstanceType(Object? object) {
   // A JavaScript Array can come from three places:
   //   1. This Dart program.
   //   2. Another Dart program loaded in the JavaScript environment.
@@ -695,40 +699,40 @@
   var defaultRti = getJSArrayInteropRti();
 
   // Case 3.
-  if (rti == null) return _castToRti(defaultRti);
+  if (rti == null) return _Utils.asRti(defaultRti);
 
   // Case 2 and perhaps case 3. Check constructor of extracted type against a
   // known instance of Rti - this is an easy way to get the constructor.
   if (JS('bool', '#.constructor !== #.constructor', rti, defaultRti)) {
-    return _castToRti(defaultRti);
+    return _Utils.asRti(defaultRti);
   }
 
   // Case 1.
-  return _castToRti(rti);
+  return _Utils.asRti(rti);
 }
 
 /// Returns the Rti type of user-defined class [object].
 /// [object] must not be an intercepted class or a closure.
 /// Called from generated code.
-Rti _instanceType(object) {
+Rti _instanceType(Object? object) {
   var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
-  return rti != null ? _castToRti(rti) : _instanceTypeFromConstructor(object);
+  return rti != null ? _Utils.asRti(rti) : _instanceTypeFromConstructor(object);
 }
 
-String instanceTypeName(object) {
+String instanceTypeName(Object? object) {
   Rti rti = instanceType(object);
   return _rtiToString(rti, null);
 }
 
-Rti _instanceTypeFromConstructor(instance) {
+Rti _instanceTypeFromConstructor(Object? instance) {
   var constructor = JS('', '#.constructor', instance);
   var probe = JS('', r'#[#]', constructor, CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME);
-  if (probe != null) return _castToRti(probe);
+  if (probe != null) return _Utils.asRti(probe);
   return _instanceTypeFromConstructorMiss(instance, constructor);
 }
 
 @pragma('dart2js:noInline')
-Rti _instanceTypeFromConstructorMiss(instance, constructor) {
+Rti _instanceTypeFromConstructorMiss(Object? instance, Object? constructor) {
   // Subclasses of Closure are synthetic classes. The synthetic classes all
   // extend a 'normal' class (Closure, BoundClosure, StaticClosure), so make
   // them appear to be the superclass. Instantiations have a `$ti` field so
@@ -750,13 +754,12 @@
 
 /// Returns the structural function type of [object], or `null` if the object is
 /// not a closure.
-Rti? _instanceFunctionType(object) =>
+Rti? _instanceFunctionType(Object? object) =>
     _isClosure(object) ? closureFunctionType(object) : null;
 
 /// Returns Rti from types table. The types table is initialized with recipe
 /// strings.
-Rti getTypeFromTypesTable(/*int*/ _index) {
-  int index = _Utils.asInt(_index);
+Rti getTypeFromTypesTable(int index) {
   var table = JS_EMBEDDED_GLOBAL('', TYPES);
   var type = _Utils.arrayAt(table, index);
   if (_Utils.isString(type)) {
@@ -764,10 +767,10 @@
     _Utils.arraySetAt(table, index, rti);
     return rti;
   }
-  return _castToRti(type);
+  return _Utils.asRti(type);
 }
 
-Type getRuntimeType(object) {
+Type getRuntimeType(Object? object) {
   Rti rti = _instanceFunctionType(object) ?? instanceType(object);
   return createRuntimeType(rti);
 }
@@ -821,10 +824,10 @@
 // (e.g. we lower a check to a direct helper), and (2) `bool` does not flow to a
 // tested type parameter. The trick will be to ensure that `H._isBool` is
 // generated.
-bool _installSpecializedIsTest(object) {
+bool _installSpecializedIsTest(Object? object) {
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
 
   if (isObjectType(testRti)) {
     return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isObject));
@@ -871,7 +874,7 @@
 }
 
 @pragma('dart2js:noInline') // Slightly smaller code.
-bool _finishIsFn(Rti testRti, object, isFn) {
+bool _finishIsFn(Rti testRti, Object? object, Object? isFn) {
   Rti._setIsTestFunction(testRti, isFn);
   return Rti._isCheck(testRti, object);
 }
@@ -896,10 +899,10 @@
 ///
 /// The first time this default `_as` method is called, it replaces itself with
 /// a specialized version.
-bool _installSpecializedAsCheck(object) {
+bool _installSpecializedAsCheck(Object? object) {
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
 
   var asFn = RAW_DART_FUNCTION_REF(_generalAsCheckImplementation);
   if (isTopType(testRti)) {
@@ -925,10 +928,10 @@
 }
 
 /// Called from generated code.
-bool _generalIsTestImplementation(object) {
+bool _generalIsTestImplementation(Object? object) {
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
   if (JS_GET_FLAG('NNBD') && object == null) {
     return _nullIs(testRti);
   }
@@ -942,20 +945,20 @@
 /// single-step specialization).
 ///
 /// Called from generated code.
-bool _generalNullableIsTestImplementation(object) {
+bool _generalNullableIsTestImplementation(Object? object) {
   if (object == null) return true;
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
   Rti baseRti = Rti._getQuestionArgument(testRti);
   return Rti._isCheck(baseRti, object);
 }
 
 /// Called from generated code.
-bool _isTestViaProperty(object) {
+bool _isTestViaProperty(Object? object) {
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
   if (JS_GET_FLAG('NNBD') && object == null) {
     return _nullIs(testRti);
   }
@@ -974,10 +977,10 @@
 
 /// General unspecialized 'as' check that works for any type.
 /// Called from generated code.
-_generalAsCheckImplementation(object) {
+Object? _generalAsCheckImplementation(Object? object) {
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
   if (object == null) {
     if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
   } else {
@@ -988,16 +991,16 @@
 
 /// General 'as' check for types that accept `null`.
 /// Called from generated code.
-_generalNullableAsCheckImplementation(object) {
+Object? _generalNullableAsCheckImplementation(Object? object) {
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
-  Rti testRti = _castToRti(JS('', 'this'));
+  Rti testRti = _Utils.asRti(JS('', 'this'));
   if (object == null) return object;
   if (Rti._isCheck(testRti, object)) return object;
   _failedAsCheck(object, testRti);
 }
 
-void _failedAsCheck(object, Rti testRti) {
+void _failedAsCheck(Object? object, Rti testRti) {
   Rti objectRti = instanceOrFunctionType(object, testRti);
   String message =
       _Error.compose(object, objectRti, _rtiToString(testRti, null));
@@ -1005,11 +1008,11 @@
 }
 
 /// Called from generated code.
-checkTypeBound(Rti type, Rti bound, variable, methodName) {
+Rti checkTypeBound(Rti type, Rti bound, String variable, String methodName) {
   if (isSubtype(_theUniverse(), type, bound)) return type;
   String message = "The type argument '${_rtiToString(type, null)}' is not"
       " a subtype of the type variable bound '${_rtiToString(bound, null)}'"
-      " of type variable '${_Utils.asString(variable)}' in '$methodName'.";
+      " of type variable '$variable' in '$methodName'.";
   throw _TypeError.fromMessage(message);
 }
 
@@ -1018,7 +1021,8 @@
   final String _message;
   _Error(this._message);
 
-  static String compose(object, objectRti, checkedTypeDescription) {
+  static String compose(
+      Object? object, Rti? objectRti, String checkedTypeDescription) {
     String objectDescription = Error.safeToString(object);
     objectRti ??= instanceType(object);
     String objectTypeDescription = _rtiToString(objectRti, null);
@@ -1049,99 +1053,176 @@
 
 /// Specialization for 'is Object'.
 /// Called from generated code via Rti `_is` method.
-bool _isObject(object) {
+bool _isObject(Object? object) {
   return !JS_GET_FLAG('NNBD') || object != null;
 }
 
 /// Specialization for 'as Object'.
 /// Called from generated code via Rti `_as` method.
-dynamic _asObject(object) {
+Object? _asObject(Object? object) {
   if (JS_GET_FLAG('LEGACY') || object != null) return object;
   throw _TypeError.forType(object, 'Object');
 }
 
 /// Specialization for 'is dynamic' and other top types.
 /// Called from generated code via Rti `_is` method.
-bool _isTop(object) {
+bool _isTop(Object? object) {
   return true;
 }
 
 /// Specialization for 'as dynamic' and other top types.
 /// Called from generated code via Rti `_as` methods.
-dynamic _asTop(object) {
+Object? _asTop(Object? object) {
   return object;
 }
 
 /// Specialization for 'is bool'.
 /// Called from generated code.
-bool _isBool(object) {
+bool _isBool(Object? object) {
   return true == object || false == object;
 }
 
-/// Specialization for 'as bool?'.
+// TODO(fishythefish): Change `dynamic` to `Object?` below once promotion works.
+
+/// Specialization for 'as bool'.
 /// Called from generated code.
-bool? _asBoolNullable(object) {
+bool _asBool(Object? object) {
+  if (_isBool(object)) return _Utils.asBool(object);
+  throw _TypeError.forType(object, 'bool');
+}
+
+/// Specialization for 'as bool*'.
+/// Called from generated code.
+bool? _asBoolS(dynamic object) {
   if (_isBool(object)) return _Utils.asBool(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'bool');
 }
 
-/// Specialization for 'as double?'.
+/// Specialization for 'as bool?'.
 /// Called from generated code.
-double? _asDoubleNullable(object) {
+bool? _asBoolQ(dynamic object) {
+  if (_isBool(object)) return _Utils.asBool(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'bool?');
+}
+
+/// Specialization for 'as double'.
+/// Called from generated code.
+double _asDouble(Object? object) {
+  if (_isNum(object)) return _Utils.asDouble(object);
+  throw _TypeError.forType(object, 'double');
+}
+
+/// Specialization for 'as double*'.
+/// Called from generated code.
+double? _asDoubleS(dynamic object) {
   if (_isNum(object)) return _Utils.asDouble(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'double');
 }
 
+/// Specialization for 'as double?'.
+/// Called from generated code.
+double? _asDoubleQ(dynamic object) {
+  if (_isNum(object)) return _Utils.asDouble(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'double?');
+}
+
 /// Specialization for 'is int'.
 /// Called from generated code.
-bool _isInt(object) {
+bool _isInt(Object? object) {
   return JS('bool', 'typeof # == "number"', object) &&
       JS('bool', 'Math.floor(#) === #', object, object);
 }
 
-/// Specialization for 'as int?'.
+/// Specialization for 'as int'.
 /// Called from generated code.
-int? _asIntNullable(object) {
+int _asInt(Object? object) {
+  if (_isInt(object)) return _Utils.asInt(object);
+  throw _TypeError.forType(object, 'int');
+}
+
+/// Specialization for 'as int*'.
+/// Called from generated code.
+int? _asIntS(dynamic object) {
   if (_isInt(object)) return _Utils.asInt(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'int');
 }
 
+/// Specialization for 'as int?'.
+/// Called from generated code.
+int? _asIntQ(dynamic object) {
+  if (_isInt(object)) return _Utils.asInt(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'int?');
+}
+
 /// Specialization for 'is num' and 'is double'.
 /// Called from generated code.
-bool _isNum(object) {
+bool _isNum(Object? object) {
   return JS('bool', 'typeof # == "number"', object);
 }
 
-/// Specialization for 'as num?'.
+/// Specialization for 'as num'.
 /// Called from generated code.
-num? _asNumNullable(object) {
+num _asNum(Object? object) {
+  if (_isNum(object)) return _Utils.asNum(object);
+  throw _TypeError.forType(object, 'num');
+}
+
+/// Specialization for 'as num*'.
+/// Called from generated code.
+num? _asNumS(dynamic object) {
   if (_isNum(object)) return _Utils.asNum(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'num');
 }
 
+/// Specialization for 'as num?'.
+/// Called from generated code.
+num? _asNumQ(dynamic object) {
+  if (_isNum(object)) return _Utils.asNum(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'num?');
+}
+
 /// Specialization for 'is String'.
 /// Called from generated code.
-bool _isString(object) {
+bool _isString(Object? object) {
   return JS('bool', 'typeof # == "string"', object);
 }
 
-/// Specialization for 'as String?'.
+/// Specialization for 'as String'.
 /// Called from generated code.
-String? _asStringNullable(object) {
+String _asString(Object? object) {
+  if (_isString(object)) return _Utils.asString(object);
+  throw _TypeError.forType(object, 'String');
+}
+
+/// Specialization for 'as String*'.
+/// Called from generated code.
+String? _asStringS(dynamic object) {
   if (_isString(object)) return _Utils.asString(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'String');
 }
 
-String _rtiArrayToString(Object array, List<String>? genericContext) {
+/// Specialization for 'as String?'.
+/// Called from generated code.
+String? _asStringQ(dynamic object) {
+  if (_isString(object)) return _Utils.asString(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'String?');
+}
+
+String _rtiArrayToString(Object? array, List<String>? genericContext) {
   String s = '', sep = '';
   for (int i = 0; i < _Utils.arrayLength(array); i++) {
     s += sep +
-        _rtiToString(_castToRti(_Utils.arrayAt(array, i)), genericContext);
+        _rtiToString(_Utils.asRti(_Utils.arrayAt(array, i)), genericContext);
     sep = ', ';
   }
   return s;
@@ -1169,9 +1250,8 @@
     for (int i = 0; i < boundsLength; i++) {
       typeParametersText += typeSep;
       typeParametersText += genericContext[genericContext.length - 1 - i];
-      Rti boundRti = _castToRti(_Utils.arrayAt(bounds, i));
-      if (!isTopType(boundRti) &&
-          (!JS_GET_FLAG('LEGACY') || !isObjectType(boundRti))) {
+      Rti boundRti = _Utils.asRti(_Utils.arrayAt(bounds, i));
+      if (!isTopType(boundRti)) {
         typeParametersText +=
             ' extends ' + _rtiToString(boundRti, genericContext);
       }
@@ -1180,7 +1260,6 @@
     typeParametersText += '>';
   }
 
-  // TODO(fishythefish): Support required named parameters.
   Rti returnType = Rti._getReturnType(functionType);
   _FunctionParameters parameters = Rti._getFunctionParameters(functionType);
   var requiredPositional =
@@ -1189,9 +1268,9 @@
   var optionalPositional =
       _FunctionParameters._getOptionalPositional(parameters);
   int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
-  var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
-  int optionalNamedLength = _Utils.arrayLength(optionalNamed);
-  assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+  var named = _FunctionParameters._getNamed(parameters);
+  int namedLength = _Utils.arrayLength(named);
+  assert(optionalPositionalLength == 0 || namedLength == 0);
 
   String returnTypeText = _rtiToString(returnType, genericContext);
 
@@ -1199,8 +1278,8 @@
   String sep = '';
   for (int i = 0; i < requiredPositionalLength; i++) {
     argumentsText += sep +
-        _rtiToString(
-            _castToRti(_Utils.arrayAt(requiredPositional, i)), genericContext);
+        _rtiToString(_Utils.asRti(_Utils.arrayAt(requiredPositional, i)),
+            genericContext);
     sep = ', ';
   }
 
@@ -1209,22 +1288,25 @@
     sep = '';
     for (int i = 0; i < optionalPositionalLength; i++) {
       argumentsText += sep +
-          _rtiToString(_castToRti(_Utils.arrayAt(optionalPositional, i)),
+          _rtiToString(_Utils.asRti(_Utils.arrayAt(optionalPositional, i)),
               genericContext);
       sep = ', ';
     }
     argumentsText += ']';
   }
 
-  if (optionalNamedLength > 0) {
+  if (namedLength > 0) {
     argumentsText += sep + '{';
     sep = '';
-    for (int i = 0; i < optionalNamedLength; i += 2) {
-      argumentsText += sep +
-          _rtiToString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1)),
-              genericContext) +
+    for (int i = 0; i < namedLength; i += 3) {
+      argumentsText += sep;
+      if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) {
+        argumentsText += 'required ';
+      }
+      argumentsText += _rtiToString(
+              _Utils.asRti(_Utils.arrayAt(named, i + 2)), genericContext) +
           ' ' +
-          _Utils.asString(_Utils.arrayAt(optionalNamed, i));
+          _Utils.asString(_Utils.arrayAt(named, i));
       sep = ', ';
     }
     argumentsText += '}';
@@ -1298,7 +1380,7 @@
 
   if (kind == Rti.kindGenericFunction) {
     Rti baseFunctionType = Rti._getGenericFunctionBase(rti);
-    Object bounds = Rti._getGenericFunctionBounds(rti);
+    var bounds = Rti._getGenericFunctionBounds(rti);
     return _functionRtiToString(baseFunctionType, genericContext,
         bounds: bounds);
   }
@@ -1318,17 +1400,16 @@
   return JS_GET_FLAG('MINIFIED') ? 'minified:$rawClassName' : rawClassName;
 }
 
-String _rtiArrayToDebugString(Object array) {
+String _rtiArrayToDebugString(Object? array) {
   String s = '[', sep = '';
   for (int i = 0; i < _Utils.arrayLength(array); i++) {
-    s += sep + _rtiToDebugString(_castToRti(_Utils.arrayAt(array, i)));
+    s += sep + _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(array, i)));
     sep = ', ';
   }
   return s + ']';
 }
 
 String functionParametersToString(_FunctionParameters parameters) {
-  // TODO(fishythefish): Support required named parameters.
   String s = '(', sep = '';
   var requiredPositional =
       _FunctionParameters._getRequiredPositional(parameters);
@@ -1336,13 +1417,13 @@
   var optionalPositional =
       _FunctionParameters._getOptionalPositional(parameters);
   int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
-  var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
-  int optionalNamedLength = _Utils.arrayLength(optionalNamed);
-  assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+  var named = _FunctionParameters._getNamed(parameters);
+  int namedLength = _Utils.arrayLength(named);
+  assert(optionalPositionalLength == 0 || namedLength == 0);
 
   for (int i = 0; i < requiredPositionalLength; i++) {
     s += sep +
-        _rtiToDebugString(_castToRti(_Utils.arrayAt(requiredPositional, i)));
+        _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(requiredPositional, i)));
     sep = ', ';
   }
 
@@ -1351,20 +1432,24 @@
     sep = '';
     for (int i = 0; i < optionalPositionalLength; i++) {
       s += sep +
-          _rtiToDebugString(_castToRti(_Utils.arrayAt(optionalPositional, i)));
+          _rtiToDebugString(
+              _Utils.asRti(_Utils.arrayAt(optionalPositional, i)));
       sep = ', ';
     }
     s += ']';
   }
 
-  if (optionalNamedLength > 0) {
+  if (namedLength > 0) {
     s += sep + '{';
     sep = '';
-    for (int i = 0; i < optionalNamedLength; i += 2) {
-      s += sep +
-          _rtiToDebugString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1))) +
+    for (int i = 0; i < namedLength; i += 3) {
+      s += sep;
+      if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) {
+        s += 'required ';
+      }
+      s += _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(named, i + 2))) +
           ' ' +
-          _Utils.asString(_Utils.arrayAt(optionalNamed, i));
+          _Utils.asString(_Utils.arrayAt(named, i));
       sep = ', ';
     }
     s += '}';
@@ -1421,7 +1506,7 @@
 
   if (kind == Rti.kindGenericFunction) {
     Rti baseFunctionType = Rti._getGenericFunctionBase(rti);
-    Object bounds = Rti._getGenericFunctionBounds(rti);
+    var bounds = Rti._getGenericFunctionBounds(rti);
     return 'genericFunction(${_rtiToDebugString(baseFunctionType)}, ${_rtiArrayToDebugString(bounds)})';
   }
 
@@ -1466,38 +1551,38 @@
 
   // Field accessors.
 
-  static evalCache(universe) =>
+  static Object evalCache(Object? universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.evalCache);
 
-  static Object typeRules(universe) =>
+  static Object typeRules(Object? universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
 
-  static Object erasedTypes(universe) =>
+  static Object erasedTypes(Object? universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.erasedTypes);
 
-  static Object typeParameterVariances(universe) =>
+  static Object typeParameterVariances(Object? universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.typeParameterVariances);
 
-  static Object? _findRule(universe, String targetType) =>
+  static Object? _findRule(Object? universe, String targetType) =>
       JS('', '#.#', typeRules(universe), targetType);
 
-  static Object? findRule(universe, String targetType) {
-    Object? rule = _findRule(universe, targetType);
+  static Object? findRule(Object? universe, String targetType) {
+    var rule = _findRule(universe, targetType);
     while (_Utils.isString(rule)) {
       rule = _findRule(universe, _Utils.asString(rule));
     }
     return rule;
   }
 
-  static Rti findErasedType(universe, String cls) {
-    Object metadata = erasedTypes(universe);
+  static Rti findErasedType(Object? universe, String cls) {
+    var metadata = erasedTypes(universe);
     var probe = JS('', '#.#', metadata, cls);
     if (probe == null) {
       return eval(universe, cls, false);
     } else if (_Utils.isNum(probe)) {
       int length = _Utils.asInt(probe);
       Rti erased = _lookupErasedRti(universe);
-      Object arguments = JS('', '[]');
+      Object? arguments = JS('', '[]');
       for (int i = 0; i < length; i++) {
         _Utils.arrayPush(arguments, erased);
       }
@@ -1505,58 +1590,58 @@
       JS('', '#.# = #', metadata, cls, interface);
       return interface;
     } else {
-      return _castToRti(probe);
+      return _Utils.asRti(probe);
     }
   }
 
-  static Object? findTypeParameterVariances(universe, String cls) =>
+  static Object? findTypeParameterVariances(Object? universe, String cls) =>
       JS('', '#.#', typeParameterVariances(universe), cls);
 
-  static void addRules(universe, rules) =>
+  static void addRules(Object? universe, Object? rules) =>
       _Utils.objectAssign(typeRules(universe), rules);
 
-  static void addErasedTypes(universe, types) =>
+  static void addErasedTypes(Object? universe, Object? types) =>
       _Utils.objectAssign(erasedTypes(universe), types);
 
-  static void addTypeParameterVariances(universe, variances) =>
+  static void addTypeParameterVariances(Object? universe, Object? variances) =>
       _Utils.objectAssign(typeParameterVariances(universe), variances);
 
-  static Object sharedEmptyArray(universe) =>
+  static JSArray sharedEmptyArray(Object? universe) =>
       JS('JSArray', '#.#', universe, RtiUniverseFieldNames.sharedEmptyArray);
 
   /// Evaluates [recipe] in the global environment.
-  static Rti eval(Object universe, String recipe, bool normalize) {
+  static Rti eval(Object? universe, String recipe, bool normalize) {
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, recipe);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, recipe);
+    if (probe != null) return _Utils.asRti(probe);
     Rti rti = _parseRecipe(universe, null, recipe, normalize);
-    _cacheSet(cache, recipe, rti);
+    _Utils.mapSet(cache, recipe, rti);
     return rti;
   }
 
   static Rti evalInEnvironment(
-      Object universe, Rti environment, String recipe) {
+      Object? universe, Rti environment, String recipe) {
     var cache = Rti._getEvalCache(environment);
     if (cache == null) {
       cache = JS('', 'new Map()');
       Rti._setEvalCache(environment, cache);
     }
-    var probe = _cacheGet(cache, recipe);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, recipe);
+    if (probe != null) return _Utils.asRti(probe);
     Rti rti = _parseRecipe(universe, environment, recipe, true);
-    _cacheSet(cache, recipe, rti);
+    _Utils.mapSet(cache, recipe, rti);
     return rti;
   }
 
-  static Rti bind(Object universe, Rti environment, Rti argumentsRti) {
+  static Rti bind(Object? universe, Rti environment, Rti argumentsRti) {
     var cache = Rti._getBindCache(environment);
     if (cache == null) {
       cache = JS('', 'new Map()');
       Rti._setBindCache(environment, cache);
     }
     String argumentsRecipe = Rti._getCanonicalRecipe(argumentsRti);
-    var probe = _cacheGet(cache, argumentsRecipe);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, argumentsRecipe);
+    if (probe != null) return _Utils.asRti(probe);
     var argumentsArray;
     if (Rti._getKind(argumentsRti) == Rti.kindBinding) {
       argumentsArray = Rti._getBindingArguments(argumentsRti);
@@ -1564,22 +1649,22 @@
       argumentsArray = JS('', '[#]', argumentsRti);
     }
     Rti rti = _lookupBindingRti(universe, environment, argumentsArray);
-    _cacheSet(cache, argumentsRecipe, rti);
+    _Utils.mapSet(cache, argumentsRecipe, rti);
     return rti;
   }
 
-  static Rti bind1(Object universe, Rti environment, Rti argumentsRti) {
+  static Rti bind1(Object? universe, Rti environment, Rti argumentsRti) {
     throw UnimplementedError('_Universe.bind1');
   }
 
-  static Rti evalTypeVariable(Object universe, Rti environment, String name) {
+  static Rti evalTypeVariable(Object? universe, Rti environment, String name) {
     int kind = Rti._getKind(environment);
     if (kind == Rti.kindBinding) {
       environment = Rti._getBindingBase(environment);
     }
 
     String interfaceName = Rti._getInterfaceName(environment);
-    Object? rule = _Universe.findRule(universe, interfaceName);
+    var rule = _Universe.findRule(universe, interfaceName);
     assert(rule != null);
     String? recipe = TypeRule.lookupTypeVariable(rule, name);
     if (recipe == null) {
@@ -1588,20 +1673,14 @@
     return _Universe.evalInEnvironment(universe, environment, recipe);
   }
 
-  static _cacheGet(cache, key) => JS('', '#.get(#)', cache, key);
-  static void _cacheSet(cache, key, value) {
-    JS('', '#.set(#, #)', cache, key, value);
-  }
-
   static Rti _parseRecipe(
-      Object universe, Object? environment, String recipe, bool normalize) {
-    Object parser = _Parser.create(universe, environment, recipe, normalize);
+      Object? universe, Object? environment, String recipe, bool normalize) {
+    var parser = _Parser.create(universe, environment, recipe, normalize);
     Rti rti = _Parser.parse(parser);
-    if (rti != null) return rti;
-    throw UnimplementedError('_Universe._parseRecipe("$recipe")');
+    return rti;
   }
 
-  static Rti _installTypeTests(Object universe, Rti rti) {
+  static Rti _installTypeTests(Object? universe, Rti rti) {
     // Set up methods to perform type tests. The general as-check methods use
     // the is-test method. The is-test method on first use overwrites itself,
     // and possibly the as-check methods, with a specialized version.
@@ -1612,8 +1691,8 @@
     return rti;
   }
 
-  static Rti _installRti(Object universe, String key, Rti rti) {
-    _cacheSet(evalCache(universe), key, rti);
+  static Rti _installRti(Object? universe, String key, Rti rti) {
+    _Utils.mapSet(evalCache(universe), key, rti);
     return rti;
   }
 
@@ -1649,57 +1728,57 @@
   static String _canonicalRecipeOfGenericFunctionParameter(int index) =>
       '$index' + Recipe.genericFunctionTypeParameterIndexString;
 
-  static Rti _lookupErasedRti(universe) {
+  static Rti _lookupErasedRti(Object? universe) {
     return _lookupTerminalRti(
         universe, Rti.kindErased, _canonicalRecipeOfErased());
   }
 
-  static Rti _lookupDynamicRti(universe) {
+  static Rti _lookupDynamicRti(Object? universe) {
     return _lookupTerminalRti(
         universe, Rti.kindDynamic, _canonicalRecipeOfDynamic());
   }
 
-  static Rti _lookupVoidRti(universe) {
+  static Rti _lookupVoidRti(Object? universe) {
     return _lookupTerminalRti(universe, Rti.kindVoid, _canonicalRecipeOfVoid());
   }
 
-  static Rti _lookupNeverRti(universe) {
+  static Rti _lookupNeverRti(Object? universe) {
     return _lookupTerminalRti(
         universe, Rti.kindNever, _canonicalRecipeOfNever());
   }
 
-  static Rti _lookupAnyRti(universe) {
+  static Rti _lookupAnyRti(Object? universe) {
     return _lookupTerminalRti(universe, Rti.kindAny, _canonicalRecipeOfAny());
   }
 
-  static Rti _lookupTerminalRti(universe, int kind, String key) {
+  static Rti _lookupTerminalRti(Object? universe, int kind, String key) {
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(universe, key, _createTerminalRti(universe, kind, key));
   }
 
-  static Rti _createTerminalRti(universe, int kind, String key) {
+  static Rti _createTerminalRti(Object? universe, int kind, String key) {
     Rti rti = Rti.allocate();
     Rti._setKind(rti, kind);
     Rti._setCanonicalRecipe(rti, key);
     return _installTypeTests(universe, rti);
   }
 
-  static Rti _lookupStarRti(universe, Rti baseType, bool normalize) {
+  static Rti _lookupStarRti(Object? universe, Rti baseType, bool normalize) {
     String key = _canonicalRecipeOfStar(baseType);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(
         universe, key, _createStarRti(universe, baseType, key, normalize));
   }
 
   static Rti _createStarRti(
-      universe, Rti baseType, String key, bool normalize) {
+      Object? universe, Rti baseType, String key, bool normalize) {
     if (normalize) {
       int baseKind = Rti._getKind(baseType);
-      if (isTopType(baseType) ||
+      if (isStrongTopType(baseType) ||
           isNullType(baseType) ||
           baseKind == Rti.kindQuestion ||
           baseKind == Rti.kindStar) {
@@ -1713,17 +1792,18 @@
     return _installTypeTests(universe, rti);
   }
 
-  static Rti _lookupQuestionRti(universe, Rti baseType, bool normalize) {
+  static Rti _lookupQuestionRti(
+      Object? universe, Rti baseType, bool normalize) {
     String key = _canonicalRecipeOfQuestion(baseType);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(
         universe, key, _createQuestionRti(universe, baseType, key, normalize));
   }
 
   static Rti _createQuestionRti(
-      universe, Rti baseType, String key, bool normalize) {
+      Object? universe, Rti baseType, String key, bool normalize) {
     if (normalize) {
       int baseKind = Rti._getKind(baseType);
       if (isStrongTopType(baseType) ||
@@ -1753,17 +1833,18 @@
     return _installTypeTests(universe, rti);
   }
 
-  static Rti _lookupFutureOrRti(universe, Rti baseType, bool normalize) {
+  static Rti _lookupFutureOrRti(
+      Object? universe, Rti baseType, bool normalize) {
     String key = _canonicalRecipeOfFutureOr(baseType);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(
         universe, key, _createFutureOrRti(universe, baseType, key, normalize));
   }
 
   static Rti _createFutureOrRti(
-      universe, Rti baseType, String key, bool normalize) {
+      Object? universe, Rti baseType, String key, bool normalize) {
     if (normalize) {
       int baseKind = Rti._getKind(baseType);
       if (isTopType(baseType) || isObjectType(baseType)) {
@@ -1783,17 +1864,17 @@
     return _installTypeTests(universe, rti);
   }
 
-  static Rti _lookupGenericFunctionParameterRti(universe, int index) {
+  static Rti _lookupGenericFunctionParameterRti(Object? universe, int index) {
     String key = _canonicalRecipeOfGenericFunctionParameter(index);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(universe, key,
         _createGenericFunctionParameterRti(universe, index, key));
   }
 
   static Rti _createGenericFunctionParameterRti(
-      universe, int index, String key) {
+      Object? universe, int index, String key) {
     Rti rti = Rti.allocate();
     Rti._setKind(rti, Rti.kindGenericFunctionParameter);
     Rti._setPrimary(rti, index);
@@ -1801,11 +1882,11 @@
     return _installTypeTests(universe, rti);
   }
 
-  static String _canonicalRecipeJoin(Object arguments) {
+  static String _canonicalRecipeJoin(Object? arguments) {
     String s = '', sep = '';
     int length = _Utils.arrayLength(arguments);
     for (int i = 0; i < length; i++) {
-      Rti argument = _castToRti(_Utils.arrayAt(arguments, i));
+      Rti argument = _Utils.asRti(_Utils.arrayAt(arguments, i));
       String subrecipe = Rti._getCanonicalRecipe(argument);
       s += sep + subrecipe;
       sep = Recipe.separatorString;
@@ -1813,21 +1894,26 @@
     return s;
   }
 
-  static String _canonicalRecipeJoinNamed(Object arguments) {
+  static String _canonicalRecipeJoinNamed(Object? arguments) {
     String s = '', sep = '';
     int length = _Utils.arrayLength(arguments);
-    assert(length.isEven);
-    for (int i = 0; i < length; i += 2) {
+    assert(length % 3 == 0);
+    for (int i = 0; i < length; i += 3) {
+      s += sep;
       String name = _Utils.asString(_Utils.arrayAt(arguments, i));
-      Rti type = _castToRti(_Utils.arrayAt(arguments, i + 1));
+      bool isRequired = _Utils.asBool(_Utils.arrayAt(arguments, i + 1));
+      String nameSep = isRequired
+          ? Recipe.requiredNameSeparatorString
+          : Recipe.nameSeparatorString;
+      Rti type = _Utils.asRti(_Utils.arrayAt(arguments, i + 2));
       String subrecipe = Rti._getCanonicalRecipe(type);
-      s += sep + name + Recipe.nameSeparatorString + subrecipe;
+      s += name + nameSep + subrecipe;
       sep = Recipe.separatorString;
     }
     return s;
   }
 
-  static String _canonicalRecipeOfInterface(String name, Object arguments) {
+  static String _canonicalRecipeOfInterface(String name, Object? arguments) {
     assert(_Utils.isString(name));
     String s = _Utils.asString(name);
     int length = _Utils.arrayLength(arguments);
@@ -1840,17 +1926,17 @@
   }
 
   static Rti _lookupInterfaceRti(
-      Object universe, String name, Object arguments) {
+      Object? universe, String name, Object? arguments) {
     String key = _canonicalRecipeOfInterface(name, arguments);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(
         universe, key, _createInterfaceRti(universe, name, arguments, key));
   }
 
   static Rti _createInterfaceRti(
-      Object universe, String name, Object typeArguments, String key) {
+      Object? universe, String name, Object? typeArguments, String key) {
     Rti rti = Rti.allocate();
     Rti._setKind(rti, Rti.kindInterface);
     Rti._setPrimary(rti, name);
@@ -1863,12 +1949,11 @@
     return _installTypeTests(universe, rti);
   }
 
-  static Rti _lookupFutureRti(Object universe, Rti base) => _lookupInterfaceRti(
-      universe,
-      JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME),
-      JS('', '[#]', base));
+  static Rti _lookupFutureRti(Object? universe, Rti base) =>
+      _lookupInterfaceRti(universe,
+          JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME), JS('', '[#]', base));
 
-  static String _canonicalRecipeOfBinding(Rti base, Object arguments) {
+  static String _canonicalRecipeOfBinding(Rti base, Object? arguments) {
     String s = Rti._getCanonicalRecipe(base);
     s += Recipe
         .toTypeString; // TODO(sra): Omit when base encoding is Rti without ToType.
@@ -1879,9 +1964,9 @@
   }
 
   /// [arguments] becomes owned by the created Rti.
-  static Rti _lookupBindingRti(Object universe, Rti base, Object arguments) {
+  static Rti _lookupBindingRti(Object? universe, Rti base, Object? arguments) {
     Rti newBase = base;
-    Object newArguments = arguments;
+    var newArguments = arguments;
     if (Rti._getKind(base) == Rti.kindBinding) {
       newBase = Rti._getBindingBase(base);
       newArguments =
@@ -1889,14 +1974,14 @@
     }
     String key = _canonicalRecipeOfBinding(newBase, newArguments);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(
         universe, key, _createBindingRti(universe, newBase, newArguments, key));
   }
 
   static Rti _createBindingRti(
-      Object universe, Rti base, Object arguments, String key) {
+      Object? universe, Rti base, Object? arguments, String key) {
     Rti rti = Rti.allocate();
     Rti._setKind(rti, Rti.kindBinding);
     Rti._setPrimary(rti, base);
@@ -1910,7 +1995,6 @@
       Rti._getCanonicalRecipe(returnType) +
       _canonicalRecipeOfFunctionParameters(parameters);
 
-  // TODO(fishythefish): Support required named parameters.
   static String _canonicalRecipeOfFunctionParameters(
       _FunctionParameters parameters) {
     var requiredPositional =
@@ -1919,9 +2003,9 @@
     var optionalPositional =
         _FunctionParameters._getOptionalPositional(parameters);
     int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
-    var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
-    int optionalNamedLength = _Utils.arrayLength(optionalNamed);
-    assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+    var named = _FunctionParameters._getNamed(parameters);
+    int namedLength = _Utils.arrayLength(named);
+    assert(optionalPositionalLength == 0 || namedLength == 0);
 
     String recipe = Recipe.startFunctionArgumentsString +
         _canonicalRecipeJoin(requiredPositional);
@@ -1934,11 +2018,11 @@
           Recipe.endOptionalGroupString;
     }
 
-    if (optionalNamedLength > 0) {
+    if (namedLength > 0) {
       String sep = requiredPositionalLength > 0 ? Recipe.separatorString : '';
       recipe += sep +
           Recipe.startNamedGroupString +
-          _canonicalRecipeJoinNamed(optionalNamed) +
+          _canonicalRecipeJoinNamed(named) +
           Recipe.endNamedGroupString;
     }
 
@@ -1946,16 +2030,16 @@
   }
 
   static Rti _lookupFunctionRti(
-      Object universe, Rti returnType, _FunctionParameters parameters) {
+      Object? universe, Rti returnType, _FunctionParameters parameters) {
     String key = _canonicalRecipeOfFunction(returnType, parameters);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(universe, key,
         _createFunctionRti(universe, returnType, parameters, key));
   }
 
-  static Rti _createFunctionRti(Object universe, Rti returnType,
+  static Rti _createFunctionRti(Object? universe, Rti returnType,
       _FunctionParameters parameters, String key) {
     Rti rti = Rti.allocate();
     Rti._setKind(rti, Rti.kindFunction);
@@ -1966,18 +2050,18 @@
   }
 
   static String _canonicalRecipeOfGenericFunction(
-          Rti baseFunctionType, Object bounds) =>
+          Rti baseFunctionType, Object? bounds) =>
       Rti._getCanonicalRecipe(baseFunctionType) +
       Recipe.startTypeArgumentsString +
       _canonicalRecipeJoin(bounds) +
       Recipe.endTypeArgumentsString;
 
   static Rti _lookupGenericFunctionRti(
-      Object universe, Rti baseFunctionType, Object bounds, bool normalize) {
+      Object? universe, Rti baseFunctionType, Object? bounds, bool normalize) {
     String key = _canonicalRecipeOfGenericFunction(baseFunctionType, bounds);
     var cache = evalCache(universe);
-    var probe = _cacheGet(cache, key);
-    if (probe != null) return _castToRti(probe);
+    var probe = _Utils.mapGet(cache, key);
+    if (probe != null) return _Utils.asRti(probe);
     return _installRti(
         universe,
         key,
@@ -1985,14 +2069,14 @@
             universe, baseFunctionType, bounds, key, normalize));
   }
 
-  static Rti _createGenericFunctionRti(Object universe, Rti baseFunctionType,
-      Object bounds, String key, bool normalize) {
+  static Rti _createGenericFunctionRti(Object? universe, Rti baseFunctionType,
+      Object? bounds, String key, bool normalize) {
     if (normalize) {
       int length = _Utils.arrayLength(bounds);
       int count = 0;
-      Object typeArguments = JS('', 'new Array(#)', length);
+      Object? typeArguments = JS('', 'new Array(#)', length);
       for (int i = 0; i < length; i++) {
-        Rti bound = _castToRti(_Utils.arrayAt(bounds, i));
+        Rti bound = _Utils.asRti(_Utils.arrayAt(bounds, i));
         if (Rti._getKind(bound) == Rti.kindNever) {
           _Utils.arraySetAt(typeArguments, i, bound);
           count++;
@@ -2142,7 +2226,7 @@
   /// Marked as no-inline so the object literal is not cloned by inlining.
   @pragma('dart2js:noInline')
   static Object create(
-      Object universe, Object? environment, String recipe, bool normalize) {
+      Object? universe, Object? environment, String recipe, bool normalize) {
     return JS(
         '',
         '{'
@@ -2160,27 +2244,27 @@
   }
 
   // Field accessors for the parser.
-  static Object universe(Object parser) => JS('', '#.u', parser);
-  static Rti environment(Object parser) => JS('Rti', '#.e', parser);
-  static String recipe(Object parser) => JS('String', '#.r', parser);
-  static Object stack(Object parser) => JS('', '#.s', parser);
-  static int position(Object parser) => JS('int', '#.p', parser);
-  static void setPosition(Object parser, int p) {
+  static Object universe(Object? parser) => JS('', '#.u', parser);
+  static Rti environment(Object? parser) => JS('Rti', '#.e', parser);
+  static String recipe(Object? parser) => JS('String', '#.r', parser);
+  static Object stack(Object? parser) => JS('', '#.s', parser);
+  static int position(Object? parser) => JS('int', '#.p', parser);
+  static void setPosition(Object? parser, int p) {
     JS('', '#.p = #', parser, p);
   }
 
-  static bool normalize(Object parser) => JS('bool', '#.n', parser);
+  static bool normalize(Object? parser) => JS('bool', '#.n', parser);
 
   static int charCodeAt(String s, int i) => JS('int', '#.charCodeAt(#)', s, i);
-  static void push(Object stack, Object value) {
+  static void push(Object? stack, Object? value) {
     JS('', '#.push(#)', stack, value);
   }
 
-  static Object pop(Object stack) => JS('', '#.pop()', stack);
+  static Object? pop(Object? stack) => JS('', '#.pop()', stack);
 
-  static Rti parse(Object parser) {
+  static Rti parse(Object? parser) {
     String source = _Parser.recipe(parser);
-    Object stack = _Parser.stack(parser);
+    var stack = _Parser.stack(parser);
     int i = 0;
     while (i < source.length) {
       int ch = charCodeAt(source, i);
@@ -2197,6 +2281,11 @@
             break;
 
           case Recipe.nameSeparator:
+            push(stack, false);
+            break;
+
+          case Recipe.requiredNameSeparator:
+            push(stack, true);
             break;
 
           case Recipe.toType:
@@ -2234,7 +2323,7 @@
             break;
 
           case Recipe.wrapStar:
-            Object u = universe(parser);
+            var u = universe(parser);
             push(
                 stack,
                 _Universe._lookupStarRti(
@@ -2244,7 +2333,7 @@
             break;
 
           case Recipe.wrapQuestion:
-            Object u = universe(parser);
+            var u = universe(parser);
             push(
                 stack,
                 _Universe._lookupQuestionRti(
@@ -2254,7 +2343,7 @@
             break;
 
           case Recipe.wrapFutureOr:
-            Object u = universe(parser);
+            var u = universe(parser);
             push(
                 stack,
                 _Universe._lookupFutureOrRti(
@@ -2292,16 +2381,16 @@
         }
       }
     }
-    Object item = pop(stack);
+    var item = pop(stack);
     return toType(universe(parser), environment(parser), item);
   }
 
-  static void pushStackFrame(Object parser, Object stack) {
+  static void pushStackFrame(Object? parser, Object? stack) {
     push(stack, position(parser));
     setPosition(parser, _Utils.arrayLength(stack));
   }
 
-  static int handleDigit(int i, int digit, String source, Object stack) {
+  static int handleDigit(int i, int digit, String source, Object? stack) {
     int value = Recipe.digitValue(digit);
     for (; i < source.length; i++) {
       int ch = charCodeAt(source, i);
@@ -2313,7 +2402,7 @@
   }
 
   static int handleIdentifier(
-      Object parser, int start, String source, Object stack, bool hasPeriod) {
+      Object? parser, int start, String source, Object? stack, bool hasPeriod) {
     int i = start + 1;
     for (; i < source.length; i++) {
       int ch = charCodeAt(source, i);
@@ -2338,10 +2427,10 @@
     return i;
   }
 
-  static void handleTypeArguments(Object parser, Object stack) {
-    Object universe = _Parser.universe(parser);
-    Object arguments = collectArray(parser, stack);
-    Object head = pop(stack);
+  static void handleTypeArguments(Object? parser, Object? stack) {
+    var universe = _Parser.universe(parser);
+    var arguments = collectArray(parser, stack);
+    var head = pop(stack);
     if (_Utils.isString(head)) {
       String name = _Utils.asString(head);
       push(stack, _Universe._lookupInterfaceRti(universe, name, arguments));
@@ -2363,15 +2452,15 @@
   }
 
   static const int optionalPositionalSentinel = -1;
-  static const int optionalNamedSentinel = -2;
+  static const int namedSentinel = -2;
 
-  static void handleFunctionArguments(Object parser, Object stack) {
-    Object universe = _Parser.universe(parser);
+  static void handleFunctionArguments(Object? parser, Object? stack) {
+    var universe = _Parser.universe(parser);
     _FunctionParameters parameters = _FunctionParameters.allocate();
-    var optionalPositional = _Universe.sharedEmptyArray(universe);
-    var optionalNamed = _Universe.sharedEmptyArray(universe);
+    Object? optionalPositional = _Universe.sharedEmptyArray(universe);
+    Object? named = _Universe.sharedEmptyArray(universe);
 
-    Object head = pop(stack);
+    var head = pop(stack);
     if (_Utils.isNum(head)) {
       int sentinel = _Utils.asInt(head);
       switch (sentinel) {
@@ -2379,8 +2468,8 @@
           optionalPositional = pop(stack);
           break;
 
-        case optionalNamedSentinel:
-          optionalNamed = pop(stack);
+        case namedSentinel:
+          named = pop(stack);
           break;
 
         default:
@@ -2394,25 +2483,25 @@
     _FunctionParameters._setRequiredPositional(
         parameters, collectArray(parser, stack));
     _FunctionParameters._setOptionalPositional(parameters, optionalPositional);
-    _FunctionParameters._setOptionalNamed(parameters, optionalNamed);
+    _FunctionParameters._setNamed(parameters, named);
     Rti returnType = toType(universe, environment(parser), pop(stack));
     push(stack, _Universe._lookupFunctionRti(universe, returnType, parameters));
   }
 
-  static void handleOptionalGroup(Object parser, Object stack) {
-    Object parameters = collectArray(parser, stack);
+  static void handleOptionalGroup(Object? parser, Object? stack) {
+    var parameters = collectArray(parser, stack);
     push(stack, parameters);
     push(stack, optionalPositionalSentinel);
   }
 
-  static void handleNamedGroup(Object parser, Object stack) {
-    Object parameters = collectNamed(parser, stack);
+  static void handleNamedGroup(Object? parser, Object? stack) {
+    var parameters = collectNamed(parser, stack);
     push(stack, parameters);
-    push(stack, optionalNamedSentinel);
+    push(stack, namedSentinel);
   }
 
-  static void handleExtendedOperations(Object parser, Object stack) {
-    Object top = pop(stack);
+  static void handleExtendedOperations(Object? parser, Object? stack) {
+    var top = pop(stack);
     if (0 == top) {
       push(stack, _Universe._lookupNeverRti(universe(parser)));
       return;
@@ -2424,14 +2513,14 @@
     throw AssertionError('Unexpected extended operation $top');
   }
 
-  static Object collectArray(Object parser, Object stack) {
+  static JSArray collectArray(Object? parser, Object? stack) {
     var array = _Utils.arraySplice(stack, position(parser));
     toTypes(_Parser.universe(parser), environment(parser), array);
     setPosition(parser, _Utils.asInt(pop(stack)));
     return array;
   }
 
-  static Object collectNamed(Object parser, Object stack) {
+  static JSArray collectNamed(Object? parser, Object? stack) {
     var array = _Utils.arraySplice(stack, position(parser));
     toTypesNamed(_Parser.universe(parser), environment(parser), array);
     setPosition(parser, _Utils.asInt(pop(stack)));
@@ -2440,7 +2529,7 @@
 
   /// Coerce a stack item into an Rti object. Strings are converted to interface
   /// types, integers are looked up in the type environment.
-  static Rti toType(Object universe, Rti environment, Object item) {
+  static Rti toType(Object? universe, Rti environment, Object? item) {
     if (_Utils.isString(item)) {
       String name = _Utils.asString(item);
       return _Universe._lookupInterfaceRti(
@@ -2448,11 +2537,11 @@
     } else if (_Utils.isNum(item)) {
       return _Parser.indexToType(universe, environment, _Utils.asInt(item));
     } else {
-      return _castToRti(item);
+      return _Utils.asRti(item);
     }
   }
 
-  static void toTypes(Object universe, Rti environment, Object items) {
+  static void toTypes(Object? universe, Rti environment, Object? items) {
     int length = _Utils.arrayLength(items);
     for (int i = 0; i < length; i++) {
       var item = _Utils.arrayAt(items, i);
@@ -2461,24 +2550,24 @@
     }
   }
 
-  static void toTypesNamed(Object universe, Rti environment, Object items) {
+  static void toTypesNamed(Object? universe, Rti environment, Object? items) {
     int length = _Utils.arrayLength(items);
-    assert(length.isEven);
-    for (int i = 1; i < length; i += 2) {
+    assert(length % 3 == 0);
+    for (int i = 2; i < length; i += 3) {
       var item = _Utils.arrayAt(items, i);
       Rti type = toType(universe, environment, item);
       _Utils.arraySetAt(items, i, type);
     }
   }
 
-  static Rti indexToType(Object universe, Rti environment, int index) {
+  static Rti indexToType(Object? universe, Rti environment, int index) {
     int kind = Rti._getKind(environment);
     if (kind == Rti.kindBinding) {
       if (index == 0) return Rti._getBindingBase(environment);
       var typeArguments = Rti._getBindingArguments(environment);
       int len = _Utils.arrayLength(typeArguments);
       if (index <= len) {
-        return _castToRti(_Utils.arrayAt(typeArguments, index - 1));
+        return _Utils.asRti(_Utils.arrayAt(typeArguments, index - 1));
       }
       // Is index into interface Rti in base.
       index -= len;
@@ -2493,12 +2582,12 @@
     var typeArguments = Rti._getInterfaceTypeArguments(environment);
     int len = _Utils.arrayLength(typeArguments);
     if (index <= len) {
-      return _castToRti(_Utils.arrayAt(typeArguments, index - 1));
+      return _Utils.asRti(_Utils.arrayAt(typeArguments, index - 1));
     }
     throw AssertionError('Bad index $index for $environment');
   }
 
-  static Rti toGenericFunctionParameter(Object universe, Object item) {
+  static Rti toGenericFunctionParameter(Object? universe, Object? item) {
     assert(_Utils.isNum(item));
     return _Universe._lookupGenericFunctionParameterRti(
         universe, _Utils.asInt(item));
@@ -2512,26 +2601,26 @@
     throw UnimplementedError("TypeRule is static methods only.");
   }
 
-  static String? lookupTypeVariable(rule, String typeVariable) =>
+  static String? lookupTypeVariable(Object? rule, String typeVariable) =>
       JS('', '#.#', rule, typeVariable);
 
-  static JSArray? lookupSupertype(rule, String supertype) =>
+  static JSArray? lookupSupertype(Object? rule, String supertype) =>
       JS('', '#.#', rule, supertype);
 }
 
 // This needs to be kept in sync with `Variance` in `entities.dart`.
 class Variance {
   // TODO(fishythefish): Try bitmask representation.
-  static const legacyCovariant = 0;
-  static const covariant = 1;
-  static const contravariant = 2;
-  static const invariant = 3;
+  static const int legacyCovariant = 0;
+  static const int covariant = 1;
+  static const int contravariant = 2;
+  static const int invariant = 3;
 }
 
 // -------- Subtype tests ------------------------------------------------------
 
 // Future entry point from compiled code.
-bool isSubtype(universe, Rti s, Rti t) {
+bool isSubtype(Object? universe, Rti s, Rti t) {
   return _isSubtype(universe, s, null, t, null);
 }
 
@@ -2558,7 +2647,7 @@
 /// the bottom of the type hierarchy, `Object` is treated as nullable, and
 /// `required` is ignored on named parameters. This should provide the same
 /// subtyping results as pre-NNBD Dart.
-bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+bool _isSubtype(Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) {
   bool isLegacy = JS_GET_FLAG('LEGACY');
 
   // Reflexivity:
@@ -2574,17 +2663,13 @@
   if (isStrongTopType(s)) return false;
 
   // Left Bottom:
-  if (isLegacy) {
-    if (isNullType(s)) return true;
-  } else {
-    if (sKind == Rti.kindNever) return true;
-  }
+  if (isBottomType(s)) return true;
 
   // Left Type Variable Bound 1:
   bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter;
   if (leftTypeVariable) {
     int index = Rti._getGenericFunctionParameterIndex(s);
-    Rti bound = _castToRti(_Utils.arrayAt(sEnv, index));
+    Rti bound = _Utils.asRti(_Utils.arrayAt(sEnv, index));
     if (_isSubtype(universe, bound, sEnv, t, tEnv)) return true;
   }
 
@@ -2693,8 +2778,8 @@
     tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv);
 
     for (int i = 0; i < sLength; i++) {
-      var sBound = _castToRti(_Utils.arrayAt(sBounds, i));
-      var tBound = _castToRti(_Utils.arrayAt(tBounds, i));
+      var sBound = _Utils.asRti(_Utils.arrayAt(sBounds, i));
+      var tBound = _Utils.asRti(_Utils.arrayAt(tBounds, i));
       if (!_isSubtype(universe, sBound, sEnv, tBound, tEnv) ||
           !_isSubtype(universe, tBound, tEnv, sBound, sEnv)) {
         return false;
@@ -2719,8 +2804,8 @@
   return false;
 }
 
-// TODO(fishythefish): Support required named parameters.
-bool _isFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+bool _isFunctionSubtype(
+    Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) {
   assert(Rti._getKind(s) == Rti.kindFunction);
   assert(Rti._getKind(t) == Rti.kindFunction);
 
@@ -2753,16 +2838,16 @@
       tRequiredPositionalLength + tOptionalPositionalLength) return false;
 
   for (int i = 0; i < sRequiredPositionalLength; i++) {
-    Rti sParameter = _castToRti(_Utils.arrayAt(sRequiredPositional, i));
-    Rti tParameter = _castToRti(_Utils.arrayAt(tRequiredPositional, i));
+    Rti sParameter = _Utils.asRti(_Utils.arrayAt(sRequiredPositional, i));
+    Rti tParameter = _Utils.asRti(_Utils.arrayAt(tRequiredPositional, i));
     if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) {
       return false;
     }
   }
 
   for (int i = 0; i < requiredPositionalDelta; i++) {
-    Rti sParameter = _castToRti(_Utils.arrayAt(sOptionalPositional, i));
-    Rti tParameter = _castToRti(
+    Rti sParameter = _Utils.asRti(_Utils.arrayAt(sOptionalPositional, i));
+    Rti tParameter = _Utils.asRti(
         _Utils.arrayAt(tRequiredPositional, sRequiredPositionalLength + i));
     if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) {
       return false;
@@ -2770,37 +2855,49 @@
   }
 
   for (int i = 0; i < tOptionalPositionalLength; i++) {
-    Rti sParameter = _castToRti(
+    Rti sParameter = _Utils.asRti(
         _Utils.arrayAt(sOptionalPositional, requiredPositionalDelta + i));
-    Rti tParameter = _castToRti(_Utils.arrayAt(tOptionalPositional, i));
+    Rti tParameter = _Utils.asRti(_Utils.arrayAt(tOptionalPositional, i));
     if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) {
       return false;
     }
   }
 
-  var sOptionalNamed = _FunctionParameters._getOptionalNamed(sParameters);
-  var tOptionalNamed = _FunctionParameters._getOptionalNamed(tParameters);
-  int sOptionalNamedLength = _Utils.arrayLength(sOptionalNamed);
-  int tOptionalNamedLength = _Utils.arrayLength(tOptionalNamed);
+  var sNamed = _FunctionParameters._getNamed(sParameters);
+  var tNamed = _FunctionParameters._getNamed(tParameters);
+  int sNamedLength = _Utils.arrayLength(sNamed);
+  int tNamedLength = _Utils.arrayLength(tNamed);
 
-  for (int i = 0, j = 0; j < tOptionalNamedLength; j += 2) {
-    String sName;
-    String tName = _Utils.asString(_Utils.arrayAt(tOptionalNamed, j));
-    do {
-      if (i >= sOptionalNamedLength) return false;
-      sName = _Utils.asString(_Utils.arrayAt(sOptionalNamed, i));
-      i += 2;
-    } while (_Utils.stringLessThan(sName, tName));
-    if (_Utils.stringLessThan(tName, sName)) return false;
-    Rti sType = _castToRti(_Utils.arrayAt(sOptionalNamed, i - 1));
-    Rti tType = _castToRti(_Utils.arrayAt(tOptionalNamed, j + 1));
-    if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false;
+  int sIndex = 0;
+  for (int tIndex = 0; tIndex < tNamedLength; tIndex += 3) {
+    String tName = _Utils.asString(_Utils.arrayAt(tNamed, tIndex));
+    while (true) {
+      if (sIndex >= sNamedLength) return false;
+      String sName = _Utils.asString(_Utils.arrayAt(sNamed, sIndex));
+      sIndex += 3;
+      if (_Utils.stringLessThan(tName, sName)) return false;
+      bool sIsRequired = _Utils.asBool(_Utils.arrayAt(sNamed, sIndex - 2));
+      if (_Utils.stringLessThan(sName, tName)) {
+        if (sIsRequired) return false;
+        continue;
+      }
+      bool tIsRequired = _Utils.asBool(_Utils.arrayAt(tNamed, tIndex + 1));
+      if (sIsRequired && !tIsRequired) return false;
+      Rti sType = _Utils.asRti(_Utils.arrayAt(sNamed, sIndex - 1));
+      Rti tType = _Utils.asRti(_Utils.arrayAt(tNamed, tIndex + 2));
+      if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false;
+      break;
+    }
   }
-
+  while (sIndex < sNamedLength) {
+    if (_Utils.asBool(_Utils.arrayAt(sNamed, sIndex + 1))) return false;
+    sIndex += 3;
+  }
   return true;
 }
 
-bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+bool _isInterfaceSubtype(
+    Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) {
   String sName = Rti._getInterfaceName(s);
   String tName = Rti._getInterfaceName(t);
 
@@ -2816,12 +2913,12 @@
     if (JS_GET_FLAG("VARIANCE")) {
       sVariances = _Universe.findTypeParameterVariances(universe, sName);
       hasVariances = sVariances != null;
-      assert(!hasVariances! || length == _Utils.arrayLength(sVariances));
+      assert(!hasVariances || length == _Utils.arrayLength(sVariances));
     }
 
     for (int i = 0; i < length; i++) {
-      Rti sArg = _castToRti(_Utils.arrayAt(sArgs, i));
-      Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
+      Rti sArg = _Utils.asRti(_Utils.arrayAt(sArgs, i));
+      Rti tArg = _Utils.asRti(_Utils.arrayAt(tArgs, i));
       if (JS_GET_FLAG("VARIANCE")) {
         int sVariance = hasVariances != null
             ? _Utils.asInt(_Utils.arrayAt(sVariances, i))
@@ -2871,7 +2968,7 @@
   // We don't list Object explicitly as a supertype of each interface, so check
   // this trivial case first.
   if (isObjectType(t)) return true;
-  Object? rule = _Universe.findRule(universe, sName);
+  var rule = _Universe.findRule(universe, sName);
   if (rule == null) return false;
   var supertypeArgs = TypeRule.lookupSupertype(rule, tName);
   if (supertypeArgs == null) return false;
@@ -2881,7 +2978,7 @@
   for (int i = 0; i < length; i++) {
     String recipe = _Utils.asString(_Utils.arrayAt(supertypeArgs, i));
     Rti supertypeArg = _Universe.evalInEnvironment(universe, s, recipe);
-    Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
+    Rti tArg = _Utils.asRti(_Utils.arrayAt(tArgs, i));
     if (!_isSubtype(universe, supertypeArg, sEnv, tArg, tEnv)) {
       return false;
     }
@@ -2898,7 +2995,10 @@
       kind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(t));
 }
 
-bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t);
+bool isTopType(Rti t) =>
+    isStrongTopType(t) ||
+    isLegacyObjectType(t) ||
+    JS_GET_FLAG('LEGACY') && isObjectType(t);
 
 bool isStrongTopType(Rti t) {
   int kind = Rti._getKind(t);
@@ -2906,10 +3006,12 @@
       kind == Rti.kindVoid ||
       kind == Rti.kindAny ||
       kind == Rti.kindErased ||
-      !JS_GET_FLAG('NNBD') && isObjectType(t) ||
       isNullableObjectType(t);
 }
 
+bool isBottomType(Rti t) =>
+    Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t);
+
 bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object>());
 bool isLegacyObjectType(Rti t) =>
     _Utils.isIdentical(t, LEGACY_TYPE_REF<Object>());
@@ -2919,30 +3021,29 @@
 bool isJsFunctionType(Rti t) =>
     _Utils.isIdentical(t, TYPE_REF<JavaScriptFunction>());
 
-/// Unchecked cast to Rti.
-Rti _castToRti(s) => JS('Rti', '#', s);
-Rti? _castToRtiOrNull(s) => JS('Rti|Null', '#', s);
-
 class _Utils {
-  static bool asBool(o) => JS('bool', '#', o);
-  static double asDouble(o) => JS('double', '#', o);
-  static int asInt(o) => JS('int', '#', o);
-  static num asNum(o) => JS('num', '#', o);
-  static String asString(o) => JS('String', '#', o);
+  static bool asBool(Object? o) => JS('bool', '#', o);
+  static double asDouble(Object? o) => JS('double', '#', o);
+  static int asInt(Object? o) => JS('int', '#', o);
+  static num asNum(Object? o) => JS('num', '#', o);
+  static String asString(Object? o) => JS('String', '#', o);
+  static Rti asRti(Object? s) => JS('Rti', '#', s);
+  static Rti? asRtiOrNull(Object? s) => JS('Rti|Null', '#', s);
 
-  static bool isString(o) => JS('bool', 'typeof # == "string"', o);
-  static bool isNum(o) => JS('bool', 'typeof # == "number"', o);
+  static bool isString(Object? o) => JS('bool', 'typeof # == "string"', o);
+  static bool isNum(Object? o) => JS('bool', 'typeof # == "number"', o);
 
-  static bool instanceOf(o, Object constructor) =>
+  static bool instanceOf(Object? o, Object? constructor) =>
       JS('bool', '# instanceof #', o, constructor);
 
-  static bool isIdentical(s, t) => JS('bool', '# === #', s, t);
-  static bool isNotIdentical(s, t) => JS('bool', '# !== #', s, t);
+  static bool isIdentical(Object? s, Object? t) => JS('bool', '# === #', s, t);
+  static bool isNotIdentical(Object? s, Object? t) =>
+      JS('bool', '# !== #', s, t);
 
-  static JSArray objectKeys(Object o) =>
+  static JSArray objectKeys(Object? o) =>
       JS('returns:JSArray;new:true;', 'Object.keys(#)', o);
 
-  static void objectAssign(Object o, Object other) {
+  static void objectAssign(Object? o, Object? other) {
     // TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated.
     var keys = objectKeys(other);
     int length = arrayLength(keys);
@@ -2952,26 +3053,26 @@
     }
   }
 
-  static bool isArray(o) => JS('bool', 'Array.isArray(#)', o);
+  static bool isArray(Object? o) => JS('bool', 'Array.isArray(#)', o);
 
-  static int arrayLength(Object array) => JS('int', '#.length', array);
+  static int arrayLength(Object? array) => JS('int', '#.length', array);
 
-  static Object arrayAt(Object array, int i) => JS('', '#[#]', array, i);
+  static Object? arrayAt(Object? array, int i) => JS('', '#[#]', array, i);
 
-  static void arraySetAt(Object array, int i, value) {
+  static void arraySetAt(Object? array, int i, Object? value) {
     JS('', '#[#] = #', array, i, value);
   }
 
-  static JSArray arrayShallowCopy(Object array) =>
+  static JSArray arrayShallowCopy(Object? array) =>
       JS('JSArray', '#.slice()', array);
 
-  static JSArray arraySplice(Object array, int position) =>
+  static JSArray arraySplice(Object? array, int position) =>
       JS('JSArray', '#.splice(#)', array, position);
 
-  static JSArray arrayConcat(Object a1, Object a2) =>
+  static JSArray arrayConcat(Object? a1, Object? a2) =>
       JS('JSArray', '#.concat(#)', a1, a2);
 
-  static void arrayPush(Object array, value) {
+  static void arrayPush(Object? array, Object? value) {
     JS('', '#.push(#)', array, value);
   }
 
@@ -2981,56 +3082,56 @@
   static bool stringLessThan(String s1, String s2) =>
       JS('bool', '# < #', s1, s2);
 
-  static mapGet(cache, key) => JS('', '#.get(#)', cache, key);
+  static Object? mapGet(Object? cache, Object? key) =>
+      JS('', '#.get(#)', cache, key);
 
-  static void mapSet(cache, key, value) {
+  static void mapSet(Object? cache, Object? key, Object? value) {
     JS('', '#.set(#, #)', cache, key, value);
   }
 }
 // -------- Entry points for testing -------------------------------------------
 
-String testingCanonicalRecipe(rti) {
+String testingCanonicalRecipe(Rti rti) {
   return Rti._getCanonicalRecipe(rti);
 }
 
-String testingRtiToString(rti) {
-  return _rtiToString(_castToRti(rti), null);
+String testingRtiToString(Rti rti) {
+  return _rtiToString(rti, null);
 }
 
-String testingRtiToDebugString(rti) {
-  return _rtiToDebugString(_castToRti(rti));
+String testingRtiToDebugString(Rti rti) {
+  return _rtiToDebugString(rti);
 }
 
 Object testingCreateUniverse() {
   return _Universe.create();
 }
 
-void testingAddRules(universe, rules) {
+void testingAddRules(Object? universe, Object? rules) {
   _Universe.addRules(universe, rules);
 }
 
-void testingAddTypeParameterVariances(universe, variances) {
+void testingAddTypeParameterVariances(Object? universe, Object? variances) {
   _Universe.addTypeParameterVariances(universe, variances);
 }
 
-bool testingIsSubtype(universe, rti1, rti2) {
-  return isSubtype(universe, _castToRti(rti1), _castToRti(rti2));
+bool testingIsSubtype(Object? universe, Rti rti1, Rti rti2) {
+  return isSubtype(universe, rti1, rti2);
 }
 
-Object testingUniverseEval(universe, String recipe) {
+Rti testingUniverseEval(Object? universe, String recipe) {
   return _Universe.eval(universe, recipe, true);
 }
 
-void testingUniverseEvalOverride(universe, String recipe, Rti rti) {
+void testingUniverseEvalOverride(Object? universe, String recipe, Rti rti) {
   var cache = _Universe.evalCache(universe);
-  _Universe._cacheSet(cache, recipe, rti);
+  _Utils.mapSet(cache, recipe, rti);
 }
 
-Object testingEnvironmentEval(universe, environment, String recipe) {
-  return _Universe.evalInEnvironment(universe, _castToRti(environment), recipe);
+Rti testingEnvironmentEval(Object? universe, Rti environment, String recipe) {
+  return _Universe.evalInEnvironment(universe, environment, recipe);
 }
 
-Object testingEnvironmentBind(universe, environment, arguments) {
-  return _Universe.bind(
-      universe, _castToRti(environment), _castToRti(arguments));
+Rti testingEnvironmentBind(Object? universe, Rti environment, Rti arguments) {
+  return _Universe.bind(universe, environment, arguments);
 }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index ef7fbff..c183861 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -51,6 +51,8 @@
   static const String endNamedGroupString = _rightBraceString;
   static const int nameSeparator = _colon;
   static const String nameSeparatorString = _colonString;
+  static const int requiredNameSeparator = _exclamation;
+  static const String requiredNameSeparatorString = _exclamationString;
 
   static const int genericFunctionTypeParameterIndex = _circumflex;
   static const String genericFunctionTypeParameterIndexString =
@@ -189,6 +191,8 @@
     test("startNamedGroup", startNamedGroup, startNamedGroupString);
     test("endNamedGroup", endNamedGroup, endNamedGroupString);
     test("nameSeparator", nameSeparator, nameSeparatorString);
+    test("requiredNameSeparator", requiredNameSeparator,
+        requiredNameSeparatorString);
     test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
         genericFunctionTypeParameterIndexString);
     test("extensionOp", extensionOp, extensionOpString);
diff --git a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
index 1befe5a..bc8f8e5 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
@@ -9,6 +9,7 @@
 import 'dart:collection' hide LinkedList, LinkedListEntry;
 import 'dart:_internal' hide Symbol;
 import 'dart:io';
+import 'dart:convert';
 import 'dart:isolate';
 import 'dart:typed_data';
 
@@ -164,7 +165,7 @@
 }
 
 void _requestPackagesMap(Uri? packageConfig) {
-  var msg = null;
+  dynamic msg = null;
   if (packageConfig != null) {
     // Explicitly specified .packages path.
     msg = _handlePackagesRequest(_traceLoading, -2, packageConfig);
@@ -204,281 +205,185 @@
   }
 }
 
-// Handling of packages requests. Finding and parsing of .packages file or
-// packages/ directories.
-const _LF = 0x0A;
-const _CR = 0x0D;
-const _SPACE = 0x20;
-const _HASH = 0x23;
-const _DOT = 0x2E;
-const _COLON = 0x3A;
-const _DEL = 0x7F;
+// The values go from ' ' to DEL and `x` means disallowed.
+const String _invalidPackageNameChars =
+    'x.xx.x.........x..........x.x.xx...........................xxxx.x..........................xxx.x';
 
-const _invalidPackageNameChars = const [
-  true, //  space
-  false, // !
-  true, //  "
-  true, //  #
-  false, // $
-  true, //  %
-  false, // &
-  false, // '
-  false, // (
-  false, // )
-  false, // *
-  false, // +
-  false, // ,
-  false, // -
-  false, // .
-  true, //  /
-  false, // 0
-  false, // 1
-  false, // 2
-  false, // 3
-  false, // 4
-  false, // 5
-  false, // 6
-  false, // 7
-  false, // 8
-  false, // 9
-  true, //  :
-  false, // ;
-  true, //  <
-  false, // =
-  true, //  >
-  true, //  ?
-  false, // @
-  false, // A
-  false, // B
-  false, // C
-  false, // D
-  false, // E
-  false, // F
-  false, // G
-  false, // H
-  false, // I
-  false, // J
-  false, // K
-  false, // L
-  false, // M
-  false, // N
-  false, // O
-  false, // P
-  false, // Q
-  false, // R
-  false, // S
-  false, // T
-  false, // U
-  false, // V
-  false, // W
-  false, // X
-  false, // Y
-  false, // Z
-  true, //  [
-  true, //  \
-  true, //  ]
-  true, //  ^
-  false, // _
-  true, //  `
-  false, // a
-  false, // b
-  false, // c
-  false, // d
-  false, // e
-  false, // f
-  false, // g
-  false, // h
-  false, // i
-  false, // j
-  false, // k
-  false, // l
-  false, // m
-  false, // n
-  false, // o
-  false, // p
-  false, // q
-  false, // r
-  false, // s
-  false, // t
-  false, // u
-  false, // v
-  false, // w
-  false, // x
-  false, // y
-  false, // z
-  true, //  {
-  true, //  |
-  true, //  }
-  false, // ~
-  true, //  DEL
-];
+bool _isValidPackageName(String packageName) {
+  const space = 0x20;
+  const del = 0x7F;
+  const dot = 0x2e;
+  const lowerX = 0x78;
+  for (int i = 0; i < packageName.length; ++i) {
+    final int char = packageName.codeUnitAt(i);
+    if (char < space || del < char) {
+      return false;
+    }
+    final int allowed = _invalidPackageNameChars.codeUnitAt(char - space);
+    assert(allowed == dot || allowed == lowerX);
+    if (allowed == lowerX) {
+      return false;
+    }
+  }
+  return true;
+}
 
-_parsePackagesFile(bool traceLoading, Uri packagesFile, List<int> data) {
+_parsePackagesFile(bool traceLoading, Uri packagesFile, String data) {
   // The first entry contains the location of the identified .packages file
   // instead of a mapping.
-  var result = [packagesFile.toString(), null];
-  var index = 0;
-  var len = data.length;
-  while (index < len) {
-    var start = index;
-    var char = data[index];
-    if ((char == _CR) || (char == _LF)) {
-      // Skipping empty lines.
-      index++;
+  final List result = [packagesFile.toString(), null];
+
+  final lines = LineSplitter.split(data);
+  for (String line in lines) {
+    final hashIndex = line.indexOf('#');
+    if (hashIndex == 0) {
+      continue;
+    }
+    if (hashIndex > 0) {
+      line = line.substring(0, hashIndex);
+    }
+    line = line.trimRight();
+    if (line.isEmpty) {
       continue;
     }
 
-    // Identify split within the line and end of the line.
-    var separator = -1;
-    var end = len;
-    // Verifying validity of package name while scanning the line.
-    var nonDot = false;
-    var invalidPackageName = false;
-
-    // Scan to the end of the line or data.
-    while (index < len) {
-      char = data[index++];
-      // If we have not reached the separator yet, determine whether we are
-      // scanning legal package name characters.
-      if (separator == -1) {
-        if ((char == _COLON)) {
-          // The first colon on a line is the separator between package name and
-          // related URI.
-          separator = index - 1;
-        } else {
-          // Still scanning the package name part. Check for the validity of
-          // the characters.
-          nonDot = nonDot || (char != _DOT);
-          invalidPackageName = invalidPackageName ||
-              (char < _SPACE) ||
-              (char > _DEL) ||
-              _invalidPackageNameChars[char - _SPACE];
-        }
-      }
-      // Identify end of line.
-      if ((char == _CR) || (char == _LF)) {
-        end = index - 1;
-        break;
-      }
+    final colonIndex = line.indexOf(':');
+    if (colonIndex <= 0) {
+      return 'Line in "$packagesFile" should be of the format '
+          '`<package-name>:<path>" but was: "$line"';
+    }
+    final packageName = line.substring(0, colonIndex);
+    if (!_isValidPackageName(packageName)) {
+      return 'Package name in $packagesFile contains disallowed characters ('
+          'was: "$packageName")';
     }
 
-    // No further handling needed for comment lines.
-    if (data[start] == _HASH) {
-      if (traceLoading) {
-        _log("Skipping comment in $packagesFile:\n"
-            "${new String.fromCharCodes(data, start, end)}");
-      }
-      continue;
-    }
-
-    // Check for a badly formatted line, starting with a ':'.
-    if (separator == start) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line starts with ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing package name in $packagesFile:\n"
-          "$line";
-    }
-
-    // Ensure there is a separator on the line.
-    if (separator == -1) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line has no ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing ':' separator in $packagesFile:\n"
-          "$line";
-    }
-
-    var packageName = new String.fromCharCodes(data, start, separator);
-
-    // Check for valid package name.
-    if (invalidPackageName || !nonDot) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Invalid package name $packageName in $packagesFile");
-      }
-      return "Invalid package name '$packageName' in $packagesFile:\n"
-          "$line";
-    }
-
+    String packageUri = line.substring(colonIndex + 1);
     if (traceLoading) {
       _log("packageName: $packageName");
-    }
-    var packageUri = new String.fromCharCodes(data, separator + 1, end);
-    if (traceLoading) {
-      _log("original packageUri: $packageUri");
+      _log("packageUri: $packageUri");
     }
     // Ensure the package uri ends with a /.
-    if (!packageUri.endsWith("/")) {
-      packageUri = "$packageUri/";
+    if (!packageUri.endsWith('/')) {
+      packageUri += '/';
     }
-    packageUri = packagesFile.resolve(packageUri).toString();
+    final resolvedPackageUri = packagesFile.resolve(packageUri).toString();
     if (traceLoading) {
-      _log("mapping: $packageName -> $packageUri");
+      _log("mapping: $packageName -> $resolvedPackageUri");
     }
     result.add(packageName);
-    result.add(packageUri);
+    result.add(resolvedPackageUri);
   }
-
   if (traceLoading) {
     _log("Parsed packages file at $packagesFile. Sending:\n$result");
   }
   return result;
 }
 
-_loadPackagesFile(bool traceLoading, Uri packagesFile) {
-  try {
-    var data = new File.fromUri(packagesFile).readAsBytesSync();
-    if (traceLoading) {
-      _log("Loaded packages file from $packagesFile:\n"
-          "${new String.fromCharCodes(data)}");
-    }
-    return _parsePackagesFile(traceLoading, packagesFile, data);
-  } catch (e, s) {
-    if (traceLoading) {
-      _log("Error loading packages: $e\n$s");
-    }
-    return "Uncaught error ($e) loading packages file.";
+// The .dart_tool/package_config.json format is described in
+//
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+//
+// The returned list has the format:
+//
+//    [0] Location of package_config.json file.
+//    [1] null
+//    [n*2] Name of n-th package
+//    [n*2 + 1] Location of n-th package's sources (as a String)
+//
+List _parsePackageConfig(bool traceLoading, Uri packageConfig, String data) {
+  final Map packageJson = json.decode(data);
+  final version = packageJson['configVersion'];
+  if (version != 2) {
+    throw 'The package configuration file has an unsupported version.';
   }
+  // The first entry contains the location of the identified
+  // .dart_tool/package_config.json file instead of a mapping.
+  final result = <dynamic>[packageConfig.toString(), null];
+  final List packages = packageJson['packages'] ?? [];
+  for (final Map package in packages) {
+    String rootUri = package['rootUri'];
+    if (!rootUri.endsWith('/')) rootUri += '/';
+    final String packageName = package['name'];
+    final String? packageUri = package['packageUri'];
+    final Uri resolvedRootUri = packageConfig.resolve(rootUri);
+    final Uri resolvedPackageUri = packageUri != null
+        ? resolvedRootUri.resolve(packageUri)
+        : resolvedRootUri;
+    if (packageUri != null &&
+        !'$resolvedPackageUri'.contains('$resolvedRootUri')) {
+      throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".';
+    }
+    if (!_isValidPackageName(packageName)) {
+      throw 'Package name in $packageConfig contains disallowed characters ('
+          'was: "$packageName")';
+    }
+    result.add(packageName);
+    result.add(resolvedPackageUri.toString());
+    if (traceLoading) {
+      _log('Resolved package "$packageName" to be at $resolvedPackageUri');
+    }
+  }
+  return result;
 }
 
-_findPackagesFile(bool traceLoading, Uri base) {
+_findPackagesConfiguration(bool traceLoading, Uri base) {
   try {
-    // Walk up the directory hierarchy to check for the existence of
-    // .packages files in parent directories and for the existence of a
-    // packages/ directory on the first iteration.
-    var dir = new File.fromUri(base).parent;
-    var prev = null;
-    // Keep searching until we reach the root.
-    while ((prev == null) || (prev.path != dir.path)) {
-      // Check for the existence of a .packages file and if it exists try to
-      // load and parse it.
-      var dirUri = dir.uri;
-      var packagesFile = dirUri.resolve(".packages");
+    // Walk up the directory hierarchy to check for the existence of either one
+    // of
+    //   - .packages (preferred)
+    //   - .dart_tool/package_config.json
+    var currentDir = new File.fromUri(base).parent;
+    while (true) {
+      final dirUri = currentDir.uri;
+
+      // We prefer using `.packages` over `.dart_tool/package_config.json` so
+      // old users of `Isolate.packageConfig` which cannot handle the new format
+      // will continue to work (see https://github.com/dart-lang/sdk/issues/41748).
+      final packagesFile = dirUri.resolve(".packages");
       if (traceLoading) {
         _log("Checking for $packagesFile file.");
       }
-      var exists = new File.fromUri(packagesFile).existsSync();
+      File file = File.fromUri(packagesFile);
+      bool exists = file.existsSync();
       if (traceLoading) {
         _log("$packagesFile exists: $exists");
       }
       if (exists) {
-        return _loadPackagesFile(traceLoading, packagesFile);
+        final String data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded packages file from $packagesFile:\n$data");
+        }
+        return _parsePackagesFile(traceLoading, packagesFile, data);
       }
-      // Move up one level.
-      prev = dir;
-      dir = dir.parent;
+
+      // We fallback to using `.dart_tool/package_config.json` if it exists.
+      final packageConfig = dirUri.resolve(".dart_tool/package_config.json");
+      if (traceLoading) {
+        _log("Checking for $packageConfig file.");
+      }
+      file = File.fromUri(packageConfig);
+      exists = file.existsSync();
+      if (traceLoading) {
+        _log("$packageConfig exists: $exists");
+      }
+      if (exists) {
+        final data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded package config file from $packageConfig:$data\n");
+        }
+        return _parsePackageConfig(traceLoading, packageConfig, data);
+      }
+
+      final parentDir = currentDir.parent;
+      if (dirUri == parentDir.uri) break;
+      currentDir = parentDir;
     }
 
-    // No .packages file was found.
     if (traceLoading) {
-      _log("Could not resolve a package location from $base");
+      _log("Could not resolve a package configuration from $base");
     }
-    return "Could not resolve a package location for base at $base";
+    return "Could not resolve a package configuration for base at $base";
   } catch (e, s) {
     if (traceLoading) {
       _log("Error loading packages: $e\n$s");
@@ -487,29 +392,62 @@
   }
 }
 
-_loadPackagesData(traceLoading, resource) {
-  try {
-    var data = resource.data;
-    var mime = data.mimeType;
-    if (mime != "text/plain") {
-      throw "MIME-type must be text/plain: $mime given.";
+int _indexOfFirstNonWhitespaceCharacter(String data) {
+  // Whitespace characters ignored in JSON spec:
+  // https://tools.ietf.org/html/rfc7159
+  const tab = 0x09;
+  const lf = 0x0A;
+  const cr = 0x0D;
+  const space = 0x20;
+
+  int index = 0;
+  while (index < data.length) {
+    final int char = data.codeUnitAt(index);
+    if (char != lf && char != cr && char != space && char != tab) {
+      break;
     }
-    var charset = data.charset;
-    if ((charset != "utf-8") && (charset != "US-ASCII")) {
-      // The C++ portion of the embedder assumes UTF-8.
-      throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
-    }
-    return _parsePackagesFile(traceLoading, resource, data.contentAsBytes());
-  } catch (e) {
-    return "Uncaught error ($e) loading packages data.";
+    index++;
   }
+  return index;
+}
+
+bool _canBeValidJson(String data) {
+  const int openCurly = 0x7B;
+  final int index = _indexOfFirstNonWhitespaceCharacter(data);
+  return index < data.length && data.codeUnitAt(index) == openCurly;
+}
+
+_parsePackageConfiguration(bool traceLoading, Uri resource, Uint8List bytes) {
+  try {
+    final data = utf8.decode(bytes);
+    if (_canBeValidJson(data)) {
+      return _parsePackageConfig(traceLoading, resource, data);
+    } else {
+      return _parsePackagesFile(traceLoading, resource, data);
+    }
+  } catch (e) {
+    return "The resource '$resource' is neither a valid '.packages' file nor "
+        "a valid '.dart_tool/package_config.json' file.";
+  }
+}
+
+bool _isValidUtf8DataUrl(UriData data) {
+  final mime = data.mimeType;
+  if (mime != "text/plain") {
+    return false;
+  }
+  final charset = data.charset;
+  if (charset != "utf-8" && charset != "US-ASCII") {
+    return false;
+  }
+  return true;
 }
 
 _handlePackagesRequest(bool traceLoading, int tag, Uri resource) {
   try {
     if (tag == -1) {
       if (resource.scheme == '' || resource.scheme == 'file') {
-        return _findPackagesFile(traceLoading, resource);
+        return _findPackagesConfiguration(traceLoading, resource);
       } else {
         return "Unsupported scheme used to locate .packages file:'$resource'.";
       }
@@ -517,19 +455,25 @@
       if (traceLoading) {
         _log("Handling load of packages map: '$resource'.");
       }
+      late Uint8List bytes;
       if (resource.scheme == '' || resource.scheme == 'file') {
-        var exists = new File.fromUri(resource).existsSync();
-        if (exists) {
-          return _loadPackagesFile(traceLoading, resource);
-        } else {
-          return "Packages file '$resource' not found.";
+        final file = File.fromUri(resource);
+        if (!file.existsSync()) {
+          return "Packages file '$resource' does not exit.";
         }
+        bytes = file.readAsBytesSync();
       } else if (resource.scheme == 'data') {
-        return _loadPackagesData(traceLoading, resource);
+        final uriData = resource.data!;
+        if (!_isValidUtf8DataUrl(uriData)) {
+          return "The data resource '$resource' must have a 'text/plain' mime "
+              "type and a 'utf-8' or 'US-ASCII' charset.";
+        }
+        bytes = uriData.contentAsBytes();
       } else {
         return "Unknown scheme (${resource.scheme}) for package file at "
             "'$resource'.";
       }
+      return _parsePackageConfiguration(traceLoading, resource, bytes);
     } else {
       return "Unknown packages request tag: $tag for '$resource'.";
     }
@@ -580,6 +524,9 @@
 }
 
 // Embedder Entrypoint:
+// The embedder calls this method with the value of the --packages command line
+// option. It can point to a ".packages" or a ".dart_tool/package_config.json"
+// file.
 @pragma("vm:entry-point")
 String _setPackagesMap(String packagesParam) {
   if (!_setupCompleted) {
@@ -641,7 +588,7 @@
   VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
 }
 
-Future<Uri> _getPackageConfigFuture() {
+Future<Uri?> _getPackageConfigFuture() {
   if (_traceLoading) {
     _log("Request for package config from user code.");
   }
@@ -671,7 +618,7 @@
     resolvedUri = _resolvePackageUri(packageUri);
   } catch (e, s) {
     if (_traceLoading) {
-      _log("Exception when resolving package URI: $packageUri");
+      _log("Exception when resolving package URI: $packageUri:\n$e\n$s");
     }
     resolvedUri = null;
   }
diff --git a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
index 1bcd089..02a9df7 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
@@ -7,7 +7,7 @@
 /// patches of that library. We plan to change this when we have a shared front
 /// end and simply use parts.
 
-import "dart:_internal" show VMLibraryHooks, patch;
+import "dart:_internal" show VMLibraryHooks, patch, checkNotNullable;
 
 import "dart:async"
     show
diff --git a/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart
index 2bcf5a9..06898f4 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart
@@ -7,7 +7,7 @@
 class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter {
   void process(List<int> data, int start, int end) native "Filter_Process";
 
-  List<int> processed({bool flush: true, bool end: false})
+  List<int>? processed({bool flush: true, bool end: false})
       native "Filter_Processed";
 }
 
diff --git a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
index 467bdc6..16e866c 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
@@ -328,6 +328,9 @@
   }
 
   String _windowsArgumentEscape(String argument) {
+    if (argument.isEmpty) {
+      return '""';
+    }
     var result = argument;
     if (argument.contains('\t') ||
         argument.contains(' ') ||
diff --git a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
index 69cc88a..9a0586d 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
@@ -104,7 +104,7 @@
 
   int processBuffer(int bufferIndex) => throw new UnimplementedError();
 
-  String selectedProtocol() native "SecureSocket_GetSelectedProtocol";
+  String? selectedProtocol() native "SecureSocket_GetSelectedProtocol";
 
   void renegotiate(bool useSessionCache, bool requestClientCertificate,
       bool requireClientCertificate) native "SecureSocket_Renegotiate";
diff --git a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
index 8ef06ed..94072d8 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
@@ -89,6 +89,11 @@
       InternetAddress address, String host) {
     return (address as _InternetAddress)._cloneWithNewHost(host);
   }
+
+  @patch
+  static InternetAddress? tryParse(String address) {
+    return _InternetAddress.tryParse(address);
+  }
 }
 
 @patch
@@ -255,6 +260,16 @@
     }
   }
 
+  static _InternetAddress? tryParse(String address) {
+    checkNotNullable(address, "address");
+    var addressBytes = _parse(address);
+    if (addressBytes == null) return null;
+    var type = addressBytes.length == _IPv4AddrLength
+        ? InternetAddressType.IPv4
+        : InternetAddressType.IPv6;
+    return _InternetAddress(type, address, null, addressBytes);
+  }
+
   factory _InternetAddress.fixed(int id) {
     switch (id) {
       case _addressLoopbackIPv4:
@@ -1446,7 +1461,7 @@
         controller.add(_RawSocket(socket));
         if (controller.isPaused) return;
       }
-    }), error: zone.bindBinaryCallbackGuarded((Object e, StackTrace st) {
+    }), error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) {
       controller.addError(e, st);
       controller.close();
     }), destroyed: () {
@@ -1560,7 +1575,7 @@
           _controller.add(RawSocketEvent.closed);
           _controller.close();
         },
-        error: zone.bindBinaryCallbackGuarded((Object e, StackTrace st) {
+        error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) {
           _controller.addError(e, st);
           _socket.close();
         }));
@@ -2113,7 +2128,7 @@
           _controller.add(RawSocketEvent.closed);
           _controller.close();
         },
-        error: zone.bindBinaryCallbackGuarded((Object e, StackTrace st) {
+        error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) {
           _controller.addError(e, st);
           _socket.close();
         }));
@@ -2187,9 +2202,9 @@
   void set multicastHops(int value) =>
       _socket.setOption(SocketOption._ipMulticastHops, value);
 
-  NetworkInterface get multicastInterface => throw "Not implemented";
+  NetworkInterface get multicastInterface => throw UnimplementedError();
   void set multicastInterface(NetworkInterface? value) =>
-      throw "Not implemented";
+      throw UnimplementedError();
 
   bool get broadcastEnabled => _socket.getOption(SocketOption._ipBroadcast);
   void set broadcastEnabled(bool value) =>
diff --git a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
index e2ced70..f602449 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
@@ -206,7 +206,7 @@
     if (end == start) {
       return 0;
     }
-    var result = _nativeReadInto(buffer, start, end! - start);
+    var result = _nativeReadInto(buffer, start, end - start);
     if (result is OSError) {
       throw new SocketException("readIntoSync failed", osError: result);
     }
@@ -297,7 +297,7 @@
       return;
     }
     _BufferAndStart bufferAndStart =
-        _ensureFastAndSerializableByteData(buffer, start, end!);
+        _ensureFastAndSerializableByteData(buffer, start, end);
     var result = _nativeWrite(bufferAndStart.buffer, bufferAndStart.start,
         end - (start - bufferAndStart.start));
     if (result is OSError) {
diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart
index 2dc17b1..aea026b 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart
@@ -196,6 +196,11 @@
   return _server.serverAddress;
 }
 
+void webServerAcceptNewWebSocketConnections(bool enable) {
+  final _server = _lazyServerBoot();
+  _server.acceptNewWebSocketConnections = enable;
+}
+
 void _clearFuture(_) {
   serverFuture = null;
 }
@@ -241,6 +246,8 @@
   VMServiceEmbedderHooks.listFiles = listFilesCallback;
   VMServiceEmbedderHooks.serverInformation = serverInformationCallback;
   VMServiceEmbedderHooks.webServerControl = webServerControlCallback;
+  VMServiceEmbedderHooks.acceptNewWebSocketConnections =
+      webServerAcceptNewWebSocketConnections;
   // Always instantiate the vmservice object so that the exit message
   // can be delivered and waiting loaders can be cancelled.
   VMService();
diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
index ed723fb..d1a5a7c 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
@@ -153,6 +153,7 @@
   final String? _serviceInfoFilename;
   HttpServer? _server;
   bool get running => _server != null;
+  bool acceptNewWebSocketConnections = true;
   int _port = -1;
 
   /// Returns the server address including the auth token.
@@ -354,11 +355,19 @@
 
     final String path = result;
     if (path == WEBSOCKET_PATH) {
-      WebSocketTransformer.upgrade(request,
-              compression: CompressionOptions.compressionOff)
-          .then((WebSocket webSocket) {
-        WebSocketClient(webSocket, _service);
-      });
+      if (acceptNewWebSocketConnections) {
+        WebSocketTransformer.upgrade(request,
+                compression: CompressionOptions.compressionOff)
+            .then((WebSocket webSocket) {
+          WebSocketClient(webSocket, _service);
+        });
+      } else {
+        request.response.statusCode = HttpStatus.forbidden;
+        request.response.write('Cannot connect directly to the VM service as '
+            'a Dart Development Service (DDS) instance has taken control and '
+            'can be found at ${_service.ddsUri}.');
+        request.response.close();
+      }
       return;
     }
 
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array.dart b/sdk_nnbd/lib/_internal/vm/lib/array.dart
index 1922173..5304841 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/array.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/array.dart
@@ -6,8 +6,8 @@
 
 @pragma("vm:entry-point")
 class _List<E> extends FixedLengthListBase<E> {
-  @pragma(
-      "vm:exact-result-type", [_List, "result-type-uses-passed-type-arguments"])
+  @pragma("vm:exact-result-type",
+      <dynamic>[_List, "result-type-uses-passed-type-arguments"])
   @pragma("vm:prefer-inline")
   factory _List(length) native "List_allocate";
 
diff --git a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
index a03c772..c3201d3 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
@@ -28,9 +28,15 @@
 
   @pragma("vm:entry-point")
   void complete([FutureOr<T>? value]) {
-    if (!isSync || value is Future<T>) {
-      _future._asyncComplete(value as FutureOr<T>);
+    // All paths require that if value is null, null as T succeeds.
+    value = (value == null) ? value as T : value;
+    if (!isSync) {
+      _future._asyncComplete(value);
+    } else if (value is Future<T>) {
+      assert(!_future._isComplete);
+      _future._chainFuture(value);
     } else {
+      // TODO(40014): Remove cast when type promotion works.
       _future._completeWithValue(value as T);
     }
   }
@@ -45,7 +51,7 @@
   }
 
   @pragma("vm:entry-point")
-  void start(f) {
+  void start(void Function() f) {
     f();
     isSync = true;
   }
@@ -56,8 +62,8 @@
 
 // We need to pass the value as first argument and leave the second and third
 // arguments empty (used for error handling).
-// See vm/ast_transformer.cc for usage.
-Function _asyncThenWrapperHelper(continuation) {
+dynamic Function(dynamic) _asyncThenWrapperHelper(
+    dynamic Function(dynamic) continuation) {
   // Any function that is used as an asynchronous callback must be registered
   // in the current Zone. Normally, this is done by the future when a
   // callback is registered (for example with `.then` or `.catchError`). In our
@@ -74,16 +80,18 @@
   // `Future` implementation could potentially invoke the callback with the
   // wrong number of arguments.
   if (Zone.current == Zone.root) return continuation;
-  return Zone.current.registerUnaryCallback(continuation);
+  return Zone.current.registerUnaryCallback<dynamic, dynamic>(continuation);
 }
 
 // We need to pass the exception and stack trace objects as second and third
-// parameter to the continuation.  See vm/ast_transformer.cc for usage.
-Function _asyncErrorWrapperHelper(continuation) {
+// parameter to the continuation.
+dynamic Function(Object, StackTrace) _asyncErrorWrapperHelper(
+    dynamic Function(dynamic, dynamic, StackTrace) continuation) {
   // See comments of `_asyncThenWrapperHelper`.
-  void errorCallback(Object e, StackTrace s) => continuation(null, e, s);
+  dynamic errorCallback(Object e, StackTrace s) => continuation(null, e, s);
   if (Zone.current == Zone.root) return errorCallback;
-  return Zone.current.registerBinaryCallback(errorCallback);
+  return Zone.current
+      .registerBinaryCallback<dynamic, Object, StackTrace>(errorCallback);
 }
 
 /// Registers the [thenCallback] and [errorCallback] on the given [object].
@@ -91,11 +99,8 @@
 /// If [object] is not a future, then it is wrapped into one.
 ///
 /// Returns the result of registering with `.then`.
-Future _awaitHelper(
-    var object,
-    FutureOr<dynamic> Function(dynamic) thenCallback,
-    Function errorCallback,
-    var awaiter) {
+Future _awaitHelper(var object, dynamic Function(dynamic) thenCallback,
+    dynamic Function(dynamic, StackTrace) errorCallback, Function awaiter) {
   late _Future future;
   if (object is! Future) {
     future = new _Future().._setValue(object);
@@ -113,7 +118,7 @@
   // We can only do this for our internal futures (the default implementation of
   // all futures that are constructed by the `dart:async` library).
   future._awaiter = awaiter;
-  return future._thenAwait(thenCallback, errorCallback);
+  return future._thenAwait<dynamic>(thenCallback, errorCallback);
 }
 
 // Called as part of the 'await for (...)' construct. Registers the
diff --git a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
index dcb8fa1..1307fb7 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
@@ -13,6 +13,10 @@
 
 import "dart:typed_data" show Uint32List;
 
+class _TypeTest<T> {
+  bool test(v) => v is T;
+}
+
 /// These are the additional parts of this patch library:
 // part "compact_hash.dart";
 
@@ -915,35 +919,3 @@
   @patch
   factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet<E>();
 }
-
-@patch
-abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
-  // We override _splayMin and _splayMax to optimize type-checks.
-  @patch
-  Node _splayMin(Node node) {
-    Node current = node;
-    Object? nextLeft = current.left;
-    while (nextLeft != null) {
-      Node left = internal.unsafeCast<Node>(nextLeft);
-      current.left = left.right;
-      left.right = current;
-      current = left;
-      nextLeft = current.left;
-    }
-    return current;
-  }
-
-  @patch
-  Node _splayMax(Node node) {
-    Node current = node;
-    Object? nextRight = current.right;
-    while (nextRight != null) {
-      Node right = internal.unsafeCast<Node>(nextRight);
-      current.right = right.left;
-      right.left = current;
-      current = right;
-      nextRight = current.right;
-    }
-    return current;
-  }
-}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
index 374221c..e4302cc 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
@@ -1498,269 +1498,19 @@
   }
 }
 
-class _Utf8StringBuffer {
-  static const int INITIAL_CAPACITY = 32;
-  // Partial state encoding.
-  static const int MASK_TWO_BIT = 0x03;
-  static const int MASK_SIZE = MASK_TWO_BIT;
-  static const int SHIFT_MISSING = 2;
-  static const int SHIFT_VALUE = 4;
-  static const int NO_PARTIAL = 0;
-
-  // UTF-8 encoding and limits.
-  static const int MAX_ASCII = 127;
-  static const int MAX_TWO_BYTE = 0x7ff;
-  static const int MAX_THREE_BYTE = 0xffff;
-  static const int MAX_UNICODE = 0X10ffff;
-  static const int MASK_TWO_BYTE = 0x1f;
-  static const int MASK_THREE_BYTE = 0x0f;
-  static const int MASK_FOUR_BYTE = 0x07;
-  static const int MASK_CONTINUE_TAG = 0xC0;
-  static const int MASK_CONTINUE_VALUE = 0x3f;
-  static const int CONTINUE_TAG = 0x80;
-
-  // UTF-16 surrogate encoding.
-  static const int LEAD_SURROGATE = 0xD800;
-  static const int TAIL_SURROGATE = 0xDC00;
-  static const int SHIFT_HIGH_SURROGATE = 10;
-  static const int MASK_LOW_SURROGATE = 0x3ff;
-
-  // The internal buffer starts as Uint8List, but may change to Uint16List
-  // if the string contains non-Latin-1 characters.
-  List<int> buffer = new Uint8List(INITIAL_CAPACITY);
-  // Number of elements in buffer.
-  int length = 0;
-  // Partial decoding state, for cases where an UTF-8 sequences is split
-  // between chunks.
-  int partialState = NO_PARTIAL;
-  // Whether all characters so far have been Latin-1 (and the buffer is
-  // still a Uint8List). Set to false when the first non-Latin-1 character
-  // is encountered, and the buffer is then also converted to a Uint16List.
-  bool isLatin1 = true;
-  // If allowing malformed, invalid UTF-8 sequences are converted to
-  // U+FFFD.
-  bool allowMalformed;
-
-  _Utf8StringBuffer(this.allowMalformed);
-
-  /**
-   * Parse the continuation of a multi-byte UTF-8 sequence.
-   *
-   * Parse [utf8] from [position] to [end]. If the sequence extends beyond
-   * `end`, store the partial state in [partialState], and continue from there
-   * on the next added slice.
-   *
-   * The [size] is the number of expected continuation bytes total,
-   * and [missing] is the number of remaining continuation bytes.
-   * The [size] is used to detect overlong encodings.
-   * The [value] is the value collected so far.
-   *
-   * When called after seeing the first multi-byte marker, the [size] and
-   * [missing] values are always the same, but they may differ if continuing
-   * after a partial sequence.
-   */
-  int addContinuation(
-      List<int> utf8, int position, int end, int size, int missing, int value) {
-    int codeEnd = position + missing;
-    do {
-      if (position == end) {
-        missing = codeEnd - position;
-        partialState =
-            size | (missing << SHIFT_MISSING) | (value << SHIFT_VALUE);
-        return end;
-      }
-      int char = utf8[position];
-      if ((char & MASK_CONTINUE_TAG) != CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          return position;
-        }
-        throw new FormatException(
-            "Expected UTF-8 continuation byte, "
-            "found $char",
-            utf8,
-            position);
-      }
-      value = 64 * value + (char & MASK_CONTINUE_VALUE);
-      position++;
-    } while (position < codeEnd);
-    if (value <= const [0, MAX_ASCII, MAX_TWO_BYTE, MAX_THREE_BYTE][size]) {
-      // Over-long encoding.
-      if (allowMalformed) {
-        value = 0xFFFD;
-      } else {
-        throw new FormatException(
-            "Invalid encoding: U+${value.toRadixString(16).padLeft(4, '0')}"
-            " encoded in ${size + 1} bytes.",
-            utf8,
-            position - 1);
-      }
-    }
-    addCharCode(value);
-    return position;
-  }
-
-  void addCharCode(int char) {
-    assert(char >= 0);
-    assert(char <= MAX_UNICODE);
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        throw new FormatException("Incomplete UTF-8 sequence");
-      }
-    }
-    if (isLatin1 && char > 0xff) {
-      _to16Bit(); // Also grows a little if close to full.
-    }
-    int length = this.length;
-    if (char <= MAX_THREE_BYTE) {
-      if (length == buffer.length) _grow();
-      buffer[length] = char;
-      this.length = length + 1;
-      return;
-    }
-    if (length + 2 > buffer.length) _grow();
-    int bits = char - 0x10000;
-    buffer[length] = LEAD_SURROGATE | (bits >> SHIFT_HIGH_SURROGATE);
-    buffer[length + 1] = TAIL_SURROGATE | (bits & MASK_LOW_SURROGATE);
-    this.length = length + 2;
-  }
-
-  void _to16Bit() {
-    assert(isLatin1);
-    Uint16List newBuffer;
-    if ((length + INITIAL_CAPACITY) * 2 <= buffer.length) {
-      // Reuse existing buffer if it's big enough.
-      newBuffer = new Uint16List.view((buffer as Uint8List).buffer);
-    } else {
-      int newCapacity = buffer.length;
-      if (newCapacity - length < INITIAL_CAPACITY) {
-        newCapacity = length + INITIAL_CAPACITY;
-      }
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-    isLatin1 = false;
-  }
-
-  void _grow() {
-    int newCapacity = buffer.length * 2;
-    List<int> newBuffer;
-    if (isLatin1) {
-      newBuffer = new Uint8List(newCapacity);
-    } else {
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-  }
-
-  void addSlice(List<int> utf8, int position, int end) {
-    assert(position < end);
-    if (partialState > 0) {
-      int continueByteCount = (partialState & MASK_TWO_BIT);
-      int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-      int value = partialState >> SHIFT_VALUE;
-      partialState = NO_PARTIAL;
-      position = addContinuation(
-          utf8, position, end, continueByteCount, missing, value);
-      if (position == end) return;
-    }
-    // Keep index and capacity in local variables while looping over
-    // ASCII characters.
-    int index = length;
-    int capacity = buffer.length;
-    while (position < end) {
-      int char = utf8[position];
-      if (char <= MAX_ASCII) {
-        if (index == capacity) {
-          length = index;
-          _grow();
-          capacity = buffer.length;
-        }
-        buffer[index++] = char;
-        position++;
-        continue;
-      }
-      length = index;
-      if ((char & MASK_CONTINUE_TAG) == CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Unexpected UTF-8 continuation byte", utf8, position);
-        }
-      } else if (char < 0xE0) {
-        // C0-DF
-        // Two-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 1, 1, char & MASK_TWO_BYTE);
-      } else if (char < 0xF0) {
-        // E0-EF
-        // Three-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 2, 2, char & MASK_THREE_BYTE);
-      } else if (char < 0xF8) {
-        // F0-F7
-        // Four-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 3, 3, char & MASK_FOUR_BYTE);
-      } else {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Invalid UTF-8 byte: $char", utf8, position);
-        }
-      }
-      index = length;
-      capacity = buffer.length;
-    }
-    length = index;
-  }
-
-  String toString() {
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        int continueByteCount = (partialState & MASK_TWO_BIT);
-        int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-        int value = partialState >> SHIFT_VALUE;
-        int seenByteCount = continueByteCount - missing + 1;
-        List source = new Uint8List(seenByteCount);
-        while (seenByteCount > 1) {
-          seenByteCount--;
-          source[seenByteCount] = CONTINUE_TAG | (value & MASK_CONTINUE_VALUE);
-          value >>= 6;
-        }
-        source[0] = value | (0x3c0 >> (continueByteCount - 1));
-        throw new FormatException(
-            "Incomplete UTF-8 sequence", source, source.length);
-      }
-    }
-    return new String.fromCharCodes(buffer, 0, length);
-  }
-}
-
 /**
  * Chunked JSON parser that parses UTF-8 chunks.
  */
 class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
   static final Uint8List emptyChunk = Uint8List(0);
 
-  final bool allowMalformed;
+  final _Utf8Decoder decoder;
   List<int> chunk = emptyChunk;
   int chunkEnd = 0;
 
-  _JsonUtf8Parser(_JsonListener listener, this.allowMalformed)
-      : super(listener) {
+  _JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
+      : decoder = new _Utf8Decoder(allowMalformed),
+        super(listener) {
     // Starts out checking for an optional BOM (KWD_BOM, count = 0).
     partialState =
         _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
@@ -1780,21 +1530,24 @@
   }
 
   void beginString() {
-    this.buffer = new _Utf8StringBuffer(allowMalformed);
+    decoder.reset();
+    this.buffer = new StringBuffer();
   }
 
   void addSliceToString(int start, int end) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addSlice(chunk, start, end);
+    final StringBuffer buffer = this.buffer;
+    buffer.write(decoder.convertChunked(chunk, start, end));
   }
 
   void addCharToString(int charCode) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addCharCode(charCode);
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
+    buffer.writeCharCode(charCode);
   }
 
   String endString() {
-    _Utf8StringBuffer buffer = this.buffer;
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
     this.buffer = null;
     return buffer.toString();
   }
@@ -1859,24 +1612,424 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
+class _Utf8Decoder {
+  /// Flags indicating presence of the various kinds of bytes in the input.
+  int _scanFlags = 0;
 
-  // Special case for _Uint8ArrayView.
-  if (units is Uint8List) {
-    if (from >= 0 && to >= 0 && to <= units.length) {
-      for (int i = from; i < to; i++) {
-        final unit = units[i];
-        if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
-      }
-      return to - from;
+  /// How many bytes of the BOM have been read so far. Set to -1 when the BOM
+  /// has been skipped (or was not present).
+  int _bomIndex = 0;
+
+  // Table for the scanning phase, which quickly scans through the input.
+  //
+  // Each input byte is looked up in the table, providing a size and some flags.
+  // The sizes are summed, and the flags are or'ed together.
+  //
+  // The resulting size and flags indicate:
+  // A) How many UTF-16 code units will be emitted by the decoding of this
+  //    input. This can be used to allocate a string of the correct length up
+  //    front.
+  // B) Which decoder and resulting string representation is appropriate. There
+  //    are three cases:
+  //    1) Pure ASCII (flags == 0): The input can simply be put into a
+  //       OneByteString without further decoding.
+  //    2) Latin1 (flags == (flagLatin1 | flagExtension)): The result can be
+  //       represented by a OneByteString, and the decoder can assume that only
+  //       Latin1 characters are present.
+  //    3) Arbitrary input (otherwise): Needs a full-featured decoder. Output
+  //       can be represented by a TwoByteString.
+
+  static const int sizeMask = 0x03;
+  static const int flagsMask = 0x3C;
+
+  static const int flagExtension = 1 << 2;
+  static const int flagLatin1 = 1 << 3;
+  static const int flagNonLatin1 = 1 << 4;
+  static const int flagIllegal = 1 << 5;
+
+  // ASCII     'A' = 64 + (1);
+  // Extension 'D' = 64 + (0 | flagExtension);
+  // Latin1    'I' = 64 + (1 | flagLatin1);
+  // BMP       'Q' = 64 + (1 | flagNonLatin1);
+  // Non-BMP   'R' = 64 + (2 | flagNonLatin1);
+  // Illegal   'a' = 64 + (1 | flagIllegal);
+  // Illegal   'b' = 64 + (2 | flagIllegal);
+  static const String scanTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // 80-9F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // A0-BF
+      "aaIIQQQQQQQQQQQQQQQQQQQQQQQQQQQQ" // C0-DF
+      "QQQQQQQQQQQQQQQQRRRRRbbbbbbbbbbb" // E0-FF
+      ;
+
+  /// Reset the decoder to a state where it is ready to decode a new string but
+  /// will not skip a leading BOM. Used by the fused UTF-8 / JSON decoder.
+  void reset() {
+    _state = initial;
+    _bomIndex = -1;
+  }
+
+  // The VM decoder handles BOM explicitly instead of via the state machine.
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = initial;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
     }
+
+    // Skip initial BOM.
+    start = skipBomSingle(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (_state == accept) {
+      return result;
+    }
+
+    if (!allowMalformed) {
+      if (!isErrorState(_state)) {
+        // Unfinished sequence.
+        _state = errorUnfinished;
+        _charOrIndex = end;
+      }
+      final String message = errorDescription(_state);
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = initial;
+    result = decodeGeneral(bytes, start, end, true);
+    assert(!isErrorState(_state));
+    return result;
   }
 
-  // Fall through to normal case.
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    // Skip initial BOM.
+    start = skipBomChunked(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    // Adjust scan flags and size based on carry-over state.
+    switch (_state) {
+      case IA:
+        break;
+      case X1:
+        flags |= _charOrIndex < (0x100 >> 6) ? flagLatin1 : flagNonLatin1;
+        if (end - start >= 1) {
+          size += _charOrIndex < (0x10000 >> 6) ? 1 : 2;
+        }
+        break;
+      case X2:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) {
+          size += _charOrIndex < (0x10000 >> 12) ? 1 : 2;
+        }
+        break;
+      case TO:
+      case TS:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) size += 1;
+        break;
+      case X3:
+      case QO:
+      case QR:
+        flags |= flagNonLatin1;
+        if (end - start >= 3) size += 2;
+        break;
+    }
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(_state == accept);
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    // Do not include any final, incomplete character in size.
+    int extensionCount = 0;
+    int i = end - 1;
+    while (i >= start && (bytes[i] & 0xC0) == 0x80) {
+      extensionCount++;
+      i--;
+    }
+    if (i >= start && bytes[i] >= ((~0x3F >> extensionCount) & 0xFF)) {
+      size -= bytes[i] >= 0xF0 ? 2 : 1;
+    }
+
+    final int carryOverState = _state;
+    final int carryOverChar = _charOrIndex;
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (!isErrorState(_state)) {
+      return result;
+    }
+    assert(_bomIndex == -1);
+
+    if (!allowMalformed) {
+      final String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = carryOverState;
+    _charOrIndex = carryOverChar;
+    result = decodeGeneral(bytes, start, end, false);
+    assert(!isErrorState(_state));
+    return result;
   }
-  return to - from;
+
+  @pragma("vm:prefer-inline")
+  int skipBomSingle(Uint8List bytes, int start, int end) {
+    if (end - start >= 3 &&
+        bytes[start] == 0xEF &&
+        bytes[start + 1] == 0xBB &&
+        bytes[start + 2] == 0xBF) {
+      return start + 3;
+    }
+    return start;
+  }
+
+  @pragma("vm:prefer-inline")
+  int skipBomChunked(Uint8List bytes, int start, int end) {
+    assert(start <= end);
+    int bomIndex = _bomIndex;
+    // Already skipped?
+    if (bomIndex == -1) return start;
+
+    const bomValues = <int>[0xEF, 0xBB, 0xBF];
+    int i = start;
+    while (bomIndex < 3) {
+      if (i == end) {
+        // Unfinished BOM.
+        _bomIndex = bomIndex;
+        return start;
+      }
+      if (bytes[i++] != bomValues[bomIndex++]) {
+        // No BOM.
+        _bomIndex = -1;
+        return start;
+      }
+    }
+    // Complete BOM.
+    _bomIndex = -1;
+    _state = initial;
+    return i;
+  }
+
+  // Scanning functions to compute the size of the resulting string and flags
+  // (written to _scanFlags) indicating which decoder to use.
+  // TODO(dartbug.com/41702): Intrinsify this function.
+  int scan(Uint8List bytes, int start, int end) {
+    _scanFlags = 0;
+    for (int i = start; i < end; i++) {
+      if (bytes[i] > 127) return i - start + scan2(bytes, i, end);
+    }
+    return end - start;
+  }
+
+  int scan2(Uint8List bytes, int start, int end) {
+    final String scanTable = _Utf8Decoder.scanTable;
+    int size = 0;
+    int flags = 0;
+    for (int i = start; i < end; i++) {
+      int t = scanTable.codeUnitAt(bytes[i]);
+      size += t & sizeMask;
+      flags |= t;
+    }
+    _scanFlags = flags & flagsMask;
+    return size;
+  }
+
+  String decode8(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    // TODO(dartbug.com/41704): Allocate an uninitialized _OneByteString and
+    // write characters to it using _setAt.
+    Uint8List chars = Uint8List(size);
+    int i = start;
+    int j = 0;
+    if (_state == X1) {
+      // Half-way though 2-byte sequence
+      assert(_charOrIndex == 2 || _charOrIndex == 3);
+      final int e = bytes[i++] ^ 0x80;
+      if (e >= 0x40) {
+        _state = errorMissingExtension;
+        _charOrIndex = i - 1;
+        return "";
+      }
+      chars[j++] = (_charOrIndex << 6) | e;
+      _state = accept;
+    }
+    assert(_state == accept);
+    while (i < end) {
+      int byte = bytes[i++];
+      if (byte >= 0x80) {
+        if (byte < 0xC0) {
+          _state = errorUnexpectedExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        assert(byte == 0xC2 || byte == 0xC3);
+        if (i == end) {
+          _state = X1;
+          _charOrIndex = byte & 0x1F;
+          break;
+        }
+        final int e = bytes[i++] ^ 0x80;
+        if (e >= 0x40) {
+          _state = errorMissingExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        byte = (byte << 6) | e;
+      }
+      chars[j++] = byte;
+    }
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
+
+  String decode16(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    // TODO(dartbug.com/41704): Allocate an uninitialized _TwoByteString and
+    // write characters to it using _setAt.
+    Uint16List chars = Uint16List(size);
+    int i = start;
+    int j = 0;
+    int state = _state;
+    int char;
+
+    // First byte
+    assert(!isErrorState(state));
+    final int byte = bytes[i++];
+    final int type = typeTable.codeUnitAt(byte) & typeMask;
+    if (state == accept) {
+      char = byte & (shiftedByteMask >> type);
+      state = transitionTable.codeUnitAt(type);
+    } else {
+      char = (byte & 0x3F) | (_charOrIndex << 6);
+      state = transitionTable.codeUnitAt(state + type);
+    }
+
+    while (i < end) {
+      final int byte = bytes[i++];
+      final int type = typeTable.codeUnitAt(byte) & typeMask;
+      if (state == accept) {
+        if (char >= 0x10000) {
+          assert(char < 0x110000);
+          chars[j++] = 0xD7C0 + (char >> 10);
+          chars[j++] = 0xDC00 + (char & 0x3FF);
+        } else {
+          chars[j++] = char;
+        }
+        char = byte & (shiftedByteMask >> type);
+        state = transitionTable.codeUnitAt(type);
+      } else if (isErrorState(state)) {
+        _state = state;
+        _charOrIndex = i - 2;
+        return "";
+      } else {
+        char = (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+      }
+    }
+
+    // Final write?
+    if (state == accept) {
+      if (char >= 0x10000) {
+        assert(char < 0x110000);
+        chars[j++] = 0xD7C0 + (char >> 10);
+        chars[j++] = 0xDC00 + (char & 0x3FF);
+      } else {
+        chars[j++] = char;
+      }
+    } else if (isErrorState(state)) {
+      _state = state;
+      _charOrIndex = end - 1;
+      return "";
+    }
+
+    _state = state;
+    _charOrIndex = char;
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
index 4060970..3a964d6 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
@@ -201,7 +201,7 @@
   // unresolved method.
   @pragma("vm:entry-point", "call")
   static void _throwNew(Object receiver, String memberName, int invocationType,
-      Object typeArguments, List arguments, List argumentNames) {
+      Object? typeArguments, List? arguments, List? argumentNames) {
     throw new NoSuchMethodError._withType(receiver, memberName, invocationType,
         typeArguments, arguments, argumentNames);
   }
@@ -260,9 +260,9 @@
       this._receiver,
       String memberName,
       int invocationType,
-      Object typeArguments,
-      List arguments,
-      List argumentNames)
+      Object? typeArguments,
+      List? arguments,
+      List? argumentNames)
       : this._invocation = new _InvocationMirror._withType(
             new Symbol(memberName),
             invocationType,
@@ -271,10 +271,10 @@
                 ? _InvocationMirror._unpackTypeArguments(typeArguments, 0)
                 : null,
             argumentNames != null
-                ? arguments.sublist(0, arguments.length - argumentNames.length)
+                ? arguments!.sublist(0, arguments.length - argumentNames.length)
                 : arguments,
             argumentNames != null
-                ? _NamedArgumentsMap(arguments, argumentNames)
+                ? _NamedArgumentsMap(arguments!, argumentNames)
                 : null);
 
   static String? _existingMethodSignature(Object receiver, String methodName,
@@ -596,6 +596,7 @@
 
 class _LateInitializationError extends Error
     implements LateInitializationError {
+  @pragma("vm:entry-point")
   _LateInitializationError(this._name);
 
   @pragma("vm:entry-point")
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
index d5749b0..d42689c 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
@@ -64,10 +64,13 @@
 // implementation, since that would pull the callback trampoline into JIT
 // snapshots. The callback trampolines can only be serialized into AOT snapshots
 // because they embed the addresses of runtime routines in JIT mode.
-Object _nativeCallbackFunction<NS extends Function>(Function target,
+//
+// Function objects returned by this native method are not Dart instances,
+// so we need to use top type as a return type to avoid type check.
+dynamic _nativeCallbackFunction<NS extends Function>(Function target,
     Object exceptionalReturn) native "Ffi_nativeCallbackFunction";
 
-Pointer<NS> _pointerFromFunction<NS extends NativeFunction>(Object function)
+Pointer<NS> _pointerFromFunction<NS extends NativeFunction>(dynamic function)
     native "Ffi_pointerFromFunction";
 
 @patch
diff --git a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
index e4dcee5..bca95ab 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
@@ -108,7 +108,7 @@
   }
 
   @pragma("vm:exact-result-type",
-      [_GrowableList, "result-type-uses-passed-type-arguments"])
+      <dynamic>[_GrowableList, "result-type-uses-passed-type-arguments"])
   factory _GrowableList._withData(_List data) native "GrowableList_allocate";
 
   @pragma("vm:exact-result-type", "dart:core#_Smi")
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index ddb3992..2faf799 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -9,6 +9,7 @@
 
 import "dart:core" hide Symbol;
 
+import "dart:isolate" show SendPort;
 import "dart:typed_data" show Int32List;
 
 /// These are the additional parts of this patch library:
@@ -16,6 +17,12 @@
 // part "print_patch.dart";
 // part "symbol_patch.dart";
 
+// On the VM, we don't make the entire legacy weak mode check
+// const to avoid having a constant in the platform libraries
+// which evaluates differently in weak vs strong mode.
+@patch
+bool typeAcceptsNull<T>() => (const <Null>[]) is List<int> || null is T;
+
 @patch
 List<T> makeListFixedLength<T>(List<T> growableList)
     native "Internal_makeListFixedLength";
@@ -45,7 +52,6 @@
   // Implementation of package root/map provision.
   static var packageRootString;
   static var packageConfigString;
-  static var packageRootUriFuture;
   static var packageConfigUriFuture;
   static var resolvePackageUriFuture;
 
@@ -128,3 +134,6 @@
 // This is implemented by a recognized method, but in bytecode through a native.
 @pragma('vm:prefer-inline')
 void reachabilityFence(Object object) native "Internal_reachabilityFence";
+
+void sendAndExit(SendPort sendPort, var message)
+    native "SendPortImpl_sendAndExitInternal_";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
index 77e3844..1f97131 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
@@ -272,7 +272,7 @@
       // current isolate's control port and capabilities.
       //
       // TODO(floitsch): Send an error message if we can't find the entry point.
-      var readyMessage = new List<Object?>.filled(2, null);
+      final readyMessage = List<Object?>.filled(2, null);
       readyMessage[0] = controlPort.sendPort;
       readyMessage[1] = capabilities;
 
@@ -319,12 +319,12 @@
   String get debugName => _getDebugName(controlPort);
 
   @patch
-  static Future<Uri> get packageRoot {
+  static Future<Uri?> get packageRoot {
     return Future.value(null);
   }
 
   @patch
-  static Future<Uri> get packageConfig {
+  static Future<Uri?> get packageConfig {
     var hook = VMLibraryHooks.packageConfigUriFuture;
     if (hook == null) {
       throw new UnsupportedError("Isolate.packageConfig");
@@ -342,7 +342,6 @@
   }
 
   static bool _packageSupported() =>
-      (VMLibraryHooks.packageRootUriFuture != null) &&
       (VMLibraryHooks.packageConfigUriFuture != null) &&
       (VMLibraryHooks.resolvePackageUriFuture != null);
 
@@ -376,18 +375,8 @@
 
     final RawReceivePort readyPort = new RawReceivePort();
     try {
-      _spawnFunction(
-          readyPort.sendPort,
-          script.toString(),
-          entryPoint,
-          message,
-          paused,
-          errorsAreFatal,
-          onExit,
-          onError,
-          null,
-          packageConfig,
-          debugName);
+      _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+          paused, errorsAreFatal, onExit, onError, packageConfig, debugName);
       return await _spawnCommon(readyPort);
     } catch (e, st) {
       readyPort.close();
@@ -430,24 +419,17 @@
       }
     }
     // Resolve the uri against the current isolate's root Uri first.
-    var spawnedUri = _rootUri!.resolveUri(uri);
+    final Uri spawnedUri = _rootUri!.resolveUri(uri);
 
     // Inherit this isolate's package resolution setup if not overridden.
-    if (!automaticPackageResolution &&
-        (packageRoot == null) &&
-        (packageConfig == null)) {
+    if (!automaticPackageResolution && packageConfig == null) {
       if (Isolate._packageSupported()) {
-        packageRoot = await Isolate.packageRoot;
         packageConfig = await Isolate.packageConfig;
       }
     }
 
     // Ensure to resolve package: URIs being handed in as parameters.
-    if (packageRoot != null) {
-      // `packages/` directory is no longer supported. Force it null.
-      // TODO(mfairhurst) Should this throw an exception?
-      packageRoot = null;
-    } else if (packageConfig != null) {
+    if (packageConfig != null) {
       // Avoid calling resolvePackageUri if not strictly necessary in case
       // the API is not supported.
       if (packageConfig.isScheme("package")) {
@@ -456,8 +438,7 @@
     }
 
     // The VM will invoke [_startIsolate] and not `main`.
-    var packageRootString = packageRoot?.toString();
-    var packageConfigString = packageConfig?.toString();
+    final packageConfigString = packageConfig?.toString();
 
     final RawReceivePort readyPort = new RawReceivePort();
     try {
@@ -473,7 +454,6 @@
           checked,
           null,
           /* environment */
-          packageRootString,
           packageConfigString,
           debugName);
       return await _spawnCommon(readyPort);
@@ -529,7 +509,6 @@
       bool errorsAreFatal,
       SendPort? onExit,
       SendPort? onError,
-      String? packageRoot,
       String? packageConfig,
       String? debugName) native "Isolate_spawnFunction";
 
@@ -544,7 +523,6 @@
       bool errorsAreFatal,
       bool? checked,
       List? environment,
-      String? packageRoot,
       String? packageConfig,
       String? debugName) native "Isolate_spawnUri";
 
diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
index 6ed550a..a7f1f13 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
@@ -1330,7 +1330,7 @@
   final int _position;
   final bool isOptional;
   final bool isNamed;
-  final List _unmirroredMetadata;
+  final List? _unmirroredMetadata;
 
   _ParameterMirror._(
       reflectee,
diff --git a/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart
index 8b78e85..06eb588 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart
@@ -10,7 +10,7 @@
   const Symbol(String name) : this._name = name;
 
   @patch
-  toString() => 'Symbol("${computeUnmangledName(this)}")';
+  String toString() => 'Symbol("${computeUnmangledName(this)}")';
 
   @patch
   static String computeUnmangledName(Symbol symbol) {
diff --git a/sdk_nnbd/lib/async/async.dart b/sdk_nnbd/lib/async/async.dart
index 616375c..8cce959 100644
--- a/sdk_nnbd/lib/async/async.dart
+++ b/sdk_nnbd/lib/async/async.dart
@@ -102,7 +102,8 @@
         IterableElementError,
         printToZone,
         printToConsole,
-        Since;
+        Since,
+        typeAcceptsNull;
 
 part 'async_error.dart';
 part 'broadcast_stream_controller.dart';
diff --git a/sdk_nnbd/lib/async/broadcast_stream_controller.dart b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
index 3684a7c..c362eea 100644
--- a/sdk_nnbd/lib/async/broadcast_stream_controller.dart
+++ b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
@@ -380,7 +380,9 @@
     if (_isEmpty) return;
     if (_hasOneListener) {
       _state |= _BroadcastStreamController._STATE_FIRING;
-      (_firstSubscription as _BroadcastSubscription<T>)._add(data);
+      _BroadcastSubscription<T> firstSubscription =
+          _firstSubscription as dynamic;
+      firstSubscription._add(data);
       _state &= ~_BroadcastStreamController._STATE_FIRING;
       if (_isEmpty) {
         _callOnCancel();
diff --git a/sdk_nnbd/lib/async/future.dart b/sdk_nnbd/lib/async/future.dart
index d1273aa..8a43bce 100644
--- a/sdk_nnbd/lib/async/future.dart
+++ b/sdk_nnbd/lib/async/future.dart
@@ -223,9 +223,8 @@
       if (result is Future<T>) {
         return result;
       } else {
-        if (result is! T)
-          throw "unreachable"; // TODO(lrn): Remove when type promotion works.
-        return new _Future<T>.value(result);
+        // TODO(40014): Remove cast when type promotion works.
+        return new _Future<T>.value(result as dynamic);
       }
     } catch (error, stackTrace) {
       var future = new _Future<T>();
@@ -259,7 +258,7 @@
    */
   @pragma("vm:entry-point")
   factory Future.value([FutureOr<T>? value]) {
-    return new _Future<T>.immediate(value as FutureOr<T>);
+    return new _Future<T>.immediate(value == null ? value as dynamic : value);
   }
 
   /**
@@ -312,7 +311,7 @@
    * later time that isn't necessarily after a known fixed duration.
    */
   factory Future.delayed(Duration duration, [FutureOr<T> computation()?]) {
-    if (computation == null && null is! T) {
+    if (computation == null && !typeAcceptsNull<T>()) {
       throw ArgumentError.value(
           null, "computation", "The type parameter is not nullable");
     }
@@ -369,9 +368,7 @@
     late StackTrace stackTrace; // The stackTrace that came with the error.
 
     // Handle an error from any of the futures.
-    // TODO(jmesserly): use `void` return type once it can be inferred for the
-    // `then` call below.
-    handleError(Object theError, StackTrace theStackTrace) {
+    void handleError(Object theError, StackTrace theStackTrace) {
       remaining--;
       List<T?>? valueList = values;
       if (valueList != null) {
@@ -412,8 +409,6 @@
               result._completeWithValue(List<T>.from(valueList));
             }
           } else {
-            // Forced read of error to assert that it has occurred earlier.
-            assert(error != null);
             if (cleanUp != null && value != null) {
               // Ensure errors from cleanUp are uncaught.
               new Future.sync(() {
@@ -421,6 +416,8 @@
               });
             }
             if (remaining == 0 && !eagerError) {
+              // If eagerError is false, and valueList is null, then
+              // error and stackTrace have been set in handleError above.
               result._completeError(error, stackTrace);
             }
           }
@@ -560,6 +557,7 @@
           result.then(nextIteration, onError: doneSignal._completeError);
           return;
         }
+        // TODO(40014): Remove cast when type promotion works.
         keepGoing = result as bool;
       }
       doneSignal._complete(null);
diff --git a/sdk_nnbd/lib/async/future_impl.dart b/sdk_nnbd/lib/async/future_impl.dart
index b23bfdb0..3f33737 100644
--- a/sdk_nnbd/lib/async/future_impl.dart
+++ b/sdk_nnbd/lib/async/future_impl.dart
@@ -41,7 +41,7 @@
 class _AsyncCompleter<T> extends _Completer<T> {
   void complete([FutureOr<T>? value]) {
     if (!future._mayComplete) throw new StateError("Future already completed");
-    future._asyncComplete(value as FutureOr<T>);
+    future._asyncComplete(value == null ? value as dynamic : value);
   }
 
   void _completeError(Object error, StackTrace stackTrace) {
@@ -52,7 +52,7 @@
 class _SyncCompleter<T> extends _Completer<T> {
   void complete([FutureOr<T>? value]) {
     if (!future._mayComplete) throw new StateError("Future already completed");
-    future._complete(value as FutureOr<T>);
+    future._complete(value == null ? value as dynamic : value);
   }
 
   void _completeError(Object error, StackTrace stackTrace) {
@@ -116,19 +116,19 @@
 
   FutureOr<T> Function(S) get _onValue {
     assert(handlesValue);
-    return callback as FutureOr<T> Function(S);
+    return callback as dynamic;
   }
 
   Function? get _onError => errorCallback;
 
   _FutureErrorTest get _errorTest {
     assert(hasErrorTest);
-    return callback as _FutureErrorTest;
+    return callback as dynamic;
   }
 
   _FutureAction get _whenCompleteAction {
     assert(handlesComplete);
-    return callback as _FutureAction;
+    return callback as dynamic;
   }
 
   /// Whether this listener has an error callback.
@@ -158,7 +158,7 @@
           errorCallback, asyncError.error, asyncError.stackTrace);
     } else {
       return _zone.runUnary<dynamic, Object>(
-          errorCallback as dynamic Function(Object), asyncError.error);
+          errorCallback as dynamic, asyncError.error);
     }
   }
 
@@ -511,8 +511,11 @@
       }
     } else {
       _FutureListener? listeners = _removeListeners();
-      // TODO(lrn): Remove cast when type promotion works.
-      _setValue(value as T); // Value promoted to T.
+      // 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.
+      _setValue(value as dynamic); // Value promoted to T.
       _propagateToListeners(this, listeners);
     }
   }
@@ -551,10 +554,17 @@
       _chainFuture(value);
       return;
     }
+    // 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.
+    _asyncCompleteWithValue(value as dynamic); // Value promoted to T.
+  }
+
+  void _asyncCompleteWithValue(T value) {
     _setPendingComplete();
     _zone.scheduleMicrotask(() {
-      // TODO(lrn): Remove cast when type promotion works.
-      _completeWithValue(value as T); // Value promoted to T.
+      _completeWithValue(value);
     });
   }
 
@@ -663,15 +673,15 @@
             listenerHasError = true;
             return;
           }
-          if (completeResult is Future) {
-            if (completeResult is _Future && completeResult._isComplete) {
-              if (completeResult._hasError) {
-                listenerValueOrError = completeResult._error;
-                listenerHasError = true;
-              }
-              // Otherwise use the existing result of source.
-              return;
+          if (completeResult is _Future && completeResult._isComplete) {
+            if (completeResult._hasError) {
+              listenerValueOrError = completeResult._error;
+              listenerHasError = true;
             }
+            // Otherwise use the existing result of source.
+            return;
+          }
+          if (completeResult is Future) {
             // We have to wait for the completeResult future to complete
             // before knowing if it's an error or we should use the result
             // of source.
diff --git a/sdk_nnbd/lib/async/stream.dart b/sdk_nnbd/lib/async/stream.dart
index d504a42..46ec161 100644
--- a/sdk_nnbd/lib/async/stream.dart
+++ b/sdk_nnbd/lib/async/stream.dart
@@ -263,7 +263,7 @@
    */
   factory Stream.periodic(Duration period,
       [T computation(int computationCount)?]) {
-    if (computation == null && null is! T) {
+    if (computation == null && !typeAcceptsNull<T>()) {
       throw ArgumentError.value(null, "computation",
           "Must not be omitted when the event type is non-nullable");
     }
@@ -523,10 +523,8 @@
           subscription.pause();
           newValue.then(add, onError: addError).whenComplete(resume);
         } else {
-          if (newValue is! E) {
-            throw "unreachable"; // TODO(lrn): Remove when type promotion works.
-          }
-          controller.add(newValue);
+          // TODO(40014): Remove cast when type promotion works.
+          controller.add(newValue as dynamic);
         }
       });
       controller.onCancel = subscription.cancel;
@@ -1076,7 +1074,9 @@
    * The [futureValue] must not be omitted if `null` is not assignable to [E].
    */
   Future<E> drain<E>([E? futureValue]) {
-    futureValue = futureValue as E;
+    if (futureValue == null) {
+      futureValue = futureValue as E;
+    }
     return listen(null, cancelOnError: true).asFuture<E>(futureValue);
   }
 
diff --git a/sdk_nnbd/lib/async/stream_controller.dart b/sdk_nnbd/lib/async/stream_controller.dart
index 8b7d786..0c0a93a 100644
--- a/sdk_nnbd/lib/async/stream_controller.dart
+++ b/sdk_nnbd/lib/async/stream_controller.dart
@@ -515,9 +515,9 @@
   _PendingEvents<T>? get _pendingEvents {
     assert(_isInitialState);
     if (!_isAddingStream) {
-      return _varData as _PendingEvents<T>?;
+      return _varData as dynamic;
     }
-    var state = _varData as _StreamControllerAddStreamState<T>;
+    _StreamControllerAddStreamState<T> state = _varData as dynamic;
     return state.varData;
   }
 
@@ -526,17 +526,17 @@
     assert(_isInitialState);
     if (!_isAddingStream) {
       Object? events = _varData;
-      if (events is! _StreamImplEvents<T>) {
+      if (events == null) {
         _varData = events = _StreamImplEvents<T>();
       }
-      return events;
+      return events as dynamic;
     }
-    var state = _varData as _StreamControllerAddStreamState<T>;
+    _StreamControllerAddStreamState<T> state = _varData as dynamic;
     Object? events = state.varData;
-    if (events is! _StreamImplEvents<T>) {
+    if (events == null) {
       state.varData = events = _StreamImplEvents<T>();
     }
-    return events;
+    return events as dynamic;
   }
 
   // Get the current subscription.
@@ -546,9 +546,10 @@
     assert(hasListener);
     Object? varData = _varData;
     if (_isAddingStream) {
-      varData = (varData as _StreamControllerAddStreamState<Object?>).varData;
+      _StreamControllerAddStreamState<Object?> streamState = varData as dynamic;
+      varData = streamState.varData;
     }
-    return varData as _ControllerSubscription<T>;
+    return varData as dynamic;
   }
 
   /**
@@ -668,7 +669,7 @@
   void _close() {
     // End of addStream stream.
     assert(_isAddingStream);
-    var addState = _varData as _StreamControllerAddStreamState<T>;
+    _StreamControllerAddStreamState<T> addState = _varData as dynamic;
     _varData = addState.varData;
     _state &= ~_STATE_ADDSTREAM;
     addState.complete();
@@ -687,7 +688,7 @@
     _PendingEvents<T>? pendingEvents = _pendingEvents;
     _state |= _STATE_SUBSCRIBED;
     if (_isAddingStream) {
-      var addState = _varData as _StreamControllerAddStreamState<T>;
+      _StreamControllerAddStreamState<T> addState = _varData as dynamic;
       addState.varData = subscription;
       addState.resume();
     } else {
@@ -712,7 +713,7 @@
     // returned future.
     Future<void>? result;
     if (_isAddingStream) {
-      var addState = _varData as _StreamControllerAddStreamState<T>;
+      _StreamControllerAddStreamState<T> addState = _varData as dynamic;
       result = addState.cancel();
     }
     _varData = null;
@@ -759,7 +760,7 @@
 
   void _recordPause(StreamSubscription<T> subscription) {
     if (_isAddingStream) {
-      var addState = _varData as _StreamControllerAddStreamState<T>;
+      _StreamControllerAddStreamState<T> addState = _varData as dynamic;
       addState.pause();
     }
     _runGuarded(onPause);
@@ -767,7 +768,7 @@
 
   void _recordResume(StreamSubscription<T> subscription) {
     if (_isAddingStream) {
-      var addState = _varData as _StreamControllerAddStreamState<T>;
+      _StreamControllerAddStreamState<T> addState = _varData as dynamic;
       addState.resume();
     }
     _runGuarded(onResume);
diff --git a/sdk_nnbd/lib/async/stream_impl.dart b/sdk_nnbd/lib/async/stream_impl.dart
index 4404d78..1c6fa50 100644
--- a/sdk_nnbd/lib/async/stream_impl.dart
+++ b/sdk_nnbd/lib/async/stream_impl.dart
@@ -213,26 +213,31 @@
   }
 
   Future<E> asFuture<E>([E? futureValue]) {
-    if (futureValue is E) {
-      // Overwrite the onDone and onError handlers.
-      _Future<E> result = new _Future<E>();
-      E resultValue = futureValue;
-      _onDone = () {
-        result._complete(resultValue);
-      };
-      _onError = (Object error, StackTrace stackTrace) {
-        Future cancelFuture = cancel();
-        if (!identical(cancelFuture, Future._nullFuture)) {
-          cancelFuture.whenComplete(() {
-            result._completeError(error, stackTrace);
-          });
-        } else {
-          result._completeError(error, stackTrace);
-        }
-      };
-      return result;
+    E resultValue;
+    if (futureValue == null) {
+      if (!typeAcceptsNull<E>()) {
+        throw ArgumentError.notNull("futureValue");
+      }
+      resultValue = futureValue as dynamic;
+    } else {
+      resultValue = futureValue;
     }
-    throw ArgumentError.notNull("futureValue");
+    // Overwrite the onDone and onError handlers.
+    _Future<E> result = new _Future<E>();
+    _onDone = () {
+      result._complete(resultValue);
+    };
+    _onError = (Object error, StackTrace stackTrace) {
+      Future cancelFuture = cancel();
+      if (!identical(cancelFuture, Future._nullFuture)) {
+        cancelFuture.whenComplete(() {
+          result._completeError(error, stackTrace);
+        });
+      } else {
+        result._completeError(error, stackTrace);
+      }
+    };
+    return result;
   }
 
   // State management.
@@ -329,7 +334,9 @@
    * of pending events later (if necessary).
    */
   void _addPending(_DelayedEvent event) {
-    var pending = (_pending ??= _StreamImplEvents<T>()) as _StreamImplEvents<T>;
+    _StreamImplEvents<T>? pending = _pending as dynamic;
+    pending ??= _StreamImplEvents<T>();
+    _pending = pending;
     pending.add(event);
     if (!_hasPending) {
       _state |= _STATE_HAS_PENDING;
@@ -368,7 +375,7 @@
       if (onError is void Function(Object, StackTrace)) {
         _zone.runBinaryGuarded<Object, StackTrace>(onError, error, stackTrace);
       } else {
-        _zone.runUnaryGuarded<Object>(_onError as void Function(Object), error);
+        _zone.runUnaryGuarded<Object>(_onError as dynamic, error);
       }
       _state &= ~_STATE_IN_CALLBACK;
     }
@@ -780,15 +787,20 @@
   Future cancel() => Future._nullFuture;
 
   Future<E> asFuture<E>([E? futureValue]) {
-    if (futureValue is E) {
-      _Future<E> result = new _Future<E>();
-      E resultValue = futureValue;
-      _onDone = () {
-        result._completeWithValue(resultValue);
-      };
-      return result;
+    E resultValue;
+    if (futureValue == null) {
+      if (!typeAcceptsNull<E>()) {
+        throw ArgumentError.notNull("futureValue");
+      }
+      resultValue = futureValue as dynamic;
+    } else {
+      resultValue = futureValue;
     }
-    throw ArgumentError.notNull("futureValue");
+    _Future<E> result = new _Future<E>();
+    _onDone = () {
+      result._completeWithValue(resultValue);
+    };
+    return result;
   }
 
   void _sendDone() {
@@ -806,7 +818,7 @@
   final _BroadcastCallback<T>? _onCancelHandler;
   final Zone _zone;
 
-  late _AsBroadcastStreamController<T>? _controller;
+  _AsBroadcastStreamController<T>? _controller;
   StreamSubscription<T>? _subscription;
 
   _AsBroadcastStream(
@@ -996,9 +1008,9 @@
 
   T get current {
     if (_subscription != null && _isPaused) {
-      return _stateData as T;
+      return _stateData as dynamic;
     }
-    return null as T;
+    return null as dynamic;
   }
 
   Future<bool> moveNext() {
@@ -1025,7 +1037,7 @@
     assert(_subscription == null);
     var stateData = _stateData;
     if (stateData != null) {
-      var stream = stateData as Stream<T>;
+      Stream<T> stream = stateData as dynamic;
       _subscription = stream.listen(_onData,
           onError: _onError, onDone: _onDone, cancelOnError: true);
       var future = new _Future<bool>();
@@ -1042,7 +1054,7 @@
     if (subscription != null) {
       _subscription = null;
       if (!_isPaused) {
-        var future = stateData as _Future<bool>;
+        _Future<bool> future = stateData as dynamic;
         future._asyncComplete(false);
       }
       return subscription.cancel();
@@ -1052,7 +1064,7 @@
 
   void _onData(T data) {
     assert(_subscription != null && !_isPaused);
-    var moveNextFuture = _stateData as _Future<bool>;
+    _Future<bool> moveNextFuture = _stateData as dynamic;
     _stateData = data;
     _isPaused = true;
     moveNextFuture._complete(true);
@@ -1061,7 +1073,7 @@
 
   void _onError(Object error, StackTrace stackTrace) {
     assert(_subscription != null && !_isPaused);
-    var moveNextFuture = _stateData as _Future<bool>;
+    _Future<bool> moveNextFuture = _stateData as dynamic;
     _subscription = null;
     _stateData = null;
     moveNextFuture._completeError(error, stackTrace);
@@ -1069,7 +1081,7 @@
 
   void _onDone() {
     assert(_subscription != null && !_isPaused);
-    var moveNextFuture = _stateData as _Future<bool>;
+    _Future<bool> moveNextFuture = _stateData as dynamic;
     _subscription = null;
     _stateData = null;
     moveNextFuture._complete(false);
diff --git a/sdk_nnbd/lib/collection/splay_tree.dart b/sdk_nnbd/lib/collection/splay_tree.dart
index b81a034..a019b64 100644
--- a/sdk_nnbd/lib/collection/splay_tree.dart
+++ b/sdk_nnbd/lib/collection/splay_tree.dart
@@ -8,36 +8,27 @@
 
 /// A node in a splay tree. It holds the sorting key and the left
 /// and right children in the tree.
-class _SplayTreeNode<K> {
-  // The key is nullable to be able to create a dummy node.
-  final K? _key;
+class _SplayTreeNode<K, Node extends _SplayTreeNode<K, Node>> {
+  final K key;
 
-  _SplayTreeNode<K>? left;
-  _SplayTreeNode<K>? right;
+  Node? left;
+  Node? right;
 
-  _SplayTreeNode(this._key);
+  _SplayTreeNode(this.key);
+}
 
-  K get key {
-    // TODO(dartbug.com/40892): replace with '_key as K'
-    K? localKey = _key;
-    return (localKey != null) ? localKey : localKey as K;
-  }
+/// A node in a splay tree based set.
+class _SplayTreeSetNode<K> extends _SplayTreeNode<K, _SplayTreeSetNode<K>> {
+  _SplayTreeSetNode(K key) : super(key);
 }
 
 /// A node in a splay tree based map.
 ///
 /// A [_SplayTreeNode] that also contains a value
-class _SplayTreeMapNode<K, V> extends _SplayTreeNode<K> {
-  // The value is nullable to be able to create a dummy node.
-  V? _value;
-
-  _SplayTreeMapNode(K? key, this._value) : super(key);
-
-  V get value {
-    // TODO(dartbug.com/40892): replace with '_value as V'
-    V? localValue = _value;
-    return (localValue != null) ? localValue : localValue as V;
-  }
+class _SplayTreeMapNode<K, V>
+    extends _SplayTreeNode<K, _SplayTreeMapNode<K, V>> {
+  V value;
+  _SplayTreeMapNode(K key, this.value) : super(key);
 }
 
 /// A splay tree is a self-balancing binary search tree.
@@ -46,16 +37,12 @@
 /// are quick to access again.
 /// It performs basic operations such as insertion, look-up and
 /// removal, in O(log(n)) amortized time.
-abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
+abstract class _SplayTree<K, Node extends _SplayTreeNode<K, Node>> {
   // The root node of the splay tree. It will contain either the last
   // element inserted or the last element looked up.
   Node? get _root;
   set _root(Node? newValue);
 
-  // The dummy node used when performing a splay on the tree. Reusing it
-  // avoids allocating a node each time a splay is performed.
-  Node get _dummy;
-
   // Number of elements in the splay tree.
   int _count = 0;
 
@@ -71,14 +58,11 @@
   int _splayCount = 0;
 
   /// The comparator that is used for this splay tree.
-  Comparator<K> get _comparator;
+  Comparator<K> get _compare;
 
   /// The predicate to determine that a given object is a valid key.
   _Predicate get _validKey;
 
-  /// Comparison used to compare keys.
-  int _compare(K key1, K key2);
-
   /// Perform the splay operation for the given key. Moves the node with
   /// the given key to the top of the tree.  If no node has the given
   /// key, the last node on the search path is moved to the top of the
@@ -90,59 +74,80 @@
   int _splay(K key) {
     if (_root == null) return -1;
 
-    // The right child of the dummy node will hold
-    // the L tree of the algorithm.  The left child of the dummy node
-    // will hold the R tree of the algorithm.  Using a dummy node, left
-    // and right will always be nodes and we avoid special cases.
-    Node left = _dummy;
-    Node right = _dummy;
-    Node current = _root!;
+    // The right and newTreeRight variables start out null, and are set
+    // after the first move left.  The right node is the destination
+    // for subsequent left rebalances, and newTreeRight holds the left
+    // child of the final tree.  The newTreeRight variable is set at most
+    // once, after the first move left, and is null iff right is null.
+    // The left and newTreeLeft variables play the corresponding role for
+    // right rebalances.
+    Node? right;
+    Node? newTreeRight;
+    Node? left;
+    Node? newTreeLeft;
+    var current = _root!;
+    // Hoist the field read out of the loop.
+    var compare = _compare;
     int comp;
     while (true) {
-      comp = _compare(current.key, key);
+      comp = compare(current.key, key);
       if (comp > 0) {
-        if (current.left == null) break;
-        comp = _compare(current.left!.key, key);
+        var currentLeft = current.left;
+        if (currentLeft == null) break;
+        comp = compare(currentLeft.key, key);
         if (comp > 0) {
           // Rotate right.
-          Node tmp = current.left as Node;
-          current.left = tmp.right;
-          tmp.right = current;
-          current = tmp;
-          if (current.left == null) break;
+          current.left = currentLeft.right;
+          currentLeft.right = current;
+          current = currentLeft;
+          currentLeft = current.left;
+          if (currentLeft == null) break;
         }
         // Link right.
-        right.left = current;
+        if (right == null) {
+          // First left rebalance, store the eventual right child
+          newTreeRight = current;
+        } else {
+          right.left = current;
+        }
         right = current;
-        current = current.left as Node;
+        current = currentLeft;
       } else if (comp < 0) {
-        if (current.right == null) break;
-        comp = _compare(current.right!.key, key);
+        var currentRight = current.right;
+        if (currentRight == null) break;
+        comp = compare(currentRight.key, key);
         if (comp < 0) {
           // Rotate left.
-          Node tmp = current.right as Node;
-          current.right = tmp.left;
-          tmp.left = current;
-          current = tmp;
-          if (current.right == null) break;
+          current.right = currentRight.left;
+          currentRight.left = current;
+          current = currentRight;
+          currentRight = current.right;
+          if (currentRight == null) break;
         }
         // Link left.
-        left.right = current;
+        if (left == null) {
+          // First right rebalance, store the eventual left child
+          newTreeLeft = current;
+        } else {
+          left.right = current;
+        }
         left = current;
-        current = current.right as Node;
+        current = currentRight;
       } else {
         break;
       }
     }
     // Assemble.
-    left.right = current.left;
-    right.left = current.right;
-    current.left = _dummy.right;
-    current.right = _dummy.left;
+    if (left != null) {
+      left.right = current.left;
+      current.left = newTreeLeft;
+    }
+    if (right != null) {
+      right.left = current.right;
+      current.right = newTreeRight;
+    }
     _root = current;
 
-    _dummy.right = null;
-    _dummy.left = null;
     _splayCount++;
     return comp;
   }
@@ -151,31 +156,57 @@
   // anchored at [node].
   // and that node is returned. It should replace the reference to [node]
   // in any parent tree or root pointer.
-  external Node _splayMin(Node node);
+  Node _splayMin(Node node) {
+    var current = node;
+    var nextLeft = current.left;
+    while (nextLeft != null) {
+      var left = nextLeft;
+      current.left = left.right;
+      left.right = current;
+      current = left;
+      nextLeft = current.left;
+    }
+    return current;
+  }
 
   // Emulates splaying with a key that is greater than any in the subtree
   // anchored at [node].
   // After this, the largest element in the tree is the root of the subtree,
   // and that node is returned. It should replace the reference to [node]
   // in any parent tree or root pointer.
-  external Node _splayMax(Node node);
+  Node _splayMax(Node node) {
+    var current = node;
+    var nextRight = current.right;
+    while (nextRight != null) {
+      var right = nextRight;
+      current.right = right.left;
+      right.left = current;
+      current = right;
+      nextRight = current.right;
+    }
+    return current;
+  }
 
   Node? _remove(K key) {
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp != 0) return null;
-    Node result = _root!;
+    var root = _root!;
+    var result = root;
+    var left = root.left;
     _count--;
     // assert(_count >= 0);
-    if (_root!.left == null) {
-      _root = _root!.right as Node?;
+    if (left == null) {
+      _root = root.right;
     } else {
-      Node? right = _root!.right as Node?;
+      var right = root.right;
       // Splay to make sure that the new root has an empty right child.
-      _root = _splayMax(_root!.left as Node);
+      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++;
     return result;
@@ -188,32 +219,35 @@
   void _addNewRoot(Node node, int comp) {
     _count++;
     _modificationCount++;
-    if (_root == null) {
+    var root = _root;
+    if (root == null) {
       _root = node;
       return;
     }
     // 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;
   }
 
   Node? get _first {
-    if (_root == null) return null;
-    _root = _splayMin(_root!);
+    var root = _root;
+    if (root == null) return null;
+    _root = _splayMin(root);
     return _root;
   }
 
   Node? get _last {
-    if (_root == null) return null;
-    _root = _splayMax(_root!);
+    var root = _root;
+    if (root == null) return null;
+    _root = _splayMax(root);
     return _root;
   }
 
@@ -224,19 +258,14 @@
   }
 }
 
-class _TypeTest<T> {
-  bool test(v) => v is T;
-}
-
-int _dynamicCompare(dynamic a, dynamic b) =>
-    Comparable.compare(a as Comparable, b as Comparable);
+int _dynamicCompare(dynamic a, dynamic b) => Comparable.compare(a, b);
 
 Comparator<K> _defaultCompare<K>() {
   // If K <: Comparable, then we can just use Comparable.compare
   // with no casts.
   Object compare = Comparable.compare;
   if (compare is Comparator<K>) {
-    return compare as Comparator<K>;
+    return compare;
   }
   // Otherwise wrap and cast the arguments on each call.
   return _dynamicCompare;
@@ -266,15 +295,14 @@
 class SplayTreeMap<K, V> extends _SplayTree<K, _SplayTreeMapNode<K, V>>
     with MapMixin<K, V> {
   _SplayTreeMapNode<K, V>? _root;
-  final _SplayTreeMapNode<K, V> _dummy = _SplayTreeMapNode<K, V>(null, null);
 
-  Comparator<K> _comparator;
+  Comparator<K> _compare;
   _Predicate _validKey;
 
   SplayTreeMap(
       [int Function(K key1, K key2)? compare,
       bool Function(dynamic potentialKey)? isValidKey])
-      : _comparator = compare ?? _defaultCompare<K>(),
+      : _compare = compare ?? _defaultCompare<K>(),
         _validKey = isValidKey ?? ((dynamic v) => v is K);
 
   /// Creates a [SplayTreeMap] that contains all key/value pairs of [other].
@@ -284,9 +312,12 @@
   factory SplayTreeMap.from(Map<dynamic, dynamic> other,
       [int Function(K key1, K key2)? compare,
       bool Function(dynamic potentialKey)? isValidKey]) {
+    if (other is Map<K, V>) {
+      return SplayTreeMap<K, V>.of(other, compare, isValidKey);
+    }
     SplayTreeMap<K, V> result = SplayTreeMap<K, V>(compare, isValidKey);
     other.forEach((dynamic k, dynamic v) {
-      result[k as K] = v as V;
+      result[k] = v;
     });
     return result;
   }
@@ -335,12 +366,10 @@
     return map;
   }
 
-  int _compare(K key1, K key2) => _comparator(key1, key2);
-
   V? operator [](Object? key) {
     if (!_validKey(key)) return null;
     if (_root != null) {
-      int comp = _splay(key as K);
+      int comp = _splay(key as dynamic);
       if (comp == 0) {
         return _root!.value;
       }
@@ -350,7 +379,7 @@
 
   V? remove(Object? key) {
     if (!_validKey(key)) return null;
-    _SplayTreeMapNode<K, V>? mapRoot = _remove(key as K);
+    _SplayTreeMapNode<K, V>? mapRoot = _remove(key as dynamic);
     if (mapRoot != null) return mapRoot.value;
     return null;
   }
@@ -361,7 +390,7 @@
     // the key to the root of the tree.
     int comp = _splay(key);
     if (comp == 0) {
-      _root!._value = value;
+      _root!.value = value;
       return;
     }
     _addNewRoot(_SplayTreeMapNode(key, value), comp);
@@ -401,9 +430,10 @@
   bool get isNotEmpty => !isEmpty;
 
   void forEach(void f(K key, V value)) {
-    Iterator<_SplayTreeNode<K>> nodes = _SplayTreeNodeIterator<K>(this);
+    Iterator<_SplayTreeMapNode<K, V>> nodes =
+        _SplayTreeNodeIterator<K, _SplayTreeMapNode<K, V>>(this);
     while (nodes.moveNext()) {
-      _SplayTreeMapNode<K, V> node = nodes.current as _SplayTreeMapNode<K, V>;
+      _SplayTreeMapNode<K, V> node = nodes.current;
       f(node.key, node.value);
     }
   }
@@ -417,21 +447,21 @@
   }
 
   bool containsKey(Object? key) {
-    return _validKey(key) && _splay(key as K) == 0;
+    return _validKey(key) && _splay(key as dynamic) == 0;
   }
 
   bool containsValue(Object? value) {
     int initialSplayCount = _splayCount;
-    bool visit(_SplayTreeMapNode? node) {
+    bool visit(_SplayTreeMapNode<K, V>? node) {
       while (node != null) {
         if (node.value == value) return true;
         if (initialSplayCount != _splayCount) {
           throw ConcurrentModificationError(this);
         }
-        if (node.right != null && visit(node.right as _SplayTreeMapNode)) {
+        if (node.right != null && visit(node.right)) {
           return true;
         }
-        node = node.left as _SplayTreeMapNode?;
+        node = node.left;
       }
       return false;
     }
@@ -439,7 +469,8 @@
     return visit(_root);
   }
 
-  Iterable<K> get keys => _SplayTreeKeyIterable<K>(this);
+  Iterable<K> get keys =>
+      _SplayTreeKeyIterable<K, _SplayTreeMapNode<K, V>>(this);
 
   Iterable<V> get values => _SplayTreeValueIterable<K, V>(this);
 
@@ -462,12 +493,14 @@
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp < 0) return _root!.key;
-    _SplayTreeNode<K>? node = _root!.left;
+    _SplayTreeMapNode<K, V>? node = _root!.left;
     if (node == null) return null;
-    while (node!.right != null) {
-      node = node.right;
+    var nodeRight = node.right;
+    while (nodeRight != null) {
+      node = nodeRight;
+      nodeRight = node.right;
     }
-    return node.key;
+    return node!.key;
   }
 
   /// Get the first key in the map that is strictly larger than [key]. Returns
@@ -477,17 +510,20 @@
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp > 0) return _root!.key;
-    _SplayTreeNode<K>? node = _root!.right;
+    _SplayTreeMapNode<K, V>? node = _root!.right;
     if (node == null) return null;
-    while (node!.left != null) {
-      node = node.left;
+    var nodeLeft = node.left;
+    while (nodeLeft != null) {
+      node = nodeLeft;
+      nodeLeft = node.left;
     }
-    return node.key;
+    return node!.key;
   }
 }
 
-abstract class _SplayTreeIterator<K, T> implements Iterator<T> {
-  final _SplayTree<K, _SplayTreeNode<K>> _tree;
+abstract class _SplayTreeIterator<K, Node extends _SplayTreeNode<K, Node>, T>
+    implements Iterator<T> {
+  final _SplayTree<K, Node> _tree;
 
   /// Worklist of nodes to visit.
   ///
@@ -497,7 +533,7 @@
   /// the nodes of a full traversal.
   ///
   /// Only valid as long as the original tree isn't reordered.
-  final List<_SplayTreeNode<K>> _workList = <_SplayTreeNode<K>>[];
+  final List<Node> _workList = [];
 
   /// Original modification counter of [_tree].
   ///
@@ -514,16 +550,16 @@
   int _splayCount;
 
   /// Current node.
-  _SplayTreeNode<K>? _currentNode;
+  Node? _currentNode;
 
-  _SplayTreeIterator(_SplayTree<K, _SplayTreeNode<K>> tree)
+  _SplayTreeIterator(_SplayTree<K, Node> tree)
       : _tree = tree,
         _modificationCount = tree._modificationCount,
         _splayCount = tree._splayCount {
     _findLeftMostDescendent(tree._root);
   }
 
-  _SplayTreeIterator.startAt(_SplayTree<K, _SplayTreeNode<K>> tree, K startKey)
+  _SplayTreeIterator.startAt(_SplayTree<K, Node> tree, K startKey)
       : _tree = tree,
         _modificationCount = tree._modificationCount,
         _splayCount = -1 {
@@ -539,11 +575,12 @@
   }
 
   T get current {
-    if (_currentNode == null) return null as T;
-    return _getValue(_currentNode!);
+    var node = _currentNode;
+    if (node == null) return null as T;
+    return _getValue(node);
   }
 
-  void _findLeftMostDescendent(_SplayTreeNode<K>? node) {
+  void _findLeftMostDescendent(Node? node) {
     while (node != null) {
       _workList.add(node);
       node = node.left;
@@ -556,16 +593,12 @@
   /// 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(_SplayTreeNode<K> currentNode) {
+  void _rebuildWorkList(Node currentNode) {
     assert(_workList.isNotEmpty);
     _workList.clear();
-    if (currentNode == null) {
-      _findLeftMostDescendent(_tree._root);
-    } else {
-      _tree._splay(currentNode.key);
-      _findLeftMostDescendent(_tree._root!.right);
-      assert(_workList.isNotEmpty);
-    }
+    _tree._splay(currentNode.key);
+    _findLeftMostDescendent(_tree._root!.right);
+    assert(_workList.isNotEmpty);
   }
 
   bool moveNext() {
@@ -589,20 +622,21 @@
     return true;
   }
 
-  T _getValue(_SplayTreeNode<K> node);
+  T _getValue(Node node);
 }
 
-class _SplayTreeKeyIterable<K> extends EfficientLengthIterable<K> {
-  _SplayTree<K, _SplayTreeNode<K>> _tree;
+class _SplayTreeKeyIterable<K, Node extends _SplayTreeNode<K, Node>>
+    extends EfficientLengthIterable<K> {
+  _SplayTree<K, Node> _tree;
   _SplayTreeKeyIterable(this._tree);
   int get length => _tree._count;
   bool get isEmpty => _tree._count == 0;
-  Iterator<K> get iterator => _SplayTreeKeyIterator<K>(_tree);
+  Iterator<K> get iterator => _SplayTreeKeyIterator<K, Node>(_tree);
 
   Set<K> toSet() {
-    SplayTreeSet<K> set = SplayTreeSet<K>(_tree._comparator, _tree._validKey);
+    SplayTreeSet<K> set = SplayTreeSet<K>(_tree._compare, _tree._validKey);
     set._count = _tree._count;
-    set._root = set._copyNode(_tree._root);
+    set._root = set._copyNode<Node>(_tree._root);
     return set;
   }
 }
@@ -615,26 +649,24 @@
   Iterator<V> get iterator => _SplayTreeValueIterator<K, V>(_map);
 }
 
-class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K, K> {
-  _SplayTreeKeyIterator(_SplayTree<K, _SplayTreeNode<K>> map) : super(map);
-  K _getValue(_SplayTreeNode<K> node) => node.key;
+class _SplayTreeKeyIterator<K, Node extends _SplayTreeNode<K, Node>>
+    extends _SplayTreeIterator<K, Node, K> {
+  _SplayTreeKeyIterator(_SplayTree<K, Node> map) : super(map);
+  K _getValue(Node node) => node.key;
 }
 
-class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<K, V> {
+class _SplayTreeValueIterator<K, V>
+    extends _SplayTreeIterator<K, _SplayTreeMapNode<K, V>, V> {
   _SplayTreeValueIterator(SplayTreeMap<K, V> map) : super(map);
-  V _getValue(_SplayTreeNode<K> node) {
-    _SplayTreeMapNode<K, V> mapNode = node as _SplayTreeMapNode<K, V>;
-    return mapNode.value;
-  }
+  V _getValue(_SplayTreeMapNode<K, V> node) => node.value;
 }
 
-class _SplayTreeNodeIterator<K>
-    extends _SplayTreeIterator<K, _SplayTreeNode<K>> {
-  _SplayTreeNodeIterator(_SplayTree<K, _SplayTreeNode<K>> tree) : super(tree);
-  _SplayTreeNodeIterator.startAt(
-      _SplayTree<K, _SplayTreeNode<K>> tree, K startKey)
+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);
-  _SplayTreeNode<K> _getValue(_SplayTreeNode<K> node) => node;
+  Node _getValue(Node node) => node;
 }
 
 /// A [Set] of objects that can be ordered relative to each other.
@@ -651,12 +683,11 @@
 /// [Comparable], and are compared using their [Comparable.compareTo] method.
 /// Non-comparable objects (including `null`) will not work as an element
 /// in that case.
-class SplayTreeSet<E> extends _SplayTree<E, _SplayTreeNode<E>>
+class SplayTreeSet<E> extends _SplayTree<E, _SplayTreeSetNode<E>>
     with IterableMixin<E>, SetMixin<E> {
-  _SplayTreeNode<E>? _root;
-  final _SplayTreeNode<E> _dummy = _SplayTreeNode<E>(null);
+  _SplayTreeSetNode<E>? _root;
 
-  Comparator<E> _comparator;
+  Comparator<E> _compare;
   _Predicate _validKey;
 
   /// Create a new [SplayTreeSet] with the given compare function.
@@ -684,7 +715,7 @@
   SplayTreeSet(
       [int Function(E key1, E key2)? compare,
       bool Function(dynamic potentialKey)? isValidKey])
-      : _comparator = compare ?? _defaultCompare<E>(),
+      : _compare = compare ?? _defaultCompare<E>(),
         _validKey = isValidKey ?? ((dynamic v) => v is E);
 
   /// Creates a [SplayTreeSet] that contains all [elements].
@@ -703,10 +734,12 @@
   factory SplayTreeSet.from(Iterable elements,
       [int Function(E key1, E key2)? compare,
       bool Function(dynamic potentialKey)? isValidKey]) {
+    if (elements is Iterable<E>) {
+      return SplayTreeSet<E>.of(elements, compare, isValidKey);
+    }
     SplayTreeSet<E> result = SplayTreeSet<E>(compare, isValidKey);
-    for (final element in elements) {
-      E e = element as E;
-      result.add(e);
+    for (var element in elements) {
+      result.add(element as dynamic);
     }
     return result;
   }
@@ -722,14 +755,14 @@
       SplayTreeSet(compare, isValidKey)..addAll(elements);
 
   Set<T> _newSet<T>() =>
-      SplayTreeSet<T>((T a, T b) => _comparator(a as E, b as E), _validKey);
+      SplayTreeSet<T>((T a, T b) => _compare(a as E, b as E), _validKey);
 
   Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
-  int _compare(E e1, E e2) => _comparator(e1, e2);
 
   // From Iterable.
 
-  Iterator<E> get iterator => _SplayTreeKeyIterator<E>(this);
+  Iterator<E> get iterator =>
+      _SplayTreeKeyIterator<E, _SplayTreeSetNode<E>>(this);
 
   int get length => _count;
   bool get isEmpty => _root == null;
@@ -759,7 +792,7 @@
   bool add(E element) {
     int compare = _splay(element);
     if (compare == 0) return false;
-    _addNewRoot(_SplayTreeNode(element), compare);
+    _addNewRoot(_SplayTreeSetNode(element), compare);
     return true;
   }
 
@@ -772,7 +805,7 @@
     for (E element in elements) {
       int compare = _splay(element);
       if (compare != 0) {
-        _addNewRoot(_SplayTreeNode(element), compare);
+        _addNewRoot(_SplayTreeSetNode(element), compare);
       }
     }
   }
@@ -785,7 +818,7 @@
 
   void retainAll(Iterable<Object?> elements) {
     // Build a set with the same sense of equality as this set.
-    SplayTreeSet<E> retainSet = SplayTreeSet<E>(_comparator, _validKey);
+    SplayTreeSet<E> retainSet = SplayTreeSet<E>(_compare, _validKey);
     int modificationCount = _modificationCount;
     for (Object? object in elements) {
       if (modificationCount != _modificationCount) {
@@ -813,7 +846,7 @@
   }
 
   Set<E> intersection(Set<Object?> other) {
-    Set<E> result = SplayTreeSet<E>(_comparator, _validKey);
+    Set<E> result = SplayTreeSet<E>(_compare, _validKey);
     for (E element in this) {
       if (other.contains(element)) result.add(element);
     }
@@ -821,7 +854,7 @@
   }
 
   Set<E> difference(Set<Object?> other) {
-    Set<E> result = SplayTreeSet<E>(_comparator, _validKey);
+    Set<E> result = SplayTreeSet<E>(_compare, _validKey);
     for (E element in this) {
       if (!other.contains(element)) result.add(element);
     }
@@ -833,19 +866,46 @@
   }
 
   SplayTreeSet<E> _clone() {
-    var set = SplayTreeSet<E>(_comparator, _validKey);
+    var set = SplayTreeSet<E>(_compare, _validKey);
     set._count = _count;
-    set._root = _copyNode(_root);
+    set._root = _copyNode<_SplayTreeSetNode<E>>(_root);
     return set;
   }
 
   // Copies the structure of a SplayTree into a new similar structure.
   // Works on _SplayTreeMapNode as well, but only copies the keys,
-  _SplayTreeNode<E>? _copyNode(_SplayTreeNode<E>? node) {
+  _SplayTreeSetNode<E>? _copyNode<Node extends _SplayTreeNode<E, Node>>(
+      Node? node) {
     if (node == null) return null;
-    return _SplayTreeNode<E>(node.key)
-      ..left = _copyNode(node.left)
-      ..right = _copyNode(node.right);
+    // Given a source node and a destination node, copy the left
+    // and right subtrees of the source node into the destination node.
+    // The left subtree is copied recursively, but the right spine
+    // of every subtree is copied iteratively.
+    void copyChildren(Node node, _SplayTreeSetNode<E> dest) {
+      Node? left;
+      Node? right;
+      do {
+        left = node.left;
+        right = node.right;
+        if (left != null) {
+          var newLeft = _SplayTreeSetNode<E>(left.key);
+          dest.left = newLeft;
+          // Recursively copy the left tree.
+          copyChildren(left, newLeft);
+        }
+        if (right != null) {
+          var newRight = _SplayTreeSetNode<E>(right.key);
+          dest.right = newRight;
+          // Set node and dest to copy the right tree iteratively.
+          node = right;
+          dest = newRight;
+        }
+      } while (right != null);
+    }
+
+    var result = _SplayTreeSetNode<E>(node.key);
+    copyChildren(node, result);
+    return result;
   }
 
   void clear() {
diff --git a/sdk_nnbd/lib/convert/base64.dart b/sdk_nnbd/lib/convert/base64.dart
index c36ba1a..0955ca1 100644
--- a/sdk_nnbd/lib/convert/base64.dart
+++ b/sdk_nnbd/lib/convert/base64.dart
@@ -651,10 +651,11 @@
     // all the characters in `charOr` and later validate that all characters
     // were ASCII.
     var charOr = 0;
+    final inverseAlphabet = _Base64Decoder._inverseAlphabet;
     for (var i = start; i < end; i++) {
       var char = input.codeUnitAt(i);
       charOr |= char;
-      var code = _inverseAlphabet[char & asciiMask];
+      var code = inverseAlphabet[char & asciiMask];
       if (code >= 0) {
         bits = ((bits << bitsPerCharacter) | code) & 0xFFFFFF;
         count = (count + 1) & 3;
diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart
index e932223..6d897a0 100644
--- a/sdk_nnbd/lib/convert/json.dart
+++ b/sdk_nnbd/lib/convert/json.dart
@@ -535,11 +535,16 @@
   static const int char_0 = 0x30;
   static const int backslash = 0x5c;
   static const int char_b = 0x62;
+  static const int char_d = 0x64;
   static const int char_f = 0x66;
   static const int char_n = 0x6e;
   static const int char_r = 0x72;
   static const int char_t = 0x74;
   static const int char_u = 0x75;
+  static const int surrogateMin = 0xd800;
+  static const int surrogateMask = 0xfc00;
+  static const int surrogateLead = 0xd800;
+  static const int surrogateTrail = 0xdc00;
 
   /// List of objects currently being traversed. Used to detect cycles.
   final List _seen = [];
@@ -573,7 +578,30 @@
     final length = s.length;
     for (var i = 0; i < length; i++) {
       var charCode = s.codeUnitAt(i);
-      if (charCode > backslash) continue;
+      if (charCode > backslash) {
+        if (charCode >= surrogateMin) {
+          // Possible surrogate. Check if it is unpaired.
+          if (((charCode & surrogateMask) == surrogateLead &&
+                  !(i + 1 < length &&
+                      (s.codeUnitAt(i + 1) & surrogateMask) ==
+                          surrogateTrail)) ||
+              ((charCode & surrogateMask) == surrogateTrail &&
+                  !(i - 1 >= 0 &&
+                      (s.codeUnitAt(i - 1) & surrogateMask) ==
+                          surrogateLead))) {
+            // Lone surrogate.
+            if (i > offset) writeStringSlice(s, offset, i);
+            offset = i + 1;
+            writeCharCode(backslash);
+            writeCharCode(char_u);
+            writeCharCode(char_d);
+            writeCharCode(hexDigit((charCode >> 8) & 0xf));
+            writeCharCode(hexDigit((charCode >> 4) & 0xf));
+            writeCharCode(hexDigit(charCode & 0xf));
+          }
+        }
+        continue;
+      }
       if (charCode < 32) {
         if (i > offset) writeStringSlice(s, offset, i);
         offset = i + 1;
@@ -961,16 +989,22 @@
       if (char <= 0x7f) {
         writeByte(char);
       } else {
-        if ((char & 0xFC00) == 0xD800 && i + 1 < end) {
-          // Lead surrogate.
-          var nextChar = string.codeUnitAt(i + 1);
-          if ((nextChar & 0xFC00) == 0xDC00) {
-            // Tail surrogate.
-            char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
-            writeFourByteCharCode(char);
-            i++;
-            continue;
+        if ((char & 0xF800) == 0xD800) {
+          // Surrogate.
+          if (char < 0xDC00 && i + 1 < end) {
+            // Lead surrogate.
+            var nextChar = string.codeUnitAt(i + 1);
+            if ((nextChar & 0xFC00) == 0xDC00) {
+              // Tail surrogate.
+              char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
+              writeFourByteCharCode(char);
+              i++;
+              continue;
+            }
           }
+          // Unpaired surrogate.
+          writeMultiByteCharCode(unicodeReplacementCharacterRune);
+          continue;
         }
         writeMultiByteCharCode(char);
       }
diff --git a/sdk_nnbd/lib/convert/string_conversion.dart b/sdk_nnbd/lib/convert/string_conversion.dart
index 1d5f038..2315330 100644
--- a/sdk_nnbd/lib/convert/string_conversion.dart
+++ b/sdk_nnbd/lib/convert/string_conversion.dart
@@ -258,12 +258,13 @@
 class _Utf8StringSinkAdapter extends ByteConversionSink {
   final _Utf8Decoder _decoder;
   final Sink<Object?> _sink;
+  final StringSink _stringSink;
 
-  _Utf8StringSinkAdapter(this._sink, StringSink stringSink, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringSink, allowMalformed);
+  _Utf8StringSinkAdapter(this._sink, this._stringSink, bool allowMalformed)
+      : _decoder = _Utf8Decoder(allowMalformed);
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_stringSink);
     _sink.close();
   }
 
@@ -273,7 +274,7 @@
 
   void addSlice(
       List<int> codeUnits, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(codeUnits, startIndex, endIndex);
+    _stringSink.write(_decoder.convertChunked(codeUnits, startIndex, endIndex));
     if (isLast) close();
   }
 }
@@ -291,11 +292,11 @@
 
   _Utf8ConversionSink._(
       this._chunkedSink, StringBuffer stringBuffer, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringBuffer, allowMalformed),
+      : _decoder = _Utf8Decoder(allowMalformed),
         _buffer = stringBuffer;
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_buffer);
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _buffer.clear();
@@ -310,7 +311,7 @@
   }
 
   void addSlice(List<int> chunk, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(chunk, startIndex, endIndex);
+    _buffer.write(_decoder.convertChunked(chunk, startIndex, endIndex));
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
diff --git a/sdk_nnbd/lib/convert/utf.dart b/sdk_nnbd/lib/convert/utf.dart
index d9324f6..f495ac0 100644
--- a/sdk_nnbd/lib/convert/utf.dart
+++ b/sdk_nnbd/lib/convert/utf.dart
@@ -55,13 +55,19 @@
   /// If [allowMalformed] is not given, it defaults to the `allowMalformed` that
   /// was used to instantiate `this`.
   String decode(List<int> codeUnits, {bool? allowMalformed}) {
-    return Utf8Decoder(allowMalformed: allowMalformed ?? _allowMalformed)
-        .convert(codeUnits);
+    // Switch between const objects to avoid allocation.
+    Utf8Decoder decoder = allowMalformed ?? _allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
+    return decoder.convert(codeUnits);
   }
 
   Utf8Encoder get encoder => const Utf8Encoder();
   Utf8Decoder get decoder {
-    return Utf8Decoder(allowMalformed: _allowMalformed);
+    // Switch between const objects to avoid allocation.
+    return _allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
   }
 }
 
@@ -133,6 +139,13 @@
   /// Allow an implementation to pick the most efficient way of storing bytes.
   static Uint8List _createBuffer(int size) => Uint8List(size);
 
+  /// Write a replacement character (U+FFFD). Used for unpaired surrogates.
+  void _writeReplacementCharacter() {
+    _buffer[_bufferIndex++] = 0xEF;
+    _buffer[_bufferIndex++] = 0xBF;
+    _buffer[_bufferIndex++] = 0xBD;
+  }
+
   /// Tries to combine the given [leadingSurrogate] with the [nextCodeUnit] and
   /// writes it to [_buffer].
   ///
@@ -140,8 +153,8 @@
   /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
   /// surrogate and has not been written yet.
   ///
-  /// It is safe to pass 0 for [nextCodeUnit] in which case only the leading
-  /// surrogate is written.
+  /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement
+  /// character is written to represent the unpaired lead surrogate.
   bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
     if (_isTailSurrogate(nextCodeUnit)) {
       var rune = _combineSurrogatePair(leadingSurrogate, nextCodeUnit);
@@ -155,14 +168,8 @@
       _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
       return true;
     } else {
-      // TODO(floitsch): allow to throw on malformed strings.
-      // Encode the half-surrogate directly into UTF-8. This yields
-      // invalid UTF-8, but we started out with invalid UTF-16.
-
-      // Surrogates are always encoded in 3 bytes in UTF-8.
-      _buffer[_bufferIndex++] = 0xE0 | (leadingSurrogate >> 12);
-      _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f);
-      _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f);
+      // Unpaired lead surrogate.
+      _writeReplacementCharacter();
       return false;
     }
   }
@@ -188,12 +195,16 @@
         if (_bufferIndex >= _buffer.length) break;
         _buffer[_bufferIndex++] = codeUnit;
       } else if (_isLeadSurrogate(codeUnit)) {
-        if (_bufferIndex + 3 >= _buffer.length) break;
+        if (_bufferIndex + 4 > _buffer.length) break;
         // Note that it is safe to read the next code unit. We decremented
         // [end] above when the last valid code unit was a leading surrogate.
         var nextCodeUnit = str.codeUnitAt(stringIndex + 1);
         var wasCombined = _writeSurrogate(codeUnit, nextCodeUnit);
         if (wasCombined) stringIndex++;
+      } else if (_isTailSurrogate(codeUnit)) {
+        if (_bufferIndex + 3 > _buffer.length) break;
+        // Unpaired tail surrogate.
+        _writeReplacementCharacter();
       } else {
         var rune = codeUnit;
         if (rune <= _TWO_BYTE_LIMIT) {
@@ -308,33 +319,7 @@
       return result;
     }
 
-    var length = codeUnits.length;
-    end = RangeError.checkValidRange(start, end, length);
-    // TODO(38725): Remove workaround when assignment promotion is implemented
-    if (end == null) {
-      throw RangeError("Invalid range");
-    }
-
-    // Fast case for ASCII strings avoids StringBuffer/_Utf8Decoder.
-    int oneBytes = _scanOneByteCharacters(codeUnits, start, end);
-    StringBuffer buffer;
-    bool isFirstCharacter = true;
-    if (oneBytes > 0) {
-      var firstPart = String.fromCharCodes(codeUnits, start, start + oneBytes);
-      start += oneBytes;
-      if (start == end) {
-        return firstPart;
-      }
-      buffer = StringBuffer(firstPart);
-      isFirstCharacter = false;
-    } else {
-      buffer = StringBuffer();
-    }
-    var decoder = _Utf8Decoder(buffer, _allowMalformed);
-    decoder._isFirstCharacter = isFirstCharacter;
-    decoder.convert(codeUnits, start, end);
-    decoder.flush(codeUnits, end);
-    return buffer.toString();
+    return _Utf8Decoder(_allowMalformed).convertSingle(codeUnits, start, end);
   }
 
   /// Starts a chunked conversion.
@@ -380,185 +365,314 @@
     0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10) |
     (tail & _SURROGATE_VALUE_MASK);
 
-/// Decodes UTF-8.
-///
-/// The decoder handles chunked input.
-// TODO(floitsch): make this class public.
 class _Utf8Decoder {
-  final bool _allowMalformed;
-  final StringSink _stringSink;
-  bool _isFirstCharacter = true;
-  int _value = 0;
-  int _expectedUnits = 0;
-  int _extraUnits = 0;
+  /// Decode malformed UTF-8 as replacement characters (instead of throwing)?
+  final bool allowMalformed;
 
-  _Utf8Decoder(this._stringSink, this._allowMalformed);
+  /// Decoder DFA state.
+  int _state;
 
-  bool get hasPartialInput => _expectedUnits > 0;
+  /// Partially decoded character. Meaning depends on state. Not used when in
+  /// the initial/accept state. When in an error state, contains the index into
+  /// the input of the error.
+  int _charOrIndex = 0;
 
-  // Limits of one through four byte encodings.
-  static const List<int> _LIMITS = <int>[
-    _ONE_BYTE_LIMIT,
-    _TWO_BYTE_LIMIT,
-    _THREE_BYTE_LIMIT,
-    _FOUR_BYTE_LIMIT
-  ];
+  // State machine for UTF-8 decoding, based on this decoder by Björn Höhrmann:
+  // https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+  //
+  // One iteration in the state machine proceeds as:
+  //
+  // type = typeTable[byte];
+  // char = (state != accept)
+  //     ? (byte & 0x3F) | (char << 6)
+  //     : byte & (shiftedByteMask >> type);
+  // state = transitionTable[state + type];
+  //
+  // After each iteration, if state == accept, char is output as a character.
 
-  void close() {
-    flush();
+  // Mask to and on the type read from the table.
+  static const int typeMask = 0x1F;
+  // Mask shifted right by byte type to mask first byte of sequence.
+  static const int shiftedByteMask = 0xF0FE;
+
+  // Byte types.
+  // 'A' = ASCII, 00-7F
+  // 'B' = 2-byte, C2-DF
+  // 'C' = 3-byte, E1-EC, EE
+  // 'D' = 3-byte (possibly surrogate), ED
+  // 'E' = Illegal, C0-C1, F5+
+  // 'F' = Low extension, 80-8F
+  // 'G' = Mid extension, 90-9F
+  // 'H' = High extension, A0-BA, BC-BE
+  // 'I' = Second byte of BOM, BB
+  // 'J' = Third byte of BOM, BF
+  // 'K' = 3-byte (possibly overlong), E0
+  // 'L' = First byte of BOM, EF
+  // 'M' = 4-byte (possibly out-of-range), F4
+  // 'N' = 4-byte, F1-F3
+  // 'O' = 4-byte (possibly overlong), F0
+  static const String typeTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "FFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGG" // 80-9F
+      "HHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJ" // A0-BF
+      "EEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" // C0-DF
+      "KCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE" // E0-FF
+      ;
+
+  // States (offsets into transition table).
+  static const int IA = 0x00; // Initial / Accept
+  static const int BB = 0x10; // Before BOM
+  static const int AB = 0x20; // After BOM
+  static const int X1 = 0x30; // Expecting one extension byte
+  static const int X2 = 0x3A; // Expecting two extension bytes
+  static const int X3 = 0x44; // Expecting three extension bytes
+  static const int TO = 0x4E; // Possibly overlong 3-byte
+  static const int TS = 0x58; // Possibly surrogate
+  static const int QO = 0x62; // Possibly overlong 4-byte
+  static const int QR = 0x6C; // Possibly out-of-range 4-byte
+  static const int B1 = 0x76; // One byte into BOM
+  static const int B2 = 0x80; // Two bytes into BOM
+  static const int E1 = 0x41; // Error: Missing extension byte
+  static const int E2 = 0x43; // Error: Unexpected extension byte
+  static const int E3 = 0x45; // Error: Invalid byte
+  static const int E4 = 0x47; // Error: Overlong encoding
+  static const int E5 = 0x49; // Error: Out of range
+  static const int E6 = 0x4B; // Error: Surrogate
+  static const int E7 = 0x4D; // Error: Unfinished
+
+  // Character equivalents for states.
+  static const String _IA = '\u0000';
+  static const String _BB = '\u0010';
+  static const String _AB = '\u0020';
+  static const String _X1 = '\u0030';
+  static const String _X2 = '\u003A';
+  static const String _X3 = '\u0044';
+  static const String _TO = '\u004E';
+  static const String _TS = '\u0058';
+  static const String _QO = '\u0062';
+  static const String _QR = '\u006C';
+  static const String _B1 = '\u0076';
+  static const String _B2 = '\u0080';
+  static const String _E1 = '\u0041';
+  static const String _E2 = '\u0043';
+  static const String _E3 = '\u0045';
+  static const String _E4 = '\u0047';
+  static const String _E5 = '\u0049';
+  static const String _E6 = '\u004B';
+  static const String _E7 = '\u004D';
+
+  // Transition table of the state machine. Maps state and byte type
+  // to next state.
+  static const String transitionTable = " "
+      // A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // IA
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_B1$_QR$_X3$_QO " // BB
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // AB
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_IA" // Overlap 5 E1s        X1
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_X1$_X1" // Overlap 5 E1s        X2
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_X2$_X2$_X2$_X2" // Overlap 5 E1s        X3
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_E4$_X1$_X1$_X1" // Overlap 5 E1s        TO
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_E6$_E6$_E6" // Overlap 5 E1s        TS
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_X2$_X2$_X2$_X2" // Overlap 5 E1s        QO
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_E5$_E5$_E5$_E5" // Overlap 5 E1s        QR
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_B2$_X1" // Overlap 5 E1s        B1
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_AB$_E1$_E1$_E1$_E1$_E1" //  B2
+      ;
+
+  // Aliases for states.
+  static const int initial = IA;
+  static const int accept = IA;
+  static const int beforeBom = BB;
+  static const int afterBom = AB;
+  static const int errorMissingExtension = E1;
+  static const int errorUnexpectedExtension = E2;
+  static const int errorInvalid = E3;
+  static const int errorOverlong = E4;
+  static const int errorOutOfRange = E5;
+  static const int errorSurrogate = E6;
+  static const int errorUnfinished = E7;
+
+  static bool isErrorState(int state) => (state & 1) != 0;
+
+  static String errorDescription(int state) {
+    switch (state) {
+      case errorMissingExtension:
+        return "Missing extension byte";
+      case errorUnexpectedExtension:
+        return "Unexpected extension byte";
+      case errorInvalid:
+        return "Invalid UTF-8 byte";
+      case errorOverlong:
+        return "Overlong encoding";
+      case errorOutOfRange:
+        return "Out of unicode range";
+      case errorSurrogate:
+        return "Encoded surrogate";
+      case errorUnfinished:
+        return "Unfinished UTF-8 octet sequence";
+      default:
+        return "";
+    }
+  }
+
+  external _Utf8Decoder(bool allowMalformed);
+
+  external String convertSingle(List<int> codeUnits, int start, int? maybeEnd);
+
+  external String convertChunked(List<int> codeUnits, int start, int? maybeEnd);
+
+  String convertGeneral(
+      List<int> codeUnits, int start, int? maybeEnd, bool single) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    if (start == end) return "";
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    String result = decodeGeneral(bytes, start, end, single);
+    if (isErrorState(_state)) {
+      String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+    return result;
   }
 
   /// Flushes this decoder as if closed.
   ///
   /// This method throws if the input was partial and the decoder was
   /// constructed with `allowMalformed` set to `false`.
-  ///
-  /// The [source] and [offset] of the current position may be provided,
-  /// and are included in the exception if one is thrown.
-  void flush([List<int>? source, int? offset]) {
-    if (hasPartialInput) {
-      if (!_allowMalformed) {
-        throw FormatException(
-            "Unfinished UTF-8 octet sequence", source, offset);
-      }
-      _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-      _value = 0;
-      _expectedUnits = 0;
-      _extraUnits = 0;
+  void flush(StringSink sink) {
+    final int state = _state;
+    _state = initial;
+    if (state <= afterBom) {
+      return;
+    }
+    // Unfinished sequence.
+    if (allowMalformed) {
+      sink.writeCharCode(unicodeReplacementCharacterRune);
+    } else {
+      throw FormatException(errorDescription(errorUnfinished), null, null);
     }
   }
 
-  void convert(List<int> codeUnits, int startIndex, int endIndex) {
-    var value = _value;
-    var expectedUnits = _expectedUnits;
-    var extraUnits = _extraUnits;
-    _value = 0;
-    _expectedUnits = 0;
-    _extraUnits = 0;
-
-    var i = startIndex;
+  String decodeGeneral(Uint8List bytes, int start, int end, bool single) {
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    int state = _state;
+    int char = _charOrIndex;
+    final StringBuffer buffer = StringBuffer();
+    int i = start;
+    int byte = bytes[i++];
     loop:
     while (true) {
       multibyte:
-      if (expectedUnits > 0) {
-        do {
-          if (i == endIndex) {
-            break loop;
-          }
-          var unit = codeUnits[i];
-          if ((unit & 0xC0) != 0x80) {
-            expectedUnits = 0;
-            if (!_allowMalformed) {
-              throw FormatException(
-                  "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                  codeUnits,
-                  i);
+      while (true) {
+        int type = typeTable.codeUnitAt(byte) & typeMask;
+        char = (state <= afterBom)
+            ? byte & (shiftedByteMask >> type)
+            : (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+        if (state == accept) {
+          buffer.writeCharCode(char);
+          if (i == end) break loop;
+          break multibyte;
+        } else if (isErrorState(state)) {
+          if (allowMalformed) {
+            switch (state) {
+              case errorInvalid:
+              case errorUnexpectedExtension:
+                // A single byte that can't start a sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
+              case errorMissingExtension:
+                // Unfinished sequence followed by a byte that can start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                // Re-parse offending byte.
+                i -= 1;
+                break;
+              default:
+                // Unfinished sequence followed by a byte that can't start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
             }
-            _isFirstCharacter = false;
-            _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-            break multibyte;
+            state = initial;
           } else {
-            value = (value << 6) | (unit & 0x3f);
-            expectedUnits--;
-            i++;
+            _state = state;
+            _charOrIndex = i - 1;
+            return "";
           }
-        } while (expectedUnits > 0);
-        if (value <= _LIMITS[extraUnits - 1]) {
-          // Overly long encoding. The value could be encoded with a shorter
-          // encoding.
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Overlong encoding of 0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          expectedUnits = extraUnits = 0;
-          value = unicodeReplacementCharacterRune;
         }
-        if (value > _FOUR_BYTE_LIMIT) {
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Character outside valid Unicode range: "
-                "0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-        }
-        if (!_isFirstCharacter || value != unicodeBomCharacterRune) {
-          _stringSink.writeCharCode(value);
-        }
-        _isFirstCharacter = false;
+        if (i == end) break loop;
+        byte = bytes[i++];
       }
 
-      while (i < endIndex) {
-        var oneBytes = _scanOneByteCharacters(codeUnits, i, endIndex);
-        if (oneBytes > 0) {
-          _isFirstCharacter = false;
-          assert(i + oneBytes <= endIndex);
-          _stringSink.write(String.fromCharCodes(codeUnits, i, i + oneBytes));
-
-          i += oneBytes;
-          if (i == endIndex) break;
-        }
-        var unit = codeUnits[i++];
-        // TODO(floitsch): the way we test we could potentially allow
-        // units that are too large, if they happen to have the
-        // right bit-pattern. (Same is true for the multibyte loop above).
-        // TODO(floitsch): optimize this loop. See:
-        // https://codereview.chromium.org/22929022/diff/1/sdk/lib/convert/utf.dart?column_width=80
-        if (unit < 0) {
-          // TODO(floitsch): should this be unit <= 0 ?
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}",
-                codeUnits,
-                i - 1);
+      final int markStart = i;
+      byte = bytes[i++];
+      if (byte < 128) {
+        int markEnd = end;
+        while (i < end) {
+          byte = bytes[i++];
+          if (byte >= 128) {
+            markEnd = i - 1;
+            break;
           }
-          _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+        }
+        assert(markStart < markEnd);
+        if (markEnd - markStart < 20) {
+          for (int m = markStart; m < markEnd; m++) {
+            buffer.writeCharCode(bytes[m]);
+          }
         } else {
-          assert(unit > _ONE_BYTE_LIMIT);
-          if ((unit & 0xE0) == 0xC0) {
-            value = unit & 0x1F;
-            expectedUnits = extraUnits = 1;
-            continue loop;
-          }
-          if ((unit & 0xF0) == 0xE0) {
-            value = unit & 0x0F;
-            expectedUnits = extraUnits = 2;
-            continue loop;
-          }
-          // 0xF5, 0xF6 ... 0xFF never appear in valid UTF-8 sequences.
-          if ((unit & 0xF8) == 0xF0 && unit < 0xF5) {
-            value = unit & 0x07;
-            expectedUnits = extraUnits = 3;
-            continue loop;
-          }
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                codeUnits,
-                i - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-          expectedUnits = extraUnits = 0;
-          _isFirstCharacter = false;
-          _stringSink.writeCharCode(value);
+          buffer.write(String.fromCharCodes(bytes, markStart, markEnd));
         }
+        if (markEnd == end) break loop;
       }
-      break loop;
     }
-    if (expectedUnits > 0) {
-      _value = value;
-      _expectedUnits = expectedUnits;
-      _extraUnits = extraUnits;
+
+    if (single && state > afterBom) {
+      // Unfinished sequence.
+      if (allowMalformed) {
+        buffer.writeCharCode(unicodeReplacementCharacterRune);
+      } else {
+        _state = errorUnfinished;
+        _charOrIndex = end;
+        return "";
+      }
     }
+    _state = state;
+    _charOrIndex = char;
+    return buffer.toString();
+  }
+
+  static Uint8List _makeUint8List(List<int> codeUnits, int start, int end) {
+    final int length = end - start;
+    final Uint8List bytes = Uint8List(length);
+    for (int i = 0; i < length; i++) {
+      int b = codeUnits[start + i];
+      if ((b & ~0xFF) != 0) {
+        // Replace invalid byte values by FF, which is also invalid.
+        b = 0xFF;
+      }
+      bytes[i] = b;
+    }
+    return bytes;
   }
 }
-
-// Returns the number of bytes in [units] starting at offset [from] which have
-// the leftmost bit set to 0.
-//
-// To increase performance of this critical method we have a special variant of
-// it implemented in the VM's patch files, which is why we make it external.
-external int _scanOneByteCharacters(List<int> units, int from, int endIndex);
diff --git a/sdk_nnbd/lib/core/int.dart b/sdk_nnbd/lib/core/int.dart
index 42af709..b1203ed 100644
--- a/sdk_nnbd/lib/core/int.dart
+++ b/sdk_nnbd/lib/core/int.dart
@@ -52,7 +52,7 @@
    * integers, the result is a number with only the bits set that are set in
    * both `this` and [other]
    *
-   * Of both operands are negative, the result is negative, otherwise
+   * If both operands are negative, the result is negative, otherwise
    * the result is non-negative.
    */
   int operator &(int other);
diff --git a/sdk_nnbd/lib/developer/service.dart b/sdk_nnbd/lib/developer/service.dart
index 9fab7f4..6d90667 100644
--- a/sdk_nnbd/lib/developer/service.dart
+++ b/sdk_nnbd/lib/developer/service.dart
@@ -42,12 +42,12 @@
   static Future<ServiceProtocolInfo> getInfo() async {
     // Port to receive response from service isolate.
     final RawReceivePort receivePort = new RawReceivePort();
-    final Completer<Uri> uriCompleter = new Completer<Uri>();
-    receivePort.handler = (Uri uri) => uriCompleter.complete(uri);
+    final Completer<Uri?> uriCompleter = new Completer<Uri?>();
+    receivePort.handler = (Uri? uri) => uriCompleter.complete(uri);
     // Request the information from the service isolate.
     _getServerInfo(receivePort.sendPort);
     // Await the response from the service isolate.
-    Uri uri = await uriCompleter.future;
+    Uri? uri = await uriCompleter.future;
     // Close the port.
     receivePort.close();
     return new ServiceProtocolInfo(uri);
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index 17aa9d8..0a6e37b 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -4049,7 +4049,7 @@
 
   String get cssFloat native;
 
-  set cssFloat(String value) native;
+  set cssFloat(String? value) native;
 
   String get cssText native;
 
@@ -10448,13 +10448,13 @@
     implements NonElementParentNode, ParentNode {
   factory DocumentFragment() => document.createDocumentFragment();
 
-  factory DocumentFragment.html(String html,
+  factory DocumentFragment.html(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     return document.body!.createFragment(html,
         validator: validator, treeSanitizer: treeSanitizer);
   }
 
-  factory DocumentFragment.svg(String svgContent,
+  factory DocumentFragment.svg(String? svgContent,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     return new svg.SvgSvgElement().createFragment(svgContent,
         validator: validator, treeSanitizer: treeSanitizer);
@@ -10503,11 +10503,11 @@
     return e.innerHtml;
   }
 
-  set innerHtml(String value) {
+  set innerHtml(String? value) {
     this.setInnerHtml(value);
   }
 
-  void setInnerHtml(String html,
+  void setInnerHtml(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     this.nodes.clear();
     append(document.body!.createFragment(html,
@@ -11795,6 +11795,10 @@
     }
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
   void setAll(int index, Iterable<Element> iterable) {
     throw new UnimplementedError();
   }
@@ -11805,6 +11809,7 @@
 
   Element removeAt(int index) {
     final result = this[index];
+    // TODO(41258): Remove null check after unfork/strong mode.
     if (result != null) {
       _element._removeChild(result);
     }
@@ -11813,9 +11818,7 @@
 
   Element removeLast() {
     final result = this.last;
-    if (result != null) {
-      _element._removeChild(result);
-    }
+    _element._removeChild(result);
     return result;
   }
 
@@ -12661,7 +12664,7 @@
    * * [NodeValidator]
    *
    */
-  factory Element.html(String html,
+  factory Element.html(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     var fragment = document.body!.createFragment(html,
         validator: validator, treeSanitizer: treeSanitizer);
@@ -12881,6 +12884,7 @@
 
   @pragma('dart2js:tryInline')
   String? getAttribute(String name) {
+    // TODO(41258): Delete this assertion after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     return _getAttribute(name);
@@ -12888,6 +12892,7 @@
 
   @pragma('dart2js:tryInline')
   String? getAttributeNS(String? namespaceURI, String name) {
+    // TODO(41258): Delete this assertion after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
     assert(name != null, 'Attribute name cannot be null');
@@ -12896,6 +12901,7 @@
 
   @pragma('dart2js:tryInline')
   bool hasAttribute(String name) {
+    // TODO(41258): Delete this assertion after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     return _hasAttribute(name);
@@ -12903,6 +12909,7 @@
 
   @pragma('dart2js:tryInline')
   bool hasAttributeNS(String? namespaceURI, String name) {
+    // TODO(41258): Delete this assertion after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
     assert(name != null, 'Attribute name cannot be null');
@@ -12911,6 +12918,7 @@
 
   @pragma('dart2js:tryInline')
   void removeAttribute(String name) {
+    // TODO(41258): Delete this assertion after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     _removeAttribute(name);
@@ -12918,6 +12926,7 @@
 
   @pragma('dart2js:tryInline')
   void removeAttributeNS(String? namespaceURI, String name) {
+    // TODO(41258): Delete this assertion after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     _removeAttributeNS(namespaceURI, name);
@@ -12925,6 +12934,7 @@
 
   @pragma('dart2js:tryInline')
   void setAttribute(String name, String value) {
+    // TODO(41258): Delete these assertions after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
@@ -12933,6 +12943,7 @@
 
   @pragma('dart2js:tryInline')
   void setAttributeNS(String? namespaceURI, String name, String value) {
+    // TODO(41258): Delete these assertions after forcing strong mode.
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
@@ -13615,7 +13626,7 @@
    * * [NodeValidator]
    * * [NodeTreeSanitizer]
    */
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     if (treeSanitizer == null) {
       if (validator == null) {
@@ -13663,7 +13674,7 @@
     if (Range.supportsCreateContextualFragment &&
         _canBeUsedToCreateContextualFragment) {
       _parseRange!.selectNodeContents(contextElement);
-      fragment = _parseRange!.createContextualFragment(html);
+      fragment = _parseRange!.createContextualFragment(html!);
     } else {
       contextElement._innerHtml = html;
 
@@ -13726,7 +13737,7 @@
    * This uses the default sanitization behavior to sanitize the HTML fragment,
    * use [setInnerHtml] to override the default behavior.
    */
-  set innerHtml(String html) {
+  set innerHtml(String? html) {
     this.setInnerHtml(html);
   }
 
@@ -13751,7 +13762,7 @@
    * * [NodeValidator]
    * * [NodeTreeSanitizer]
    */
-  void setInnerHtml(String html,
+  void setInnerHtml(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     text = null;
     if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
@@ -14551,7 +14562,7 @@
   String get _innerHtml native;
 
   @JSName('innerHTML')
-  set _innerHtml(String value) native;
+  set _innerHtml(String? value) native;
 
   @JSName('localName')
   String get _localName native;
@@ -19185,7 +19196,7 @@
 
   String get value native;
 
-  set value(String value) native;
+  set value(String? value) native;
 
   DateTime get valueAsDate =>
       convertNativeToDart_DateTime(this._get_valueAsDate);
@@ -19266,7 +19277,7 @@
   set name(String value);
 
   String get value;
-  set value(String value);
+  set value(String? value);
 
   List<Node> get labels;
 
@@ -22514,7 +22525,7 @@
         NavigatorOnLine,
         NavigatorAutomationInformation,
         NavigatorID {
-  List<Gamepad> getGamepads() {
+  List<Gamepad?> getGamepads() {
     var gamepadList = _getGamepads();
 
     // If no prototype we need one for the world to hookup to the proper Dart class.
@@ -22666,7 +22677,7 @@
   @JSName('getGamepads')
   @Returns('_GamepadList')
   @Creates('_GamepadList')
-  List<Gamepad> _getGamepads() native;
+  List<Gamepad?> _getGamepads() native;
 
   Future<RelatedApplication> getInstalledRelatedApps() =>
       promiseToFuture<RelatedApplication>(
@@ -27847,7 +27858,7 @@
   String get innerHtml native;
 
   @JSName('innerHTML')
-  set innerHtml(String value) native;
+  set innerHtml(String? value) native;
 
   String get mode native;
 
@@ -29255,7 +29266,7 @@
 
   String get headers native;
 
-  set headers(String value) native;
+  set headers(String? value) native;
 
   int get rowSpan native;
 
@@ -29321,7 +29332,7 @@
   @JSName('createTBody')
   TableSectionElement _nativeCreateTBody() native;
 
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     if (Range.supportsCreateContextualFragment) {
       return super.createFragment(html,
@@ -29412,7 +29423,7 @@
   TableCellElement insertCell(int index) =>
       _insertCell(index) as TableCellElement;
 
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     if (Range.supportsCreateContextualFragment) {
       return super.createFragment(html,
@@ -29475,7 +29486,7 @@
 
   TableRowElement insertRow(int index) => _insertRow(index) as TableRowElement;
 
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     if (Range.supportsCreateContextualFragment) {
       return super.createFragment(html,
@@ -29570,7 +29581,7 @@
    *
    * * <https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin>
    */
-  void setInnerHtml(String html,
+  void setInnerHtml(String? html,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     text = null;
     content.nodes.clear();
@@ -29712,7 +29723,7 @@
 
   String get value native;
 
-  set value(String value) native;
+  set value(String? value) native;
 
   bool get willValidate native;
 
@@ -32703,7 +32714,7 @@
   @Returns('Window|=Object')
   dynamic get _get_top native;
 
-  VisualViewport get visualViewport native;
+  VisualViewport? get visualViewport native;
 
   /**
    * The current window.
@@ -35685,7 +35696,7 @@
   _ElementAttributeMap(Element element) : super(element);
 
   bool containsKey(Object? key) {
-    return _element._hasAttribute(key as String);
+    return key is String && _element._hasAttribute(key);
   }
 
   String? operator [](Object? key) {
@@ -35711,8 +35722,8 @@
   // Inline this because almost all call sites of [remove] do not use [value],
   // and the annotations on the `getAttribute` call allow it to be removed.
   @pragma('dart2js:tryInline')
-  static String _remove(Element element, String key) {
-    String value = JS(
+  static String? _remove(Element element, String key) {
+    String? value = JS(
         // throws:null(1) is not accurate since [key] could be malformed, but
         // [key] is checked again by `removeAttributeNS`.
         'returns:String|Null;depends:all;effects:none;throws:null(1)',
@@ -35728,12 +35739,12 @@
  * Wrapper to expose namespaced attributes as a typed map.
  */
 class _NamespacedAttributeMap extends _AttributeMap {
-  final String _namespace;
+  final String? _namespace;
 
   _NamespacedAttributeMap(Element element, this._namespace) : super(element);
 
   bool containsKey(Object? key) {
-    return _element._hasAttributeNS(_namespace, key as String);
+    return key is String && _element._hasAttributeNS(_namespace, key);
   }
 
   String? operator [](Object? key) {
@@ -35761,8 +35772,8 @@
   // returned [value], and the annotations on the `getAttributeNS` call allow it
   // to be removed.
   @pragma('dart2js:tryInline')
-  static String _remove(String namespace, Element element, String key) {
-    String value = JS(
+  static String? _remove(String? namespace, Element element, String key) {
+    String? value = JS(
         // throws:null(1) is not accurate since [key] could be malformed, but
         // [key] is checked again by `removeAttributeNS`.
         'returns:String|Null;depends:all;effects:none;throws:null(1)',
@@ -36097,7 +36108,8 @@
    * after the operation, and returns `false` if [value] is absent after the
    * operation.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To toggle multiple classes, use
@@ -36131,7 +36143,8 @@
    * If this CssClassSet corresponds to one element. Returns true if [value] was
    * added to the set, otherwise false.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To add multiple classes use
@@ -40378,7 +40391,7 @@
       view = window;
     }
 
-    var eventObj;
+    dynamic eventObj;
 
     // Currently this works on everything but Safari. Safari throws an
     // "Attempting to change access mechanism for an unconfigurable property"
@@ -40622,14 +40635,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.
 
-void Function(T)? _wrapZone<T>(void Function(T) callback) {
+void Function(T)? _wrapZone<T>(void Function(T)? callback) {
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.root) return callback;
   if (callback == null) return null;
   return Zone.current.bindUnaryCallbackGuarded(callback);
 }
 
-void Function(T1, T2)? _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
+void Function(T1, T2)? _wrapBinaryZone<T1, T2>(
+    void Function(T1, T2)? callback) {
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.root) return callback;
   if (callback == null) return null;
@@ -40944,7 +40958,7 @@
   /// important attributes we want to check, remove it if it's not valid
   /// or not allowed, either as a whole or particular attributes.
   void _sanitizeElement(Element element, Node? parent, bool corrupted,
-      String text, String tag, Map attrs, String isAttr) {
+      String text, String tag, Map attrs, String? isAttr) {
     if (false != corrupted) {
       _removeNode(element, parent);
       window.console
diff --git a/sdk_nnbd/lib/html/html_common/css_class_set.dart b/sdk_nnbd/lib/html/html_common/css_class_set.dart
index 3421b75..ff15a4d 100644
--- a/sdk_nnbd/lib/html/html_common/css_class_set.dart
+++ b/sdk_nnbd/lib/html/html_common/css_class_set.dart
@@ -108,7 +108,7 @@
     _validateToken(value);
     // TODO - figure out if we need to do any validation here
     // or if the browser natively does enough.
-    return modify((s) => s.add(value));
+    return modify((s) => s.add(value)) ?? false;
   }
 
   /**
diff --git a/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 4bbd020..4cb159b 100644
--- a/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1002,7 +1002,7 @@
     request.onError.listen(controller.addError);
 
     request.onSuccess.listen((e) {
-      T cursor = request.result as dynamic;
+      T? cursor = request.result as dynamic;
       if (cursor == null) {
         controller.close();
       } else {
diff --git a/sdk_nnbd/lib/internal/internal.dart b/sdk_nnbd/lib/internal/internal.dart
index a18f40d..dad3b05 100644
--- a/sdk_nnbd/lib/internal/internal.dart
+++ b/sdk_nnbd/lib/internal/internal.dart
@@ -18,16 +18,21 @@
 import 'dart:core' hide Symbol;
 import 'dart:core' as core show Symbol;
 import 'dart:math' show Random;
+import 'dart:typed_data' show Uint8List;
 
 part 'async_cast.dart';
 part 'cast.dart';
 part 'errors.dart';
 part 'iterable.dart';
 part 'list.dart';
+part 'linked_list.dart';
 part 'print.dart';
 part 'sort.dart';
 part 'symbol.dart';
-part 'linked_list.dart';
+
+// Returns true iff `null as T` will succeed based on the
+// execution mode.
+external bool typeAcceptsNull<T>();
 
 // Powers of 10 up to 10^22 are representable as doubles.
 // Powers of 10 above that are only approximate due to lack of precission.
diff --git a/sdk_nnbd/lib/io/common.dart b/sdk_nnbd/lib/io/common.dart
index e6a56bc..dd4e46f 100644
--- a/sdk_nnbd/lib/io/common.dart
+++ b/sdk_nnbd/lib/io/common.dart
@@ -50,7 +50,7 @@
   * operating system.
   */
 @pragma("vm:entry-point")
-class OSError {
+class OSError implements Exception {
   /** Constant used to indicate that no OS error code is available. */
   static const int noErrorCode = -1;
 
diff --git a/sdk_nnbd/lib/io/file_impl.dart b/sdk_nnbd/lib/io/file_impl.dart
index 7be1bf3..ee34b7d 100644
--- a/sdk_nnbd/lib/io/file_impl.dart
+++ b/sdk_nnbd/lib/io/file_impl.dart
@@ -166,8 +166,8 @@
   _FileStreamConsumer.fromStdio(int fd)
       : _openFuture = new Future.value(_File._openStdioSync(fd));
 
-  Future<File> addStream(Stream<List<int>> stream) {
-    Completer<File> completer = new Completer<File>.sync();
+  Future<File?> addStream(Stream<List<int>> stream) {
+    Completer<File?> completer = new Completer<File?>.sync();
     _openFuture.then((openedFile) {
       late StreamSubscription<List<int>> _subscription;
       void error(e, StackTrace stackTrace) {
@@ -770,7 +770,7 @@
     if (end == start) {
       return new Future.value(0);
     }
-    int length = end! - start;
+    int length = end - start;
     return _dispatch(_IOService.fileReadInto, [null, length]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "readInto failed", path);
@@ -791,7 +791,7 @@
     if (end == start) {
       return 0;
     }
-    var result = _ops.readInto(buffer, start, end!);
+    var result = _ops.readInto(buffer, start, end);
     if (result is OSError) {
       throw new FileSystemException("readInto failed", path, result);
     }
@@ -834,7 +834,7 @@
     }
     _BufferAndStart result;
     try {
-      result = _ensureFastAndSerializableByteData(buffer, start, end!);
+      result = _ensureFastAndSerializableByteData(buffer, start, end);
     } catch (e) {
       return new Future.error(e);
     }
@@ -863,7 +863,7 @@
       return;
     }
     _BufferAndStart bufferAndStart =
-        _ensureFastAndSerializableByteData(buffer, start, end!);
+        _ensureFastAndSerializableByteData(buffer, start, end);
     var result = _ops.writeFrom(bufferAndStart.buffer, bufferAndStart.start,
         end - (start - bufferAndStart.start));
     if (result is OSError) {
diff --git a/sdk_nnbd/lib/io/io_sink.dart b/sdk_nnbd/lib/io/io_sink.dart
index d4a3ec8..622656a 100644
--- a/sdk_nnbd/lib/io/io_sink.dart
+++ b/sdk_nnbd/lib/io/io_sink.dart
@@ -31,8 +31,7 @@
    * The [Encoding] used when writing strings. Depending on the
    * underlying consumer this property might be mutable.
    */
-  Encoding get encoding;
-  void set encoding(Encoding newEncoding);
+  late Encoding encoding;
 
   /**
    * Adds byte [data] to the target consumer, ignoring [encoding].
diff --git a/sdk_nnbd/lib/io/network_profiling.dart b/sdk_nnbd/lib/io/network_profiling.dart
index 87d6527..59c47f4 100644
--- a/sdk_nnbd/lib/io/network_profiling.dart
+++ b/sdk_nnbd/lib/io/network_profiling.dart
@@ -221,8 +221,8 @@
     final map = <String, dynamic>{
       'id': id,
     };
-    _setIfNotNull(map, 'startTime', startTime.toString());
-    _setIfNotNull(map, 'endTime', endTime.toString());
+    _setIfNotNull(map, 'startTime', startTime);
+    _setIfNotNull(map, 'endTime', endTime);
     _setIfNotNull(map, 'address', address);
     _setIfNotNull(map, 'port', port);
     _setIfNotNull(map, 'socketType', socketType);
diff --git a/sdk_nnbd/lib/io/secure_socket.dart b/sdk_nnbd/lib/io/secure_socket.dart
index fef9d16..08e9bf7 100644
--- a/sdk_nnbd/lib/io/secure_socket.dart
+++ b/sdk_nnbd/lib/io/secure_socket.dart
@@ -113,7 +113,7 @@
     return ((socket as dynamic /*_Socket*/)._detachRaw() as Future)
         .then<RawSecureSocket>((detachedRaw) {
       return RawSecureSocket.secure(detachedRaw[0] as RawSocket,
-          subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>,
+          subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>?,
           host: host,
           context: context,
           onBadCertificate: onBadCertificate,
@@ -151,7 +151,7 @@
     return ((socket as dynamic /*_Socket*/)._detachRaw() as Future)
         .then<RawSecureSocket>((detachedRaw) {
       return RawSecureSocket.secureServer(detachedRaw[0] as RawSocket, context,
-          subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>,
+          subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>?,
           bufferedData: bufferedData,
           requestClientCertificate: requestClientCertificate,
           requireClientCertificate: requireClientCertificate,
@@ -1236,7 +1236,7 @@
       Uint8List protocols);
   void destroy();
   void handshake();
-  String selectedProtocol();
+  String? selectedProtocol();
   void rehandshake();
   void renegotiate(bool useSessionCache, bool requestClientCertificate,
       bool requireClientCertificate);
diff --git a/sdk_nnbd/lib/io/socket.dart b/sdk_nnbd/lib/io/socket.dart
index bf1e209..b5e814f 100644
--- a/sdk_nnbd/lib/io/socket.dart
+++ b/sdk_nnbd/lib/io/socket.dart
@@ -213,6 +213,12 @@
    */
   external static InternetAddress _cloneWithNewHost(
       InternetAddress address, String host);
+
+  /// Attempts to parse [address] as a numeric address.
+  ///
+  /// Returns `null` If [address] is not a numeric IPv4 (dotted-decimal
+  /// notation) or IPv6 (hexadecimal representation) address.
+  external static InternetAddress? tryParse(String address);
 }
 
 /**
diff --git a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
index 8eaabef..0ca84b9 100644
--- a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
@@ -3037,11 +3037,11 @@
     return container.innerHtml;
   }
 
-  set innerHtml(String value) {
+  set innerHtml(String? value) {
     this.setInnerHtml(value);
   }
 
-  DocumentFragment createFragment(String svg,
+  DocumentFragment createFragment(String? svg,
       {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
     if (treeSanitizer == null) {
       if (validator == null) {
diff --git a/sdk_nnbd/lib/vmservice/running_isolate.dart b/sdk_nnbd/lib/vmservice/running_isolate.dart
index 9de347f..029c6aa 100644
--- a/sdk_nnbd/lib/vmservice/running_isolate.dart
+++ b/sdk_nnbd/lib/vmservice/running_isolate.dart
@@ -105,7 +105,7 @@
     var pauseType;
     try {
       pauseType = await _isolatePauseType(service, message.params['isolateId']);
-    } catch (errorResponse) {
+    } on Response catch (errorResponse) {
       return errorResponse;
     }
     if (pauseType == kInvalidPauseEvent ||
diff --git a/sdk_nnbd/lib/vmservice/vmservice.dart b/sdk_nnbd/lib/vmservice/vmservice.dart
index f5a176e..4b2988a 100644
--- a/sdk_nnbd/lib/vmservice/vmservice.dart
+++ b/sdk_nnbd/lib/vmservice/vmservice.dart
@@ -46,7 +46,8 @@
 // the cleanup method will be invoked after being removed from the map.
 final isolateEmbedderData = <int, IsolateEmbedderData>{};
 
-// These must be kept in sync with the declarations in vm/json_stream.h.
+// These must be kept in sync with the declarations in vm/json_stream.h and
+// pkg/dds/lib/src/stream_manager.dart.
 const kParseError = -32700;
 const kInvalidRequest = -32600;
 const kMethodNotFound = -32601;
@@ -168,6 +169,10 @@
 /// Called when we want to [enable] or disable the web server.
 typedef Future<Uri?> WebServerControlCallback(bool enable);
 
+/// Called when we want to [enable] or disable new websocket connections to the
+/// server.
+typedef void WebServerAcceptNewWebSocketConnectionsCallback(bool enable);
+
 /// Hooks that are setup by the embedder.
 class VMServiceEmbedderHooks {
   static ServerStartCallback? serverStart;
@@ -181,6 +186,8 @@
   static ListFilesCallback? listFiles;
   static ServerInformationCallback? serverInformation;
   static WebServerControlCallback? webServerControl;
+  static WebServerAcceptNewWebSocketConnectionsCallback?
+      acceptNewWebSocketConnections;
 }
 
 class _ClientResumePermissions {
@@ -212,6 +219,33 @@
 
   final devfs = DevFS();
 
+  Uri get ddsUri => _ddsUri!;
+  Uri? _ddsUri;
+
+  Future<String> _yieldControlToDDS(Message message) async {
+    final acceptNewWebSocketConnections =
+        VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+    if (acceptNewWebSocketConnections == null) {
+      return encodeRpcError(message, kFeatureDisabled,
+          details:
+              'Embedder does not support yielding to a VM service intermediary.');
+    }
+    final uri = message.params['uri'];
+    if (uri == null) {
+      return encodeMissingParamError(message, 'uri');
+    }
+    // DDS can only take control if there is no other clients connected
+    // directly to the VM service.
+    if (clients.length > 1) {
+      return encodeRpcError(message, kFeatureDisabled,
+          details:
+              'Existing VM service clients prevent DDS from taking control.');
+    }
+    acceptNewWebSocketConnections(false);
+    _ddsUri = Uri.parse(uri);
+    return encodeSuccess(message);
+  }
+
   void _clearClientName(Client client) {
     final name = client.name;
     client.name = null;
@@ -350,6 +384,16 @@
     for (final handle in client.serviceHandles.values) {
       handle(null);
     }
+    if (clients.isEmpty) {
+      // If DDS was connected, we are in single client mode and need to
+      // allow for new websocket connections.
+      final acceptNewWebSocketConnections =
+          VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+      if (_ddsUri != null && acceptNewWebSocketConnections != null) {
+        acceptNewWebSocketConnections(true);
+        _ddsUri = null;
+      }
+    }
   }
 
   void _eventMessageHandler(String streamId, Response event) {
@@ -662,45 +706,6 @@
         details: 'Unknown service: ${message.method}');
   }
 
-  Future<String> _spawnUri(Message message) async {
-    final token = message.params['token'];
-    if (token == null) {
-      return encodeMissingParamError(message, 'token');
-    }
-    if (token is! String) {
-      return encodeInvalidParamError(message, 'token');
-    }
-    final uri = message.params['uri'];
-    if (uri == null) {
-      return encodeMissingParamError(message, 'uri');
-    }
-    if (uri is! String) {
-      return encodeInvalidParamError(message, 'uri');
-    }
-    final args = message.params['args'];
-    final argsOfString = <String>[];
-    if (args != null) {
-      if (args is! List) {
-        return encodeInvalidParamError(message, 'args');
-      }
-      for (final arg in args) {
-        if (arg is! String) {
-          return encodeInvalidParamError(message, 'args');
-        }
-        argsOfString.add(arg);
-      }
-    }
-    final msg = message.params['message'];
-
-    Isolate.spawnUri(Uri.parse(uri), argsOfString, msg).then((isolate) {
-      _spawnUriNotify(isolate.controlPort, token);
-    }).catchError((e) {
-      _spawnUriNotify(e.toString(), token);
-    });
-
-    return encodeSuccess(message);
-  }
-
   Future<Response?> routeRequest(VMService _, Message message) async {
     final response = await _routeRequestImpl(message);
     if (response == null) {
@@ -716,6 +721,9 @@
       if (message.completed) {
         return await message.response;
       }
+      if (message.method == '_yieldControlToDDS') {
+        return await _yieldControlToDDS(message);
+      }
       if (message.method == 'streamListen') {
         return await _streamListen(message);
       }
@@ -725,9 +733,6 @@
       if (message.method == 'registerService') {
         return await _registerService(message);
       }
-      if (message.method == '_spawnUri') {
-        return await _spawnUri(message);
-      }
       if (message.method == 'setClientName') {
         return _setClientName(message);
       }
@@ -792,6 +797,3 @@
 
 /// Get the bytes to the tar archive.
 Uint8List _requestAssets() native 'VMService_RequestAssets';
-
-/// Notify the vm service that an isolate has been spawned via rpc.
-void _spawnUriNotify(obj, String token) native 'VMService_spawnUriNotify';
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
new file mode 100644
index 0000000..14f2c45
--- /dev/null
+++ b/tests/co19/co19-co19.status
@@ -0,0 +1,642 @@
+# 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.
+
+Language/Classes/*: Skip # Not migrated to NNBD
+Language/Classes/Abstract_Instance_Members/*: Skip # Not migrated to NNBD
+Language/Classes/Class_Member_Conflicts/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/Constant_Constructors/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/Factories/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/Generative_Constructors/*: Skip # Not migrated to NNBD
+Language/Classes/Getters/*: Skip # Not migrated to NNBD
+Language/Classes/Instance_Methods/*: Skip # Not migrated to NNBD
+Language/Classes/Instance_Methods/Operators/*: Skip # Not migrated to NNBD
+Language/Classes/Instance_Variables/*: Skip # Not migrated to NNBD
+Language/Classes/Setters/*: Skip # Not migrated to NNBD
+Language/Classes/Static_Methods/*: Skip # Not migrated to NNBD
+Language/Classes/Static_Variables/*: Skip # Not migrated to NNBD
+Language/Classes/Superclasses/*: Skip # Not migrated to NNBD
+Language/Classes/Superclasses/Inheritance_and_Overriding/*: Skip # Not migrated to NNBD
+Language/Classes/Superinterfaces/*: Skip # Not migrated to NNBD
+Language/Enums/*: Skip # Not migrated to NNBD
+Language/Errors_and_Warnings/*: Skip # Not migrated to NNBD
+Language/Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Additive_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Assignable_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Assignment/*: Skip # Not migrated to NNBD
+Language/Expressions/Assignment/Compound_Assignment/*: Skip # Not migrated to NNBD
+Language/Expressions/Await_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Bitwise_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Booleans/*: Skip # Not migrated to NNBD
+Language/Expressions/Booleans/Boolean_Conversion/*: Skip # Not migrated to NNBD
+Language/Expressions/Conditional/*: Skip # Not migrated to NNBD
+Language/Expressions/Constants/*: Skip # Not migrated to NNBD
+Language/Expressions/Equality/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Unqualified_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Identifier_Reference/*: Skip # Not migrated to NNBD
+Language/Expressions/If_null_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Instance_Creation/*: Skip # Not migrated to NNBD
+Language/Expressions/Instance_Creation/Const/*: Skip # Not migrated to NNBD
+Language/Expressions/Instance_Creation/New/*: Skip # Not migrated to NNBD
+Language/Expressions/Lists/*: Skip # Not migrated to NNBD
+Language/Expressions/Logical_Boolean_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Lookup/*: Skip # Not migrated to NNBD
+Language/Expressions/Lookup/Getter_and_Setter_Lookup/*: Skip # Not migrated to NNBD
+Language/Expressions/Lookup/Method_Lookup/*: Skip # Not migrated to NNBD
+Language/Expressions/Maps/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/Cascaded_Invocations/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/Ordinary_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/Super_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Multiplicative_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Null/*: Skip # Not migrated to NNBD
+Language/Expressions/Numbers/*: Skip # Not migrated to NNBD
+Language/Expressions/Object_Identity/*: Skip # Not migrated to NNBD
+Language/Expressions/Postfix_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Super_Closurization/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/*: Skip # Not migrated to NNBD
+Language/Expressions/Relational_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Shift/*: Skip # Not migrated to NNBD
+Language/Expressions/Spawning_an_Isolate/*: Skip # Not migrated to NNBD
+Language/Expressions/Strings/*: Skip # Not migrated to NNBD
+Language/Expressions/Strings/String_Interpolation/*: Skip # Not migrated to NNBD
+Language/Expressions/Symbols/*: Skip # Not migrated to NNBD
+Language/Expressions/This/*: Skip # Not migrated to NNBD
+Language/Expressions/Throw/*: Skip # Not migrated to NNBD
+Language/Expressions/Top_level_Getter_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Type_Cast/*: Skip # Not migrated to NNBD
+Language/Expressions/Type_Test/*: Skip # Not migrated to NNBD
+Language/Expressions/Unary_Expressions/*: Skip # Not migrated to NNBD
+Language/Functions/*: Skip # Not migrated to NNBD
+Language/Functions/External_Functions/*: Skip # Not migrated to NNBD
+Language/Functions/Formal_Parameters/*: Skip # Not migrated to NNBD
+Language/Functions/Formal_Parameters/Optional_Formals/*: Skip # Not migrated to NNBD
+Language/Functions/Formal_Parameters/Required_Formals/*: Skip # Not migrated to NNBD
+Language/Functions/Function_Declarations/*: Skip # Not migrated to NNBD
+Language/Functions/Type_of_a_Function/*: Skip # Not migrated to NNBD
+Language/Generics/*: Skip # Not migrated to NNBD
+Language/Generics/Superbounded_types/*: Skip # Not migrated to NNBD
+Language/Interfaces/Superinterfaces/*: Skip # Not migrated to NNBD
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Exports/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Imports/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Parts/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Scripts/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/URIs/*: Skip # Not migrated to NNBD
+Language/Metadata/*: Skip # Not migrated to NNBD
+Language/Mixins/*: Skip # Not migrated to NNBD
+Language/Mixins/Mixin_Application/*: Skip # Not migrated to NNBD
+Language/Mixins/Mixin_Composition/*: Skip # Not migrated to NNBD
+Language/Overview/*: Skip # Not migrated to NNBD
+Language/Overview/Privacy/*: Skip # Not migrated to NNBD
+Language/Overview/Scoping/*: Skip # Not migrated to NNBD
+Language/Reference/Lexical_Rules/*: Skip # Not migrated to NNBD
+Language/Reference/Lexical_Rules/Comments/*: Skip # Not migrated to NNBD
+Language/Reference/Lexical_Rules/Reserved_Words/*: Skip # Not migrated to NNBD
+Language/Reference/Operator_Precedence/*: Skip # Not migrated to NNBD
+Language/Statements/Assert/*: Skip # Not migrated to NNBD
+Language/Statements/Blocks/*: Skip # Not migrated to NNBD
+Language/Statements/Break/*: Skip # Not migrated to NNBD
+Language/Statements/Continue/*: Skip # Not migrated to NNBD
+Language/Statements/Do/*: Skip # Not migrated to NNBD
+Language/Statements/Expression_Statements/*: Skip # Not migrated to NNBD
+Language/Statements/For/*: Skip # Not migrated to NNBD
+Language/Statements/For/Asynchronous_For_in/*: Skip # Not migrated to NNBD
+Language/Statements/For/For_Loop/*: Skip # Not migrated to NNBD
+Language/Statements/For/For_in/*: Skip # Not migrated to NNBD
+Language/Statements/If/*: Skip # Not migrated to NNBD
+Language/Statements/Labels/*: Skip # Not migrated to NNBD
+Language/Statements/Local_Function_Declaration/*: Skip # Not migrated to NNBD
+Language/Statements/Local_Variable_Declaration/*: Skip # Not migrated to NNBD
+Language/Statements/Rethrow/*: Skip # Not migrated to NNBD
+Language/Statements/Return/*: Skip # Not migrated to NNBD
+Language/Statements/Switch/*: Skip # Not migrated to NNBD
+Language/Statements/Try/*: Skip # Not migrated to NNBD
+Language/Statements/While/*: Skip # Not migrated to NNBD
+Language/Statements/Yield_and_Yield_Each/*: Skip # Not migrated to NNBD
+Language/Statements/Yield_and_Yield_Each/Yield/*: Skip # Not migrated to NNBD
+Language/Statements/Yield_and_Yield_Each/Yield_Each/*: Skip # Not migrated to NNBD
+Language/Types/Dynamic_Type_System/*: Skip # Not migrated to NNBD
+Language/Types/Function_Types/*: Skip # Not migrated to NNBD
+Language/Types/Interface_Types/*: Skip # Not migrated to NNBD
+Language/Types/Parameterized_Types/*: Skip # Not migrated to NNBD
+Language/Types/Parameterized_Types/Actual_Type_of_Declaration/*: Skip # Not migrated to NNBD
+Language/Types/Static_Types/*: Skip # Not migrated to NNBD
+Language/Types/Type_Aliases/*: Skip # Not migrated to NNBD
+Language/Types/Type_Void/*: Skip # Not migrated to NNBD
+Language/Types/Type_dynamic/*: Skip # Not migrated to NNBD
+Language/Variables/*: Skip # Not migrated to NNBD
+Language/Variables/Evaluation_of_Implicit_Variable_Getters/*: Skip # Not migrated to NNBD
+LanguageFeatures/Constant-update-2018/*: Skip # Not migrated to NNBD
+LanguageFeatures/Control-flow-collections/*: Skip # Not migrated to NNBD
+LanguageFeatures/Extension-methods/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/class/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/class/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/class/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/typedef/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/typedef/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/typedef/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Set-literals/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/dynamic/type-aliases/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/static/type-aliases/*: Skip # Not migrated to NNBD
+LanguageFeatures/Spread-collections/*: Skip # Not migrated to NNBD
+LanguageFeatures/Super-bounded-types/*: Skip # Not migrated to NNBD
+LanguageFeatures/Super-mixins/*: Skip # Not migrated to NNBD
+LanguageFeatures/Triple-Shift/*: Skip # Not migrated to NNBD
+LanguageFeatures/int-to-double/*: Skip # Not migrated to NNBD
+LanguageFeatures/regression/*: Skip # Not migrated to NNBD
+LibTest/async/Completer/*: Skip # Not migrated to NNBD
+LibTest/async/DeferredLibrary/*: Skip # Not migrated to NNBD
+LibTest/async/EventSink/*: Skip # Not migrated to NNBD
+LibTest/async/Future/*: Skip # Not migrated to NNBD
+LibTest/async/Stream/*: Skip # Not migrated to NNBD
+LibTest/async/StreamConsumer/*: Skip # Not migrated to NNBD
+LibTest/async/StreamController/*: Skip # Not migrated to NNBD
+LibTest/async/StreamIterator/*: Skip # Not migrated to NNBD
+LibTest/async/StreamSink/*: Skip # Not migrated to NNBD
+LibTest/async/StreamTransformer/*: Skip # Not migrated to NNBD
+LibTest/async/Timer/*: Skip # Not migrated to NNBD
+LibTest/async/Zone/*: Skip # Not migrated to NNBD
+LibTest/collection/DoubleLinkedQueue/*: Skip # Not migrated to NNBD
+LibTest/collection/DoubleLinkedQueueEntry/*: Skip # Not migrated to NNBD
+LibTest/collection/HasNextIterator/*: Skip # Not migrated to NNBD
+LibTest/collection/HashMap/*: Skip # Not migrated to NNBD
+LibTest/collection/HashSet/*: Skip # Not migrated to NNBD
+LibTest/collection/IterableBase/*: Skip # Not migrated to NNBD
+LibTest/collection/IterableMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedHashMap/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedHashSet/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedList/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedListEntry/*: Skip # Not migrated to NNBD
+LibTest/collection/ListBase/*: Skip # Not migrated to NNBD
+LibTest/collection/ListMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/ListQueue/*: Skip # Not migrated to NNBD
+LibTest/collection/MapBase/*: Skip # Not migrated to NNBD
+LibTest/collection/MapMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/MapView/*: Skip # Not migrated to NNBD
+LibTest/collection/Queue/*: Skip # Not migrated to NNBD
+LibTest/collection/SetBase/*: Skip # Not migrated to NNBD
+LibTest/collection/SetMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/SplayTreeMap/*: Skip # Not migrated to NNBD
+LibTest/collection/SplayTreeSet/*: Skip # Not migrated to NNBD
+LibTest/collection/UnmodifiableListView/*: Skip # Not migrated to NNBD
+LibTest/collection/UnmodifiableMapBase/*: Skip # Not migrated to NNBD
+LibTest/collection/UnmodifiableMapView/*: Skip # Not migrated to NNBD
+LibTest/convert/AsciiCodec/*: Skip # Not migrated to NNBD
+LibTest/convert/AsciiDecoder/*: Skip # Not migrated to NNBD
+LibTest/convert/AsciiEncoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Base64Codec/*: Skip # Not migrated to NNBD
+LibTest/convert/Base64Decoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Base64Encoder/*: Skip # Not migrated to NNBD
+LibTest/convert/ByteConversionSink/*: Skip # Not migrated to NNBD
+LibTest/convert/ChunkedConversionSink/*: Skip # Not migrated to NNBD
+LibTest/convert/ClosableStringSink/*: Skip # Not migrated to NNBD
+LibTest/convert/Encoding/*: Skip # Not migrated to NNBD
+LibTest/convert/HtmlEscape/*: Skip # Not migrated to NNBD
+LibTest/convert/HtmlEscapeMode/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonCodec/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonDecoder/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonEncoder/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonUtf8Encoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Latin1Codec/*: Skip # Not migrated to NNBD
+LibTest/convert/Latin1Decoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Latin1Encoder/*: Skip # Not migrated to NNBD
+LibTest/convert/LineSplitter/*: Skip # Not migrated to NNBD
+LibTest/convert/StringConversionSink/*: Skip # Not migrated to NNBD
+LibTest/convert/Utf8Codec/*: Skip # Not migrated to NNBD
+LibTest/convert/Utf8Decoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Utf8Encoder/*: Skip # Not migrated to NNBD
+LibTest/core/AbstractClassInstantiationError/*: Skip # Not migrated to NNBD
+LibTest/core/ArgumentError/*: Skip # Not migrated to NNBD
+LibTest/core/AssertionError/*: Skip # Not migrated to NNBD
+LibTest/core/BidirectionalIterator/*: Skip # Not migrated to NNBD
+LibTest/core/CastError/*: Skip # Not migrated to NNBD
+LibTest/core/ConcurrentModificationError/*: Skip # Not migrated to NNBD
+LibTest/core/CyclicInitializationError/*: Skip # Not migrated to NNBD
+LibTest/core/DateTime/*: Skip # Not migrated to NNBD
+LibTest/core/Deprecated/*: Skip # Not migrated to NNBD
+LibTest/core/Duration/*: Skip # Not migrated to NNBD
+LibTest/core/Error/*: Skip # Not migrated to NNBD
+LibTest/core/Exception/*: Skip # Not migrated to NNBD
+LibTest/core/Expando/*: Skip # Not migrated to NNBD
+LibTest/core/FallThroughError/*: Skip # Not migrated to NNBD
+LibTest/core/FormatException/*: Skip # Not migrated to NNBD
+LibTest/core/Function/*: Skip # Not migrated to NNBD
+LibTest/core/IndexError/*: Skip # Not migrated to NNBD
+LibTest/core/IntegerDivisionByZeroException/*: Skip # Not migrated to NNBD
+LibTest/core/Invocation/*: Skip # Not migrated to NNBD
+LibTest/core/Iterable/*: Skip # Not migrated to NNBD
+LibTest/core/Iterator/*: Skip # Not migrated to NNBD
+LibTest/core/List/*: Skip # Not migrated to NNBD
+LibTest/core/Map/*: Skip # Not migrated to NNBD
+LibTest/core/Match/*: Skip # Not migrated to NNBD
+LibTest/core/NoSuchMethodError/*: Skip # Not migrated to NNBD
+LibTest/core/Null/*: Skip # Not migrated to NNBD
+LibTest/core/Object/*: Skip # Not migrated to NNBD
+LibTest/core/OutOfMemoryError/*: Skip # Not migrated to NNBD
+LibTest/core/RangeError/*: Skip # Not migrated to NNBD
+LibTest/core/RegExp/*: Skip # Not migrated to NNBD
+LibTest/core/RegExp/Pattern_semantics/*: Skip # Not migrated to NNBD
+LibTest/core/RuneIterator/*: Skip # Not migrated to NNBD
+LibTest/core/Runes/*: Skip # Not migrated to NNBD
+LibTest/core/Set/*: Skip # Not migrated to NNBD
+LibTest/core/StackOverflowError/*: Skip # Not migrated to NNBD
+LibTest/core/StackTrace/*: Skip # Not migrated to NNBD
+LibTest/core/StateError/*: Skip # Not migrated to NNBD
+LibTest/core/Stopwatch/*: Skip # Not migrated to NNBD
+LibTest/core/String/*: Skip # Not migrated to NNBD
+LibTest/core/StringBuffer/*: Skip # Not migrated to NNBD
+LibTest/core/Symbol/*: Skip # Not migrated to NNBD
+LibTest/core/TypeError/*: Skip # Not migrated to NNBD
+LibTest/core/UnimplementedError/*: Skip # Not migrated to NNBD
+LibTest/core/UnsupportedError/*: Skip # Not migrated to NNBD
+LibTest/core/Uri/*: Skip # Not migrated to NNBD
+LibTest/core/UriData/*: Skip # Not migrated to NNBD
+LibTest/core/bool/*: Skip # Not migrated to NNBD
+LibTest/core/double/*: Skip # Not migrated to NNBD
+LibTest/core/int/*: Skip # Not migrated to NNBD
+LibTest/html/CanvasRenderingContext2D/*: Skip # Not migrated to NNBD
+LibTest/html/Document/*: Skip # Not migrated to NNBD
+LibTest/html/Element/*: Skip # Not migrated to NNBD
+LibTest/html/Event/*: Skip # Not migrated to NNBD
+LibTest/html/HttpRequest/*: Skip # Not migrated to NNBD
+LibTest/html/HttpRequestUpload/*: Skip # Not migrated to NNBD
+LibTest/html/IFrameElement/*: Skip # Not migrated to NNBD
+LibTest/html/Node/*: Skip # Not migrated to NNBD
+LibTest/html/Window/*: Skip # Not migrated to NNBD
+LibTest/io/BytesBuilder/*: Skip # Not migrated to NNBD
+LibTest/io/CompressionOptions/*: Skip # Not migrated to NNBD
+LibTest/io/ContentType/*: Skip # Not migrated to NNBD
+LibTest/io/Cookie/*: Skip # Not migrated to NNBD
+LibTest/io/Datagram/*: Skip # Not migrated to NNBD
+LibTest/io/Directory/*: Skip # Not migrated to NNBD
+LibTest/io/File/*: Skip # Not migrated to NNBD
+LibTest/io/FileStat/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemCreateEvent/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemDeleteEvent/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemEntity/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemModifyEvent/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemMoveEvent/*: Skip # Not migrated to NNBD
+LibTest/io/GZipCodec/*: Skip # Not migrated to NNBD
+LibTest/io/HeaderValue/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClient/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientBasicCredentials/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientDigestCredentials/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientRequest/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientResponse/*: Skip # Not migrated to NNBD
+LibTest/io/HttpServer/*: Skip # Not migrated to NNBD
+LibTest/io/IOSink/*: Skip # Not migrated to NNBD
+LibTest/io/InternetAddress/*: Skip # Not migrated to NNBD
+LibTest/io/Link/*: Skip # Not migrated to NNBD
+LibTest/io/NetworkInterface/*: Skip # Not migrated to NNBD
+LibTest/io/OSError/*: Skip # Not migrated to NNBD
+LibTest/io/Process/*: Skip # Not migrated to NNBD
+LibTest/io/ProcessInfo/*: Skip # Not migrated to NNBD
+LibTest/io/ProcessResult/*: Skip # Not migrated to NNBD
+LibTest/io/ProcessSignal/*: Skip # Not migrated to NNBD
+LibTest/io/RandomAccessFile/*: Skip # Not migrated to NNBD
+LibTest/io/RawDatagramSocket/*: Skip # Not migrated to NNBD
+LibTest/io/RawSecureServerSocket/*: Skip # Not migrated to NNBD
+LibTest/io/Stdin/*: Skip # Not migrated to NNBD
+LibTest/io/Stdout/*: Skip # Not migrated to NNBD
+LibTest/io/SystemEncoding/*: Skip # Not migrated to NNBD
+LibTest/io/WebSocket/*: Skip # Not migrated to NNBD
+LibTest/io/WebSocketTransformer/*: Skip # Not migrated to NNBD
+LibTest/io/ZLibCodec/*: Skip # Not migrated to NNBD
+LibTest/io/ZLibDecoder/*: Skip # Not migrated to NNBD
+LibTest/io/ZLibEncoder/*: Skip # Not migrated to NNBD
+LibTest/io/certificates/*: Skip # Not migrated to NNBD
+LibTest/io/exit/*: Skip # Not migrated to NNBD
+LibTest/io/exitCode/*: Skip # Not migrated to NNBD
+LibTest/io/gzip/*: Skip # Not migrated to NNBD
+LibTest/io/pid/*: Skip # Not migrated to NNBD
+LibTest/io/sleep/*: Skip # Not migrated to NNBD
+LibTest/io/stderr/*: Skip # Not migrated to NNBD
+LibTest/io/systemEncodingConstant/*: Skip # Not migrated to NNBD
+LibTest/io/zlib/*: Skip # Not migrated to NNBD
+LibTest/isolate/Capability/*: Skip # Not migrated to NNBD
+LibTest/isolate/Isolate/*: Skip # Not migrated to NNBD
+LibTest/isolate/RawReceivePort/*: Skip # Not migrated to NNBD
+LibTest/isolate/ReceivePort/*: Skip # Not migrated to NNBD
+LibTest/isolate/SendPort/*: Skip # Not migrated to NNBD
+LibTest/math/*: Skip # Not migrated to NNBD
+LibTest/math/MutableRectangle/*: Skip # Not migrated to NNBD
+LibTest/math/Point/*: Skip # Not migrated to NNBD
+LibTest/math/Random/*: Skip # Not migrated to NNBD
+LibTest/math/Rectangle/*: Skip # Not migrated to NNBD
+LibTest/mirrors/*: Skip # Not migrated to NNBD
+LibTest/typed_data/*: Skip # Not migrated to NNBD
+LibTest/typed_data/ByteBuffer/*: Skip # Not migrated to NNBD
+LibTest/typed_data/ByteData/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float32List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float32x4/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float32x4List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float64List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float64x2/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float64x2List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int16List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int32List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int32x4/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int32x4List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int64List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int8List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint16List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint32List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint64List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint8ClampedList/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint8List/*: Skip # Not migrated to NNBD
+
+[ $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
+
+[ $runtime != none ]
+LibTest/async/Completer/completeError_A02_t01: Skip # See breaking change #40674
+LibTest/async/Future/Future.error_A01_t01: Skip # See breaking change #40674
+LibTest/async/StreamController/addError_A02_t01: Skip # See breaking change #40674
+LibTest/collection/HashSet/HashSet.from_A02_t01: Skip # See breaking change #40674
+LibTest/collection/ListQueue/ListQueue.from_A03_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator.at_A01_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator.at_A02_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator.at_A03_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator_A01_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/currentAsString_A03_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/movePrevious_A02_t02: Skip # See breaking change #40674
+LibTest/core/RuneIterator/rawIndex_A02_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/reset_A01_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/reset_A01_t02: Skip # See breaking change #40674
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
new file mode 100644
index 0000000..dddded9
--- /dev/null
+++ b/tests/co19/co19-dart2js.status
@@ -0,0 +1,34 @@
+# 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.
+
+[ $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/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
+Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+LibTest/io/*: SkipByDesign # dart:io not supported.
+LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
+
+[ $compiler == dart2js && $runtime == d8 ]
+LibTest/html/*: SkipByDesign # d8 is not a browser
+
+[ $compiler == dart2js && $runtime == d8 && $host_checked ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t04: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t05: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t06: Slow, Pass
+LibTest/core/List/List_class_A01_t05: Slow, Pass
+LibTest/core/List/List_class_A01_t06: Slow, Pass
+
+[ $compiler == dart2js && $runtime == ie11 ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # slow babeljs transformation
+LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # slow babeljs transformation
+LibTest/collection/ListBase/ListBase_class_A01_t06: SkipSlow # slow babeljs transformation
+LibTest/collection/ListMixin/ListMixin_class_A01_t04: SkipSlow # slow babeljs transformation
+LibTest/collection/ListMixin/ListMixin_class_A01_t05: SkipSlow # slow babeljs transformation
+LibTest/collection/ListMixin/ListMixin_class_A01_t06: SkipSlow # slow babeljs transformation
+LibTest/core/List/List_class_A01_t04: SkipSlow # slow babeljs transformation
+LibTest/core/List/List_class_A01_t05: SkipSlow # slow babeljs transformation
+LibTest/core/List/List_class_A01_t06: SkipSlow # slow babeljs transformation
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
new file mode 100644
index 0000000..087f30b
--- /dev/null
+++ b/tests/co19/co19-dartdevc.status
@@ -0,0 +1,83 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $compiler == dartdevc || $compiler == dartdevk ]
+Language/Classes/Constructors/Generative_Constructors/formal_parameter_t07: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/fresh_instance_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t02: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializers_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializers_t15: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializing_this_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/redirection_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/syntax_t01: Skip # Times out
+Language/Classes/Constructors/implicit_constructor_t01: Skip # Times out
+Language/Classes/Constructors/implicit_constructor_t02: Skip # Times out
+Language/Classes/Constructors/name_t01: Skip # Times out
+Language/Classes/Constructors/name_t02: Skip # Times out
+Language/Classes/Constructors/name_t03: Skip # Times out
+Language/Classes/Getters/instance_getter_t01: Skip # Times out
+Language/Classes/Getters/instance_getter_t02: Skip # Times out
+Language/Classes/Getters/instance_getter_t03: Skip # Times out
+Language/Classes/Getters/instance_getter_t04: Skip # Times out
+Language/Classes/Getters/instance_getter_t05: Skip # Times out
+Language/Classes/Getters/instance_getter_t06: Skip # Times out
+Language/Classes/Getters/override_t04: Skip # Times out
+Language/Classes/Getters/return_type_t01: Skip # Times out
+Language/Classes/Getters/static_t01/none: Skip # Times out
+Language/Classes/Getters/static_t02: Skip # Times out
+Language/Classes/Getters/syntax_t01: Skip # Times out
+Language/Classes/Getters/void_return_type_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/arity_0_or_1_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/arity_0_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/syntax_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/syntax_t03: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t03: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t04: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t06: Skip # Times out
+Language/Classes/Instance_Methods/override_subtype_t05: Skip # Times out
+Language/Classes/Instance_Methods/override_subtype_t06: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t08: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: Skip # Times out
+Language/Classes/Instance_Variables/definition_t01: Skip # Times out
+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/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/Spawning_an_Isolate/new_isolate_t01: SkipByDesign # dart:isolate not supported.
+Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+Language/Types/Interface_Types/subtype_t27: Skip # Times out
+Language/Types/Interface_Types/subtype_t28: Skip # Times out
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Skip # Times out
+LibTest/html/Element/blur_A01_t01: Skip # Times out
+LibTest/html/Element/focus_A01_t01: Skip # Times out
+LibTest/html/Element/loadEvent_A01_t01: Skip # Times out
+LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out
+LibTest/html/Element/onLoad_A01_t01: Skip # Times out
+LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out
+LibTest/html/Element/onTransitionEnd_A01_t01: Skip # Times out
+LibTest/html/Element/transitionEndEvent_A01_t01: Skip # Times out
+LibTest/html/HttpRequest/onError_A01_t02: Skip # Times out
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # Times out
+LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/blur_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/enteredView_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/focus_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/onMouseWheel_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Skip # Times out
+LibTest/io/*: SkipByDesign # dart:io not supported.
+LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
new file mode 100644
index 0000000..8aa80ab
--- /dev/null
+++ b/tests/co19/co19-kernel.status
@@ -0,0 +1,205 @@
+# 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.
+
+[ $builder_tag == bytecode_interpreter ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
+
+[ $compiler == dartkb ]
+LibTest/isolate/Isolate/kill_A01_t01: Skip # Issue 37699
+LibTest/isolate/Isolate/pause_A01_t01: Skip # Issue 37699
+LibTest/isolate/Isolate/pause_A01_t02: Skip # Issue 37699
+
+[ $compiler == fasta ]
+Language/Statements/For/syntax_t13: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
+Language/Statements/For/syntax_t20: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: Crash
+
+[ $runtime == vm ]
+LibTest/collection/ListBase/ListBase_class_A01_t02: Slow, Pass # Does many calls
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Slow, Pass # Does many calls
+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
+
+[ $runtime == vm && $system == linux && ($compiler == dartk || $compiler == dartkb) ]
+LibTest/isolate/Isolate/spawn_A06_t03: Crash
+
+[ $runtime == vm && $system == macos && ($compiler == dartk || $compiler == dartkb) ]
+LibTest/collection/ListBase/ListBase_class_A01_t02: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t03: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t03: Slow, Pass
+LibTest/core/List/List_class_A01_t02: Slow, Pass
+LibTest/core/List/List_class_A01_t03: Slow, Pass
+
+[ $runtime != vm && ($compiler == dartk || $compiler == dartkb) ]
+Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: Crash
+
+[ $compiler == dartk || $compiler == dartkb ]
+Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
+LibTest/isolate/SendPort/send_A01_t02: Crash
+LibTest/isolate/SendPort/send_A01_t03: Crash
+
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+LibTest/isolate/Isolate/spawnUri*: Skip
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
new file mode 100644
index 0000000..c3ddffa
--- /dev/null
+++ b/tests/co19/co19-runtime.status
@@ -0,0 +1,13 @@
+# 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.
+
+[ $runtime != none ]
+LibTest/core/Uri/hasEmptyPath_A01_t01: RuntimeError
+LibTest/core/Uri/parse_A05_t01: RuntimeError
+
+[ $compiler != dart2js && $runtime != none && $runtime != vm && !$checked ]
+LibTest/async/Future/catchError_A03_t05: RuntimeError
+
+[ $compiler == fasta || $runtime == dart_precompiled || $runtime == vm ]
+LibTest/html/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 2bb6211..dddded9 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -6,15 +6,11 @@
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
 Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
-LayoutTests/*: Skip # These tests are going to be removed.
 LibTest/io/*: SkipByDesign # dart:io not supported.
 LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
-WebPlatformTest/*: Skip # These tests are going to be removed.
 
 [ $compiler == dart2js && $runtime == d8 ]
-LayoutTests/*: SkipByDesign # d8 is not a browser
 LibTest/html/*: SkipByDesign # d8 is not a browser
-WebPlatformTest/*: SkipByDesign # d8 is not a browser
 
 [ $compiler == dart2js && $runtime == d8 && $host_checked ]
 LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
diff --git a/tests/co19_2/co19_2-dartdevc.status b/tests/co19_2/co19_2-dartdevc.status
index b204630..087f30b 100644
--- a/tests/co19_2/co19_2-dartdevc.status
+++ b/tests/co19_2/co19_2-dartdevc.status
@@ -59,7 +59,6 @@
 Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
 Language/Types/Interface_Types/subtype_t27: Skip # Times out
 Language/Types/Interface_Types/subtype_t28: Skip # Times out
-LayoutTests/*: Skip # These tests are going to be removed.
 LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Skip # Times out
 LibTest/html/Element/blur_A01_t01: Skip # Times out
 LibTest/html/Element/focus_A01_t01: Skip # Times out
@@ -82,4 +81,3 @@
 LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Skip # Times out
 LibTest/io/*: SkipByDesign # dart:io not supported.
 LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
-WebPlatformTest/*: Skip # These tests are going to be removed.
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
index acb6832..c3ddffa 100644
--- a/tests/co19_2/co19_2-runtime.status
+++ b/tests/co19_2/co19_2-runtime.status
@@ -10,6 +10,4 @@
 LibTest/async/Future/catchError_A03_t05: RuntimeError
 
 [ $compiler == fasta || $runtime == dart_precompiled || $runtime == vm ]
-LayoutTests/fast/*: SkipByDesign # DOM not supported on VM.
 LibTest/html/*: SkipByDesign # dart:html not supported on VM.
-WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/compiler/dart2js/analyses/analysis_helper.dart b/tests/compiler/dart2js/analyses/analysis_helper.dart
index d70a4bc..ba0e1f5 100644
--- a/tests/compiler/dart2js/analyses/analysis_helper.dart
+++ b/tests/compiler/dart2js/analyses/analysis_helper.dart
@@ -310,6 +310,8 @@
     assert(
         node is! ir.Expression ||
             staticType == typeEnvironment.nullType ||
+            staticType is ir.InterfaceType &&
+                staticType.classNode == typeEnvironment.futureOrClass ||
             typeEnvironment.isSubtypeOf(
                 staticType,
                 _getStaticTypeFromExpression(node),
diff --git a/tests/compiler/dart2js/analyses/api_allowed_nnbd.json b/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
new file mode 100644
index 0000000..e32d5da
--- /dev/null
+++ b/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
@@ -0,0 +1,205 @@
+{
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart": {
+    "Dynamic invocation of '[]'.": 5,
+    "Dynamic invocation of '<'.": 4,
+    "Dynamic invocation of '>='.": 1,
+    "Dynamic invocation of '<='.": 1,
+    "Dynamic invocation of '>'.": 2
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart": {
+    "Dynamic invocation of '[]'.": 3,
+    "Dynamic access of 'isNaN'.": 3,
+    "Dynamic invocation of '<='.": 2,
+    "Dynamic invocation of '-'.": 3,
+    "Dynamic invocation of '&'.": 1,
+    "Dynamic invocation of '>>'.": 1,
+    "Dynamic invocation of '<'.": 2,
+    "Dynamic invocation of '+'.": 1,
+    "Dynamic invocation of '>'.": 1,
+    "Dynamic access of 'length'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart": {
+    "Dynamic invocation of '<'.": 1,
+    "Dynamic invocation of '+'.": 1,
+    "Dynamic invocation of '>='.": 1,
+    "Dynamic invocation of 'substring'.": 7,
+    "Dynamic invocation of 'allMatches'.": 3,
+    "Dynamic access of 'isNotEmpty'.": 1,
+    "Dynamic invocation of '_js_helper::_execGlobal'.": 1,
+    "Dynamic access of 'start'.": 1,
+    "Dynamic access of 'end'.": 1,
+    "Dynamic invocation of 'call'.": 13,
+    "Dynamic access of 'length'.": 3,
+    "Dynamic invocation of 'codeUnitAt'.": 2,
+    "Dynamic invocation of '[]'.": 1,
+    "Dynamic access of 'iterator'.": 2,
+    "Dynamic invocation of 'replaceRange'.": 2
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart": {
+    "Dynamic access of '_js_helper::_length'.": 2,
+    "Dynamic access of '_js_helper::_modifications'.": 4,
+    "Dynamic invocation of 'containsKey'.": 1,
+    "Dynamic access of '_js_helper::_first'.": 2
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart": {
+    "Dynamic invocation of '<'.": 1,
+    "Dynamic invocation of '-'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart": {
+    "Dynamic access of 'length'.": 2,
+    "Dynamic invocation of '[]'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart": {
+    "Dynamic access of 'length'.": 1,
+    "Dynamic invocation of '-'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart": {
+    "Dynamic invocation of '>'.": 1,
+    "Dynamic invocation of '>='.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart": {
+    "Dynamic invocation of '-'.": 1,
+    "Dynamic access of 'iterator'.": 1,
+    "Dynamic invocation of 'call'.": 4,
+    "Dynamic invocation of 'then'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart": {
+    "Dynamic access of 'dart.collection::_length'.": 2,
+    "Dynamic invocation of 'dart.collection::_computeKeys'.": 2,
+    "Dynamic invocation of 'containsKey'.": 2,
+    "Dynamic access of 'dart.collection::_keys'.": 2,
+    "Dynamic access of 'length'.": 1,
+    "Dynamic access of 'isEmpty'.": 1,
+    "Dynamic access of 'dart.collection::_modifications'.": 5,
+    "Dynamic access of 'dart.collection::_map'.": 4,
+    "Dynamic access of 'dart.collection::_elements'.": 1,
+    "Dynamic access of 'dart.collection::_element'.": 1,
+    "Dynamic access of 'dart.collection::_first'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/html/dart2js/html_dart2js.dart": {
+    "Dynamic access of 'style'.": 1,
+    "Dynamic invocation of 'remove'.": 2,
+    "Dynamic update to 'dart.dom.html::_innerHtml'.": 1,
+    "Dynamic access of 'firstChild'.": 2,
+    "Dynamic access of 'tagName'.": 2,
+    "Dynamic invocation of 'call'.": 2,
+    "Dynamic invocation of 'dart.dom.html::_initKeyboardEvent'.": 1,
+    "Dynamic access of 'attributes'.": 1,
+    "Dynamic invocation of '[]'.": 1,
+    "Dynamic invocation of 'toLowerCase'.": 1,
+    "Dynamic invocation of 'attached'.": 1,
+    "Dynamic invocation of 'detached'.": 1,
+    "Dynamic invocation of 'attributeChanged'.": 1,
+    "Dynamic invocation of 'createElement'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/html/html_common/conversions.dart": {
+    "Dynamic invocation of '[]='.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/html/html_common/filtered_element_list.dart": {
+    "Dynamic invocation of 'remove'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/directory_impl.dart": {
+    "Dynamic invocation of '[]'.": 10
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/file_impl.dart": {
+    "Dynamic invocation of '[]'.": 4,
+    "Dynamic access of 'length'.": 2
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/file_system_entity.dart": {
+    "Dynamic invocation of '[]'.": 7
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/io_resource_info.dart": {
+    "Dynamic invocation of '[]'.": 1,
+    "Dynamic access of 'path'.": 1,
+    "Dynamic access of 'dart.io::_path'.": 1,
+    "Dynamic access of 'pid'.": 1,
+    "Dynamic access of 'dart.io::_arguments'.": 1,
+    "Dynamic access of 'dart.io::_workingDirectory'.": 2,
+    "Dynamic access of 'isListening'.": 3,
+    "Dynamic access of 'address'.": 4,
+    "Dynamic access of 'host'.": 5,
+    "Dynamic access of 'port'.": 3,
+    "Dynamic access of 'remoteAddress'.": 2,
+    "Dynamic access of 'remotePort'.": 2,
+    "Dynamic access of 'isTcp'.": 1,
+    "Dynamic access of 'type'.": 1,
+    "Dynamic access of 'name'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/link.dart": {
+    "Dynamic invocation of '[]'.": 3
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/platform_impl.dart": {
+    "Dynamic invocation of 'indexOf'.": 1,
+    "Dynamic invocation of '>'.": 1,
+    "Dynamic invocation of 'substring'.": 2,
+    "Dynamic invocation of '+'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/secure_server_socket.dart": {
+    "Dynamic update to 'dart.io::_owner'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/secure_socket.dart": {
+    "Dynamic invocation of '[]'.": 10,
+    "Dynamic invocation of 'dart.io::_detachRaw'.": 2,
+    "Dynamic access of 'closedReadEventSent'.": 1,
+    "Dynamic update to 'dart.io::_owner'.": 1,
+    "Dynamic access of 'length'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/stdio.dart": {
+    "Dynamic invocation of 'writeFromSync'.": 1,
+    "Dynamic invocation of 'cancel'.": 1,
+    "Dynamic invocation of 'closeSync'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/io/common.dart": {
+    "Dynamic invocation of '[]'.": 3
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_patch.dart": {
+    "Dynamic invocation of '[]'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart": {
+    "Dynamic invocation of 'createFragment'.": 1,
+    "Dynamic access of 'nodes'.": 1,
+    "Dynamic invocation of 'where'.": 1,
+    "Dynamic access of 'single'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/core/errors.dart": {
+    "Dynamic access of 'length'.": 2
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart": {
+    "Dynamic invocation of 'clear'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/convert/json.dart": {
+    "Dynamic invocation of 'toJson'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_http/crypto.dart": {
+    "Dynamic invocation of '+'.": 2,
+    "Dynamic invocation of '&'.": 3,
+    "Dynamic invocation of 'unary-'.": 1,
+    "Dynamic invocation of '-'.": 2
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_http/http_date.dart": {
+    "Dynamic access of 'length'.": 3,
+    "Dynamic invocation of '<'.": 1,
+    "Dynamic invocation of '>='.": 2,
+    "Dynamic invocation of '[]'.": 7
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_http/http_headers.dart": {
+    "Dynamic invocation of 'toLowerCase'.": 1
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_http/http_impl.dart": {
+    "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
+  },
+  "org-dartlang-sdk:///sdk_nnbd/lib/_http/websocket_impl.dart": {
+    "Dynamic invocation of 'dart._http::_toJSON'.": 1
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/analyses/api_dynamic_test.dart b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
index d9a0bf7..53e4196 100644
--- a/tests/compiler/dart2js/analyses/api_dynamic_test.dart
+++ b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
@@ -5,14 +5,16 @@
 // @dart = 2.7
 
 import 'package:async_helper/async_helper.dart';
+import '../helpers/memory_compiler.dart';
 import 'analysis_helper.dart';
 
 // TODO(johnniwinther): Remove unneeded dynamic accesses from platform source
 // code.
 main(List<String> args) {
+  var goldenFile = isDart2jsNnbd ? 'api_allowed_nnbd.json' : 'api_allowed.json';
   asyncTest(() async {
     await run(Uri.parse('memory:main.dart'),
-        'tests/compiler/dart2js/analyses/api_allowed.json',
+        'tests/compiler/dart2js/analyses/$goldenFile',
         analyzedUrisFilter: (Uri uri) => uri.scheme == 'dart',
         memorySourceFiles: {'main.dart': 'main() {}'},
         verbose: args.contains('-v'),
diff --git a/tests/compiler/dart2js/annotations/annotations_test.dart b/tests/compiler/dart2js/annotations/annotations_test.dart
index 82c35a0..a4424c6 100644
--- a/tests/compiler/dart2js/annotations/annotations_test.dart
+++ b/tests/compiler/dart2js/annotations/annotations_test.dart
@@ -24,7 +24,7 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, const AnnotationDataComputer(),
-        args: args, testedConfigs: allStrongConfigs);
+        args: args, testedConfigs: allSpecConfigs);
   });
 }
 
diff --git a/tests/compiler/dart2js/annotations/data/marker.options b/tests/compiler/dart2js/annotations/data/marker.options
index 730d5c7..24b51f0 100644
--- a/tests/compiler/dart2js/annotations/data/marker.options
+++ b/tests/compiler/dart2js/annotations/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/annotations/annotations_test.dart
-omit=tests/compiler/dart2js/annotations/annotations_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/annotations/annotations_test.dart
+prod:nnbd-off=tests/compiler/dart2js/annotations/annotations_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/annotations/annotations_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/annotations/annotations_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/closure/data/generic.dart b/tests/compiler/dart2js/closure/data/generic.dart
index a2f552d..2ceb029 100644
--- a/tests/compiler/dart2js/closure/data/generic.dart
+++ b/tests/compiler/dart2js/closure/data/generic.dart
@@ -58,12 +58,12 @@
     }
 
     var local2 =
-        /*strong.fields=[S,this],free=[S,this],hasThis*/
-        /*omit.hasThis*/
+        /*spec:nnbd-off|spec:nnbd-sdk.fields=[S,this],free=[S,this],hasThis*/
+        /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
         (o) {
       return
-          /*strong.fields=[S,this],free=[S,this],hasThis*/
-          /*omit.hasThis*/
+          /*spec:nnbd-off|spec:nnbd-sdk.fields=[S,this],free=[S,this],hasThis*/
+          /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
           () => new Map<T, S>();
     };
     return local2(local<double>());
diff --git a/tests/compiler/dart2js/closure/data/instantiation.dart b/tests/compiler/dart2js/closure/data/instantiation.dart
index 19949ff..17031f5 100644
--- a/tests/compiler/dart2js/closure/data/instantiation.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation.dart
@@ -7,8 +7,8 @@
 T id<T>(T t) => t;
 
 method<S>(S s) {
-  /*strong.fields=[S],free=[S]*/
-  /*omit.*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[S],free=[S]*/
+  /*prod:nnbd-off.*/
   S Function(S) getId() => id;
   return getId();
 }
diff --git a/tests/compiler/dart2js/closure/data/instantiation1.dart b/tests/compiler/dart2js/closure/data/instantiation1.dart
index 3f31e41..0e0d917 100644
--- a/tests/compiler/dart2js/closure/data/instantiation1.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation1.dart
@@ -13,8 +13,8 @@
   /*member: B.method:hasThis*/
   method() {
     return
-        /*strong.fields=[this],free=[this],hasThis*/
-        /*omit.hasThis*/
+        /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
+        /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
         () {
       F<S> c = f;
       return c;
diff --git a/tests/compiler/dart2js/closure/data/instantiation2.dart b/tests/compiler/dart2js/closure/data/instantiation2.dart
index 8e75f09..b74a15d 100644
--- a/tests/compiler/dart2js/closure/data/instantiation2.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation2.dart
@@ -13,8 +13,7 @@
   /*member: B.method:hasThis*/
   method() {
     return
-        /*strong.fields=[this],free=[this],hasThis*/
-        /*omit.fields=[this],free=[this],hasThis*/
+        /*fields=[this],free=[this],hasThis*/
         () {
       F<S> c = f;
       return c;
diff --git a/tests/compiler/dart2js/closure/data/instantiation3.dart b/tests/compiler/dart2js/closure/data/instantiation3.dart
index 2157d67..c20327b 100644
--- a/tests/compiler/dart2js/closure/data/instantiation3.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation3.dart
@@ -10,8 +10,8 @@
 
 method<S>() {
   return
-      /*strong.fields=[S],free=[S]*/
-      /*omit.*/
+      /*spec:nnbd-off|spec:nnbd-sdk.fields=[S],free=[S]*/
+      /*prod:nnbd-off.*/
       () {
     F<S> c = f;
     return c;
diff --git a/tests/compiler/dart2js/closure/data/instantiation4.dart b/tests/compiler/dart2js/closure/data/instantiation4.dart
index 05b8caf..0da1e4b 100644
--- a/tests/compiler/dart2js/closure/data/instantiation4.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation4.dart
@@ -10,8 +10,7 @@
 
 method<S>() {
   return
-      /*strong.fields=[S],free=[S]*/
-      /*omit.fields=[S],free=[S]*/
+      /*fields=[S],free=[S]*/
       () {
     F<S> c = f;
     return c;
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
index 516b390..8a7c352 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
@@ -11,8 +11,8 @@
   /*member: A.method:hasThis*/
   @pragma('dart2js:noInline')
   method() {
-    /*omit.hasThis*/
-    /*strong.fields=[this],free=[this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
     dynamic local() => <T>[];
     return local;
   }
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart
index 42e8cf2..f389236 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart
@@ -8,8 +8,8 @@
 
 @pragma('dart2js:noInline')
 method<T>() {
-  /*omit.*/
-  /*strong.fields=[T],free=[T]*/
+  /*prod:nnbd-off.*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
   dynamic local() => <T>[];
   return local;
 }
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
index 6ee00d3..d1b27bd 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
@@ -11,8 +11,8 @@
   /*member: A.method:hasThis*/
   @pragma('dart2js:noInline')
   method() {
-    /*omit.hasThis*/
-    /*strong.fields=[this],free=[this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
     dynamic local() => <T, int>{};
     return local;
   }
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart
index d2adfbb..57a3dfd 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart
@@ -8,8 +8,8 @@
 
 @pragma('dart2js:noInline')
 method<T>() {
-  /*omit.*/
-  /*strong.fields=[T],free=[T]*/
+  /*prod:nnbd-off.*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
   dynamic local() => <T, int>{};
   return local;
 }
diff --git a/tests/compiler/dart2js/closure/data/marker.options b/tests/compiler/dart2js/closure/data/marker.options
index f297827..ba31510 100644
--- a/tests/compiler/dart2js/closure/data/marker.options
+++ b/tests/compiler/dart2js/closure/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/closure/closure_test.dart
-omit=tests/compiler/dart2js/closure/closure_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/closure/closure_test.dart
+prod:nnbd-off=tests/compiler/dart2js/closure/closure_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/closure/closure_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/closure/closure_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/closure/data/test_type_class.dart b/tests/compiler/dart2js/closure/data/test_type_class.dart
index ead1797..0c92250 100644
--- a/tests/compiler/dart2js/closure/data/test_type_class.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_class.dart
@@ -33,15 +33,15 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in strong mode.
+/// Implicit as-cast is only required in spec:nnbd-off mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: Class3.:hasThis*/
 class Class3<T> {
   /*member: Class3.method3:hasThis*/
   method3(dynamic o) {
-    /*omit.fields=[o],free=[o],hasThis*/
-    /*strong.fields=[o,this],free=[o,this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o],hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[o,this],free=[o,this],hasThis*/
     T local() => o;
     return local;
   }
diff --git a/tests/compiler/dart2js/closure/data/test_type_method.dart b/tests/compiler/dart2js/closure/data/test_type_method.dart
index faad952..452f6c1 100644
--- a/tests/compiler/dart2js/closure/data/test_type_method.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_method.dart
@@ -27,13 +27,13 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in strong mode.
+/// Implicit as-cast is only required in spec:nnbd-off mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: method3:*/
 method3<T>(dynamic o) {
-  /*strong.fields=[T,o],free=[T,o]*/
-  /*omit.fields=[o],free=[o]*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T,o],free=[T,o]*/
+  /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o]*/
   T local() => o;
   return local;
 }
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_class.dart b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
index 1732242..5d1cfdc 100644
--- a/tests/compiler/dart2js/closure/data/type_annotations_class.dart
+++ b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
@@ -43,30 +43,30 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is only captured in strong mode.
+/// A local function parameter type is only captured in spec:nnbd-off mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: Class2.:hasThis*/
 class Class2<T> {
   /*member: Class2.method2:hasThis*/
   method2() {
-    /*omit.hasThis*/
-    /*strong.fields=[this],free=[this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
     dynamic local(T t) => t;
     return local;
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is only captured in strong mode.
+/// A local function return type is only captured in spec:nnbd-off mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: Class3.:hasThis*/
 class Class3<T> {
   /*member: Class3.method3:hasThis*/
   method3(dynamic o) {
-    /*omit.fields=[o],free=[o],hasThis*/
-    /*strong.fields=[o,this],free=[o,this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o],hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[o,this],free=[o,this],hasThis*/
     T local() => o;
     return local;
   }
@@ -108,8 +108,8 @@
 class Class6<T> {
   /*member: Class6.method6:hasThis*/
   method6() {
-    /*omit.hasThis*/
-    /*strong.fields=[this],free=[this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
     dynamic local(T t) {
       /*fields=[t],free=[t],hasThis*/
       dynamic inner() => t;
@@ -128,8 +128,8 @@
 class Class7<T> {
   /*member: Class7.method7:hasThis*/
   method7(dynamic o) {
-    /*omit.fields=[o],free=[o],hasThis*/
-    /*strong.fields=[o,this],free=[o,this],hasThis*/
+    /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o],hasThis*/
+    /*spec:nnbd-off|spec:nnbd-sdk.fields=[o,this],free=[o,this],hasThis*/
     T local() {
       /*fields=[o],free=[o],hasThis*/
       dynamic inner() => o;
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_method.dart b/tests/compiler/dart2js/closure/data/type_annotations_method.dart
index 4bf4396..a73576f 100644
--- a/tests/compiler/dart2js/closure/data/type_annotations_method.dart
+++ b/tests/compiler/dart2js/closure/data/type_annotations_method.dart
@@ -19,23 +19,23 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is captured in strong mode.
+/// A local function parameter type is captured in spec:nnbd-off mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 method2<T>() {
-  /*strong.fields=[T],free=[T]*/
-  /*omit.*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
+  /*prod:nnbd-off.*/
   dynamic local(T t) => t;
   return local;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is captured in strong mode.
+/// A local function return type is captured in spec:nnbd-off mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 method3<T>(dynamic o) {
-  /*strong.fields=[T,o],free=[T,o]*/
-  /*omit.fields=[o],free=[o]*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T,o],free=[T,o]*/
+  /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o]*/
   T local() => o;
   return local;
 }
@@ -65,8 +65,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 method6<T>() {
-  /*strong.fields=[T],free=[T]*/
-  /*omit.*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
+  /*prod:nnbd-off.*/
   dynamic local(T t) {
     /*fields=[t],free=[t]*/
     dynamic inner() => t;
@@ -81,8 +81,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 method7<T>(dynamic o) {
-  /*strong.fields=[T,o],free=[T,o]*/
-  /*omit.fields=[o],free=[o]*/
+  /*spec:nnbd-off|spec:nnbd-sdk.fields=[T,o],free=[T,o]*/
+  /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o]*/
   T local() {
     /*fields=[o],free=[o]*/
     dynamic inner() => o;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index e5afcba..ae298ae 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
@@ -26,27 +26,55 @@
 }
 
 class Class2a<T> {
-  /*strong.member: Class2a.field2:checked,emitted*/
-  /*omit.member: Class2a.field2:emitted*/
+  /*spec:nnbd-sdk.member: Class2a.field2:
+   checked,
+   emitted
+  */
+  /*spec:nnbd-off.member: Class2a.field2:checked,emitted*/
+  /*prod:nnbd-off|prod:nnbd-sdk.member: Class2a.field2:emitted*/
   T field2;
 }
 
-/*strong.member: method2:calls=[set$field2(1)],params=1*/
-/*omit.member: method2:assign=[field2],params=1*/
+/*spec:nnbd-off.member: method2:calls=[set$field2(1)],params=1*/
+/*prod:nnbd-off.member: method2:assign=[field2],params=1*/
 @pragma('dart2js:noInline')
+/*spec:nnbd-sdk.member: method2:
+ calls=[set$field2(1)],
+ params=1
+*/
+/*prod:nnbd-sdk.member: method2:
+ assign=[field2],
+ params=1
+*/
 method2(dynamic c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*strong.member: Class3a.field3:checked,emitted*/
-  /*omit.member: Class3a.field3:emitted,set=simple*/
+  /*spec:nnbd-sdk.member: Class3a.field3:
+   checked,
+   emitted
+  */
+  /*prod:nnbd-sdk.member: Class3a.field3:
+   emitted,
+   set=simple
+  */
+  /*spec:nnbd-off.member: Class3a.field3:checked,emitted*/
+  /*prod:nnbd-off.member: Class3a.field3:emitted,set=simple*/
   int field3;
 }
 
 class Class3b {
-  /*strong.member: Class3b.field3:checked,emitted*/
-  /*omit.member: Class3b.field3:emitted,set=simple*/
+  /*spec:nnbd-sdk.member: Class3b.field3:
+   checked,
+   emitted
+  */
+  /*prod:nnbd-sdk.member: Class3b.field3:
+   emitted,
+   set=simple
+  */
+  /*spec:nnbd-off.member: Class3b.field3:checked,emitted*/
+  /*prod:nnbd-off.member: Class3b.field3:emitted,set=simple*/
   int field3;
 }
 
@@ -57,15 +85,31 @@
 }
 
 class Class4a {
-  /*strong.member: Class4a.field4:checked,emitted*/
-  /*omit.member: Class4a.field4:emitted,set=simple*/
+  /*spec:nnbd-sdk.member: Class4a.field4:
+   checked,
+   emitted
+  */
+  /*prod:nnbd-sdk.member: Class4a.field4:
+   emitted,
+   set=simple
+  */
+  /*spec:nnbd-off.member: Class4a.field4:checked,emitted*/
+  /*prod:nnbd-off.member: Class4a.field4:emitted,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*strong.member: Class4b.field4:checked,emitted*/
-  /*omit.member: Class4b.field4:emitted,set=simple*/
+  /*spec:nnbd-off.member: Class4b.field4:checked,emitted*/
+  /*prod:nnbd-off.member: Class4b.field4:emitted,set=simple*/
   @override
+  /*spec:nnbd-sdk.member: Class4b.field4:
+   checked,
+   emitted
+  */
+  /*prod:nnbd-sdk.member: Class4b.field4:
+   emitted,
+   set=simple
+  */
   int field4;
 }
 
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
index 053a59c..cef28b2 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
@@ -26,27 +26,51 @@
 }
 
 class Class2a<T> {
-  /*strong.member: Class2a.field2:checked,elided*/
-  /*omit.member: Class2a.field2:elided*/
+  /*spec:nnbd-sdk.member: Class2a.field2:
+   checked,
+   elided
+  */
+  /*spec:nnbd-off.member: Class2a.field2:checked,elided*/
+  /*prod:nnbd-off|prod:nnbd-sdk.member: Class2a.field2:elided*/
   T field2;
 }
 
-/*strong.member: method2:calls=[set$field2(1)],params=1*/
-/*omit.member: method2:params=1*/
+/*spec:nnbd-off.member: method2:calls=[set$field2(1)],params=1*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: method2:params=1*/
 @pragma('dart2js:noInline')
+/*spec:nnbd-sdk.member: method2:
+ calls=[set$field2(1)],
+ params=1
+*/
 method2(dynamic c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*strong.member: Class3a.field3:checked,elided*/
-  /*omit.member: Class3a.field3:elided,set=simple*/
+  /*spec:nnbd-sdk.member: Class3a.field3:
+   checked,
+   elided
+  */
+  /*prod:nnbd-sdk.member: Class3a.field3:
+   elided,
+   set=simple
+  */
+  /*spec:nnbd-off.member: Class3a.field3:checked,elided*/
+  /*prod:nnbd-off.member: Class3a.field3:elided,set=simple*/
   int field3;
 }
 
 class Class3b {
-  /*strong.member: Class3b.field3:checked,elided*/
-  /*omit.member: Class3b.field3:elided,set=simple*/
+  /*spec:nnbd-sdk.member: Class3b.field3:
+   checked,
+   elided
+  */
+  /*prod:nnbd-sdk.member: Class3b.field3:
+   elided,
+   set=simple
+  */
+  /*spec:nnbd-off.member: Class3b.field3:checked,elided*/
+  /*prod:nnbd-off.member: Class3b.field3:elided,set=simple*/
   int field3;
 }
 
@@ -57,15 +81,31 @@
 }
 
 class Class4a {
-  /*strong.member: Class4a.field4:checked,elided*/
-  /*omit.member: Class4a.field4:elided,set=simple*/
+  /*spec:nnbd-sdk.member: Class4a.field4:
+   checked,
+   elided
+  */
+  /*prod:nnbd-sdk.member: Class4a.field4:
+   elided,
+   set=simple
+  */
+  /*spec:nnbd-off.member: Class4a.field4:checked,elided*/
+  /*prod:nnbd-off.member: Class4a.field4:elided,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*strong.member: Class4b.field4:checked,elided*/
-  /*omit.member: Class4b.field4:elided,set=simple*/
+  /*spec:nnbd-off.member: Class4b.field4:checked,elided*/
+  /*prod:nnbd-off.member: Class4b.field4:elided,set=simple*/
   @override
+  /*spec:nnbd-sdk.member: Class4b.field4:
+   checked,
+   elided
+  */
+  /*prod:nnbd-sdk.member: Class4b.field4:
+   elided,
+   set=simple
+  */
   int field4;
 }
 
diff --git a/tests/compiler/dart2js/codegen/model_data/marker.options b/tests/compiler/dart2js/codegen/model_data/marker.options
index f7d45f7..ab72a7b2 100644
--- a/tests/compiler/dart2js/codegen/model_data/marker.options
+++ b/tests/compiler/dart2js/codegen/model_data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/codegen/model_test.dart
-omit=tests/compiler/dart2js/codegen/model_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/codegen/model_test.dart
+prod:nnbd-off=tests/compiler/dart2js/codegen/model_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/codegen/model_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/codegen/model_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
index e26d48d..654b5bb 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
@@ -20,8 +20,15 @@
 @pragma('dart2js:noInline')
 void bar(I2 x) {}
 
-/*strong.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
-/*omit.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*spec:nnbd-off|prod:nnbd-off.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*spec:nnbd-sdk|prod:nnbd-sdk.member: main:
+ calls=[
+  bar(1),
+  bar(1),
+  foo(1),
+  foo(1)],
+ params=0
+*/
 main() {
   dynamic f = bar;
 
diff --git a/tests/compiler/dart2js/codegen/model_test.dart b/tests/compiler/dart2js/codegen/model_test.dart
index 95dedea..9e694ee 100644
--- a/tests/compiler/dart2js/codegen/model_test.dart
+++ b/tests/compiler/dart2js/codegen/model_test.dart
@@ -53,7 +53,7 @@
 
   @override
   DataInterpreter<Features> get dataValidator =>
-      const FeaturesDataInterpreter();
+      const FeaturesDataInterpreter(wildcard: '*');
 }
 
 class Tags {
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
index f31c25c..832e2f2 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
@@ -6,11 +6,12 @@
 
 import 'lib1.dart' deferred as lib;
 
-/*member: main:
+/*spec:nnbd-off.member: main:
  OutputUnit(main, {}),
  constants=[
   MapConstant(<int, dynamic Function({M b})>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]
 */
+/*spec:nnbd-sdk.member: main:OutputUnit(main, {}),constants=[MapConstant(<int*, dynamic Function({M* b})*>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]*/
 main() async {
   await lib.loadLibrary();
   print(lib.table[1]);
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
index 6828e57..9521da6 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
@@ -9,10 +9,11 @@
 
 typedef dynamic G<T>(T v);
 
-/*member: m:
+/*spec:nnbd-off.member: m:
  OutputUnit(1, {b}),
  constants=[InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
 */
+/*spec:nnbd-sdk.member: m:OutputUnit(1, {b}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(1, {b})]*/
 m(int x, {G<int> f: getFoo}) {
   print(f(x));
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
index 4ca1497..2f185de 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
@@ -9,11 +9,12 @@
 
 typedef dynamic G<T>(T v);
 
-/*member: m:
+/*spec:nnbd-off.member: m:
  OutputUnit(1, {b}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
 */
+/*spec:nnbd-sdk.member: m:OutputUnit(1, {b}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(1, {b})]*/
 m(int x, {G<int> f: getFoo}) {
   print(f(x));
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
index 00caeb1..e49ee5f 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
@@ -9,11 +9,12 @@
 
 typedef dynamic G<T, S>(T v, S w);
 
-/*member: m:
+/*spec:nnbd-off.member: m:
  OutputUnit(3, {c}),
  constants=[
   InstantiationConstant([int, int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
 */
+/*spec:nnbd-sdk.member: m:OutputUnit(3, {c}),constants=[InstantiationConstant([int*, int*],FunctionConstant(getFoo))=OutputUnit(3, {c})]*/
 m(int x, int y, {G<int, int> f: getFoo}) {
   print(f(x, y));
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
index 89d5d6d..ecf0bc4 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
@@ -9,11 +9,12 @@
 
 typedef dynamic G<T>(T v);
 
-/*member: m:
+/*spec:nnbd-off.member: m:
  OutputUnit(2, {b}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(2, {b})]
 */
+/*spec:nnbd-sdk.member: m:OutputUnit(2, {b}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(2, {b})]*/
 m(int x, {G<int> f: getFoo}) {
   print(f(x));
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
index d7a9c46..714e91f 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
@@ -9,11 +9,12 @@
 
 typedef dynamic G<T>(T v);
 
-/*member: m:
+/*spec:nnbd-off.member: m:
  OutputUnit(3, {c}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
 */
+/*spec:nnbd-sdk.member: m:OutputUnit(3, {c}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(3, {c})]*/
 m(int x, {G<int> f: getFoo}) {
   print(f(x));
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/marker.options b/tests/compiler/dart2js/deferred_loading/data/marker.options
index 94f0636..c970e11 100644
--- a/tests/compiler/dart2js/deferred_loading/data/marker.options
+++ b/tests/compiler/dart2js/deferred_loading/data/marker.options
@@ -1 +1,2 @@
-strong=tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
index 016ba07..a236b19 100644
--- a/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
@@ -9,12 +9,13 @@
 import "package:expect/expect.dart";
 import "lib1.dart";
 
-/*member: foo:
+/*spec:nnbd-off.member: foo:
  OutputUnit(3, {lib2}),
  constants=[
   ListConstant(<Map<int,int>>[MapConstant(<int, int>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),
   MapConstant(<int, int>{IntConstant(1): IntConstant(3)})=OutputUnit(3, {lib2})]
 */
+/*spec:nnbd-sdk.member: foo:OutputUnit(3, {lib2}),constants=[ListConstant(<Map<int*,int*>*>[MapConstant(<int*, int*>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),MapConstant(<int*, int*>{IntConstant(1): IntConstant(3)})=OutputUnit(3, {lib2})]*/
 foo() {
   Expect.equals(1, C.foo());
   Expect.mapEquals({}, C1.foo);
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
index d9b4bac..2423196 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
@@ -8,7 +8,7 @@
 import 'lib2.dart' as lib2;
 import 'lib3.dart' deferred as lib3;
 
-/*member: main:
+/*spec:nnbd-off.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(A<B>())=OutputUnit(1, {lib1}),
@@ -16,6 +16,7 @@
   ConstructedConstant(C<D>())=OutputUnit(main, {}),
   ConstructedConstant(E<F>())=OutputUnit(3, {lib3})]
 */
+/*spec:nnbd-sdk.member: main:OutputUnit(main, {}),constants=[ConstructedConstant(A<B*>())=OutputUnit(1, {lib1}),ConstructedConstant(A<F*>())=OutputUnit(1, {lib1}),ConstructedConstant(C<D*>())=OutputUnit(main, {}),ConstructedConstant(E<F*>())=OutputUnit(3, {lib3})]*/
 main() async {
   await lib1.loadLibrary();
   lib1.field1;
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index 96b7600..f25018a 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -34,11 +34,9 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, const OutputUnitDataComputer(),
-        options: compilerOptions,
-        args: args,
-        setUpFunction: () {
+        options: compilerOptions, args: args, setUpFunction: () {
       importPrefixes.clear();
-    }, testedConfigs: allStrongConfigs);
+    }, testedConfigs: allSpecConfigs);
   });
 }
 
diff --git a/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart b/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
index c9a6b53..1919b8a 100644
--- a/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
+++ b/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
@@ -10,9 +10,10 @@
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 
-import 'package:_fe_analyzer_shared/src/util/filenames.dart';
 import 'package:compiler/compiler.dart' as compiler;
 
+import '../helpers/memory_compiler.dart';
+
 const Map<String, String> SOURCES = const {
   "/main.dart": """
     import "foo.dart";
@@ -48,9 +49,8 @@
   var entrypoint = Uri.parse("file:///main.dart");
 
   // Find the path to sdk/ in the repo relative to this script.
-  Uri librariesSpec = Uri.base.resolve('sdk/lib/libraries.json');
-  var platformDir =
-      Uri.parse(nativeToUriPath(Platform.resolvedExecutable)).resolve('.');
+  Uri librariesSpec = sdkLibrariesSpecificationUri;
+  var platformDir = sdkPlatformBinariesPath;
   asyncTest(() => compiler.compile(
           entrypoint,
           librariesSpec,
diff --git a/tests/compiler/dart2js/end_to_end/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
index 4a045ee..a5182d3 100644
--- a/tests/compiler/dart2js/end_to_end/exit_code_test.dart
+++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -31,6 +31,7 @@
 import 'package:compiler/src/universe/world_impact.dart';
 import 'package:compiler/src/world.dart';
 import 'diagnostic_reporter_helper.dart';
+import '../helpers/memory_compiler.dart';
 
 class TestCompiler extends CompilerImpl {
   final String testMarker;
@@ -192,7 +193,8 @@
     entry.compileFunc = compile;
 
     List<String> args = new List<String>.from(options)
-      ..add("--libraries-spec=${Uri.base.resolve('sdk/lib/libraries.json')}")
+      ..add("--libraries-spec=$sdkLibrariesSpecificationUri")
+      ..add("--platform-binaries=$sdkPlatformBinariesPath")
       ..add("tests/compiler/dart2js/end_to_end/data/exit_code_helper.dart");
     Future result = entry.internalMain(args);
     return result.catchError((e, s) {
diff --git a/tests/compiler/dart2js/end_to_end/library_env_test.dart b/tests/compiler/dart2js/end_to_end/library_env_test.dart
index 996bedf..ac96c89 100644
--- a/tests/compiler/dart2js/end_to_end/library_env_test.dart
+++ b/tests/compiler/dart2js/end_to_end/library_env_test.dart
@@ -8,8 +8,8 @@
 /// environment variable set.
 
 import 'dart:async';
-import 'dart:io';
 
+import '../helpers/memory_compiler.dart';
 import '../helpers/memory_source_file_helper.dart';
 
 import "package:async_helper/async_helper.dart";
@@ -71,8 +71,6 @@
   }
 }
 
-final platformDir = Uri.parse(Platform.resolvedExecutable).resolve('.');
-
 class CustomCompiler extends CompilerImpl {
   CustomCompiler(List<String> options, Map<String, String> environment)
       : super(
@@ -80,9 +78,9 @@
             const NullCompilerOutput(),
             const DummyCompilerDiagnostics(),
             CompilerOptions.parse(
-                ['--platform-binaries=$platformDir']..addAll(options),
-                librariesSpecificationUri:
-                    Uri.base.resolve("sdk/lib/libraries.json"))
+                ['--platform-binaries=$sdkPlatformBinariesPath']
+                  ..addAll(options),
+                librariesSpecificationUri: sdkLibrariesSpecificationUri)
               ..environment = environment);
 }
 
diff --git a/tests/compiler/dart2js/end_to_end/no_platform_test.dart b/tests/compiler/dart2js/end_to_end/no_platform_test.dart
index 5699366..ef897a9 100644
--- a/tests/compiler/dart2js/end_to_end/no_platform_test.dart
+++ b/tests/compiler/dart2js/end_to_end/no_platform_test.dart
@@ -12,6 +12,7 @@
 import 'package:kernel/target/targets.dart' hide DiagnosticReporter;
 import 'package:front_end/src/api_prototype/standard_file_system.dart' as fe;
 import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
+import '../helpers/memory_compiler.dart';
 
 main() {
   runTest(Map<fe.ExperimentalFlag, bool> experimentalFlags) async {
@@ -19,8 +20,7 @@
         fe.initializeCompiler(
             null,
             new Dart2jsTarget('dart2js', new TargetFlags()),
-            Uri.base
-                .resolve('sdk/lib/libraries.json'), // librariesSpecificationUri
+            sdkLibrariesSpecificationUri,
             [], // additionalDills
             Uri.base.resolve('.packages'), // packagesFileUri
             experimentalFlags: experimentalFlags,
@@ -37,7 +37,9 @@
   }
 
   asyncTest(() async {
-    await runTest(const {});
-    await runTest(const {fe.ExperimentalFlag.extensionMethods: true});
+    Map<fe.ExperimentalFlag, bool> baseFlags = {
+      fe.ExperimentalFlag.nonNullable: isDart2jsNnbd
+    };
+    await runTest(baseFlags);
   });
 }
diff --git a/tests/compiler/dart2js/end_to_end/output_type_test.dart b/tests/compiler/dart2js/end_to_end/output_type_test.dart
index 150e8f4..bd7c075 100644
--- a/tests/compiler/dart2js/end_to_end/output_type_test.dart
+++ b/tests/compiler/dart2js/end_to_end/output_type_test.dart
@@ -22,6 +22,8 @@
 import 'package:compiler/src/tracer.dart' show TRACE_FILTER_PATTERN_FOR_TEST;
 import 'package:expect/expect.dart';
 
+import '../helpers/memory_compiler.dart';
+
 class TestRandomAccessFileOutputProvider implements CompilerOutput {
   final RandomAccessFileOutputProvider provider;
   List<String> outputs = <String>[];
@@ -44,7 +46,8 @@
 Future<Null> test(List<String> arguments, List<String> expectedOutput,
     {List<String> groupOutputs: const <String>[]}) async {
   List<String> options = new List<String>.from(arguments)
-    ..add("--libraries-spec=${Uri.base.resolve('sdk/lib/libraries.json')}");
+    ..add("--platform-binaries=$sdkPlatformBinariesPath")
+    ..add("--libraries-spec=$sdkLibrariesSpecificationUri");
   print('--------------------------------------------------------------------');
   print('dart2js ${options.join(' ')}');
   TestRandomAccessFileOutputProvider outputProvider;
@@ -90,7 +93,7 @@
       'custom.js_1.part.js', 'custom.js_1.part.js.map',
       'def/deferred.json', // From --deferred-map
       'custom.js.info.json', // From --dump-info
-      'dart.cfg', // From TRACE_FILTER_PATTERN_FOR_TEST
+      'custom.js.cfg', // From TRACE_FILTER_PATTERN_FOR_TEST
     ], groupOutputs: [
       '.dot', // From PRINT_GRAPH
     ]);
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 20e6173..d6da685 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -19,6 +19,7 @@
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' as ir;
 
+import '../helpers/compiler_helper.dart';
 import '../helpers/memory_compiler.dart';
 import '../equivalence/id_equivalence.dart';
 
@@ -26,42 +27,54 @@
     show DataInterpreter, StringDataInterpreter;
 export '../helpers/memory_compiler.dart' show CollectedMessage;
 
-const String strongMarker = 'strong';
-const String omitMarker = 'omit';
+const String specWithNnbdOffMarker = 'spec:nnbd-off';
+const String prodWithNnbdOffMarker = 'prod:nnbd-off';
+const String specWithNnbdSdkMarker = 'spec:nnbd-sdk';
+const String prodWithNnbdSdkMarker = 'prod:nnbd-sdk';
 
-const TestConfig strongConfig =
-    const TestConfig(strongMarker, 'strong mode', []);
+const TestConfig specWithNnbdOffConfig = const TestConfig(
+    specWithNnbdOffMarker, 'compliance mode with nnbd off', []);
 
-const TestConfig omitConfig = const TestConfig(
-    omitMarker,
-    'strong mode without implicit checks',
+const TestConfig prodWithNnbdOffConfig = const TestConfig(
+    prodWithNnbdOffMarker,
+    'production mode with nnbd off',
+    [Flags.omitImplicitChecks, Flags.laxRuntimeTypeToString]);
+
+const TestConfig specWithNnbdSdkConfig = const TestConfig(
+    specWithNnbdSdkMarker, 'compliance mode with nnbd sdk', []);
+
+const TestConfig prodWithNnbdSdkConfig = const TestConfig(
+    prodWithNnbdSdkMarker,
+    'production mode with nnbd sdk',
     [Flags.omitImplicitChecks, Flags.laxRuntimeTypeToString]);
 
 const List<String> allInternalMarkers = const [
-  strongMarker,
-  omitMarker,
+  specWithNnbdOffMarker,
+  prodWithNnbdOffMarker,
+  specWithNnbdSdkMarker,
+  prodWithNnbdSdkMarker
 ];
 
 /// Default internal configurations not including experimental features.
-const List<TestConfig> defaultInternalConfigs = const [
-  strongConfig,
-  omitConfig
-];
+List<TestConfig> defaultInternalConfigs = isDart2jsNnbd
+    ? const [specWithNnbdSdkConfig, prodWithNnbdSdkConfig]
+    : const [specWithNnbdOffConfig, prodWithNnbdOffConfig];
 
 /// All internal configurations including experimental features.
-const List<TestConfig> allInternalConfigs = const [
-  strongConfig,
-  omitConfig,
-];
+List<TestConfig> allInternalConfigs = isDart2jsNnbd
+    ? const [specWithNnbdSdkConfig, prodWithNnbdSdkConfig]
+    : const [specWithNnbdOffConfig, prodWithNnbdOffConfig];
 
 /// Compliance mode configurations (with strong mode checks) including
 /// experimental features.
-const List<TestConfig> allStrongConfigs = const [
-  strongConfig,
-];
+List<TestConfig> allSpecConfigs = isDart2jsNnbd
+    ? const [specWithNnbdSdkConfig]
+    : const [specWithNnbdOffConfig];
 
 /// Test configuration used in tests shared with CFE.
-const TestConfig sharedConfig = const TestConfig(dart2jsMarker, 'dart2js', []);
+TestConfig sharedConfig = isDart2jsNnbd
+    ? const TestConfig(dart2jsWithNnbdSdkMarker, 'dart2js with nnbd sdk', [])
+    : const TestConfig(dart2jsMarker, 'dart2js', []);
 
 abstract class DataComputer<T> {
   const DataComputer();
@@ -400,7 +413,8 @@
     int shards: 1,
     int shardIndex: 0,
     void onTest(Uri uri),
-    List<TestConfig> testedConfigs = defaultInternalConfigs}) async {
+    List<TestConfig> testedConfigs = const []}) async {
+  if (testedConfigs.isEmpty) testedConfigs = defaultInternalConfigs;
   Set<String> testedMarkers =
       testedConfigs.map((config) => config.marker).toSet();
   Expect.isTrue(
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
index 4c7031d..bb22f2a 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -19,7 +19,8 @@
 }
 
 class Class2 {
-  /*strong.member: Class2.field2:constant=BoolConstant(true)*/
+  /*spec:nnbd-off|spec:nnbd-sdk.member: Class2.field2:constant=BoolConstant(true)*/
+  /*prod:nnbd-off|prod:nnbd-sdk.strong.member: Class2.field2:constant=BoolConstant(true)*/
   final bool field2;
 
   const Class2({this.field2: false});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/marker.options b/tests/compiler/dart2js/field_analysis/jdata/marker.options
index e9de6cf..f333b74 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/marker.options
+++ b/tests/compiler/dart2js/field_analysis/jdata/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
-omit=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+prod:nnbd-off=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
index 63c45ec..b4886b3 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
@@ -178,10 +178,12 @@
   /*member: Class1.field9b:constant=ListConstant([])*/
   var field9b = const [];
 
-  /*member: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+  /*spec:nnbd-sdk.member: Class1.field9c:initial=ListConstant(<int*>[IntConstant(0), IntConstant(1)])*/
   var field9c = const [0, 1];
 
-  /*member: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+  /*spec:nnbd-sdk.member: Class1.field9d:constant=ListConstant(<int*>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
   var field9d = const [0, 1, 2];
 
   /*member: Class1.field10a:initial=MapConstant({})*/
@@ -190,10 +192,12 @@
   /*member: Class1.field10b:constant=MapConstant({})*/
   var field10b = const {};
 
-  /*member: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+  /*spec:nnbd-sdk.member: Class1.field10c:initial=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
   var field10c = const {0: 1, 2: 3};
 
-  /*member: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+  /*spec:nnbd-sdk.member: Class1.field10d:constant=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
   var field10d = const {0: 1, 2: 3, 4: 5};
 
   /*member: Class1.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
@@ -270,10 +274,12 @@
   /*member: Class2.field9b:constant=ListConstant([])*/
   var field9b;
 
-  /*member: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+  /*spec:nnbd-sdk.member: Class2.field9c:initial=ListConstant(<int*>[IntConstant(0), IntConstant(1)])*/
   var field9c;
 
-  /*member: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+  /*spec:nnbd-sdk.member: Class2.field9d:constant=ListConstant(<int*>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
   var field9d;
 
   /*member: Class2.field10a:initial=MapConstant({})*/
@@ -282,10 +288,12 @@
   /*member: Class2.field10b:constant=MapConstant({})*/
   var field10b;
 
-  /*member: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+  /*spec:nnbd-sdk.member: Class2.field10c:initial=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
   var field10c;
 
-  /*member: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+  /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+  /*spec:nnbd-sdk.member: Class2.field10d:constant=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
   var field10d;
 
   /*member: Class2.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
index e301643..857f7e8 100644
--- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -20,7 +20,7 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('jdata'));
     await checkTests(dataDir, const JAllocatorAnalysisDataComputer(),
-        args: args, testedConfigs: allStrongConfigs);
+        args: args, testedConfigs: allSpecConfigs);
   });
 }
 
diff --git a/tests/compiler/dart2js/field_analysis/kdata/marker.options b/tests/compiler/dart2js/field_analysis/kdata/marker.options
index 16bd064..19ad6c1 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/marker.options
+++ b/tests/compiler/dart2js/field_analysis/kdata/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
-omit=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+prod:nnbd-off=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
index 3a8f113..22af00e 100644
--- a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
@@ -20,7 +20,7 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('kdata'));
     await checkTests(dataDir, const KAllocatorAnalysisDataComputer(),
-        args: args, testedConfigs: allStrongConfigs);
+        args: args, testedConfigs: allSpecConfigs);
   });
 }
 
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index b82a36d1..56b387d 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -69,32 +69,44 @@
     """));
 
     var types = env.types;
+    var options = env.compiler.options;
+
+    String printType(DartType type) => type.toStructuredText(
+        printLegacyStars: options.printLegacyStars,
+        useLegacySubtyping: options.useLegacySubtyping);
+
+    List<String> printTypes(List<DartType> types) =>
+        types.map(printType).toList();
 
     testToString(FunctionType type, String expectedToString) {
-      Expect.equals(expectedToString, type.toString());
+      Expect.equals(expectedToString, printType(type));
     }
 
     testBounds(FunctionType type, List<DartType> expectedBounds) {
       Expect.equals(expectedBounds.length, type.typeVariables.length,
-          "Unexpected type variable count in $type.");
+          "Unexpected type variable count in ${printType(type)}.");
       for (int i = 0; i < expectedBounds.length; i++) {
         Expect.equals(expectedBounds[i], type.typeVariables[i].bound,
-            "Unexpected ${i}th bound in $type.");
+            "Unexpected ${i}th bound in ${printType(type)}.");
       }
     }
 
     testInstantiate(FunctionType type, List<DartType> instantiation,
         String expectedToString) {
       DartType result = types.instantiate(type, instantiation);
-      Expect.equals(expectedToString, result.toString(),
-          "Unexpected instantiation of $type with $instantiation: $result");
+      String resultString = printType(result);
+      Expect.equals(
+          expectedToString,
+          resultString,
+          "Unexpected instantiation of ${printType(type)} with $instantiation: "
+          "$resultString");
     }
 
     void testSubst(List<DartType> arguments, List<DartType> parameters,
         DartType type1, String expectedToString) {
       DartType subst = types.subst(arguments, parameters, type1);
-      Expect.equals(expectedToString, subst.toString(),
-          "$type1.subst($arguments,$parameters)");
+      Expect.equals(expectedToString, printType(subst),
+          "${printType(type1)}.subst(${printTypes(arguments)},${printTypes(parameters)})");
     }
 
     testRelations(DartType a, DartType b,
@@ -102,19 +114,21 @@
       if (areEqual) {
         isSubtype = true;
       }
+      String aString = printType(a);
+      String bString = printType(b);
       Expect.equals(
           areEqual,
           a == b,
-          "Expected `$a` and `$b` to be ${areEqual ? 'equal' : 'non-equal'}, "
-          "but they are not.");
+          "Expected `$aString` and `$bString` to be "
+          "${areEqual ? 'equal' : 'non-equal'}, but they are not.");
       Expect.equals(
           isSubtype,
           env.isSubtype(a, b),
-          "Expected `$a` ${isSubtype ? '' : 'not '}to be a subtype of `$b`, "
-          "but it is${isSubtype ? ' not' : ''}.");
+          "Expected `$aString` ${isSubtype ? '' : 'not '}to be a subtype of "
+          "`$bString`, but it is${isSubtype ? ' not' : ''}.");
       if (isSubtype) {
         Expect.isTrue(env.isPotentialSubtype(a, b),
-            '$a <: $b but not a potential subtype.');
+            '$aString <: $bString but not a potential subtype.');
       }
     }
 
@@ -289,7 +303,7 @@
       Expect.isTrue(
           functionTypeVariables.isEmpty,
           "Function type variables found on constructor $constructor: "
-          "$functionTypeVariables");
+          "${printTypes(functionTypeVariables)}");
     });
   });
 }
diff --git a/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
index ef4dfc5..a6a17a0 100644
--- a/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
+++ b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
@@ -34,9 +34,11 @@
     """);
 
     for (FunctionTypeData data in signatures) {
-      FunctionType functionType = env.getElementType('t${data.name}');
+      FunctionType functionType =
+          env.getElementType('t${data.name}').withoutNullability;
       FunctionEntity method = env.getElement('m${data.name}');
-      FunctionType methodType = env.getElementType('m${data.name}');
+      FunctionType methodType =
+          env.getElementType('m${data.name}').withoutNullability;
       ParameterStructure parameterStructure = method.parameterStructure;
       Expect.equals(functionType, methodType, "Type mismatch on $data");
       Expect.equals(
diff --git a/tests/compiler/dart2js/helpers/compiler_helper.dart b/tests/compiler/dart2js/helpers/compiler_helper.dart
index 9c40a59..5a39fad 100644
--- a/tests/compiler/dart2js/helpers/compiler_helper.dart
+++ b/tests/compiler/dart2js/helpers/compiler_helper.dart
@@ -7,6 +7,7 @@
 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';
diff --git a/tests/compiler/dart2js/helpers/d8_helper.dart b/tests/compiler/dart2js/helpers/d8_helper.dart
index 50edff3..dae47ad 100644
--- a/tests/compiler/dart2js/helpers/d8_helper.dart
+++ b/tests/compiler/dart2js/helpers/d8_helper.dart
@@ -61,7 +61,7 @@
   }
 
   List<String> d8Args = [
-    'sdk/lib/_internal/js_runtime/lib/preambles/d8.js',
+    '$sdkPath/_internal/js_runtime/lib/preambles/d8.js',
     output
   ];
   if (printSteps) print('Running: d8 ${d8Args.join(' ')}');
diff --git a/tests/compiler/dart2js/helpers/memory_compiler.dart b/tests/compiler/dart2js/helpers/memory_compiler.dart
index 761eb23..e941153 100644
--- a/tests/compiler/dart2js/helpers/memory_compiler.dart
+++ b/tests/compiler/dart2js/helpers/memory_compiler.dart
@@ -8,6 +8,7 @@
 
 import 'dart:async';
 
+import 'package:_fe_analyzer_shared/src/util/filenames.dart';
 import 'package:compiler/compiler.dart' show DiagnosticHandler;
 import 'package:compiler/compiler_new.dart'
     show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
@@ -24,6 +25,21 @@
 export 'package:compiler/compiler_new.dart' show CompilationResult;
 export 'diagnostic_helper.dart';
 
+bool isDart2jsNnbd =
+    Platform.environment['DART_CONFIGURATION'] == 'ReleaseX64NNBD';
+
+String sdkPath = isDart2jsNnbd ? 'sdk_nnbd/lib' : 'sdk/lib';
+
+String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json';
+
+Uri sdkLibrariesSpecificationUri =
+    Uri.base.resolve(sdkLibrariesSpecificationPath);
+
+Uri sdkPlatformBinariesUri =
+    Uri.parse(nativeToUriPath(Platform.resolvedExecutable)).resolve('.');
+
+String sdkPlatformBinariesPath = sdkPlatformBinariesUri.toString();
+
 class MultiDiagnostics implements CompilerDiagnostics {
   final List<CompilerDiagnostics> diagnosticsList;
 
@@ -107,7 +123,7 @@
     Uri librariesSpecificationUri,
     Uri packageConfig}) {
   retainDataForTesting = true;
-  librariesSpecificationUri ??= Uri.base.resolve('sdk/lib/libraries.json');
+  librariesSpecificationUri ??= sdkLibrariesSpecificationUri;
 
   if (packageConfig == null) {
     if (Platform.packageConfig != null) {
diff --git a/tests/compiler/dart2js/impact/data/as.dart b/tests/compiler/dart2js/impact/data/as.dart
index efe5dd4..b4c3f2d 100644
--- a/tests/compiler/dart2js/impact/data/as.dart
+++ b/tests/compiler/dart2js/impact/data/as.dart
@@ -11,14 +11,178 @@
   promoted(null);
 }
 
-/*member: explicitAs:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:String]*/
+/*spec:nnbd-off.member: explicitAs:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:String]
+*/
+/*spec:nnbd-sdk.member: explicitAs:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:String*]
+*/
 explicitAs(String i) {
   i.length;
   // ignore: unnecessary_cast
   return i as String;
 }
 
-/*member: implicitAs:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:String]*/
+/*spec:nnbd-off.member: implicitAs:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:String]
+*/
+/*spec:nnbd-sdk.member: implicitAs:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:String*]
+*/
 String implicitAs(String i) {
   dynamic j = i;
   i.length;
@@ -26,7 +190,91 @@
   return j;
 }
 
-/*member: promoted:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:String]*/
+/*spec:nnbd-off.member: promoted:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:String]
+*/
+/*spec:nnbd-sdk.member: promoted:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:String*]
+*/
 String promoted(dynamic i) {
   if (i is! String) return null;
   i.length;
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index c4f1a10..70738c5 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -219,13 +219,227 @@
   return () async* {};
 }
 
-/*member: testAsyncForIn:dynamic=[_StreamIterator.cancel(0),_StreamIterator.current,_StreamIterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),StreamIterator.(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_asyncAwait(2),_asyncRethrow(2),_asyncReturn(2),_asyncStartSync(2),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_makeAsyncAwaitCompleter<dynamic>(0),_wrapJsFunctionForAsync(1),findType(1),instanceType(1)],type=[impl:Stream<dynamic>,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*spec:nnbd-off.member: testAsyncForIn:
+ dynamic=[
+  _StreamIterator.cancel(0),
+  _StreamIterator.current,
+  _StreamIterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  StreamIterator.(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Stream<dynamic>,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+/*spec:nnbd-sdk.member: testAsyncForIn:
+ dynamic=[
+  _StreamIterator.cancel(0),
+  _StreamIterator.current,
+  _StreamIterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  StreamIterator.(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Stream<dynamic>*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testAsyncForIn(o) async {
   // ignore: UNUSED_LOCAL_VARIABLE
   await for (var e in o) {}
 }
 
-/*member: testAsyncForInTyped:dynamic=[_StreamIterator.cancel(0),_StreamIterator.current,_StreamIterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),StreamIterator.(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_asyncAwait(2),_asyncRethrow(2),_asyncReturn(2),_asyncStartSync(2),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_makeAsyncAwaitCompleter<dynamic>(0),_wrapJsFunctionForAsync(1),findType(1),instanceType(1)],type=[impl:Stream<dynamic>,impl:int,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*spec:nnbd-off.member: testAsyncForInTyped:
+ dynamic=[
+  _StreamIterator.cancel(0),
+  _StreamIterator.current,
+  _StreamIterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  StreamIterator.(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Stream<dynamic>,
+  impl:int,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+/*spec:nnbd-sdk.member: testAsyncForInTyped:
+ dynamic=[
+  _StreamIterator.cancel(0),
+  _StreamIterator.current,
+  _StreamIterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  StreamIterator.(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Stream<dynamic>*,
+  impl:int*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testAsyncForInTyped(o) async {
   // ignore: UNUSED_LOCAL_VARIABLE
   await for (int e in o) {}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index 4ba507b..4e7ab2c 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -139,7 +139,89 @@
 testForwardingConstructor() => new ForwardingConstructorClass(null);
 
 class ForwardingConstructorTypedSuperClass {
-  /*member: ForwardingConstructorTypedSuperClass.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
+  /*spec:nnbd-off.member: ForwardingConstructorTypedSuperClass.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:int]
+  */
+  /*spec:nnbd-sdk.member: ForwardingConstructorTypedSuperClass.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:int*]
+  */
   ForwardingConstructorTypedSuperClass(int arg);
 }
 
@@ -153,7 +235,113 @@
 testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
 
 class ForwardingConstructorGenericSuperClass<T> {
-  /*member: ForwardingConstructorGenericSuperClass.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:ForwardingConstructorGenericSuperClass.T]*/
+  /*spec:nnbd-off.member: ForwardingConstructorGenericSuperClass.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ForwardingConstructorGenericSuperClass.T]
+  */
+  /*spec:nnbd-sdk.member: ForwardingConstructorGenericSuperClass.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ForwardingConstructorGenericSuperClass.T*]
+  */
   ForwardingConstructorGenericSuperClass(T arg);
 }
 
@@ -183,18 +371,138 @@
 */
 testEnum() => Enum.A;
 
-/*member: staticGenericMethod:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,inst:List<staticGenericMethod.T>,param:Object,param:staticGenericMethod.T]*/
+/*spec:nnbd-off.member: staticGenericMethod:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  inst:List<staticGenericMethod.T>,
+  param:Object,
+  param:staticGenericMethod.T]
+*/
+/*spec:nnbd-sdk.member: staticGenericMethod:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  inst:List<staticGenericMethod.T*>,
+  param:Object*,
+  param:staticGenericMethod.T*]
+*/
 List<T> staticGenericMethod<T>(T arg) => [arg];
 
-/*member: testStaticGenericMethod:
+/*spec:nnbd-off.member: testStaticGenericMethod:
   static=[staticGenericMethod<bool>(1)],
   type=[inst:JSBool]
 */
+/*spec:nnbd-sdk.member: testStaticGenericMethod:
+ static=[staticGenericMethod<bool*>(1)],
+ type=[inst:JSBool]
+*/
 testStaticGenericMethod() {
   staticGenericMethod<bool>(true);
 }
 
-/*member: testInstanceGenericMethod:dynamic=[exact:GenericClass.genericMethod<bool>(1)],static=[GenericClass.generative(0),checkTypeBound(4),throwTypeError(1)],type=[inst:JSBool]*/
+/*spec:nnbd-off.member: testInstanceGenericMethod:dynamic=[exact:GenericClass.genericMethod<bool>(1)],static=[GenericClass.generative(0),checkTypeBound(4),throwTypeError(1)],type=[inst:JSBool]*/
+/*spec:nnbd-sdk.member: testInstanceGenericMethod:
+ dynamic=[exact:GenericClass.genericMethod<bool*>(1)],
+ static=[
+  GenericClass.generative(0),
+  checkTypeBound(4),
+  throwTypeError(1)],
+ type=[inst:JSBool]
+*/
 testInstanceGenericMethod() {
   new GenericClass<int, String>.generative().genericMethod<bool>(false);
 }
@@ -230,7 +538,117 @@
 class GenericClass<X, Y> {
   const GenericClass.generative();
 
-  /*member: GenericClass.genericMethod:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,inst:Map<GenericClass.X,genericMethod.T>,param:Object,param:genericMethod.T]*/
+  /*spec:nnbd-off.member: GenericClass.genericMethod:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    inst:Map<GenericClass.X,genericMethod.T>,
+    param:Object,
+    param:genericMethod.T]
+  */
+  /*spec:nnbd-sdk.member: GenericClass.genericMethod:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    inst:Map<GenericClass.X*,genericMethod.T*>,
+    param:Object*,
+    param:genericMethod.T*]
+  */
   Map<X, T> genericMethod<T>(T arg) => {null: arg};
 }
 
diff --git a/tests/compiler/dart2js/impact/data/constants/lib.dart b/tests/compiler/dart2js/impact/data/constants/lib.dart
index 3f0a149..964ffcb 100644
--- a/tests/compiler/dart2js/impact/data/constants/lib.dart
+++ b/tests/compiler/dart2js/impact/data/constants/lib.dart
@@ -44,7 +44,113 @@
 
 const typeLiteralField = String;
 
-/*member: id:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
+/*spec:nnbd-off.member: id:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Object,
+  param:id.T]
+*/
+/*spec:nnbd-sdk.member: id:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Object*,
+  param:id.T*]
+*/
 T id<T>(T t) => t;
 
 const int Function(int) _instantiation = id;
diff --git a/tests/compiler/dart2js/impact/data/constants/main.dart b/tests/compiler/dart2js/impact/data/constants/main.dart
index 1b959de..3a80aee 100644
--- a/tests/compiler/dart2js/impact/data/constants/main.dart
+++ b/tests/compiler/dart2js/impact/data/constants/main.dart
@@ -7,7 +7,7 @@
 import 'lib.dart';
 import 'lib.dart' deferred as defer;
 
-/*member: main:static=**/
+/*member: main:static=%*/
 main() {
   nullLiteral();
   boolLiteral();
@@ -91,7 +91,10 @@
 /*member: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteral() => #foo;
 
-/*member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: listLiteral:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 listLiteral() => const [true, false];
 
 /*member: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
@@ -109,7 +112,16 @@
 */
 instanceConstant() => const Class(true, false);
 
-/*member: typeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-off.member: typeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-sdk.member: typeLiteral:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:String*]
+*/
 typeLiteral() {
   const dynamic local = String;
   return local;
@@ -151,7 +163,10 @@
 /*member: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteralRef() => symbolLiteralField;
 
-/*member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: listLiteralRef:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 listLiteralRef() => listLiteralField;
 
 /*member: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
@@ -169,7 +184,16 @@
 */
 instanceConstantRef() => instanceConstantField;
 
-/*member: typeLiteralRef:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-off.member: typeLiteralRef:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-sdk.member: typeLiteralRef:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:String*]
+*/
 typeLiteralRef() => typeLiteralField;
 
 /*member: instantiationRef:static=[closureFunctionType(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
@@ -201,7 +225,10 @@
 symbolLiteralDeferred() => defer.symbolLiteralField;
 
 // TODO(johnniwinther): Should we record that this is deferred?
-/*member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: listLiteralDeferred:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 listLiteralDeferred() => defer.listLiteralField;
 
 // TODO(johnniwinther): Should we record that this is deferred?
@@ -222,7 +249,16 @@
 */
 instanceConstantDeferred() => defer.instanceConstantField;
 
-/*member: typeLiteralDeferred:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String{defer}]*/
+/*spec:nnbd-off.member: typeLiteralDeferred:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String{defer}]*/
+/*spec:nnbd-sdk.member: typeLiteralDeferred:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:String*{defer}]
+*/
 typeLiteralDeferred() => defer.typeLiteralField;
 
 /*member: instantiationDeferred:static=[closureFunctionType(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index 3ffff0b..cba8812 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -111,7 +111,8 @@
   const Class.redirect();
 }
 
-/*member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*spec:nnbd-off.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*spec:nnbd-sdk.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int*,String*>]*/
 testConstRedirectingFactoryInvokeGeneric() {
   const GenericClass<int, String>.redirect();
 }
@@ -154,7 +155,89 @@
   /*member: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 
-  /*member: GenericClass.fact:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Object]*/
+  /*spec:nnbd-off.member: GenericClass.fact:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:Object]
+  */
+  /*spec:nnbd-sdk.member: GenericClass.fact:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:Object*]
+  */
   factory GenericClass.fact() => null;
 
   const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
diff --git a/tests/compiler/dart2js/impact/data/effectively_final.dart b/tests/compiler/dart2js/impact/data/effectively_final.dart
index d2677d7..ffb98ea 100644
--- a/tests/compiler/dart2js/impact/data/effectively_final.dart
+++ b/tests/compiler/dart2js/impact/data/effectively_final.dart
@@ -69,7 +69,107 @@
 /*member: _method1:type=[inst:JSNull]*/
 num _method1() => null;
 
-/*member: effectivelyFinalPromoted:dynamic=[int.+,num.+],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_method1(0),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32,is:int]*/
+/*spec:nnbd-off.member: effectivelyFinalPromoted:
+ dynamic=[
+  int.+,
+  num.+],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _method1(0),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  is:int]
+*/
+/*spec:nnbd-sdk.member: effectivelyFinalPromoted:
+ dynamic=[
+  int.+,
+  num.+],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _method1(0),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  is:int*]
+*/
 effectivelyFinalPromoted() {
   dynamic c = _method1();
   c + 0;
@@ -81,7 +181,109 @@
 /*member: _method2:type=[inst:JSNull]*/
 String _method2() => null;
 
-/*member: effectivelyFinalPromotedInvalid:dynamic=[String.+,int.+],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_method2(0),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,is:int]*/
+/*spec:nnbd-off.member: effectivelyFinalPromotedInvalid:
+ dynamic=[
+  String.+,
+  int.+],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _method2(0),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  is:int]
+*/
+/*spec:nnbd-sdk.member: effectivelyFinalPromotedInvalid:
+ dynamic=[
+  String.+,
+  int.+],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _method2(0),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  is:int*]
+*/
 effectivelyFinalPromotedInvalid() {
   dynamic c = _method2();
   c + '';
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index 3f2ef46..153a7bf 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -107,58 +107,1628 @@
 */
 testPreDec(o) => --o;
 
-/*member: testIs:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:Class]*/
+/*spec:nnbd-off.member: testIs:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:Class]
+*/
+/*spec:nnbd-sdk.member: testIs:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:Class*]
+*/
 testIs() => null is Class;
 
-/*member: testIsGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:GenericClass<int,String>]*/
+/*spec:nnbd-off.member: testIsGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int,String>]
+*/
+/*spec:nnbd-sdk.member: testIsGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int*,String*>*]
+*/
 testIsGeneric() => null is GenericClass<int, String>;
 
-/*member: testIsGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*spec:nnbd-off.member: testIsGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>]
+*/
+/*spec:nnbd-sdk.member: testIsGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsGenericRaw() => null is GenericClass;
 
-/*member: testIsGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*spec:nnbd-off.member: testIsGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>]
+*/
+/*spec:nnbd-sdk.member: testIsGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
 
-/*member: testIsNot:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:Class]*/
+/*spec:nnbd-off.member: testIsNot:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:Class]
+*/
+/*spec:nnbd-sdk.member: testIsNot:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:Class*]
+*/
 testIsNot() => null is! Class;
 
-/*member: testIsNotGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:GenericClass<int,String>]*/
+/*spec:nnbd-off.member: testIsNotGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int,String>]
+*/
+/*spec:nnbd-sdk.member: testIsNotGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int*,String*>*]
+*/
 testIsNotGeneric() => null is! GenericClass<int, String>;
 
-/*member: testIsNotGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*spec:nnbd-off.member: testIsNotGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>]
+*/
+/*spec:nnbd-sdk.member: testIsNotGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsNotGenericRaw() => null is! GenericClass;
 
-/*member: testIsNotGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*spec:nnbd-off.member: testIsNotGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>]
+*/
+/*spec:nnbd-sdk.member: testIsNotGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
 
-/*member: testIsTypedef:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function()]*/
+/*spec:nnbd-off.member: testIsTypedef:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function()]
+*/
+/*spec:nnbd-sdk.member: testIsTypedef:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function()*]
+*/
 testIsTypedef() => null is Typedef;
 
-/*member: testIsTypedefGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:int Function(String)]*/
+/*spec:nnbd-off.member: testIsTypedefGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:int Function(String)]
+*/
+/*spec:nnbd-sdk.member: testIsTypedefGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:int* Function(String*)*]
+*/
 testIsTypedefGeneric() => null is GenericTypedef<int, String>;
 
-/*member: testIsTypedefGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function(dynamic)]*/
+/*spec:nnbd-off.member: testIsTypedefGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)]
+*/
+/*spec:nnbd-sdk.member: testIsTypedefGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)*]
+*/
 testIsTypedefGenericRaw() => null is GenericTypedef;
 
-/*member: testIsTypedefGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function(dynamic)]*/
+/*spec:nnbd-off.member: testIsTypedefGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)]
+*/
+/*spec:nnbd-sdk.member: testIsTypedefGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)*]
+*/
 testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
 
-/*member: testIsTypedefDeep:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:List<int Function(dynamic Function(dynamic))>]*/
+/*spec:nnbd-off.member: testIsTypedefDeep:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:List<int Function(dynamic Function(dynamic))>]
+*/
+/*spec:nnbd-sdk.member: testIsTypedefDeep:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:List<int* Function(dynamic Function(dynamic)*)*>*]
+*/
 testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
 
-/*member: testAs:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:Class,inst:Closure,inst:JSBool]*/
+/*spec:nnbd-off.member: testAs:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:Class,
+  inst:Closure,
+  inst:JSBool]
+*/
+/*spec:nnbd-sdk.member: testAs:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:Class*,
+  inst:Closure,
+  inst:JSBool]
+*/
 // ignore: UNNECESSARY_CAST
 testAs(dynamic o) => o as Class;
 
-/*member: testAsGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2),throwRuntimeError(1)],type=[as:GenericClass<int,String>,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>]*/
+/*spec:nnbd-off.member: testAsGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<int,String>,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+/*spec:nnbd-sdk.member: testAsGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<int*,String*>*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
 // ignore: UNNECESSARY_CAST
 testAsGeneric(dynamic o) => o as GenericClass<int, String>;
 
-/*member: testAsGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:GenericClass<dynamic,dynamic>,inst:Closure,inst:JSBool]*/
+/*spec:nnbd-off.member: testAsGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<dynamic,dynamic>,
+  inst:Closure,
+  inst:JSBool]
+*/
+/*spec:nnbd-sdk.member: testAsGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<dynamic,dynamic>*,
+  inst:Closure,
+  inst:JSBool]
+*/
 // ignore: UNNECESSARY_CAST
 testAsGenericRaw(dynamic o) => o as GenericClass;
 
-/*member: testAsGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:GenericClass<dynamic,dynamic>,inst:Closure,inst:JSBool]*/
+/*spec:nnbd-off.member: testAsGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<dynamic,dynamic>,
+  inst:Closure,
+  inst:JSBool]
+*/
+/*spec:nnbd-sdk.member: testAsGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<dynamic,dynamic>*,
+  inst:Closure,
+  inst:JSBool]
+*/
 // ignore: UNNECESSARY_CAST
 testAsGenericDynamic(dynamic o) => o as GenericClass<dynamic, dynamic>;
 
@@ -170,7 +1740,95 @@
 /*member: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
 testIfNotNull(o) => o?.foo;
 
-/*member: testTypedIfNotNull:dynamic=[Class.==,Class.field],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class]*/
+/*spec:nnbd-off.member: testTypedIfNotNull:
+ dynamic=[
+  Class.==,
+  Class.field],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class]
+*/
+/*spec:nnbd-sdk.member: testTypedIfNotNull:
+ dynamic=[
+  Class.==,
+  Class.field],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class*]
+*/
 testTypedIfNotNull(Class o) => o?.field;
 
 /*member: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
index dcdb613..ac1d171 100644
--- a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
@@ -14,10 +14,230 @@
 /*member: C.:static=[Object.(0)]*/
 class C implements A<int>, B<String, bool> {}
 
-/*member: testA:dynamic=[call<A.T>(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),extractTypeArguments<A<dynamic>>(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[impl:A<dynamic>,impl:Function,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,is:A<A.T>]*/
+/*spec:nnbd-off.member: testA:
+ dynamic=[call<A.T>(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  extractTypeArguments<A<dynamic>>(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A<dynamic>,
+  impl:Function,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:A<A.T>]
+*/
+/*spec:nnbd-sdk.member: testA:
+ dynamic=[call<A.T>(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  extractTypeArguments<A<dynamic>*>(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A<dynamic>*,
+  impl:Function,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:A<A.T>]
+*/
 testA(c, f) => extractTypeArguments<A>(c, f);
 
-/*member: testB:dynamic=[call<B.S,B.U>(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),extractTypeArguments<B<dynamic,dynamic>>(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[impl:B<dynamic,dynamic>,impl:Function,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,is:B<B.S,B.U>]*/
+/*spec:nnbd-off.member: testB:
+ dynamic=[call<B.S,B.U>(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  extractTypeArguments<B<dynamic,dynamic>>(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:B<dynamic,dynamic>,
+  impl:Function,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:B<B.S,B.U>]
+*/
+/*spec:nnbd-sdk.member: testB:
+ dynamic=[call<B.S,B.U>(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  extractTypeArguments<B<dynamic,dynamic>*>(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:B<dynamic,dynamic>*,
+  impl:Function,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:B<B.S,B.U>]
+*/
 testB(c, f) => extractTypeArguments<B>(c, f);
 
 /*member: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/future_or.dart b/tests/compiler/dart2js/impact/data/future_or.dart
index 336fdef..0e51f38 100644
--- a/tests/compiler/dart2js/impact/data/future_or.dart
+++ b/tests/compiler/dart2js/impact/data/future_or.dart
@@ -6,7 +6,23 @@
 
 import "dart:async";
 
-/*member: main:dynamic=[runtimeType],runtimeType=[unknown:FutureOr<int>],static=[Future.value(1),checkTypeBound(4),print(1),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*spec:nnbd-off.member: main:dynamic=[runtimeType],runtimeType=[unknown:FutureOr<int>],static=[Future.value(1),checkTypeBound(4),print(1),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*spec:nnbd-sdk.member: main:
+ dynamic=[runtimeType],
+ runtimeType=[unknown:FutureOr<int*>*],
+ static=[
+  Future.value(1),
+  checkTypeBound(4),
+  print(1),
+  throwTypeError(1)],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
 @pragma('dart2js:disableFinal')
 void main() {
   FutureOr<int> i = new Future<int>.value(0);
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index 755036c..36e9210 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -30,10 +30,170 @@
   testGenericClass();
 }
 
-/*member: testDefaultValuesPositional:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
+/*spec:nnbd-off.member: testDefaultValuesPositional:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:bool]
+*/
+/*spec:nnbd-sdk.member: testDefaultValuesPositional:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:bool*]
+*/
 testDefaultValuesPositional([bool value = false]) {}
 
-/*member: testDefaultValuesNamed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
+/*spec:nnbd-off.member: testDefaultValuesNamed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:bool]
+*/
+/*spec:nnbd-sdk.member: testDefaultValuesNamed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:bool*]
+*/
 testDefaultValuesNamed({bool value: false}) {}
 
 class ClassFieldInitializer1 {
@@ -86,7 +246,87 @@
 
 /*member: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
 class ClassInstanceFieldWithInitializer {
-  /*member: ClassInstanceFieldWithInitializer.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
+  /*spec:nnbd-off.member: ClassInstanceFieldWithInitializer.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:bool]
+  */
+  /*spec:nnbd-sdk.member: ClassInstanceFieldWithInitializer.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:bool*]
+  */
   var field = false;
 }
 
@@ -95,7 +335,89 @@
 
 /*member: ClassInstanceFieldTyped.:static=[Object.(0)]*/
 class ClassInstanceFieldTyped {
-  /*member: ClassInstanceFieldTyped.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:int]*/
+  /*spec:nnbd-off.member: ClassInstanceFieldTyped.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:int]
+  */
+  /*spec:nnbd-sdk.member: ClassInstanceFieldTyped.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:int*]
+  */
   int field;
 }
 
@@ -122,7 +444,113 @@
 testSuperInitializer() => new ClassSuperInitializer();
 
 class ClassGeneric<T> {
-  /*member: ClassGeneric.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:ClassGeneric.T]*/
+  /*spec:nnbd-off.member: ClassGeneric.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ClassGeneric.T]
+  */
+  /*spec:nnbd-sdk.member: ClassGeneric.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ClassGeneric.T*]
+  */
   ClassGeneric(T arg);
 }
 
diff --git a/tests/compiler/dart2js/impact/data/injected_cast.dart b/tests/compiler/dart2js/impact/data/injected_cast.dart
index 08fb66f..6c2a678 100644
--- a/tests/compiler/dart2js/impact/data/injected_cast.dart
+++ b/tests/compiler/dart2js/impact/data/injected_cast.dart
@@ -16,11 +16,177 @@
 
 /*member: Class1.:static=[Object.(0)]*/
 class Class1 {
-  /*member: Class1.field1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A]*/
+  /*spec:nnbd-off.member: Class1.field1:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A]
+  */
+  /*spec:nnbd-sdk.member: Class1.field1:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A*]
+  */
   A field1;
 }
 
-/*member: method1:dynamic=[Class1.field1=],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,inst:Closure,inst:JSBool,is:Class1]*/
+/*spec:nnbd-off.member: method1:
+ dynamic=[Class1.field1=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A,
+  inst:Closure,
+  inst:JSBool,
+  is:Class1]
+*/
+/*spec:nnbd-sdk.member: method1:
+ dynamic=[Class1.field1=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class1*]
+*/
 method1(dynamic o, dynamic value) {
   if (o is! Class1) return;
   o.field1 = value;
@@ -28,21 +194,131 @@
 
 /*member: Class2.:static=[Object.(0)]*/
 class Class2<T> {
-  /*member: Class2.field2:
-   static=*,
-   type=[inst:*,param:Class2.T]
+  /*spec:nnbd-off.member: Class2.field2:
+   static=%,
+   type=[inst:%,param:Class2.T]
    */
+  /*spec:nnbd-sdk.member: Class2.field2:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:Class2.T*]
+  */
   T field2;
 }
 
-/*member: method2:
+/*spec:nnbd-off.member: method2:
  dynamic=[Class2.field2=],
- static=*,
+ static=%,
  type=[
   impl:A,
-  inst:*,
+  inst:%,
   is:Class2<A>]
 */
+/*spec:nnbd-sdk.member: method2:
+ dynamic=[Class2.field2=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:Class2<A*>*]
+*/
 method2(dynamic o, dynamic value) {
   if (o is! Class2<A>) return;
   o.field2 = value;
@@ -50,11 +326,185 @@
 
 /*member: Class3.:static=[Object.(0)]*/
 class Class3 {
-  /*member: Class3.method3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+  /*spec:nnbd-off.member: Class3.method3:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A,
+    param:B,
+    param:C]
+  */
+  /*spec:nnbd-sdk.member: Class3.method3:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A*,
+    param:B*,
+    param:C*]
+  */
   method3(A a, [B b, C c]) {}
 }
 
-/*member: method3:dynamic=[Class3.method3(3)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,impl:C,inst:Closure,inst:JSBool,is:Class3,param:B]*/
+/*spec:nnbd-off.member: method3:
+ dynamic=[Class3.method3(3)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A,
+  impl:C,
+  inst:Closure,
+  inst:JSBool,
+  is:Class3,
+  param:B]
+*/
+/*spec:nnbd-sdk.member: method3:
+ dynamic=[Class3.method3(3)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  impl:C*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class3*,
+  param:B*]
+*/
 method3(dynamic o, dynamic a, B b, dynamic c) {
   if (o is! Class3) return;
   o.method3(a, b, c);
@@ -62,11 +512,185 @@
 
 /*member: Class4.:static=[Object.(0)]*/
 class Class4 {
-  /*member: Class4.method4:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+  /*spec:nnbd-off.member: Class4.method4:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A,
+    param:B,
+    param:C]
+  */
+  /*spec:nnbd-sdk.member: Class4.method4:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A*,
+    param:B*,
+    param:C*]
+  */
   method4(A a, {B b, C c}) {}
 }
 
-/*member: method4:dynamic=[Class4.method4(1,b,c)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,impl:C,inst:Closure,inst:JSBool,is:Class4,param:B]*/
+/*spec:nnbd-off.member: method4:
+ dynamic=[Class4.method4(1,b,c)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A,
+  impl:C,
+  inst:Closure,
+  inst:JSBool,
+  is:Class4,
+  param:B]
+*/
+/*spec:nnbd-sdk.member: method4:
+ dynamic=[Class4.method4(1,b,c)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  impl:C*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class4*,
+  param:B*]
+*/
 method4(dynamic o, dynamic a, B b, dynamic c) {
   if (o is! Class4) return;
   o.method4(a, c: c, b: b);
@@ -74,10 +698,10 @@
 
 /*member: Class5.:static=[Object.(0)]*/
 class Class5<T1, T2> {
-  /*member: Class5.method5:
-   static=*,
+  /*spec:nnbd-off.member: Class5.method5:
+   static=%,
    type=[
-    inst:*,
+    inst:%,
     param:C,
     param:Class5.T1,
     param:Class5.T2,
@@ -85,21 +709,140 @@
     param:method5.S1,
     param:method5.S2]
   */
+  /*spec:nnbd-sdk.member: Class5.method5:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:C*,
+    param:Class5.T1*,
+    param:Class5.T2*,
+    param:Object*,
+    param:method5.S1*,
+    param:method5.S2*]
+  */
   method5<S1, S2>(T1 a, [T2 b, C c, S1 d, S2 e]) {}
 }
 
-/*member: method5:
+/*spec:nnbd-off.member: method5:
  dynamic=[Class5.method5<D,E>(5)],
- static=*,
+ static=%,
  type=[
   impl:A,
   impl:D,
-  inst:*,
+  inst:%,
   is:Class5<A,B>,
   param:B,
   param:C,
   param:E]
 */
+/*spec:nnbd-sdk.member: method5:
+ dynamic=[Class5.method5<D*,E*>(5)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A*,
+  impl:D*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:Class5<A*,B*>*,
+  param:B*,
+  param:C*,
+  param:E*]
+*/
 method5(dynamic o, dynamic a, B b, C c, dynamic d, E e) {
   if (o is! Class5<A, B>) return;
   o.method5<D, E>(a, b, c, d, e);
@@ -107,10 +850,10 @@
 
 /*member: Class6.:static=[Object.(0)]*/
 class Class6<T1, T2> {
-  /*member: Class6.method6:
-   static=*,
+  /*spec:nnbd-off.member: Class6.method6:
+   static=%,
    type=[
-    inst:*,
+    inst:%,
     param:C,
     param:Class6.T1,
     param:Class6.T2,
@@ -118,21 +861,140 @@
     param:method6.S1,
     param:method6.S2]
   */
+  /*spec:nnbd-sdk.member: Class6.method6:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:C*,
+    param:Class6.T1*,
+    param:Class6.T2*,
+    param:Object*,
+    param:method6.S1*,
+    param:method6.S2*]
+  */
   method6<S1, S2>(T1 a, {T2 b, C c, S1 d, S2 e}) {}
 }
 
-/*member: method6:
+/*spec:nnbd-off.member: method6:
  dynamic=[Class6.method6<D,E>(1,b,c,d,e)],
- static=*,
+ static=%,
  type=[
   impl:A,
   impl:D,
-  inst:*,
+  inst:%,
   is:Class6<A,B>,
   param:B,
   param:C,
   param:E]
 */
+/*spec:nnbd-sdk.member: method6:
+ dynamic=[Class6.method6<D*,E*>(1,b,c,d,e)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A*,
+  impl:D*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:Class6<A*,B*>*,
+  param:B*,
+  param:C*,
+  param:E*]
+*/
 method6(dynamic o, dynamic a, B b, C c, dynamic d, E e) {
   if (o is! Class6<A, B>) return;
   o.method6<D, E>(a, d: d, b: b, e: e, c: c);
@@ -144,7 +1006,95 @@
   A Function(A) get f => null;
 }
 
-/*member: method7:dynamic=[Class7.f(1),call(1)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,inst:Closure,inst:JSBool,is:Class7]*/
+/*spec:nnbd-off.member: method7:
+ dynamic=[
+  Class7.f(1),
+  call(1)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A,
+  inst:Closure,
+  inst:JSBool,
+  is:Class7]
+*/
+/*spec:nnbd-sdk.member: method7:
+ dynamic=[
+  Class7.f(1),
+  call(1)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class7*]
+*/
 method7(dynamic o, dynamic a) {
   if (o is! Class7) return;
   o.f(a);
@@ -152,33 +1102,287 @@
 
 /*member: F.:static=[Object.(0)]*/
 class F<T> {
-  /*member: F.method:static=*,type=[inst:*,param:List<F.T>]*/
+  /*spec:nnbd-off.member: F.method:static=%,type=[inst:%,param:List<F.T>]*/
+  /*spec:nnbd-sdk.member: F.method:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:List<F.T*>*]
+  */
   T method(List<T> list) => null;
 
-  /*member: F.field:static=*,type=[inst:*,param:F.T]*/
+  /*spec:nnbd-off.member: F.field:static=%,type=[inst:%,param:F.T]*/
+  /*spec:nnbd-sdk.member: F.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:F.T*]
+  */
   T field;
 }
 
 /*member: G.:static=[F.(0)]*/
 class G extends F<int> {}
 
-/*member: method8:
+/*spec:nnbd-off.member: method8:
  dynamic=[G.method(1)],
- static=*,
- type=[impl:List<int>,inst:*,is:G,param:Iterable<int>]
+ static=%,
+ type=[impl:List<int>,inst:%,is:G,param:Iterable<int>]
+*/
+/*spec:nnbd-sdk.member: method8:
+ dynamic=[G.method(1)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:List<int*>*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:G*,
+  param:Iterable<int*>*]
 */
 method8(dynamic g, Iterable<int> iterable) {
   if (g is! G) return null;
   return g.method(iterable);
 }
 
-/*member: method9:dynamic=[G.field=],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:int,inst:Closure,inst:JSBool,inst:JSNull,is:G,param:num]*/
+/*spec:nnbd-off.member: method9:
+ dynamic=[G.field=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:int,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:G,
+  param:num]
+*/
+/*spec:nnbd-sdk.member: method9:
+ dynamic=[G.field=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:int*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:G*,
+  param:num*]
+*/
 method9(dynamic g, num value) {
   if (g is! G) return null;
   return g.field = value;
 }
 
-/*member: main:**/
+/*member: main:%*/
 main() {
   method1(new Class1(), null);
   method2(new Class2<A>(), null);
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index 41ca532..3e7d4b4 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -117,18 +117,292 @@
   topLevelFunction3(15, c: 16, b: 17);
 }
 
-/*member: topLevelFunction1Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
+/*spec:nnbd-off.member: topLevelFunction1Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:int]
+*/
+/*spec:nnbd-sdk.member: topLevelFunction1Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:int*]
+*/
 void topLevelFunction1Typed(int a) {}
 
-/*member: topLevelFunction2Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:String,param:double,param:num]*/
+/*spec:nnbd-off.member: topLevelFunction2Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:String,
+  param:double,
+  param:num]
+*/
+/*spec:nnbd-sdk.member: topLevelFunction2Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:String*,
+  param:double*,
+  param:num*]
+*/
 int topLevelFunction2Typed(String a, [num b, double c]) => null;
 
-/*member: topLevelFunction3Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:List<int>,param:Map<String,bool>,param:bool]*/
+/*spec:nnbd-off.member: topLevelFunction3Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:List<int>,
+  param:Map<String,bool>,
+  param:bool]
+*/
+/*spec:nnbd-sdk.member: topLevelFunction3Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:List<int*>*,
+  param:Map<String*,bool*>*,
+  param:bool*]
+*/
 double topLevelFunction3Typed(bool a, {List<int> b, Map<String, bool> c}) {
   return null;
 }
 
-/*member: testTopLevelInvokeTyped:
+/*spec:nnbd-off.member: testTopLevelInvokeTyped:
  static=[
   topLevelFunction1Typed(1),
   topLevelFunction2Typed(1),
@@ -152,6 +426,30 @@
   inst:List<int>,
   inst:Map<String,bool>]
 */
+/*spec:nnbd-sdk.member: testTopLevelInvokeTyped:
+ static=[
+  topLevelFunction1Typed(1),
+  topLevelFunction2Typed(1),
+  topLevelFunction2Typed(2),
+  topLevelFunction2Typed(3),
+  topLevelFunction3Typed(1),
+  topLevelFunction3Typed(1,b),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,c)],
+ type=[
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNull,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  inst:List<int*>,
+  inst:Map<String*,bool*>]
+*/
 testTopLevelInvokeTyped() {
   topLevelFunction1Typed(0);
   topLevelFunction2Typed('1');
@@ -164,16 +462,424 @@
   topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
 }
 
-/*member: topLevelFunctionTyped1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num)]*/
+/*spec:nnbd-off.member: topLevelFunctionTyped1:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num)]
+*/
+/*spec:nnbd-sdk.member: topLevelFunctionTyped1:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*)*]
+*/
 topLevelFunctionTyped1(void a(num b)) {}
 
-/*member: topLevelFunctionTyped2:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,[String])]*/
+/*spec:nnbd-off.member: topLevelFunctionTyped2:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num,[String])]
+*/
+/*spec:nnbd-sdk.member: topLevelFunctionTyped2:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*,[String*])*]
+*/
 topLevelFunctionTyped2(void a(num b, [String c])) {}
 
-/*member: topLevelFunctionTyped3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,{String c,int d})]*/
+/*spec:nnbd-off.member: topLevelFunctionTyped3:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num,{String c,int d})]
+*/
+/*spec:nnbd-sdk.member: topLevelFunctionTyped3:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*,{String* c,int* d})*]
+*/
 topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
 
-/*member: topLevelFunctionTyped4:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,{int c,String d})]*/
+/*spec:nnbd-off.member: topLevelFunctionTyped4:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num,{int c,String d})]
+*/
+/*spec:nnbd-sdk.member: topLevelFunctionTyped4:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*,{int* c,String* d})*]
+*/
 topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
 
 /*member: testTopLevelFunctionTyped:
@@ -212,7 +918,87 @@
 /*member: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
 testTopLevelSetterSet() => topLevelSetter = null;
 
-/*member: topLevelSetterTyped=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
+/*spec:nnbd-off.member: topLevelSetterTyped=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:int]
+*/
+/*spec:nnbd-sdk.member: topLevelSetterTyped=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:int*]
+*/
 void set topLevelSetterTyped(int value) {}
 
 /*member: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
@@ -241,25 +1027,375 @@
 /*member: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
 testTopLevelFieldFinal() => topLevelFieldFinal;
 
-/*member: topLevelFieldTyped:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:int]*/
+/*spec:nnbd-off.member: topLevelFieldTyped:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:int]
+*/
+/*spec:nnbd-sdk.member: topLevelFieldTyped:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:int*]
+*/
 int topLevelFieldTyped;
 
 /*member: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
 testTopLevelFieldTyped() => topLevelFieldTyped;
 
-/*member: topLevelFieldGeneric1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*spec:nnbd-off.member: topLevelFieldGeneric1:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:GenericClass<dynamic,dynamic>]
+*/
+/*spec:nnbd-sdk.member: topLevelFieldGeneric1:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:GenericClass<dynamic,dynamic>*]
+*/
 GenericClass topLevelFieldGeneric1;
 
 /*member: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
 testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
 
-/*member: topLevelFieldGeneric2:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*spec:nnbd-off.member: topLevelFieldGeneric2:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:GenericClass<dynamic,dynamic>]
+*/
+/*spec:nnbd-sdk.member: topLevelFieldGeneric2:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:GenericClass<dynamic,dynamic>*]
+*/
 GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
 
 /*member: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
 testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
 
-/*member: topLevelFieldGeneric3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:GenericClass<int,String>]*/
+/*spec:nnbd-off.member: topLevelFieldGeneric3:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:GenericClass<int,String>]
+*/
+/*spec:nnbd-sdk.member: topLevelFieldGeneric3:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:GenericClass<int*,String*>*]
+*/
 GenericClass<int, String> topLevelFieldGeneric3;
 
 /*member: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
@@ -384,7 +1520,111 @@
   localFunction() {}
 }
 
-/*member: testLocalFunctionTyped:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),computeSignature(3),def:localFunction,findType(1),getRuntimeTypeArguments(3),getRuntimeTypeInfo(1),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:Function,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:String]*/
+/*spec:nnbd-off.member: testLocalFunctionTyped:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  computeSignature(3),
+  def:localFunction,
+  findType(1),
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:String]
+*/
+/*spec:nnbd-sdk.member: testLocalFunctionTyped:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  computeSignature(3),
+  def:localFunction,
+  findType(1),
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:String*]
+*/
 testLocalFunctionTyped() {
   // ignore: UNUSED_ELEMENT
   int localFunction(String a) => null;
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index 98f8cee..c5581aa 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -61,7 +61,111 @@
 /*member: GenericClass.:static=[JavaScriptObject.(0)]*/
 @JS()
 class GenericClass<T> {
-  /*member: GenericClass.method:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:void Function(GenericClass.T)]*/
+  /*spec:nnbd-off.member: GenericClass.method:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:void Function(GenericClass.T)]
+  */
+  /*spec:nnbd-sdk.member: GenericClass.method:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:void Function(GenericClass.T*)*]
+  */
   external GenericClass method([Callback<T> callback]);
 }
 
diff --git a/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart b/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
index 18db4e3..d0dfa5c 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
@@ -11,11 +11,209 @@
 
 import 'package:js/js.dart';
 
-/*member: foo=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,native:ApplicationCacheErrorEvent,native:DomError,native:DomException,native:ErrorEvent,native:MediaError,native:NavigatorUserMediaError,native:OverconstrainedError,native:PositionError,native:SensorErrorEvent,native:SpeechRecognitionError,native:SqlError,param:Function]*/
+/*spec:nnbd-off.member: foo=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  native:ApplicationCacheErrorEvent,
+  native:DomError,
+  native:DomException,
+  native:ErrorEvent,
+  native:MediaError,
+  native:NavigatorUserMediaError,
+  native:OverconstrainedError,
+  native:PositionError,
+  native:SensorErrorEvent,
+  native:SpeechRecognitionError,
+  native:SqlError,
+  param:Function]
+*/
+/*spec:nnbd-sdk.member: foo=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  native:ApplicationCacheErrorEvent,
+  native:DomError,
+  native:DomException,
+  native:ErrorEvent,
+  native:MediaError,
+  native:NavigatorUserMediaError,
+  native:OverconstrainedError,
+  native:PositionError,
+  native:SensorErrorEvent,
+  native:SpeechRecognitionError,
+  native:SqlError,
+  param:Function*]
+*/
 @JS()
 external set foo(Function f);
 
-/*member: _doStuff:dynamic=[File.==,File.name],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1),print(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,inst:JSString,param:File,param:String]*/
+/*spec:nnbd-off.member: _doStuff:
+ dynamic=[
+  File.==,
+  File.name],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1),
+  print(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:JSString,
+  param:File,
+  param:String]
+*/
+/*spec:nnbd-sdk.member: _doStuff:
+ dynamic=[
+  File.==,
+  File.name],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1),
+  print(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:JSString,
+  param:File*,
+  param:String*]
+*/
 void _doStuff(String name, File file) {
   if (file == null) {
     print('OK');
@@ -23,12 +221,16 @@
   print(file.name);
 }
 
-/*member: main:
+/*spec:nnbd-off.member: main:
  static=[
  _doStuff,
  allowInterop<Function>(1),
  set:foo]
 */
+/*spec:nnbd-sdk.member: main:static=[
+  _doStuff,
+  allowInterop<Function*>(1),
+  set:foo]*/
 void main() {
   foo = allowInterop(_doStuff);
 }
diff --git a/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart b/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
index ebd83d7..b52a2ad 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
@@ -11,11 +11,233 @@
 
 import 'package:js/js.dart';
 
-/*member: foo=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,native:ApplicationCacheErrorEvent,native:DomError,native:DomException,native:ErrorEvent,native:File,native:MediaError,native:NavigatorUserMediaError,native:OverconstrainedError,native:PositionError,native:SensorErrorEvent,native:SpeechRecognitionError,native:SqlError,param:void Function(String,File)]*/
+/*spec:nnbd-off.member: foo=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  native:ApplicationCacheErrorEvent,
+  native:DomError,
+  native:DomException,
+  native:ErrorEvent,
+  native:File,
+  native:MediaError,
+  native:NavigatorUserMediaError,
+  native:OverconstrainedError,
+  native:PositionError,
+  native:SensorErrorEvent,
+  native:SpeechRecognitionError,
+  native:SqlError,
+  param:void Function(String,File)]
+*/
+/*spec:nnbd-sdk.member: foo=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  native:ApplicationCacheErrorEvent,
+  native:DomError,
+  native:DomException,
+  native:ErrorEvent,
+  native:File,
+  native:MediaError,
+  native:NavigatorUserMediaError,
+  native:OverconstrainedError,
+  native:PositionError,
+  native:SensorErrorEvent,
+  native:SpeechRecognitionError,
+  native:SqlError,
+  param:void Function(String*,File*)*]
+*/
 @JS()
 external set foo(void Function(String, File) f);
 
-/*member: _doStuff:dynamic=[File.==,File.name],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1),print(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,inst:JSString,param:File,param:String]*/
+/*spec:nnbd-off.member: _doStuff:
+ dynamic=[
+  File.==,
+  File.name],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1),
+  print(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:JSString,
+  param:File,
+  param:String]
+*/
+/*spec:nnbd-sdk.member: _doStuff:
+ dynamic=[
+  File.==,
+  File.name],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1),
+  print(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:JSString,
+  param:File*,
+  param:String*]
+*/
 void _doStuff(String name, File file) {
   if (file == null) {
     print('OK');
@@ -23,12 +245,16 @@
   print(file.name);
 }
 
-/*member: main:
+/*spec:nnbd-off.member: main:
  static=[
   _doStuff,
   allowInterop<void Function(String,File)>(1),
   set:foo]
 */
+/*spec:nnbd-sdk.member: main:static=[
+  _doStuff,
+  allowInterop<void Function(String*,File*)*>(1),
+  set:foo]*/
 void main() {
   foo = allowInterop(_doStuff);
 }
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index 4edd315..9c0bcfa 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -131,7 +131,16 @@
 /*member: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testIfNullConstSymbol() => const Symbol(null ?? 'foo');
 
-/*member: testTypeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:Object]*/
+/*spec:nnbd-off.member: testTypeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:Object]*/
+/*spec:nnbd-sdk.member: testTypeLiteral:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:Object*]
+*/
 testTypeLiteral() => Object;
 
 /*member: testBoolFromEnvironment:type=[inst:JSBool]*/
@@ -143,13 +152,17 @@
 /*member: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
 testEmptyListLiteralDynamic() => <dynamic>[];
 
-/*member: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*spec:nnbd-off.member: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*spec:nnbd-sdk.member: testEmptyListLiteralTyped:type=[inst:List<String*>]*/
 testEmptyListLiteralTyped() => <String>[];
 
 /*member: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
 testEmptyListLiteralConstant() => const [];
 
-/*member: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: testNonEmptyListLiteral:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 testNonEmptyListLiteral() => [true];
 
 /*member: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
@@ -158,7 +171,8 @@
 /*member: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
 testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
 
-/*member: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*spec:nnbd-off.member: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*spec:nnbd-sdk.member: testEmptyMapLiteralTyped:type=[inst:Map<String*,int*>]*/
 testEmptyMapLiteralTyped() => <String, int>{};
 
 /*member: testEmptyMapLiteralConstant:
@@ -170,7 +184,11 @@
 */
 testEmptyMapLiteralConstant() => const {};
 
-/*member: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*spec:nnbd-off.member: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*spec:nnbd-sdk.member: testNonEmptyMapLiteral:type=[
+  inst:JSBool,
+  inst:JSNull,
+  inst:Map<Null,bool*>]*/
 testNonEmptyMapLiteral() => {null: true};
 
 class GenericClass<X, Y> {
diff --git a/tests/compiler/dart2js/impact/data/marker.options b/tests/compiler/dart2js/impact/data/marker.options
index f001ac8..8ea68a6 100644
--- a/tests/compiler/dart2js/impact/data/marker.options
+++ b/tests/compiler/dart2js/impact/data/marker.options
@@ -1 +1,2 @@
-strong=tests/compiler/dart2js/impact/impact_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/impact/impact_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/impact/impact_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index f700202..a923095 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -47,18 +47,112 @@
 testNativeMethodCreates() native;
 
 // This will trigger native instantiation and therefore include type use
-// `native:X` for all native types. This is truncated to `type=[*]` to avoid
+// `native:X` for all native types. This is truncated to `type=[%]` to avoid
 // dependency on the particular types. If `testNativeMethodReturns` was not
 // called `testNativeMethodCreates` would instead trigger the native
 // instantiations, so the blame is a bit arbitrary.
-/*member: testNativeMethodReturns:type=[*]*/
+/*member: testNativeMethodReturns:type=[%]*/
 @Returns('String|Null|JSArray')
 // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
 testNativeMethodReturns() native;
 
 @Native("NativeClass")
 class NativeClass {
-  /*member: NativeClass.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,native:JSExtendableArray<JSExtendableArray.E>,native:Object,native:String,native:bool,native:double,native:int,param:Object]*/
+  /*spec:nnbd-off.member: NativeClass.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    native:JSExtendableArray<JSExtendableArray.E>,
+    native:Object,
+    native:String,
+    native:bool,
+    native:double,
+    native:int,
+    param:Object]
+  */
+  /*spec:nnbd-sdk.member: NativeClass.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    native:JSExtendableArray<JSExtendableArray.E>,
+    native:Object,
+    native:String,
+    native:bool,
+    native:double,
+    native:int,
+    param:Object*]
+  */
   @annotation_Creates_SerializedScriptValue
   final Object field;
 
@@ -67,5 +161,89 @@
   }
 }
 
-/*member: testNativeField:dynamic=[NativeClass.field],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:NativeClass]*/
+/*spec:nnbd-off.member: testNativeField:
+ dynamic=[NativeClass.field],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:NativeClass]
+*/
+/*spec:nnbd-sdk.member: testNativeField:
+ dynamic=[NativeClass.field],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:NativeClass*]
+*/
 testNativeField(NativeClass c) => c.field;
diff --git a/tests/compiler/dart2js/impact/data/promotion.dart b/tests/compiler/dart2js/impact/data/promotion.dart
index 04fec9f..fe2a60d 100644
--- a/tests/compiler/dart2js/impact/data/promotion.dart
+++ b/tests/compiler/dart2js/impact/data/promotion.dart
@@ -39,17 +39,265 @@
   dynamicToNoSuchMethodTearOff(null);
 }
 
-/*member: positiveTyped:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass,param:Class]*/
+/*spec:nnbd-off.member: positiveTyped:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass,
+  param:Class]
+*/
+/*spec:nnbd-sdk.member: positiveTyped:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass*,
+  param:Class*]
+*/
 positiveTyped(Class cls) {
   if (cls is SubClass) cls.method();
 }
 
-/*member: positiveDynamic:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass]*/
+/*spec:nnbd-off.member: positiveDynamic:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass]
+*/
+/*spec:nnbd-sdk.member: positiveDynamic:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass*]
+*/
 positiveDynamic(dynamic cls) {
   if (cls is SubClass) cls.method();
 }
 
-/*member: negativeDynamic:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass]*/
+/*spec:nnbd-off.member: negativeDynamic:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass]
+*/
+/*spec:nnbd-sdk.member: negativeDynamic:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass*]
+*/
 negativeDynamic(dynamic cls) {
   if (cls is! SubClass) return;
   cls.method();
diff --git a/tests/compiler/dart2js/impact/data/runtime_type.dart b/tests/compiler/dart2js/impact/data/runtime_type.dart
index 9efa562..e9cdb53 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type.dart
@@ -6,9 +6,16 @@
 
 /*member: Class1a.:static=[Object.(0)]*/
 class Class1a<T> {
-  /*member: Class1a.==:
+  /*spec:nnbd-off.member: Class1a.==:
    dynamic=[this:Class1a.runtimeType,Object.runtimeType,Type.==],
-   runtimeType=[equals:Class1a<Class1a.T>/Object]
+   runtimeType=[equals:Class1a<Class1a.T>==Object]
+  */
+  /*spec:nnbd-sdk.member: Class1a.==:
+   dynamic=[
+    Object.runtimeType,
+    Type.==,
+    this:Class1a.runtimeType],
+   runtimeType=[equals:Class1a<Class1a.T*>*==Object]
   */
   bool operator ==(other) {
     return runtimeType == other.runtimeType;
@@ -17,9 +24,19 @@
 
 /*member: Class1b.:static=[Class1a.(0)]*/
 class Class1b<T> extends Class1a<T> {
-  /*member: Class1b.==:
-   dynamic=[this:Class1b.runtimeType,Object.runtimeType,Type.==],
-   runtimeType=[equals:Object/Class1b<Class1b.T>]
+  /*spec:nnbd-off.member: Class1b.==:
+   dynamic=[
+    Object.runtimeType,
+    Type.==,
+    this:Class1b.runtimeType],
+   runtimeType=[equals:Object==Class1b<Class1b.T>]
+  */
+  /*spec:nnbd-sdk.member: Class1b.==:
+   dynamic=[
+    Object.runtimeType,
+    Type.==,
+    this:Class1b.runtimeType],
+   runtimeType=[equals:Object==Class1b<Class1b.T*>*]
   */
   bool operator ==(other) {
     return other.runtimeType == runtimeType;
@@ -28,9 +45,22 @@
 
 /*member: Class1c.:static=[Object.(0)]*/
 class Class1c<T> implements Class1a<T> {
-  /*member: Class1c.==:
-   dynamic=[this:Class1c.runtimeType,Object.==,Object.runtimeType,Type.==],
-   runtimeType=[equals:Class1c<Class1c.T>/Object],
+  /*spec:nnbd-off.member: Class1c.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1c.runtimeType],
+   runtimeType=[equals:Class1c<Class1c.T>==Object],
+   type=[inst:JSNull]
+  */
+  /*spec:nnbd-sdk.member: Class1c.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1c.runtimeType],
+   runtimeType=[equals:Class1c<Class1c.T*>*==Object],
    type=[inst:JSNull]
   */
   bool operator ==(other) {
@@ -40,9 +70,22 @@
 
 /*member: Class1d.:static=[Object.(0)]*/
 class Class1d<T> implements Class1a<T> {
-  /*member: Class1d.==:
-   dynamic=[this:Class1d.runtimeType,Object.==,Object.runtimeType,Type.==],
-   runtimeType=[equals:Object/Class1d<Class1d.T>],
+  /*spec:nnbd-off.member: Class1d.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1d.runtimeType],
+   runtimeType=[equals:Object==Class1d<Class1d.T>],
+   type=[inst:JSNull]
+  */
+  /*spec:nnbd-sdk.member: Class1d.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1d.runtimeType],
+   runtimeType=[equals:Object==Class1d<Class1d.T*>*],
    type=[inst:JSNull]
   */
   bool operator ==(other) {
@@ -62,88 +105,2854 @@
 /*member: Class4.:static=[Object.(0)]*/
 class Class4 {}
 
-/*member: toString1:dynamic=[Class2.runtimeType,toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),S(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSString,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: toString1:
+ dynamic=[
+  Class2.runtimeType,
+  toString(0)],
+ runtimeType=[string:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  S(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSString,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: toString1:
+ dynamic=[
+  Class2.runtimeType,
+  toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  S(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSString,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString1(Class2<int> c) => '${c.runtimeType}';
 
-/*member: toString2:dynamic=[Class2.==,Class2.runtimeType,toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),S(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSString,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: toString2:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  toString(0)],
+ runtimeType=[string:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  S(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSString,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: toString2:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  S(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSString,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString2(Class2<int> c) => '${c?.runtimeType}';
 
-/*member: toString3:dynamic=[Class2.runtimeType,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: toString3:
+ dynamic=[
+  Class2.runtimeType,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: toString3:
+ dynamic=[
+  Class2.runtimeType,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString3(Class2<int> c) => c.runtimeType.toString();
 
-/*member: toString4:dynamic=[Class2.runtimeType,Type.==,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: toString4:
+ dynamic=[
+  Class2.runtimeType,
+  Type.==,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: toString4:
+ dynamic=[
+  Class2.runtimeType,
+  Type.==,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString4(Class2<int> c) => c.runtimeType?.toString();
 
-/*member: toString5:dynamic=[Class2.==,Class2.runtimeType,Type.==,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: toString5:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  Type.==,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: toString5:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  Type.==,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString5(Class2<int> c) => c?.runtimeType?.toString();
 
-/*member: toString6:dynamic=[Class2.==,Class2.runtimeType,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: toString6:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: toString6:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString6(Class2<int> c) => c?.runtimeType.toString();
 
-/*member: unknown:dynamic=[Class2.runtimeType],runtimeType=[unknown:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*spec:nnbd-off.member: unknown:
+ dynamic=[Class2.runtimeType],
+ runtimeType=[unknown:Class2<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int>]
+*/
+/*spec:nnbd-sdk.member: unknown:
+ dynamic=[Class2.runtimeType],
+ runtimeType=[unknown:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 unknown(Class2<int> c) => c.runtimeType;
 
-/*member: equals1:dynamic=[Class1a.==,Class1a.runtimeType,Class1d.==,Class1d.runtimeType,Type.==],runtimeType=[equals:Class1a<int>/Class1d<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class1a<int>,param:Class1d<int>]*/
+/*spec:nnbd-off.member: equals1:
+ dynamic=[
+  Class1a.==,
+  Class1a.runtimeType,
+  Class1d.==,
+  Class1d.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class1a<int>==Class1d<int>],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class1a<int>,
+  param:Class1d<int>]
+*/
+/*spec:nnbd-sdk.member: equals1:
+ dynamic=[
+  Class1a.==,
+  Class1a.runtimeType,
+  Class1d.==,
+  Class1d.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class1a<int*>*==Class1d<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class1a<int*>*,
+  param:Class1d<int*>*]
+*/
 equals1(Class1a<int> a, Class1d<int> b) => a?.runtimeType == b?.runtimeType;
 
-/*member: almostEquals1:dynamic=[Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals1:
+ dynamic=[
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals1:
+ dynamic=[
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals1(Class3 a) => a.runtimeType == null;
 
-/*member: almostEquals2:dynamic=[Class3.==,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals2(Class3 a) => a?.runtimeType == null;
 
-/*member: almostEquals3:dynamic=[Class3.runtimeType,Null.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals3:
+ dynamic=[
+  Class3.runtimeType,
+  Null.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals3:
+ dynamic=[
+  Class3.runtimeType,
+  Null.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals3(Class3 a) => null == a.runtimeType;
 
-/*member: almostEquals4:dynamic=[Class3.==,Class3.runtimeType,Null.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Null.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Null.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals4(Class3 a) => null == a?.runtimeType;
 
-/*member: almostEquals5:dynamic=[Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals5:
+ dynamic=[
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals5:
+ dynamic=[
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*]
+*/
 almostEquals5(Class3 a) => a.runtimeType == a.field;
 
-/*member: almostEquals6:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals6:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals6:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals6(Class3 a) => a?.runtimeType == a.field;
 
-/*member: almostEquals7:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals7:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals7:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals7(Class3 a) => a.runtimeType == a?.field;
 
-/*member: almostEquals8:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals8:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals8:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals8(Class3 a) => a?.runtimeType == a?.field;
 
-/*member: almostEquals9:dynamic=[Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals9:
+ dynamic=[
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals9:
+ dynamic=[
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*]
+*/
 almostEquals9(Class3 a) => a.field == a.runtimeType;
 
-/*member: almostEquals10:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals10:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals10:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals10(Class3 a) => a?.field == a.runtimeType;
 
-/*member: almostEquals11:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals11:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals11:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals11(Class3 a) => a.field == a?.runtimeType;
 
-/*member: almostEquals12:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostEquals12:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostEquals12:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals12(Class3 a) => a?.field == a?.runtimeType;
 
-/*member: almostToString1:dynamic=[Class3.runtimeType,Type.toString],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
+/*spec:nnbd-off.member: almostToString1:
+ dynamic=[
+  Class3.runtimeType,
+  Type.toString],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostToString1:
+ dynamic=[
+  Class3.runtimeType,
+  Type.toString],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*]
+*/
 almostToString1(Class3 a) => a.runtimeType.toString;
 
-/*member: almostToString2:dynamic=[Class3.==,Class3.runtimeType,Type.==,Type.toString],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostToString2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.==,
+  Type.toString],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostToString2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.==,
+  Type.toString],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostToString2(Class3 a) => a?.runtimeType?.toString;
 
-/*member: almostToString3:dynamic=[Class3.runtimeType,Type.noSuchMethod(1)],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostToString3:
+ dynamic=[
+  Class3.runtimeType,
+  Type.noSuchMethod(1)],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostToString3:
+ dynamic=[
+  Class3.runtimeType,
+  Type.noSuchMethod(1)],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostToString3(Class3 a) => a.runtimeType.noSuchMethod(null);
 
-/*member: almostToString4:dynamic=[Class3.==,Class3.runtimeType,Type.noSuchMethod(1)],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*spec:nnbd-off.member: almostToString4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.noSuchMethod(1)],
+ runtimeType=[unknown:Class3],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3]
+*/
+/*spec:nnbd-sdk.member: almostToString4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.noSuchMethod(1)],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostToString4(Class3 a) => a?.runtimeType.noSuchMethod(null);
 
-/*member: notEquals1:dynamic=[Class3.runtimeType,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3,param:Class4]*/
+/*spec:nnbd-off.member: notEquals1:
+ dynamic=[
+  Class3.runtimeType,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3==Class4],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3,
+  param:Class4]
+*/
+/*spec:nnbd-sdk.member: notEquals1:
+ dynamic=[
+  Class3.runtimeType,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals1(Class3 a, Class4 b) => a.runtimeType != b.runtimeType;
 
-/*member: notEquals2:dynamic=[Class3.==,Class3.runtimeType,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
+/*spec:nnbd-off.member: notEquals2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3==Class4],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3,
+  param:Class4]
+*/
+/*spec:nnbd-sdk.member: notEquals2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals2(Class3 a, Class4 b) => a?.runtimeType != b.runtimeType;
 
-/*member: notEquals3:dynamic=[Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
+/*spec:nnbd-off.member: notEquals3:
+ dynamic=[
+  Class3.runtimeType,
+  Class4.==,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3==Class4],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3,
+  param:Class4]
+*/
+/*spec:nnbd-sdk.member: notEquals3:
+ dynamic=[
+  Class3.runtimeType,
+  Class4.==,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals3(Class3 a, Class4 b) => a.runtimeType != b?.runtimeType;
 
-/*member: notEquals4:dynamic=[Class3.==,Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
+/*spec:nnbd-off.member: notEquals4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Class4.==,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3==Class4],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3,
+  param:Class4]
+*/
+/*spec:nnbd-sdk.member: notEquals4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Class4.==,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals4(Class3 a, Class4 b) => a?.runtimeType != b?.runtimeType;
 
 /*member: main:dynamic=[exact:Class1a.==],static=[Class1a.(0),Class1b.(0),Class1c.(0),Class1d.(0),Class2.(0),Class3.(0),Class4.(0),almostEquals1(1),almostEquals10(1),almostEquals11(1),almostEquals12(1),almostEquals2(1),almostEquals3(1),almostEquals4(1),almostEquals5(1),almostEquals6(1),almostEquals7(1),almostEquals8(1),almostEquals9(1),almostToString1(1),almostToString2(1),almostToString3(1),almostToString4(1),checkTypeBound(4),equals1(2),notEquals1(2),notEquals2(2),notEquals3(2),notEquals4(2),print(1),throwTypeError(1),toString1(1),toString2(1),toString3(1),toString4(1),toString5(1),toString6(1),unknown(1)]*/
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index 57bb512a..e0ab8fb 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -67,13 +67,203 @@
     return 1;
 }
 
-/*member: testForIn:dynamic=[Iterator.current,Iterator.iterator,Iterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkConcurrentModificationError(2),findType(1),instanceType(1)],type=[impl:Iterable<dynamic>,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*spec:nnbd-off.member: testForIn:
+ dynamic=[
+  Iterator.current,
+  Iterator.iterator,
+  Iterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkConcurrentModificationError(2),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Iterable<dynamic>,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+/*spec:nnbd-sdk.member: testForIn:
+ dynamic=[
+  Iterator.current,
+  Iterator.iterator,
+  Iterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkConcurrentModificationError(2),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Iterable<dynamic>*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testForIn(o) {
   // ignore: UNUSED_LOCAL_VARIABLE
   for (var e in o) {}
 }
 
-/*member: testForInTyped:dynamic=[Iterator.current,Iterator.iterator,Iterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkConcurrentModificationError(2),findType(1),instanceType(1)],type=[impl:Iterable<dynamic>,impl:int,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*spec:nnbd-off.member: testForInTyped:
+ dynamic=[
+  Iterator.current,
+  Iterator.iterator,
+  Iterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkConcurrentModificationError(2),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Iterable<dynamic>,
+  impl:int,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+/*spec:nnbd-sdk.member: testForInTyped:
+ dynamic=[
+  Iterator.current,
+  Iterator.iterator,
+  Iterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkConcurrentModificationError(2),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Iterable<dynamic>*,
+  impl:int*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testForInTyped(o) {
   // ignore: UNUSED_LOCAL_VARIABLE
   for (int e in o) {}
@@ -89,7 +279,93 @@
   try {} catch (e) {}
 }
 
-/*member: testTryCatchOn:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_installSpecializedIsTest(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),unwrapException(1)],type=[catch:String,inst:Closure,inst:JSBool,inst:PlainJavaScriptObject,inst:UnknownJavaScriptObject]*/
+/*spec:nnbd-off.member: testTryCatchOn:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  unwrapException(1)],
+ type=[
+  catch:String,
+  inst:Closure,
+  inst:JSBool,
+  inst:PlainJavaScriptObject,
+  inst:UnknownJavaScriptObject]
+*/
+/*spec:nnbd-sdk.member: testTryCatchOn:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  unwrapException(1)],
+ type=[
+  catch:String*,
+  inst:Closure,
+  inst:JSBool,
+  inst:PlainJavaScriptObject,
+  inst:UnknownJavaScriptObject]
+*/
 testTryCatchOn() {
   // ignore: UNUSED_CATCH_CLAUSE
   try {} on String catch (e) {}
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index 1ae3981..c3ff87b 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -25,15 +25,13 @@
     print('==================================================================');
     useImpactDataForTesting = false;
     await checkTests(dataDir, const ImpactDataComputer(),
-        args: args,
-        testedConfigs: [strongConfig]);
+        args: args, testedConfigs: allSpecConfigs);
 
     print('Testing computation of ResolutionImpact through ImpactData');
     print('==================================================================');
     useImpactDataForTesting = true;
     await checkTests(dataDir, const ImpactDataComputer(),
-        args: args,
-        testedConfigs: [strongConfig]);
+        args: args, testedConfigs: allSpecConfigs);
   });
 }
 
@@ -48,6 +46,8 @@
 class ImpactDataComputer extends DataComputer<Features> {
   const ImpactDataComputer();
 
+  static const String wildcard = '%';
+
   @override
   void computeMemberData(Compiler compiler, MemberEntity member,
       Map<Id, ActualData<Features>> actualMap,
@@ -57,14 +57,14 @@
     ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
     Features features = new Features();
     if (impact.typeUses.length > 50) {
-      features.addElement(Tags.typeUse, '*');
+      features.addElement(Tags.typeUse, wildcard);
     } else {
       for (TypeUse use in impact.typeUses) {
         features.addElement(Tags.typeUse, use.shortText);
       }
     }
     if (impact.staticUses.length > 50) {
-      features.addElement(Tags.staticUse, '*');
+      features.addElement(Tags.staticUse, wildcard);
     } else {
       for (StaticUse use in impact.staticUses) {
         features.addElement(Tags.staticUse, use.shortText);
@@ -94,5 +94,5 @@
 
   @override
   DataInterpreter<Features> get dataValidator =>
-      const FeaturesDataInterpreter();
+      const FeaturesDataInterpreter(wildcard: wildcard);
 }
diff --git a/tests/compiler/dart2js/inference/callers/marker.options b/tests/compiler/dart2js/inference/callers/marker.options
index 10b39a7..64dc9c4 100644
--- a/tests/compiler/dart2js/inference/callers/marker.options
+++ b/tests/compiler/dart2js/inference/callers/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inference/callers_test.dart
-omit=tests/compiler/dart2js/inference/callers_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inference/callers_test.dart
+prod:nnbd-off=tests/compiler/dart2js/inference/callers_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/callers_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inference/callers_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
index 23487e5..48c81d4 100644
--- a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -11,8 +11,8 @@
 /*member: f:[subclass=JSInt]*/
 int f(
         int
-            /*strong.[null|subclass=Object]*/
-            /*omit.[null|subclass=JSInt]*/
+            /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+            /*prod:nnbd-off|prod:nnbd-sdk.[null|subclass=JSInt]*/
             i) =>
     2 /*invoke: [exact=JSUInt31]*/ * i;
 
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index b93f472..8ca5209 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -57,8 +57,8 @@
       i /*invoke: [subclass=JSPositiveInt]*/ ++) {
     methods. /*invoke: [exact=JSExtendableArray]*/ add(
         /*[null]*/ (int
-            /*strong.[null|subclass=Object]*/
-            /*omit.[null|subclass=JSInt]*/
+            /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+            /*prod:nnbd-off|prod:nnbd-sdk.[null|subclass=JSInt]*/
             x) {
       res = x;
       sum = x /*invoke: [null|subclass=JSInt]*/ + i;
diff --git a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
index 9624438..a08ef1a 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
@@ -6,7 +6,7 @@
 
 import 'dart:typed_data';
 
-// TODO(johnniwinther): Fix inference for strong mode. List elements should not
+// TODO(johnniwinther): Fix inference for spec:nnbd-off mode. List elements should not
 // be [empty].
 
 /*member: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_const.dart b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
index 3ff4fbb..4e4595d 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_const.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
@@ -7,8 +7,8 @@
 /*member: closure:[exact=JSUInt31]*/
 int closure(
     int
-        /*strong.Union([exact=JSDouble], [exact=JSUInt31])*/
-        /*omit.[exact=JSUInt31]*/
+        /*spec:nnbd-off|spec:nnbd-sdk.Union([exact=JSDouble], [exact=JSUInt31])*/
+        /*prod:nnbd-off|prod:nnbd-sdk.[exact=JSUInt31]*/
         x) {
   return x;
 }
diff --git a/tests/compiler/dart2js/inference/data/marker.options b/tests/compiler/dart2js/inference/data/marker.options
index ed13f42..46aaaf9 100644
--- a/tests/compiler/dart2js/inference/data/marker.options
+++ b/tests/compiler/dart2js/inference/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inference/inference_test_helper.dart
-omit=tests/compiler/dart2js/inference/inference_test_helper.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inference/inference_test_helper.dart
+prod:nnbd-off=tests/compiler/dart2js/inference/inference_test_helper.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/inference_test_helper.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inference/inference_test_helper.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index daa1bdd..671f70c 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -17,8 +17,8 @@
   /*member: Class1.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
           Invocation
-              /*strong.[null|subclass=Object]*/
-              /*omit.[null|exact=JSInvocationMirror]*/
+              /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+              /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
               _) =>
       42;
 
@@ -41,8 +41,8 @@
   /*member: Class2.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
           Invocation
-              /*strong.[null|subclass=Object]*/
-              /*omit.[null|exact=JSInvocationMirror]*/
+              /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+              /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
               _) =>
       42;
 
@@ -65,8 +65,8 @@
   /*member: Class3.noSuchMethod:[null|subclass=Object]*/
   noSuchMethod(
       Invocation
-          /*strong.[null|subclass=Object]*/
-          /*omit.[null|exact=JSInvocationMirror]*/
+          /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+          /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
           invocation) {
     return invocation
         .
@@ -101,8 +101,8 @@
   /*member: Class4.noSuchMethod:[null]*/
   noSuchMethod(
       Invocation
-          /*strong.[null|subclass=Object]*/
-          /*omit.[null|exact=JSInvocationMirror]*/
+          /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+          /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
           invocation) {
     this. /*update: [exact=Class4]*/ field = invocation
         .
diff --git a/tests/compiler/dart2js/inference/data/no_such_method1.dart b/tests/compiler/dart2js/inference/data/no_such_method1.dart
index f2bac32..8b37b2c 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method1.dart
@@ -8,8 +8,8 @@
 class A {
   /*member: A.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
-          /*strong.[null|subclass=Object]*/
-          /*omit.[null|exact=JSInvocationMirror]*/
+          /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+          /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
           im) =>
       42;
 }
diff --git a/tests/compiler/dart2js/inference/data/no_such_method2.dart b/tests/compiler/dart2js/inference/data/no_such_method2.dart
index 8f56a10..9c5f719 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method2.dart
@@ -8,8 +8,8 @@
 abstract class A {
   /*member: A.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
-          /*strong.[null|subclass=Object]*/
-          /*omit.[null|exact=JSInvocationMirror]*/
+          /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+          /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
           im) =>
       42;
 }
@@ -33,8 +33,8 @@
 
   /*member: D.noSuchMethod:[exact=JSDouble]*/
   noSuchMethod(
-          /*omit.[null|exact=JSInvocationMirror]*/
-          /*strong.[null|subclass=Object]*/
+          /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
+          /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
           im) =>
       42.5;
 }
diff --git a/tests/compiler/dart2js/inference/data/no_such_method3.dart b/tests/compiler/dart2js/inference/data/no_such_method3.dart
index 06a8679..473e312 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method3.dart
@@ -10,8 +10,8 @@
   // throws an exception.
   /*member: A.noSuchMethod:[empty]*/
   noSuchMethod(
-          /*strong.[null|subclass=Object]*/
-          /*omit.[null|exact=JSInvocationMirror]*/
+          /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+          /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
           im) =>
       throw 'foo';
 }
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index 3cdb9d4..e73c209 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -18,8 +18,8 @@
 /*member: _trustParameters:[exact=JSUInt31]*/
 _trustParameters(
     int
-        /*strong.Union([exact=JSString], [exact=JSUInt31])*/
-        /*omit.[exact=JSUInt31]*/
+        /*spec:nnbd-off|spec:nnbd-sdk.Union([exact=JSString], [exact=JSUInt31])*/
+        /*prod:nnbd-off|prod:nnbd-sdk.[exact=JSUInt31]*/
         i) {
   return i;
 }
diff --git a/tests/compiler/dart2js/inference/inference_data/marker.options b/tests/compiler/dart2js/inference/inference_data/marker.options
index c90afd3..1ac262c 100644
--- a/tests/compiler/dart2js/inference/inference_data/marker.options
+++ b/tests/compiler/dart2js/inference/inference_data/marker.options
@@ -1 +1,2 @@
-strong=tests/compiler/dart2js/inference/inference_data_test.dart
+spec:nnbd-off=tests/compiler/dart2js/inference/inference_data_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/inference_data_test.dart
diff --git a/tests/compiler/dart2js/inference/inference_data_test.dart b/tests/compiler/dart2js/inference/inference_data_test.dart
index 48392cd..1ad073f 100644
--- a/tests/compiler/dart2js/inference/inference_data_test.dart
+++ b/tests/compiler/dart2js/inference/inference_data_test.dart
@@ -25,7 +25,7 @@
         new Directory.fromUri(Platform.script.resolve('inference_data'));
     await checkTests(dataDir, const InferenceDataComputer(),
         args: args,
-        testedConfigs: [strongConfig],
+        testedConfigs: allSpecConfigs,
         options: [stopAfterTypeInference]);
   });
 }
diff --git a/tests/compiler/dart2js/inference/side_effects/marker.options b/tests/compiler/dart2js/inference/side_effects/marker.options
index 03ae8ce..18f405c 100644
--- a/tests/compiler/dart2js/inference/side_effects/marker.options
+++ b/tests/compiler/dart2js/inference/side_effects/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inference/side_effects_test.dart
-omit=tests/compiler/dart2js/inference/side_effects_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inference/side_effects_test.dart
+prod:nnbd-off=tests/compiler/dart2js/inference/side_effects_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/side_effects_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inference/side_effects_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inlining/data/constructor.dart b/tests/compiler/dart2js/inlining/data/constructor.dart
index f9e0070..5e4b03e 100644
--- a/tests/compiler/dart2js/inlining/data/constructor.dart
+++ b/tests/compiler/dart2js/inlining/data/constructor.dart
@@ -51,7 +51,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3<T> {
-  /*member: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class3.:[forceInlineGenericConstructor:Class3<int*>]*/
   @pragma('dart2js:tryInline')
   Class3();
 }
@@ -67,13 +68,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4a<T> implements Class4b<T> {
-  /*member: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4a.:[forceInlineGenericFactory:Class4a<int*>]*/
   @pragma('dart2js:tryInline')
   Class4a();
 }
 
 class Class4b<T> {
-  /*member: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4b.:[forceInlineGenericFactory:Class4b<int*>]*/
   @pragma('dart2js:tryInline')
   factory Class4b() => new Class4a<T>();
 }
diff --git a/tests/compiler/dart2js/inlining/data/marker.options b/tests/compiler/dart2js/inlining/data/marker.options
index 4750f8f..2dc3010 100644
--- a/tests/compiler/dart2js/inlining/data/marker.options
+++ b/tests/compiler/dart2js/inlining/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inlining/inlining_test.dart
-omit=tests/compiler/dart2js/inlining/inlining_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inlining/inlining_test.dart
+prod:nnbd-off=tests/compiler/dart2js/inlining/inlining_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inlining/inlining_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inlining/inlining_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inlining/data/nested.dart b/tests/compiler/dart2js/inlining/data/nested.dart
index e735510..f1239aa 100644
--- a/tests/compiler/dart2js/inlining/data/nested.dart
+++ b/tests/compiler/dart2js/inlining/data/nested.dart
@@ -15,7 +15,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1<T> {
-  /*member: Class1.:[nestedGenericInlining:Class1<int>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class1.:[nestedGenericInlining:Class1<int>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class1.:[nestedGenericInlining:Class1<int*>]*/
   @pragma('dart2js:tryInline')
   Class1();
 
@@ -29,7 +30,8 @@
 class Class2<T> {
   // TODO(johnniwinther): Should the type have been Class<List<int>>?
   // Similarly below.
-  /*member: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class2.:[nestedGenericInlining:Class2<List<Class1.T*>*>]*/
   @pragma('dart2js:tryInline')
   Class2();
 
@@ -49,7 +51,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3a<T> implements Class3b<T> {
-  /*member: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class3a.:[nestedGenericFactoryInlining:Class3a<int*>]*/
   @pragma('dart2js:tryInline')
   Class3a();
 
@@ -61,7 +64,8 @@
 }
 
 abstract class Class3b<T> {
-  /*member: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class3b.:[nestedGenericFactoryInlining:Class3b<int*>]*/
   @pragma('dart2js:tryInline')
   factory Class3b() => new Class3a<T>();
 
@@ -69,7 +73,8 @@
 }
 
 class Class4a<T> implements Class4b<T> {
-  /*member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T*>]*/
   @pragma('dart2js:tryInline')
   Class4a();
 
@@ -79,7 +84,8 @@
 }
 
 abstract class Class4b<T> {
-  /*member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
+  /*spec:nnbd-off|prod:nnbd-off.member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
+  /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T*>*>]*/
   @pragma('dart2js:tryInline')
   factory Class4b() => new Class4a<T>();
 
diff --git a/tests/compiler/dart2js/inlining/data/type_variables.dart b/tests/compiler/dart2js/inlining/data/type_variables.dart
index 14a1ce3..40fb3b1 100644
--- a/tests/compiler/dart2js/inlining/data/type_variables.dart
+++ b/tests/compiler/dart2js/inlining/data/type_variables.dart
@@ -9,12 +9,14 @@
   inlineTypeTests();
 }
 
-/*member: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
+/*spec:nnbd-off|prod:nnbd-off.member: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
+/*spec:nnbd-sdk|prod:nnbd-sdk.member: Mixin1.:[inlineTypeTests:Mixin1<int*>]*/
 class Mixin1<S> {
   var field = /*[]*/ (S s) => null;
 }
 
-/*member: Class1.:[inlineTypeTests:Class1<int>]*/
+/*spec:nnbd-off|prod:nnbd-off.member: Class1.:[inlineTypeTests:Class1<int>]*/
+/*spec:nnbd-sdk|prod:nnbd-sdk.member: Class1.:[inlineTypeTests:Class1<int*>]*/
 class Class1<T> extends Object with Mixin1<T> {}
 
 /*member: _inlineTypeTests:[inlineTypeTests]*/
diff --git a/tests/compiler/dart2js/jumps/data/marker.options b/tests/compiler/dart2js/jumps/data/marker.options
index 37aec9d..6c8f0b4 100644
--- a/tests/compiler/dart2js/jumps/data/marker.options
+++ b/tests/compiler/dart2js/jumps/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/jumps/jump_test.dart
-omit=tests/compiler/dart2js/jumps/jump_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/jumps/jump_test.dart
+prod:nnbd-off=tests/compiler/dart2js/jumps/jump_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/jumps/jump_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/jumps/jump_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/member_usage/data/marker.options b/tests/compiler/dart2js/member_usage/data/marker.options
index 91b789d..31de344 100644
--- a/tests/compiler/dart2js/member_usage/data/marker.options
+++ b/tests/compiler/dart2js/member_usage/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/member_usage/member_usage_test.dart
-omit=tests/compiler/dart2js/member_usage/member_usage_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/member_usage/member_usage_test.dart
+prod:nnbd-off=tests/compiler/dart2js/member_usage/member_usage_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/member_usage/member_usage_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/member_usage/member_usage_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/member_usage/member_usage_test.dart b/tests/compiler/dart2js/member_usage/member_usage_test.dart
index 834cd14..ff367d6 100644
--- a/tests/compiler/dart2js/member_usage/member_usage_test.dart
+++ b/tests/compiler/dart2js/member_usage/member_usage_test.dart
@@ -25,12 +25,12 @@
     print(' Test with enqueuer checks');
     print('------------------------------------------------------------------');
     await checkTests(dataDir, const ClosedWorldDataComputer(false),
-        args: args, testedConfigs: allStrongConfigs);
+        args: args, testedConfigs: allSpecConfigs);
     print('------------------------------------------------------------------');
     print(' Test without enqueuer checks');
     print('------------------------------------------------------------------');
     await checkTests(dataDir, const ClosedWorldDataComputer(true),
-        args: args, testedConfigs: allStrongConfigs);
+        args: args, testedConfigs: allSpecConfigs);
   });
 }
 
diff --git a/tests/compiler/dart2js/model/cfe_annotations_test.dart b/tests/compiler/dart2js/model/cfe_annotations_test.dart
index 2dde603..3c5dbd4 100644
--- a/tests/compiler/dart2js/model/cfe_annotations_test.dart
+++ b/tests/compiler/dart2js/model/cfe_annotations_test.dart
@@ -11,6 +11,7 @@
 import 'package:compiler/src/ir/annotations.dart';
 import 'package:compiler/src/js_backend/native_data.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
+import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/kernel/element_map_impl.dart';
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' as ir;
@@ -204,6 +205,7 @@
       void testAll(NativeData nativeData) {
         void testMember(String idPrefix, ir.Member member,
             {bool implicitJsInteropMember, bool implicitNativeMember}) {
+          if (memberIsIgnorable(member)) return;
           String memberId = '$idPrefix::${member.name.name}';
           MemberEntity memberEntity = elementMap.getMember(member);
 
diff --git a/tests/compiler/dart2js/model/future_or_test.dart b/tests/compiler/dart2js/model/future_or_test.dart
index 87d52be..feb5e2e 100644
--- a/tests/compiler/dart2js/model/future_or_test.dart
+++ b/tests/compiler/dart2js/model/future_or_test.dart
@@ -8,6 +8,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:expect/expect.dart';
+import '../helpers/memory_compiler.dart';
 import '../helpers/type_test_helper.dart';
 
 main() {
@@ -52,6 +53,14 @@
   new C().futureOrT();
 }
 """);
+    var options = env.compiler.options;
+
+    String typeToString(DartType type) {
+      return type.toStructuredText(
+          printLegacyStars: options.printLegacyStars,
+          useLegacySubtyping: options.useLegacySubtyping);
+    }
+
     FunctionType getFunctionType(String name, String expectedType,
         [ClassEntity cls]) {
       FunctionType type = env.getMemberType(name, cls);
@@ -59,9 +68,9 @@
           "Member $name not found${cls != null ? ' in class $cls' : ''}.");
       Expect.equals(
           expectedType,
-          '${type}',
+          typeToString(type),
           "Unexpected type for $name"
-              "${cls != null ? ' in class $cls' : ''}.");
+          "${cls != null ? ' in class $cls' : ''}.");
       return type;
     }
 
@@ -70,12 +79,12 @@
       FunctionType type = env.getMemberType(name, cls);
       Expect.isNotNull(type,
           "Member $name not found${cls != null ? ' in class $cls' : ''}.");
-      DartType returnType = type.returnType;
+      DartType returnType = type.returnType.withoutNullability;
       Expect.equals(
           expectedType,
-          '${returnType}',
+          typeToString(returnType),
           "Unexpected return type for $name"
-              "${cls != null ? ' in class $cls' : ''}.");
+          "${cls != null ? ' in class $cls' : ''}.");
       return returnType;
     }
 
@@ -107,13 +116,13 @@
     ClassEntity C = env.getClass('C');
     DartType futureT = getReturnType('futureT', 'Future<C.T>', C);
     FutureOrType futureOrT = getReturnType('futureOrT', 'FutureOr<C.T>', C);
-    DartType T = futureOrT.typeArgument;
+    DartType T = futureOrT.typeArgument.withoutNullability;
     Expect.isTrue(futureOrT.containsTypeVariables);
     futureOrT.forEachTypeVariable((t) => Expect.equals(T, t));
 
     DartType returnVoid = getFunctionType('returnVoid', 'void Function()');
-    DartType returnFutureNull =
-        getFunctionType('futureOrNull', 'Future<Null> Function()');
+    DartType returnFutureNull = getFunctionType('futureOrNull',
+        isDart2jsNnbd ? 'Future<Null>? Function()' : 'Future<Null> Function()');
 
     List<DartType> all = [
       Object_,
diff --git a/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart b/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
index 7535b2d..ae719aa 100644
--- a/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
+++ b/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
@@ -145,6 +145,7 @@
               .parameterTypes
               .first;
         }
+        type = type.withoutNullability;
         Expect.isTrue(type is TypeVariableType,
             "Unexpected member type for $member: $type");
         TypeVariableType typeVariable = type;
diff --git a/tests/compiler/dart2js/model/type_substitution_test.dart b/tests/compiler/dart2js/model/type_substitution_test.dart
index d5db6b3..64e3702 100644
--- a/tests/compiler/dart2js/model/type_substitution_test.dart
+++ b/tests/compiler/dart2js/model/type_substitution_test.dart
@@ -228,23 +228,23 @@
       env.elementEnvironment,
       arguments,
       parameters,
-      types.functionType(intType, [StringType], [], [], [], []),
-      types.functionType(intType, [StringType], [], [], [], []));
+      types.functionType(intType, [StringType], [], [], {}, [], []),
+      types.functionType(intType, [StringType], [], [], {}, [], []));
   testSubstitution(
       types,
       env.elementEnvironment,
       arguments,
       parameters,
-      types.functionType(types.voidType(), [T, S], [], [], [], []),
+      types.functionType(types.voidType(), [T, S], [], [], {}, [], []),
       types.functionType(
-          types.voidType(), [intType, StringType], [], [], [], []));
+          types.voidType(), [intType, StringType], [], [], {}, [], []));
   testSubstitution(
       types,
       env.elementEnvironment,
       arguments,
       parameters,
       types.functionType(
-          types.voidType(), [types.dynamicType()], [], [], [], []),
+          types.voidType(), [types.dynamicType()], [], [], {}, [], []),
       types.functionType(
-          types.voidType(), [types.dynamicType()], [], [], [], []));
+          types.voidType(), [types.dynamicType()], [], [], {}, [], []));
 }
diff --git a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
index 865a2d0..4db1df3 100644
--- a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
+++ b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
@@ -54,8 +54,8 @@
   }
 }
 
-/*strong.member: main:*/
-/*omit.member: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
 main() {
   var c1 = new ViewCardComponent();
   c1.ctx = new CardComponent();
diff --git a/tests/compiler/dart2js/optimization/data/index.dart b/tests/compiler/dart2js/optimization/data/index.dart
index 7b95043..8047545 100644
--- a/tests/compiler/dart2js/optimization/data/index.dart
+++ b/tests/compiler/dart2js/optimization/data/index.dart
@@ -39,8 +39,8 @@
   return list[index]; // CFE inserts an implicit cast of the index.
 }
 
-/*strong.member: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
-/*omit.member: mutableDynamicListDynamicIndex:Specializer=[Index]*/
+/*spec:nnbd-off.member: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableDynamicListDynamicIndex:Specializer=[Index]*/
 @pragma('dart2js:noInline')
 @pragma('dart2js:disableFinal')
 mutableDynamicListDynamicIndex(dynamic index) {
diff --git a/tests/compiler/dart2js/optimization/data/index_assign.dart b/tests/compiler/dart2js/optimization/data/index_assign.dart
index 45a88e4..67d5523 100644
--- a/tests/compiler/dart2js/optimization/data/index_assign.dart
+++ b/tests/compiler/dart2js/optimization/data/index_assign.dart
@@ -10,39 +10,39 @@
   list[0] = 1;
 }
 
-/*strong.member: unknownListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: unknownListIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: unknownListIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: unknownListIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 unknownListIndexAssign(List list) {
   list[0] = 1;
 }
 
-/*strong.member: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 possiblyNullMutableListIndexAssign(bool b) {
   var list = b ? [0] : null;
   list[0] = 1;
 }
 
-/*strong.member: mutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: mutableListIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: mutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableListIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 mutableListIndexAssign() {
   var list = [0];
   list[0] = 1;
 }
 
-/*strong.member: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 mutableListDynamicIndexAssign(dynamic index) {
   var list = [0];
   list[index] = 1;
 }
 
-/*strong.member: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 mutableListDynamicValueIndexAssign(dynamic value) {
   var list = [0];
diff --git a/tests/compiler/dart2js/optimization/data/marker.options b/tests/compiler/dart2js/optimization/data/marker.options
index 3b03def..2c09b09 100644
--- a/tests/compiler/dart2js/optimization/data/marker.options
+++ b/tests/compiler/dart2js/optimization/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/optimization/optimization_test.dart
-omit=tests/compiler/dart2js/optimization/optimization_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/optimization/optimization_test.dart
+prod:nnbd-off=tests/compiler/dart2js/optimization/optimization_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/optimization/optimization_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/optimization/optimization_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/optimization/optimization_test.dart b/tests/compiler/dart2js/optimization/optimization_test.dart
index e2687f6..b5f2987 100644
--- a/tests/compiler/dart2js/optimization/optimization_test.dart
+++ b/tests/compiler/dart2js/optimization/optimization_test.dart
@@ -38,7 +38,7 @@
   const OptimizationDataValidator({this.strict: false});
 
   @override
-  String getText(OptimizationTestLog actualData) {
+  String getText(OptimizationTestLog actualData, [String indentation]) {
     Features features = new Features();
     for (OptimizationLogEntry entry in actualData.entries) {
       features.addElement(
diff --git a/tests/compiler/dart2js/rti/data/async_foreach.dart b/tests/compiler/dart2js/rti/data/async_foreach.dart
index 22efbe0..16b3479 100644
--- a/tests/compiler/dart2js/rti/data/async_foreach.dart
+++ b/tests/compiler/dart2js/rti/data/async_foreach.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*strong.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
-/*omit.class: Class:needsArgs*/
+/*spec:nnbd-off.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
+/*prod:nnbd-off.class: Class:needsArgs*/
 class Class<T> {
   method() {
     var list = <T>[];
@@ -16,8 +16,8 @@
     // This happens because the closure is thought as possibly going to the
     // async.errorHandler callback.
     list.forEach(
-        /*strong.needsSignature*/
-        /*omit.needsSignature*/
+        /*spec:nnbd-off.needsSignature*/
+        /*prod:nnbd-off.needsSignature*/
         (x) => print(x));
   }
 }
diff --git a/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart b/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart
index 7c27624..208a51d 100644
--- a/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart
+++ b/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart
@@ -4,16 +4,16 @@
 
 // @dart = 2.7
 
-/*strong.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
   method() {
     var list = <T>[];
     // If any method was `async`, this would have triggered the need for type
     // arguments on `Class`. See the 'async_foreach.dart' test.
     list.forEach(
-        /*strong.needsSignature*/
-        /*omit.*/
+        /*spec:nnbd-off.needsSignature*/
+        /*prod:nnbd-off.*/
         (x) => print(x));
   }
 }
diff --git a/tests/compiler/dart2js/rti/data/async_local.dart b/tests/compiler/dart2js/rti/data/async_local.dart
index 14bd0d2..a402273 100644
--- a/tests/compiler/dart2js/rti/data/async_local.dart
+++ b/tests/compiler/dart2js/rti/data/async_local.dart
@@ -12,8 +12,8 @@
   // This happens because the closure is thought as possibly going to the
   // async.errorHandler callback.
 
-  /*strong.needsSignature*/
-  /*omit.needsSignature*/
+  /*spec:nnbd-off.needsSignature*/
+  /*prod:nnbd-off.needsSignature*/
   local(object, stacktrace) => null;
 
   return local;
diff --git a/tests/compiler/dart2js/rti/data/async_local_nonasync.dart b/tests/compiler/dart2js/rti/data/async_local_nonasync.dart
index e07c33e7..350559d 100644
--- a/tests/compiler/dart2js/rti/data/async_local_nonasync.dart
+++ b/tests/compiler/dart2js/rti/data/async_local_nonasync.dart
@@ -8,8 +8,8 @@
   // If any method was `async`, this would have triggered the need for the
   // signature on this closure. See the 'async_local.dart' test.
 
-  /*strong.*/
-  /*omit.*/
+  /*spec:nnbd-off.*/
+  /*prod:nnbd-off.*/
   local(object, stacktrace) => null;
 
   return local;
diff --git a/tests/compiler/dart2js/rti/data/async_local_typed.dart b/tests/compiler/dart2js/rti/data/async_local_typed.dart
index 5154e91..3ef5a62 100644
--- a/tests/compiler/dart2js/rti/data/async_local_typed.dart
+++ b/tests/compiler/dart2js/rti/data/async_local_typed.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*strong.class: Class:explicit=[Class<int>],needsArgs*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:explicit=[Class<int>],needsArgs*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {}
 
 main() async {
@@ -14,8 +14,8 @@
   // `dynamic Function(dynamic, Class<int>)`, is not a potential subtype and
   // therefore doesn't need its signature.
 
-  /*strong.needsSignature*/
-  /*omit.*/
+  /*spec:nnbd-off.needsSignature*/
+  /*prod:nnbd-off.*/
   local(object, Class<int> stacktrace) => null;
 
   return local;
diff --git a/tests/compiler/dart2js/rti/data/call_typed_generic.dart b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
index 3cf8ad8..2dbf94e 100644
--- a/tests/compiler/dart2js/rti/data/call_typed_generic.dart
+++ b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
@@ -6,11 +6,11 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
-/*omit.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
 class A<T> {
-  /*strong.member: A.call:*/
-  /*omit.member: A.call:*/
+  /*spec:nnbd-off.member: A.call:*/
+  /*prod:nnbd-off.member: A.call:*/
   call(T t) {}
 }
 
diff --git a/tests/compiler/dart2js/rti/data/closure.dart b/tests/compiler/dart2js/rti/data/closure.dart
index 4804c14..ab166f5 100644
--- a/tests/compiler/dart2js/rti/data/closure.dart
+++ b/tests/compiler/dart2js/rti/data/closure.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*omit.class: A:needsArgs*/
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:needsArgs*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
 class A<T> {
   m() {
     return /*needsSignature*/ (T t) {};
@@ -16,8 +16,8 @@
     // TODO(johnniwinther): Optimize local function type signature need.
     return
 
-        /*strong.needsSignature*/
-        /*omit.needsSignature*/
+        /*spec:nnbd-off.needsSignature*/
+        /*prod:nnbd-off.needsSignature*/
         (int t) {};
   }
 }
diff --git a/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart b/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart
index 6fd577d..229f8f7 100644
--- a/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart
+++ b/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*omit.class: A:*/
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
 class A<T> {
   @pragma('dart2js:noInline')
   m() {
diff --git a/tests/compiler/dart2js/rti/data/closure_unneeded.dart b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
index 6fd577d..229f8f7 100644
--- a/tests/compiler/dart2js/rti/data/closure_unneeded.dart
+++ b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*omit.class: A:*/
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
 class A<T> {
   @pragma('dart2js:noInline')
   m() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is2.dart b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
index 09f291b..5018f3a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*omit.class: A:*/
-/*strong.class: A:explicit=[A]*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
 class A {
   /*member: A.instanceMethod:deps=[B.instanceMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not2.dart b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
index c8f9f6e..83b7dda 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*strong.class: A:explicit=[A]*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
 class A {
   /*member: A.instanceMethod:deps=[B.instanceMethod]*/
   instanceMethod<T>(t) => t;
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
index 74625dd..666f0f9 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*omit.class: A:*/
-/*strong.class: A:explicit=[A]*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
 class A {
   /*member: A.instanceMethod:deps=[staticMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
diff --git a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
index 7bf6ce1..8812e53 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*strong.class: A:explicit=[A]*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
 class A {
   /*member: A.instanceMethod:deps=[B.instanceMethod],exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
   instanceMethod<T>() => T;
diff --git a/tests/compiler/dart2js/rti/data/explicit_as.dart b/tests/compiler/dart2js/rti/data/explicit_as.dart
index 8bb7f30..439b1a3 100644
--- a/tests/compiler/dart2js/rti/data/explicit_as.dart
+++ b/tests/compiler/dart2js/rti/data/explicit_as.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*strong.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
-/*omit.class: C:*/
+/*spec:nnbd-off.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
+/*prod:nnbd-off.class: C:*/
 class C<T> {
   T field;
 }
diff --git a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
index 8d429b8..e45aa6c 100644
--- a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
+++ b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
@@ -21,12 +21,12 @@
   void test(String nameOfT, bool expectedResult) {
     // TODO(johnniwinther): Optimize local function type signature need.
 
-    /*strong.needsSignature*/
-    /*omit.needsSignature*/
+    /*spec:nnbd-off.needsSignature*/
+    /*prod:nnbd-off.needsSignature*/
     int foo(bool a, [String b]) => null;
 
-    /*strong.needsSignature*/
-    /*omit.needsSignature*/
+    /*spec:nnbd-off.needsSignature*/
+    /*prod:nnbd-off.needsSignature*/
     int baz(bool a, {String b}) => null;
 
     Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
diff --git a/tests/compiler/dart2js/rti/data/generic_bounds.dart b/tests/compiler/dart2js/rti/data/generic_bounds.dart
index dcfdfbc..d87e5fd 100644
--- a/tests/compiler/dart2js/rti/data/generic_bounds.dart
+++ b/tests/compiler/dart2js/rti/data/generic_bounds.dart
@@ -6,46 +6,46 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class1a:explicit=[Class1a]*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a]*/
 class Class1a {}
 
 class Class1b extends Class1a {}
 
-/*strong.class: Class2a:explicit=[Class2a<num>],needsArgs*/
+/*spec:nnbd-off.class: Class2a:explicit=[Class2a<num>],needsArgs*/
 class Class2a<T> {}
 
 class Class2b<T> extends Class2a<T> {}
 
-/*strong.member: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*spec:nnbd-off.member: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
 method1<T extends Class1a>() => null;
 
-/*strong.member: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*spec:nnbd-off.member: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
 method2<T extends Class2a<num>>() => null;
 
 method3<T>() => null;
 
 class Class3 {
-  /*strong.member: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*spec:nnbd-off.member: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
   method4<T extends Class1a>() => null;
 
-  /*strong.member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+  /*spec:nnbd-off.member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
   method5<T extends Class2a<num>>() => null;
 
   method6<T>() => null;
 }
 
-/*strong.class: Class4:explicit=[Class4]*/
+/*spec:nnbd-off.class: Class4:explicit=[Class4]*/
 class Class4 {}
 
-/*strong.member: method10:needsArgs*/
+/*spec:nnbd-off.member: method10:needsArgs*/
 method10<T extends Class4>() => null;
 
 main() {
-  /*strong.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
-  /*omit.*/method7<T extends Class1a>() => null;
+  /*spec:nnbd-off.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+  /*prod:nnbd-off.*/method7<T extends Class1a>() => null;
 
-  /*strong.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
-  /*omit.*/method8<T extends Class2a<num>>() => null;
+  /*spec:nnbd-off.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+  /*prod:nnbd-off.*/method8<T extends Class2a<num>>() => null;
 
   /**/
   method9<T>() => null;
diff --git a/tests/compiler/dart2js/rti/data/generic_class_is2.dart b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
index 1f60af6..4801a9b 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
@@ -9,8 +9,8 @@
 /*class: A:implicit=[List<A<C2>>,List<A<C>>]*/
 class A<T> {}
 
-/*omit.class: A1:*/
-/*strong.class: A1:implicit=[A1]*/
+/*prod:nnbd-off.class: A1:*/
+/*spec:nnbd-off.class: A1:implicit=[A1]*/
 class A1 implements A<C1> {}
 
 /*class: B:direct,explicit=[B.T],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_creation.dart b/tests/compiler/dart2js/rti/data/generic_creation.dart
index d0a90fa..a2b5519 100644
--- a/tests/compiler/dart2js/rti/data/generic_creation.dart
+++ b/tests/compiler/dart2js/rti/data/generic_creation.dart
@@ -8,44 +8,44 @@
 
 /*class: A:needsArgs*/
 
-/*strong.member: A.:*/
-/*omit.member: A.:*/
+/*spec:nnbd-off.member: A.:*/
+/*prod:nnbd-off.member: A.:*/
 class A<X, Y, Z> {
-  /*strong.member: A.shift:*/
-  /*omit.member: A.shift:*/
+  /*spec:nnbd-off.member: A.shift:*/
+  /*prod:nnbd-off.member: A.shift:*/
   shift() => new A<Z, X, Y>();
 
-  /*strong.member: A.swap:*/
-  /*omit.member: A.swap:*/
+  /*spec:nnbd-off.member: A.swap:*/
+  /*prod:nnbd-off.member: A.swap:*/
   swap() => new A<Z, Y, X>();
 
-  /*strong.member: A.first:*/
-  /*omit.member: A.first:*/
+  /*spec:nnbd-off.member: A.first:*/
+  /*prod:nnbd-off.member: A.first:*/
   first() => new A<X, X, X>();
 
-  /*strong.member: A.last:*/
-  /*omit.member: A.last:*/
+  /*spec:nnbd-off.member: A.last:*/
+  /*prod:nnbd-off.member: A.last:*/
   last() => new A<Z, Z, Z>();
 
-  /*strong.member: A.wrap:*/
-  /*omit.member: A.wrap:*/
+  /*spec:nnbd-off.member: A.wrap:*/
+  /*prod:nnbd-off.member: A.wrap:*/
   wrap() => new A<A<X, X, X>, A<Y, Y, Y>, A<Z, Z, Z>>();
 }
 
-/*strong.member: B.:*/
-/*omit.member: B.:*/
+/*spec:nnbd-off.member: B.:*/
+/*prod:nnbd-off.member: B.:*/
 class B extends A<U, V, W> {}
 
 /*class: C:needsArgs*/
 
-/*strong.member: C.:*/
-/*omit.member: C.:*/
+/*spec:nnbd-off.member: C.:*/
+/*prod:nnbd-off.member: C.:*/
 class C<T> extends A<U, T, W> {}
 
 /*class: D:needsArgs*/
 
-/*strong.member: D.:*/
-/*omit.member: D.:*/
+/*spec:nnbd-off.member: D.:*/
+/*prod:nnbd-off.member: D.:*/
 class D<X, Y, Z> extends A<Y, Z, X> {}
 
 class U {}
@@ -54,12 +54,12 @@
 
 class W {}
 
-/*strong.member: sameType:*/
-/*omit.member: sameType:*/
+/*spec:nnbd-off.member: sameType:*/
+/*prod:nnbd-off.member: sameType:*/
 sameType(a, b) => Expect.equals(a.runtimeType, b.runtimeType);
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   A a = new A<U, V, W>();
   sameType(new A<W, U, V>(), a.shift());
diff --git a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
index 3599e85..1b5c9bf 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
@@ -10,8 +10,8 @@
 /*class: B:deps=[method],explicit=[B<A>],needsArgs*/
 class B<T> {}
 
-/*strong.member: method:needsArgs*/
-/*omit.member: method:needsArgs*/
+/*spec:nnbd-off.member: method:needsArgs*/
+/*prod:nnbd-off.member: method:needsArgs*/
 method<T>() => new B<T>();
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is.dart b/tests/compiler/dart2js/rti/data/generic_method_is.dart
index 8f24a5d..53bf8c4 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*strong.member: method:direct,explicit=[method.T],needsArgs*/
-/*omit.member: method:direct,explicit=[method.T],needsArgs*/
+/*spec:nnbd-off.member: method:direct,explicit=[method.T],needsArgs*/
+/*prod:nnbd-off.member: method:direct,explicit=[method.T],needsArgs*/
 method<T>(T t) => t is T;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is2.dart b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
index de364f3..590ae1b 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
@@ -7,19 +7,19 @@
 /*class: A1:implicit=[A1]*/
 class A1 {}
 
-/*strong.class: A2:implicit=[A2]*/
+/*spec:nnbd-off.class: A2:implicit=[A2]*/
 class A2 {}
 
 /*class: B1:implicit=[B1]*/
 class B1 {}
 
-/*strong.class: B2:implicit=[B2]*/
+/*spec:nnbd-off.class: B2:implicit=[B2]*/
 class B2 {}
 
 /*class: C1:implicit=[C1]*/
 class C1 {}
 
-/*strong.class: C2:implicit=[C2]*/
+/*spec:nnbd-off.class: C2:implicit=[C2]*/
 class C2 {}
 
 /*class: C3:implicit=[C3]*/
@@ -28,19 +28,19 @@
 /*class: D1:implicit=[D1]*/
 class D1 {}
 
-/*strong.class: D2:implicit=[D2]*/
+/*spec:nnbd-off.class: D2:implicit=[D2]*/
 class D2 {}
 
 /*class: E1:implicit=[E1]*/
 class E1 {}
 
-/*strong.class: E2:implicit=[E2]*/
+/*spec:nnbd-off.class: E2:implicit=[E2]*/
 class E2 {}
 
 /*class: F1:implicit=[F1]*/
 class F1 {}
 
-/*strong.class: F2:implicit=[F2]*/
+/*spec:nnbd-off.class: F2:implicit=[F2]*/
 class F2 {}
 
 /*class: F3:implicit=[F3]*/
@@ -50,7 +50,7 @@
 // Calls to this imply a check of the passed type arguments.
 bool topLevelMethod1<T>(T t, {a1}) => t is T;
 
-/*strong.member: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
+/*spec:nnbd-off.member: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
 // Calls to this does _not_ imply a check of the passed type arguments.
 T topLevelMethod2<T>(T t, {a2}) => t;
 
@@ -59,7 +59,7 @@
   // Calls to this imply a check of the passed type arguments.
   bool instanceMethod1<S>(S s, {b1}) => s is S;
 
-  /*strong.member: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
+  /*spec:nnbd-off.member: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
   // Calls to this does _not_ imply a check of the passed type arguments.
   S instanceMethod2<S>(S s, {b2}) => s;
 }
@@ -70,13 +70,13 @@
   bool localFunction1<U>(U u, {c1}) => u is U;
 
   // Calls to this does _not_ imply a check of the passed type arguments.
-  /*strong.direct,explicit=[localFunction2.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c2], types=1)]*/
+  /*spec:nnbd-off.direct,explicit=[localFunction2.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c2], types=1)]*/
   U localFunction2<U>(U u, {c2}) => u;
 
   // Calls to this does _not_ imply a check of the passed type arguments. A
   // call to the .call function on this will, though, since it has the same
   // signature as [localFunction1] which needs its type arguments.
-  /*strong.direct,explicit=[localFunction3.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c1], types=1)]*/
+  /*spec:nnbd-off.direct,explicit=[localFunction3.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c1], types=1)]*/
   localFunction3<U>(U u, {c1}) => u;
 
   var c = new Class();
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
index 13c5edd..f32f4e6 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
@@ -6,22 +6,22 @@
 
 // Test derived from language_2/generic_methods_dynamic_test/05
 
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
-/*strong.class: global#List:deps=[C.bar],explicit=[List,List<B>,List<String>],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
+/*spec:nnbd-off.class: global#List:deps=[C.bar],explicit=[List,List<B>,List<String>],indirect,needsArgs*/
 
-/*omit.class: global#List:deps=[C.bar],explicit=[List,List<B>],needsArgs*/
+/*prod:nnbd-off.class: global#List:deps=[C.bar],explicit=[List,List<B>],needsArgs*/
 import "package:expect/expect.dart";
 
 class A {}
 
-/*strong.class: B:explicit=[List<B>],implicit=[B]*/
-/*omit.class: B:explicit=[List<B>]*/
+/*spec:nnbd-off.class: B:explicit=[List<B>],implicit=[B]*/
+/*prod:nnbd-off.class: B:explicit=[List<B>]*/
 class B {}
 
 class C {
-  /*strong.member: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
-  /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*spec:nnbd-off.member: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*prod:nnbd-off.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
   List<T> bar<T>(Iterable<T> t) => <T>[t.first];
 }
 
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
index e0575e5..b780758 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
@@ -8,21 +8,21 @@
 
 import "package:expect/expect.dart";
 
-/*omit.class: A:deps=[C.bar],explicit=[A<B>],needsArgs*/
-/*strong.class: A:deps=[C.bar],direct,explicit=[A.T,A<B>,A<bar.T>],needsArgs*/
+/*prod:nnbd-off.class: A:deps=[C.bar],explicit=[A<B>],needsArgs*/
+/*spec:nnbd-off.class: A:deps=[C.bar],direct,explicit=[A.T,A<B>,A<bar.T>],needsArgs*/
 class A<T> {
   final T field;
 
   A(this.field);
 }
 
-/*omit.class: B:explicit=[A<B>]*/
-/*strong.class: B:explicit=[A<B>],implicit=[B]*/
+/*prod:nnbd-off.class: B:explicit=[A<B>]*/
+/*spec:nnbd-off.class: B:explicit=[A<B>],implicit=[B]*/
 class B {}
 
 class C {
-  /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
-  /*strong.member: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*prod:nnbd-off.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*spec:nnbd-off.member: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
   A<T> bar<T>(A<T> t) => new A<T>(t.field);
 }
 
diff --git a/tests/compiler/dart2js/rti/data/implicit_as.dart b/tests/compiler/dart2js/rti/data/implicit_as.dart
index 6c76287..95770b8 100644
--- a/tests/compiler/dart2js/rti/data/implicit_as.dart
+++ b/tests/compiler/dart2js/rti/data/implicit_as.dart
@@ -4,8 +4,8 @@
 
 // @dart = 2.7
 
-/*strong.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
-/*omit.class: C:*/
+/*spec:nnbd-off.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
+/*prod:nnbd-off.class: C:*/
 class C<T> {
   T field;
 }
diff --git a/tests/compiler/dart2js/rti/data/indirect_through_static.dart b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
index f1cc990..3dd9a7c 100644
--- a/tests/compiler/dart2js/rti/data/indirect_through_static.dart
+++ b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
@@ -4,19 +4,19 @@
 
 // @dart = 2.7
 
-/*strong.class: A:implicit=[A]*/
-/*omit.class: A:implicit=[A]*/
+/*spec:nnbd-off.class: A:implicit=[A]*/
+/*prod:nnbd-off.class: A:implicit=[A]*/
 abstract class A {}
 
 class B implements A {}
 
-/*strong.class: C:
+/*spec:nnbd-off.class: C:
   deps=[lookup],
   explicit=[C<lookup.T>,Map<String,C>],
   implicit=[C],
   needsArgs
 */
-/*omit.class: C:
+/*prod:nnbd-off.class: C:
  deps=[lookup],explicit=[C<lookup.T>],
  needsArgs
 */
@@ -28,8 +28,8 @@
   map['x'] = new C<B>();
 }
 
-/*strong.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
-/*omit.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*spec:nnbd-off.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*prod:nnbd-off.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
 C<T> lookup<T>(String key) {
   final value = map[key];
   if (value != null && value is C<T>) {
diff --git a/tests/compiler/dart2js/rti/data/instantiation1.dart b/tests/compiler/dart2js/rti/data/instantiation1.dart
index bd638dc..3ed0070 100644
--- a/tests/compiler/dart2js/rti/data/instantiation1.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation1.dart
@@ -4,13 +4,13 @@
 
 // @dart = 2.7
 
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B]*/
 int f<T>(T a) => null;
 
 typedef int F<R>(R a);
 
-/*strong.class: B:explicit=[int Function(B.S)],indirect,needsArgs*/
+/*spec:nnbd-off.class: B:explicit=[int Function(B.S)],indirect,needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation2.dart b/tests/compiler/dart2js/rti/data/instantiation2.dart
index 8c040bc..ee21996 100644
--- a/tests/compiler/dart2js/rti/data/instantiation2.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation2.dart
@@ -4,14 +4,14 @@
 
 // @dart = 2.7
 
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
 bool f<T>(T a) => a is T;
 
 typedef bool F<R>(R a);
 
-/*strong.class: B:explicit=[bool Function(B.S)],indirect,needsArgs*/
-/*omit.class: B:indirect,needsArgs*/
+/*spec:nnbd-off.class: B:explicit=[bool Function(B.S)],indirect,needsArgs*/
+/*prod:nnbd-off.class: B:indirect,needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation3.dart b/tests/compiler/dart2js/rti/data/instantiation3.dart
index 19899d9..67bfc44 100644
--- a/tests/compiler/dart2js/rti/data/instantiation3.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation3.dart
@@ -4,13 +4,13 @@
 
 // @dart = 2.7
 
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B]*/
 int f<T>(T a) => null;
 
 typedef int F<R>(R a);
 
-/*strong.class: B:direct,explicit=[int Function(B.S)],needsArgs*/
+/*spec:nnbd-off.class: B:direct,explicit=[int Function(B.S)],needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation4.dart b/tests/compiler/dart2js/rti/data/instantiation4.dart
index c40ca9c..57616a0 100644
--- a/tests/compiler/dart2js/rti/data/instantiation4.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation4.dart
@@ -4,14 +4,14 @@
 
 // @dart = 2.7
 
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
 bool f<T>(T a) => a is T;
 
 typedef bool F<R>(R a);
 
-/*strong.class: B:direct,explicit=[bool Function(B.S)],needsArgs*/
-/*omit.class: B:indirect,needsArgs*/
+/*spec:nnbd-off.class: B:direct,explicit=[bool Function(B.S)],needsArgs*/
+/*prod:nnbd-off.class: B:indirect,needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation5.dart b/tests/compiler/dart2js/rti/data/instantiation5.dart
index 8f3fb60..7ffbd29 100644
--- a/tests/compiler/dart2js/rti/data/instantiation5.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation5.dart
@@ -4,13 +4,13 @@
 
 // @dart = 2.7
 
-/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.member: f:deps=[method]*/
+/*spec:nnbd-off.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*prod:nnbd-off.member: f:deps=[method]*/
 int f<T>(T a) => null;
 
 typedef int F<R>(R a);
 
-/*strong.member: method:indirect,needsArgs*/
+/*spec:nnbd-off.member: method:indirect,needsArgs*/
 method<S>() {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation6.dart b/tests/compiler/dart2js/rti/data/instantiation6.dart
index 212557f..a2e2c79 100644
--- a/tests/compiler/dart2js/rti/data/instantiation6.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation6.dart
@@ -4,14 +4,14 @@
 
 // @dart = 2.7
 
-/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*spec:nnbd-off.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*prod:nnbd-off.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
 bool f<T>(T a) => a is T;
 
 typedef bool F<R>(R a);
 
-/*strong.member: method:indirect,needsArgs*/
-/*omit.member: method:indirect,needsArgs*/
+/*spec:nnbd-off.member: method:indirect,needsArgs*/
+/*prod:nnbd-off.member: method:indirect,needsArgs*/
 method<S>() {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation7.dart b/tests/compiler/dart2js/rti/data/instantiation7.dart
index 2786071..71498ebb 100644
--- a/tests/compiler/dart2js/rti/data/instantiation7.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation7.dart
@@ -4,23 +4,23 @@
 
 // @dart = 2.7
 
-/*strong.member: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
-/*omit.member: f1:deps=[method]*/
+/*spec:nnbd-off.member: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
+/*prod:nnbd-off.member: f1:deps=[method]*/
 int f1<T>(T a, T b, T c) => null;
 
-/*strong.member: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
-/*omit.member: f2:deps=[method]*/
+/*spec:nnbd-off.member: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
+/*prod:nnbd-off.member: f2:deps=[method]*/
 int f2<T, S>(T a, S b, S c) => null;
 
-/*strong.member: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
-/*omit.member: f3:deps=[method]*/
+/*spec:nnbd-off.member: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
+/*prod:nnbd-off.member: f3:deps=[method]*/
 int f3<T, S, U>(T a, S b, U c) => null;
 
 typedef int F1<R>(R a, R b, R c);
 typedef int F2<R, P>(R a, P b, P c);
 typedef int F3<R, P, Q>(R a, P b, Q c);
 
-/*strong.member: method:indirect,needsArgs*/
+/*spec:nnbd-off.member: method:indirect,needsArgs*/
 method<X, Y, Z>() {
   F1<X> c1;
   F2<X, Y> c2;
diff --git a/tests/compiler/dart2js/rti/data/list_literal.dart b/tests/compiler/dart2js/rti/data/list_literal.dart
index b5caf11..4baa47f 100644
--- a/tests/compiler/dart2js/rti/data/list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/list_literal.dart
@@ -4,11 +4,11 @@
 
 // @dart = 2.7
 
-/*strong.class: global#List:deps=[Class.m],explicit=[List,List<String>],indirect,needsArgs*/
-/*omit.class: global#List:deps=[Class.m],explicit=[List],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#List:deps=[Class.m],explicit=[List,List<String>],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#List:deps=[Class.m],explicit=[List],indirect,needsArgs*/
 
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class();
diff --git a/tests/compiler/dart2js/rti/data/list_to_set.dart b/tests/compiler/dart2js/rti/data/list_to_set.dart
index d5457ee..576528d 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set.dart
@@ -4,11 +4,11 @@
 
 // @dart = 2.7
 
-/*strong.class: global#List:deps=[Class],explicit=[List,List<String>],indirect,needsArgs*/
-/*omit.class: global#List:deps=[Class],explicit=[List],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#List:deps=[Class],explicit=[List,List<String>],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#List:deps=[Class],explicit=[List],indirect,needsArgs*/
 
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/data/local_function_generic.dart b/tests/compiler/dart2js/rti/data/local_function_generic.dart
index 99ea166..c3ca915 100644
--- a/tests/compiler/dart2js/rti/data/local_function_generic.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_generic.dart
@@ -7,8 +7,8 @@
 import 'package:expect/expect.dart';
 
 method1() {
-  /*strong.direct,explicit=[local.T],needsArgs,needsSignature*/
-  /*omit.needsSignature*/
+  /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsSignature*/
+  /*prod:nnbd-off.needsSignature*/
   T local<T>(T t) => t;
   return local;
 }
diff --git a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
index 585ab8b..66de226 100644
--- a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
@@ -6,10 +6,10 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.member: method:needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
+/*spec:nnbd-off.member: method:implicit=[method.T],indirect,needsArgs*/
+/*prod:nnbd-off.member: method:needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
 
 @pragma('dart2js:noInline')
 method<T>() {
diff --git a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
index 2aea2bb..0fed376 100644
--- a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
@@ -6,11 +6,11 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
-/*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
+/*spec:nnbd-off.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#LinkedHashMap:deps=[Map],needsArgs*/
 
-/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.member: method:needsArgs*/
+/*spec:nnbd-off.member: method:implicit=[method.T],indirect,needsArgs*/
+/*prod:nnbd-off.member: method:needsArgs*/
 @pragma('dart2js:noInline')
 method<T>() {
   return () => <T, int>{};
diff --git a/tests/compiler/dart2js/rti/data/local_function_signature2.dart b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
index 9d38877..48d3161 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signature2.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
@@ -27,8 +27,8 @@
 }
 
 class Class2 {
-  /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
-  /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*spec:nnbd-off.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*prod:nnbd-off.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
   method4<T>() {
     /*needsSignature*/
     num local(T n) => null;
@@ -46,8 +46,8 @@
 }
 
 class Class4 {
-  /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
-  /*omit.member: Class4.method6:*/
+  /*spec:nnbd-off.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+  /*prod:nnbd-off.member: Class4.method6:*/
   method6<T>() {
     /**/
     num local(num n, T t) => null;
@@ -55,8 +55,8 @@
   }
 }
 
-/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.member: method7:needsArgs*/
+/*spec:nnbd-off.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*prod:nnbd-off.member: method7:needsArgs*/
 method7<T>() {
   /*needsSignature*/
   num local(T n) => null;
@@ -70,8 +70,8 @@
   return local;
 }
 
-/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.member: method9:*/
+/*spec:nnbd-off.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*prod:nnbd-off.member: method9:*/
 method9<T>() {
   /**/
   num local(num n, T t) => null;
@@ -79,8 +79,8 @@
 }
 
 method10() {
-  /*strong.direct,explicit=[local.T],needsArgs*/
-  /*omit.*/
+  /*spec:nnbd-off.direct,explicit=[local.T],needsArgs*/
+  /*prod:nnbd-off.*/
   num local<T>(T n) => null;
   return local;
 }
@@ -92,8 +92,8 @@
 }
 
 method12() {
-  /*strong.direct,explicit=[local.T],needsArgs*/
-  /*omit.*/
+  /*spec:nnbd-off.direct,explicit=[local.T],needsArgs*/
+  /*prod:nnbd-off.*/
   num local<T>(num n, T t) => null;
   return local;
 }
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures.dart b/tests/compiler/dart2js/rti/data/local_function_signatures.dart
index f963ae0..2a2b2e9 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signatures.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures.dart
@@ -8,8 +8,8 @@
 
 class Class1 {
   method1() {
-    /*strong.needsSignature*/
-    /*omit.needsSignature*/
+    /*spec:nnbd-off.needsSignature*/
+    /*prod:nnbd-off.needsSignature*/
     num local(num n) => null;
     return local;
   }
@@ -25,8 +25,8 @@
   }
 }
 
-/*omit.class: Class2:needsArgs*/
-/*strong.class: Class2:direct,explicit=[Class2.T],needsArgs*/
+/*prod:nnbd-off.class: Class2:needsArgs*/
+/*spec:nnbd-off.class: Class2:direct,explicit=[Class2.T],needsArgs*/
 class Class2<T> {
   method4() {
     /*needsSignature*/
@@ -44,8 +44,8 @@
   }
 }
 
-/*omit.class: Class4:*/
-/*strong.class: Class4:direct,explicit=[Class4.T],needsArgs*/
+/*prod:nnbd-off.class: Class4:*/
+/*spec:nnbd-off.class: Class4:direct,explicit=[Class4.T],needsArgs*/
 class Class4<T> {
   method6() {
     /**/
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
index 0f38f17..1a089c8 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
@@ -27,8 +27,8 @@
 }
 
 class Class2 {
-  /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
-  /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*spec:nnbd-off.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*prod:nnbd-off.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
   method4<T>() {
     /*needsSignature*/
     num local(T n) => null;
@@ -46,8 +46,8 @@
 }
 
 class Class4 {
-  /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
-  /*omit.member: Class4.method6:*/
+  /*spec:nnbd-off.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+  /*prod:nnbd-off.member: Class4.method6:*/
   method6<T>() {
     /**/
     num local(num n, T t) => null;
@@ -55,8 +55,8 @@
   }
 }
 
-/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.member: method7:needsArgs*/
+/*spec:nnbd-off.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*prod:nnbd-off.member: method7:needsArgs*/
 method7<T>() {
   /*needsSignature*/
   num local(T n) => null;
@@ -70,8 +70,8 @@
   return local;
 }
 
-/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.member: method9:*/
+/*spec:nnbd-off.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*prod:nnbd-off.member: method9:*/
 method9<T>() {
   /**/
   num local(num n, T t) => null;
@@ -79,8 +79,8 @@
 }
 
 method10() {
-  /*strong.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
-  /*omit.needsSignature*/
+  /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
+  /*prod:nnbd-off.needsSignature*/
   num local<T>(T n) => null;
   return local;
 }
@@ -92,8 +92,8 @@
 }
 
 method12() {
-  /*strong.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>]*/
-  /*omit.*/
+  /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>]*/
+  /*prod:nnbd-off.*/
   num local<T>(num n, T t) => null;
   return local;
 }
@@ -105,8 +105,8 @@
 }
 
 num Function(num) method14() {
-  /*strong.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
-  /*omit.needsSignature*/
+  /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
+  /*prod:nnbd-off.needsSignature*/
   num local<T>(T n) => null;
   return local;
 }
diff --git a/tests/compiler/dart2js/rti/data/map_literal.dart b/tests/compiler/dart2js/rti/data/map_literal.dart
index 3472e19..47252cb 100644
--- a/tests/compiler/dart2js/rti/data/map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal.dart
@@ -4,17 +4,17 @@
 
 // @dart = 2.7
 
-/*omit.class: global#Map:*/
-/*strong.class: global#Map:explicit=[Map],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#Map:*/
+/*spec:nnbd-off.class: global#Map:explicit=[Map],indirect,needsArgs*/
 
-/*omit.class: global#LinkedHashMap:deps=[Map]*/
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#LinkedHashMap:deps=[Map]*/
+/*spec:nnbd-off.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 
-/*omit.class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
-/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
+/*spec:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
 
-/*omit.class: global#double:explicit=[double]*/
-/*strong.class: global#double:explicit=[double],implicit=[double]*/
+/*prod:nnbd-off.class: global#double:explicit=[double]*/
+/*spec:nnbd-off.class: global#double:explicit=[double],implicit=[double]*/
 
 /*class: global#JSDouble:*/
 
diff --git a/tests/compiler/dart2js/rti/data/map_to_set.dart b/tests/compiler/dart2js/rti/data/map_to_set.dart
index 127552a..78dff5e 100644
--- a/tests/compiler/dart2js/rti/data/map_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/map_to_set.dart
@@ -4,17 +4,17 @@
 
 // @dart = 2.7
 
-/*omit.class: global#Map:deps=[Class],needsArgs*/
-/*strong.class: global#Map:deps=[Class],explicit=[Map],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#Map:deps=[Class],needsArgs*/
+/*spec:nnbd-off.class: global#Map:deps=[Class],explicit=[Map],indirect,needsArgs*/
 
-/*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#LinkedHashMap:deps=[Map],needsArgs*/
+/*spec:nnbd-off.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 
-/*omit.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
+/*spec:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
 
-/*omit.class: global#double:explicit=[double]*/
-/*strong.class: global#double:explicit=[double],implicit=[double]*/
+/*prod:nnbd-off.class: global#double:explicit=[double]*/
+/*spec:nnbd-off.class: global#double:explicit=[double],implicit=[double]*/
 
 /*class: global#JSDouble:*/
 
@@ -25,8 +25,8 @@
   set is Set<String>;
 }
 
-/*omit.class: Class:needsArgs*/
-/*strong.class: Class:implicit=[Class.S,Class.T],indirect,needsArgs*/
+/*prod:nnbd-off.class: Class:needsArgs*/
+/*spec:nnbd-off.class: Class:implicit=[Class.S,Class.T],indirect,needsArgs*/
 class Class<T, S> {
   m() {
     return <T, S>{};
diff --git a/tests/compiler/dart2js/rti/data/marker.options b/tests/compiler/dart2js/rti/data/marker.options
index b77684b..cef4600 100644
--- a/tests/compiler/dart2js/rti/data/marker.options
+++ b/tests/compiler/dart2js/rti/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/rti/rti_need_test_helper.dart
-omit=tests/compiler/dart2js/rti/rti_need_test_helper.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/rti/rti_need_test_helper.dart
+prod:nnbd-off=tests/compiler/dart2js/rti/rti_need_test_helper.dart
+spec:nnbd-sdk=tests/compiler/dart2js/rti/rti_need_test_helper.dart
+prod:nnbd-sdk=tests/compiler/dart2js/rti/rti_need_test_helper.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/rti/data/method_signatures.dart b/tests/compiler/dart2js/rti/data/method_signatures.dart
index b8332d1..77a96ee 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures.dart
@@ -17,11 +17,11 @@
   Object method3(num n) => null;
 }
 
-/*strong.class: Class2:direct,explicit=[Class2.T],needsArgs*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:direct,explicit=[Class2.T],needsArgs*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.method4:*/
-  /*omit.member: Class2.method4:*/
+  /*spec:nnbd-off.member: Class2.method4:*/
+  /*prod:nnbd-off.member: Class2.method4:*/
   num method4(T n) => null;
 }
 
@@ -31,8 +31,8 @@
   T method5(num n) => null;
 }
 
-/*omit.class: Class4:*/
-/*strong.class: Class4:direct,explicit=[Class4.T],needsArgs*/
+/*prod:nnbd-off.class: Class4:*/
+/*spec:nnbd-off.class: Class4:direct,explicit=[Class4.T],needsArgs*/
 class Class4<T> {
   /*member: Class4.method6:*/
   num method6(num n, T t) => null;
diff --git a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
index eb0efc1..0a7024c 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
@@ -18,8 +18,8 @@
 }
 
 class Class2 {
-  /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
-  /*omit.member: Class2.method4:*/
+  /*spec:nnbd-off.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+  /*prod:nnbd-off.member: Class2.method4:*/
   num method4<T>(T n) => null;
 }
 
@@ -29,20 +29,20 @@
 }
 
 class Class4 {
-  /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
-  /*omit.member: Class4.method6:*/
+  /*spec:nnbd-off.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+  /*prod:nnbd-off.member: Class4.method6:*/
   num method6<T>(num n, T t) => null;
 }
 
-/*strong.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
-/*omit.member: method7:*/
+/*spec:nnbd-off.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+/*prod:nnbd-off.member: method7:*/
 num method7<T>(T n) => null;
 
 /*member: method8:*/
 T method8<T>(num n) => null;
 
-/*strong.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
-/*omit.member: method9:*/
+/*spec:nnbd-off.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+/*prod:nnbd-off.member: method9:*/
 num method9<T>(num n, T t) => null;
 
 @pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
index a42deee..48bbd34 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
@@ -6,16 +6,16 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   /*needsSignature*/
   local1a() {}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
index c44c1f7..77913d6 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
@@ -6,27 +6,27 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
-  /*strong.needsArgs,needsSignature*/
-  /*omit.needsArgs,needsSignature*/
+  /*spec:nnbd-off.needsArgs,needsSignature*/
+  /*prod:nnbd-off.needsArgs,needsSignature*/
   T local1a<T>() => null;
 
-  /*strong.needsArgs,needsSignature*/
-  /*omit.needsArgs,needsSignature*/
+  /*spec:nnbd-off.needsArgs,needsSignature*/
+  /*prod:nnbd-off.needsArgs,needsSignature*/
   T local1b<T>() => null;
 
-  /*strong.direct,explicit=[local2.T],needsArgs,needsSignature*/
-  /*omit.needsArgs,needsSignature*/
+  /*spec:nnbd-off.direct,explicit=[local2.T],needsArgs,needsSignature*/
+  /*prod:nnbd-off.needsArgs,needsSignature*/
   T local2<T>(T t, String s) => t;
 
   Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
index 230f46f..51e8cfc 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
@@ -8,15 +8,15 @@
 
 String method() => null;
 
-/*omit.class: Class1:needsArgs*/
-/*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
+/*prod:nnbd-off.class: Class1:needsArgs*/
+/*spec:nnbd-off.class: Class1:direct,explicit=[Class1.T],needsArgs*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 
-  /*strong.member: Class1.method:*/
-  /*omit.member: Class1.method:*/
+  /*spec:nnbd-off.member: Class1.method:*/
+  /*prod:nnbd-off.member: Class1.method:*/
   method() {
     /*needsSignature*/
     T local1a() => null;
@@ -33,16 +33,16 @@
   }
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   new Class1<int>().method();
   new Class2<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
index 43358cb..549493b 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
@@ -6,40 +6,40 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 
   // TODO(johnniwinther): Currently only methods that use class type variables
   // in their signature are marked as 'needs signature'. Change this to mark
   // all methods that need to support access to their function type at runtime.
 
-  /*strong.member: Class1.method1a:*/
-  /*omit.member: Class1.method1a:*/
+  /*spec:nnbd-off.member: Class1.method1a:*/
+  /*prod:nnbd-off.member: Class1.method1a:*/
   method1a() => null;
 
-  /*strong.member: Class1.method1b:*/
-  /*omit.member: Class1.method1b:*/
+  /*spec:nnbd-off.member: Class1.method1b:*/
+  /*prod:nnbd-off.member: Class1.method1b:*/
   method1b() => null;
 
-  /*strong.member: Class1.method2:*/
-  /*omit.member: Class1.method2:*/
+  /*spec:nnbd-off.member: Class1.method2:*/
+  /*prod:nnbd-off.member: Class1.method2:*/
   method2(t, s) => t;
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   var c = new Class1<int>();
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
index e2cd3bd..2feedd8 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
@@ -6,36 +6,36 @@
 
 import 'package:expect/expect.dart';
 
-/*omit.class: Class1:needsArgs*/
-/*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
+/*prod:nnbd-off.class: Class1:needsArgs*/
+/*spec:nnbd-off.class: Class1:direct,explicit=[Class1.T],needsArgs*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 
-  /*strong.member: Class1.method1a:needsSignature*/
-  /*omit.member: Class1.method1a:needsSignature*/
+  /*spec:nnbd-off.member: Class1.method1a:needsSignature*/
+  /*prod:nnbd-off.member: Class1.method1a:needsSignature*/
   T method1a() => null;
 
-  /*strong.member: Class1.method1b:needsSignature*/
-  /*omit.member: Class1.method1b:needsSignature*/
+  /*spec:nnbd-off.member: Class1.method1b:needsSignature*/
+  /*prod:nnbd-off.member: Class1.method1b:needsSignature*/
   T method1b() => null;
 
-  /*strong.member: Class1.method2:needsSignature*/
-  /*omit.member: Class1.method2:needsSignature*/
+  /*spec:nnbd-off.member: Class1.method2:needsSignature*/
+  /*prod:nnbd-off.member: Class1.method2:needsSignature*/
   T method2(T t, String s) => t;
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   var c = new Class1<int>();
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
index 77593d4..d08a341 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
@@ -6,28 +6,28 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.member: method1a:*/
-/*omit.member: method1a:*/
+/*spec:nnbd-off.member: method1a:*/
+/*prod:nnbd-off.member: method1a:*/
 method1a() => null;
 
-/*strong.member: method1b:*/
-/*omit.member: method1b:*/
+/*spec:nnbd-off.member: method1b:*/
+/*prod:nnbd-off.member: method1b:*/
 method1b() => null;
 
-/*strong.member: method2:*/
-/*omit.member: method2:*/
+/*spec:nnbd-off.member: method2:*/
+/*prod:nnbd-off.member: method2:*/
 method2(t, s) => t;
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
   Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
index 198424c..e43e522 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
@@ -12,20 +12,20 @@
 /*member: method1b:*/
 T method1b<T>() => null;
 
-/*strong.member: method2:direct,explicit=[method2.T],needsArgs*/
-/*omit.member: method2:*/
+/*spec:nnbd-off.member: method2:direct,explicit=[method2.T],needsArgs*/
+/*prod:nnbd-off.member: method2:*/
 T method2<T>(T t, String s) => t;
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
   Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
index 5656b34..ca1408e 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
@@ -6,11 +6,11 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<S> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 
   /*member: Class1.method1a:*/
@@ -19,21 +19,21 @@
   /*member: Class1.method1b:*/
   T method1b<T>() => null;
 
-  /*strong.member: Class1.method2:direct,explicit=[method2.T],needsArgs*/
-  /*omit.member: Class1.method2:*/
+  /*spec:nnbd-off.member: Class1.method2:direct,explicit=[method2.T],needsArgs*/
+  /*prod:nnbd-off.member: Class1.method2:*/
   T method2<T>(T t, String s) => t;
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   var c = new Class1<int>();
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
index cc64617..8622fed 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
@@ -4,23 +4,23 @@
 
 // @dart = 2.7
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
-  /*strong.needsSignature*/
-  /*omit.*/
+  /*spec:nnbd-off.needsSignature*/
+  /*prod:nnbd-off.*/
   local1() {}
 
-  /*strong.needsSignature*/
-  /*omit.*/
+  /*spec:nnbd-off.needsSignature*/
+  /*prod:nnbd-off.*/
   local2(int i, String s) => i;
 
   print('${local1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
index e79d08a..d01980c 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
@@ -4,23 +4,23 @@
 
 // @dart = 2.7
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
-  /*strong.needsArgs,needsSignature*/
-  /*omit.*/
+  /*spec:nnbd-off.needsArgs,needsSignature*/
+  /*prod:nnbd-off.*/
   local1<T>() {}
 
-  /*strong.needsArgs,needsSignature,selectors=[Selector(call, call, arity=2, types=1)]*/
-  /*omit.*/
+  /*spec:nnbd-off.needsArgs,needsSignature,selectors=[Selector(call, call, arity=2, types=1)]*/
+  /*prod:nnbd-off.*/
   local2<T>(t, s) => t;
 
   print('${local1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
index d1d3744..ac6dcf5 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
@@ -4,28 +4,28 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 
-  /*strong.member: Class1.method:needsSignature*/
-  /*omit.member: Class1.method:*/
+  /*spec:nnbd-off.member: Class1.method:needsSignature*/
+  /*prod:nnbd-off.member: Class1.method:*/
   T method() => null;
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print(cls1.method.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
index ef8ea71..25c1942 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
@@ -4,24 +4,24 @@
 
 // @dart = 2.7
 
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
 class Class<T> {
-  /*strong.member: Class.:*/
-  /*omit.member: Class.:*/
+  /*spec:nnbd-off.member: Class.:*/
+  /*prod:nnbd-off.member: Class.:*/
   Class();
 }
 
-/*strong.member: method1:*/
-/*omit.member: method1:*/
+/*spec:nnbd-off.member: method1:*/
+/*prod:nnbd-off.member: method1:*/
 method1() {}
 
-/*strong.member: method2:*/
-/*omit.member: method2:*/
+/*spec:nnbd-off.member: method2:*/
+/*prod:nnbd-off.member: method2:*/
 method2(int i, String s) => i;
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   print('${method1.runtimeType}');
   method2(0, '');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
index cc6dfc5..5f321e0 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
@@ -8,12 +8,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.member: Class1a.:*/
-  /*omit.member: Class1a.:*/
+  /*spec:nnbd-off.member: Class1a.:*/
+  /*prod:nnbd-off.member: Class1a.:*/
   Class1a();
 
-  /*strong.member: Class1a.==:*/
-  /*omit.member: Class1a.==:*/
+  /*spec:nnbd-off.member: Class1a.==:*/
+  /*prod:nnbd-off.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return runtimeType == other.runtimeType;
@@ -22,8 +22,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.member: Class1b.:*/
-  /*omit.member: Class1b.:*/
+  /*spec:nnbd-off.member: Class1b.:*/
+  /*prod:nnbd-off.member: Class1b.:*/
   Class1b();
 }
 
@@ -31,21 +31,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.member: Class1c.:*/
-  /*omit.member: Class1c.:*/
+  /*spec:nnbd-off.member: Class1c.:*/
+  /*prod:nnbd-off.member: Class1c.:*/
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
index 77abea4..9f77e4c 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
@@ -8,12 +8,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.member: Class1a.:*/
-  /*omit.member: Class1a.:*/
+  /*spec:nnbd-off.member: Class1a.:*/
+  /*prod:nnbd-off.member: Class1a.:*/
   Class1a();
 
-  /*strong.member: Class1a.==:*/
-  /*omit.member: Class1a.==:*/
+  /*spec:nnbd-off.member: Class1a.==:*/
+  /*prod:nnbd-off.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return other.runtimeType == runtimeType;
@@ -22,8 +22,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.member: Class1b.:*/
-  /*omit.member: Class1b.:*/
+  /*spec:nnbd-off.member: Class1b.:*/
+  /*prod:nnbd-off.member: Class1b.:*/
   Class1b();
 }
 
@@ -31,21 +31,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.member: Class1c.:*/
-  /*omit.member: Class1c.:*/
+  /*spec:nnbd-off.member: Class1c.:*/
+  /*prod:nnbd-off.member: Class1c.:*/
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
index 5b030ba..ccdccad 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
@@ -8,12 +8,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.member: Class1a.:*/
-  /*omit.member: Class1a.:*/
+  /*spec:nnbd-off.member: Class1a.:*/
+  /*prod:nnbd-off.member: Class1a.:*/
   Class1a();
 
-  /*strong.member: Class1a.==:*/
-  /*omit.member: Class1a.==:*/
+  /*spec:nnbd-off.member: Class1a.==:*/
+  /*prod:nnbd-off.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return runtimeType == other?.runtimeType;
@@ -22,8 +22,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.member: Class1b.:*/
-  /*omit.member: Class1b.:*/
+  /*spec:nnbd-off.member: Class1b.:*/
+  /*prod:nnbd-off.member: Class1b.:*/
   Class1b();
 }
 
@@ -31,21 +31,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.member: Class1c.:*/
-  /*omit.member: Class1c.:*/
+  /*spec:nnbd-off.member: Class1c.:*/
+  /*prod:nnbd-off.member: Class1c.:*/
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
index 9892440..fd1f0dc 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
@@ -8,12 +8,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.member: Class1a.:*/
-  /*omit.member: Class1a.:*/
+  /*spec:nnbd-off.member: Class1a.:*/
+  /*prod:nnbd-off.member: Class1a.:*/
   Class1a();
 
-  /*strong.member: Class1a.==:*/
-  /*omit.member: Class1a.==:*/
+  /*spec:nnbd-off.member: Class1a.==:*/
+  /*prod:nnbd-off.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return other?.runtimeType == runtimeType;
@@ -22,8 +22,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.member: Class1b.:*/
-  /*omit.member: Class1b.:*/
+  /*spec:nnbd-off.member: Class1b.:*/
+  /*prod:nnbd-off.member: Class1b.:*/
   Class1b();
 }
 
@@ -31,21 +31,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.member: Class1c.:*/
-  /*omit.member: Class1c.:*/
+  /*spec:nnbd-off.member: Class1c.:*/
+  /*prod:nnbd-off.member: Class1c.:*/
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
index b7b1d2c..ad20c46 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
@@ -6,37 +6,37 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class1a:explicit=[Class1a]*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a]*/
 class Class1a {
   Class1a();
 }
 
-/*strong.class: Class1b:needsArgs*/
-/*omit.class: Class1b:needsArgs*/
+/*spec:nnbd-off.class: Class1b:needsArgs*/
+/*prod:nnbd-off.class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a {
   Class1b();
 }
 
-/*strong.class: Class1c:needsArgs*/
-/*omit.class: Class1c:needsArgs*/
+/*spec:nnbd-off.class: Class1c:needsArgs*/
+/*prod:nnbd-off.class: Class1c:needsArgs*/
 class Class1c<T> extends Class1a {
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
   Class2();
 }
 
-/*strong.member: test:*/
-/*omit.member: test:*/
+/*spec:nnbd-off.member: test:*/
+/*prod:nnbd-off.member: test:*/
 test(Class1a c, Type type) {
   return c.runtimeType == type;
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Expect.isTrue(test(new Class1a(), Class1a));
   Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
index 8482f3d..2098c62 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
@@ -6,38 +6,38 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class1a:explicit=[Class1a],needsArgs*/
-/*omit.class: Class1a:needsArgs*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a],needsArgs*/
+/*prod:nnbd-off.class: Class1a:needsArgs*/
 class Class1a<T> {
   Class1a();
 }
 
-/*strong.class: Class1b:needsArgs*/
-/*omit.class: Class1b:needsArgs*/
+/*spec:nnbd-off.class: Class1b:needsArgs*/
+/*prod:nnbd-off.class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
   Class1b();
 }
 
-/*strong.class: Class1c:needsArgs*/
-/*omit.class: Class1c:needsArgs*/
+/*spec:nnbd-off.class: Class1c:needsArgs*/
+/*prod:nnbd-off.class: Class1c:needsArgs*/
 class Class1c<T> extends Class1a<T> {
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
   Class2();
 }
 
-/*strong.member: test:*/
-/*omit.member: test:*/
+/*spec:nnbd-off.member: test:*/
+/*prod:nnbd-off.member: test:*/
 test(Class1a c, Type type) {
   return c.runtimeType == type;
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Expect.isTrue(test(new Class1a(), Class1a));
   Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
index 980f832..9d448cd 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
@@ -6,45 +6,45 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: Class1a:explicit=[Class1a]*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a]*/
 class Class1a {
   Class1a();
 }
 
-/*strong.class: Class1b:needsArgs*/
-/*omit.class: Class1b:needsArgs*/
+/*spec:nnbd-off.class: Class1b:needsArgs*/
+/*prod:nnbd-off.class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a {
   Class1b();
 }
 
-/*strong.class: Class1c:needsArgs*/
-/*omit.class: Class1c:needsArgs*/
+/*spec:nnbd-off.class: Class1c:needsArgs*/
+/*prod:nnbd-off.class: Class1c:needsArgs*/
 class Class1c<T> extends Class1a {
   Class1c();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
   Class2();
 }
 
-/*strong.class: Class3:explicit=[Class3]*/
-/*omit.class: Class3:*/
+/*spec:nnbd-off.class: Class3:explicit=[Class3]*/
+/*prod:nnbd-off.class: Class3:*/
 class Class3<T> {
   final Class1a field;
 
   Class3(this.field);
 }
 
-/*strong.member: test:*/
-/*omit.member: test:*/
+/*spec:nnbd-off.member: test:*/
+/*prod:nnbd-off.member: test:*/
 test(Class3 c, Type type) {
   return c.field.runtimeType == type;
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Expect.isTrue(test(new Class3<int>(new Class1a()), Class1a));
   Expect.isFalse(test(new Class3<int>(new Class1b<int>()), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
index 36de144..a5a2214 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
@@ -7,7 +7,7 @@
 /*member: global#instantiate1:needsArgs*/
 
 main() {
-  /*strong.direct,explicit=[id.T],needsArgs,needsInst=[<int>],needsSignature*/
+  /*spec:nnbd-off.direct,explicit=[id.T],needsArgs,needsInst=[<int>],needsSignature*/
   T id<T>(T t, String s) => t;
   int Function(int, String s) x = id;
   print("${x.runtimeType}");
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
index 2b1fc09..d5c35e2 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
@@ -6,7 +6,7 @@
 
 /*member: global#instantiate1:needsArgs*/
 
-/*strong.member: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+/*spec:nnbd-off.member: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
 T id<T>(T t, String s) => t;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
index 0060b4c..49733ad 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
@@ -7,7 +7,7 @@
 /*member: global#instantiate1:needsArgs*/
 
 class Class {
-  /*strong.member: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+  /*spec:nnbd-off.member: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
   T id<T>(T t, String s) => t;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
index 33499d6..a414f91 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
@@ -4,32 +4,32 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1 {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.class: Class3:needsArgs*/
-/*omit.class: Class3:*/
+/*spec:nnbd-off.class: Class3:needsArgs*/
+/*prod:nnbd-off.class: Class3:*/
 class Class3<T> implements Class1 {
-  /*strong.member: Class3.:*/
-  /*omit.member: Class3.:*/
+  /*spec:nnbd-off.member: Class3.:*/
+  /*prod:nnbd-off.member: Class3.:*/
   Class3();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1 cls1 = new Class1();
   print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
index b2f2adb..97d71504 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
@@ -4,24 +4,24 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
index 2fa2623..c13a88b 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
@@ -4,24 +4,24 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print(cls1.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
index 75ce88e..d8418e1 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
@@ -4,24 +4,24 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print(cls1?.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
index 520fbb6..56a3c53 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
@@ -4,24 +4,24 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print('${cls1?.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
index 8272616..b9a04c6 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
@@ -4,24 +4,24 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1<T> {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:needsArgs*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:needsArgs*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   dynamic cls1 = new Class1<int>();
   print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
index 33499d6..a414f91 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
@@ -4,32 +4,32 @@
 
 // @dart = 2.7
 
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
 class Class1 {
-  /*strong.member: Class1.:*/
-  /*omit.member: Class1.:*/
+  /*spec:nnbd-off.member: Class1.:*/
+  /*prod:nnbd-off.member: Class1.:*/
   Class1();
 }
 
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
 class Class2<T> {
-  /*strong.member: Class2.:*/
-  /*omit.member: Class2.:*/
+  /*spec:nnbd-off.member: Class2.:*/
+  /*prod:nnbd-off.member: Class2.:*/
   Class2();
 }
 
-/*strong.class: Class3:needsArgs*/
-/*omit.class: Class3:*/
+/*spec:nnbd-off.class: Class3:needsArgs*/
+/*prod:nnbd-off.class: Class3:*/
 class Class3<T> implements Class1 {
-  /*strong.member: Class3.:*/
-  /*omit.member: Class3.:*/
+  /*spec:nnbd-off.member: Class3.:*/
+  /*prod:nnbd-off.member: Class3.:*/
   Class3();
 }
 
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
 main() {
   Class1 cls1 = new Class1();
   print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args.dart b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
index 905ab05..bd72027 100644
--- a/tests/compiler/dart2js/rti/data/subtype_named_args.dart
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
@@ -8,7 +8,7 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: A:
+/*spec:nnbd-off.class: A:
  explicit=[
   A,G<A,A1,A1,A1>,
   dynamic Function({a:A,b:A1,c:A1,d:A1}),
@@ -20,7 +20,7 @@
   dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),
   dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
 */
-/*omit.class: A:
+/*prod:nnbd-off.class: A:
  explicit=[
   dynamic Function({a:A,b:B,c:C,d:D}),
   dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -28,13 +28,13 @@
 */
 class A {}
 
-/*strong.class: A1:explicit=[A1,G<A,A1,A1,A1>,List<List<A1>>,dynamic Function({a:A,b:A1,c:A1,d:A1}),dynamic Function({g:G<A,A1,A1,A1>,l:List<List<A1>>,m:Map<num,num>})]*/
+/*spec:nnbd-off.class: A1:explicit=[A1,G<A,A1,A1,A1>,List<List<A1>>,dynamic Function({a:A,b:A1,c:A1,d:A1}),dynamic Function({g:G<A,A1,A1,A1>,l:List<List<A1>>,m:Map<num,num>})]*/
 class A1 {}
 
-/*strong.class: A2:explicit=[A2]*/
+/*spec:nnbd-off.class: A2:explicit=[A2]*/
 class A2 {}
 
-/*strong.class: B:
+/*spec:nnbd-off.class: B:
  explicit=[
   B,
   dynamic Function({a:A,b:B,c:C,d:D}),
@@ -44,7 +44,7 @@
   dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),
   dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
 */
-/*omit.class: B:
+/*prod:nnbd-off.class: B:
  explicit=[
   dynamic Function({a:A,b:B,c:C,d:D}),
   dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -52,7 +52,7 @@
 */
 class B implements A, A1, A2 {}
 
-/*strong.class: C:
+/*spec:nnbd-off.class: C:
  explicit=[
   C,
   dynamic Function({a:A,b:B,c:C,d:D}),
@@ -61,7 +61,7 @@
   dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),
   dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
 */
-/*omit.class: C:
+/*prod:nnbd-off.class: C:
  explicit=[
   dynamic Function({a:A,b:B,c:C,d:D}),
   dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -69,7 +69,7 @@
 */
 class C implements B {}
 
-/*strong.class: D:
+/*spec:nnbd-off.class: D:
  explicit=[
   D,G<D,D,D,D>,List<List<D>>,
   dynamic Function({a:A,b:B,c:C,d:D}),
@@ -78,7 +78,7 @@
   dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),dynamic Function({g:G<D,D,D,D>,l:List<List<D>>,m:Map<int,int>}),
   dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
 */
-/*omit.class: D:
+/*prod:nnbd-off.class: D:
  explicit=[
   dynamic Function({a:A,b:B,c:C,d:D}),
   dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -86,7 +86,7 @@
 */
 class D implements C {}
 
-/*strong.class: G:
+/*spec:nnbd-off.class: G:
  explicit=[
   G,G<A,A1,A1,A1>,G<D,D,D,D>,
   dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic}),
@@ -97,7 +97,7 @@
   dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})],
  needsArgs
 */
-/*omit.class: G:
+/*prod:nnbd-off.class: G:
  explicit=[
   dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
   dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]
@@ -123,19 +123,19 @@
 
 main() {
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({D a, B b, C c, A d}) {} is classesFunc);
   Expect.isTrue(
       /*needsSignature*/
       ({A a, A b, A c, A d}) {} is classesFunc);
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({D a, A1 b, A1 c, A1 d}) {} is classesFunc);
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({D a, A2 b, A2 c, A2 d}) {} is classesFunc);
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({D a, D b, D c, D d}) {} is classesFunc);
   Expect.isTrue(
       /*needsSignature*/
@@ -149,7 +149,7 @@
       ({Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g}) {}
           is genericsFunc);
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({Map<int, int> m, List<List<D>> l, G<D, D, D, D> g}) {} is genericsFunc);
   Expect.isTrue(
       /*needsSignature*/
@@ -159,10 +159,10 @@
       ({Object m, Object l, Object g}) {} is genericsFunc);
 
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({A x, G y, mixFunc z, var v}) {} is dynamicFunc);
   Expect.isTrue(
-      /*strong.needsSignature*/
+      /*spec:nnbd-off.needsSignature*/
       ({int x, bool y, List<Map> z, classesFunc v}) {} is dynamicFunc);
 
   Expect.isTrue((
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args1.dart b/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
index dc140e4..08e4684 100644
--- a/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
@@ -8,18 +8,18 @@
 
 import "package:expect/expect.dart";
 
-/*strong.class: A:explicit=[A,dynamic Function({a:A})]*/
+/*spec:nnbd-off.class: A:explicit=[A,dynamic Function({a:A})]*/
 class A {}
 
-/*strong.class: B:explicit=[B,dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
-/*omit.class: B:explicit=[dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
+/*spec:nnbd-off.class: B:explicit=[B,dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
+/*prod:nnbd-off.class: B:explicit=[dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
 class B implements A {}
 
-/*strong.class: C:explicit=[C,dynamic Function({a:C}),dynamic Function({c:C})]*/
-/*omit.class: C:explicit=[dynamic Function({c:C})]*/
+/*spec:nnbd-off.class: C:explicit=[C,dynamic Function({a:C}),dynamic Function({c:C})]*/
+/*prod:nnbd-off.class: C:explicit=[dynamic Function({c:C})]*/
 class C implements B {}
 
-/*strong.class: D:explicit=[D,dynamic Function({a:D})]*/
+/*spec:nnbd-off.class: D:explicit=[D,dynamic Function({a:D})]*/
 class D implements C {}
 
 typedef t1({B a});
@@ -39,8 +39,8 @@
 main() {
   Expect.isTrue(/*needsSignature*/ ({A a}) {} is t1);
   Expect.isTrue(/*needsSignature*/ ({B a}) {} is t1);
-  Expect.isTrue(/*strong.needsSignature*/ ({C a}) {} is t1);
-  Expect.isTrue(/*strong.needsSignature*/ ({D a}) {} is t1);
+  Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({C a}) {} is t1);
+  Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({D a}) {} is t1);
   Expect.isTrue(/*needsSignature*/ ({Object a}) {} is t1);
   Expect.isTrue(/*needsSignature*/ ({var a}) {} is t1);
 
@@ -90,8 +90,8 @@
 
   Expect.isTrue(/*needsSignature*/ ({A a}) {} is t8);
   Expect.isTrue(/*needsSignature*/ ({B a}) {} is t8);
-  Expect.isTrue(/*strong.needsSignature*/ ({C a}) {} is t8);
-  Expect.isTrue(/*strong.needsSignature*/ ({D a}) {} is t8);
+  Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({C a}) {} is t8);
+  Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({D a}) {} is t8);
   Expect.isTrue(/*needsSignature*/ ({Object a}) {} is t8);
   Expect.isTrue(/*needsSignature*/ ({var a}) {} is t8);
   Expect.isTrue(({num a}) {} is t8);
diff --git a/tests/compiler/dart2js/rti/data/tear_off_generic.dart b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
index fea635a..727f8be 100644
--- a/tests/compiler/dart2js/rti/data/tear_off_generic.dart
+++ b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
@@ -4,11 +4,11 @@
 
 // @dart = 2.7
 
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
-/*omit.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
 class A<T> {
-  /*strong.member: A.m:*/
-  /*omit.member: A.m:*/
+  /*spec:nnbd-off.member: A.m:*/
+  /*prod:nnbd-off.member: A.m:*/
   void m(T t) {}
 
   /*member: A.f:*/
diff --git a/tests/compiler/dart2js/rti/emission/closure_function.dart b/tests/compiler/dart2js/rti/emission/closure_function.dart
index d478691..8e032bf 100644
--- a/tests/compiler/dart2js/rti/emission/closure_function.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_function.dart
@@ -10,8 +10,7 @@
 main() {
   test(
 
-      /*strong.checks=[],instance*/
-      /*omit.checks=[],instance*/
+      /*checks=[],instance*/
       () {});
   test(null);
 }
diff --git a/tests/compiler/dart2js/rti/emission/closure_function_type.dart b/tests/compiler/dart2js/rti/emission/closure_function_type.dart
index 6436a12..b40047e 100644
--- a/tests/compiler/dart2js/rti/emission/closure_function_type.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_function_type.dart
@@ -11,7 +11,6 @@
   test(/*checks=[$signature],instance*/ () {});
   test(
 
-      /*strong.checks=[],instance*/
-      /*omit.checks=[],instance*/
+      /*checks=[],instance*/
       (a) {});
 }
diff --git a/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart b/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
index 28e2660..15549d7 100644
--- a/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
@@ -12,8 +12,7 @@
     // potential subtype of the checked function types.
     return
 
-        /*strong.checks=[],instance*/
-        /*omit.checks=[],instance*/
+        /*checks=[],instance*/
         (T t, String s) {};
   }
 }
diff --git a/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart b/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart
index 097a0ce9..280e65d 100644
--- a/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart
+++ b/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart
@@ -4,14 +4,14 @@
 
 // @dart = 2.7
 
-/*strong.class: A1:checkedInstance,checks=[],instance*/
-/*omit.class: A1:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A1:checkedInstance,checks=[],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A1:checks=[],instance*/
 class A1 {}
 
 // Constructor calls are always statically invoked, so there is no checks at the
 // entry and the `Test1` constructor does not cause any checks.
-/*strong.class: B1:checks=[$isA1],instance*/
-/*omit.class: B1:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B1:checks=[$isA1],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B1:checks=[],instance*/
 class B1 implements A1 {}
 
 /*class: Test1:checks=[],instance*/
diff --git a/tests/compiler/dart2js/rti/emission/event_callback.dart b/tests/compiler/dart2js/rti/emission/event_callback.dart
index 288d1da..7402b76 100644
--- a/tests/compiler/dart2js/rti/emission/event_callback.dart
+++ b/tests/compiler/dart2js/rti/emission/event_callback.dart
@@ -6,8 +6,8 @@
 
 import 'dart:html';
 
-/*strong.class: global#Event:checkedInstance,checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
-/*omit.class: global#Event:checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
+/*spec:nnbd-off.class: global#Event:checkedInstance,checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
+/*prod:nnbd-off.class: global#Event:checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
 /*class: global#MouseEvent:checks=[$isMouseEvent],instance,typeArgument*/
 /*class: global#KeyboardEvent:checks=[$isKeyboardEvent],instance,typeArgument*/
 
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
index e636027..8e9d63f 100644
--- a/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
@@ -4,12 +4,12 @@
 
 // @dart = 2.7
 
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
 class A {}
 
-/*strong.class: B:checkedInstance,checks=[$isA],typeArgument*/
-/*omit.class: B:checks=[$isA],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checkedInstance,checks=[$isA],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[$isA],typeArgument*/
 class B implements A {}
 
 /*class: C:checks=[],indirectInstance*/
@@ -24,7 +24,7 @@
 main() {
   C<A> c = new D();
   c.method(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       (A a) {});
 }
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
index b5bdbee..9a9331c 100644
--- a/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
+++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
@@ -7,19 +7,19 @@
 // Test that we emit the relation between B and A even when B is only live
 // as a type argument through the supertype of D.
 
-/*strong.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
 class A {}
 
-/*strong.class: B:checks=[$isA],typeArgument*/
-/*omit.class: B:checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checks=[$isA],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[],typeArgument*/
 class B implements A {}
 
-/*strong.class: C:checkedInstance*/
-/*omit.class: C:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: C:checkedInstance*/
+/*prod:nnbd-off.class: C:*/
 class C<T> {}
 
-/*strong.class: D:checks=[$isC],instance*/
-/*omit.class: D:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: D:checks=[$isC],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: D:checks=[],instance*/
 class D implements C<B> {}
 
 main() {
diff --git a/tests/compiler/dart2js/rti/emission/function_type_argument.dart b/tests/compiler/dart2js/rti/emission/function_type_argument.dart
index f674415..cf4fdc3 100644
--- a/tests/compiler/dart2js/rti/emission/function_type_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/function_type_argument.dart
@@ -6,14 +6,14 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: C:checkedInstance,checks=[],instance,typeArgument*/
-/*omit.class: C:checks=[],instance,typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: C:checkedInstance,checks=[],instance,typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: C:checks=[],instance,typeArgument*/
 class C {
   call(int i) {}
 }
 
-/*strong.class: D:checkedInstance,checks=[],instance,typeArgument*/
-/*omit.class: D:checks=[],instance,typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: D:checkedInstance,checks=[],instance,typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: D:checks=[],instance,typeArgument*/
 class D {
   call(double i) {}
 }
diff --git a/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart b/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart
index 0241ff4..5c4b796 100644
--- a/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart
+++ b/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart
@@ -8,12 +8,12 @@
 
 library generic_methods_dynamic_test;
 
-/*strong.class: A:checkedInstance,checks=[],typeArgument*/
-/*omit.class: A:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checks=[],typeArgument*/
+/*prod:nnbd-off.class: A:*/
 class A {}
 
-/*strong.class: B:checks=[],instance*/
-/*omit.class: B:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checks=[],instance*/
+/*prod:nnbd-off.class: B:*/
 class B {}
 
 /*class: C:*/
diff --git a/tests/compiler/dart2js/rti/emission/indirect_through_static.dart b/tests/compiler/dart2js/rti/emission/indirect_through_static.dart
index 5a70d24..8246072 100644
--- a/tests/compiler/dart2js/rti/emission/indirect_through_static.dart
+++ b/tests/compiler/dart2js/rti/emission/indirect_through_static.dart
@@ -4,16 +4,13 @@
 
 // @dart = 2.7
 
-/*strong.class: A:checkedInstance,checks=[],typeArgument*/
-/*omit.class: A:checkedInstance,checks=[],typeArgument*/
+/*class: A:checkedInstance,checks=[],typeArgument*/
 abstract class A {}
 
-/*strong.class: B:checks=[$isA],typeArgument*/
-/*omit.class: B:checks=[$isA],typeArgument*/
+/*class: B:checks=[$isA],typeArgument*/
 class B implements A {}
 
-/*strong.class: C:checkedInstance,checks=[],instance,typeArgument*/
-/*omit.class: C:checkedInstance,checks=[],instance,typeArgument*/
+/*class: C:checkedInstance,checks=[],instance,typeArgument*/
 class C<T> {}
 
 final Map<String, C> map = {};
diff --git a/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart b/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart
index 65a16f8..b86d758 100644
--- a/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart
+++ b/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart
@@ -14,8 +14,8 @@
 import 'package:expect/expect.dart';
 import 'package:js/js.dart';
 
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
 @JS()
 @anonymous
 class A<T> {
diff --git a/tests/compiler/dart2js/rti/emission/list.dart b/tests/compiler/dart2js/rti/emission/list.dart
index 6efdf08..ee93c8d 100644
--- a/tests/compiler/dart2js/rti/emission/list.dart
+++ b/tests/compiler/dart2js/rti/emission/list.dart
@@ -4,17 +4,17 @@
 
 // @dart = 2.7
 
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
-/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
-/*omit.class: global#JSArray:checks=[$isIterable],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
+/*prod:nnbd-off.class: global#JSArray:checks=[$isIterable],instance*/
 
 /*class: global#Iterable:checkedInstance*/
 
 class A {}
 
-/*strong.class: B:checkedInstance,checks=[],typeArgument*/
-/*omit.class: B:checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checkedInstance,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[],typeArgument*/
 class B {}
 
 @pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart b/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart
index 7573410..115a5d1 100644
--- a/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart
@@ -6,8 +6,8 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
-/*omit.class: global#JSArray:checks=[$isList],instance*/
+/*spec:nnbd-off.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
+/*prod:nnbd-off.class: global#JSArray:checks=[$isList],instance*/
 
 @pragma('dart2js:noInline')
 method<T>() {
diff --git a/tests/compiler/dart2js/rti/emission/map_literal.dart b/tests/compiler/dart2js/rti/emission/map_literal.dart
index 273331d..e424e80 100644
--- a/tests/compiler/dart2js/rti/emission/map_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/map_literal.dart
@@ -4,12 +4,12 @@
 
 // @dart = 2.7
 
-/*strong.class: global#Map:instance*/
+/*spec:nnbd-off.class: global#Map:instance*/
 
 /*class: global#LinkedHashMap:*/
 /*class: global#JsLinkedHashMap:checks=[],instance*/
 
-/*strong.class: global#double:checkedInstance,checks=[],instance,typeArgument*/
+/*spec:nnbd-off.class: global#double:checkedInstance,checks=[],instance,typeArgument*/
 
 /*class: global#JSDouble:checks=[],instance*/
 
diff --git a/tests/compiler/dart2js/rti/emission/marker.options b/tests/compiler/dart2js/rti/emission/marker.options
index bc69057..a072260 100644
--- a/tests/compiler/dart2js/rti/emission/marker.options
+++ b/tests/compiler/dart2js/rti/emission/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/rti/rti_emission_test.dart
-omit=tests/compiler/dart2js/rti/rti_emission_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/rti/rti_emission_test.dart
+prod:nnbd-off=tests/compiler/dart2js/rti/rti_emission_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/rti/rti_emission_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/rti/rti_emission_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart b/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart
index 36f671d..9809bbc 100644
--- a/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart
+++ b/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart
@@ -28,12 +28,12 @@
 // inserts an implicit cast at the call-site or we disregard the forced check
 // because it is a static call.
 
-/*strong.class: Class1a:checkedInstance*/
-/*omit.class: Class1a:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class1a:checkedInstance*/
+/*prod:nnbd-off.class: Class1a:*/
 class Class1a {}
 
-/*strong.class: Class1b:checkedInstance*/
-/*omit.class: Class1b:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class1b:checkedInstance*/
+/*prod:nnbd-off.class: Class1b:*/
 class Class1b {}
 
 // Checks are needed both with and without --omit-implicit-checks.
@@ -52,12 +52,12 @@
 /*class: Class3b:*/
 class Class3b {}
 
-/*strong.class: Class4a:checkedInstance*/
-/*omit.class: Class4a:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class4a:checkedInstance*/
+/*prod:nnbd-off.class: Class4a:*/
 class Class4a<T> {}
 
-/*strong.class: Class4b:checkedInstance*/
-/*omit.class: Class4b:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class4b:checkedInstance*/
+/*prod:nnbd-off.class: Class4b:*/
 class Class4b<T> {}
 
 // Checks are needed both with and without --omit-implicit-checks.
diff --git a/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart b/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart
index 668a859..bddb58e 100644
--- a/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart
+++ b/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart
@@ -5,8 +5,8 @@
 // @dart = 2.7
 
 main() {
-  /*strong.checks=[$signature],instance*/
-  /*omit.checks=[],instance*/
+  /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+  /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
   T id<T>(T t) => t;
   int Function(int) x = id;
   print("${x.runtimeType}");
diff --git a/tests/compiler/dart2js/rti/emission/static_argument.dart b/tests/compiler/dart2js/rti/emission/static_argument.dart
index 4230400..3730ece 100644
--- a/tests/compiler/dart2js/rti/emission/static_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/static_argument.dart
@@ -4,19 +4,18 @@
 
 // @dart = 2.7
 
-/*strong.class: I1:*/
-/*omit.class: I1:*/
+/*spec:nnbd-off|prod:nnbd-off.class: I1:*/
 class I1 {}
 
-/*strong.class: I2:checkedInstance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: I2:checkedInstance*/
 class I2 {}
 
-/*strong.class: A:checks=[$isI2],instance*/
-/*omit.class: A:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checks=[$isI2],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checks=[],instance*/
 class A implements I1, I2 {}
 
-/*strong.class: B:checks=[$isI2],instance*/
-/*omit.class: B:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checks=[$isI2],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[],instance*/
 class B implements I1, I2 {}
 
 @pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/emission/subtype_named_args.dart b/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
index def20ab..9478512 100644
--- a/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
+++ b/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
@@ -8,32 +8,32 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
 class A {}
 
-/*strong.class: A1:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A1:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A1:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A1:checkedTypeArgument,checks=[],typeArgument*/
 class A1 {}
 
-/*strong.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A2:checkedTypeArgument,checks=[],typeArgument*/
 class A2 {}
 
-/*strong.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
-/*omit.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
 class B implements A, A1, A2 {}
 
-/*strong.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
-/*omit.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
 class C implements B {}
 
-/*strong.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
-/*omit.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
 class D implements C {}
 
-/*strong.class: G:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: G:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: G:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: G:checkedTypeArgument,checks=[],typeArgument*/
 class G<T, S, U, W> {}
 
 typedef classesFunc({A a, B b, C c, D d});
@@ -55,23 +55,23 @@
 
 main() {
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({D a, B b, C c, A d}) {} is classesFunc);
   Expect.isTrue(
       /*checks=[$signature],instance*/
       ({A a, A b, A c, A d}) {} is classesFunc);
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({D a, A1 b, A1 c, A1 d}) {} is classesFunc);
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({D a, A2 b, A2 c, A2 d}) {} is classesFunc);
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({D a, D b, D c, D d}) {} is classesFunc);
   Expect.isTrue(
       /*checks=[$signature],instance*/
@@ -83,8 +83,8 @@
       ({Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g}) {}
           is genericsFunc);
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({Map<int, int> m, List<List<D>> l, G<D, D, D, D> g}) {} is genericsFunc);
   Expect.isTrue(
       /*checks=[$signature],instance*/
@@ -94,12 +94,12 @@
       ({Object m, Object l, Object g}) {} is genericsFunc);
 
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({A x, G y, mixFunc z, var v}) {} is dynamicFunc);
   Expect.isTrue(
-      /*strong.checks=[$signature],instance*/
-      /*omit.checks=[],instance*/
+      /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+      /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
       ({int x, bool y, List<Map> z, classesFunc v}) {} is dynamicFunc);
 
   Expect.isTrue(
diff --git a/tests/compiler/dart2js/rti/emission/tear_off_types.dart b/tests/compiler/dart2js/rti/emission/tear_off_types.dart
index 4381d93..7bf619c 100644
--- a/tests/compiler/dart2js/rti/emission/tear_off_types.dart
+++ b/tests/compiler/dart2js/rti/emission/tear_off_types.dart
@@ -36,12 +36,12 @@
 @pragma('dart2js:noInline')
 bool _test1(f) => f is A1<int> Function();
 
-/*strong.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A2:checkedTypeArgument,checks=[],typeArgument*/
 class A2<T> {}
 
-/*strong.class: B2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: B2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B2:checkedTypeArgument,checks=[],typeArgument*/
 class B2 extends A2<int> {}
 
 @pragma('dart2js:noInline')
@@ -58,12 +58,12 @@
 @pragma('dart2js:noInline')
 bool _test2(f) => f is void Function(A2<int>);
 
-/*strong.class: A3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A3:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A3:checkedTypeArgument,checks=[],typeArgument*/
 class A3<T> {}
 
-/*strong.class: B3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: B3:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B3:checkedTypeArgument,checks=[],typeArgument*/
 class B3 extends A3<int> {}
 
 @pragma('dart3js:noInline')
diff --git a/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart b/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart
index 0c93e47..7fea711 100644
--- a/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart
@@ -14,6 +14,8 @@
 
 import 'helpers/source_map_validator_helper.dart';
 
+import '../helpers/memory_compiler.dart';
+
 void main() {
   String mainFile =
       'tests/compiler/dart2js/sourcemaps/test_files/validator_test_file.dart';
@@ -22,7 +24,8 @@
         Future<CompilationResult> result = entry.internalMain([
           mainFile,
           '-o${tmpDir.path}/out.js',
-          '--libraries-spec=sdk/lib/libraries.json',
+          '--platform-binaries=$sdkPlatformBinariesPath',
+          '--libraries-spec=$sdkLibrariesSpecificationPath',
         ]);
         return result.then((CompilationResult result) {
           CompilerImpl compiler = result.compiler;
diff --git a/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart b/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart
index 3da203d..4b9229e 100644
--- a/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart
@@ -13,6 +13,8 @@
 
 import 'helpers/source_map_validator_helper.dart';
 
+import '../helpers/memory_compiler.dart';
+
 void main() {
   asyncTest(() => createTempDir().then((Directory tmpDir) {
         String file = 'tests/compiler/dart2js/sourcemaps/test_files/'
@@ -21,7 +23,8 @@
         var result = entry.internalMain([
           file,
           '-o${tmpDir.path}/out.js',
-          '--libraries-spec=sdk/lib/libraries.json',
+          '--platform-binaries=$sdkPlatformBinariesPath',
+          '--libraries-spec=$sdkLibrariesSpecificationPath',
         ]);
         return result.then((CompilationResult result) {
           CompilerImpl compiler = result.compiler;
diff --git a/tests/compiler/dart2js/sourcemaps/load_save_test.dart b/tests/compiler/dart2js/sourcemaps/load_save_test.dart
index 3355040..65fda6a 100644
--- a/tests/compiler/dart2js/sourcemaps/load_save_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/load_save_test.dart
@@ -9,13 +9,15 @@
 import 'package:source_maps/source_maps.dart';
 import 'tools/load.dart';
 import 'tools/save.dart';
+import '../helpers/memory_compiler.dart';
 
-const String SOURCEMAP = '''
+String SOURCEMAP = '''
 {
   "version": 3,
   "file": "out.js",
   "sourceRoot": "",
-  "sources": ["sdk/lib/_internal/compiler/js_lib/js_primitives.dart","hello_world.dart","sdk/lib/_internal/compiler/js_lib/internal_patch.dart"],
+  "sources":
+      ["$sdkPath/_internal/compiler/js_lib/js_primitives.dart","hello_world.dart","$sdkPath/_internal/compiler/js_lib/internal_patch.dart"],
   "names": ["printString","main","printToConsole"],
   "mappings": "A;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;eAoBAA;;;AAIIA;;;;AAOAA;;;AAKAA;;;AAMAA;;;GAOJA;;sC;;QC5CAC;;ICYEC;GDRFD;;;;A;A;A;;;A;;;A;A;A;A;A;A;A;;;;;;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;C;;;;;;;;;;;;;;;;;;;;;;;;;;;;A"
 }''';
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
index 6006fb4..6785cc0 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
@@ -15,6 +15,8 @@
 
 import 'package:sourcemap_testing/src/stacktrace_helper.dart';
 
+import '../helpers/memory_compiler.dart';
+
 void main(List<String> args) {
   ArgParser argParser = new ArgParser(allowTrailingOptions: true);
   argParser.addFlag('write-js', defaultsTo: false);
@@ -84,7 +86,8 @@
   return testStackTrace(test, config, (String input, String output) async {
     List<String> arguments = [
       '-o$output',
-      '--libraries-spec=sdk/lib/libraries.json',
+      '--platform-binaries=$sdkPlatformBinariesPath',
+      '--libraries-spec=$sdkLibrariesSpecificationPath',
       '--packages=${Platform.packageConfig}',
       Flags.testMode,
       '--enable-experiment=extension-methods',
@@ -95,7 +98,7 @@
     return compilationResult.isSuccess;
   },
       jsPreambles: (input, output) =>
-          ['sdk/lib/_internal/js_runtime/lib/preambles/d8.js'],
+          ['$sdkPath/_internal/js_runtime/lib/preambles/d8.js'],
       afterExceptions: testAfterExceptions,
       beforeExceptions: beforeExceptions,
       verbose: verbose,
diff --git a/tests/compiler/dart2js/sourcemaps/stepping_test.dart b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
index 311d462..f5911da 100644
--- a/tests/compiler/dart2js/sourcemaps/stepping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
@@ -16,6 +16,8 @@
 import 'package:expect/expect.dart';
 import 'package:sourcemap_testing/src/stepping_helper.dart';
 
+import '../helpers/memory_compiler.dart';
+
 void main(List<String> args) {
   ArgParser argParser = new ArgParser(allowTrailingOptions: true);
   argParser.addFlag('debug', abbr: 'd', defaultsTo: false);
@@ -77,7 +79,7 @@
   CompilationResult compilationResult = await entry.internalMain(arguments);
   Expect.isTrue(compilationResult.isSuccess);
   List<String> scriptD8Command = [
-    'sdk/lib/_internal/js_runtime/lib/preambles/d8.js',
+    '$sdkPath/_internal/js_runtime/lib/preambles/d8.js',
     outputFile
   ];
   ProcessResult result = runD8AndStep(dir.path, annotatedCode, scriptD8Command);
diff --git a/tests/compiler/dart2js/static_type/data/marker.options b/tests/compiler/dart2js/static_type/data/marker.options
index 95c2117..12bfcee 100644
--- a/tests/compiler/dart2js/static_type/data/marker.options
+++ b/tests/compiler/dart2js/static_type/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/static_type/static_type_test.dart
-omit=tests/compiler/dart2js/static_type/static_type_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/static_type/static_type_test.dart
+prod:nnbd-off=tests/compiler/dart2js/static_type/static_type_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/static_type/static_type_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/static_type/static_type_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/static_type/static_type_test.dart b/tests/compiler/dart2js/static_type/static_type_test.dart
index 250f450..a2c679e 100644
--- a/tests/compiler/dart2js/static_type/static_type_test.dart
+++ b/tests/compiler/dart2js/static_type/static_type_test.dart
@@ -27,7 +27,7 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, new StaticTypeDataComputer(),
-        args: args, testedConfigs: [strongConfig]);
+        args: args, testedConfigs: allSpecConfigs);
   });
 }
 
diff --git a/tests/compiler/dart2js/static_type/type_promotion_data/marker.options b/tests/compiler/dart2js/static_type/type_promotion_data/marker.options
index c280594..d745ddd 100644
--- a/tests/compiler/dart2js/static_type/type_promotion_data/marker.options
+++ b/tests/compiler/dart2js/static_type/type_promotion_data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/static_type/type_promotion_test.dart
-omit=tests/compiler/dart2js/static_type/type_promotion_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/static_type/type_promotion_test.dart
+prod:nnbd-off=tests/compiler/dart2js/static_type/type_promotion_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/static_type/type_promotion_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/static_type/type_promotion_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/constant_folding2_test.dart b/tests/compiler/dart2js_extra/constant_folding2_test.dart
new file mode 100644
index 0000000..b8fbee4
--- /dev/null
+++ b/tests/compiler/dart2js_extra/constant_folding2_test.dart
@@ -0,0 +1,66 @@
+// 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:expect/expect.dart';
+
+get b => 499;
+@pragma('dart2js:noInline')
+get b_noInline => b;
+const b0 = 499 is FutureOr<int>;
+final b1 = 499 is FutureOr<int>;
+get b2 => 499 is FutureOr<int>;
+get b3 => b is FutureOr<int>;
+get b4 => b_noInline is FutureOr<int>;
+
+get c => 499;
+@pragma('dart2js:noInline')
+get c_noInline => c;
+const c0 = 499 is FutureOr<FutureOr<int>>;
+final c1 = 499 is FutureOr<FutureOr<int>>;
+get c2 => 499 is FutureOr<FutureOr<int>>;
+get c3 => c is FutureOr<FutureOr<int>>;
+get c4 => c_noInline is FutureOr<FutureOr<int>>;
+
+get d => 499.0;
+@pragma('dart2js:noInline')
+get d_noInline => d;
+const d0 = 499.0 is FutureOr<int>;
+final d1 = 499.0 is FutureOr<int>;
+get d2 => 499.0 is FutureOr<int>;
+get d3 => d is FutureOr<int>;
+get d4 => d_noInline is FutureOr<int>;
+
+get e => 499;
+@pragma('dart2js:noInline')
+get e_noInline => e;
+const e0 = 499 is FutureOr<double>;
+final e1 = 499 is FutureOr<double>;
+get e2 => 499 is FutureOr<double>;
+get e3 => e is FutureOr<double>;
+get e4 => e_noInline is FutureOr<double>;
+
+get f => 499;
+@pragma('dart2js:noInline')
+get f_noInline => f;
+const f0 = 499 is FutureOr<FutureOr<double>>;
+final f1 = 499 is FutureOr<FutureOr<double>>;
+get f2 => 499 is FutureOr<FutureOr<double>>;
+get f3 => f is FutureOr<FutureOr<double>>;
+get f4 => f_noInline is FutureOr<FutureOr<double>>;
+
+test(fromConst, fromFinal, fromImplicitConstant, fromInlined, fromRuntime) {
+  Expect.equals(fromRuntime, fromConst);
+  Expect.equals(fromRuntime, fromFinal);
+  Expect.equals(fromRuntime, fromInlined);
+  Expect.equals(fromRuntime, fromImplicitConstant);
+}
+
+main() {
+  test(b0, b1, b2, b3, b4);
+  test(c0, c1, c2, c3, c4);
+  test(d0, d1, d2, d3, d4);
+  test(e0, e1, e2, e3, e4);
+  test(f0, f1, f2, f3, f4);
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/constant_truncate_test.dart b/tests/compiler/dart2js_extra/constant_truncate_test.dart
new file mode 100644
index 0000000..9d2c4de
--- /dev/null
+++ b/tests/compiler/dart2js_extra/constant_truncate_test.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.
+
+const a0 = 0 ~/ 0; //# a0: compile-time error
+const a1 = 0.0 ~/ 0; //# a1: compile-time error
+const a2 = -0.0 ~/ 0; //# a2: compile-time error
+const a3 = double.nan ~/ 0; //# a3: compile-time error
+const a4 = double.infinity ~/ 0; //# a4: compile-time error
+const a5 = double.negativeInfinity ~/ 0; //# a5: compile-time error
+
+const b0 = 0 ~/ 0.0; //# b0: compile-time error
+const b1 = 0.0 ~/ 0.0; //# b1: compile-time error
+const b2 = -0.0 ~/ 0.0; //# b2: compile-time error
+const b3 = double.nan ~/ 0.0; //# b3: compile-time error
+const b4 = double.infinity ~/ 0.0; //# b4: compile-time error
+const b5 = double.negativeInfinity ~/ 0.0; //# b5: compile-time error
+
+const c0 = 0 ~/ -0.0; //# c0: compile-time error
+const c1 = 0.0 ~/ -0.0; //# c1: compile-time error
+const c2 = -0.0 ~/ -0.0; //# c2: compile-time error
+const c3 = double.nan ~/ -0.0; //# c3: compile-time error
+const c4 = double.infinity ~/ -0.0; //# c4: compile-time error
+const c5 = double.negativeInfinity ~/ -0.0; //# c5: compile-time error
+
+const d0 = 0 ~/ double.nan; //# d0: compile-time error
+const d1 = 0.0 ~/ double.nan; //# d1: compile-time error
+const d2 = -0.0 ~/ double.nan; //# d2: compile-time error
+const d3 = double.nan ~/ double.nan; //# d3: compile-time error
+const d4 = double.infinity ~/ double.nan; //# d4: compile-time error
+const d5 = double.negativeInfinity ~/ double.nan; //# d5: compile-time error
+
+const e0 = 0 ~/ double.infinity; //# e0: ok
+const e1 = 0.0 ~/ double.infinity; //# e1: ok
+const e2 = -0.0 ~/ double.infinity; //# e2: ok
+const e3 = double.nan ~/ double.infinity; //# e3: compile-time error
+const e4 = double.infinity ~/ double.infinity; //# e4: compile-time error
+const e5 = double.negativeInfinity ~/ double.infinity; //# e5: compile-time error
+
+const f0 = 0 ~/ double.negativeInfinity; //# f0: ok
+const f1 = 0.0 ~/ double.negativeInfinity; //# f1: ok
+const f2 = -0.0 ~/ double.negativeInfinity; //# f2: ok
+const f3 = double.nan ~/ double.negativeInfinity; //# f3: compile-time error
+const f4 = double.infinity ~/ double.negativeInfinity; //# f4: compile-time error
+const f5 = double.negativeInfinity ~/ double.negativeInfinity; //# f5: compile-time error
+
+main() {
+  test(0, 0, () => a0); //# a0: continued
+  test(0.0, 0, () => a1); //# a1: continued
+  test(-0.0, 0, () => a2); //# a2: continued
+  test(double.nan, 0, () => a3); //# a3: continued
+  test(double.infinity, 0, () => a4); //# a4: continued
+  test(double.negativeInfinity, 0, () => a5); //# a5: continued
+
+  test(0, 0.0, () => b0); //# b0: continued
+  test(0.0, 0.0, () => b1); //# b1: continued
+  test(-0.0, 0.0, () => b2); //# b2: continued
+  test(double.nan, 0.0, () => b3); //# b3: continued
+  test(double.infinity, 0.0, () => b4); //# b4: continued
+  test(double.negativeInfinity, 0.0, () => b5); //# b5: continued
+
+  test(0, -0.0, () => c0); //# c0: continued
+  test(0.0, -0.0, () => c1); //# c1: continued
+  test(-0.0, -0.0, () => c2); //# c2: continued
+  test(double.nan, -0.0, () => c3); //# c3: continued
+  test(double.infinity, -0.0, () => c4); //# c4: continued
+  test(double.negativeInfinity, -0.0, () => c5); //# c5: continued
+
+  test(0, double.nan, () => d0); //# d0: continued
+  test(0.0, double.nan, () => d1); //# d1: continued
+  test(-0.0, double.nan, () => d2); //# d2: continued
+  test(double.nan, double.nan, () => d3); //# d3: continued
+  test(double.infinity, double.nan, () => d4); //# d4: continued
+  test(double.negativeInfinity, double.nan, () => d5); //# d5: continued
+
+  test(0, double.infinity, () => e0); //# e0: continued
+  test(0.0, double.infinity, () => e1); //# e1: continued
+  test(-0.0, double.infinity, () => e2); //# e2: continued
+  test(double.nan, double.infinity, () => e3); //# e3: continued
+  test(double.infinity, double.infinity, () => e4); //# e4: continued
+  test(double.negativeInfinity, double.infinity, () => e5); //# e5: continued
+
+  test(0, double.negativeInfinity, () => f0); //# f0: continued
+  test(0.0, double.negativeInfinity, () => f1); //# f1: continued
+  test(-0.0, double.negativeInfinity, () => f2); //# f2: continued
+  test(double.nan, double.negativeInfinity, () => f3); //# f3: continued
+  test(double.infinity, double.negativeInfinity, () => f4); //# f4: continued
+  test(double.negativeInfinity, double.negativeInfinity, () => f5); //# f5: continued
+}
+
+void test(num a, num b, num Function() f) {
+  num result;
+  try {
+    result = a ~/ b;
+    print('$a ~/ $b = $result');
+  } catch (e) {
+    print('$a ~/ $b throws $e');
+    throws(f);
+    return;
+  }
+  expect(f(), result);
+}
+
+void expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected $expected, actual $actual';
+  }
+}
+
+void throws(num Function() f) {
+  try {
+    f();
+  } catch (e) {
+    return;
+  }
+  throw 'Expected exception';
+}
diff --git a/tests/compiler/dart2js_extra/regress/unused_generator_type_parameter_test.dart b/tests/compiler/dart2js_extra/regress/unused_generator_type_parameter_test.dart
new file mode 100644
index 0000000..65dba5b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/regress/unused_generator_type_parameter_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+import "package:expect/expect.dart";
+
+class Foo<X> {
+  // T is unused, so can be erased, but that should not break anything.  The
+  // generator should still have a header and a body since it needs to compute
+  // the return type.
+  Iterable<Set<X>> bar<T>() sync* {}
+}
+
+main() {
+  var f = Foo<String>();
+  var c = f.bar<int>();
+  Expect.isFalse(c.iterator is Iterator<Set<int>>);
+  Expect.isTrue(c.iterator is Iterator<Set<String>>);
+}
diff --git a/tests/compiler/dart2js_extra/rti/required_named_parameters_test.dart b/tests/compiler/dart2js_extra/rti/required_named_parameters_test.dart
new file mode 100644
index 0000000..309a381
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/required_named_parameters_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd
+
+import 'dart:_rti' as rti;
+import 'dart:_foreign_helper' show JS;
+import "package:expect/expect.dart";
+
+const typeRulesJson = r'''
+{
+  "B": {"A": []},
+  "C": {"B": []}
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+
+main() {
+  var universe = rti.testingCreateUniverse();
+  rti.testingAddRules(universe, typeRules);
+
+  // Recipe is properly parsed
+  var rti1 = rti.testingUniverseEval(universe, "@(B,{a!B,b:B,c!B})");
+
+  // Subtype must be contravariant in its named parameter types
+  var rti2 = rti.testingUniverseEval(universe, "@(B,{a!A,b:B,c!B})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:A,c!B})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!C,b:B,c!B})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:C,c!B})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not omit optional named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,c!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not omit required named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may contain additional named optional parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d:A})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may redeclare required parameters as optional.
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a:A,b:A,c:A})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not redeclare optional parameters as required
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b!A,c!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not declare new required named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Rti.toString() appears as expected
+  Expect.equals('(B, {required B a, B b, required B c}) => dynamic',
+      rti.testingRtiToString(rti1));
+
+  // Rti debug string properly annotates all required parameters
+  Expect.equals(
+      2, 'required'.allMatches(rti.testingRtiToDebugString(rti1)).length);
+}
diff --git a/tests/compiler/dart2js_extra/rti/subtype_test.dart b/tests/compiler/dart2js_extra/rti/subtype_test.dart
index 0d34f3f..3ffea446 100644
--- a/tests/compiler/dart2js_extra/rti/subtype_test.dart
+++ b/tests/compiler/dart2js_extra/rti/subtype_test.dart
@@ -39,6 +39,7 @@
   testInterfaces();
   testTopTypes();
   testNull();
+  testBottom();
   testFutureOr();
   testFunctions();
   testGenericFunctions();
@@ -80,6 +81,11 @@
   equivalent(nullName, nullName);
 }
 
+void testBottom() {
+  String never = '0&';
+  equivalent(nullName, never); // This test is run with legacy subtyping
+}
+
 void testFutureOr() {
   strictSubtype('$futureName<int>', '$futureName<num>');
   strictSubtype('int', 'int/');
diff --git a/tests/compiler/dartdevc_native/nnbd_basic_assignment.dart b/tests/compiler/dartdevc_native/nnbd_basic_assignment_test.dart
similarity index 100%
rename from tests/compiler/dartdevc_native/nnbd_basic_assignment.dart
rename to tests/compiler/dartdevc_native/nnbd_basic_assignment_test.dart
diff --git a/tests/compiler/dartdevc_native/nnbd_strong_subtype_test.dart b/tests/compiler/dartdevc_native/nnbd_strong_subtype_test.dart
index 9bc25d9..e6d5448 100644
--- a/tests/compiler/dartdevc_native/nnbd_strong_subtype_test.dart
+++ b/tests/compiler/dartdevc_native/nnbd_strong_subtype_test.dart
@@ -1,12 +1,18 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 // Requirements=nnbd-strong
 
-import 'dart:async' show Future;
+import 'dart:_runtime' show typeRep, legacyTypeRep;
+import 'dart:async' show FutureOr;
 
-import 'runtime_utils.dart' show futureOrOf, voidType;
+import 'runtime_utils.dart'
+    show
+        checkSubtype,
+        checkProperSubtype,
+        checkMutualSubtype,
+        checkSubtypeFailure;
 import 'runtime_utils_nnbd.dart';
 
 class A {}
@@ -23,271 +29,259 @@
 
 void main() {
   // Top type symmetry.
-  // Object? <: dynamic
-  checkSubtype(nullable(Object), dynamic);
-  // dynamic <: Object?
-  checkSubtype(dynamic, nullable(Object));
-  // Object? <: void
-  checkSubtype(nullable(Object), voidType);
-  // void <: Object?
-  checkSubtype(voidType, nullable(Object));
-  // void <: dynamic
-  checkSubtype(voidType, dynamic);
-  // dynamic <: void
-  checkSubtype(dynamic, voidType);
+  // Object? <:> dynamic
+  checkMutualSubtype(typeRep<Object?>(), typeRep<dynamic>());
+  // Object? <:> void
+  checkMutualSubtype(typeRep<Object?>(), typeRep<void>());
+  // void <:> dynamic
+  checkMutualSubtype(typeRep<void>(), typeRep<dynamic>());
 
   // Bottom is subtype of top.
-  // never <: dynamic
-  checkProperSubtype(Never, dynamic);
-  // never <: void
-  checkProperSubtype(Never, voidType);
-  // never <: Object?
-  checkProperSubtype(Never, nullable(Object));
+  // Never <: dynamic
+  checkProperSubtype(typeRep<Never>(), typeRep<dynamic>());
+  // Never <: void
+  checkProperSubtype(typeRep<Never>(), typeRep<void>());
+  // Never <: Object?
+  checkProperSubtype(typeRep<Never>(), typeRep<Object?>());
 
   // Object is between top and bottom.
   // Object <: Object?
-  checkProperSubtype(Object, nullable(Object));
-  // never <: Object
-  checkProperSubtype(Never, Object);
+  checkSubtype(typeRep<Object>(), typeRep<Object?>());
+  // Never <: Object
+  checkProperSubtype(typeRep<Never>(), typeRep<Object>());
 
   // Null is between top and bottom.
   // Null <: Object?
-  checkProperSubtype(Null, nullable(Object));
-  // never <: Null
-  checkProperSubtype(Never, Null);
+  checkProperSubtype(typeRep<Null>(), typeRep<Object?>());
+  // Never <: Null
+  checkProperSubtype(typeRep<Never>(), typeRep<Null>());
 
   // Class is between Object and bottom.
   // A <: Object
-  checkProperSubtype(A, dynamic);
-  // never <: A
-  checkProperSubtype(Never, A);
+  checkProperSubtype(typeRep<A>(), typeRep<dynamic>());
+  // Never <: A
+  checkProperSubtype(typeRep<Never>(), typeRep<A>());
 
   // Nullable types are a union of T and Null.
   // A <: A?
-  checkProperSubtype(A, nullable(A));
+  checkProperSubtype(typeRep<A>(), typeRep<A?>());
   // Null <: A?
-  checkProperSubtype(Null, nullable(A));
+  checkProperSubtype(typeRep<Null>(), typeRep<A?>());
   // A? <: Object?
-  checkProperSubtype(nullable(A), nullable(Object));
+  checkProperSubtype(typeRep<A?>(), typeRep<Object?>());
 
   // Legacy types will eventually be migrated to T or T? but until then are
   // symmetric with both.
-  // Object* <: Object
-  checkSubtype(legacy(Object), Object);
-  // Object <: Object*
-  checkSubtype(Object, legacy(Object));
-  // Object* <: Object?
-  checkSubtype(legacy(Object), nullable(Object));
-  // Object? <: Object*
-  checkSubtype(nullable(Object), legacy(Object));
+  // Object* <:> Object
+  checkMutualSubtype(legacyTypeRep<Object>(), typeRep<Object>());
+  // Object* <:> Object?
+  checkMutualSubtype(legacyTypeRep<Object>(), typeRep<Object?>());
+
+  // Bottom Types
   // Null <: Object*
-  checkSubtype(Null, legacy(Object));
-  // never <: Object*
-  checkSubtype(Never, legacy(Object));
-  // A* <: A
-  checkSubtype(legacy(A), A);
-  // A <: A*
-  checkSubtype(A, legacy(A));
-  // A* <: A?
-  checkSubtype(legacy(A), nullable(A));
-  // A? <: A*
-  checkSubtype(nullable(A), legacy(A));
+  checkSubtype(typeRep<Null>(), legacyTypeRep<Object>());
+  // Never <: Object*
+  checkSubtype(typeRep<Never>(), legacyTypeRep<Object>());
+  // A* <:> A
+  checkMutualSubtype(legacyTypeRep<A>(), typeRep<A>());
+  // A* <:> A?
+  checkMutualSubtype(legacyTypeRep<A>(), typeRep<A?>());
   // A* <: Object
-  checkProperSubtype(legacy(A), Object);
+  checkProperSubtype(legacyTypeRep<A>(), typeRep<Object>());
   // A* <: Object?
-  checkProperSubtype(legacy(A), nullable(Object));
+  checkProperSubtype(legacyTypeRep<A>(), typeRep<Object?>());
   // Null <: A*
-  checkProperSubtype(Null, legacy(A));
-  // never <: A*
-  checkProperSubtype(Never, legacy(A));
+  checkProperSubtype(typeRep<Null>(), legacyTypeRep<A>());
+  // Never <: A*
+  checkProperSubtype(typeRep<Never>(), legacyTypeRep<A>());
 
   // Futures.
   // Null <: FutureOr<Object?>
-  checkProperSubtype(Null, futureOrOf(nullable(Object)));
+  checkProperSubtype(typeRep<Null>(), typeRep<FutureOr<Object?>>());
   // Object <: FutureOr<Object?>
-  checkProperSubtype(Object, futureOrOf(nullable(Object)));
-  // Object? <: FutureOr<Object?>
-  checkSubtype(nullable(Object), futureOrOf(nullable(Object)));
-  // Object <: FutureOr<Object>
-  checkSubtype(Object, futureOrOf(Object));
-  // FutureOr<Object> <: Object
-  checkSubtype(futureOrOf(Object), Object);
+  checkProperSubtype(typeRep<Object>(), typeRep<FutureOr<Object?>>());
+  // Object? <:> FutureOr<Object?>
+  checkMutualSubtype(typeRep<Object?>(), typeRep<FutureOr<Object?>>());
+  // Object <:> FutureOr<Object>
+  checkMutualSubtype(typeRep<Object>(), typeRep<FutureOr<Object>>());
   // Object <: FutureOr<dynamic>
-  checkProperSubtype(Object, futureOrOf(dynamic));
+  checkProperSubtype(typeRep<Object>(), typeRep<FutureOr<dynamic>>());
   // Object <: FutureOr<void>
-  checkProperSubtype(Object, futureOrOf(voidType));
+  checkProperSubtype(typeRep<Object>(), typeRep<FutureOr<void>>());
   // Future<Object> <: FutureOr<Object?>
-  checkProperSubtype(generic1(Future, Object), futureOrOf(nullable(Object)));
+  checkProperSubtype(typeRep<Future<Object>>(), typeRep<FutureOr<Object?>>());
   // Future<Object?> <: FutureOr<Object?>
-  checkProperSubtype(
-      generic1(Future, nullable(Object)), futureOrOf(nullable(Object)));
+  checkProperSubtype(typeRep<Future<Object?>>(), typeRep<FutureOr<Object?>>());
   // FutureOr<Never> <: Future<Never>
-  checkSubtype(futureOrOf(Never), generic1(Future, Never));
+  checkSubtype(typeRep<FutureOr<Never>>(), typeRep<Future<Never>>());
   // Future<B> <: FutureOr<A>
-  checkProperSubtype(generic1(Future, B), futureOrOf(A));
+  checkProperSubtype(typeRep<Future<B>>(), typeRep<FutureOr<A>>());
   // B <: <: FutureOr<A>
-  checkProperSubtype(B, futureOrOf(A));
+  checkProperSubtype(typeRep<B>(), typeRep<FutureOr<A>>());
   // Future<B> <: Future<A>
-  checkProperSubtype(generic1(Future, B), generic1(Future, A));
+  checkProperSubtype(typeRep<Future<B>>(), typeRep<Future<A>>());
 
   // Interface subtypes.
   // A <: A
-  checkSubtype(A, A);
+  checkSubtype(typeRep<A>(), typeRep<A>());
   // B <: A
-  checkProperSubtype(B, A);
+  checkProperSubtype(typeRep<B>(), typeRep<A>());
   // C <: B
-  checkProperSubtype(C, B);
+  checkProperSubtype(typeRep<C>(), typeRep<B>());
   // C <: A
-  checkProperSubtype(C, A);
+  checkProperSubtype(typeRep<C>(), typeRep<A>());
 
   // Functions.
   // A -> B <: Function
-  checkProperSubtype(function1(B, A), Function);
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<Function>());
 
   // A -> B <: A -> B
-  checkSubtype(function1(B, A), function1(B, A));
+  checkSubtype(typeRep<B Function(A)>(), typeRep<B Function(A)>());
 
   // A -> B <: B -> B
-  checkProperSubtype(function1(B, A), function1(B, B));
-  // TODO(nshahan) Subtype check with covariant keyword?
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<B Function(B)>());
 
   // A -> B <: A -> A
-  checkSubtype(function1(B, A), function1(A, A));
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<A Function(A)>());
 
   // Generic Function Subtypes.
   // Bound is a built in type.
   // <T extends int> void -> void <: <T extends int> void -> void
-  checkSubtype(genericFunction(int), genericFunction(int));
+  checkSubtype(
+      genericFunction(typeRep<int>()), genericFunction(typeRep<int>()));
 
   // <T extends String> A -> T <: <T extends String> B -> T
-  checkProperSubtype(
-      functionGenericReturn(String, A), functionGenericReturn(String, B));
+  checkProperSubtype(functionGenericReturn(typeRep<String>(), typeRep<A>()),
+      functionGenericReturn(typeRep<String>(), typeRep<B>()));
 
   // <T extends double> T -> B <: <T extends double> T -> A
-  checkProperSubtype(
-      functionGenericArg(double, B), functionGenericArg(double, A));
+  checkProperSubtype(functionGenericArg(typeRep<double>(), typeRep<B>()),
+      functionGenericArg(typeRep<double>(), typeRep<A>()));
 
   // Bound is a function type.
   // <T extends A -> B> void -> void <: <T extends A -> B> void -> void
-  checkSubtype(
-      genericFunction(function1(B, A)), genericFunction(function1(B, A)));
+  checkSubtype(genericFunction(typeRep<A Function(B)>()),
+      genericFunction(typeRep<A Function(B)>()));
 
   // <T extends A -> B> A -> T <: <T extends A -> B> B -> T
-  checkProperSubtype(functionGenericReturn(function1(B, A), A),
-      functionGenericReturn(function1(B, A), B));
+  checkProperSubtype(
+      functionGenericReturn(typeRep<A Function(B)>(), typeRep<A>()),
+      functionGenericReturn(typeRep<A Function(B)>(), typeRep<B>()));
 
   // <T extends A -> B> T -> B <: <T extends A -> B> T -> A
-  checkProperSubtype(functionGenericArg(function1(B, A), B),
-      functionGenericArg(function1(B, A), A));
+  checkProperSubtype(functionGenericArg(typeRep<A Function(B)>(), typeRep<B>()),
+      functionGenericArg(typeRep<A Function(B)>(), typeRep<A>()));
 
   // Bound is a user defined class.
   // <T extends B> void -> void <: <T extends B> void -> void
-  checkSubtype(genericFunction(B), genericFunction(B));
+  checkSubtype(genericFunction(typeRep<B>()), genericFunction(typeRep<B>()));
 
   // <T extends B> A -> T <: <T extends B> B -> T
-  checkProperSubtype(functionGenericReturn(B, A), functionGenericReturn(B, B));
+  checkProperSubtype(functionGenericReturn(typeRep<B>(), typeRep<A>()),
+      functionGenericReturn(typeRep<B>(), typeRep<B>()));
 
   // <T extends B> T -> B <: <T extends B> T -> A
-  checkProperSubtype(functionGenericArg(B, B), functionGenericArg(B, A));
+  checkProperSubtype(functionGenericArg(typeRep<B>(), typeRep<B>()),
+      functionGenericArg(typeRep<B>(), typeRep<A>()));
 
   // Bound is a Future.
   // <T extends Future<B>> void -> void <: <T extends Future<B>> void -> void
-  checkSubtype(genericFunction(generic1(Future, B)),
-      genericFunction(generic1(Future, B)));
+  checkSubtype(genericFunction(typeRep<Future<B>>()),
+      genericFunction(typeRep<Future<B>>()));
 
   // <T extends Future<B>> A -> T <: <T extends Future<B>> B -> T
-  checkProperSubtype(functionGenericReturn(generic1(Future, B), A),
-      functionGenericReturn(generic1(Future, B), B));
+  checkProperSubtype(functionGenericReturn(typeRep<Future<B>>(), typeRep<A>()),
+      functionGenericReturn(typeRep<Future<B>>(), typeRep<B>()));
 
   // <T extends Future<B>> T -> B <: <T extends Future<B>> T -> A
-  checkProperSubtype(functionGenericArg(generic1(Future, B), B),
-      functionGenericArg(generic1(Future, B), A));
+  checkProperSubtype(functionGenericArg(typeRep<Future<B>>(), typeRep<B>()),
+      functionGenericArg(typeRep<Future<B>>(), typeRep<A>()));
 
   // Bound is a FutureOr.
   // <T extends FutureOr<B>> void -> void <:
   //    <T extends FutureOr<B>> void -> void
-  checkSubtype(genericFunction(futureOrOf(B)), genericFunction(futureOrOf(B)));
+  checkSubtype(genericFunction(typeRep<FutureOr<B>>()),
+      genericFunction(typeRep<FutureOr<B>>()));
 
   // <T extends FutureOr<B>> A -> T <: <T extends FutureOr<B>> B -> T
-  checkProperSubtype(functionGenericReturn(futureOrOf(B), A),
-      functionGenericReturn(futureOrOf(B), B));
+  checkProperSubtype(
+      functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<A>()),
+      functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<B>()));
 
   // <T extends FutureOr<B>> T -> B <: <T extends FutureOr<B>> T -> A
-  checkProperSubtype(functionGenericArg(futureOrOf(B), B),
-      functionGenericArg(futureOrOf(B), A));
+  checkProperSubtype(functionGenericArg(typeRep<FutureOr<B>>(), typeRep<B>()),
+      functionGenericArg(typeRep<FutureOr<B>>(), typeRep<A>()));
 
   // Generics.
-  // D <: D<B>
-  checkSubtype(D, generic1(D, B));
-  // D<B> <: D
-  checkSubtype(generic1(D, B), D);
+  // D <:> D<B>
+  checkMutualSubtype(typeRep<D>(), typeRep<D<B>>());
   // D<C> <: D<B>
-  checkProperSubtype(generic1(D, C), generic1(D, B));
+  checkProperSubtype(typeRep<D<C>>(), typeRep<D<B>>());
 
   // F <: E
-  checkProperSubtype(F, E);
+  checkProperSubtype(typeRep<F>(), typeRep<E>());
   // F <: E<A, A>
-  checkProperSubtype(F, generic2(E, A, A));
+  checkProperSubtype(typeRep<F>(), typeRep<E<A, A>>());
+  // E<B, B> <: E
+  checkProperSubtype(typeRep<E<B, B>>(), typeRep<E>());
   // E<B, B> <: E<A, A>
-  checkProperSubtype(generic2(E, B, B), E);
-  // E<B, B> <: E<A, A>
-  checkProperSubtype(generic2(E, B, B), generic2(E, A, A));
+  checkProperSubtype(typeRep<E<B, B>>(), typeRep<E<A, A>>());
 
   // Nullable interface subtypes.
   // B <: A?
-  checkProperSubtype(B, nullable(A));
+  checkProperSubtype(typeRep<B>(), typeRep<A?>());
   // C <: A?
-  checkProperSubtype(C, nullable(A));
+  checkProperSubtype(typeRep<C>(), typeRep<A?>());
   // B? <: A?
-  checkProperSubtype(nullable(B), nullable(A));
+  checkProperSubtype(typeRep<B?>(), typeRep<A?>());
   // C? <: A?
-  checkProperSubtype(nullable(C), nullable(A));
+  checkProperSubtype(typeRep<C?>(), typeRep<A?>());
 
   // Mixed mode.
   // B* <: A
-  checkProperSubtype(legacy(B), A);
+  checkProperSubtype(legacyTypeRep<B>(), typeRep<A>());
   // B* <: A?
-  checkProperSubtype(legacy(B), nullable(A));
+  checkProperSubtype(legacyTypeRep<B>(), typeRep<A?>());
   // A* <\: B
-  checkSubtypeFailure(legacy(A), B);
+  checkSubtypeFailure(legacyTypeRep<A>(), typeRep<B>());
   // B? <: A*
-  checkProperSubtype(nullable(B), legacy(A));
+  checkProperSubtype(typeRep<B?>(), legacyTypeRep<A>());
   // B <: A*
-  checkProperSubtype(B, legacy(A));
+  checkProperSubtype(typeRep<B>(), legacyTypeRep<A>());
   // A <: B*
-  checkSubtypeFailure(A, legacy(B));
+  checkSubtypeFailure(typeRep<A>(), legacyTypeRep<B>());
   // A? <: B*
-  checkSubtypeFailure(nullable(A), legacy(B));
+  checkSubtypeFailure(typeRep<A?>(), legacyTypeRep<B>());
 
   // Allowed in weak mode.
   // dynamic <\: Object
-  checkSubtypeFailure(dynamic, Object);
+  checkSubtypeFailure(typeRep<dynamic>(), typeRep<Object>());
   // void <\: Object
-  checkSubtypeFailure(voidType, Object);
+  checkSubtypeFailure(typeRep<void>(), typeRep<Object>());
   // Object? <\: Object
-  checkSubtypeFailure(nullable(Object), Object);
+  checkSubtypeFailure(typeRep<Object?>(), typeRep<Object>());
   // A? <\: Object
-  checkSubtypeFailure(nullable(A), Object);
+  checkSubtypeFailure(typeRep<A?>(), typeRep<Object>());
   // A? <\: A
-  checkSubtypeFailure(nullable(A), A);
-  // Null <\: never
-  checkSubtypeFailure(Null, Never);
+  checkSubtypeFailure(typeRep<A?>(), typeRep<A>());
+  // Null <\: Never
+  checkSubtypeFailure(typeRep<Null>(), typeRep<Never>());
   // Null <\: Object
-  checkSubtypeFailure(Null, Object);
+  checkSubtypeFailure(typeRep<Null>(), typeRep<Object>());
   // Null <\: A
-  checkSubtypeFailure(Null, A);
+  checkSubtypeFailure(typeRep<Null>(), typeRep<A>());
   // Null <\: FutureOr<A>
-  checkSubtypeFailure(Null, futureOrOf(A));
+  checkSubtypeFailure(typeRep<Null>(), typeRep<FutureOr<A>>());
   // Null <\: Future<A>
-  checkSubtypeFailure(Null, generic1(Future, A));
+  checkSubtypeFailure(typeRep<Null>(), typeRep<Future<A>>());
   // FutureOr<Null> <\: Future<Null>
-  checkSubtypeFailure(futureOrOf(Null), generic1(Future, Null));
+  checkSubtypeFailure(typeRep<FutureOr<Null>>(), typeRep<Future<Null>>());
   // Null <\: Future<A?>
-  checkSubtypeFailure(Null, generic1(Future, nullable(A)));
+  checkSubtypeFailure(typeRep<Null>(), typeRep<Future<A?>>());
   // FutureOr<Object?> <\: Object
-  checkSubtypeFailure(futureOrOf(nullable(Object)), Object);
+  checkSubtypeFailure(typeRep<FutureOr<Object?>>(), typeRep<Object>());
   // FutureOr<dynamic> <\: Object
-  checkSubtypeFailure(futureOrOf(dynamic), Object);
+  checkSubtypeFailure(typeRep<FutureOr<dynamic>>(), typeRep<Object>());
   // FutureOr<void> <\: Object
-  checkSubtypeFailure(futureOrOf(voidType), Object);
+  checkSubtypeFailure(typeRep<FutureOr<void>>(), typeRep<Object>());
 }
diff --git a/tests/compiler/dartdevc_native/nnbd_type_normalization_test.dart b/tests/compiler/dartdevc_native/nnbd_type_normalization_test.dart
index 6946585..2ae889c 100644
--- a/tests/compiler/dartdevc_native/nnbd_type_normalization_test.dart
+++ b/tests/compiler/dartdevc_native/nnbd_type_normalization_test.dart
@@ -4,35 +4,34 @@
 
 // Requirements=nnbd
 
-import 'dart:_runtime' as dart;
+import 'dart:_runtime' show legacy, nullable, typeRep, legacyTypeRep;
 
 import 'package:expect/expect.dart';
 
-import 'runtime_utils_nnbd.dart';
-
 class A {}
 
 void main() {
   // A?? == A?
-  Expect.identical(nullable(nullable(A)), nullable(A));
+  Expect.identical(nullable(typeRep<A?>()), typeRep<A?>());
   // A?* == A?
-  Expect.identical(legacy(nullable(A)), nullable(A));
+  Expect.identical(legacy(typeRep<A?>()), typeRep<A?>());
   // A*? == A?
-  Expect.identical(nullable(legacy(A)), nullable(A));
+  Expect.identical(nullable(legacyTypeRep<A>()), typeRep<A?>());
   // A** == A*
-  Expect.identical(legacy(legacy(A)), legacy(A));
+  Expect.identical(legacy(legacyTypeRep<A>()), legacyTypeRep<A>());
+
+  // The tests below need explicit wrapping in nullable and legacy to ensure
+  // they appear at runtime and the runtime library normalizes them correctly.
   // Null? == Null
-  Expect.identical(nullable(Null), Null);
+  Expect.identical(nullable(typeRep<Null>()), typeRep<Null>());
   // Never? == Null
-  Expect.identical(nullable(Never), Null);
+  Expect.identical(nullable(typeRep<Never>()), typeRep<Null>());
   // dynamic? == dynamic
-  Expect.identical(nullable(dynamic), dynamic);
+  Expect.identical(nullable(typeRep<dynamic>()), typeRep<dynamic>());
   // void? == void
-  Expect.identical(
-      nullable(dart.wrapType(dart.void_)), dart.wrapType(dart.void_));
+  Expect.identical(nullable(typeRep<void>()), typeRep<void>());
   // dynamic* == dynamic
-  Expect.identical(legacy(dynamic), dynamic);
+  Expect.identical(legacy(typeRep<dynamic>()), typeRep<dynamic>());
   // void* == void
-  Expect.identical(
-      legacy(dart.wrapType(dart.void_)), dart.wrapType(dart.void_));
+  Expect.identical(legacy(typeRep<void>()), typeRep<void>());
 }
diff --git a/tests/compiler/dartdevc_native/nnbd_weak_subtype_test.dart b/tests/compiler/dartdevc_native/nnbd_weak_subtype_test.dart
index 9160e7a..205d2f1 100644
--- a/tests/compiler/dartdevc_native/nnbd_weak_subtype_test.dart
+++ b/tests/compiler/dartdevc_native/nnbd_weak_subtype_test.dart
@@ -1,12 +1,18 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 // Requirements=nnbd-weak
 
+import 'dart:_runtime' show typeRep, legacyTypeRep;
 import 'dart:async';
 
-import 'runtime_utils.dart' show futureOrOf, voidType;
+import 'runtime_utils.dart'
+    show
+        checkSubtype,
+        checkProperSubtype,
+        checkMutualSubtype,
+        checkSubtypeFailure;
 import 'runtime_utils_nnbd.dart';
 
 class A {}
@@ -23,271 +29,259 @@
 
 void main() {
   // Top type symmetry.
-  // Object? <: dynamic
-  checkSubtype(nullable(Object), dynamic);
-  // dynamic <: Object?
-  checkSubtype(dynamic, nullable(Object));
-  // Object? <: void
-  checkSubtype(nullable(Object), voidType);
-  // void <: Object?
-  checkSubtype(voidType, nullable(Object));
-  // void <: dynamic
-  checkSubtype(voidType, dynamic);
-  // dynamic <: void
-  checkSubtype(dynamic, voidType);
+  // Object? <:> dynamic
+  checkMutualSubtype(typeRep<Object?>(), typeRep<dynamic>());
+  // Object? <:> void
+  checkMutualSubtype(typeRep<Object?>(), typeRep<void>());
+  // void <:> dynamic
+  checkMutualSubtype(typeRep<void>(), typeRep<dynamic>());
 
   // Bottom is subtype of top.
-  // never <: dynamic
-  checkProperSubtype(Never, dynamic);
-  // never <: void
-  checkProperSubtype(Never, voidType);
-  // never <: Object?
-  checkProperSubtype(Never, nullable(Object));
+  // Never <: dynamic
+  checkProperSubtype(typeRep<Never>(), typeRep<dynamic>());
+  // Never <: void
+  checkProperSubtype(typeRep<Never>(), typeRep<void>());
+  // Never <: Object?
+  checkProperSubtype(typeRep<Never>(), typeRep<Object?>());
 
   // Object is between top and bottom.
   // Object <: Object?
-  checkSubtype(Object, nullable(Object));
-  // never <: Object
-  checkProperSubtype(Never, Object);
+  checkSubtype(typeRep<Object>(), typeRep<Object?>());
+  // Never <: Object
+  checkProperSubtype(typeRep<Never>(), typeRep<Object>());
 
   // Null is between top and bottom.
   // Null <: Object?
-  checkProperSubtype(Null, nullable(Object));
-  // never <: Null
-  checkSubtype(Never, Null);
+  checkProperSubtype(typeRep<Null>(), typeRep<Object?>());
+  // Never <: Null
+  checkSubtype(typeRep<Never>(), typeRep<Null>());
 
   // Class is between Object and bottom.
   // A <: Object
-  checkProperSubtype(A, dynamic);
-  // never <: A
-  checkProperSubtype(Never, A);
+  checkProperSubtype(typeRep<A>(), typeRep<dynamic>());
+  // Never <: A
+  checkProperSubtype(typeRep<Never>(), typeRep<A>());
 
   // Nullable types are a union of T and Null.
   // A <: A?
-  checkSubtype(A, nullable(A));
+  checkSubtype(typeRep<A>(), typeRep<A?>());
   // Null <: A?
-  checkProperSubtype(Null, nullable(A));
+  checkProperSubtype(typeRep<Null>(), typeRep<A?>());
   // A? <: Object?
-  checkProperSubtype(nullable(A), nullable(Object));
+  checkProperSubtype(typeRep<A?>(), typeRep<Object?>());
 
   // Legacy types will eventually be migrated to T or T? but until then are
   // symmetric with both.
-  // Object* <: Object
-  checkSubtype(legacy(Object), Object);
-  // Object <: Object*
-  checkSubtype(Object, legacy(Object));
-  // Object* <: Object?
-  checkSubtype(legacy(Object), nullable(Object));
-  // Object? <: Object*
-  checkSubtype(nullable(Object), legacy(Object));
+  // Object* <:> Object
+  checkMutualSubtype(legacyTypeRep<Object>(), typeRep<Object>());
+  // Object* <:> Object?
+  checkMutualSubtype(legacyTypeRep<Object>(), typeRep<Object?>());
+
+  // Bottom Types
   // Null <: Object*
-  checkSubtype(Null, legacy(Object));
-  // never <: Object*
-  checkSubtype(Never, legacy(Object));
-  // A* <: A
-  checkSubtype(legacy(A), A);
-  // A <: A*
-  checkSubtype(A, legacy(A));
-  // A* <: A?
-  checkSubtype(legacy(A), nullable(A));
-  // A? <: A*
-  checkSubtype(nullable(A), legacy(A));
+  checkSubtype(typeRep<Null>(), legacyTypeRep<Object>());
+  // Never <: Object*
+  checkSubtype(typeRep<Never>(), legacyTypeRep<Object>());
+  // A* <:> A
+  checkMutualSubtype(legacyTypeRep<A>(), typeRep<A>());
+  // A* <:> A?
+  checkMutualSubtype(legacyTypeRep<A>(), typeRep<A?>());
   // A* <: Object
-  checkProperSubtype(legacy(A), Object);
+  checkProperSubtype(legacyTypeRep<A>(), typeRep<Object>());
   // A* <: Object?
-  checkProperSubtype(legacy(A), nullable(Object));
+  checkProperSubtype(legacyTypeRep<A>(), typeRep<Object?>());
   // Null <: A*
-  checkProperSubtype(Null, legacy(A));
-  // never <: A*
-  checkProperSubtype(Never, legacy(A));
+  checkProperSubtype(typeRep<Null>(), legacyTypeRep<A>());
+  // Never <: A*
+  checkProperSubtype(typeRep<Never>(), legacyTypeRep<A>());
 
   // Futures.
   // Null <: FutureOr<Object?>
-  checkProperSubtype(Null, futureOrOf(nullable(Object)));
+  checkProperSubtype(typeRep<Null>(), typeRep<FutureOr<Object?>>());
   // Object <: FutureOr<Object?>
-  checkSubtype(Object, futureOrOf(nullable(Object)));
-  // Object? <: FutureOr<Object?>
-  checkSubtype(nullable(Object), futureOrOf(nullable(Object)));
-  // Object <: FutureOr<Object>
-  checkSubtype(Object, futureOrOf(Object));
-  // FutureOr<Object> <: Object
-  checkSubtype(futureOrOf(Object), Object);
-  // Object <: FutureOr<dynamic>
-  checkSubtype(Object, futureOrOf(dynamic));
-  // Object <: FutureOr<void>
-  checkSubtype(Object, futureOrOf(voidType));
+  checkSubtype(typeRep<Object>(), typeRep<FutureOr<Object?>>());
+  // Object? <:> FutureOr<Object?>
+  checkMutualSubtype(typeRep<Object?>(), typeRep<FutureOr<Object?>>());
+  // Object <:> FutureOr<Object>
+  checkMutualSubtype(typeRep<Object>(), typeRep<FutureOr<Object>>());
+  // Object <:> FutureOr<dynamic>
+  checkMutualSubtype(typeRep<Object>(), typeRep<FutureOr<dynamic>>());
+  // Object <:> FutureOr<void>
+  checkMutualSubtype(typeRep<Object>(), typeRep<FutureOr<void>>());
   // Future<Object> <: FutureOr<Object?>
-  checkProperSubtype(generic1(Future, Object), futureOrOf(nullable(Object)));
+  checkProperSubtype(typeRep<Future<Object>>(), typeRep<FutureOr<Object?>>());
   // Future<Object?> <: FutureOr<Object?>
-  checkProperSubtype(
-      generic1(Future, nullable(Object)), futureOrOf(nullable(Object)));
+  checkProperSubtype(typeRep<Future<Object?>>(), typeRep<FutureOr<Object?>>());
   // FutureOr<Never> <: Future<Never>
-  checkSubtype(futureOrOf(Never), generic1(Future, Never));
+  checkSubtype(typeRep<FutureOr<Never>>(), typeRep<Future<Never>>());
   // Future<B> <: FutureOr<A>
-  checkProperSubtype(generic1(Future, B), futureOrOf(A));
+  checkProperSubtype(typeRep<Future<B>>(), typeRep<FutureOr<A>>());
   // B <: <: FutureOr<A>
-  checkProperSubtype(B, futureOrOf(A));
+  checkProperSubtype(typeRep<B>(), typeRep<FutureOr<A>>());
   // Future<B> <: Future<A>
-  checkProperSubtype(generic1(Future, B), generic1(Future, A));
+  checkProperSubtype(typeRep<Future<B>>(), typeRep<Future<A>>());
 
   // Interface subtypes.
   // A <: A
-  checkSubtype(A, A);
+  checkSubtype(typeRep<A>(), typeRep<A>());
   // B <: A
-  checkProperSubtype(B, A);
+  checkProperSubtype(typeRep<B>(), typeRep<A>());
   // C <: B
-  checkProperSubtype(C, B);
+  checkProperSubtype(typeRep<C>(), typeRep<B>());
   // C <: A
-  checkProperSubtype(C, A);
+  checkProperSubtype(typeRep<C>(), typeRep<A>());
 
   // Functions.
   // A -> B <: Function
-  checkProperSubtype(function1(B, A), Function);
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<Function>());
 
   // A -> B <: A -> B
-  checkSubtype(function1(B, A), function1(B, A));
+  checkSubtype(typeRep<B Function(A)>(), typeRep<B Function(A)>());
 
   // A -> B <: B -> B
-  checkProperSubtype(function1(B, A), function1(B, B));
-  // TODO(nshahan) Subtype check with covariant keyword?
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<B Function(B)>());
 
   // A -> B <: A -> A
-  checkSubtype(function1(B, A), function1(A, A));
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<A Function(A)>());
 
   // Generic Function Subtypes.
   // Bound is a built in type.
   // <T extends int> void -> void <: <T extends int> void -> void
-  checkSubtype(genericFunction(int), genericFunction(int));
+  checkSubtype(
+      genericFunction(typeRep<int>()), genericFunction(typeRep<int>()));
 
   // <T extends String> A -> T <: <T extends String> B -> T
-  checkProperSubtype(
-      functionGenericReturn(String, A), functionGenericReturn(String, B));
+  checkProperSubtype(functionGenericReturn(typeRep<String>(), typeRep<A>()),
+      functionGenericReturn(typeRep<String>(), typeRep<B>()));
 
   // <T extends double> T -> B <: <T extends double> T -> A
-  checkProperSubtype(
-      functionGenericArg(double, B), functionGenericArg(double, A));
+  checkProperSubtype(functionGenericArg(typeRep<double>(), typeRep<B>()),
+      functionGenericArg(typeRep<double>(), typeRep<A>()));
 
   // Bound is a function type.
   // <T extends A -> B> void -> void <: <T extends A -> B> void -> void
-  checkSubtype(
-      genericFunction(function1(B, A)), genericFunction(function1(B, A)));
+  checkSubtype(genericFunction(typeRep<A Function(B)>()),
+      genericFunction(typeRep<A Function(B)>()));
 
   // <T extends A -> B> A -> T <: <T extends A -> B> B -> T
-  checkProperSubtype(functionGenericReturn(function1(B, A), A),
-      functionGenericReturn(function1(B, A), B));
+  checkProperSubtype(
+      functionGenericReturn(typeRep<A Function(B)>(), typeRep<A>()),
+      functionGenericReturn(typeRep<A Function(B)>(), typeRep<B>()));
 
   // <T extends A -> B> T -> B <: <T extends A -> B> T -> A
-  checkProperSubtype(functionGenericArg(function1(B, A), B),
-      functionGenericArg(function1(B, A), A));
+  checkProperSubtype(functionGenericArg(typeRep<A Function(B)>(), typeRep<B>()),
+      functionGenericArg(typeRep<A Function(B)>(), typeRep<A>()));
 
   // Bound is a user defined class.
   // <T extends B> void -> void <: <T extends B> void -> void
-  checkSubtype(genericFunction(B), genericFunction(B));
+  checkSubtype(genericFunction(typeRep<B>()), genericFunction(typeRep<B>()));
 
   // <T extends B> A -> T <: <T extends B> B -> T
-  checkProperSubtype(functionGenericReturn(B, A), functionGenericReturn(B, B));
+  checkProperSubtype(functionGenericReturn(typeRep<B>(), typeRep<A>()),
+      functionGenericReturn(typeRep<B>(), typeRep<B>()));
 
   // <T extends B> T -> B <: <T extends B> T -> A
-  checkProperSubtype(functionGenericArg(B, B), functionGenericArg(B, A));
+  checkProperSubtype(functionGenericArg(typeRep<B>(), typeRep<B>()),
+      functionGenericArg(typeRep<B>(), typeRep<A>()));
 
   // Bound is a Future.
   // <T extends Future<B>> void -> void <: <T extends Future<B>> void -> void
-  checkSubtype(genericFunction(generic1(Future, B)),
-      genericFunction(generic1(Future, B)));
+  checkSubtype(genericFunction(typeRep<Future<B>>()),
+      genericFunction(typeRep<Future<B>>()));
 
   // <T extends Future<B>> A -> T <: <T extends Future<B>> B -> T
-  checkProperSubtype(functionGenericReturn(generic1(Future, B), A),
-      functionGenericReturn(generic1(Future, B), B));
+  checkProperSubtype(functionGenericReturn(typeRep<Future<B>>(), typeRep<A>()),
+      functionGenericReturn(typeRep<Future<B>>(), typeRep<B>()));
 
   // <T extends Future<B>> T -> B <: <T extends Future<B>> T -> A
-  checkProperSubtype(functionGenericArg(generic1(Future, B), B),
-      functionGenericArg(generic1(Future, B), A));
+  checkProperSubtype(functionGenericArg(typeRep<Future<B>>(), typeRep<B>()),
+      functionGenericArg(typeRep<Future<B>>(), typeRep<A>()));
 
   // Bound is a FutureOr.
   // <T extends FutureOr<B>> void -> void <:
   //    <T extends FutureOr<B>> void -> void
-  checkSubtype(genericFunction(futureOrOf(B)), genericFunction(futureOrOf(B)));
+  checkSubtype(genericFunction(typeRep<FutureOr<B>>()),
+      genericFunction(typeRep<FutureOr<B>>()));
 
   // <T extends FutureOr<B>> A -> T <: <T extends FutureOr<B>> B -> T
-  checkProperSubtype(functionGenericReturn(futureOrOf(B), A),
-      functionGenericReturn(futureOrOf(B), B));
+  checkProperSubtype(
+      functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<A>()),
+      functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<B>()));
 
   // <T extends FutureOr<B>> T -> B <: <T extends FutureOr<B>> T -> A
-  checkProperSubtype(functionGenericArg(futureOrOf(B), B),
-      functionGenericArg(futureOrOf(B), A));
+  checkProperSubtype(functionGenericArg(typeRep<FutureOr<B>>(), typeRep<B>()),
+      functionGenericArg(typeRep<FutureOr<B>>(), typeRep<A>()));
 
   // Generics.
-  // D <: D<B>
-  checkSubtype(D, generic1(D, B));
-  // D<B> <: D
-  checkSubtype(generic1(D, B), D);
+  // D <:> D<B>
+  checkMutualSubtype(typeRep<D>(), typeRep<D<B>>());
   // D<C> <: D<B>
-  checkProperSubtype(generic1(D, C), generic1(D, B));
+  checkProperSubtype(typeRep<D<C>>(), typeRep<D<B>>());
 
   // F <: E
-  checkProperSubtype(F, E);
+  checkProperSubtype(typeRep<F>(), typeRep<E>());
   // F <: E<A, A>
-  checkProperSubtype(F, generic2(E, A, A));
+  checkProperSubtype(typeRep<F>(), typeRep<E<A, A>>());
+  // E<B, B> <: E
+  checkProperSubtype(typeRep<E<B, B>>(), typeRep<E>());
   // E<B, B> <: E<A, A>
-  checkProperSubtype(generic2(E, B, B), E);
-  // E<B, B> <: E<A, A>
-  checkProperSubtype(generic2(E, B, B), generic2(E, A, A));
+  checkProperSubtype(typeRep<E<B, B>>(), typeRep<E<A, A>>());
 
   // Nullable interface subtypes.
   // B <: A?
-  checkProperSubtype(B, nullable(A));
+  checkProperSubtype(typeRep<B>(), typeRep<A?>());
   // C <: A?
-  checkProperSubtype(C, nullable(A));
+  checkProperSubtype(typeRep<C>(), typeRep<A?>());
   // B? <: A?
-  checkProperSubtype(nullable(B), nullable(A));
+  checkProperSubtype(typeRep<B?>(), typeRep<A?>());
   // C? <: A?
-  checkProperSubtype(nullable(C), nullable(A));
+  checkProperSubtype(typeRep<C?>(), typeRep<A?>());
 
   // Mixed mode.
   // B* <: A
-  checkProperSubtype(legacy(B), A);
+  checkProperSubtype(legacyTypeRep<B>(), typeRep<A>());
   // B* <: A?
-  checkProperSubtype(legacy(B), nullable(A));
+  checkProperSubtype(legacyTypeRep<B>(), typeRep<A?>());
   // A* <\: B
-  checkSubtypeFailure(legacy(A), B);
+  checkSubtypeFailure(legacyTypeRep<A>(), typeRep<B>());
   // B? <: A*
-  checkProperSubtype(nullable(B), legacy(A));
+  checkProperSubtype(typeRep<B?>(), legacyTypeRep<A>());
   // B <: A*
-  checkProperSubtype(B, legacy(A));
+  checkProperSubtype(typeRep<B>(), legacyTypeRep<A>());
   // A <: B*
-  checkSubtypeFailure(A, legacy(B));
+  checkSubtypeFailure(typeRep<A>(), legacyTypeRep<B>());
   // A? <: B*
-  checkSubtypeFailure(nullable(A), legacy(B));
+  checkSubtypeFailure(typeRep<A?>(), legacyTypeRep<B>());
 
   // Allowed in weak mode.
   // dynamic <: Object
-  checkSubtype(dynamic, Object);
+  checkSubtype(typeRep<dynamic>(), typeRep<Object>());
   // void <: Object
-  checkSubtype(voidType, Object);
+  checkSubtype(typeRep<void>(), typeRep<Object>());
   // Object? <: Object
-  checkSubtype(nullable(Object), Object);
+  checkSubtype(typeRep<Object?>(), typeRep<Object>());
   // A? <: Object
-  checkProperSubtype(nullable(A), Object);
+  checkProperSubtype(typeRep<A?>(), typeRep<Object>());
   // A? <: A
-  checkSubtype(nullable(A), A);
-  // Null <: never
-  checkSubtype(Null, Never);
+  checkSubtype(typeRep<A?>(), typeRep<A>());
+  // Null <: Never
+  checkSubtype(typeRep<Null>(), typeRep<Never>());
   // Null <: Object
-  checkProperSubtype(Null, Object);
+  checkProperSubtype(typeRep<Null>(), typeRep<Object>());
   // Null <: A
-  checkProperSubtype(Null, A);
+  checkProperSubtype(typeRep<Null>(), typeRep<A>());
   // Null <: FutureOr<A>
-  checkProperSubtype(Null, futureOrOf(A));
+  checkProperSubtype(typeRep<Null>(), typeRep<FutureOr<A>>());
   // Null <: Future<A>
-  checkProperSubtype(Null, generic1(Future, A));
+  checkProperSubtype(typeRep<Null>(), typeRep<Future<A>>());
   // FutureOr<Null> <: Future<Null>
-  checkSubtype(futureOrOf(Null), generic1(Future, Null));
+  checkSubtype(typeRep<FutureOr<Null>>(), typeRep<Future<Null>>());
   // Null <: Future<A?>
-  checkProperSubtype(Null, generic1(Future, nullable(A)));
+  checkProperSubtype(typeRep<Null>(), typeRep<Future<A?>>());
   // FutureOr<Object?> <: Object
-  checkSubtype(futureOrOf(nullable(Object)), Object);
+  checkSubtype(typeRep<FutureOr<Object?>>(), typeRep<Object>());
   // FutureOr<dynamic> <: Object
-  checkSubtype(futureOrOf(dynamic), Object);
+  checkSubtype(typeRep<FutureOr<dynamic>>(), typeRep<Object>());
   // FutureOr<void> <: Object
-  checkSubtype(futureOrOf(voidType), Object);
+  checkSubtype(typeRep<FutureOr<void>>(), typeRep<Object>());
 }
diff --git a/tests/compiler/dartdevc_native/runtime_utils.dart b/tests/compiler/dartdevc_native/runtime_utils.dart
index b5a32c0..5b14053 100644
--- a/tests/compiler/dartdevc_native/runtime_utils.dart
+++ b/tests/compiler/dartdevc_native/runtime_utils.dart
@@ -2,101 +2,50 @@
 // for details. 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:_foreign_helper' show JS;
-import 'dart:_runtime' as dart;
+import 'dart:_runtime' show gFnType, typeRep, isSubtypeOf;
 
-import 'dart:async' show FutureOr;
 import 'package:expect/expect.dart';
 
-// Function type used to extract the FutureOr now that a raw FutureOr gets
-// normalized away.
-typedef _futureOrReturn = FutureOr<int> Function();
-
-// The runtime representation of the void type.
-final voidType = dart.wrapType(dart.void_);
-
-/// Unwrap the user code type representation to expose the runtime
-/// representation of [t].
+/// Returns an unwrapped generic function type with a bounded type argument in
+/// the form: <T extends [bound]> void -> void.
 ///
-/// Generic functions are unchanged, as they have a separate runtime type object representation.
-Object unwrap(Type t) {
-  if (t is dart.GenericFunctionType) {
-    return t;
-  }
-  return dart.unwrapType(t);
-}
+// TODO(nshahan): The generic function type is created as a legacy type.
+genericFunction(bound) => gFnType((T) => [typeRep<void>(), []], (T) => [bound]);
 
-Type futureOrOf(Type tWrapped) {
-  var t = unwrap(tWrapped);
-  var f = unwrap(_futureOrReturn);
-  // Extract a raw FutureOr from an existing use.
-  var futureOrGeneric = dart.getGenericClass(JS('', '#.returnType', f));
-  return dart.wrapType(JS('', '#(#)', futureOrGeneric, t));
-}
-
-// Returns sWrapped<tWrapped> as a wrapped type.
-Type generic1(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  var sGeneric = dart.getGenericClass(s);
-  return dart.wrapType(JS('', '#(#)', sGeneric, t));
-}
-
-// Returns sWrapped<tWrapped, rWrapped> as a wrapped type.
-Type generic2(Type sWrapped, Type tWrapped, Type rWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  var r = unwrap(rWrapped);
-  var sGeneric = dart.getGenericClass(s);
-  return dart.wrapType(JS('', '#(#, #)', sGeneric, t, r));
-}
-
-// Returns a function type of argWrapped -> returnWrapped as a wrapped type.
-Type function1(Type returnWrapped, Type argWrapped) {
-  var returnType = unwrap(returnWrapped);
-  var argType = unwrap(argWrapped);
-  var fun = dart.fnType(returnType, [argType]);
-  return dart.wrapType(fun);
-}
-
-// Returns a function type with a bounded type argument that takes no argument
-// and returns void as a wrapped type.
-Type genericFunction(Type boundWrapped) =>
-    dart.gFnType((T) => [dart.VoidType, []], (T) => [unwrap(boundWrapped)]);
-
-// Returns a function type with a bounded generic return type of
-// <T extends boundWrapped> argWrapped -> T as a wrapped type.
-Type functionGenericReturn(Type boundWrapped, Type argWrapped) => dart.gFnType(
+/// Returns an unwrapped generic function type with a bounded type argument in
+/// the form: <T extends [bound]> [argumentType] -> T.
+///
+// TODO(nshahan): The generic function type is created as a legacy type.
+functionGenericReturn(bound, argumentType) => gFnType(
     (T) => [
           T,
-          [unwrap(argWrapped)]
+          [argumentType]
         ],
-    (T) => [unwrap(boundWrapped)]);
+    (T) => [bound]);
 
-// Returns a function with a bounded generic argument type of
-// <T extends boundWrapped> T -> returnWrapped as a wrapped type.
-Type functionGenericArg(Type boundWrapped, Type returnWrapped) => dart.gFnType(
+/// Returns an unwrapped generic function type with a bounded type argument in
+/// the form: <T extends [bound]> T -> [returnType].
+///
+// TODO(nshahan): The generic function type is created as a legacy type.
+functionGenericArg(bound, returnType) => gFnType(
     (T) => [
-          unwrap(returnWrapped),
+          returnType,
           [T]
         ],
-    (T) => [unwrap(boundWrapped)]);
+    (T) => [bound]);
 
-void checkSubtype(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  Expect.isTrue(dart.isSubtypeOf(s, t), '$s should be subtype of $t.');
+void checkSubtype(s, t) =>
+    Expect.isTrue(isSubtypeOf(s, t), '$s should be subtype of $t.');
+
+void checkProperSubtype(s, t) {
+  Expect.isTrue(isSubtypeOf(s, t), '$s should be subtype of $t.');
+  checkSubtypeFailure(t, s);
 }
 
-void checkProperSubtype(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  Expect.isTrue(dart.isSubtypeOf(s, t), '$s should be subtype of $t.');
-  checkSubtypeFailure(tWrapped, sWrapped);
+void checkMutualSubtype(Object s, Object t) {
+  Expect.isTrue(isSubtypeOf(s, t), '$s should be subtype of $t.');
+  Expect.isTrue(isSubtypeOf(t, s), '$t should be subtype of $s.');
 }
 
-void checkSubtypeFailure(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  Expect.isFalse(dart.isSubtypeOf(s, t), '$s should not be subtype of $t.');
-}
+void checkSubtypeFailure(s, t) =>
+    Expect.isFalse(isSubtypeOf(s, t), '$s should not be subtype of $t.');
diff --git a/tests/compiler/dartdevc_native/runtime_utils_nnbd.dart b/tests/compiler/dartdevc_native/runtime_utils_nnbd.dart
index 47dd2bc..3d10655 100644
--- a/tests/compiler/dartdevc_native/runtime_utils_nnbd.dart
+++ b/tests/compiler/dartdevc_native/runtime_utils_nnbd.dart
@@ -3,110 +3,27 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:_foreign_helper' show JS;
-import 'dart:_runtime' as dart;
+import 'dart:_runtime' show gFnType, typeRep;
 
-import 'package:expect/expect.dart';
+/// Returns an unwrapped generic function type with a bounded type argument in
+/// the form: <T extends [bound]> void -> void.
+Object genericFunction(Object bound) =>
+    gFnType((T) => [typeRep<void>(), []], (T) => [bound]);
 
-/// Unwrap the user code type representation to expose the runtime
-/// representation of [t].
-///
-/// Legacy types (produced by the legacy helper below) are returned unchanged
-/// because they are created unwrapped since wrapping will strip the legacy from
-/// them by design.
-/// Generic functions are also unchanged, as they have a separate runtime type object representation.
-Object unwrap(Type t) {
-  if (JS<bool>('!', '# instanceof #', t, dart.LegacyType) ||
-      JS<bool>('!', '# instanceof #', t, dart.GenericFunctionType)) {
-    return t;
-  }
-  return dart.unwrapType(t);
-}
-
-/// Returns tWrapped? as a wrapped type.
-Type nullable(Type tWrapped) {
-  var t = unwrap(tWrapped);
-  var tNullable = dart.nullable(t);
-  return dart.wrapType(tNullable);
-}
-
-/// Returns tWrapped* as an *unwrapped* type when it produces a legacy type, and
-/// a *wrapped* type when the legacy has been normalized away.
-///
-/// For example DDC does not create a legacy dynamic type, only dynamic.
-///
-/// This is the only helper to return an unwrapped version of a type because
-/// wrapping a legacy type will strip off the legacy by design.
-Type legacy(Type tWrapped) {
-  var t = unwrap(tWrapped);
-  var tLegacy = dart.legacy(t);
-  // During normalization some types never get created as legacy versions.
-  // Ex: dynamic.
-  return tLegacy is dart.LegacyType ? tLegacy : dart.wrapType(tLegacy);
-}
-
-// Returns sWrapped<tWrapped> as a wrapped type.
-Type generic1(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  var sGeneric = dart.getGenericClass(s);
-  return dart.wrapType(JS('', '#(#)', sGeneric, t));
-}
-
-// Returns sWrapped<tWrapped, rWrapped> as a wrapped type.
-Type generic2(Type sWrapped, Type tWrapped, Type rWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  var r = unwrap(rWrapped);
-  var sGeneric = dart.getGenericClass(s);
-  return dart.wrapType(JS('', '#(#, #)', sGeneric, t, r));
-}
-
-// Returns a function type of argWrapped -> returnWrapped as a wrapped type.
-Type function1(Type returnWrapped, Type argWrapped) {
-  var returnType = unwrap(returnWrapped);
-  var argType = unwrap(argWrapped);
-  var fun = dart.fnType(returnType, [argType]);
-  return dart.wrapType(fun);
-}
-
-// Returns a function type with a bounded type argument that takes no argument
-// and returns void as a wrapped type.
-Type genericFunction(Type boundWrapped) =>
-    dart.gFnType((T) => [dart.VoidType, []], (T) => [unwrap(boundWrapped)]);
-
-// Returns a function type with a bounded generic return type of
-// <T extends boundWrapped> argWrapped -> T as a wrapped type.
-Type functionGenericReturn(Type boundWrapped, Type argWrapped) => dart.gFnType(
+/// Returns an unwrapped generic function type with a bounded type argument in
+/// the form: <T extends [bound]> [argumentType] -> T.
+Object functionGenericReturn(Object bound, Object argType) => gFnType(
     (T) => [
           T,
-          [unwrap(argWrapped)]
+          [argType]
         ],
-    (T) => [unwrap(boundWrapped)]);
+    (T) => [bound]);
 
-// Returns a function with a bounded generic argument type of
-// <T extends boundWrapped> T -> returnWrapped as a wrapped type.
-Type functionGenericArg(Type boundWrapped, Type returnWrapped) => dart.gFnType(
+/// Returns an unwrapped generic function type with a bounded type argument in
+/// the form: <T extends [bound]> T -> [returnType].
+Object functionGenericArg(Object bound, Object returnType) => gFnType(
     (T) => [
-          unwrap(returnWrapped),
+          returnType,
           [T]
         ],
-    (T) => [unwrap(boundWrapped)]);
-
-void checkSubtype(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  Expect.isTrue(dart.isSubtypeOf(s, t), '$s should be subtype of $t.');
-}
-
-void checkProperSubtype(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  Expect.isTrue(dart.isSubtypeOf(s, t), '$s should be subtype of $t.');
-  checkSubtypeFailure(tWrapped, sWrapped);
-}
-
-void checkSubtypeFailure(Type sWrapped, Type tWrapped) {
-  var s = unwrap(sWrapped);
-  var t = unwrap(tWrapped);
-  Expect.isFalse(dart.isSubtypeOf(s, t), '$s should not be subtype of $t.');
-}
+    (T) => [bound]);
diff --git a/tests/compiler/dartdevc_native/subtype_test.dart b/tests/compiler/dartdevc_native/subtype_test.dart
index 93d7ebc7..51e0c75 100644
--- a/tests/compiler/dartdevc_native/subtype_test.dart
+++ b/tests/compiler/dartdevc_native/subtype_test.dart
@@ -4,7 +4,8 @@
 
 // @dart = 2.6
 
-import 'dart:async';
+import 'dart:_runtime' show typeRep;
+import 'dart:async' show FutureOr;
 
 import 'runtime_utils.dart';
 
@@ -22,122 +23,128 @@
 
 void main() {
   // A <: dynamic
-  checkProperSubtype(A, dynamic);
+  checkProperSubtype(typeRep<A>(), typeRep<dynamic>());
   // A <: Object
-  checkProperSubtype(A, Object);
-  // TODO(nshahan) Test void as top? A <: void
+  checkProperSubtype(typeRep<A>(), typeRep<Object>());
+  // A <: Object
+  checkProperSubtype(typeRep<A>(), typeRep<void>());
 
   // Null <: A
-  checkProperSubtype(Null, A);
+  checkProperSubtype(typeRep<Null>(), typeRep<A>());
 
   // FutureOr<Null> <: Future<Null>
-  checkSubtype(futureOrOf(Null), generic1(Future, Null));
+  checkSubtype(typeRep<FutureOr<Null>>(), typeRep<Future<Null>>());
   // Future<Null> <: FutureOr<Null>
-  checkSubtype(generic1(Future, Null), futureOrOf(Null));
+  checkSubtype(typeRep<Future<Null>>(), typeRep<FutureOr<Null>>());
   // Future<B> <: FutureOr<A>
-  checkProperSubtype(generic1(Future, B), futureOrOf(A));
+  checkProperSubtype(typeRep<Future<B>>(), typeRep<FutureOr<A>>());
   // B <: <: FutureOr<A>
-  checkProperSubtype(B, futureOrOf(A));
+  checkProperSubtype(typeRep<B>(), typeRep<FutureOr<A>>());
   // Future<B> <: Future<A>
-  checkProperSubtype(generic1(Future, B), generic1(Future, A));
+  checkProperSubtype(typeRep<Future<B>>(), typeRep<Future<A>>());
   // B <: A
-  checkProperSubtype(B, A);
+  checkProperSubtype(typeRep<B>(), typeRep<A>());
 
   // A <: A
-  checkSubtype(A, A);
+  checkSubtype(typeRep<A>(), typeRep<A>());
   // C <: B
-  checkProperSubtype(C, B);
+  checkProperSubtype(typeRep<C>(), typeRep<B>());
   // C <: A
-  checkProperSubtype(C, A);
+  checkProperSubtype(typeRep<C>(), typeRep<A>());
 
   // A -> B <: Function
-  checkProperSubtype(function1(B, A), Function);
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<Function>());
 
   // A -> B <: A -> B
-  checkSubtype(function1(B, A), function1(B, A));
+  checkSubtype(typeRep<B Function(A)>(), typeRep<B Function(A)>());
 
   // A -> B <: B -> B
-  checkProperSubtype(function1(B, A), function1(B, B));
-  // TODO(nshahan) Subtype check with covariant keyword?
+  checkProperSubtype(typeRep<B Function(A)>(), typeRep<B Function(B)>());
 
   // A -> B <: A -> A
-  checkSubtype(function1(B, A), function1(A, A));
+  checkSubtype(typeRep<B Function(A)>(), typeRep<A Function(A)>());
 
   // Generic Function Subtypes.
   // Bound is a built in type.
   // <T extends int> void -> void <: <T extends int> void -> void
-  checkSubtype(genericFunction(int), genericFunction(int));
+  checkSubtype(
+      genericFunction(typeRep<int>()), genericFunction(typeRep<int>()));
 
   // <T extends String> A -> T <: <T extends String> B -> T
-  checkProperSubtype(
-      functionGenericReturn(String, A), functionGenericReturn(String, B));
+  checkProperSubtype(functionGenericReturn(typeRep<String>(), typeRep<A>()),
+      functionGenericReturn(typeRep<String>(), typeRep<B>()));
 
   // <T extends double> T -> B <: <T extends double> T -> A
-  checkProperSubtype(
-      functionGenericArg(double, B), functionGenericArg(double, A));
+  checkProperSubtype(functionGenericArg(typeRep<double>(), typeRep<B>()),
+      functionGenericArg(typeRep<double>(), typeRep<A>()));
 
   // Bound is a function type.
   // <T extends A -> B> void -> void <: <T extends A -> B> void -> void
-  checkSubtype(
-      genericFunction(function1(B, A)), genericFunction(function1(B, A)));
+  checkSubtype(genericFunction(typeRep<B Function(A)>()),
+      genericFunction(typeRep<B Function(A)>()));
 
   // <T extends A -> B> A -> T <: <T extends A -> B> B -> T
-  checkProperSubtype(functionGenericReturn(function1(B, A), A),
-      functionGenericReturn(function1(B, A), B));
+  checkProperSubtype(
+      functionGenericReturn(typeRep<B Function(A)>(), typeRep<A>()),
+      functionGenericReturn(typeRep<B Function(A)>(), typeRep<B>()));
 
   // <T extends A -> B> T -> B <: <T extends A -> B> T -> A
-  checkProperSubtype(functionGenericArg(function1(B, A), B),
-      functionGenericArg(function1(B, A), A));
+  checkProperSubtype(functionGenericArg(typeRep<B Function(A)>(), typeRep<B>()),
+      functionGenericArg(typeRep<B Function(A)>(), typeRep<A>()));
 
   // Bound is a user defined class.
   // <T extends B> void -> void <: <T extends B> void -> void
-  checkSubtype(genericFunction(B), genericFunction(B));
+  checkSubtype(genericFunction(typeRep<B>()), genericFunction(typeRep<B>()));
 
   // <T extends B> A -> T <: <T extends B> B -> T
-  checkProperSubtype(functionGenericReturn(B, A), functionGenericReturn(B, B));
+  checkProperSubtype(functionGenericReturn(typeRep<B>(), typeRep<A>()),
+      functionGenericReturn(typeRep<B>(), typeRep<B>()));
 
   // <T extends B> T -> B <: <T extends B> T -> A
-  checkProperSubtype(functionGenericArg(B, B), functionGenericArg(B, A));
+  checkProperSubtype(functionGenericArg(typeRep<B>(), typeRep<B>()),
+      functionGenericArg(typeRep<B>(), typeRep<A>()));
 
   // Bound is a Future.
   // <T extends Future<B>> void -> void <: <T extends Future<B>> void -> void
-  checkSubtype(genericFunction(generic1(Future, B)),
-      genericFunction(generic1(Future, B)));
+  checkSubtype(genericFunction(typeRep<Future<B>>()),
+      genericFunction(typeRep<Future<B>>()));
 
   // <T extends Future<B>> A -> T <: <T extends Future<B>> B -> T
-  checkProperSubtype(functionGenericReturn(generic1(Future, B), A),
-      functionGenericReturn(generic1(Future, B), B));
+  checkProperSubtype(functionGenericReturn(typeRep<Future<B>>(), typeRep<A>()),
+      functionGenericReturn(typeRep<Future<B>>(), typeRep<B>()));
 
   // <T extends Future<B>> T -> B <: <T extends Future<B>> T -> A
-  checkProperSubtype(functionGenericArg(generic1(Future, B), B),
-      functionGenericArg(generic1(Future, B), A));
+  checkProperSubtype(functionGenericArg(typeRep<Future<B>>(), typeRep<B>()),
+      functionGenericArg(typeRep<Future<B>>(), typeRep<A>()));
 
   // Bound is a FutureOr.
   // <T extends FutureOr<B>> void -> void <:
   //    <T extends FutureOr<B>> void -> void
-  checkSubtype(genericFunction(futureOrOf(B)), genericFunction(futureOrOf(B)));
+  checkSubtype(genericFunction(typeRep<FutureOr<B>>()),
+      genericFunction(typeRep<FutureOr<B>>()));
 
   // <T extends FutureOr<B>> A -> T <: <T extends FutureOr<B>> B -> T
-  checkProperSubtype(functionGenericReturn(futureOrOf(B), A),
-      functionGenericReturn(futureOrOf(B), B));
+  checkProperSubtype(
+      functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<A>()),
+      functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<B>()));
 
   // <T extends FutureOr<B>> T -> B <: <T extends FutureOr<B>> T -> A
-  checkProperSubtype(functionGenericArg(futureOrOf(B), B),
-      functionGenericArg(futureOrOf(B), A));
+  checkProperSubtype(functionGenericArg(typeRep<FutureOr<B>>(), typeRep<B>()),
+      functionGenericArg(typeRep<FutureOr<B>>(), typeRep<A>()));
 
   // D <: D<B>
-  checkSubtype(D, generic1(D, B));
+  checkSubtype(typeRep<D>(), typeRep<D<B>>());
   // D<B> <: D
-  checkSubtype(generic1(D, B), D);
+  checkSubtype(typeRep<D<B>>(), typeRep<D>());
   // D<C> <: D<B>
-  checkProperSubtype(generic1(D, C), generic1(D, B));
+  checkSubtype(typeRep<D<C>>(), typeRep<D<B>>());
 
   // F <: E
-  checkProperSubtype(F, E);
+  checkProperSubtype(typeRep<F>(), typeRep<E>());
   // F <: E<A, A>
-  checkProperSubtype(F, generic2(E, A, A));
+  checkProperSubtype(typeRep<F>(), typeRep<E<A, A>>());
+  // E<B, B> <: E
+  checkProperSubtype(typeRep<E<B, B>>(), typeRep<E>());
   // // E<B, B> <: E<A, A>
-  checkProperSubtype(generic2(E, B, B), E);
-  // // E<B, B> <: E<A, A>
-  checkProperSubtype(generic2(E, B, B), generic2(E, A, A));
+  checkProperSubtype(typeRep<E<B, B>>(), typeRep<E<A, A>>());
 }
diff --git a/tests/compiler/dartdevc_native/variance_subtype_test.dart b/tests/compiler/dartdevc_native/variance_subtype_test.dart
index 96090bb..b930484 100644
--- a/tests/compiler/dartdevc_native/variance_subtype_test.dart
+++ b/tests/compiler/dartdevc_native/variance_subtype_test.dart
@@ -8,143 +8,184 @@
 
 // Tests runtime subtyping with explicit variance modifiers.
 
-import 'dart:async';
+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(generic1(Covariant, Lower), generic1(Covariant, Middle));
+  checkProperSubtype(typeRep<Covariant<Lower>>(), typeRep<Covariant<Middle>>());
 
   // Covariant<Middle> <: Covariant<Middle>
-  checkSubtype(generic1(Covariant, Middle), generic1(Covariant, Middle));
+  checkSubtype(typeRep<Covariant<Middle>>(), typeRep<Covariant<Middle>>());
 
   // Contravariant<Upper> <: Contravariant<Middle>
-  checkProperSubtype(generic1(Contravariant, Upper), generic1(Contravariant, Middle));
+  checkProperSubtype(
+      typeRep<Contravariant<Upper>>(), typeRep<Contravariant<Middle>>());
 
   // Contravariant<Middle> <: Contravariant<Middle>
-  checkSubtype(generic1(Contravariant, Middle), generic1(Contravariant, Middle));
+  checkSubtype(
+      typeRep<Contravariant<Middle>>(), typeRep<Contravariant<Middle>>());
 
   // Invariant<Middle> <: Invariant<Middle>
-  checkSubtype(generic1(Invariant, Middle), generic1(Invariant, Middle));
+  checkSubtype(typeRep<Invariant<Middle>>(), typeRep<Invariant<Middle>>());
 
   // Invariant<dynamic> <:> Invariant<Object>
-  checkSubtype(generic1(Invariant, dynamic), generic1(Invariant, Object));
-  checkSubtype(generic1(Invariant, Object), generic1(Invariant, dynamic));
+  checkMutualSubtype(
+      typeRep<Invariant<dynamic>>(), typeRep<Invariant<Object>>());
 
   // Invariant<FutureOr<dynamic>> <:> Invariant<dynamic>
-  checkSubtype(generic1(Invariant, futureOrOf(dynamic)), generic1(Invariant, dynamic));
-  checkSubtype(generic1(Invariant, dynamic), generic1(Invariant, futureOrOf(dynamic)));
+  checkMutualSubtype(
+      typeRep<Invariant<FutureOr<dynamic>>>(), typeRep<Invariant<dynamic>>());
 
   // Invariant<FutureOr<Null>> <:> Invariant<Future<Null>>
-  checkSubtype(generic1(Invariant, futureOrOf(Null)), generic1(Invariant, generic1(Future, Null)));
-  checkSubtype(generic1(Invariant, generic1(Future, Null)), generic1(Invariant, futureOrOf(Null)));
+  checkMutualSubtype(
+      typeRep<Invariant<FutureOr<Null>>>(), typeRep<Invariant<Future<Null>>>());
 
   // LegacyCovariant<Lower> <: LegacyCovariant<Middle>
-  checkProperSubtype(generic1(LegacyCovariant, Lower), generic1(LegacyCovariant, Middle));
+  checkProperSubtype(
+      typeRep<LegacyCovariant<Lower>>(), typeRep<LegacyCovariant<Middle>>());
 
   // List<Covariant<Lower>> <: Iterable<Covariant<Middle>>
-  checkProperSubtype(generic1(List, generic1(Covariant, Lower)), generic1(Iterable, generic1(Covariant, Middle)));
+  checkProperSubtype(typeRep<List<Covariant<Lower>>>(),
+      typeRep<Iterable<Covariant<Middle>>>());
 
   // List<Contravariant<Upper>> <: Iterable<Contravariant<Middle>>
-  checkProperSubtype(generic1(List, generic1(Contravariant, Upper)), generic1(Iterable, generic1(Contravariant, Middle)));
+  checkProperSubtype(typeRep<List<Contravariant<Upper>>>(),
+      typeRep<Iterable<Contravariant<Middle>>>());
 
   // List<Invariant<Middle>> <: Iterable<Invariant<Middle>>
-  checkProperSubtype(generic1(List, generic1(Invariant, Middle)), generic1(Iterable, generic1(Invariant, Middle)));
+  checkProperSubtype(typeRep<List<Invariant<Middle>>>(),
+      typeRep<Iterable<Invariant<Middle>>>());
 
   // List<LegacyCovariant<Lower>> <: Iterable<LegacyCovariant<Middle>>
-  checkProperSubtype(generic1(List, generic1(LegacyCovariant, Lower)), generic1(Iterable, generic1(LegacyCovariant, Middle)));
+  checkProperSubtype(typeRep<List<LegacyCovariant<Lower>>>(),
+      typeRep<Iterable<LegacyCovariant<Middle>>>());
 
   // String -> Covariant<Lower> <: String -> Covariant<Middle>
-  checkProperSubtype(function1(generic1(Covariant, Lower), String), function1(generic1(Covariant, Middle), String));
+  checkProperSubtype(typeRep<Covariant<Lower> Function(String)>(),
+      typeRep<Covariant<Middle> Function(String)>());
 
   // Covariant<Upper> -> String <: Covariant<Middle> -> String
-  checkProperSubtype(function1(String, generic1(Covariant, Upper)), function1(String, generic1(Covariant, Middle)));
+  checkProperSubtype(typeRep<String Function(Covariant<Upper>)>(),
+      typeRep<String Function(Covariant<Middle>)>());
 
   // String -> Contravariant<Upper> <: String -> Contravariant<Middle>
-  checkProperSubtype(function1(generic1(Contravariant, Upper), String), function1(generic1(Contravariant, Middle), String));
+  checkProperSubtype(typeRep<Contravariant<Upper> Function(String)>(),
+      typeRep<Contravariant<Middle> Function(String)>());
 
   // Contravariant<Lower> -> String <: Contravariant<Middle> -> String
-  checkProperSubtype(function1(String, generic1(Contravariant, Lower)), function1(String, generic1(Contravariant, Middle)));
+  checkProperSubtype(typeRep<String Function(Contravariant<Lower>)>(),
+      typeRep<String Function(Contravariant<Middle>)>());
 
   // String -> Invariant<Middle> <: String -> Invariant<Middle>
-  checkSubtype(function1(generic1(Invariant, Middle), String), function1(generic1(Invariant, Middle), String));
+  checkSubtype(typeRep<String Function(Invariant<Middle>)>(),
+      typeRep<String Function(Invariant<Middle>)>());
 
   // Invariant<Middle> -> String <: Invariant<Middle> -> String
-  checkSubtype(function1(String, generic1(Invariant, Middle)), function1(String, generic1(Invariant, Middle)));
+  checkSubtype(typeRep<String Function(Invariant<Middle>)>(),
+      typeRep<String Function(Invariant<Middle>)>());
 
   // String -> LegacyCovariant<Lower> <: String -> LegacyCovariant<Middle>
-  checkProperSubtype(function1(generic1(LegacyCovariant, Lower), String), function1(generic1(LegacyCovariant, Middle), String));
+  checkProperSubtype(typeRep<LegacyCovariant<Lower> Function(String)>(),
+      typeRep<LegacyCovariant<Middle> Function(String)>());
 
   // LegacyCovariant<Upper> -> String <: LegacyCovariant<Middle> -> String
-  checkProperSubtype(function1(String, generic1(LegacyCovariant, Upper)), function1(String, generic1(LegacyCovariant, Middle)));
+  checkProperSubtype(typeRep<String Function(LegacyCovariant<Upper>)>(),
+      typeRep<String Function(LegacyCovariant<Middle>)>());
 
   // Covariant<Upper> </: Covariant<Middle>
-  checkSubtypeFailure(generic1(Covariant, Upper), generic1(Covariant, Middle));
+  checkSubtypeFailure(
+      typeRep<Covariant<Upper>>(), typeRep<Covariant<Middle>>());
 
   // Contravariant<Lower> </: Contravariant<Middle>
-  checkSubtypeFailure(generic1(Contravariant, Lower), generic1(Contravariant, Middle));
+  checkSubtypeFailure(
+      typeRep<Contravariant<Lower>>(), typeRep<Contravariant<Middle>>());
 
   // Invariant<Upper> </: Invariant<Middle>
-  checkSubtypeFailure(generic1(Invariant, Upper), generic1(Invariant, Middle));
+  checkSubtypeFailure(
+      typeRep<Invariant<Upper>>(), typeRep<Invariant<Middle>>());
 
   // Invariant<Lower> </: Invariant<Middle>
-  checkSubtypeFailure(generic1(Invariant, Lower), generic1(Invariant, Middle));
+  checkSubtypeFailure(
+      typeRep<Invariant<Lower>>(), typeRep<Invariant<Middle>>());
 
   // LegacyCovariant<Upper> </: LegacyCovariant<Middle>
-  checkSubtypeFailure(generic1(LegacyCovariant, Upper), generic1(LegacyCovariant, Middle));
+  checkSubtypeFailure(
+      typeRep<LegacyCovariant<Upper>>(), typeRep<LegacyCovariant<Middle>>());
 
   // List<Covariant<Upper>> </: Iterable<Covariant<Middle>>
-  checkSubtypeFailure(generic1(List, generic1(Covariant, Upper)), generic1(Iterable, generic1(Covariant, Middle)));
+  checkSubtypeFailure(typeRep<List<Covariant<Upper>>>(),
+      typeRep<Iterable<Covariant<Middle>>>());
 
   // List<Contravariant<Lower>> </: Iterable<Contravariant<Middle>>
-  checkSubtypeFailure(generic1(List, generic1(Contravariant, Lower)), generic1(Iterable, generic1(Contravariant, Middle)));
+  checkSubtypeFailure(typeRep<List<Contravariant<Lower>>>(),
+      typeRep<Iterable<Contravariant<Middle>>>());
 
   // List<Invariant<Upper>> </: Iterable<Invariant<Middle>>
-  checkSubtypeFailure(generic1(List, generic1(Invariant, Upper)), generic1(Iterable, generic1(Invariant, Middle)));
+  checkSubtypeFailure(typeRep<List<Invariant<Upper>>>(),
+      typeRep<Iterable<Invariant<Middle>>>());
 
   // List<Invariant<Lower>> </: Iterable<Invariant<Middle>>
-  checkSubtypeFailure(generic1(List, generic1(Invariant, Lower)), generic1(Iterable, generic1(Invariant, Middle)));
+  checkSubtypeFailure(typeRep<List<Invariant<Lower>>>(),
+      typeRep<Iterable<Invariant<Middle>>>());
 
   // List<LegacyCovariant<Upper>> </: Iterable<LegacyCovariant<Middle>>
-  checkSubtypeFailure(generic1(List, generic1(LegacyCovariant, Upper)), generic1(Iterable, generic1(LegacyCovariant, Middle)));
+  checkSubtypeFailure(typeRep<List<LegacyCovariant<Upper>>>(),
+      typeRep<Iterable<LegacyCovariant<Middle>>>());
 
   // String -> Covariant<Upper> </: String -> Covariant<Middle>
-  checkSubtypeFailure(function1(generic1(Covariant, Upper), String), function1(generic1(Covariant, Middle), String));
+  checkSubtypeFailure(typeRep<Covariant<Upper> Function(String)>(),
+      typeRep<Covariant<Middle> Function(String)>());
 
   // Covariant<Lower> -> String </: Covariant<Middle> -> String
-  checkSubtypeFailure(function1(String, generic1(Covariant, Lower)), function1(String, generic1(Covariant, Middle)));
+  checkSubtypeFailure(typeRep<String Function(Covariant<Lower>)>(),
+      typeRep<String Function(Covariant<Middle>)>());
 
   // String -> Contravariant<Lower> </: String -> Contravariant<Middle>
-  checkSubtypeFailure(function1(generic1(Contravariant, Lower), String), function1(generic1(Contravariant, Middle), String));
+  checkSubtypeFailure(typeRep<Contravariant<Lower> Function(String)>(),
+      typeRep<Contravariant<Middle> Function(String)>());
 
   // Contravariant<Upper> -> String </: Contravariant<Middle> -> String
-  checkSubtypeFailure(function1(String, generic1(Contravariant, Upper)), function1(String, generic1(Contravariant, Middle)));
+  checkSubtypeFailure(typeRep<String Function(Contravariant<Upper>)>(),
+      typeRep<String Function(Contravariant<Middle>)>());
 
   // String -> Invariant<Upper> </: String -> Invariant<Middle>
-  checkSubtypeFailure(function1(generic1(Invariant, Upper), String), function1(generic1(Invariant, Middle), String));
+  checkSubtypeFailure(typeRep<Invariant<Upper> Function(String)>(),
+      typeRep<Invariant<Middle> Function(String)>());
 
   // Invariant<Upper> -> String </: Invariant<Middle> -> String
-  checkSubtypeFailure(function1(String, generic1(Invariant, Upper)), function1(String, generic1(Invariant, Middle)));
+  checkSubtypeFailure(typeRep<String Function(Invariant<Upper>)>(),
+      typeRep<String Function(Invariant<Middle>)>());
 
   // String -> Invariant<Lower> </: String -> Invariant<Middle>
-  checkSubtypeFailure(function1(generic1(Invariant, Lower), String), function1(generic1(Invariant, Middle), String));
+  checkSubtypeFailure(typeRep<Invariant<Lower> Function(String)>(),
+      typeRep<Invariant<Middle> Function(String)>());
 
   // Invariant<Lower> -> String <: Invariant<Middle> -> String
-  checkSubtypeFailure(function1(String, generic1(Invariant, Lower)), function1(String, generic1(Invariant, Middle)));
+  checkSubtypeFailure(typeRep<String Function(Invariant<Lower>)>(),
+      typeRep<String Function(Invariant<Middle>)>());
 
   // String -> LegacyCovariant<Upper> </: String -> LegacyCovariant<Middle>
-  checkSubtypeFailure(function1(generic1(LegacyCovariant, Upper), String), function1(generic1(LegacyCovariant, Middle), String));
+  checkSubtypeFailure(typeRep<LegacyCovariant<Upper> Function(String)>(),
+      typeRep<LegacyCovariant<Middle> Function(String)>());
 
   // LegacyCovariant<Lower> -> String </: LegacyCovariant<Middle> -> String
-  checkSubtypeFailure(function1(String, generic1(LegacyCovariant, Lower)), function1(String, generic1(LegacyCovariant, Middle)));
+  checkSubtypeFailure(typeRep<String Function(LegacyCovariant<Lower>)>(),
+      typeRep<String Function(LegacyCovariant<Middle>)>());
 }
diff --git a/tests/compiler/dartdevc_native/variance_test.dart b/tests/compiler/dartdevc_native/variance_test.dart
index b649ca3..ac2e683 100644
--- a/tests/compiler/dartdevc_native/variance_test.dart
+++ b/tests/compiler/dartdevc_native/variance_test.dart
@@ -8,7 +8,8 @@
 
 // Tests the emission of explicit variance modifiers.
 
-import 'dart:_runtime' as dart;
+import 'dart:_runtime'
+    show wrapType, unwrapType, getGenericArgVariances, Variance, typeRep;
 
 import 'package:expect/expect.dart';
 
@@ -26,31 +27,27 @@
 
 class G<inout T> = Object with F<T>;
 
-List getVariances(Type typeWrapped) {
-  var type = dart.unwrapType(typeWrapped);
-  return dart.getGenericArgVariances(type);
-}
-
-void checkVariances(List v1, List v2) {
-  Expect.equals(v1.length, v2.length);
-  for (int i = 0; i < v1.length; i++) {
-    Expect.equals(v1[i], v2[i]);
-  }
+List getVariances(Object t) {
+  // TODO(nshahan) Update to handle legacy wrapper when we unfork dart:_runtime.
+  var type = unwrapType(wrapType(t));
+  return getGenericArgVariances(type);
 }
 
 main() {
-  checkVariances(getVariances(A), [dart.Variance.contravariant]);
+  Expect.listEquals([Variance.contravariant], getVariances(typeRep<A>()));
 
-  checkVariances(getVariances(B), [dart.Variance.covariant]);
+  Expect.listEquals([Variance.covariant], getVariances(typeRep<B>()));
 
-  checkVariances(getVariances(C), [dart.Variance.invariant]);
+  Expect.listEquals([Variance.invariant], getVariances(typeRep<C>()));
 
   // Implicit variance is not emitted into the generated code.
-  Expect.isNull(getVariances(D));
+  Expect.isNull(getVariances(typeRep<D>()));
 
-  checkVariances(getVariances(E), [dart.Variance.invariant, dart.Variance.covariant, dart.Variance.contravariant]);
+  Expect.listEquals(
+      [Variance.invariant, Variance.covariant, Variance.contravariant],
+      getVariances(typeRep<E>()));
 
-  checkVariances(getVariances(F), [dart.Variance.contravariant]);
+  Expect.listEquals([Variance.contravariant], getVariances(typeRep<F>()));
 
-  checkVariances(getVariances(G), [dart.Variance.invariant]);
+  Expect.listEquals([Variance.invariant], getVariances(typeRep<G>()));
 }
diff --git a/tests/corelib/apply_generic_function_test.dart b/tests/corelib/apply_generic_function_test.dart
index b9e6e3e..ad75ee1 100644
--- a/tests/corelib/apply_generic_function_test.dart
+++ b/tests/corelib/apply_generic_function_test.dart
@@ -13,7 +13,7 @@
 
 main() {
   test(res, func, list, map) {
-    map = symbolMapToStringMap(map);
+    map = symbolToStringMap(map);
     Expect.equals(res, Function.apply(func, list, map));
   }
 
diff --git a/tests/corelib/apply_test.dart b/tests/corelib/apply_test.dart
index 0958dab..364f2f4 100644
--- a/tests/corelib/apply_test.dart
+++ b/tests/corelib/apply_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
-import "symbol_map_helper.dart";
 
 // Testing Function.apply calls correctly.
 // This test is not testing error handling, only that correct parameters
diff --git a/tests/corelib/cast_errors_test.dart b/tests/corelib/cast_errors_test.dart
new file mode 100644
index 0000000..0d75f28
--- /dev/null
+++ b/tests/corelib/cast_errors_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import 'cast_helper.dart';
+
+void main() {
+  testSetDowncast();
+  testMapDowncast();
+}
+
+void testSetDowncast() {
+  var setEls = new Set<C?>.from(elements);
+  var dSet = Set.castFrom<C?, D?>(setEls);
+
+  var newC = new C();
+  dSet.add(newC);
+  //       ^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'C' can't be assigned to the parameter type 'D?'.
+}
+
+void testMapDowncast() {
+  var map = new Map.fromIterables(elements, elements);
+  var dMap = Map.castFrom<C?, C?, D?, D?>(map);
+
+  dMap[c] = d;
+  //   ^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] A value of type 'C' can't be assigned to a variable of type 'D?'.
+  dMap[d] = c;
+  //        ^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+  // [cfe] A value of type 'C' can't be assigned to a variable of type 'D?'.
+}
diff --git a/tests/corelib/cast_helper.dart b/tests/corelib/cast_helper.dart
new file mode 100644
index 0000000..d0537da
--- /dev/null
+++ b/tests/corelib/cast_helper.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final elements = <C?>[c, d, e, f, null];
+
+class C {}
+
+class D extends C {}
+
+class E extends C {}
+
+class F implements D, E {}
+
+final c = C();
+final d = D();
+final e = E();
+final f = F();
diff --git a/tests/corelib/cast_iterable_test.dart b/tests/corelib/cast_iterable_test.dart
new file mode 100644
index 0000000..35ce89e
--- /dev/null
+++ b/tests/corelib/cast_iterable_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testDowncastDirectAccess();
+  testDowncastNoDirectAccess();
+  testDowncastUntouchableElements();
+  testUpcast();
+}
+
+void testDowncastDirectAccess() {
+  var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+
+  // An iterable that (likely) can do direct access.
+  var dIterable = Iterable.castFrom<C?, D?>(iterable);
+
+  Expect.throws(() => dIterable.first);
+  Expect.equals(d, dIterable.elementAt(1));
+  Expect.throws(() => dIterable.elementAt(2)); // E is not D?
+  Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+  Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+  Expect.throws(() => dIterable.toList());
+}
+
+void testDowncastNoDirectAccess() {
+  var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+
+  // An iterable that cannot do direct access.
+  var dIterable = Iterable.castFrom<C?, D?>(iterable.where((_) => true));
+
+  Expect.throws(() => dIterable.first);
+  Expect.equals(d, dIterable.elementAt(1));
+  // E is not D?.
+  Expect.throws(() => dIterable.elementAt(2));
+  Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+  Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+  Expect.throws(() => dIterable.toList());
+}
+
+void testDowncastUntouchableElements() {
+  // Iterable that definitely won't survive accessing element 3.
+  var iterable = new Iterable<C?>.generate(
+      elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+  var dIterable = Iterable.castFrom<C?, D?>(iterable);
+
+  Expect.throws(() => dIterable.first);
+  Expect.equals(d, dIterable.elementAt(1));
+  Expect.throws(() => dIterable.elementAt(3));
+  // Skip does not access element.
+  Expect.equals(null, dIterable.skip(4).first);
+  Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+  Expect.throws(() => dIterable.toList());
+}
+
+void testUpcast() {
+  var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+
+  var objectIterable = Iterable.castFrom<C?, Object?>(iterable);
+  Expect.listEquals(elements, objectIterable.toList());
+}
diff --git a/tests/corelib/cast_list_test.dart b/tests/corelib/cast_list_test.dart
new file mode 100644
index 0000000..c214685
--- /dev/null
+++ b/tests/corelib/cast_list_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testDowncast();
+  testUpcast();
+  testRegression();
+}
+
+void testDowncast() {
+  var list = new List<C?>.from(elements);
+  var dList = List.castFrom<C?, D?>(list);
+
+  Expect.throws(() => dList.first); // C is not D?.
+  Expect.equals(d, dList[1]);
+  Expect.throws(() => dList[2]); // E is not D?.
+  Expect.equals(f, dList[3]);
+  Expect.equals(null, dList.last);
+
+  Expect.throws(() => dList.toList());
+
+  // Setting works.
+  dList[2] = d;
+  Expect.equals(d, dList[2]);
+}
+
+void testUpcast() {
+  var list = new List<C?>.from(elements);
+  var objectList = List.castFrom<C?, Object?>(list);
+  Expect.listEquals(elements, objectList);
+  Expect.throws(() => objectList[2] = new Object()); // Cannot set non-C.
+  Expect.listEquals(elements, objectList);
+}
+
+void testRegression() {
+  var numList = <num>[4, 3, 2, 1];
+  var intList = numList.cast<int>();
+  intList.sort(null);
+  Expect.listEquals([1, 2, 3, 4], numList);
+  Expect.listEquals([1, 2, 3, 4], intList);
+}
diff --git a/tests/corelib/cast_map_test.dart b/tests/corelib/cast_map_test.dart
new file mode 100644
index 0000000..a827b0c
--- /dev/null
+++ b/tests/corelib/cast_map_test.dart
@@ -0,0 +1,57 @@
+// 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:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testDowncast();
+  testUpcast();
+}
+
+void testDowncast() {
+  var map = new Map.fromIterables(elements, elements);
+  var dMap = Map.castFrom<C?, C?, D?, D?>(map);
+
+  Expect.isTrue(dMap is Map<D?, D?>);
+
+  Expect.equals(null, dMap[new C()]);
+  Expect.throws(() => dMap[c]); // C is not D?.
+  Expect.isTrue(dMap.containsKey(c)); // containsKey should not be typed.
+  Expect.equals(d, dMap[d]);
+  Expect.throws(() => dMap[e]); // E is not D?.
+  Expect.isTrue(dMap.containsKey(null));
+  Expect.equals(null, dMap[null]);
+
+  Expect.equals(5, dMap.length);
+  Expect.throws(() => dMap.remove(c)); // Removes key but fails to return value.
+  Expect.equals(4, dMap.length);
+  Expect.equals(null, dMap[c]);
+
+  // Test keys and values.
+  Expect.isTrue(dMap.keys is Iterable<D?>);
+  Expect.isTrue(dMap.values is Iterable<D?>);
+  Expect.throws(() => dMap.keys.toList());
+  Expect.throws(() => dMap.values.toList());
+}
+
+void testUpcast() {
+  var map = new Map.fromIterables(elements, elements);
+  var objectMap = Map.castFrom<C?, C?, Object?, Object?>(map);
+
+  Expect.equals(5, objectMap.length);
+  Expect.equals(c, objectMap[c]);
+  Expect.isTrue(objectMap.containsKey(c));
+  Expect.equals(c, objectMap.remove(c));
+  Expect.equals(4, objectMap.length);
+
+  // Test keys and values.
+  Expect.isTrue(objectMap.keys is Iterable<Object?>);
+  Expect.isTrue(objectMap.values is Iterable<Object?>);
+  var expected = new List<Object?>.from(elements);
+  expected.remove(c);
+  Expect.listEquals(expected, objectMap.keys.toList());
+  Expect.listEquals(expected, objectMap.values.toList());
+}
diff --git a/tests/corelib/cast_set_test.dart b/tests/corelib/cast_set_test.dart
new file mode 100644
index 0000000..d33ccd73
--- /dev/null
+++ b/tests/corelib/cast_set_test.dart
@@ -0,0 +1,71 @@
+// 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:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testOrder();
+  testDowncast();
+  testUpcast();
+  testNewSet();
+}
+
+void testOrder() {
+  var setEls = new Set<C?>.from(elements); // Linked HashSet.
+  Expect.listEquals(elements, setEls.toList()); // Preserves order.
+}
+
+void testDowncast() {
+  var setEls = new Set<C?>.from(elements);
+  var dSet = Set.castFrom<C?, D?>(setEls);
+
+  // Preserves order.
+  Expect.throws(() => dSet.first); // C is not D?.
+  Expect.equals(d, dSet.elementAt(1));
+  Expect.throws(() => dSet.elementAt(2)); // E is not D?.
+  Expect.equals(f, dSet.elementAt(3));
+  Expect.equals(null, dSet.elementAt(4));
+
+  Expect.throws(() => dSet.toList());
+
+  // Contains should not be typed.
+  var newC = new C();
+  Expect.isFalse(dSet.contains(newC));
+  Expect.isTrue(dSet.contains(c));
+
+  // Remove and length should not be typed.
+  Expect.equals(5, dSet.length);
+  dSet.remove(c); // Success, no type checks.
+  Expect.equals(4, dSet.length);
+}
+
+void testUpcast() {
+  var setEls = new Set<C?>.from(elements);
+  var objectSet = Set.castFrom<C?, Object?>(setEls);
+
+  Expect.listEquals(elements, objectSet.toList());
+
+  var newObject = new Object();
+  Expect.throws(() => objectSet.add(newObject));
+  Expect.isFalse(objectSet.contains(newObject));
+
+  var toSet = objectSet.toSet();
+  Expect.isTrue(toSet is LinkedHashSet<Object?>);
+  Expect.isFalse(toSet is LinkedHashSet<C?>);
+}
+
+void testNewSet() {
+  // Specified custom newSet as empty HashSet.
+  var setEls = new Set<C?>.from(elements);
+  var customNewSet;
+  var objectSet2 = Set.castFrom<C?, Object?>(setEls,
+      newSet: <T>() => customNewSet = new HashSet<T>());
+
+  var customToSet = objectSet2.toSet();
+  Expect.isTrue(customToSet is HashSet<Object?>);
+  Expect.isFalse(customToSet is HashSet<C?>);
+  Expect.identical(customToSet, customNewSet);
+}
diff --git a/tests/corelib/cast_strong_test.dart b/tests/corelib/cast_strong_test.dart
new file mode 100644
index 0000000..22d5248
--- /dev/null
+++ b/tests/corelib/cast_strong_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testIterable();
+  testList();
+  testMap();
+  testSet();
+}
+
+testIterable() {
+  var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+  // Downcast non-nullable.
+
+  // An iterable that (likely) can do direct access.
+  var dIterableDirect = Iterable.castFrom<C?, D>(iterable);
+  Expect.equals(d, dIterableDirect.elementAt(1));
+  // null is not D.
+  Expect.throws(() => dIterableDirect.skip(3).elementAt(1));
+
+  // An iterable that cannot do direct access.
+  var dIterableNonDirect =
+      Iterable.castFrom<C?, D>(iterable.where((_) => true));
+  Expect.equals(d, dIterableNonDirect.elementAt(1));
+  // null is not D.
+  Expect.throws(() => dIterableNonDirect.skip(3).elementAt(1));
+
+  // Iterable that definitely won't survive accessing element 3.
+  var iterableLimited = new Iterable<C?>.generate(
+      elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+  var dIterableLimited = Iterable.castFrom<C?, D>(iterableLimited);
+  Expect.equals(d, dIterableLimited.elementAt(1));
+  // null is not D.
+  Expect.throws(() => dIterableLimited.skip(3).elementAt(1));
+
+  // Upcast non-nullable.
+  var objectIterable = Iterable.castFrom<C?, Object>(iterable);
+  // null is not Object.
+  Expect.throws(() => objectIterable.skip(3).elementAt(1));
+}
+
+testList() {
+  var list = new List<C?>.from(elements);
+
+  // Downcast non-nullable.
+  var dList = List.castFrom<C?, D>(list);
+  Expect.equals(d, dList[1]);
+  Expect.throws(() => dList.last); // null is not D.
+
+  // Upcast non-nullable.
+  var objectList = List.castFrom<C?, Object>(list);
+  Expect.throws(() => objectList.last); // null is not Object.
+}
+
+testMap() {
+  var map = new Map.fromIterables(elements, elements);
+
+  // Downcast non-nullable.
+  var dMap = Map.castFrom<C?, C?, D, D>(map);
+  Expect.equals(d, dMap[d]);
+  Expect.isTrue(dMap.containsKey(null));
+  Expect.equals(null, dMap[null]);
+
+  // Test keys and values
+  Expect.isTrue(dMap.keys is Iterable<D>);
+  Expect.isTrue(dMap.values is Iterable<D>);
+  Expect.throws(() => dMap.keys.toList());
+  Expect.throws(() => dMap.values.toList());
+
+  // Upcast non-nullable.
+  var objectMap = Map.castFrom<C?, C?, Object, Object>(map);
+  Expect.isTrue(objectMap.containsKey(null));
+  Expect.equals(null, objectMap[null]);
+
+  // Test keys and values
+  Expect.isTrue(objectMap.keys is Iterable<Object>);
+  Expect.isTrue(objectMap.values is Iterable<Object>);
+  // null is not Object.
+  Expect.throws(() => objectMap.keys.toList());
+  Expect.throws(() => objectMap.values.toList());
+}
+
+testSet() {
+  var setEls = new Set<C?>.from(elements);
+
+  // Downcast non-nullable.
+  var dSet = Set.castFrom<C?, D>(setEls);
+  Expect.equals(d, dSet.elementAt(1));
+  Expect.throws(() => dSet.last); // null is not D.
+
+  // Upcast non-nullable.
+  var objectSet = Set.castFrom<C?, Object>(setEls);
+  Expect.throws(() => objectSet.last); // null is not Object.
+}
diff --git a/tests/corelib/cast_test.dart b/tests/corelib/cast_test.dart
deleted file mode 100644
index 7f17351..0000000
--- a/tests/corelib/cast_test.dart
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:collection";
-import "dart:typed_data";
-import "package:expect/expect.dart";
-
-// TODO(rnystrom): Not migrated to NNBD yet.
-// See https://github.com/dart-lang/sdk/issues/39517.
-
-void main() {
-  testIterable();
-  testList();
-}
-
-final elements = <C>[c, d, e, f, null];
-
-void testIterable() {
-  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
-  // Down-cast
-  {
-    // An iterable that (likely) can do direct access.
-    var dIterable = Iterable.castFrom<C, D>(iterable);
-
-    Expect.throws(() => dIterable.first, null, "1.first");
-    Expect.equals(d, dIterable.elementAt(1));
-    Expect.throws(() => dIterable.elementAt(2), null, "1.2"); // E is not D.
-    Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
-    Expect.equals(null, dIterable.skip(3).elementAt(1));
-
-    Expect.throws(() => dIterable.toList(), null, "1.toList");
-  }
-
-  {
-    // An iterable that cannot do direct access.
-    var dIterable2 = Iterable.castFrom<C, D>(iterable.where((_) => true));
-
-    Expect.throws(() => dIterable2.first, null, "2.first");
-    Expect.equals(d, dIterable2.elementAt(1));
-    Expect.throws(() => dIterable2.elementAt(2), null, "2.2"); // E is not D.
-    Expect.equals(f, dIterable2.skip(3).first); // Skip does not access element.
-    Expect.equals(null, dIterable2.skip(3).elementAt(1));
-
-    Expect.throws(() => dIterable2.toList(), null, "2.toList");
-  }
-
-  {
-    // Iterable that definitely won't survive accessing element 2.
-    var iterable3 = new Iterable<C>.generate(
-        elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
-    var dIterable3 = Iterable.castFrom<C, D>(iterable3);
-
-    Expect.throws(() => dIterable3.first, null, "3.first");
-    Expect.equals(d, dIterable3.elementAt(1));
-    Expect.throws(() => dIterable3.elementAt(3), null, "3.3");
-    // Skip does not access element.
-    Expect.equals(null, dIterable3.skip(4).first);
-    Expect.equals(null, dIterable3.skip(3).elementAt(1));
-
-    Expect.throws(() => dIterable3.toList(), null, "3.toList");
-  }
-
-  // Up-cast.
-  {
-    var oIterable4 = Iterable.castFrom<C, Object>(iterable);
-    Expect.listEquals(elements, oIterable4.toList());
-  }
-}
-
-void testList() {
-  // Down-cast.
-  var list = new List<C>.from(elements);
-  var dList = List.castFrom<C, D>(list);
-
-  Expect.throws(() => dList.first); // C is not D.
-  Expect.equals(d, dList[1]);
-  Expect.throws(() => dList[2]); // E is not D.
-  Expect.equals(f, dList[3]);
-  Expect.equals(null, dList.last);
-
-  Expect.throws(() => dList.toList());
-
-  dList[2] = d;
-  Expect.equals(d, dList[2]); // Setting works.
-
-  // Up-cast.
-  var list2 = new List<C>.from(elements);
-  var dList2 = List.castFrom<C, Object>(list2);
-  Expect.listEquals(elements, dList2);
-  Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
-  Expect.listEquals(elements, dList2);
-
-  // Regression test.
-  var list3 = <num>[4, 3, 2, 1];
-  var dList3 = list3.cast<int>();
-  dList3.sort(null);
-  Expect.listEquals([1, 2, 3, 4], list3);
-}
-
-void testSet() {
-  var set = new Set<C>.from(elements); // Linked HashSet.
-  Expect.listEquals(elements, set.toList()); // Preserves order.
-
-  var dSet = Set.castFrom<C, D>(set);
-
-  // Preserves order.
-  Expect.throws(() => dSet.first); // C is not D.
-  Expect.equals(d, dSet.elementAt(1));
-  Expect.throws(() => dSet.elementAt(2)); // E is not D.
-
-  Expect.throws(() => dSet.toList());
-
-  // Contains is not typed.
-  var newC = new C();
-  Expect.isFalse(dSet.contains(newC));
-  dSet.add(newC);
-  Expect.isTrue(dSet.contains(newC));
-
-  Expect.equals(5, dSet.length);
-  dSet.remove(newC);
-  Expect.equals(5, dSet.length);
-  dSet.remove(c); // Success, no type checks.
-  Expect.equals(4, dSet.length);
-
-  // Up-cast
-  var set2 = new Set<C>.from(elements);
-  var dSet2 = Set.castFrom<C, Object>(set2);
-
-  var newObject = new Object();
-  Expect.throws(() => dSet2.add(newObject));
-  Expect.isFalse(dSet.contains(newObject));
-
-  var toSet2 = dSet2.toSet();
-  Expect.isTrue(toSet2 is LinkedHashSet<Object>);
-  Expect.isTrue(toSet2 is! LinkedHashSet<C>);
-
-  // Custom emptySet.
-
-  var set3 = new Set<C>.from(elements);
-  var dSet3 = Set.castFrom<C, Object>(set3, newSet: <T>() => new HashSet<T>());
-
-  var toSet3 = dSet3.toSet();
-  Expect.isTrue(toSet3 is HashSet<Object>);
-  Expect.isTrue(toSet3 is HashSet<C>);
-  Expect.isTrue(toSet3 is! LinkedHashSet<Object>);
-}
-
-void testMap() {
-  var map = new Map.fromIterables(elements, elements);
-
-  var dMap = Map.castFrom<C, C, D, D>(map);
-
-  Expect.isTrue(dMap is Map<D, D>);
-
-  Expect.equals(null, dMap[new C()]);
-  Expect.throws(() => dMap[c]);
-  Expect.isTrue(dMap.containsKey(c));
-  Expect.equals(d, dMap[d]);
-  Expect.throws(() => dMap[e]);
-  Expect.equals(null, dMap[null]);
-
-  Expect.equals(5, dMap.length);
-  dMap.remove(c); // Success, no type checks along the way.
-  Expect.equals(4, dMap.length);
-  Expect.equals(null, dMap[c]);
-
-  Expect.throws(() => dMap[c] = d);
-  Expect.throws(() => dMap[d] = c);
-  Expect.equals(4, dMap.length);
-
-  Expect.isTrue(dMap.keys is Iterable<D>);
-  Expect.isTrue(dMap.values is Iterable<D>);
-  Expect.throws(() => dMap.keys.toList());
-  Expect.throws(() => dMap.values.toList());
-}
-
-class C {}
-
-class D extends C {}
-
-class E extends C {}
-
-class F implements D, E {}
-
-final c = new C();
-final d = new D();
-final e = new E();
-final f = new F();
diff --git a/tests/corelib/cast_weak_test.dart b/tests/corelib/cast_weak_test.dart
new file mode 100644
index 0000000..571b8c7
--- /dev/null
+++ b/tests/corelib/cast_weak_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testIterable();
+  testList();
+  testMap();
+  testSet();
+}
+
+testIterable() {
+  var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+  // Downcast non-nullable.
+
+  // An iterable that (likely) can do direct access.
+  var dIterableDirect = Iterable.castFrom<C?, D>(iterable);
+  Expect.equals(d, dIterableDirect.elementAt(1));
+  Expect.equals(null, dIterableDirect.skip(3).elementAt(1));
+
+  // An iterable that cannot do direct access.
+  var dIterableNonDirect =
+      Iterable.castFrom<C?, D>(iterable.where((_) => true));
+  Expect.equals(d, dIterableNonDirect.elementAt(1));
+  Expect.equals(null, dIterableNonDirect.skip(3).elementAt(1));
+
+  // Iterable that definitely won't survive accessing element 3.
+  var iterableLimited = new Iterable<C?>.generate(
+      elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+  var dIterableLimited = Iterable.castFrom<C?, D>(iterableLimited);
+  Expect.equals(d, dIterableLimited.elementAt(1));
+  Expect.equals(null, dIterableLimited.skip(3).elementAt(1));
+
+  // Upcast non-nullable.
+  var objectIterable = Iterable.castFrom<C?, Object>(iterable);
+  Expect.equals(null, objectIterable.skip(3).elementAt(1));
+}
+
+testList() {
+  var list = new List<C?>.from(elements);
+
+  // Downcast non-nullable.
+  var dList = List.castFrom<C?, D>(list);
+  Expect.equals(d, dList[1]);
+  Expect.equals(null, dList.last);
+
+  // Upcast non-nullable.
+  var objectList = List.castFrom<C?, Object>(list);
+  Expect.equals(null, objectList.last);
+}
+
+testMap() {
+  var map = new Map.fromIterables(elements, elements);
+
+  // Downcast non-nullable.
+  var dMap = Map.castFrom<C?, C?, D, D>(map);
+  Expect.equals(d, dMap[d]);
+  Expect.isTrue(dMap.containsKey(null));
+  Expect.equals(null, dMap[null]);
+
+  // Test keys and values
+  Expect.isTrue(dMap.keys is Iterable<D>);
+  Expect.isTrue(dMap.values is Iterable<D>);
+  Expect.throws(() => dMap.keys.toList());
+  Expect.throws(() => dMap.values.toList());
+
+  // Upcast non-nullable.
+  var objectMap = Map.castFrom<C?, C?, Object, Object>(map);
+  Expect.isTrue(objectMap.containsKey(null));
+  Expect.equals(null, objectMap[null]);
+
+  // Test keys and values
+  Expect.isTrue(objectMap.keys is Iterable<Object>);
+  Expect.isTrue(objectMap.values is Iterable<Object>);
+  var expectedValues = new List<Object>.from(elements);
+  Expect.listEquals(expectedValues, objectMap.values.toList());
+}
+
+testSet() {
+  var setEls = new Set<C?>.from(elements);
+
+  // Downcast non-nullable.
+  var dSet = Set.castFrom<C?, D>(setEls);
+  Expect.equals(d, dSet.elementAt(1));
+  Expect.equals(null, dSet.last);
+
+  // Upcast non-nullable.
+  var objectSet = Set.castFrom<C?, Object>(setEls);
+  Expect.equals(null, objectSet.last);
+}
diff --git a/tests/corelib/collection_length_test.dart b/tests/corelib/collection_length_test.dart
index 27dae6e..2bc1f18 100644
--- a/tests/corelib/collection_length_test.dart
+++ b/tests/corelib/collection_length_test.dart
@@ -70,7 +70,8 @@
   testCollection(new LinkedHashSet(), N);
   testCollection(new ListQueue(), N);
   testCollection(new DoubleLinkedQueue(), N);
-  testList(new List()..length = N, N);
-  testList(new List(N), N);
+  testList([]..length = N, N);
+  testList(new List.filled(0, null, growable: true)..length = N, N);
+  testList(new List.filled(N, null), N);
   testString(N);
 }
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 00d80ea6..4ed80aa 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -13,7 +13,7 @@
 
 [ $builder_tag == obfuscated && $runtime == dart_precompiled ]
 apply_generic_function_test: SkipByDesign # Function.apply with named args
-apply_test: Skip # Uses new Symbol via symbolMapToStringMap helper
+apply_test: Skip # Uses new Symbol via symbolToStringMap helper
 dynamic_nosuchmethod_test: SkipByDesign # Expects names in NSM
 error_stack_trace1_test: SkipByDesign # Expects unobfuscated stack trace
 type_tostring_test: SkipByDesign # Expects names in Type.toString()
diff --git a/tests/corelib/error_stack_trace2_test.dart b/tests/corelib/error_stack_trace2_test.dart
index 47f6a7d..2b3d302 100644
--- a/tests/corelib/error_stack_trace2_test.dart
+++ b/tests/corelib/error_stack_trace2_test.dart
@@ -15,6 +15,20 @@
   return cyclicStatic;
 }
 
+// Helper method to detect whether [errorType] is an overflow error.
+//
+// TODO(41308): Use `is StackOverflowError` once DDC converts overflow errors
+// from JavaSript.
+bool isOverflowError(Type errorType) {
+  void detectOverflowError() => detectOverflowError();
+  try {
+    detectOverflowError();
+  } catch (e) {
+    return errorType == e.runtimeType;
+  }
+  return false;
+}
+
 main() {
   bool hasThrown = false;
   try {
@@ -22,7 +36,8 @@
   } catch (e2) {
     var e = e2;
     hasThrown = true;
-    Expect.isTrue(e is StackOverflowError);
+    Expect.isTrue(isOverflowError(e.runtimeType),
+        "Got '$e' instead of StackOverflowError");
   }
   Expect.isTrue(hasThrown);
 }
diff --git a/tests/corelib/expando_test.dart b/tests/corelib/expando_test.dart
index 04d6ad4..02810bc 100644
--- a/tests/corelib/expando_test.dart
+++ b/tests/corelib/expando_test.dart
@@ -10,7 +10,7 @@
   static testMain() {
     var legal = [
       new Object(),
-      new List(),
+      new List.filled(0, null),
       [1, 2, 3],
       const [1, 2, 3],
       new Map(),
diff --git a/tests/corelib/growable_list_test.dart b/tests/corelib/growable_list_test.dart
index 4c095f0..2f030f4 100644
--- a/tests/corelib/growable_list_test.dart
+++ b/tests/corelib/growable_list_test.dart
@@ -51,8 +51,9 @@
     }
     _current = _nextIndex;
     _nextIndex++;
-    if (_current == _iterable.callbackIndex) {
-      _iterable.callback();
+    var tempCallback = _iterable.callback;
+    if (_current == _iterable.callbackIndex && tempCallback != null) {
+      tempCallback();
     }
     return true;
   }
@@ -83,21 +84,19 @@
     Expect.throws(fn, (_) => true, name);
   }
 
-  testFixedLength(new List<int?>(0));
-  testFixedLength(new List<int?>(5));
+  testFixedLength(new List<int?>.empty());
   testFixedLength(new List<int?>.filled(5, null)); // default growable: false.
-  testGrowable(new List<int?>());
-  testGrowable(new List<int?>()..length = 5);
+  testGrowable(<int?>[]);
+  testGrowable(<int?>[]..length = 5);
   testGrowable(new List<int?>.filled(5, null, growable: true));
-  Expect.throwsArgumentError(() => new List<int?>(-1), "-1");
+  Expect.throwsArgumentError(() => new List<int?>.filled(-1, null), "-1");
   // There must be limits. Fix this test if we ever allow 2^63 elements.
-  Expect.throws(() => new List<int?>(0x7ffffffffffff000),
+  Expect.throws(() => new List<int?>.filled(0x7ffffffffffff000, null),
       (e) => e is OutOfMemoryError || e is ArgumentError, "bignum");
-  Expect.throwsArgumentError(() => new List<int?>(null), "null");
   testThrowsOrTypeError(
-      () => new List([] as dynamic), // Cast to avoid warning.
+      () => new List.filled([] as dynamic, null), // Cast to avoid warning.
       'list');
-  testThrowsOrTypeError(() => new List([42] as dynamic), "list2");
+  testThrowsOrTypeError(() => new List.filled([42] as dynamic, null), "list2");
 }
 
 void testConcurrentModification() {
diff --git a/tests/corelib/iterable_contains_test.dart b/tests/corelib/iterable_contains_test.dart
index 760a104..08b1c23 100644
--- a/tests/corelib/iterable_contains_test.dart
+++ b/tests/corelib/iterable_contains_test.dart
@@ -15,8 +15,8 @@
     Expect.isFalse(list.contains(notInList), "!$list.contains($notInList)");
   }
 
-  List fixedList = new List(list.length);
-  List growList = new List();
+  List fixedList = new List.filled(list.length, null);
+  List growList = [];
   for (int i = 0; i < list.length; i++) {
     fixedList[i] = list[i];
     growList.add(list[i]);
diff --git a/tests/corelib/iterable_fold_test.dart b/tests/corelib/iterable_fold_test.dart
index b531ccc..a6ee921 100644
--- a/tests/corelib/iterable_fold_test.dart
+++ b/tests/corelib/iterable_fold_test.dart
@@ -25,7 +25,7 @@
   for (dynamic iterable in [
     const [1, 2, 3],
     [1, 2, 3],
-    new List(3)
+    new List<int?>.filled(3, null)
       ..[0] = 1
       ..[1] = 2
       ..[2] = 3,
@@ -86,7 +86,7 @@
   for (var iterable in [
     const [],
     [],
-    new List(0),
+    new List.empty(),
     {}.keys,
     {}.values,
     new Iterable.generate(0, (x) => x + 1),
@@ -116,7 +116,7 @@
   for (dynamic iterable in [
     const [1],
     [1],
-    new List(1)..[0] = 1,
+    new List.filled(1, 1),
     {1: 1}.keys,
     {1: 1}.values,
     new Iterable.generate(1, (x) => x + 1),
diff --git a/tests/corelib/iterable_reduce_test.dart b/tests/corelib/iterable_reduce_test.dart
index 6ee66d0..4425c96 100644
--- a/tests/corelib/iterable_reduce_test.dart
+++ b/tests/corelib/iterable_reduce_test.dart
@@ -26,7 +26,7 @@
   for (dynamic iterable in [
     const [1, 2, 3],
     [1, 2, 3],
-    new List(3)
+    new List<int?>.filled(3, null)
       ..[0] = 1
       ..[1] = 2
       ..[2] = 3,
@@ -88,7 +88,7 @@
   for (var iterable in [
     const [],
     [],
-    new List(0),
+    new List.empty(),
     {}.keys,
     {}.values,
     new Iterable.generate(0, (x) => x + 1),
@@ -119,7 +119,7 @@
   for (dynamic iterable in [
     const [1],
     [1],
-    new List(1)..[0] = 1,
+    new List.filled(1, 1),
     {1: 1}.keys,
     {1: 1}.values,
     new Iterable.generate(1, (x) => x + 1),
diff --git a/tests/corelib/list_concurrent_modify_test.dart b/tests/corelib/list_concurrent_modify_test.dart
index 0111063..df62919 100644
--- a/tests/corelib/list_concurrent_modify_test.dart
+++ b/tests/corelib/list_concurrent_modify_test.dart
@@ -8,10 +8,8 @@
 
 void main() {
   // Growable lists. Initial length 0.
-  testConcurrentModification(new List());
-  testConcurrentModification(new List<int>().toList());
-  testConcurrentModification(new List<int?>(0).toList());
-  testConcurrentModification(new List.filled(0, null, growable: true));
+  testConcurrentModification(<int>[].toList());
+  testConcurrentModification(new List.filled(0, 0, growable: true));
   testConcurrentModification([]);
   testConcurrentModification(new List.from(const []));
   testConcurrentModification(new MyList([]));
@@ -28,7 +26,7 @@
   testConcurrentAddSelf([1, 2, 3]);
 }
 
-void testConcurrentModification(List<int?> list) {
+void testConcurrentModification(List<int> list) {
   // add, removeLast.
   list.clear();
   list.addAll([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1]);
@@ -93,6 +91,10 @@
     _source.length = length;
   }
 
+  void add(E element) {
+    _source.add(element);
+  }
+
   E operator [](int index) => _source[index];
   void operator []=(int index, E value) {
     _source[index] = value;
diff --git a/tests/corelib/list_map_test.dart b/tests/corelib/list_map_test.dart
index 19ce07e..cf27a37 100644
--- a/tests/corelib/list_map_test.dart
+++ b/tests/corelib/list_map_test.dart
@@ -115,7 +115,7 @@
     testOp((i) => i.every((n) => n < 5), "every<5");
     testOp((i) => i.every((n) => n < 10), "every<10");
     testOp((i) => i.reduce((a, b) => a + b), "reduce-sum");
-    testOp((i) => i.fold/*<int>*/(0, (a, b) => a + b), "fold-sum");
+    testOp((i) => i.fold<int>(0, (a, b) => a + b), "fold-sum");
     testOp((i) => i.join("-"), "join-");
     testOp((i) => i.join(""), "join");
     testOp((i) => i.join(), "join-null");
diff --git a/tests/corelib/list_removeat_test.dart b/tests/corelib/list_removeat_test.dart
index 6fedda8..a1657c2 100644
--- a/tests/corelib/list_removeat_test.dart
+++ b/tests/corelib/list_removeat_test.dart
@@ -25,7 +25,10 @@
   // Index must be integer and in range.
   Expect.throwsRangeError(() => l1.removeAt(-1), "negative");
   Expect.throwsRangeError(() => l1.removeAt(5), "too large");
-  Expect.throwsArgumentError(() => l1.removeAt(null), "too large");
+  Expect.throws(() => l1.removeAt(null),
+      // With --null-safety a TypeError is thrown
+      // With --no-null-safety an ArgumentError is thrown
+      (e) => e is TypeError || e is ArgumentError, "is null");
 
   Expect.equals(2, l1.removeAt(2), "l1-remove2");
   Expect.equals(1, l1[1], "l1-1[1]");
@@ -47,7 +50,7 @@
   testModifiableList(new MyList([0, 1, 2, 3, 4]));
 
   // Fixed size list.
-  var l2 = new List(5);
+  var l2 = new List<int?>.filled(5, null);
   for (var i = 0; i < 5; i++) l2[i] = i;
   Expect.throwsUnsupportedError(() => l2.removeAt(2), "fixed-length");
 
diff --git a/tests/corelib/list_reversed_test.dart b/tests/corelib/list_reversed_test.dart
index e331f8c..e26e731 100644
--- a/tests/corelib/list_reversed_test.dart
+++ b/tests/corelib/list_reversed_test.dart
@@ -106,7 +106,7 @@
     testOp((i) => i.every((n) => n < 5), "every<5");
     testOp((i) => i.every((n) => n < 10), "every<10");
     testOp((i) => i.reduce((a, b) => a + b), "reduce-sum");
-    testOp((i) => i.fold/*<int>*/(0, (a, b) => a + b), "fold-sum");
+    testOp((i) => i.fold<int>(0, (a, b) => a + b), "fold-sum");
     testOp((i) => i.join("-"), "join-");
     testOp((i) => i.join(""), "join");
     testOp((i) => i.join(), "join-null");
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index 18f2749..a607a5a 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -22,22 +22,20 @@
   testTypedList(new Int32List(4).toList(growable: false));
 
   // Fixed length lists, length 4.
-  testFixedLengthList(<T>() => new List<T?>(4));
-  testFixedLengthList(<T>() => new List<T?>(4).toList(growable: false));
-  testFixedLengthList(<T>() => (new List<T?>()..length = 4).toList(growable: false));
+  testFixedLengthList(<T>(T t) => List<T>.filled(4, t));
+  testFixedLengthList(<T>(T t) => List<T>.filled(4, t).toList(growable: false));
   // ListBase implementation of List.
-  testFixedLengthList(<T>() => new MyFixedList(new List<T?>(4)));
-  testFixedLengthList(<T>() => new MyFixedList<T?>(new List<T?>(4)).toList(growable: false));
+  testFixedLengthList(<T>(T t) => new MyFixedList(List<T>.filled(4, t)));
+  testFixedLengthList(<T>(T t) =>
+      new MyFixedList<T>(List<T>.filled(4, t)).toList(growable: false));
 
   // Growable lists. Initial length 0.
-  testGrowableList(<T>() => new List());
-  testGrowableList(<T>() => new List<T?>().toList());
-  testGrowableList(<T>() => new List<T?>(0).toList());
-  testGrowableList(<T>() => new List<T?>.filled(0, null, growable: true));
-  testGrowableList(<T>() => []);
-  testGrowableList(<T>() => new List.from(const []));
-  testGrowableList(<T>() => new MyList([]));
-  testGrowableList(<T>() => new MyList<T>([]).toList());
+  testGrowableList(<T>(T t) => <T>[].toList());
+  testGrowableList(<T>(T t) => new List<T>.filled(0, t, growable: true));
+  testGrowableList(<T>(T t) => []);
+  testGrowableList(<T>(T t) => new List.from(const []));
+  testGrowableList(<T>(T t) => new MyList([]));
+  testGrowableList(<T>(T t) => new MyList<T>([]).toList());
 
   testTypedGrowableList(new Uint8List(0).toList());
   testTypedGrowableList(new Int8List(0).toList());
@@ -118,7 +116,7 @@
 
   // Empty lists.
   testRangeErrors([], "list");
-  testRangeErrors(new List(0), "fixed-list");
+  testRangeErrors(List.filled(0, null, growable: false), "fixed-list");
   testRangeErrors(const [], "const-list");
   testRangeErrors(new List.unmodifiable([]), "unmodifiable");
   testRangeErrors(new Uint8List(0), "typed-list");
@@ -126,7 +124,7 @@
   testRangeErrors([1, 2, 3].sublist(1, 1), "sub-list");
   // Non-empty lists.
   testRangeErrors([1, 2, 3], "list");
-  testRangeErrors(new List(3), "fixed-list");
+  testRangeErrors(List.filled(3, null, growable: false), "fixed-list");
   testRangeErrors(const [1, 2, 3], "const-list");
   testRangeErrors(new List.unmodifiable([1, 2, 3]), "unmodifiable");
   testRangeErrors(new Uint8List(3), "typed-list");
@@ -164,7 +162,7 @@
   }
 
   // setRange.
-  list.setRange(0, 4, [3, 2, 1, 0]);
+  list.setRange(0, 4, <int>[3, 2, 1, 0]);
   Expect.listEquals([3, 2, 1, 0], list);
 
   list.setRange(1, 4, list);
@@ -179,9 +177,9 @@
   Expect.listEquals([2, 1, 2, 1], list);
 
   // setAll.
-  list.setAll(0, [3, 2, 0, 1]);
+  list.setAll(0, <int>[3, 2, 0, 1]);
   Expect.listEquals([3, 2, 0, 1], list);
-  list.setAll(1, [0, 1]);
+  list.setAll(1, <int>[0, 1]);
   Expect.listEquals([3, 0, 1, 1], list);
 
   // fillRange.
@@ -195,22 +193,22 @@
   Expect.listEquals([9, 9, 9, 9], list);
 
   // sort.
-  list.setRange(0, 4, [3, 2, 1, 0]);
+  list.setRange(0, 4, <int>[3, 2, 1, 0]);
   list.sort();
   Expect.listEquals([0, 1, 2, 3], list);
-  list.setRange(0, 4, [1, 2, 3, 0]);
+  list.setRange(0, 4, <int>[1, 2, 3, 0]);
   list.sort();
   Expect.listEquals([0, 1, 2, 3], list);
-  list.setRange(0, 4, [1, 3, 0, 2]);
+  list.setRange(0, 4, <int>[1, 3, 0, 2]);
   list.sort((a, b) => b! - a!); // reverse compare.
   Expect.listEquals([3, 2, 1, 0], list);
-  list.setRange(0, 4, [1, 2, 3, 0]);
+  list.setRange(0, 4, <int>[1, 2, 3, 0]);
   list.sort((a, b) => b! - a!);
   Expect.listEquals([3, 2, 1, 0], list);
 
   // Some Iterable methods.
 
-  list.setRange(0, 4, [0, 1, 2, 3]);
+  list.setRange(0, 4, <int>[0, 1, 2, 3]);
   // map.
   testMap(val) {
     return val * 2 + 10;
@@ -279,8 +277,8 @@
 void testLengthInvariantOperations(List<int?> list) {
   testTypedLengthInvariantOperations(list);
 
-  Expect.throwsTypeError(() => testUntypedListTests(list),
-      'List<int> cannot store non-ints');
+  Expect.throwsTypeError(
+      () => testUntypedListTests(list), 'List<int> cannot store non-ints');
 
   // Argument errors on bad indices. List is still [0, 1, 2, 3].
 
@@ -300,18 +298,18 @@
   Expect.throwsArgumentError(() => list.getRange(-1, 5));
   Expect.throwsArgumentError(() => list.getRange(2, 5));
   Expect.throwsArgumentError(() => list.getRange(4, 2));
-  Expect.throwsArgumentError(() => list.setRange(-1, 2, [1, 2, 3]));
-  Expect.throwsArgumentError(() => list.setRange(-1, 5, [1, 2, 3, 4, 5, 6]));
-  Expect.throwsArgumentError(() => list.setRange(2, 5, [1, 2, 3]));
-  Expect.throwsArgumentError(() => list.setRange(4, 2, [1, 2]));
+  Expect.throwsArgumentError(() => list.setRange(-1, 2, <int>[1, 2, 3]));
+  Expect.throwsArgumentError(() => list.setRange(-1, 5, <int>[1, 2, 3, 4, 5, 6]));
+  Expect.throwsArgumentError(() => list.setRange(2, 5, <int>[1, 2, 3]));
+  Expect.throwsArgumentError(() => list.setRange(4, 2, <int>[1, 2]));
   // for setAll, end is implicitly start + values.length.
-  Expect.throwsArgumentError(() => list.setAll(-1, []));
-  Expect.throwsArgumentError(() => list.setAll(5, []));
-  Expect.throwsArgumentError(() => list.setAll(2, [1, 2, 3]));
-  Expect.throwsArgumentError(() => list.fillRange(-1, 2));
-  Expect.throwsArgumentError(() => list.fillRange(-1, 5));
-  Expect.throwsArgumentError(() => list.fillRange(2, 5));
-  Expect.throwsArgumentError(() => list.fillRange(4, 2));
+  Expect.throwsArgumentError(() => list.setAll(-1, <int>[]));
+  Expect.throwsArgumentError(() => list.setAll(5, <int>[]));
+  Expect.throwsArgumentError(() => list.setAll(2, <int>[1, 2, 3]));
+  Expect.throwsArgumentError(() => list.fillRange(-1, 2, 1));
+  Expect.throwsArgumentError(() => list.fillRange(-1, 5, 1));
+  Expect.throwsArgumentError(() => list.fillRange(2, 5, 1));
+  Expect.throwsArgumentError(() => list.fillRange(4, 2, 1));
 }
 
 void testTypedList(List<int> list) {
@@ -319,51 +317,60 @@
   testCannotChangeLength(list);
 }
 
-void testFixedLengthList(List<T?> Function<T>() createList) {
-  testLengthInvariantOperations(createList<int>());
-  testCannotChangeLength(createList<int>());
-  testUntypedListTests(createList());
+void testFixedLengthList(List<T> Function<T>(T t) createList) {
+  testLengthInvariantOperations(createList<int>(-1));
+  testCannotChangeLength(createList<int>(-1));
+  testLengthInvariantOperations(createList<int?>(null));
+  testCannotChangeLength(createList<int?>(null));
+  testUntypedListTests(createList(null));
 }
 
 void testCannotChangeLength(List<int?> list) {
-  list.setAll(0, [0, 1, 2, 3]);
+  list.setAll(0, <int>[0, 1, 2, 3]);
   Expect.throwsUnsupportedError(() => list.add(0));
-  Expect.throwsUnsupportedError(() => list.addAll([0]));
+  Expect.throwsUnsupportedError(() => list.addAll(<int>[0]));
   Expect.throwsUnsupportedError(() => list.removeLast());
   Expect.throwsUnsupportedError(() => list.insert(0, 1));
-  Expect.throwsUnsupportedError(() => list.insertAll(0, [1]));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, <int>[1]));
   Expect.throwsUnsupportedError(() => list.clear());
   Expect.throwsUnsupportedError(() => list.remove(1));
   Expect.throwsUnsupportedError(() => list.removeAt(1));
   Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
-  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, <int>[]));
 }
 
 void testTypedGrowableList(List<int> list) {
   testLength(0, list);
-  // set length.
-  list.length = 4;
+  list.addAll([0, 0, 0, 0]);
   testLength(4, list);
 
   testTypedLengthInvariantOperations(list);
 
   testGrowableListOperations(list);
+
+  list.length = 2;
+  testLength(2, list);
 }
 
-void testGrowableList(List<T?> Function<T>() createList) {
-  List<int?> list = createList<int>();
+void testGrowableList(List<T> Function<T>(T t) createList) {
+  List<int> list = createList<int>(-1);
   testLength(0, list);
-  list.length = 4;
+  list.addAll([0, 0, 0, 0]);
   testLength(4, list);
-
   testLengthInvariantOperations(list);
   testGrowableListOperations(list);
 
-  List listDynamic = createList();
+  List<int?> listNullable = createList<int?>(null);
+  testLength(0, listNullable);
+  listNullable.length = 4;
+  testLength(4, listNullable);
+  testLengthInvariantOperations(listNullable);
+  testGrowableListOperations(listNullable);
+
+  List listDynamic = createList(null);
   testLength(0, listDynamic);
   listDynamic.length = 4;
   testLength(4, listDynamic);
-
   testUntypedListTests(listDynamic);
 }
 
@@ -453,39 +460,39 @@
   Expect.listEquals([2], list);
 
   // insertAll
-  list.insertAll(0, [1, 2, 3]);
+  list.insertAll(0, <int>[1, 2, 3]);
   Expect.listEquals([1, 2, 3, 2], list);
 
-  list.insertAll(2, []);
+  list.insertAll(2, <int>[]);
   Expect.listEquals([1, 2, 3, 2], list);
 
-  list.insertAll(4, [7, 9]);
+  list.insertAll(4, <int>[7, 9]);
   Expect.listEquals([1, 2, 3, 2, 7, 9], list);
 
   // addAll
   list.addAll(list.reversed.toList());
   Expect.listEquals([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1], list);
 
-  list.addAll([]);
+  list.addAll(<int>[]);
   Expect.listEquals([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1], list);
 
   // replaceRange
-  list.replaceRange(3, 7, [0, 0]);
+  list.replaceRange(3, 7, <int>[0, 0]);
   Expect.listEquals([1, 2, 3, 0, 0, 7, 2, 3, 2, 1], list);
 
-  list.replaceRange(2, 3, [5, 5, 5]);
+  list.replaceRange(2, 3, <int>[5, 5, 5]);
   Expect.listEquals([1, 2, 5, 5, 5, 0, 0, 7, 2, 3, 2, 1], list);
 
-  list.replaceRange(2, 4, [6, 6]);
+  list.replaceRange(2, 4, <int>[6, 6]);
   Expect.listEquals([1, 2, 6, 6, 5, 0, 0, 7, 2, 3, 2, 1], list);
 
-  list.replaceRange(6, 8, []);
+  list.replaceRange(6, 8, <int>[]);
   Expect.listEquals([1, 2, 6, 6, 5, 0, 2, 3, 2, 1], list);
 
   // Any operation that doesn't change the length should be safe for iteration.
   testSafeConcurrentModification(action()) {
     list.length = 4;
-    list.setAll(0, [0, 1, 2, 3]);
+    list.setAll(0, <int>[0, 1, 2, 3]);
     for (var i in list) {
       action();
     }
@@ -510,7 +517,7 @@
   // Argument errors on bad indices for methods that are only allowed
   // on growable lists.
   list.length = 4;
-  list.setAll(0, [0, 1, 2, 3]);
+  list.setAll(0, <int>[0, 1, 2, 3]);
 
   // Direct indices (0 <= index < length).
   Expect.throwsArgumentError(() => list.removeAt(-1));
@@ -518,19 +525,19 @@
   // Direct indices including end (0 <= index <= length).
   Expect.throwsArgumentError(() => list.insert(-1, 0));
   Expect.throwsArgumentError(() => list.insert(5, 0));
-  Expect.throwsArgumentError(() => list.insertAll(-1, [0]));
-  Expect.throwsArgumentError(() => list.insertAll(5, [0]));
-  Expect.throwsArgumentError(() => list.insertAll(-1, [0]));
-  Expect.throwsArgumentError(() => list.insertAll(5, [0]));
+  Expect.throwsArgumentError(() => list.insertAll(-1, <int>[0]));
+  Expect.throwsArgumentError(() => list.insertAll(5, <int>[0]));
+  Expect.throwsArgumentError(() => list.insertAll(-1, <int>[0]));
+  Expect.throwsArgumentError(() => list.insertAll(5, <int>[0]));
   // Ranges (0 <= start <= end <= length).
   Expect.throwsArgumentError(() => list.removeRange(-1, 2));
   Expect.throwsArgumentError(() => list.removeRange(2, 5));
   Expect.throwsArgumentError(() => list.removeRange(-1, 5));
   Expect.throwsArgumentError(() => list.removeRange(4, 2));
-  Expect.throwsArgumentError(() => list.replaceRange(-1, 2, [9]));
-  Expect.throwsArgumentError(() => list.replaceRange(2, 5, [9]));
-  Expect.throwsArgumentError(() => list.replaceRange(-1, 5, [9]));
-  Expect.throwsArgumentError(() => list.replaceRange(4, 2, [9]));
+  Expect.throwsArgumentError(() => list.replaceRange(-1, 2, <int>[9]));
+  Expect.throwsArgumentError(() => list.replaceRange(2, 5, <int>[9]));
+  Expect.throwsArgumentError(() => list.replaceRange(-1, 5, <int>[9]));
+  Expect.throwsArgumentError(() => list.replaceRange(4, 2, <int>[9]));
 }
 
 class Yes {
@@ -546,6 +553,10 @@
     _source.length = length;
   }
 
+  void add(E element) {
+    _source.add(element);
+  }
+
   E operator [](int index) => _source[index];
   void operator []=(int index, E value) {
     _source[index] = value;
@@ -568,11 +579,10 @@
 
 void testListConstructor() {
   // Is fixed-length.
-  Expect.throws(() => new List(0).add(4));
-  Expect.throws(() => new List(-2));  // Not negative. //# 01: ok
+  Expect.throws(() => new List<int?>.filled(0, null).add(4));
+  Expect.throws(() => new List.filled(-2, null)); // Not negative. //# 01: ok
   // Not null.
-  Expect.throws(() => new List(null));
-  Expect.listEquals([4], new List()..add(4));
+  Expect.listEquals([4], <int>[]..add(4));
   // Is fixed-length.
   Expect.throws(() => new List.filled(0, 42).add(4));
   // Not negative.
diff --git a/tests/corelib/map_test.dart b/tests/corelib/map_test.dart
index 09b9311..30618b0 100644
--- a/tests/corelib/map_test.dart
+++ b/tests/corelib/map_test.dart
@@ -55,14 +55,17 @@
   testNumericKeys(new MapBaseMap<num, String>());
   testNumericKeys(new MapMixinMap<num, String>());
 
+  // NaN maps need to have nullable value types because the forEach method
+  // cannot look up the value and therefore might find `null` instead of the
+  // actuall value. See MapMixin.forEach in dart:collection/maps.dart
   testNaNKeys(new Map());
-  testNaNKeys(new Map<num, String>());
+  testNaNKeys(new Map<num, String?>());
   testNaNKeys(new HashMap());
-  testNaNKeys(new HashMap<num, String>());
+  testNaNKeys(new HashMap<num, String?>());
   testNaNKeys(new LinkedHashMap());
-  testNaNKeys(new LinkedHashMap<num, String>());
-  testNaNKeys(new MapBaseMap<num, String>());
-  testNaNKeys(new MapMixinMap<num, String>());
+  testNaNKeys(new LinkedHashMap<num, String?>());
+  testNaNKeys(new MapBaseMap<num, String?>());
+  testNaNKeys(new MapMixinMap<num, String?>());
   // Identity maps fail the NaN-keys tests because the test assumes that
   // NaN is not equal to NaN.
 
@@ -160,7 +163,7 @@
 
 void testMap<K, V>(
     Map<K, V> typedMap, key1, key2, key3, key4, key5, key6, key7, key8) {
-  var map = typedMap;
+  dynamic map = typedMap;
   int value1 = 10;
   int value2 = 20;
   int value3 = 30;
@@ -379,7 +382,7 @@
 }
 
 void testMapLiteral() {
-  Map m = {"a": 1, "b": 2, "c": 3};
+  var m = {"a": 1, "b": 2, "c": 3};
   Expect.equals(3, m.length);
   int sum = 0;
   m.forEach((a, b) {
diff --git a/tests/corelib/queue_test.dart b/tests/corelib/queue_test.dart
index 0729bf6..a34038e 100644
--- a/tests/corelib/queue_test.dart
+++ b/tests/corelib/queue_test.dart
@@ -420,12 +420,12 @@
     }
     Expect.equals(null, entry2);
 
-    var firstEntry = queue1.firstEntry();
-    var secondEntry = queue1.firstEntry().nextEntry();
-    var thirdEntry = queue1.lastEntry();
+    var firstEntry = queue1.firstEntry()!;
+    var secondEntry = queue1.firstEntry()!.nextEntry()!;
+    var thirdEntry = queue1.lastEntry()!;
     firstEntry.prepend(4);
     firstEntry.append(5);
-    secondEntry!.prepend(6);
+    secondEntry.prepend(6);
     secondEntry.append(7);
     thirdEntry.prepend(8);
     thirdEntry.append(9);
@@ -446,11 +446,11 @@
 
   entry.append(37);
   entry.prepend(87);
-  var prev = entry.previousEntry();
-  var next = entry.nextEntry();
+  var prev = entry.previousEntry()!;
+  var next = entry.nextEntry()!;
   Expect.equals(42, entry.element);
-  Expect.equals(37, next!.element);
-  Expect.equals(87, prev!.element);
+  Expect.equals(37, next.element);
+  Expect.equals(87, prev.element);
   Expect.identical(entry, prev.nextEntry());
   Expect.identical(entry, next.previousEntry());
   Expect.equals(null, next.nextEntry());
diff --git a/tests/corelib/regexp/global_test.dart b/tests/corelib/regexp/global_test.dart
index 2ca88ce..2722ef5 100644
--- a/tests/corelib/regexp/global_test.dart
+++ b/tests/corelib/regexp/global_test.dart
@@ -52,6 +52,7 @@
     if (m.group(1) != null) return "-";
     if (m.group(2) != null) return "+";
     if (m.group(3) != null) return "=";
+    throw 'Unexpected match $m';
   });
   assertEquals("= -. +, or + -. There is - =.", str);
 
@@ -88,6 +89,7 @@
     if (m.group(1) != null) return "-";
     if (m.group(2) != null) return "+";
     if (m.group(3) != null) return "=";
+    throw 'Unexpected match $m';
   });
   assertEquals("= -. +, or + -. There is - =.", str);
 
diff --git a/tests/corelib/regexp/regexp_test.dart b/tests/corelib/regexp/regexp_test.dart
index 1cb8ac7..9f42f43 100644
--- a/tests/corelib/regexp/regexp_test.dart
+++ b/tests/corelib/regexp/regexp_test.dart
@@ -32,10 +32,12 @@
   assertEquals("foo:bar:baz", str.split(regexp).join(":"));
 }
 
-void assertEquals(actual, expected, [message]) =>
+void assertEquals(actual, expected, [String message = ""]) =>
     Expect.equals(actual, expected, message);
-void assertTrue(actual, [message]) => Expect.isTrue(actual, message);
-void assertFalse(actual, [message]) => Expect.isFalse(actual, message);
+void assertTrue(actual, [String message = ""]) =>
+    Expect.isTrue(actual, message);
+void assertFalse(actual, [String message = ""]) =>
+    Expect.isFalse(actual, message);
 void assertThrows(fn) => Expect.throws(fn);
 
 void main() {
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index 18deeb3..117f35a 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -177,7 +177,7 @@
   }
 
   // Test Set.addAll.
-  List list = new List(10);
+  List list = new List.filled(10, null);
   for (int i = 0; i < 10; i++) {
     list[i] = i + 10;
   }
diff --git a/tests/corelib/sort_helper.dart b/tests/corelib/sort_helper.dart
index 6b8307b..657fe12 100644
--- a/tests/corelib/sort_helper.dart
+++ b/tests/corelib/sort_helper.dart
@@ -27,7 +27,7 @@
   }
 
   void testSortIntLists() {
-    var a = new List<int>(40);
+    var a = new List<int>.filled(40, -1);
 
     for (int i = 0; i < a.length; i++) {
       a[i] = i;
@@ -83,11 +83,10 @@
     a[33] = 1;
     testSort(a);
 
-    var a2 = new List<int>(0);
+    var a2 = new List<int>.empty();
     testSort(a2);
 
-    var a3 = new List<int>(1);
-    a3[0] = 1;
+    var a3 = new List<int>.filled(1, 1);
     testSort(a3);
 
     // --------
@@ -124,7 +123,7 @@
   }
 
   void testInsertionSort(int i1, int i2, int i3, int i4) {
-    var a = new List<int>(4);
+    var a = new List<int>.filled(4, -1);
     a[0] = i1;
     a[1] = i2;
     a[2] = i3;
@@ -133,7 +132,7 @@
   }
 
   void testSortDoubleLists() {
-    var a = new List<double>(40);
+    var a = new List<double>.filled(40, -1);
     for (int i = 0; i < a.length; i++) {
       a[i] = 1.0 * i + 0.5;
     }
diff --git a/tests/corelib/symbol_map_helper.dart b/tests/corelib/symbol_map_helper.dart
index da9e7e5..2fe69f6 100644
--- a/tests/corelib/symbol_map_helper.dart
+++ b/tests/corelib/symbol_map_helper.dart
@@ -5,7 +5,7 @@
 library dart.test.symbol_map_helper;
 
 // TODO(ahe): Update map literals to avoid this method.
-Map<Symbol, dynamic> symbolMapToStringMap(Map<String, dynamic> map) {
+Map<Symbol, dynamic>? symbolToStringMap(Map<String, dynamic> map) {
   if (map == null) return null;
   Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
   map.forEach((name, value) {
diff --git a/tests/corelib/symbol_operator_test.dart b/tests/corelib/symbol_operator_test.dart
index ac79499..c32837f 100644
--- a/tests/corelib/symbol_operator_test.dart
+++ b/tests/corelib/symbol_operator_test.dart
@@ -76,6 +76,6 @@
 }
 
 class Symbolize {
-  Symbol lastMember;
+  Symbol? lastMember;
   noSuchMethod(m) => lastMember = m.memberName;
 }
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index bb45fe0..550fc57 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -470,8 +470,8 @@
   });
   var params = uri.queryParametersAll;
   Expect.equals(2, params.length);
-  Expect.listEquals(["42", "37"], params["x"]);
-  Expect.listEquals(["43", "38"], params["y"]);
+  Expect.listEquals(["42", "37"], params["x"]!);
+  Expect.listEquals(["43", "38"], params["y"]!);
 }
 
 main() {
diff --git a/tests/corelib/weak_mode/README b/tests/corelib/weak_mode/README
new file mode 100644
index 0000000..9da48ae
--- /dev/null
+++ b/tests/corelib/weak_mode/README
@@ -0,0 +1,2 @@
+This directory contains tests specific to null safety weak mode
+behavior.
\ No newline at end of file
diff --git a/tests/corelib/weak_mode/asyncMap_accepts_null.dart b/tests/corelib/weak_mode/asyncMap_accepts_null.dart
new file mode 100644
index 0000000..d25a21a
--- /dev/null
+++ b/tests/corelib/weak_mode/asyncMap_accepts_null.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+import "dart:async";
+import "package:expect/expect.dart";
+
+// Regression test for https://github.com/dart-lang/sdk/issues/41465
+
+void main() {
+  var stream = Stream.fromIterable([1, 2, 3, 4]);
+  var eventsStream =
+      stream.asyncMap((i) => i % 2 == 0 ? i : null).where((i) => i != null);
+  eventsStream.listen(Expect.isNotNull);
+}
diff --git a/tests/corelib/weak_mode/future_sync_accepts_null.dart b/tests/corelib/weak_mode/future_sync_accepts_null.dart
new file mode 100644
index 0000000..79ac038
--- /dev/null
+++ b/tests/corelib/weak_mode/future_sync_accepts_null.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+import "dart:async";
+import "package:expect/expect.dart";
+
+// Regression test for https://github.com/dart-lang/sdk/issues/41465
+
+void main() async {
+  var f = Future<int>.sync(() => null);
+  Expect.isNull(await f);
+}
diff --git a/tests/corelib_2/cast_helper.dart b/tests/corelib_2/cast_helper.dart
new file mode 100644
index 0000000..6e2d76a
--- /dev/null
+++ b/tests/corelib_2/cast_helper.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final elements = <C>[c, d, e, f, null];
+
+class C {}
+
+class D extends C {}
+
+class E extends C {}
+
+class F implements D, E {}
+
+final c = C();
+final d = D();
+final e = E();
+final f = F();
diff --git a/tests/corelib_2/cast_iterable_test.dart b/tests/corelib_2/cast_iterable_test.dart
new file mode 100644
index 0000000..19836f0
--- /dev/null
+++ b/tests/corelib_2/cast_iterable_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testDowncastDirectAccess();
+  testDowncastNoDirectAccess();
+  testDowncastUntouchableElements();
+  testUpcast();
+}
+
+void testDowncastDirectAccess() {
+  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
+
+  // An iterable that (likely) can do direct access.
+  var dIterable = Iterable.castFrom<C, D>(iterable);
+
+  Expect.throws(() => dIterable.first, null, "direct.first");
+  Expect.equals(d, dIterable.elementAt(1));
+  Expect.throws(() => dIterable.elementAt(2), null, "direct.2"); // E is not D.
+  Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+  Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+  Expect.throws(() => dIterable.toList(), null, "direct.toList");
+}
+
+void testDowncastNoDirectAccess() {
+  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
+
+  // An iterable that cannot do direct access.
+  var dIterable = Iterable.castFrom<C, D>(iterable.where((_) => true));
+
+  Expect.throws(() => dIterable.first, null, "nonDirect.first");
+  Expect.equals(d, dIterable.elementAt(1));
+  // E is not D.
+  Expect.throws(() => dIterable.elementAt(2), null, "nonDirect.2");
+  Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+  Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+  Expect.throws(() => dIterable.toList(), null, "nonDirect.toList");
+}
+
+void testDowncastUntouchableElements() {
+  // Iterable that definitely won't survive accessing element 3.
+  var iterable = new Iterable<C>.generate(
+      elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+  var dIterable = Iterable.castFrom<C, D>(iterable);
+
+  Expect.throws(() => dIterable.first, null, "untouchable.first");
+  Expect.equals(d, dIterable.elementAt(1));
+  Expect.throws(() => dIterable.elementAt(3), null, "untouchable.3");
+  // Skip does not access element.
+  Expect.equals(null, dIterable.skip(4).first);
+  Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+  Expect.throws(() => dIterable.toList(), null, "untouchable.toList");
+}
+
+void testUpcast() {
+  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
+
+  var objectIterable = Iterable.castFrom<C, Object>(iterable);
+  Expect.listEquals(elements, objectIterable.toList());
+}
diff --git a/tests/corelib_2/cast_list_test.dart b/tests/corelib_2/cast_list_test.dart
new file mode 100644
index 0000000..75f3072
--- /dev/null
+++ b/tests/corelib_2/cast_list_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testDowncast();
+  testUpcast();
+  testRegression();
+}
+
+void testDowncast() {
+  var list = new List<C>.from(elements);
+  var dList = List.castFrom<C, D>(list);
+
+  Expect.throws(() => dList.first); // C is not D.
+  Expect.equals(d, dList[1]);
+  Expect.throws(() => dList[2]); // E is not D.
+  Expect.equals(f, dList[3]);
+  Expect.equals(null, dList.last);
+
+  Expect.throws(() => dList.toList());
+
+  // Setting works.
+  dList[2] = d;
+  Expect.equals(d, dList[2]);
+}
+
+void testUpcast() {
+  var list2 = new List<C>.from(elements);
+  var dList2 = List.castFrom<C, Object>(list2);
+  Expect.listEquals(elements, dList2);
+  Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
+  Expect.listEquals(elements, dList2);
+}
+
+void testRegression() {
+  var numList = <num>[4, 3, 2, 1];
+  var intList = numList.cast<int>();
+  intList.sort(null);
+  Expect.listEquals([1, 2, 3, 4], numList);
+  Expect.listEquals([1, 2, 3, 4], intList);
+}
diff --git a/tests/corelib_2/cast_map_test.dart b/tests/corelib_2/cast_map_test.dart
new file mode 100644
index 0000000..123bd1e
--- /dev/null
+++ b/tests/corelib_2/cast_map_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testDowncast();
+  testUpcast();
+}
+
+void testDowncast() {
+  var map = new Map.fromIterables(elements, elements);
+  var dMap = Map.castFrom<C, C, D, D>(map);
+
+  Expect.isTrue(dMap is Map<D, D>);
+
+  Expect.equals(null, dMap[new C()]);
+  Expect.throws(() => dMap[c]); // C is not D.
+  Expect.isTrue(dMap.containsKey(c)); // containsKey should not be typed.
+  Expect.equals(d, dMap[d]);
+  Expect.throws(() => dMap[e]); // E is not D.
+  Expect.isTrue(dMap.containsKey(null));
+  Expect.equals(null, dMap[null]);
+
+  Expect.equals(5, dMap.length);
+  Expect.throws(() => dMap.remove(c)); // Removes key but fails to return value.
+  Expect.equals(4, dMap.length);
+  Expect.equals(null, dMap[c]);
+
+  // Runtime errors when assigning or accessing a C.
+  Expect.throws(() => dMap[c] = d);
+  Expect.throws(() => dMap[d] = c);
+  Expect.equals(4, dMap.length);
+
+  // Test keys and values.
+  Expect.isTrue(dMap.keys is Iterable<D>);
+  Expect.isTrue(dMap.values is Iterable<D>);
+  Expect.throws(() => dMap.keys.toList());
+  Expect.throws(() => dMap.values.toList());
+}
+
+void testUpcast() {
+  var map = new Map.fromIterables(elements, elements);
+  var objectMap = Map.castFrom<C, C, Object, Object>(map);
+
+  Expect.equals(5, objectMap.length);
+  Expect.equals(c, objectMap[c]);
+  Expect.isTrue(objectMap.containsKey(c));
+  Expect.equals(c, objectMap.remove(c));
+  Expect.equals(4, objectMap.length);
+
+  // Test keys and values.
+  Expect.isTrue(objectMap.keys is Iterable<Object>);
+  Expect.isTrue(objectMap.values is Iterable<Object>);
+  var expected = new List<Object>.from(elements);
+  expected.remove(c);
+  Expect.listEquals(expected, objectMap.keys.toList());
+  Expect.listEquals(expected, objectMap.values.toList());
+}
diff --git a/tests/corelib_2/cast_set_test.dart b/tests/corelib_2/cast_set_test.dart
new file mode 100644
index 0000000..8b8dc71
--- /dev/null
+++ b/tests/corelib_2/cast_set_test.dart
@@ -0,0 +1,73 @@
+// 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:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+  testOrder();
+  testDowncast();
+  testUpcast();
+  testNewSet();
+}
+
+void testOrder() {
+  var setEls = new Set<C>.from(elements); // Linked HashSet.
+  Expect.listEquals(elements, setEls.toList()); // Preserves order.
+}
+
+void testDowncast() {
+  var setEls = new Set<C>.from(elements);
+  var dSet = Set.castFrom<C, D>(setEls);
+
+  // Preserves order.
+  Expect.throws(() => dSet.first); // C is not D.
+  Expect.equals(d, dSet.elementAt(1));
+  Expect.throws(() => dSet.elementAt(2)); // E is not D.
+  Expect.equals(f, dSet.elementAt(3));
+  Expect.equals(null, dSet.elementAt(4));
+
+  Expect.throws(() => dSet.toList());
+
+  // Contains should not be typed.
+  var newC = new C();
+  Expect.isFalse(dSet.contains(newC));
+  Expect.throws(() => dSet.add(newC));
+  Expect.isFalse(dSet.contains(newC));
+  Expect.isTrue(dSet.contains(c));
+
+  // Remove and length should not be typed.
+  Expect.equals(5, dSet.length);
+  dSet.remove(c); // Success, no type checks.
+  Expect.equals(4, dSet.length);
+}
+
+void testUpcast() {
+  var setEls = new Set<C>.from(elements);
+  var objectSet = Set.castFrom<C, Object>(setEls);
+
+  Expect.listEquals(elements, objectSet.toList());
+
+  var newObject = new Object();
+  Expect.throws(() => objectSet.add(newObject));
+  Expect.isFalse(objectSet.contains(newObject));
+
+  var toSet = objectSet.toSet();
+  Expect.isTrue(toSet is LinkedHashSet<Object>);
+  Expect.isFalse(toSet is LinkedHashSet<C>);
+}
+
+void testNewSet() {
+  // Specified custom newSet as empty HashSet.
+  var setEls = new Set<C>.from(elements);
+  var customNewSet;
+  var objectSet2 = Set.castFrom<C, Object>(setEls,
+      newSet: <T>() => customNewSet = new HashSet<T>());
+
+  var customToSet = objectSet2.toSet();
+  Expect.isTrue(customToSet is HashSet<Object>);
+  Expect.isFalse(customToSet is HashSet<C>);
+  Expect.identical(customToSet, customNewSet);
+}
diff --git a/tests/corelib_2/cast_test.dart b/tests/corelib_2/cast_test.dart
deleted file mode 100644
index 36efe9e..0000000
--- a/tests/corelib_2/cast_test.dart
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:collection";
-import "dart:typed_data";
-import "package:expect/expect.dart";
-
-void main() {
-  testIterable();
-  testList();
-}
-
-final elements = <C>[c, d, e, f, null];
-
-void testIterable() {
-  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
-  // Down-cast
-  {
-    // An iterable that (likely) can do direct access.
-    var dIterable = Iterable.castFrom<C, D>(iterable);
-
-    Expect.throws(() => dIterable.first, null, "1.first");
-    Expect.equals(d, dIterable.elementAt(1));
-    Expect.throws(() => dIterable.elementAt(2), null, "1.2"); // E is not D.
-    Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
-    Expect.equals(null, dIterable.skip(3).elementAt(1));
-
-    Expect.throws(() => dIterable.toList(), null, "1.toList");
-  }
-
-  {
-    // An iterable that cannot do direct access.
-    var dIterable2 = Iterable.castFrom<C, D>(iterable.where((_) => true));
-
-    Expect.throws(() => dIterable2.first, null, "2.first");
-    Expect.equals(d, dIterable2.elementAt(1));
-    Expect.throws(() => dIterable2.elementAt(2), null, "2.2"); // E is not D.
-    Expect.equals(f, dIterable2.skip(3).first); // Skip does not access element.
-    Expect.equals(null, dIterable2.skip(3).elementAt(1));
-
-    Expect.throws(() => dIterable2.toList(), null, "2.toList");
-  }
-
-  {
-    // Iterable that definitely won't survive accessing element 2.
-    var iterable3 = new Iterable<C>.generate(
-        elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
-    var dIterable3 = Iterable.castFrom<C, D>(iterable3);
-
-    Expect.throws(() => dIterable3.first, null, "3.first");
-    Expect.equals(d, dIterable3.elementAt(1));
-    Expect.throws(() => dIterable3.elementAt(3), null, "3.3");
-    // Skip does not access element.
-    Expect.equals(null, dIterable3.skip(4).first);
-    Expect.equals(null, dIterable3.skip(3).elementAt(1));
-
-    Expect.throws(() => dIterable3.toList(), null, "3.toList");
-  }
-
-  // Up-cast.
-  {
-    var oIterable4 = Iterable.castFrom<C, Object>(iterable);
-    Expect.listEquals(elements, oIterable4.toList());
-  }
-}
-
-void testList() {
-  // Down-cast.
-  var list = new List<C>.from(elements);
-  var dList = List.castFrom<C, D>(list);
-
-  Expect.throws(() => dList.first); // C is not D.
-  Expect.equals(d, dList[1]);
-  Expect.throws(() => dList[2]); // E is not D.
-  Expect.equals(f, dList[3]);
-  Expect.equals(null, dList.last);
-
-  Expect.throws(() => dList.toList());
-
-  dList[2] = d;
-  Expect.equals(d, dList[2]); // Setting works.
-
-  // Up-cast.
-  var list2 = new List<C>.from(elements);
-  var dList2 = List.castFrom<C, Object>(list2);
-  Expect.listEquals(elements, dList2);
-  Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
-  Expect.listEquals(elements, dList2);
-
-  // Regression test.
-  var list3 = <num>[4, 3, 2, 1];
-  var dList3 = list3.cast<int>();
-  dList3.sort(null);
-  Expect.listEquals([1, 2, 3, 4], list3);
-}
-
-void testSet() {
-  var set = new Set<C>.from(elements); // Linked HashSet.
-  Expect.listEquals(elements, set.toList()); // Preserves order.
-
-  var dSet = Set.castFrom<C, D>(set);
-
-  // Preserves order.
-  Expect.throws(() => dSet.first); // C is not D.
-  Expect.equals(d, dSet.elementAt(1));
-  Expect.throws(() => dSet.elementAt(2)); // E is not D.
-
-  Expect.throws(() => dSet.toList());
-
-  // Contains is not typed.
-  var newC = new C();
-  Expect.isFalse(dSet.contains(newC));
-  dSet.add(newC);
-  Expect.isTrue(dSet.contains(newC));
-
-  Expect.equals(5, dSet.length);
-  dSet.remove(newC);
-  Expect.equals(5, dSet.length);
-  dSet.remove(c); // Success, no type checks.
-  Expect.equals(4, dSet.length);
-
-  // Up-cast
-  var set2 = new Set<C>.from(elements);
-  var dSet2 = Set.castFrom<C, Object>(set2);
-
-  var newObject = new Object();
-  Expect.throws(() => dSet2.add(newObject));
-  Expect.isFalse(dSet.contains(newObject));
-
-  var toSet2 = dSet2.toSet();
-  Expect.isTrue(toSet2 is LinkedHashSet<Object>);
-  Expect.isTrue(toSet2 is! LinkedHashSet<C>);
-
-  // Custom emptySet.
-
-  var set3 = new Set<C>.from(elements);
-  var dSet3 = Set.castFrom<C, Object>(set3, newSet: <T>() => new HashSet<T>());
-
-  var toSet3 = dSet3.toSet();
-  Expect.isTrue(toSet3 is HashSet<Object>);
-  Expect.isTrue(toSet3 is HashSet<C>);
-  Expect.isTrue(toSet3 is! LinkedHashSet<Object>);
-}
-
-void testMap() {
-  var map = new Map.fromIterables(elements, elements);
-
-  var dMap = Map.castFrom<C, C, D, D>(map);
-
-  Expect.isTrue(dMap is Map<D, D>);
-
-  Expect.equals(null, dMap[new C()]);
-  Expect.throws(() => dMap[c]);
-  Expect.isTrue(dMap.containsKey(c));
-  Expect.equals(d, dMap[d]);
-  Expect.throws(() => dMap[e]);
-  Expect.equals(null, dMap[null]);
-
-  Expect.equals(5, dMap.length);
-  dMap.remove(c); // Success, no type checks along the way.
-  Expect.equals(4, dMap.length);
-  Expect.equals(null, dMap[c]);
-
-  Expect.throws(() => dMap[c] = d);
-  Expect.throws(() => dMap[d] = c);
-  Expect.equals(4, dMap.length);
-
-  Expect.isTrue(dMap.keys is Iterable<D>);
-  Expect.isTrue(dMap.values is Iterable<D>);
-  Expect.throws(() => dMap.keys.toList());
-  Expect.throws(() => dMap.values.toList());
-}
-
-class C {}
-
-class D extends C {}
-
-class E extends C {}
-
-class F implements D, E {}
-
-final c = new C();
-final d = new D();
-final e = new E();
-final f = new F();
diff --git a/tests/language/assert/assignable_type_test.dart b/tests/language/assert/assignable_type_test.dart
index 06b1c8d..d769352 100644
--- a/tests/language/assert/assignable_type_test.dart
+++ b/tests/language/assert/assignable_type_test.dart
@@ -15,7 +15,7 @@
 }
 
 testInt64List() {
-  var array = new List(10);
+  var array = new List<int?>.filled(10, null);
   testInt64ListImpl(array);
 }
 
diff --git a/tests/language/assert/with_type_test_or_cast_test.dart b/tests/language/assert/with_type_test_or_cast_test.dart
index 85a18ec..f494804 100644
--- a/tests/language/assert/with_type_test_or_cast_test.dart
+++ b/tests/language/assert/with_type_test_or_cast_test.dart
@@ -12,7 +12,7 @@
 // VMOptions=--enable_asserts
 
 main() {
-  var names = new List<int>();
+  var names = <int>[];
 
   // Generic type test.
   assert(names is List<int>);
diff --git a/tests/language/async/return_types_test.dart b/tests/language/async/return_types_test.dart
index 473150f..9adba85 100644
--- a/tests/language/async/return_types_test.dart
+++ b/tests/language/async/return_types_test.dart
@@ -41,8 +41,6 @@
 // [error line 40, column 1]
 // [cfe] Functions marked 'async' must have a return type assignable to 'Future'.
   return 3;
-  //     ^
-  // [analyzer] STATIC_TYPE_WARNING.RETURN_OF_INVALID_TYPE
 }
 
 Future<int> foo6() async {
diff --git a/tests/language/async_star/await_for_test.dart b/tests/language/async_star/await_for_test.dart
index 13d8fc8..9f12002 100644
--- a/tests/language/async_star/await_for_test.dart
+++ b/tests/language/async_star/await_for_test.dart
@@ -24,7 +24,7 @@
   test('simple stream, await', () {
     f(Stream<int> s) async {
       var r = 0;
-      await for (var v in s) r += await Future.microtask(() => v);
+      await for (var v in s) r += await Future<int>.microtask(() => v);
       return r;
     }
 
@@ -57,7 +57,7 @@
   test('simple stream, await, reyield', () {
     f(Stream<int> s) async* {
       var r = 0;
-      await for (var v in s) yield r += await Future.microtask(() => v);
+      await for (var v in s) yield r += await Future<int>.microtask(() => v);
     }
 
     return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
@@ -93,7 +93,7 @@
       var r = 0;
       await for (var i in mkStream(5)) {
         await for (var j in mkStream(3)) {
-          r += await Future.microtask(() => i * j);
+          r += await Future<int>.microtask(() => i * j);
         }
       }
       return r;
@@ -108,9 +108,9 @@
     f() async {
       var r = 0;
       await for (var i in mkStream(5)) {
-        var ai = await Future.microtask(() => i);
+        var ai = await Future<int>.microtask(() => i);
         await for (var j in mkStream(3)) {
-          r += await Future.microtask(() => ai * j);
+          r += await Future<int>.microtask(() => ai * j);
         }
       }
       return r;
@@ -136,7 +136,7 @@
     f(Stream<int> s) async {
       var r = 0;
       await for (var i in s) {
-        r += await Future.delayed(ms * 10, () => i);
+        r += await Future<int>.delayed(ms * 10, () => i);
       }
       return r;
     }
diff --git a/tests/language/closure/bound_closure_equality_test.dart b/tests/language/closure/bound_closure_equality_test.dart
new file mode 100644
index 0000000..6ed96db
--- /dev/null
+++ b/tests/language/closure/bound_closure_equality_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  const A();
+  foo() => 42;
+}
+
+class B {
+  foo() => 42;
+}
+
+main() {
+  // Use an array to defeat type inferencing.
+  var array = <dynamic>[new A(), new A(), new B(), new B()];
+  var set = new Set.from(array.map((a) => a.foo));
+  Expect.equals(array.length, set.length);
+  set.addAll(array.map((a) => a.foo));
+  Expect.equals(array.length, set.length);
+
+  for (int i = 0; i < array.length; i += 2) {
+    Expect.isTrue(set.contains(array[i].foo));
+    Expect.equals(array[i], array[i]);
+    Expect.equals(array[i].foo, array[i].foo);
+    Expect.equals(array[i].foo.hashCode, array[i].foo.hashCode);
+    for (int j = 0; j < array.length; j++) {
+      if (i == j) continue;
+      Expect.notEquals(array[i].foo, array[j].foo);
+    }
+  }
+
+  // Try with dart2js intercepted types.
+  array = <dynamic>['foo', 'bar', [], [], const []];
+  set = new Set.from(array.map((a) => a.indexOf));
+  Expect.equals(array.length, set.length);
+  set.addAll(array.map((a) => a.indexOf));
+  Expect.equals(array.length, set.length);
+
+  for (int i = 0; i < array.length; i += 2) {
+    Expect.isTrue(set.contains(array[i].indexOf));
+    Expect.equals(array[i], array[i]);
+    Expect.equals(array[i].indexOf, array[i].indexOf);
+    Expect.equals(array[i].indexOf.hashCode, array[i].indexOf.hashCode);
+    for (int j = 0; j < array.length; j++) {
+      if (i == j) continue;
+      Expect.notEquals(array[i].indexOf, array[j].indexOf);
+    }
+  }
+
+  array = <dynamic>[const A(), const A()];
+  set = new Set.from(array.map((a) => a.foo));
+  Expect.equals(1, set.length);
+  set.addAll(array.map((a) => a.foo));
+  Expect.equals(1, set.length);
+
+  Expect.isTrue(set.contains(array[0].foo));
+  Expect.equals(array[0].foo, array[0].foo);
+  Expect.equals(array[0].foo.hashCode, array[0].foo.hashCode);
+  Expect.equals(array[0].foo, array[1].foo);
+  Expect.equals(array[0].foo.hashCode, array[1].foo.hashCode);
+
+  array = <dynamic>[const [], const []];
+  set = new Set.from(array.map((a) => a.indexOf));
+  Expect.equals(1, set.length);
+  set.addAll(array.map((a) => a.indexOf));
+  Expect.equals(1, set.length);
+
+  Expect.isTrue(set.contains(array[0].indexOf));
+  Expect.equals(array[0].indexOf, array[0].indexOf);
+  Expect.equals(array[0].indexOf.hashCode, array[0].indexOf.hashCode);
+  Expect.equals(array[0].indexOf, array[1].indexOf);
+  Expect.equals(array[0].indexOf.hashCode, array[1].indexOf.hashCode);
+}
diff --git a/tests/language/closure/bound_closure_primitives_test.dart b/tests/language/closure/bound_closure_primitives_test.dart
new file mode 100644
index 0000000..cd5bdfe
--- /dev/null
+++ b/tests/language/closure/bound_closure_primitives_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to make sure dart2js does not try to use the same
+// BoundClosureClass between an intercepted method and a
+// non-intercepted method.
+
+import "package:expect/expect.dart";
+
+class A {
+  // Make dart2js try to share a bound closure for [foo] with a bound
+  // closure for [List.add], by having same number of arguments.
+  foo(a) => a;
+}
+
+main() {
+  var array = <dynamic>[[], new A()];
+  var method = array[0].add;
+  method(42);
+
+  method = array[1].foo;
+  Expect.equals(42, method(42));
+
+  Expect.equals(1, array[0].length);
+  Expect.isTrue(array[0].contains(42));
+}
diff --git a/tests/language/closure/break1_test.dart b/tests/language/closure/break1_test.dart
new file mode 100644
index 0000000..8522fae
--- /dev/null
+++ b/tests/language/closure/break1_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for closures.
+
+import "package:expect/expect.dart";
+
+class ClosureBreak1 {
+  ClosureBreak1(this.field);
+  int field;
+}
+
+class ClosureBreak1Test {
+  static testMain() {
+    var o1 = new ClosureBreak1(3);
+    String newstr = "abcdefgh";
+    foo() {
+      o1.field++;
+      Expect.equals(8, newstr.length);
+    }
+
+    bool loop = true;
+    L:
+    while (loop) {
+      String newstr1 = "abcd";
+      var o2 = new ClosureBreak1(3);
+      foo1() {
+        o2.field++;
+        Expect.equals(4, newstr1.length);
+      }
+
+      Expect.equals(4, newstr1.length);
+      while (loop) {
+        int newint = 0;
+        var o3 = new ClosureBreak1(3);
+        foo2() {
+          o3.field++;
+          Expect.equals(0, newint);
+        }
+
+        foo2();
+        break L;
+      }
+    }
+    foo();
+    Expect.equals(4, o1.field);
+  }
+}
+
+main() {
+  ClosureBreak1Test.testMain();
+}
diff --git a/tests/language/closure/break2_test.dart b/tests/language/closure/break2_test.dart
new file mode 100644
index 0000000..5742620
--- /dev/null
+++ b/tests/language/closure/break2_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for closures.
+
+import "package:expect/expect.dart";
+
+class ClosureBreak2 {
+  ClosureBreak2(this.field);
+  int field;
+}
+
+class ClosureBreak2Test {
+  static testMain() {
+    var o1 = new ClosureBreak2(3);
+    String newstr = "abcdefgh";
+    foo() {
+      o1.field++;
+      Expect.equals(8, newstr.length);
+    }
+
+    bool loop = true;
+    L:
+    while (loop) {
+      String newstr1 = "abcd";
+      Expect.equals(4, newstr1.length);
+      while (loop) {
+        int newint = 0;
+        Expect.equals(4, newstr1.length);
+        break L;
+      }
+    }
+    foo();
+    Expect.equals(4, o1.field);
+  }
+}
+
+main() {
+  ClosureBreak2Test.testMain();
+}
diff --git a/tests/language/closure/break_test.dart b/tests/language/closure/break_test.dart
new file mode 100644
index 0000000..ae99035
--- /dev/null
+++ b/tests/language/closure/break_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for closures.
+
+import "package:expect/expect.dart";
+
+class ClosureBreak {
+  ClosureBreak(this.field);
+  int field;
+}
+
+class ClosureBreakTest {
+  static testMain() {
+    var o1 = new ClosureBreak(3);
+    String newstr = "abcdefgh";
+    foo() {
+      o1.field++;
+      Expect.equals(8, newstr.length);
+    }
+
+    bool loop = true;
+    L1:
+    while (loop) {
+      String newstr1 = "abcd";
+      var o2 = new ClosureBreak(3);
+      foo1() {
+        o2.field++;
+        Expect.equals(4, newstr1.length);
+      }
+
+      Expect.equals(4, newstr1.length);
+      L2:
+      while (loop) {
+        int newint = 0;
+        var o3 = new ClosureBreak(3);
+        foo2() {
+          o3.field++;
+          Expect.equals(0, newint);
+        }
+
+        foo2();
+        break L2;
+      }
+      foo1();
+      Expect.equals(4, newstr1.length);
+      break L1;
+    }
+    foo();
+    Expect.equals(4, o1.field);
+  }
+}
+
+main() {
+  ClosureBreakTest.testMain();
+}
diff --git a/tests/language/closure/call_wrong_argument_count_test.dart b/tests/language/closure/call_wrong_argument_count_test.dart
new file mode 100644
index 0000000..ef9f964
--- /dev/null
+++ b/tests/language/closure/call_wrong_argument_count_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Test mismatch in argument counts.
+import 'package:expect/expect.dart';
+
+int melke(f) {
+  return f(1, 2, 3);
+}
+
+main() {
+  kuh(int a, int b) {
+    return a + b;
+  }
+
+  Expect.throws(() {
+    melke(kuh);
+  });
+}
diff --git a/tests/language/closure/closure2_test.dart b/tests/language/closure/closure2_test.dart
new file mode 100644
index 0000000..bf3cf01
--- /dev/null
+++ b/tests/language/closure/closure2_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for closures.
+
+import "package:expect/expect.dart";
+
+bounce(fn) {
+  return fn();
+}
+
+demo(s) {
+  var i, a = bounce(() => s);
+  return a;
+}
+
+main() {
+  Expect.equals("Bounce!", demo("Bounce!"));
+}
diff --git a/tests/language/closure/closure3_test.dart b/tests/language/closure/closure3_test.dart
new file mode 100644
index 0000000..8841d375
--- /dev/null
+++ b/tests/language/closure/closure3_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that a NoSuchMethodError is thrown even when an expression
+// seems to be free of side-effects.
+
+test(x, y) {
+  (() {
+    x - y;
+  })();
+}
+
+main() {
+  Expect.throwsNoSuchMethodError(() => test(null, 2));
+}
diff --git a/tests/language/closure/closure4_test.dart b/tests/language/closure/closure4_test.dart
new file mode 100644
index 0000000..5445b7d
--- /dev/null
+++ b/tests/language/closure/closure4_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart2js failed when a declared function was captured inside itself.
+
+foo(f) => f(499);
+
+main() {
+  fun(x) {
+    if (x < 3) {
+      return foo((x) => fun(x));
+    } else {
+      return x;
+    }
+  }
+
+  Expect.equals(499, fun(499));
+}
diff --git a/tests/language/closure/closure5_test.dart b/tests/language/closure/closure5_test.dart
new file mode 100644
index 0000000..bf698b6
--- /dev/null
+++ b/tests/language/closure/closure5_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart2js failed when a declared function was captured inside itself.
+
+foo(f) => f(499);
+
+main() {
+  fun(x) {
+    if (x < 3) {
+      return foo((x) => fun(x));
+    } else {
+      return x;
+    }
+  }
+
+  Expect.equals(499, foo((x) => fun(x)));
+}
diff --git a/tests/language/closure/closure6_test.dart b/tests/language/closure/closure6_test.dart
new file mode 100644
index 0000000..ea37454
--- /dev/null
+++ b/tests/language/closure/closure6_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that captured final variables are correctly mangled.
+
+class A {
+  foo() {
+    length() => 400;
+    final box_0 = 28;
+    var x = 29;
+    var f = () => length() + box_0 + x + bar();
+    return f();
+  }
+
+  bar() => 42;
+}
+
+main() {
+  Expect.equals(499, new A().foo());
+}
diff --git a/tests/language/closure/closure7_test.dart b/tests/language/closure/closure7_test.dart
new file mode 100644
index 0000000..91b8f7b
--- /dev/null
+++ b/tests/language/closure/closure7_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that implicitly bound closures work correctly
+
+class A {
+  foo() => 499;
+  fooo() => 4999; // Implicit closure class can be shared with foo.
+  bar(x, {y: 8, z: 10}) => "1 $x $y $z";
+  gee(x, {y: 9, z: 11}) => "2 $x $y $z"; // Must not be shared with "bar".
+  toto(x, {y: 8, z: 10}) => "3 $x $y $z"; // Could be shared with "bar".
+
+  fisk(x, {y: 8, zz: 10}) => "4 $x $y $zz";
+  titi(x, {y: 8, zz: 77}) => "5 $x $y $zz"; // Could be shared with "fisk",
+  // because default-val is never used.
+}
+
+class B {
+  // All implicit closures of B can be shared with their equivalent functions
+  // of A.
+  foo() => 4990;
+  fooo() => 49990;
+  bar(x, {y: 8, z: 10}) => "1B $x $y $z";
+  gee(x, {y: 9, z: 11}) => "2B $x $y $z";
+  toto(x, {y: 8, z: 10}) => "3B $x $y $z";
+  fisk(x, {y: 8, zz: 10}) => "4B $x $y $zz";
+  titi(x, {y: 8, zz: 77}) => "5B $x $y $zz";
+}
+
+tearOffFoo(o) => o.foo;
+tearOffFooo(o) => o.fooo;
+tearOffBar(o) => o.bar;
+tearOffGee(o) => o.gee;
+tearOffToto(o) => o.toto;
+tearOffFisk(o) => o.fisk;
+tearOffTiti(o) => o.titi;
+
+main() {
+  var a = new A();
+  var b = new B();
+  Expect.equals(499, tearOffFoo(a)());
+  Expect.equals(4990, tearOffFoo(b)());
+  Expect.equals(4999, tearOffFooo(a)());
+  Expect.equals(49990, tearOffFooo(b)());
+
+  var barA = tearOffBar(a);
+  var barB = tearOffBar(b);
+  var geeA = tearOffGee(a);
+  var geeB = tearOffGee(b);
+  var totoA = tearOffToto(a);
+  var totoB = tearOffToto(b);
+  Expect.equals("1 33 8 10", barA(33));
+  Expect.equals("1B 33 8 10", barB(33));
+  Expect.equals("2 33 9 11", geeA(33));
+  Expect.equals("2B 33 9 11", geeB(33));
+  Expect.equals("3 33 8 10", totoA(33));
+  Expect.equals("3B 33 8 10", totoB(33));
+
+  Expect.equals("1 35 8 10", barA(35));
+  Expect.equals("1B 35 8 10", barB(35));
+  Expect.equals("2 35 9 11", geeA(35));
+  Expect.equals("2B 35 9 11", geeB(35));
+  Expect.equals("3 35 8 10", totoA(35));
+  Expect.equals("3B 35 8 10", totoB(35));
+
+  Expect.equals("1 35 8 77", barA(35, z: 77));
+  Expect.equals("1B 35 8 77", barB(35, z: 77));
+  Expect.equals("2 35 9 77", geeA(35, z: 77));
+  Expect.equals("2B 35 9 77", geeB(35, z: 77));
+  Expect.equals("3 35 8 77", totoA(35, z: 77));
+  Expect.equals("3B 35 8 77", totoB(35, z: 77));
+
+  Expect.equals("1 35 8 77", barA(35, z: 77));
+  Expect.equals("1B 35 8 77", barB(35, z: 77));
+  Expect.equals("2 35 9 77", geeA(35, z: 77));
+  Expect.equals("2B 35 9 77", geeB(35, z: 77));
+  Expect.equals("3 35 8 77", totoA(35, z: 77));
+  Expect.equals("3B 35 8 77", totoB(35, z: 77));
+
+  var fiskA = tearOffFisk(a);
+  var fiskB = tearOffFisk(b);
+  var titiA = tearOffTiti(a);
+  var titiB = tearOffTiti(b);
+
+  Expect.equals("4 311 8 987", fiskA(311, zz: 987));
+  Expect.equals("4B 311 8 987", fiskB(311, zz: 987));
+  Expect.equals("5 311 8 987", titiA(311, zz: 987));
+  Expect.equals("5B 311 8 987", titiB(311, zz: 987));
+
+  Expect.equals("4 311 765 987", fiskA(311, y: 765, zz: 987));
+  Expect.equals("4B 311 765 987", fiskB(311, y: 765, zz: 987));
+  Expect.equals("5 311 765 987", titiA(311, y: 765, zz: 987));
+  Expect.equals("5B 311 765 987", titiB(311, y: 765, zz: 987));
+}
diff --git a/tests/language/closure/closure8_test.dart b/tests/language/closure/closure8_test.dart
new file mode 100644
index 0000000..211c722
--- /dev/null
+++ b/tests/language/closure/closure8_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Regression test for issue 6353.
+
+class A<E> {}
+
+class C<E> extends A<E> {
+  forEach(callback(E element)) {}
+}
+
+class D<E> {
+  lala(E element) {}
+}
+
+main() {
+  var c = new C<int>();
+  c.forEach(new D<int>().lala);
+}
diff --git a/tests/language/closure/closure_test.dart b/tests/language/closure/closure_test.dart
new file mode 100644
index 0000000..9dc3a90
--- /dev/null
+++ b/tests/language/closure/closure_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for closures.
+
+import "package:expect/expect.dart";
+
+class A {
+  var field;
+  A(this.field) {}
+}
+
+class ClosureTest {
+  static testMain() {
+    var o = new A(3);
+    foo() => o.field++;
+    Expect.equals(3, foo());
+    Expect.equals(4, o.field);
+  }
+}
+
+main() {
+  ClosureTest.testMain();
+}
diff --git a/tests/language/closure/closures_initializer2_test.dart b/tests/language/closure/closures_initializer2_test.dart
new file mode 100644
index 0000000..337639b
--- /dev/null
+++ b/tests/language/closure/closures_initializer2_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {
+  var t;
+  A() : t = (() => T);
+}
+
+expect(result, expected) {
+  if (result != expected) {
+    throw 'Expected $expected, got $result';
+  }
+}
+
+main() {
+  for (var i = 0; i < int.parse("1"); i++) {
+    expect(new A<int>().t() is Type, true);
+  }
+}
diff --git a/tests/language/closure/closures_initializer_test.dart b/tests/language/closure/closures_initializer_test.dart
new file mode 100644
index 0000000..0d60490
--- /dev/null
+++ b/tests/language/closure/closures_initializer_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {
+  var t;
+  A() : t = (() => <T>[]);
+}
+
+class B<T> {
+  var t;
+  B() : t = (() => T);
+}
+
+expect(result, expected) {
+  if (result != expected) {
+    throw 'Expected $expected, got $result';
+  }
+}
+
+main() {
+  expect(new A<int>().t() is List<int>, true);
+  expect(new A<String>().t() is List<int>, false);
+  expect(new B<int>().t() is Type, true);
+  expect(new B<int>().t(), int);
+}
diff --git a/tests/language/closure/closures_with_complex_params_test.dart b/tests/language/closure/closures_with_complex_params_test.dart
new file mode 100644
index 0000000..175999a
--- /dev/null
+++ b/tests/language/closure/closures_with_complex_params_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Tests for parsing closures with complex parameter types.
+const defaultPair = Pair<int, Pair<int, int>>(-1, Pair(-2, -3));
+
+main() {
+  test1();
+  test2();
+  test3();
+}
+
+class Pair<A, B> {
+  final A fst;
+  final B snd;
+  const Pair(A this.fst, B this.snd);
+}
+
+test1() {
+  // Closures with nested parameterized types.
+  var cdar1 = (Pair<int, Pair<int, int>> pr) => pr.snd.fst;
+  var cdar2 = (Pair<int, Pair<int, int>> pr) => pr.snd.fst;
+
+  var e = new Pair<int, Pair<int, int>>(100, new Pair<int, int>(200, 300));
+
+  Expect.equals(200, cdar1(e));
+  Expect.equals(200, cdar2(e));
+}
+
+test2() {
+  // Closures with nested parameterized types in optional position
+  var cdar1 = ([Pair<int, Pair<int, int>> pr = defaultPair]) => pr.snd.fst;
+  var cdar2 = ([Pair<int, Pair<int, int>> pr = defaultPair]) => pr.snd.fst;
+
+  var e = new Pair<int, Pair<int, int>>(100, new Pair<int, int>(200, 300));
+
+  Expect.equals(200, cdar1(e));
+  Expect.equals(200, cdar2(e));
+}
+
+test3() {
+  // Closures with nested parameterized types.
+  var f1 = (Pair<int, Pair<int, int>> pr) => pr.snd.fst + 1;
+  var f2 = (Pair<int, Pair<int, int>> pr) => pr.snd.fst + 2;
+
+  // Closures with function type with nested parameterized types.
+  var ap1 = (f(Pair<int, Pair<int, int>> pr1), Pair<int, Pair<int, int>> pr) =>
+      f(pr) * 10;
+  var ap2 = (f(Pair<int, Pair<int, int>> pr1), Pair<int, Pair<int, int>> pr) =>
+      f(pr) * 100;
+
+  var e = new Pair<int, Pair<int, int>>(100, new Pair<int, int>(200, 300));
+
+  Expect.equals(2010, ap1(f1, e));
+  Expect.equals(2020, ap1(f2, e));
+  Expect.equals(20100, ap2(f1, e));
+  Expect.equals(20200, ap2(f2, e));
+}
diff --git a/tests/language/closure/cycles_test.dart b/tests/language/closure/cycles_test.dart
new file mode 100644
index 0000000..7ad7dae
--- /dev/null
+++ b/tests/language/closure/cycles_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Based on dartbug.com/7681
+// Verify that context chains do not lead to unintended memory being held.
+
+library closure_cycles_test;
+
+import "dart:async";
+
+class X {
+  late Function onX;
+  X() {
+    Timer.run(() => onX(new Y()));
+  }
+}
+
+class Y {
+  late Function onY;
+  var heavyMemory;
+  static var count = 0;
+  Y() {
+    // Consume large amounts of memory per iteration to fail/succeed quicker.
+    heavyMemory = new List.filled(10 * 1024 * 1024, null);
+    // Terminate the test if we allocated enough memory without running out.
+    if (count++ > 100) return;
+    Timer.run(() => onY());
+  }
+}
+
+void doIt() {
+  var x = new X();
+  x.onX = (y) {
+    y.onY = () {
+      y; // Capturing y can lead to endless context chains!
+      doIt();
+    };
+  };
+}
+
+void main() {
+  doIt();
+}
diff --git a/tests/language/closure/forwarding_stub_tearoff_generic_test.dart b/tests/language/closure/forwarding_stub_tearoff_generic_test.dart
new file mode 100644
index 0000000..1bccc6e
--- /dev/null
+++ b/tests/language/closure/forwarding_stub_tearoff_generic_test.dart
@@ -0,0 +1,43 @@
+// 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:expect/expect.dart";
+
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(B x) {}
+}
+
+abstract class I<T> {
+  void f(T x);
+}
+
+// D contains a forwarding stub for f which ensures that `x` is type checked.
+class D extends C implements I<B> {}
+
+void checkStubTearoff(dynamic tearoff) {
+  // Since the stub's parameter is covariant, its type should be reified as
+  // Object.
+  Expect.isTrue(tearoff is void Function(Object));
+
+  // Verify that the appropriate runtime check occurs.
+  tearoff(new B()); // No error
+  Expect.throwsTypeError(() {
+    tearoff(new A());
+  });
+}
+
+main() {
+  // The same forwarding stub should be torn off from D regardless of what
+  // interface is used to tear it off.
+  D d = new D();
+  C c = d;
+  I i = d;
+  checkStubTearoff(d.f);
+  checkStubTearoff(c.f);
+  checkStubTearoff(i.f);
+}
diff --git a/tests/language/closure/forwarding_stub_tearoff_test.dart b/tests/language/closure/forwarding_stub_tearoff_test.dart
new file mode 100644
index 0000000..12aa7bf
--- /dev/null
+++ b/tests/language/closure/forwarding_stub_tearoff_test.dart
@@ -0,0 +1,43 @@
+// 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:expect/expect.dart";
+
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(B x) {}
+}
+
+abstract class I {
+  void f(covariant A x);
+}
+
+// D contains a forwarding stub for f which ensures that `x` is type checked.
+class D extends C implements I {}
+
+void checkStubTearoff(dynamic tearoff) {
+  // Since the stub's parameter is covariant, its type should be reified as
+  // Object.
+  Expect.isTrue(tearoff is void Function(Object));
+
+  // Verify that the appropriate runtime check occurs.
+  tearoff(new B()); // No error
+  Expect.throwsTypeError(() {
+    tearoff(new A());
+  });
+}
+
+main() {
+  // The same forwarding stub should be torn off from D regardless of what
+  // interface is used to tear it off.
+  D d = new D();
+  C c = d;
+  I i = d;
+  checkStubTearoff(d.f);
+  checkStubTearoff(c.f);
+  checkStubTearoff(i.f);
+}
diff --git a/tests/language/closure/implicit1_test.dart b/tests/language/closure/implicit1_test.dart
new file mode 100644
index 0000000..4a8a4f4
--- /dev/null
+++ b/tests/language/closure/implicit1_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--enable_type_checks --enable_asserts
+
+typedef Handler(bool e);
+
+class Hello {
+  Hello() {}
+  void handler2(bool e) {
+    print('handler2');
+  }
+
+  static void handler1(bool e) {
+    print('handler1');
+  }
+
+  void addEventListener(String s, Handler handler, bool status) {
+    handler(status);
+  }
+
+  static void main() {
+    final h = new Hello();
+    h.addEventListener('click', handler1, false);
+    h.addEventListener('click', h.handler2, false);
+  }
+}
+
+main() {
+  Hello.main();
+}
diff --git a/tests/language/closure/implicit2_test.dart b/tests/language/closure/implicit2_test.dart
new file mode 100644
index 0000000..a03f458
--- /dev/null
+++ b/tests/language/closure/implicit2_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class B {
+  foo(i) => 499 + i;
+}
+
+class A {
+  var b;
+  A() : b = new B();
+
+  foo(i) {
+    return (() => b.foo(i))();
+  }
+}
+
+main() {
+  var a = new A();
+  Expect.equals(510, a.foo(11));
+  var f = a.foo;
+  Expect.equals(521, f(22));
+}
diff --git a/tests/language/closure/implicit_closure_test.dart b/tests/language/closure/implicit_closure_test.dart
new file mode 100644
index 0000000..a9ea617
--- /dev/null
+++ b/tests/language/closure/implicit_closure_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing invocation of implicit closures.
+// VMOptions=
+// VMOptions=--use_slow_path
+
+import "package:expect/expect.dart";
+
+class First {
+  First(this.i) {}
+  var b;
+  int foo() {
+    return i;
+  }
+
+  Function foo1() {
+    local() {
+      return i;
+    }
+
+    return local;
+  }
+
+  int i;
+}
+
+class ImplicitClosureTest {
+  static void testMain() {
+    First obj = new First(20);
+
+    Function func = () => obj.i;
+    obj.b = func;
+    Expect.equals(20, obj.b());
+
+    var ib1 = obj.foo1();
+    Expect.equals(obj.i, ib1());
+
+    var ib = obj.foo;
+    Expect.equals(obj.i, ib());
+  }
+}
+
+main() {
+  ImplicitClosureTest.testMain();
+}
diff --git a/tests/language/closure/in_constructor_test.dart b/tests/language/closure/in_constructor_test.dart
new file mode 100644
index 0000000..4c768a3
--- /dev/null
+++ b/tests/language/closure/in_constructor_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  var closure;
+
+  factory A.factory() => new A(() => <T>[]);
+
+  A([this.closure]) {
+    if (closure == null) {
+      closure = () => <T>[];
+    }
+  }
+}
+
+main() {
+  Expect.isTrue((new A.factory()).closure() is List);
+  Expect.isTrue((new A()).closure() is List);
+  Expect.isTrue((new A<int>.factory()).closure() is List<int>);
+  Expect.isTrue((new A<int>()).closure() is List<int>);
+  Expect.isFalse((new A<int>.factory()).closure() is List<String>);
+  Expect.isFalse((new A<int>()).closure() is List<String>);
+}
diff --git a/tests/language/closure/in_field_initializer_test.dart b/tests/language/closure/in_field_initializer_test.dart
new file mode 100644
index 0000000..e2dbc5b
--- /dev/null
+++ b/tests/language/closure/in_field_initializer_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class Foo {
+  var closures = {'a': (int x, int y) => x + y};
+}
+
+main() {
+  var closures = new Foo().closures;
+  Expect.equals(6, closures['a']!(4, 2));
+}
diff --git a/tests/language/closure/in_initializer2_test.dart b/tests/language/closure/in_initializer2_test.dart
new file mode 100644
index 0000000..a782c64
--- /dev/null
+++ b/tests/language/closure/in_initializer2_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Test that a parameter used in a closure is properly boxed.
+
+import "package:expect/expect.dart";
+
+abstract class S {
+  S() {
+    Expect.equals(2, this.f());
+  }
+
+  get f;
+}
+
+class A extends S {
+  var f;
+  A(a) : f = (() => ++a) {
+    Expect.equals(a, 2);
+  }
+}
+
+main() {
+  var a = new A(1);
+  Expect.equals(a.f(), 3);
+}
diff --git a/tests/language/closure/in_initializer_test.dart b/tests/language/closure/in_initializer_test.dart
new file mode 100644
index 0000000..3556649
--- /dev/null
+++ b/tests/language/closure/in_initializer_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+// Test that a parameter used in two different closures defined in a
+// constructor initializer, is properly boxed.
+
+import "package:expect/expect.dart";
+
+class A {
+  var f;
+  var g;
+  A(a)
+      : f = (() => 42 + a),
+        g = (() => ++a) {
+    a = 4;
+  }
+}
+
+class B extends A {
+  B() : super(42);
+}
+
+class C extends A {
+  var h;
+  C(a)
+      : h = (() => ++a),
+        super(42);
+}
+
+main() {
+  dynamic a = new A(1);
+  Expect.equals(46, a.f());
+  Expect.equals(5, a.g());
+  Expect.equals(47, a.f());
+
+  a = new B();
+  Expect.equals(46, a.f());
+  Expect.equals(5, a.g());
+  Expect.equals(47, a.f());
+
+  a = new C(0);
+  Expect.equals(46, a.f());
+  Expect.equals(5, a.g());
+  Expect.equals(47, a.f());
+  Expect.equals(1, a.h());
+  Expect.equals(2, a.h());
+  Expect.equals(47, a.f());
+  Expect.equals(6, a.g());
+  Expect.equals(48, a.f());
+}
diff --git a/tests/language/closure/internals_runtime_test.dart b/tests/language/closure/internals_runtime_test.dart
new file mode 100644
index 0000000..1b52d32
--- /dev/null
+++ b/tests/language/closure/internals_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class C {
+  foo() => 123;
+}
+
+main() {
+  var f = new C().foo;
+
+
+
+}
diff --git a/tests/language/closure/internals_test.dart b/tests/language/closure/internals_test.dart
new file mode 100644
index 0000000..78f04ab
--- /dev/null
+++ b/tests/language/closure/internals_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class C {
+  foo() => 123;
+}
+
+main() {
+  var f = new C().foo;
+  var target = f.target;
+  //             ^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'target' isn't defined for the class 'dynamic Function()'.
+  var self = f.self;
+  //           ^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'self' isn't defined for the class 'dynamic Function()'.
+  var receiver = f.receiver;
+  //               ^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'receiver' isn't defined for the class 'dynamic Function()'.
+}
diff --git a/tests/language/closure/invoked_through_interface_target_field_test.dart b/tests/language/closure/invoked_through_interface_target_field_test.dart
new file mode 100644
index 0000000..a60f495
--- /dev/null
+++ b/tests/language/closure/invoked_through_interface_target_field_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.
+
+// Note: this test expects a compile error (getter overrides a method), but it
+// contains more code than necessary to provoke the compile error.  The reason
+// for the extra code is to document the complications that would arise if we
+// decided to eliminate the compile error (and allow getters to override
+// methods).
+
+import "package:expect/expect.dart";
+
+typedef void F<T>(T t);
+
+abstract class A {
+  void foo(Object n);
+}
+
+class C implements A {
+  F<Object> foo;
+  //        ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+  C(this.foo);
+}
+
+class D<T> {
+  void m(T t) {}
+}
+
+F<Object> bar(D<int> d) => d.m as dynamic;
+void baz(A a) {
+  Expect.throws(() {
+    // This call looks like it doesn't require any runtime type checking, since
+    // it is a call to a regular method with no covariant parameters.  However,
+    // if we decide to allow getters to override methods, then it's possible
+    // that it's actually invoking a getter that returns a closure, and that
+    // closure might have covariant parameters that need runtime type checks.
+    a.foo('hi');
+  });
+  // This call is ok because the types match up at runtime.
+  a.foo(1);
+}
+
+main() {
+  baz(new C(bar(new D<int>())));
+}
diff --git a/tests/language/closure/invoked_through_interface_target_getter_test.dart b/tests/language/closure/invoked_through_interface_target_getter_test.dart
new file mode 100644
index 0000000..05edef8
--- /dev/null
+++ b/tests/language/closure/invoked_through_interface_target_getter_test.dart
@@ -0,0 +1,46 @@
+// 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.
+
+// Note: this test expects a compile error (getter overrides a method), but it
+// contains more code than necessary to provoke the compile error.  The reason
+// for the extra code is to document the complications that would arise if we
+// decided to eliminate the compile error (and allow getters to override
+// methods).
+
+import "package:expect/expect.dart";
+
+typedef void F<T>(T t);
+
+abstract class A {
+  void foo(Object n);
+}
+
+class C implements A {
+  F<Object> get foo => bar(new D<int>());
+  //            ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class D<T> {
+  void m(T t) {}
+}
+
+F<Object> bar(D<int> d) => d.m as dynamic;
+void baz(A a) {
+  Expect.throws(() {
+    // This call looks like it doesn't require any runtime type checking, since
+    // it is a call to a regular method with no covariant parameters.  However,
+    // if we decide to allow getters to override methods, then it's possible
+    // that it's actually invoking a getter that returns a closure, and that
+    // closure might have covariant parameters that need runtime type checks.
+    a.foo('hi');
+  });
+  // This call is ok because the types match up at runtime.
+  a.foo(1);
+}
+
+main() {
+  baz(new C());
+}
diff --git a/tests/language/closure/minify_closure_variable_collision_test.dart b/tests/language/closure/minify_closure_variable_collision_test.dart
new file mode 100644
index 0000000..282acef
--- /dev/null
+++ b/tests/language/closure/minify_closure_variable_collision_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js, that used to minify a captured
+// variable's name to the same name as inherited Object methods.
+
+var array = [new A()];
+
+class A {
+  operator ==(other) {
+    return true;
+  }
+}
+
+foo() {
+  // Use lots of variables, to maximize the chance of collisions.
+  var a = 42;
+  var b = 42;
+  var c = 42;
+  var d = 42;
+  var e = 42;
+  var f = 42;
+  var g = 42;
+  var h = 42;
+  var i = 42;
+  var j = 42;
+  var k = 42;
+  var l = 42;
+  var m = 42;
+  var n = 42;
+  array[0] = () {
+    return a + b + c + d + e + f + g + h + i + j + k + l + m + n;
+  };
+}
+
+main() {
+  foo();
+  if (array[0] == new A()) {
+    throw 'Test failed';
+  }
+  if (array[0]() != 42 * 14) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/language/closure/nested_generic_closure_test.dart b/tests/language/closure/nested_generic_closure_test.dart
new file mode 100644
index 0000000..53fd1f9
--- /dev/null
+++ b/tests/language/closure/nested_generic_closure_test.dart
@@ -0,0 +1,49 @@
+// 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:expect/expect.dart';
+
+void foo(F f<F>(F f)) {}
+
+B bar<B>(B g<F>(F f)) => throw "uncalled";
+
+Function baz<B>() {
+  B foo<F>(B b, F f) => throw "uncalled";
+  return foo;
+}
+
+class C<T> {
+  void foo(F f<F>(T t, F f)) => null;
+  B bar<B>(B g<F>(T t, F f)) => throw "uncalled";
+  Function baz<B>() {
+    B foo<F>(T t, F f) => throw "uncalled";
+    return foo;
+  }
+}
+
+main() {
+  // Check the run-time type of the functions with generic parameters.
+
+  Expect.type<void Function(X Function<X>(X))>(foo);
+
+  Expect.isTrue(bar is X1 Function<X1>(X1 Function<X2>(X2)));
+
+  Expect.isTrue(baz<int>() is int Function<X1>(int, X1));
+  Expect.isTrue(baz<Object>() is Object Function<X1>(Object, X1));
+  Expect.isTrue(baz<Null>() is Null Function<X1>(Null, X1));
+
+  void testC<T>() {
+    var c = new C<T>();
+
+    Expect.type<void Function(F Function<F>(T, F))>(c.foo);
+
+    Expect.isTrue(c.bar is X1 Function<X1>(X1 Function<X2>(T, X2)));
+
+    Expect.isTrue(c.baz<int>() is int Function<X1>(T, X1));
+  }
+
+  testC<bool>();
+  testC<Object>();
+  testC<Null>();
+}
diff --git a/tests/language/closure/param_null_to_object_test.dart b/tests/language/closure/param_null_to_object_test.dart
new file mode 100644
index 0000000..e34f400
--- /dev/null
+++ b/tests/language/closure/param_null_to_object_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Requirements=nnbd-strong
+import "package:expect/expect.dart";
+
+main() {
+  // Pre-NNBD bottom type.
+  int Function(Null) f = (x) => 1; // Runtime type is int Function(Object?)
+  Expect.isTrue(f is int Function(Null));
+  Expect.isTrue(f is int Function(Never));
+  Expect.isTrue(f is int Function(String));
+  Expect.isTrue(f is int Function(Object));
+  Expect.isTrue(f is int Function(Object?));
+
+  // NNBD bottom type.
+  int Function(Never) g = (x) => 1; // Runtime type is int Function(Object?)
+  Expect.isTrue(g is int Function(Null));
+  Expect.isTrue(g is int Function(Never));
+  Expect.isTrue(g is int Function(String));
+  Expect.isTrue(g is int Function(Object));
+  Expect.isTrue(g is int Function(Object?));
+
+  int Function(String) h = (x) => 1; // Runtime type is int Function(String)
+  Expect.isFalse(h is int Function(Null));
+  Expect.isTrue(h is int Function(Never));
+  Expect.isTrue(h is int Function(String));
+  Expect.isFalse(h is int Function(Object));
+  Expect.isFalse(h is int Function(Object?));
+}
diff --git a/tests/language/closure/param_null_to_object_weak_test.dart b/tests/language/closure/param_null_to_object_weak_test.dart
new file mode 100644
index 0000000..31b8208
--- /dev/null
+++ b/tests/language/closure/param_null_to_object_weak_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Requirements=nnbd-weak
+import "package:expect/expect.dart";
+
+main() {
+  // Pre-NNBD bottom type.
+  int Function(Null) f = (x) => 1; // Runtime type is int Function(Object?)
+  Expect.isTrue(f is int Function(Null));
+  Expect.isTrue(f is int Function(Never));
+  Expect.isTrue(f is int Function(String));
+  Expect.isTrue(f is int Function(Object));
+  Expect.isTrue(f is int Function(Object?));
+
+  // NNBD bottom type.
+  int Function(Never) g = (x) => 1; // Runtime type is int Function(Object?)
+  Expect.isTrue(g is int Function(Null));
+  Expect.isTrue(g is int Function(Never));
+  Expect.isTrue(g is int Function(String));
+  Expect.isTrue(g is int Function(Object));
+  Expect.isTrue(g is int Function(Object?));
+
+  int Function(String) h = (x) => 1; // Runtime type is int Function(String)
+  Expect.isTrue(h is int Function(Null));
+  Expect.isTrue(h is int Function(Never));
+  Expect.isTrue(h is int Function(String));
+  Expect.isFalse(h is int Function(Object));
+  Expect.isFalse(h is int Function(Object?));
+}
diff --git a/tests/language/closure/parameter_types_test.dart b/tests/language/closure/parameter_types_test.dart
new file mode 100644
index 0000000..3fa1521
--- /dev/null
+++ b/tests/language/closure/parameter_types_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Regression test for dart2js, where the optimizer was too aggressive
+// about parameter types of closures.
+
+class A {
+  Function f;
+  A(this.f);
+  _do() => f(1);
+}
+
+main() {
+  int invokeCount = 0;
+  closure(a) {
+    if (invokeCount++ == 1) {
+      Expect.isTrue(a is int);
+    }
+  }
+
+  closure('s');
+  new A(closure)._do();
+  Expect.equals(2, invokeCount);
+}
diff --git a/tests/language/closure/parse_closures_in_initializers_test.dart b/tests/language/closure/parse_closures_in_initializers_test.dart
new file mode 100644
index 0000000..9fc7eda
--- /dev/null
+++ b/tests/language/closure/parse_closures_in_initializers_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+// Test that function literals are parsed correctly in initializers.
+
+class A {
+  final x;
+  static foo(f) => f();
+
+  A.parenthesized(y) : x = (() => y);
+  A.stringLiteral(y) : x = "**${() => y}--";
+  A.listLiteral(y) : x = [() => y];
+  A.mapLiteral(y) : x = {"fun": () => y};
+  A.arg(y) : x = foo(() => y);
+}
+
+main() {
+  var a, f;
+  a = new A.parenthesized(499);
+  f = a.x;
+  Expect.isTrue(f is Function);
+  Expect.equals(499, f());
+
+  // The toString of closures is not specified. Just make sure that there is no
+  // crash.
+  a = new A.stringLiteral(42);
+  Expect.isTrue(a.x.startsWith("**"));
+  Expect.isTrue(a.x.endsWith("--"));
+
+  a = new A.listLiteral(99);
+  f = a.x[0];
+  Expect.isTrue(f is Function);
+  Expect.equals(99, f());
+
+  a = new A.mapLiteral(314);
+  f = a.x["fun"];
+  Expect.isTrue(f is Function);
+  Expect.equals(314, f());
+
+  a = new A.arg(123);
+  Expect.equals(123, a.x);
+}
diff --git a/tests/language/closure/partial_instantiation_eager_bounds_check_test.dart b/tests/language/closure/partial_instantiation_eager_bounds_check_test.dart
new file mode 100644
index 0000000..d20a83e
--- /dev/null
+++ b/tests/language/closure/partial_instantiation_eager_bounds_check_test.dart
@@ -0,0 +1,21 @@
+// 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 test checks that necessary type argument bounds checks are performed
+// eagerly during partial instantiation, rather than being delayed until the
+// partially instantiated closure is invoked.
+
+import "package:expect/expect.dart";
+
+class C<T> {
+  void foo<S extends T>(S x) {}
+}
+
+void main() {
+  C<Object> c = C<int>();
+  void Function(String) fn;
+  Expect.throwsTypeError(() {
+    fn = c.foo;
+  });
+}
diff --git a/tests/language/closure/partial_instantiation_static_bounds_check_runtime_test.dart b/tests/language/closure/partial_instantiation_static_bounds_check_runtime_test.dart
new file mode 100644
index 0000000..4596750
--- /dev/null
+++ b/tests/language/closure/partial_instantiation_static_bounds_check_runtime_test.dart
@@ -0,0 +1,31 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+topFn<T extends num>(T x) {
+  print(T);
+}
+
+class C<T> {
+  instanceFn<S extends T>(S x) {
+    print(S);
+  }
+}
+
+class D<T> extends C<T> {
+  void foo() {
+
+  }
+}
+
+void main() {
+  localFn<T extends num>(T x) {
+    print(T);
+  }
+
+
+
+}
diff --git a/tests/language/closure/partial_instantiation_static_bounds_check_test.dart b/tests/language/closure/partial_instantiation_static_bounds_check_test.dart
new file mode 100644
index 0000000..38192ba
--- /dev/null
+++ b/tests/language/closure/partial_instantiation_static_bounds_check_test.dart
@@ -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 file.
+
+topFn<T extends num>(T x) {
+  print(T);
+}
+
+class C<T> {
+  instanceFn<S extends T>(S x) {
+    print(S);
+  }
+}
+
+class D<T> extends C<T> {
+  void foo() {
+    void Function(int) k = instanceFn;
+    //                     ^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+  }
+}
+
+void main() {
+  localFn<T extends num>(T x) {
+    print(T);
+  }
+
+  void Function(String) k0 = localFn;
+  //                         ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+  void Function(String) k1 = topFn;
+  //                         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+}
diff --git a/tests/language/closure/partial_tearoff_instantiation_test.dart b/tests/language/closure/partial_tearoff_instantiation_test.dart
new file mode 100644
index 0000000..629b3bd
--- /dev/null
+++ b/tests/language/closure/partial_tearoff_instantiation_test.dart
@@ -0,0 +1,121 @@
+// 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:expect/expect.dart";
+
+typedef F1 = void Function<T>(T);
+typedef void F2<T>(T v);
+
+dynamic defaultFLatest;
+
+void defaultF<T>(T v) {
+  defaultFLatest = v;
+}
+
+class X1 {
+  final F1 f;
+  const X1({this.f: defaultF});
+}
+
+class X2 {
+  final F2 f;
+  const X2({this.f: defaultF});
+}
+
+class Y1 {
+  F1 f = defaultF;
+}
+
+class Y2 {
+  F2 f = defaultF;
+}
+
+dynamic foo() {
+  if (defaultFLatest == -1) return -1;
+  return "not -1";
+}
+
+void main() {
+  {
+    var x = const X1();
+
+    // OK with implicit dynamic type argument.
+    x.f("hello1");
+    Expect.equals("hello1", defaultFLatest);
+
+    // OK with explicit dynamic type argument.
+    x.f<dynamic>("hello2");
+    Expect.equals("hello2", defaultFLatest);
+
+    // OK with correctly given argument type.
+    x.f<String>("hello3");
+    Expect.equals("hello3", defaultFLatest);
+
+    // OK with correctly given argument type.
+    x.f<int>(42);
+    Expect.equals(42, defaultFLatest);
+
+    // Not OK with incorrectly given argument type.
+    x.f<int>("hello"); //# 01: compile-time error
+
+    // Not OK with incorrectly given argument type.
+    x.f<int>(foo()); //# 02: runtime error
+
+    var y = new Y1();
+    y.f = defaultF;
+
+    // OK with implicit dynamic type argument.
+    y.f("hello4");
+    Expect.equals("hello4", defaultFLatest);
+
+    // OK with explicit dynamic type argument.
+    y.f<dynamic>("hello5");
+    Expect.equals("hello5", defaultFLatest);
+
+    // OK with correctly given argument type.
+    y.f<String>("hello6");
+    Expect.equals("hello6", defaultFLatest);
+
+    // OK with correctly given argument type.
+    y.f<int>(43);
+    Expect.equals(43, defaultFLatest);
+
+    // Not OK with incorrectly given argument type.
+    y.f<int>("hello"); //# 03: compile-time error
+
+    // Not OK with incorrectly given argument type.
+    y.f<int>(foo()); //# 04: runtime error
+  }
+  {
+    var x = const X2();
+
+    // OK with no type arguments.
+    x.f("hello1");
+    Expect.equals("hello1", defaultFLatest);
+
+    // Not OK with a type argument.
+    x.f<dynamic>("hello2"); //# 05: compile-time error
+
+    // Not OK with a type argument.
+    x.f<String>("hello3"); //# 06: compile-time error
+
+    var y = new Y2();
+    y.f = defaultF;
+
+    // OK with no type argument.
+    y.f("hello4");
+    Expect.equals("hello4", defaultFLatest);
+
+    // Not OK with a type argument.
+    y.f<dynamic>("hello5"); //# 07: compile-time error
+
+    // Not OK with a type argument.
+    y.f<String>("hello6"); //# 08: compile-time error
+
+    // Correct runtime type of x.f.
+    void instantiatedFType(dynamic _) {}
+    Expect.equals(x.f.runtimeType.toString(),
+        instantiatedFType.runtimeType.toString()); // #09: ok
+  }
+}
diff --git a/tests/language/closure/self_reference_test.dart b/tests/language/closure/self_reference_test.dart
new file mode 100644
index 0000000..a47b1bf
--- /dev/null
+++ b/tests/language/closure/self_reference_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+// Tests a self-reference of a closure inside a try/catch.
+// Dart2js must not try to box the closure-reference.
+
+main() {
+  var counter = 0;
+  inner(value) {
+    if (value == 0) return 0;
+    try {
+      return inner(value - 1);
+    } finally {
+      counter++;
+    }
+  }
+
+  Expect.equals(0, inner(199));
+  Expect.equals(199, counter);
+}
diff --git a/tests/language/closure/shared_state_test.dart b/tests/language/closure/shared_state_test.dart
new file mode 100644
index 0000000..85c9908
--- /dev/null
+++ b/tests/language/closure/shared_state_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Tests for closures sharing mutable bindings.
+
+var f;
+var g;
+
+setupPlain() {
+  int j = 1000;
+  // Two closures sharing variable 'j'; j initially is 1000.
+  f = (int x) {
+    var q = j;
+    j = x;
+    return q;
+  };
+  g = (int x) {
+    var q = j;
+    j = x;
+    return q;
+  };
+}
+
+setupLoop() {
+  for (int i = 0; i < 2; i++) {
+    int j = i * 1000; // The last stored closure has j initially 1000.
+    // Two closures sharing variable 'j'.
+    f = (int x) {
+      var q = j;
+      j = x;
+      return q;
+    };
+    g = (int x) {
+      var q = j;
+      j = x;
+      return q;
+    };
+  }
+}
+
+setupNestedLoop() {
+  for (int outer = 0; outer < 2; outer++) {
+    int j = outer * 1000;
+    for (int i = 0; i < 2; i++) {
+      // Two closures sharing variable 'j' in a loop at different nesting.
+      f = (int x) {
+        var q = j;
+        j = x;
+        return q;
+      };
+      g = (int x) {
+        var q = j;
+        j = x;
+        return q;
+      };
+    }
+  }
+}
+
+test(setup) {
+  setup();
+  Expect.equals(1000, f(100));
+  Expect.equals(100, f(200));
+  Expect.equals(200, f(300));
+  Expect.equals(300, g(400));
+  Expect.equals(400, g(500));
+}
+
+main() {
+  test(setupPlain);
+  test(setupLoop);
+  test(setupNestedLoop);
+}
diff --git a/tests/language/closure/side_effect_test.dart b/tests/language/closure/side_effect_test.dart
new file mode 100644
index 0000000..a7b0f50
--- /dev/null
+++ b/tests/language/closure/side_effect_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+typedef void VoidToVoid();
+
+var b;
+VoidToVoid a = () {
+  b = 42;
+};
+
+var c = [new C()];
+
+class C {
+  nonInlinable1() {
+    a();
+  }
+
+  nonInlinable2() {
+    var a = () {
+      b = 42;
+    };
+    a();
+  }
+}
+
+testClosureInStaticField() {
+  var temp = c[0];
+  Expect.isNull(b);
+  temp.nonInlinable1();
+  Expect.equals(42, b);
+  b = null;
+}
+
+testLocalClosure() {
+  var temp = c[0];
+  Expect.isNull(b);
+  temp.nonInlinable2();
+  Expect.equals(42, b);
+}
+
+main() {
+  testClosureInStaticField();
+  testLocalClosure();
+}
diff --git a/tests/language/closure/tearoff_bounds_instantiation_test.dart b/tests/language/closure/tearoff_bounds_instantiation_test.dart
new file mode 100644
index 0000000..b823c64
--- /dev/null
+++ b/tests/language/closure/tearoff_bounds_instantiation_test.dart
@@ -0,0 +1,20 @@
+// 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 test checks that the type parameter bounds on tearoffs from generic
+// classes are properly instantiated in the signature of the tearoff.
+
+import "package:expect/expect.dart";
+
+class C<T> {
+  void foo<S extends T>(S x) {}
+}
+
+void foo<S extends int>(S x) {}
+
+void main() {
+  dynamic c = C<int>();
+  dynamic fn = c.foo;
+  Expect.equals("${fn.runtimeType}", "${foo.runtimeType}");
+}
diff --git a/tests/language/closure/tearoff_dynamic_test.dart b/tests/language/closure/tearoff_dynamic_test.dart
new file mode 100644
index 0000000..08b9091
--- /dev/null
+++ b/tests/language/closure/tearoff_dynamic_test.dart
@@ -0,0 +1,170 @@
+// 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:expect/expect.dart';
+
+class C {
+  dynamic f(int x) => x + 1;
+  dynamic g(int x) => x + 2;
+}
+
+class D extends C {
+  f(int x) => x + 41;
+  get superF => super.f;
+  get superG => super.g;
+}
+
+tearoffEquals(f1, f2) {
+  Expect.equals(f1, f2);
+  Expect.equals(f1.hashCode, f2.hashCode);
+}
+
+tearoffNotEquals(f1, f2) {
+  Expect.notEquals(f1, f2);
+  Expect.notEquals(f1.hashCode, f2.hashCode);
+}
+
+testDynamic() {
+  C c = new C();
+
+  dynamic f1 = c.f;
+  Expect.throws(() => f1(2.5));
+  Expect.equals(f1(41), 42);
+
+  dynamic f2 = (c as dynamic).f;
+  Expect.throws(() => f2(2.5));
+  Expect.equals(f2(41), 42);
+
+  tearoffEquals(f1, f1);
+  tearoffEquals(f1, f2);
+  tearoffEquals(f1, c.f);
+  tearoffEquals(c.g, (c as dynamic).g);
+
+  tearoffNotEquals(f1, new C().f);
+  tearoffNotEquals(f1, (new C() as dynamic).f);
+  tearoffNotEquals(f1, c.g);
+  tearoffNotEquals(f1, (c as dynamic).g);
+  tearoffNotEquals(null, f1);
+  tearoffNotEquals(f1, null);
+}
+
+testSuper() {
+  D d = new D();
+  dynamic superF1 = d.superF;
+  dynamic superF2 = (d as dynamic).superF;
+
+  Expect.throws(() => superF1(2.5));
+  Expect.throws(() => superF2(2.5));
+  Expect.equals(superF1(41), 42);
+  Expect.equals(superF2(41), 42);
+
+  tearoffEquals(superF1, superF1);
+  tearoffEquals(superF1, superF2);
+  tearoffEquals(superF1, d.superF);
+  tearoffEquals(d.f, (d as dynamic).f);
+
+  tearoffNotEquals(superF1, d.f);
+  tearoffNotEquals(superF1, (d as dynamic).f);
+  tearoffNotEquals(superF1, new D().superF);
+  tearoffNotEquals(superF1, (new D() as dynamic).superF);
+  tearoffNotEquals(superF1, d.superG);
+  tearoffNotEquals(superF1, (d as dynamic).superG);
+
+  tearoffEquals(d.superG, (d as dynamic).superG);
+  tearoffEquals(d.g, d.superG);
+}
+
+class S {
+  final int id;
+  S(this.id);
+  toString() => 'S#$id';
+}
+
+testToString() {
+  testType<T>(T c) {
+    dynamic d = c;
+    Object? o = c;
+    tearoffEquals(c.toString, d.toString);
+    tearoffEquals(c.toString, o.toString);
+
+    var expected = c.toString();
+    dynamic f = d.toString;
+    tearoffEquals(f(), expected);
+    f = o.toString;
+    tearoffEquals(f(), expected);
+    var g = c.toString;
+    tearoffEquals(g(), expected);
+  }
+
+  testType(new C());
+  testType(new D());
+  testType(new S(1));
+  testType(new S(2));
+  testType(new Object());
+  testType(null);
+  testType(Object); // Type
+  testType(C); // Type
+  testType(42);
+  testType('hi');
+  testType(true);
+  testType([1, 2, 3]);
+  testType({'a': 'b'});
+  testType((x) => x + 1);
+  testType(testType as dynamic); // illegal inferred type for T otherwise
+}
+
+class N {
+  noSuchMethod(i) => i;
+}
+
+testNoSuchMethod() {
+  // Create an invocation.
+  Invocation i = (new N() as dynamic).foo(1, bar: 2);
+  tearoffEquals(i.memberName, #foo);
+
+  testType<T>(T c) {
+    dynamic d = c;
+    Object? o = c;
+    tearoffEquals(c.noSuchMethod, d.noSuchMethod);
+    tearoffEquals(c.noSuchMethod, o.noSuchMethod);
+
+    var expected;
+    try {
+      c.noSuchMethod(i);
+    } on NoSuchMethodError catch (error) {
+      var nsm = '$error';
+      Expect.isTrue(nsm.startsWith("NoSuchMethodError: "));
+      Expect.isTrue(nsm.contains("'foo'"));
+      expected = (e) => e is NoSuchMethodError && '$e' == nsm;
+    }
+    dynamic f = d.noSuchMethod;
+    Expect.throws(() => f(i), expected);
+    f = o.noSuchMethod;
+    Expect.throws(() => f(i), expected);
+    var g = c.noSuchMethod;
+    Expect.throws(() => g(i), expected);
+  }
+
+  testType(new C());
+  testType(new D());
+  testType(new S(1));
+  testType(new S(2));
+  testType(new Object());
+  testType(null);
+  testType(Object); // Type
+  testType(C); // Type
+  testType(42);
+  testType('hi');
+  testType(true);
+  testType([1, 2, 3]);
+  testType({'a': 'b'});
+  testType((x) => x + 1);
+  testType(testType as dynamic); // illegal inferred type for T otherwise
+}
+
+main() {
+  testDynamic();
+  testSuper();
+  testToString();
+  testNoSuchMethod();
+}
diff --git a/tests/language/closure/type_arguments_test.dart b/tests/language/closure/type_arguments_test.dart
new file mode 100644
index 0000000..f046f83
--- /dev/null
+++ b/tests/language/closure/type_arguments_test.dart
@@ -0,0 +1,42 @@
+// 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:expect/expect.dart";
+
+typedef MapFunc<S1, S2> = void Function(Map<S1, S2>? arg);
+
+class A<P> {
+  final List barTypeArguments = [];
+
+  void foo<Q, Q1 extends P, Q2 extends Q, Q3 extends P, Q4 extends Q>() {
+    void bar<T1 extends P, T2 extends Q>(Map<T1, T2>? arg) {
+      barTypeArguments..add(T1)..add(T2);
+    }
+
+    // Call with explicit type arguments.
+    bar<Q1, Q2>(null);
+
+    // No explicit type arguments - should be instantiated to bounds.
+    bar(null);
+
+    // Partial tear-off instantiation.
+    MapFunc<Q3, Q4> instantiated = bar;
+    instantiated(null);
+  }
+}
+
+abstract class MyIterable implements Iterable {}
+
+main() {
+  final a = new A<num>();
+  a.foo<Iterable, int, List, double, MyIterable>();
+  Expect.listEquals(
+      [int, List, num, Iterable, double, MyIterable], a.barTypeArguments);
+
+  // Test instantiation to bounds in the enclosing method.
+  dynamic b = new A<int>();
+  b.foo();
+  Expect.listEquals(
+      [int, dynamic, int, dynamic, int, dynamic], b.barTypeArguments);
+}
diff --git a/tests/language/closure/type_test.dart b/tests/language/closure/type_test.dart
new file mode 100644
index 0000000..90ba188
--- /dev/null
+++ b/tests/language/closure/type_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for a closure result type test that cannot be eliminated at compile
+// time.
+
+import "package:expect/expect.dart";
+
+void test(A func(String value), String value) {
+  Expect.throwsTypeError(() {
+    func(value) as B;
+  });
+}
+
+
+class A {
+}
+
+class B extends A {
+}
+
+class C {
+  static A a(String x) => new A();
+}
+
+A aclosure(String x) => C.a(x);
+A bclosure() => new A();
+
+main() {
+  test(aclosure, "foo");
+  test((bar) => bclosure(), "baz");
+}
diff --git a/tests/language/closure/type_variable_test.dart b/tests/language/closure/type_variable_test.dart
new file mode 100644
index 0000000..2ed61c2
--- /dev/null
+++ b/tests/language/closure/type_variable_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the type argument is available inside a closure.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  foo() {
+    bar() => T;
+    return bar();
+  }
+}
+
+main() {
+  Expect.equals(new A<int>().foo(), int);
+}
diff --git a/tests/language/closure/type_variables_test.dart b/tests/language/closure/type_variables_test.dart
new file mode 100644
index 0000000..2fe276c
--- /dev/null
+++ b/tests/language/closure/type_variables_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import "package:expect/expect.dart";
+
+// Test that type variables are available in closures.
+
+class A<T> {
+  A();
+
+  A.bar() {
+    g() {
+      new A<T>();
+    }
+
+    g();
+  }
+
+  foo() {
+    g() {
+      return new A<T>();
+    }
+
+    return g();
+  }
+}
+
+class B<K> {
+  makeBaz() {
+    return (K key) async {
+      return null;
+    };
+  }
+}
+
+typedef Future<Null> aBaz(int a);
+
+main() {
+  Expect.isTrue(new A<int>().foo() is A<int>);
+  Expect.isTrue(new A<int>.bar().foo() is A<int>);
+  Expect.isTrue(new B<int>().makeBaz() is aBaz);
+}
diff --git a/tests/language/closure/unnamed_closure_test.dart b/tests/language/closure/unnamed_closure_test.dart
new file mode 100644
index 0000000..49fa570
--- /dev/null
+++ b/tests/language/closure/unnamed_closure_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+getNonArray() => new A();
+
+class A {
+  operator [](index) => index;
+}
+
+main() {
+  Expect.equals(42, () {
+    var res;
+    do {
+      var a = getNonArray();
+      res = a[42];
+    } while (false);
+    return res;
+  }());
+}
diff --git a/tests/language/closure/variable_shadow_test.dart b/tests/language/closure/variable_shadow_test.dart
new file mode 100644
index 0000000..4b1edb4
--- /dev/null
+++ b/tests/language/closure/variable_shadow_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// The intermediate variable 'y' must either be preserved
+// or parameters must be renamed.
+
+foo(x) {
+  var y = x;
+  bar(x) {
+    return y - x;
+  }
+
+  return bar;
+}
+
+main() {
+  Expect.equals(-10, foo(10)(20));
+}
diff --git a/tests/language/closure/with_super_field_test.dart b/tests/language/closure/with_super_field_test.dart
new file mode 100644
index 0000000..68cc3be
--- /dev/null
+++ b/tests/language/closure/with_super_field_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "package:meta/meta.dart" show virtual;
+
+class A {
+  @virtual
+  int a;
+  A() : a = 42;
+}
+
+class B extends A {
+  int get a => 54;
+  returnSuper() => super.a;
+  returnSuperInClosure() => () => super.a;
+}
+
+main() {
+  B b = new B();
+  Expect.equals(54, b.a);
+  Expect.equals(42, b.returnSuper());
+  Expect.equals(42, b.returnSuperInClosure()());
+}
diff --git a/tests/language/closure/with_super_send_test.dart b/tests/language/closure/with_super_send_test.dart
new file mode 100644
index 0000000..bcaae49
--- /dev/null
+++ b/tests/language/closure/with_super_send_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test a closurized super send.
+
+class Super {
+  m() => "super";
+}
+
+class Sub extends Super {
+  m() => "sub";
+
+  test() {
+    var x;
+    [0].forEach((e) => x = super.m());
+    return x;
+  }
+}
+
+main() {
+  Expect.equals("super", new Sub().test());
+  Expect.equals("super", new Super().m());
+  Expect.equals("sub", new Sub().m());
+}
diff --git a/tests/language/const/cast1_test.dart b/tests/language/const/cast1_test.dart
new file mode 100644
index 0000000..2363f3f
--- /dev/null
+++ b/tests/language/const/cast1_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+/// Implicit casts in constants are supported and treated as compile-time errors
+/// if they are not valid.
+
+class A {
+  final int n;
+  const A(dynamic input) : n = input;
+}
+
+main() {
+  print(const A(2)); //# 01: ok
+  print(const A('2')); //# 02: compile-time error
+}
diff --git a/tests/language/const/cast2_test.dart b/tests/language/const/cast2_test.dart
new file mode 100644
index 0000000..326a884
--- /dev/null
+++ b/tests/language/const/cast2_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+/// Explicit casts in constants are supported and treated as compile-time errors
+/// if they are not valid.
+
+class A {
+  final int n;
+  const A(dynamic input) : n = input as int;
+}
+
+main() {
+  print(const A(2)); //# 01: ok
+  print(const A('2')); //# 02: compile-time error
+}
diff --git a/tests/language/const/cast3_test.dart b/tests/language/const/cast3_test.dart
new file mode 100644
index 0000000..f7d7354
--- /dev/null
+++ b/tests/language/const/cast3_test.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.
+
+/// Casts in constants correctly substitute type variables.
+
+class A {
+  const A();
+}
+
+class B implements A {
+  const B();
+}
+
+class M<T extends A> {
+  final T a;
+  const M(dynamic t) : a = t; // adds implicit cast `as T`
+}
+
+main() {
+  print(const M<B>(const B()));
+}
diff --git a/tests/language/const/cast4_test.dart b/tests/language/const/cast4_test.dart
new file mode 100644
index 0000000..cb7a250
--- /dev/null
+++ b/tests/language/const/cast4_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+/// Casts in constants correctly substitute type variables.
+
+class A {
+  const A();
+}
+
+class B implements A {
+  const B();
+}
+
+class M<T extends A> {
+  final T a;
+  const M(dynamic t) : a = t; // adds implicit cast `as T`
+}
+
+class N<S extends A> extends M<S> {
+  const N(dynamic t) : super(t);
+}
+
+main() {
+  print(const N<B>(const B()));
+}
diff --git a/tests/language/const/conditional_runtime_test.dart b/tests/language/const/conditional_runtime_test.dart
new file mode 100644
index 0000000..5b9d8c8
--- /dev/null
+++ b/tests/language/const/conditional_runtime_test.dart
@@ -0,0 +1,59 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for conditionals as compile-time constants.
+
+import 'package:expect/expect.dart';
+
+class Marker {
+  final field;
+  const Marker(this.field);
+}
+
+var var0 = const Marker(0);
+var var1 = const Marker(1);
+const const0 = const Marker(0);
+const const1 = const Marker(1);
+
+const trueConst = true;
+const falseConst = false;
+var nonConst = true;
+const zeroConst = 0;
+
+const cond1 = trueConst ? const0 : const1;
+
+
+
+const cond2 = falseConst ? const0 : const1;
+
+
+
+
+
+
+
+
+
+
+
+void main() {
+  Expect.identical(var0, cond1);
+
+
+
+  Expect.identical(var1, cond2);
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/const/conditional_test.dart b/tests/language/const/conditional_test.dart
new file mode 100644
index 0000000..33aec86
--- /dev/null
+++ b/tests/language/const/conditional_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for conditionals as compile-time constants.
+
+import 'package:expect/expect.dart';
+
+class Marker {
+  final field;
+  const Marker(this.field);
+}
+
+var var0 = const Marker(0);
+var var1 = const Marker(1);
+const const0 = const Marker(0);
+const const1 = const Marker(1);
+
+const trueConst = true;
+const falseConst = false;
+var nonConst = true;
+const zeroConst = 0;
+
+const cond1 = trueConst ? const0 : const1;
+const cond1a = trueConst ? nonConst : const1;
+//                       ^
+// [cfe] Constant evaluation error:
+//                         ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+const cond1b = trueConst ? const0 : nonConst;
+//                                  ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+
+const cond2 = falseConst ? const0 : const1;
+const cond2a = falseConst ? nonConst : const1;
+//                          ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+const cond2b = falseConst ? const0 : nonConst;
+//                        ^
+// [cfe] Constant evaluation error:
+//                                   ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+
+const cond3 = nonConst ? const0 : const1;
+//            ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+//                     ^
+// [cfe] Constant evaluation error:
+const cond3a = nonConst ? nonConst : const1;
+//             ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+//                      ^
+// [cfe] Constant evaluation error:
+//                        ^
+// [cfe] Not a constant expression.
+const cond3b = nonConst ? const0 : nonConst;
+//             ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Not a constant expression.
+//                      ^
+// [cfe] Constant evaluation error:
+//                                 ^
+// [cfe] Not a constant expression.
+
+const cond4 = zeroConst ? const0 : const1;
+//            ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_BOOL
+// [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+//            ^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+const cond4a = zeroConst ? nonConst : const1;
+//             ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_BOOL
+// [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+//             ^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+//                         ^
+// [cfe] Not a constant expression.
+const cond4b = zeroConst ? const0 : nonConst;
+//             ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_BOOL
+// [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+//             ^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+//                                  ^
+// [cfe] Not a constant expression.
+
+void main() {
+  Expect.identical(var0, cond1);
+  Expect.identical(nonConst, cond1a);
+  Expect.identical(var0, cond1b);
+
+  Expect.identical(var1, cond2);
+  Expect.identical(var1, cond2a);
+  Expect.identical(nonConst, cond2b);
+
+  Expect.identical(var0, cond3);
+  Expect.identical(nonConst, cond3a);
+  Expect.identical(var0, cond3b);
+
+  Expect.identical(var1, cond4);
+  Expect.identical(var1, cond4a);
+  Expect.identical(nonConst, cond4b);
+}
diff --git a/tests/language/const/const2_test.dart b/tests/language/const/const2_test.dart
new file mode 100644
index 0000000..6a9f94e
--- /dev/null
+++ b/tests/language/const/const2_test.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=
+// VMOptions=--compile_all
+
+// Exercises language constructs that require compile time constants
+
+// Initialize with different literal types
+const b = true;
+const s = "apple";
+const i = 1;
+const d = 3.3;
+const h = 0xf;
+const n = null;
+const aList = const [1, 2, 3]; // array literal
+const aMap = const {"1": "one", "2": "banana"}; // map literal
+
+const INT_LIT = 5;
+const INT_LIT_REF = INT_LIT;
+const DOUBLE_LIT = 1.5;
+const BOOL_LIT = true;
+const STRING_LIT = "Hello";
+
+const BOP1_0 = INT_LIT + 1;
+const BOP1_1 = 1 + INT_LIT;
+const BOP1_2 = INT_LIT - 1;
+const BOP1_3 = 1 - INT_LIT;
+const BOP1_4 = INT_LIT * 1;
+const BOP1_5 = 1 * INT_LIT;
+const BOP1_6 = INT_LIT / 1;
+const BOP1_7 = 1 / INT_LIT;
+const BOP2_0 = DOUBLE_LIT + 1.5;
+const BOP2_1 = 1.5 + DOUBLE_LIT;
+const BOP2_2 = DOUBLE_LIT - 1.5;
+const BOP2_3 = 1.5 - DOUBLE_LIT;
+const BOP2_4 = DOUBLE_LIT * 1.5;
+const BOP2_5 = 1.5 * DOUBLE_LIT;
+const BOP2_6 = DOUBLE_LIT / 1.5;
+const BOP2_7 = 1.5 / DOUBLE_LIT;
+const BOP3_0 = 2 < INT_LIT;
+const BOP3_1 = INT_LIT < 2;
+const BOP3_2 = 2 > INT_LIT;
+const BOP3_3 = INT_LIT > 2;
+const BOP3_4 = 2 < DOUBLE_LIT;
+const BOP3_5 = DOUBLE_LIT < 2;
+const BOP3_6 = 2 > DOUBLE_LIT;
+const BOP3_7 = DOUBLE_LIT > 2;
+const BOP3_8 = 2 <= INT_LIT;
+const BOP3_9 = INT_LIT <= 2;
+const BOP3_10 = 2 >= INT_LIT;
+const BOP3_11 = INT_LIT >= 2;
+const BOP3_12 = 2.0 <= DOUBLE_LIT;
+const BOP3_13 = DOUBLE_LIT <= 2.0;
+const BOP3_14 = 2.0 >= DOUBLE_LIT;
+const BOP3_15 = DOUBLE_LIT >= 2;
+const BOP4_0 = 5 % INT_LIT;
+const BOP4_1 = INT_LIT % 5;
+const BOP4_2 = 5.0 % DOUBLE_LIT;
+const BOP4_3 = DOUBLE_LIT % 5.0;
+const BOP5_0 = 0x80 & 0x04;
+const BOP5_1 = 0x80 | 0x04;
+const BOP5_2 = 0x80 << 0x04;
+const BOP5_3 = 0x80 >> 0x04;
+const BOP5_4 = 0x80 ~/ 0x04;
+const BOP5_5 = 0x80 ^ 0x04;
+const BOP6 = BOOL_LIT && true;
+const BOP7 = false || BOOL_LIT;
+const BOP8 = STRING_LIT == "World!";
+const BOP9 = "Hello" != STRING_LIT;
+const BOP10 = INT_LIT == INT_LIT_REF;
+const BOP11 = BOOL_LIT != true;
+
+// Multiple binary expressions
+const BOP20 = 1 * INT_LIT / 3 + INT_LIT + 9;
+
+// Parenthised expressions
+const BOP30 = (1 > 2);
+const BOP31 = (1 * 2) + 3;
+const BOP32 = 3 + (1 * 2);
+
+// Unary expressions
+const UOP1_0 = !BOOL_LIT;
+const UOP1_1 = BOOL_LIT || !true;
+const UOP1_2 = !BOOL_LIT || true;
+const UOP1_3 = !(BOOL_LIT && true);
+const UOP2_0 = ~0xf0;
+const UOP2_1 = ~INT_LIT;
+const UOP2_2 = ~INT_LIT & 123;
+const UOP2_3 = ~(INT_LIT | 0xff);
+const UOP3_0 = -0xf0;
+const UOP3_1 = -INT_LIT;
+const UOP3_2 = -INT_LIT + 123;
+const UOP3_3 = -(INT_LIT * 0xff);
+const UOP3_4 = -0xf0;
+const UOP3_5 = -DOUBLE_LIT;
+const UOP3_6 = -DOUBLE_LIT + 123;
+const UOP3_7 = -(DOUBLE_LIT * 0xff);
+
+class A {
+  const A();
+  static const a = const A(); // Assignment from Constant constructor OK
+}
+
+main() {}
diff --git a/tests/language/const/const3_test.dart b/tests/language/const/const3_test.dart
new file mode 100644
index 0000000..8872c57
--- /dev/null
+++ b/tests/language/const/const3_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that initializers of const fields can be declared out of order.
+
+import "package:expect/expect.dart";
+
+const P = 2 * (O - N);
+const N = 1;
+const O = 1 + 3;
+
+void main() {
+  Expect.equals(1, N);
+  Expect.equals(4, O);
+  Expect.equals(6, P);
+}
diff --git a/tests/language/const/const4_lib.dart b/tests/language/const/const4_lib.dart
new file mode 100644
index 0000000..c9d2840
--- /dev/null
+++ b/tests/language/const/const4_lib.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// See CTConst4Test.dart
+
+library CTConst4Lib;
+
+const B = 1;
diff --git a/tests/language/const/const4_test.dart b/tests/language/const/const4_test.dart
new file mode 100644
index 0000000..c47f33c
--- /dev/null
+++ b/tests/language/const/const4_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check compile-time constant library references with prefixes
+
+library CTConst4Test;
+
+import "package:expect/expect.dart";
+import "const4_lib.dart" as mylib;
+
+const A = mylib.B;
+
+main() {
+  Expect.equals(1, A);
+}
diff --git a/tests/language/const/const_locals_constant_locals_test.dart b/tests/language/const/const_locals_constant_locals_test.dart
new file mode 100644
index 0000000..9f937df
--- /dev/null
+++ b/tests/language/const/const_locals_constant_locals_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that constant local variables have constant initializers.
+
+import "package:expect/expect.dart";
+
+void main() {
+  const c1;
+  //    ^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED
+  //      ^
+  // [cfe] The const variable ';' must be initialized.
+  const c2 = 0;
+  const c3 = field;
+  //         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  // [cfe] Constant evaluation error:
+  //         ^
+  // [cfe] Not a constant expression.
+  const c4 = finalField;
+  //         ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  // [cfe] Constant evaluation error:
+  //         ^
+  // [cfe] Not a constant expression.
+  const c5 = constField;
+  const c6 = method();
+  //         ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  // [cfe] Method invocation is not a constant expression.
+  const c7 = new Class();
+  //         ^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  // [cfe] New expression is not a constant expression.
+  const c8 = const Class();
+}
+
+var field = 0;
+
+final finalField = 0;
+
+const constField = 0;
+
+method() => 0;
+
+class Class {
+  const Class();
+}
diff --git a/tests/language/const/const_locals_runtime_test.dart b/tests/language/const/const_locals_runtime_test.dart
new file mode 100644
index 0000000..efabff5
--- /dev/null
+++ b/tests/language/const/const_locals_runtime_test.dart
@@ -0,0 +1,33 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that constant local variables have constant initializers.
+
+import "package:expect/expect.dart";
+
+void main() {
+
+  const c2 = 0;
+
+
+  const c5 = constField;
+
+
+  const c8 = const Class();
+}
+
+var field = 0;
+
+final finalField = 0;
+
+const constField = 0;
+
+method() => 0;
+
+class Class {
+  const Class();
+}
diff --git a/tests/language/const/const_test.dart b/tests/language/const/const_test.dart
new file mode 100644
index 0000000..d97f547
--- /dev/null
+++ b/tests/language/const/const_test.dart
@@ -0,0 +1,43 @@
+// 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.
+// Check const classes.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+class AConst {
+  const AConst() : b_ = 3;
+  final int b_;
+}
+
+class BConst {
+  const BConst();
+  set foo(value) {}
+  get foo {
+    return 5;
+  }
+
+  operator [](ix) {
+    return ix;
+  }
+
+  operator []=(ix, value) {}
+}
+
+testMain() {
+  var o = const AConst();
+  Expect.equals(3, o.b_);
+
+  var x = (const BConst()).foo++;
+  Expect.equals(5, x);
+
+  var y = (const BConst())[5]++;
+  Expect.equals(5, y);
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testMain();
+  }
+}
diff --git a/tests/language/const/constants_test.dart b/tests/language/const/constants_test.dart
new file mode 100644
index 0000000..5864dbe
--- /dev/null
+++ b/tests/language/const/constants_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+class C {
+  factory C() => C._();
+
+  C._();
+}
+
+const
+// [error line 11, column 1, length 5]
+// [analyzer] SYNTACTIC_ERROR.EXTRANEOUS_MODIFIER
+// [cfe] Can't have modifier 'const' here.
+t() => null;
+
+const
+// [error line 17, column 1, length 5]
+// [analyzer] SYNTACTIC_ERROR.EXTRANEOUS_MODIFIER
+// [cfe] Can't have modifier 'const' here.
+get v => null;
+
+main() {
+  const
+      dynamic x = t();
+      //          ^^^
+      // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+      // [cfe] Method invocation is not a constant expression.
+  const y = const C();
+  //        ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  //        ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
+  //              ^
+  // [cfe] Cannot invoke a non-'const' factory where a const expression is expected.
+  const
+      dynamic z = v;
+      //          ^
+      // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+      // [cfe] Constant evaluation error:
+}
diff --git a/tests/language/const/constructor2_test.dart b/tests/language/const/constructor2_test.dart
new file mode 100644
index 0000000..e8a5d63
--- /dev/null
+++ b/tests/language/const/constructor2_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 14348.
+
+class A<T> {
+  const A();
+}
+
+class B<S> extends A<S> {
+  const B();
+}
+
+class C<U> {
+  final A<U> a;
+
+  const C(A<U> this.a);
+  const C.optional([A<U> this.a = const A()]);
+  const C.named({A<U> this.a = const A()});
+  const C.untyped(this.a);
+  const C.subtyped(B<U> this.a);
+  const factory C.redirecting(B<U> a) = D<U>;
+}
+
+class D<U> extends C<U> {
+  const D(B<U> b) : super(b);
+}
+
+class E {
+  const factory E.redirecting1(int a) = F<int>;
+  const factory E.redirecting2(int a) = F<int>.redirecting;
+  const factory E.redirecting3(double a) = F<double>.redirecting;
+}
+
+class F<V> implements E {
+  final V field;
+
+  const F(this.field);
+  const factory F.redirecting(V field) = G<V>;
+}
+
+class G<W> implements F<W> {
+  final W field;
+  const G(W field) : this.field = field;
+}
+
+main() {
+  const A<int> a = const B<int>();
+
+  const C(a); //# 01: ok
+  const C.optional(a); //# 02: ok
+  const C.named(a: a); //# 03: ok
+  const C.untyped(a); //# 04: ok
+
+  // Can't infer type argument U for C since a has type A and the argument has
+  // type B<U>, not A<U>. So tries to assign A<int> to B<dynamic> which fails.
+  const C.subtyped(a); //# 05: compile-time error
+  const C.redirecting(a); //# 06: compile-time error
+
+  const C<int>(a); //# 07: ok
+  const C<int>.optional(a); //# 08: ok
+  const C<int>.named(a: a); //# 09: ok
+  const C<int>.untyped(a); //# 10: ok
+
+  // These are compile-time errors with NNBD because of the implicit downcasts.
+  const C<int>.subtyped(a); //# 11: compile-time error
+  const C<int>.redirecting(a); //# 12: compile-time error
+
+  const C<double>(a); //# 13: compile-time error
+  const C<double>.optional(a); //# 14: compile-time error
+  const C<double>.named(a: a); //# 15: compile-time error
+  const C<double>.untyped(a); //# 16: compile-time error
+  const C<double>.subtyped(a); //# 17: compile-time error
+  const C<double>.redirecting(a); //# 18: compile-time error
+
+  const E.redirecting1(0); //# 19: ok
+  const E.redirecting1(''); //# 20: compile-time error
+  const E.redirecting2(0); //# 21: ok
+  const E.redirecting2(''); //# 22: compile-time error
+  const E.redirecting3(0.0); //# 23: ok
+  const E.redirecting3(''); //# 24: compile-time error
+}
diff --git a/tests/language/const/constructor3_runtime_1_test.dart b/tests/language/const/constructor3_runtime_1_test.dart
new file mode 100644
index 0000000..2a970db
--- /dev/null
+++ b/tests/language/const/constructor3_runtime_1_test.dart
@@ -0,0 +1,28 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  final double d;
+  const C(this.d);
+}
+
+class D extends C {
+  const D(var d) : super(d);
+}
+
+const intValue = 0;
+const c = const C(0.0);
+
+
+
+
+main() {
+  print(c);
+
+
+
+}
diff --git a/tests/language/const/constructor3_runtime_2_test.dart b/tests/language/const/constructor3_runtime_2_test.dart
new file mode 100644
index 0000000..799f5d7
--- /dev/null
+++ b/tests/language/const/constructor3_runtime_2_test.dart
@@ -0,0 +1,28 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  final double d;
+  const C(this.d);
+}
+
+class D extends C {
+  const D(var d) : super(d);
+}
+
+const intValue = 0;
+
+
+const e = const D(0.0);
+
+
+main() {
+
+
+  print(e);
+
+}
diff --git a/tests/language/const/constructor3_runtime_test.dart b/tests/language/const/constructor3_runtime_test.dart
new file mode 100644
index 0000000..5c2e771
--- /dev/null
+++ b/tests/language/const/constructor3_runtime_test.dart
@@ -0,0 +1,28 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  final double d;
+  const C(this.d);
+}
+
+class D extends C {
+  const D(var d) : super(d);
+}
+
+const intValue = 0;
+
+
+
+
+
+main() {
+
+
+
+
+}
diff --git a/tests/language/const/constructor3_test.dart b/tests/language/const/constructor3_test.dart
new file mode 100644
index 0000000..54191d1
--- /dev/null
+++ b/tests/language/const/constructor3_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  final double d;
+  const C(this.d);
+}
+
+class D extends C {
+  const D(var d) : super(d);
+}
+
+const intValue = 0;
+const c = const C(0.0);
+const d = const C(intValue);
+//                ^^^^^^^^
+// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+// [cfe] The argument type 'int' can't be assigned to the parameter type 'double'.
+//                ^^^^^^^^
+// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+const e = const D(0.0);
+const f = const D(intValue);
+//        ^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+//              ^
+// [cfe] Constant evaluation error:
+
+main() {
+  print(c);
+  print(d);
+  print(e);
+  print(f);
+}
diff --git a/tests/language/const/constructor_mixin2_runtime_test.dart b/tests/language/const/constructor_mixin2_runtime_test.dart
new file mode 100644
index 0000000..5ca87e9
--- /dev/null
+++ b/tests/language/const/constructor_mixin2_runtime_test.dart
@@ -0,0 +1,25 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Mixin {
+  var nonFinalField;
+}
+
+class A {
+  const A(foo);
+}
+
+class B extends A
+
+{
+  const B(foo) : super(foo);
+}
+
+main() {
+  var a = const B(42);
+
+}
diff --git a/tests/language/const/constructor_mixin2_test.dart b/tests/language/const/constructor_mixin2_test.dart
new file mode 100644
index 0000000..a7bc863
--- /dev/null
+++ b/tests/language/const/constructor_mixin2_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Mixin {
+  var nonFinalField;
+}
+
+class A {
+  const A(foo);
+}
+
+class B extends A
+    with Mixin
+{
+  const B(foo) : super(foo);
+//      ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
+//      ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD
+//               ^
+// [cfe] A constant constructor can't call a non-constant super constructor.
+}
+
+main() {
+  var a = const B(42);
+  a.nonFinalField = 54;
+}
diff --git a/tests/language/const/constructor_mixin3_test.dart b/tests/language/const/constructor_mixin3_test.dart
new file mode 100644
index 0000000..9eb4d76
--- /dev/null
+++ b/tests/language/const/constructor_mixin3_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Mixin {}
+
+class A {
+  const A();
+}
+
+class B extends A with Mixin {
+  const B();
+}
+
+main() {
+  var a = const B();
+}
diff --git a/tests/language/const/constructor_mixin_test.dart b/tests/language/const/constructor_mixin_test.dart
new file mode 100644
index 0000000..a177ce1
--- /dev/null
+++ b/tests/language/const/constructor_mixin_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Mixin {}
+
+class A {
+  const A(foo);
+}
+
+class B extends A with Mixin {
+  const B(foo) : super(foo);
+}
+
+main() {
+  var a = const B(42);
+}
diff --git a/tests/language/const/constructor_nonconst_field_runtime_test.dart b/tests/language/const/constructor_nonconst_field_runtime_test.dart
new file mode 100644
index 0000000..a08abbe
--- /dev/null
+++ b/tests/language/const/constructor_nonconst_field_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+
+  final int j = 1;
+  const A();
+}
+
+int f() {
+  return 3;
+}
+
+main() {
+  const A().j;
+}
diff --git a/tests/language/const/constructor_nonconst_field_test.dart b/tests/language/const/constructor_nonconst_field_test.dart
new file mode 100644
index 0000000..d2e7030
--- /dev/null
+++ b/tests/language/const/constructor_nonconst_field_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  final int i = f();
+  //            ^
+  // [cfe] Method invocation is not a constant expression.
+  final int j = 1;
+  const A();
+//^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST
+}
+
+int f() {
+  return 3;
+}
+
+main() {
+  const A().j;
+}
diff --git a/tests/language/const/constructor_nonconst_param_runtime_test.dart b/tests/language/const/constructor_nonconst_param_runtime_test.dart
new file mode 100644
index 0000000..5ba2bf7
--- /dev/null
+++ b/tests/language/const/constructor_nonconst_param_runtime_test.dart
@@ -0,0 +1,21 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class A {
+  const A(int a);
+}
+
+class B {
+
+  const B(dynamic v) //
+
+  ;
+}
+
+void main() {
+  const B("");
+}
diff --git a/tests/language/const/constructor_nonconst_param_test.dart b/tests/language/const/constructor_nonconst_param_test.dart
new file mode 100644
index 0000000..bca1b3e
--- /dev/null
+++ b/tests/language/const/constructor_nonconst_param_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+class A {
+  const A(int a);
+}
+
+class B {
+  final a;
+  const B(dynamic v) //
+      : a = A(v)
+      //    ^^^^
+      // [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
+      // [cfe] Constant evaluation error:
+      //    ^
+      // [cfe] Constant expression expected.
+  ;
+}
+
+void main() {
+  const B("");
+//^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+}
diff --git a/tests/language/const/constructor_runtime_test.dart b/tests/language/const/constructor_runtime_test.dart
new file mode 100644
index 0000000..3317ec1
--- /dev/null
+++ b/tests/language/const/constructor_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  final int x;
+  const A.named() : x = 42;
+  A() : x = -1;
+}
+
+main() {
+  Expect.equals(42, (const A<int>.named()).x);
+  Expect.equals(42, (new A<int>.named()).x);
+
+}
diff --git a/tests/language/const/constructor_super2_test.dart b/tests/language/const/constructor_super2_test.dart
new file mode 100644
index 0000000..f922769
--- /dev/null
+++ b/tests/language/const/constructor_super2_test.dart
@@ -0,0 +1,29 @@
+// 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:expect/expect.dart';
+
+class A {
+  final a;
+
+  const A(this.a);
+}
+
+class B extends A {
+  final b;
+
+  const B(a, this.b) : super(a);
+}
+
+@pragma('dart2js:noInline')
+foo() => const B(1, 2);
+
+@pragma('dart2js:noInline')
+bar() => const B(2, 2);
+
+void main() {
+  Expect.notEquals(foo(), bar());
+  Expect.notEquals(foo().a, bar().a);
+  Expect.equals(foo().b, bar().b);
+}
diff --git a/tests/language/const/constructor_super_runtime_test.dart b/tests/language/const/constructor_super_runtime_test.dart
new file mode 100644
index 0000000..aa555a62
--- /dev/null
+++ b/tests/language/const/constructor_super_runtime_test.dart
@@ -0,0 +1,36 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  final a;
+  A(this.a); // Not const.
+  const A.five() : a = 5;
+}
+
+class B extends A {
+  final b;
+  B(x)
+      : b = x + 1,
+        super(x);
+
+  // Const constructor cannot call non-const super constructor.
+
+}
+
+class C extends A {
+  C() : super(0);
+  // Implicit call to non-const constructor A(x).
+
+}
+
+main() {
+
+  var b1 = new B(0);
+
+}
diff --git a/tests/language/const/constructor_super_test.dart b/tests/language/const/constructor_super_test.dart
new file mode 100644
index 0000000..f710d15
--- /dev/null
+++ b/tests/language/const/constructor_super_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  final a;
+  A(this.a); // Not const.
+  const A.five() : a = 5;
+}
+
+class B extends A {
+  final b;
+  B(x)
+      : b = x + 1,
+        super(x);
+
+  // Const constructor cannot call non-const super constructor.
+  const B.zerofive() : b = 0, super(5);
+  //                          ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
+  // [cfe] A constant constructor can't call a non-constant super constructor.
+}
+
+class C extends A {
+  C() : super(0);
+  // Implicit call to non-const constructor A(x).
+  const C.named(x);
+  //    ^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
+  // [cfe] The superclass, 'A', has no unnamed constructor that takes no arguments.
+  //    ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NO_DEFAULT_SUPER_CONSTRUCTOR
+}
+
+main() {
+  var b = new B.zerofive();
+  var b1 = new B(0);
+  var c = new C.named("");
+}
diff --git a/tests/language/const/constructor_syntax_runtime_test.dart b/tests/language/const/constructor_syntax_runtime_test.dart
new file mode 100644
index 0000000..bccb4a8
--- /dev/null
+++ b/tests/language/const/constructor_syntax_runtime_test.dart
@@ -0,0 +1,38 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+main() {
+
+
+  var c1 = const C1();
+
+  var c3 = const C3();
+}
+
+abstract class I0 {
+  factory I0() = C0;
+}
+
+class C0 implements I0 {
+  C0();
+}
+
+class C1 {
+  const C1();
+
+}
+
+class C2 {
+  C2();
+}
+
+class C3 {
+  const C3()
+
+  ;
+  final field = null;
+}
diff --git a/tests/language/const/constructor_syntax_test.dart b/tests/language/const/constructor_syntax_test.dart
new file mode 100644
index 0000000..99a420e
--- /dev/null
+++ b/tests/language/const/constructor_syntax_test.dart
@@ -0,0 +1,62 @@
+// 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.
+
+main() {
+  var c0 = const C0();
+  //       ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
+  //             ^
+  // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
+  var i0 = const I0();
+  //       ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
+  //             ^
+  // [cfe] Cannot invoke a non-'const' factory where a const expression is expected.
+  var c1 = const C1();
+  var c2 = const C2();
+  //       ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
+  //             ^
+  // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
+  var c3 = const C3();
+  //       ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+}
+
+abstract class I0 {
+  factory I0() = C0;
+}
+
+class C0 implements I0 {
+  C0();
+}
+
+class C1 {
+  const C1();
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
+//      ^
+// [cfe] Constructor is marked 'const' so all fields must be final.
+  var modifiable;
+}
+
+class C2 {
+  C2();
+}
+
+class C3 {
+  const C3()
+      : field = new C0()
+      //^^^^^
+      // [analyzer] STATIC_WARNING.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
+      //      ^
+      // [cfe] 'field' is a final instance variable that has already been initialized.
+      //      ^
+      // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
+      //        ^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
+      // [cfe] New expression is not a constant expression.
+  ;
+  final field = null;
+}
diff --git a/tests/language/const/constructor_test.dart b/tests/language/const/constructor_test.dart
new file mode 100644
index 0000000..6873889
--- /dev/null
+++ b/tests/language/const/constructor_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  final int x;
+  const A.named() : x = 42;
+  A() : x = -1;
+}
+
+main() {
+  Expect.equals(42, (const A<int>.named()).x);
+  Expect.equals(42, (new A<int>.named()).x);
+  const A<int>();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
+//      ^
+// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
+}
diff --git a/tests/language/const/counter_runtime_test.dart b/tests/language/const/counter_runtime_test.dart
new file mode 100644
index 0000000..dd8251f
--- /dev/null
+++ b/tests/language/const/counter_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Bug: 4254106 Constant constructors must have (implicit) const parameters.
+
+class ConstCounter {
+  const ConstCounter(int i)
+      : nextValue_ = (
+            // Incorrect assignment of a non-const function to a final field.
+
+                i + 1);
+
+  final nextValue_;
+}
+
+main() {
+  const ConstCounter(3);
+}
diff --git a/tests/language/const/counter_test.dart b/tests/language/const/counter_test.dart
new file mode 100644
index 0000000..0ca474f
--- /dev/null
+++ b/tests/language/const/counter_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Bug: 4254106 Constant constructors must have (implicit) const parameters.
+
+class ConstCounter {
+  const ConstCounter(int i)
+      : nextValue_ = (
+      //             ^
+      // [cfe] Can't find ')' to match '('.
+
+            // Incorrect assignment of a non-const function to a final field.
+            () => i + 1;
+//          ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
+// [cfe] Not a constant expression.
+//                     ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  final nextValue_;
+}
+
+main() {
+  const ConstCounter(3);
+//^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+}
diff --git a/tests/language/const/ct_const_test.dart b/tests/language/const/ct_const_test.dart
new file mode 100644
index 0000000..defab06
--- /dev/null
+++ b/tests/language/const/ct_const_test.dart
@@ -0,0 +1,134 @@
+// 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.
+
+// Test of apparent compile-time nature of constant evaluation. Constant Lists,
+// Maps and other objects should be identical independent of formation.
+
+import "package:expect/expect.dart";
+
+abstract class Roman {
+  static const I = 1;
+  static const II = 2;
+  static const III = 3;
+  static const IV = 4;
+  static const V = 5;
+
+  static const VivaItalia = const {"green": 1, "red": 3, "white": 2};
+}
+
+class Point {
+  static const int zero = 0;
+
+  static const origin = const Point(0, 0);
+  static const origin2 = const Point(zero, Roman.IV - 4);
+
+  const Point(x, y)
+      : x_ = x,
+        y_ = y;
+  const Point.X(x)
+      : x_ = x,
+        y_ = Roman.V - Roman.II - 3;
+
+  bool operator ==(final dynamic other) {
+    return (this.x_ == other.x_) && (this.y_ == other.y_);
+  }
+
+  final int x_, y_;
+}
+
+class Line {
+  const Line(Point begin, Point end)
+      : beg_ = begin,
+        end_ = end;
+  final Point beg_;
+  final Point end_;
+}
+
+class CTConstTest {
+  static int getZero() {
+    return 0;
+  }
+
+  static const naught = null;
+
+  static testMain() {
+    Expect.equals(0, Point.zero);
+    Expect.equals(0, Point.origin.x_);
+    Expect.equals(true, identical(Point.origin, Point.origin2));
+    var p1 = const Point(0, 0);
+    Expect.equals(true, identical(Point.origin, p1));
+
+    Expect.equals(false, Point.origin == const Point(1, 1));
+    Expect.equals(false, identical(Point.origin, const Point(1, 1)));
+
+    var p2 = new Point(0, getZero());
+    Expect.equals(true, Point.origin == p2); // Point.operator==
+
+    Expect.equals(true, identical(const Point.X(5), const Point(5, 0)));
+    Line l1 = const Line(Point.origin, const Point(1, 1));
+    Line l2 = const Line(const Point(0, 0), const Point(1, 1));
+    Line l3 = new Line(const Point(0, 0), const Point(1, 1));
+    Expect.equals(true, identical(l1, l2));
+
+    final evenNumbers = const <int>[2, 2 * 2, 2 * 3, 2 * 4, 2 * 5];
+    Expect.equals(true, identical(evenNumbers, const <int>[2, 4, 6, 8, 10]));
+    Expect.equals(
+        true, !identical(evenNumbers, const <dynamic>[2, 4, 6, 8, 10]));
+
+    final c11dGermany1 = const {"black": 1, "red": 2, "yellow": 3};
+    Expect.equals(true,
+        identical(c11dGermany1, const {"black": 1, "red": 2, "yellow": 3}));
+
+    final c11dGermany2 = const {"black": 1, "red": 2, "yellow": 3};
+    Expect.equals(true, identical(c11dGermany1, c11dGermany2));
+
+    final c11dBelgium = const {"black": 1, "yellow": 2, "red": 3};
+    Expect.equals(false, c11dGermany1 == c11dBelgium);
+    Expect.equals(false, identical(c11dGermany1, c11dBelgium));
+
+    final c11dItaly = const {"green": 1, "red": 3, "white": 2};
+    Expect.equals(
+        true, identical(c11dItaly, const {"green": 1, "red": 3, "white": 2}));
+    Expect.equals(true, identical(c11dItaly, Roman.VivaItalia));
+
+    Expect.equals(3, c11dItaly.length);
+    Expect.equals(3, c11dItaly.keys.length);
+    Expect.equals(true, c11dItaly.containsKey("white"));
+    Expect.equals(false, c11dItaly.containsKey("black"));
+
+    // Make sure the map object is immutable.
+    bool caughtException = false;
+    try {
+      c11dItaly["green"] = 0;
+    } on UnsupportedError catch (e) {
+      caughtException = true;
+    }
+    Expect.equals(true, caughtException);
+    Expect.equals(1, c11dItaly["green"]);
+
+    caughtException = false;
+    try {
+      c11dItaly.clear();
+    } on UnsupportedError catch (e) {
+      caughtException = true;
+    }
+    Expect.equals(true, caughtException);
+    Expect.equals(1, c11dItaly["green"]);
+
+    caughtException = false;
+    try {
+      c11dItaly.remove("orange");
+    } on UnsupportedError catch (e) {
+      caughtException = true;
+    }
+    Expect.equals(true, caughtException);
+    Expect.equals(1, c11dItaly["green"]);
+
+    Expect.equals(true, null == naught);
+  }
+}
+
+main() {
+  CTConstTest.testMain();
+}
diff --git a/tests/language/const/double_in_int_op_test.dart b/tests/language/const/double_in_int_op_test.dart
new file mode 100644
index 0000000..ed12305
--- /dev/null
+++ b/tests/language/const/double_in_int_op_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=triple-shift
+
+main() {
+  const dynamic i1 = 3;
+  const dynamic i2 = 2;
+  const dynamic d1 = 3.3;
+  const dynamic d2 = 2.2;
+
+  const sum = 0 + //
+      (i1 | i2) + //# ii1: ok
+      (i1 & i2) + //# ii2: ok
+      (i1 ^ i2) + //# ii3: ok
+      (i1 << i2) + //# ii4: ok
+      (i1 >> i2) + //# ii5: ok
+      (i1 >>> i2) + //# ii6: ok
+      (i1 | d2) + //# id1: compile-time error
+      (i1 & d2) + //# id2: compile-time error
+      (i1 ^ d2) + //# id3: compile-time error
+      (i1 << d2) + //# id4: compile-time error
+      (i1 >> d2) + //# id5: compile-time error
+      (i1 >>> d2) + //# id6: compile-time error
+      (d1 | i2) + //# di1: compile-time error
+      (d1 & i2) + //# di2: compile-time error
+      (d1 ^ i2) + //# di3: compile-time error
+      (d1 << i2) + //# di4: compile-time error
+      (d1 >> i2) + //# di5: compile-time error
+      (d1 >>> i2) + //# di6: compile-time error
+      (d1 | d2) + //# dd1: compile-time error
+      (d1 & d2) + //# dd2: compile-time error
+      (d1 ^ d2) + //# dd3: compile-time error
+      (d1 << d2) + //# dd4: compile-time error
+      (d1 >> d2) + //# dd5: compile-time error
+      (d1 >>> d2) + //# dd6: compile-time error
+      0;
+  print(sum);
+}
diff --git a/tests/language/const/dynamic_type_literal_runtime_1_test.dart b/tests/language/const/dynamic_type_literal_runtime_1_test.dart
new file mode 100644
index 0000000..8f56bb6
--- /dev/null
+++ b/tests/language/const/dynamic_type_literal_runtime_1_test.dart
@@ -0,0 +1,21 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test that 'dynamic' can be used in const expressions and has the expected
+// behavior.
+
+import "package:expect/expect.dart";
+
+const d = dynamic;
+const i = int;
+
+void main() {
+  Expect.isTrue(identical(d, dynamic));
+  // Duplicate key error.
+
+
+}
diff --git a/tests/language/const/dynamic_type_literal_runtime_2_test.dart b/tests/language/const/dynamic_type_literal_runtime_2_test.dart
new file mode 100644
index 0000000..478a9ed
--- /dev/null
+++ b/tests/language/const/dynamic_type_literal_runtime_2_test.dart
@@ -0,0 +1,21 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test that 'dynamic' can be used in const expressions and has the expected
+// behavior.
+
+import "package:expect/expect.dart";
+
+const d = dynamic;
+const i = int;
+
+void main() {
+
+  // Duplicate key error.
+
+  Expect.equals(2, const { d: 1, i: 2 }.length);
+}
diff --git a/tests/language/const/dynamic_type_literal_runtime_test.dart b/tests/language/const/dynamic_type_literal_runtime_test.dart
new file mode 100644
index 0000000..05cb59a
--- /dev/null
+++ b/tests/language/const/dynamic_type_literal_runtime_test.dart
@@ -0,0 +1,21 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test that 'dynamic' can be used in const expressions and has the expected
+// behavior.
+
+import "package:expect/expect.dart";
+
+const d = dynamic;
+const i = int;
+
+void main() {
+
+  // Duplicate key error.
+
+
+}
diff --git a/tests/language/const/dynamic_type_literal_test.dart b/tests/language/const/dynamic_type_literal_test.dart
new file mode 100644
index 0000000..e69bb8f
--- /dev/null
+++ b/tests/language/const/dynamic_type_literal_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// Test that 'dynamic' can be used in const expressions and has the expected
+// behavior.
+
+import "package:expect/expect.dart";
+
+const d = dynamic;
+const i = int;
+
+void main() {
+  Expect.isTrue(identical(d, dynamic));
+  // Duplicate key error.
+  Expect.equals(1, const { d: 1, d: 2 }.length);
+  //               ^
+  // [cfe] Constant evaluation error:
+  //                             ^
+  // [analyzer] COMPILE_TIME_ERROR.EQUAL_KEYS_IN_CONST_MAP
+  Expect.equals(2, const { d: 1, i: 2 }.length);
+}
diff --git a/tests/language/const/error_multiply_initialized_test.dart b/tests/language/const/error_multiply_initialized_test.dart
new file mode 100644
index 0000000..490ea0f
--- /dev/null
+++ b/tests/language/const/error_multiply_initialized_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// If a constant constructor contains an initializer, or an initializing
+// formal, for a final field which itself has an initializer at its
+// declaration, then a compile-time error should be reported regardless of
+// whether the constructor is called with "const" or "new".
+
+import "package:expect/expect.dart";
+
+class C {
+  final x = 1;
+  const C() : x = 2; //# 01: compile-time error
+  const C() : x = 2; //# 02: compile-time error
+  const C(this.x); //# 03: compile-time error
+  const C(this.x); //# 04: compile-time error
+}
+
+main() {
+  const C(); //# 01: continued
+  new C(); //# 02: continued
+  const C(2); //# 03: continued
+  new C(2); //# 04: continued
+}
diff --git a/tests/language/const/escape_frog_test.dart b/tests/language/const/escape_frog_test.dart
new file mode 100644
index 0000000..0380058
--- /dev/null
+++ b/tests/language/const/escape_frog_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test division by power of two.
+// Test that results before and after optimization are the same.
+
+import "package:expect/expect.dart";
+
+class Foo {
+  final Bar<Foo> bar = const Bar /* comment here use to trigger bug 323 */ ();
+}
+
+class Bar<T extends Foo> {
+  const Bar();
+}
+
+main() {
+  Expect.equals(new Foo().bar, const Bar());
+}
diff --git a/tests/language/const/evaluation_test.dart b/tests/language/const/evaluation_test.dart
new file mode 100644
index 0000000..cd0353e
--- /dev/null
+++ b/tests/language/const/evaluation_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that compile-time evaluation of constants is consistent with runtime
+// evaluation.
+
+import 'package:expect/expect.dart';
+
+const top_const = identical(-0.0, 0);
+final top_final = identical(-0.0, 0);
+var top_var = identical(-0.0, 0);
+
+@top_const
+class C {
+  static const static_const = identical(-0.0, 0);
+  static final static_final = identical(-0.0, 0);
+  static var static_var = identical(-0.0, 0);
+
+  final instance_final = identical(-0.0, 0);
+  var instance_var = identical(-0.0, 0);
+
+  void test() {
+    const local_const = identical(-0.0, 0);
+    final local_final = identical(-0.0, 0);
+    var local_var = identical(-0.0, 0);
+
+    Expect.equals(identical(-0.0, 0), top_const);
+    Expect.equals(top_const, top_final);
+    Expect.equals(top_final, top_var);
+    Expect.equals(top_var, static_const);
+    Expect.equals(static_const, static_final);
+    Expect.equals(static_final, static_var);
+    Expect.equals(static_var, instance_final);
+    Expect.equals(instance_final, instance_var);
+    Expect.equals(instance_var, local_const);
+    Expect.equals(local_const, local_final);
+    Expect.equals(local_final, local_var);
+  }
+}
+
+void main() {
+  new C().test();
+}
diff --git a/tests/language/const/factory_redirection_test.dart b/tests/language/const/factory_redirection_test.dart
new file mode 100644
index 0000000..e1cc36d
--- /dev/null
+++ b/tests/language/const/factory_redirection_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that factory redirections work for compile-time constants, and
+// that abstract classes can redirect.
+
+abstract class C {
+  const factory C(int x) = D;
+}
+
+class D implements C {
+  final int i;
+  const D(this.i);
+  m() => 'called m';
+}
+
+main() {
+  const C c = const C(42);
+  D d = c as D;
+  Expect.equals(42, d.i);
+  Expect.equals('called m', d.m());
+  d = new C(42) as D;
+  Expect.equals(42, d.i);
+  Expect.equals('called m', d.m());
+}
diff --git a/tests/language/const/factory_with_body_runtime_test.dart b/tests/language/const/factory_with_body_runtime_test.dart
new file mode 100644
index 0000000..559defc
--- /dev/null
+++ b/tests/language/const/factory_with_body_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Tests that a "const factory" with body produces a compile-time error.
+
+class ConstFactoryWithBody {
+
+}
+
+main() {
+
+}
diff --git a/tests/language/const/factory_with_body_test.dart b/tests/language/const/factory_with_body_test.dart
new file mode 100644
index 0000000..a9577bb
--- /dev/null
+++ b/tests/language/const/factory_with_body_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Tests that a "const factory" with body produces a compile-time error.
+
+class ConstFactoryWithBody {
+  const ConstFactoryWithBody();
+
+  const factory ConstFactoryWithBody.one() { return ConstFactoryWithBody(); }
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.CONST_FACTORY
+// [cfe] Only redirecting factory constructors can be declared to be 'const'.
+}
+
+main() {
+  const ConstFactoryWithBody.one();
+}
diff --git a/tests/language/const/for_in_variable_test.dart b/tests/language/const/for_in_variable_test.dart
new file mode 100644
index 0000000..2eb63b7
--- /dev/null
+++ b/tests/language/const/for_in_variable_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+main() {
+  for (
+      const //# 01: compile-time error
+      final //# 02: ok
+      int x in const [1, 2, 3]) {
+    break;
+  }
+}
diff --git a/tests/language/const/getter_runtime_test.dart b/tests/language/const/getter_runtime_test.dart
new file mode 100644
index 0000000..4d32485
--- /dev/null
+++ b/tests/language/const/getter_runtime_test.dart
@@ -0,0 +1,25 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Check that const getters are not allowed.
+
+import 'package:expect/expect.dart';
+
+class C {
+  const C();
+
+
+  get x => 1;
+}
+
+
+get y => 2;
+
+main() {
+  const C().x;
+  y;
+}
diff --git a/tests/language/const/getter_test.dart b/tests/language/const/getter_test.dart
new file mode 100644
index 0000000..c843529
--- /dev/null
+++ b/tests/language/const/getter_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Check that const getters are not allowed.
+
+import 'package:expect/expect.dart';
+
+class C {
+  const C();
+
+  const
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.EXTRANEOUS_MODIFIER
+// [cfe] Can't have modifier 'const' here.
+  get x => 1;
+}
+
+const
+// [error line 19, column 1, length 5]
+// [analyzer] SYNTACTIC_ERROR.EXTRANEOUS_MODIFIER
+// [cfe] Can't have modifier 'const' here.
+get y => 2;
+
+main() {
+  const C().x;
+  y;
+}
diff --git a/tests/language/const/global_test.dart b/tests/language/const/global_test.dart
new file mode 100644
index 0000000..99143d4
--- /dev/null
+++ b/tests/language/const/global_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+const a = 1;
+
+main() {
+  Expect.equals(1, a);
+  Expect.equals(1, const A(a).a);
+  Expect.equals(1, const [const A(a)][0].a);
+}
+
+class A {
+  final a;
+  const A(this.a);
+}
diff --git a/tests/language/const/inference_test.dart b/tests/language/const/inference_test.dart
new file mode 100644
index 0000000..77b20ec
--- /dev/null
+++ b/tests/language/const/inference_test.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+R constFunction<T, R>(T _) => throw "uncalled";
+
+C<T> getC<T>() => const C(constFunction);
+
+List<T> getList<T>() => const [];
+
+Set<T> getSet<T>() => const {};
+
+Map<K, V> getMap<K, V>() => const {};
+
+R Function(T) getFunction<T, R>() {
+  List<R Function(T)> list = const [constFunction];
+  return list[0];
+}
+
+C<T> getImplicitConstC<T>() {
+  List<C<T>> list = const [C(constFunction)];
+  return list[0];
+}
+
+List<T> getImplicitConstList<T>() {
+  List<List<T>> list = const [[]];
+  return list[0];
+}
+
+Set<T> getImplicitConstSet<T>() {
+  List<Set<T>> list = const [{}];
+  return list[0];
+}
+
+Map<K, V> getImplicitConstMap<K, V>() {
+  List<Map<K, V>> list = const [{}];
+  return list[0];
+}
+
+class C<T> {
+  final Object fn;
+  const C(T Function(T) this.fn);
+}
+
+void expectOfType<T>(Object obj) {
+  // An exact type test would be better, but since `Never` is a subtype of all
+  // types that can be written in Dart, it should not matter in practice.
+  //
+  // (`obj.runtimeType == T` does not work for List/Map/Sets because the runtime
+  // type is an implementation-specific subtype of those interfaces.)
+  Expect.isTrue(obj is T, "`$obj` should be of type `$T`");
+}
+
+testClassInstance() {
+  expectOfType<C<Never>>(getC<int>());
+  expectOfType<C<Never>>(getC<String>());
+  expectOfType<C<Never>>(getC());
+}
+
+testImplicitConstClassInstance() {
+  expectOfType<C<Never>>(getImplicitConstC<int>());
+  expectOfType<C<Never>>(getImplicitConstC<String>());
+  expectOfType<C<Never>>(getImplicitConstC());
+}
+
+testDownwardsClassInference() {
+  expectOfType<Never Function(Never)>(getC<int>().fn);
+  expectOfType<Never Function(Never)>(getC<String>().fn);
+  expectOfType<Never Function(Never)>(getC().fn);
+}
+
+testList() {
+  expectOfType<List<Never>>(getList<int>());
+  expectOfType<List<Never>>(getList<String>());
+  expectOfType<List<Never>>(getList());
+}
+
+testImplicitConstList() {
+  expectOfType<List<Never>>(getImplicitConstList<int>());
+  expectOfType<List<Never>>(getImplicitConstList<String>());
+  expectOfType<List<Never>>(getImplicitConstList());
+}
+
+testImplicitConstSet() {
+  expectOfType<Set<Never>>(getImplicitConstSet<int>());
+  expectOfType<Set<Never>>(getImplicitConstSet<String>());
+  expectOfType<Set<Never>>(getImplicitConstSet());
+}
+
+testSet() {
+  expectOfType<Set<Never>>(getSet<int>());
+  expectOfType<Set<Never>>(getSet<String>());
+  expectOfType<Set<Never>>(getSet());
+}
+
+testMap() {
+  expectOfType<Map<Never, Never>>(getMap<int, int>());
+  expectOfType<Map<Never, Never>>(getMap<int, String>());
+  expectOfType<Map<Never, Never>>(getMap<String, int>());
+  expectOfType<Map<Never, Never>>(getMap<String, String>());
+  expectOfType<Map<Never, Never>>(getMap<Never, Never>());
+  expectOfType<Map<Never, Never>>(getMap());
+}
+
+testImplicitConstMap() {
+  expectOfType<Map<Never, Never>>(getImplicitConstMap<int, int>());
+  expectOfType<Map<Never, Never>>(getImplicitConstMap<int, String>());
+  expectOfType<Map<Never, Never>>(getImplicitConstMap<String, int>());
+  expectOfType<Map<Never, Never>>(getImplicitConstMap<String, String>());
+  expectOfType<Map<Never, Never>>(getImplicitConstMap<Never, Never>());
+  expectOfType<Map<Never, Never>>(getImplicitConstMap());
+}
+
+testFunction() {
+  expectOfType<Never Function(Object?)>(getFunction<int, int>());
+  expectOfType<Never Function(Object?)>(getFunction<int, String>());
+  expectOfType<Never Function(Object?)>(getFunction<String, int>());
+  expectOfType<Never Function(Object?)>(getFunction<String, String>());
+  expectOfType<Never Function(Object?)>(getFunction<Never, Never>());
+  expectOfType<Never Function(Object?)>(getFunction());
+}
+
+/// Tests that use type inference for constants do not reference the type
+/// parameter. Instead, free type parameters are substituted to obtain the
+/// least closure (e.g. `List<T>` becomes `List<Never>` and `R Function(T)`
+/// becomes `Never Function(Object)`).
+main() {
+  testClassInstance();
+  testImplicitConstClassInstance();
+  testDownwardsClassInference();
+  testList();
+  testImplicitConstList();
+  testSet();
+  testImplicitConstSet();
+  testMap();
+  testImplicitConstMap();
+  testFunction();
+}
diff --git a/tests/language/const/init2_runtime_1_test.dart b/tests/language/const/init2_runtime_1_test.dart
new file mode 100644
index 0000000..7338f45
--- /dev/null
+++ b/tests/language/const/init2_runtime_1_test.dart
@@ -0,0 +1,15 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const intValue = 0;
+const double c = 0.0;
+
+
+main() {
+  print(c);
+
+}
diff --git a/tests/language/const/init2_runtime_test.dart b/tests/language/const/init2_runtime_test.dart
new file mode 100644
index 0000000..5970f29
--- /dev/null
+++ b/tests/language/const/init2_runtime_test.dart
@@ -0,0 +1,15 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const intValue = 0;
+
+
+
+main() {
+
+
+}
diff --git a/tests/language/const/init2_test.dart b/tests/language/const/init2_test.dart
new file mode 100644
index 0000000..7f5e1a3
--- /dev/null
+++ b/tests/language/const/init2_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const intValue = 0;
+const double c = 0.0;
+const double d = intValue;
+//               ^^^^^^^^
+// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+// [cfe] A value of type 'int' can't be assigned to a variable of type 'double'.
+//               ^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+
+main() {
+  print(c);
+  print(d);
+}
diff --git a/tests/language/const/init_test.dart b/tests/language/const/init_test.dart
new file mode 100644
index 0000000..714f9e1
--- /dev/null
+++ b/tests/language/const/init_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that initializers of static const fields are compile time constants.
+
+import "package:expect/expect.dart";
+
+class Point {
+  final x_;
+  final y_;
+  const Point(x, y)
+      : x_ = x,
+        y_ = y;
+}
+
+class ConstInitTest {
+  static const N = 1;
+  static const O = 1 + 3;
+  static const P = 2 * (O - N);
+  static const Q = const Point(0, 0);
+
+  static const Q2 = const Point(0, 0);
+  static const P2 = 2 * (O - N);
+  static const O2 = 1 + 3;
+  static const N2 = 1;
+
+  static testMain() {
+    Expect.equals(1, N);
+    Expect.equals(4, O);
+    Expect.equals(6, P);
+    Expect.equals(0, Q.x_);
+    Expect.equals(0, Q.y_);
+  }
+}
+
+main() {
+  ConstInitTest.testMain();
+}
diff --git a/tests/language/const/instance_field_runtime_test.dart b/tests/language/const/instance_field_runtime_test.dart
new file mode 100644
index 0000000..697b231
--- /dev/null
+++ b/tests/language/const/instance_field_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that const instance fields are compile-time errors.
+
+class C {
+
+}
+
+void main() {
+  new C();
+}
diff --git a/tests/language/const/instance_field_test.dart b/tests/language/const/instance_field_test.dart
new file mode 100644
index 0000000..f80551a
--- /dev/null
+++ b/tests/language/const/instance_field_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that const instance fields are compile-time errors.
+
+class C {
+  const field = 0;
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INSTANCE_FIELD
+// [cfe] Only static fields can be declared as const.
+}
+
+void main() {
+  new C();
+}
diff --git a/tests/language/const/list_test.dart b/tests/language/const/list_test.dart
new file mode 100644
index 0000000..b34be30
--- /dev/null
+++ b/tests/language/const/list_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class ConstListTest {
+  static testConstructors() {
+    List fixedList = List.filled(4, -1, growable: false);
+    List fixedList2 = List.filled(4, -1, growable: false);
+    List growableList = List.filled(0, -1, growable: true);
+    List growableList2 = List.filled(0, -1, growable: true);
+    for (int i = 0; i < 4; i++) {
+      fixedList[i] = i;
+      fixedList2[i] = i;
+      growableList.add(i);
+      growableList2.add(i);
+    }
+    Expect.equals(growableList, growableList);
+    Expect.notEquals(growableList, growableList2);
+    Expect.equals(fixedList, fixedList);
+    Expect.notEquals(fixedList, fixedList2);
+    Expect.notEquals(fixedList, growableList);
+    growableList.add(4);
+    Expect.notEquals(fixedList, growableList);
+    Expect.equals(4, growableList.removeLast());
+    Expect.notEquals(fixedList, growableList);
+    fixedList[3] = 0;
+    Expect.notEquals(fixedList, growableList);
+  }
+
+  static testLiterals() {
+    dynamic a = [1, 2, 3.1];
+    dynamic b = [1, 2, 3.1];
+    Expect.notEquals(a, b);
+    a = const [1, 2, 3.1];
+    b = const [1, 2, 3.1];
+    Expect.identical(a, b);
+    a = const <num>[1, 2, 3.1];
+    b = const [1, 2, 3.1];
+    Expect.identical(a, b);
+    a = const <dynamic>[1, 2, 3.1];
+    b = const [1, 2, 3.1];
+    Expect.notEquals(a, b);
+  }
+}
+
+main() {
+  ConstListTest.testConstructors();
+  ConstListTest.testLiterals();
+}
diff --git a/tests/language/const/local_test.dart b/tests/language/const/local_test.dart
new file mode 100644
index 0000000..f5288ed
--- /dev/null
+++ b/tests/language/const/local_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  const a = 1;
+  Expect.equals(1, a);
+  Expect.equals(1, const A(a).a);
+  Expect.equals(1, const [const A(a)][0].a);
+}
+
+class A {
+  final a;
+  const A(this.a);
+}
diff --git a/tests/language/const/locals_test.dart b/tests/language/const/locals_test.dart
new file mode 100644
index 0000000..00fc637
--- /dev/null
+++ b/tests/language/const/locals_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test of compile time constant local variables.
+
+const N = 8;
+
+class ConstFoo {
+  final x;
+  const ConstFoo(this.x);
+}
+
+main() {
+  const MIN = 2 - 1;
+  const MAX = N * 2;
+  const MASK = (1 << (MAX - MIN + 1)) - 1; // 65535.
+  Expect.equals(1, MIN);
+  Expect.equals(16, MAX);
+  Expect.equals(65535, MASK);
+  const s = 'MIN = $MIN  MAX = $MAX  MASK = $MASK';
+  Expect.identical(s, 'MIN = $MIN  MAX = $MAX  MASK = $MASK');
+  Expect.equals("MIN = 1  MAX = 16  MASK = 65535", s);
+  var cf1 = const ConstFoo(MASK);
+  var cf2 = const ConstFoo(s);
+  var cf3 = const ConstFoo('MIN = $MIN  MAX = $MAX  MASK = $MASK');
+  Expect.identical(cf2, cf3);
+  Expect.isFalse(identical(cf2, cf1));
+}
diff --git a/tests/language/const/map2_runtime_test.dart b/tests/language/const/map2_runtime_test.dart
new file mode 100644
index 0000000..9e1fe97
--- /dev/null
+++ b/tests/language/const/map2_runtime_test.dart
@@ -0,0 +1,32 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  const factory A() = B;
+}
+
+class B implements A {
+  const B();
+
+
+}
+
+confuse(x) {
+  if (new DateTime.now() == 42) return confuse(2);
+  return x;
+}
+
+main() {
+  // It is a compile-time error if the key type overrides operator ==.
+  dynamic m = const {const A(): 42};
+  Expect.equals(42, m[confuse(const B())]);
+
+  m = const {"foo": 99, const A(): 499};
+  Expect.equals(499, m[confuse(const B())]);
+}
diff --git a/tests/language/const/map2_test.dart b/tests/language/const/map2_test.dart
new file mode 100644
index 0000000..a5f3798
--- /dev/null
+++ b/tests/language/const/map2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  const factory A() = B;
+}
+
+class B implements A {
+  const B();
+
+  operator ==(o) => true;
+}
+
+confuse(x) {
+  if (new DateTime.now() == 42) return confuse(2);
+  return x;
+}
+
+main() {
+  // It is a compile-time error if the key type overrides operator ==.
+  dynamic m = const {const A(): 42};
+  //          ^
+  // [cfe] Constant evaluation error:
+  //                 ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+  Expect.equals(42, m[confuse(const B())]);
+
+  m = const {"foo": 99, const A(): 499};
+  //  ^
+  // [cfe] Constant evaluation error:
+  //                    ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+  Expect.equals(499, m[confuse(const B())]);
+}
diff --git a/tests/language/const/map3_runtime_test.dart b/tests/language/const/map3_runtime_test.dart
new file mode 100644
index 0000000..4416774
--- /dev/null
+++ b/tests/language/const/map3_runtime_test.dart
@@ -0,0 +1,27 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  static const b = const B();
+}
+
+class B implements A {
+  const B();
+
+
+}
+
+main() {
+  // It is a compile-time error if the key type overrides operator ==.
+  dynamic m = const {A.b: 42};
+  Expect.equals(42, m[const B()]);
+
+  m = const {"foo": 99, A.b: 499};
+  Expect.equals(499, m[const B()]);
+}
diff --git a/tests/language/const/map3_test.dart b/tests/language/const/map3_test.dart
new file mode 100644
index 0000000..b7ee989
--- /dev/null
+++ b/tests/language/const/map3_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  static const b = const B();
+}
+
+class B implements A {
+  const B();
+
+  operator ==(o) => true;
+}
+
+main() {
+  // It is a compile-time error if the key type overrides operator ==.
+  dynamic m = const {A.b: 42};
+  //          ^
+  // [cfe] Constant evaluation error:
+  //                 ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+  Expect.equals(42, m[const B()]);
+
+  m = const {"foo": 99, A.b: 499};
+  //  ^
+  // [cfe] Constant evaluation error:
+  //                    ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+  Expect.equals(499, m[const B()]);
+}
diff --git a/tests/language/const/map4_test.dart b/tests/language/const/map4_test.dart
new file mode 100644
index 0000000..397672c
--- /dev/null
+++ b/tests/language/const/map4_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  dynamic a = {1: 'a', 2: 'b', 3: 'c'};
+  dynamic b = {1: 'a', 2: 'b', 3: 'c'};
+  Expect.equals(false, a == b);
+
+  a = const {1: 'a', 2: 'b', 3: 'c'};
+  b = const {1: 'a', 2: 'b', 3: 'c'};
+  Expect.equals(true, a == b);
+
+  a = const <int, String>{1: 'a', 2: 'b', 3: 'c'};
+  b = const {1: 'a', 2: 'b', 3: 'c'};
+  Expect.equals(true, a == b);
+
+  a = const <num, String>{1: 'a', 2: 'b', 3: 'c'};
+  b = const {1: 'a', 2: 'b', 3: 'c'};
+  Expect.equals(false, a == b);
+
+  a = const <dynamic, dynamic>{1: 'a', 2: 'b', 3: 'c'};
+  b = const {1: 'a', 2: 'b', 3: 'c'};
+  Expect.equals(false, a == b);
+}
diff --git a/tests/language/const/map_test.dart b/tests/language/const/map_test.dart
new file mode 100644
index 0000000..19ced31
--- /dev/null
+++ b/tests/language/const/map_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+main() {
+  // TODO(terry): Should check:
+  //   - const map is immutable
+  //   - simple expressions are const e.g., 2 + 3, true && !false, etc.
+  //   - const with final and/or static with same const attributes
+  //     Additionally new class instances with a static const same identity
+  //   - const for all types (int, num, double, String, boolean, and objects)
+  //   - canonicalization - const created only once same identity e.g.,
+  //
+  //     getConstMap() => const [1, 2];
+  //     var a = getConstMap();
+  //     var b = getConstMap();
+  //     Expect.equals(a.hashCode, b.hashCode);
+
+  // Make sure that const maps use the == operator and not object identity. The
+  // specification does not explicitly require it, otherwise ints and Strings
+  // wouldn't make much sense as keys.
+  var m = const {1: 42, "foo": 499, 2: "bar"};
+  Expect.equals(42, m[getValueNonOptimized(1.0)]);
+  Expect.equals(
+      499, m[getValueNonOptimized(new String.fromCharCodes("foo".runes))]);
+  Expect.equals('bar', m[getValueNonOptimized(2)]);
+}
diff --git a/tests/language/const/named_test.dart b/tests/language/const/named_test.dart
new file mode 100644
index 0000000..94b5598
--- /dev/null
+++ b/tests/language/const/named_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that const constructors work with named arguments.
+
+import "package:expect/expect.dart";
+
+main() {
+  var d = const Duration(milliseconds: 499);
+  Expect.equals(499, d.inMilliseconds);
+}
diff --git a/tests/language/const/native_factory_test.dart b/tests/language/const/native_factory_test.dart
new file mode 100644
index 0000000..13d398f
--- /dev/null
+++ b/tests/language/const/native_factory_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Cake {
+  final name;
+  const Cake(this.name);
+  const factory Cake.BakeMeACake()
+      native "Cake_BakeMeACake"; /*@compile-error=unspecified*/
+}
+
+main() {
+  var c = const Cake("Sacher");
+}
diff --git a/tests/language/const/nested_test.dart b/tests/language/const/nested_test.dart
new file mode 100644
index 0000000..bf52d67
--- /dev/null
+++ b/tests/language/const/nested_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test of compile time constant local variables in outer function levels.
+
+const N = 8;
+
+class ConstFoo {
+  final x;
+  const ConstFoo(this.x);
+}
+
+getClosure() {
+  const MIN = 2 - 1;
+  const MAX = N * 2;
+  const MASK = (1 << (MAX - MIN + 1)) - 1; // 65535.
+
+  void foo() {
+    Expect.equals(1, MIN);
+    Expect.equals(16, MAX);
+    Expect.equals(65535, MASK);
+    // Refer to compile time constant local variables in outer scope.
+    const s = 'MIN = $MIN  MAX = $MAX  MASK = $MASK';
+    Expect.isTrue(identical(s, 'MIN = $MIN  MAX = $MAX  MASK = $MASK'));
+    Expect.equals("MIN = 1  MAX = 16  MASK = 65535", s);
+    var cf1 = const ConstFoo(MASK);
+    var cf2 = const ConstFoo(s);
+    var cf3 = const ConstFoo('MIN = $MIN  MAX = $MAX  MASK = $MASK');
+    Expect.isTrue(identical(cf2, cf3));
+    Expect.isFalse(identical(cf2, cf1));
+  }
+
+  return foo;
+}
+
+main() {
+  var f = getClosure();
+  f();
+}
diff --git a/tests/language/const/objects_are_immutable_test.dart b/tests/language/const/objects_are_immutable_test.dart
new file mode 100644
index 0000000..7633716
--- /dev/null
+++ b/tests/language/const/objects_are_immutable_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that const objects (including literals) are immutable.
+
+import "package:expect/expect.dart";
+
+class A {
+  const A(this.x, this.y);
+  final num x, y;
+}
+
+main() {
+  dynamic list = const [1, 2];
+  Expect.throws(() => list[0] = 3);
+  Expect.equals(1, list[0]);
+
+  dynamic m = const {'foo': 499};
+  Expect.throws(() => m['foo'] = 42);
+  Expect.equals(499, m['foo']);
+
+  dynamic a1 = const A(1, 2);
+  Expect.throws(() => a1.x = 499);
+  Expect.equals(1, a1.x);
+
+  dynamic a2 = const A(1, 2);
+  Expect.throws(() => a2.x = 499);
+  Expect.equals(1, a2.x);
+}
diff --git a/tests/language/const/optional_args_runtime_test.dart b/tests/language/const/optional_args_runtime_test.dart
new file mode 100644
index 0000000..46d23f9
--- /dev/null
+++ b/tests/language/const/optional_args_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Check that const objects (including literals) are immutable.
+
+// Must be 'const {}' to be valid.
+invalid(
+    [var p =
+
+    const
+
+    {}]) {}
+
+main() {
+  invalid();
+}
diff --git a/tests/language/const/optional_args_test.dart b/tests/language/const/optional_args_test.dart
new file mode 100644
index 0000000..3d7c779
--- /dev/null
+++ b/tests/language/const/optional_args_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Check that const objects (including literals) are immutable.
+
+// Must be 'const {}' to be valid.
+invalid(
+    [var p =
+    /*
+    const
+    */
+    {}]) {}
+//  ^^
+// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE
+// [cfe] Constant expression expected.
+
+main() {
+  invalid();
+}
diff --git a/tests/language/const/qq_test.dart b/tests/language/const/qq_test.dart
new file mode 100644
index 0000000..9b27099
--- /dev/null
+++ b/tests/language/const/qq_test.dart
@@ -0,0 +1,140 @@
+// 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.
+
+// Check that ?? is compile-time constant.
+
+import "package:expect/expect.dart";
+
+// These are typed `Object?` to avoid warnings that the "??" are unnecessary
+// when the LHS is non-nullable.
+const Object? theNull = null;
+const Object? notNull = const Object();
+
+// Top-level const field initializer.
+const test1 = theNull ?? notNull;
+const test2 = notNull ?? theNull;
+const test3 = theNull ?? theNull ?? notNull;
+const test4 = theNull ?? theNull ?? theNull;
+
+class P {
+  final v;
+  const P(this.v);
+}
+
+// Annotation parameter (not checked by test!)
+@P(theNull ?? notNull)
+@P(notNull ?? theNull)
+@P(theNull ?? theNull ?? notNull)
+@P(theNull ?? theNull ?? theNull)
+class C {
+  // Static const field initializer.
+  static const test5 = theNull ?? notNull;
+  static const test6 = notNull ?? theNull;
+  static const test7 = theNull ?? theNull ?? notNull;
+  static const test8 = theNull ?? theNull ?? theNull;
+
+  // (Constructor) parameter defaults.
+  final test9;
+  final test10;
+  final test11;
+  final test12;
+
+  // Const constructor initializer list.
+  final test13;
+  final test14;
+  final test15;
+  final test16;
+  final test17;
+
+  const C(x,
+      [this.test9 = theNull ?? notNull,
+      this.test10 = notNull ?? theNull,
+      this.test11 = theNull ?? theNull ?? notNull,
+      this.test12 = theNull ?? theNull ?? theNull])
+      : test13 = theNull ?? x,
+        test14 = notNull ?? x,
+        test15 = x ?? notNull,
+        test16 = theNull ?? theNull ?? x,
+        test17 = theNull ?? x ?? notNull;
+
+  List methodLocal() {
+    // Method local const variable initializer.
+    const test18 = theNull ?? notNull;
+    const test19 = notNull ?? theNull;
+    const test20 = theNull ?? theNull ?? notNull;
+    const test21 = theNull ?? theNull ?? theNull;
+
+    return const [test18, test19, test20, test21];
+  }
+
+  List expressionLocal() {
+    // Constant expression sub-expression.
+    return const [
+      theNull ?? notNull,
+      notNull ?? theNull,
+      theNull ?? theNull ?? notNull,
+      theNull ?? theNull ?? theNull
+    ];
+  }
+}
+
+main() {
+  Expect.identical(notNull, test1, "test1");
+  Expect.identical(notNull, test2, "test2");
+  Expect.identical(notNull, test3, "test3");
+  Expect.identical(theNull, test4, "test4");
+
+  Expect.identical(notNull, C.test5, "test5");
+  Expect.identical(notNull, C.test6, "test6");
+  Expect.identical(notNull, C.test7, "test7");
+  Expect.identical(theNull, C.test8, "test8");
+
+  const c1 = const C(null);
+  Expect.identical(notNull, c1.test9, "test9");
+  Expect.identical(notNull, c1.test10, "test10");
+  Expect.identical(notNull, c1.test11, "test11");
+  Expect.identical(theNull, c1.test12, "test12");
+
+  Expect.identical(theNull, c1.test13, "test13");
+  Expect.identical(notNull, c1.test14, "test14");
+  Expect.identical(notNull, c1.test15, "test15");
+  Expect.identical(theNull, c1.test16, "test16");
+  Expect.identical(notNull, c1.test17, "test17");
+
+  var list = c1.methodLocal();
+  Expect.identical(notNull, list[0], "test18");
+  Expect.identical(notNull, list[1], "test19");
+  Expect.identical(notNull, list[2], "test20");
+  Expect.identical(theNull, list[3], "test21");
+
+  list = c1.expressionLocal();
+  Expect.identical(notNull, list[0], "test22");
+  Expect.identical(notNull, list[1], "test23");
+  Expect.identical(notNull, list[2], "test24");
+  Expect.identical(theNull, list[3], "test25");
+
+  const c2 = const C(42);
+  Expect.identical(notNull, c2.test9, "test26");
+  Expect.identical(notNull, c2.test10, "test27");
+  Expect.identical(notNull, c2.test11, "test28");
+  Expect.identical(theNull, c2.test12, "test29");
+
+  Expect.identical(42, c2.test13, "test30");
+  Expect.identical(notNull, c2.test14, "test31");
+  Expect.identical(42, c2.test15, "test32");
+  Expect.identical(42, c2.test16, "test33");
+  Expect.identical(42, c2.test17, "test34");
+
+  list = c2.methodLocal();
+  Expect.identical(notNull, list[0], "test35");
+  Expect.identical(notNull, list[1], "test36");
+  Expect.identical(notNull, list[2], "test37");
+  Expect.identical(theNull, list[3], "test38");
+
+  list = c2.expressionLocal();
+  Expect.identical(notNull, list[0], "test39");
+  Expect.identical(notNull, list[1], "test40");
+  Expect.identical(notNull, list[2], "test41");
+  Expect.identical(theNull, list[3], "test42");
+}
diff --git a/tests/language/const/redirect_skips_supertype_test.dart b/tests/language/const/redirect_skips_supertype_test.dart
new file mode 100644
index 0000000..f79ad5a
--- /dev/null
+++ b/tests/language/const/redirect_skips_supertype_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// Since C redirects to C.named, it doesn't implicitly refer to B's
+// unnamed constructor.  Therefore there is no cycle.
+
+class B {
+  final x;
+  const B() : x = y;
+  const B.named() : x = null;
+}
+
+class C extends B {
+  const C() : this.named();
+  const C.named() : super.named();
+}
+
+const y = const C();
+
+main() {
+  print(y);
+}
diff --git a/tests/language/const/redirecting_factory_test.dart b/tests/language/const/redirecting_factory_test.dart
new file mode 100644
index 0000000..c7f8bf2
--- /dev/null
+++ b/tests/language/const/redirecting_factory_test.dart
@@ -0,0 +1,58 @@
+// 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:expect/expect.dart';
+
+class K implements L {
+  final field1;
+  final field2;
+  const K({this.field1: 42, this.field2: true});
+}
+
+class L {
+  const factory L() = K;
+  const factory L.named1({field1, field2}) = K;
+  const factory L.named2({field2, field1}) = K;
+}
+
+const K l1 = const L() as K;
+
+const K l2a = const L.named1() as K;
+const K l2b = const L.named1(field1: 87) as K;
+const K l2c = const L.named1(field2: false) as K;
+const K l2d = const L.named1(field1: 87, field2: false) as K;
+const K l2e = const L.named1(field2: false, field1: 87) as K;
+
+const K l3a = const L.named2() as K;
+const K l3b = const L.named2(field1: 87) as K;
+const K l3c = const L.named2(field2: false) as K;
+const K l3d = const L.named2(field1: 87, field2: false) as K;
+const K l3e = const L.named2(field2: false, field1: 87) as K;
+
+main() {
+  Expect.equals(42, l1.field1);
+  Expect.equals(true, l1.field2);
+
+  Expect.equals(42, l2a.field1);
+  Expect.equals(true, l2a.field2);
+  Expect.equals(87, l2b.field1);
+  Expect.equals(true, l2b.field2);
+  Expect.equals(42, l2c.field1);
+  Expect.equals(false, l2c.field2);
+  Expect.equals(87, l2d.field1);
+  Expect.equals(false, l2d.field2);
+  Expect.equals(87, l2e.field1);
+  Expect.equals(false, l2e.field2);
+
+  Expect.equals(42, l3a.field1);
+  Expect.equals(true, l3a.field2);
+  Expect.equals(87, l3b.field1);
+  Expect.equals(true, l3b.field2);
+  Expect.equals(42, l3c.field1);
+  Expect.equals(false, l3c.field2);
+  Expect.equals(87, l3d.field1);
+  Expect.equals(false, l3d.field2);
+  Expect.equals(87, l3e.field1);
+  Expect.equals(false, l3e.field2);
+}
diff --git a/tests/language/const/string_test.dart b/tests/language/const/string_test.dart
new file mode 100644
index 0000000..13f1a9c
--- /dev/null
+++ b/tests/language/const/string_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Exercises compile-time string constants
+
+const yz = "y" + "z";
+
+main() {
+  // Constant comparisons are independent of the quotes used.
+  Expect.isTrue(identical("abcd", 'abcd'));
+  Expect.isTrue(identical('abcd', "abcd"));
+  Expect.isTrue(identical("ab\"cd", 'ab"cd'));
+  Expect.isTrue(identical('ab\'cd', "ab'cd"));
+
+  // String concatenation works even when quotes are different.
+  Expect.isTrue(identical("abcd", "ab" "cd"));
+  Expect.isTrue(identical("abcd", "ab" 'cd'));
+  Expect.isTrue(identical("abcd", 'ab' 'cd'));
+  Expect.isTrue(identical("abcd", 'ab' "cd"));
+
+  // Or when there are more than 2 contatenations.
+  Expect.isTrue(identical("abcd", "a" "b" "cd"));
+  Expect.isTrue(identical("abcd", "a" "b" "c" "d"));
+  Expect.isTrue(identical('abcd', 'a' 'b' 'c' 'd'));
+  Expect.isTrue(identical("abcd", "a" "b" 'c' "d"));
+  Expect.isTrue(identical("abcd", 'a' 'b' 'c' 'd'));
+  Expect.isTrue(identical("abcd", 'a' "b" 'c' "d"));
+
+  Expect.isTrue(identical("a'b'cd", "a" "'b'" 'c' "d"));
+  Expect.isTrue(identical("a\"b\"cd", "a" '"b"' 'c' "d"));
+  Expect.isTrue(identical("a\"b\"cd", "a" '"b"' 'c' "d"));
+  Expect.isTrue(identical("a'b'cd", 'a' "'b'" 'c' "d"));
+  Expect.isTrue(identical('a\'b\'cd', "a" "'b'" 'c' "d"));
+  Expect.isTrue(identical('a"b"cd', 'a' '"b"' 'c' "d"));
+  Expect.isTrue(identical("a\"b\"cd", 'a' '"b"' 'c' "d"));
+
+  const a = identical("ab", "a" + "b");
+  Expect.isTrue(a);
+
+  const b = identical("xyz", "x" + yz);
+  Expect.isTrue(b);
+
+  const c = identical("12", "1" "2");
+  Expect.isTrue(c);
+
+  const d = identical("zyz", "z$yz");
+  Expect.isTrue(d);
+}
diff --git a/tests/language/const/switch2_runtime_test.dart b/tests/language/const/switch2_runtime_test.dart
new file mode 100644
index 0000000..38657b1
--- /dev/null
+++ b/tests/language/const/switch2_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  var a = [1, 2, 3][2];
+  switch (a) {
+
+
+
+    case 1:
+      print("OK");
+  }
+}
diff --git a/tests/language/const/switch2_test.dart b/tests/language/const/switch2_test.dart
new file mode 100644
index 0000000..7d784f1
--- /dev/null
+++ b/tests/language/const/switch2_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  var a = [1, 2, 3][2];
+  switch (a) {
+    case 0.0:
+    //   ^^^
+    // [analyzer] COMPILE_TIME_ERROR.CASE_EXPRESSION_TYPE_IS_NOT_SWITCH_EXPRESSION_SUBTYPE
+    //   ^^^
+    // [analyzer] COMPILE_TIME_ERROR.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+    //   ^
+    // [cfe] Type 'double' of the case expression is not a subtype of type 'int' of this switch expression.
+    //   ^
+    // [cfe] Case expression '0.0' does not have a primitive operator '=='.
+      print("illegal");
+      break;
+    case 1:
+      print("OK");
+  }
+}
diff --git a/tests/language/const/switch_test.dart b/tests/language/const/switch_test.dart
new file mode 100644
index 0000000..c4048c7
--- /dev/null
+++ b/tests/language/const/switch_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class C {
+  final field;
+  const C(this.field);
+}
+
+const c1 = const C(0.0);
+const c2 = const C(0);
+const c3 = const C(0.5 + 0.5);
+const c4 = const C(1);
+
+main() {
+  Expect.equals('0.0', test(c1)); //# 01: ok
+  Expect.equals('0', test(c2)); //# 02: ok
+  Expect.equals('1.0', test(c3)); //# 03: ok
+  Expect.equals('1', test(c4)); //# 04: ok
+}
+
+String test(C c) {
+  switch (c) {
+    case const C(0.0):
+      return '0.0';
+    case const C(0):
+      return '0';
+    case const C(1.0):
+      return '1.0';
+    case const C(1):
+      return '1';
+  }
+  return '';
+}
diff --git a/tests/language/const/syntax_runtime_test.dart b/tests/language/const/syntax_runtime_test.dart
new file mode 100644
index 0000000..93d1f48
--- /dev/null
+++ b/tests/language/const/syntax_runtime_test.dart
@@ -0,0 +1,92 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  const f0 = 42;
+
+  const int f2 = 87;
+
+  Expect.equals(42, f0);
+  Expect.equals(87, f2);
+
+  Expect.equals(42, F0);
+
+  Expect.equals(87, F2);
+
+
+  Expect.isTrue(P0 is Point);
+
+
+
+
+  Expect.isTrue(A0 is int);
+  Expect.isTrue(A1 is int);
+
+
+
+  Expect.isTrue(C0.X is C1);
+
+
+  Expect.equals("Hello 42", B2);
+
+
+  const cf1 = identical(const Point(1, 2), const Point(1, 2));
+
+
+
+
+  var f5 = B5;
+}
+
+const F0 = 42;
+
+const int F2 = 87;
+
+
+class Point {
+  final x, y;
+  const Point(this.x, this.y);
+  operator +(int other) => x;
+}
+
+// Check that compile time expressions can include invocations of
+// user-defined const constructors.
+const P0 = const Point(0, 0);
+
+
+
+
+// Check that we cannot have cyclic references in compile time
+// expressions.
+const A0 = 42;
+const A1 = A0 + 1;
+
+
+
+class C0 {
+  static const X = const C1();
+}
+
+class C1 {
+  const C1()
+
+  ;
+  final x = null;
+}
+
+// Check that sub-expressions of binary + are numeric.
+const B0 = 42;
+const B1 = "Hello";
+const B2 = "$B1 $B0";
+
+
+// Check identical.
+
+
+const B5 = identical(1, const Point(1, 2));
diff --git a/tests/language/const/syntax_test.dart b/tests/language/const/syntax_test.dart
new file mode 100644
index 0000000..e9ccc4e
--- /dev/null
+++ b/tests/language/const/syntax_test.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  const f0 = 42;
+  const f1;
+  //    ^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED
+  //      ^
+  // [cfe] The const variable ';' must be initialized.
+  const int f2 = 87;
+  const int f3;
+  //        ^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED
+  //          ^
+  // [cfe] The const variable ';' must be initialized.
+  Expect.equals(42, f0);
+  Expect.equals(87, f2);
+
+  Expect.equals(42, F0);
+  Expect.equals(null, F1);
+  Expect.equals(87, F2);
+  Expect.equals(null, F3);
+
+  Expect.isTrue(P0 is Point);
+  Expect.isTrue(P1 is int);
+  Expect.isTrue(P2 is Point);
+  Expect.isTrue(P3 is int);
+
+  Expect.isTrue(A0 is int);
+  Expect.isTrue(A1 is int);
+  Expect.isTrue(A2 is int);
+  Expect.isTrue(A3 is int);
+
+  Expect.isTrue(C0.X is C1);
+  Expect.isTrue(C0.X.x is C1);
+
+  Expect.equals("Hello 42", B2);
+  Expect.equals("42Hello", B3);
+
+  const cf1 = identical(const Point(1, 2), const Point(1, 2));
+
+  const cf2 = identical(const Point(1, 2), new Point(1, 2));
+  //                                       ^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  // [cfe] New expression is not a constant expression.
+
+  var f4 = B4;
+  var f5 = B5;
+}
+
+const F0 = 42;
+const F1;
+//    ^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED
+// [cfe] The const variable 'F1' must be initialized.
+const int F2 = 87;
+const int F3;
+//        ^
+// [cfe] The const variable 'F3' must be initialized.
+//        ^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED
+
+class Point {
+  final x, y;
+  const Point(this.x, this.y);
+  operator +(int other) => x;
+}
+
+// Check that compile time expressions can include invocations of
+// user-defined const constructors.
+const P0 = const Point(0, 0);
+const P1 = const Point(0, 0) + 1;
+//         ^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_NUM
+//                           ^
+// [cfe] Constant evaluation error:
+const P2 = new Point(0, 0);
+//         ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] New expression is not a constant expression.
+const P3 = new Point(0, 0) + 1;
+//         ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] New expression is not a constant expression.
+
+// Check that we cannot have cyclic references in compile time
+// expressions.
+const A0 = 42;
+const A1 = A0 + 1;
+const A2 = A3 + 1;
+//    ^^
+// [analyzer] COMPILE_TIME_ERROR.RECURSIVE_COMPILE_TIME_CONSTANT
+// [cfe] Can't infer the type of 'A2': circularity found during type inference.
+//         ^^
+// [analyzer] COMPILE_TIME_ERROR.TOP_LEVEL_CYCLE
+//            ^
+// [cfe] Constant evaluation error:
+const A3 = A2 + 1;
+//    ^^
+// [analyzer] COMPILE_TIME_ERROR.RECURSIVE_COMPILE_TIME_CONSTANT
+//         ^^
+// [analyzer] COMPILE_TIME_ERROR.TOP_LEVEL_CYCLE
+
+class C0 {
+  static const X = const C1();
+  //           ^
+  // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_COMPILE_TIME_CONSTANT
+}
+
+class C1 {
+  const C1()
+      : x = C0.X
+      //^
+      // [analyzer] STATIC_WARNING.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
+      //  ^
+      // [cfe] 'x' is a final instance variable that has already been initialized.
+      //  ^
+      // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
+  ;
+  final x = null;
+}
+
+// Check that sub-expressions of binary + are numeric.
+const B0 = 42;
+const B1 = "Hello";
+const B2 = "$B1 $B0";
+const B3 = B0 + B1;
+//         ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_NUM
+//              ^^
+// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] A value of type 'String' can't be assigned to a variable of type 'num'.
+
+// Check identical.
+
+const B4 = identical(1, new Point(1, 2));
+//                      ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] New expression is not a constant expression.
+const B5 = identical(1, const Point(1, 2));
diff --git a/tests/language/const/tree_test.dart b/tests/language/const/tree_test.dart
new file mode 100644
index 0000000..7c0cd28
--- /dev/null
+++ b/tests/language/const/tree_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+class A {
+  final List<A> children;
+  const A({this.children: const []});
+}
+
+const a = const A();
+const b = const A(children: const [a]);
+
+main() {
+  print(b);
+}
diff --git a/tests/language/const/types_test.dart b/tests/language/const/types_test.dart
new file mode 100644
index 0000000..3199c0c
--- /dev/null
+++ b/tests/language/const/types_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test handling of malformed types in constant expressions.
+
+use(x) {}
+
+class Class<T> implements Supertype, GenericSupertype<T> {
+  const Class();
+  const Class.named();
+
+  void test() {
+    use(const []);
+    use(const <Class>[]);
+    use(const <Class<int>>[]);
+    use(const <Class<Unresolved>>[]); //# 01: compile-time error
+    use(const <Unresolved>[]); //# 02: compile-time error
+
+    use(const {});
+    use(const <Class>{});
+    use(const <String, Class>{});
+    use(const <String, Class<int>>{});
+    use(const <String, Class<Unresolved>>{}); //# 04: compile-time error
+    use(const <String, Unresolved>{}); //# 05: compile-time error
+
+    use(const Class());
+    use(const Class<int>());
+    use(const Class<Unresolved>()); //# 06: compile-time error
+    use(const Class<T>()); //# 07: compile-time error
+    use(const Class<Class<T>>()); //# 08: compile-time error
+
+    use(const Unresolved()); //# 09: compile-time error
+    use(const Unresolved<int>()); //# 10: compile-time error
+    use(const prefix.Unresolved()); //# 11: compile-time error
+    use(const prefix.Unresolved<int>()); //# 12: compile-time error
+
+    use(const Class.named());
+    use(const Class<int>.named());
+    use(const Class<Unresolved>.named()); //# 13: compile-time error
+    use(const Class<T>.named()); //# 14: compile-time error
+    use(const Class<Class<T>>.named()); //# 15: compile-time error
+
+    use(const Class.nonamed()); //# 16: compile-time error
+    use(const Class<int>.nonamed()); //# 17: compile-time error
+    use(const Class<Unresolved>.nonamed()); //# 18: compile-time error
+    use(const Class<T>.nonamed()); //# 19: compile-time error
+    use(const Class<Class<T>>.nonamed()); //# 20: compile-time error
+
+    use(const Unresolved.named()); //# 21: compile-time error
+    use(const Unresolved<int>.named()); //# 22: compile-time error
+  }
+}
+
+class Supertype {
+  const factory Supertype() = Unresolved; //# 23: compile-time error
+  const factory Supertype() = Unresolved<int>; //# 24: compile-time error
+  const factory Supertype() = Unresolved.named; //# 25: compile-time error
+  const factory Supertype() = Unresolved<int>.named; //# 26: compile-time error
+
+  const factory Supertype() = prefix.Unresolved; //# 27: compile-time error
+  const factory Supertype() = prefix.Unresolved<int>; //# 28: compile-time error
+  const factory Supertype() = prefix.Unresolved.named; //# 29: compile-time error
+  const factory Supertype() = prefix.Unresolved<int>.named; //# 30: compile-time error
+
+  const factory Supertype() = Class; //# 31: ok
+  const factory Supertype() = Class<int>; //# 32: ok
+  const factory Supertype() = Class<Unresolved>; //# 35: compile-time error
+
+  const factory Supertype() = Class.named; //# 36: ok
+  const factory Supertype() = Class<int>.named; //# 37: ok
+  const factory Supertype() = Class<Unresolved>.named; //# 40: compile-time error
+}
+
+class GenericSupertype<T> {
+  const factory GenericSupertype() = Class<T>; //# 33: ok
+  const factory GenericSupertype() = Class<Class<T>>; //# 34: compile-time error
+
+  const factory GenericSupertype() = Class<T>.named; //# 38: ok
+  const factory GenericSupertype() = Class<Class<T>>.named; //# 39: compile-time error
+
+  const factory GenericSupertype() = T; //# 41: compile-time error
+}
+
+void main() {
+  new Class().test();
+  new Supertype();
+  new GenericSupertype();
+}
diff --git a/tests/language/const/var_helper.dart b/tests/language/const/var_helper.dart
new file mode 100644
index 0000000..ad3806c
--- /dev/null
+++ b/tests/language/const/var_helper.dart
@@ -0,0 +1,11 @@
+// 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.
+// All things regarding constant variables.
+
+/** Helper library for 'var_test.dart' */
+library const_var_helper;
+
+class Foo<E> {
+  const Foo();
+}
diff --git a/tests/language/const/var_test.dart b/tests/language/const/var_test.dart
new file mode 100644
index 0000000..60557f6
--- /dev/null
+++ b/tests/language/const/var_test.dart
@@ -0,0 +1,30 @@
+// 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.
+// All things regarding constant variables.
+
+library const_var;
+
+import 'var_helper.dart' as foo;
+
+const untypedTopLevel = 1;
+const int typedTopLevel = 2;
+const Map<String, String> genericTopLevel = const <String, String>{};
+
+main() {
+  const untypedLocal = 3;
+  const int typedLocal = 4;
+  const Map<String, String> genericLocal = const <String, String>{};
+  const [];
+  const {};
+  const <int>[];
+  const <String, int>{};
+  const Foo();
+  const Foo<int>();
+  const foo.Foo();
+  const foo.Foo<int>();
+}
+
+class Foo<E> {
+  const Foo();
+}
diff --git a/tests/language/constants_2018/const_type_test.dart b/tests/language/constants_2018/const_type_test.dart
new file mode 100644
index 0000000..c6c3f33
--- /dev/null
+++ b/tests/language/constants_2018/const_type_test.dart
@@ -0,0 +1,100 @@
+// 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 types do matter when an expression is evaluated as constant.
+
+main() {
+  const C c = C();
+  const T.test01(c); //# 01: compile-time error
+  const T.test02(c, c); //# 02: compile-time error
+  const T.test03(c, c); //# 03: compile-time error
+  const T.test04(c, c); //# 04: compile-time error
+  const T.test05(c, c); //# 05: compile-time error
+  const T.test06(c, c); //# 06: compile-time error
+  const T.test07(c, c); //# 07: compile-time error
+  const T.test08(c, c); //# 08: compile-time error
+  const T.test09(c, c); //# 09: compile-time error
+  const T.test10(c, c); //# 10: compile-time error
+  const T.test11(c, c); //# 11: compile-time error
+  const T.test12(c, c); //# 12: compile-time error
+  const T.test13(c, c); //# 13: compile-time error
+  const T.test14(c); //# 14: compile-time error
+  const T.test15(c, c); //# 15: compile-time error
+  const T.test16(c, c); //# 16: compile-time error
+  const T.test17(c, c); //# 17: compile-time error
+  const T.test18(c, c); //# 18: compile-time error
+  const T.test19(c); //# 19: compile-time error
+
+  const v01 = false ? c : -c; //# 20: compile-time error
+  const v02 = false ? c : c + c; //# 21: compile-time error
+  const v03 = false ? c : c - c; //# 22: compile-time error
+  const v04 = false ? c : c * c; //# 23: compile-time error
+  const v05 = false ? c : c / c; //# 24: compile-time error
+  const v06 = false ? c : c ~/ c; //# 25: compile-time error
+  const v07 = false ? c : c % c; //# 26: compile-time error
+  const v08 = false ? c : c << c; //# 27: compile-time error
+  const v09 = false ? c : c >> c; //# 28: compile-time error
+  const v10 = false ? c : c >>> c; //# 29: compile-time error
+  const v11 = false ? c : c & c; //# 30: compile-time error
+  const v12 = false ? c : c | c; //# 31: compile-time error
+  const v13 = false ? c : c ^ c; //# 32: compile-time error
+  const v14 = false ? c : ~c; //# 33: compile-time error
+  const v15 = false ? c : c < c; //# 34: compile-time error
+  const v16 = false ? c : c > c; //# 35: compile-time error
+  const v17 = false ? c : c <= c; //# 36: compile-time error
+  const v18 = false ? c : c >= c; //# 37: compile-time error
+  const v19 = false ? c : c.length; //# 38: compile-time error
+}
+
+// Each expression in the forwarding generative constructors must be
+// potentially constant. They are only checked for being actually
+// constant when the constructor is invoked.
+class T {
+  const T(C o);
+  const T.test01(C x) : this(-x);
+  const T.test02(C x, C y) : this(x + y);
+  const T.test03(C x, C y) : this(x - y);
+  const T.test04(C x, C y) : this(x * y);
+  const T.test05(C x, C y) : this(x / y);
+  const T.test06(C x, C y) : this(x ~/ y);
+  const T.test07(C x, C y) : this(x % y);
+  const T.test08(C x, C y) : this(x << y);
+  const T.test09(C x, C y) : this(x >> y);
+  const T.test10(C x, C y) : this(x >>> y); //# 10: continued
+  const T.test11(C x, C y) : this(x & y);
+  const T.test12(C x, C y) : this(x | y);
+  const T.test13(C x, C y) : this(x ^ y);
+  const T.test14(C x) : this(~x);
+  const T.test15(C x, C y) : this(x < y);
+  const T.test16(C x, C y) : this(x > y);
+  const T.test17(C x, C y) : this(x <= y);
+  const T.test18(C x, C y) : this(x >= y);
+  const T.test19(C x) : this(x.length);
+}
+
+class C {
+  const C();
+  C operator -() => this;
+  C operator +(C other) => this;
+  C operator -(C other) => this;
+  C operator *(C other) => this;
+  C operator /(C other) => this;
+  C operator ~/(C other) => this;
+  C operator %(C other) => this;
+  C operator <<(C other) => this;
+  C operator >>(C other) => this;
+  // Remove the multi-test markers and one of the lines below,
+  // when `>>>` is implemented.
+  C operator >>>(C other) => this;  //# 10: continued
+  C operator >>>(C other) => this;  //# 29: continued
+  C operator &(C other) => this;
+  C operator |(C other) => this;
+  C operator ^(C other) => this;
+  C operator ~() => this;
+  C operator <(C other) => this;
+  C operator >(C other) => this;
+  C operator <=(C other) => this;
+  C operator >=(C other) => this;
+  C get length => this;
+}
\ No newline at end of file
diff --git a/tests/language/constants_2018/constant_type_literal_test.dart b/tests/language/constants_2018/constant_type_literal_test.dart
new file mode 100644
index 0000000..b886d77
--- /dev/null
+++ b/tests/language/constants_2018/constant_type_literal_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that non-deferred type literals are constant expressions.
+
+import "dart:core";
+import "dart:core" as core;
+// No reloading support for deferred loading.
+// See https://github.com/dart-lang/sdk/issues/33118.
+import "dart:core" deferred as dcore; //# 01: compile-time error
+
+// Declares F function type alias, M mixin and C class.
+import "constant_type_literal_types.dart";
+import "constant_type_literal_types.dart" as p;
+// No reloading support for deferred loading.
+// See https://github.com/dart-lang/sdk/issues/33118.
+import "constant_type_literal_types.dart" //# 02: compile-time error
+    deferred as d; //# 02: continued
+
+main() {
+  const Test(int, core.int);
+  const Test(C, p.C);
+  const Test(M, p.M);
+  const Test(F, p.F);
+  const c1 = //
+      dcore. //# 01: continued
+          int;
+  const Test(c1, int);
+  const c2 = //
+      d. //# 02: continued
+          C;
+  const Test(c2, C);
+}
+
+class Test {
+  const Test(Type t1, Type t2) : assert(identical(t1, t2));
+}
diff --git a/tests/language/constants_2018/constant_type_literal_types.dart b/tests/language/constants_2018/constant_type_literal_types.dart
new file mode 100644
index 0000000..d3f5f2c
--- /dev/null
+++ b/tests/language/constants_2018/constant_type_literal_types.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Helper file for constant_type_literal_test.dart.
+// Tests that non-deferred type literals are constant expressions.
+
+typedef F = void Function();
+
+class C {}
+
+mixin M {}
diff --git a/tests/language/constants_2018/constant_types_test.dart b/tests/language/constants_2018/constant_types_test.dart
new file mode 100644
index 0000000..2c8dee1
--- /dev/null
+++ b/tests/language/constants_2018/constant_types_test.dart
@@ -0,0 +1,48 @@
+// 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 in some positions only constant types are allowed, so not
+// type parameters. But in other positions potentially constant types are
+// allowed, so type parameters.
+
+import "package:expect/expect.dart";
+
+class T<X> {
+  final Object? value;
+  const T.test1()
+      : value = const //
+            <X> //# 01: compile-time error
+            [];
+  const T.test2(Object o)
+      : value = o //
+            as X //# 02: ok
+  ;
+  const T.test3(Object o)
+      : value = o //
+            is X //# 03: ok
+  ;
+  const T.test4()
+      : value = null //
+            ?? X //# 04: compile-time error
+  ;
+}
+
+class T2 {
+  final Object value;
+  const T2.test1() : value = const <int>[];
+  const T2.test2(Object o) : value = o as int;
+  const T2.test3(Object o) : value = o is int;
+  const T2.test4() : value = int;
+}
+
+main() {
+  // The errors in class T are errors independently of whether the
+  // constructor is invoked or not.
+
+  // Constant type expressions are allowed.
+  Expect.equals(const <int>[], const T2.test1().value);
+  Expect.equals(2, const T2.test2(2).value);
+  Expect.isTrue(const T2.test3(2).value);
+  Expect.equals(int, const T2.test4().value);
+}
diff --git a/tests/language/constants_2018/equals_test.dart b/tests/language/constants_2018/equals_test.dart
new file mode 100644
index 0000000..9e50b76
--- /dev/null
+++ b/tests/language/constants_2018/equals_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that equality is allowed for receivers of specific types.
+
+import "package:expect/expect.dart";
+
+main() {
+  const c = C(); // Does not override operator==.
+  const d = D(); // Overrides operator==.
+
+  // Allowed if receiver is int, double, String, bool or Null, ...
+  Expect.isTrue(const T.eq(1, 1).value);
+  Expect.isTrue(const T.eq(1.5, 1.5).value);
+  Expect.isTrue(const T.eq("", "").value);
+  Expect.isTrue(const T.eq(true, true).value);
+  Expect.isTrue(const T.eq(null, null).value);
+
+  Expect.isFalse(const T.eq(1, c).value);
+  Expect.isFalse(const T.eq(1.5, c).value);
+  Expect.isFalse(const T.eq("", c).value);
+  Expect.isFalse(const T.eq(true, c).value);
+  Expect.isFalse(const T.eq(null, c).value);
+
+  Expect.isFalse(const T.eq(1, d).value);
+  Expect.isFalse(const T.eq(1.5, d).value);
+  Expect.isFalse(const T.eq("", d).value);
+  Expect.isFalse(const T.eq(true, d).value);
+  Expect.isFalse(const T.eq(null, d).value);
+
+  // ... or if second operand is Null.
+  Expect.isFalse(const T.eq(1, null).value);
+  Expect.isFalse(const T.eq(1.5, null).value);
+  Expect.isFalse(const T.eq("", null).value);
+  Expect.isFalse(const T.eq(false, null).value);
+  Expect.isFalse(const T.eq(c, null).value);
+  Expect.isFalse(const T.eq(d, null).value);
+
+  // Otherwise not allowed.
+  const T.eq(c, c); //# 01: compile-time error
+  const T.eq(c, 1); //# 02: compile-time error
+  const T.eq(c, ""); //# 03: compile-time error
+  const T.eq(E.value1, E.value2); //# 04: compile-time error
+}
+
+class T {
+  final Object value;
+  const T.eq(Object? o1, Object? o2) : value = o1 == o2;
+}
+
+/// Class that does not override operator==.
+class C {
+  const C();
+}
+
+/// Class that overrides operator==.
+class D {
+  const D();
+  bool operator ==(Object other) => identical(this, other);
+}
+
+enum E { value1, value2 }
diff --git a/tests/language/constants_2018/potential_const_dynamic_test.dart b/tests/language/constants_2018/potential_const_dynamic_test.dart
new file mode 100644
index 0000000..90de32f
--- /dev/null
+++ b/tests/language/constants_2018/potential_const_dynamic_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that a dynamic type does not affect whether an expression is
+// potentially constant, the actual type of the value of an experssion
+// only matters if the expression is evaluated as a constant.
+
+main() {
+  Object c = C();
+  T.test01(c);
+  T.test02(c, c);
+  T.test03(c, c);
+  T.test04(c, c);
+  T.test05(c, c);
+  T.test06(c, c);
+  T.test07(c, c);
+  T.test08(c, c);
+  T.test09(c, c);
+  T.test10(c, c); //# sh3: ok
+  T.test11(c, c);
+  T.test12(c, c);
+  T .test13(c, c);
+  T.test14(c);
+  T.test15(c, c);
+  T.test16(c, c);
+  T.test17(c, c);
+  T.test18(c, c);
+  T.test19(c);
+}
+
+class T {
+  const T(Object o);
+  const T.test01(dynamic x) : this(-x);
+  const T.test02(dynamic x, dynamic y) : this(x + y);
+  const T.test03(dynamic x, dynamic y) : this(x - y);
+  const T.test04(dynamic x, dynamic y) : this(x * y);
+  const T.test05(dynamic x, dynamic y) : this(x / y);
+  const T.test06(dynamic x, dynamic y) : this(x ~/ y);
+  const T.test07(dynamic x, dynamic y) : this(x % y);
+  const T.test08(dynamic x, dynamic y) : this(x << y);
+  const T.test09(dynamic x, dynamic y) : this(x >> y);
+  const T.test10(dynamic x, dynamic y) : this(x >>> y); //# sh3: continued
+  const T.test11(dynamic x, dynamic y) : this(x & y);
+  const T.test12(dynamic x, dynamic y) : this(x | y);
+  const T.test13(dynamic x, dynamic y) : this(x ^ y);
+  const T.test14(dynamic x) : this(~x);
+  const T.test15(dynamic x, dynamic y) : this(x < y);
+  const T.test16(dynamic x, dynamic y) : this(x > y);
+  const T.test17(dynamic x, dynamic y) : this(x <= y);
+  const T.test18(dynamic x, dynamic y) : this(x >= y);
+  const T.test19(dynamic x) : this(x.length);
+}
+
+class C {
+  const C();
+  dynamic operator -() => this;
+  dynamic operator +(dynamic other) => this;
+  dynamic operator -(dynamic other) => this;
+  dynamic operator *(dynamic other) => this;
+  dynamic operator /(dynamic other) => this;
+  dynamic operator ~/(dynamic other) => this;
+  dynamic operator %(dynamic other) => this;
+  dynamic operator <<(dynamic other) => this;
+  dynamic operator >>(dynamic other) => this;
+  dynamic operator >>>(dynamic other) => this; //# sh3: continued
+  dynamic operator &(dynamic other) => this;
+  dynamic operator |(dynamic other) => this;
+  dynamic operator ^(dynamic other) => this;
+  dynamic operator ~() => this;
+  dynamic operator <(dynamic other) => this;
+  dynamic operator >(dynamic other) => this;
+  dynamic operator <=(dynamic other) => this;
+  dynamic operator >=(dynamic other) => this;
+  dynamic get length => this;
+}
\ No newline at end of file
diff --git a/tests/language/constants_2018/potential_const_shortcircuit_test.dart b/tests/language/constants_2018/potential_const_shortcircuit_test.dart
new file mode 100644
index 0000000..2ce656c
--- /dev/null
+++ b/tests/language/constants_2018/potential_const_shortcircuit_test.dart
@@ -0,0 +1,57 @@
+// 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 short-circuit operators do not care about the unevaluated part.
+
+import "package:expect/expect.dart";
+
+main() {
+  const c = C();
+  // Short-circuited operations.
+  // Non-taken branch of ?:.
+  const c1 = true ? c : c + c;
+  const c2 = false ? c + c : c;
+  // Non-taken part of &&, ||, ??.
+  const c3 = (c != null) || c < c;
+  const c4 = (c == null) && c < c;
+  const c5 = (c as dynamic) ?? c + c;
+  Expect.identical(c, c1);
+  Expect.identical(c, c2);
+  Expect.isTrue(c3);
+  Expect.isFalse(c4);
+  Expect.identical(c, c5);
+  // Nested short-circuiting.
+  const c6 = true ? c == null && c + c : c < c;
+  Expect.isFalse(c6);
+
+  // Concrete use-case.
+  Expect.equals(1, const T.length("a").value);
+  Expect.equals(0, const T.length("").value);
+  Expect.equals(0, const T.length(null).value);
+  Expect.equals(1, T.length([1]).value);
+  Expect.equals(0, T.length([]).value);
+  Expect.equals(0, T.length(null).value);
+
+  Expect.equals(1, const T.asserts("a").value);
+  Expect.equals(0, const T.asserts("").value);
+  Expect.equals(0, const T.asserts(null).value);
+  Expect.equals(1, T.asserts([1]).value);
+  Expect.equals(0, T.asserts([]).value);
+  Expect.equals(0, T.asserts(null).value);
+}
+
+class T {
+  final Object value;
+  const T(this.value);
+  const T.length(dynamic l) : value = (l == null ? 0 : l.length);
+  const T.asserts(dynamic l)
+      : assert(l == null || l.length < 2),
+        value = (l ?? "").length;
+}
+
+class C {
+  const C();
+  dynamic operator +(dynamic other) => throw "Never";
+  bool operator <(dynamic other) => throw "Never";
+}
diff --git a/tests/language/constants_2018/potential_const_type_test.dart b/tests/language/constants_2018/potential_const_type_test.dart
new file mode 100644
index 0000000..0f06507
--- /dev/null
+++ b/tests/language/constants_2018/potential_const_type_test.dart
@@ -0,0 +1,95 @@
+// 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 types do not affect whether an expression is potentially
+// constant, they only matter if the expression is evaluated as a constant.
+
+main() {
+  const C c = C();
+  T.test01(c);
+  T.test02(c, c);
+  T.test03(c, c);
+  T.test04(c, c);
+  T.test05(c, c);
+  T.test06(c, c);
+  T.test07(c, c);
+  T.test08(c, c);
+  T.test09(c, c);
+  T.test10(c, c); //# sh3: ok
+  T.test11(c, c);
+  T.test12(c, c);
+  T.test13(c, c);
+  T.test14(c);
+  T.test15(c, c);
+  T.test16(c, c);
+  T.test17(c, c);
+  T.test18(c, c);
+  T.test19(c);
+
+  const v01 = true ? c : -c;
+  const v02 = true ? c : c + c;
+  const v03 = true ? c : c - c;
+  const v04 = true ? c : c * c;
+  const v05 = true ? c : c / c;
+  const v06 = true ? c : c ~/ c;
+  const v07 = true ? c : c % c;
+  const v08 = true ? c : c << c;
+  const v09 = true ? c : c >> c;
+  const v10 = true ? c : c >>> c; //# sh3: continued
+  const v11 = true ? c : c & c;
+  const v12 = true ? c : c | c;
+  const v13 = true ? c : c ^ c;
+  const v14 = true ? c : ~c;
+  const v15 = true ? c : c < c;
+  const v16 = true ? c : c > c;
+  const v17 = true ? c : c <= c;
+  const v18 = true ? c : c >= c;
+  const v19 = true ? c : c.length;
+}
+
+class T {
+  const T(C o);
+  const T.test01(C x) : this(-x);
+  const T.test02(C x, C y) : this(x + y);
+  const T.test03(C x, C y) : this(x - y);
+  const T.test04(C x, C y) : this(x * y);
+  const T.test05(C x, C y) : this(x / y);
+  const T.test06(C x, C y) : this(x ~/ y);
+  const T.test07(C x, C y) : this(x % y);
+  const T.test08(C x, C y) : this(x << y);
+  const T.test09(C x, C y) : this(x >> y);
+  const T.test10(C x, C y) : this(x >>> y); //# sh3: continued
+  const T.test11(C x, C y) : this(x & y);
+  const T.test12(C x, C y) : this(x | y);
+  const T.test13(C x, C y) : this(x ^ y);
+  const T.test14(C x) : this(~x);
+  const T.test15(C x, C y) : this(x < y);
+  const T.test16(C x, C y) : this(x > y);
+  const T.test17(C x, C y) : this(x <= y);
+  const T.test18(C x, C y) : this(x >= y);
+  const T.test19(C x) : this(x.length);
+}
+
+class C {
+  const C();
+  C operator -() => this;
+  C operator +(C other) => this;
+  C operator -(C other) => this;
+  C operator *(C other) => this;
+  C operator /(C other) => this;
+  C operator ~/(C other) => this;
+  C operator %(C other) => this;
+  C operator <<(C other) => this;
+  C operator >>(C other) => this;
+  C operator >>>(C other) => this; //# sh3: continued
+  C operator &(C other) => this;
+  C operator |(C other) => this;
+  C operator ^(C other) => this;
+  C operator ~() => this;
+  C operator <(C other) => this;
+  C operator >(C other) => this;
+  C operator <=(C other) => this;
+  C operator >=(C other) => this;
+  C get length => this;
+}
\ No newline at end of file
diff --git a/tests/language/constants_2018/type_cast_test.dart b/tests/language/constants_2018/type_cast_test.dart
new file mode 100644
index 0000000..679c2e2
--- /dev/null
+++ b/tests/language/constants_2018/type_cast_test.dart
@@ -0,0 +1,26 @@
+// 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 type casts (as) are allowed.
+
+main() {
+  const t = T.explicit(Sub());
+
+  // Inline.
+  const Object o = "";
+  const len = (o as String).length;
+}
+
+class Super {
+  const Super();
+}
+
+class Sub extends Super {
+  const Sub();
+}
+
+class T {
+  final Sub value;
+  const T.explicit(Super s) : value = s as Sub;
+}
diff --git a/tests/language/constants_2018/type_check_test.dart b/tests/language/constants_2018/type_check_test.dart
new file mode 100644
index 0000000..7c7a318
--- /dev/null
+++ b/tests/language/constants_2018/type_check_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that type checks (is) are allowed.
+
+import "package:expect/expect.dart";
+
+main() {
+  const c = C();
+  const l = [1];
+  const s = "a";
+
+  Expect.equals(1, const T.length(s, 42).value);
+  Expect.equals(42, const T.length(l, 42).value);
+  Expect.equals(1, const T.length2(s, 42).value);
+  Expect.equals(42, const T.length2(l, 42).value);
+
+  Expect.equals(3, const T.sum(1, 2).value);
+  Expect.equals(3.7, const T.sum(1.5, 2.2).value);
+  Expect.equals("abc", const T.sum("a", "bc").value);
+  Expect.equals("a", const T.sum("a", 2).value);
+}
+
+class T {
+  final Object value;
+  const T.length(dynamic l, int defaultValue)
+      : value = l is String ? l.length : defaultValue;
+  const T.length2(dynamic l, int defaultValue)
+      : value = l is! String ? defaultValue : l.length;
+  const T.sum(dynamic o1, dynamic o2)
+      : value = ((o1 is num) & (o2 is num)) | ((o1 is String) & (o2 is String))
+            ? o1 + o2
+            : o1;
+}
+
+class C {
+  const C();
+  dynamic operator +(dynamic other) => throw "Never";
+  bool operator <(dynamic other) => throw "Never";
+}
diff --git a/tests/language/constructor/bad_constructor_runtime_1_test.dart b/tests/language/constructor/bad_constructor_runtime_1_test.dart
new file mode 100644
index 0000000..cf8d562
--- /dev/null
+++ b/tests/language/constructor/bad_constructor_runtime_1_test.dart
@@ -0,0 +1,39 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// A constructor can't be static.
+class A {
+
+  A();
+}
+
+// A factory constructor can't be static.
+class B {
+
+  factory B() { return B._(); }
+
+  B._();
+}
+
+// A named constructor can have the same name as a setter.
+class E {
+  set setter(value) {}
+  E.setter();
+}
+
+// A constructor can't be static.
+class F {
+
+  F(){}
+}
+
+main() {
+  new A();
+  new B();
+  new E.setter();
+  new F();
+}
diff --git a/tests/language/constructor/bad_constructor_runtime_test.dart b/tests/language/constructor/bad_constructor_runtime_test.dart
new file mode 100644
index 0000000..71e14bd
--- /dev/null
+++ b/tests/language/constructor/bad_constructor_runtime_test.dart
@@ -0,0 +1,39 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// A constructor can't be static.
+class A {
+
+  A();
+}
+
+// A factory constructor can't be static.
+class B {
+
+  factory B() { return B._(); }
+
+  B._();
+}
+
+// A named constructor can have the same name as a setter.
+class E {
+
+  E.setter();
+}
+
+// A constructor can't be static.
+class F {
+
+  F(){}
+}
+
+main() {
+  new A();
+  new B();
+  new E.setter();
+  new F();
+}
diff --git a/tests/language/constructor/bad_constructor_test.dart b/tests/language/constructor/bad_constructor_test.dart
new file mode 100644
index 0000000..5cb42f6
--- /dev/null
+++ b/tests/language/constructor/bad_constructor_test.dart
@@ -0,0 +1,48 @@
+// 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.
+
+// A constructor can't be static.
+class A {
+  static
+//^^^^^^
+// [analyzer] SYNTACTIC_ERROR.STATIC_CONSTRUCTOR
+// [cfe] Constructors can't be static.
+  A();
+  // ^
+  // [analyzer] SYNTACTIC_ERROR.MISSING_FUNCTION_BODY
+  // [cfe] Expected a function body or '=>'.
+}
+
+// A factory constructor can't be static.
+class B {
+  static
+//^^^^^^
+// [analyzer] SYNTACTIC_ERROR.EXTRANEOUS_MODIFIER
+// [cfe] Can't have modifier 'static' here.
+  factory B() { return B._(); }
+
+  B._();
+}
+
+// A named constructor can have the same name as a setter.
+class E {
+  set setter(value) {}
+  E.setter();
+}
+
+// A constructor can't be static.
+class F {
+  static
+//^^^^^^
+// [analyzer] SYNTACTIC_ERROR.STATIC_CONSTRUCTOR
+// [cfe] Constructors can't be static.
+  F(){}
+}
+
+main() {
+  new A();
+  new B();
+  new E.setter();
+  new F();
+}
diff --git a/tests/language/constructor/bad_named_constructor_runtime_test.dart b/tests/language/constructor/bad_named_constructor_runtime_test.dart
new file mode 100644
index 0000000..c84de90
--- /dev/null
+++ b/tests/language/constructor/bad_named_constructor_runtime_test.dart
@@ -0,0 +1,15 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class A {
+  A() {}
+
+}
+
+main() {
+  new A();
+}
diff --git a/tests/language/constructor/bad_named_constructor_test.dart b/tests/language/constructor/bad_named_constructor_test.dart
new file mode 100644
index 0000000..d8a40d9
--- /dev/null
+++ b/tests/language/constructor/bad_named_constructor_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+class A {
+  A() {}
+  WrongName.foo() {}
+//^^^^^^^^^
+// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTRUCTOR_NAME
+// [cfe] The name of a constructor must match the name of the enclosing class.
+}
+
+main() {
+  new A();
+}
diff --git a/tests/language/constructor/body_test.dart b/tests/language/constructor/body_test.dart
new file mode 100644
index 0000000..d64d61f
--- /dev/null
+++ b/tests/language/constructor/body_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors without function bodies.
+
+import "package:expect/expect.dart";
+
+// Test a non-const constructor works without a body.
+class First {
+  First(int this.value);
+  First.named(int this.value);
+  int value;
+}
+
+// Test a const constructor works without a body.
+class Second {
+  const Second(int this.value);
+  const Second.named(int this.value);
+  final int value;
+}
+
+class ConstructorBodyTest {
+  static testMain() {
+    Expect.equals(4, new First(4).value);
+    Expect.equals(5, new First.named(5).value);
+    Expect.equals(6, new Second(6).value);
+    Expect.equals(7, new Second.named(7).value);
+  }
+}
+
+main() {
+  ConstructorBodyTest.testMain();
+}
diff --git a/tests/language/constructor/bodyless_wrong_arg_runtime_test.dart b/tests/language/constructor/bodyless_wrong_arg_runtime_test.dart
new file mode 100644
index 0000000..6a6c07e
--- /dev/null
+++ b/tests/language/constructor/bodyless_wrong_arg_runtime_test.dart
@@ -0,0 +1,25 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Base {
+  final String name;
+  const Base(this.name);
+}
+
+class C extends Base {
+  const C(String s)
+      : super(
+        // Call super constructor with wrong argument count.
+
+        s
+
+        );
+}
+
+main() {
+  const C("str");
+}
diff --git a/tests/language/constructor/bodyless_wrong_arg_test.dart b/tests/language/constructor/bodyless_wrong_arg_test.dart
new file mode 100644
index 0000000..4e669d0
--- /dev/null
+++ b/tests/language/constructor/bodyless_wrong_arg_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+class Base {
+  final String name;
+  const Base(this.name);
+}
+
+class C extends Base {
+  const C(String s)
+      // Call super constructor with wrong argument count.
+      : super();
+      //     ^^
+      // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+      // [cfe] Too few positional arguments: 1 required, 0 given.
+}
+
+main() {
+  const C("str");
+}
diff --git a/tests/language/constructor/call_as_function_test.dart b/tests/language/constructor/call_as_function_test.dart
new file mode 100644
index 0000000..cb1dbda
--- /dev/null
+++ b/tests/language/constructor/call_as_function_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Point {
+  const Point(this.x, this.y);
+  final int x;
+  final int y;
+}
+
+main() {
+  Point p = Point(1, 2);
+}
diff --git a/tests/language/constructor/call_wrong_argument_count_runtime_test.dart b/tests/language/constructor/call_wrong_argument_count_runtime_test.dart
new file mode 100644
index 0000000..adb20bd
--- /dev/null
+++ b/tests/language/constructor/call_wrong_argument_count_runtime_test.dart
@@ -0,0 +1,15 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Stockhorn {
+  Stockhorn(int a);
+}
+
+main() {
+  new Stockhorn(1);
+
+}
diff --git a/tests/language/constructor/call_wrong_argument_count_test.dart b/tests/language/constructor/call_wrong_argument_count_test.dart
new file mode 100644
index 0000000..4830bcd
--- /dev/null
+++ b/tests/language/constructor/call_wrong_argument_count_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Stockhorn {
+  Stockhorn(int a);
+}
+
+main() {
+  new Stockhorn(1);
+  new Stockhorn();
+  //           ^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+  // [cfe] Too few positional arguments: 1 required, 0 given.
+}
diff --git a/tests/language/constructor/constructor10_runtime_test.dart b/tests/language/constructor/constructor10_runtime_test.dart
new file mode 100644
index 0000000..554c0e1
--- /dev/null
+++ b/tests/language/constructor/constructor10_runtime_test.dart
@@ -0,0 +1,47 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that the implicit super call for synthetic constructors are checked.
+
+class A {
+  final x;
+  A(this.x);
+}
+
+class B extends A {
+
+  B() : super(null);
+
+}
+
+// ==========
+
+class Y extends A {
+
+  Y() : super(null);
+
+}
+
+class Z extends Y {
+  Z() : super();
+}
+
+// ==============
+
+class G extends A {
+
+  G() : super(null);
+
+}
+
+class H extends G {}
+
+main() {
+  new B().x;
+  new Z().x;
+  new H().x;
+}
diff --git a/tests/language/constructor/constructor10_test.dart b/tests/language/constructor/constructor10_test.dart
new file mode 100644
index 0000000..06426fb
--- /dev/null
+++ b/tests/language/constructor/constructor10_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that the implicit super call for synthetic constructors are checked.
+
+class A {
+  final x;
+  A(this.x);
+}
+
+class B extends A {
+//    ^
+// [analyzer] COMPILE_TIME_ERROR.NO_DEFAULT_SUPER_CONSTRUCTOR
+// [cfe] The superclass, 'A', has no unnamed constructor that takes no arguments.
+  /*
+  B() : super(null);
+  */
+}
+
+// ==========
+
+class Y extends A {
+//    ^
+// [analyzer] COMPILE_TIME_ERROR.NO_DEFAULT_SUPER_CONSTRUCTOR
+// [cfe] The superclass, 'A', has no unnamed constructor that takes no arguments.
+  /*
+  Y() : super(null);
+  */
+}
+
+class Z extends Y {
+  Z() : super();
+}
+
+// ==============
+
+class G extends A {
+//    ^
+// [analyzer] COMPILE_TIME_ERROR.NO_DEFAULT_SUPER_CONSTRUCTOR
+// [cfe] The superclass, 'A', has no unnamed constructor that takes no arguments.
+  /*
+  G() : super(null);
+  */
+}
+
+class H extends G {}
+
+main() {
+  new B().x;
+  new Z().x;
+  new H().x;
+}
diff --git a/tests/language/constructor/constructor11_test.dart b/tests/language/constructor/constructor11_test.dart
new file mode 100644
index 0000000..73d08a3
--- /dev/null
+++ b/tests/language/constructor/constructor11_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that the implicit super call for synthetic constructors are checked.
+
+import "package:expect/expect.dart";
+
+class A {
+  final x;
+  A([this.x = 499]);
+}
+
+class B extends A {}
+
+// ==========
+
+class X {
+  final x;
+  X([this.x = 42]);
+}
+
+class Y extends X {}
+
+class Z extends Y {
+  Z() : super();
+}
+
+// ==============
+
+class F {
+  final x;
+  F([this.x = 99]);
+}
+
+class G extends F {}
+
+class H extends G {}
+
+main() {
+  Expect.equals(499, new B().x);
+  Expect.equals(42, new Z().x);
+  Expect.equals(99, new H().x);
+}
diff --git a/tests/language/constructor/constructor12_lib.dart b/tests/language/constructor/constructor12_lib.dart
new file mode 100644
index 0000000..70dfe76
--- /dev/null
+++ b/tests/language/constructor/constructor12_lib.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// TODO(nshahan) Merge back into constructor12_test.dart along with the
+// expectation from constructor12_strong_test.dart after ending support for weak
+// mode.
+
+class B {
+  final z;
+  B(this.z);
+
+  foo() => this.z;
+}
+
+class A<T> extends B {
+  var captured, captured2;
+  var typedList;
+
+  // p must be inside a box (in dart2js).
+  A(p)
+      : captured = (() => p),
+        super(p++) {
+    // Make constructor body non-inlinable.
+    try {} catch (e) {}
+
+    captured2 = () => p++;
+
+    // In the current implementation of dart2js makes the generic type an
+    // argument to the body.
+    typedList = <T>[];
+  }
+
+  foo() => captured();
+  bar() => captured2();
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
diff --git a/tests/language/constructor/constructor12_strong_test.dart b/tests/language/constructor/constructor12_strong_test.dart
new file mode 100644
index 0000000..bcc2672
--- /dev/null
+++ b/tests/language/constructor/constructor12_strong_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// Requirements=nnbd-strong
+
+// Copied from constructor12_test.dart to break out a single expectation that
+// is different in weak and strong modes.
+
+import "package:expect/expect.dart";
+
+import 'constructor12_lib.dart';
+
+main() {
+  var a2 = confuse(new A(2));
+  Expect.isFalse(a2 is A<Object>);
+}
diff --git a/tests/language/constructor/constructor12_test.dart b/tests/language/constructor/constructor12_test.dart
new file mode 100644
index 0000000..2af0ed2
--- /dev/null
+++ b/tests/language/constructor/constructor12_test.dart
@@ -0,0 +1,40 @@
+// 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:expect/expect.dart";
+
+import 'constructor12_lib.dart';
+
+main() {
+  var a = confuse(new A<int>(1));
+  var a2 = confuse(new A(2));
+  var b = confuse(new B(3));
+  Expect.equals(2, a.foo());
+  Expect.equals(3, a2.foo());
+  Expect.equals(3, b.foo());
+  Expect.equals(1, a.z);
+  Expect.equals(2, a2.z);
+  Expect.equals(3, b.z);
+  Expect.isTrue(a is A<int>);
+  Expect.isFalse(a is A<String>);
+  Expect.isFalse(a2 is A<int>);
+  Expect.isFalse(a2 is A<String>);
+  // TODO(nshahan) Move back from constructor12_strong_test.dart after ending
+  // support for weak mode.
+  // Expect.isFalse(a2 is A<Object>);
+  Expect.isTrue(a2 is A<Object?>);
+  Expect.equals(2, a.bar());
+  Expect.equals(3, a2.bar());
+  Expect.equals(3, a.foo());
+  Expect.equals(4, a2.foo());
+  Expect.equals(0, a.typedList.length);
+  Expect.equals(0, a2.typedList.length);
+  a.typedList.add(499);
+  Expect.equals(1, a.typedList.length);
+  Expect.equals(0, a2.typedList.length);
+  Expect.isTrue(a.typedList is List<int>);
+  Expect.isFalse(a2.typedList is List<int>);
+  Expect.isFalse(a.typedList is List<String>);
+  Expect.isFalse(a2.typedList is List<String>);
+}
diff --git a/tests/language/constructor/constructor12_weak_test.dart b/tests/language/constructor/constructor12_weak_test.dart
new file mode 100644
index 0000000..2a4d2f6
--- /dev/null
+++ b/tests/language/constructor/constructor12_weak_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Requirements=nnbd-weak
+
+// Copied from constructor12_test.dart to break out a single expectation that
+// is different in weak and strong modes.
+
+import "package:expect/expect.dart";
+
+import 'constructor12_lib.dart';
+
+main() {
+  var a2 = confuse(new A(2));
+  // Only true in weak mode.
+  Expect.isTrue(a2 is A<Object>);
+}
diff --git a/tests/language/constructor/constructor13_runtime_test.dart b/tests/language/constructor/constructor13_runtime_test.dart
new file mode 100644
index 0000000..e2ff3b6
--- /dev/null
+++ b/tests/language/constructor/constructor13_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Check that there's no crash when constructor called with wrong
+// number of args.
+
+class Klass {
+  Klass(v) {}
+}
+
+main() {
+
+  new Klass(1);
+
+}
diff --git a/tests/language/constructor/constructor13_test.dart b/tests/language/constructor/constructor13_test.dart
new file mode 100644
index 0000000..f6790ec
--- /dev/null
+++ b/tests/language/constructor/constructor13_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// Check that there's no crash when constructor called with wrong
+// number of args.
+
+class Klass {
+  Klass(v) {}
+}
+
+main() {
+  new Klass();
+  //       ^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+  // [cfe] Too few positional arguments: 1 required, 0 given.
+  new Klass(1);
+  new Klass(1, 2);
+  //       ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+  // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+}
diff --git a/tests/language/constructor/constructor2_test.dart b/tests/language/constructor/constructor2_test.dart
new file mode 100644
index 0000000..97dd7de
--- /dev/null
+++ b/tests/language/constructor/constructor2_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+// Expect the initializer expressions E(i) to be evaluated
+// in the order 1, 2, 3, ...
+// Each expression must be evaluated exactly once.
+
+String trace = "";
+
+int E(int i) {
+  trace += "$i-";
+  return i;
+}
+
+class A {
+  var a1;
+  A(x, y) : a1 = E(4) {
+    Expect.equals(2, x);
+    Expect.equals(3, y);
+    Expect.equals(4, a1);
+    E(6);
+  }
+}
+
+class B extends A {
+  var b1, b2;
+
+  B(x)
+      : b1 = E(1),
+        b2 = E(5),
+        super(E(2), E(3)) {
+    Expect.equals(1, b1);
+    Expect.equals(5, b2);
+    E(7);
+  }
+}
+
+main() {
+  var b = new B(0);
+  Expect.equals("1-5-2-3-4-6-7-", trace);
+}
diff --git a/tests/language/constructor/constructor3_test.dart b/tests/language/constructor/constructor3_test.dart
new file mode 100644
index 0000000..4bb7173
--- /dev/null
+++ b/tests/language/constructor/constructor3_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+// Expect the initializer expressions E(i) to be evaluated
+// in the order 1, 2, 3, ...
+// Each expression must be evaluated exactly once.
+
+String trace = "";
+
+int E(int i) {
+  trace += "$i-";
+  return i;
+}
+
+class A {
+  var a1;
+  A(x, y) : a1 = E(3) {
+    Expect.equals(1, x);
+    Expect.equals(2, y);
+    E(5);
+  }
+}
+
+class B extends A {
+  var b1;
+  B(x)
+      : b1 = E(4),
+        super(E(1), E(2)) {
+    // Implicit super call to A's body happens here.
+    Expect.equals(4, b1);
+    E(6);
+  }
+}
+
+main() {
+  var b = new B(0);
+  Expect.equals("4-1-2-3-5-6-", trace);
+}
diff --git a/tests/language/constructor/constructor4_test.dart b/tests/language/constructor/constructor4_test.dart
new file mode 100644
index 0000000..b4df9b0
--- /dev/null
+++ b/tests/language/constructor/constructor4_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+// Expect the initializer expressions E(i) to be evaluated
+// in the order 1, 2, 3, ...
+// Each expression must be evaluated exactly once.
+
+String trace = "";
+
+int E(int i) {
+  trace += "$i-";
+  return i;
+}
+
+class A {
+  var a1;
+  A() : a1 = E(2) {
+    E(3);
+  }
+}
+
+class B extends A {
+  var b1;
+  B(x) : b1 = E(1) /* Implicit super call to A's initializers happens here. */ {
+    // Implicit super call to A's body happens here.
+    E(4);
+  }
+}
+
+main() {
+  var b = new B(0);
+  Expect.equals("1-2-3-4-", trace);
+}
diff --git a/tests/language/constructor/constructor5_test.dart b/tests/language/constructor/constructor5_test.dart
new file mode 100644
index 0000000..52020cf
--- /dev/null
+++ b/tests/language/constructor/constructor5_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+// Super initializer and super constructor body are executed in with the same
+// bindings.
+
+String trace = "";
+
+int E(int i) {
+  trace = "$trace$i-";
+  return i;
+}
+
+class A {
+  A({arg1: 100, arg2: 200})
+      : a1 = E(arg1++),
+        a2 = E(arg2++) {
+    // b2 should be initialized between the above initializers and the following
+    // statements.
+    E(arg1); // 101
+    E(arg2); // 51
+  }
+  var a1;
+  var a2;
+}
+
+class B extends A {
+  // Initializers in order: b1, super, b2.
+  B(x, y)
+      : b1 = E(x++),
+        b2 = E(y++),
+        super(arg2: 50) {
+    // Implicit super call to A's body happens here.
+    E(x); // 11
+    E(y); // 21
+  }
+  var b1;
+  var b2;
+}
+
+class C extends B {
+  C() : super(10, 20);
+}
+
+main() {
+  var c = new C();
+  Expect.equals(100, c.a1);
+  Expect.equals(50, c.a2);
+  Expect.equals(10, c.b1);
+  Expect.equals(20, c.b2);
+
+  Expect.equals("10-20-100-50-101-51-11-21-", trace);
+}
diff --git a/tests/language/constructor/constructor6_test.dart b/tests/language/constructor/constructor6_test.dart
new file mode 100644
index 0000000..71f6c38
--- /dev/null
+++ b/tests/language/constructor/constructor6_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+// Super initializer and super constructor body are executed in with the same
+// bindings.
+
+String trace = "";
+
+int E(int i) {
+  trace = "$trace$i-";
+  return i;
+}
+
+class A {
+  // f closes-over arg.  arg needs to be preserved while b2 is initialized.
+  A(arg)
+      : a = E(arg += 1),
+        f = (() => E(arg += 10)) {
+    // b2 should be initialized between the above initializers and the following
+    // statements.
+    var r1 = f();
+    E(arg += 100); // If this is the same arg as closed by f, ...
+    var r2 = f(); //  .. the effect of +=100 will be seen here.
+  }
+  final a;
+  final f;
+}
+
+class B extends A {
+  // Initializers in order: b1, super, b2.
+  B(x, y)
+      : b1 = E(x++),
+        b2 = E(y++),
+        super(1000) {
+    // Implicit super call to A's body happens here.
+    E(x);
+    E(y);
+    f();
+  }
+  var b1;
+  var b2;
+}
+
+class C extends B {
+  C() : super(10, 20);
+}
+
+main() {
+  var c = new C();
+  Expect.equals("10-20-1001-1011-1111-1121-11-21-1131-", trace);
+}
diff --git a/tests/language/constructor/constructor7_test.dart b/tests/language/constructor/constructor7_test.dart
new file mode 100644
index 0000000..5ed7be4
--- /dev/null
+++ b/tests/language/constructor/constructor7_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+// Expect the initializer expressions E(i) to be evaluated
+// in the order 1, 2, 3, ...
+// This test has no inheritance but many fields to flush out issues with
+// ordering of fields.
+
+String trace = "";
+
+int E(int i) {
+  trace += "$i-";
+  return i;
+}
+
+class A {
+  var j; //      Names are in reverse order to detect sorting by name...
+  var i = 0; //  Initialized odd/even to detect these inits affecting order.
+  var h;
+  var g = 0;
+  var f;
+  var e = 0;
+  var d;
+  var c = 0;
+  var b;
+  var a = 0;
+
+  A()
+      : a = E(1), // Initializations in different order to decls.  Ascending...
+        b = E(2),
+        c = E(3),
+        f = E(4), // Descending to be perverse...
+        e = E(5),
+        d = E(6),
+        g = E(7), // Ascending again.
+        h = E(8),
+        i = E(9),
+        j = E(10) {
+    Expect.equals(1, a);
+    Expect.equals(2, b);
+    Expect.equals(3, c);
+
+    Expect.equals(4, f);
+    Expect.equals(5, e);
+    Expect.equals(6, d);
+
+    Expect.equals(7, g);
+    Expect.equals(8, h);
+    Expect.equals(9, i);
+    Expect.equals(10, j);
+  }
+}
+
+main() {
+  var x = new A();
+  Expect.equals('1-2-3-4-5-6-7-8-9-10-', trace);
+}
diff --git a/tests/language/constructor/constructor8_test.dart b/tests/language/constructor/constructor8_test.dart
new file mode 100644
index 0000000..2de31c4
--- /dev/null
+++ b/tests/language/constructor/constructor8_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Regression test for dart2js that used to crash on this program.
+
+class A {
+  var b;
+
+  // The closure in the constructor body used to confuse the SSA builder
+  // when it created the call to the constructor body.
+  A.withClosure(Map? a) {
+    var c;
+    var f = () {
+      return c = 42;
+    };
+    b = f();
+    Expect.equals(42, b);
+    Expect.equals(42, c);
+  }
+}
+
+main() {
+  new A.withClosure(null);
+  new A.withClosure({});
+}
diff --git a/tests/language/constructor/constructor9_runtime_test.dart b/tests/language/constructor/constructor9_runtime_test.dart
new file mode 100644
index 0000000..fcdbf5a
--- /dev/null
+++ b/tests/language/constructor/constructor9_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that all final instance fields of a class are initialized by
+// constructors.
+
+class Klass {
+  Klass(var v) : field_ = v {}
+
+  var field_;
+}
+
+main() {
+  new Klass(5);
+}
diff --git a/tests/language/constructor/constructor9_test.dart b/tests/language/constructor/constructor9_test.dart
new file mode 100644
index 0000000..4c7b35d
--- /dev/null
+++ b/tests/language/constructor/constructor9_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that all final instance fields of a class are initialized by
+// constructors.
+
+class Klass {
+  Klass(var v) : field_ = v {}
+//^^^^^
+// [analyzer] STATIC_WARNING.FINAL_NOT_INITIALIZED_CONSTRUCTOR
+  final uninitializedFinalField_;
+  //    ^
+  // [cfe] Final field 'uninitializedFinalField_' is not initialized.
+  final uninitializedFinalField_;
+  //    ^^^^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'uninitializedFinalField_' is already declared in this scope.
+  var field_;
+}
+
+main() {
+  new Klass(5);
+}
diff --git a/tests/language/constructor/constructor_test.dart b/tests/language/constructor/constructor_test.dart
new file mode 100644
index 0000000..17c3842
--- /dev/null
+++ b/tests/language/constructor/constructor_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+import "package:expect/expect.dart";
+
+class A extends B {
+  A(x, y)
+      : a = x,
+        super(y) {}
+
+  var a;
+}
+
+class B {
+  var b;
+
+  B(x) : b = x {}
+
+  B.namedB(var x) : b = x {}
+}
+
+// Test the order of initialization: first the instance variable then
+// the super constructor.
+abstract class Alpha {
+  Alpha(v) {
+    this.foo(v);
+  }
+  foo(v) => throw 'Alpha.foo should never be called.';
+}
+
+class Beta extends Alpha {
+  Beta(v)
+      : b = 1,
+        super(v) {}
+
+  foo(v) {
+    // Check that 'b' was initialized.
+    Expect.equals(1, b);
+    b = v;
+  }
+
+  var b;
+}
+
+class ConstructorTest {
+  static testMain() {
+    var o = new A(10, 2);
+    Expect.equals(10, o.a);
+    Expect.equals(2, o.b);
+
+    var o1 = new B.namedB(10);
+    Expect.equals(10, o1.b);
+
+    Expect.equals(22, o.a + o.b + o1.b);
+
+    var beta = new Beta(3);
+    Expect.equals(3, beta.b);
+  }
+}
+
+main() {
+  ConstructorTest.testMain();
+}
diff --git a/tests/language/constructor/cyclic_constructor_test.dart b/tests/language/constructor/cyclic_constructor_test.dart
new file mode 100644
index 0000000..1b2533f
--- /dev/null
+++ b/tests/language/constructor/cyclic_constructor_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+class A {
+  A.a() : this.b();
+  //      ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_CONSTRUCTOR_REDIRECT
+  A.b()
+    : this.a()
+    //^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_CONSTRUCTOR_REDIRECT
+    //     ^
+    // [cfe] Redirecting constructors can't be cyclic.
+  ;
+  A.c() : this.b();
+}
+
+main() {
+  new A.a();
+  new A.b();
+  new A.c();
+}
diff --git a/tests/language/constructor/cyclic_runtime_test.dart b/tests/language/constructor/cyclic_runtime_test.dart
new file mode 100644
index 0000000..b0cf8aff
--- /dev/null
+++ b/tests/language/constructor/cyclic_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class A {
+  A.a() : this.b();
+  A.b()
+
+  ;
+  A.c() : this.b();
+}
+
+main() {
+  new A.a();
+  new A.b();
+  new A.c();
+}
diff --git a/tests/language/constructor/default_class_implicit_constructor_test.dart b/tests/language/constructor/default_class_implicit_constructor_test.dart
new file mode 100644
index 0000000..30d48a5
--- /dev/null
+++ b/tests/language/constructor/default_class_implicit_constructor_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// An abstract class with a redirecting factory to a class with no declared
+// constructor should use the implicit default constructor.
+
+abstract class A {
+  factory A() = B;
+}
+
+class B implements A {}
+
+main() {
+  var val = new A();
+  Expect.equals(true, val is A);
+  Expect.equals(true, val is B);
+}
diff --git a/tests/language/constructor/default_factory2_runtime_test.dart b/tests/language/constructor/default_factory2_runtime_test.dart
new file mode 100644
index 0000000..2113b80
--- /dev/null
+++ b/tests/language/constructor/default_factory2_runtime_test.dart
@@ -0,0 +1,24 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Check type bounds when invoking a redirecting factory method
+
+abstract class Foo {}
+
+abstract class IA<T> {
+
+}
+
+class A<T extends Foo> implements IA<T> {
+  factory A() { return A._(); }
+
+  A._();
+}
+
+main() {
+
+}
diff --git a/tests/language/constructor/default_factory2_test.dart b/tests/language/constructor/default_factory2_test.dart
new file mode 100644
index 0000000..a8b56b8
--- /dev/null
+++ b/tests/language/constructor/default_factory2_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Check type bounds when invoking a redirecting factory method
+
+abstract class Foo {}
+
+abstract class IA<T> {
+  factory IA() = A<T>;
+  //             ^
+  // [cfe] The type 'T' doesn't extend 'Foo'.
+  //               ^
+  // [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+}
+
+class A<T extends Foo> implements IA<T> {
+  factory A() { return A._(); }
+
+  A._();
+}
+
+main() {
+  var result = new IA<String>();
+  //               ^
+  // [cfe] Type argument 'String' doesn't conform to the bound 'Foo' of the type variable 'T' on 'A'.
+}
diff --git a/tests/language/constructor/default_factory3_test.dart b/tests/language/constructor/default_factory3_test.dart
new file mode 100644
index 0000000..58d89b9
--- /dev/null
+++ b/tests/language/constructor/default_factory3_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Check possibly still unresolved upper bounds of default factory class.
+
+abstract class A<T extends Foo> {
+  factory A() = _AImpl<T>;
+}
+
+class Moo extends Foo {}
+
+class Foo extends Bar {}
+
+class Bar {}
+
+class _AImpl<T extends Foo> implements A<T> {
+  factory _AImpl() { return _AImpl._(); }
+
+  _AImpl._();
+}
+
+main() {
+  var result = new A<Moo>();
+}
diff --git a/tests/language/constructor/default_factory_library.dart b/tests/language/constructor/default_factory_library.dart
new file mode 100644
index 0000000..a7cd293
--- /dev/null
+++ b/tests/language/constructor/default_factory_library.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program for testing default factories defined across libraries
+
+library lib;
+
+import "default_factory_library_test.dart" as test;
+
+// References a factory class in another library
+abstract class A {
+  factory A() = test.C.A;
+  int methodA();
+}
diff --git a/tests/language/constructor/default_factory_library_test.dart b/tests/language/constructor/default_factory_library_test.dart
new file mode 100644
index 0000000..d141456
--- /dev/null
+++ b/tests/language/constructor/default_factory_library_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program for testing factories defined across libraries
+
+library test;
+
+import "package:expect/expect.dart";
+import "default_factory_library.dart" as lib;
+
+class B implements lib.A, C {
+  int methodA() {
+    return 1;
+  }
+
+  int methodB() {
+    return 2;
+  }
+}
+
+abstract class C implements lib.A {
+  // Referenced from an abstract class in another library
+  factory C.A() {
+    return new B();
+  }
+}
+
+main() {
+  dynamic val = new lib.A();
+  Expect.equals(true, (val is B));
+  Expect.equals(1, val.methodA());
+  Expect.equals(2, val.methodB());
+}
diff --git a/tests/language/constructor/default_factory_runtime_test.dart b/tests/language/constructor/default_factory_runtime_test.dart
new file mode 100644
index 0000000..a12c7e5
--- /dev/null
+++ b/tests/language/constructor/default_factory_runtime_test.dart
@@ -0,0 +1,38 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program for testing default factories.
+
+abstract class Vehicle {
+
+}
+
+class Bike implements Vehicle, GoogleOne {
+  Bike.redOne() {}
+}
+
+abstract class SpaceShip {
+  factory SpaceShip() = GoogleOne;
+}
+
+class GoogleOne implements SpaceShip {
+  GoogleOne.internal_() {}
+  factory GoogleOne() {
+    return new GoogleOne.internal_();
+  }
+  factory GoogleOne.Vehicle() {
+    return new Bike.redOne();
+  }
+}
+
+main() {
+  Expect.equals(true, (new Bike.redOne()) is Bike);
+  Expect.equals(true, (new SpaceShip()) is GoogleOne);
+
+}
diff --git a/tests/language/constructor/default_factory_test.dart b/tests/language/constructor/default_factory_test.dart
new file mode 100644
index 0000000..43a93e8
--- /dev/null
+++ b/tests/language/constructor/default_factory_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program for testing default factories.
+
+abstract class Vehicle {
+  factory Vehicle() = GoogleOne.Vehicle;
+  //                  ^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.REDIRECT_TO_INVALID_RETURN_TYPE
+  // [cfe] The constructor function type 'GoogleOne Function()' isn't a subtype of 'Vehicle Function()'.
+}
+
+class Bike implements Vehicle, GoogleOne {
+  Bike.redOne() {}
+}
+
+abstract class SpaceShip {
+  factory SpaceShip() = GoogleOne;
+}
+
+class GoogleOne implements SpaceShip {
+  GoogleOne.internal_() {}
+  factory GoogleOne() {
+    return new GoogleOne.internal_();
+  }
+  factory GoogleOne.Vehicle() {
+    return new Bike.redOne();
+  }
+}
+
+main() {
+  Expect.equals(true, (new Bike.redOne()) is Bike);
+  Expect.equals(true, (new SpaceShip()) is GoogleOne);
+  var ensureItsCalled = new Vehicle();
+}
diff --git a/tests/language/constructor/default_test.dart b/tests/language/constructor/default_test.dart
new file mode 100644
index 0000000..aae9c52
--- /dev/null
+++ b/tests/language/constructor/default_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for default constructors.
+
+import "package:expect/expect.dart";
+
+class A {
+  A() : a = 499;
+
+  var a;
+}
+
+class B extends A {
+  B() {
+    Expect.equals(499, a);
+  }
+}
+
+main() {
+  new B();
+}
diff --git a/tests/language/constructor/duplicate_final_test.dart b/tests/language/constructor/duplicate_final_test.dart
new file mode 100644
index 0000000..96c1d22
--- /dev/null
+++ b/tests/language/constructor/duplicate_final_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that duplicate initialization of a final field is a runtime error.
+
+class Class {
+  final f = 10;
+
+  Class(v) : f = v; //# 01: compile-time error
+
+  Class(this.f); //# 02: compile-time error
+
+  // If a field is initialized multiple times in the initializer
+  // list, it's a compile time error.
+  Class(this.f) : f = 0; //# 03: compile-time error
+}
+
+main() {
+  new Class(5); //# 01: continued
+  new Class(5); //# 02: continued
+  new Class(5); //# 03: continued
+}
diff --git a/tests/language/constructor/duplicate_initializers_runtime_test.dart b/tests/language/constructor/duplicate_initializers_runtime_test.dart
new file mode 100644
index 0000000..94a3466
--- /dev/null
+++ b/tests/language/constructor/duplicate_initializers_runtime_test.dart
@@ -0,0 +1,32 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that initializers are not duplicated
+
+ class Class {
+   Class(var v) : field_ = v
+   // Test against duplicate final field initialization in initializing list.
+
+   ;
+   Class.field(this.field_)
+   // Test against duplicate final field initialization between initializing
+   // formals and initializer list.
+
+   ;
+   // Test against duplicate final field initialization in initializing formals.
+   Class.two_fields(this.field_
+
+       );
+   final field_;
+ }
+
+ main() {
+   new Class(42);
+   new Class.field(42);
+   new Class.two_fields(42
+
+       );
+ }
diff --git a/tests/language/constructor/duplicate_initializers_test.dart b/tests/language/constructor/duplicate_initializers_test.dart
new file mode 100644
index 0000000..1b4125a
--- /dev/null
+++ b/tests/language/constructor/duplicate_initializers_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that initializers are not duplicated
+
+ class Class {
+   Class(var v) : field_ = v
+   // Test against duplicate final field initialization in initializing list.
+    , field_ = 2
+    //^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS
+    //       ^
+    // [cfe] 'field_' is a final instance variable that has already been initialized.
+   ;
+   Class.field(this.field_)
+   // Test against duplicate final field initialization between initializing
+   // formals and initializer list.
+    : field_ = 2
+    //^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER
+    //       ^
+    // [cfe] 'field_' is a final instance variable that has already been initialized.
+   ;
+   // Test against duplicate final field initialization in initializing formals.
+   Class.two_fields(this.field_
+    , this.field_
+    //     ^^^^^^
+    // [cfe] 'field_' is a final instance variable that has already been initialized.
+    //     ^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.FINAL_INITIALIZED_MULTIPLE_TIMES
+    // [cfe] Duplicated parameter name 'field_'.
+       );
+   final field_;
+ }
+
+ main() {
+   new Class(42);
+   new Class.field(42);
+   new Class.two_fields(42
+     , 42
+       );
+ }
diff --git a/tests/language/constructor/duplicate_runtime_test.dart b/tests/language/constructor/duplicate_runtime_test.dart
new file mode 100644
index 0000000..c65bc41
--- /dev/null
+++ b/tests/language/constructor/duplicate_runtime_test.dart
@@ -0,0 +1,15 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+  Foo();
+
+}
+
+main() {
+  new Foo();
+}
diff --git a/tests/language/constructor/duplicate_test.dart b/tests/language/constructor/duplicate_test.dart
new file mode 100644
index 0000000..80f717e
--- /dev/null
+++ b/tests/language/constructor/duplicate_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+  Foo();
+  Foo();
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR
+// [cfe] 'Foo' is already declared in this scope.
+}
+
+main() {
+  new Foo();
+  //  ^
+  // [cfe] Can't use 'Foo' because it is declared more than once.
+}
diff --git a/tests/language/constructor/evaluation_redirecting_constructor_test.dart b/tests/language/constructor/evaluation_redirecting_constructor_test.dart
new file mode 100644
index 0000000..6236c0a
--- /dev/null
+++ b/tests/language/constructor/evaluation_redirecting_constructor_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+int counter = 0;
+
+class Bar {
+  Bar() {
+    counter++;
+  }
+}
+
+class A {
+  var _bar = new Bar();
+  A() : this._();
+  A._() {
+    () => 42;
+  }
+}
+
+main() {
+  new A();
+  Expect.equals(1, counter);
+}
diff --git a/tests/language/constructor/example_constructor_test.dart b/tests/language/constructor/example_constructor_test.dart
new file mode 100644
index 0000000..f015b07
--- /dev/null
+++ b/tests/language/constructor/example_constructor_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for testing order of constructor invocation.
+
+import "package:expect/expect.dart";
+
+var trace = "";
+
+int rec(int i) {
+  trace += "$i ";
+  return i;
+}
+
+class A {
+  A(int x) : x = rec(4) {
+    Expect.equals(3, x); // Parameter x
+    Expect.equals(4, this.x);
+    rec(5);
+  }
+  final int x;
+}
+
+class B extends A {
+  B(this.a, int y, int z)
+      : z = rec(1),
+        y = rec(2),
+        super(rec(3)) {
+    rec(6);
+  }
+  int a;
+  int y;
+  int z;
+}
+
+main() {
+  var test = new B(rec(0), 0, 0);
+  Expect.equals(0, test.a);
+  Expect.equals(4, test.x);
+  Expect.equals(2, test.y);
+  Expect.equals(1, test.z);
+  Expect.equals("0 1 2 3 4 5 6 ", trace);
+}
diff --git a/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart b/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart
new file mode 100644
index 0000000..70738fe
--- /dev/null
+++ b/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js bug 18257: Properly infer types for forwarding
+// factory constructors with optional parameters with default values.
+
+main() {
+  A a = new A.a1();
+  a.test();
+}
+
+class A {
+  final bool condition;
+
+  A({this.condition: true});
+
+  factory A.a1({condition}) = _A1.boo;
+
+  test() {
+    if (condition != true) {
+      throw "FAILED";
+    }
+  }
+}
+
+class _A1 extends A {
+  _A1.boo({condition: true}) : super(condition: condition);
+}
diff --git a/tests/language/constructor/implicit_super_constructor_call_test.dart b/tests/language/constructor/implicit_super_constructor_call_test.dart
new file mode 100644
index 0000000..fca1a62
--- /dev/null
+++ b/tests/language/constructor/implicit_super_constructor_call_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// This is a regression test for http://dartbug.com/22723.
+
+import "package:expect/expect.dart";
+
+class A {
+  final x;
+
+  @pragma('dart2js:noInline')
+  A({this.x: "foo"}) {
+    Expect.equals("foo", x.toString());
+  }
+}
+
+class C extends A {
+  C(foobar) {}
+}
+
+main() {
+  var c = new C(499);
+  Expect.equals("foo", c.x.toString());
+}
diff --git a/tests/language/constructor/implicit_super_constructor_test.dart b/tests/language/constructor/implicit_super_constructor_test.dart
new file mode 100644
index 0000000..2c31206
--- /dev/null
+++ b/tests/language/constructor/implicit_super_constructor_test.dart
@@ -0,0 +1,20 @@
+// 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:expect/expect.dart";
+
+abstract class A {
+  int _x = 42;
+}
+
+abstract class B extends A {}
+
+class C extends B {
+  C() {}
+}
+
+main() {
+  // Regression test for https://github.com/dart-lang/sdk/issues/27421
+  Expect.equals(new C()._x, 42);
+}
diff --git a/tests/language/constructor/inference_super_constructor_call_test.dart b/tests/language/constructor/inference_super_constructor_call_test.dart
new file mode 100644
index 0000000..a95c185
--- /dev/null
+++ b/tests/language/constructor/inference_super_constructor_call_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js's inferrer that used to not propagate
+// types given to generative constructors in super constructor calls.
+
+import "package:expect/expect.dart";
+
+class A {
+  final field;
+  A.full(this.field);
+}
+
+class B extends A {
+  // The following super call used to not be analyzed properly.
+  B.full(field) : super.full(field);
+}
+
+main() {
+  // Call [A.full] with an int to have the inferrer think [field] is
+  // always an int.
+  Expect.equals(84, new A.full(42).field + 42);
+  Expect.throwsNoSuchMethodError(() => new B.full(null).field + 42,);
+}
diff --git a/tests/language/constructor/initializer_test.dart b/tests/language/constructor/initializer_test.dart
new file mode 100644
index 0000000..4204885
--- /dev/null
+++ b/tests/language/constructor/initializer_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  var _x, _y;
+  A(x, [y = 10])
+      : _x = x++,
+        _y = y++ {
+    // Check that value of modified constructor parameters
+    // is remembered in the constructor body.
+    Expect.equals(x, _x + 1);
+    Expect.equals(y, _y + 1);
+  }
+}
+
+class B extends A {
+  var _a, _b;
+  // The super call in the middle of the initializer list conceptually
+  // forces two super call chains, one for initializer list and a second
+  // one for the constructor bodies.
+  B(a, b)
+      : _a = a++,
+        _b = b++,
+        super(a + b++) {
+    Expect.equals(a, _a + 1);
+    Expect.equals(b, _b + 2);
+    Expect.equals(a + (b - 2), _x - 1);
+  }
+}
+
+main() {
+  dynamic o = new B(3, 5);
+  Expect.equals(3, o._a);
+  Expect.equals(5, o._b);
+  Expect.equals(10, o._x);
+  Expect.equals(10, o._y);
+  o = new A(3);
+  Expect.equals(3, o._x);
+  Expect.equals(10, o._y);
+}
diff --git a/tests/language/constructor/missing_const_constructor_test.dart b/tests/language/constructor/missing_const_constructor_test.dart
new file mode 100644
index 0000000..123eccf
--- /dev/null
+++ b/tests/language/constructor/missing_const_constructor_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test handling of unknown constructor in const expression.
+
+class GoodClass {
+  const GoodClass();
+}
+
+GoodClass? GOOD_CLASS
+    = const GoodClass() //# 01: ok
+    = const GoodClass.BAD_NAME() //# 02: compile-time error
+    = const GoodClass("bad arg") //# 03: compile-time error
+    ;
+
+const BadClass BAD_CLASS = const BadClass(); //# 04: compile-time error
+BadClass BAD_CLASS = const BadClass(); //# 05: compile-time error
+
+void main() {
+  try {
+    print(GOOD_CLASS);
+    print(BAD_CLASS); //# 04: continued
+    print(BAD_CLASS); //# 05: continued
+    print(const BadClass()); //# 06: compile-time error
+  } catch (e) {}
+}
diff --git a/tests/language/constructor/multiple_field_assignment_constructor_test.dart b/tests/language/constructor/multiple_field_assignment_constructor_test.dart
new file mode 100644
index 0000000..7292e80
--- /dev/null
+++ b/tests/language/constructor/multiple_field_assignment_constructor_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "../compiler_annotations.dart";
+
+var a = [null];
+
+class A {
+  var foo;
+  var bar;
+
+  @DontInline()
+  A() {
+    // Currently defeat inlining by using a closure.
+    bar = () => 42;
+    foo = 42;
+    foo = a[0];
+  }
+}
+
+class B {
+  var foo;
+  var bar;
+
+  @DontInline()
+  B() {
+    // Currently defeat inlining by using a closure.
+    bar = () => 42;
+    foo = 42;
+    foo = a[0];
+    if (false) foo = 42;
+  }
+}
+
+main() {
+  // Surround the call to [bar] by allocations of [A] and [B] to
+  // ensure their constructors get analyzed first.
+  new A();
+  new B();
+  bar();
+  new A();
+  new B();
+}
+
+@DontInline()
+bar() {
+  // Currently defeat inlining by using a closure.
+  Expect.throwsNoSuchMethodError(() => new A().foo + 42);
+  Expect.throwsNoSuchMethodError(() => new B().foo + 42);
+}
diff --git a/tests/language/constructor/name_clash_lib.dart b/tests/language/constructor/name_clash_lib.dart
new file mode 100644
index 0000000..ff52f3b
--- /dev/null
+++ b/tests/language/constructor/name_clash_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+var global = 0;
+
+class A {
+  A() {
+    global += 10;
+    try {} catch (e) {} // no inline
+  }
+}
diff --git a/tests/language/constructor/name_clash_test.dart b/tests/language/constructor/name_clash_test.dart
new file mode 100644
index 0000000..e7681ef
--- /dev/null
+++ b/tests/language/constructor/name_clash_test.dart
@@ -0,0 +1,18 @@
+// 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:expect/expect.dart';
+import 'name_clash_lib.dart' as lib;
+
+class A extends lib.A {
+  A() {
+    lib.global += 100;
+    try {} catch (e) {} // no inline
+  }
+}
+
+main() {
+  new A();
+  Expect.equals(110, lib.global);
+}
diff --git a/tests/language/constructor/name_test.dart b/tests/language/constructor/name_test.dart
new file mode 100644
index 0000000..43e764f
--- /dev/null
+++ b/tests/language/constructor/name_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+  Bar.Foo(); //# 01: compile-time error
+  factory Bar(); //# 02: syntax error
+  factory Bar.Baz(); //# 03: syntax error
+}
+
+void main() {
+  new Foo();
+  new Foo.Foo(); //# 01: continued
+  new Foo.Baz(); //# 03: continued
+}
diff --git a/tests/language/constructor/named_arguments_test.dart b/tests/language/constructor/named_arguments_test.dart
new file mode 100644
index 0000000..854ae04
--- /dev/null
+++ b/tests/language/constructor/named_arguments_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for default constructors.
+
+import "package:expect/expect.dart";
+
+late String message;
+
+foo() {
+  message += 'foo';
+  return 1;
+}
+
+bar() {
+  message += 'bar';
+  return 2;
+}
+
+class X {
+  var i;
+  var j;
+  X({a: 'defa', b: 'defb'})
+      : this.i = a,
+        this.j = b;
+  X.foo() : this(b: 1, a: 2);
+  X.bar()
+      : this(
+                     1, // //# 01: compile-time error, runtime error
+            a: 2);
+  X.baz() : this(a: 1, b: 2);
+  X.qux() : this(b: 2);
+  X.hest() : this();
+  X.fisk() : this(b: bar(), a: foo());
+  X.naebdyr() : this(a: foo(), b: bar());
+}
+
+test(x, a, b) {
+  Expect.equals(x.i, a);
+  Expect.equals(x.j, b);
+}
+
+main() {
+  test(new X.foo(), 2, 1);
+  test(new X.bar(), 2, 'defb');
+  test(new X.baz(), 1, 2);
+  test(new X.qux(), 'defa', 2);
+  test(new X.hest(), 'defa', 'defb');
+
+  message = '';
+  new X.fisk();
+  Expect.equals('barfoo', message);
+
+  message = '';
+  new X.naebdyr();
+  Expect.equals('foobar', message);
+}
diff --git a/tests/language/constructor/named_constructor_test.dart b/tests/language/constructor/named_constructor_test.dart
new file mode 100644
index 0000000..915f147
--- /dev/null
+++ b/tests/language/constructor/named_constructor_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library named_constructor_test;
+
+import 'package:expect/expect.dart';
+import 'named_lib.dart' as prefix;
+
+class Class<T> {
+  final int value;
+  Class() : value = 0;
+  Class.named() : value = 1;
+}
+
+void main() {
+  Expect.equals(0, new Class().value);
+  Expect.equals(0, new Class<int>().value);
+
+  Expect.equals(1, new Class.named().value);
+  Expect.equals(1, new Class<int>.named().value);
+  // 'Class.named' is not a type:
+  new Class.named<int>().value;
+  //        ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //             ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+
+  // 'Class<int>.named<int>' doesn't fit the grammar syntax T.id:
+  new Class<int>.named<int>().value;
+  //             ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+
+  new prefix.Class().value;
+  // 'prefix' is not a type:
+  new prefix<int>.Class().value;
+  //  ^^^^^^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'prefix.Class'.
+  new prefix.Class<int>().value;
+  // 'prefix<int>.Class<int>' doesn't fit the grammar syntax T.id:
+  new prefix<int>.Class<int>().value;
+  //  ^^^^^^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'prefix.Class'.
+  //              ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+
+  new prefix.Class.named().value;
+  // 'prefix<int>.Class.named' doesn't fit the grammar syntax T.id:
+  new prefix<int>.Class.named().value;
+  //  ^^^^^^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'prefix.Class'.
+  //              ^^^^^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected '(' after this.
+
+
+  // 'prefix.Class<int>.named' doesn't fit the grammar syntax T.id:
+  new prefix.Class<int>.named().value;
+  // 'prefix.Class.named<int>' doesn't fit the grammar syntax T.id:
+  new prefix.Class.named<int>().value;
+  //               ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+
+  // 'prefix<int>.Class<int>' doesn't fit the grammar syntax T.id:
+  new prefix<int>.Class<int>.named().value;
+  //  ^^^^^^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'prefix.Class'.
+  //              ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+
+
+  // 'prefix<int>.Class.named<int>' doesn't fit the grammar syntax T.id:
+  new prefix<int>.Class.named<int>().value;
+  //  ^^^^^^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'prefix.Class'.
+  //              ^^^^^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected '(' after this.
+
+
+  // 'prefix.Class<int>.named<int>' doesn't fit the grammar syntax T.id:
+  new prefix.Class<int>.named<int>().value;
+  //                    ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+
+  // 'prefix<int>.Class<int>.named<int>' doesn't fit the grammar syntax T.id:
+  new prefix<int>.Class<int>.named<int>().value;
+  //  ^^^^^^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'prefix.Class'.
+  //              ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+}
diff --git a/tests/language/constructor/named_lib.dart b/tests/language/constructor/named_lib.dart
new file mode 100644
index 0000000..210d54c
--- /dev/null
+++ b/tests/language/constructor/named_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library named_constructor_lib;
+
+class Class<T> {
+  final int value;
+  Class() : value = 2;
+  Class.named() : value = 3;
+}
diff --git a/tests/language/constructor/named_runtime_test.dart b/tests/language/constructor/named_runtime_test.dart
new file mode 100644
index 0000000..815b05b
--- /dev/null
+++ b/tests/language/constructor/named_runtime_test.dart
@@ -0,0 +1,52 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library named_constructor_test;
+
+import 'package:expect/expect.dart';
+import 'named_lib.dart' as prefix;
+
+class Class<T> {
+  final int value;
+  Class() : value = 0;
+  Class.named() : value = 1;
+}
+
+void main() {
+  Expect.equals(0, new Class().value);
+  Expect.equals(0, new Class<int>().value);
+
+  Expect.equals(1, new Class.named().value);
+  Expect.equals(1, new Class<int>.named().value);
+  // 'Class.named' is not a type:
+
+  // 'Class<int>.named<int>' doesn't fit the grammar syntax T.id:
+
+
+  new prefix.Class().value;
+  // 'prefix' is not a type:
+
+  new prefix.Class<int>().value;
+  // 'prefix<int>.Class<int>' doesn't fit the grammar syntax T.id:
+
+
+  new prefix.Class.named().value;
+  // 'prefix<int>.Class.named' doesn't fit the grammar syntax T.id:
+
+  // 'prefix.Class<int>.named' doesn't fit the grammar syntax T.id:
+  new prefix.Class<int>.named().value;
+  // 'prefix.Class.named<int>' doesn't fit the grammar syntax T.id:
+
+  // 'prefix<int>.Class<int>' doesn't fit the grammar syntax T.id:
+
+  // 'prefix<int>.Class.named<int>' doesn't fit the grammar syntax T.id:
+
+  // 'prefix.Class<int>.named<int>' doesn't fit the grammar syntax T.id:
+
+  // 'prefix<int>.Class<int>.named<int>' doesn't fit the grammar syntax T.id:
+
+}
diff --git a/tests/language/constructor/no_such_constructor_runtime_test.dart b/tests/language/constructor/no_such_constructor_runtime_test.dart
new file mode 100644
index 0000000..17ee996
--- /dev/null
+++ b/tests/language/constructor/no_such_constructor_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  A();
+}
+
+main() {
+
+}
diff --git a/tests/language/constructor/no_such_constructor_test.dart b/tests/language/constructor/no_such_constructor_test.dart
new file mode 100644
index 0000000..b106273
--- /dev/null
+++ b/tests/language/constructor/no_such_constructor_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  A();
+}
+
+main() {
+  new A(42);
+  //   ^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+  // [cfe] Too many positional arguments: 0 allowed, but 1 found.
+}
diff --git a/tests/language/constructor/non_const_constructor_without_body_test.dart b/tests/language/constructor/non_const_constructor_without_body_test.dart
new file mode 100644
index 0000000..cd2005a
--- /dev/null
+++ b/tests/language/constructor/non_const_constructor_without_body_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class NonConstConstructorWithoutBodyTest {
+  int x = -1;
+
+  NonConstConstructorWithoutBodyTest();
+  NonConstConstructorWithoutBodyTest.named();
+  NonConstConstructorWithoutBodyTest.initializers() : x = 1;
+  NonConstConstructorWithoutBodyTest.parameters(int x) : x = x + 1;
+  NonConstConstructorWithoutBodyTest.fieldParameter(int this.x);
+  NonConstConstructorWithoutBodyTest.redirection() : this.initializers();
+
+  static testMain() {
+    Expect.equals(-1, new NonConstConstructorWithoutBodyTest().x);
+    Expect.equals(-1, new NonConstConstructorWithoutBodyTest.named().x);
+    Expect.equals(1, new NonConstConstructorWithoutBodyTest.initializers().x);
+    Expect.equals(2, new NonConstConstructorWithoutBodyTest.parameters(1).x);
+    Expect.equals(
+        2, new NonConstConstructorWithoutBodyTest.fieldParameter(2).x);
+    Expect.equals(1, new NonConstConstructorWithoutBodyTest.redirection().x);
+  }
+}
+
+main() {
+  NonConstConstructorWithoutBodyTest.testMain();
+}
diff --git a/tests/language/constructor/non_parameterized_factory2_test.dart b/tests/language/constructor/non_parameterized_factory2_test.dart
new file mode 100644
index 0000000..2833d06
--- /dev/null
+++ b/tests/language/constructor/non_parameterized_factory2_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+abstract class Interface<T> {
+  factory Interface() = Factory<T>;
+  factory Interface.withArg(T value) = Factory<T>.withArg;
+}
+
+class Factory<T> implements Interface<T> {
+  factory Factory() {
+    return Factory._();
+  }
+
+  factory Factory.withArg(T value) {
+    return Factory._();
+  }
+
+  Factory._();
+}
+
+main() {
+  new Interface<int>();
+  new Interface<int>.withArg(4);
+}
diff --git a/tests/language/constructor/non_parameterized_factory_test.dart b/tests/language/constructor/non_parameterized_factory_test.dart
new file mode 100644
index 0000000..36cd6aa
--- /dev/null
+++ b/tests/language/constructor/non_parameterized_factory_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+abstract class Interface<T> {
+  factory Interface() = Factory<T>;
+  factory Interface.withArg(T value) = Factory<T>.withArg;
+}
+
+class Factory<T> implements Interface<T> {
+  factory Factory() {
+    return Factory._();
+  }
+
+  factory Factory.withArg(T value) {
+    return Factory._();
+  }
+
+  Factory._();
+}
+
+main() {
+  new Interface();
+  new Interface.withArg(4);
+}
diff --git a/tests/language/constructor/redirect2_runtime_test.dart b/tests/language/constructor/redirect2_runtime_test.dart
new file mode 100644
index 0000000..f5216f6
--- /dev/null
+++ b/tests/language/constructor/redirect2_runtime_test.dart
@@ -0,0 +1,32 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Redirection constructors must not have a function body.
+
+class A {
+  var x;
+  A(this.x) {}
+
+  // Redirecting constructor must not have a function body.
+
+
+  // Redirecting constructor must not initialize any fields.
+
+
+  // Redirecting constructor must not have initializing formal parameters.
+
+
+  // Redirection constructors must not call super constructor.
+
+}
+
+main() {
+  new A(3);
+
+
+
+
+}
diff --git a/tests/language/constructor/redirect2_test.dart b/tests/language/constructor/redirect2_test.dart
new file mode 100644
index 0000000..0999747
--- /dev/null
+++ b/tests/language/constructor/redirect2_test.dart
@@ -0,0 +1,46 @@
+// 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.
+// Redirection constructors must not have a function body.
+
+class A {
+  var x;
+  A(this.x) {}
+
+  // Redirecting constructor must not have a function body.
+  A.illegalBody(x) : this(3) {}
+  //                         ^
+  // [analyzer] SYNTACTIC_ERROR.REDIRECTING_CONSTRUCTOR_WITH_BODY
+  // [cfe] Redirecting constructors can't have a body.
+
+  // Redirecting constructor must not initialize any fields.
+  A.illegalInit() : this(3), x = 5;
+  //                         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
+  //                           ^
+  // [cfe] Can't have other initializers together with 'this'.
+
+  // Redirecting constructor must not have initializing formal parameters.
+  A.illegalFormal(this.x) : this(3);
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
+  //                   ^
+  // [cfe] Can't have other initializers together with 'this'.
+
+  // Redirection constructors must not call super constructor.
+  A.illegalSuper() : this(3), super(3);
+  //                          ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.SUPER_IN_REDIRECTING_CONSTRUCTOR
+  // [cfe] Can't have other initializers together with 'this'.
+  //                               ^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+  // [cfe] Too many positional arguments: 0 allowed, but 1 found.
+}
+
+main() {
+  new A(3);
+  new A.illegalBody(10);
+  new A.illegalInit();
+  new A.illegalFormal(10);
+  new A.illegalSuper();
+}
diff --git a/tests/language/constructor/redirect_cycle_runtime_test.dart b/tests/language/constructor/redirect_cycle_runtime_test.dart
new file mode 100644
index 0000000..4a05857
--- /dev/null
+++ b/tests/language/constructor/redirect_cycle_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Redirection constructors must not be cyclic.
+
+class A {
+  var x;
+  A(x)
+
+      ;
+}
+
+main() {
+  new A(10);
+}
diff --git a/tests/language/constructor/redirect_cycle_test.dart b/tests/language/constructor/redirect_cycle_test.dart
new file mode 100644
index 0000000..6730e06
--- /dev/null
+++ b/tests/language/constructor/redirect_cycle_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Redirection constructors must not be cyclic.
+
+class A {
+  var x;
+  A(x)
+      : this(0)
+      //^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_CONSTRUCTOR_REDIRECT
+      // [cfe] Redirecting constructors can't be cyclic.
+      ;
+}
+
+main() {
+  new A(10);
+}
diff --git a/tests/language/constructor/redirect_indirect_cycle_runtime_test.dart b/tests/language/constructor/redirect_indirect_cycle_runtime_test.dart
new file mode 100644
index 0000000..94159a5
--- /dev/null
+++ b/tests/language/constructor/redirect_indirect_cycle_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  var x;
+  A(x) : this.named(x, 0);
+  A.named(x, int y)
+      // Redirecting constructors must not be cyclic.
+
+      ;
+}
+
+main() {
+  new A(10);
+}
diff --git a/tests/language/constructor/redirect_indirect_cycle_test.dart b/tests/language/constructor/redirect_indirect_cycle_test.dart
new file mode 100644
index 0000000..aa2bb69
--- /dev/null
+++ b/tests/language/constructor/redirect_indirect_cycle_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  var x;
+  A(x) : this.named(x, 0);
+  //     ^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_CONSTRUCTOR_REDIRECT
+  A.named(x, int y)
+      // Redirecting constructors must not be cyclic.
+      : this(x + y)
+      //^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_CONSTRUCTOR_REDIRECT
+      // [cfe] Redirecting constructors can't be cyclic.
+      ;
+}
+
+main() {
+  new A(10);
+}
diff --git a/tests/language/constructor/redirect_runtime_test.dart b/tests/language/constructor/redirect_runtime_test.dart
new file mode 100644
index 0000000..f6084b8
--- /dev/null
+++ b/tests/language/constructor/redirect_runtime_test.dart
@@ -0,0 +1,75 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for redirection constructors.
+
+import "package:expect/expect.dart";
+
+class A {
+  var x;
+  A(this.x) {}
+  A.named(x, int y) : this(x + y);
+  A.named2(int x, int y, z) : this.named(staticFun(x, y), z);
+
+  // The following is a bit tricky. It is a compile-time error to
+  // refer to this (implicitly or explicitly) from an initializer.
+  // When we remove the line with moreStaticFun, staticFun is really a
+  // static function and it is legal to call it. This is what will
+  // happen in the /none version of this test. However, in /01,
+  // staticFun isn't really a static function and should cause a
+  // compile-time error.
+  static
+
+      int staticFun(int v1, int v2) {
+    return v1 * v2;
+  }
+}
+
+class B extends A {
+  B(y) : super(y + 1) {}
+  B.named(y) : super.named(y, y + 1) {}
+}
+
+class C {
+  final x;
+  const C(this.x);
+  const C.named(x, int y) : this(x + y);
+}
+
+class D extends C {
+  const D(y) : super(y + 1);
+  const D.named(y) : super.named(y, y + 1);
+}
+
+class ConstructorRedirectTest {
+  static testMain() {
+    var a = new A(499);
+    Expect.equals(499, a.x);
+    a = new A.named(349, 499);
+    Expect.equals(349 + 499, a.x);
+    a = new A.named2(11, 42, 99);
+    Expect.equals(11 * 42 + 99, a.x);
+
+    var b = new B(498);
+    Expect.equals(499, b.x);
+    b = new B.named(249);
+    Expect.equals(499, b.x);
+
+    C c = const C(499);
+    Expect.equals(499, c.x);
+    c = const C.named(249, 250);
+    Expect.equals(499, c.x);
+
+    D d = const D(498);
+    Expect.equals(499, d.x);
+    d = const D.named(249);
+    Expect.equals(499, d.x);
+  }
+}
+
+main() {
+  ConstructorRedirectTest.testMain();
+}
diff --git a/tests/language/constructor/redirect_test.dart b/tests/language/constructor/redirect_test.dart
new file mode 100644
index 0000000..0f1ee3a
--- /dev/null
+++ b/tests/language/constructor/redirect_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for redirection constructors.
+
+import "package:expect/expect.dart";
+
+class A {
+  var x;
+  A(this.x) {}
+  A.named(x, int y) : this(x + y);
+  A.named2(int x, int y, z) : this.named(staticFun(x, y), z);
+  //                                     ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
+  // [cfe] Can't access 'this' in a field initializer to read 'staticFun'.
+
+  // The following is a bit tricky. It is a compile-time error to
+  // refer to this (implicitly or explicitly) from an initializer.
+  // When we remove the line with moreStaticFun, staticFun is really a
+  // static function and it is legal to call it. This is what will
+  // happen in the /none version of this test. However, in /01,
+  // staticFun isn't really a static function and should cause a
+  // compile-time error.
+  static
+  moreStaticFun() {}
+      int staticFun(int v1, int v2) {
+    return v1 * v2;
+  }
+}
+
+class B extends A {
+  B(y) : super(y + 1) {}
+  B.named(y) : super.named(y, y + 1) {}
+}
+
+class C {
+  final x;
+  const C(this.x);
+  const C.named(x, int y) : this(x + y);
+}
+
+class D extends C {
+  const D(y) : super(y + 1);
+  const D.named(y) : super.named(y, y + 1);
+}
+
+class ConstructorRedirectTest {
+  static testMain() {
+    var a = new A(499);
+    Expect.equals(499, a.x);
+    a = new A.named(349, 499);
+    Expect.equals(349 + 499, a.x);
+    a = new A.named2(11, 42, 99);
+    Expect.equals(11 * 42 + 99, a.x);
+
+    var b = new B(498);
+    Expect.equals(499, b.x);
+    b = new B.named(249);
+    Expect.equals(499, b.x);
+
+    C c = const C(499);
+    Expect.equals(499, c.x);
+    c = const C.named(249, 250);
+    Expect.equals(499, c.x);
+
+    D d = const D(498);
+    Expect.equals(499, d.x);
+    d = const D.named(249);
+    Expect.equals(499, d.x);
+  }
+}
+
+main() {
+  ConstructorRedirectTest.testMain();
+}
diff --git a/tests/language/constructor/reference_runtime_10_test.dart b/tests/language/constructor/reference_runtime_10_test.dart
new file mode 100644
index 0000000..b96d8f9
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_10_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  Foo.bar();
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_11_test.dart b/tests/language/constructor/reference_runtime_11_test.dart
new file mode 100644
index 0000000..cea554d
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_11_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  Foo<int>();
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_12_test.dart b/tests/language/constructor/reference_runtime_12_test.dart
new file mode 100644
index 0000000..5b58eae
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_12_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  Foo<int>.bar();
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_1_test.dart b/tests/language/constructor/reference_runtime_1_test.dart
new file mode 100644
index 0000000..450bc7f
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_1_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+  new Foo();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_2_test.dart b/tests/language/constructor/reference_runtime_2_test.dart
new file mode 100644
index 0000000..cab730f
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_2_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+  new Foo.bar();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_3_test.dart b/tests/language/constructor/reference_runtime_3_test.dart
new file mode 100644
index 0000000..20ac3d2
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_3_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+  new Foo<int>();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_4_test.dart b/tests/language/constructor/reference_runtime_4_test.dart
new file mode 100644
index 0000000..e69fe77
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_4_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+  new Foo<int>.bar();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_5_test.dart b/tests/language/constructor/reference_runtime_5_test.dart
new file mode 100644
index 0000000..4dda061
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_5_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+  const Foo();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_6_test.dart b/tests/language/constructor/reference_runtime_6_test.dart
new file mode 100644
index 0000000..75859e0
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_6_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+  const Foo.bar();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_7_test.dart b/tests/language/constructor/reference_runtime_7_test.dart
new file mode 100644
index 0000000..b18721e
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_7_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+  const Foo<int>();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_8_test.dart b/tests/language/constructor/reference_runtime_8_test.dart
new file mode 100644
index 0000000..1493e34
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_8_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  const Foo<int>.bar();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_9_test.dart b/tests/language/constructor/reference_runtime_9_test.dart
new file mode 100644
index 0000000..cad70b0
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_9_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  Foo();
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_runtime_test.dart b/tests/language/constructor/reference_runtime_test.dart
new file mode 100644
index 0000000..12b5314
--- /dev/null
+++ b/tests/language/constructor/reference_runtime_test.dart
@@ -0,0 +1,44 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/constructor/reference_test.dart b/tests/language/constructor/reference_test.dart
new file mode 100644
index 0000000..52e1235
--- /dev/null
+++ b/tests/language/constructor/reference_test.dart
@@ -0,0 +1,117 @@
+// 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.
+
+class Foo<X> {
+  const Foo();
+  const Foo.bar();
+  const Foo.baz();
+}
+
+main() {
+  new Foo();
+  new Foo.bar();
+  new Foo.bar.baz();
+  //  ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+  //          ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+  new Foo<int>();
+  new Foo<int>.bar();
+  new Foo<int>.bar.baz();
+  //           ^^^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected '(' after this.
+  //               ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_METHOD
+  // [cfe] The method 'baz' isn't defined for the class 'Foo<int>'.
+  new Foo.bar<int>();
+  //      ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //         ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  new Foo.bar<int>.baz();
+  //      ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //         ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  //               ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+  new Foo.bar.baz<int>();
+  //  ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+  //          ^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //          ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+
+  const Foo();
+  const Foo.bar();
+  const Foo.bar.baz();
+  //    ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+  //            ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+  const Foo<int>();
+  const Foo<int>.bar();
+  const Foo<int>.bar.baz();
+  //             ^^^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected '(' after this.
+  //                 ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_METHOD
+  // [cfe] The method 'baz' isn't defined for the class 'Foo<int>'.
+  const Foo.bar<int>();
+  //        ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //           ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  const Foo.bar<int>.baz();
+  //        ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //           ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  //                 ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+  const Foo.bar.baz<int>();
+  //    ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+  //            ^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //            ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+
+  Foo();
+  Foo.bar();
+  Foo.bar.baz();
+  //  ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] Getter not found: 'bar'.
+  Foo<int>();
+  Foo<int>.bar();
+  Foo<int>.bar.baz();
+  //       ^^^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected '(' after this.
+  //           ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_METHOD
+  // [cfe] The method 'baz' isn't defined for the class 'Foo<int>'.
+  Foo.bar<int>();
+  //  ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //     ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  Foo.bar<int>.baz();
+  //  ^
+  // [cfe] A constructor invocation can't have type arguments on the constructor name.
+  //     ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+  //           ^
+  // [cfe] Method not found: 'Foo.bar.baz'.
+  Foo.bar.baz<int>();
+  //  ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] Getter not found: 'bar'.
+}
diff --git a/tests/language/constructor/return_runtime_test.dart b/tests/language/constructor/return_runtime_test.dart
new file mode 100644
index 0000000..9c23cd9
--- /dev/null
+++ b/tests/language/constructor/return_runtime_test.dart
@@ -0,0 +1,47 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart spec 0.03, section 11.10 - generative constructors can only have return
+// statements in the form 'return;'.
+class A {
+  int x;
+  A(this.x) {
+    return;
+  }
+  A.test1(this.x) {
+
+  }
+  A.test2(this.x) {
+
+  }
+  int foo(int y) => x + y;
+}
+
+class B {
+
+}
+
+class C {
+  int value = -1;
+
+}
+
+class D {
+  int value = -1;
+
+}
+
+main() {
+  Expect.equals((new A(1)).foo(10), 11);
+  Expect.equals((new A.test1(1)).foo(10), 11);
+  Expect.equals((new A.test2(1)).foo(10), 11);
+  new B();
+  new C();
+  new D();
+}
diff --git a/tests/language/constructor/return_test.dart b/tests/language/constructor/return_test.dart
new file mode 100644
index 0000000..6a46892
--- /dev/null
+++ b/tests/language/constructor/return_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart spec 0.03, section 11.10 - generative constructors can only have return
+// statements in the form 'return;'.
+class A {
+  int x;
+  A(this.x) {
+    return;
+  }
+  A.test1(this.x) {
+    return this;
+//  ^
+// [cfe] Constructors can't have a return type.
+//         ^^^^
+// [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
+  }
+  A.test2(this.x) {
+    return null;
+//  ^
+// [cfe] Constructors can't have a return type.
+//         ^^^^
+// [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
+  }
+  int foo(int y) => x + y;
+}
+
+class B {
+  B() => B._();
+  //  ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
+  //     ^
+  // [cfe] Constructors can't have a return type.
+
+  B._();
+}
+
+class C {
+  int value;
+  C() : value = 1 { return null; }
+  //                ^
+  // [cfe] Constructors can't have a return type.
+  //                       ^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
+}
+
+class D {
+  int value = -1;
+  D(): value = 1 => D._();
+  //             ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
+  //                ^
+  // [cfe] Constructors can't have a return type.
+
+  D._();
+}
+
+main() {
+  Expect.equals((new A(1)).foo(10), 11);
+  Expect.equals((new A.test1(1)).foo(10), 11);
+  Expect.equals((new A.test2(1)).foo(10), 11);
+  new B();
+  new C();
+  new D();
+}
diff --git a/tests/language/constructor/setter_test.dart b/tests/language/constructor/setter_test.dart
new file mode 100644
index 0000000..bad56d3
--- /dev/null
+++ b/tests/language/constructor/setter_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test that setters are not invokable in the initializer list.
+
+class A {
+  A() : a = 499; /*@compile-error=unspecified*/
+
+  set a(val) {}
+}
+
+main() {
+  new A();
+}
diff --git a/tests/language/constructor/type_parameter_runtime_test.dart b/tests/language/constructor/type_parameter_runtime_test.dart
new file mode 100644
index 0000000..6cb2a75
--- /dev/null
+++ b/tests/language/constructor/type_parameter_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo {
+
+}
+
+main() {
+  new Foo();
+}
diff --git a/tests/language/constructor/type_parameter_test.dart b/tests/language/constructor/type_parameter_test.dart
new file mode 100644
index 0000000..3712c26
--- /dev/null
+++ b/tests/language/constructor/type_parameter_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+class Foo {
+  Foo<A>() {}
+  // ^^^
+  // [analyzer] SYNTACTIC_ERROR.TYPE_PARAMETER_ON_CONSTRUCTOR
+  // [cfe] Constructors can't have type parameters.
+}
+
+main() {
+  new Foo();
+}
diff --git a/tests/language/constructor/unresolved_default_constructor_test.dart b/tests/language/constructor/unresolved_default_constructor_test.dart
new file mode 100644
index 0000000..07fdc72
--- /dev/null
+++ b/tests/language/constructor/unresolved_default_constructor_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test unresolved default constructor calls cause compilation errors.
+
+import 'package:expect/expect.dart';
+
+class A {
+  A.named();
+  static method() {}
+}
+
+main() {
+  A.method();
+  Expect.throws(() => new A());
+  //                      ^
+  // [analyzer] STATIC_WARNING.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
+  // [cfe] Method not found: 'A'.
+}
diff --git a/tests/language/constructor/unresolved_default_runtime_test.dart b/tests/language/constructor/unresolved_default_runtime_test.dart
new file mode 100644
index 0000000..dd83067
--- /dev/null
+++ b/tests/language/constructor/unresolved_default_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test unresolved default constructor calls cause compilation errors.
+
+import 'package:expect/expect.dart';
+
+class A {
+  A.named();
+  static method() {}
+}
+
+main() {
+  A.method();
+
+}
diff --git a/tests/language/constructor/unresolved_in_factory_test.dart b/tests/language/constructor/unresolved_in_factory_test.dart
new file mode 100644
index 0000000..a9aa72a
--- /dev/null
+++ b/tests/language/constructor/unresolved_in_factory_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that an unresolved method call in a factory is a compile error.
+
+class A {
+  factory A() {
+    foo(); /*@compile-error=unspecified*/
+  }
+}
+
+main() {
+  new A();
+}
diff --git a/tests/language/constructor/with_mixin_test.dart b/tests/language/constructor/with_mixin_test.dart
new file mode 100644
index 0000000..5e4badc
--- /dev/null
+++ b/tests/language/constructor/with_mixin_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+// Test super constructor invocation with mixins.
+// Regression test for issue dartbug.com/22604
+
+import "package:expect/expect.dart";
+
+var a_count = 0;
+var b_count = 0;
+
+class A {
+  final int x;
+  A(int this.x) {
+    a_count++;
+  }
+}
+
+class I {}
+
+class B extends A with I {
+  int y;
+
+  B(int xx)
+      : y = 13,
+        super(xx) {
+    b_count++;
+  }
+}
+
+void main() {
+  var b = new B(17);
+  Expect.equals(1, a_count);
+  Expect.equals(1, b_count);
+}
diff --git a/tests/language/constructor/with_type_parameters_test.dart b/tests/language/constructor/with_type_parameters_test.dart
new file mode 100644
index 0000000..8df1733
--- /dev/null
+++ b/tests/language/constructor/with_type_parameters_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+class Bar<T> {
+  Bar() {} //# 01: ok
+  Bar.boo() {} //# 02: ok
+  Bar<E>() {} //# 03: compile-time error
+  Bar<E>.boo() {} //# 04: syntax error
+  Bar.boo<E>() {} //# 05: syntax error
+  Bar.boo<E>.baz() {} //# 06: syntax error
+
+  Bar(); //# 07: ok
+  Bar.boo(); //# 08: ok
+  Bar<E>(); //# 09: compile-time error
+  Bar<E>.boo(); //# 10: syntax error
+  Bar.boo<E>(); //# 11: syntax error
+  Bar.boo<E>.baz(); //# 12: syntax error
+
+  const Bar(); //# 13: ok
+  const Bar.boo(); //# 14: ok
+  const Bar<E>(); //# 15: syntax error
+  const Bar<E>.boo(); //# 16: syntax error
+  const Bar.boo<E>(); //# 17: syntax error
+  const Bar.boo<E>.baz(); //# 18: syntax error
+}
+
+main() {}
diff --git a/tests/language/control_flow_collections/await_for_downcast_test.dart b/tests/language/control_flow_collections/await_for_downcast_test.dart
new file mode 100644
index 0000000..be8aa65
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_downcast_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that downcasting elements in collection-await-for is a compile error.
+Stream<int> stream(List<int> values) => Stream.fromIterable(values);
+Stream<num> numStream(List<num> values) => Stream.fromIterable(values);
+
+void main() async {
+  await testList();
+  await testMap();
+  await testSet();
+}
+
+Future<void> testList() async {
+  // Downcast stream.
+  Object obj = stream([1, 2, 3, 4]);
+  var a = <int>[await for (var n in obj) n];
+  //                                ^^^
+  // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_TYPE
+  // [cfe] The type 'Object' used in the 'for' loop must implement 'Stream<dynamic>'.
+
+  // Downcast variable.
+  var b = <int>[
+    await for (int n in numStream([1, 2, 3, 4])) n
+    //             ^
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //                  ^^^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_ELEMENT_TYPE
+  ];
+
+  // Downcast element.
+  var c = <int>[
+    await for (num n in numStream([1, 2, 3, 4])) n
+    //                                           ^
+    // [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+  ];
+}
+
+Future<void> testMap() async {
+  // Downcast stream.
+  Object obj = stream([1, 2, 3, 4]);
+  var a = <int, int>{await for (var n in obj) n: n};
+  //                                     ^^^
+  // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_TYPE
+  // [cfe] The type 'Object' used in the 'for' loop must implement 'Stream<dynamic>'.
+
+  // Downcast variable.
+  var b = <int, int>{
+    await for (int n in numStream([1, 2, 3, 4])) n: n
+    //             ^
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //                  ^^^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_ELEMENT_TYPE
+  };
+
+  // Downcast element.
+  var c = <int, int>{
+    await for (num n in numStream([1, 2, 3, 4])) n: n
+    //                                           ^
+    // [analyzer] STATIC_WARNING.MAP_KEY_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //                                              ^
+    // [analyzer] STATIC_WARNING.MAP_VALUE_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+  };
+}
+
+Future<void> testSet() async {
+  // Downcast stream.
+  Object obj = stream([1, 2, 3, 4]);
+  var a = <int>{await for (var n in obj) n};
+  //                                ^^^
+  // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_TYPE
+  // [cfe] The type 'Object' used in the 'for' loop must implement 'Stream<dynamic>'.
+
+  // Downcast variable.
+  var b = <int>{
+    await for (int n in numStream([1, 2, 3, 4])) n
+    //             ^
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //                  ^^^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_ELEMENT_TYPE
+  };
+
+  // Downcast element.
+  var c = <int>{
+    await for (num n in numStream([1, 2, 3, 4])) n
+    //                                           ^
+    // [analyzer] STATIC_WARNING.SET_ELEMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+  };
+}
diff --git a/tests/language/control_flow_collections/await_for_dynamic_null_test.dart b/tests/language/control_flow_collections/await_for_dynamic_null_test.dart
new file mode 100644
index 0000000..aad701f2
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_dynamic_null_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that an implicit dynamic cast of a null stream is caught.
+import 'package:async_helper/async_helper.dart';
+
+void main() {
+  asyncTest(() async {
+    // Null stream.
+    dynamic nullStream = null;
+    asyncExpectThrows<Error>(
+        () async => <int>[await for (var i in nullStream) 1]);
+    asyncExpectThrows<Error>(
+        () async => <int, int>{await for (var i in nullStream) 1: 1});
+    asyncExpectThrows<Error>(
+        () async => <int>{await for (var i in nullStream) 1});
+  });
+}
diff --git a/tests/language/control_flow_collections/await_for_inference_test.dart b/tests/language/control_flow_collections/await_for_inference_test.dart
new file mode 100644
index 0000000..e0c1df8
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_inference_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test how await for interacts with inference.
+import "package:async_helper/async_helper.dart";
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+Stream<int> stream() => Stream.fromIterable([1]);
+
+void main() {
+  asyncTest(() async {
+    await testBottomUpInference();
+    await testLoopVariableInference();
+    await testTopDownInference();
+  });
+}
+
+Future<void> testBottomUpInference() async {
+  // Lists.
+  Expect.type<List<int>>([await for (var i in stream()) 1]);
+  Expect.type<List<int>>(
+      [await for (var i in stream()) 1, await for (var i in stream()) 2]);
+  Expect.type<List<num>>(
+      [await for (var i in stream()) 1, await for (var i in stream()) 0.2]);
+  Expect.type<List<int>>([await for (var i in stream()) 1, 2]);
+  Expect.type<List<num>>([await for (var i in stream()) 1, 0.2]);
+  Expect.type<List<dynamic>>([await for (var i in stream()) ...[]]);
+  Expect.type<List<int>>([await for (var i in stream()) ...<int>[]]);
+
+  // Maps.
+  Expect.type<Map<int, int>>({await for (var i in stream()) 1: 1});
+  Expect.type<Map<int, int>>(
+      {await for (var i in stream()) 1: 1, await for (var i in stream()) 2: 2});
+  Expect.type<Map<num, num>>({
+    await for (var i in stream()) 1: 0.1,
+    await for (var i in stream()) 0.2: 2
+  });
+  Expect.type<Map<int, int>>({await for (var i in stream()) 1: 1, 2: 2});
+  Expect.type<Map<num, num>>({await for (var i in stream()) 1: 0.1, 0.2: 2});
+  Expect.type<Map<dynamic, dynamic>>({await for (var i in stream()) ...{}});
+  Expect.type<Map<int, int>>({await for (var i in stream()) ...<int, int>{}});
+
+  // Sets.
+  Expect.type<Set<int>>({await for (var i in stream()) 1});
+  Expect.type<Set<int>>(
+      {await for (var i in stream()) 1, await for (var i in stream()) 2});
+  Expect.type<Set<num>>(
+      {await for (var i in stream()) 1, await for (var i in stream()) 0.2});
+  Expect.type<Set<int>>({await for (var i in stream()) 1, 2});
+  Expect.type<Set<num>>({await for (var i in stream()) 1, 0.2});
+  Expect.type<Set<dynamic>>({await for (var i in stream()) ...[]});
+  Expect.type<Set<int>>({await for (var i in stream()) ...<int>[]});
+
+  // If a nested iterable's type is dynamic, the element type is dynamic.
+  Expect.type<List<dynamic>>(
+      [1, await for (var i in stream()) ...([] as dynamic)]);
+  Expect.type<Set<dynamic>>(
+      {1, await for (var i in stream()) ...([] as dynamic)});
+
+  // If a nested maps's type is dynamic, the key and value types are dynamic.
+  Expect.type<Map<dynamic, dynamic>>(
+      {1: 1, await for (var i in stream()) ...({} as dynamic)});
+}
+
+Future<void> testLoopVariableInference() async {
+  // Infers loop variable from stream.
+  Expect.type<List<int>>([await for (var i in stream()) i]);
+  Expect.type<List<String>>(
+      [await for (var i in stream()) i.toRadixString(10)]);
+
+  // Loop variable type is pushed into stream.
+  Expect.listEquals(<int>[1], [await for (int i in expectIntStream([1])) i]);
+}
+
+Future<void> testTopDownInference() async {
+  // Lists.
+
+  // The context element type is pushed into the body.
+  Expect.listEquals(<int>[1],
+      <int>[await for (var i in stream()) expectInt(1)]);
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.listEquals(<int>[1, 2],
+      [1, await for (var i in stream()) expectDynamic(2)]);
+
+  // Maps.
+
+  // The context element type is pushed into the body.
+  Expect.mapEquals(<int, String>{1: "s"}, <int, String>{
+    await for (var i in stream()) expectInt(1): expectString("s")
+  });
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.mapEquals(<int, String>{1: "s", 2: "t"}, {
+    1: "s",
+    await for (var i in stream()) expectDynamic(2): expectDynamic("t")
+  });
+
+  // Sets.
+
+  // The context element type is pushed into the body.
+  Expect.setEquals(<int>{1}, <int>{await for (var i in stream()) expectInt(1)});
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.setEquals(<int>{1, 2},
+      {1, await for (var i in stream()) expectDynamic(2)});
+}
diff --git a/tests/language/control_flow_collections/await_for_null_test.dart b/tests/language/control_flow_collections/await_for_null_test.dart
new file mode 100644
index 0000000..a8f4154
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_null_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that a null stream expression produces a compile error.
+void main() async {
+  // Null stream.
+  Stream<int>? nullStream;
+  var a = <int>[await for (var i in nullStream) 1];
+  //                                ^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] The type 'Stream<int>?' used in the 'for' loop must implement 'Stream<dynamic>'.
+  var b = <int, int>{await for (var i in nullStream) 1: 1};
+  //                                     ^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] The type 'Stream<int>?' used in the 'for' loop must implement 'Stream<dynamic>'.
+  var c = <int>{await for (var i in nullStream) 1};
+  //                                ^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] The type 'Stream<int>?' used in the 'for' loop must implement 'Stream<dynamic>'.
+}
diff --git a/tests/language/control_flow_collections/await_for_syntax_error_test.dart b/tests/language/control_flow_collections/await_for_syntax_error_test.dart
new file mode 100644
index 0000000..d64303a
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_syntax_error_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  // Use await for in non-async function.
+  var _ = [await for (var i in Stream<int>.empty()) i]; //# 01: compile-time error
+
+  () async {
+    // Use await for variable out of scope.
+    var _ = [await for (var i in Stream<int>.empty()) 1, i]; //# 02: compile-time error
+
+    // Use await for variable in own initializer.
+    var _ = [await for (var i in Stream<Object>.fromIterable([i])) 1]; //# 03: compile-time error
+  }();
+}
diff --git a/tests/language/control_flow_collections/await_for_test.dart b/tests/language/control_flow_collections/await_for_test.dart
new file mode 100644
index 0000000..ce84fe0
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_test.dart
@@ -0,0 +1,234 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+final list = [1, 2, 3, 4];
+final map = {1: 1, 2: 2, 3: 3, 4: 4};
+final set = {1, 2, 3, 4};
+
+Stream<int> stream(List<int> values) => Stream.fromIterable(values);
+Stream<num> numStream(List<num> values) => Stream.fromIterable(values);
+
+void main() {
+  asyncTest(() async {
+    await testList();
+    await testMap();
+    await testSet();
+    await testDuplicateKeys();
+    await testKeyOrder();
+    await testRuntimeErrors();
+  });
+}
+
+Future<void> testList() async {
+  // Only await for.
+  Expect.listEquals(list, <int>[await for (var i in stream(list)) i]);
+
+  // Await for at beginning.
+  Expect.listEquals(list, <int>[await for (var i in stream([1, 2])) i, 3, 4]);
+
+  // Await for in middle.
+  Expect.listEquals(list, <int>[1, await for (var i in stream([2, 3])) i, 4]);
+
+  // Await for at end.
+  Expect.listEquals(list, <int>[1, 2, await for (var i in stream([3, 4])) i]);
+
+  // Empty await for.
+  Expect.listEquals(list,
+      <int>[1, 2, await for (var i in stream([])) i, 3, 4]);
+
+  // Multiple await fors.
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1])) i,
+    2,
+    await for (var i in stream([3, 4])) i
+  ]);
+
+  // Spread inside await for.
+  Expect.listEquals(list,
+      <int>[await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]]);
+
+  // If inside await for.
+  Expect.listEquals(list,
+      <int>[await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i]);
+
+  // Else inside await for.
+  Expect.listEquals(list,
+      <int>[await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i else i]);
+
+  // For inside await for.
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([0, 2])) for (var j = 1; j <= 2; j++) i + j
+  ]);
+
+  // Does not flatten nested collection literal.
+  Expect.listEquals([1], [await for (var i in stream([1])) [i]].first);
+  Expect.mapEquals({1: 1}, [await for (var i in stream([1])) {i: i}].first);
+  Expect.setEquals({1}, [await for (var i in stream([1])) {i}].first);
+}
+
+Future<void> testMap() async {
+  // Only for.
+  Expect.mapEquals(map, <int, int>{await for (var i in stream(list)) i: i});
+
+  // Await for at beginning.
+  Expect.mapEquals(map,
+      <int, int>{await for (var i in stream([1, 2])) i: i, 3: 3, 4: 4});
+
+  // Await for in middle.
+  Expect.mapEquals(map,
+      <int, int>{1: 1, await for (var i in stream([2, 3])) i: i, 4: 4});
+
+  // Await for at end.
+  Expect.mapEquals(map,
+      <int, int>{1: 1, 2: 2, await for (var i in stream([3, 4])) i: i});
+
+  // Empty await for.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    await for (var i in stream([])) i: i,
+    2: 2,
+    3: 3,
+    4: 4
+  });
+
+  // Multiple await fors.
+  Expect.mapEquals(map, <int, int>{
+    await for (var i in stream([1])) i: i,
+    2: 2,
+    await for (var i in stream([3, 4])) i: i
+  });
+
+  // Spread inside await for.
+  Expect.mapEquals(map, <int, int>{
+    await for (var i in stream([0, 2]))
+      ...<int, int>{1 + i: 1 + i, 2 + i: 2 + i}
+  });
+
+  // If inside await for.
+  Expect.mapEquals(map, <int, int>{
+    await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i: i
+  });
+
+  // Else inside await for.
+  Expect.mapEquals(map, <int, int>{
+    await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i: -i else i: i
+  });
+
+  // For inside await for.
+  Expect.mapEquals(map, <int, int>{
+    await for (var i in stream([0, 2]))
+      for (var j = 1; j <= 2; j++) i + j: i + j
+  });
+}
+
+Future<void> testSet() async {
+  // Only await for.
+  Expect.setEquals(set, <int>{await for (var i in stream(list)) i});
+
+  // Await for at beginning.
+  Expect.setEquals(set, <int>{await for (var i in stream([1, 2])) i, 3, 4});
+
+  // Await for in middle.
+  Expect.setEquals(set, <int>{1, await for (var i in stream([2, 3])) i, 4});
+
+  // Await for at end.
+  Expect.setEquals(set, <int>{1, 2, await for (var i in stream([3, 4])) i});
+
+  // Empty await for.
+  Expect.setEquals(set,
+      <int>{1, await for (var i in stream([])) i, 2, 3, 4});
+
+  // Multiple await fors.
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1])) i,
+    2,
+    await for (var i in stream([3, 4])) i
+  });
+
+  // Spread inside await for.
+  Expect.setEquals(set,
+      <int>{await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]});
+
+  // If inside await for.
+  Expect.setEquals(set,
+      <int>{await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i});
+
+  // Else inside await for.
+  Expect.setEquals(set,
+      <int>{await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i else i});
+
+  // For inside await for.
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([0, 2])) for (var j = 1; j <= 2; j++) i + j
+  });
+
+  // Does not flatten nested collection literal.
+  Expect.listEquals([1], {await for (var i in stream([1])) [i]}.first);
+  Expect.mapEquals({1: 1}, {await for (var i in stream([1])) {i: i}}.first);
+  Expect.setEquals({1}, {await for (var i in stream([1])) {i}}.first);
+}
+
+Future<void> testDuplicateKeys() async {
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    await for (var i in stream([1, 2, 3])) i: i,
+    await for (var i in stream([2, 3])) i: i,
+    3: 3,
+    4: 4
+  });
+  Expect.setEquals(set, <int>{
+    1,
+    await for (var i in stream([1, 2, 3])) i,
+    await for (var i in stream([2, 3])) i,
+    3,
+    4
+  });
+}
+
+Future<void> testKeyOrder() async {
+  // First equal key wins.
+  var e1a = Equality(1, "a");
+  var e1b = Equality(1, "b");
+  var e2a = Equality(2, "a");
+  var e2b = Equality(2, "b");
+  var keys = [e1b, e2a, e2b];
+  var values = [2, 3, 4];
+
+  var map = <Equality, int>{
+    e1a: 1,
+    await for (var i in stream([0, 1, 2])) keys[i]: values[i]
+  };
+  Expect.equals("1:a,2:a", map.keys.join(","));
+  Expect.equals("2,4", map.values.join(","));
+
+  var set = <Equality>{e1a, await for (var i in stream([0, 1, 2])) keys[i]};
+  Expect.equals("1:a,2:a", set.join(","));
+}
+
+Future<void> testRuntimeErrors() async {
+  // Cast variable.
+  dynamic nonStream = 3;
+  asyncExpectThrows<TypeError>(
+      () async => <int>[await for (int i in nonStream) 1]);
+  asyncExpectThrows<TypeError>(
+      () async => <int, int>{await for (int i in nonStream) 1: 1});
+  asyncExpectThrows<TypeError>(
+      () async => <int>{await for (int i in nonStream) 1});
+
+  // Wrong element type.
+  dynamic nonInt = "string";
+  asyncExpectThrows<TypeError>(
+      () async => <int>[await for (var i in stream([1])) nonInt]);
+  asyncExpectThrows<TypeError>(
+      () async => <int, int>{await for (var i in stream([1])) nonInt: 1});
+  asyncExpectThrows<TypeError>(
+      () async => <int, int>{await for (var i in stream([1])) 1: nonInt});
+  asyncExpectThrows<TypeError>(
+      () async => <int>{await for (var i in stream([1])) nonInt});
+}
diff --git a/tests/language/control_flow_collections/await_for_type_error_test.dart b/tests/language/control_flow_collections/await_for_type_error_test.dart
new file mode 100644
index 0000000..e63a52e
--- /dev/null
+++ b/tests/language/control_flow_collections/await_for_type_error_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  () async {
+    // Non-Stream type.
+    int nonStream = 3;
+    var _ = <int>[await for (var i in nonStream) 1]; //# 01: compile-time error
+    var _ = <int, int>{await for (var i in nonStream) 1: 1}; //# 02: compile-time error
+    var _ = <int>{await for (var i in nonStream) 1}; //# 03: compile-time error
+
+    // Wrong element type.
+    Stream<String> s = Stream.fromIterable(["s"]);
+    var _ = <int>[await for (int i in s) 1]; //# 07: compile-time error
+    var _ = <int, int>{await for (int i in s) 1: 1}; //# 08: compile-time error
+    var _ = <int>{await for (int i in s) 1}; //# 09: compile-time error
+
+    // Wrong body element type.
+    var _ = <int>[await for (var i in s) "s"]; //# 10: compile-time error
+    var _ = <int, int>{await for (var i in s) "s": 1}; //# 11: compile-time error
+    var _ = <int, int>{await for (var i in s) 1: "s"}; //# 12: compile-time error
+    var _ = <int>{await for (var i in s) "s"}; //# 13: compile-time error
+  }();
+}
diff --git a/tests/language/control_flow_collections/for_await_test.dart b/tests/language/control_flow_collections/for_await_test.dart
new file mode 100644
index 0000000..2baeefc
--- /dev/null
+++ b/tests/language/control_flow_collections/for_await_test.dart
@@ -0,0 +1,105 @@
+// 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:async_helper/async_helper.dart";
+import 'package:expect/expect.dart';
+
+final list = [1, 2, 3];
+final map = {1: 1, 2: 2, 3: 3};
+final set = {1, 2, 3};
+
+void main() {
+  asyncTest(() async {
+    await testList();
+    await testMap();
+    await testSet();
+  });
+}
+
+Future<void> testList() async {
+  var future123 = Future.value([1, 2, 3]);
+  var future1 = Future.value(1);
+
+  // Await in iterable.
+  Expect.listEquals(list, [for (var i in await future123) i]);
+
+  // Await in for-in body.
+  Expect.listEquals(list, [for (var i in [1, 2, 3]) await Future.value(i)]);
+
+  // Await in initializer.
+  Expect.listEquals(list, [for (var i = await future1; i < 4; i++) i]);
+
+  // Await in condition.
+  Expect.listEquals(list,
+      [for (var i = 1; await Future.value(i < 4); i++) i]);
+
+  // Await in increment.
+  Expect.listEquals(list,
+      [for (var i = 1; i < 4; await Future(() => i++)) i]);
+
+  // Await in for body.
+  Expect.listEquals(list,
+      [for (var i = 1; i < 4; i++) await Future.value(i)]);
+}
+
+Future<void> testMap() async {
+  var future123 = Future.value([1, 2, 3]);
+  var future1 = Future.value(1);
+
+  // Await in iterable.
+  Expect.mapEquals(map, {for (var i in await future123) i: i});
+
+  // Await in for-in body key.
+  Expect.mapEquals(map,
+      {for (var i in [1, 2, 3]) await Future.value(i): i});
+
+  // Await in for-in body value.
+  Expect.mapEquals(map,
+      {for (var i in [1, 2, 3]) i: await Future.value(i)});
+
+  // Await in initializer.
+  Expect.mapEquals(map, {for (var i = await future1; i < 4; i++) i: i});
+
+  // Await in condition.
+  Expect.mapEquals(map,
+      {for (var i = 1; await Future.value(i < 4); i++) i: i});
+
+  // Await in increment.
+  Expect.mapEquals(map,
+      {for (var i = 1; i < 4; await Future(() => i++)) i: i});
+
+  // Await in for body key.
+  Expect.mapEquals(map,
+      {for (var i = 1; i < 4; i++) await Future.value(i): i});
+
+  // Await in for body value.
+  Expect.mapEquals(map,
+      {for (var i = 1; i < 4; i++) i: await Future.value(i)});
+}
+
+Future<void> testSet() async {
+  var future123 = Future.value([1, 2, 3]);
+  var future1 = Future.value(1);
+
+  // Await in iterable.
+  Expect.setEquals(set, {for (var i in await future123) i});
+
+  // Await in for-in body.
+  Expect.setEquals(set, {for (var i in [1, 2, 3]) await Future.value(i)});
+
+  // Await in initializer.
+  Expect.setEquals(set, {for (var i = await future1; i < 4; i++) i});
+
+  // Await in condition.
+  Expect.setEquals(set,
+      {for (var i = 1; await Future.value(i < 4); i++) i});
+
+  // Await in increment.
+  Expect.setEquals(set,
+      {for (var i = 1; i < 4; await Future(() => i++)) i});
+
+  // Await in for body.
+  Expect.setEquals(set,
+      {for (var i = 1; i < 4; i++) await Future.value(i)});
+}
diff --git a/tests/language/control_flow_collections/for_const_error_test.dart b/tests/language/control_flow_collections/for_const_error_test.dart
new file mode 100644
index 0000000..3348639
--- /dev/null
+++ b/tests/language/control_flow_collections/for_const_error_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  // For cannot be used in a const collection.
+  const _ = [for (var i in []) 1]; //# 00: compile-time error
+  const _ = {for (var i in []) 1: 1}; //# 01: compile-time error
+  const _ = {for (var i in []) 1}; //# 02: compile-time error
+
+  const _ = [for (; false;) 1]; //# 03: compile-time error
+  const _ = {for (; false;) 1: 1}; //# 04: compile-time error
+  const _ = {for (; false;) 1}; //# 05: compile-time error
+
+  () async {
+    const _ = <int>[await for (var i in []) 1]; //# 06: compile-time error
+    const _ = <int, int>{await for (var i in []) 1: 1}; //# 07: compile-time error
+    const _ = <int>{await for (var i in []) 1}; //# 08: compile-time error
+  }();
+}
diff --git a/tests/language/control_flow_collections/for_downcast_test.dart b/tests/language/control_flow_collections/for_downcast_test.dart
new file mode 100644
index 0000000..f857295
--- /dev/null
+++ b/tests/language/control_flow_collections/for_downcast_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that downcasting elements in collection-for is a compile error.
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testNullIterable();
+}
+
+void testList() {
+  // Downcast iterable.
+  Object obj = <int>[1, 2, 3, 4];
+  var a = <int>[for (var n in obj) n];
+  //                          ^^^
+  // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_TYPE
+  // [cfe] The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+
+  // Downcast variable.
+  var b = <int>[
+    for (int n in <num>[1, 2, 3, 4]) n
+    //       ^
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //            ^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_ELEMENT_TYPE
+  ];
+
+  // Downcast element.
+  var c = <int>[
+    for (num n in <num>[1, 2, 3, 4]) n
+    //                               ^
+    // [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+  ];
+
+  // Downcast condition.
+  var d = <int>[for (var i = 1; (i < 2) as Object; i++) i];
+  //                            ^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+  //                                    ^
+  // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+}
+
+void testMap() {
+  // Downcast iterable.
+  Object obj = <int>[1, 2, 3, 4];
+  var a = <int, int>{for (var n in obj) n: n};
+  //                               ^^^
+  // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_TYPE
+  // [cfe] The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+
+  // Downcast variable.
+  var b = <int, int>{
+    for (int n in <num>[1, 2, 3, 4]) n: n
+    //       ^
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //            ^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_ELEMENT_TYPE
+  };
+
+  // Downcast element.
+  var c = <int, int>{
+    for (num n in <num>[1, 2, 3, 4]) n: n
+    //                               ^
+    // [analyzer] STATIC_WARNING.MAP_KEY_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //                                  ^
+    // [analyzer] STATIC_WARNING.MAP_VALUE_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+  };
+
+  // Downcast condition.
+  var d = <int, int>{for (var i = 1; (i < 2) as Object; i++) i: i};
+  //                                 ^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+  //                                         ^
+  // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+}
+
+void testSet() {
+  // Downcast iterable.
+  Object obj = <int>[1, 2, 3, 4];
+  var a = <int>{for (var n in obj) n};
+  //                          ^^^
+  // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_TYPE
+  // [cfe] The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+
+  // Downcast variable.
+  var b = <int>{
+    for (int n in <num>[1, 2, 3, 4]) n
+    //       ^
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+    //            ^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.FOR_IN_OF_INVALID_ELEMENT_TYPE
+  };
+
+  // Downcast element.
+  var c = <int>{
+    for (num n in <num>[1, 2, 3, 4]) n
+    //                               ^
+    // [analyzer] STATIC_WARNING.SET_ELEMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+  };
+
+  // Downcast condition.
+  var d = <int>{for (var i = 1; (i < 2) as Object; i++) i};
+  //                            ^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+  //                                    ^
+  // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+}
+
+void testNullIterable() {
+  // Null iterable.
+  Iterable<int>? nullIterable = null;
+  var a = <int>[for (var i in nullIterable) 1];
+  //                          ^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+  var b = {for (var i in nullIterable) 1: 1};
+  //                     ^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+  var c = <int>{for (var i in nullIterable) 1};
+  //                          ^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+}
diff --git a/tests/language/control_flow_collections/for_dynamic_null_strong_test.dart b/tests/language/control_flow_collections/for_dynamic_null_strong_test.dart
new file mode 100644
index 0000000..a0565d8
--- /dev/null
+++ b/tests/language/control_flow_collections/for_dynamic_null_strong_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+import 'package:expect/expect.dart';
+
+void main() {
+  // Null condition expression.
+  dynamic nullBool = null;
+  Expect.throwsTypeError(() => <int>[for (; nullBool;) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (; nullBool;) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (; nullBool;) 1});
+
+  // Null iterable.
+  dynamic nullIterable = null;
+  Expect.throwsTypeError(() => <int>[for (var i in nullIterable) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (var i in nullIterable) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (var i in nullIterable) 1});
+}
diff --git a/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart b/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart
new file mode 100644
index 0000000..5904782
--- /dev/null
+++ b/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+import 'package:expect/expect.dart';
+
+void main() {
+  // Null condition expression.
+  dynamic nullBool = null;
+  Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]);
+  Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1});
+  Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1});
+
+  // Null iterable.
+  dynamic nullIterable = null;
+  // The current behavior is inconsistent across the backends. The VM currently
+  // tries calling .iterable and throws a NoSuchMethodError. DDC throws a
+  // TypeError.
+  Expect.throws(() => <int>[for (var i in nullIterable) 1]);
+  Expect.throws(() => <int, int>{for (var i in nullIterable) 1: 1});
+  Expect.throws(() => <int>{for (var i in nullIterable) 1});
+}
diff --git a/tests/language/control_flow_collections/for_inference_test.dart b/tests/language/control_flow_collections/for_inference_test.dart
new file mode 100644
index 0000000..4e022e0
--- /dev/null
+++ b/tests/language/control_flow_collections/for_inference_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test how control flow interacts with inference.
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+void main() {
+  testBottomUpInference();
+  testLoopVariableInference();
+  testTopDownInference();
+}
+
+void testBottomUpInference() {
+  // Lists.
+  Expect.type<List<int>>([for (; false;) 1]);
+  Expect.type<List<int>>([for (; false;) 1, for (; false;) 2]);
+  Expect.type<List<num>>([for (; false;) 1, for (; false;) 0.2]);
+  Expect.type<List<int>>([for (; false;) 1, 2]);
+  Expect.type<List<num>>([for (; false;) 1, 0.2]);
+  Expect.type<List<dynamic>>([for (; false;) ...[]]);
+  Expect.type<List<int>>([for (; false;) ...<int>[]]);
+
+  // Maps.
+  Expect.type<Map<int, int>>({for (; false;) 1: 1});
+  Expect.type<Map<int, int>>({for (; false;) 1: 1, for (; false;) 2: 2});
+  Expect.type<Map<num, num>>({for (; false;) 1: 0.1, for (; false;) 0.2: 2});
+  Expect.type<Map<int, int>>({for (; false;) 1: 1, 2: 2});
+  Expect.type<Map<num, num>>({for (; false;) 1: 0.1, 0.2: 2});
+  Expect.type<Map<dynamic, dynamic>>({for (; false;) ...{}});
+  Expect.type<Map<int, int>>({for (; false;) ...<int, int>{}});
+
+  // Sets.
+  Expect.type<Set<int>>({for (; false;) 1});
+  Expect.type<Set<int>>({for (; false;) 1, for (; false;) 2});
+  Expect.type<Set<num>>({for (; false;) 1, for (; false;) 0.2});
+  Expect.type<Set<int>>({for (; false;) 1, 2});
+  Expect.type<Set<num>>({for (; false;) 1, 0.2});
+  Expect.type<Set<dynamic>>({for (; false;) ...[]});
+  Expect.type<Set<int>>({for (; false;) ...<int>[]});
+
+  // If a nested iterable's type is dynamic, the element type is dynamic.
+  Expect.type<List<dynamic>>([for (; false;) ...([] as dynamic)]);
+  Expect.type<Set<dynamic>>({1, for (; false;) ...([] as dynamic)});
+
+  // If a nested maps's type is dynamic, the key and value types are dynamic.
+  Expect.type<Map<dynamic, dynamic>>({1: 1, for (; false;) ...({} as dynamic)});
+}
+
+void testLoopVariableInference() {
+  // Infers loop variable from iterable.
+  Expect.type<List<int>>([for (var i in <int>[1]) i]);
+  Expect.type<List<String>>([for (var i in <int>[1]) i.toRadixString(10)]);
+
+  // Infers loop variable from initializer.
+  Expect.type<List<int>>([for (var i = 1; i < 2; i++) i]);
+  Expect.type<List<String>>([for (var i = 1; i < 2; i++) i.toRadixString(10)]);
+
+  // Loop variable type is pushed into sequence.
+  Expect.listEquals(<int>[1], [for (int i in expectIntIterable([1])) i]);
+
+  // Loop variable type is pushed into initializer.
+  Expect.listEquals(<int>[1], [for (int i = expectInt(1); i < 2; i++) i]);
+}
+
+void testTopDownInference() {
+  // Lists.
+
+  // The context element type is pushed into the body.
+  Expect.listEquals(<int>[1], <int>[for (var i = 0; i < 1; i++) expectInt(1)]);
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.listEquals(<int>[1, 2],
+      [1, for (var i = 0; i < 1; i++) expectDynamic(2)]);
+
+  // Maps.
+
+  // The context element type is pushed into the body.
+  Expect.mapEquals(<int, String>{1: "s"}, <int, String>{
+    for (var i = 0; i < 1; i++) expectInt(1): expectString("s")
+  });
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.mapEquals(<int, String>{1: "s", 2: "t"}, {
+    1: "s",
+    for (var i = 0; i < 1; i++) expectDynamic(2): expectDynamic("t")
+  });
+
+  // Sets.
+
+  // The context element type is pushed into the body.
+  Expect.setEquals(<int>{1}, <int>{for (var i = 0; i < 1; i++) expectInt(1)});
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.setEquals(<int>{1, 2},
+      {1, for (var i = 0; i < 1; i++) expectDynamic(2)});
+}
diff --git a/tests/language/control_flow_collections/for_non_bool_condition_test.dart b/tests/language/control_flow_collections/for_non_bool_condition_test.dart
new file mode 100644
index 0000000..a808e9c
--- /dev/null
+++ b/tests/language/control_flow_collections/for_non_bool_condition_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  // Non-bool condition expression.
+  dynamic nonBool = 3;
+  Expect.throwsTypeError(() => <int>[for (; nonBool;) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (; nonBool;) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (; nonBool;) 1});
+}
diff --git a/tests/language/control_flow_collections/for_null_condition_test.dart b/tests/language/control_flow_collections/for_null_condition_test.dart
new file mode 100644
index 0000000..31b02b9
--- /dev/null
+++ b/tests/language/control_flow_collections/for_null_condition_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  // Null condition expression.
+  bool? nullBool = null;
+  var a = <int>[for (; nullBool;) 1];
+  //                   ^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] A value of type 'bool?' can't be assigned to a variable of type 'bool'.
+  var b = <int, int>{for (; nullBool;) 1: 1};
+  //                        ^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] A value of type 'bool?' can't be assigned to a variable of type 'bool'.
+  var c = <int>{for (; nullBool;) 1};
+  //                   ^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] A value of type 'bool?' can't be assigned to a variable of type 'bool'.
+}
diff --git a/tests/language/control_flow_collections/for_runtime_error_test.dart b/tests/language/control_flow_collections/for_runtime_error_test.dart
new file mode 100644
index 0000000..ea5cfe4
--- /dev/null
+++ b/tests/language/control_flow_collections/for_runtime_error_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  // Cast for variable.
+  dynamic nonInt = "string";
+  Expect.throwsTypeError(() => <int>[for (int i = nonInt; false;) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (int i = nonInt; false;) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (int i = nonInt; false;) 1});
+
+  // Cast for-in variable.
+  dynamic nonIterable = 3;
+  Expect.throwsTypeError(() => <int>[for (int i in nonIterable) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (int i in nonIterable) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (int i in nonIterable) 1});
+
+  // Wrong element type.
+  Expect.throwsTypeError(() => <int>[for (var i = 0; i < 1; i++) nonInt]);
+  Expect.throwsTypeError(
+      () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1});
+  Expect.throwsTypeError(
+      () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt});
+  Expect.throwsTypeError(() => <int>{for (var i = 0; i < 1; i++) nonInt});
+}
diff --git a/tests/language/control_flow_collections/for_test.dart b/tests/language/control_flow_collections/for_test.dart
new file mode 100644
index 0000000..c25a4d4
--- /dev/null
+++ b/tests/language/control_flow_collections/for_test.dart
@@ -0,0 +1,204 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+final list = [1, 2, 3, 4];
+final map = {1: 1, 2: 2, 3: 3, 4: 4};
+final set = {1, 2, 3, 4};
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testDuplicateKeys();
+  testKeyOrder();
+}
+
+void testList() {
+  // Only for.
+  Expect.listEquals(list, <int>[for (var i in list) i]);
+
+  // For at beginning.
+  Expect.listEquals(list, <int>[for (var i in <int>[1, 2]) i, 3, 4]);
+
+  // For in middle.
+  Expect.listEquals(list, <int>[1, for (var i in <int>[2, 3]) i, 4]);
+
+  // For at end.
+  Expect.listEquals(list, <int>[1, 2, for (var i in <int>[3, 4]) i]);
+
+  // Empty for.
+  Expect.listEquals(list,
+      <int>[1, for (var i in <int>[]) i, 2, 3, for (; false;) 9, 4]);
+
+  // Multiple fors.
+  Expect.listEquals(list,
+      <int>[for (var i in <int>[1]) i, 2, for (var i = 3; i <= 4; i++) i]);
+
+  // Spread inside for.
+  Expect.listEquals(list,
+      <int>[for (var i in <int>[0, 2]) ...<int>[1 + i, 2 + i]]);
+
+  // If inside for.
+  Expect.listEquals(list,
+      <int>[for (var i in <int>[1, 9, 2, 3, 9, 4]) if (i != 9) i]);
+
+  // Else inside for.
+  Expect.listEquals(list,
+      <int>[for (var i in <int>[1, -2, 3, -4]) if (i < 0) -i else i]);
+
+  // For inside for.
+  Expect.listEquals(list,
+      <int>[for (var i in <int>[0, 2]) for (var j = 1; j <= 2; j++) i + j]);
+
+  // Does not flatten nested collection literal.
+  Expect.listEquals([1], [for (var i = 1; i < 2; i++) [i]].first);
+  Expect.mapEquals({1: 1}, [for (var i = 1; i < 2; i++) {i: i}].first);
+  Expect.setEquals({1}, [for (var i = 1; i < 2; i++) {i}].first);
+
+  // Downcast condition.
+  Expect.listEquals([1], <int>[for (var i = 1; (i < 2) as dynamic; i++) i]);
+}
+
+void testMap() {
+  // Only for.
+  Expect.mapEquals(map, <int, int>{for (var i in list) i: i});
+
+  // For at beginning.
+  Expect.mapEquals(map,
+      <int, int>{for (var i in <int>[1, 2]) i: i, 3: 3, 4: 4});
+
+  // For in middle.
+  Expect.mapEquals(map,
+      <int, int>{1: 1, for (var i in <int>[2, 3]) i: i, 4: 4});
+
+  // For at end.
+  Expect.mapEquals(map,
+      <int, int>{1: 1, 2: 2, for (var i in <int>[3, 4]) i: i});
+
+  // Empty for.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    for (var i in <int>[]) i: i,
+    2: 2,
+    3: 3,
+    for (; false;) 9: 9,
+    4: 4
+  });
+
+  // Multiple fors.
+  Expect.mapEquals(map, <int, int>{
+    for (var i in <int>[1]) i: i,
+    2: 2,
+    for (var i = 3; i <= 4; i++) i: i
+  });
+
+  // Spread inside for.
+  Expect.mapEquals(map, <int, int>{
+    for (var i in <int>[0, 2]) ...<int, int>{1 + i: 1 + i, 2 + i: 2 + i}
+  });
+
+  // If inside for.
+  Expect.mapEquals(map,
+      <int, int>{for (var i in <int>[1, 9, 2, 3, 9, 4]) if (i != 9) i: i});
+
+  // Else inside for.
+  Expect.mapEquals(map,
+      <int, int>{for (var i in <int>[1, -2, 3, -4]) if (i < 0) -i: -i else i: i});
+
+  // For inside for.
+  Expect.mapEquals(map, <int, int>{
+    for (var i in <int>[0, 2]) for (var j = 1; j <= 2; j++) i + j: i + j
+  });
+
+  // Downcast condition.
+  Expect.mapEquals({1 : 1},
+      <int, int>{for (var i = 1; (i < 2) as dynamic; i++) i: i});
+}
+
+void testSet() {
+  // Only for.
+  Expect.setEquals(set, <int>{for (var i in list) i});
+
+  // For at beginning.
+  Expect.setEquals(set, <int>{for (var i in <int>[1, 2]) i, 3, 4});
+
+  // For in middle.
+  Expect.setEquals(set, <int>{1, for (var i in <int>[2, 3]) i, 4});
+
+  // For at end.
+  Expect.setEquals(set, <int>{1, 2, for (var i in <int>[3, 4]) i});
+
+  // Empty for.
+  Expect.setEquals(set,
+      <int>{1, for (var i in <int>[]) i, 2, 3, for (; false;) 9, 4});
+
+  // Multiple fors.
+  Expect.setEquals(set,
+      <int>{for (var i in <int>[1]) i, 2, for (var i = 3; i <= 4; i++) i});
+
+  // Spread inside for.
+  Expect.setEquals(set,
+      <int>{for (var i in <int>[0, 2]) ...<int>[1 + i, 2 + i]});
+
+  // If inside for.
+  Expect.setEquals(set,
+      <int>{for (var i in <int>[1, 9, 2, 3, 9, 4]) if (i != 9) i});
+
+  // Else inside for.
+  Expect.setEquals(set,
+      <int>{for (var i in <int>[1, -2, 3, -4]) if (i < 0) -i else i});
+
+  // For inside for.
+  Expect.setEquals(set,
+      <int>{for (var i in <int>[0, 2]) for (var j = 1; j <= 2; j++) i + j});
+
+  // Does not flatten nested collection literal.
+  Expect.listEquals([1], {for (var i = 1; i < 2; i++) [i]}.first);
+  Expect.mapEquals({1: 1}, {for (var i = 1; i < 2; i++) {i: i}}.first);
+  Expect.setEquals({1}, {for (var i = 1; i < 2; i++) {i}}.first);
+
+  // Downcast condition.
+  Expect.setEquals({1}, <int>{for (var i = 1; (i < 2) as dynamic; i++) i});
+}
+
+void testDuplicateKeys() {
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    for (var i in <int>[1, 2, 3]) i: i,
+    for (var i = 2; i <= 3; i++) i: i,
+    3: 3,
+    4: 4
+  });
+  Expect.setEquals(set, <int>{
+    1,
+    for (var i in <int>[1, 2, 3]) i,
+    for (var i = 2; i <= 3; i++) i,
+    3,
+    4
+  });
+}
+
+void testKeyOrder() {
+  // First equal key wins.
+  var e1a = Equality(1, "a");
+  var e1b = Equality(1, "b");
+  var e2a = Equality(2, "a");
+  var e2b = Equality(2, "b");
+  var keys = [e1b, e2a, e2b];
+  var values = [2, 3, 4];
+
+  var map = <Equality, int>{
+    e1a: 1,
+    for (var i = 0; i < keys.length; i++) keys[i]: values[i]
+  };
+  Expect.equals("1:a,2:a", map.keys.join(","));
+  Expect.equals("2,4", map.values.join(","));
+
+  var set = <Equality>{e1a, for (var i = 0; i < keys.length; i++) keys[i]};
+  Expect.equals("1:a,2:a", set.join(","));
+}
diff --git a/tests/language/control_flow_collections/for_variable_test.dart b/tests/language/control_flow_collections/for_variable_test.dart
new file mode 100644
index 0000000..8433907
--- /dev/null
+++ b/tests/language/control_flow_collections/for_variable_test.dart
@@ -0,0 +1,202 @@
+// 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 for how variables and scoping work with for elements.
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+String global = "global";
+
+void main() {
+  testClosure();
+  Test().shadowing();
+  Test().reuseVariable();
+}
+
+void testClosure() {
+  var closures = [];
+  capture(callback) {
+    closures.add(callback);
+    return callback();
+  }
+
+  reset() {
+    closures.clear();
+  }
+
+  // Close over for-in loop variable in element.
+  var list = [for (var i in [0, 1]) () => i];
+  Expect.equals(0, list[0]());
+  Expect.equals(1, list[1]());
+
+  // Close over loop variable in element.
+  list = [for (var i = 0; i < 2; i++) () => i];
+  Expect.equals(0, list[0]());
+  Expect.equals(1, list[1]());
+
+  // Close over variable in condition expression.
+  var list2 = [for (var i = 0; capture(() => i++) < 2;) i];
+  Expect.equals(1, closures[0]());
+  Expect.equals(2, closures[1]());
+  Expect.listEquals([1, 2], list2);
+  reset();
+
+  // Close over variable in increment expression.
+  var list3 = [for (var i = 0; i < 2; capture(() => i++)) i];
+  Expect.equals(1, closures[0]());
+  Expect.equals(2, closures[1]());
+  Expect.listEquals([0, 1], list3);
+  reset();
+}
+
+class TestBase {
+  String inherited = "inherited";
+}
+
+class Test extends TestBase {
+  static String staticField = "static field";
+
+  String field = "field";
+
+  void shadowing() {
+    var local = "local";
+
+    // C-style for.
+    var list = [
+      for (String? global = "for"; global != null; global = null) global
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (String? staticField = "for"; staticField != null; staticField = null)
+        staticField
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (String? field = "for"; field != null; field = null) field
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (String? inherited = "for"; inherited != null; inherited = null) inherited
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (String? local = "for"; local != null; local = null) local
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (String? outer = "outer"; outer != null; outer = null)
+        for (String? outer = "for"; outer != null; outer = null)
+          outer
+    ];
+    Expect.listEquals(["for"], list);
+
+    // For-in.
+    list = [for (var global in ["for"]) global];
+    Expect.listEquals(["for"], list);
+
+    list = [for (var staticField in ["for"]) staticField];
+    Expect.listEquals(["for"], list);
+
+    list = [for (var field in ["for"]) field];
+    Expect.listEquals(["for"], list);
+
+    list = [for (var inherited in ["for"]) inherited];
+    Expect.listEquals(["for"], list);
+
+    list = [for (var local in ["for"]) local];
+    Expect.listEquals(["for"], list);
+
+    list = [for (var outer in ["outer"]) for (var outer in ["for"]) outer];
+    Expect.listEquals(["for"], list);
+  }
+
+  void reuseVariable() {
+    var local = "local";
+
+    // C-style for.
+    var list = [
+      for (global = "for"; global == "for"; global = "after") global
+    ];
+    Expect.listEquals(["for"], list);
+    Expect.equals("after", global);
+    global = "global";
+
+    list = [
+      for (staticField = "for"; staticField == "for"; staticField = "after")
+        staticField
+    ];
+    Expect.listEquals(["for"], list);
+    Expect.equals("after", staticField);
+    staticField = "staticField";
+
+    list = [
+      for (field = "for"; field == "for"; field = "after") field
+    ];
+    Expect.listEquals(["for"], list);
+    Expect.equals("after", field);
+    field = "field";
+
+    list = [
+      for (inherited = "for"; inherited == "for"; inherited = "after") inherited
+    ];
+    Expect.listEquals(["for"], list);
+    Expect.equals("after", inherited);
+    inherited = "inherited";
+
+    list = [
+      for (local = "for"; local == "for"; local = "after") local
+    ];
+    Expect.listEquals(["for"], list);
+    Expect.equals("after", local);
+    local = "local";
+
+    list = [
+      for (var outer = "outer"; outer == "outer"; outer = "outer after") ...[
+        for (outer = "for"; outer == "for"; outer = "after") outer,
+        outer
+      ]
+    ];
+    Expect.listEquals(["for", "after"], list);
+
+    // For-in.
+    list = [for (global in ["for"]) global];
+    Expect.listEquals(["for"], list);
+    Expect.equals("for", global);
+    global = "global";
+
+    list = [for (staticField in ["for"]) staticField];
+    Expect.listEquals(["for"], list);
+    Expect.equals("for", staticField);
+    staticField = "staticField";
+
+    list = [for (field in ["for"]) field];
+    Expect.listEquals(["for"], list);
+    Expect.equals("for", field);
+    field = "field";
+
+    list = [for (inherited in ["for"]) inherited];
+    Expect.listEquals(["for"], list);
+    Expect.equals("for", inherited);
+    inherited = "inherited";
+
+    list = [for (local in ["for"]) local];
+    Expect.listEquals(["for"], list);
+    Expect.equals("for", local);
+    local = "local";
+
+    list = [
+      for (var outer in ["outer"]) ...[
+        for (outer in ["for"]) outer,
+        outer
+      ]
+    ];
+    Expect.listEquals(["for", "for"], list);
+  }
+}
diff --git a/tests/language/control_flow_collections/if_await_test.dart b/tests/language/control_flow_collections/if_await_test.dart
new file mode 100644
index 0000000..08d0c60
--- /dev/null
+++ b/tests/language/control_flow_collections/if_await_test.dart
@@ -0,0 +1,93 @@
+// 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:async_helper/async_helper.dart";
+import 'package:expect/expect.dart';
+
+final list = [1, 2, 3];
+final map = {1: 1, 2: 2, 3: 3};
+final set = {1, 2, 3};
+
+void main() {
+  asyncTest(() async {
+    await testList();
+    await testMap();
+    await testSet();
+  });
+}
+
+Future<void> testList() async {
+  var futureTrue = Future.value(true);
+  var future2 = Future.value(2);
+  var future9 = Future.value(9);
+
+  // Await in condition.
+  Expect.listEquals(list, [1, if (await futureTrue) 2, 3]);
+
+  // Await in then branch.
+  Expect.listEquals(list, [1, if (true) await future2, 3]);
+
+  // Await in else branch.
+  Expect.listEquals(list, [1, if (false) 9 else await future2, 3]);
+
+  // Await in untaken then branch.
+  Expect.listEquals(list, [1, 2, if (false) await future9, 3]);
+
+  // Await in untaken else branch.
+  Expect.listEquals(list, [1, if (true) 2 else await future9, 3]);
+}
+
+Future<void> testMap() async {
+  var futureTrue = Future.value(true);
+  var future2 = Future.value(2);
+  var future9 = Future.value(9);
+
+  // Await in condition.
+  Expect.mapEquals(map, {1: 1, if (await futureTrue) 2: 2, 3: 3});
+
+  // Await in then branch key.
+  Expect.mapEquals(map, {1: 1, if (true) await future2: 2, 3: 3});
+
+  // Await in then branch value.
+  Expect.mapEquals(map, {1: 1, if (true) 2: await future2, 3: 3});
+
+  // Await in else branch key.
+  Expect.mapEquals(map, {1: 1, if (false) 9: 9 else await future2: 2, 3: 3});
+
+  // Await in else branch value.
+  Expect.mapEquals(map, {1: 1, if (false) 9: 9 else 2: await future2, 3: 3});
+
+  // Await in untaken then branch key.
+  Expect.mapEquals(map, {1: 1, 2: 2, if (false) await future9: 9, 3: 3});
+
+  // Await in untaken then branch value.
+  Expect.mapEquals(map, {1: 1, 2: 2, if (false) 9: await future9, 3: 3});
+
+  // Await in untaken else branch key.
+  Expect.mapEquals(map, {1: 1, if (true) 2: 2 else await future9: 9, 3: 3});
+
+  // Await in untaken else branch value.
+  Expect.mapEquals(map, {1: 1, if (true) 2: 2 else 9: await future9, 3: 3});
+}
+
+Future<void> testSet() async {
+  var futureTrue = Future.value(true);
+  var future2 = Future.value(2);
+  var future9 = Future.value(9);
+
+  // Await in condition.
+  Expect.setEquals(set, {1, if (await futureTrue) 2, 3});
+
+  // Await in then branch.
+  Expect.setEquals(set, {1, if (true) await future2, 3});
+
+  // Await in else branch.
+  Expect.setEquals(set, {1, if (false) 9 else await future2, 3});
+
+  // Await in untaken then branch.
+  Expect.setEquals(set, {1, 2, if (false) await future9, 3});
+
+  // Await in untaken else branch.
+  Expect.setEquals(set, {1, if (true) 2 else await future9, 3});
+}
diff --git a/tests/language/control_flow_collections/if_const_error_test.dart b/tests/language/control_flow_collections/if_const_error_test.dart
new file mode 100644
index 0000000..bc1d0e2
--- /dev/null
+++ b/tests/language/control_flow_collections/if_const_error_test.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+final nonConstBool = true;
+final nonConstInt = 3;
+
+const dynamic nonBool = 3;
+const dynamic nonInt = "s";
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testShortCircuit();
+}
+
+void testList() {
+  // Condition must be constant.
+  const _ = <int>[if (nonConstBool) 1]; //# 01: compile-time error
+
+  // Condition must be Boolean.
+  const _ = <int>[if (nonBool) 1]; //# 02: compile-time error
+
+  // Then element must be constant, whether or not branch is taken.
+  const _ = <int>[if (true) nonConstInt]; //# 03: compile-time error
+  const _ = <int>[if (false) nonConstInt]; //# 04: compile-time error
+
+  // Else element must be constant, whether or not branch is taken.
+  const _ = <int>[if (true) 1 else nonConstInt]; //# 05: compile-time error
+  const _ = <int>[if (false) 1 else nonConstInt]; //# 06: compile-time error
+
+  // Then element must have right type if branch is chosen.
+  const _ = <int>[if (true) nonInt]; //# 07: compile-time error
+
+  // Else element must have right type if branch is chosen.
+  const _ = <int>[if (false) 9 else nonInt]; //# 08: compile-time error
+}
+
+void testMap() {
+  // Condition must be constant.
+  const _ = <int, int>{if (nonConstBool) 1: 1}; //# 09: compile-time error
+
+  // Condition must be Boolean.
+  const _ = <int, int>{if (nonBool) 1: 1}; //# 10: compile-time error
+
+  // Then key element must be constant, whether or not branch is taken.
+  const _ = <int, int>{if (true) nonConstInt: 1}; //# 11: compile-time error
+  const _ = <int, int>{if (false) nonConstInt: 1}; //# 12: compile-time error
+
+  // Then value element must be constant, whether or not branch is taken.
+  const _ = <int, int>{if (true) 1: nonConstInt}; //# 13: compile-time error
+  const _ = <int, int>{if (false) 1: nonConstInt}; //# 14: compile-time error
+
+  // Else key element must be constant, whether or not branch is taken.
+  const _ = <int, int>{if (true) 1 else nonConstInt: 1}; //# 15: compile-time error
+  const _ = <int, int>{if (false) 1 else nonConstInt: 1}; //# 16: compile-time error
+
+  // Else value element must be constant, whether or not branch is taken.
+  const _ = <int, int>{if (true) 1 else 1: nonConstInt}; //# 17: compile-time error
+  const _ = <int, int>{if (false) 1 else 1: nonConstInt}; //# 18: compile-time error
+
+  // Then key element must have right type if branch is chosen.
+  const _ = <int, int>{if (true) nonInt: 1}; //# 19: compile-time error
+
+  // Then value element must have right type if branch is chosen.
+  const _ = <int, int>{if (true) 1: nonInt}; //# 20: compile-time error
+
+  // Else key element must have right type if branch is chosen.
+  const _ = <int, int>{if (false) 9 else nonInt: 1}; //# 21: compile-time error
+
+  // Else value element must have right type if branch is chosen.
+  const _ = <int, int>{if (false) 9 else 1: nonInt}; //# 22: compile-time error
+
+  // Key cannot override operator.==().
+  const obj = 0.1;
+  const _ = {if (true) 0.1: 1}; //# 23: compile-time error
+  const _ = {if (true) Duration(seconds: 0): 1}; //# 24: compile-time error
+  const _ = {if (true) obj: 1}; //# 25: compile-time error
+
+  // Cannot have key collision when branch is chosen.
+  const _ = <int, int>{1: 1, if (true) 1: 1}; //# 25: compile-time error
+  const _ = <int, int>{if (true) 1: 1, if (true) 1: 1}; //# 26: compile-time error
+}
+
+void testSet() {
+  // Condition must be constant.
+  const _ = <int>{if (nonConstBool) 1}; //# 27: compile-time error
+
+  // Condition must be Boolean.
+  const _ = <int>{if (nonBool) 1}; //# 28: compile-time error
+
+  // Then element must be constant, whether or not branch is taken.
+  const _ = <int>{if (true) nonConstInt}; //# 29: compile-time error
+  const _ = <int>{if (false) nonConstInt}; //# 30: compile-time error
+
+  // Else element must be constant, whether or not branch is taken.
+  const _ = <int>{if (true) 1 else nonConstInt}; //# 31: compile-time error
+  const _ = <int>{if (false) 1 else nonConstInt}; //# 32: compile-time error
+
+  // Then element must have right type if branch is chosen.
+  const _ = <int>{if (true) nonInt}; //# 33: compile-time error
+
+  // Else element must have right type if branch is chosen.
+  const _ = <int>{if (false) 9 else nonInt}; //# 34: compile-time error
+
+  // Cannot override operator.==().
+  const obj = 0.1;
+  const _ = {if (true) 0.1}; //# 35: compile-time error
+  const _ = {if (true) Duration(seconds: 0)}; //# 36: compile-time error
+  const _ = {if (true) obj}; //# 37: compile-time error
+
+  // Cannot have collision when branch is chosen.
+  const _ = <int>{1, if (true) 1}; //# 38: compile-time error
+  const _ = <int>{if (true) 1, if (true) 1}; //# 39: compile-time error
+}
+
+void testShortCircuit() {
+  // A const expression that throws causes a compile error if it occurs inside
+  // the chosen branch of an if.
+
+  // Store null in a dynamically-typed constant to avoid the type error on "+".
+  const dynamic nil = null;
+
+  // With no else.
+  const _ = [if (true) nil + 1]; //# 40: compile-time error
+
+  // With else.
+  const _ = [if (true) nil + 1 else 1]; //# 41: compile-time error
+  const _ = [if (false) 1 else nil + 1]; //# 42: compile-time error
+}
diff --git a/tests/language/control_flow_collections/if_const_test.dart b/tests/language/control_flow_collections/if_const_test.dart
new file mode 100644
index 0000000..78417bc
--- /dev/null
+++ b/tests/language/control_flow_collections/if_const_test.dart
@@ -0,0 +1,238 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+// Typed as dynamic to also test spreading a value of type dynamic.
+const dynamic list = [1, 2, 3];
+const dynamic map = {1: 1, 2: 2, 3: 3};
+const dynamic set = {1, 2, 3};
+
+const dynamic dynamicTrue = true;
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testShortCircuit();
+  testDuplicateKeys();
+  testKeyOrder();
+}
+
+void testList() {
+  // Then if true.
+  Expect.identical(list, const <int>[1, if (true) 2, 3]);
+
+  // Nothing if false and no else.
+  Expect.identical(list, const <int>[1, if (false) 9, 2, 3]);
+
+  // Else if false.
+  Expect.identical(list, const <int>[1, if (false) 9 else 2, 3]);
+
+  // Only if.
+  Expect.identical(const [1], const <int>[if (true) 1]);
+
+  // If at beginning.
+  Expect.identical(list, const <int>[if (true) 1, 2, 3]);
+
+  // If in middle.
+  Expect.identical(list, const <int>[1, if (true) 2, 3]);
+
+  // If at end.
+  Expect.identical(list, const <int>[1, 2, if (true) 3]);
+
+  // Multiple ifs.
+  Expect.identical(list,
+      const <int>[if (true) 1, if (false) 9, 2, if (true) 3]);
+
+  // Cast condition.
+  Expect.identical(const [1], const <int>[if (dynamicTrue) 1]);
+
+  // Does not flatten nested collection literal.
+  Expect.identical(const [1], const [if (true) [1]].first);
+  Expect.identical(const {1: 1}, const [if (true) {1: 1}].first);
+  Expect.identical(const {1}, const [if (true) {1}].first);
+
+  // Nested spread.
+  Expect.identical(list,
+      const <int>[if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]]);
+
+  // Nested if in then.
+  Expect.identical(const [1],
+      const <int>[if (true) if (true) 1, if (true) if (false) 9]);
+
+  // Nested if in else.
+  Expect.identical(const [1], const <int>[if (false) 9 else if (true) 1]);
+}
+
+void testMap() {
+  // Then if true.
+  Expect.identical(map, const <int, int>{1: 1, if (true) 2: 2, 3: 3});
+
+  // Nothing if false and no else.
+  Expect.identical(map, const <int, int>{1: 1, if (false) 9: 9, 2: 2, 3: 3});
+
+  // Else if false.
+  Expect.identical(map,
+      const <int, int>{1: 1, if (false) 9: 9 else 2: 2, 3: 3});
+
+  // Only if.
+  Expect.identical(const {1: 1}, const <int, int>{if (true) 1: 1});
+
+  // If at beginning.
+  Expect.identical(map, const <int, int>{if (true) 1: 1, 2: 2, 3: 3});
+
+  // If in middle.
+  Expect.identical(map, const <int, int>{1: 1, if (true) 2: 2, 3: 3});
+
+  // If at end.
+  Expect.identical(map, const <int, int>{1: 1, 2: 2, if (true) 3: 3});
+
+  // Multiple ifs.
+  Expect.identical(map,
+      const <int, int>{if (true) 1: 1, if (false) 9: 9, 2: 2, if (true) 3: 3});
+
+  // Cast condition.
+  Expect.identical(const {1: 1}, const <int, int>{if (dynamicTrue) 1: 1});
+
+  // Nested spread.
+  Expect.identical(map, const <int, int>{
+    if (true) ...<int, int>{1: 1, 2: 2},
+    if (false) 9: 9 else ...<int, int>{3: 3}
+  });
+
+  // Nested if in then.
+  Expect.identical(const {1: 1},
+      const <int, int>{if (true) if (true) 1: 1, if (true) if (false) 9: 9});
+
+  // Nested if in else.
+  Expect.identical(const {1: 1},
+      const <int, int>{if (false) 9: 9 else if (true) 1: 1});
+}
+
+void testSet() {
+  // Then if true.
+  Expect.identical(set, const <int>{1, if (true) 2, 3});
+
+  // Nothing if false and no else.
+  Expect.identical(set, const <int>{1, if (false) 9, 2, 3});
+
+  // Else if false.
+  Expect.identical(set, const <int>{1, if (false) 9 else 2, 3});
+
+  // Only if.
+  Expect.identical(const <int>{1}, const <int>{if (true) 1});
+
+  // If at beginning.
+  Expect.identical(set, const <int>{if (true) 1, 2, 3});
+
+  // If in middle.
+  Expect.identical(set, const <int>{1, if (true) 2, 3});
+
+  // If at end.
+  Expect.identical(set, const <int>{1, 2, if (true) 3});
+
+  // Multiple ifs.
+  Expect.identical(set,
+      const <int>{if (true) 1, if (false) 9, 2, if (true) 3});
+
+  // Cast condition.
+  Expect.identical(const <int>{1}, const <int>{if (dynamicTrue) 1});
+
+  // Does not flatten nested collection literal.
+  Expect.identical(const <int>[1], const <List<int>>{if (true) [1]}.first);
+  Expect.identical(
+      const <int, int>{1: 1}, const <Map<int, int>>{if (true) {1: 1}}.first);
+  Expect.identical(const <int>{1}, const <Set<int>>{if (true) {1}}.first);
+
+  // Nested spread.
+  Expect.identical(set,
+      const <int>{if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]});
+
+  // Nested if in then.
+  Expect.identical(const <int>{1},
+      const <int>{if (true) if (true) 1, if (true) if (false) 9});
+
+  // Nested if in else.
+  Expect.identical(const <int>{1}, const <int>{if (false) 9 else if (true) 1});
+}
+
+void testShortCircuit() {
+  // A const expression that throws does not cause a compile error if it occurs
+  // inside an unchosen branch of an if.
+
+  // Store null in a dynamically-typed constant to avoid the type error on "+".
+  const dynamic nil = null;
+
+  Expect.identical(const <int>[1],
+      const <int>[if (true) 1, if (false) nil + 1]);
+  Expect.identical(const <int>[1, 2],
+      const <int>[if (true) 1 else nil + 1, if (false) nil + 1 else 2]);
+
+  Expect.identical(const <int, int>{1: 1}, const <int, int>{
+    if (true) 1: 1,
+    if (false) nil + 1: 9,
+    if (false) 9: nil + 1
+  });
+  Expect.identical(const <int, int>{1: 1, 2: 2}, const <int, int>{
+    if (true) 1: 1 else nil + 1: 9,
+    if (false) 9: nil + 1 else 2: 2
+  });
+
+  Expect.identical(const <int>{1},
+      const <int>{if (true) 1, if (false) nil + 1});
+  Expect.identical(const <int>{1, 2},
+      const <int>{if (true) 1 else nil + 1, if (false) nil + 1 else 2});
+
+  // A const expression whose value isn't the right type does not cause a
+  // compile error if it occurs inside an unchosen branch.
+  const dynamic nonInt = "s";
+
+  Expect.identical(const <int>[1], const <int>[if (true) 1, if (false) nonInt]);
+  Expect.identical(const <int>[1, 2],
+      const <int>[if (true) 1 else nonInt, if (false) nonInt else 2]);
+
+  Expect.identical(const <int, int>{1: 1}, const <int, int>{
+    if (true) 1: 1,
+    if (false) nonInt: 9,
+    if (false) 9: nonInt
+  });
+  Expect.identical(const <int, int>{1: 1, 2: 2}, const <int, int>{
+    if (true) 1: 1 else nonInt: 9,
+    if (false) 9: nonInt else 2: 2
+  });
+
+  Expect.identical(const <int>{1}, const <int>{if (true) 1, if (false) nonInt});
+  Expect.identical(const <int>{1, 2},
+      const <int>{if (true) 1 else nonInt, if (false) nonInt else 2});
+}
+
+void testDuplicateKeys() {
+  // Duplicate keys from unchosen branches are not an error.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    if (false) 1: 1,
+    if (true) 2: 2 else 3: 3,
+    3: 3
+  });
+
+  Expect.setEquals(set, const <int>{1, if (false) 1, if (true) 2 else 3, 3});
+}
+
+void testKeyOrder() {
+  // Canonicalization isn't affected by which elements are conditional.
+  Expect.identical(map,
+      const <int, int>{1: 1, if (true) 2: 2, if (false) 9: 9, 3: 3});
+  Expect.identical(map,
+      const <int, int>{if (false) 9: 9 else 1: 1, 2: 2, if (true) 3: 3});
+
+  Expect.identical(set, const <int>{1, if (true) 2, if (false) 9, 3});
+  Expect.identical(set, const <int>{if (false) 9 else 1, 2, if (true) 3});
+
+  // Ordering does affect canonicalization.
+  Expect.notIdentical(map, const <int, int>{1: 1, if (true) 3: 3, 2: 2});
+  Expect.notIdentical(set, const <int>{1, if (true) 3, 2});
+}
diff --git a/tests/language/control_flow_collections/if_downcast_test.dart b/tests/language/control_flow_collections/if_downcast_test.dart
new file mode 100644
index 0000000..4150456
--- /dev/null
+++ b/tests/language/control_flow_collections/if_downcast_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  var a = <int>[if (true as Object) 1];
+  //                ^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+  //                     ^
+  // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+
+  var b = <int, int>{if (true as Object) 1: 1};
+  //                     ^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+  //                          ^
+  // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+
+  var c = <int>{if (true as Object) 1};
+  //                ^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+  //                     ^
+  // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+}
diff --git a/tests/language/control_flow_collections/if_dynamic_null_strong_test.dart b/tests/language/control_flow_collections/if_dynamic_null_strong_test.dart
new file mode 100644
index 0000000..0450c0b
--- /dev/null
+++ b/tests/language/control_flow_collections/if_dynamic_null_strong_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic nullBool;
+  Expect.throwsTypeError(() => <int>[if (nullBool) 1]);
+  Expect.throwsTypeError(() => <int, int>{if (nullBool) 1: 1});
+  Expect.throwsTypeError(() => <int>{if (nullBool) 1});
+}
diff --git a/tests/language/control_flow_collections/if_dynamic_null_weak_test.dart b/tests/language/control_flow_collections/if_dynamic_null_weak_test.dart
new file mode 100644
index 0000000..4e76cf3
--- /dev/null
+++ b/tests/language/control_flow_collections/if_dynamic_null_weak_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic nullBool;
+  Expect.throwsAssertionError(() => <int>[if (nullBool) 1]);
+  Expect.throwsAssertionError(() => <int, int>{if (nullBool) 1: 1});
+  Expect.throwsAssertionError(() => <int>{if (nullBool) 1});
+}
diff --git a/tests/language/control_flow_collections/if_inference_test.dart b/tests/language/control_flow_collections/if_inference_test.dart
new file mode 100644
index 0000000..11c7b95
--- /dev/null
+++ b/tests/language/control_flow_collections/if_inference_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test how control flow interacts with inference.
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+void main() {
+  testBottomUpInference();
+  testTopDownInference();
+}
+
+void testBottomUpInference() {
+  // Lists.
+  expectListOf<int>([if (true) 1]);
+  expectListOf<int>([if (true) 1 else 2]);
+  expectListOf<num>([if (true) 1 else 0.2]);
+  expectListOf<int>([if (true) 1, 2]);
+  expectListOf<num>([if (true) 1, 0.2]);
+  expectListOf<dynamic>([if (true) ...[]]);
+  expectListOf<int>([if (true) ...<int>[]]);
+
+  // Maps.
+  expectMapOf<int, int>({if (true) 1: 1});
+  expectMapOf<int, int>({if (true) 1: 1 else 2: 2});
+  expectMapOf<num, num>({if (true) 1: 0.1 else 0.2: 2});
+  expectMapOf<int, int>({if (true) 1: 1, 2: 2});
+  expectMapOf<num, num>({if (true) 1: 0.1, 0.2: 2});
+  expectMapOf<dynamic, dynamic>({if (true) ...{}});
+  expectMapOf<int, int>({if (true) ...<int, int>{}});
+
+  // Sets.
+  expectSetOf<int>({if (true) 1});
+  expectSetOf<int>({if (true) 1 else 2});
+  expectSetOf<num>({if (true) 1 else 0.2});
+  expectSetOf<int>({if (true) 1, 2});
+  expectSetOf<num>({if (true) 1, 0.2});
+  expectSetOf<dynamic>({if (true) ...[]});
+  expectSetOf<int>({if (true) ...<int>[]});
+
+  // If a nested iterable's type is dynamic, the element type is dynamic.
+  expectListOf<dynamic>([if (true) ...([] as dynamic)]);
+  expectSetOf<dynamic>({1, if (true) ...([] as dynamic)});
+
+  // If a nested maps's type is dynamic, the key and value types are dynamic.
+  expectMapOf<dynamic, dynamic>({1: 1, if (true) ...({} as dynamic)});
+}
+
+void testTopDownInference() {
+  // Lists.
+
+  // The context element type is pushed into the branches.
+  Expect.listEquals(<int>[1], <int>[if (true) expectInt(1)]);
+  Expect.listEquals(<int>[1], <int>[if (false) 9 else expectInt(1)]);
+
+  // Bottom up-inference from elements is not pushed back down into branches.
+  Expect.listEquals(<int>[1, 2], [1, if (true) expectDynamic(2)]);
+  Expect.listEquals(<int>[1, 2], [1, if (false) 9 else expectDynamic(2)]);
+
+  // Maps.
+
+  // The context element type is pushed into the branches.
+  Expect.mapEquals(<int, String>{1: "s"},
+      <int, String>{if (true) expectInt(1): expectString("s")});
+
+  // Bottom up-inference from elements is not pushed back down into branches.
+  Expect.mapEquals(<int, String>{1: "s", 2: "t"},
+      {1: "s", if (true) expectDynamic(2): expectDynamic("t")});
+
+  // Sets.
+
+  // The context element type is pushed into the branches.
+  Expect.setEquals(<int>{1}, <int>{if (true) expectInt(1)});
+  Expect.setEquals(<int>{1}, <int>{if (false) 9 else expectInt(1)});
+
+  // Bottom up-inference from elements is not pushed back down into branches.
+  Expect.setEquals(<int>{1, 2}, {1, if (true) expectDynamic(2)});
+  Expect.setEquals(<int>{1, 2}, {1, if (false) 9 else expectDynamic(2)});
+}
diff --git a/tests/language/control_flow_collections/if_null_condition_test.dart b/tests/language/control_flow_collections/if_null_condition_test.dart
new file mode 100644
index 0000000..667c6bd
--- /dev/null
+++ b/tests/language/control_flow_collections/if_null_condition_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  bool? nullBool;
+  var a = <int>[if (nullBool) 1];
+  //                ^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] A value of type 'bool?' can't be assigned to a variable of type 'bool'.
+
+  var b = <int, int>{if (nullBool) 1: 1};
+  //                     ^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] A value of type 'bool?' can't be assigned to a variable of type 'bool'.
+
+  var c = <int>{if (nullBool) 1};
+  //                ^^^^^^^^
+  // [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe] A value of type 'bool?' can't be assigned to a variable of type 'bool'.
+}
diff --git a/tests/language/control_flow_collections/if_promotion_test.dart b/tests/language/control_flow_collections/if_promotion_test.dart
new file mode 100644
index 0000000..382db01
--- /dev/null
+++ b/tests/language/control_flow_collections/if_promotion_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  var a = "a";
+}
+
+class B extends A {
+  var b = "b";
+}
+
+class C extends B {
+  var c = "c";
+}
+
+void main() {
+  A a = A();
+  print(a.a);
+  print(a.b); //# 01: compile-time error
+
+  var list = [
+    a.a,
+    a.b, //# 02: compile-time error
+    a.c, //# 03: compile-time error
+
+    if (a is B) [
+      a.a,
+      a.b,
+      a.c, //# 04: compile-time error
+
+      if (a is C) [
+        a.a,
+        a.b,
+        a.c,
+      ] else [
+        a.a,
+        a.b,
+        a.c, //# 05: compile-time error
+      ],
+
+      a.a,
+      a.b,
+      a.c, //# 06: compile-time error
+    ] else [
+      a.a,
+      a.b, //# 07: compile-time error
+      a.c, //# 08: compile-time error
+    ],
+
+    a.a,
+    a.b, //# 09: compile-time error
+    a.c, //# 10: compile-time error
+  ];
+}
diff --git a/tests/language/control_flow_collections/if_runtime_error_test.dart b/tests/language/control_flow_collections/if_runtime_error_test.dart
new file mode 100644
index 0000000..1dba5b8
--- /dev/null
+++ b/tests/language/control_flow_collections/if_runtime_error_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic nonBool = 3;
+  Expect.throwsTypeError(() => <int>[if (nonBool) 1]);
+  Expect.throwsTypeError(() => <int, int>{if (nonBool) 1: 1});
+  Expect.throwsTypeError(() => <int>{if (nonBool) 1});
+}
diff --git a/tests/language/control_flow_collections/if_test.dart b/tests/language/control_flow_collections/if_test.dart
new file mode 100644
index 0000000..6113823
--- /dev/null
+++ b/tests/language/control_flow_collections/if_test.dart
@@ -0,0 +1,225 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+import 'utils.dart';
+
+final list = [1, 2, 3];
+final map = {1: 1, 2: 2, 3: 3};
+final set = {1, 2, 3};
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testShortCircuit();
+  testDuplicateKeys();
+  testKeyOrder();
+}
+
+void testList() {
+  // Then if true.
+  Expect.listEquals(list, <int>[1, if (true) 2, 3]);
+
+  // Nothing if false and no else.
+  Expect.listEquals(list, <int>[1, if (false) 9, 2, 3]);
+
+  // Else if false.
+  Expect.listEquals(list, <int>[1, if (false) 9 else 2, 3]);
+
+  // Only if.
+  Expect.listEquals([1], <int>[if (true) 1]);
+
+  // If at beginning.
+  Expect.listEquals(list, <int>[if (true) 1, 2, 3]);
+
+  // If in middle.
+  Expect.listEquals(list, <int>[1, if (true) 2, 3]);
+
+  // If at end.
+  Expect.listEquals(list, <int>[1, 2, if (true) 3]);
+
+  // Multiple ifs.
+  Expect.listEquals(list,
+      <int>[if (true) 1, if (false) 9, 2, if (true) 3]);
+
+  // Cast condition.
+  Expect.listEquals(<int>[1], <int>[if (true as dynamic) 1]);
+
+  // Does not flatten nested collection literal.
+  Expect.listEquals([1], [if (true) [1]].first);
+  Expect.mapEquals({1: 1}, [if (true) {1: 1}].first);
+  Expect.setEquals({1}, [if (true) {1}].first);
+
+  // Nested spread.
+  Expect.listEquals(list,
+      <int>[if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]]);
+
+  // Nested if in then.
+  Expect.listEquals([1], <int>[if (true) if (true) 1, if (true) if (false) 9]);
+
+  // Nested if in else.
+  Expect.listEquals([1], <int>[if (false) 9 else if (true) 1]);
+
+  // Nested for in then.
+  Expect.listEquals(list, <int>[if (true) for (var i in list) i]);
+
+  // Nested for in else.
+  Expect.listEquals(list, <int>[if (false) 9 else for (var i in list) i]);
+}
+
+void testMap() {
+  // Then if true.
+  Expect.mapEquals(map, <int, int>{1: 1, if (true) 2: 2, 3: 3});
+
+  // Nothing if false and no else.
+  Expect.mapEquals(map, <int, int>{1: 1, if (false) 9: 9, 2: 2, 3: 3});
+
+  // Else if false.
+  Expect.mapEquals(map, <int, int>{1: 1, if (false) 9: 9 else 2: 2, 3: 3});
+
+  // Only if.
+  Expect.mapEquals(<int, int>{1: 1}, <int, int>{if (true) 1: 1});
+
+  // If at beginning.
+  Expect.mapEquals(map, <int, int>{if (true) 1: 1, 2: 2, 3: 3});
+
+  // If in middle.
+  Expect.mapEquals(map, <int, int>{1: 1, if (true) 2: 2, 3: 3});
+
+  // If at end.
+  Expect.mapEquals(map, <int, int>{1: 1, 2: 2, if (true) 3: 3});
+
+  // Multiple ifs.
+  Expect.mapEquals(map,
+      <int, int>{if (true) 1: 1, if (false) 9: 9, 2: 2, if (true) 3: 3});
+
+  // Cast condition.
+  Expect.mapEquals(<int, int>{1: 1}, <int, int>{if (true as dynamic) 1: 1});
+
+  // Nested spread.
+  Expect.mapEquals(map, <int, int>{
+    if (true) ...<int, int>{1: 1, 2: 2},
+    if (false) 9: 9 else ...<int, int>{3: 3}
+  });
+
+  // Nested if in then.
+  Expect.mapEquals({1: 1},
+      <int, int>{if (true) if (true) 1: 1, if (true) if (false) 9: 9});
+
+  // Nested if in else.
+  Expect.mapEquals({1: 1},
+      <int, int>{if (false) 9: 9 else if (true) 1: 1});
+
+  // Nested for in then.
+  Expect.mapEquals(map, <int, int>{if (true) for (var i in list) i: i});
+
+  // Nested for in else.
+  Expect.mapEquals(map, <int, int>{if (false) 9: 9 else for (var i in list) i: i});
+}
+
+void testSet() {
+  // Then if true.
+  Expect.setEquals(set, <int>{1, if (true) 2, 3});
+
+  // Nothing if false and no else.
+  Expect.setEquals(set, <int>{1, if (false) 9, 2, 3});
+
+  // Else if false.
+  Expect.setEquals(set, <int>{1, if (false) 9 else 2, 3});
+
+  // Only if.
+  Expect.setEquals({1}, <int>{if (true) 1});
+
+  // If at beginning.
+  Expect.setEquals(set, <int>{if (true) 1, 2, 3});
+
+  // If in middle.
+  Expect.setEquals(set, <int>{1, if (true) 2, 3});
+
+  // If at end.
+  Expect.setEquals(set, <int>{1, 2, if (true) 3});
+
+  // Multiple ifs.
+  Expect.setEquals(set,
+      <int>{if (true) 1, if (false) 9, 2, if (true) 3});
+
+  // Cast condition.
+  Expect.setEquals({1}, <int>{if (true as dynamic) 1});
+
+  // Does not flatten nested collection literal.
+  Expect.listEquals([1], {if (true) [1]}.first);
+  Expect.mapEquals({1: 1}, {if (true) {1: 1}}.first);
+  Expect.setEquals({1}, {if (true) {1}}.first);
+
+  // Nested spread.
+  Expect.setEquals(set,
+      <int>{if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]});
+
+  // Nested if in then.
+  Expect.setEquals({1}, <int>{if (true) if (true) 1, if (true) if (false) 9});
+
+  // Nested if in else.
+  Expect.setEquals({1}, <int>{if (false) 9 else if (true) 1});
+
+  // Nested for in then.
+  Expect.setEquals(set, <int>{if (true) for (var i in list) i});
+
+  // Nested for in else.
+  Expect.setEquals(set, <int>{if (false) 9 else for (var i in list) i});
+}
+
+void testShortCircuit() {
+  var transcript = <String>[];
+  T log<T>(T value) {
+    transcript.add(value.toString());
+    return value;
+  }
+
+  // With no else.
+  Expect.listEquals([1], [if (true) log(1), if (false) log(2)]);
+  Expect.equals("1", transcript.join(","));
+  transcript.clear();
+
+  // With else.
+  Expect.listEquals([1, 4],
+      [if (true) log(1) else log(2), if (false) log(3) else log(4)]);
+  Expect.equals("1,4", transcript.join(","));
+}
+
+void testDuplicateKeys() {
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    if (true) 1: 1,
+    if (false) 9: 9 else 2: 2,
+    2: 2,
+    3: 3
+  });
+  Expect.setEquals(set, <int>{1, if (true) 1, if (false) 9 else 2, 2, 3});
+}
+
+void testKeyOrder() {
+  // First equal key wins.
+  var e1a = Equality(1, "a");
+  var e1b = Equality(1, "b");
+  var e2a = Equality(2, "a");
+  var e2b = Equality(2, "b");
+
+  var map = <Equality, int>{
+    e1a: 0,
+    if (true) e1b: 0,
+    if (true) e2a: 0,
+    if (true) e2b: 0
+  };
+  Expect.equals("1:a,2:a", map.keys.join(","));
+
+  var set = <Equality>{
+    e1a,
+    if (true) e1b,
+    if (true) e2a,
+    if (true) e2b
+  };
+  Expect.equals("1:a,2:a", set.join(","));
+}
diff --git a/tests/language/control_flow_collections/map_set_ambiguity_error_test.dart b/tests/language/control_flow_collections/map_set_ambiguity_error_test.dart
new file mode 100644
index 0000000..ae4fee4
--- /dev/null
+++ b/tests/language/control_flow_collections/map_set_ambiguity_error_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test cases where the syntax is ambiguous between maps and sets when control
+// flow elements contain spreads.
+import 'dart:collection';
+
+import 'utils.dart';
+
+void main() {
+  Map<int, int> map = {};
+  Set<int> set = Set();
+  dynamic dyn = map;
+  Iterable<int> iterable = [];
+  CustomSet customSet = CustomSet();
+  CustomMap customMap = CustomMap();
+
+  var _ = {if (true) ...dyn}; //# 00: compile-time error
+  var _ = {if (true) ...map else ...set}; //# 01: compile-time error
+  var _ = {if (true) ...map else ...iterable}; //# 02: compile-time error
+  var _ = {if (true) ...map else ...customSet}; //# 03: compile-time error
+  var _ = {if (true) ...set else ...customMap}; //# 04: compile-time error
+  var _ = {if (true) ...dyn else ...dyn}; //# 05: compile-time error
+  var _ = {if (true) ...iterable else ...customMap}; //# 06: compile-time error
+  var _ = {if (true) ...customSet else ...customMap}; //# 07: compile-time error
+
+  var _ = {for (; false;) ...dyn}; //# 08: compile-time error
+  var _ = {for (; false;) ...map, ...set}; //# 09: compile-time error
+  var _ = {for (; false;) ...map, ...iterable}; //# 10: compile-time error
+  var _ = {for (; false;) ...map, ...customSet}; //# 11: compile-time error
+  var _ = {for (; false;) ...set, ...customMap}; //# 12: compile-time error
+  var _ = {for (; false;) ...dyn, ...dyn}; //# 13: compile-time error
+  var _ = {for (; false;) ...iterable, ...customMap}; //# 14: compile-time error
+  var _ = {for (; false;) ...customSet, ...customMap}; //# 15: compile-time error
+}
diff --git a/tests/language/control_flow_collections/map_set_ambiguity_test.dart b/tests/language/control_flow_collections/map_set_ambiguity_test.dart
new file mode 100644
index 0000000..bf5f685
--- /dev/null
+++ b/tests/language/control_flow_collections/map_set_ambiguity_test.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test cases where the syntax is ambiguous between maps and sets because of
+// spreads inside control flow.
+import 'dart:collection';
+
+import 'utils.dart';
+
+void main() {
+  testBottomUpInference();
+  testTopDownInference();
+}
+
+void testBottomUpInference() {
+  Map<int, int> map = {};
+  Set<int> set = Set();
+  dynamic dynMap = map;
+  dynamic dynSet = set;
+  Iterable<int> iterable = [];
+  CustomSet customSet = CustomSet();
+  CustomMap customMap = CustomMap();
+
+  // Note: The commented out cases are the error cases. They are shown here for
+  // completeness and tested in map_set_ambiguity_error_test.dart.
+  expectMapOf<int, int>({if (true) ...map});
+  expectSetOf<int>({if (true) ...set});
+  // expect___Of<...>({if (true) ...dyn});
+  expectSetOf<int>({if (true) ...iterable});
+  expectSetOf<int>({if (true) ...customSet});
+  expectMapOf<int, String>({if (true) ...customMap});
+
+  expectMapOf<int, int>({if (true) ...map else ...map});
+  // expect___Of<...>({if (true) ...map else ...set});
+  expectMapOf<dynamic, dynamic>({if (true) ...map else ...dynMap});
+  // expect___Of<...>({if (true) ...map else ...iterable});
+  // expect___Of<...>({if (true) ...map else ...customSet});
+  expectMapOf<int, Object>({if (true) ...map else ...customMap});
+
+  expectSetOf<int>({if (true) ...set else ...set});
+  expectSetOf<dynamic>({if (true) ...set else ...dynSet});
+  expectSetOf<int>({if (true) ...set else ...iterable});
+  expectSetOf<int>({if (true) ...set else ...customSet});
+  // expect___Of<...>({if (true) ...set else ...customMap});
+
+  // expect___Of<...>({if (true) ...dyn else ...dyn});
+  expectSetOf<dynamic>({if (true) ...dynSet else ...iterable});
+  expectSetOf<dynamic>({if (true) ...dynSet else ...customSet});
+  expectMapOf<dynamic, dynamic>({if (true) ...dynMap else ...customMap});
+
+  expectSetOf<int>({if (true) ...iterable else ...iterable});
+  expectSetOf<int>({if (true) ...iterable else ...customSet});
+  // expect___Of<...>({if (true) ...iterable else ...customMap});
+
+  expectSetOf<int>({if (true) ...customSet else ...customSet});
+  // expect___Of<...>({if (true) ...customSet else ...customMap});
+
+  expectMapOf<int, String>({if (true) ...customMap else ...customMap});
+
+  // Note: The commented out cases are the error cases. They are shown here for
+  // completeness and tested in map_set_ambiguity_error_test.dart.
+  expectMapOf<int, int>({for (; false;) ...map});
+  expectSetOf<int>({for (; false;) ...set});
+  // expect___Of<...>({for (; false;) ...dyn});
+  expectSetOf<int>({for (; false;) ...iterable});
+  expectSetOf<int>({for (; false;) ...customSet});
+  expectMapOf<int, String>({for (; false;) ...customMap});
+
+  expectMapOf<int, int>({for (; false;) ...map, for (; false;) ...map});
+  // expect___Of<...>({for (; false;) ...map, for (; false;) ...set});
+  expectMapOf<dynamic, dynamic>(
+      {for (; false;) ...map, for (; false;) ...dynMap});
+  // expect___Of<...>({for (; false;) ...map, for (; false;) ...iterable});
+  // expect___Of<...>({for (; false;) ...map, for (; false;) ...customSet});
+  expectMapOf<int, Object>(
+      {for (; false;) ...map, for (; false;) ...customMap});
+
+  expectSetOf<int>({for (; false;) ...set, for (; false;) ...set});
+  expectSetOf<dynamic>({for (; false;) ...set, for (; false;) ...dynSet});
+  expectSetOf<int>({for (; false;) ...set, for (; false;) ...iterable});
+  expectSetOf<int>({for (; false;) ...set, for (; false;) ...customSet});
+  // expect___Of<...>({for (; false;) ...set, for (; false;) ...customMap});
+
+  // expect___Of<...>({for (; false;) ...dyn, for (; false;) ...dyn});
+  expectSetOf<dynamic>(
+      {for (; false;) ...dynSet, for (; false;) ...iterable});
+  expectSetOf<dynamic>(
+      {for (; false;) ...dynSet, for (; false;) ...customSet});
+  expectMapOf<dynamic, dynamic>(
+      {for (; false;) ...dynMap, for (; false;) ...customMap});
+
+  expectSetOf<int>(
+      {for (; false;) ...iterable, for (; false;) ...iterable});
+  expectSetOf<int>(
+      {for (; false;) ...iterable, for (; false;) ...customSet});
+  // expect___Of<...>(
+  //     {for (; false;) ...iterable, for (; false;) ...customMap});
+
+  expectSetOf<int>(
+      {for (; false;) ...customSet, for (; false;) ...customSet});
+  // expect___Of<...>(
+  //     {for (; false;) ...customSet, for (; false;) ...customMap});
+
+  expectMapOf<int, String>(
+      {for (; false;) ...customMap, for (; false;) ...customMap});
+}
+
+void testTopDownInference() {
+  dynamic untypedMap = <int, int>{};
+  dynamic untypedIterable = <int>[];
+
+  Map<int, int> map = {if (true) ...untypedMap};
+  Set<int> set = {if (true) ...untypedIterable};
+  Iterable<int> iterable = {if (true) ...untypedIterable};
+
+  expectMapOf<int, int>(map);
+  expectSetOf<int>(set);
+  expectSetOf<int>(iterable);
+
+  map = {for (; false;) ...untypedMap};
+  set = {for (; false;) ...untypedIterable};
+  iterable = {for (; false;) ...untypedIterable};
+
+  expectMapOf<int, int>(map);
+  expectSetOf<int>(set);
+  expectSetOf<int>(iterable);
+}
diff --git a/tests/language/control_flow_collections/syntax_error_test.dart b/tests/language/control_flow_collections/syntax_error_test.dart
new file mode 100644
index 0000000..8b9fa65
--- /dev/null
+++ b/tests/language/control_flow_collections/syntax_error_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+void main() {
+  // No then element.
+  var _ = [if (true)]; //# 00: syntax error
+
+  // No then element with else.
+  var _ = [if (true) else 0]; //# 01: syntax error
+
+  // No else element.
+  var _ = [if (true) 0 else]; //# 02: syntax error
+
+  // Spread if.
+  var _ = [...if (true) 0]; //# 03: syntax error
+
+  // Spread for.
+  var _ = [...for (; false;) 0]; //# 04: syntax error
+
+  // Use if in map entry.
+  var _ = {if (true) 1: 1: 2}; //# 05: syntax error
+  var _ = {1: if (true) 2: 2}; //# 06: syntax error
+
+  // Use for in map entry.
+  var _ = {for (; false;) 1: 1: 2}; //# 07: syntax error
+  var _ = {1: for (; false;) 2: 2}; //# 08: syntax error
+
+  // Use for variable out of scope.
+  var _ = [for (var i = 0; false;) 1, i]; //# 09: compile-time error
+
+  // Use for-in variable out of scope.
+  var _ = [for (var i in [1]; false;) 1, i]; //# 10: syntax error
+
+  // Use for variable in own initializer.
+  var _ = [for (var i = i; false;) 1]; //# 11: compile-time error
+
+  // Use for-in variable in own initializer.
+  var _ = [for (var i in [i]) 1]; //# 12: compile-time error
+}
diff --git a/tests/language/control_flow_collections/syntax_test.dart b/tests/language/control_flow_collections/syntax_test.dart
new file mode 100644
index 0000000..0ed9829
--- /dev/null
+++ b/tests/language/control_flow_collections/syntax_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests syntax edge cases.
+import 'package:expect/expect.dart';
+
+void main() {
+  // Trailing comma after then.
+  Expect.listEquals([1], [if (true) 1,]);
+  Expect.mapEquals({1: 1}, {if (true) 1: 1,});
+  Expect.setEquals({1}, {if (true) 1,});
+
+  // Trailing comma after else.
+  Expect.listEquals([1], [if (true) 1 else 2,]);
+  Expect.mapEquals({1: 1}, {if (true) 1: 1 else 2: 2,});
+  Expect.setEquals({1}, {if (true) 1 else 2,});
+
+  // Trailing comma after for.
+  Expect.listEquals([1], [1, for (; false;) 2,]);
+  Expect.mapEquals({1: 1}, {1: 1, for (; false;) 2: 2,});
+  Expect.setEquals({1}, {1, for (; false;) 2,});
+
+  // Dangling else.
+  Expect.listEquals([1], [if (true) if (false) 0 else 1]);
+  Expect.listEquals([1], [if (true) if (false) 0 else 1 else 2]);
+  Expect.listEquals([2], [if (false) if (false) 0 else 1 else 2]);
+
+  // Precedence of then.
+  Expect.listEquals([1, 2, 3], [1, if (true) true ? 2 : 0, 3]);
+  var a = 0;
+  Expect.listEquals([1, 2, 3], [1, if (true) a = 2, 3]);
+
+  // Precedence of else.
+  Expect.listEquals([1, 2, 3], [1, if (false) 0 else true ? 2 : 0, 3]);
+  a = 0;
+  Expect.listEquals([1, 2, 3], [1, if (false) 0 else a = 2, 3]);
+
+  // Precedence of for.
+  Expect.listEquals([1, 2, 3],
+      [1, for (var i = 0; i < 1; i++) true ? 2 : 0, 3]);
+  a = 0;
+  Expect.listEquals([1, 2, 3], [1, for (var i = 0; i < 1; i++) a = 2, 3]);
+}
diff --git a/tests/language/control_flow_collections/type_error_test.dart b/tests/language/control_flow_collections/type_error_test.dart
new file mode 100644
index 0000000..63f6706
--- /dev/null
+++ b/tests/language/control_flow_collections/type_error_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+void main() {
+  // Non-Boolean if condition.
+  var _ = <int>[if (1) 2]; //# 00: compile-time error
+  var _ = <int, int>{if (1) 2: 2}; //# 01: compile-time error
+  var _ = <int>{if (1) 2}; //# 02: compile-time error
+
+  // Wrong then element type.
+  var _ = <int>[if (true) "s"]; //# 04: compile-time error
+  var _ = <int, int>{if (true) "s": 1}; //# 05: compile-time error
+  var _ = <int, int>{if (true) 1: "s"}; //# 06: compile-time error
+  var _ = <int>{if (true) "s"}; //# 07: compile-time error
+
+  // Wrong else element type.
+  var _ = <int>[if (false) 1 else "s"]; //# 08: compile-time error
+  var _ = <int, int>{if (false) 1: 1 else "s": 2}; //# 09: compile-time error
+  var _ = <int, int>{if (false) 1: 1 else 2: "s"}; //# 10: compile-time error
+  var _ = <int>{if (false) 1 else "s"}; //# 11: compile-time error
+
+  // Non-Boolean for condition.
+  var _ = <int>[for (; 1;) 2]; //# 12: compile-time error
+  var _ = <int, int>{for (; 1;) 2: 2}; //# 13: compile-time error
+  var _ = <int>{for (; 1;) 2}; //# 14: compile-time error
+
+  // Wrong for-in element type.
+  List<String> s = ["s"];
+  var _ = <int>[for (int i in s) 1]; //# 15: compile-time error
+  var _ = <int, int>{for (int i in s) 1: 1}; //# 16: compile-time error
+  var _ = <int>{for (int i in s) 1}; //# 17: compile-time error
+
+  // Wrong for declaration element type.
+  var _ = <int>[for (int i = "s"; false;) 1]; //# 18: compile-time error
+  var _ = <int, int>{for (int i = "s"; false;) 1: 1}; //# 19: compile-time error
+  var _ = <int>{for (int i = "s"; false;) 1}; //# 20: compile-time error
+
+  // Wrong for body element type.
+  var _ = <int>[for (; false;) "s"]; //# 21: compile-time error
+  var _ = <int, int>{for (; false;) "s": 1}; //# 22: compile-time error
+  var _ = <int, int>{for (; false;) 1: "s"}; //# 23: compile-time error
+  var _ = <int>{for (; false;) "s"}; //# 24: compile-time error
+
+  // Non-iterable sequence type.
+  int nonIterable = 3;
+  var _ = <int>[for (int i in nonIterable) 1]; //# 25: compile-time error
+  var _ = <int, int>{for (int i in nonIterable) 1: 1}; //# 26: compile-time error
+  var _ = <int>{for (int i in nonIterable) 1}; //# 27: compile-time error
+}
diff --git a/tests/language/control_flow_collections/utils.dart b/tests/language/control_flow_collections/utils.dart
new file mode 100644
index 0000000..c8e5dc8
--- /dev/null
+++ b/tests/language/control_flow_collections/utils.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:expect/expect.dart';
+
+class CustomMap with MapMixin<int, String> {
+  Iterable<int> get keys => [];
+  String? operator [](Object? key) => "";
+  operator []=(int key, String value) {}
+  String remove(Object? key) => throw UnsupportedError("unsupported");
+  void clear() => throw UnsupportedError("unsupported");
+}
+
+class CustomSet extends SetBase<int> {
+  bool add(int value) => throw UnsupportedError("unsupported");
+  bool contains(Object? value) => throw UnsupportedError("unsupported");
+  Iterator<int> get iterator => <int>[].iterator;
+  int get length => 0;
+  int? lookup(Object? value) => throw UnsupportedError("unsupported");
+  bool remove(Object? value) => throw UnsupportedError("unsupported");
+  Set<int> toSet() => this;
+}
+
+class Equality {
+  final int id;
+  final String name;
+  const Equality(this.id, this.name);
+  int get hashCode => id;
+  bool operator ==(Object other) => other is Equality && id == other.id;
+  String toString() => "$id:$name";
+}
+
+T expectDynamic<T>(dynamic value) {
+  Expect.equals(dynamic, T);
+  return value;
+}
+
+T expectInt<T>(dynamic value) {
+  Expect.equals(int, T);
+  return value;
+}
+
+T expectString<T>(dynamic value) {
+  Expect.equals(String, T);
+  return value;
+}
+
+Iterable<T> expectIntIterable<T>(dynamic value) {
+  Expect.equals(int, T);
+  return value;
+}
+
+Set<T> expectIntSet<T>() {
+  Expect.equals(int, T);
+  return Set();
+}
+
+Stream<T> expectIntStream<T>(dynamic elements) {
+  Expect.equals(int, T);
+  return Stream<T>.fromIterable(elements);
+}
+
+Set<T> expectDynamicSet<T>() {
+  Expect.equals(dynamic, T);
+  return Set();
+}
+
+/// Hacky way of testing the inferred generic type arguments of [object].
+///
+/// [Expect.type()] only performs a subtype test, which means that it will
+/// return `true` when asked if a `List<int>` is a `List<num>` or
+/// `List<dynamic>`. For inference, we want to test the type more precisely.
+///
+/// There isn't a good way to do that in tests yet so, for now, we just see if
+/// the runtime type contains the given type argument string.
+// TODO(rnystrom): Do something less horribly brittle.
+void _expectTypeArguments(String typeArguments, Object object) {
+  var typeName = object.runtimeType.toString();
+
+  // If an implementation prints dynamic instantiations like a raw type,
+  // handle that.
+  if (!typeName.contains("<") &&
+      (typeArguments == "dynamic" || typeArguments == "dynamic, dynamic")) {
+    return;
+  }
+
+  if (!typeName.contains("<$typeArguments>")) {
+    Expect.fail("Object should have had generic type '<$typeArguments>', "
+        "but was '$typeName'.");
+  }
+}
+
+void expectListOf<T>(Object object) {
+  Expect.type<List>(object);
+  _expectTypeArguments(T.toString(), object);
+}
+
+void expectSetOf<T>(Object object) {
+  Expect.type<Set>(object);
+  _expectTypeArguments(T.toString(), object);
+}
+
+void expectMapOf<K, V>(Object object) {
+  Expect.type<Map>(object);
+  _expectTypeArguments("$K, $V", object);
+}
diff --git a/tests/language/covariant/covariant_test.dart b/tests/language/covariant/covariant_test.dart
new file mode 100644
index 0000000..2ccc708
--- /dev/null
+++ b/tests/language/covariant/covariant_test.dart
@@ -0,0 +1,431 @@
+// 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.
+
+// Test that `covariant` can be parsed (and ignored) by
+// dart2js and the VM.
+// This test only checks for non-strong mode behavior.
+//
+// Generally, `covariant` should be ignored, when it is used in the right
+// places.
+
+import 'package:expect/expect.dart';
+
+// Top level field may not have a covariant.
+// Would be considered a minor (acceptable) bug, if it was accepted here too.
+covariant // //# 00: syntax error
+int x0 = 0;
+
+covariant int covariant = 0; // //# 00b: syntax error
+
+int covariant = 0; // //# 00c: ok
+
+// Getters may never have `covariant`. (Neither on the top-level nor as members)
+covariant // //# 01: syntax error
+int get x1 => 499;
+
+// Top level setters may not have a covariant.
+// Would be considered a minor (acceptable) bug, if it was accepted here too.
+void set x2(
+    covariant //# 02: compile-time error
+    int val) {}
+
+// Same as above, but with `covariant` in different positions.
+// The `covariant` is just wrong there.
+
+int
+covariant // //# 03: syntax error
+    x3 = 0;
+
+int
+covariant // //# 04: syntax error
+    get x4 => 499;
+
+void set x5(
+    int
+    covariant //# 05: syntax error
+        val) {}
+
+// Same without types.
+
+// Since `covariant` is a built-in identifier, it is not allowed here.
+covariant x6; // //# 06: syntax error
+
+covariant covariant; // //# 06b: syntax error
+
+// Getters may never have `covariant`.
+covariant // //# 07: syntax error
+get x7 => 499;
+
+// Top level setters may not have a covariant.
+// Would be considered a minor (acceptable) bug, if it was accepted here too.
+void set x8(
+    covariant //# 08: compile-time error
+    val) {}
+
+// If there is no type, then `covariant` is simply the parameter name:
+void set x9(covariant) {}
+
+// Covariant won't work on return types.
+covariant // //# 10: syntax error
+int f10() => 499;
+
+// Covariant won't work as a return type.
+covariant // //# 11: syntax error
+f11() => 499;
+
+// Covariant should not work on top-level methods.
+// It's a minor (acceptable) bug to not error out here.
+int f12(
+    covariant //# 12: compile-time error
+        int x) =>
+    499;
+
+// `Covariant` must be in front of the types.
+int f13(
+        int
+    covariant //# 13: syntax error
+            x) =>
+    499;
+
+// Covariant should not work on top-level methods.
+// It's a minor (acceptable) bug to not error out here.
+int f14(
+    covariant //# 14: compile-time error
+        final x) =>
+    499;
+
+// `Covariant` must be in front of modifiers.
+int f15(
+        final
+    covariant //# 15: syntax error
+            x) =>
+    499;
+
+// Covariant should not work on top-level methods.
+// It's a minor (acceptable) bug to not error out here.
+int f16(
+    covariant //# 16: compile-time error
+        final int x) =>
+    499;
+
+// `Covariant` must be in front of modifiers.
+int f17(
+        final
+    covariant //# 17: syntax error
+            int
+            x) =>
+    499;
+
+// On its own, `covariant` is just a parameter name.
+int f18(covariant) => covariant;
+
+covariant; // //# 19: syntax error
+
+// All of the above as statics in a class.
+class A {
+  // Static fields may not have a covariant.
+  // Would be considered a minor (acceptable) bug, if it was accepted here too.
+  static
+  covariant // //# 20: syntax error
+      int x20 = 0;
+
+  static covariant int covariant = 0; // //# 20b: syntax error
+
+  static int covariant = 0; // //# 20c: ok
+
+  // Getters may never have `covariant`.
+  static
+  covariant // //# 21: syntax error
+      int get x21 => 499;
+
+  // Getters may never have `covariant`.
+  covariant // //# 21b: syntax error
+  static int get x21b => 499;
+
+  // Static setters may not have a covariant.
+  // Would be considered a minor (acceptable) bug, if it was accepted here too.
+  static void set x22(
+      covariant //# 22: compile-time error
+      int val) {}
+
+  // Same as above, but with `covariant` in different positions.
+  // The `covariant` is just wrong there.
+
+  static int
+  covariant // //# 23: syntax error
+      x23 = 0;
+
+  static int
+  covariant // //# 24: syntax error
+      get x24 => 499;
+
+  static void set x25(
+      int
+    covariant //# 25: syntax error
+          val) {}
+
+  // Since `covariant` is a built-in identifier, it is not allowed here.
+  static covariant x26; //# 26: syntax error
+  static covariant covariant; //# 26b: syntax error
+
+  // Getters may never have `covariant`.
+  static
+  covariant // //# 27: syntax error
+      get x27 => 499;
+
+  covariant // //# 27b: syntax error
+  static get x27b => 499;
+
+  // Static setters may not have a covariant.
+  // Would be considered a minor (acceptable) bug, if it was accepted here too.
+  static void set x28(
+      covariant //# 28: compile-time error
+      val) {}
+
+  // If there is no type, then `covariant` is simply the parameter name:
+  static void set x29(covariant) {}
+
+  // Covariant won't work on return types.
+  static
+  covariant // //# 30: syntax error
+      int f30() => 499;
+
+  covariant // //# 30b: syntax error
+  static int f30b() => 499;
+
+  // Covariant won't work as a return type.
+  static
+  covariant // //# 31: syntax error
+      f31() => 499;
+
+  covariant // //# 31b: syntax error
+  static f31b() => 499;
+
+  // Covariant should not work on static methods.
+  // It's a minor (acceptable) bug to not error out here.
+  static int f32(
+      covariant //# 32: compile-time error
+          int x) =>
+      499;
+
+  // `Covariant` must be in front of the types.
+  static int f33(
+          int
+      covariant //# 33: syntax error
+              x) =>
+      499;
+
+  // Covariant should not work on top-level methods.
+  // It's a minor (acceptable) bug to not error out here.
+  static int f34(
+      covariant //# 34: compile-time error
+          final x) =>
+      499;
+
+  // `Covariant` must be in front of modifiers.
+  static int f35(
+          final
+      covariant //# 35: syntax error
+              x) =>
+      499;
+
+  // Covariant should not work on top-level methods.
+  // It's a minor (acceptable) bug to not error out here.
+  static int f36(
+      covariant //# 36: compile-time error
+          final int x) =>
+      499;
+
+  // `Covariant` must be in front of modifiers.
+  static int f37(
+          final
+      covariant //# 37: syntax error
+              int
+              x) =>
+      499;
+
+  // `Covariant` on its own is just a parameter name.
+  static int f38(covariant) => covariant;
+
+  static covariant; // //# 39: syntax error
+
+}
+
+// All of the above as instance members in a class.
+class B {
+  covariant // //# 40: ok
+  int x40 = 0;
+
+  covariant int covariant = 0; // //# 40b: ok
+
+  int covariant = 0; //           //# 40c: ok
+
+  // Getters may never have `covariant`.
+  covariant // //# 41: syntax error
+  int get x41 => 499;
+
+  void set x42(
+      covariant // //# 42: ok
+      int val) {}
+
+  // `covariant` in the wrong position.
+  int
+  covariant // //# 43: syntax error
+      x43 = 0;
+
+  // `covariant` in the wrong position.
+  int
+  covariant // //# 44: syntax error
+      get x44 => 499;
+
+  void set x45(
+      int
+    covariant //# 45: syntax error
+          val) {}
+
+  // Since `covariant` is a built-in identifier, it is not allowed here.
+  covariant x46; //# 46: syntax error
+  covariant covariant; //# 46b: syntax error
+
+  // Getters may never have `covariant`.
+  covariant // //# 47: syntax error
+  get x47 => 499;
+
+  void set x48(
+      covariant // //# 48: ok
+      val) {}
+
+  // If there is no type, then `covariant` is simply the parameter name:
+  void set x49(covariant) {}
+
+  // Covariant won't work on return types.
+  covariant // //# 50: syntax error
+  int f50() => 499;
+
+  // Covariant won't work as a return type.
+  covariant // //# 51: syntax error
+  f51() => 499;
+
+  int f52(
+      covariant // //# 52: ok
+          int x) =>
+      499;
+
+  // `Covariant` must be in front of the types.
+  int f53(
+          int
+      covariant //# 53: syntax error
+              x) =>
+      499;
+
+  int f54(
+      covariant // //# 54: ok
+          final x) =>
+      499;
+
+  // `Covariant` must be in front of modifiers.
+  int f55(
+          final
+      covariant //# 55: syntax error
+              x) =>
+      499;
+
+  int f56(
+      covariant // //# 56: ok
+          final int x) =>
+      499;
+
+  // `Covariant` must be in front of modifiers.
+  int f57(
+          final
+      covariant //# 57: syntax error
+              int
+              x) =>
+      499;
+
+  // `Covariant` on its own is just a parameter name.
+  int f58(covariant) => covariant;
+
+  covariant; // //# 59: syntax error
+}
+
+void use(x) {}
+
+main() {
+  x0 = 0;
+  covariant = 0; // //# 00b: continued
+  covariant = 0; // //# 00c: continued
+  use(x1);
+  x2 = 499;
+  use(x3);
+  use(x4);
+  x5 = 42;
+  x6 = 0; //# 06: continued
+  covariant = 0; //# 06b: continued
+  use(x7);
+  x8 = 11;
+  x9 = 12;
+  use(f10());
+  use(f11());
+  use(f12(2));
+  use(f13(3));
+  use(f14(3));
+  use(f15(3));
+  use(f16(3));
+  use(f17(3));
+  Expect.equals(123, f18(123));
+  use(covariant); // //# 19: continued
+
+  A.x20 = 0;
+  A.covariant = 0; // //# 20b: continued
+  A.covariant = 0; // //# 20c: continued
+  use(A.x21);
+  use(A.x21b);
+  A.x22 = 499;
+  use(A.x23);
+  use(A.x24);
+  A.x25 = 42;
+  A.x26 = 0; //# 26: continued
+  A.covariant = 0; //# 26b: continued
+  use(A.x27);
+  use(A.x27b);
+  A.x28 = 11;
+  A.x29 = 12;
+  use(A.f30());
+  use(A.f31());
+  use(A.f31b());
+  use(A.f32(2));
+  use(A.f33(3));
+  use(A.f34(3));
+  use(A.f35(3));
+  use(A.f36(3));
+  use(A.f37(3));
+  Expect.equals(1234, A.f38(1234));
+  use(A.covariant); // //# 39: continued
+
+  var b = new B();
+  b.x40 = 0;
+  b.covariant = 0; // //# 40b: continued
+  b.covariant = 0; // //# 40c: continued
+  use(b.x41);
+  b.x42 = 499;
+  use(b.x43);
+  use(b.x44);
+  b.x45 = 42;
+  b.x46 = 0; //# 46: continued
+  b.covariant = 0; //# 46b: continued
+  use(b.x47);
+  b.x48 = 11;
+  b.x49 = 12;
+  use(b.f50());
+  use(b.f51());
+  use(b.f52(2));
+  use(b.f53(2));
+  use(b.f54(3));
+  use(b.f55(3));
+  use(b.f56(3));
+  use(b.f57(3));
+  Expect.equals(12345, b.f58(12345));
+  use(B.covariant); // //# 59: continued
+}
diff --git a/tests/language/covariant/field_test.dart b/tests/language/covariant/field_test.dart
new file mode 100644
index 0000000..11ed033
--- /dev/null
+++ b/tests/language/covariant/field_test.dart
@@ -0,0 +1,58 @@
+// 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:expect/expect.dart";
+
+class A {}
+
+abstract class B<T> {
+  // x will be marked genericCovariantInterface, since x's type is covariant in
+  // the type parameter T.
+  void set s2(T x);
+
+  // x will be marked genericCovariantInterface, since x's type is covariant in
+  // the type parameter T.
+  void set s3(T x);
+
+  void set s4(Object? x);
+
+  void set s5(Object? x) {
+    s4 = x;
+  }
+}
+
+class C extends B<A> {
+  A? s1;
+
+  // s2 will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  A? s2;
+
+  // s3 will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  covariant A? s3;
+
+  covariant A? s4;
+}
+
+main() {
+  // Dynamic method calls should always have their arguments type checked.
+  dynamic d = new C();
+  Expect.throwsTypeError(() => d.s1 = new Object()); //# 01: ok
+
+  // Interface calls should have any arguments marked "genericCovariantImpl"
+  // type checked provided that the corresponding argument on the interface
+  // target is marked "genericCovariantInterface".
+  B<Object> b = new C();
+  Expect.throwsTypeError(() => b.s2 = new Object()); //# 02: ok
+
+  // Interface calls should have any arguments marked "covariant" type checked,
+  // regardless of whether the corresponding argument on the interface target is
+  // marked "genericCovariantInterface".
+  Expect.throwsTypeError(() => b.s3 = new Object()); //# 03: ok
+  Expect.throwsTypeError(() => b.s4 = new Object()); //# 04: ok
+
+  // This calls should have any arguments marked "covariant" type checked.
+  Expect.throwsTypeError(() => b.s5 = new Object()); //# 05: ok
+}
diff --git a/tests/language/covariant/method_test.dart b/tests/language/covariant/method_test.dart
new file mode 100644
index 0000000..03ea520
--- /dev/null
+++ b/tests/language/covariant/method_test.dart
@@ -0,0 +1,63 @@
+// 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:expect/expect.dart";
+
+class A {}
+
+abstract class B<T> {
+  // x will be marked genericCovariantInterface, since x's type is covariant in
+  // the type parameter T.
+  void f2(T x);
+
+  // x will be marked genericCovariantInterface, since x's type is covariant in
+  // the type parameter T.
+  void f3(T x);
+
+  void f4(Object x);
+
+  void f5(Object x) {
+    f4(x);
+  }
+}
+
+class C extends B<A> {
+  void f1(A x) {}
+
+  // x will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  void f2(A x) {}
+
+  // x will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  void f3(covariant A x) {}
+
+  void f4(covariant A x) {}
+}
+
+main() {
+  // Dynamic method calls should always have their arguments type checked.
+  dynamic d = new C();
+  Expect.throwsTypeError(() => d.f1(new Object())); //# 01: ok
+
+  // Closure calls should have any arguments marked "genericCovariantImpl" type
+  // checked.
+  B<Object> b = new C();
+  void Function(Object) f = b.f2;
+  Expect.throwsTypeError(() => f(new Object())); //# 02: ok
+
+  // Interface calls should have any arguments marked "genericCovariantImpl"
+  // type checked provided that the corresponding argument on the interface
+  // target is marked "genericCovariantInterface".
+  Expect.throwsTypeError(() => b.f2(new Object())); //# 03: ok
+
+  // Interface calls should have any arguments marked "covariant" type checked,
+  // regardless of whether the corresponding argument on the interface target is
+  // marked "genericCovariantInterface".
+  Expect.throwsTypeError(() => b.f3(new Object())); //# 04: ok
+  Expect.throwsTypeError(() => b.f4(new Object())); //# 05: ok
+
+  // This calls should have any arguments marked "covariant" type checked.
+  Expect.throwsTypeError(() => b.f5(new Object())); //# 06: ok
+}
diff --git a/tests/language/covariant/override_test.dart b/tests/language/covariant/override_test.dart
new file mode 100644
index 0000000..503cf86
--- /dev/null
+++ b/tests/language/covariant/override_test.dart
@@ -0,0 +1,96 @@
+// 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.
+
+library covariant_override_test;
+
+// This test contains cases where `covariant` is used as intended.
+
+abstract class A {
+  A(this.f1, this.f2, this.f3);
+
+  // Normal usage, "by design": superclass requests covariance.
+  void m1(covariant Object o);
+
+  // Normal usage, "ad hoc": subclass requests covariance.
+  void m2(Object o);
+
+  // Syntactic special case: omit the type in subclass.
+  void m3(Object o);
+
+  // Positional optional arguments.
+  void m4([covariant Object o = 0]);
+  void m5([Object o = 0]);
+  void m6([Object o = 0]);
+
+  // Named arguments.
+  void m7({covariant Object arg = 0});
+  void m8({Object arg = 0});
+  void m9({Object arg = 0});
+
+  // Normal usage on field, "by design": superclass requests covariance.
+  covariant Object f1;
+
+  // Normal usage on field, "ad hoc": subclass requests covariance.
+  Object f2;
+
+  // Syntactic special case.
+  Object f3;
+}
+
+abstract class B extends A {
+  B(num f1, num f2, num f3) : super(f1, f2, f3);
+
+  void m1(num n);
+  void m2(covariant num n);
+  void m3(covariant n);
+  void m4([num n]);
+  void m5([covariant num n]);
+  void m6([covariant n]);
+  void m7({num arg});
+  void m8({covariant num arg});
+  void m9({covariant arg});
+  num get f1;
+  void set f1(num n);
+  num get f2;
+  void set f2(covariant num n);
+  void set f3(covariant n);
+}
+
+class C extends B {
+  C(int f1, int f2, int f3) : super(f1, f2, f3);
+
+  void m1(int i) {}
+  void m2(int i) {}
+  void m3(int i) {}
+  void m4([int i = 0]) {}
+  void m5([int i = 0]) {}
+  void m6([int i = 0]) {}
+  void m7({int arg = 0}) {}
+  void m8({int arg = 0}) {}
+  void m9({int arg = 0}) {}
+  int get f1 => 0;
+  void set f1(covariant int i) {}
+  int get f2 => 0;
+  void set f2(covariant int i) {}
+  int get f3 => 0;
+  void set f3(int i) {}
+}
+
+main() {
+  // For Dart 1.x, `covariant` has no runtime semantics; we just ensure
+  // that the code is not unused, such that we know it will be parsed.
+  A a = new C(39, 40, 41);
+  a.m1(42);
+  a.m2(42);
+  a.m3(42);
+  a.m4(42);
+  a.m5(42);
+  a.m6(42);
+  a.m7(arg: 42);
+  a.m8(arg: 42);
+  a.m9(arg: 42);
+  a.f1 = 42;
+  a.f2 = 42;
+  a.f3 = 42;
+}
diff --git a/tests/language/covariant/return_type_test.dart b/tests/language/covariant/return_type_test.dart
new file mode 100644
index 0000000..43c6c9e
--- /dev/null
+++ b/tests/language/covariant/return_type_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  List<int> l = [1, 2, 3].where((x) => x.isEven).map((x) => x + 1);
+  //            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+  //                                             ^
+  // [cfe] A value of type 'Iterable<int>' can't be assigned to a variable of type 'List<int>'.
+
+  {
+    // Works.
+    C<Object> c = C<Object>(1);
+    Iterable<bool Function(Object)> myList = c.f();
+  }
+
+  {
+    C<Object> c = C<Object>(1);
+    List<bool Function(Object)> myList = c.f();
+    //                                   ^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    //                                     ^
+    // [cfe] A value of type 'Iterable<bool Function(Object)>' can't be assigned to a variable of type 'List<bool Function(Object)>'.
+  }
+
+  {
+    C<Object> c = C<int>(1);
+    List<bool Function(Object)> myList = c.f();
+    //                                   ^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    //                                     ^
+    // [cfe] A value of type 'Iterable<bool Function(Object)>' can't be assigned to a variable of type 'List<bool Function(Object)>'.
+  }
+
+  {
+    C<Object> c = C<int>(1);
+    Iterable<bool Function(Object)> myList = c.f();
+  }
+
+  {
+    // Works.
+    C<Iterable<Object>> c = D<Object>([1]);
+    Iterable<bool Function(Iterable<Object>)> myList = c.f();
+  }
+
+  {
+    C<Iterable<Object>> c = D<Object>([1]);
+    List<bool Function(Iterable<Object>)> myList = c.f();
+    //                                             ^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    //                                               ^
+    // [cfe] A value of type 'Iterable<bool Function(Iterable<Object>)>' can't be assigned to a variable of type 'List<bool Function(Iterable<Object>)>'.
+  }
+
+  {
+    C<Iterable<Object>> c = D<int>([1]);
+    Iterable<bool Function(Iterable<Object>)> myList = c.f();
+  }
+}
+
+class C<T> {
+  final T t;
+  C(this.t);
+  Iterable<bool Function(T)> f() sync* {
+    yield (T x) => x == t;
+  }
+}
+
+class D<S> extends C<Iterable<S>> {
+  D(Iterable<S> s) : super(s);
+}
diff --git a/tests/language/covariant/setter_test.dart b/tests/language/covariant/setter_test.dart
new file mode 100644
index 0000000..1a19dca
--- /dev/null
+++ b/tests/language/covariant/setter_test.dart
@@ -0,0 +1,90 @@
+// 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:expect/expect.dart";
+
+class A {}
+
+abstract class B<T> {
+  // x will be marked genericCovariantInterface, since x's type is covariant in
+  // the type parameter T.
+  void set s2(T x);
+
+  // x will be marked genericCovariantInterface, since x's type is covariant in
+  // the type parameter T.
+  void set s3(T x);
+
+  void set s4(Object x);
+
+  void set s5(Object x) {
+    s4 = x;
+  }
+}
+
+class C extends B<A> {
+  void set s1(A x) {}
+
+  // x will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  void set s2(A x) {}
+
+  // x will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  void set s3(covariant A x) {}
+
+  void set s4(covariant A x) {}
+}
+
+main() {
+  // Dynamic method calls should always have their arguments type checked.
+  dynamic d = new C();
+  Expect.throwsTypeError(() => d.s1 = new Object()); //# 01: ok
+
+  // Interface calls should have any arguments marked "genericCovariantImpl"
+  // type checked provided that the corresponding argument on the interface
+  // target is marked "genericCovariantInterface".
+  B<Object> b = new C();
+  Expect.throwsTypeError(() => b.s2 = new Object()); //# 02: ok
+
+  // Interface calls should have any arguments marked "covariant" type checked,
+  // regardless of whether the corresponding argument on the interface target is
+  // marked "genericCovariantInterface".
+  Expect.throwsTypeError(() => b.s3 = new Object()); //# 03: ok
+  Expect.throwsTypeError(() => b.s4 = new Object()); //# 04: ok
+
+  // This calls should have any arguments marked "covariant" type checked.
+  Expect.throwsTypeError(() => b.s5 = new Object()); //# 05: ok
+
+  testMixin(); //# 06: ok
+}
+
+abstract class D<T> {
+  void set m1(T x);
+}
+
+class E {
+  void set m1(A x) {}
+}
+
+class F = Object with E implements D<A>;
+class G = C with E implements D<A>;
+
+class H extends Object with E implements D<A> {}
+
+class I extends Object with F {}
+
+void testMixin() {
+  D<Object> f = new F();
+  f.m1 = new A();
+  Expect.throwsTypeError(() => f.m1 = new Object());
+  f = new G();
+  f.m1 = new A();
+  Expect.throwsTypeError(() => f.m1 = new Object());
+  f = new H();
+  f.m1 = new A();
+  Expect.throwsTypeError(() => f.m1 = new Object());
+  f = new I();
+  f.m1 = new A();
+  Expect.throwsTypeError(() => f.m1 = new Object());
+}
diff --git a/tests/language/covariant/subtyping_tearoff1_test.dart b/tests/language/covariant/subtyping_tearoff1_test.dart
new file mode 100644
index 0000000..404b4bb
--- /dev/null
+++ b/tests/language/covariant/subtyping_tearoff1_test.dart
@@ -0,0 +1,19 @@
+// 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:expect/expect.dart';
+
+class Foo<T> {
+  dynamic method(T x) {}
+}
+
+typedef dynamic TakeNum(num x);
+
+main() {
+  Foo<int> intFoo = new Foo<int>();
+  Foo<num> numFoo = intFoo;
+  TakeNum f = numFoo.method;
+  Expect.throws(() => f(2.5));
+  dynamic f2 = numFoo.method;
+  Expect.throws(() => f2(2.5));
+}
diff --git a/tests/language/covariant/subtyping_tearoff2_test.dart b/tests/language/covariant/subtyping_tearoff2_test.dart
new file mode 100644
index 0000000..306d83d
--- /dev/null
+++ b/tests/language/covariant/subtyping_tearoff2_test.dart
@@ -0,0 +1,26 @@
+// 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:expect/expect.dart';
+
+class Implementation {
+  dynamic method(int x) {}
+}
+
+abstract class Interface<T> {
+  dynamic method(T x);
+}
+
+class Subclass extends Implementation implements Interface<int> {}
+
+typedef dynamic TakeNum(num x);
+
+main() {
+  Subclass subclass = new Subclass();
+  Interface<int> intInterface = subclass;
+  Interface<num> numInterface = intInterface;
+  TakeNum f = numInterface.method;
+  Expect.throws(() => f(2.5));
+  dynamic f2 = f;
+  Expect.throws(() => f2(2.5));
+}
diff --git a/tests/language/covariant/subtyping_tearoff3_test.dart b/tests/language/covariant/subtyping_tearoff3_test.dart
new file mode 100644
index 0000000..3e1109b
--- /dev/null
+++ b/tests/language/covariant/subtyping_tearoff3_test.dart
@@ -0,0 +1,39 @@
+// 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:expect/expect.dart';
+
+class Implementation {
+  dynamic method(int x) {}
+}
+
+abstract class Interface1<T> {
+  dynamic method(T x);
+}
+
+abstract class Interface2<T> {
+  dynamic method(T x);
+}
+
+class Subclass extends Implementation
+    implements Interface1<int>, Interface2<int> {}
+
+typedef dynamic TakeNum(num x);
+
+main() {
+  Subclass subclass = new Subclass();
+
+  Interface1<int> intInterface1 = subclass;
+  Interface1<num> numInterface1 = intInterface1;
+  TakeNum f1 = numInterface1.method;
+  Expect.throws(() => f1(2.5));
+  dynamic f1dynamic = f1;
+  Expect.throws(() => f1dynamic(2.5));
+
+  Interface2<int> intInterface2 = subclass;
+  Interface2<num> numInterface2 = intInterface2;
+  TakeNum f2 = numInterface2.method;
+  Expect.throws(() => f2(2.5));
+  dynamic f2dynamic = f2;
+  Expect.throws(() => f2dynamic(2.5));
+}
diff --git a/tests/language/covariant/subtyping_test.dart b/tests/language/covariant/subtyping_test.dart
new file mode 100644
index 0000000..da7af10
--- /dev/null
+++ b/tests/language/covariant/subtyping_test.dart
@@ -0,0 +1,248 @@
+// 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:expect/expect.dart';
+
+class Fields<T> {
+  late T x;
+  late T _y;
+  late T _z;
+
+  m() {
+    _y = x;
+  }
+
+  n(Fields<T> c) {
+    c._z = x;
+  }
+}
+
+testField() {
+  Fields<Object> c = new Fields<int>();
+  Expect.throwsTypeError(() => c.x = 'hello');
+
+  Fields<dynamic> d = new Fields<int>();
+  Expect.throwsTypeError(() => c.x = 'hello');
+}
+
+testPrivateFields() {
+  Fields<Object> c = new Fields<int>()..x = 42;
+  c.m();
+  Expect.equals(c._y, 42);
+
+  Fields<Object> c2 = new Fields<String>()..x = 'hi';
+  c2.n(c2);
+  Expect.equals(c2._z, 'hi');
+  Expect.throwsTypeError(() => c.n(c2));
+  Expect.equals(c2._z, 'hi');
+}
+
+class NumBounds<T extends num> {
+  bool m(T t) => t.isNegative;
+}
+
+class MethodTakesNum extends NumBounds<int> {
+  bool m(num obj) => obj.isNegative; // does not need check
+}
+
+class MethodTakesInt extends NumBounds<int> {
+  bool m(int obj) => obj.isNegative; // needs a check
+}
+
+testClassBounds() {
+  NumBounds<num> d = new MethodTakesNum();
+  Expect.equals(d.m(-1.1), true);
+  d = new MethodTakesInt();
+  Expect.throwsTypeError(() => d.m(-1.1));
+}
+
+typedef void F<T>(T t);
+typedef G<T> = void Function<S extends T>(S s);
+
+class FnChecks<T> {
+  late F<T> f;
+  late G<T> g;
+  late T _t;
+  T getT() => _t;
+  F<T> setterForT() {
+    return (T t) {
+      _t = t;
+    };
+  }
+}
+
+testReturnOfFunctionType() {
+  FnChecks<int> cInt = new FnChecks<int>();
+  FnChecks<Object> cObj = cInt;
+  Expect.throwsTypeError(() => cObj.setterForT());
+  Expect.throwsTypeError(() => (cObj.setterForT() as F<Object>));
+  FnChecks<dynamic> cDyn = cInt;
+  Expect.throwsTypeError(() => cDyn.setterForT());
+  Expect.throwsTypeError(
+      () => (cDyn as dynamic).setterForT()('hi')); // dcall throws
+  cInt.setterForT()(42);
+  Expect.equals(cObj.getT(), 42);
+}
+
+testTearoffReturningFunctionType() {
+  FnChecks<int> cInt = new FnChecks<int>();
+  FnChecks<Object> cObj = cInt;
+
+  Expect.throwsTypeError(
+      () => cObj.setterForT, 'unsound tear-off throws at runtime');
+  Expect.equals(cInt.setterForT, cInt.setterForT, 'sound tear-off works');
+}
+
+testFieldOfFunctionType() {
+  FnChecks<Object> c = new FnChecks<String>()..f = (String b) {};
+  Expect.throwsTypeError(() {
+    F<Object> f = c.f;
+  });
+  Expect.throwsTypeError(() {
+    Object f = c.f;
+  });
+  Expect.throwsTypeError(() => c.f);
+  Expect.throwsTypeError(() => c.f(42));
+  Expect.throwsTypeError(() => c.f('hi'));
+  FnChecks<String> cStr = c as FnChecks<String>;
+  cStr.f('hi');
+  FnChecks<dynamic> cDyn = c;
+  Expect.throwsTypeError(() => cDyn.f);
+  Expect.throwsTypeError(() => (cDyn as dynamic).f(42)); // dcall throws
+}
+
+testFieldOfGenericFunctionType() {
+  FnChecks<Object> c = new FnChecks<num>()
+    ..g = <S extends num>(S s) => s.isNegative;
+
+  Expect.throwsTypeError(() {
+    G<Object> g = c.g;
+  });
+  Expect.throwsTypeError(() {
+    var g = c.g;
+  });
+  Expect.throwsTypeError(() => c.g<String>('hi'));
+  Expect.throwsTypeError(() => c.g<int>(42));
+  FnChecks<num> cNum = c as FnChecks<num>;
+  cNum.g(42);
+}
+
+class Base {
+  int _t = 0;
+  add(int t) {
+    _t += t;
+  }
+}
+
+abstract class I<T> {
+  add(T t);
+}
+
+class ExtendsBase extends Base implements I<int> {}
+
+class MixinBase extends Object with Base implements I<int> {}
+
+class MixinBase2 = Object with Base implements I<int>;
+
+testMixinApplication() {
+  I<Object> i = new ExtendsBase();
+  I<Object> j = new MixinBase();
+  I<Object> k = new MixinBase2();
+  Expect.throwsTypeError(() => i.add('hi'));
+  Expect.throwsTypeError(() => j.add('hi'));
+  Expect.throwsTypeError(() => k.add('hi'));
+}
+
+class GenericMethodBounds<T> {
+  Type get t => T;
+  GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
+  GenericMethodBounds<E> bar<E extends void Function(T)>() =>
+      new GenericMethodBounds<E>();
+}
+
+class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
+  GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
+  GenericMethodBounds<E> bar<E extends void Function(num)>() =>
+      new GenericMethodBounds<E>();
+}
+
+GenericMethodBounds<E> Function<E extends T>() genericFunctionWithBounds<T>() {
+  inner<E extends T>() => new GenericMethodBounds<E>();
+  return inner;
+}
+
+testGenericMethodBounds() {
+  test(GenericMethodBounds<Object?> g) {
+    Expect.throwsTypeError(() => g.foo<String>());
+    Expect.throwsTypeError(() => g.foo());
+    Expect.equals(g.foo<Null>().t, Null);
+    Expect.equals(g.foo<int>().t, int);
+    Expect.isFalse(g.foo<int>() is GenericMethodBounds<double>);
+    g.bar<Function(Object?)>();
+    dynamic d = g;
+    d.bar<Function(num)>();
+    Expect.throwsTypeError(() => d.bar<Function(String)>());
+    Expect.throwsTypeError(() => d.bar<Function(Null)>());
+  }
+
+  test(new GenericMethodBounds<num>());
+  test(new GenericMethodBounds<int>());
+  test(new GenericMethodBoundsDerived());
+  test(genericFunctionWithBounds<num>()<int>());
+}
+
+class ClassF<T> {
+  late T x;
+  void call(T t) {
+    x = t;
+  }
+}
+
+testCallMethod() {
+  ClassF<int> cc = new ClassF<int>();
+  ClassF<Object> ca = cc; // An upcast, per covariance.
+  F<Object> f = ca;
+  void f2(Object x) {}
+  Expect.equals(f.runtimeType, f2.runtimeType);
+  Expect.throwsTypeError(() => f(new Object()));
+}
+
+class TearOff<T> {
+  method1(T t) => null; // needs check
+  method2(Function(T) takesT) => null;
+  method3(T Function() returnsT) => null; // needs check
+  method4(Function(Function(T)) takesTakesT) => null; // needs check
+  method5(Function(T Function()) takesReturnsT) => null;
+  method6(Function(T) Function() returnsTakesT) => null;
+  method7(T Function() Function() returnsReturnsT) => null; // needs check
+}
+
+testTearOffRuntimeType() {
+  expectRTTI(tearoff, type) => Expect.equals('${tearoff.runtimeType}', type,
+      'covariant params should reify with Object as their type');
+
+  TearOff<num> t = new TearOff<int>();
+  expectRTTI(t.method1, '(Object) => dynamic');
+
+  expectRTTI(t.method2, '((int) => dynamic) => dynamic');
+  expectRTTI(t.method3, '(Object) => dynamic');
+
+  expectRTTI(t.method4, '(Object) => dynamic');
+  expectRTTI(t.method5, '((() => int) => dynamic) => dynamic');
+  expectRTTI(t.method6, '(() => (int) => dynamic) => dynamic');
+  expectRTTI(t.method7, '(Object) => dynamic');
+}
+
+main() {
+  testField();
+  testPrivateFields();
+  testClassBounds();
+  testReturnOfFunctionType();
+  testTearoffReturningFunctionType();
+  testFieldOfFunctionType();
+  testFieldOfGenericFunctionType();
+  testMixinApplication();
+  testGenericMethodBounds();
+  testCallMethod();
+  testTearOffRuntimeType();
+}
diff --git a/tests/language/covariant/subtyping_unsafe_call1_test.dart b/tests/language/covariant/subtyping_unsafe_call1_test.dart
new file mode 100644
index 0000000..b5d4884
--- /dev/null
+++ b/tests/language/covariant/subtyping_unsafe_call1_test.dart
@@ -0,0 +1,14 @@
+// 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:expect/expect.dart';
+
+class Foo<T> {
+  dynamic method(T x) {}
+}
+
+main() {
+  Foo<int> intFoo = new Foo<int>();
+  Foo<num> numFoo = intFoo;
+  Expect.throws(() => numFoo.method(2.5));
+}
diff --git a/tests/language/covariant/subtyping_unsafe_call2_test.dart b/tests/language/covariant/subtyping_unsafe_call2_test.dart
new file mode 100644
index 0000000..5e45c37
--- /dev/null
+++ b/tests/language/covariant/subtyping_unsafe_call2_test.dart
@@ -0,0 +1,21 @@
+// 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:expect/expect.dart';
+
+class Implementation {
+  dynamic method(int x) {}
+}
+
+abstract class Interface<T> {
+  dynamic method(T x);
+}
+
+class Subclass extends Implementation implements Interface<int> {}
+
+main() {
+  Subclass subclass = new Subclass();
+  Interface<int> intInterface = subclass;
+  Interface<num> numInterface = intInterface;
+  Expect.throws(() => numInterface.method(2.5));
+}
diff --git a/tests/language/covariant/subtyping_unsafe_call3_test.dart b/tests/language/covariant/subtyping_unsafe_call3_test.dart
new file mode 100644
index 0000000..71143e6
--- /dev/null
+++ b/tests/language/covariant/subtyping_unsafe_call3_test.dart
@@ -0,0 +1,31 @@
+// 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:expect/expect.dart';
+
+class Implementation {
+  dynamic method(int x) {}
+}
+
+abstract class Interface1<T> {
+  dynamic method(T x);
+}
+
+abstract class Interface2<T> {
+  dynamic method(T x);
+}
+
+class Subclass extends Implementation
+    implements Interface1<int>, Interface2<int> {}
+
+main() {
+  Subclass subclass = new Subclass();
+
+  Interface1<int> intInterface1 = subclass;
+  Interface1<num> numInterface1 = intInterface1;
+  Expect.throws(() => numInterface1.method(2.5));
+
+  Interface2<int> intInterface2 = subclass;
+  Interface2<num> numInterface2 = intInterface2;
+  Expect.throws(() => numInterface2.method(2.5));
+}
diff --git a/tests/language/covariant/subtyping_with_mixin_test.dart b/tests/language/covariant/subtyping_with_mixin_test.dart
new file mode 100644
index 0000000..8bff28e
--- /dev/null
+++ b/tests/language/covariant/subtyping_with_mixin_test.dart
@@ -0,0 +1,29 @@
+// 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:expect/expect.dart';
+
+class A {}
+
+class B extends A {}
+
+class Base<S> {}
+
+class Mixin<T> {
+  void f(T arg) {}
+}
+
+abstract class Interface {
+  void f(covariant A arg);
+}
+
+class C<S> extends Base<S> with Mixin<B> implements Interface {}
+
+main() {
+  Interface i = new C<String>();
+  i.f(new B());
+  Expect.throwsTypeError(() {
+    i.f(new A());
+  });
+}
diff --git a/tests/language/covariant/tear_off_type_test.dart b/tests/language/covariant/tear_off_type_test.dart
new file mode 100644
index 0000000..160f46f
--- /dev/null
+++ b/tests/language/covariant/tear_off_type_test.dart
@@ -0,0 +1,29 @@
+// 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:expect/expect.dart";
+
+typedef U F<T, U>(T x);
+
+class C<T> {
+  T f(List<T> x) {
+    throw "uncalled";
+  }
+}
+
+F<List<num>, num> g(C<num> c) {
+  return c.f;
+}
+
+void main() {
+  var tearoff = g(new C<int>());
+  // Since C.f's x parameter is covariant, its type is changed to Object when
+  // determining the type of the tearoff.  So the type of the tearoff should be
+  // `(Object) -> int`.  (Not, for example, `(List<Object>) -> int` or
+  // `(List<Object>) -> Object`)
+  Expect.isTrue(tearoff is F<Object, int>);
+  // Because the function accepts any object, we can pass strings to it.  This
+  // will not work in Dart 1.
+  Expect.isTrue(tearoff is F<String, int>);
+}
diff --git a/tests/language/covariant/type_parameter_test.dart b/tests/language/covariant/type_parameter_test.dart
new file mode 100644
index 0000000..7bff58b
--- /dev/null
+++ b/tests/language/covariant/type_parameter_test.dart
@@ -0,0 +1,38 @@
+// 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:expect/expect.dart";
+
+class A {}
+
+abstract class B<T> {
+  // U will be marked genericCovariantInterface, since U's bound is covariant in
+  // the type parameter T.
+  void f2<U extends T>();
+}
+
+class C extends B<A> {
+  void f1<U extends A>() {}
+
+  // x will be marked genericCovariantImpl, since it might be called via
+  // e.g. B<Object>.
+  void f2<U extends A>() {}
+}
+
+main() {
+  // Dynamic method calls should always have their type arguments checked.
+  dynamic d = new C();
+  Expect.throwsTypeError(() => d.f1<Object>()); //# 01: ok
+
+  // Closure calls should have any type arguments marked "genericCovariantImpl"
+  // checked.
+  B<Object> b = new C();
+  void Function<U extends Object>() f = b.f2;
+  Expect.throwsTypeError(() => f<Object>()); //# 02: ok
+
+  // Interface calls should have any type arguments marked
+  // "genericCovariantImpl" checked provided that the corresponding type
+  // argument on the interface target is marked "genericCovariantInterface".
+  Expect.throwsTypeError(() => b.f2<Object>()); //# 03: ok
+}
diff --git a/tests/language/covariant_override/runtime_check_test.dart b/tests/language/covariant_override/runtime_check_test.dart
new file mode 100644
index 0000000..eedc274
--- /dev/null
+++ b/tests/language/covariant_override/runtime_check_test.dart
@@ -0,0 +1,34 @@
+// 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:expect/expect.dart";
+
+class View {
+  addChild(View v) {}
+  transform(View fn(View v)) {}
+}
+
+class MyView extends View {
+  addChild(covariant MyView v) {}
+  transform(covariant MyView fn(Object v)) {}
+}
+
+main() {
+  dynamic mv = new MyView();
+  dynamic v = new View();
+
+  mv.addChild(mv);
+  Expect.throws(() => mv.addChild(v));
+
+  mv.transform((_) => new MyView());
+
+  // TODO(jmesserly): these *should* be cast failures, but DDC is currently
+  // ignoring function type failures w/ a warning at the console...
+
+  // * -> * not a subtype of Object -> MyView
+  Expect.throws(() => mv.transform((_) => mv));
+
+  // View -> View not a subtype of Object -> MyView
+  Expect.throws(() => mv.transform((View x) => x));
+}
diff --git a/tests/language/covariant_override/tear_off_type_test.dart b/tests/language/covariant_override/tear_off_type_test.dart
new file mode 100644
index 0000000..732aaf6
--- /dev/null
+++ b/tests/language/covariant_override/tear_off_type_test.dart
@@ -0,0 +1,159 @@
+// 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:expect/expect.dart";
+
+// If a parameter is directly or indirectly a covariant override, its type in
+// the method tear-off should become Object?.
+
+typedef void TakeInts(int a, int b, int c, int d, int e);
+typedef void TakeObjectsAndInts(Object? a, int b, Object? c, int d, int e);
+typedef void TakeObjects(Object? a, Object? b, Object? c, Object? d, Object? e);
+
+typedef void TakeOptionalInts([int a, int b, int c, int d]);
+typedef void TakeOptionalObjectsAndInts([Object? a, int b, Object? c, int d]);
+
+typedef void TakeNamedInts({int a, int b, int c, int d});
+typedef void TakeNamedObjectsAndInts({Object? a, int b, Object? c, int d});
+
+class M1 {
+  method(covariant int a, int b) {}
+}
+
+class M2 {
+  method(int a, covariant int b) {}
+}
+
+class C extends Object with M1, M2 {}
+
+class Direct {
+  void positional(covariant int a, int b, covariant int c, int d, int e) {}
+  void optional(
+      [covariant int a = 0, int b = 0, covariant int c = 0, int d = 0]) {}
+  void named(
+      {covariant int a = 0, int b = 0, covariant int c = 0, int d = 0}) {}
+}
+
+class Inherited extends Direct {}
+
+// ---
+
+class Override1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Override2 extends Override1 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Override3 extends Override2 {
+  void method(int a, int b, int c, int d, int e) {}
+}
+
+// ---
+
+abstract class Implement1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Implement2 {
+  void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Implement3 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement4 implements Implement3 {
+  void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Implement5 implements Implement1, Implement2, Implement4 {
+  void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+// ---
+
+class Interface1 {
+  void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Interface2 {
+  void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Mixin1 {
+  void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Mixin2 {
+  void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Superclass {
+  void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Mixed extends Superclass
+    with Mixin1, Mixin2
+    implements Interface1, Interface2 {}
+
+void main() {
+  testDirect();
+  testInherited();
+  testOverriden();
+  testImplemented();
+  testMixed();
+}
+
+void testDirect() {
+  var positional = new Direct().positional;
+  Expect.isTrue(positional is TakeInts);
+  Expect.isTrue(positional is TakeObjectsAndInts);
+
+  var optional = new Direct().optional;
+  Expect.isTrue(optional is TakeOptionalInts);
+  Expect.isTrue(optional is TakeOptionalObjectsAndInts);
+
+  var named = new Direct().named;
+  Expect.isTrue(named is TakeNamedInts);
+  Expect.isTrue(named is TakeNamedObjectsAndInts);
+}
+
+void testInherited() {
+  var positional = new Inherited().positional;
+  Expect.isTrue(positional is TakeInts);
+  Expect.isTrue(positional is TakeObjectsAndInts);
+
+  var optional = new Inherited().optional;
+  Expect.isTrue(optional is TakeOptionalInts);
+  Expect.isTrue(optional is TakeOptionalObjectsAndInts);
+
+  var named = new Inherited().named;
+  Expect.isTrue(named is TakeNamedInts);
+  Expect.isTrue(named is TakeNamedObjectsAndInts);
+}
+
+void testOverriden() {
+  var method2 = new Override2().method;
+  Expect.isTrue(method2 is TakeInts);
+  Expect.isTrue(method2 is TakeObjectsAndInts);
+
+  var method3 = new Override3().method;
+  Expect.isTrue(method3 is TakeInts);
+  Expect.isTrue(method3 is TakeObjectsAndInts);
+}
+
+void testImplemented() {
+  var method = new Implement5().method;
+  Expect.isTrue(method is TakeInts);
+  Expect.isTrue(method is TakeObjects);
+}
+
+void testMixed() {
+  // TODO(rnystrom): https://github.com/dart-lang/sdk/issues/28395
+  var method = new Mixed().method;
+  Expect.isTrue(method is TakeInts);
+  Expect.isTrue(method is TakeObjects);
+}
diff --git a/tests/language/deferred/call_empty_before_load_lib.dart b/tests/language/deferred/call_empty_before_load_lib.dart
new file mode 100644
index 0000000..32dd376
--- /dev/null
+++ b/tests/language/deferred/call_empty_before_load_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+thefun() {}
diff --git a/tests/language/deferred/call_empty_before_load_test.dart b/tests/language/deferred/call_empty_before_load_test.dart
new file mode 100644
index 0000000..9a13981
--- /dev/null
+++ b/tests/language/deferred/call_empty_before_load_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+// Test that calling a function, even though it itself has no effect, will
+// trigger an error if the corresponding deferred library has not been loaded.
+
+import "package:expect/expect.dart";
+import "call_empty_before_load_lib.dart" deferred as lib1;
+
+main() {
+  Expect.throws(() => lib1.thefun());
+}
diff --git a/tests/language/deferred/closurize_load_library_lib.dart b/tests/language/deferred/closurize_load_library_lib.dart
new file mode 100644
index 0000000..9878ae9
--- /dev/null
+++ b/tests/language/deferred/closurize_load_library_lib.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var trueVar = true;
diff --git a/tests/language/deferred/closurize_load_library_test.dart b/tests/language/deferred/closurize_load_library_test.dart
new file mode 100644
index 0000000..0f45d3a
--- /dev/null
+++ b/tests/language/deferred/closurize_load_library_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "closurize_load_library_lib.dart" deferred as lib;
+
+void main() {
+  var x = lib.loadLibrary;
+  asyncStart();
+  x().then((_) {
+    Expect.isTrue(lib.trueVar);
+    asyncEnd();
+  });
+}
diff --git a/tests/language/deferred/constant_list_lib.dart b/tests/language/deferred/constant_list_lib.dart
new file mode 100644
index 0000000..93a6740
--- /dev/null
+++ b/tests/language/deferred/constant_list_lib.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final finalConstList = const [1, 2];
+var nonFinalConstList = const [3, 4];
diff --git a/tests/language/deferred/constant_list_test.dart b/tests/language/deferred/constant_list_test.dart
new file mode 100644
index 0000000..01ee8d6
--- /dev/null
+++ b/tests/language/deferred/constant_list_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "constant_list_lib.dart" deferred as lib;
+
+void main() {
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals("[1, 2]", lib.finalConstList.toString());
+    Expect.equals("[3, 4]", lib.nonFinalConstList.toString());
+    asyncEnd();
+  });
+}
diff --git a/tests/language/deferred/constraints_lib.dart b/tests/language/deferred/constraints_lib.dart
new file mode 100644
index 0000000..0bf3cc9
--- /dev/null
+++ b/tests/language/deferred/constraints_lib.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  static int staticMethod() => 42;
+}
+
+class G<T> {}
+
+class Const {
+  const Const();
+  const Const.otherConstructor();
+  static const instance = const Const();
+}
+
+const constantInstance = const Const();
diff --git a/tests/language/deferred/constraints_lib2.dart b/tests/language/deferred/constraints_lib2.dart
new file mode 100644
index 0000000..830705f
--- /dev/null
+++ b/tests/language/deferred/constraints_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() => 42;
+
+class C {}
diff --git a/tests/language/deferred/constraints_type_annotation_test.dart b/tests/language/deferred/constraints_type_annotation_test.dart
new file mode 100644
index 0000000..9d86ccb
--- /dev/null
+++ b/tests/language/deferred/constraints_type_annotation_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "constraints_lib.dart" deferred as lib;
+import "constraints_lib.dart" as lib2; //# type_annotation_non_deferred: ok
+
+class F {}
+
+class G2<T> {}
+
+main() {
+  lib.C a = null; //# type_annotation_null: compile-time error
+  Expect.throws(() { //# new_before_load: compile-time error
+    lib.C a = new lib.C(); //# new_before_load: continued
+  }, (e) => e is Error); //# new_before_load: continued
+
+  // In this case we do not defer C.
+  lib2.C a1 = new lib2.C(); //# type_annotation_non_deferred: continued
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    lib.C a2 = new lib.C(); //# type_annotation1: dynamic type error, compile-time error
+    lib.G<F> a3 = new lib.G<F>(); //# type_annotation_generic1: dynamic type error, compile-time error
+    G2<lib.C> a4 = new G2(); //# type_annotation_generic2: compile-time error
+    G2<lib.C> a5 = new G2<lib.C>(); //# type_annotation_generic3: compile-time error
+    lib.G<lib.C> a = new lib.G<lib.C>(); //# type_annotation_generic4: dynamic type error, compile-time error
+    var a6 = new lib.C(); //# new: ok
+    var g1 = new lib.G<F>(); //# new_generic1: ok
+    // new G2<lib.C>() does not give a dynamic type error because a malformed
+    // type used as type-parameter is treated as dynamic.
+    var g2 = new G2<lib.C>(); //# new_generic2: compile-time error
+    var g3 = new lib.G<lib.C>(); //# new_generic3: compile-time error
+    var instance = lib.constantInstance;
+    Expect.throwsTypeError(() { //# is_check: compile-time error
+      bool a7 = instance is lib.Const; //# is_check: continued
+    }); //# is_check: continued
+    Expect.throwsTypeError(() { //# as_operation: compile-time error
+      instance as lib.Const; //# as_operation: continued
+    }); //# as_operation: continued
+    Expect.throwsTypeError(() { //# catch_check: compile-time error
+      try { throw instance; } on lib.Const {} //# catch_check: continued
+    }); //# catch_check: continued
+    int i = lib.C.staticMethod(); //# static_method: ok
+    asyncEnd();
+  });
+}
+
+lib.C a9 = null; //# type_annotation_top_level: compile-time error
diff --git a/tests/language/deferred/duplicate_prefix1_runtime_test.dart b/tests/language/deferred/duplicate_prefix1_runtime_test.dart
new file mode 100644
index 0000000..0feaa2e
--- /dev/null
+++ b/tests/language/deferred/duplicate_prefix1_runtime_test.dart
@@ -0,0 +1,11 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "prefix_constraints_lib2.dart" as lib;
+
+
+void main() {}
diff --git a/tests/language/deferred/duplicate_prefix1_test.dart b/tests/language/deferred/duplicate_prefix1_test.dart
new file mode 100644
index 0000000..7668c0f
--- /dev/null
+++ b/tests/language/deferred/duplicate_prefix1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "prefix_constraints_lib2.dart" as lib;
+import "prefix_constraints_lib.dart" deferred as lib;
+//                                   ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.SHARED_DEFERRED_PREFIX
+//                                               ^
+// [cfe] Can't use the name 'lib' for a deferred library, as the name is used elsewhere.
+
+void main() {}
diff --git a/tests/language/deferred/duplicate_prefix2_runtime_test.dart b/tests/language/deferred/duplicate_prefix2_runtime_test.dart
new file mode 100644
index 0000000..482f828
--- /dev/null
+++ b/tests/language/deferred/duplicate_prefix2_runtime_test.dart
@@ -0,0 +1,11 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+import "prefix_constraints_lib2.dart" as lib;
+
+void main() {}
diff --git a/tests/language/deferred/duplicate_prefix2_test.dart b/tests/language/deferred/duplicate_prefix2_test.dart
new file mode 100644
index 0000000..cee67e0
--- /dev/null
+++ b/tests/language/deferred/duplicate_prefix2_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "prefix_constraints_lib.dart" deferred as lib;
+//                                   ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.SHARED_DEFERRED_PREFIX
+//                                               ^
+// [cfe] Can't use the name 'lib' for a deferred library, as the name is used elsewhere.
+import "prefix_constraints_lib2.dart" as lib;
+
+void main() {}
diff --git a/tests/language/deferred/duplicate_prefix3_runtime_test.dart b/tests/language/deferred/duplicate_prefix3_runtime_test.dart
new file mode 100644
index 0000000..3f409b6
--- /dev/null
+++ b/tests/language/deferred/duplicate_prefix3_runtime_test.dart
@@ -0,0 +1,11 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+
+
+void main() {}
diff --git a/tests/language/deferred/duplicate_prefix3_test.dart b/tests/language/deferred/duplicate_prefix3_test.dart
new file mode 100644
index 0000000..ee80c82
--- /dev/null
+++ b/tests/language/deferred/duplicate_prefix3_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "prefix_constraints_lib.dart" deferred as lib;
+//                                   ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.SHARED_DEFERRED_PREFIX
+import "prefix_constraints_lib2.dart" deferred as lib;
+//                                    ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.SHARED_DEFERRED_PREFIX
+//                                                ^
+// [cfe] Can't use the name 'lib' for a deferred library, as the name is used elsewhere.
+
+void main() {}
diff --git a/tests/language/deferred/function_type_lib.dart b/tests/language/deferred/function_type_lib.dart
new file mode 100644
index 0000000..939122e
--- /dev/null
+++ b/tests/language/deferred/function_type_lib.dart
@@ -0,0 +1,20 @@
+// 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:expect/expect.dart';
+
+class T {
+  A foo(int x) { return A(); }
+}
+
+class A {}
+
+typedef A F(int x);
+
+use(x) => x;
+
+runTest() {
+  use(new A());
+  Expect.isTrue(new T().foo is F);
+}
diff --git a/tests/language/deferred/function_type_test.dart b/tests/language/deferred/function_type_test.dart
new file mode 100644
index 0000000..49e151b
--- /dev/null
+++ b/tests/language/deferred/function_type_test.dart
@@ -0,0 +1,11 @@
+// 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 'function_type_lib.dart' deferred as lib;
+
+main() {
+  lib.loadLibrary().then((_) {
+    lib.runTest();
+  });
+}
diff --git a/tests/language/deferred/global_lib.dart b/tests/language/deferred/global_lib.dart
new file mode 100644
index 0000000..d4f3f05
--- /dev/null
+++ b/tests/language/deferred/global_lib.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var sideEffectCounter = 0;
+
+final finalConstGlobal = "finalConstGlobal";
+final finalNonConstGlobal = (() {
+  sideEffectCounter++;
+  return "finalNonConstGlobal";
+}());
+
+var lazyConstGlobal = "lazyConstGlobal";
+// Regression test for bug #21840.
+var const1Global = const {};
+final lazyConstGlobal2 = const1Global;
+
+var lazyNonConstGlobal = (() {
+  sideEffectCounter++;
+  return "lazyNonConstGlobal";
+}());
+
+readFinalConstGlobal() => finalConstGlobal;
+readFinalNonConstGlobal() => finalNonConstGlobal;
+readLazyConstGlobal() => lazyConstGlobal;
+readLazyNonConstGlobal() => lazyNonConstGlobal;
+writeLazyConstGlobal(x) {
+  lazyConstGlobal = x;
+}
+
+writeLazyNonConstGlobal(x) {
+  lazyNonConstGlobal = x;
+}
diff --git a/tests/language/deferred/global_test.dart b/tests/language/deferred/global_test.dart
new file mode 100644
index 0000000..6d13fc1
--- /dev/null
+++ b/tests/language/deferred/global_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "global_lib.dart" deferred as lib;
+
+Object? nonDeferredGlobal = const {};
+
+void main() {
+  nonDeferredGlobal = null;
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    // Ensure non-deferred globals are not reset when loading a deferred
+    // library.
+    Expect.equals(null, nonDeferredGlobal);
+
+    Expect.equals("finalConstGlobal", lib.finalConstGlobal);
+    Expect.equals(0, lib.sideEffectCounter);
+    Expect.equals("finalNonConstGlobal", lib.finalNonConstGlobal);
+    Expect.equals(1, lib.sideEffectCounter);
+    Expect.equals("finalConstGlobal", lib.finalConstGlobal);
+    Expect.equals("finalNonConstGlobal", lib.finalNonConstGlobal);
+    Expect.equals("lazyConstGlobal", lib.lazyConstGlobal);
+    Expect.equals(1, lib.sideEffectCounter);
+    Expect.equals("lazyNonConstGlobal", lib.lazyNonConstGlobal);
+    Expect.equals(2, lib.sideEffectCounter);
+    Expect.equals("finalConstGlobal", lib.readFinalConstGlobal());
+    Expect.equals("finalNonConstGlobal", lib.readFinalNonConstGlobal());
+    Expect.equals("lazyConstGlobal", lib.readLazyConstGlobal());
+    Expect.equals("lazyNonConstGlobal", lib.readLazyNonConstGlobal());
+
+    lib.lazyConstGlobal = "lazyConstGlobal_mutated";
+    lib.lazyNonConstGlobal = "lazyNonConstGlobal_mutated";
+    Expect.equals("lazyConstGlobal_mutated", lib.lazyConstGlobal);
+    Expect.equals("lazyNonConstGlobal_mutated", lib.lazyNonConstGlobal);
+    Expect.equals("lazyConstGlobal_mutated", lib.readLazyConstGlobal());
+    Expect.equals("lazyNonConstGlobal_mutated", lib.readLazyNonConstGlobal());
+    Expect.equals(2, lib.sideEffectCounter);
+
+    lib.writeLazyConstGlobal("lazyConstGlobal_mutated2");
+    lib.writeLazyNonConstGlobal("lazyNonConstGlobal_mutated2");
+    Expect.equals("lazyConstGlobal_mutated2", lib.lazyConstGlobal);
+    Expect.equals("lazyNonConstGlobal_mutated2", lib.lazyNonConstGlobal);
+    Expect.equals("lazyConstGlobal_mutated2", lib.readLazyConstGlobal());
+    Expect.equals("lazyNonConstGlobal_mutated2", lib.readLazyNonConstGlobal());
+
+    Expect.mapEquals({}, lib.lazyConstGlobal2);
+    lib.const1Global = const {'foo': 'bar'};
+    Expect.equals(2, lib.sideEffectCounter);
+    Expect.equals(const {'foo': 'bar'}['foo'], lib.const1Global['foo']);
+    // Try loading the deferred library again, should not reset the globals.
+    lib.loadLibrary().then((_) {
+      Expect.equals(const {'foo': 'bar'}['foo'], lib.const1Global['foo']);
+      asyncEnd();
+    });
+  });
+}
diff --git a/tests/language/deferred/import_core_test.dart b/tests/language/deferred/import_core_test.dart
new file mode 100644
index 0000000..f3d6644
--- /dev/null
+++ b/tests/language/deferred/import_core_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+// Nothing in the language spec explicitly prohibits a deferred import of
+// 'dart:core'.  Make sure it doesn't lead to any strange behavior.
+
+import "dart:core" deferred as core;
+
+main() {
+  core.loadLibrary().then((_) => null);
+}
diff --git a/tests/language/deferred/inheritance_constraints_lib.dart b/tests/language/deferred/inheritance_constraints_lib.dart
new file mode 100644
index 0000000..38d3e68
--- /dev/null
+++ b/tests/language/deferred/inheritance_constraints_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {}
+
+class Foo2 {}
diff --git a/tests/language/deferred/inheritance_constraints_runtime_test.dart b/tests/language/deferred/inheritance_constraints_runtime_test.dart
new file mode 100644
index 0000000..719a170
--- /dev/null
+++ b/tests/language/deferred/inheritance_constraints_runtime_test.dart
@@ -0,0 +1,43 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "inheritance_constraints_lib.dart" deferred as lib;
+
+class Foo {}
+
+class Foo2 extends D {}
+
+class A extends
+
+    Foo {}
+
+class B
+    implements
+
+        Foo {}
+
+class C1 {}
+
+class C = C1
+    with
+
+        Foo;
+
+class D {
+  D();
+  factory D.factory() =
+
+      Foo2;
+}
+
+void main() {
+  new A();
+  new B();
+  new C();
+  new D.factory();
+}
diff --git a/tests/language/deferred/inheritance_constraints_test.dart b/tests/language/deferred/inheritance_constraints_test.dart
new file mode 100644
index 0000000..9dd18f2
--- /dev/null
+++ b/tests/language/deferred/inheritance_constraints_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "inheritance_constraints_lib.dart" deferred as lib;
+
+class Foo {}
+
+class Foo2 extends D {}
+
+class A extends lib.Foo {}
+//              ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.EXTENDS_DEFERRED_CLASS
+
+class B implements lib.Foo {}
+//                 ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_DEFERRED_CLASS
+
+class C1 {}
+
+class C = C1 with lib.Foo;
+//                ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.MIXIN_DEFERRED_CLASS
+
+class D {
+  D();
+  factory D.factory() = lib.Foo2;
+//                      ^^^^^^^^
+// [analyzer] STATIC_WARNING.REDIRECT_TO_INVALID_RETURN_TYPE
+// [cfe] The constructor function type 'Foo2 Function()' isn't a subtype of 'D Function()'.
+}
+
+void main() {
+  new A();
+  new B();
+  new C();
+  new D.factory();
+}
diff --git a/tests/language/deferred/inlined_test.dart b/tests/language/deferred/inlined_test.dart
new file mode 100644
index 0000000..5aa45b0
--- /dev/null
+++ b/tests/language/deferred/inlined_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+// Declares foo that returns 42.
+import "constraints_lib2.dart" deferred as lib;
+
+import 'package:expect/expect.dart';
+
+bool libLoaded = false;
+
+main() {
+  Expect.equals(88, heyhey());
+
+  // Trigger optimization of 'hehey' which inlines 'barbar'.
+  for (int i = 0; i < 30000; i++) {
+    heyhey();
+  }
+
+  lib.loadLibrary().then((_) {
+    libLoaded = true;
+    Expect.equals(42, heyhey());
+  });
+}
+
+// Inline bar in optimized code.
+heyhey() => barbar();
+
+barbar() {
+  if (libLoaded) {
+    // Returns 42.
+    return lib.foo();
+  }
+  return 88;
+}
diff --git a/tests/language/deferred/load_constants.dart b/tests/language/deferred/load_constants.dart
new file mode 100644
index 0000000..a67bd03
--- /dev/null
+++ b/tests/language/deferred/load_constants.dart
@@ -0,0 +1,20 @@
+// 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 version of two-argument Ackermann-Peter function.
+
+library deferred_load_constants;
+
+// Constant declaration.
+const c = const C();
+
+// Class declaration (`C` is a constant expression).
+class C {
+  const C();
+  static int staticfun(int x) => x;
+}
+
+// Function type definition.
+typedef int funtype(int x);
+// Top-level function.
+int toplevel(int x) => x;
diff --git a/tests/language/deferred/load_constants_runtime_test.dart b/tests/language/deferred/load_constants_runtime_test.dart
new file mode 100644
index 0000000..97e91a2
--- /dev/null
+++ b/tests/language/deferred/load_constants_runtime_test.dart
@@ -0,0 +1,38 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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 version of two-argument Ackermann-Peter function.
+
+library deferred_load_constants;
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "load_constants.dart" deferred as foo;
+import "load_constants.dart";
+
+main() {
+  asyncStart();
+  Expect.throws(() => foo.c);
+  Expect.throws(() => foo.C);
+  Expect.throws(() => foo.funtype);
+  Expect.throws(() => foo.toplevel);
+  foo.loadLibrary().whenComplete(() {
+    // Reading constant declarations through deferred prefix works.
+    Expect.identical(c, foo.c);
+    Expect.identical(C, foo.C);
+    Expect.identical(funtype, foo.funtype);
+    Expect.identical(toplevel, foo.toplevel);
+    Expect.identical(C.staticfun, foo.C.staticfun);
+    // Access through deferred prefix is not a constant expression.
+
+
+
+
+
+
+    asyncEnd();
+  });
+}
diff --git a/tests/language/deferred/load_constants_test.dart b/tests/language/deferred/load_constants_test.dart
new file mode 100644
index 0000000..a57e24c
--- /dev/null
+++ b/tests/language/deferred/load_constants_test.dart
@@ -0,0 +1,60 @@
+// 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 version of two-argument Ackermann-Peter function.
+
+library deferred_load_constants;
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "load_constants.dart" deferred as foo;
+import "load_constants.dart";
+
+main() {
+  asyncStart();
+  Expect.throws(() => foo.c);
+  Expect.throws(() => foo.C);
+  Expect.throws(() => foo.funtype);
+  Expect.throws(() => foo.toplevel);
+  foo.loadLibrary().whenComplete(() {
+    // Reading constant declarations through deferred prefix works.
+    Expect.identical(c, foo.c);
+    Expect.identical(C, foo.C);
+    Expect.identical(funtype, foo.funtype);
+    Expect.identical(toplevel, foo.toplevel);
+    Expect.identical(C.staticfun, foo.C.staticfun);
+    // Access through deferred prefix is not a constant expression.
+    Expect.throws(() => const [foo.c]);
+    //                  ^
+    // [cfe] Constant evaluation error:
+    //                         ^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_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
+    // [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
+    // [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
+    // [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
+    // [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/deferred/load_inval_code_lib.dart b/tests/language/deferred/load_inval_code_lib.dart
new file mode 100644
index 0000000..512a8b3
--- /dev/null
+++ b/tests/language/deferred/load_inval_code_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() {
+  return "foo from library";
+}
diff --git a/tests/language/deferred/load_inval_code_test.dart b/tests/language/deferred/load_inval_code_test.dart
new file mode 100644
index 0000000..596e0bc
--- /dev/null
+++ b/tests/language/deferred/load_inval_code_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--optimization-counter-threshold=100
+
+import "load_inval_code_lib.dart" deferred as d;
+
+bool loaded = false;
+
+var x = 0;
+
+bla() {
+  if (loaded) {
+    // Loading the library should have invalidated the optimized
+    // code containing the NSME. Now expect this call to succeed.
+    d.foo();
+  } else {
+    // Do some "busy work" to trigger optimization.
+    for (var i = 0; i < 100; i++) {
+      x++;
+    }
+  }
+}
+
+warmup() {
+  for (int i = 1; i < 1000; i++) {
+    bla();
+  }
+}
+
+main() {
+  warmup();
+  d.loadLibrary().then((_) {
+    loaded = true;
+    bla();
+  });
+}
diff --git a/tests/language/deferred/load_library_wrong_args_lib.dart b/tests/language/deferred/load_library_wrong_args_lib.dart
new file mode 100644
index 0000000..0f02e43
--- /dev/null
+++ b/tests/language/deferred/load_library_wrong_args_lib.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() => 42;
diff --git a/tests/language/deferred/load_library_wrong_args_test.dart b/tests/language/deferred/load_library_wrong_args_test.dart
new file mode 100644
index 0000000..c991e2e6
--- /dev/null
+++ b/tests/language/deferred/load_library_wrong_args_test.dart
@@ -0,0 +1,10 @@
+import "load_library_wrong_args_lib.dart" deferred as lib;
+
+void main() {
+  // Loadlibrary should be called without arguments.
+  lib.loadLibrary(10);
+//^
+// [cfe] 'loadLibrary' takes no arguments.
+//               ^^^^
+// [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+}
diff --git a/tests/language/deferred/mixin_lib1.dart b/tests/language/deferred/mixin_lib1.dart
new file mode 100644
index 0000000..3b43ffe
--- /dev/null
+++ b/tests/language/deferred/mixin_lib1.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib1;
+
+import "mixin_shared.dart";
+import "mixin_test.dart";
+
+class Mixin {
+  foo() => "lib1.Mixin";
+}
+
+class A extends Object with NonDeferredMixin {
+  foo() {
+    return "A with " + super.foo();
+  }
+}
+
+class B extends Object with Mixin {
+  foo() {
+    return "B with " + super.foo();
+  }
+}
+
+class C extends Object with Mixin, NonDeferredMixin1 {
+  foo() {
+    return "C with " + super.foo();
+  }
+}
+
+class D extends Object with NonDeferredMixin2, Mixin {
+  foo() {
+    return "D with " + super.foo();
+  }
+}
+
+class E extends Object with SharedMixin {
+  foo() {
+    return "E with " + super.foo();
+  }
+}
diff --git a/tests/language/deferred/mixin_lib2.dart b/tests/language/deferred/mixin_lib2.dart
new file mode 100644
index 0000000..32fafef
--- /dev/null
+++ b/tests/language/deferred/mixin_lib2.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib2;
+
+import "mixin_shared.dart";
+
+class A extends Object with SharedMixin {
+  foo() {
+    return "lib2.A with " + super.foo();
+  }
+}
diff --git a/tests/language/deferred/mixin_shared.dart b/tests/language/deferred/mixin_shared.dart
new file mode 100644
index 0000000..8b6a293
--- /dev/null
+++ b/tests/language/deferred/mixin_shared.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library shared;
+
+class SharedMixin {
+  foo() => "SharedMixin";
+}
diff --git a/tests/language/deferred/mixin_test.dart b/tests/language/deferred/mixin_test.dart
new file mode 100644
index 0000000..33594b7
--- /dev/null
+++ b/tests/language/deferred/mixin_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "mixin_lib1.dart" deferred as lib1;
+import "mixin_lib2.dart" deferred as lib2;
+
+class NonDeferredMixin {
+  foo() => "NonDeferredMixin";
+}
+
+class NonDeferredMixin1 {
+  foo() => "NonDeferredMixin1";
+}
+
+class NonDeferredMixin2 {
+  foo() => "NonDeferredMixin2";
+}
+
+main() {
+  Expect.equals("NonDeferredMixin", new NonDeferredMixin().foo());
+  Expect.equals("NonDeferredMixin1", new NonDeferredMixin1().foo());
+  Expect.equals("NonDeferredMixin2", new NonDeferredMixin2().foo());
+  asyncStart();
+  lib1.loadLibrary().then((_) {
+    Expect.equals("lib1.Mixin", new lib1.Mixin().foo());
+    Expect.equals("A with NonDeferredMixin", new lib1.A().foo());
+    Expect.equals("B with lib1.Mixin", new lib1.B().foo());
+    Expect.equals("C with NonDeferredMixin1", new lib1.C().foo());
+    Expect.equals("D with lib1.Mixin", new lib1.D().foo());
+    Expect.equals("E with SharedMixin", new lib1.E().foo());
+    lib2.loadLibrary().then((_) {
+      Expect.equals("lib2.A with SharedMixin", new lib2.A().foo());
+      asyncEnd();
+    });
+  });
+}
diff --git a/tests/language/deferred/no_prefix_runtime_test.dart b/tests/language/deferred/no_prefix_runtime_test.dart
new file mode 100644
index 0000000..1cbab75
--- /dev/null
+++ b/tests/language/deferred/no_prefix_runtime_test.dart
@@ -0,0 +1,13 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Loading a deferred library without prefix is not allowed.
+import "constraints_lib2.dart"
+
+    ;
+
+void main() {}
diff --git a/tests/language/deferred/no_prefix_test.dart b/tests/language/deferred/no_prefix_test.dart
new file mode 100644
index 0000000..ff778e5
--- /dev/null
+++ b/tests/language/deferred/no_prefix_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Loading a deferred library without prefix is not allowed.
+import "constraints_lib2.dart"
+  deferred
+//^^^^^^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_PREFIX_IN_DEFERRED_IMPORT
+// [cfe] Deferred imports should have a prefix.
+    ;
+
+void main() {}
diff --git a/tests/language/deferred/no_such_method_lib.dart b/tests/language/deferred/no_such_method_lib.dart
new file mode 100644
index 0000000..ccb0091
--- /dev/null
+++ b/tests/language/deferred/no_such_method_lib.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@proxy
+class C {
+  noSuchMethod(Invocation invocation) => 42;
+}
diff --git a/tests/language/deferred/no_such_method_test.dart b/tests/language/deferred/no_such_method_test.dart
new file mode 100644
index 0000000..0673319
--- /dev/null
+++ b/tests/language/deferred/no_such_method_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "no_such_method_lib.dart" deferred as lib;
+
+void main() {
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(42, (new lib.C() as dynamic).nonExisting());
+    asyncEnd();
+  });
+}
diff --git a/tests/language/deferred/not_loaded_check_lib.dart b/tests/language/deferred/not_loaded_check_lib.dart
new file mode 100644
index 0000000..704b4c1
--- /dev/null
+++ b/tests/language/deferred/not_loaded_check_lib.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo(int arg) {}
+
+class C {
+  C(int arg) {}
+  static foo(int arg) {}
+}
+
+var a;
+
+int get getter => 42;
+
+void set setter(int arg) {
+  a = 10;
+}
+
+var list = <int>[];
+
+var closure = (int arg) => 3;
diff --git a/tests/language/deferred/not_loaded_check_test.dart b/tests/language/deferred/not_loaded_check_test.dart
new file mode 100644
index 0000000..44c0fd4
--- /dev/null
+++ b/tests/language/deferred/not_loaded_check_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "not_loaded_check_lib.dart" deferred as lib;
+
+// Test that we give appropriate errors when accessing an element that is not
+// yet loaded.
+
+var c;
+
+expectSideEffect(test) {
+  c = 0;
+  test();
+  Expect.isTrue(c == 1);
+}
+
+expectNoSideEffect(test) {
+  c = 0;
+  test();
+  Expect.isTrue(c == 0);
+}
+
+expectThrowsNotLoaded(test) {
+  Expect.throws(test, (e) => e is Error);
+}
+
+int sideEffect() {
+  c = 1;
+  return 10;
+}
+
+void main() {
+  expectSideEffect(() {
+    expectThrowsNotLoaded(() {
+      lib.foo(sideEffect());
+    });
+  });
+  expectNoSideEffect(() {
+    expectThrowsNotLoaded(() {
+      lib.C.foo(sideEffect());
+    });
+  });
+  expectSideEffect(() {
+    expectThrowsNotLoaded(() {
+      new lib.C(sideEffect());
+    });
+  });
+  expectThrowsNotLoaded(() {
+    lib.a;
+  });
+  expectSideEffect(() {
+    expectThrowsNotLoaded(() {
+      lib.a = sideEffect();
+    });
+  });
+  expectThrowsNotLoaded(() {
+    lib.getter;
+  });
+  expectSideEffect(() {
+    expectThrowsNotLoaded(() {
+      lib.setter = sideEffect();
+    });
+  });
+  expectNoSideEffect(() {
+    expectThrowsNotLoaded(() {
+      lib.list[sideEffect()] = sideEffect();
+    });
+  });
+  expectSideEffect(() {
+    expectThrowsNotLoaded(() {
+      lib.closure(sideEffect());
+    });
+  });
+}
diff --git a/tests/language/deferred/only_constant_lib.dart b/tests/language/deferred/only_constant_lib.dart
new file mode 100644
index 0000000..1c84126
--- /dev/null
+++ b/tests/language/deferred/only_constant_lib.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const constant = const ["a", "b", "c"];
diff --git a/tests/language/deferred/only_constant_test.dart b/tests/language/deferred/only_constant_test.dart
new file mode 100644
index 0000000..37d2a2a
--- /dev/null
+++ b/tests/language/deferred/only_constant_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing import of only constants from a deferred library.
+
+import 'package:expect/expect.dart';
+
+import "only_constant_lib.dart" deferred as lib;
+
+void main() {
+  lib.loadLibrary().then((_) {
+    Expect.equals(lib.constant, const ["a", "b", "c"]);
+  });
+}
diff --git a/tests/language/deferred/optimized_test.dart b/tests/language/deferred/optimized_test.dart
new file mode 100644
index 0000000..7fd0a99
--- /dev/null
+++ b/tests/language/deferred/optimized_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --compiler-passes=-Inlining
+
+// Declares foo that returns 42.
+import "constraints_lib2.dart" deferred as lib;
+
+import 'package:expect/expect.dart';
+
+bool libLoaded = false;
+
+main() {
+  Expect.equals(88, heyhey());
+
+  for (int i = 0; i < 30; i++) {
+    heyhey();
+  }
+
+  lib.loadLibrary().then((_) {
+    libLoaded = true;
+    Expect.equals(42, heyhey());
+  });
+}
+
+heyhey() => barbar();
+
+barbar() {
+  if (libLoaded) {
+    // Returns 42.
+    return lib.foo();
+  }
+  return 88;
+}
diff --git a/tests/language/deferred/prefix_constraints_lib.dart b/tests/language/deferred/prefix_constraints_lib.dart
new file mode 100644
index 0000000..c79d4e5
--- /dev/null
+++ b/tests/language/deferred/prefix_constraints_lib.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() => 24;
diff --git a/tests/language/deferred/prefix_constraints_lib2.dart b/tests/language/deferred/prefix_constraints_lib2.dart
new file mode 100644
index 0000000..c79d4e5
--- /dev/null
+++ b/tests/language/deferred/prefix_constraints_lib2.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() => 24;
diff --git a/tests/language/deferred/redirecting_factory_lib1.dart b/tests/language/deferred/redirecting_factory_lib1.dart
new file mode 100644
index 0000000..1e1a7a1
--- /dev/null
+++ b/tests/language/deferred/redirecting_factory_lib1.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib1;
+
+import "redirecting_factory_lib2.dart" deferred as lib2;
+import "redirecting_factory_test.dart" as main;
+
+loadLib2() {
+  return lib2.loadLibrary();
+}
+
+class C extends main.C {
+  String get foo => "lib1";
+  C();
+  factory C.a() = lib2.C;
+}
diff --git a/tests/language/deferred/redirecting_factory_lib2.dart b/tests/language/deferred/redirecting_factory_lib2.dart
new file mode 100644
index 0000000..a72be64
--- /dev/null
+++ b/tests/language/deferred/redirecting_factory_lib2.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib2;
+
+import "redirecting_factory_lib1.dart" as lib1;
+
+class C extends lib1.C {
+  String get foo => "lib2";
+}
diff --git a/tests/language/deferred/redirecting_factory_test.dart b/tests/language/deferred/redirecting_factory_test.dart
new file mode 100644
index 0000000..1ee76d3
--- /dev/null
+++ b/tests/language/deferred/redirecting_factory_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+library main;
+
+import "redirecting_factory_lib1.dart" deferred as lib1;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+class C {
+  String get foo => "main";
+  C();
+  factory C.a() = lib1.C;
+  factory C.b() = lib1.C.a;
+}
+
+test1() async {
+  Expect.throws(() {
+    new C.a();
+  });
+  Expect.throws(() {
+    new C.b();
+  });
+}
+
+test2() async {
+  await lib1.loadLibrary();
+  Expect.equals("lib1", new C.a().foo);
+  Expect.throws(() {
+    new C.b();
+  });
+}
+
+test3() async {
+  await lib1.loadLibrary();
+  await lib1.loadLib2();
+  Expect.equals("lib1", new C.a().foo);
+  Expect.equals("lib2", new C.b().foo);
+}
+
+test() async {
+  await test1();
+  await test2();
+  await test3();
+}
+
+void main() {
+  asyncStart();
+  test().then((_) => asyncEnd());
+}
diff --git a/tests/language/deferred/regression_22995_lib.dart b/tests/language/deferred/regression_22995_lib.dart
new file mode 100644
index 0000000..b6e3aef
--- /dev/null
+++ b/tests/language/deferred/regression_22995_lib.dart
@@ -0,0 +1,11 @@
+// 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 'regression_22995_test.dart';
+
+foofoo() {
+  new A();
+  new B();
+  new C();
+}
diff --git a/tests/language/deferred/regression_22995_test.dart b/tests/language/deferred/regression_22995_test.dart
new file mode 100644
index 0000000..fdd36c1
--- /dev/null
+++ b/tests/language/deferred/regression_22995_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that closurizing a function implies a dependency on its type.
+
+import "package:expect/expect.dart";
+
+import 'regression_22995_lib.dart' deferred as lib;
+
+class A {}
+
+class B {}
+
+class C {}
+
+typedef Ti(int x);
+typedef TB(B x);
+typedef TTi(Ti x);
+typedef Tg<T>(T x);
+
+class T {
+  fA(A a) => null;
+  fTB(TB a) => null;
+  fTgC(Tg<C> a) => null;
+}
+
+main() {
+  Expect.isFalse(new T().fA is Ti);
+  Expect.isFalse(new T().fTB is TTi);
+  Expect.isFalse(new T().fTgC is TTi);
+  lib.loadLibrary().then((_) {
+    lib.foofoo();
+  });
+}
diff --git a/tests/language/deferred/regression_28678_lib.dart b/tests/language/deferred/regression_28678_lib.dart
new file mode 100644
index 0000000..d985e0a
--- /dev/null
+++ b/tests/language/deferred/regression_28678_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var v;
+
+class Clazz {}
diff --git a/tests/language/deferred/regression_28678_test.dart b/tests/language/deferred/regression_28678_test.dart
new file mode 100644
index 0000000..16a95f9
--- /dev/null
+++ b/tests/language/deferred/regression_28678_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Test that await after deferred loading works as expected.
+
+import 'dart:async';
+import "package:expect/expect.dart";
+import 'regression_28678_lib.dart' deferred as lib;
+
+class A {
+  m() => "here";
+}
+
+f(a, b) => new Future.microtask(() {});
+
+class R {
+  Future test_deferred() async {
+    var a = new A();
+    await lib.loadLibrary();
+    await f(lib.Clazz, lib.v);
+    Expect.equals("here", a.m());
+  }
+}
+
+main() async {
+  await new R().test_deferred();
+}
diff --git a/tests/language/deferred/shadow_load_library_lib.dart b/tests/language/deferred/shadow_load_library_lib.dart
new file mode 100644
index 0000000..e7811aa
--- /dev/null
+++ b/tests/language/deferred/shadow_load_library_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+loadLibrary() => 42;
+
+var trueVar = true;
diff --git a/tests/language/deferred/shadow_load_library_test.dart b/tests/language/deferred/shadow_load_library_test.dart
new file mode 100644
index 0000000..2c096c9
--- /dev/null
+++ b/tests/language/deferred/shadow_load_library_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+// This library contains a member loadLibrary.
+// Check that we shadow this member.
+import "shadow_load_library_lib.dart" deferred as lib;
+
+void main() {
+  var x = lib.loadLibrary();
+  Expect.isTrue(x is Future);
+  asyncStart();
+  x.then((_) {
+    Expect.isTrue(lib.trueVar);
+    // Check that shadowing still is in place after loading the library.
+    Expect.isTrue(lib.loadLibrary() is Future);
+    asyncEnd();
+  });
+}
diff --git a/tests/language/deferred/shared_and_unshared_classes_lib1.dart b/tests/language/deferred/shared_and_unshared_classes_lib1.dart
new file mode 100644
index 0000000..28d2ef3
--- /dev/null
+++ b/tests/language/deferred/shared_and_unshared_classes_lib1.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib1;
+
+import "shared_and_unshared_classes_lib_shared.dart";
+
+foo() {
+  print(new C1());
+  print(new CShared());
+}
diff --git a/tests/language/deferred/shared_and_unshared_classes_lib2.dart b/tests/language/deferred/shared_and_unshared_classes_lib2.dart
new file mode 100644
index 0000000..86fc901
--- /dev/null
+++ b/tests/language/deferred/shared_and_unshared_classes_lib2.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib2;
+
+import "shared_and_unshared_classes_lib_shared.dart";
+
+foo() {
+  print(new C2());
+  print(new CShared());
+}
diff --git a/tests/language/deferred/shared_and_unshared_classes_lib_shared.dart b/tests/language/deferred/shared_and_unshared_classes_lib_shared.dart
new file mode 100644
index 0000000..a2c5665
--- /dev/null
+++ b/tests/language/deferred/shared_and_unshared_classes_lib_shared.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library shared;
+
+class CShared {
+  toString() => "shared";
+}
+
+class C1 {
+  toString() => "C1";
+}
+
+class C2 {
+  toString() => "C2";
+}
diff --git a/tests/language/deferred/shared_and_unshared_classes_test.dart b/tests/language/deferred/shared_and_unshared_classes_test.dart
new file mode 100644
index 0000000..a815c74
--- /dev/null
+++ b/tests/language/deferred/shared_and_unshared_classes_test.dart
@@ -0,0 +1,22 @@
+// 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:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "shared_and_unshared_classes_lib1.dart" deferred as lib1;
+import "shared_and_unshared_classes_lib2.dart" deferred as lib2;
+import "dart:async";
+
+void main() {
+  asyncTest(() {
+    return Future.wait([
+      lib1.loadLibrary().then((_) {
+        lib1.foo();
+      }),
+      lib2.loadLibrary().then((_) {
+        lib2.foo();
+      })
+    ]);
+  });
+}
diff --git a/tests/language/deferred/static_seperate_lib1.dart b/tests/language/deferred/static_seperate_lib1.dart
new file mode 100644
index 0000000..07e9cf5
--- /dev/null
+++ b/tests/language/deferred/static_seperate_lib1.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib1;
+
+class ConstClass {
+  final x;
+  const ConstClass(this.x);
+}
+
+var x = const ConstClass(const ConstClass(1));
+
+class C {
+  static foo() {
+    () {}(); // Hack to avoid inlining.
+    return 1;
+  }
+
+  bar() {
+    () {}(); // Hack to avoid inlining.
+    return 1;
+  }
+}
+
+class C1 {
+  static var foo = const {};
+  var bar = const {};
+}
+
+class C2 {
+  static var foo = new Map<int, int>.from({1: 2});
+  var bar = new Map<int, int>.from({1: 2});
+}
+
+class C3 {
+  static final foo = const ConstClass(const ConstClass(1));
+  final bar = const ConstClass(const ConstClass(1));
+}
+
+class C4 {
+  static final foo = new Map<ConstClass, ConstClass>.from({x: x});
+  final bar = new Map<ConstClass, ConstClass>.from({x: x});
+}
+
+class C5 {
+  static const foo = const [
+    const {1: 3}
+  ];
+  bar() {
+    () {}(); // Hack to avoid inlining.
+    return 1;
+  }
+}
diff --git a/tests/language/deferred/static_seperate_lib2.dart b/tests/language/deferred/static_seperate_lib2.dart
new file mode 100644
index 0000000..683b9a4
--- /dev/null
+++ b/tests/language/deferred/static_seperate_lib2.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib2;
+
+import "package:expect/expect.dart";
+import "static_seperate_lib1.dart";
+
+foo() {
+  Expect.equals(1, C.foo());
+  Expect.mapEquals({}, C1.foo);
+
+  Expect.mapEquals({1: 2}, C2.foo);
+  C2.foo = {1: 2};
+  Expect.mapEquals({1: 2}, C2.foo);
+
+  Expect.equals(x, C3.foo);
+  Expect.mapEquals({x: x}, C4.foo);
+  Expect.listEquals([
+    const {1: 3}
+  ], C5.foo);
+}
diff --git a/tests/language/deferred/static_seperate_test.dart b/tests/language/deferred/static_seperate_test.dart
new file mode 100644
index 0000000..c920eb8
--- /dev/null
+++ b/tests/language/deferred/static_seperate_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The class lib1.C is referenced via lib1
+// The static function lib1.C.foo is referenced via lib2
+// Dart2js will put them in seperate hunks.
+// Similarly for C2, ..., C5.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "static_seperate_lib1.dart" deferred as lib1;
+import "static_seperate_lib2.dart" deferred as lib2;
+
+void main() {
+  asyncStart();
+  Expect.throws(() => new lib1.C());
+  lib1.loadLibrary().then((_) {
+    lib2.loadLibrary().then((_) {
+      print("HERE");
+      Expect.equals(1, new lib1.C().bar());
+      var x = new lib1.C2();
+      Expect.mapEquals({1: 2}, x.bar);
+      x.bar = {2: 3};
+      Expect.mapEquals({2: 3}, x.bar);
+
+      Expect.equals(lib1.x, new lib1.C3().bar);
+      Expect.mapEquals({lib1.x: lib1.x}, new lib1.C4().bar);
+      Expect.equals(1, new lib1.C5().bar());
+
+      lib2.foo();
+      asyncEnd();
+    });
+  });
+}
diff --git a/tests/language/deferred/super_dependency_lib.dart b/tests/language/deferred/super_dependency_lib.dart
new file mode 100644
index 0000000..8638a4f
--- /dev/null
+++ b/tests/language/deferred/super_dependency_lib.dart
@@ -0,0 +1,11 @@
+// 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.
+
+class A {}
+
+class C extends A {
+  foo() {
+    super.foo = 3;
+  }
+}
diff --git a/tests/language/deferred/super_dependency_runtime_test.dart b/tests/language/deferred/super_dependency_runtime_test.dart
new file mode 100644
index 0000000..c09a7f8
--- /dev/null
+++ b/tests/language/deferred/super_dependency_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Regression test.
+// lib.C.foo has code that references `super.foo=` that does not exist. This
+// used to cause a crash.
+
+import "package:expect/expect.dart";
+
+
+main() async {
+
+
+}
diff --git a/tests/language/deferred/super_dependency_test.dart b/tests/language/deferred/super_dependency_test.dart
new file mode 100644
index 0000000..f49380c
--- /dev/null
+++ b/tests/language/deferred/super_dependency_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Regression test.
+// lib.C.foo has code that references `super.foo=` that does not exist. This
+// used to cause a crash.
+
+import "package:expect/expect.dart";
+//        ^^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SUPER_SETTER
+// [cfe] Superclass has no setter named 'foo'.
+import "super_dependency_lib.dart" deferred as lib;
+
+main() async {
+  await lib.loadLibrary();
+  Expect.throwsNoSuchMethodError(() => new lib.C().foo());
+}
diff --git a/tests/language/deferred/type_dependency_lib1.dart b/tests/language/deferred/type_dependency_lib1.dart
new file mode 100644
index 0000000..491ecc6
--- /dev/null
+++ b/tests/language/deferred/type_dependency_lib1.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2015, the Dart Team. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+library lib1;
+
+import "type_dependency_lib3.dart";
+
+bool fooIs(x) {
+  return x is A;
+}
+
+bool fooAs(x) {
+  try {
+    return (x as A).p;
+  } on TypeError {
+    return false;
+  }
+}
+
+bool fooAnnotation(x) {
+  try {
+    A y = x;
+    return y is! String;
+  } on TypeError {
+    return false;
+  }
+}
diff --git a/tests/language/deferred/type_dependency_lib2.dart b/tests/language/deferred/type_dependency_lib2.dart
new file mode 100644
index 0000000..d20f4c0
--- /dev/null
+++ b/tests/language/deferred/type_dependency_lib2.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, the Dart Team. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+library lib2;
+
+import "type_dependency_lib3.dart";
+
+getInstance() {
+  return new A();
+}
diff --git a/tests/language/deferred/type_dependency_lib3.dart b/tests/language/deferred/type_dependency_lib3.dart
new file mode 100644
index 0000000..ae8c258
--- /dev/null
+++ b/tests/language/deferred/type_dependency_lib3.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib3;
+
+class A {
+  var p = true;
+}
diff --git a/tests/language/deferred/type_dependency_test.dart b/tests/language/deferred/type_dependency_test.dart
new file mode 100644
index 0000000..7d31d5f
--- /dev/null
+++ b/tests/language/deferred/type_dependency_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2015, the Dart Team. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+/// Checks that lib1.fooX's dependencies on [A] via is-checks, as-expressions
+/// and type-annotations(in checked-mode) is correctly tracked.
+
+import "type_dependency_lib1.dart" deferred as lib1;
+import "type_dependency_lib2.dart" deferred as lib2;
+import "package:expect/expect.dart";
+
+main() async {
+  await lib1.loadLibrary();
+  // Split the cases into a multi-test to test each feature separately.
+  Expect.isFalse(
+      lib1.fooIs //# is: ok
+      lib1.fooAs //# as: ok
+      lib1.fooAnnotation //# type_annotation: ok
+      ("string")
+      is! String //# none: ok
+      );
+  await lib2.loadLibrary();
+  Expect.isTrue(
+      lib1.fooIs //# is: ok
+      lib1.fooAs //# as: ok
+      lib1.fooAnnotation //# type_annotation: ok
+      (lib2.getInstance())
+      is! String //# none: ok
+      );
+}
diff --git a/tests/language/double/comparison_test.dart b/tests/language/double/comparison_test.dart
new file mode 100644
index 0000000..cf00962
--- /dev/null
+++ b/tests/language/double/comparison_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Tests VM optimizing compiler negate condition for doubles (bug 5376516).
+
+loop() {
+  for (double d = 0.0; d < 1100.0; d++) {}
+  for (double d = 0.0; d <= 1100.0; d++) {}
+  for (double d = 1000.0; d > 0.0; d--) {}
+  for (double d = 1000.0; d >= 0.0; d--) {}
+}
+
+main() {
+  loop();
+  loop();
+}
diff --git a/tests/language/double/identical_test.dart b/tests/language/double/identical_test.dart
new file mode 100644
index 0000000..16b99fe
--- /dev/null
+++ b/tests/language/double/identical_test.dart
@@ -0,0 +1,14 @@
+// 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:expect/expect.dart";
+
+main() {
+  Expect.isTrue(identical(42.0, 42.0));
+  Expect.isTrue(identical(-0.0, -0.0));
+  Expect.isTrue(identical(0.0, 0.0));
+  Expect.isTrue(identical(1.234E9, 1.234E9));
+  Expect.isFalse(identical(0.0, -0.0));
+  Expect.isTrue(identical(double.nan, double.nan));
+}
diff --git a/tests/language/double/int_addition_test.dart b/tests/language/double/int_addition_test.dart
new file mode 100644
index 0000000..809fec5
--- /dev/null
+++ b/tests/language/double/int_addition_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+// Test that optimized code does not silently convert integers to doubles.
+
+main() {
+  // Optimize add-op
+  for (int i = 0; i < 20; i++) {
+    addOp(1.1, 2.1);
+  }
+
+  Expect.isTrue(addOp(1.1, 2.1) is double);
+  Expect.isTrue(addOp(1, 2) is int);
+}
+
+addOp(a, b) => a + b;
diff --git a/tests/language/double/int_to_string_test.dart b/tests/language/double/int_to_string_test.dart
new file mode 100644
index 0000000..04c7ef7
--- /dev/null
+++ b/tests/language/double/int_to_string_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals("0.0", (0.0).toString());
+  Expect.equals("9.0", (9.0).toString());
+  Expect.equals("90.0", (90.0).toString());
+  Expect.equals(
+      "111111111111111110000.0", (111111111111111111111.0).toString());
+  Expect.equals("-9.0", (-9.0).toString());
+  Expect.equals("-90.0", (-90.0).toString());
+  Expect.equals(
+      "-111111111111111110000.0", (-111111111111111111111.0).toString());
+  Expect.equals("1000.0", (1000.0).toString());
+  Expect.equals("1000000000000000100.0", (1000000000000000128.0).toString());
+}
diff --git a/tests/language/double/invalid_runtime_test.dart b/tests/language/double/invalid_runtime_test.dart
new file mode 100644
index 0000000..a47bfc7
--- /dev/null
+++ b/tests/language/double/invalid_runtime_test.dart
@@ -0,0 +1,13 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test an invalid double format
+
+main() {
+
+  ;
+}
diff --git a/tests/language/double/invalid_test.dart b/tests/language/double/invalid_test.dart
new file mode 100644
index 0000000..dcfe3f4
--- /dev/null
+++ b/tests/language/double/invalid_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Test an invalid double format
+
+main() {
+  3457e
+//^
+// [cfe] Numbers in exponential notation should always contain an exponent (an integer number with an optional sign).
+//    ^
+// [analyzer] SYNTACTIC_ERROR.MISSING_DIGIT
+  ;
+}
diff --git a/tests/language/double/modulo_test.dart b/tests/language/double/modulo_test.dart
new file mode 100644
index 0000000..d17bcc5
--- /dev/null
+++ b/tests/language/double/modulo_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test optimization of modulo operator on Double.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+main() {
+  double k = -0.33333;
+  double firstResPos = doMod(k, 1.0);
+  double firstResNeg = doMod(k, -1.0);
+  for (int i = 0; i < 20; i++) {
+    Expect.equals(firstResPos, doMod(k, 1.0));
+    Expect.equals(firstResNeg, doMod(k, -1.0));
+  }
+}
+
+doMod(a, b) => a % b;
diff --git a/tests/language/double/nan_comparison_test.dart b/tests/language/double/nan_comparison_test.dart
new file mode 100644
index 0000000..64eb038
--- /dev/null
+++ b/tests/language/double/nan_comparison_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Tests double comparisons with NaN in different contexts.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+test_expr(a, b) => a != b;
+
+test_conditional(a, b) => a != b ? true : false;
+
+test_branch(a, b) {
+  if (a != b) {
+    return true;
+  }
+  return false;
+}
+
+main() {
+  Expect.equals(true, test_expr(0.5, double.nan));
+  for (var i = 0; i < 20; i++) test_expr(0.5, double.nan);
+  Expect.equals(true, test_expr(0.5, double.nan));
+
+  Expect.equals(true, test_conditional(0.5, double.nan));
+  for (var i = 0; i < 20; i++) test_conditional(0.5, double.nan);
+  Expect.equals(true, test_conditional(0.5, double.nan));
+
+  Expect.equals(true, test_branch(0.5, double.nan));
+  for (var i = 0; i < 20; i++) test_branch(0.5, double.nan);
+  Expect.equals(true, test_branch(0.5, double.nan));
+}
diff --git a/tests/language/double/to_string_as_exponential2_runtime_test.dart b/tests/language/double/to_string_as_exponential2_runtime_test.dart
new file mode 100644
index 0000000..1c0a498
--- /dev/null
+++ b/tests/language/double/to_string_as_exponential2_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  var v = 1.0;
+  Expect.throwsRangeError(() => v.toStringAsExponential(-1));
+  Expect.throwsRangeError(() => v.toStringAsExponential(21));
+
+
+
+}
diff --git a/tests/language/double/to_string_as_exponential2_test.dart b/tests/language/double/to_string_as_exponential2_test.dart
new file mode 100644
index 0000000..fbe03c4
--- /dev/null
+++ b/tests/language/double/to_string_as_exponential2_test.dart
@@ -0,0 +1,24 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  var v = 1.0;
+  Expect.throwsRangeError(() => v.toStringAsExponential(-1));
+  Expect.throwsRangeError(() => v.toStringAsExponential(21));
+  v.toStringAsExponential(1.5);
+  //                      ^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'double' can't be assigned to the parameter type 'int?'.
+  v.toStringAsExponential("string");
+  //                      ^^^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'String' can't be assigned to the parameter type 'int?'.
+  v.toStringAsExponential("3");
+  //                      ^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'String' can't be assigned to the parameter type 'int?'.
+}
diff --git a/tests/language/double/to_string_as_exponential3_test.dart b/tests/language/double/to_string_as_exponential3_test.dart
new file mode 100644
index 0000000..7300013
--- /dev/null
+++ b/tests/language/double/to_string_as_exponential3_test.dart
@@ -0,0 +1,12 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals("1.00000000000000000000e+0", (1.0).toStringAsExponential(20));
+  Expect.equals("1.00000000000000005551e-1", (0.1).toStringAsExponential(20));
+  Expect.equals(1.00000000000000005551e-1, 0.1);
+}
diff --git a/tests/language/double/to_string_as_exponential_test.dart b/tests/language/double/to_string_as_exponential_test.dart
new file mode 100644
index 0000000..e201913
--- /dev/null
+++ b/tests/language/double/to_string_as_exponential_test.dart
@@ -0,0 +1,100 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals("1e+0", (1.0).toStringAsExponential());
+  Expect.equals("1.1e+1", (11.0).toStringAsExponential());
+  Expect.equals("1.12e+2", (112.0).toStringAsExponential());
+  Expect.equals("1e+0", (1.0).toStringAsExponential(null));
+  Expect.equals("1.1e+1", (11.0).toStringAsExponential(null));
+  Expect.equals("1.12e+2", (112.0).toStringAsExponential(null));
+  Expect.equals("1e+0", (1.0).toStringAsExponential(0));
+  Expect.equals("1e+1", (11.0).toStringAsExponential(0));
+  Expect.equals("1e+2", (112.0).toStringAsExponential(0));
+  Expect.equals("1.0e+0", (1.0).toStringAsExponential(1));
+  Expect.equals("1.1e+1", (11.0).toStringAsExponential(1));
+  Expect.equals("1.1e+2", (112.0).toStringAsExponential(1));
+  Expect.equals("1.00e+0", (1.0).toStringAsExponential(2));
+  Expect.equals("1.10e+1", (11.0).toStringAsExponential(2));
+  Expect.equals("1.12e+2", (112.0).toStringAsExponential(2));
+  Expect.equals("1.000e+0", (1.0).toStringAsExponential(3));
+  Expect.equals("1.100e+1", (11.0).toStringAsExponential(3));
+  Expect.equals("1.120e+2", (112.0).toStringAsExponential(3));
+  Expect.equals("1e-1", (0.1).toStringAsExponential());
+  Expect.equals("1.1e-1", (0.11).toStringAsExponential());
+  Expect.equals("1.12e-1", (0.112).toStringAsExponential());
+  Expect.equals("1e-1", (0.1).toStringAsExponential(null));
+  Expect.equals("1.1e-1", (0.11).toStringAsExponential(null));
+  Expect.equals("1.12e-1", (0.112).toStringAsExponential(null));
+  Expect.equals("1e-1", (0.1).toStringAsExponential(0));
+  Expect.equals("1e-1", (0.11).toStringAsExponential(0));
+  Expect.equals("1e-1", (0.112).toStringAsExponential(0));
+  Expect.equals("1.0e-1", (0.1).toStringAsExponential(1));
+  Expect.equals("1.1e-1", (0.11).toStringAsExponential(1));
+  Expect.equals("1.1e-1", (0.112).toStringAsExponential(1));
+  Expect.equals("1.00e-1", (0.1).toStringAsExponential(2));
+  Expect.equals("1.10e-1", (0.11).toStringAsExponential(2));
+  Expect.equals("1.12e-1", (0.112).toStringAsExponential(2));
+  Expect.equals("1.000e-1", (0.1).toStringAsExponential(3));
+  Expect.equals("1.100e-1", (0.11).toStringAsExponential(3));
+  Expect.equals("1.120e-1", (0.112).toStringAsExponential(3));
+
+  Expect.equals("-0e+0", (-0.0).toStringAsExponential());
+  Expect.equals("-1e+0", (-1.0).toStringAsExponential());
+  Expect.equals("-1.1e+1", (-11.0).toStringAsExponential());
+  Expect.equals("-1.12e+2", (-112.0).toStringAsExponential());
+  Expect.equals("-0e+0", (-0.0).toStringAsExponential(null));
+  Expect.equals("-1e+0", (-1.0).toStringAsExponential(null));
+  Expect.equals("-1.1e+1", (-11.0).toStringAsExponential(null));
+  Expect.equals("-1.12e+2", (-112.0).toStringAsExponential(null));
+  Expect.equals("-1e+0", (-1.0).toStringAsExponential(0));
+  Expect.equals("-1e+1", (-11.0).toStringAsExponential(0));
+  Expect.equals("-1e+2", (-112.0).toStringAsExponential(0));
+  Expect.equals("-1.0e+0", (-1.0).toStringAsExponential(1));
+  Expect.equals("-1.1e+1", (-11.0).toStringAsExponential(1));
+  Expect.equals("-1.1e+2", (-112.0).toStringAsExponential(1));
+  Expect.equals("-1.00e+0", (-1.0).toStringAsExponential(2));
+  Expect.equals("-1.10e+1", (-11.0).toStringAsExponential(2));
+  Expect.equals("-1.12e+2", (-112.0).toStringAsExponential(2));
+  Expect.equals("-1.000e+0", (-1.0).toStringAsExponential(3));
+  Expect.equals("-1.100e+1", (-11.0).toStringAsExponential(3));
+  Expect.equals("-1.120e+2", (-112.0).toStringAsExponential(3));
+  Expect.equals("-1e-1", (-0.1).toStringAsExponential());
+  Expect.equals("-1.1e-1", (-0.11).toStringAsExponential());
+  Expect.equals("-1.12e-1", (-0.112).toStringAsExponential());
+  Expect.equals("-1e-1", (-0.1).toStringAsExponential(null));
+  Expect.equals("-1.1e-1", (-0.11).toStringAsExponential(null));
+  Expect.equals("-1.12e-1", (-0.112).toStringAsExponential(null));
+  Expect.equals("-1e-1", (-0.1).toStringAsExponential(0));
+  Expect.equals("-1e-1", (-0.11).toStringAsExponential(0));
+  Expect.equals("-1e-1", (-0.112).toStringAsExponential(0));
+  Expect.equals("-1.0e-1", (-0.1).toStringAsExponential(1));
+  Expect.equals("-1.1e-1", (-0.11).toStringAsExponential(1));
+  Expect.equals("-1.1e-1", (-0.112).toStringAsExponential(1));
+  Expect.equals("-1.00e-1", (-0.1).toStringAsExponential(2));
+  Expect.equals("-1.10e-1", (-0.11).toStringAsExponential(2));
+  Expect.equals("-1.12e-1", (-0.112).toStringAsExponential(2));
+  Expect.equals("-1.000e-1", (-0.1).toStringAsExponential(3));
+  Expect.equals("-1.100e-1", (-0.11).toStringAsExponential(3));
+  Expect.equals("-1.120e-1", (-0.112).toStringAsExponential(3));
+
+  Expect.equals("NaN", (double.nan).toStringAsExponential(2));
+  Expect.equals("Infinity", (double.infinity).toStringAsExponential(2));
+  Expect.equals("-Infinity", (-double.infinity).toStringAsExponential(2));
+  Expect.equals("1e+0", (1.0).toStringAsExponential(0));
+  Expect.equals("0e+0", (0.0).toStringAsExponential());
+  Expect.equals("0e+0", (0.0).toStringAsExponential(null));
+  Expect.equals("0.00e+0", (0.0).toStringAsExponential(2));
+  Expect.equals("1e+1", (11.2356).toStringAsExponential(0));
+  Expect.equals("1.1236e+1", (11.2356).toStringAsExponential(4));
+  Expect.equals("1.1236e-4", (0.000112356).toStringAsExponential(4));
+  Expect.equals("-1.1236e-4", (-0.000112356).toStringAsExponential(4));
+  Expect.equals("1.12356e-4", (0.000112356).toStringAsExponential());
+  Expect.equals("-1.12356e-4", (-0.000112356).toStringAsExponential());
+  Expect.equals("1.12356e-4", (0.000112356).toStringAsExponential(null));
+  Expect.equals("-1.12356e-4", (-0.000112356).toStringAsExponential(null));
+}
diff --git a/tests/language/double/to_string_as_fixed2_runtime_test.dart b/tests/language/double/to_string_as_fixed2_runtime_test.dart
new file mode 100644
index 0000000..821394f
--- /dev/null
+++ b/tests/language/double/to_string_as_fixed2_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  var v = 0.0;
+  Expect.throwsRangeError(() => v.toStringAsFixed(-1));
+  Expect.throwsRangeError(() => v.toStringAsFixed(21));
+
+
+
+}
diff --git a/tests/language/double/to_string_as_fixed_test.dart b/tests/language/double/to_string_as_fixed_test.dart
new file mode 100644
index 0000000..6e0aed2
--- /dev/null
+++ b/tests/language/double/to_string_as_fixed_test.dart
@@ -0,0 +1,104 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+class ToStringAsFixedTest {
+  static void testMain() {
+    Expect.equals("2.000", 2.0.toStringAsFixed(3));
+    Expect.equals("2.100", 2.1.toStringAsFixed(3));
+    Expect.equals("2.120", 2.12.toStringAsFixed(3));
+    Expect.equals("2.123", 2.123.toStringAsFixed(3));
+    Expect.equals("2.124", 2.1239.toStringAsFixed(3));
+    Expect.equals("NaN", (0.0 / 0.0).toStringAsFixed(3));
+    Expect.equals("Infinity", (1.0 / 0.0).toStringAsFixed(3));
+    Expect.equals("-Infinity", (-1.0 / 0.0).toStringAsFixed(3));
+    Expect.equals(
+        "1.1111111111111111e+21", 1111111111111111111111.0.toStringAsFixed(8));
+    Expect.equals("0.1", 0.1.toStringAsFixed(1));
+    Expect.equals("0.10", 0.1.toStringAsFixed(2));
+    Expect.equals("0.100", 0.1.toStringAsFixed(3));
+    Expect.equals("0.01", 0.01.toStringAsFixed(2));
+    Expect.equals("0.010", 0.01.toStringAsFixed(3));
+    Expect.equals("0.0100", 0.01.toStringAsFixed(4));
+    Expect.equals("0.00", 0.001.toStringAsFixed(2));
+    Expect.equals("0.001", 0.001.toStringAsFixed(3));
+    Expect.equals("0.0010", 0.001.toStringAsFixed(4));
+    Expect.equals("1.0000", 1.0.toStringAsFixed(4));
+    Expect.equals("1.0", 1.0.toStringAsFixed(1));
+    Expect.equals("1", 1.0.toStringAsFixed(0));
+    Expect.equals("12", 12.0.toStringAsFixed(0));
+    Expect.equals("1", 1.1.toStringAsFixed(0));
+    Expect.equals("12", 12.1.toStringAsFixed(0));
+    Expect.equals("1", 1.12.toStringAsFixed(0));
+    Expect.equals("12", 12.12.toStringAsFixed(0));
+    Expect.equals("0.0000006", 0.0000006.toStringAsFixed(7));
+    Expect.equals("0.00000006", 0.00000006.toStringAsFixed(8));
+    Expect.equals("0.000000060", 0.00000006.toStringAsFixed(9));
+    Expect.equals("0.0000000600", 0.00000006.toStringAsFixed(10));
+    Expect.equals("0", 0.0.toStringAsFixed(0));
+    Expect.equals("0.0", 0.0.toStringAsFixed(1));
+    Expect.equals("0.00", 0.0.toStringAsFixed(2));
+
+    Expect.equals("-0.1", (-0.1).toStringAsFixed(1));
+    Expect.equals("-0.10", (-0.1).toStringAsFixed(2));
+    Expect.equals("-0.100", (-0.1).toStringAsFixed(3));
+    Expect.equals("-0.01", (-0.01).toStringAsFixed(2));
+    Expect.equals("-0.010", (-0.01).toStringAsFixed(3));
+    Expect.equals("-0.0100", (-0.01).toStringAsFixed(4));
+    Expect.equals("-0.00", (-0.001).toStringAsFixed(2));
+    Expect.equals("-0.001", (-0.001).toStringAsFixed(3));
+    Expect.equals("-0.0010", (-0.001).toStringAsFixed(4));
+    Expect.equals("-1.0000", (-1.0).toStringAsFixed(4));
+    Expect.equals("-1.0", (-1.0).toStringAsFixed(1));
+    Expect.equals("-1", (-1.0).toStringAsFixed(0));
+    Expect.equals("-1", (-1.1).toStringAsFixed(0));
+    Expect.equals("-12", (-12.1).toStringAsFixed(0));
+    Expect.equals("-1", (-1.12).toStringAsFixed(0));
+    Expect.equals("-12", (-12.12).toStringAsFixed(0));
+    Expect.equals("-0.0000006", (-0.0000006).toStringAsFixed(7));
+    Expect.equals("-0.00000006", (-0.00000006).toStringAsFixed(8));
+    Expect.equals("-0.000000060", (-0.00000006).toStringAsFixed(9));
+    Expect.equals("-0.0000000600", (-0.00000006).toStringAsFixed(10));
+    Expect.equals("-0", (-0.0).toStringAsFixed(0));
+    Expect.equals("-0.0", (-0.0).toStringAsFixed(1));
+    Expect.equals("-0.00", (-0.0).toStringAsFixed(2));
+
+    Expect.equals("1000", 1000.0.toStringAsFixed(0));
+    Expect.equals("0", 0.00001.toStringAsFixed(0));
+    Expect.equals("0.00001", 0.00001.toStringAsFixed(5));
+    Expect.equals(
+        "0.00000000000000000010", 0.0000000000000000001.toStringAsFixed(20));
+    Expect.equals("0.00001000000000000", 0.00001.toStringAsFixed(17));
+    Expect.equals("1.00000000000000000", 1.0.toStringAsFixed(17));
+    Expect.equals(
+        "1000000000000000128", 1000000000000000128.0.toStringAsFixed(0));
+    Expect.equals(
+        "100000000000000128.0", 100000000000000128.0.toStringAsFixed(1));
+    Expect.equals(
+        "10000000000000128.00", 10000000000000128.0.toStringAsFixed(2));
+    Expect.equals("10000000000000128.00000000000000000000",
+        10000000000000128.0.toStringAsFixed(20));
+    Expect.equals("0", 0.0.toStringAsFixed(0));
+    Expect.equals("-42.000", (-42.0).toStringAsFixed(3));
+    Expect.equals(
+        "-1000000000000000128", (-1000000000000000128.0).toStringAsFixed(0));
+    Expect.equals("-0.00000000000000000010",
+        (-0.0000000000000000001).toStringAsFixed(20));
+    Expect.equals(
+        "0.12312312312312299889", 0.123123123123123.toStringAsFixed(20));
+    // Test that we round up even when the last digit generated is even.
+    // dtoa does not do this in its original form.
+    Expect.equals("1", 0.5.toStringAsFixed(0));
+    Expect.equals("-1", (-0.5).toStringAsFixed(0));
+    Expect.equals("1.3", 1.25.toStringAsFixed(1));
+    Expect.equals("234.2040", 234.20405.toStringAsFixed(4));
+    Expect.equals("234.2041", 234.2040506.toStringAsFixed(4));
+  }
+}
+
+main() {
+  ToStringAsFixedTest.testMain();
+}
diff --git a/tests/language/double/to_string_as_precision2_runtime_test.dart b/tests/language/double/to_string_as_precision2_runtime_test.dart
new file mode 100644
index 0000000..8831dca
--- /dev/null
+++ b/tests/language/double/to_string_as_precision2_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  var v = 0.0;
+  Expect.throwsRangeError(() => v.toStringAsPrecision(0));
+  Expect.throwsRangeError(() => v.toStringAsPrecision(22));
+
+
+
+}
diff --git a/tests/language/double/to_string_as_precision3_test.dart b/tests/language/double/to_string_as_precision3_test.dart
new file mode 100644
index 0000000..19f390ca
--- /dev/null
+++ b/tests/language/double/to_string_as_precision3_test.dart
@@ -0,0 +1,18 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals(
+      "0.000555000000000000046248", (0.000555).toStringAsPrecision(21));
+  Expect.equals(0.000555000000000000046248, 0.000555);
+  Expect.equals(
+      "5.54999999999999980179e-7", (0.000000555).toStringAsPrecision(21));
+  Expect.equals(5.54999999999999980179e-7, 0.000000555);
+  Expect.equals(
+      "-5.54999999999999980179e-7", (-0.000000555).toStringAsPrecision(21));
+  Expect.equals(-5.54999999999999980179e-7, -0.000000555);
+}
diff --git a/tests/language/double/to_string_as_precision_test.dart b/tests/language/double/to_string_as_precision_test.dart
new file mode 100644
index 0000000..6c048fe
--- /dev/null
+++ b/tests/language/double/to_string_as_precision_test.dart
@@ -0,0 +1,42 @@
+// 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.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals("NaN", (double.nan).toStringAsPrecision(1));
+  Expect.equals("Infinity", (double.infinity).toStringAsPrecision(2));
+  Expect.equals("-Infinity", (-double.infinity).toStringAsPrecision(2));
+  Expect.equals("0.000555000000000000", (0.000555).toStringAsPrecision(15));
+  Expect.equals("5.55000000000000e-7", (0.000000555).toStringAsPrecision(15));
+  Expect.equals("-5.55000000000000e-7", (-0.000000555).toStringAsPrecision(15));
+  Expect.equals("1e+8", (123456789.0).toStringAsPrecision(1));
+  Expect.equals("123456789", (123456789.0).toStringAsPrecision(9));
+  Expect.equals("1.2345679e+8", (123456789.0).toStringAsPrecision(8));
+  Expect.equals("1.234568e+8", (123456789.0).toStringAsPrecision(7));
+  Expect.equals("-1.234568e+8", (-123456789.0).toStringAsPrecision(7));
+  Expect.equals("-1.2e-9", (-.0000000012345).toStringAsPrecision(2));
+  Expect.equals("-1.2e-8", (-.000000012345).toStringAsPrecision(2));
+  Expect.equals("-1.2e-7", (-.00000012345).toStringAsPrecision(2));
+  Expect.equals("-0.0000012", (-.0000012345).toStringAsPrecision(2));
+  Expect.equals("-0.000012", (-.000012345).toStringAsPrecision(2));
+  Expect.equals("-0.00012", (-.00012345).toStringAsPrecision(2));
+  Expect.equals("-0.0012", (-.0012345).toStringAsPrecision(2));
+  Expect.equals("-0.012", (-.012345).toStringAsPrecision(2));
+  Expect.equals("-0.12", (-.12345).toStringAsPrecision(2));
+  Expect.equals("-1.2", (-1.2345).toStringAsPrecision(2));
+  Expect.equals("-12", (-12.345).toStringAsPrecision(2));
+  Expect.equals("-1.2e+2", (-123.45).toStringAsPrecision(2));
+  Expect.equals("-1.2e+3", (-1234.5).toStringAsPrecision(2));
+  Expect.equals("-1.2e+4", (-12345.0).toStringAsPrecision(2));
+  Expect.equals("-1.235e+4", (-12345.67).toStringAsPrecision(4));
+  Expect.equals("-1.234e+4", (-12344.67).toStringAsPrecision(4));
+  Expect.equals("-0.0", (-0.0).toStringAsPrecision(2));
+  Expect.equals("-0", (-0.0).toStringAsPrecision(1));
+  // Test that we round up even when the last digit generated is even.
+  // dtoa does not do this in its original form.
+  Expect.equals("1.3", 1.25.toStringAsPrecision(2));
+  Expect.equals("1.4", 1.35.toStringAsPrecision(2));
+}
diff --git a/tests/language/double/to_string_test.dart b/tests/language/double/to_string_test.dart
new file mode 100644
index 0000000..fcdafb9
--- /dev/null
+++ b/tests/language/double/to_string_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test basic integer operations.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals("NaN", (double.nan).toString());
+  Expect.equals("Infinity", (1 / 0).toString());
+  Expect.equals("-Infinity", (-1 / 0).toString());
+  Expect.equals("90.12", (90.12).toString());
+  Expect.equals("0.1", (0.1).toString());
+  Expect.equals("0.01", (0.01).toString());
+  Expect.equals("0.0123", (0.0123).toString());
+  Expect.equals(
+      "1.1111111111111111e+21", (1111111111111111111111.0).toString());
+  Expect.equals(
+      "1.1111111111111111e+22", (11111111111111111111111.0).toString());
+  Expect.equals("0.00001", (0.00001).toString());
+  Expect.equals("0.000001", (0.000001).toString());
+  Expect.equals("1e-7", (0.0000001).toString());
+  Expect.equals("1.2e-7", (0.00000012).toString());
+  Expect.equals("1.23e-7", (0.000000123).toString());
+  Expect.equals("1e-8", (0.00000001).toString());
+  Expect.equals("1.2e-8", (0.000000012).toString());
+  Expect.equals("1.23e-8", (0.0000000123).toString());
+
+  Expect.equals("-0.0", (-0.0).toString());
+  Expect.equals("-90.12", (-90.12).toString());
+  Expect.equals("-0.1", (-0.1).toString());
+  Expect.equals("-0.01", (-0.01).toString());
+  Expect.equals("-0.0123", (-0.0123).toString());
+  Expect.equals(
+      "-1.1111111111111111e+21", (-1111111111111111111111.0).toString());
+  Expect.equals(
+      "-1.1111111111111111e+22", (-11111111111111111111111.0).toString());
+  Expect.equals("-0.00001", (-0.00001).toString());
+  Expect.equals("-0.000001", (-0.000001).toString());
+  Expect.equals("-1e-7", (-0.0000001).toString());
+  Expect.equals("-1.2e-7", (-0.00000012).toString());
+  Expect.equals("-1.23e-7", (-0.000000123).toString());
+  Expect.equals("-1e-8", (-0.00000001).toString());
+  Expect.equals("-1.2e-8", (-0.000000012).toString());
+  Expect.equals("-1.23e-8", (-0.0000000123).toString());
+
+  Expect.equals("0.00001", (0.00001).toString());
+  Expect.equals("1e+21", (1000000000000000012800.0).toString());
+  Expect.equals("-1e+21", (-1000000000000000012800.0).toString());
+  Expect.equals("1e-7", (0.0000001).toString());
+  Expect.equals("-1e-7", (-0.0000001).toString());
+  Expect.equals(
+      "1.0000000000000001e+21", (1000000000000000128000.0).toString());
+  Expect.equals("0.000001", (0.000001).toString());
+  Expect.equals("1e-7", (0.0000001).toString());
+}
diff --git a/tests/language/double_literals/double_literal_coercion_error_test.dart b/tests/language/double_literals/double_literal_coercion_error_test.dart
new file mode 100644
index 0000000..6b574fc
--- /dev/null
+++ b/tests/language/double_literals/double_literal_coercion_error_test.dart
@@ -0,0 +1,299 @@
+// 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.
+
+// Introduces a context with double as type.
+void notDouble([double value = 0.0]) {
+  if (value != 0.0) throw "unreachable";
+}
+
+main() {
+  notDouble(
+    // Large decimal numbers which are not representable as doubles.
+    9007199254740993, //     2^53+2^0      //# 001: compile-time error
+    18014398509481983, //    2^54-2^0      //# 002: compile-time error
+    18014398509481985, //    2^54+2^0      //# 003: compile-time error
+    18014398509481986, //    2^54+2^1      //# 004: compile-time error
+    4611686018427387903, //  2^62-2^0      //# 005: compile-time error
+    4611686018427387902, //  2^62-2^1      //# 006: compile-time error
+    4611686018427387900, //  2^62-2^2      //# 007: compile-time error
+    4611686018427387896, //  2^62-2^3      //# 008: compile-time error
+    4611686018427387888, //  2^62-2^4      //# 009: compile-time error
+    4611686018427387872, //  2^62-2^5      //# 010: compile-time error
+    4611686018427387840, //  2^62-2^6      //# 011: compile-time error
+    4611686018427387776, //  2^62-2^7      //# 012: compile-time error
+    4611686018427387648, //  2^62-2^8      //# 013: compile-time error
+    4611686018427387905, //  2^62+2^0      //# 014: compile-time error
+    4611686018427387906, //  2^62+2^1      //# 015: compile-time error
+    4611686018427387908, //  2^62+2^2      //# 016: compile-time error
+    4611686018427387912, //  2^62+2^3      //# 017: compile-time error
+    4611686018427387920, //  2^62+2^4      //# 018: compile-time error
+    4611686018427387936, //  2^62+2^5      //# 019: compile-time error
+    4611686018427387968, //  2^62+2^6      //# 020: compile-time error
+    4611686018427388032, //  2^62+2^7      //# 021: compile-time error
+    4611686018427388160, //  2^62+2^8      //# 022: compile-time error
+    4611686018427388416, //  2^62+2^9      //# 023: compile-time error
+    9223372036854775807, //  2^63-2^0      //# 024: compile-time error
+    9223372036854775806, //  2^63-2^1      //# 025: compile-time error
+    9223372036854775804, //  2^63-2^2      //# 026: compile-time error
+    9223372036854775800, //  2^63-2^3      //# 027: compile-time error
+    9223372036854775792, //  2^63-2^4      //# 028: compile-time error
+    9223372036854775776, //  2^63-2^5      //# 029: compile-time error
+    9223372036854775744, //  2^63-2^6      //# 030: compile-time error
+    9223372036854775680, //  2^63-2^7      //# 031: compile-time error
+    9223372036854775552, //  2^63-2^8      //# 032: compile-time error
+    9223372036854775296, //  2^63-2^9      //# 033: compile-time error
+    9223372036854775809, //  2^63+2^0      //# 034: compile-time error
+    9223372036854775810, //  2^63+2^1      //# 035: compile-time error
+    9223372036854775812, //  2^63+2^2      //# 036: compile-time error
+    9223372036854775816, //  2^63+2^3      //# 037: compile-time error
+    9223372036854775824, //  2^63+2^4      //# 038: compile-time error
+    9223372036854775840, //  2^63+2^5      //# 039: compile-time error
+    9223372036854775872, //  2^63+2^6      //# 040: compile-time error
+    9223372036854775936, //  2^63+2^7      //# 041: compile-time error
+    9223372036854776064, //  2^63+2^8      //# 042: compile-time error
+    9223372036854776320, //  2^63+2^9      //# 043: compile-time error
+    9223372036854776832, //  2^63+2^10     //# 044: compile-time error
+    18446744073709551615, // 2^64-2^0      //# 045: compile-time error
+    18446744073709551614, // 2^64-2^1      //# 046: compile-time error
+    18446744073709551612, // 2^64-2^2      //# 047: compile-time error
+    18446744073709551608, // 2^64-2^3      //# 048: compile-time error
+    18446744073709551600, // 2^64-2^4      //# 049: compile-time error
+    18446744073709551584, // 2^64-2^5      //# 050: compile-time error
+    18446744073709551552, // 2^64-2^6      //# 051: compile-time error
+    18446744073709551488, // 2^64-2^7      //# 052: compile-time error
+    18446744073709551360, // 2^64-2^8      //# 053: compile-time error
+    18446744073709551104, // 2^64-2^9      //# 054: compile-time error
+    18446744073709550592, // 2^64-2^10     //# 055: compile-time error
+    18446744073709551617, // 2^64+2^0      //# 056: compile-time error
+    18446744073709551618, // 2^64+2^1      //# 057: compile-time error
+    18446744073709551620, // 2^64+2^2      //# 058: compile-time error
+    18446744073709551624, // 2^64+2^3      //# 059: compile-time error
+    18446744073709551632, // 2^64+2^4      //# 060: compile-time error
+    18446744073709551648, // 2^64+2^5      //# 061: compile-time error
+    18446744073709551680, // 2^64+2^6      //# 062: compile-time error
+    18446744073709551744, // 2^64+2^7      //# 063: compile-time error
+    18446744073709551872, // 2^64+2^8      //# 064: compile-time error
+    18446744073709552128, // 2^64+2^9      //# 065: compile-time error
+    18446744073709552640, // 2^64+2^10     //# 066: compile-time error
+    18446744073709553664, // 2^64+2^11     //# 067: compile-time error
+    179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367, // maxValue - 1 //# 068 : compile-time error
+    179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369, // maxValue + 1 //# 069 : compile-time error
+    359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361838599762500808052368249716734, // maxValue * 2 //# 070P : compile-time error
+
+    // Negative numbers too.
+    -9007199254740993, //     -(2^53+2^0)  //# 071: compile-time error
+    -18014398509481983, //    -(2^54-2^0)  //# 072: compile-time error
+    -18014398509481985, //    -(2^54+2^0)  //# 073: compile-time error
+    -18014398509481986, //    -(2^54+2^1)  //# 074: compile-time error
+    -4611686018427387903, //  -(2^62-2^0)  //# 075: compile-time error
+    -4611686018427387902, //  -(2^62-2^1)  //# 076: compile-time error
+    -4611686018427387900, //  -(2^62-2^2)  //# 077: compile-time error
+    -4611686018427387896, //  -(2^62-2^3)  //# 078: compile-time error
+    -4611686018427387888, //  -(2^62-2^4)  //# 079: compile-time error
+    -4611686018427387872, //  -(2^62-2^5)  //# 080: compile-time error
+    -4611686018427387840, //  -(2^62-2^6)  //# 081: compile-time error
+    -4611686018427387776, //  -(2^62-2^7)  //# 082: compile-time error
+    -4611686018427387648, //  -(2^62-2^8)  //# 083: compile-time error
+    -4611686018427387905, //  -(2^62+2^0)  //# 084: compile-time error
+    -4611686018427387906, //  -(2^62+2^1)  //# 085: compile-time error
+    -4611686018427387908, //  -(2^62+2^2)  //# 086: compile-time error
+    -4611686018427387912, //  -(2^62+2^3)  //# 087: compile-time error
+    -4611686018427387920, //  -(2^62+2^4)  //# 088: compile-time error
+    -4611686018427387936, //  -(2^62+2^5)  //# 089: compile-time error
+    -4611686018427387968, //  -(2^62+2^6)  //# 090: compile-time error
+    -4611686018427388032, //  -(2^62+2^7)  //# 091: compile-time error
+    -4611686018427388160, //  -(2^62+2^8)  //# 092: compile-time error
+    -4611686018427388416, //  -(2^62+2^9)  //# 093: compile-time error
+    -9223372036854775807, //  -(2^63-2^0)  //# 094: compile-time error
+    -9223372036854775806, //  -(2^63-2^1)  //# 095: compile-time error
+    -9223372036854775804, //  -(2^63-2^2)  //# 096: compile-time error
+    -9223372036854775800, //  -(2^63-2^3)  //# 097: compile-time error
+    -9223372036854775792, //  -(2^63-2^4)  //# 098: compile-time error
+    -9223372036854775776, //  -(2^63-2^5)  //# 099: compile-time error
+    -9223372036854775744, //  -(2^63-2^6)  //# 100: compile-time error
+    -9223372036854775680, //  -(2^63-2^7)  //# 101: compile-time error
+    -9223372036854775552, //  -(2^63-2^8)  //# 102: compile-time error
+    -9223372036854775296, //  -(2^63-2^9)  //# 103: compile-time error
+    -9223372036854775809, //  -(2^63+2^0)  //# 104: compile-time error
+    -9223372036854775810, //  -(2^63+2^1)  //# 105: compile-time error
+    -9223372036854775812, //  -(2^63+2^2)  //# 106: compile-time error
+    -9223372036854775816, //  -(2^63+2^3)  //# 107: compile-time error
+    -9223372036854775824, //  -(2^63+2^4)  //# 108: compile-time error
+    -9223372036854775840, //  -(2^63+2^5)  //# 109: compile-time error
+    -9223372036854775872, //  -(2^63+2^6)  //# 110: compile-time error
+    -9223372036854775936, //  -(2^63+2^7)  //# 111: compile-time error
+    -9223372036854776064, //  -(2^63+2^8)  //# 112: compile-time error
+    -9223372036854776320, //  -(2^63+2^9)  //# 113: compile-time error
+    -9223372036854776832, //  -(2^63+2^10) //# 114: compile-time error
+    -18446744073709551615, // -(2^64-2^0)  //# 115: compile-time error
+    -18446744073709551614, // -(2^64-2^1)  //# 116: compile-time error
+    -18446744073709551612, // -(2^64-2^2)  //# 117: compile-time error
+    -18446744073709551608, // -(2^64-2^3)  //# 118: compile-time error
+    -18446744073709551600, // -(2^64-2^4)  //# 119: compile-time error
+    -18446744073709551584, // -(2^64-2^5)  //# 120: compile-time error
+    -18446744073709551552, // -(2^64-2^6)  //# 121: compile-time error
+    -18446744073709551488, // -(2^64-2^7)  //# 122: compile-time error
+    -18446744073709551360, // -(2^64-2^8)  //# 123: compile-time error
+    -18446744073709551104, // -(2^64-2^9)  //# 124: compile-time error
+    -18446744073709550592, // -(2^64-2^10) //# 125: compile-time error
+    -18446744073709551617, // -(2^64+2^0)  //# 126: compile-time error
+    -18446744073709551618, // -(2^64+2^1)  //# 127: compile-time error
+    -18446744073709551620, // -(2^64+2^2)  //# 128: compile-time error
+    -18446744073709551624, // -(2^64+2^3)  //# 129: compile-time error
+    -18446744073709551632, // -(2^64+2^4)  //# 130: compile-time error
+    -18446744073709551648, // -(2^64+2^5)  //# 131: compile-time error
+    -18446744073709551680, // -(2^64+2^6)  //# 132: compile-time error
+    -18446744073709551744, // -(2^64+2^7)  //# 133: compile-time error
+    -18446744073709551872, // -(2^64+2^8)  //# 134: compile-time error
+    -18446744073709552128, // -(2^64+2^9)  //# 135: compile-time error
+    -18446744073709552640, // -(2^64+2^10) //# 136: compile-time error
+    -18446744073709553664, // -(2^64+2^11) //# 137: compile-time error
+    -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367, // -(maxValue - 1) //# 138 : compile-time error
+    -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369, // -(maxValue + 1) //# 139 : compile-time error
+    -359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361838599762500808052368249716734, // -(maxValue * 2) //# 140B : compile-time error
+
+    // Same numbers as hexadecimal literals.
+    0x20000000000001, //    2^53+2^0      //# 141: compile-time error
+    0x3fffffffffffff, //    2^54-2^0      //# 142: compile-time error
+    0x40000000000001, //    2^54+2^0      //# 143: compile-time error
+    0x40000000000002, //    2^54+2^1      //# 144: compile-time error
+    0x3fffffffffffffff, //  2^62-2^0      //# 145: compile-time error
+    0x3ffffffffffffffe, //  2^62-2^1      //# 146: compile-time error
+    0x3ffffffffffffffc, //  2^62-2^2      //# 147: compile-time error
+    0x3ffffffffffffff8, //  2^62-2^3      //# 148: compile-time error
+    0x3ffffffffffffff0, //  2^62-2^4      //# 149: compile-time error
+    0x3fffffffffffffe0, //  2^62-2^5      //# 150: compile-time error
+    0x3fffffffffffffc0, //  2^62-2^6      //# 151: compile-time error
+    0x3fffffffffffff80, //  2^62-2^7      //# 152: compile-time error
+    0x3fffffffffffff00, //  2^62-2^8      //# 153: compile-time error
+    0x4000000000000001, //  2^62+2^0      //# 154: compile-time error
+    0x4000000000000002, //  2^62+2^1      //# 155: compile-time error
+    0x4000000000000004, //  2^62+2^2      //# 156: compile-time error
+    0x4000000000000008, //  2^62+2^3      //# 157: compile-time error
+    0x4000000000000010, //  2^62+2^4      //# 158: compile-time error
+    0x4000000000000020, //  2^62+2^5      //# 159: compile-time error
+    0x4000000000000040, //  2^62+2^6      //# 160: compile-time error
+    0x4000000000000080, //  2^62+2^7      //# 161: compile-time error
+    0x4000000000000100, //  2^62+2^8      //# 162: compile-time error
+    0x4000000000000200, //  2^62+2^9      //# 163: compile-time error
+    0x7fffffffffffffff, //  2^63-2^0      //# 164: compile-time error
+    0x7ffffffffffffffe, //  2^63-2^1      //# 165: compile-time error
+    0x7ffffffffffffffc, //  2^63-2^2      //# 166: compile-time error
+    0x7ffffffffffffff8, //  2^63-2^3      //# 167: compile-time error
+    0x7ffffffffffffff0, //  2^63-2^4      //# 168: compile-time error
+    0x7fffffffffffffe0, //  2^63-2^5      //# 169: compile-time error
+    0x7fffffffffffffc0, //  2^63-2^6      //# 170: compile-time error
+    0x7fffffffffffff80, //  2^63-2^7      //# 171: compile-time error
+    0x7fffffffffffff00, //  2^63-2^8      //# 172: compile-time error
+    0x7ffffffffffffe00, //  2^63-2^9      //# 173: compile-time error
+    0x8000000000000001, //  2^63+2^0      //# 174: compile-time error
+    0x8000000000000002, //  2^63+2^1      //# 175: compile-time error
+    0x8000000000000004, //  2^63+2^2      //# 176: compile-time error
+    0x8000000000000008, //  2^63+2^3      //# 177: compile-time error
+    0x8000000000000010, //  2^63+2^4      //# 178: compile-time error
+    0x8000000000000020, //  2^63+2^5      //# 179: compile-time error
+    0x8000000000000040, //  2^63+2^6      //# 180: compile-time error
+    0x8000000000000080, //  2^63+2^7      //# 181: compile-time error
+    0x8000000000000100, //  2^63+2^8      //# 182: compile-time error
+    0x8000000000000200, //  2^63+2^9      //# 183: compile-time error
+    0x8000000000000400, //  2^63+2^10     //# 184: compile-time error
+    0xffffffffffffffff, //  2^64-2^0      //# 185: compile-time error
+    0xfffffffffffffffe, //  2^64-2^1      //# 186: compile-time error
+    0xfffffffffffffffc, //  2^64-2^2      //# 187: compile-time error
+    0xfffffffffffffff8, //  2^64-2^3      //# 188: compile-time error
+    0xfffffffffffffff0, //  2^64-2^4      //# 189: compile-time error
+    0xffffffffffffffe0, //  2^64-2^5      //# 190: compile-time error
+    0xffffffffffffffc0, //  2^64-2^6      //# 191: compile-time error
+    0xffffffffffffff80, //  2^64-2^7      //# 192: compile-time error
+    0xffffffffffffff00, //  2^64-2^8      //# 193: compile-time error
+    0xfffffffffffffe00, //  2^64-2^9      //# 194: compile-time error
+    0xfffffffffffffc00, //  2^64-2^10     //# 195: compile-time error
+    0x10000000000000001, // 2^64+2^0      //# 196: compile-time error
+    0x10000000000000002, // 2^64+2^1      //# 197: compile-time error
+    0x10000000000000004, // 2^64+2^2      //# 198: compile-time error
+    0x10000000000000008, // 2^64+2^3      //# 199: compile-time error
+    0x10000000000000010, // 2^64+2^4      //# 200: compile-time error
+    0x10000000000000020, // 2^64+2^5      //# 201: compile-time error
+    0x10000000000000040, // 2^64+2^6      //# 202: compile-time error
+    0x10000000000000080, // 2^64+2^7      //# 203: compile-time error
+    0x10000000000000100, // 2^64+2^8      //# 204: compile-time error
+    0x10000000000000200, // 2^64+2^9      //# 205: compile-time error
+    0x10000000000000400, // 2^64+2^10     //# 206: compile-time error
+    0x10000000000000800, // 2^64+2^11     //# 207: compile-time error
+    0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, // maxValue - 1 //# 208 : compile-time error
+    0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // maxValue + 1 //# 209 : compile-time error
+    0x1fffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // maxValue * 2 //# 210V : compile-time error
+
+    -0x20000000000001, //    -(2^53+2^0)      //# 211: compile-time error
+    -0x3fffffffffffff, //    -(2^54-2^0)      //# 212: compile-time error
+    -0x40000000000001, //    -(2^54+2^0)      //# 213: compile-time error
+    -0x40000000000002, //    -(2^54+2^1)      //# 214: compile-time error
+    -0x3fffffffffffffff, //  -(2^62-2^0)      //# 215: compile-time error
+    -0x3ffffffffffffffe, //  -(2^62-2^1)      //# 216: compile-time error
+    -0x3ffffffffffffffc, //  -(2^62-2^2)      //# 217: compile-time error
+    -0x3ffffffffffffff8, //  -(2^62-2^3)      //# 218: compile-time error
+    -0x3ffffffffffffff0, //  -(2^62-2^4)      //# 219: compile-time error
+    -0x3fffffffffffffe0, //  -(2^62-2^5)      //# 220: compile-time error
+    -0x3fffffffffffffc0, //  -(2^62-2^6)      //# 221: compile-time error
+    -0x3fffffffffffff80, //  -(2^62-2^7)      //# 222: compile-time error
+    -0x3fffffffffffff00, //  -(2^62-2^8)      //# 223: compile-time error
+    -0x4000000000000001, //  -(2^62+2^0)      //# 224: compile-time error
+    -0x4000000000000002, //  -(2^62+2^1)      //# 225: compile-time error
+    -0x4000000000000004, //  -(2^62+2^2)      //# 226: compile-time error
+    -0x4000000000000008, //  -(2^62+2^3)      //# 227: compile-time error
+    -0x4000000000000010, //  -(2^62+2^4)      //# 228: compile-time error
+    -0x4000000000000020, //  -(2^62+2^5)      //# 229: compile-time error
+    -0x4000000000000040, //  -(2^62+2^6)      //# 230: compile-time error
+    -0x4000000000000080, //  -(2^62+2^7)      //# 231: compile-time error
+    -0x4000000000000100, //  -(2^62+2^8)      //# 232: compile-time error
+    -0x4000000000000200, //  -(2^62+2^9)      //# 233: compile-time error
+    -0x7fffffffffffffff, //  -(2^63-2^0)      //# 234: compile-time error
+    -0x7ffffffffffffffe, //  -(2^63-2^1)      //# 235: compile-time error
+    -0x7ffffffffffffffc, //  -(2^63-2^2)      //# 236: compile-time error
+    -0x7ffffffffffffff8, //  -(2^63-2^3)      //# 237: compile-time error
+    -0x7ffffffffffffff0, //  -(2^63-2^4)      //# 238: compile-time error
+    -0x7fffffffffffffe0, //  -(2^63-2^5)      //# 239: compile-time error
+    -0x7fffffffffffffc0, //  -(2^63-2^6)      //# 240: compile-time error
+    -0x7fffffffffffff80, //  -(2^63-2^7)      //# 241: compile-time error
+    -0x7fffffffffffff00, //  -(2^63-2^8)      //# 242: compile-time error
+    -0x7ffffffffffffe00, //  -(2^63-2^9)      //# 243: compile-time error
+    -0x8000000000000001, //  -(2^63+2^0)      //# 244: compile-time error
+    -0x8000000000000002, //  -(2^63+2^1)      //# 245: compile-time error
+    -0x8000000000000004, //  -(2^63+2^2)      //# 246: compile-time error
+    -0x8000000000000008, //  -(2^63+2^3)      //# 247: compile-time error
+    -0x8000000000000010, //  -(2^63+2^4)      //# 248: compile-time error
+    -0x8000000000000020, //  -(2^63+2^5)      //# 249: compile-time error
+    -0x8000000000000040, //  -(2^63+2^6)      //# 250: compile-time error
+    -0x8000000000000080, //  -(2^63+2^7)      //# 251: compile-time error
+    -0x8000000000000100, //  -(2^63+2^8)      //# 252: compile-time error
+    -0x8000000000000200, //  -(2^63+2^9)      //# 253: compile-time error
+    -0x8000000000000400, //  -(2^63+2^10)     //# 254: compile-time error
+    -0xffffffffffffffff, //  -(2^64-2^0)      //# 255: compile-time error
+    -0xfffffffffffffffe, //  -(2^64-2^1)      //# 256: compile-time error
+    -0xfffffffffffffffc, //  -(2^64-2^2)      //# 257: compile-time error
+    -0xfffffffffffffff8, //  -(2^64-2^3)      //# 258: compile-time error
+    -0xfffffffffffffff0, //  -(2^64-2^4)      //# 259: compile-time error
+    -0xffffffffffffffe0, //  -(2^64-2^5)      //# 260: compile-time error
+    -0xffffffffffffffc0, //  -(2^64-2^6)      //# 261: compile-time error
+    -0xffffffffffffff80, //  -(2^64-2^7)      //# 262: compile-time error
+    -0xffffffffffffff00, //  -(2^64-2^8)      //# 263: compile-time error
+    -0xfffffffffffffe00, //  -(2^64-2^9)      //# 264: compile-time error
+    -0xfffffffffffffc00, //  -(2^64-2^10)     //# 265: compile-time error
+    -0x10000000000000001, // -(2^64+2^0)      //# 266: compile-time error
+    -0x10000000000000002, // -(2^64+2^1)      //# 267: compile-time error
+    -0x10000000000000004, // -(2^64+2^2)      //# 268: compile-time error
+    -0x10000000000000008, // -(2^64+2^3)      //# 269: compile-time error
+    -0x10000000000000010, // -(2^64+2^4)      //# 270: compile-time error
+    -0x10000000000000020, // -(2^64+2^5)      //# 271: compile-time error
+    -0x10000000000000040, // -(2^64+2^6)      //# 272: compile-time error
+    -0x10000000000000080, // -(2^64+2^7)      //# 273: compile-time error
+    -0x10000000000000100, // -(2^64+2^8)      //# 274: compile-time error
+    -0x10000000000000200, // -(2^64+2^9)      //# 275: compile-time error
+    -0x10000000000000400, // -(2^64+2^10)     //# 276: compile-time error
+    -0x10000000000000800, // -(2^64+2^11)     //# 277: compile-time error
+    -0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, // -(maxValue - 1) //# 278 : compile-time error
+    -0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // -(maxValue + 1) //# 279 : compile-time error
+    -0x1fffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // -(maxValue * 2) //# 280 : compile-time error
+  );
+}
diff --git a/tests/language/double_literals/double_literal_coercion_test.dart b/tests/language/double_literals/double_literal_coercion_test.dart
new file mode 100644
index 0000000..b18b22f
--- /dev/null
+++ b/tests/language/double_literals/double_literal_coercion_test.dart
@@ -0,0 +1,149 @@
+// 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:expect/expect.dart";
+
+// Pass expected value and then decimal literal value in a double context.
+void expectDouble(double expectedValue, double actualValue) {
+  Expect.identical(expectedValue, actualValue);
+}
+
+// Some exact powers of two as double values.
+double p2_8 = 256.0;
+double p2_30 = 1073741824.0;
+double p2_31 = 2147483648.0;
+double p2_32 = 4294967296.0;
+double p2_52 = 4503599627370496.0;
+double p2_53 = 9007199254740992.0;
+double p2_54 = 18014398509481984.0;
+double p2_62 = 4611686018427387904.0;
+double p2_63 = 9223372036854775808.0;
+double p2_64 = 18446744073709551616.0;
+double maxValue = 1.7976931348623157e+308;
+
+main() {
+  expectDouble(0.0, 0);
+  expectDouble(1.0, 1);
+  expectDouble(0.0, 00);
+  expectDouble(1.0, 01);
+  expectDouble(p2_8 - 1, 255);
+  expectDouble(p2_8, 256);
+  expectDouble(p2_8 + 1, 257);
+  expectDouble(p2_30 - 1, 1073741823);
+  expectDouble(p2_30, 1073741824);
+  expectDouble(p2_30 + 1, 1073741825);
+  expectDouble(p2_31 - 1, 2147483647);
+  expectDouble(p2_31, 2147483648);
+  expectDouble(p2_31 + 1, 2147483649);
+  expectDouble(p2_32 - 1, 4294967295);
+  expectDouble(p2_32, 4294967296);
+  expectDouble(p2_32 + 1, 4294967297);
+  expectDouble(p2_52 - 1, 4503599627370495);
+  expectDouble(p2_52, 4503599627370496);
+  expectDouble(p2_52 + 1, 4503599627370497);
+  expectDouble(p2_53 - 1, 9007199254740991);
+  expectDouble(p2_53, 9007199254740992);
+  expectDouble(p2_53 + 2, 9007199254740994);
+  expectDouble(p2_54 - 2, 18014398509481982);
+  expectDouble(p2_54, 18014398509481984);
+  expectDouble(p2_54 + 4, 18014398509481988);
+  expectDouble(p2_62, 4611686018427387904);
+  expectDouble(p2_63, 9223372036854775808);
+  expectDouble(p2_64, 18446744073709551616);
+  expectDouble(maxValue,
+      179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368);
+
+  expectDouble(-0.0, -0);
+  expectDouble(-1.0, -1);
+  expectDouble(-0.0, -00);
+  expectDouble(-1.0, -01);
+  expectDouble(-(p2_8 - 1), -255);
+  expectDouble(-(p2_8), -256);
+  expectDouble(-(p2_8 + 1), -257);
+  expectDouble(-(p2_30 - 1), -1073741823);
+  expectDouble(-(p2_30), -1073741824);
+  expectDouble(-(p2_30 + 1), -1073741825);
+  expectDouble(-(p2_31 - 1), -2147483647);
+  expectDouble(-(p2_31), -2147483648);
+  expectDouble(-(p2_31 + 1), -2147483649);
+  expectDouble(-(p2_32 - 1), -4294967295);
+  expectDouble(-(p2_32), -4294967296);
+  expectDouble(-(p2_32 + 1), -4294967297);
+  expectDouble(-(p2_52 - 1), -4503599627370495);
+  expectDouble(-(p2_52), -4503599627370496);
+  expectDouble(-(p2_52 + 1), -4503599627370497);
+  expectDouble(-(p2_53 - 1), -9007199254740991);
+  expectDouble(-(p2_53), -9007199254740992);
+  expectDouble(-(p2_53 + 2), -9007199254740994);
+  expectDouble(-(p2_54 - 2), -18014398509481982);
+  expectDouble(-(p2_54), -18014398509481984);
+  expectDouble(-(p2_54 + 4), -18014398509481988);
+  expectDouble(-(p2_62), -4611686018427387904);
+  expectDouble(-(p2_63), -9223372036854775808);
+  expectDouble(-(p2_64), -18446744073709551616);
+  expectDouble(-maxValue,
+      -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368);
+
+  expectDouble(0.0, 0x0);
+  expectDouble(1.0, 0x1);
+  expectDouble(0.0, 0x00);
+  expectDouble(1.0, 0x01);
+  expectDouble(p2_8 - 1, 0xff);
+  expectDouble(p2_8, 0x100);
+  expectDouble(p2_8 + 1, 0x101);
+  expectDouble(p2_30 - 1, 0x3fffffff);
+  expectDouble(p2_30, 0x40000000);
+  expectDouble(p2_30 + 1, 0x40000001);
+  expectDouble(p2_31 - 1, 0x7fffffff);
+  expectDouble(p2_31, 0x80000000);
+  expectDouble(p2_31 + 1, 0x80000001);
+  expectDouble(p2_32 - 1, 0xffffffff);
+  expectDouble(p2_32, 0x100000000);
+  expectDouble(p2_32 + 1, 0x100000001);
+  expectDouble(p2_52 - 1, 0xfffffffffffff);
+  expectDouble(p2_52, 0x10000000000000);
+  expectDouble(p2_52 + 1, 0x10000000000001);
+  expectDouble(p2_53 - 1, 0x1fffffffffffff);
+  expectDouble(p2_53, 0x20000000000000);
+  expectDouble(p2_53 + 2, 0x20000000000002);
+  expectDouble(p2_54 - 2, 0x3ffffffffffffe);
+  expectDouble(p2_54, 0x40000000000000);
+  expectDouble(p2_54 + 4, 0x40000000000004);
+  expectDouble(p2_62, 0x4000000000000000);
+  expectDouble(p2_63, 0x8000000000000000);
+  expectDouble(p2_64, 0x10000000000000000);
+  expectDouble(maxValue,
+      0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
+
+  expectDouble(-0.0, -0x0);
+  expectDouble(-1.0, -0x1);
+  expectDouble(-0.0, -0x00);
+  expectDouble(-1.0, -0x01);
+  expectDouble(-(p2_8 - 1), -0xff);
+  expectDouble(-(p2_8), -0x100);
+  expectDouble(-(p2_8 + 1), -0x101);
+  expectDouble(-(p2_30 - 1), -0x3fffffff);
+  expectDouble(-(p2_30), -0x40000000);
+  expectDouble(-(p2_30 + 1), -0x40000001);
+  expectDouble(-(p2_31 - 1), -0x7fffffff);
+  expectDouble(-(p2_31), -0x80000000);
+  expectDouble(-(p2_31 + 1), -0x80000001);
+  expectDouble(-(p2_32 - 1), -0xffffffff);
+  expectDouble(-(p2_32), -0x100000000);
+  expectDouble(-(p2_32 + 1), -0x100000001);
+  expectDouble(-(p2_52 - 1), -0xfffffffffffff);
+  expectDouble(-(p2_52), -0x10000000000000);
+  expectDouble(-(p2_52 + 1), -0x10000000000001);
+  expectDouble(-(p2_53 - 1), -0x1fffffffffffff);
+  expectDouble(-(p2_53), -0x20000000000000);
+  expectDouble(-(p2_53 + 2), -0x20000000000002);
+  expectDouble(-(p2_54 - 2), -0x3ffffffffffffe);
+  expectDouble(-(p2_54), -0x40000000000000);
+  expectDouble(-(p2_54 + 4), -0x40000000000004);
+  expectDouble(-(p2_62), -0x4000000000000000);
+  expectDouble(-(p2_63), -0x8000000000000000);
+  expectDouble(-(p2_64), -0x10000000000000000);
+  expectDouble(-maxValue,
+      -0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
+}
diff --git a/tests/language/double_literals/implicit_double_context_test.dart b/tests/language/double_literals/implicit_double_context_test.dart
new file mode 100644
index 0000000..117b5cd
--- /dev/null
+++ b/tests/language/double_literals/implicit_double_context_test.dart
@@ -0,0 +1,683 @@
+// 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 "dart:async" show FutureOr;
+
+import "package:expect/expect.dart";
+
+// Check that integer literals in a double context are allowed
+// for various double context.
+
+main() {
+  // Variable initializer context.
+  double v1 = 0;
+  Expect.identical(0.0, v1);
+  double v2 = 1;
+  Expect.identical(1.0, v2);
+  double v3 = -0;
+  Expect.identical(-0.0, v3);
+  double v4 = -1;
+  Expect.identical(-1.0, v4);
+  double v5 = 9223372036854775808; // 2^63, not valid signed 64-bit integer.
+  Expect.identical(9223372036854775808.0, v5);
+  double v6 = 18446744073709551616; // 2^64.
+  Expect.identical(18446744073709551616.0, v6);
+  double v7 = 0x02; // Hex literal.
+  Expect.identical(2.0, v7);
+  double v8 = -0x02; // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Const variable initializer context.
+  const double c1 = 0;
+  Expect.identical(0.0, c1);
+  const double c2 = 1;
+  Expect.identical(1.0, c2);
+  const double c3 = -0;
+  Expect.identical(-0.0, c3);
+  const double c4 = -1;
+  Expect.identical(-1.0, c4);
+  const double c5 = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, c5);
+  const double c6 = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, c6);
+  const double c7 = 0x02; // Hex literal.
+  Expect.identical(2.0, c7);
+  const double c8 = -0x02; // Hex literal.
+  Expect.identical(-2.0, c8);
+
+  // Assignment context, variable.
+  double value;
+  value = 0;
+  Expect.identical(0.0, value);
+  value = 1;
+  Expect.identical(1.0, value);
+  value = -0;
+  Expect.identical(-0.0, value);
+  value = -1;
+  Expect.identical(-1.0, value);
+  value = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, value);
+  value = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, value);
+  value = 0x02;
+  Expect.identical(2.0, value);
+  value = -0x02;
+  Expect.identical(-2.0, value);
+
+  // Assignment context, setter.
+  setter = 0;
+  Expect.identical(0.0, lastSetValue);
+  setter = 1;
+  Expect.identical(1.0, lastSetValue);
+  setter = -0;
+  Expect.identical(-0.0, lastSetValue);
+  setter = -1;
+  Expect.identical(-1.0, lastSetValue);
+  setter = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, lastSetValue);
+  setter = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, lastSetValue);
+  setter = 0x02;
+  Expect.identical(2.0, lastSetValue);
+  setter = -0x02;
+  Expect.identical(-2.0, lastSetValue);
+
+  // Argument context.
+  test(0.0, 0);
+  test(1.0, 1);
+  test(-0.0, -0);
+  test(-1.0, -1);
+  test(9223372036854775808.0, 9223372036854775808);
+  test(18446744073709551616.0, 18446744073709551616);
+  test(2.0, 0x02);
+  test(-2.0, -0x02);
+
+  // Argument context, operator setter.
+  List<double> box = [0.5];
+  box[0] = 0;
+  Expect.identical(0.0, box[0]);
+  box[0] = 1;
+  Expect.identical(1.0, box[0]);
+  box[0] = -0;
+  Expect.identical(-0.0, box[0]);
+  box[0] = -1;
+  Expect.identical(-1.0, box[0]);
+  box[0] = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, box[0]);
+  box[0] = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, box[0]);
+  box[0] = 0x02;
+  Expect.identical(2.0, box[0]);
+  box[0] = -0x02;
+  Expect.identical(-2.0, box[0]);
+
+  // Argument context, custom operators.
+  var oper = Oper();
+  Expect.identical(0.0, oper + 0);
+  Expect.identical(1.0, oper + 1);
+  Expect.identical(-0.0, oper + -0);
+  Expect.identical(-1.0, oper + -1);
+  Expect.identical(9223372036854775808.0, oper + 9223372036854775808);
+  Expect.identical(18446744073709551616.0, oper + 18446744073709551616);
+  Expect.identical(2.0, oper + 0x02);
+  Expect.identical(-2.0, oper + -0x02);
+
+  Expect.identical(0.0, oper >> 0);
+  Expect.identical(1.0, oper >> 1);
+  Expect.identical(-0.0, oper >> -0);
+  Expect.identical(-1.0, oper >> -1);
+  Expect.identical(9223372036854775808.0, oper >> 9223372036854775808);
+  Expect.identical(18446744073709551616.0, oper >> 18446744073709551616);
+  Expect.identical(2.0, oper >> 0x02);
+  Expect.identical(-2.0, oper >> -0x02);
+
+  Expect.identical(0.0, oper[0]);
+  Expect.identical(1.0, oper[1]);
+  Expect.identical(-0.0, oper[-0]);
+  Expect.identical(-1.0, oper[-1]);
+  Expect.identical(9223372036854775808.0, oper[9223372036854775808]);
+  Expect.identical(18446744073709551616.0, oper[18446744073709551616]);
+  Expect.identical(2.0, oper[0x02]);
+  Expect.identical(-2.0, oper[-0x02]);
+
+  // Explicit return context.
+  double fun1() => 0;
+  Expect.identical(0.0, fun1());
+  double fun2() => 1;
+  Expect.identical(1.0, fun2());
+  double fun3() => -0;
+  Expect.identical(-0.0, fun3());
+  double fun4() => -1;
+  Expect.identical(-1.0, fun4());
+  double fun5() => 9223372036854775808;
+  Expect.identical(9223372036854775808.0, fun5());
+  double fun6() => 18446744073709551616;
+  Expect.identical(18446744073709551616.0, fun6());
+  double fun7() => 0x02;
+  Expect.identical(2.0, fun7());
+  double fun8() => -0x02;
+  Expect.identical(-2.0, fun8());
+
+  // Inferred return context.
+  testFun(0.0, () => 0);
+  testFun(1.0, () => 1);
+  testFun(-0.0, () => -0);
+  testFun(-1.0, () => -1);
+  testFun(9223372036854775808.0, () => 9223372036854775808);
+  testFun(18446744073709551616.0, () => 18446744073709551616);
+  testFun(2.0, () => 0x02);
+  testFun(-2.0, () => -0x02);
+
+  // Function default value context.
+  Object deffun1([double v = 0]) => v;
+  Expect.identical(0.0, deffun1());
+  Object deffun2([double v = 1]) => v;
+  Expect.identical(1.0, deffun2());
+  Object deffun3([double v = -0]) => v;
+  Expect.identical(-0.0, deffun3());
+  Object deffun4([double v = -1]) => v;
+  Expect.identical(-1.0, deffun4());
+  Object deffun5([double v = 9223372036854775808]) => v;
+  Expect.identical(9223372036854775808.0, deffun5());
+  Object deffun6([double v = 18446744073709551616]) => v;
+  Expect.identical(18446744073709551616.0, deffun6());
+  Object deffun7([double v = 0x02]) => v;
+  Expect.identical(2.0, deffun7());
+  Object deffun8([double v = -0x02]) => v;
+  Expect.identical(-2.0, deffun8());
+
+  // Explicit collection literal context.
+  box = <double>[0];
+  Expect.identical(0.0, box[0]);
+  box = <double>[1];
+  Expect.identical(1.0, box[0]);
+  box = <double>[-0];
+  Expect.identical(-0.0, box[0]);
+  box = <double>[-1];
+  Expect.identical(-1.0, box[0]);
+  box = <double>[9223372036854775808];
+  Expect.identical(9223372036854775808.0, box[0]);
+  box = <double>[18446744073709551616];
+  Expect.identical(18446744073709551616.0, box[0]);
+  box = <double>[0x02];
+  Expect.identical(2.0, box[0]);
+  box = <double>[-0x02];
+  Expect.identical(-2.0, box[0]);
+
+  // Implicit collection literal context.
+  box = [0];
+  Expect.identical(0.0, box[0]);
+  box = [1];
+  Expect.identical(1.0, box[0]);
+  box = [-0];
+  Expect.identical(-0.0, box[0]);
+  box = [-1];
+  Expect.identical(-1.0, box[0]);
+  box = [9223372036854775808];
+  Expect.identical(9223372036854775808.0, box[0]);
+  box = [18446744073709551616];
+  Expect.identical(18446744073709551616.0, box[0]);
+  box = [0x02];
+  Expect.identical(2.0, box[0]);
+  box = [-0x02];
+  Expect.identical(-2.0, box[0]);
+
+  Map<double?, double?> map;
+  // Explicit map key context.
+  map = <double, Null>{0: null};
+  Expect.identical(0.0, map.keys.first);
+  map = <double, Null>{1: null};
+  Expect.identical(1.0, map.keys.first);
+  map = <double, Null>{-0: null};
+  Expect.identical(-0.0, map.keys.first);
+  map = <double, Null>{-1: null};
+  Expect.identical(-1.0, map.keys.first);
+  map = <double, Null>{9223372036854775808: null};
+  Expect.identical(9223372036854775808.0, map.keys.first);
+  map = <double, Null>{18446744073709551616: null};
+  Expect.identical(18446744073709551616.0, map.keys.first);
+  map = <double, Null>{0x02: null};
+  Expect.identical(2.0, map.keys.first);
+  map = <double, Null>{-0x02: null};
+  Expect.identical(-2.0, map.keys.first);
+
+  // Implicit map key context.
+  map = {0: null};
+  Expect.identical(0.0, map.keys.first);
+  map = {1: null};
+  Expect.identical(1.0, map.keys.first);
+  map = {-0: null};
+  Expect.identical(-0.0, map.keys.first);
+  map = {-1: null};
+  Expect.identical(-1.0, map.keys.first);
+  map = {9223372036854775808: null};
+  Expect.identical(9223372036854775808.0, map.keys.first);
+  map = {18446744073709551616: null};
+  Expect.identical(18446744073709551616.0, map.keys.first);
+  map = {0x02: null};
+  Expect.identical(2.0, map.keys.first);
+  map = {-0x02: null};
+  Expect.identical(-2.0, map.keys.first);
+
+  // Explicit map value context.
+  map = <Null, double>{null: 0};
+  Expect.identical(0.0, map.values.first);
+  map = <Null, double>{null: 1};
+  Expect.identical(1.0, map.values.first);
+  map = <Null, double>{null: -0};
+  Expect.identical(-0.0, map.values.first);
+  map = <Null, double>{null: -1};
+  Expect.identical(-1.0, map.values.first);
+  map = <Null, double>{null: 9223372036854775808};
+  Expect.identical(9223372036854775808.0, map.values.first);
+  map = <Null, double>{null: 18446744073709551616};
+  Expect.identical(18446744073709551616.0, map.values.first);
+  map = <Null, double>{null: 0x02};
+  Expect.identical(2.0, map.values.first);
+  map = <Null, double>{null: -0x02};
+  Expect.identical(-2.0, map.values.first);
+
+  // Implicit map value context.
+  map = {null: 0};
+  Expect.identical(0.0, map.values.first);
+  map = {null: 1};
+  Expect.identical(1.0, map.values.first);
+  map = {null: -0};
+  Expect.identical(-0.0, map.values.first);
+  map = {null: -1};
+  Expect.identical(-1.0, map.values.first);
+  map = {null: 9223372036854775808};
+  Expect.identical(9223372036854775808.0, map.values.first);
+  map = {null: 18446744073709551616};
+  Expect.identical(18446744073709551616.0, map.values.first);
+  map = {null: 0x02};
+  Expect.identical(2.0, map.values.first);
+  map = {null: -0x02};
+  Expect.identical(-2.0, map.values.first);
+
+  // Top-level contexts
+  Expect.identical(0.0, ts1);
+  Expect.identical(1.0, ts2);
+  Expect.identical(-0.0, ts3);
+  Expect.identical(-1.0, ts4);
+  Expect.identical(9223372036854775808.0, ts5);
+  Expect.identical(18446744073709551616.0, ts6);
+  Expect.identical(2.0, ts7);
+  Expect.identical(-2.0, ts8);
+
+  Expect.identical(0.0, tc1);
+  Expect.identical(1.0, tc2);
+  Expect.identical(-0.0, tc3);
+  Expect.identical(-1.0, tc4);
+  Expect.identical(9223372036854775808.0, tc5);
+  Expect.identical(18446744073709551616.0, tc6);
+  Expect.identical(2.0, tc7);
+  Expect.identical(-2.0, tc8);
+
+  Expect.identical(0.0, tg1);
+  Expect.identical(1.0, tg2);
+  Expect.identical(-0.0, tg3);
+  Expect.identical(-1.0, tg4);
+  Expect.identical(9223372036854775808.0, tg5);
+  Expect.identical(18446744073709551616.0, tg6);
+  Expect.identical(2.0, tg7);
+  Expect.identical(-2.0, tg8);
+
+  // Class contexts
+  var c = new C.ci1();
+  Expect.identical(0.0, c.v1);
+  Expect.identical(1.0, c.v2);
+  Expect.identical(-0.0, c.v3);
+  Expect.identical(-1.0, c.v4);
+  Expect.identical(9223372036854775808.0, c.v5);
+  Expect.identical(18446744073709551616.0, c.v6);
+  Expect.identical(2.0, c.v7);
+  Expect.identical(-2.0, c.v8);
+
+  Expect.identical(0.0, C.s1);
+  Expect.identical(1.0, C.s2);
+  Expect.identical(-0.0, C.s3);
+  Expect.identical(-1.0, C.s4);
+  Expect.identical(9223372036854775808.0, C.s5);
+  Expect.identical(18446744073709551616.0, C.s6);
+  Expect.identical(2.0, C.s7);
+  Expect.identical(-2.0, C.s8);
+
+  Expect.identical(0.0, C.c1);
+  Expect.identical(1.0, C.c2);
+  Expect.identical(-0.0, C.c3);
+  Expect.identical(-1.0, C.c4);
+  Expect.identical(9223372036854775808.0, C.c5);
+  Expect.identical(18446744073709551616.0, C.c6);
+  Expect.identical(2.0, C.c7);
+  Expect.identical(-2.0, C.c8);
+
+  Expect.identical(0.0, new C.cc1().d);
+  Expect.identical(1.0, new C.cc2().d);
+  Expect.identical(-0.0, new C.cc3().d);
+  Expect.identical(-1.0, new C.cc4().d);
+  Expect.identical(9223372036854775808.0, new C.cc5().d);
+  Expect.identical(18446744073709551616.0, new C.cc6().d);
+  Expect.identical(2.0, new C.cc7().d);
+  Expect.identical(-2.0, new C.cc8().d);
+
+  Expect.identical(0.0, const C.cc1().d);
+  Expect.identical(1.0, const C.cc2().d);
+  Expect.identical(-0.0, const C.cc3().d);
+  Expect.identical(-1.0, const C.cc4().d);
+  Expect.identical(9223372036854775808.0, const C.cc5().d);
+  Expect.identical(18446744073709551616.0, const C.cc6().d);
+  Expect.identical(2.0, const C.cc7().d);
+  Expect.identical(-2.0, const C.cc8().d);
+
+  Expect.identical(0.0, new C.ci1().d);
+  Expect.identical(1.0, new C.ci2().d);
+  Expect.identical(-0.0, new C.ci3().d);
+  Expect.identical(-1.0, new C.ci4().d);
+  Expect.identical(9223372036854775808.0, new C.ci5().d);
+  Expect.identical(18446744073709551616.0, new C.ci6().d);
+  Expect.identical(2.0, new C.ci7().d);
+  Expect.identical(-2.0, new C.ci8().d);
+
+  Expect.identical(0.0, const C.ci1().d);
+  Expect.identical(1.0, const C.ci2().d);
+  Expect.identical(-0.0, const C.ci3().d);
+  Expect.identical(-1.0, const C.ci4().d);
+  Expect.identical(9223372036854775808.0, const C.ci5().d);
+  Expect.identical(18446744073709551616.0, const C.ci6().d);
+  Expect.identical(2.0, const C.ci7().d);
+  Expect.identical(-2.0, const C.ci8().d);
+
+  // Nested context, `?:`.
+  v1 = false ? 42.0 : 0;
+  Expect.identical(0.0, v1);
+  v2 = false ? 42.0 : 1;
+  Expect.identical(1.0, v2);
+  v3 = false ? 42.0 : -0;
+  Expect.identical(-0.0, v3);
+  v4 = false ? 42.0 : -1;
+  Expect.identical(-1.0, v4);
+  v5 = false ? 42.0 : 9223372036854775808;
+  Expect.identical(9223372036854775808.0, v5);
+  v6 = false ? 42.0 : 18446744073709551616;
+  Expect.identical(18446744073709551616.0, v6);
+  v7 = false ? 42.0 : 0x02; // Hex literal.
+  Expect.identical(2.0, v7);
+  v8 = false ? 42.0 : -0x02; // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Nested context, `??`.
+  double? nl = double.tryParse("not a double"); // Returns null typed as double.
+  v1 = nl ?? 0;
+  Expect.identical(0.0, v1);
+  v2 = nl ?? 1;
+  Expect.identical(1.0, v2);
+  v3 = nl ?? -0;
+  Expect.identical(-0.0, v3);
+  v4 = nl ?? -1;
+  Expect.identical(-1.0, v4);
+  v5 = nl ?? 9223372036854775808;
+  Expect.identical(9223372036854775808.0, v5);
+  v6 = nl ?? 18446744073709551616;
+  Expect.identical(18446744073709551616.0, v6);
+  v7 = nl ?? 0x02; // Hex literal.
+  Expect.identical(2.0, v7);
+  v8 = nl ?? -0x02; // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Nested context, `..`.
+  v1 = 0..toString();
+  Expect.identical(0.0, v1);
+  v2 = 1..toString();
+  Expect.identical(1.0, v2);
+  v3 = -0
+    ..toString();
+  Expect.identical(-0.0, v3);
+  v4 = -1
+    ..toString();
+  Expect.identical(-1.0, v4);
+  v5 = 9223372036854775808..toString();
+  Expect.identical(9223372036854775808.0, v5);
+  v6 = 18446744073709551616..toString();
+  Expect.identical(18446744073709551616.0, v6);
+  v7 = 0x02..toString(); // Hex literal.
+  Expect.identical(2.0, v7);
+  v8 = -0x02
+    ..toString(); // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Nexted context, double assignment.
+  Object object;
+  object = value = 0;
+  Expect.identical(0.0, value);
+  object = value = 1;
+  Expect.identical(1.0, value);
+  object = value = -0;
+  Expect.identical(-0.0, value);
+  object = value = -1;
+  Expect.identical(-1.0, value);
+  object = value = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, value);
+  object = value = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, value);
+  object = value = 0x02;
+  Expect.identical(2.0, value);
+  object = value = -0x02;
+  Expect.identical(-2.0, value);
+
+  // Nested context, value of assignment.
+  Expect.identical(0.0, value = 0);
+  Expect.identical(1.0, value = 1);
+  Expect.identical(-0.0, value = -0);
+  Expect.identical(-1.0, value = -1);
+  Expect.identical(9223372036854775808.0, value = 9223372036854775808);
+  Expect.identical(18446744073709551616.0, value = 18446744073709551616);
+  Expect.identical(2.0, value = 0x02);
+  Expect.identical(-2.0, value = -0x02);
+
+  // JavaScript platforms represent integers as doubles, so negating them will
+  // result in negative zero, unfortunately.
+  int zero = 0;
+  bool platformHasNegativeZeroInts = (-zero).isNegative;
+
+  // Not promoted without a double context.
+  num x = -0;
+  Expect.identical(0, x);
+  Expect.equals(x.isNegative, platformHasNegativeZeroInts);
+
+  var list = [3.14, 2.17, -0];
+  Expect.notType<List<double>>(list);
+  Expect.identical(0, list[2]);
+  Expect.equals(list[2].isNegative, platformHasNegativeZeroInts);
+
+  // FutureOr<double> also forces double.
+  // "Type that int is not assignable to, but double is."
+  FutureOr<double> fo1 = 0;
+  Expect.identical(0.0, fo1);
+  FutureOr<double> fo2 = 1;
+  Expect.identical(1.0, fo2);
+  FutureOr<double> fo3 = -0;
+  Expect.identical(-0.0, fo3);
+  FutureOr<double> fo4 = -1;
+  Expect.identical(-1.0, fo4);
+  FutureOr<double> fo5 = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, fo5);
+  FutureOr<double> fo6 = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, fo6);
+  FutureOr<double> fo7 = 0x02; // Hex literal.
+  Expect.identical(2.0, fo7);
+  FutureOr<double> fo8 = -0x02; // Hex literal.
+  Expect.identical(-2.0, fo8);
+
+  // Some other FutureOr cases, without being exhaustive.
+  {
+    Object func([FutureOr<double> x = 9223372036854775808]) => x;
+    Expect.identical(9223372036854775808.0, func(9223372036854775808));
+    Expect.identical(9223372036854775808.0, func());
+    FutureOr<double> func2() => 9223372036854775808;
+    Expect.identical(9223372036854775808.0, func2());
+    testGeneric<FutureOr<double>>(9223372036854775808.0, 9223372036854775808);
+    List<FutureOr<double>> l = [9223372036854775808];
+    testGeneric<FutureOr<double>>(9223372036854775808.0, l[0]);
+    l.add(9223372036854775808);
+    testGeneric<FutureOr<double>>(9223372036854775808.0, l[1]);
+    l.add(0.0);
+    l[2] = 9223372036854775808;
+    testGeneric<FutureOr<double>>(9223372036854775808.0, l[2]);
+  }
+
+  // Type variables statically bound to double also force doubles:
+  testGeneric<double>(0.0, 0);
+  testGeneric<double>(1.0, 1);
+  testGeneric<double>(-0.0, -0);
+  testGeneric<double>(-1.0, -1);
+  testGeneric<double>(9223372036854775808.0, 9223372036854775808);
+  testGeneric<double>(18446744073709551616.0, 18446744073709551616);
+  testGeneric<double>(2.0, 0x02);
+  testGeneric<double>(-2.0, -0x02);
+
+  // Uses static type, not run-time type.
+  Super sub = Sub();
+  Expect.identical(0.0, sub.method(0));
+  Expect.identical(1.0, sub.method(1));
+  Expect.identical(-0.0, sub.method(-0));
+  Expect.identical(-1.0, sub.method(-1));
+  Expect.identical(9223372036854775808.0, sub.method(9223372036854775808));
+  Expect.identical(18446744073709551616.0, sub.method(18446744073709551616));
+  Expect.identical(2.0, sub.method(0x02));
+  Expect.identical(-2.0, sub.method(-0x02));
+
+  {
+    // Check that the correct value is used as receiver for the cascade.
+    var collector = StringBuffer();
+    double tricky = -42
+      ..toString().codeUnits.forEach(collector.writeCharCode);
+    Expect.equals("${-42.0}", collector.toString());
+  }
+
+  bool isDigit(int charCode) => (charCode ^ 0x30) <= 9;
+  // Throws because double context does not affect "4", so the toString does
+  // not contain any non-digit (like ".", which it would if 4 was a double).
+  // The context type of "4.toString..." is not double, and the `-`
+  // is not having a literal as operand.
+  Expect.throws(() {
+    double tricky =
+        -4.toString().codeUnits.firstWhere((c) => !isDigit(c)).toDouble();
+  });
+}
+
+void test(double expect, double value) {
+  Expect.identical(expect, value);
+}
+
+void testFun(double expect, double f()) {
+  Expect.identical(expect, f());
+}
+
+void testGeneric<T>(double expect, T value) {
+  Expect.identical(expect, value);
+}
+
+class Oper {
+  Object operator +(double value) => value;
+  Object operator >>(double value) => value;
+  Object operator [](double value) => value;
+}
+
+class C {
+  // Instance variable initializer
+  final double v1 = 0;
+  final double v2 = 1;
+  final double v3 = -0;
+  final double v4 = -1;
+  final double v5 = 9223372036854775808;
+  final double v6 = 18446744073709551616;
+  final double v7 = 0x02; // Hex literal.
+  final double v8 = -0x02; // Hex literal.
+
+  // Static class variable initializer
+  static double s1 = 0;
+  static double s2 = 1;
+  static double s3 = -0;
+  static double s4 = -1;
+  static double s5 = 9223372036854775808;
+  static double s6 = 18446744073709551616;
+  static double s7 = 0x02; // Hex literal.
+  static double s8 = -0x02; // Hex literal.
+
+  // Const class variable initializer context.
+  static const double c1 = 0;
+  static const double c2 = 1;
+  static const double c3 = -0;
+  static const double c4 = -1;
+  static const double c5 = 9223372036854775808;
+  static const double c6 = 18446744073709551616;
+  static const double c7 = 0x02; // Hex literal.
+  static const double c8 = -0x02; // Hex literal.
+
+  final double d;
+
+  // Default value context for a double initializing formal.
+  const C.cc1([this.d = 0]);
+  const C.cc2([this.d = 1]);
+  const C.cc3([this.d = -0]);
+  const C.cc4([this.d = -1]);
+  const C.cc5([this.d = 9223372036854775808]);
+  const C.cc6([this.d = 18446744073709551616]);
+  const C.cc7([this.d = 0x02]);
+  const C.cc8([this.d = -0x02]);
+
+  // Initializer list expressions context.
+  const C.ci1() : this.d = 0;
+  const C.ci2() : this.d = 1;
+  const C.ci3() : this.d = -0;
+  const C.ci4() : this.d = -1;
+  const C.ci5() : this.d = 9223372036854775808;
+  const C.ci6() : this.d = 18446744073709551616;
+  const C.ci7() : this.d = 0x02;
+  const C.ci8() : this.d = -0x02;
+}
+
+// Top-level lazy variable initializer
+double ts1 = 0;
+double ts2 = 1;
+double ts3 = -0;
+double ts4 = -1;
+double ts5 = 9223372036854775808;
+double ts6 = 18446744073709551616;
+double ts7 = 0x02; // Hex literal.
+double ts8 = -0x02; // Hex literal.
+
+// Top-level const variable initializer.
+const double tc1 = 0;
+const double tc2 = 1;
+const double tc3 = -0;
+const double tc4 = -1;
+const double tc5 = 9223372036854775808; // 2^63, invalid signed 64-bit integer.
+const double tc6 = 18446744073709551616;
+const double tc7 = 0x02; // Hex literal.
+const double tc8 = -0x02; // Hex literal.
+
+// Top-level getter return context.
+double get tg1 => 0;
+double get tg2 => 1;
+double get tg3 => -0;
+double get tg4 => -1;
+double get tg5 => 9223372036854775808;
+double get tg6 => 18446744073709551616;
+double get tg7 => 0x02; // Hex literal.
+double get tg8 => -0x02; // Hex literal.
+
+Object? lastSetValue = null;
+void set setter(double v) {
+  lastSetValue = v;
+}
+
+abstract class Super {
+  Object method(double v);
+}
+
+class Sub implements Super {
+  Object method(Object o) => o;
+}
diff --git a/tests/language/dynamic/call_test.dart b/tests/language/dynamic/call_test.dart
new file mode 100644
index 0000000..65335cd
--- /dev/null
+++ b/tests/language/dynamic/call_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing dynamic calls.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() {}
+  int foo(int i) {
+    return i;
+  }
+}
+
+class DynamicCallTest {
+  static void testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.foo(1));
+  }
+}
+
+main() {
+  DynamicCallTest.testMain();
+}
diff --git a/tests/language/dynamic/dynamic2_runtime_test.dart b/tests/language/dynamic/dynamic2_runtime_test.dart
new file mode 100644
index 0000000..d7159b8
--- /dev/null
+++ b/tests/language/dynamic/dynamic2_runtime_test.dart
@@ -0,0 +1,17 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Test the prohibited use of 'dynamic' in extending and implementing classes.
+
+class A
+
+
+{}
+
+main() {
+  new A();
+}
diff --git a/tests/language/dynamic/dynamic2_test.dart b/tests/language/dynamic/dynamic2_test.dart
new file mode 100644
index 0000000..6871f9f
--- /dev/null
+++ b/tests/language/dynamic/dynamic2_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Test the prohibited use of 'dynamic' in extending and implementing classes.
+
+class A
+//    ^
+// [cfe] The type 'dynamic' can't be used as supertype.
+  extends dynamic
+  //      ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENDS_NON_CLASS
+  implements dynamic
+  //         ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_NON_CLASS
+{}
+
+main() {
+  new A();
+}
diff --git a/tests/language/dynamic/dynamic_test.dart b/tests/language/dynamic/dynamic_test.dart
new file mode 100644
index 0000000..e89b44e
--- /dev/null
+++ b/tests/language/dynamic/dynamic_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program testing the use of 'dynamic' in generic types.
+
+import "package:expect/expect.dart";
+
+abstract class Iface<K, V> {}
+
+class M1<K, V> implements Iface<K, V> {}
+
+class M2<K> implements Iface<K, dynamic> {}
+
+class M3 implements Iface<String, dynamic> {}
+
+typedef dynamic F1<T>(dynamic x, T y);
+
+class HasFieldDynamic {
+  HasFieldDynamic() : dynamic = "dynamic" {}
+  var dynamic; // Field named dynamic is allowed.
+}
+
+class HasMethodDynamic {
+  dynamic() => "dynamic"; // Method named dynamic is allowed.
+}
+
+main() {
+  // dynamic is a top-type, equivalent to Object at runtime.
+  Expect.isTrue(dynamic is Type);
+  Expect.equals(dynamic, dynamic);
+
+  // dynamic is not a subtype of num or String.
+  M1<dynamic, dynamic> m1 = new M1<dynamic, dynamic>();
+  Expect.isFalse(m1 is Iface<dynamic, num>);
+  Expect.isFalse(m1 is Iface<String, dynamic>);
+  Expect.isFalse(m1 is Iface<String, num>);
+  Expect.isFalse(m1 is Iface<num, String>);
+
+  M2<dynamic> m2 = new M2<dynamic>(); // is Iface<dynamic, dynamic>.
+  Expect.isFalse(m2 is Iface<dynamic, num>);
+  Expect.isFalse(m2 is Iface<String, dynamic>);
+  Expect.isFalse(m2 is Iface<String, num>);
+  Expect.isFalse(m2 is Iface<num, String>);
+
+  M3 m3 = new M3(); // is IFace<String, dynamic>.
+  Expect.isFalse(m3 is Iface<dynamic, num>);
+  Expect.isTrue(m3 is Iface<String, dynamic>);
+  Expect.isFalse(m3 is Iface<String, num>);
+  Expect.isTrue(m3 is! Iface<num, String>);
+
+  F1<int> f1 = (dynamic s, int i) => s[i]; // is dynamic Function(dynamic, int).
+  Expect.isTrue(f1 is F1<int>);
+
+  // "dynamic" is not a reserved word or built-in identifier.
+
+  HasFieldDynamic has_field = new HasFieldDynamic();
+  Expect.equals("dynamic", has_field.dynamic);
+
+  HasMethodDynamic has_method = new HasMethodDynamic();
+  Expect.equals("dynamic", has_method.dynamic());
+
+  {
+    int dynamic = 0; // Local variable named dynamic is allowed.
+    Expect.equals(0, dynamic);
+  }
+}
diff --git a/tests/language/dynamic/field_runtime_test.dart b/tests/language/dynamic/field_runtime_test.dart
new file mode 100644
index 0000000..aebfbf6
--- /dev/null
+++ b/tests/language/dynamic/field_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+//
+// Test that ensures that fields can be accessed dynamically.
+
+import "package:expect/expect.dart";
+
+class A extends C {
+  var a;
+  var b;
+}
+
+class C {
+  foo() {
+
+
+  }
+  bar() {
+
+
+  }
+}
+
+main() {
+  var a = new A();
+  a.a = 1;
+  a.b = a;
+
+
+}
diff --git a/tests/language/dynamic/field_test.dart b/tests/language/dynamic/field_test.dart
new file mode 100644
index 0000000..ebe094e
--- /dev/null
+++ b/tests/language/dynamic/field_test.dart
@@ -0,0 +1,43 @@
+// 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.
+//
+// Test that ensures that fields can be accessed dynamically.
+
+import "package:expect/expect.dart";
+
+class A extends C {
+  var a;
+  var b;
+}
+
+class C {
+  foo() {
+    print(a);
+    //    ^
+    // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+    // [cfe] The getter 'a' isn't defined for the class 'C'.
+    return a;
+    //     ^
+    // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+    // [cfe] The getter 'a' isn't defined for the class 'C'.
+  }
+  bar() {
+    print(b.a);
+    //    ^
+    // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+    // [cfe] The getter 'b' isn't defined for the class 'C'.
+    return b.a;
+    //     ^
+    // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+    // [cfe] The getter 'b' isn't defined for the class 'C'.
+  }
+}
+
+main() {
+  var a = new A();
+  a.a = 1;
+  a.b = a;
+  Expect.equals(1, a.foo());
+  Expect.equals(1, a.bar());
+}
diff --git a/tests/language/dynamic/hash_code_test.dart b/tests/language/dynamic/hash_code_test.dart
new file mode 100644
index 0000000..b705dd8
--- /dev/null
+++ b/tests/language/dynamic/hash_code_test.dart
@@ -0,0 +1,10 @@
+// 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:expect/expect.dart";
+
+void main() {
+  dynamic x = 3;
+  Expect.equals(3, x.hashCode);
+}
diff --git a/tests/language/dynamic/invoke_test.dart b/tests/language/dynamic/invoke_test.dart
new file mode 100644
index 0000000..d01beca
--- /dev/null
+++ b/tests/language/dynamic/invoke_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing dynamic calls.
+
+import "package:expect/expect.dart";
+
+// Make this something that DDC considers side effecting.
+dynamic get d => "hello";
+
+regress29504() {
+  // These forms were being incorrectly generated as dynamic invokes, which is
+  // not supposed to be done for the Object members that are always present on
+  // all Dart types, including `null`.
+  //
+  // See https://github.com/dart-lang/sdk/issues/29504
+  //
+  // What we're testing here is that none of these generate dynamic invokes,
+  // because that will throw a NoSuchMethod error if it happens.
+  Expect.equals(d.runtimeType, String);
+  Expect.equals(d?.runtimeType, String);
+  Expect.equals(d..runtimeType, "hello");
+
+  Expect.equals(d.hashCode, "hello".hashCode);
+  Expect.equals(d?.hashCode, "hello".hashCode);
+  Expect.equals(d..hashCode, "hello");
+
+  Expect.equals(d.toString(), "hello");
+  Expect.equals(d?.toString(), "hello");
+  Expect.equals(d..toString(), "hello");
+}
+
+main() {
+  regress29504();
+}
diff --git a/tests/language/dynamic/prefix_core_test.dart b/tests/language/dynamic/prefix_core_test.dart
new file mode 100644
index 0000000..65da032
--- /dev/null
+++ b/tests/language/dynamic/prefix_core_test.dart
@@ -0,0 +1,18 @@
+// 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.
+// Test explicit import of dart:core in the source code..
+
+library DynamicPrefixCoreTest.dart;
+
+import "package:expect/expect.dart";
+import "dart:core" as mycore;
+
+void main() {
+  // The built-in type declaration `dynamic`, which is declared in the
+  // library `dart:core`, denotes the `dynamic` type. So, in this library
+  // it must be reference with the prefix.
+  dynamic; //# 01: compile-time error
+
+  Expect.isTrue(mycore.dynamic is mycore.Type); //# 02: ok
+}
diff --git a/tests/language/dynamic/set_test.dart b/tests/language/dynamic/set_test.dart
new file mode 100644
index 0000000..35f2b97
--- /dev/null
+++ b/tests/language/dynamic/set_test.dart
@@ -0,0 +1,34 @@
+// 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.
+//
+// Test that ensures that fields can be accessed dynamically.
+
+import "package:expect/expect.dart";
+
+class C {
+  final x = "hello";
+  get y => ", ";
+  m() => "world!";
+}
+
+// Regression test for https://github.com/dart-lang/sdk/issues/27258
+main() {
+  dynamic c = new C();
+  Expect.equals(c.x + c.y + c.m(), "hello, world!");
+
+  Expect.throws(() {
+    c.x = 1;
+  });
+  Expect.throws(() {
+    c.x = '1';
+  });
+  Expect.throws(() {
+    c.y = '2';
+  });
+  Expect.throws(() {
+    c.m = '3';
+  });
+
+  Expect.equals(c.x + c.y + c.m(), "hello, world!");
+}
diff --git a/tests/language/dynamic/type_literal_test.dart b/tests/language/dynamic/type_literal_test.dart
new file mode 100644
index 0000000..335e9ae
--- /dev/null
+++ b/tests/language/dynamic/type_literal_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test generation of 'dynamic' type literals.
+
+import "package:expect/expect.dart";
+
+void main() {
+  Expect.isTrue(dynamic is Type);
+  Expect.isFalse(dynamic == Type);
+}
diff --git a/tests/language/dynamic_type_helper.dart b/tests/language/dynamic_type_helper.dart
new file mode 100644
index 0000000..cb14450
--- /dev/null
+++ b/tests/language/dynamic_type_helper.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dynamic_type_helper;
+
+import 'package:expect/expect.dart';
+
+/// Checks that a dynamic type error is thrown when [f] is executed
+/// and [expectTypeError] is `true`.
+void testDynamicTypeError(bool expectTypeError, f(), [String? message]) {
+  if (expectTypeError) {
+    checkDynamicTypeError(f, message);
+  } else {
+    checkNoDynamicTypeError(f, message);
+  }
+}
+
+/// Checks that a dynamic type error is thrown when f is executed.
+void checkDynamicTypeError(f(), [String? message]) {
+  message = message != null ? ': $message' : '';
+  try {
+    f();
+    Expect.fail('Missing type error$message.');
+  } on TypeError catch (e) {}
+}
+
+/// Checks that no dynamic type error is thrown when [f] is executed.
+void checkNoDynamicTypeError(f(), [String? message]) {
+  message = message != null ? ': $message' : '';
+  try {
+    f();
+  } on TypeError catch (e) {
+    Expect.fail('Unexpected type error$message.');
+  }
+}
diff --git a/tests/language/enum/duplicate_lib.dart b/tests/language/enum/duplicate_lib.dart
new file mode 100644
index 0000000..b9c84f5
--- /dev/null
+++ b/tests/language/enum/duplicate_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library enum_duplicate_lib;
+
+enum Enum1 {
+  A,
+  B,
+}
+
+class Enum2 {
+  static Iterable get values => ['Enum2.A', 'Enum2.B'];
+}
diff --git a/tests/language/enum/duplicate_test.dart b/tests/language/enum/duplicate_test.dart
new file mode 100644
index 0000000..7904652
--- /dev/null
+++ b/tests/language/enum/duplicate_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// Test for duplicate enums.
+
+library enum_duplicate_test;
+
+import 'package:expect/expect.dart';
+
+import 'duplicate_lib.dart' as lib; //# 01: ok
+import 'duplicate_lib.dart' as lib; //# 02: ok
+
+enum Enum1 {
+  A,
+  B,
+}
+
+enum Enum2 {
+  A,
+  B,
+}
+
+main() {
+  Expect.equals('Enum1.A,Enum1.B', Enum1.values.join(','));
+  Expect.equals('Enum1.A,Enum1.B', lib.Enum1.values.join(',')); //# 01: continued
+  Expect.equals('Enum2.A,Enum2.B', Enum2.values.join(','));
+  Expect.equals('Enum2.A,Enum2.B', lib.Enum2.values.join(',')); //# 02: continued
+}
diff --git a/tests/language/enum/enum_test.dart b/tests/language/enum/enum_test.dart
new file mode 100644
index 0000000..87d6d65
--- /dev/null
+++ b/tests/language/enum/enum_test.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+enum Enum1 { _ }
+enum Enum2 { A }
+enum Enum3 { B, C }
+enum Enum4 {
+  D,
+  E,
+}
+enum Enum5 { F, G, H }
+enum _Enum6 { I, _J }
+
+enum _IsNot { IsNot }
+
+// Regression test for https://github.com/dart-lang/sdk/issues/33348
+enum JSFunctionPrototype {
+  length,
+  prototype,
+  __proto__,
+  arguments,
+  caller,
+  calee,
+  name,
+  constructor,
+  apply,
+  bind,
+  call
+}
+
+void expectIs<T>(T t, bool Function(Object?) test) {
+  Object? obj = t;
+  Expect.isTrue(test(obj), '$obj is $T');
+  Expect.isFalse(obj is _IsNot, '$obj is _IsNot');
+  // test cast
+  t = obj as T;
+  Expect.throwsTypeError(() => obj as _IsNot, '$obj as _IsNot');
+}
+
+main() {
+  expectIs(Enum1._, (e) => e is Enum1);
+  expectIs(Enum2.A, (e) => e is Enum2);
+  expectIs(Enum3.B, (e) => e is Enum3);
+  expectIs(Enum4.E, (e) => e is Enum4);
+  expectIs(Enum5.G, (e) => e is Enum5);
+
+  Expect.equals('Enum1._', Enum1._.toString());
+  Expect.equals(0, Enum1._.index);
+  Expect.listEquals([Enum1._], Enum1.values);
+  Enum1.values.forEach(test1);
+
+  Expect.equals('Enum2.A', Enum2.A.toString());
+  Expect.equals(0, Enum2.A.index);
+  Expect.listEquals([Enum2.A], Enum2.values);
+  Expect.identical(const <Enum2>[Enum2.A], Enum2.values);
+  Enum2.values.forEach(test2);
+
+  Expect.equals('Enum3.B', Enum3.B.toString());
+  Expect.equals('Enum3.C', Enum3.C.toString());
+  Expect.equals(0, Enum3.B.index);
+  Expect.equals(1, Enum3.C.index);
+  Expect.listEquals([Enum3.B, Enum3.C], Enum3.values);
+  Enum3.values.forEach(test3);
+
+  Expect.equals('Enum4.D', Enum4.D.toString());
+  Expect.equals('Enum4.E', Enum4.E.toString());
+  Expect.equals(0, Enum4.D.index);
+  Expect.equals(1, Enum4.E.index);
+  Expect.listEquals([Enum4.D, Enum4.E], Enum4.values);
+  Enum4.values.forEach(test4);
+
+  Expect.equals('Enum5.F', Enum5.F.toString());
+  Expect.equals('Enum5.G', Enum5.G.toString());
+  Expect.equals('Enum5.H', Enum5.H.toString());
+  Expect.equals(0, Enum5.F.index);
+  Expect.equals(1, Enum5.G.index);
+  Expect.equals(2, Enum5.H.index);
+  Expect.listEquals([Enum5.F, Enum5.G, Enum5.H], Enum5.values);
+  Enum5.values.forEach(test5);
+
+  Expect.equals('_Enum6.I', _Enum6.I.toString());
+  Expect.equals('_Enum6._J', _Enum6._J.toString());
+
+  for (var value in JSFunctionPrototype.values) {
+    expectIs(value, (e) => e is JSFunctionPrototype);
+  }
+  Expect.equals(JSFunctionPrototype.length, JSFunctionPrototype.values[0]);
+}
+
+test1(Enum1 e) {
+  int index;
+  switch (e) {
+    case Enum1._:
+      index = 0;
+      break;
+  }
+  Expect.equals(e.index, index);
+}
+
+test2(Enum2 e) {
+  int index;
+  switch (e) {
+    case Enum2.A:
+      index = 0;
+      break;
+  }
+  Expect.equals(e.index, index);
+}
+
+test3(Enum3 e) {
+  int index;
+  switch (e) {
+    case Enum3.C:
+      index = 1;
+      break;
+    case Enum3.B:
+      index = 0;
+      break;
+  }
+  Expect.equals(e.index, index);
+}
+
+test4(Enum4 e) {
+  int index;
+  switch (e) {
+    case Enum4.D:
+      index = 0;
+      break;
+    case Enum4.E:
+      index = 1;
+      break;
+  }
+  Expect.equals(e.index, index);
+}
+
+test5(Enum5 e) {
+  int index;
+  switch (e) {
+    case Enum5.H:
+      index = 2;
+      break;
+    case Enum5.F:
+      index = 0;
+      break;
+    case Enum5.G:
+      index = 1;
+      break;
+  }
+  Expect.equals(e.index, index);
+}
diff --git a/tests/language/enum/index_test.dart b/tests/language/enum/index_test.dart
new file mode 100644
index 0000000..ce6994b
--- /dev/null
+++ b/tests/language/enum/index_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Test index access for enums.
+
+library enum_index_test;
+
+import 'package:expect/expect.dart';
+
+enum Enum {
+  A,
+  B,
+}
+
+class Class {
+  var index;
+}
+
+main() {
+  test(null, new Class());
+  test(0, Enum.A);
+  test(1, Enum.B);
+}
+
+test(expected, object) {
+  Expect.equals(expected, object.index);
+}
diff --git a/tests/language/enum/initialization_near_stack_overflow_test.dart b/tests/language/enum/initialization_near_stack_overflow_test.dart
new file mode 100644
index 0000000..598b382
--- /dev/null
+++ b/tests/language/enum/initialization_near_stack_overflow_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// https://github.com/flutter/flutter/issues/25041
+
+// This test may produce a compile time exception from stack overflow during
+// enum initialization or succeed in enum initialization depending on exactly
+// how much stack is left and used by the compiler. It should never crash nor
+// produce a runtime exception.
+
+enum Fruit {
+  apple,
+  banana,
+}
+
+getFruit() => Fruit.apple;
+
+recurse() {
+  try {
+    recurse();
+  } catch (e, st) {
+    print("$e ${getFruit()}");
+  }
+}
+
+main() {
+  try {
+    recurse();
+  } on StackOverflowError catch (e) {
+    // Swallow.
+  }
+}
diff --git a/tests/language/enum/is_keyword_runtime_test.dart b/tests/language/enum/is_keyword_runtime_test.dart
new file mode 100644
index 0000000..2e9a471
--- /dev/null
+++ b/tests/language/enum/is_keyword_runtime_test.dart
@@ -0,0 +1,13 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test that `enum` is considered a keyword and therefore invalid as the name of
+// declarations.
+
+main() {
+
+}
diff --git a/tests/language/enum/is_keyword_test.dart b/tests/language/enum/is_keyword_test.dart
new file mode 100644
index 0000000..5e7d0b5
--- /dev/null
+++ b/tests/language/enum/is_keyword_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+// Test that `enum` is considered a keyword and therefore invalid as the name of
+// declarations.
+
+main() {
+  var enum;
+  //  ^^^^
+  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+  // [cfe] Expected an identifier, but got 'enum'.
+}
diff --git a/tests/language/enum/private_lib.dart b/tests/language/enum/private_lib.dart
new file mode 100644
index 0000000..c8fb00f
--- /dev/null
+++ b/tests/language/enum/private_lib.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library enum_private_lib;
+
+enum Enum2 {
+  _A,
+  _B,
+}
diff --git a/tests/language/enum/private_runtime_1_test.dart b/tests/language/enum/private_runtime_1_test.dart
new file mode 100644
index 0000000..34af126
--- /dev/null
+++ b/tests/language/enum/private_runtime_1_test.dart
@@ -0,0 +1,25 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test privacy issue for enums.
+
+library enum_private_test;
+
+import 'package:expect/expect.dart';
+
+import 'private_lib.dart';
+
+enum Enum1 {
+  _A,
+  _B,
+}
+
+main() {
+  Expect.equals('Enum1._A,Enum1._B', Enum1.values.join(','));
+  Expect.equals('Enum2._A,Enum2._B', Enum2.values.join(','));
+
+}
diff --git a/tests/language/enum/private_runtime_test.dart b/tests/language/enum/private_runtime_test.dart
new file mode 100644
index 0000000..adc8d7a
--- /dev/null
+++ b/tests/language/enum/private_runtime_test.dart
@@ -0,0 +1,25 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test privacy issue for enums.
+
+library enum_private_test;
+
+import 'package:expect/expect.dart';
+
+import 'private_lib.dart';
+
+enum Enum1 {
+  _A,
+  _B,
+}
+
+main() {
+  Expect.equals('Enum1._A,Enum1._B', Enum1.values.join(','));
+
+
+}
diff --git a/tests/language/enum/private_test.dart b/tests/language/enum/private_test.dart
new file mode 100644
index 0000000..bd99d84
--- /dev/null
+++ b/tests/language/enum/private_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Test privacy issue for enums.
+
+library enum_private_test;
+
+import 'package:expect/expect.dart';
+
+import 'private_lib.dart';
+
+enum Enum1 {
+  _A,
+  _B,
+}
+
+main() {
+  Expect.equals('Enum1._A,Enum1._B', Enum1.values.join(','));
+  Expect.equals('Enum2._A,Enum2._B', Enum2.values.join(','));
+  Expect.throwsNoSuchMethodError(() => Enum2._A);
+  //                                         ^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_ENUM_CONSTANT
+  // [cfe] Getter not found: '_A'.
+}
diff --git a/tests/language/enum/syntax_test.dart b/tests/language/enum/syntax_test.dart
new file mode 100644
index 0000000..250e1ae
--- /dev/null
+++ b/tests/language/enum/syntax_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Basic syntax test for enumeration types
+
+enum Color { red, orange, yellow, green }
+
+// Additional comma at end of list is ok.
+enum Veggies {
+  carrot,
+  bean,
+  broccolo,
+}
+
+// Need at least one enumeration identifier.
+enum Nada {} // //# 01: syntax error
+
+// Duplicate entries are a compile-time error
+enum ComeAgain { ahau, knust, zipfel, knust, gupf } // //# 02: compile-time error
+
+// Enum entries must not collide with implicitly defined members.
+enum ComeAgain { ahau, knust, zipfel, index } //# 03: compile-time error
+
+enum ComeAgain { ahau, knust, zipfel, values } //# 04: compile-time error
+
+enum ComeAgain { ahau, knust, zipfel, toString } //# 05: compile-time error
+
+// Enum entry must not collide with enum type name.
+enum ComeAgain { ahau, knust, zipfel, ComeAgain } //# 06: compile-time error
+
+// Missing comma.
+enum Numbers { one, two, three four, five } // //# 07: syntax error
+
+// Missing enum type name.
+enum { eins, zwei, drei } // //# 08: syntax error
+
+// Duplicate name in library scope.
+topLevelFunction() => null;
+enum topLevelFunction { bla, blah } // //# 09: compile-time error
+
+class C {}
+enum C { bla, blah } // //# 10: compile-time error
+
+var zzTop;
+enum zzTop { Billy, Dusty, Frank } // //# 11: compile-time error
+
+// Enum type cannot be super type or interface type.
+class Rainbow extends Color {} // //# 20: compile-time error
+class Rainbow implements Color {} // //# 21: compile-time error
+class Rainbow extends List with Color {} // //# 22: compile-time error
+
+main() {
+  Nada x; //# 01: continued
+  var x = ComeAgain.zipfel; // //# 02: continued
+  var x = ComeAgain.zipfel; // //# 03: continued
+  var x = ComeAgain.zipfel; // //# 04: continued
+  var x = ComeAgain.zipfel; // //# 05: continued
+  var x = ComeAgain.zipfel; // //# 06: continued
+  var x = Numbers.four; // //# 07: continued
+  var x = topLevelFunction.bla; // //# 09: continued
+  var x = C.bla; // //# 10: continued
+  var x = zzTop.Frank; // //# 11: continued
+
+  var x = new Rainbow(); // //# 20: continued
+  var x = new Rainbow(); // //# 21: continued
+  var x = new Rainbow(); // //# 22: continued
+
+  // It is a compile-time error to explicitly instantiate an enum instance.
+  var x = new Color(); // //# 30: compile-time error
+}
diff --git a/tests/language/enum/value_name_test.dart b/tests/language/enum/value_name_test.dart
new file mode 100644
index 0000000..f4a0d8a
--- /dev/null
+++ b/tests/language/enum/value_name_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+enum ErrorContext { general, name, description, targets }
+
+void main() {
+  Expect.equals(ErrorContext.name, ErrorContext.name);
+}
diff --git a/tests/language/exception/catch_liveness_test.dart b/tests/language/exception/catch_liveness_test.dart
new file mode 100644
index 0000000..df9a3dd
--- /dev/null
+++ b/tests/language/exception/catch_liveness_test.dart
@@ -0,0 +1,29 @@
+// 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:expect/expect.dart";
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+foo() => 1;
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+throwException() => throw 'x';
+
+main() {
+  var x = 10;
+  var e2 = null;
+  try {
+    var t = foo();
+    throwException();
+    print(t);
+    x = 3;
+  } catch (e) {
+    Expect.equals(10, x);
+    e2 = e;
+  }
+  Expect.equals(10, x);
+  Expect.equals('x', e2);
+}
diff --git a/tests/language/exception/code_after_try_is_executed_test.dart b/tests/language/exception/code_after_try_is_executed_test.dart
new file mode 100644
index 0000000..57ffd84
--- /dev/null
+++ b/tests/language/exception/code_after_try_is_executed_test.dart
@@ -0,0 +1,19 @@
+// 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.
+// Test that the runtime still runs the code after a try/catch. The
+// test cannot use Expect.throws, because Expect.throws uses the same
+// pattern.
+
+import "package:expect/expect.dart";
+
+main() {
+  var exception;
+  try {
+    throw 'foo';
+  } on String catch (ex) {
+    exception = ex;
+  }
+  Expect.isTrue(exception is String);
+  throw 'foo'; //# 01: runtime error
+}
diff --git a/tests/language/exception/exception_test.dart b/tests/language/exception/exception_test.dart
new file mode 100644
index 0000000..86c2206
--- /dev/null
+++ b/tests/language/exception/exception_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class ExceptionTest {
+  static testMain() {
+    int i = 0;
+    try {
+      throw "Hello";
+    } on String catch (s) {
+      print(s);
+      i += 10;
+    }
+
+    try {
+      throw "bye";
+    } on String catch (s) {
+      print(s);
+      i += 10;
+    }
+    Expect.equals(20, i);
+
+    bool correctCatch = false;
+    try {
+      // This throws NullThrownError
+      throw (null as dynamic);
+    } on String catch (s) {
+      correctCatch = false;
+    } on NullThrownError catch (e) {
+      correctCatch = true;
+    } catch (x) {
+      correctCatch = false;
+    }
+    Expect.isTrue(correctCatch);
+  }
+}
+
+main() {
+  ExceptionTest.testMain();
+}
diff --git a/tests/language/exception/finally10_test.dart b/tests/language/exception/finally10_test.dart
new file mode 100644
index 0000000..dfe47b5
--- /dev/null
+++ b/tests/language/exception/finally10_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a catch block that throws.
+
+import "package:expect/expect.dart";
+
+class A {
+  var field;
+  start() {}
+  stop() {
+    field = 42;
+  }
+}
+
+class B {
+  var totalCompileTime = new A();
+  var runCompiler = new Object();
+
+  run() {
+    totalCompileTime.start();
+    try {
+      throw 'foo';
+    } catch (exception) {
+      // Use [runCompiler] twice to ensure it will have a local
+      // variable.
+      runCompiler.toString();
+      runCompiler.toString();
+      rethrow;
+    } finally {
+      totalCompileTime.stop();
+    }
+  }
+}
+
+main() {
+  var b = new B();
+  try {
+    b.run();
+    throw 'Expected exception';
+  } catch (exception) {
+    // Expected exception.
+  }
+
+  Expect.equals(42, b.totalCompileTime.field);
+}
diff --git a/tests/language/exception/finally11_test.dart b/tests/language/exception/finally11_test.dart
new file mode 100644
index 0000000..dbe7288
--- /dev/null
+++ b/tests/language/exception/finally11_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a nested try block.
+
+import "package:expect/expect.dart";
+
+class A {
+  var field;
+  start() {}
+  stop() {
+    field = 42;
+  }
+}
+
+class B {
+  var totalCompileTime = new A();
+  var runCompiler = new Object();
+
+  run() {
+    totalCompileTime.start();
+    try {
+      throw 'foo';
+    } catch (exception) {
+      try {
+        // Use [runCompiler] twice to ensure it will have a local
+        // variable.
+        runCompiler.toString();
+        runCompiler.toString();
+      } catch (exception) {}
+      rethrow;
+    } finally {
+      totalCompileTime.stop();
+    }
+  }
+}
+
+main() {
+  var b = new B();
+  try {
+    b.run();
+    throw 'Expected exception';
+  } catch (exception) {
+    // Expected exception.
+  }
+
+  Expect.equals(42, b.totalCompileTime.field);
+}
diff --git a/tests/language/exception/finally12_test.dart b/tests/language/exception/finally12_test.dart
new file mode 100644
index 0000000..e4f56a0
--- /dev/null
+++ b/tests/language/exception/finally12_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a nested try block.
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo() {
+  var b = a == 8; // This should not be GVN'ed.
+  while (!b) {
+    try {
+      try {} finally {
+        a = 8;
+        break;
+      }
+    } finally {
+      return a == 8;
+    }
+  }
+}
+
+main() {
+  Expect.isTrue(foo());
+}
diff --git a/tests/language/exception/finally1_test.dart b/tests/language/exception/finally1_test.dart
new file mode 100644
index 0000000..0e8510a
--- /dev/null
+++ b/tests/language/exception/finally1_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      int j;
+      j = func();
+      i = 1;
+      return i; // Value of i on return is 1.
+    } finally {
+      i = i + 800; // Should get executed on return.
+    }
+    return i + 200; // Should not get executed.
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally1Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.f1());
+    Expect.equals(801, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally1Test.testMain();
+}
diff --git a/tests/language/exception/finally2_test.dart b/tests/language/exception/finally2_test.dart
new file mode 100644
index 0000000..fd64f69
--- /dev/null
+++ b/tests/language/exception/finally2_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      int j;
+      j = func();
+      try {
+        i = 1;
+        return i; // Value of i is 1 on return.
+      } finally {
+        i = i + 400; // Should get executed when we return.
+      }
+      i = 2; // Should not get executed.
+      return i;
+    } finally {
+      i = i + 800; // Should get executed when we return.
+    }
+    return i + 200; // Should not get executed.
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally2Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.f1());
+    Expect.equals(1201, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally2Test.testMain();
+}
diff --git a/tests/language/exception/finally3_test.dart b/tests/language/exception/finally3_test.dart
new file mode 100644
index 0000000..c36ba0f
--- /dev/null
+++ b/tests/language/exception/finally3_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      try {
+        int j;
+        j = func();
+        L1:
+        while (i <= 0) {
+          if (i == 0) {
+            try {
+              i = 1;
+              func();
+              try {
+                int j;
+                j = func();
+                while (j < 50) {
+                  j += func();
+                  if (j > 30) {
+                    continue L1; // Break out of nested try blocks.
+                  }
+                }
+                i = 200000; // Should not get executed.
+              } finally {
+                i = i + 200; // Should get executed when we break out.
+              }
+            } finally {
+              i = i + 400; // Should get executed when we break out.
+            }
+          }
+        }
+      } finally {
+        i = i + 800; // Should get executed as normal control flow.
+      }
+      return i; // Value of i should be 1401.
+    } finally {
+      i = i + 1600; // Should get executed as part of return above.
+    }
+    i = i + 2000000; // Should not get executed.
+    return 1;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally3Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1401, obj.f1());
+    Expect.equals(3001, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally3Test.testMain();
+}
diff --git a/tests/language/exception/finally4_test.dart b/tests/language/exception/finally4_test.dart
new file mode 100644
index 0000000..fcc308c
--- /dev/null
+++ b/tests/language/exception/finally4_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      int j;
+      j = func();
+      i = 1;
+    } finally {
+      i = i + 10;
+    }
+    return i + 200; // Should return here with i = 211.
+    try {
+      int j;
+      j = func();
+    } finally {
+      i = i + 10; // Should not get executed as part of return above.
+    }
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally4Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(211, obj.f1());
+    Expect.equals(11, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally4Test.testMain();
+}
diff --git a/tests/language/exception/finally5_test.dart b/tests/language/exception/finally5_test.dart
new file mode 100644
index 0000000..09cbdc15
--- /dev/null
+++ b/tests/language/exception/finally5_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1(int param) {
+    if (param == 0) {
+      try {
+        int j;
+        j = func();
+        try {
+          i = 1;
+          return i; // Value of i is 1 on return.
+        } finally {
+          i = i + 400; // Should get executed when we return.
+        }
+        i = 2; // Should not get executed.
+        return i;
+      } finally {
+        i = i + 800; // Should get executed when we return.
+      }
+      return i + 200; // Should not get executed.
+    }
+    try {
+      int j;
+      j = func();
+      try {
+        i = 4;
+        return i; // Value of i is 1 on return.
+      } finally {
+        i = i + 100; // Should get executed when we return.
+      }
+      i = 2; // Should not get executed.
+      return i;
+    } finally {
+      i = i + 200; // Should get executed when we return.
+    }
+    return i + 200; // Should not get executed.
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally5Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.f1(0));
+    Expect.equals(1201, obj.i);
+    Expect.equals(4, obj.f1(1));
+    Expect.equals(304, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally5Test.testMain();
+}
diff --git a/tests/language/exception/finally6_test.dart b/tests/language/exception/finally6_test.dart
new file mode 100644
index 0000000..e9c5ea5
--- /dev/null
+++ b/tests/language/exception/finally6_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      try {
+        int j;
+        j = func();
+        L1:
+        while (i <= 0) {
+          if (i == 0) {
+            try {
+              i = 1;
+              func();
+              try {
+                int j;
+                j = func();
+                L1:
+                while (j < 50) {
+                  j += func();
+                  if (j > 30) {
+                    break L1; // Break out of nested try blocks.
+                  }
+                }
+                i += 200000; // Should get executed.
+              } finally {
+                i = i + 200; // Should get executed as normal control flow.
+              }
+            } finally {
+              i = i + 400; // Should get executed as normal control flow.
+            }
+          }
+        }
+      } finally {
+        i = i + 800; // Should get executed as normal control flow.
+      }
+      return i; // Value of i should be 201401.
+    } finally {
+      i = i + 1600; // Should get executed as part of return above.
+    }
+    i = i + 2000000; // Should not get executed.
+    return 1;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally6Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(201401, obj.f1());
+    Expect.equals(203001, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally6Test.testMain();
+}
diff --git a/tests/language/exception/finally7_test.dart b/tests/language/exception/finally7_test.dart
new file mode 100644
index 0000000..afa6a67
--- /dev/null
+++ b/tests/language/exception/finally7_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks after an exception
+// is thrown from inside a local function capturing a variable.
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException(String message) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  static int f1(int k) {
+    var b;
+    try {
+      var a = new List<dynamic>.filled(10, null);
+      int i = 0;
+      while (i < 10) {
+        int j = i;
+        a[i] = () {
+          if (j == 5) {
+            throw new MyException("Test for exception being thrown");
+          }
+          k += 10;
+          return j;
+        };
+        if (i == 0) {
+          b = a[i];
+        }
+        i++;
+      }
+      for (int i = 0; i < 10; i++) {
+        a[i]();
+      }
+    } on MyException catch (exception) {
+      k += 100;
+      print(exception.message_);
+      b();
+    } finally {
+      k += 1000;
+      b();
+    }
+    return k;
+  }
+}
+
+class ExecuteFinally7Test {
+  static testMain() {
+    Expect.equals(1171, Helper.f1(1));
+  }
+}
+
+main() {
+  ExecuteFinally7Test.testMain();
+}
diff --git a/tests/language/exception/finally8_test.dart b/tests/language/exception/finally8_test.dart
new file mode 100644
index 0000000..c697eee
--- /dev/null
+++ b/tests/language/exception/finally8_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// This test ensures that the finally block executes correctly when
+// there are throw, break and return statements in the finally block.
+
+import "package:expect/expect.dart";
+
+class Hello {
+  static var sum;
+
+  static foo() {
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } finally {
+      sum += 1;
+      throw 'ball';
+      sum += 1;
+    }
+  }
+
+  static foo1() {
+    bool loop = true;
+    sum = 0;
+    L:
+    while (loop) {
+      try {
+        sum += 1;
+        return 'hi';
+      } finally {
+        sum += 1;
+        break L;
+        sum += 1;
+      }
+    }
+  }
+
+  static foo2() {
+    bool loop = true;
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } finally {
+      sum += 1;
+      return 10;
+      sum += 1;
+    }
+  }
+
+  static foo3() {
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } finally {
+      sum += 1;
+      return 10;
+      sum += 1;
+    }
+  }
+
+  static void main() {
+    foo1();
+    Expect.equals(2, sum);
+    foo2();
+    Expect.equals(2, sum);
+    foo3();
+    Expect.equals(2, sum);
+    try {
+      foo();
+    } catch (e) {}
+    Expect.equals(2, sum);
+  }
+}
+
+main() {
+  Hello.main();
+}
diff --git a/tests/language/exception/finally9_test.dart b/tests/language/exception/finally9_test.dart
new file mode 100644
index 0000000..5513466
--- /dev/null
+++ b/tests/language/exception/finally9_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// This test ensures that the finally block executes correctly when
+// there are throw, break and return statements in the finally block.
+
+import "package:expect/expect.dart";
+
+class Hello {
+  static var sum;
+
+  static foo() {
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } catch (e) {
+      sum += 1;
+      throw 'ball';
+      sum += 1;
+    } finally {
+      sum += 1;
+      throw 'ball';
+      sum += 1;
+    }
+  }
+
+  static foo1() {
+    bool loop = true;
+    sum = 0;
+    L:
+    while (loop) {
+      try {
+        sum += 1;
+        return 'hi';
+      } catch (ex) {
+        sum += 1;
+      } finally {
+        try {
+          L1:
+          while (loop) {
+            sum += 1;
+            break L;
+            sum += 1;
+          }
+        } catch (ex) {
+          sum += 1;
+        } finally {
+          sum += 1;
+        }
+      }
+    }
+  }
+
+  static void main() {
+    foo1();
+    Expect.equals(3, sum);
+    try {
+      foo();
+    } catch (e) {
+      // Ignore.
+    }
+    Expect.equals(2, sum);
+  }
+}
+
+main() {
+  Hello.main();
+}
diff --git a/tests/language/exception/finally_test.dart b/tests/language/exception/finally_test.dart
new file mode 100644
index 0000000..9277416
--- /dev/null
+++ b/tests/language/exception/finally_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test for a bug in dart2js where the update of a field in a try
+// block would not be seen by the finally block. See dartbug.com/5517.
+
+class A {
+  int i;
+  A() : i = 42;
+
+  foo() {
+    bool executedFinally = false;
+    if (i == 42) {
+      try {
+        i = 12;
+      } finally {
+        Expect.equals(12, i);
+        executedFinally = true;
+      }
+    }
+    Expect.isTrue(executedFinally);
+  }
+}
+
+main() {
+  new A().foo();
+}
diff --git a/tests/language/exception/identity_test.dart b/tests/language/exception/identity_test.dart
new file mode 100644
index 0000000..2b16607
--- /dev/null
+++ b/tests/language/exception/identity_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that an object when thrown stays the same.
+
+class A {
+  A();
+}
+
+check(exception) {
+  try {
+    throw exception;
+  } catch (e) {
+    Expect.equals(exception, e);
+  }
+}
+
+main() {
+  check("str");
+  check(new A());
+  check(1);
+  check(1.2);
+}
diff --git a/tests/language/exception/in_increment_test.dart b/tests/language/exception/in_increment_test.dart
new file mode 100644
index 0000000..5e34a60
--- /dev/null
+++ b/tests/language/exception/in_increment_test.dart
@@ -0,0 +1,25 @@
+// 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.
+// Test throws exception in the middle of the increment operation, the setter
+// part of the instance field increment never completes.
+// VMOptions=--optimization-counter-threshold=10
+
+main() {
+  var a = new A();
+  a.field = new A();
+  for (int i = 0; i < 20; i++) {
+    try {
+      a.foo(i);
+    } catch (e) {
+      // Ignore.
+    }
+  }
+}
+
+class A {
+  var field;
+  foo(i) {
+    field++; // throw exception
+  }
+}
diff --git a/tests/language/exception/on_catch_malformed_type_test.dart b/tests/language/exception/on_catch_malformed_type_test.dart
new file mode 100644
index 0000000..8b49027
--- /dev/null
+++ b/tests/language/exception/on_catch_malformed_type_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that malformed types in on-catch are handled correctly, that is,
+// throws a type error in both production and checked mode.
+
+import 'package:expect/expect.dart';
+
+catchUnresolvedBefore() {
+  try {
+    throw "foo";
+    Expect.fail("This code shouldn't be executed");
+  } on String catch (oks) {
+    // This is tested before the catch block below.
+  } on Unavailable catch (ex) { /*@compile-error=unspecified*/
+    Expect.fail("This code shouldn't be executed");
+  }
+}
+
+catchUnresolvedAfter() {
+  Expect.throwsTypeError(() {
+    try {
+      throw "foo";
+      Expect.fail("This code shouldn't be executed");
+    } on Unavailable catch (ex) { /*@compile-error=unspecified*/
+      // This is tested before the catch block below.
+      // In both production and checked mode the test causes a type error.
+    } on String catch (oks) {
+      Expect.fail("This code shouldn't be executed");
+    }
+  });
+}
+
+main() {
+  catchUnresolvedBefore();
+  catchUnresolvedAfter();
+}
diff --git a/tests/language/exception/rethrow_test.dart b/tests/language/exception/rethrow_test.dart
new file mode 100644
index 0000000..0b0d3bc
--- /dev/null
+++ b/tests/language/exception/rethrow_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException();
+}
+
+class OtherException {
+  const OtherException();
+}
+
+class RethrowTest {
+  late MyException currentException;
+
+  void throwException() {
+    currentException = new MyException();
+    throw currentException;
+  }
+
+  void testRethrowPastUncaught() {
+    try {
+      try {
+        try {
+          throwException();
+          Expect.fail("Should have thrown an exception");
+        } catch (e) {
+          Expect.equals(true, identical(e, currentException));
+          rethrow;
+          Expect.fail("Should have thrown an exception");
+        }
+      } on OtherException catch (e) {
+        Expect.fail("Should not have caught OtherException");
+      }
+    } catch (e) {
+      Expect.equals(true, identical(e, currentException));
+    }
+  }
+
+  void testRethrow() {
+    try {
+      try {
+        throwException();
+        Expect.fail("Should have thrown an exception");
+      } catch (e) {
+        Expect.equals(true, identical(e, currentException));
+        rethrow;
+        Expect.fail("Should have thrown an exception");
+      }
+    } catch (e) {
+      Expect.equals(true, identical(e, currentException));
+    }
+  }
+}
+
+main() {
+  RethrowTest t = new RethrowTest();
+  t.testRethrow();
+  t.testRethrowPastUncaught();
+}
diff --git a/tests/language/exception/throw1_test.dart b/tests/language/exception/throw1_test.dart
new file mode 100644
index 0000000..1ae121e
--- /dev/null
+++ b/tests/language/exception/throw1_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException2 implements TestException {
+  const MyException2([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException3 implements TestException {
+  const MyException3([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+      if (j > 0) {
+        throw new MyException2("Test for exception being thrown");
+      }
+    } on MyException3 catch (exception) {
+      i = 100;
+      print(exception.getMessage());
+    } on TestException catch (exception) {
+      i = 50;
+      print(exception.getMessage());
+    } on MyException2 catch (exception) {
+      i = 150;
+      print(exception.getMessage());
+    } on MyException catch (exception) {
+      i = 200;
+      print(exception.getMessage());
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class Throw1Test {
+  static testMain() {
+    Expect.equals(850, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw1Test.testMain();
+}
diff --git a/tests/language/exception/throw2_test.dart b/tests/language/exception/throw2_test.dart
new file mode 100644
index 0000000..eaade24
--- /dev/null
+++ b/tests/language/exception/throw2_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException2 implements TestException {
+  const MyException2([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException3 implements TestException {
+  const MyException3([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+    } on MyException3 catch (exception) {
+      i = 100;
+      print(exception.getMessage());
+    } on MyException2 catch (exception) {
+      try {
+        i = func2();
+        i = 200;
+      } on TestException catch (exception) {
+        i = 50;
+      }
+      print(exception.getMessage());
+    } on MyException catch (exception) {
+      i = func2();
+      print(exception.getMessage());
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    if (i > 0) {
+      throw new MyException2("Test for exception being thrown");
+    }
+    return i;
+  }
+
+  static int func2() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    if (i > 0) {
+      throw new MyException2("Test for exception being thrown");
+    }
+    return i;
+  }
+}
+
+class Throw2Test {
+  static testMain() {
+    Expect.equals(850, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw2Test.testMain();
+}
diff --git a/tests/language/exception/throw3_test.dart b/tests/language/exception/throw3_test.dart
new file mode 100644
index 0000000..1d72345
--- /dev/null
+++ b/tests/language/exception/throw3_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException([String message = ""]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      i = 100;
+      i = func();
+      i = 200;
+    } on MyException catch (exception) {
+      i = 50;
+      print(exception.message_);
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    try {
+      int i = 0;
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException("Test for exception being thrown");
+      }
+    } on MyException catch (ex) {
+      print(ex.message_);
+      rethrow; // Rethrow the exception.
+    }
+    return 10;
+  }
+}
+
+class Throw3Test {
+  static testMain() {
+    Expect.equals(850, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw3Test.testMain();
+}
diff --git a/tests/language/exception/throw4_test.dart b/tests/language/exception/throw4_test.dart
new file mode 100644
index 0000000..6dd2f74
--- /dev/null
+++ b/tests/language/exception/throw4_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+  const MyException1([String message = "1"]) : message_ = message;
+  final String message_;
+}
+
+class MyException2 {
+  const MyException2([String message = "2"]) : message_ = message;
+  final String message_;
+}
+
+class MyException3 {
+  const MyException3([String message = "3"]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    int j = 0;
+    try {
+      j = func();
+    } on MyException3 catch (exception) {
+      i = i + 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = i + 200;
+      print(exception.message_);
+    } on MyException1 catch (exception) {
+      i = i + 100;
+      print(exception.message_);
+    } finally {
+      i = i + 1000;
+    }
+    return i;
+  }
+
+  // No catch in the same function for the type of exception being thrown
+  // in the try block here. We expect the handler if checks to fall thru,
+  // the finally block to run and an implicit rethrow to happen.
+  int func() {
+    i = 0;
+    try {
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException1("Test for MyException1 being thrown");
+      }
+    } on MyException3 catch (exception) {
+      i = 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = 200;
+      print(exception.message_);
+    } finally {
+      i = 800;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class Throw4Test {
+  static testMain() {
+    Expect.equals(1900, new Helper().f1());
+  }
+}
+
+main() {
+  Throw4Test.testMain();
+}
diff --git a/tests/language/exception/throw5_test.dart b/tests/language/exception/throw5_test.dart
new file mode 100644
index 0000000..349ade7
--- /dev/null
+++ b/tests/language/exception/throw5_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+  const MyException1([String message = "1"]) : message_ = message;
+  final String message_;
+}
+
+class MyException2 {
+  const MyException2([String message = "2"]) : message_ = message;
+  final String message_;
+}
+
+class MyException3 {
+  const MyException3([String message = "3"]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+    } on MyException3 catch (exception) {
+      i = 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = 200;
+      print(exception.message_);
+    } on MyException1 catch (exception) {
+      i = 100;
+      print(exception.message_);
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  // No catch in the same function for the type of exception being thrown
+  // in the try block here. We expect the handler if checks to fall thru and
+  // implicit rethrow to happen.
+  static int func() {
+    int i = 0;
+    try {
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException1("Test for MyException1 being thrown");
+      }
+    } on MyException3 catch (exception) {
+      i = 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = 200;
+      print(exception.message_);
+    }
+    return i;
+  }
+}
+
+class Throw5Test {
+  static testMain() {
+    Expect.equals(900, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw5Test.testMain();
+}
diff --git a/tests/language/exception/throw6_test.dart b/tests/language/exception/throw6_test.dart
new file mode 100644
index 0000000..1433467
--- /dev/null
+++ b/tests/language/exception/throw6_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+  const MyException1([String message = "1"]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    int j = 0;
+    try {
+      j = func();
+    } catch (exception) {
+      i = i + 100;
+      print(exception.message_);
+    } finally {
+      i = i + 1000;
+    }
+    return i;
+  }
+
+  // No catch in the same function for the type of exception being thrown
+  // in the try block here. We expect the handler if checks to fall thru,
+  // the finally block to run and an implicit rethrow to happen.
+  int func() {
+    i = 0;
+    try {
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException1("Test for MyException1 being thrown");
+      }
+    } finally {
+      i = 800;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class Throw6Test {
+  static testMain() {
+    Expect.equals(1900, new Helper().f1());
+  }
+}
+
+main() {
+  Throw6Test.testMain();
+}
diff --git a/tests/language/exception/throw8_test.dart b/tests/language/exception/throw8_test.dart
new file mode 100644
index 0000000..de84012
--- /dev/null
+++ b/tests/language/exception/throw8_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+var finallyExecutionCount = 0;
+bar() {
+  try {
+    try {
+      return 499;
+    } catch (e, st) {
+      rethrow;
+    }
+  } finally {
+    finallyExecutionCount++;
+    throw "quit finally with throw";
+  }
+}
+
+main() {
+  bool hasThrown = false;
+  try {
+    bar();
+  } catch (x) {
+    hasThrown = true;
+    Expect.equals(1, finallyExecutionCount);
+  }
+  Expect.isTrue(hasThrown);
+}
diff --git a/tests/language/exception/throw_expr_test.dart b/tests/language/exception/throw_expr_test.dart
new file mode 100644
index 0000000..c1f5044
--- /dev/null
+++ b/tests/language/exception/throw_expr_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program for testing throw expressions.
+
+void test1() {
+  var x = 6;
+  try {
+    throw x = 10;
+    x = 0;
+  } catch (e) {
+    Expect.equals(10, e);
+    Expect.equals(10, x);
+    x = 15;
+  }
+  Expect.equals(15, x);
+  x = 100;
+  try {
+    throw x++;
+    x = 0;
+  } catch (e) {
+    Expect.equals(100, e);
+    Expect.equals(101, x);
+    x = 150;
+  }
+  Expect.equals(150, x);
+}
+
+void test2() {
+  var x = 6;
+  try {
+    throw x + 4;
+  } catch (e) {
+    Expect.equals(10, e);
+    Expect.equals(6, x);
+    x = 15;
+  }
+  Expect.equals(15, x);
+}
+
+foo(x, y) => throw "foo" "$x";
+
+bar(x, y) => throw "foo" "${throw x}";
+
+class Q {
+  var qqq;
+  f(x) {
+    qqq = x;
+  }
+
+  Q get nono => throw "nono";
+}
+
+void test3() {
+  try {
+    throw throw throw "up";
+  } catch (e) {
+    Expect.equals("up", e);
+  }
+
+  dynamic x = 10;
+  try {
+    foo(x = 12, throw 7);
+  } catch (e) {
+    Expect.equals(7, e);
+    Expect.equals(12, x);
+  }
+
+  x = 10;
+  try {
+    foo(x++, 10);
+  } catch (e) {
+    Expect.equals("foo10", e);
+    Expect.equals(11, x);
+  }
+
+  x = 100;
+  try {
+    bar(++x, 10);
+  } catch (e) {
+    Expect.equals(101, e);
+    Expect.equals(101, x);
+  }
+
+  x = null;
+  try {
+    x = new Q();
+    x
+      ..f(11)
+      ..qqq = throw 77
+      ..f(22);
+  } catch (e) {
+    Expect.equals(77, e);
+    Expect.equals(11, x.qqq);
+  }
+}
+
+void test4() {
+  var q = new Q();
+  Expect.throws(() => q.nono, (e) => e == "nono");
+}
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+}
diff --git a/tests/language/exception/throw_test.dart b/tests/language/exception/throw_test.dart
new file mode 100644
index 0000000..0c864cc
--- /dev/null
+++ b/tests/language/exception/throw_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException(String this.message_);
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+      if (j > 0) {
+        throw new MyException("Test for exception being thrown");
+      }
+    } on MyException catch (exception) {
+      i = 100;
+      print(exception.message_);
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class ThrowTest {
+  static testMain() {
+    Expect.equals(900, Helper.f1(1));
+  }
+}
+
+main() {
+  ThrowTest.testMain();
+}
diff --git a/tests/language/exception/try_catch2_test.dart b/tests/language/exception/try_catch2_test.dart
new file mode 100644
index 0000000..8da606c
--- /dev/null
+++ b/tests/language/exception/try_catch2_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown. (Nested try/catch blocks).
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class StackTrace {
+  StackTrace() {}
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = f2();
+      i = i + 1;
+      try {
+        j = f2() + f3() + j;
+        i = i + 1;
+      } on TestException catch (e, trace) {
+        j = 50;
+      }
+      j = f3() + j;
+    } on MyException catch (exception) {
+      i = 100;
+    } on TestException catch (e, trace) {
+      i = 200;
+    }
+    return i;
+  }
+
+  static int f2() {
+    return 2;
+  }
+
+  static int f3() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class TryCatch2Test {
+  static testMain() {
+    Expect.equals(3, Helper.f1(1));
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatch2Test.testMain();
+  }
+}
diff --git a/tests/language/exception/try_catch3_test.dart b/tests/language/exception/try_catch3_test.dart
new file mode 100644
index 0000000..6cff3f8
--- /dev/null
+++ b/tests/language/exception/try_catch3_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : this._message = message;
+  String getMessage() {
+    return _message;
+  }
+
+  final String _message;
+}
+
+class MyParameterizedException<U, V> implements TestException {
+  const MyParameterizedException([String message = ""])
+      : this._message = message;
+  String getMessage() {
+    return _message;
+  }
+
+  final String _message;
+}
+
+class StackTrace {
+  StackTrace() {}
+  printStackTrace(TestException ex) {
+    print(ex);
+  }
+}
+
+class Helper {
+  static int test1(int i) {
+    try {
+      int j;
+      j = f2();
+      j = f3();
+      try {
+        int k = f2();
+        f3();
+      } on MyException catch (ex) {
+        int i = 10;
+        print(i);
+      } on TestException catch (ex) {
+        int k = 10;
+        print(k);
+      }
+      try {
+        j = j + 24;
+      } catch (e) {
+        i = 300;
+        print(e.getMessage());
+      }
+      try {
+        j += 20;
+      } catch (e) {
+        i = 400;
+        print(e.getMessage());
+      }
+      try {
+        j += 40;
+      } catch (e) {
+        i = 600;
+        print(e.getMessage());
+      }
+      try {
+        j += 60;
+      } catch (e, trace) {
+        i = 700;
+        print(trace.toString());
+        print(e.getMessage());
+      }
+      try {
+        j += 80;
+      } on MyException catch (e) {
+        i = 500;
+        print(e.getMessage());
+      }
+    } on MyParameterizedException<String, TestException> catch (e, trace) {
+      i = 800;
+      print(trace.toString());
+      rethrow;
+    } on MyException catch (exception) {
+      i = 100;
+      print(exception.getMessage());
+    } on TestException catch (e, trace) {
+      i = 200;
+      print(trace.toString());
+    } finally {
+      i = 900;
+    }
+    return i;
+  }
+
+  static int f2() {
+    return 2;
+  }
+
+  static int f3() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class TryCatchTest {
+  static testMain() {
+    Expect.equals(900, Helper.test1(1));
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatchTest.testMain();
+  }
+}
diff --git a/tests/language/exception/try_catch4_test.dart b/tests/language/exception/try_catch4_test.dart
new file mode 100644
index 0000000..a6cbe03
--- /dev/null
+++ b/tests/language/exception/try_catch4_test.dart
@@ -0,0 +1,206 @@
+// 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.
+// Check that our SSA graph does have the try body a predecessor of a
+// try/finally.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo1() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      return false;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+doThrow() {
+  throw 2;
+}
+
+foo2() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      doThrow();
+      return false;
+    } catch (e) {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo3() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      doThrow();
+    } catch (e) {
+      a = 8;
+      entered = true;
+      return false;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo4() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      break;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo5() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      doThrow();
+      break;
+    } catch (e) {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo6() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      doThrow();
+    } catch (e) {
+      a = 8;
+      entered = true;
+      break;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo7() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      continue;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo8() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      doThrow();
+      continue;
+    } catch (e) {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo9() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      doThrow();
+    } catch (e) {
+      a = 8;
+      entered = true;
+      continue;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+main_test() {
+  a = 0;
+  Expect.isTrue(foo1());
+  a = 0;
+  Expect.isTrue(foo2());
+  a = 0;
+  Expect.isTrue(foo3());
+  a = 0;
+  Expect.isTrue(foo4());
+  a = 0;
+  Expect.isTrue(foo5());
+  a = 0;
+  Expect.isTrue(foo6());
+  a = 0;
+  Expect.isTrue(foo7());
+  a = 0;
+  Expect.isTrue(foo8());
+  a = 0;
+  Expect.isTrue(foo9());
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    main_test();
+  }
+}
diff --git a/tests/language/exception/try_catch5_test.dart b/tests/language/exception/try_catch5_test.dart
new file mode 100644
index 0000000..6920b06
--- /dev/null
+++ b/tests/language/exception/try_catch5_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that our SSA graph does have the try body a predecessor of a
+// try/finally.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo1() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      try {
+        a = 8;
+        return false;
+      } finally {
+        b = 8 == a;
+        entered = true;
+        continue;
+      }
+    } finally {
+      continue;
+    }
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    a = 0;
+    Expect.isTrue(foo1());
+  }
+}
diff --git a/tests/language/exception/try_catch_on_syntax_test.dart b/tests/language/exception/try_catch_on_syntax_test.dart
new file mode 100644
index 0000000..c19a94f
--- /dev/null
+++ b/tests/language/exception/try_catch_on_syntax_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+void test1() {
+  var foo = 0;
+  try {
+    throw new MyException1();
+  }
+  on on MyException2 catch (e) { } //# 02: syntax error
+  catch MyException2 catch (e) { } //# 03: syntax error
+  catch catch catch (e) { } //# 04: syntax error
+  on (e) { } //# 05: syntax error
+  catch MyException2 catch (e) { } //# 06: syntax error
+  on MyException2 catch (e) {
+    foo = 1;
+  } on MyException1 catch (e) {
+    foo = 2;
+  } on MyException catch (e) {
+    foo = 3;
+  }
+  on UndefinedClass //# 07: compile-time error
+  catch (e) {
+    foo = 4;
+  }
+  Expect.equals(2, foo);
+}
+
+testFinal() {
+  try {
+    throw "catch this!";
+  } catch (e, s) {
+    // Test that the error and stack trace variables are final.
+      e = null; // //# 10: compile-time error
+      s = null; // //# 11: compile-time error
+  }
+}
+
+main() {
+  test1();
+  testFinal();
+}
diff --git a/tests/language/exception/try_catch_optimized1_test.dart b/tests/language/exception/try_catch_optimized1_test.dart
new file mode 100644
index 0000000..c3b522a
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized1_test.dart
@@ -0,0 +1,290 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+maythrow(x) {
+  if (x == null) throw 42;
+  return 99;
+}
+
+f1(x) {
+  var result = 123;
+  try {
+    result = maythrow(x);
+    if (result > 100) throw 42;
+  } catch (e) {
+    Expect.equals(result, 123);
+    Expect.equals(42, e);
+    result = 0;
+  }
+  return result;
+}
+
+class A {
+  maythrow(x) {
+    if (x == null) throw 42;
+    return 99;
+  }
+}
+
+f2(x) {
+  dynamic result = 123;
+  var a = new A();
+  try {
+    result++;
+    result = a.maythrow(x);
+  } catch (e) {
+    Expect.equals(124, result);
+    result = x;
+  }
+  return result;
+}
+
+f3(x, y) {
+  var result = 123;
+  var a = new A();
+  try {
+    result++;
+    result = a.maythrow(x);
+  } catch (e) {
+    result = y + 1; // Deopt on overflow
+  }
+  return result;
+}
+
+f4(x) {
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f4(e, "abc");
+  }
+}
+
+check_f4(e, s) {
+  if (e != 42) throw "ERROR";
+  if (s != "abc") throw "ERROR";
+}
+
+f5(x) {
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f5(e, "abc");
+  }
+
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f5(e, "abc");
+  }
+}
+
+check_f5(e, s) {
+  if (e != 42) throw "ERROR";
+  if (s != "abc") throw "ERROR";
+}
+
+f6(x, y) {
+  var a = x;
+  var b = y;
+  var c = 123;
+  check_f6(42, null, 1, 123, null, 1);
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f6(e, a, b, c, x, y);
+  }
+}
+
+check_f6(e, a, b, c, x, y) {
+  if (e != 42) throw "ERROR";
+  if (a != null) throw "ERROR";
+  if (b != 1) throw "ERROR";
+  if (c != 123) throw "ERROR";
+  if (x != null) throw "ERROR";
+  if (y != 1) throw "ERROR";
+}
+
+bool f7(String str) {
+  double d = double.parse(str);
+  var t = d;
+  try {
+    var a = d.toInt();
+    return false;
+  } on UnsupportedError catch (e) {
+    Expect.equals(true, identical(t, d));
+    return true;
+  }
+}
+
+f8(x, [a = 3, b = 4]) {
+  var c = 123;
+  var y = a;
+  try {
+    maythrow(x);
+  } catch (e, s) {
+    check_f8(e, s, a, b, c, x, y);
+  }
+}
+
+check_f8(e, s, a, b, c, x, y) {
+  if (e != 42) throw "ERROR";
+  if (s is! StackTrace) throw "ERROR";
+  if (a != 3) {
+    print(a);
+    throw "ERROR";
+  }
+  if (b != 4) throw "ERROR";
+  if (c != 123) throw "ERROR";
+  if (x != null) throw "ERROR";
+  if (y != a) throw "ERROR";
+}
+
+f9(x, [a = 3, b = 4]) {
+  var c = 123;
+  var y = a;
+  try {
+    if (x < a) maythrow(null);
+    maythrow(x);
+  } catch (e, s) {
+    check_f9(e, s, a, b, c, x, y);
+  }
+}
+
+check_f9(e, s, a, b, c, x, y) {
+  if (e != 42) throw "ERROR";
+  if (s is! StackTrace) throw "ERROR";
+  if (a != 3) {
+    print(a);
+    throw "ERROR";
+  }
+  if (b != 4) throw "ERROR";
+  if (c != 123) throw "ERROR";
+  if (x != null) throw "ERROR";
+  if (y != a) throw "ERROR";
+}
+
+f10(x, y) {
+  var result = 123;
+  try {
+    result = maythrow(x);
+  } catch (e) {
+    Expect.equals(123, result);
+    Expect.equals(0.5, y / 2.0);
+    result = 0;
+  }
+  return result;
+}
+
+f11(x) {
+  var result = 123;
+  var tmp = x;
+  try {
+    result = maythrow(x);
+    if (result > 100) throw 42;
+  } catch (e, s) {
+    Expect.equals(123, result);
+    Expect.equals(true, identical(tmp, x));
+    Expect.equals(true, s is StackTrace);
+    result = 0;
+  }
+  return result;
+}
+
+f12([x = null]) {
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f12(e, x);
+  }
+}
+
+check_f12(e, x) {
+  if (e != 42) throw "ERROR";
+  if (x != null) throw "ERROR";
+}
+
+f13(x) {
+  var result = 123;
+  try {
+    try {
+      result = maythrow(x);
+      if (result > 100) throw 42;
+    } catch (e) {
+      Expect.equals(123, result);
+      result = 0;
+    }
+    maythrow(x);
+  } catch (e) {
+    result++;
+  }
+  return result;
+}
+
+main() {
+  for (var i = 0; i < 20; i++) f1("abc");
+  Expect.equals(99, f1("abc"));
+  Expect.equals(0, f1(null));
+
+  for (var i = 0; i < 20; i++) f2("abc");
+  Expect.equals(99, f2("abc"));
+  Expect.equals(null, f2(null));
+
+  f3("123", 0);
+  for (var i = 0; i < 20; i++) f3(null, 0);
+  Expect.equals(99, f3("123", 0));
+  Expect.equals(0x40000000, f3(null, 0x3fffffff));
+
+  f4(null);
+  for (var i = 0; i < 20; i++) f4(123);
+  f4(null);
+
+  f5(null);
+  for (var i = 0; i < 20; i++) f5(123);
+  f5(null);
+
+  f6(null, 1);
+  for (var i = 0; i < 20; i++) f6(123, 1);
+  f6(null, 1);
+
+  f7("1.2");
+  f7("Infinity");
+  f7("-Infinity");
+  for (var i = 0; i < 20; i++) f7("1.2");
+  Expect.equals(false, f7("1.2"));
+  Expect.equals(true, f7("Infinity"));
+  Expect.equals(true, f7("-Infinity"));
+  Expect.equals(false, f7("123456789012345")); // Deopt.
+  for (var i = 0; i < 20; i++) f7("123456789012345");
+  Expect.equals(true, f7("Infinity"));
+  Expect.equals(true, f7("-Infinity"));
+
+  for (var i = 0; i < 20; i++) f8(null);
+  f8(null);
+
+  f9(5);
+  f9(5.0);
+  for (var i = 0; i < 20; i++) f9(3);
+  f9(3);
+
+  var y = 1.0;
+  Expect.equals(0, f10(null, y));
+  for (var i = 0; i < 20; i++) f10("abc", y);
+  Expect.equals(99, f10("abc", y));
+  Expect.equals(0, f10(null, y));
+
+  for (var i = 0; i < 20; i++) f11("abc");
+  Expect.equals(99, f11("abc"));
+  Expect.equals(0, f11(null));
+
+  for (var i = 0; i < 20; i++) f12(null);
+  f12(null);
+
+  f13(null);
+  for (var i = 0; i < 20; i++) f13("abc");
+  Expect.equals(99, f13("abc"));
+  Expect.equals(1, f13(null));
+}
diff --git a/tests/language/exception/try_catch_optimized2_test.dart b/tests/language/exception/try_catch_optimized2_test.dart
new file mode 100644
index 0000000..159a6e5
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized2_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test allocation sinking with optimized try-catch.
+
+bar() {
+  // Should not be inlined.
+  try {} finally {}
+}
+
+foo(List<int> a) {
+  var r = 0;
+  for (var i in a) {
+    r += i;
+  }
+  try {
+    bar();
+  } finally {}
+  return r;
+}
+
+main() {
+  var a = [1, 2, 3];
+  for (var i = 0; i < 20; i++) foo(a);
+  Expect.equals(6, foo(a));
+}
diff --git a/tests/language/exception/try_catch_optimized3_test.dart b/tests/language/exception/try_catch_optimized3_test.dart
new file mode 100644
index 0000000..a2b03fc
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized3_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test unboxed double operations inside try-catch.
+foo(bool b) {
+  if (b) throw 123;
+}
+
+test_double(double x, bool b) {
+  try {
+    x += 1.0;
+    foo(b);
+  } catch (e) {
+    var result = x - 1.0;
+    Expect.equals(1.0, result);
+    return result;
+  }
+}
+
+main() {
+  for (var i = 0; i < 100; i++) test_double(1.0, false);
+  test_double(1.0, false);
+  Expect.equals(1.0, test_double(1.0, true));
+}
diff --git a/tests/language/exception/try_catch_optimized4_test.dart b/tests/language/exception/try_catch_optimized4_test.dart
new file mode 100644
index 0000000..dc98f31
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized4_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test correct dead phi elimination with try catch.
+
+List<Object> a = [1, 2, 3, 4, 5];
+
+class MyError {}
+
+class M {
+  maythrow(i) {
+    try {
+      if (i <= 5) throw new MyError();
+    } catch (e) {
+      throw e;
+    }
+  }
+}
+
+loop_test() {
+  bool failed = false;
+  M m = new M();
+  for (Object i in a) {
+    try {
+      String res = m.maythrow(i);
+      failed = true;
+    } on MyError catch (e) {}
+    if (!identical(failed, false)) {
+      Expect.fail("");
+    }
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) loop_test();
+}
diff --git a/tests/language/exception/try_catch_optimized5_test.dart b/tests/language/exception/try_catch_optimized5_test.dart
new file mode 100644
index 0000000..a3b7b99
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized5_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
+
+// Test optional parameters updated inside try-catch
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+m1(int b) {
+  if (b == 1) throw 123;
+}
+
+@pragma('vm:never-inline')
+m2(int b) {
+  if (b == 2) throw 456;
+}
+
+@pragma('vm:never-inline')
+test1(int b, [int state = 0]) {
+  try {
+    state++;
+    m1(b);
+    state++;
+    m2(b);
+    state++;
+  } catch (e, s) {
+    if (b == 1 && state != 1) throw "fail1";
+    if (b == 2 && state != 2) throw "fail2";
+    if (b == 3 && state != 3) throw "fail3";
+    if (s is! StackTrace) throw "fail4";
+    return e;
+  }
+  return "no throw";
+}
+
+@pragma('vm:never-inline')
+test2(int b, [int state = -1]) {
+  state = 0;
+  try {
+    state++;
+    m1(b);
+    state++;
+    m2(b);
+    state++;
+  } catch (e, s) {
+    if (b == 1 && state != 1) throw "fail1";
+    if (b == 2 && state != 2) throw "fail2";
+    if (b == 3 && state != 3) throw "fail3";
+    if (s is! StackTrace) throw "fail4";
+    return e;
+  }
+  return "no throw";
+}
+
+main() {
+  for (var i = 0; i < 300; i++) {
+    Expect.equals("no throw", test1(0));
+  }
+  Expect.equals("no throw", test1(0));
+  Expect.equals(123, test1(1));
+  Expect.equals(456, test1(2));
+
+  for (var i = 0; i < 300; i++) {
+    Expect.equals("no throw", test2(0));
+  }
+  Expect.equals("no throw", test2(0));
+  Expect.equals(123, test2(1));
+  Expect.equals(456, test2(2));
+}
diff --git a/tests/language/exception/try_catch_osr_test.dart b/tests/language/exception/try_catch_osr_test.dart
new file mode 100644
index 0000000..345f764
--- /dev/null
+++ b/tests/language/exception/try_catch_osr_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Test OSR in different places of a try-catch.
+
+import "package:expect/expect.dart";
+
+maythrow(x) {
+  try {
+    if (x == null) throw 42;
+    return 99;
+  } finally {}
+}
+
+f1() {
+  var s = 0, t = "abc";
+  for (var i = 0; i < 21; ++i) {
+    s += i;
+  }
+  try {
+    maythrow(null);
+  } catch (e) {
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    s++;
+  }
+  return s;
+}
+
+f2([int x = 1]) {
+  var s = 0;
+  var t = "abc";
+  try {
+    try {
+      for (var i = 0; i < 20; ++i) {
+        if (i == 18) maythrow(null);
+        s += x;
+      }
+    } catch (e) {
+      Expect.equals(1, x);
+      Expect.equals("abc", t);
+      Expect.equals(42, e);
+      s++;
+    }
+  } catch (e) {}
+  return s;
+}
+
+f3() {
+  var s = 0, t = "abc";
+  try {
+    maythrow(null);
+  } catch (e) {
+    Expect.equals("abc", t);
+    for (var i = 0; i < 21; ++i) {
+      s += i;
+    }
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    return s;
+  }
+}
+
+f4() {
+  var s = 0, t = "abc";
+  try {
+    for (var i = 0; i < 21; ++i) {
+      if (i == 18) maythrow(null);
+      s += i;
+    }
+  } catch (e) {
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    s++;
+  }
+  return s;
+}
+
+f5() {
+  var s, t = "abc";
+  try {
+    maythrow(null);
+  } catch (e) {
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    s = 0;
+  }
+  for (var i = 0; i < 21; ++i) {
+    s += i;
+  }
+  Expect.equals("abc", t);
+  return s;
+}
+
+main() {
+  Expect.equals(211, f1());
+  Expect.equals(19, f2());
+  Expect.equals(210, f3());
+  Expect.equals(9 * 17 + 1, f4());
+  Expect.equals(210, f5());
+}
diff --git a/tests/language/exception/try_catch_regress_27483_test.dart b/tests/language/exception/try_catch_regress_27483_test.dart
new file mode 100644
index 0000000..dde7246
--- /dev/null
+++ b/tests/language/exception/try_catch_regress_27483_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
+
+// Test local variables updated inside try-catch.
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+m1(int b) {
+  if (b == 1) throw 123;
+}
+
+@pragma('vm:never-inline')
+m2(int b) {
+  if (b == 2) throw 456;
+}
+
+@pragma('vm:never-inline')
+test(b) {
+  var state = 0;
+  try {
+    state++;
+    m1(b);
+    state++;
+    m2(b);
+    state++;
+  } catch (e, s) {
+    if (b == 1 && state != 1) throw "fail1";
+    if (b == 2 && state != 2) throw "fail2";
+    if (b == 3 && state != 3) throw "fail3";
+    return e;
+  }
+  return "no throw";
+}
+
+main() {
+  for (var i = 0; i < 300; i++) {
+    Expect.equals("no throw", test(0));
+  }
+  Expect.equals("no throw", test(0));
+  Expect.equals(123, test(1));
+  Expect.equals(456, test(2));
+}
diff --git a/tests/language/exception/try_catch_runtime_test.dart b/tests/language/exception/try_catch_runtime_test.dart
new file mode 100644
index 0000000..872f9d7
--- /dev/null
+++ b/tests/language/exception/try_catch_runtime_test.dart
@@ -0,0 +1,199 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+class TryCatchTest {
+  static void test1() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test2() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException catch (e) {
+      foo = 2;
+    } on MyException1 catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test3() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test4() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } on MyException catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test5() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } catch (e) {
+      foo = 2;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test6() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test7() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test8() {
+    var e = 3;
+    var caught = false;
+    try {
+      throw new MyException();
+    } catch (exc) {
+      caught = true;
+    }
+    Expect.equals(true, caught);
+    Expect.equals(3, e);
+  }
+
+  static void test9() {
+    dynamic e = 6;
+    try {
+      throw "up";
+    } on String {
+      e = "s";
+    } on int {
+      e = "i";
+    }
+    Expect.equals("s", e);
+  }
+
+  static void test10() {
+    try {
+      throw "up";
+    } on String catch (e) {
+      var e = 1; // ok, shadows exception variable.
+      Expect.equals(1, e);
+    }
+  }
+
+  static void test11() {
+    var e0 = 11;
+    try {
+      throw "up";
+    } on int catch (e0) {
+      Expect.fail("unreachable");
+    } on String catch (e1) {
+      // e0 from the other catch clause is not in scope.
+      Expect.equals(11, e0);
+    }
+  }
+
+  static void test12() {
+    const x = const [];
+    try {
+      throw "up";
+    } catch (e) {
+      Expect.equals("up", e);
+    } on String catch (e) {
+      // Compile-time constants in unreachable catch blocks are still
+      // compiled.
+
+      Expect.fail("unreachable");
+    }
+  }
+
+  static void testMain() {
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    test12();
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatchTest.testMain();
+  }
+}
diff --git a/tests/language/exception/try_catch_syntax_test.dart b/tests/language/exception/try_catch_syntax_test.dart
new file mode 100644
index 0000000..5a192d1
--- /dev/null
+++ b/tests/language/exception/try_catch_syntax_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+main() {
+  testMissingCatch();
+  testMissingTry();
+  testDuplicateCatchVariable();
+  testIllegalFinally();
+  testIllegalCatch();
+  testIllegalRethrow();
+}
+
+testMissingCatch() {
+  try { } // //# 01: syntax error
+}
+
+testMissingTry() {
+  on Exception catch (e) { } //                  //# 02: syntax error
+  on Exception catch (e, trace) { } //           //# 03: syntax error
+  finally { } //                                 //# 04: syntax error
+}
+
+testDuplicateCatchVariable() {
+  try { } on Exception catch (e, e) { } //# 05: compile-time error
+}
+
+testIllegalFinally() {
+  try { } finally (e) { } //# 06: syntax error
+}
+
+testIllegalCatch() {
+  try { } catch () { } //             //# 07: syntax error
+  try { } on MammaMia catch (e) { } //# 08: compile-time error
+  try { } catch (var e) { } //        //# 09: syntax error
+  try { } catch (final e) { } //      //# 10: syntax error
+  try { } catch (int e) { } //        //# 11: syntax error
+  try { } catch (final int e) { } //  //# 12: syntax error
+  try { } catch ([e, s]) { } //       //# 13: syntax error
+  try { } catch (e, [s]) { } //       //# 14: syntax error
+  try { } catch (e, [s0, s1]) { } //  //# 15: syntax error
+}
+
+testIllegalRethrow() {
+  try { rethrow; } catch (e) { } //            //# 16: compile-time error
+  try { } catch (e) { } finally { rethrow; } //# 17: compile-time error
+}
diff --git a/tests/language/exception/try_catch_test.dart b/tests/language/exception/try_catch_test.dart
new file mode 100644
index 0000000..2b8fee2
--- /dev/null
+++ b/tests/language/exception/try_catch_test.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+class TryCatchTest {
+  static void test1() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test2() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException catch (e) {
+      foo = 2;
+    } on MyException1 catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test3() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test4() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } on MyException catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test5() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } catch (e) {
+      foo = 2;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test6() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test7() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test8() {
+    var e = 3;
+    var caught = false;
+    try {
+      throw new MyException();
+    } catch (exc) {
+      caught = true;
+    }
+    Expect.equals(true, caught);
+    Expect.equals(3, e);
+  }
+
+  static void test9() {
+    dynamic e = 6;
+    try {
+      throw "up";
+    } on String {
+      e = "s";
+    } on int {
+      e = "i";
+    }
+    Expect.equals("s", e);
+  }
+
+  static void test10() {
+    try {
+      throw "up";
+    } on String catch (e) {
+      var e = 1; // ok, shadows exception variable.
+      Expect.equals(1, e);
+    }
+  }
+
+  static void test11() {
+    var e0 = 11;
+    try {
+      throw "up";
+    } on int catch (e0) {
+      Expect.fail("unreachable");
+    } on String catch (e1) {
+      // e0 from the other catch clause is not in scope.
+      Expect.equals(11, e0);
+    }
+  }
+
+  static void test12() {
+    const x = const [];
+    try {
+      throw "up";
+    } catch (e) {
+      Expect.equals("up", e);
+    } on String catch (e) {
+      // Compile-time constants in unreachable catch blocks are still
+      // compiled.
+      const y = x[0];
+      //        ^^^^
+      // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+      //         ^
+      // [cfe] Constant evaluation error:
+      Expect.fail("unreachable");
+    }
+  }
+
+  static void testMain() {
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    test12();
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatchTest.testMain();
+  }
+}
diff --git a/tests/language/exception/try_finally_regress_25333_test.dart b/tests/language/exception/try_finally_regress_25333_test.dart
new file mode 100644
index 0000000..6318f7c
--- /dev/null
+++ b/tests/language/exception/try_finally_regress_25333_test.dart
@@ -0,0 +1,64 @@
+// 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.
+
+// Test correct handling of try-catch inside try-finally.
+
+import "package:expect/expect.dart";
+
+void main() {
+  print("== test1 ==");
+  bool caught = false;
+  try {
+    test1();
+    print("Unexpected 1"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 1: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+  print("== test2 ==");
+  caught = false;
+  try {
+    test2();
+    print("Unexpected 2"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 2: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+}
+
+void test1() {
+  try {
+    throw "Ball";
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch (e) {
+      print("test 1 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+void test2() {
+  try {
+    throwError(); // call a method that throws an error
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch (e) {
+      print("test 2 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+void throwError() {
+  throw "Ball";
+}
diff --git a/tests/language/exception/try_finally_regress_25654_test.dart b/tests/language/exception/try_finally_regress_25654_test.dart
new file mode 100644
index 0000000..32a236f
--- /dev/null
+++ b/tests/language/exception/try_finally_regress_25654_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// Test break out of try-finally.
+
+import "package:expect/expect.dart";
+
+var count = 0;
+
+test() {
+  L:
+  while (true) {
+    try {
+      break L;
+    } finally {
+      count++;
+    }
+  }
+  throw "ex";
+}
+
+main() {
+  bool caught = false;
+  try {
+    test();
+  } catch (e) {
+    caught = true;
+    Expect.equals(e, "ex");
+  }
+  Expect.isTrue(caught);
+  Expect.equals(1, count);
+}
diff --git a/tests/language/export/ambiguous_main_a.dart b/tests/language/export/ambiguous_main_a.dart
new file mode 100644
index 0000000..4a7b820
--- /dev/null
+++ b/tests/language/export/ambiguous_main_a.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library export_ambiguous_main_a;
+
+main() {
+  print('export_ambiguous_main_a');
+}
diff --git a/tests/language/export/ambiguous_main_b.dart b/tests/language/export/ambiguous_main_b.dart
new file mode 100644
index 0000000..734a620
--- /dev/null
+++ b/tests/language/export/ambiguous_main_b.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library export_ambiguous_main_b;
+
+main() {
+  print('export_ambiguous_main_b');
+}
diff --git a/tests/language/export/ambiguous_main_test.dart b/tests/language/export/ambiguous_main_test.dart
new file mode 100644
index 0000000..b2a8a24
--- /dev/null
+++ b/tests/language/export/ambiguous_main_test.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'ambiguous_main_a.dart';
+export 'ambiguous_main_b.dart'; /*@compile-error=unspecified*/
diff --git a/tests/language/export/cyclic_helper1.dart b/tests/language/export/cyclic_helper1.dart
new file mode 100644
index 0000000..7e42191
--- /dev/null
+++ b/tests/language/export/cyclic_helper1.dart
@@ -0,0 +1,15 @@
+// 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.
+
+library export_cyclic_helper1;
+
+import 'cyclic_helper2.dart';
+export 'cyclic_helper2.dart';
+
+class B {
+  A? a;
+  B? b;
+  C? c;
+  D? d;
+}
diff --git a/tests/language/export/cyclic_helper2.dart b/tests/language/export/cyclic_helper2.dart
new file mode 100644
index 0000000..d18256c
--- /dev/null
+++ b/tests/language/export/cyclic_helper2.dart
@@ -0,0 +1,17 @@
+// 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.
+
+library export_cyclic_helper2;
+
+import 'cyclic_test.dart';
+import 'cyclic_helper3.dart';
+export 'cyclic_test.dart';
+export 'cyclic_helper3.dart';
+
+class C {
+  A? a;
+  B? b;
+  C? c;
+  D? d;
+}
diff --git a/tests/language/export/cyclic_helper3.dart b/tests/language/export/cyclic_helper3.dart
new file mode 100644
index 0000000..17b9ff9
--- /dev/null
+++ b/tests/language/export/cyclic_helper3.dart
@@ -0,0 +1,7 @@
+// 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.
+
+library export_cyclic_helper3;
+
+class D {}
diff --git a/tests/language/export/cyclic_test.dart b/tests/language/export/cyclic_test.dart
new file mode 100644
index 0000000..d854a39
--- /dev/null
+++ b/tests/language/export/cyclic_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+// Test cyclic export and re-export.
+
+/**
+ * export_cyclic_test re-exports export_cyclic_helper1 which declares B
+ * export_cyclic_helper1 re-exports export_cyclic_helper2 which declares C
+ * export_cyclic_helper2 re-exports export_cyclic_test which declares A
+ * export_cyclic_helper2 re-exports export_cyclic_helper3 which declares D
+ */
+
+library export_cyclic_test;
+
+import 'cyclic_helper1.dart';
+export 'cyclic_helper1.dart';
+
+class A {}
+
+void main() {
+  print(new A());
+  print(new B());
+  print(new C());
+  print(new D());
+}
diff --git a/tests/language/export/double_same_main_test.dart b/tests/language/export/double_same_main_test.dart
new file mode 100644
index 0000000..8923855
--- /dev/null
+++ b/tests/language/export/double_same_main_test.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'top_level_entry_test.dart';
+export 'main_test.dart' show main;
diff --git a/tests/language/export/duplicate_collision_test.dart b/tests/language/export/duplicate_collision_test.dart
new file mode 100644
index 0000000..5948d9b
--- /dev/null
+++ b/tests/language/export/duplicate_collision_test.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'duplicate_import_libd.dart'; //# 01: compile-time error
+
+void main() {}
diff --git a/tests/language/export/duplicate_export_test.dart b/tests/language/export/duplicate_export_test.dart
new file mode 100644
index 0000000..75f8a82
--- /dev/null
+++ b/tests/language/export/duplicate_export_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that it is not a compile-time error to reexport the same elements
+// through different paths.
+
+library duplicate_export_test;
+
+export 'duplicate_import_liba.dart';
+export 'duplicate_liba.dart'; // reexports 'duplicate_import_liba.dart'.
+
+void main() {}
diff --git a/tests/language/export/duplicate_import_liba.dart b/tests/language/export/duplicate_import_liba.dart
new file mode 100644
index 0000000..b8af1a7
--- /dev/null
+++ b/tests/language/export/duplicate_import_liba.dart
@@ -0,0 +1,13 @@
+// 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.
+
+library liba;
+
+var field;
+
+void method() {}
+
+class Class {}
+
+void methodOrClass() {}
diff --git a/tests/language/export/duplicate_import_libb.dart b/tests/language/export/duplicate_import_libb.dart
new file mode 100644
index 0000000..456147f
--- /dev/null
+++ b/tests/language/export/duplicate_import_libb.dart
@@ -0,0 +1,13 @@
+// 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.
+
+library libb;
+
+var field;
+
+void method() {}
+
+class Class {}
+
+class methodOrClass {}
diff --git a/tests/language/export/duplicate_import_libc.dart b/tests/language/export/duplicate_import_libc.dart
new file mode 100644
index 0000000..d1f1b41
--- /dev/null
+++ b/tests/language/export/duplicate_import_libc.dart
@@ -0,0 +1,11 @@
+// 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.
+
+library libc;
+
+var field;
+
+void method() {}
+
+class Class {}
diff --git a/tests/language/export/duplicate_import_libd.dart b/tests/language/export/duplicate_import_libd.dart
new file mode 100644
index 0000000..14f1ff4
--- /dev/null
+++ b/tests/language/export/duplicate_import_libd.dart
@@ -0,0 +1,13 @@
+// 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.
+
+library libd;
+
+import 'duplicate_import_liba.dart';
+import 'duplicate_import_libb.dart';
+import 'duplicate_import_libc.dart';
+
+export '../duplicate_import_liba.dart';
+export 'duplicate_import_libb.dart';
+export 'duplicate_import_libc.dart';
diff --git a/tests/language/export/duplicate_liba.dart b/tests/language/export/duplicate_liba.dart
new file mode 100644
index 0000000..7b68d42
--- /dev/null
+++ b/tests/language/export/duplicate_liba.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library export_liba;
+
+export 'duplicate_import_liba.dart';
diff --git a/tests/language/export/export_test.dart b/tests/language/export/export_test.dart
new file mode 100644
index 0000000..e1faa61
--- /dev/null
+++ b/tests/language/export/export_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// Test export and re-export.
+
+library export_test;
+
+import 'helper1.dart';
+import 'helper3.dart' as lib;
+
+void main() {
+  print(new Exported());
+  print(new ReExported());
+  print(new lib.Exported());
+  print(new lib.ReExported());
+}
diff --git a/tests/language/export/helper1.dart b/tests/language/export/helper1.dart
new file mode 100644
index 0000000..5b670f4
--- /dev/null
+++ b/tests/language/export/helper1.dart
@@ -0,0 +1,10 @@
+// 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.
+
+library export_helper1;
+
+import 'helper2.dart';
+export 'helper2.dart';
+
+class Exported extends ReExported {}
diff --git a/tests/language/export/helper2.dart b/tests/language/export/helper2.dart
new file mode 100644
index 0000000..50dcc3d
--- /dev/null
+++ b/tests/language/export/helper2.dart
@@ -0,0 +1,7 @@
+// 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.
+
+library export_helper2;
+
+class ReExported {}
diff --git a/tests/language/export/helper3.dart b/tests/language/export/helper3.dart
new file mode 100644
index 0000000..3b3bed9
--- /dev/null
+++ b/tests/language/export/helper3.dart
@@ -0,0 +1,10 @@
+// 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.
+
+library export_helper3;
+
+import 'helper4.dart';
+export 'helper4.dart';
+
+class Exported extends ReExported {}
diff --git a/tests/language/export/helper4.dart b/tests/language/export/helper4.dart
new file mode 100644
index 0000000..3ca68ec
--- /dev/null
+++ b/tests/language/export/helper4.dart
@@ -0,0 +1,7 @@
+// 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.
+
+library export_helper4;
+
+class ReExported {}
diff --git a/tests/language/export/local_a.dart b/tests/language/export/local_a.dart
new file mode 100644
index 0000000..dd6d039
--- /dev/null
+++ b/tests/language/export/local_a.dart
@@ -0,0 +1,11 @@
+// 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.
+
+library local_export_a;
+
+export 'local_a_export.dart';
+
+class A {
+  method() => 42;
+}
diff --git a/tests/language/export/local_a_export.dart b/tests/language/export/local_a_export.dart
new file mode 100644
index 0000000..1919d38
--- /dev/null
+++ b/tests/language/export/local_a_export.dart
@@ -0,0 +1,7 @@
+// 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.
+
+library local_export_a_export;
+
+int A = 0;
diff --git a/tests/language/export/local_export_test.dart b/tests/language/export/local_export_test.dart
new file mode 100644
index 0000000..2ed4659
--- /dev/null
+++ b/tests/language/export/local_export_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+library localExportTest;
+
+import "package:expect/expect.dart";
+import 'local_a.dart';
+
+void main() {
+  Expect.equals(42, new A().method());
+}
diff --git a/tests/language/export/main_override_test.dart b/tests/language/export/main_override_test.dart
new file mode 100644
index 0000000..6578288
--- /dev/null
+++ b/tests/language/export/main_override_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'top_level_entry_test.dart';
+
+main() {
+  print('export_main_override');
+}
diff --git a/tests/language/export/main_test.dart b/tests/language/export/main_test.dart
new file mode 100644
index 0000000..1e920a7
--- /dev/null
+++ b/tests/language/export/main_test.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'top_level_entry_test.dart';
diff --git a/tests/language/export/not_shadowed_by_prefix_helper.dart b/tests/language/export/not_shadowed_by_prefix_helper.dart
new file mode 100644
index 0000000..d6d44fd
--- /dev/null
+++ b/tests/language/export/not_shadowed_by_prefix_helper.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export "not_shadowed_by_prefix_helper2.dart";
+import "dart:core" as f;
diff --git a/tests/language/export/not_shadowed_by_prefix_helper2.dart b/tests/language/export/not_shadowed_by_prefix_helper2.dart
new file mode 100644
index 0000000..ae2dca5
--- /dev/null
+++ b/tests/language/export/not_shadowed_by_prefix_helper2.dart
@@ -0,0 +1,9 @@
+// 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.
+
+void f() {
+  f_called = true;
+}
+
+bool f_called = false;
diff --git a/tests/language/export/not_shadowed_by_prefix_test.dart b/tests/language/export/not_shadowed_by_prefix_test.dart
new file mode 100644
index 0000000..6cebd57
--- /dev/null
+++ b/tests/language/export/not_shadowed_by_prefix_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Verify that import prefixes within an imported library don't shadow
+// names re-exported by that library.
+
+import "package:expect/expect.dart";
+import "not_shadowed_by_prefix_helper.dart";
+
+main() {
+  f();
+  Expect.isTrue(f_called);
+}
diff --git a/tests/language/export/order_helper1.dart b/tests/language/export/order_helper1.dart
new file mode 100644
index 0000000..68dd448
--- /dev/null
+++ b/tests/language/export/order_helper1.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'order_test.dart';
+export 'order_helper2.dart' show z;
diff --git a/tests/language/export/order_helper2.dart b/tests/language/export/order_helper2.dart
new file mode 100644
index 0000000..7effbfb
--- /dev/null
+++ b/tests/language/export/order_helper2.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'order_helper1.dart';
+
+class Info {
+  int x = y;
+}
+
+int get z => 38;
diff --git a/tests/language/export/order_test.dart b/tests/language/export/order_test.dart
new file mode 100644
index 0000000..94cb915
--- /dev/null
+++ b/tests/language/export/order_test.dart
@@ -0,0 +1,16 @@
+// 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:expect/expect.dart';
+import 'order_helper1.dart' as bar;
+import 'order_helper2.dart';
+
+final y = 38;
+final info = new Info();
+
+void main() {
+  Expect.equals(38, info.x);
+  Expect.equals(38, bar.y);
+  Expect.equals(38, bar.z);
+}
diff --git a/tests/language/export/private_runtime_test.dart b/tests/language/export/private_runtime_test.dart
new file mode 100644
index 0000000..e78b2b1
--- /dev/null
+++ b/tests/language/export/private_runtime_test.dart
@@ -0,0 +1,13 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Check that private dart:_ libraries cannot be imported.
+
+
+
+main() {
+  print("Done.");
+}
diff --git a/tests/language/export/private_test.dart b/tests/language/export/private_test.dart
new file mode 100644
index 0000000..d152f32
--- /dev/null
+++ b/tests/language/export/private_test.dart
@@ -0,0 +1,13 @@
+// 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.
+// Check that private dart:_ libraries cannot be imported.
+
+export "dart:_internal";
+// [error line 6, column 1, length 24]
+// [analyzer] COMPILE_TIME_ERROR.EXPORT_INTERNAL_LIBRARY
+// [cfe] Can't access platform private library.
+
+main() {
+  print("Done.");
+}
diff --git a/tests/language/export/reexport_core_helper.dart b/tests/language/export/reexport_core_helper.dart
new file mode 100644
index 0000000..86c81bf5
--- /dev/null
+++ b/tests/language/export/reexport_core_helper.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library reexport_core_helper;
+
+export 'dart:core';
diff --git a/tests/language/export/reexport_core_test.dart b/tests/language/export/reexport_core_test.dart
new file mode 100644
index 0000000..e4a17dd
--- /dev/null
+++ b/tests/language/export/reexport_core_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that exports are handled for libraries loaded prior to the entry point
+// library.
+//
+// This test uses the fact that dart2js loads dart:core before the
+// reexport_core_helper and reexport_core_test libraries and the exports of
+// dart:core is therefore computed before the exports of reexport_core_helper.
+
+library reexport_core_test;
+
+import "package:expect/expect.dart";
+import 'reexport_core_helper.dart' as core;
+
+void main() {
+  var o = new Object();
+  Expect.isTrue(o is core.Object);
+}
diff --git a/tests/language/export/top_level_entry.dart b/tests/language/export/top_level_entry.dart
new file mode 100644
index 0000000..4399b58
--- /dev/null
+++ b/tests/language/export/top_level_entry.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of top_level_entry_test.dart;
+
+main() {}
diff --git a/tests/language/export/top_level_entry_test.dart b/tests/language/export/top_level_entry_test.dart
new file mode 100644
index 0000000..5f8c178
--- /dev/null
+++ b/tests/language/export/top_level_entry_test.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library top_level_entry_test.dart;
+
+part 'top_level_entry.dart';
diff --git a/tests/language/extension_methods/basic_static_extension_test.dart b/tests/language/extension_methods/basic_static_extension_test.dart
new file mode 100644
index 0000000..7256a98
--- /dev/null
+++ b/tests/language/extension_methods/basic_static_extension_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+// Tests the syntax of extension methods, and that the extensions are
+// invocable, and that type variables are bound correctly.
+
+// There are no extension *conflicts*.
+// For each invocation,  there is exactly one extension member in scope
+// which applies.
+
+// Target types.
+class Unnamed {}
+
+class Named {}
+
+class UnnamedGeneric<T> {}
+
+class NamedGeneric<T> {}
+
+String str(String name, Object? object) =>
+    "$name(${object == null ? "null" : "non-null"})";
+
+// Unnamed local extension.
+extension on Unnamed? {
+  String get name => str("unnamed", this);
+}
+
+extension NamedExt on Named? {
+  String get name => str("named", this);
+}
+
+extension<T> on UnnamedGeneric<T>? {
+  String get name => str("unnamed generic", this);
+  List<T> get list => <T>[];
+}
+
+extension NamedGenericExt<T> on NamedGeneric<T>? {
+  String get name => str("named generic", this);
+  List<T> get list => <T>[];
+}
+
+extension General on Object? {
+  String get generalName => str("general", this);
+}
+
+extension GeneralGeneric<T> on T {
+  String get generalGenericName => str("general generic", this);
+  List<T> get generalList => <T>[];
+}
+
+main() {
+  // Unnamed.
+  Unnamed unnamed = Unnamed();
+  Unnamed? unnamedNull = null;
+
+  Expect.equals("unnamed(non-null)", unnamed.name);
+  Expect.equals("unnamed(null)", unnamedNull.name);
+
+  Expect.equals("general(non-null)", unnamed.generalName);
+  Expect.equals("general(null)", unnamedNull.generalName);
+
+  Expect.equals("general generic(non-null)", unnamed.generalGenericName);
+  Expect.equals("general generic(null)", unnamedNull.generalGenericName);
+  Expect.type<List<Unnamed>>(unnamed.generalList);
+  Expect.type<List<Unnamed?>>(unnamedNull.generalList);
+
+  // Named.
+  Named named = Named();
+  Named? namedNull = null;
+
+  Expect.equals("named(non-null)", named.name);
+  Expect.equals("named(null)", namedNull.name);
+
+  Expect.equals("general(non-null)", named.generalName);
+  Expect.equals("general(null)", namedNull.generalName);
+
+  Expect.equals("general generic(non-null)", named.generalGenericName);
+  Expect.equals("general generic(null)", namedNull.generalGenericName);
+  Expect.type<List<Named>>(named.generalList);
+  Expect.type<List<Named?>>(namedNull.generalList);
+
+  // Unnamed Generic.
+  UnnamedGeneric<num> unnamedGeneric = UnnamedGeneric<int>();
+  UnnamedGeneric<num>? unnamedGenericNull = null;
+
+  Expect.equals("unnamed generic(non-null)", unnamedGeneric.name);
+  Expect.equals("unnamed generic(null)", unnamedGenericNull.name);
+  Expect.type<List<num>>(unnamedGeneric.list);
+  Expect.notType<List<int>>(unnamedGeneric.list);
+  Expect.type<List<num>>(unnamedGenericNull.list);
+  Expect.notType<List<int>>(unnamedGenericNull.list);
+
+  Expect.equals("general(non-null)", unnamedGeneric.generalName);
+  Expect.equals("general(null)", unnamedGenericNull.generalName);
+
+  Expect.equals("general generic(non-null)", unnamedGeneric.generalGenericName);
+  Expect.equals("general generic(null)", unnamedGenericNull.generalGenericName);
+  Expect.type<List<UnnamedGeneric<num>>>(unnamedGeneric.generalList);
+  Expect.type<List<UnnamedGeneric<num>?>>(unnamedGenericNull.generalList);
+
+  // Named Generic.
+  NamedGeneric<num> namedGeneric = NamedGeneric<int>();
+  NamedGeneric<num>? namedGenericNull = null;
+
+  Expect.equals("named generic(non-null)", namedGeneric.name);
+  Expect.equals("named generic(null)", namedGenericNull.name);
+  Expect.type<List<num>>(namedGeneric.list);
+  Expect.notType<List<int>>(namedGeneric.list);
+  Expect.type<List<num>>(namedGenericNull.list);
+  Expect.notType<List<int>>(namedGenericNull.list);
+
+  Expect.equals("general(non-null)", namedGeneric.generalName);
+  Expect.equals("general(null)", namedGenericNull.generalName);
+
+  Expect.equals("general generic(non-null)", namedGeneric.generalGenericName);
+  Expect.equals("general generic(null)", namedGenericNull.generalGenericName);
+  Expect.type<List<NamedGeneric<num>>>(namedGeneric.generalList);
+  Expect.type<List<NamedGeneric<num>?>>(namedGenericNull.generalList);
+}
diff --git a/tests/language/extension_methods/extension_operation_in_const_test.dart b/tests/language/extension_methods/extension_operation_in_const_test.dart
new file mode 100644
index 0000000..4dc4b6a
--- /dev/null
+++ b/tests/language/extension_methods/extension_operation_in_const_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+extension on Object {
+  int operator -() => 42;
+  int get length => 5;
+}
+
+class Tester {
+  final value;
+  const Tester.neg(Object o) : value = -o;
+  const Tester.length(Object o) : value = o.length;
+}
+
+main() {
+  const //
+      Object //# neg: compile-time error
+      i = 2;
+  const int x = -i;
+  print(x);
+
+  const //
+      Object //# length: compile-time error
+      s = "fisk";
+  const int y = s.length;
+  print(y);
+
+  Expect.equals(42, new Tester.neg(3).value);
+  const tx = Tester.neg(42); //# tneg: compile-time error
+  print(tx); //# tneg: continued
+
+  Expect.equals(5, new Tester.length("abc").value);
+  const ty = Tester.length("abc"); //# tlength: compile-time error
+  print(ty); //# tlength: continued
+}
diff --git a/tests/language/extension_methods/helpers/also_on_object.dart b/tests/language/extension_methods/helpers/also_on_object.dart
new file mode 100644
index 0000000..afe30e34
--- /dev/null
+++ b/tests/language/extension_methods/helpers/also_on_object.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// An extension conflicting with the one from "on_object.dart";
+extension AlsoOnObject on Object {
+  String get onObject => "also object";
+}
diff --git a/tests/language/extension_methods/helpers/class_no_shadow.dart b/tests/language/extension_methods/helpers/class_no_shadow.dart
new file mode 100644
index 0000000..31e8195
--- /dev/null
+++ b/tests/language/extension_methods/helpers/class_no_shadow.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+const String instanceValue = "1";
+
+void checkInstanceValue(String other) {
+  Expect.equals(other, instanceValue);
+}
+
+// A class which has only its own instance methods
+class A {
+  String fieldInInstanceScope = instanceValue;
+  String get getterInInstanceScope => instanceValue;
+  set setterInInstanceScope(String x) {
+    checkInstanceValue(x);
+  }
+
+  String methodInInstanceScope() => instanceValue;
+}
diff --git a/tests/language/extension_methods/helpers/class_shadow.dart b/tests/language/extension_methods/helpers/class_shadow.dart
new file mode 100644
index 0000000..2e603d1a
--- /dev/null
+++ b/tests/language/extension_methods/helpers/class_shadow.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "class_no_shadow.dart";
+
+// A class which has its own instance methods, which also
+// shadows the global scope
+class AGlobal extends A {
+  String fieldInGlobalScope = instanceValue;
+  String get getterInGlobalScope => instanceValue;
+  set setterInGlobalScope(String x) {
+    checkInstanceValue(x);
+  }
+
+  String methodInGlobalScope() => instanceValue;
+}
diff --git a/tests/language/extension_methods/helpers/extension_all.dart b/tests/language/extension_methods/helpers/extension_all.dart
new file mode 100644
index 0000000..80656a7
--- /dev/null
+++ b/tests/language/extension_methods/helpers/extension_all.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "class_no_shadow.dart";
+
+const double otherExtensionValue = 1.234;
+
+void checkOtherExtensionValue(double other) {
+  Expect.equals(other, otherExtensionValue);
+}
+
+// An extension which defines all symbols
+extension ExtraExt on A {
+  double get fieldInGlobalScope => otherExtensionValue;
+  double get getterInGlobalScope => otherExtensionValue;
+  set setterInGlobalScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInGlobalScope() => otherExtensionValue;
+
+  double get fieldInInstanceScope => otherExtensionValue;
+  double get getterInInstanceScope => otherExtensionValue;
+  set setterInInstanceScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInInstanceScope() => otherExtensionValue;
+
+  double get fieldInExtensionScope => otherExtensionValue;
+  double get getterInExtensionScope => otherExtensionValue;
+  set setterInExtensionScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInExtensionScope() => otherExtensionValue;
+
+  double get fieldInOtherExtensionScope => otherExtensionValue;
+  double get getterInOtherExtensionScope => otherExtensionValue;
+  set setterInOtherExtensionScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language/extension_methods/helpers/extension_global_instance.dart b/tests/language/extension_methods/helpers/extension_global_instance.dart
new file mode 100644
index 0000000..1fbbe7b
--- /dev/null
+++ b/tests/language/extension_methods/helpers/extension_global_instance.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "class_no_shadow.dart";
+
+const double otherExtensionValue = 1.234;
+
+void checkOtherExtensionValue(double other) {
+  Expect.equals(other, otherExtensionValue);
+}
+
+// An extension which defines only global, instance and its own symbols
+extension ExtraExt on A {
+  double get fieldInGlobalScope => otherExtensionValue;
+  double get getterInGlobalScope => otherExtensionValue;
+  set setterInGlobalScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInGlobalScope() => otherExtensionValue;
+
+  double get fieldInInstanceScope => otherExtensionValue;
+  double get getterInInstanceScope => otherExtensionValue;
+  set setterInInstanceScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInInstanceScope() => otherExtensionValue;
+
+  double get fieldInOtherExtensionScope => otherExtensionValue;
+  double get getterInOtherExtensionScope => otherExtensionValue;
+  set setterInOtherExtensionScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language/extension_methods/helpers/extension_only.dart b/tests/language/extension_methods/helpers/extension_only.dart
new file mode 100644
index 0000000..d625af7
--- /dev/null
+++ b/tests/language/extension_methods/helpers/extension_only.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "class_no_shadow.dart";
+
+const double otherExtensionValue = 1.234;
+
+void checkOtherExtensionValue(double other) {
+  Expect.equals(other, otherExtensionValue);
+}
+
+// An extension which defines only its own symbols
+extension ExtraExt on A {
+  double get fieldInOtherExtensionScope => otherExtensionValue;
+  double get getterInOtherExtensionScope => otherExtensionValue;
+  set setterInOtherExtensionScope(double x) {
+    checkOtherExtensionValue(x);
+  }
+
+  double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language/extension_methods/helpers/global_scope.dart b/tests/language/extension_methods/helpers/global_scope.dart
new file mode 100644
index 0000000..ae6f4fe
--- /dev/null
+++ b/tests/language/extension_methods/helpers/global_scope.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+const int globalValue = 0;
+
+void checkGlobalValue(int x) {
+  Expect.equals(x, globalValue);
+}
+
+// Add symbols to the global scope
+int fieldInGlobalScope = globalValue;
+int get getterInGlobalScope => globalValue;
+set setterInGlobalScope(int x) {
+  checkGlobalValue(x);
+}
+
+int methodInGlobalScope() => globalValue;
diff --git a/tests/language/extension_methods/helpers/on_int.dart b/tests/language/extension_methods/helpers/on_int.dart
new file mode 100644
index 0000000..a835f16
--- /dev/null
+++ b/tests/language/extension_methods/helpers/on_int.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension OnInt on int {
+  String get onObject => "int";
+  String get onInt => "int";
+}
diff --git a/tests/language/extension_methods/helpers/on_object.dart b/tests/language/extension_methods/helpers/on_object.dart
new file mode 100644
index 0000000..dfca4d6
--- /dev/null
+++ b/tests/language/extension_methods/helpers/on_object.dart
@@ -0,0 +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.
+
+extension OnObject on Object {
+  String get onObject => "object";
+}
diff --git a/tests/language/extension_methods/static_extension_bounds_error_test.dart b/tests/language/extension_methods/static_extension_bounds_error_test.dart
new file mode 100644
index 0000000..d78b2a8
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_bounds_error_test.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests bounds checking for extension methods
+
+extension E1<T extends num> on T {
+  int get e1 => 1;
+}
+
+extension E2<T extends S, S extends num> on T {
+  int get e2 => 2;
+}
+
+extension E3<T> on T {
+  S f3<S extends T>(S x) => x;
+}
+
+extension E4<T extends Rec<T>> on T {
+  int get e4 => 4;
+}
+
+class Rec<T extends Rec<T>> {}
+
+class RecSolution extends Rec<RecSolution> {}
+
+void main() {
+  String s = "s";
+  int i = 0;
+  double d = 1.0;
+
+  // Inferred type of String does not satisfy the bound.
+  s.e1;
+//  ^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+// [cfe] The getter 'e1' isn't defined for the class 'String'.
+  E1(s).e1;
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'E1|get#e1'.
+  E1<String>(s).e1;
+//^
+// [cfe] Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'E1|get#e1'.
+//   ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
+  // Inferred types of int and double are ok
+  i.e1;
+  E1(i).e1;
+  E1<int>(i).e1;
+  d.e1;
+  E1(d).e1;
+  E1<double>(d).e1;
+
+  // Inferred type of String does not satisfy the bound.
+  s.e2;
+//  ^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+// [cfe] The getter 'e2' isn't defined for the class 'String'.
+  E2(s).e2;
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'String' doesn't conform to the bound 'S' of the type variable 'T' on 'E2|get#e2'.
+  E2<String, num>(s).e2;
+//^
+// [cfe] Type argument 'String' doesn't conform to the bound 'S' of the type variable 'T' on 'E2|get#e2'.
+//   ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
+  // Inferred types of int and double are ok
+  i.e2;
+  E2(i).e2;
+  E2<int, num>(i).e2;
+  d.e2;
+  E2(d).e2;
+  E2<double, num>(d).e2;
+
+  // Inferred type int for method type parameter doesn't match the inferred
+  // bound of String
+  s.f3(3);
+//  ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+  E3(s).f3(3);
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+  E3<String>(s).f3(3);
+//              ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+
+  // Inferred type int for method type parameter is ok
+  i.f3(3);
+  E3(i).f3(3);
+  E3<int>(i).f3(3);
+
+  // Inferred type int for method type parameter doesn't match the inferred
+  // bound of double
+  d.f3(3);
+//  ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+  E3(d).f3(3);
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+  E3<double>(d).f3(3);
+//              ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+
+  RecSolution recs = RecSolution();
+  Rec<dynamic> superRec = RecSolution(); // Super-bounded type.
+
+  // Inferred type of RecSolution is ok
+  recs.e4;
+  E4(recs).e4;
+  E4<RecSolution>(recs).e4;
+
+  // Inferred super-bounded type is invalid as type argument
+  superRec.e4;
+//         ^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+// [cfe] The getter 'e4' isn't defined for the class 'Rec<dynamic>'.
+  E4(superRec).e4;
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'Rec<dynamic>' doesn't conform to the bound 'Rec<T>' of the type variable 'T' on 'E4|get#e4'.
+  E4<Rec<dynamic>>(superRec).e4;
+//^
+// [cfe] Type argument 'Rec<dynamic>' doesn't conform to the bound 'Rec<T>' of the type variable 'T' on 'E4|get#e4'.
+//   ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+}
diff --git a/tests/language/extension_methods/static_extension_constant_error_test.dart b/tests/language/extension_methods/static_extension_constant_error_test.dart
new file mode 100644
index 0000000..e7a0d0c
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_constant_error_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'static_extension_constant_lib.dart';
+
+// Tests that it is an error to invoke an extension method during constant
+// expression evaluation. The expressions should be the same as those in
+// `runtimeExtensionCalls`, so that it is verified that each of them will
+// invoke an extension method.
+
+void main() {
+  // The initializing expressions should be identical to the elements in
+  // `runtimeExtensionCalls`.
+
+  const c01 = ~i;
+  //          ^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c02 = b & b;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c03 = b | b;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c04 = b ^ b;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c05 = i ~/ i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c06 = i >> i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c08 = i << i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c09 = i + i;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c10 = -i;
+  //          ^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c11 = d - d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c12 = d * d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c13 = d / d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c14 = d % d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c15 = d < i;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c16 = i <= d;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c17 = d > i;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c18 = i >= i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c19 = s.length;
+  //          ^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
diff --git a/tests/language/extension_methods/static_extension_constant_lib.dart b/tests/language/extension_methods/static_extension_constant_lib.dart
new file mode 100644
index 0000000..23d6de9
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_constant_lib.dart
@@ -0,0 +1,55 @@
+// 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.
+
+extension ExtendObject on Object {
+  int operator ~() => 1;
+  bool operator &(Object other) => false;
+  bool operator |(Object other) => false;
+  bool operator ^(Object other) => true;
+  int operator ~/(Object other) => 0;
+  int operator >>(Object other) => 1;
+  // int operator >>>(Object other) => 2; // Requires triple-shift.
+  int operator <<(Object other) => 0;
+  int operator +(Object other) => 0;
+  double operator -() => 1.0;
+  double operator -(Object other) => 1.0;
+  double operator *(Object other) => 1.0;
+  double operator /(Object other) => 2.0;
+  double operator %(Object other) => 1.0;
+  bool operator <(Object other) => false;
+  bool operator <=(Object other) => true;
+  bool operator >(Object other) => true;
+  bool operator >=(Object other) => false;
+  int get length => 1;
+}
+
+const Object b = true;
+const Object i = 3;
+const Object d = 2.4;
+const Object s = 'Hello!';
+
+// These expressions should be identical to the ones in
+// static_extension_constant_{,error}_test.dart, to ensure that
+// they invoke an extension method, and that this is an error.
+var runtimeExtensionCalls = <Object>[
+  ~i,
+  b & b,
+  b | b,
+  b ^ b,
+  i ~/ i,
+  i >> i,
+  // i >>> i, // Requries triple-shift.
+  i << i,
+  i + i,
+  -i,
+  d - d,
+  d * d,
+  d / d,
+  d % d,
+  d < i,
+  i <= d,
+  d > i,
+  i >= i,
+  s.length,
+];
diff --git a/tests/language/extension_methods/static_extension_constant_test.dart b/tests/language/extension_methods/static_extension_constant_test.dart
new file mode 100644
index 0000000..1295d4a
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_constant_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+import 'static_extension_constant_lib.dart' hide b, i, d, s;
+import 'static_extension_constant_lib.dart' as lib show b, i, d, s;
+
+// Ensure that all expressions in runtimeExtensionCalls invoke
+// an extension method rather than an instance method, such that
+// static_extension_constant_error_test gets an error for them all.
+
+const dynamic b = lib.b;
+const dynamic i = lib.i;
+const dynamic d = lib.d;
+const dynamic s = lib.s;
+
+// These expressions should be identical to those in
+// `lib.runtimeExtensionCalls`.
+var dynamicInstanceCalls = <Object>[
+  ~i,
+  b & b,
+  b | b,
+  b ^ b,
+  i ~/ i,
+  i >> i,
+  // i >>> i, // Requries triple-shift.
+  i << i,
+  i + i,
+  -i,
+  d - d,
+  d * d,
+  d / d,
+  d % d,
+  d < i,
+  i <= d,
+  d > i,
+  i >= i,
+  s.length,
+];
+
+void main() {
+  for (int i = 0; i < dynamicInstanceCalls.length; ++i) {
+    Expect.notEquals(dynamicInstanceCalls[i], runtimeExtensionCalls[i]);
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_deferred_double_import_test.dart b/tests/language/extension_methods/static_extension_deferred_double_import_test.dart
new file mode 100644
index 0000000..0ef1f33
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_double_import_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_object.dart" deferred as p1 hide OnObject;
+
+// Allow explicit and implicit access to non-deferred import extensions.
+
+void main() async {
+  Object o = 1;
+  Expect.equals("object", OnObject(o).onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_deferred_import_error_test.dart b/tests/language/extension_methods/static_extension_deferred_import_error_test.dart
new file mode 100644
index 0000000..3d0c5ba
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_import_error_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// It is an error to import a deferred library containing extensions without
+// hiding them.
+import "helpers/on_object.dart" deferred as p1;
+// [error line 9, column 1]
+// [cfe] Extension 'OnObject' cannot be imported through a deferred import.
+//     ^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.DEFERRED_IMPORT_OF_EXTENSION
+
+void main() async {}
diff --git a/tests/language/extension_methods/static_extension_deferred_import_resolution_error_test.dart b/tests/language/extension_methods/static_extension_deferred_import_resolution_error_test.dart
new file mode 100644
index 0000000..59920e7
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_import_resolution_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" deferred as p1 hide OnObject;
+
+void main() {
+  Object o = 1;
+  OnObject(o).onObject;
+//^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_FUNCTION
+// [cfe] Method not found: 'OnObject'.
+  o.onObject;
+  //^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'onObject' isn't defined for the class 'Object'.
+}
diff --git a/tests/language/extension_methods/static_extension_deferred_import_test.dart b/tests/language/extension_methods/static_extension_deferred_import_test.dart
new file mode 100644
index 0000000..829a242
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_import_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" deferred as p1 hide OnObject;
+
+void main() {}
diff --git a/tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart b/tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart
new file mode 100644
index 0000000..686c40f
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests interactions between getters and setters where there is a conflict.
+
+// Conflicting class declarations.
+
+class C0 {
+  int get m1 => 0;
+  void set m2(int x) {}
+  int operator [](int index) => 0;
+}
+
+extension E0 on C0 {
+  void set m1(int x) {}
+  int get m2 => 0;
+  void operator []=(int index, int value) {}
+}
+
+void test0() {
+  C0 c0 = C0();
+  c0.m1;
+  c0.m1 = 0;
+  // ^^
+  // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+  // [cfe] The setter 'm1' isn't defined for the class 'C0'.
+  E0(c0).m1 = 0;
+  E0(c0).m1;
+  //     ^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_GETTER
+  // [cfe] Getter not found: 'm1'.
+
+  c0.m1 += 0;
+  // ^^
+  // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+  // [cfe] The setter 'm1' isn't defined for the class 'C0'.
+
+  c0.m1++;
+  // ^^
+  // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+  // [cfe] The setter 'm1' isn't defined for the class 'C0'.
+
+  c0.m2 = 0;
+  c0.m2;
+  // ^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'm2' isn't defined for the class 'C0'.
+  c0.m2 += 0;
+  // ^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'm2' isn't defined for the class 'C0'.
+  c0.m2++;
+  // ^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'm2' isn't defined for the class 'C0'.
+
+  E0(c0).m2;
+
+  c0[0];
+  c0[0] = 0;
+  //^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+  // [cfe] The operator '[]=' isn't defined for the class 'C0'.
+  E0(c0)[0];
+  //    ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
+  // [cfe] Getter not found: '[]'.
+  E0(c0)[0] = 0;
+
+  c0[0] += 0;
+  //^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+  // [cfe] The operator '[]=' isn't defined for the class 'C0'.
+  c0[0]++;
+  //^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+  // [cfe] The operator '[]=' isn't defined for the class 'C0'.
+
+  E0(c0)[0] += 0;
+  //    ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
+  // [cfe] The operator '[]' isn't defined for the class 'C0'.
+  E0(c0)[0]++;
+  //    ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
+  // [cfe] The operator '[]' isn't defined for the class 'C0'.
+}
+
+// Conflicting extensions.
+
+class C1<T> {}
+
+extension E1A<T> on C1<T> {
+  int get m1 => 0;
+  void set m2(int x) {}
+  int operator [](int index) => 0;
+}
+
+extension E1B on C1<Object?> {
+  void set m1(int x) {}
+  int get m2 => 0;
+  void operator []=(int index, int value) {}
+}
+
+void test1() {
+  C1<int> c1a = C1(); // E1A is more specific.
+  c1a.m1;
+
+  c1a.m1 = 0;
+  //  ^^
+  // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
+  // [cfe] The setter 'm1' isn't defined for the class 'C1<int>'.
+
+  c1a.m2;
+  //  ^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'm2' isn't defined for the class 'C1<int>'.
+
+  c1a.m2 = 0;
+
+  c1a[0] = 0;
+  // ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+  // [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
+
+  c1a[0] += 0;
+  // ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+  // [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
+
+  c1a[0]++;
+  // ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+  // [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
+
+  c1a[0];
+
+  C1<Object> c1b = C1<Object>(); // Neither extension is more specific.
+
+  c1b.m1;
+  //  ^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b.m1 = 0;
+  //  ^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b.m1 += 0;
+  //  ^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b.m1++;
+  //  ^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b.m2;
+  //  ^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'm2' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b[0];
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+//   ^
+// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b[0] = 0;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+//   ^
+// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b[0] += 0;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+//   ^
+// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+//   ^
+// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+  c1b[0]++;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+//   ^
+// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+//   ^
+// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+}
+
+// Getter on the extension itself.
+class C2 {
+  int get m1 => 0;
+  void set m2(int x) {}
+  int get mc => 0;
+  void operator []=(int index, int value) {}
+}
+
+extension E2 on C2 {
+  void set m1(int x) {}
+  int get m2 => 0;
+  String get me => "";
+  int operator [](int index) => 0;
+
+  void test2() {
+    // Using `this.member` means using the `on` type.
+
+    this.m1;
+    this.m1 = 0;
+    //   ^^
+    // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+    // [cfe] The setter 'm1' isn't defined for the class 'C2'.
+
+    this.m2 = 0;
+    this.m2;
+    //   ^^
+    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+    // [cfe] The getter 'm2' isn't defined for the class 'C2'.
+
+    this[0] = 0;
+    this[0];
+    //  ^^^
+    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+    // [cfe] The operator '[]' isn't defined for the class 'C2'.
+
+    this[0] += 0;
+    //  ^^^
+    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+    // [cfe] The operator '[]' isn't defined for the class 'C2'.
+
+    this[0]++;
+    //  ^^^
+    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+    // [cfe] The operator '[]' isn't defined for the class 'C2'.
+
+    // Check that `this.mc` refers to `C2.mc`.
+    this.mc.toRadixString(16);
+    // Check that `this.me` refers to `E2.me`.
+    this.me.substring(0);
+  }
+}
+
+main() {
+  test0();
+  test1();
+  C2().test2();
+}
diff --git a/tests/language/extension_methods/static_extension_getter_setter_test.dart b/tests/language/extension_methods/static_extension_getter_setter_test.dart
new file mode 100644
index 0000000..7224cb5
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_getter_setter_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests getters and setters where one or both is defined
+// by an extension.
+
+import "package:expect/expect.dart";
+
+main() {
+  C c = C();
+  // v1: C get, C set
+  expectGet("C.v1", c.v1);
+  expectSet("C.v1=1", c.v1 = Result("1"));
+  // v2: C get, E1 get/set, C wins.
+  expectGet("C.v2", c.v2);
+  expectSet("E1.v2=2", E1(c).v2 = Result("2"));
+  // v3: E1 get/set, C set, C wins.
+  expectGet("E1.v3", E1(c).v3);
+  expectSet("C.v3=3", c.v3 = Result("3"));
+  // v4: E1 get/set
+  expectGet("E1.v4", c.v4);
+  expectSet("E1.v4=4", c.v4 = Result("4"));
+  // v5: E1 get, E2 set, neither more specific.
+  expectGet("E1.v5", E1(c).v5);
+  expectSet("E2.v5=5", E2(c).v5 = Result("5"));
+
+  expectSet("C.v1=C.v1+1", c.v1++);
+  expectSet("E1.v4=E1.v4+1", c.v4++);
+
+  expectSet("C.v1=C.v1+a", c.v1 += "a");
+  expectSet("C.v1=C.v1-b", c.v1 -= "b");
+  expectSet("E1.v4=E1.v4-b", c.v4 -= "b");
+
+  // Explicit application used by all accesses of read/write operations
+  expectSet("E1.v1=E1.v1+1", E1(c).v1++);
+  expectSet("E1.v2=E1.v2+1", E1(c).v2++);
+  expectSet("E1.v3=E1.v3+1", E1(c).v3++);
+  // Same using `+= 1` instead of `++`.
+  expectSet("E1.v1=E1.v1+1", E1(c).v1 += 1);
+  expectSet("E1.v2=E1.v2+1", E1(c).v2 += 1);
+  expectSet("E1.v3=E1.v3+1", E1(c).v3 += 1);
+  // Same fully expanded.
+  expectSet("E1.v1=E1.v1+1", E1(c).v1 = E1(c).v1 + 1);
+  expectSet("E1.v2=E1.v2+1", E1(c).v2 = E1(c).v2 + 1);
+  expectSet("E1.v3=E1.v3+1", E1(c).v3 = E1(c).v3 + 1);
+
+  // Cascades work.
+  expectSet(
+      "E1.v4=E1.v4+[C.v1=C.v1-[C.v3=a]]",
+      c
+        ..v3 = Result("a")
+        ..v1 -= Result("[$lastSetter]")
+        ..v4 += Result("[$lastSetter]"));
+}
+
+/// Expect the value of [result] to be the [expected] string
+expectGet(String expected, Result result) {
+  Expect.equals(expected, result.value);
+}
+
+/// Expect the [lastSetter] value set by evaluating [assignment] to be
+/// [expected].
+expectSet(String expected, void assignment) {
+  Expect.equals(expected, lastSetter);
+}
+
+/// Last value passed to any of our tested setters.
+String? lastSetter = null;
+
+/// A type which supports a `+` operation accepting `int`,
+/// so we can test `+=` and `++`.
+class Result {
+  final String value;
+  Result(this.value);
+  Result operator +(Object o) => Result("$value+$o");
+  Result operator -(Object o) => Result("$value-$o");
+  String toString() => value;
+}
+
+/// Target type for extensions.
+///
+/// Declares [v1] getter and setter, [v2] getter and [v3] setter.
+class C {
+  Result get v1 => Result("C.v1");
+  void set v1(Result value) {
+    lastSetter = "C.v1=$value";
+  }
+
+  Result get v2 => Result("C.v2");
+
+  void set v3(Result value) {
+    lastSetter = "C.v3=$value";
+  }
+}
+
+/// Primary extension on [C].
+///
+/// Declares [v1], [v2] and [v3] getters and setters.
+///
+/// Declares [v4] getter and setter, and [v5] getter
+/// which are supplemented by a setter from the [E2] extension.
+extension E1 on C {
+  // Same basename as C getter and setter.
+  Result get v1 => Result("E1.v1");
+
+  void set v1(Result value) {
+    lastSetter = "E1.v1=$value";
+  }
+
+  // Same basename as C getter.
+  Result get v2 => Result("E1.v2");
+
+  void set v2(Result value) {
+    lastSetter = "E1.v2=$value";
+  }
+
+  // Same basename as C setter.
+  Result get v3 => Result("E1.v3");
+
+  void set v3(Result value) {
+    lastSetter = "E1.v3=$value";
+  }
+
+  // No other declarations with same basename.
+  Result get v4 => Result("E1.v4");
+
+  void set v4(Result value) {
+    lastSetter = "E1.v4=$value";
+  }
+
+  // Same basename as E2 setter.
+  Result get v5 => Result("E1.v5");
+}
+
+/// A different extension than [E1] on [C].
+///
+/// Declares [v5] setter.
+extension E2 on C {
+  void set v5(Result value) {
+    lastSetter = "E2.v5=$value";
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_import_hide_error_test.dart b/tests/language/extension_methods/static_extension_import_hide_error_test.dart
new file mode 100644
index 0000000..9a93aa0
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_hide_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" hide OnInt;
+
+void main() {
+  int i = 0;
+  Object o = i;
+  i.onInt;
+  //^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'onInt' isn't defined for the class 'int'.
+  i.onObject;
+  o.onObject;
+}
diff --git a/tests/language/extension_methods/static_extension_import_hide_test.dart b/tests/language/extension_methods/static_extension_import_hide_test.dart
new file mode 100644
index 0000000..33efb80
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_hide_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" hide OnInt;
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("object", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_hide_error_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_hide_error_test.dart
new file mode 100644
index 0000000..3c485e8
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_hide_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" as p1 hide OnInt;
+
+void main() {
+  int i = 0;
+  Object o = i;
+  i.onInt;
+  //^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'onInt' isn't defined for the class 'int'.
+  i.onObject;
+  o.onObject;
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_hide_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_hide_test.dart
new file mode 100644
index 0000000..eb24f4d
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_hide_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" as p1 hide OnInt;
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("object", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_show_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_show_test.dart
new file mode 100644
index 0000000..caae31c
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_show_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1 show OnObject;
+import "helpers/on_int.dart";
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("int", i.onInt);
+  Expect.equals("int", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_test.dart
new file mode 100644
index 0000000..bc64023
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1;
+import "helpers/on_int.dart";
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("int", i.onInt);
+  Expect.equals("int", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_test.dart b/tests/language/extension_methods/static_extension_import_test.dart
new file mode 100644
index 0000000..2585595
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart";
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("int", i.onInt);
+  Expect.equals("int", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_unprefixed_show_test.dart b/tests/language/extension_methods/static_extension_import_unprefixed_show_test.dart
new file mode 100644
index 0000000..5a45148
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_unprefixed_show_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" show OnObject;
+import "helpers/on_int.dart";
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("int", i.onInt);
+  Expect.equals("int", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_inference_test.dart b/tests/language/extension_methods/static_extension_inference_test.dart
new file mode 100644
index 0000000..4e1774e
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_inference_test.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension method resolution type inference.
+
+import "package:expect/expect.dart";
+
+void main() {
+  List<num> numList = <int>[];
+  // Inference of E1(numList), implicit or explicit, is the same as
+  // for C1(numList), which infers `num`.
+  var numListInstance1 = C1<num>(numList);
+
+  Expect.type<List<num>>(numList.argList1);
+  sameType(numListInstance1.argDynList1, numList.argDynList1);
+  sameType(numListInstance1.selfList1, numList.selfList1);
+
+  Expect.type<List<num>>(E1(numList).argList1);
+  sameType(numListInstance1.argDynList1, E1(numList).argDynList1);
+  sameType(numListInstance1.selfList1, E1(numList).selfList1);
+
+  var numListInstance2 = C2<List<num>>(numList);
+
+  Expect.type<List<List<num>>>(numList.argList2);
+  sameType(numListInstance2.argDynList2, numList.argDynList2);
+  sameType(numListInstance2.selfList2, numList.selfList2);
+
+  Expect.type<List<List<num>>>(E2(numList).argList2);
+  sameType(numListInstance2.argDynList2, E2(numList).argDynList2);
+  sameType(numListInstance2.selfList2, E2(numList).selfList2);
+
+  Pair<int, double> pair = Pair(1, 2.5);
+  var pairInstance3 = C3<int, double>(pair);
+
+  Expect.type<List<int>>(pair.argList3);
+  Expect.type<List<double>>(pair.arg2List3);
+  sameType(pairInstance3.argDynList3, pair.argDynList3);
+  sameType(pairInstance3.arg2DynList3, pair.arg2DynList3);
+  sameType(pairInstance3.selfList3, pair.selfList3);
+
+  Expect.type<List<int>>(E3(pair).argList3);
+  Expect.type<List<double>>(E3(pair).arg2List3);
+  sameType(pairInstance3.argDynList3, E3(pair).argDynList3);
+  sameType(pairInstance3.arg2DynList3, E3(pair).arg2DynList3);
+  sameType(pairInstance3.selfList3, E3(pair).selfList3);
+
+  var pairInstance4 = C4<num>(pair);
+
+  Expect.type<List<num>>(pair.argList4);
+  sameType(pairInstance4.argDynList4, pair.argDynList4);
+  sameType(pairInstance4.selfList4, pair.selfList4);
+
+  Expect.type<List<num>>(E4(pair).argList4);
+  sameType(pairInstance4.argDynList4, E4(pair).argDynList4);
+  sameType(pairInstance4.selfList4, E4(pair).selfList4);
+
+  List<int> intList = <int>[1];
+  var intListInstance5 = C5<int>(intList);
+
+  Expect.type<List<int>>(intList.argList5);
+  sameType(intListInstance5.argDynList5, intList.argDynList5);
+  sameType(intListInstance5.selfList5, intList.selfList5);
+
+  Expect.type<List<int>>(E5(intList).argList5);
+  sameType(intListInstance5.argDynList5, E5(intList).argDynList5);
+  sameType(intListInstance5.selfList5, E5(intList).selfList5);
+}
+
+void sameType(o1, o2) {
+  Expect.equals(o1.runtimeType, o2.runtimeType);
+}
+
+extension E1<T> on List<T> {
+  List<T> get argList1 => <T>[];
+  List<Object?> get argDynList1 => <T>[];
+  List<Object?> get selfList1 {
+    var result = [this];
+    return result;
+  }
+}
+
+class C1<T> {
+  List<T> self;
+  C1(this.self);
+  List<T> get argList1 => <T>[];
+  List<Object?> get argDynList1 => <T>[];
+  List<Object?> get selfList1 {
+    var result = [self];
+    return result;
+  }
+}
+
+extension E2<T> on T {
+  List<T> get argList2 => <T>[];
+  List<Object?> get argDynList2 => <T>[];
+  List<Object?> get selfList2 {
+    var result = [this];
+    return result;
+  }
+}
+
+class C2<T> {
+  T self;
+  C2(this.self);
+  List<T> get argList2 => <T>[];
+  List<Object?> get argDynList2 => <T>[];
+  List<Object?> get selfList2 {
+    var result = [self];
+    return result;
+  }
+}
+
+extension E3<S, T> on Pair<T, S> {
+  List<T> get argList3 => <T>[];
+  List<Object?> get argDynList3 => <T>[];
+  List<S> get arg2List3 => <S>[];
+  List<Object?> get arg2DynList3 => <S>[];
+  List<Object?> get selfList3 {
+    var result = [this];
+    return result;
+  }
+}
+
+class C3<T, S> {
+  Pair<T, S> self;
+  C3(this.self);
+  List<T> get argList3 => <T>[];
+  List<Object?> get argDynList3 => <T>[];
+  List<S> get arg2List3 => <S>[];
+  List<Object?> get arg2DynList3 => <S>[];
+  List<Object?> get selfList3 {
+    var result = [self];
+    return result;
+  }
+}
+
+extension E4<T> on Pair<T, T> {
+  List<T> get argList4 => <T>[];
+  List<Object?> get argDynList4 => <T>[];
+  List<Object?> get selfList4 {
+    var result = [this];
+    return result;
+  }
+}
+
+class C4<T> {
+  Pair<T, T> self;
+  C4(this.self);
+  List<T> get argList4 => <T>[];
+  List<Object?> get argDynList4 => <T>[];
+  List<Object?> get selfList4 {
+    var result = [self];
+    return result;
+  }
+}
+
+extension E5<T extends num> on List<T> {
+  List<T> get argList5 => <T>[];
+  List<Object?> get argDynList5 => <T>[];
+  List<Object?> get selfList5 {
+    var result = [this];
+    return result;
+  }
+}
+
+class C5<T extends num> {
+  List<T> self;
+  C5(this.self);
+  List<T> get argList5 => <T>[];
+  List<Object?> get argDynList5 => <T>[];
+  List<Object?> get selfList5 {
+    var result = [self];
+    return result;
+  }
+}
+
+class Pair<A, B> {
+  final A first;
+  final B second;
+  Pair(this.first, this.second);
+}
diff --git a/tests/language/extension_methods/static_extension_internal_basename_shadowing_error_test.dart b/tests/language/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
new file mode 100644
index 0000000..5c5c1c7
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
@@ -0,0 +1,505 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+///////////////////////////////////////////////////////////////////////
+// The following tests check that setters or getters in an extension
+// correctly shadow members with the same basename in the surrounding
+// scope.
+///////////////////////////////////////////////////////////////////////
+
+int get topLevelGetter => -1;
+void set topLevelSetter(int _) {}
+int topLevelField = -3;
+int topLevelMethod(int x) => -4;
+
+// Check that an instance getter in an extension shadows top level
+// members with the same basename.
+extension E1 on A1 {
+  int get topLevelSetter => 1;
+  int get topLevelField => 2;
+  int get topLevelMethod => 3;
+  void test() {
+    // The instance getter shadows the global setter
+    topLevelSetter = topLevelSetter + 1;
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+    topLevelSetter++;
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+    topLevelSetter = 0;
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+
+    // The instance getter shadows the global field setter
+    topLevelField = topLevelField + 1;
+//  ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+    topLevelField++;
+//  ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+    topLevelField = 0;
+//  ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+
+    // The instance getter shadows the global method
+    topLevelMethod(4);
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+//                ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+  }
+}
+
+class A1 {}
+
+// Check that an instance setter in an extension shadows top level
+// members with the same basename.
+extension E2 on A2 {
+  void set topLevelGetter(int _) {}
+  void set topLevelField(int _) {}
+  void set topLevelMethod(int _) {}
+  void test() {
+    // The instance setter shadows the global getter
+    topLevelGetter = topLevelGetter + 1;
+//                   ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+    topLevelGetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+    topLevelGetter;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+    topLevelGetter = 3;
+
+    // The instance setter shadows the global field getter
+    topLevelField = topLevelField + 1;
+//                  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+    topLevelField++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+    topLevelField;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+
+    // The instance setter shadows the global method
+    topLevelMethod(4);
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelMethod'.
+  }
+}
+
+class A2 {}
+
+// Check that a static getter in an extension shadows top level
+// members with the same basename.
+extension E3 on A3 {
+  static int get topLevelSetter => 1;
+  static int get topLevelField => 2;
+  static int get topLevelMethod => 3;
+  void test() {
+    // The static getter shadows the global setter
+    topLevelSetter = topLevelSetter + 1;
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+    topLevelSetter++;
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+    topLevelSetter = 0;
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+
+    // The static getter shadows the global field setter
+    topLevelField = topLevelField + 1;
+//  ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+    topLevelField++;
+//  ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+    topLevelField = 0;
+//  ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+
+    // The static getter shadows the global method
+    topLevelMethod(4);
+//  ^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+//                   ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+  }
+}
+
+class A3 {}
+
+// Check that a static setter in an extension shadows top level
+// members with the same basename.
+extension E4 on A4 {
+  static void set topLevelGetter(int _) {}
+  static void set topLevelField(int _) {}
+  static void set topLevelMethod(int _) {}
+  void test() {
+    // The static setter shadows the global getter
+    topLevelGetter = topLevelGetter + 1;
+//                   ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+    topLevelGetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+    topLevelGetter;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+
+    // The static setter shadows the global field getter
+    topLevelField = topLevelField + 1;
+//                  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+    topLevelField++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+    topLevelField;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+
+    // The static setter shadows the global method
+    topLevelMethod(4);
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelMethod'.
+  }
+}
+
+class A4 {}
+
+// Define extensions on A6.
+extension E5 on A6 {
+  void set extensionSetter(int _) {}
+  int extensionMethod(int x) => -3;
+}
+
+// Check that an instance getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E6 on A6 {
+  int get extensionSetter => 1;
+  int get extensionMethod => 3;
+  void test() {
+    // The instance getter shadows the other extension's setter
+    extensionSetter = extensionSetter + 1;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+    extensionSetter++;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+    extensionSetter = 0;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+
+    // The instance getter shadows the other extensions method
+    extensionMethod(4);
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+//                 ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+  }
+}
+
+class A6 {}
+
+// Check that an instance getter in a class shadows extension
+// members with the same basename from extension E5.
+class A7 extends A6 {
+  int get extensionSetter => 1;
+  int get extensionMethod => 3;
+  void test() {
+    // The instance getter shadows the other extension's setter
+    extensionSetter = extensionSetter + 1;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] The setter 'extensionSetter' isn't defined for the class 'A7'.
+    extensionSetter++;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] The setter 'extensionSetter' isn't defined for the class 'A7'.
+    extensionSetter = 0;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] The setter 'extensionSetter' isn't defined for the class 'A7'.
+
+    // The instance getter shadows the other extensions method
+    extensionMethod(4);
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+//                 ^
+// [cfe] 'extensionMethod' isn't a function or method and can't be invoked.
+  }
+}
+
+// Define extensions on A8.
+extension E7 on A8 {
+  int get extensionGetter => -1;
+  int extensionMethod(int x) => -3;
+}
+
+// Check that an instance setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E8 on A8 {
+  void set extensionGetter(int _) {}
+  void set extensionMethod(int _) {}
+  void test() {
+    // The instance setter shadows the other extension's getter
+    extensionGetter = extensionGetter + 1;
+//                    ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+    extensionGetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+    extensionGetter;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+
+    // The instance setter shadows the other extension's method.
+    extensionMethod(4);
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionMethod'.
+  }
+}
+
+class A8 {}
+
+// Check that an instance setter in a class shadows extension
+// members with the same basename from extension E7.
+class A9 extends A8 {
+  void set extensionGetter(int _) {}
+  void set extensionMethod(int _) {}
+  void test() {
+    // The instance setter shadows the other extension's getter
+    extensionGetter = extensionGetter + 1;
+//                    ^^
+// [analyzer] unspecified
+// [cfe] The getter 'extensionGetter' isn't defined for the class 'A9'.
+    extensionGetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] The getter 'extensionGetter' isn't defined for the class 'A9'.
+    extensionGetter;
+//  ^^
+// [analyzer] unspecified
+// [cfe] The getter 'extensionGetter' isn't defined for the class 'A9'.
+
+    // The instance setter shadows the other extension's method.
+    extensionMethod(4);
+//  ^^
+// [analyzer] unspecified
+// [cfe] The method 'extensionMethod' isn't defined for the class 'A9'.
+  }
+}
+
+// Define extensions on A10.
+extension E9 on A10 {
+  void set extensionSetter(int _) {}
+  void set extensionFieldSetter(int _) {}
+  int extensionMethod(int x) => -3;
+}
+
+// Check that a static getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E10 on A10 {
+  static int get extensionSetter => 1;
+  static final int extensionFieldSetter = 2;
+  static int get extensionMethod => 3;
+  void test() {
+    // The static getter shadows the other extension's setter
+    extensionSetter = extensionSetter + 1;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+    extensionSetter++;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+    extensionSetter = 0;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+
+    // The static field shadows the other extension's setter
+    extensionFieldSetter = extensionFieldSetter + 1;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+    extensionFieldSetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+    extensionFieldSetter = 0;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+
+    // The static getter shadows the other extensions method
+    extensionMethod(4);
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+//                     ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+  }
+}
+
+class A10 {}
+
+// Check that a static getter in a class shadows extension
+// members with the same basename from extension E9.
+class A11 extends A10 {
+  static int get extensionSetter => 1;
+  static final int extensionFieldSetter = 2;
+  static int get extensionMethod => 3;
+  void test() {
+    // The static getter shadows the other extension's setter
+    extensionSetter = extensionSetter + 1;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+    extensionSetter++;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+    extensionSetter = 0;
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+
+    // The static field shadows the other extension's setter
+    extensionFieldSetter = extensionFieldSetter + 1;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+    extensionFieldSetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+    extensionFieldSetter = 0;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+
+    // The static getter shadows the other extensions method
+    extensionMethod(4);
+//  ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+//                 ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+  }
+}
+
+// Define extensions on A12.
+extension E11 on A12 {
+  int get extensionGetter => -1;
+  int extensionMethod(int x) => -3;
+}
+
+// Check that a static setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E12 on A12 {
+  static void set extensionGetter(int _) {}
+  static void set extensionMethod(int _) {}
+  void test() {
+    // The static setter shadows the other extension's getter
+    extensionGetter = extensionGetter + 1;
+//                    ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+    extensionGetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+    extensionGetter;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+
+    // The static setter shadows the other extension's method.
+    extensionMethod(4);
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionMethod'.
+  }
+}
+
+class A12 {}
+
+// Check that a static setter in a class shadows extension
+// members with the same basename from extension E11.
+class A13 extends A12 {
+  static void set extensionGetter(int _) {}
+  static void set extensionMethod(int _) {}
+  void test() {
+    // The static setter shadows the other extension's getter
+    extensionGetter = extensionGetter + 1;
+//                    ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+    extensionGetter++;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+    extensionGetter;
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+
+    // The static setter shadows the other extension's method.
+    extensionMethod(4);
+//  ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionMethod'.
+  }
+}
+
+void main() {
+  A1().test();
+  A2().test();
+  A3().test();
+  A4().test();
+  A6().test();
+  A7().test();
+  A8().test();
+  A9().test();
+  A10().test();
+  A11().test();
+  A12().test();
+  A13().test();
+}
diff --git a/tests/language/extension_methods/static_extension_internal_basename_shadowing_test.dart b/tests/language/extension_methods/static_extension_internal_basename_shadowing_test.dart
new file mode 100644
index 0000000..659bcc2
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_basename_shadowing_test.dart
@@ -0,0 +1,276 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+///////////////////////////////////////////////////////////////////////
+// The following tests check that setters or getters in an extension
+// correctly shadow members with the same basename in the surrounding
+// scope.
+///////////////////////////////////////////////////////////////////////
+
+String get topLevelGetter => "-1";
+void set topLevelSetter(String _) {}
+String topLevelField = "-3";
+String topLevelMethod(String x) => "-4";
+
+// Location that extension setters write to.
+int? _storeTo = null;
+// Check that the most recent setter call set the value
+// of _storeTo.
+void checkSetter(int x) {
+  int? written = _storeTo;
+  _storeTo = null;
+  Expect.equals(written, x);
+}
+
+// Check that an instance getter in an extension shadows top level
+// members with the same basename.
+extension E1 on A1 {
+  int get topLevelSetter => 1;
+  int get topLevelField => 2;
+  int get topLevelMethod => 3;
+  void test() {
+    // Reading the local getters is valid
+    Expect.equals(topLevelSetter + 1, 2);
+    Expect.equals(topLevelField + 1, 3);
+    Expect.equals(topLevelMethod + 1, 4);
+  }
+}
+
+class A1 {}
+
+// Check that an instance setter in an extension shadows top level
+// members with the same basename.
+extension E2 on A2 {
+  void set topLevelGetter(int x) {
+    _storeTo = x;
+  }
+
+  void set topLevelField(int x) {
+    _storeTo = x;
+  }
+
+  void set topLevelMethod(int x) {
+    _storeTo = x;
+  }
+
+  void test() {
+    checkSetter(topLevelGetter = 42);
+    checkSetter(topLevelField = 42);
+    checkSetter(topLevelMethod = 42);
+  }
+}
+
+class A2 {}
+
+// Check that a static getter in an extension shadows top level
+// members with the same basename.
+extension E3 on A3 {
+  static int get topLevelSetter => 1;
+  static int get topLevelField => 2;
+  static int get topLevelMethod => 3;
+  void test() {
+    // Reading the local getters is valid
+    Expect.equals(topLevelSetter + 1, 2);
+    Expect.equals(topLevelField + 1, 3);
+    Expect.equals(topLevelMethod + 1, 4);
+  }
+}
+
+class A3 {}
+
+// Check that a static setter in an extension shadows top level
+// members with the same basename.
+extension E4 on A4 {
+  static void set topLevelGetter(int x) {
+    _storeTo = x;
+  }
+
+  static void set topLevelField(int x) {
+    _storeTo = x;
+  }
+
+  static void set topLevelMethod(int x) {
+    _storeTo = x;
+  }
+
+  void test() {
+    checkSetter(topLevelGetter = 42);
+    checkSetter(topLevelField = 42);
+    checkSetter(topLevelMethod = 42);
+  }
+}
+
+class A4 {}
+
+// Define extensions on A6.
+extension E5 on A6 {
+  void set extensionSetter(int x) {}
+  int extensionMethod(int x) => -3;
+}
+
+// Check that an instance getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E6 on A6 {
+  int get extensionSetter => 1;
+  int get extensionMethod => 3;
+  void test() {
+    // Reading the local getters is valid
+    Expect.equals(extensionSetter + 1, 2);
+    Expect.equals(extensionMethod + 1, 4);
+  }
+}
+
+class A6 {}
+
+// Check that an instance getter in a class shadows extension
+// members with the same basename from extension E5.
+class A7 extends A6 {
+  int get extensionSetter => 1;
+  int get extensionMethod => 3;
+  void test() {
+    // Reading the local getters is valid
+    Expect.equals(extensionSetter + 1, 2);
+    Expect.equals(extensionMethod + 1, 4);
+  }
+}
+
+// Define extensions on A8.
+extension E7 on A8 {
+  int get extensionGetter => -1;
+  int extensionMethod(int x) => -3;
+}
+
+// Check that an instance setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E8 on A8 {
+  void set extensionGetter(int x) {
+    _storeTo = x;
+  }
+
+  void set extensionMethod(int x) {
+    _storeTo = x;
+  }
+
+  void test() {
+    checkSetter(extensionGetter = 42);
+    checkSetter(extensionMethod = 42);
+  }
+}
+
+class A8 {}
+
+// Check that an instance setter in a class shadows extension
+// members with the same basename from extension E7.
+class A9 extends A8 {
+  void set extensionGetter(int x) {
+    _storeTo = x;
+  }
+
+  void set extensionMethod(int x) {
+    _storeTo = x;
+  }
+
+  void test() {
+    checkSetter(extensionGetter = 42);
+    checkSetter(extensionMethod = 42);
+  }
+}
+
+// Define extensions on A10.
+extension E9 on A10 {
+  void set extensionSetter(int x) {}
+  void set extensionFieldSetter(int x) {}
+  int extensionMethod(int x) => -3;
+}
+
+// Check that a static getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E10 on A10 {
+  static int get extensionSetter => 1;
+  static final int extensionFieldSetter = 2;
+  static int get extensionMethod => 3;
+  void test() {
+    // Reading the local getters is valid
+    Expect.equals(extensionSetter + 1, 2);
+    Expect.equals(extensionFieldSetter + 1, 3);
+    Expect.equals(extensionMethod + 1, 4);
+  }
+}
+
+class A10 {}
+
+// Check that a static getter in a class shadows extension
+// members with the same basename from extension E9.
+class A11 extends A10 {
+  static int get extensionSetter => 1;
+  static final int extensionFieldSetter = 2;
+  static int get extensionMethod => 3;
+  void test() {
+    // Reading the local getters is valid
+    Expect.equals(extensionSetter + 1, 2);
+    Expect.equals(extensionFieldSetter + 1, 3);
+    Expect.equals(extensionMethod + 1, 4);
+  }
+}
+
+// Define extensions on A12.
+extension E11 on A12 {
+  int get extensionGetter => -1;
+  int extensionMethod(int x) => -3;
+}
+
+// Check that a static setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E12 on A12 {
+  static void set extensionGetter(int x) {
+    _storeTo = x;
+  }
+
+  static void set extensionMethod(int x) {
+    _storeTo = x;
+  }
+
+  void test() {
+    checkSetter(extensionGetter = 42);
+    checkSetter(extensionMethod = 42);
+  }
+}
+
+class A12 {}
+
+// Check that a static setter in a class shadows extension
+// members with the same basename from extension E11.
+class A13 extends A12 {
+  static void set extensionGetter(int x) {
+    _storeTo = x;
+  }
+
+  static void set extensionMethod(int x) {
+    _storeTo = x;
+  }
+
+  void test() {
+    checkSetter(extensionGetter = 42);
+    checkSetter(extensionMethod = 42);
+  }
+}
+
+void main() {
+  A1().test();
+  A2().test();
+  A3().test();
+  A4().test();
+  A6().test();
+  A7().test();
+  A8().test();
+  A9().test();
+  A10().test();
+  A11().test();
+  A12().test();
+  A13().test();
+}
diff --git a/tests/language/extension_methods/static_extension_internal_name_conflict_error_test.dart b/tests/language/extension_methods/static_extension_internal_name_conflict_error_test.dart
new file mode 100644
index 0000000..a284784
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_name_conflict_error_test.dart
@@ -0,0 +1,258 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests that errors are given for internal name conflicts in extension methods.
+
+// It is an error to have duplicate type parameter names.
+extension E1<T, T> on int {
+//              ^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] A type variable can't have the same name as another.
+}
+
+extension E2 on int {}
+
+// It is an error to have duplicate extension names.
+extension E2 on int {}
+//        ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+class E2 {}
+//    ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+typedef E2 = int Function(int);
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+void E2(int x) {}
+//   ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+int E2 = 3;
+//  ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+////////////////////////////////////////////////////////////////////
+// It is an error to have two static members with the same base name
+// unless one is a setter and one is a getter.
+//
+// The next set of tests check various combinations of member name
+// conflicts: first testing that members of the same kind (e.g.
+// method/method) induce conflicts for the various combinations of
+// static/instance; and then testing that members of different kind (e.g.
+// method/getter) induce conflicts for the various combinations of
+// static/instance.
+////////////////////////////////////////////////////////////////////
+
+// Check static members colliding with static members (of the same kind)
+extension E3 on int {
+  static int method() => 0;
+  static int get property => 1;
+  static void set property(int value) {}
+  static int field = 3;
+  static int field2 = 4;
+
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'method' is already declared in this scope.
+  static int get property => 1;
+  //             ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'property' is already declared in this scope.
+  static void set property(int value) {}
+  //              ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'property' is already declared in this scope.
+  static int field = 3;
+  //         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'field' is already declared in this scope.
+  static int get field2 => 1;
+  //             ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'field2' is already declared in this scope.
+  static void set field2(int value) {}
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+}
+
+// Check instance members colliding with instance members (of the same kind).
+extension E4 on int {
+  int method() => 0;
+  int get property => 1;
+  void set property(int value) {}
+
+  int method() => 0;
+  //  ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'method' is already declared in this scope.
+  int get property => 1;
+  //      ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'property' is already declared in this scope.
+  void set property(int value) {}
+  //       ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'property' is already declared in this scope.
+}
+
+// Check static members colliding with static members (of the same kind).
+extension E5 on int {
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  static int get property => 1;
+  //             ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  static void set property(int value) {}
+  //              ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  static int get property2 => 1;
+  //             ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Conflicts with setter 'property2'.
+  static void set property3(int x) {}
+  //              ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Conflicts with member 'property3'.
+  static int field = 3;
+  //         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Conflicts with setter 'field'.
+  static int field2 = 3;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+
+  int method() => 0;
+  //  ^
+  // [cfe] 'method' is already declared in this scope.
+  int get property => 1;
+  //      ^
+  // [cfe] 'property' is already declared in this scope.
+  void set property(int value) {}
+  //       ^
+  // [cfe] 'property' is already declared in this scope.
+  void set property2(int value) {}
+  //       ^
+  // [cfe] Conflicts with member 'property2'.
+  int get property3 => 1;
+  //      ^
+  // [cfe] Conflicts with setter 'property3'.
+  void set field(int value) {}
+  //       ^
+  // [cfe] Conflicts with member 'field'.
+  int get field2 => 1;
+  //      ^
+  // [cfe] 'field2' is already declared in this scope.
+}
+
+// Check a static method colliding with a static getter.
+extension E6 on int {
+  static int method() => 0;
+  static int get method => 1;
+  //             ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'method' is already declared in this scope.
+}
+
+// Check a static method colliding with a static setter.
+extension E7 on int {
+  static int method() => 0;
+  //         ^
+  // [cfe] Conflicts with setter 'method'.
+  static void set method(int value) {}
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] Conflicts with member 'method'.
+}
+
+// Check a static method colliding with a static field.
+extension E8 on int {
+  static int method() => 0;
+  static int method = 3;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'method' is already declared in this scope.
+}
+
+// Check an instance method colliding with an instance getter.
+extension E9 on int {
+  int method() => 0;
+  int get method => 1;
+  //      ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'method' is already declared in this scope.
+}
+
+// Check an instance method colliding with an instance setter.
+extension E10 on int {
+  int method() => 0;
+  //  ^
+  // [cfe] Conflicts with setter 'method'.
+  void set method(int value) {}
+  //       ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] Conflicts with member 'method'.
+}
+
+// Check a static method colliding with an instance getter.
+extension E11 on int {
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  int get method => 1;
+  //      ^
+  // [cfe] 'method' is already declared in this scope.
+}
+
+// Check a static method colliding with an instance setter.
+extension E12 on int {
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Conflicts with setter 'method'.
+  void set method(int value) {}
+  //       ^
+  // [cfe] Conflicts with member 'method'.
+}
+
+// Check an instance method colliding with a static getter.
+extension E13 on int {
+  int method() => 0;
+  static int get method => 1;
+  //             ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] 'method' is already declared in this scope.
+}
+
+// Check an instance method colliding with a static setter.
+extension E14 on int {
+  int method() => 0;
+  //  ^
+  // [cfe] Conflicts with setter 'method'.
+  static void set method(int value) {}
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Conflicts with member 'method'.
+}
+
+// Check an instance method colliding with a static field.
+extension E15 on int {
+  int method() => 0;
+  static int method = 3;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] 'method' is already declared in this scope.
+}
+
+void main() {}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_0_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_0_test.dart
new file mode 100644
index 0000000..418ba2b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_0_test.dart
@@ -0,0 +1,208 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test an extension MyExt with no members against:
+//   - a class A with only its own members
+//   - and another extension ExtraExt with only its own members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with no overlapping symbols into scope.
+import "helpers/extension_only.dart";
+
+const bool extensionValue = true;
+
+// An extension which defines no members of its own
+extension MyExt on A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of the other extension (when present)
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = this.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = this.getterInInstanceScope;
+      checkInstanceValue(t0);
+      this.setterInInstanceScope = instanceValue;
+      String t2 = this.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension.
+    {
+      double t0 = this.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = this.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      this.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = this.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = self.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = self.getterInInstanceScope;
+      checkInstanceValue(t1);
+      self.setterInInstanceScope = instanceValue;
+      String t2 = self.methodInInstanceScope();
+      checkInstanceValue(t2);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension.
+    {
+      double t0 = self.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = self.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      self.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = self.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of the other extension (when present)
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    String t0 = a.fieldInInstanceScope;
+    checkInstanceValue(t0);
+    String t1 = a.getterInInstanceScope;
+    checkInstanceValue(t1);
+    a.setterInInstanceScope = instanceValue;
+    String t2 = a.methodInInstanceScope();
+    checkInstanceValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    double t0 = a.fieldInOtherExtensionScope;
+    checkOtherExtensionValue(t0);
+    double t1 = a.getterInOtherExtensionScope;
+    checkOtherExtensionValue(t1);
+    a.setterInOtherExtensionScope = otherExtensionValue;
+    double t2 = a.methodInOtherExtensionScope();
+    checkOtherExtensionValue(t2);
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_1_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_1_test.dart
new file mode 100644
index 0000000..052ab86
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_1_test.dart
@@ -0,0 +1,244 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test an extension MyExt with no members against:
+//   - a class A with only its own members
+//   - and an extension ExtraExt which overlaps the global and class members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt that overlaps the global and instance names
+// into scope.
+import "helpers/extension_global_instance.dart";
+
+const bool extensionValue = true;
+
+// An extension which defines no members of its own
+extension MyExt on A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of the other extension (when present)
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Global symbols prefixed by `this` resolve to the version on the other
+    // extension
+    {
+      double t0 = this.fieldInGlobalScope;
+      checkOtherExtensionValue(t0);
+      double t1 = this.getterInGlobalScope;
+      checkOtherExtensionValue(t1);
+      this.setterInGlobalScope = otherExtensionValue;
+      double t2 = this.methodInGlobalScope();
+      checkOtherExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = this.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = this.getterInInstanceScope;
+      checkInstanceValue(t0);
+      this.setterInInstanceScope = instanceValue;
+      String t2 = this.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension.
+    {
+      double t0 = this.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = this.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      this.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = this.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Global symbols on an instance resolve to the version on the other
+    // extension
+    {
+      double t0 = self.fieldInGlobalScope;
+      checkOtherExtensionValue(t0);
+      double t1 = self.getterInGlobalScope;
+      checkOtherExtensionValue(t1);
+      self.setterInGlobalScope = otherExtensionValue;
+      double t2 = self.methodInGlobalScope();
+      checkOtherExtensionValue(t2);
+    }
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = self.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = self.getterInInstanceScope;
+      checkInstanceValue(t1);
+      self.setterInInstanceScope = instanceValue;
+      String t2 = self.methodInInstanceScope();
+      checkInstanceValue(t2);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension.
+    {
+      double t0 = self.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = self.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      self.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = self.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of the other extension (when present)
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Global symbols on an instance resolve to the version on the other
+  // extension
+  {
+    double t0 = a.fieldInGlobalScope;
+    checkOtherExtensionValue(t0);
+    double t1 = a.getterInGlobalScope;
+    checkOtherExtensionValue(t1);
+    a.setterInGlobalScope = otherExtensionValue;
+    double t2 = a.methodInGlobalScope();
+    checkOtherExtensionValue(t2);
+  }
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    String t0 = a.fieldInInstanceScope;
+    checkInstanceValue(t0);
+    String t1 = a.getterInInstanceScope;
+    checkInstanceValue(t1);
+    a.setterInInstanceScope = instanceValue;
+    String t2 = a.methodInInstanceScope();
+    checkInstanceValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    double t0 = a.fieldInOtherExtensionScope;
+    checkOtherExtensionValue(t0);
+    double t1 = a.getterInOtherExtensionScope;
+    checkOtherExtensionValue(t1);
+    a.setterInOtherExtensionScope = otherExtensionValue;
+    double t2 = a.methodInOtherExtensionScope();
+    checkOtherExtensionValue(t2);
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_2_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_2_test.dart
new file mode 100644
index 0000000..861bb4b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_2_test.dart
@@ -0,0 +1,325 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test an extension MyExt with members whose names overlap with names from the
+// global, and instance scopes:
+//   - a class A with only its own members
+//   - an extension ExtraExt which has only its own members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with no overlapping symbols into scope.
+import "helpers/extension_only.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+// An extension which defines all members
+extension MyExt on A {
+  bool get fieldInGlobalScope => true;
+  bool get getterInGlobalScope => true;
+  set setterInGlobalScope(bool x) {
+    Expect.equals(true, x);
+  }
+
+  bool methodInGlobalScope() => true;
+
+  bool get fieldInInstanceScope => true;
+  bool get getterInInstanceScope => true;
+  set setterInInstanceScope(bool x) {
+    Expect.equals(true, x);
+  }
+
+  bool methodInInstanceScope() => true;
+
+  bool get fieldInExtensionScope => true;
+  bool get getterInExtensionScope => true;
+  set setterInExtensionScope(bool x) {
+    Expect.equals(true, x);
+  }
+
+  bool methodInExtensionScope() => true;
+
+  void testNakedIdentifiers() {
+    // Globals should resolve to local extension versions
+    {
+      bool t0 = fieldInGlobalScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInGlobalScope;
+      checkExtensionValue(t1);
+      setterInGlobalScope = extensionValue;
+      bool t2 = methodInGlobalScope();
+      checkExtensionValue(t2);
+    }
+
+    // Un-prefixed instance members resolve to the local extension versions
+    {
+      bool t0 = fieldInInstanceScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInInstanceScope;
+      checkExtensionValue(t0);
+      setterInInstanceScope = extensionValue;
+      bool t2 = methodInInstanceScope();
+      checkExtensionValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in this extension
+    {
+      bool t0 = fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+      bool t2 = methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension (unresolved identifier "id" gets turned into
+    // "this.id", which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Globals should resolve to local extension versions
+    {
+      bool t0 = this.fieldInGlobalScope;
+      checkExtensionValue(t0);
+      bool t1 = this.getterInGlobalScope;
+      checkExtensionValue(t1);
+      this.setterInGlobalScope = extensionValue;
+      bool t2 = this.methodInGlobalScope();
+      checkExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the extension
+    {
+      String t0 = this.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = this.getterInInstanceScope;
+      checkInstanceValue(t0);
+      this.setterInInstanceScope = instanceValue;
+      String t2 = this.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods on this extension
+    {
+      bool t0 = this.fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = this.getterInExtensionScope;
+      checkExtensionValue(t1);
+      this.setterInExtensionScope = extensionValue;
+      bool t2 = this.methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      double t0 = this.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = this.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      this.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = this.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Globals should resolve to local extension versions
+    {
+      bool t0 = self.fieldInGlobalScope;
+      checkExtensionValue(t0);
+      bool t1 = self.getterInGlobalScope;
+      checkExtensionValue(t1);
+      self.setterInGlobalScope = extensionValue;
+      bool t2 = self.methodInGlobalScope();
+      checkExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the extension
+    {
+      String t0 = self.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = self.getterInInstanceScope;
+      checkInstanceValue(t0);
+      self.setterInInstanceScope = instanceValue;
+      String t2 = self.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods on this extension
+    {
+      bool t0 = self.fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = self.getterInExtensionScope;
+      checkExtensionValue(t1);
+      self.setterInExtensionScope = extensionValue;
+      bool t2 = self.methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      double t0 = self.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = self.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      self.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = self.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of the other extension (when present)
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members defined only in this extension resolve correctly.
+    {
+      bool t0 = fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+      bool t2 = methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members defined in the external extension resolve correctly
+    // (an unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Global symbols on an instance resolve to the version on this
+  // extension
+  {
+    bool t0 = a.fieldInGlobalScope;
+    checkExtensionValue(t0);
+    bool t1 = a.getterInGlobalScope;
+    checkExtensionValue(t1);
+    a.setterInGlobalScope = extensionValue;
+    bool t2 = a.methodInGlobalScope();
+    checkExtensionValue(t2);
+  }
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    String t0 = a.fieldInInstanceScope;
+    checkInstanceValue(t0);
+    String t1 = a.getterInInstanceScope;
+    checkInstanceValue(t1);
+    a.setterInInstanceScope = instanceValue;
+    String t2 = a.methodInInstanceScope();
+    checkInstanceValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in this
+  // extension.
+  {
+    bool t0 = a.fieldInExtensionScope;
+    checkExtensionValue(t0);
+    bool t1 = a.getterInExtensionScope;
+    checkExtensionValue(t1);
+    a.setterInExtensionScope = extensionValue;
+    bool t2 = a.methodInExtensionScope();
+    checkExtensionValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    double t0 = a.fieldInOtherExtensionScope;
+    checkOtherExtensionValue(t0);
+    double t1 = a.getterInOtherExtensionScope;
+    checkOtherExtensionValue(t1);
+    a.setterInOtherExtensionScope = otherExtensionValue;
+    double t2 = a.methodInOtherExtensionScope();
+    checkOtherExtensionValue(t2);
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_3_error_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_3_error_test.dart
new file mode 100644
index 0000000..b0409f9
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_3_error_test.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+//   - a class A with only its own members
+//   - an extension ExtraExt which has global and instance members as well as
+//     its own
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with members that overlap the global and instance
+// names into scope.
+import "helpers/extension_global_instance.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+// An extension which defines members of its own, as well members overlapping
+// the instance and global names.
+extension MyExt on A {
+  bool get fieldInGlobalScope => extensionValue;
+  bool get getterInGlobalScope => extensionValue;
+  set setterInGlobalScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInGlobalScope() => extensionValue;
+
+  bool get fieldInInstanceScope => extensionValue;
+  bool get getterInInstanceScope => extensionValue;
+  set setterInInstanceScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInInstanceScope() => extensionValue;
+
+  bool get fieldInExtensionScope => extensionValue;
+  bool get getterInExtensionScope => extensionValue;
+  set setterInExtensionScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInExtensionScope() => extensionValue;
+
+  void testNakedIdentifiers() {
+    // Globals should resolve to local extension versions
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Un-prefixed instance members resolve to the local extension versions
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members resolve to the extension methods in this extension
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension (unresolved identifier "id" gets turned into
+    // "this.id", which is then subject to extension method lookup).
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Prefixed globals are ambiguous
+    {
+      bool t0 = this.fieldInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t0);
+      bool t1 = this.getterInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t1);
+      this.setterInGlobalScope = extensionValue;
+      //   ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      bool t2 = this.methodInGlobalScope();
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of either extension
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members resolve to the extension methods on this extension
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Prefixed globals are ambiguous
+    {
+      bool t0 = self.fieldInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t0);
+      bool t1 = self.getterInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t1);
+      self.setterInGlobalScope = extensionValue;
+      //   ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      bool t2 = self.methodInGlobalScope();
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the extension
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members resolve to the extension methods on this extension
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of either extension
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members resolve to the extension methods in the local
+    // extension.
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      // No errors: see static_extension_internal_resolution_3_test.dart
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Global names come from both extensions and hence are ambiguous.
+  {
+    bool t0 = a.fieldInGlobalScope;
+    //          ^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t0);
+    bool t1 = a.getterInGlobalScope;
+    //          ^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t1);
+    a.setterInGlobalScope = extensionValue;
+    //^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    bool t2 = a.methodInGlobalScope();
+    //          ^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t2);
+  }
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    // No errors: see static_extension_internal_resolution_3_test.dart
+  }
+
+  // Extension members resolve to the extension methods in this
+  // extension.
+  {
+    // No errors: see static_extension_internal_resolution_3_test.dart
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    // No errors: see static_extension_internal_resolution_3_test.dart
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_3_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_3_test.dart
new file mode 100644
index 0000000..f6c57e9
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_3_test.dart
@@ -0,0 +1,309 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the non error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+//   - a class A with only its own members
+//   - an extension ExtraExt which has global and instance members as well as
+//     its own
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with members that overlap the global and instance
+// names into scope.
+import "helpers/extension_global_instance.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+// An extension which defines members of its own, as well members overlapping
+// the instance and global names.
+extension MyExt on A {
+  bool get fieldInGlobalScope => extensionValue;
+  bool get getterInGlobalScope => extensionValue;
+  set setterInGlobalScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInGlobalScope() => extensionValue;
+
+  bool get fieldInInstanceScope => extensionValue;
+  bool get getterInInstanceScope => extensionValue;
+  set setterInInstanceScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInInstanceScope() => extensionValue;
+
+  bool get fieldInExtensionScope => extensionValue;
+  bool get getterInExtensionScope => extensionValue;
+  set setterInExtensionScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInExtensionScope() => extensionValue;
+
+  void testNakedIdentifiers() {
+    // Globals should resolve to local extension versions
+    {
+      bool t0 = fieldInGlobalScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInGlobalScope;
+      checkExtensionValue(t1);
+      setterInGlobalScope = extensionValue;
+      bool t2 = methodInGlobalScope();
+      checkExtensionValue(t2);
+    }
+
+    // Un-prefixed instance members resolve to the local extension versions
+    {
+      bool t0 = fieldInInstanceScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInInstanceScope;
+      checkExtensionValue(t0);
+      setterInInstanceScope = extensionValue;
+      bool t2 = methodInInstanceScope();
+      checkExtensionValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in this extension
+    {
+      bool t0 = fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+      bool t2 = methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension (unresolved identifier "id" gets turned into
+    // "this.id", which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Prefixed globals are ambiguous
+    {
+      // Error cases tested in static_extension_internal_resolution_3_error_test.dart
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of either extension
+    {
+      String t0 = this.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = this.getterInInstanceScope;
+      checkInstanceValue(t0);
+      this.setterInInstanceScope = instanceValue;
+      String t2 = this.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods on this extension
+    {
+      bool t0 = this.fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = this.getterInExtensionScope;
+      checkExtensionValue(t1);
+      this.setterInExtensionScope = extensionValue;
+      bool t2 = this.methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      double t0 = this.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = this.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      this.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = this.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Prefixed globals are ambiguous
+    {
+      // Error cases tested in static_extension_internal_resolution_3_error_test.dart
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the extension
+    {
+      String t0 = self.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = self.getterInInstanceScope;
+      checkInstanceValue(t0);
+      self.setterInInstanceScope = instanceValue;
+      String t2 = self.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members resolve to the extension methods on this extension
+    {
+      bool t0 = self.fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = self.getterInExtensionScope;
+      checkExtensionValue(t1);
+      self.setterInExtensionScope = extensionValue;
+      bool t2 = self.methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      double t0 = self.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = self.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      self.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = self.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of either extension
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members defined internally resolve correctly.
+    {
+      bool t0 = fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+      bool t2 = methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members defined elsewhere resolve correctly
+    // (an unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Global names come from both extensions and hence are ambiguous.
+  {
+    // Error cases tested in static_extension_internal_resolution_3_error_test.dart
+  }
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    String t0 = a.fieldInInstanceScope;
+    checkInstanceValue(t0);
+    String t1 = a.getterInInstanceScope;
+    checkInstanceValue(t1);
+    a.setterInInstanceScope = instanceValue;
+    String t2 = a.methodInInstanceScope();
+    checkInstanceValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in this
+  // extension.
+  {
+    bool t0 = a.fieldInExtensionScope;
+    checkExtensionValue(t0);
+    bool t1 = a.getterInExtensionScope;
+    checkExtensionValue(t1);
+    a.setterInExtensionScope = extensionValue;
+    bool t2 = a.methodInExtensionScope();
+    checkExtensionValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    double t0 = a.fieldInOtherExtensionScope;
+    checkOtherExtensionValue(t0);
+    double t1 = a.getterInOtherExtensionScope;
+    checkOtherExtensionValue(t1);
+    a.setterInOtherExtensionScope = otherExtensionValue;
+    double t2 = a.methodInOtherExtensionScope();
+    checkOtherExtensionValue(t2);
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_4_error_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_4_error_test.dart
new file mode 100644
index 0000000..6cd8d4b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_4_error_test.dart
@@ -0,0 +1,338 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+//   - a class A with only its own members
+//   - an extension ExtraExt which has members overlapping the global names,
+//     the instance names from A, and the extension names from MyExt, as well as
+//     its own names.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with symbols that overlap the global, instance,
+// and extension names into scope.
+import "helpers/extension_all.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+// An extension which defines its own members
+extension MyExt on A {
+  bool get fieldInGlobalScope => extensionValue;
+  bool get getterInGlobalScope => extensionValue;
+  set setterInGlobalScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInGlobalScope() => extensionValue;
+
+  bool get fieldInInstanceScope => extensionValue;
+  bool get getterInInstanceScope => extensionValue;
+  set setterInInstanceScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInInstanceScope() => extensionValue;
+
+  bool get fieldInExtensionScope => extensionValue;
+  bool get getterInExtensionScope => extensionValue;
+  set setterInExtensionScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInExtensionScope() => extensionValue;
+
+  void testNakedIdentifiers() {
+    // Globals should resolve to local extension versions
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Un-prefixed instance members resolve to the local extension versions
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Extension members resolve to the extension methods in this extension
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension (unresolved identifier "id" gets turned into
+    // "this.id", which is then subject to extension method lookup).
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Prefixed globals are ambiguous
+    {
+      bool t0 = this.fieldInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t0);
+      bool t1 = this.getterInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t1);
+      this.setterInGlobalScope = extensionValue;
+      //   ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      bool t2 = this.methodInGlobalScope();
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of either extension
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Extension members are ambigious.
+    {
+      bool t0 = this.fieldInExtensionScope;
+      //             ^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t0);
+      bool t1 = this.getterInExtensionScope;
+      //             ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t1);
+      this.setterInExtensionScope = extensionValue;
+      //   ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      bool t2 = this.methodInExtensionScope();
+      //             ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Prefixed globals are ambiguous
+    {
+      bool t0 = self.fieldInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t0);
+      bool t1 = self.getterInGlobalScope;
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t1);
+      self.setterInGlobalScope = extensionValue;
+      //   ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      bool t2 = self.methodInGlobalScope();
+      //             ^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the extension
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Extension members are ambigious.
+    {
+      bool t0 = self.fieldInExtensionScope;
+      //             ^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t0);
+      bool t1 = self.getterInExtensionScope;
+      //             ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t1);
+      self.setterInExtensionScope = extensionValue;
+      //   ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      bool t2 = self.methodInExtensionScope();
+      //             ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of either extension
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+
+    // Extension members are ambiguous
+    {
+      bool t0 = fieldInExtensionScope;
+      //        ^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+      //        ^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      //        ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+      //        ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+//    ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+// [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+//    ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+      bool t2 = methodInExtensionScope();
+      //        ^^^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+      // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+      checkExtensionValue(t2);
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      // No errors: see static_extension_internal_resolution_4_test.dart
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Global names come from both extensions and hence are ambiguous.
+  {
+    bool t0 = a.fieldInGlobalScope;
+    //          ^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t0);
+    bool t1 = a.getterInGlobalScope;
+    //          ^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t1);
+    a.setterInGlobalScope = extensionValue;
+    //^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    bool t2 = a.methodInGlobalScope();
+    //          ^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t2);
+  }
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    // No errors: see static_extension_internal_resolution_4_test.dart
+  }
+
+  // Extension members are ambiguous
+  {
+    bool t0 = a.fieldInExtensionScope;
+    //          ^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t0);
+    bool t1 = a.getterInExtensionScope;
+    //          ^^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t1);
+    a.setterInExtensionScope = extensionValue;
+    //^^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+    bool t2 = a.methodInExtensionScope();
+    //          ^^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+    // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+    checkExtensionValue(t2);
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    // No errors: see static_extension_internal_resolution_4_test.dart
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_4_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_4_test.dart
new file mode 100644
index 0000000..93955cb
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_4_test.dart
@@ -0,0 +1,284 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the non error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+//   - a class A with only its own members
+//   - an extension ExtraExt which has members overlapping the global names,
+//     the instance names from A, and the extension names from MyExt, as well as
+//     its own names.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with symbols that overlap the global, instance,
+// and extension names into scope.
+import "helpers/extension_all.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+// An extension which defines its own members
+extension MyExt on A {
+  bool get fieldInGlobalScope => extensionValue;
+  bool get getterInGlobalScope => extensionValue;
+  set setterInGlobalScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInGlobalScope() => extensionValue;
+
+  bool get fieldInInstanceScope => extensionValue;
+  bool get getterInInstanceScope => extensionValue;
+  set setterInInstanceScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInInstanceScope() => extensionValue;
+
+  bool get fieldInExtensionScope => extensionValue;
+  bool get getterInExtensionScope => extensionValue;
+  set setterInExtensionScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInExtensionScope() => extensionValue;
+
+  void testNakedIdentifiers() {
+    // Globals should resolve to local extension versions
+    {
+      bool t0 = fieldInGlobalScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInGlobalScope;
+      checkExtensionValue(t1);
+      setterInGlobalScope = extensionValue;
+      bool t2 = methodInGlobalScope();
+      checkExtensionValue(t2);
+    }
+
+    // Un-prefixed instance members resolve to the local extension versions
+    {
+      bool t0 = fieldInInstanceScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInInstanceScope;
+      checkExtensionValue(t0);
+      setterInInstanceScope = extensionValue;
+      bool t2 = methodInInstanceScope();
+      checkExtensionValue(t0);
+    }
+
+    // Extension members resolve to the extension methods in this extension
+    {
+      bool t0 = fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+      bool t2 = methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension (unresolved identifier "id" gets turned into
+    // "this.id", which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnThis() {
+    // Prefixed globals are ambiguous
+    {
+      // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of either extension
+    {
+      String t0 = this.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = this.getterInInstanceScope;
+      checkInstanceValue(t0);
+      this.setterInInstanceScope = instanceValue;
+      String t2 = this.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members are ambigious.
+    {
+      // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      double t0 = this.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = this.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      this.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = this.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void testIdentifiersOnInstance() {
+    A self = this;
+
+    // Prefixed globals are ambiguous
+    {
+      // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the extension
+    {
+      String t0 = self.fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = self.getterInInstanceScope;
+      checkInstanceValue(t0);
+      self.setterInInstanceScope = instanceValue;
+      String t2 = self.methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members are ambigious.
+    {
+      // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+    }
+
+    // Extension members not on this extension resolve to the extension methods
+    // in the other extension.
+    {
+      double t0 = self.fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = self.getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      self.setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = self.methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+    MyExt(this).testIdentifiersOnThis();
+    MyExt(this).testIdentifiersOnInstance();
+  }
+}
+
+class B extends A {
+  void testNakedIdentifiers() {
+    // Globals should resolve to the global name space, and not to the members
+    // of either extension
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Instance members resolve to the instance methods and not the members
+    // of the other extension (when present)
+    {
+      String t0 = fieldInInstanceScope;
+      checkInstanceValue(t0);
+      String t1 = getterInInstanceScope;
+      checkInstanceValue(t0);
+      setterInInstanceScope = instanceValue;
+      String t2 = methodInInstanceScope();
+      checkInstanceValue(t0);
+    }
+
+    // Extension members are ambigious.
+    {
+      // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+    }
+
+    // Extension members resolve to the extension methods in the other
+    // extension (unresolved identifier "id" gets turned into "this.id",
+    // which is then subject to extension method lookup).
+    {
+      double t0 = fieldInOtherExtensionScope;
+      checkOtherExtensionValue(t0);
+      double t1 = getterInOtherExtensionScope;
+      checkOtherExtensionValue(t1);
+      setterInOtherExtensionScope = otherExtensionValue;
+      double t2 = methodInOtherExtensionScope();
+      checkOtherExtensionValue(t2);
+    }
+  }
+}
+
+void main() {
+  var a = new A();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+
+  // Check external resolution as well while we're here
+
+  // Global names come from both extensions and hence are ambiguous.
+  {
+    // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+  }
+
+  // Instance members resolve to the instance methods and not the members
+  // of the other extension (when present)
+  {
+    String t0 = a.fieldInInstanceScope;
+    checkInstanceValue(t0);
+    String t1 = a.getterInInstanceScope;
+    checkInstanceValue(t1);
+    a.setterInInstanceScope = instanceValue;
+    String t2 = a.methodInInstanceScope();
+    checkInstanceValue(t2);
+  }
+
+  // Extension members are ambigious.
+  {
+    // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+  }
+
+  // Extension members resolve to the extension methods in the other
+  // extension.
+  {
+    double t0 = a.fieldInOtherExtensionScope;
+    checkOtherExtensionValue(t0);
+    double t1 = a.getterInOtherExtensionScope;
+    checkOtherExtensionValue(t1);
+    a.setterInOtherExtensionScope = otherExtensionValue;
+    double t2 = a.methodInOtherExtensionScope();
+    checkOtherExtensionValue(t2);
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_5_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_5_test.dart
new file mode 100644
index 0000000..0334769
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_5_test.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the non error cases for an extension MyExt with member names
+// overlapping the instance scopes against:
+//   - a class AGlobal which overlaps the names from the global scope as well
+//     as providing its own members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class AGlobal with instance members and global members into scope.
+import "helpers/class_shadow.dart";
+import "helpers/class_no_shadow.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+// Put the extension members in the global scope
+int fieldInExtensionScope = globalValue;
+int get getterInExtensionScope => globalValue;
+set setterInExtensionScope(int x) {
+  checkGlobalValue(x);
+}
+
+int methodInExtensionScope() => globalValue;
+
+// Put the superclass members in the global scope
+int fieldInInstanceScope = globalValue;
+int get getterInInstanceScope => globalValue;
+set setterInInstanceScope(int x) {
+  checkGlobalValue(x);
+}
+
+int methodInInstanceScope() => globalValue;
+
+// An extension which defines only its own members
+extension MyExt on AGlobal {
+  bool get fieldInExtensionScope => extensionValue;
+  bool get getterInExtensionScope => extensionValue;
+  set setterInExtensionScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInExtensionScope() => extensionValue;
+
+  bool get fieldInInstanceScope => extensionValue;
+  bool get getterInInstanceScope => extensionValue;
+  set setterInInstanceScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  bool methodInInstanceScope() => extensionValue;
+
+  void testNakedIdentifiers() {
+    // Members that are in the global namespace and the instance namespace
+    // resolve to the global namespace.
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Members that are in the global namespace and the local namespace resolve
+    // to the local namespace.
+    {
+      bool t0 = fieldInExtensionScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInExtensionScope;
+      checkExtensionValue(t1);
+      setterInExtensionScope = extensionValue;
+      bool t2 = methodInExtensionScope();
+      checkExtensionValue(t2);
+    }
+
+    // Members that are in the global namespace and the instance and the local
+    // namespace resolve to the local namespace.
+    {
+      bool t0 = fieldInInstanceScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInInstanceScope;
+      checkExtensionValue(t1);
+      setterInInstanceScope = extensionValue;
+      bool t2 = methodInInstanceScope();
+      checkExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    MyExt(this).testNakedIdentifiers();
+  }
+}
+
+class B extends AGlobal {
+  void testNakedIdentifiers() {
+    // Members that are in the global namespace and the superclass namespace
+    // should resolve to the global name space, and not to the members of the
+    // superclass.
+    {
+      int t0 = fieldInGlobalScope;
+      checkGlobalValue(t0);
+      int t1 = getterInGlobalScope;
+      checkGlobalValue(t1);
+      setterInGlobalScope = globalValue;
+      int t2 = methodInGlobalScope();
+      checkGlobalValue(t2);
+    }
+
+    // Members that are in the global namespace and the extension namespace
+    // should resolve to the global name space, and not to the members of the
+    // extension.
+    {
+      int t0 = fieldInExtensionScope;
+      checkGlobalValue(t0);
+      int t1 = getterInExtensionScope;
+      checkGlobalValue(t1);
+      setterInExtensionScope = globalValue;
+      int t2 = methodInExtensionScope();
+      checkGlobalValue(t2);
+    }
+
+    // Members that are in the global namespace, and the superclass namespace,
+    // and the extension namespace, should resolve to the global name space, and
+    // not to the members of the extension nor the members of the superclass.
+    {
+      int t0 = fieldInInstanceScope;
+      checkGlobalValue(t0);
+      int t1 = getterInInstanceScope;
+      checkGlobalValue(t1);
+      setterInInstanceScope = globalValue;
+      int t2 = methodInInstanceScope();
+      checkGlobalValue(t2);
+    }
+  }
+}
+
+void main() {
+  var a = new AGlobal();
+  a.instanceTest();
+  new B().testNakedIdentifiers();
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_6_error_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_6_error_test.dart
new file mode 100644
index 0000000..258feaa
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_6_error_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test various static error corner cases around internal resolution.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class AGlobal with instance members and global members into scope.
+import "helpers/class_shadow.dart";
+
+extension GenericExtension<T> on T {
+  T get self => this;
+  // Check that capture is avoided when expanding out
+  // self references.
+  void shadowTypeParam<T>(T x) {
+    T y = self;
+    //    ^^^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    // [cfe] A value of type '#T' can't be assigned to a variable of type 'T'.
+  }
+
+  void castToShadowedTypeParam<T>() {
+    dynamic s = self;
+    (s as T);
+  }
+
+  List<T> mkList() => <T>[];
+  void castToShadowedTypeList<T>() {
+    (mkList() as List<T>);
+  }
+}
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+extension StaticExt on AGlobal {
+  // Valid to overlap static names with the target type symbols
+  static bool get fieldInInstanceScope => extensionValue;
+  //              ^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  static bool get getterInInstanceScope => extensionValue;
+  //              ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  static set setterInInstanceScope(bool x) {
+    //       ^^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+    checkExtensionValue(x);
+  }
+
+  static bool methodInInstanceScope() => extensionValue;
+  //          ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+
+  // Add the global symbols
+  static bool get fieldInGlobalScope => extensionValue;
+  static bool get getterInGlobalScope => extensionValue;
+  static set setterInGlobalScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  static bool methodInGlobalScope() => extensionValue;
+
+  // Invalid to overlap the static and extension scopes
+  bool get fieldInInstanceScope => extensionValue;
+  //       ^
+  // [cfe] 'fieldInInstanceScope' is already declared in this scope.
+  bool get getterInInstanceScope => extensionValue;
+  //       ^
+  // [cfe] 'getterInInstanceScope' is already declared in this scope.
+  set setterInInstanceScope(bool x) {
+    //^
+    // [cfe] 'setterInInstanceScope' is already declared in this scope.
+    checkExtensionValue(x);
+  }
+
+  bool methodInInstanceScope() => extensionValue;
+  //   ^
+  // [cfe] 'methodInInstanceScope' is already declared in this scope.
+
+  void testNakedIdentifiers() {
+    // Symbols in the global scope and the local static scope resolve to
+    // the local static scope.
+    {
+      // No errors: see static_extension_internal_resolution_6_test.dart
+    }
+
+    // Symbols in the global scope, the instance scope, and the local static scope
+    // resolve to the local static scope.
+    {
+      // No errors: see static_extension_internal_resolution_6_test.dart
+    }
+  }
+
+  void instanceTest() {
+    StaticExt(this).testNakedIdentifiers();
+  }
+}
+
+void main() {
+  var a = new AGlobal();
+  a.instanceTest();
+
+  Expect.throwsTypeError(() => 3.castToShadowedTypeParam<String>());
+  Expect.throwsTypeError(() => 3.castToShadowedTypeList<String>());
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_6_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_6_test.dart
new file mode 100644
index 0000000..f8dd416
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_6_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test various non-error corner cases around internal resolution.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused.  They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class AGlobal with instance members and global members into scope.
+import "helpers/class_shadow.dart";
+
+extension GenericExtension<T> on T {
+  T get self => this;
+  void castToShadowedTypeParam<T>() {
+    dynamic s = self;
+    (s as T);
+  }
+
+  List<T> mkList() => <T>[];
+  void castToShadowedTypeList<T>() {
+    (mkList() as List<T>);
+  }
+}
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+  Expect.equals(x, extensionValue);
+}
+
+extension StaticExt on AGlobal {
+  // Valid to overlap static names with the target type symbols
+  static bool get fieldInInstanceScope => extensionValue;
+  static bool get getterInInstanceScope => extensionValue;
+  static set setterInInstanceScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  static bool methodInInstanceScope() => extensionValue;
+
+  // Add the global symbols
+  static bool get fieldInGlobalScope => extensionValue;
+  static bool get getterInGlobalScope => extensionValue;
+  static set setterInGlobalScope(bool x) {
+    checkExtensionValue(x);
+  }
+
+  static bool methodInGlobalScope() => extensionValue;
+
+  void testNakedIdentifiers() {
+    // Symbols in the global scope and the local static scope resolve to
+    // the local static scope.
+    {
+      bool t0 = fieldInGlobalScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInGlobalScope;
+      checkExtensionValue(t1);
+      setterInGlobalScope = extensionValue;
+      bool t2 = methodInGlobalScope();
+      checkExtensionValue(t2);
+    }
+
+    // Symbols in the global scope, the instance scope, and the local static scope
+    // resolve to the local static scope.
+    {
+      bool t0 = fieldInInstanceScope;
+      checkExtensionValue(t0);
+      bool t1 = getterInInstanceScope;
+      checkExtensionValue(t1);
+      setterInInstanceScope = extensionValue;
+      bool t2 = methodInInstanceScope();
+      checkExtensionValue(t2);
+    }
+  }
+
+  void instanceTest() {
+    StaticExt(this).testNakedIdentifiers();
+  }
+}
+
+void main() {
+  var a = new AGlobal();
+  a.instanceTest();
+
+  Expect.throwsTypeError(() => 3.castToShadowedTypeParam<String>());
+}
diff --git a/tests/language/extension_methods/static_extension_operators_test.dart b/tests/language/extension_methods/static_extension_operators_test.dart
new file mode 100644
index 0000000..20e0f0d
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_operators_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+// Tests that static extensions can be used for all operators.
+
+void main() {
+  Object a = "a";
+  Object b = "b";
+  Object c = "c";
+
+  expect("(-a)", -a);
+  expect("(~a)", ~a);
+  expect("(a+b)", a + b);
+  expect("(a-b)", a - b);
+  expect("(a*b)", a * b);
+  expect("(a/b)", a / b);
+  expect("(a%b)", a % b);
+  expect("(a~/b)", a ~/ b);
+  expect("(a|b)", a | b);
+  expect("(a&b)", a & b);
+  expect("(a^b)", a ^ b);
+  expect("(a<b)", a < b);
+  expect("(a>b)", a > b);
+  expect("(a<=b)", a <= b);
+  expect("(a>=b)", a >= b);
+  expect("(a<<b)", a << b);
+  expect("(a>>b)", a >> b);
+  // expect("(a>>>b)", a >>> b);
+  expect("a(b)", a(b));
+  expect("a(b,c)", a(b, c));
+  expect("a[b]", a[b]);
+  expect("c", a[b] = c, "a[b]=c");
+
+  // Operator-assignment works and evaluates to its RHS value.
+  expect("(a.field+b)", a.field += b, "a.field=(a.field+b)");
+  expect("(a.field-b)", a.field -= b, "a.field=(a.field-b)");
+  expect("(a.field*b)", a.field *= b, "a.field=(a.field*b)");
+  expect("(a.field/b)", a.field /= b, "a.field=(a.field/b)");
+  expect("(a.field%b)", a.field %= b, "a.field=(a.field%b)");
+  expect("(a.field~/b)", a.field ~/= b, "a.field=(a.field~/b)");
+  expect("(a.field|b)", a.field |= b, "a.field=(a.field|b)");
+  expect("(a.field&b)", a.field &= b, "a.field=(a.field&b)");
+  expect("(a.field^b)", a.field ^= b, "a.field=(a.field^b)");
+  expect("(a.field<<b)", a.field <<= b, "a.field=(a.field<<b)");
+  expect("(a.field>>b)", a.field >>= b, "a.field=(a.field>>b)");
+  // expect("(a.field>>>b)", a.field >>>= b, "a.field=(a.field>>>b)");
+
+  // Even on index operations.
+  expect("(a[c]+b)", a[c] += b, "a[c]=(a[c]+b)");
+  expect("(a[c]-b)", a[c] -= b, "a[c]=(a[c]-b)");
+  expect("(a[c]*b)", a[c] *= b, "a[c]=(a[c]*b)");
+  expect("(a[c]/b)", a[c] /= b, "a[c]=(a[c]/b)");
+  expect("(a[c]%b)", a[c] %= b, "a[c]=(a[c]%b)");
+  expect("(a[c]~/b)", a[c] ~/= b, "a[c]=(a[c]~/b)");
+  expect("(a[c]|b)", a[c] |= b, "a[c]=(a[c]|b)");
+  expect("(a[c]&b)", a[c] &= b, "a[c]=(a[c]&b)");
+  expect("(a[c]^b)", a[c] ^= b, "a[c]=(a[c]^b)");
+  expect("(a[c]<<b)", a[c] <<= b, "a[c]=(a[c]<<b)");
+  expect("(a[c]>>b)", a[c] >>= b, "a[c]=(a[c]>>b)");
+  // expect("(a[c]>>>b)", a[c] >>>= b, "a[c]=(a[c]>>>b)");
+
+  // And ++/-- expands to their assignments.
+  expect("(a.field+1)", ++a.field, "a.field=(a.field+1)");
+  expect("(a.field-1)", --a.field, "a.field=(a.field-1)");
+  expect("a.field", a.field++, "a.field=(a.field+1)");
+  expect("a.field", a.field--, "a.field=(a.field-1)");
+  expect("(a[b]+1)", ++a[b], "a[b]=(a[b]+1)");
+  expect("(a[b]-1)", --a[b], "a[b]=(a[b]-1)");
+  expect("a[b]", a[b]++, "a[b]=(a[b]+1)");
+  expect("a[b]", a[b]--, "a[b]=(a[b]-1)");
+
+  // Combinations.
+  expect("(a+b[b(c)]((a*b)))", a + b[c[a] = b(c)](a * b), "c[a]=b(c)");
+
+  // Operator precedence is unaffected by being extensions.
+  expect("(c<((-a)|(b^((~c)&((a<<b)>>((c-a)+((((b*c)~/a)%b)/c)))))))",
+      c < -a | b ^ ~c & a << b >> c - a + b * c ~/ a % b / c);
+  expect("((((((((((((c/b)%a)~/c)*b)+a)-c)<<b)>>a)&(~c))^b)|(-a))>b)",
+      c / b % a ~/ c * b + a - c << b >> a & ~c ^ b | -a > b);
+}
+
+// Last value set by []= or setter.
+String setValue = "";
+
+void expect(String expect, Object value, [String? expectSet]) {
+  Expect.equals(expect, value, "value");
+  if (expectSet != null) Expect.equals(expectSet, setValue, "assignment");
+}
+
+extension Ops on Object {
+  Object operator -() => "(-${this})";
+  Object operator ~() => "(~${this})";
+  Object operator +(Object other) => "(${this}+$other)";
+  Object operator -(Object other) => "(${this}-$other)";
+  Object operator *(Object other) => "(${this}*$other)";
+  Object operator /(Object other) => "(${this}/$other)";
+  Object operator %(Object other) => "(${this}%$other)";
+  Object operator ~/(Object other) => "(${this}~/$other)";
+  Object operator |(Object other) => "(${this}|$other)";
+  Object operator &(Object other) => "(${this}&$other)";
+  Object operator ^(Object other) => "(${this}^$other)";
+  Object operator <(Object other) => "(${this}<$other)";
+  Object operator >(Object other) => "(${this}>$other)";
+  Object operator <=(Object other) => "(${this}<=$other)";
+  Object operator >=(Object other) => "(${this}>=$other)";
+  Object operator <<(Object other) => "(${this}<<$other)";
+  Object operator >>(Object other) => "(${this}>>$other)";
+  // TODO: enable `>>>` when it has been implemented.
+  // String operator >>>(Object other) => "(${this}>>>$other)";
+
+  // Cannot make an extension method for `==` because it's declared by Object.
+
+  Object operator [](Object other) => "${this}[$other]";
+  void operator []=(Object other, Object value) {
+    setValue = "${this}[$other]=$value";
+  }
+
+  Object call([arg1, arg2]) =>
+      "${this}(${[arg1, arg2].where((x) => x != null).join(",")})";
+
+  Object get field => "${this}.field";
+  void set field(Object other) {
+    setValue = "${this}.field=$other";
+  }
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_double_import_test.dart b/tests/language/extension_methods/static_extension_prefix_double_import_test.dart
new file mode 100644
index 0000000..3df4552
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_double_import_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_object.dart" as p2;
+
+void main() {
+  Object o = 1;
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_import_conflict_test.dart b/tests/language/extension_methods/static_extension_prefix_import_conflict_test.dart
new file mode 100644
index 0000000..7f3993f
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_import_conflict_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/also_on_object.dart" as p2;
+
+void main() {
+  Object o = 1;
+  o.onObject;
+  //^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'onObject' is defined in multiple extensions for 'Object' and neither is more specific.
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_import_show_test.dart b/tests/language/extension_methods/static_extension_prefix_import_show_test.dart
new file mode 100644
index 0000000..8f5cf73
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_import_show_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1 show OnObject;
+import "helpers/on_int.dart" as p2 show OnInt;
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("int", i.onInt);
+  Expect.equals("int", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_import_test.dart b/tests/language/extension_methods/static_extension_prefix_import_test.dart
new file mode 100644
index 0000000..eba2e94
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_import_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1;
+import "helpers/on_int.dart" as p2;
+
+void main() {
+  int i = 0;
+  Object o = i;
+  Expect.equals("int", i.onInt);
+  Expect.equals("int", i.onObject);
+  Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_resolution_failures_test.dart b/tests/language/extension_methods/static_extension_resolution_failures_test.dart
new file mode 100644
index 0000000..f68d72b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_resolution_failures_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension method resolution failures.
+
+import "package:expect/expect.dart";
+
+main() {
+  A a = C();
+  B1 b1 = C();
+  B2 b2 = C();
+  C c = C();
+
+  Expect.equals("EA.v1", a.v1);
+  Expect.equals("EB1.v1", b1.v1);
+  Expect.equals("EB2.v1", b2.v1);
+  Expect.equals("EC.v1", c.v1);
+
+  Expect.equals("EA.v2", a.v2);
+  Expect.equals("EB1.v2", b1.v2);
+  Expect.equals("EB2.v2", b2.v2);
+  // Cannot determine which of EB1 and EB2's v2 is more specific
+  c.v2;
+  //^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'v2' is defined in multiple extensions for 'C' and neither is more specific.
+
+  Expect.equals("EA.v3", a.v3);
+  Expect.equals("EA.v3", b1.v3);
+  Expect.equals("EA.v3", b2.v3);
+  Expect.equals("EA.v3", c.v3);
+
+  Iterable<num> i_num = <int>[];
+  Iterable<int> ii = <int>[];
+  List<num> ln = <int>[];
+  List<int> li = <int>[];
+
+  // No `i_num` extension declared.
+  i_num.i_num;
+  //    ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'i_num' isn't defined for the class 'Iterable<num>'.
+
+  Expect.equals("Iterable<int>.i_num", ii.i_num);
+  Expect.equals("List<num>.i_num", ln.i_num);
+
+  // Both apply, neither is more specific.
+  li.i_num;
+  // ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'i_num' is defined in multiple extensions for 'List<int>' and neither is more specific.
+
+  // no most specific because both are equally specific.
+  c.cs;
+  //^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The property 'cs' is defined in multiple extensions for 'C' and neither is more specific.
+
+  // Both EIT.e1 and ELO.e1 apply, but their instantiated on
+  // types are incomparable, and hence this is an error.
+  ln.e1();
+  // ^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  // [cfe] The method 'e1' is defined in multiple extensions for 'List<num>' and neither is more specific.
+}
+
+// Diamond class hierarchy.
+class A {}
+
+class B1 implements A {}
+
+class B2 implements A {}
+
+class C implements B1, B2 {}
+
+extension EA on A {
+  String get v1 => "EA.v1";
+  String get v2 => "EA.v2";
+  String get v3 => "EA.v3";
+}
+
+extension EB1 on B1 {
+  String get v1 => "EB1.v1";
+  String get v2 => "EB1.v2";
+}
+
+extension EB2 on B2 {
+  String get v1 => "EB2.v1";
+  String get v2 => "EB2.v2";
+}
+
+extension EC on C {
+  String get v1 => "EC.v1";
+}
+
+// Iterable<num>, Iterable<int>, List<num> and List<int> also forms diamond
+// hierarchy.
+extension II on Iterable<int> {
+  String get i_num => "Iterable<int>.i_num";
+}
+
+extension LN on List<num> {
+  String get i_num => "List<num>.i_num";
+}
+
+// Two exactly identical `on` types.
+extension C1 on C {
+  String get cs => "C1.cs";
+}
+
+extension C2 on C {
+  String get cs => "C2.cs";
+}
+
+extension EIT<T> on Iterable<T> {
+  String e1() => "Iterable<T>.e1";
+}
+
+extension ELO on List<Object> {
+  String e1() => "List<Object>.e1";
+}
diff --git a/tests/language/extension_methods/static_extension_resolution_test.dart b/tests/language/extension_methods/static_extension_resolution_test.dart
new file mode 100644
index 0000000..e3dfcd2
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_resolution_test.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+// Tests the resolution of multiple applicable extensions.
+
+String? lastSetterValue;
+
+class SuperTarget {}
+
+class Target<T> extends SuperTarget {
+  String targetMethod() => "targetMethod";
+  String get targetGetter => "targetGetter";
+  void set targetSetter(String argument) {
+    lastSetterValue = "targetSetter: $argument";
+  }
+}
+
+class SubTarget<T> extends Target<T> {
+  String subTargetMethod() => "subTargetMethod";
+  String get subTargetGetter => "subTargetGetter";
+  void set subTargetSetter(String argument) {
+    lastSetterValue = "subTargetSetter: $argument";
+  }
+}
+
+extension E1<T> on SubTarget<T> {
+  static String name = "SubTarget<T>";
+
+  String e1() => "$name.e1";
+
+  String targetMethod() => "$name.targetMethod";
+  String get targetGetter => "$name.targetGetter";
+  void set targetSetter(String value) {
+    lastSetterValue = "$name.targetSetter: $value";
+  }
+
+  String subTargetMethod() => "$name.subTargetMethod";
+  String get subTargetGetter => "$name.subTargetGetter";
+  void set subTargetSetter(String value) {
+    lastSetterValue = "$name.subTargetSetter: $value";
+  }
+
+  List<T> get typedList => <T>[];
+}
+
+extension E2 on SubTarget<Object> {
+  static String name = "SubTarget<Object>";
+
+  String e1() => "$name.e1";
+  String e2() => "$name.e2";
+
+  String targetMethod() => "$name.targetMethod";
+  String get targetGetter => "$name.targetGetter";
+  void set targetSetter(String value) {
+    lastSetterValue = "$name.targetSetter: $value";
+  }
+
+  String subTargetMethod() => "$name.subTargetMethod";
+  String get subTargetGetter => "$name.subTargetGetter";
+  void set subTargetSetter(String value) {
+    lastSetterValue = "$name.subTargetSetter: $value";
+  }
+}
+
+extension E3<T> on Target<T> {
+  static String name = "Target<T>";
+
+  String e1() => "$name.e1";
+  String e2() => "$name.e2";
+  String e3() => "$name.e3";
+
+  String targetMethod() => "$name.targetMethod";
+  String get targetGetter => "$name.targetGetter";
+  void set targetSetter(String value) {
+    lastSetterValue = "$name.targetSetter: $value";
+  }
+
+  String subTargetMethod() => "$name.subTargetMethod";
+  String get subTargetGetter => "$name.subTargetGetter";
+  void set subTargetSetter(String value) {
+    lastSetterValue = "$name.subTargetSetter: $value";
+  }
+
+  List<T> get typedList => <T>[];
+}
+
+extension E4 on Target<Object> {
+  static String name = "Target<Object>";
+
+  String e1() => "$name.e1";
+  String e2() => "$name.e2";
+  String e3() => "$name.e3";
+  String e4() => "$name.e4";
+
+  String targetMethod() => "$name.targetMethod";
+  String get targetGetter => "$name.targetGetter";
+  void set targetSetter(String value) {
+    lastSetterValue = "$name.targetSetter: $value";
+  }
+
+  String subTargetMethod() => "$name.subTargetMethod";
+  String get subTargetGetter => "$name.subTargetGetter";
+  void set subTargetSetter(String value) {
+    lastSetterValue = "$name.subTargetSetter: $value";
+  }
+}
+
+extension E5<T> on T {
+  static String name = "T";
+
+  String e1() => "$name.e1";
+  String e2() => "$name.e2";
+  String e3() => "$name.e3";
+  String e4() => "$name.e4";
+  String e5() => "$name.e5";
+
+  String targetMethod() => "$name.targetMethod";
+  String get targetGetter => "$name.targetGetter";
+  void set targetSetter(String value) {
+    lastSetterValue = "$name.targetSetter: $value";
+  }
+
+  String subTargetMethod() => "$name.subTargetMethod";
+  String get subTargetGetter => "$name.subTargetGetter";
+  void set subTargetSetter(String value) {
+    lastSetterValue = "$name.subTargetSetter: $value";
+  }
+
+  List<T> get typedList => <T>[];
+}
+
+extension E6 on Object {
+  static String name = "Object";
+
+  String e1() => "$name.e1";
+  String e2() => "$name.e2";
+  String e3() => "$name.e3";
+  String e4() => "$name.e4";
+  String e5() => "$name.e5";
+  String e6() => "$name.e6";
+
+  String targetMethod() => "$name.targetMethod";
+  String get targetGetter => "$name.targetGetter";
+  void set targetSetter(String value) {
+    lastSetterValue = "$name.targetSetter: $value";
+  }
+
+  String subTargetMethod() => "$name.subTargetMethod";
+  String get subTargetGetter => "$name.subTargetGetter";
+  void set subTargetSetter(String value) {
+    lastSetterValue = "$name.subTargetSetter: $value";
+  }
+}
+
+main() {
+  SubTarget<num> s1 = SubTarget<int>();
+  Target<num> t1 = SubTarget<int>();
+  SuperTarget o1 = SubTarget<int>();
+  Target<int> ti1 = SubTarget<int>();
+  ;
+  SubTarget<int> si1 = SubTarget<int>();
+  ;
+
+  // Interface methods take precedence.
+
+  Expect.equals("targetGetter", s1.targetGetter);
+  Expect.equals("targetMethod", s1.targetMethod());
+  s1.targetSetter = "1";
+  Expect.equals("targetSetter: 1", lastSetterValue);
+
+  Expect.equals("subTargetGetter", s1.subTargetGetter);
+  Expect.equals("subTargetMethod", s1.subTargetMethod());
+  s1.subTargetSetter = "2";
+  Expect.equals("subTargetSetter: 2", lastSetterValue);
+
+  Expect.equals("targetGetter", t1.targetGetter);
+  Expect.equals("targetMethod", t1.targetMethod());
+  t1.targetSetter = "3";
+  Expect.equals("targetSetter: 3", lastSetterValue);
+
+  // Methods not on the instance resolve to extension methods.
+
+  Expect.equals("Target<T>.subTargetGetter", t1.subTargetGetter);
+  Expect.equals("Target<T>.subTargetMethod", t1.subTargetMethod());
+  t1.subTargetSetter = "4";
+  Expect.equals("Target<T>.subTargetSetter: 4", lastSetterValue);
+
+  Expect.type<List<int>>(ti1.typedList);
+  Expect.type<List<int>>(si1.typedList);
+  Expect.type<List<SuperTarget>>(o1.typedList);
+
+  // Extension methods can be called directly using override syntax.
+
+  Expect.equals("SubTarget<T>.targetGetter", E1<num>(si1).targetGetter);
+  Expect.equals("SubTarget<T>.targetMethod", E1<num>(si1).targetMethod());
+  E1<num>(si1).targetSetter = "5";
+  Expect.equals("SubTarget<T>.targetSetter: 5", lastSetterValue);
+
+  Expect.equals("SubTarget<T>.subTargetGetter", E1<num>(si1).subTargetGetter);
+  Expect.equals("SubTarget<T>.subTargetMethod", E1<num>(si1).subTargetMethod());
+  E1<num>(si1).subTargetSetter = "6";
+  Expect.equals("SubTarget<T>.subTargetSetter: 6", lastSetterValue);
+
+  Expect.type<List<num>>(E1<num>(si1).typedList);
+
+  // Applicable methods.
+  Expect.equals("SubTarget<T>.e1", s1.e1());
+  Expect.equals("T.e2", s1.e2());
+  Expect.equals("T.e3", s1.e3());
+  Expect.equals("T.e4", s1.e4());
+  Expect.equals("T.e5", s1.e5());
+  Expect.equals("Object.e6", s1.e6());
+
+  Expect.equals("Target<T>.e1", t1.e1());
+  Expect.equals("Target<T>.e2", t1.e2());
+  Expect.equals("Target<T>.e3", t1.e3());
+  Expect.equals("T.e4", t1.e4());
+  Expect.equals("T.e5", t1.e5());
+  Expect.equals("Object.e6", t1.e6());
+
+  Expect.equals("T.e1", o1.e1());
+  Expect.equals("T.e2", o1.e2());
+  Expect.equals("T.e3", o1.e3());
+  Expect.equals("T.e4", o1.e4());
+  Expect.equals("T.e5", o1.e5());
+  Expect.equals("Object.e6", o1.e6());
+}
diff --git a/tests/language/extension_methods/static_extension_setter_getter_assignability_error_test.dart b/tests/language/extension_methods/static_extension_setter_getter_assignability_error_test.dart
new file mode 100644
index 0000000..f7cc524
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_setter_getter_assignability_error_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// It is an error to have a setter and a getter in an extension where
+// the return type of the getter is not assignable to the argument type
+// of the setter.
+extension E1 on int {
+  static int get property => 1;
+  //     ^^
+  // [cfe] unspecified
+  //             ^^^^^^^^
+  // [analyzer] STATIC_WARNING.GETTER_NOT_SUBTYPE_SETTER_TYPES
+  static void set property(String value) {}
+  //                       ^^
+  // [cfe] unspecified
+  int get property2 => 1;
+  //  ^^
+  // [cfe] unspecified
+  //      ^^^^^^^^^
+  // [analyzer] STATIC_WARNING.GETTER_NOT_SUBTYPE_SETTER_TYPES
+  void set property2(String x) {}
+  //                 ^^
+  // [cfe] unspecified
+}
+
+void main() {}
diff --git a/tests/language/extension_methods/static_extension_silly_types_test.dart b/tests/language/extension_methods/static_extension_silly_types_test.dart
new file mode 100644
index 0000000..cbe21d6
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_silly_types_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension methods on the non-function, non-class types.
+
+import "dart:async" show FutureOr;
+
+import "package:expect/expect.dart";
+
+void main() {
+  M m = C();
+  Object o = Object();
+  Function fun = () => null;
+  f() => 0;
+  String f1(int x) => "$x";
+  String f2([int x = 0, int y = 0]) => "${x + y}";
+  int i = 0;
+  Future<int> fi = Future<int>.value(0);
+  Future<Future<int>> ffi = Future<Future<int>>.value(fi);
+  FutureOr<FutureOr<int>> foi = 1;
+  Future<Null> fn = Future<Null>.value(null);
+  Null n = null;
+
+  // `on M` matches mixin interface.
+  Expect.equals(1, m.m);
+  // `on void` matches anything.
+  Expect.equals(2, o.v);
+  Expect.equals(2, n.v);
+  // `on dynamic` matches anything.
+  Expect.equals(3, o.d);
+  Expect.equals(3, n.d);
+  // `on Function` matches any function type and Function itself.
+  Expect.equals(4, f.f);
+  Expect.equals(4, fun.f);
+  Expect.equals(4, f1.f);
+  Expect.equals(4, f2.f);
+  // `on <function type>` matches those functions.
+  Expect.equals(5, f1.fu);
+  Expect.equals(5, f2.fu);
+  // `on FutureOr<int>` matches both future and not.
+  Expect.equals(6, i.fi);
+  Expect.equals(6, fi.fi);
+  // `on FutureOr<Object>` matches everything.
+  Expect.equals(7, o.fo);
+  Expect.equals(7, n.fo);
+  // `on FutureOr<Future<Object>>` matches any future or futureOr.
+  Expect.equals(8, fi.ffo);
+  Expect.equals(8, ffi.ffo);
+  // `on FutureOr<Null>` matches Null and FutureOr<Null>.
+  Expect.equals(9, fn.fn);
+  Expect.equals(9, n.fn);
+  // `on Null` does match null. No errors for receiver being null.
+  Expect.equals(10, n.n);
+
+  // Matching can deconstruct static function types.
+  Expect.equals(int, f1.parameterType);
+  Expect.equals(String, f1.returnType);
+  Expect.equals(int, f2.parameterType);
+  Expect.equals(String, f2.returnType);
+  // And static FutureOr types.
+  Expect.equals(int, i.futureType);
+  Expect.equals(int, fi.futureType);
+  Expect.equals(type<Future<int>>(), ffi.futureType);
+  Expect.equals(type<FutureOr<int>>(), foi.futureType);
+  // TODO: Update and enable when
+  //  https://github.com/dart-lang/language/issues/436
+  // is resolved.
+  // Expect.equals(dynamic, n.futureType); // Inference treats `null` as no hint.
+}
+
+Type type<T>() => T;
+
+mixin M {}
+
+class C = Object with M;
+
+extension on M {
+  int get m => 1;
+}
+
+extension on void {
+  int get v => 2;
+  testVoid() {
+    // No access on void. Static type of `this` is void!
+    this //
+            .toString() //# 01: compile-time error
+        ;
+  }
+}
+
+extension on dynamic {
+  int get d => 3;
+
+  void testDynamic() {
+    // Static type of `this` is dynamic, allows dynamic invocation.
+    this.arglebargle();
+  }
+}
+
+extension on Function {
+  int get f => 4;
+
+  void testFunction() {
+    // Static type of `this` is Function. Allows any dynamic invocation.
+    this();
+    this(1);
+    this(x: 1);
+    // No function can have both optional positional and named parameters.
+  }
+}
+
+extension on String Function(int) {
+  int get fu => 5;
+}
+
+extension on FutureOr<int> {
+  int get fi => 6;
+
+  void testFutureOr() {
+    var self = this;
+    // The `this` type can be type-promoted to both Future<int> and int.
+    if (self is Future<int>) {
+      self.then((int x) {});
+    } else if (self is int) {
+      self + 2;
+    }
+  }
+}
+
+extension on FutureOr<Object?> {
+  int get fo => 7;
+}
+
+extension on FutureOr<Future<Object?>> {
+  int get ffo => 8;
+}
+
+extension on FutureOr<Null> {
+  int get fn => 9;
+}
+
+extension on Null {
+  int get n => 10;
+}
+
+// TODO: Type `Never` when it's added.
+
+extension<T> on FutureOr<T> {
+  Type get futureType => T;
+}
+
+extension<R, T> on R Function(T) {
+  Type get returnType => R;
+  Type get parameterType => T;
+}
diff --git a/tests/language/extension_methods/static_extension_syntax_test.dart b/tests/language/extension_methods/static_extension_syntax_test.dart
new file mode 100644
index 0000000..0d71b60
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_syntax_test.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension declaration syntax combinations.
+
+import "package:expect/expect.dart";
+
+void checkStaticType<T>(T x) {
+  Expect.type<T>(x);
+}
+
+main() {
+  Object object = <int>[];
+  List<Object> list = <int>[];
+  List<num> numList = <int>[];
+  Pair<int, double> numPair = Pair(1, 2.5);
+  RecSolution recs = RecSolution();
+
+  Expect.equals(0, object.e0);
+  Expect.equals(0, list.e0);
+
+  Expect.equals(1, object.e1);
+  Expect.equals(1, list.e1);
+
+  Expect.equals(0, object.e4);
+  Expect.equals(0, list.e4);
+  Expect.equals(4, numList.e4);
+
+  Expect.equals(0, object.e5);
+  Expect.equals(0, list.e5);
+  Expect.equals(5, numList.e5);
+
+  Expect.equals(0, object.e6);
+  Expect.equals(6, list.e6);
+  Expect.equals(6, numList.e6);
+  checkStaticType<List<num>>(numList.list6);
+
+  Expect.equals(0, object.e7);
+  Expect.equals(7, list.e7);
+  Expect.equals(7, numList.e7);
+  checkStaticType<List<num>>(numList.list7);
+
+  Expect.equals(10, object.e10);
+  Expect.equals(10, numList.e10);
+  checkStaticType<List<Object>>(object.list10);
+  checkStaticType<List<List<num>>>(numList.list10);
+
+  Expect.equals(11, object.e11);
+  Expect.equals(11, numList.e11);
+  checkStaticType<List<Object>>(object.list11);
+  checkStaticType<List<List<num>>>(numList.list11);
+
+  Expect.equals(0, object.e14);
+  Expect.equals(14, numPair.e14);
+  Expect.type<List<num>>(numPair.list14);
+  checkStaticType<List<num>>(numPair.list14);
+
+  Expect.equals(0, object.e16);
+  Expect.equals(16, numPair.e16);
+  Expect.type<Map<int, double>>(numPair.map16);
+  checkStaticType<Map<int, double>>(numPair.map16);
+
+  Expect.equals(0, object.e17);
+  Expect.equals(0, list.e17);
+  Expect.equals(17, numList.e17);
+  Expect.type<List<num>>(numList.list17);
+  checkStaticType<List<num>>(numList.list17);
+
+  Expect.equals(0, object.e19);
+  Expect.equals(19, recs.e19);
+  Expect.type<List<RecSolution>>(recs.list19);
+  checkStaticType<List<RecSolution>>(recs.list19);
+
+  Expect.equals(0, object.e20);
+  Expect.equals(20, recs.e20);
+  Expect.type<List<RecSolution>>(recs.list20);
+  checkStaticType<List<RecSolution>>(recs.list20);
+}
+
+extension on Object {
+  int get e0 => 0;
+  // Fallbacks to test cases where other extensions do not apply.
+  int get e4 => 0;
+  int get e5 => 0;
+  int get e6 => 0;
+  int get e7 => 0;
+  int get e14 => 0;
+  int get e16 => 0;
+  int get e17 => 0;
+  int get e19 => 0;
+  int get e20 => 0;
+}
+
+extension E1 on Object {
+  int get e1 => 1;
+}
+
+extension on List<num> {
+  int get e4 => 4;
+}
+
+extension E5 on List<num> {
+  int get e5 => 5;
+}
+
+extension<T> on List<T> {
+  int get e6 => 6;
+  List<T> get list6 => <T>[];
+}
+
+extension E7<T> on List<T> {
+  int get e7 => 7;
+  List<T> get list7 => <T>[];
+}
+
+extension<T> on T {
+  int get e10 => 10;
+  List<T> get list10 => <T>[];
+}
+
+extension E11<T> on T {
+  int get e11 => 11;
+  List<T> get list11 => <T>[];
+}
+
+extension<T> on Pair<T, T> {
+  int get e14 => 14;
+  List<T> get list14 => <T>[];
+}
+
+extension E16<S, T> on Pair<S, T> {
+  int get e16 => 16;
+  Map<S, T> get map16 => <S, T>{};
+}
+
+extension<T extends num> on List<T> {
+  int get e17 => 17;
+  List<T> get list17 => <T>[];
+}
+
+extension<T extends Rec<T>> on T {
+  int get e19 => 19;
+  List<T> get list19 => <T>[];
+}
+
+extension E20<T extends Rec<T>> on T {
+  int get e20 => 20;
+  List<T> get list20 => <T>[];
+}
+
+class Pair<A, B> {
+  final A first;
+  final B second;
+  const Pair(this.first, this.second);
+}
+
+class Rec<T extends Rec<T>> {}
+
+class RecSolution extends Rec<RecSolution> {}
diff --git a/tests/language/extension_methods/syntax/extension_methods_test.dart b/tests/language/extension_methods/syntax/extension_methods_test.dart
new file mode 100644
index 0000000..51013db
--- /dev/null
+++ b/tests/language/extension_methods/syntax/extension_methods_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+
+class C {
+  int get one => 1;
+}
+
+extension E on C {
+  int get two => 2;
+}
+
+main() {
+  C c = C();
+  var result = c.one + c.two;
+  Expect.equals(result, 3);
+}
diff --git a/tests/language/factory/and_instance_variable_runtime_test.dart b/tests/language/factory/and_instance_variable_runtime_test.dart
new file mode 100644
index 0000000..f250fb8
--- /dev/null
+++ b/tests/language/factory/and_instance_variable_runtime_test.dart
@@ -0,0 +1,41 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+abstract class A {
+  var bar;
+  factory A.bar() = B.bar;
+
+  get foo => bar;
+
+}
+
+class B implements A {
+  var bar;
+  factory B.bar() => new C.bar();
+
+  get foo => bar;
+
+
+  B() {}
+}
+
+class C extends B {
+  C.bar() {
+    bar = "foo";
+  }
+
+
+}
+
+main() {
+  assert(new A.bar().foo == "foo");
+  assert(new B.bar().foo == "foo");
+  assert(new C.bar().foo == "foo");
+  assert(new A.bar().bar == "foo");
+  assert(new B.bar().bar == "foo");
+  assert(new C.bar().bar == "foo");
+}
diff --git a/tests/language/factory/and_instance_variable_test.dart b/tests/language/factory/and_instance_variable_test.dart
new file mode 100644
index 0000000..b35c290
--- /dev/null
+++ b/tests/language/factory/and_instance_variable_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+abstract class A {
+  var bar;
+  factory A.bar() = B.bar;
+
+  get foo => bar;
+  static get baz => bar;
+  //                ^^^
+  // [analyzer] COMPILE_TIME_ERROR.INSTANCE_MEMBER_ACCESS_FROM_STATIC
+  // [cfe] Getter not found: 'bar'.
+}
+
+class B implements A {
+  var bar;
+  factory B.bar() => new C.bar();
+
+  get foo => bar;
+  static get baz => bar;
+  //                ^^^
+  // [analyzer] COMPILE_TIME_ERROR.INSTANCE_MEMBER_ACCESS_FROM_STATIC
+  // [cfe] Getter not found: 'bar'.
+
+  B() {}
+}
+
+class C extends B {
+  C.bar() {
+    bar = "foo";
+  }
+
+  static get baz => bar;
+  //                ^^^
+  // [analyzer] COMPILE_TIME_ERROR.INSTANCE_MEMBER_ACCESS_FROM_STATIC
+  // [cfe] Getter not found: 'bar'.
+}
+
+main() {
+  assert(new A.bar().foo == "foo");
+  assert(new B.bar().foo == "foo");
+  assert(new C.bar().foo == "foo");
+  assert(new A.bar().bar == "foo");
+  assert(new B.bar().bar == "foo");
+  assert(new C.bar().bar == "foo");
+}
diff --git a/tests/language/factory/arrow_test.dart b/tests/language/factory/arrow_test.dart
new file mode 100644
index 0000000..d2cf528
--- /dev/null
+++ b/tests/language/factory/arrow_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  A.foo() {}
+  factory A() => new A.foo();
+}
+
+main() {
+  Expect.isTrue(new A() is A);
+}
diff --git a/tests/language/factory/factory1_test.dart b/tests/language/factory/factory1_test.dart
new file mode 100644
index 0000000..d29187b
--- /dev/null
+++ b/tests/language/factory/factory1_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing factory generic result types.
+
+class A<T> {
+  A() {}
+  factory A.factory() {
+    return new A<String>(); // //# 00: compile-time error
+    return A<T>();
+  }
+}
+
+class B<T> extends A<T> {
+  B() {}
+  factory B.factory() {
+    return new B<String>(); // //# 01: compile-time error
+    return B<T>();
+  }
+}
+
+main() {
+  new A<String>.factory();
+  new A<int>.factory(); // //# 00: dynamic type error
+  new B<String>.factory();
+  new B<int>.factory(); // //# 01: dynamic type error
+}
diff --git a/tests/language/factory/factory2_test.dart b/tests/language/factory/factory2_test.dart
new file mode 100644
index 0000000..f8a2e3a
--- /dev/null
+++ b/tests/language/factory/factory2_test.dart
@@ -0,0 +1,67 @@
+// 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.
+
+// Test compile time error for factories with parameterized types.
+
+import "dart:collection";
+
+abstract class A<T> {
+  factory A.create() = AFactory<T>.create; // //# 01: compile-time error
+}
+
+class AFactory {
+  //   Compile time error: should be AFactory<T> to match abstract class above
+  factory A.create() { // //# 01: compile-time error
+    return null;// //# 01: continued
+  } // //# 01: continued
+}
+
+abstract class Link<T> extends IterableBase<T> {
+  // does not match constructor for LinkFactory
+  factory Link(T head, [Link<T> tail]) = LinkFactory<T>; //# 03: compile-time error
+  Link<T> prepend(T element);
+}
+
+abstract class EmptyLink<T> extends Link<T> {
+  const factory EmptyLink() = LinkTail<T>;
+}
+
+class LinkFactory<T> {
+  factory LinkFactory(head, [Link tail]) {}
+}
+
+// Does not implement all of Iterable
+class AbstractLink<T> implements Link<T> { /*@compile-error=unspecified*/
+  const AbstractLink();
+  Link<T> prepend(T element) {
+    return new Link<T>(element, this);
+  }
+}
+
+// Does not implement all of Iterable
+class LinkTail<T> extends AbstractLink<T> implements EmptyLink<T> { /*@compile-error=unspecified*/
+  const LinkTail();
+}
+
+// Does not implement all of Iterable
+class LinkEntry<T> extends AbstractLink<T> { /*@compile-error=unspecified*/
+  LinkEntry(T head, Link<T> realTail);
+}
+
+class Fisk {
+  // instantiation of abstract class
+  Link<String> nodes = const EmptyLink(); /*@compile-error=unspecified*/
+}
+
+main() {
+  // Equivalent to new Link<dynamic>.create().
+  var a = new A.create(); // //# none: compile-time error
+  var a = new A.create(); // //# 01: continued
+
+  new Fisk();
+  // instantiation of abstract class
+  new EmptyLink<String>().prepend('hest'); //# compile-time error
+  // instantiation of abstract class
+  const EmptyLink<String>().prepend('fisk'); //# compile-time error
+}
diff --git a/tests/language/factory/factory3_test.dart b/tests/language/factory/factory3_test.dart
new file mode 100644
index 0000000..fe15ad9
--- /dev/null
+++ b/tests/language/factory/factory3_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+
+// Test compile time error for factories with parameterized types.
+
+abstract class A<T> {
+  A();
+  A.create();
+}
+
+abstract class B<T> extends A<T>{}
+
+// Compile time error: should be AFactory<T> to match abstract class above
+class AFactory extends B<int> {
+  factory A.create() { // //# 01: compile-time error
+    return null; // //# 01: continued
+  } // //# 01: continued
+}
+
+abstract class Link<T> extends IterableBase<T> {
+  factory Link(T head, [Link<T> tail]) = LinkEntry<T>;
+  Link<T> prepend(T element);
+}
+
+abstract class EmptyLink<T> extends Link<T> {
+  const factory EmptyLink() = LinkTail<T>;
+}
+
+class AbstractLink<T> implements Link<T> { /*@compile-error=unspecified*/
+  const AbstractLink();
+  Link<T> prepend(T element) {
+    print("$element");
+    if (0 is T) {
+      throw "0 is not a T";
+    }
+    return new Link<T>(element, this);
+  }
+}
+
+class LinkTail<T> extends AbstractLink<T> implements EmptyLink<T> { /*@compile-error=unspecified*/
+  const LinkTail();
+}
+
+class LinkEntry<T> extends AbstractLink<T> { /*@compile-error=unspecified*/
+  LinkEntry(T head, [Link<T> Tail]);
+}
+
+class Fisk {
+  Link<Fisk> nodes = const EmptyLink<Fisk>();
+  final int id;
+  Fisk(this.id);
+  toString() => id.toString();
+}
+
+main() {
+  var a = new AFactory.create(); // //# 01: continued
+  var a = new AFactory.create(); // //# none: compile-time error
+  new Fisk(0).nodes.prepend(new Fisk(1)).prepend(new Fisk(2));
+}
diff --git a/tests/language/factory/factory4_runtime_test.dart b/tests/language/factory/factory4_runtime_test.dart
new file mode 100644
index 0000000..931127b
--- /dev/null
+++ b/tests/language/factory/factory4_runtime_test.dart
@@ -0,0 +1,24 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+abstract class Link<T> {
+
+}
+
+class A<T> {}
+
+class LinkFactory<T> extends A<T> {
+  factory LinkFactory.create() {
+    return LinkFactory._();
+  }
+
+  LinkFactory._();
+}
+
+main() {
+
+}
diff --git a/tests/language/factory/factory4_test.dart b/tests/language/factory/factory4_test.dart
new file mode 100644
index 0000000..8aeb051
--- /dev/null
+++ b/tests/language/factory/factory4_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+abstract class Link<T> {
+  factory Link.create() = LinkFactory.create;
+  //                      ^^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.REDIRECT_TO_INVALID_RETURN_TYPE
+  // [cfe] The constructor function type 'LinkFactory<dynamic> Function()' isn't a subtype of 'Link<T> Function()'.
+}
+
+class A<T> {}
+
+class LinkFactory<T> extends A<T> {
+  factory LinkFactory.create() {
+    return LinkFactory._();
+  }
+
+  LinkFactory._();
+}
+
+main() {
+  new Link<int>.create();
+}
diff --git a/tests/language/factory/factory5_runtime_test.dart b/tests/language/factory/factory5_runtime_test.dart
new file mode 100644
index 0000000..f5205c3
--- /dev/null
+++ b/tests/language/factory/factory5_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+abstract class Link<T> {
+
+}
+
+class LinkFactory<T> {
+  factory LinkFactory.create() {
+    return LinkFactory._();
+  }
+
+  LinkFactory._();
+}
+
+main() {
+
+}
diff --git a/tests/language/factory/factory5_test.dart b/tests/language/factory/factory5_test.dart
new file mode 100644
index 0000000..b06af33
--- /dev/null
+++ b/tests/language/factory/factory5_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+abstract class Link<T> {
+  factory Link.create() = LinkFactory<T>.create;
+  //                      ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.REDIRECT_TO_INVALID_RETURN_TYPE
+  // [cfe] The constructor function type 'LinkFactory<T> Function()' isn't a subtype of 'Link<T> Function()'.
+}
+
+class LinkFactory<T> {
+  factory LinkFactory.create() {
+    return LinkFactory._();
+  }
+  factory LinkFactory.Foo() = Foo<T>;
+  //                          ^^^
+  // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CLASS
+  // [cfe] Couldn't find constructor 'Foo'.
+  //                          ^
+  // [cfe] Redirection constructor target not found: 'Foo'
+
+  LinkFactory._();
+}
+
+main() {
+  new Link<int>.create();
+}
diff --git a/tests/language/factory/factory6_runtime_test.dart b/tests/language/factory/factory6_runtime_test.dart
new file mode 100644
index 0000000..8452028
--- /dev/null
+++ b/tests/language/factory/factory6_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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:expect/expect.dart';
+
+abstract class Link<T> {
+
+}
+
+class LinkFactory<T> {
+
+}
+
+main() {
+
+}
diff --git a/tests/language/factory/factory6_test.dart b/tests/language/factory/factory6_test.dart
new file mode 100644
index 0000000..7e36cb9
--- /dev/null
+++ b/tests/language/factory/factory6_test.dart
@@ -0,0 +1,25 @@
+// 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:expect/expect.dart';
+
+abstract class Link<T> {
+  factory Link.Foo() = LinkFactory<T>.Foo;
+  //                   ^^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.REDIRECT_TO_INVALID_RETURN_TYPE
+  // [cfe] The constructor function type 'LinkFactory<T> Function()' isn't a subtype of 'Link<T> Function()'.
+}
+
+class LinkFactory<T> {
+  factory LinkFactory.Foo() = Foo<T>;
+  //                          ^^^
+  // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CLASS
+  // [cfe] Couldn't find constructor 'Foo'.
+  //                          ^
+  // [cfe] Redirection constructor target not found: 'Foo'
+}
+
+main() {
+  Expect.throws(() => new Link<int>.Foo());
+}
diff --git a/tests/language/factory/factory_test.dart b/tests/language/factory/factory_test.dart
new file mode 100644
index 0000000..14a5983
--- /dev/null
+++ b/tests/language/factory/factory_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing factories.
+
+import "package:expect/expect.dart";
+
+class A {
+  factory A(n) {
+    return new A.internal(n);
+  }
+  A.internal(n) : n_ = n {}
+  var n_;
+}
+
+class B {
+  factory B.my() {
+    return new B(3);
+  }
+  B(n) : n_ = n {}
+  var n_;
+}
+
+class FactoryTest {
+  static testMain() {
+    new B.my();
+    var b = new B.my();
+    Expect.equals(3, b.n_);
+    var a = new A(5);
+    Expect.equals(5, a.n_);
+  }
+}
+
+// Test compile time error for factories with parameterized types.
+
+abstract class Link<T> {
+  factory Link.create() = LinkFactory<T>.create;
+  //                      ^^^^^^^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS
+  // [cfe] Expected 0 type arguments.
+  //                      ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.REDIRECT_TO_INVALID_RETURN_TYPE
+}
+
+class LinkFactory {
+  //   Compile time error: should be LinkFactory<T> to match abstract class above
+  factory Link.create() {
+  //      ^^^^
+  // [analyzer] COMPILE_TIME_ERROR.INVALID_FACTORY_NAME_NOT_A_CLASS
+  // [cfe] The name of a constructor must match the name of the enclosing class.
+    return LinkFactory._();
+  }
+
+  LinkFactory._();
+}
+
+
+main() {
+  FactoryTest.testMain();
+  var a = new Link<int>.create();
+  //          ^
+  // [cfe] Expected 0 type arguments.
+}
diff --git a/tests/language/factory/implementation_test.dart b/tests/language/factory/implementation_test.dart
new file mode 100644
index 0000000..7492df8
--- /dev/null
+++ b/tests/language/factory/implementation_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+abstract class A {
+  factory A(int x, int y) = B;
+}
+
+class B implements A {
+  final int x;
+  final int y;
+
+  B(this.x, this.y);
+
+  // This factory should never be invoked.
+  factory B.A(int a, int b) {
+    return new B(0, 0);
+  }
+
+  factory B.X(int a, int b) {
+    return new B(a * 10, b * 10);
+  }
+}
+
+main() {
+  var a = new B(1, 2);
+  // Check that constructor B is invoked and not factory B.A.
+  Expect.equals(1, a.x);
+  Expect.equals(2, a.y);
+
+  var x = new B.X(11, 22);
+  // Check that factory is invoked.
+  Expect.equals(110, x.x);
+  Expect.equals(220, x.y);
+}
diff --git a/tests/language/factory/redirection2_runtime_test.dart b/tests/language/factory/redirection2_runtime_test.dart
new file mode 100644
index 0000000..2592b7e
--- /dev/null
+++ b/tests/language/factory/redirection2_runtime_test.dart
@@ -0,0 +1,28 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that it is a compile-time error to have a redirection in a
+// non-factory constructor.
+
+class Foo {
+  Foo()
+
+  ;
+}
+
+class Bar extends Foo {
+  factory Bar() => Bar._();
+
+  Bar._();
+}
+
+main() {
+  Expect.isTrue(new Foo() is Foo);
+  Expect.isFalse(new Foo() is Bar);
+}
diff --git a/tests/language/factory/redirection2_test.dart b/tests/language/factory/redirection2_test.dart
new file mode 100644
index 0000000..275d766
--- /dev/null
+++ b/tests/language/factory/redirection2_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that it is a compile-time error to have a redirection in a
+// non-factory constructor.
+
+class Foo {
+  Foo()
+  = Bar
+//^
+// [analyzer] SYNTACTIC_ERROR.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR
+// [cfe] Expected a function body or '=>'.
+//^
+// [cfe] Only factory constructor can specify '=' redirection.
+//  ^
+// [cfe] Constructors can't have a return type.
+  ;
+}
+
+class Bar extends Foo {
+  factory Bar() => Bar._();
+
+  Bar._();
+}
+
+main() {
+  Expect.isTrue(new Foo() is Foo);
+  Expect.isFalse(new Foo() is Bar);
+}
diff --git a/tests/language/factory/redirection3_cyclic_runtime_test.dart b/tests/language/factory/redirection3_cyclic_runtime_test.dart
new file mode 100644
index 0000000..ecbccc2
--- /dev/null
+++ b/tests/language/factory/redirection3_cyclic_runtime_test.dart
@@ -0,0 +1,28 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that a cycle in redirecting factories leads to a compile-time error.
+
+class A {
+  factory A.foo() = B;
+}
+
+class B implements A {
+  factory B() = C.bar;
+}
+
+class C implements B {
+  factory C.bar() = C.foo;
+  factory C.foo() = C
+
+  ;
+  C();
+}
+
+main() {
+  new A.foo();
+}
diff --git a/tests/language/factory/redirection3_cyclic_test.dart b/tests/language/factory/redirection3_cyclic_test.dart
new file mode 100644
index 0000000..ed352be
--- /dev/null
+++ b/tests/language/factory/redirection3_cyclic_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that a cycle in redirecting factories leads to a compile-time error.
+
+class A {
+  factory A.foo() = B;
+  //      ^
+  // [cfe] Cyclic definition of factory 'A.foo'.
+}
+
+class B implements A {
+  factory B() = C.bar;
+}
+
+class C implements B {
+  factory C.bar() = C.foo;
+  //                ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_FACTORY_REDIRECT
+  factory C.foo() = C.bar();
+  //                ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_FACTORY_REDIRECT
+  //                  ^^^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected ';' after this.
+  //                     ^
+  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+  // [cfe] Expected an identifier, but got '('.
+  //                     ^^^
+  // [analyzer] STATIC_WARNING.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
+  C();
+}
+
+main() {
+  new A.foo();
+}
diff --git a/tests/language/factory/redirection_test.dart b/tests/language/factory/redirection_test.dart
new file mode 100644
index 0000000..bddc5368
--- /dev/null
+++ b/tests/language/factory/redirection_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  A() : x = null;
+
+  const A.constant(this.x);
+
+  factory A.factory() {
+    return new B<Set>();
+  }
+
+  factory A.test01() = T; // //# 01: compile-time error
+
+  factory A.test02() = dynamic; // //# 02: compile-time error
+
+  factory A.test03() = Undefined; // //# 03: compile-time error
+
+  factory A.test04() = C.test04; // //# 04: compile-time error
+
+  final T x;
+}
+
+class B<T> extends A<T> {
+  B();
+
+  factory B.A() = A<T>;
+
+  const factory B.A_constant(T x) = A<T>.constant;
+
+  factory B.A_factory() = A<T>.factory;
+
+  factory B.test04() = A.test04; // //# 04: continued
+
+  factory B.test05(int incompatible) = A<T>.factory; // //# 05: compile-time error
+
+  factory B.test05(int incompatible) = A<T>.factory; // //# 06: compile-time error
+}
+
+class C<K, V> extends B<V> {
+  C();
+
+  factory C.A() = A<V>; // //# none: compile-time error
+
+  factory C.A_factory() = A<V>.factory;  // //# none: compile-time error
+
+  const factory C.B_constant(V x) = B<V>.A_constant;
+
+  factory C.test04() = B.test04; // //# 04: continued
+
+  factory C.test06(int incompatible) = B<K>.test05; // //# 06: continued
+
+  const factory C.test07(V x) = B<V>.A; // //# 07: compile-time error
+}
+
+main() {
+  new A<List>.test01(); // //# 01: continued
+  new A<List>.test02(); // //# 02: continued
+  new A<List>.test03(); // //# 03: continued
+  new C.test04(); // //# 04: continued
+  new B.test05(0); // //# 05: continued
+  new C<int, int>.test06(0); // //# 06: continued
+  new C<int, int>.test07(0); // //# 07: continued
+  Expect.isTrue(new A<List>() is A<List>);
+  Expect.isTrue(new A<bool>.constant(true).x);
+  Expect.isTrue(new A<Set>.factory() is B<Set>);
+  Expect.isTrue(new B<List>.A() is A<List>); // //# 08: compile-time error
+  Expect.isFalse(new B<List>.A() is A<Set>); // //# 09: compile-time error
+  Expect.isTrue(new B<bool>.A_constant(true).x); // //# 10: compile-time error
+  Expect.isTrue(new B<List>.A_factory() is B<Set>); // //# 11: compile-time error
+  Expect.isTrue(new C<String, num>.A() is A<num>); // //# 12: compile-time error
+  Expect.isTrue(new C<String, num>.A_factory() is B<Set>); // //# 13: compile-time error
+  Expect.isTrue(new C<String, bool>.B_constant(true).x); // //# 14: compile-time error
+}
diff --git a/tests/language/factory/return_type_checked_runtime_test.dart b/tests/language/factory/return_type_checked_runtime_test.dart
new file mode 100644
index 0000000..3bef4c2
--- /dev/null
+++ b/tests/language/factory/return_type_checked_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+
+}
+
+main() {
+
+}
diff --git a/tests/language/factory/return_type_checked_test.dart b/tests/language/factory/return_type_checked_test.dart
new file mode 100644
index 0000000..bff29b4
--- /dev/null
+++ b/tests/language/factory/return_type_checked_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  factory A() => 42;
+  //             ^^
+  // [analyzer] STATIC_TYPE_WARNING.RETURN_OF_INVALID_TYPE_FROM_CLOSURE
+  // [cfe] A value of type 'int' can't be assigned to a variable of type 'A'.
+}
+
+main() {
+  Expect.throws(() => new A());
+}
diff --git a/tests/language/factory/runtime_test.dart b/tests/language/factory/runtime_test.dart
new file mode 100644
index 0000000..bac5c66
--- /dev/null
+++ b/tests/language/factory/runtime_test.dart
@@ -0,0 +1,54 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing factories.
+
+import "package:expect/expect.dart";
+
+class A {
+  factory A(n) {
+    return new A.internal(n);
+  }
+  A.internal(n) : n_ = n {}
+  var n_;
+}
+
+class B {
+  factory B.my() {
+    return new B(3);
+  }
+  B(n) : n_ = n {}
+  var n_;
+}
+
+class FactoryTest {
+  static testMain() {
+    new B.my();
+    var b = new B.my();
+    Expect.equals(3, b.n_);
+    var a = new A(5);
+    Expect.equals(5, a.n_);
+  }
+}
+
+// Test compile time error for factories with parameterized types.
+
+
+
+
+
+
+  //   Compile time error: should be LinkFactory<T> to match abstract class above
+
+
+
+
+
+
+main() {
+  FactoryTest.testMain();
+
+}
diff --git a/tests/language/factory/type_parameter2_test.dart b/tests/language/factory/type_parameter2_test.dart
new file mode 100644
index 0000000..6536be8
--- /dev/null
+++ b/tests/language/factory/type_parameter2_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that type variables are correctly set in instances created by factories.
+
+import 'package:expect/expect.dart';
+
+var p;
+bool done = false;
+
+class D {}
+
+abstract class I<T> {
+  factory I.name() {
+    return new C<T>.name();
+  }
+}
+
+class C<T> implements I<T> {
+  C.name() {
+    Expect.isTrue(p is T);
+    done = true;
+  }
+}
+
+main() {
+  p = new D();
+  new I<D>.name();
+  Expect.equals(true, done);
+}
diff --git a/tests/language/factory/type_parameter_test.dart b/tests/language/factory/type_parameter_test.dart
new file mode 100644
index 0000000..c9e7a0b
--- /dev/null
+++ b/tests/language/factory/type_parameter_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  factory A.factory() {
+    return new B<T>();
+  }
+
+  A();
+
+  build() {
+    return new A<T>();
+  }
+}
+
+class B<T> extends A<T> {
+  B();
+
+  build() {
+    return new B<T>();
+  }
+}
+
+main() {
+  Expect.isTrue(new A<List>() is A<List>);
+  Expect.isTrue(new A<List>.factory() is B<List>);
+
+  // Check that we don't always return true for is checks with
+  // generics.
+  Expect.isFalse(new A<List>() is A<Set>);
+  Expect.isFalse(new A<List>.factory() is B<Set>);
+
+  Expect.isTrue(new A<List>().build() is A<List>);
+  Expect.isFalse(new A<List>().build() is A<Set>);
+
+  Expect.isTrue(new A<List>.factory().build() is B<List>);
+  Expect.isFalse(new A<List>.factory().build() is B<Set>);
+
+  Expect.isTrue(new B<List>().build() is B<List>);
+  Expect.isFalse(new B<List>().build() is B<Set>);
+}
diff --git a/tests/language/factory/with_type_parameters_test.dart b/tests/language/factory/with_type_parameters_test.dart
new file mode 100644
index 0000000..e0c1583
--- /dev/null
+++ b/tests/language/factory/with_type_parameters_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+class Foo<T> {
+  Foo._();
+
+  factory Foo
+             <X> //# 01: syntax error
+             <X extends T> //# 02: syntax error
+             () => new Bar<T>();
+
+  factory Foo
+             <X> //# 03: syntax error
+             <X extends T> //# 04: syntax error
+             .far
+                 <X> //# 05: syntax error
+                 <X extends T> //# 06: syntax error
+                 <X>.fip //# 07: syntax error
+                 <X extends T>.fip //# 08: syntax error
+                 () => new Bar<T>();
+}
+
+class Bar<T> extends Foo<T> {
+  Bar(): super._() {}
+}
+
+main() {
+  new Foo<String>();
+  new Foo<String>.far();
+}
diff --git a/tests/language/field/decl_missing_var_type_runtime_test.dart b/tests/language/field/decl_missing_var_type_runtime_test.dart
new file mode 100644
index 0000000..3d31ad0
--- /dev/null
+++ b/tests/language/field/decl_missing_var_type_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Exercises issue 2997, missing var or type on field declarations should
+// generate a compile-time error.
+
+class A {
+
+
+}
+
+main() {
+
+}
diff --git a/tests/language/field/decl_missing_var_type_test.dart b/tests/language/field/decl_missing_var_type_test.dart
new file mode 100644
index 0000000..6435dfb
--- /dev/null
+++ b/tests/language/field/decl_missing_var_type_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Exercises issue 2997, missing var or type on field declarations should
+// generate a compile-time error.
+
+class A {
+  _this;
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_CONST_FINAL_VAR_OR_TYPE
+// [cfe] Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+  A(x) : this._this = x;
+}
+
+main() {
+  new A(0);
+}
diff --git a/tests/language/field/field1_test.dart b/tests/language/field/field1_test.dart
new file mode 100644
index 0000000..1591ad1
--- /dev/null
+++ b/tests/language/field/field1_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs in class fields declarations.
+// Should be an error because we have setter/getter functions and fields
+// in the class.
+
+class C {
+  var a;
+
+  get a {/*@compile-error=unspecified*/
+    return 1;
+  }
+
+  set a(int val) {/*@compile-error=unspecified*/
+    var x = val;
+  }
+
+  get b {
+    return 2;
+  }
+
+  set b(int val) {
+    var x = val;
+  }
+}
+
+class Field1Test {
+  static testMain() {
+    var c = new C();
+  }
+}
+
+main() {
+  Field1Test.testMain();
+}
diff --git a/tests/language/field/field2_test.dart b/tests/language/field/field2_test.dart
new file mode 100644
index 0000000..a822357
--- /dev/null
+++ b/tests/language/field/field2_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs in class fields declarations.
+// Should be an error because we have setter/getter functions and fields
+// in the class.
+
+class C {
+  get a {
+    return 1;
+  }
+
+  set a(int val) {
+    var x = val;
+  }
+
+  get b {
+    return 2;
+  }
+
+  set b(int val) {
+    var x = val;
+  }
+
+  var a;/*@compile-error=unspecified*/
+}
+
+class Field2Test {
+  static testMain() {
+    var c = new C();
+  }
+}
+
+main() {
+  Field2Test.testMain();
+}
diff --git a/tests/language/field/field3_test.dart b/tests/language/field/field3_test.dart
new file mode 100644
index 0000000..901dd06
--- /dev/null
+++ b/tests/language/field/field3_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs in class fields declarations.
+
+import "package:expect/expect.dart";
+
+class C {
+  // illegal: var cannot follow final
+  final var a = 0;// //# 00: syntax error
+  // illegal: final field declaration, must be initialized
+  final b; // //# 01: compile-time error
+  final c; // //# 02: compile-time error
+  final d; // //# 03: ok
+  final e; // //# 04: ok
+  final f = 0; // //# 05: ok
+
+  C() {} //# 02: continued
+  C(this.d) {} //# 03: continued
+  C(x) : e = x {} //# 04: continued
+}
+
+main() {
+  var val = new C(); //# 00: continued
+  var val = new C(); //# 01: continued
+  var val = new C(); //# 02: continued
+  var val = new C(0); //# 03: continued
+  var val = new C(0); //# 04: continued
+  var val = new C(); //# 05: continued
+}
diff --git a/tests/language/field/field4_test.dart b/tests/language/field/field4_test.dart
new file mode 100644
index 0000000..8c8ef6d
--- /dev/null
+++ b/tests/language/field/field4_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs in class fields declarations.
+// Should be an error because we have a field overriding a function name.
+
+class A {
+  int a() {
+    return 1;
+  }
+
+  var a;/*@compile-error=unspecified*/
+}
+
+class Field4Test {
+  static testMain() {
+    var a = new A();
+  }
+}
+
+main() {
+  Field4Test.testMain();
+}
diff --git a/tests/language/field/field5_test.dart b/tests/language/field/field5_test.dart
new file mode 100644
index 0000000..943e9bb
--- /dev/null
+++ b/tests/language/field/field5_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs in class fields declarations.
+// Should be an error because we have a function overriding a field name.
+
+class A {
+  var a;
+  int a() {/*@compile-error=unspecified*/
+    return 1;
+  }
+}
+
+class Field5Test {
+  static testMain() {
+    var a = new A();
+  }
+}
+
+main() {
+  Field5Test.testMain();
+}
diff --git a/tests/language/field/field6_test.dart b/tests/language/field/field6_test.dart
new file mode 100644
index 0000000..fcf0f40
--- /dev/null
+++ b/tests/language/field/field6_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs in class fields declarations.
+// Should be an error because we have a getter overriding a function name.
+
+class A {
+  int a() { // //# 00: ok
+    return 1;// //# 00: ok
+  }// //# 00: ok
+
+  int get a {// //# 00: compile-time error
+    return 10;// //# 00: ok
+  }// //# 00: ok
+
+  int get a {// //# 01: ok
+    return 10;// //# 01: ok
+  }// //# 01: ok
+
+  int a() {// //# 01: compile-time error
+    return 1;// //# 01: ok
+  }// //# 01: ok
+
+}
+
+class Field6Test {
+  static testMain() {
+    var a = new A();
+  }
+}
+
+main() {
+  Field6Test.testMain();
+}
diff --git a/tests/language/field/field_test.dart b/tests/language/field/field_test.dart
new file mode 100644
index 0000000..b5061ee
--- /dev/null
+++ b/tests/language/field/field_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing setting/getting of instance fields.
+
+import "package:expect/expect.dart";
+
+class First {
+  First() {}
+  var a;
+  var b;
+
+  addFields() {
+    return a + b;
+  }
+
+  setValues() {
+    a = 24;
+    b = 10;
+    return a + b;
+  }
+}
+
+class Second extends First {
+  var c;
+  get a {
+    return -12;
+  }
+
+  set b(a) {
+    a.c = 12;
+  }
+}
+
+class FieldInitializedToNull {
+  int? x, y;
+
+  static void test() {
+    var f = new FieldInitializedToNull();
+    int? missingArg([int? x = 42]) => x;
+    Expect.isNull(f.x);
+    Expect.isNull(f.y);
+    // Regression tests for a DDC bug, where undefined gets initialized in the
+    // fields, and is incorrect recognized as a missing argument.
+    Expect.isNull(missingArg(f.x));
+    Expect.isNull(missingArg(f.y));
+  }
+}
+
+class FieldTest {
+  static one() {
+    var f = new First();
+    f.a = 3;
+    f.b = f.a;
+    Expect.equals(3, f.a);
+    Expect.equals(f.a, f.b);
+    f.b = (f.a = 10);
+    Expect.equals(10, f.a);
+    Expect.equals(10, f.b);
+    f.b = f.a = 15;
+    Expect.equals(15, f.a);
+    Expect.equals(15, f.b);
+    Expect.equals(30, f.addFields());
+    Expect.equals(34, f.setValues());
+    Expect.equals(24, f.a);
+    Expect.equals(10, f.b);
+  }
+
+  static two() {
+    // The tests below are a little cumbersome because not
+    // everything is implemented yet.
+    var o = new Second();
+    // 'a' getter is overridden, always returns -12.
+    Expect.equals(-12, o.a);
+    o.a = 2;
+    Expect.equals(-12, o.a);
+    // 'b' setter is overridden to write 12 to field 'c'.
+    o.b = o;
+    Expect.equals(12, o.c);
+  }
+}
+
+main() {
+  FieldTest.one();
+  FieldTest.two();
+  FieldInitializedToNull.test();
+}
diff --git a/tests/language/field/increment_bailout_test.dart b/tests/language/field/increment_bailout_test.dart
new file mode 100644
index 0000000..1ee4e5a
--- /dev/null
+++ b/tests/language/field/increment_bailout_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2js regression test for issue 8781.
+
+import "package:expect/expect.dart";
+
+class N {
+  var outgoing;
+  var incoming;
+  N(this.outgoing, this.incoming);
+}
+
+class A {
+  int offset = 0;
+  var list;
+  var node;
+
+  A(node)
+      : node = node,
+        list = node.outgoing;
+
+  next() {
+    // dart2js used to update [offset] twice: once in the optimized
+    // version, which would bailout to the non-optimized version
+    // because [list] is not an Array, and once in the non-optimized
+    // version.
+    var edge = list[offset++];
+    if (list == node.outgoing) {
+      list = node.incoming;
+      offset = 0;
+    } else
+      list = null;
+    return edge;
+  }
+}
+
+main() {
+  var o = new A(new N(confuse([1]), confuse([2])));
+
+  for (var i = 1; i <= 2; i++) Expect.equals(i, o.next());
+
+  Expect.equals(null, o.list);
+}
+
+// Use confuse to defeat type inferencing.
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) {
+  return x;
+}
diff --git a/tests/language/field/inference_test.dart b/tests/language/field/inference_test.dart
new file mode 100644
index 0000000..7a0132b
--- /dev/null
+++ b/tests/language/field/inference_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js and its SsaConstructionFieldTypes
+// phase.
+
+import "package:expect/expect.dart";
+
+class A {
+  var _field;
+  final other;
+  get field => _field;
+  A(this._field) : other = null;
+  A.fromOther(this.other) {
+    _field = other.field;
+  }
+}
+
+class B {
+  var a;
+  B() {
+    try {
+      // Defeat inlining.
+      // An inlined generative constructor call used to confuse
+      // dart2js.
+      a = new A(42);
+    } catch (e) {
+      rethrow;
+    }
+  }
+}
+
+var array = [new A(42), new B()];
+
+main() {
+  // Surround the call to [analyzeAfterB] by two [: new B() :] calls
+  // to ensure the [B] constructor will be analyzed first.
+  new B();
+  var a = analyzeAfterB();
+  new B();
+  Expect.equals(42, a._field);
+}
+
+analyzeAfterB() {
+  try {
+    // Defeat inlining.
+    return new A.fromOther(array[0]);
+  } catch (e) {
+    rethrow;
+  }
+}
diff --git a/tests/language/field/initialization_order_test.dart b/tests/language/field/initialization_order_test.dart
new file mode 100644
index 0000000..832b712
--- /dev/null
+++ b/tests/language/field/initialization_order_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that field initializers are evaluated in the right order.
+
+int counter = 0;
+
+class Mark {
+  static late StringBuffer buffer;
+  Mark(value) {
+    buffer.write('$value.');
+  }
+}
+
+class OneField {
+  var a = new Mark('a');
+
+  OneField();
+
+  OneField.init() : a = new Mark('ai');
+}
+
+class TwoFields {
+  var b = new Mark('b');
+  var a = new Mark('a');
+
+  TwoFields();
+
+  TwoFields.initA() : a = new Mark('ai');
+
+  TwoFields.initB() : b = new Mark('bi');
+
+  TwoFields.initBoth()
+      : a = new Mark('ai'),
+        b = new Mark('bi');
+}
+
+class InheritOneField extends OneField {
+  var b = new Mark('b');
+
+  InheritOneField() : super();
+
+  InheritOneField.init()
+      : b = new Mark('bi'),
+        super();
+
+  InheritOneField.superWithInit() : super.init();
+
+  InheritOneField.initWithSuperInit_correctOrder()
+      : b = new Mark('bi'),
+        super.init();
+
+  InheritOneField.initWithSuperInit_incorrectOrder()
+      :
+        super.init(), //# 01: compile-time error
+        b = new Mark('bi')
+        , super.init() //# none: ok
+  ;
+}
+
+String run(callback) {
+  Mark.buffer = new StringBuffer();
+  callback();
+  return Mark.buffer.toString();
+}
+
+main() {
+  Expect.equals('a.', run(() => new OneField()));
+  Expect.equals('a.ai.', run(() => new OneField.init()));
+
+  Expect.equals('b.a.', run(() => new TwoFields()));
+  Expect.equals('b.a.ai.', run(() => new TwoFields.initA()));
+  Expect.equals('b.a.bi.', run(() => new TwoFields.initB()));
+  Expect.equals('b.a.ai.bi.', run(() => new TwoFields.initBoth()));
+
+  Expect.equals('b.a.', run(() => new InheritOneField()));
+  Expect.equals('b.bi.a.', run(() => new InheritOneField.init()));
+  Expect.equals('b.a.ai.', run(() => new InheritOneField.superWithInit()));
+  Expect.equals(
+      'b.bi.a.ai.', run(() => new InheritOneField.initWithSuperInit_correctOrder()));
+  Expect.equals(
+      'b.bi.a.ai.', run(() => new InheritOneField.initWithSuperInit_incorrectOrder()));
+}
diff --git a/tests/language/field/method4_test.dart b/tests/language/field/method4_test.dart
new file mode 100644
index 0000000..c637241
--- /dev/null
+++ b/tests/language/field/method4_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test to catch error reporting bugs when using a field like a method.
+
+class A {
+  var foo;
+  A() {
+    foo = () {};
+  }
+  void bar(var a) {
+    a.foo();/*@compile-error=unspecified*/ // Tries to invoke the non-existing method 'foo'.
+    /*
+    'a.foo()' is a "Regular instance-method invocation". The guide says:
+    "If no method is found, the result of the invocation expression is
+    equivalent to: $0.noSuchMethod(r"id", [$1, ..., $N])."
+    Invoking noSuchMethod on an instance of A will invoke Object's
+    noSuchMethod (because A doesn't override that method). Object's
+    noSuchMethod will throw an error.
+    */
+  }
+}
+
+class FieldMethod4Test {
+  static testMain() {
+    var a = new A();
+    a.bar();/*@compile-error=unspecified*/
+  }
+}
+
+main() {
+  FieldMethod4Test.testMain();
+}
diff --git a/tests/language/field/method_test.dart b/tests/language/field/method_test.dart
new file mode 100644
index 0000000..012b60a
--- /dev/null
+++ b/tests/language/field/method_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test. Fields can be invoked directly if they are unqualified.
+
+class A {
+  var foo;
+  A() {
+    foo = () {};
+  }
+  void bar() {
+    foo(); // <= foo is a field, but can still be invoked without parenthesis.
+  }
+}
+
+class FieldMethodTest {
+  static testMain() {
+    new A().bar();
+  }
+}
+
+main() {
+  FieldMethodTest.testMain();
+}
diff --git a/tests/language/field/optimization2_test.dart b/tests/language/field/optimization2_test.dart
new file mode 100644
index 0000000..d0ee6bd
--- /dev/null
+++ b/tests/language/field/optimization2_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program to test type-based optimization on fields.
+
+class A {
+  var x;
+  A() : x = new B();
+  foo() {
+    x++;
+  }
+}
+
+class B {
+  operator +(other) => 498;
+}
+
+main() {
+  var a = new A();
+  a.foo();
+  a.foo();
+  Expect.equals(499, a.x);
+}
diff --git a/tests/language/field/optimization3_test.dart b/tests/language/field/optimization3_test.dart
new file mode 100644
index 0000000..bf2ec9a
--- /dev/null
+++ b/tests/language/field/optimization3_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program to test type-based optimization on fields.
+
+class A {
+  dynamic a = 0;
+  var b = 0;
+  foo() {
+    var c = b + 27;
+    for (var i = 0; i < 1; i++) {
+      for (var j = 0; j < 1; j++) {
+        Expect.equals(50, c + 23);
+      }
+    }
+    return a > 0.2;
+  }
+
+  setA(value) {
+    a = value;
+  }
+
+  setB(value) {
+    b = value;
+  }
+
+  operator >(other) => other == 0.2;
+}
+
+main() {
+  var a = new A();
+  Expect.isFalse(a.foo());
+  a.setA(new A());
+  a.setB(0);
+  Expect.isTrue(a.foo());
+}
diff --git a/tests/language/field/optimization_test.dart b/tests/language/field/optimization_test.dart
new file mode 100644
index 0000000..58a1461
--- /dev/null
+++ b/tests/language/field/optimization_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program to test type-based optimization on fields.
+
+class A {
+  var x;
+  A() : x = 0;
+  foo() {
+    x++;
+  }
+
+  toto() {
+    x = 99;
+  }
+
+  bar(y) {
+    x = y;
+  }
+}
+
+class B {
+  operator +(other) => "ok";
+}
+
+main() {
+  var a = new A();
+  a.foo();
+  a.toto();
+  a.bar("str");
+  a.bar(new B());
+  a.foo();
+  Expect.equals("ok", a.x);
+}
diff --git a/tests/language/field/override2_test.dart b/tests/language/field/override2_test.dart
new file mode 100644
index 0000000..d37a8ba
--- /dev/null
+++ b/tests/language/field/override2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we are accessing the right field in a method of a super
+// class, when that field is overridden.
+
+import "package:expect/expect.dart";
+
+class A {
+  final a = [42]; /*@compile-error=unspecified*/
+  foo() => a[0];
+}
+
+class B extends A {
+  final a = new Map();
+}
+
+main() {
+  Expect.equals(null, new B().foo());
+  Expect.equals(42, new A().foo());
+}
diff --git a/tests/language/field/override3_test.dart b/tests/language/field/override3_test.dart
new file mode 100644
index 0000000..9b100be
--- /dev/null
+++ b/tests/language/field/override3_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when a static field conflicts with
+// an inherited instance member of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42; // //# 00: compile-time error
+  get foo => 42; // //# 01: compile-time error
+  foo() => 42; // //# 02: compile-time error
+  set foo(value) { } // //# 03: compile-time error
+}
+
+class B extends A {
+  static var foo = 42;
+}
+
+main() {
+  Expect.equals(42, B.foo);
+}
diff --git a/tests/language/field/override4_test.dart b/tests/language/field/override4_test.dart
new file mode 100644
index 0000000..0ccee61
--- /dev/null
+++ b/tests/language/field/override4_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when an instance field conflicts
+// with an inherited instance method of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  dynamic foo = 42; // //# 00: ok
+  get foo => 42; // //# 01: ok
+  foo() => 42; // //# 02: compile-time error
+  set foo(value) { } // //# 03: ok
+}
+
+class B extends A {
+  dynamic foo = 42;
+}
+
+main() {
+  Expect.equals(42, new B().foo);
+}
diff --git a/tests/language/field/override_optimization_test.dart b/tests/language/field/override_optimization_test.dart
new file mode 100644
index 0000000..83ad81e
--- /dev/null
+++ b/tests/language/field/override_optimization_test.dart
@@ -0,0 +1,34 @@
+// 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:expect/expect.dart";
+import "package:meta/meta.dart";
+
+class A {
+  @virtual
+  final dynamic flag = true;
+  @virtual
+  final dynamic x = 42;
+}
+
+class B extends A {
+  dynamic flag;
+  dynamic x;
+}
+
+void main() {
+  A a = new B();
+  var exception;
+  try {
+    if (a.flag) {
+      Expect.fail('This should be unreachable');
+    } else {
+      Expect.fail('This should also be unreachable');
+    }
+  } catch (e) {
+    exception = e;
+  }
+  Expect.isTrue(exception is AssertionError || exception is TypeError);
+  Expect.throws(() => a.x + 8);
+}
diff --git a/tests/language/field/override_test.dart b/tests/language/field/override_test.dart
new file mode 100644
index 0000000..187773b
--- /dev/null
+++ b/tests/language/field/override_test.dart
@@ -0,0 +1,50 @@
+// 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.
+// Test overriding of fields.
+
+import "package:expect/expect.dart";
+
+class A {}
+
+class B1 extends A {}
+
+class B2 extends A {}
+
+class Super {
+  Super() : super();
+
+  B1 field;
+}
+
+class Sub extends Super {
+  Sub() : super();
+
+  // Invalid override. The type of 'Sub.field' ('() → A') isn't a subtype of
+  // 'Super.field' ('() → B1').
+  A field; // //# 00: compile-time error
+}
+
+class SubSub extends Super {
+  SubSub() : super();
+
+  // B2 not assignable to B1
+  B2 field; // //# 01: compile-time error
+}
+
+main() {
+  SubSub val1 = new SubSub();
+  val1.field = new B2(); //# 02: compile-time error
+  Expect.equals(true, val1.field is B2); //# 02: continued
+
+  Sub val2 = new Sub();
+  val2.field = new A(); //# none: compile-time error
+  Expect.equals(true, val2.field is A);
+  Expect.equals(false, val2.field is B1);
+  Expect.equals(false, val2.field is B2);
+
+  Super val3 = new Super();
+  val3.field = new B1();
+  Expect.equals(true, val3.field is B1);
+  Expect.equals(false, val3.field is B2);
+}
diff --git a/tests/language/field/parameter_test.dart b/tests/language/field/parameter_test.dart
new file mode 100644
index 0000000..58d0639
--- /dev/null
+++ b/tests/language/field/parameter_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing setting/getting of instance fields.
+
+import "package:expect/expect.dart";
+
+class A {
+  int? x = 4;
+  A(this.x);
+  A.named([this.x]);
+  A.named2([this.x = 2]);
+  A.named3();
+}
+
+class B extends A {
+  B(x) : super(x + 10);
+  B.named_() : super.named();
+  B.named(x) : super.named(x + 10);
+  B.named2_() : super.named2();
+  B.named2(x) : super.named2(x + 10);
+  B.named3() : super.named3();
+}
+
+main() {
+  Expect.equals(0, new A(0).x);
+  Expect.equals(null, new A.named().x);
+  Expect.equals(1, new A.named(1).x);
+  Expect.equals(2, new A.named2().x);
+  Expect.equals(3, new A.named2(3).x);
+  Expect.equals(4, new A.named3().x);
+
+  Expect.equals(10, new B(0).x);
+  Expect.equals(null, new B.named_().x);
+  Expect.equals(11, new B.named(1).x);
+  Expect.equals(2, new B.named2_().x);
+  Expect.equals(13, new B.named2(3).x);
+  Expect.equals(4, new B.named3().x);
+}
diff --git a/tests/language/field/super_access2_test.dart b/tests/language/field/super_access2_test.dart
new file mode 100644
index 0000000..e1decf8
--- /dev/null
+++ b/tests/language/field/super_access2_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// Tests that a super call to access a field in a super class is just a normal
+// field access.
+
+import "package:expect/expect.dart";
+
+class A {
+  final int y = 42;
+}
+
+class B extends A {
+  int get x => super.y;
+  void set x(val) {}
+}
+
+void main() {
+  var b = new B();
+  Expect.equals(42, b.x);
+}
diff --git a/tests/language/field/super_access_test.dart b/tests/language/field/super_access_test.dart
new file mode 100644
index 0000000..7f6bf2d
--- /dev/null
+++ b/tests/language/field/super_access_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Tests that a super call to access a field in a super class is just a normal
+// field access.
+
+import "package:expect/expect.dart";
+
+class A {
+  int? y;
+}
+
+class B extends A {
+  int? get x => super.y;
+  void set x(val) {
+    super.y = val;
+  }
+}
+
+void main() {
+  var b = new B();
+  b.x = 42;
+  Expect.equals(42, b.x);
+}
diff --git a/tests/language/field/type_check2_test.dart b/tests/language/field/type_check2_test.dart
new file mode 100644
index 0000000..3cd1f00
--- /dev/null
+++ b/tests/language/field/type_check2_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+class A {
+  A? a;
+
+  bar(c) {
+    c.a = 2; //# 01: runtime error
+  }
+}
+
+class B {
+  int? a;
+}
+
+main() {
+  new A().bar(new A()); //# 01: continued
+  new A().bar(new B());
+}
diff --git a/tests/language/field/type_check_runtime_test.dart b/tests/language/field/type_check_runtime_test.dart
new file mode 100644
index 0000000..367e950
--- /dev/null
+++ b/tests/language/field/type_check_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class A {
+  int e = -1;
+}
+
+void main() {
+
+}
diff --git a/tests/language/field/type_check_test.dart b/tests/language/field/type_check_test.dart
new file mode 100644
index 0000000..09b5507
--- /dev/null
+++ b/tests/language/field/type_check_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  int e = -1;
+}
+
+void main() {
+  new A().e = "String";
+  //          ^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+  // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
+}
diff --git a/tests/language/field/wierd_name_test.dart b/tests/language/field/wierd_name_test.dart
new file mode 100644
index 0000000..d76eaa8
--- /dev/null
+++ b/tests/language/field/wierd_name_test.dart
@@ -0,0 +1,149 @@
+// 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 program for testing setting/getting of instance fields.
+
+import "package:expect/expect.dart";
+
+// dart2js used to have a bug where a local called '_' in the constructor
+// shadowed the parameter named after a field. This lead to the field being
+// initialized to 'this' (a cycle) rather than the correct initializer value.
+//
+// This test is in the language tests rather than dart2js specific tests since
+// the dart2js specific tests are not run in all configurations that could
+// tickle this issue.
+
+int ii = 0;
+
+class Thing {
+  var _;
+  var $_;
+  // Extra fields to make use of local in constructor beneficial and to exhaust
+  // single-character names.
+  var a = ++ii, b = ++ii, c = ++ii, d = ++ii, e = ++ii;
+  var f = ++ii, g = ++ii, h = ++ii, i = ++ii, j = ++ii;
+  var k = ++ii, l = ++ii, m = ++ii, n = ++ii, o = ++ii;
+  var p = ++ii, q = ++ii, r = ++ii, s = ++ii, t = ++ii;
+  var u = ++ii, v = ++ii, w = ++ii, x = ++ii, y = ++ii;
+  var z = ++ii;
+  var A = ++ii, B = ++ii, C = ++ii, D = ++ii, E = ++ii;
+  var F = ++ii, G = ++ii, H = ++ii, I = ++ii, J = ++ii;
+  var K = ++ii, L = ++ii, M = ++ii, N = ++ii, O = ++ii;
+  var P = ++ii, Q = ++ii, R = ++ii, S = ++ii, T = ++ii;
+  var U = ++ii, V = ++ii, W = ++ii, X = ++ii, Y = ++ii;
+  var Z = ++ii;
+  var $ = ++ii;
+
+  var f30 = ++ii, f31 = ++ii, f32 = ++ii, f33 = ++ii, f34 = ++ii;
+  var f35 = ++ii, f36 = ++ii, f37 = ++ii, f38 = ++ii, f39 = ++ii;
+  var f40 = ++ii, f41 = ++ii, f42 = ++ii, f43 = ++ii, f44 = ++ii;
+  var f45 = ++ii, f46 = ++ii, f47 = ++ii, f48 = ++ii, f49 = ++ii;
+  var f50 = ++ii, f51 = ++ii, f52 = ++ii, f53 = ++ii, f54 = ++ii;
+  var f55 = ++ii, f56 = ++ii, f57 = ++ii, f58 = ++ii, f59 = ++ii;
+
+  @pragma('dart2js:noInline')
+  Thing(this._, this.$_);
+  toString() {
+    if (depth > 0) return 'recursion!';
+    try {
+      ++depth;
+      var sum = a +
+          b +
+          c +
+          d +
+          e +
+          f +
+          g +
+          h +
+          i +
+          j +
+          k +
+          l +
+          m +
+          n +
+          o +
+          p +
+          q +
+          r +
+          s +
+          t +
+          u +
+          v +
+          w +
+          x +
+          y +
+          z +
+          A +
+          B +
+          C +
+          D +
+          E +
+          F +
+          G +
+          H +
+          I +
+          J +
+          K +
+          L +
+          M +
+          N +
+          O +
+          P +
+          Q +
+          R +
+          S +
+          T +
+          U +
+          V +
+          W +
+          X +
+          Y +
+          Z +
+          $ +
+          f30 +
+          f31 +
+          f32 +
+          f33 +
+          f34 +
+          f35 +
+          f36 +
+          f37 +
+          f38 +
+          f39 +
+          f40 +
+          f41 +
+          f42 +
+          f43 +
+          f44 +
+          f45 +
+          f46 +
+          f47 +
+          f48 +
+          f49 +
+          f50 +
+          f51 +
+          f52 +
+          f53 +
+          f54 +
+          f55 +
+          f56 +
+          f57 +
+          f58 +
+          f59;
+      return 'Thing(${_}, ${$_}, ${sum})';
+    } finally {
+      --depth;
+    }
+  }
+
+  static int depth = 0;
+}
+
+main() {
+  var t1 = new Thing(1, 2);
+  var t2 = new Thing(3, 4);
+  var t3 = [];
+
+  Expect.equals(
+      '[Thing(1, 2, 3486), Thing(3, 4, 10375), []]', '${[t1, t2, t3]}');
+}
diff --git a/tests/language/final/attempt_reinitialization_runtime_test.dart b/tests/language/final/attempt_reinitialization_runtime_test.dart
new file mode 100644
index 0000000..b16a2c7
--- /dev/null
+++ b/tests/language/final/attempt_reinitialization_runtime_test.dart
@@ -0,0 +1,23 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Foo {
+
+
+}
+
+class CoffeeShop {
+
+
+
+}
+
+void main() {
+
+
+
+}
diff --git a/tests/language/final/attempt_reinitialization_test.dart b/tests/language/final/attempt_reinitialization_test.dart
new file mode 100644
index 0000000..009998b
--- /dev/null
+++ b/tests/language/final/attempt_reinitialization_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+class Foo {
+  Foo(this.x);
+  //       ^
+  // [analyzer] STATIC_WARNING.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
+  // [cfe] 'x' is a final instance variable that has already been initialized.
+  final int x = 42;
+}
+
+class CoffeeShop {
+  final String shopName = "Coffee Lab";
+  CoffeeShop.name(String shopName)
+      : this.shopName = shopName;
+      //     ^^^^^^^^
+      // [analyzer] STATIC_WARNING.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
+      //              ^
+      // [cfe] 'shopName' is a final instance variable that has already been initialized.
+}
+
+void main() {
+  Foo f = new Foo(10);
+  CoffeeShop presidentialCoffee =
+      new CoffeeShop.name("Covfefe Lab");
+}
diff --git a/tests/language/final/field_initialization_order_test.dart b/tests/language/final/field_initialization_order_test.dart
new file mode 100644
index 0000000..69f8b11
--- /dev/null
+++ b/tests/language/final/field_initialization_order_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that initializers for final fields are evaluated in the right
+// order.
+
+int counter = 0;
+
+class Mark {
+  static late StringBuffer buffer;
+  Mark(value) {
+    buffer.write('$value.');
+  }
+}
+
+class OneField {
+  final a = new Mark('a');
+  OneField();
+}
+
+class TwoFields {
+  final a = new Mark('a');
+  final b = new Mark('b');
+  TwoFields();
+}
+
+class InheritOneField extends OneField {
+  final b = new Mark('b');
+  InheritOneField();
+}
+
+class MixedFields extends OneField {
+  final b = new Mark('b');
+  var c = new Mark('c');
+  final d = new Mark('d');
+  MixedFields();
+  MixedFields.c0() : c = new Mark('cc');
+  MixedFields.c1()
+      : c = new Mark('cc'),
+        super();
+}
+
+String run(callback) {
+  Mark.buffer = new StringBuffer();
+  callback();
+  return Mark.buffer.toString();
+}
+
+main() {
+  Expect.equals('a.', run(() => new OneField()));
+  Expect.equals('a.b.', run(() => new TwoFields()));
+  Expect.equals('b.a.', run(() => new InheritOneField()));
+
+  Expect.equals('b.c.d.a.', run(() => new MixedFields()));
+  Expect.equals('b.c.d.cc.a.', run(() => new MixedFields.c0()));
+  Expect.equals('b.c.d.cc.a.', run(() => new MixedFields.c1()));
+}
diff --git a/tests/language/final/field_override_test.dart b/tests/language/final/field_override_test.dart
new file mode 100644
index 0000000..5548bdf
--- /dev/null
+++ b/tests/language/final/field_override_test.dart
@@ -0,0 +1,29 @@
+// 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:expect/expect.dart";
+
+class A {
+  int _x = 42;
+  void set x(int val) {
+    _x = val;
+  }
+
+  int get x => _x;
+}
+
+class B extends A {
+  final x = 3;
+  // we can still get to the super property
+  int get y => _x;
+}
+
+void main() {
+  var b = new B();
+  Expect.equals(3, b.x);
+
+  b.x = 21;
+  Expect.equals(3, b.x);
+  Expect.equals(21, b.y);
+}
diff --git a/tests/language/final/for_in_variable_test.dart b/tests/language/final/for_in_variable_test.dart
new file mode 100644
index 0000000..0365e67
--- /dev/null
+++ b/tests/language/final/for_in_variable_test.dart
@@ -0,0 +1,9 @@
+// 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.
+
+main() {
+  for (final i in [1, 2, 3]) {
+    i = 4; /*@compile-error=unspecified*/
+  }
+}
diff --git a/tests/language/final/initializer_instance_reference_test.dart b/tests/language/final/initializer_instance_reference_test.dart
new file mode 100644
index 0000000..1f17dfc
--- /dev/null
+++ b/tests/language/final/initializer_instance_reference_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// Dart2js regression test. Error in initializer might be report with the wrong
+// current element.
+
+class C {
+  const C();
+
+  final x = 1;
+  final y = x; /*@compile-error=unspecified*/
+}
+
+main() {
+  const C().y;
+}
diff --git a/tests/language/final/is_not_const_test.dart b/tests/language/final/is_not_const_test.dart
new file mode 100644
index 0000000..798b40f
--- /dev/null
+++ b/tests/language/final/is_not_const_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+final F0 = 42;
+const C0 = F0; /*@compile-error=unspecified*/
+
+main() {
+  Expect.equals(42, F0);
+  Expect.equals(42, C0);
+}
diff --git a/tests/language/final/param_test.dart b/tests/language/final/param_test.dart
new file mode 100644
index 0000000..197e357
--- /dev/null
+++ b/tests/language/final/param_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Disallow assignment of parameters marked as final.
+
+class A {
+  static void test(final x) {
+    x = 2; /*@compile-error=unspecified*/
+  }
+}
+
+main() {
+  A.test(1);
+}
diff --git a/tests/language/final/super_field_set_test.dart b/tests/language/final/super_field_set_test.dart
new file mode 100644
index 0000000..227b272
--- /dev/null
+++ b/tests/language/final/super_field_set_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+class SuperClass {
+  final field = 0;
+  noSuchMethod(_) => 42;
+}
+
+class Class extends SuperClass {
+  m() {
+    super.field = 87; /*@compile-error=unspecified*/
+  }
+}
+
+main() {
+  new Class().m();
+}
diff --git a/tests/language/final/syntax_test.dart b/tests/language/final/syntax_test.dart
new file mode 100644
index 0000000..42b2163
--- /dev/null
+++ b/tests/language/final/syntax_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  final f0 = 42;
+  final f1; //# 01: compile-time error
+  final int f2 = 87;
+  final int f3; //# 02: compile-time error
+  Expect.equals(42, f0);
+  Expect.equals(87, f2);
+
+  Expect.equals(42, F0);
+  Expect.equals(null, F1); //# 03: continued
+  Expect.equals(87, F2);
+  Expect.equals(null, F3); //# 04: continued
+
+  Expect.isTrue(P0 is Point);
+  Expect.isTrue(P1 is int);
+  Expect.isTrue(P2 is Point);
+  Expect.isTrue(P3 is int);
+
+  Expect.isTrue(A0 is int);
+  Expect.isTrue(A1 is int);
+  Expect.isTrue(A2 is int); //# 08: runtime error
+  Expect.isTrue(A3 is int); //# 08: continued
+
+  Expect.isTrue(C0.X is C1);
+  Expect.isTrue(C0.X.x is C1); //# 09: compile-time error
+
+  Expect.equals("Hello 42", B2);
+  Expect.equals("42Hello", B3); //# 10: compile-time error
+}
+
+final F0 = 42;
+final F1; //                //# 03: syntax error
+final int F2 = 87;
+final int F3; //            //# 04: syntax error
+
+class Point {
+  final x, y;
+  const Point(this.x, this.y);
+  operator +(int other) => x;
+}
+
+// Check that compile time expressions can include invocations of
+// user-defined final constructors.
+final P0 = const Point(0, 0);
+final P1 = const Point(0, 0) + 1;
+final P2 = new Point(0, 0);
+final P3 = new Point(0, 0) + 1;
+
+// Check that we cannot have cyclic references in compile time
+// expressions.
+final A0 = 42;
+final A1 = A0 + 1;
+final dynamic A2 = A3 + 1; //# 08: continued
+final dynamic A3 = A2 + 1; //# 08: continued
+
+class C0 {
+  static final X = const C1();
+}
+
+class C1 {
+  const C1()
+      : x = C0.X //# 09: continued
+  ;
+  final x = null;
+}
+
+// Check that sub-expressions of binary + are numeric.
+final B0 = 42;
+final B1 = "Hello";
+final B2 = "$B1 $B0";
+final B3 = B0 + B1; //# 10: continued
diff --git a/tests/language/final/used_in_try_test.dart b/tests/language/final/used_in_try_test.dart
new file mode 100644
index 0000000..259ba8d
--- /dev/null
+++ b/tests/language/final/used_in_try_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  while (true) {
+    final a = 'fff'.substring(1, 2);
+    try {
+      Expect.equals('f', a);
+    } catch (e) {
+      rethrow;
+    }
+    break;
+  }
+}
diff --git a/tests/language/final/variable_assignment_runtime_test.dart b/tests/language/final/variable_assignment_runtime_test.dart
new file mode 100644
index 0000000..1fabb8b
--- /dev/null
+++ b/tests/language/final/variable_assignment_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test to make sure we catch assignments to final local variables.
+
+main() {
+  final x = 30;
+
+
+
+
+}
diff --git a/tests/language/final/variable_assignment_test.dart b/tests/language/final/variable_assignment_test.dart
new file mode 100644
index 0000000..f001d40
--- /dev/null
+++ b/tests/language/final/variable_assignment_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Test to make sure we catch assignments to final local variables.
+
+main() {
+  final x = 30;
+  x = 0;
+//^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
+// [cfe] Can't assign to the final variable 'x'.
+  x += 1;
+//^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
+// [cfe] Can't assign to the final variable 'x'.
+  ++x;
+  //^
+  // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
+  // [cfe] Can't assign to the final variable 'x'.
+  x++;
+//^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
+// [cfe] Can't assign to the final variable 'x'.
+}
diff --git a/tests/language/function/apply_generic2_test.dart b/tests/language/function/apply_generic2_test.dart
new file mode 100644
index 0000000..d45117a
--- /dev/null
+++ b/tests/language/function/apply_generic2_test.dart
@@ -0,0 +1,47 @@
+// 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:expect/expect.dart";
+
+makeFn() {
+  return <T extends num>({T? a1, T? a2, T? a3, T? a4, T? a5}) {
+    return <T?>[a1, a2, a3, a4, a5];
+  };
+}
+
+staticFn<T extends num>({T? a1, T? a2, T? a3, T? a4, T? a5, T? xx}) {
+  return <T?>[a1, a2, a3, a4, a5, xx];
+}
+
+class CCC {
+  memberFn<T extends num>({T? a1, T? a2, T? a3, T? a4, T? a5, T? yy}) {
+    return <T?>[a1, a2, a3, a4, a5, yy];
+  }
+}
+
+check(a, b) {
+  print('a: $a\nb: $b');
+  Expect.equals(a.toString(), b.toString());
+}
+
+main() {
+  check('[null, 33, null, 11, 22, null]',
+      Function.apply(new CCC().memberFn, [], {#a4: 11, #a5: 22, #a2: 33}));
+
+  Expect.throwsTypeError(
+      () => Function.apply(new CCC().memberFn, [], {#a3: 'hi'}));
+
+  check('[11, 22, 33, null, null]',
+      Function.apply(makeFn(), [], {#a1: 11, #a2: 22, #a3: 33}));
+
+  check('[null, 33, null, 11, 22]',
+      Function.apply(makeFn(), [], {#a4: 11, #a5: 22, #a2: 33}));
+
+  Expect.throwsTypeError(() => Function.apply(makeFn(), [], {#a3: 'hi'}));
+
+  check('[null, 33, null, 11, 22, null]',
+      Function.apply(staticFn, [], {#a4: 11, #a5: 22, #a2: 33}));
+
+  Expect.throwsTypeError(() => Function.apply(staticFn, [], {#a3: 'hi'}));
+}
diff --git a/tests/language/function/apply_generic_test.dart b/tests/language/function/apply_generic_test.dart
new file mode 100644
index 0000000..4831e5d
--- /dev/null
+++ b/tests/language/function/apply_generic_test.dart
@@ -0,0 +1,64 @@
+// 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:expect/expect.dart";
+
+List<T?> staticFn<T>(
+    [T? a1, T? a2, T? a3, T? a4, T? a5, T? a6, T? a7, T? a8, T? a9, T? a10]) {
+  return <T?>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+}
+
+class C<CT> {
+  List<T?> memberFn<T>(
+      [T? a1, T? a2, T? a3, T? a4, T? a5, T? a6, T? a7, T? a8, T? a9, T? a10]) {
+    return <T?>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+  }
+
+  // Intercepted, e.g. on JSArray.
+  List<T?> map<T>(
+      [T? a1, T? a2, T? a3, T? a4, T? a5, T? a6, T? a7, T? a8, T? a9, T? a10]) {
+    return <T?>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+  }
+}
+
+check(a, b) {
+  print('a: $a\nb: $b');
+  Expect.equals(a.toString(), b.toString());
+}
+
+main() {
+  check('[1, 2, 3, null, null, null, null, null, null, null]',
+      Function.apply(staticFn, [1, 2, 3]));
+
+  check('[1, 2, 3, 4, null, null, null, null, null, null]',
+      Function.apply(staticFn, [1, 2, 3, 4]));
+
+  check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+      Function.apply(staticFn, [1, 2, 3, 4, 5, 6, 7]));
+
+  var o = new C<num>();
+  dynamic memberFn1 = o.map;
+
+  check('[1, 2, 3, null, null, null, null, null, null, null]',
+      Function.apply(memberFn1, [1, 2, 3]));
+
+  check('[1, 2, 3, 4, null, null, null, null, null, null]',
+      Function.apply(memberFn1, [1, 2, 3, 4]));
+
+  check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+      Function.apply(memberFn1, [1, 2, 3, 4, 5, 6, 7]));
+
+  dynamic memberFn2 = o.memberFn;
+
+  check('[1, 2, 3, null, null, null, null, null, null, null]',
+      Function.apply(memberFn2, [1, 2, 3]));
+
+  check('[1, 2, 3, 4, null, null, null, null, null, null]',
+      Function.apply(memberFn2, [1, 2, 3, 4]));
+
+  check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+      Function.apply(memberFn2, [1, 2, 3, 4, 5, 6, 7]));
+
+  // TODO(sra): Apply of instantiations
+}
diff --git a/tests/language/function/argument_test.dart b/tests/language/function/argument_test.dart
new file mode 100644
index 0000000..f56861a
--- /dev/null
+++ b/tests/language/function/argument_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for function passing.
+
+import "package:expect/expect.dart";
+
+class FunctionArgumentTest {
+  static testMe(Function f) {
+    return f();
+  }
+
+  static void testMain() {
+    Expect.equals(42, testMe(() {
+      return 42;
+    }));
+  }
+}
+
+main() {
+  FunctionArgumentTest.testMain();
+}
diff --git a/tests/language/function/call_generic_test.dart b/tests/language/function/call_generic_test.dart
new file mode 100644
index 0000000..de3b0bd
--- /dev/null
+++ b/tests/language/function/call_generic_test.dart
@@ -0,0 +1,83 @@
+// 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.
+// dart2jsOptions=-Ddart.isdart2js=true
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+List staticFn<T>([T? a1, T? a2, T? a3, T? a4, T? a5]) => [T, a1, a2, a3, a4, a5];
+
+class C {
+  @pragma('dart2js:noInline')
+  List memberFn<T>([T? a1, T? a2, T? a3, T? a4, T? a5]) => [T, a1, a2, a3, a4, a5];
+
+  @pragma('dart2js:noInline')
+  // 'map' is implemented by native iterables. On dart2js, 'map' has interceptor
+  // calling convention.
+  List map<T>([T? a1, T? a2, T? a3, T? a4, T? a5]) => [T, a1, a2, a3, a4, a5];
+}
+
+check(expected, actual) {
+  print('a:  $expected');
+  print('b:  $actual');
+  if (((actual[0] == Object && expected[0] == dynamic) ||
+          (actual[0] == dynamic && expected[0] == Object)) &&
+      !const bool.fromEnvironment('dart.isdart2js')) {
+    // TODO(32483): dartdevk sometimes defaults type to 'Object' when 'dynamic'
+    // is required. Remove this hack when fixed.
+    // TODO(31581): dart2js needs instantiate-to-bound to generic 'dynamic'
+    // instead of 'Object'.
+    actual = actual.toList()..[0] = expected[0];
+    print('b*: $actual');
+  }
+  Expect.equals(expected.toString(), actual.toString());
+}
+
+main() {
+  check([dynamic, 1, 2, 3, null, null], staticFn(1 as dynamic, 2, 3));
+
+  check([Object, 'Z', 2, 4, null, null], staticFn('Z', 2, 4));
+
+  check([int, 3, 2, 1, null, null], staticFn(3, 2, 1));
+
+  dynamic f1 = staticFn;
+
+  check([dynamic, 4, 2, 3, null, null], f1(4 as dynamic, 2, 3));
+
+  check([dynamic, 'Q', 2, 3, null, null], f1('Q', 2, 3));
+
+  check([dynamic, 6, 2, 3, null, null], f1(6, 2, 3));
+
+  check([int, 7, 2, null, null, null], f1<int>(7, 2));
+
+  var c = new C();
+
+  check([dynamic, 8, 2, 3, null, null], c.memberFn(8 as dynamic, 2, 3));
+
+  check([Object, 'A', 2, 3, null, null], c.memberFn('A', 2, 3));
+
+  check([int, 9, 2, 3, null, null], c.memberFn<int>(9, 2, 3));
+
+  check([dynamic, 10, 2, 3, null, null], c.map(10 as dynamic, 2, 3));
+
+  check([Object, 'B', 2, 3, null, null], c.map('B', 2, 3));
+
+  check([int, 11, 2, 3, null, null], c.map(11, 2, 3));
+
+  dynamic o = new C();
+
+  check([dynamic, 12, 2, 3, null, null], o.memberFn(12 as dynamic, 2, 3));
+
+  check([dynamic, 'C', 2, 3, null, null], o.memberFn('C', 2, 3));
+
+  check([int, 13, 2, null, null, null], o.memberFn<int>(13, 2));
+
+  check([dynamic, 14, 2, 3, null, null], o.map(14 as dynamic, 2, 3));
+
+  check([dynamic, 'D', 2, 3, null, null], o.map('D', 2, 3));
+
+  check([int, 15, null, null, null, null], o.map<int>(15));
+
+  check([int, 16, 2, 3, 4, null], o.map<int>(16, 2, 3, 4));
+}
diff --git a/tests/language/function/field_test.dart b/tests/language/function/field_test.dart
new file mode 100644
index 0000000..099a11d
--- /dev/null
+++ b/tests/language/function/field_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--fatal-type-errors --enable_type_checks
+//
+// Test of calling Function, which is field of some class.
+
+import "package:expect/expect.dart";
+
+class Wrapper {
+  late Function f;
+}
+
+main() {
+  Wrapper w = new Wrapper();
+  w.f = () {
+    return 42;
+  };
+  Expect.equals(42, w.f());
+}
diff --git a/tests/language/function/function_test.dart b/tests/language/function/function_test.dart
new file mode 100644
index 0000000..201b8f1
--- /dev/null
+++ b/tests/language/function/function_test.dart
@@ -0,0 +1,378 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Tests function statements and expressions.
+
+class Bug4089219 {
+  int x;
+  var f;
+
+  Bug4089219(int i) : this.x = i {
+    f = () => x;
+  }
+}
+
+class Bug4342163 {
+  final m;
+  Bug4342163(int a) : this.m = (() => a) {}
+}
+
+class StaticFunctionDef {
+  static const int one = 1;
+  static var fn1;
+  static var fn2;
+  static var fn3;
+
+  static init() {
+    fn1 = () {
+      return one;
+    };
+    fn2 = () {
+      return (() {
+        return one;
+      })();
+    };
+    fn3 = () {
+      final local = 1;
+      return (() {
+        return local;
+      })();
+    };
+  }
+}
+
+class A {
+  var ma;
+  A(a) {
+    ma = a;
+  }
+}
+
+class B1 extends A {
+  final mfn;
+  B1(int a)
+      : this.mfn = (() {
+          return a;
+        }),
+        super(a);
+}
+
+class B2 extends A {
+  final mfn;
+  B2(int a)
+      : this.mfn = (() {
+          return a;
+        }),
+        super(2);
+}
+
+class B3 extends A {
+  final mfn;
+  B3(int a)
+      : this.mfn = (() {
+          return a;
+        }),
+        super(() {
+          return a;
+        });
+}
+
+typedef void Fisk();
+
+class FunctionTest {
+  FunctionTest() {}
+
+  static void testMain() {
+    var test = new FunctionTest();
+    test.testForEach();
+    test.testVarOrder1();
+    test.testVarOrder2();
+    test.testLexicalClosureRef1();
+    test.testLexicalClosureRef2();
+    test.testLexicalClosureRef3();
+    test.testLexicalClosureRef4();
+    test.testLexicalClosureRef5();
+    test.testDefaultParametersOrder();
+    test.testParametersOrder();
+    test.testFunctionDefaults1();
+    test.testFunctionDefaults2();
+    test.testEscapingFunctions();
+    test.testThisBinding();
+    test.testFnBindingInStatics();
+    test.testFnBindingInInitLists();
+    test.testSubclassConstructorScopeAlias();
+  }
+
+  void testSubclassConstructorScopeAlias() {
+    var b1 = new B1(10);
+    Expect.equals(10, (b1.mfn)());
+    Expect.equals(10, b1.ma);
+
+    var b2 = new B2(11);
+    Expect.equals(11, (b2.mfn)());
+    Expect.equals(2, b2.ma);
+
+    var b3 = new B3(12);
+    Expect.equals(12, (b3.mfn)());
+    Expect.equals(12, (b3.ma)());
+  }
+
+  void testFnBindingInInitLists() {
+    Expect.equals(1, (new Bug4342163(1).m)());
+  }
+
+  void testFnBindingInStatics() {
+    StaticFunctionDef.init();
+    Expect.equals(1, ((StaticFunctionDef.fn1)()));
+    Expect.equals(1, ((StaticFunctionDef.fn2)()));
+    Expect.equals(1, ((StaticFunctionDef.fn3)()));
+  }
+
+  Fisk testReturnVoidFunction() {
+    void f() {}
+    Fisk x = f;
+    return f;
+  }
+
+  void testVarOrder1() {
+    var a = 0, b = a++, c = a++;
+
+    Expect.equals(a, 2);
+    Expect.equals(b, 0);
+    Expect.equals(c, 1);
+  }
+
+  void testVarOrder2() {
+    var a = 0;
+    f() {
+      return a++;
+    }
+
+    ;
+    var b = f(), c = f();
+
+    Expect.equals(a, 2);
+    Expect.equals(b, 0);
+    Expect.equals(c, 1);
+  }
+
+  void testLexicalClosureRef1() {
+    var a = 1;
+    var f, g;
+    {
+      var b = 2;
+      f = () {
+        return b - a;
+      };
+    }
+
+    {
+      var b = 3;
+      g = () {
+        return b - a;
+      };
+    }
+    Expect.equals(1, f());
+    Expect.equals(2, g());
+  }
+
+  void testLexicalClosureRef2() {
+    var a = 1;
+    var f, g;
+    {
+      var b = 2;
+      f = () {
+        return (() {
+          return b - a;
+        })();
+      };
+    }
+
+    {
+      var b = 3;
+      g = () {
+        return (() {
+          return b - a;
+        })();
+      };
+    }
+    Expect.equals(1, f());
+    Expect.equals(2, g());
+  }
+
+  void testLexicalClosureRef3() {
+    var a = [];
+    for (int i = 0; i < 10; i++) {
+      var x = i;
+      a.add(() {
+        return x;
+      });
+    }
+
+    var sum = 0;
+    for (int i = 0; i < a.length; i++) {
+      sum += (a[i])() as int;
+    }
+
+    Expect.equals(45, sum);
+  }
+
+  void testLexicalClosureRef5() {
+    {
+      var a;
+      Expect.equals(null, a);
+      a = 1;
+      Expect.equals(1, a);
+    }
+
+    {
+      var a;
+      Expect.equals(null, a);
+      a = 1;
+      Expect.equals(1, a);
+    }
+  }
+
+  // Make sure labels are preserved, and a second 'i' does influence the first.
+  void testLexicalClosureRef4() {
+    var a = [];
+    x:
+    for (int i = 0; i < 10; i++) {
+      a.add(() {
+        return i;
+      });
+      continue x;
+    }
+
+    var sum = 0;
+    for (int i = 0; i < a.length; i++) {
+      sum += (a[i])() as int;
+    }
+
+    Expect.equals(45, sum);
+  }
+
+  int tempField = -1;
+
+  void testForEach() {
+    List<int> vals = [1, 2, 3];
+    int total = 0;
+    vals.forEach((int v) {
+      total += v;
+    });
+    Expect.equals(6, total);
+  }
+
+  void testDefaultParametersOrder() {
+    f([a = 1, b = 3]) {
+      return a - b;
+    }
+
+    Expect.equals(-2, f());
+  }
+
+  void testParametersOrder() {
+    f(a, b) {
+      return a - b;
+    }
+
+    Expect.equals(-2, f(1, 3));
+  }
+
+  void testFunctionDefaults1() {
+    // TODO(jimhug): This return null shouldn't be necessary.
+    f() {
+      return null;
+    }
+
+    ;
+    (([a = 10]) {
+      Expect.equals(10, a);
+    })();
+    ((a, [b = 10]) {
+      Expect.equals(10, b);
+    })(1);
+    (([a = 10]) {
+      Expect.equals(null, a);
+    })(f());
+    // FAILS: (([a = 10]) { Expect.equals(null ,a); })( f() );
+  }
+
+  void testFunctionDefaults2() {
+    Expect.equals(10, helperFunctionDefaults2());
+    Expect.equals(1, helperFunctionDefaults2(1));
+  }
+
+  num helperFunctionDefaults2([a = 10]) {
+    return (() {
+      return a;
+    })();
+  }
+
+  void testEscapingFunctions() {
+    f() {
+      return 42;
+    }
+
+    ;
+    (() {
+      Expect.equals(42, f());
+    })();
+    var o = new Bug4089219(42);
+    Expect.equals(42, (o.f)());
+  }
+
+  void testThisBinding() {
+    Expect.equals(this, () {
+      return this;
+    }());
+  }
+}
+
+typedef void Foo<A, B>(A a, B b);
+
+class Bar<A, B> {
+  Foo<A, B> field;
+  Bar(A a, B b) : this.field = ((A a1, B b2) {}) {
+    field(a, b);
+  }
+}
+
+typedef UntypedFunction(arg);
+typedef UntypedFunction2(arg);
+
+class UseFunctionTypes {
+  void test() {
+    Function? f = null;
+    UntypedFunction? uf = null;
+    UntypedFunction2? uf2 = null;
+    Foo? foo = null;
+    Foo<int, String>? fooIntString = null;
+    Foo<Object, Object>? fooObjectObject = null;
+
+    f = uf;
+    f = uf2;
+    f = foo;
+    f = fooIntString;
+
+    uf = f as UntypedFunction?;
+    uf2 = f;
+    foo = f as Foo?;
+    fooIntString = f as Foo<int, String>?;
+
+    fooIntString = foo as Foo<int, String>?;
+
+    foo = fooObjectObject as Foo?;
+    fooObjectObject = foo as Foo<Object, Object>?;
+
+    uf = uf2;
+    uf2 = uf;
+  }
+}
+
+main() {
+  FunctionTest.testMain();
+}
diff --git a/tests/language/function/getter_test.dart b/tests/language/function/getter_test.dart
new file mode 100644
index 0000000..efc483e
--- /dev/null
+++ b/tests/language/function/getter_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  a() => 42;
+}
+
+main() {
+  Expect.equals(new A().a(), (new A().a)());
+}
diff --git a/tests/language/function/literals2_test.dart b/tests/language/function/literals2_test.dart
new file mode 100644
index 0000000..2b5de44
--- /dev/null
+++ b/tests/language/function/literals2_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test for new function type alias.
+
+import "package:expect/expect.dart";
+
+class FunctionLiteralsTest {
+  static void testMain() {
+    f(x) {
+      return x * 2;
+    }
+
+    f(42); // make sure it is parsed as a function call
+    Expect.equals(20, f(10));
+
+    int g(x) {
+      return x * 2;
+    }
+
+    g(42); // make sure it is parsed as a function call
+    Expect.equals(20, g(10));
+
+    h(x) {
+      return x * 2;
+    }
+
+    h(42); // make sure it is parsed as a function call
+    Expect.equals(20, h(10));
+
+    dynamic a = (x) {
+      return x + 2;
+    };
+    Expect.equals(7, a(5));
+
+    Expect.equals(
+        10,
+        apply((k) {
+          return k << 1;
+        }, 5));
+    Expect.equals(20, apply((k) => k << 1, 10));
+
+    a = new A(3);
+    Expect.equals(-1, a.f);
+    Expect.equals(-3, a.f2);
+
+    a = new A.n(5);
+    Expect.equals(-2, a.f);
+    Expect.equals(2, a.f2);
+
+    Expect.equals(true, isOdd(5));
+    Expect.equals(false, isOdd(8));
+
+    var b = new B(10);
+    Expect.equals(10, b.n);
+    Expect.equals(100, (b.f)(10));
+
+    b = new B.withZ(10);
+    Expect.equals(10, b.n);
+    Expect.equals(101, (b.f)(10));
+
+    var c = new C(5);
+    Expect.equals("2*x is 10", c.s);
+
+    int x = 0;
+    int y = 1;
+    // make sure this isn't parsed as a generic type
+    Expect.isTrue(x < y, "foo");
+  }
+}
+
+int apply(f, n) {
+  return f(n) as int;
+}
+
+bool isOdd(b) => b % 2 == 1;
+
+class A {
+  int f = -1;
+  int f2 = -1;
+  A(p) : f = apply((j) => 2 - j, p) {
+    /* constr. body */
+    f2 = -p;
+  }
+  A.n(p) : f = 1 + apply((j) => 2 - j, p) {
+    /* constr. body */
+    f2 = -f;
+  }
+}
+
+class B {
+  var f;
+  int n = -1;
+  B(z) : f = ((x) => x * x) {
+    n = z;
+  }
+  B.withZ(z)
+      : f = ((x) {
+          return x * x + 1;
+        }) {
+    n = z;
+  }
+}
+
+class C {
+  String s;
+  C(x) : s = "2*x is ${() { return 2*x; }()}";
+}
+
+main() {
+  FunctionLiteralsTest.testMain();
+}
diff --git a/tests/language/function/literals_test.dart b/tests/language/function/literals_test.dart
new file mode 100644
index 0000000..e75ce3a
--- /dev/null
+++ b/tests/language/function/literals_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+/**
+ * Test various forms of function literals.
+ */
+typedef int IntFunc(int);
+
+class FunctionLiteralsTest {
+  static void checkIntFunction<T>(expected, int f(T x), arg) {
+    Expect.equals(expected, f(arg));
+  }
+
+  static void checkIntFuncFunction<T>(expected, IntFunc f(T x), arg) {
+    Expect.equals(expected, f(arg)(arg));
+  }
+
+  int func1(int x) => x;
+
+  int func2(x) => x;
+
+  int func3(int x) {
+    return x;
+  }
+
+  int func4(x) {
+    return x;
+  }
+
+  FunctionLiteralsTest() {}
+
+  static void testMain() {
+    var test = new FunctionLiteralsTest();
+    test.testArrow();
+    test.testArrowArrow();
+    test.testArrowBlock();
+    test.testBlock();
+    test.testBlockArrow();
+    test.testBlockBlock();
+    test.testFunctionRef();
+  }
+
+  void testArrow() {
+    checkIntFunction(42, (x) => x as int, 42);
+    checkIntFunction(42, (dynamic x) => x, 42);
+  }
+
+  void testArrowArrow() {
+    checkIntFuncFunction(84, (x) => (y) => (x as int) + (y as int), 42);
+    checkIntFuncFunction(84, (dynamic x) => (y) => x + y, 42);
+  }
+
+  void testArrowBlock() {
+    checkIntFuncFunction(
+        84,
+        (x) => (y) {
+              return (x as int) + (y as int);
+            },
+        42);
+    checkIntFuncFunction(
+        84,
+        (int x) => (y) {
+              return (x + y) as int;
+            },
+        42);
+  }
+
+  void testBlock() {
+    checkIntFunction(42, (x) {
+      return x as int;
+    }, 42);
+    checkIntFunction(42, (int x) {
+      return x;
+    }, 42);
+  }
+
+  void testBlockArrow() {
+    checkIntFuncFunction(84, (x) {
+      return (y) => (x as int) + (y as int);
+    }, 42);
+    checkIntFuncFunction(84, (int x) {
+      return (y) => (x + y) as int;
+    }, 42);
+  }
+
+  void testBlockBlock() {
+    checkIntFuncFunction(84, (x) {
+      return (y) {
+        return (x as int) + (y as int);
+      };
+    }, 42);
+    checkIntFuncFunction(84, (int x) {
+      return (y) {
+        return (x + y) as int;
+      };
+    }, 42);
+  }
+
+  void testFunctionRef() {
+    checkIntFunction(42, func1, 42);
+    checkIntFunction(42, func2, 42);
+    checkIntFunction(42, func3, 42);
+    checkIntFunction(42, func4, 42);
+  }
+}
+
+main() {
+  FunctionLiteralsTest.testMain();
+}
diff --git a/tests/language/function/local2_test.dart b/tests/language/function/local2_test.dart
new file mode 100644
index 0000000..44d2ef9
--- /dev/null
+++ b/tests/language/function/local2_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program testing closures.
+
+import "package:expect/expect.dart";
+
+typedef T F<T>(T t);
+
+class Parameterized<T> {
+  Parameterized() {}
+  T mul3(F<T> f, T t) {
+    return (3 as dynamic) * f(t);
+  }
+
+  T test(T t) {
+    return mul3((T t) {
+      return (3 as dynamic) * t;
+    }, t);
+  }
+}
+
+class LocalFunction2Test {
+  static int f(int n) {
+    int a = 0;
+    var g = (int n) {
+      a += n;
+      return a;
+    };
+    var h = (int n) {
+      a += 10 * n;
+      return a;
+    };
+    return g(n) + h(n);
+  }
+
+  static testMain() {
+    Expect.equals(3 + 33, f(3));
+    Expect.equals(9.0, new Parameterized<double>().test(1.0));
+  }
+}
+
+main() {
+  LocalFunction2Test.testMain();
+}
diff --git a/tests/language/function/local3_test.dart b/tests/language/function/local3_test.dart
new file mode 100644
index 0000000..46c3284
--- /dev/null
+++ b/tests/language/function/local3_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program testing closures.
+
+import "package:expect/expect.dart";
+
+class LocalFunction3Test {
+  static testExceptions() {
+    dynamic f = (int n) {
+      return n + 1;
+    };
+    Expect.equals(true, f is Object);
+    bool exception_caught = false;
+    try {
+      f.xyz(0);
+    } on NoSuchMethodError {
+      exception_caught = true;
+    }
+    Expect.equals(true, exception_caught);
+    exception_caught = false;
+    String f_string = "";
+    try {
+      f_string = f.toString();
+    } on NoSuchMethodError  {
+      exception_caught = true;
+    }
+    Expect.equals(false, exception_caught);
+    Expect.equals(true, f_string.startsWith("Closure"));
+  }
+
+  static testMain() {
+    testExceptions();
+  }
+}
+
+main() {
+  LocalFunction3Test.testMain();
+}
diff --git a/tests/language/function/local_function_test.dart b/tests/language/function/local_function_test.dart
new file mode 100644
index 0000000..4ed1bff
--- /dev/null
+++ b/tests/language/function/local_function_test.dart
@@ -0,0 +1,227 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program testing closures.
+
+import "package:expect/expect.dart";
+
+class LocalFunctionTest {
+  LocalFunctionTest()
+      : field1 = 100,
+        field2_ = 200 {}
+  static int f(int n) {
+    int a = 0;
+    g(int m) {
+      a = 3 * n + m + 1; // Capture parameter n and local a.
+      return a;
+    }
+
+    var b = g(n);
+    return a + b;
+  }
+
+  static int h(int n) {
+    k(int n) {
+      var a = new List<dynamic>.filled(n, null);
+      var b = new List<dynamic>.filled(n, null);
+      int i;
+      for (i = 0; i < n; i++) {
+        var j = i;
+        a[i] = () => i; // Captured i is always n.
+        b[i] = () => j; // Captured j varies from 0 to n-1.
+      }
+      var a_sum = 0;
+      var b_sum = 0;
+      for (int i = 0; i < n; i++) {
+        a_sum += a[i]() as int;
+        b_sum += b[i]() as int;
+      }
+      return a_sum + b_sum;
+    }
+
+    return k(n);
+  }
+
+  static int h2(int n) {
+    k(int n) {
+      var a = new List<dynamic>.filled(n, null);
+      var b = new List<dynamic>.filled(n, null);
+      for (int i = 0; i < n; i++) {
+        var j = i;
+        a[i] = () => i; // Captured i varies from 0 to n-1.
+        b[i] = () => j; // Captured j varies from 0 to n-1.
+      }
+      var a_sum = 0;
+      var b_sum = 0;
+      for (int i = 0; i < n; i++) {
+        a_sum += a[i]() as int;
+        b_sum += b[i]() as int;
+      }
+      return a_sum + b_sum;
+    }
+
+    return k(n);
+  }
+
+  int field1;
+  int field2_;
+  int get field2 {
+    return field2_;
+  }
+
+  void set field2(int value) {
+    field2_ = value;
+  }
+
+  int method(int n) {
+    incField1() {
+      field1++;
+    }
+
+    incField2() {
+      field2++;
+    }
+
+    for (int i = 0; i < n; i++) {
+      incField1();
+      incField2();
+    }
+    return field1 + field2;
+  }
+
+  int execute(int times, apply(int x)) {
+    for (int i = 0; i < times; i++) {
+      apply(i);
+    }
+    return field1;
+  }
+
+  int testExecute(int n) {
+    execute(n, (int x) {
+      field1 += x;
+    });
+    return field1;
+  }
+
+  static int foo(int n) {
+    return -100; // Wrong foo.
+  }
+
+  static testSelfReference1(int n) {
+    int foo(int n) {
+      if (n == 0) {
+        return 0;
+      } else {
+        return 1 + foo(n - 1); // Local foo, not static foo.
+      }
+    }
+
+    ;
+    return foo(n); // Local foo, not static foo.
+  }
+
+  static void hep(Function f) {
+    f();
+  }
+
+  static testNesting(int n) {
+    var a = new List<dynamic>.filled(n * n, null);
+    f0() {
+      for (int i = 0; i < n; i++) {
+        int vi = i;
+        f1() {
+          for (int j = 0; j < n; j++) {
+            int vj = j;
+            a[i * n + j] = () => vi * n + vj;
+          }
+        }
+
+        f1();
+      }
+    }
+
+    f0();
+    int result = 0;
+    for (int k = 0; k < n * n; k++) {
+      Expect.equals(k, a[k]());
+      result += a[k]() as int;
+    }
+    return result;
+  }
+
+  static var field5;
+  static var set_field5_func;
+  static testClosureCallStatement(int x) {
+    LocalFunctionTest.set_field5_func = (int n) {
+      field5 = n * n;
+    };
+    (LocalFunctionTest.set_field5_func)(x);
+    Expect.equals(x * x, LocalFunctionTest.field5);
+    return true;
+  }
+
+  static testExceptions() {
+    dynamic f = (int n) => n + 1;
+    Expect.equals(2, f(1));
+    Expect.equals(true, f is Function);
+    Expect.equals(true, f is Object);
+    Expect.equals(true, f.toString().startsWith("Closure"));
+    bool exception_caught = false;
+    try {
+      f(1, 2);
+    } on NoSuchMethodError catch (e) {
+      exception_caught = true;
+    }
+    Expect.equals(true, exception_caught);
+    exception_caught = false;
+    try {
+      f();
+    } on NoSuchMethodError catch (e) {
+      exception_caught = true;
+    }
+    Expect.equals(true, exception_caught);
+    exception_caught = false;
+    try {
+      f.xyz(0);
+    } on NoSuchMethodError catch (e) {
+      exception_caught = true;
+    }
+    Expect.equals(true, exception_caught);
+
+    // Overwrite closure value.
+    f = 3;
+    exception_caught = false;
+    try {
+      f(1);
+    } on NoSuchMethodError catch (e) {
+      exception_caught = true;
+    }
+    Expect.equals(true, exception_caught);
+
+    // Do not expect any exceptions to be thrown.
+    var g = ([int n = 1]) => n + 1;
+    Expect.equals(2, g());
+    Expect.equals(3, g(2));
+  }
+
+  static int doThis(int n, int f(int n)) {
+    return f(n);
+  }
+
+  static testMain() {
+    Expect.equals(2 * (3 * 2 + 2 + 1), f(2));
+    Expect.equals(10 * 10 + 10 * 9 / 2, h(10));
+    Expect.equals(90, h2(10));
+    Expect.equals(320, new LocalFunctionTest().method(10));
+    Expect.equals(145, new LocalFunctionTest().testExecute(10));
+    Expect.equals(5, testSelfReference1(5));
+    Expect.equals(24 * 25 / 2, testNesting(5));
+    Expect.equals(true, testClosureCallStatement(7));
+    Expect.equals(99, doThis(10, (n) => n * n - 1));
+    testExceptions();
+  }
+}
+
+main() {
+  LocalFunctionTest.testMain();
+}
diff --git a/tests/language/function/local_non_equal_test.dart b/tests/language/function/local_non_equal_test.dart
new file mode 100644
index 0000000..5fbaf57
--- /dev/null
+++ b/tests/language/function/local_non_equal_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+foo() => () => 42;
+bar() {
+  var c = () => 54;
+  return c;
+}
+
+baz() {
+  c() => 68;
+  return c;
+}
+
+main() {
+  var first = foo();
+  var second = foo();
+  Expect.isFalse(identical(first, second));
+  Expect.notEquals(first, second);
+
+  first = bar();
+  second = bar();
+  Expect.isFalse(identical(first, second));
+  Expect.notEquals(first, second);
+
+  first = baz();
+  second = baz();
+  Expect.isFalse(identical(first, second));
+  Expect.notEquals(first, second);
+}
diff --git a/tests/language/function/malformed_result_type_runtime_test.dart b/tests/language/function/malformed_result_type_runtime_test.dart
new file mode 100644
index 0000000..02b26b4
--- /dev/null
+++ b/tests/language/function/malformed_result_type_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for a function with a malformed result type.
+
+import "package:expect/expect.dart";
+
+class C<T, U> {}
+
+main() {
+
+}
diff --git a/tests/language/function/malformed_result_type_test.dart b/tests/language/function/malformed_result_type_test.dart
new file mode 100644
index 0000000..182258b
--- /dev/null
+++ b/tests/language/function/malformed_result_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for a function with a malformed result type.
+
+import "package:expect/expect.dart";
+
+class C<T, U> {}
+
+main() {
+  C<int> f() => throw "uncalled";
+//^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS
+// [cfe] Expected 2 type arguments.
+}
diff --git a/tests/language/function/propagation_test.dart b/tests/language/function/propagation_test.dart
new file mode 100644
index 0000000..9c6f7e6
--- /dev/null
+++ b/tests/language/function/propagation_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  int call(String str) => 499;
+}
+
+typedef int F(String str);
+
+main() {
+  var a = new A();
+  Expect.type<A>(a);
+  Expect.notType<F>(a);
+
+  Function a3 = new A();
+  Expect.notType<A>(a3);
+
+  F a4 = new A();
+  Expect.notType<A>(a4);
+}
diff --git a/tests/language/function/syntax_test.dart b/tests/language/function/syntax_test.dart
new file mode 100644
index 0000000..3baf2df
--- /dev/null
+++ b/tests/language/function/syntax_test.dart
@@ -0,0 +1,733 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Tests function statement and expression syntax.
+
+class FunctionSyntaxTest {
+  static void testMain
+/* //# 00: syntax error
+      ()
+*/ //# 00: continued
+  {
+    testNestedFunctions();
+    testFunctionExpressions();
+    testPrecedence();
+    testInitializers();
+    testFunctionParameter();
+    testFunctionIdentifierExpression();
+    testFunctionIdentifierStatement();
+  }
+
+  static void testNestedFunctions
+/* //# 01: syntax error
+      ()
+*/ //# 01: continued
+  {
+    // No types - braces.
+    nb0
+/* //# 02: syntax error
+        ()
+*/ //# 02: continued
+    {
+      return 42;
+    }
+
+    nb1
+/* //# 03: syntax error
+        (a)
+*/ //# 03: continued
+    {
+      return a;
+    }
+
+    nb2
+/* //# 04: syntax error
+        (a, b)
+*/ //# 04: continued
+    {
+      return a + b;
+    }
+
+    Expect.equals(42, nb0());
+    Expect.equals(87, nb1(87));
+    Expect.equals(1 + 2, nb2(1, 2));
+
+    // No types - arrows.
+    na0
+/* //# 05: syntax error
+        ()
+*/ //# 05: continued
+            =>
+            42;
+    na1
+/* //# 06: syntax error
+        (a)
+*/ //# 06: continued
+            =>
+            a;
+    na2
+/* //# 07: syntax error
+        (a, b)
+*/ //# 07: continued
+            =>
+            a + b;
+    Expect.equals(42, na0());
+    Expect.equals(87, na1(87));
+    Expect.equals(1 + 2, na2(1, 2));
+
+    // Return type - braces.
+    int rb0
+/* //# 08: syntax error
+        ()
+*/ //# 08: continued
+    {
+      return 42;
+    }
+
+    int rb1
+/* //# 09: syntax error
+        (a)
+*/ //# 09: continued
+    {
+      return a;
+    }
+
+    int rb2
+/* //# 10: syntax error
+        (a, b)
+*/ //# 10: continued
+    {
+      return a + b;
+    }
+
+    Expect.equals(42, rb0());
+    Expect.equals(87, rb1(87));
+    Expect.equals(1 + 2, rb2(1, 2));
+
+    // Return type - arrows.
+    int ra0
+/* //# 11: syntax error
+        ()
+*/ //# 11: continued
+            =>
+            42;
+    int ra1
+/* //# 12: syntax error
+        (a)
+*/ //# 12: continued
+            =>
+            a;
+    int ra2
+/* //# 13: syntax error
+        (a, b)
+*/ //# 13: continued
+            =>
+            a + b;
+    Expect.equals(42, ra0());
+    Expect.equals(87, ra1(87));
+    Expect.equals(1 + 2, ra2(1, 2));
+
+    // Fully typed - braces.
+    int fb1
+/* //# 14: syntax error
+        (int a)
+*/ //# 14: continued
+    {
+      return a;
+    }
+
+    int fb2
+/* //# 15: syntax error
+        (int a, int b)
+*/ //# 15: continued
+    {
+      return a + b;
+    }
+
+    Expect.equals(42, rb0());
+    Expect.equals(87, rb1(87));
+    Expect.equals(1 + 2, rb2(1, 2));
+
+    // Fully typed - arrows.
+    int fa1
+/* //# 16: syntax error
+        (int a)
+*/ //# 16: continued
+            =>
+            a;
+    int fa2
+/* //# 17: syntax error
+        (int a, int b)
+*/ //# 17: continued
+            =>
+            a + b;
+    Expect.equals(42, ra0());
+    Expect.equals(87, ra1(87));
+    Expect.equals(1 + 2, ra2(1, 2));
+
+    // Generic types - braces.
+    List<int> gb0
+/* //# 18: syntax error
+        ()
+*/ //# 18: continued
+    {
+      return [42];
+    }
+
+    List<int> gb1
+/* //# 19: syntax error
+        (List<int> a)
+*/ //# 19: continued
+    {
+      return a;
+    }
+
+    Expect.equals(42, gb0()[0]);
+    Expect.equals(87, gb1([87])[0]);
+
+    // Generic types - arrows.
+    List<int> ga0
+/* //# 20: syntax error
+        ()
+*/ //# 20: continued
+            =>
+            [42];
+    List<int> ga1
+/* //# 21: syntax error
+        (List<int> a)
+*/ //# 21: continued
+            =>
+            a;
+    Expect.equals(42, ga0()[0]);
+    Expect.equals(87, ga1([87])[0]);
+  }
+
+  static void testFunctionExpressions
+/* //# 22: syntax error
+      ()
+*/ //# 22: continued
+  {
+    eval0
+/* //# 23: syntax error
+        (fn)
+*/ //# 23: continued
+            =>
+            fn();
+    eval1
+/* //# 24: syntax error
+        (fn, a)
+*/ //# 24: continued
+            =>
+            fn(a);
+    eval2
+/* //# 25: syntax error
+        (fn, a, b)
+*/ //# 25: continued
+            =>
+            fn(a, b);
+
+    // No types - braces.
+    Expect.equals(42, eval0(
+/* //# 26: syntax error
+        ()
+*/ //# 26: continued
+        {
+      return 42;
+    }));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 27: syntax error
+            (a)
+*/ //# 27: continued
+            {
+          return a;
+        }, 87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 28: syntax error
+            (a, b)
+*/ //# 28: continued
+            {
+          return a + b;
+        }, 1, 2));
+    Expect.equals(42, eval0(
+/* //# 29: syntax error
+        ()
+*/ //# 29: continued
+        {
+      return 42;
+    }));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 30: syntax error
+            (a)
+*/ //# 30: continued
+            {
+          return a;
+        }, 87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 31: syntax error
+            (a, b)
+*/ //# 31: continued
+            {
+          return a + b;
+        }, 1, 2));
+
+    // No types - arrows.
+    Expect.equals(
+        42,
+        eval0(
+/* //# 32: syntax error
+            ()
+*/ //# 32: continued
+                =>
+                42));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 33: syntax error
+            (a)
+*/ //# 33: continued
+                =>
+                a,
+            87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 34: syntax error
+            (a, b)
+*/ //# 34: continued
+                =>
+                a + b,
+            1,
+            2));
+    Expect.equals(
+        42,
+        eval0(
+/* //# 35: syntax error
+            ()
+*/ //# 35: continued
+                =>
+                42));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 36: syntax error
+            (a)
+*/ //# 36: continued
+                =>
+                a,
+            87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 37: syntax error
+            (a, b)
+*/ //# 37: continued
+                =>
+                a + b,
+            1,
+            2));
+
+    // Argument types - braces.
+    Expect.equals(42, eval0(
+/* //# 44: syntax error
+        ()
+*/ //# 44: continued
+        {
+      return 42;
+    }));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 45: syntax error
+            (int a)
+*/ //# 45: continued
+            {
+          return a;
+        }, 87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 46: syntax error
+            (int a, int b)
+*/ //# 46: continued
+            {
+          return a + b;
+        }, 1, 2));
+    Expect.equals(42, eval0(
+/* //# 47: syntax error
+        ()
+*/ //# 47: continued
+        {
+      return 42;
+    }));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 48: syntax error
+            (int a)
+*/ //# 48: continued
+            {
+          return a;
+        }, 87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 49: syntax error
+            (int a, int b)
+*/ //# 49: continued
+            {
+          return a + b;
+        }, 1, 2));
+
+    // Argument types - arrows.
+    Expect.equals(
+        42,
+        eval0(
+/* //# 50: syntax error
+            ()
+*/ //# 50: continued
+                =>
+                42));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 51: syntax error
+            (int a)
+*/ //# 51: continued
+                =>
+                a,
+            87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 52: syntax error
+            (int a, int b)
+*/ //# 52: continued
+                =>
+                a + b,
+            1,
+            2));
+    Expect.equals(
+        42,
+        eval0(
+/* //# 53: syntax error
+            ()
+*/ //# 53: continued
+                =>
+                42));
+    Expect.equals(
+        87,
+        eval1(
+/* //# 54: syntax error
+            (int a)
+*/ //# 54: continued
+                =>
+                a,
+            87));
+    Expect.equals(
+        1 + 2,
+        eval2(
+/* //# 55: syntax error
+            (int a, int b)
+*/ //# 55: continued
+                =>
+                a + b,
+            1,
+            2));
+  }
+
+  static void testPrecedence
+/* //# 64: syntax error
+      ()
+*/ //# 64: continued
+  {
+    expectEvaluatesTo
+/* //# 65: syntax error
+        (value, fn)
+*/ //# 65: continued
+    {
+      Expect.equals(value, fn());
+    }
+
+    // Assignment.
+    var x;
+    expectEvaluatesTo(42, () => x = 42);
+    Expect.equals(42, x);
+    x = 1;
+    expectEvaluatesTo(100, () => x += 99);
+    Expect.equals(100, x);
+    x = 1;
+    expectEvaluatesTo(87, () => x *= 87);
+    Expect.equals(87, x);
+
+    // Conditional.
+    expectEvaluatesTo(42, () => true ? 42 : 87);
+    expectEvaluatesTo(87, () => false ? 42 : 87);
+
+    // Logical or.
+    expectEvaluatesTo(true, () => true || true);
+    expectEvaluatesTo(true, () => true || false);
+    expectEvaluatesTo(true, () => false || true);
+    expectEvaluatesTo(false, () => false || false);
+
+    // Logical and.
+    expectEvaluatesTo(true, () => true && true);
+    expectEvaluatesTo(false, () => true && false);
+    expectEvaluatesTo(false, () => false && true);
+    expectEvaluatesTo(false, () => false && false);
+
+    // Bitwise operations.
+    expectEvaluatesTo(3, () => 1 | 2);
+    expectEvaluatesTo(2, () => 3 ^ 1);
+    expectEvaluatesTo(1, () => 3 & 1);
+
+    // Equality.
+    expectEvaluatesTo(true, () => 1 == 1);
+    expectEvaluatesTo(false, () => 1 != 1);
+    expectEvaluatesTo(true, () => identical(1, 1));
+    expectEvaluatesTo(false, () => !identical(1, 1));
+
+    // Relational.
+    expectEvaluatesTo(true, () => 1 <= 1);
+    expectEvaluatesTo(false, () => 1 < 1);
+    expectEvaluatesTo(false, () => 1 > 1);
+    expectEvaluatesTo(true, () => 1 >= 1);
+
+    // Is.
+    expectEvaluatesTo(true, () => 1 is int);
+    expectEvaluatesTo(true, () => 1.0 is double);
+
+    // Shift.
+    expectEvaluatesTo(2, () => 1 << 1);
+    expectEvaluatesTo(1, () => 2 >> 1);
+
+    // Additive.
+    expectEvaluatesTo(2, () => 1 + 1);
+    expectEvaluatesTo(1, () => 2 - 1);
+
+    // Multiplicative.
+    expectEvaluatesTo(2, () => 1 * 2);
+    expectEvaluatesTo(2.0, () => 4 / 2);
+    expectEvaluatesTo(2, () => 4 ~/ 2);
+    expectEvaluatesTo(0, () => 4 % 2);
+
+    // Negate.
+    expectEvaluatesTo(false, () => !true);
+
+    // Postfix / prefix.
+    var y = 0;
+    expectEvaluatesTo(0, () => y++);
+    expectEvaluatesTo(2, () => ++y);
+    expectEvaluatesTo(1, () => --y);
+    expectEvaluatesTo(1, () => y--);
+    Expect.equals(0, y);
+
+    // Selector.
+    fn
+/* //# 66: syntax error
+        ()
+*/ //# 66: continued
+            =>
+            42;
+    var list = [87];
+    expectEvaluatesTo(42, () => fn());
+    expectEvaluatesTo(1, () => list.length);
+    expectEvaluatesTo(87, () => list[0]);
+    expectEvaluatesTo(87, () => list.removeLast());
+  }
+
+  static void testInitializers
+/* //# 67: syntax error
+      ()
+*/ //# 67: continued
+  {
+    Expect.equals(42, (new C.cb0().fn)());
+    Expect.equals(43, (new C.ca0().fn)());
+    Expect.equals(44, (new C.cb1().fn)());
+    Expect.equals(45, (new C.ca1().fn)());
+    Expect.equals(46, (new C.cb2().fn)());
+    Expect.equals(47, (new C.ca2().fn)());
+    Expect.equals(48, (new C.cb3().fn)());
+    Expect.equals(49, (new C.ca3().fn)());
+
+    Expect.equals(52, (new C.nb0().fn)());
+    Expect.equals(53, (new C.na0().fn)());
+    Expect.equals(54, (new C.nb1().fn)());
+    Expect.equals(55, (new C.na1().fn)());
+    Expect.equals(56, (new C.nb2().fn)());
+    Expect.equals(57, (new C.na2().fn)());
+    Expect.equals(58, (new C.nb3().fn)());
+    Expect.equals(59, (new C.na3().fn)());
+
+    Expect.equals(62, (new C.rb0().fn)());
+    Expect.equals(63, (new C.ra0().fn)());
+    Expect.equals(64, (new C.rb1().fn)());
+    Expect.equals(65, (new C.ra1().fn)());
+    Expect.equals(66, (new C.rb2().fn)());
+    Expect.equals(67, (new C.ra2().fn)());
+    Expect.equals(68, (new C.rb3().fn)());
+    Expect.equals(69, (new C.ra3().fn)());
+  }
+
+  static void testFunctionParameter
+/* //# 68: syntax error
+      ()
+*/ //# 68: continued
+  {
+    f0(fn()) => fn();
+    Expect.equals(42, f0(() => 42));
+
+    f1(int fn()) => fn();
+    Expect.equals(87, f1(() => 87));
+
+    f2(fn(a)) => fn(42);
+    Expect.equals(43, f2((a) => a + 1));
+
+    f3(fn(int a)) => fn(42);
+    Expect.equals(44, f3((int a) => a + 2));
+  }
+
+  static void testFunctionIdentifierExpression
+/* //# 69: syntax error
+      ()
+*/ //# 69: continued
+  {
+    Expect.equals(
+        87,
+        (
+/* //# 70: syntax error
+            ()
+*/ //# 70: continued
+                =>
+                87)());
+  }
+
+  static void testFunctionIdentifierStatement
+/* //# 71: syntax error
+      ()
+*/ //# 71: continued
+  {
+    function
+/* //# 72: syntax error
+        ()
+*/ //# 72: continued
+            =>
+            42;
+    Expect.equals(42, function());
+    Expect.equals(true, function is Function);
+  }
+}
+
+class C {
+  C.cb0()
+      : fn = (() {
+          return 42;
+        }) {}
+  C.ca0() : fn = (() => 43) {}
+
+  C.cb1()
+      : fn = wrap(() {
+          return 44;
+        }) {}
+  C.ca1() : fn = wrap(() => 45) {}
+
+  C.cb2()
+      : fn = [
+          () {
+            return 46;
+          }
+        ][0] {}
+  C.ca2() : fn = [() => 47][0] {}
+
+  C.cb3()
+      : fn = {
+          'x': () {
+            return 48;
+          }
+        }['x'] {}
+  C.ca3() : fn = {'x': () => 49}['x'] {}
+
+  C.nb0()
+      : fn = (() {
+          return 52;
+        }) {}
+  C.na0() : fn = (() => 53) {}
+
+  C.nb1()
+      : fn = wrap(() {
+          return 54;
+        }) {}
+  C.na1() : fn = wrap(() => 55) {}
+
+  C.nb2()
+      : fn = [
+          () {
+            return 56;
+          }
+        ][0] {}
+  C.na2() : fn = [() => 57][0] {}
+
+  C.nb3()
+      : fn = {
+          'x': () {
+            return 58;
+          }
+        }['x'] {}
+  C.na3() : fn = {'x': () => 59}['x'] {}
+
+  C.rb0()
+      : fn = (() {
+          return 62;
+        }) {}
+  C.ra0() : fn = (() => 63) {}
+
+  C.rb1()
+      : fn = wrap(() {
+          return 64;
+        }) {}
+  C.ra1() : fn = wrap(() => 65) {}
+
+  C.rb2()
+      : fn = [
+          () {
+            return 66;
+          }
+        ][0] {}
+  C.ra2() : fn = [() => 67][0] {}
+
+  C.rb3()
+      : fn = {
+          'x': () {
+            return 68;
+          }
+        }['x'] {}
+  C.ra3() : fn = {'x': () => 69}['x'] {}
+
+  static wrap
+/* //# 73: syntax error
+      (fn)
+*/ //# 73: continued
+  {
+    return fn;
+  }
+
+  final fn;
+}
+
+main
+/* //# 74: syntax error
+    ()
+*/ //# 74: continued
+{
+  FunctionSyntaxTest.testMain();
+}
diff --git a/tests/language/function/type2_test.dart b/tests/language/function/type2_test.dart
new file mode 100644
index 0000000..42ca6ff
--- /dev/null
+++ b/tests/language/function/type2_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  A(f) {
+    f(42);
+  }
+}
+
+class B<T> extends A<T> {
+  B() : super((T param) => 42);
+}
+
+main() {
+  var t = new B<int>();
+  Expect.throwsTypeError(() => new B<String>());
+}
diff --git a/tests/language/function/type3_test.dart b/tests/language/function/type3_test.dart
new file mode 100644
index 0000000..b21b3e0
--- /dev/null
+++ b/tests/language/function/type3_test.dart
@@ -0,0 +1,28 @@
+// 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:expect/expect.dart";
+
+class A<T> {
+  @pragma('dart2js:noInline')
+  A();
+
+  @pragma('dart2js:noInline')
+  foo() => new B<T>();
+}
+
+class B<T> {
+  T bar() => throw "uncalled";
+}
+
+typedef F();
+typedef F2(x);
+
+// Dart2js realized that the generic type for A was not needed, but then used
+// it nevertheless when it constructed the closure.
+main() {
+  var f = new A<int>().foo().bar;
+  Expect.isTrue(f is F);
+  Expect.isFalse(f is F2);
+}
diff --git a/tests/language/function/type_alias10_test.dart b/tests/language/function/type_alias10_test.dart
new file mode 100644
index 0000000..664ad7a
--- /dev/null
+++ b/tests/language/function/type_alias10_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/30912.
+import 'package:expect/expect.dart';
+
+class Foo {}
+
+class Bar {}
+
+typedef Type Func<S extends Foo, T>(T s);
+
+class Baz<S extends Foo, T extends Bar> {
+  Func<S, Bar>? func;
+}
+
+void main() {
+  dynamic baz = new Baz();
+  Expect.isNull(baz.func);
+  baz.func = (Bar b) => b.runtimeType;
+  Expect.equals(baz.func(new Bar()), Bar);
+}
diff --git a/tests/language/function/type_alias2_test.dart b/tests/language/function/type_alias2_test.dart
new file mode 100644
index 0000000..59c3166
--- /dev/null
+++ b/tests/language/function/type_alias2_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--enable_type_checks
+
+// Dart test for function type alias with optional parameters.
+import "package:expect/expect.dart";
+
+typedef int f1<T>([int? a, int? b, T? c]);
+typedef int f2<T>([int? a, int? b, T? d]);
+typedef int f3<T>({int? a, int? b, T? c});
+typedef int f4<T>({int? a, int? b, T? d});
+
+class A<T> {
+  int baz([int? a, int? b, T? c]) => -1;
+  int bar({int? a, int? b, T? c}) => -1;
+}
+
+int baz([int? a, int? b, int? c]) => -1;
+
+int bar({int? a, int? b, int? c}) => -1;
+
+main() {
+  Expect.isFalse(baz is f1);
+  Expect.isFalse(baz is f3);
+  Expect.isFalse(bar is f1);
+  Expect.isFalse(bar is f3);
+  Expect.isFalse(baz is f1);
+  Expect.isTrue(baz is f1<int>);
+  Expect.isTrue(bar is f3<int>);
+  Expect.isFalse(baz is f1<double>);
+  Expect.isFalse(bar is f3<double>);
+  Expect.isFalse(baz is f2);
+  Expect.isFalse(bar is f4);
+  Expect.isTrue(baz is f2<int>);
+  Expect.isFalse(bar is f2<int>);
+
+  A<int> a = new A<int>();
+  Expect.isTrue(a.baz is f1);
+  Expect.isFalse(a.baz is f3);
+  Expect.isFalse(a.bar is f1);
+  Expect.isTrue(a.bar is f3);
+  Expect.isTrue(a.baz is f1);
+  Expect.isTrue(a.baz is f1<Object>);
+  Expect.isTrue(a.bar is f3<Object>);
+  Expect.isTrue(a.baz is f1<int>);
+  Expect.isTrue(a.bar is f3<int>);
+  Expect.isTrue(a.baz is f1<double>);
+  Expect.isTrue(a.bar is f3<double>);
+  Expect.isTrue(a.baz is f2);
+  Expect.isFalse(a.bar is f4);
+  Expect.isTrue(a.baz is f2<Object>);
+  Expect.isFalse(a.bar is f2<Object>);
+}
diff --git a/tests/language/function/type_alias3_test.dart b/tests/language/function/type_alias3_test.dart
new file mode 100644
index 0000000..69ebd6e1
--- /dev/null
+++ b/tests/language/function/type_alias3_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for function type alias with an imported result type that happens
+// to have the same name as a type parameter.
+import "package:expect/expect.dart";
+import "../library11.dart" as lib11;
+
+typedef lib11.Library111<Library111> F<Library111>(
+    lib11.Library111<Library111> a, Library111 b);
+
+class A<T> {
+  T foo(T a, bool b) => throw "uncalled";
+}
+
+main() {
+  var a = new A<lib11.Library111<bool>>();
+  var b = new A<lib11.Library111<int>>();
+  Expect.isTrue(a.foo is! F);
+  Expect.isTrue(a.foo is F<bool>);
+  Expect.isTrue(a.foo is! F<int>);
+  Expect.isTrue(b.foo is! F);
+  Expect.isTrue(b.foo is! F<bool>);
+  Expect.isTrue(a.foo is! F<int>);
+}
diff --git a/tests/language/function/type_alias4_test.dart b/tests/language/function/type_alias4_test.dart
new file mode 100644
index 0000000..3bdba67
--- /dev/null
+++ b/tests/language/function/type_alias4_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for function type alias with a type parameter as result type.
+import "package:expect/expect.dart";
+
+typedef bool F<bool>(bool a); // 'bool' is not the boolean type.
+
+bool bar(bool a) => false;
+
+int baz(int a) => -1;
+
+class A<T> {
+  T foo(T a) => throw "uncalled";
+}
+
+main() {
+  Expect.isTrue(bar is! F);
+  Expect.isTrue(baz is! F);
+  Expect.isTrue(bar is! F<Object>);
+  Expect.isTrue(baz is! F<Object>);
+  Expect.isTrue(bar is F<bool>);
+  Expect.isTrue(baz is F<int>);
+  Expect.isTrue(bar is! F<int>);
+  Expect.isTrue(baz is! F<bool>);
+
+  var b = new A<bool>();
+  var i = new A<int>();
+  Expect.isTrue(b.foo is F, 'runtime type of covaraint parameters is Object');
+  Expect.isTrue(i.foo is F, 'runtime type of covaraint parameters is Object');
+  Expect.isTrue(
+      b.foo is F<Object>, 'runtime type of covaraint parameters is Object');
+  Expect.isTrue(
+      i.foo is F<Object>, 'runtime type of covaraint parameters is Object');
+  Expect.isTrue(b.foo is F<bool>);
+  Expect.isTrue(i.foo is F<int>);
+  Expect.isTrue(b.foo is! F<int>);
+  Expect.isTrue(i.foo is! F<bool>);
+}
diff --git a/tests/language/function/type_alias5_test.dart b/tests/language/function/type_alias5_test.dart
new file mode 100644
index 0000000..40d6309
--- /dev/null
+++ b/tests/language/function/type_alias5_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for illegally self referencing function type alias.
+
+typedef Handle Handle(String command); //# 00: compile-time error
+
+typedef F(F x); //# 01: compile-time error
+
+typedef A(B x); //# 02: compile-time error
+typedef B(A x); //# 02: continued
+
+main() {
+  Handle h; //# 00: continued
+  F f; //# 01: continued
+  A f; //# 02: continued
+}
diff --git a/tests/language/function/type_alias6_runtime_test.dart b/tests/language/function/type_alias6_runtime_test.dart
new file mode 100644
index 0000000..362fccf
--- /dev/null
+++ b/tests/language/function/type_alias6_runtime_test.dart
@@ -0,0 +1,31 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for legally self referencing function type alias.
+
+import "package:expect/expect.dart";
+
+typedef F(
+    List
+
+        x);
+
+typedef D C();
+
+class D {
+  C foo() => throw "uncalled";
+  D bar() => throw "uncalled";
+}
+
+main() {
+  var f = (List x) {};
+  Expect.isTrue(f is F);
+  var g = (List<F> x) {};
+  Expect.isFalse(g is F);
+  var d = new D();
+  Expect.isTrue(d.foo is! C);
+  Expect.isTrue(d.bar is C);
+}
diff --git a/tests/language/function/type_alias6_test.dart b/tests/language/function/type_alias6_test.dart
new file mode 100644
index 0000000..f8e508d
--- /dev/null
+++ b/tests/language/function/type_alias6_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for legally self referencing function type alias.
+
+import "package:expect/expect.dart";
+
+typedef F(List<F> x);
+// [error line 8, column 1, length 21]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+//      ^
+// [cfe] The typedef 'F' has a reference to itself.
+
+typedef D C();
+
+class D {
+  C foo() => throw "uncalled";
+  D bar() => throw "uncalled";
+}
+
+main() {
+  var f = (List x) {};
+  Expect.isTrue(f is F);
+  var g = (List<F> x) {};
+  Expect.isFalse(g is F);
+  var d = new D();
+  Expect.isTrue(d.foo is! C);
+  Expect.isTrue(d.bar is C);
+}
diff --git a/tests/language/function/type_alias7_test.dart b/tests/language/function/type_alias7_test.dart
new file mode 100644
index 0000000..79bd6e7
--- /dev/null
+++ b/tests/language/function/type_alias7_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+typedef void funcType([int arg]);
+
+typedef void badFuncType([int arg = 0]); //# 00: compile-time error
+
+typedef void badFuncType({int arg: 0}); //# 02: compile-time error
+
+class A
+  extends funcType // //# 01: compile-time error
+{}
+
+main() {
+  new A();
+  badFuncType f; //# 00: continued
+  badFuncType f; //# 02: continued
+}
diff --git a/tests/language/function/type_alias8_test.dart b/tests/language/function/type_alias8_test.dart
new file mode 100644
index 0000000..b272ed7
--- /dev/null
+++ b/tests/language/function/type_alias8_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 9442.
+
+typedef dynamic GetFromThing<T extends Thing>(T target);
+
+typedef GetFromThing<T>? DefGetFromThing<T extends Thing>(dynamic def);
+
+class Thing {}
+
+class Test {
+  static final DefGetFromThing<Thing> fromThing = (dynamic def) {};
+}
+
+main() {
+  Test.fromThing(10);
+}
diff --git a/tests/language/function/type_alias9_runtime_test.dart b/tests/language/function/type_alias9_runtime_test.dart
new file mode 100644
index 0000000..1aa72a3
--- /dev/null
+++ b/tests/language/function/type_alias9_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for legally self referencing function type alias.
+
+typedef void F(
+    List
+
+        l);
+typedef void G(List<F> l);
+
+main() {
+  F? foo(G? g) => g as F?;
+  foo(null);
+}
diff --git a/tests/language/function/type_alias9_test.dart b/tests/language/function/type_alias9_test.dart
new file mode 100644
index 0000000..71c0d7b
--- /dev/null
+++ b/tests/language/function/type_alias9_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for legally self referencing function type alias.
+
+typedef void F(List<G> l);
+// [error line 6, column 1, length 26]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+//           ^
+// [cfe] The typedef 'F' has a reference to itself.
+typedef void G(List<F> l);
+// [error line 11, column 1, length 26]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+
+main() {
+  F? foo(G? g) => g as F?;
+  foo(null);
+}
diff --git a/tests/language/function/type_alias_test.dart b/tests/language/function/type_alias_test.dart
new file mode 100644
index 0000000..9fc9f28
--- /dev/null
+++ b/tests/language/function/type_alias_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--enable_type_checks
+//
+// Dart test for function type alias.
+
+import "package:expect/expect.dart";
+
+typedef Fun(Never a, Never b);
+
+typedef int IntFun(Never a, Never b);
+
+typedef bool BoolFun(Never a, Never b);
+
+typedef int CompareObj(Object a, Object b);
+
+typedef int CompareInt(int a, int b);
+
+typedef int CompareString(String a, String b, [bool swap]);
+
+typedef void Test();
+
+typedef ParameterizedFun1<T, U extends bool, V>(T t, U u);
+
+typedef List<T> ParameterizedFun2<T, U, V extends Map<T, int>>(
+    Map<T, int> t, U u);
+
+typedef void BoundsCheck<T extends num>(T arg);
+
+class FunctionTypeAliasTest {
+  FunctionTypeAliasTest() {}
+  static int test<T>(int compare(T a, T b), T a, T b) {
+    return compare(a, b);
+  }
+
+  foo(Test arg) {}
+  static bar() {
+    FunctionTypeAliasTest a = new FunctionTypeAliasTest();
+    a.foo(() {});
+    return 0;
+  }
+
+  static void testMain() {
+    int compareStrLen(String a, String b) {
+      return a.length - b.length;
+    }
+
+    Expect.isTrue(compareStrLen is Fun);
+    Expect.isTrue(compareStrLen is IntFun);
+    Expect.isTrue(compareStrLen is! BoolFun);
+    Expect.isTrue(compareStrLen is! CompareObj);
+    Expect.isTrue(compareStrLen is! CompareInt);
+    Expect.isTrue(compareStrLen is! CompareString);
+    Expect.equals(3, test(compareStrLen, "abcdef", "xyz"));
+
+    int compareStrLenSwap(String a, String b, [bool swap = false]) {
+      return swap ? (a.length - b.length) : (b.length - a.length);
+    }
+
+    Expect.isTrue(compareStrLenSwap is Fun);
+    Expect.isTrue(compareStrLenSwap is IntFun);
+    Expect.isTrue(compareStrLenSwap is! BoolFun);
+    Expect.isTrue(compareStrLenSwap is! CompareObj);
+    Expect.isTrue(compareStrLenSwap is! CompareInt);
+    Expect.isTrue(compareStrLenSwap is CompareString);
+
+    int compareStrLenReverse(String a, String b, [bool reverse = false]) {
+      return reverse ? (a.length - b.length) : (b.length - a.length);
+    }
+
+    Expect.isTrue(compareStrLenReverse is Fun);
+    Expect.isTrue(compareStrLenReverse is IntFun);
+    Expect.isTrue(compareStrLenReverse is! BoolFun);
+    Expect.isTrue(compareStrLenReverse is! CompareObj);
+    Expect.isTrue(compareStrLenReverse is! CompareInt);
+    Expect.isTrue(compareStrLenReverse is CompareString);
+
+    int compareObj(Object a, Object b) {
+      return identical(a, b) ? 0 : -1;
+    }
+
+    Expect.isTrue(compareObj is Fun);
+    Expect.isTrue(compareObj is IntFun);
+    Expect.isTrue(compareObj is! BoolFun);
+    Expect.isTrue(compareObj is CompareObj);
+    Expect.isTrue(compareObj is CompareInt);
+    Expect.isTrue(compareObj is! CompareString);
+    Expect.equals(-1, test(compareObj, "abcdef", "xyz"));
+
+    CompareInt minus = (int a, int b) {
+      return a - b;
+    };
+    Expect.isTrue(minus is Fun);
+    Expect.isTrue(minus is IntFun);
+    Expect.isTrue(minus is! BoolFun);
+    Expect.isTrue(minus is! CompareObj);
+    Expect.isTrue(minus is CompareInt);
+    Expect.isTrue(minus is! CompareString);
+    Expect.equals(99, test(minus, 100, 1));
+
+    int plus(int a, [int b = 1]) {
+      return a + b;
+    }
+
+    ;
+    Expect.isTrue(plus is Fun);
+    Expect.isTrue(plus is IntFun);
+    Expect.isTrue(plus is! BoolFun);
+    Expect.isTrue(plus is! CompareObj);
+    Expect.isTrue(plus is CompareInt);
+    Expect.isTrue(plus is! CompareString);
+
+    Expect.equals(0, bar());
+
+    Function boundsTrue = (num arg) {};
+    Function boundsFalse = (String arg) {};
+    Expect.isTrue(boundsTrue is BoundsCheck<int>);
+    Expect.isFalse(boundsFalse is BoundsCheck<num>);
+  }
+}
+
+main() {
+  FunctionTypeAliasTest.testMain();
+}
diff --git a/tests/language/function/type_call_getter2_runtime_test.dart b/tests/language/function/type_call_getter2_runtime_test.dart
new file mode 100644
index 0000000..689328b
--- /dev/null
+++ b/tests/language/function/type_call_getter2_runtime_test.dart
@@ -0,0 +1,76 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  final call = null;
+}
+
+class B {
+  get call => null;
+}
+
+class C {
+  set call(x) {}
+}
+
+typedef int F(String str);
+
+main() {
+  A a = new A();
+  B b = new B();
+  C c = new C();
+
+  final
+
+      a2 = a;
+
+  final
+
+      a3 = a;
+
+  final
+
+      b2 = b;
+
+  final
+
+      b3 = b;
+
+  final
+
+      c2 = c;
+
+  final
+
+      c3 = c;
+
+  Expect.throwsTypeError(() {
+    Function a4 = a as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    F a5 = a as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    Function b4 = b as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    F b5 = b as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    Function c4 = c as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    F c5 = c as dynamic;
+  });
+}
diff --git a/tests/language/function/type_call_getter2_test.dart b/tests/language/function/type_call_getter2_test.dart
new file mode 100644
index 0000000..c52cb9e
--- /dev/null
+++ b/tests/language/function/type_call_getter2_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  final call = null;
+}
+
+class B {
+  get call => null;
+}
+
+class C {
+  set call(x) {}
+}
+
+typedef int F(String str);
+
+main() {
+  A a = new A();
+  B b = new B();
+  C c = new C();
+
+  final
+      Function
+      a2 = a;
+      //   ^
+      // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+      // [cfe] A value of type 'A' can't be assigned to a variable of type 'Function'.
+
+  final
+      F
+      a3 = a;
+      //   ^
+      // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+      // [cfe] A value of type 'A' can't be assigned to a variable of type 'int Function(String)'.
+
+  final
+      Function
+      b2 = b;
+      //   ^
+      // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+      // [cfe] A value of type 'B' can't be assigned to a variable of type 'Function'.
+
+  final
+      F
+      b3 = b;
+      //   ^
+      // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+      // [cfe] A value of type 'B' can't be assigned to a variable of type 'int Function(String)'.
+
+  final
+      Function
+      c2 = c;
+      //   ^
+      // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+      // [cfe] A value of type 'C' can't be assigned to a variable of type 'Function'.
+
+  final
+      F
+      c3 = c;
+      //   ^
+      // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+      // [cfe] A value of type 'C' can't be assigned to a variable of type 'int Function(String)'.
+
+  Expect.throwsTypeError(() {
+    Function a4 = a as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    F a5 = a as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    Function b4 = b as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    F b5 = b as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    Function c4 = c as dynamic;
+  });
+
+  Expect.throwsTypeError(() {
+    F c5 = c as dynamic;
+  });
+}
diff --git a/tests/language/function/type_call_getter_test.dart b/tests/language/function/type_call_getter_test.dart
new file mode 100644
index 0000000..52ecbaa
--- /dev/null
+++ b/tests/language/function/type_call_getter_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  final call = null;
+}
+
+class B {
+  get call => null;
+}
+
+class C {
+  set call(x) {}
+}
+
+typedef int F(String str);
+
+main() {
+  Expect.isFalse(new A() is Function);
+  Expect.isFalse(new B() is Function);
+  Expect.isFalse(new C() is Function);
+  Expect.isFalse(new A() is F);
+  Expect.isFalse(new B() is F);
+  Expect.isFalse(new C() is F);
+}
diff --git a/tests/language/function/type_in_constant_test.dart b/tests/language/function/type_in_constant_test.dart
new file mode 100644
index 0000000..ca9db12
--- /dev/null
+++ b/tests/language/function/type_in_constant_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+/// Test that consts can be created with inlined function types as type
+/// arguments.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+  const A();
+}
+
+@pragma('dart2js:noInline')
+test(a, b) {
+  Expect.notEquals(a, b);
+}
+
+main() {
+  test(const A<int Function()>(), const A<String Function()>());
+  test(const A<int>(), const A<String Function()>());
+  test(const A<int Function()>(), const A<String>());
+}
diff --git a/tests/language/function/type_parameter2_test.dart b/tests/language/function/type_parameter2_test.dart
new file mode 100644
index 0000000..4a30d5a
--- /dev/null
+++ b/tests/language/function/type_parameter2_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to check that we can parse closure type formal parameters with
+// default value.
+
+import "package:expect/expect.dart";
+
+class FunctionTypeParameterTest {
+  static var formatter;
+
+  static SetFormatter([String fmt(int i)? = null]) {
+    formatter = fmt;
+  }
+
+  static void testMain() {
+    Expect.equals(null, formatter);
+    SetFormatter((i) => "$i");
+    Expect.equals(false, null == formatter);
+    Expect.equals("1234", formatter(1230 + 4));
+    SetFormatter();
+    Expect.equals(null, formatter);
+  }
+}
+
+main() {
+  FunctionTypeParameterTest.testMain();
+}
diff --git a/tests/language/function/type_parameter3_test.dart b/tests/language/function/type_parameter3_test.dart
new file mode 100644
index 0000000..cb79201
--- /dev/null
+++ b/tests/language/function/type_parameter3_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that we detect that a function literal is not
+/// a compile time constant.
+
+test([String fmt(int i) = (i) => "$i"]) {}
+//                        ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE
+// [cfe] Not a constant expression.
+//                                 ^
+// [cfe] Not a constant expression.
+
+main() {
+  test();
+}
diff --git a/tests/language/function/type_parameter_bound_object_test.dart b/tests/language/function/type_parameter_bound_object_test.dart
new file mode 100644
index 0000000..61486c2f
--- /dev/null
+++ b/tests/language/function/type_parameter_bound_object_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+Q hest<Q>(dynamic x) {
+  if (x is Q) return x;
+  throw "unreached";
+}
+
+Q Function<Q>(dynamic) pony = hest;
+Q Function<Q extends Object?>(dynamic) zebra = hest;
+
+main() {
+  hest(42).fisk(); //# 01: runtime error
+  pony(42).fisk(); //# 02: runtime error
+  zebra(42).fisk(); //# 03: compile-time error
+}
diff --git a/tests/language/function/type_parameter_test.dart b/tests/language/function/type_parameter_test.dart
new file mode 100644
index 0000000..4f18fb8
--- /dev/null
+++ b/tests/language/function/type_parameter_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test to check that we can parse closure type formal parameters with
+// default value.
+
+class A {
+  final f;
+  A(int this.f());
+  const A.nother(int this.f());
+
+  static Function? func;
+
+  static SetFunc([String fmt(int i)? = null]) {
+    func = fmt;
+  }
+}
+
+main() {
+  Expect.equals(null, A.func);
+  A.SetFunc((i) => "$i");
+  Expect.equals(false, null == A.func);
+  Expect.equals("1234", A.func!(1230 + 4));
+  A.SetFunc();
+  Expect.equals(null, A.func);
+
+  Expect.equals(42, new A(() => 42).f());
+  Expect.equals(42, new A.nother(() => 42).f());
+}
diff --git a/tests/language/function/type_test.dart b/tests/language/function/type_test.dart
new file mode 100644
index 0000000..0812e71
--- /dev/null
+++ b/tests/language/function/type_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for a function type test that cannot be eliminated at compile time.
+import "package:expect/expect.dart";
+
+typedef FListInt(List<int> l);
+
+main() {
+  Expect.throwsTypeError(() {
+    // Static result type of f(), i.e. FList, is a subtype of FListInt.
+    // However, run time type of returned function is not a subtype of FListInt.
+    // Run time type check should not be eliminated.
+    FListInt fli = ((List<String> l) => null) as dynamic;
+  });
+}
diff --git a/tests/language/function/type_this_parameter_test.dart b/tests/language/function/type_this_parameter_test.dart
new file mode 100644
index 0000000..4ce65c7
--- /dev/null
+++ b/tests/language/function/type_this_parameter_test.dart
@@ -0,0 +1,17 @@
+// 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.
+// Check that function types are accepted for constructor arguments that
+// initialize fields.
+
+import "package:expect/expect.dart";
+
+class A {
+  Function f;
+  A(int this.f());
+}
+
+main() {
+  var a = new A(() => 499);
+  Expect.equals(499, (a.f)());
+}
diff --git a/tests/language/function_subtype/regress41680_strong_test.dart b/tests/language/function_subtype/regress41680_strong_test.dart
new file mode 100644
index 0000000..f8b79e1
--- /dev/null
+++ b/tests/language/function_subtype/regress41680_strong_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import "package:expect/expect.dart";
+
+typedef dynamicToDynamic = dynamic Function(dynamic);
+
+typedef voidToT = T Function<T>();
+
+dynamic dynamicNull = null;
+
+cast<T>(dynamic value) => value as T;
+
+bool allowsArgument(T Function<T>() fn) => true;
+
+main() {
+  // In strong mode Null is not a subtype of function types.
+  Expect.throwsTypeError(() => dynamicNull as Function);
+  Expect.throwsTypeError(() => dynamicNull as dynamicToDynamic);
+  Expect.throwsTypeError(() => cast<dynamic Function(dynamic)>(dynamicNull));
+  Expect.throwsTypeError(() => dynamicNull as voidToT);
+  Expect.throwsTypeError(() => allowsArgument(dynamicNull));
+}
diff --git a/tests/language/function_subtype/regress41680_weak_test.dart b/tests/language/function_subtype/regress41680_weak_test.dart
new file mode 100644
index 0000000..570ccd5
--- /dev/null
+++ b/tests/language/function_subtype/regress41680_weak_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+typedef dynamicToDynamic = dynamic Function(dynamic);
+
+typedef voidToT = T Function<T>();
+
+dynamic dynamicNull = null;
+
+dynamic cast<T>(dynamic value) => value as T;
+
+bool allowsArgument(T Function<T>() fn) => true;
+
+main() {
+  // In weak mode Null should be allowed as a subtype of function types.
+  Expect.equals(null, dynamicNull as Function);
+  Expect.equals(null, dynamicNull as dynamicToDynamic);
+  Expect.equals(null, cast<dynamic Function(dynamic)>(dynamicNull));
+  Expect.equals(null, dynamicNull as voidToT);
+  Expect.equals(true, allowsArgument(dynamicNull));
+}
diff --git a/tests/language/function_type/function_type0_test.dart b/tests/language/function_type/function_type0_test.dart
new file mode 100644
index 0000000..d2134ef
--- /dev/null
+++ b/tests/language/function_type/function_type0_test.dart
@@ -0,0 +1,923 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x);
+typedef F1<T> = Function Function(List<T> x);
+typedef F2<T> = core.List<core.int> Function(int y, {List<Function> x});
+typedef F3<T> = Function(int, {Function x});
+typedef F4<T> = Function Function<A>(int x);
+typedef F5<T> = int Function(int, {int x}) Function();
+typedef F6<T> = int Function([core.List<core.int> x]) Function();
+typedef F7<T> = Function Function(int y, [int x]) Function();
+typedef F8<T> = Function Function(int, [List<Function>]) Function();
+typedef F9<T> = Function Function(int, {List<T> x}) Function();
+typedef F10<T> = List<Function> Function(List<Function> x) Function();
+typedef F11<T> = List<Function> Function(int y, [List<T> x]) Function();
+typedef F12<T> = core.List<core.int> Function([Function]) Function();
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x})
+    Function();
+typedef F14<T> = List<T> Function(int y, {int x}) Function();
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x]) Function();
+typedef F16<T> = Function(int) Function();
+typedef F17<T> = Function(int x, [List<Function>]) Function();
+typedef F18<T> = Function(int y, {List<T> x}) Function();
+typedef F19<T> = void Function([List<Function> x]) Function();
+typedef F20<T> = void Function(List<T>) Function();
+typedef F21<T> = List<Function> Function<A>(Function x) Function();
+typedef F22<T> = Function<A>(List<Function> x) Function();
+typedef F23<T> = void Function<A>(core.List<core.int> x) Function();
+
+int f0(int x) => throw 'uncalled';
+Function f1(List<int> x) => throw 'uncalled';
+core.List<core.int> f2(int y, {List<Function> x = const []}) =>
+    throw 'uncalled';
+f3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+Function f4<A>(int x) => throw 'uncalled';
+int Function(int, {int x}) f5() => throw 'uncalled';
+int Function([core.List<core.int> x]) f6() => throw 'uncalled';
+Function Function(int y, [int x]) f7() => throw 'uncalled';
+Function Function(int, [List<Function>]) f8() => throw 'uncalled';
+Function Function(int, {List<int> x}) f9() => throw 'uncalled';
+List<Function> Function(List<Function> x) f10() => throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11() => throw 'uncalled';
+core.List<core.int> Function([Function]) f12() => throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x}) f13() => throw 'uncalled';
+List<int> Function(int y, {int x}) f14() => throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15() => throw 'uncalled';
+Function(int) f16() => throw 'uncalled';
+Function(int x, [List<Function>]) f17() => throw 'uncalled';
+Function(int y, {List<int> x}) f18() => throw 'uncalled';
+void Function([List<Function> x]) f19() => throw 'uncalled';
+void Function(List<int>) f20() => throw 'uncalled';
+List<Function> Function<A>(Function x) f21() => throw 'uncalled';
+Function<A>(List<Function> x) f22() => throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23() => throw 'uncalled';
+
+class U0<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x) x0;
+  late Function Function(List<T> x) x1;
+  late core.List<core.int> Function(int y, {List<Function> x}) x2;
+  late Function(int, {Function x}) x3;
+  late Function Function<A>(int x) x4;
+  late int Function(int, {int x}) Function() x5;
+  late int Function([core.List<core.int> x]) Function() x6;
+  late Function Function(int y, [int x]) Function() x7;
+  late Function Function(int, [List<Function>]) Function() x8;
+  late Function Function(int, {List<T> x}) Function() x9;
+  late List<Function> Function(List<Function> x) Function() x10;
+  late List<Function> Function(int y, [List<T> x]) Function() x11;
+  late core.List<core.int> Function([Function]) Function() x12;
+  late core.List<core.int> Function({core.List<core.int> x}) Function() x13;
+  late List<T> Function(int y, {int x}) Function() x14;
+  late List<T> Function(int, [core.List<core.int> x]) Function() x15;
+  late Function(int) Function() x16;
+  late Function(int x, [List<Function>]) Function() x17;
+  late Function(int y, {List<T> x}) Function() x18;
+  late void Function([List<Function> x]) Function() x19;
+  late void Function(List<T>) Function() x20;
+  late List<Function> Function<A>(Function x) Function() x21;
+  late Function<A>(List<Function> x) Function() x22;
+  late void Function<A>(core.List<core.int> x) Function() x23;
+
+  U0({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x) => throw 'uncalled';
+  Function m1(List<T> x) => throw 'uncalled';
+  core.List<core.int> m2(int y, {List<Function> x = const []}) =>
+      throw 'uncalled';
+  m3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  Function m4<A>(int x) => throw 'uncalled';
+  int Function(int, {int x}) m5() => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6() => throw 'uncalled';
+  Function Function(int y, [int x]) m7() => throw 'uncalled';
+  Function Function(int, [List<Function>]) m8() => throw 'uncalled';
+  Function Function(int, {List<T> x}) m9() => throw 'uncalled';
+  List<Function> Function(List<Function> x) m10() => throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11() => throw 'uncalled';
+  core.List<core.int> Function([Function]) m12() => throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x}) m13() =>
+      throw 'uncalled';
+  List<T> Function(int y, {int x}) m14() => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15() => throw 'uncalled';
+  Function(int) m16() => throw 'uncalled';
+  Function(int x, [List<Function>]) m17() => throw 'uncalled';
+  Function(int y, {List<T> x}) m18() => throw 'uncalled';
+  void Function([List<Function> x]) m19() => throw 'uncalled';
+  void Function(List<T>) m20() => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21() => throw 'uncalled';
+  Function<A>(List<Function> x) m22() => throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(List<T> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(List<T> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([Function]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(List<T>) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U0().runTests();
+  new U0<int>(tIsInt: true).runTests();
+  new U0<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type10_test.dart b/tests/language/function_type/function_type10_test.dart
new file mode 100644
index 0000000..fc803d6
--- /dev/null
+++ b/tests/language/function_type/function_type10_test.dart
@@ -0,0 +1,948 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {int x});
+typedef F1<T> = Function Function(int y, {List<T> x});
+typedef F2<T> = core.List<core.int> Function(int, {core.List<core.int> x});
+typedef F3<T> = Function({List<Function> x});
+typedef F4<T> = List<Function> Function<A>(List<Function> x);
+typedef F5<T> = int Function(Function x) Function<B extends core.int>();
+typedef F6<T> = int Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function([int]) Function<B extends core.int>();
+typedef F8<T> = Function Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F9<T> = Function Function() Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function([List<T>])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function([Function x]) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F16<T> = Function(int, [int]) Function<B extends core.int>();
+typedef F17<T> = Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int x) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(int, [List<T>]) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>(List<T> x) Function<B extends core.int>();
+typedef F23<T> = void Function<A>() Function<B extends core.int>();
+
+int f0(int y, {int x = -1}) => throw 'uncalled';
+Function f1(int y, {List<int> x = const []}) => throw 'uncalled';
+core.List<core.int> f2(int x0, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+f3({List<Function> x = const []}) => throw 'uncalled';
+List<Function> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(Function x) f5<B extends core.int>() => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([int]) f7<B extends core.int>() => throw 'uncalled';
+Function Function({List<Function> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+Function Function() f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<int>]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x})
+    f13<B extends core.int>() => throw 'uncalled';
+List<int> Function([Function x]) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(core.List<core.int>) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, [int]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, {List<Function> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(int x) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, [List<int>]) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>(List<int> x) f22<B extends core.int>() => throw 'uncalled';
+void Function<A>() f23<B extends core.int>() => throw 'uncalled';
+
+class U10<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {int x}) x0;
+  late Function Function(int y, {List<T> x}) x1;
+  late core.List<core.int> Function(int, {core.List<core.int> x}) x2;
+  late Function({List<Function> x}) x3;
+  late List<Function> Function<A>(List<Function> x) x4;
+  late int Function(Function x) Function<B extends core.int>() x5;
+  late int Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x6;
+  late Function Function([int]) Function<B extends core.int>() x7;
+  late Function Function({List<Function> x}) Function<B extends core.int>() x8;
+  late Function Function() Function<B extends core.int>() x9;
+  late List<Function> Function(int, [List<Function> x])
+      Function<B extends core.int>() x10;
+  late List<Function> Function([List<T>]) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int x, [Function])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function([Function x]) Function<B extends core.int>() x14;
+  late List<T> Function(core.List<core.int>) Function<B extends core.int>() x15;
+  late Function(int, [int]) Function<B extends core.int>() x16;
+  late Function(int, {List<Function> x}) Function<B extends core.int>() x17;
+  late void Function(int x) Function<B extends core.int>() x18;
+  late void Function(int y, [List<Function> x]) Function<B extends core.int>()
+      x19;
+  late void Function(int, [List<T>]) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>() x21;
+  late Function<A>(List<T> x) Function<B extends core.int>() x22;
+  late void Function<A>() Function<B extends core.int>() x23;
+
+  U10({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {int x = -1}) => throw 'uncalled';
+  Function m1(int y, {List<T> x = const []}) => throw 'uncalled';
+  core.List<core.int> m2(int x0, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  m3({List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(Function x) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([int]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function({List<Function> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function() m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<T>]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x})
+      m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function([Function x]) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, [int]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, {List<Function> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int x) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, [List<T>]) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(List<T> x) m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>() m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int y, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function({List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function({List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U10().runTests();
+  new U10<int>(tIsInt: true).runTests();
+  new U10<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type11_test.dart b/tests/language/function_type/function_type11_test.dart
new file mode 100644
index 0000000..5499988
--- /dev/null
+++ b/tests/language/function_type/function_type11_test.dart
@@ -0,0 +1,948 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(Function x);
+typedef F1<T> = Function Function();
+typedef F2<T> = core.List<core.int> Function(int y, {core.List<core.int> x});
+typedef F3<T> = Function(int, {List<Function> x});
+typedef F4<T> = List<Function> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(Function x) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function([int]) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = Function Function() Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function([List<T>])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function([Function x]) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [int]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, {List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int x) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>(List<T> x) Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>() Function<B extends core.int>(int x);
+
+int f0(Function x) => throw 'uncalled';
+Function f1() => throw 'uncalled';
+core.List<core.int> f2(int y, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+f3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(Function x) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([int]) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function({List<Function> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function() f9<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function([List<int>]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x})
+    f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function([Function x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(core.List<core.int>) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [int]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int, {List<Function> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int x) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [List<int>]) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function<A>(List<int> x) f22<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>() f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U11<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(Function x) x0;
+  late Function Function() x1;
+  late core.List<core.int> Function(int y, {core.List<core.int> x}) x2;
+  late Function(int, {List<Function> x}) x3;
+  late List<Function> Function<A>(core.List<core.int> x) x4;
+  late int Function(Function x) Function<B extends core.int>(int x) x5;
+  late int Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x6;
+  late Function Function([int]) Function<B extends core.int>(int x) x7;
+  late Function Function({List<Function> x}) Function<B extends core.int>(int x)
+      x8;
+  late Function Function() Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int, [List<Function> x])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function([List<T>]) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int x, [Function])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function([Function x]) Function<B extends core.int>(int x) x14;
+  late List<T> Function(core.List<core.int>) Function<B extends core.int>(int x)
+      x15;
+  late Function(int, [int]) Function<B extends core.int>(int x) x16;
+  late Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+      x17;
+  late void Function(int x) Function<B extends core.int>(int x) x18;
+  late void Function(int y, [List<Function> x]) Function<B extends core.int>(
+      int x) x19;
+  late void Function(int, [List<T>]) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>(int x) x21;
+  late Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
+  late void Function<A>() Function<B extends core.int>(int x) x23;
+
+  U11({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(Function x) => throw 'uncalled';
+  Function m1() => throw 'uncalled';
+  core.List<core.int> m2(int y, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  m3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(Function x) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([int]) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function({List<Function> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function() m9<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<T>]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x})
+      m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function([Function x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [int]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, {List<Function> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int x) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [List<T>]) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function<A>(List<T> x) m22<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>() m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(Function x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(Function x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function()
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function() l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function());
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is Function Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U11().runTests();
+  new U11<int>(tIsInt: true).runTests();
+  new U11<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type12_test.dart b/tests/language/function_type/function_type12_test.dart
new file mode 100644
index 0000000..2bb14fc
--- /dev/null
+++ b/tests/language/function_type/function_type12_test.dart
@@ -0,0 +1,941 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([Function x]);
+typedef F1<T> = List<Function> Function(int x);
+typedef F2<T> = core.List<core.int> Function(List<T> x);
+typedef F3<T> = Function(int y, {List<Function> x});
+typedef F4<T> = List<Function> Function<A>(List<T> x);
+typedef F5<T> = int Function([Function x]) Function();
+typedef F6<T> = int Function(core.List<core.int>) Function();
+typedef F7<T> = Function Function(int, [int]) Function();
+typedef F8<T> = Function Function(int, {List<Function> x}) Function();
+typedef F9<T> = List<Function> Function(int x) Function();
+typedef F10<T> = List<Function> Function(int y, [List<Function> x]) Function();
+typedef F11<T> = List<Function> Function(int, [List<T>]) Function();
+typedef F12<T> = core.List<core.int> Function({Function x}) Function();
+typedef F13<T> = core.List<core.int> Function(List<T> x) Function();
+typedef F14<T> = List<T> Function(int, [Function x]) Function();
+typedef F15<T> = List<T> Function([core.List<core.int>]) Function();
+typedef F16<T> = Function(int x, [int]) Function();
+typedef F17<T> = Function(int y, {List<Function> x}) Function();
+typedef F18<T> = void Function([int x]) Function();
+typedef F19<T> = void Function(List<Function>) Function();
+typedef F20<T> = void Function(int x, [List<T>]) Function();
+typedef F21<T> = List<Function> Function<A>(List<T> x) Function();
+typedef F22<T> = Function<A>() Function();
+typedef F23<T> = void Function<A>(A x) Function();
+
+int f0([Function x = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x) => throw 'uncalled';
+core.List<core.int> f2(List<int> x) => throw 'uncalled';
+f3(int y, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f4<A>(List<int> x) => throw 'uncalled';
+int Function([Function x]) f5() => throw 'uncalled';
+int Function(core.List<core.int>) f6() => throw 'uncalled';
+Function Function(int, [int]) f7() => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8() => throw 'uncalled';
+List<Function> Function(int x) f9() => throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10() => throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11() => throw 'uncalled';
+core.List<core.int> Function({Function x}) f12() => throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13() => throw 'uncalled';
+List<int> Function(int, [Function x]) f14() => throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15() => throw 'uncalled';
+Function(int x, [int]) f16() => throw 'uncalled';
+Function(int y, {List<Function> x}) f17() => throw 'uncalled';
+void Function([int x]) f18() => throw 'uncalled';
+void Function(List<Function>) f19() => throw 'uncalled';
+void Function(int x, [List<int>]) f20() => throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21() => throw 'uncalled';
+Function<A>() f22() => throw 'uncalled';
+void Function<A>(A x) f23() => throw 'uncalled';
+
+class U12<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([Function x]) x0;
+  late List<Function> Function(int x) x1;
+  late core.List<core.int> Function(List<T> x) x2;
+  late Function(int y, {List<Function> x}) x3;
+  late List<Function> Function<A>(List<T> x) x4;
+  late int Function([Function x]) Function() x5;
+  late int Function(core.List<core.int>) Function() x6;
+  late Function Function(int, [int]) Function() x7;
+  late Function Function(int, {List<Function> x}) Function() x8;
+  late List<Function> Function(int x) Function() x9;
+  late List<Function> Function(int y, [List<Function> x]) Function() x10;
+  late List<Function> Function(int, [List<T>]) Function() x11;
+  late core.List<core.int> Function({Function x}) Function() x12;
+  late core.List<core.int> Function(List<T> x) Function() x13;
+  late List<T> Function(int, [Function x]) Function() x14;
+  late List<T> Function([core.List<core.int>]) Function() x15;
+  late Function(int x, [int]) Function() x16;
+  late Function(int y, {List<Function> x}) Function() x17;
+  late void Function([int x]) Function() x18;
+  late void Function(List<Function>) Function() x19;
+  late void Function(int x, [List<T>]) Function() x20;
+  late List<Function> Function<A>(List<T> x) Function() x21;
+  late Function<A>() Function() x22;
+  late void Function<A>(A x) Function() x23;
+
+  U12({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([Function x = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x) => throw 'uncalled';
+  core.List<core.int> m2(List<T> x) => throw 'uncalled';
+  m3(int y, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m4<A>(List<T> x) => throw 'uncalled';
+  int Function([Function x]) m5() => throw 'uncalled';
+  int Function(core.List<core.int>) m6() => throw 'uncalled';
+  Function Function(int, [int]) m7() => throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8() => throw 'uncalled';
+  List<Function> Function(int x) m9() => throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x]) m10() => throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11() => throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12() => throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13() => throw 'uncalled';
+  List<T> Function(int, [Function x]) m14() => throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15() => throw 'uncalled';
+  Function(int x, [int]) m16() => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17() => throw 'uncalled';
+  void Function([int x]) m18() => throw 'uncalled';
+  void Function(List<Function>) m19() => throw 'uncalled';
+  void Function(int x, [List<T>]) m20() => throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21() => throw 'uncalled';
+  Function<A>() m22() => throw 'uncalled';
+  void Function<A>(A x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(List<T> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(List<T> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [int]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({Function x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T> x) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<Function>) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(A x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U12().runTests();
+  new U12<int>(tIsInt: true).runTests();
+  new U12<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type13_test.dart b/tests/language/function_type/function_type13_test.dart
new file mode 100644
index 0000000..bdf2ac2
--- /dev/null
+++ b/tests/language/function_type/function_type13_test.dart
@@ -0,0 +1,924 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [Function x]);
+typedef F1<T> = List<Function> Function([int x]);
+typedef F2<T> = core.List<core.int> Function([List<T> x]);
+typedef F3<T> = Function(core.List<core.int> x);
+typedef F4<T> = List<Function> Function<A>();
+typedef F5<T> = int Function([Function x]) Function(int x);
+typedef F6<T> = int Function(core.List<core.int>) Function(int x);
+typedef F7<T> = Function Function(int, [int]) Function(int x);
+typedef F8<T> = Function Function(int, {List<Function> x}) Function(int x);
+typedef F9<T> = List<Function> Function(int x) Function(int x);
+typedef F10<T> = List<Function> Function(int y, [List<Function> x]) Function(
+    int x);
+typedef F11<T> = List<Function> Function(int, [List<T>]) Function(int x);
+typedef F12<T> = core.List<core.int> Function({Function x}) Function(int x);
+typedef F13<T> = core.List<core.int> Function(List<T> x) Function(int x);
+typedef F14<T> = List<T> Function(int, [Function x]) Function(int x);
+typedef F15<T> = List<T> Function([core.List<core.int>]) Function(int x);
+typedef F16<T> = Function(int x, [int]) Function(int x);
+typedef F17<T> = Function(int y, {List<Function> x}) Function(int x);
+typedef F18<T> = void Function([int x]) Function(int x);
+typedef F19<T> = void Function(List<Function>) Function(int x);
+typedef F20<T> = void Function(int x, [List<T>]) Function(int x);
+typedef F21<T> = List<Function> Function<A>(List<T> x) Function(int x);
+typedef F22<T> = Function<A>() Function(int x);
+typedef F23<T> = void Function<A>(A x) Function(int x);
+
+int f0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+List<Function> f1([int x = -1]) => throw 'uncalled';
+core.List<core.int> f2([List<int> x = const []]) => throw 'uncalled';
+f3(core.List<core.int> x) => throw 'uncalled';
+List<Function> f4<A>() => throw 'uncalled';
+int Function([Function x]) f5(int x) => throw 'uncalled';
+int Function(core.List<core.int>) f6(int x) => throw 'uncalled';
+Function Function(int, [int]) f7(int x) => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(int x) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function({Function x}) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13(int x) => throw 'uncalled';
+List<int> Function(int, [Function x]) f14(int x) => throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15(int x) => throw 'uncalled';
+Function(int x, [int]) f16(int x) => throw 'uncalled';
+Function(int y, {List<Function> x}) f17(int x) => throw 'uncalled';
+void Function([int x]) f18(int x) => throw 'uncalled';
+void Function(List<Function>) f19(int x) => throw 'uncalled';
+void Function(int x, [List<int>]) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21(int x) => throw 'uncalled';
+Function<A>() f22(int x) => throw 'uncalled';
+void Function<A>(A x) f23(int x) => throw 'uncalled';
+
+class U13<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [Function x]) x0;
+  late List<Function> Function([int x]) x1;
+  late core.List<core.int> Function([List<T> x]) x2;
+  late Function(core.List<core.int> x) x3;
+  late List<Function> Function<A>() x4;
+  late int Function([Function x]) Function(int x) x5;
+  late int Function(core.List<core.int>) Function(int x) x6;
+  late Function Function(int, [int]) Function(int x) x7;
+  late Function Function(int, {List<Function> x}) Function(int x) x8;
+  late List<Function> Function(int x) Function(int x) x9;
+  late List<Function> Function(int y, [List<Function> x]) Function(int x) x10;
+  late List<Function> Function(int, [List<T>]) Function(int x) x11;
+  late core.List<core.int> Function({Function x}) Function(int x) x12;
+  late core.List<core.int> Function(List<T> x) Function(int x) x13;
+  late List<T> Function(int, [Function x]) Function(int x) x14;
+  late List<T> Function([core.List<core.int>]) Function(int x) x15;
+  late Function(int x, [int]) Function(int x) x16;
+  late Function(int y, {List<Function> x}) Function(int x) x17;
+  late void Function([int x]) Function(int x) x18;
+  late void Function(List<Function>) Function(int x) x19;
+  late void Function(int x, [List<T>]) Function(int x) x20;
+  late List<Function> Function<A>(List<T> x) Function(int x) x21;
+  late Function<A>() Function(int x) x22;
+  late void Function<A>(A x) Function(int x) x23;
+
+  U13({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  List<Function> m1([int x = -1]) => throw 'uncalled';
+  core.List<core.int> m2([List<T> x = const []]) => throw 'uncalled';
+  m3(core.List<core.int> x) => throw 'uncalled';
+  List<Function> m4<A>() => throw 'uncalled';
+  int Function([Function x]) m5(int x) => throw 'uncalled';
+  int Function(core.List<core.int>) m6(int x) => throw 'uncalled';
+  Function Function(int, [int]) m7(int x) => throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(int x) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x]) m10(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13(int x) => throw 'uncalled';
+  List<T> Function(int, [Function x]) m14(int x) => throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15(int x) => throw 'uncalled';
+  Function(int x, [int]) m16(int x) => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17(int x) => throw 'uncalled';
+  void Function([int x]) m18(int x) => throw 'uncalled';
+  void Function(List<Function>) m19(int x) => throw 'uncalled';
+  void Function(int x, [List<T>]) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21(int x) => throw 'uncalled';
+  Function<A>() m22(int x) => throw 'uncalled';
+  void Function<A>(A x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function([List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(core.List<core.int> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([Function x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U13().runTests();
+  new U13<int>(tIsInt: true).runTests();
+  new U13<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type14_test.dart b/tests/language/function_type/function_type14_test.dart
new file mode 100644
index 0000000..9b9f58c0
--- /dev/null
+++ b/tests/language/function_type/function_type14_test.dart
@@ -0,0 +1,968 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [Function x]);
+typedef F1<T> = List<Function> Function(int, [int x]);
+typedef F2<T> = core.List<core.int> Function(int, [List<T> x]);
+typedef F3<T> = Function([core.List<core.int> x]);
+typedef F4<T> = List<Function> Function<A>(A x);
+typedef F5<T> = int Function([Function x]) Function<B extends core.int>();
+typedef F6<T> = int Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [int]) Function<B extends core.int>();
+typedef F8<T> = Function Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int x) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function({Function x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(List<T> x)
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int x, [int]) Function<B extends core.int>();
+typedef F17<T> = Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function([int x]) Function<B extends core.int>();
+typedef F19<T> = void Function(List<Function>) Function<B extends core.int>();
+typedef F20<T> = void Function(int x, [List<T>]) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(List<T> x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>() Function<B extends core.int>();
+typedef F23<T> = void Function<A>(A x) Function<B extends core.int>();
+
+int f0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x0, [int x = -1]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [List<int> x = const []]) => throw 'uncalled';
+f3([core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f4<A>(A x) => throw 'uncalled';
+int Function([Function x]) f5<B extends core.int>() => throw 'uncalled';
+int Function(core.List<core.int>) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [int]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int x) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({Function x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [Function x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int x, [int]) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, {List<Function> x}) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function([int x]) f18<B extends core.int>() => throw 'uncalled';
+void Function(List<Function>) f19<B extends core.int>() => throw 'uncalled';
+void Function(int x, [List<int>]) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>() f22<B extends core.int>() => throw 'uncalled';
+void Function<A>(A x) f23<B extends core.int>() => throw 'uncalled';
+
+class U14<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [Function x]) x0;
+  late List<Function> Function(int, [int x]) x1;
+  late core.List<core.int> Function(int, [List<T> x]) x2;
+  late Function([core.List<core.int> x]) x3;
+  late List<Function> Function<A>(A x) x4;
+  late int Function([Function x]) Function<B extends core.int>() x5;
+  late int Function(core.List<core.int>) Function<B extends core.int>() x6;
+  late Function Function(int, [int]) Function<B extends core.int>() x7;
+  late Function Function(int, {List<Function> x}) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int x) Function<B extends core.int>() x9;
+  late List<Function> Function(int y, [List<Function> x])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(int, [List<T>]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function({Function x}) Function<B extends core.int>()
+      x12;
+  late core.List<core.int> Function(List<T> x) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int, [Function x]) Function<B extends core.int>() x14;
+  late List<T> Function([core.List<core.int>]) Function<B extends core.int>()
+      x15;
+  late Function(int x, [int]) Function<B extends core.int>() x16;
+  late Function(int y, {List<Function> x}) Function<B extends core.int>() x17;
+  late void Function([int x]) Function<B extends core.int>() x18;
+  late void Function(List<Function>) Function<B extends core.int>() x19;
+  late void Function(int x, [List<T>]) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(List<T> x) Function<B extends core.int>() x21;
+  late Function<A>() Function<B extends core.int>() x22;
+  late void Function<A>(A x) Function<B extends core.int>() x23;
+
+  U14({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x0, [int x = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [List<T> x = const []]) => throw 'uncalled';
+  m3([core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m4<A>(A x) => throw 'uncalled';
+  int Function([Function x]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(core.List<core.int>) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [int]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x])
+      m10<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [Function x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int x, [int]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([int x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(List<Function>) m19<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [List<T>]) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>() m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>(A x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([Function x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(core.List<core.int>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function<B extends core.int>()
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(int x, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U14().runTests();
+  new U14<int>(tIsInt: true).runTests();
+  new U14<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type15_test.dart b/tests/language/function_type/function_type15_test.dart
new file mode 100644
index 0000000..0083d12
--- /dev/null
+++ b/tests/language/function_type/function_type15_test.dart
@@ -0,0 +1,992 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(Function);
+typedef F1<T> = List<Function> Function(int y, [int x]);
+typedef F2<T> = core.List<core.int> Function(int y, [List<T> x]);
+typedef F3<T> = Function(int, [core.List<core.int> x]);
+typedef F4<T> = List<Function> Function<A>(List<A> x);
+typedef F5<T> = int Function([Function x]) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(core.List<core.int>) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(int, [int]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int x) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function({Function x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int x, [int]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function([int x]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function(int x, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>() Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>(A x) Function<B extends core.int>(int x);
+
+int f0(Function x0) => throw 'uncalled';
+List<Function> f1(int y, [int x = -1]) => throw 'uncalled';
+core.List<core.int> f2(int y, [List<int> x = const []]) => throw 'uncalled';
+f3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f4<A>(List<A> x) => throw 'uncalled';
+int Function([Function x]) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(core.List<core.int>) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [int]) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({Function x}) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [Function x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int x, [int]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, {List<Function> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([int x]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(List<Function>) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int x, [List<int>]) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>() f22<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(A x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U15<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(Function) x0;
+  late List<Function> Function(int y, [int x]) x1;
+  late core.List<core.int> Function(int y, [List<T> x]) x2;
+  late Function(int, [core.List<core.int> x]) x3;
+  late List<Function> Function<A>(List<A> x) x4;
+  late int Function([Function x]) Function<B extends core.int>(int x) x5;
+  late int Function(core.List<core.int>) Function<B extends core.int>(int x) x6;
+  late Function Function(int, [int]) Function<B extends core.int>(int x) x7;
+  late Function Function(int, {List<Function> x}) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int x) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int y, [List<Function> x])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function(int, [List<T>]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function({Function x}) Function<B extends core.int>(
+      int x) x12;
+  late core.List<core.int> Function(List<T> x) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int, [Function x]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function([core.List<core.int>]) Function<B extends core.int>(
+      int x) x15;
+  late Function(int x, [int]) Function<B extends core.int>(int x) x16;
+  late Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+      x17;
+  late void Function([int x]) Function<B extends core.int>(int x) x18;
+  late void Function(List<Function>) Function<B extends core.int>(int x) x19;
+  late void Function(int x, [List<T>]) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(List<T> x) Function<B extends core.int>(int x)
+      x21;
+  late Function<A>() Function<B extends core.int>(int x) x22;
+  late void Function<A>(A x) Function<B extends core.int>(int x) x23;
+
+  U15({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(Function x0) => throw 'uncalled';
+  List<Function> m1(int y, [int x = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int y, [List<T> x = const []]) => throw 'uncalled';
+  m3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m4<A>(List<A> x) => throw 'uncalled';
+  int Function([Function x]) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(core.List<core.int>) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [int]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [Function x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int x, [int]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([int x]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(List<Function>) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int x, [List<T>]) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>() m22<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(A x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(Function)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(Function));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([Function x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function<B extends core.int>(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int x, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U15().runTests();
+  new U15<int>(tIsInt: true).runTests();
+  new U15<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type16_test.dart b/tests/language/function_type/function_type16_test.dart
new file mode 100644
index 0000000..63edfae
--- /dev/null
+++ b/tests/language/function_type/function_type16_test.dart
@@ -0,0 +1,893 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([Function]);
+typedef F1<T> = List<Function> Function(int);
+typedef F2<T> = core.List<core.int> Function(List<T>);
+typedef F3<T> = Function(int y, [core.List<core.int> x]);
+typedef F4<T> = core.List<core.int> Function<A>(int x);
+typedef F5<T> = int Function(int, [Function x]) Function();
+typedef F6<T> = int Function([core.List<core.int>]) Function();
+typedef F7<T> = Function Function(int x, [int]) Function();
+typedef F8<T> = Function Function(int y, {List<Function> x}) Function();
+typedef F9<T> = List<Function> Function([int x]) Function();
+typedef F10<T> = List<Function> Function(List<Function>) Function();
+typedef F11<T> = List<Function> Function(int x, [List<T>]) Function();
+typedef F12<T> = core.List<core.int> Function(int, {Function x}) Function();
+typedef F13<T> = core.List<core.int> Function([List<T> x]) Function();
+typedef F14<T> = List<T> Function(int y, [Function x]) Function();
+typedef F15<T> = List<T> Function(int, [core.List<core.int>]) Function();
+typedef F16<T> = Function({int x}) Function();
+typedef F17<T> = Function(core.List<core.int> x) Function();
+typedef F18<T> = void Function(int, [int x]) Function();
+typedef F19<T> = void Function([List<Function>]) Function();
+typedef F20<T> = void Function({List<T> x}) Function();
+typedef F21<T> = List<Function> Function<A>() Function();
+typedef F22<T> = Function<A>(A x) Function();
+typedef F23<T> = void Function<A>(List<A> x) Function();
+
+int f0([Function x0 = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x0) => throw 'uncalled';
+core.List<core.int> f2(List<int> x0) => throw 'uncalled';
+f3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(int x) => throw 'uncalled';
+int Function(int, [Function x]) f5() => throw 'uncalled';
+int Function([core.List<core.int>]) f6() => throw 'uncalled';
+Function Function(int x, [int]) f7() => throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8() => throw 'uncalled';
+List<Function> Function([int x]) f9() => throw 'uncalled';
+List<Function> Function(List<Function>) f10() => throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12() => throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13() => throw 'uncalled';
+List<int> Function(int y, [Function x]) f14() => throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15() => throw 'uncalled';
+Function({int x}) f16() => throw 'uncalled';
+Function(core.List<core.int> x) f17() => throw 'uncalled';
+void Function(int, [int x]) f18() => throw 'uncalled';
+void Function([List<Function>]) f19() => throw 'uncalled';
+void Function({List<int> x}) f20() => throw 'uncalled';
+List<Function> Function<A>() f21() => throw 'uncalled';
+Function<A>(A x) f22() => throw 'uncalled';
+void Function<A>(List<A> x) f23() => throw 'uncalled';
+
+class U16<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([Function]) x0;
+  late List<Function> Function(int) x1;
+  late core.List<core.int> Function(List<T>) x2;
+  late Function(int y, [core.List<core.int> x]) x3;
+  late core.List<core.int> Function<A>(int x) x4;
+  late int Function(int, [Function x]) Function() x5;
+  late int Function([core.List<core.int>]) Function() x6;
+  late Function Function(int x, [int]) Function() x7;
+  late Function Function(int y, {List<Function> x}) Function() x8;
+  late List<Function> Function([int x]) Function() x9;
+  late List<Function> Function(List<Function>) Function() x10;
+  late List<Function> Function(int x, [List<T>]) Function() x11;
+  late core.List<core.int> Function(int, {Function x}) Function() x12;
+  late core.List<core.int> Function([List<T> x]) Function() x13;
+  late List<T> Function(int y, [Function x]) Function() x14;
+  late List<T> Function(int, [core.List<core.int>]) Function() x15;
+  late Function({int x}) Function() x16;
+  late Function(core.List<core.int> x) Function() x17;
+  late void Function(int, [int x]) Function() x18;
+  late void Function([List<Function>]) Function() x19;
+  late void Function({List<T> x}) Function() x20;
+  late List<Function> Function<A>() Function() x21;
+  late Function<A>(A x) Function() x22;
+  late void Function<A>(List<A> x) Function() x23;
+
+  U16({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([Function x0 = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x0) => throw 'uncalled';
+  core.List<core.int> m2(List<T> x0) => throw 'uncalled';
+  m3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(int x) => throw 'uncalled';
+  int Function(int, [Function x]) m5() => throw 'uncalled';
+  int Function([core.List<core.int>]) m6() => throw 'uncalled';
+  Function Function(int x, [int]) m7() => throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8() => throw 'uncalled';
+  List<Function> Function([int x]) m9() => throw 'uncalled';
+  List<Function> Function(List<Function>) m10() => throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12() => throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13() => throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14() => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15() => throw 'uncalled';
+  Function({int x}) m16() => throw 'uncalled';
+  Function(core.List<core.int> x) m17() => throw 'uncalled';
+  void Function(int, [int x]) m18() => throw 'uncalled';
+  void Function([List<Function>]) m19() => throw 'uncalled';
+  void Function({List<T> x}) m20() => throw 'uncalled';
+  List<Function> Function<A>() m21() => throw 'uncalled';
+  Function<A>(A x) m22() => throw 'uncalled';
+  void Function<A>(List<A> x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(List<T>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(List<T>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function>) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>() Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U16().runTests();
+  new U16<int>(tIsInt: true).runTests();
+  new U16<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type17_test.dart b/tests/language/function_type/function_type17_test.dart
new file mode 100644
index 0000000..50b4291d
--- /dev/null
+++ b/tests/language/function_type/function_type17_test.dart
@@ -0,0 +1,898 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [Function]);
+typedef F1<T> = List<Function> Function([int]);
+typedef F2<T> = core.List<core.int> Function([List<T>]);
+typedef F3<T> = Function(core.List<core.int>);
+typedef F4<T> = core.List<core.int> Function<A>(Function x);
+typedef F5<T> = int Function(int, [Function x]) Function(int x);
+typedef F6<T> = int Function([core.List<core.int>]) Function(int x);
+typedef F7<T> = Function Function(int x, [int]) Function(int x);
+typedef F8<T> = Function Function(int y, {List<Function> x}) Function(int x);
+typedef F9<T> = List<Function> Function([int x]) Function(int x);
+typedef F10<T> = List<Function> Function(List<Function>) Function(int x);
+typedef F11<T> = List<Function> Function(int x, [List<T>]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, {Function x}) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function([List<T> x]) Function(int x);
+typedef F14<T> = List<T> Function(int y, [Function x]) Function(int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int>]) Function(int x);
+typedef F16<T> = Function({int x}) Function(int x);
+typedef F17<T> = Function(core.List<core.int> x) Function(int x);
+typedef F18<T> = void Function(int, [int x]) Function(int x);
+typedef F19<T> = void Function([List<Function>]) Function(int x);
+typedef F20<T> = void Function({List<T> x}) Function(int x);
+typedef F21<T> = List<Function> Function<A>() Function(int x);
+typedef F22<T> = Function<A>(A x) Function(int x);
+typedef F23<T> = void Function<A>(List<A> x) Function(int x);
+
+int f0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+List<Function> f1([int x0 = -1]) => throw 'uncalled';
+core.List<core.int> f2([List<int> x0 = const []]) => throw 'uncalled';
+f3(core.List<core.int> x0) => throw 'uncalled';
+core.List<core.int> f4<A>(Function x) => throw 'uncalled';
+int Function(int, [Function x]) f5(int x) => throw 'uncalled';
+int Function([core.List<core.int>]) f6(int x) => throw 'uncalled';
+Function Function(int x, [int]) f7(int x) => throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8(int x) => throw 'uncalled';
+List<Function> Function([int x]) f9(int x) => throw 'uncalled';
+List<Function> Function(List<Function>) f10(int x) => throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12(int x) => throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13(int x) => throw 'uncalled';
+List<int> Function(int y, [Function x]) f14(int x) => throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15(int x) => throw 'uncalled';
+Function({int x}) f16(int x) => throw 'uncalled';
+Function(core.List<core.int> x) f17(int x) => throw 'uncalled';
+void Function(int, [int x]) f18(int x) => throw 'uncalled';
+void Function([List<Function>]) f19(int x) => throw 'uncalled';
+void Function({List<int> x}) f20(int x) => throw 'uncalled';
+List<Function> Function<A>() f21(int x) => throw 'uncalled';
+Function<A>(A x) f22(int x) => throw 'uncalled';
+void Function<A>(List<A> x) f23(int x) => throw 'uncalled';
+
+class U17<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [Function]) x0;
+  late List<Function> Function([int]) x1;
+  late core.List<core.int> Function([List<T>]) x2;
+  late Function(core.List<core.int>) x3;
+  late core.List<core.int> Function<A>(Function x) x4;
+  late int Function(int, [Function x]) Function(int x) x5;
+  late int Function([core.List<core.int>]) Function(int x) x6;
+  late Function Function(int x, [int]) Function(int x) x7;
+  late Function Function(int y, {List<Function> x}) Function(int x) x8;
+  late List<Function> Function([int x]) Function(int x) x9;
+  late List<Function> Function(List<Function>) Function(int x) x10;
+  late List<Function> Function(int x, [List<T>]) Function(int x) x11;
+  late core.List<core.int> Function(int, {Function x}) Function(int x) x12;
+  late core.List<core.int> Function([List<T> x]) Function(int x) x13;
+  late List<T> Function(int y, [Function x]) Function(int x) x14;
+  late List<T> Function(int, [core.List<core.int>]) Function(int x) x15;
+  late Function({int x}) Function(int x) x16;
+  late Function(core.List<core.int> x) Function(int x) x17;
+  late void Function(int, [int x]) Function(int x) x18;
+  late void Function([List<Function>]) Function(int x) x19;
+  late void Function({List<T> x}) Function(int x) x20;
+  late List<Function> Function<A>() Function(int x) x21;
+  late Function<A>(A x) Function(int x) x22;
+  late void Function<A>(List<A> x) Function(int x) x23;
+
+  U17({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  List<Function> m1([int x0 = -1]) => throw 'uncalled';
+  core.List<core.int> m2([List<T> x0 = const []]) => throw 'uncalled';
+  m3(core.List<core.int> x0) => throw 'uncalled';
+  core.List<core.int> m4<A>(Function x) => throw 'uncalled';
+  int Function(int, [Function x]) m5(int x) => throw 'uncalled';
+  int Function([core.List<core.int>]) m6(int x) => throw 'uncalled';
+  Function Function(int x, [int]) m7(int x) => throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function([int x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(List<Function>) m10(int x) => throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15(int x) => throw 'uncalled';
+  Function({int x}) m16(int x) => throw 'uncalled';
+  Function(core.List<core.int> x) m17(int x) => throw 'uncalled';
+  void Function(int, [int x]) m18(int x) => throw 'uncalled';
+  void Function([List<Function>]) m19(int x) => throw 'uncalled';
+  void Function({List<T> x}) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>() m21(int x) => throw 'uncalled';
+  Function<A>(A x) m22(int x) => throw 'uncalled';
+  void Function<A>(List<A> x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function([List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(core.List<core.int>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(core.List<core.int>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U17().runTests();
+  new U17<int>(tIsInt: true).runTests();
+  new U17<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type18_test.dart b/tests/language/function_type/function_type18_test.dart
new file mode 100644
index 0000000..6df5530
--- /dev/null
+++ b/tests/language/function_type/function_type18_test.dart
@@ -0,0 +1,942 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [Function]);
+typedef F1<T> = List<Function> Function(int, [int]);
+typedef F2<T> = core.List<core.int> Function(int, [List<T>]);
+typedef F3<T> = Function([core.List<core.int>]);
+typedef F4<T> = core.List<core.int> Function<A>(List<Function> x);
+typedef F5<T> = int Function(int, [Function x]) Function<B extends core.int>();
+typedef F6<T> = int Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int x, [int]) Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([int x]) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(List<Function>)
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function([List<T> x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F16<T> = Function({int x}) Function<B extends core.int>();
+typedef F17<T> = Function(core.List<core.int> x) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [int x]) Function<B extends core.int>();
+typedef F19<T> = void Function([List<Function>]) Function<B extends core.int>();
+typedef F20<T> = void Function({List<T> x}) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>() Function<B extends core.int>();
+typedef F22<T> = Function<A>(A x) Function<B extends core.int>();
+typedef F23<T> = void Function<A>(List<A> x) Function<B extends core.int>();
+
+int f0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x0, [int x1 = -1]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+f3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int, [Function x]) f5<B extends core.int>() => throw 'uncalled';
+int Function([core.List<core.int>]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int x, [int]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([int x]) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(List<Function>) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, [Function x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function({int x}) f16<B extends core.int>() => throw 'uncalled';
+Function(core.List<core.int> x) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [int x]) f18<B extends core.int>() => throw 'uncalled';
+void Function([List<Function>]) f19<B extends core.int>() => throw 'uncalled';
+void Function({List<int> x}) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>() f21<B extends core.int>() => throw 'uncalled';
+Function<A>(A x) f22<B extends core.int>() => throw 'uncalled';
+void Function<A>(List<A> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U18<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [Function]) x0;
+  late List<Function> Function(int, [int]) x1;
+  late core.List<core.int> Function(int, [List<T>]) x2;
+  late Function([core.List<core.int>]) x3;
+  late core.List<core.int> Function<A>(List<Function> x) x4;
+  late int Function(int, [Function x]) Function<B extends core.int>() x5;
+  late int Function([core.List<core.int>]) Function<B extends core.int>() x6;
+  late Function Function(int x, [int]) Function<B extends core.int>() x7;
+  late Function Function(int y, {List<Function> x})
+      Function<B extends core.int>() x8;
+  late List<Function> Function([int x]) Function<B extends core.int>() x9;
+  late List<Function> Function(List<Function>) Function<B extends core.int>()
+      x10;
+  late List<Function> Function(int x, [List<T>]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int, {Function x})
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function([List<T> x]) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int y, [Function x]) Function<B extends core.int>() x14;
+  late List<T> Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x15;
+  late Function({int x}) Function<B extends core.int>() x16;
+  late Function(core.List<core.int> x) Function<B extends core.int>() x17;
+  late void Function(int, [int x]) Function<B extends core.int>() x18;
+  late void Function([List<Function>]) Function<B extends core.int>() x19;
+  late void Function({List<T> x}) Function<B extends core.int>() x20;
+  late List<Function> Function<A>() Function<B extends core.int>() x21;
+  late Function<A>(A x) Function<B extends core.int>() x22;
+  late void Function<A>(List<A> x) Function<B extends core.int>() x23;
+
+  U18({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x0, [int x1 = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  m3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int, [Function x]) m5<B extends core.int>() => throw 'uncalled';
+  int Function([core.List<core.int>]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int x, [int]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([int x]) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(List<Function>) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function({int x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(core.List<core.int> x) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [int x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function([List<Function>]) m19<B extends core.int>() => throw 'uncalled';
+  void Function({List<T> x}) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>() m21<B extends core.int>() => throw 'uncalled';
+  Function<A>(A x) m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>(List<A> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function<B extends core.int>()
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(core.List<core.int> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U18().runTests();
+  new U18<int>(tIsInt: true).runTests();
+  new U18<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type19_test.dart b/tests/language/function_type/function_type19_test.dart
new file mode 100644
index 0000000..7a276f1
--- /dev/null
+++ b/tests/language/function_type/function_type19_test.dart
@@ -0,0 +1,969 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({Function x});
+typedef F1<T> = List<Function> Function(int x, [int]);
+typedef F2<T> = core.List<core.int> Function(int x, [List<T>]);
+typedef F3<T> = Function(int, [core.List<core.int>]);
+typedef F4<T> = core.List<core.int> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int x, [int]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([int x]) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(List<Function>)
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function([List<T> x])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function({int x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function(core.List<core.int> x) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int, [int x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function({List<T> x}) Function<B extends core.int>(int x);
+typedef F21<T> = List<Function> Function<A>() Function<B extends core.int>(
+    int x);
+typedef F22<T> = Function<A>(A x) Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+
+int f0({Function x = _voidFunction}) => throw 'uncalled';
+List<Function> f1(int x, [int x0 = -1]) => throw 'uncalled';
+core.List<core.int> f2(int x, [List<int> x0 = const []]) => throw 'uncalled';
+f3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int, [Function x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function([core.List<core.int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int x, [int]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([int x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<Function>) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [Function x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function({int x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(core.List<core.int> x) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [int x]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function([List<Function>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function({List<int> x}) f20<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function<A>() f21<B extends core.int>(int x) => throw 'uncalled';
+Function<A>(A x) f22<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(List<A> x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U19<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({Function x}) x0;
+  late List<Function> Function(int x, [int]) x1;
+  late core.List<core.int> Function(int x, [List<T>]) x2;
+  late Function(int, [core.List<core.int>]) x3;
+  late core.List<core.int> Function<A>(core.List<core.int> x) x4;
+  late int Function(int, [Function x]) Function<B extends core.int>(int x) x5;
+  late int Function([core.List<core.int>]) Function<B extends core.int>(int x)
+      x6;
+  late Function Function(int x, [int]) Function<B extends core.int>(int x) x7;
+  late Function Function(int y, {List<Function> x})
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function([int x]) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(List<Function>) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function(int x, [List<T>]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int, {Function x})
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function([List<T> x]) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int y, [Function x]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x15;
+  late Function({int x}) Function<B extends core.int>(int x) x16;
+  late Function(core.List<core.int> x) Function<B extends core.int>(int x) x17;
+  late void Function(int, [int x]) Function<B extends core.int>(int x) x18;
+  late void Function([List<Function>]) Function<B extends core.int>(int x) x19;
+  late void Function({List<T> x}) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>() Function<B extends core.int>(int x) x21;
+  late Function<A>(A x) Function<B extends core.int>(int x) x22;
+  late void Function<A>(List<A> x) Function<B extends core.int>(int x) x23;
+
+  U19({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({Function x = _voidFunction}) => throw 'uncalled';
+  List<Function> m1(int x, [int x0 = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  m3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int, [Function x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function([core.List<core.int>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int x, [int]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([int x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<Function>) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function({int x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(core.List<core.int> x) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [int x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<Function>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function({List<T> x}) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function<A>() m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(A x) m22<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(List<A> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function<B extends core.int>(int x)
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function({List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>()
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U19().runTests();
+  new U19<int>(tIsInt: true).runTests();
+  new U19<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type1_test.dart b/tests/language/function_type/function_type1_test.dart
new file mode 100644
index 0000000..4358f50
--- /dev/null
+++ b/tests/language/function_type/function_type1_test.dart
@@ -0,0 +1,927 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([int x]);
+typedef F1<T> = Function Function([List<T> x]);
+typedef F2<T> = core.List<core.int> Function(core.List<core.int> x);
+typedef F3<T> = Function(int y, {Function x});
+typedef F4<T> = Function Function<A>(Function x);
+typedef F5<T> = int Function(int, {int x}) Function(int x);
+typedef F6<T> = int Function([core.List<core.int> x]) Function(int x);
+typedef F7<T> = Function Function(int y, [int x]) Function(int x);
+typedef F8<T> = Function Function(int, [List<Function>]) Function(int x);
+typedef F9<T> = Function Function(int, {List<T> x}) Function(int x);
+typedef F10<T> = List<Function> Function(List<Function> x) Function(int x);
+typedef F11<T> = List<Function> Function(int y, [List<T> x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function([Function]) Function(int x);
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x}) Function(
+    int x);
+typedef F14<T> = List<T> Function(int y, {int x}) Function(int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x]) Function(int x);
+typedef F16<T> = Function(int) Function(int x);
+typedef F17<T> = Function(int x, [List<Function>]) Function(int x);
+typedef F18<T> = Function(int y, {List<T> x}) Function(int x);
+typedef F19<T> = void Function([List<Function> x]) Function(int x);
+typedef F20<T> = void Function(List<T>) Function(int x);
+typedef F21<T> = List<Function> Function<A>(Function x) Function(int x);
+typedef F22<T> = Function<A>(List<Function> x) Function(int x);
+typedef F23<T> = void Function<A>(core.List<core.int> x) Function(int x);
+
+int f0([int x = -1]) => throw 'uncalled';
+Function f1([List<int> x = const []]) => throw 'uncalled';
+core.List<core.int> f2(core.List<core.int> x) => throw 'uncalled';
+f3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+Function f4<A>(Function x) => throw 'uncalled';
+int Function(int, {int x}) f5(int x) => throw 'uncalled';
+int Function([core.List<core.int> x]) f6(int x) => throw 'uncalled';
+Function Function(int y, [int x]) f7(int x) => throw 'uncalled';
+Function Function(int, [List<Function>]) f8(int x) => throw 'uncalled';
+Function Function(int, {List<int> x}) f9(int x) => throw 'uncalled';
+List<Function> Function(List<Function> x) f10(int x) => throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([Function]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {int x}) f14(int x) => throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15(int x) => throw 'uncalled';
+Function(int) f16(int x) => throw 'uncalled';
+Function(int x, [List<Function>]) f17(int x) => throw 'uncalled';
+Function(int y, {List<int> x}) f18(int x) => throw 'uncalled';
+void Function([List<Function> x]) f19(int x) => throw 'uncalled';
+void Function(List<int>) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(Function x) f21(int x) => throw 'uncalled';
+Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23(int x) => throw 'uncalled';
+
+class U1<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([int x]) x0;
+  late Function Function([List<T> x]) x1;
+  late core.List<core.int> Function(core.List<core.int> x) x2;
+  late Function(int y, {Function x}) x3;
+  late Function Function<A>(Function x) x4;
+  late int Function(int, {int x}) Function(int x) x5;
+  late int Function([core.List<core.int> x]) Function(int x) x6;
+  late Function Function(int y, [int x]) Function(int x) x7;
+  late Function Function(int, [List<Function>]) Function(int x) x8;
+  late Function Function(int, {List<T> x}) Function(int x) x9;
+  late List<Function> Function(List<Function> x) Function(int x) x10;
+  late List<Function> Function(int y, [List<T> x]) Function(int x) x11;
+  late core.List<core.int> Function([Function]) Function(int x) x12;
+  late core.List<core.int> Function({core.List<core.int> x}) Function(int x)
+      x13;
+  late List<T> Function(int y, {int x}) Function(int x) x14;
+  late List<T> Function(int, [core.List<core.int> x]) Function(int x) x15;
+  late Function(int) Function(int x) x16;
+  late Function(int x, [List<Function>]) Function(int x) x17;
+  late Function(int y, {List<T> x}) Function(int x) x18;
+  late void Function([List<Function> x]) Function(int x) x19;
+  late void Function(List<T>) Function(int x) x20;
+  late List<Function> Function<A>(Function x) Function(int x) x21;
+  late Function<A>(List<Function> x) Function(int x) x22;
+  late void Function<A>(core.List<core.int> x) Function(int x) x23;
+
+  U1({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([int x = -1]) => throw 'uncalled';
+  Function m1([List<T> x = const []]) => throw 'uncalled';
+  core.List<core.int> m2(core.List<core.int> x) => throw 'uncalled';
+  m3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  Function m4<A>(Function x) => throw 'uncalled';
+  int Function(int, {int x}) m5(int x) => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6(int x) => throw 'uncalled';
+  Function Function(int y, [int x]) m7(int x) => throw 'uncalled';
+  Function Function(int, [List<Function>]) m8(int x) => throw 'uncalled';
+  Function Function(int, {List<T> x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(List<Function> x) m10(int x) => throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([Function]) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {int x}) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15(int x) => throw 'uncalled';
+  Function(int) m16(int x) => throw 'uncalled';
+  Function(int x, [List<Function>]) m17(int x) => throw 'uncalled';
+  Function(int y, {List<T> x}) m18(int x) => throw 'uncalled';
+  void Function([List<Function> x]) m19(int x) => throw 'uncalled';
+  void Function(List<T>) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21(int x) => throw 'uncalled';
+  Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function([List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function([List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int y, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U1().runTests();
+  new U1<int>(tIsInt: true).runTests();
+  new U1<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type20_test.dart b/tests/language/function_type/function_type20_test.dart
new file mode 100644
index 0000000..a8df364
--- /dev/null
+++ b/tests/language/function_type/function_type20_test.dart
@@ -0,0 +1,918 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {Function x});
+typedef F1<T> = List<Function> Function({int x});
+typedef F2<T> = core.List<core.int> Function({List<T> x});
+typedef F3<T> = Function(int x, [core.List<core.int>]);
+typedef F4<T> = core.List<core.int> Function<A>(List<T> x);
+typedef F5<T> = int Function(int y, [Function x]) Function();
+typedef F6<T> = int Function(int, [core.List<core.int>]) Function();
+typedef F7<T> = Function Function({int x}) Function();
+typedef F8<T> = Function Function(core.List<core.int> x) Function();
+typedef F9<T> = List<Function> Function(int, [int x]) Function();
+typedef F10<T> = List<Function> Function([List<Function>]) Function();
+typedef F11<T> = List<Function> Function({List<T> x}) Function();
+typedef F12<T> = core.List<core.int> Function(int y, {Function x}) Function();
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x]) Function();
+typedef F14<T> = List<T> Function(Function) Function();
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>]) Function();
+typedef F16<T> = Function(int, {int x}) Function();
+typedef F17<T> = Function([core.List<core.int> x]) Function();
+typedef F18<T> = void Function(int y, [int x]) Function();
+typedef F19<T> = void Function(int, [List<Function>]) Function();
+typedef F20<T> = void Function(int, {List<T> x}) Function();
+typedef F21<T> = List<Function> Function<A>(A x) Function();
+typedef F22<T> = Function<A>(List<A> x) Function();
+typedef F23<T> = int Function(B x) Function<B extends core.int>();
+
+int f0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+List<Function> f1({int x = -1}) => throw 'uncalled';
+core.List<core.int> f2({List<int> x = const []}) => throw 'uncalled';
+f3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(List<int> x) => throw 'uncalled';
+int Function(int y, [Function x]) f5() => throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6() => throw 'uncalled';
+Function Function({int x}) f7() => throw 'uncalled';
+Function Function(core.List<core.int> x) f8() => throw 'uncalled';
+List<Function> Function(int, [int x]) f9() => throw 'uncalled';
+List<Function> Function([List<Function>]) f10() => throw 'uncalled';
+List<Function> Function({List<int> x}) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12() => throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13() => throw 'uncalled';
+List<int> Function(Function) f14() => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15() => throw 'uncalled';
+Function(int, {int x}) f16() => throw 'uncalled';
+Function([core.List<core.int> x]) f17() => throw 'uncalled';
+void Function(int y, [int x]) f18() => throw 'uncalled';
+void Function(int, [List<Function>]) f19() => throw 'uncalled';
+void Function(int, {List<int> x}) f20() => throw 'uncalled';
+List<Function> Function<A>(A x) f21() => throw 'uncalled';
+Function<A>(List<A> x) f22() => throw 'uncalled';
+int Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U20<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {Function x}) x0;
+  late List<Function> Function({int x}) x1;
+  late core.List<core.int> Function({List<T> x}) x2;
+  late Function(int x, [core.List<core.int>]) x3;
+  late core.List<core.int> Function<A>(List<T> x) x4;
+  late int Function(int y, [Function x]) Function() x5;
+  late int Function(int, [core.List<core.int>]) Function() x6;
+  late Function Function({int x}) Function() x7;
+  late Function Function(core.List<core.int> x) Function() x8;
+  late List<Function> Function(int, [int x]) Function() x9;
+  late List<Function> Function([List<Function>]) Function() x10;
+  late List<Function> Function({List<T> x}) Function() x11;
+  late core.List<core.int> Function(int y, {Function x}) Function() x12;
+  late core.List<core.int> Function(int, [List<T> x]) Function() x13;
+  late List<T> Function(Function) Function() x14;
+  late List<T> Function(int x, [core.List<core.int>]) Function() x15;
+  late Function(int, {int x}) Function() x16;
+  late Function([core.List<core.int> x]) Function() x17;
+  late void Function(int y, [int x]) Function() x18;
+  late void Function(int, [List<Function>]) Function() x19;
+  late void Function(int, {List<T> x}) Function() x20;
+  late List<Function> Function<A>(A x) Function() x21;
+  late Function<A>(List<A> x) Function() x22;
+  late int Function(B x) Function<B extends core.int>() x23;
+
+  U20({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  List<Function> m1({int x = -1}) => throw 'uncalled';
+  core.List<core.int> m2({List<T> x = const []}) => throw 'uncalled';
+  m3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int y, [Function x]) m5() => throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6() => throw 'uncalled';
+  Function Function({int x}) m7() => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8() => throw 'uncalled';
+  List<Function> Function(int, [int x]) m9() => throw 'uncalled';
+  List<Function> Function([List<Function>]) m10() => throw 'uncalled';
+  List<Function> Function({List<T> x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13() => throw 'uncalled';
+  List<T> Function(Function) m14() => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15() => throw 'uncalled';
+  Function(int, {int x}) m16() => throw 'uncalled';
+  Function([core.List<core.int> x]) m17() => throw 'uncalled';
+  void Function(int y, [int x]) m18() => throw 'uncalled';
+  void Function(int, [List<Function>]) m19() => throw 'uncalled';
+  void Function(int, {List<T> x}) m20() => throw 'uncalled';
+  List<Function> Function<A>(A x) m21() => throw 'uncalled';
+  Function<A>(List<A> x) m22() => throw 'uncalled';
+  int Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function({List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function({List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int x, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int y, [Function x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({int x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// int Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    int Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is int Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U20().runTests();
+  new U20<int>(tIsInt: true).runTests();
+  new U20<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type21_test.dart b/tests/language/function_type/function_type21_test.dart
new file mode 100644
index 0000000..ae5fdb6
--- /dev/null
+++ b/tests/language/function_type/function_type21_test.dart
@@ -0,0 +1,899 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {Function x});
+typedef F1<T> = List<Function> Function(int, {int x});
+typedef F2<T> = core.List<core.int> Function(int, {List<T> x});
+typedef F3<T> = Function({core.List<core.int> x});
+typedef F4<T> = core.List<core.int> Function<A>();
+typedef F5<T> = int Function(int y, [Function x]) Function(int x);
+typedef F6<T> = int Function(int, [core.List<core.int>]) Function(int x);
+typedef F7<T> = Function Function({int x}) Function(int x);
+typedef F8<T> = Function Function(core.List<core.int> x) Function(int x);
+typedef F9<T> = List<Function> Function(int, [int x]) Function(int x);
+typedef F10<T> = List<Function> Function([List<Function>]) Function(int x);
+typedef F11<T> = List<Function> Function({List<T> x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {Function x}) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x]) Function(int x);
+typedef F14<T> = List<T> Function(Function) Function(int x);
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>]) Function(int x);
+typedef F16<T> = Function(int, {int x}) Function(int x);
+typedef F17<T> = Function([core.List<core.int> x]) Function(int x);
+typedef F18<T> = void Function(int y, [int x]) Function(int x);
+typedef F19<T> = void Function(int, [List<Function>]) Function(int x);
+typedef F20<T> = void Function(int, {List<T> x}) Function(int x);
+typedef F21<T> = List<Function> Function<A>(A x) Function(int x);
+typedef F22<T> = Function<A>(List<A> x) Function(int x);
+typedef F23<T> = int Function(B x) Function<B extends core.int>(int x);
+
+int f0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+List<Function> f1(int x0, {int x = -1}) => throw 'uncalled';
+core.List<core.int> f2(int x0, {List<int> x = const []}) => throw 'uncalled';
+f3({core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f4<A>() => throw 'uncalled';
+int Function(int y, [Function x]) f5(int x) => throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6(int x) => throw 'uncalled';
+Function Function({int x}) f7(int x) => throw 'uncalled';
+Function Function(core.List<core.int> x) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [int x]) f9(int x) => throw 'uncalled';
+List<Function> Function([List<Function>]) f10(int x) => throw 'uncalled';
+List<Function> Function({List<int> x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13(int x) => throw 'uncalled';
+List<int> Function(Function) f14(int x) => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15(int x) => throw 'uncalled';
+Function(int, {int x}) f16(int x) => throw 'uncalled';
+Function([core.List<core.int> x]) f17(int x) => throw 'uncalled';
+void Function(int y, [int x]) f18(int x) => throw 'uncalled';
+void Function(int, [List<Function>]) f19(int x) => throw 'uncalled';
+void Function(int, {List<int> x}) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(A x) f21(int x) => throw 'uncalled';
+Function<A>(List<A> x) f22(int x) => throw 'uncalled';
+int Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U21<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {Function x}) x0;
+  late List<Function> Function(int, {int x}) x1;
+  late core.List<core.int> Function(int, {List<T> x}) x2;
+  late Function({core.List<core.int> x}) x3;
+  late core.List<core.int> Function<A>() x4;
+  late int Function(int y, [Function x]) Function(int x) x5;
+  late int Function(int, [core.List<core.int>]) Function(int x) x6;
+  late Function Function({int x}) Function(int x) x7;
+  late Function Function(core.List<core.int> x) Function(int x) x8;
+  late List<Function> Function(int, [int x]) Function(int x) x9;
+  late List<Function> Function([List<Function>]) Function(int x) x10;
+  late List<Function> Function({List<T> x}) Function(int x) x11;
+  late core.List<core.int> Function(int y, {Function x}) Function(int x) x12;
+  late core.List<core.int> Function(int, [List<T> x]) Function(int x) x13;
+  late List<T> Function(Function) Function(int x) x14;
+  late List<T> Function(int x, [core.List<core.int>]) Function(int x) x15;
+  late Function(int, {int x}) Function(int x) x16;
+  late Function([core.List<core.int> x]) Function(int x) x17;
+  late void Function(int y, [int x]) Function(int x) x18;
+  late void Function(int, [List<Function>]) Function(int x) x19;
+  late void Function(int, {List<T> x}) Function(int x) x20;
+  late List<Function> Function<A>(A x) Function(int x) x21;
+  late Function<A>(List<A> x) Function(int x) x22;
+  late int Function(B x) Function<B extends core.int>(int x) x23;
+
+  U21({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  List<Function> m1(int x0, {int x = -1}) => throw 'uncalled';
+  core.List<core.int> m2(int x0, {List<T> x = const []}) => throw 'uncalled';
+  m3({core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m4<A>() => throw 'uncalled';
+  int Function(int y, [Function x]) m5(int x) => throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6(int x) => throw 'uncalled';
+  Function Function({int x}) m7(int x) => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [int x]) m9(int x) => throw 'uncalled';
+  List<Function> Function([List<Function>]) m10(int x) => throw 'uncalled';
+  List<Function> Function({List<T> x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13(int x) => throw 'uncalled';
+  List<T> Function(Function) m14(int x) => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15(int x) => throw 'uncalled';
+  Function(int, {int x}) m16(int x) => throw 'uncalled';
+  Function([core.List<core.int> x]) m17(int x) => throw 'uncalled';
+  void Function(int y, [int x]) m18(int x) => throw 'uncalled';
+  void Function(int, [List<Function>]) m19(int x) => throw 'uncalled';
+  void Function(int, {List<T> x}) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(A x) m21(int x) => throw 'uncalled';
+  Function<A>(List<A> x) m22(int x) => throw 'uncalled';
+  int Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function({core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [Function x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {Function x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// int Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    int Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is int Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U21().runTests();
+  new U21<int>(tIsInt: true).runTests();
+  new U21<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type22_test.dart b/tests/language/function_type/function_type22_test.dart
new file mode 100644
index 0000000..371ad94
--- /dev/null
+++ b/tests/language/function_type/function_type22_test.dart
@@ -0,0 +1,947 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<Function> x);
+typedef F1<T> = List<Function> Function(int y, {int x});
+typedef F2<T> = core.List<core.int> Function(int y, {List<T> x});
+typedef F3<T> = Function(int, {core.List<core.int> x});
+typedef F4<T> = core.List<core.int> Function<A>(A x);
+typedef F5<T> = int Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function({int x}) Function<B extends core.int>();
+typedef F8<T> = Function Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [int x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([List<Function>])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function({List<T> x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(Function) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int, {int x}) Function<B extends core.int>();
+typedef F17<T> = Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int y, [int x]) Function<B extends core.int>();
+typedef F19<T> = void Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(int, {List<T> x}) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(A x) Function<B extends core.int>();
+typedef F22<T> = Function<A>(List<A> x) Function<B extends core.int>();
+typedef F23<T> = Function Function(B x) Function<B extends core.int>();
+
+int f0(List<Function> x) => throw 'uncalled';
+List<Function> f1(int y, {int x = -1}) => throw 'uncalled';
+core.List<core.int> f2(int y, {List<int> x = const []}) => throw 'uncalled';
+f3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f4<A>(A x) => throw 'uncalled';
+int Function(int y, [Function x]) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function({int x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function(core.List<core.int> x) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [int x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<Function>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({List<int> x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(Function) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, {int x}) f16<B extends core.int>() => throw 'uncalled';
+Function([core.List<core.int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, [int x]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, [List<Function>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, {List<int> x}) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(A x) f21<B extends core.int>() => throw 'uncalled';
+Function<A>(List<A> x) f22<B extends core.int>() => throw 'uncalled';
+Function Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U22<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<Function> x) x0;
+  late List<Function> Function(int y, {int x}) x1;
+  late core.List<core.int> Function(int y, {List<T> x}) x2;
+  late Function(int, {core.List<core.int> x}) x3;
+  late core.List<core.int> Function<A>(A x) x4;
+  late int Function(int y, [Function x]) Function<B extends core.int>() x5;
+  late int Function(int, [core.List<core.int>]) Function<B extends core.int>()
+      x6;
+  late Function Function({int x}) Function<B extends core.int>() x7;
+  late Function Function(core.List<core.int> x) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int, [int x]) Function<B extends core.int>() x9;
+  late List<Function> Function([List<Function>]) Function<B extends core.int>()
+      x10;
+  late List<Function> Function({List<T> x}) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int y, {Function x})
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, [List<T> x])
+      Function<B extends core.int>() x13;
+  late List<T> Function(Function) Function<B extends core.int>() x14;
+  late List<T> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x15;
+  late Function(int, {int x}) Function<B extends core.int>() x16;
+  late Function([core.List<core.int> x]) Function<B extends core.int>() x17;
+  late void Function(int y, [int x]) Function<B extends core.int>() x18;
+  late void Function(int, [List<Function>]) Function<B extends core.int>() x19;
+  late void Function(int, {List<T> x}) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(A x) Function<B extends core.int>() x21;
+  late Function<A>(List<A> x) Function<B extends core.int>() x22;
+  late Function Function(B x) Function<B extends core.int>() x23;
+
+  U22({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<Function> x) => throw 'uncalled';
+  List<Function> m1(int y, {int x = -1}) => throw 'uncalled';
+  core.List<core.int> m2(int y, {List<T> x = const []}) => throw 'uncalled';
+  m3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m4<A>(A x) => throw 'uncalled';
+  int Function(int y, [Function x]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function({int x}) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [int x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<Function>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({List<T> x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(Function) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, {int x}) m16<B extends core.int>() => throw 'uncalled';
+  Function([core.List<core.int> x]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, [int x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, [List<Function>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, {List<T> x}) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(A x) m21<B extends core.int>() => throw 'uncalled';
+  Function<A>(List<A> x) m22<B extends core.int>() => throw 'uncalled';
+  Function Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<Function> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<Function> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [Function x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x])
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(int, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is Function Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U22().runTests();
+  new U22<int>(tIsInt: true).runTests();
+  new U22<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type23_test.dart b/tests/language/function_type/function_type23_test.dart
new file mode 100644
index 0000000..eb2db97
--- /dev/null
+++ b/tests/language/function_type/function_type23_test.dart
@@ -0,0 +1,951 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<Function> x]);
+typedef F1<T> = List<Function> Function(Function x);
+typedef F2<T> = core.List<core.int> Function();
+typedef F3<T> = Function(int y, {core.List<core.int> x});
+typedef F4<T> = core.List<core.int> Function<A>(List<A> x);
+typedef F5<T> = int Function(int y, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function({int x}) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, [int x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function({List<T> x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(Function) Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, {int x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function([core.List<core.int> x]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function(int, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(A x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = Function<A>(List<A> x) Function<B extends core.int>(int x);
+typedef F23<T> = Function Function(B x) Function<B extends core.int>(int x);
+
+int f0([List<Function> x = const []]) => throw 'uncalled';
+List<Function> f1(Function x) => throw 'uncalled';
+core.List<core.int> f2() => throw 'uncalled';
+f3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f4<A>(List<A> x) => throw 'uncalled';
+int Function(int y, [Function x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function({int x}) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(core.List<core.int> x) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [int x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([List<Function>]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({List<int> x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(Function) f14<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function(int, {int x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function([core.List<core.int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, [int x]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [List<Function>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, {List<int> x}) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(A x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(List<A> x) f22<B extends core.int>(int x) => throw 'uncalled';
+Function Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U23<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<Function> x]) x0;
+  late List<Function> Function(Function x) x1;
+  late core.List<core.int> Function() x2;
+  late Function(int y, {core.List<core.int> x}) x3;
+  late core.List<core.int> Function<A>(List<A> x) x4;
+  late int Function(int y, [Function x]) Function<B extends core.int>(int x) x5;
+  late int Function(int, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x6;
+  late Function Function({int x}) Function<B extends core.int>(int x) x7;
+  late Function Function(core.List<core.int> x) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int, [int x]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function([List<Function>]) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function({List<T> x}) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int y, {Function x})
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, [List<T> x])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(Function) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x15;
+  late Function(int, {int x}) Function<B extends core.int>(int x) x16;
+  late Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+      x17;
+  late void Function(int y, [int x]) Function<B extends core.int>(int x) x18;
+  late void Function(int, [List<Function>]) Function<B extends core.int>(int x)
+      x19;
+  late void Function(int, {List<T> x}) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(A x) Function<B extends core.int>(int x) x21;
+  late Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
+  late Function Function(B x) Function<B extends core.int>(int x) x23;
+
+  U23({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<Function> x = const []]) => throw 'uncalled';
+  List<Function> m1(Function x) => throw 'uncalled';
+  core.List<core.int> m2() => throw 'uncalled';
+  m3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int y, [Function x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({int x}) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [int x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<Function>]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({List<T> x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(Function) m14<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function(int, {int x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function([core.List<core.int> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, [int x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [List<Function>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, {List<T> x}) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(A x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(List<A> x) m22<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(Function x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(Function x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function()
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function());
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int y, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(A x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is Function Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U23().runTests();
+  new U23<int>(tIsInt: true).runTests();
+  new U23<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type24_test.dart b/tests/language/function_type/function_type24_test.dart
new file mode 100644
index 0000000..71b8e09
--- /dev/null
+++ b/tests/language/function_type/function_type24_test.dart
@@ -0,0 +1,944 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<Function> x]);
+typedef F1<T> = List<Function> Function([Function x]);
+typedef F2<T> = List<T> Function(int x);
+typedef F3<T> = Function(List<T> x);
+typedef F4<T> = List<T> Function<A>(int x);
+typedef F5<T> = int Function(Function) Function();
+typedef F6<T> = int Function(int x, [core.List<core.int>]) Function();
+typedef F7<T> = Function Function(int, {int x}) Function();
+typedef F8<T> = Function Function([core.List<core.int> x]) Function();
+typedef F9<T> = List<Function> Function(int y, [int x]) Function();
+typedef F10<T> = List<Function> Function(int, [List<Function>]) Function();
+typedef F11<T> = List<Function> Function(int, {List<T> x}) Function();
+typedef F12<T> = core.List<core.int> Function(List<Function> x) Function();
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x]) Function();
+typedef F14<T> = List<T> Function([Function]) Function();
+typedef F15<T> = List<T> Function({core.List<core.int> x}) Function();
+typedef F16<T> = Function(int y, {int x}) Function();
+typedef F17<T> = Function(int, [core.List<core.int> x]) Function();
+typedef F18<T> = void Function(int) Function();
+typedef F19<T> = void Function(int x, [List<Function>]) Function();
+typedef F20<T> = void Function(int y, {List<T> x}) Function();
+typedef F21<T> = List<Function> Function<A>(List<A> x) Function();
+typedef F22<T> = A Function<A>(int x) Function();
+typedef F23<T> = List<Function> Function(B x) Function<B extends core.int>();
+
+int f0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+List<Function> f1([Function x = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x) => throw 'uncalled';
+f3(List<int> x) => throw 'uncalled';
+List<int> f4<A>(int x) => throw 'uncalled';
+int Function(Function) f5() => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6() => throw 'uncalled';
+Function Function(int, {int x}) f7() => throw 'uncalled';
+Function Function([core.List<core.int> x]) f8() => throw 'uncalled';
+List<Function> Function(int y, [int x]) f9() => throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10() => throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11() => throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12() => throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13() => throw 'uncalled';
+List<int> Function([Function]) f14() => throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15() => throw 'uncalled';
+Function(int y, {int x}) f16() => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17() => throw 'uncalled';
+void Function(int) f18() => throw 'uncalled';
+void Function(int x, [List<Function>]) f19() => throw 'uncalled';
+void Function(int y, {List<int> x}) f20() => throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21() => throw 'uncalled';
+A Function<A>(int x) f22() => throw 'uncalled';
+List<Function> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U24<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<Function> x]) x0;
+  late List<Function> Function([Function x]) x1;
+  late List<T> Function(int x) x2;
+  late Function(List<T> x) x3;
+  late List<T> Function<A>(int x) x4;
+  late int Function(Function) Function() x5;
+  late int Function(int x, [core.List<core.int>]) Function() x6;
+  late Function Function(int, {int x}) Function() x7;
+  late Function Function([core.List<core.int> x]) Function() x8;
+  late List<Function> Function(int y, [int x]) Function() x9;
+  late List<Function> Function(int, [List<Function>]) Function() x10;
+  late List<Function> Function(int, {List<T> x}) Function() x11;
+  late core.List<core.int> Function(List<Function> x) Function() x12;
+  late core.List<core.int> Function(int y, [List<T> x]) Function() x13;
+  late List<T> Function([Function]) Function() x14;
+  late List<T> Function({core.List<core.int> x}) Function() x15;
+  late Function(int y, {int x}) Function() x16;
+  late Function(int, [core.List<core.int> x]) Function() x17;
+  late void Function(int) Function() x18;
+  late void Function(int x, [List<Function>]) Function() x19;
+  late void Function(int y, {List<T> x}) Function() x20;
+  late List<Function> Function<A>(List<A> x) Function() x21;
+  late A Function<A>(int x) Function() x22;
+  late List<Function> Function(B x) Function<B extends core.int>() x23;
+
+  U24({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  List<Function> m1([Function x = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x) => throw 'uncalled';
+  m3(List<T> x) => throw 'uncalled';
+  List<T> m4<A>(int x) => throw 'uncalled';
+  int Function(Function) m5() => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6() => throw 'uncalled';
+  Function Function(int, {int x}) m7() => throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8() => throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9() => throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10() => throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12() => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13() => throw 'uncalled';
+  List<T> Function([Function]) m14() => throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15() => throw 'uncalled';
+  Function(int y, {int x}) m16() => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17() => throw 'uncalled';
+  void Function(int) m18() => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19() => throw 'uncalled';
+  void Function(int y, {List<T> x}) m20() => throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21() => throw 'uncalled';
+  A Function<A>(int x) m22() => throw 'uncalled';
+  List<Function> Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(List<T> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<T> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(int x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<Function> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is List<Function> Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U24().runTests();
+  new U24<int>(tIsInt: true).runTests();
+  new U24<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type25_test.dart b/tests/language/function_type/function_type25_test.dart
new file mode 100644
index 0000000..e50f32c
--- /dev/null
+++ b/tests/language/function_type/function_type25_test.dart
@@ -0,0 +1,956 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [List<Function> x]);
+typedef F1<T> = List<Function> Function(int, [Function x]);
+typedef F2<T> = List<T> Function([int x]);
+typedef F3<T> = Function([List<T> x]);
+typedef F4<T> = List<T> Function<A>(Function x);
+typedef F5<T> = int Function(Function) Function(int x);
+typedef F6<T> = int Function(int x, [core.List<core.int>]) Function(int x);
+typedef F7<T> = Function Function(int, {int x}) Function(int x);
+typedef F8<T> = Function Function([core.List<core.int> x]) Function(int x);
+typedef F9<T> = List<Function> Function(int y, [int x]) Function(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function>]) Function(int x);
+typedef F11<T> = List<Function> Function(int, {List<T> x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function> x) Function(int x);
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x]) Function(
+    int x);
+typedef F14<T> = List<T> Function([Function]) Function(int x);
+typedef F15<T> = List<T> Function({core.List<core.int> x}) Function(int x);
+typedef F16<T> = Function(int y, {int x}) Function(int x);
+typedef F17<T> = Function(int, [core.List<core.int> x]) Function(int x);
+typedef F18<T> = void Function(int) Function(int x);
+typedef F19<T> = void Function(int x, [List<Function>]) Function(int x);
+typedef F20<T> = void Function(int y, {List<T> x}) Function(int x);
+typedef F21<T> = List<Function> Function<A>(List<A> x) Function(int x);
+typedef F22<T> = A Function<A>(int x) Function(int x);
+typedef F23<T> = List<Function> Function(B x) Function<B extends core.int>(
+    int x);
+
+int f0(int y, [List<Function> x = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+List<int> f2([int x = -1]) => throw 'uncalled';
+f3([List<int> x = const []]) => throw 'uncalled';
+List<int> f4<A>(Function x) => throw 'uncalled';
+int Function(Function) f5(int x) => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6(int x) => throw 'uncalled';
+Function Function(int, {int x}) f7(int x) => throw 'uncalled';
+Function Function([core.List<core.int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, [int x]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10(int x) => throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13(int x) =>
+    throw 'uncalled';
+List<int> Function([Function]) f14(int x) => throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15(int x) => throw 'uncalled';
+Function(int y, {int x}) f16(int x) => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17(int x) => throw 'uncalled';
+void Function(int) f18(int x) => throw 'uncalled';
+void Function(int x, [List<Function>]) f19(int x) => throw 'uncalled';
+void Function(int y, {List<int> x}) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21(int x) => throw 'uncalled';
+A Function<A>(int x) f22(int x) => throw 'uncalled';
+List<Function> Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U25<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [List<Function> x]) x0;
+  late List<Function> Function(int, [Function x]) x1;
+  late List<T> Function([int x]) x2;
+  late Function([List<T> x]) x3;
+  late List<T> Function<A>(Function x) x4;
+  late int Function(Function) Function(int x) x5;
+  late int Function(int x, [core.List<core.int>]) Function(int x) x6;
+  late Function Function(int, {int x}) Function(int x) x7;
+  late Function Function([core.List<core.int> x]) Function(int x) x8;
+  late List<Function> Function(int y, [int x]) Function(int x) x9;
+  late List<Function> Function(int, [List<Function>]) Function(int x) x10;
+  late List<Function> Function(int, {List<T> x}) Function(int x) x11;
+  late core.List<core.int> Function(List<Function> x) Function(int x) x12;
+  late core.List<core.int> Function(int y, [List<T> x]) Function(int x) x13;
+  late List<T> Function([Function]) Function(int x) x14;
+  late List<T> Function({core.List<core.int> x}) Function(int x) x15;
+  late Function(int y, {int x}) Function(int x) x16;
+  late Function(int, [core.List<core.int> x]) Function(int x) x17;
+  late void Function(int) Function(int x) x18;
+  late void Function(int x, [List<Function>]) Function(int x) x19;
+  late void Function(int y, {List<T> x}) Function(int x) x20;
+  late List<Function> Function<A>(List<A> x) Function(int x) x21;
+  late A Function<A>(int x) Function(int x) x22;
+  late List<Function> Function(B x) Function<B extends core.int>(int x) x23;
+
+  U25({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [List<Function> x = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  List<T> m2([int x = -1]) => throw 'uncalled';
+  m3([List<T> x = const []]) => throw 'uncalled';
+  List<T> m4<A>(Function x) => throw 'uncalled';
+  int Function(Function) m5(int x) => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6(int x) => throw 'uncalled';
+  Function Function(int, {int x}) m7(int x) => throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10(int x) => throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function([Function]) m14(int x) => throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15(int x) => throw 'uncalled';
+  Function(int y, {int x}) m16(int x) => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17(int x) => throw 'uncalled';
+  void Function(int) m18(int x) => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19(int x) => throw 'uncalled';
+  void Function(int y, {List<T> x}) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21(int x) => throw 'uncalled';
+  A Function<A>(int x) m22(int x) => throw 'uncalled';
+  List<Function> Function(B x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, [List<T> x])
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<Function> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is List<Function> Function(B x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U25().runTests();
+  new U25<int>(tIsInt: true).runTests();
+  new U25<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type26_test.dart b/tests/language/function_type/function_type26_test.dart
new file mode 100644
index 0000000..bb5510c
--- /dev/null
+++ b/tests/language/function_type/function_type26_test.dart
@@ -0,0 +1,1011 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<Function>);
+typedef F1<T> = List<Function> Function(int y, [Function x]);
+typedef F2<T> = List<T> Function(int, [int x]);
+typedef F3<T> = Function(int, [List<T> x]);
+typedef F4<T> = List<T> Function<A>(List<Function> x);
+typedef F5<T> = int Function(Function) Function<B extends core.int>();
+typedef F6<T> = int Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int, {int x}) Function<B extends core.int>();
+typedef F8<T> = Function Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function([Function]) Function<B extends core.int>();
+typedef F15<T> = List<T> Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function(int y, {int x}) Function<B extends core.int>();
+typedef F17<T> = Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int) Function<B extends core.int>();
+typedef F19<T> = void Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(List<A> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(int x) Function<B extends core.int>();
+typedef F23<T> = core.List<core.int> Function(B x)
+    Function<B extends core.int>();
+
+int f0(List<Function> x0) => throw 'uncalled';
+List<Function> f1(int y, [Function x = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x0, [int x = -1]) => throw 'uncalled';
+f3(int x0, [List<int> x = const []]) => throw 'uncalled';
+List<int> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(Function) f5<B extends core.int>() => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, {int x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function([core.List<core.int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, [int x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([Function]) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int y, {int x}) f16<B extends core.int>() => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int) f18<B extends core.int>() => throw 'uncalled';
+void Function(int x, [List<Function>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int y, {List<int> x}) f20<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(int x) f22<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U26<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<Function>) x0;
+  late List<Function> Function(int y, [Function x]) x1;
+  late List<T> Function(int, [int x]) x2;
+  late Function(int, [List<T> x]) x3;
+  late List<T> Function<A>(List<Function> x) x4;
+  late int Function(Function) Function<B extends core.int>() x5;
+  late int Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+      x6;
+  late Function Function(int, {int x}) Function<B extends core.int>() x7;
+  late Function Function([core.List<core.int> x]) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int y, [int x]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int, [List<Function>])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(int, {List<T> x}) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(List<Function> x)
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int y, [List<T> x])
+      Function<B extends core.int>() x13;
+  late List<T> Function([Function]) Function<B extends core.int>() x14;
+  late List<T> Function({core.List<core.int> x}) Function<B extends core.int>()
+      x15;
+  late Function(int y, {int x}) Function<B extends core.int>() x16;
+  late Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+      x17;
+  late void Function(int) Function<B extends core.int>() x18;
+  late void Function(int x, [List<Function>]) Function<B extends core.int>()
+      x19;
+  late void Function(int y, {List<T> x}) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(List<A> x) Function<B extends core.int>() x21;
+  late A Function<A>(int x) Function<B extends core.int>() x22;
+  late core.List<core.int> Function(B x) Function<B extends core.int>() x23;
+
+  U26({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<Function> x0) => throw 'uncalled';
+  List<Function> m1(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x0, [int x = -1]) => throw 'uncalled';
+  m3(int x0, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(Function) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, {int x}) m7<B extends core.int>() => throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([Function]) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int y, {int x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, {List<T> x}) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(int x) m22<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(B x) m23<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<Function>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<Function>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x)
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function<B extends core.int>()
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// core.List<core.int> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is core.List<core.int> Function(B x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U26().runTests();
+  new U26<int>(tIsInt: true).runTests();
+  new U26<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type27_test.dart b/tests/language/function_type/function_type27_test.dart
new file mode 100644
index 0000000..d96f60e
--- /dev/null
+++ b/tests/language/function_type/function_type27_test.dart
@@ -0,0 +1,1032 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<Function>]);
+typedef F1<T> = List<Function> Function(Function);
+typedef F2<T> = List<T> Function(int y, [int x]);
+typedef F3<T> = Function(int y, [List<T> x]);
+typedef F4<T> = List<T> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(Function) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, {int x}) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int y, [int x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function([Function]) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int y, {int x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function(int y, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(List<A> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(int x) Function<B extends core.int>(int x);
+typedef F23<T> = core.List<core.int> Function(B x) Function<B extends core.int>(
+    int x);
+
+int f0([List<Function> x0 = const []]) => throw 'uncalled';
+List<Function> f1(Function x0) => throw 'uncalled';
+List<int> f2(int y, [int x = -1]) => throw 'uncalled';
+f3(int y, [List<int> x = const []]) => throw 'uncalled';
+List<int> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(Function) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {int x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([core.List<core.int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [int x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function([Function]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, {int x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int x, [List<Function>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, {List<int> x}) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(int x) f22<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function(B x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U27<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<Function>]) x0;
+  late List<Function> Function(Function) x1;
+  late List<T> Function(int y, [int x]) x2;
+  late Function(int y, [List<T> x]) x3;
+  late List<T> Function<A>(core.List<core.int> x) x4;
+  late int Function(Function) Function<B extends core.int>(int x) x5;
+  late int Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x6;
+  late Function Function(int, {int x}) Function<B extends core.int>(int x) x7;
+  late Function Function([core.List<core.int> x]) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int y, [int x]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int, [List<Function>])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function(int, {List<T> x}) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(List<Function> x)
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int y, [List<T> x])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function([Function]) Function<B extends core.int>(int x) x14;
+  late List<T> Function({core.List<core.int> x}) Function<B extends core.int>(
+      int x) x15;
+  late Function(int y, {int x}) Function<B extends core.int>(int x) x16;
+  late Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x17;
+  late void Function(int) Function<B extends core.int>(int x) x18;
+  late void Function(int x, [List<Function>]) Function<B extends core.int>(
+      int x) x19;
+  late void Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+      x20;
+  late List<Function> Function<A>(List<A> x) Function<B extends core.int>(int x)
+      x21;
+  late A Function<A>(int x) Function<B extends core.int>(int x) x22;
+  late core.List<core.int> Function(B x) Function<B extends core.int>(int x)
+      x23;
+
+  U27({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<Function> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(Function x0) => throw 'uncalled';
+  List<T> m2(int y, [int x = -1]) => throw 'uncalled';
+  m3(int y, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(Function) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {int x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function([Function]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {int x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {List<T> x}) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(int x) m22<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function(B x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(Function)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(Function));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// core.List<core.int> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is core.List<core.int> Function(B x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U27().runTests();
+  new U27<int>(tIsInt: true).runTests();
+  new U27<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type28_test.dart b/tests/language/function_type/function_type28_test.dart
new file mode 100644
index 0000000..43d24f0
--- /dev/null
+++ b/tests/language/function_type/function_type28_test.dart
@@ -0,0 +1,945 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<Function>]);
+typedef F1<T> = List<Function> Function([Function]);
+typedef F2<T> = List<T> Function(int);
+typedef F3<T> = Function(List<T>);
+typedef F4<T> = List<T> Function<A>(List<T> x);
+typedef F5<T> = int Function([Function]) Function();
+typedef F6<T> = int Function({core.List<core.int> x}) Function();
+typedef F7<T> = Function Function(int y, {int x}) Function();
+typedef F8<T> = Function Function(int, [core.List<core.int> x]) Function();
+typedef F9<T> = List<Function> Function(int) Function();
+typedef F10<T> = List<Function> Function(int x, [List<Function>]) Function();
+typedef F11<T> = List<Function> Function(int y, {List<T> x}) Function();
+typedef F12<T> = core.List<core.int> Function([List<Function> x]) Function();
+typedef F13<T> = core.List<core.int> Function(List<T>) Function();
+typedef F14<T> = List<T> Function(int, [Function]) Function();
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x}) Function();
+typedef F16<T> = Function(Function x) Function();
+typedef F17<T> = Function(int y, [core.List<core.int> x]) Function();
+typedef F18<T> = void Function([int]) Function();
+typedef F19<T> = void Function({List<Function> x}) Function();
+typedef F20<T> = void Function() Function();
+typedef F21<T> = core.List<core.int> Function<A>(int x) Function();
+typedef F22<T> = A Function<A>(Function x) Function();
+typedef F23<T> = List<T> Function(B x) Function<B extends core.int>();
+
+int f0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+List<Function> f1([Function x0 = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x0) => throw 'uncalled';
+f3(List<int> x0) => throw 'uncalled';
+List<int> f4<A>(List<int> x) => throw 'uncalled';
+int Function([Function]) f5() => throw 'uncalled';
+int Function({core.List<core.int> x}) f6() => throw 'uncalled';
+Function Function(int y, {int x}) f7() => throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8() => throw 'uncalled';
+List<Function> Function(int) f9() => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10() => throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11() => throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12() => throw 'uncalled';
+core.List<core.int> Function(List<int>) f13() => throw 'uncalled';
+List<int> Function(int, [Function]) f14() => throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15() => throw 'uncalled';
+Function(Function x) f16() => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17() => throw 'uncalled';
+void Function([int]) f18() => throw 'uncalled';
+void Function({List<Function> x}) f19() => throw 'uncalled';
+void Function() f20() => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21() => throw 'uncalled';
+A Function<A>(Function x) f22() => throw 'uncalled';
+List<int> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U28<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<Function>]) x0;
+  late List<Function> Function([Function]) x1;
+  late List<T> Function(int) x2;
+  late Function(List<T>) x3;
+  late List<T> Function<A>(List<T> x) x4;
+  late int Function([Function]) Function() x5;
+  late int Function({core.List<core.int> x}) Function() x6;
+  late Function Function(int y, {int x}) Function() x7;
+  late Function Function(int, [core.List<core.int> x]) Function() x8;
+  late List<Function> Function(int) Function() x9;
+  late List<Function> Function(int x, [List<Function>]) Function() x10;
+  late List<Function> Function(int y, {List<T> x}) Function() x11;
+  late core.List<core.int> Function([List<Function> x]) Function() x12;
+  late core.List<core.int> Function(List<T>) Function() x13;
+  late List<T> Function(int, [Function]) Function() x14;
+  late List<T> Function(int, {core.List<core.int> x}) Function() x15;
+  late Function(Function x) Function() x16;
+  late Function(int y, [core.List<core.int> x]) Function() x17;
+  late void Function([int]) Function() x18;
+  late void Function({List<Function> x}) Function() x19;
+  late void Function() Function() x20;
+  late core.List<core.int> Function<A>(int x) Function() x21;
+  late A Function<A>(Function x) Function() x22;
+  late List<T> Function(B x) Function<B extends core.int>() x23;
+
+  U28({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  List<Function> m1([Function x0 = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x0) => throw 'uncalled';
+  m3(List<T> x0) => throw 'uncalled';
+  List<T> m4<A>(List<T> x) => throw 'uncalled';
+  int Function([Function]) m5() => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6() => throw 'uncalled';
+  Function Function(int y, {int x}) m7() => throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8() => throw 'uncalled';
+  List<Function> Function(int) m9() => throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10() => throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11() => throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12() => throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13() => throw 'uncalled';
+  List<T> Function(int, [Function]) m14() => throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15() => throw 'uncalled';
+  Function(Function x) m16() => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17() => throw 'uncalled';
+  void Function([int]) m18() => throw 'uncalled';
+  void Function({List<Function> x}) m19() => throw 'uncalled';
+  void Function() m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21() => throw 'uncalled';
+  A Function<A>(Function x) m22() => throw 'uncalled';
+  List<T> Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(List<T>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<T>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function x) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<T> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is List<T> Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U28().runTests();
+  new U28<int>(tIsInt: true).runTests();
+  new U28<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type29_test.dart b/tests/language/function_type/function_type29_test.dart
new file mode 100644
index 0000000..698cd38
--- /dev/null
+++ b/tests/language/function_type/function_type29_test.dart
@@ -0,0 +1,952 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [List<Function>]);
+typedef F1<T> = List<Function> Function(int, [Function]);
+typedef F2<T> = List<T> Function([int]);
+typedef F3<T> = Function([List<T>]);
+typedef F4<T> = List<T> Function<A>();
+typedef F5<T> = int Function([Function]) Function(int x);
+typedef F6<T> = int Function({core.List<core.int> x}) Function(int x);
+typedef F7<T> = Function Function(int y, {int x}) Function(int x);
+typedef F8<T> = Function Function(int, [core.List<core.int> x]) Function(int x);
+typedef F9<T> = List<Function> Function(int) Function(int x);
+typedef F10<T> = List<Function> Function(int x, [List<Function>]) Function(
+    int x);
+typedef F11<T> = List<Function> Function(int y, {List<T> x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function> x]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(List<T>) Function(int x);
+typedef F14<T> = List<T> Function(int, [Function]) Function(int x);
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x}) Function(int x);
+typedef F16<T> = Function(Function x) Function(int x);
+typedef F17<T> = Function(int y, [core.List<core.int> x]) Function(int x);
+typedef F18<T> = void Function([int]) Function(int x);
+typedef F19<T> = void Function({List<Function> x}) Function(int x);
+typedef F20<T> = void Function() Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(int x) Function(int x);
+typedef F22<T> = A Function<A>(Function x) Function(int x);
+typedef F23<T> = List<T> Function(B x) Function<B extends core.int>(int x);
+
+int f0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+List<int> f2([int x0 = -1]) => throw 'uncalled';
+f3([List<int> x0 = const []]) => throw 'uncalled';
+List<int> f4<A>() => throw 'uncalled';
+int Function([Function]) f5(int x) => throw 'uncalled';
+int Function({core.List<core.int> x}) f6(int x) => throw 'uncalled';
+Function Function(int y, {int x}) f7(int x) => throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(int) f9(int x) => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10(int x) => throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(List<int>) f13(int x) => throw 'uncalled';
+List<int> Function(int, [Function]) f14(int x) => throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15(int x) => throw 'uncalled';
+Function(Function x) f16(int x) => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17(int x) => throw 'uncalled';
+void Function([int]) f18(int x) => throw 'uncalled';
+void Function({List<Function> x}) f19(int x) => throw 'uncalled';
+void Function() f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21(int x) => throw 'uncalled';
+A Function<A>(Function x) f22(int x) => throw 'uncalled';
+List<int> Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U29<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [List<Function>]) x0;
+  late List<Function> Function(int, [Function]) x1;
+  late List<T> Function([int]) x2;
+  late Function([List<T>]) x3;
+  late List<T> Function<A>() x4;
+  late int Function([Function]) Function(int x) x5;
+  late int Function({core.List<core.int> x}) Function(int x) x6;
+  late Function Function(int y, {int x}) Function(int x) x7;
+  late Function Function(int, [core.List<core.int> x]) Function(int x) x8;
+  late List<Function> Function(int) Function(int x) x9;
+  late List<Function> Function(int x, [List<Function>]) Function(int x) x10;
+  late List<Function> Function(int y, {List<T> x}) Function(int x) x11;
+  late core.List<core.int> Function([List<Function> x]) Function(int x) x12;
+  late core.List<core.int> Function(List<T>) Function(int x) x13;
+  late List<T> Function(int, [Function]) Function(int x) x14;
+  late List<T> Function(int, {core.List<core.int> x}) Function(int x) x15;
+  late Function(Function x) Function(int x) x16;
+  late Function(int y, [core.List<core.int> x]) Function(int x) x17;
+  late void Function([int]) Function(int x) x18;
+  late void Function({List<Function> x}) Function(int x) x19;
+  late void Function() Function(int x) x20;
+  late core.List<core.int> Function<A>(int x) Function(int x) x21;
+  late A Function<A>(Function x) Function(int x) x22;
+  late List<T> Function(B x) Function<B extends core.int>(int x) x23;
+
+  U29({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  List<T> m2([int x0 = -1]) => throw 'uncalled';
+  m3([List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m4<A>() => throw 'uncalled';
+  int Function([Function]) m5(int x) => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6(int x) => throw 'uncalled';
+  Function Function(int y, {int x}) m7(int x) => throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int) m9(int x) => throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13(int x) => throw 'uncalled';
+  List<T> Function(int, [Function]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15(int x) => throw 'uncalled';
+  Function(Function x) m16(int x) => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17(int x) => throw 'uncalled';
+  void Function([int]) m18(int x) => throw 'uncalled';
+  void Function({List<Function> x}) m19(int x) => throw 'uncalled';
+  void Function() m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21(int x) => throw 'uncalled';
+  A Function<A>(Function x) m22(int x) => throw 'uncalled';
+  List<T> Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [List<Function>])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int y, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<T> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is List<T> Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U29().runTests();
+  new U29<int>(tIsInt: true).runTests();
+  new U29<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type2_test.dart b/tests/language/function_type/function_type2_test.dart
new file mode 100644
index 0000000..91eb040
--- /dev/null
+++ b/tests/language/function_type/function_type2_test.dart
@@ -0,0 +1,984 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [int x]);
+typedef F1<T> = Function Function(int, [List<T> x]);
+typedef F2<T> = core.List<core.int> Function([core.List<core.int> x]);
+typedef F3<T> = Function(List<Function> x);
+typedef F4<T> = Function Function<A>(List<Function> x);
+typedef F5<T> = int Function(int, {int x}) Function<B extends core.int>();
+typedef F6<T> = int Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F9<T> = Function Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([Function])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int) Function<B extends core.int>();
+typedef F17<T> = Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F18<T> = Function(int y, {List<T> x}) Function<B extends core.int>();
+typedef F19<T> = void Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(List<T>) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(Function x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>(List<Function> x) Function<B extends core.int>();
+typedef F23<T> = void Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+
+int f0(int x0, [int x = -1]) => throw 'uncalled';
+Function f1(int x0, [List<int> x = const []]) => throw 'uncalled';
+core.List<core.int> f2([core.List<core.int> x = const []]) => throw 'uncalled';
+f3(List<Function> x) => throw 'uncalled';
+Function f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int, {int x}) f5<B extends core.int>() => throw 'uncalled';
+int Function([core.List<core.int> x]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, [int x]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, [List<Function>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, {List<int> x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(List<Function> x) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([Function]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x})
+    f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, {int x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int) f16<B extends core.int>() => throw 'uncalled';
+Function(int x, [List<Function>]) f17<B extends core.int>() => throw 'uncalled';
+Function(int y, {List<int> x}) f18<B extends core.int>() => throw 'uncalled';
+void Function([List<Function> x]) f19<B extends core.int>() => throw 'uncalled';
+void Function(List<int>) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(Function x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>(List<Function> x) f22<B extends core.int>() => throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23<B extends core.int>() =>
+    throw 'uncalled';
+
+class U2<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [int x]) x0;
+  late Function Function(int, [List<T> x]) x1;
+  late core.List<core.int> Function([core.List<core.int> x]) x2;
+  late Function(List<Function> x) x3;
+  late Function Function<A>(List<Function> x) x4;
+  late int Function(int, {int x}) Function<B extends core.int>() x5;
+  late int Function([core.List<core.int> x]) Function<B extends core.int>() x6;
+  late Function Function(int y, [int x]) Function<B extends core.int>() x7;
+  late Function Function(int, [List<Function>]) Function<B extends core.int>()
+      x8;
+  late Function Function(int, {List<T> x}) Function<B extends core.int>() x9;
+  late List<Function> Function(List<Function> x) Function<B extends core.int>()
+      x10;
+  late List<Function> Function(int y, [List<T> x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function([Function]) Function<B extends core.int>()
+      x12;
+  late core.List<core.int> Function({core.List<core.int> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function(int y, {int x}) Function<B extends core.int>() x14;
+  late List<T> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x15;
+  late Function(int) Function<B extends core.int>() x16;
+  late Function(int x, [List<Function>]) Function<B extends core.int>() x17;
+  late Function(int y, {List<T> x}) Function<B extends core.int>() x18;
+  late void Function([List<Function> x]) Function<B extends core.int>() x19;
+  late void Function(List<T>) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(Function x) Function<B extends core.int>()
+      x21;
+  late Function<A>(List<Function> x) Function<B extends core.int>() x22;
+  late void Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x23;
+
+  U2({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [int x = -1]) => throw 'uncalled';
+  Function m1(int x0, [List<T> x = const []]) => throw 'uncalled';
+  core.List<core.int> m2([core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  m3(List<Function> x) => throw 'uncalled';
+  Function m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int, {int x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, [int x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [List<Function>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, {List<T> x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(List<Function> x) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x})
+      m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, {int x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int) m16<B extends core.int>() => throw 'uncalled';
+  Function(int x, [List<Function>]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int y, {List<T> x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function([List<Function> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(List<T>) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(List<Function> x) m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(List<Function> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<Function> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is Function(int y, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is Function<A>(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U2().runTests();
+  new U2<int>(tIsInt: true).runTests();
+  new U2<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type30_test.dart b/tests/language/function_type/function_type30_test.dart
new file mode 100644
index 0000000..195eaba
--- /dev/null
+++ b/tests/language/function_type/function_type30_test.dart
@@ -0,0 +1,976 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({List<Function> x});
+typedef F1<T> = List<Function> Function(int x, [Function]);
+typedef F2<T> = List<T> Function(int, [int]);
+typedef F3<T> = Function(int, [List<T>]);
+typedef F4<T> = List<T> Function<A>(A x);
+typedef F5<T> = int Function([Function]) Function<B extends core.int>();
+typedef F6<T> = int Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(List<T>)
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [Function])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function(Function x) Function<B extends core.int>();
+typedef F17<T> = Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F18<T> = void Function([int]) Function<B extends core.int>();
+typedef F19<T> = void Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F20<T> = void Function() Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(int x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(Function x) Function<B extends core.int>();
+typedef F23<T> = Function(B x) Function<B extends core.int>();
+
+int f0({List<Function> x = const []}) => throw 'uncalled';
+List<Function> f1(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x0, [int x1 = -1]) => throw 'uncalled';
+f3(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+List<int> f4<A>(A x) => throw 'uncalled';
+int Function([Function]) f5<B extends core.int>() => throw 'uncalled';
+int Function({core.List<core.int> x}) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, {int x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int>) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [Function]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(Function x) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function([int]) f18<B extends core.int>() => throw 'uncalled';
+void Function({List<Function> x}) f19<B extends core.int>() => throw 'uncalled';
+void Function() f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(Function x) f22<B extends core.int>() => throw 'uncalled';
+Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U30<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({List<Function> x}) x0;
+  late List<Function> Function(int x, [Function]) x1;
+  late List<T> Function(int, [int]) x2;
+  late Function(int, [List<T>]) x3;
+  late List<T> Function<A>(A x) x4;
+  late int Function([Function]) Function<B extends core.int>() x5;
+  late int Function({core.List<core.int> x}) Function<B extends core.int>() x6;
+  late Function Function(int y, {int x}) Function<B extends core.int>() x7;
+  late Function Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x8;
+  late List<Function> Function(int) Function<B extends core.int>() x9;
+  late List<Function> Function(int x, [List<Function>])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(int y, {List<T> x})
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function([List<Function> x])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(List<T>) Function<B extends core.int>() x13;
+  late List<T> Function(int, [Function]) Function<B extends core.int>() x14;
+  late List<T> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x15;
+  late Function(Function x) Function<B extends core.int>() x16;
+  late Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+      x17;
+  late void Function([int]) Function<B extends core.int>() x18;
+  late void Function({List<Function> x}) Function<B extends core.int>() x19;
+  late void Function() Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(int x) Function<B extends core.int>()
+      x21;
+  late A Function<A>(Function x) Function<B extends core.int>() x22;
+  late Function(B x) Function<B extends core.int>() x23;
+
+  U30({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x0, [int x1 = -1]) => throw 'uncalled';
+  m3(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  List<T> m4<A>(A x) => throw 'uncalled';
+  int Function([Function]) m5<B extends core.int>() => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, {int x}) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [Function]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(Function x) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([int]) m18<B extends core.int>() => throw 'uncalled';
+  void Function({List<Function> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function() m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(Function x) m22<B extends core.int>() => throw 'uncalled';
+  Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(int x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U30().runTests();
+  new U30<int>(tIsInt: true).runTests();
+  new U30<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type31_test.dart b/tests/language/function_type/function_type31_test.dart
new file mode 100644
index 0000000..3426339
--- /dev/null
+++ b/tests/language/function_type/function_type31_test.dart
@@ -0,0 +1,997 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {List<Function> x});
+typedef F1<T> = List<Function> Function({Function x});
+typedef F2<T> = List<T> Function(int x, [int]);
+typedef F3<T> = Function(int x, [List<T>]);
+typedef F4<T> = List<T> Function<A>(List<A> x);
+typedef F5<T> = int Function([Function]) Function<B extends core.int>(int x);
+typedef F6<T> = int Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(List<T>)
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(Function x) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function([int]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function({List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function() Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(int x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(Function x) Function<B extends core.int>(int x);
+typedef F23<T> = Function(B x) Function<B extends core.int>(int x);
+
+int f0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f1({Function x = _voidFunction}) => throw 'uncalled';
+List<int> f2(int x, [int x0 = -1]) => throw 'uncalled';
+f3(int x, [List<int> x0 = const []]) => throw 'uncalled';
+List<int> f4<A>(List<A> x) => throw 'uncalled';
+int Function([Function]) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function({core.List<core.int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {int x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int) f9<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int>) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [Function]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function(Function x) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([int]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function({List<Function> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function() f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(Function x) f22<B extends core.int>(int x) => throw 'uncalled';
+Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U31<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {List<Function> x}) x0;
+  late List<Function> Function({Function x}) x1;
+  late List<T> Function(int x, [int]) x2;
+  late Function(int x, [List<T>]) x3;
+  late List<T> Function<A>(List<A> x) x4;
+  late int Function([Function]) Function<B extends core.int>(int x) x5;
+  late int Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+      x6;
+  late Function Function(int y, {int x}) Function<B extends core.int>(int x) x7;
+  late Function Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int x, [List<Function>])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function(int y, {List<T> x}) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([List<Function> x])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(List<T>) Function<B extends core.int>(int x)
+      x13;
+  late List<T> Function(int, [Function]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x15;
+  late Function(Function x) Function<B extends core.int>(int x) x16;
+  late Function(int y, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x17;
+  late void Function([int]) Function<B extends core.int>(int x) x18;
+  late void Function({List<Function> x}) Function<B extends core.int>(int x)
+      x19;
+  late void Function() Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(int x) Function<B extends core.int>(
+      int x) x21;
+  late A Function<A>(Function x) Function<B extends core.int>(int x) x22;
+  late Function(B x) Function<B extends core.int>(int x) x23;
+
+  U31({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m1({Function x = _voidFunction}) => throw 'uncalled';
+  List<T> m2(int x, [int x0 = -1]) => throw 'uncalled';
+  m3(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m4<A>(List<A> x) => throw 'uncalled';
+  int Function([Function]) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {int x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [Function]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function(Function x) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([int]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function({List<Function> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function() m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(Function x) m22<B extends core.int>(int x) => throw 'uncalled';
+  Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int x, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function<B extends core.int>(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U31().runTests();
+  new U31<int>(tIsInt: true).runTests();
+  new U31<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type32_test.dart b/tests/language/function_type/function_type32_test.dart
new file mode 100644
index 0000000..423bcd1
--- /dev/null
+++ b/tests/language/function_type/function_type32_test.dart
@@ -0,0 +1,872 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {List<Function> x});
+typedef F1<T> = List<Function> Function(int, {Function x});
+typedef F2<T> = List<T> Function({int x});
+typedef F3<T> = Function({List<T> x});
+typedef F4<T> = Function<A>(int x);
+typedef F5<T> = int Function(int, [Function]) Function();
+typedef F6<T> = int Function(int, {core.List<core.int> x}) Function();
+typedef F7<T> = Function Function(Function x) Function();
+typedef F8<T> = Function Function(int y, [core.List<core.int> x]) Function();
+typedef F9<T> = List<Function> Function([int]) Function();
+typedef F10<T> = List<Function> Function({List<Function> x}) Function();
+typedef F11<T> = List<Function> Function() Function();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x])
+    Function();
+typedef F13<T> = core.List<core.int> Function([List<T>]) Function();
+typedef F14<T> = List<T> Function(int x, [Function]) Function();
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x}) Function();
+typedef F16<T> = Function([Function x]) Function();
+typedef F17<T> = Function(core.List<core.int>) Function();
+typedef F18<T> = void Function(int, [int]) Function();
+typedef F19<T> = void Function(int, {List<Function> x}) Function();
+typedef F20<T> = int Function<A>(int x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(Function x) Function();
+typedef F22<T> = A Function<A>(List<Function> x) Function();
+typedef F23<T> = B Function(B x) Function<B extends core.int>();
+
+int f0(int y, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f1(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+List<int> f2({int x = -1}) => throw 'uncalled';
+f3({List<int> x = const []}) => throw 'uncalled';
+f4<A>(int x) => throw 'uncalled';
+int Function(int, [Function]) f5() => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6() => throw 'uncalled';
+Function Function(Function x) f7() => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8() => throw 'uncalled';
+List<Function> Function([int]) f9() => throw 'uncalled';
+List<Function> Function({List<Function> x}) f10() => throw 'uncalled';
+List<Function> Function() f11() => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x]) f12() => throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13() => throw 'uncalled';
+List<int> Function(int x, [Function]) f14() => throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15() => throw 'uncalled';
+Function([Function x]) f16() => throw 'uncalled';
+Function(core.List<core.int>) f17() => throw 'uncalled';
+void Function(int, [int]) f18() => throw 'uncalled';
+void Function(int, {List<Function> x}) f19() => throw 'uncalled';
+int Function<A>(int x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21() => throw 'uncalled';
+A Function<A>(List<Function> x) f22() => throw 'uncalled';
+B Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U32<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {List<Function> x}) x0;
+  late List<Function> Function(int, {Function x}) x1;
+  late List<T> Function({int x}) x2;
+  late Function({List<T> x}) x3;
+  late Function<A>(int x) x4;
+  late int Function(int, [Function]) Function() x5;
+  late int Function(int, {core.List<core.int> x}) Function() x6;
+  late Function Function(Function x) Function() x7;
+  late Function Function(int y, [core.List<core.int> x]) Function() x8;
+  late List<Function> Function([int]) Function() x9;
+  late List<Function> Function({List<Function> x}) Function() x10;
+  late List<Function> Function() Function() x11;
+  late core.List<core.int> Function(int, [List<Function> x]) Function() x12;
+  late core.List<core.int> Function([List<T>]) Function() x13;
+  late List<T> Function(int x, [Function]) Function() x14;
+  late List<T> Function(int y, {core.List<core.int> x}) Function() x15;
+  late Function([Function x]) Function() x16;
+  late Function(core.List<core.int>) Function() x17;
+  late void Function(int, [int]) Function() x18;
+  late void Function(int, {List<Function> x}) Function() x19;
+  late int Function<A>(int x) Function() x20;
+  late core.List<core.int> Function<A>(Function x) Function() x21;
+  late A Function<A>(List<Function> x) Function() x22;
+  late B Function(B x) Function<B extends core.int>() x23;
+
+  U32({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  List<T> m2({int x = -1}) => throw 'uncalled';
+  m3({List<T> x = const []}) => throw 'uncalled';
+  m4<A>(int x) => throw 'uncalled';
+  int Function(int, [Function]) m5() => throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6() => throw 'uncalled';
+  Function Function(Function x) m7() => throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8() => throw 'uncalled';
+  List<Function> Function([int]) m9() => throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10() => throw 'uncalled';
+  List<Function> Function() m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x]) m12() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13() => throw 'uncalled';
+  List<T> Function(int x, [Function]) m14() => throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15() => throw 'uncalled';
+  Function([Function x]) m16() => throw 'uncalled';
+  Function(core.List<core.int>) m17() => throw 'uncalled';
+  void Function(int, [int]) m18() => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19() => throw 'uncalled';
+  int Function<A>(int x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21() => throw 'uncalled';
+  A Function<A>(List<Function> x) m22() => throw 'uncalled';
+  B Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function({List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function({List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function x) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function() Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T>]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(int x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U32().runTests();
+  new U32<int>(tIsInt: true).runTests();
+  new U32<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type33_test.dart b/tests/language/function_type/function_type33_test.dart
new file mode 100644
index 0000000..e7c166b
--- /dev/null
+++ b/tests/language/function_type/function_type33_test.dart
@@ -0,0 +1,882 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(core.List<core.int> x);
+typedef F1<T> = List<Function> Function(int y, {Function x});
+typedef F2<T> = List<T> Function(int, {int x});
+typedef F3<T> = Function(int, {List<T> x});
+typedef F4<T> = Function<A>(Function x);
+typedef F5<T> = int Function(int, [Function]) Function(int x);
+typedef F6<T> = int Function(int, {core.List<core.int> x}) Function(int x);
+typedef F7<T> = Function Function(Function x) Function(int x);
+typedef F8<T> = Function Function(int y, [core.List<core.int> x]) Function(
+    int x);
+typedef F9<T> = List<Function> Function([int]) Function(int x);
+typedef F10<T> = List<Function> Function({List<Function> x}) Function(int x);
+typedef F11<T> = List<Function> Function() Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function([List<T>]) Function(int x);
+typedef F14<T> = List<T> Function(int x, [Function]) Function(int x);
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x}) Function(
+    int x);
+typedef F16<T> = Function([Function x]) Function(int x);
+typedef F17<T> = Function(core.List<core.int>) Function(int x);
+typedef F18<T> = void Function(int, [int]) Function(int x);
+typedef F19<T> = void Function(int, {List<Function> x}) Function(int x);
+typedef F20<T> = int Function<A>(int x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(Function x) Function(int x);
+typedef F22<T> = A Function<A>(List<Function> x) Function(int x);
+typedef F23<T> = B Function(B x) Function<B extends core.int>(int x);
+
+int f0(core.List<core.int> x) => throw 'uncalled';
+List<Function> f1(int y, {Function x = _voidFunction}) => throw 'uncalled';
+List<int> f2(int x0, {int x = -1}) => throw 'uncalled';
+f3(int x0, {List<int> x = const []}) => throw 'uncalled';
+f4<A>(Function x) => throw 'uncalled';
+int Function(int, [Function]) f5(int x) => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6(int x) => throw 'uncalled';
+Function Function(Function x) f7(int x) => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function([int]) f9(int x) => throw 'uncalled';
+List<Function> Function({List<Function> x}) f10(int x) => throw 'uncalled';
+List<Function> Function() f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13(int x) => throw 'uncalled';
+List<int> Function(int x, [Function]) f14(int x) => throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15(int x) =>
+    throw 'uncalled';
+Function([Function x]) f16(int x) => throw 'uncalled';
+Function(core.List<core.int>) f17(int x) => throw 'uncalled';
+void Function(int, [int]) f18(int x) => throw 'uncalled';
+void Function(int, {List<Function> x}) f19(int x) => throw 'uncalled';
+int Function<A>(int x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21(int x) => throw 'uncalled';
+A Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+B Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U33<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(core.List<core.int> x) x0;
+  late List<Function> Function(int y, {Function x}) x1;
+  late List<T> Function(int, {int x}) x2;
+  late Function(int, {List<T> x}) x3;
+  late Function<A>(Function x) x4;
+  late int Function(int, [Function]) Function(int x) x5;
+  late int Function(int, {core.List<core.int> x}) Function(int x) x6;
+  late Function Function(Function x) Function(int x) x7;
+  late Function Function(int y, [core.List<core.int> x]) Function(int x) x8;
+  late List<Function> Function([int]) Function(int x) x9;
+  late List<Function> Function({List<Function> x}) Function(int x) x10;
+  late List<Function> Function() Function(int x) x11;
+  late core.List<core.int> Function(int, [List<Function> x]) Function(int x)
+      x12;
+  late core.List<core.int> Function([List<T>]) Function(int x) x13;
+  late List<T> Function(int x, [Function]) Function(int x) x14;
+  late List<T> Function(int y, {core.List<core.int> x}) Function(int x) x15;
+  late Function([Function x]) Function(int x) x16;
+  late Function(core.List<core.int>) Function(int x) x17;
+  late void Function(int, [int]) Function(int x) x18;
+  late void Function(int, {List<Function> x}) Function(int x) x19;
+  late int Function<A>(int x) Function(int x) x20;
+  late core.List<core.int> Function<A>(Function x) Function(int x) x21;
+  late A Function<A>(List<Function> x) Function(int x) x22;
+  late B Function(B x) Function<B extends core.int>(int x) x23;
+
+  U33({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(core.List<core.int> x) => throw 'uncalled';
+  List<Function> m1(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  List<T> m2(int x0, {int x = -1}) => throw 'uncalled';
+  m3(int x0, {List<T> x = const []}) => throw 'uncalled';
+  m4<A>(Function x) => throw 'uncalled';
+  int Function(int, [Function]) m5(int x) => throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6(int x) => throw 'uncalled';
+  Function Function(Function x) m7(int x) => throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8(int x) =>
+      throw 'uncalled';
+  List<Function> Function([int]) m9(int x) => throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10(int x) => throw 'uncalled';
+  List<Function> Function() m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13(int x) => throw 'uncalled';
+  List<T> Function(int x, [Function]) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15(int x) =>
+      throw 'uncalled';
+  Function([Function x]) m16(int x) => throw 'uncalled';
+  Function(core.List<core.int>) m17(int x) => throw 'uncalled';
+  void Function(int, [int]) m18(int x) => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19(int x) => throw 'uncalled';
+  int Function<A>(int x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21(int x) => throw 'uncalled';
+  A Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+  B Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(core.List<core.int> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function() Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U33().runTests();
+  new U33<int>(tIsInt: true).runTests();
+  new U33<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type34_test.dart b/tests/language/function_type/function_type34_test.dart
new file mode 100644
index 0000000..e3643a3
--- /dev/null
+++ b/tests/language/function_type/function_type34_test.dart
@@ -0,0 +1,922 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([core.List<core.int> x]);
+typedef F1<T> = List<Function> Function(List<Function> x);
+typedef F2<T> = List<T> Function(int y, {int x});
+typedef F3<T> = Function(int y, {List<T> x});
+typedef F4<T> = Function<A>(List<Function> x);
+typedef F5<T> = int Function(int, [Function]) Function<B extends core.int>();
+typedef F6<T> = int Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(Function x) Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([int]) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function() Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function([List<T>])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function([Function x]) Function<B extends core.int>();
+typedef F17<T> = Function(core.List<core.int>) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [int]) Function<B extends core.int>();
+typedef F19<T> = void Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(int x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(Function x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(List<Function> x) Function<B extends core.int>();
+typedef F23<T> = List<B> Function(B x) Function<B extends core.int>();
+
+int f0([core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f1(List<Function> x) => throw 'uncalled';
+List<int> f2(int y, {int x = -1}) => throw 'uncalled';
+f3(int y, {List<int> x = const []}) => throw 'uncalled';
+f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int, [Function]) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(Function x) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([int]) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function({List<Function> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function() f11<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x])
+    f12<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int x, [Function]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([Function x]) f16<B extends core.int>() => throw 'uncalled';
+Function(core.List<core.int>) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [int]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, {List<Function> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(int x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(List<Function> x) f22<B extends core.int>() => throw 'uncalled';
+List<B> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U34<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([core.List<core.int> x]) x0;
+  late List<Function> Function(List<Function> x) x1;
+  late List<T> Function(int y, {int x}) x2;
+  late Function(int y, {List<T> x}) x3;
+  late Function<A>(List<Function> x) x4;
+  late int Function(int, [Function]) Function<B extends core.int>() x5;
+  late int Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+      x6;
+  late Function Function(Function x) Function<B extends core.int>() x7;
+  late Function Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x8;
+  late List<Function> Function([int]) Function<B extends core.int>() x9;
+  late List<Function> Function({List<Function> x})
+      Function<B extends core.int>() x10;
+  late List<Function> Function() Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [List<Function> x])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function([List<T>]) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int x, [Function]) Function<B extends core.int>() x14;
+  late List<T> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x15;
+  late Function([Function x]) Function<B extends core.int>() x16;
+  late Function(core.List<core.int>) Function<B extends core.int>() x17;
+  late void Function(int, [int]) Function<B extends core.int>() x18;
+  late void Function(int, {List<Function> x}) Function<B extends core.int>()
+      x19;
+  late int Function<A>(int x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(Function x)
+      Function<B extends core.int>() x21;
+  late A Function<A>(List<Function> x) Function<B extends core.int>() x22;
+  late List<B> Function(B x) Function<B extends core.int>() x23;
+
+  U34({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m1(List<Function> x) => throw 'uncalled';
+  List<T> m2(int y, {int x = -1}) => throw 'uncalled';
+  m3(int y, {List<T> x = const []}) => throw 'uncalled';
+  m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int, [Function]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(Function x) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([int]) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function() m11<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int x, [Function]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([Function x]) m16<B extends core.int>() => throw 'uncalled';
+  Function(core.List<core.int>) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [int]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(int x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(List<Function> x) m22<B extends core.int>() => throw 'uncalled';
+  List<B> Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<Function> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<Function> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(core.List<core.int>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<B> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<B> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is List<B> Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U34().runTests();
+  new U34<int>(tIsInt: true).runTests();
+  new U34<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type35_test.dart b/tests/language/function_type/function_type35_test.dart
new file mode 100644
index 0000000..313cf3d
--- /dev/null
+++ b/tests/language/function_type/function_type35_test.dart
@@ -0,0 +1,922 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [core.List<core.int> x]);
+typedef F1<T> = List<Function> Function([List<Function> x]);
+typedef F2<T> = List<T> Function(Function x);
+typedef F3<T> = Function();
+typedef F4<T> = Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(Function x) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([int]) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function() Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function([List<T>])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([Function x]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(core.List<core.int>) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int, [int]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(int x) Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(Function x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F23<T> = List<B> Function(B x) Function<B extends core.int>(int x);
+
+int f0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f1([List<Function> x = const []]) => throw 'uncalled';
+List<int> f2(Function x) => throw 'uncalled';
+f3() => throw 'uncalled';
+f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int, [Function]) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(Function x) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function([int]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({List<Function> x}) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function() f11<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [Function]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function([Function x]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(core.List<core.int>) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [int]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, {List<Function> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(int x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<B> Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U35<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [core.List<core.int> x]) x0;
+  late List<Function> Function([List<Function> x]) x1;
+  late List<T> Function(Function x) x2;
+  late Function() x3;
+  late Function<A>(core.List<core.int> x) x4;
+  late int Function(int, [Function]) Function<B extends core.int>(int x) x5;
+  late int Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x6;
+  late Function Function(Function x) Function<B extends core.int>(int x) x7;
+  late Function Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function([int]) Function<B extends core.int>(int x) x9;
+  late List<Function> Function({List<Function> x}) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function() Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [List<Function> x])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function([List<T>]) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int x, [Function]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x15;
+  late Function([Function x]) Function<B extends core.int>(int x) x16;
+  late Function(core.List<core.int>) Function<B extends core.int>(int x) x17;
+  late void Function(int, [int]) Function<B extends core.int>(int x) x18;
+  late void Function(int, {List<Function> x}) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(int x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(Function x) Function<B extends core.int>(
+      int x) x21;
+  late A Function<A>(List<Function> x) Function<B extends core.int>(int x) x22;
+  late List<B> Function(B x) Function<B extends core.int>(int x) x23;
+
+  U35({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m1([List<Function> x = const []]) => throw 'uncalled';
+  List<T> m2(Function x) => throw 'uncalled';
+  m3() => throw 'uncalled';
+  m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int, [Function]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(Function x) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function([int]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function() m11<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [Function]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function([Function x]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(core.List<core.int>) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [int]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(int x) m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<B> Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(Function x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(Function x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function()
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function() l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function());
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function<B extends core.int>(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<B> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<B> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is List<B> Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U35().runTests();
+  new U35<int>(tIsInt: true).runTests();
+  new U35<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type36_test.dart b/tests/language/function_type/function_type36_test.dart
new file mode 100644
index 0000000..ff2124d
--- /dev/null
+++ b/tests/language/function_type/function_type36_test.dart
@@ -0,0 +1,873 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [core.List<core.int> x]);
+typedef F1<T> = List<Function> Function(int, [List<Function> x]);
+typedef F2<T> = List<T> Function([Function x]);
+typedef F3<T> = void Function(int x);
+typedef F4<T> = Function<A>(List<T> x);
+typedef F5<T> = int Function(int x, [Function]) Function();
+typedef F6<T> = int Function(int y, {core.List<core.int> x}) Function();
+typedef F7<T> = Function Function([Function x]) Function();
+typedef F8<T> = Function Function(core.List<core.int>) Function();
+typedef F9<T> = List<Function> Function(int, [int]) Function();
+typedef F10<T> = List<Function> Function(int, {List<Function> x}) Function();
+typedef F11<T> = core.List<core.int> Function(int x) Function();
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function();
+typedef F13<T> = core.List<core.int> Function(int, [List<T>]) Function();
+typedef F14<T> = List<T> Function({Function x}) Function();
+typedef F15<T> = List<T> Function(List<T> x) Function();
+typedef F16<T> = Function(int, [Function x]) Function();
+typedef F17<T> = Function([core.List<core.int>]) Function();
+typedef F18<T> = void Function(int x, [int]) Function();
+typedef F19<T> = void Function(int y, {List<Function> x}) Function();
+typedef F20<T> = int Function<A>(Function x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x) Function();
+typedef F22<T> = A Function<A>(core.List<core.int> x) Function();
+typedef F23<T> = void Function(B x) Function<B extends core.int>();
+
+int f0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [List<Function> x = const []]) => throw 'uncalled';
+List<int> f2([Function x = _voidFunction]) => throw 'uncalled';
+void f3(int x) => throw 'uncalled';
+f4<A>(List<int> x) => throw 'uncalled';
+int Function(int x, [Function]) f5() => throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6() => throw 'uncalled';
+Function Function([Function x]) f7() => throw 'uncalled';
+Function Function(core.List<core.int>) f8() => throw 'uncalled';
+List<Function> Function(int, [int]) f9() => throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10() => throw 'uncalled';
+core.List<core.int> Function(int x) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x]) f12() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13() => throw 'uncalled';
+List<int> Function({Function x}) f14() => throw 'uncalled';
+List<int> Function(List<int> x) f15() => throw 'uncalled';
+Function(int, [Function x]) f16() => throw 'uncalled';
+Function([core.List<core.int>]) f17() => throw 'uncalled';
+void Function(int x, [int]) f18() => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19() => throw 'uncalled';
+int Function<A>(Function x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21() => throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22() => throw 'uncalled';
+void Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U36<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [core.List<core.int> x]) x0;
+  late List<Function> Function(int, [List<Function> x]) x1;
+  late List<T> Function([Function x]) x2;
+  late void Function(int x) x3;
+  late Function<A>(List<T> x) x4;
+  late int Function(int x, [Function]) Function() x5;
+  late int Function(int y, {core.List<core.int> x}) Function() x6;
+  late Function Function([Function x]) Function() x7;
+  late Function Function(core.List<core.int>) Function() x8;
+  late List<Function> Function(int, [int]) Function() x9;
+  late List<Function> Function(int, {List<Function> x}) Function() x10;
+  late core.List<core.int> Function(int x) Function() x11;
+  late core.List<core.int> Function(int y, [List<Function> x]) Function() x12;
+  late core.List<core.int> Function(int, [List<T>]) Function() x13;
+  late List<T> Function({Function x}) Function() x14;
+  late List<T> Function(List<T> x) Function() x15;
+  late Function(int, [Function x]) Function() x16;
+  late Function([core.List<core.int>]) Function() x17;
+  late void Function(int x, [int]) Function() x18;
+  late void Function(int y, {List<Function> x}) Function() x19;
+  late int Function<A>(Function x) Function() x20;
+  late core.List<core.int> Function<A>(List<Function> x) Function() x21;
+  late A Function<A>(core.List<core.int> x) Function() x22;
+  late void Function(B x) Function<B extends core.int>() x23;
+
+  U36({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  List<T> m2([Function x = _voidFunction]) => throw 'uncalled';
+  void m3(int x) => throw 'uncalled';
+  m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int x, [Function]) m5() => throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6() => throw 'uncalled';
+  Function Function([Function x]) m7() => throw 'uncalled';
+  Function Function(core.List<core.int>) m8() => throw 'uncalled';
+  List<Function> Function(int, [int]) m9() => throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10() => throw 'uncalled';
+  core.List<core.int> Function(int x) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x]) m12() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13() => throw 'uncalled';
+  List<T> Function({Function x}) m14() => throw 'uncalled';
+  List<T> Function(List<T> x) m15() => throw 'uncalled';
+  Function(int, [Function x]) m16() => throw 'uncalled';
+  Function([core.List<core.int>]) m17() => throw 'uncalled';
+  void Function(int x, [int]) m18() => throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19() => throw 'uncalled';
+  int Function<A>(Function x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21() => throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22() => throw 'uncalled';
+  void Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int x, [Function]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({Function x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T> x) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U36().runTests();
+  new U36<int>(tIsInt: true).runTests();
+  new U36<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type37_test.dart b/tests/language/function_type/function_type37_test.dart
new file mode 100644
index 0000000..343bdca
--- /dev/null
+++ b/tests/language/function_type/function_type37_test.dart
@@ -0,0 +1,856 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(core.List<core.int>);
+typedef F1<T> = List<Function> Function(int y, [List<Function> x]);
+typedef F2<T> = List<T> Function(int, [Function x]);
+typedef F3<T> = void Function([int x]);
+typedef F4<T> = Function<A>();
+typedef F5<T> = int Function(int x, [Function]) Function(int x);
+typedef F6<T> = int Function(int y, {core.List<core.int> x}) Function(int x);
+typedef F7<T> = Function Function([Function x]) Function(int x);
+typedef F8<T> = Function Function(core.List<core.int>) Function(int x);
+typedef F9<T> = List<Function> Function(int, [int]) Function(int x);
+typedef F10<T> = List<Function> Function(int, {List<Function> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int x) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function(int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T>]) Function(int x);
+typedef F14<T> = List<T> Function({Function x}) Function(int x);
+typedef F15<T> = List<T> Function(List<T> x) Function(int x);
+typedef F16<T> = Function(int, [Function x]) Function(int x);
+typedef F17<T> = Function([core.List<core.int>]) Function(int x);
+typedef F18<T> = void Function(int x, [int]) Function(int x);
+typedef F19<T> = void Function(int y, {List<Function> x}) Function(int x);
+typedef F20<T> = int Function<A>(Function x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x) Function(
+    int x);
+typedef F22<T> = A Function<A>(core.List<core.int> x) Function(int x);
+typedef F23<T> = void Function(B x) Function<B extends core.int>(int x);
+
+int f0(core.List<core.int> x0) => throw 'uncalled';
+List<Function> f1(int y, [List<Function> x = const []]) => throw 'uncalled';
+List<int> f2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+void f3([int x = -1]) => throw 'uncalled';
+f4<A>() => throw 'uncalled';
+int Function(int x, [Function]) f5(int x) => throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6(int x) => throw 'uncalled';
+Function Function([Function x]) f7(int x) => throw 'uncalled';
+Function Function(core.List<core.int>) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [int]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int x) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13(int x) => throw 'uncalled';
+List<int> Function({Function x}) f14(int x) => throw 'uncalled';
+List<int> Function(List<int> x) f15(int x) => throw 'uncalled';
+Function(int, [Function x]) f16(int x) => throw 'uncalled';
+Function([core.List<core.int>]) f17(int x) => throw 'uncalled';
+void Function(int x, [int]) f18(int x) => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19(int x) => throw 'uncalled';
+int Function<A>(Function x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21(int x) =>
+    throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22(int x) => throw 'uncalled';
+void Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U37<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(core.List<core.int>) x0;
+  late List<Function> Function(int y, [List<Function> x]) x1;
+  late List<T> Function(int, [Function x]) x2;
+  late void Function([int x]) x3;
+  late Function<A>() x4;
+  late int Function(int x, [Function]) Function(int x) x5;
+  late int Function(int y, {core.List<core.int> x}) Function(int x) x6;
+  late Function Function([Function x]) Function(int x) x7;
+  late Function Function(core.List<core.int>) Function(int x) x8;
+  late List<Function> Function(int, [int]) Function(int x) x9;
+  late List<Function> Function(int, {List<Function> x}) Function(int x) x10;
+  late core.List<core.int> Function(int x) Function(int x) x11;
+  late core.List<core.int> Function(int y, [List<Function> x]) Function(int x)
+      x12;
+  late core.List<core.int> Function(int, [List<T>]) Function(int x) x13;
+  late List<T> Function({Function x}) Function(int x) x14;
+  late List<T> Function(List<T> x) Function(int x) x15;
+  late Function(int, [Function x]) Function(int x) x16;
+  late Function([core.List<core.int>]) Function(int x) x17;
+  late void Function(int x, [int]) Function(int x) x18;
+  late void Function(int y, {List<Function> x}) Function(int x) x19;
+  late int Function<A>(Function x) Function(int x) x20;
+  late core.List<core.int> Function<A>(List<Function> x) Function(int x) x21;
+  late A Function<A>(core.List<core.int> x) Function(int x) x22;
+  late void Function(B x) Function<B extends core.int>(int x) x23;
+
+  U37({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(core.List<core.int> x0) => throw 'uncalled';
+  List<Function> m1(int y, [List<Function> x = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  void m3([int x = -1]) => throw 'uncalled';
+  m4<A>() => throw 'uncalled';
+  int Function(int x, [Function]) m5(int x) => throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6(int x) => throw 'uncalled';
+  Function Function([Function x]) m7(int x) => throw 'uncalled';
+  Function Function(core.List<core.int>) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [int]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13(int x) => throw 'uncalled';
+  List<T> Function({Function x}) m14(int x) => throw 'uncalled';
+  List<T> Function(List<T> x) m15(int x) => throw 'uncalled';
+  Function(int, [Function x]) m16(int x) => throw 'uncalled';
+  Function([core.List<core.int>]) m17(int x) => throw 'uncalled';
+  void Function(int x, [int]) m18(int x) => throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19(int x) => throw 'uncalled';
+  int Function<A>(Function x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21(int x) =>
+      throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22(int x) => throw 'uncalled';
+  void Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(core.List<core.int>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(core.List<core.int>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([int x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([int x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [Function]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<Function> x)
+        Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U37().runTests();
+  new U37<int>(tIsInt: true).runTests();
+  new U37<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type38_test.dart b/tests/language/function_type/function_type38_test.dart
new file mode 100644
index 0000000..e6a102d
--- /dev/null
+++ b/tests/language/function_type/function_type38_test.dart
@@ -0,0 +1,899 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([core.List<core.int>]);
+typedef F1<T> = List<Function> Function(List<Function>);
+typedef F2<T> = List<T> Function(int y, [Function x]);
+typedef F3<T> = void Function(int, [int x]);
+typedef F4<T> = Function<A>(A x);
+typedef F5<T> = int Function(int x, [Function]) Function<B extends core.int>();
+typedef F6<T> = int Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F7<T> = Function Function([Function x]) Function<B extends core.int>();
+typedef F8<T> = Function Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [int])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int x)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function({Function x}) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(List<T> x) Function<B extends core.int>();
+typedef F16<T> = Function(int, [Function x]) Function<B extends core.int>();
+typedef F17<T> = Function([core.List<core.int>]) Function<B extends core.int>();
+typedef F18<T> = void Function(int x, [int]) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(Function x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F23<T> = B Function(int x) Function<B extends core.int>();
+
+int f0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(List<Function> x0) => throw 'uncalled';
+List<int> f2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+void f3(int x0, [int x = -1]) => throw 'uncalled';
+f4<A>(A x) => throw 'uncalled';
+int Function(int x, [Function]) f5<B extends core.int>() => throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([Function x]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(core.List<core.int>) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [int]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x])
+    f12<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function({Function x}) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(List<int> x) f15<B extends core.int>() => throw 'uncalled';
+Function(int, [Function x]) f16<B extends core.int>() => throw 'uncalled';
+Function([core.List<core.int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int x, [int]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(Function x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+B Function(int x) f23<B extends core.int>() => throw 'uncalled';
+
+class U38<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([core.List<core.int>]) x0;
+  late List<Function> Function(List<Function>) x1;
+  late List<T> Function(int y, [Function x]) x2;
+  late void Function(int, [int x]) x3;
+  late Function<A>(A x) x4;
+  late int Function(int x, [Function]) Function<B extends core.int>() x5;
+  late int Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x6;
+  late Function Function([Function x]) Function<B extends core.int>() x7;
+  late Function Function(core.List<core.int>) Function<B extends core.int>() x8;
+  late List<Function> Function(int, [int]) Function<B extends core.int>() x9;
+  late List<Function> Function(int, {List<Function> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int x) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int y, [List<Function> x])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, [List<T>])
+      Function<B extends core.int>() x13;
+  late List<T> Function({Function x}) Function<B extends core.int>() x14;
+  late List<T> Function(List<T> x) Function<B extends core.int>() x15;
+  late Function(int, [Function x]) Function<B extends core.int>() x16;
+  late Function([core.List<core.int>]) Function<B extends core.int>() x17;
+  late void Function(int x, [int]) Function<B extends core.int>() x18;
+  late void Function(int y, {List<Function> x}) Function<B extends core.int>()
+      x19;
+  late int Function<A>(Function x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(List<Function> x)
+      Function<B extends core.int>() x21;
+  late A Function<A>(core.List<core.int> x) Function<B extends core.int>() x22;
+  late B Function(int x) Function<B extends core.int>() x23;
+
+  U38({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(List<Function> x0) => throw 'uncalled';
+  List<T> m2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  void m3(int x0, [int x = -1]) => throw 'uncalled';
+  m4<A>(A x) => throw 'uncalled';
+  int Function(int x, [Function]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([Function x]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(core.List<core.int>) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [int]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function({Function x}) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(List<T> x) m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [Function x]) m16<B extends core.int>() => throw 'uncalled';
+  Function([core.List<core.int>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [int]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(Function x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+  B Function(int x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<Function>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<Function>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [int x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [int x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [Function]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int x, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>()
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function([core.List<core.int>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(int x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(int x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U38().runTests();
+  new U38<int>(tIsInt: true).runTests();
+  new U38<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type39_test.dart b/tests/language/function_type/function_type39_test.dart
new file mode 100644
index 0000000..fefb0cf
--- /dev/null
+++ b/tests/language/function_type/function_type39_test.dart
@@ -0,0 +1,932 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [core.List<core.int>]);
+typedef F1<T> = List<Function> Function([List<Function>]);
+typedef F2<T> = List<T> Function(Function);
+typedef F3<T> = void Function(int y, [int x]);
+typedef F4<T> = Function<A>(List<A> x);
+typedef F5<T> = int Function(int x, [Function]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function([Function x]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, [int])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int x)
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function({Function x}) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function([core.List<core.int>]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int x, [int]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(Function x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F23<T> = B Function(int x) Function<B extends core.int>(int x);
+
+int f0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+List<Function> f1([List<Function> x0 = const []]) => throw 'uncalled';
+List<int> f2(Function x0) => throw 'uncalled';
+void f3(int y, [int x = -1]) => throw 'uncalled';
+f4<A>(List<A> x) => throw 'uncalled';
+int Function(int x, [Function]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([Function x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(core.List<core.int>) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [int]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function({Function x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(List<int> x) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [Function x]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function([core.List<core.int>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int x, [int]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(Function x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+B Function(int x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U39<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [core.List<core.int>]) x0;
+  late List<Function> Function([List<Function>]) x1;
+  late List<T> Function(Function) x2;
+  late void Function(int y, [int x]) x3;
+  late Function<A>(List<A> x) x4;
+  late int Function(int x, [Function]) Function<B extends core.int>(int x) x5;
+  late int Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x6;
+  late Function Function([Function x]) Function<B extends core.int>(int x) x7;
+  late Function Function(core.List<core.int>) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int, [int]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(int, {List<Function> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int x) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int y, [List<Function> x])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, [List<T>])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function({Function x}) Function<B extends core.int>(int x) x14;
+  late List<T> Function(List<T> x) Function<B extends core.int>(int x) x15;
+  late Function(int, [Function x]) Function<B extends core.int>(int x) x16;
+  late Function([core.List<core.int>]) Function<B extends core.int>(int x) x17;
+  late void Function(int x, [int]) Function<B extends core.int>(int x) x18;
+  late void Function(int y, {List<Function> x}) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(Function x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(List<Function> x)
+      Function<B extends core.int>(int x) x21;
+  late A Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+      x22;
+  late B Function(int x) Function<B extends core.int>(int x) x23;
+
+  U39({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  List<Function> m1([List<Function> x0 = const []]) => throw 'uncalled';
+  List<T> m2(Function x0) => throw 'uncalled';
+  void m3(int y, [int x = -1]) => throw 'uncalled';
+  m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int x, [Function]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([Function x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(core.List<core.int>) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [int]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function({Function x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(List<T> x) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [Function x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([core.List<core.int>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int x, [int]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(Function x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  B Function(int x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(Function)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(Function));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [int x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [int x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+        l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(int x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(int x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U39().runTests();
+  new U39<int>(tIsInt: true).runTests();
+  new U39<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type3_test.dart b/tests/language/function_type/function_type3_test.dart
new file mode 100644
index 0000000..23c5873
--- /dev/null
+++ b/tests/language/function_type/function_type3_test.dart
@@ -0,0 +1,1009 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [int x]);
+typedef F1<T> = Function Function(int y, [List<T> x]);
+typedef F2<T> = core.List<core.int> Function(int, [core.List<core.int> x]);
+typedef F3<T> = Function([List<Function> x]);
+typedef F4<T> = Function Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int, {int x}) Function<B extends core.int>(int x);
+typedef F6<T> = int Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = Function Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([Function])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int x, [List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = Function(int y, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function(List<T>) Function<B extends core.int>(int x);
+typedef F21<T> = List<Function> Function<A>(Function x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F23<T> = void Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+
+int f0(int y, [int x = -1]) => throw 'uncalled';
+Function f1(int y, [List<int> x = const []]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+f3([List<Function> x = const []]) => throw 'uncalled';
+Function f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int, {int x}) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function([core.List<core.int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, [int x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [List<Function>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {List<int> x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<Function> x) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([Function]) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x}) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {int x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function(int) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int x, [List<Function>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, {List<int> x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([List<Function> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(List<int>) f20<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function<A>(Function x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U3<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [int x]) x0;
+  late Function Function(int y, [List<T> x]) x1;
+  late core.List<core.int> Function(int, [core.List<core.int> x]) x2;
+  late Function([List<Function> x]) x3;
+  late Function Function<A>(core.List<core.int> x) x4;
+  late int Function(int, {int x}) Function<B extends core.int>(int x) x5;
+  late int Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+      x6;
+  late Function Function(int y, [int x]) Function<B extends core.int>(int x) x7;
+  late Function Function(int, [List<Function>]) Function<B extends core.int>(
+      int x) x8;
+  late Function Function(int, {List<T> x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(List<Function> x) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function(int y, [List<T> x]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([Function]) Function<B extends core.int>(
+      int x) x12;
+  late core.List<core.int> Function({core.List<core.int> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(int y, {int x}) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x15;
+  late Function(int) Function<B extends core.int>(int x) x16;
+  late Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+      x17;
+  late Function(int y, {List<T> x}) Function<B extends core.int>(int x) x18;
+  late void Function([List<Function> x]) Function<B extends core.int>(int x)
+      x19;
+  late void Function(List<T>) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(Function x) Function<B extends core.int>(
+      int x) x21;
+  late Function<A>(List<Function> x) Function<B extends core.int>(int x) x22;
+  late void Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x23;
+
+  U3({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [int x = -1]) => throw 'uncalled';
+  Function m1(int y, [List<T> x = const []]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  m3([List<Function> x = const []]) => throw 'uncalled';
+  Function m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int, {int x}) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, [int x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [List<Function>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {List<T> x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<Function> x) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function]) m12<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x}) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {int x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function(int) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int x, [List<Function>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {List<T> x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<Function> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(List<T>) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int y, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function([List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function<B extends core.int>(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+        l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U3().runTests();
+  new U3<int>(tIsInt: true).runTests();
+  new U3<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type40_test.dart b/tests/language/function_type/function_type40_test.dart
new file mode 100644
index 0000000..860dbec
--- /dev/null
+++ b/tests/language/function_type/function_type40_test.dart
@@ -0,0 +1,897 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [core.List<core.int>]);
+typedef F1<T> = List<Function> Function(int, [List<Function>]);
+typedef F2<T> = List<T> Function([Function]);
+typedef F3<T> = void Function(int);
+typedef F4<T> = A Function<A>(int x);
+typedef F5<T> = int Function({Function x}) Function();
+typedef F6<T> = int Function(List<T> x) Function();
+typedef F7<T> = Function Function(int, [Function x]) Function();
+typedef F8<T> = Function Function([core.List<core.int>]) Function();
+typedef F9<T> = List<Function> Function(int x, [int]) Function();
+typedef F10<T> = List<Function> Function(int y, {List<Function> x}) Function();
+typedef F11<T> = core.List<core.int> Function([int x]) Function();
+typedef F12<T> = core.List<core.int> Function(List<Function>) Function();
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>]) Function();
+typedef F14<T> = List<T> Function(int, {Function x}) Function();
+typedef F15<T> = List<T> Function([List<T> x]) Function();
+typedef F16<T> = Function(int y, [Function x]) Function();
+typedef F17<T> = Function(int, [core.List<core.int>]) Function();
+typedef F18<T> = void Function({int x}) Function();
+typedef F19<T> = void Function(core.List<core.int> x) Function();
+typedef F20<T> = int Function<A>(List<Function> x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function();
+typedef F22<T> = A Function<A>(List<T> x) Function();
+typedef F23<T> = B Function(Function x) Function<B extends core.int>();
+
+int f0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+List<int> f2([Function x0 = _voidFunction]) => throw 'uncalled';
+void f3(int x0) => throw 'uncalled';
+A f4<A>(int x) => throw 'uncalled';
+int Function({Function x}) f5() => throw 'uncalled';
+int Function(List<int> x) f6() => throw 'uncalled';
+Function Function(int, [Function x]) f7() => throw 'uncalled';
+Function Function([core.List<core.int>]) f8() => throw 'uncalled';
+List<Function> Function(int x, [int]) f9() => throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10() => throw 'uncalled';
+core.List<core.int> Function([int x]) f11() => throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12() => throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13() => throw 'uncalled';
+List<int> Function(int, {Function x}) f14() => throw 'uncalled';
+List<int> Function([List<int> x]) f15() => throw 'uncalled';
+Function(int y, [Function x]) f16() => throw 'uncalled';
+Function(int, [core.List<core.int>]) f17() => throw 'uncalled';
+void Function({int x}) f18() => throw 'uncalled';
+void Function(core.List<core.int> x) f19() => throw 'uncalled';
+int Function<A>(List<Function> x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x) f21() =>
+    throw 'uncalled';
+A Function<A>(List<int> x) f22() => throw 'uncalled';
+B Function(Function x) f23<B extends core.int>() => throw 'uncalled';
+
+class U40<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [core.List<core.int>]) x0;
+  late List<Function> Function(int, [List<Function>]) x1;
+  late List<T> Function([Function]) x2;
+  late void Function(int) x3;
+  late A Function<A>(int x) x4;
+  late int Function({Function x}) Function() x5;
+  late int Function(List<T> x) Function() x6;
+  late Function Function(int, [Function x]) Function() x7;
+  late Function Function([core.List<core.int>]) Function() x8;
+  late List<Function> Function(int x, [int]) Function() x9;
+  late List<Function> Function(int y, {List<Function> x}) Function() x10;
+  late core.List<core.int> Function([int x]) Function() x11;
+  late core.List<core.int> Function(List<Function>) Function() x12;
+  late core.List<core.int> Function(int x, [List<T>]) Function() x13;
+  late List<T> Function(int, {Function x}) Function() x14;
+  late List<T> Function([List<T> x]) Function() x15;
+  late Function(int y, [Function x]) Function() x16;
+  late Function(int, [core.List<core.int>]) Function() x17;
+  late void Function({int x}) Function() x18;
+  late void Function(core.List<core.int> x) Function() x19;
+  late int Function<A>(List<Function> x) Function() x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x) Function() x21;
+  late A Function<A>(List<T> x) Function() x22;
+  late B Function(Function x) Function<B extends core.int>() x23;
+
+  U40({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  List<T> m2([Function x0 = _voidFunction]) => throw 'uncalled';
+  void m3(int x0) => throw 'uncalled';
+  A m4<A>(int x) => throw 'uncalled';
+  int Function({Function x}) m5() => throw 'uncalled';
+  int Function(List<T> x) m6() => throw 'uncalled';
+  Function Function(int, [Function x]) m7() => throw 'uncalled';
+  Function Function([core.List<core.int>]) m8() => throw 'uncalled';
+  List<Function> Function(int x, [int]) m9() => throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x}) m10() => throw 'uncalled';
+  core.List<core.int> Function([int x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12() => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13() => throw 'uncalled';
+  List<T> Function(int, {Function x}) m14() => throw 'uncalled';
+  List<T> Function([List<T> x]) m15() => throw 'uncalled';
+  Function(int y, [Function x]) m16() => throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17() => throw 'uncalled';
+  void Function({int x}) m18() => throw 'uncalled';
+  void Function(core.List<core.int> x) m19() => throw 'uncalled';
+  int Function<A>(List<Function> x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x) m21() =>
+      throw 'uncalled';
+  A Function<A>(List<T> x) m22() => throw 'uncalled';
+  B Function(Function x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({Function x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T> x) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function>) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({int x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(Function x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(Function x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U40().runTests();
+  new U40<int>(tIsInt: true).runTests();
+  new U40<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type41_test.dart b/tests/language/function_type/function_type41_test.dart
new file mode 100644
index 0000000..48ae18b
--- /dev/null
+++ b/tests/language/function_type/function_type41_test.dart
@@ -0,0 +1,903 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({core.List<core.int> x});
+typedef F1<T> = List<Function> Function(int x, [List<Function>]);
+typedef F2<T> = List<T> Function(int, [Function]);
+typedef F3<T> = void Function([int]);
+typedef F4<T> = A Function<A>(Function x);
+typedef F5<T> = int Function({Function x}) Function(int x);
+typedef F6<T> = int Function(List<T> x) Function(int x);
+typedef F7<T> = Function Function(int, [Function x]) Function(int x);
+typedef F8<T> = Function Function([core.List<core.int>]) Function(int x);
+typedef F9<T> = List<Function> Function(int x, [int]) Function(int x);
+typedef F10<T> = List<Function> Function(int y, {List<Function> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function([int x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function>) Function(int x);
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>]) Function(int x);
+typedef F14<T> = List<T> Function(int, {Function x}) Function(int x);
+typedef F15<T> = List<T> Function([List<T> x]) Function(int x);
+typedef F16<T> = Function(int y, [Function x]) Function(int x);
+typedef F17<T> = Function(int, [core.List<core.int>]) Function(int x);
+typedef F18<T> = void Function({int x}) Function(int x);
+typedef F19<T> = void Function(core.List<core.int> x) Function(int x);
+typedef F20<T> = int Function<A>(List<Function> x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function(int x);
+typedef F22<T> = A Function<A>(List<T> x) Function(int x);
+typedef F23<T> = B Function(Function x) Function<B extends core.int>(int x);
+
+int f0({core.List<core.int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+List<int> f2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+void f3([int x0 = -1]) => throw 'uncalled';
+A f4<A>(Function x) => throw 'uncalled';
+int Function({Function x}) f5(int x) => throw 'uncalled';
+int Function(List<int> x) f6(int x) => throw 'uncalled';
+Function Function(int, [Function x]) f7(int x) => throw 'uncalled';
+Function Function([core.List<core.int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int x, [int]) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13(int x) => throw 'uncalled';
+List<int> Function(int, {Function x}) f14(int x) => throw 'uncalled';
+List<int> Function([List<int> x]) f15(int x) => throw 'uncalled';
+Function(int y, [Function x]) f16(int x) => throw 'uncalled';
+Function(int, [core.List<core.int>]) f17(int x) => throw 'uncalled';
+void Function({int x}) f18(int x) => throw 'uncalled';
+void Function(core.List<core.int> x) f19(int x) => throw 'uncalled';
+int Function<A>(List<Function> x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x) f21(int x) =>
+    throw 'uncalled';
+A Function<A>(List<int> x) f22(int x) => throw 'uncalled';
+B Function(Function x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U41<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({core.List<core.int> x}) x0;
+  late List<Function> Function(int x, [List<Function>]) x1;
+  late List<T> Function(int, [Function]) x2;
+  late void Function([int]) x3;
+  late A Function<A>(Function x) x4;
+  late int Function({Function x}) Function(int x) x5;
+  late int Function(List<T> x) Function(int x) x6;
+  late Function Function(int, [Function x]) Function(int x) x7;
+  late Function Function([core.List<core.int>]) Function(int x) x8;
+  late List<Function> Function(int x, [int]) Function(int x) x9;
+  late List<Function> Function(int y, {List<Function> x}) Function(int x) x10;
+  late core.List<core.int> Function([int x]) Function(int x) x11;
+  late core.List<core.int> Function(List<Function>) Function(int x) x12;
+  late core.List<core.int> Function(int x, [List<T>]) Function(int x) x13;
+  late List<T> Function(int, {Function x}) Function(int x) x14;
+  late List<T> Function([List<T> x]) Function(int x) x15;
+  late Function(int y, [Function x]) Function(int x) x16;
+  late Function(int, [core.List<core.int>]) Function(int x) x17;
+  late void Function({int x}) Function(int x) x18;
+  late void Function(core.List<core.int> x) Function(int x) x19;
+  late int Function<A>(List<Function> x) Function(int x) x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x) Function(int x)
+      x21;
+  late A Function<A>(List<T> x) Function(int x) x22;
+  late B Function(Function x) Function<B extends core.int>(int x) x23;
+
+  U41({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({core.List<core.int> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  void m3([int x0 = -1]) => throw 'uncalled';
+  A m4<A>(Function x) => throw 'uncalled';
+  int Function({Function x}) m5(int x) => throw 'uncalled';
+  int Function(List<T> x) m6(int x) => throw 'uncalled';
+  Function Function(int, [Function x]) m7(int x) => throw 'uncalled';
+  Function Function([core.List<core.int>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int x, [int]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([int x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13(int x) => throw 'uncalled';
+  List<T> Function(int, {Function x}) m14(int x) => throw 'uncalled';
+  List<T> Function([List<T> x]) m15(int x) => throw 'uncalled';
+  Function(int y, [Function x]) m16(int x) => throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17(int x) => throw 'uncalled';
+  void Function({int x}) m18(int x) => throw 'uncalled';
+  void Function(core.List<core.int> x) m19(int x) => throw 'uncalled';
+  int Function<A>(List<Function> x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x) m21(int x) =>
+      throw 'uncalled';
+  A Function<A>(List<T> x) m22(int x) => throw 'uncalled';
+  B Function(Function x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([int])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([int]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(Function x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(Function x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is B Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U41().runTests();
+  new U41<int>(tIsInt: true).runTests();
+  new U41<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type42_test.dart b/tests/language/function_type/function_type42_test.dart
new file mode 100644
index 0000000..37251c3
--- /dev/null
+++ b/tests/language/function_type/function_type42_test.dart
@@ -0,0 +1,951 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {core.List<core.int> x});
+typedef F1<T> = List<Function> Function({List<Function> x});
+typedef F2<T> = List<T> Function(int x, [Function]);
+typedef F3<T> = void Function(int, [int]);
+typedef F4<T> = A Function<A>(List<Function> x);
+typedef F5<T> = int Function({Function x}) Function<B extends core.int>();
+typedef F6<T> = int Function(List<T> x) Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int x, [int])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function([int x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(List<Function>)
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function([List<T> x]) Function<B extends core.int>();
+typedef F16<T> = Function(int y, [Function x]) Function<B extends core.int>();
+typedef F17<T> = Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F18<T> = void Function({int x}) Function<B extends core.int>();
+typedef F19<T> = void Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(List<T> x) Function<B extends core.int>();
+typedef F23<T> = B Function(List<Function> x) Function<B extends core.int>();
+
+int f0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+List<Function> f1({List<Function> x = const []}) => throw 'uncalled';
+List<int> f2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+void f3(int x0, [int x1 = -1]) => throw 'uncalled';
+A f4<A>(List<Function> x) => throw 'uncalled';
+int Function({Function x}) f5<B extends core.int>() => throw 'uncalled';
+int Function(List<int> x) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [Function x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([core.List<core.int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int x, [int]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([int x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, {Function x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([List<int> x]) f15<B extends core.int>() => throw 'uncalled';
+Function(int y, [Function x]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, [core.List<core.int>]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function({int x}) f18<B extends core.int>() => throw 'uncalled';
+void Function(core.List<core.int> x) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(List<Function> x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x)
+    f21<B extends core.int>() => throw 'uncalled';
+A Function<A>(List<int> x) f22<B extends core.int>() => throw 'uncalled';
+B Function(List<Function> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U42<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {core.List<core.int> x}) x0;
+  late List<Function> Function({List<Function> x}) x1;
+  late List<T> Function(int x, [Function]) x2;
+  late void Function(int, [int]) x3;
+  late A Function<A>(List<Function> x) x4;
+  late int Function({Function x}) Function<B extends core.int>() x5;
+  late int Function(List<T> x) Function<B extends core.int>() x6;
+  late Function Function(int, [Function x]) Function<B extends core.int>() x7;
+  late Function Function([core.List<core.int>]) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int x, [int]) Function<B extends core.int>() x9;
+  late List<Function> Function(int y, {List<Function> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function([int x]) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(List<Function>)
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int x, [List<T>])
+      Function<B extends core.int>() x13;
+  late List<T> Function(int, {Function x}) Function<B extends core.int>() x14;
+  late List<T> Function([List<T> x]) Function<B extends core.int>() x15;
+  late Function(int y, [Function x]) Function<B extends core.int>() x16;
+  late Function(int, [core.List<core.int>]) Function<B extends core.int>() x17;
+  late void Function({int x}) Function<B extends core.int>() x18;
+  late void Function(core.List<core.int> x) Function<B extends core.int>() x19;
+  late int Function<A>(List<Function> x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>() x21;
+  late A Function<A>(List<T> x) Function<B extends core.int>() x22;
+  late B Function(List<Function> x) Function<B extends core.int>() x23;
+
+  U42({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  List<Function> m1({List<Function> x = const []}) => throw 'uncalled';
+  List<T> m2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  void m3(int x0, [int x1 = -1]) => throw 'uncalled';
+  A m4<A>(List<Function> x) => throw 'uncalled';
+  int Function({Function x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function(List<T> x) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, [Function x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([core.List<core.int>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x, [int]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x})
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([int x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, {Function x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([List<T> x]) m15<B extends core.int>() => throw 'uncalled';
+  Function(int y, [Function x]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function({int x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function(core.List<core.int> x) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(List<Function> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x)
+      m21<B extends core.int>() => throw 'uncalled';
+  A Function<A>(List<T> x) m22<B extends core.int>() => throw 'uncalled';
+  B Function(List<Function> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [int])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [int]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function<B extends core.int>()
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>])
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(List<Function> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<Function> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is B Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U42().runTests();
+  new U42<int>(tIsInt: true).runTests();
+  new U42<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type43_test.dart b/tests/language/function_type/function_type43_test.dart
new file mode 100644
index 0000000..86d8998
--- /dev/null
+++ b/tests/language/function_type/function_type43_test.dart
@@ -0,0 +1,979 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {core.List<core.int> x});
+typedef F1<T> = List<Function> Function(int, {List<Function> x});
+typedef F2<T> = List<T> Function({Function x});
+typedef F3<T> = void Function(int x, [int]);
+typedef F4<T> = A Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function({Function x}) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(List<T> x) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int x, [int])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function([int x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function>)
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function([List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int y, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function({int x}) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(List<T> x) Function<B extends core.int>(int x);
+typedef F23<T> = B Function(List<Function> x) Function<B extends core.int>(
+    int x);
+
+int f0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x0, {List<Function> x = const []}) => throw 'uncalled';
+List<int> f2({Function x = _voidFunction}) => throw 'uncalled';
+void f3(int x, [int x0 = -1]) => throw 'uncalled';
+A f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function({Function x}) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(List<int> x) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, [Function x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([core.List<core.int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [int]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int, {Function x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([List<int> x]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, [Function x]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [core.List<core.int>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function({int x}) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(core.List<core.int> x) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(List<Function> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x) f21<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+A Function<A>(List<int> x) f22<B extends core.int>(int x) => throw 'uncalled';
+B Function(List<Function> x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U43<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {core.List<core.int> x}) x0;
+  late List<Function> Function(int, {List<Function> x}) x1;
+  late List<T> Function({Function x}) x2;
+  late void Function(int x, [int]) x3;
+  late A Function<A>(core.List<core.int> x) x4;
+  late int Function({Function x}) Function<B extends core.int>(int x) x5;
+  late int Function(List<T> x) Function<B extends core.int>(int x) x6;
+  late Function Function(int, [Function x]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function([core.List<core.int>]) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int x, [int]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(int y, {List<Function> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function([int x]) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(List<Function>)
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int x, [List<T>])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, {Function x}) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function([List<T> x]) Function<B extends core.int>(int x) x15;
+  late Function(int y, [Function x]) Function<B extends core.int>(int x) x16;
+  late Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+      x17;
+  late void Function({int x}) Function<B extends core.int>(int x) x18;
+  late void Function(core.List<core.int> x) Function<B extends core.int>(int x)
+      x19;
+  late int Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>(int x) x21;
+  late A Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
+  late B Function(List<Function> x) Function<B extends core.int>(int x) x23;
+
+  U43({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  List<T> m2({Function x = _voidFunction}) => throw 'uncalled';
+  void m3(int x, [int x0 = -1]) => throw 'uncalled';
+  A m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function({Function x}) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(List<T> x) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int, [Function x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([core.List<core.int>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [int]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([int x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {Function x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<T> x]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, [Function x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function({int x}) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(core.List<core.int> x) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(List<Function> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x)
+      m21<B extends core.int>(int x) => throw 'uncalled';
+  A Function<A>(List<T> x) m22<B extends core.int>(int x) => throw 'uncalled';
+  B Function(List<Function> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [int])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [int]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function({Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<Function> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U43().runTests();
+  new U43<int>(tIsInt: true).runTests();
+  new U43<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type44_test.dart b/tests/language/function_type/function_type44_test.dart
new file mode 100644
index 0000000..a500615
--- /dev/null
+++ b/tests/language/function_type/function_type44_test.dart
@@ -0,0 +1,946 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<T> x);
+typedef F1<T> = List<Function> Function(int y, {List<Function> x});
+typedef F2<T> = List<T> Function(int, {Function x});
+typedef F3<T> = void Function({int x});
+typedef F4<T> = A Function<A>(List<T> x);
+typedef F5<T> = int Function(int, {Function x}) Function();
+typedef F6<T> = int Function([List<T> x]) Function();
+typedef F7<T> = Function Function(int y, [Function x]) Function();
+typedef F8<T> = Function Function(int, [core.List<core.int>]) Function();
+typedef F9<T> = List<Function> Function({int x}) Function();
+typedef F10<T> = List<Function> Function(core.List<core.int> x) Function();
+typedef F11<T> = core.List<core.int> Function(int, [int x]) Function();
+typedef F12<T> = core.List<core.int> Function([List<Function>]) Function();
+typedef F13<T> = core.List<core.int> Function({List<T> x}) Function();
+typedef F14<T> = List<T> Function(int y, {Function x}) Function();
+typedef F15<T> = List<T> Function(int, [List<T> x]) Function();
+typedef F16<T> = Function(Function) Function();
+typedef F17<T> = Function(int x, [core.List<core.int>]) Function();
+typedef F18<T> = void Function(int, {int x}) Function();
+typedef F19<T> = void Function([core.List<core.int> x]) Function();
+typedef F20<T> = int Function<A>(core.List<core.int> x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x) Function();
+typedef F22<T> = A Function<A>() Function();
+typedef F23<T> = B Function(core.List<core.int> x)
+    Function<B extends core.int>();
+
+int f0(List<int> x) => throw 'uncalled';
+List<Function> f1(int y, {List<Function> x = const []}) => throw 'uncalled';
+List<int> f2(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+void f3({int x = -1}) => throw 'uncalled';
+A f4<A>(List<int> x) => throw 'uncalled';
+int Function(int, {Function x}) f5() => throw 'uncalled';
+int Function([List<int> x]) f6() => throw 'uncalled';
+Function Function(int y, [Function x]) f7() => throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8() => throw 'uncalled';
+List<Function> Function({int x}) f9() => throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10() => throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11() => throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12() => throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13() => throw 'uncalled';
+List<int> Function(int y, {Function x}) f14() => throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15() => throw 'uncalled';
+Function(Function) f16() => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17() => throw 'uncalled';
+void Function(int, {int x}) f18() => throw 'uncalled';
+void Function([core.List<core.int> x]) f19() => throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21() => throw 'uncalled';
+A Function<A>() f22() => throw 'uncalled';
+B Function(core.List<core.int> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U44<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<T> x) x0;
+  late List<Function> Function(int y, {List<Function> x}) x1;
+  late List<T> Function(int, {Function x}) x2;
+  late void Function({int x}) x3;
+  late A Function<A>(List<T> x) x4;
+  late int Function(int, {Function x}) Function() x5;
+  late int Function([List<T> x]) Function() x6;
+  late Function Function(int y, [Function x]) Function() x7;
+  late Function Function(int, [core.List<core.int>]) Function() x8;
+  late List<Function> Function({int x}) Function() x9;
+  late List<Function> Function(core.List<core.int> x) Function() x10;
+  late core.List<core.int> Function(int, [int x]) Function() x11;
+  late core.List<core.int> Function([List<Function>]) Function() x12;
+  late core.List<core.int> Function({List<T> x}) Function() x13;
+  late List<T> Function(int y, {Function x}) Function() x14;
+  late List<T> Function(int, [List<T> x]) Function() x15;
+  late Function(Function) Function() x16;
+  late Function(int x, [core.List<core.int>]) Function() x17;
+  late void Function(int, {int x}) Function() x18;
+  late void Function([core.List<core.int> x]) Function() x19;
+  late int Function<A>(core.List<core.int> x) Function() x20;
+  late core.List<core.int> Function<A>(List<T> x) Function() x21;
+  late A Function<A>() Function() x22;
+  late B Function(core.List<core.int> x) Function<B extends core.int>() x23;
+
+  U44({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<T> x) => throw 'uncalled';
+  List<Function> m1(int y, {List<Function> x = const []}) => throw 'uncalled';
+  List<T> m2(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  void m3({int x = -1}) => throw 'uncalled';
+  A m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int, {Function x}) m5() => throw 'uncalled';
+  int Function([List<T> x]) m6() => throw 'uncalled';
+  Function Function(int y, [Function x]) m7() => throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8() => throw 'uncalled';
+  List<Function> Function({int x}) m9() => throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10() => throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11() => throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12() => throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13() => throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14() => throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15() => throw 'uncalled';
+  Function(Function) m16() => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17() => throw 'uncalled';
+  void Function(int, {int x}) m18() => throw 'uncalled';
+  void Function([core.List<core.int> x]) m19() => throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21() => throw 'uncalled';
+  A Function<A>() m22() => throw 'uncalled';
+  B Function(core.List<core.int> x) m23<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<T> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<T> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({int x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({int x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int, {Function x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({int x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(core.List<core.int> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U44().runTests();
+  new U44<int>(tIsInt: true).runTests();
+  new U44<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type45_test.dart b/tests/language/function_type/function_type45_test.dart
new file mode 100644
index 0000000..5cdf875
--- /dev/null
+++ b/tests/language/function_type/function_type45_test.dart
@@ -0,0 +1,929 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<T> x]);
+typedef F1<T> = List<Function> Function(core.List<core.int> x);
+typedef F2<T> = List<T> Function(int y, {Function x});
+typedef F3<T> = void Function(int, {int x});
+typedef F4<T> = A Function<A>();
+typedef F5<T> = int Function(int, {Function x}) Function(int x);
+typedef F6<T> = int Function([List<T> x]) Function(int x);
+typedef F7<T> = Function Function(int y, [Function x]) Function(int x);
+typedef F8<T> = Function Function(int, [core.List<core.int>]) Function(int x);
+typedef F9<T> = List<Function> Function({int x}) Function(int x);
+typedef F10<T> = List<Function> Function(core.List<core.int> x) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function>]) Function(int x);
+typedef F13<T> = core.List<core.int> Function({List<T> x}) Function(int x);
+typedef F14<T> = List<T> Function(int y, {Function x}) Function(int x);
+typedef F15<T> = List<T> Function(int, [List<T> x]) Function(int x);
+typedef F16<T> = Function(Function) Function(int x);
+typedef F17<T> = Function(int x, [core.List<core.int>]) Function(int x);
+typedef F18<T> = void Function(int, {int x}) Function(int x);
+typedef F19<T> = void Function([core.List<core.int> x]) Function(int x);
+typedef F20<T> = int Function<A>(core.List<core.int> x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x) Function(int x);
+typedef F22<T> = A Function<A>() Function(int x);
+typedef F23<T> = B Function(core.List<core.int> x) Function<B extends core.int>(
+    int x);
+
+int f0([List<int> x = const []]) => throw 'uncalled';
+List<Function> f1(core.List<core.int> x) => throw 'uncalled';
+List<int> f2(int y, {Function x = _voidFunction}) => throw 'uncalled';
+void f3(int x0, {int x = -1}) => throw 'uncalled';
+A f4<A>() => throw 'uncalled';
+int Function(int, {Function x}) f5(int x) => throw 'uncalled';
+int Function([List<int> x]) f6(int x) => throw 'uncalled';
+Function Function(int y, [Function x]) f7(int x) => throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8(int x) => throw 'uncalled';
+List<Function> Function({int x}) f9(int x) => throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13(int x) => throw 'uncalled';
+List<int> Function(int y, {Function x}) f14(int x) => throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15(int x) => throw 'uncalled';
+Function(Function) f16(int x) => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17(int x) => throw 'uncalled';
+void Function(int, {int x}) f18(int x) => throw 'uncalled';
+void Function([core.List<core.int> x]) f19(int x) => throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21(int x) => throw 'uncalled';
+A Function<A>() f22(int x) => throw 'uncalled';
+B Function(core.List<core.int> x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U45<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<T> x]) x0;
+  late List<Function> Function(core.List<core.int> x) x1;
+  late List<T> Function(int y, {Function x}) x2;
+  late void Function(int, {int x}) x3;
+  late A Function<A>() x4;
+  late int Function(int, {Function x}) Function(int x) x5;
+  late int Function([List<T> x]) Function(int x) x6;
+  late Function Function(int y, [Function x]) Function(int x) x7;
+  late Function Function(int, [core.List<core.int>]) Function(int x) x8;
+  late List<Function> Function({int x}) Function(int x) x9;
+  late List<Function> Function(core.List<core.int> x) Function(int x) x10;
+  late core.List<core.int> Function(int, [int x]) Function(int x) x11;
+  late core.List<core.int> Function([List<Function>]) Function(int x) x12;
+  late core.List<core.int> Function({List<T> x}) Function(int x) x13;
+  late List<T> Function(int y, {Function x}) Function(int x) x14;
+  late List<T> Function(int, [List<T> x]) Function(int x) x15;
+  late Function(Function) Function(int x) x16;
+  late Function(int x, [core.List<core.int>]) Function(int x) x17;
+  late void Function(int, {int x}) Function(int x) x18;
+  late void Function([core.List<core.int> x]) Function(int x) x19;
+  late int Function<A>(core.List<core.int> x) Function(int x) x20;
+  late core.List<core.int> Function<A>(List<T> x) Function(int x) x21;
+  late A Function<A>() Function(int x) x22;
+  late B Function(core.List<core.int> x) Function<B extends core.int>(int x)
+      x23;
+
+  U45({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<T> x = const []]) => throw 'uncalled';
+  List<Function> m1(core.List<core.int> x) => throw 'uncalled';
+  List<T> m2(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  void m3(int x0, {int x = -1}) => throw 'uncalled';
+  A m4<A>() => throw 'uncalled';
+  int Function(int, {Function x}) m5(int x) => throw 'uncalled';
+  int Function([List<T> x]) m6(int x) => throw 'uncalled';
+  Function Function(int y, [Function x]) m7(int x) => throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8(int x) => throw 'uncalled';
+  List<Function> Function({int x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15(int x) => throw 'uncalled';
+  Function(Function) m16(int x) => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17(int x) => throw 'uncalled';
+  void Function(int, {int x}) m18(int x) => throw 'uncalled';
+  void Function([core.List<core.int> x]) m19(int x) => throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21(int x) => throw 'uncalled';
+  A Function<A>() m22(int x) => throw 'uncalled';
+  B Function(core.List<core.int> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<T> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<T> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(core.List<core.int> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {int x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {int x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {Function x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(core.List<core.int> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U45().runTests();
+  new U45<int>(tIsInt: true).runTests();
+  new U45<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type46_test.dart b/tests/language/function_type/function_type46_test.dart
new file mode 100644
index 0000000..ebd19bf
--- /dev/null
+++ b/tests/language/function_type/function_type46_test.dart
@@ -0,0 +1,1007 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<T> x]);
+typedef F1<T> = List<Function> Function([core.List<core.int> x]);
+typedef F2<T> = List<T> Function(List<Function> x);
+typedef F3<T> = void Function(int y, {int x});
+typedef F4<T> = A Function<A>(A x);
+typedef F5<T> = int Function(int, {Function x}) Function<B extends core.int>();
+typedef F6<T> = int Function([List<T> x]) Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function({int x}) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, [int x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([List<Function>])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function({List<T> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function(Function) Function<B extends core.int>();
+typedef F17<T> = Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int, {int x}) Function<B extends core.int>();
+typedef F19<T> = void Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>() Function<B extends core.int>();
+typedef F23<T> = B Function(List<T> x) Function<B extends core.int>();
+
+int f0(int x0, [List<int> x = const []]) => throw 'uncalled';
+List<Function> f1([core.List<core.int> x = const []]) => throw 'uncalled';
+List<int> f2(List<Function> x) => throw 'uncalled';
+void f3(int y, {int x = -1}) => throw 'uncalled';
+A f4<A>(A x) => throw 'uncalled';
+int Function(int, {Function x}) f5<B extends core.int>() => throw 'uncalled';
+int Function([List<int> x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int y, [Function x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({int x}) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, {Function x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(Function) f16<B extends core.int>() => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, {int x}) f18<B extends core.int>() => throw 'uncalled';
+void Function([core.List<core.int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>() f22<B extends core.int>() => throw 'uncalled';
+B Function(List<int> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U46<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<T> x]) x0;
+  late List<Function> Function([core.List<core.int> x]) x1;
+  late List<T> Function(List<Function> x) x2;
+  late void Function(int y, {int x}) x3;
+  late A Function<A>(A x) x4;
+  late int Function(int, {Function x}) Function<B extends core.int>() x5;
+  late int Function([List<T> x]) Function<B extends core.int>() x6;
+  late Function Function(int y, [Function x]) Function<B extends core.int>() x7;
+  late Function Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x8;
+  late List<Function> Function({int x}) Function<B extends core.int>() x9;
+  late List<Function> Function(core.List<core.int> x)
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, [int x]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function([List<Function>])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function({List<T> x}) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int y, {Function x}) Function<B extends core.int>() x14;
+  late List<T> Function(int, [List<T> x]) Function<B extends core.int>() x15;
+  late Function(Function) Function<B extends core.int>() x16;
+  late Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+      x17;
+  late void Function(int, {int x}) Function<B extends core.int>() x18;
+  late void Function([core.List<core.int> x]) Function<B extends core.int>()
+      x19;
+  late int Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x20;
+  late core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>()
+      x21;
+  late A Function<A>() Function<B extends core.int>() x22;
+  late B Function(List<T> x) Function<B extends core.int>() x23;
+
+  U46({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<T> x = const []]) => throw 'uncalled';
+  List<Function> m1([core.List<core.int> x = const []]) => throw 'uncalled';
+  List<T> m2(List<Function> x) => throw 'uncalled';
+  void m3(int y, {int x = -1}) => throw 'uncalled';
+  A m4<A>(A x) => throw 'uncalled';
+  int Function(int, {Function x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function([List<T> x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, [Function x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({int x}) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(Function) m16<B extends core.int>() => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, {int x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function([core.List<core.int> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>() m22<B extends core.int>() => throw 'uncalled';
+  B Function(List<T> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [List<T> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function([core.List<core.int> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<Function> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<Function> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {int x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {int x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {Function x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x)
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function<B extends core.int>()
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(List<T> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<T> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U46().runTests();
+  new U46<int>(tIsInt: true).runTests();
+  new U46<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type47_test.dart b/tests/language/function_type/function_type47_test.dart
new file mode 100644
index 0000000..cec7699
--- /dev/null
+++ b/tests/language/function_type/function_type47_test.dart
@@ -0,0 +1,1029 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [List<T> x]);
+typedef F1<T> = List<Function> Function(int, [core.List<core.int> x]);
+typedef F2<T> = List<T> Function([List<Function> x]);
+typedef F3<T> = void Function(Function x);
+typedef F4<T> = A Function<A>(List<A> x);
+typedef F5<T> = int Function(int, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function([List<T> x]) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function({int x}) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function({List<T> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(Function) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, {int x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>() Function<B extends core.int>(int x);
+typedef F23<T> = B Function(List<T> x) Function<B extends core.int>(int x);
+
+int f0(int y, [List<int> x = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+List<int> f2([List<Function> x = const []]) => throw 'uncalled';
+void f3(Function x) => throw 'uncalled';
+A f4<A>(List<A> x) => throw 'uncalled';
+int Function(int, {Function x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function([List<int> x]) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, [Function x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({int x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {Function x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(Function) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, {int x}) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function([core.List<core.int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>() f22<B extends core.int>(int x) => throw 'uncalled';
+B Function(List<int> x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U47<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [List<T> x]) x0;
+  late List<Function> Function(int, [core.List<core.int> x]) x1;
+  late List<T> Function([List<Function> x]) x2;
+  late void Function(Function x) x3;
+  late A Function<A>(List<A> x) x4;
+  late int Function(int, {Function x}) Function<B extends core.int>(int x) x5;
+  late int Function([List<T> x]) Function<B extends core.int>(int x) x6;
+  late Function Function(int y, [Function x]) Function<B extends core.int>(
+      int x) x7;
+  late Function Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function({int x}) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(core.List<core.int> x)
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int, [int x]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([List<Function>])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function({List<T> x}) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int y, {Function x}) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+      x15;
+  late Function(Function) Function<B extends core.int>(int x) x16;
+  late Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x17;
+  late void Function(int, {int x}) Function<B extends core.int>(int x) x18;
+  late void Function([core.List<core.int> x]) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x20;
+  late core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>(
+      int x) x21;
+  late A Function<A>() Function<B extends core.int>(int x) x22;
+  late B Function(List<T> x) Function<B extends core.int>(int x) x23;
+
+  U47({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [List<T> x = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  List<T> m2([List<Function> x = const []]) => throw 'uncalled';
+  void m3(Function x) => throw 'uncalled';
+  A m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int, {Function x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function([List<T> x]) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int y, [Function x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({int x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(Function) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, {int x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([core.List<core.int> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>() m22<B extends core.int>(int x) => throw 'uncalled';
+  B Function(List<T> x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [List<T> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<Function> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<Function> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(Function x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(Function x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function([List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function<B extends core.int>(int x)
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+        l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(List<T> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<T> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is B Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U47().runTests();
+  new U47<int>(tIsInt: true).runTests();
+  new U47<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type48_test.dart b/tests/language/function_type/function_type48_test.dart
new file mode 100644
index 0000000..c500094
--- /dev/null
+++ b/tests/language/function_type/function_type48_test.dart
@@ -0,0 +1,924 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<T>);
+typedef F1<T> = List<Function> Function(int y, [core.List<core.int> x]);
+typedef F2<T> = List<T> Function(int, [List<Function> x]);
+typedef F3<T> = void Function([Function x]);
+typedef F4<T> = List<A> Function<A>(int x);
+typedef F5<T> = int Function(int y, {Function x}) Function();
+typedef F6<T> = int Function(int, [List<T> x]) Function();
+typedef F7<T> = Function Function(Function) Function();
+typedef F8<T> = Function Function(int x, [core.List<core.int>]) Function();
+typedef F9<T> = List<Function> Function(int, {int x}) Function();
+typedef F10<T> = List<Function> Function([core.List<core.int> x]) Function();
+typedef F11<T> = core.List<core.int> Function(int y, [int x]) Function();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>]) Function();
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x}) Function();
+typedef F14<T> = List<T> Function(List<Function> x) Function();
+typedef F15<T> = List<T> Function(int y, [List<T> x]) Function();
+typedef F16<T> = Function([Function]) Function();
+typedef F17<T> = Function({core.List<core.int> x}) Function();
+typedef F18<T> = void Function(int y, {int x}) Function();
+typedef F19<T> = void Function(int, [core.List<core.int> x]) Function();
+typedef F20<T> = int Function<A>(List<T> x) Function();
+typedef F21<T> = core.List<core.int> Function<A>() Function();
+typedef F22<T> = A Function<A>(A x) Function();
+typedef F23<T> = B Function() Function<B extends core.int>();
+
+int f0(List<int> x0) => throw 'uncalled';
+List<Function> f1(int y, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+List<int> f2(int x0, [List<Function> x = const []]) => throw 'uncalled';
+void f3([Function x = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(int x) => throw 'uncalled';
+int Function(int y, {Function x}) f5() => throw 'uncalled';
+int Function(int, [List<int> x]) f6() => throw 'uncalled';
+Function Function(Function) f7() => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8() => throw 'uncalled';
+List<Function> Function(int, {int x}) f9() => throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12() => throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13() => throw 'uncalled';
+List<int> Function(List<Function> x) f14() => throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15() => throw 'uncalled';
+Function([Function]) f16() => throw 'uncalled';
+Function({core.List<core.int> x}) f17() => throw 'uncalled';
+void Function(int y, {int x}) f18() => throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19() => throw 'uncalled';
+int Function<A>(List<int> x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>() f21() => throw 'uncalled';
+A Function<A>(A x) f22() => throw 'uncalled';
+B Function() f23<B extends core.int>() => throw 'uncalled';
+
+class U48<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<T>) x0;
+  late List<Function> Function(int y, [core.List<core.int> x]) x1;
+  late List<T> Function(int, [List<Function> x]) x2;
+  late void Function([Function x]) x3;
+  late List<A> Function<A>(int x) x4;
+  late int Function(int y, {Function x}) Function() x5;
+  late int Function(int, [List<T> x]) Function() x6;
+  late Function Function(Function) Function() x7;
+  late Function Function(int x, [core.List<core.int>]) Function() x8;
+  late List<Function> Function(int, {int x}) Function() x9;
+  late List<Function> Function([core.List<core.int> x]) Function() x10;
+  late core.List<core.int> Function(int y, [int x]) Function() x11;
+  late core.List<core.int> Function(int, [List<Function>]) Function() x12;
+  late core.List<core.int> Function(int, {List<T> x}) Function() x13;
+  late List<T> Function(List<Function> x) Function() x14;
+  late List<T> Function(int y, [List<T> x]) Function() x15;
+  late Function([Function]) Function() x16;
+  late Function({core.List<core.int> x}) Function() x17;
+  late void Function(int y, {int x}) Function() x18;
+  late void Function(int, [core.List<core.int> x]) Function() x19;
+  late int Function<A>(List<T> x) Function() x20;
+  late core.List<core.int> Function<A>() Function() x21;
+  late A Function<A>(A x) Function() x22;
+  late B Function() Function<B extends core.int>() x23;
+
+  U48({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<T> x0) => throw 'uncalled';
+  List<Function> m1(int y, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  List<T> m2(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  void m3([Function x = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(int x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5() => throw 'uncalled';
+  int Function(int, [List<T> x]) m6() => throw 'uncalled';
+  Function Function(Function) m7() => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8() => throw 'uncalled';
+  List<Function> Function(int, {int x}) m9() => throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10() => throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>]) m12() => throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13() => throw 'uncalled';
+  List<T> Function(List<Function> x) m14() => throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15() => throw 'uncalled';
+  Function([Function]) m16() => throw 'uncalled';
+  Function({core.List<core.int> x}) m17() => throw 'uncalled';
+  void Function(int y, {int x}) m18() => throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19() => throw 'uncalled';
+  int Function<A>(List<T> x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>() m21() => throw 'uncalled';
+  A Function<A>(A x) m22() => throw 'uncalled';
+  B Function() m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<T>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<T>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(
+        m1 is List<Function> Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<Function> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([Function x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([Function x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>() Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(A x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function() Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function() Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U48().runTests();
+  new U48<int>(tIsInt: true).runTests();
+  new U48<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type49_test.dart b/tests/language/function_type/function_type49_test.dart
new file mode 100644
index 0000000..04c1f3e
--- /dev/null
+++ b/tests/language/function_type/function_type49_test.dart
@@ -0,0 +1,926 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<T>]);
+typedef F1<T> = List<Function> Function(core.List<core.int>);
+typedef F2<T> = List<T> Function(int y, [List<Function> x]);
+typedef F3<T> = void Function(int, [Function x]);
+typedef F4<T> = List<A> Function<A>(Function x);
+typedef F5<T> = int Function(int y, {Function x}) Function(int x);
+typedef F6<T> = int Function(int, [List<T> x]) Function(int x);
+typedef F7<T> = Function Function(Function) Function(int x);
+typedef F8<T> = Function Function(int x, [core.List<core.int>]) Function(int x);
+typedef F9<T> = List<Function> Function(int, {int x}) Function(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int> x]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int y, [int x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x}) Function(int x);
+typedef F14<T> = List<T> Function(List<Function> x) Function(int x);
+typedef F15<T> = List<T> Function(int y, [List<T> x]) Function(int x);
+typedef F16<T> = Function([Function]) Function(int x);
+typedef F17<T> = Function({core.List<core.int> x}) Function(int x);
+typedef F18<T> = void Function(int y, {int x}) Function(int x);
+typedef F19<T> = void Function(int, [core.List<core.int> x]) Function(int x);
+typedef F20<T> = int Function<A>(List<T> x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>() Function(int x);
+typedef F22<T> = A Function<A>(A x) Function(int x);
+typedef F23<T> = B Function() Function<B extends core.int>(int x);
+
+int f0([List<int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(core.List<core.int> x0) => throw 'uncalled';
+List<int> f2(int y, [List<Function> x = const []]) => throw 'uncalled';
+void f3(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(Function x) => throw 'uncalled';
+int Function(int y, {Function x}) f5(int x) => throw 'uncalled';
+int Function(int, [List<int> x]) f6(int x) => throw 'uncalled';
+Function Function(Function) f7(int x) => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int, {int x}) f9(int x) => throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13(int x) => throw 'uncalled';
+List<int> Function(List<Function> x) f14(int x) => throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15(int x) => throw 'uncalled';
+Function([Function]) f16(int x) => throw 'uncalled';
+Function({core.List<core.int> x}) f17(int x) => throw 'uncalled';
+void Function(int y, {int x}) f18(int x) => throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19(int x) => throw 'uncalled';
+int Function<A>(List<int> x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>() f21(int x) => throw 'uncalled';
+A Function<A>(A x) f22(int x) => throw 'uncalled';
+B Function() f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U49<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<T>]) x0;
+  late List<Function> Function(core.List<core.int>) x1;
+  late List<T> Function(int y, [List<Function> x]) x2;
+  late void Function(int, [Function x]) x3;
+  late List<A> Function<A>(Function x) x4;
+  late int Function(int y, {Function x}) Function(int x) x5;
+  late int Function(int, [List<T> x]) Function(int x) x6;
+  late Function Function(Function) Function(int x) x7;
+  late Function Function(int x, [core.List<core.int>]) Function(int x) x8;
+  late List<Function> Function(int, {int x}) Function(int x) x9;
+  late List<Function> Function([core.List<core.int> x]) Function(int x) x10;
+  late core.List<core.int> Function(int y, [int x]) Function(int x) x11;
+  late core.List<core.int> Function(int, [List<Function>]) Function(int x) x12;
+  late core.List<core.int> Function(int, {List<T> x}) Function(int x) x13;
+  late List<T> Function(List<Function> x) Function(int x) x14;
+  late List<T> Function(int y, [List<T> x]) Function(int x) x15;
+  late Function([Function]) Function(int x) x16;
+  late Function({core.List<core.int> x}) Function(int x) x17;
+  late void Function(int y, {int x}) Function(int x) x18;
+  late void Function(int, [core.List<core.int> x]) Function(int x) x19;
+  late int Function<A>(List<T> x) Function(int x) x20;
+  late core.List<core.int> Function<A>() Function(int x) x21;
+  late A Function<A>(A x) Function(int x) x22;
+  late B Function() Function<B extends core.int>(int x) x23;
+
+  U49({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<T> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(core.List<core.int> x0) => throw 'uncalled';
+  List<T> m2(int y, [List<Function> x = const []]) => throw 'uncalled';
+  void m3(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(Function x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5(int x) => throw 'uncalled';
+  int Function(int, [List<T> x]) m6(int x) => throw 'uncalled';
+  Function Function(Function) m7(int x) => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, {int x}) m9(int x) => throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13(int x) => throw 'uncalled';
+  List<T> Function(List<Function> x) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15(int x) => throw 'uncalled';
+  Function([Function]) m16(int x) => throw 'uncalled';
+  Function({core.List<core.int> x}) m17(int x) => throw 'uncalled';
+  void Function(int y, {int x}) m18(int x) => throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19(int x) => throw 'uncalled';
+  int Function<A>(List<T> x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>() m21(int x) => throw 'uncalled';
+  A Function<A>(A x) m22(int x) => throw 'uncalled';
+  B Function() m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<T>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<T>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(core.List<core.int>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(core.List<core.int>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [List<Function> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [Function x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function() Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function() Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U49().runTests();
+  new U49<int>(tIsInt: true).runTests();
+  new U49<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type4_test.dart b/tests/language/function_type/function_type4_test.dart
new file mode 100644
index 0000000..77b3d2b
--- /dev/null
+++ b/tests/language/function_type/function_type4_test.dart
@@ -0,0 +1,953 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int);
+typedef F1<T> = Function Function(List<T>);
+typedef F2<T> = core.List<core.int> Function(int y, [core.List<core.int> x]);
+typedef F3<T> = Function(int, [List<Function> x]);
+typedef F4<T> = Function Function<A>(List<T> x);
+typedef F5<T> = int Function(int y, {int x}) Function();
+typedef F6<T> = int Function(int, [core.List<core.int> x]) Function();
+typedef F7<T> = Function Function(int) Function();
+typedef F8<T> = Function Function(int x, [List<Function>]) Function();
+typedef F9<T> = Function Function(int y, {List<T> x}) Function();
+typedef F10<T> = List<Function> Function([List<Function> x]) Function();
+typedef F11<T> = List<Function> Function(List<T>) Function();
+typedef F12<T> = core.List<core.int> Function(int, [Function]) Function();
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function();
+typedef F14<T> = List<T> Function(Function x) Function();
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x]) Function();
+typedef F16<T> = Function([int]) Function();
+typedef F17<T> = Function({List<Function> x}) Function();
+typedef F18<T> = Function() Function();
+typedef F19<T> = void Function(int, [List<Function> x]) Function();
+typedef F20<T> = void Function([List<T>]) Function();
+typedef F21<T> = List<Function> Function<A>(List<Function> x) Function();
+typedef F22<T> = Function<A>(core.List<core.int> x) Function();
+typedef F23<T> = void Function<A>(List<T> x) Function();
+
+int f0(int x0) => throw 'uncalled';
+Function f1(List<int> x0) => throw 'uncalled';
+core.List<core.int> f2(int y, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+f3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+Function f4<A>(List<int> x) => throw 'uncalled';
+int Function(int y, {int x}) f5() => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6() => throw 'uncalled';
+Function Function(int) f7() => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8() => throw 'uncalled';
+Function Function(int y, {List<int> x}) f9() => throw 'uncalled';
+List<Function> Function([List<Function> x]) f10() => throw 'uncalled';
+List<Function> Function(List<int>) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12() => throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x}) f13() =>
+    throw 'uncalled';
+List<int> Function(Function x) f14() => throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15() => throw 'uncalled';
+Function([int]) f16() => throw 'uncalled';
+Function({List<Function> x}) f17() => throw 'uncalled';
+Function() f18() => throw 'uncalled';
+void Function(int, [List<Function> x]) f19() => throw 'uncalled';
+void Function([List<int>]) f20() => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21() => throw 'uncalled';
+Function<A>(core.List<core.int> x) f22() => throw 'uncalled';
+void Function<A>(List<int> x) f23() => throw 'uncalled';
+
+class U4<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int) x0;
+  late Function Function(List<T>) x1;
+  late core.List<core.int> Function(int y, [core.List<core.int> x]) x2;
+  late Function(int, [List<Function> x]) x3;
+  late Function Function<A>(List<T> x) x4;
+  late int Function(int y, {int x}) Function() x5;
+  late int Function(int, [core.List<core.int> x]) Function() x6;
+  late Function Function(int) Function() x7;
+  late Function Function(int x, [List<Function>]) Function() x8;
+  late Function Function(int y, {List<T> x}) Function() x9;
+  late List<Function> Function([List<Function> x]) Function() x10;
+  late List<Function> Function(List<T>) Function() x11;
+  late core.List<core.int> Function(int, [Function]) Function() x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x}) Function()
+      x13;
+  late List<T> Function(Function x) Function() x14;
+  late List<T> Function(int y, [core.List<core.int> x]) Function() x15;
+  late Function([int]) Function() x16;
+  late Function({List<Function> x}) Function() x17;
+  late Function() Function() x18;
+  late void Function(int, [List<Function> x]) Function() x19;
+  late void Function([List<T>]) Function() x20;
+  late List<Function> Function<A>(List<Function> x) Function() x21;
+  late Function<A>(core.List<core.int> x) Function() x22;
+  late void Function<A>(List<T> x) Function() x23;
+
+  U4({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0) => throw 'uncalled';
+  Function m1(List<T> x0) => throw 'uncalled';
+  core.List<core.int> m2(int y, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  m3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  Function m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int y, {int x}) m5() => throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6() => throw 'uncalled';
+  Function Function(int) m7() => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8() => throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9() => throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10() => throw 'uncalled';
+  List<Function> Function(List<T>) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12() => throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x}) m13() =>
+      throw 'uncalled';
+  List<T> Function(Function x) m14() => throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15() => throw 'uncalled';
+  Function([int]) m16() => throw 'uncalled';
+  Function({List<Function> x}) m17() => throw 'uncalled';
+  Function() m18() => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19() => throw 'uncalled';
+  void Function([List<T>]) m20() => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21() => throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22() => throw 'uncalled';
+  void Function<A>(List<T> x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(List<T>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(List<T>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int y, {int x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(List<T>) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function x) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function([List<T>]) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U4().runTests();
+  new U4<int>(tIsInt: true).runTests();
+  new U4<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type50_test.dart b/tests/language/function_type/function_type50_test.dart
new file mode 100644
index 0000000..cc83722
--- /dev/null
+++ b/tests/language/function_type/function_type50_test.dart
@@ -0,0 +1,947 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<T>]);
+typedef F1<T> = List<Function> Function([core.List<core.int>]);
+typedef F2<T> = List<T> Function(List<Function>);
+typedef F3<T> = void Function(int y, [Function x]);
+typedef F4<T> = List<A> Function<A>(List<Function> x);
+typedef F5<T> = int Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, [List<T> x]) Function<B extends core.int>();
+typedef F7<T> = Function Function(Function) Function<B extends core.int>();
+typedef F8<T> = Function Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, {int x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function([Function]) Function<B extends core.int>();
+typedef F17<T> = Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int y, {int x}) Function<B extends core.int>();
+typedef F19<T> = void Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(List<T> x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>()
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(A x) Function<B extends core.int>();
+
+int f0(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+List<Function> f1([core.List<core.int> x0 = const []]) => throw 'uncalled';
+List<int> f2(List<Function> x0) => throw 'uncalled';
+void f3(int y, [Function x = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int y, {Function x}) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, [List<int> x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(Function) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {int x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(List<Function> x) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([Function]) f16<B extends core.int>() => throw 'uncalled';
+Function({core.List<core.int> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, {int x}) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(List<int> x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>() f21<B extends core.int>() => throw 'uncalled';
+A Function<A>(A x) f22<B extends core.int>() => throw 'uncalled';
+
+class U50<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<T>]) x0;
+  late List<Function> Function([core.List<core.int>]) x1;
+  late List<T> Function(List<Function>) x2;
+  late void Function(int y, [Function x]) x3;
+  late List<A> Function<A>(List<Function> x) x4;
+  late int Function(int y, {Function x}) Function<B extends core.int>() x5;
+  late int Function(int, [List<T> x]) Function<B extends core.int>() x6;
+  late Function Function(Function) Function<B extends core.int>() x7;
+  late Function Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x8;
+  late List<Function> Function(int, {int x}) Function<B extends core.int>() x9;
+  late List<Function> Function([core.List<core.int> x])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int y, [int x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [List<Function>])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, {List<T> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function(List<Function> x) Function<B extends core.int>() x14;
+  late List<T> Function(int y, [List<T> x]) Function<B extends core.int>() x15;
+  late Function([Function]) Function<B extends core.int>() x16;
+  late Function({core.List<core.int> x}) Function<B extends core.int>() x17;
+  late void Function(int y, {int x}) Function<B extends core.int>() x18;
+  late void Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x19;
+  late int Function<A>(List<T> x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>() Function<B extends core.int>() x21;
+  late A Function<A>(A x) Function<B extends core.int>() x22;
+
+  U50({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  List<Function> m1([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  List<T> m2(List<Function> x0) => throw 'uncalled';
+  void m3(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, [List<T> x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(Function) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {int x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(List<Function> x) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([Function]) m16<B extends core.int>() => throw 'uncalled';
+  Function({core.List<core.int> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, {int x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(List<T> x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>() m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(A x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int, [List<T>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<T>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function([core.List<core.int>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<Function>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<Function>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [Function x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>()
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U50().runTests();
+  new U50<int>(tIsInt: true).runTests();
+  new U50<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type51_test.dart b/tests/language/function_type/function_type51_test.dart
new file mode 100644
index 0000000..d77cc17
--- /dev/null
+++ b/tests/language/function_type/function_type51_test.dart
@@ -0,0 +1,974 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [List<T>]);
+typedef F1<T> = List<Function> Function(int, [core.List<core.int>]);
+typedef F2<T> = List<T> Function([List<Function>]);
+typedef F3<T> = void Function(Function);
+typedef F4<T> = List<A> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int y, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(Function) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, {int x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int y, [int x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([Function]) Function<B extends core.int>(int x);
+typedef F17<T> = Function({core.List<core.int> x}) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(List<T> x) Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>() Function<B extends core.int>(
+    int x);
+typedef F22<T> = A Function<A>(A x) Function<B extends core.int>(int x);
+
+int f0(int x, [List<int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [core.List<core.int> x1 = const []]) =>
+    throw 'uncalled';
+List<int> f2([List<Function> x0 = const []]) => throw 'uncalled';
+void f3(Function x0) => throw 'uncalled';
+List<A> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int y, {Function x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, [List<int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(Function) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {int x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(List<Function> x) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([Function]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function({core.List<core.int> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, {int x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(List<int> x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>() f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(A x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U51<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [List<T>]) x0;
+  late List<Function> Function(int, [core.List<core.int>]) x1;
+  late List<T> Function([List<Function>]) x2;
+  late void Function(Function) x3;
+  late List<A> Function<A>(core.List<core.int> x) x4;
+  late int Function(int y, {Function x}) Function<B extends core.int>(int x) x5;
+  late int Function(int, [List<T> x]) Function<B extends core.int>(int x) x6;
+  late Function Function(Function) Function<B extends core.int>(int x) x7;
+  late Function Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int, {int x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function([core.List<core.int> x])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int y, [int x])
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [List<Function>])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, {List<T> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(List<Function> x) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+      x15;
+  late Function([Function]) Function<B extends core.int>(int x) x16;
+  late Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+      x17;
+  late void Function(int y, {int x}) Function<B extends core.int>(int x) x18;
+  late void Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(List<T> x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>() Function<B extends core.int>(int x)
+      x21;
+  late A Function<A>(A x) Function<B extends core.int>(int x) x22;
+
+  U51({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [core.List<core.int> x1 = const []]) =>
+      throw 'uncalled';
+  List<T> m2([List<Function> x0 = const []]) => throw 'uncalled';
+  void m3(Function x0) => throw 'uncalled';
+  List<A> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [List<T> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(Function) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {int x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(List<Function> x) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([Function]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function({core.List<core.int> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {int x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(List<T> x) m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>() m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(A x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int x, [List<T>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<Function>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<Function>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(Function)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(Function));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>()
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U51().runTests();
+  new U51<int>(tIsInt: true).runTests();
+  new U51<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type52_test.dart b/tests/language/function_type/function_type52_test.dart
new file mode 100644
index 0000000..9e3ad9f
--- /dev/null
+++ b/tests/language/function_type/function_type52_test.dart
@@ -0,0 +1,896 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({List<T> x});
+typedef F1<T> = List<Function> Function(int x, [core.List<core.int>]);
+typedef F2<T> = List<T> Function(int, [List<Function>]);
+typedef F3<T> = void Function([Function]);
+typedef F4<T> = List<A> Function<A>(List<T> x);
+typedef F5<T> = int Function(List<Function> x) Function();
+typedef F6<T> = int Function(int y, [List<T> x]) Function();
+typedef F7<T> = Function Function([Function]) Function();
+typedef F8<T> = Function Function({core.List<core.int> x}) Function();
+typedef F9<T> = List<Function> Function(int y, {int x}) Function();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x])
+    Function();
+typedef F11<T> = core.List<core.int> Function(int) Function();
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>])
+    Function();
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x}) Function();
+typedef F14<T> = List<T> Function([List<Function> x]) Function();
+typedef F15<T> = List<T> Function(List<T>) Function();
+typedef F16<T> = Function(int, [Function]) Function();
+typedef F17<T> = Function(int, {core.List<core.int> x}) Function();
+typedef F18<T> = void Function(Function x) Function();
+typedef F19<T> = void Function(int y, [core.List<core.int> x]) Function();
+typedef F20<T> = int Function<A>() Function();
+typedef F21<T> = core.List<core.int> Function<A>(A x) Function();
+typedef F22<T> = A Function<A>(List<A> x) Function();
+
+int f0({List<int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x, [core.List<core.int> x0 = const []]) =>
+    throw 'uncalled';
+List<int> f2(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+void f3([Function x0 = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(List<int> x) => throw 'uncalled';
+int Function(List<Function> x) f5() => throw 'uncalled';
+int Function(int y, [List<int> x]) f6() => throw 'uncalled';
+Function Function([Function]) f7() => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8() => throw 'uncalled';
+List<Function> Function(int y, {int x}) f9() => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(int) f11() => throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>]) f12() => throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13() => throw 'uncalled';
+List<int> Function([List<Function> x]) f14() => throw 'uncalled';
+List<int> Function(List<int>) f15() => throw 'uncalled';
+Function(int, [Function]) f16() => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17() => throw 'uncalled';
+void Function(Function x) f18() => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19() => throw 'uncalled';
+int Function<A>() f20() => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21() => throw 'uncalled';
+A Function<A>(List<A> x) f22() => throw 'uncalled';
+
+class U52<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({List<T> x}) x0;
+  late List<Function> Function(int x, [core.List<core.int>]) x1;
+  late List<T> Function(int, [List<Function>]) x2;
+  late void Function([Function]) x3;
+  late List<A> Function<A>(List<T> x) x4;
+  late int Function(List<Function> x) Function() x5;
+  late int Function(int y, [List<T> x]) Function() x6;
+  late Function Function([Function]) Function() x7;
+  late Function Function({core.List<core.int> x}) Function() x8;
+  late List<Function> Function(int y, {int x}) Function() x9;
+  late List<Function> Function(int, [core.List<core.int> x]) Function() x10;
+  late core.List<core.int> Function(int) Function() x11;
+  late core.List<core.int> Function(int x, [List<Function>]) Function() x12;
+  late core.List<core.int> Function(int y, {List<T> x}) Function() x13;
+  late List<T> Function([List<Function> x]) Function() x14;
+  late List<T> Function(List<T>) Function() x15;
+  late Function(int, [Function]) Function() x16;
+  late Function(int, {core.List<core.int> x}) Function() x17;
+  late void Function(Function x) Function() x18;
+  late void Function(int y, [core.List<core.int> x]) Function() x19;
+  late int Function<A>() Function() x20;
+  late core.List<core.int> Function<A>(A x) Function() x21;
+  late A Function<A>(List<A> x) Function() x22;
+
+  U52({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({List<T> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x, [core.List<core.int> x0 = const []]) =>
+      throw 'uncalled';
+  List<T> m2(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  void m3([Function x0 = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(List<T> x) => throw 'uncalled';
+  int Function(List<Function> x) m5() => throw 'uncalled';
+  int Function(int y, [List<T> x]) m6() => throw 'uncalled';
+  Function Function([Function]) m7() => throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8() => throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9() => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x]) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int) m11() => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>]) m12() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13() => throw 'uncalled';
+  List<T> Function([List<Function> x]) m14() => throw 'uncalled';
+  List<T> Function(List<T>) m15() => throw 'uncalled';
+  Function(int, [Function]) m16() => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17() => throw 'uncalled';
+  void Function(Function x) m18() => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19() => throw 'uncalled';
+  int Function<A>() m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21() => throw 'uncalled';
+  A Function<A>(List<A> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function({List<T> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({List<T> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<Function>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([Function])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([Function]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(List<Function> x) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T>) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function x) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U52().runTests();
+  new U52<int>(tIsInt: true).runTests();
+  new U52<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type53_test.dart b/tests/language/function_type/function_type53_test.dart
new file mode 100644
index 0000000..9bf4d02
--- /dev/null
+++ b/tests/language/function_type/function_type53_test.dart
@@ -0,0 +1,879 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {List<T> x});
+typedef F1<T> = List<Function> Function({core.List<core.int> x});
+typedef F2<T> = List<T> Function(int x, [List<Function>]);
+typedef F3<T> = void Function(int, [Function]);
+typedef F4<T> = List<A> Function<A>();
+typedef F5<T> = int Function(List<Function> x) Function(int x);
+typedef F6<T> = int Function(int y, [List<T> x]) Function(int x);
+typedef F7<T> = Function Function([Function]) Function(int x);
+typedef F8<T> = Function Function({core.List<core.int> x}) Function(int x);
+typedef F9<T> = List<Function> Function(int y, {int x}) Function(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x}) Function(
+    int x);
+typedef F14<T> = List<T> Function([List<Function> x]) Function(int x);
+typedef F15<T> = List<T> Function(List<T>) Function(int x);
+typedef F16<T> = Function(int, [Function]) Function(int x);
+typedef F17<T> = Function(int, {core.List<core.int> x}) Function(int x);
+typedef F18<T> = void Function(Function x) Function(int x);
+typedef F19<T> = void Function(int y, [core.List<core.int> x]) Function(int x);
+typedef F20<T> = int Function<A>() Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(A x) Function(int x);
+typedef F22<T> = A Function<A>(List<A> x) Function(int x);
+
+int f0(int x0, {List<int> x = const []}) => throw 'uncalled';
+List<Function> f1({core.List<core.int> x = const []}) => throw 'uncalled';
+List<int> f2(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+void f3(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>() => throw 'uncalled';
+int Function(List<Function> x) f5(int x) => throw 'uncalled';
+int Function(int y, [List<int> x]) f6(int x) => throw 'uncalled';
+Function Function([Function]) f7(int x) => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, {int x}) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function([List<Function> x]) f14(int x) => throw 'uncalled';
+List<int> Function(List<int>) f15(int x) => throw 'uncalled';
+Function(int, [Function]) f16(int x) => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17(int x) => throw 'uncalled';
+void Function(Function x) f18(int x) => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19(int x) => throw 'uncalled';
+int Function<A>() f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21(int x) => throw 'uncalled';
+A Function<A>(List<A> x) f22(int x) => throw 'uncalled';
+
+class U53<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {List<T> x}) x0;
+  late List<Function> Function({core.List<core.int> x}) x1;
+  late List<T> Function(int x, [List<Function>]) x2;
+  late void Function(int, [Function]) x3;
+  late List<A> Function<A>() x4;
+  late int Function(List<Function> x) Function(int x) x5;
+  late int Function(int y, [List<T> x]) Function(int x) x6;
+  late Function Function([Function]) Function(int x) x7;
+  late Function Function({core.List<core.int> x}) Function(int x) x8;
+  late List<Function> Function(int y, {int x}) Function(int x) x9;
+  late List<Function> Function(int, [core.List<core.int> x]) Function(int x)
+      x10;
+  late core.List<core.int> Function(int) Function(int x) x11;
+  late core.List<core.int> Function(int x, [List<Function>]) Function(int x)
+      x12;
+  late core.List<core.int> Function(int y, {List<T> x}) Function(int x) x13;
+  late List<T> Function([List<Function> x]) Function(int x) x14;
+  late List<T> Function(List<T>) Function(int x) x15;
+  late Function(int, [Function]) Function(int x) x16;
+  late Function(int, {core.List<core.int> x}) Function(int x) x17;
+  late void Function(Function x) Function(int x) x18;
+  late void Function(int y, [core.List<core.int> x]) Function(int x) x19;
+  late int Function<A>() Function(int x) x20;
+  late core.List<core.int> Function<A>(A x) Function(int x) x21;
+  late A Function<A>(List<A> x) Function(int x) x22;
+
+  U53({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {List<T> x = const []}) => throw 'uncalled';
+  List<Function> m1({core.List<core.int> x = const []}) => throw 'uncalled';
+  List<T> m2(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  void m3(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>() => throw 'uncalled';
+  int Function(List<Function> x) m5(int x) => throw 'uncalled';
+  int Function(int y, [List<T> x]) m6(int x) => throw 'uncalled';
+  Function Function([Function]) m7(int x) => throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<Function> x]) m14(int x) => throw 'uncalled';
+  List<T> Function(List<T>) m15(int x) => throw 'uncalled';
+  Function(int, [Function]) m16(int x) => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17(int x) => throw 'uncalled';
+  void Function(Function x) m18(int x) => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19(int x) => throw 'uncalled';
+  int Function<A>() m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21(int x) => throw 'uncalled';
+  A Function<A>(List<A> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int, {List<T> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function({core.List<core.int> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [List<Function>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [Function])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [Function]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function> x) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, {List<T> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U53().runTests();
+  new U53<int>(tIsInt: true).runTests();
+  new U53<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type54_test.dart b/tests/language/function_type/function_type54_test.dart
new file mode 100644
index 0000000..1e3208c
--- /dev/null
+++ b/tests/language/function_type/function_type54_test.dart
@@ -0,0 +1,921 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {List<T> x});
+typedef F1<T> = List<Function> Function(int, {core.List<core.int> x});
+typedef F2<T> = List<T> Function({List<Function> x});
+typedef F3<T> = void Function(int x, [Function]);
+typedef F4<T> = List<A> Function<A>(A x);
+typedef F5<T> = int Function(List<Function> x) Function<B extends core.int>();
+typedef F6<T> = int Function(int y, [List<T> x]) Function<B extends core.int>();
+typedef F7<T> = Function Function([Function]) Function<B extends core.int>();
+typedef F8<T> = Function Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(List<T>) Function<B extends core.int>();
+typedef F16<T> = Function(int, [Function]) Function<B extends core.int>();
+typedef F17<T> = Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function(Function x) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>() Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(A x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(List<A> x) Function<B extends core.int>();
+
+int f0(int y, {List<int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x0, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+List<int> f2({List<Function> x = const []}) => throw 'uncalled';
+void f3(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(A x) => throw 'uncalled';
+int Function(List<Function> x) f5<B extends core.int>() => throw 'uncalled';
+int Function(int y, [List<int> x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function([Function]) f7<B extends core.int>() => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {int x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x])
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int) f11<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>])
+    f12<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([List<Function> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(List<int>) f15<B extends core.int>() => throw 'uncalled';
+Function(int, [Function]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function(Function x) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>() f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(List<A> x) f22<B extends core.int>() => throw 'uncalled';
+
+class U54<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {List<T> x}) x0;
+  late List<Function> Function(int, {core.List<core.int> x}) x1;
+  late List<T> Function({List<Function> x}) x2;
+  late void Function(int x, [Function]) x3;
+  late List<A> Function<A>(A x) x4;
+  late int Function(List<Function> x) Function<B extends core.int>() x5;
+  late int Function(int y, [List<T> x]) Function<B extends core.int>() x6;
+  late Function Function([Function]) Function<B extends core.int>() x7;
+  late Function Function({core.List<core.int> x}) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int y, {int x}) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int x, [List<Function>])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int y, {List<T> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function([List<Function> x]) Function<B extends core.int>() x14;
+  late List<T> Function(List<T>) Function<B extends core.int>() x15;
+  late Function(int, [Function]) Function<B extends core.int>() x16;
+  late Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+      x17;
+  late void Function(Function x) Function<B extends core.int>() x18;
+  late void Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x19;
+  late int Function<A>() Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(A x) Function<B extends core.int>() x21;
+  late A Function<A>(List<A> x) Function<B extends core.int>() x22;
+
+  U54({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {List<T> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x0, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  List<T> m2({List<Function> x = const []}) => throw 'uncalled';
+  void m3(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(A x) => throw 'uncalled';
+  int Function(List<Function> x) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int y, [List<T> x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function([Function]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([List<Function> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(List<T>) m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [Function]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(Function x) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>() m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(List<A> x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int y, {List<T> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [Function]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function> x) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U54().runTests();
+  new U54<int>(tIsInt: true).runTests();
+  new U54<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type55_test.dart b/tests/language/function_type/function_type55_test.dart
new file mode 100644
index 0000000..5722ccb
--- /dev/null
+++ b/tests/language/function_type/function_type55_test.dart
@@ -0,0 +1,921 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function();
+typedef F1<T> = List<Function> Function(int y, {core.List<core.int> x});
+typedef F2<T> = List<T> Function(int, {List<Function> x});
+typedef F3<T> = void Function({Function x});
+typedef F4<T> = List<A> Function<A>(List<A> x);
+typedef F5<T> = int Function(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int y, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function([Function]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int y, {int x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int) Function<B extends core.int>(
+    int x);
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(List<T>) Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [Function]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function(Function x) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>() Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(A x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(List<A> x) Function<B extends core.int>(int x);
+
+int f0() => throw 'uncalled';
+List<Function> f1(int y, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+List<int> f2(int x0, {List<Function> x = const []}) => throw 'uncalled';
+void f3({Function x = _voidFunction}) => throw 'uncalled';
+List<A> f4<A>(List<A> x) => throw 'uncalled';
+int Function(List<Function> x) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int y, [List<int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([Function]) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {int x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function([List<Function> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(List<int>) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [Function]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(Function x) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>() f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(List<A> x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U55<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function() x0;
+  late List<Function> Function(int y, {core.List<core.int> x}) x1;
+  late List<T> Function(int, {List<Function> x}) x2;
+  late void Function({Function x}) x3;
+  late List<A> Function<A>(List<A> x) x4;
+  late int Function(List<Function> x) Function<B extends core.int>(int x) x5;
+  late int Function(int y, [List<T> x]) Function<B extends core.int>(int x) x6;
+  late Function Function([Function]) Function<B extends core.int>(int x) x7;
+  late Function Function({core.List<core.int> x}) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int y, {int x}) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int x, [List<Function>])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int y, {List<T> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function([List<Function> x]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(List<T>) Function<B extends core.int>(int x) x15;
+  late Function(int, [Function]) Function<B extends core.int>(int x) x16;
+  late Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x17;
+  late void Function(Function x) Function<B extends core.int>(int x) x18;
+  late void Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x19;
+  late int Function<A>() Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(A x) Function<B extends core.int>(int x)
+      x21;
+  late A Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
+
+  U55({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0() => throw 'uncalled';
+  List<Function> m1(int y, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  List<T> m2(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  void m3({Function x = _voidFunction}) => throw 'uncalled';
+  List<A> m4<A>(List<A> x) => throw 'uncalled';
+  int Function(List<Function> x) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int y, [List<T> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([Function]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function([List<Function> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(List<T>) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [Function]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(Function x) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  int Function<A>() m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(List<A> x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function()
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function() l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function());
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(
+        m1 is List<Function> Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U55().runTests();
+  new U55<int>(tIsInt: true).runTests();
+  new U55<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type56_test.dart b/tests/language/function_type/function_type56_test.dart
new file mode 100644
index 0000000..0ba9a93
--- /dev/null
+++ b/tests/language/function_type/function_type56_test.dart
@@ -0,0 +1,842 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x);
+typedef F1<T> = List<Function> Function(List<T> x);
+typedef F2<T> = List<T> Function(int y, {List<Function> x});
+typedef F3<T> = void Function(int, {Function x});
+typedef F4<T> = void Function<A>(int x);
+typedef F5<T> = int Function([List<Function> x]) Function();
+typedef F6<T> = int Function(List<T>) Function();
+typedef F7<T> = Function Function(int, [Function]) Function();
+typedef F8<T> = Function Function(int, {core.List<core.int> x}) Function();
+typedef F9<T> = List<Function> Function(Function x) Function();
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function();
+typedef F11<T> = core.List<core.int> Function([int]) Function();
+typedef F12<T> = core.List<core.int> Function({List<Function> x}) Function();
+typedef F13<T> = core.List<core.int> Function() Function();
+typedef F14<T> = List<T> Function(int, [List<Function> x]) Function();
+typedef F15<T> = List<T> Function([List<T>]) Function();
+typedef F16<T> = Function(int x, [Function]) Function();
+typedef F17<T> = Function(int y, {core.List<core.int> x}) Function();
+typedef F18<T> = void Function([Function x]) Function();
+typedef F19<T> = void Function(core.List<core.int>) Function();
+typedef F20<T> = int Function<A>(A x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x) Function();
+typedef F22<T> = List<A> Function<A>(int x) Function();
+
+Function f0(int x) => throw 'uncalled';
+List<Function> f1(List<int> x) => throw 'uncalled';
+List<int> f2(int y, {List<Function> x = const []}) => throw 'uncalled';
+void f3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+void f4<A>(int x) => throw 'uncalled';
+int Function([List<Function> x]) f5() => throw 'uncalled';
+int Function(List<int>) f6() => throw 'uncalled';
+Function Function(int, [Function]) f7() => throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8() => throw 'uncalled';
+List<Function> Function(Function x) f9() => throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x]) f10() =>
+    throw 'uncalled';
+core.List<core.int> Function([int]) f11() => throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12() => throw 'uncalled';
+core.List<core.int> Function() f13() => throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14() => throw 'uncalled';
+List<int> Function([List<int>]) f15() => throw 'uncalled';
+Function(int x, [Function]) f16() => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17() => throw 'uncalled';
+void Function([Function x]) f18() => throw 'uncalled';
+void Function(core.List<core.int>) f19() => throw 'uncalled';
+int Function<A>(A x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21() => throw 'uncalled';
+List<A> Function<A>(int x) f22() => throw 'uncalled';
+
+class U56<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x) x0;
+  late List<Function> Function(List<T> x) x1;
+  late List<T> Function(int y, {List<Function> x}) x2;
+  late void Function(int, {Function x}) x3;
+  late void Function<A>(int x) x4;
+  late int Function([List<Function> x]) Function() x5;
+  late int Function(List<T>) Function() x6;
+  late Function Function(int, [Function]) Function() x7;
+  late Function Function(int, {core.List<core.int> x}) Function() x8;
+  late List<Function> Function(Function x) Function() x9;
+  late List<Function> Function(int y, [core.List<core.int> x]) Function() x10;
+  late core.List<core.int> Function([int]) Function() x11;
+  late core.List<core.int> Function({List<Function> x}) Function() x12;
+  late core.List<core.int> Function() Function() x13;
+  late List<T> Function(int, [List<Function> x]) Function() x14;
+  late List<T> Function([List<T>]) Function() x15;
+  late Function(int x, [Function]) Function() x16;
+  late Function(int y, {core.List<core.int> x}) Function() x17;
+  late void Function([Function x]) Function() x18;
+  late void Function(core.List<core.int>) Function() x19;
+  late int Function<A>(A x) Function() x20;
+  late core.List<core.int> Function<A>(List<A> x) Function() x21;
+  late List<A> Function<A>(int x) Function() x22;
+
+  U56({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x) => throw 'uncalled';
+  List<Function> m1(List<T> x) => throw 'uncalled';
+  List<T> m2(int y, {List<Function> x = const []}) => throw 'uncalled';
+  void m3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  void m4<A>(int x) => throw 'uncalled';
+  int Function([List<Function> x]) m5() => throw 'uncalled';
+  int Function(List<T>) m6() => throw 'uncalled';
+  Function Function(int, [Function]) m7() => throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8() => throw 'uncalled';
+  List<Function> Function(Function x) m9() => throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x]) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function([int]) m11() => throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12() => throw 'uncalled';
+  core.List<core.int> Function() m13() => throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14() => throw 'uncalled';
+  List<T> Function([List<T>]) m15() => throw 'uncalled';
+  Function(int x, [Function]) m16() => throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17() => throw 'uncalled';
+  void Function([Function x]) m18() => throw 'uncalled';
+  void Function(core.List<core.int>) m19() => throw 'uncalled';
+  int Function<A>(A x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21() => throw 'uncalled';
+  List<A> Function<A>(int x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<T> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<T> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T>) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function() Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(A x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U56().runTests();
+  new U56<int>(tIsInt: true).runTests();
+  new U56<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type57_test.dart b/tests/language/function_type/function_type57_test.dart
new file mode 100644
index 0000000..127cf18
--- /dev/null
+++ b/tests/language/function_type/function_type57_test.dart
@@ -0,0 +1,848 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([int x]);
+typedef F1<T> = List<Function> Function([List<T> x]);
+typedef F2<T> = List<T> Function(core.List<core.int> x);
+typedef F3<T> = void Function(int y, {Function x});
+typedef F4<T> = void Function<A>(Function x);
+typedef F5<T> = int Function([List<Function> x]) Function(int x);
+typedef F6<T> = int Function(List<T>) Function(int x);
+typedef F7<T> = Function Function(int, [Function]) Function(int x);
+typedef F8<T> = Function Function(int, {core.List<core.int> x}) Function(int x);
+typedef F9<T> = List<Function> Function(Function x) Function(int x);
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function(int x);
+typedef F11<T> = core.List<core.int> Function([int]) Function(int x);
+typedef F12<T> = core.List<core.int> Function({List<Function> x}) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function() Function(int x);
+typedef F14<T> = List<T> Function(int, [List<Function> x]) Function(int x);
+typedef F15<T> = List<T> Function([List<T>]) Function(int x);
+typedef F16<T> = Function(int x, [Function]) Function(int x);
+typedef F17<T> = Function(int y, {core.List<core.int> x}) Function(int x);
+typedef F18<T> = void Function([Function x]) Function(int x);
+typedef F19<T> = void Function(core.List<core.int>) Function(int x);
+typedef F20<T> = int Function<A>(A x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x) Function(int x);
+typedef F22<T> = List<A> Function<A>(int x) Function(int x);
+
+Function f0([int x = -1]) => throw 'uncalled';
+List<Function> f1([List<int> x = const []]) => throw 'uncalled';
+List<int> f2(core.List<core.int> x) => throw 'uncalled';
+void f3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+void f4<A>(Function x) => throw 'uncalled';
+int Function([List<Function> x]) f5(int x) => throw 'uncalled';
+int Function(List<int>) f6(int x) => throw 'uncalled';
+Function Function(int, [Function]) f7(int x) => throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(Function x) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12(int x) => throw 'uncalled';
+core.List<core.int> Function() f13(int x) => throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14(int x) => throw 'uncalled';
+List<int> Function([List<int>]) f15(int x) => throw 'uncalled';
+Function(int x, [Function]) f16(int x) => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17(int x) => throw 'uncalled';
+void Function([Function x]) f18(int x) => throw 'uncalled';
+void Function(core.List<core.int>) f19(int x) => throw 'uncalled';
+int Function<A>(A x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(int x) f22(int x) => throw 'uncalled';
+
+class U57<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([int x]) x0;
+  late List<Function> Function([List<T> x]) x1;
+  late List<T> Function(core.List<core.int> x) x2;
+  late void Function(int y, {Function x}) x3;
+  late void Function<A>(Function x) x4;
+  late int Function([List<Function> x]) Function(int x) x5;
+  late int Function(List<T>) Function(int x) x6;
+  late Function Function(int, [Function]) Function(int x) x7;
+  late Function Function(int, {core.List<core.int> x}) Function(int x) x8;
+  late List<Function> Function(Function x) Function(int x) x9;
+  late List<Function> Function(int y, [core.List<core.int> x]) Function(int x)
+      x10;
+  late core.List<core.int> Function([int]) Function(int x) x11;
+  late core.List<core.int> Function({List<Function> x}) Function(int x) x12;
+  late core.List<core.int> Function() Function(int x) x13;
+  late List<T> Function(int, [List<Function> x]) Function(int x) x14;
+  late List<T> Function([List<T>]) Function(int x) x15;
+  late Function(int x, [Function]) Function(int x) x16;
+  late Function(int y, {core.List<core.int> x}) Function(int x) x17;
+  late void Function([Function x]) Function(int x) x18;
+  late void Function(core.List<core.int>) Function(int x) x19;
+  late int Function<A>(A x) Function(int x) x20;
+  late core.List<core.int> Function<A>(List<A> x) Function(int x) x21;
+  late List<A> Function<A>(int x) Function(int x) x22;
+
+  U57({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([int x = -1]) => throw 'uncalled';
+  List<Function> m1([List<T> x = const []]) => throw 'uncalled';
+  List<T> m2(core.List<core.int> x) => throw 'uncalled';
+  void m3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  void m4<A>(Function x) => throw 'uncalled';
+  int Function([List<Function> x]) m5(int x) => throw 'uncalled';
+  int Function(List<T>) m6(int x) => throw 'uncalled';
+  Function Function(int, [Function]) m7(int x) => throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(Function x) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([int]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function() m13(int x) => throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14(int x) => throw 'uncalled';
+  List<T> Function([List<T>]) m15(int x) => throw 'uncalled';
+  Function(int x, [Function]) m16(int x) => throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17(int x) => throw 'uncalled';
+  void Function([Function x]) m18(int x) => throw 'uncalled';
+  void Function(core.List<core.int>) m19(int x) => throw 'uncalled';
+  int Function<A>(A x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(int x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function() Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int y, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U57().runTests();
+  new U57<int>(tIsInt: true).runTests();
+  new U57<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type58_test.dart b/tests/language/function_type/function_type58_test.dart
new file mode 100644
index 0000000..55dcc02
--- /dev/null
+++ b/tests/language/function_type/function_type58_test.dart
@@ -0,0 +1,892 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [int x]);
+typedef F1<T> = List<Function> Function(int, [List<T> x]);
+typedef F2<T> = List<T> Function([core.List<core.int> x]);
+typedef F3<T> = void Function(List<Function> x);
+typedef F4<T> = void Function<A>(List<Function> x);
+typedef F5<T> = int Function([List<Function> x]) Function<B extends core.int>();
+typedef F6<T> = int Function(List<T>) Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [Function])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(Function x)
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function([int])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function() Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function([List<T>]) Function<B extends core.int>();
+typedef F16<T> = Function(int x, [Function]) Function<B extends core.int>();
+typedef F17<T> = Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function([Function x]) Function<B extends core.int>();
+typedef F19<T> = void Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(A x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x)
+    Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(int x) Function<B extends core.int>();
+
+Function f0(int x0, [int x = -1]) => throw 'uncalled';
+List<Function> f1(int x0, [List<int> x = const []]) => throw 'uncalled';
+List<int> f2([core.List<core.int> x = const []]) => throw 'uncalled';
+void f3(List<Function> x) => throw 'uncalled';
+void f4<A>(List<Function> x) => throw 'uncalled';
+int Function([List<Function> x]) f5<B extends core.int>() => throw 'uncalled';
+int Function(List<int>) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [Function]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(Function x) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x])
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function([int]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function() f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([List<int>]) f15<B extends core.int>() => throw 'uncalled';
+Function(int x, [Function]) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function([Function x]) f18<B extends core.int>() => throw 'uncalled';
+void Function(core.List<core.int>) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(A x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>(int x) f22<B extends core.int>() => throw 'uncalled';
+
+class U58<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [int x]) x0;
+  late List<Function> Function(int, [List<T> x]) x1;
+  late List<T> Function([core.List<core.int> x]) x2;
+  late void Function(List<Function> x) x3;
+  late void Function<A>(List<Function> x) x4;
+  late int Function([List<Function> x]) Function<B extends core.int>() x5;
+  late int Function(List<T>) Function<B extends core.int>() x6;
+  late Function Function(int, [Function]) Function<B extends core.int>() x7;
+  late Function Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x8;
+  late List<Function> Function(Function x) Function<B extends core.int>() x9;
+  late List<Function> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function([int]) Function<B extends core.int>() x11;
+  late core.List<core.int> Function({List<Function> x})
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function() Function<B extends core.int>() x13;
+  late List<T> Function(int, [List<Function> x]) Function<B extends core.int>()
+      x14;
+  late List<T> Function([List<T>]) Function<B extends core.int>() x15;
+  late Function(int x, [Function]) Function<B extends core.int>() x16;
+  late Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+      x17;
+  late void Function([Function x]) Function<B extends core.int>() x18;
+  late void Function(core.List<core.int>) Function<B extends core.int>() x19;
+  late int Function<A>(A x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>()
+      x21;
+  late List<A> Function<A>(int x) Function<B extends core.int>() x22;
+
+  U58({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [int x = -1]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m2([core.List<core.int> x = const []]) => throw 'uncalled';
+  void m3(List<Function> x) => throw 'uncalled';
+  void m4<A>(List<Function> x) => throw 'uncalled';
+  int Function([List<Function> x]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(List<T>) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, [Function]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(Function x) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([int]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function() m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([List<T>]) m15<B extends core.int>() => throw 'uncalled';
+  Function(int x, [Function]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([Function x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(core.List<core.int>) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(A x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  List<A> Function<A>(int x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<Function> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([List<Function> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int x, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<A> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U58().runTests();
+  new U58<int>(tIsInt: true).runTests();
+  new U58<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type59_test.dart b/tests/language/function_type/function_type59_test.dart
new file mode 100644
index 0000000..8903d02
--- /dev/null
+++ b/tests/language/function_type/function_type59_test.dart
@@ -0,0 +1,917 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [int x]);
+typedef F1<T> = List<Function> Function(int y, [List<T> x]);
+typedef F2<T> = List<T> Function(int, [core.List<core.int> x]);
+typedef F3<T> = void Function([List<Function> x]);
+typedef F4<T> = void Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function([List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(List<T>) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(Function x)
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function([int])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function() Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function([List<T>]) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int x, [Function]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function([Function x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(A x) Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(int x) Function<B extends core.int>(int x);
+
+Function f0(int y, [int x = -1]) => throw 'uncalled';
+List<Function> f1(int y, [List<int> x = const []]) => throw 'uncalled';
+List<int> f2(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+void f3([List<Function> x = const []]) => throw 'uncalled';
+void f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function([List<Function> x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(List<int>) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, [Function]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(Function x) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function() f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([List<int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int x, [Function]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([Function x]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(core.List<core.int>) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(A x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(int x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U59<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [int x]) x0;
+  late List<Function> Function(int y, [List<T> x]) x1;
+  late List<T> Function(int, [core.List<core.int> x]) x2;
+  late void Function([List<Function> x]) x3;
+  late void Function<A>(core.List<core.int> x) x4;
+  late int Function([List<Function> x]) Function<B extends core.int>(int x) x5;
+  late int Function(List<T>) Function<B extends core.int>(int x) x6;
+  late Function Function(int, [Function]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function(Function x) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function([int]) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function({List<Function> x})
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function() Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, [List<Function> x]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function([List<T>]) Function<B extends core.int>(int x) x15;
+  late Function(int x, [Function]) Function<B extends core.int>(int x) x16;
+  late Function(int y, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x17;
+  late void Function([Function x]) Function<B extends core.int>(int x) x18;
+  late void Function(core.List<core.int>) Function<B extends core.int>(int x)
+      x19;
+  late int Function<A>(A x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>(
+      int x) x21;
+  late List<A> Function<A>(int x) Function<B extends core.int>(int x) x22;
+
+  U59({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [int x = -1]) => throw 'uncalled';
+  List<Function> m1(int y, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  void m3([List<Function> x = const []]) => throw 'uncalled';
+  void m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function([List<Function> x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(List<T>) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int, [Function]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(Function x) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x])
+      m10<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function([int]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function() m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<T>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int x, [Function]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([Function x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(core.List<core.int>) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(A x) m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(int x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function()
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int x, [Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U59().runTests();
+  new U59<int>(tIsInt: true).runTests();
+  new U59<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type5_test.dart b/tests/language/function_type/function_type5_test.dart
new file mode 100644
index 0000000..43c4b84
--- /dev/null
+++ b/tests/language/function_type/function_type5_test.dart
@@ -0,0 +1,932 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([int]);
+typedef F1<T> = Function Function([List<T>]);
+typedef F2<T> = core.List<core.int> Function(core.List<core.int>);
+typedef F3<T> = Function(int y, [List<Function> x]);
+typedef F4<T> = Function Function<A>();
+typedef F5<T> = int Function(int y, {int x}) Function(int x);
+typedef F6<T> = int Function(int, [core.List<core.int> x]) Function(int x);
+typedef F7<T> = Function Function(int) Function(int x);
+typedef F8<T> = Function Function(int x, [List<Function>]) Function(int x);
+typedef F9<T> = Function Function(int y, {List<T> x}) Function(int x);
+typedef F10<T> = List<Function> Function([List<Function> x]) Function(int x);
+typedef F11<T> = List<Function> Function(List<T>) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [Function]) Function(int x);
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function(int x);
+typedef F14<T> = List<T> Function(Function x) Function(int x);
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x]) Function(
+    int x);
+typedef F16<T> = Function([int]) Function(int x);
+typedef F17<T> = Function({List<Function> x}) Function(int x);
+typedef F18<T> = Function() Function(int x);
+typedef F19<T> = void Function(int, [List<Function> x]) Function(int x);
+typedef F20<T> = void Function([List<T>]) Function(int x);
+typedef F21<T> = List<Function> Function<A>(List<Function> x) Function(int x);
+typedef F22<T> = Function<A>(core.List<core.int> x) Function(int x);
+typedef F23<T> = void Function<A>(List<T> x) Function(int x);
+
+int f0([int x0 = -1]) => throw 'uncalled';
+Function f1([List<int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f2(core.List<core.int> x0) => throw 'uncalled';
+f3(int y, [List<Function> x = const []]) => throw 'uncalled';
+Function f4<A>() => throw 'uncalled';
+int Function(int y, {int x}) f5(int x) => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6(int x) => throw 'uncalled';
+Function Function(int) f7(int x) => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8(int x) => throw 'uncalled';
+Function Function(int y, {List<int> x}) f9(int x) => throw 'uncalled';
+List<Function> Function([List<Function> x]) f10(int x) => throw 'uncalled';
+List<Function> Function(List<int>) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function(Function x) f14(int x) => throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15(int x) =>
+    throw 'uncalled';
+Function([int]) f16(int x) => throw 'uncalled';
+Function({List<Function> x}) f17(int x) => throw 'uncalled';
+Function() f18(int x) => throw 'uncalled';
+void Function(int, [List<Function> x]) f19(int x) => throw 'uncalled';
+void Function([List<int>]) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21(int x) => throw 'uncalled';
+Function<A>(core.List<core.int> x) f22(int x) => throw 'uncalled';
+void Function<A>(List<int> x) f23(int x) => throw 'uncalled';
+
+class U5<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([int]) x0;
+  late Function Function([List<T>]) x1;
+  late core.List<core.int> Function(core.List<core.int>) x2;
+  late Function(int y, [List<Function> x]) x3;
+  late Function Function<A>() x4;
+  late int Function(int y, {int x}) Function(int x) x5;
+  late int Function(int, [core.List<core.int> x]) Function(int x) x6;
+  late Function Function(int) Function(int x) x7;
+  late Function Function(int x, [List<Function>]) Function(int x) x8;
+  late Function Function(int y, {List<T> x}) Function(int x) x9;
+  late List<Function> Function([List<Function> x]) Function(int x) x10;
+  late List<Function> Function(List<T>) Function(int x) x11;
+  late core.List<core.int> Function(int, [Function]) Function(int x) x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x}) Function(
+      int x) x13;
+  late List<T> Function(Function x) Function(int x) x14;
+  late List<T> Function(int y, [core.List<core.int> x]) Function(int x) x15;
+  late Function([int]) Function(int x) x16;
+  late Function({List<Function> x}) Function(int x) x17;
+  late Function() Function(int x) x18;
+  late void Function(int, [List<Function> x]) Function(int x) x19;
+  late void Function([List<T>]) Function(int x) x20;
+  late List<Function> Function<A>(List<Function> x) Function(int x) x21;
+  late Function<A>(core.List<core.int> x) Function(int x) x22;
+  late void Function<A>(List<T> x) Function(int x) x23;
+
+  U5({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([int x0 = -1]) => throw 'uncalled';
+  Function m1([List<T> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m2(core.List<core.int> x0) => throw 'uncalled';
+  m3(int y, [List<Function> x = const []]) => throw 'uncalled';
+  Function m4<A>() => throw 'uncalled';
+  int Function(int y, {int x}) m5(int x) => throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6(int x) => throw 'uncalled';
+  Function Function(int) m7(int x) => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8(int x) => throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9(int x) => throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10(int x) => throw 'uncalled';
+  List<Function> Function(List<T>) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function(Function x) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15(int x) =>
+      throw 'uncalled';
+  Function([int]) m16(int x) => throw 'uncalled';
+  Function({List<Function> x}) m17(int x) => throw 'uncalled';
+  Function() m18(int x) => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19(int x) => throw 'uncalled';
+  void Function([List<T>]) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21(int x) => throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22(int x) => throw 'uncalled';
+  void Function<A>(List<T> x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function([List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function([List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(core.List<core.int>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int y, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {int x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x}) Function(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U5().runTests();
+  new U5<int>(tIsInt: true).runTests();
+  new U5<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type60_test.dart b/tests/language/function_type/function_type60_test.dart
new file mode 100644
index 0000000..c42ce16
--- /dev/null
+++ b/tests/language/function_type/function_type60_test.dart
@@ -0,0 +1,942 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int);
+typedef F1<T> = List<Function> Function(List<T>);
+typedef F2<T> = List<T> Function(int y, [core.List<core.int> x]);
+typedef F3<T> = void Function(int, [List<Function> x]);
+typedef F4<T> = void Function<A>(List<T> x);
+typedef F5<T> = int Function(int, [List<Function> x]) Function();
+typedef F6<T> = int Function([List<T>]) Function();
+typedef F7<T> = Function Function(int x, [Function]) Function();
+typedef F8<T> = Function Function(int y, {core.List<core.int> x}) Function();
+typedef F9<T> = List<Function> Function([Function x]) Function();
+typedef F10<T> = List<Function> Function(core.List<core.int>) Function();
+typedef F11<T> = core.List<core.int> Function(int, [int]) Function();
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x})
+    Function();
+typedef F13<T> = List<T> Function(int x) Function();
+typedef F14<T> = List<T> Function(int y, [List<Function> x]) Function();
+typedef F15<T> = List<T> Function(int, [List<T>]) Function();
+typedef F16<T> = Function({Function x}) Function();
+typedef F17<T> = Function(List<T> x) Function();
+typedef F18<T> = void Function(int, [Function x]) Function();
+typedef F19<T> = void Function([core.List<core.int>]) Function();
+typedef F20<T> = int Function<A>(List<A> x) Function();
+typedef F21<T> = List<T> Function<A>(int x) Function();
+typedef F22<T> = List<A> Function<A>(Function x) Function();
+
+Function f0(int x0) => throw 'uncalled';
+List<Function> f1(List<int> x0) => throw 'uncalled';
+List<int> f2(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+void f3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+void f4<A>(List<int> x) => throw 'uncalled';
+int Function(int, [List<Function> x]) f5() => throw 'uncalled';
+int Function([List<int>]) f6() => throw 'uncalled';
+Function Function(int x, [Function]) f7() => throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8() => throw 'uncalled';
+List<Function> Function([Function x]) f9() => throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10() => throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x}) f12() => throw 'uncalled';
+List<int> Function(int x) f13() => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14() => throw 'uncalled';
+List<int> Function(int, [List<int>]) f15() => throw 'uncalled';
+Function({Function x}) f16() => throw 'uncalled';
+Function(List<int> x) f17() => throw 'uncalled';
+void Function(int, [Function x]) f18() => throw 'uncalled';
+void Function([core.List<core.int>]) f19() => throw 'uncalled';
+int Function<A>(List<A> x) f20() => throw 'uncalled';
+List<int> Function<A>(int x) f21() => throw 'uncalled';
+List<A> Function<A>(Function x) f22() => throw 'uncalled';
+
+class U60<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int) x0;
+  late List<Function> Function(List<T>) x1;
+  late List<T> Function(int y, [core.List<core.int> x]) x2;
+  late void Function(int, [List<Function> x]) x3;
+  late void Function<A>(List<T> x) x4;
+  late int Function(int, [List<Function> x]) Function() x5;
+  late int Function([List<T>]) Function() x6;
+  late Function Function(int x, [Function]) Function() x7;
+  late Function Function(int y, {core.List<core.int> x}) Function() x8;
+  late List<Function> Function([Function x]) Function() x9;
+  late List<Function> Function(core.List<core.int>) Function() x10;
+  late core.List<core.int> Function(int, [int]) Function() x11;
+  late core.List<core.int> Function(int, {List<Function> x}) Function() x12;
+  late List<T> Function(int x) Function() x13;
+  late List<T> Function(int y, [List<Function> x]) Function() x14;
+  late List<T> Function(int, [List<T>]) Function() x15;
+  late Function({Function x}) Function() x16;
+  late Function(List<T> x) Function() x17;
+  late void Function(int, [Function x]) Function() x18;
+  late void Function([core.List<core.int>]) Function() x19;
+  late int Function<A>(List<A> x) Function() x20;
+  late List<T> Function<A>(int x) Function() x21;
+  late List<A> Function<A>(Function x) Function() x22;
+
+  U60({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0) => throw 'uncalled';
+  List<Function> m1(List<T> x0) => throw 'uncalled';
+  List<T> m2(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  void m3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  void m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5() => throw 'uncalled';
+  int Function([List<T>]) m6() => throw 'uncalled';
+  Function Function(int x, [Function]) m7() => throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8() => throw 'uncalled';
+  List<Function> Function([Function x]) m9() => throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10() => throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x}) m12() =>
+      throw 'uncalled';
+  List<T> Function(int x) m13() => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14() => throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15() => throw 'uncalled';
+  Function({Function x}) m16() => throw 'uncalled';
+  Function(List<T> x) m17() => throw 'uncalled';
+  void Function(int, [Function x]) m18() => throw 'uncalled';
+  void Function([core.List<core.int>]) m19() => throw 'uncalled';
+  int Function<A>(List<A> x) m20() => throw 'uncalled';
+  List<T> Function<A>(int x) m21() => throw 'uncalled';
+  List<A> Function<A>(Function x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<T>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<T>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int, [List<Function> x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({Function x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T> x) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U60().runTests();
+  new U60<int>(tIsInt: true).runTests();
+  new U60<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type61_test.dart b/tests/language/function_type/function_type61_test.dart
new file mode 100644
index 0000000..1d6bb68
--- /dev/null
+++ b/tests/language/function_type/function_type61_test.dart
@@ -0,0 +1,922 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([int]);
+typedef F1<T> = List<Function> Function([List<T>]);
+typedef F2<T> = List<T> Function(core.List<core.int>);
+typedef F3<T> = void Function(int y, [List<Function> x]);
+typedef F4<T> = void Function<A>();
+typedef F5<T> = int Function(int, [List<Function> x]) Function(int x);
+typedef F6<T> = int Function([List<T>]) Function(int x);
+typedef F7<T> = Function Function(int x, [Function]) Function(int x);
+typedef F8<T> = Function Function(int y, {core.List<core.int> x}) Function(
+    int x);
+typedef F9<T> = List<Function> Function([Function x]) Function(int x);
+typedef F10<T> = List<Function> Function(core.List<core.int>) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x}) Function(
+    int x);
+typedef F13<T> = List<T> Function(int x) Function(int x);
+typedef F14<T> = List<T> Function(int y, [List<Function> x]) Function(int x);
+typedef F15<T> = List<T> Function(int, [List<T>]) Function(int x);
+typedef F16<T> = Function({Function x}) Function(int x);
+typedef F17<T> = Function(List<T> x) Function(int x);
+typedef F18<T> = void Function(int, [Function x]) Function(int x);
+typedef F19<T> = void Function([core.List<core.int>]) Function(int x);
+typedef F20<T> = int Function<A>(List<A> x) Function(int x);
+typedef F21<T> = List<T> Function<A>(int x) Function(int x);
+typedef F22<T> = List<A> Function<A>(Function x) Function(int x);
+
+Function f0([int x0 = -1]) => throw 'uncalled';
+List<Function> f1([List<int> x0 = const []]) => throw 'uncalled';
+List<int> f2(core.List<core.int> x0) => throw 'uncalled';
+void f3(int y, [List<Function> x = const []]) => throw 'uncalled';
+void f4<A>() => throw 'uncalled';
+int Function(int, [List<Function> x]) f5(int x) => throw 'uncalled';
+int Function([List<int>]) f6(int x) => throw 'uncalled';
+Function Function(int x, [Function]) f7(int x) => throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function([Function x]) f9(int x) => throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x}) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int x) f13(int x) => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14(int x) => throw 'uncalled';
+List<int> Function(int, [List<int>]) f15(int x) => throw 'uncalled';
+Function({Function x}) f16(int x) => throw 'uncalled';
+Function(List<int> x) f17(int x) => throw 'uncalled';
+void Function(int, [Function x]) f18(int x) => throw 'uncalled';
+void Function([core.List<core.int>]) f19(int x) => throw 'uncalled';
+int Function<A>(List<A> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(int x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(Function x) f22(int x) => throw 'uncalled';
+
+class U61<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([int]) x0;
+  late List<Function> Function([List<T>]) x1;
+  late List<T> Function(core.List<core.int>) x2;
+  late void Function(int y, [List<Function> x]) x3;
+  late void Function<A>() x4;
+  late int Function(int, [List<Function> x]) Function(int x) x5;
+  late int Function([List<T>]) Function(int x) x6;
+  late Function Function(int x, [Function]) Function(int x) x7;
+  late Function Function(int y, {core.List<core.int> x}) Function(int x) x8;
+  late List<Function> Function([Function x]) Function(int x) x9;
+  late List<Function> Function(core.List<core.int>) Function(int x) x10;
+  late core.List<core.int> Function(int, [int]) Function(int x) x11;
+  late core.List<core.int> Function(int, {List<Function> x}) Function(int x)
+      x12;
+  late List<T> Function(int x) Function(int x) x13;
+  late List<T> Function(int y, [List<Function> x]) Function(int x) x14;
+  late List<T> Function(int, [List<T>]) Function(int x) x15;
+  late Function({Function x}) Function(int x) x16;
+  late Function(List<T> x) Function(int x) x17;
+  late void Function(int, [Function x]) Function(int x) x18;
+  late void Function([core.List<core.int>]) Function(int x) x19;
+  late int Function<A>(List<A> x) Function(int x) x20;
+  late List<T> Function<A>(int x) Function(int x) x21;
+  late List<A> Function<A>(Function x) Function(int x) x22;
+
+  U61({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([int x0 = -1]) => throw 'uncalled';
+  List<Function> m1([List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m2(core.List<core.int> x0) => throw 'uncalled';
+  void m3(int y, [List<Function> x = const []]) => throw 'uncalled';
+  void m4<A>() => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5(int x) => throw 'uncalled';
+  int Function([List<T>]) m6(int x) => throw 'uncalled';
+  Function Function(int x, [Function]) m7(int x) => throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8(int x) =>
+      throw 'uncalled';
+  List<Function> Function([Function x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x}) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15(int x) => throw 'uncalled';
+  Function({Function x}) m16(int x) => throw 'uncalled';
+  Function(List<T> x) m17(int x) => throw 'uncalled';
+  void Function(int, [Function x]) m18(int x) => throw 'uncalled';
+  void Function([core.List<core.int>]) m19(int x) => throw 'uncalled';
+  int Function<A>(List<A> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(int x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(Function x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(core.List<core.int>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function> x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U61().runTests();
+  new U61<int>(tIsInt: true).runTests();
+  new U61<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type62_test.dart b/tests/language/function_type/function_type62_test.dart
new file mode 100644
index 0000000..5cfc9ec
--- /dev/null
+++ b/tests/language/function_type/function_type62_test.dart
@@ -0,0 +1,967 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [int]);
+typedef F1<T> = List<Function> Function(int, [List<T>]);
+typedef F2<T> = List<T> Function([core.List<core.int>]);
+typedef F3<T> = void Function(List<Function>);
+typedef F4<T> = void Function<A>(A x);
+typedef F5<T> = int Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F6<T> = int Function([List<T>]) Function<B extends core.int>();
+typedef F7<T> = Function Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([Function x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, [int])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int x) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F16<T> = Function({Function x}) Function<B extends core.int>();
+typedef F17<T> = Function(List<T> x) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F19<T> = void Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(List<A> x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(int x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(Function x) Function<B extends core.int>();
+
+Function f0(int x0, [int x1 = -1]) => throw 'uncalled';
+List<Function> f1(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+List<int> f2([core.List<core.int> x0 = const []]) => throw 'uncalled';
+void f3(List<Function> x0) => throw 'uncalled';
+void f4<A>(A x) => throw 'uncalled';
+int Function(int, [List<Function> x]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function([List<int>]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [Function]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([Function x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x})
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int x) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [List<int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function({Function x}) f16<B extends core.int>() => throw 'uncalled';
+Function(List<int> x) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [Function x]) f18<B extends core.int>() => throw 'uncalled';
+void Function([core.List<core.int>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(List<A> x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(int x) f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(Function x) f22<B extends core.int>() => throw 'uncalled';
+
+class U62<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [int]) x0;
+  late List<Function> Function(int, [List<T>]) x1;
+  late List<T> Function([core.List<core.int>]) x2;
+  late void Function(List<Function>) x3;
+  late void Function<A>(A x) x4;
+  late int Function(int, [List<Function> x]) Function<B extends core.int>() x5;
+  late int Function([List<T>]) Function<B extends core.int>() x6;
+  late Function Function(int x, [Function]) Function<B extends core.int>() x7;
+  late Function Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x8;
+  late List<Function> Function([Function x]) Function<B extends core.int>() x9;
+  late List<Function> Function(core.List<core.int>)
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, [int]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int, {List<Function> x})
+      Function<B extends core.int>() x12;
+  late List<T> Function(int x) Function<B extends core.int>() x13;
+  late List<T> Function(int y, [List<Function> x])
+      Function<B extends core.int>() x14;
+  late List<T> Function(int, [List<T>]) Function<B extends core.int>() x15;
+  late Function({Function x}) Function<B extends core.int>() x16;
+  late Function(List<T> x) Function<B extends core.int>() x17;
+  late void Function(int, [Function x]) Function<B extends core.int>() x18;
+  late void Function([core.List<core.int>]) Function<B extends core.int>() x19;
+  late int Function<A>(List<A> x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(int x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(Function x) Function<B extends core.int>() x22;
+
+  U62({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [int x1 = -1]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  List<T> m2([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  void m3(List<Function> x0) => throw 'uncalled';
+  void m4<A>(A x) => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function([List<T>]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int x, [Function]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([Function x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x})
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function({Function x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(List<T> x) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [Function x]) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([core.List<core.int>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(List<A> x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(int x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(Function x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(List<Function>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<Function>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U62().runTests();
+  new U62<int>(tIsInt: true).runTests();
+  new U62<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type63_test.dart b/tests/language/function_type/function_type63_test.dart
new file mode 100644
index 0000000..9950b66
--- /dev/null
+++ b/tests/language/function_type/function_type63_test.dart
@@ -0,0 +1,986 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [int]);
+typedef F1<T> = List<Function> Function(int x, [List<T>]);
+typedef F2<T> = List<T> Function(int, [core.List<core.int>]);
+typedef F3<T> = void Function([List<Function>]);
+typedef F4<T> = void Function<A>(List<A> x);
+typedef F5<T> = int Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function([List<T>]) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([Function x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int x) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function({Function x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function(List<T> x) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(List<A> x) Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(int x) Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(Function x) Function<B extends core.int>(
+    int x);
+
+Function f0(int x, [int x0 = -1]) => throw 'uncalled';
+List<Function> f1(int x, [List<int> x0 = const []]) => throw 'uncalled';
+List<int> f2(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+void f3([List<Function> x0 = const []]) => throw 'uncalled';
+void f4<A>(List<A> x) => throw 'uncalled';
+int Function(int, [List<Function> x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function([List<int>]) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int x, [Function]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function([Function x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int x) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function({Function x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(List<int> x) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, [Function x]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([core.List<core.int>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(List<A> x) f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(int x) f21<B extends core.int>(int x) => throw 'uncalled';
+List<A> Function<A>(Function x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U63<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [int]) x0;
+  late List<Function> Function(int x, [List<T>]) x1;
+  late List<T> Function(int, [core.List<core.int>]) x2;
+  late void Function([List<Function>]) x3;
+  late void Function<A>(List<A> x) x4;
+  late int Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+      x5;
+  late int Function([List<T>]) Function<B extends core.int>(int x) x6;
+  late Function Function(int x, [Function]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function([Function x]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(core.List<core.int>)
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int, [int]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int, {List<Function> x})
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int x) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int y, [List<Function> x]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function(int, [List<T>]) Function<B extends core.int>(int x) x15;
+  late Function({Function x}) Function<B extends core.int>(int x) x16;
+  late Function(List<T> x) Function<B extends core.int>(int x) x17;
+  late void Function(int, [Function x]) Function<B extends core.int>(int x) x18;
+  late void Function([core.List<core.int>]) Function<B extends core.int>(int x)
+      x19;
+  late int Function<A>(List<A> x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(int x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(Function x) Function<B extends core.int>(int x) x22;
+
+  U63({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [int x0 = -1]) => throw 'uncalled';
+  List<Function> m1(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  void m3([List<Function> x0 = const []]) => throw 'uncalled';
+  void m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function([List<T>]) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int x, [Function]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function([Function x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int x) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function({Function x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(List<T> x) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, [Function x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([core.List<core.int>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(List<A> x) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function<A>(int x) m21<B extends core.int>(int x) => throw 'uncalled';
+  List<A> Function<A>(Function x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function({Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U63().runTests();
+  new U63<int>(tIsInt: true).runTests();
+  new U63<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type64_test.dart b/tests/language/function_type/function_type64_test.dart
new file mode 100644
index 0000000..56e5697
--- /dev/null
+++ b/tests/language/function_type/function_type64_test.dart
@@ -0,0 +1,941 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({int x});
+typedef F1<T> = List<Function> Function({List<T> x});
+typedef F2<T> = List<T> Function(int x, [core.List<core.int>]);
+typedef F3<T> = void Function(int, [List<Function>]);
+typedef F4<T> = int Function(int x) Function();
+typedef F5<T> = int Function(int y, [List<Function> x]) Function();
+typedef F6<T> = int Function(int, [List<T>]) Function();
+typedef F7<T> = Function Function({Function x}) Function();
+typedef F8<T> = Function Function(List<T> x) Function();
+typedef F9<T> = List<Function> Function(int, [Function x]) Function();
+typedef F10<T> = List<Function> Function([core.List<core.int>]) Function();
+typedef F11<T> = core.List<core.int> Function(int x, [int]) Function();
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function();
+typedef F13<T> = List<T> Function([int x]) Function();
+typedef F14<T> = List<T> Function(List<Function>) Function();
+typedef F15<T> = List<T> Function(int x, [List<T>]) Function();
+typedef F16<T> = Function(int, {Function x}) Function();
+typedef F17<T> = Function([List<T> x]) Function();
+typedef F18<T> = void Function(int y, [Function x]) Function();
+typedef F19<T> = void Function(int, [core.List<core.int>]) Function();
+typedef F20<T> = Function Function<A>(int x) Function();
+typedef F21<T> = List<T> Function<A>(Function x) Function();
+typedef F22<T> = List<A> Function<A>(List<Function> x) Function();
+
+Function f0({int x = -1}) => throw 'uncalled';
+List<Function> f1({List<int> x = const []}) => throw 'uncalled';
+List<int> f2(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+void f3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+int Function(int x) f4() => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5() => throw 'uncalled';
+int Function(int, [List<int>]) f6() => throw 'uncalled';
+Function Function({Function x}) f7() => throw 'uncalled';
+Function Function(List<int> x) f8() => throw 'uncalled';
+List<Function> Function(int, [Function x]) f9() => throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10() => throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x}) f12() =>
+    throw 'uncalled';
+List<int> Function([int x]) f13() => throw 'uncalled';
+List<int> Function(List<Function>) f14() => throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15() => throw 'uncalled';
+Function(int, {Function x}) f16() => throw 'uncalled';
+Function([List<int> x]) f17() => throw 'uncalled';
+void Function(int y, [Function x]) f18() => throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19() => throw 'uncalled';
+Function Function<A>(int x) f20() => throw 'uncalled';
+List<int> Function<A>(Function x) f21() => throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22() => throw 'uncalled';
+
+class U64<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({int x}) x0;
+  late List<Function> Function({List<T> x}) x1;
+  late List<T> Function(int x, [core.List<core.int>]) x2;
+  late void Function(int, [List<Function>]) x3;
+  late int Function(int x) Function() x4;
+  late int Function(int y, [List<Function> x]) Function() x5;
+  late int Function(int, [List<T>]) Function() x6;
+  late Function Function({Function x}) Function() x7;
+  late Function Function(List<T> x) Function() x8;
+  late List<Function> Function(int, [Function x]) Function() x9;
+  late List<Function> Function([core.List<core.int>]) Function() x10;
+  late core.List<core.int> Function(int x, [int]) Function() x11;
+  late core.List<core.int> Function(int y, {List<Function> x}) Function() x12;
+  late List<T> Function([int x]) Function() x13;
+  late List<T> Function(List<Function>) Function() x14;
+  late List<T> Function(int x, [List<T>]) Function() x15;
+  late Function(int, {Function x}) Function() x16;
+  late Function([List<T> x]) Function() x17;
+  late void Function(int y, [Function x]) Function() x18;
+  late void Function(int, [core.List<core.int>]) Function() x19;
+  late Function Function<A>(int x) Function() x20;
+  late List<T> Function<A>(Function x) Function() x21;
+  late List<A> Function<A>(List<Function> x) Function() x22;
+
+  U64({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({int x = -1}) => throw 'uncalled';
+  List<Function> m1({List<T> x = const []}) => throw 'uncalled';
+  List<T> m2(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  void m3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  int Function(int x) m4() => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5() => throw 'uncalled';
+  int Function(int, [List<T>]) m6() => throw 'uncalled';
+  Function Function({Function x}) m7() => throw 'uncalled';
+  Function Function(List<T> x) m8() => throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9() => throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10() => throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x}) m12() =>
+      throw 'uncalled';
+  List<T> Function([int x]) m13() => throw 'uncalled';
+  List<T> Function(List<Function>) m14() => throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15() => throw 'uncalled';
+  Function(int, {Function x}) m16() => throw 'uncalled';
+  Function([List<T> x]) m17() => throw 'uncalled';
+  void Function(int y, [Function x]) m18() => throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19() => throw 'uncalled';
+  Function Function<A>(int x) m20() => throw 'uncalled';
+  List<T> Function<A>(Function x) m21() => throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({Function x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T> x) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function>) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(int x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U64().runTests();
+  new U64<int>(tIsInt: true).runTests();
+  new U64<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type65_test.dart b/tests/language/function_type/function_type65_test.dart
new file mode 100644
index 0000000..e3bef3e
--- /dev/null
+++ b/tests/language/function_type/function_type65_test.dart
@@ -0,0 +1,946 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {int x});
+typedef F1<T> = List<Function> Function(int, {List<T> x});
+typedef F2<T> = List<T> Function({core.List<core.int> x});
+typedef F3<T> = void Function(int x, [List<Function>]);
+typedef F4<T> = int Function(int x) Function(int x);
+typedef F5<T> = int Function(int y, [List<Function> x]) Function(int x);
+typedef F6<T> = int Function(int, [List<T>]) Function(int x);
+typedef F7<T> = Function Function({Function x}) Function(int x);
+typedef F8<T> = Function Function(List<T> x) Function(int x);
+typedef F9<T> = List<Function> Function(int, [Function x]) Function(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int>]) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int x, [int]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function(int x);
+typedef F13<T> = List<T> Function([int x]) Function(int x);
+typedef F14<T> = List<T> Function(List<Function>) Function(int x);
+typedef F15<T> = List<T> Function(int x, [List<T>]) Function(int x);
+typedef F16<T> = Function(int, {Function x}) Function(int x);
+typedef F17<T> = Function([List<T> x]) Function(int x);
+typedef F18<T> = void Function(int y, [Function x]) Function(int x);
+typedef F19<T> = void Function(int, [core.List<core.int>]) Function(int x);
+typedef F20<T> = Function Function<A>(int x) Function(int x);
+typedef F21<T> = List<T> Function<A>(Function x) Function(int x);
+typedef F22<T> = List<A> Function<A>(List<Function> x) Function(int x);
+
+Function f0(int x0, {int x = -1}) => throw 'uncalled';
+List<Function> f1(int x0, {List<int> x = const []}) => throw 'uncalled';
+List<int> f2({core.List<core.int> x = const []}) => throw 'uncalled';
+void f3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+int Function(int x) f4(int x) => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5(int x) => throw 'uncalled';
+int Function(int, [List<int>]) f6(int x) => throw 'uncalled';
+Function Function({Function x}) f7(int x) => throw 'uncalled';
+Function Function(List<int> x) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [Function x]) f9(int x) => throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x}) f12(int x) =>
+    throw 'uncalled';
+List<int> Function([int x]) f13(int x) => throw 'uncalled';
+List<int> Function(List<Function>) f14(int x) => throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15(int x) => throw 'uncalled';
+Function(int, {Function x}) f16(int x) => throw 'uncalled';
+Function([List<int> x]) f17(int x) => throw 'uncalled';
+void Function(int y, [Function x]) f18(int x) => throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19(int x) => throw 'uncalled';
+Function Function<A>(int x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(Function x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+
+class U65<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {int x}) x0;
+  late List<Function> Function(int, {List<T> x}) x1;
+  late List<T> Function({core.List<core.int> x}) x2;
+  late void Function(int x, [List<Function>]) x3;
+  late int Function(int x) Function(int x) x4;
+  late int Function(int y, [List<Function> x]) Function(int x) x5;
+  late int Function(int, [List<T>]) Function(int x) x6;
+  late Function Function({Function x}) Function(int x) x7;
+  late Function Function(List<T> x) Function(int x) x8;
+  late List<Function> Function(int, [Function x]) Function(int x) x9;
+  late List<Function> Function([core.List<core.int>]) Function(int x) x10;
+  late core.List<core.int> Function(int x, [int]) Function(int x) x11;
+  late core.List<core.int> Function(int y, {List<Function> x}) Function(int x)
+      x12;
+  late List<T> Function([int x]) Function(int x) x13;
+  late List<T> Function(List<Function>) Function(int x) x14;
+  late List<T> Function(int x, [List<T>]) Function(int x) x15;
+  late Function(int, {Function x}) Function(int x) x16;
+  late Function([List<T> x]) Function(int x) x17;
+  late void Function(int y, [Function x]) Function(int x) x18;
+  late void Function(int, [core.List<core.int>]) Function(int x) x19;
+  late Function Function<A>(int x) Function(int x) x20;
+  late List<T> Function<A>(Function x) Function(int x) x21;
+  late List<A> Function<A>(List<Function> x) Function(int x) x22;
+
+  U65({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {int x = -1}) => throw 'uncalled';
+  List<Function> m1(int x0, {List<T> x = const []}) => throw 'uncalled';
+  List<T> m2({core.List<core.int> x = const []}) => throw 'uncalled';
+  void m3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  int Function(int x) m4(int x) => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5(int x) => throw 'uncalled';
+  int Function(int, [List<T>]) m6(int x) => throw 'uncalled';
+  Function Function({Function x}) m7(int x) => throw 'uncalled';
+  Function Function(List<T> x) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9(int x) => throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x}) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function([int x]) m13(int x) => throw 'uncalled';
+  List<T> Function(List<Function>) m14(int x) => throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15(int x) => throw 'uncalled';
+  Function(int, {Function x}) m16(int x) => throw 'uncalled';
+  Function([List<T> x]) m17(int x) => throw 'uncalled';
+  void Function(int y, [Function x]) m18(int x) => throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19(int x) => throw 'uncalled';
+  Function Function<A>(int x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(Function x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U65().runTests();
+  new U65<int>(tIsInt: true).runTests();
+  new U65<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type66_test.dart b/tests/language/function_type/function_type66_test.dart
new file mode 100644
index 0000000..1de0e6a
--- /dev/null
+++ b/tests/language/function_type/function_type66_test.dart
@@ -0,0 +1,994 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {int x});
+typedef F1<T> = List<Function> Function(int y, {List<T> x});
+typedef F2<T> = List<T> Function(int, {core.List<core.int> x});
+typedef F3<T> = void Function({List<Function> x});
+typedef F4<T> = int Function(int x) Function<B extends core.int>();
+typedef F5<T> = int Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, [List<T>]) Function<B extends core.int>();
+typedef F7<T> = Function Function({Function x}) Function<B extends core.int>();
+typedef F8<T> = Function Function(List<T> x) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int x, [int])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function([int x]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(List<Function>)
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int, {Function x}) Function<B extends core.int>();
+typedef F17<T> = Function([List<T> x]) Function<B extends core.int>();
+typedef F18<T> = void Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F19<T> = void Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(int x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(Function x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+
+Function f0(int y, {int x = -1}) => throw 'uncalled';
+List<Function> f1(int y, {List<int> x = const []}) => throw 'uncalled';
+List<int> f2(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+void f3({List<Function> x = const []}) => throw 'uncalled';
+int Function(int x) f4<B extends core.int>() => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function(int, [List<int>]) f6<B extends core.int>() => throw 'uncalled';
+Function Function({Function x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function(List<int> x) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int, [Function x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x})
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function([int x]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(List<Function>) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, {Function x}) f16<B extends core.int>() => throw 'uncalled';
+Function([List<int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, [Function x]) f18<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(int x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(Function x) f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+
+class U66<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {int x}) x0;
+  late List<Function> Function(int y, {List<T> x}) x1;
+  late List<T> Function(int, {core.List<core.int> x}) x2;
+  late void Function({List<Function> x}) x3;
+  late int Function(int x) Function<B extends core.int>() x4;
+  late int Function(int y, [List<Function> x]) Function<B extends core.int>()
+      x5;
+  late int Function(int, [List<T>]) Function<B extends core.int>() x6;
+  late Function Function({Function x}) Function<B extends core.int>() x7;
+  late Function Function(List<T> x) Function<B extends core.int>() x8;
+  late List<Function> Function(int, [Function x]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function([core.List<core.int>])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int x, [int]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int y, {List<Function> x})
+      Function<B extends core.int>() x12;
+  late List<T> Function([int x]) Function<B extends core.int>() x13;
+  late List<T> Function(List<Function>) Function<B extends core.int>() x14;
+  late List<T> Function(int x, [List<T>]) Function<B extends core.int>() x15;
+  late Function(int, {Function x}) Function<B extends core.int>() x16;
+  late Function([List<T> x]) Function<B extends core.int>() x17;
+  late void Function(int y, [Function x]) Function<B extends core.int>() x18;
+  late void Function(int, [core.List<core.int>]) Function<B extends core.int>()
+      x19;
+  late Function Function<A>(int x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(Function x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(List<Function> x) Function<B extends core.int>() x22;
+
+  U66({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {int x = -1}) => throw 'uncalled';
+  List<Function> m1(int y, {List<T> x = const []}) => throw 'uncalled';
+  List<T> m2(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  void m3({List<Function> x = const []}) => throw 'uncalled';
+  int Function(int x) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, [List<T>]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function({Function x}) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(List<T> x) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x})
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function([int x]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(List<Function>) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, {Function x}) m16<B extends core.int>() => throw 'uncalled';
+  Function([List<T> x]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [Function x]) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(int x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(Function x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U66().runTests();
+  new U66<int>(tIsInt: true).runTests();
+  new U66<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type67_test.dart b/tests/language/function_type/function_type67_test.dart
new file mode 100644
index 0000000..0875a3d
--- /dev/null
+++ b/tests/language/function_type/function_type67_test.dart
@@ -0,0 +1,994 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(Function x);
+typedef F1<T> = List<Function> Function();
+typedef F2<T> = List<T> Function(int y, {core.List<core.int> x});
+typedef F3<T> = void Function(int, {List<Function> x});
+typedef F4<T> = int Function(int x) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function({Function x}) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int x, [int])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function([int x]) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function([List<T> x]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(int x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<T> Function<A>(Function x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = List<A> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+
+Function f0(Function x) => throw 'uncalled';
+List<Function> f1() => throw 'uncalled';
+List<int> f2(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+void f3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+int Function(int x) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, [List<int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function({Function x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(List<int> x) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [Function x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function([int x]) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(List<Function>) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, {Function x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function([List<int> x]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, [Function x]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(int x) f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(Function x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U67<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(Function x) x0;
+  late List<Function> Function() x1;
+  late List<T> Function(int y, {core.List<core.int> x}) x2;
+  late void Function(int, {List<Function> x}) x3;
+  late int Function(int x) Function<B extends core.int>(int x) x4;
+  late int Function(int y, [List<Function> x]) Function<B extends core.int>(
+      int x) x5;
+  late int Function(int, [List<T>]) Function<B extends core.int>(int x) x6;
+  late Function Function({Function x}) Function<B extends core.int>(int x) x7;
+  late Function Function(List<T> x) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int, [Function x]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function([core.List<core.int>])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int x, [int]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int y, {List<Function> x})
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function([int x]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(List<Function>) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+      x15;
+  late Function(int, {Function x}) Function<B extends core.int>(int x) x16;
+  late Function([List<T> x]) Function<B extends core.int>(int x) x17;
+  late void Function(int y, [Function x]) Function<B extends core.int>(int x)
+      x18;
+  late void Function(int, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(int x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(Function x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x22;
+
+  U67({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(Function x) => throw 'uncalled';
+  List<Function> m1() => throw 'uncalled';
+  List<T> m2(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  void m3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  int Function(int x) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [List<T>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({Function x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(List<T> x) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x})
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function([int x]) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(List<Function>) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, {Function x}) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([List<T> x]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, [Function x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(int x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(Function x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(Function x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(Function x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function()
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function());
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, {Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function([List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+        l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U67().runTests();
+  new U67<int>(tIsInt: true).runTests();
+  new U67<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type68_test.dart b/tests/language/function_type/function_type68_test.dart
new file mode 100644
index 0000000..1f28348
--- /dev/null
+++ b/tests/language/function_type/function_type68_test.dart
@@ -0,0 +1,915 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([Function x]);
+typedef F1<T> = core.List<core.int> Function(int x);
+typedef F2<T> = List<T> Function(List<T> x);
+typedef F3<T> = void Function(int y, {List<Function> x});
+typedef F4<T> = int Function([int x]) Function();
+typedef F5<T> = int Function(List<Function>) Function();
+typedef F6<T> = int Function(int x, [List<T>]) Function();
+typedef F7<T> = Function Function(int, {Function x}) Function();
+typedef F8<T> = Function Function([List<T> x]) Function();
+typedef F9<T> = List<Function> Function(int y, [Function x]) Function();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>]) Function();
+typedef F11<T> = core.List<core.int> Function({int x}) Function();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x) Function();
+typedef F13<T> = List<T> Function(int, [int x]) Function();
+typedef F14<T> = List<T> Function([List<Function>]) Function();
+typedef F15<T> = List<T> Function({List<T> x}) Function();
+typedef F16<T> = Function(int y, {Function x}) Function();
+typedef F17<T> = Function(int, [List<T> x]) Function();
+typedef F18<T> = void Function(Function) Function();
+typedef F19<T> = void Function(int x, [core.List<core.int>]) Function();
+typedef F20<T> = Function Function<A>(Function x) Function();
+typedef F21<T> = List<T> Function<A>(List<Function> x) Function();
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x) Function();
+
+Function f0([Function x = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x) => throw 'uncalled';
+List<int> f2(List<int> x) => throw 'uncalled';
+void f3(int y, {List<Function> x = const []}) => throw 'uncalled';
+int Function([int x]) f4() => throw 'uncalled';
+int Function(List<Function>) f5() => throw 'uncalled';
+int Function(int x, [List<int>]) f6() => throw 'uncalled';
+Function Function(int, {Function x}) f7() => throw 'uncalled';
+Function Function([List<int> x]) f8() => throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9() => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10() => throw 'uncalled';
+core.List<core.int> Function({int x}) f11() => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12() => throw 'uncalled';
+List<int> Function(int, [int x]) f13() => throw 'uncalled';
+List<int> Function([List<Function>]) f14() => throw 'uncalled';
+List<int> Function({List<int> x}) f15() => throw 'uncalled';
+Function(int y, {Function x}) f16() => throw 'uncalled';
+Function(int, [List<int> x]) f17() => throw 'uncalled';
+void Function(Function) f18() => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19() => throw 'uncalled';
+Function Function<A>(Function x) f20() => throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21() => throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22() => throw 'uncalled';
+
+class U68<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([Function x]) x0;
+  late core.List<core.int> Function(int x) x1;
+  late List<T> Function(List<T> x) x2;
+  late void Function(int y, {List<Function> x}) x3;
+  late int Function([int x]) Function() x4;
+  late int Function(List<Function>) Function() x5;
+  late int Function(int x, [List<T>]) Function() x6;
+  late Function Function(int, {Function x}) Function() x7;
+  late Function Function([List<T> x]) Function() x8;
+  late List<Function> Function(int y, [Function x]) Function() x9;
+  late List<Function> Function(int, [core.List<core.int>]) Function() x10;
+  late core.List<core.int> Function({int x}) Function() x11;
+  late core.List<core.int> Function(core.List<core.int> x) Function() x12;
+  late List<T> Function(int, [int x]) Function() x13;
+  late List<T> Function([List<Function>]) Function() x14;
+  late List<T> Function({List<T> x}) Function() x15;
+  late Function(int y, {Function x}) Function() x16;
+  late Function(int, [List<T> x]) Function() x17;
+  late void Function(Function) Function() x18;
+  late void Function(int x, [core.List<core.int>]) Function() x19;
+  late Function Function<A>(Function x) Function() x20;
+  late List<T> Function<A>(List<Function> x) Function() x21;
+  late List<A> Function<A>(core.List<core.int> x) Function() x22;
+
+  U68({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([Function x = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x) => throw 'uncalled';
+  List<T> m2(List<T> x) => throw 'uncalled';
+  void m3(int y, {List<Function> x = const []}) => throw 'uncalled';
+  int Function([int x]) m4() => throw 'uncalled';
+  int Function(List<Function>) m5() => throw 'uncalled';
+  int Function(int x, [List<T>]) m6() => throw 'uncalled';
+  Function Function(int, {Function x}) m7() => throw 'uncalled';
+  Function Function([List<T> x]) m8() => throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9() => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>]) m10() => throw 'uncalled';
+  core.List<core.int> Function({int x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x) m12() => throw 'uncalled';
+  List<T> Function(int, [int x]) m13() => throw 'uncalled';
+  List<T> Function([List<Function>]) m14() => throw 'uncalled';
+  List<T> Function({List<T> x}) m15() => throw 'uncalled';
+  Function(int y, {Function x}) m16() => throw 'uncalled';
+  Function(int, [List<T> x]) m17() => throw 'uncalled';
+  void Function(Function) m18() => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19() => throw 'uncalled';
+  Function Function<A>(Function x) m20() => throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21() => throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<T> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<T> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int x]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function>) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U68().runTests();
+  new U68<int>(tIsInt: true).runTests();
+  new U68<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type69_test.dart b/tests/language/function_type/function_type69_test.dart
new file mode 100644
index 0000000..ad7b5cb
--- /dev/null
+++ b/tests/language/function_type/function_type69_test.dart
@@ -0,0 +1,922 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [Function x]);
+typedef F1<T> = core.List<core.int> Function([int x]);
+typedef F2<T> = List<T> Function([List<T> x]);
+typedef F3<T> = void Function(core.List<core.int> x);
+typedef F4<T> = int Function([int x]) Function(int x);
+typedef F5<T> = int Function(List<Function>) Function(int x);
+typedef F6<T> = int Function(int x, [List<T>]) Function(int x);
+typedef F7<T> = Function Function(int, {Function x}) Function(int x);
+typedef F8<T> = Function Function([List<T> x]) Function(int x);
+typedef F9<T> = List<Function> Function(int y, [Function x]) Function(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function({int x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x) Function(
+    int x);
+typedef F13<T> = List<T> Function(int, [int x]) Function(int x);
+typedef F14<T> = List<T> Function([List<Function>]) Function(int x);
+typedef F15<T> = List<T> Function({List<T> x}) Function(int x);
+typedef F16<T> = Function(int y, {Function x}) Function(int x);
+typedef F17<T> = Function(int, [List<T> x]) Function(int x);
+typedef F18<T> = void Function(Function) Function(int x);
+typedef F19<T> = void Function(int x, [core.List<core.int>]) Function(int x);
+typedef F20<T> = Function Function<A>(Function x) Function(int x);
+typedef F21<T> = List<T> Function<A>(List<Function> x) Function(int x);
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x) Function(int x);
+
+Function f0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1([int x = -1]) => throw 'uncalled';
+List<int> f2([List<int> x = const []]) => throw 'uncalled';
+void f3(core.List<core.int> x) => throw 'uncalled';
+int Function([int x]) f4(int x) => throw 'uncalled';
+int Function(List<Function>) f5(int x) => throw 'uncalled';
+int Function(int x, [List<int>]) f6(int x) => throw 'uncalled';
+Function Function(int, {Function x}) f7(int x) => throw 'uncalled';
+Function Function([List<int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({int x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int x]) f13(int x) => throw 'uncalled';
+List<int> Function([List<Function>]) f14(int x) => throw 'uncalled';
+List<int> Function({List<int> x}) f15(int x) => throw 'uncalled';
+Function(int y, {Function x}) f16(int x) => throw 'uncalled';
+Function(int, [List<int> x]) f17(int x) => throw 'uncalled';
+void Function(Function) f18(int x) => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19(int x) => throw 'uncalled';
+Function Function<A>(Function x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22(int x) => throw 'uncalled';
+
+class U69<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [Function x]) x0;
+  late core.List<core.int> Function([int x]) x1;
+  late List<T> Function([List<T> x]) x2;
+  late void Function(core.List<core.int> x) x3;
+  late int Function([int x]) Function(int x) x4;
+  late int Function(List<Function>) Function(int x) x5;
+  late int Function(int x, [List<T>]) Function(int x) x6;
+  late Function Function(int, {Function x}) Function(int x) x7;
+  late Function Function([List<T> x]) Function(int x) x8;
+  late List<Function> Function(int y, [Function x]) Function(int x) x9;
+  late List<Function> Function(int, [core.List<core.int>]) Function(int x) x10;
+  late core.List<core.int> Function({int x}) Function(int x) x11;
+  late core.List<core.int> Function(core.List<core.int> x) Function(int x) x12;
+  late List<T> Function(int, [int x]) Function(int x) x13;
+  late List<T> Function([List<Function>]) Function(int x) x14;
+  late List<T> Function({List<T> x}) Function(int x) x15;
+  late Function(int y, {Function x}) Function(int x) x16;
+  late Function(int, [List<T> x]) Function(int x) x17;
+  late void Function(Function) Function(int x) x18;
+  late void Function(int x, [core.List<core.int>]) Function(int x) x19;
+  late Function Function<A>(Function x) Function(int x) x20;
+  late List<T> Function<A>(List<Function> x) Function(int x) x21;
+  late List<A> Function<A>(core.List<core.int> x) Function(int x) x22;
+
+  U69({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1([int x = -1]) => throw 'uncalled';
+  List<T> m2([List<T> x = const []]) => throw 'uncalled';
+  void m3(core.List<core.int> x) => throw 'uncalled';
+  int Function([int x]) m4(int x) => throw 'uncalled';
+  int Function(List<Function>) m5(int x) => throw 'uncalled';
+  int Function(int x, [List<T>]) m6(int x) => throw 'uncalled';
+  Function Function(int, {Function x}) m7(int x) => throw 'uncalled';
+  Function Function([List<T> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({int x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int x]) m13(int x) => throw 'uncalled';
+  List<T> Function([List<Function>]) m14(int x) => throw 'uncalled';
+  List<T> Function({List<T> x}) m15(int x) => throw 'uncalled';
+  Function(int y, {Function x}) m16(int x) => throw 'uncalled';
+  Function(int, [List<T> x]) m17(int x) => throw 'uncalled';
+  void Function(Function) m18(int x) => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19(int x) => throw 'uncalled';
+  Function Function<A>(Function x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(core.List<core.int> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int> x)
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U69().runTests();
+  new U69<int>(tIsInt: true).runTests();
+  new U69<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type6_test.dart b/tests/language/function_type/function_type6_test.dart
new file mode 100644
index 0000000..7939e63
--- /dev/null
+++ b/tests/language/function_type/function_type6_test.dart
@@ -0,0 +1,981 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [int]);
+typedef F1<T> = Function Function(int, [List<T>]);
+typedef F2<T> = core.List<core.int> Function([core.List<core.int>]);
+typedef F3<T> = Function(List<Function>);
+typedef F4<T> = Function Function<A>(A x);
+typedef F5<T> = int Function(int y, {int x}) Function<B extends core.int>();
+typedef F6<T> = int Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int) Function<B extends core.int>();
+typedef F8<T> = Function Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F9<T> = Function Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(List<T>)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [Function])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(Function x) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function([int]) Function<B extends core.int>();
+typedef F17<T> = Function({List<Function> x}) Function<B extends core.int>();
+typedef F18<T> = Function() Function<B extends core.int>();
+typedef F19<T> = void Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F20<T> = void Function([List<T>]) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F23<T> = void Function<A>(List<T> x) Function<B extends core.int>();
+
+int f0(int x0, [int x1 = -1]) => throw 'uncalled';
+Function f1(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f2([core.List<core.int> x0 = const []]) => throw 'uncalled';
+f3(List<Function> x0) => throw 'uncalled';
+Function f4<A>(A x) => throw 'uncalled';
+int Function(int y, {int x}) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, {List<int> x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<Function> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(List<int>) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x})
+    f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(Function x) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([int]) f16<B extends core.int>() => throw 'uncalled';
+Function({List<Function> x}) f17<B extends core.int>() => throw 'uncalled';
+Function() f18<B extends core.int>() => throw 'uncalled';
+void Function(int, [List<Function> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function([List<int>]) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>(core.List<core.int> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+void Function<A>(List<int> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U6<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [int]) x0;
+  late Function Function(int, [List<T>]) x1;
+  late core.List<core.int> Function([core.List<core.int>]) x2;
+  late Function(List<Function>) x3;
+  late Function Function<A>(A x) x4;
+  late int Function(int y, {int x}) Function<B extends core.int>() x5;
+  late int Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+      x6;
+  late Function Function(int) Function<B extends core.int>() x7;
+  late Function Function(int x, [List<Function>]) Function<B extends core.int>()
+      x8;
+  late Function Function(int y, {List<T> x}) Function<B extends core.int>() x9;
+  late List<Function> Function([List<Function> x])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(List<T>) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [Function])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function(Function x) Function<B extends core.int>() x14;
+  late List<T> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x15;
+  late Function([int]) Function<B extends core.int>() x16;
+  late Function({List<Function> x}) Function<B extends core.int>() x17;
+  late Function() Function<B extends core.int>() x18;
+  late void Function(int, [List<Function> x]) Function<B extends core.int>()
+      x19;
+  late void Function([List<T>]) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(List<Function> x)
+      Function<B extends core.int>() x21;
+  late Function<A>(core.List<core.int> x) Function<B extends core.int>() x22;
+  late void Function<A>(List<T> x) Function<B extends core.int>() x23;
+
+  U6({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [int x1 = -1]) => throw 'uncalled';
+  Function m1(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m2([core.List<core.int> x0 = const []]) =>
+      throw 'uncalled';
+  m3(List<Function> x0) => throw 'uncalled';
+  Function m4<A>(A x) => throw 'uncalled';
+  int Function(int y, {int x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(List<T>) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x})
+      m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(Function x) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([int]) m16<B extends core.int>() => throw 'uncalled';
+  Function({List<Function> x}) m17<B extends core.int>() => throw 'uncalled';
+  Function() m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([List<T>]) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+  void Function<A>(List<T> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(List<Function>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<Function>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {int x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function<B extends core.int>()
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function({List<Function> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U6().runTests();
+  new U6<int>(tIsInt: true).runTests();
+  new U6<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type70_test.dart b/tests/language/function_type/function_type70_test.dart
new file mode 100644
index 0000000..1c44dd1
--- /dev/null
+++ b/tests/language/function_type/function_type70_test.dart
@@ -0,0 +1,968 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [Function x]);
+typedef F1<T> = core.List<core.int> Function(int, [int x]);
+typedef F2<T> = List<T> Function(int, [List<T> x]);
+typedef F3<T> = void Function([core.List<core.int> x]);
+typedef F4<T> = int Function([int x]) Function<B extends core.int>();
+typedef F5<T> = int Function(List<Function>) Function<B extends core.int>();
+typedef F6<T> = int Function(int x, [List<T>]) Function<B extends core.int>();
+typedef F7<T> = Function Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F8<T> = Function Function([List<T> x]) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function({int x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int, [int x]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function([List<Function>])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function({List<T> x}) Function<B extends core.int>();
+typedef F16<T> = Function(int y, {Function x}) Function<B extends core.int>();
+typedef F17<T> = Function(int, [List<T> x]) Function<B extends core.int>();
+typedef F18<T> = void Function(Function) Function<B extends core.int>();
+typedef F19<T> = void Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(Function x)
+    Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+
+Function f0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [int x = -1]) => throw 'uncalled';
+List<int> f2(int x0, [List<int> x = const []]) => throw 'uncalled';
+void f3([core.List<core.int> x = const []]) => throw 'uncalled';
+int Function([int x]) f4<B extends core.int>() => throw 'uncalled';
+int Function(List<Function>) f5<B extends core.int>() => throw 'uncalled';
+int Function(int x, [List<int>]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, {Function x}) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([List<int> x]) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({int x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [int x]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function([List<Function>]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function({List<int> x}) f15<B extends core.int>() => throw 'uncalled';
+Function(int y, {Function x}) f16<B extends core.int>() => throw 'uncalled';
+Function(int, [List<int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function(Function) f18<B extends core.int>() => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(Function x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+
+class U70<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [Function x]) x0;
+  late core.List<core.int> Function(int, [int x]) x1;
+  late List<T> Function(int, [List<T> x]) x2;
+  late void Function([core.List<core.int> x]) x3;
+  late int Function([int x]) Function<B extends core.int>() x4;
+  late int Function(List<Function>) Function<B extends core.int>() x5;
+  late int Function(int x, [List<T>]) Function<B extends core.int>() x6;
+  late Function Function(int, {Function x}) Function<B extends core.int>() x7;
+  late Function Function([List<T> x]) Function<B extends core.int>() x8;
+  late List<Function> Function(int y, [Function x])
+      Function<B extends core.int>() x9;
+  late List<Function> Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function({int x}) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(core.List<core.int> x)
+      Function<B extends core.int>() x12;
+  late List<T> Function(int, [int x]) Function<B extends core.int>() x13;
+  late List<T> Function([List<Function>]) Function<B extends core.int>() x14;
+  late List<T> Function({List<T> x}) Function<B extends core.int>() x15;
+  late Function(int y, {Function x}) Function<B extends core.int>() x16;
+  late Function(int, [List<T> x]) Function<B extends core.int>() x17;
+  late void Function(Function) Function<B extends core.int>() x18;
+  late void Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x19;
+  late Function Function<A>(Function x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(List<Function> x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x22;
+
+  U70({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [int x = -1]) => throw 'uncalled';
+  List<T> m2(int x0, [List<T> x = const []]) => throw 'uncalled';
+  void m3([core.List<core.int> x = const []]) => throw 'uncalled';
+  int Function([int x]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(List<Function>) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int x, [List<T>]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, {Function x}) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([List<T> x]) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function({int x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x)
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, [int x]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function([List<Function>]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function({List<T> x}) m15<B extends core.int>() => throw 'uncalled';
+  Function(int y, {Function x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, [List<T> x]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(Function) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(Function x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int x, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+        l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U70().runTests();
+  new U70<int>(tIsInt: true).runTests();
+  new U70<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type71_test.dart b/tests/language/function_type/function_type71_test.dart
new file mode 100644
index 0000000..61df998
--- /dev/null
+++ b/tests/language/function_type/function_type71_test.dart
@@ -0,0 +1,997 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(Function);
+typedef F1<T> = core.List<core.int> Function(int y, [int x]);
+typedef F2<T> = List<T> Function(int y, [List<T> x]);
+typedef F3<T> = void Function(int, [core.List<core.int> x]);
+typedef F4<T> = int Function([int x]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int x, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function([List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function({int x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int, [int x]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function({List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int y, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int, [List<T> x]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(Function) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(Function x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<T> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+
+Function f0(Function x0) => throw 'uncalled';
+core.List<core.int> f1(int y, [int x = -1]) => throw 'uncalled';
+List<int> f2(int y, [List<int> x = const []]) => throw 'uncalled';
+void f3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+int Function([int x]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(List<Function>) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int x, [List<int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {Function x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({int x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int x]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([List<Function>]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function({List<int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, {Function x}) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [List<int> x]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(Function) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(Function x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U71<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(Function) x0;
+  late core.List<core.int> Function(int y, [int x]) x1;
+  late List<T> Function(int y, [List<T> x]) x2;
+  late void Function(int, [core.List<core.int> x]) x3;
+  late int Function([int x]) Function<B extends core.int>(int x) x4;
+  late int Function(List<Function>) Function<B extends core.int>(int x) x5;
+  late int Function(int x, [List<T>]) Function<B extends core.int>(int x) x6;
+  late Function Function(int, {Function x}) Function<B extends core.int>(int x)
+      x7;
+  late Function Function([List<T> x]) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int y, [Function x])
+      Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function({int x}) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(core.List<core.int> x)
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int, [int x]) Function<B extends core.int>(int x) x13;
+  late List<T> Function([List<Function>]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function({List<T> x}) Function<B extends core.int>(int x) x15;
+  late Function(int y, {Function x}) Function<B extends core.int>(int x) x16;
+  late Function(int, [List<T> x]) Function<B extends core.int>(int x) x17;
+  late void Function(Function) Function<B extends core.int>(int x) x18;
+  late void Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(Function x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x21;
+  late List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x22;
+
+  U71({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(Function x0) => throw 'uncalled';
+  core.List<core.int> m1(int y, [int x = -1]) => throw 'uncalled';
+  List<T> m2(int y, [List<T> x = const []]) => throw 'uncalled';
+  void m3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  int Function([int x]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(List<Function>) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int x, [List<T>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {Function x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<T> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({int x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int x]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<Function>]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function({List<T> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {Function x}) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [List<T> x]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(Function) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(Function x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(Function)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(Function));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(List<Function>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+        int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U71().runTests();
+  new U71<int>(tIsInt: true).runTests();
+  new U71<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type72_test.dart b/tests/language/function_type/function_type72_test.dart
new file mode 100644
index 0000000..b33b49b
--- /dev/null
+++ b/tests/language/function_type/function_type72_test.dart
@@ -0,0 +1,942 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([Function]);
+typedef F1<T> = core.List<core.int> Function(int);
+typedef F2<T> = List<T> Function(List<T>);
+typedef F3<T> = void Function(int y, [core.List<core.int> x]);
+typedef F4<T> = int Function(int, [int x]) Function();
+typedef F5<T> = int Function([List<Function>]) Function();
+typedef F6<T> = int Function({List<T> x}) Function();
+typedef F7<T> = Function Function(int y, {Function x}) Function();
+typedef F8<T> = Function Function(int, [List<T> x]) Function();
+typedef F9<T> = List<Function> Function(Function) Function();
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>])
+    Function();
+typedef F11<T> = core.List<core.int> Function(int, {int x}) Function();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x])
+    Function();
+typedef F13<T> = List<T> Function(int y, [int x]) Function();
+typedef F14<T> = List<T> Function(int, [List<Function>]) Function();
+typedef F15<T> = List<T> Function(int, {List<T> x}) Function();
+typedef F16<T> = Function(List<Function> x) Function();
+typedef F17<T> = Function(int y, [List<T> x]) Function();
+typedef F18<T> = void Function([Function]) Function();
+typedef F19<T> = void Function({core.List<core.int> x}) Function();
+typedef F20<T> = Function Function<A>(List<Function> x) Function();
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x) Function();
+typedef F22<T> = List<A> Function<A>(List<T> x) Function();
+
+Function f0([Function x0 = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x0) => throw 'uncalled';
+List<int> f2(List<int> x0) => throw 'uncalled';
+void f3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+int Function(int, [int x]) f4() => throw 'uncalled';
+int Function([List<Function>]) f5() => throw 'uncalled';
+int Function({List<int> x}) f6() => throw 'uncalled';
+Function Function(int y, {Function x}) f7() => throw 'uncalled';
+Function Function(int, [List<int> x]) f8() => throw 'uncalled';
+List<Function> Function(Function) f9() => throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>]) f10() => throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11() => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x]) f12() => throw 'uncalled';
+List<int> Function(int y, [int x]) f13() => throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14() => throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15() => throw 'uncalled';
+Function(List<Function> x) f16() => throw 'uncalled';
+Function(int y, [List<int> x]) f17() => throw 'uncalled';
+void Function([Function]) f18() => throw 'uncalled';
+void Function({core.List<core.int> x}) f19() => throw 'uncalled';
+Function Function<A>(List<Function> x) f20() => throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21() => throw 'uncalled';
+List<A> Function<A>(List<int> x) f22() => throw 'uncalled';
+
+class U72<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([Function]) x0;
+  late core.List<core.int> Function(int) x1;
+  late List<T> Function(List<T>) x2;
+  late void Function(int y, [core.List<core.int> x]) x3;
+  late int Function(int, [int x]) Function() x4;
+  late int Function([List<Function>]) Function() x5;
+  late int Function({List<T> x}) Function() x6;
+  late Function Function(int y, {Function x}) Function() x7;
+  late Function Function(int, [List<T> x]) Function() x8;
+  late List<Function> Function(Function) Function() x9;
+  late List<Function> Function(int x, [core.List<core.int>]) Function() x10;
+  late core.List<core.int> Function(int, {int x}) Function() x11;
+  late core.List<core.int> Function([core.List<core.int> x]) Function() x12;
+  late List<T> Function(int y, [int x]) Function() x13;
+  late List<T> Function(int, [List<Function>]) Function() x14;
+  late List<T> Function(int, {List<T> x}) Function() x15;
+  late Function(List<Function> x) Function() x16;
+  late Function(int y, [List<T> x]) Function() x17;
+  late void Function([Function]) Function() x18;
+  late void Function({core.List<core.int> x}) Function() x19;
+  late Function Function<A>(List<Function> x) Function() x20;
+  late List<T> Function<A>(core.List<core.int> x) Function() x21;
+  late List<A> Function<A>(List<T> x) Function() x22;
+
+  U72({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([Function x0 = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x0) => throw 'uncalled';
+  List<T> m2(List<T> x0) => throw 'uncalled';
+  void m3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  int Function(int, [int x]) m4() => throw 'uncalled';
+  int Function([List<Function>]) m5() => throw 'uncalled';
+  int Function({List<T> x}) m6() => throw 'uncalled';
+  Function Function(int y, {Function x}) m7() => throw 'uncalled';
+  Function Function(int, [List<T> x]) m8() => throw 'uncalled';
+  List<Function> Function(Function) m9() => throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>]) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11() => throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x]) m12() =>
+      throw 'uncalled';
+  List<T> Function(int y, [int x]) m13() => throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14() => throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15() => throw 'uncalled';
+  Function(List<Function> x) m16() => throw 'uncalled';
+  Function(int y, [List<T> x]) m17() => throw 'uncalled';
+  void Function([Function]) m18() => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19() => throw 'uncalled';
+  Function Function<A>(List<Function> x) m20() => throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21() => throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<T>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<T>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U72().runTests();
+  new U72<int>(tIsInt: true).runTests();
+  new U72<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type73_test.dart b/tests/language/function_type/function_type73_test.dart
new file mode 100644
index 0000000..605428e
--- /dev/null
+++ b/tests/language/function_type/function_type73_test.dart
@@ -0,0 +1,951 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [Function]);
+typedef F1<T> = core.List<core.int> Function([int]);
+typedef F2<T> = List<T> Function([List<T>]);
+typedef F3<T> = void Function(core.List<core.int>);
+typedef F4<T> = int Function(int, [int x]) Function(int x);
+typedef F5<T> = int Function([List<Function>]) Function(int x);
+typedef F6<T> = int Function({List<T> x}) Function(int x);
+typedef F7<T> = Function Function(int y, {Function x}) Function(int x);
+typedef F8<T> = Function Function(int, [List<T> x]) Function(int x);
+typedef F9<T> = List<Function> Function(Function) Function(int x);
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int, {int x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x]) Function(
+    int x);
+typedef F13<T> = List<T> Function(int y, [int x]) Function(int x);
+typedef F14<T> = List<T> Function(int, [List<Function>]) Function(int x);
+typedef F15<T> = List<T> Function(int, {List<T> x}) Function(int x);
+typedef F16<T> = Function(List<Function> x) Function(int x);
+typedef F17<T> = Function(int y, [List<T> x]) Function(int x);
+typedef F18<T> = void Function([Function]) Function(int x);
+typedef F19<T> = void Function({core.List<core.int> x}) Function(int x);
+typedef F20<T> = Function Function<A>(List<Function> x) Function(int x);
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x) Function(int x);
+typedef F22<T> = List<A> Function<A>(List<T> x) Function(int x);
+
+Function f0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1([int x0 = -1]) => throw 'uncalled';
+List<int> f2([List<int> x0 = const []]) => throw 'uncalled';
+void f3(core.List<core.int> x0) => throw 'uncalled';
+int Function(int, [int x]) f4(int x) => throw 'uncalled';
+int Function([List<Function>]) f5(int x) => throw 'uncalled';
+int Function({List<int> x}) f6(int x) => throw 'uncalled';
+Function Function(int y, {Function x}) f7(int x) => throw 'uncalled';
+Function Function(int, [List<int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(Function) f9(int x) => throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [int x]) f13(int x) => throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14(int x) => throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15(int x) => throw 'uncalled';
+Function(List<Function> x) f16(int x) => throw 'uncalled';
+Function(int y, [List<int> x]) f17(int x) => throw 'uncalled';
+void Function([Function]) f18(int x) => throw 'uncalled';
+void Function({core.List<core.int> x}) f19(int x) => throw 'uncalled';
+Function Function<A>(List<Function> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(List<int> x) f22(int x) => throw 'uncalled';
+
+class U73<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [Function]) x0;
+  late core.List<core.int> Function([int]) x1;
+  late List<T> Function([List<T>]) x2;
+  late void Function(core.List<core.int>) x3;
+  late int Function(int, [int x]) Function(int x) x4;
+  late int Function([List<Function>]) Function(int x) x5;
+  late int Function({List<T> x}) Function(int x) x6;
+  late Function Function(int y, {Function x}) Function(int x) x7;
+  late Function Function(int, [List<T> x]) Function(int x) x8;
+  late List<Function> Function(Function) Function(int x) x9;
+  late List<Function> Function(int x, [core.List<core.int>]) Function(int x)
+      x10;
+  late core.List<core.int> Function(int, {int x}) Function(int x) x11;
+  late core.List<core.int> Function([core.List<core.int> x]) Function(int x)
+      x12;
+  late List<T> Function(int y, [int x]) Function(int x) x13;
+  late List<T> Function(int, [List<Function>]) Function(int x) x14;
+  late List<T> Function(int, {List<T> x}) Function(int x) x15;
+  late Function(List<Function> x) Function(int x) x16;
+  late Function(int y, [List<T> x]) Function(int x) x17;
+  late void Function([Function]) Function(int x) x18;
+  late void Function({core.List<core.int> x}) Function(int x) x19;
+  late Function Function<A>(List<Function> x) Function(int x) x20;
+  late List<T> Function<A>(core.List<core.int> x) Function(int x) x21;
+  late List<A> Function<A>(List<T> x) Function(int x) x22;
+
+  U73({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1([int x0 = -1]) => throw 'uncalled';
+  List<T> m2([List<T> x0 = const []]) => throw 'uncalled';
+  void m3(core.List<core.int> x0) => throw 'uncalled';
+  int Function(int, [int x]) m4(int x) => throw 'uncalled';
+  int Function([List<Function>]) m5(int x) => throw 'uncalled';
+  int Function({List<T> x}) m6(int x) => throw 'uncalled';
+  Function Function(int y, {Function x}) m7(int x) => throw 'uncalled';
+  Function Function(int, [List<T> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(Function) m9(int x) => throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [int x]) m13(int x) => throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15(int x) => throw 'uncalled';
+  Function(List<Function> x) m16(int x) => throw 'uncalled';
+  Function(int y, [List<T> x]) m17(int x) => throw 'uncalled';
+  void Function([Function]) m18(int x) => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19(int x) => throw 'uncalled';
+  Function Function<A>(List<Function> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(core.List<core.int>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(core.List<core.int>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U73().runTests();
+  new U73<int>(tIsInt: true).runTests();
+  new U73<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type74_test.dart b/tests/language/function_type/function_type74_test.dart
new file mode 100644
index 0000000..110832e
--- /dev/null
+++ b/tests/language/function_type/function_type74_test.dart
@@ -0,0 +1,1001 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [Function]);
+typedef F1<T> = core.List<core.int> Function(int, [int]);
+typedef F2<T> = List<T> Function(int, [List<T>]);
+typedef F3<T> = void Function([core.List<core.int>]);
+typedef F4<T> = int Function(int, [int x]) Function<B extends core.int>();
+typedef F5<T> = int Function([List<Function>]) Function<B extends core.int>();
+typedef F6<T> = int Function({List<T> x}) Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(Function)
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, {int x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function(List<Function> x) Function<B extends core.int>();
+typedef F17<T> = Function(int y, [List<T> x]) Function<B extends core.int>();
+typedef F18<T> = void Function([Function]) Function<B extends core.int>();
+typedef F19<T> = void Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(List<T> x) Function<B extends core.int>();
+
+Function f0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [int x1 = -1]) => throw 'uncalled';
+List<int> f2(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+void f3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+int Function(int, [int x]) f4<B extends core.int>() => throw 'uncalled';
+int Function([List<Function>]) f5<B extends core.int>() => throw 'uncalled';
+int Function({List<int> x}) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int y, {Function x}) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [List<int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(Function) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>])
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, [int x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(List<Function> x) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, [List<int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function([Function]) f18<B extends core.int>() => throw 'uncalled';
+void Function({core.List<core.int> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(List<Function> x) f20<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>(List<int> x) f22<B extends core.int>() => throw 'uncalled';
+
+class U74<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [Function]) x0;
+  late core.List<core.int> Function(int, [int]) x1;
+  late List<T> Function(int, [List<T>]) x2;
+  late void Function([core.List<core.int>]) x3;
+  late int Function(int, [int x]) Function<B extends core.int>() x4;
+  late int Function([List<Function>]) Function<B extends core.int>() x5;
+  late int Function({List<T> x}) Function<B extends core.int>() x6;
+  late Function Function(int y, {Function x}) Function<B extends core.int>() x7;
+  late Function Function(int, [List<T> x]) Function<B extends core.int>() x8;
+  late List<Function> Function(Function) Function<B extends core.int>() x9;
+  late List<Function> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, {int x}) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function([core.List<core.int> x])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int y, [int x]) Function<B extends core.int>() x13;
+  late List<T> Function(int, [List<Function>]) Function<B extends core.int>()
+      x14;
+  late List<T> Function(int, {List<T> x}) Function<B extends core.int>() x15;
+  late Function(List<Function> x) Function<B extends core.int>() x16;
+  late Function(int y, [List<T> x]) Function<B extends core.int>() x17;
+  late void Function([Function]) Function<B extends core.int>() x18;
+  late void Function({core.List<core.int> x}) Function<B extends core.int>()
+      x19;
+  late Function Function<A>(List<Function> x) Function<B extends core.int>()
+      x20;
+  late List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x21;
+  late List<A> Function<A>(List<T> x) Function<B extends core.int>() x22;
+
+  U74({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [int x1 = -1]) => throw 'uncalled';
+  List<T> m2(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  void m3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  int Function(int, [int x]) m4<B extends core.int>() => throw 'uncalled';
+  int Function([List<Function>]) m5<B extends core.int>() => throw 'uncalled';
+  int Function({List<T> x}) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, {Function x}) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [List<T> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(Function) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, [int x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(List<Function> x) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, [List<T> x]) m17<B extends core.int>() => throw 'uncalled';
+  void Function([Function]) m18<B extends core.int>() => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(List<Function> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int y, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U74().runTests();
+  new U74<int>(tIsInt: true).runTests();
+  new U74<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type75_test.dart b/tests/language/function_type/function_type75_test.dart
new file mode 100644
index 0000000..0f7938c
--- /dev/null
+++ b/tests/language/function_type/function_type75_test.dart
@@ -0,0 +1,1022 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({Function x});
+typedef F1<T> = core.List<core.int> Function(int x, [int]);
+typedef F2<T> = List<T> Function(int x, [List<T>]);
+typedef F3<T> = void Function(int, [core.List<core.int>]);
+typedef F4<T> = int Function(int, [int x]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function([List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function({List<T> x}) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(Function) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, {int x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(List<Function> x) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int y, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function([Function]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+
+Function f0({Function x = _voidFunction}) => throw 'uncalled';
+core.List<core.int> f1(int x, [int x0 = -1]) => throw 'uncalled';
+List<int> f2(int x, [List<int> x0 = const []]) => throw 'uncalled';
+void f3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+int Function(int, [int x]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function([List<Function>]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function({List<int> x}) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, {Function x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [List<int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(Function) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [int x]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(List<Function> x) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, [List<int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([Function]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function({core.List<core.int> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(List<Function> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(List<int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U75<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({Function x}) x0;
+  late core.List<core.int> Function(int x, [int]) x1;
+  late List<T> Function(int x, [List<T>]) x2;
+  late void Function(int, [core.List<core.int>]) x3;
+  late int Function(int, [int x]) Function<B extends core.int>(int x) x4;
+  late int Function([List<Function>]) Function<B extends core.int>(int x) x5;
+  late int Function({List<T> x}) Function<B extends core.int>(int x) x6;
+  late Function Function(int y, {Function x}) Function<B extends core.int>(
+      int x) x7;
+  late Function Function(int, [List<T> x]) Function<B extends core.int>(int x)
+      x8;
+  late List<Function> Function(Function) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int, {int x}) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([core.List<core.int> x])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int y, [int x]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, [List<Function>]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+      x15;
+  late Function(List<Function> x) Function<B extends core.int>(int x) x16;
+  late Function(int y, [List<T> x]) Function<B extends core.int>(int x) x17;
+  late void Function([Function]) Function<B extends core.int>(int x) x18;
+  late void Function({core.List<core.int> x}) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(List<Function> x) Function<B extends core.int>(
+      int x) x20;
+  late List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x21;
+  late List<A> Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
+
+  U75({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({Function x = _voidFunction}) => throw 'uncalled';
+  core.List<core.int> m1(int x, [int x0 = -1]) => throw 'uncalled';
+  List<T> m2(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  void m3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  int Function(int, [int x]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function([List<Function>]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function({List<T> x}) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int y, {Function x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [List<T> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(Function) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [int x]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(List<Function> x) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, [List<T> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([Function]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(List<Function> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function({List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function<B extends core.int>(int x)
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function<B extends core.int>(int x)
+        l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U75().runTests();
+  new U75<int>(tIsInt: true).runTests();
+  new U75<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type76_test.dart b/tests/language/function_type/function_type76_test.dart
new file mode 100644
index 0000000..0465785
--- /dev/null
+++ b/tests/language/function_type/function_type76_test.dart
@@ -0,0 +1,921 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {Function x});
+typedef F1<T> = core.List<core.int> Function({int x});
+typedef F2<T> = List<T> Function({List<T> x});
+typedef F3<T> = void Function(int x, [core.List<core.int>]);
+typedef F4<T> = int Function(int y, [int x]) Function();
+typedef F5<T> = int Function(int, [List<Function>]) Function();
+typedef F6<T> = int Function(int, {List<T> x}) Function();
+typedef F7<T> = Function Function(List<Function> x) Function();
+typedef F8<T> = Function Function(int y, [List<T> x]) Function();
+typedef F9<T> = List<Function> Function([Function]) Function();
+typedef F10<T> = List<Function> Function({core.List<core.int> x}) Function();
+typedef F11<T> = core.List<core.int> Function(int y, {int x}) Function();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function();
+typedef F13<T> = List<T> Function(int) Function();
+typedef F14<T> = List<T> Function(int x, [List<Function>]) Function();
+typedef F15<T> = List<T> Function(int y, {List<T> x}) Function();
+typedef F16<T> = Function([List<Function> x]) Function();
+typedef F17<T> = Function(List<T>) Function();
+typedef F18<T> = void Function(int, [Function]) Function();
+typedef F19<T> = void Function(int, {core.List<core.int> x}) Function();
+typedef F20<T> = Function Function<A>(core.List<core.int> x) Function();
+typedef F21<T> = List<T> Function<A>(List<T> x) Function();
+typedef F22<T> = List<A> Function<A>() Function();
+
+Function f0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+core.List<core.int> f1({int x = -1}) => throw 'uncalled';
+List<int> f2({List<int> x = const []}) => throw 'uncalled';
+void f3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+int Function(int y, [int x]) f4() => throw 'uncalled';
+int Function(int, [List<Function>]) f5() => throw 'uncalled';
+int Function(int, {List<int> x}) f6() => throw 'uncalled';
+Function Function(List<Function> x) f7() => throw 'uncalled';
+Function Function(int y, [List<int> x]) f8() => throw 'uncalled';
+List<Function> Function([Function]) f9() => throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10() => throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x]) f12() =>
+    throw 'uncalled';
+List<int> Function(int) f13() => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14() => throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15() => throw 'uncalled';
+Function([List<Function> x]) f16() => throw 'uncalled';
+Function(List<int>) f17() => throw 'uncalled';
+void Function(int, [Function]) f18() => throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19() => throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20() => throw 'uncalled';
+List<int> Function<A>(List<int> x) f21() => throw 'uncalled';
+List<A> Function<A>() f22() => throw 'uncalled';
+
+class U76<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {Function x}) x0;
+  late core.List<core.int> Function({int x}) x1;
+  late List<T> Function({List<T> x}) x2;
+  late void Function(int x, [core.List<core.int>]) x3;
+  late int Function(int y, [int x]) Function() x4;
+  late int Function(int, [List<Function>]) Function() x5;
+  late int Function(int, {List<T> x}) Function() x6;
+  late Function Function(List<Function> x) Function() x7;
+  late Function Function(int y, [List<T> x]) Function() x8;
+  late List<Function> Function([Function]) Function() x9;
+  late List<Function> Function({core.List<core.int> x}) Function() x10;
+  late core.List<core.int> Function(int y, {int x}) Function() x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x]) Function()
+      x12;
+  late List<T> Function(int) Function() x13;
+  late List<T> Function(int x, [List<Function>]) Function() x14;
+  late List<T> Function(int y, {List<T> x}) Function() x15;
+  late Function([List<Function> x]) Function() x16;
+  late Function(List<T>) Function() x17;
+  late void Function(int, [Function]) Function() x18;
+  late void Function(int, {core.List<core.int> x}) Function() x19;
+  late Function Function<A>(core.List<core.int> x) Function() x20;
+  late List<T> Function<A>(List<T> x) Function() x21;
+  late List<A> Function<A>() Function() x22;
+
+  U76({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  core.List<core.int> m1({int x = -1}) => throw 'uncalled';
+  List<T> m2({List<T> x = const []}) => throw 'uncalled';
+  void m3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  int Function(int y, [int x]) m4() => throw 'uncalled';
+  int Function(int, [List<Function>]) m5() => throw 'uncalled';
+  int Function(int, {List<T> x}) m6() => throw 'uncalled';
+  Function Function(List<Function> x) m7() => throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8() => throw 'uncalled';
+  List<Function> Function([Function]) m9() => throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10() => throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x]) m12() =>
+      throw 'uncalled';
+  List<T> Function(int) m13() => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14() => throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15() => throw 'uncalled';
+  Function([List<Function> x]) m16() => throw 'uncalled';
+  Function(List<T>) m17() => throw 'uncalled';
+  void Function(int, [Function]) m18() => throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19() => throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20() => throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21() => throw 'uncalled';
+  List<A> Function<A>() m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function({int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function({int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>() Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U76().runTests();
+  new U76<int>(tIsInt: true).runTests();
+  new U76<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type77_test.dart b/tests/language/function_type/function_type77_test.dart
new file mode 100644
index 0000000..e310c8f
--- /dev/null
+++ b/tests/language/function_type/function_type77_test.dart
@@ -0,0 +1,925 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {Function x});
+typedef F1<T> = core.List<core.int> Function(int, {int x});
+typedef F2<T> = List<T> Function(int, {List<T> x});
+typedef F3<T> = void Function({core.List<core.int> x});
+typedef F4<T> = int Function(int y, [int x]) Function(int x);
+typedef F5<T> = int Function(int, [List<Function>]) Function(int x);
+typedef F6<T> = int Function(int, {List<T> x}) Function(int x);
+typedef F7<T> = Function Function(List<Function> x) Function(int x);
+typedef F8<T> = Function Function(int y, [List<T> x]) Function(int x);
+typedef F9<T> = List<Function> Function([Function]) Function(int x);
+typedef F10<T> = List<Function> Function({core.List<core.int> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int y, {int x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function(int x);
+typedef F13<T> = List<T> Function(int) Function(int x);
+typedef F14<T> = List<T> Function(int x, [List<Function>]) Function(int x);
+typedef F15<T> = List<T> Function(int y, {List<T> x}) Function(int x);
+typedef F16<T> = Function([List<Function> x]) Function(int x);
+typedef F17<T> = Function(List<T>) Function(int x);
+typedef F18<T> = void Function(int, [Function]) Function(int x);
+typedef F19<T> = void Function(int, {core.List<core.int> x}) Function(int x);
+typedef F20<T> = Function Function<A>(core.List<core.int> x) Function(int x);
+typedef F21<T> = List<T> Function<A>(List<T> x) Function(int x);
+typedef F22<T> = List<A> Function<A>() Function(int x);
+
+Function f0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+core.List<core.int> f1(int x0, {int x = -1}) => throw 'uncalled';
+List<int> f2(int x0, {List<int> x = const []}) => throw 'uncalled';
+void f3({core.List<core.int> x = const []}) => throw 'uncalled';
+int Function(int y, [int x]) f4(int x) => throw 'uncalled';
+int Function(int, [List<Function>]) f5(int x) => throw 'uncalled';
+int Function(int, {List<int> x}) f6(int x) => throw 'uncalled';
+Function Function(List<Function> x) f7(int x) => throw 'uncalled';
+Function Function(int y, [List<int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function([Function]) f9(int x) => throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int) f13(int x) => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14(int x) => throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15(int x) => throw 'uncalled';
+Function([List<Function> x]) f16(int x) => throw 'uncalled';
+Function(List<int>) f17(int x) => throw 'uncalled';
+void Function(int, [Function]) f18(int x) => throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19(int x) => throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(List<int> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>() f22(int x) => throw 'uncalled';
+
+class U77<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {Function x}) x0;
+  late core.List<core.int> Function(int, {int x}) x1;
+  late List<T> Function(int, {List<T> x}) x2;
+  late void Function({core.List<core.int> x}) x3;
+  late int Function(int y, [int x]) Function(int x) x4;
+  late int Function(int, [List<Function>]) Function(int x) x5;
+  late int Function(int, {List<T> x}) Function(int x) x6;
+  late Function Function(List<Function> x) Function(int x) x7;
+  late Function Function(int y, [List<T> x]) Function(int x) x8;
+  late List<Function> Function([Function]) Function(int x) x9;
+  late List<Function> Function({core.List<core.int> x}) Function(int x) x10;
+  late core.List<core.int> Function(int y, {int x}) Function(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x]) Function(
+      int x) x12;
+  late List<T> Function(int) Function(int x) x13;
+  late List<T> Function(int x, [List<Function>]) Function(int x) x14;
+  late List<T> Function(int y, {List<T> x}) Function(int x) x15;
+  late Function([List<Function> x]) Function(int x) x16;
+  late Function(List<T>) Function(int x) x17;
+  late void Function(int, [Function]) Function(int x) x18;
+  late void Function(int, {core.List<core.int> x}) Function(int x) x19;
+  late Function Function<A>(core.List<core.int> x) Function(int x) x20;
+  late List<T> Function<A>(List<T> x) Function(int x) x21;
+  late List<A> Function<A>() Function(int x) x22;
+
+  U77({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  core.List<core.int> m1(int x0, {int x = -1}) => throw 'uncalled';
+  List<T> m2(int x0, {List<T> x = const []}) => throw 'uncalled';
+  void m3({core.List<core.int> x = const []}) => throw 'uncalled';
+  int Function(int y, [int x]) m4(int x) => throw 'uncalled';
+  int Function(int, [List<Function>]) m5(int x) => throw 'uncalled';
+  int Function(int, {List<T> x}) m6(int x) => throw 'uncalled';
+  Function Function(List<Function> x) m7(int x) => throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function([Function]) m9(int x) => throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int) m13(int x) => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15(int x) => throw 'uncalled';
+  Function([List<Function> x]) m16(int x) => throw 'uncalled';
+  Function(List<T>) m17(int x) => throw 'uncalled';
+  void Function(int, [Function]) m18(int x) => throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19(int x) => throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>() m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U77().runTests();
+  new U77<int>(tIsInt: true).runTests();
+  new U77<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type78_test.dart b/tests/language/function_type/function_type78_test.dart
new file mode 100644
index 0000000..bc3a0af
--- /dev/null
+++ b/tests/language/function_type/function_type78_test.dart
@@ -0,0 +1,974 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(List<Function> x);
+typedef F1<T> = core.List<core.int> Function(int y, {int x});
+typedef F2<T> = List<T> Function(int y, {List<T> x});
+typedef F3<T> = void Function(int, {core.List<core.int> x});
+typedef F4<T> = int Function(int y, [int x]) Function<B extends core.int>();
+typedef F5<T> = int Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, {List<T> x}) Function<B extends core.int>();
+typedef F7<T> = Function Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([Function])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function([List<Function> x]) Function<B extends core.int>();
+typedef F17<T> = Function(List<T>) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [Function]) Function<B extends core.int>();
+typedef F19<T> = void Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(List<T> x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>() Function<B extends core.int>();
+
+Function f0(List<Function> x) => throw 'uncalled';
+core.List<core.int> f1(int y, {int x = -1}) => throw 'uncalled';
+List<int> f2(int y, {List<int> x = const []}) => throw 'uncalled';
+void f3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+int Function(int y, [int x]) f4<B extends core.int>() => throw 'uncalled';
+int Function(int, [List<Function>]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function(int, {List<int> x}) f6<B extends core.int>() => throw 'uncalled';
+Function Function(List<Function> x) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, [List<int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([Function]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([List<Function> x]) f16<B extends core.int>() => throw 'uncalled';
+Function(List<int>) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [Function]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function<A>(List<int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>() f22<B extends core.int>() => throw 'uncalled';
+
+class U78<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(List<Function> x) x0;
+  late core.List<core.int> Function(int y, {int x}) x1;
+  late List<T> Function(int y, {List<T> x}) x2;
+  late void Function(int, {core.List<core.int> x}) x3;
+  late int Function(int y, [int x]) Function<B extends core.int>() x4;
+  late int Function(int, [List<Function>]) Function<B extends core.int>() x5;
+  late int Function(int, {List<T> x}) Function<B extends core.int>() x6;
+  late Function Function(List<Function> x) Function<B extends core.int>() x7;
+  late Function Function(int y, [List<T> x]) Function<B extends core.int>() x8;
+  late List<Function> Function([Function]) Function<B extends core.int>() x9;
+  late List<Function> Function({core.List<core.int> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int y, {int x})
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int) Function<B extends core.int>() x13;
+  late List<T> Function(int x, [List<Function>]) Function<B extends core.int>()
+      x14;
+  late List<T> Function(int y, {List<T> x}) Function<B extends core.int>() x15;
+  late Function([List<Function> x]) Function<B extends core.int>() x16;
+  late Function(List<T>) Function<B extends core.int>() x17;
+  late void Function(int, [Function]) Function<B extends core.int>() x18;
+  late void Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x19;
+  late Function Function<A>(core.List<core.int> x)
+      Function<B extends core.int>() x20;
+  late List<T> Function<A>(List<T> x) Function<B extends core.int>() x21;
+  late List<A> Function<A>() Function<B extends core.int>() x22;
+
+  U78({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(List<Function> x) => throw 'uncalled';
+  core.List<core.int> m1(int y, {int x = -1}) => throw 'uncalled';
+  List<T> m2(int y, {List<T> x = const []}) => throw 'uncalled';
+  void m3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  int Function(int y, [int x]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int, [List<Function>]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, {List<T> x}) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(List<Function> x) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([Function]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([List<Function> x]) m16<B extends core.int>() => throw 'uncalled';
+  Function(List<T>) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [Function]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>() m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(List<Function> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(List<Function> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([List<Function> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function<B extends core.int>()
+        l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U78().runTests();
+  new U78<int>(tIsInt: true).runTests();
+  new U78<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type79_test.dart b/tests/language/function_type/function_type79_test.dart
new file mode 100644
index 0000000..7932960
--- /dev/null
+++ b/tests/language/function_type/function_type79_test.dart
@@ -0,0 +1,997 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([List<Function> x]);
+typedef F1<T> = core.List<core.int> Function(Function x);
+typedef F2<T> = List<T> Function();
+typedef F3<T> = void Function(int y, {core.List<core.int> x});
+typedef F4<T> = int Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F5<T> = int Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([Function])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int y, {int x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(List<T>) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = List<A> Function<A>() Function<B extends core.int>(int x);
+
+Function f0([List<Function> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(Function x) => throw 'uncalled';
+List<int> f2() => throw 'uncalled';
+void f3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+int Function(int y, [int x]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, [List<Function>]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, {List<int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(List<Function> x) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, [List<int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([Function]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([List<Function> x]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(List<int>) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, [Function]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>(List<int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>() f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U79<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([List<Function> x]) x0;
+  late core.List<core.int> Function(Function x) x1;
+  late List<T> Function() x2;
+  late void Function(int y, {core.List<core.int> x}) x3;
+  late int Function(int y, [int x]) Function<B extends core.int>(int x) x4;
+  late int Function(int, [List<Function>]) Function<B extends core.int>(int x)
+      x5;
+  late int Function(int, {List<T> x}) Function<B extends core.int>(int x) x6;
+  late Function Function(List<Function> x) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+      x8;
+  late List<Function> Function([Function]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function({core.List<core.int> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int y, {int x})
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int x, [List<Function>]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+      x15;
+  late Function([List<Function> x]) Function<B extends core.int>(int x) x16;
+  late Function(List<T>) Function<B extends core.int>(int x) x17;
+  late void Function(int, [Function]) Function<B extends core.int>(int x) x18;
+  late void Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x20;
+  late List<T> Function<A>(List<T> x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>() Function<B extends core.int>(int x) x22;
+
+  U79({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([List<Function> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(Function x) => throw 'uncalled';
+  List<T> m2() => throw 'uncalled';
+  void m3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  int Function(int y, [int x]) m4<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [List<Function>]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, {List<T> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(List<Function> x) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([Function]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([List<Function> x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(List<T>) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, [Function]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>() m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(Function x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(Function x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function()
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function());
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int y, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function<B extends core.int>(
+        int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U79().runTests();
+  new U79<int>(tIsInt: true).runTests();
+  new U79<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type7_test.dart b/tests/language/function_type/function_type7_test.dart
new file mode 100644
index 0000000..eb38ae3
--- /dev/null
+++ b/tests/language/function_type/function_type7_test.dart
@@ -0,0 +1,1001 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [int]);
+typedef F1<T> = Function Function(int x, [List<T>]);
+typedef F2<T> = core.List<core.int> Function(int, [core.List<core.int>]);
+typedef F3<T> = Function([List<Function>]);
+typedef F4<T> = Function Function<A>(List<A> x);
+typedef F5<T> = int Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = Function Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(List<T>) Function<B extends core.int>(
+    int x);
+typedef F12<T> = core.List<core.int> Function(int, [Function])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(Function x) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([int]) Function<B extends core.int>(int x);
+typedef F17<T> = Function({List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F18<T> = Function() Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function([List<T>]) Function<B extends core.int>(int x);
+typedef F21<T> = List<Function> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+
+int f0(int x, [int x0 = -1]) => throw 'uncalled';
+Function f1(int x, [List<int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [core.List<core.int> x1 = const []]) =>
+    throw 'uncalled';
+f3([List<Function> x0 = const []]) => throw 'uncalled';
+Function f4<A>(List<A> x) => throw 'uncalled';
+int Function(int y, {int x}) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {List<int> x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([List<Function> x]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<int>) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x})
+    f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(Function x) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function([int]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function({List<Function> x}) f17<B extends core.int>(int x) => throw 'uncalled';
+Function() f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, [List<Function> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([List<int>]) f20<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(core.List<core.int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function<A>(List<int> x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U7<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [int]) x0;
+  late Function Function(int x, [List<T>]) x1;
+  late core.List<core.int> Function(int, [core.List<core.int>]) x2;
+  late Function([List<Function>]) x3;
+  late Function Function<A>(List<A> x) x4;
+  late int Function(int y, {int x}) Function<B extends core.int>(int x) x5;
+  late int Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x6;
+  late Function Function(int) Function<B extends core.int>(int x) x7;
+  late Function Function(int x, [List<Function>]) Function<B extends core.int>(
+      int x) x8;
+  late Function Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function([List<Function> x]) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function(List<T>) Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [Function])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(Function x) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x15;
+  late Function([int]) Function<B extends core.int>(int x) x16;
+  late Function({List<Function> x}) Function<B extends core.int>(int x) x17;
+  late Function() Function<B extends core.int>(int x) x18;
+  late void Function(int, [List<Function> x]) Function<B extends core.int>(
+      int x) x19;
+  late void Function([List<T>]) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(List<Function> x)
+      Function<B extends core.int>(int x) x21;
+  late Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+      x22;
+  late void Function<A>(List<T> x) Function<B extends core.int>(int x) x23;
+
+  U7({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [int x0 = -1]) => throw 'uncalled';
+  Function m1(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [core.List<core.int> x1 = const []]) =>
+      throw 'uncalled';
+  m3([List<Function> x0 = const []]) => throw 'uncalled';
+  Function m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int y, {int x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<T>) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x})
+      m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(Function x) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function([int]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function({List<Function> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function() m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<T>]) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function<A>(List<T> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int x, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function([List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(List<T>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U7().runTests();
+  new U7<int>(tIsInt: true).runTests();
+  new U7<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type80_test.dart b/tests/language/function_type/function_type80_test.dart
new file mode 100644
index 0000000..1cb0d30
--- /dev/null
+++ b/tests/language/function_type/function_type80_test.dart
@@ -0,0 +1,946 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [List<Function> x]);
+typedef F1<T> = core.List<core.int> Function([Function x]);
+typedef F2<T> = Function(int x);
+typedef F3<T> = void Function(List<T> x);
+typedef F4<T> = int Function(int) Function();
+typedef F5<T> = int Function(int x, [List<Function>]) Function();
+typedef F6<T> = int Function(int y, {List<T> x}) Function();
+typedef F7<T> = Function Function([List<Function> x]) Function();
+typedef F8<T> = Function Function(List<T>) Function();
+typedef F9<T> = List<Function> Function(int, [Function]) Function();
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x})
+    Function();
+typedef F11<T> = core.List<core.int> Function(Function x) Function();
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function();
+typedef F13<T> = List<T> Function([int]) Function();
+typedef F14<T> = List<T> Function({List<Function> x}) Function();
+typedef F15<T> = List<T> Function() Function();
+typedef F16<T> = Function(int, [List<Function> x]) Function();
+typedef F17<T> = Function([List<T>]) Function();
+typedef F18<T> = void Function(int x, [Function]) Function();
+typedef F19<T> = void Function(int y, {core.List<core.int> x}) Function();
+typedef F20<T> = Function Function<A>(List<T> x) Function();
+typedef F21<T> = List<T> Function<A>() Function();
+typedef F22<T> = List<A> Function<A>(A x) Function();
+
+Function f0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+core.List<core.int> f1([Function x = _voidFunction]) => throw 'uncalled';
+f2(int x) => throw 'uncalled';
+void f3(List<int> x) => throw 'uncalled';
+int Function(int) f4() => throw 'uncalled';
+int Function(int x, [List<Function>]) f5() => throw 'uncalled';
+int Function(int y, {List<int> x}) f6() => throw 'uncalled';
+Function Function([List<Function> x]) f7() => throw 'uncalled';
+Function Function(List<int>) f8() => throw 'uncalled';
+List<Function> Function(int, [Function]) f9() => throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x}) f10() => throw 'uncalled';
+core.List<core.int> Function(Function x) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x]) f12() =>
+    throw 'uncalled';
+List<int> Function([int]) f13() => throw 'uncalled';
+List<int> Function({List<Function> x}) f14() => throw 'uncalled';
+List<int> Function() f15() => throw 'uncalled';
+Function(int, [List<Function> x]) f16() => throw 'uncalled';
+Function([List<int>]) f17() => throw 'uncalled';
+void Function(int x, [Function]) f18() => throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19() => throw 'uncalled';
+Function Function<A>(List<int> x) f20() => throw 'uncalled';
+List<int> Function<A>() f21() => throw 'uncalled';
+List<A> Function<A>(A x) f22() => throw 'uncalled';
+
+class U80<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [List<Function> x]) x0;
+  late core.List<core.int> Function([Function x]) x1;
+  late Function(int x) x2;
+  late void Function(List<T> x) x3;
+  late int Function(int) Function() x4;
+  late int Function(int x, [List<Function>]) Function() x5;
+  late int Function(int y, {List<T> x}) Function() x6;
+  late Function Function([List<Function> x]) Function() x7;
+  late Function Function(List<T>) Function() x8;
+  late List<Function> Function(int, [Function]) Function() x9;
+  late List<Function> Function(int, {core.List<core.int> x}) Function() x10;
+  late core.List<core.int> Function(Function x) Function() x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x]) Function()
+      x12;
+  late List<T> Function([int]) Function() x13;
+  late List<T> Function({List<Function> x}) Function() x14;
+  late List<T> Function() Function() x15;
+  late Function(int, [List<Function> x]) Function() x16;
+  late Function([List<T>]) Function() x17;
+  late void Function(int x, [Function]) Function() x18;
+  late void Function(int y, {core.List<core.int> x}) Function() x19;
+  late Function Function<A>(List<T> x) Function() x20;
+  late List<T> Function<A>() Function() x21;
+  late List<A> Function<A>(A x) Function() x22;
+
+  U80({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1([Function x = _voidFunction]) => throw 'uncalled';
+  m2(int x) => throw 'uncalled';
+  void m3(List<T> x) => throw 'uncalled';
+  int Function(int) m4() => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5() => throw 'uncalled';
+  int Function(int y, {List<T> x}) m6() => throw 'uncalled';
+  Function Function([List<Function> x]) m7() => throw 'uncalled';
+  Function Function(List<T>) m8() => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9() => throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x}) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function x) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x]) m12() =>
+      throw 'uncalled';
+  List<T> Function([int]) m13() => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14() => throw 'uncalled';
+  List<T> Function() m15() => throw 'uncalled';
+  Function(int, [List<Function> x]) m16() => throw 'uncalled';
+  Function([List<T>]) m17() => throw 'uncalled';
+  void Function(int x, [Function]) m18() => throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19() => throw 'uncalled';
+  Function Function<A>(List<T> x) m20() => throw 'uncalled';
+  List<T> Function<A>() m21() => throw 'uncalled';
+  List<A> Function<A>(A x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(List<T> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<T> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T>) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function x) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function() Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>() Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U80().runTests();
+  new U80<int>(tIsInt: true).runTests();
+  new U80<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type81_test.dart b/tests/language/function_type/function_type81_test.dart
new file mode 100644
index 0000000..0c89ae4
--- /dev/null
+++ b/tests/language/function_type/function_type81_test.dart
@@ -0,0 +1,953 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [List<Function> x]);
+typedef F1<T> = core.List<core.int> Function(int, [Function x]);
+typedef F2<T> = Function([int x]);
+typedef F3<T> = void Function([List<T> x]);
+typedef F4<T> = int Function(int) Function(int x);
+typedef F5<T> = int Function(int x, [List<Function>]) Function(int x);
+typedef F6<T> = int Function(int y, {List<T> x}) Function(int x);
+typedef F7<T> = Function Function([List<Function> x]) Function(int x);
+typedef F8<T> = Function Function(List<T>) Function(int x);
+typedef F9<T> = List<Function> Function(int, [Function]) Function(int x);
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(Function x) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function(int x);
+typedef F13<T> = List<T> Function([int]) Function(int x);
+typedef F14<T> = List<T> Function({List<Function> x}) Function(int x);
+typedef F15<T> = List<T> Function() Function(int x);
+typedef F16<T> = Function(int, [List<Function> x]) Function(int x);
+typedef F17<T> = Function([List<T>]) Function(int x);
+typedef F18<T> = void Function(int x, [Function]) Function(int x);
+typedef F19<T> = void Function(int y, {core.List<core.int> x}) Function(int x);
+typedef F20<T> = Function Function<A>(List<T> x) Function(int x);
+typedef F21<T> = List<T> Function<A>() Function(int x);
+typedef F22<T> = List<A> Function<A>(A x) Function(int x);
+
+Function f0(int y, [List<Function> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [Function x = _voidFunction]) =>
+    throw 'uncalled';
+f2([int x = -1]) => throw 'uncalled';
+void f3([List<int> x = const []]) => throw 'uncalled';
+int Function(int) f4(int x) => throw 'uncalled';
+int Function(int x, [List<Function>]) f5(int x) => throw 'uncalled';
+int Function(int y, {List<int> x}) f6(int x) => throw 'uncalled';
+Function Function([List<Function> x]) f7(int x) => throw 'uncalled';
+Function Function(List<int>) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [Function]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x}) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(Function x) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function([int]) f13(int x) => throw 'uncalled';
+List<int> Function({List<Function> x}) f14(int x) => throw 'uncalled';
+List<int> Function() f15(int x) => throw 'uncalled';
+Function(int, [List<Function> x]) f16(int x) => throw 'uncalled';
+Function([List<int>]) f17(int x) => throw 'uncalled';
+void Function(int x, [Function]) f18(int x) => throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19(int x) => throw 'uncalled';
+Function Function<A>(List<int> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>() f21(int x) => throw 'uncalled';
+List<A> Function<A>(A x) f22(int x) => throw 'uncalled';
+
+class U81<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [List<Function> x]) x0;
+  late core.List<core.int> Function(int, [Function x]) x1;
+  late Function([int x]) x2;
+  late void Function([List<T> x]) x3;
+  late int Function(int) Function(int x) x4;
+  late int Function(int x, [List<Function>]) Function(int x) x5;
+  late int Function(int y, {List<T> x}) Function(int x) x6;
+  late Function Function([List<Function> x]) Function(int x) x7;
+  late Function Function(List<T>) Function(int x) x8;
+  late List<Function> Function(int, [Function]) Function(int x) x9;
+  late List<Function> Function(int, {core.List<core.int> x}) Function(int x)
+      x10;
+  late core.List<core.int> Function(Function x) Function(int x) x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x]) Function(
+      int x) x12;
+  late List<T> Function([int]) Function(int x) x13;
+  late List<T> Function({List<Function> x}) Function(int x) x14;
+  late List<T> Function() Function(int x) x15;
+  late Function(int, [List<Function> x]) Function(int x) x16;
+  late Function([List<T>]) Function(int x) x17;
+  late void Function(int x, [Function]) Function(int x) x18;
+  late void Function(int y, {core.List<core.int> x}) Function(int x) x19;
+  late Function Function<A>(List<T> x) Function(int x) x20;
+  late List<T> Function<A>() Function(int x) x21;
+  late List<A> Function<A>(A x) Function(int x) x22;
+
+  U81({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [List<Function> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [Function x = _voidFunction]) =>
+      throw 'uncalled';
+  m2([int x = -1]) => throw 'uncalled';
+  void m3([List<T> x = const []]) => throw 'uncalled';
+  int Function(int) m4(int x) => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5(int x) => throw 'uncalled';
+  int Function(int y, {List<T> x}) m6(int x) => throw 'uncalled';
+  Function Function([List<Function> x]) m7(int x) => throw 'uncalled';
+  Function Function(List<T>) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function x) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function([int]) m13(int x) => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14(int x) => throw 'uncalled';
+  List<T> Function() m15(int x) => throw 'uncalled';
+  Function(int, [List<Function> x]) m16(int x) => throw 'uncalled';
+  Function([List<T>]) m17(int x) => throw 'uncalled';
+  void Function(int x, [Function]) m18(int x) => throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19(int x) => throw 'uncalled';
+  Function Function<A>(List<T> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>() m21(int x) => throw 'uncalled';
+  List<A> Function<A>(A x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function([List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function() Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U81().runTests();
+  new U81<int>(tIsInt: true).runTests();
+  new U81<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type82_test.dart b/tests/language/function_type/function_type82_test.dart
new file mode 100644
index 0000000..ac0159d4
--- /dev/null
+++ b/tests/language/function_type/function_type82_test.dart
@@ -0,0 +1,989 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(List<Function>);
+typedef F1<T> = core.List<core.int> Function(int y, [Function x]);
+typedef F2<T> = Function(int, [int x]);
+typedef F3<T> = void Function(int, [List<T> x]);
+typedef F4<T> = int Function(int) Function<B extends core.int>();
+typedef F5<T> = int Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int y, {List<T> x}) Function<B extends core.int>();
+typedef F7<T> = Function Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(List<T>) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [Function])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(Function x)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function([int]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function() Function<B extends core.int>();
+typedef F16<T> = Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F17<T> = Function([List<T>]) Function<B extends core.int>();
+typedef F18<T> = void Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F19<T> = void Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(List<T> x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>() Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(A x) Function<B extends core.int>();
+
+Function f0(List<Function> x0) => throw 'uncalled';
+core.List<core.int> f1(int y, [Function x = _voidFunction]) => throw 'uncalled';
+f2(int x0, [int x = -1]) => throw 'uncalled';
+void f3(int x0, [List<int> x = const []]) => throw 'uncalled';
+int Function(int) f4<B extends core.int>() => throw 'uncalled';
+int Function(int x, [List<Function>]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function(int y, {List<int> x}) f6<B extends core.int>() => throw 'uncalled';
+Function Function([List<Function> x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(List<int>) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int, [Function]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x})
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(Function x) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function([int]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function({List<Function> x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function() f15<B extends core.int>() => throw 'uncalled';
+Function(int, [List<Function> x]) f16<B extends core.int>() => throw 'uncalled';
+Function([List<int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int x, [Function]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(List<int> x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>() f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(A x) f22<B extends core.int>() => throw 'uncalled';
+
+class U82<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(List<Function>) x0;
+  late core.List<core.int> Function(int y, [Function x]) x1;
+  late Function(int, [int x]) x2;
+  late void Function(int, [List<T> x]) x3;
+  late int Function(int) Function<B extends core.int>() x4;
+  late int Function(int x, [List<Function>]) Function<B extends core.int>() x5;
+  late int Function(int y, {List<T> x}) Function<B extends core.int>() x6;
+  late Function Function([List<Function> x]) Function<B extends core.int>() x7;
+  late Function Function(List<T>) Function<B extends core.int>() x8;
+  late List<Function> Function(int, [Function]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(Function x) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x12;
+  late List<T> Function([int]) Function<B extends core.int>() x13;
+  late List<T> Function({List<Function> x}) Function<B extends core.int>() x14;
+  late List<T> Function() Function<B extends core.int>() x15;
+  late Function(int, [List<Function> x]) Function<B extends core.int>() x16;
+  late Function([List<T>]) Function<B extends core.int>() x17;
+  late void Function(int x, [Function]) Function<B extends core.int>() x18;
+  late void Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x19;
+  late Function Function<A>(List<T> x) Function<B extends core.int>() x20;
+  late List<T> Function<A>() Function<B extends core.int>() x21;
+  late List<A> Function<A>(A x) Function<B extends core.int>() x22;
+
+  U82({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(List<Function> x0) => throw 'uncalled';
+  core.List<core.int> m1(int y, [Function x = _voidFunction]) =>
+      throw 'uncalled';
+  m2(int x0, [int x = -1]) => throw 'uncalled';
+  void m3(int x0, [List<T> x = const []]) => throw 'uncalled';
+  int Function(int) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int y, {List<T> x}) m6<B extends core.int>() => throw 'uncalled';
+  Function Function([List<Function> x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(List<T>) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x})
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(Function x) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function([int]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function() m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [List<Function> x]) m16<B extends core.int>() =>
+      throw 'uncalled';
+  Function([List<T>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [Function]) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(List<T> x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>() m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(A x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(List<Function>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(List<Function>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U82().runTests();
+  new U82<int>(tIsInt: true).runTests();
+  new U82<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type83_test.dart b/tests/language/function_type/function_type83_test.dart
new file mode 100644
index 0000000..7cd2eb5
--- /dev/null
+++ b/tests/language/function_type/function_type83_test.dart
@@ -0,0 +1,1011 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([List<Function>]);
+typedef F1<T> = core.List<core.int> Function(Function);
+typedef F2<T> = Function(int y, [int x]);
+typedef F3<T> = void Function(int y, [List<T> x]);
+typedef F4<T> = int Function(int) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int y, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(List<T>) Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, [Function])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(Function x)
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function([int]) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function() Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function([List<T>]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int x, [Function]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<T> Function<A>() Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(A x) Function<B extends core.int>(int x);
+
+Function f0([List<Function> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(Function x0) => throw 'uncalled';
+f2(int y, [int x = -1]) => throw 'uncalled';
+void f3(int y, [List<int> x = const []]) => throw 'uncalled';
+int Function(int) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int x, [List<Function>]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int y, {List<int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<Function> x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(List<int>) f8<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function(int, [Function]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(Function x) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function([int]) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function({List<Function> x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function() f15<B extends core.int>(int x) => throw 'uncalled';
+Function(int, [List<Function> x]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([List<int>]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int x, [Function]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(List<int> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>() f21<B extends core.int>(int x) => throw 'uncalled';
+List<A> Function<A>(A x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U83<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([List<Function>]) x0;
+  late core.List<core.int> Function(Function) x1;
+  late Function(int y, [int x]) x2;
+  late void Function(int y, [List<T> x]) x3;
+  late int Function(int) Function<B extends core.int>(int x) x4;
+  late int Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+      x5;
+  late int Function(int y, {List<T> x}) Function<B extends core.int>(int x) x6;
+  late Function Function([List<Function> x]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(List<T>) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int, [Function]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(Function x) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function([int]) Function<B extends core.int>(int x) x13;
+  late List<T> Function({List<Function> x}) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function() Function<B extends core.int>(int x) x15;
+  late Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+      x16;
+  late Function([List<T>]) Function<B extends core.int>(int x) x17;
+  late void Function(int x, [Function]) Function<B extends core.int>(int x) x18;
+  late void Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x19;
+  late Function Function<A>(List<T> x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>() Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(A x) Function<B extends core.int>(int x) x22;
+
+  U83({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([List<Function> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(Function x0) => throw 'uncalled';
+  m2(int y, [int x = -1]) => throw 'uncalled';
+  void m3(int y, [List<T> x = const []]) => throw 'uncalled';
+  int Function(int) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int y, {List<T> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<Function> x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(List<T>) m8<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function x) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function([int]) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function() m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [List<Function> x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([List<T>]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int x, [Function]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function Function<A>(List<T> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>() m21<B extends core.int>(int x) => throw 'uncalled';
+  List<A> Function<A>(A x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(Function)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(Function));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int y, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int y, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int y, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function<B extends core.int>(int x)
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U83().runTests();
+  new U83<int>(tIsInt: true).runTests();
+  new U83<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type84_test.dart b/tests/language/function_type/function_type84_test.dart
new file mode 100644
index 0000000..4c34ba2
--- /dev/null
+++ b/tests/language/function_type/function_type84_test.dart
@@ -0,0 +1,891 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [List<Function>]);
+typedef F1<T> = core.List<core.int> Function([Function]);
+typedef F2<T> = Function(int);
+typedef F3<T> = void Function(List<T>);
+typedef F4<T> = int Function([int]) Function();
+typedef F5<T> = int Function({List<Function> x}) Function();
+typedef F6<T> = int Function() Function();
+typedef F7<T> = Function Function(int, [List<Function> x]) Function();
+typedef F8<T> = Function Function([List<T>]) Function();
+typedef F9<T> = List<Function> Function(int x, [Function]) Function();
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function();
+typedef F11<T> = core.List<core.int> Function([Function x]) Function();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>) Function();
+typedef F13<T> = List<T> Function(int, [int]) Function();
+typedef F14<T> = List<T> Function(int, {List<Function> x}) Function();
+typedef F15<T> = Function(int x) Function();
+typedef F16<T> = Function(int y, [List<Function> x]) Function();
+typedef F17<T> = Function(int, [List<T>]) Function();
+typedef F18<T> = void Function({Function x}) Function();
+typedef F19<T> = void Function(List<T> x) Function();
+typedef F20<T> = Function Function<A>() Function();
+typedef F21<T> = List<T> Function<A>(A x) Function();
+typedef F22<T> = List<A> Function<A>(List<A> x) Function();
+
+Function f0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f1([Function x0 = _voidFunction]) => throw 'uncalled';
+f2(int x0) => throw 'uncalled';
+void f3(List<int> x0) => throw 'uncalled';
+int Function([int]) f4() => throw 'uncalled';
+int Function({List<Function> x}) f5() => throw 'uncalled';
+int Function() f6() => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7() => throw 'uncalled';
+Function Function([List<int>]) f8() => throw 'uncalled';
+List<Function> Function(int x, [Function]) f9() => throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x}) f10() =>
+    throw 'uncalled';
+core.List<core.int> Function([Function x]) f11() => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12() => throw 'uncalled';
+List<int> Function(int, [int]) f13() => throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14() => throw 'uncalled';
+Function(int x) f15() => throw 'uncalled';
+Function(int y, [List<Function> x]) f16() => throw 'uncalled';
+Function(int, [List<int>]) f17() => throw 'uncalled';
+void Function({Function x}) f18() => throw 'uncalled';
+void Function(List<int> x) f19() => throw 'uncalled';
+Function Function<A>() f20() => throw 'uncalled';
+List<int> Function<A>(A x) f21() => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22() => throw 'uncalled';
+
+class U84<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [List<Function>]) x0;
+  late core.List<core.int> Function([Function]) x1;
+  late Function(int) x2;
+  late void Function(List<T>) x3;
+  late int Function([int]) Function() x4;
+  late int Function({List<Function> x}) Function() x5;
+  late int Function() Function() x6;
+  late Function Function(int, [List<Function> x]) Function() x7;
+  late Function Function([List<T>]) Function() x8;
+  late List<Function> Function(int x, [Function]) Function() x9;
+  late List<Function> Function(int y, {core.List<core.int> x}) Function() x10;
+  late core.List<core.int> Function([Function x]) Function() x11;
+  late core.List<core.int> Function(core.List<core.int>) Function() x12;
+  late List<T> Function(int, [int]) Function() x13;
+  late List<T> Function(int, {List<Function> x}) Function() x14;
+  late Function(int x) Function() x15;
+  late Function(int y, [List<Function> x]) Function() x16;
+  late Function(int, [List<T>]) Function() x17;
+  late void Function({Function x}) Function() x18;
+  late void Function(List<T> x) Function() x19;
+  late Function Function<A>() Function() x20;
+  late List<T> Function<A>(A x) Function() x21;
+  late List<A> Function<A>(List<A> x) Function() x22;
+
+  U84({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m1([Function x0 = _voidFunction]) => throw 'uncalled';
+  m2(int x0) => throw 'uncalled';
+  void m3(List<T> x0) => throw 'uncalled';
+  int Function([int]) m4() => throw 'uncalled';
+  int Function({List<Function> x}) m5() => throw 'uncalled';
+  int Function() m6() => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7() => throw 'uncalled';
+  Function Function([List<T>]) m8() => throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9() => throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x}) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12() => throw 'uncalled';
+  List<T> Function(int, [int]) m13() => throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14() => throw 'uncalled';
+  Function(int x) m15() => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16() => throw 'uncalled';
+  Function(int, [List<T>]) m17() => throw 'uncalled';
+  void Function({Function x}) m18() => throw 'uncalled';
+  void Function(List<T> x) m19() => throw 'uncalled';
+  Function Function<A>() m20() => throw 'uncalled';
+  List<T> Function<A>(A x) m21() => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(List<T>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<T>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([Function x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({Function x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<T> x) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>() Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U84().runTests();
+  new U84<int>(tIsInt: true).runTests();
+  new U84<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type85_test.dart b/tests/language/function_type/function_type85_test.dart
new file mode 100644
index 0000000..a56fa37
--- /dev/null
+++ b/tests/language/function_type/function_type85_test.dart
@@ -0,0 +1,901 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [List<Function>]);
+typedef F1<T> = core.List<core.int> Function(int, [Function]);
+typedef F2<T> = Function([int]);
+typedef F3<T> = void Function([List<T>]);
+typedef F4<T> = int Function([int]) Function(int x);
+typedef F5<T> = int Function({List<Function> x}) Function(int x);
+typedef F6<T> = int Function() Function(int x);
+typedef F7<T> = Function Function(int, [List<Function> x]) Function(int x);
+typedef F8<T> = Function Function([List<T>]) Function(int x);
+typedef F9<T> = List<Function> Function(int x, [Function]) Function(int x);
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function(int x);
+typedef F11<T> = core.List<core.int> Function([Function x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>) Function(
+    int x);
+typedef F13<T> = List<T> Function(int, [int]) Function(int x);
+typedef F14<T> = List<T> Function(int, {List<Function> x}) Function(int x);
+typedef F15<T> = Function(int x) Function(int x);
+typedef F16<T> = Function(int y, [List<Function> x]) Function(int x);
+typedef F17<T> = Function(int, [List<T>]) Function(int x);
+typedef F18<T> = void Function({Function x}) Function(int x);
+typedef F19<T> = void Function(List<T> x) Function(int x);
+typedef F20<T> = Function Function<A>() Function(int x);
+typedef F21<T> = List<T> Function<A>(A x) Function(int x);
+typedef F22<T> = List<A> Function<A>(List<A> x) Function(int x);
+
+Function f0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [Function x1 = _voidFunction]) =>
+    throw 'uncalled';
+f2([int x0 = -1]) => throw 'uncalled';
+void f3([List<int> x0 = const []]) => throw 'uncalled';
+int Function([int]) f4(int x) => throw 'uncalled';
+int Function({List<Function> x}) f5(int x) => throw 'uncalled';
+int Function() f6(int x) => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7(int x) => throw 'uncalled';
+Function Function([List<int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int x, [Function]) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x}) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([Function x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int]) f13(int x) => throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14(int x) => throw 'uncalled';
+Function(int x) f15(int x) => throw 'uncalled';
+Function(int y, [List<Function> x]) f16(int x) => throw 'uncalled';
+Function(int, [List<int>]) f17(int x) => throw 'uncalled';
+void Function({Function x}) f18(int x) => throw 'uncalled';
+void Function(List<int> x) f19(int x) => throw 'uncalled';
+Function Function<A>() f20(int x) => throw 'uncalled';
+List<int> Function<A>(A x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22(int x) => throw 'uncalled';
+
+class U85<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [List<Function>]) x0;
+  late core.List<core.int> Function(int, [Function]) x1;
+  late Function([int]) x2;
+  late void Function([List<T>]) x3;
+  late int Function([int]) Function(int x) x4;
+  late int Function({List<Function> x}) Function(int x) x5;
+  late int Function() Function(int x) x6;
+  late Function Function(int, [List<Function> x]) Function(int x) x7;
+  late Function Function([List<T>]) Function(int x) x8;
+  late List<Function> Function(int x, [Function]) Function(int x) x9;
+  late List<Function> Function(int y, {core.List<core.int> x}) Function(int x)
+      x10;
+  late core.List<core.int> Function([Function x]) Function(int x) x11;
+  late core.List<core.int> Function(core.List<core.int>) Function(int x) x12;
+  late List<T> Function(int, [int]) Function(int x) x13;
+  late List<T> Function(int, {List<Function> x}) Function(int x) x14;
+  late Function(int x) Function(int x) x15;
+  late Function(int y, [List<Function> x]) Function(int x) x16;
+  late Function(int, [List<T>]) Function(int x) x17;
+  late void Function({Function x}) Function(int x) x18;
+  late void Function(List<T> x) Function(int x) x19;
+  late Function Function<A>() Function(int x) x20;
+  late List<T> Function<A>(A x) Function(int x) x21;
+  late List<A> Function<A>(List<A> x) Function(int x) x22;
+
+  U85({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [Function x1 = _voidFunction]) =>
+      throw 'uncalled';
+  m2([int x0 = -1]) => throw 'uncalled';
+  void m3([List<T> x0 = const []]) => throw 'uncalled';
+  int Function([int]) m4(int x) => throw 'uncalled';
+  int Function({List<Function> x}) m5(int x) => throw 'uncalled';
+  int Function() m6(int x) => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7(int x) => throw 'uncalled';
+  Function Function([List<T>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int]) m13(int x) => throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14(int x) => throw 'uncalled';
+  Function(int x) m15(int x) => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16(int x) => throw 'uncalled';
+  Function(int, [List<T>]) m17(int x) => throw 'uncalled';
+  void Function({Function x}) m18(int x) => throw 'uncalled';
+  void Function(List<T> x) m19(int x) => throw 'uncalled';
+  Function Function<A>() m20(int x) => throw 'uncalled';
+  List<T> Function<A>(A x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function([List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int>)
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>() Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U85().runTests();
+  new U85<int>(tIsInt: true).runTests();
+  new U85<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type86_test.dart b/tests/language/function_type/function_type86_test.dart
new file mode 100644
index 0000000..3961f324
--- /dev/null
+++ b/tests/language/function_type/function_type86_test.dart
@@ -0,0 +1,936 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({List<Function> x});
+typedef F1<T> = core.List<core.int> Function(int x, [Function]);
+typedef F2<T> = Function(int, [int]);
+typedef F3<T> = void Function(int, [List<T>]);
+typedef F4<T> = int Function([int]) Function<B extends core.int>();
+typedef F5<T> = int Function({List<Function> x}) Function<B extends core.int>();
+typedef F6<T> = int Function() Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function([List<T>]) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function([Function x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int, [int]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F15<T> = Function(int x) Function<B extends core.int>();
+typedef F16<T> = Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F17<T> = Function(int, [List<T>]) Function<B extends core.int>();
+typedef F18<T> = void Function({Function x}) Function<B extends core.int>();
+typedef F19<T> = void Function(List<T> x) Function<B extends core.int>();
+typedef F20<T> = Function Function<A>() Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(A x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(List<A> x) Function<B extends core.int>();
+
+Function f0({List<Function> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x, [Function x0 = _voidFunction]) =>
+    throw 'uncalled';
+f2(int x0, [int x1 = -1]) => throw 'uncalled';
+void f3(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+int Function([int]) f4<B extends core.int>() => throw 'uncalled';
+int Function({List<Function> x}) f5<B extends core.int>() => throw 'uncalled';
+int Function() f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([List<int>]) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int x, [Function]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x})
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function([Function x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [int]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function(int x) f15<B extends core.int>() => throw 'uncalled';
+Function(int y, [List<Function> x]) f16<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, [List<int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function({Function x}) f18<B extends core.int>() => throw 'uncalled';
+void Function(List<int> x) f19<B extends core.int>() => throw 'uncalled';
+Function Function<A>() f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(A x) f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22<B extends core.int>() => throw 'uncalled';
+
+class U86<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({List<Function> x}) x0;
+  late core.List<core.int> Function(int x, [Function]) x1;
+  late Function(int, [int]) x2;
+  late void Function(int, [List<T>]) x3;
+  late int Function([int]) Function<B extends core.int>() x4;
+  late int Function({List<Function> x}) Function<B extends core.int>() x5;
+  late int Function() Function<B extends core.int>() x6;
+  late Function Function(int, [List<Function> x]) Function<B extends core.int>()
+      x7;
+  late Function Function([List<T>]) Function<B extends core.int>() x8;
+  late List<Function> Function(int x, [Function]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function([Function x]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(core.List<core.int>)
+      Function<B extends core.int>() x12;
+  late List<T> Function(int, [int]) Function<B extends core.int>() x13;
+  late List<T> Function(int, {List<Function> x}) Function<B extends core.int>()
+      x14;
+  late Function(int x) Function<B extends core.int>() x15;
+  late Function(int y, [List<Function> x]) Function<B extends core.int>() x16;
+  late Function(int, [List<T>]) Function<B extends core.int>() x17;
+  late void Function({Function x}) Function<B extends core.int>() x18;
+  late void Function(List<T> x) Function<B extends core.int>() x19;
+  late Function Function<A>() Function<B extends core.int>() x20;
+  late List<T> Function<A>(A x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(List<A> x) Function<B extends core.int>() x22;
+
+  U86({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({List<Function> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x, [Function x0 = _voidFunction]) =>
+      throw 'uncalled';
+  m2(int x0, [int x1 = -1]) => throw 'uncalled';
+  void m3(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  int Function([int]) m4<B extends core.int>() => throw 'uncalled';
+  int Function({List<Function> x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function() m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([List<T>]) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x})
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [int]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int x) m15<B extends core.int>() => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, [List<T>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function({Function x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function(List<T> x) m19<B extends core.int>() => throw 'uncalled';
+  Function Function<A>() m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(A x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function({List<Function> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function<B extends core.int>()
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U86().runTests();
+  new U86<int>(tIsInt: true).runTests();
+  new U86<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type87_test.dart b/tests/language/function_type/function_type87_test.dart
new file mode 100644
index 0000000..c0da986
--- /dev/null
+++ b/tests/language/function_type/function_type87_test.dart
@@ -0,0 +1,954 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {List<Function> x});
+typedef F1<T> = core.List<core.int> Function({Function x});
+typedef F2<T> = Function(int x, [int]);
+typedef F3<T> = void Function(int x, [List<T>]);
+typedef F4<T> = int Function([int]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function({List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function() Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function([List<T>]) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function([Function x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int, [int]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function(int x) Function<B extends core.int>(int x);
+typedef F16<T> = Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, [List<T>]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function({Function x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(List<T> x) Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>() Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(A x) Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+
+Function f0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+core.List<core.int> f1({Function x = _voidFunction}) => throw 'uncalled';
+f2(int x, [int x0 = -1]) => throw 'uncalled';
+void f3(int x, [List<int> x0 = const []]) => throw 'uncalled';
+int Function([int]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function({List<Function> x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function() f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [Function]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([Function x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int x) f15<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, [List<Function> x]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [List<int>]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function({Function x}) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(List<int> x) f19<B extends core.int>(int x) => throw 'uncalled';
+Function Function<A>() f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(A x) f21<B extends core.int>(int x) => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U87<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {List<Function> x}) x0;
+  late core.List<core.int> Function({Function x}) x1;
+  late Function(int x, [int]) x2;
+  late void Function(int x, [List<T>]) x3;
+  late int Function([int]) Function<B extends core.int>(int x) x4;
+  late int Function({List<Function> x}) Function<B extends core.int>(int x) x5;
+  late int Function() Function<B extends core.int>(int x) x6;
+  late Function Function(int, [List<Function> x]) Function<B extends core.int>(
+      int x) x7;
+  late Function Function([List<T>]) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int x, [Function]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function([Function x]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(core.List<core.int>)
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int, [int]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, {List<Function> x}) Function<B extends core.int>(
+      int x) x14;
+  late Function(int x) Function<B extends core.int>(int x) x15;
+  late Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+      x16;
+  late Function(int, [List<T>]) Function<B extends core.int>(int x) x17;
+  late void Function({Function x}) Function<B extends core.int>(int x) x18;
+  late void Function(List<T> x) Function<B extends core.int>(int x) x19;
+  late Function Function<A>() Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(A x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
+
+  U87({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1({Function x = _voidFunction}) => throw 'uncalled';
+  m2(int x, [int x0 = -1]) => throw 'uncalled';
+  void m3(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  int Function([int]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function({List<Function> x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function() m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<T>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x})
+      m10<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int x) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [List<T>]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function({Function x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(List<T> x) m19<B extends core.int>(int x) => throw 'uncalled';
+  Function Function<A>() m20<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function<A>(A x) m21<B extends core.int>(int x) => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function({Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function({Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int x, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int x, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int x, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function<B extends core.int>(
+        int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function({Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U87().runTests();
+  new U87<int>(tIsInt: true).runTests();
+  new U87<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type88_test.dart b/tests/language/function_type/function_type88_test.dart
new file mode 100644
index 0000000..1544392
--- /dev/null
+++ b/tests/language/function_type/function_type88_test.dart
@@ -0,0 +1,917 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {List<Function> x});
+typedef F1<T> = core.List<core.int> Function(int, {Function x});
+typedef F2<T> = Function({int x});
+typedef F3<T> = void Function({List<T> x});
+typedef F4<T> = int Function(int, [int]) Function();
+typedef F5<T> = int Function(int, {List<Function> x}) Function();
+typedef F6<T> = Function Function(int x) Function();
+typedef F7<T> = Function Function(int y, [List<Function> x]) Function();
+typedef F8<T> = Function Function(int, [List<T>]) Function();
+typedef F9<T> = List<Function> Function({Function x}) Function();
+typedef F10<T> = List<Function> Function(List<T> x) Function();
+typedef F11<T> = core.List<core.int> Function(int, [Function x]) Function();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>]) Function();
+typedef F13<T> = List<T> Function(int x, [int]) Function();
+typedef F14<T> = List<T> Function(int y, {List<Function> x}) Function();
+typedef F15<T> = Function([int x]) Function();
+typedef F16<T> = Function(List<Function>) Function();
+typedef F17<T> = Function(int x, [List<T>]) Function();
+typedef F18<T> = void Function(int, {Function x}) Function();
+typedef F19<T> = void Function([List<T> x]) Function();
+typedef F20<T> = Function Function<A>(A x) Function();
+typedef F21<T> = List<T> Function<A>(List<A> x) Function();
+typedef F22<T> = void Function<A>(int x) Function();
+
+Function f0(int y, {List<Function> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x0, {Function x = _voidFunction}) =>
+    throw 'uncalled';
+f2({int x = -1}) => throw 'uncalled';
+void f3({List<int> x = const []}) => throw 'uncalled';
+int Function(int, [int]) f4() => throw 'uncalled';
+int Function(int, {List<Function> x}) f5() => throw 'uncalled';
+Function Function(int x) f6() => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7() => throw 'uncalled';
+Function Function(int, [List<int>]) f8() => throw 'uncalled';
+List<Function> Function({Function x}) f9() => throw 'uncalled';
+List<Function> Function(List<int> x) f10() => throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11() => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12() => throw 'uncalled';
+List<int> Function(int x, [int]) f13() => throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14() => throw 'uncalled';
+Function([int x]) f15() => throw 'uncalled';
+Function(List<Function>) f16() => throw 'uncalled';
+Function(int x, [List<int>]) f17() => throw 'uncalled';
+void Function(int, {Function x}) f18() => throw 'uncalled';
+void Function([List<int> x]) f19() => throw 'uncalled';
+Function Function<A>(A x) f20() => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21() => throw 'uncalled';
+void Function<A>(int x) f22() => throw 'uncalled';
+
+class U88<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {List<Function> x}) x0;
+  late core.List<core.int> Function(int, {Function x}) x1;
+  late Function({int x}) x2;
+  late void Function({List<T> x}) x3;
+  late int Function(int, [int]) Function() x4;
+  late int Function(int, {List<Function> x}) Function() x5;
+  late Function Function(int x) Function() x6;
+  late Function Function(int y, [List<Function> x]) Function() x7;
+  late Function Function(int, [List<T>]) Function() x8;
+  late List<Function> Function({Function x}) Function() x9;
+  late List<Function> Function(List<T> x) Function() x10;
+  late core.List<core.int> Function(int, [Function x]) Function() x11;
+  late core.List<core.int> Function([core.List<core.int>]) Function() x12;
+  late List<T> Function(int x, [int]) Function() x13;
+  late List<T> Function(int y, {List<Function> x}) Function() x14;
+  late Function([int x]) Function() x15;
+  late Function(List<Function>) Function() x16;
+  late Function(int x, [List<T>]) Function() x17;
+  late void Function(int, {Function x}) Function() x18;
+  late void Function([List<T> x]) Function() x19;
+  late Function Function<A>(A x) Function() x20;
+  late List<T> Function<A>(List<A> x) Function() x21;
+  late void Function<A>(int x) Function() x22;
+
+  U88({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {List<Function> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x0, {Function x = _voidFunction}) =>
+      throw 'uncalled';
+  m2({int x = -1}) => throw 'uncalled';
+  void m3({List<T> x = const []}) => throw 'uncalled';
+  int Function(int, [int]) m4() => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5() => throw 'uncalled';
+  Function Function(int x) m6() => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7() => throw 'uncalled';
+  Function Function(int, [List<T>]) m8() => throw 'uncalled';
+  List<Function> Function({Function x}) m9() => throw 'uncalled';
+  List<Function> Function(List<T> x) m10() => throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11() => throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>]) m12() => throw 'uncalled';
+  List<T> Function(int x, [int]) m13() => throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14() => throw 'uncalled';
+  Function([int x]) m15() => throw 'uncalled';
+  Function(List<Function>) m16() => throw 'uncalled';
+  Function(int x, [List<T>]) m17() => throw 'uncalled';
+  void Function(int, {Function x}) m18() => throw 'uncalled';
+  void Function([List<T> x]) m19() => throw 'uncalled';
+  Function Function<A>(A x) m20() => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21() => throw 'uncalled';
+  void Function<A>(int x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function({int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function({int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function({List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int, [int]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int x) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function>) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(A x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(int x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U88().runTests();
+  new U88<int>(tIsInt: true).runTests();
+  new U88<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type89_test.dart b/tests/language/function_type/function_type89_test.dart
new file mode 100644
index 0000000..a1e892f
--- /dev/null
+++ b/tests/language/function_type/function_type89_test.dart
@@ -0,0 +1,921 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(core.List<core.int> x);
+typedef F1<T> = core.List<core.int> Function(int y, {Function x});
+typedef F2<T> = Function(int, {int x});
+typedef F3<T> = void Function(int, {List<T> x});
+typedef F4<T> = int Function(int, [int]) Function(int x);
+typedef F5<T> = int Function(int, {List<Function> x}) Function(int x);
+typedef F6<T> = Function Function(int x) Function(int x);
+typedef F7<T> = Function Function(int y, [List<Function> x]) Function(int x);
+typedef F8<T> = Function Function(int, [List<T>]) Function(int x);
+typedef F9<T> = List<Function> Function({Function x}) Function(int x);
+typedef F10<T> = List<Function> Function(List<T> x) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int, [Function x]) Function(
+    int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>]) Function(
+    int x);
+typedef F13<T> = List<T> Function(int x, [int]) Function(int x);
+typedef F14<T> = List<T> Function(int y, {List<Function> x}) Function(int x);
+typedef F15<T> = Function([int x]) Function(int x);
+typedef F16<T> = Function(List<Function>) Function(int x);
+typedef F17<T> = Function(int x, [List<T>]) Function(int x);
+typedef F18<T> = void Function(int, {Function x}) Function(int x);
+typedef F19<T> = void Function([List<T> x]) Function(int x);
+typedef F20<T> = Function Function<A>(A x) Function(int x);
+typedef F21<T> = List<T> Function<A>(List<A> x) Function(int x);
+typedef F22<T> = void Function<A>(int x) Function(int x);
+
+Function f0(core.List<core.int> x) => throw 'uncalled';
+core.List<core.int> f1(int y, {Function x = _voidFunction}) => throw 'uncalled';
+f2(int x0, {int x = -1}) => throw 'uncalled';
+void f3(int x0, {List<int> x = const []}) => throw 'uncalled';
+int Function(int, [int]) f4(int x) => throw 'uncalled';
+int Function(int, {List<Function> x}) f5(int x) => throw 'uncalled';
+Function Function(int x) f6(int x) => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7(int x) => throw 'uncalled';
+Function Function(int, [List<int>]) f8(int x) => throw 'uncalled';
+List<Function> Function({Function x}) f9(int x) => throw 'uncalled';
+List<Function> Function(List<int> x) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [int]) f13(int x) => throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14(int x) => throw 'uncalled';
+Function([int x]) f15(int x) => throw 'uncalled';
+Function(List<Function>) f16(int x) => throw 'uncalled';
+Function(int x, [List<int>]) f17(int x) => throw 'uncalled';
+void Function(int, {Function x}) f18(int x) => throw 'uncalled';
+void Function([List<int> x]) f19(int x) => throw 'uncalled';
+Function Function<A>(A x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21(int x) => throw 'uncalled';
+void Function<A>(int x) f22(int x) => throw 'uncalled';
+
+class U89<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(core.List<core.int> x) x0;
+  late core.List<core.int> Function(int y, {Function x}) x1;
+  late Function(int, {int x}) x2;
+  late void Function(int, {List<T> x}) x3;
+  late int Function(int, [int]) Function(int x) x4;
+  late int Function(int, {List<Function> x}) Function(int x) x5;
+  late Function Function(int x) Function(int x) x6;
+  late Function Function(int y, [List<Function> x]) Function(int x) x7;
+  late Function Function(int, [List<T>]) Function(int x) x8;
+  late List<Function> Function({Function x}) Function(int x) x9;
+  late List<Function> Function(List<T> x) Function(int x) x10;
+  late core.List<core.int> Function(int, [Function x]) Function(int x) x11;
+  late core.List<core.int> Function([core.List<core.int>]) Function(int x) x12;
+  late List<T> Function(int x, [int]) Function(int x) x13;
+  late List<T> Function(int y, {List<Function> x}) Function(int x) x14;
+  late Function([int x]) Function(int x) x15;
+  late Function(List<Function>) Function(int x) x16;
+  late Function(int x, [List<T>]) Function(int x) x17;
+  late void Function(int, {Function x}) Function(int x) x18;
+  late void Function([List<T> x]) Function(int x) x19;
+  late Function Function<A>(A x) Function(int x) x20;
+  late List<T> Function<A>(List<A> x) Function(int x) x21;
+  late void Function<A>(int x) Function(int x) x22;
+
+  U89({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(core.List<core.int> x) => throw 'uncalled';
+  core.List<core.int> m1(int y, {Function x = _voidFunction}) =>
+      throw 'uncalled';
+  m2(int x0, {int x = -1}) => throw 'uncalled';
+  void m3(int x0, {List<T> x = const []}) => throw 'uncalled';
+  int Function(int, [int]) m4(int x) => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5(int x) => throw 'uncalled';
+  Function Function(int x) m6(int x) => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7(int x) => throw 'uncalled';
+  Function Function(int, [List<T>]) m8(int x) => throw 'uncalled';
+  List<Function> Function({Function x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(List<T> x) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [int]) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14(int x) => throw 'uncalled';
+  Function([int x]) m15(int x) => throw 'uncalled';
+  Function(List<Function>) m16(int x) => throw 'uncalled';
+  Function(int x, [List<T>]) m17(int x) => throw 'uncalled';
+  void Function(int, {Function x}) m18(int x) => throw 'uncalled';
+  void Function([List<T> x]) m19(int x) => throw 'uncalled';
+  Function Function<A>(A x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21(int x) => throw 'uncalled';
+  void Function<A>(int x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(core.List<core.int> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int, [int]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int x) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U89().runTests();
+  new U89<int>(tIsInt: true).runTests();
+  new U89<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type8_test.dart b/tests/language/function_type/function_type8_test.dart
new file mode 100644
index 0000000..d5634fe
--- /dev/null
+++ b/tests/language/function_type/function_type8_test.dart
@@ -0,0 +1,903 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({int x});
+typedef F1<T> = Function Function({List<T> x});
+typedef F2<T> = core.List<core.int> Function(int x, [core.List<core.int>]);
+typedef F3<T> = Function(int, [List<Function>]);
+typedef F4<T> = List<Function> Function<A>(int x);
+typedef F5<T> = int Function(Function x) Function();
+typedef F6<T> = int Function(int y, [core.List<core.int> x]) Function();
+typedef F7<T> = Function Function([int]) Function();
+typedef F8<T> = Function Function({List<Function> x}) Function();
+typedef F9<T> = Function Function() Function();
+typedef F10<T> = List<Function> Function(int, [List<Function> x]) Function();
+typedef F11<T> = List<Function> Function([List<T>]) Function();
+typedef F12<T> = core.List<core.int> Function(int x, [Function]) Function();
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function();
+typedef F14<T> = List<T> Function([Function x]) Function();
+typedef F15<T> = List<T> Function(core.List<core.int>) Function();
+typedef F16<T> = Function(int, [int]) Function();
+typedef F17<T> = Function(int, {List<Function> x}) Function();
+typedef F18<T> = void Function(int x) Function();
+typedef F19<T> = void Function(int y, [List<Function> x]) Function();
+typedef F20<T> = void Function(int, [List<T>]) Function();
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x) Function();
+typedef F22<T> = Function<A>(List<T> x) Function();
+typedef F23<T> = void Function<A>() Function();
+
+int f0({int x = -1}) => throw 'uncalled';
+Function f1({List<int> x = const []}) => throw 'uncalled';
+core.List<core.int> f2(int x, [core.List<core.int> x0 = const []]) =>
+    throw 'uncalled';
+f3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+List<Function> f4<A>(int x) => throw 'uncalled';
+int Function(Function x) f5() => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6() => throw 'uncalled';
+Function Function([int]) f7() => throw 'uncalled';
+Function Function({List<Function> x}) f8() => throw 'uncalled';
+Function Function() f9() => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10() => throw 'uncalled';
+List<Function> Function([List<int>]) f11() => throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12() => throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x}) f13() =>
+    throw 'uncalled';
+List<int> Function([Function x]) f14() => throw 'uncalled';
+List<int> Function(core.List<core.int>) f15() => throw 'uncalled';
+Function(int, [int]) f16() => throw 'uncalled';
+Function(int, {List<Function> x}) f17() => throw 'uncalled';
+void Function(int x) f18() => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19() => throw 'uncalled';
+void Function(int, [List<int>]) f20() => throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21() => throw 'uncalled';
+Function<A>(List<int> x) f22() => throw 'uncalled';
+void Function<A>() f23() => throw 'uncalled';
+
+class U8<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({int x}) x0;
+  late Function Function({List<T> x}) x1;
+  late core.List<core.int> Function(int x, [core.List<core.int>]) x2;
+  late Function(int, [List<Function>]) x3;
+  late List<Function> Function<A>(int x) x4;
+  late int Function(Function x) Function() x5;
+  late int Function(int y, [core.List<core.int> x]) Function() x6;
+  late Function Function([int]) Function() x7;
+  late Function Function({List<Function> x}) Function() x8;
+  late Function Function() Function() x9;
+  late List<Function> Function(int, [List<Function> x]) Function() x10;
+  late List<Function> Function([List<T>]) Function() x11;
+  late core.List<core.int> Function(int x, [Function]) Function() x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x}) Function()
+      x13;
+  late List<T> Function([Function x]) Function() x14;
+  late List<T> Function(core.List<core.int>) Function() x15;
+  late Function(int, [int]) Function() x16;
+  late Function(int, {List<Function> x}) Function() x17;
+  late void Function(int x) Function() x18;
+  late void Function(int y, [List<Function> x]) Function() x19;
+  late void Function(int, [List<T>]) Function() x20;
+  late List<Function> Function<A>(core.List<core.int> x) Function() x21;
+  late Function<A>(List<T> x) Function() x22;
+  late void Function<A>() Function() x23;
+
+  U8({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({int x = -1}) => throw 'uncalled';
+  Function m1({List<T> x = const []}) => throw 'uncalled';
+  core.List<core.int> m2(int x, [core.List<core.int> x0 = const []]) =>
+      throw 'uncalled';
+  m3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  List<Function> m4<A>(int x) => throw 'uncalled';
+  int Function(Function x) m5() => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6() => throw 'uncalled';
+  Function Function([int]) m7() => throw 'uncalled';
+  Function Function({List<Function> x}) m8() => throw 'uncalled';
+  Function Function() m9() => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10() => throw 'uncalled';
+  List<Function> Function([List<T>]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12() => throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x}) m13() =>
+      throw 'uncalled';
+  List<T> Function([Function x]) m14() => throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15() => throw 'uncalled';
+  Function(int, [int]) m16() => throw 'uncalled';
+  Function(int, {List<Function> x}) m17() => throw 'uncalled';
+  void Function(int x) m18() => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19() => throw 'uncalled';
+  void Function(int, [List<T>]) m20() => throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21() => throw 'uncalled';
+  Function<A>(List<T> x) m22() => throw 'uncalled';
+  void Function<A>() m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function({List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function({List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function x) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([int]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function() Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [int]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>() Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U8().runTests();
+  new U8<int>(tIsInt: true).runTests();
+  new U8<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type90_test.dart b/tests/language/function_type/function_type90_test.dart
new file mode 100644
index 0000000..728530c
--- /dev/null
+++ b/tests/language/function_type/function_type90_test.dart
@@ -0,0 +1,963 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([core.List<core.int> x]);
+typedef F1<T> = core.List<core.int> Function(List<Function> x);
+typedef F2<T> = Function(int y, {int x});
+typedef F3<T> = void Function(int y, {List<T> x});
+typedef F4<T> = int Function(int, [int]) Function<B extends core.int>();
+typedef F5<T> = int Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F6<T> = Function Function(int x) Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function({Function x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(List<T> x)
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int x, [int]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F15<T> = Function([int x]) Function<B extends core.int>();
+typedef F16<T> = Function(List<Function>) Function<B extends core.int>();
+typedef F17<T> = Function(int x, [List<T>]) Function<B extends core.int>();
+typedef F18<T> = void Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F19<T> = void Function([List<T> x]) Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(A x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(List<A> x) Function<B extends core.int>();
+typedef F22<T> = void Function<A>(int x) Function<B extends core.int>();
+
+Function f0([core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(List<Function> x) => throw 'uncalled';
+f2(int y, {int x = -1}) => throw 'uncalled';
+void f3(int y, {List<int> x = const []}) => throw 'uncalled';
+int Function(int, [int]) f4<B extends core.int>() => throw 'uncalled';
+int Function(int, {List<Function> x}) f5<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int x) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [List<int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({Function x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(List<int> x) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int x, [int]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function([int x]) f15<B extends core.int>() => throw 'uncalled';
+Function(List<Function>) f16<B extends core.int>() => throw 'uncalled';
+Function(int x, [List<int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, {Function x}) f18<B extends core.int>() => throw 'uncalled';
+void Function([List<int> x]) f19<B extends core.int>() => throw 'uncalled';
+Function Function<A>(A x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21<B extends core.int>() => throw 'uncalled';
+void Function<A>(int x) f22<B extends core.int>() => throw 'uncalled';
+
+class U90<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([core.List<core.int> x]) x0;
+  late core.List<core.int> Function(List<Function> x) x1;
+  late Function(int y, {int x}) x2;
+  late void Function(int y, {List<T> x}) x3;
+  late int Function(int, [int]) Function<B extends core.int>() x4;
+  late int Function(int, {List<Function> x}) Function<B extends core.int>() x5;
+  late Function Function(int x) Function<B extends core.int>() x6;
+  late Function Function(int y, [List<Function> x])
+      Function<B extends core.int>() x7;
+  late Function Function(int, [List<T>]) Function<B extends core.int>() x8;
+  late List<Function> Function({Function x}) Function<B extends core.int>() x9;
+  late List<Function> Function(List<T> x) Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, [Function x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function([core.List<core.int>])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int x, [int]) Function<B extends core.int>() x13;
+  late List<T> Function(int y, {List<Function> x})
+      Function<B extends core.int>() x14;
+  late Function([int x]) Function<B extends core.int>() x15;
+  late Function(List<Function>) Function<B extends core.int>() x16;
+  late Function(int x, [List<T>]) Function<B extends core.int>() x17;
+  late void Function(int, {Function x}) Function<B extends core.int>() x18;
+  late void Function([List<T> x]) Function<B extends core.int>() x19;
+  late Function Function<A>(A x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(List<A> x) Function<B extends core.int>() x21;
+  late void Function<A>(int x) Function<B extends core.int>() x22;
+
+  U90({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(List<Function> x) => throw 'uncalled';
+  m2(int y, {int x = -1}) => throw 'uncalled';
+  void m3(int y, {List<T> x = const []}) => throw 'uncalled';
+  int Function(int, [int]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int x) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [List<T>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({Function x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(List<T> x) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x, [int]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function([int x]) m15<B extends core.int>() => throw 'uncalled';
+  Function(List<Function>) m16<B extends core.int>() => throw 'uncalled';
+  Function(int x, [List<T>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, {Function x}) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([List<T> x]) m19<B extends core.int>() => throw 'uncalled';
+  Function Function<A>(A x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21<B extends core.int>() => throw 'uncalled';
+  void Function<A>(int x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(List<Function> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(List<Function> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int y, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int y, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int y, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int, [int]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function<B extends core.int>()
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int x, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is void Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U90().runTests();
+  new U90<int>(tIsInt: true).runTests();
+  new U90<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type91_test.dart b/tests/language/function_type/function_type91_test.dart
new file mode 100644
index 0000000..102e3de
--- /dev/null
+++ b/tests/language/function_type/function_type91_test.dart
@@ -0,0 +1,954 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [core.List<core.int> x]);
+typedef F1<T> = core.List<core.int> Function([List<Function> x]);
+typedef F2<T> = Function(Function x);
+typedef F3<T> = void Function();
+typedef F4<T> = int Function(int, [int]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F6<T> = Function Function(int x) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function({Function x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int x, [int]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function([int x]) Function<B extends core.int>(int x);
+typedef F16<T> = Function(List<Function>) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int x, [List<T>]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([List<T> x]) Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(A x) Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = void Function<A>(int x) Function<B extends core.int>(int x);
+
+Function f0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f1([List<Function> x = const []]) => throw 'uncalled';
+f2(Function x) => throw 'uncalled';
+void f3() => throw 'uncalled';
+int Function(int, [int]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, {List<Function> x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int x) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [List<int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({Function x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<int> x) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [int]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([int x]) f15<B extends core.int>(int x) => throw 'uncalled';
+Function(List<Function>) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int x, [List<int>]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, {Function x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([List<int> x]) f19<B extends core.int>(int x) => throw 'uncalled';
+Function Function<A>(A x) f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function<A>(int x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U91<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [core.List<core.int> x]) x0;
+  late core.List<core.int> Function([List<Function> x]) x1;
+  late Function(Function x) x2;
+  late void Function() x3;
+  late int Function(int, [int]) Function<B extends core.int>(int x) x4;
+  late int Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+      x5;
+  late Function Function(int x) Function<B extends core.int>(int x) x6;
+  late Function Function(int y, [List<Function> x])
+      Function<B extends core.int>(int x) x7;
+  late Function Function(int, [List<T>]) Function<B extends core.int>(int x) x8;
+  late List<Function> Function({Function x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(List<T> x) Function<B extends core.int>(int x)
+      x10;
+  late core.List<core.int> Function(int, [Function x])
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function([core.List<core.int>])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int x, [int]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int y, {List<Function> x}) Function<B extends core.int>(
+      int x) x14;
+  late Function([int x]) Function<B extends core.int>(int x) x15;
+  late Function(List<Function>) Function<B extends core.int>(int x) x16;
+  late Function(int x, [List<T>]) Function<B extends core.int>(int x) x17;
+  late void Function(int, {Function x}) Function<B extends core.int>(int x) x18;
+  late void Function([List<T> x]) Function<B extends core.int>(int x) x19;
+  late Function Function<A>(A x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(List<A> x) Function<B extends core.int>(int x) x21;
+  late void Function<A>(int x) Function<B extends core.int>(int x) x22;
+
+  U91({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1([List<Function> x = const []]) => throw 'uncalled';
+  m2(Function x) => throw 'uncalled';
+  void m3() => throw 'uncalled';
+  int Function(int, [int]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int x) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [List<T>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({Function x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<T> x) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [int]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([int x]) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(List<Function>) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int x, [List<T>]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, {Function x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<T> x]) m19<B extends core.int>(int x) => throw 'uncalled';
+  Function Function<A>(A x) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function<A>(int x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(Function x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(Function x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function()
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function() l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function());
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function<B extends core.int>(
+        int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int x, [List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is void Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U91().runTests();
+  new U91<int>(tIsInt: true).runTests();
+  new U91<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type92_test.dart b/tests/language/function_type/function_type92_test.dart
new file mode 100644
index 0000000..053e0f8
--- /dev/null
+++ b/tests/language/function_type/function_type92_test.dart
@@ -0,0 +1,868 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [core.List<core.int> x]);
+typedef F1<T> = core.List<core.int> Function(int, [List<Function> x]);
+typedef F2<T> = Function([Function x]);
+typedef F3<T> = int Function<A>(int x);
+typedef F4<T> = int Function(int x, [int]) Function();
+typedef F5<T> = int Function(int y, {List<Function> x}) Function();
+typedef F6<T> = Function Function([int x]) Function();
+typedef F7<T> = Function Function(List<Function>) Function();
+typedef F8<T> = Function Function(int x, [List<T>]) Function();
+typedef F9<T> = List<Function> Function(int, {Function x}) Function();
+typedef F10<T> = List<Function> Function([List<T> x]) Function();
+typedef F11<T> = core.List<core.int> Function(int y, [Function x]) Function();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function();
+typedef F13<T> = List<T> Function({int x}) Function();
+typedef F14<T> = List<T> Function(core.List<core.int> x) Function();
+typedef F15<T> = Function(int, [int x]) Function();
+typedef F16<T> = Function([List<Function>]) Function();
+typedef F17<T> = Function({List<T> x}) Function();
+typedef F18<T> = void Function(int y, {Function x}) Function();
+typedef F19<T> = void Function(int, [List<T> x]) Function();
+typedef F20<T> = Function Function<A>(List<A> x) Function();
+typedef F21<T> = Function<A>(int x) Function();
+typedef F22<T> = void Function<A>(Function x) Function();
+
+Function f0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [List<Function> x = const []]) =>
+    throw 'uncalled';
+f2([Function x = _voidFunction]) => throw 'uncalled';
+int f3<A>(int x) => throw 'uncalled';
+int Function(int x, [int]) f4() => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5() => throw 'uncalled';
+Function Function([int x]) f6() => throw 'uncalled';
+Function Function(List<Function>) f7() => throw 'uncalled';
+Function Function(int x, [List<int>]) f8() => throw 'uncalled';
+List<Function> Function(int, {Function x}) f9() => throw 'uncalled';
+List<Function> Function([List<int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>]) f12() =>
+    throw 'uncalled';
+List<int> Function({int x}) f13() => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14() => throw 'uncalled';
+Function(int, [int x]) f15() => throw 'uncalled';
+Function([List<Function>]) f16() => throw 'uncalled';
+Function({List<int> x}) f17() => throw 'uncalled';
+void Function(int y, {Function x}) f18() => throw 'uncalled';
+void Function(int, [List<int> x]) f19() => throw 'uncalled';
+Function Function<A>(List<A> x) f20() => throw 'uncalled';
+Function<A>(int x) f21() => throw 'uncalled';
+void Function<A>(Function x) f22() => throw 'uncalled';
+
+class U92<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [core.List<core.int> x]) x0;
+  late core.List<core.int> Function(int, [List<Function> x]) x1;
+  late Function([Function x]) x2;
+  late int Function<A>(int x) x3;
+  late int Function(int x, [int]) Function() x4;
+  late int Function(int y, {List<Function> x}) Function() x5;
+  late Function Function([int x]) Function() x6;
+  late Function Function(List<Function>) Function() x7;
+  late Function Function(int x, [List<T>]) Function() x8;
+  late List<Function> Function(int, {Function x}) Function() x9;
+  late List<Function> Function([List<T> x]) Function() x10;
+  late core.List<core.int> Function(int y, [Function x]) Function() x11;
+  late core.List<core.int> Function(int, [core.List<core.int>]) Function() x12;
+  late List<T> Function({int x}) Function() x13;
+  late List<T> Function(core.List<core.int> x) Function() x14;
+  late Function(int, [int x]) Function() x15;
+  late Function([List<Function>]) Function() x16;
+  late Function({List<T> x}) Function() x17;
+  late void Function(int y, {Function x}) Function() x18;
+  late void Function(int, [List<T> x]) Function() x19;
+  late Function Function<A>(List<A> x) Function() x20;
+  late Function<A>(int x) Function() x21;
+  late void Function<A>(Function x) Function() x22;
+
+  U92({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [List<Function> x = const []]) =>
+      throw 'uncalled';
+  m2([Function x = _voidFunction]) => throw 'uncalled';
+  int m3<A>(int x) => throw 'uncalled';
+  int Function(int x, [int]) m4() => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5() => throw 'uncalled';
+  Function Function([int x]) m6() => throw 'uncalled';
+  Function Function(List<Function>) m7() => throw 'uncalled';
+  Function Function(int x, [List<T>]) m8() => throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9() => throw 'uncalled';
+  List<Function> Function([List<T> x]) m10() => throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>]) m12() =>
+      throw 'uncalled';
+  List<T> Function({int x}) m13() => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14() => throw 'uncalled';
+  Function(int, [int x]) m15() => throw 'uncalled';
+  Function([List<Function>]) m16() => throw 'uncalled';
+  Function({List<T> x}) m17() => throw 'uncalled';
+  void Function(int y, {Function x}) m18() => throw 'uncalled';
+  void Function(int, [List<T> x]) m19() => throw 'uncalled';
+  Function Function<A>(List<A> x) m20() => throw 'uncalled';
+  Function<A>(int x) m21() => throw 'uncalled';
+  void Function<A>(Function x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(int x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(int x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function([int x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function>) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12
+        is core.List<core.int> Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function({int x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(int x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U92().runTests();
+  new U92<int>(tIsInt: true).runTests();
+  new U92<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type93_test.dart b/tests/language/function_type/function_type93_test.dart
new file mode 100644
index 0000000..e87c2ba
--- /dev/null
+++ b/tests/language/function_type/function_type93_test.dart
@@ -0,0 +1,878 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(core.List<core.int>);
+typedef F1<T> = core.List<core.int> Function(int y, [List<Function> x]);
+typedef F2<T> = Function(int, [Function x]);
+typedef F3<T> = int Function<A>(Function x);
+typedef F4<T> = int Function(int x, [int]) Function(int x);
+typedef F5<T> = int Function(int y, {List<Function> x}) Function(int x);
+typedef F6<T> = Function Function([int x]) Function(int x);
+typedef F7<T> = Function Function(List<Function>) Function(int x);
+typedef F8<T> = Function Function(int x, [List<T>]) Function(int x);
+typedef F9<T> = List<Function> Function(int, {Function x}) Function(int x);
+typedef F10<T> = List<Function> Function([List<T> x]) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int y, [Function x]) Function(
+    int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function(int x);
+typedef F13<T> = List<T> Function({int x}) Function(int x);
+typedef F14<T> = List<T> Function(core.List<core.int> x) Function(int x);
+typedef F15<T> = Function(int, [int x]) Function(int x);
+typedef F16<T> = Function([List<Function>]) Function(int x);
+typedef F17<T> = Function({List<T> x}) Function(int x);
+typedef F18<T> = void Function(int y, {Function x}) Function(int x);
+typedef F19<T> = void Function(int, [List<T> x]) Function(int x);
+typedef F20<T> = Function Function<A>(List<A> x) Function(int x);
+typedef F21<T> = Function<A>(int x) Function(int x);
+typedef F22<T> = void Function<A>(Function x) Function(int x);
+
+Function f0(core.List<core.int> x0) => throw 'uncalled';
+core.List<core.int> f1(int y, [List<Function> x = const []]) =>
+    throw 'uncalled';
+f2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+int f3<A>(Function x) => throw 'uncalled';
+int Function(int x, [int]) f4(int x) => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5(int x) => throw 'uncalled';
+Function Function([int x]) f6(int x) => throw 'uncalled';
+Function Function(List<Function>) f7(int x) => throw 'uncalled';
+Function Function(int x, [List<int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int, {Function x}) f9(int x) => throw 'uncalled';
+List<Function> Function([List<int> x]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function({int x}) f13(int x) => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14(int x) => throw 'uncalled';
+Function(int, [int x]) f15(int x) => throw 'uncalled';
+Function([List<Function>]) f16(int x) => throw 'uncalled';
+Function({List<int> x}) f17(int x) => throw 'uncalled';
+void Function(int y, {Function x}) f18(int x) => throw 'uncalled';
+void Function(int, [List<int> x]) f19(int x) => throw 'uncalled';
+Function Function<A>(List<A> x) f20(int x) => throw 'uncalled';
+Function<A>(int x) f21(int x) => throw 'uncalled';
+void Function<A>(Function x) f22(int x) => throw 'uncalled';
+
+class U93<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(core.List<core.int>) x0;
+  late core.List<core.int> Function(int y, [List<Function> x]) x1;
+  late Function(int, [Function x]) x2;
+  late int Function<A>(Function x) x3;
+  late int Function(int x, [int]) Function(int x) x4;
+  late int Function(int y, {List<Function> x}) Function(int x) x5;
+  late Function Function([int x]) Function(int x) x6;
+  late Function Function(List<Function>) Function(int x) x7;
+  late Function Function(int x, [List<T>]) Function(int x) x8;
+  late List<Function> Function(int, {Function x}) Function(int x) x9;
+  late List<Function> Function([List<T> x]) Function(int x) x10;
+  late core.List<core.int> Function(int y, [Function x]) Function(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int>]) Function(int x)
+      x12;
+  late List<T> Function({int x}) Function(int x) x13;
+  late List<T> Function(core.List<core.int> x) Function(int x) x14;
+  late Function(int, [int x]) Function(int x) x15;
+  late Function([List<Function>]) Function(int x) x16;
+  late Function({List<T> x}) Function(int x) x17;
+  late void Function(int y, {Function x}) Function(int x) x18;
+  late void Function(int, [List<T> x]) Function(int x) x19;
+  late Function Function<A>(List<A> x) Function(int x) x20;
+  late Function<A>(int x) Function(int x) x21;
+  late void Function<A>(Function x) Function(int x) x22;
+
+  U93({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(core.List<core.int> x0) => throw 'uncalled';
+  core.List<core.int> m1(int y, [List<Function> x = const []]) =>
+      throw 'uncalled';
+  m2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  int m3<A>(Function x) => throw 'uncalled';
+  int Function(int x, [int]) m4(int x) => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5(int x) => throw 'uncalled';
+  Function Function([int x]) m6(int x) => throw 'uncalled';
+  Function Function(List<Function>) m7(int x) => throw 'uncalled';
+  Function Function(int x, [List<T>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9(int x) => throw 'uncalled';
+  List<Function> Function([List<T> x]) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function({int x}) m13(int x) => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14(int x) => throw 'uncalled';
+  Function(int, [int x]) m15(int x) => throw 'uncalled';
+  Function([List<Function>]) m16(int x) => throw 'uncalled';
+  Function({List<T> x}) m17(int x) => throw 'uncalled';
+  void Function(int y, {Function x}) m18(int x) => throw 'uncalled';
+  void Function(int, [List<T> x]) m19(int x) => throw 'uncalled';
+  Function Function<A>(List<A> x) m20(int x) => throw 'uncalled';
+  Function<A>(int x) m21(int x) => throw 'uncalled';
+  void Function<A>(Function x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(core.List<core.int>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(core.List<core.int>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(
+        m1 is core.List<core.int> Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(Function x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(Function x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [Function x])
+        Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U93().runTests();
+  new U93<int>(tIsInt: true).runTests();
+  new U93<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type94_test.dart b/tests/language/function_type/function_type94_test.dart
new file mode 100644
index 0000000..011496a
--- /dev/null
+++ b/tests/language/function_type/function_type94_test.dart
@@ -0,0 +1,912 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([core.List<core.int>]);
+typedef F1<T> = core.List<core.int> Function(List<Function>);
+typedef F2<T> = Function(int y, [Function x]);
+typedef F3<T> = int Function<A>(List<Function> x);
+typedef F4<T> = int Function(int x, [int]) Function<B extends core.int>();
+typedef F5<T> = int Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F6<T> = Function Function([int x]) Function<B extends core.int>();
+typedef F7<T> = Function Function(List<Function>)
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([List<T> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function({int x}) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F15<T> = Function(int, [int x]) Function<B extends core.int>();
+typedef F16<T> = Function([List<Function>]) Function<B extends core.int>();
+typedef F17<T> = Function({List<T> x}) Function<B extends core.int>();
+typedef F18<T> = void Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F19<T> = void Function(int, [List<T> x]) Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(List<A> x) Function<B extends core.int>();
+typedef F21<T> = Function<A>(int x) Function<B extends core.int>();
+typedef F22<T> = void Function<A>(Function x) Function<B extends core.int>();
+
+Function f0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(List<Function> x0) => throw 'uncalled';
+f2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+int f3<A>(List<Function> x) => throw 'uncalled';
+int Function(int x, [int]) f4<B extends core.int>() => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([int x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(List<Function>) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [List<int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {Function x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<int> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function({int x}) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, [int x]) f15<B extends core.int>() => throw 'uncalled';
+Function([List<Function>]) f16<B extends core.int>() => throw 'uncalled';
+Function({List<int> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, {Function x}) f18<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, [List<int> x]) f19<B extends core.int>() => throw 'uncalled';
+Function Function<A>(List<A> x) f20<B extends core.int>() => throw 'uncalled';
+Function<A>(int x) f21<B extends core.int>() => throw 'uncalled';
+void Function<A>(Function x) f22<B extends core.int>() => throw 'uncalled';
+
+class U94<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([core.List<core.int>]) x0;
+  late core.List<core.int> Function(List<Function>) x1;
+  late Function(int y, [Function x]) x2;
+  late int Function<A>(List<Function> x) x3;
+  late int Function(int x, [int]) Function<B extends core.int>() x4;
+  late int Function(int y, {List<Function> x}) Function<B extends core.int>()
+      x5;
+  late Function Function([int x]) Function<B extends core.int>() x6;
+  late Function Function(List<Function>) Function<B extends core.int>() x7;
+  late Function Function(int x, [List<T>]) Function<B extends core.int>() x8;
+  late List<Function> Function(int, {Function x}) Function<B extends core.int>()
+      x9;
+  late List<Function> Function([List<T> x]) Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int y, [Function x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x12;
+  late List<T> Function({int x}) Function<B extends core.int>() x13;
+  late List<T> Function(core.List<core.int> x) Function<B extends core.int>()
+      x14;
+  late Function(int, [int x]) Function<B extends core.int>() x15;
+  late Function([List<Function>]) Function<B extends core.int>() x16;
+  late Function({List<T> x}) Function<B extends core.int>() x17;
+  late void Function(int y, {Function x}) Function<B extends core.int>() x18;
+  late void Function(int, [List<T> x]) Function<B extends core.int>() x19;
+  late Function Function<A>(List<A> x) Function<B extends core.int>() x20;
+  late Function<A>(int x) Function<B extends core.int>() x21;
+  late void Function<A>(Function x) Function<B extends core.int>() x22;
+
+  U94({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(List<Function> x0) => throw 'uncalled';
+  m2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  int m3<A>(List<Function> x) => throw 'uncalled';
+  int Function(int x, [int]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([int x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(List<Function>) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int x, [List<T>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<T> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function({int x}) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, [int x]) m15<B extends core.int>() => throw 'uncalled';
+  Function([List<Function>]) m16<B extends core.int>() => throw 'uncalled';
+  Function({List<T> x}) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int y, {Function x}) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, [List<T> x]) m19<B extends core.int>() => throw 'uncalled';
+  Function Function<A>(List<A> x) m20<B extends core.int>() => throw 'uncalled';
+  Function<A>(int x) m21<B extends core.int>() => throw 'uncalled';
+  void Function<A>(Function x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(List<Function>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(List<Function>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int y, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int y, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(List<Function> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is void Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U94().runTests();
+  new U94<int>(tIsInt: true).runTests();
+  new U94<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type95_test.dart b/tests/language/function_type/function_type95_test.dart
new file mode 100644
index 0000000..e5be48e
--- /dev/null
+++ b/tests/language/function_type/function_type95_test.dart
@@ -0,0 +1,932 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [core.List<core.int>]);
+typedef F1<T> = core.List<core.int> Function([List<Function>]);
+typedef F2<T> = Function(Function);
+typedef F3<T> = int Function<A>(core.List<core.int> x);
+typedef F4<T> = int Function(int x, [int]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F6<T> = Function Function([int x]) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([List<T> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function({int x}) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function(int, [int x]) Function<B extends core.int>(int x);
+typedef F16<T> = Function([List<Function>]) Function<B extends core.int>(int x);
+typedef F17<T> = Function({List<T> x}) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = Function Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = Function<A>(int x) Function<B extends core.int>(int x);
+typedef F22<T> = void Function<A>(Function x) Function<B extends core.int>(
+    int x);
+
+Function f0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f1([List<Function> x0 = const []]) => throw 'uncalled';
+f2(Function x0) => throw 'uncalled';
+int f3<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int x, [int]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([int x]) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(List<Function>) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int x, [List<int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {Function x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([List<int> x]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function({int x}) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [int x]) f15<B extends core.int>(int x) => throw 'uncalled';
+Function([List<Function>]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function({List<int> x}) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, {Function x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [List<int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(List<A> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(int x) f21<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(Function x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U95<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [core.List<core.int>]) x0;
+  late core.List<core.int> Function([List<Function>]) x1;
+  late Function(Function) x2;
+  late int Function<A>(core.List<core.int> x) x3;
+  late int Function(int x, [int]) Function<B extends core.int>(int x) x4;
+  late int Function(int y, {List<Function> x}) Function<B extends core.int>(
+      int x) x5;
+  late Function Function([int x]) Function<B extends core.int>(int x) x6;
+  late Function Function(List<Function>) Function<B extends core.int>(int x) x7;
+  late Function Function(int x, [List<T>]) Function<B extends core.int>(int x)
+      x8;
+  late List<Function> Function(int, {Function x}) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function([List<T> x]) Function<B extends core.int>(int x)
+      x10;
+  late core.List<core.int> Function(int y, [Function x])
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function({int x}) Function<B extends core.int>(int x) x13;
+  late List<T> Function(core.List<core.int> x) Function<B extends core.int>(
+      int x) x14;
+  late Function(int, [int x]) Function<B extends core.int>(int x) x15;
+  late Function([List<Function>]) Function<B extends core.int>(int x) x16;
+  late Function({List<T> x}) Function<B extends core.int>(int x) x17;
+  late void Function(int y, {Function x}) Function<B extends core.int>(int x)
+      x18;
+  late void Function(int, [List<T> x]) Function<B extends core.int>(int x) x19;
+  late Function Function<A>(List<A> x) Function<B extends core.int>(int x) x20;
+  late Function<A>(int x) Function<B extends core.int>(int x) x21;
+  late void Function<A>(Function x) Function<B extends core.int>(int x) x22;
+
+  U95({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m1([List<Function> x0 = const []]) => throw 'uncalled';
+  m2(Function x0) => throw 'uncalled';
+  int m3<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int x, [int]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([int x]) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(List<Function>) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int x, [List<T>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<T> x]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function({int x}) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [int x]) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function([List<Function>]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function({List<T> x}) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, {Function x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [List<T> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(List<A> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(int x) m21<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(Function x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(Function)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(Function) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(Function));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(core.List<core.int> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int x, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function<B extends core.int>(int x)
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is Function(int, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([List<Function>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function({List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U95().runTests();
+  new U95<int>(tIsInt: true).runTests();
+  new U95<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type96_test.dart b/tests/language/function_type/function_type96_test.dart
new file mode 100644
index 0000000..ec3c67d
--- /dev/null
+++ b/tests/language/function_type/function_type96_test.dart
@@ -0,0 +1,895 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [core.List<core.int>]);
+typedef F1<T> = core.List<core.int> Function(int, [List<Function>]);
+typedef F2<T> = Function([Function]);
+typedef F3<T> = int Function<A>(List<T> x);
+typedef F4<T> = int Function({int x}) Function();
+typedef F5<T> = int Function(core.List<core.int> x) Function();
+typedef F6<T> = Function Function(int, [int x]) Function();
+typedef F7<T> = Function Function([List<Function>]) Function();
+typedef F8<T> = Function Function({List<T> x}) Function();
+typedef F9<T> = List<Function> Function(int y, {Function x}) Function();
+typedef F10<T> = List<Function> Function(int, [List<T> x]) Function();
+typedef F11<T> = core.List<core.int> Function(Function) Function();
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function();
+typedef F13<T> = List<T> Function(int, {int x}) Function();
+typedef F14<T> = List<T> Function([core.List<core.int> x]) Function();
+typedef F15<T> = Function(int y, [int x]) Function();
+typedef F16<T> = Function(int, [List<Function>]) Function();
+typedef F17<T> = Function(int, {List<T> x}) Function();
+typedef F18<T> = void Function(List<Function> x) Function();
+typedef F19<T> = void Function(int y, [List<T> x]) Function();
+typedef F20<T> = List<Function> Function<A>(int x) Function();
+typedef F21<T> = Function<A>(Function x) Function();
+typedef F22<T> = void Function<A>(List<Function> x) Function();
+
+Function f0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [List<Function> x1 = const []]) =>
+    throw 'uncalled';
+f2([Function x0 = _voidFunction]) => throw 'uncalled';
+int f3<A>(List<int> x) => throw 'uncalled';
+int Function({int x}) f4() => throw 'uncalled';
+int Function(core.List<core.int> x) f5() => throw 'uncalled';
+Function Function(int, [int x]) f6() => throw 'uncalled';
+Function Function([List<Function>]) f7() => throw 'uncalled';
+Function Function({List<int> x}) f8() => throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9() => throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(Function) f11() => throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>]) f12() =>
+    throw 'uncalled';
+List<int> Function(int, {int x}) f13() => throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14() => throw 'uncalled';
+Function(int y, [int x]) f15() => throw 'uncalled';
+Function(int, [List<Function>]) f16() => throw 'uncalled';
+Function(int, {List<int> x}) f17() => throw 'uncalled';
+void Function(List<Function> x) f18() => throw 'uncalled';
+void Function(int y, [List<int> x]) f19() => throw 'uncalled';
+List<Function> Function<A>(int x) f20() => throw 'uncalled';
+Function<A>(Function x) f21() => throw 'uncalled';
+void Function<A>(List<Function> x) f22() => throw 'uncalled';
+
+class U96<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [core.List<core.int>]) x0;
+  late core.List<core.int> Function(int, [List<Function>]) x1;
+  late Function([Function]) x2;
+  late int Function<A>(List<T> x) x3;
+  late int Function({int x}) Function() x4;
+  late int Function(core.List<core.int> x) Function() x5;
+  late Function Function(int, [int x]) Function() x6;
+  late Function Function([List<Function>]) Function() x7;
+  late Function Function({List<T> x}) Function() x8;
+  late List<Function> Function(int y, {Function x}) Function() x9;
+  late List<Function> Function(int, [List<T> x]) Function() x10;
+  late core.List<core.int> Function(Function) Function() x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>]) Function()
+      x12;
+  late List<T> Function(int, {int x}) Function() x13;
+  late List<T> Function([core.List<core.int> x]) Function() x14;
+  late Function(int y, [int x]) Function() x15;
+  late Function(int, [List<Function>]) Function() x16;
+  late Function(int, {List<T> x}) Function() x17;
+  late void Function(List<Function> x) Function() x18;
+  late void Function(int y, [List<T> x]) Function() x19;
+  late List<Function> Function<A>(int x) Function() x20;
+  late Function<A>(Function x) Function() x21;
+  late void Function<A>(List<Function> x) Function() x22;
+
+  U96({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [List<Function> x1 = const []]) =>
+      throw 'uncalled';
+  m2([Function x0 = _voidFunction]) => throw 'uncalled';
+  int m3<A>(List<T> x) => throw 'uncalled';
+  int Function({int x}) m4() => throw 'uncalled';
+  int Function(core.List<core.int> x) m5() => throw 'uncalled';
+  Function Function(int, [int x]) m6() => throw 'uncalled';
+  Function Function([List<Function>]) m7() => throw 'uncalled';
+  Function Function({List<T> x}) m8() => throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9() => throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10() => throw 'uncalled';
+  core.List<core.int> Function(Function) m11() => throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>]) m12() =>
+      throw 'uncalled';
+  List<T> Function(int, {int x}) m13() => throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14() => throw 'uncalled';
+  Function(int y, [int x]) m15() => throw 'uncalled';
+  Function(int, [List<Function>]) m16() => throw 'uncalled';
+  Function(int, {List<T> x}) m17() => throw 'uncalled';
+  void Function(List<Function> x) m18() => throw 'uncalled';
+  void Function(int y, [List<T> x]) m19() => throw 'uncalled';
+  List<Function> Function<A>(int x) m20() => throw 'uncalled';
+  Function<A>(Function x) m21() => throw 'uncalled';
+  void Function<A>(List<Function> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(List<T> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(List<T> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function({int x}) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function({int x}) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U96().runTests();
+  new U96<int>(tIsInt: true).runTests();
+  new U96<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type97_test.dart b/tests/language/function_type/function_type97_test.dart
new file mode 100644
index 0000000..061794a
--- /dev/null
+++ b/tests/language/function_type/function_type97_test.dart
@@ -0,0 +1,874 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({core.List<core.int> x});
+typedef F1<T> = core.List<core.int> Function(int x, [List<Function>]);
+typedef F2<T> = Function(int, [Function]);
+typedef F3<T> = int Function<A>();
+typedef F4<T> = int Function({int x}) Function(int x);
+typedef F5<T> = int Function(core.List<core.int> x) Function(int x);
+typedef F6<T> = Function Function(int, [int x]) Function(int x);
+typedef F7<T> = Function Function([List<Function>]) Function(int x);
+typedef F8<T> = Function Function({List<T> x}) Function(int x);
+typedef F9<T> = List<Function> Function(int y, {Function x}) Function(int x);
+typedef F10<T> = List<Function> Function(int, [List<T> x]) Function(int x);
+typedef F11<T> = core.List<core.int> Function(Function) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function(int x);
+typedef F13<T> = List<T> Function(int, {int x}) Function(int x);
+typedef F14<T> = List<T> Function([core.List<core.int> x]) Function(int x);
+typedef F15<T> = Function(int y, [int x]) Function(int x);
+typedef F16<T> = Function(int, [List<Function>]) Function(int x);
+typedef F17<T> = Function(int, {List<T> x}) Function(int x);
+typedef F18<T> = void Function(List<Function> x) Function(int x);
+typedef F19<T> = void Function(int y, [List<T> x]) Function(int x);
+typedef F20<T> = List<Function> Function<A>(int x) Function(int x);
+typedef F21<T> = Function<A>(Function x) Function(int x);
+typedef F22<T> = void Function<A>(List<Function> x) Function(int x);
+
+Function f0({core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x, [List<Function> x0 = const []]) =>
+    throw 'uncalled';
+f2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+int f3<A>() => throw 'uncalled';
+int Function({int x}) f4(int x) => throw 'uncalled';
+int Function(core.List<core.int> x) f5(int x) => throw 'uncalled';
+Function Function(int, [int x]) f6(int x) => throw 'uncalled';
+Function Function([List<Function>]) f7(int x) => throw 'uncalled';
+Function Function({List<int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(Function) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {int x}) f13(int x) => throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14(int x) => throw 'uncalled';
+Function(int y, [int x]) f15(int x) => throw 'uncalled';
+Function(int, [List<Function>]) f16(int x) => throw 'uncalled';
+Function(int, {List<int> x}) f17(int x) => throw 'uncalled';
+void Function(List<Function> x) f18(int x) => throw 'uncalled';
+void Function(int y, [List<int> x]) f19(int x) => throw 'uncalled';
+List<Function> Function<A>(int x) f20(int x) => throw 'uncalled';
+Function<A>(Function x) f21(int x) => throw 'uncalled';
+void Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+
+class U97<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({core.List<core.int> x}) x0;
+  late core.List<core.int> Function(int x, [List<Function>]) x1;
+  late Function(int, [Function]) x2;
+  late int Function<A>() x3;
+  late int Function({int x}) Function(int x) x4;
+  late int Function(core.List<core.int> x) Function(int x) x5;
+  late Function Function(int, [int x]) Function(int x) x6;
+  late Function Function([List<Function>]) Function(int x) x7;
+  late Function Function({List<T> x}) Function(int x) x8;
+  late List<Function> Function(int y, {Function x}) Function(int x) x9;
+  late List<Function> Function(int, [List<T> x]) Function(int x) x10;
+  late core.List<core.int> Function(Function) Function(int x) x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>]) Function(
+      int x) x12;
+  late List<T> Function(int, {int x}) Function(int x) x13;
+  late List<T> Function([core.List<core.int> x]) Function(int x) x14;
+  late Function(int y, [int x]) Function(int x) x15;
+  late Function(int, [List<Function>]) Function(int x) x16;
+  late Function(int, {List<T> x}) Function(int x) x17;
+  late void Function(List<Function> x) Function(int x) x18;
+  late void Function(int y, [List<T> x]) Function(int x) x19;
+  late List<Function> Function<A>(int x) Function(int x) x20;
+  late Function<A>(Function x) Function(int x) x21;
+  late void Function<A>(List<Function> x) Function(int x) x22;
+
+  U97({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x, [List<Function> x0 = const []]) =>
+      throw 'uncalled';
+  m2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  int m3<A>() => throw 'uncalled';
+  int Function({int x}) m4(int x) => throw 'uncalled';
+  int Function(core.List<core.int> x) m5(int x) => throw 'uncalled';
+  Function Function(int, [int x]) m6(int x) => throw 'uncalled';
+  Function Function([List<Function>]) m7(int x) => throw 'uncalled';
+  Function Function({List<T> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(Function) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {int x}) m13(int x) => throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14(int x) => throw 'uncalled';
+  Function(int y, [int x]) m15(int x) => throw 'uncalled';
+  Function(int, [List<Function>]) m16(int x) => throw 'uncalled';
+  Function(int, {List<T> x}) m17(int x) => throw 'uncalled';
+  void Function(List<Function> x) m18(int x) => throw 'uncalled';
+  void Function(int y, [List<T> x]) m19(int x) => throw 'uncalled';
+  List<Function> Function<A>(int x) m20(int x) => throw 'uncalled';
+  Function<A>(Function x) m21(int x) => throw 'uncalled';
+  void Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>()
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>());
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function({int x}) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(Function) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U97().runTests();
+  new U97<int>(tIsInt: true).runTests();
+  new U97<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type98_test.dart b/tests/language/function_type/function_type98_test.dart
new file mode 100644
index 0000000..1a7aded
--- /dev/null
+++ b/tests/language/function_type/function_type98_test.dart
@@ -0,0 +1,918 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {core.List<core.int> x});
+typedef F1<T> = core.List<core.int> Function({List<Function> x});
+typedef F2<T> = Function(int x, [Function]);
+typedef F3<T> = int Function<A>(A x);
+typedef F4<T> = int Function({int x}) Function<B extends core.int>();
+typedef F5<T> = int Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F6<T> = Function Function(int, [int x]) Function<B extends core.int>();
+typedef F7<T> = Function Function([List<Function>])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function({List<T> x}) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(Function)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int, {int x}) Function<B extends core.int>();
+typedef F14<T> = List<T> Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F15<T> = Function(int y, [int x]) Function<B extends core.int>();
+typedef F16<T> = Function(int, [List<Function>]) Function<B extends core.int>();
+typedef F17<T> = Function(int, {List<T> x}) Function<B extends core.int>();
+typedef F18<T> = void Function(List<Function> x) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F20<T> = List<Function> Function<A>(int x)
+    Function<B extends core.int>();
+typedef F21<T> = Function<A>(Function x) Function<B extends core.int>();
+typedef F22<T> = void Function<A>(List<Function> x)
+    Function<B extends core.int>();
+
+Function f0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f1({List<Function> x = const []}) => throw 'uncalled';
+f2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+int f3<A>(A x) => throw 'uncalled';
+int Function({int x}) f4<B extends core.int>() => throw 'uncalled';
+int Function(core.List<core.int> x) f5<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [int x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function([List<Function>]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function({List<int> x}) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(Function) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int, {int x}) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function(int y, [int x]) f15<B extends core.int>() => throw 'uncalled';
+Function(int, [List<Function>]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, {List<int> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(List<Function> x) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, [List<int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function<A>(int x) f20<B extends core.int>() => throw 'uncalled';
+Function<A>(Function x) f21<B extends core.int>() => throw 'uncalled';
+void Function<A>(List<Function> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+
+class U98<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {core.List<core.int> x}) x0;
+  late core.List<core.int> Function({List<Function> x}) x1;
+  late Function(int x, [Function]) x2;
+  late int Function<A>(A x) x3;
+  late int Function({int x}) Function<B extends core.int>() x4;
+  late int Function(core.List<core.int> x) Function<B extends core.int>() x5;
+  late Function Function(int, [int x]) Function<B extends core.int>() x6;
+  late Function Function([List<Function>]) Function<B extends core.int>() x7;
+  late Function Function({List<T> x}) Function<B extends core.int>() x8;
+  late List<Function> Function(int y, {Function x})
+      Function<B extends core.int>() x9;
+  late List<Function> Function(int, [List<T> x]) Function<B extends core.int>()
+      x10;
+  late core.List<core.int> Function(Function) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int, {int x}) Function<B extends core.int>() x13;
+  late List<T> Function([core.List<core.int> x]) Function<B extends core.int>()
+      x14;
+  late Function(int y, [int x]) Function<B extends core.int>() x15;
+  late Function(int, [List<Function>]) Function<B extends core.int>() x16;
+  late Function(int, {List<T> x}) Function<B extends core.int>() x17;
+  late void Function(List<Function> x) Function<B extends core.int>() x18;
+  late void Function(int y, [List<T> x]) Function<B extends core.int>() x19;
+  late List<Function> Function<A>(int x) Function<B extends core.int>() x20;
+  late Function<A>(Function x) Function<B extends core.int>() x21;
+  late void Function<A>(List<Function> x) Function<B extends core.int>() x22;
+
+  U98({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1({List<Function> x = const []}) => throw 'uncalled';
+  m2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  int m3<A>(A x) => throw 'uncalled';
+  int Function({int x}) m4<B extends core.int>() => throw 'uncalled';
+  int Function(core.List<core.int> x) m5<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [int x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function([List<Function>]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function({List<T> x}) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, {int x}) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int y, [int x]) m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [List<Function>]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, {List<T> x}) m17<B extends core.int>() => throw 'uncalled';
+  void Function(List<Function> x) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [List<T> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function<A>(int x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(Function x) m21<B extends core.int>() => throw 'uncalled';
+  void Function<A>(List<Function> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function({List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function({List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int x, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int x, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(A x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(A x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function({int x}) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U98().runTests();
+  new U98<int>(tIsInt: true).runTests();
+  new U98<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type99_test.dart b/tests/language/function_type/function_type99_test.dart
new file mode 100644
index 0000000..59b8b8e
--- /dev/null
+++ b/tests/language/function_type/function_type99_test.dart
@@ -0,0 +1,943 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {core.List<core.int> x});
+typedef F1<T> = core.List<core.int> Function(int, {List<Function> x});
+typedef F2<T> = Function({Function x});
+typedef F3<T> = int Function<A>(List<A> x);
+typedef F4<T> = int Function({int x}) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F6<T> = Function Function(int, [int x]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function({List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(Function)
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int, {int x}) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function(int y, [int x]) Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int, {List<T> x}) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int y, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = List<Function> Function<A>(int x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = Function<A>(Function x) Function<B extends core.int>(int x);
+typedef F22<T> = void Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+
+Function f0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x0, {List<Function> x = const []}) =>
+    throw 'uncalled';
+f2({Function x = _voidFunction}) => throw 'uncalled';
+int f3<A>(List<A> x) => throw 'uncalled';
+int Function({int x}) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(core.List<core.int> x) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [int x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<Function>]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function({List<int> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(Function) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int, {int x}) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, [int x]) f15<B extends core.int>(int x) => throw 'uncalled';
+Function(int, [List<Function>]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, {List<int> x}) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(List<Function> x) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, [List<int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(int x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(Function x) f21<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U99<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {core.List<core.int> x}) x0;
+  late core.List<core.int> Function(int, {List<Function> x}) x1;
+  late Function({Function x}) x2;
+  late int Function<A>(List<A> x) x3;
+  late int Function({int x}) Function<B extends core.int>(int x) x4;
+  late int Function(core.List<core.int> x) Function<B extends core.int>(int x)
+      x5;
+  late Function Function(int, [int x]) Function<B extends core.int>(int x) x6;
+  late Function Function([List<Function>]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function({List<T> x}) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int y, {Function x})
+      Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int, [List<T> x]) Function<B extends core.int>(
+      int x) x10;
+  late core.List<core.int> Function(Function) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int, {int x}) Function<B extends core.int>(int x) x13;
+  late List<T> Function([core.List<core.int> x]) Function<B extends core.int>(
+      int x) x14;
+  late Function(int y, [int x]) Function<B extends core.int>(int x) x15;
+  late Function(int, [List<Function>]) Function<B extends core.int>(int x) x16;
+  late Function(int, {List<T> x}) Function<B extends core.int>(int x) x17;
+  late void Function(List<Function> x) Function<B extends core.int>(int x) x18;
+  late void Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+      x19;
+  late List<Function> Function<A>(int x) Function<B extends core.int>(int x)
+      x20;
+  late Function<A>(Function x) Function<B extends core.int>(int x) x21;
+  late void Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x22;
+
+  U99({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x0, {List<Function> x = const []}) =>
+      throw 'uncalled';
+  m2({Function x = _voidFunction}) => throw 'uncalled';
+  int m3<A>(List<A> x) => throw 'uncalled';
+  int Function({int x}) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(core.List<core.int> x) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [int x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<Function>]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({List<T> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int, {int x}) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, [int x]) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [List<Function>]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, {List<T> x}) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(List<Function> x) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, [List<T> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(int x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(Function x) m21<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function({Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function({Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(List<A> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(List<A> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function({int x}) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is Function(int y, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, {List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is Function<A>(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U99().runTests();
+  new U99<int>(tIsInt: true).runTests();
+  new U99<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type9_test.dart b/tests/language/function_type/function_type9_test.dart
new file mode 100644
index 0000000..f967587
--- /dev/null
+++ b/tests/language/function_type/function_type9_test.dart
@@ -0,0 +1,910 @@
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {int x});
+typedef F1<T> = Function Function(int, {List<T> x});
+typedef F2<T> = core.List<core.int> Function({core.List<core.int> x});
+typedef F3<T> = Function(int x, [List<Function>]);
+typedef F4<T> = List<Function> Function<A>(Function x);
+typedef F5<T> = int Function(Function x) Function(int x);
+typedef F6<T> = int Function(int y, [core.List<core.int> x]) Function(int x);
+typedef F7<T> = Function Function([int]) Function(int x);
+typedef F8<T> = Function Function({List<Function> x}) Function(int x);
+typedef F9<T> = Function Function() Function(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function> x]) Function(
+    int x);
+typedef F11<T> = List<Function> Function([List<T>]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [Function]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function(int x);
+typedef F14<T> = List<T> Function([Function x]) Function(int x);
+typedef F15<T> = List<T> Function(core.List<core.int>) Function(int x);
+typedef F16<T> = Function(int, [int]) Function(int x);
+typedef F17<T> = Function(int, {List<Function> x}) Function(int x);
+typedef F18<T> = void Function(int x) Function(int x);
+typedef F19<T> = void Function(int y, [List<Function> x]) Function(int x);
+typedef F20<T> = void Function(int, [List<T>]) Function(int x);
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x) Function(
+    int x);
+typedef F22<T> = Function<A>(List<T> x) Function(int x);
+typedef F23<T> = void Function<A>() Function(int x);
+
+int f0(int x0, {int x = -1}) => throw 'uncalled';
+Function f1(int x0, {List<int> x = const []}) => throw 'uncalled';
+core.List<core.int> f2({core.List<core.int> x = const []}) => throw 'uncalled';
+f3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+List<Function> f4<A>(Function x) => throw 'uncalled';
+int Function(Function x) f5(int x) => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6(int x) => throw 'uncalled';
+Function Function([int]) f7(int x) => throw 'uncalled';
+Function Function({List<Function> x}) f8(int x) => throw 'uncalled';
+Function Function() f9(int x) => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10(int x) => throw 'uncalled';
+List<Function> Function([List<int>]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function([Function x]) f14(int x) => throw 'uncalled';
+List<int> Function(core.List<core.int>) f15(int x) => throw 'uncalled';
+Function(int, [int]) f16(int x) => throw 'uncalled';
+Function(int, {List<Function> x}) f17(int x) => throw 'uncalled';
+void Function(int x) f18(int x) => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19(int x) => throw 'uncalled';
+void Function(int, [List<int>]) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21(int x) =>
+    throw 'uncalled';
+Function<A>(List<int> x) f22(int x) => throw 'uncalled';
+void Function<A>() f23(int x) => throw 'uncalled';
+
+class U9<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {int x}) x0;
+  late Function Function(int, {List<T> x}) x1;
+  late core.List<core.int> Function({core.List<core.int> x}) x2;
+  late Function(int x, [List<Function>]) x3;
+  late List<Function> Function<A>(Function x) x4;
+  late int Function(Function x) Function(int x) x5;
+  late int Function(int y, [core.List<core.int> x]) Function(int x) x6;
+  late Function Function([int]) Function(int x) x7;
+  late Function Function({List<Function> x}) Function(int x) x8;
+  late Function Function() Function(int x) x9;
+  late List<Function> Function(int, [List<Function> x]) Function(int x) x10;
+  late List<Function> Function([List<T>]) Function(int x) x11;
+  late core.List<core.int> Function(int x, [Function]) Function(int x) x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x}) Function(
+      int x) x13;
+  late List<T> Function([Function x]) Function(int x) x14;
+  late List<T> Function(core.List<core.int>) Function(int x) x15;
+  late Function(int, [int]) Function(int x) x16;
+  late Function(int, {List<Function> x}) Function(int x) x17;
+  late void Function(int x) Function(int x) x18;
+  late void Function(int y, [List<Function> x]) Function(int x) x19;
+  late void Function(int, [List<T>]) Function(int x) x20;
+  late List<Function> Function<A>(core.List<core.int> x) Function(int x) x21;
+  late Function<A>(List<T> x) Function(int x) x22;
+  late void Function<A>() Function(int x) x23;
+
+  U9({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {int x = -1}) => throw 'uncalled';
+  Function m1(int x0, {List<T> x = const []}) => throw 'uncalled';
+  core.List<core.int> m2({core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  m3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  List<Function> m4<A>(Function x) => throw 'uncalled';
+  int Function(Function x) m5(int x) => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6(int x) => throw 'uncalled';
+  Function Function([int]) m7(int x) => throw 'uncalled';
+  Function Function({List<Function> x}) m8(int x) => throw 'uncalled';
+  Function Function() m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<T>]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function([Function x]) m14(int x) => throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15(int x) => throw 'uncalled';
+  Function(int, [int]) m16(int x) => throw 'uncalled';
+  Function(int, {List<Function> x}) m17(int x) => throw 'uncalled';
+  void Function(int x) m18(int x) => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19(int x) => throw 'uncalled';
+  void Function(int, [List<T>]) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21(int x) =>
+      throw 'uncalled';
+  Function<A>(List<T> x) m22(int x) => throw 'uncalled';
+  void Function<A>() m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int x, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([int]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function() Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x}) Function(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(core.List<core.int> x)
+        Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>() Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U9().runTests();
+  new U9<int>(tIsInt: true).runTests();
+  new U9<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/test_generator.dart b/tests/language/function_type/test_generator.dart
new file mode 100644
index 0000000..f02d099
--- /dev/null
+++ b/tests/language/function_type/test_generator.dart
@@ -0,0 +1,831 @@
+// 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:io';
+
+// By convention:
+//
+//   T: generic type of typedef.
+//   A: generic type of returned function.
+//   B: generic type of function.
+//
+// Example:
+//    typedef F<T>: Function<A> Function<B>();
+//
+// We only use: Function, List, int (and function types).
+// We import 'dart:core' directly and with prefix 'core'.
+
+abstract class Printable {
+  /// Builds a descriptive string that can be used as an identifier.
+  ///
+  /// The string is mainly used for disambiguation, and not for its readability.
+  void writeIdentifier(StringBuffer buffer);
+}
+
+abstract class TypeLike implements Printable {
+  /// Prints `this` as valid Dart code for a Type.
+  void writeType(StringBuffer buffer);
+
+  /// Whether this type uses T in some way.
+  bool get usesT;
+
+  /// Whether this type uses T in a return (covariant) position.
+  ///
+  /// For example: `T`, `List<T>`, `T Function()`, or `Function(Function(T))`.
+  bool get returnsT;
+
+  /// Whether this type uses T in a parameter (contravariant) position.
+  ///
+  /// For example, `Function(T)`, `Function(List<T>)`, or
+  /// `Function(T Function())`.
+  bool get takesT;
+}
+
+/// Provides a unique integer for every parameter in a function.
+int parameterNameCounter = 0;
+
+/// Whether `T` should be replaced with `int`.
+bool shouldReplaceTWithInt = false;
+
+class Parameter implements TypeLike {
+  final TypeLike type;
+  final String name;
+
+  Parameter(this.type, this.name);
+
+  // Type or name can be null.
+  @override
+  writeIdentifier(buffer) {
+    if (type == null) {
+      buffer.write("null");
+    } else {
+      type.writeIdentifier(buffer);
+    }
+    buffer.write("_");
+    buffer.write(name);
+  }
+
+  void writeType(StringBuffer buffer) {
+    assert(type != null || name != null);
+    if (name == null) {
+      type.writeType(buffer);
+    } else if (type == null) {
+      buffer.write(name);
+    } else {
+      type.writeType(buffer);
+      buffer.write(" ");
+      buffer.write(name);
+    }
+  }
+
+  void writeInFunction(StringBuffer buffer, {bool optional}) {
+    assert(type != null || name != null);
+    if (name == null) {
+      type.writeType(buffer);
+      buffer.write(" x");
+      buffer.write(parameterNameCounter++);
+    } else if (type == null) {
+      buffer.write(name);
+    } else {
+      type.writeType(buffer);
+      buffer.write(" ");
+      buffer.write(name);
+    }
+
+    // Write a default value for optional parameters to avoid nullability
+    // errors.
+    if (optional) {
+      buffer.write(" = ");
+
+      var nominalType = type as NominalType;
+      const baseTypes = {
+        "int": "-1",
+        "Function": "_voidFunction",
+        "List": "const []",
+      };
+
+      if (baseTypes.containsKey(nominalType.name)) {
+        buffer.write(baseTypes[nominalType.name]);
+      } else if (shouldReplaceTWithInt && nominalType.name == "T") {
+        buffer.write("-1");
+      } else {
+        throw UnsupportedError("No default value for $type");
+      }
+    }
+  }
+
+  bool operator ==(other) {
+    return other is Parameter && name == other.name && type == other.type;
+  }
+
+  int get hashCode {
+    return ((name.hashCode * 37) ^ type.hashCode) & 0xFFFFFFFF;
+  }
+
+  bool get usesT => type?.usesT ?? false;
+  bool get takesT => type?.takesT ?? false;
+  bool get returnsT => type?.returnsT ?? false;
+}
+
+class GenericParameter implements TypeLike {
+  final String name;
+  final TypeLike bound;
+
+  GenericParameter(this.name, [this.bound]);
+
+  // Bound may be null.
+  @override
+  writeIdentifier(buffer) {
+    buffer.write(name);
+    buffer.write("_");
+    if (bound == null) {
+      buffer.write("null");
+    } else {
+      bound.writeIdentifier(buffer);
+    }
+  }
+
+  @override
+  writeType(buffer) {
+    buffer.write(name);
+    if (bound != null) {
+      buffer.write(" extends ");
+      bound.writeType(buffer);
+    }
+  }
+
+  bool operator ==(other) {
+    return other is GenericParameter &&
+        name == other.name &&
+        bound == other.bound;
+  }
+
+  int get hashCode {
+    return ((name.hashCode * 23) ^ bound.hashCode) & 0xFFFFFFFF;
+  }
+
+  bool get usesT => bound?.usesT ?? false;
+  bool get takesT => bound?.takesT ?? false;
+  bool get returnsT => bound?.returnsT ?? false;
+}
+
+void _describeList(StringBuffer buffer, List<Printable> list) {
+  if (list == null) {
+    buffer.write("0");
+    return;
+  }
+  buffer.write(list.length.toString());
+  buffer.write("_");
+  for (int i = 0; i < list.length; i++) {
+    if (i != 0) buffer.write("_");
+    list[i].writeIdentifier(buffer);
+  }
+}
+
+void _writeTypes(StringBuffer buffer, List<TypeLike> list,
+    [String prefix = "", String postfix = ""]) {
+  if (list == null || list.isEmpty) return;
+  buffer.write(prefix);
+  for (int i = 0; i < list.length; i++) {
+    if (i != 0) buffer.write(", ");
+    list[i].writeType(buffer);
+  }
+  buffer.write(postfix);
+}
+
+/// Write the parameters in [list] to [buffer]. If [inFunction] is true then
+/// the output are the formal parameters of a function signature (where
+/// optionals will have default values), and if [inFunction] is false then the
+/// output are formal parameter types of a function type (where default values
+/// and names of positional parameters are omitted).
+void _writeParameters(
+    StringBuffer buffer, List<Parameter> list, bool inFunction,
+    [String prefix = "", String postfix = ""]) {
+  if (list == null || list.isEmpty) return;
+  buffer.write(prefix);
+  for (int i = 0; i < list.length; i++) {
+    if (i != 0) buffer.write(", ");
+    if (inFunction) {
+      list[i].writeInFunction(buffer, optional: prefix != "");
+    } else {
+      list[i].writeType(buffer);
+    }
+  }
+  buffer.write(postfix);
+}
+
+bool _listUsesT(List elements) {
+  if (elements == null) return false;
+  return elements.any((p) => p.usesT);
+}
+
+bool _listEquals(List list1, List list2) {
+  if (list1 == list2) return true; // Also covers both being null.
+  if (list1 == null || list2 == null) return false;
+  for (int i = 0; i < list1.length; i++) {
+    if (list1[i] != list2[i]) return false;
+  }
+  return true;
+}
+
+int _listHash(List list) {
+  if (list == null) return null.hashCode;
+  int result = 71;
+  for (int i = 0; i < list.length; i++) {
+    result = ((result * 11) ^ list[i].hashCode) & 0xFFFFFFFF;
+  }
+  return result;
+}
+
+class FunctionType implements TypeLike {
+  final TypeLike returnType;
+  final List<GenericParameter> generic;
+  final List<Parameter> required;
+  final List<Parameter> optional;
+  final List<Parameter> named;
+
+  FunctionType(this.returnType, this.generic, this.required,
+      [this.optional, this.named]);
+
+  @override
+  writeIdentifier(buffer) {
+    buffer.write("Fun_");
+    if (returnType == null) {
+      buffer.write("null");
+    } else {
+      returnType.writeIdentifier(buffer);
+    }
+    buffer.write("_");
+    _describeList(buffer, generic);
+    buffer.write("_");
+    _describeList(buffer, required);
+    buffer.write("_");
+    _describeList(buffer, optional);
+    buffer.write("_");
+    _describeList(buffer, named);
+  }
+
+  @override
+  writeType(buffer) {
+    if (returnType != null) {
+      returnType.writeType(buffer);
+      buffer.write(" ");
+    }
+    buffer.write("Function");
+    if (generic != null) _writeTypes(buffer, generic, "<", ">");
+    buffer.write("(");
+    bool inFunction = false;
+    _writeParameters(buffer, required, inFunction);
+    if ((optional != null || named != null) &&
+        required != null &&
+        required.isNotEmpty) {
+      buffer.write(", ");
+    }
+    _writeParameters(buffer, optional, inFunction, "[", "]");
+    _writeParameters(buffer, named, inFunction, "{", "}");
+    buffer.write(")");
+  }
+
+  /// Writes this type as if it was a function.
+  void writeFunction(StringBuffer buffer, String name, {bool replaceT: true}) {
+    shouldReplaceTWithInt = replaceT;
+    parameterNameCounter = 0;
+
+    if (returnType != null) {
+      returnType.writeType(buffer);
+      buffer.write(" ");
+    }
+
+    buffer.write(name);
+    if (generic != null) _writeTypes(buffer, generic, "<", ">");
+    buffer.write("(");
+    bool inFunction = true;
+    _writeParameters(buffer, required, inFunction);
+    if ((optional != null || named != null) &&
+        required != null &&
+        required.isNotEmpty) {
+      buffer.write(", ");
+    }
+    _writeParameters(buffer, optional, inFunction, "[", "]");
+    _writeParameters(buffer, named, inFunction, "{", "}");
+    buffer.write(") => throw 'uncalled';");
+
+    shouldReplaceTWithInt = false;
+  }
+
+  bool operator ==(other) {
+    return returnType == other.returnType &&
+        _listEquals(generic, other.generic) &&
+        _listEquals(required, other.required) &&
+        _listEquals(optional, other.optional) &&
+        _listEquals(named, other.named);
+  }
+
+  int get hashCode {
+    return ((returnType.hashCode * 13) ^
+            (_listHash(generic) * 17) ^
+            (_listHash(required) * 53) ^
+            (_listHash(optional) ^ 31) ^
+            (_listHash(named) * 87)) &
+        0xFFFFFFFF;
+  }
+
+  bool get usesT {
+    return (returnType?.usesT ?? false) ||
+        [generic, required, optional, named].any(_listUsesT);
+  }
+
+  bool get returnsT {
+    return (returnType?.returnsT ?? false) ||
+        [generic, required, optional, named]
+            .any((l) => l?.any((p) => p.takesT) ?? false);
+  }
+
+  bool get takesT {
+    return (returnType?.takesT ?? false) ||
+        [generic, required, optional, named]
+            .any((l) => l?.any((p) => p.returnsT) ?? false);
+  }
+
+  bool get reifiedTypeUsesT {
+    return returnType?.usesT ?? returnsT;
+  }
+}
+
+class NominalType implements TypeLike {
+  final String prefix;
+  final String name;
+  final List<TypeLike> generic;
+
+  NominalType(this.name, [this.prefix, this.generic]);
+
+  @override
+  writeIdentifier(buffer) {
+    buffer.write(prefix);
+    buffer.write("_");
+    buffer.write(name);
+    _describeList(buffer, generic);
+  }
+
+  @override
+  writeType(buffer) {
+    if (prefix != null && prefix != "") {
+      buffer.write(prefix);
+      buffer.write(".");
+    }
+    if (shouldReplaceTWithInt && name == "T") {
+      buffer.write("int");
+    } else {
+      buffer.write(name);
+    }
+    _writeTypes(buffer, generic, "<", ">");
+  }
+
+  bool operator ==(other) {
+    return other is NominalType && prefix == other.prefix && name == other.name;
+  }
+
+  int get hashCode {
+    return ((prefix.hashCode * 37) ^ name.hashCode) & 0xFFFFFFFF;
+  }
+
+  bool get usesT => name == "T" || _listUsesT(generic);
+
+  bool get returnsT => name == "T" || generic?.any((t) => t.returnsT) ?? false;
+
+  bool get takesT => generic?.any((t) => t.takesT) ?? false;
+}
+
+List<TypeLike> buildFunctionTypes() {
+  List<GenericParameter> as = [
+    new GenericParameter("A"),
+    // new GenericParameter("A", new NominalType("int")),
+    // new GenericParameter("A", new NominalType("int", "core")),
+  ];
+  List<GenericParameter> bs = [
+    // new GenericParameter("B"),
+    // new GenericParameter("B", new NominalType("int")),
+    new GenericParameter("B", new NominalType("int", "core")),
+  ];
+  List<TypeLike> basicTypes = [
+    new NominalType("int"),
+    // new NominalType("int", "core"),
+    // new NominalType("List"),
+    // new NominalType("List", "core"),
+    new NominalType("Function"),
+    new NominalType("List", "", [new NominalType("Function")]),
+    new NominalType("List", "core", [new NominalType("int", "core")]),
+    new NominalType("List", "", [new NominalType("T")]),
+    // new NominalType("List", "", [new NominalType("Function")]),
+  ];
+
+  List<TypeLike> basicsPlusNull = [
+    basicTypes,
+    <TypeLike>[null]
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusVoid = [
+    basicsPlusNull,
+    [new NominalType("void")],
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusB = [
+    basicsPlusNull,
+    [
+      new NominalType("B"),
+      new NominalType("List", "", [new NominalType("B")])
+    ]
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusBPlusVoid = [
+    basicsPlusNullPlusB,
+    [new NominalType("void")],
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusA = [
+    basicsPlusNull,
+    [
+      new NominalType("A"),
+      new NominalType("List", "", [new NominalType("A")])
+    ]
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusAPlusVoid = [
+    basicsPlusNullPlusA,
+    [new NominalType("void")],
+  ].expand((x) => x).toList();
+
+  List<TypeLike> buildFunctionTypes(TypeLike returnType, TypeLike parameterType,
+      [List<GenericParameter> generics,
+      bool generateMoreCombinations = false]) {
+    List<TypeLike> result = [];
+
+    if (parameterType == null) {
+      // int Function().
+      result.add(new FunctionType(returnType, generics, null));
+      return result;
+    }
+
+    // int Function(int x).
+    result.add(new FunctionType(
+        returnType, generics, [new Parameter(parameterType, "x")]));
+
+    if (!generateMoreCombinations) return result;
+
+    // int Function([int x]).
+    result.add(new FunctionType(
+        returnType, generics, null, [new Parameter(parameterType, "x")]));
+    // int Function(int, [int x])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), null)],
+        [new Parameter(parameterType, "x")]));
+    // int Function(int x, [int x])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), "y")],
+        [new Parameter(parameterType, "x")]));
+    // int Function(int);
+    result.add(new FunctionType(
+        returnType, generics, [new Parameter(parameterType, null)]));
+    // int Function([int]);
+    result.add(new FunctionType(
+        returnType, generics, null, [new Parameter(parameterType, null)]));
+    // int Function(int, [int])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), null)],
+        [new Parameter(parameterType, null)]));
+    // int Function(int x, [int])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), "x")],
+        [new Parameter(parameterType, null)]));
+    // int Function({int x}).
+    result.add(new FunctionType(
+        returnType, generics, null, null, [new Parameter(parameterType, "x")]));
+    // int Function(int, {int x})
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), null)],
+        null,
+        [new Parameter(parameterType, "x")]));
+    // int Function(int x, {int x})
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), "y")],
+        null,
+        [new Parameter(parameterType, "x")]));
+    return result;
+  }
+
+  // The "smaller" function types. May also be used non-nested.
+  List<TypeLike> functionTypes = [];
+
+  for (TypeLike returnType in basicsPlusNullPlusVoid) {
+    for (TypeLike parameterType in basicsPlusNull) {
+      bool generateMoreCombinations = true;
+      functionTypes.addAll(buildFunctionTypes(
+          returnType, parameterType, null, generateMoreCombinations));
+    }
+  }
+
+  // These use `B` from the generic type of the enclosing function.
+  List<TypeLike> returnFunctionTypesB = [];
+  for (TypeLike returnType in basicsPlusNullPlusBPlusVoid) {
+    TypeLike parameterType = new NominalType("B");
+    returnFunctionTypesB.addAll(buildFunctionTypes(returnType, parameterType));
+  }
+  for (TypeLike parameterType in basicsPlusNull) {
+    TypeLike returnType = new NominalType("B");
+    returnFunctionTypesB.addAll(buildFunctionTypes(returnType, parameterType));
+  }
+
+  for (TypeLike returnType in basicsPlusNullPlusAPlusVoid) {
+    for (TypeLike parameterType in basicsPlusNullPlusA) {
+      for (GenericParameter a in as) {
+        functionTypes
+            .addAll(buildFunctionTypes(returnType, parameterType, [a]));
+      }
+    }
+  }
+
+  List<TypeLike> types = [];
+  types.addAll(functionTypes);
+
+  // Now add some higher-order function types.
+  for (TypeLike returnType in functionTypes) {
+    types.addAll(buildFunctionTypes(returnType, null));
+    types.addAll(buildFunctionTypes(returnType, new NominalType("int")));
+    for (var b in bs) {
+      types.addAll(buildFunctionTypes(returnType, null, [b]));
+      types.addAll(buildFunctionTypes(returnType, new NominalType("int"), [b]));
+    }
+  }
+  for (TypeLike returnType in returnFunctionTypesB) {
+    for (var b in bs) {
+      types.addAll(buildFunctionTypes(returnType, null, [b]));
+      types.addAll(buildFunctionTypes(returnType, new NominalType("int"), [b]));
+    }
+  }
+
+  return types;
+}
+
+final String HEADER = """
+// 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.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+""";
+
+class Unit {
+  int typeCounter = 0;
+  final String name;
+  final StringBuffer typedefs = new StringBuffer();
+  final StringBuffer globals = new StringBuffer();
+  final StringBuffer tests = new StringBuffer();
+  final StringBuffer fields = new StringBuffer();
+  final StringBuffer statics = new StringBuffer();
+  final StringBuffer testMethods = new StringBuffer();
+  final StringBuffer methods = new StringBuffer();
+
+  Unit(this.name);
+
+  void write(StringBuffer buffer) {
+    buffer.write("""
+$HEADER
+
+$typedefs
+
+$globals
+
+class $name<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+$fields
+
+  $name({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+$methods
+
+  runTests() {\n$tests  }
+
+$testMethods
+}
+
+void main() {
+  new $name().runTests();
+  new $name<int>(tIsInt: true).runTests();
+  new $name<bool>(tIsBool: true).runTests();
+}
+    """);
+  }
+}
+
+final TEST_METHOD_HEADER = """
+  /// #typeCode
+  void #testName() {""";
+
+// Tests that apply for every type.
+final COMMON_TESTS_TEMPLATE = """
+    Expect.isTrue(#staticFunName is #typeName<int>);
+    Expect.isTrue(confuse(#staticFunName) is #typeName<int>);
+    // In checked mode, verifies the type.
+    #typeCode #localName;
+    // The static function #staticFunName sets `T` to `int`.
+    if (tIsInt) {
+      #fieldName = #staticFunName as dynamic;
+      #localName = #staticFunName as dynamic;
+      #fieldName = confuse(#staticFunName);
+      #localName = confuse(#staticFunName);
+    }
+
+    Expect.isTrue(#methodFunName is #typeName<T>);
+    Expect.isTrue(#methodFunName is #typeCode);
+    Expect.isTrue(confuse(#methodFunName) is #typeName<T>);
+    // In checked mode, verifies the type.
+    #fieldName = #methodFunName;
+    #localName = #methodFunName;
+    #fieldName = confuse(#methodFunName);
+    #localName = confuse(#methodFunName);""";
+
+// Tests that depend on the typedef "T" argument.
+//
+// These tests are executed when the surrounding class is instantiated with
+// its generic type set to `int`, `dynamic` or `bool`. In the latter case, the
+// class field `tIsBool` is set to true.
+
+// While the types themselves are not affected by the class` `T`, the methods
+// of the class may use `T`:
+//
+// For example:
+//   class A<T> {
+//      f(List<T> x) {}
+//   }
+final TYPEDEF_T_TESTS_TEMPLATE = """
+    // The static function has its T always set to int.
+    Expect.isTrue(#staticFunName is #typeName<int>);
+    Expect.isFalse(#staticFunName is #typeName<bool>);
+    Expect.isTrue(confuse(#staticFunName) is #typeName<int>);
+    Expect.isFalse(confuse(#staticFunName) is #typeName<bool>);
+    if (tIsBool) {
+      Expect.throws(() { #fieldName = (#staticFunName as dynamic); });
+      Expect.throws(() { #fieldName = confuse(#staticFunName); });
+      Expect.throws(() { #localName = (#staticFunName as dynamic); });
+      Expect.throws(() { #localName = confuse(#staticFunName); });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(#isIntValue, #methodFunName is #typeName<int>);
+      Expect.equals(#isBoolValue, #methodFunName is #typeName<bool>);
+      Expect.equals(#isIntValue, confuse(#methodFunName) is #typeName<int>);
+      Expect.equals(#isBoolValue, confuse(#methodFunName) is #typeName<bool>);
+    }
+""";
+
+final TEST_METHOD_FOOTER = "  }";
+
+String createTypeName(int id) => "F$id";
+String createStaticFunName(int id) => "f$id";
+String createMethodFunName(int id) => "m$id";
+String createFieldName(int id) => "x$id";
+String createLocalName(int id) => "l$id";
+String createTestName(int id) => "test${createTypeName(id)}";
+
+String createTypeCode(FunctionType type) {
+  StringBuffer typeBuffer = new StringBuffer();
+  type.writeType(typeBuffer);
+  return typeBuffer.toString();
+}
+
+String createStaticFunCode(FunctionType type, int id) {
+  StringBuffer staticFunBuffer = new StringBuffer();
+  type.writeFunction(staticFunBuffer, createStaticFunName(id));
+  return staticFunBuffer.toString();
+}
+
+String createMethodFunCode(FunctionType type, int id) {
+  StringBuffer methodFunBuffer = new StringBuffer();
+  type.writeFunction(methodFunBuffer, createMethodFunName(id), replaceT: false);
+  return methodFunBuffer.toString();
+}
+
+String createTestMethodFunCode(FunctionType type, String typeCode, int id) {
+  var tIsInt = type.reifiedTypeUsesT ? 'tIsInt' : 'true';
+  var tIsBool = type.reifiedTypeUsesT ? 'tIsBool' : 'true';
+
+  String fillTemplate(String template, int id) {
+    var result = template
+        .replaceAll("#typeName", createTypeName(id))
+        .replaceAll("#staticFunName", createStaticFunName(id))
+        .replaceAll("#methodFunName", createMethodFunName(id))
+        .replaceAll("#fieldName", createFieldName(id))
+        .replaceAll("#localName", createLocalName(id))
+        .replaceAll("#testName", createTestName(id))
+        .replaceAll("#typeCode", typeCode)
+        .replaceAll("#isIntValue", tIsInt)
+        .replaceAll("#isBoolValue", tIsBool);
+    assert(!result.contains("#"));
+    return result;
+  }
+
+  String commonTests = fillTemplate(COMMON_TESTS_TEMPLATE, id);
+  String genericTTests = "";
+  if (type.usesT) {
+    genericTTests = fillTemplate(TYPEDEF_T_TESTS_TEMPLATE, id);
+  }
+  return """
+${fillTemplate(TEST_METHOD_HEADER, id)}
+$commonTests
+$genericTTests
+$TEST_METHOD_FOOTER
+""";
+}
+
+void generateTests() {
+  // Keep methods and classes smaller by distributing over several different
+  // classes.
+  List<Unit> units = [];
+  for (int i = 0; i < 100; i++) {
+    units.add(new Unit("U$i"));
+  }
+
+  var types = buildFunctionTypes();
+
+  int unitCounter = 0;
+  for (var type in types) {
+    Unit unit = units[unitCounter % units.length];
+    unitCounter++;
+    int typeCounter = unit.typeCounter++;
+
+    String typeName = createTypeName(typeCounter);
+    String fieldName = createFieldName(typeCounter);
+    String testName = createTestName(typeCounter);
+
+    String typeCode = createTypeCode(type);
+    String staticFunCode = createStaticFunCode(type, typeCounter);
+    String methodFunCode = createMethodFunCode(type, typeCounter);
+    String testMethodCode =
+        createTestMethodFunCode(type, typeCode, typeCounter);
+
+    unit.typedefs.writeln("typedef $typeName<T> = $typeCode;");
+    unit.globals.writeln(staticFunCode);
+    // Mark all fields 'late' to avoid uninitialized field errors.
+    unit.fields.writeln("  late $typeCode $fieldName;");
+    unit.methods.writeln("  $methodFunCode");
+    unit.testMethods.writeln("$testMethodCode");
+    unit.tests.writeln("    $testName();");
+  }
+
+  for (int i = 0; i < units.length; i++) {
+    var unit = units[i];
+    var buffer = new StringBuffer();
+    unit.write(buffer);
+    var path = Platform.script.resolve("function_type${i}_test.dart").path;
+    new File(path).writeAsStringSync(buffer.toString());
+  }
+}
+
+void printUsage() {
+  print("""
+Generates function type tests.
+
+All tests are generated in the same directory as this script.
+""");
+}
+
+void main(List<String> arguments) {
+  if (arguments.length != 0) {
+    printUsage();
+    return;
+  }
+  generateTests();
+}
diff --git a/tests/language/library1.dart b/tests/language/library1.dart
new file mode 100644
index 0000000..96cdd1b
--- /dev/null
+++ b/tests/language/library1.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+library library1.dart;
+
+var foo;
+
+bar() => "library1.dart bar()";
+
+baz() => "library1.dart baz()";
+
+var bay;
+
+typedef int bax(int a, int b);
+
+class baw {}
diff --git a/tests/language/library10.dart b/tests/language/library10.dart
new file mode 100644
index 0000000..afa22f6
--- /dev/null
+++ b/tests/language/library10.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+library library10.dart;
+
+import "library11.dart" as lib11;
+import "package:expect/expect.dart";
+
+class Library10 {
+  Library10(this.fld);
+  int func() {
+    return 2;
+  }
+
+  var fld;
+  static int static_func() {
+    var result = 0;
+    var obj = new lib11.Library11(4);
+    result = obj.fld;
+    Expect.equals(4, result);
+    result += obj.func();
+    Expect.equals(7, result);
+    result += lib11.Library11.static_func();
+    Expect.equals(9, result);
+    result += lib11.Library11.static_fld;
+    Expect.equals(10, result);
+    Expect.equals(100, lib11.top_level11);
+    Expect.equals(200, lib11.top_level_func11());
+    return 3;
+  }
+
+  static var static_fld = 4;
+}
+
+const int top_level10 = 10;
+int top_level_func10() {
+  return 20;
+}
diff --git a/tests/language/library11.dart b/tests/language/library11.dart
new file mode 100644
index 0000000..f8a4395
--- /dev/null
+++ b/tests/language/library11.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+library library11.dart;
+
+class Library11 {
+  Library11(this.fld);
+  Library11.namedConstructor(this.fld);
+  int func() {
+    return 3;
+  }
+
+  var fld;
+  static int static_func() {
+    return 2;
+  }
+
+  static var static_fld = 1;
+}
+
+class Library111<T> {
+  Library111.namedConstructor(T this.fld);
+  T fld;
+}
+
+const int top_level11 = 100;
+int top_level_func11() {
+  return 200;
+}
diff --git a/tests/language/library12.dart b/tests/language/library12.dart
new file mode 100644
index 0000000..1eeaa0e
--- /dev/null
+++ b/tests/language/library12.dart
@@ -0,0 +1,48 @@
+// 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.
+//
+
+library library12.dart;
+
+import 'package:expect/expect.dart';
+
+import "library11.dart";
+
+class Library12 {
+  Library12(this.fld);
+  Library12.other(fld, multiplier) {
+    this.fld = fld * multiplier;
+  }
+  func() {
+    return 2;
+  }
+
+  var fld;
+  static static_func() {
+    var result = 0;
+    var obj = new Library11(4);
+    result = obj.fld;
+    Expect.equals(4, result);
+    result += obj.func();
+    Expect.equals(7, result);
+    result += Library11.static_func();
+    Expect.equals(9, result);
+    result += Library11.static_fld;
+    Expect.equals(10, result);
+    Expect.equals(100, top_level11);
+    Expect.equals(200, top_level_func11());
+    return 3;
+  }
+
+  static var static_fld = 4;
+}
+
+abstract class Library12Interface {
+  Library12 addObjects(Library12 value1, Library12 value2);
+}
+
+const int top_level12 = 10;
+top_level_func12() {
+  return 20;
+}
diff --git a/tests/language/library2.dart b/tests/language/library2.dart
new file mode 100644
index 0000000..219303f
--- /dev/null
+++ b/tests/language/library2.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var foo;
+var foo1 = 0;
+
+bar() => "library2.dart bar()";
+
+var baz;
+
+bay() => "library2.dart bay()";
+
+typedef double bax(int a, int b);
+
+var baw;
diff --git a/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart b/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart
new file mode 100644
index 0000000..695dfa3
--- /dev/null
+++ b/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  Never never = throw "Unreachable";
+  bool boolean = true;
+  dynamic any = 3;
+  Null nil = null;
+  Object object = Object();
+  Object? objectOrNull = null;
+
+  {
+    // Check that values of type `Never` are usable as booleans.
+    if (never) {}
+    [if (never) 3];
+    never ? 3 : 4;
+    while (never) {}
+    do {} while (never);
+    never || true;
+    never && true;
+    true || never;
+    true && never;
+    for (int i = 0; never; i++) {}
+    [for (int i = 0; never; i++) 3];
+  }
+  {
+    // Check that values of type `boolean` are usable as booleans.
+    if (boolean) {}
+    [if (boolean) 3];
+    boolean ? 3 : 4;
+    while (boolean) {}
+    do {} while (boolean);
+    boolean || true;
+    boolean && true;
+    true || boolean;
+    true && boolean;
+    for (int i = 0; boolean; i++) {}
+    [for (int i = 0; boolean; i++) 3];
+  }
+  {
+    // Check that values of type `dynamic` are usable as booleans.
+    if (any) {}
+    [if (any) 3];
+    any ? 3 : 4;
+    while (any) {}
+    do {} while (any);
+    any || true;
+    any && true;
+    true || any;
+    true && any;
+    for (int i = 0; any; i++) {}
+    [for (int i = 0; any; i++) 3];
+  }
+  {
+    // Check that values of type `Null` are not usable as booleans.
+    if (nil) {}
+    //  ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    [if (nil) 3];
+    //   ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    nil ? 3 : 4;
+//  ^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+// [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    while (nil) {}
+    //     ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    do {} while (nil);
+    //           ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    nil || true;
+//  ^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+// [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    nil && true;
+//  ^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+// [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    true || nil;
+    //      ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    true && nil;
+    //      ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    for (int i = 0; nil; i++) {}
+    //              ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+    [for (int i = 0; nil; i++) 3];
+    //               ^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
+  }
+  {
+    // Check that values of type `Object` are not usable as booleans.
+    if (object) {}
+    //  ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    [if (object) 3];
+    //   ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    object ? 3 : 4;
+//  ^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    while (object) {}
+    //     ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    do {} while (object);
+    //           ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    object || true;
+//  ^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    object && true;
+//  ^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    true || object;
+    //      ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    true && object;
+    //      ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    for (int i = 0; object; i++) {}
+    //              ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+    [for (int i = 0; object; i++) 3];
+    //               ^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
+  }
+  {
+    // Check that values of type `Object?` are not usable as booleans.
+    if (objectOrNull) {}
+    //  ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    [if (objectOrNull) 3];
+    //   ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    objectOrNull ? 3 : 4;
+//  ^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    while (objectOrNull) {}
+    //     ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    do {} while (objectOrNull);
+    //           ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    objectOrNull || true;
+//  ^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    objectOrNull && true;
+//  ^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    true || objectOrNull;
+    //      ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    true && objectOrNull;
+    //      ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    for (int i = 0; objectOrNull; i++) {}
+    //              ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+    [for (int i = 0; objectOrNull; i++) 3];
+    //               ^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
+    // [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
+  }
+}
diff --git a/tests/language/nnbd/boolean_conversion/boolean_conversion_lib1.dart b/tests/language/nnbd/boolean_conversion/boolean_conversion_lib1.dart
new file mode 100644
index 0000000..4811a87
--- /dev/null
+++ b/tests/language/nnbd/boolean_conversion/boolean_conversion_lib1.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This library defines a set of test functions 'xxxAsBoolean" and a check
+// combinator called `check` which test the runtime behavior of conversions
+// of values in boolean condional positions (e.g. the condition of a conditional
+// statement).
+//
+// For example: calling `check(dynamicAsBoolean, value, expectation)` tests that
+// using `value` as the condition in a number of different syntactic constructs
+// with static type `dynamic` behaves as expected by `expectation`, where
+// `expectation` should be one of:
+// Expect.throwsAssertionError if a null conversion error is expected
+// Expect.throwsTypeError if an implicit cast error is expected
+// expectOk if no runtime error is expected.
+
+void expectOk(void Function() f) {
+  f();
+}
+
+final int constructsTested = 11;
+
+void check<T>(void Function(T, int) test, T value,
+    void Function(void Function()) expectation) {
+  for (int i = 0; i < constructsTested; i++) {
+    expectation(() => test(value, i));
+  }
+}
+
+void neverAsBoolean(Never value, int index) {
+  // Check that values of type `Never` are boolean converted appropriately
+  // In strong checking mode, this code is unreachable.  In weak checking mode,
+  // we may get passed `null` for `value`, and so we check that the `null` value
+  // causes an assertion error to be thrown appropriately.
+  switch (index) {
+    case 0:
+      if (value) {}
+      break;
+    case 1:
+      [if (value) 3];
+      break;
+    case 2:
+      value ? 3 : 4;
+      break;
+    case 3:
+      while (value) {
+        break;
+      }
+      break;
+    case 4:
+      var done = false;
+      do {
+        if (done) break;
+        done = true;
+      } while (value);
+      break;
+    case 5:
+      value || true;
+      break;
+    case 6:
+      value && true;
+      break;
+    case 7:
+      false || value;
+      break;
+    case 8:
+      true && value;
+      break;
+    case 9:
+      for (int i = 0; value; i++) {
+        break;
+      }
+      break;
+    case 10:
+      [for (int i = 0; value; i++) 3];
+      break;
+    default:
+      throw "Invalid index";
+  }
+}
+
+void booleanAsBoolean(bool value, int index) {
+  // Check that values of type `boolean` are boolean converted appropriately
+  switch (index) {
+    case 0:
+      if (value) {}
+      break;
+    case 1:
+      [if (value) 3];
+      break;
+    case 2:
+      value ? 3 : 4;
+      break;
+    case 3:
+      while (value) {
+        break;
+      }
+      break;
+    case 4:
+      var done = false;
+      do {
+        if (done) break;
+        done = true;
+      } while (value);
+      break;
+    case 5:
+      value || true;
+      break;
+    case 6:
+      value && true;
+      break;
+    case 7:
+      false || value;
+      break;
+    case 8:
+      true && value;
+      break;
+    case 9:
+      for (int i = 0; value; i++) {
+        break;
+      }
+      break;
+    case 10:
+      [for (int i = 0; value; value = false) 3];
+      break;
+    default:
+      throw "Invalid index";
+  }
+}
+
+void dynamicAsBoolean(dynamic value, int index) {
+  // Check that values of type `dynamic` are boolean converted appropriately
+  switch (index) {
+    case 0:
+      if (value) {}
+      break;
+    case 1:
+      [if (value) 3];
+      break;
+    case 2:
+      value ? 3 : 4;
+      break;
+    case 3:
+      while (value) {
+        break;
+      }
+      break;
+    case 4:
+      var done = false;
+      do {
+        if (done) break;
+        done = true;
+      } while (value);
+      break;
+    case 5:
+      value || true;
+      break;
+    case 6:
+      value && true;
+      break;
+    case 7:
+      false || value;
+      break;
+    case 8:
+      true && value;
+      break;
+    case 9:
+      for (int i = 0; value; i++) {
+        break;
+      }
+      break;
+    case 10:
+      [for (int i = 0; value; value = false) 3];
+      break;
+    default:
+      throw "Invalid index";
+  }
+}
diff --git a/tests/language/nnbd/boolean_conversion/boolean_conversion_strong_test.dart b/tests/language/nnbd/boolean_conversion/boolean_conversion_strong_test.dart
new file mode 100644
index 0000000..a64664f
--- /dev/null
+++ b/tests/language/nnbd/boolean_conversion/boolean_conversion_strong_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+// Test implicit casts and null conversions for boolean expressions
+// in strong mode.
+
+import 'package:expect/expect.dart';
+import 'boolean_conversion_lib1.dart';
+
+void main() {
+  check(booleanAsBoolean, true, expectOk);
+  check(booleanAsBoolean, false, expectOk);
+
+  check(dynamicAsBoolean, null, Expect.throwsTypeError);
+  check(dynamicAsBoolean, true, expectOk);
+  check(dynamicAsBoolean, false, expectOk);
+
+  check(dynamicAsBoolean, "", Expect.throwsTypeError);
+  check(dynamicAsBoolean, "true", Expect.throwsTypeError);
+  check(dynamicAsBoolean, "null", Expect.throwsTypeError);
+  check(dynamicAsBoolean, "undefined", Expect.throwsTypeError);
+  check(dynamicAsBoolean, 0, Expect.throwsTypeError);
+  check(dynamicAsBoolean, 1, Expect.throwsTypeError);
+  check(dynamicAsBoolean, [true], Expect.throwsTypeError);
+}
diff --git a/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart b/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart
new file mode 100644
index 0000000..c8b0167
--- /dev/null
+++ b/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart
@@ -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 file.
+
+// @dart=2.7
+
+// Requirements=nnbd-weak
+
+// Test implicit casts and null conversions for boolean expressions
+// in weak mode.
+
+import 'package:expect/expect.dart';
+import 'boolean_conversion_lib1.dart';
+
+void main() {
+  check(neverAsBoolean, null, Expect.throwsAssertionError);
+
+  check(booleanAsBoolean, null, Expect.throwsAssertionError);
+  check(booleanAsBoolean, true, expectOk);
+  check(booleanAsBoolean, false, expectOk);
+
+  check(dynamicAsBoolean, null, Expect.throwsAssertionError);
+  check(dynamicAsBoolean, true, expectOk);
+  check(dynamicAsBoolean, false, expectOk);
+
+  check(dynamicAsBoolean, "", Expect.throwsTypeError);
+  check(dynamicAsBoolean, "true", Expect.throwsTypeError);
+  check(dynamicAsBoolean, "null", Expect.throwsTypeError);
+  check(dynamicAsBoolean, "undefined", Expect.throwsTypeError);
+  check(dynamicAsBoolean, 0, Expect.throwsTypeError);
+  check(dynamicAsBoolean, 1, Expect.throwsTypeError);
+  check(dynamicAsBoolean, [true], Expect.throwsTypeError);
+}
diff --git a/tests/language/nnbd/extreme_bounds/glb_futureor_test.dart b/tests/language/nnbd/extreme_bounds/glb_futureor_test.dart
new file mode 100644
index 0000000..7ebd3ca
--- /dev/null
+++ b/tests/language/nnbd/extreme_bounds/glb_futureor_test.dart
@@ -0,0 +1,159 @@
+// 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:expect/expect.dart';
+
+/*
+ * Set up three synthetic types Left, Right, Bottom, such that
+ * Left and Right are not subtype related, both are
+ * supertypes of Bottom, and GLB(Left, Right) == Bottom
+ */
+typedef Left = void Function(double);
+typedef Right = void Function(int);
+typedef Bottom = void Function(num);
+
+/*
+ * Typedefs which given a type T produce a contra-variant
+ * occurrence of FutureOr<T>, Future<T>, and T respectively.
+ */
+typedef TakesFutureOr<T> = void Function(FutureOr<T>);
+typedef TakesFuture<T> = void Function(Future<T>);
+typedef Takes<T> = void Function(T);
+
+/*
+* Given a type T, produce a type Exactly<T> such that
+* Exactly<S> <: Exactly<T> iff S and T are mutual subtypes.
+*/
+typedef Exactly<T> = T Function(T);
+/*
+* Given an argument of type T, produce a result of type Exactly<T>.
+*/
+Exactly<T> exactly<T>(T t) => (T t) => t;
+
+/*
+* Given a call infer(a, b) where a has type void Function(S0) and b has type
+* void Function(S1), set up an inference constraint system of the form:
+* ? <: T <: S0
+* ? <: T <: S1
+* which merges to:
+* ? <: T <: GLB(S0, S1)
+*/
+Exactly<void Function(T)> infer<T>(void Function(T) x, void Function(T) y) {
+  return (void Function(T) t) => t;
+}
+
+void test(bool b) {
+  // Variables of specific types for input into the GLB algorithm
+  TakesFutureOr<Left> futureOrLeft = (_) {};
+  TakesFutureOr<Right> futureOrRight = (_) {};
+  TakesFuture<Left> futureLeft = (_) {};
+  TakesFuture<Right> futureRight = (_) {};
+  Takes<Left> left = (_) {};
+  Takes<Right> right = (_) {};
+
+  // Check variables of exact type.  Assigning the result of inference
+  // to any of these checks that the result is exactly as expect.
+  Exactly<TakesFutureOr<Bottom>> checkFutureOrBottom = (t) => t;
+  Exactly<TakesFuture<Bottom>> checkFutureBottom = (t) => t;
+  Exactly<Takes<Bottom>> checkBottom = (t) => t;
+
+  // Note: assignments are done in separate steps below to avoid interactions
+  // with downward inference.
+
+  // GLB(FutureOr<A>, FutureOr<B>) = FutureOr<GLB(A, B)>
+  {
+    // Compute the upper bound of the function types, which computes
+    // the GLB of the argument types.
+    var glb = b ? futureOrLeft : futureOrRight;
+    // Capture the inferred type of glb as an exact type.
+    var exactlyGlb = exactly(glb);
+    // Check that the inferred type is exactly as expected.
+    checkFutureOrBottom = exactlyGlb;
+    Expect.type<Exactly<TakesFutureOr<Bottom>>>(exactlyGlb);
+
+    // Compute the upper bound of the function types via inference
+    // constraint merge which computes the GLB of the argument types.
+    var merge = infer(futureOrLeft, futureOrRight);
+    checkFutureOrBottom = merge;
+    Expect.type<Exactly<TakesFutureOr<Bottom>>>(merge);
+  }
+
+  // GLB(FutureOr<A>, Future<B>) = Future<GLB(A, B)>
+  {
+    // Compute the upper bound of the function types, which computes
+    // the GLB of the argument types.
+    var glb = b ? futureOrLeft : futureRight;
+    // Capture the inferred type of glb as an exact type.
+    var exactlyGlb = exactly(glb);
+    // Check that the inferred type is exactly as expected.
+    checkFutureBottom = exactlyGlb;
+    Expect.type<Exactly<TakesFuture<Bottom>>>(exactlyGlb);
+
+    // Compute the upper bound of the function types via inference
+    // constraint merge which computes the GLB of the argument types.
+    var merge = infer(futureOrLeft, futureRight);
+    checkFutureBottom = merge;
+    Expect.type<Exactly<TakesFuture<Bottom>>>(merge);
+  }
+
+  // GLB(Future<A>, FutureOr<B>) = Future<GLB(A, B)>
+  {
+    // Compute the upper bound of the function types, which computes
+    // the GLB of the argument types.
+    var glb = b ? futureLeft : futureOrRight;
+    // Capture the inferred type of glb as an exact type.
+    var exactlyGlb = exactly(glb);
+    // Check that the inferred type is exactly as expected.
+    checkFutureBottom = exactlyGlb;
+    Expect.type<Exactly<TakesFuture<Bottom>>>(exactlyGlb);
+
+    // Compute the upper bound of the function types via inference
+    // constraint merge which computes the GLB of the argument types.
+    var merge = infer(futureLeft, futureOrRight);
+    checkFutureBottom = merge;
+    Expect.type<Exactly<TakesFuture<Bottom>>>(merge);
+  }
+
+  // GLB(FutureOr<A>, B) = GLB(A, B)
+  {
+    // Compute the upper bound of the function types, which computes
+    // the GLB of the argument types.
+    var glb = b ? futureOrLeft : right;
+    // Capture the inferred type of glb as an exact type.
+    var exactlyGlb = exactly(glb);
+    // Check that the inferred type is exactly as expected.
+    checkBottom = exactlyGlb;
+    Expect.type<Exactly<Takes<Bottom>>>(exactlyGlb);
+
+    // Compute the upper bound of the function types via inference
+    // constraint merge which computes the GLB of the argument types.
+    var merge = infer(futureOrLeft, right);
+    checkBottom = merge;
+    Expect.type<Exactly<Takes<Bottom>>>(merge);
+  }
+
+  // GLB(A, FutureOr<B>) = GLB(A, B)
+  {
+    // Compute the upper bound of the function types, which computes
+    // the GLB of the argument types.
+    var glb = b ? left : futureOrRight;
+    // Capture the inferred type of glb as an exact type.
+    var exactlyGlb = exactly(glb);
+    // Check that the inferred type is exactly as expected.
+    checkBottom = exactlyGlb;
+    Expect.type<Exactly<Takes<Bottom>>>(exactlyGlb);
+
+    // Compute the upper bound of the function types via inference
+    // constraint merge which computes the GLB of the argument types.
+    var merge = infer(left, futureOrRight);
+    checkBottom = merge;
+    Expect.type<Exactly<Takes<Bottom>>>(merge);
+  }
+}
+
+main() {
+  test(true);
+  test(false);
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_error_test.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_error_test.dart
new file mode 100644
index 0000000..3566ad6
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_error_test.dart
@@ -0,0 +1,658 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// Verifies that a member declared in a null-safe class which overrides
+// a legacy member with the same name gets a null-safe signature instead of
+// inheriting the legacy signature from the super-interface (concretely,
+// it is not the signature from `A<int*>`).
+
+import 'legacy_resolves_conflict_1_lib2.dart';
+
+void main() {
+  // All classes named `De..` override `m`. The ones whose name ends in `q`
+  // do not admit invoking `isEven`; the remaining ones do not admit passing
+  // null as the parameter to `m`.
+
+  De0().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De0q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De1().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De1q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De2().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De2q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De3().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De3q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De4().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De4q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De5().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De5q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De6().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De6q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De7().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De7q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De8().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De8q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De9().m(null).isEven;
+//        ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De9q().m(null).isEven;
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De10().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De10q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De11().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De11q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De12().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De12q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De13().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De13q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De14().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De14q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De15().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De15q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De16().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De16q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De17().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De17q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De18().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De18q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De19().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De19q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De20().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De20q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De21().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De21q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De22().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De22q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De23().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De23q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De24().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De24q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De25().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De25q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De26().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De26q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De27().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De27q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De28().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De28q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De29().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De29q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De30().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De30q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De31().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De31q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De32().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De32q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De33().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De33q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De34().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De34q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De35().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De35q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De36().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De36q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De37().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De37q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De38().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De38q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De39().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De39q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De40().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De40q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De41().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De41q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De42().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De42q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De43().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De43q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De44().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De44q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De45().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De45q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De46().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De46q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De47().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De47q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De48().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De48q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De49().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De49q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De50().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De50q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De51().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De51q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De52().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De52q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De53().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De53q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De54().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De54q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De55().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De55q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De56().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De56q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De57().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De57q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De58().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De58q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De59().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De59q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De60().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De60q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De61().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De61q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De62().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De62q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De63().m(null).isEven;
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  De63q().m(null).isEven;
+//                ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_legacy_lib.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_legacy_lib.dart
new file mode 100644
index 0000000..5797f56
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_legacy_lib.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.6
+
+// Import a null-safe library which defines several classes `B...`, each of
+// which implements either `A<int>` or `A<int?>`, or in the case of `Bwm` and
+// `Bwmq` which implement either `M<int>` or `M<int?>`, respectively. This
+// library then declares legacy classes that create a superinterface conflict,
+// e.g., by having both `A<int>` and `A<int?>` as indirect superinterfaces.
+// The absence of errors in this test verifies that member signature
+// compatibility in legacy libraries is done with respect to the nullability
+// erased signatures.
+
+import 'legacy_resolves_conflict_1_lib.dart';
+
+// Naming conventions: This library iterates over all the ways a legacy class
+// can have conflicting opted-in classes `B...` as superinterfaces. The ones
+// that can be concrete are concrete. The resulting classes are simply named
+// `C#` where `#` is a running counter (it doesn't seem helpful to encode the
+// way in which each of them has said superinterfaces).
+
+class C0 extends Be implements Beq {}
+
+abstract class C1 implements Be, Beq {}
+
+class C2 extends Be implements Biq {}
+
+abstract class C3 implements Be, Biq {}
+
+class C4 extends Be implements Bwcq {}
+
+abstract class C5 implements Be, Bwcq {}
+
+class C6 extends Be implements Bwmq {}
+
+abstract class C7 implements Be, Bwmq {}
+
+class C8 extends Bi implements Beq {}
+
+abstract class C9 implements Bi, Beq {}
+
+class C10 extends Bi implements Biq {}
+
+abstract class C11 implements Bi, Biq {}
+
+class C12 extends Bi implements Bwcq {}
+
+abstract class C13 implements Bi, Bwcq {}
+
+class C14 extends Bi implements Bwmq {}
+
+abstract class C15 implements Bi, Bwmq {}
+
+class C16 extends Bwc implements Beq {}
+
+abstract class C17 implements Bwc, Beq {}
+
+class C18 extends Bwc implements Biq {}
+
+abstract class C19 implements Bwc, Biq {}
+
+class C20 extends Bwc implements Bwcq {}
+
+abstract class C21 implements Bwc, Bwcq {}
+
+class C22 extends Bwc implements Bwmq {}
+
+abstract class C23 implements Bwc, Bwmq {}
+
+class C24 extends Bwm implements Beq {}
+
+abstract class C25 implements Bwm, Beq {}
+
+class C26 extends Bwm implements Biq {}
+
+abstract class C27 implements Bwm, Biq {}
+
+class C28 extends Bwm implements Bwcq {}
+
+abstract class C29 implements Bwm, Bwcq {}
+
+class C30 extends Bwm implements Bwmq {}
+
+abstract class C31 implements Bwm, Bwmq {}
+
+class C32 extends Beq implements Be {}
+
+abstract class C33 implements Beq, Be {}
+
+class C34 extends Beq implements Bi {}
+
+abstract class C35 implements Beq, Bi {}
+
+class C36 extends Beq implements Bwc {}
+
+abstract class C37 implements Beq, Bwc {}
+
+class C38 extends Beq implements Bwm {}
+
+abstract class C39 implements Beq, Bwm {}
+
+class C40 extends Biq implements Be {}
+
+abstract class C41 implements Biq, Be {}
+
+class C42 extends Biq implements Bi {}
+
+abstract class C43 implements Biq, Bi {}
+
+class C44 extends Biq implements Bwc {}
+
+abstract class C45 implements Biq, Bwc {}
+
+class C46 extends Biq implements Bwm {}
+
+abstract class C47 implements Biq, Bwm {}
+
+class C48 extends Bwcq implements Be {}
+
+abstract class C49 implements Bwcq, Be {}
+
+class C50 extends Bwcq implements Bi {}
+
+abstract class C51 implements Bwcq, Bi {}
+
+class C52 extends Bwcq implements Bwc {}
+
+abstract class C53 implements Bwcq, Bwc {}
+
+class C54 extends Bwcq implements Bwm {}
+
+abstract class C55 implements Bwcq, Bwm {}
+
+class C56 extends Bwmq implements Be {}
+
+abstract class C57 implements Bwmq, Be {}
+
+class C58 extends Bwmq implements Bi {}
+
+abstract class C59 implements Bwmq, Bi {}
+
+class C60 extends Bwmq implements Bwc {}
+
+abstract class C61 implements Bwmq, Bwc {}
+
+class C62 extends Bwmq implements Bwm {}
+
+abstract class C63 implements Bwmq, Bwm {}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_lib.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_lib.dart
new file mode 100644
index 0000000..44d61bb
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_lib.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This library sets up various null-safe classes which have as a
+// superinterface one of `A<int>`,`A<int?>`, `M<int>` or `M<int?>`.
+// Each class has a getter, setter, and method; each is concrete; and
+// the method signatures are incompatible (so the signature from `A<int>`
+// and from `A<int?>` do not have a correct override relationship in
+// any direction), thus allowing a test to verify that legacy type
+// mitigation does take place when superinterfaces like `A<int>` and
+// `A<int?>` are brought together, it is not just overriding.
+
+// Naming conventions: Class `A` and mixin `M` are used as the top of every
+// superinterface graph (except Object). Classes named `Be..` extend `A`,
+// classes named `Bwm..` apply the mixin `M` (`w` refers to `with`), and
+// classes named `Bwc..` apply the class `A` as a mixin. Finally, classes
+// named `Bi..` implement `A`. In each case, classes whose name ends in `q`
+// have `A<int?>` as a superinterface and other classes have `A<int>`.
+// All classes are concrete, so a couple of them repeat the member
+// implementation declarations (with the same member signatures, i.e., with
+// no conflicts).
+
+class A<X> {
+  List<X> get a => [];
+  set a(List<X> _) {}
+  X m(X x) => x;
+}
+
+mixin M<X> {
+  List<X> get a => [];
+  set a(List<X> _) {}
+  X m(X x) => x;
+}
+
+class Be extends A<int> {}
+
+class Bi implements A<int> {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class Beq extends A<int?> {}
+
+class Biq implements A<int?> {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+class Bwc with A<int> {}
+
+class Bwcq with A<int?> {}
+
+class Bwm with M<int> {}
+
+class Bwmq with M<int?> {}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_lib2.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_lib2.dart
new file mode 100644
index 0000000..bb473a9
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_lib2.dart
@@ -0,0 +1,918 @@
+// 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 a legacy library which defines legacy classes each of which brings
+// together conflicting null-safe superinterfaces (e.g. `A<int>` and `A<int?>)
+// and/or brings together members with the same name whose member signatures
+// conflict on nullability.
+
+// Each class defined here overrides all of the members from a legacy class
+// using either nullable or non-nullable types. This test validates that there
+// are no errors triggered by this override: that is, that neither the presence
+// of indirect conflicting interfaces, nor of multiple conflicting member
+// signatures causes an error.
+
+import 'legacy_resolves_conflict_1_legacy_lib.dart';
+
+// Naming conventions: Class `De#` extends `C#`, where `#` stands for a number
+// in 0..63, and declares members whose member signatures use non-nullable
+// types. Class `De#q` extends `C#`, and declares members whose member
+// signatures use nullable types (`q` refers to the question marks). Class
+// `Di#` implements `C#`, is abstract, and does not declare any members.
+
+class De0 extends C0 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De0q extends C0 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di0 implements C0 {}
+
+class De1 extends C1 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De1q extends C1 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di1 implements C1 {}
+
+class De2 extends C2 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De2q extends C2 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di2 implements C2 {}
+
+class De3 extends C3 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De3q extends C3 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di3 implements C3 {}
+
+class De4 extends C4 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De4q extends C4 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di4 implements C4 {}
+
+class De5 extends C5 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De5q extends C5 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di5 implements C5 {}
+
+class De6 extends C6 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De6q extends C6 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di6 implements C6 {}
+
+class De7 extends C7 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De7q extends C7 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di7 implements C7 {}
+
+class De8 extends C8 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De8q extends C8 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di8 implements C8 {}
+
+class De9 extends C9 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De9q extends C9 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di9 implements C9 {}
+
+class De10 extends C10 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De10q extends C10 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di10 implements C10 {}
+
+class De11 extends C11 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De11q extends C11 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di11 implements C11 {}
+
+class De12 extends C12 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De12q extends C12 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di12 implements C12 {}
+
+class De13 extends C13 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De13q extends C13 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di13 implements C13 {}
+
+class De14 extends C14 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De14q extends C14 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di14 implements C14 {}
+
+class De15 extends C15 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De15q extends C15 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di15 implements C15 {}
+
+class De16 extends C16 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De16q extends C16 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di16 implements C16 {}
+
+class De17 extends C17 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De17q extends C17 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di17 implements C17 {}
+
+class De18 extends C18 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De18q extends C18 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di18 implements C18 {}
+
+class De19 extends C19 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De19q extends C19 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di19 implements C19 {}
+
+class De20 extends C20 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De20q extends C20 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di20 implements C20 {}
+
+class De21 extends C21 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De21q extends C21 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di21 implements C21 {}
+
+class De22 extends C22 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De22q extends C22 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di22 implements C22 {}
+
+class De23 extends C23 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De23q extends C23 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di23 implements C23 {}
+
+class De24 extends C24 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De24q extends C24 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di24 implements C24 {}
+
+class De25 extends C25 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De25q extends C25 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di25 implements C25 {}
+
+class De26 extends C26 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De26q extends C26 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di26 implements C26 {}
+
+class De27 extends C27 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De27q extends C27 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di27 implements C27 {}
+
+class De28 extends C28 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De28q extends C28 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di28 implements C28 {}
+
+class De29 extends C29 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De29q extends C29 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di29 implements C29 {}
+
+class De30 extends C30 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De30q extends C30 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di30 implements C30 {}
+
+class De31 extends C31 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De31q extends C31 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di31 implements C31 {}
+
+class De32 extends C32 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De32q extends C32 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di32 implements C32 {}
+
+class De33 extends C33 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De33q extends C33 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di33 implements C33 {}
+
+class De34 extends C34 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De34q extends C34 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di34 implements C34 {}
+
+class De35 extends C35 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De35q extends C35 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di35 implements C35 {}
+
+class De36 extends C36 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De36q extends C36 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di36 implements C36 {}
+
+class De37 extends C37 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De37q extends C37 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di37 implements C37 {}
+
+class De38 extends C38 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De38q extends C38 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di38 implements C38 {}
+
+class De39 extends C39 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De39q extends C39 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di39 implements C39 {}
+
+class De40 extends C40 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De40q extends C40 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di40 implements C40 {}
+
+class De41 extends C41 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De41q extends C41 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di41 implements C41 {}
+
+class De42 extends C42 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De42q extends C42 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di42 implements C42 {}
+
+class De43 extends C43 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De43q extends C43 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di43 implements C43 {}
+
+class De44 extends C44 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De44q extends C44 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di44 implements C44 {}
+
+class De45 extends C45 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De45q extends C45 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di45 implements C45 {}
+
+class De46 extends C46 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De46q extends C46 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di46 implements C46 {}
+
+class De47 extends C47 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De47q extends C47 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di47 implements C47 {}
+
+class De48 extends C48 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De48q extends C48 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di48 implements C48 {}
+
+class De49 extends C49 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De49q extends C49 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di49 implements C49 {}
+
+class De50 extends C50 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De50q extends C50 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di50 implements C50 {}
+
+class De51 extends C51 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De51q extends C51 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di51 implements C51 {}
+
+class De52 extends C52 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De52q extends C52 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di52 implements C52 {}
+
+class De53 extends C53 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De53q extends C53 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di53 implements C53 {}
+
+class De54 extends C54 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De54q extends C54 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di54 implements C54 {}
+
+class De55 extends C55 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De55q extends C55 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di55 implements C55 {}
+
+class De56 extends C56 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De56q extends C56 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di56 implements C56 {}
+
+class De57 extends C57 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De57q extends C57 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di57 implements C57 {}
+
+class De58 extends C58 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De58q extends C58 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di58 implements C58 {}
+
+class De59 extends C59 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De59q extends C59 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di59 implements C59 {}
+
+class De60 extends C60 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De60q extends C60 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di60 implements C60 {}
+
+class De61 extends C61 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De61q extends C61 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di61 implements C61 {}
+
+class De62 extends C62 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De62q extends C62 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di62 implements C62 {}
+
+class De63 extends C63 {
+  List<int> get a => [];
+  set a(List<int> _) {}
+  int m(int x) => x;
+}
+
+class De63q extends C63 {
+  List<int?> get a => [];
+  set a(List<int?> _) {}
+  int? m(int? x) => x;
+}
+
+abstract class Di63 implements C63 {}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_test.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_test.dart
new file mode 100644
index 0000000..157e0a2
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_1_test.dart
@@ -0,0 +1,147 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// Verify that conflicting implemented interfaces are resolved at a legacy
+// class `C`, and an opted-in class can extend or implement `C` without
+// incurring an error.
+
+import 'package:expect/expect.dart';
+import 'legacy_resolves_conflict_1_legacy_lib.dart';
+import 'legacy_resolves_conflict_1_lib2.dart';
+
+void main() {
+  // Ensure that no class is eliminated by tree-shaking.
+  Expect.isNotNull([
+    De0, De0q, Di0, De1, De1q, Di1, De2, De2q, Di2, De3, //
+    De3q, Di3, De4, De4q, Di4, De5, De5q, Di5, De6, De6q, //
+    Di6, De7, De7q, Di7, De8, De8q, Di8, De9, De9q, Di9, //
+    De10, De10q, Di10, De11, De11q, Di11, De12, De12q, Di12, De13, //
+    De13q, Di13, De14, De14q, Di14, De15, De15q, Di15, De16, De16q, //
+    Di16, De17, De17q, Di17, De18, De18q, Di18, De19, De19q, Di19, //
+    De20, De20q, Di20, De21, De21q, Di21, De22, De22q, Di22, De23, //
+    De23q, Di23, De24, De24q, Di24, De25, De25q, Di25, De26, De26q, //
+    Di26, De27, De27q, Di27, De28, De28q, Di28, De29, De29q, Di29, //
+    De30, De30q, Di30, De31, De31q, Di31, De32, De32q, Di32, De33, //
+    De33q, Di33, De34, De34q, Di34, De35, De35q, Di35, De36, De36q, //
+    Di36, De37, De37q, Di37, De38, De38q, Di38, De39, De39q, Di39, //
+    De40, De40q, Di40, De41, De41q, Di41, De42, De42q, Di42, De43, //
+    De43q, Di43, De44, De44q, Di44, De45, De45q, Di45, De46, De46q, //
+    Di46, De47, De47q, Di47, De48, De48q, Di48, De49, De49q, Di49, //
+    De50, De50q, Di50, De51, De51q, Di51, De52, De52q, Di52, De53, //
+    De53q, Di53, De54, De54q, Di54, De55, De55q, Di55, De56, De56q, //
+    Di56, De57, De57q, Di57, De58, De58q, Di58, De59, De59q, Di59, //
+    De60, De60q, Di60, De61, De61q, Di61, De62, De62q, Di62, De63, //
+    De63q, Di63, //
+  ]);
+
+  // Verify that concrete legacy classes implement `A<int*>`, thus allowing
+  // `m(null).isEven` with no compile-time errors, but expect a dynamic error
+  // because every implementation of `m` returns its argument.
+  Expect.throws(() => C0().m(null).isEven);
+  Expect.throws(() => C2().m(null).isEven);
+  Expect.throws(() => C4().m(null).isEven);
+  Expect.throws(() => C6().m(null).isEven);
+  Expect.throws(() => C8().m(null).isEven);
+  Expect.throws(() => C10().m(null).isEven);
+  Expect.throws(() => C12().m(null).isEven);
+  Expect.throws(() => C14().m(null).isEven);
+  Expect.throws(() => C16().m(null).isEven);
+  Expect.throws(() => C18().m(null).isEven);
+  Expect.throws(() => C20().m(null).isEven);
+  Expect.throws(() => C22().m(null).isEven);
+  Expect.throws(() => C24().m(null).isEven);
+  Expect.throws(() => C26().m(null).isEven);
+  Expect.throws(() => C28().m(null).isEven);
+  Expect.throws(() => C30().m(null).isEven);
+  Expect.throws(() => C32().m(null).isEven);
+  Expect.throws(() => C34().m(null).isEven);
+  Expect.throws(() => C36().m(null).isEven);
+  Expect.throws(() => C38().m(null).isEven);
+  Expect.throws(() => C40().m(null).isEven);
+  Expect.throws(() => C42().m(null).isEven);
+  Expect.throws(() => C44().m(null).isEven);
+  Expect.throws(() => C46().m(null).isEven);
+  Expect.throws(() => C48().m(null).isEven);
+  Expect.throws(() => C50().m(null).isEven);
+  Expect.throws(() => C52().m(null).isEven);
+  Expect.throws(() => C54().m(null).isEven);
+  Expect.throws(() => C56().m(null).isEven);
+  Expect.throws(() => C58().m(null).isEven);
+  Expect.throws(() => C60().m(null).isEven);
+  Expect.throws(() => C62().m(null).isEven);
+
+  // Perform a similar check on the abstract classes.
+  void testAbstractClasses(
+      C1 c1,
+      C3 c3,
+      C5 c5,
+      C7 c7,
+      C9 c9,
+      C11 c11,
+      C13 c13,
+      C15 c15,
+      C17 c17,
+      C19 c19,
+      C21 c21,
+      C23 c23,
+      C25 c25,
+      C27 c27,
+      C29 c29,
+      C31 c31,
+      C33 c33,
+      C35 c35,
+      C37 c37,
+      C39 c39,
+      C41 c41,
+      C43 c43,
+      C45 c45,
+      C47 c47,
+      C49 c49,
+      C51 c51,
+      C53 c53,
+      C55 c55,
+      C57 c57,
+      C59 c59,
+      C61 c61,
+      C63 c63) {
+    c1.m(null).isEven;
+    c3.m(null).isEven;
+    c5.m(null).isEven;
+    c7.m(null).isEven;
+    c9.m(null).isEven;
+    c11.m(null).isEven;
+    c13.m(null).isEven;
+    c15.m(null).isEven;
+    c17.m(null).isEven;
+    c19.m(null).isEven;
+    c21.m(null).isEven;
+    c23.m(null).isEven;
+    c25.m(null).isEven;
+    c27.m(null).isEven;
+    c29.m(null).isEven;
+    c31.m(null).isEven;
+    c33.m(null).isEven;
+    c35.m(null).isEven;
+    c37.m(null).isEven;
+    c39.m(null).isEven;
+    c41.m(null).isEven;
+    c43.m(null).isEven;
+    c45.m(null).isEven;
+    c47.m(null).isEven;
+    c49.m(null).isEven;
+    c51.m(null).isEven;
+    c53.m(null).isEven;
+    c55.m(null).isEven;
+    c57.m(null).isEven;
+    c59.m(null).isEven;
+    c61.m(null).isEven;
+    c63.m(null).isEven;
+  }
+
+  // Ensure that `testAbstractClasses` is not eliminated by tree-shaking,
+  // but don't call it (so we avoid the need for actual arguments).
+  print(testAbstractClasses);
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_legacy_lib.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_legacy_lib.dart
new file mode 100644
index 0000000..f5e88b5
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_legacy_lib.dart
@@ -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 file.
+
+// @dart = 2.6
+
+// Import two null-safe classes `B` and `Bq` which contain the same member
+// names with types which are compatible except that they differ in
+// nullability. Declare legacy classes that embody a conflict by having
+// both `B` and `Bq` as superinterfaces. The absence of errors in this test
+// verifies that member signature compatibility in legacy libraries is done
+// with respect to the nullability erased signatures.
+
+import 'legacy_resolves_conflict_2_lib.dart';
+
+// Naming convention: We iterate over all ways `B` and `Bq` can be direct
+// superinterfaces of a class C, and the latter is named `C#` where `#` is
+// simply a running counter (because it seems to be of limited value to
+// encode the way `B` and `Bq` are used as superinterfaces). Note that `C2`
+// and `C5` must be abstract, because we do not wish to declare any members
+// in these classes such that they can be concrete.
+
+class C0 extends B implements Bq {}
+
+class C1 extends B with Bq {}
+
+abstract class C2 implements B, Bq {}
+
+class C3 extends Bq implements B {}
+
+class C4 extends Bq with B {}
+
+abstract class C5 implements Bq, B {}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_lib.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_lib.dart
new file mode 100644
index 0000000..e354dec
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_lib.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This library declares two null-safe classes `B` and `Bq` with members using
+// non-nullable types respectively nullable types. The member signatures are
+// incompatible (there is no correct override relationship between them in
+// any direction), so subtypes can create a conflict by having both as
+// superinterfaces, cf. 'legacy_resolves_conflict_2_legacy_lib.dart'.
+
+// Naming conventions: Class `B` has members whose member signatures use
+// non-nullable types, and `Bq` has members whose member signatures use
+// nullable types (`b` refers to the question marks).
+
+class B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_test.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_test.dart
new file mode 100644
index 0000000..01b6d42
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_2_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// Verify that conflicting member signatures are resolved at a legacy
+// class `C`, and an opted-in class can extend or implement `C` without
+// incurring an error, with and without overriding the conflicting member.
+
+import 'package:expect/expect.dart';
+import 'legacy_resolves_conflict_2_legacy_lib.dart';
+
+// Naming convention: Class `De#` extends class `C#` and declares members
+// with member signatures using non-nullable types (so `int*` is overridden
+// by `int` in various manners). Class `De#q` extends class `C#` and declares
+// members with member signatures using nullable types (so `int*` is
+// overridden by `int?` in various manners). The abstract class `Di#`
+// implements class `C#` and does not declare any members; this just serves
+// to ensure that an opted-in class can implement a legacy class with a
+// baked-in conflict in its member signatures.
+
+class De0 extends C0 {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class De0q extends C0 {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+abstract class Di0 implements C0 {}
+
+class De1 extends C1 {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class De1q extends C1 {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+abstract class Di1 implements C1 {}
+
+class De2 extends C2 {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class De2q extends C2 {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+abstract class Di2 implements C2 {}
+
+class De3 extends C3 {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class De3q extends C3 {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+abstract class Di3 implements C3 {}
+
+class De4 extends C4 {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class De4q extends C4 {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+abstract class Di4 implements C4 {}
+
+class De5 extends C5 {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class De5q extends C5 {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+abstract class Di5 implements C5 {}
+
+void main() {
+  // Ensure that no class is eliminated by tree-shaking.
+  Expect.isNotNull([C0, C1, C2, C3, C4, C5]);
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_error_test.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_error_test.dart
new file mode 100644
index 0000000..bda8280
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_error_test.dart
@@ -0,0 +1,356 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// Verify that member signatures are computed correctly for null-safe
+// classes having both a legacy and a null-safe superinterface, and with some
+// classes also overriding declarations in the class itself. The expected
+// member signatures are indicated in comments on each class in the library
+// 'legacy_resolves_conflict_3_lib2.dart'. This test uses lack of assignability
+// to ascertain that a selection of classes that are expected to have a
+// null-safe member signature for `m` do not have a legacy member signature.
+
+// The point is that 'legacy_resolves_conflict_3_test.dart' would succeed even
+// in the case where, say, `DwB0().a` has type `List<int* Function(int*)>`,
+// and similarly for other receiver types, but this test would then fail
+// to have the corresponding compile-time errors.
+
+import 'legacy_resolves_conflict_3_legacy_lib.dart';
+import 'legacy_resolves_conflict_3_lib.dart';
+import 'legacy_resolves_conflict_3_lib2.dart';
+
+// Naming conventions: Please consult 'legacy_resolves_conflict_3_lib2.dart'.
+
+class DiBqO0 implements C0, Bq {
+  List<int Function(int)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int Function(int)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int Function(int) m(int Function(int) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBOq0 implements C0, B {
+  List<int? Function(int?)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int? Function(int?)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int? Function(int?) m(int? Function(int?) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBqO1 implements C1, Bq {
+  List<int Function(int)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int Function(int)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int Function(int) m(int Function(int) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBOq1 implements C1, B {
+  List<int? Function(int?)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int? Function(int?)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int? Function(int?) m(int? Function(int?) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBqO2 implements C2, Bq {
+  List<int Function(int)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int Function(int)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int Function(int) m(int Function(int) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBOq2 implements C2, B {
+  List<int? Function(int?)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int? Function(int?)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int? Function(int?) m(int? Function(int?) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBqO3 implements C3, Bq {
+  List<int Function(int)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int Function(int)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int Function(int) m(int Function(int) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBOq3 implements C3, B {
+  List<int? Function(int?)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int? Function(int?)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int? Function(int?) m(int? Function(int?) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBqO4 implements C4, Bq {
+  List<int Function(int)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int Function(int)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int Function(int) m(int Function(int) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBOq4 implements C4, B {
+  List<int? Function(int?)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int? Function(int?)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int? Function(int?) m(int? Function(int?) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBqO5 implements C5, Bq {
+  List<int Function(int)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int Function(int)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int Function(int) m(int Function(int) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+class DiBOq5 implements C5, B {
+  List<int? Function(int?)> get a => [];
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  set a(List<int? Function(int?)> _) {}
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  int? Function(int?) m(int? Function(int?) x) => x;
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+void main() {
+  // Verify that some classes have a signature which is not as in `Bq`.
+  List<List<int? Function(int?)>> xsBq = [
+    DwB0().a,
+//  ^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBO0().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwB1().a,
+//  ^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBO1().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwB2().a,
+//  ^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBO2().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwB3().a,
+//  ^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBO3().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwB4().a,
+//  ^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBO4().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwB5().a,
+//  ^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBO5().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+  ];
+
+  // Verify that some classes have a signature which is not as in `B`.
+  List<List<int Function(int)>> xsB = [
+    DwBq0().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBqOq0().a,
+//  ^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwBq1().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBqOq1().a,
+//  ^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwBq2().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBqOq2().a,
+//  ^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwBq3().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBqOq3().a,
+//  ^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwBq4().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBqOq4().a,
+//  ^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DwBq5().a,
+//  ^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+
+    DiBqOq5().a,
+//  ^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+// [cfe] unspecified
+  ];
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_legacy_lib.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_legacy_lib.dart
new file mode 100644
index 0000000..1e56adc
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_legacy_lib.dart
@@ -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 file.
+
+// @dart = 2.6
+
+// Import two null-safe classes `B` and `Bq` which contain the same member
+// names with types that are compatible except that they differ in nullability.
+// Declare legacy classes that has either `B` or `Bq` as a superinterface.
+
+// The absence of errors in this test is unremarkable (there are no conflicts),
+// but it allows for a null-safe subtype to declare overriding members, cf.
+// 'legacy_resolves_conflict_3_lib2.dart'.
+
+import 'legacy_resolves_conflict_3_lib.dart';
+
+// Naming convention: Class `C#`, where `#` is just a running counter, has
+// a single legacy class (`B` or `Bq`) as a superinterface. The point is that
+// we wish to test the treatment of a legacy class when there is no conflict
+// among its opted-in superinterfaces: `C#` is considered to implement
+// `A<int*>`, for all `#`.
+
+class C0 extends B {}
+
+class C1 with B {}
+
+abstract class C2 implements B {}
+
+class C3 extends Bq {}
+
+class C4 with Bq {}
+
+abstract class C5 implements Bq {}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_lib.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_lib.dart
new file mode 100644
index 0000000..c936fd2
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_lib.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This library declares two null-safe classes `B` and `Bq` with members
+// using non-nullable types respectively nullable types. Subtypes having
+// either `B` or `Bq` as a superinterface are declared in the library
+// 'legacy_resolves_conflict_3_legacy_lib.dart', and the library
+// 'legacy_resolves_conflict_3_lib2.dart' declares an override. See the
+// comments there for further information.
+
+// Naming convention: Class `B` has member signatures using non-nullable types,
+// and `Bq` has member signatures using nullable types (`q` refers to the
+// question marks).
+
+class B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+class Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_lib2.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_lib2.dart
new file mode 100644
index 0000000..8702ebe
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_lib2.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Each class defined here has a legacy superinterface as well as a null-safe
+// superinterface, thus bringing together legacy and null-safe member
+// signatures. Some classes also contain overriding member declarations.
+// Each class has a comment indicating the expected member signatures.
+// We use this to test whether the resulting member signature is computed
+// correctly, cf. 'legacy_resolves_conflict_3{,_error}_test.dart'.
+
+import 'legacy_resolves_conflict_3_legacy_lib.dart';
+import 'legacy_resolves_conflict_3_lib.dart';
+
+// Naming conventions: Every class in this library has a name starting with
+// `D`, to identify it as belonging to this group: Opted-in, subtype of a
+// legacy class.
+//
+// Every class name ends in a digit, that we designate as `#`. A class whose
+// name ends in `#` extends or implements the legacy class `C#`.
+//
+// The class `DiX#` implements `X` (`i` refers to `implements`). The class
+// `DwX#` applies `X` as a mixin (`w` refers to `with`). The class `DiXO#`
+// implements `X` and declares overriding members using non-nullable
+// types. Class `DiXOq#` implements `X` and declares overriding members using
+// nullable types.
+
+// When `C#` is considered to implement `A<int*>` it becomes possible for a
+// subtype of `C#` to have a superinterface with members that are compatible
+// with the members of `A<int*>`, even in the case where they conflict with
+// members of `A<int>`/`A<int?>`, which is actually found in the superinterface
+// graph of `C#`. That kind of relationship is created by this library.
+
+// Member signatures: B.
+class DiB0 extends C0 implements B {}
+
+// Member signatures: Bq.
+class DiBq0 extends C0 implements Bq {}
+
+// Member signatures: B.
+class DwB0 extends C0 with B {}
+
+// Member signatures: Bq.
+class DwBq0 extends C0 with Bq {}
+
+// Member signatures: B.
+class DiBO0 implements C0, B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+// Member signatures: Bq.
+class DiBqOq0 implements C0, Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+// Member signatures: B.
+class DiB1 extends C1 implements B {}
+
+// Member signatures: Bq.
+class DiBq1 extends C1 implements Bq {}
+
+// Member signatures: B.
+class DwB1 extends C1 with B {}
+
+// Member signatures: Bq.
+class DwBq1 extends C1 with Bq {}
+
+// Member signatures: B.
+class DiBO1 implements C1, B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+// Member signatures: Bq.
+class DiBqOq1 implements C1, Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+// Member signatures: B.
+abstract class DiB2 extends C2 implements B {}
+
+// Member signatures: Bq.
+abstract class DiBq2 extends C2 implements Bq {}
+
+// Member signatures: B.
+class DwB2 extends C2 with B {}
+
+// Member signatures: Bq.
+class DwBq2 extends C2 with Bq {}
+
+// Member signatures: B.
+class DiBO2 implements C2, B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+// Member signatures: Bq.
+class DiBqOq2 implements C2, Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+// Member signatures: B.
+class DiB3 extends C3 implements B {}
+
+// Member signatures: Bq.
+class DiBq3 extends C3 implements Bq {}
+
+// Member signatures: B.
+class DwB3 extends C3 with B {}
+
+// Member signatures: Bq.
+class DwBq3 extends C3 with Bq {}
+
+// Member signatures: B.
+class DiBO3 implements C3, B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+// Member signatures: Bq.
+class DiBqOq3 implements C3, Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+// Member signatures: B.
+class DiB4 extends C4 implements B {}
+
+// Member signatures: Bq.
+class DiBq4 extends C4 implements Bq {}
+
+// Member signatures: B.
+class DwB4 extends C4 with B {}
+
+// Member signatures: Bq.
+class DwBq4 extends C4 with Bq {}
+
+// Member signatures: B.
+class DiBO4 implements C4, B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+// Member signatures: Bq.
+class DiBqOq4 implements C4, Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
+
+// Member signatures: B.
+abstract class DiB5 extends C5 implements B {}
+
+// Member signatures: Bq.
+abstract class DiBq5 extends C5 implements Bq {}
+
+// Member signatures: B.
+class DwB5 extends C5 with B {}
+
+// Member signatures: Bq.
+class DwBq5 extends C5 with Bq {}
+
+// Member signatures: B.
+class DiBO5 implements C5, B {
+  List<int Function(int)> get a => [];
+  set a(List<int Function(int)> _) {}
+  int Function(int) m(int Function(int) x) => x;
+}
+
+// Member signatures: Bq.
+class DiBqOq5 implements C5, Bq {
+  List<int? Function(int?)> get a => [];
+  set a(List<int? Function(int?)> _) {}
+  int? Function(int?) m(int? Function(int?) x) => x;
+}
diff --git a/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_test.dart b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_test.dart
new file mode 100644
index 0000000..c5ccb58
--- /dev/null
+++ b/tests/language/nnbd/mixed_inheritance/legacy_resolves_conflict_3_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// Verify that member signatures are computed correctly for null-safe
+// classes having both a legacy and a null-safe superinterface, and with some
+// classes also overriding declarations in the class itself. The expected
+// member signatures are indicated in comments on each class in the library
+// 'legacy_resolves_conflict_3_lib2.dart'. This test uses assignability to
+// confirm that the return type of the getter `a` is assignable to the
+// expected type; 'legacy_resolves_conflict_3_error_test.dart' complements
+// this by ascertaining that said return type is not legacy.
+
+import 'package:expect/expect.dart';
+import 'legacy_resolves_conflict_3_lib.dart';
+import 'legacy_resolves_conflict_3_lib2.dart';
+
+void main() {
+  // Ensure that no class is eliminated by tree-shaking.
+  Expect.isNotNull([
+    DiB0, DiBq0, DwB0, DwBq0, DiBO0, DiBqOq0, //
+    DiB1, DiBq1, DwB1, DwBq1, DiBO1, DiBqOq1, //
+    DiB2, DiBq2, DwB2, DwBq2, DiBO2, DiBqOq2, //
+    DiB3, DiBq3, DwB3, DwBq3, DiBO3, DiBqOq3, //
+    DiB4, DiBq4, DwB4, DwBq4, DiBO4, DiBqOq4, //
+    DiB5, DiBq5, DwB5, DwBq5, DiBO5, DiBqOq5, //
+  ]);
+
+  // Verify that some classes have a signature as in `B`.
+  List<List<int Function(int)>> xsB = [
+    DiB0().a, DwB0().a, DiBO0().a, DiB1().a, DwB1().a, DiBO1().a, //
+    /*DiB2,*/ DwB2().a, DiBO2().a, DiB3().a, DwB3().a, DiBO3().a, //
+    DiB4().a, DwB4().a, DiBO4().a, /*DiB5,*/ DwB5().a, DiBO5().a, //
+  ];
+
+  // Verify that some classes have a signature as in `Bq`.
+  List<List<int? Function(int?)>> xsBq = [
+    DiBq0().a, DwBq0().a, DiBqOq0().a, DiBq1().a, DwBq1().a, DiBqOq1().a, //
+    /*DiBq2,*/ DwBq2().a, DiBqOq2().a, DiBq3().a, DwBq3().a, DiBqOq3().a, //
+    DiBq4().a, DwBq4().a, DiBqOq4().a, /*DiBq5,*/ DwBq5().a, DiBqOq5().a, //
+  ];
+
+  void testAbstractClasses(DiB2 diB2, DiBq2 diBq2, DiB5 diB5, DiBq5 diBq5) {
+    List<List<int Function(int)>> xsB = [diB2.a, diB5.a];
+    List<List<int? Function(int?)>> xsBq = [diBq2.a, diBq5.a];
+    print("$xsB, $xsBq");
+  }
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_error_test.dart b/tests/language/nnbd/never/never_null_assignability_error_test.dart
new file mode 100644
index 0000000..5c745a6
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_error_test.dart
@@ -0,0 +1,217 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'never_null_assignability_lib1.dart';
+
+// This test validates that in a null safe (opted in) library which calls out
+// to another null safe (opted in) library, the static errors around `Never`
+// and `Null` that are suppressed when calling out a null safe library from
+// a **legacy** library are correctly reported.  This file is derived from
+// never_null_assignability_weak_test.dart and validates that calls to a
+// null safe library that are only permitted in that test because of legacy
+// support become errors when it is opted in.
+
+// Tests for direct calls to null safe functions.
+void testNullSafeCalls() {
+  // Test calling a null safe function expecting Null from a null safe library
+  {
+    takesNull(nil);
+    takesNull(never);
+    takesNull(3 as dynamic);
+    (takesNull as dynamic)(3);
+  }
+
+  // Test calling a null safe function expecting Never from a null safe library
+  {
+    takesNever(nil);
+    //         ^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'Null' can't be assigned to the parameter type 'Never'.
+    takesNever(never);
+    takesNever(3 as dynamic);
+    (takesNever as dynamic)(3);
+  }
+
+  // Test calling a null safe function expecting int from a null safe library
+  {
+    takesInt(3);
+    takesInt(nil);
+    //       ^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'Null' can't be assigned to the parameter type 'int'.
+    takesInt(nil as dynamic);
+    (takesInt as dynamic)(nil);
+    (takesInt as dynamic)("hello");
+  }
+
+  // Test calling a null safe function expecting Object from a null safe library
+  {
+    takesObject(3);
+    takesObject(nil);
+    //          ^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'Null' can't be assigned to the parameter type 'Object'.
+    takesObject(nil as dynamic);
+    (takesObject as dynamic)(nil);
+  }
+
+  // Test calling a null safe function expecting Object? from a null safe library
+  {
+    takesAny(3);
+    takesAny(nil);
+    (takesAny as dynamic)(nil);
+  }
+}
+
+void testNullSafeApply() {
+  // Test applying a null safe function of static type void Function(Null)
+  // in a null safe library, when called with null cast to Null at the call
+  // site.
+  {
+    applyTakesNull(takesNull, nil);
+    applyTakesNull(takesNever, nil);
+    //             ^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNull(takesAny, nil);
+
+    applyTakesNull(takesInt, nil);
+    //             ^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNull(takesObject, nil);
+    //             ^^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
+  }
+
+  // Test applying a null safe function of static type void Function(Null)
+  // in a null safe library, when called with a non-null value cast to Null
+  // at the call site.
+  {
+    applyTakesNull(takesNull, 3);
+    applyTakesNull(takesNever, 3);
+    //             ^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNull(takesInt, 3);
+    //             ^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNull(takesObject, 3);
+    //             ^^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNull(takesAny, 3);
+  }
+
+  // Test applying a null safe function of static type void Function(Never)
+  // in a null safe library, when called with null cast to Never at the call
+  // site.
+  {
+    applyTakesNever(takesNull, nil);
+    applyTakesNever(takesNever, nil);
+    applyTakesNever(takesAny, nil);
+    applyTakesNever(takesInt, nil);
+    applyTakesNever(takesObject, nil);
+  }
+
+  // Test applying a null safe function of static type void Function(Never)
+  // in a null safe library, when called with a non-null value cast to Never
+  // at the call site.
+  {
+    applyTakesNever(takesNull, 3);
+    applyTakesNever(takesNever, 3);
+    applyTakesNever(takesInt, 3);
+    applyTakesNever(takesObject, 3);
+    applyTakesNever(takesAny, 3);
+  }
+}
+
+void testNullSafeApplyDynamically() {
+  // Test dynamically applying a null safe function of static type
+  // void Function(Null) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNullDynamically(takesNull, nil);
+    applyTakesNullDynamically(takesNever, nil);
+    //                        ^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNullDynamically(takesAny, nil);
+    applyTakesNullDynamically(takesInt, nil);
+    //                        ^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNullDynamically(takesObject, nil);
+    //                        ^^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Null) in a null safe library, when called with
+  // a non-null value.
+  {
+    applyTakesNullDynamically(takesNull, 3);
+    applyTakesNullDynamically(takesNever, 3);
+    //                        ^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNullDynamically(takesInt, 3);
+    //                        ^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNullDynamically(takesInt, "hello");
+    //                        ^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNullDynamically(takesObject, 3);
+    //                        ^^^^^^^^^^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
+    applyTakesNullDynamically(takesAny, 3);
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Never) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNeverDynamically(takesNull, nil);
+    applyTakesNeverDynamically(takesNever, nil);
+    applyTakesNeverDynamically(takesAny, nil);
+    applyTakesNeverDynamically(takesInt, nil);
+    applyTakesNeverDynamically(takesObject, nil);
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Never) in a null safe library, when called with
+  // a non-null value.
+  {
+    applyTakesNeverDynamically(takesNull, 3);
+    applyTakesNeverDynamically(takesNever, 3);
+    applyTakesNeverDynamically(takesInt, 3);
+    applyTakesNeverDynamically(takesInt, "hello");
+    applyTakesNeverDynamically(takesObject, 3);
+    applyTakesNeverDynamically(takesAny, 3);
+  }
+}
+
+void main() {
+  never = null;
+  // ^
+  // [analyzer] unspecified
+  //      ^
+  // [cfe] A value of type 'Null' can't be assigned to a variable of type 'Never'.
+  never = nil;
+  // ^
+  // [analyzer] unspecified
+  //      ^
+  // [cfe] A value of type 'Null' can't be assigned to a variable of type 'Never'.
+  nil = never;
+  testNullSafeCalls();
+  testNullSafeApply();
+  testNullSafeApplyDynamically();
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_lib1.dart b/tests/language/nnbd/never/never_null_assignability_lib1.dart
new file mode 100644
index 0000000..b006476
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_lib1.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Null nil = null;
+
+Never never = throw "Never";
+
+void takesAny(Object? n) {}
+
+void takesObject(Object n) {
+  // In weak mode, we may get null.  Throw AssertionError so that this
+  // can be distinguished from a dynamic call failure.
+  if (n == null) throw AssertionError("Not an Object");
+}
+
+void takesInt(int n) {
+  // In weak mode, we may get null.  Throw AssertionError so that this
+  // can be distinguished from a dynamic call failure.
+  if (n == null) throw AssertionError("Not an int");
+}
+
+void takesNull(Null n) {
+  if (n != null) throw AssertionError("Not null");
+}
+
+void takesNever(Never n) {
+  // In weak mode, we may get null.  Throw AssertionError so that this
+  // can be distinguished from a dynamic call failure.
+  if (n != null) throw AssertionError("Not null");
+}
+
+void applyTakesNull(void Function(Null) fn, dynamic arg) {
+  // Make the cast explicit for clarity.
+  fn(arg as Null);
+}
+
+void applyTakesNever(void Function(Never) fn, dynamic arg) {
+  // Make the cast explicit for clarity.
+  fn(arg as Never);
+}
+
+void applyTakesNullDynamically(void Function(Null) fn, dynamic arg) {
+  (fn as dynamic)(arg);
+}
+
+void applyTakesNeverDynamically(void Function(Never) fn, dynamic arg) {
+  (fn as dynamic)(arg);
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_strong_test.dart b/tests/language/nnbd/never/never_null_assignability_strong_test.dart
new file mode 100644
index 0000000..a902e45
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_strong_test.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import 'package:expect/expect.dart';
+import 'never_null_assignability_lib1.dart';
+
+// Tests for direct calls to null safe functions.
+void testNullSafeCalls() {
+  // Test calling a null safe function expecting Null from a null safe libary
+  {
+    takesNull(nil);
+    Expect.throws<String>(() => takesNull(never));
+    // 3 can't be cast to Null or Never
+    Expect.throwsTypeError(() => takesNull(3 as dynamic));
+    Expect.throwsTypeError(() => (takesNull as dynamic)(3));
+  }
+
+  // Test calling a null safe function expecting Never from a null safe libary
+  {
+    Expect.throws<String>(() => takesNever(never));
+    // 3 can't be cast to Null or Never
+    Expect.throwsTypeError(() => takesNever(3 as dynamic));
+    Expect.throwsTypeError(() => (takesNever as dynamic)(3));
+  }
+
+  // Test calling a null safe function expecting int from a null safe libary
+  {
+    takesInt(3);
+    Expect.throwsTypeError(() => takesInt(nil as dynamic));
+    Expect.throwsTypeError(() => (takesInt as dynamic)(nil));
+    Expect.throwsTypeError(() => (takesInt as dynamic)("hello"));
+  }
+
+  // Test calling a null safe function expecting Object from a null safe libary
+  {
+    takesObject(3);
+    Expect.throwsTypeError(() => takesObject(nil as dynamic));
+    Expect.throwsTypeError(() => (takesObject as dynamic)(nil));
+  }
+
+  // Test calling a null safe function expecting Object? from a null safe libary
+  {
+    takesAny(3);
+    takesAny(nil);
+    (takesAny as dynamic)(nil);
+  }
+}
+
+void testNullSafeApply() {
+  // Test applying a null safe function of static type void Function(Null)
+  // in a null safe library, when called with null cast to Null at the call
+  // site.
+  {
+    applyTakesNull(takesNull, nil);
+    applyTakesNull(takesAny, nil);
+  }
+
+  // Test applying a null safe function of static type void Function(Null)
+  // in a null safe library, when called with a non-null value cast to Null
+  // at the call site.
+  {
+    Expect.throwsTypeError(() => applyTakesNull(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesAny, 3));
+  }
+
+  // Test applying a null safe function of static type void Function(Never)
+  // in a null safe library, when called with null cast to Never at the call
+  // site.
+  {
+    // Cast of null to Never should fail.
+    Expect.throwsTypeError(() => applyTakesNever(takesNull, nil));
+    // Cast of null to Never should fail.
+    Expect.throwsTypeError(() => applyTakesNever(takesNever, nil));
+    // Cast of null to Never should fail.
+    Expect.throwsTypeError(() => applyTakesNever(takesInt, nil));
+    // Cast of null to Never should fail.
+    Expect.throwsTypeError(() => applyTakesNever(takesObject, nil));
+    // Cast of null to Never should fail.
+    Expect.throwsTypeError(() => applyTakesNever(takesAny, nil));
+  }
+
+  // Test applying a null safe function of static type void Function(Never)
+  // in a null safe library, when called with a non-null value cast to Never
+  // at the call site.
+  {
+    Expect.throwsTypeError(() => applyTakesNever(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesNever, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesInt, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesObject, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesAny, 3));
+  }
+}
+
+void testNullSafeApplyDynamically() {
+  // Test dynamically applying a null safe function of static type
+  // void Function(Null) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNullDynamically(takesNull, nil);
+    applyTakesNullDynamically(takesAny, nil);
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Null) in a null safe library, when called with
+  // a non-null value.
+  {
+    Expect.throwsTypeError(() => applyTakesNullDynamically(takesNull, 3));
+    applyTakesNullDynamically(takesAny, 3);
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Never) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNeverDynamically(takesNull, nil);
+    applyTakesNeverDynamically(takesAny, nil);
+
+    // Dynamic call should fail.
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, nil));
+    // Dynamic call should fail.
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, nil));
+    // Dynamic call should fail.
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesObject, nil));
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Never) in a null safe library, when called with
+  // a non-null value.
+  {
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, 3));
+    applyTakesNeverDynamically(takesInt, 3);
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, "hello"));
+    applyTakesNeverDynamically(takesObject, 3);
+    applyTakesNeverDynamically(takesAny, 3);
+  }
+}
+
+void main() {
+  testNullSafeCalls();
+  testNullSafeApply();
+  testNullSafeApplyDynamically();
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_weak_test.dart b/tests/language/nnbd/never/never_null_assignability_weak_test.dart
new file mode 100644
index 0000000..1c87799
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_weak_test.dart
@@ -0,0 +1,316 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.7
+
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+import 'never_null_assignability_lib1.dart';
+
+void takesLegacyObject(Object n) {
+  // In a legacy library, we may get null.  Throw AssertionError so that this
+  // can be distinguished from a dynamic call failure.
+  if (n == null) throw AssertionError("Not an Object");
+}
+
+void takesLegacyInt(int n) {
+  // In a legacy library, we may get null.  Throw AssertionError so that this
+  // can be distinguished from a dynamic call failure.
+  if (n == null) throw AssertionError("Not an int");
+}
+
+void takesLegacyNull(Null n) {
+  // This should never happen!
+  if (n != null) throw AssertionError("Not null");
+}
+
+// Tests for direct calls to null safe functions.
+void testNullSafeCalls() {
+  // Test calling a null safe function expecting Null from a legacy library
+  {
+    takesNull(nil);
+    takesNull(never);
+    // Even in weak mode, 3 can't be cast to Null or Never
+    Expect.throwsTypeError(() => takesNull(3 as dynamic));
+    Expect.throwsTypeError(() => (takesNull as dynamic)(3));
+  }
+
+  // Test calling a null safe function expecting Never from a legacy library
+  {
+    takesNever(nil);
+    takesNever(never);
+    // Even in weak mode, 3 can't be cast to Null or Never
+    Expect.throwsTypeError(() => takesNever(3 as dynamic));
+    Expect.throwsTypeError(() => (takesNever as dynamic)(3));
+  }
+
+  // Test calling a null safe function expecting int from a legacy library
+  {
+    takesInt(3);
+    Expect.throwsAssertionError(() => takesInt(nil));
+    Expect.throwsAssertionError(() => takesInt(nil as dynamic));
+    Expect.throwsAssertionError(() => (takesInt as dynamic)(nil));
+    Expect.throwsTypeError(() => (takesInt as dynamic)("hello"));
+  }
+
+  // Test calling a null safe function expecting Object from a legacy library
+  {
+    takesObject(3);
+    Expect.throwsAssertionError(() => takesObject(nil));
+    Expect.throwsAssertionError(() => takesObject(nil as dynamic));
+    Expect.throwsAssertionError(() => (takesObject as dynamic)(nil));
+  }
+
+  // Test calling a null safe function expecting Object? from a legacy library
+  {
+    takesAny(3);
+    takesAny(nil);
+    (takesAny as dynamic)(nil);
+  }
+}
+
+// Tests for direct calls to legacy functions.
+void testLegacyCalls() {
+  // Test calling a legacy function expecting Null from a legacy library
+  {
+    takesLegacyNull(nil);
+    // Even in weak mode, 3 can't be cast to Null or Never
+    Expect.throwsTypeError(() => takesLegacyNull(3 as dynamic));
+    Expect.throwsTypeError(() => (takesLegacyNull as dynamic)(3));
+  }
+
+  // Test calling a legacy function expecting int from a legacy library
+  {
+    takesLegacyInt(3);
+    Expect.throwsAssertionError(() => takesLegacyInt(nil));
+    Expect.throwsAssertionError(() => (takesLegacyInt as dynamic)(nil));
+    Expect.throwsTypeError(() => (takesLegacyInt as dynamic)("hello"));
+  }
+
+  // Test calling a legacy function expecting Object from a legacy library
+  {
+    takesLegacyObject(3);
+    Expect.throwsAssertionError(() => takesLegacyObject(nil));
+    Expect.throwsAssertionError(() => (takesLegacyObject as dynamic)(nil));
+  }
+}
+
+void testNullSafeApply() {
+  // Test applying a null safe function of static type void Function(Null)
+  // in a null safe library, when called with null cast to Null at the call
+  // site.
+  {
+    applyTakesNull(takesNull, nil);
+    applyTakesNull(takesNever, nil);
+    applyTakesNull(takesAny, nil);
+
+    // Cast of null to Null shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNull(takesInt, nil));
+    // Cast of null to Null shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNull(takesObject, nil));
+  }
+
+  // Test applying a null safe function of static type void Function(Null)
+  // in a null safe library, when called with a non-null value cast to Null
+  // at the call site.
+  {
+    Expect.throwsTypeError(() => applyTakesNull(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesNever, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesInt, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesObject, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesAny, 3));
+  }
+
+  // Test applying a null safe function of static type void Function(Never)
+  // in a null safe library, when called with null cast to Never at the call
+  // site.
+  {
+    applyTakesNever(takesNull, nil);
+    applyTakesNever(takesNever, nil);
+    applyTakesNever(takesAny, nil);
+
+    // Cast of null to Never shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNever(takesInt, nil));
+    // Cast of null to Never shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNever(takesObject, nil));
+  }
+
+  // Test applying a null safe function of static type void Function(Never)
+  // in a null safe library, when called with a non-null value cast to Never
+  // at the call site.
+  {
+    Expect.throwsTypeError(() => applyTakesNever(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesNever, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesInt, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesObject, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesAny, 3));
+  }
+}
+
+void testLegacyApply() {
+  // Test applying a legacy function of static type void Function(Null)
+  // in a null safe library, when called with null cast to Null at the call
+  // site.
+  {
+    applyTakesNull(takesLegacyNull, nil);
+
+    // Cast of null to Null shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNull(takesLegacyInt, nil));
+    // Cast of null to Null shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNull(takesLegacyObject, nil));
+  }
+
+  // Test applying a legacy function of static type void Function(Null)
+  // in a null safe library, when called with a non-null value cast to Null
+  // at the call site.
+  {
+    Expect.throwsTypeError(() => applyTakesNull(takesLegacyNull, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesLegacyInt, 3));
+    Expect.throwsTypeError(() => applyTakesNull(takesLegacyObject, 3));
+  }
+
+  // Test applying a legacy function of static type void Function(Never)
+  // in a null safe library, when called with null cast to Never at the call
+  // site.
+  {
+    applyTakesNever(takesLegacyNull, nil);
+
+    // Cast of null to Never shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNever(takesLegacyInt, nil));
+    // Cast of null to Never shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNever(takesLegacyObject, nil));
+  }
+
+  // Test applying a legacy function of static type void Function(Never)
+  // in a null safe library, when called with a non-null value cast to Never
+  // at the call site.
+  {
+    Expect.throwsTypeError(() => applyTakesNever(takesLegacyNull, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesLegacyInt, 3));
+    Expect.throwsTypeError(() => applyTakesNever(takesLegacyObject, 3));
+  }
+}
+
+void testNullSafeApplyDynamically() {
+  // Test dynamically applying a null safe function of static type
+  // void Function(Null) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNullDynamically(takesNull, nil);
+    applyTakesNullDynamically(takesNever, nil);
+    applyTakesNullDynamically(takesAny, nil);
+
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(() => applyTakesNullDynamically(takesInt, nil));
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNullDynamically(takesObject, nil));
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Null) in a null safe library, when called with
+  // a non-null value.
+  {
+    Expect.throwsTypeError(() => applyTakesNullDynamically(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNullDynamically(takesNever, 3));
+    applyTakesNullDynamically(takesInt, 3);
+    Expect.throwsTypeError(() => applyTakesNullDynamically(takesInt, "hello"));
+    applyTakesNullDynamically(takesObject, 3);
+    applyTakesNullDynamically(takesAny, 3);
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Never) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNeverDynamically(takesNull, nil);
+    applyTakesNeverDynamically(takesNever, nil);
+    applyTakesNeverDynamically(takesAny, nil);
+
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNeverDynamically(takesInt, nil));
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNeverDynamically(takesObject, nil));
+  }
+
+  // Test dynamically applying a null safe function of static type
+  // void Function(Never) in a null safe library, when called with
+  // a non-null value.
+  {
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNull, 3));
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, 3));
+    applyTakesNeverDynamically(takesInt, 3);
+    Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, "hello"));
+    applyTakesNeverDynamically(takesObject, 3);
+    applyTakesNeverDynamically(takesAny, 3);
+  }
+}
+
+void testLegacyApplyDynamically() {
+  // Test dynamically applying a legacy function of static type
+  // void Function(Null) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNullDynamically(takesLegacyNull, nil);
+
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNullDynamically(takesLegacyInt, nil));
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNullDynamically(takesLegacyObject, nil));
+  }
+
+  // Test dynamically applying a legacy function of static type
+  // void Function(Null) in a null safe library, when called with
+  // a non-null value.
+  {
+    Expect.throwsTypeError(() => applyTakesNullDynamically(takesLegacyNull, 3));
+    applyTakesNullDynamically(takesLegacyInt, 3);
+    Expect.throwsTypeError(
+        () => applyTakesNullDynamically(takesLegacyInt, "hello"));
+    applyTakesNullDynamically(takesLegacyObject, 3);
+  }
+
+  // Test dynamically applying a legacy function of static type
+  // void Function(Never) in a null safe library, when called with
+  // null.
+  {
+    applyTakesNeverDynamically(takesLegacyNull, nil);
+
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNeverDynamically(takesLegacyInt, nil));
+    // Dynamic call shouldn't fail, check that we reach the assertion.
+    Expect.throwsAssertionError(
+        () => applyTakesNeverDynamically(takesLegacyObject, nil));
+  }
+
+  // Test dynamically applying a legacy function of static type
+  // void Function(Never) in a null safe library, when called with
+  // a non-null value.
+  {
+    Expect.throwsTypeError(
+        () => applyTakesNeverDynamically(takesLegacyNull, 3));
+    applyTakesNeverDynamically(takesLegacyInt, 3);
+    Expect.throwsTypeError(
+        () => applyTakesNeverDynamically(takesLegacyInt, "hello"));
+    applyTakesNeverDynamically(takesLegacyObject, 3);
+  }
+}
+
+void main() {
+  never = null;
+  never = nil;
+  nil = never;
+  testNullSafeCalls();
+  testLegacyCalls();
+  testNullSafeApply();
+  testLegacyApply();
+  testNullSafeApplyDynamically();
+  testLegacyApplyDynamically();
+}
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart
index 8dee572..bffc4f9 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart
@@ -15,13 +15,17 @@
 
   // Valid: Invocation with all arguments provided.
   f("", p1: 100, p2: "", p3: true);
+  Function.apply(f, [""], {#p1: 100, #p2: "", #p3: true});
 
   // Valid: Invocation that omits non-required named arguments.
   f("", p1: 100, p2: "");
+  Function.apply(f, [""], {#p1: 100, #p2: ""});
 
   // Valid: Invocation may pass null as a required named argument.
   f("", p1: null, p2: null);
+  Function.apply(f, [""], {#p1: null, #p2: null});
 
   // Valid: Invocation may omit a required named argument.
   f("", p1: 100);
+  Function.apply(f, [""], {#p1: 100});
 }
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
index c066411..7139036 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
@@ -32,9 +32,15 @@
   Expect.throws(() {
     f("", p1: null, p2: null);
   });
+  Expect.throws(() {
+    Function.apply(f, [""], {#p1: null, #p2: null});
+  });
 
   // Invalid: Invocation that omits a required named argument.
   Expect.throws(() {
     f("", p1: 100);
   });
+  Expect.throws(() {
+    Function.apply(f, [""], {#p1: 100});
+  });
 }
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_test.dart
index c6c6f68..d19b0eb 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_test.dart
@@ -19,7 +19,9 @@
 
   // Valid: Invocation with all arguments provided.
   f("", p1: 100, p2: "", p3: true);
+  Function.apply(f, [""], {#p1: 100, #p2: "", #p3: true});
 
   // Valid: Invocation that omits non-required named arguments.
   f("", p1: 100, p2: "");
+  Function.apply(f, [""], {#p1: 100, #p2: ""});
 }
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart
index 5468b69..7d161e9 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart
@@ -26,7 +26,9 @@
 
   // Valid: Invocation may pass null as a required named argument in weak mode.
   f("", p1: null, p2: null);
+  Function.apply(f, [""], {#p1: null, #p2: null});
 
   // Valid: Invocation may omit a required named argument in weak mode.
   f("", p1: 100);
+  Function.apply(f, [""], {#p1: 100});
 }
diff --git a/tests/language/nnbd/resolution/issue41479_test.dart b/tests/language/nnbd/resolution/issue41479_test.dart
new file mode 100644
index 0000000..bf6f6cd
--- /dev/null
+++ b/tests/language/nnbd/resolution/issue41479_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+main() {
+  A a = A()..foo?.isEven;
+}
+
+class A {
+  int? get foo => 0;
+}
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 c4f6385..43472fd 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
@@ -19,7 +19,7 @@
 void f2(NotGeneric? x) {
   x?[0] + 1;
 //^^^^^
-// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
   x?[0] = 1;
   useNonNullable(x?[0] = 1);
@@ -46,14 +46,14 @@
 void f3<T extends num>(Generic<T>? x) {
   x?[0] + 1;
 //^^^^^
-// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
 }
 
 void f4<T extends num>(Generic<T?> x) {
   x[0] + 1;
 //^^^^
-// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.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 b050b2a..830c848 100644
--- a/tests/language/nnbd/resolution/question_question_lub_test.dart
+++ b/tests/language/nnbd/resolution/question_question_lub_test.dart
@@ -16,13 +16,13 @@
   (nullableInt ?? nonNullInt) + 1;
   (nullableInt ?? nullableInt) + 1;
 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
   (nonNullInt ?? nullableInt) + 1;
 //               ^^^^^^^^^^^
 // [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
 //^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
   (nonNullInt ?? nonNullInt) + 1;
 //               ^^^^^^^^^^
diff --git a/tests/language/nnbd/static_errors/default_list_constructor_test.dart b/tests/language/nnbd/static_errors/default_list_constructor_test.dart
index c15b01e..396a087 100644
--- a/tests/language/nnbd/static_errors/default_list_constructor_test.dart
+++ b/tests/language/nnbd/static_errors/default_list_constructor_test.dart
@@ -2,22 +2,35 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-experiment=non-nullable
-
-import 'opted_out_library.dart';
-
 // Test that it is an error to call the default List constructor.
 main() {
-  var a = new List<int>(3); //# 01: compile-time error
-  var b = new List<int?>(3); //# 02: compile-time-error
-  var c = new List<int>(); //# 03: compile-time error
-  var d = new List<int?>(); //# 04: compile-time error
-  List<C> c = new List(5); //# 05: compile-time error
-  consumeListOfStringStar(new List(3)); //# 06: compile-time error
+  var a = new List<int>(3);
+  //          ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
+  // [cfe] Can't use the default List constructor.
+  var b = new List<int?>(3);
+  //          ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
+  // [cfe] Can't use the default List constructor.
+  var c = new List<int>();
+  //          ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
+  // [cfe] Can't use the default List constructor.
+  var d = new List<int?>();
+  //          ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
+  // [cfe] Can't use the default List constructor.
+  List<C> e = new List(5);
+  //              ^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
+  // [cfe] Can't use the default List constructor.
 }
 
 class A<T> {
-  var l = new List<T>(3); //# 07: compile-time error
+  var l = new List<T>(3);
+  //          ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
+  // [cfe] Can't use the default List constructor.
 }
 
 class C {}
diff --git a/tests/language/nnbd/static_errors/nullable_in_on_clause_test.dart b/tests/language/nnbd/static_errors/nullable_in_on_clause_test.dart
deleted file mode 100644
index ac7db83..0000000
--- a/tests/language/nnbd/static_errors/nullable_in_on_clause_test.dart
+++ /dev/null
@@ -1,31 +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.
-
-// SharedOptions=--enable-experiment=non-nullable
-
-// Test that it is an error if the type `T` in the on-catch clause `on T catch`
-// is potentially nullable.
-import 'package:expect/expect.dart';
-import 'dart:core';
-import 'dart:core' as core;
-
-main() {
-  try {} catch (e) {}
-  try {} on A catch (e) {}
-  try {} on A? {} //# 01: compile-time error
-}
-
-class A {}
-
-class B<C> {
-  m() {
-    try {} on C {} //# 02: compile-time error
-  }
-}
-
-class D<E extends Object> {
-  m() {
-    try {} on E {}
-  }
-}
\ No newline at end of file
diff --git a/tests/language/nnbd/static_errors/opted_out_library.dart b/tests/language/nnbd/static_errors/opted_out_library.dart
deleted file mode 100644
index fefacf5..0000000
--- a/tests/language/nnbd/static_errors/opted_out_library.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-// @dart=2.3
-
-void consumeListOfStringStar(List<String> l) {}
diff --git a/tests/language/nnbd/static_errors/throw_of_invalid_type_test.dart b/tests/language/nnbd/static_errors/throw_of_invalid_type_test.dart
new file mode 100644
index 0000000..564a7b4
--- /dev/null
+++ b/tests/language/nnbd/static_errors/throw_of_invalid_type_test.dart
@@ -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 file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// Test that it is an error if the static type of `e` in the expression
+// `throw e` is not assignable to `Object`.
+import 'package:expect/expect.dart';
+
+main() {
+  f1(0);
+  f2(0);
+  f3();
+}
+
+void f1(int a) {
+  try {
+    throw a;
+  } catch (e) {}
+}
+
+void f2(int? a) {
+  try {
+    throw a; //# 01: compile-time error
+  } catch (e) {}
+}
+
+void f3() {
+  try {
+    throw null; //# 02: compile-time error
+  } catch (e) {}
+}
diff --git a/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart b/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart
index cee406f..4e23e5f 100644
--- a/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart
+++ b/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart
@@ -170,7 +170,7 @@
   dyn.toString(); //# 124: ok
   dyn.hashCode; //# 125: ok
   dyn.runtimeType; //# 126: ok
-  dyn.noSuchMethod(null); //# 127: ok
+  dyn.noSuchMethod(Invocation.method(#toString, [])); //# 127: ok
   dyn + 1; //# 128: ok
   -dyn; //# 129: ok
   dyn++; //# 130: ok
diff --git a/tests/language/nnbd/subtyping/regress41272_test.dart b/tests/language/nnbd/subtyping/regress41272_test.dart
new file mode 100644
index 0000000..2519404
--- /dev/null
+++ b/tests/language/nnbd/subtyping/regress41272_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization_counter_threshold=10 --deterministic
+// Requirements=nnbd-strong
+
+// Verifies that null cannot be casted to Object.
+// Regression test for https://github.com/dart-lang/sdk/issues/41272.
+
+import 'package:expect/expect.dart';
+
+doTest() {
+  dynamic x;
+  Expect.throwsTypeError(() {
+    x as Object;
+  });
+}
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    doTest();
+  }
+}
diff --git a/tests/language/nnbd/top_merge/top_merge_interfaces_direct_error_test.dart b/tests/language/nnbd/top_merge/top_merge_interfaces_direct_error_test.dart
new file mode 100644
index 0000000..311fe6e
--- /dev/null
+++ b/tests/language/nnbd/top_merge/top_merge_interfaces_direct_error_test.dart
@@ -0,0 +1,490 @@
+// 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';
+
+// Tests several aspects of the TOP_MERGE algorithm for merging super-interfaces.
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+T deconstruct<T>(A<T> x) => throw "Unreachable";
+
+void takesObject(Object x) {}
+
+class D0 extends A<dynamic> implements B<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D1 extends A<Object?> implements B<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D2 extends A<void> implements B<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D3 extends A<Object?> implements B<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D4 extends A<void> implements B<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D5 extends A<dynamic> implements B<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D6 extends A<void> implements B<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object?>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D7 extends A<dynamic> implements B<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we implement A<dynamic>
+  }
+}
+
+// Test the same examples with top level normalization
+
+class ND0 extends A<FutureOr<dynamic>> implements B<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND1 extends A<FutureOr<Object?>> implements B<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND2 extends A<FutureOr<void>> implements B<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND3 extends A<FutureOr<Object?>> implements B<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND4 extends A<FutureOr<void>> implements B<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND5 extends A<FutureOr<dynamic>> implements B<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND6 extends A<FutureOr<void>> implements B<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object?>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND7 extends A<FutureOr<dynamic>> implements B<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we implement A<dynamic>
+  }
+}
+
+// Test the same examples with deep normalization
+
+class DND0 extends A<FutureOr<dynamic> Function()>
+    implements B<Object? Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND1 extends A<FutureOr<Object?> Function()>
+    implements B<dynamic Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND2 extends A<FutureOr<void> Function()>
+    implements B<Object? Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND3 extends A<FutureOr<Object?> Function()>
+    implements B<void Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND4 extends A<FutureOr<void> Function()>
+    implements B<dynamic Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND5 extends A<FutureOr<dynamic> Function()>
+    implements B<void Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND6 extends A<FutureOr<void> Function()> implements B<void Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object? Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND7 extends A<FutureOr<dynamic> Function()>
+    implements B<dynamic Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we implement A<dynamic Function()>
+  }
+}
+
+// Test the same examples with deep normalization + typedefs
+
+typedef Wrap<T> = FutureOr<T>? Function();
+
+class WND0 extends A<Wrap<FutureOr<dynamic>>> implements B<Wrap<Object?>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND1 extends A<Wrap<FutureOr<Object?>>> implements B<Wrap<dynamic>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND2 extends A<Wrap<FutureOr<void>>> implements B<Wrap<Object?>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND3 extends A<Wrap<FutureOr<Object?>>> implements B<Wrap<void>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND4 extends A<Wrap<FutureOr<void>>> implements B<Wrap<dynamic>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND5 extends A<Wrap<FutureOr<dynamic>>> implements B<Wrap<void>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND6 extends A<Wrap<FutureOr<void>>> implements B<Wrap<void>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object? Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND7 extends A<Wrap<FutureOr<dynamic>>> implements B<Wrap<dynamic>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we implement A<dynamic Function()>
+  }
+}
diff --git a/tests/language/nnbd/top_merge/top_merge_interfaces_mixin_error_test.dart b/tests/language/nnbd/top_merge/top_merge_interfaces_mixin_error_test.dart
new file mode 100644
index 0000000..e7241c5
--- /dev/null
+++ b/tests/language/nnbd/top_merge/top_merge_interfaces_mixin_error_test.dart
@@ -0,0 +1,483 @@
+// 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';
+
+// Tests several aspects of the TOP_MERGE algorithm for merging super-interfaces.
+
+class A<T> {}
+
+mixin M<T> implements A<T> {}
+
+T deconstruct<T>(A<T> x) => throw "Unreachable";
+
+void takesObject(Object x) {}
+
+class D0 extends A<dynamic> with M<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D1 extends A<Object?> with M<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D2 extends A<void> with M<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D3 extends A<Object?> with M<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D4 extends A<void> with M<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D5 extends A<dynamic> with M<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D6 extends A<void> with M<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object?>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D7 extends A<dynamic> with M<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we implement A<dynamic>
+  }
+}
+
+// Test the same examples with top level normalization
+
+class ND0 extends A<FutureOr<dynamic>> with M<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND1 extends A<FutureOr<Object?>> with M<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND2 extends A<FutureOr<void>> with M<Object?> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND3 extends A<FutureOr<Object?>> with M<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND4 extends A<FutureOr<void>> with M<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND5 extends A<FutureOr<dynamic>> with M<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void>
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND6 extends A<FutureOr<void>> with M<void> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we do not implement A<dynamic>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object?>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND7 extends A<FutureOr<dynamic>> with M<dynamic> {
+  void test() {
+    var x = deconstruct(this);
+    x.foo; // Check that we implement A<dynamic>
+  }
+}
+
+// Test the same examples with deep normalization
+
+class DND0 extends A<FutureOr<dynamic> Function()> with M<Object? Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND1 extends A<FutureOr<Object?> Function()> with M<dynamic Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND2 extends A<FutureOr<void> Function()> with M<Object? Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND3 extends A<FutureOr<Object?> Function()> with M<void Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND4 extends A<FutureOr<void> Function()> with M<dynamic Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND5 extends A<FutureOr<dynamic> Function()> with M<void Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND6 extends A<FutureOr<void> Function()> with M<void Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object? Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND7 extends A<FutureOr<dynamic> Function()> with M<dynamic Function()> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we implement A<dynamic Function()>
+  }
+}
+
+// Test the same examples with deep normalization + typedefs
+
+typedef Wrap<T> = FutureOr<T>? Function();
+
+class WND0 extends A<Wrap<FutureOr<dynamic>>> with M<Wrap<Object?>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND1 extends A<Wrap<FutureOr<Object?>>> with M<Wrap<dynamic>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND2 extends A<Wrap<FutureOr<void>>> with M<Wrap<Object?>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND3 extends A<Wrap<FutureOr<Object?>>> with M<Wrap<void>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND4 extends A<Wrap<FutureOr<void>>> with M<Wrap<dynamic>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND5 extends A<Wrap<FutureOr<dynamic>>> with M<Wrap<void>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<void Function()>
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND6 extends A<Wrap<FutureOr<void>>> with M<Wrap<void>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we do not implement A<dynamic Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that we do not implement A<Object? Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that we do not implement A<Object Function()>
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND7 extends A<Wrap<FutureOr<dynamic>>> with M<Wrap<dynamic>> {
+  void test() {
+    var x = deconstruct(this)();
+    x.foo; // Check that we implement A<dynamic Function()>
+  }
+}
diff --git a/tests/language/nnbd/top_merge/top_merge_members_direct_error_test.dart b/tests/language/nnbd/top_merge/top_merge_members_direct_error_test.dart
new file mode 100644
index 0000000..79beb98
--- /dev/null
+++ b/tests/language/nnbd/top_merge/top_merge_members_direct_error_test.dart
@@ -0,0 +1,528 @@
+// 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';
+
+// Tests several aspects of the TOP_MERGE algorithm for merging members
+
+class A<T> {
+  T member() {
+    throw "Unreachable";
+  }
+}
+
+class B<T> {
+  T member() {
+    throw "Unreachable";
+  }
+}
+
+void takesObject(Object x) {}
+
+class D0 extends A<dynamic> implements B<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D1 extends A<Object?> implements B<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D2 extends A<void> implements B<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D3 extends A<Object?> implements B<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D4 extends A<void> implements B<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D5 extends A<dynamic> implements B<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D6 extends A<void> implements B<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return Object?
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D7 extends A<dynamic> implements B<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns dynamic
+  }
+}
+
+// Test the same examples with top level normalization
+
+class ND0 extends A<FutureOr<dynamic>> implements B<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND1 extends A<FutureOr<Object?>> implements B<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND2 extends A<FutureOr<void>> implements B<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND3 extends A<FutureOr<Object?>> implements B<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND4 extends A<FutureOr<void>> implements B<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND5 extends A<FutureOr<dynamic>> implements B<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND6 extends A<FutureOr<void>> implements B<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return dynamic
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return Object?
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return Object
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND7 extends A<FutureOr<dynamic>> implements B<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns dynamic
+  }
+}
+
+// Test the same examples with deep normalization
+
+class DND0 extends A<FutureOr<dynamic> Function()>
+    implements B<Object? Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND1 extends A<FutureOr<Object?> Function()>
+    implements B<dynamic Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND2 extends A<FutureOr<void> Function()>
+    implements B<Object? Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND3 extends A<FutureOr<Object?> Function()>
+    implements B<void Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND4 extends A<FutureOr<void> Function()>
+    implements B<dynamic Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND5 extends A<FutureOr<dynamic> Function()>
+    implements B<void Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND6 extends A<FutureOr<void> Function()> implements B<void Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return Object? Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND7 extends A<FutureOr<dynamic> Function()>
+    implements B<dynamic Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns dynamic Function()
+  }
+}
+
+// Test the same examples with deep normalization + typedefs
+
+typedef Wrap<T> = FutureOr<T>? Function();
+
+class WND0 extends A<Wrap<FutureOr<dynamic>>> implements B<Wrap<Object?>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND1 extends A<Wrap<FutureOr<Object?>>> implements B<Wrap<dynamic>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND2 extends A<Wrap<FutureOr<void>>> implements B<Wrap<Object?>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND3 extends A<Wrap<FutureOr<Object?>>> implements B<Wrap<void>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND4 extends A<Wrap<FutureOr<void>>> implements B<Wrap<dynamic>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND5 extends A<Wrap<FutureOr<dynamic>>> implements B<Wrap<void>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return void Function()
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND6 extends A<Wrap<FutureOr<void>>> implements B<Wrap<void>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return dynamic Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return Object? Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return Object Function()
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND7 extends A<Wrap<FutureOr<dynamic>>> implements B<Wrap<dynamic>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns dynamic Function()
+  }
+}
diff --git a/tests/language/nnbd/top_merge/top_merge_members_mixin_error_test.dart b/tests/language/nnbd/top_merge/top_merge_members_mixin_error_test.dart
new file mode 100644
index 0000000..4be0ef7
--- /dev/null
+++ b/tests/language/nnbd/top_merge/top_merge_members_mixin_error_test.dart
@@ -0,0 +1,504 @@
+// 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';
+
+// Tests several aspects of the TOP_MERGE algorithm for merging super-interfaces.
+// This tests that TOP_MERGE is not applied when a mixin causes an override.
+// Instead, the signature of the mixed in method should apply.
+
+class A<T> {
+  T member() {
+    throw "Unreachable";
+  }
+}
+
+mixin M<T> {
+  T member() {
+    throw "Unreachable";
+  }
+}
+
+void takesObject(Object x) {}
+
+class D0 extends A<dynamic> with M<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D1 extends A<Object?> with M<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class D2 extends A<void> with M<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D3 extends A<Object?> with M<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D4 extends A<void> with M<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class D5 extends A<dynamic> with M<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D6 extends A<void> with M<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D7 extends A<dynamic> with M<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+// Test the same examples with top level normalization
+
+class ND0 extends A<FutureOr<dynamic>> with M<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND1 extends A<FutureOr<Object?>> with M<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class ND2 extends A<FutureOr<void>> with M<Object?> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND3 extends A<FutureOr<Object?>> with M<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND4 extends A<FutureOr<void>> with M<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class ND5 extends A<FutureOr<dynamic>> with M<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND6 extends A<FutureOr<void>> with M<void> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND7 extends A<FutureOr<dynamic>> with M<dynamic> {
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+// Test the same examples with deep normalization
+
+class DND0 extends A<FutureOr<dynamic> Function()> with M<Object? Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND1 extends A<FutureOr<Object?> Function()> with M<dynamic Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns `dynamic Function()`
+  }
+}
+
+class DND2 extends A<FutureOr<void> Function()> with M<Object? Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND3 extends A<FutureOr<Object?> Function()> with M<void Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object? Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND4 extends A<FutureOr<void> Function()> with M<dynamic Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns `dynamic Function()`
+  }
+}
+
+class DND5 extends A<FutureOr<dynamic> Function()> with M<void Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object? Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND6 extends A<FutureOr<void> Function()> with M<void Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object? Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND7 extends A<FutureOr<dynamic> Function()> with M<dynamic Function()> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns `dynamic Function()`
+  }
+}
+
+// Test the same examples with deep normalization + typedefs
+
+// With all mixin examples, no normalization is specified, and so
+// all errors and warnings should look like the `Object?` errors and
+// warnings (we don't distinguish between the method sets on `Object?`
+// and `FutureOr<T>` for any `T`).
+
+typedef Wrap<T> = FutureOr<T>? Function();
+
+class WND0 extends A<Wrap<FutureOr<dynamic>>> with M<Wrap<Object?>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND1 extends A<Wrap<FutureOr<Object?>>> with M<Wrap<dynamic>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND2 extends A<Wrap<FutureOr<void>>> with M<Wrap<Object?>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND3 extends A<Wrap<FutureOr<Object?>>> with M<Wrap<void>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND4 extends A<Wrap<FutureOr<void>>> with M<Wrap<dynamic>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND5 extends A<Wrap<FutureOr<dynamic>>> with M<Wrap<void>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND6 extends A<Wrap<FutureOr<void>>> with M<Wrap<void>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND7 extends A<Wrap<FutureOr<dynamic>>> with M<Wrap<dynamic>> {
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
diff --git a/tests/language/nnbd/top_merge/top_merge_members_override_error_test.dart b/tests/language/nnbd/top_merge/top_merge_members_override_error_test.dart
new file mode 100644
index 0000000..85a5efb
--- /dev/null
+++ b/tests/language/nnbd/top_merge/top_merge_members_override_error_test.dart
@@ -0,0 +1,626 @@
+// 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';
+
+// Tests several aspects of the TOP_MERGE algorithm for merging super-interfaces.
+// This tests that TOP_MERGE is not applied when a class directly overrides a
+// method. Instead, the signature of the overriding method should apply.
+
+class A<T> {
+  T member() {
+    throw "Unreachable";
+  }
+}
+
+void takesObject(Object x) {}
+
+class D0 extends A<dynamic> {
+  Object? member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D1 extends A<Object?> {
+  dynamic member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class D2 extends A<void> {
+  Object? member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D3 extends A<Object?> {
+  void member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D4 extends A<void> {
+  dynamic member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class D5 extends A<dynamic> {
+  void member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D6 extends A<void> {
+  void member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class D7 extends A<dynamic> {
+  dynamic member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+// Test the same examples with top level normalization
+
+class ND0 extends A<FutureOr<dynamic>> {
+  Object? member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND1 extends A<FutureOr<Object?>> {
+  dynamic member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class ND2 extends A<FutureOr<void>> {
+  Object? member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void`
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND3 extends A<FutureOr<Object?>> {
+  void member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND4 extends A<FutureOr<void>> {
+  dynamic member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+class ND5 extends A<FutureOr<dynamic>> {
+  void member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND6 extends A<FutureOr<void>> {
+  void member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member does not return `dynamic`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object?`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class ND7 extends A<FutureOr<dynamic>> {
+  dynamic member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member();
+    x.foo; // Check that member returns `dynamic`
+  }
+}
+
+// Test the same examples with deep normalization
+
+class DND0 extends A<FutureOr<dynamic> Function()> {
+  Object? Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND1 extends A<FutureOr<Object?> Function()> {
+  dynamic Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns `dynamic Function()`
+  }
+}
+
+class DND2 extends A<FutureOr<void> Function()> {
+  Object? Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND3 extends A<FutureOr<Object?> Function()> {
+  void Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object? Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND4 extends A<FutureOr<void> Function()> {
+  dynamic Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns `dynamic Function()`
+  }
+}
+
+class DND5 extends A<FutureOr<dynamic> Function()> {
+  void Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object? Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND6 extends A<FutureOr<void> Function()> {
+  void Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `Object? Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class DND7 extends A<FutureOr<dynamic> Function()> {
+  dynamic Function() member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member returns `dynamic Function()`
+  }
+}
+
+// Test the same examples with deep normalization + typedefs
+
+// With all override examples, no normalization is specified, and so
+// all errors and warnings should look like the `Object?` errors and
+// warnings (we don't distinguish between the method sets on `Object?`
+// and `FutureOr<T>` for any `T`).
+
+typedef Wrap<T> = FutureOr<T>? Function();
+
+class WND0 extends A<Wrap<FutureOr<dynamic>>> {
+  Wrap<FutureOr<Object?>> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND1 extends A<Wrap<FutureOr<Object?>>> {
+  Wrap<dynamic> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND2 extends A<Wrap<FutureOr<void>>> {
+  Wrap<Object?> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND3 extends A<Wrap<FutureOr<Object?>>> {
+  Wrap<void> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND4 extends A<Wrap<FutureOr<void>>> {
+  Wrap<dynamic> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND5 extends A<Wrap<FutureOr<dynamic>>> {
+  Wrap<void> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND6 extends A<Wrap<FutureOr<void>>> {
+  Wrap<void> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
+
+class WND7 extends A<Wrap<FutureOr<dynamic>>> {
+  Wrap<dynamic> member() {
+    throw "Unreachable";
+  }
+
+  void test() {
+    var self = this;
+    var x = self.member()();
+    x.foo; // Check that member does not return `dynamic Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+    x.toString; // Check that member does not return `void Function()`
+    takesObject(x); // Check that member does not return `Object Function()`
+    //   ^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
diff --git a/tests/language/nnbd/try_catch/default_catch_type_error_test.dart b/tests/language/nnbd/try_catch/default_catch_type_error_test.dart
new file mode 100644
index 0000000..73b3b94
--- /dev/null
+++ b/tests/language/nnbd/try_catch/default_catch_type_error_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  try {} catch (error) {
+    error.notAMethodOnObject();
+    //    ^^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_METHOD
+    // [cfe] The method 'notAMethodOnObject' isn't defined for the class 'Object'.
+    _takesObject(error);
+  }
+}
+
+void _takesObject(Object o) {}
diff --git a/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart b/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
index a9a546f..dd1df88 100644
--- a/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
+++ b/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
@@ -5,7 +5,7 @@
 // SharedOptions=--enable-experiment=non-nullable
 
 void f(Object x) {
-  void Function() g;
+  late void Function() g;
 
   if (x is String) {
     x.length;
diff --git a/tests/language/nnbd/type_promotion/promoted_lhs_used_as_assignment_context_test.dart b/tests/language/nnbd/type_promotion/promoted_lhs_used_as_assignment_context_test.dart
new file mode 100644
index 0000000..245ec8b
--- /dev/null
+++ b/tests/language/nnbd/type_promotion/promoted_lhs_used_as_assignment_context_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+import 'package:expect/expect.dart';
+
+void f(Object x) {
+  if (x is double) {
+    // The context for the RHS of the assignment should be `double`, so the `1`
+    // should be converted to `1.0`, and thus `x` should remain promoted and
+    // the call to `g` should be statically ok.
+    x = 1;
+    g(x);
+    // Furthermore, at runtime, the value of x should be a double.
+    Expect.isTrue(x is double);
+    // However, the context is only advisory; it is still ok to assign a
+    // non-double (un-doing the promotion).
+    x = 'foo';
+    Expect.isTrue(x is String);
+  }
+}
+
+void g(double x) {}
+
+main() {
+  f(1.0);
+}
diff --git a/tests/language/operator/invalid_operators_test.dart b/tests/language/operator/invalid_operators_test.dart
index 5faf742..4e90b5b 100644
--- a/tests/language/operator/invalid_operators_test.dart
+++ b/tests/language/operator/invalid_operators_test.dart
@@ -162,7 +162,7 @@
 
 class Operators3 {
   operator ==([dynamic a]) => true;
-  //           ^
+  //           ^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
   //                   ^
   // [cfe] An operator can't have optional parameters.
diff --git a/tests/language/regress/regress40765_test.dart b/tests/language/regress/regress40765_test.dart
new file mode 100644
index 0000000..175be2d
--- /dev/null
+++ b/tests/language/regress/regress40765_test.dart
@@ -0,0 +1,42 @@
+// 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 Something {
+  final int x;
+  Something({required this.x});
+}
+
+abstract class Base {
+  Something get x;
+}
+
+class Child1 extends Base {
+  final Something x;
+  Child1({required this.x});
+}
+
+class Child2 extends Base {
+  final int y;
+  final Something x;
+  Child2({required this.x, required this.y});
+}
+
+@pragma('vm:never-inline')
+int foo(int k, Base x) {
+  var y = 0;
+  for (var i = 0; i < k; i++) {
+    x as Child1;
+    // Next line will be hoisted out as x.{Child1::x}.{Something::x}
+    // and at foo(0, Child2(..., y: 24)) will end up executing as
+    // x.{Child1::x} -> will load Child2::y (24) and then segfault.
+    y = x.x.x;
+  }
+  return y;
+}
+
+void main() {
+  print(foo(1, Child1(x: Something(x: 1))));
+  print(foo(1, Child1(x: Something(x: 2))));
+  print(foo(0, Child2(x: Something(x: 42), y: 24)));
+}
diff --git a/tests/language/regress/regress41613_test.dart b/tests/language/regress/regress41613_test.dart
new file mode 100644
index 0000000..0ea1de0
--- /dev/null
+++ b/tests/language/regress/regress41613_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.7
+
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+main() {
+  // In legacy Dart 2 and null safety weak mode the error handlers can
+  // return null.
+  Expect.equals(null, int.parse("foo", onError: (_) => null));
+  Expect.equals(null, double.parse("foo", (_) => null));
+}
diff --git a/tests/language/void/await_void_error_test.dart b/tests/language/void/await_void_error_test.dart
new file mode 100644
index 0000000..94b902b
--- /dev/null
+++ b/tests/language/void/await_void_error_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that it is an error to await an expression of type `void`.
+
+import "dart:async";
+
+void v;
+List<void> vs = [null];
+FutureOr<void> fov;
+
+void main() async {
+  await print('');
+  //    ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  await v;
+  //    ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  await vs[0];
+  //    ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  var v2 = vs[0];
+  await v2;
+  //    ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // A `FutureOr<void>` can be awaited.
+  await fov;
+}
diff --git a/tests/language_2/async/return_types_test.dart b/tests/language_2/async/return_types_test.dart
index 473150f..4ecd5b4 100644
--- a/tests/language_2/async/return_types_test.dart
+++ b/tests/language_2/async/return_types_test.dart
@@ -19,7 +19,7 @@
   return "String";
   //     ^^^^^^^^
   // [analyzer] STATIC_TYPE_WARNING.RETURN_OF_INVALID_TYPE
-  // [cfe] A value of type 'String' can't be assigned to a variable of type 'FutureOr<int>'.
+  // [cfe] A value of type 'Future<String>' can't be assigned to a variable of type 'FutureOr<int>'.
 }
 
 Future<int, String>
@@ -27,22 +27,16 @@
 // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS
 // [cfe] Expected 1 type arguments.
 foo4() async {
-// [error line 29, column 1]
-// [cfe] Functions marked 'async' must have a return type assignable to 'Future'.
   return "String";
-  //     ^
-  // [cfe] A value of type 'String' can't be assigned to a variable of type 'FutureOr<invalid-type>'.
 }
 
 int
-// [error line 37, column 1, length 3]
+// [error line 33, column 1, length 3]
 // [analyzer] STATIC_TYPE_WARNING.ILLEGAL_ASYNC_RETURN_TYPE
 foo5() async {
-// [error line 40, column 1]
+// [error line 36, column 1]
 // [cfe] Functions marked 'async' must have a return type assignable to 'Future'.
   return 3;
-  //     ^
-  // [analyzer] STATIC_TYPE_WARNING.RETURN_OF_INVALID_TYPE
 }
 
 Future<int> foo6() async {
diff --git a/tests/language_2/const/inference_test.dart b/tests/language_2/const/inference_test.dart
index 2e556bf..b925f20 100644
--- a/tests/language_2/const/inference_test.dart
+++ b/tests/language_2/const/inference_test.dart
@@ -122,10 +122,10 @@
   expectOfType<Null Function(Object)>(getFunction());
 }
 
-/// Tests that type inference for constants does not reference the type
-/// parameter. Instead, free type parameters should substituted to obtain the
+/// Tests that use type inference for constants do not reference the type
+/// parameter. Instead, free type parameters are substituted to obtain the
 /// least closure (e.g. `List<T>` becomes `List<Null>` and `R Function(T)`
-/// becomes `Null Function(Object)`).
+/// becomes `Null Function(Object?)`).
 main() {
   testClassInstance();
   testImplicitConstClassInstance();
diff --git a/tests/language_2/const/runtime_test.dart b/tests/language_2/const/runtime_test.dart
deleted file mode 100644
index bb84f01..0000000
--- a/tests/language_2/const/runtime_test.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// TODO(multitest): This was automatically migrated from a multitest and may
-// contain strange or dead code.
-
-// 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.
-
-class C {
-  factory C() => null;
-}
-
-
-t() => null;
-
-
-get v => null;
-
-main() {
-
-      dynamic x = t();
-
-
-      dynamic z = v;
-}
diff --git a/tests/language_2/control_flow_collections/await_for_null_test.dart b/tests/language_2/control_flow_collections/await_for_null_test.dart
index f1c1460..b176ea0 100644
--- a/tests/language_2/control_flow_collections/await_for_null_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_null_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test that a null stream expression procudes a runtime error.
+// Test that a null stream expression produces a runtime error.
 import 'package:async_helper/async_helper.dart';
 
 void main() {
diff --git a/tests/language_2/covariant/tear_off_type_test.dart b/tests/language_2/covariant/tear_off_type_test.dart
index c3a848c..ba52670e 100644
--- a/tests/language_2/covariant/tear_off_type_test.dart
+++ b/tests/language_2/covariant/tear_off_type_test.dart
@@ -16,10 +16,10 @@
 
 void main() {
   var tearoff = g(new C<int>());
-  // Since C.f's x parameter is covariant, its type is changed to Object when
+  // Since C.f's x parameter is covariant, its type is changed to `Object?` when
   // determining the type of the tearoff.  So the type of the tearoff should be
-  // `(Object) -> int`.  (Not, for example, `(List<Object>) -> int` or
-  // `(List<Object>) -> Object`)
+  // `(Object?) -> int`.  (Not, for example, `(List<Object?>) -> int` or
+  // `(List<Object?>) -> Object?`)
   Expect.isTrue(tearoff is F<Object, int>);
   // Because the function accepts any object, we can pass strings to it.  This
   // will not work in Dart 1.
diff --git a/tests/language_2/double/to_string_as_fixed2_test.dart b/tests/language_2/double/to_string_as_fixed2_test.dart
index bc76e63..3040a30 100644
--- a/tests/language_2/double/to_string_as_fixed2_test.dart
+++ b/tests/language_2/double/to_string_as_fixed2_test.dart
@@ -3,6 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test basic integer operations.
 
+// [NNBD non-migrated]: This test has no language/ counterpart. The static
+// errors are just redundant tests of the static type system, and the runtime
+// errors are redundant with to_string_as_fixed2_runtime_test.dart.
+
 import "package:expect/expect.dart";
 
 main() {
diff --git a/tests/language_2/double/to_string_as_precision2_test.dart b/tests/language_2/double/to_string_as_precision2_test.dart
index e69d0c9..4ce0c34 100644
--- a/tests/language_2/double/to_string_as_precision2_test.dart
+++ b/tests/language_2/double/to_string_as_precision2_test.dart
@@ -3,6 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test basic integer operations.
 
+// [NNBD non-migrated]: This test has no language/ counterpart. The static
+// errors are just redundant tests of the static type system, and the runtime
+// errors are redundant with to_string_as_precision2_runtime_test.dart.
+
 import "package:expect/expect.dart";
 
 main() {
diff --git a/tests/language_2/dynamic/prefix_core_test.dart b/tests/language_2/dynamic/prefix_core_test.dart
index 7823543..65da032 100644
--- a/tests/language_2/dynamic/prefix_core_test.dart
+++ b/tests/language_2/dynamic/prefix_core_test.dart
@@ -9,10 +9,10 @@
 import "dart:core" as mycore;
 
 void main() {
-  // Should still be available because it is not a member of dart:core.
-  Expect.isTrue(dynamic is mycore.Type);
+  // The built-in type declaration `dynamic`, which is declared in the
+  // library `dart:core`, denotes the `dynamic` type. So, in this library
+  // it must be reference with the prefix.
+  dynamic; //# 01: compile-time error
 
-  Expect.throws(() => mycore.dynamic is mycore.Type, //    //# 01: compile-time error
-                (e) => e is mycore.NoSuchMethodError, //   //# 01: continued
-                'dynamic is not a member of dart:core'); //# 01: continued
+  Expect.isTrue(mycore.dynamic is mycore.Type); //# 02: ok
 }
diff --git a/tests/language_2/extension_methods/static_extension_constant_error_test.dart b/tests/language_2/extension_methods/static_extension_constant_error_test.dart
new file mode 100644
index 0000000..e7a0d0c
--- /dev/null
+++ b/tests/language_2/extension_methods/static_extension_constant_error_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'static_extension_constant_lib.dart';
+
+// Tests that it is an error to invoke an extension method during constant
+// expression evaluation. The expressions should be the same as those in
+// `runtimeExtensionCalls`, so that it is verified that each of them will
+// invoke an extension method.
+
+void main() {
+  // The initializing expressions should be identical to the elements in
+  // `runtimeExtensionCalls`.
+
+  const c01 = ~i;
+  //          ^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c02 = b & b;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c03 = b | b;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c04 = b ^ b;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c05 = i ~/ i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c06 = i >> i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c08 = i << i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c09 = i + i;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c10 = -i;
+  //          ^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c11 = d - d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c12 = d * d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c13 = d / d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c14 = d % d;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c15 = d < i;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c16 = i <= d;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c17 = d > i;
+  //          ^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c18 = i >= i;
+  //          ^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+  const c19 = s.length;
+  //          ^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
diff --git a/tests/language_2/extension_methods/static_extension_constant_lib.dart b/tests/language_2/extension_methods/static_extension_constant_lib.dart
new file mode 100644
index 0000000..23d6de9
--- /dev/null
+++ b/tests/language_2/extension_methods/static_extension_constant_lib.dart
@@ -0,0 +1,55 @@
+// 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.
+
+extension ExtendObject on Object {
+  int operator ~() => 1;
+  bool operator &(Object other) => false;
+  bool operator |(Object other) => false;
+  bool operator ^(Object other) => true;
+  int operator ~/(Object other) => 0;
+  int operator >>(Object other) => 1;
+  // int operator >>>(Object other) => 2; // Requires triple-shift.
+  int operator <<(Object other) => 0;
+  int operator +(Object other) => 0;
+  double operator -() => 1.0;
+  double operator -(Object other) => 1.0;
+  double operator *(Object other) => 1.0;
+  double operator /(Object other) => 2.0;
+  double operator %(Object other) => 1.0;
+  bool operator <(Object other) => false;
+  bool operator <=(Object other) => true;
+  bool operator >(Object other) => true;
+  bool operator >=(Object other) => false;
+  int get length => 1;
+}
+
+const Object b = true;
+const Object i = 3;
+const Object d = 2.4;
+const Object s = 'Hello!';
+
+// These expressions should be identical to the ones in
+// static_extension_constant_{,error}_test.dart, to ensure that
+// they invoke an extension method, and that this is an error.
+var runtimeExtensionCalls = <Object>[
+  ~i,
+  b & b,
+  b | b,
+  b ^ b,
+  i ~/ i,
+  i >> i,
+  // i >>> i, // Requries triple-shift.
+  i << i,
+  i + i,
+  -i,
+  d - d,
+  d * d,
+  d / d,
+  d % d,
+  d < i,
+  i <= d,
+  d > i,
+  i >= i,
+  s.length,
+];
diff --git a/tests/language_2/extension_methods/static_extension_constant_test.dart b/tests/language_2/extension_methods/static_extension_constant_test.dart
new file mode 100644
index 0000000..1295d4a
--- /dev/null
+++ b/tests/language_2/extension_methods/static_extension_constant_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+import 'static_extension_constant_lib.dart' hide b, i, d, s;
+import 'static_extension_constant_lib.dart' as lib show b, i, d, s;
+
+// Ensure that all expressions in runtimeExtensionCalls invoke
+// an extension method rather than an instance method, such that
+// static_extension_constant_error_test gets an error for them all.
+
+const dynamic b = lib.b;
+const dynamic i = lib.i;
+const dynamic d = lib.d;
+const dynamic s = lib.s;
+
+// These expressions should be identical to those in
+// `lib.runtimeExtensionCalls`.
+var dynamicInstanceCalls = <Object>[
+  ~i,
+  b & b,
+  b | b,
+  b ^ b,
+  i ~/ i,
+  i >> i,
+  // i >>> i, // Requries triple-shift.
+  i << i,
+  i + i,
+  -i,
+  d - d,
+  d * d,
+  d / d,
+  d % d,
+  d < i,
+  i <= d,
+  d > i,
+  i >= i,
+  s.length,
+];
+
+void main() {
+  for (int i = 0; i < dynamicInstanceCalls.length; ++i) {
+    Expect.notEquals(dynamicInstanceCalls[i], runtimeExtensionCalls[i]);
+  }
+}
diff --git a/tests/language_2/function/type_alias9_test.dart b/tests/language_2/function/type_alias9_test.dart
index d7e4c1f..fa15400 100644
--- a/tests/language_2/function/type_alias9_test.dart
+++ b/tests/language_2/function/type_alias9_test.dart
@@ -14,7 +14,5 @@
 
 main() {
   F foo(G g) => g;
-  //            ^
-  // [cfe] A value of type 'void Function(List<invalid-type>)' can't be assigned to a variable of type 'void Function(List<void Function(List<invalid-type>)>)'.
   foo(null);
 }
diff --git a/tests/language_2/function_subtype/regress41680_test.dart b/tests/language_2/function_subtype/regress41680_test.dart
new file mode 100644
index 0000000..e4d689d
--- /dev/null
+++ b/tests/language_2/function_subtype/regress41680_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+typedef dynamicToDynamic = dynamic Function(dynamic);
+
+typedef voidToT = T Function<T>();
+
+dynamic dynamicNull = null;
+
+dynamic cast<T>(dynamic value) => value as T;
+
+bool allowsArgument(T Function<T>() fn) => true;
+
+main() {
+  // In legacy Dart 2 Null should be allowed as a subtype of function types.
+  Expect.equals(null, dynamicNull as Function);
+  Expect.equals(null, dynamicNull as dynamicToDynamic);
+  Expect.equals(null, cast<dynamic Function(dynamic)>(dynamicNull));
+  Expect.equals(null, dynamicNull as voidToT);
+  Expect.equals(true, allowsArgument(dynamicNull));
+}
diff --git a/tests/language_2/interface/interface_test.dart b/tests/language_2/interface/interface_test.dart
index 5ffd3d4..b05e0a6 100644
--- a/tests/language_2/interface/interface_test.dart
+++ b/tests/language_2/interface/interface_test.dart
@@ -11,6 +11,8 @@
   factory Bi() = InterfaceTest;
   //      ^
   // [cfe] Factory redirects to class 'InterfaceTest', which is abstract and can't be instantiated.
+  //             ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR
 }
 
 abstract class Simple implements Ai {}
diff --git a/tests/language_2/mixin/invalid_override_in_mixin_test.dart b/tests/language_2/mixin/invalid_override_in_mixin_test.dart
index b8edfea..bd79f66 100644
--- a/tests/language_2/mixin/invalid_override_in_mixin_test.dart
+++ b/tests/language_2/mixin/invalid_override_in_mixin_test.dart
@@ -13,7 +13,6 @@
 
 class C extends Object with A {
 //    ^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'A' to 'Object' introduces an erroneous override of 'noSuchMethod'.
 //    ^
 // [cfe] Class 'Object with A' inherits multiple members named 'noSuchMethod' with incompatible signatures.
diff --git a/tests/language_2/mixin/method_override_test.dart b/tests/language_2/mixin/method_override_test.dart
index 3b8e104..3987455 100644
--- a/tests/language_2/mixin/method_override_test.dart
+++ b/tests/language_2/mixin/method_override_test.dart
@@ -22,7 +22,6 @@
 // Wrong return type.
 abstract class C1 = CII with CIS;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'C1' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'C1' introduces an erroneous override of 'id'.
@@ -30,7 +29,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class C2 extends CII with CIS {}
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'CIS' to 'CII' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'CII with CIS' inherits multiple members named 'id' with incompatible signatures.
@@ -41,7 +39,6 @@
 // Wrong argument type.
 abstract class C3 = CII with CSI;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'C3' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'C3' introduces an erroneous override of 'id'.
@@ -49,7 +46,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class C4 extends CII with CSI {}
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'CSI' to 'CII' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'CII with CSI' inherits multiple members named 'id' with incompatible signatures.
@@ -61,7 +57,6 @@
 abstract class C6 extends CII with CTT<int> {}
 abstract class C7  = CII with CTT<String>;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'C7' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'C7' introduces an erroneous override of 'id'.
@@ -69,7 +64,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class C8 extends CII with CTT<String> {}
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'CTT' to 'CII' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'CII with CTT<String>' inherits multiple members named 'id' with incompatible signatures.
@@ -99,7 +93,6 @@
 // It's NOT OK to rename named parameters.
 abstract class N3 = NIIx with NIIy;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'N3' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'N3' introduces an erroneous override of 'id'.
@@ -107,7 +100,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N4 extends NIIx with NIIy {}
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'NIIy' to 'NIIx' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'NIIx with NIIy' inherits multiple members named 'id' with incompatible signatures.
@@ -118,7 +110,6 @@
 // It's NOT OK to drop named parameters.
 abstract class N5 = NIIx with NII;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'N5' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'N5' introduces an erroneous override of 'id'.
@@ -126,7 +117,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N6 extends NIIx with NII {}
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'NII' to 'NIIx' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'NIIx with NII' inherits multiple members named 'id' with incompatible signatures.
@@ -150,7 +140,6 @@
 abstract class N8 extends NIIx with NBABxy<int, int> {}
 abstract class N9 = NIIx with NBABxy<String, int>;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'N9' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'N9' introduces an erroneous override of 'id'.
@@ -158,7 +147,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N10 extends NIIx with NBABxy<String, int> {}
 //             ^^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'NBABxy' to 'NIIx' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'NIIx with NBABxy<String, int>' inherits multiple members named 'id' with incompatible signatures.
@@ -166,7 +154,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N11 = NIIx with NTTy<int>;
 //             ^^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'N11' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'N11' introduces an erroneous override of 'id'.
@@ -174,7 +161,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N12 extends NIIx with NTTy<int> {}
 //             ^^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'NTTy' to 'NIIx' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'NIIx with NTTy<int>' inherits multiple members named 'id' with incompatible signatures.
@@ -182,7 +168,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N13 = NIIx with NTTx<int>;
 //             ^^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'N13' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'N13' introduces an erroneous override of 'id'.
@@ -190,7 +175,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class N14 extends NIIx with NTTx<int> {}
 //             ^^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'NTTx' to 'NIIx' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'NIIx with NTTx<int>' inherits multiple members named 'id' with incompatible signatures.
@@ -249,7 +233,6 @@
 abstract class O8 extends OII with OBAB<int, int> {}
 abstract class O9 = OII with OBAB<String, int>;
 //             ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'O9' inherits multiple members named 'id' with incompatible signatures.
 //             ^
 // [cfe] The mixin application class 'O9' introduces an erroneous override of 'id'.
@@ -257,7 +240,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 abstract class O10 extends OII with OBAB<String, int> {}
 //             ^^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Applying the mixin 'OBAB' to 'OII' introduces an erroneous override of 'id'.
 //             ^
 // [cfe] Class 'OII with OBAB<String, int>' inherits multiple members named 'id' with incompatible signatures.
@@ -299,7 +281,6 @@
 class G1 = GTTnum with MTTnum;
 class G2 = GTTnum with MTTint;
 //    ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'G2' inherits multiple members named 'id' with incompatible signatures.
 //    ^
 // [cfe] The mixin application class 'G2' introduces an erroneous override of 'id'.
@@ -307,7 +288,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 class G3 = GTTnum with MTT;
 //    ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'G3' inherits multiple members named 'id' with incompatible signatures.
 //    ^
 // [cfe] The mixin application class 'G3' introduces an erroneous override of 'id'.
@@ -315,7 +295,6 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 class G4 = GTTnum with MTTnumR;
 //    ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
 // [cfe] Class 'G4' inherits multiple members named 'id' with incompatible signatures.
 //    ^
 // [cfe] The mixin application class 'G4' introduces an erroneous override of 'id'.
@@ -323,7 +302,7 @@
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 class G5 = GTTnum with CII;
 //    ^^
-// [analyzer] COMPILE_TIME_ERROR.INCONSISTENT_INHERITANCE
+// [analyzer] STATIC_WARNING.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
 // [cfe] The mixin application class 'G5' introduces an erroneous override of 'id'.
 //    ^
 // [cfe] The non-abstract class 'G5' is missing implementations for these members:
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
index 49b9cf3..80b22b7 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
@@ -13,9 +13,9 @@
 // Use the aliased type.
 
 abstract class C {
-  final T<Null> v7;
+  final T<Map> v7;
 
-  C(): v7 = T<D>();
+  C(): v7 = T<Map>();
   //        ^
   // [analyzer] unspecified
   // [cfe] unspecified
@@ -45,7 +45,7 @@
 
 main() {
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  v9[{}] = {T<D>()};
+  v9[{}] = {T<C>()};
   //        ^
   // [analyzer] unspecified
   // [cfe] unspecified
@@ -75,7 +75,7 @@
 // [analyzer] unspecified
 // [cfe] unspecified
 
-  T<C>.name1(D(), null);
+  T<C>.name1(C(), null);
 //^^^^^^^^^^^^^^^^^^^^^
 // [analyzer] unspecified
 // [cfe] unspecified
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart
index ffb06d2..1c2604c 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart
@@ -28,6 +28,7 @@
   List<T<T>> v6 = [];
   final T<Null> v7;
 
+  C(): v7 = null;
   C.name1(this.v5, this.v7);
   factory C.name2(T<D> arg1, T<Null> arg2) = C.name1;
 
diff --git a/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart b/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart
index efd4162..b24e824 100644
--- a/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart
@@ -16,6 +16,14 @@
 
 // Use the aliased type.
 
+class C {
+  final T v12;
+
+  C(): v12 = T();
+  //         ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
 
 abstract class D2 extends C with T {}
 //             ^
@@ -28,6 +36,22 @@
 // [cfe] unspecified
 
 main() {
+  var v14 = <Set<T>, Set<T>>{{}: {}};
+  v14[{}] = {T()};
+  //         ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  T();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  T v17 = foo<T>(T());
+  //             ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T.named();
 //^
 // [analyzer] unspecified
diff --git a/tests/language_2/nonfunction_type_aliases/usage_type_variable_test.dart b/tests/language_2/nonfunction_type_aliases/usage_type_variable_test.dart
index 3e10b20..ffd1e16 100644
--- a/tests/language_2/nonfunction_type_aliases/usage_type_variable_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/usage_type_variable_test.dart
@@ -32,7 +32,7 @@
   List<T> v11 = [];
   final T v12;
 
-  C(): v12 = T();
+  C(): v12 = null;
   C.name1(this.v10, this.v12);
   factory C.name2(T arg1, T arg2) = C.name1;
 
@@ -57,11 +57,10 @@
 main() {
   var v13 = <T>[];
   var v14 = <Set<T>, Set<T>>{{}: {}};
-  v14[{}] = {T()};
+  v14[{}] = {D1()};
   var v15 = {v13};
   Set<List<T>> v16 = v15;
   v15 = v16;
-  T();
-  T v17 = foo<T>(T());
+  T v17 = foo<T>(null);
   id(v17);
 }
diff --git a/tests/language_2/regress/regress22976_test.dart b/tests/language_2/regress/regress22976_test.dart
index 7b54b5d..63180f8 100644
--- a/tests/language_2/regress/regress22976_test.dart
+++ b/tests/language_2/regress/regress22976_test.dart
@@ -19,6 +19,8 @@
   C<String, int> c2 = new C<String, int>();
   A<int> a0 = c1;
   A<int> a1 = c2;
+  //          ^^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
   //          ^
   // [cfe] A value of type 'C<String, int>' can't be assigned to a variable of type 'A<int>'.
 }
diff --git a/tests/language_2/regress/regress34235_test.dart b/tests/language_2/regress/regress34235_test.dart
index d8bf539..7451dc5 100644
--- a/tests/language_2/regress/regress34235_test.dart
+++ b/tests/language_2/regress/regress34235_test.dart
@@ -21,7 +21,6 @@
 
 class Derived extends BaseWithM1 with M2 {}
 //    ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 // [cfe] Applying the mixin 'M2' to 'BaseWithM1' introduces an erroneous override of 'foo'.
 //                                    ^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
diff --git a/tests/language_2/regress/regress40765_test.dart b/tests/language_2/regress/regress40765_test.dart
new file mode 100644
index 0000000..711cf10
--- /dev/null
+++ b/tests/language_2/regress/regress40765_test.dart
@@ -0,0 +1,42 @@
+// 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 Something {
+  final int x;
+  Something({this.x});
+}
+
+abstract class Base {
+  Something get x;
+}
+
+class Child1 extends Base {
+  final Something x;
+  Child1({this.x});
+}
+
+class Child2 extends Base {
+  final int y;
+  final Something x;
+  Child2({this.x, this.y});
+}
+
+@pragma('vm:never-inline')
+int foo(int k, Base x) {
+  var y = 0;
+  for (var i = 0; i < k; i++) {
+    x as Child1;
+    // Next line will be hoisted out as x.{Child1::x}.{Something::x}
+    // and at foo(0, Child2(..., y: 24)) will end up executing as
+    // x.{Child1::x} -> will load Child2::y (24) and then segfault.
+    y = x.x.x;
+  }
+  return y;
+}
+
+void main() {
+  print(foo(1, Child1(x: Something(x: 1))));
+  print(foo(1, Child1(x: Something(x: 2))));
+  print(foo(0, Child2(x: Something(x: 42), y: 24)));
+}
diff --git a/tests/language_2/regress/regress41613_test.dart b/tests/language_2/regress/regress41613_test.dart
new file mode 100644
index 0000000..5c31ecb
--- /dev/null
+++ b/tests/language_2/regress/regress41613_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  // In legacy Dart 2 and null safety weak mode the error handlers can
+  // return null.
+  Expect.equals(null, int.parse("foo", onError: (_) => null));
+  Expect.equals(null, double.parse("foo", (_) => null));
+}
diff --git a/tests/language_2/type_variable/scope_test.dart b/tests/language_2/type_variable/scope_test.dart
index f4c04ca..10051d0 100644
--- a/tests/language_2/type_variable/scope_test.dart
+++ b/tests/language_2/type_variable/scope_test.dart
@@ -25,8 +25,6 @@
     // [cfe] Type variables can't be used in static members.
     //         ^^^^^^^^^^^^^^^^^
     // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
-    //             ^
-    // [cfe] A value of type 'Foo<String>' can't be assigned to a variable of type 'Foo<invalid-type>'.
     return new Foo<String>();
     //     ^^^^^^^^^^^^^^^^^
     // [analyzer] STATIC_TYPE_WARNING.RETURN_OF_INVALID_TYPE
diff --git a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
index 0ae03df..2811208 100644
--- a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
+++ b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
@@ -10,25 +10,25 @@
 abstract class A<in X> {
 //               ^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
   int foo(X bar);
 }
 
 class B<out X, in Y, inout Z> {}
 //      ^^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 //             ^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 //                   ^^^^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 
 class C<in T> extends A<T> {
 //      ^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
   @override
   int foo(T bar) {
     return 2;
@@ -38,29 +38,29 @@
 mixin D<out T> {}
 //      ^^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 
 class E1 {}
 
 mixin E<in T extends E1> {}
 //      ^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 
 class F<out T> = Object with D<T>;
 //      ^^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 
 class G<out out> {}
 //      ^^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 
 class H<out inout> {}
 //      ^^^
 // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
 
 main() {
   B<int, String, bool> b = B();
diff --git a/tests/language_2/vm/regress_flutter_55345_const_test.dart b/tests/language_2/vm/regress_flutter_55345_const_test.dart
new file mode 100644
index 0000000..9b548ff
--- /dev/null
+++ b/tests/language_2/vm/regress_flutter_55345_const_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that references to deduplicated mixins are properly updated
+// in types which are only accessible through constants.
+// Regression test for https://github.com/flutter/flutter/issues/55345.
+
+class Diagnosticable {}
+
+class SomeClass with Diagnosticable {}
+
+class State<T> with Diagnosticable {
+  const State();
+}
+
+class StateA extends State {
+  const StateA();
+}
+
+class StateB extends State<int> {
+  const StateB();
+}
+
+const c1 = StateA();
+const c2 = StateB();
+
+main() {
+  print(const [
+    {
+      (c1 ?? c2): [
+        [c1 ?? c2]
+      ]
+    },
+    'abc'
+  ]);
+}
diff --git a/tests/language_2/vm/regress_flutter_55345_test.dart b/tests/language_2/vm/regress_flutter_55345_test.dart
new file mode 100644
index 0000000..f5ee00a
--- /dev/null
+++ b/tests/language_2/vm/regress_flutter_55345_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that references to deduplicated mixins are properly updated.
+// Regression test for https://github.com/flutter/flutter/issues/55345.
+
+class Diagnosticable {}
+
+class SomeClass with Diagnosticable {}
+
+class State<T> with Diagnosticable {}
+
+class StateA extends State {}
+
+class StateB extends State<int> {}
+
+StateA a = StateA();
+StateB b = StateB();
+
+List<T> foo<T>(T x) {
+  print(T);
+  return <T>[x];
+}
+
+T Function<S extends T>(T) bar<T>(T x) {
+  print(T);
+
+  return <S extends T>(T y) {
+    print(S);
+    print(y);
+    return y;
+  };
+}
+
+main() {
+  State x1 = a ?? b;
+  print(x1);
+
+  var x2 = a ?? b;
+  var x3 = foo(x2);
+  var x4 = bar(x3);
+  x4(x3);
+}
diff --git a/tests/language_2/void/await_void_test.dart b/tests/language_2/void/await_void_test.dart
new file mode 100644
index 0000000..314e732
--- /dev/null
+++ b/tests/language_2/void/await_void_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that it is not an error to await an expression of type `void`.
+
+import "dart:async";
+
+void v;
+List<void> vs = [null];
+FutureOr<void> fov;
+
+void main() async {
+  await print('');
+  await v;
+  await vs[0];
+  var v2 = vs[0];
+  await v2;
+  await fov;
+}
diff --git a/tests/lib/async/catch_errors.dart b/tests/lib/async/catch_errors.dart
index ff9260d..02c403c 100644
--- a/tests/lib/async/catch_errors.dart
+++ b/tests/lib/async/catch_errors.dart
@@ -3,7 +3,7 @@
 import 'dart:async';
 
 Stream catchErrors(dynamic body()) {
-  StreamController controller;
+  late StreamController controller;
 
   bool onError(e, st) {
     controller.add(e);
@@ -19,16 +19,16 @@
 }
 
 runZonedScheduleMicrotask(body(),
-    {void onScheduleMicrotask(void callback()), Function? onError}) {
+    {void onScheduleMicrotask(void callback())?, Function? onError}) {
   if (onScheduleMicrotask == null) {
-    return runZonedGuarded(body, onError);
+    return runZonedGuarded(body, onError as void Function(Object, StackTrace));
   }
-  HandleUncaughtErrorHandler errorHandler;
+  HandleUncaughtErrorHandler? errorHandler;
   if (onError != null) {
     errorHandler = (Zone self, ZoneDelegate parent, Zone zone, error,
         StackTrace stackTrace) {
       try {
-        return self.parent.runUnary(onError, error);
+        return self.parent!.runUnary(onError as void Function(Object), error);
       } catch (e, s) {
         if (identical(e, error)) {
           return parent.handleUncaughtError(zone, error, stackTrace);
@@ -38,10 +38,10 @@
       }
     };
   }
-  ScheduleMicrotaskHandler asyncHandler;
+  ScheduleMicrotaskHandler? asyncHandler;
   if (onScheduleMicrotask != null) {
     asyncHandler = (Zone self, ZoneDelegate parent, Zone zone, f()) {
-      self.parent.runUnary(onScheduleMicrotask, () => zone.runGuarded(f));
+      self.parent!.runUnary(onScheduleMicrotask, () => zone.runGuarded(f));
     };
   }
   ZoneSpecification specification = new ZoneSpecification(
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index 671e724..6699366 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -151,7 +151,7 @@
 }
 
 class CaptureEvents extends Events {
-  StreamSubscription subscription;
+  late StreamSubscription subscription;
   bool cancelOnError = false;
 
   CaptureEvents(Stream stream, {bool cancelOnError: false}) {
diff --git a/tests/lib/async/future_or_type_test.dart b/tests/lib/async/future_or_type_test.dart
index ed6b36e..2ecb31c 100644
--- a/tests/lib/async/future_or_type_test.dart
+++ b/tests/lib/async/future_or_type_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // In strong mode, `FutureOr` should be a valid type in most locations.
+// Requirements=nnbd-strong
 
 import 'dart:async';
 import 'package:expect/expect.dart';
@@ -65,10 +66,10 @@
     nullableVariable = nullableNumFutureDouble;
     nullableVariable = nullableIntFuture;
     nullableVariable = nullableDoubleFuture;
-    nullableVariable = nullableObjectFuture;
 
     // Disallows invalid values.
     // These are all valid down-casts that fail at runtime.
+    Expect.throws(() => nullableVariable = nullableObjectFuture);
     Expect.throws(() => nullableVariable = objectValue);
     Expect.throws(() => nullableVariable = objectFuture);
     Expect.throws(() => nullableVariable = objectFutureInt);
@@ -108,10 +109,10 @@
     nullableFun(nullableNumFutureDouble);
     nullableFun(nullableIntFuture);
     nullableFun(nullableDoubleFuture);
-    nullableFun(nullableObjectFuture);
 
     // Disallows invalid values.
     // These are all valid down-casts that fail at runtime.
+    Expect.throws(() => nullableFun(nullableObjectFuture));
     Expect.throws(() => nullableFun(objectValue));
     Expect.throws(() => nullableFun(objectFuture));
     Expect.throws(() => nullableFun(objectFutureInt));
@@ -138,7 +139,7 @@
     Expect.throws(() => fun2(nullableObjectFuture));
 
     // Implicit down-cast to return type.
-    FutureOr<num> nullableFun2(dynamic objectValue) => objectValue;
+    FutureOr<num?> nullableFun2(dynamic objectValue) => objectValue;
     nullableFun2(nullValue);
     nullableFun2(intValue);
     nullableFun2(doubleValue);
@@ -151,15 +152,15 @@
     nullableFun2(nullableNumFutureDouble);
     nullableFun2(nullableIntFuture);
     nullableFun2(nullableDoubleFuture);
-    nullableFun2(nullableObjectFuture);
 
-    Expect.throws(() => fun2(objectValue));
-    Expect.throws(() => fun2(objectFuture));
-    Expect.throws(() => fun2(objectFutureInt));
+    Expect.throws(() => nullableFun2(nullableObjectFuture));
+    Expect.throws(() => nullableFun2(objectValue));
+    Expect.throws(() => nullableFun2(objectFuture));
+    Expect.throws(() => nullableFun2(objectFutureInt));
   }
 
   {
-    List<Object> list = new List<FutureOr<num>>();
+    List<Object> list = <FutureOr<num>>[];
     list.add(intValue);
     list.add(doubleValue);
     list.add(numFutureInt);
@@ -178,7 +179,7 @@
     Expect.throws(() => list.add(nullableDoubleFuture));
     Expect.throws(() => list.add(nullableObjectFuture));
 
-    List<Object?> nullableList = new List<FutureOr<num?>>();
+    List<Object?> nullableList = <FutureOr<num?>>[];
     nullableList.add(nullValue);
     nullableList.add(intValue);
     nullableList.add(doubleValue);
@@ -191,8 +192,8 @@
     nullableList.add(nullableNumFutureDouble);
     nullableList.add(nullableIntFuture);
     nullableList.add(nullableDoubleFuture);
-    nullableList.add(nullableObjectFuture);
 
+    Expect.throws(() => nullableList.add(nullableObjectFuture));
     Expect.throws(() => nullableList.add(objectValue));
     Expect.throws(() => nullableList.add(objectFuture));
     Expect.throws(() => nullableList.add(objectFutureInt));
@@ -233,10 +234,10 @@
     nullableNumFutureDouble as FutureOr<num?>;
     nullableIntFuture as FutureOr<num?>;
     nullableDoubleFuture as FutureOr<num?>;
-    nullableObjectFuture as FutureOr<num?>;
 
     // Disallows invalid values.
     // These are all valid down-casts that fail at runtime.
+    Expect.throws(() => nullableObjectFuture as FutureOr<num?>);
     Expect.throws(() => objectValue as FutureOr<num?>);
     Expect.throws(() => objectFuture as FutureOr<num?>);
     Expect.throws(() => objectFutureInt as FutureOr<num?>);
@@ -442,7 +443,7 @@
     Expect.isFalse(new C<Null>().isCheck(objectFuture));
     Expect.isFalse(new C<Null>().isCheck(objectFutureInt));
 
-    Expect.isFalse(new C<FutureOr<num?>>().isCheck(nullValue));
+    Expect.isTrue(new C<FutureOr<num?>>().isCheck(nullValue));
     Expect.isTrue(new C<FutureOr<num?>>().isCheck(intValue));
     Expect.isTrue(new C<FutureOr<num?>>().isCheck(doubleValue));
     Expect.isTrue(new C<FutureOr<num?>>().isCheck(numFutureInt));
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index c38da0f..b084c86 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -41,7 +41,7 @@
   Future val = new Future.value(42);
   Future err1 = new Future.error("Error")..catchError((_) {});
   try {
-    throw new List(0);
+    throw [];
   } catch (e, st) {
     Future err2 = new Future.error(e, st)..catchError((_) {});
   }
@@ -83,7 +83,7 @@
   final completer = new Completer<int>();
   final future = completer.future;
 
-  late int after;
+  int? after;
 
   asyncStart();
   future.then((int v) {
@@ -101,7 +101,7 @@
   final completer = new Completer<int>();
   final future = completer.future;
 
-  late int after;
+  int? after;
   completer.complete(3);
   Expect.isNull(after);
 
@@ -148,13 +148,14 @@
 // Tests for [catchError]
 
 void testException() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   final ex = new Exception();
 
   asyncStart();
   future.then((v) {
     throw "Value not expected";
+    return null;
   }).catchError((error) {
     Expect.equals(error, ex);
     asyncEnd();
@@ -163,7 +164,7 @@
 }
 
 void testExceptionHandler() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   final ex = new Exception();
 
@@ -184,7 +185,7 @@
 }
 
 void testExceptionHandlerReturnsTrue() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   final ex = new Exception();
 
@@ -200,7 +201,7 @@
 }
 
 void testExceptionHandlerReturnsTrue2() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   final ex = new Exception();
 
@@ -218,7 +219,7 @@
 }
 
 void testExceptionHandlerReturnsFalse() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   final ex = new Exception();
 
@@ -515,13 +516,14 @@
 }
 
 void testFutureThenThrowsAsync() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   int error = 42;
 
   asyncStart();
   future.then((v) {
     throw error;
+    return null;
   }).catchError((e) {
     Expect.identical(error, e);
     asyncEnd();
@@ -530,7 +532,7 @@
 }
 
 void testFutureCatchThrowsAsync() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   int error = 42;
 
@@ -545,7 +547,7 @@
 }
 
 void testFutureCatchRethrowsAsync() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   var error;
 
@@ -561,7 +563,7 @@
 }
 
 void testFutureWhenThrowsAsync() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   var error = 42;
 
@@ -576,7 +578,7 @@
 }
 
 void testCompleteWithError() {
-  final completer = new Completer<int>();
+  final completer = new Completer<int?>();
   final future = completer.future;
   var error = 42;
 
@@ -660,7 +662,7 @@
   asyncStart();
   final completer = new Completer<int>();
   final completer2 = new Completer<int>();
-  completer.complete(new CustomFuture(completer2.future));
+  completer.complete(new CustomFuture<int>(completer2.future));
   completer.future.then((v) {
     Expect.equals(42, v);
     asyncEnd();
@@ -672,7 +674,7 @@
   asyncStart();
   final completer = new Completer<int>();
   final completer2 = new Completer<int>();
-  completer.complete(new CustomFuture(completer2.future));
+  completer.complete(new CustomFuture<int>(completer2.future));
   completer.future.then((v) {
     Expect.fail("Should not happen");
     asyncEnd();
@@ -686,7 +688,7 @@
 void testCompleteErrorWithCustomFuture() {
   asyncStart();
   final completer = new Completer<int>();
-  var future = new CustomFuture(new Future.value(42));
+  var future = new CustomFuture<int>(new Future.value(42));
   completer.completeError(future);
   completer.future.then((_) {
     Expect.fail("Shouldn't happen");
@@ -770,8 +772,8 @@
   void doTest(int mask, int permute) {
     asyncStart();
     String stringId = "waitCleanup-$mask-$permute";
-    List<Future?> futures = new List(3);
-    List cleanup = new List(3);
+    List<Future?> futures = <Future?>[null, null, null];
+    List cleanup = [null, null, null];
     int permuteTmp = permute;
     for (int i = 0; i < 3; i++) {
       bool throws = (mask & (1 << i)) != 0;
@@ -815,8 +817,8 @@
     asyncStart();
     bool done = false;
     String stringId = "waitCleanup-$mask-$permute";
-    List<Future?> futures = new List<Future?>(3);
-    List cleanup = new List(3);
+    List<Future?> futures = <Future?>[null, null, null];
+    List cleanup = [null, null, null];
     int permuteTmp = permute;
     for (int i = 0; i < 3; i++) {
       bool throws = (mask & (1 << i)) != 0;
@@ -845,7 +847,8 @@
     }
 
     Future.wait(futures.map((future) => future!),
-          eagerError: true, cleanUp: cleanUp).then((_) {
+            eagerError: true, cleanUp: cleanUp)
+        .then((_) {
       Expect.fail("No error: $stringId");
     }, onError: (e, s) {
       asyncEnd();
@@ -869,7 +872,7 @@
   asyncStart();
   asyncStart();
   runZonedGuarded(() {
-    Future.wait([
+    Future<List<int>?>.value(Future.wait([
       new Future.delayed(cms, () => 0),
       new Future.delayed(cms * 2, () => throw 1),
       new Future.delayed(cms * 3, () => 2)
@@ -878,12 +881,12 @@
       Expect.isFalse(cleanups[index]);
       cleanups[index] = true;
       throw index;
-    }).catchError((e) {
+    })).catchError((e) {
       Expect.equals(e, 1);
       asyncEnd();
     });
   }, (e, s) {
-    int index = e;
+    int index = e as int;
     Expect.isTrue(index == 0 || index == 2, "$index");
     Expect.isFalse(uncaughts[index]);
     uncaughts[index] = true;
@@ -901,7 +904,7 @@
         new Iterable.generate(5, (i) {
           if (i != 3) return new Future.delayed(cms * (i + 1), () => i);
           throw "throwing synchronously in iterable";
-        }), cleanUp: (index) {
+        }), cleanUp: (dynamic index) {
       Expect.isFalse(cleanups[index]);
       cleanups[index] = true;
       if (cleanups.every((x) => x)) asyncEnd();
@@ -919,7 +922,7 @@
 
 void testWaitSyncError2() {
   asyncStart();
-  Future.wait(badIterable()).catchError((e, st) {
+  Future<List?>.value(Future.wait(badIterable())).catchError((e, st) {
     // Makes sure that the `catchError` is invoked.
     // Regression test: an earlier version of `Future.wait` would propagate
     // the error too soon for the code to install an error handler.
@@ -945,7 +948,7 @@
 
   asyncStart();
   runZoned(() {
-    Future.wait(badIterable()).catchError((e, st) {
+    Future<List?>.value(Future.wait(badIterable())).catchError((e, st) {
       Expect.identical(e, caughtError);
       Expect.equals(1, count);
       asyncEnd();
@@ -1000,9 +1003,10 @@
     testType("Future.sync(future($value))",
         new Future<int>.sync(() => new Future<int>.value(value)));
     testType("Future.value($value)", new Future<int>.value(value));
+    testType(
+        "Future.error", new Future<int>.error("ERR")..catchError((_) => value));
   }
   testType("Completer.future", new Completer<int>().future);
-  testType("Future.error", new Future<int>.error("ERR")..catchError((_) {}));
 }
 
 void testAnyValue() {
@@ -1248,7 +1252,7 @@
       : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1);
   Future<S> then<S>(action(value), {Function? onError}) {
     var c = new Completer<S>();
-    c.complete(new Future.microtask(() => action(_result)));
+    c.complete(new Future<S>.microtask(() => action(_result)));
     return c.future;
   }
 
diff --git a/tests/lib/async/futures_test.dart b/tests/lib/async/futures_test.dart
index 1fd0648..9d8597f 100644
--- a/tests/lib/async/futures_test.dart
+++ b/tests/lib/async/futures_test.dart
@@ -9,12 +9,12 @@
 import 'dart:async';
 
 Future testWaitEmpty() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   return Future.wait(futures);
 }
 
 Future testCompleteAfterWait() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c = new Completer<Object?>();
   futures.add(c.future);
   Future future = Future.wait(futures);
@@ -23,7 +23,7 @@
 }
 
 Future testCompleteBeforeWait() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c = new Completer();
   futures.add(c.future);
   c.complete(null);
@@ -31,7 +31,7 @@
 }
 
 Future testWaitWithMultipleValues() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -44,7 +44,7 @@
 }
 
 Future testWaitWithSingleError() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -52,7 +52,7 @@
   c1.complete();
   c2.completeError('correct error');
 
-  return Future.wait(futures).then((_) {
+  return Future.wait(futures).then<void>((_) {
     throw 'incorrect error';
   }).catchError((error, stackTrace) {
     Expect.equals('correct error', error);
@@ -61,7 +61,7 @@
 }
 
 Future testWaitWithMultipleErrors() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -69,7 +69,7 @@
   c1.completeError('correct error');
   c2.completeError('incorrect error 1');
 
-  return Future.wait(futures).then((_) {
+  return Future.wait(futures).then<void>((_) {
     throw 'incorrect error 2';
   }).catchError((error, stackTrace) {
     Expect.equals('correct error', error);
@@ -77,8 +77,17 @@
   });
 }
 
+// Regression test for https://github.com/dart-lang/sdk/issues/41656
+Future testWaitWithErrorAndNonErrorEager() {
+  return Future(() {
+    var f1 = Future(() => throw "Error");
+    var f2 = Future(() => 3);
+    return Future.wait([f1, f2], eagerError: true);
+  }).then((_) => 0, onError: (_) => -1);
+}
+
 Future testWaitWithMultipleErrorsEager() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -86,7 +95,7 @@
   c1.completeError('correct error');
   c2.completeError('incorrect error 1');
 
-  return Future.wait(futures, eagerError: true).then((_) {
+  return Future.wait(futures, eagerError: true).then<void>((_) {
     throw 'incorrect error 2';
   }).catchError((error, stackTrace) {
     Expect.equals('correct error', error);
@@ -103,7 +112,7 @@
 }
 
 Future testWaitWithSingleErrorWithStackTrace() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -111,7 +120,7 @@
   c1.complete();
   c2.completeError('correct error', currentStackTrace);
 
-  return Future.wait(futures).then((_) {
+  return Future.wait(futures).then<void>((_) {
     throw 'incorrect error';
   }).catchError((error, stackTrace) {
     Expect.equals('correct error', error);
@@ -120,7 +129,7 @@
 }
 
 Future testWaitWithMultipleErrorsWithStackTrace() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -128,7 +137,7 @@
   c1.completeError('correct error', currentStackTrace);
   c2.completeError('incorrect error 1');
 
-  return Future.wait(futures).then((_) {
+  return Future.wait(futures).then<void>((_) {
     throw 'incorrect error 2';
   }).catchError((error, stackTrace) {
     Expect.equals('correct error', error);
@@ -137,7 +146,7 @@
 }
 
 Future testWaitWithMultipleErrorsWithStackTraceEager() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
   final c1 = new Completer();
   final c2 = new Completer();
   futures.add(c1.future);
@@ -145,7 +154,7 @@
   c1.completeError('correct error', currentStackTrace);
   c2.completeError('incorrect error 1');
 
-  return Future.wait(futures, eagerError: true).then((_) {
+  return Future.wait(futures, eagerError: true).then<void>((_) {
     throw 'incorrect error 2';
   }).catchError((error, stackTrace) {
     Expect.equals('correct error', error);
@@ -164,7 +173,7 @@
   final c2 = new Completer();
   final futures = <Future>[c1.future, c2.future];
   final waited = Future.wait(futures, eagerError: true);
-  final result = waited.then((v) {
+  final result = waited.then<void>((v) {
     throw "should not be called";
   }, onError: (e, s) {
     Expect.equals(e, 42);
@@ -184,7 +193,7 @@
 
 Future testForEach() {
   final seen = <int>[];
-  return Future.forEach([1, 2, 3, 4, 5], (n) {
+  return Future.forEach([1, 2, 3, 4, 5], (dynamic n) {
     seen.add(n);
     return new Future.value();
   }).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
@@ -198,11 +207,11 @@
 
 Future testForEachWithException() {
   final seen = <int>[];
-  return Future.forEach([1, 2, 3, 4, 5], (n) {
+  return Future.forEach([1, 2, 3, 4, 5], (dynamic n) {
     if (n == 4) throw 'correct exception';
     seen.add(n);
     return new Future.value();
-  }).then((_) {
+  }).then<void>((_) {
     throw 'incorrect exception';
   }).catchError((error) {
     Expect.equals('correct exception', error);
@@ -231,7 +240,7 @@
     count++;
     if (count == 4) throw 'correct exception';
     return new Future(() => true);
-  }).then((_) {
+  }).then<void>((_) {
     throw 'incorrect exception';
   }).catchError((error) {
     Expect.equals('correct exception', error);
@@ -241,7 +250,7 @@
 }
 
 main() {
-  final futures = new List<Future>();
+  final futures = <Future>[];
 
   futures.add(testWaitEmpty());
   futures.add(testCompleteAfterWait());
@@ -249,6 +258,7 @@
   futures.add(testWaitWithMultipleValues());
   futures.add(testWaitWithSingleError());
   futures.add(testWaitWithMultipleErrors());
+  futures.add(testWaitWithErrorAndNonErrorEager());
   futures.add(testWaitWithMultipleErrorsEager());
   futures.add(testWaitWithSingleErrorWithStackTrace());
   futures.add(testWaitWithMultipleErrorsWithStackTrace());
@@ -264,7 +274,7 @@
 
   asyncStart();
   Future.wait(futures).then((List list) {
-    Expect.equals(18, list.length);
+    Expect.equals(19, list.length);
     asyncEnd();
   });
 }
diff --git a/tests/lib/async/regress154963234_strong_test.dart b/tests/lib/async/regress154963234_strong_test.dart
new file mode 100644
index 0000000..d2e537b
--- /dev/null
+++ b/tests/lib/async/regress154963234_strong_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import "package:expect/expect.dart";
+
+main() {
+  var shortDuration = Duration(milliseconds: 5);
+
+  Expect.isTrue(Future<int?>.delayed(shortDuration) is Future);
+  // In strong mode not passing a computation will throw when the type argument
+  // passed is not nullable.
+  Expect.throwsArgumentError(() => Future<int>.delayed(shortDuration));
+}
diff --git a/tests/lib/async/regress154963234_weak_test.dart b/tests/lib/async/regress154963234_weak_test.dart
new file mode 100644
index 0000000..0c689f7
--- /dev/null
+++ b/tests/lib/async/regress154963234_weak_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+main() {
+  var shortDuration = Duration(milliseconds: 5);
+
+  Expect.isTrue(Future<int?>.delayed(shortDuration) is Future);
+  // In weak mode passing computation is not required because any type passed as
+  // the type argument can be nullable.
+  Expect.isTrue(Future<int>.delayed(shortDuration) is Future);
+}
diff --git a/tests/lib/async/run_zoned8_test.dart b/tests/lib/async/run_zoned8_test.dart
index 9a6b917..5e10118 100644
--- a/tests/lib/async/run_zoned8_test.dart
+++ b/tests/lib/async/run_zoned8_test.dart
@@ -24,7 +24,7 @@
       events.add(counter);
       throw counter;
     });
-  }, (e, [s]) {
+  }, (e, [StackTrace? s]) {
     events.add("error: $e");
     Expect.isNotNull(s); // Regression test for http://dartbug.com/33589
   });
diff --git a/tests/lib/async/slow_consumer2_test.dart b/tests/lib/async/slow_consumer2_test.dart
index 5722efb..15710a4 100644
--- a/tests/lib/async/slow_consumer2_test.dart
+++ b/tests/lib/async/slow_consumer2_test.dart
@@ -88,7 +88,7 @@
       listSize -= sentCount - targetCount;
       sentCount = targetCount;
     }
-    controller.add(new List(listSize));
+    controller.add(List.filled(listSize, -1));
     int ms = listSize * 1000 ~/ bytesPerSecond;
     Duration duration = new Duration(milliseconds: ms);
     if (!controller.isPaused) new Timer(duration, send);
diff --git a/tests/lib/async/slow_consumer_test.dart b/tests/lib/async/slow_consumer_test.dart
index 81f811b..56b83b4 100644
--- a/tests/lib/async/slow_consumer_test.dart
+++ b/tests/lib/async/slow_consumer_test.dart
@@ -89,7 +89,7 @@
       listSize -= sentCount - targetCount;
       sentCount = targetCount;
     }
-    controller.add(new List(listSize));
+    controller.add(new List.filled(listSize, null));
     int ms = listSize * 1000 ~/ bytesPerSecond;
     Duration duration = new Duration(milliseconds: ms);
     if (!controller.isPaused) {
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index 70223fe..b77d0df 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -22,7 +22,7 @@
   test("StreamController.fold", () {
     StreamController c = new StreamController();
     Stream stream = c.stream.asBroadcastStream(onCancel: cancelSub);
-    stream.fold(0, (a, b) => a + b).then(expectAsync((int v) {
+    stream.fold<dynamic>(0, (a, b) => a + b).then(expectAsync((int v) {
       Expect.equals(42, v);
     }));
     c.add(10);
@@ -33,9 +33,9 @@
   test("StreamController.fold throws", () {
     StreamController c = new StreamController();
     Stream stream = c.stream.asBroadcastStream(onCancel: cancelSub);
-    stream.fold(0, (a, b) {
+    Future<int?>.value(stream.fold(0, (a, b) {
       throw "Fnyf!";
-    }).catchError(expectAsync((error) {
+    })).catchError(expectAsync((error) {
       Expect.equals("Fnyf!", error);
     }));
     c.add(42);
@@ -46,7 +46,7 @@
   test("Single-subscription StreamController.fold", () {
     StreamController c = new StreamController();
     Stream stream = c.stream;
-    stream.fold(0, (a, b) => a + b).then(expectAsync((int v) {
+    stream.fold<dynamic>(0, (a, b) => a + b).then(expectAsync((int v) {
       Expect.equals(42, v);
     }));
     c.add(10);
@@ -57,9 +57,9 @@
   test("Single-subscription StreamController.fold throws", () {
     StreamController c = new StreamController();
     Stream stream = c.stream;
-    stream.fold(0, (a, b) {
+    Future<int?>.value(stream.fold(0, (a, b) {
       throw "Fnyf!";
-    }).catchError(expectAsync((e) {
+    })).catchError(expectAsync((e) {
       Expect.equals("Fnyf!", e);
     }));
     c.add(42);
@@ -669,8 +669,8 @@
   });
 }
 
-void testSink({
-    required bool sync, required bool broadcast, required bool asBroadcast}) {
+void testSink(
+    {required bool sync, required bool broadcast, required bool asBroadcast}) {
   String type =
       "${sync ? "S" : "A"}${broadcast ? "B" : "S"}${asBroadcast ? "aB" : ""}";
   test("$type-controller-sink", () {
diff --git a/tests/lib/async/stream_join_test.dart b/tests/lib/async/stream_join_test.dart
index 6e3a98b..49077aa 100644
--- a/tests/lib/async/stream_join_test.dart
+++ b/tests/lib/async/stream_join_test.dart
@@ -52,8 +52,7 @@
 
   test("join-error", () {
     StreamController c = new StreamController();
-    c.stream
-        .join("X")
+    Future<String?>.value(c.stream.join("X"))
         .catchError(expectAsync((String s) => expect(s, equals("BAD!"))));
     c.add(new Foo("foo"));
     c.add(new Foo("bar"));
diff --git a/tests/lib/async/stream_state_helper.dart b/tests/lib/async/stream_state_helper.dart
index 6178495..5d0471d 100644
--- a/tests/lib/async/stream_state_helper.dart
+++ b/tests/lib/async/stream_state_helper.dart
@@ -12,35 +12,38 @@
 class SubscriptionProtocolTest {
   final StreamProtocolTest _streamTest;
   final int id;
-  StreamSubscription _subscription;
+  StreamSubscription? _subscription;
 
   SubscriptionProtocolTest(this.id, this._subscription, this._streamTest);
 
-  void pause([Future resumeSignal]) {
-    if (_subscription == null) throw new StateError("Not subscribed");
-    _subscription.pause(resumeSignal);
+  void pause([Future? resumeSignal]) {
+    var subscription = _subscription;
+    if (subscription == null) throw new StateError("Not subscribed");
+    subscription.pause(resumeSignal);
   }
 
   void resume() {
-    if (_subscription == null) throw new StateError("Not subscribed");
-    _subscription.resume();
+    var subscription = _subscription;
+    if (subscription == null) throw new StateError("Not subscribed");
+    subscription.resume();
   }
 
   void cancel() {
-    if (_subscription == null) throw new StateError("Not subscribed");
-    _subscription.cancel();
+    var subscription = _subscription;
+    if (subscription == null) throw new StateError("Not subscribed");
+    subscription.cancel();
     _subscription = null;
   }
 
-  void expectData(var data, [void action()]) {
+  void expectData(var data, [void action()?]) {
     _streamTest._expectData(this, data, action);
   }
 
-  void expectError(var error, [void action()]) {
+  void expectError(var error, [void action()?]) {
     _streamTest._expectError(this, error, action);
   }
 
-  void expectDone([void action()]) {
+  void expectDone([void action()?]) {
     _streamTest._expectDone(this, action);
   }
 }
@@ -49,14 +52,14 @@
   bool trace = false;
   final bool isBroadcast;
   final bool isAsBroadcast;
-  StreamController _controller;
-  Stream _controllerStream;
+  late StreamController _controller;
+  late Stream _controllerStream;
   // Most recent subscription created. Used as default for pause/resume.
-  SubscriptionProtocolTest _latestSubscription;
-  List<Event> _expectations = new List<Event>();
+  SubscriptionProtocolTest? _latestSubscription;
+  List<Event> _expectations = <Event>[];
   int _nextExpectationIndex = 0;
   int _subscriptionIdCounter = 0;
-  Function _onComplete;
+  Function? _onComplete;
 
   StreamProtocolTest.broadcast({bool sync: false})
       : isBroadcast = true,
@@ -128,20 +131,20 @@
     if (trace) {
       print("[Listen #$subscriptionId(#${_latestSubscription.hashCode})]");
     }
-    return _latestSubscription;
+    return _latestSubscription!;
   }
 
   // Actions on the most recently created subscription.
-  void pause([Future resumeSignal]) {
-    _latestSubscription.pause(resumeSignal);
+  void pause([Future? resumeSignal]) {
+    _latestSubscription!.pause(resumeSignal);
   }
 
   void resume() {
-    _latestSubscription.resume();
+    _latestSubscription!.resume();
   }
 
   void cancel() {
-    _latestSubscription.cancel();
+    _latestSubscription!.cancel();
     _latestSubscription = null;
   }
 
@@ -155,7 +158,7 @@
             "Found   : Early termination.\n${expect._stackTrace}");
       });
     }
-    _onComplete();
+    _onComplete!();
   }
 
   // Handling of stream events.
@@ -260,75 +263,75 @@
   }
 
   // Adds _expectations.
-  void expectAny([void action()]) {
+  void expectAny([void action()?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new LogAnyEvent(action));
   }
 
-  void expectData(var data, [void action()]) {
+  void expectData(var data, [void action()?]) {
     _expectData(null, data, action);
   }
 
-  void _expectData(SubscriptionProtocolTest sub, var data, void action()) {
+  void _expectData(SubscriptionProtocolTest? sub, var data, void action()?) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new DataEvent(sub, data, action));
   }
 
-  void expectError(var error, [void action()]) {
+  void expectError(var error, [void action()?]) {
     _expectError(null, error, action);
   }
 
-  void _expectError(SubscriptionProtocolTest sub, var error, void action()) {
+  void _expectError(SubscriptionProtocolTest? sub, var error, void action()?) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new ErrorEvent(sub, error, action));
   }
 
-  void expectDone([void action()]) {
+  void expectDone([void action()?]) {
     _expectDone(null, action);
   }
 
-  void _expectDone(SubscriptionProtocolTest sub, [void action()]) {
+  void _expectDone(SubscriptionProtocolTest? sub, [void action()?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new DoneEvent(sub, action));
   }
 
-  void expectPause([void action()]) {
+  void expectPause([void action()?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new PauseCallbackEvent(action));
   }
 
-  void expectResume([void action()]) {
+  void expectResume([void action()?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new ResumeCallbackEvent(action));
   }
 
-  void expectListen([void action()]) {
+  void expectListen([void action()?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new SubscriptionCallbackEvent(action));
   }
 
-  void expectCancel([void action()]) {
+  void expectCancel([void action()?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
     _expectations.add(new CancelCallbackEvent(action));
   }
 
-  void expectBroadcastListen([void action(StreamSubscription sub)]) {
+  void expectBroadcastListen([void action(StreamSubscription sub)?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
@@ -336,7 +339,7 @@
     _expectations.add(new BroadcastListenCallbackEvent(action));
   }
 
-  void expectBroadcastCancel([void action(StreamSubscription sub)]) {
+  void expectBroadcastCancel([void action(StreamSubscription sub)?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
@@ -344,7 +347,7 @@
     _expectations.add(new BroadcastCancelCallbackEvent(action));
   }
 
-  void expectBroadcastListenOpt([void action(StreamSubscription sub)]) {
+  void expectBroadcastListenOpt([void action(StreamSubscription sub)?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
@@ -352,7 +355,7 @@
     _expectations.add(new BroadcastListenCallbackEvent(action));
   }
 
-  void expectBroadcastCancelOpt([void action(StreamSubscription sub)]) {
+  void expectBroadcastCancelOpt([void action(StreamSubscription sub)?]) {
     if (_onComplete == null) {
       _fail("Adding expectation after completing");
     }
@@ -379,9 +382,9 @@
 }
 
 class Event {
-  Function _action;
-  StackTrace _stackTrace;
-  Event(void action())
+  Function? _action;
+  StackTrace? _stackTrace;
+  Event(void action()?)
       : _action = (action == null) ? null : expectAsync(action) {
     try {
       throw 0;
@@ -389,7 +392,7 @@
       _stackTrace = s;
     }
   }
-  Event.broadcast(void action(StreamSubscription sub))
+  Event.broadcast(void action(StreamSubscription sub)?)
       : _action = (action == null) ? null : expectAsync(action) {
     try {
       throw 0;
@@ -412,37 +415,37 @@
 
   bool matchPause() {
     if (!_testPause()) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
   bool matchResume() {
     if (!_testResume()) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
   bool matchSubscribe() {
     if (!_testSubscribe()) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
   bool matchCancel() {
     if (!_testCancel()) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
   bool matchBroadcastListen(StreamSubscription sub) {
     if (!_testBroadcastListen()) return false;
-    if (_action != null) _action(sub);
+    _action?.call(sub);
     return true;
   }
 
   bool matchBroadcastCancel(StreamSubscription sub) {
     if (!_testBroadcastCancel()) return false;
-    if (_action != null) _action(sub);
+    _action?.call(sub);
     return true;
   }
 
@@ -458,31 +461,31 @@
 }
 
 class SubscriptionEvent extends Event {
-  SubscriptionProtocolTest subscription;
-  SubscriptionEvent(this.subscription, void action()) : super(action);
+  SubscriptionProtocolTest? subscription;
+  SubscriptionEvent(this.subscription, void action()?) : super(action);
 
   bool matchData(int id, var data) {
-    if (subscription != null && subscription.id != id) return false;
+    if (subscription != null && subscription!.id != id) return false;
     if (!_testData(data)) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
   bool matchError(int id, e) {
-    if (subscription != null && subscription.id != id) return false;
+    if (subscription != null && subscription!.id != id) return false;
     if (!_testError(e)) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
   bool matchDone(int id) {
-    if (subscription != null && subscription.id != id) return false;
+    if (subscription != null && subscription!.id != id) return false;
     if (!_testDone()) return false;
-    if (_action != null) _action();
+    _action?.call();
     return true;
   }
 
-  String get _id => (subscription == null) ? "" : "#${subscription.id}";
+  String get _id => (subscription == null) ? "" : "#${subscription!.id}";
 }
 
 class MismatchEvent extends Event {
@@ -492,7 +495,7 @@
 
 class DataEvent extends SubscriptionEvent {
   final data;
-  DataEvent(SubscriptionProtocolTest sub, this.data, void action())
+  DataEvent(SubscriptionProtocolTest? sub, this.data, void action()?)
       : super(sub, action);
   bool _testData(var data) => this.data == data;
   String toString() => "[Data$_id: $data]";
@@ -500,51 +503,51 @@
 
 class ErrorEvent extends SubscriptionEvent {
   final error;
-  ErrorEvent(SubscriptionProtocolTest sub, this.error, void action())
+  ErrorEvent(SubscriptionProtocolTest? sub, this.error, void action()?)
       : super(sub, action);
   bool _testError(error) => this.error == error;
   String toString() => "[Error$_id: $error]";
 }
 
 class DoneEvent extends SubscriptionEvent {
-  DoneEvent(SubscriptionProtocolTest sub, void action()) : super(sub, action);
+  DoneEvent(SubscriptionProtocolTest? sub, void action()?) : super(sub, action);
   bool _testDone() => true;
   String toString() => "[Done$_id]";
 }
 
 class PauseCallbackEvent extends Event {
-  PauseCallbackEvent(void action()) : super(action);
+  PauseCallbackEvent(void action()?) : super(action);
   bool _testPause() => true;
   String toString() => "[Paused]";
 }
 
 class ResumeCallbackEvent extends Event {
-  ResumeCallbackEvent(void action()) : super(action);
+  ResumeCallbackEvent(void action()?) : super(action);
   bool _testResume() => true;
   String toString() => "[Resumed]";
 }
 
 class SubscriptionCallbackEvent extends Event {
-  SubscriptionCallbackEvent(void action()) : super(action);
+  SubscriptionCallbackEvent(void action()?) : super(action);
   bool _testSubscribe() => true;
   String toString() => "[Subscribed]";
 }
 
 class CancelCallbackEvent extends Event {
-  CancelCallbackEvent(void action()) : super(action);
+  CancelCallbackEvent(void action()?) : super(action);
   bool _testCancel() => true;
   String toString() => "[Cancelled]";
 }
 
 class BroadcastCancelCallbackEvent extends Event {
-  BroadcastCancelCallbackEvent(void action(StreamSubscription sub))
+  BroadcastCancelCallbackEvent(void action(StreamSubscription sub)?)
       : super.broadcast(action);
   bool _testBroadcastCancel() => true;
   String toString() => "[BroadcastCancel]";
 }
 
 class BroadcastListenCallbackEvent extends Event {
-  BroadcastListenCallbackEvent(void action(StreamSubscription sub))
+  BroadcastListenCallbackEvent(void action(StreamSubscription sub)?)
       : super.broadcast(action);
   bool _testBroadcastListen() => true;
   String toString() => "[BroadcastListen]";
@@ -554,7 +557,7 @@
 class LogAnyEvent extends Event {
   String _actual = "*Not matched yet*";
 
-  LogAnyEvent(void action()) : super(action);
+  LogAnyEvent(void action()?) : super(action);
 
   bool _testData(var data) {
     _actual = "*[Data $data]";
diff --git a/tests/lib/async/zone_error_callback_test.dart b/tests/lib/async/zone_error_callback_test.dart
index 8961b67..7b81e7e 100644
--- a/tests/lib/async/zone_error_callback_test.dart
+++ b/tests/lib/async/zone_error_callback_test.dart
@@ -226,14 +226,16 @@
   {
     asyncStart();
     StreamController controller = new StreamController();
-    controller.stream.every((x) => throw error1).catchError(expectErrorOnly);
+    Future<bool?>.value(controller.stream.every((x) => throw error1))
+        .catchError(expectErrorOnly);
     controller.add(null);
   }
 
   {
     asyncStart();
     StreamController controller = new StreamController();
-    controller.stream.any((x) => throw error1).catchError(expectErrorOnly);
+    Future<bool?>.value(controller.stream.any((x) => throw error1))
+        .catchError(expectErrorOnly);
     controller.add(null);
   }
 
diff --git a/tests/lib/async/zone_run_unary_test.dart b/tests/lib/async/zone_run_unary_test.dart
index b505bc5d..0f7fd74 100644
--- a/tests/lib/async/zone_run_unary_test.dart
+++ b/tests/lib/async/zone_run_unary_test.dart
@@ -25,7 +25,7 @@
 
   events.add("zone forked");
   Zone expectedZone = forked;
-  var result = forked.runUnary((arg) {
+  var result = forked.runUnary((dynamic arg) {
     Expect.identical(expectedZone, Zone.current);
     events.add("run closure");
     return arg + 3;
@@ -43,7 +43,7 @@
 
   asyncStart();
   shouldForward = true;
-  result = forked.runUnary((arg) {
+  result = forked.runUnary((dynamic arg) {
     Expect.identical(forked, Zone.current);
     events.add("run closure 2");
     scheduleMicrotask(() {
diff --git a/tests/lib/convert/base64_test.dart b/tests/lib/convert/base64_test.dart
index 6e85a7c..40867fc 100644
--- a/tests/lib/convert/base64_test.dart
+++ b/tests/lib/convert/base64_test.dart
@@ -118,7 +118,7 @@
       for (int j = i; j < encoded.length; j += increment) {
         {
           // Using add/close
-          List<List<int>> results;
+          late List<List<int>> results;
           var sink = new ChunkedConversionSink<List<int>>.withCallback((v) {
             results = v;
           });
@@ -132,7 +132,7 @@
         }
         {
           // Using addSlice
-          List<List<int>> results;
+          late List<List<int>> results;
           var sink = new ChunkedConversionSink<List<int>>.withCallback((v) {
             results = v;
           });
diff --git a/tests/lib/convert/chunked_conversion_utf82_test.dart b/tests/lib/convert/chunked_conversion_utf82_test.dart
index bc0b200..2e07f87 100644
--- a/tests/lib/convert/chunked_conversion_utf82_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf82_test.dart
@@ -46,11 +46,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -77,11 +80,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -220,44 +223,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/chunked_conversion_utf86_test.dart b/tests/lib/convert/chunked_conversion_utf86_test.dart
index a42e752..8c9a08c 100644
--- a/tests/lib/convert/chunked_conversion_utf86_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf86_test.dart
@@ -28,11 +28,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -59,11 +62,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -202,44 +205,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/chunked_conversion_utf87_test.dart b/tests/lib/convert/chunked_conversion_utf87_test.dart
index ab42ee2..5434f1f 100644
--- a/tests/lib/convert/chunked_conversion_utf87_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf87_test.dart
@@ -49,11 +49,14 @@
   return utf8.decode(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -80,11 +83,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -223,44 +226,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/chunked_conversion_utf88_test.dart b/tests/lib/convert/chunked_conversion_utf88_test.dart
index 932682d..93cab53b 100644
--- a/tests/lib/convert/chunked_conversion_utf88_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf88_test.dart
@@ -112,16 +112,15 @@
   const LEADING_SURROGATE = 0xd801;
   const TRAILING_SURROGATE = 0xdc12;
   const UTF8_ENCODING = const [0xf0, 0x90, 0x90, 0x92];
-  const UTF8_LEADING = const [0xed, 0xa0, 0x81];
-  const UTF8_TRAILING = const [0xed, 0xb0, 0x92];
+  const UTF8_REPLACEMENT = const [0xef, 0xbf, 0xbd];
   const CHAR_A = 0x61;
 
   // Test surrogates at all kinds of locations.
   var codeUnits = <int>[];
   for (int i = 0; i < 2049; i++) {
     // Invariant: codeUnits[0..i - 1] is filled with CHAR_A (character 'a').
-    codeUnits.length = i + 1;
-    codeUnits[i] = CHAR_A;
+    codeUnits.add(CHAR_A);
+    Expect.equals(i + 1, codeUnits.length);
 
     // Only test for problem zones, close to powers of two.
     if (i > 20 && _nextPowerOf2(i - 2) - i > 10) continue;
@@ -129,20 +128,21 @@
     codeUnits[i] = LEADING_SURROGATE;
     var str = new String.fromCharCodes(codeUnits);
     var bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
-    codeUnits.length = i + 2;
+    codeUnits.add(CHAR_A);
+    Expect.equals(i + 2, codeUnits.length);
     codeUnits[i] = LEADING_SURROGATE;
     codeUnits[i + 1] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
@@ -157,39 +157,40 @@
     codeUnits[i + 1] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
-    codeUnits.length = i + 3;
+    codeUnits.add(CHAR_A);
+    Expect.equals(i + 3, codeUnits.length);
     codeUnits[i] = LEADING_SURROGATE;
     codeUnits[i + 1] = TRAILING_SURROGATE;
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
@@ -208,12 +209,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
@@ -221,12 +222,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
@@ -234,15 +235,16 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     // Make sure the invariant is correct.
+    codeUnits.length = i + 1;
     codeUnits[i] = CHAR_A;
   }
 }
diff --git a/tests/lib/convert/json_lib_test.dart b/tests/lib/convert/json_lib_test.dart
index 29aa3f0..faad0cf 100644
--- a/tests/lib/convert/json_lib_test.dart
+++ b/tests/lib/convert/json_lib_test.dart
@@ -104,8 +104,8 @@
 
   // Lists.
   Expect.equals('[]', json.encode([]));
-  Expect.equals('[]', json.encode(new List(0)));
-  Expect.equals('[null,null,null]', json.encode(new List(3)));
+  Expect.equals('[]', json.encode(new List.empty()));
+  Expect.equals('[null,null,null]', json.encode(new List.filled(3, null)));
   validateRoundTrip([3, -4.5, null, true, 'hi', false]);
   Expect.equals(
       '[[3],[],[null],["hi",true]]',
diff --git a/tests/lib/convert/json_utf8_chunk_test.dart b/tests/lib/convert/json_utf8_chunk_test.dart
index db6a220..e75019d 100644
--- a/tests/lib/convert/json_utf8_chunk_test.dart
+++ b/tests/lib/convert/json_utf8_chunk_test.dart
@@ -148,7 +148,7 @@
 // Tests combinations of numbers, strings and keywords.
 void testAll() {
   var s = r'{"":[true,false,42, -33e-3,null,"\u0080"], "z": 0}';
-  bool check(o) {
+  void check(o) {
     if (o is Map) {
       Expect.equals(2, o.length);
       Expect.equals(0, o["z"]);
@@ -284,69 +284,69 @@
 void testMalformed() {
   // Overlong encodings.
   jsonMalformedTest(
-      "overlong-0-2", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-0-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-0-4", "@\uFFFD@",
+      "overlong-0-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest(
-      "overlong-7f-2", "@\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-7f-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7f-4", "@\uFFFD@",
+      "overlong-7f-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x81, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-80-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-80-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-80-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-80-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x82, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-7ff-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7ff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-7ff-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7ff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x9f, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest("overlong-800-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-800-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0xa0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-ffff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-ffff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x8f, 0xbf, 0xbf, 0x40, 0x22]);
 
   // Unterminated multibyte sequences.
   jsonMalformedTest(
       "unterminated-2-normal", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-3-normal", "@\uFFFD\uFFFD@",
       [0x22, 0x40, 0xe0, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-4-normal", "@\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-multi", "@\uFFFD\x80@",
       [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-escape", "@\uFFFD\n@",
       [0x22, 0x40, 0xc0, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xe0, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-end", "@\uFFFD", [0x22, 0x40, 0xc0, 0x22]);
 
   jsonMalformedTest(
-      "unterminated-3-end", "@\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
+      "unterminated-3-end", "@\uFFFD\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
 
-  jsonMalformedTest(
-      "unterminated-4-end", "@\uFFFD", [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
+  jsonMalformedTest("unterminated-4-end", "@\uFFFD\uFFFD\uFFFD",
+      [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
 
   // Unexpected continuation byte
   // - after a normal character.
@@ -372,13 +372,13 @@
       "leading-2", "@\uFFFD\x80@", [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-3-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-3-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-3-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-4-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-3", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-3", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   // Overlong encodings of ASCII outside of strings always fail.
diff --git a/tests/lib/convert/line_splitter_test.dart b/tests/lib/convert/line_splitter_test.dart
index 81b4bf3..4196bf0 100644
--- a/tests/lib/convert/line_splitter_test.dart
+++ b/tests/lib/convert/line_splitter_test.dart
@@ -26,7 +26,7 @@
 
   var inputs = const ['line1', 'line2', 'long line 3', ' line 4 ', 'l5'];
 
-  var buffer = inputs.fold(new StringBuffer(), (buff, e) {
+  var buffer = inputs.fold(new StringBuffer(), (dynamic buff, dynamic e) {
     buff.write(e);
     buff.write(lineTerminators[breakIndex]);
 
diff --git a/tests/lib/convert/unicode_tests.dart b/tests/lib/convert/unicode_tests.dart
index 9f0493b..82d7f17 100644
--- a/tests/lib/convert/unicode_tests.dart
+++ b/tests/lib/convert/unicode_tests.dart
@@ -227,8 +227,8 @@
   var tests = <List>[];
   tests.addAll(_TEST_PAIRS);
   tests.addAll(_TEST_PAIRS.map((test) {
-    var bytes = test[0];
-    var string = test[1];
+    var bytes = test[0] as List<int>;
+    var string = test[1] as String;
     var longBytes = <int>[];
     var longString = "";
     for (int i = 0; i < 100; i++) {
diff --git a/tests/lib/convert/utf82_test.dart b/tests/lib/convert/utf82_test.dart
index df08103..cf0c2b0 100644
--- a/tests/lib/convert/utf82_test.dart
+++ b/tests/lib/convert/utf82_test.dart
@@ -28,11 +28,14 @@
   return new Utf8Codec(allowMalformed: true).decoder.convert(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -64,11 +67,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -207,44 +210,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/utf84_test.dart b/tests/lib/convert/utf84_test.dart
index bc1db59..566b1fa 100755
--- a/tests/lib/convert/utf84_test.dart
+++ b/tests/lib/convert/utf84_test.dart
@@ -727,10 +727,14 @@
   Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
   Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
-  Expect
-      .listEquals([0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
+  Expect.listEquals(
+      [0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
 
   // unexpected continuation bytes
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
@@ -795,12 +799,15 @@
   // Sequences with last continuation byte missing
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
       "2-byte sequence with last byte missing");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80]), "3-byte sequence with last byte missing");
   Expect.listEquals(
-      [unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80]),
-      "4-byte sequence with last byte missing");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xe0, 0x80]),
+      "3-byte sequence with last byte missing");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80]), "4-byte sequence with last byte missing");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -871,6 +878,9 @@
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune
       ],
       utf8ToRunes([
@@ -890,8 +900,8 @@
         0x80,
         0x80,
         0xdf,
-        0xef,
-        0xbf,
+        0xef, // These two bytes form one incomplete sequence.
+        0xbf, // All others form one per byte.
         0xf7,
         0xbf,
         0xbf,
@@ -908,10 +918,10 @@
       "Concatenation of incomplete sequences");
 
   // Impossible bytes
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -921,11 +931,20 @@
 
   // Overlong sequences
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0xaf]), "c0 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0xaf]),
+      "c0 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -943,11 +962,20 @@
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc1, 0xbf]),
+      "c1 bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -965,11 +993,20 @@
   ], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0x80]), "c0 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0x80]),
+      "c0 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
diff --git a/tests/lib/convert/utf85_test.dart b/tests/lib/convert/utf85_test.dart
index 3f287e9..a380991 100644
--- a/tests/lib/convert/utf85_test.dart
+++ b/tests/lib/convert/utf85_test.dart
@@ -9,7 +9,7 @@
 
 main() {
   for (int i = 0; i <= 0x10FFFF; i++) {
-    if (i == unicodeBomCharacterRune) continue;
+    if (i == unicodeBomCharacterRune || (i & 0x1FF800) == 0xD800) continue;
     Expect.equals(
         i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
   }
diff --git a/tests/lib/convert/utf8_encode_test.dart b/tests/lib/convert/utf8_encode_test.dart
index 1e611bb..0a43e14 100644
--- a/tests/lib/convert/utf8_encode_test.dart
+++ b/tests/lib/convert/utf8_encode_test.dart
@@ -25,8 +25,8 @@
   String ascii = "ABCDE";
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0));
-  Expect
-      .listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
+  Expect.listEquals(
+      [0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
   Expect.listEquals([0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 1));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44], encoder.convert(ascii, 0, 4));
   Expect.listEquals([0x42, 0x43, 0x44], encoder.convert(ascii, 1, 4));
@@ -50,6 +50,6 @@
   Expect.listEquals(
       [0xc2, 0x82, 0xe1, 0x81, 0x81], encoder.convert(unicode, 1, 3));
   // Split in the middle of a surrogate pair.
-  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xed, 0xa0, 0x80],
+  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xef, 0xbf, 0xbd],
       encoder.convert(unicode, 1, 4));
 }
diff --git a/tests/lib/convert/utf8_test.dart b/tests/lib/convert/utf8_test.dart
index 858c982..6f97fd0 100644
--- a/tests/lib/convert/utf8_test.dart
+++ b/tests/lib/convert/utf8_test.dart
@@ -73,28 +73,29 @@
 
   // Bad encoding, points to first bad byte.
   testExn([0x80, 0x00], 0);
-  testExn([0xC0, 0x00], 1);
-  testExn([0xE0, 0x00], 1);
-  testExn([0xE0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x00], 1);
-  testExn([0xF0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x80, 0x80, 0x00], 3);
+  testExn([0xC2, 0x00], 1);
+  testExn([0xE2, 0x00], 1);
+  testExn([0xE2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x00], 1);
+  testExn([0xF2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x80, 0x80, 0x00], 3);
   testExn([0xF8, 0x00], 0);
   // Short encoding, points to end.
-  testExn([0xC0], 1);
-  testExn([0xE0], 1);
-  testExn([0xE0, 0x80], 2);
-  testExn([0xF0], 1);
-  testExn([0xF0, 0x80], 2);
-  testExn([0xF0, 0x80, 0x80], 3);
-  // Overlong encoding, points to start of encoding.
+  testExn([0xC2], 1);
+  testExn([0xE2], 1);
+  testExn([0xE2, 0x80], 2);
+  testExn([0xF2], 1);
+  testExn([0xF2, 0x80], 2);
+  testExn([0xF2, 0x80, 0x80], 3);
+  // Overlong encoding, points to byte that gave enough information to conclude
+  // that it was overlong.
   testExn([0xC0, 0x80], 0);
   testExn([0xC1, 0xBF], 0);
-  testExn([0xE0, 0x80, 0x80], 0);
-  testExn([0xE0, 0x9F, 0xBF], 0);
-  testExn([0xF0, 0x80, 0x80, 0x80], 0);
-  testExn([0xF0, 0x8F, 0xBF, 0xBF], 0);
+  testExn([0xE0, 0x80, 0x80], 1);
+  testExn([0xE0, 0x9F, 0xBF], 1);
+  testExn([0xF0, 0x80, 0x80, 0x80], 1);
+  testExn([0xF0, 0x8F, 0xBF, 0xBF], 1);
   // Invalid character (value too large, over 0x10FFFF).
-  testExn([0xF4, 0x90, 0x80, 0x80], 0);
+  testExn([0xF4, 0x90, 0x80, 0x80], 1);
   testExn([0xF7, 0xBF, 0xBF, 0xBF], 0);
 }
diff --git a/tests/lib/html/Ahem.ttf b/tests/lib/html/Ahem.ttf
new file mode 100644
index 0000000..ac81cb0
--- /dev/null
+++ b/tests/lib/html/Ahem.ttf
Binary files differ
diff --git a/tests/lib/html/async_cancellingisolate.dart b/tests/lib/html/async_cancellingisolate.dart
new file mode 100644
index 0000000..b04c5b1
--- /dev/null
+++ b/tests/lib/html/async_cancellingisolate.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library async_cancellingisolate;
+
+import 'dart:async';
+import 'package:expect/minitest.dart';
+
+main(message, replyTo) {
+  var command = message.first;
+  expect(command, 'START');
+  var shot = false;
+  var oneshot;
+  var periodic;
+  periodic = new Timer.periodic(const Duration(milliseconds: 10), (timer) {
+    expect(shot, isFalse);
+    shot = true;
+    expect(timer, same(periodic));
+    periodic.cancel();
+    oneshot.cancel();
+    // Wait some more time to be sure callbacks won't be invoked any
+    // more.
+    new Timer(const Duration(milliseconds: 50), () {
+      replyTo.send('DONE');
+    });
+  });
+  // We launch the oneshot timer after the periodic timer. Otherwise a
+  // (very long) context switch could make this test flaky: assume the
+  // oneshot timer is created first and then there is a 30ms context switch.
+  // when the periodic timer is scheduled it would execute after the oneshot.
+  oneshot = new Timer(const Duration(milliseconds: 30), () {
+    fail('Should never be invoked');
+  });
+}
diff --git a/tests/lib/html/async_oneshot.dart b/tests/lib/html/async_oneshot.dart
new file mode 100644
index 0000000..475efe3
--- /dev/null
+++ b/tests/lib/html/async_oneshot.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:expect/minitest.dart';
+
+main(message, replyTo) {
+  var command = message.first;
+  expect(command, 'START');
+  new Timer(const Duration(milliseconds: 10), () {
+    replyTo.send('DONE');
+  });
+}
diff --git a/tests/lib/html/async_periodictimer.dart b/tests/lib/html/async_periodictimer.dart
new file mode 100644
index 0000000..9837ae5
--- /dev/null
+++ b/tests/lib/html/async_periodictimer.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library async_periodictimer;
+
+import 'dart:async';
+import 'package:expect/minitest.dart';
+
+main(message, replyTo) {
+  var command = message.first;
+  expect(command, 'START');
+  int counter = 0;
+  new Timer.periodic(const Duration(milliseconds: 10), (timer) {
+    if (counter == 3) {
+      counter = 1024;
+      timer.cancel();
+      // Wait some more time to be sure callback won't be invoked any
+      // more.
+      new Timer(const Duration(milliseconds: 30), () {
+        replyTo.send('DONE');
+      });
+      return;
+    }
+    assert(counter < 3);
+    counter++;
+  });
+}
diff --git a/tests/lib/html/async_test.dart b/tests/lib/html/async_test.dart
new file mode 100644
index 0000000..7720d5a
--- /dev/null
+++ b/tests/lib/html/async_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library async_test;
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:html';
+
+import 'async_oneshot.dart' as oneshot_test show main;
+import 'async_periodictimer.dart' as periodictimer_test show main;
+import 'async_cancellingisolate.dart' as cancelling_test show main;
+
+oneshot(message) => oneshot_test.main(message.first, message.last);
+periodicTimerIsolate(message) =>
+    periodictimer_test.main(message.first, message.last);
+cancellingIsolate(message) => cancelling_test.main(message.first, message.last);
+
+main() {
+  test('one shot timer in pure isolate', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(oneshot, [
+      ['START'],
+      response.sendPort
+    ]);
+    expect(remote.then((_) => response.first), completion('DONE'));
+  });
+
+  test('periodic timer in pure isolate', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(periodicTimerIsolate, [
+      ['START'],
+      response.sendPort
+    ]);
+    expect(remote.then((_) => response.first), completion('DONE'));
+  });
+
+  test('cancellation in pure isolate', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(cancellingIsolate, [
+      ['START'],
+      response.sendPort
+    ]);
+    expect(remote.then((_) => response.first), completion('DONE'));
+  });
+}
diff --git a/tests/lib/html/audiobuffersourcenode_test.dart b/tests/lib/html/audiobuffersourcenode_test.dart
new file mode 100644
index 0000000..fd6fa86
--- /dev/null
+++ b/tests/lib/html/audiobuffersourcenode_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:web_audio';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(AudioContext.supported, isTrue);
+    });
+  });
+
+  group('functional', () {
+    test('createBuffer', () {
+      if (AudioContext.supported) {
+        var ctx = new AudioContext();
+        AudioBufferSourceNode node = ctx.createBufferSource();
+        expect(node is AudioBufferSourceNode, isTrue);
+        node.start(ctx.currentTime, 0, 2);
+        expect(node is AudioBufferSourceNode, isTrue);
+      }
+    });
+  });
+}
diff --git a/tests/lib/html/audiocontext_test.dart b/tests/lib/html/audiocontext_test.dart
new file mode 100644
index 0000000..8316130
--- /dev/null
+++ b/tests/lib/html/audiocontext_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:typed_data';
+import 'dart:web_audio';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isAudioContext =
+      predicate((x) => x is AudioContext, 'is an AudioContext');
+
+  group('supported', () {
+    test('supported', () {
+      expect(AudioContext.supported, true);
+    });
+  });
+
+  group('functional', () {
+    var context;
+    if (AudioContext.supported) {
+      context = new AudioContext();
+    }
+
+    test('constructorTest', () {
+      if (AudioContext.supported) {
+        expect(context, isNotNull);
+        expect(context, isAudioContext);
+      }
+    });
+
+    test('audioRenames', () {
+      if (AudioContext.supported) {
+        GainNode gainNode = context.createGain();
+        gainNode.connectNode(context.destination);
+        expect(gainNode is GainNode, isTrue);
+
+        expect(context.createAnalyser() is AnalyserNode, isTrue);
+        expect(context.createChannelMerger() is AudioNode, isTrue);
+        expect(context.createChannelSplitter() is AudioNode, isTrue);
+        expect(context.createOscillator() is OscillatorNode, isTrue);
+        expect(context.createPanner() is PannerNode, isTrue);
+        expect(
+            context.createScriptProcessor(4096) is ScriptProcessorNode, isTrue);
+      }
+    });
+
+    // TODO(9322): This test times out.
+    /*
+    test('onAudioProcess', () {
+      if(AudioContext.supported) {
+        var completer = new Completer<bool>();
+        var context = new AudioContext();
+        var scriptProcessor = context.createScriptProcessor(1024, 1, 2);
+        scriptProcessor.connectNode(context.destination);
+        bool alreadyCalled = false;
+        scriptProcessor.onAudioProcess.listen((event) {
+          if (!alreadyCalled) {
+            completer.complete(true);
+          }
+          alreadyCalled = true;
+        });
+        return completer.future;
+      }
+    });
+    */
+
+    test('oscillatorTypes', () {
+      if (AudioContext.supported) {
+        OscillatorNode oscillator = context.createOscillator();
+        oscillator.connectNode(context.destination);
+
+        oscillator.type = 'sawtooth';
+        expect(oscillator.type, equals('sawtooth'));
+
+        oscillator.type = 'sine';
+        expect(oscillator.type, equals('sine'));
+
+        oscillator.type = 'square';
+        expect(oscillator.type, equals('square'));
+
+        oscillator.type = 'triangle';
+        expect(oscillator.type, equals('triangle'));
+
+        //expect(() => oscillator.type = 7, throws); Firefox does not throw, it
+        //simply ignores this value.
+        expect(oscillator.type, equals('triangle'));
+
+        // Firefox does not throw when it receives invalid values; it simply
+        // ignores them.
+        //expect(() => oscillator.type = ['heap object not a string'], throws);
+        expect(oscillator.type, equals('triangle'));
+      }
+    });
+  });
+}
diff --git a/tests/lib/html/audioelement_test.dart b/tests/lib/html/audioelement_test.dart
new file mode 100644
index 0000000..e45f1bc
--- /dev/null
+++ b/tests/lib/html/audioelement_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('constructorTest1', () {
+    var audio = new AudioElement();
+    expect(audio, isNotNull);
+    expect(audio is AudioElement, isTrue);
+  });
+
+  test('constructorTest2', () {
+    var audio = new AudioElement('IntentionallyMissingFileURL');
+    expect(audio, isNotNull);
+    expect(audio is AudioElement, isTrue);
+    expect(audio.src.contains('IntentionallyMissingFileURL'), isTrue);
+  });
+
+  test('canPlayTypeTest', () {
+    var audio = new AudioElement();
+    var canPlay = audio.canPlayType("audio/mp4");
+    expect(canPlay, isNotNull);
+    expect(canPlay is String, isTrue);
+  });
+}
diff --git a/tests/lib/html/b_element_test.dart b/tests/lib/html/b_element_test.dart
new file mode 100644
index 0000000..f60b633
--- /dev/null
+++ b/tests/lib/html/b_element_test.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.
+
+import 'dart:html';
+
+main() {
+  new Element.tag('b');
+}
diff --git a/tests/lib/html/blob_constructor_test.dart b/tests/lib/html/blob_constructor_test.dart
new file mode 100644
index 0000000..d5f5d34
--- /dev/null
+++ b/tests/lib/html/blob_constructor_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('basic', () {
+    var b = new Blob([]);
+    expect(b.size, 0);
+  });
+
+  test('type1', () {
+    // OPTIONALS var b = new Blob(['Harry'], type: 'text');
+    var b = new Blob(['Harry'], 'text');
+    expect(b.size, 5);
+    expect(b.type, 'text');
+  });
+
+  test('endings1', () {
+    // OPTIONALS var b = new Blob(['A\nB\n'], endings: 'transparent');
+    var b = new Blob(['A\nB\n'], null, 'transparent');
+    expect(b.size, 4);
+  });
+
+  test('endings2', () {
+    // OPTIONALS var b = new Blob(['A\nB\n'], endings: 'native');
+    var b = new Blob(['A\nB\n'], null, 'native');
+    expect(b.size, predicate((x) => x == 4 || x == 6),
+        reason: "b.size should be 4 or 6");
+  });
+
+  test('twoStrings', () {
+    // OPTIONALS var b = new Blob(['123', 'xyz'], type: 'text/plain;charset=UTF-8');
+    var b = new Blob(['123', 'xyz'], 'text/plain;charset=UTF-8');
+    expect(b.size, 6);
+  });
+
+  test('fromBlob1', () {
+    var b1 = new Blob([]);
+    var b2 = new Blob([b1]);
+    expect(b2.size, 0);
+  });
+
+  test('fromBlob2', () {
+    var b1 = new Blob(['x']);
+    var b2 = new Blob([b1, b1]);
+    expect(b1.size, 1);
+    expect(b2.size, 2);
+  });
+
+  test('fromArrayBuffer', () {
+    var a = new Uint8List(100).buffer; // i.e. new ArrayBuffer(100);
+    var b = new Blob([a, a]);
+    expect(b.size, 200);
+  });
+}
diff --git a/tests/lib/html/cache_test.dart b/tests/lib/html/cache_test.dart
new file mode 100644
index 0000000..2e0991b
--- /dev/null
+++ b/tests/lib/html/cache_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(ApplicationCache.supported, isTrue);
+    });
+  });
+
+  group('ApplicationCache', () {
+    test('ApplicationCache', () {
+      var expectation = ApplicationCache.supported ? returnsNormally : throws;
+      expect(() {
+        ApplicationCache appCache = window.applicationCache;
+        expect(cacheStatusToString(appCache.status), "UNCACHED");
+      }, expectation);
+    });
+  });
+}
+
+String cacheStatusToString(int status) {
+  switch (status) {
+    case ApplicationCache.UNCACHED: // UNCACHED == 0
+      return 'UNCACHED';
+    case ApplicationCache.IDLE: // IDLE == 1
+      return 'IDLE';
+    case ApplicationCache.CHECKING: // CHECKING == 2
+      return 'CHECKING';
+    case ApplicationCache.DOWNLOADING: // DOWNLOADING == 3
+      return 'DOWNLOADING';
+    case ApplicationCache.UPDATEREADY: // UPDATEREADY == 4
+      return 'UPDATEREADY';
+    case ApplicationCache.OBSOLETE: // OBSOLETE == 5
+      return 'OBSOLETE';
+    default:
+      return 'UNKNOWN CACHE STATUS';
+  }
+  ;
+}
diff --git a/tests/lib/html/callback_list_test.dart b/tests/lib/html/callback_list_test.dart
new file mode 100644
index 0000000..d6390b1
--- /dev/null
+++ b/tests/lib/html/callback_list_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library callback_list_test;
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:expect/minitest.dart';
+
+var callbackDone = false;
+bool isCallbackDone() => callbackDone;
+
+Future waitUntilCallbackDone(bool test()) async {
+  var completer = new Completer();
+  check() {
+    if (test()) {
+      completer.complete();
+    } else {
+      new Timer(Duration.zero, check);
+    }
+  }
+
+  check();
+  return completer.future;
+}
+
+void main() async {
+  window.navigator.persistentStorage.requestQuota(1024 * 1024, _quotaHandler);
+
+  await waitUntilCallbackDone(isCallbackDone);
+  expect(true, isCallbackDone());
+}
+
+Future _quotaHandler(int byteCount) async {
+  FileSystem filesystem =
+      await window.requestFileSystem(1024 * 1024, persistent: true);
+  DirectoryEntry dir = await filesystem.root;
+  DirectoryReader dirReader = dir.createReader();
+  await dirReader.readEntries();
+  List<Entry> secondEntries = await dirReader.readEntries();
+  callbackDone = true;
+}
diff --git a/tests/lib/html/callbacks_test.dart b/tests/lib/html/callbacks_test.dart
new file mode 100644
index 0000000..e7402fe
--- /dev/null
+++ b/tests/lib/html/callbacks_test.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.
+
+import 'dart:html';
+
+main() {
+  window.requestAnimationFrame((num time) => false);
+}
diff --git a/tests/lib/html/canvas_pixel_array_type_alias_test.dart b/tests/lib/html/canvas_pixel_array_type_alias_test.dart
new file mode 100644
index 0000000..3c992de
--- /dev/null
+++ b/tests/lib/html/canvas_pixel_array_type_alias_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+// We have aliased the legacy type CanvasPixelArray with the new type
+// Uint8ClampedArray by mapping the CanvasPixelArray type tag to
+// Uint8ClampedArray.  It is not a perfect match since CanvasPixelArray is
+// missing the ArrayBufferView members.  These should appear to be null.
+
+var inscrutable;
+
+main() {
+  inscrutable = (x) => x;
+
+  int width = 100;
+  int height = 100;
+
+  CanvasElement canvas = new CanvasElement(width: width, height: height);
+  document.body!.append(canvas);
+
+  CanvasRenderingContext2D context = canvas.context2D;
+
+  group('basic', () {
+    test('CreateImageData', () {
+      ImageData image = context.createImageData(canvas.width, canvas.height);
+      List<int> data = image.data;
+      // It is legal for the dart2js compiler to believe the type of the native
+      //   ImageData.data and elides the check, so check the type explicitly:
+      expect(inscrutable(data) is List<int>, isTrue,
+          reason: 'canvas array type');
+
+      expect(data.length, 40000);
+      checkPixel(data, 0, [0, 0, 0, 0]);
+      checkPixel(data, width * height - 1, [0, 0, 0, 0]);
+
+      data[100] = 200;
+      expect(data[100], equals(200));
+    });
+  });
+
+  group('types1', () {
+    test('isList', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is List, true);
+    });
+
+    test('isListT_pos', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is List<int>, true);
+    });
+  });
+
+  group('types2', () {
+    test('isListT_neg', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is List<String>, false);
+    });
+
+    test('isUint8ClampedList', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is Uint8ClampedList, true);
+    });
+
+    test('consistent_isUint8ClampedList', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      // Static and dynamic values consistent?  Type inference should be able to
+      // constant-fold 'data is Uint8ClampedList' to 'true'.
+      expect(inscrutable(data) is Uint8ClampedList == data is Uint8ClampedList,
+          isTrue);
+    });
+
+    // TODO(sra): Why does this fail on Dartium? There are two types with the
+    // same print string:
+    //
+    //     Expected: ?:<Uint8ClampedList> Actual: ?:<Uint8ClampedList>
+    /*
+    test('runtimeType', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data).runtimeType, Uint8ClampedList);
+    });
+    */
+
+    test('consistent_runtimeType', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data).runtimeType == data.runtimeType, isTrue);
+    });
+  });
+
+  group('types2_runtimeTypeName', () {
+    test('runtimeTypeName', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect('${inscrutable(data).runtimeType}', 'Uint8ClampedList');
+    });
+  });
+
+  group('typed_data', () {
+    test('elementSizeInBytes', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data).elementSizeInBytes, 1);
+    });
+  });
+}
+
+void checkPixel(List<int> data, int offset, List<int> rgba) {
+  offset *= 4;
+  for (var i = 0; i < 4; ++i) {
+    expect(rgba[i], equals(data[offset + i]));
+  }
+}
diff --git a/tests/lib/html/canvas_test.dart b/tests/lib/html/canvas_test.dart
new file mode 100644
index 0000000..dd3910f
--- /dev/null
+++ b/tests/lib/html/canvas_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library CanvasTest;
+
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  CanvasElement canvas;
+  CanvasRenderingContext2D context;
+  int width = 100;
+  int height = 100;
+
+  canvas = new CanvasElement(width: width, height: height);
+  document.body!.append(canvas);
+
+  context = canvas.context2D;
+
+  test('CreateImageData', () {
+    ImageData image = context.createImageData(canvas.width, canvas.height);
+    List<int> data = image.data;
+
+    expect(data.length, 40000);
+    checkPixel(data, 0, [0, 0, 0, 0]);
+    checkPixel(data, width * height - 1, [0, 0, 0, 0]);
+
+    data[100] = 200;
+    expect(data[100], equals(200));
+  });
+
+  test('toDataUrl', () {
+    var canvas = new CanvasElement(width: 100, height: 100);
+    var context = canvas.context2D;
+    context.fillStyle = 'red';
+    context.fill();
+
+    var url = canvas.toDataUrl();
+
+    var img = new ImageElement();
+    img.onLoad.listen(expectAsync((_) {
+      expect(img.complete, true);
+    }));
+    img.onError.listen((_) {
+      fail('URL failed to load.');
+    });
+    img.src = url;
+  });
+}
+
+void checkPixel(List<int> data, int offset, List<int> rgba) {
+  offset *= 4;
+  for (var i = 0; i < 4; ++i) {
+    expect(data[offset + i], equals(rgba[i]));
+  }
+}
diff --git a/tests/lib/html/canvasrendering/arc_test.dart b/tests/lib/html/canvasrendering/arc_test.dart
new file mode 100644
index 0000000..d60fb1e
--- /dev/null
+++ b/tests/lib/html/canvasrendering/arc_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:html';
+import 'dart:math';
+
+import 'canvas_rendering_util.dart';
+import 'package:expect/minitest.dart';
+
+main() {
+  setUp(setupFunc);
+  tearDown(tearDownFunc);
+
+  test('default arc should be clockwise', () {
+    context.beginPath();
+    final r = 10;
+
+    // Center of arc.
+    final cx = 20;
+    final cy = 20;
+    // Arc centered at (20, 20) with radius 10 will go clockwise
+    // from (20 + r, 20) to (20, 20 + r), which is 1/4 of a circle.
+    context.arc(cx, cy, r, 0, pi / 2);
+
+    context.strokeStyle = 'green';
+    context.lineWidth = 2;
+    context.stroke();
+
+    // Center should not be filled.
+    expectPixelUnfilled(cx, cy);
+
+    // (cx + r, cy) should be filled.
+    expectPixelFilled(cx + r, cy, true);
+    // (cx, cy + r) should be filled.
+    expectPixelFilled(cx, cy + r, true);
+    // (cx - r, cy) should be empty.
+    expectPixelFilled(cx - r, cy, false);
+    // (cx, cy - r) should be empty.
+    expectPixelFilled(cx, cy - r, false);
+
+    // (cx + r/SQRT2, cy + r/SQRT2) should be filled.
+    expectPixelFilled((cx + r / sqrt2).toInt(), (cy + r / sqrt2).toInt(), true);
+
+    // (cx - r/SQRT2, cy - r/SQRT2) should be empty.
+    expectPixelFilled(
+        (cx - r / sqrt2).toInt(), (cy + r / sqrt2).toInt(), false);
+
+    // (cx + r/SQRT2, cy + r/SQRT2) should be empty.
+    expectPixelFilled(
+        (cx - r / sqrt2).toInt(), (cy - r / sqrt2).toInt(), false);
+
+    // (cx - r/SQRT2, cy - r/SQRT2) should be empty.
+    expectPixelFilled(
+        (cx + r / sqrt2).toInt(), (cy - r / sqrt2).toInt(), false);
+  });
+
+  test('arc anticlockwise', () {
+    context.beginPath();
+    final r = 10;
+
+    // Center of arc.
+    final cx = 20;
+    final cy = 20;
+    // Arc centered at (20, 20) with radius 10 will go anticlockwise
+    // from (20 + r, 20) to (20, 20 + r), which is 3/4 of a circle.
+    // Because of the way arc work, when going anti-clockwise, the end points
+    // are not included, so small values are added to radius to make a little
+    // more than a 3/4 circle.
+    context.arc(cx, cy, r, .1, pi / 2 - .1, true);
+
+    context.strokeStyle = 'green';
+    context.lineWidth = 2;
+    context.stroke();
+
+    // Center should not be filled.
+    expectPixelUnfilled(cx, cy);
+
+    // (cx + r, cy) should be filled.
+    expectPixelFilled(cx + r, cy, true);
+    // (cx, cy + r) should be filled.
+    expectPixelFilled(cx, cy + r, true);
+    // (cx - r, cy) should be filled.
+    expectPixelFilled(cx - r, cy, true);
+    // (cx, cy - r) should be filled.
+    expectPixelFilled(cx, cy - r, true);
+
+    // (cx + r/SQRT2, cy + r/SQRT2) should be empty.
+    expectPixelFilled(
+        (cx + r / sqrt2).toInt(), (cy + r / sqrt2).toInt(), false);
+
+    // (cx - r/SQRT2, cy - r/SQRT2) should be filled.
+    expectPixelFilled((cx - r / sqrt2).toInt(), (cy + r / sqrt2).toInt(), true);
+
+    // (cx + r/SQRT2, cy + r/SQRT2) should be filled.
+    expectPixelFilled((cx - r / sqrt2).toInt(), (cy - r / sqrt2).toInt(), true);
+
+    // (cx - r/SQRT2, cy - r/SQRT2) should be filled.
+    expectPixelFilled((cx + r / sqrt2).toInt(), (cy - r / sqrt2).toInt(), true);
+  });
+}
diff --git a/tests/lib/html/canvasrendering/canvas_rendering_util.dart b/tests/lib/html/canvasrendering/canvas_rendering_util.dart
new file mode 100644
index 0000000..037da9e
--- /dev/null
+++ b/tests/lib/html/canvasrendering/canvas_rendering_util.dart
@@ -0,0 +1,80 @@
+// 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.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:html';
+import 'dart:math';
+
+import 'package:expect/minitest.dart';
+
+// Some rounding errors in the browsers.
+checkPixel(List<int> pixel, List<int> expected) {
+  expect(pixel[0], closeTo(expected[0], 2));
+  expect(pixel[1], closeTo(expected[1], 2));
+  expect(pixel[2], closeTo(expected[2], 2));
+  expect(pixel[3], closeTo(expected[3], 2));
+}
+
+var canvas;
+var context;
+var otherCanvas;
+var otherContext;
+var video;
+
+void createCanvas() {
+  canvas = new CanvasElement();
+  canvas.width = 100;
+  canvas.height = 100;
+
+  context = canvas.context2D;
+}
+
+void createOtherCanvas() {
+  otherCanvas = new CanvasElement();
+  otherCanvas.width = 10;
+  otherCanvas.height = 10;
+  otherContext = otherCanvas.context2D;
+  otherContext.fillStyle = "red";
+  otherContext.fillRect(0, 0, otherCanvas.width, otherCanvas.height);
+}
+
+void setupFunc() {
+  createCanvas();
+  createOtherCanvas();
+  video = new VideoElement();
+}
+
+void tearDownFunc() {
+  canvas = null;
+  context = null;
+  otherCanvas = null;
+  otherContext = null;
+  video = null;
+}
+
+List<int> readPixel(int x, int y) {
+  var imageData = context.getImageData(x, y, 1, 1);
+  return imageData.data;
+}
+
+/// Returns true if the pixel has some data in it, false otherwise.
+bool isPixelFilled(int x, int y) => readPixel(x, y).any((p) => p != 0);
+
+String pixelDataToString(List<int> data, int x, int y) {
+  return '[${data.join(", ")}]';
+}
+
+String _filled(bool v) => v ? "filled" : "unfilled";
+
+void expectPixelFilled(int x, int y, [bool filled = true]) {
+  expect(isPixelFilled(x, y), filled,
+      reason: 'Pixel at ($x, $y) was expected to'
+          ' be: <${_filled(filled)}> but was: <${_filled(!filled)}> with data: '
+          '${pixelDataToString(readPixel(x, y), x, y)}');
+}
+
+void expectPixelUnfilled(int x, int y) {
+  expectPixelFilled(x, y, false);
+}
diff --git a/tests/lib/html/canvasrendering/draw_image_canvas_element_test.dart b/tests/lib/html/canvasrendering/draw_image_canvas_element_test.dart
new file mode 100644
index 0000000..942c8f6
--- /dev/null
+++ b/tests/lib/html/canvasrendering/draw_image_canvas_element_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:html';
+import 'dart:math';
+
+import 'canvas_rendering_util.dart';
+import 'package:expect/minitest.dart';
+
+main() {
+  setUp(setupFunc);
+  tearDown(tearDownFunc);
+
+  test('with 3 params', () {
+    // Draw an image to the canvas from a canvas element.
+    context.drawImage(otherCanvas, 50, 50);
+
+    expectPixelFilled(50, 50);
+    expectPixelFilled(55, 55);
+    expectPixelFilled(59, 59);
+    expectPixelUnfilled(60, 60);
+    expectPixelUnfilled(0, 0);
+    expectPixelUnfilled(70, 70);
+  });
+  test('with 5 params', () {
+    // Draw an image to the canvas from a canvas element.
+    context.drawImageToRect(otherCanvas, new Rectangle(50, 50, 20, 20));
+
+    expectPixelFilled(50, 50);
+    expectPixelFilled(55, 55);
+    expectPixelFilled(59, 59);
+    expectPixelFilled(60, 60);
+    expectPixelFilled(69, 69);
+    expectPixelUnfilled(70, 70);
+    expectPixelUnfilled(0, 0);
+    expectPixelUnfilled(80, 80);
+  });
+  test('with 9 params', () {
+    // Draw an image to the canvas from a canvas element.
+    otherContext.fillStyle = "blue";
+    otherContext.fillRect(5, 5, 5, 5);
+    context.drawImageToRect(otherCanvas, new Rectangle(50, 50, 20, 20),
+        sourceRect: new Rectangle(2, 2, 6, 6));
+
+    checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
+    checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
+    checkPixel(readPixel(60, 50), [255, 0, 0, 255]);
+    checkPixel(readPixel(65, 65), [0, 0, 255, 255]);
+    checkPixel(readPixel(69, 69), [0, 0, 255, 255]);
+    expectPixelFilled(50, 50);
+    expectPixelFilled(55, 55);
+    expectPixelFilled(59, 59);
+    expectPixelFilled(60, 60);
+    expectPixelFilled(69, 69);
+    expectPixelUnfilled(70, 70);
+    expectPixelUnfilled(0, 0);
+    expectPixelUnfilled(80, 80);
+  });
+
+  test('createImageData', () {
+    var imageData = context.createImageData(15, 15);
+    expect(imageData.width, 15);
+    expect(imageData.height, 15);
+
+    var other = context.createImageDataFromImageData(imageData);
+    expect(other.width, 15);
+    expect(other.height, 15);
+  });
+
+  test('createPattern', () {
+    var pattern = context.createPattern(new CanvasElement(), '');
+    //var pattern2 = context.createPatternFromImage(new ImageElement(), '');
+  });
+}
diff --git a/tests/lib/html/canvasrendering/draw_image_video_element_test.dart b/tests/lib/html/canvasrendering/draw_image_video_element_test.dart
new file mode 100644
index 0000000..9ae591e
--- /dev/null
+++ b/tests/lib/html/canvasrendering/draw_image_video_element_test.dart
@@ -0,0 +1,223 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:math';
+
+import 'canvas_rendering_util.dart';
+import 'package:async_helper/async_helper.dart';
+
+// These videos and base64 strings are the same video, representing 2
+// frames of 8x8 red pixels.
+// The videos were created with:
+//   convert -size 8x8 xc:red blank1.jpg
+//   convert -size 8x8 xc:red blank2.jpg
+//   avconv -f image2  -i "blank%d.jpg" -c:v libx264 small.mp4
+//   avconv -i small.mp4 small.webm
+//   python -m base64 -e small.mp4
+//   python -m base64 -e small.webm
+var mp4VideoUrl = '/root_dart/tests/lib/html/small.mp4';
+var webmVideoUrl = '/root_dart/tests/lib/html/small.webm';
+var mp4VideoDataUrl =
+    'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAA'
+    'AIZnJlZQAAAsdtZGF0AAACmwYF//+X3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlID'
+    'EyMCByMjE1MSBhM2Y0NDA3IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZW'
+    'Z0IDIwMDMtMjAxMSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG'
+    '9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweD'
+    'ExMSBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj'
+    '0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MCBjcW09MC'
+    'BkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aH'
+    'JlYWRzPTE4IHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZW'
+    'Q9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl'
+    '9weXJhbWlkPTAgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MCBvcG'
+    'VuX2dvcD0xIHdlaWdodHA9MiBrZXlpbnQ9MjUwIGtleWludF9taW49MjUgc2NlbmVjdX'
+    'Q9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPT'
+    'EgY3JmPTUxLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IGlwX3'
+    'JhdGlvPTEuMjUgYXE9MToxLjAwAIAAAAARZYiEB//3aoK5/tP9+8yeuIEAAAAHQZoi2P'
+    '/wgAAAAzxtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAAUAABAAABAAAAAAAAAA'
+    'AAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAA'
+    'AAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT/////7/AAACUHRyYWsAAA'
+    'BcdGtoZAAAAA8AAAAAAAAAAAAAAAEAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAQAAAA'
+    'AAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAACAAAAAgAAAAAACRlZHRzAAAAHG'
+    'Vsc3QAAAAAAAAAAQAAAFAAAAABAAEAAAAAAchtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAA'
+    'AAAAAZAAAAAlXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSG'
+    'FuZGxlcgAAAAFzbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZg'
+    'AAAAAAAAABAAAADHVybCAAAAABAAABM3N0YmwAAACXc3RzZAAAAAAAAAABAAAAh2F2Yz'
+    'EAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAACAAIAEgAAABIAAAAAAAAAAEAAAAAAAAAAA'
+    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwFNQAr/4QAYZ01ACuiPyy'
+    '4C2QAAAwABAAADADIPEiUSAQAGaOvAZSyAAAAAGHN0dHMAAAAAAAAAAQAAAAIAAAABAA'
+    'AAFHN0c3MAAAAAAAAAAQAAAAEAAAAYY3R0cwAAAAAAAAABAAAAAgAAAAEAAAAcc3RzYw'
+    'AAAAAAAAABAAAAAQAAAAEAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAK0AAAACwAAAB'
+    'hzdGNvAAAAAAAAAAIAAAAwAAAC5AAAAGB1ZHRhAAAAWG1ldGEAAAAAAAAAIWhkbHIAAA'
+    'AAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqXRvbwAAABtkYXRhAAAAAQ'
+    'AAAABMYXZmNTMuMjEuMQ==';
+var webmVideoDataUrl =
+    'data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlY'
+    'm1Ch4ECQoWBAhhTgGcBAAAAAAAB/hFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua'
+    '1OsggEsTbuMU6uEHFO7a1OsggHk7AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAA'
+    'EEq17GDD0JATYCLTGF2ZjUzLjIxLjFXQYtMYXZmNTMuMjEuMXOkkJatuHwTJ7cvFLSzB'
+    'Smxbp5EiYhAVAAAAAAAABZUrmsBAAAAAAAAR64BAAAAAAAAPteBAXPFgQGcgQAitZyDd'
+    'W5khoVWX1ZQOIOBASPjg4QCYloA4AEAAAAAAAASsIEIuoEIVLCBCFS6gQhUsoEDH0O2d'
+    'QEAAAAAAABZ54EAo72BAACA8AIAnQEqCAAIAABHCIWFiIWEiAICAnWqA/gD+gINTRgA/'
+    'v0hRf/kb+PnRv/I4//8WE8DijI//FRAo5WBACgAsQEAARAQABgAGFgv9AAIAAAcU7trA'
+    'QAAAAAAAA67jLOBALeH94EB8YIBfw==';
+
+Future testWithThreeParams() async {
+  setupFunc();
+
+  video.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+  if (video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+    video.src = webmVideoUrl;
+  } else if (video.canPlayType(
+          'video/mp4; codecs="avc1.4D401E, mp4a.40.2"', null) !=
+      '') {
+    video.src = mp4VideoUrl;
+  } else {
+    window.console.log('Video is not supported on this system.');
+  }
+
+  // Without user interaction, playing the video requires autoplay to be enabled
+  // and autoplay can only be enabled if muted. We loop the video so there is
+  // always an active frame that can be drawn.
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
+  context.drawImage(video, 50, 50);
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(54, 54);
+  expectPixelFilled(57, 57);
+  expectPixelUnfilled(58, 58);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(70, 70);
+  tearDownFunc();
+}
+
+Future testWithFiveParams() async {
+  setupFunc();
+
+  video.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+
+  if (video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+    video.src = webmVideoUrl;
+  } else if (video.canPlayType(
+          'video/mp4; codecs="avc1.4D401E, mp4a.40.2"', null) !=
+      '') {
+    video.src = mp4VideoUrl;
+  } else {
+    // TODO(amouravski): Better fallback?
+    window.console.log('Video is not supported on this system.');
+  }
+
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
+  context.drawImageToRect(video, new Rectangle(50, 50, 20, 20));
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(55, 55);
+  expectPixelFilled(59, 59);
+  expectPixelFilled(60, 60);
+  expectPixelFilled(69, 69);
+  expectPixelUnfilled(70, 70);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(80, 80);
+  tearDownFunc();
+}
+
+Future testWithNineParams() async {
+  setupFunc();
+
+  video.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+
+  if (video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+    video.src = webmVideoUrl;
+  } else if (video.canPlayType(
+          'video/mp4; codecs="avc1.4D401E, mp4a.40.2"', null) !=
+      '') {
+    video.src = mp4VideoUrl;
+  } else {
+    // TODO(amouravski): Better fallback?
+    window.console.log('Video is not supported on this system.');
+  }
+
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
+  context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
+      sourceRect: new Rectangle(2, 2, 6, 6));
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(55, 55);
+  expectPixelFilled(59, 59);
+  expectPixelFilled(60, 60);
+  expectPixelFilled(69, 69);
+  expectPixelUnfilled(70, 70);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(80, 80);
+  tearDownFunc();
+}
+
+Future testDataUrlWithNineParams() async {
+  setupFunc();
+
+  video = new VideoElement();
+  canvas = new CanvasElement();
+
+  video.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+
+  if (video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+    video.src = webmVideoDataUrl;
+  } else if (video.canPlayType(
+          'video/mp4; codecs="avc1.4D401E, mp4a.40.2"', null) !=
+      '') {
+    video.src = mp4VideoDataUrl;
+  } else {
+    // TODO(amouravski): Better fallback?
+    window.console.log('Video is not supported on this system.');
+  }
+
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
+  context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
+      sourceRect: new Rectangle(2, 2, 6, 6));
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(55, 55);
+  expectPixelFilled(59, 59);
+  expectPixelFilled(60, 60);
+  expectPixelFilled(69, 69);
+  expectPixelUnfilled(70, 70);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(80, 80);
+  tearDownFunc();
+}
+
+main() {
+  asyncTest(() async {
+    await testWithThreeParams();
+    await testWithFiveParams();
+    await testWithNineParams();
+    await testDataUrlWithNineParams();
+  });
+}
diff --git a/tests/lib/html/canvasrendering/fill_text_test.dart b/tests/lib/html/canvasrendering/fill_text_test.dart
new file mode 100644
index 0000000..49e3c17
--- /dev/null
+++ b/tests/lib/html/canvasrendering/fill_text_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:html';
+import 'dart:math';
+
+import 'canvas_rendering_util.dart';
+import 'package:expect/minitest.dart';
+
+main() {
+  setUp(setupFunc);
+  tearDown(tearDownFunc);
+
+  final x = 20;
+  final y = 20;
+
+  test('without maxWidth', () {
+    context.font = '40pt Garamond';
+    context.fillStyle = 'blue';
+
+    // Draw a blue box.
+    context.fillText('█', x, y);
+
+    var width = context.measureText('█').width.ceil();
+
+    checkPixel(readPixel(x, y), [0, 0, 255, 255]);
+    checkPixel(readPixel(x + 10, y), [0, 0, 255, 255]);
+
+    expectPixelUnfilled(x - 10, y);
+    expectPixelFilled(x, y);
+    expectPixelFilled(x + 10, y);
+
+    // The box does not draw after `width` pixels.
+    // Check -2 rather than -1 because this seems
+    // to run into a rounding error on Mac bots.
+    expectPixelFilled((x + width - 2).toInt(), y);
+    expectPixelUnfilled((x + width + 1).toInt(), y);
+  });
+
+  test('with maxWidth null', () {
+    context.font = '40pt Garamond';
+    context.fillStyle = 'blue';
+
+    // Draw a blue box with null maxWidth.
+    context.fillText('█', x, y, null);
+
+    var width = context.measureText('█').width.ceil();
+
+    checkPixel(readPixel(x, y), [0, 0, 255, 255]);
+    checkPixel(readPixel(x + 10, y), [0, 0, 255, 255]);
+
+    expectPixelUnfilled(x - 10, y);
+    expectPixelFilled(x, y);
+    expectPixelFilled(x + 10, y);
+
+    // The box does not draw after `width` pixels.
+    // Check -2 rather than -1 because this seems
+    // to run into a rounding error on Mac bots.
+    expectPixelFilled((x + width - 2).toInt(), y);
+    expectPixelUnfilled((x + width + 1).toInt(), y);
+  });
+
+  test('with maxWidth defined', () {
+    context.font = '40pt Garamond';
+    context.fillStyle = 'blue';
+
+    final maxWidth = 20;
+
+    // Draw a blue box that's at most 20 pixels wide.
+    context.fillText('█', x, y, maxWidth);
+
+    checkPixel(readPixel(x, y), [0, 0, 255, 255]);
+    checkPixel(readPixel(x + 10, y), [0, 0, 255, 255]);
+
+    // The box does not draw after 20 pixels.
+    expectPixelUnfilled(x - 10, y);
+    expectPixelUnfilled(x + maxWidth + 1, y);
+    expectPixelUnfilled(x + maxWidth + 20, y);
+    expectPixelFilled(x, y);
+    expectPixelFilled(x + 10, y);
+  });
+}
diff --git a/tests/lib/html/canvasrendering/image_element_test.dart b/tests/lib/html/canvasrendering/image_element_test.dart
new file mode 100644
index 0000000..a1d8040
--- /dev/null
+++ b/tests/lib/html/canvasrendering/image_element_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:math';
+
+import 'canvas_rendering_util.dart';
+import 'package:async_helper/async_helper.dart';
+
+Future testWithThreeParams() async {
+  setupFunc();
+  // Draw an image to the canvas from an image element.
+  var dataUrl = otherCanvas.toDataUrl('image/gif');
+  var img = new ImageElement();
+
+  var loadedFuture = img.onLoad.first;
+  img.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+  img.src = dataUrl;
+
+  await loadedFuture;
+  context.drawImage(img, 50, 50);
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(55, 55);
+  expectPixelFilled(59, 59);
+  expectPixelUnfilled(60, 60);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(70, 70);
+  tearDownFunc();
+}
+
+Future testWithFiveParams() async {
+  setupFunc();
+  // Draw an image to the canvas from an image element and scale it.
+  var dataUrl = otherCanvas.toDataUrl('image/gif');
+  var img = new ImageElement();
+
+  var loadedFuture = img.onLoad.first;
+  img.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+  img.src = dataUrl;
+
+  await loadedFuture;
+  context.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(55, 55);
+  expectPixelFilled(59, 59);
+  expectPixelFilled(60, 60);
+  expectPixelFilled(69, 69);
+  expectPixelUnfilled(70, 70);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(80, 80);
+  tearDownFunc();
+}
+
+Future testWithNineParams() async {
+  setupFunc();
+  // Draw an image to the canvas from an image element and scale it.
+  otherContext.fillStyle = "blue";
+  otherContext.fillRect(5, 5, 5, 5);
+  var dataUrl = otherCanvas.toDataUrl('image/gif');
+  var img = new ImageElement();
+
+  var loadedFuture = img.onLoad.first;
+  img.onError.listen((_) {
+    throw ('URL failed to load.');
+  });
+  img.src = dataUrl;
+
+  await loadedFuture;
+  // This will take a 6x6 square from the first canvas from position 2,2
+  // and then scale it to a 20x20 square and place it to the second
+  // canvas at 50,50.
+  context.drawImageToRect(img, new Rectangle(50, 50, 20, 20),
+      sourceRect: new Rectangle(2, 2, 6, 6));
+
+  checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
+  checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
+  checkPixel(readPixel(60, 50), [255, 0, 0, 255]);
+  checkPixel(readPixel(65, 65), [0, 0, 255, 255]);
+  checkPixel(readPixel(69, 69), [0, 0, 255, 255]);
+
+  expectPixelFilled(50, 50);
+  expectPixelFilled(55, 55);
+  expectPixelFilled(59, 59);
+  expectPixelFilled(60, 60);
+  expectPixelFilled(69, 69);
+  expectPixelUnfilled(70, 70);
+  expectPixelUnfilled(0, 0);
+  expectPixelUnfilled(80, 80);
+  tearDownFunc();
+}
+
+main() {
+  asyncTest(() async {
+    await testWithThreeParams();
+    await testWithFiveParams();
+    await testWithNineParams();
+  });
+}
diff --git a/tests/lib/html/canvasrendering/pixel_manipulation_test.dart b/tests/lib/html/canvasrendering/pixel_manipulation_test.dart
new file mode 100644
index 0000000..586072a
--- /dev/null
+++ b/tests/lib/html/canvasrendering/pixel_manipulation_test.dart
@@ -0,0 +1,171 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library canvas_rendering_context_2d_test;
+
+import 'dart:html';
+import 'dart:math';
+
+import 'canvas_rendering_util.dart';
+import 'package:expect/minitest.dart';
+
+main() {
+  setUp(setupFunc);
+  tearDown(tearDownFunc);
+
+  test('setFillColorRgb', () {
+    context.setFillColorRgb(255, 0, 255, 1);
+    context.fillRect(0, 0, canvas.width, canvas.height);
+    expect(readPixel(2, 2), [255, 0, 255, 255]);
+  });
+
+  test('setFillColorHsl hue', () {
+    context.setFillColorHsl(0, 100, 50);
+    context.fillRect(0, 0, canvas.width, canvas.height);
+    checkPixel(readPixel(2, 2), [255, 0, 0, 255]);
+  });
+
+  test('setFillColorHsl hue 2', () {
+    context.setFillColorHsl(240, 100, 50);
+    context.fillRect(0, 0, canvas.width, canvas.height);
+    checkPixel(readPixel(2, 2), [0, 0, 255, 255]);
+  });
+
+  test('setFillColorHsl sat', () {
+    context.setFillColorHsl(0, 0, 50);
+    context.fillRect(0, 0, canvas.width, canvas.height);
+    checkPixel(readPixel(2, 2), [127, 127, 127, 255]);
+  });
+
+  test('setStrokeColorRgb', () {
+    context.setStrokeColorRgb(255, 0, 255, 1);
+    context.lineWidth = 10;
+    context.strokeRect(0, 0, canvas.width, canvas.height);
+    expect(readPixel(2, 2), [255, 0, 255, 255]);
+  });
+
+  test('setStrokeColorHsl hue', () {
+    context.setStrokeColorHsl(0, 100, 50);
+    context.lineWidth = 10;
+    context.strokeRect(0, 0, canvas.width, canvas.height);
+    expect(readPixel(2, 2), [255, 0, 0, 255]);
+  });
+
+  test('setStrokeColorHsl hue 2', () {
+    context.setStrokeColorHsl(240, 100, 50);
+    context.lineWidth = 10;
+    context.strokeRect(0, 0, canvas.width, canvas.height);
+    expect(readPixel(2, 2), [0, 0, 255, 255]);
+  });
+
+  test('setStrokeColorHsl sat', () {
+    context.setStrokeColorHsl(0, 0, 50);
+    context.lineWidth = 10;
+    context.strokeRect(0, 0, canvas.width, canvas.height);
+    checkPixel(readPixel(2, 2), [127, 127, 127, 255]);
+  });
+
+  test('fillStyle', () {
+    context.fillStyle = "red";
+    context.fillRect(0, 0, canvas.width, canvas.height);
+    checkPixel(readPixel(2, 2), [255, 0, 0, 255]);
+  });
+
+  test('strokeStyle', () {
+    context.strokeStyle = "blue";
+    context.lineWidth = 10;
+    context.strokeRect(0, 0, canvas.width, canvas.height);
+    expect(readPixel(2, 2), [0, 0, 255, 255]);
+  });
+
+  test('fillStyle linearGradient', () {
+    var gradient = context.createLinearGradient(0, 0, 20, 20);
+    gradient.addColorStop(0, 'red');
+    gradient.addColorStop(1, 'blue');
+    context.fillStyle = gradient;
+    context.fillRect(0, 0, canvas.width, canvas.height);
+    expect(context.fillStyle is CanvasGradient, isTrue);
+  });
+
+  test('putImageData', () {
+    context.fillStyle = 'green';
+    context.fillRect(0, 0, canvas.width, canvas.height);
+
+    ImageData expectedData = context.getImageData(0, 0, 10, 10);
+    expectedData.data[0] = 25;
+    expectedData.data[1] = 65;
+    expectedData.data[2] = 255;
+    // Set alpha to 255 to make the pixels show up.
+    expectedData.data[3] = 255;
+
+    context.putImageData(expectedData, 0, 0);
+
+    var resultingData = context.getImageData(0, 0, 10, 10);
+    // Make sure that we read back what we wrote.
+    expect(resultingData.data, expectedData.data);
+  });
+
+  test('putImageData dirty rectangle', () {
+    context.fillStyle = 'green';
+    context.fillRect(0, 0, canvas.width, canvas.height);
+
+    ImageData drawnData = context.getImageData(0, 0, 10, 10);
+    drawnData.data[0] = 25;
+    drawnData.data[1] = 65;
+    drawnData.data[2] = 255;
+    drawnData.data[3] = 255;
+
+    // Draw these pixels to the 2nd pixel.
+    drawnData.data[2 * 4 + 0] = 25;
+    drawnData.data[2 * 4 + 1] = 65;
+    drawnData.data[2 * 4 + 2] = 255;
+    drawnData.data[2 * 4 + 3] = 255;
+
+    // Draw these pixels to the 8th pixel.
+    drawnData.data[7 * 4 + 0] = 25;
+    drawnData.data[7 * 4 + 1] = 65;
+    drawnData.data[7 * 4 + 2] = 255;
+    drawnData.data[7 * 4 + 3] = 255;
+
+    // Use a dirty rectangle to limit what pixels are drawn.
+    context.putImageData(drawnData, 0, 0, 1, 0, 5, 5);
+
+    // Expect the data to be all green, as we skip all drawn pixels.
+    ImageData expectedData = context.createImageData(10, 10);
+    for (int i = 0; i < expectedData.data.length; i++) {
+      switch (i % 4) {
+        case 0:
+          expectedData.data[i] = 0;
+          break;
+        case 1:
+          expectedData.data[i] = 128;
+          break;
+        case 2:
+          expectedData.data[i] = 0;
+          break;
+        case 3:
+          expectedData.data[i] = 255;
+          break;
+      }
+    }
+    // Third pixel was copied.
+    expectedData.data[2 * 4 + 0] = 25;
+    expectedData.data[2 * 4 + 1] = 65;
+    expectedData.data[2 * 4 + 2] = 255;
+    expectedData.data[2 * 4 + 3] = 255;
+
+    // Make sure that our data is all green.
+    var resultingData = context.getImageData(0, 0, 10, 10);
+    expect(resultingData.data, expectedData.data);
+  });
+
+  test('putImageData throws with wrong number of arguments', () {
+    ImageData expectedData = context.getImageData(0, 0, 10, 10);
+
+    // TODO(antonm): in Dartium ArgumentError should be thrown too.
+    expect(() => context.putImageData(expectedData, 0, 0, 1), throws);
+    expect(() => context.putImageData(expectedData, 0, 0, 1, 1), throws);
+    expect(() => context.putImageData(expectedData, 0, 0, 1, 1, 5), throws);
+  });
+}
diff --git a/tests/lib/html/cdata_test.dart b/tests/lib/html/cdata_test.dart
new file mode 100644
index 0000000..60c311a
--- /dev/null
+++ b/tests/lib/html/cdata_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('remove', () {
+    var div = new Element.html('<div>content</div>');
+    var cdata = div.nodes[0];
+    expect(cdata is CharacterData, true);
+    expect(cdata, isNotNull);
+    expect(div.innerHtml, 'content');
+
+    cdata.remove();
+    expect(div.innerHtml, '');
+  });
+}
diff --git a/tests/lib/html/client_rect_test.dart b/tests/lib/html/client_rect_test.dart
new file mode 100644
index 0000000..a02fb0d
--- /dev/null
+++ b/tests/lib/html/client_rect_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isRectList =
+      predicate((x) => x is DomRectList, 'should be a DomRectList');
+  var isListOfRectangle =
+      predicate((x) => x is List<Rectangle>, 'should be a List<Rectangle>');
+
+  var isRectangle = predicate((x) => x is Rectangle, 'should be a Rectangle');
+  var isDomRectReadOnly =
+      predicate((x) => x is DomRectReadOnly, 'should be a DomRectReadOnly');
+
+  insertTestDiv() {
+    var element = new Element.tag('div');
+    element.innerHtml = r'''
+    A large block of text should go here. Click this
+    block of text multiple times to see each line
+    highlight with every click of the mouse button.
+    ''';
+    document.body!.append(element);
+    return element;
+  }
+
+  test("DomRectList test", () {
+    insertTestDiv();
+    var range = new Range();
+    var rects = range.getClientRects();
+    expect(rects, isListOfRectangle);
+    expect(rects, isRectList);
+  });
+
+  test("ClientRect ==", () {
+    var rect1 = document.body!.getBoundingClientRect();
+    var rect2 = document.body!.getBoundingClientRect();
+    expect(rect1, isRectangle);
+    expect(rect1, isDomRectReadOnly);
+    expect(rect1, equals(rect2));
+  });
+}
diff --git a/tests/lib/html/cross_domain_iframe_script.html b/tests/lib/html/cross_domain_iframe_script.html
new file mode 100644
index 0000000..b626071
--- /dev/null
+++ b/tests/lib/html/cross_domain_iframe_script.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+
+<html>
+  <head>
+  	<meta charset="utf-8">
+    <title>cross_domain_iframe_script</title>
+  </head>
+
+  <body>
+    <script type="application/javascript"
+            src="/root_dart/tests/lib/html/cross_domain_iframe_script.js">
+    </script>
+  </body>
+</html>
diff --git a/tests/lib/html/cross_domain_iframe_script.js b/tests/lib/html/cross_domain_iframe_script.js
new file mode 100644
index 0000000..9dcdc75
--- /dev/null
+++ b/tests/lib/html/cross_domain_iframe_script.js
@@ -0,0 +1 @@
+window.parent.postMessage('foobar', '*');
\ No newline at end of file
diff --git a/tests/lib/html/cross_domain_iframe_test.dart b/tests/lib/html/cross_domain_iframe_test.dart
new file mode 100644
index 0000000..cbd2726
--- /dev/null
+++ b/tests/lib/html/cross_domain_iframe_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:expect/minitest.dart';
+
+main() {
+  var uri = Uri.parse(window.location.href);
+
+  var crossOriginPort = int.parse(uri.queryParameters['crossOriginPort']!);
+  var crossOrigin = '${uri.scheme}://${uri.host}:$crossOriginPort';
+  var crossOriginUrl =
+      '$crossOrigin/root_dart/tests/lib/html/cross_domain_iframe_script.html';
+
+  var iframe = new IFrameElement();
+  iframe.src = crossOriginUrl;
+  document.body!.append(iframe);
+
+  return window.onMessage
+      .where((MessageEvent event) {
+        return event.origin == crossOrigin;
+      })
+      .first
+      .then((MessageEvent event) {
+        expect(event.data, equals('foobar'));
+        expect(event.source, isNotNull);
+      });
+}
diff --git a/tests/lib/html/cross_frame_test.dart b/tests/lib/html/cross_frame_test.dart
new file mode 100644
index 0000000..def8d71
--- /dev/null
+++ b/tests/lib/html/cross_frame_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isWindowBase = predicate((x) => x is WindowBase, 'is a WindowBase');
+  var isWindow = predicate((x) => x is Window, 'is a Window');
+  var isLocationBase = predicate((x) => x is LocationBase, 'is a LocationBase');
+  var isLocation = predicate((x) => x is Location, 'is a Location');
+  var isHistoryBase = predicate((x) => x is HistoryBase, 'is a HistoryBase');
+  var isHistory = predicate((x) => x is History, 'is a History');
+
+  final dynamic iframe = new IFrameElement();
+  document.body!.append(iframe);
+
+  test('window', () {
+    expect(window, isWindow);
+    expect(window.document, document);
+  });
+
+  test('iframe', () {
+    final frameWindow = iframe.contentWindow;
+    expect(frameWindow, isWindowBase);
+    //TODO(gram) The next test should be written as:
+    //    expect(frameWindow, isNot(isWindow));
+    // but that will cause problems now until is/is! work
+    // properly in dart2js instead of always returning true.
+    expect(frameWindow is! Window, isTrue);
+    expect(frameWindow.parent, isWindow);
+
+    // Ensure that the frame's document is inaccessible via window.
+    expect(() => frameWindow.document, throws);
+  });
+
+  test('contentDocument', () {
+    // Ensure that the frame's document is inaccessible.
+    expect(() => iframe.contentDocument, throws);
+  });
+
+  test('location', () {
+    expect(window.location, isLocation);
+    final frameLocation = iframe.contentWindow.location;
+    expect(frameLocation, isLocationBase);
+    // TODO(gram) Similar to the above, the next test should be:
+    //     expect(frameLocation, isNot(isLocation));
+    expect(frameLocation is! Location, isTrue);
+
+    expect(() => frameLocation.href, throws);
+    expect(() => frameLocation.hash, throws);
+
+    final frameParentLocation = iframe.contentWindow.parent.location;
+    expect(frameParentLocation, isLocation);
+  });
+
+  test('history', () {
+    expect(window.history, isHistory);
+    final frameHistory = iframe.contentWindow.history;
+    expect(frameHistory, isHistoryBase);
+    // See earlier comments.
+    //expect(frameHistory, isNot(isHistory));
+    expect(frameHistory is! History, isTrue);
+
+    // Valid methods.
+    frameHistory.forward();
+
+    expect(() => frameHistory.length, throws);
+
+    final frameParentHistory = iframe.contentWindow.parent.history;
+    expect(frameParentHistory, isHistory);
+  });
+}
diff --git a/tests/lib/html/crypto_test.dart b/tests/lib/html/crypto_test.dart
new file mode 100644
index 0000000..9cb63ab
--- /dev/null
+++ b/tests/lib/html/crypto_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(Crypto.supported, true);
+    });
+  });
+
+  group('functional', () {
+    if (Crypto.supported) {
+      // This will actually pass on FF since it has a Crypto API, but it is
+      // incompatible.
+      test('exists', () {
+        var crypto = window.crypto;
+        expect(crypto is Crypto, isTrue);
+      });
+
+      test('successful call', () {
+        var crypto = window.crypto;
+        var data = new Uint8List(100);
+        expect(data.every((e) => e == 0), isTrue);
+        crypto.getRandomValues(data);
+        // In theory this is flaky. However, in practice you will get 100 zeroes
+        // in a row from a cryptographically secure random number generator so
+        // rarely that we don't have to worry about it.
+        expect(data.any((e) => e != 0), isTrue);
+      });
+
+      test('type mismatch', () {
+        var crypto = window.crypto;
+        var data = new Float32List(100);
+        expect(() {
+          crypto.getRandomValues(data);
+        }, throws, reason: 'Only typed array views with integer types allowed');
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/css_rule_list_test.dart b/tests/lib/html/css_rule_list_test.dart
new file mode 100644
index 0000000..596e2d8
--- /dev/null
+++ b/tests/lib/html/css_rule_list_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isCssRuleList =
+      predicate((x) => x is List<CssRule>, 'is a List<CssRule>');
+
+  test("ClientRectList test", () {
+    var sheet = document.styleSheets[0] as CssStyleSheet;
+    List<CssRule> rulesList = sheet.cssRules;
+    expect(rulesList, isCssRuleList);
+  });
+}
diff --git a/tests/lib/html/css_selector_test.dart b/tests/lib/html/css_selector_test.dart
new file mode 100644
index 0000000..9d82842
--- /dev/null
+++ b/tests/lib/html/css_selector_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/expect.dart';
+import 'utils.dart';
+
+main() {
+  final String htmlPayload = "<div>"
+      "<div>"
+      "<p class='a'>"
+      "<span>Test #1</span>"
+      "</p>"
+      "</div>"
+      "<div>"
+      "<p class='b'>"
+      "<span>Test #2</span>"
+      "</p>"
+      "</div>"
+      "</div>";
+
+  final elements =
+      new Element.html(htmlPayload, treeSanitizer: new NullTreeSanitizer());
+  document.body!.nodes.add(elements);
+
+  var para = document.body!.querySelector('p') as ParagraphElement;
+  para.classes.removeAll(['a', 'b']);
+
+  para = document.body!.querySelector('p') as ParagraphElement;
+  Expect.equals('<p class=""><span>Test #1</span></p>', para.outerHtml);
+
+  para = document.body!.querySelector('p') as ParagraphElement;
+  para.classes.addAll(['c']);
+
+  para = document.body!.querySelector('p') as ParagraphElement;
+  Expect.equals('<p class="c"><span>Test #1</span></p>', para.outerHtml);
+
+  var allPara = document.body!.querySelectorAll('p');
+  allPara.classes.removeAll(['b', 'c']);
+
+  var checkAllPara = document.body!.querySelectorAll('p');
+  Expect.equals(
+      '<p class=""><span>Test #1</span></p>', checkAllPara[0].outerHtml);
+  Expect.equals(
+      '<p class=""><span>Test #2</span></p>', checkAllPara[1].outerHtml);
+}
diff --git a/tests/lib/html/css_test.dart b/tests/lib/html/css_test.dart
new file mode 100644
index 0000000..a3a00f9
--- /dev/null
+++ b/tests/lib/html/css_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library CssTest;
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supportsPointConversions', () {
+    test('supported', () {
+      expect(Window.supportsPointConversions, true);
+    });
+  });
+
+  group('functional', () {
+    test('DomPoint', () {
+      var expectation =
+          Window.supportsPointConversions ? returnsNormally : throws;
+      expect(() {
+        Element element = new Element.tag('div');
+        element.attributes['style'] = '''
+          position: absolute;
+          width: 60px;
+          height: 100px;
+          left: 0px;
+          top: 0px;
+          background-color: red;
+          -webkit-transform: translate3d(250px, 100px, 0px);
+          -moz-transform: translate3d(250px, 100px, 0px);
+          ''';
+        document.body!.append(element);
+
+        var elemRect = element.getBoundingClientRect();
+
+        checkPoint(250, 100, new Point(elemRect.left, elemRect.top));
+        checkPoint(310, 200, new Point(elemRect.right, elemRect.bottom));
+      }, expectation);
+    });
+  });
+}
+
+void checkPoint(expectedX, expectedY, Point point) {
+  expect(point.x.round(), equals(expectedX), reason: 'Wrong point.x');
+  expect(point.y.round(), equals(expectedY), reason: 'Wrong point.y');
+}
diff --git a/tests/lib/html/cssstyledeclaration_test.dart b/tests/lib/html/cssstyledeclaration_test.dart
new file mode 100644
index 0000000..aa8a5d4
--- /dev/null
+++ b/tests/lib/html/cssstyledeclaration_test.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library CssStyleDeclarationTest;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+main() {
+  createTestStyle() {
+    return new CssStyleDeclaration.css("""
+      color: blue;
+      width: 2px !important;
+    """);
+  }
+
+  ;
+
+  test('default constructor is empty', () {
+    var style = new CssStyleDeclaration();
+    expect(style.cssText.isEmpty, isTrue);
+    expect(style.getPropertyPriority('color').isEmpty, isTrue);
+    expect(style.item(0).isEmpty, isTrue);
+    expect(style.length, 0);
+    // These assertions throw a UnimplementedError in dartium:
+    // expect(style.parentRule, isNull);
+    // expect(style.getPropertyCssValue('color'), isNull);
+    // expect(style.getPropertyShorthand('color'), isNull);
+  });
+
+  test('length is wrapped', () {
+    expect(createTestStyle().length, 2);
+  });
+
+  test('getPropertyPriority is wrapped', () {
+    var style = createTestStyle();
+    expect(style.getPropertyPriority("color").isEmpty, isTrue);
+    expect(style.getPropertyPriority("width"), equals("important"));
+  });
+
+  test('removeProperty is wrapped', () {
+    var style = createTestStyle();
+    style.removeProperty("width");
+    expect(style.cssText.trim(), equals("color: blue;"));
+  });
+
+  test('CSS property empty getters and setters', () {
+    var style = createTestStyle();
+    expect(style.border, equals(""));
+
+    style.border = "1px solid blue";
+    style.border = "";
+    expect(style.border, equals(""));
+
+    style.border = "1px solid blue";
+    style.border = null;
+    expect(style.border, equals(""));
+  });
+
+  test('CSS property getters and setters', () {
+    var style = createTestStyle();
+    expect(style.color, equals("blue"));
+    expect(style.width, equals("2px"));
+
+    style.color = "red";
+    style.transform = "translate(10px, 20px)";
+
+    expect(style.color, equals("red"));
+    expect(style.transform, equals("translate(10px, 20px)"));
+  });
+
+  test('Browser prefixes', () {
+    var element = new DivElement();
+    element.style.transform = 'translateX(10px)';
+    document.body!.children.add(element);
+
+    var style = element.getComputedStyle();
+    // Some browsers will normalize this, so it'll be a matrix rather than
+    // the original string. Just check that it's something other than null.
+    expect(style.transform.length, greaterThan(3));
+  });
+
+  // IE9 requires an extra poke for some properties to get applied.
+  test('IE9 Invalidation', () {
+    var element = new DivElement();
+    document.body!.children.add(element);
+
+    // Need to wait one tick after the element has been added to the page.
+    new Timer(const Duration(milliseconds: 10), expectAsync(() {
+      element.style.textDecoration = 'underline';
+      var style = element.getComputedStyle();
+      expect(style.textDecoration.contains('underline'), isTrue);
+    }));
+  });
+
+  test('Invalid values', () {
+    var element = new DivElement();
+    // Should not throw an error.
+    element.style.background = 'some_bad_value';
+  });
+
+  test('css multi get', () {
+    var listElement = new Element.html(
+        '<ul class="foo">'
+        '<li class="bar" style="background-color: red; border-left: 10px;">'
+        '<li class="baz" style="background-color: black;>'
+        '<li class="baz classy" style="background-color: blue; ">'
+        '</ul>',
+        treeSanitizer: new NullTreeSanitizer());
+    document.documentElement!.children.add(listElement);
+
+    var elements = document.querySelectorAll('li');
+    expect(elements.style.backgroundColor, equals('red'));
+    expect(elements.style.borderLeftWidth, equals('10px'));
+    elements = document.querySelectorAll('.baz');
+    expect(elements.style.backgroundColor, equals('black'));
+    expect(elements.style.borderLeftWidth, equals(''));
+    elements = document.querySelectorAll('.bar');
+    expect(elements.style.backgroundColor, equals('red'));
+  });
+
+  test('css multi set', () {
+    var listElement = new Element.html(
+        '<ul class="foo">'
+        '<li class="bar" style="background-color: red; border-left: 10px;">'
+        '<li class="baz" style="background-color: black;>'
+        '<li class="baz" id="wat" style="background-color: blue; ">'
+        '</ul>',
+        treeSanitizer: new NullTreeSanitizer());
+    document.documentElement!.children.add(listElement);
+
+    var elements = document.querySelectorAll('li');
+    elements.style.backgroundColor = 'green';
+    expect(elements.style.backgroundColor, equals('green'));
+    expect(elements.style.borderLeftWidth, equals('10px'));
+
+    elements = document.querySelectorAll('.baz');
+    expect(elements.style.backgroundColor, equals('green'));
+    elements.style.backgroundColor = 'yellow';
+    expect(elements.style.backgroundColor, equals('yellow'));
+    expect(elements.style.borderLeftWidth, equals(''));
+
+    elements = document.querySelectorAll('.bar');
+    expect(elements.style.backgroundColor, equals('green'));
+    elements = document.querySelectorAll('#wat');
+    expect(elements.style.backgroundColor, equals('yellow'));
+
+    elements.style.borderLeftWidth = '18px';
+    expect(elements.style.borderLeftWidth, equals('18px'));
+    elements = document.querySelectorAll('li');
+    expect(elements.style.borderLeftWidth, equals('10px'));
+  });
+
+  test('supports property', () {
+    expect(document.body!.style.supportsProperty('bogus-property'), false);
+    expect(document.body!.style.supportsProperty('background'), true);
+    expect(document.body!.style.supportsProperty('borderBottomWidth'), true);
+    expect(document.body!.style.supportsProperty('animation'), true);
+  });
+}
diff --git a/tests/lib/html/custom/attribute_changed_callback_test.dart b/tests/lib/html/custom/attribute_changed_callback_test.dart
new file mode 100644
index 0000000..6455cc3
--- /dev/null
+++ b/tests/lib/html/custom/attribute_changed_callback_test.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library attribute_changed_callback_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class A extends HtmlElement {
+  static final tag = 'x-a';
+  factory A() => new Element.tag(tag) as A;
+  A.created() : super.created();
+
+  static var attributeChangedInvocations = 0;
+
+  void attributeChanged(name, oldValue, newValue) {
+    attributeChangedInvocations++;
+  }
+}
+
+class B extends HtmlElement {
+  static final tag = 'x-b';
+  factory B() => new Element.tag(tag) as B;
+  B.created() : super.created() {
+    invocations.add('created');
+  }
+
+  static var invocations = [];
+
+  Completer? completer;
+
+  void attributeChanged(name, oldValue, newValue) {
+    invocations.add('$name: $oldValue => $newValue');
+    if (completer != null) {
+      completer!.complete('value changed to $newValue');
+      completer = null;
+    }
+  }
+}
+
+// Pump custom events polyfill events.
+void customElementsTakeRecords() {
+  if (js.context.hasProperty('CustomElements')) {
+    js.context['CustomElements'].callMethod('takeRecords');
+  }
+}
+
+main() async {
+  // Adapted from Blink's fast/dom/custom/attribute-changed-callback test.
+
+  await customElementsReady;
+  document.registerElement2(A.tag, {'prototype': A});
+  document.registerElement2(B.tag, {'prototype': B});
+
+  group('fully_supported', () {
+    test('transfer attribute changed callback', () {
+      var element = new A();
+
+      element.attributes['a'] = 'b';
+      expect(A.attributeChangedInvocations, 1);
+    });
+
+    test('add, change and remove an attribute', () {
+      var b = new B();
+
+      B.invocations = [];
+      b.attributes['data-s'] = 't';
+      expect(B.invocations, ['data-s: null => t']);
+
+      b.attributes['data-v'] = 'w';
+      B.invocations = [];
+      b.attributes['data-v'] = 'x';
+      expect(B.invocations, ['data-v: w => x']);
+
+      B.invocations = [];
+      b.attributes['data-v'] = 'x';
+      expect(B.invocations, []);
+
+      b.attributes.remove('data-v');
+      expect(B.invocations, ['data-v: x => null']);
+    });
+
+    test('add, change ID', () {
+      B.invocations = [];
+
+      var b = new B();
+      var completer = new Completer();
+      b.completer = completer;
+      b.id = 'x';
+      return completer.future
+          .then((_) => expect(B.invocations, ['created', 'id: null => x']))
+          .then((_) {
+        B.invocations = [];
+        var secondCompleter = new Completer();
+        b.completer = secondCompleter;
+        b.attributes.remove('id');
+        return secondCompleter.future;
+      }).then((_) => expect(B.invocations, ['id: x => null']));
+    });
+  });
+
+  group('unsupported_on_polyfill', () {
+    // If these tests start passing, don't remove the status suppression. Move
+    // the tests to the fullYy_supported group.
+
+    test('add, change classes', () {
+      var b = new B();
+
+      B.invocations = [];
+      b.classes.toggle('u');
+      expect(B.invocations, ['class: null => u']);
+    });
+  });
+}
diff --git a/tests/lib/html/custom/attribute_changed_callback_test.html b/tests/lib/html/custom/attribute_changed_callback_test.html
new file mode 100644
index 0000000..b38ec6e
--- /dev/null
+++ b/tests/lib/html/custom/attribute_changed_callback_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> attribute_changed_callback_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running attribute_changed_callback_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/created_callback_test.dart b/tests/lib/html/custom/created_callback_test.dart
new file mode 100644
index 0000000..5889b06
--- /dev/null
+++ b/tests/lib/html/custom/created_callback_test.dart
@@ -0,0 +1,296 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library created_callback_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class A extends HtmlElement {
+  static final tag = 'x-a';
+  factory A() => new Element.tag(tag) as A;
+  A.created() : super.created() {
+    createdInvocations++;
+  }
+
+  static int createdInvocations = 0;
+}
+
+class B extends HtmlElement {
+  static final tag = 'x-b';
+  factory B() => new Element.tag(tag) as B;
+  B.created() : super.created();
+}
+
+class C extends HtmlElement {
+  static final tag = 'x-c';
+  factory C() => new Element.tag(tag) as C;
+  C.created() : super.created() {
+    createdInvocations++;
+
+    if (this.id != 'u') {
+      return;
+    }
+
+    var t = div.querySelector('#t');
+    var v = div.querySelector('#v');
+    var w = div.querySelector('#w');
+
+    expect(querySelector('x-b:not(:unresolved)'), this);
+    expect(querySelectorAll(':unresolved'), [v, w]);
+
+    // As per:
+    // http://www.w3.org/TR/2013/WD-custom-elements-20130514/#serializing-and-parsing
+    // creation order is t, u, v, w (postorder).
+    expect(t is C, isTrue);
+    // Note, this is different from JavaScript where this would be false.
+    expect(v is C, isTrue);
+  }
+
+  static int createdInvocations = 0;
+  static var div;
+}
+
+main() async {
+  // Adapted from Blink's
+  // fast/dom/custom/created-callback test.
+
+  await customElementsReady;
+  document.registerElement2(B.tag, {'prototype': B});
+  document.registerElement2(C.tag, {'prototype': C});
+  ErrorConstructorElement.register();
+
+  test('transfer created callback', () {
+    document.registerElement2(A.tag, {'prototype': A as dynamic});
+    var x = new A();
+    expect(A.createdInvocations, 1);
+  });
+
+  test('unresolved and created callback timing', () {
+    var div = new DivElement();
+    C.div = div;
+    div.setInnerHtml("""
+<x-c id="t"></x-c>
+<x-b id="u"></x-b>
+<x-c id="v"></x-c>
+<x-b id="w"></x-b>
+""", treeSanitizer: NodeTreeSanitizer.trusted);
+
+    upgradeCustomElements(div);
+
+    expect(C.createdInvocations, 2);
+    expect(div.querySelector('#w') is B, isTrue);
+  });
+
+  test('nesting of constructors', NestedElement.test);
+
+  test('access while upgrading gets unupgraded element',
+      AccessWhileUpgradingElement.test);
+
+  test('cannot call created constructor', () {
+    expect(() {
+      new B.created();
+    }, throws);
+  });
+
+  test('cannot register without created', () {
+    expect(() {
+      document.registerElement2(
+          MissingCreatedElement.tag, {'prototype': MissingCreatedElement});
+    }, throws);
+  });
+
+  test('throw on createElement does not upgrade', () {
+    ErrorConstructorElement.callCount = 0;
+
+    var e;
+    expectGlobalError(() {
+      e = new Element.tag(ErrorConstructorElement.tag);
+    });
+    expect(ErrorConstructorElement.callCount, 1);
+    expect(e is HtmlElement, isTrue);
+    expect(e is ErrorConstructorElement, isFalse);
+
+    var dummy = new DivElement();
+    dummy.append(e);
+    e = dummy.firstChild;
+    expect(ErrorConstructorElement.callCount, 1);
+  });
+
+  test('throw on innerHtml does not upgrade', () {
+    ErrorConstructorElement.callCount = 0;
+
+    var dummy = new DivElement();
+    var tag = ErrorConstructorElement.tag;
+    expectGlobalError(() {
+      dummy.setInnerHtml('<$tag></$tag>',
+          treeSanitizer: NodeTreeSanitizer.trusted);
+    });
+
+    expect(ErrorConstructorElement.callCount, 1);
+
+    var e = dummy.firstChild;
+    // Accessing should not re-run the constructor.
+    expect(ErrorConstructorElement.callCount, 1);
+    expect(e is HtmlElement, isTrue);
+    expect(e is ErrorConstructorElement, isFalse);
+  });
+
+  test('cannot register created with params', () {
+    expect(() {
+      document.registerElement2(
+          'x-created-with-params', {'prototype': CreatedWithParametersElement});
+    }, throws);
+  });
+
+  test('created cannot be called from nested constructor',
+      NestedCreatedConstructorElement.test);
+
+  // TODO(vsm): Port additional test from upstream here:
+  // http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/dom/custom/created-callback.html?r1=156141&r2=156185
+}
+
+class NestedElement extends HtmlElement {
+  static final tag = 'x-nested';
+
+  final Element b = new B();
+
+  factory NestedElement() => new Element.tag(tag) as NestedElement;
+  NestedElement.created() : super.created();
+
+  static void register() {
+    document.registerElement2(tag, {'prototype': NestedElement});
+  }
+
+  static void test() {
+    register();
+
+    var e = new NestedElement();
+    expect(e.b, isNotNull);
+    expect(e.b is B, isTrue);
+    expect(e is NestedElement, isTrue);
+  }
+}
+
+class AccessWhileUpgradingElement extends HtmlElement {
+  static final tag = 'x-access-while-upgrading';
+
+  static late Element upgradingContext;
+  static late Element upgradingContextChild;
+
+  final foo = runInitializerCode();
+
+  factory AccessWhileUpgradingElement() =>
+      new Element.tag(tag) as AccessWhileUpgradingElement;
+  AccessWhileUpgradingElement.created() : super.created();
+
+  static runInitializerCode() {
+    upgradingContextChild = upgradingContext.firstChild as Element;
+
+    return 666;
+  }
+
+  static void register() {
+    document.registerElement2(tag, {'prototype': AccessWhileUpgradingElement});
+  }
+
+  static void test() {
+    register();
+
+    upgradingContext = new DivElement();
+    upgradingContext.setInnerHtml('<$tag></$tag>',
+        treeSanitizer: new NullTreeSanitizer());
+    dynamic child = upgradingContext.firstChild;
+
+    expect(child.foo, 666);
+    expect(upgradingContextChild is HtmlElement, isFalse);
+    expect(upgradingContextChild is AccessWhileUpgradingElement, isFalse,
+        reason: 'Elements accessed while upgrading should not be upgraded.');
+  }
+}
+
+class MissingCreatedElement extends HtmlElement {
+  static final tag = 'x-missing-created';
+
+  factory MissingCreatedElement() =>
+      new Element.tag(tag) as MissingCreatedElement;
+}
+
+class ErrorConstructorElement extends HtmlElement {
+  static final tag = 'x-throws-in-constructor';
+  static int callCount = 0;
+
+  factory ErrorConstructorElement() =>
+      new Element.tag(tag) as ErrorConstructorElement;
+
+  ErrorConstructorElement.created() : super.created() {
+    ++callCount;
+    throw new Exception('Just messin with ya');
+  }
+
+  static void register() {
+    document.registerElement2(tag, {'prototype': ErrorConstructorElement});
+  }
+}
+
+class NestedCreatedConstructorElement extends HtmlElement {
+  static final tag = 'x-nested-created-constructor';
+
+  // Should not be able to call this here.
+  final B b = constructB();
+  static B? constructedB;
+
+  factory NestedCreatedConstructorElement() =>
+      new Element.tag(tag) as NestedCreatedConstructorElement;
+  NestedCreatedConstructorElement.created() : super.created();
+
+  static void register() {
+    document
+        .registerElement2(tag, {'prototype': NestedCreatedConstructorElement});
+  }
+
+  // Try to run the created constructor, and record the results.
+  static constructB() {
+    // This should throw an exception.
+    constructedB = new B.created();
+    return constructedB;
+  }
+
+  static void test() {
+    register();
+
+    // Exception should have occurred on upgrade.
+    var e;
+    expectGlobalError(() {
+      e = new Element.tag(tag);
+    });
+    expect(e is NestedCreatedConstructorElement, isFalse);
+    expect(e is HtmlElement, isTrue);
+    // Should not have been set.
+    expect(constructedB, isNull);
+  }
+}
+
+class CreatedWithParametersElement extends HtmlElement {
+  CreatedWithParametersElement.created(ignoredParam) : super.created();
+}
+
+void expectGlobalError(Function test) {
+  js.context['testExpectsGlobalError'] = true;
+  try {
+    test();
+  } catch (e) {
+    rethrow;
+  } finally {
+    js.context['testExpectsGlobalError'] = false;
+  }
+  var errors = js.context['testSuppressedGlobalErrors'];
+  expect(errors['length'], 1);
+  // Clear out the errors;
+  js.context['testSuppressedGlobalErrors']['length'] = 0;
+}
diff --git a/tests/lib/html/custom/created_callback_test.html b/tests/lib/html/custom/created_callback_test.html
new file mode 100644
index 0000000..ca6e193
--- /dev/null
+++ b/tests/lib/html/custom/created_callback_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> created_callback_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running created_callback_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/document_register_basic_test.dart b/tests/lib/html/custom/document_register_basic_test.dart
new file mode 100644
index 0000000..7a5db71
--- /dev/null
+++ b/tests/lib/html/custom/document_register_basic_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library document_register_basic_test;
+
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class Foo extends HtmlElement {
+  static final tag = 'x-foo';
+  factory Foo() => new Element.tag(tag) as Foo;
+  Foo.created() : super.created();
+
+  get thisIsACustomClass => true;
+}
+
+class Bar extends HtmlElement {
+  static final tag = 'x-bar';
+  factory Bar() => new Element.tag(tag) as Bar;
+  Bar.created() : super.created();
+
+  get thisIsACustomClass => true;
+}
+
+class Baz extends Foo {
+  static final tag = 'x-baz';
+  factory Baz() => new Element.tag(tag) as Baz;
+  Baz.created() : super.created();
+
+  get thisIsAlsoACustomClass => true;
+}
+
+class BadB {}
+
+abstract class BadC extends HtmlElement {
+  BadC.created() : super.created();
+}
+
+main() async {
+  // Adapted from Blink's fast/dom/custom/document-register-basic test.
+
+  await customElementsReady;
+
+  test('Testing document.registerElement2() basic behaviors', () {
+    document.registerElement2(Foo.tag, {'prototype': Foo});
+
+    // Cannot register an existing dart:html type.
+    expect(
+        () => document.registerElement2('x-bad-a', {'prototype': HtmlElement}),
+        throws);
+
+    // Invalid user type.  Doesn't inherit from HtmlElement.
+    expect(() => document.registerElement2('x-bad-b', {'prototype': BadB}),
+        throws);
+
+    // Cannot register abstract class.
+    expect(() => document.registerElement2('x-bad-c', {'prototype': BadC}),
+        throws);
+
+    // Not a type.
+    expect(() => document.registerElement2('x-bad-d', {'prototype': null}),
+        throws);
+
+    // Cannot register system type.
+    expect(() => document.registerElement2('x-bad-e', {'prototype': Object}),
+        throws);
+
+    // Constructor initiated instantiation
+    var createdFoo = new Foo();
+    expect(createdFoo.thisIsACustomClass, isTrue);
+
+    // Dart type correctness
+    expect(createdFoo is HtmlElement, isTrue);
+    expect(createdFoo is Foo, isTrue);
+    expect(createdFoo.runtimeType, Foo);
+
+    // Native getter
+    expect(createdFoo.tagName, "X-FOO");
+
+    // Native setter
+    createdFoo.innerHtml = "Hello";
+    expect(createdFoo.text, "Hello");
+
+    // Native method
+    var childDiv = new DivElement();
+    createdFoo.append(childDiv);
+    expect(createdFoo.lastChild, childDiv);
+
+    // Parser initiated instantiation
+    var container = new DivElement()..id = "container";
+    document.body!.append(container);
+    container.setInnerHtml("<x-foo></x-foo>",
+        treeSanitizer: new NullTreeSanitizer());
+    upgradeCustomElements(container);
+    var parsedFoo = container.firstChild;
+
+    expect(parsedFoo is Foo, isTrue);
+    expect((parsedFoo as Foo).tagName, "X-FOO");
+
+    // Ensuring the wrapper is retained
+    var someProperty = new Expando();
+    someProperty[parsedFoo] = "hello";
+    expect(container.firstChild, parsedFoo);
+    expect(someProperty[container.firstChild!], someProperty[parsedFoo]);
+
+    // Having another constructor
+    document.registerElement2(Bar.tag, {'prototype': Bar});
+    var createdBar = new Bar();
+    expect(createdBar is Bar, isTrue);
+    expect(createdBar is Foo, isFalse);
+    expect(createdBar.tagName, "X-BAR");
+
+    // Having a subclass
+    document.registerElement2(Baz.tag, {'prototype': Baz});
+    var createdBaz = new Baz();
+    expect(createdBaz.tagName, "X-BAZ");
+    expect(createdBaz.thisIsACustomClass, isTrue);
+    expect(createdBaz.thisIsAlsoACustomClass, isTrue);
+
+    // With irregular cases
+    var createdUpperBar = new Element.tag("X-BAR");
+    var createdMixedBar = new Element.tag("X-Bar");
+    expect(createdUpperBar is Bar, isTrue);
+    expect(createdUpperBar.tagName, "X-BAR");
+    expect(createdMixedBar is Bar, isTrue);
+    expect(createdMixedBar.tagName, "X-BAR");
+
+    container.setInnerHtml("<X-BAR></X-BAR><X-Bar></X-Bar>",
+        treeSanitizer: new NullTreeSanitizer());
+    upgradeCustomElements(container);
+    expect(container.firstChild is Bar, isTrue);
+    expect((container.firstChild as Bar).tagName, "X-BAR");
+    expect(container.lastChild is Bar, isTrue);
+    expect((container.lastChild as Bar).tagName, "X-BAR");
+
+    // Constructors shouldn't interfere with each other
+    expect((new Foo()).tagName, "X-FOO");
+    expect((new Bar()).tagName, "X-BAR");
+    expect((new Baz()).tagName, "X-BAZ");
+  });
+}
diff --git a/tests/lib/html/custom/document_register_basic_test.html b/tests/lib/html/custom/document_register_basic_test.html
new file mode 100644
index 0000000..c4042b3
--- /dev/null
+++ b/tests/lib/html/custom/document_register_basic_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> document_register_basic_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running document_register_basic_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/document_register_template_test.dart b/tests/lib/html/custom/document_register_template_test.dart
new file mode 100644
index 0000000..65cffec
--- /dev/null
+++ b/tests/lib/html/custom/document_register_template_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+main() async {
+  await customElementsReady;
+
+  test('can register custom template with webcomponents-lite polyfill', () {
+    document.registerElement2(
+        'my-element', {'prototype': MyElement, 'extends': 'template'});
+    dynamic e = new Element.tag('template', 'my-element');
+    document.body!.append(e);
+    expect(e is TemplateElement, isTrue);
+    expect(e.method(), 'value');
+  });
+}
+
+class MyElement extends TemplateElement {
+  MyElement.created() : super.created();
+  method() => 'value';
+}
diff --git a/tests/lib/html/custom/document_register_template_test.html b/tests/lib/html/custom/document_register_template_test.html
new file mode 100644
index 0000000..7c48c6a
--- /dev/null
+++ b/tests/lib/html/custom/document_register_template_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> document_register_basic_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents-lite.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running document_register_basic_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/document_register_type_extensions_test.dart b/tests/lib/html/custom/document_register_type_extensions_test.dart
new file mode 100644
index 0000000..bbeafb5
--- /dev/null
+++ b/tests/lib/html/custom/document_register_type_extensions_test.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class Foo extends HtmlElement {
+  static const tag = 'x-foo';
+  static final List<String> outerHtmlStrings = [
+    '<x-foo></x-foo>',
+    '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-foo></x-foo>'
+  ];
+  factory Foo() => new Element.tag(tag) as Foo;
+  Foo.created() : super.created();
+}
+
+class Bar extends InputElement {
+  static const tag = 'x-bar';
+  static const outerHtmlString = '<input is="x-bar">';
+  factory Bar() => new Element.tag('input', tag) as Bar;
+  Bar.created() : super.created();
+}
+
+class Baz extends Foo {
+  static const tag = 'x-baz';
+  static final List<String> outerHtmlStrings = [
+    '<x-baz></x-baz>',
+    '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-baz></x-baz>'
+  ];
+  factory Baz() => new Element.tag(tag) as Baz;
+  Baz.created() : super.created();
+}
+
+class Qux extends Bar {
+  static const tag = 'x-qux';
+  factory Qux() => new Element.tag('input', tag) as Qux;
+  Qux.created() : super.created();
+}
+
+class FooBad extends DivElement {
+  static const tag = 'x-foo';
+  factory FooBad() => new Element.tag('div', tag) as FooBad;
+  FooBad.created() : super.created();
+}
+
+class MyCanvas extends CanvasElement {
+  static const tag = 'my-canvas';
+  factory MyCanvas() => new Element.tag('canvas', tag) as MyCanvas;
+
+  MyCanvas.created() : super.created();
+
+  void fillAsRed() {
+    width = 100;
+    height = 100;
+
+    CanvasRenderingContext2D context =
+        this.getContext('2d') as CanvasRenderingContext2D;
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, width, height);
+    context.fill();
+
+    var data = context.getImageData(0, 0, 1, 1).data;
+    expect(data, [255, 0, 0, 255]);
+  }
+}
+
+class CustomDiv extends DivElement {
+  CustomDiv.created() : super.created();
+}
+
+class CustomCustomDiv extends CustomDiv {
+  static const tag = 'custom-custom';
+  CustomCustomDiv.created() : super.created();
+}
+
+main() async {
+  // Adapted from Blink's fast/dom/custom/document-register-type-extension test.
+
+  var testForm = new FormElement()..id = 'testForm';
+  document.body!.append(testForm);
+
+  var isFormControl = (element) {
+    testForm.append(element);
+    return element.form == testForm;
+  };
+
+  var registeredTypes = false;
+  void registerTypes() {
+    if (registeredTypes) {
+      return;
+    }
+    registeredTypes = true;
+    document.registerElement2(Foo.tag, {'prototype': Foo});
+    document.registerElement2(Bar.tag, {'prototype': Bar, 'extends': 'input'});
+    document.registerElement2(Baz.tag, {'prototype': Baz});
+    document.registerElement2(Qux.tag, {'prototype': Qux, 'extends': 'input'});
+    document.registerElement2(
+        MyCanvas.tag, {'prototype': MyCanvas, 'extends': 'canvas'});
+    document.registerElement2(
+        CustomCustomDiv.tag, {'prototype': CustomCustomDiv, 'extends': 'div'});
+  }
+
+  await customElementsReady;
+
+  group('registration', () {
+    test('cannot register twice', () {
+      registerTypes();
+      expect(
+          () => document.registerElement2(
+              FooBad.tag, {'prototype': Foo, 'extends': 'div'}),
+          throws);
+    });
+
+    test('cannot register for non-matching tag', () {
+      registerTypes();
+      expect(() {
+        document.registerElement2(
+            'x-input-div', {'prototype': Bar, 'extends': 'div'});
+      }, throws);
+    });
+
+    test('cannot register type extension for custom tag', () {
+      registerTypes();
+      expect(() {
+        document
+            .registerElement2('x-custom-tag', {'prototype': CustomCustomDiv});
+      }, throws);
+    });
+  });
+
+  group('construction', () {
+    group('constructors', () {
+      registerTypes();
+      test('custom tag', () {
+        var fooNewed = new Foo();
+        expect(fooNewed.outerHtml, anyOf(Foo.outerHtmlStrings));
+        expect(fooNewed is Foo, isTrue);
+        expect(fooNewed is HtmlElement, isTrue);
+        expect(fooNewed is UnknownElement, isFalse);
+      });
+
+      test('type extension', () {
+        var barNewed = new Bar();
+        expect(barNewed.outerHtml, Bar.outerHtmlString);
+        expect(barNewed is Bar, isTrue);
+        expect(barNewed is InputElement, isTrue);
+        expect(isFormControl(barNewed), isTrue);
+      });
+
+      test('custom tag deriving from custom tag', () {
+        var bazNewed = new Baz();
+        expect(bazNewed.outerHtml, anyOf(Baz.outerHtmlStrings));
+        expect(bazNewed is Baz, isTrue);
+        expect(bazNewed is HtmlElement, isTrue);
+        expect(bazNewed is UnknownElement, isFalse);
+      });
+
+      test('type extension deriving from custom tag', () {
+        var quxNewed = new Qux();
+        var quxOuterHtml = '<input is="x-qux">';
+        expect(quxNewed.outerHtml, quxOuterHtml);
+        expect(quxNewed is Qux, isTrue);
+        expect(quxNewed is InputElement, isTrue);
+        expect(isFormControl(quxNewed), isTrue);
+      });
+    });
+
+    group('single-parameter createElement', () {
+      registerTypes();
+      test('custom tag', () {
+        var fooCreated = new Element.tag('x-foo');
+        expect(fooCreated.outerHtml, anyOf(Foo.outerHtmlStrings));
+        expect(fooCreated is Foo, isTrue);
+      });
+
+      test('does not upgrade type extension', () {
+        var barCreated = new Element.tag('x-bar');
+        expect(barCreated is Bar, isFalse);
+        expect(barCreated.outerHtml, "<x-bar></x-bar>");
+        expect(barCreated is UnknownElement, isFalse);
+        expect(barCreated is HtmlElement, isTrue);
+      });
+
+      test('custom tag deriving from custom tag', () {
+        var bazCreated = new Element.tag('x-baz');
+        expect(bazCreated.outerHtml, anyOf(Baz.outerHtmlStrings));
+        expect(bazCreated is Baz, isTrue);
+        expect(bazCreated is UnknownElement, isFalse);
+      });
+
+      test('type extension deriving from custom tag', () {
+        var quxCreated = new Element.tag('x-qux');
+        expect(quxCreated.outerHtml, "<x-qux></x-qux>");
+        expect(quxCreated is Qux, isFalse);
+        expect(quxCreated is UnknownElement, isFalse);
+        expect(quxCreated is HtmlElement, isTrue);
+      });
+    });
+
+    group('createElement with type extension', () {
+      registerTypes();
+      test('does not upgrade extension of custom tag', () {
+        var divFooCreated = new Element.tag("div", Foo.tag);
+        expect(divFooCreated.outerHtml, '<div is="x-foo"></div>');
+        expect(divFooCreated is Foo, isFalse);
+        expect(divFooCreated is DivElement, isTrue);
+      });
+
+      test('upgrades valid extension', () {
+        var inputBarCreated = new Element.tag("input", Bar.tag);
+        expect(inputBarCreated.outerHtml, Bar.outerHtmlString);
+        expect(inputBarCreated is Bar, isTrue);
+        expect(inputBarCreated is UnknownElement, isFalse);
+        expect(isFormControl(inputBarCreated), isTrue);
+      });
+
+      test('type extension of incorrect tag', () {
+        var divBarCreated = new Element.tag("div", Bar.tag);
+        expect(divBarCreated.outerHtml, '<div is="x-bar"></div>');
+        expect(divBarCreated is Bar, isFalse);
+        expect(divBarCreated is DivElement, isTrue);
+      });
+
+      test('incorrect extension of custom tag', () {
+        var fooBarCreated = new Element.tag(Foo.tag, Bar.tag);
+        expect(
+            fooBarCreated.outerHtml,
+            anyOf([
+              '<x-foo is="x-bar"></x-foo>',
+              '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" />'
+                  '<x-foo is="x-bar"></x-foo>'
+            ]));
+        expect(fooBarCreated is Foo, isTrue);
+      });
+
+      test('incorrect extension of type extension', () {
+        var barFooCreated = new Element.tag(Bar.tag, Foo.tag);
+        expect(barFooCreated.outerHtml, '<x-bar is="x-foo"></x-bar>');
+        expect(barFooCreated is UnknownElement, isFalse);
+        expect(barFooCreated is HtmlElement, isTrue);
+      });
+
+      test('null type extension', () {
+        var fooCreatedNull = new Element.tag(Foo.tag, null);
+        expect(fooCreatedNull.outerHtml, anyOf(Foo.outerHtmlStrings));
+        expect(fooCreatedNull is Foo, isTrue);
+      });
+
+      test('empty type extension', () {
+        var fooCreatedEmpty = new Element.tag(Foo.tag, "");
+        expect(fooCreatedEmpty.outerHtml, anyOf(Foo.outerHtmlStrings));
+        expect(fooCreatedEmpty is Foo, isTrue);
+      });
+    });
+  });
+
+  group('namespaces', () {
+    test('createElementNS', () {
+      registerTypes();
+      var fooCreatedNS = document.createElementNS(
+          "http://www.w3.org/1999/xhtml", Foo.tag, null);
+      expect(fooCreatedNS.outerHtml, anyOf(Foo.outerHtmlStrings));
+      expect(fooCreatedNS is Foo, isTrue);
+
+      var barCreatedNS = document.createElementNS(
+          "http://www.w3.org/1999/xhtml", "input", Bar.tag);
+      expect(barCreatedNS.outerHtml, Bar.outerHtmlString);
+      expect(barCreatedNS is Bar, isTrue);
+      expect(isFormControl(barCreatedNS), isTrue);
+
+      expect(
+          () => document.createElementNS(
+              'http://example.com/2013/no-such-namespace', 'xml:lang', 'x-bar'),
+          throws);
+    });
+  });
+
+  group('parsing', () {
+    test('parsing', () {
+      registerTypes();
+      createElementFromHtml(html) {
+        var container = new DivElement()
+          ..setInnerHtml(html, treeSanitizer: new NullTreeSanitizer());
+        upgradeCustomElements(container);
+        return container.firstChild;
+      }
+
+      var fooParsed = createElementFromHtml('<x-foo>');
+      expect(fooParsed is Foo, isTrue);
+
+      var barParsed = createElementFromHtml('<input is=x-bar>');
+      expect(barParsed is Bar, isTrue);
+      expect(isFormControl(barParsed), isTrue);
+
+      var divFooParsed = createElementFromHtml('<div is=x-foo>');
+      expect(divFooParsed is Foo, isFalse);
+      expect(divFooParsed is DivElement, isTrue);
+
+      var namedBarParsed = createElementFromHtml('<x-bar>');
+      expect(namedBarParsed is Bar, isFalse);
+      // Polyfill does not convert parsed unregistered custom elements to
+      // HtmlElement.
+      // expect(namedBarParsed is UnknownElement, isFalse);
+      expect(namedBarParsed is HtmlElement, isTrue);
+
+      var divBarParsed = createElementFromHtml('<div is=x-bar>');
+      expect(divBarParsed is Bar, isFalse);
+      expect(divBarParsed is DivElement, isTrue);
+    });
+  });
+
+  group('functional', () {
+    test('canvas', () {
+      registerTypes();
+      var canvas = new MyCanvas();
+      canvas.fillAsRed();
+    });
+  });
+}
diff --git a/tests/lib/html/custom/document_register_type_extensions_test.html b/tests/lib/html/custom/document_register_type_extensions_test.html
new file mode 100644
index 0000000..30c2138
--- /dev/null
+++ b/tests/lib/html/custom/document_register_type_extensions_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> document_register_type_extensions_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running document_register_type_extensions_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/element_upgrade_failure_test.dart b/tests/lib/html/custom/element_upgrade_failure_test.dart
new file mode 100644
index 0000000..947af1c
--- /dev/null
+++ b/tests/lib/html/custom/element_upgrade_failure_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class FooElement extends HtmlElement {
+  static final tag = 'x-foo';
+
+  final int initializedField = 666;
+  late js.JsObject _proxy = new js.JsObject.fromBrowserObject(this);
+
+  factory FooElement() => new Element.tag(tag) as FooElement;
+  FooElement.created() : super.created();
+
+  String doSomething() => _proxy.callMethod('doSomething');
+
+  bool get fooCreated => _proxy['fooCreated'];
+}
+
+main() async {
+  await customElementsReady;
+  var upgrader = document.createElementUpgrader(FooElement);
+  js.context['upgradeListener'] = (e) {
+    upgrader.upgrade(e);
+  };
+
+  test('cannot create upgrader for interfaces', () {
+    expect(() {
+      // TODO(srujzs): Determine if this should be a static error.
+      document.createElementUpgrader(HtmlElementInterface);
+    }, throws);
+  });
+
+  test('cannot upgrade interfaces', () {
+    expect(() {
+      upgrader.upgrade(new HtmlElementInterface());
+      //                   ^^^^^^^^^^^^^^^^^^^^
+      // [analyzer] STATIC_WARNING.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
+    }, throws);
+  });
+}
+
+class HtmlElementInterface implements HtmlElement {
+  //  ^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
+  HtmlElementInterface.created();
+}
diff --git a/tests/lib/html/custom/element_upgrade_test.dart b/tests/lib/html/custom/element_upgrade_test.dart
new file mode 100644
index 0000000..ad574bd
--- /dev/null
+++ b/tests/lib/html/custom/element_upgrade_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class FooElement extends HtmlElement {
+  static final tag = 'x-foo';
+
+  final int initializedField = 666;
+  late js.JsObject _proxy = new js.JsObject.fromBrowserObject(this);
+
+  factory FooElement() => new Element.tag(tag) as FooElement;
+  FooElement.created() : super.created();
+
+  String doSomething() => _proxy.callMethod('doSomething');
+
+  bool get fooCreated => _proxy['fooCreated'];
+}
+
+main() async {
+  await customElementsReady;
+  var upgrader = document.createElementUpgrader(FooElement);
+  js.context['upgradeListener'] = (e) {
+    upgrader.upgrade(e);
+  };
+
+  document.registerElement2('custom-element', {'prototype': CustomElement});
+
+  test('created gets proxied', () {
+    var element = document.createElement(FooElement.tag);
+    expect(element is FooElement, isTrue);
+    expect((element as FooElement).initializedField, 666);
+    expect(element.text, 'constructed');
+
+    js.context.callMethod('validateIsFoo', [element]);
+
+    expect(element.doSomething(), 'didSomething');
+    expect(element.fooCreated, true);
+  });
+
+  test('dart constructor works', () {
+    var element = new FooElement();
+    expect(element is FooElement, isTrue);
+    expect(element.text, 'constructed');
+
+    js.context.callMethod('validateIsFoo', [element]);
+
+    expect(element.doSomething(), 'didSomething');
+  });
+
+  test('cannot upgrade more than once', () {
+    var fooElement = new FooElement();
+    expect(() {
+      upgrader.upgrade(fooElement);
+    }, throws);
+  });
+
+  test('cannot upgrade non-matching elements', () {
+    expect(() {
+      upgrader.upgrade(new DivElement());
+    }, throws);
+  });
+
+  test('cannot upgrade custom elements', () {
+    var custom = new CustomElement();
+    expect(() {
+      upgrader.upgrade(custom);
+    }, throws);
+  });
+
+  test('can upgrade with extendsTag', () {
+    var upgrader = document.createElementUpgrader(CustomDiv, extendsTag: 'div');
+    var div = new DivElement();
+    var customDiv = upgrader.upgrade(div);
+    expect(customDiv is CustomDiv, isTrue);
+
+    var htmlElement = document.createElement('not-registered');
+    expect(() {
+      upgrader.upgrade(htmlElement);
+    }, throws);
+  });
+
+  test('cannot create upgrader for built-in types', () {
+    expect(() {
+      document.createElementUpgrader(HtmlElement);
+    }, throws);
+  });
+}
+
+class CustomDiv extends DivElement {
+  CustomDiv.created() : super.created();
+}
+
+class CustomElement extends HtmlElement {
+  factory CustomElement() =>
+      document.createElement('custom-element') as CustomElement;
+  CustomElement.created() : super.created();
+}
diff --git a/tests/lib/html/custom/element_upgrade_test.html b/tests/lib/html/custom/element_upgrade_test.html
new file mode 100644
index 0000000..e06cdbc
--- /dev/null
+++ b/tests/lib/html/custom/element_upgrade_test.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta name="dart.unittest" content="full-stack-traces">
+<title> element_upgrade_test </title>
+<style>
+   .unittest-table { font-family:monospace; border:1px; }
+   .unittest-pass { background: #6b3;}
+   .unittest-fail { background: #d55;}
+   .unittest-error { background: #a11;}
+</style>
+<script src="/packages/web_components/webcomponents.js"></script>
+<script src="/packages/web_components/dart_support.js"></script>
+
+<body>
+  <h1> Running element_upgrade_test </h1>
+
+<script>
+var Foo = function() {};
+Foo.prototype = Object.create(HTMLElement.prototype);
+Foo.prototype.createdCallback = function() {
+  this.fooCreated = true;
+  this.textContent = 'constructed';
+
+  // Tell the Dart side that this was created.
+  // For testing purposes, for real code this would use a different mechanism.
+  window.upgradeListener(this);
+};
+
+Foo.prototype.doSomething = function() {
+  this.textContent = 'didSomething';
+  return 'didSomething';
+};
+
+Foo = document.registerElement('x-foo', Foo);
+
+function validateIsFoo(element) {
+  if (!(element instanceof Foo)) {
+    throw Error('Element is not a Foo');
+  }
+
+  if (!element.fooCreated) {
+    throw Error('Expected fooCreated to be set');
+  }
+}
+</script>
+
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
diff --git a/tests/lib/html/custom/entered_left_view/disconnected_subtree_test.dart b/tests/lib/html/custom/entered_left_view/disconnected_subtree_test.dart
new file mode 100644
index 0000000..dba7ed4
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/disconnected_subtree_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2020 the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'entered_left_view_util.dart';
+import 'package:async_helper/async_minitest.dart';
+
+import '../utils.dart';
+
+main() async {
+  await setupFunc();
+  group('disconnected_subtree', () {
+    var div = new DivElement();
+
+    setUp() {
+      invocations = [];
+    }
+
+    test('Enters a disconnected subtree of DOM', () {
+      setUp();
+      div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+      upgradeCustomElements(div);
+
+      expect(invocations, ['created'],
+          reason: 'the attached callback should not be invoked when inserted '
+              'into a disconnected subtree');
+    });
+
+    test('Leaves a disconnected subtree of DOM', () {
+      setUp();
+      div.innerHtml = '';
+      expect(invocations, [],
+          reason:
+              'the detached callback should not be invoked when removed from a '
+              'disconnected subtree');
+    });
+
+    test('Enters a document with a view as a constituent of a subtree', () {
+      setUp();
+      div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+      upgradeCustomElements(div);
+      invocations = [];
+      document.body!.append(div);
+      customElementsTakeRecords();
+      expect(invocations, ['attached'],
+          reason:
+              'the attached callback should be invoked when inserted into a '
+              'document with a view as part of a subtree');
+    });
+  });
+}
diff --git a/tests/lib/html/custom/entered_left_view/disconnected_subtree_test.html b/tests/lib/html/custom/entered_left_view/disconnected_subtree_test.html
new file mode 100644
index 0000000..0fd8683
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/disconnected_subtree_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> disconnected_subtree_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running disconnected_subtree_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/entered_left_view/entered_left_view_standard_events_test.dart b/tests/lib/html/custom/entered_left_view/entered_left_view_standard_events_test.dart
new file mode 100644
index 0000000..3d78763
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/entered_left_view_standard_events_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2020 the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'entered_left_view_util.dart';
+import 'package:async_helper/async_minitest.dart';
+
+import '../utils.dart';
+
+main() async {
+  await setupFunc();
+  group('standard_events', () {
+    var a;
+    setUp() {
+      invocations = [];
+    }
+
+    test('Created', () {
+      setUp();
+      a = new Element.tag('x-a');
+      expect(invocations, ['created']);
+    });
+
+    test('attached', () {
+      setUp();
+      document.body!.append(a);
+      customElementsTakeRecords();
+      expect(invocations, ['attached']);
+    });
+
+    test('detached', () {
+      setUp();
+      a.remove();
+      customElementsTakeRecords();
+      expect(invocations, ['detached']);
+    });
+
+    var div = new DivElement();
+    test('nesting does not trigger attached', () {
+      setUp();
+      div.append(a);
+      customElementsTakeRecords();
+      expect(invocations, []);
+    });
+
+    test('nested entering triggers attached', () {
+      setUp();
+      document.body!.append(div);
+      customElementsTakeRecords();
+      expect(invocations, ['attached']);
+    });
+
+    test('nested leaving triggers detached', () {
+      setUp();
+      div.remove();
+      customElementsTakeRecords();
+      expect(invocations, ['detached']);
+    });
+  });
+}
diff --git a/tests/lib/html/custom/entered_left_view/entered_left_view_standard_events_test.html b/tests/lib/html/custom/entered_left_view/entered_left_view_standard_events_test.html
new file mode 100644
index 0000000..3688e05
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/entered_left_view_standard_events_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> entered_left_view_standard_events_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running entered_left_view_standard_events_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/entered_left_view/entered_left_view_util.dart b/tests/lib/html/custom/entered_left_view/entered_left_view_util.dart
new file mode 100644
index 0000000..d5f6e7d
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/entered_left_view_util.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:async_helper/async_minitest.dart';
+
+import '../utils.dart';
+
+var invocations = [];
+
+class Foo extends HtmlElement {
+  Foo.created() : super.created() {
+    invocations.add('created');
+  }
+
+  void attached() {
+    invocations.add('attached');
+  }
+
+  void enteredView() {
+    // Deprecated name. Should never be called since we override "attached".
+    invocations.add('enteredView');
+  }
+
+  void detached() {
+    invocations.add('detached');
+  }
+
+  void leftView() {
+    // Deprecated name. Should never be called since we override "detached".
+    invocations.add('leftView');
+  }
+
+  void attributeChanged(String name, String oldValue, String newValue) {
+    invocations.add('attribute changed');
+  }
+}
+
+// Test that the deprecated callbacks still work.
+class FooOldCallbacks extends HtmlElement {
+  FooOldCallbacks.created() : super.created() {
+    invocations.add('created');
+  }
+
+  void enteredView() {
+    invocations.add('enteredView');
+  }
+
+  void leftView() {
+    invocations.add('leftView');
+  }
+
+  void attributeChanged(String name, String oldValue, String newValue) {
+    invocations.add('attribute changed');
+  }
+}
+
+var docA = document;
+var docB = document.implementation.createHtmlDocument('');
+var nullSanitizer = new NullTreeSanitizer();
+
+setupFunc() {
+  // Adapted from Blink's
+  // fast/dom/custom/attached-detached-document.html test.
+  return customElementsReady.then((_) {
+    document.registerElement2('x-a', {'prototype': Foo});
+    document.registerElement2('x-a-old', {'prototype': FooOldCallbacks});
+  });
+}
diff --git a/tests/lib/html/custom/entered_left_view/shadow_dom_test.dart b/tests/lib/html/custom/entered_left_view/shadow_dom_test.dart
new file mode 100644
index 0000000..3da372e
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/shadow_dom_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2020 the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'entered_left_view_util.dart';
+import 'package:async_helper/async_minitest.dart';
+
+import '../utils.dart';
+
+main() async {
+  await setupFunc();
+  group('shadow_dom', () {
+    var div;
+    var s;
+    setUp() {
+      invocations = [];
+      div = new DivElement();
+      s = div.createShadowRoot();
+    }
+
+    tearDown() {
+      customElementsTakeRecords();
+    }
+
+    test('Created in Shadow DOM that is not in a document', () {
+      setUp();
+      s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+      upgradeCustomElements(s);
+
+      expect(invocations, ['created'],
+          reason: 'the attached callback should not be invoked when entering a '
+              'Shadow DOM subtree not in the document');
+      tearDown();
+    });
+
+    test('Leaves Shadow DOM that is not in a document', () {
+      setUp();
+      s.innerHtml = '';
+      expect(invocations, [],
+          reason: 'the detached callback should not be invoked when leaving a '
+              'Shadow DOM subtree not in the document');
+      tearDown();
+    });
+
+    test('Enters a document with a view as a constituent of Shadow DOM', () {
+      setUp();
+      s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+      upgradeCustomElements(s);
+
+      document.body!.append(div);
+      customElementsTakeRecords();
+      expect(invocations, ['created', 'attached'],
+          reason: 'the attached callback should be invoked when inserted into '
+              'a document with a view as part of Shadow DOM');
+
+      div.remove();
+      customElementsTakeRecords();
+
+      expect(invocations, ['created', 'attached', 'detached'],
+          reason: 'the detached callback should be invoked when removed from a '
+              'document with a view as part of Shadow DOM');
+      tearDown();
+    });
+  });
+}
diff --git a/tests/lib/html/custom/entered_left_view/shadow_dom_test.html b/tests/lib/html/custom/entered_left_view/shadow_dom_test.html
new file mode 100644
index 0000000..c0967ae
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/shadow_dom_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> shadow_dom_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running shadow_dom_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/entered_left_view/standard_events_old_callback_names_test.dart b/tests/lib/html/custom/entered_left_view/standard_events_old_callback_names_test.dart
new file mode 100644
index 0000000..27bafae
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/standard_events_old_callback_names_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020 the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'entered_left_view_util.dart';
+import 'package:async_helper/async_minitest.dart';
+
+import '../utils.dart';
+
+main() async {
+  await setupFunc();
+  // TODO(jmesserly): remove after deprecation period.
+  group('standard_events_old_callback_names', () {
+    var a;
+    setUp() {
+      invocations = [];
+    }
+
+    test('Created', () {
+      setUp();
+      a = new Element.tag('x-a-old');
+      expect(invocations, ['created']);
+    });
+
+    test('enteredView', () {
+      setUp();
+      document.body!.append(a);
+      customElementsTakeRecords();
+      expect(invocations, ['enteredView']);
+    });
+
+    test('leftView', () {
+      setUp();
+      a.remove();
+      customElementsTakeRecords();
+      expect(invocations, ['leftView']);
+    });
+
+    var div = new DivElement();
+    test('nesting does not trigger enteredView', () {
+      setUp();
+      div.append(a);
+      customElementsTakeRecords();
+      expect(invocations, []);
+    });
+
+    test('nested entering triggers enteredView', () {
+      setUp();
+      document.body!.append(div);
+      customElementsTakeRecords();
+      expect(invocations, ['enteredView']);
+    });
+
+    test('nested leaving triggers leftView', () {
+      setUp();
+      div.remove();
+      customElementsTakeRecords();
+      expect(invocations, ['leftView']);
+    });
+  });
+}
diff --git a/tests/lib/html/custom/entered_left_view/standard_events_old_callback_names_test.html b/tests/lib/html/custom/entered_left_view/standard_events_old_callback_names_test.html
new file mode 100644
index 0000000..b8d57a1
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/standard_events_old_callback_names_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> standard_events_old_callback_names_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running standard_events_old_callback_names_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/entered_left_view/viewless_document_test.dart b/tests/lib/html/custom/entered_left_view/viewless_document_test.dart
new file mode 100644
index 0000000..33fa4a4
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/viewless_document_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2020 the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'entered_left_view_util.dart';
+import 'package:async_helper/async_minitest.dart';
+
+import '../utils.dart';
+
+main() async {
+  await setupFunc();
+  group('viewless_document', () {
+    var a;
+    setUp() {
+      invocations = [];
+    }
+
+    test('Created, owned by a document without a view', () {
+      setUp();
+      a = docB.createElement('x-a');
+      expect(a.ownerDocument, docB,
+          reason: 'new instance should be owned by the document the definition '
+              'was registered with');
+      expect(invocations, ['created'],
+          reason: 'calling the constructor should invoke the created callback');
+    });
+
+    test('Entered document without a view', () {
+      setUp();
+      docB.body!.append(a);
+      expect(invocations, [],
+          reason: 'attached callback should not be invoked when entering a '
+              'document without a view');
+    });
+
+    test('Attribute changed in document without a view', () {
+      setUp();
+      a.setAttribute('data-foo', 'bar');
+      expect(invocations, ['attribute changed'],
+          reason: 'changing an attribute should invoke the callback, even in a '
+              'document without a view');
+    });
+
+    test('Entered document with a view', () {
+      setUp();
+      document.body!.append(a);
+      customElementsTakeRecords();
+      expect(invocations, ['attached'],
+          reason:
+              'attached callback should be invoked when entering a document '
+              'with a view');
+    });
+
+    test('Left document with a view', () {
+      setUp();
+      a.remove();
+      customElementsTakeRecords();
+      expect(invocations, ['detached'],
+          reason: 'detached callback should be invoked when leaving a document '
+              'with a view');
+    });
+
+    test('Created in a document without a view', () {
+      setUp();
+      docB.body!.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+      upgradeCustomElements(docB.body!);
+
+      expect(invocations, ['created'],
+          reason: 'only created callback should be invoked when parsing a '
+              'custom element in a document without a view');
+    });
+  });
+}
diff --git a/tests/lib/html/custom/entered_left_view/viewless_document_test.html b/tests/lib/html/custom/entered_left_view/viewless_document_test.html
new file mode 100644
index 0000000..f3b2182
--- /dev/null
+++ b/tests/lib/html/custom/entered_left_view/viewless_document_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> viewless_document_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running viewless_document_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom/regress_194523002_test.dart b/tests/lib/html/custom/regress_194523002_test.dart
new file mode 100644
index 0000000..1d36000
--- /dev/null
+++ b/tests/lib/html/custom/regress_194523002_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for CL 194523002.
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'utils.dart';
+
+class A extends HtmlElement {
+  static final tag = 'x-a';
+  factory A() => new Element.tag(tag) as A;
+  A.created() : super.created();
+}
+
+main() async {
+  // Adapted from Blink's
+  // fast/dom/custom/constructor-calls-created-synchronously test.
+
+  await customElementsReady;
+  document.registerElement2(A.tag, {'prototype': A});
+}
diff --git a/tests/lib/html/custom/utils.dart b/tests/lib/html/custom/utils.dart
new file mode 100644
index 0000000..5fb73a7f
--- /dev/null
+++ b/tests/lib/html/custom/utils.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+/**
+ * Verifies that [actual] has the same graph structure as [expected].
+ * Detects cycles and DAG structure in Maps and Lists.
+ */
+verifyGraph(expected, actual) {
+  var eItems = [];
+  var aItems = [];
+
+  message(path, reason) => path == ''
+      ? reason
+      : reason == null ? "path: $path" : "path: $path, $reason";
+
+  walk(path, expected, actual) {
+    if (expected is String || expected is num || expected == null) {
+      expect(actual, equals(expected), reason: message(path, 'not equal'));
+      return;
+    }
+
+    // Cycle or DAG?
+    for (int i = 0; i < eItems.length; i++) {
+      if (identical(expected, eItems[i])) {
+        expect(actual, same(aItems[i]),
+            reason: message(path, 'missing back or side edge'));
+        return;
+      }
+    }
+    for (int i = 0; i < aItems.length; i++) {
+      if (identical(actual, aItems[i])) {
+        expect(expected, same(eItems[i]),
+            reason: message(path, 'extra back or side edge'));
+        return;
+      }
+    }
+    eItems.add(expected);
+    aItems.add(actual);
+
+    if (expected is Blob) {
+      expect(actual is Blob, isTrue, reason: '$actual is Blob');
+      expect(expected.type, equals(actual.type),
+          reason: message(path, '.type'));
+      expect(expected.size, equals(actual.size),
+          reason: message(path, '.size'));
+      return;
+    }
+
+    if (expected is ByteBuffer) {
+      expect(actual is ByteBuffer, isTrue, reason: '$actual is ByteBuffer');
+      expect(expected.lengthInBytes, equals(actual.lengthInBytes),
+          reason: message(path, '.lengthInBytes'));
+      // TODO(antonm): one can create a view on top of those
+      // and check if contents identical.  Let's do it later.
+      return;
+    }
+
+    if (expected is DateTime) {
+      expect(actual is DateTime, isTrue, reason: '$actual is DateTime');
+      expect(expected.millisecondsSinceEpoch,
+          equals(actual.millisecondsSinceEpoch),
+          reason: message(path, '.millisecondsSinceEpoch'));
+      return;
+    }
+
+    if (expected is ImageData) {
+      expect(actual is ImageData, isTrue, reason: '$actual is ImageData');
+      expect(expected.width, equals(actual.width),
+          reason: message(path, '.width'));
+      expect(expected.height, equals(actual.height),
+          reason: message(path, '.height'));
+      walk('$path.data', expected.data, actual.data);
+      return;
+    }
+
+    if (expected is TypedData) {
+      expect(actual is TypedData, isTrue, reason: '$actual is TypedData');
+      walk('$path/.buffer', expected.buffer, actual.buffer);
+      expect(expected.offsetInBytes, equals(actual.offsetInBytes),
+          reason: message(path, '.offsetInBytes'));
+      expect(expected.lengthInBytes, equals(actual.lengthInBytes),
+          reason: message(path, '.lengthInBytes'));
+      // And also fallback to elements check below.
+    }
+
+    if (expected is List) {
+      expect(actual, predicate((v) => v is List),
+          reason: message(path, '$actual is List'));
+      expect(actual.length, expected.length,
+          reason: message(path, 'different list lengths'));
+      for (var i = 0; i < expected.length; i++) {
+        walk('$path[$i]', expected[i], actual[i]);
+      }
+      return;
+    }
+
+    if (expected is Map) {
+      expect(actual, predicate((v) => v is Map),
+          reason: message(path, '$actual is Map'));
+      for (var key in expected.keys) {
+        if (!actual.containsKey(key)) {
+          expect(false, isTrue, reason: message(path, 'missing key "$key"'));
+        }
+        walk('$path["$key"]', expected[key], actual[key]);
+      }
+      for (var key in actual.keys) {
+        if (!expected.containsKey(key)) {
+          expect(false, isTrue, reason: message(path, 'extra key "$key"'));
+        }
+      }
+      return;
+    }
+
+    expect(false, isTrue, reason: 'Unhandled type: $expected');
+  }
+
+  walk('', expected, actual);
+}
+
+/**
+ * Sanitizer which does nothing.
+ */
+class NullTreeSanitizer implements NodeTreeSanitizer {
+  void sanitizeTree(Node node) {}
+}
+
+/**
+ * Validate that two DOM trees are equivalent.
+ */
+void validateNodeTree(Node a, Node b, [String path = '']) {
+  path = '${path}${a.runtimeType}';
+  expect(a.nodeType, b.nodeType, reason: '$path nodeTypes differ');
+  expect(a.nodeValue, b.nodeValue, reason: '$path nodeValues differ');
+  expect(a.text, b.text, reason: '$path texts differ');
+  expect(a.nodes.length, b.nodes.length, reason: '$path nodes.lengths differ');
+
+  if (a is Element) {
+    Element bE = b as Element;
+    Element aE = a;
+
+    expect(aE.tagName, bE.tagName, reason: '$path tagNames differ');
+    expect(aE.attributes.length, bE.attributes.length,
+        reason: '$path attributes.lengths differ');
+    for (var key in aE.attributes.keys) {
+      expect(aE.attributes[key], bE.attributes[key],
+          reason: '$path attribute [$key] values differ');
+    }
+  }
+  for (var i = 0; i < a.nodes.length; ++i) {
+    validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
+  }
+}
+
+/**
+ * Upgrade all custom elements in the subtree which have not been upgraded.
+ *
+ * This is needed to cover timing scenarios which the custom element polyfill
+ * does not cover.
+ */
+void upgradeCustomElements(Node node) {
+  if (js.context.hasProperty('CustomElements') &&
+      js.context['CustomElements'].hasProperty('upgradeAll')) {
+    js.context['CustomElements'].callMethod('upgradeAll', [node]);
+  }
+}
+
+/**
+ * A future that completes once all custom elements in the initial HTML page
+ * have been upgraded.
+ *
+ * This is needed because the native implementation can update the elements
+ * while parsing the HTML document, but the custom element polyfill cannot,
+ * so it completes this future once all elements are upgraded.
+ */
+// TODO(jmesserly): rename to webComponentsReady to match the event?
+Future customElementsReady = () {
+  if (_isReady) return new Future.value();
+
+  // Not upgraded. Wait for the polyfill to fire the WebComponentsReady event.
+  // Note: we listen on document (not on document.body) to allow this polyfill
+  // to be loaded in the HEAD element.
+  return document.on['WebComponentsReady'].first;
+}();
+
+// Return true if we are using the polyfill and upgrade is complete, or if we
+// have native document.register and therefore the browser took care of it.
+// Otherwise return false, including the case where we can't find the polyfill.
+bool get _isReady {
+  // If we don't have dart:js, assume things are ready
+  if (js.context == null) return true;
+
+  var customElements = js.context['CustomElements'];
+  if (customElements == null) {
+    // Return true if native document.register, otherwise false.
+    // (Maybe the polyfill isn't loaded yet. Wait for it.)
+    return document.supportsRegisterElement;
+  }
+
+  return customElements['ready'] == true;
+}
+
+/**
+ * *Note* this API is primarily intended for tests. In other code it is better
+ * to write it in a style that works with or without the polyfill, rather than
+ * using this method.
+ *
+ * Synchronously trigger evaluation of pending lifecycle events, which otherwise
+ * need to wait for a [MutationObserver] to signal the changes in the polyfill.
+ * This method can be used to resolve differences in timing between native and
+ * polyfilled custom elements.
+ */
+void customElementsTakeRecords([Node? node]) {
+  var customElements = js.context['CustomElements'];
+  if (customElements == null) return;
+  customElements.callMethod('takeRecords', [node]);
+}
diff --git a/tests/lib/html/custom_element_method_clash_test.dart b/tests/lib/html/custom_element_method_clash_test.dart
new file mode 100644
index 0000000..cd18adb
--- /dev/null
+++ b/tests/lib/html/custom_element_method_clash_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library custom_elements_method_clash;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:async_helper/async_minitest.dart';
+import 'utils.dart';
+
+class CustomElement extends HtmlElement {
+  factory CustomElement() => new Element.tag('x-custom') as CustomElement;
+
+  CustomElement.created() : super.created() {}
+
+  // Try to clash with native 'appendChild' method.
+  void appendChild() {
+    throw 'Gotcha!';
+  }
+}
+
+main() async {
+  await customElementsReady;
+
+  group('test', () {
+    test('test', () {
+      document.registerElement2('x-custom', {'prototype': CustomElement});
+      CustomElement custom = new CustomElement();
+      document.body!.children.add(custom);
+
+      // Will call appendChild in JS.
+      custom.children.add(new DivElement()..text = 'Hello world!');
+
+      try {
+        custom.appendChild(); // Make sure method is not tree shaken.
+        fail('appendChild did not throw');
+      } catch (e) {
+        expect(e, equals('Gotcha!'));
+      }
+    });
+  });
+}
diff --git a/tests/lib/html/custom_element_method_clash_test.html b/tests/lib/html/custom_element_method_clash_test.html
new file mode 100644
index 0000000..1c216a5
--- /dev/null
+++ b/tests/lib/html/custom_element_method_clash_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> custom_element_method_clash_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running custom_element_method_clash_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom_element_name_clash_test.dart b/tests/lib/html/custom_element_name_clash_test.dart
new file mode 100644
index 0000000..098bc93
--- /dev/null
+++ b/tests/lib/html/custom_element_name_clash_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library custom_elements_name_clash;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:async_helper/async_minitest.dart';
+import 'utils.dart';
+
+class CustomElement extends HtmlElement {
+  factory CustomElement() => new Element.tag('x-custom') as CustomElement;
+
+  CustomElement.created() : super.created() {}
+
+  // Try to clash with native 'appendChild' method.
+  var appendChild = 123;
+}
+
+main() async {
+  await customElementsReady;
+
+  group('test', () {
+    test('test', () {
+      document.registerElement2('x-custom', {'prototype': CustomElement});
+      CustomElement custom = new CustomElement();
+      document.body!.children.add(custom);
+      // Will call appendChild in JS.
+      custom.children.add(new DivElement()..text = 'Hello world!');
+    });
+  });
+}
diff --git a/tests/lib/html/custom_element_name_clash_test.html b/tests/lib/html/custom_element_name_clash_test.html
new file mode 100644
index 0000000..289b371
--- /dev/null
+++ b/tests/lib/html/custom_element_name_clash_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> custom_element_name_clash_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running custom_element_name_clash_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom_elements_23127_test.dart b/tests/lib/html/custom_elements_23127_test.dart
new file mode 100644
index 0000000..395de21
--- /dev/null
+++ b/tests/lib/html/custom_elements_23127_test.dart
@@ -0,0 +1,131 @@
+// 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.
+
+// Regression test for http://dartbug.com/23127
+// Tests super calls to a custom element upgrade constructor with various
+// combinations of parameters and type arguments.
+
+library custom_elements_23127_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:async_helper/async_minitest.dart';
+import 'utils.dart';
+
+abstract class B1 extends HtmlElement {
+  void action();
+
+  B1.created() : super.created() {
+    action();
+  }
+}
+
+abstract class B1T<T> extends HtmlElement {
+  void action();
+  var qq = false;
+  B1T.created() : super.created() {
+    action();
+    qq = this is T;
+  }
+}
+
+abstract class B2 extends HtmlElement {
+  void action();
+  var qq;
+  B2.created([a = 1, b = 2, c = 3])
+      : qq = callTwice(() => ++a * ++b), // [a] and [b] are boxed.
+        super.created() {
+    action();
+    qq = [qq, a, b, c];
+  }
+}
+
+abstract class B2T<T> extends HtmlElement {
+  void action();
+  var qq;
+  B2T.created([a = 1, b = 2, c = 3])
+      : qq = callTwice(() => ++a * ++b),
+        super.created() {
+    action();
+    qq = [this is T, qq, a, b, c];
+  }
+}
+
+class C1 extends B1 {
+  int z = 0;
+  C1.created() : super.created();
+  action() {
+    z = 3;
+  }
+}
+
+class C1T extends B1T {
+  int z = 0;
+  C1T.created() : super.created();
+  action() {
+    z = 3;
+  }
+}
+
+class C2 extends B2 {
+  int z = 0;
+  C2.created() : super.created(20);
+  action() {
+    z = 3;
+  }
+}
+
+class C2T extends B2T {
+  int z = 0;
+  C2T.created() : super.created(20);
+  action() {
+    z = 3;
+  }
+}
+
+var callTwice;
+
+main() async {
+  await customElementsReady;
+
+  callTwice = (f) {
+    f();
+    return f();
+  };
+
+  group('baseline', () {
+    test('C1', () {
+      document.register('x-c1', C1);
+      C1 e = document.createElement('x-c1') as C1;
+      expect(e.z, 3);
+    });
+  });
+
+  group('c1t', () {
+    test('C1T', () {
+      document.register('x-c1t', C1T);
+      C1T e = document.createElement('x-c1t') as C1T;
+      expect(e.z, 3);
+      expect(e.qq, true);
+    });
+  });
+
+  group('c2', () {
+    test('C2', () {
+      document.register('x-c2', C2);
+      C2 e = document.createElement('x-c2') as C2;
+      expect(e.z, 3);
+      expect(e.qq, [88, 22, 4, 3]);
+    });
+  });
+
+  group('c2t', () {
+    test('C2T', () {
+      document.register('x-c2t', C2T);
+      C2T e = document.createElement('x-c2t') as C2T;
+      expect(e.z, 3);
+      expect(e.qq, [true, 88, 22, 4, 3]);
+    });
+  });
+}
diff --git a/tests/lib/html/custom_elements_23127_test.html b/tests/lib/html/custom_elements_23127_test.html
new file mode 100644
index 0000000..1384fa0
--- /dev/null
+++ b/tests/lib/html/custom_elements_23127_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> custom_elements_23127_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running custom_elements_23127_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom_elements_test.dart b/tests/lib/html/custom_elements_test.dart
new file mode 100644
index 0000000..30e14a7
--- /dev/null
+++ b/tests/lib/html/custom_elements_test.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library custom_elements_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:async_helper/async_minitest.dart';
+import 'utils.dart';
+
+class CustomMixin {
+  var mixinMethodCalled;
+
+  void mixinMethod() {
+    mixinMethodCalled = true;
+  }
+}
+
+class CustomType extends HtmlElement with CustomMixin {
+  bool createdCalled = false;
+
+  CustomType.created() : super.created() {
+    createdCalled = true;
+    customCreatedCount++;
+  }
+
+  void invokeMixinMethod() {
+    mixinMethod();
+  }
+}
+
+int customCreatedCount = 0;
+
+int nextTagId = 0;
+String get nextTag => 'x-type${nextTagId++}';
+
+class NotAnElement {}
+
+main() async {
+  await customElementsReady;
+
+  group('register', () {
+    test('register', () {
+      var tag = nextTag;
+      document.registerElement(tag, CustomType);
+
+      var element = new Element.tag(tag) as CustomType;
+      expect(element, isNotNull);
+      expect(element is CustomType, isTrue);
+      expect(element.createdCalled, isTrue);
+    });
+
+    test('register twice', () {
+      var tag = nextTag;
+      document.registerElement(tag, CustomType);
+      expect(() {
+        document.registerElement(tag, CustomType);
+      }, throws, reason: 'Cannot register a tag more than once.');
+
+      var newTag = nextTag;
+      document.registerElement(newTag, CustomType);
+
+      var element = new Element.tag(newTag) as CustomType;
+      expect(element, isNotNull);
+      expect(element is CustomType, isTrue);
+    });
+
+    test('register native', () {
+      expect(() {
+        document.registerElement(nextTag, BodyElement);
+      }, throws, reason: 'Cannot register a native element.');
+    });
+
+    test('register non-element', () {
+      expect(() {
+        document.registerElement(nextTag, NotAnElement);
+      }, throws, reason: 'Cannot register a non-element.');
+    });
+  });
+
+  // TODO(vsm): Modify this test once we agree on the proper semantics.
+  /*
+  group('preregister', () {
+
+    test('pre-registration construction', () {
+      var tag = nextTag;
+      var dom = new Element.html('<div><$tag></$tag></div>');
+
+      var preElement = dom.children[0];
+      expect(preElement, isNotNull);
+      expect(preElement is HtmlElement, isTrue);
+      expect(preElement is CustomType, isFalse);
+      var firedOnPre = false;
+      preElement.onFocus.listen((_) {
+        firedOnPre = true;
+      });
+
+      document.registerElement(tag, CustomType);
+      upgradeCustomElements(dom);
+
+      var postElement = dom.children[0];
+      expect(postElement, isNotNull);
+      expect(postElement is CustomType, isTrue);
+      expect(postElement.createdCalled, isTrue);
+
+      // Element from first query remains an UnknownElement.
+      expect(preElement is HtmlElement, isTrue);
+      expect(preElement.parent, dom);
+      expect(dom.children.length, 1);
+
+      var firedOnPost = false;
+      postElement.onFocus.listen((_) {
+        firedOnPost = true;
+      });
+      // Event handlers persist on old and new element.
+      postElement.dispatchEvent(new Event('focus'));
+      expect(firedOnPre, isTrue);
+      expect(firedOnPost, isTrue);
+    });
+  });*/
+
+  group('innerHtml', () {
+    test('query', () {
+      var tag = nextTag;
+      document.registerElement(tag, CustomType);
+      var element = new DivElement();
+      element.setInnerHtml('<$tag></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+      upgradeCustomElements(element);
+      document.body!.nodes.add(element);
+      var queried = querySelector(tag) as CustomType;
+
+      expect(queried, isNotNull);
+      expect(queried is CustomType, isTrue);
+      expect(queried.createdCalled, isTrue);
+    });
+
+    test('query id', () {
+      var tag = nextTag;
+      document.registerElement(tag, CustomType);
+      var element = new DivElement();
+      element.setInnerHtml('<$tag id="someid"></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+      upgradeCustomElements(element);
+      document.body!.nodes.add(element);
+      var queried = querySelector('#someid') as CustomType;
+
+      expect(queried, isNotNull);
+      expect(queried is CustomType, isTrue);
+      expect(queried.id, "someid");
+    });
+  });
+
+  group('lifecycle', () {
+    test('created', () {
+      int oldCount = customCreatedCount;
+      var tag = nextTag;
+      document.registerElement(tag, CustomType);
+      var element = new DivElement();
+      element.setInnerHtml('<$tag></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+      upgradeCustomElements(element);
+      document.body!.nodes.add(element);
+      expect(customCreatedCount, oldCount + 1);
+    });
+  });
+
+  group('mixins', () {
+    test('can invoke mixin methods', () {
+      var tag = nextTag;
+      document.registerElement(tag, CustomType);
+
+      var element = new Element.tag(tag) as CustomType;
+      element.invokeMixinMethod();
+      expect(element.mixinMethodCalled, isTrue);
+    });
+  });
+}
diff --git a/tests/lib/html/custom_elements_test.html b/tests/lib/html/custom_elements_test.html
new file mode 100644
index 0000000..a5751b8
--- /dev/null
+++ b/tests/lib/html/custom_elements_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> custom_elements_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <h1> Running custom_elements_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/custom_tags_test.dart b/tests/lib/html/custom_tags_test.dart
new file mode 100644
index 0000000..98b60c2
--- /dev/null
+++ b/tests/lib/html/custom_tags_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+main() {
+  test('create via custom tag', () {
+    var element = new Element.tag('x-basic1')..id = 'basic1';
+    document.body!.nodes.add(element);
+
+    var queryById = querySelector('#basic1');
+    expect(queryById, equals(element));
+
+    var queryByTag = querySelectorAll('x-basic1');
+    expect(queryByTag.length, equals(1));
+    expect(queryByTag[0], equals(element));
+  });
+
+  test('custom inner html', () {
+    var element = new DivElement();
+    element.setInnerHtml("<x-basic2 id='basic2'></x-basic2>",
+        treeSanitizer: new NullTreeSanitizer());
+    document.body!.nodes.add(element);
+
+    var queryById = querySelector('#basic2');
+    expect(queryById is Element, isTrue);
+
+    var queryByTag = querySelectorAll('x-basic2');
+    expect(queryByTag.length, equals(1));
+    expect(queryByTag[0], equals(queryById));
+  });
+
+  test('type extension inner html', () {
+    var element = new DivElement();
+    element.setInnerHtml("<div is='x-basic3' id='basic3'></div>",
+        treeSanitizer: new NullTreeSanitizer());
+    document.body!.nodes.add(element);
+
+    var queryById = querySelector('#basic3');
+    expect(queryById is DivElement, isTrue);
+  });
+}
diff --git a/tests/lib/html/dart_object_local_storage_test.dart b/tests/lib/html/dart_object_local_storage_test.dart
new file mode 100644
index 0000000..3c7130b
--- /dev/null
+++ b/tests/lib/html/dart_object_local_storage_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+// TODO(vsm): Rename this to wrapper_caching_test or similar.  It's
+// basically a port of dom/dart_object_local_storage_test.dart.  For
+// wrapping implementation of dart:html (i.e., the dartium one), it is
+// effectively testing dart_object_local_storage in the underlying dom
+// object.
+main() {
+  BodyElement body = document.body!;
+  Storage localStorage = window.localStorage;
+  Storage sessionStorage = window.sessionStorage;
+  var element = new Element.tag('canvas');
+  element.id = 'test';
+  body.append(element);
+
+  test('body', () {
+    expect(body, equals(document.body));
+  });
+  test('localStorage', () {
+    expect(localStorage, equals(window.localStorage));
+  });
+  test('sessionStorage', () {
+    expect(sessionStorage, equals(window.sessionStorage));
+  });
+  test('unknown', () {
+    var test = document.querySelector('#test');
+    expect(element, equals(test));
+  });
+}
diff --git a/tests/lib/html/datalistelement_test.dart b/tests/lib/html/datalistelement_test.dart
new file mode 100644
index 0000000..2a9396d
--- /dev/null
+++ b/tests/lib/html/datalistelement_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isDataListElement =
+      predicate((x) => x is DataListElement, 'is a DataListElement');
+
+  var div;
+
+  setUp(() {
+    div = new DivElement();
+    document.body!.append(div);
+    div.innerHtml = """
+<input id="input" list="browsers" />
+<datalist id="browsers">
+  <option value="Chrome">
+  <option value="Firefox">
+  <option value="Internet Explorer">
+  <option value="Opera">
+  <option value="Safari">
+</datalist>
+""";
+  });
+
+  tearDown(() {
+    document.body!.nodes.removeLast();
+  });
+
+  test('is', () {
+    try {
+      var list = document.querySelector('#browsers');
+      expect(list, isDataListElement);
+    } catch (e) {
+      expect(DataListElement.supported, false);
+    }
+  });
+
+  test('list', () {
+    try {
+      var list = document.querySelector('#browsers') as DataListElement;
+      var input = document.querySelector('#input') as InputElement;
+      expect(input.list, list);
+    } catch (e) {
+      expect(DataListElement.supported, false);
+    }
+  });
+
+  test('options', () {
+    try {
+      var options =
+          (document.querySelector('#browsers') as DataListElement).options;
+      expect(options.length, 5);
+    } catch (e) {
+      expect(DataListElement.supported, false);
+    }
+  });
+
+  test('create', () {
+    try {
+      var list = new DataListElement();
+      expect(list, isDataListElement);
+    } catch (e) {
+      expect(DataListElement.supported, false);
+    }
+  });
+}
diff --git a/tests/lib/html/dispatch_parent_event.js b/tests/lib/html/dispatch_parent_event.js
new file mode 100644
index 0000000..ee204b4
--- /dev/null
+++ b/tests/lib/html/dispatch_parent_event.js
@@ -0,0 +1,5 @@
+// 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.
+//
+window.parent.dispatchEvent(new Event('detect_errors'));
diff --git a/tests/lib/html/document_test.dart b/tests/lib/html/document_test.dart
new file mode 100644
index 0000000..334f67e
--- /dev/null
+++ b/tests/lib/html/document_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isElement = predicate((x) => x is Element, 'is an Element');
+  var isDivElement = predicate((x) => x is DivElement, 'is a DivElement');
+  var isAnchorElement =
+      predicate((x) => x is AnchorElement, 'is an AnchorElement');
+  var isUnknownElement =
+      predicate((x) => x is UnknownElement, 'is UnknownElement');
+
+  var inscrutable;
+
+  test('CreateElement', () {
+    // FIXME: nifty way crashes, do it boring way.
+    expect(new Element.tag('span'), isElement);
+    expect(new Element.tag('div'), isDivElement);
+    expect(new Element.tag('a'), isAnchorElement);
+    expect(new Element.tag('bad_name'), isUnknownElement);
+  });
+
+  group('document', () {
+    inscrutable = (x) => x;
+
+    test('Document.query', () {
+      Document doc = new DomParser().parseFromString('''<ResultSet>
+           <Row>A</Row>
+           <Row>B</Row>
+           <Row>C</Row>
+         </ResultSet>''', 'text/xml');
+
+      var rs = doc.querySelector('ResultSet');
+      expect(rs, isNotNull);
+    });
+
+    test('CreateElement', () {
+      // FIXME: nifty way crashes, do it boring way.
+      expect(new Element.tag('span'), isElement);
+      expect(new Element.tag('div'), isDivElement);
+      expect(new Element.tag('a'), isAnchorElement);
+      expect(new Element.tag('bad_name'), isUnknownElement);
+    });
+
+    test('adoptNode', () {
+      var div = new Element.html('<div><div id="foo">bar</div></div>');
+      var doc = document.implementation.createHtmlDocument('');
+      expect(doc.adoptNode(div), div);
+      expect(div.ownerDocument, doc);
+      doc.body!.nodes.add(div);
+      expect(doc.querySelector('#foo')!.text, 'bar');
+    });
+
+    test('importNode', () {
+      var div = new Element.html('<div><div id="foo">bar</div></div>');
+      var doc = document.implementation.createHtmlDocument('');
+      var div2 = doc.importNode(div, true);
+      expect(div2, notEquals(div));
+      expect(div2.ownerDocument, doc);
+      doc.body!.nodes.add(div2);
+      expect(doc.querySelector('#foo')!.text, 'bar');
+    });
+
+    test('typeTest1', () {
+      inscrutable = inscrutable(inscrutable);
+      var doc1 = document;
+      expect(doc1 is HtmlDocument, true);
+      expect(inscrutable(doc1) is HtmlDocument, true);
+      var doc2 = document.implementation.createHtmlDocument('');
+      expect(doc2 is HtmlDocument, true);
+      expect(inscrutable(doc2) is HtmlDocument, true);
+    });
+
+    test('typeTest2', () {
+      inscrutable = inscrutable(inscrutable);
+      // XML document.
+      var doc3 = document.implementation.createDocument(null, 'report', null);
+      expect(doc3 is HtmlDocument, false);
+      expect(inscrutable(doc3) is HtmlDocument, false);
+    });
+  });
+}
diff --git a/tests/lib/html/documentfragment_test.dart b/tests/lib/html/documentfragment_test.dart
new file mode 100644
index 0000000..451427d
--- /dev/null
+++ b/tests/lib/html/documentfragment_test.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+main() {
+  var isAnchorElement =
+      predicate((x) => x is AnchorElement, 'is an AnchorElement');
+
+  List<String> _nodeStrings(Iterable<Node> input) {
+    List<String> out = [];
+    for (Node n in input) {
+      if (n is Element) {
+        Element e = n;
+        out.add(e.tagName);
+      } else {
+        out.add(n.text!);
+      }
+    }
+    return out;
+  }
+
+  void expectEmptyStyleDeclaration(CssStyleDeclaration style) {
+    expect(style.cssText, equals(''));
+    expect(style.getPropertyPriority('color'), equals(''));
+    expect(style.item(0), equals(''));
+    expect(style.length, equals(0));
+    // TODO(jacobr): these checks throw UnimplementedErrors in dartium.
+    // expect(style.parentRule, isNull);
+    // expect(style.getPropertyCssValue('color'), isNull);
+    // expect(style.getPropertyShorthand('color'), isNull);
+    // expect(style.isPropertyImplicit('color'), isFalse);
+
+    // Ideally these would throw errors, but it's not possible to create a class
+    // that'll intercept these calls without implementing the entire
+    // CssStyleDeclaration interface, so we'll settle for them being no-ops.
+    style.cssText = '* {color: blue}';
+    style.removeProperty('color');
+    style.setProperty('color', 'blue');
+  }
+
+  group('constructors', () {
+    test('0-argument makes an empty fragment', () {
+      final fragment = new DocumentFragment();
+      expect(fragment.children, equals([]));
+    });
+
+    test('.html parses input as HTML', () {
+      final fragment = new DocumentFragment.html('<a>foo</a>');
+      expect(fragment.children[0], isAnchorElement);
+    });
+
+    // test('.svg parses input as SVG', () {
+    //   final fragment = new DocumentFragment.svg('<a>foo</a>');
+    //   expect(fragment.children[0] is SVGAElement, isTrue);
+    // });
+
+    // TODO(nweiz): enable this once XML is ported.
+    // test('.xml parses input as XML', () {
+    //   final fragment = new DocumentFragment.xml('<a>foo</a>');
+    //   expect(fragment.children[0] is XMLElement, isTrue);
+    // });
+  });
+
+  group('children', () {
+    late DocumentFragment fragment;
+    late List<Element> children;
+
+    init() {
+      fragment = new DocumentFragment();
+      children = fragment.children;
+      fragment.nodes.addAll([
+        new Text("1"),
+        new Element.tag("A"),
+        new Element.tag("B"),
+        new Text("2"),
+        new Element.tag("I"),
+        new Text("3"),
+        new Element.tag("U")
+      ]);
+    }
+
+    test('is initially empty', () {
+      children = new DocumentFragment().children;
+      expect(children, equals([]));
+      expect(children.isEmpty, isTrue);
+    });
+
+    test('filters out non-element nodes', () {
+      init();
+      expect(_nodeStrings(fragment.nodes),
+          equals(["1", "A", "B", "2", "I", "3", "U"]));
+      expect(_nodeStrings(children), equals(["A", "B", "I", "U"]));
+    });
+
+    test('only indexes children, not other nodes', () {
+      init();
+      children[1] = new Element.tag("BR");
+      expect(_nodeStrings(fragment.nodes),
+          equals(["1", "A", "BR", "2", "I", "3", "U"]));
+      expect(_nodeStrings(children), equals(["A", "BR", "I", "U"]));
+    });
+
+    test('adds to both children and nodes', () {
+      init();
+      children.add(new Element.tag("UL"));
+      expect(_nodeStrings(fragment.nodes),
+          equals(["1", "A", "B", "2", "I", "3", "U", "UL"]));
+      expect(_nodeStrings(children), equals(["A", "B", "I", "U", "UL"]));
+    });
+
+    test('removes only children, from both children and nodes', () {
+      init();
+      expect(children.removeLast().tagName, equals('U'));
+      expect(
+          _nodeStrings(fragment.nodes), equals(["1", "A", "B", "2", "I", "3"]));
+      expect(_nodeStrings(children), equals(["A", "B", "I"]));
+
+      expect(children.removeLast().tagName, "I");
+      expect(_nodeStrings(fragment.nodes), equals(["1", "A", "B", "2", "3"]));
+      expect(_nodeStrings(children), equals(["A", "B"]));
+    });
+
+    test('accessors are wrapped', () {
+      init();
+      expect(children[0].tagName, "A");
+      expect(_nodeStrings(children.where((e) => e.tagName == "I")), ["I"]);
+      expect(children.every((e) => e is Element), isTrue);
+      expect(children.any((e) => e.tagName == "U"), isTrue);
+      expect(children.isEmpty, isFalse);
+      expect(children.length, 4);
+      expect(children[2].tagName, "I");
+      expect(children.last.tagName, "U");
+    });
+
+    test('setting children overwrites nodes as well', () {
+      init();
+      fragment.children = [new Element.tag("DIV"), new Element.tag("HEAD")];
+      expect(_nodeStrings(fragment.nodes), equals(["DIV", "HEAD"]));
+    });
+  });
+
+  test('setting innerHtml works', () {
+    var fragment = new DocumentFragment();
+    fragment.append(new Text("foo"));
+    fragment.innerHtml = "<a>bar</a>baz";
+    expect(_nodeStrings(fragment.nodes), equals(["A", "baz"]));
+  });
+
+  test('getting innerHtml works', () {
+    var fragment = new DocumentFragment();
+    fragment.nodes.addAll([new Text("foo"), new Element.html("<A>bar</A>")]);
+    expect(fragment.innerHtml, "foo<a>bar</a>");
+  });
+
+  test('query searches the fragment', () {
+    var fragment = new DocumentFragment.html(
+        "<div class='foo'><a>foo</a><b>bar</b></div>");
+    expect(fragment.querySelector(".foo a")!.tagName, "A");
+    expect(_nodeStrings(fragment.querySelectorAll<Element>(".foo *")),
+        equals(["A", "B"]));
+  });
+}
diff --git a/tests/lib/html/dom_constructors_test.dart b/tests/lib/html/dom_constructors_test.dart
new file mode 100644
index 0000000..ff70268
--- /dev/null
+++ b/tests/lib/html/dom_constructors_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('FileReader', () {
+    FileReader fileReader = new FileReader();
+    expect(fileReader.readyState, equals(FileReader.EMPTY));
+  });
+}
diff --git a/tests/lib/html/dom_isolates_test.dart.child_isolate.dart b/tests/lib/html/dom_isolates_test.dart.child_isolate.dart
new file mode 100644
index 0000000..31e97d2
--- /dev/null
+++ b/tests/lib/html/dom_isolates_test.dart.child_isolate.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+import 'dart:isolate';
+
+main() {
+  port.receive((msg, replyTo) {
+    if (msg != 'check') {
+      replyTo.send('wrong msg: $msg');
+    }
+    replyTo.send('${window.location}');
+    port.close();
+  });
+}
diff --git a/tests/lib/html/domparser_test.dart b/tests/lib/html/domparser_test.dart
new file mode 100644
index 0000000..b7aa5f3
--- /dev/null
+++ b/tests/lib/html/domparser_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isDomParser = predicate((x) => x is DomParser, 'is a DomParser');
+
+  test('constructorTest', () {
+    var ctx = new DomParser();
+    expect(ctx, isNotNull);
+    expect(ctx, isDomParser);
+  });
+}
diff --git a/tests/lib/html/element_add_test.dart b/tests/lib/html/element_add_test.dart
new file mode 100644
index 0000000..e443659
--- /dev/null
+++ b/tests/lib/html/element_add_test.dart
@@ -0,0 +1,267 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+main() {
+  var isSpanElement = predicate((x) => x is SpanElement, 'is a SpanElemt');
+  var isDivElement = predicate((x) => x is DivElement, 'is a DivElement');
+  var isText = predicate((x) => x is Text, 'is a Text');
+
+  void expectNoSuchMethod(void fn()) => expect(fn, throwsNoSuchMethodError);
+
+  group('append', () {
+    test('htmlelement', () {
+      var el = new DivElement();
+      el.append(new SpanElement());
+      expect(el.children.length, equals(1));
+      var span = el.children[0];
+      expect(span, isSpanElement);
+
+      el.append(new DivElement());
+      expect(el.children.length, equals(2));
+      // Validate that the first item is still first.
+      expect(el.children[0], equals(span));
+      expect(el.children[1], isDivElement);
+    });
+
+    test('documentFragment', () {
+      var fragment = new DocumentFragment();
+      fragment.append(new SpanElement());
+      expect(fragment.children.length, equals(1));
+      expect(fragment.children[0], isSpanElement);
+    });
+  });
+
+  group('appendHtml', () {
+    test('htmlelement', () {
+      var el = new DivElement();
+      el.appendHtml('<span></span>');
+      expect(el.children.length, equals(1));
+      var span = el.children[0];
+      expect(span, isSpanElement);
+
+      el.appendHtml('<div></div>');
+      expect(el.children.length, equals(2));
+      // Validate that the first item is still first.
+      expect(el.children[0], equals(span));
+      expect(el.children[1], isDivElement);
+    });
+
+    test('documentFragment', () {
+      var fragment = new DocumentFragment();
+      fragment.appendHtml('<span>something</span>');
+      expect(fragment.children.length, equals(1));
+      expect(fragment.children[0], isSpanElement);
+    });
+
+    test('html interpreted in correct context', () {
+      // appendHtml, in order to sanitize, needs to create a document fragment,
+      // but it needs to be created in the right context. If we try to append
+      // table components then the document fragment needs the table context
+      // or it will fail to create them.
+      var el = new TableElement();
+      el.appendHtml('<tr><td>foo</td></tr>');
+      expect(el.children.length, 1);
+      var section = el.children.first;
+      expect(section is TableSectionElement, isTrue);
+      var row = section.children.first;
+      expect(row is TableRowElement, isTrue);
+      var item = row.children.first;
+      expect(item is TableCellElement, isTrue);
+      expect(item.innerHtml, 'foo');
+    });
+
+    test("use body context for elements that are don't support it", () {
+      // Some elements can't be used as context for createContextualFragment,
+      // often because it doesn't make any sense. So adding children to a
+      // <br> has no real effect on the page, but we can do it. But the
+      // document fragment will have to be created in the body context. Verify
+      // that this doesn't throw and that the children show up.
+      var el = new BRElement();
+      el.appendHtml("<p>Stuff</p>");
+      expect(el.children.length, 1);
+      expect(el.children[0].outerHtml, "<p>Stuff</p>");
+    });
+  });
+
+  group('appendText', () {
+    test('htmlelement', () {
+      var el = new DivElement();
+      el.appendText('foo');
+      // No children were created.
+      expect(el.children.length, equals(0));
+      // One text node was added.
+      expect(el.nodes.length, equals(1));
+    });
+
+    test('htmlelement', () {
+      var el = new DivElement();
+      var twoNewLines = "\n\n";
+      el.appendText(twoNewLines);
+      // No children were created.
+      expect(el.children.length, equals(0));
+      // One text node was added.
+      expect(el.nodes.length, equals(1));
+      expect(el.nodes[0], isText);
+      expect(el.nodes[0].text, equals(twoNewLines));
+      expect(el.text, equals(twoNewLines));
+    });
+
+    test('documentFragment', () {
+      var fragment = new DocumentFragment();
+      fragment.appendText('foo');
+      // No children were created.
+      expect(fragment.children.length, equals(0));
+      // One text node was added.
+      expect(fragment.nodes.length, equals(1));
+    });
+  });
+
+  group('insertAdjacentElement', () {
+    test('beforebegin', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      var newChild = new SpanElement();
+      parent.children.add(child);
+
+      child.insertAdjacentElement('beforebegin', newChild);
+
+      expect(parent.children.length, 2);
+      expect(parent.children[0], isSpanElement);
+    });
+
+    test('afterend', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      var newChild = new SpanElement();
+      parent.children.add(child);
+
+      child.insertAdjacentElement('afterend', newChild);
+
+      expect(parent.children.length, 2);
+      expect(parent.children[1], isSpanElement);
+    });
+
+    test('afterbegin', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      var newChild = new SpanElement();
+      parent.children.add(child);
+
+      parent.insertAdjacentElement('afterbegin', newChild);
+
+      expect(parent.children.length, 2);
+      expect(parent.children[0], isSpanElement);
+    });
+
+    test('beforeend', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      var newChild = new SpanElement();
+      parent.children.add(child);
+
+      parent.insertAdjacentElement('beforeend', newChild);
+
+      expect(parent.children.length, 2);
+      expect(parent.children[1], isSpanElement);
+    });
+  });
+
+  group('insertAdjacentHtml', () {
+    test('beforebegin', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      child.insertAdjacentHtml('beforebegin', '<span></span>');
+
+      expect(parent.children.length, 2);
+      expect(parent.children[0], isSpanElement);
+    });
+
+    test('afterend', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      child.insertAdjacentHtml('afterend', '<span></span>');
+
+      expect(parent.children.length, 2);
+      expect(parent.children[1], isSpanElement);
+    });
+
+    test('afterbegin', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      parent.insertAdjacentHtml('afterbegin', '<span></span>');
+
+      expect(parent.children.length, 2);
+      expect(parent.children[0], isSpanElement);
+    });
+
+    test('beforeend', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      parent.insertAdjacentHtml('beforeend', '<span></span>');
+
+      expect(parent.children.length, 2);
+      expect(parent.children[1], isSpanElement);
+    });
+  });
+
+  group('insertAdjacentText', () {
+    test('beforebegin', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      child.insertAdjacentText('beforebegin', 'test');
+
+      expect(parent.nodes.length, 2);
+      expect(parent.nodes[0], isText);
+    });
+
+    test('afterend', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      child.insertAdjacentText('afterend', 'test');
+
+      expect(parent.nodes.length, 2);
+      expect(parent.nodes[1], isText);
+    });
+
+    test('afterbegin', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      parent.insertAdjacentText('afterbegin', 'test');
+
+      expect(parent.nodes.length, 2);
+      expect(parent.nodes[0], isText);
+    });
+
+    test('beforeend', () {
+      var parent = new DivElement();
+      var child = new DivElement();
+      parent.children.add(child);
+
+      parent.insertAdjacentText('beforeend', 'test');
+
+      expect(parent.nodes.length, 2);
+      expect(parent.nodes[1], isText);
+    });
+  });
+}
diff --git a/tests/lib/html/element_animate_omit_timing_test.dart b/tests/lib/html/element_animate_omit_timing_test.dart
new file mode 100644
index 0000000..933d695
--- /dev/null
+++ b/tests/lib/html/element_animate_omit_timing_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_animate_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  test('omit timing', () {
+    if (Animation.supported) {
+      var body = document.body!;
+      var player = body.animate([
+        {"transform": "translate(100px, -100%)"},
+        {"transform": "translate(400px, 500px)"}
+      ]);
+      player.on['finish'].listen(expectAsync((_) => 'done'));
+    }
+  });
+}
diff --git a/tests/lib/html/element_animate_simple_timing_test.dart b/tests/lib/html/element_animate_simple_timing_test.dart
new file mode 100644
index 0000000..27f13da
--- /dev/null
+++ b/tests/lib/html/element_animate_simple_timing_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_animate_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  test('simple timing', () {
+    if (Animation.supported) {
+      var body = document.body!;
+      var opacity = num.parse(body.getComputedStyle().opacity);
+      body.animate([
+        {"opacity": 100},
+        {"opacity": 0}
+      ], 100);
+      var newOpacity = num.parse(body.getComputedStyle().opacity);
+      expect(newOpacity == opacity, isTrue);
+    }
+  });
+}
diff --git a/tests/lib/html/element_animate_supported_test.dart b/tests/lib/html/element_animate_supported_test.dart
new file mode 100644
index 0000000..7f11c8a
--- /dev/null
+++ b/tests/lib/html/element_animate_supported_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_animate_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(Animation.supported, isTrue);
+  });
+}
diff --git a/tests/lib/html/element_animate_timing_dict_test.dart b/tests/lib/html/element_animate_timing_dict_test.dart
new file mode 100644
index 0000000..28faf1a
--- /dev/null
+++ b/tests/lib/html/element_animate_timing_dict_test.dart
@@ -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 file.
+
+library element_animate_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  test('timing dict', () {
+    if (Animation.supported) {
+      var body = document.body!;
+      // Animate different characteristics so the tests can run concurrently.
+      var fontSize = body.getComputedStyle().fontSize;
+      var player = body.animate([
+        {"font-size": "500px"},
+        {"font-size": fontSize}
+      ], {
+        "duration": 100
+      });
+      var newFontSize = body.getComputedStyle().fontSize;
+      // Don't bother to parse to numbers, as long as it's changed that
+      // indicates something is happening.
+      expect(newFontSize == fontSize, isFalse);
+      player.on['finish'].listen(expectAsync((_) => 'done'));
+    }
+  });
+}
diff --git a/tests/lib/html/element_classes_svg_test.dart b/tests/lib/html/element_classes_svg_test.dart
new file mode 100644
index 0000000..cc05a21
--- /dev/null
+++ b/tests/lib/html/element_classes_svg_test.dart
@@ -0,0 +1,229 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:html';
+import 'dart:svg' as svg;
+
+import "package:expect/expect.dart";
+import 'package:expect/minitest.dart';
+
+// Test for `querySelectorAll(xxx).classes.op()` where the query returns mixed
+// Html and Svg elements.
+
+Element makeElementsContainer() {
+  var e = new Element.html('<ul class="yes foo">'
+      '<li class="yes quux qux">'
+      '</ul>');
+  final svgContent = r"""
+<svg version="1.1">
+  <circle class="yes qux"></circle>
+  <path class="yes classy"></path>
+</svg>""";
+  final svgElement = new svg.SvgElement.svg(svgContent);
+  e.append(svgElement);
+  return e;
+}
+
+Element? elementsContainer;
+
+/// Test top-level querySelectorAll with generics.
+topLevelQuerySelector() {
+  var noElementsTop = querySelectorAll<svg.PathElement>('.no');
+  expect(noElementsTop.length, 0);
+  expect(noElementsTop is List, true);
+
+  // Expect runtime error all elements in the list are not the proper type.
+  Expect.throwsAssertionError(() => querySelectorAll<svg.CircleElement>('path'),
+      'All elements not of type CircleElement');
+
+  var simpleElems = querySelectorAll('circle');
+  expect(simpleElems.length, 1);
+  expect(simpleElems is List, true);
+  expect(simpleElems is List<dynamic>, true);
+  expect(simpleElems is List<svg.CircleElement>, false);
+  expect(simpleElems[0] is svg.CircleElement, true);
+
+  var varElementsFromTop = querySelectorAll<svg.CircleElement>('circle');
+  expect(varElementsFromTop.length, 1);
+  expect(varElementsFromTop is List, true);
+  expect(varElementsFromTop is List<svg.CircleElement>, true);
+  expect(varElementsFromTop[0] is svg.CircleElement, true);
+  expect(varElementsFromTop is List<svg.PathElement>, false);
+  expect(varElementsFromTop[0] is svg.PathElement, false);
+
+  List<svg.CircleElement> elementsFromTop =
+      querySelectorAll<svg.CircleElement>('circle');
+  expect(elementsFromTop is List, true);
+  expect(elementsFromTop is List<svg.CircleElement>, true);
+  expect(elementsFromTop[0] is svg.CircleElement, true);
+  expect(elementsFromTop.length, 1);
+}
+
+ElementList<Element> elementsSetup() {
+  elementsContainer = makeElementsContainer();
+  document.documentElement!.children.add(elementsContainer!);
+  var elements = document.querySelectorAll('.yes');
+  expect(elements.length, 4);
+
+  topLevelQuerySelector();
+
+  return elements;
+}
+
+void elementsTearDown() {
+  if (elementsContainer != null) {
+    document.documentElement!.children.remove(elementsContainer!);
+    elementsContainer = null;
+  }
+}
+
+/// Returns a canonical string for Set<String> and lists of Element's classes.
+String view(var e) {
+  if (e is Set) return '${e.toList()..sort()}';
+  if (e is Element) return view(e.classes);
+  if (e is Iterable) return '${e.map(view).toList()}';
+  throw new ArgumentError('Cannot make canonical view string for: $e}');
+}
+
+main() {
+  Set<String> extractClasses(Element el) {
+    final match = new RegExp('class="([^"]+)"').firstMatch(el.outerHtml)!;
+    return new LinkedHashSet.from(match[1]!.split(' '));
+  }
+
+  tearDown(elementsTearDown);
+
+  test('list_view', () {
+    // Test that the 'view' helper function is behaving.
+    var elements = elementsSetup();
+    expect(view(elements.classes), '[classy, foo, quux, qux, yes]');
+    expect(view(elements),
+        '[[foo, yes], [quux, qux, yes], [qux, yes], [classy, yes]]');
+  });
+
+  test('listClasses=', () {
+    var elements = elementsSetup();
+
+    elements.classes = ['foo', 'qux'];
+    expect(view(elements.classes), '[foo, qux]');
+    expect(view(elements), '[[foo, qux], [foo, qux], [foo, qux], [foo, qux]]');
+
+    var elements2 = document.querySelectorAll('.qux');
+    expect(view(elements2.classes), '[foo, qux]');
+    expect(view(elements2), '[[foo, qux], [foo, qux], [foo, qux], [foo, qux]]');
+
+    for (Element e in elements2) {
+      expect(e.classes, equals(['foo', 'qux']));
+      expect(extractClasses(e), equals(['foo', 'qux']));
+    }
+
+    elements.classes = [];
+    expect(view(elements2.classes), '[]');
+    expect(view(elements2), '[[], [], [], []]');
+  });
+
+  test('listMap', () {
+    var elements = elementsSetup();
+    expect(elements.classes.map((c) => c.toUpperCase()).toList(),
+        unorderedEquals(['YES', 'FOO', 'QUX', 'QUUX', 'CLASSY']));
+  });
+
+  test('listContains', () {
+    var elements = elementsSetup();
+    expect(elements.classes.contains('classy'), isTrue);
+    expect(elements.classes.contains('troll'), isFalse);
+  });
+
+  test('listAdd', () {
+    var elements = elementsSetup();
+    var added = elements.classes.add('lassie');
+    expect(added, isFalse);
+
+    expect(view(elements.classes), '[classy, foo, lassie, quux, qux, yes]');
+    expect(
+        view(elements),
+        '[[foo, lassie, yes], [lassie, quux, qux, yes], '
+        '[lassie, qux, yes], [classy, lassie, yes]]');
+  });
+
+  test('listRemove', () {
+    var elements = elementsSetup();
+    expect(elements.classes.remove('lassi'), isFalse);
+    expect(view(elements.classes), '[classy, foo, quux, qux, yes]');
+    expect(view(elements),
+        '[[foo, yes], [quux, qux, yes], [qux, yes], [classy, yes]]');
+
+    expect(elements.classes.remove('qux'), isTrue);
+    expect(view(elements.classes), '[classy, foo, quux, yes]');
+    expect(view(elements), '[[foo, yes], [quux, yes], [yes], [classy, yes]]');
+  });
+
+  test('listToggle', () {
+    var elements = elementsSetup();
+    elements.classes.toggle('qux');
+    expect(view(elements.classes), '[classy, foo, quux, qux, yes]');
+    expect(view(elements),
+        '[[foo, qux, yes], [quux, yes], [yes], [classy, qux, yes]]');
+  });
+
+  test('listAddAll', () {
+    var elements = elementsSetup();
+    elements.classes.addAll(['qux', 'lassi', 'sassy']);
+    expect(
+        view(elements.classes), '[classy, foo, lassi, quux, qux, sassy, yes]');
+    expect(
+        view(elements),
+        '[[foo, lassi, qux, sassy, yes], [lassi, quux, qux, sassy, yes], '
+        '[lassi, qux, sassy, yes], [classy, lassi, qux, sassy, yes]]');
+  });
+
+  test('listRemoveAll', () {
+    var elements = elementsSetup();
+    elements.classes.removeAll(['qux', 'classy', 'mumble']);
+    expect(view(elements.classes), '[foo, quux, yes]');
+    expect(view(elements), '[[foo, yes], [quux, yes], [yes], [yes]]');
+
+    elements.classes.removeAll(['foo', 'yes']);
+    expect(view(elements.classes), '[quux]');
+    expect(view(elements), '[[], [quux], [], []]');
+  });
+
+  test('listToggleAll', () {
+    var elements = elementsSetup();
+    elements.classes.toggleAll(['qux', 'mornin']);
+    expect(view(elements.classes), '[classy, foo, mornin, quux, qux, yes]');
+    expect(
+        view(elements),
+        '[[foo, mornin, qux, yes], [mornin, quux, yes], '
+        '[mornin, yes], [classy, mornin, qux, yes]]');
+  });
+
+  test('listRetainAll', () {
+    var elements = elementsSetup();
+    elements.classes.retainAll(['bar', 'baz', 'classy', 'qux']);
+    expect(view(elements.classes), '[classy, qux]');
+    expect(view(elements), '[[], [qux], [qux], [classy]]');
+  });
+
+  test('listRemoveWhere', () {
+    var elements = elementsSetup();
+    elements.classes.removeWhere((s) => s.startsWith('q'));
+    expect(view(elements.classes), '[classy, foo, yes]');
+    expect(view(elements), '[[foo, yes], [yes], [yes], [classy, yes]]');
+  });
+
+  test('listRetainWhere', () {
+    var elements = elementsSetup();
+    elements.classes.retainWhere((s) => s.startsWith('q'));
+    expect(view(elements.classes), '[quux, qux]');
+    expect(view(elements), '[[], [quux, qux], [qux], []]');
+  });
+
+  test('listContainsAll', () {
+    var elements = elementsSetup();
+    expect(elements.classes.containsAll(['qux', 'mornin']), isFalse);
+    expect(elements.classes.containsAll(['qux', 'classy']), isTrue);
+  });
+}
diff --git a/tests/lib/html/element_classes_test.dart b/tests/lib/html/element_classes_test.dart
new file mode 100644
index 0000000..0345692
--- /dev/null
+++ b/tests/lib/html/element_classes_test.dart
@@ -0,0 +1,390 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+Element makeElement() => new Element.tag('div');
+
+Element makeElementWithClasses() =>
+    new Element.html('<div class="foo bar baz"></div>');
+
+CssClassSet makeClassSet() => makeElementWithClasses().classes;
+
+Element makeListElement() => new Element.html('<ul class="foo bar baz">'
+    '<li class="quux qux">'
+    '<li class="meta">'
+    '<li class="classy lassy">'
+    '<li class="qux lassy">'
+    '</ul>');
+
+Element? listElement;
+
+ElementList<Element> listElementSetup() {
+  listElement = makeListElement();
+  document.documentElement!.children.add(listElement!);
+  return document.querySelectorAll('li');
+}
+
+void listElementTearDown() {
+  if (listElement != null) {
+    document.documentElement!.children.remove(listElement!);
+    listElement = null;
+  }
+}
+
+/// Returns a canonical string for Set<String> and lists of Element's classes.
+String view(var e) {
+  if (e is Set) return '${e.toList()..sort()}';
+  if (e is Element) return view(e.classes);
+  if (e is Iterable) return '${e.map(view).toList()}';
+  throw new ArgumentError('Cannot make canonical view string for: $e}');
+}
+
+main() {
+  Set<String> extractClasses(Element el) {
+    final match = new RegExp('class="([^"]+)"').firstMatch(el.outerHtml)!;
+    return new LinkedHashSet.from(match[1]!.split(' '));
+  }
+
+  test('affects the "class" attribute', () {
+    final el = makeElementWithClasses();
+    el.classes.add('qux');
+    expect(extractClasses(el), equals(['foo', 'bar', 'baz', 'qux']));
+  });
+
+  test('is affected by the "class" attribute', () {
+    final el = makeElementWithClasses();
+    el.attributes['class'] = 'foo qux';
+    expect(el.classes, equals(['foo', 'qux']));
+  });
+
+  test('classes=', () {
+    final el = makeElementWithClasses();
+    el.classes = ['foo', 'qux'];
+    expect(el.classes, equals(['foo', 'qux']));
+    expect(extractClasses(el), equals(['foo', 'qux']));
+  });
+
+  test('toString', () {
+    expect(makeClassSet().toString().split(' '), equals(['foo', 'bar', 'baz']));
+    expect(makeElement().classes.toString(), '');
+  });
+
+  test('forEach', () {
+    final classes = <String>[];
+    makeClassSet().forEach(classes.add);
+    expect(classes, equals(['foo', 'bar', 'baz']));
+  });
+
+  test('iterator', () {
+    final classes = <String>[];
+    for (var el in makeClassSet()) {
+      classes.add(el);
+    }
+    expect(classes, equals(['foo', 'bar', 'baz']));
+  });
+
+  test('map', () {
+    expect(makeClassSet().map((c) => c.toUpperCase()).toList(),
+        equals(['FOO', 'BAR', 'BAZ']));
+  });
+
+  test('where', () {
+    expect(makeClassSet().where((c) => c.contains('a')).toList(),
+        equals(['bar', 'baz']));
+  });
+
+  test('every', () {
+    expect(makeClassSet().every((c) => c is String), isTrue);
+    expect(makeClassSet().every((c) => c.contains('a')), isFalse);
+  });
+
+  test('any', () {
+    expect(makeClassSet().any((c) => c.contains('a')), isTrue);
+    expect(makeClassSet().any((c) => c is num), isFalse);
+  });
+
+  test('isEmpty', () {
+    expect(makeClassSet().isEmpty, isFalse);
+    expect(makeElement().classes.isEmpty, isTrue);
+  });
+
+  test('length', () {
+    expect(makeClassSet().length, 3);
+    expect(makeElement().classes.length, 0);
+  });
+
+  test('contains', () {
+    expect(makeClassSet().contains('foo'), isTrue);
+    expect(makeClassSet().contains('qux'), isFalse);
+  });
+
+  test('contains-bad', () {
+    // Non-strings return `false`.
+    // Strings need to be valid tokens.
+    final classes = makeClassSet();
+    expect(classes.contains(1), isFalse);
+    expect(() => classes.contains(''), throws);
+    expect(() => classes.contains('foo bar'), throws);
+  });
+
+  test('add', () {
+    final classes = makeClassSet();
+    var added = classes.add('qux');
+    expect(added, isTrue);
+    expect(classes, equals(['foo', 'bar', 'baz', 'qux']));
+
+    added = classes.add('qux');
+    expect(added, isFalse);
+    final list = new List.from(classes);
+    list.sort((a, b) => a.compareTo(b));
+    expect(list, equals(['bar', 'baz', 'foo', 'qux']),
+        reason: "The class set shouldn't have duplicate elements.");
+  });
+
+  test('add-bad', () {
+    final classes = makeClassSet();
+    expect(() => classes.add(''), throws);
+    expect(() => classes.add('foo bar'), throws);
+  });
+
+  test('remove', () {
+    final classes = makeClassSet();
+    classes.remove('bar');
+    expect(classes, equals(['foo', 'baz']));
+    classes.remove('qux');
+    expect(classes, equals(['foo', 'baz']));
+  });
+
+  test('remove-bad', () {
+    final classes = makeClassSet();
+    expect(() => classes.remove(''), throws);
+    expect(() => classes.remove('foo bar'), throws);
+  });
+
+  test('toggle', () {
+    final classes = makeClassSet();
+    classes.toggle('bar');
+    expect(classes, equals(['foo', 'baz']));
+    classes.toggle('qux');
+    expect(classes, equals(['foo', 'baz', 'qux']));
+
+    classes.toggle('qux', true);
+    expect(classes, equals(['foo', 'baz', 'qux']));
+    classes.toggle('qux', false);
+    expect(classes, equals(['foo', 'baz']));
+    classes.toggle('qux', false);
+    expect(classes, equals(['foo', 'baz']));
+    classes.toggle('qux', true);
+    expect(classes, equals(['foo', 'baz', 'qux']));
+  });
+
+  test('toggle-bad', () {
+    final classes = makeClassSet();
+    expect(() => classes.toggle(''), throws);
+    expect(() => classes.toggle('', true), throws);
+    expect(() => classes.toggle('', false), throws);
+    expect(() => classes.toggle('foo bar'), throws);
+    expect(() => classes.toggle('foo bar', true), throws);
+    expect(() => classes.toggle('foo bar', false), throws);
+  });
+
+  test('addAll', () {
+    final classes = makeClassSet();
+    classes.addAll(['bar', 'qux', 'bip']);
+    expect(classes, equals(['foo', 'bar', 'baz', 'qux', 'bip']));
+  });
+
+  test('removeAll', () {
+    final classes = makeClassSet();
+    classes.removeAll(['bar', 'baz', 'qux']);
+    expect(classes, equals(['foo']));
+  });
+
+  test('toggleAll', () {
+    final classes = makeClassSet();
+    classes.toggleAll(['bar', 'foo']);
+    expect(classes, equals(['baz']));
+    classes.toggleAll(['qux', 'quux']);
+    expect(classes, equals(['baz', 'qux', 'quux']));
+    classes.toggleAll(['bar', 'foo'], true);
+    expect(classes, equals(['baz', 'qux', 'quux', 'bar', 'foo']));
+    classes.toggleAll(['baz', 'quux'], false);
+    expect(classes, equals(['qux', 'bar', 'foo']));
+  });
+
+  test('retainAll', () {
+    final classes = makeClassSet();
+    classes.retainAll(['bar', 'baz', 'qux']);
+    expect(classes, equals(['bar', 'baz']));
+  });
+
+  test('removeWhere', () {
+    final classes = makeClassSet();
+    classes.removeWhere((s) => s.startsWith('b'));
+    expect(classes, equals(['foo']));
+  });
+
+  test('retainWhere', () {
+    final classes = makeClassSet();
+    classes.retainWhere((s) => s.startsWith('b'));
+    expect(classes, equals(['bar', 'baz']));
+  });
+
+  test('containsAll', () {
+    final classes = makeClassSet();
+    expect(classes.containsAll(['foo', 'baz']), isTrue);
+    expect(classes.containsAll(['foo', 'qux']), isFalse);
+    expect(classes.containsAll(['foo', 'baz'].toSet()), isTrue);
+    expect(classes.containsAll(['foo', 'qux'].toSet()), isFalse);
+  });
+
+  test('intersection', () {
+    final classes = makeClassSet();
+    expect(classes.intersection(['foo', 'qux', 'baz'].toSet()),
+        unorderedEquals(['foo', 'baz']));
+  });
+
+  test('clear', () {
+    final classes = makeClassSet();
+    classes.clear();
+    expect(classes, equals([]));
+  });
+
+  test('order', () {
+    var classes = makeClassSet();
+    classes.add('aardvark');
+    expect(classes, equals(['foo', 'bar', 'baz', 'aardvark']));
+    classes.toggle('baz');
+    expect(classes, equals(['foo', 'bar', 'aardvark']));
+    classes.toggle('baz');
+    expect(classes, equals(['foo', 'bar', 'aardvark', 'baz']));
+  });
+
+  tearDown(listElementTearDown);
+
+  test('list_view', () {
+    // Test that the 'view' helper function is behaving.
+    var elements = listElementSetup();
+    expect(view(elements.classes), '[classy, lassy, meta, quux, qux]');
+    expect(
+        view(elements), '[[quux, qux], [meta], [classy, lassy], [lassy, qux]]');
+  });
+
+  test('listClasses=', () {
+    var elements = listElementSetup();
+    elements.classes = ['foo', 'qux'];
+    elements = document.querySelectorAll('li');
+    for (Element e in elements) {
+      expect(e.classes, equals(['foo', 'qux']));
+      expect(extractClasses(e), equals(['foo', 'qux']));
+    }
+
+    elements.classes = [];
+    expect(view(elements.classes), '[]');
+    expect(view(elements), '[[], [], [], []]');
+  });
+
+  test('listMap', () {
+    var elements = listElementSetup();
+    expect(elements.classes.map((c) => c.toUpperCase()).toList(),
+        unorderedEquals(['QUX', 'QUUX', 'META', 'CLASSY', 'LASSY']));
+  });
+
+  test('listContains', () {
+    var elements = listElementSetup();
+    expect(elements.classes.contains('lassy'), isTrue);
+    expect(elements.classes.contains('foo'), isFalse);
+  });
+
+  test('listAdd', () {
+    var elements = listElementSetup();
+    var added = elements.classes.add('lassie');
+    expect(added, isNull);
+
+    expect(view(elements.classes), '[classy, lassie, lassy, meta, quux, qux]');
+    expect(
+        view(elements),
+        '[[lassie, quux, qux], [lassie, meta], [classy, lassie, lassy], '
+        '[lassie, lassy, qux]]');
+  });
+
+  test('listRemove', () {
+    var elements = listElementSetup();
+    expect(elements.classes.remove('lassi'), isFalse);
+    expect(view(elements.classes), '[classy, lassy, meta, quux, qux]');
+    expect(
+        view(elements), '[[quux, qux], [meta], [classy, lassy], [lassy, qux]]');
+
+    expect(elements.classes.remove('qux'), isTrue);
+    expect(view(elements.classes), '[classy, lassy, meta, quux]');
+    expect(view(elements), '[[quux], [meta], [classy, lassy], [lassy]]');
+  });
+
+  test('listToggle', () {
+    var elements = listElementSetup();
+    elements.classes.toggle('qux');
+    expect(view(elements.classes), '[classy, lassy, meta, quux, qux]');
+    expect(
+        view(elements), '[[quux], [meta, qux], [classy, lassy, qux], [lassy]]');
+  });
+
+  test('listAddAll', () {
+    var elements = listElementSetup();
+    elements.classes.addAll(['qux', 'lassi', 'sassy']);
+    expect(view(elements.classes),
+        '[classy, lassi, lassy, meta, quux, qux, sassy]');
+    expect(
+        view(elements),
+        '[[lassi, quux, qux, sassy], [lassi, meta, qux, sassy], '
+        '[classy, lassi, lassy, qux, sassy], [lassi, lassy, qux, sassy]]');
+  });
+
+  test('listRemoveAll', () {
+    var elements = listElementSetup();
+    elements.classes.removeAll(['qux', 'lassy', 'meta']);
+    expect(view(elements.classes), '[classy, quux]');
+    expect(view(elements), '[[quux], [], [classy], []]');
+  });
+
+  test('listToggleAll', () {
+    var elements = listElementSetup();
+    elements.classes.toggleAll(['qux', 'meta', 'mornin']);
+    expect(view(elements.classes), '[classy, lassy, meta, mornin, quux, qux]');
+    expect(
+        view(elements),
+        '[[meta, mornin, quux], [mornin, qux], '
+        '[classy, lassy, meta, mornin, qux], [lassy, meta, mornin]]');
+  });
+
+  test('listRetainAll', () {
+    var elements = listElementSetup();
+    elements.classes.retainAll(['bar', 'baz', 'qux']);
+    expect(view(elements.classes), '[qux]');
+    expect(view(elements), '[[qux], [], [], [qux]]');
+  });
+
+  test('listRemoveWhere', () {
+    var elements = listElementSetup();
+    elements.classes.removeWhere((s) => s.startsWith('q'));
+    expect(view(elements.classes), '[classy, lassy, meta]');
+    expect(view(elements), '[[], [meta], [classy, lassy], [lassy]]');
+  });
+
+  test('listRetainWhere', () {
+    var elements = listElementSetup();
+    elements.classes.retainWhere((s) => s.startsWith('q'));
+    expect(view(elements.classes), '[quux, qux]');
+    expect(view(elements), '[[quux, qux], [], [], [qux]]');
+  });
+
+  test('listContainsAll', () {
+    var elements = listElementSetup();
+    expect(elements.classes.containsAll(['qux', 'meta', 'mornin']), isFalse);
+    expect(elements.classes.containsAll(['qux', 'lassy', 'classy']), isTrue);
+  });
+}
diff --git a/tests/lib/html/element_constructor_1_test.dart b/tests/lib/html/element_constructor_1_test.dart
new file mode 100644
index 0000000..bd265b4
--- /dev/null
+++ b/tests/lib/html/element_constructor_1_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Put universally passing event constructors in this file.
+// Move constructors that fail on some configuration to their own
+// element_constructor_foo_test.dart file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isAnchorElement =
+      predicate((x) => x is AnchorElement, 'is an AnchorElement');
+  var isAreaElement = predicate((x) => x is AreaElement, 'is an AreaElement');
+  var isDivElement = predicate((x) => x is DivElement, 'is a DivElement');
+  var isCanvasElement =
+      predicate((x) => x is CanvasElement, 'is a CanvasElement');
+  var isParagraphElement =
+      predicate((x) => x is ParagraphElement, 'is a ParagraphElement');
+  var isSpanElement = predicate((x) => x is SpanElement, 'is a SpanElement');
+  var isSelectElement =
+      predicate((x) => x is SelectElement, 'is a SelectElement');
+
+  test('anchor1', () {
+    var e = new AnchorElement();
+    expect(e, isAnchorElement);
+  });
+
+  test('anchor2', () {
+    var e = new AnchorElement(href: '#blah');
+    expect(e, isAnchorElement);
+    expect(e.href.endsWith('#blah'), isTrue);
+  });
+
+  test('area', () {
+    var e = new AreaElement();
+    expect(e, isAreaElement);
+  });
+
+  // AudioElement tested in audioelement_test.dart
+
+  test('div', () {
+    var e = new DivElement();
+    expect(e, isDivElement);
+  });
+
+  test('canvas1', () {
+    var e = new CanvasElement();
+    expect(e, isCanvasElement);
+  });
+
+  test('canvas2', () {
+    var e = new CanvasElement(height: 100, width: 200);
+    expect(e, isCanvasElement);
+    expect(e.width, 200);
+    expect(e.height, 100);
+  });
+
+  test('p', () {
+    var e = new ParagraphElement();
+    expect(e, isParagraphElement);
+  });
+
+  test('span', () {
+    var e = new SpanElement();
+    expect(e, isSpanElement);
+  });
+
+  test('select', () {
+    var e = new SelectElement();
+    expect(e, isSelectElement);
+  });
+}
diff --git a/tests/lib/html/element_dimensions_test.dart b/tests/lib/html/element_dimensions_test.dart
new file mode 100644
index 0000000..e45aed4
--- /dev/null
+++ b/tests/lib/html/element_dimensions_test.dart
@@ -0,0 +1,260 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isElement = predicate((x) => x is Element, 'is an Element');
+  var isCanvasElement =
+      predicate((x) => x is CanvasElement, 'is a CanvasElement');
+  var isDivElement = predicate((x) => x is DivElement, 'is a isDivElement');
+
+  var div = new DivElement();
+  div.id = 'test';
+  document.body!.nodes.add(div);
+
+  void initDiv() {
+    var style = div.style;
+    style
+      ..padding = '4px'
+      ..border = '0px solid #fff'
+      ..margin = '6px'
+      ..height = '10px'
+      ..width = '11px'
+      ..boxSizing = 'content-box'
+      ..overflow = 'visible';
+  }
+
+  div.nodes.addAll([
+    new DivElement(),
+    new CanvasElement(),
+    new DivElement(),
+    new Text('Hello'),
+    new DivElement(),
+    new Text('World'),
+    new CanvasElement()
+  ]);
+
+  group('dimensions', () {
+    setUp(initDiv);
+
+    test('contentEdge.height', () {
+      var all1 = querySelectorAll('#test');
+
+      expect(all1.contentEdge.height, 10);
+      expect(all1[0].getComputedStyle().getPropertyValue('height'), '10px');
+
+      all1.contentEdge.height = new Dimension.px(600);
+      all1.contentEdge.height = 600;
+      expect(all1.contentEdge.height, 600);
+      expect(all1[0].getComputedStyle().getPropertyValue('height'), '600px');
+      all1[0].style.visibility = 'hidden';
+      expect(all1.contentEdge.height, 600);
+      all1[0].style.visibility = 'visible';
+
+      // If user passes in a negative number, set height to 0.
+      all1.contentEdge.height = new Dimension.px(-1);
+      expect(all1.contentEdge.height, 0);
+
+      // Adding padding or border shouldn't affect the height for
+      // non-box-sizing.
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.height, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.height, 0);
+    });
+
+    test('contentEdge.height with border-box', () {
+      var all1 = document.querySelectorAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.contentEdge.height, 2);
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.height, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.height, 0);
+    });
+
+    test('contentEdge.width', () {
+      var all1 = document.querySelectorAll('#test');
+      expect(all1.contentEdge.width, 11);
+      expect(all1[0].getComputedStyle().getPropertyValue('width'), '11px');
+
+      all1.contentEdge.width = new Dimension.px(600);
+      expect(all1.contentEdge.width, 600);
+      expect(all1[0].getComputedStyle().getPropertyValue('width'), '600px');
+      all1[0].style.visibility = 'hidden';
+      expect(all1.contentEdge.width, 600);
+      all1[0].style.visibility = 'visible';
+
+      // If user passes in a negative number, set width to 0.
+      all1.contentEdge.width = new Dimension.px(-1);
+      expect(all1.contentEdge.width, 0);
+
+      // Adding padding or border shouldn't affect the width.
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.width, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.width, 0);
+    });
+
+    test('contentEdge.width with border-box', () {
+      var all1 = document.querySelectorAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.contentEdge.width, 3);
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.width, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.width, 0);
+    });
+
+    test('paddingEdge.height', () {
+      var all1 = document.querySelectorAll('#test');
+      expect(all1.paddingEdge.height, 18);
+      all1[0].style.visibility = 'hidden';
+      expect(all1.paddingEdge.height, 18);
+      all1[0].style.visibility = 'visible';
+
+      // Adding border shouldn't affect the paddingEdge.height.
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.height, 18);
+      // Adding padding should affect the paddingEdge.height.
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.height, 650);
+    });
+
+    test('paddingEdge.height with border-box', () {
+      var all1 = document.querySelectorAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.paddingEdge.height, 10);
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.height, 640);
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.height, 640);
+    });
+
+    test('paddingEdge.width', () {
+      var all1 = document.querySelectorAll('#test');
+      expect(all1.paddingEdge.width, 19);
+      all1[0].style.visibility = 'hidden';
+      expect(all1.paddingEdge.width, 19);
+      all1[0].style.visibility = 'visible';
+
+      // Adding border shouldn't affect the width.
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.width, 19);
+
+      // Adding padding should affect the paddingEdge.width.
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.width, 651);
+    });
+
+    test('paddingEdge.width with border-box', () {
+      var all1 = document.querySelectorAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.paddingEdge.width, 11);
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.width, 640);
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.width, 640);
+    });
+
+    test('borderEdge.height and marginEdge.height', () {
+      var all1 = document.querySelectorAll('#test');
+      expect(div.borderEdge.height, 18);
+      expect(div.marginEdge.height, 30);
+      expect(all1.borderEdge.height, 18);
+      expect(all1.marginEdge.height, 30);
+      all1[0].style.visibility = 'hidden';
+      expect(all1.borderEdge.height, 18);
+      all1[0].style.visibility = 'visible';
+
+      // Adding border should affect the borderEdge.height.
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.height, 22);
+      // Adding padding should affect the borderEdge.height.
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.height, 654);
+      expect(all1.marginEdge.height, 666);
+    });
+
+    test('borderEdge.height and marginEdge.height with border-box', () {
+      var all1 = document.querySelectorAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.borderEdge.height, 10);
+      expect(all1.marginEdge.height, 22);
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.height, 640);
+      expect(all1.marginEdge.height, 652);
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.height, 644);
+      expect(all1.marginEdge.height, 656);
+    });
+
+    test('borderEdge.width and marginEdge.width', () {
+      var all1 = document.querySelectorAll('#test');
+      expect(all1.borderEdge.width, 19);
+      expect(all1.marginEdge.width, 31);
+
+      // Adding border should affect the width.
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.width, 23);
+
+      // Adding padding should affect the borderEdge.width.
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.width, 655);
+      expect(all1.marginEdge.width, 667);
+    });
+
+    test('borderEdge.width and marginEdge.width with border-box', () {
+      var all1 = document.querySelectorAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.borderEdge.width, 11);
+      expect(all1.marginEdge.width, 23);
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.width, 640);
+      expect(all1.marginEdge.width, 652);
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.width, 644);
+      expect(all1.marginEdge.width, 656);
+    });
+
+    test('left and top', () {
+      div.style.border = '1px solid #fff';
+      div.style.margin = '6px 7px';
+      div.style.padding = '4px 5px';
+      var all1 = document.querySelectorAll('#test');
+
+      expect(all1.borderEdge.left, all1[0].getBoundingClientRect().left);
+      expect(all1.borderEdge.top, all1[0].getBoundingClientRect().top);
+
+      expect(
+          all1.contentEdge.left, all1[0].getBoundingClientRect().left + 1 + 5);
+      expect(all1.contentEdge.top, all1[0].getBoundingClientRect().top + 1 + 4);
+
+      expect(all1.marginEdge.left, all1[0].getBoundingClientRect().left - 7);
+      expect(all1.marginEdge.top, all1[0].getBoundingClientRect().top - 6);
+
+      expect(all1.paddingEdge.left, all1[0].getBoundingClientRect().left + 1);
+      expect(all1.paddingEdge.top, all1[0].getBoundingClientRect().top + 1);
+    });
+
+    test('setHeight ElementList', () {
+      div.style.border = '1px solid #fff';
+      div.style.margin = '6px 7px';
+      div.style.padding = '4px 5px';
+      var all1 = document.querySelectorAll('div');
+      all1.contentEdge.height = new Dimension.px(200);
+      all1.contentEdge.height = 200;
+      for (Element elem in all1) {
+        expect(elem.contentEdge.height, 200);
+      }
+      all1.contentEdge.height = new Dimension.px(10);
+      for (Element elem in all1) {
+        expect(elem.contentEdge.height, 10);
+      }
+    });
+  });
+}
diff --git a/tests/lib/html/element_offset_test.dart b/tests/lib/html/element_offset_test.dart
new file mode 100644
index 0000000..21681cf
--- /dev/null
+++ b/tests/lib/html/element_offset_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  void initPage() {
+    var level1 = new UListElement()
+      ..classes.add('level-1')
+      ..children.add(new LIElement()..innerHtml = 'I');
+    var itemii = new LIElement()
+      ..classes.add('item-ii')
+      ..style.position = 'relative'
+      ..style.top = '4px'
+      ..innerHtml = 'II';
+    level1.children.add(itemii);
+    var level2 = new UListElement();
+    itemii.children.add(level2);
+    var itema = new LIElement()
+      ..classes.add('item-a')
+      ..innerHtml = 'A';
+    var item1 = new LIElement()
+      ..classes.add('item-1')
+      ..innerHtml = '1';
+    var item2 = new LIElement()
+      ..classes.add('item-2')
+      ..innerHtml = '2';
+    var level3 = new UListElement()..children.addAll([item1, item2]);
+    var itemb = new LIElement()
+      ..classes.add('item-b')
+      ..style.position = 'relative'
+      ..style.top = '20px'
+      ..style.left = '150px'
+      ..innerHtml = 'B'
+      ..children.add(level3);
+    level2.children.addAll([itema, itemb, new LIElement()..innerHtml = 'C']);
+    document.body!.append(level1);
+    document.body!.style.whiteSpace = 'nowrap';
+
+    var bar = new DivElement()..classes.add('bar');
+    var style = bar.style;
+    style
+      ..position = 'absolute'
+      ..top = '8px'
+      ..left = '90px';
+    var baz = new DivElement()..classes.add('baz');
+    style = baz.style;
+    style
+      ..position = 'absolute'
+      ..top = '600px'
+      ..left = '7000px';
+    bar.children.add(baz);
+
+    var quux = new DivElement()..classes.add('quux');
+    var qux = new DivElement()..classes.add('qux')..children.add(quux);
+
+    document.body!.append(bar);
+    document.body!.append(qux);
+  }
+
+  group('offset', () {
+    setUp(initPage);
+
+    test('offsetTo', () {
+      var itema = querySelector('.item-a')!;
+      var itemb = querySelector('.item-b')!;
+      var item1 = querySelector('.item-1')!;
+      var itemii = querySelector('.item-ii')!;
+      var level1 = querySelector('.level-1')!;
+      var baz = querySelector('.baz')!;
+      var bar = querySelector('.bar')!;
+      var qux = querySelector('.qux')!;
+      var quux = querySelector('.quux')!;
+
+      var point = itema.offsetTo(itemii);
+      expect(point.x, 40);
+      expect(point.y, inInclusiveRange(16, 20));
+
+      expect(baz.offsetTo(bar).x, 7000);
+      expect(baz.offsetTo(bar).y, inInclusiveRange(599, 604));
+
+      qux.style.position = 'fixed';
+      expect(quux.offsetTo(qux).x, 0);
+      expect(quux.offsetTo(qux).y, 0);
+
+      point = item1.offsetTo(itemb);
+      expect(point.x, 40);
+      expect(point.y, inInclusiveRange(16, 20));
+      point = itemb.offsetTo(itemii);
+      expect(point.x, 190);
+      expect(point.y, inInclusiveRange(52, 60));
+      point = item1.offsetTo(itemii);
+      expect(point.x, 230);
+      expect(point.y, inInclusiveRange(68, 80));
+    });
+
+    test('documentOffset', () {
+      var bar = querySelector('.bar')!;
+      var baz = querySelector('.baz')!;
+      var qux = querySelector('.qux')!;
+      var quux = querySelector('.quux')!;
+      var itema = querySelector('.item-a')!;
+      var itemb = querySelector('.item-b')!;
+      var item1 = querySelector('.item-1')!;
+      var itemii = querySelector('.item-ii')!;
+
+      expect(itema.documentOffset.x, 88);
+      expect(itema.documentOffset.y, inInclusiveRange(111, 160));
+
+      expect(itemii.documentOffset.x, 48);
+      expect(itemii.documentOffset.y, inInclusiveRange(95, 145));
+
+      expect(itemb.documentOffset.x, 238);
+      expect(itemb.documentOffset.y, inInclusiveRange(147, 205));
+
+      expect(item1.documentOffset.x, 278);
+      expect(item1.documentOffset.y, inInclusiveRange(163, 222));
+
+      expect(bar.documentOffset.x, 90);
+      expect(bar.documentOffset.y, 8);
+
+      expect(baz.documentOffset.x, 7090);
+      expect(baz.documentOffset.y, 608);
+
+      expect(qux.documentOffset.x, 8);
+      expect(qux.documentOffset.y, inInclusiveRange(203, 240));
+
+      expect(quux.documentOffset.x, 8);
+      expect(quux.documentOffset.y, inInclusiveRange(203, 240));
+    });
+  });
+}
diff --git a/tests/lib/html/element_test.dart b/tests/lib/html/element_test.dart
new file mode 100644
index 0000000..cff1fab
--- /dev/null
+++ b/tests/lib/html/element_test.dart
@@ -0,0 +1,998 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library ElementTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'package:expect/expect.dart';
+import 'dart:async';
+import 'dart:html';
+import 'dart:svg' as svg;
+import 'utils.dart';
+
+expectLargeRect(Rectangle rect) {
+  expect(rect.top, 0);
+  expect(rect.left, 0);
+  expect(rect.width, greaterThan(100));
+  expect(rect.height, greaterThan(100));
+  expect(rect.bottom, rect.top + rect.height);
+  expect(rect.right, rect.left + rect.width);
+}
+
+void testUnsupported(String name, void f()) {
+  test(name, () => Expect.throwsUnsupportedError(f));
+}
+
+main() {
+  var isHRElement = predicate((x) => x is HRElement, 'is a HRElement');
+  var isBRElement = predicate((x) => x is BRElement, 'is a BRElement');
+  var isInputElement =
+      predicate((x) => x is InputElement, 'is an InputElement');
+  var isImageElement =
+      predicate((x) => x is ImageElement, 'is an ImageElement');
+  var isSpanElement = predicate((x) => x is SpanElement, 'is a SpanElement');
+  var isAnchorElement =
+      predicate((x) => x is AnchorElement, 'is an AnchorElement');
+  var isElementList =
+      predicate((x) => x is List<Element>, 'is a List<Element>');
+  var isElementIterable =
+      predicate((x) => x is Iterable<Element>, 'is an Iterable<Element>');
+  var isHeadingElement =
+      predicate((x) => x is HeadingElement, 'is a HeadingElement');
+
+  Element makeElement() => new Element.tag('div');
+
+  Element makeElementWithChildren() =>
+      new Element.html("<div><br/><img/><input/></div>");
+
+  group('position', () {
+    test('computedStyle', () {
+      final element = document.body!;
+      var style = element.getComputedStyle();
+      expect(style.getPropertyValue('left'), 'auto');
+    });
+
+    test('client position synchronous', () {
+      final container = new Element.tag("div");
+      container.style.position = 'absolute';
+      container.style.top = '8px';
+      container.style.left = '9px';
+      final element = new Element.tag("div");
+      element.style.width = '200px';
+      element.style.height = '200px';
+      container.children.add(element);
+      document.body!.children.add(container);
+
+      expect(element.client.width, greaterThan(100));
+      expect(element.client.height, greaterThan(100));
+      expect(element.offset.width, greaterThan(100));
+      expect(element.offset.height, greaterThan(100));
+      expect(element.scrollWidth, greaterThan(100));
+      expect(element.scrollHeight, greaterThan(100));
+      expect(element.getBoundingClientRect().left, 9);
+      expect(element.getBoundingClientRect().top, 8);
+
+      expect(element.documentOffset.x, 9);
+      expect(element.documentOffset.y, 8);
+      container.remove();
+    });
+  });
+
+  group('constructors', () {
+    test('error', () {
+      Expect.throwsStateError(() => new Element.html('<br/><br/>'));
+    });
+
+    test('.html has no parent',
+        () => expect(new Element.html('<br/>').parent, isNull));
+
+    test('.html table', () {
+      // http://developers.whatwg.org/tabular-data.html#tabular-data
+      TableElement node = new Element.html('''
+<table>
+ <caption>Characteristics with positive and negative sides</caption>
+ <thead>
+  <tr>
+   <th id="n"> Negative
+   <th> Characteristic
+   <th> Positive
+ <tbody>
+  <tr>
+   <td headers="n r1"> Sad
+   <th id="r1"> Mood
+   <td> Happy
+  <tr>
+   <td headers="n r2"> Failing
+   <th id="r2"> Grade
+   <td> Passing
+</table>''') as TableElement;
+      expect(node.tagName, 'TABLE');
+      expect(node.parent, isNull);
+      expect(node.caption!.innerHtml,
+          'Characteristics with positive and negative sides');
+      expect(node.tHead!.rows.length, 1);
+      expect(node.tHead!.rows[0].cells.length, 3);
+      expect(node.tBodies.length, 1);
+      expect(node.tBodies[0].rows.length, 2);
+      expect(node.tBodies[0].rows[1].cells.map((c) => c.innerHtml),
+          [' Failing\n   ', ' Grade\n   ', ' Passing\n']);
+    });
+
+    test('.html caption', () {
+      var table = new TableElement();
+      TableCaptionElement node = table
+          .createFragment('<caption><p>Table 1.')
+          .nodes
+          .single as TableCaptionElement;
+      expect(node.tagName, 'CAPTION');
+      expect(node.parent, isNull);
+      expect(node.innerHtml, '<p>Table 1.</p>');
+    });
+
+    test('.html colgroup', () {
+      var table = new TableElement();
+      TableColElement node = table
+          .createFragment('<colgroup> <col> <col> <col>')
+          .nodes
+          .single as TableColElement;
+      expect(node.tagName, 'COLGROUP');
+      expect(node.parent, isNull);
+      expect(node.innerHtml, ' <col> <col> <col>');
+    });
+
+    test('.html tbody', () {
+      var innerHtml = '<tr><td headers="n r1">Sad</td><td>Happy</td></tr>';
+      var table = new TableElement();
+      TableSectionElement node = table
+          .createFragment('<tbody>$innerHtml')
+          .nodes
+          .single as TableSectionElement;
+      expect(node.tagName, 'TBODY');
+      expect(node.parent, isNull);
+      expect(node.rows.length, 1);
+      expect(node.rows[0].cells.length, 2);
+      expect(node.innerHtml, innerHtml);
+    });
+
+    test('.html thead', () {
+      var innerHtml = '<tr><th id="n">Negative</th><th>Positive</th></tr>';
+      var table = new TableElement();
+      TableSectionElement node = table
+          .createFragment('<thead>$innerHtml')
+          .nodes
+          .single as TableSectionElement;
+      expect(node.tagName, 'THEAD');
+      expect(node.parent, isNull);
+      expect(node.rows.length, 1);
+      expect(node.rows[0].cells.length, 2);
+      expect(node.innerHtml, innerHtml);
+    });
+
+    test('.html tfoot', () {
+      var innerHtml = '<tr><th>percentage</th><td>34.3%</td></tr>';
+      var table = new TableElement();
+      TableSectionElement node = table
+          .createFragment('<tfoot>$innerHtml')
+          .nodes
+          .single as TableSectionElement;
+      expect(node.tagName, 'TFOOT');
+      expect(node.parent, isNull);
+      expect(node.rows.length, 1);
+      expect(node.rows[0].cells.length, 2);
+      expect(node.innerHtml, innerHtml);
+    });
+
+    test('.html tr', () {
+      var table = new TableElement();
+      document.body!.append(table);
+      var tBody = table.createTBody();
+      TableRowElement node = tBody
+          .createFragment('<tr><td>foo<td>bar')
+          .nodes
+          .single as TableRowElement;
+      expect(node.tagName, 'TR');
+      expect(node.parent, isNull);
+      expect(node.cells.map((c) => c.innerHtml), ['foo', 'bar']);
+    });
+
+    test('.html td', () {
+      var table = new TableElement();
+      document.body!.append(table);
+      var tBody = table.createTBody();
+      var tRow = tBody.addRow();
+      TableCellElement node =
+          tRow.createFragment('<td>foobar').nodes.single as TableCellElement;
+      expect(node.tagName, 'TD');
+      expect(node.parent, isNull);
+      expect(node.innerHtml, 'foobar');
+    });
+
+    test('.html th', () {
+      var table = new TableElement();
+      document.body!.append(table);
+      var tBody = table.createTBody();
+      var tRow = tBody.addRow();
+      TableCellElement node =
+          tRow.createFragment('<th>foobar').nodes.single as TableCellElement;
+      expect(node.tagName, 'TH');
+      expect(node.parent, isNull);
+      expect(node.innerHtml, 'foobar');
+    });
+
+    test('.html can fire events', () {
+      var e = new Element.html('<button>aha</button>');
+      var gotEvent = false;
+      e.onClick.listen((_) {
+        gotEvent = true;
+      });
+      e.click();
+      expect(gotEvent, isTrue, reason: 'click should have raised click event');
+    });
+  });
+
+  group('eventListening', () {
+    test('streams', () {
+      final target = new TextAreaElement();
+
+      void testEvent(Stream stream, String type, [createEvent(String type)?]) {
+        var firedOnEvent = false;
+        stream.listen((e) {
+          firedOnEvent = true;
+        });
+        expect(firedOnEvent, isFalse);
+        var event = createEvent != null ? createEvent(type) : new Event(type);
+        target.dispatchEvent(event);
+
+        expect(firedOnEvent, isTrue);
+      }
+
+      testEvent(target.onAbort, 'abort');
+      testEvent(target.onBeforeCopy, 'beforecopy');
+      testEvent(target.onBeforeCut, 'beforecut');
+      testEvent(target.onBeforePaste, 'beforepaste');
+      testEvent(target.onBlur, 'blur');
+      testEvent(target.onChange, 'change');
+      testEvent(
+          target.onContextMenu, 'contextmenu', (type) => new MouseEvent(type));
+      // We cannot test dispatching a true ClipboardEvent as the DOM does not
+      // provide a way to create a fake ClipboardEvent.
+      testEvent(target.onCopy, 'copy');
+      testEvent(target.onCut, 'cut');
+      testEvent(target.onPaste, 'paste');
+
+      testEvent(
+          target.onDoubleClick, 'dblclick', (type) => new MouseEvent(type));
+      testEvent(target.onDrag, 'drag', (type) => new MouseEvent(type));
+      testEvent(target.onDragEnd, 'dragend', (type) => new MouseEvent(type));
+      testEvent(
+          target.onDragEnter, 'dragenter', (type) => new MouseEvent(type));
+      testEvent(
+          target.onDragLeave, 'dragleave', (type) => new MouseEvent(type));
+      testEvent(target.onDragOver, 'dragover', (type) => new MouseEvent(type));
+      testEvent(
+          target.onDragStart, 'dragstart', (type) => new MouseEvent(type));
+      testEvent(target.onDrop, 'drop', (type) => new MouseEvent(type));
+      testEvent(target.onError, 'error');
+      testEvent(target.onFocus, 'focus');
+      testEvent(target.onFullscreenChange, 'webkitfullscreenchange');
+      testEvent(target.onInput, 'input');
+      testEvent(target.onInvalid, 'invalid');
+      testEvent(target.onKeyDown, 'keydown', (type) => new KeyboardEvent(type));
+      testEvent(
+          target.onKeyPress, 'keypress', (type) => new KeyboardEvent(type));
+      testEvent(target.onKeyUp, 'keyup', (type) => new KeyboardEvent(type));
+      testEvent(target.onLoad, 'load');
+      testEvent(
+          target.onMouseDown, 'mousedown', (type) => new MouseEvent(type));
+      testEvent(
+          target.onMouseMove, 'mousemove', (type) => new MouseEvent(type));
+      testEvent(target.onMouseOut, 'mouseout', (type) => new MouseEvent(type));
+      testEvent(
+          target.onMouseOver, 'mouseover', (type) => new MouseEvent(type));
+      testEvent(target.onMouseUp, 'mouseup', (type) => new MouseEvent(type));
+      testEvent(target.onReset, 'reset');
+      testEvent(target.onScroll, 'scroll');
+      testEvent(target.onSearch, 'search');
+      testEvent(target.onSelect, 'select');
+      testEvent(target.onSelectStart, 'selectstart');
+      testEvent(target.onSubmit, 'submit');
+      // We would prefer to create new touch events for this test via
+      // new TouchEvent(null, null, null, type)
+      // but that fails on desktop browsers as touch is not enabled.
+      testEvent(target.onTouchCancel, 'touchcancel');
+      testEvent(target.onTouchEnd, 'touchend');
+      testEvent(target.onTouchLeave, 'touchleave');
+      testEvent(target.onTouchMove, 'touchmove');
+      testEvent(target.onTouchStart, 'touchstart');
+    });
+  });
+
+  group('click', () {
+    test('clickEvent', () {
+      var e = new DivElement();
+      var firedEvent = false;
+      e.onClick.listen((event) {
+        firedEvent = true;
+      });
+      expect(firedEvent, false);
+      e.click();
+      expect(firedEvent, true);
+
+      var e2 = new DivElement();
+      var firedEvent2 = false;
+      e2.onClick.matches('.foo').listen((event) {
+        firedEvent2 = true;
+      });
+      e2.click();
+      expect(firedEvent2, false);
+      e2.classes.add('foo');
+      e2.click();
+      expect(firedEvent2, true);
+    });
+  });
+
+  group('attributes', () {
+    test('manipulation', () {
+      final element = new Element.html(
+          '''<div class="foo" style="overflow: hidden" data-foo="bar"
+                   data-foo2="bar2" dir="rtl">
+               </div>''',
+          treeSanitizer: new NullTreeSanitizer());
+      final attributes = element.attributes;
+      expect(attributes['class'], 'foo');
+      startsWith(match) => predicate((x) => x is String && x.startsWith(match));
+      expect(attributes['style'], startsWith('overflow: hidden'));
+      expect(attributes['data-foo'], 'bar');
+      expect(attributes['data-foo2'], 'bar2');
+      expect(attributes.length, 5);
+      expect(element.dataset.length, 2);
+      element.dataset['foo'] = 'baz';
+      expect(element.dataset['foo'], 'baz');
+      expect(attributes['data-foo'], 'baz');
+      attributes['data-foo2'] = 'baz2';
+      expect(attributes['data-foo2'], 'baz2');
+      expect(element.dataset['foo2'], 'baz2');
+      expect(attributes['dir'], 'rtl');
+
+      final dataset = element.dataset;
+      dataset.remove('foo2');
+      expect(attributes.length, 4);
+      expect(dataset.length, 1);
+      attributes.remove('style');
+      expect(attributes.length, 3);
+      dataset['foo3'] = 'baz3';
+      expect(dataset.length, 2);
+      expect(attributes.length, 4);
+      attributes['style'] = 'width: 300px;';
+      expect(attributes.length, 5);
+    });
+
+    test('namespaces', () {
+      var element =
+          new svg.SvgElement.svg('''<svg xmlns="http://www.w3.org/2000/svg"
+                  xmlns:xlink="http://www.w3.org/1999/xlink">
+            <image xlink:href="foo" data-foo="bar"/>
+          </svg>''').children[0];
+
+      var attributes = element.attributes;
+      expect(attributes.length, 1);
+      expect(attributes['data-foo'], 'bar');
+
+      var xlinkAttrs =
+          element.getNamespacedAttributes('http://www.w3.org/1999/xlink');
+      expect(xlinkAttrs.length, 1);
+      expect(xlinkAttrs['href'], 'foo');
+
+      xlinkAttrs.remove('href');
+      expect(xlinkAttrs.length, 0);
+
+      xlinkAttrs['href'] = 'bar';
+      expect(xlinkAttrs['href'], 'bar');
+
+      var randomAttrs = element.getNamespacedAttributes('http://example.com');
+      expect(randomAttrs.length, 0);
+      randomAttrs['href'] = 'bar';
+      expect(randomAttrs.length, 1);
+    });
+  });
+
+  group('children', () {
+    test('is a subset of nodes', () {
+      var el = new Element.html("<div>Foo<br/><img/></div>");
+      expect(el.nodes.length, 3);
+      expect(el.children.length, 2);
+      expect(el.nodes[1], el.children[0]);
+      expect(el.nodes[2], el.children[1]);
+    });
+
+    test('changes when an element is added to nodes', () {
+      var el = new Element.html("<div>Foo<br/><img/></div>");
+      el.nodes.add(new Element.tag('hr'));
+      expect(el.children.length, 3);
+      expect(el.children[2], isHRElement);
+      expect(el.nodes[3], el.children[2]);
+    });
+
+    test('changes nodes when an element is added', () {
+      var el = new Element.html("<div>Foo<br/><img/></div>");
+      el.children.add(new Element.tag('hr'));
+      expect(el.nodes.length, 4);
+      expect(el.nodes[3], isHRElement);
+      expect(el.children[2], el.nodes[3]);
+    });
+
+    test('last', () {
+      var el = makeElementWithChildren();
+      expect(el.children.last, isInputElement);
+    });
+
+    test('forEach', () {
+      var els = [];
+      var el = makeElementWithChildren();
+      el.children.forEach((n) => els.add(n));
+      expect(els[0], isBRElement);
+      expect(els[1], isImageElement);
+      expect(els[2], isInputElement);
+    });
+
+    test('where', () {
+      var filtered =
+          makeElementWithChildren().children.where((n) => n is ImageElement);
+      expect(1, filtered.length);
+      expect(filtered.first, isImageElement);
+      expect(filtered, isElementIterable);
+    });
+
+    test('every', () {
+      var el = makeElementWithChildren();
+      expect(el.children.every((n) => n is Element), isTrue);
+      expect(el.children.every((n) => n is InputElement), isFalse);
+    });
+
+    test('any', () {
+      var el = makeElementWithChildren();
+      expect(el.children.any((n) => n is InputElement), isTrue);
+      expect(el.children.any((n) => n is svg.SvgElement), isFalse);
+    });
+
+    test('isEmpty', () {
+      expect(makeElement().children.isEmpty, isTrue);
+      expect(makeElementWithChildren().children.isEmpty, isFalse);
+    });
+
+    test('length', () {
+      expect(makeElement().children.length, 0);
+      expect(makeElementWithChildren().children.length, 3);
+    });
+
+    test('[]', () {
+      var el = makeElementWithChildren();
+      expect(el.children[0], isBRElement);
+      expect(el.children[1], isImageElement);
+      expect(el.children[2], isInputElement);
+    });
+
+    test('[]=', () {
+      var el = makeElementWithChildren();
+      el.children[1] = new Element.tag('hr');
+      expect(el.children[0], isBRElement);
+      expect(el.children[1], isHRElement);
+      expect(el.children[2], isInputElement);
+    });
+
+    test('add', () {
+      var el = makeElement();
+      el.children.add(new Element.tag('hr'));
+      expect(el.children.last, isHRElement);
+    });
+
+    test('iterator', () {
+      var els = [];
+      var el = makeElementWithChildren();
+      for (var subel in el.children) {
+        els.add(subel);
+      }
+      expect(els[0], isBRElement);
+      expect(els[1], isImageElement);
+      expect(els[2], isInputElement);
+    });
+
+    test('addAll', () {
+      var el = makeElementWithChildren();
+      el.children.addAll([
+        new Element.tag('span'),
+        new Element.tag('a'),
+        new Element.tag('h1')
+      ]);
+      expect(el.children[0], isBRElement);
+      expect(el.children[1], isImageElement);
+      expect(el.children[2], isInputElement);
+      expect(el.children[3], isSpanElement);
+      expect(el.children[4], isAnchorElement);
+      expect(el.children[5], isHeadingElement);
+    });
+
+    test('insert', () {
+      var element = new DivElement();
+      element.children.insert(0, new BRElement());
+      expect(element.children[0], isBRElement);
+      element.children.insert(0, new HRElement());
+      expect(element.children[0], isHRElement);
+      element.children.insert(1, new ImageElement());
+      expect(element.children[1], isImageElement);
+      element.children.insert(element.children.length, new InputElement());
+      expect(element.children.last, isInputElement);
+    });
+
+    test('clear', () {
+      var el = makeElementWithChildren();
+      el.children.clear();
+      expect(el.children, equals([]));
+    });
+
+    test('removeLast', () {
+      var el = makeElementWithChildren();
+      expect(el.children.removeLast(), isInputElement);
+      expect(el.children.length, 2);
+      expect(el.children.removeLast(), isImageElement);
+      expect(el.children.length, 1);
+    });
+
+    test('sublist', () {
+      var el = makeElementWithChildren();
+      expect(el.children.sublist(1, 2), isElementList);
+    });
+
+    test('getRange', () {
+      var el = makeElementWithChildren();
+      expect(el.children.getRange(1, 2).length, 1);
+    });
+
+    test('retainWhere', () {
+      var el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.retainWhere((e) => true);
+      expect(el.children.length, 3);
+
+      el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.retainWhere((e) => false);
+      expect(el.children.length, 0);
+
+      el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.retainWhere((e) => e.localName == 'input');
+      expect(el.children.length, 1);
+
+      el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.retainWhere((e) => e.localName == 'br');
+      expect(el.children.length, 1);
+    });
+
+    test('removeWhere', () {
+      var el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.removeWhere((e) => true);
+      expect(el.children.length, 0);
+
+      el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.removeWhere((e) => false);
+      expect(el.children.length, 3);
+
+      el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.removeWhere((e) => e.localName == 'input');
+      expect(el.children.length, 2);
+
+      el = makeElementWithChildren();
+      expect(el.children.length, 3);
+      el.children.removeWhere((e) => e.localName == 'br');
+      expect(el.children.length, 2);
+    });
+
+    testUnsupported('sort', () {
+      var l = makeElementWithChildren().children;
+      l.sort();
+    });
+
+    testUnsupported('setRange', () {
+      var l = makeElementWithChildren().children;
+      l.setRange(0, 0, []);
+    });
+
+    testUnsupported('replaceRange', () {
+      var l = makeElementWithChildren().children;
+      l.replaceRange(0, 0, []);
+    });
+
+    testUnsupported('removeRange', () {
+      var l = makeElementWithChildren().children;
+      l.removeRange(0, 1);
+    });
+
+    testUnsupported('insertAll', () {
+      var l = makeElementWithChildren().children;
+      l.insertAll(0, []);
+    });
+  });
+
+  group('matches', () {
+    test('matches', () {
+      var element = new DivElement();
+      document.body!.append(element);
+      element.classes.add('test');
+
+      expect(element.matches('div'), true);
+      expect(element.matches('span'), false);
+      expect(element.matches('.test'), true);
+    });
+  });
+
+  group('querySelectorAll', () {
+    List<Element> getQuerySelectorAll() {
+      return new Element.html("""
+<div>
+  <hr/>
+  <a class='q' href='http://dartlang.org'>Dart!</a>
+  <p>
+    <span class='q'>Hello</span>,
+    <em>world</em>!
+  </p>
+  <hr class='q'/>
+</div>
+""").querySelectorAll('.q');
+    }
+
+    List<Element> getEmptyQuerySelectorAll() =>
+        new Element.tag('div').querySelectorAll('img');
+
+    test('last', () {
+      expect(getQuerySelectorAll().last, isHRElement);
+    });
+
+    test('forEach', () {
+      var els = [];
+      getQuerySelectorAll().forEach((el) => els.add(el));
+      expect(els[0], isAnchorElement);
+      expect(els[1], isSpanElement);
+      expect(els[2], isHRElement);
+    });
+
+    test('map', () {
+      var texts = getQuerySelectorAll().map((el) => el.text).toList();
+      expect(texts, equals(['Dart!', 'Hello', '']));
+    });
+
+    test('where', () {
+      var filtered =
+          getQuerySelectorAll().where((n) => n is SpanElement).toList();
+      expect(filtered.length, 1);
+      expect(filtered[0], isSpanElement);
+      expect(filtered, isElementList);
+    });
+
+    test('every', () {
+      var el = getQuerySelectorAll();
+      expect(el.every((n) => n is Element), isTrue);
+      expect(el.every((n) => n is SpanElement), isFalse);
+    });
+
+    test('any', () {
+      var el = getQuerySelectorAll();
+      expect(el.any((n) => n is SpanElement), isTrue);
+      expect(el.any((n) => n is svg.SvgElement), isFalse);
+    });
+
+    test('isEmpty', () {
+      expect(getEmptyQuerySelectorAll().isEmpty, isTrue);
+      expect(getQuerySelectorAll().isEmpty, isFalse);
+    });
+
+    test('length', () {
+      expect(getEmptyQuerySelectorAll().length, 0);
+      expect(getQuerySelectorAll().length, 3);
+    });
+
+    test('[]', () {
+      var els = getQuerySelectorAll();
+      expect(els[0], isAnchorElement);
+      expect(els[1], isSpanElement);
+      expect(els[2], isHRElement);
+    });
+
+    test('iterator', () {
+      var els = [];
+      for (var subel in getQuerySelectorAll()) {
+        els.add(subel);
+      }
+      expect(els[0], isAnchorElement);
+      expect(els[1], isSpanElement);
+      expect(els[2], isHRElement);
+    });
+
+    test('sublist', () {
+      expect(getQuerySelectorAll().sublist(1, 2) is List<Element>, isTrue);
+    });
+
+    testUnsupported(
+        '[]=', () => getQuerySelectorAll()[1] = new Element.tag('br'));
+    testUnsupported(
+        'add', () => getQuerySelectorAll().add(new Element.tag('br')));
+
+    testUnsupported('addAll', () {
+      getQuerySelectorAll().addAll([
+        new Element.tag('span'),
+        new Element.tag('a'),
+        new Element.tag('h1')
+      ]);
+    });
+
+    testUnsupported('sort', () => getQuerySelectorAll().sort((a1, a2) => 0));
+
+    testUnsupported('setRange', () {
+      getQuerySelectorAll().setRange(0, 1, [new BRElement()]);
+    });
+
+    testUnsupported(
+        'removeRange', () => getQuerySelectorAll().removeRange(0, 1));
+
+    testUnsupported('clear', () => getQuerySelectorAll().clear());
+
+    testUnsupported('removeLast', () => getQuerySelectorAll().removeLast());
+  });
+
+  group('functional', () {
+    test('toString', () {
+      final elems = makeElementWithChildren().children;
+      expect(elems.toString(), "[br, img, input]");
+      final elem = makeElement().children;
+      expect(elem.toString(), '[]');
+    });
+
+    test('scrollIntoView', () {
+      var child = new DivElement();
+      document.body!.append(child);
+
+      child.scrollIntoView(ScrollAlignment.TOP);
+      child.scrollIntoView(ScrollAlignment.BOTTOM);
+      child.scrollIntoView(ScrollAlignment.CENTER);
+      child.scrollIntoView();
+    });
+  });
+
+  group('_ElementList', () {
+    List<Element> makeElList() => makeElementWithChildren().children;
+
+    test('where', () {
+      var filtered = makeElList().where((n) => n is ImageElement);
+      expect(filtered.length, 1);
+      expect(filtered.first, isImageElement);
+      expect(filtered, isElementIterable);
+    });
+
+    test('sublist', () {
+      var range = makeElList().sublist(1, 3);
+      expect(range, isElementList);
+      expect(range[0], isImageElement);
+      expect(range[1], isInputElement);
+    });
+  });
+
+  group('eventDelegation', () {
+    test('matches', () {
+      Element clickOne = new Element.a();
+      Element selectorOne = new Element.div()
+        ..classes.add('selector')
+        ..children.add(clickOne);
+
+      Element clickTwo = new Element.a();
+      Element selectorTwo = new Element.div()
+        ..classes.add('selector')
+        ..children.add(clickTwo);
+      document.body!.append(selectorOne);
+      document.body!.append(selectorTwo);
+
+      document.body!.onClick
+          .matches('.selector')
+          .listen(expectAsync1((Event event) {
+        expect(event.currentTarget, document.body);
+        expect(event.target, clickOne);
+        expect(event.matchingTarget, selectorOne);
+      }));
+
+      selectorOne.onClick
+          .matches('.selector')
+          .listen(expectAsync1((Event event) {
+        expect(event.currentTarget, selectorOne);
+        expect(event.target, clickOne);
+        expect(event.matchingTarget, selectorOne);
+      }));
+      clickOne.click();
+
+      Element elem = new Element.div()..classes.addAll(['a', 'b']);
+      Element img = new Element.img()
+        ..classes.addAll(['b', 'a', 'd'])
+        ..id = 'cookie';
+      Element input = new InputElement()..classes.addAll(['c', 'd']);
+      var div = new Element.div()
+        ..classes.add('a')
+        ..id = 'wat';
+      document.body!.append(elem);
+      document.body!.append(img);
+      document.body!.append(input);
+      document.body!.append(div);
+
+      Element elem4 = new Element.div()..classes.addAll(['i', 'j']);
+      Element elem5 = new Element.div()
+        ..classes.addAll(['g', 'h'])
+        ..children.add(elem4);
+      Element elem6 = new Element.div()
+        ..classes.addAll(['e', 'f'])
+        ..children.add(elem5);
+      document.body!.append(elem6);
+
+      var firedEvent = false;
+      var elems = querySelectorAll('.a');
+      querySelectorAll('.a').onClick.listen((event) {
+        firedEvent = true;
+      });
+      expect(firedEvent, false);
+      querySelector('.c')!.click();
+      expect(firedEvent, false);
+      querySelector('#wat')!.click();
+      expect(firedEvent, true);
+
+      var firedEvent4 = false;
+      querySelectorAll('.a').onClick.matches('.d').listen((event) {
+        firedEvent4 = true;
+      });
+      expect(firedEvent4, false);
+      querySelector('.c')!.click();
+      expect(firedEvent4, false);
+      querySelector('#wat')!.click();
+      expect(firedEvent4, false);
+      querySelector('#cookie')!.click();
+      expect(firedEvent4, true);
+
+      var firedEvent2 = false;
+      querySelectorAll('.a').onClick.listen((event) {
+        firedEvent2 = true;
+      });
+      Element elem2 = new Element.html('<div class="a"><br/>');
+      document.body!.append(elem2);
+      elem2.click();
+      expect(firedEvent2, false);
+      elem2.classes.add('a');
+      elem2.click();
+      expect(firedEvent2, false);
+
+      var firedEvent3 = false;
+      querySelectorAll(':root').onClick.matches('.a').listen((event) {
+        firedEvent3 = true;
+      });
+      Element elem3 = new Element.html('<div class="d"><br/>');
+      document.body!.append(elem3);
+      elem3.click();
+      expect(firedEvent3, false);
+      elem3.classes.add('a');
+      elem3.click();
+      expect(firedEvent3, true);
+
+      var firedEvent5 = false;
+      querySelectorAll(':root').onClick.matches('.e').listen((event) {
+        firedEvent5 = true;
+      });
+      expect(firedEvent5, false);
+      querySelector('.i')!.click();
+      expect(firedEvent5, true);
+    });
+
+    test('event ordering', () {
+      var a = new DivElement();
+      var b = new DivElement();
+      a.append(b);
+      var c = new DivElement();
+      b.append(c);
+
+      var eventOrder = [];
+
+      ElementStream aEvent = a.on['custom_event'] as ElementStream;
+      aEvent.listen((_) {
+        eventOrder.add('a no-capture');
+      });
+
+      aEvent.capture((_) {
+        eventOrder.add('a capture');
+      });
+
+      ElementStream bEvent = b.on['custom_event'] as ElementStream;
+      bEvent.listen((_) {
+        eventOrder.add('b no-capture');
+      });
+
+      bEvent.capture((_) {
+        eventOrder.add('b capture');
+      });
+
+      document.body!.append(a);
+
+      var event = new Event('custom_event', canBubble: true);
+      c.dispatchEvent(event);
+      expect(eventOrder,
+          ['a capture', 'b capture', 'b no-capture', 'a no-capture']);
+    });
+  });
+
+  group('ElementList', () {
+    // Tests for methods on the DOM class 'NodeList'.
+    //
+    // There are two interesting things that are validated here from the
+    // viewpoint of the dart2js implementation of a 'native' class:
+    //
+    //   1. Some methods are implemented from by 'Object' or 'Interceptor';
+    //      some of these tests validate that a method can be called.
+    //   2. Some methods are implemented by mixins.
+
+    ElementList<Element> makeElementList() =>
+        (new Element.html("<div>Foo<br/><!--baz--><br/><br/></div>"))
+            .querySelectorAll('br');
+
+    test('hashCode', () {
+      var nodes = makeElementList();
+      var hash = nodes.hashCode;
+      final int N = 1000;
+      int matchCount = 0;
+      for (int i = 0; i < N; i++) {
+        if (makeElementList().hashCode == hash) matchCount++;
+      }
+      expect(matchCount, lessThan(N));
+    });
+
+    test('operator==', () {
+      var a = [makeElementList(), makeElementList(), null];
+      for (int i = 0; i < a.length; i++) {
+        for (int j = 0; j < a.length; j++) {
+          expect(i == j, a[i] == a[j]);
+        }
+      }
+    });
+
+    test('runtimeType', () {
+      var nodes1 = makeElementList();
+      var nodes2 = makeElementList();
+      var type1 = nodes1.runtimeType;
+      var type2 = nodes2.runtimeType;
+      expect(type1 == type2, true);
+      String name = '$type1';
+      if (name.length > 3) {
+        expect(name.contains('ElementList'), true);
+      }
+    });
+
+    test('first', () {
+      var nodes = makeElementList();
+      expect(nodes.first, isBRElement);
+    });
+
+    test('last', () {
+      var nodes = makeElementList();
+      expect(nodes.last, isBRElement);
+    });
+
+    test('where', () {
+      var filtered = makeElementList().where((n) => n is BRElement).toList();
+      expect(filtered.length, 3);
+      expect(filtered[0], isBRElement);
+    });
+
+    test('sublist', () {
+      var range = makeElementList().sublist(1, 3);
+      expect(range.length, 2);
+      expect(range[0], isBRElement);
+      expect(range[1], isBRElement);
+    });
+  });
+}
diff --git a/tests/lib/html/element_types_constructors1_test.dart b/tests/lib/html/element_types_constructors1_test.dart
new file mode 100644
index 0000000..9c5575d
--- /dev/null
+++ b/tests/lib/html/element_types_constructors1_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      if (supported) {
+        expect(fn(), isTrue);
+      } else {
+        // Can either throw or return false.
+        expect(() => (fn() || (throw "false")), throws);
+      }
+    });
+  }
+
+  group('constructors', () {
+    check('a', () => new AnchorElement() is AnchorElement);
+    check('area', () => new AreaElement() is AreaElement);
+    check('audio', () => new AudioElement() is AudioElement);
+    check('body', () => new BodyElement() is BodyElement);
+    check('br', () => new BRElement() is BRElement);
+    check('base', () => new BaseElement() is BaseElement);
+    check('button', () => new ButtonElement() is ButtonElement);
+    check('canvas', () => new CanvasElement() is CanvasElement);
+    check('caption', () => new TableCaptionElement() is TableCaptionElement);
+    check('content', () => new ContentElement() is ContentElement,
+        ContentElement.supported);
+    check('details', () => new DetailsElement() is DetailsElement,
+        DetailsElement.supported);
+    check('datalist', () => new DataListElement() is DataListElement,
+        DataListElement.supported);
+    check('dl', () => new DListElement() is DListElement);
+    check('div', () => new DivElement() is DivElement);
+    check('embed', () => new EmbedElement() is EmbedElement,
+        EmbedElement.supported);
+  });
+}
diff --git a/tests/lib/html/element_types_constructors2_test.dart b/tests/lib/html/element_types_constructors2_test.dart
new file mode 100644
index 0000000..d1376b0
--- /dev/null
+++ b/tests/lib/html/element_types_constructors2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      if (supported) {
+        expect(fn(), supported);
+      } else {
+        // Can either throw or return false.
+        expect(() => (fn() || (throw "false")), throws);
+      }
+    });
+  }
+
+  group('constructors', () {
+    check('fieldset', () => new FieldSetElement() is FieldSetElement);
+    check('form', () => new FormElement() is FormElement);
+    check('head', () => new HeadElement() is HeadElement);
+    check('hr', () => new HRElement() is HRElement);
+    check('html', () => new HtmlHtmlElement() is HtmlHtmlElement);
+    check('h1', () => new HeadingElement.h1() is HeadingElement);
+    check('h2', () => new HeadingElement.h2() is HeadingElement);
+    check('h3', () => new HeadingElement.h3() is HeadingElement);
+    check('h4', () => new HeadingElement.h4() is HeadingElement);
+    check('h5', () => new HeadingElement.h5() is HeadingElement);
+    check('h6', () => new HeadingElement.h6() is HeadingElement);
+    check('iframe', () => new IFrameElement() is IFrameElement);
+    check('img', () => new ImageElement() is ImageElement);
+    check('input', () => new InputElement() is InputElement);
+  });
+}
diff --git a/tests/lib/html/element_types_constructors3_test.dart b/tests/lib/html/element_types_constructors3_test.dart
new file mode 100644
index 0000000..dcd5dbd
--- /dev/null
+++ b/tests/lib/html/element_types_constructors3_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      if (supported) {
+        expect(fn(), isTrue);
+      } else {
+        // Can either throw or return false.
+        expect(() => (fn() || (throw "false")), throws);
+      }
+    });
+  }
+
+  group('constructors', () {
+    check('li', () => new LIElement() is LIElement);
+    check('label', () => new LabelElement() is LabelElement);
+    check('legen', () => new LegendElement() is LegendElement);
+    check('link', () => new LinkElement() is LinkElement);
+    check('map', () => new MapElement() is MapElement);
+    check('menu', () => new MenuElement() is MenuElement);
+    check('meta', () => new MetaElement() is MetaElement);
+    check('meter', () => new MeterElement() is MeterElement,
+        MeterElement.supported);
+    check('del', () => new Element.tag('del') is ModElement);
+    check('ins', () => new Element.tag('ins') is ModElement);
+    check('object', () => new ObjectElement() is ObjectElement,
+        ObjectElement.supported);
+    check('ol', () => new OListElement() is OListElement);
+    check('optgroup', () => new OptGroupElement() is OptGroupElement);
+    check('option', () => new OptionElement() is OptionElement);
+    check('output', () => new OutputElement() is OutputElement,
+        OutputElement.supported);
+  });
+}
diff --git a/tests/lib/html/element_types_constructors4_test.dart b/tests/lib/html/element_types_constructors4_test.dart
new file mode 100644
index 0000000..26e6acb
--- /dev/null
+++ b/tests/lib/html/element_types_constructors4_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      if (supported) {
+        expect(fn(), isTrue);
+      } else {
+        // Can either throw or return false.
+        expect(() => (fn() || (throw "false")), throws);
+      }
+    });
+  }
+
+  group('constructors', () {
+    check('p', () => new ParagraphElement() is ParagraphElement);
+    check('param', () => new ParamElement() is ParamElement);
+    check('pre', () => new PreElement() is PreElement);
+    check('progress', () => new ProgressElement() is ProgressElement,
+        ProgressElement.supported);
+    check('q', () => new QuoteElement() is QuoteElement);
+    check('script', () => new ScriptElement() is ScriptElement);
+    check('select', () => new SelectElement() is SelectElement);
+    check('shadow', () => new ShadowElement() is ShadowElement,
+        ShadowElement.supported);
+    check('source', () => new SourceElement() is SourceElement);
+    check('span', () => new SpanElement() is SpanElement);
+    check('style', () => new StyleElement() is StyleElement);
+  });
+}
diff --git a/tests/lib/html/element_types_constructors5_test.dart b/tests/lib/html/element_types_constructors5_test.dart
new file mode 100644
index 0000000..7039442
--- /dev/null
+++ b/tests/lib/html/element_types_constructors5_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      if (supported) {
+        expect(fn(), isTrue);
+      } else {
+        // Can either throw or return false.
+        expect(() => (fn() || (throw "false")), throws);
+      }
+    });
+  }
+
+  group('constructors', () {
+    check('table', () => new TableElement() is TableElement);
+    check('template', () => new TemplateElement() is TemplateElement,
+        TemplateElement.supported);
+    check('textarea', () => new TextAreaElement() is TextAreaElement);
+    check('title', () => new TitleElement() is TitleElement);
+    check('td', () => new TableCellElement() is TableCellElement);
+    check('col', () => new TableColElement() is TableColElement);
+    check('colgroup', () => new Element.tag('colgroup') is TableColElement);
+    check('tr', () => new TableRowElement() is TableRowElement);
+    check('tbody', () => new Element.tag('tbody') is TableSectionElement);
+    check('tfoot', () => new Element.tag('tfoot') is TableSectionElement);
+    check('thead', () => new Element.tag('thead') is TableSectionElement);
+    check('track', () => new TrackElement() is TrackElement,
+        TrackElement.supported);
+  });
+}
diff --git a/tests/lib/html/element_types_constructors6_test.dart b/tests/lib/html/element_types_constructors6_test.dart
new file mode 100644
index 0000000..50b81c2
--- /dev/null
+++ b/tests/lib/html/element_types_constructors6_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      if (supported) {
+        expect(fn(), isTrue);
+      } else {
+        // Can either throw or return false.
+        expect(() => (fn() || (throw "false")), throws);
+      }
+    });
+  }
+
+  group('ul', () {
+    check('ul', () => new UListElement() is UListElement);
+
+    test('accepts li', () {
+      var ul = new UListElement();
+      var li = new LIElement();
+      ul.append(li);
+    });
+  });
+  group('constructors', () {
+    check('video', () => new VideoElement() is VideoElement);
+    check('unknown', () => new Element.tag('someunknown') is UnknownElement);
+  });
+}
diff --git a/tests/lib/html/element_types_content_test.dart b/tests/lib/html/element_types_content_test.dart
new file mode 100644
index 0000000..2e0109f
--- /dev/null
+++ b/tests/lib/html/element_types_content_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('content_supported', () {
+    expect(ContentElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_datalist_test.dart b/tests/lib/html/element_types_datalist_test.dart
new file mode 100644
index 0000000..a12acc5
--- /dev/null
+++ b/tests/lib/html/element_types_datalist_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('datalist_supported', () {
+    expect(DataListElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_details_test.dart b/tests/lib/html/element_types_details_test.dart
new file mode 100644
index 0000000..b47f998
--- /dev/null
+++ b/tests/lib/html/element_types_details_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('details_supported', () {
+    expect(DetailsElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_embed_test.dart b/tests/lib/html/element_types_embed_test.dart
new file mode 100644
index 0000000..7c23d38
--- /dev/null
+++ b/tests/lib/html/element_types_embed_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('embed_supported', () {
+    expect(EmbedElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_meter_test.dart b/tests/lib/html/element_types_meter_test.dart
new file mode 100644
index 0000000..cdd917e
--- /dev/null
+++ b/tests/lib/html/element_types_meter_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('meter_supported', () {
+    expect(MeterElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_object_test.dart b/tests/lib/html/element_types_object_test.dart
new file mode 100644
index 0000000..03f508c
--- /dev/null
+++ b/tests/lib/html/element_types_object_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('object_supported', () {
+    expect(ObjectElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_output_test.dart b/tests/lib/html/element_types_output_test.dart
new file mode 100644
index 0000000..8781aa3
--- /dev/null
+++ b/tests/lib/html/element_types_output_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('output_supported', () {
+    expect(OutputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_progress_test.dart b/tests/lib/html/element_types_progress_test.dart
new file mode 100644
index 0000000..9dac474
--- /dev/null
+++ b/tests/lib/html/element_types_progress_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('progress_supported', () {
+    expect(ProgressElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_shadow_test.dart b/tests/lib/html/element_types_shadow_test.dart
new file mode 100644
index 0000000..271c49d
--- /dev/null
+++ b/tests/lib/html/element_types_shadow_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('shadow_supported', () {
+    expect(ShadowElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_template_test.dart b/tests/lib/html/element_types_template_test.dart
new file mode 100644
index 0000000..d7939ab
--- /dev/null
+++ b/tests/lib/html/element_types_template_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('template_supported', () {
+    expect(TemplateElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/element_types_track_test.dart b/tests/lib/html/element_types_track_test.dart
new file mode 100644
index 0000000..27c65d1
--- /dev/null
+++ b/tests/lib/html/element_types_track_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('track_supported', () {
+    expect(TrackElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/event_callback_test.dart b/tests/lib/html/event_callback_test.dart
new file mode 100644
index 0000000..347e754
--- /dev/null
+++ b/tests/lib/html/event_callback_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// Regression test for issue 33627.
+
+import 'dart:html';
+import 'package:expect/expect.dart';
+
+void main() {
+  try {
+    print('InputElement');
+    var i = new InputElement();
+    print('> onKeyPress');
+    i.onKeyPress.listen(onEvent);
+    print('> onClick');
+    i.onClick.listen(onEvent);
+    print('TextAreaElement');
+    var e = new TextAreaElement();
+    print('> onKeyPress');
+    e.onKeyPress.listen(onEvent);
+    print('> onClick');
+    e.onClick.listen(onEvent);
+    print('Done!');
+  } catch (e, s) {
+    print('$e\n$s');
+    Expect.fail("Unexpected exception: $e");
+  }
+}
+
+void onEvent(Event e) {
+  print(e);
+}
diff --git a/tests/lib/html/event_customevent_test.dart b/tests/lib/html/event_customevent_test.dart
new file mode 100644
index 0000000..f109a39
--- /dev/null
+++ b/tests/lib/html/event_customevent_test.dart
@@ -0,0 +1,83 @@
+// 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.
+
+library EventCustomEventTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+import 'dart:js' as js;
+
+class DartPayloadData {
+  final dartValue;
+
+  DartPayloadData(this.dartValue);
+}
+
+main() {
+  test('custom events', () {
+    var provider = new EventStreamProvider<CustomEvent>('foo');
+    var el = new DivElement();
+
+    var fired = false;
+    provider.forTarget(el).listen((ev) {
+      fired = true;
+      expect(ev.detail, {'type': 'detail'});
+    });
+
+    var ev = new CustomEvent('foo',
+        canBubble: false, cancelable: false, detail: {'type': 'detail'});
+    el.dispatchEvent(ev);
+    expect(fired, isTrue);
+  });
+
+  test('custom events from JS', () {
+    var scriptContents = '''
+      var event = document.createEvent("CustomEvent");
+      event.initCustomEvent("js_custom_event", true, true, {type: "detail"});
+      window.dispatchEvent(event);
+    ''';
+
+    var fired = false;
+    window.on['js_custom_event'].listen((ev) {
+      fired = true;
+      expect((ev as CustomEvent).detail, {'type': 'detail'});
+    });
+
+    var script = new ScriptElement();
+    script.text = scriptContents;
+    document.body!.append(script);
+
+    expect(fired, isTrue);
+  });
+
+  test('custom events to JS', () {
+    expect(js.context['gotDartEvent'], isNull);
+    var scriptContents = '''
+      window.addEventListener('dart_custom_event', function(e) {
+        if (e.detail == 'dart_message') {
+          e.preventDefault();
+          window.gotDartEvent = true;
+        }
+        window.console.log('here' + e.detail);
+      }, false);''';
+
+    document.body!.append(new ScriptElement()..text = scriptContents);
+
+    var event = new CustomEvent('dart_custom_event', detail: 'dart_message');
+    window.dispatchEvent(event);
+    expect(js.context['gotDartEvent'], isTrue);
+  });
+
+  test('custom data to Dart', () {
+    var data = new DartPayloadData(666);
+    var event = new CustomEvent('dart_custom_data_event', detail: data);
+
+    var future = window.on['dart_custom_data_event'].first.then((_) {
+      expect(event.detail.dartValue, 666);
+    });
+
+    document.body!.dispatchEvent(event);
+    return future;
+  });
+}
diff --git a/tests/lib/html/event_test.dart b/tests/lib/html/event_test.dart
new file mode 100644
index 0000000..8735137
--- /dev/null
+++ b/tests/lib/html/event_test.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+eventTest(String name, Event eventFn(), void validate(Event),
+    [String type = 'foo']) {
+  test(name, () {
+    final el = new Element.tag('div');
+    var fired = false;
+    el.on[type].listen((ev) {
+      fired = true;
+      validate(ev);
+    });
+    el.dispatchEvent(eventFn());
+    expect(fired, isTrue, reason: 'Expected event to be dispatched.');
+  });
+}
+
+main() {
+  // Issue 1005.
+  // eventTest('AnimationEvent', () => new AnimationEvent('foo', 'color', 0.5),
+  //     (ev) {
+  //   expect(ev.animationName, 'color');
+  //   expect(ev.elapsedTime, 0.5);
+  // });
+
+  // Issue 1005.
+  // eventTest('BeforeLoadEvent',
+  //    () => new BeforeLoadEvent('foo', 'http://example.url'),
+  //    (ev) { expect(ev.url, 'http://example.url'); });
+
+  // Issue 1005.
+  // eventTest('CloseEvent',
+  //     () => new CloseEvent('foo', 5, 'reason', wasClean: true),
+  //     (ev) {
+  //   expect(ev.code, 5);
+  //   expect(ev.reason, 'reason');
+  //   expect(ev.wasClean, isTrue);
+  // });
+
+  eventTest(
+      'CompositionEvent',
+      () =>
+          new CompositionEvent('compositionstart', view: window, data: 'data'),
+      (ev) {
+    expect(ev.data, 'data');
+  }, 'compositionstart');
+
+  // initCustomEvent is not yet implemented
+  // eventTest('CustomEvent',
+  //     () => new CustomEvent('foo', false, false, 'detail'),
+  //     (ev) { expect(ev.detail, 'detail'); });
+
+  // DeviceMotionEvent has no properties to itself, so just test that it doesn't
+  // error out on creation and can be dispatched.
+  // Suppress. DeviceMotion has no constructor, and I don't think it can be
+  // created on a non-mobile device. Issue 23321
+  // eventTest('DeviceMotionEvent', () => new DeviceMotionEvent('foo'), (ev) {});
+
+  // initDeviceOrientationEvent is not yet implemented
+  // eventTest('DeviceOrientationEvent',
+  //     () => new DeviceOrientationEvent('foo', 0.1, 0.2, 0.3),
+  //     (ev) {
+  //   expect(ev.alpha, 0.1);
+  //   expect(ev.beta, 0.2);
+  //   expect(ev.gamma, 0.3);
+  // });
+
+  // Issue 1005.
+  // eventTest('ErrorEvent',
+  //     () => new ErrorEvent('foo', 'message', 'filename', 10),
+  //     (ev) {
+  //   expect('message', ev.message);
+  //   expect('filename', ev.filename);
+  //   expect(ev.lineno, 10);
+  // });
+
+  eventTest(
+      'Event', () => new Event('foo', canBubble: false, cancelable: false),
+      (ev) {
+    expect(ev.type, equals('foo'));
+    expect(ev.bubbles, isFalse);
+    expect(ev.cancelable, isFalse);
+  });
+
+  eventTest(
+      'HashChangeEvent',
+      () => new HashChangeEvent('foo',
+          oldUrl: 'http://old.url', newUrl: 'http://new.url'), (ev) {
+    expect(ev.oldUrl, equals('http://old.url'));
+    expect(ev.newUrl, equals('http://new.url'));
+  });
+
+  // KeyboardEvent has its own test file, and has cross-browser issues.
+
+  eventTest(
+      'MouseEvent',
+      () => new MouseEvent('foo',
+          view: window,
+          detail: 1,
+          screenX: 2,
+          screenY: 3,
+          clientX: 4,
+          clientY: 5,
+          button: 6,
+          ctrlKey: true,
+          altKey: true,
+          shiftKey: true,
+          metaKey: true,
+          relatedTarget: document.body), (ev) {
+    expect(ev.detail, 1);
+    expect(ev.screen.x, 2);
+    expect(ev.screen.y, 3);
+    expect(ev.client.x, 4);
+    expect(ev.client.y, 5);
+    expect(ev.offset.x, 4); // Same as clientX.
+    expect(ev.offset.y, 5); // Same as clientY.
+    expect(ev.button, 6);
+    expect(ev.ctrlKey, isTrue);
+    expect(ev.altKey, isTrue);
+    expect(ev.shiftKey, isTrue);
+    expect(ev.metaKey, isTrue);
+    // TODO(alanknight): The target does not seem to get correctly set.
+    // Issue 23438
+    //  expect(ev.relatedTarget, document.body);
+  });
+
+  // Issue 1005.
+  // eventTest('OverflowEvent',
+  //     () => new OverflowEvent(OverflowEvent.BOTH, true, true),
+  //     (ev) {
+  //   expect(ev.orient, OverflowEvent.BOTH);
+  //   expect(ev.horizontalOverflow, isTrue);
+  //   expect(ev.verticalOverflow, isTrue);
+  // }, type: 'overflowchanged');
+
+  // Issue 1005.
+  // eventTest('PageTransitionEvent',
+  //     () => new PageTransitionEvent('foo', persisted: true),
+  //     (ev) { expect(ev.persisted, isTrue); });
+
+  // initPopStateEvent is not yet implemented
+  // eventTest('PopStateEvent', () => new PopStateEvent('foo', 'state'),
+  //     (ev) { expect(ev.state, 'state'); }
+
+  // Issue 1005.
+  // eventTest('ProgressEvent',
+  //     // canBubble and cancelable are currently required to avoid dartc
+  //     // complaining about the types of the named arguments.
+  //     () => new ProgressEvent('foo', 5, canBubble: true, cancelable: true,
+  //         lengthComputable: true, total: 10),
+  //     (ev) {
+  //   expect(ev.loaded, 5);
+  //   expect(ev.lengthComputable, isTrue);
+  //   expect(ev.total, 10);
+  // });
+
+  eventTest(
+      'StorageEvent',
+      () => new StorageEvent('foo',
+          key: 'key',
+          url: 'http://example.url',
+          storageArea: window.localStorage,
+          canBubble: true,
+          cancelable: true,
+          oldValue: 'old',
+          newValue: 'new'), (ev) {
+    expect(ev.key, 'key');
+    expect(ev.url, 'http://example.url');
+    // Equality isn't preserved for storageArea
+    expect(ev.storageArea, isNotNull);
+    expect(ev.oldValue, 'old');
+    expect(ev.newValue, 'new');
+  });
+
+  // Issue 1005.
+  // eventTest('TransitionEvent', () => new TransitionEvent('foo', 'color', 0.5),
+  //     (ev) {
+  //   expect(ev.propertyName, 'color');
+  //   expect(ev.elapsedTime, 0.5);
+  // });
+
+  eventTest('UIEvent', () => new UIEvent('foo', view: window, detail: 12),
+      (ev) {
+    expect(window, ev.view);
+    expect(12, ev.detail);
+  });
+
+  eventTest(
+      'WheelEvent',
+      // TODO(alanknight): Can't pass window on Dartium. Add view: window
+      // once going through JS.
+      () => new WheelEvent("mousewheel",
+          deltaX: 1,
+          deltaY: 0,
+          detail: 4,
+          screenX: 3,
+          screenY: 4,
+          clientX: 5,
+          clientY: 6,
+          ctrlKey: true,
+          altKey: true,
+          shiftKey: true,
+          metaKey: true), (ev) {
+    expect(ev.deltaX, 1);
+    expect(ev.deltaY, 0);
+    expect(ev.screen.x, 3);
+    expect(ev.screen.y, 4);
+    expect(ev.client.x, 5);
+    expect(ev.client.y, 6);
+    expect(ev.ctrlKey, isTrue);
+    expect(ev.altKey, isTrue);
+    expect(ev.shiftKey, isTrue);
+    expect(ev.metaKey, isTrue);
+  }, 'mousewheel');
+}
diff --git a/tests/lib/html/events_test.dart b/tests/lib/html/events_test.dart
new file mode 100644
index 0000000..c704b2a
--- /dev/null
+++ b/tests/lib/html/events_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library tests.html.events_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:async_helper/async_minitest.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  test('TimeStamp', () {
+    var event = new Event('test');
+
+    var timeStamp = event.timeStamp;
+    expect(timeStamp, greaterThan(0));
+  });
+
+  test('Event canBubble and cancelable', () {
+    // Try every combination of canBubble and cancelable
+    for (var i = 0; i < 4; i++) {
+      var bubble = (i & 1) != 0;
+      var cancel = (i & 2) != 0;
+      var e = new Event('input', canBubble: bubble, cancelable: cancel);
+      expect(e.bubbles, bubble, reason: 'canBubble was set to $bubble');
+      expect(e.cancelable, cancel, reason: 'cancelable was set to $cancel');
+    }
+  });
+
+  // The next test is not asynchronous because [on['test'].dispatch(event)] fires the event
+  // and event listener synchronously.
+  test('EventTarget', () {
+    var element = new Element.tag('test');
+    element.id = 'eventtarget';
+    document.body!.append(element);
+
+    var invocationCounter = 0;
+    void handler(Event e) {
+      expect(e.type, equals('test'));
+      var target = e.target;
+      expect(element, equals(target));
+      invocationCounter++;
+    }
+
+    var event = new Event('test');
+
+    invocationCounter = 0;
+    element.dispatchEvent(event);
+    expect(invocationCounter, 0);
+
+    var provider = new EventStreamProvider<Event>('test');
+
+    var sub = provider.forTarget(element).listen(handler);
+    invocationCounter = 0;
+    element.dispatchEvent(event);
+    expect(invocationCounter, 1);
+
+    sub.cancel();
+    invocationCounter = 0;
+    element.dispatchEvent(event);
+    expect(invocationCounter, 0);
+
+    provider.forTarget(element).listen(handler);
+    invocationCounter = 0;
+    element.dispatchEvent(event);
+    expect(invocationCounter, 1);
+
+    provider.forTarget(element).listen(handler);
+    invocationCounter = 0;
+    element.dispatchEvent(event);
+
+    // NOTE: when run in a custom zone, the handler is wrapped
+    // The logic for html events which ensures identical handlers are added only
+    // once is therefor muted by the wrapped handlers.
+    // Hence, we get different behavior depending on the current zone.
+    if (Zone.current == Zone.root) {
+      expect(invocationCounter, 1);
+    } else {
+      expect(invocationCounter, 2);
+    }
+  });
+
+  test('InitMouseEvent', () {
+    var div = new Element.tag('div');
+    var event = new MouseEvent('zebra', relatedTarget: div);
+  });
+
+  test('DOM event callbacks are associated with the correct zone', () {
+    var callbacks = [];
+
+    var element = new Element.tag('test');
+    element.id = 'eventtarget';
+    document.body!.append(element);
+
+    // runZoned executes the function synchronously, but we don't want to
+    // rely on this. We therefore wrap it into an expectAsync.
+    runZoned(expectAsync0(() {
+      var zone = Zone.current;
+      Expect.notEquals(zone, Zone.root);
+
+      StreamSubscription<Event>? sub;
+
+      void handler(Event e) {
+        expect(Zone.current, equals(zone));
+
+        scheduleMicrotask(expectAsync0(() {
+          expect(Zone.current, equals(zone));
+          sub!.cancel();
+        }));
+      }
+
+      sub = element.on['test'].listen(expectAsync1(handler));
+    }));
+    element.dispatchEvent(new Event('test'));
+  });
+}
diff --git a/tests/lib/html/exceptions_test.dart b/tests/lib/html/exceptions_test.dart
new file mode 100644
index 0000000..7d937ba
--- /dev/null
+++ b/tests/lib/html/exceptions_test.dart
@@ -0,0 +1,19 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('EventException', () {
+    final event = new Event('Event');
+    // Intentionally do not initialize it!
+    try {
+      document.dispatchEvent(event);
+    } on DomException catch (e) {
+      expect(e.name, DomException.INVALID_STATE);
+    }
+  });
+}
diff --git a/tests/lib/html/file_sample_test.dart b/tests/lib/html/file_sample_test.dart
new file mode 100644
index 0000000..15d36f4
--- /dev/null
+++ b/tests/lib/html/file_sample_test.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library file_sample;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/minitest.dart';
+
+// Expected output from all functions, asynchronous, and event routines.
+const String log_results = 'test-first\n' +
+    'acquire START\n' +
+    'acquire CALLBACK START\n' +
+    'acquire CALLBACK END\n' +
+    'first START\n' +
+    'first END\n' +
+    'test-second\n' +
+    'second START\n' +
+    'second END\n' +
+    'reader onLoadEnd event\n' +
+    'file content = XYZZY Output\n';
+
+// Simple logger to record all output.
+class Logger {
+  StringBuffer _log = new StringBuffer();
+
+  void log(String message) {
+    _log.writeln(message);
+  }
+
+  String get contents => _log.toString();
+}
+
+Logger testLog = new Logger();
+
+Future<FileSystem>? _fileSystem;
+
+late DirectoryEntry _myDirectory;
+
+Future<FileSystem> get fileSystem async {
+  if (_fileSystem != null) return _fileSystem!;
+
+  testLog.log('acquire START');
+  _fileSystem = window.requestFileSystem(100);
+
+  var fs = await _fileSystem!;
+  testLog.log('acquire CALLBACK START');
+  expect(fs.runtimeType, FileSystem);
+  expect(fs.root.runtimeType, DirectoryEntry);
+  testLog.log('acquire CALLBACK END');
+
+  return _fileSystem!;
+}
+
+Future<FileEntry> createFile() async {
+  var fs = await fileSystem;
+
+  _myDirectory =
+      await fs.root.createDirectory('my_directory') as DirectoryEntry;
+
+  FileEntry fileEntry = await _myDirectory.createFile('log.txt') as FileEntry;
+
+  expect(fileEntry.isFile, true);
+  expect(fileEntry.name, 'log.txt');
+  expect(fileEntry.fullPath, '/my_directory/log.txt');
+
+  FileWriter writer = await fileEntry.createWriter();
+
+  Blob blob = new Blob(['XYZZY Output'], 'text/plain');
+
+  writer.write(blob);
+
+  var reader = new FileReader();
+
+  var completer = new Completer<String>();
+
+  reader.onLoadEnd.listen((event) {
+    testLog.log('reader onLoadEnd event');
+    dynamic target = event.currentTarget;
+    testLog.log('file content = ${target.result}');
+    expect(target.result, 'XYZZY Output');
+
+    completer.complete(target.result);
+  });
+
+  Blob readBlob = await fileEntry.file();
+
+  reader.readAsText(readBlob);
+
+  // Wait until onLoadEnd if fired.
+  await completer.future;
+
+  return new Future<FileEntry>.value(fileEntry);
+}
+
+Future<List<Entry>> readEntries(DirectoryEntry directory) async {
+  DirectoryReader reader = directory.createReader();
+  List<Entry> entries = await reader.readEntries();
+  return entries;
+}
+
+Future testFileSystemRequest() async {
+  testLog.log('test-first');
+  var fs = await fileSystem;
+  testLog.log('first START');
+  expect(fs.runtimeType, FileSystem);
+  expect(fs.root.runtimeType, DirectoryEntry);
+  testLog.log('first END');
+}
+
+Future testFileSystemRequestCreateRW() async {
+  testLog.log('test-second');
+  var fs = await fileSystem;
+  testLog.log('second START');
+  expect(fs.runtimeType, FileSystem);
+  expect(fs.root.runtimeType, DirectoryEntry);
+  testLog.log('second END');
+
+  FileEntry fileEntry = await createFile();
+  expect(fileEntry.name, 'log.txt');
+
+  List<Entry> entries = await readEntries(fs.root);
+  expect(entries.length > 0, true);
+  expect(entries[0].isDirectory, true);
+  expect(entries[0].name, 'my_directory');
+
+  List<Entry> myEntries = await readEntries(_myDirectory);
+  expect(myEntries.length, 1);
+  expect(myEntries[0].isFile, true);
+  expect(myEntries[0].name, 'log.txt');
+
+  // Validate every function, async and event mechanism successfully ran.
+  expect(testLog.contents, log_results);
+}
+
+main() {
+  asyncTest(() async {
+    await testFileSystemRequest();
+    await testFileSystemRequestCreateRW();
+  });
+}
diff --git a/tests/lib/html/fileapi_directory_reader_test.dart b/tests/lib/html/fileapi_directory_reader_test.dart
new file mode 100644
index 0000000..7468759
--- /dev/null
+++ b/tests/lib/html/fileapi_directory_reader_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+class FileAndDir {
+  FileEntry file;
+  DirectoryEntry dir;
+  FileAndDir(this.file, this.dir);
+}
+
+late FileSystem fs;
+
+main() async {
+  getFileSystem() async {
+    fs = await window.requestFileSystem(100);
+  }
+
+  // Do the boilerplate to get several files and directories created to then
+  // test the functions that use those items.
+  Future doDirSetup(String testName) async {
+    await getFileSystem();
+
+    var file = await fs.root.createFile('file_$testName') as FileEntry;
+    var dir = await fs.root.createDirectory('dir_$testName') as DirectoryEntry;
+    return new Future.value(new FileAndDir(file, dir));
+  }
+
+  if (FileSystem.supported) {
+    test('readEntries', () async {
+      var fileAndDir = await doDirSetup('readEntries');
+      var reader = await fileAndDir.dir.createReader();
+      var entries = await reader.readEntries();
+      expect(entries is List, true);
+    });
+  }
+}
diff --git a/tests/lib/html/fileapi_directory_test.dart b/tests/lib/html/fileapi_directory_test.dart
new file mode 100644
index 0000000..b2c7945
--- /dev/null
+++ b/tests/lib/html/fileapi_directory_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+class FileAndDir {
+  FileEntry file;
+  DirectoryEntry dir;
+  FileAndDir(this.file, this.dir);
+}
+
+late FileSystem fs;
+
+main() async {
+  getFileSystem() async {
+    fs = await window.requestFileSystem(100);
+  }
+
+  if (FileSystem.supported) {
+    await getFileSystem();
+
+    test('directoryDoesntExist', () async {
+      try {
+        await fs.root.getDirectory('directory2');
+      } catch (error) {
+        expect(true, error is DomException);
+        expect(DomException.NOT_FOUND, error.name);
+      }
+    });
+
+    test('directoryCreate', () async {
+      var entry = await fs.root.createDirectory('directory3');
+      expect(entry.name, equals('directory3'));
+    });
+  }
+}
diff --git a/tests/lib/html/fileapi_entry_test.dart b/tests/lib/html/fileapi_entry_test.dart
new file mode 100644
index 0000000..7669fc8
--- /dev/null
+++ b/tests/lib/html/fileapi_entry_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+class FileAndDir {
+  FileEntry file;
+  DirectoryEntry dir;
+  FileAndDir(this.file, this.dir);
+}
+
+late FileSystem fs;
+
+main() async {
+  getFileSystem() async {
+    return await window.requestFileSystem(100).then((FileSystem fileSystem) {
+      fs = fileSystem;
+    });
+  }
+
+  // Do the boilerplate to get several files and directories created to then
+  // test the functions that use those items.
+  Future doDirSetup(String testName) async {
+    await getFileSystem();
+
+    var file = await fs.root.createFile('file_$testName') as FileEntry;
+    var dir = await fs.root.createDirectory('dir_$testName') as DirectoryEntry;
+    return new Future.value(new FileAndDir(file, dir));
+  }
+
+  if (FileSystem.supported) {
+    test('copy_move', () async {
+      var fileAndDir = await doDirSetup('copyTo');
+      var entry =
+          await fileAndDir.file.copyTo(fileAndDir.dir, name: 'copiedFile');
+      expect(entry.isFile, true, reason: "Expected File");
+      expect(entry.name, 'copiedFile');
+
+      // getParent
+      fileAndDir = await doDirSetup('getParent');
+      entry = await fileAndDir.file.getParent();
+      expect(entry.name, '');
+      expect(entry.isDirectory, true, reason: "Expected Directory");
+
+      // moveTo
+      fileAndDir = await doDirSetup('moveTo');
+      entry = await fileAndDir.file.moveTo(fileAndDir.dir, name: 'movedFile');
+      expect(entry.name, 'movedFile');
+      expect(entry.fullPath, '/dir_moveTo/movedFile');
+
+      try {
+        entry = await fs.root.getFile('file4');
+        fail("File file4 should not exist.");
+      } catch (error) {
+        expect(error is DomException, true,
+            reason: "Not DomException - not exist");
+        expect(DomException.NOT_FOUND, error.name);
+      }
+
+      // remove
+      fileAndDir = await doDirSetup('remove');
+      expect('file_remove', fileAndDir.file.name);
+      await fileAndDir.file.remove();
+      try {
+        var entry = await fileAndDir.dir.getFile(fileAndDir.file.name);
+        fail("file not removed");
+      } catch (error) {
+        expect(error is DomException, true,
+            reason: "Not DomException - removed");
+        expect(DomException.NOT_FOUND, error.name);
+      }
+    });
+  }
+}
diff --git a/tests/lib/html/fileapi_file_entry_test.dart b/tests/lib/html/fileapi_file_entry_test.dart
new file mode 100644
index 0000000..1789003
--- /dev/null
+++ b/tests/lib/html/fileapi_file_entry_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+class FileAndDir {
+  FileEntry file;
+  DirectoryEntry dir;
+  FileAndDir(this.file, this.dir);
+}
+
+late FileSystem fs;
+
+main() async {
+  getFileSystem() async {
+    fs = await window.requestFileSystem(100);
+  }
+
+  // Do the boilerplate to get several files and directories created to then
+  // test the functions that use those items.
+  Future doDirSetup(String testName) async {
+    await getFileSystem();
+
+    var file = await fs.root.createFile('file_$testName') as FileEntry;
+    var dir = await fs.root.createDirectory('dir_$testName') as DirectoryEntry;
+    return new Future.value(new FileAndDir(file, dir));
+  }
+
+  if (FileSystem.supported) {
+    test('createWriter', () async {
+      var fileAndDir = await doDirSetup('createWriter');
+      var writer = await fileAndDir.file.createWriter();
+      expect(writer.position, 0);
+      expect(writer.readyState, FileWriter.INIT);
+      expect(writer.length, 0);
+    });
+
+    test('file', () async {
+      var fileAndDir = await doDirSetup('file');
+      var fileObj = await fileAndDir.file.file();
+      expect(fileObj.name, fileAndDir.file.name);
+      expect(fileObj.relativePath, '');
+      expect(
+          new DateTime.now().difference(fileObj.lastModifiedDate).inMinutes <
+              30,
+          isTrue);
+    });
+  }
+}
diff --git a/tests/lib/html/fileapi_file_test.dart b/tests/lib/html/fileapi_file_test.dart
new file mode 100644
index 0000000..f70bb13
--- /dev/null
+++ b/tests/lib/html/fileapi_file_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+class FileAndDir {
+  FileEntry file;
+  DirectoryEntry dir;
+  FileAndDir(this.file, this.dir);
+}
+
+late FileSystem fs;
+
+main() async {
+  getFileSystem() async {
+    fs = await window.requestFileSystem(100);
+  }
+
+  if (FileSystem.supported) {
+    await getFileSystem();
+
+    test('fileDoesntExist', () async {
+      try {
+        var fileObj = await fs.root.getFile('file2');
+        fail("file found");
+      } catch (error) {
+        expect(true, error is DomException);
+        expect(DomException.NOT_FOUND, error.name);
+      }
+    });
+
+    test('fileCreate', () async {
+      var fileObj = await fs.root.createFile('file4');
+      expect(fileObj.name, equals('file4'));
+      expect(fileObj.isFile, isTrue);
+
+      var metadata = await fileObj.getMetadata();
+      var changeTime = metadata.modificationTime;
+
+      // Increased Windows buildbots can sometimes be particularly slow.
+      expect(new DateTime.now().difference(changeTime).inMinutes < 4, isTrue);
+      expect(metadata.size, equals(0));
+    });
+  }
+}
diff --git a/tests/lib/html/fileapi_supported_test.dart b/tests/lib/html/fileapi_supported_test.dart
new file mode 100644
index 0000000..75fe3b8
--- /dev/null
+++ b/tests/lib/html/fileapi_supported_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+Future<FileSystem>? _fileSystem;
+
+Future<FileSystem> get fileSystem async {
+  if (_fileSystem != null) return _fileSystem!;
+
+  _fileSystem = window.requestFileSystem(100);
+
+  var fs = await _fileSystem!;
+  expect(fs.runtimeType, FileSystem);
+  expect(fs.root.runtimeType, DirectoryEntry);
+
+  return _fileSystem!;
+}
+
+main() {
+  test('supported', () {
+    expect(FileSystem.supported, true);
+  });
+
+  test('requestFileSystem', () async {
+    var expectation = FileSystem.supported ? returnsNormally : throws;
+    expect(() async {
+      var fs = await fileSystem;
+    }, expectation);
+  });
+}
diff --git a/tests/lib/html/fileapi_supported_throws_test.dart b/tests/lib/html/fileapi_supported_throws_test.dart
new file mode 100644
index 0000000..9367451
--- /dev/null
+++ b/tests/lib/html/fileapi_supported_throws_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fileapi;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  test('requestFileSystem', () async {
+    var expectation = FileSystem.supported ? returnsNormally : throws;
+    expect(() async {
+      await window.requestFileSystem(100);
+    }, expectation);
+  });
+}
diff --git a/tests/lib/html/filereader_test.dart b/tests/lib/html/filereader_test.dart
new file mode 100644
index 0000000..6f58706
--- /dev/null
+++ b/tests/lib/html/filereader_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library filereader_test;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+import 'dart:typed_data';
+
+main() {
+  test('readAsText', () {
+    var reader = new FileReader();
+    reader.onLoad.listen(expectAsync((event) {
+      var result = reader.result;
+      expect(result, equals('hello world'));
+    }));
+    reader.readAsText(new Blob(['hello ', 'world']));
+  });
+
+  test('readAsArrayBuffer', () {
+    var reader = new FileReader();
+    reader.onLoad.listen(expectAsync((event) {
+      var result = reader.result;
+      expect(result is Uint8List, isTrue);
+      expect(result, equals([65, 66, 67]));
+    }));
+    reader.readAsArrayBuffer(new Blob(['ABC']));
+  });
+
+  test('readDataUrl', () {
+    var reader = new FileReader();
+    reader.onLoad.listen(expectAsync((event) {
+      String result = reader.result as String;
+      expect(result.startsWith('data:'), isTrue);
+    }));
+    reader.readAsDataUrl(new Blob(['ABC']));
+  });
+}
diff --git a/tests/lib/html/filteredelementlist_test.dart b/tests/lib/html/filteredelementlist_test.dart
new file mode 100644
index 0000000..247c4e8
--- /dev/null
+++ b/tests/lib/html/filteredelementlist_test.dart
@@ -0,0 +1,108 @@
+// 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:html';
+import 'dart:html_common';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var t1 = new Text('T1'),
+      t2 = new Text('T2'),
+      t3 = new Text('T3'),
+      t4 = new Text('T4');
+
+  var d1 = new DivElement(), d2 = new DivElement(), d3 = new DivElement();
+
+  createTestDiv() {
+    var testDiv = new DivElement();
+    testDiv
+      ..append(t1)
+      ..append(d1)
+      ..append(t2)
+      ..append(d2)
+      ..append(t3)
+      ..append(d3)
+      ..append(t4);
+    return testDiv;
+  }
+
+  test('FilteredElementList.insert test', () {
+    var i = new DivElement();
+
+    // Insert before first element
+    var nodeList = createTestDiv();
+    var elementList = new FilteredElementList(nodeList);
+    elementList.insert(0, i);
+    expect(nodeList.childNodes[0], t1);
+    expect(nodeList.childNodes[1], i);
+    expect(nodeList.childNodes[2], d1);
+
+    // Insert in middle
+    nodeList = createTestDiv();
+    elementList = new FilteredElementList(nodeList);
+    elementList.insert(1, i);
+    expect(nodeList.childNodes[2], t2);
+    expect(nodeList.childNodes[3], i);
+    expect(nodeList.childNodes[4], d2);
+
+    // Insert before last element
+    nodeList = createTestDiv();
+    elementList = new FilteredElementList(nodeList);
+    elementList.insert(2, i);
+    expect(nodeList.childNodes[4], t3);
+    expect(nodeList.childNodes[5], i);
+    expect(nodeList.childNodes[6], d3);
+  });
+
+  test('FilteredElementList.insertAll test', () {
+    var i1 = new DivElement(), i2 = new DivElement();
+
+    var it = [i1, i2];
+
+    // Insert before first element
+    var nodeList = createTestDiv();
+    var elementList = new FilteredElementList(nodeList);
+    elementList.insertAll(0, it);
+    expect(nodeList.childNodes[0], t1);
+    expect(nodeList.childNodes[1], i1);
+    expect(nodeList.childNodes[2], i2);
+    expect(nodeList.childNodes[3], d1);
+
+    // Insert in middle
+    nodeList = createTestDiv();
+    elementList = new FilteredElementList(nodeList);
+    elementList.insertAll(1, it);
+    expect(nodeList.childNodes[2], t2);
+    expect(nodeList.childNodes[3], i1);
+    expect(nodeList.childNodes[4], i2);
+    expect(nodeList.childNodes[5], d2);
+
+    // Insert before last element
+    nodeList = createTestDiv();
+    elementList = new FilteredElementList(nodeList);
+    elementList.insertAll(2, it);
+    expect(nodeList.childNodes[4], t3);
+    expect(nodeList.childNodes[5], i1);
+    expect(nodeList.childNodes[6], i2);
+    expect(nodeList.childNodes[7], d3);
+  });
+
+  test('FilteredElementList.insertAndRemove', () {
+    var emptyDiv = new DivElement();
+    var elementList = new FilteredElementList(emptyDiv);
+    expect(() => elementList[0], throwsRangeError);
+    expect(() => elementList.insert(2, new BRElement()), throwsRangeError);
+    var br = new BRElement();
+    elementList.insert(0, br);
+    expect(elementList.removeLast(), br);
+    elementList.add(br);
+    expect(elementList.remove(br), isTrue);
+    var br2 = new BRElement();
+    elementList.add(br);
+    expect(elementList.remove(br2), isFalse);
+    expect(elementList[0], br);
+    expect(() => elementList[1], throwsRangeError);
+  });
+}
diff --git a/tests/lib/html/fontface_loaded_test.dart b/tests/lib/html/fontface_loaded_test.dart
new file mode 100644
index 0000000..ef07061
--- /dev/null
+++ b/tests/lib/html/fontface_loaded_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fontface_loaded_test;
+
+import 'package:async_helper/async_minitest.dart';
+
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:html';
+
+class NullTreeSanitizer implements NodeTreeSanitizer {
+  void sanitizeTree(Node node) {}
+}
+
+main() {
+  var style = new Element.html('''
+      <style>
+      @font-face {
+        font-family: 'Ahem';
+        src: url(/root_dart/tests/lib/html/Ahem.ttf);
+        font-style: italic;
+        font-weight: 300;
+        unicode-range: U+0-3FF;
+        font-variant: small-caps;
+        -webkit-font-feature-settings: "dlig" 1;
+        /* font-stretch property is not supported */
+      }
+      </style>
+      ''', treeSanitizer: new NullTreeSanitizer());
+  document.head!.append(style);
+
+  test('document fonts - temporary', () async {
+    var atLeastOneFont = false;
+    var loaded = <Future<FontFace>>[];
+    document.fonts.forEach((FontFace fontFace, _, __) async {
+      atLeastOneFont = true;
+      var f1 = fontFace.loaded;
+      var f2 = fontFace.loaded;
+      loaded.add(fontFace.load());
+      loaded.add(f1);
+      loaded.add(f2);
+    });
+    expect(atLeastOneFont, isTrue);
+    return Future.wait(loaded).then(expectAsync((_) async {
+      document.fonts.forEach((fontFace, _, __) {
+        expect(fontFace.status, 'loaded');
+      });
+      expect(loaded.length, 3);
+      for (var loadedEntry in loaded) {
+        var fontFace = await loadedEntry;
+        expect(fontFace.status, 'loaded');
+        var fontFamily = fontFace.family;
+        if (fontFamily.startsWith('"')) {
+          // FF wraps family in quotes - remove the quotes.
+          fontFamily = fontFamily.substring(1, fontFamily.length - 1);
+        }
+        expect(fontFamily, 'Ahem');
+      }
+    }));
+  });
+}
diff --git a/tests/lib/html/fontface_test.dart b/tests/lib/html/fontface_test.dart
new file mode 100644
index 0000000..a663def
--- /dev/null
+++ b/tests/lib/html/fontface_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test("Creation with parameters", () {
+    var font = new FontFace('Ahem', 'url(Ahem.ttf)', {'variant': 'small-caps'});
+    expect(font is FontFace, isTrue);
+    expect(font.family, 'Ahem');
+    expect(font.variant, 'small-caps');
+  });
+}
diff --git a/tests/lib/html/form_data_test.dart b/tests/lib/html/form_data_test.dart
new file mode 100644
index 0000000..03592e2
--- /dev/null
+++ b/tests/lib/html/form_data_test.dart
@@ -0,0 +1,80 @@
+// 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.
+
+library FormDataTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+
+void main() {
+  // TODO(efortuna): This is a bad test. Revisit when we have tests that can run
+  // both a server and fire up a browser.
+  group('supported', () {
+    test('supported', () {
+      expect(FormData.supported, isTrue);
+    });
+  });
+
+  group('functional', () {
+    test('unsupported throws', () {
+      var expectation = FormData.supported ? returnsNormally : throws;
+      expect(() {
+        new FormData();
+      }, expectation);
+    });
+
+    var isFormData = predicate((x) => x is FormData, 'is a FormData');
+
+    if (FormData.supported) {
+      test('constructorTest1', () {
+        var form = new FormData();
+        expect(form, isNotNull);
+        expect(form, isFormData);
+      });
+
+      test('constructorTest2', () {
+        var form = new FormData(new FormElement());
+        expect(form, isNotNull);
+        expect(form, isFormData);
+      });
+
+      test('appendTest', () {
+        var form = new FormData();
+        form.append('test', '1');
+        form.append('username', 'Elmo');
+        form.append('address', '1 Sesame Street');
+        form.append('password', '123456');
+        expect(form, isNotNull);
+      });
+
+      test('appendBlob', () {
+        var form = new FormData();
+        var blob = new Blob(
+            ['Indescribable... Indestructible! Nothing can stop it!'],
+            'text/plain');
+        form.appendBlob('theBlob', blob, 'theBlob.txt');
+      });
+
+      test('send', () {
+        var form = new FormData();
+        var blobString =
+            'Indescribable... Indestructible! Nothing can stop it!';
+        var blob = new Blob([blobString], 'text/plain');
+        form.appendBlob('theBlob', blob, 'theBlob.txt');
+
+        var xhr = new HttpRequest();
+        xhr.open('POST',
+            '${window.location.protocol}//${window.location.host}/echo');
+
+        xhr.onLoad.listen(expectAsync((e) {
+          expect(xhr.responseText.contains(blobString), isTrue);
+        }));
+        xhr.onError.listen((e) {
+          fail('$e');
+        });
+        xhr.send(form);
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/form_element_test.dart b/tests/lib/html/form_element_test.dart
new file mode 100644
index 0000000..4cc6807f
--- /dev/null
+++ b/tests/lib/html/form_element_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+void main() {
+  var isFormElement = predicate((x) => x is FormElement, 'is a FormElement');
+
+  test('constructorTest1', () {
+    var form = new FormElement();
+    expect(form, isNotNull);
+    expect(form, isFormElement);
+  });
+
+  test('checkValidityTest', () {
+    var form = new FormElement();
+    form.innerHtml = '<label>Google: <input type="search" name="q"></label> '
+        '<input type="submit" value="Search...">';
+    expect(form.checkValidity(), isTrue);
+    // TODO(efortuna): Issue 4832.
+    form.innerHtml = '<input type="email" value="notemail" blaber="test"'
+        ' required>';
+    expect(form.checkValidity(), isFalse);
+  });
+
+  var form = new FormElement();
+  test('acceptCharsetTest', () {
+    var charset = 'abc';
+    form.acceptCharset = charset;
+    expect(form.acceptCharset, charset);
+  });
+
+  test('actionTest', () {
+    var action = 'http://dartlang.org/';
+    form.action = action;
+    expect(form.action, action);
+  });
+
+  test('autocompleteTest', () {
+    var auto = 'on';
+    form.autocomplete = auto;
+    expect(form.autocomplete, auto);
+  });
+
+  test('encodingAndEnctypeTest', () {
+    expect(form.enctype, form.encoding);
+  });
+
+  test('lengthTest', () {
+    expect(form.length, 0);
+    form.innerHtml = '<label>Google: <input type="search" name="q"></label> '
+        '<input type="submit" value="Search...">';
+    expect(form.length, 2);
+  });
+
+  test('methodTest', () {
+    var method = 'post';
+    form.method = method;
+    expect(form.method, method);
+  });
+
+  test('nameTest', () {
+    var name = 'aname';
+    form.name = name;
+    expect(form.name, name);
+  });
+
+  test('noValidateTest', () {
+    form.noValidate = true;
+    expect(form.noValidate, true);
+  });
+
+  test('targetTest', () {
+    var target = 'target';
+    form.target = target;
+    expect(form.target, target);
+  });
+}
diff --git a/tests/lib/html/gamepad_test.dart b/tests/lib/html/gamepad_test.dart
new file mode 100644
index 0000000..35c2764
--- /dev/null
+++ b/tests/lib/html/gamepad_test.dart
@@ -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 file.
+
+import 'package:expect/minitest.dart';
+import 'dart:html';
+
+main() {
+  var isGamepadList =
+      predicate((x) => x is List<Gamepad?>, 'is a List<Gamepad?>');
+
+  insertTestDiv() {
+    var element = new Element.tag('div');
+    element.innerHtml = r'''
+    A large block of text should go here. Click this
+    block of text multiple times to see each line
+    highlight with every click of the mouse button.
+    ''';
+    document.body!.append(element);
+    return element;
+  }
+
+  test("getGamepads", () {
+    insertTestDiv();
+    var gamepads = window.navigator.getGamepads();
+    expect(gamepads, isGamepadList);
+    for (var gamepad in gamepads) {
+      if (gamepad != null) {
+        expect(gamepad.id, isNotNull);
+      }
+    }
+  });
+}
diff --git a/tests/lib/html/geolocation_test.dart b/tests/lib/html/geolocation_test.dart
new file mode 100644
index 0000000..30d24dc
--- /dev/null
+++ b/tests/lib/html/geolocation_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Actual tests require browser interaction. This just makes sure the API
+  // is present.
+  test('is not null', () {
+    expect(window.navigator.geolocation, isNotNull);
+  });
+}
diff --git a/tests/lib/html/hidden_dom_1_test.dart b/tests/lib/html/hidden_dom_1_test.dart
new file mode 100644
index 0000000..8c4f892
--- /dev/null
+++ b/tests/lib/html/hidden_dom_1_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+// Test that the dart:html API does not leak native jsdom methods:
+//   onfocus setter.
+
+main() {
+  test('test1', () {
+    document.body!.children.add(new Element.html(r'''
+<div id='div1'>
+Hello World!
+</div>'''));
+    Element? e = document.querySelector('#div1');
+    expect(e, isNotNull);
+
+    expect(() {
+      confuse(e!).onfocus = null;
+    }, throwsNoSuchMethodError);
+  });
+}
+
+class Decoy {
+  void set onfocus(x) {
+    throw 'dead code';
+  }
+}
+
+confuse(x) => opaqueTrue() ? x : (opaqueTrue() ? new Object() : new Decoy());
+
+/** Returns `true`, but in a way that confuses the compiler. */
+opaqueTrue() => true; // Expand as needed.
diff --git a/tests/lib/html/hidden_dom_2_test.dart b/tests/lib/html/hidden_dom_2_test.dart
new file mode 100644
index 0000000..163de35
--- /dev/null
+++ b/tests/lib/html/hidden_dom_2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+// Test that the dart:html API does not leak native jsdom methods:
+//   appendChild operation.
+
+main() {
+  test('test1', () {
+    document.body!.children.add(new Element.html(r'''
+<div id='div1'>
+Hello World!
+</div>'''));
+    Element? e = document.querySelector('#div1');
+    Element e2 = new Element.html(r"<div id='xx'>XX</div>");
+    expect(e, isNotNull);
+
+    expect(() {
+      confuse(e!).appendChild(e2);
+    }, throwsNoSuchMethodError);
+  });
+}
+
+class Decoy {
+  void appendChild(x) {
+    throw 'dead code';
+  }
+}
+
+confuse(x) => opaqueTrue() ? x : (opaqueTrue() ? new Object() : new Decoy());
+
+/** Returns `true`, but in a way that confuses the compiler. */
+opaqueTrue() => true; // Expand as needed.
diff --git a/tests/lib/html/history_hash_change_test.dart b/tests/lib/html/history_hash_change_test.dart
new file mode 100644
index 0000000..d2d2ccb
--- /dev/null
+++ b/tests/lib/html/history_hash_change_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library HistoryTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+import 'dart:async';
+
+main() {
+  test('supported', () {
+    expect(HashChangeEvent.supported, true);
+  });
+}
diff --git a/tests/lib/html/history_supported_test.dart b/tests/lib/html/history_supported_test.dart
new file mode 100644
index 0000000..779e2a3
--- /dev/null
+++ b/tests/lib/html/history_supported_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library HistoryTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+import 'dart:async';
+
+main() {
+  test('supports_state', () {
+    expect(History.supportsState, true);
+  });
+
+  test('supported_HashChangeEvent', () {
+    expect(HashChangeEvent.supported, true);
+  });
+}
diff --git a/tests/lib/html/history_test.dart b/tests/lib/html/history_test.dart
new file mode 100644
index 0000000..100b220
--- /dev/null
+++ b/tests/lib/html/history_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library HistoryTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+import 'dart:async';
+
+main() {
+  var expectation = History.supportsState ? returnsNormally : throws;
+
+  test('pushState', () {
+    expect(() {
+      window.history.pushState(null, document.title, '?dummy');
+      var length = window.history.length;
+
+      window.history.pushState(null, document.title, '?foo=bar');
+
+      expect(window.location.href.endsWith('foo=bar'), isTrue);
+    }, expectation);
+  });
+
+  test('pushState with data', () {
+    expect(() {
+      window.history.pushState({'one': 1}, document.title, '?dummy');
+      expect(window.history.state, equals({'one': 1}));
+      window.history.pushState(null, document.title, '?foo=bar');
+
+      expect(window.location.href.endsWith('foo=bar'), isTrue);
+    }, expectation);
+  });
+
+  test('back', () {
+    expect(() {
+      window.history.pushState(null, document.title, '?dummy1');
+      window.history.pushState(null, document.title, '?dummy2');
+      var length = window.history.length;
+
+      expect(window.location.href.endsWith('dummy2'), isTrue);
+
+      // Need to wait a frame or two to let the pushState events occur.
+      new Timer(const Duration(milliseconds: 100), expectAsync(() {
+        window.onPopState.first.then(expectAsync((_) {
+          expect(window.history.length, length);
+          expect(window.location.href.endsWith('dummy1'), isTrue);
+        }));
+
+        window.history.back();
+      }));
+    }, expectation);
+  });
+
+  test('replaceState', () {
+    expect(() {
+      var length = window.history.length;
+
+      window.history.replaceState(null, document.title, '?foo=baz');
+      expect(window.history.length, length);
+      expect(window.location.href.endsWith('foo=baz'), isTrue);
+    }, expectation);
+  });
+
+  test('popstatevent', () {
+    expect(() {
+      var event = new Event.eventType('PopStateEvent', 'popstate');
+      expect(event is PopStateEvent, true);
+    }, expectation);
+  });
+
+  test('hashchangeevent', () {
+    var expectation = HashChangeEvent.supported ? returnsNormally : throws;
+    expect(() {
+      var event = new HashChangeEvent('change', oldUrl: 'old', newUrl: 'new');
+      expect(event is HashChangeEvent, true);
+      expect(event.oldUrl, 'old');
+      expect(event.newUrl, 'new');
+    }, expectation);
+  });
+}
diff --git a/tests/lib/html/html_mock_test.dart b/tests/lib/html/html_mock_test.dart
new file mode 100644
index 0000000..94c016d
--- /dev/null
+++ b/tests/lib/html/html_mock_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+class Mock {
+  noSuchMethod(Invocation i) {
+    if (this is Window) return document;
+    if (this is FileList) return new MockFile();
+    return null;
+  }
+}
+
+@proxy
+class MockBodyElement extends Mock implements BodyElement {
+  Node append(Node e) => e;
+}
+
+class _EventListeners {
+  Stream<Event> get onBlur => new Stream.fromIterable([]);
+}
+
+@proxy
+class MockHtmlDocument extends Mock
+    with _EventListeners
+    implements HtmlDocument {
+  BodyElement get body => new MockBodyElement();
+}
+
+@proxy
+class MockWindow extends Mock with _EventListeners implements Window {
+  Stream<Event> get onBeforeUnload => new Stream.fromIterable([]);
+
+  String name = "MOCK_NAME";
+}
+
+@proxy
+class MockLocation extends Mock implements Location {
+  String href = "MOCK_HREF";
+}
+
+@proxy
+class MockFileList extends Mock implements FileList {}
+
+@proxy
+class MockFile extends Mock implements File {}
+
+main() {
+  test('is', () {
+    var win = new MockWindow();
+    expect(win is Window, isTrue);
+  });
+
+  test('getter', () {
+    var win = new MockWindow();
+    expect(win.document, equals(document));
+  });
+
+  test('override', () {
+    Window win = new MockWindow();
+    expect(win.name, equals("MOCK_NAME"));
+  });
+
+  test('override', () {
+    var loc1 = new MockLocation();
+    Location loc2 = loc1;
+    dynamic loc3 = loc1;
+    expect(loc1.href, equals("MOCK_HREF"));
+    loc1.href = "RESET";
+    expect(loc2.href, equals("RESET"));
+    loc2.href = "RESET2";
+    expect(loc3.href, equals("RESET2"));
+  });
+
+  test('method', () {
+    HtmlDocument doc = new MockHtmlDocument();
+  });
+
+  test('mixin', () {
+    Window win = new MockWindow();
+    expect(win.onBlur is Stream, isTrue, reason: 'onBlur should be a stream');
+    HtmlDocument doc = new MockHtmlDocument();
+    expect(doc.onBlur is Stream, isTrue, reason: 'onBlur should be a stream');
+  });
+
+  test('operator', () {
+    var fileList = new MockFileList();
+    expect(fileList[1] is File, isTrue);
+  });
+}
diff --git a/tests/lib/html/htmlcollection_test.dart b/tests/lib/html/htmlcollection_test.dart
new file mode 100644
index 0000000..e0d60e3
--- /dev/null
+++ b/tests/lib/html/htmlcollection_test.dart
@@ -0,0 +1,275 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+bool isChecked(Element e) => (e as CheckboxInputElement).checked;
+bool isUnchecked(Element e) => !(e as CheckboxInputElement).checked;
+
+// Test that List<Element> implements List<T>
+main() {
+  Element insertTestDiv() {
+    Element element = new Element.tag('div');
+    element.innerHtml = r"""
+<div id='allChecked'>
+<input type="checkbox" name="c1" value="1" checked="yes">
+<input type="checkbox" name="c2" value="2" checked="yes">
+<input type="checkbox" name="c3" value="3" checked="yes">
+<input type="checkbox" name="c4" value="4" checked="yes">
+</div>
+<div id='someChecked'>
+<input type="checkbox" name="s1" value="1" checked="yes">
+<input type="checkbox" name="s2" value="2">
+<input type="checkbox" name="s3" value="3" checked="yes">
+<input type="checkbox" name="s4" value="4">
+</div>
+<div id='noneChecked'>
+<input type="checkbox" name="n1" value="1">
+<input type="checkbox" name="n2" value="2">
+<input type="checkbox" name="n3" value="3">
+<input type="checkbox" name="n4" value="4">
+</div>
+<div id='emptyDiv'></div>
+""";
+    document.body!.append(element);
+    return element;
+  }
+
+  test('IsList', () {
+    Element root = insertTestDiv();
+
+    List<Element> eachChecked = document.querySelector('#allChecked')!.children;
+
+    expect(eachChecked is List, isTrue);
+
+    root.remove();
+  });
+  test('Every', () {
+    Element root = insertTestDiv();
+
+    List<Element> eachChecked = document.querySelector('#allChecked')!.children;
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(eachChecked.length, 4);
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(eachChecked.every(isChecked), isTrue);
+    expect(eachChecked.every(isUnchecked), isFalse);
+    expect(someChecked.every(isChecked), isFalse);
+    expect(someChecked.every(isUnchecked), isFalse);
+    expect(noneChecked.every(isChecked), isFalse);
+    expect(noneChecked.every(isUnchecked), isTrue);
+
+    root.remove();
+  });
+  test('Some', () {
+    Element root = insertTestDiv();
+
+    List<Element> eachChecked = document.querySelector('#allChecked')!.children;
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(eachChecked.length, 4);
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(eachChecked.any(isChecked), isTrue);
+    expect(eachChecked.any(isUnchecked), isFalse);
+    expect(someChecked.any(isChecked), isTrue);
+    expect(someChecked.any(isUnchecked), isTrue);
+    expect(noneChecked.any(isChecked), isFalse);
+    expect(noneChecked.any(isUnchecked), isTrue);
+
+    root.remove();
+  });
+  test('Filter', () {
+    Element root = insertTestDiv();
+
+    List<Element> eachChecked = document.querySelector('#allChecked')!.children;
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(eachChecked.length, 4);
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(eachChecked.where(isChecked).length, 4);
+    expect(eachChecked.where(isUnchecked).length, 0);
+    expect(someChecked.where(isChecked).length, 2);
+    expect(someChecked.where(isUnchecked).length, 2);
+    expect(noneChecked.where(isChecked).length, 0);
+    expect(noneChecked.where(isUnchecked).length, 4);
+
+    root.remove();
+  });
+  test('IsEmpty', () {
+    Element root = insertTestDiv();
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> emptyDiv = document.querySelector('#emptyDiv')!.children;
+
+    expect(someChecked.length, 4);
+    expect(emptyDiv.length, 0);
+
+    expect(someChecked.isEmpty, isFalse);
+    expect(emptyDiv.isEmpty, isTrue);
+
+    root.remove();
+  });
+
+  int countWithForEach(collection, predicate) {
+    int count = 0;
+    collection.forEach((element) {
+      if (predicate(element)) count++;
+    });
+    return count;
+  }
+
+  test('ForEach', () {
+    Element root = insertTestDiv();
+
+    List<Element> eachChecked = document.querySelector('#allChecked')!.children;
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(eachChecked.length, 4);
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(countWithForEach(eachChecked, isChecked), 4);
+    expect(countWithForEach(eachChecked, isUnchecked), 0);
+    expect(countWithForEach(someChecked, isChecked), 2);
+    expect(countWithForEach(someChecked, isUnchecked), 2);
+    expect(countWithForEach(noneChecked, isChecked), 0);
+    expect(countWithForEach(noneChecked, isUnchecked), 4);
+
+    root.remove();
+  });
+
+  int countWithForLoop(collection, predicate) {
+    int count = 0;
+    for (var element in collection) {
+      if (predicate(element)) count++;
+    }
+    return count;
+  }
+
+  test('ForLoop', () {
+    // Uses iterator.
+    Element root = insertTestDiv();
+
+    List<Element> eachChecked = document.querySelector('#allChecked')!.children;
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(eachChecked.length, 4);
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(countWithForLoop(eachChecked, isChecked), 4);
+    expect(countWithForLoop(eachChecked, isUnchecked), 0);
+    expect(countWithForLoop(someChecked, isChecked), 2);
+    expect(countWithForLoop(someChecked, isUnchecked), 2);
+    expect(countWithForLoop(noneChecked, isChecked), 0);
+    expect(countWithForLoop(noneChecked, isUnchecked), 4);
+
+    root.remove();
+  });
+  test('Last', () {
+    Element root = insertTestDiv();
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    expect(someChecked.length, 4);
+
+    expect(someChecked.last, equals(someChecked[3]));
+
+    root.remove();
+  });
+  test('IndexOf', () {
+    Element root = insertTestDiv();
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(someChecked.indexOf(someChecked[0], 0), 0);
+    expect(someChecked.indexOf(someChecked[1], 0), 1);
+    expect(someChecked.indexOf(someChecked[2], 0), 2);
+    expect(someChecked.indexOf(someChecked[3], 0), 3);
+
+    expect(someChecked.indexOf(someChecked[0], 1), -1);
+    expect(someChecked.indexOf(someChecked[1], 2), -1);
+    expect(someChecked.indexOf(someChecked[2], 3), -1);
+    expect(someChecked.indexOf(someChecked[3], 4), -1);
+
+    expect(someChecked.indexOf(noneChecked[0], 0), -1);
+    expect(noneChecked.indexOf(someChecked[0], 0), -1);
+    expect(someChecked.indexOf(noneChecked[1], 0), -1);
+    expect(noneChecked.indexOf(someChecked[1], 0), -1);
+
+    root.remove();
+  });
+  test('LastIndexOf', () {
+    Element root = insertTestDiv();
+
+    List<Element> someChecked =
+        document.querySelector('#someChecked')!.children;
+
+    List<Element> noneChecked =
+        document.querySelector('#noneChecked')!.children;
+
+    expect(someChecked.length, 4);
+    expect(noneChecked.length, 4);
+
+    expect(someChecked.lastIndexOf(someChecked[0], 3), 0);
+    expect(someChecked.lastIndexOf(someChecked[1], 3), 1);
+    expect(someChecked.lastIndexOf(someChecked[2], 3), 2);
+    expect(someChecked.lastIndexOf(someChecked[3], 3), 3);
+
+    expect(someChecked.lastIndexOf(someChecked[0], -1), -1);
+    expect(someChecked.lastIndexOf(someChecked[1], 0), -1);
+    expect(someChecked.lastIndexOf(someChecked[2], 1), -1);
+    expect(someChecked.lastIndexOf(someChecked[3], 2), -1);
+
+    expect(someChecked.lastIndexOf(noneChecked[0], 3), -1);
+    expect(noneChecked.lastIndexOf(someChecked[0], 3), -1);
+    expect(someChecked.lastIndexOf(noneChecked[1], 3), -1);
+    expect(noneChecked.lastIndexOf(someChecked[1], 3), -1);
+
+    root.remove();
+  });
+}
diff --git a/tests/lib/html/htmlelement_test.dart b/tests/lib/html/htmlelement_test.dart
new file mode 100644
index 0000000..898ac06
--- /dev/null
+++ b/tests/lib/html/htmlelement_test.dart
@@ -0,0 +1,105 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+main() {
+  test('InnerHTML', () {
+    Element element = new Element.tag('div');
+    element.id = 'test';
+    element.innerHtml = 'Hello World';
+    document.body!.append(element);
+
+    element = document.querySelector('#test')!;
+    expect(element.innerHtml, 'Hello World');
+    element.remove();
+  });
+  test('HTMLTable', () {
+    TableElement table = new Element.tag('table') as TableElement;
+
+    TableRowElement row = new Element.tag('tr') as TableRowElement;
+    table.append(row);
+
+    row.append(new Element.tag('td'));
+    row.append(new Element.tag('td'));
+
+    expect(row.cells.length, 2);
+
+    TableRowElement headerRow = table.rows[0];
+    expect(headerRow.cells.length, 2);
+  });
+  test('dataset', () {
+    Element div = new Element.tag('div');
+
+    expect(div.dataset.isEmpty, isTrue);
+    expect(div.dataset['foo'], isNull);
+    expect(div.dataset.isEmpty, isTrue);
+
+    div.dataset['foo'] = 'foo-value';
+    expect(div.dataset['foo'], 'foo-value');
+    expect(div.dataset.isEmpty, isFalse);
+
+    expect(div.dataset.containsValue('foo-value'), isTrue);
+    expect(div.dataset.containsValue('bar-value'), isFalse);
+    expect(div.dataset.containsKey('foo'), isTrue);
+    expect(div.dataset.containsKey('bar'), isFalse);
+
+    bool hasBeenInvoked;
+    String f() {
+      hasBeenInvoked = true;
+      return 'bar-value';
+    }
+
+    hasBeenInvoked = false;
+    expect(div.dataset.putIfAbsent('bar', f), 'bar-value');
+    expect(hasBeenInvoked, isTrue);
+
+    hasBeenInvoked = false;
+    expect(div.dataset.putIfAbsent('bar', f), 'bar-value');
+    expect(hasBeenInvoked, isFalse);
+
+    final keys = <String>[];
+    final values = <String>[];
+    div.dataset.forEach((String key, String value) {
+      keys.add(key);
+      values.add(value);
+    });
+    expect(keys, unorderedEquals(['foo', 'bar']));
+    expect(values, unorderedEquals(['foo-value', 'bar-value']));
+
+    expect(new List<String>.from(div.dataset.keys),
+        unorderedEquals(['foo', 'bar']));
+    expect(new List<String>.from(div.dataset.values),
+        unorderedEquals(['foo-value', 'bar-value']));
+
+    expect(div.dataset.length, 2);
+    expect(div.dataset.isEmpty, isFalse);
+
+    expect(div.dataset.remove('qux'), isNull);
+    expect(div.dataset.length, 2);
+    expect(div.dataset.isEmpty, isFalse);
+
+    expect(div.dataset.remove('foo'), 'foo-value');
+    expect(div.dataset.length, 1);
+    expect(div.dataset.isEmpty, isFalse);
+
+    div.dataset.clear();
+    expect(div.dataset.length, 0);
+    expect(div.dataset.isEmpty, isTrue);
+
+    Element otherDiv = new Element.html(
+        '<div id="dataDiv" data-my-message="Hello World"></div>',
+        treeSanitizer: new NullTreeSanitizer());
+    expect(otherDiv.dataset.containsKey('myMessage'), isTrue);
+
+    Element anotherDiv = new Element.html(
+        '<div id="dataDiv" data-eggs="bacon"></div>',
+        treeSanitizer: new NullTreeSanitizer());
+    expect(anotherDiv.dataset.containsKey('eggs'), isTrue);
+  });
+}
diff --git a/tests/lib/html/htmloptionscollection_test.dart b/tests/lib/html/htmloptionscollection_test.dart
new file mode 100644
index 0000000..583cd88
--- /dev/null
+++ b/tests/lib/html/htmloptionscollection_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('indexedAccessTest', () {
+    // FIXME: we need some massaging to dart:html to enable HTMLOptionsCollection.add
+    // and hence programatic building of collection.
+    SelectElement selectElement = new Element.html('''
+      <select>
+        <option value="0">Option0</option>
+        <option value="1">Option1</option>
+        <option value="2">Option2</option>
+      ''') as SelectElement;
+    final optionsCollection = selectElement.options;
+
+    expect(optionsCollection[0].value, equals('0'));
+    expect(optionsCollection[1].value, equals('1'));
+    expect(optionsCollection[2].value, equals('2'));
+
+    expect(optionsCollection[0].text, equals('Option0'));
+    expect(optionsCollection[1].text, equals('Option1'));
+    expect(optionsCollection[2].text, equals('Option2'));
+
+    expect(() {
+      (optionsCollection as dynamic)[0] = 1;
+    }, throws);
+
+    // OPTIONALS optionsCollection[0] = new OptionElement(value: '42', data: 'Option42');
+    expect(() {
+      optionsCollection[0] = new OptionElement(data: 'Option42', value: '42');
+    }, throws);
+  });
+}
diff --git a/tests/lib/html/http_test.dart b/tests/lib/html/http_test.dart
new file mode 100644
index 0000000..905f4d5
--- /dev/null
+++ b/tests/lib/html/http_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+bool testSwitch(int currentValue) {
+  switch (currentValue) {
+    case HttpStatus.continue_:
+      return true;
+    case HttpStatus.ok:
+      return true;
+    case HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR:
+      return true;
+  }
+
+  return false;
+}
+
+main() {
+  expect(testSwitch(HttpStatus.continue_), isTrue);
+  expect(testSwitch(HttpStatus.CONTINUE), isTrue);
+
+  expect(testSwitch(HttpStatus.ok), isTrue);
+  expect(testSwitch(HttpStatus.OK), isTrue);
+
+  expect(testSwitch(HttpStatus.networkConnectTimeoutError), isTrue);
+  expect(testSwitch(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR), isTrue);
+
+  expect(testSwitch(-20100), isFalse);
+}
diff --git a/tests/lib/html/indexeddb_1_test.dart b/tests/lib/html/indexeddb_1_test.dart
new file mode 100644
index 0000000..8dfc0b0
--- /dev/null
+++ b/tests/lib/html/indexeddb_1_test.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library IndexedDB1Test;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:math' as math;
+import 'dart:indexed_db' as idb;
+
+const String STORE_NAME = 'TEST';
+const int VERSION = 1;
+
+var databaseNameIndex = 0;
+String nextDatabaseName() {
+  return 'Test1_${databaseNameIndex++}';
+}
+
+Future testUpgrade() {
+  var dbName = nextDatabaseName();
+  var upgraded = false;
+
+  // Delete any existing DBs.
+  return html.window.indexedDB!.deleteDatabase(dbName).then((_) {
+    return html.window.indexedDB!
+        .open(dbName, version: 1, onUpgradeNeeded: (e) {});
+  }).then((db) {
+    db.close();
+  }).then((_) {
+    return html.window.indexedDB!.open(dbName, version: 2,
+        onUpgradeNeeded: (e) {
+      expect(e.oldVersion, 1);
+      expect(e.newVersion, 2);
+      upgraded = true;
+    });
+  }).then((_) {
+    expect(upgraded, isTrue);
+  });
+}
+
+testReadWrite(key, value, matcher,
+        [dbName,
+        storeName = STORE_NAME,
+        version = VERSION,
+        stringifyResult = false]) =>
+    () {
+      if (dbName == null) {
+        dbName = nextDatabaseName();
+      }
+      createObjectStore(e) {
+        idb.ObjectStore store = e.target.result.createObjectStore(storeName);
+        expect(store, isNotNull);
+      }
+
+      late idb.Database db;
+      return html.window.indexedDB!.deleteDatabase(dbName).then((_) {
+        return html.window.indexedDB!
+            .open(dbName, version: version, onUpgradeNeeded: createObjectStore);
+      }).then((idb.Database result) {
+        db = result;
+        var transaction = db.transactionList([storeName], 'readwrite');
+        transaction.objectStore(storeName).put(value, key);
+        return transaction.completed;
+      }).then((_) {
+        var transaction = db.transaction(storeName, 'readonly');
+        return transaction.objectStore(storeName).getObject(key);
+      }).then((object) {
+        db.close();
+        if (stringifyResult) {
+          // Stringify the numbers to verify that we're correctly returning ints
+          // as ints vs doubles.
+          expect(object.toString(), matcher);
+        } else {
+          expect(object, matcher);
+        }
+      }).whenComplete(() {
+        return html.window.indexedDB!.deleteDatabase(dbName);
+      });
+    };
+
+testReadWriteTyped(key, value, matcher,
+        [dbName,
+        String storeName = STORE_NAME,
+        version = VERSION,
+        stringifyResult = false]) =>
+    () {
+      if (dbName == null) {
+        dbName = nextDatabaseName();
+      }
+      void createObjectStore(e) {
+        var store = e.target.result.createObjectStore(storeName);
+        expect(store, isNotNull);
+      }
+
+      late idb.Database db;
+      // Delete any existing DBs.
+      return html.window.indexedDB!.deleteDatabase(dbName).then((_) {
+        return html.window.indexedDB!
+            .open(dbName, version: version, onUpgradeNeeded: createObjectStore);
+      }).then((idb.Database result) {
+        db = result;
+        idb.Transaction transaction =
+            db.transactionList([storeName], 'readwrite');
+        transaction.objectStore(storeName).put(value, key);
+
+        return transaction.completed;
+      }).then((idb.Database result) {
+        idb.Transaction transaction = db.transaction(storeName, 'readonly');
+        return transaction.objectStore(storeName).getObject(key);
+      }).then((object) {
+        db.close();
+        if (stringifyResult) {
+          // Stringify the numbers to verify that we're correctly returning ints
+          // as ints vs doubles.
+          expect(object.toString(), matcher);
+        } else {
+          expect(object, matcher);
+        }
+      }).whenComplete(() {
+        return html.window.indexedDB!.deleteDatabase(dbName);
+      });
+    };
+
+void testTypes(testFunction) {
+  test('String', testFunction(123, 'Hoot!', equals('Hoot!')));
+  test('int', testFunction(123, 12345, equals(12345)));
+  test('List', testFunction(123, [1, 2, 3], equals([1, 2, 3])));
+  test('List 2', testFunction(123, [2, 3, 4], equals([2, 3, 4])));
+  test('bool', testFunction(123, [true, false], equals([true, false])));
+  test(
+      'largeInt',
+      testFunction(123, 1371854424211, equals("1371854424211"), null,
+          STORE_NAME, VERSION, true));
+  test(
+      'largeDoubleConvertedToInt',
+      testFunction(123, 1371854424211.0, equals("1371854424211"), null,
+          STORE_NAME, VERSION, true));
+  test(
+      'largeIntInMap',
+      testFunction(123, {'time': 4503599627370492},
+          equals("{time: 4503599627370492}"), null, STORE_NAME, VERSION, true));
+  var now = new DateTime.now();
+  test(
+      'DateTime',
+      testFunction(
+          123,
+          now,
+          predicate((date) =>
+              date.millisecondsSinceEpoch == now.millisecondsSinceEpoch)));
+}
+
+main() {
+  // Test that indexed_db is properly flagged as supported or not.
+  // Note that the rest of the indexed_db tests assume that this has been
+  // checked.
+  group('supported', () {
+    test('supported', () {
+      expect(idb.IdbFactory.supported, true);
+    });
+  });
+
+  group('functional', () {
+    test('throws when unsupported', () {
+      var expectation = idb.IdbFactory.supported ? returnsNormally : throws;
+
+      expect(() {
+        var db = html.window.indexedDB!;
+        db.open('random_db');
+      }, expectation);
+    });
+
+    // Don't bother with these tests if it's unsupported.
+    if (idb.IdbFactory.supported) {
+      test('upgrade', testUpgrade);
+      group('dynamic', () {
+        testTypes(testReadWrite);
+      });
+      group('typed', () {
+        testTypes(testReadWriteTyped);
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/indexeddb_2_test.dart b/tests/lib/html/indexeddb_2_test.dart
new file mode 100644
index 0000000..9c4da2b
--- /dev/null
+++ b/tests/lib/html/indexeddb_2_test.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library IndexedDB1Test;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:indexed_db' as idb;
+import 'dart:collection';
+import 'utils.dart';
+
+// Write and re-read Maps: simple Maps; Maps with DAGs; Maps with cycles.
+
+const String DB_NAME = 'Test2';
+const String STORE_NAME = 'TEST';
+const int VERSION = 1;
+
+testReadWrite(key, value, check,
+    [dbName = DB_NAME, storeName = STORE_NAME, version = VERSION]) async {
+  void createObjectStore(e) {
+    idb.ObjectStore store = e.target.result.createObjectStore(storeName);
+    expect(store, isNotNull);
+  }
+
+  idb.Database? db;
+  // Delete any existing DBs.
+  try {
+    await html.window.indexedDB!.deleteDatabase(dbName);
+    db = await html.window.indexedDB!
+        .open(dbName, version: version, onUpgradeNeeded: createObjectStore);
+
+    idb.Transaction transaction = db.transactionList([storeName], 'readwrite');
+    transaction.objectStore(storeName).put(value, key);
+
+    db = await transaction.completed;
+    transaction = db.transaction(storeName, 'readonly');
+    var object = await transaction.objectStore(storeName).getObject(key);
+
+    db.close();
+    check(value, object);
+  } catch (error) {
+    if (db != null) {
+      db.close();
+    }
+    throw error;
+  }
+}
+
+List<String> get nonNativeListData {
+  List<String> list = [];
+  list.add("data");
+  list.add("clone");
+  list.add("error");
+  list.add("test");
+  return list;
+}
+
+main() {
+  var obj1 = {'a': 100, 'b': 's'};
+  var obj2 = {'x': obj1, 'y': obj1}; // DAG.
+
+  var obj3 = {};
+  obj3['a'] = 100;
+  obj3['b'] = obj3; // Cycle.
+
+  var obj4 = new SplayTreeMap<String, dynamic>(); // Different implementation.
+  obj4['a'] = 100;
+  obj4['b'] = 's';
+
+  var cyclic_list = <Object>[1, 2, 3];
+  cyclic_list[1] = cyclic_list;
+
+  go(name, data) => testReadWrite(123, data, verifyGraph);
+
+  test('test_verifyGraph', () {
+    // Nice to know verifyGraph is working before we rely on it.
+    verifyGraph(obj4, obj4);
+    verifyGraph(obj1, new Map.from(obj1));
+    verifyGraph(obj4, new Map.from(obj4));
+
+    var l1 = [1, 2, 3];
+    var l2 = [
+      const [1, 2, 3],
+      const [1, 2, 3]
+    ];
+    verifyGraph([l1, l1], l2);
+    // Use a try-catch block, since failure can be an expect exception.
+    // package:expect does not allow catching test exceptions.
+    try {
+      verifyGraph([
+        [1, 2, 3],
+        [1, 2, 3]
+      ], l2);
+      fail("Expected failure in verifying the graph.");
+    } catch (_) {
+      // Expected failure. Continue.
+    }
+
+    verifyGraph(cyclic_list, cyclic_list);
+  });
+
+  // Don't bother with these tests if it's unsupported.
+  // Support is tested in indexeddb_1_test
+  if (idb.IdbFactory.supported) {
+    asyncTest(() async {
+      await go('test_simple', obj1);
+      await go('test_DAG', obj2);
+      await go('test_cycle', obj3);
+      await go('test_simple_splay', obj4);
+      await go('const_array_1', const [
+        const [1],
+        const [2]
+      ]);
+      await go('const_array_dag', const [
+        const [1],
+        const [1]
+      ]);
+      await go('array_deferred_copy', [1, 2, 3, obj3, obj3, 6]);
+      await go('array_deferred_copy_2', [
+        1,
+        2,
+        3,
+        [4, 5, obj3],
+        [obj3, 6]
+      ]);
+      await go('cyclic_list', cyclic_list);
+      await go('non-native lists', nonNativeListData);
+    });
+  }
+}
diff --git a/tests/lib/html/indexeddb_3_test.dart b/tests/lib/html/indexeddb_3_test.dart
new file mode 100644
index 0000000..2835aaf
--- /dev/null
+++ b/tests/lib/html/indexeddb_3_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library IndexedDB3Test;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:indexed_db';
+
+// Read with cursor.
+
+const String DB_NAME = 'Test3';
+const String STORE_NAME = 'TEST';
+const int VERSION = 1;
+
+Future<Database> createAndOpenDb() {
+  return html.window.indexedDB!.deleteDatabase(DB_NAME).then((_) {
+    return html.window.indexedDB!.open(DB_NAME, version: VERSION,
+        onUpgradeNeeded: (VersionChangeEvent e) {
+      var db = e.target.result;
+      db.createObjectStore(STORE_NAME);
+    });
+  });
+}
+
+Future<Database> writeItems(Database db) {
+  Future<Object> write(index) {
+    var transaction = db.transaction(STORE_NAME, 'readwrite');
+    transaction.objectStore(STORE_NAME).put('Item $index', index);
+    return transaction.completed;
+  }
+
+  var future = write(0);
+  for (var i = 1; i < 100; ++i) {
+    future = future.then((_) => write(i));
+  }
+
+  // Chain on the DB so we return it at the end.
+  return future.then((_) => db);
+}
+
+Future<Database> setupDb() {
+  return createAndOpenDb().then(writeItems);
+}
+
+Future<Database> readAllViaCursor(Database db) {
+  Transaction txn = db.transaction(STORE_NAME, 'readonly');
+  ObjectStore objectStore = txn.objectStore(STORE_NAME);
+  int itemCount = 0;
+  int sumKeys = 0;
+  var lastKey = null;
+
+  var cursors = objectStore.openCursor().asBroadcastStream();
+  cursors.listen((cursor) {
+    ++itemCount;
+    lastKey = cursor.key;
+    sumKeys += cursor.key as int;
+    expect(cursor.value, 'Item ${cursor.key}');
+    cursor.next();
+  });
+  cursors.last.then((cursor) {
+    expect(lastKey, 99);
+    expect(sumKeys, (100 * 99) ~/ 2);
+    expect(itemCount, 100);
+  });
+
+  return cursors.last.then((_) => db);
+}
+
+Future<Database> readAllReversedViaCursor(Database db) {
+  Transaction txn = db.transaction(STORE_NAME, 'readonly');
+  ObjectStore objectStore = txn.objectStore(STORE_NAME);
+  int itemCount = 0;
+  int sumKeys = 0;
+  var lastKey = null;
+
+  var cursors = objectStore.openCursor(direction: 'prev').asBroadcastStream();
+  cursors.listen((cursor) {
+    ++itemCount;
+    lastKey = cursor.key;
+    sumKeys += cursor.key as int;
+    expect(cursor.value, 'Item ${cursor.key}');
+    cursor.next();
+  });
+  cursors.last.then((cursor) {
+    expect(lastKey, 0);
+    expect(sumKeys, (100 * 99) ~/ 2);
+    expect(itemCount, 100);
+  });
+  return cursors.last.then((_) => db);
+}
+
+main() {
+  // Don't bother with these tests if it's unsupported.
+  // Support is tested in indexeddb_1_test
+  if (IdbFactory.supported) {
+    asyncTest(() async {
+      var db = await setupDb();
+      await readAllViaCursor(db);
+      await readAllReversedViaCursor(db);
+    });
+  }
+}
diff --git a/tests/lib/html/indexeddb_4_test.dart b/tests/lib/html/indexeddb_4_test.dart
new file mode 100644
index 0000000..c129225
--- /dev/null
+++ b/tests/lib/html/indexeddb_4_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library IndexedDB4Test;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:indexed_db';
+
+// Test for KeyRange and Cursor.
+
+const String DB_NAME = 'Test4';
+const String STORE_NAME = 'TEST';
+const int VERSION = 1;
+
+Future<Database> createAndOpenDb() {
+  return html.window.indexedDB!.deleteDatabase(DB_NAME).then((_) {
+    return html.window.indexedDB!.open(DB_NAME, version: VERSION,
+        onUpgradeNeeded: (e) {
+      var db = e.target.result;
+      db.createObjectStore(STORE_NAME);
+    });
+  });
+}
+
+Future<Database> writeItems(Database db) {
+  Future<Object?> write(index) {
+    var transaction = db.transaction(STORE_NAME, 'readwrite');
+    return transaction
+        .objectStore(STORE_NAME)
+        .put({'content': 'Item $index'}, index) as Future<Object?>;
+  }
+
+  var future = write(0);
+  for (var i = 1; i < 100; ++i) {
+    future = future.then((_) => write(i));
+  }
+
+  // Chain on the DB so we return it at the end.
+  return future.then((_) => db);
+}
+
+Future<Database> setupDb() {
+  return createAndOpenDb().then(writeItems);
+}
+
+testRange(db, range, expectedFirst, expectedLast) {
+  Transaction txn = db.transaction(STORE_NAME, 'readonly');
+  ObjectStore objectStore = txn.objectStore(STORE_NAME);
+  var cursors = objectStore
+      .openCursor(range: range, autoAdvance: true)
+      .asBroadcastStream();
+
+  int lastKey = 0;
+  cursors.listen((cursor) {
+    lastKey = cursor.key as int;
+    var value = cursor.value;
+    expect(value['content'], 'Item ${cursor.key}');
+  });
+
+  if (expectedFirst != null) {
+    cursors.first.then((cursor) {
+      expect(cursor.key, expectedFirst);
+    });
+  }
+  if (expectedLast != null) {
+    cursors.last.then((cursor) {
+      expect(lastKey, expectedLast);
+    });
+  }
+
+  return cursors.length.then((length) {
+    if (expectedFirst == null) {
+      expect(length, 0);
+    } else {
+      expect(length, expectedLast - expectedFirst + 1);
+    }
+  });
+}
+
+main() async {
+  // Don't bother with these tests if it's unsupported.
+  // Support is tested in indexeddb_1_test
+  if (IdbFactory.supported) {
+    var db = await setupDb();
+    test('only1', () => testRange(db, new KeyRange.only(55), 55, 55));
+    test('only2', () => testRange(db, new KeyRange.only(100), null, null));
+    test('only3', () => testRange(db, new KeyRange.only(-1), null, null));
+
+    test('lower1', () => testRange(db, new KeyRange.lowerBound(40), 40, 99));
+    // OPTIONALS lower2() => testRange(db, new KeyRange.lowerBound(40, open: true), 41, 99);
+    test('lower2',
+        () => testRange(db, new KeyRange.lowerBound(40, true), 41, 99));
+    // OPTIONALS lower3() => testRange(db, new KeyRange.lowerBound(40, open: false), 40, 99);
+    test('lower3',
+        () => testRange(db, new KeyRange.lowerBound(40, false), 40, 99));
+
+    test('upper1', () => testRange(db, new KeyRange.upperBound(40), 0, 40));
+    // OPTIONALS upper2() => testRange(db, new KeyRange.upperBound(40, open: true), 0, 39);
+    test('upper2',
+        () => testRange(db, new KeyRange.upperBound(40, true), 0, 39));
+    // upper3() => testRange(db, new KeyRange.upperBound(40, open: false), 0, 40);
+    test('upper3',
+        () => testRange(db, new KeyRange.upperBound(40, false), 0, 40));
+
+    test('bound1', () => testRange(db, new KeyRange.bound(20, 30), 20, 30));
+
+    test('bound2', () => testRange(db, new KeyRange.bound(-100, 200), 0, 99));
+
+    bound3() =>
+        // OPTIONALS testRange(db, new KeyRange.bound(20, 30, upperOpen: true),
+        testRange(db, new KeyRange.bound(20, 30, false, true), 20, 29);
+
+    bound4() =>
+        // OPTIONALS testRange(db, new KeyRange.bound(20, 30, lowerOpen: true),
+        testRange(db, new KeyRange.bound(20, 30, true), 21, 30);
+
+    bound5() =>
+        // OPTIONALS testRange(db, new KeyRange.bound(20, 30, lowerOpen: true, upperOpen: true),
+        testRange(db, new KeyRange.bound(20, 30, true, true), 21, 29);
+  }
+}
diff --git a/tests/lib/html/indexeddb_5_test.dart b/tests/lib/html/indexeddb_5_test.dart
new file mode 100644
index 0000000..052a34d
--- /dev/null
+++ b/tests/lib/html/indexeddb_5_test.dart
@@ -0,0 +1,148 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library IndexedDB1Test;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:indexed_db' as idb;
+
+var dbName = 'test_db_5';
+var storeName = 'test_store';
+var indexName = 'name_index';
+var db;
+var value = {'name_index': 'one', 'value': 'add_value'};
+
+Future testInit() async {
+  await html.window.indexedDB!.deleteDatabase(dbName);
+  db = await html.window.indexedDB!.open(dbName, version: 1,
+      onUpgradeNeeded: (idb.VersionChangeEvent e) {
+    var db = e.target.result;
+    var objectStore = db.createObjectStore(storeName, autoIncrement: true);
+    objectStore.createIndex(indexName, 'name_index', unique: false);
+  });
+}
+
+Future testAddDelete() async {
+  var transaction = db.transaction(storeName, 'readwrite');
+  var key = await transaction.objectStore(storeName).add(value);
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  var readValue = await transaction.objectStore(storeName).getObject(key);
+  expect(readValue['value'], value['value']);
+  await transaction.completed;
+  transaction = db.transactionList([storeName], 'readwrite');
+  await transaction.objectStore(storeName).delete(key);
+  await transaction.completed;
+  transaction = db.transactionList([storeName], 'readonly');
+  var count = await transaction.objectStore(storeName).count();
+  expect(count, 0);
+}
+
+Future testClearCount() async {
+  var transaction = db.transaction(storeName, 'readwrite');
+  transaction.objectStore(storeName).add(value);
+
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  var count = await transaction.objectStore(storeName).count();
+  expect(count, 1);
+  await transaction.completed;
+  transaction = db.transactionList([storeName], 'readwrite');
+  transaction.objectStore(storeName).clear();
+  await transaction.completed;
+  transaction = db.transactionList([storeName], 'readonly');
+  count = await transaction.objectStore(storeName).count();
+  expect(count, 0);
+}
+
+Future testIndex() async {
+  var transaction = db.transaction(storeName, 'readwrite');
+  transaction.objectStore(storeName).add(value);
+  transaction.objectStore(storeName).add(value);
+  transaction.objectStore(storeName).add(value);
+  transaction.objectStore(storeName).add(value);
+
+  await transaction.completed;
+  transaction = db.transactionList([storeName], 'readonly');
+  var index = transaction.objectStore(storeName).index(indexName);
+  var count = await index.count();
+  expect(count, 4);
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  index = transaction.objectStore(storeName).index(indexName);
+  var cursorsLength = await index.openCursor(autoAdvance: true).length;
+  expect(cursorsLength, 4);
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  index = transaction.objectStore(storeName).index(indexName);
+  cursorsLength = await index.openKeyCursor(autoAdvance: true).length;
+  expect(cursorsLength, 4);
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  index = transaction.objectStore(storeName).index(indexName);
+  var readValue = await index.get('one');
+  expect(readValue['value'], value['value']);
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readwrite');
+  transaction.objectStore(storeName).clear();
+  return transaction.completed;
+}
+
+Future testCursor() async {
+  var deleteValue = {'name_index': 'two', 'value': 'delete_value'};
+  var updateValue = {'name_index': 'three', 'value': 'update_value'};
+  var updatedValue = {'name_index': 'three', 'value': 'updated_value'};
+  var transaction = db.transaction(storeName, 'readwrite');
+  transaction.objectStore(storeName).add(value);
+  transaction.objectStore(storeName).add(deleteValue);
+  transaction.objectStore(storeName).add(updateValue);
+
+  await transaction.completed;
+  transaction = db.transactionList([storeName], 'readwrite');
+  var index = transaction.objectStore(storeName).index(indexName);
+  var cursors = index.openCursor().asBroadcastStream();
+
+  cursors.listen((cursor) {
+    var value = cursor.value;
+    if (value['value'] == 'delete_value') {
+      cursor.delete().then((_) {
+        cursor.next();
+      });
+    } else if (value['value'] == 'update_value') {
+      cursor.update(updatedValue).then((_) {
+        cursor.next();
+      });
+    } else {
+      cursor.next();
+    }
+  });
+  await cursors.last;
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  index = transaction.objectStore(storeName).index(indexName);
+  var readValue = await index.get('three');
+  expect(readValue['value'], 'updated_value');
+  await transaction.completed;
+  transaction = db.transaction(storeName, 'readonly');
+  index = transaction.objectStore(storeName).index(indexName);
+  readValue = await index.get('two');
+  expect(readValue, isNull);
+  return transaction.completed;
+}
+
+main() {
+  if (!idb.IdbFactory.supported) {
+    return;
+  }
+  asyncTest(() async {
+    await testInit();
+    await testAddDelete();
+    await testClearCount();
+    await testIndex();
+    await testCursor();
+  });
+}
diff --git a/tests/lib/html/input_element_attributes_test.dart b/tests/lib/html/input_element_attributes_test.dart
new file mode 100644
index 0000000..09730b9
--- /dev/null
+++ b/tests/lib/html/input_element_attributes_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+@pragma('dart2js:noInline')
+returnNothing() {}
+
+// Gets an undefined value from JS.
+dynamic _undefined = returnNothing();
+
+main() {
+  test('valueSetNull', () {
+    final e = new TextInputElement();
+    e.value = null;
+    expect(e.value, '');
+  });
+  test('valueSetNullProxy', () {
+    final e = new TextInputElement();
+    e.value = _undefined;
+    expect(e.value, 'undefined');
+  });
+}
diff --git a/tests/lib/html/input_element_constructor_test.dart b/tests/lib/html/input_element_constructor_test.dart
new file mode 100644
index 0000000..43a6e79
--- /dev/null
+++ b/tests/lib/html/input_element_constructor_test.dart
@@ -0,0 +1,112 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+void check(element, String type, [bool supported = true]) {
+  expect(element is InputElement, true);
+  if (supported) {
+    expect(element.type, type);
+  } else {
+    expect(element.type, 'text');
+  }
+}
+
+main() {
+  test('hidden', () {
+    check(new HiddenInputElement(), 'hidden');
+  });
+
+  test('search', () {
+    check(new SearchInputElement(), 'search', SearchInputElement.supported);
+  });
+
+  test('text', () {
+    check(new TextInputElement(), 'text');
+  });
+
+  test('url', () {
+    check(new UrlInputElement(), 'url', UrlInputElement.supported);
+  });
+
+  test('telephone', () {
+    check(new TelephoneInputElement(), 'tel', TelephoneInputElement.supported);
+  });
+
+  test('email', () {
+    check(new EmailInputElement(), 'email', EmailInputElement.supported);
+  });
+
+  test('password', () {
+    check(new PasswordInputElement(), 'password');
+  });
+
+  test('date', () {
+    check(new DateInputElement(), 'date', DateInputElement.supported);
+  });
+
+  test('month', () {
+    check(new MonthInputElement(), 'month', MonthInputElement.supported);
+  });
+
+  test('week', () {
+    check(new WeekInputElement(), 'week', WeekInputElement.supported);
+  });
+
+  test('time', () {
+    check(new TimeInputElement(), 'time', TimeInputElement.supported);
+    if (TimeInputElement.supported) {
+      var element = new TimeInputElement();
+      var now = new DateTime.now();
+      element.valueAsDate = now;
+      expect(element.valueAsDate is DateTime, isTrue);
+
+      // Bug 8813, setting it is just going to the epoch.
+      //expect(element.valueAsDate, now);
+    }
+  });
+
+  test('datetime-local', () {
+    check(new LocalDateTimeInputElement(), 'datetime-local',
+        LocalDateTimeInputElement.supported);
+  });
+
+  test('number', () {
+    check(new NumberInputElement(), 'number', NumberInputElement.supported);
+  });
+
+  test('range', () {
+    check(new RangeInputElement(), 'range', RangeInputElement.supported);
+  });
+
+  test('checkbox', () {
+    check(new CheckboxInputElement(), 'checkbox');
+  });
+
+  test('radio', () {
+    check(new RadioButtonInputElement(), 'radio');
+  });
+
+  test('file', () {
+    check(new FileUploadInputElement(), 'file');
+  });
+
+  test('submit', () {
+    check(new SubmitButtonInputElement(), 'submit');
+  });
+
+  test('image', () {
+    check(new ImageButtonInputElement(), 'image');
+  });
+
+  test('reset', () {
+    check(new ResetButtonInputElement(), 'reset');
+  });
+
+  test('button', () {
+    check(new ButtonInputElement(), 'button');
+  });
+}
diff --git a/tests/lib/html/input_element_date_test.dart b/tests/lib/html/input_element_date_test.dart
new file mode 100644
index 0000000..6d24371
--- /dev/null
+++ b/tests/lib/html/input_element_date_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(DateInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_datetime_test.dart b/tests/lib/html/input_element_datetime_test.dart
new file mode 100644
index 0000000..ee7acd0
--- /dev/null
+++ b/tests/lib/html/input_element_datetime_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(LocalDateTimeInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_email_test.dart b/tests/lib/html/input_element_email_test.dart
new file mode 100644
index 0000000..2f65bae
--- /dev/null
+++ b/tests/lib/html/input_element_email_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(EmailInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_month_test.dart b/tests/lib/html/input_element_month_test.dart
new file mode 100644
index 0000000..0668d81
--- /dev/null
+++ b/tests/lib/html/input_element_month_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(MonthInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_number_test.dart b/tests/lib/html/input_element_number_test.dart
new file mode 100644
index 0000000..17bd37b
--- /dev/null
+++ b/tests/lib/html/input_element_number_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(NumberInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_range_test.dart b/tests/lib/html/input_element_range_test.dart
new file mode 100644
index 0000000..c6d21cd
--- /dev/null
+++ b/tests/lib/html/input_element_range_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(RangeInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_search_test.dart b/tests/lib/html/input_element_search_test.dart
new file mode 100644
index 0000000..7e57334
--- /dev/null
+++ b/tests/lib/html/input_element_search_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(SearchInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_tel_test.dart b/tests/lib/html/input_element_tel_test.dart
new file mode 100644
index 0000000..de7919c
--- /dev/null
+++ b/tests/lib/html/input_element_tel_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(TelephoneInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_time_test.dart b/tests/lib/html/input_element_time_test.dart
new file mode 100644
index 0000000..c5a8477
--- /dev/null
+++ b/tests/lib/html/input_element_time_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(TimeInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_url_test.dart b/tests/lib/html/input_element_url_test.dart
new file mode 100644
index 0000000..8b14ca0
--- /dev/null
+++ b/tests/lib/html/input_element_url_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(UrlInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/input_element_week_test.dart b/tests/lib/html/input_element_week_test.dart
new file mode 100644
index 0000000..35430cc
--- /dev/null
+++ b/tests/lib/html/input_element_week_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('supported', () {
+    expect(WeekInputElement.supported, true);
+  });
+}
diff --git a/tests/lib/html/instance_of_test.dart b/tests/lib/html/instance_of_test.dart
new file mode 100644
index 0000000..9ee04b3
--- /dev/null
+++ b/tests/lib/html/instance_of_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var canvas;
+
+  canvas = new Element.tag('canvas');
+  canvas.attributes['width'] = '100';
+  canvas.attributes['height'] = '100';
+  document.body!.append(canvas);
+
+  var isCanvasRenderingContext = predicate(
+      (x) => x is CanvasRenderingContext, 'is a CanvasRenderingContext');
+  var isNotCanvasRenderingContext = predicate(
+      (x) => x is! CanvasRenderingContext, 'is not a CanvasRenderingContext');
+  var isCanvasRenderingContext2D = predicate(
+      (x) => x is CanvasRenderingContext2D, 'is a CanvasRenderingContext2D');
+  var isNotCanvasRenderingContext2D = predicate(
+      (x) => x is! CanvasRenderingContext2D,
+      'is not a CanvasRenderingContext2D');
+  var isElement = predicate((x) => x is Element, 'is an Element');
+  var isNotElement = predicate((x) => x is! Element, 'is not an Element');
+  var isCanvasElement =
+      predicate((x) => x is CanvasElement, 'is a CanvasElement');
+  var isNotCanvasElement =
+      predicate((x) => x is! CanvasElement, 'is not a CanvasElement');
+  var isImageData = predicate((x) => x is ImageData, 'is an ImageData');
+  var isNotImageData = predicate((x) => x is! ImageData, 'is not an ImageData');
+  //var isUint8ClampedArray =
+  //  predicate((x) => x is Uint8ClampedArray, 'is a Uint8ClampedArray');
+  var isIntList = predicate((x) => x is List<int>, 'is a List<int>');
+
+  test('Instanceof', () {
+    expect(canvas, isNotCanvasRenderingContext);
+    expect(canvas, isNotCanvasRenderingContext2D);
+    expect(canvas, isElement);
+    expect(canvas, isCanvasElement);
+    expect(canvas, isNotImageData);
+    // expect(canvas, isNot(isCanvasPixelArray));
+
+    var context = canvas.getContext('2d');
+    expect(context, isCanvasRenderingContext);
+    expect(context, isCanvasRenderingContext2D);
+    expect(context, isNotElement);
+    expect(context, isNotCanvasElement);
+    expect(context, isNotImageData);
+    // expect(context, isNot(isCanvasPixelArray));
+
+    // FIXME(b/5286633): Interface injection type check workaround.
+    var image = (context as CanvasRenderingContext2D)
+        .createImageData(canvas.width as dynamic, canvas.height as dynamic);
+    expect(image, isNotCanvasRenderingContext);
+    expect(image, isNotCanvasRenderingContext2D);
+    expect(image, isNotElement);
+    expect(image, isNotCanvasElement);
+    expect(image, isImageData);
+    // expect(image, isNot(isCanvasPixelArray));
+
+    // Include CanvasPixelArray since constructor and prototype are not
+    // available until one is created.
+    var bytes = image.data;
+    expect(bytes, isNotCanvasRenderingContext);
+    expect(bytes, isNotCanvasRenderingContext2D);
+    expect(bytes, isNotElement);
+    expect(bytes, isNotCanvasElement);
+    expect(bytes, isNotImageData);
+    expect(bytes, isIntList);
+
+    // FIXME: Ensure this is an SpanElement when we next update
+    // WebKit IDL.
+    var span = new Element.tag('span');
+    expect(span, isElement);
+  });
+}
diff --git a/tests/lib/html/interactive_geolocation_test.dart b/tests/lib/html/interactive_geolocation_test.dart
new file mode 100644
index 0000000..1ad3a13
--- /dev/null
+++ b/tests/lib/html/interactive_geolocation_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library interactive_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'utils.dart';
+
+Future testGetCurrentPosition() async {
+  var position = await window.navigator.geolocation.getCurrentPosition();
+  Expect.isNotNull(position.coords.latitude);
+  Expect.isNotNull(position.coords.longitude);
+  Expect.isNotNull(position.coords.accuracy);
+}
+
+Future testWatchPosition() async {
+  var position = await window.navigator.geolocation.watchPosition().first;
+  Expect.isNotNull(position.coords.latitude);
+  Expect.isNotNull(position.coords.longitude);
+  Expect.isNotNull(position.coords.accuracy);
+}
+
+main() {
+  asyncTest(() async {
+    await testGetCurrentPosition();
+    await testWatchPosition();
+  });
+}
diff --git a/tests/lib/html/interactive_media_test.dart b/tests/lib/html/interactive_media_test.dart
new file mode 100644
index 0000000..840e16a
--- /dev/null
+++ b/tests/lib/html/interactive_media_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library interactive_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+import 'package:async_helper/async_helper.dart';
+
+// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
+
+main() async {
+  if (MediaStream.supported) {
+    test('getUserMedia audio', () async {
+      try {
+        var mediaStream = await window.navigator.getUserMedia(audio: true);
+        expect(mediaStream, isNotNull);
+        expect(mediaStream is MediaStream, true);
+        var devices = window.navigator.mediaDevices;
+        var enumDevices = await devices.enumerateDevices();
+        expect(enumDevices.length > 1, true);
+        for (var device in enumDevices) {
+          var goodDevLabel = device.label.endsWith('Built-in Output') ||
+              device.label.endsWith('Built-in Microphone');
+          expect(goodDevLabel, true);
+        }
+      } catch (e) {
+        // Could fail if bot machine doesn't support audio or video.
+        expect(e.name == DomException.NOT_FOUND, true);
+      }
+    });
+
+    test('getUserMedia', () {
+      return window.navigator.getUserMedia(video: true).then((stream) {
+        expect(stream, isNotNull);
+
+        var url = Url.createObjectUrlFromStream(stream);
+        expect(url, isNotNull);
+
+        var video = new VideoElement()..autoplay = true;
+
+        var completer = new Completer();
+        video.onError.listen((e) {
+          completer.completeError(e);
+        });
+        video.onPlaying.first.then((e) {
+          completer.complete(video);
+        });
+
+        document.body!.append(video);
+        video.src = url;
+
+        return completer.future;
+      }).catchError((e) {
+        // Could fail if bot machine doesn't support audio or video.
+        expect(e.name == DomException.NOT_FOUND, true);
+      });
+    });
+
+    test('getUserMediaComplexConstructor', () {
+      return window.navigator.getUserMedia(video: {
+        'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
+        'optional': [
+          {'minFrameRate': 60},
+          {'maxWidth': 640}
+        ]
+      }).then((stream) {
+        expect(stream, isNotNull);
+
+        var url = Url.createObjectUrlFromStream(stream);
+        expect(url, isNotNull);
+
+        var video = new VideoElement()..autoplay = true;
+
+        var completer = new Completer();
+        video.onError.listen((e) {
+          completer.completeError(e);
+        });
+        video.onPlaying.first.then((e) {
+          completer.complete(video);
+        });
+
+        document.body!.append(video);
+        video.src = url;
+
+        return completer.future;
+      }).catchError((e) {
+        // Could fail if bot machine doesn't support audio or video.
+        expect(e.name == DomException.NOT_FOUND, true);
+      });
+    });
+  }
+}
diff --git a/tests/lib/html/interactive_test.dart b/tests/lib/html/interactive_test.dart
new file mode 100644
index 0000000..86b1e6c
--- /dev/null
+++ b/tests/lib/html/interactive_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library interactive_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:expect/minitest.dart';
+import 'utils.dart';
+
+main() {
+  group('KeyEvent', () {
+    keydownHandlerTest(KeyEvent e) {
+      document.body!.innerHtml =
+          '${document.body!.innerHtml}KeyDOWN: CharCode: ${e.charCode}, '
+          'KeyCode: ${e.keyCode}<br />';
+      expect(e.charCode, 0);
+    }
+
+    keypressHandlerTest(KeyEvent e) {
+      document.body!.innerHtml =
+          '${document.body!.innerHtml}KeyPRESS: CharCode: ${e.charCode}, '
+          'KeyCode: ${e.keyCode}<br />';
+    }
+
+    keyupHandlerTest(KeyEvent e) {
+      document.body!.innerHtml =
+          '${document.body!.innerHtml}KeyUP: CharCode: ${e.charCode}, KeyCode:'
+          ' ${e.keyCode}<br />';
+      expect(e.charCode, 0);
+    }
+
+    keyupHandlerTest2(KeyEvent e) {
+      document.body!.innerHtml =
+          '${document.body!.innerHtml}A second KeyUP handler: CharCode: '
+          '${e.charCode}, KeyCode: ${e.keyCode}<br />';
+      expect(e.charCode, 0);
+    }
+
+    test('keys', () {
+      document.body!.innerHtml =
+          '${document.body!.innerHtml}To test keyboard event values, press '
+          'some keys on your keyboard.<br /><br />The charcode for keydown and '
+          'keyup should be 0, and the keycode should (generally) be populated '
+          'with a value. Keycode and charcode should both have values for the '
+          'keypress event.';
+      KeyboardEventStream.onKeyDown(document.body!).listen(keydownHandlerTest);
+      KeyboardEventStream.onKeyPress(document.body!)
+          .listen(keypressHandlerTest);
+      KeyboardEventStream.onKeyUp(document.body!).listen(keyupHandlerTest);
+      KeyboardEventStream.onKeyUp(document.body!).listen(keyupHandlerTest2);
+    });
+  });
+}
diff --git a/tests/lib/html/isolates_test.dart b/tests/lib/html/isolates_test.dart
new file mode 100644
index 0000000..bec82b3
--- /dev/null
+++ b/tests/lib/html/isolates_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library IsolatesTest;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:async';
+import 'dart:html';
+import 'dart:convert';
+import 'dart:isolate' as isolate;
+
+String responseFor(message) => 'response for $message';
+
+void isolateEntry(isolate.SendPort initialReplyTo) {
+  var port = new isolate.ReceivePort();
+  initialReplyTo.send(port.sendPort);
+
+  bool wasThrown = false;
+  try {
+    window.alert('Test');
+  } catch (e) {
+    wasThrown = true;
+  }
+  // If wasn't thrown, do not listen to messages to make test fail.
+  if (!wasThrown) {
+    return;
+  }
+
+  // Check that convert library was loaded to isolate.
+  json.encode([1, 2, 3]);
+
+  port.listen((message) {
+    var data = message[0];
+    var replyTo = message[1];
+    replyTo.send(responseFor(data));
+  });
+}
+
+Future sendReceive(isolate.SendPort port, msg) {
+  var response = new isolate.ReceivePort();
+  port.send([msg, response.sendPort]);
+  return response.first;
+}
+
+main() {
+  test('IsolateSpawn', () {
+    var port = new isolate.ReceivePort();
+    isolate.Isolate.spawn(isolateEntry, port.sendPort);
+    port.close();
+  });
+  test('NonDOMIsolates', () {
+    var callback = expectAsync(() {});
+    var response = new isolate.ReceivePort();
+    var remote = isolate.Isolate.spawn(isolateEntry, response.sendPort);
+    response.first.then((port) {
+      final msg1 = 'foo';
+      final msg2 = 'bar';
+      sendReceive(port, msg1).then((response) {
+        expect(response, equals(responseFor(msg1)));
+        sendReceive(port, msg2).then((response) {
+          expect(response, equals(responseFor(msg2)));
+          callback();
+        });
+      });
+    });
+  });
+}
diff --git a/tests/lib/html/js_array_test.dart b/tests/lib/html/js_array_test.dart
new file mode 100644
index 0000000..1775ed4
--- /dev/null
+++ b/tests/lib/html/js_array_test.dart
@@ -0,0 +1,675 @@
+// 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.
+
+@JS("ArrayTest.Util")
+library js_array_test;
+
+import 'dart:html';
+
+import 'dart:js' as js;
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+import 'json_helper.dart' as json_helper;
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+ArrayTest = {};
+ArrayTest.Util = {
+  callJsMethod: function(jsObj, jsMethodName, args) {
+    return jsObj[jsMethodName].apply(jsObj, args);
+  },
+
+  jsEnumerateIndices: function(obj) {
+    var ret = [];
+    for(var i in obj) {
+      ret.push(i);
+    }
+    return ret;
+  },
+
+  checkIsArray: function(obj) {
+    return Array.isArray(obj);
+  },
+
+  concatValues: function(obj) {
+    return obj.concat("a", "b", ["c", "d"], 42, {foo: 10});
+  },
+
+  concatOntoArray: function(obj) {
+    return [1,2,3].concat(obj, "foo");
+  },
+
+  repeatedConcatOntoArray: function(obj) {
+    return [1,2,3].concat(obj, obj);
+  },
+
+  everyGreaterThanZero: function(obj) {
+    return obj.every(function(currentValue, index, array) {
+      return currentValue > 0;
+    });
+  },
+
+  everyGreaterThanZeroCheckThisArg: function(obj) {
+    var j = 0;
+    return obj.every(function(currentValue, index, array) {
+      if (j != index) {
+        throw "Unxpected index";
+      }
+      j++;
+      if (array !== obj) {
+        throw "Array argument doesn't match obj";
+      }
+      return currentValue > 0;
+    });
+  },
+
+  filterGreater42: function(obj) {
+    return obj.filter(function(currentValue, index, array) {
+      return currentValue > 42;
+    });
+  },
+
+  forEachCollectResult: function(array) {
+    var result = [];
+    array.forEach(function(currentValue) {
+      result.push(currentValue * 2);
+    });
+    return result;
+  },
+
+  someEqual42: function(array) {
+    return array.some(function(currentValue) {
+      return currentValue == 42;
+    });
+  },
+
+  sortNumbersBackwards: function(array) {
+    return array.sort(function(a, b) {
+      return b - a;
+    });
+  },
+
+  spliceDummyItems: function(array) {
+    return array.splice(1, 2, "quick" ,"brown", "fox");
+  },
+
+  spliceTestStringArgs: function(array) {
+    return array.splice("1.2", "2.01", "quick" ,"brown", "fox");
+  },
+
+  splicePastEnd: function(array) {
+    return array.splice(1, 5332, "quick" ,"brown", "fox");
+  },
+
+  callJsToString: function(array) {
+    return array.toString();
+  },
+
+  mapAddIndexToEachElement: function(array) {
+    return array.map(function(currentValue, index) {
+      return currentValue + index;
+    });
+  },
+
+  reduceSumDoubledElements: function(array) {
+    return array.reduce(function(previousValue, currentValue) {
+          return previousValue + currentValue*2;
+        },
+        0);
+  },
+
+  // TODO(jacobr): add a test that distinguishes reduce from reduceRight.
+  reduceRightSumDoubledElements: function(array) {
+    return array.reduceRight(function(previousValue, currentValue) {
+          return previousValue + currentValue*2;
+        },
+        0);
+  },
+
+  getOwnPropertyDescriptor: function(array, property) {
+    return Object.getOwnPropertyDescriptor(array, property);
+  },
+
+  setLength: function(array, len) {
+    return array.length = len;
+  },
+
+  getValue: function(obj, index) {
+    return obj[index];
+  },
+
+  setValue: function(obj, index, value) {
+    return obj[index] = value;
+  },
+
+  // Calling a method from Dart List on an arbitrary target object.
+  callListMethodOnTarget: function(dartArray, target, methodName, args) {
+    return dartArray[methodName].apply(target, args);
+  },
+
+  newArray: function() { return []; },
+
+  newLiteral: function() { return {}; },
+
+};
+""");
+}
+
+@JS()
+class PropertyDescriptor {
+  external get value;
+  external bool get writable;
+  external bool get enumerable;
+  external bool get configurable;
+}
+
+@JS()
+class SimpleJsLiteralClass {
+  external get foo;
+}
+
+class Foo {}
+
+@JS()
+external callJsMethod(List array, String methodName, List args);
+
+callIndexOf(List array, value) => callJsMethod(array, "indexOf", [value]);
+callLastIndexOf(List array, value) =>
+    callJsMethod(array, "lastIndexOf", [value]);
+
+callPop(List array) => callJsMethod(array, "pop", []);
+callPush(List array, element) => callJsMethod(array, "push", [element]);
+callShift(List array) => callJsMethod(array, "shift", []);
+callReverse(List array) => callJsMethod(array, "reverse", []);
+
+callListMethodOnObject(object, String methodName, List args) =>
+    callListMethodOnTarget([], object, methodName, args);
+
+@JS()
+external jsEnumerateIndices(obj);
+@JS()
+external bool checkIsArray(obj);
+@JS()
+external concatValues(obj);
+
+@JS()
+external concatOntoArray(obj);
+
+@JS()
+external repeatedConcatOntoArray(obj);
+@JS()
+external bool everyGreaterThanZero(obj);
+@JS()
+external bool everyGreaterThanZeroCheckThisArg(obj);
+
+@JS()
+external filterGreater42(obj);
+
+@JS()
+external forEachCollectResult(List array);
+@JS()
+external someEqual42(List array);
+@JS()
+external sortNumbersBackwards(List array);
+
+@JS()
+external List spliceDummyItems(List array);
+
+@JS()
+external List spliceTestStringArgs(List array);
+
+@JS()
+external List splicePastEnd(List array);
+
+@JS()
+external String callJsToString(List array);
+
+@JS()
+external mapAddIndexToEachElement(List array);
+@JS()
+external reduceSumDoubledElements(List array);
+
+// TODO(jacobr): add a test that distinguishes reduce from reduceRight.
+@JS()
+external reduceRightSumDoubledElements(List array);
+
+@JS()
+external PropertyDescriptor getOwnPropertyDescriptor(obj, property);
+
+@JS("setLength")
+external callSetLength(List array, length);
+
+@JS()
+external getValue(obj, index);
+
+@JS()
+external setValue(obj, index, value);
+
+@JS()
+external callListMethodOnTarget(
+    List target, object, String methodName, List args);
+
+@JS()
+external newArray();
+
+@JS()
+external newLiteral();
+
+main() {
+  _injectJs();
+
+  group('indexOf', () {
+    var div = new DivElement();
+    var list = [3, 42, "foo", 42, div];
+    test('found', () {
+      expect(callIndexOf(list, 3), equals(0));
+      expect(callIndexOf(list, 42), equals(1));
+      expect(callIndexOf(list, "foo"), equals(2));
+      expect(callIndexOf(list, div), equals(4));
+    });
+
+    test('missing', () {
+      expect(callIndexOf(list, 31), equals(-1));
+      expect(callIndexOf(list, "42"), equals(-1));
+      expect(callIndexOf(list, null), equals(-1));
+    });
+  });
+
+  group('set length', () {
+    test('larger', () {
+      var list = ["a", "b", "c", "d"];
+      expect(callSetLength(list, 10), equals(10));
+      expect(list.length, equals(10));
+      expect(list.last, equals(null));
+      expect(list[3], equals("d"));
+    });
+
+    test('smaller', () {
+      var list = ["a", "b", "c", "d"];
+      expect(callSetLength(list, 2), equals(2));
+      expect(list.first, equals("a"));
+      expect(list.last, equals("b"));
+      expect(list.length, equals(2));
+      expect(callSetLength(list, 0), equals(0));
+      expect(list.length, equals(0));
+      expect(callSetLength(list, 2), equals(2));
+      expect(list.first, equals(null));
+    });
+
+    test('invalid', () {
+      var list = ["a", "b", "c", "d"];
+      expect(() => callSetLength(list, 2.3), throws);
+      expect(list.length, equals(4));
+      expect(() => callSetLength(list, -1), throws);
+      expect(list.length, equals(4));
+      // Make sure we are coercing to a JS number.
+      expect(callSetLength(list, "2"), equals("2"));
+      expect(list.length, equals(2));
+    });
+  });
+
+  group('join', () {
+    var list = [3, 42, "foo"];
+    var listWithDartClasses = [3, new Foo(), 42, "foo", new Object()];
+    test('default', () {
+      expect(callJsMethod(list, "join", []), equals("3,42,foo"));
+      expect(callJsMethod(listWithDartClasses, "join", []),
+          equals("3,${new Foo()},42,foo,${new Object()}"));
+    });
+
+    test('custom separator', () {
+      expect(callJsMethod(list, "join", ["##"]), equals("3##42##foo"));
+    });
+  });
+
+  group('lastIndexOf', () {
+    var list = [3, 42, "foo", 42];
+    test('found', () {
+      expect(callLastIndexOf(list, 3), equals(0));
+      expect(callLastIndexOf(list, 42), equals(3));
+      expect(callLastIndexOf(list, "foo"), equals(2));
+    });
+
+    test('missing', () {
+      expect(callLastIndexOf(list, 31), equals(-1));
+      expect(callLastIndexOf(list, "42"), equals(-1));
+      expect(callLastIndexOf(list, null), equals(-1));
+    });
+  });
+
+  group('pop', () {
+    test('all', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [3, 42, "foo", foo, div];
+      expect(callPop(list), equals(div));
+      expect(list.length, equals(4));
+      expect(callPop(list), equals(foo));
+      expect(list.length, equals(3));
+      expect(callPop(list), equals("foo"));
+      expect(list.length, equals(2));
+      expect(callPop(list), equals(42));
+      expect(list.length, equals(1));
+      expect(callPop(list), equals(3));
+      expect(list.length, equals(0));
+      expect(callPop(list), equals(null));
+      expect(list.length, equals(0));
+    });
+  });
+
+  group('push', () {
+    test('strings', () {
+      var list = [];
+      var div = new DivElement();
+      expect(callPush(list, "foo"), equals(1));
+      expect(callPush(list, "bar"), equals(2));
+      // Calling push with 0 elements should do nothing.
+      expect(callJsMethod(list, "push", []), equals(2));
+      expect(callPush(list, "baz"), equals(3));
+      expect(callPush(list, div), equals(4));
+      expect(callJsMethod(list, "push", ["a", "b"]), equals(6));
+      expect(list, equals(["foo", "bar", "baz", div, "a", "b"]));
+    });
+  });
+
+  group('shift', () {
+    test('all', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [3, 42, "foo", foo, div];
+      expect(callShift(list), equals(3));
+      expect(list.length, equals(4));
+      expect(callShift(list), equals(42));
+      expect(list.length, equals(3));
+      expect(callShift(list), equals("foo"));
+      expect(list.length, equals(2));
+      expect(callShift(list), equals(foo));
+      expect(list.length, equals(1));
+      expect(callShift(list), equals(div));
+      expect(list.length, equals(0));
+      expect(callShift(list), equals(null));
+      expect(list.length, equals(0));
+    });
+  });
+
+  group('reverse', () {
+    test('simple', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [div, 42, foo];
+      callReverse(list);
+      expect(list, equals([foo, 42, div]));
+      list = [3, 42];
+      callReverse(list);
+      expect(list, equals([42, 3]));
+    });
+  });
+
+  group('slice', () {
+    test('copy', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [3, 42, "foo", foo, div];
+      var copy = callJsMethod(list, "slice", []);
+      expect(identical(list, copy), isFalse);
+      expect(copy.length, equals(list.length));
+      for (var i = 0; i < list.length; i++) {
+        expect(list[i], equals(copy[i]));
+      }
+      expect(identical(list[3], copy[3]), isTrue);
+      expect(identical(list[4], copy[4]), isTrue);
+
+      copy.add("dummy");
+      expect(list.length + 1, equals(copy.length));
+    });
+
+    test('specify start', () {
+      var list = [3, 42, "foo"];
+      var copy = callJsMethod(list, "slice", [1]);
+      expect(copy.first, equals(42));
+    });
+
+    test('specify start and end', () {
+      var list = [3, 42, 92, "foo"];
+      var copy = callJsMethod(list, "slice", [1, 3]);
+      expect(copy.first, equals(42));
+      expect(copy.last, equals(92));
+    });
+
+    test('from end', () {
+      var list = [3, 42, 92, "foo"];
+      expect(callJsMethod(list, "slice", [-2]), equals([92, "foo"]));
+
+      // Past the end of the front of the array.
+      expect(callJsMethod(list, "slice", [-2, 3]), equals([92]));
+
+      // Past the end of the front of the array.
+      expect(callJsMethod(list, "slice", [-10, 2]), equals([3, 42]));
+    });
+  });
+
+  group("js snippet tests", () {
+    test("enumerate indices", () {
+      var list = ["a", "b", "c", "d"];
+      var indices = jsEnumerateIndices(list);
+      expect(indices.length, equals(4));
+      for (int i = 0; i < 4; i++) {
+        expect(indices[i], equals('$i'));
+      }
+    });
+
+    test("set element", () {
+      var list = ["a", "b", "c", "d"];
+      setValue(list, 0, 42);
+      expect(list[0], equals(42));
+      setValue(list, 1, 84);
+      expect(list[1], equals(84));
+      setValue(list, 6, 100); // Off the end of the list.
+      expect(list.length, equals(7));
+      expect(list[4], equals(null));
+      expect(list[6], equals(100));
+
+      // These tests have to be commented out because we don't persist
+      // JS proxies for Dart objects like we could/should.
+      // setValue(list, -1, "foo"); // Not a valid array index
+      // expect(getValue(list, -1), equals("foo"));
+      // expect(getValue(list, "-1"), equals("foo"));
+    });
+
+    test("get element", () {
+      var list = ["a", "b", "c", "d"];
+      expect(getValue(list, 0), equals("a"));
+      expect(getValue(list, 1), equals("b"));
+      expect(getValue(list, 6), equals(null));
+      expect(getValue(list, -1), equals(null));
+
+      expect(getValue(list, "0"), equals("a"));
+      expect(getValue(list, "1"), equals("b"));
+    });
+
+    test("is array", () {
+      var list = ["a", "b"];
+      expect(checkIsArray(list), isTrue);
+    });
+
+    test("property descriptors", () {
+      // This test matters to make behavior consistent with JS native arrays
+      // and to make devtools integration work well.
+      var list = ["a", "b"];
+      var descriptor = getOwnPropertyDescriptor(list, 0);
+
+      expect(descriptor.value, equals("a"));
+      expect(descriptor.writable, isTrue);
+      // TODO(jacobr): commented out until https://github.com/dart-lang/sdk/issues/26128
+      // is fixed.
+      // expect(descriptor.enumerable, isTrue);
+      // expect(descriptor.configurable, isTrue);
+
+      descriptor = getOwnPropertyDescriptor(list, "length");
+      expect(descriptor.value, equals(2));
+      expect(descriptor.writable, isTrue);
+      expect(descriptor.enumerable, isFalse);
+      expect(descriptor.configurable, isFalse);
+    });
+
+    test("concat js arrays", () {
+      var list = ["1", "2"];
+      // Tests that calling the concat method from JS will flatten out JS arrays
+      // We concat the array with "a", "b", ["c", "d"], 42, {foo: 10}
+      // which should generate ["1", "2", "a", "b", ["c", "d"], 42, {foo: 10}]
+      var ret = concatValues(list);
+      expect(list.length, equals(2));
+      expect(ret.length, equals(8));
+      expect(ret[0], equals("1"));
+      expect(ret[3], equals("b"));
+      expect(ret[5], equals("d"));
+      expect(ret[6], equals(42));
+      dynamic item = ret[7];
+      expect(item.foo, equals(10));
+    });
+
+    test("concat onto arrays", () {
+      // This test only passes if we have monkey patched the core Array object
+      // prototype to handle Dart Lists.
+      var list = ["a", "b"];
+      var ret = concatOntoArray(list);
+      expect(list.length, equals(2));
+      expect(ret, equals([1, 2, 3, "a", "b", "foo"]));
+    });
+
+    test("dart arrays on dart arrays", () {
+      // This test only passes if we have monkey patched the core Array object
+      // prototype to handle Dart Lists.
+      var list = ["a", "b"];
+      var ret = callJsMethod(list, "concat", [
+        ["c", "d"],
+        "e",
+        ["f", "g"]
+      ]);
+      expect(list.length, equals(2));
+      expect(ret, equals(["a", "b", "c", "d", "e", "f", "g"]));
+    });
+
+    test("every greater than zero", () {
+      expect(everyGreaterThanZero([1, 5]), isTrue);
+      expect(everyGreaterThanZeroCheckThisArg([1, 5]), isTrue);
+      expect(everyGreaterThanZero([1, 0]), isFalse);
+      expect(everyGreaterThanZero([]), isTrue);
+    });
+
+    test("filter greater than 42", () {
+      expect(filterGreater42([1, 5]), equals([]));
+      expect(filterGreater42([43, 5, 49]), equals([43, 49]));
+      expect(filterGreater42(["43", "5", "49"]), equals(["43", "49"]));
+    });
+
+    test("for each collect result", () {
+      expect(forEachCollectResult([1, 5, 7]), equals([2, 10, 14]));
+    });
+
+    test("some", () {
+      expect(someEqual42([1, 5, 9]), isFalse);
+      expect(someEqual42([1, 42, 9]), isTrue);
+    });
+
+    test("sort backwards", () {
+      var arr = [1, 5, 9];
+      var ret = sortNumbersBackwards(arr);
+      expect(identical(arr, ret), isTrue);
+      expect(ret, equals([9, 5, 1]));
+    });
+
+    test("splice dummy items", () {
+      var list = [1, 2, 3, 4];
+      var removed = spliceDummyItems(list);
+      expect(removed.length, equals(2));
+      expect(removed[0], equals(2));
+      expect(removed[1], equals(3));
+      expect(list.first, equals(1));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+      expect(list.last, equals(4));
+    });
+
+    test("splice string args", () {
+      var list = [1, 2, 3, 4];
+      var removed = spliceTestStringArgs(list);
+      expect(removed.length, equals(2));
+      expect(removed[0], equals(2));
+      expect(removed[1], equals(3));
+      expect(list.first, equals(1));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+      expect(list.last, equals(4));
+    });
+
+    test("splice pastEndOfArray", () {
+      var list = [1, 2, 3, 4];
+      var removed = splicePastEnd(list);
+      expect(removed.length, equals(3));
+      expect(list.first, equals(1));
+      expect(list.length, equals(4));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+    });
+
+    test("splice both bounds past end of array", () {
+      var list = [1];
+      var removed = splicePastEnd(list);
+      expect(removed.length, equals(0));
+      expect(list.first, equals(1));
+      expect(list.length, equals(4));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+    });
+
+    test("call List method on JavaScript object", () {
+      var jsObject = newLiteral();
+      callListMethodOnObject(jsObject, 'push', ["a"]);
+      callListMethodOnObject(jsObject, 'push', ["b"]);
+      callListMethodOnObject(jsObject, 'push', ["c", "d"]);
+      callListMethodOnObject(jsObject, 'push', []);
+
+      expect(json_helper.stringify(jsObject),
+          equals('{"0":"a","1":"b","2":"c","3":"d","length":4}'));
+
+      expect(callListMethodOnObject(jsObject, 'pop', []), equals("d"));
+      expect(callListMethodOnObject(jsObject, 'join', ["#"]), equals("a#b#c"));
+
+      var jsArray = newArray();
+      callListMethodOnObject(jsArray, 'push', ["a"]);
+      callListMethodOnObject(jsArray, 'push', ["b"]);
+      callListMethodOnObject(jsArray, 'push', ["c", "d"]);
+      callListMethodOnObject(jsArray, 'push', []);
+
+      expect(json_helper.stringify(jsArray), equals('["a","b","c","d"]'));
+    });
+  });
+
+  // This test group is disabled until we figure out an efficient way to
+  // distinguish between "array" Dart List types and non-array Dart list types.
+  /*
+  group('Non-array Lists', () {
+    test('opaque proxy', () {
+      // Dartium could easily support making LinkedList and all other classes
+      // implementing List behave like a JavaScript array but that would
+      // be challenging to implement in dart2js until browsers support ES6.
+      var list = ["a", "b", "c", "d"];
+      var listView = new UnmodifiableListView(list.getRange(1,3));
+      expect(listView is List, isTrue);
+      expect(listView.length, equals(2));
+      expect(checkIsArray(listView), isFalse);
+      expect(checkIsArray(listView.toList()), isTrue);
+      expect(getOwnPropertyDescriptor(
+          listView, "length"), equals(null));
+    });
+  });
+  */
+}
diff --git a/tests/lib/html/js_browser_test.dart b/tests/lib/html/js_browser_test.dart
new file mode 100644
index 0000000..8c0714b
--- /dev/null
+++ b/tests/lib/html/js_browser_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('Nodes are proxied', () {
+    var node = new JsObject.fromBrowserObject(new DivElement());
+    context.callMethod('addTestProperty', [node]);
+    expect(node is JsObject, isTrue);
+    // TODO(justinfagnani): make this work in IE9
+    // expect(node.instanceof(context['HTMLDivElement']), isTrue);
+    expect(node['testProperty'], 'test');
+  });
+
+  test('primitives throw ArgumentError', () {
+    for (var v in ['a', 1, 2.0, true]) {
+      expect(() => new JsObject.fromBrowserObject(v), throwsArgumentError);
+    }
+  });
+}
diff --git a/tests/lib/html/js_caching_test.dart b/tests/lib/html/js_caching_test.dart
new file mode 100644
index 0000000..62cfc52
--- /dev/null
+++ b/tests/lib/html/js_caching_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('JS->Dart', () {
+    // Test that we are not pulling cached proxy from the prototype
+    // when asking for a proxy for the object.
+    final proto = context['someProto'];
+    expect(proto['role'], equals('proto'));
+    final obj = context['someObject'];
+    expect(obj['role'], equals('object'));
+  });
+}
diff --git a/tests/lib/html/js_context_test.dart b/tests/lib/html/js_context_test.dart
new file mode 100644
index 0000000..426d121
--- /dev/null
+++ b/tests/lib/html/js_context_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('read global field', () {
+    expect(context['x'], equals(42));
+    expect(context['y'], isNull);
+  });
+
+  test('read global field with underscore', () {
+    expect(context['_x'], equals(123));
+    expect(context['y'], isNull);
+  });
+
+  test('write global field', () {
+    context['y'] = 42;
+    expect(context['y'], equals(42));
+  });
+}
diff --git a/tests/lib/html/js_dart_functions_test.dart b/tests/lib/html/js_dart_functions_test.dart
new file mode 100644
index 0000000..f4d20b1
--- /dev/null
+++ b/tests/lib/html/js_dart_functions_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('invoke Dart callback from JS', () {
+    expect(() => context.callMethod('invokeCallback'), throws);
+
+    context['callback'] = () => 42;
+    expect(context.callMethod('invokeCallback'), equals(42));
+
+    context.deleteProperty('callback');
+  });
+
+  test('pass a Dart function to JS and back', () {
+    var dartFunction = () => 42;
+    context['dartFunction'] = dartFunction;
+    expect(identical(context['dartFunction'], dartFunction), isTrue);
+    context.deleteProperty('dartFunction');
+  });
+
+  test('callback as parameter', () {
+    expect(context.callMethod('getTypeOf', [context['razzle']]),
+        equals("function"));
+  });
+
+  test('invoke Dart callback from JS with this', () {
+    // A JavaScript constructor function implemented in Dart which
+    // uses 'this'
+    final constructor = new JsFunction.withThis(($this, arg1) {
+      var t = $this;
+      $this['a'] = 42;
+    });
+    var o = new JsObject(constructor, ["b"]);
+    expect(o['a'], equals(42));
+  });
+
+  test('invoke Dart callback from JS with 11 parameters', () {
+    context['callbackWith11params'] =
+        (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) =>
+            '$p1$p2$p3$p4$p5$p6$p7$p8$p9$p10$p11';
+    expect(context.callMethod('invokeCallbackWith11params'),
+        equals('1234567891011'));
+  });
+
+  test('return a JS proxy to JavaScript', () {
+    var result = context.callMethod('testJsMap', [
+      () => new JsObject.jsify({'value': 42})
+    ]);
+    expect(result, 42);
+  });
+
+  test('emulated functions should not be callable in JS', () {
+    context['callable'] = new Callable();
+    expect(() => context.callMethod('callable'), throwsNoSuchMethodError);
+
+    Function f = new Callable();
+    context['callable'] = f;
+    expect(context.callMethod('callable'), 'called');
+    context.deleteProperty('callable');
+  });
+}
diff --git a/tests/lib/html/js_dart_js_test.dart b/tests/lib/html/js_dart_js_test.dart
new file mode 100644
index 0000000..2ad2a2e
--- /dev/null
+++ b/tests/lib/html/js_dart_js_test.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('Date', () {
+    context['o'] = new DateTime(1995, 12, 17);
+    var dateType = context['Date'];
+    expect(context.callMethod('isPropertyInstanceOf', ['o', dateType]), isTrue);
+    context.deleteProperty('o');
+  });
+
+  skipIE9_test('window', () {
+    context['o'] = window;
+    var windowType = context['Window'];
+    expect(
+        context.callMethod('isPropertyInstanceOf', ['o', windowType]), isTrue);
+    context.deleteProperty('o');
+  });
+
+  skipIE9_test('document', () {
+    context['o'] = document;
+    var documentType = context['Document'];
+    expect(context.callMethod('isPropertyInstanceOf', ['o', documentType]),
+        isTrue);
+    context.deleteProperty('o');
+  });
+
+  skipIE9_test('Blob', () {
+    var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
+    context['o'] = new Blob(fileParts, 'text/html');
+    var blobType = context['Blob'];
+    expect(context.callMethod('isPropertyInstanceOf', ['o', blobType]), isTrue);
+    context.deleteProperty('o');
+  });
+
+  test('unattached DivElement', () {
+    context['o'] = new DivElement();
+    var divType = context['HTMLDivElement'];
+    expect(context.callMethod('isPropertyInstanceOf', ['o', divType]), isTrue);
+    context.deleteProperty('o');
+  });
+
+  test('Event', () {
+    context['o'] = new CustomEvent('test');
+    var eventType = context['Event'];
+    expect(
+        context.callMethod('isPropertyInstanceOf', ['o', eventType]), isTrue);
+    context.deleteProperty('o');
+  });
+
+  test('KeyRange', () {
+    if (IdbFactory.supported) {
+      context['o'] = new KeyRange.only(1);
+      var keyRangeType = context['IDBKeyRange'];
+      expect(context.callMethod('isPropertyInstanceOf', ['o', keyRangeType]),
+          isTrue);
+      context.deleteProperty('o');
+    }
+  });
+
+  // this test fails in IE9 for very weird, but unknown, reasons
+  // the expression context['ImageData'] fails if useHtmlConfiguration()
+  // is called, or if the other tests in this file are enabled
+  skipIE9_test('ImageData', () {
+    var canvas = new CanvasElement();
+    var ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
+    context['o'] = ctx.createImageData(1, 1);
+    var imageDataType = context['ImageData'];
+    expect(context.callMethod('isPropertyInstanceOf', ['o', imageDataType]),
+        isTrue);
+    context.deleteProperty('o');
+  });
+
+  test('typed data: Int32List', () {
+    if (Platform.supportsTypedData) {
+      context['o'] = new Int32List.fromList([1, 2, 3, 4]);
+      var listType = context['Int32Array'];
+      // TODO(jacobr): make this test pass. Currently some type information
+      // is lost when typed arrays are passed between JS and Dart.
+      // expect(context.callMethod('isPropertyInstanceOf', ['o', listType]),
+      //    isTrue);
+      context.deleteProperty('o');
+    }
+  });
+}
diff --git a/tests/lib/html/js_dart_to_string_test.dart b/tests/lib/html/js_dart_to_string_test.dart
new file mode 100644
index 0000000..357b08d
--- /dev/null
+++ b/tests/lib/html/js_dart_to_string_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+@JS()
+library js_dart_to_string_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+
+  function jsToStringViaCoercion(a) {
+    return a + '';
+  };
+""");
+}
+
+@JS()
+external String jsToStringViaCoercion(obj);
+
+class ExampleClassWithCustomToString {
+  var x;
+  ExampleClassWithCustomToString(this.x);
+  String toString() => "#$x#";
+}
+
+main() {
+  _injectJs();
+
+  group('toString', () {
+    test('custom dart', () {
+      var x = new ExampleClassWithCustomToString("fooBar");
+      expect(jsToStringViaCoercion(x), equals("#fooBar#"));
+      expect(jsToStringViaCoercion({'a': 1, 'b': 2}), equals("{a: 1, b: 2}"));
+    });
+  });
+}
diff --git a/tests/lib/html/js_dispatch_property_test.dart b/tests/lib/html/js_dispatch_property_test.dart
new file mode 100644
index 0000000..3fbe2ea
--- /dev/null
+++ b/tests/lib/html/js_dispatch_property_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Test for dart2js initialization of dispatchPropertyName.
+
+import 'package:expect/minitest.dart';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+
+import 'js_dispatch_property_test_lib.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  group('group', () {
+    test('test', () {
+      // Force dynamic interceptor dispatch.
+      var a = confuse(create());
+      expect(a.foo('A'), equals('Foo A'));
+    });
+  });
+}
diff --git a/tests/lib/html/js_dispatch_property_test.html b/tests/lib/html/js_dispatch_property_test.html
new file mode 100644
index 0000000..8b7fc4b
--- /dev/null
+++ b/tests/lib/html/js_dispatch_property_test.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<--
+// 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.
+-->
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> js_type_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+</head>
+<body>
+  <h1> Running js_type_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/tests/lib/html/js_dispatch_property_test_js.js"></script>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/js_dispatch_property_test_js.js b/tests/lib/html/js_dispatch_property_test_js.js
new file mode 100644
index 0000000..0b159d6
--- /dev/null
+++ b/tests/lib/html/js_dispatch_property_test_js.js
@@ -0,0 +1,17 @@
+// 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.
+
+self.create = function() {
+  return {
+    // If the dispatch property name is uninitialized, it will be `undefined` or
+    // `null`, which will match these properties on dispatch record
+    // lookup. These properties map to malformed dispatch records to force an
+    // error.
+
+    'undefined': {p: false},
+    'null': {p: false},
+
+    foo: function(x) { return 'Foo ' + x; },
+  };
+}
\ No newline at end of file
diff --git a/tests/lib/html/js_dispatch_property_test_lib.dart b/tests/lib/html/js_dispatch_property_test_lib.dart
new file mode 100644
index 0000000..80a87a1
--- /dev/null
+++ b/tests/lib/html/js_dispatch_property_test_lib.dart
@@ -0,0 +1,17 @@
+// 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.
+
+@JS()
+library js_dispatch_property_test_lib;
+
+import 'package:js/js.dart';
+
+@JS()
+external A create();
+
+@JS()
+@anonymous
+class A {
+  external String foo(String x);
+}
diff --git a/tests/lib/html/js_extend_class_test.dart b/tests/lib/html/js_extend_class_test.dart
new file mode 100644
index 0000000..546a45a
--- /dev/null
+++ b/tests/lib/html/js_extend_class_test.dart
@@ -0,0 +1,63 @@
+// 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.
+
+@JS()
+library js_extend_class_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS('Date')
+class JSDate {
+  external get jsField;
+  external get jsMethod;
+}
+
+@JS('Date.prototype.jsField')
+external set datePrototypeJSField(v);
+
+@JS('Date.prototype.jsMethod')
+external set datePrototypeJSMethod(v);
+
+// Extending a JS class with a Dart class is only supported by DDC for now.
+// We extend the Date class instead of a user defined JS class to avoid the
+// hassle of ensuring the JS class exists before we use it.
+class DartJsDate extends JSDate {
+  get dartField => 100;
+  int dartMethod(x) {
+    return x * 2;
+  }
+}
+
+main() {
+  // Monkey-patch the JS Date class.
+  datePrototypeJSField = 42;
+  datePrototypeJSMethod = allowInterop((x) => x * 10);
+
+  group('extend js class', () {
+    test('js class members', () {
+      var bar = new DartJsDate();
+      expect(bar.jsField, equals(42));
+      expect(bar.jsMethod(5), equals(50));
+
+      expect(bar.dartField, equals(100));
+      expect(bar.dartMethod(4), equals(8));
+    });
+
+    test('instance checks and casts', () {
+      var bar = new DartJsDate();
+      expect(bar is JSDate, isTrue);
+      expect(bar as JSDate, equals(bar));
+    });
+
+    test('dart subclass members', () {
+      var bar = new DartJsDate();
+      expect(bar.dartField, equals(100));
+      expect(bar.dartMethod(4), equals(8));
+    });
+  });
+}
diff --git a/tests/lib/html/js_function_getter_test.dart b/tests/lib/html/js_function_getter_test.dart
new file mode 100644
index 0000000..d01e29b
--- /dev/null
+++ b/tests/lib/html/js_function_getter_test.dart
@@ -0,0 +1,105 @@
+// 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.
+
+@JS()
+library js_function_getter_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  var bar = { };
+
+  bar.instanceMember = function() {
+    if (this !== bar) {
+      throw 'Unexpected this!';
+    }
+    return arguments.length;
+  };
+
+  bar.staticMember = function() {
+    return arguments.length * 2;
+  };
+
+  bar.dynamicStatic = function() {
+    return arguments.length;
+  };
+
+  bar.add = function(a, b) {
+    return a + b;
+  };
+
+  var foo = { 'bar' : bar };
+""");
+}
+
+typedef int AddFn(int x, int y);
+
+@JS()
+abstract class Bar {
+  external Function get staticMember;
+  external Function get instanceMember;
+  external AddFn get add;
+  external get dynamicStatic;
+  external num get nonFunctionStatic;
+}
+
+@JS()
+abstract class Foo {
+  external Bar get bar;
+}
+
+@JS()
+external Foo get foo;
+
+main() {
+  _injectJs();
+
+  group('call getter as function', () {
+    test('member function', () {
+      expect(foo.bar.instanceMember(), equals(0));
+      expect(foo.bar.instanceMember(0), equals(1));
+      expect(foo.bar.instanceMember(0, 0), equals(2));
+      expect(foo.bar.instanceMember(0, 0, 0, 0, 0, 0), equals(6));
+      var instanceMember = foo.bar.instanceMember;
+      expect(() => instanceMember(), throws);
+      expect(() => instanceMember(0), throws);
+      expect(() => instanceMember(0, 0), throws);
+      expect(() => instanceMember(0, 0, 0, 0, 0, 0), throws);
+    });
+
+    test('static function', () {
+      expect(foo.bar.staticMember(), equals(0));
+      expect(foo.bar.staticMember(0), equals(2));
+      expect(foo.bar.staticMember(0, 0), equals(4));
+      expect(foo.bar.staticMember(0, 0, 0, 0, 0, 0), equals(12));
+      var staticMember = foo.bar.staticMember;
+      expect(staticMember(), equals(0));
+      expect(staticMember(0), equals(2));
+      expect(staticMember(0, 0), equals(4));
+      expect(staticMember(0, 0, 0, 0, 0, 0), equals(12));
+    });
+
+    test('static dynamicStatic', () {
+      expect(foo.bar.dynamicStatic(), equals(0));
+      expect(foo.bar.dynamicStatic(0), equals(1));
+      expect(foo.bar.dynamicStatic(0, 0), equals(2));
+      expect(foo.bar.dynamicStatic(0, 0, 0, 0, 0, 0), equals(6));
+      var dynamicStatic = foo.bar.dynamicStatic;
+      expect(dynamicStatic(), equals(0));
+      expect(dynamicStatic(0), equals(1));
+      expect(dynamicStatic(0, 0), equals(2));
+      expect(dynamicStatic(0, 0, 0, 0, 0, 0), equals(6));
+    });
+
+    test('typedef function', () {
+      expect(foo.bar.add(4, 5), equals(9));
+    });
+  });
+}
diff --git a/tests/lib/html/js_function_getter_trust_types/compile_test.dart b/tests/lib/html/js_function_getter_trust_types/compile_test.dart
new file mode 100644
index 0000000..9cbbe1f
--- /dev/null
+++ b/tests/lib/html/js_function_getter_trust_types/compile_test.dart
@@ -0,0 +1,52 @@
+// 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.
+
+// SharedOptions=--trust-type-annotations
+@JS()
+library js_function_getter_trust_types_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+import 'js_function_util.dart';
+
+main() {
+  injectJs();
+
+  foo.bar.nonFunctionStatic();
+//        ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+  foo.bar.nonFunctionStatic(0);
+//        ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+  foo.bar.nonFunctionStatic(0, 0);
+//        ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+  foo.bar.nonFunctionStatic(0, 0, 0, 0, 0, 0);
+//        ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+  foo.bar.add(4);
+  //         ^
+  // [cfe] Error: Too few positional arguments: 2 required, 1 given.
+  //         ^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+
+  foo.bar.add(4, 5, 10);
+  //         ^
+  // [cfe] Error: Too many positional arguments: 2 allowed, but 3 found.
+  //         ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+}
diff --git a/tests/lib/html/js_function_getter_trust_types/function_test.dart b/tests/lib/html/js_function_getter_trust_types/function_test.dart
new file mode 100644
index 0000000..5a49f47
--- /dev/null
+++ b/tests/lib/html/js_function_getter_trust_types/function_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--trust-type-annotations
+@JS()
+library js_function_getter_trust_types_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+import 'js_function_util.dart';
+
+main() {
+  injectJs();
+
+  Expect.equals(foo.bar.add(4, 5), 9);
+}
diff --git a/tests/lib/html/js_function_getter_trust_types/js_function_util.dart b/tests/lib/html/js_function_getter_trust_types/js_function_util.dart
new file mode 100644
index 0000000..2f89030
--- /dev/null
+++ b/tests/lib/html/js_function_getter_trust_types/js_function_util.dart
@@ -0,0 +1,48 @@
+// 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.
+
+// SharedOptions=--trust-type-annotations
+@JS()
+library js_function_getter_trust_types_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+
+injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  var bar = { };
+
+  bar.nonFunctionStatic = function() {
+    return arguments.length * 2;
+  };
+
+  bar.add = function(a, b) {
+    return a + b;
+  };
+
+  var foo = { 'bar' : bar };
+""");
+}
+
+typedef int AddFn(int x, int y);
+
+@JS()
+class NotAFn {}
+
+@JS()
+abstract class Bar {
+  external AddFn get add;
+  external NotAFn get nonFunctionStatic;
+}
+
+@JS()
+abstract class Foo {
+  external Bar get bar;
+}
+
+@JS()
+external Foo get foo;
diff --git a/tests/lib/html/js_identity_test.dart b/tests/lib/html/js_identity_test.dart
new file mode 100644
index 0000000..dadf6a9
--- /dev/null
+++ b/tests/lib/html/js_identity_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('context instances should be identical', () {
+    var c1 = context;
+    var c2 = context;
+    expect(identical(c1, c2), isTrue);
+  });
+
+  test('identical JS objects should have identical proxies', () {
+    var o1 = new JsObject(context['Foo'], [1]);
+    context['f1'] = o1;
+    var o2 = context['f1'];
+    expect(identical(o1, o2), isTrue);
+  });
+
+  test('identical Dart functions should have identical proxies', () {
+    var f1 = allowInterop(() => print("I'm a Function!"));
+    expect(context.callMethod('identical', [f1, f1]), isTrue);
+  });
+
+  test('identical JS functions should have identical proxies', () {
+    var f1 = context['Object'];
+    var f2 = context['Object'];
+    expect(identical(f1, f2), isTrue);
+  });
+
+  // TODO(justinfagnani): old tests duplicate checks above, remove
+  // on test next cleanup pass
+  test('test proxy equality', () {
+    var foo1 = new JsObject(context['Foo'], [1]);
+    var foo2 = new JsObject(context['Foo'], [2]);
+    context['foo1'] = foo1;
+    context['foo2'] = foo2;
+    expect(foo1, notEquals(context['foo2']));
+    expect(foo2, equals(context['foo2']));
+    context.deleteProperty('foo1');
+    context.deleteProperty('foo2');
+  });
+
+  test('retrieve same dart Object', () {
+    final obj = new Object();
+    context['obj'] = obj;
+    expect(context['obj'], same(obj));
+    context.deleteProperty('obj');
+  });
+}
diff --git a/tests/lib/html/js_interop_1_test.dart b/tests/lib/html/js_interop_1_test.dart
new file mode 100644
index 0000000..5f57dfb
--- /dev/null
+++ b/tests/lib/html/js_interop_1_test.dart
@@ -0,0 +1,32 @@
+// 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
+
+library JsInterop1Test;
+
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+import 'dart:html';
+
+injectSource(code) {
+  final script = new ScriptElement();
+  script.type = 'text/javascript';
+  script.innerHtml = code;
+  document.body!.append(script);
+}
+
+main() {
+  asyncTest(() async {
+    var subscription;
+    var completer = Completer<void>();
+    subscription = window.onMessage.listen((e) {
+      if (!completer.isCompleted && e.data == 'hello') {
+        completer.complete();
+        subscription.cancel();
+      }
+    });
+    injectSource("window.postMessage('hello', '*');");
+
+    await completer;
+  });
+}
diff --git a/tests/lib/html/js_interop_constructor_name/div_test.dart b/tests/lib/html/js_interop_constructor_name/div_test.dart
new file mode 100644
index 0000000..02a7826
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/div_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsTest;
+
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:js';
+import 'package:js/js.dart';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+import 'package:expect/minitest.dart';
+
+@JS()
+external makeDiv(String text);
+
+@JS()
+class HTMLDivElement {
+  external String bar();
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  test('dom-is-dom', () {
+    var e = confuse(new html.DivElement());
+    expect(e is html.DivElement, isTrue);
+  });
+
+  test('js-is-dom', () {
+    var e = confuse(makeDiv('hello'));
+    expect(e is html.DivElement, isFalse);
+  });
+
+  test('js-is-js', () {
+    var e = confuse(makeDiv('hello'));
+    expect(e is HTMLDivElement, isTrue);
+  });
+}
diff --git a/tests/lib/html/js_interop_constructor_name/div_test.html b/tests/lib/html/js_interop_constructor_name/div_test.html
new file mode 100644
index 0000000..7ef030a
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/div_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> div_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+</head>
+<body>
+  <h1> Running div_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/tests/lib/html/js_interop_constructor_name/test_js.js"></script>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/js_interop_constructor_name/error1_test.dart b/tests/lib/html/js_interop_constructor_name/error1_test.dart
new file mode 100644
index 0000000..bb27475
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/error1_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsTest;
+
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:js';
+import 'package:js/js.dart';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+import 'package:expect/minitest.dart';
+
+@JS()
+external makeDiv(String text);
+
+@JS()
+class HTMLDivElement {
+  external String bar();
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  test('dom-is-js', () {
+    var e = confuse(new html.DivElement());
+    // Currently, HTML types are not [JavaScriptObject]s. We could change that
+    // by having HTML types extend JavaScriptObject, in which case we would
+    // change this expectation.
+    expect(e is HTMLDivElement, isFalse);
+  });
+}
diff --git a/tests/lib/html/js_interop_constructor_name/error1_test.html b/tests/lib/html/js_interop_constructor_name/error1_test.html
new file mode 100644
index 0000000..7eb4631
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/error1_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> error1_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+</head>
+<body>
+  <h1> Running error1_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/tests/lib/html/js_interop_constructor_name/test_js.js"></script>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/js_interop_constructor_name/error2_test.dart b/tests/lib/html/js_interop_constructor_name/error2_test.dart
new file mode 100644
index 0000000..9fab532
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/error2_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsTest;
+
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:js';
+import 'package:js/js.dart';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+import 'package:expect/minitest.dart';
+
+@JS()
+external makeDiv(String text);
+
+@JS()
+class HTMLDivElement {
+  external String bar();
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  test('String-is-not-js', () {
+    var e = confuse('kombucha');
+    // A String should not be a JS interop type. The type test flags are added
+    // to Interceptor, but should be added to the class that implements all
+    // the JS-interop methods.
+    expect(e is HTMLDivElement, isFalse);
+  });
+}
diff --git a/tests/lib/html/js_interop_constructor_name/error2_test.html b/tests/lib/html/js_interop_constructor_name/error2_test.html
new file mode 100644
index 0000000..f05cdb4
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/error2_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> error2_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+</head>
+<body>
+  <h1> Running error2_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/tests/lib/html/js_interop_constructor_name/test_js.js"></script>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/js_interop_constructor_name/method_test.dart b/tests/lib/html/js_interop_constructor_name/method_test.dart
new file mode 100644
index 0000000..e881467
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/method_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsTest;
+
+import 'dart:async';
+import 'dart:html' as html;
+import 'dart:js';
+import 'package:js/js.dart';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic, Expect;
+import 'package:expect/minitest.dart';
+
+@JS()
+external makeDiv(String text);
+
+@JS()
+class HTMLDivElement {
+  external String bar();
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  test('js-call-js-method', () {
+    var e = confuse(makeDiv('hello'));
+    expect(e.bar(), equals('hello'));
+  });
+
+  test('dom-call-js-method', () {
+    var e = confuse(new html.DivElement());
+    expect(() => e.bar(), throws);
+  });
+
+  test('js-call-dom-method', () {
+    var e = confuse(makeDiv('hello'));
+    expect(() => e.clone(false), throws);
+  });
+
+  test('dom-call-dom-method', () {
+    var e = confuse(new html.DivElement());
+    Expect.type<html.DivElement>(e.clone(false));
+  });
+}
diff --git a/tests/lib/html/js_interop_constructor_name/method_test.html b/tests/lib/html/js_interop_constructor_name/method_test.html
new file mode 100644
index 0000000..a8a0173
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/method_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> method_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+</head>
+<body>
+  <h1> Running method_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/tests/lib/html/js_interop_constructor_name/test_js.js"></script>
+  <script type="text/javascript"
+      src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/lib/html/js_interop_constructor_name/test_js.js b/tests/lib/html/js_interop_constructor_name/test_js.js
new file mode 100644
index 0000000..828cbc9
--- /dev/null
+++ b/tests/lib/html/js_interop_constructor_name/test_js.js
@@ -0,0 +1,20 @@
+(function() {
+
+  // A constructor function with the same name as a HTML element.
+  function HTMLDivElement(a) {
+    this.a = a;
+  }
+
+  HTMLDivElement.prototype.bar = function() {
+    return this.a;
+  }
+
+  HTMLDivElement.prototype.toString = function() {
+    return "HTMLDivElement(" + this.a + ")";
+  }
+
+  self.makeDiv = function(text) {
+    return new HTMLDivElement(text);
+  };
+
+})();
diff --git a/tests/lib/html/js_javascript_function_test.dart b/tests/lib/html/js_javascript_function_test.dart
new file mode 100644
index 0000000..af9394e
--- /dev/null
+++ b/tests/lib/html/js_javascript_function_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:js';
+
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('is check', () {
+    var fn = (String s) => true;
+    var jsFn = allowInterop(fn);
+    expect(fn is StringToBool, isTrue);
+    expect(jsFn is StringToBool, isTrue);
+    expect(jsFn is Function, isTrue);
+    expect(jsFn is List, isFalse);
+  });
+}
diff --git a/tests/lib/html/js_jsarray_test.dart b/tests/lib/html/js_jsarray_test.dart
new file mode 100644
index 0000000..312e324
--- /dev/null
+++ b/tests/lib/html/js_jsarray_test.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('new JsArray()', () {
+    var array = new JsArray();
+    var arrayType = context['Array'];
+    expect(array.instanceof(arrayType), true);
+    expect(array, []);
+    // basic check that it behaves like a List
+    array.addAll([1, 2, 3]);
+    expect(array, [1, 2, 3]);
+  });
+
+  test('new JsArray.from()', () {
+    var array = new JsArray.from([1, 2, 3]);
+    var arrayType = context['Array'];
+    expect(array.instanceof(arrayType), true);
+    expect(array, [1, 2, 3]);
+  });
+
+  test('get Array from JS', () {
+    context['a'] = new JsObject(context['Array'], [1, 2, 3]);
+    expect(context.callMethod('isPropertyInstanceOf', ['a', context['Array']]),
+        isTrue);
+    var a = context['a'];
+    expect(a is JsArray, isTrue);
+    expect(a, [1, 2, 3]);
+    context.deleteProperty('a');
+  });
+
+  test('pass Array to JS', () {
+    context['a'] = [1, 2, 3];
+    var a = context['a'];
+    expect(a is List, isTrue);
+    expect(a is JsArray, isFalse);
+    expect(a, [1, 2, 3]);
+    context.deleteProperty('a');
+  });
+
+  test('[]', () {
+    var array = new JsArray.from([1, 2]);
+    expect(array[0], 1);
+    expect(array[1], 2);
+    expect(() => array[-1], throwsRangeError);
+    expect(() => array[2], throwsRangeError);
+  });
+
+  test('[]=', () {
+    var array = new JsArray<Object>.from([1, 2]);
+    array[0] = 'd';
+    array[1] = 'e';
+    expect(array, ['d', 'e']);
+    expect(() => array[-1] = 3, throwsRangeError);
+    expect(() => array[2] = 3, throwsRangeError);
+  });
+
+  test('length', () {
+    var array = new JsArray<int?>.from([1, 2, 3]);
+    expect(array.length, 3);
+    array.add(4);
+    expect(array.length, 4);
+    array.length = 2;
+    expect(array, [1, 2]);
+    array.length = 3;
+    expect(array, [1, 2, null]);
+  });
+
+  test('add', () {
+    var array = new JsArray();
+    array.add('a');
+    expect(array, ['a']);
+    array.add('b');
+    expect(array, ['a', 'b']);
+  });
+
+  test('addAll', () {
+    var array = new JsArray();
+    array.addAll(['a', 'b']);
+    expect(array, ['a', 'b']);
+    // make sure addAll can handle Iterables
+    array.addAll(new Set.from(['c']));
+    expect(array, ['a', 'b', 'c']);
+  });
+
+  test('insert', () {
+    var array = new JsArray.from([]);
+    array.insert(0, 'b');
+    expect(array, ['b']);
+    array.insert(0, 'a');
+    expect(array, ['a', 'b']);
+    array.insert(2, 'c');
+    expect(array, ['a', 'b', 'c']);
+    expect(() => array.insert(4, 'e'), throwsRangeError);
+    expect(() => array.insert(-1, 'e'), throwsRangeError);
+  });
+
+  test('removeAt', () {
+    var array = new JsArray.from(['a', 'b', 'c']);
+    expect(array.removeAt(1), 'b');
+    expect(array, ['a', 'c']);
+    expect(() => array.removeAt(2), throwsRangeError);
+    expect(() => array.removeAt(-1), throwsRangeError);
+  });
+
+  test('removeLast', () {
+    var array = new JsArray.from(['a', 'b', 'c']);
+    expect(array.removeLast(), 'c');
+    expect(array, ['a', 'b']);
+    array.length = 0;
+    expect(() => array.removeLast(), throwsRangeError);
+  });
+
+  test('removeRange', () {
+    var array = new JsArray.from(['a', 'b', 'c', 'd']);
+    array.removeRange(1, 3);
+    expect(array, ['a', 'd']);
+    expect(() => array.removeRange(-1, 2), throwsRangeError);
+    expect(() => array.removeRange(0, 3), throwsRangeError);
+    expect(() => array.removeRange(2, 1), throwsRangeError);
+  });
+
+  test('setRange', () {
+    var array = new JsArray.from(['a', 'b', 'c', 'd']);
+    array.setRange(1, 3, ['e', 'f']);
+    expect(array, ['a', 'e', 'f', 'd']);
+    array.setRange(3, 4, ['g', 'h', 'i'], 1);
+    expect(array, ['a', 'e', 'f', 'h']);
+  });
+
+  test('sort', () {
+    var array = new JsArray.from(['c', 'a', 'b']);
+    array.sort();
+    expect(array, ['a', 'b', 'c']);
+  });
+
+  test('sort with a Comparator', () {
+    var array = new JsArray.from(['c', 'a', 'b']);
+    array.sort((a, b) => -(a.compareTo(b)));
+    expect(array, ['c', 'b', 'a']);
+  });
+}
diff --git a/tests/lib/html/js_jsfunc_callmethod_test.dart b/tests/lib/html/js_jsfunc_callmethod_test.dart
new file mode 100644
index 0000000..374c4ad
--- /dev/null
+++ b/tests/lib/html/js_jsfunc_callmethod_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('new JsObject can return a JsFunction', () {
+    var f = new JsObject(context['Function']);
+    expect(f is JsFunction, isTrue);
+  });
+
+  test('JsFunction.apply on a function defined in JS', () {
+    expect(context['razzle'].apply([]), equals(42));
+  });
+
+  test('JsFunction.apply on a function that uses this', () {
+    var object = new Object();
+    expect(context['returnThis'].apply([], thisArg: object), same(object));
+  });
+
+  test('JsObject.callMethod on a function defined in JS', () {
+    expect(context.callMethod('razzle'), equals(42));
+    expect(() => context.callMethod('dazzle'), throwsNoSuchMethodError);
+  });
+
+  test('callMethod with many arguments', () {
+    expect(context.callMethod('varArgs', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
+        equals(55));
+  });
+
+  test('access a property of a function', () {
+    expect(context.callMethod('Bar'), "ret_value");
+    expect(context['Bar']['foo'], "property_value");
+  });
+/*
+ TODO(jacobr): evaluate whether we should be in the business of throwing
+ ArgumentError outside of checked mode. In unchecked mode this should just
+ return a NoSuchMethodError as the class lacks a method "true".
+
+    test('callMethod throws if name is not a String or num', () {
+      expect(() => context.callMethod(true),
+          throwsArgumentError);
+    });
+*/
+}
diff --git a/tests/lib/html/js_jsify_test.dart b/tests/lib/html/js_jsify_test.dart
new file mode 100644
index 0000000..4a59a1f
--- /dev/null
+++ b/tests/lib/html/js_jsify_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('convert a List', () {
+    final list = [1, 2, 3, 4, 5, 6, 7, 8];
+    var array = new JsObject.jsify(list);
+    expect(context.callMethod('isArray', [array]), isTrue);
+    expect(array['length'], equals(list.length));
+    for (var i = 0; i < list.length; i++) {
+      expect(array[i], equals(list[i]));
+    }
+  });
+
+  test('convert an Iterable', () {
+    final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]);
+    var array = new JsObject.jsify(set);
+    expect(context.callMethod('isArray', [array]), isTrue);
+    expect(array['length'], equals(set.length));
+    for (var i = 0; i < array['length']; i++) {
+      expect(set.contains(array[i]), isTrue);
+    }
+  });
+
+  test('convert a Map', () {
+    var map = {
+      'a': 1,
+      'b': 2,
+      'c': 3,
+      'd': allowInteropCaptureThis((that) => 42)
+    };
+    var jsMap = new JsObject.jsify(map);
+    expect(!context.callMethod('isArray', [jsMap]), isTrue);
+    for (final key in map.keys) {
+      expect(context.callMethod('checkMap', [jsMap, key, map[key]]), isTrue);
+    }
+  });
+
+  test('deep convert a complex object', () {
+    dynamic object = {
+      'a': [
+        1,
+        [2, 3]
+      ],
+      'b': {
+        'c': 3,
+        'd': new JsObject(context['Foo'], [42])
+      },
+      'e': null
+    };
+    var jsObject = new JsObject.jsify(object);
+    expect(jsObject['a'][0], equals(object['a'][0]));
+    expect(jsObject['a'][1][0], equals(object['a'][1][0]));
+    expect(jsObject['a'][1][1], equals(object['a'][1][1]));
+    expect(jsObject['b']['c'], equals(object['b']['c']));
+    expect(jsObject['b']['d'], equals(object['b']['d']));
+    expect(jsObject['b']['d'].callMethod('bar'), equals(42));
+    expect(jsObject['e'], isNull);
+  });
+
+  test('throws if object is not a Map or Iterable', () {
+    expect(() => new JsObject.jsify('a'), throwsArgumentError);
+  });
+}
diff --git a/tests/lib/html/js_jsobject_test.dart b/tests/lib/html/js_jsobject_test.dart
new file mode 100644
index 0000000..a718cb4
--- /dev/null
+++ b/tests/lib/html/js_jsobject_test.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('new Foo()', () {
+    var foo = new JsObject(context['Foo'], [42]);
+    expect(foo['a'], equals(42));
+    expect(foo.callMethod('bar'), equals(42));
+    expect(() => foo.callMethod('baz'), throwsNoSuchMethodError);
+  });
+
+  test('new container.Foo()', () {
+    final Foo2 = context['container']['Foo'];
+    final foo = new JsObject(Foo2, [42]);
+    expect(foo['a'], 42);
+    expect(Foo2['b'], 38);
+  });
+
+  test('new Array()', () {
+    var a = new JsObject(context['Array']);
+    expect(a is JsArray, isTrue);
+
+    // Test that the object still behaves via the base JsObject interface.
+    // JsArray specific tests are below.
+    expect(a['length'], 0);
+
+    a.callMethod('push', ["value 1"]);
+    expect(a['length'], 1);
+    expect(a[0], "value 1");
+
+    a.callMethod('pop');
+    expect(a['length'], 0);
+  });
+
+  test('new Date()', () {
+    final a = new JsObject(context['Date']);
+    expect(a.callMethod('getTime'), isNotNull);
+  });
+
+  test('new Date(12345678)', () {
+    final a = new JsObject(context['Date'], [12345678]);
+    expect(a.callMethod('getTime'), equals(12345678));
+  });
+
+  test('new Date("December 17, 1995 03:24:00 GMT")', () {
+    final a = new JsObject(context['Date'], ["December 17, 1995 03:24:00 GMT"]);
+    expect(a.callMethod('getTime'), equals(819170640000));
+  });
+
+  test('new Date(1995,11,17)', () {
+    // Note: JS Date counts months from 0 while Dart counts from 1.
+    final a = new JsObject(context['Date'], [1995, 11, 17]);
+    final b = new DateTime(1995, 12, 17);
+    expect(a.callMethod('getTime'), equals(b.millisecondsSinceEpoch));
+  });
+
+  test('new Date(1995,11,17,3,24,0)', () {
+    // Note: JS Date counts months from 0 while Dart counts from 1.
+    final a = new JsObject(context['Date'], [1995, 11, 17, 3, 24, 0]);
+    final b = new DateTime(1995, 12, 17, 3, 24, 0);
+    expect(a.callMethod('getTime'), equals(b.millisecondsSinceEpoch));
+  });
+
+  test('new Object()', () {
+    final a = new JsObject(context['Object']);
+    expect(a, isNotNull);
+
+    a['attr'] = "value";
+    expect(a['attr'], equals("value"));
+  });
+
+  test(r'new RegExp("^\w+$")', () {
+    final a = new JsObject(context['RegExp'], [r'^\w+$']);
+    expect(a, isNotNull);
+    expect(a.callMethod('test', ['true']), isTrue);
+    expect(a.callMethod('test', [' false']), isFalse);
+  });
+
+  test('js instantiation via map notation : new Array()', () {
+    final a = new JsObject(context['Array']);
+    expect(a, isNotNull);
+    expect(a['length'], equals(0));
+
+    a.callMethod('push', ["value 1"]);
+    expect(a['length'], equals(1));
+    expect(a[0], equals("value 1"));
+
+    a.callMethod('pop');
+    expect(a['length'], equals(0));
+  });
+
+  test('js instantiation via map notation : new Date()', () {
+    final a = new JsObject(context['Date']);
+    expect(a.callMethod('getTime'), isNotNull);
+  });
+
+  test('typed array', () {
+    if (Platform.supportsTypedData) {
+      // Safari's ArrayBuffer is not a Function and so doesn't support bind
+      // which JsObject's constructor relies on.
+      // bug: https://bugs.webkit.org/show_bug.cgi?id=122976
+      if (context['ArrayBuffer']['bind'] != null) {
+        final codeUnits = "test".codeUnits;
+        final buf = new JsObject(context['ArrayBuffer'], [codeUnits.length]);
+        final bufView = new JsObject(context['Uint8Array'], [buf]);
+        for (var i = 0; i < codeUnits.length; i++) {
+          bufView[i] = codeUnits[i];
+        }
+      }
+    }
+  });
+
+  test('>10 parameters', () {
+    final o = new JsObject(context['Baz'], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
+    for (var i = 1; i <= 11; i++) {
+      expect(o["f$i"], i);
+    }
+    expect(o['constructor'], equals(context['Baz']));
+  });
+}
diff --git a/tests/lib/html/js_methods_test.dart b/tests/lib/html/js_methods_test.dart
new file mode 100644
index 0000000..4c226a8
--- /dev/null
+++ b/tests/lib/html/js_methods_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('hashCode and ==', () {
+    final o1 = context['Object'];
+    final o2 = context['Object'];
+    expect(o1 == o2, isTrue);
+    expect(o1.hashCode == o2.hashCode, isTrue);
+    final d = context['document'];
+    expect(o1 == d, isFalse);
+  });
+
+  test('toString', () {
+    var foo = new JsObject(context['Foo'], [42]);
+    expect(foo.toString(), equals("I'm a Foo a=42"));
+    var container = context['container'];
+    expect(container.toString(), equals("[object Object]"));
+  });
+
+  test('toString returns a String even if the JS object does not', () {
+    var foo = new JsObject(context['Liar']);
+    expect(foo.callMethod('toString'), 1);
+    expect(foo.toString(), '1');
+  });
+
+  test('instanceof', () {
+    var foo = new JsObject(context['Foo'], [1]);
+    expect(foo.instanceof(context['Foo']), isTrue);
+    expect(foo.instanceof(context['Object']), isTrue);
+    expect(foo.instanceof(context['String']), isFalse);
+  });
+
+  test('deleteProperty', () {
+    var object = new JsObject.jsify({});
+    object['a'] = 1;
+    expect(context['Object'].callMethod('keys', [object])['length'], 1);
+    expect(context['Object'].callMethod('keys', [object])[0], "a");
+    object.deleteProperty("a");
+    expect(context['Object'].callMethod('keys', [object])['length'], 0);
+  });
+
+/* TODO(jacobr): this is another test that is inconsistent with JS semantics.
+  test('deleteProperty throws if name is not a String or num', () {
+    var object = new JsObject.jsify({});
+    expect(() => object.deleteProperty(true),
+        throwsArgumentError);
+  });
+*/
+
+  test('hasProperty', () {
+    var object = new JsObject.jsify({});
+    object['a'] = 1;
+    expect(object.hasProperty('a'), isTrue);
+    expect(object.hasProperty('b'), isFalse);
+  });
+
+/* TODO(jacobr): is this really the correct unchecked mode behavior?
+  test('hasProperty throws if name is not a String or num', () {
+    var object = new JsObject.jsify({});
+    expect(() => object.hasProperty(true),
+        throwsArgumentError);
+  });
+*/
+
+  test('[] and []=', () {
+    final myArray = context['myArray'];
+    expect(myArray['length'], equals(1));
+    expect(myArray[0], equals("value1"));
+    myArray[0] = "value2";
+    expect(myArray['length'], equals(1));
+    expect(myArray[0], equals("value2"));
+
+    final foo = new JsObject(context['Foo'], [1]);
+    foo["getAge"] = () => 10;
+    expect(foo.callMethod('getAge'), equals(10));
+  });
+
+/* TODO(jacobr): remove as we should only throw this in checked mode.
+  test('[] and []= throw if name is not a String or num', () {
+    var object = new JsObject.jsify({});
+    expect(() => object[true],
+        throwsArgumentError);
+    expect(() => object[true] = 1,
+        throwsArgumentError);
+  });
+*/
+}
diff --git a/tests/lib/html/js_mock_test.dart b/tests/lib/html/js_mock_test.dart
new file mode 100644
index 0000000..310abc9
--- /dev/null
+++ b/tests/lib/html/js_mock_test.dart
@@ -0,0 +1,67 @@
+// 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.
+
+@JS()
+library mock;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS('Node')
+class Node {}
+
+@JS('HTMLDocument')
+class Document extends Node {
+  external Element get body;
+}
+
+@JS()
+external get foo;
+
+@JS()
+external Document get document;
+
+@JS('Element')
+class Element extends Node {
+  external String get tagName;
+}
+
+class MockDocument implements Document {
+  final Element body = new MockElement();
+}
+
+class MockElement implements Element {
+  final tagName = 'MockBody';
+}
+
+void main() {
+  test('js', () {
+    var f = foo;
+    expect(f, isNull);
+
+    var doc = document;
+    expect(doc is Document, isTrue);
+    // Fails in dart2js
+    //expect(doc is! Element, isTrue);
+
+    expect(doc is Node, isTrue);
+
+    expect(doc is! MockDocument, isTrue);
+    expect(doc is! MockElement, isTrue);
+  });
+
+  test('mock', () {
+    var doc = new MockDocument();
+    expect(doc is Document, isTrue);
+    // Fails in dart2js
+    // expect(doc is! Element, isTrue);
+    expect(doc is Node, isTrue);
+
+    var body = doc.body;
+    // Fails in dart2js
+    // expect(body is! Document, isTrue);
+    expect(body is Element, isTrue);
+    expect(body is Node, isTrue);
+  });
+}
diff --git a/tests/lib/html/js_test_util.dart b/tests/lib/html/js_test_util.dart
new file mode 100644
index 0000000..e56887f
--- /dev/null
+++ b/tests/lib/html/js_test_util.dart
@@ -0,0 +1,228 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library TestJsUtils;
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:js';
+
+import 'package:expect/minitest.dart';
+
+injectJs() {
+  final script = new ScriptElement();
+  script.type = 'text/javascript';
+  script.innerHtml = r"""
+var x = 42;
+
+var _x = 123;
+
+var myArray = ["value1"];
+
+var foreignDoc = (function(){
+  var doc = document.implementation.createDocument("", "root", null);
+  var element = doc.createElement('element');
+  element.setAttribute('id', 'abc');
+  doc.documentElement.appendChild(element);
+  return doc;
+})();
+
+function razzle() {
+  return x;
+}
+
+function returnThis() {
+  return this;
+}
+
+function getTypeOf(o) {
+  return typeof(o);
+}
+
+function varArgs() {
+  var args = arguments;
+  var sum = 0;
+  for (var i = 0; i < args.length; ++i) {
+    sum += args[i];
+  }
+  return sum;
+}
+
+function Foo(a) {
+  this.a = a;
+}
+
+Foo.b = 38;
+
+Foo.prototype.bar = function() {
+  return this.a;
+}
+Foo.prototype.toString = function() {
+  return "I'm a Foo a=" + this.a;
+}
+
+var container = new Object();
+container.Foo = Foo;
+
+function isArray(a) {
+  return a instanceof Array;
+}
+
+function checkMap(m, key, value) {
+  if (m.hasOwnProperty(key))
+    return m[key] == value;
+  else
+    return false;
+}
+
+function invokeCallback() {
+  return callback();
+}
+
+function invokeCallbackWith11params() {
+  return callbackWith11params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+}
+
+function returnElement(element) {
+  return element;
+}
+
+function getElementAttribute(element, attr) {
+  return element.getAttribute(attr);
+}
+
+function addClassAttributes(list) {
+  var result = "";
+  for (var i=0; i < list.length; i++) {
+    result += list[i].getAttribute("class");
+  }
+  return result;
+}
+
+function getNewDate() {
+  return new Date(1995, 11, 17);
+}
+
+function getNewDivElement() {
+  return document.createElement("div");
+}
+
+function getNewEvent() {
+  return new CustomEvent('test');
+}
+
+function getNewBlob() {
+  var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
+  return new Blob(fileParts, {type : 'text/html'});
+}
+
+function getNewIDBKeyRange() {
+  return IDBKeyRange.only(1);
+}
+
+function getNewImageData() {
+  var canvas = document.createElement('canvas');
+  var context = canvas.getContext('2d');
+  return context.createImageData(1, 1);
+}
+
+function getNewInt32Array() {
+  return new Int32Array([1, 2, 3, 4, 5, 6, 7, 8]);
+}
+
+function getNewArrayBuffer() {
+  return new ArrayBuffer(8);
+}
+
+function isPropertyInstanceOf(property, type) {
+  return window[property] instanceof type;
+}
+
+function testJsMap(callback) {
+  var result = callback();
+  return result['value'];
+}
+
+function addTestProperty(o) {
+  o.testProperty = "test";
+}
+
+function fireClickEvent(w) {
+  var event = w.document.createEvent('Events');
+  event.initEvent('click', true, false);
+  w.document.dispatchEvent(event);
+}
+
+function Bar() {
+  return "ret_value";
+}
+Bar.foo = "property_value";
+
+function Baz(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) {
+  this.f1 = p1;
+  this.f2 = p2;
+  this.f3 = p3;
+  this.f4 = p4;
+  this.f5 = p5;
+  this.f6 = p6;
+  this.f7 = p7;
+  this.f8 = p8;
+  this.f9 = p9;
+  this.f10 = p10;
+  this.f11 = p11;
+}
+
+function Liar(){}
+
+Liar.prototype.toString = function() {
+  return 1;
+}
+
+function identical(o1, o2) {
+  return o1 === o2;
+}
+
+var someProto = { role: "proto" };
+var someObject = Object.create(someProto);
+someObject.role = "object";
+
+""";
+  document.body!.append(script);
+}
+
+typedef bool StringToBool(String s);
+
+// Some test are either causing other test to fail in IE9, or they are failing
+// for unknown reasons
+// useHtmlConfiguration+ImageData bug: dartbug.com/14355
+skipIE9_test(String description, t()) {
+  if (Platform.supportsTypedData) {
+    test(description, t);
+  }
+}
+
+class Foo {
+  final JsObject _proxy;
+
+  Foo(num a) : this._proxy = new JsObject(context['Foo'], [a]);
+
+  JsObject toJs() => _proxy;
+
+  num get a => _proxy['a'];
+  num bar() => _proxy.callMethod('bar');
+}
+
+class Color {
+  static final RED = new Color._("red");
+  static final BLUE = new Color._("blue");
+  String _value;
+  Color._(this._value);
+  String toJs() => this._value;
+}
+
+class TestDartObject {}
+
+class Callable {
+  call() => 'called';
+}
diff --git a/tests/lib/html/js_transferrables_test.dart b/tests/lib/html/js_transferrables_test.dart
new file mode 100644
index 0000000..46fcdcc
--- /dev/null
+++ b/tests/lib/html/js_transferrables_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+import 'dart:typed_data' show Int32List;
+import 'dart:js';
+
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+import 'js_test_util.dart';
+
+main() {
+  injectJs();
+
+  test('DateTime', () {
+    var date = context.callMethod('getNewDate');
+    expect(date is DateTime, isTrue);
+  });
+
+  test('window', () {
+    expect(context['window'] is Window, isTrue);
+  });
+
+  test('foreign browser objects should be proxied', () {
+    var iframe = new IFrameElement();
+    document.body!.children.add(iframe);
+    var proxy = new JsObject.fromBrowserObject(iframe);
+
+    // Window
+    var contentWindow = proxy['contentWindow'];
+    expect(contentWindow is! Window, isTrue);
+    expect(contentWindow is JsObject, isTrue);
+
+    // Node
+    var foreignDoc = contentWindow['document'];
+    expect(foreignDoc is! Node, isTrue);
+    expect(foreignDoc is JsObject, isTrue);
+
+    // Event
+    var clicked = false;
+    foreignDoc['onclick'] = (e) {
+      expect(e is! Event, isTrue);
+      expect(e is JsObject, isTrue);
+      clicked = true;
+    };
+
+    context.callMethod('fireClickEvent', [contentWindow]);
+    expect(clicked, isTrue);
+  });
+
+  test('foreign functions pass function is checks', () {
+    var iframe = new IFrameElement();
+    document.body!.children.add(iframe);
+    var proxy = new JsObject.fromBrowserObject(iframe);
+
+    var contentWindow = proxy['contentWindow'];
+    var foreignDoc = contentWindow['document'];
+
+    // Function
+    var foreignFunction = foreignDoc['createElement'];
+    expect(foreignFunction is JsFunction, isTrue);
+
+    // Verify that internal isChecks in callMethod work.
+    foreignDoc.callMethod('createElement', ['div']);
+
+    var typedContentWindow = js_util.getProperty(iframe, 'contentWindow');
+    var typedForeignDoc = js_util.getProperty(typedContentWindow, 'document');
+
+    var typedForeignFunction =
+        js_util.getProperty(typedForeignDoc, 'createElement');
+    expect(typedForeignFunction is Function, isTrue);
+    js_util.callMethod(typedForeignDoc, 'createElement', ['div']);
+  });
+
+  test('document', () {
+    expect(context['document'] is Document, isTrue);
+  });
+
+  skipIE9_test('Blob', () {
+    var blob = context.callMethod('getNewBlob');
+    expect(blob is Blob, isTrue);
+    expect(blob.type, equals('text/html'));
+  });
+
+  test('unattached DivElement', () {
+    var node = context.callMethod('getNewDivElement');
+    expect(node is DivElement, isTrue);
+  });
+
+  test('Event', () {
+    var event = context.callMethod('getNewEvent');
+    expect(event is Event, true);
+  });
+
+  test('KeyRange', () {
+    if (IdbFactory.supported) {
+      var node = context.callMethod('getNewIDBKeyRange');
+      expect(node is KeyRange, isTrue);
+    }
+  });
+
+  test('ImageData', () {
+    var node = context.callMethod('getNewImageData');
+    expect(node is ImageData, isTrue);
+  });
+
+  test('typed data: Int32Array', () {
+    if (Platform.supportsTypedData) {
+      var list = context.callMethod('getNewInt32Array');
+      print(list);
+      expect(list is Int32List, isTrue);
+      expect(list, equals([1, 2, 3, 4, 5, 6, 7, 8]));
+    }
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_anonymous2_exp_test.dart b/tests/lib/html/js_typed_interop_anonymous2_exp_test.dart
new file mode 100644
index 0000000..2c827b8
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_anonymous2_exp_test.dart
@@ -0,0 +1,54 @@
+// 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.
+
+// SharedOptions=--experimental-trust-js-interop-type-annotations
+
+// Same test as js_typed_interop_anonymous2, but using the
+// --experimental-trust-js-interop-type-annotations flag.
+@JS()
+library js_typed_interop_anonymous2_exp_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class A {
+  external factory A({B? b});
+
+  external B? get b;
+}
+
+@JS()
+@anonymous
+class B {
+  external factory B({C? c});
+
+  external C? get c;
+}
+
+@JS()
+@anonymous
+class C {
+  external factory C();
+}
+
+// D is unreachable, and that is OK
+@JS()
+@anonymous
+class D {
+  external factory D();
+}
+
+main() {
+  test('simple', () {
+    var b = new B();
+    var a = new A(b: b);
+    expect(a.b, equals(b));
+    expect(b.c, isNull);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_anonymous2_test.dart b/tests/lib/html/js_typed_interop_anonymous2_test.dart
new file mode 100644
index 0000000..a5b5302
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_anonymous2_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+@JS()
+library js_typed_interop_anonymous2_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class A {
+  external factory A({B? b});
+
+  external B? get b;
+}
+
+@JS()
+@anonymous
+class B {
+  external factory B({C? c});
+
+  external C? get c;
+}
+
+@JS()
+@anonymous
+class C {
+  external factory C();
+}
+
+// D is unreachable, and that is OK
+@JS()
+@anonymous
+class D {
+  external factory D();
+}
+
+main() {
+  test('simple', () {
+    var b = new B();
+    var a = new A(b: b);
+    expect(a.b, equals(b));
+    expect(b.c, isNull);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_anonymous_exp_test.dart b/tests/lib/html/js_typed_interop_anonymous_exp_test.dart
new file mode 100644
index 0000000..e160bdd
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_anonymous_exp_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+// SharedOptions=--experimental-trust-js-interop-type-annotations
+
+// Same test as js_typed_interop_anonymous, but using the
+// --experimental-trust-js-interop-type-annotations flag.
+@JS()
+library js_typed_interop_anonymous_exp_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class Literal {
+  external factory Literal({int? x, String? y, num? z});
+
+  external int? get x;
+  external String? get y;
+  external num? get z;
+}
+
+main() {
+  test('simple', () {
+    var l = new Literal(x: 3, y: "foo");
+    expect(l.x, equals(3));
+    expect(l.y, equals("foo"));
+    expect(l.z, isNull);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_anonymous_test.dart b/tests/lib/html/js_typed_interop_anonymous_test.dart
new file mode 100644
index 0000000..485f812
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_anonymous_test.dart
@@ -0,0 +1,69 @@
+// 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.
+
+@JS()
+library js_typed_interop_anonymous_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class Literal {
+  external factory Literal({int? x, String? y, num? z});
+
+  external set x(int? v);
+  external int? get x;
+  external String? get y;
+  external num? get z;
+}
+
+class MockLiteral implements Literal {
+  int? _v = 0;
+  set x(int? v) {
+    _v = v;
+  }
+
+  int? get x => _v;
+  String? get y => "";
+  num? get z => 1;
+}
+
+main() {
+  test('simple', () {
+    var l = new Literal(x: 3, y: "foo");
+    expect(l.x, equals(3));
+    expect(l.y, equals("foo"));
+    expect(l.z, isNull);
+  });
+
+  test('mock', () {
+    Literal l = new MockLiteral();
+    expect(l.x, equals(0));
+    l.x = 3;
+    expect(l.x, equals(3));
+    expect(l.y, equals(""));
+    expect(l.z, equals(1));
+  });
+
+  // Test that instance checks behave appropriately.
+  test('Instance checks: implements', () {
+    Object l = new Literal(x: 3, y: "foo");
+    Object m = new MockLiteral();
+    expect(m is Literal, isTrue);
+    expect(m is MockLiteral, isTrue);
+    expect(l is Literal, isTrue);
+    expect(l is MockLiteral, isFalse);
+  });
+
+  // Test that casts behave appropriately.
+  test('Casts: implements', () {
+    Object l = new Literal(x: 3, y: "foo");
+    Object m = new MockLiteral();
+    expect(m as Literal, equals(m));
+    expect(m as MockLiteral, equals(m));
+    expect(l as Literal, equals(l));
+    expect(() => l as MockLiteral, throws);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart b/tests/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart
new file mode 100644
index 0000000..046dcff
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// SharedOptions=--experimental-trust-js-interop-type-annotations
+
+// Same test as js_typed_interop_anonymous_unreachable, but using the
+// --experimental-trust-js-interop-type-annotations flag.
+@JS()
+library js_typed_interop_anonymous_unreachable_exp_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class Literal {
+  external factory Literal({required int x, required String y, required num z});
+
+  external int get x;
+  external String get y;
+  external num get z;
+}
+
+main() {
+  test('nothing to do', () {
+    // This test is empty, but it is a regression for Issue# 24974: dart2js
+    // would crash trying to compile code that used @anonymous and that was
+    // not reachable from main.
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_anonymous_unreachable_test.dart b/tests/lib/html/js_typed_interop_anonymous_unreachable_test.dart
new file mode 100644
index 0000000..e0dbaff
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_anonymous_unreachable_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+@JS()
+library js_typed_interop_anonymous_unreachable_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class Literal {
+  external factory Literal({required int x, required String y, required num z});
+
+  external int get x;
+  external String get y;
+  external num get z;
+}
+
+main() {
+  test('nothing to do', () {
+    // This test is empty, but it is a regression for Issue# 24974: dart2js
+    // would crash trying to compile code that used @anonymous and that was
+    // not reachable from main.
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_bind_this_test.dart b/tests/lib/html/js_typed_interop_bind_this_test.dart
new file mode 100644
index 0000000..a444043
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_bind_this_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+@JS()
+library js_typed_interop_bind_this_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+// This is a regression test for https://github.com/dart-lang/sdk/issues/25658
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  function JsTest() {
+  }
+
+  JsTest.returnThis = function(name, value) {
+    return this;
+  };
+""");
+}
+
+@JS('JsTest.returnThis')
+external returnThis([name, value]);
+
+@JS('JsTest')
+external get jsTestObject;
+
+@JS('window')
+external get jsWindow;
+
+main() {
+  _injectJs();
+
+  group('bind this', () {
+    test('simple', () {
+      expect(identical(returnThis(), jsWindow), isFalse);
+      expect(identical(returnThis(), null), isFalse);
+      expect(identical(returnThis(), jsTestObject), isTrue);
+    });
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_callable_object_test.dart b/tests/lib/html/js_typed_interop_callable_object_test.dart
new file mode 100644
index 0000000..659d2a91
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_callable_object_test.dart
@@ -0,0 +1,68 @@
+// 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.
+
+@JS()
+library js_typed_interop_callable_object_test;
+
+import 'dart:html';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+// This is a regression test for https://github.com/dart-lang/sdk/issues/25658
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  window.callableObject = function (a, b) { return a + b; };
+  window.callableObject.foo = function() { return "bar"; };
+  window.callableObject.bar = 42;
+
+""");
+}
+
+@JS()
+@anonymous
+class CallableObject {
+  /// If a @JS class implements `call`, the underlying representation must be
+  /// a JavaScript callable (i.e. function).
+  external num call(num a, num b);
+  external int get bar;
+  external String foo();
+}
+
+@JS()
+external CallableObject get callableObject;
+
+main() {
+  _injectJs();
+
+  group('callable object', () {
+    test('simple', () {
+      var obj = callableObject;
+      expect(obj(4, 5), equals(9));
+      expect(obj.bar, equals(42));
+      expect(obj.foo(), equals("bar"));
+
+      expect(callableObject(4, 5), equals(9));
+      expect(callableObject.bar, equals(42));
+      expect(callableObject.foo(), equals("bar"));
+    });
+
+    test('dynamic', () {
+      var obj = confuse(callableObject);
+      expect(obj(4, 5), equals(9));
+      expect(obj.bar, equals(42));
+      expect(obj.foo(), equals("bar"));
+    });
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_default_arg_static_test.dart b/tests/lib/html/js_typed_interop_default_arg_static_test.dart
new file mode 100644
index 0000000..5fbf41b
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_default_arg_static_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  var Foo = {
+    get42: function(b) { return arguments.length >= 1 ? b : 42; }
+  };
+""");
+}
+
+@JS()
+class Foo {
+  external static num get42([num? b = 3
+      // TODO(41375): This should be a static error. It's invalid to have a
+      // default value.
+      ]);
+}
+
+main() {
+  _injectJs();
+
+  test('call tearoff from dart with default', () {
+    var f = Foo.get42;
+    // Note: today both SSA and CPS remove the extra argument on static calls,
+    // but they fail to do so on tearoffs.
+    expect(f(), 3);
+    // TODO(41375): Remove this once the above is resolved. This is temporary
+    // to track this test failure.
+    throw ("This test should not execute. It should fail to compile above.");
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_default_arg_test.dart b/tests/lib/html/js_typed_interop_default_arg_test.dart
new file mode 100644
index 0000000..b309af5
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_default_arg_test.dart
@@ -0,0 +1,45 @@
+// 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.
+
+@JS()
+library js_typed_interop_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  var Foo = {
+    get42: function(b) { return arguments.length >= 1 ? b : 42; }
+  };
+""");
+}
+
+@JS()
+class Foo {
+  external static num get42([num? b]);
+}
+
+main() {
+  _injectJs();
+
+  test('call directly from dart', () {
+    expect(Foo.get42(2), 2);
+    expect(Foo.get42(), 42);
+  });
+
+  test('call tearoff from dart with arg', () {
+    var f = Foo.get42;
+    expect(f(2), 2);
+  });
+
+  test('call tearoff from dart with no arg', () {
+    var f = Foo.get42;
+    expect(f(), 42);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_dynamic_test.dart b/tests/lib/html/js_typed_interop_dynamic_test.dart
new file mode 100644
index 0000000..030c9c2
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_dynamic_test.dart
@@ -0,0 +1,55 @@
+// 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.
+
+@JS()
+library js_typed_interop_anonymous_test;
+
+import 'dart:html';
+import 'dart:js' as js;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class Literal {
+  external factory Literal({int? x, String? y, num? z, Function? foo});
+
+  external int? get x;
+  external String? get y;
+  external num? get z;
+  external Function? get foo;
+}
+
+@JS()
+@anonymous
+class FunctionWithExpando {
+  external int call();
+  external String get myExpando;
+}
+
+main() {
+  test('object', () {
+    dynamic l = new Literal(x: 3, y: 'foo', foo: allowInterop((x) => x * 2));
+    expect(l.x, equals(3));
+    expect(l.y, equals('foo'));
+    expect(l.z, isNull);
+    expect(l.foo(4), equals(8));
+  });
+
+  test('function', () {
+    // Get a JS function.
+    dynamic f = js_util.getProperty(window, 'addEventListener');
+    js_util.setProperty(f, 'myExpando', 'foo');
+    expect(f.myExpando, equals('foo'));
+  });
+
+  test('dart object', () {
+    dynamic o = new Object();
+    js_util.setProperty(o, 'x', 3);
+    expect(() => o.x, throwsNoSuchMethodError);
+    expect(() => o.foo(), throwsNoSuchMethodError);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_lazy_test.dart b/tests/lib/html/js_typed_interop_lazy_test.dart
new file mode 100644
index 0000000..98b26ff
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_lazy_test.dart
@@ -0,0 +1,285 @@
+// 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.
+
+@JS()
+library js_typed_interop_lazy_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS('someProperty')
+external get foo;
+
+@JS('baz.bar')
+external get bar;
+
+@JS('baz.LazyClass')
+class LazyClass {
+  external factory LazyClass(a);
+  external get a;
+}
+
+@JS('baz.foo.NestedLazyClass')
+class NestedLazyClass {
+  external factory NestedLazyClass(a);
+  external get a;
+}
+
+@anonymous
+@JS('some.bogus.ignored.js.path')
+class AnonClass {
+  external factory AnonClass({a});
+  external get a;
+}
+
+@anonymous
+@JS()
+class AnonClass2 {
+  external factory AnonClass2({b});
+  external get b;
+}
+
+abstract class Foo<T> {
+  T get obj;
+}
+
+class Mock1LazyClass implements LazyClass {
+  noSuchMethod(Invocation i) => i.memberName == #a ? 42 : null;
+}
+
+class Mock2LazyClass implements LazyClass {
+  get a => 42;
+}
+
+class Mock1NestedLazyClass implements NestedLazyClass {
+  noSuchMethod(Invocation i) => i.memberName == #a ? 42 : null;
+}
+
+class Mock2NestedLazyClass implements NestedLazyClass {
+  get a => 42;
+}
+
+class Other {
+  noSuchMethod(Invocation i) {}
+}
+
+// Test that the lazy JS classes can be used as a generic type argument.
+class FooImpl extends Foo<LazyClass> {
+  LazyClass get obj => new LazyClass(100);
+}
+
+class NestedFooImpl extends Foo<NestedLazyClass> {
+  NestedLazyClass get obj => new NestedLazyClass(100);
+}
+
+class ExampleGenericClass<T> {
+  String add(T foo) {
+    return foo.toString();
+  }
+}
+
+main() {
+  group('lazy property', () {
+    test('simple', () {
+      expect(foo, isNull);
+      js_util.setProperty(window, 'someProperty', 42);
+      expect(foo, equals(42));
+    });
+
+    test('nested', () {
+      js_util.setProperty(window, 'baz', js_util.newObject());
+      expect(bar, isNull);
+      js_util.setProperty(window, 'baz', js_util.jsify({'bar': 100}));
+      expect(bar, equals(100));
+    });
+  });
+
+  group('lazy class', () {
+    test('type literal', () {
+      // Fine because we can determine the class literals are equal without
+      // having to determine what (non-existant) JS type they correspond to.
+      var x = LazyClass;
+      var y = LazyClass;
+      expect(x == y, isTrue);
+    });
+
+    test('reference in type parameter', () {
+      var o = new FooImpl();
+      expect(o is Foo<LazyClass>, isTrue);
+    });
+
+    test('create instance', () {
+      var anon = new AnonClass(a: 42);
+      // Until LazyClass is defined, fall back to Anon behavior.
+      expect(anon is LazyClass, isTrue); //# 01: ok
+      expect(new Object() is! LazyClass, isTrue);
+
+      document.body!.append(new ScriptElement()
+        ..type = 'text/javascript'
+        ..innerHtml = r"""
+window.baz = {};
+
+baz.LazyClass = function LazyClass(a) {
+  this.a = a;
+};
+""");
+      var l = new LazyClass(42);
+      expect(l.a, equals(42));
+      expect(l is LazyClass, isTrue);
+      expect(l is AnonClass, isTrue);
+      expect((l as AnonClass) == l, isTrue);
+      expect((l as AnonClass2) == l, isTrue);
+      expect(anon is! LazyClass, isTrue); //# 01: ok
+      expect(anon is AnonClass, isTrue);
+      expect(anon is AnonClass2, isTrue);
+
+      // Sanity check that is and as are not broken.
+      expect(new Object() is! LazyClass, isTrue);
+      expect(new Object() is! AnonClass, isTrue);
+      expect(new Object() is! AnonClass2, isTrue);
+
+      expect(<AnonClass>[] is List<AnonClass>, isTrue);
+      // TODO(jacobr): why doesn't this test pass?
+      // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+      expect(<int>[] is! List<AnonClass>, isTrue);
+      expect(<AnonClass>[] is! List<LazyClass>, isTrue); //# 01: ok
+      expect(<int>[] is! List<LazyClass>, isTrue);
+      expect(<LazyClass>[] is List<LazyClass>, isTrue);
+
+      var listLazyClass = <LazyClass?>[];
+      Object instanceLazyObject = l;
+      expect(() => listLazyClass.add(42 as dynamic), throws); //# 01: ok
+      // Regression test for bug where this call failed.
+      listLazyClass.add(instanceLazyObject as LazyClass?);
+      listLazyClass.add(null);
+
+      dynamic listLazyClassDynamic = listLazyClass;
+      expect(() => listLazyClassDynamic.add(42), throws); //# 01: ok
+      // Regression test for bug where this call failed.
+      listLazyClassDynamic.add(instanceLazyObject);
+      listLazyClassDynamic.add(null);
+
+      var genericClass = new ExampleGenericClass<LazyClass?>();
+      genericClass.add(instanceLazyObject as LazyClass?);
+      expect(() => genericClass.add(42 as dynamic), throws); //# 01: ok
+      genericClass.add(null);
+
+      dynamic genericClassDynamic = genericClass;
+      genericClassDynamic.add(instanceLazyObject);
+      expect(() => genericClassDynamic.add(42), throws); //# 01: ok
+      genericClassDynamic.add(null);
+    });
+
+    test('mocks', () {
+      var mock1 = new Mock1LazyClass();
+      expect(mock1 is LazyClass, isTrue);
+      expect((mock1 as dynamic) as LazyClass, equals(mock1));
+      expect(mock1.a, equals(42));
+
+      var mock2 = new Mock2LazyClass();
+      expect(mock2 is LazyClass, isTrue);
+      expect((mock2 as dynamic) as LazyClass, equals(mock2));
+      expect(mock2.a, equals(42));
+
+      Object other = new Other();
+      expect(other is LazyClass, isFalse);
+    });
+  });
+
+  group('nested lazy class', () {
+    test('type literal', () {
+      // Fine because we can determine the class literals are equal without
+      // having to determine what (non-existant) JS type they correspond to.
+      var x = NestedLazyClass;
+      var y = NestedLazyClass;
+      expect(x == y, isTrue);
+    });
+
+    test('reference in type parameter', () {
+      var o = new NestedFooImpl();
+      expect(o is Foo<NestedLazyClass>, isTrue);
+    });
+
+    test('create instance', () {
+      var anon = new AnonClass(a: 42);
+      // Until NestedLazyClass is defined, fall back to Anon behavior.
+      expect(anon is NestedLazyClass, isTrue); //# 01: ok
+      expect(new Object() is! NestedLazyClass, isTrue);
+
+      document.body!.append(new ScriptElement()
+        ..type = 'text/javascript'
+        ..innerHtml = r"""
+window.baz = window.baz || {};
+window.baz.foo = {};
+
+baz.foo.NestedLazyClass = function NestedLazyClass(a) {
+  this.a = a;
+};
+""");
+      var l = new NestedLazyClass(42);
+      expect(l.a, equals(42));
+      expect(l is NestedLazyClass, isTrue);
+      expect(l is AnonClass, isTrue);
+      expect((l as AnonClass) == l, isTrue);
+      expect((l as AnonClass2) == l, isTrue);
+      expect(anon is! NestedLazyClass, isTrue); //# 01: ok
+      expect(anon is AnonClass, isTrue);
+      expect(anon is AnonClass2, isTrue);
+
+      // Sanity check that is and as are not broken.
+      expect(new Object() is! NestedLazyClass, isTrue);
+      expect(new Object() is! AnonClass, isTrue);
+      expect(new Object() is! AnonClass2, isTrue);
+
+      expect(<AnonClass>[] is List<AnonClass>, isTrue);
+      // TODO(jacobr): why doesn't this test pass?
+      // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+      expect(<int>[] is! List<AnonClass>, isTrue);
+      expect(<AnonClass>[] is! List<NestedLazyClass>, isTrue); //# 01: ok
+      expect(<int>[] is! List<NestedLazyClass>, isTrue);
+      expect(<NestedLazyClass>[] is List<NestedLazyClass>, isTrue);
+
+      var listLazyClass = <NestedLazyClass?>[];
+      Object instanceLazyObject = l;
+      expect(() => listLazyClass.add(42 as dynamic), throws); //# 01: ok
+      // Regression test for bug where this call failed.
+      listLazyClass.add(instanceLazyObject as NestedLazyClass?);
+      listLazyClass.add(null);
+
+      dynamic listLazyClassDynamic = listLazyClass;
+      expect(() => listLazyClassDynamic.add(42), throws); //# 01: ok
+      // Regression test for bug where this call failed.
+      listLazyClassDynamic.add(instanceLazyObject);
+      listLazyClassDynamic.add(null);
+
+      var genericClass = new ExampleGenericClass<NestedLazyClass?>();
+      genericClass.add(instanceLazyObject as NestedLazyClass?);
+      expect(() => genericClass.add(42 as dynamic), throws); //# 01: ok
+      genericClass.add(null);
+
+      dynamic genericClassDynamic = genericClass;
+      genericClassDynamic.add(instanceLazyObject);
+      expect(() => genericClassDynamic.add(42), throws); //# 01: ok
+      genericClassDynamic.add(null);
+    });
+
+    test('mocks', () {
+      var mock1 = new Mock1NestedLazyClass();
+      expect(mock1 is NestedLazyClass, isTrue);
+      expect((mock1 as dynamic) as NestedLazyClass, equals(mock1));
+      expect(mock1.a, equals(42));
+
+      var mock2 = new Mock2NestedLazyClass();
+      expect(mock2 is NestedLazyClass, isTrue);
+      expect((mock2 as dynamic) as NestedLazyClass, equals(mock2));
+      expect(mock2.a, equals(42));
+
+      Object other = new Other();
+      expect(other is NestedLazyClass, isFalse);
+    });
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_rename_static_test.dart b/tests/lib/html/js_typed_interop_rename_static_test.dart
new file mode 100644
index 0000000..48d6831
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_rename_static_test.dart
@@ -0,0 +1,95 @@
+// 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.
+
+@JS()
+library js_typed_interop_rename_static_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS('JSTopLevelField')
+external set topLevelFieldOnlySetter(v);
+
+@JS('JSTopLevelField')
+external get topLevelFieldOnlyGetter;
+
+@JS()
+external get topLevelFieldNoRename;
+
+@JS()
+external set topLevelSetterNoRename(v);
+
+@JS()
+external topLevelMethod(v);
+
+@JS('topLevelMethod')
+external renamedTopLevelMethod(v);
+
+@JS('JSFoo')
+class Foo {
+  @JS('JSBar')
+  external static get bar;
+
+  @JS('JSBar')
+  external static set bar(v);
+
+  @JS('JSBar2')
+  external static get bar2;
+
+  @JS('JSBaz')
+  external static set baz(v);
+
+  @JS('JSMethodAddBar')
+  external static addBar(a);
+}
+
+main() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+window.JSFoo = {
+  'JSBar': 42,
+  'JSBar2': 80,
+  'JSMethodAddBar': function(a,b) { return a + this.JSBar; }
+};
+window.JSTopLevelField = 91;
+window.topLevelFieldNoRename = 8;
+window.topLevelMethod = function(a) { return a * 2; };
+""");
+
+  group('rename static', () {
+    test('getter', () {
+      expect(Foo.bar, equals(42));
+      expect(Foo.bar2, equals(80));
+      expect(topLevelFieldOnlyGetter, 91);
+      expect(topLevelFieldNoRename, 8);
+    });
+
+    test('setter', () {
+      Foo.baz = 100;
+      expect(js_util.getProperty(js_util.getProperty(window, 'JSFoo'), 'JSBaz'),
+          equals(100));
+      Foo.bar = 30;
+      expect(Foo.bar, equals(30));
+      expect(js_util.getProperty(js_util.getProperty(window, 'JSFoo'), 'JSBar'),
+          equals(30));
+      topLevelFieldOnlySetter = 83;
+      expect(topLevelFieldOnlyGetter, 83);
+      topLevelSetterNoRename = 10;
+      expect(js_util.getProperty(window, 'topLevelSetterNoRename'), 10);
+    });
+
+    test('method', () {
+      Foo.bar = 100;
+      expect(Foo.addBar(10), equals(110));
+      Foo.bar = 200;
+      expect(Foo.addBar(10), equals(210));
+      expect(topLevelMethod(10), equals(20));
+      expect(renamedTopLevelMethod(10), equals(20));
+    });
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_side_cast_exp_test.dart b/tests/lib/html/js_typed_interop_side_cast_exp_test.dart
new file mode 100644
index 0000000..be112c8
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_side_cast_exp_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+// SharedOptions=--experimental-trust-js-interop-type-annotations
+
+// Similar test to js_typed_interop_side_cast, but because we are using the
+// --experimental-trust-js-interop-type-annotations flag, we test a slightly
+// different behavior.
+@JS()
+library js_typed_interop_side_cast_exp_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class A {
+  external int get x;
+  external factory A({required int x});
+}
+
+@JS()
+@anonymous
+class B {
+  external int get x;
+  external factory B({required int x});
+}
+
+@JS()
+@anonymous
+class C {
+  external int get x;
+  external factory C({required int x});
+}
+
+main() {
+  test('side-casts work for reachable types', () {
+    new C(x: 3); // make C reachable
+    dynamic a = new A(x: 3);
+    expect(a is C, isTrue);
+    C c = a;
+    expect(c.x, equals(3));
+  });
+
+  // Note: this test would fail without the experimental flag.
+  test('side-casts do not work for unreachable types', () {
+    dynamic a = new A(x: 3);
+    expect(a is B, isFalse); //# 01: ok
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_side_cast_test.dart b/tests/lib/html/js_typed_interop_side_cast_test.dart
new file mode 100644
index 0000000..c222073
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_side_cast_test.dart
@@ -0,0 +1,45 @@
+// 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.
+
+@JS()
+library js_typed_interop_anonymous2_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+@anonymous
+class A {
+  external int get x;
+  external factory A({required int x});
+}
+
+@JS()
+@anonymous
+class C {
+  external int get x;
+  external factory C({required int x});
+}
+
+@JS()
+@anonymous
+class B {
+  external int get x;
+  external factory B({required int x});
+}
+
+main() {
+  test('side-casts work for reachable types', () {
+    new C(x: 3); // make C reachable
+    dynamic a = new A(x: 3);
+    expect(a is C, isTrue);
+    C c = a;
+    expect(c.x, equals(3));
+  });
+
+  test('side-casts work for otherwise unreachable types', () {
+    dynamic a = new A(x: 3);
+    expect(a is B, isTrue);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_test.dart b/tests/lib/html/js_typed_interop_test.dart
new file mode 100644
index 0000000..3ee46e0
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_test.dart
@@ -0,0 +1,459 @@
+// 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.
+
+@JS()
+library js_typed_interop_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  var Foo = {
+    multiplyDefault2: function(a, b) {
+      if (arguments.length >= 2) return a *b;
+      return a * 2;
+    }
+  };
+
+  var foo = {
+    x: 3,
+    z: 40, // Not specified in typed Dart API so should fail in checked mode.
+    multiplyByX: function(arg) { return arg * this.x; },
+    // This function can be torn off without having to bind this.
+    multiplyBy2: function(arg) { return arg * 2; },
+    multiplyDefault2Function: function(a, b) {
+      if (arguments.length >= 2) return a * b;
+      return a * 2;
+    },
+    callClosureWithArg1: function(closure, arg) {
+      return closure(arg);
+    },
+    callClosureWithArg2: function(closure, arg1, arg2) {
+      return closure(arg1, arg2);
+    },
+    callClosureWithArgAndThis: function(closure, arg) {
+      return closure.apply(this, [arg]);
+    },
+
+    getBar: function() {
+      return bar;
+    }
+  };
+
+  var foob = {
+    x: 8,
+    y: "why",
+    multiplyByX: function(arg) { return arg * this.x; }
+  };
+
+  var bar = {
+    x: "foo",
+    multiplyByX: true,
+    getFoo: function() {
+      return foo;
+    }
+  };
+
+  function ClassWithConstructor(a, b) {
+    this.a = a;
+    this.b = b;
+  };
+
+  ClassWithConstructor.prototype = {
+    getA: function() { return this.a;}
+  };
+
+  var selection = ["a", "b", "c", foo, bar];
+
+  function returnNumArgs() { return arguments.length; };
+  function returnLastArg() { return arguments[arguments.length-1]; };
+
+  function confuse(obj) { return obj; }
+
+  function isUndefined(obj) { return obj === void 0; }
+
+  function StringWrapper(str) {
+    this.str = str;
+  }
+  StringWrapper.prototype = {
+    charCodeAt: function(index) {
+      return this.str.charCodeAt(index);
+    }
+  };
+  function getCanvasContext() {
+    return document.createElement('canvas').getContext('2d');
+  }
+  window.windowProperty = 42;
+  document.documentProperty = 45;
+""");
+}
+
+class RegularClass {
+  factory RegularClass(a) {
+    return new RegularClass.fooConstructor(a);
+  }
+  RegularClass.fooConstructor(this.a);
+  var a;
+}
+
+@JS()
+class ClassWithConstructor {
+  external ClassWithConstructor(aParam, bParam);
+  external getA();
+  external get a;
+  external get b;
+}
+
+@JS('ClassWithConstructor')
+class ClassWithFactory {
+  external factory ClassWithFactory(aParam, bParam);
+  external getA();
+  external get a;
+  external get b;
+}
+
+typedef num MultiplyWithDefault(num a, [num? b]);
+
+@JS()
+@anonymous
+class Foo {
+  external int get x;
+  external set x(int v);
+  external num multiplyByX(num y);
+  external num multiplyBy2(num y);
+  external MultiplyWithDefault get multiplyDefault2Function;
+
+  external callClosureWithArgAndThis(Function closure, arg);
+  external callClosureWithArg1(Function closure, arg1);
+  external callClosureWithArg2(Function closure, arg1, arg2);
+  external Bar getBar();
+
+  external static num multiplyDefault2(num a, [num? b]);
+}
+
+@anonymous
+@JS()
+class ExampleLiteral {
+  external factory ExampleLiteral({int? x, String? y, num? z});
+
+  external int? get x;
+  external String? get y;
+  external num? get z;
+}
+
+@anonymous
+@JS()
+class EmptyLiteral {
+  external factory EmptyLiteral();
+}
+
+@JS('Foob')
+class Foob extends Foo {
+  external String get y;
+}
+
+@JS('Bar')
+class Bar {
+  external String get x;
+  external bool get multiplyByX;
+  external Foo getFoo();
+}
+
+// No @JS is required for these external methods as the library is
+// annotated with Js.
+external Foo get foo;
+external Foob get foob;
+external Bar get bar;
+external Selection get selection;
+
+addWithDefault(a, [b = 100]) => a + b;
+
+external Function get returnNumArgs;
+external Function get returnLastArg;
+
+const STRINGIFY_LOCATION = "JSON.stringify";
+@JS(STRINGIFY_LOCATION)
+external String stringify(obj);
+
+@JS()
+class StringWrapper {
+  external StringWrapper(String str);
+  external int charCodeAt(int i);
+}
+
+// Defeat JS type inference by calling through JavaScript interop.
+@JS()
+external confuse(obj);
+
+@JS()
+external isUndefined(obj);
+
+@JS()
+external CanvasRenderingContext2D getCanvasContext();
+
+@JS('window.window.document.documentProperty')
+external num get propertyOnDocument;
+
+@JS('window.self.window.window.windowProperty')
+external num get propertyOnWindow;
+
+class DartClassWithNullField {
+  int? x;
+}
+
+main() {
+  _injectJs();
+
+  group('object literal', () {
+    test('simple', () {
+      var l = new ExampleLiteral(x: 3, y: "foo");
+      expect(l.x, equals(3));
+      expect(l.y, equals("foo"));
+      expect(l.z, isNull);
+      expect(stringify(l), equals('{"x":3,"y":"foo"}'));
+      var l2 = new ExampleLiteral(y: "foo", x: 3);
+      expect(l2.x, equals(l.x));
+      expect(l2.y, equals(l.y));
+      l = new ExampleLiteral(z: 100);
+      expect(l.x, isNull);
+      expect(l.y, isNull);
+      expect(l.z, equals(100));
+      expect(stringify(l), equals('{"z":100}'));
+    });
+
+    test('empty', () {
+      var l = new EmptyLiteral();
+      expect(stringify(l), equals('{}'));
+    });
+  });
+
+  group('constructor', () {
+    test('simple', () {
+      var o = new ClassWithConstructor("foo", "bar");
+      expect(o.a, equals("foo"));
+      expect(o.b, equals("bar"));
+      expect(o.getA(), equals("foo"));
+    });
+
+    test('external factory', () {
+      var o = new ClassWithFactory("foo", "bar");
+      expect(o.a, equals("foo"));
+      expect(o.b, equals("bar"));
+      expect(o.getA(), equals("foo"));
+    });
+  });
+
+  group('property', () {
+    test('get', () {
+      expect(foo.x, equals(3));
+      expect(foob.x, equals(8));
+      expect(foob.y, equals("why"));
+
+      // Exists in JS but not in API.
+      // TODO(29419): add back this line once the appropriate metadata is
+      // tracked for anonymous JS classes (DARTBUG.
+      // expect(() => (foo as dynamic).zSomeInvalidName, throws);
+      expect(bar.multiplyByX, isTrue);
+    });
+    test('set', () {
+      foo.x = 42;
+      expect(foo.x, equals(42));
+      // Property tagged as read only in typed API.
+      // TODO(29419): add back this line once the appropriate metadata is
+      // tracked for anonymous JS classes.
+      // expect(() => (foob as dynamic).y = "bla", throws);
+      // expect(() => (foo as dynamic).unknownName = 42, throws);
+    });
+  });
+
+  group('method', () {
+    test('call', () {
+      foo.x = 100;
+      expect(foo.multiplyByX(4), equals(400));
+      foob.x = 10;
+      expect(foob.multiplyByX(4), equals(40));
+    });
+
+    test('tearoff', () {
+      foo.x = 10;
+      Function multiplyBy2 = foo.multiplyBy2;
+      expect(multiplyBy2(5), equals(10));
+      foo.x = 73;
+      Function multiplyByX = foo.multiplyByX;
+      // Tearing off a JS closure doesn't bind this.
+      // You will need to use the new method tearoff syntax to bind this.
+      // Invoking will trigger an error throwing because "this is undefined".
+      expect(() => multiplyByX(4), throws);
+
+      MultiplyWithDefault multiplyWithDefault = foo.multiplyDefault2Function;
+      expect(multiplyWithDefault(6, 6), equals(36));
+      expect(multiplyWithDefault(6), equals(12));
+      Function untypedFunction = foo.multiplyDefault2Function;
+      // Calling with extra bogus arguments has no impact for JavaScript
+      // methods.
+      expect(untypedFunction(6, 6, "ignored", "ignored"), equals(36));
+      expect(
+          untypedFunction(6, 6, "ignored", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+          equals(36));
+      // Calling a JavaScript method with too few arguments is also fine and
+      // defaults to JavaScript behavior of setting all unspecified arguments
+      // to undefined resulting in multiplying undefined by 2 == NAN.
+      expect(untypedFunction().toString(), equals(double.nan.toString()));
+    });
+  });
+
+  group('static_method_call', () {
+    test('call directly from dart', () {
+      expect(Foo.multiplyDefault2(6, 7), equals(42));
+      expect(Foo.multiplyDefault2(6), equals(12));
+    });
+  });
+
+  // Note: these extra groups are added to be able to mark each test
+  // individually in status files. This should be split as separate test files.
+  group('static_method_tearoff_1', () {
+    test('call tearoff from dart', () {
+      MultiplyWithDefault tearOffMethod = Foo.multiplyDefault2;
+      expect(tearOffMethod(6, 6), equals(36));
+    });
+  });
+
+  group('static_method_tearoff_2', () {
+    test('call tearoff from dart', () {
+      MultiplyWithDefault tearOffMethod = Foo.multiplyDefault2;
+      expect(tearOffMethod(6), equals(12));
+    });
+  });
+
+  group('closure', () {
+    test('call from js', () {
+      localClosure(x) => x * 10;
+      var wrappedLocalClosure = allowInterop(localClosure);
+      var wrappedLocalClosure2 = allowInterop(localClosure);
+      expect(identical(wrappedLocalClosure2, wrappedLocalClosure), isTrue);
+      expect(foo.callClosureWithArg1(wrappedLocalClosure, 10), equals(100));
+      expect(foo.callClosureWithArg1(wrappedLocalClosure, "a"),
+          equals("aaaaaaaaaa"));
+      expect(foo.callClosureWithArg1(allowInterop(addWithDefault), 10),
+          equals(110));
+      expect(foo.callClosureWithArg2(allowInterop(addWithDefault), 10, 20),
+          equals(30));
+      addThisXAndArg(Foo that, int arg) {
+        return foo.x + arg;
+      }
+
+      dynamic wrappedCaptureThisClosure =
+          allowInteropCaptureThis(addThisXAndArg);
+      expect(wrappedCaptureThisClosure is Function, isTrue);
+      expect(wrappedCaptureThisClosure is Map, isFalse);
+      expect(wrappedCaptureThisClosure is Object, isTrue);
+      foo.x = 20;
+      expect(foo.callClosureWithArgAndThis(wrappedCaptureThisClosure, 10),
+          equals(30));
+      foo.x = 50;
+      expect(foo.callClosureWithArgAndThis(wrappedCaptureThisClosure, 10),
+          equals(60));
+      expect(
+          identical(allowInteropCaptureThis(addThisXAndArg),
+              wrappedCaptureThisClosure),
+          isTrue);
+
+      ExampleLiteral addXValues(that, ExampleLiteral arg) {
+        return new ExampleLiteral(x: that.x + arg.x);
+      }
+
+      // Check to make sure returning a JavaScript value from a Dart closure
+      // works as expected.
+      expect(
+          foo
+              .callClosureWithArg2(allowInterop(addXValues),
+                  new ExampleLiteral(x: 20), new ExampleLiteral(x: 10))
+              .x,
+          equals(30));
+
+      foo.x = 50;
+      expect(
+          foo
+              .callClosureWithArgAndThis(allowInteropCaptureThis(addXValues),
+                  new ExampleLiteral(x: 10))
+              .x,
+          equals(60));
+    });
+
+    test('call from dart', () {
+      var returnNumArgsFn = returnNumArgs;
+      var returnLastArgFn = returnLastArg;
+      expect(returnNumArgsFn(), equals(0));
+      expect(returnNumArgsFn("a", "b", "c"), equals(3));
+      expect(returnNumArgsFn("a", "b", "c", null, null), equals(5));
+      expect(returnNumArgsFn(1, 2, 3, 4, 5, 6, null), equals(7));
+      expect(returnNumArgsFn(1, 2, 3, 4, 5, 6, 7, 8), equals(8));
+      expect(returnLastArgFn(1, 2, "foo"), equals("foo"));
+      expect(returnLastArgFn(1, 2, 3, 4, 5, 6, "foo"), equals("foo"));
+    });
+  });
+
+  group('chain calls', () {
+    test("method calls", () {
+      // In dart2js make sure we still use interceptors when making nested
+      // calls to objects.
+      var bar = foo.getBar().getFoo().getBar().getFoo().getBar();
+      expect(bar.x, equals("foo"));
+    });
+  });
+
+  group('avoid leaks on dart:core', () {
+    test('String', () {
+      var s = confuse('Hello');
+      var stringWrapper = confuse(new StringWrapper('Hello'));
+      // Make sure we don't allow calling JavaScript methods on String.
+      expect(() => s.charCodeAt(0), throws);
+      expect(stringWrapper.charCodeAt(0), equals(72));
+    });
+  });
+
+  group('type check', () {
+    test('js interfaces', () {
+      // Is checks return true for all anonymous JS interfaces.
+      dynamic dartObject = new Object();
+      expect(foo is Foo, isTrue);
+      expect(foo is ExampleLiteral, isTrue);
+
+      expect(dartObject is Foo, isFalse);
+      expect(dartObject is ExampleLiteral, isFalse);
+
+      expect(selection is List, isTrue);
+
+      // We do know at runtime whether something is a JsArray or not.
+      expect(foo is List, isFalse);
+    });
+
+    test('dart interfaces', () {
+      expect(foo is Function, isFalse);
+      expect(selection is List, isTrue);
+    });
+  });
+
+  group('html', () {
+    test('return html type', () {
+      expect(getCanvasContext() is CanvasRenderingContext2D, isTrue);
+    });
+    test('js path contains html types', () {
+      expect(propertyOnWindow, equals(42));
+      expect(propertyOnDocument, equals(45));
+    });
+  });
+
+  test('Dart field is null instead of undefined', () {
+    expect(isUndefined(new DartClassWithNullField().x), false);
+  });
+}
diff --git a/tests/lib/html/js_typed_interop_type1_test.dart b/tests/lib/html/js_typed_interop_type1_test.dart
new file mode 100644
index 0000000..e85bce1
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_type1_test.dart
@@ -0,0 +1,53 @@
+// 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.
+
+@JS()
+library js_typed_interop_type1_test;
+
+import 'dart:html';
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+class A {
+  external get foo;
+
+  external A(var foo);
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+@pragma('dart2js:noInline')
+testA(A o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testF(F o) {
+  return o.foo;
+}
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+function A(foo) {
+  this.foo = foo;
+}
+""");
+}
+
+main() {
+  _injectJs();
+
+  var a = new A(1);
+  var f = new F(6);
+
+  Expect.equals(testA(a), 1);
+  Expect.equals(testF(f), 6);
+}
diff --git a/tests/lib/html/js_typed_interop_type2_test.dart b/tests/lib/html/js_typed_interop_type2_test.dart
new file mode 100644
index 0000000..c3c6ca0
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_type2_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+@JS()
+library js_typed_interop_type2_test;
+
+import 'dart:html';
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+@anonymous
+class C {
+  external get foo;
+
+  external factory C({required foo});
+}
+
+@JS()
+@anonymous
+class D {
+  external get foo;
+
+  external factory D({required foo});
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+@pragma('dart2js:noInline')
+testC(C o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testF(F o) {
+  return o.foo;
+}
+
+main() {
+  dynamic d = new D(foo: 4);
+  var f = new F(6);
+  Expect.equals(testC(d), 4);
+  Expect.equals(testF(f), 6);
+}
diff --git a/tests/lib/html/js_typed_interop_type3_test.dart b/tests/lib/html/js_typed_interop_type3_test.dart
new file mode 100644
index 0000000..d764182
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_type3_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_type3_test;
+
+import 'dart:html';
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+class A {
+  external get foo;
+
+  external A(var foo);
+}
+
+@JS()
+@anonymous
+class C {
+  external get foo;
+
+  external factory C({required foo});
+}
+
+@JS()
+@anonymous
+class D {
+  external get foo;
+
+  external factory D({required foo});
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+@pragma('dart2js:noInline')
+testA(A o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testC(C o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testD(D o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testF(F o) {
+  return o.foo;
+}
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+function A(foo) {
+  this.foo = foo;
+}
+""");
+}
+
+main() {
+  _injectJs();
+
+  var a = new A(1);
+  dynamic d = new D(foo: 4);
+
+  Expect.equals(testA(a), 1); //# 01: ok
+  Expect.equals(testA(a), 1); //# 02: ok
+  Expect.equals(testA(d), 4);
+  Expect.equals(testD(d), 4); //# 02: continued
+}
diff --git a/tests/lib/html/js_typed_interop_type_test.dart b/tests/lib/html/js_typed_interop_type_test.dart
new file mode 100644
index 0000000..c3967b5
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_type_test.dart
@@ -0,0 +1,161 @@
+// 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.
+
+@JS()
+library js_typed_interop_type_test;
+
+import 'dart:html';
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+class A {
+  var foo;
+
+  external A(var foo);
+}
+
+@JS()
+class B {
+  var foo;
+
+  external B(var foo);
+}
+
+@JS()
+@anonymous
+class C {
+  late final foo;
+
+  external factory C({foo});
+}
+
+@JS()
+@anonymous
+class D {
+  late final foo;
+
+  external factory D({foo});
+}
+
+class E {
+  final foo;
+
+  E(this.foo);
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+@pragma('dart2js:noInline')
+testA(A o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testB(B o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testC(C o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testD(D o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testE(E o) {
+  return o.foo;
+}
+
+@pragma('dart2js:noInline')
+testF(F o) {
+  return o.foo;
+}
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+function A(foo) {
+  this.foo = foo;
+}
+
+function B(foo) {
+  this.foo = foo;
+}
+""");
+}
+
+void expectValueOrTypeError(f(), value) {
+  try {
+    dynamic i = 0;
+    // TODO(rnystrom): Revisit this now that checked mode is gone in 2.0.
+    String s = i; // Test for checked mode.
+    Expect.equals(f(), value);
+  } on TypeError catch (error) {
+    Expect.throwsTypeError(f);
+  }
+}
+
+main() {
+  _injectJs();
+
+  dynamic a = new A(1);
+  dynamic b = new B(2);
+  dynamic c = new C(foo: 3);
+  dynamic d = new D(foo: 4);
+  dynamic e = new E(5);
+  dynamic f = new F(6);
+
+  Expect.equals(testA(a), 1);
+  Expect.equals(testB(b), 2);
+  Expect.equals(testA(b), 2);
+  Expect.equals(testA(c), 3);
+  Expect.equals(testA(d), 4);
+  expectValueOrTypeError(() => testA(e), 5);
+  expectValueOrTypeError(() => testA(f), 6);
+
+  Expect.equals(testB(a), 1);
+  Expect.equals(testB(b), 2);
+  Expect.equals(testB(c), 3);
+  Expect.equals(testB(d), 4);
+  expectValueOrTypeError(() => testB(e), 5);
+  expectValueOrTypeError(() => testB(f), 6);
+
+  Expect.equals(testC(a), 1);
+  Expect.equals(testC(b), 2);
+  Expect.equals(testC(c), 3);
+  Expect.equals(testC(d), 4);
+  expectValueOrTypeError(() => testC(e), 5);
+  expectValueOrTypeError(() => testC(f), 6);
+
+  Expect.equals(testD(a), 1);
+  Expect.equals(testD(b), 2);
+  Expect.equals(testD(c), 3);
+  Expect.equals(testD(d), 4);
+  expectValueOrTypeError(() => testD(e), 5);
+  expectValueOrTypeError(() => testD(f), 6);
+
+  expectValueOrTypeError(() => testE(a), 1);
+  expectValueOrTypeError(() => testE(b), 2);
+  expectValueOrTypeError(() => testE(c), 3);
+  expectValueOrTypeError(() => testE(d), 4);
+  Expect.equals(testE(e), 5);
+  expectValueOrTypeError(() => testE(f), 6);
+
+  expectValueOrTypeError(() => testF(a), 1);
+  expectValueOrTypeError(() => testF(b), 2);
+  expectValueOrTypeError(() => testF(c), 3);
+  expectValueOrTypeError(() => testF(d), 4);
+  expectValueOrTypeError(() => testF(e), 5);
+  Expect.equals(testF(f), 6);
+}
diff --git a/tests/lib/html/js_typed_interop_window_property_test.dart b/tests/lib/html/js_typed_interop_window_property_test.dart
new file mode 100644
index 0000000..4790b7a
--- /dev/null
+++ b/tests/lib/html/js_typed_interop_window_property_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+@JS()
+library js_typed_interop_window_property_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+// This is a regression test for https://github.com/dart-lang/sdk/issues/24817
+
+_injectJs() {
+  document.body!.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  window.foo = [function() { return 42; }];
+""");
+}
+
+@JS("window.foo")
+external List<Function> get foo;
+
+main() {
+  _injectJs();
+
+  Expect.equals(foo[0](), 42);
+}
diff --git a/tests/lib/html/js_util_test.dart b/tests/lib/html/js_util_test.dart
new file mode 100644
index 0000000..f06e729
--- /dev/null
+++ b/tests/lib/html/js_util_test.dart
@@ -0,0 +1,387 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_native_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:typed_data' show ByteBuffer, Int32List;
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+import 'package:async_helper/async_helper.dart';
+
+_injectJs() {
+  final script = new ScriptElement();
+  script.type = 'text/javascript';
+  script.innerHtml = r"""
+var x = 42;
+
+var _x = 123;
+
+var myArray = ["value1"];
+
+function returnThis() {
+  return this;
+}
+
+function getTypeOf(o) {
+  return typeof(o);
+}
+
+function Foo(a) {
+  this.a = a;
+}
+
+Foo.b = 38;
+
+Foo.prototype.bar = function() {
+  return this.a;
+}
+Foo.prototype.toString = function() {
+  return "I'm a Foo a=" + this.a;
+}
+
+var container = new Object();
+container.Foo = Foo;
+
+function checkMap(m, key, value) {
+  if (m.hasOwnProperty(key))
+    return m[key] == value;
+  else
+    return false;
+}
+
+var rejectedPromise = new Promise((resolve, reject) => reject('rejected'));
+var resolvedPromise = new Promise(resolve => resolve('resolved'));
+function getResolvedPromise() {
+  return resolvedPromise;
+}
+
+""";
+  document.body!.append(script);
+}
+
+@JS()
+external bool checkMap(m, String, value);
+
+@JS('JSON.stringify')
+external String stringify(o);
+
+@JS('Node')
+external get JSNodeType;
+
+@JS('Element')
+external get JSElementType;
+
+@JS('Text')
+external get JSTextType;
+
+@JS('HTMLCanvasElement')
+external get JSHtmlCanvasElementType;
+
+@JS()
+class Foo {
+  external Foo(num a);
+
+  external num get a;
+  external num bar();
+}
+
+@JS('Foo')
+external get JSFooType;
+
+@JS()
+@anonymous
+class ExampleTypedLiteral {
+  external factory ExampleTypedLiteral({a, b, JS$_c, JS$class});
+
+  external get a;
+  external get b;
+  external get JS$_c;
+  external set JS$_c(v);
+  // Identical to JS$_c but only accessible within the library.
+  external get _c;
+  external get JS$class;
+  external set JS$class(v);
+}
+
+@JS()
+abstract class Promise<T> {}
+
+@JS()
+external Promise get resolvedPromise;
+
+@JS()
+external Promise get rejectedPromise;
+
+@JS()
+external Promise getResolvedPromise();
+
+@JS("Object.prototype.hasOwnProperty")
+external get _hasOwnProperty;
+
+bool hasOwnProperty(o, String name) {
+  return js_util.callMethod(_hasOwnProperty, 'call', [o, name]);
+}
+
+main() {
+  _injectJs();
+
+  group('js_util.jsify()', () {
+    test('convert a List', () {
+      final list = [1, 2, 3, 4, 5, 6, 7, 8];
+      var array = js_util.jsify(list);
+      expect(array is List, isTrue);
+      expect(identical(array, list), isFalse);
+      expect(array.length, equals(list.length));
+      for (var i = 0; i < list.length; i++) {
+        expect(array[i], equals(list[i]));
+      }
+    });
+
+    test('convert an Iterable', () {
+      final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]);
+      var array = js_util.jsify(set);
+      expect(array is List, isTrue);
+      expect(array.length, equals(set.length));
+      for (var i = 0; i < array.length; i++) {
+        expect(set.contains(array[i]), isTrue);
+      }
+    });
+
+    test('convert a Map', () {
+      var map = {'a': 1, 'b': 2, 'c': 3};
+      var jsMap = js_util.jsify(map);
+      expect(jsMap is! List, isTrue);
+      for (var key in map.keys) {
+        expect(checkMap(jsMap, key, map[key]), isTrue);
+      }
+    });
+
+    test('deep convert a complex object', () {
+      dynamic object = {
+        'a': [
+          1,
+          [2, 3]
+        ],
+        'b': {'c': 3, 'd': new Foo(42)},
+        'e': null
+      };
+      var jsObject = js_util.jsify(object);
+      expect(js_util.getProperty(jsObject, 'a')[0], equals(object['a'][0]));
+      expect(
+          js_util.getProperty(jsObject, 'a')[1][0], equals(object['a'][1][0]));
+      expect(
+          js_util.getProperty(jsObject, 'a')[1][1], equals(object['a'][1][1]));
+      expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'c'),
+          equals(object['b']['c']));
+      expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'),
+          equals(object['b']['d']));
+      expect(
+          js_util.callMethod(
+              js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'),
+              'bar', []),
+          equals(42));
+      expect(js_util.getProperty(jsObject, 'e'), isNull);
+    });
+
+    test('throws if object is not a Map or Iterable', () {
+      expect(() => js_util.jsify('a'), throwsArgumentError);
+    });
+  });
+
+  group('js_util.newObject', () {
+    test('create', () {
+      expect(identical(js_util.newObject(), js_util.newObject()), isFalse);
+    });
+
+    test('callMethod', () {
+      var o = js_util.newObject();
+      expect(js_util.callMethod(o, 'toString', []), equals('[object Object]'));
+      expect(stringify(o), equals('{}'));
+    });
+
+    test('properties', () {
+      var o = js_util.newObject();
+      expect(js_util.hasProperty(o, 'foo bar'), isFalse);
+      expect(js_util.hasProperty(o, 'toString'), isTrue);
+      expect(hasOwnProperty(o, 'toString'), isFalse);
+      expect(hasOwnProperty(o, 'foo bar'), isFalse);
+      js_util.setProperty(o, 'foo bar', 42);
+      expect(hasOwnProperty(o, 'foo bar'), isTrue);
+      expect(js_util.getProperty(o, 'foo bar'), equals(42));
+      expect(js_util.hasProperty(o, 'foo bar'), isTrue);
+      expect(stringify(o), equals('{"foo bar":42}'));
+    });
+  });
+
+  group('hasProperty', () {
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.hasProperty(f, 'a'), isTrue);
+      expect(js_util.hasProperty(f, 'toString'), isTrue);
+      js_util.setProperty(f, '__proto__', null);
+      expect(js_util.hasProperty(f, 'toString'), isFalse);
+    });
+    test('typed literal', () {
+      var l =
+          new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: null, JS$class: true);
+      expect(js_util.hasProperty(l, 'a'), isTrue);
+      expect(js_util.hasProperty(l, 'b'), isTrue);
+      expect(js_util.hasProperty(l, '_c'), isTrue);
+      expect(l.JS$_c, isNull);
+      expect(js_util.hasProperty(l, 'class'), isTrue);
+      // JS$_c escapes to _c so the property JS$_c will not exist on the object.
+      expect(js_util.hasProperty(l, r'JS$_c'), isFalse);
+      expect(js_util.hasProperty(l, r'JS$class'), isFalse);
+      expect(l.JS$class, isTrue);
+
+      l = new ExampleTypedLiteral(a: null);
+      expect(js_util.hasProperty(l, 'a'), isTrue);
+      expect(js_util.hasProperty(l, 'b'), isFalse);
+      expect(js_util.hasProperty(l, '_c'), isFalse);
+      expect(js_util.hasProperty(l, 'class'), isFalse);
+
+      l = new ExampleTypedLiteral(JS$_c: 74);
+      expect(js_util.hasProperty(l, '_c'), isTrue);
+      expect(l.JS$_c, equals(74));
+    });
+  });
+
+  group('getProperty', () {
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.getProperty(f, 'a'), equals(42));
+      expect(js_util.getProperty(f, 'toString') is Function, isTrue);
+      js_util.setProperty(f, '__proto__', null);
+      expect(js_util.getProperty(f, 'toString'), isNull);
+    });
+
+    test('typed literal', () {
+      var l = new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: 7, JS$class: true);
+      expect(js_util.getProperty(l, 'a'), equals('x'));
+      expect(js_util.getProperty(l, 'b'), equals(42));
+      expect(js_util.getProperty(l, '_c'), equals(7));
+      expect(l.JS$_c, equals(7));
+      expect(js_util.getProperty(l, 'class'), isTrue);
+      expect(js_util.getProperty(l, r'JS$_c'), isNull);
+      expect(js_util.getProperty(l, r'JS$class'), isNull);
+    });
+  });
+
+  group('setProperty', () {
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.getProperty(f, 'a'), equals(42));
+      js_util.setProperty(f, 'a', 100);
+      expect(f.a, equals(100));
+      expect(js_util.getProperty(f, 'a'), equals(100));
+    });
+
+    test('typed literal', () {
+      var l = new ExampleTypedLiteral();
+      js_util.setProperty(l, 'a', 'foo');
+      expect(js_util.getProperty(l, 'a'), equals('foo'));
+      expect(l.a, equals('foo'));
+      js_util.setProperty(l, 'a', l);
+      expect(identical(l.a, l), isTrue);
+      var list = ['arr'];
+      js_util.setProperty(l, 'a', list);
+      expect(identical(l.a, list), isTrue);
+      l.JS$class = 42;
+      expect(l.JS$class, equals(42));
+      js_util.setProperty(l, 'class', 100);
+      expect(l.JS$class, equals(100));
+    });
+  });
+
+  group('callMethod', () {
+    test('html object', () {
+      var canvas = new CanvasElement();
+      expect(
+          identical(canvas.getContext('2d'),
+              js_util.callMethod(canvas, 'getContext', ['2d'])),
+          isTrue);
+    });
+
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.callMethod(f, 'bar', []), equals(42));
+    });
+  });
+
+  group('instanceof', () {
+    test('html object', () {
+      var canvas = new Element.tag('canvas');
+      expect(js_util.instanceof(canvas, JSNodeType), isTrue);
+      expect(js_util.instanceof(canvas, JSTextType), isFalse);
+      expect(js_util.instanceof(canvas, JSElementType), isTrue);
+      expect(js_util.instanceof(canvas, JSHtmlCanvasElementType), isTrue);
+      var div = new Element.tag('div');
+      expect(js_util.instanceof(div, JSNodeType), isTrue);
+      expect(js_util.instanceof(div, JSTextType), isFalse);
+      expect(js_util.instanceof(div, JSElementType), isTrue);
+      expect(js_util.instanceof(div, JSHtmlCanvasElementType), isFalse);
+
+      var text = new Text('foo');
+      expect(js_util.instanceof(text, JSNodeType), isTrue);
+      expect(js_util.instanceof(text, JSTextType), isTrue);
+      expect(js_util.instanceof(text, JSElementType), isFalse);
+    });
+
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.instanceof(f, JSFooType), isTrue);
+      expect(js_util.instanceof(f, JSNodeType), isFalse);
+    });
+
+    test('typed literal', () {
+      var l = new ExampleTypedLiteral();
+      expect(js_util.instanceof(l, JSFooType), isFalse);
+    });
+  });
+
+  group('callConstructor', () {
+    test('html object', () {
+      var textNode = js_util.callConstructor(JSTextType, ['foo']);
+      expect(js_util.instanceof(textNode, JSTextType), isTrue);
+      expect(textNode is Text, isTrue);
+      expect(textNode.text, equals('foo'));
+    });
+
+    test('typed object', () {
+      Foo f = js_util.callConstructor(JSFooType, [42]);
+      expect(f.a, equals(42));
+    });
+  });
+
+  Future<void> testResolvedPromise() async {
+    final String result = await js_util.promiseToFuture(resolvedPromise);
+    expect(result, equals('resolved'));
+  }
+
+  Future<void> testRejectedPromise() async {
+    try {
+      final String result = await promiseToFuture(rejectedPromise);
+      fail('expected Future to throw an error');
+    } catch (error) {
+      expect(error, equals('rejected'));
+    }
+  }
+
+  Future<void> testReturnRejectedPromise() async {
+    final String result = await promiseToFuture(getResolvedPromise());
+    expect(result, equals('resolved'));
+  }
+
+  asyncTest(() async {
+    await testResolvedPromise();
+    await testRejectedPromise();
+    await testReturnRejectedPromise();
+  });
+}
diff --git a/tests/lib/html/json_helper.dart b/tests/lib/html/json_helper.dart
new file mode 100644
index 0000000..7d037ae
--- /dev/null
+++ b/tests/lib/html/json_helper.dart
@@ -0,0 +1,10 @@
+// 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.
+
+@JS("JSON")
+library json_helper;
+
+import 'package:js/js.dart';
+
+external String stringify(object);
diff --git a/tests/lib/html/keyboard_event_test.dart b/tests/lib/html/keyboard_event_test.dart
new file mode 100644
index 0000000..74e63d3
--- /dev/null
+++ b/tests/lib/html/keyboard_event_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library KeyboardEventTest;
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+// Test that we are correctly determining keyCode and charCode uniformly across
+// browsers.
+
+void testKeyboardEventConstructor() {
+  new KeyboardEvent('keyup');
+}
+
+void keydownHandlerTest(KeyEvent e) {
+  expect(e.charCode, 0);
+}
+
+void testKeys() {
+  var subscription =
+      KeyboardEventStream.onKeyDown(document.body!).listen(keydownHandlerTest);
+  var subscription2 =
+      KeyEvent.keyDownEvent.forTarget(document.body).listen(keydownHandlerTest);
+  var subscription3 =
+      document.body!.onKeyDown.listen((e) => print('regular listener'));
+  subscription.cancel();
+  subscription2.cancel();
+  subscription3.cancel();
+}
+
+void testConstructKeyEvent() {
+  int handlerCallCount = 0;
+  CustomStream<KeyEvent> stream = KeyEvent.keyPressEvent
+      .forTarget(document.body!) as CustomStream<KeyEvent>;
+  var subscription = stream.listen((keyEvent) {
+    expect(keyEvent.charCode, 97);
+    expect(keyEvent.keyCode, 65);
+    handlerCallCount++;
+  });
+  var k = new KeyEvent('keypress', keyCode: 65, charCode: 97);
+  stream.add(k);
+  subscription.cancel();
+  // Capital "A":
+  stream.add(new KeyEvent('keydown', keyCode: 16, charCode: 0));
+
+  subscription = stream.listen((keyEvent) {
+    expect(keyEvent.charCode, 65);
+    expect(keyEvent.keyCode, 65);
+    handlerCallCount++;
+  });
+  stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 65));
+  subscription.cancel();
+
+  expect(handlerCallCount, 2);
+}
+
+void testKeyEventSequence() {
+  int handlerCallCount = 0;
+  // Press "?" by simulating "shift" and then the key that has "/" and "?" on
+  // it.
+  CustomStream<KeyEvent> streamDown =
+      KeyEvent.keyDownEvent.forTarget(document.body!) as CustomStream<KeyEvent>;
+  CustomStream<KeyEvent> streamPress = KeyEvent.keyPressEvent
+      .forTarget(document.body!) as CustomStream<KeyEvent>;
+  CustomStream<KeyEvent> streamUp =
+      KeyEvent.keyUpEvent.forTarget(document.body!) as CustomStream<KeyEvent>;
+
+  var subscription = streamDown.listen((keyEvent) {
+    expect(keyEvent.keyCode, predicate([16, 191].contains));
+    expect(keyEvent.charCode, 0);
+    handlerCallCount++;
+  });
+
+  var subscription2 = streamPress.listen((keyEvent) {
+    expect(keyEvent.keyCode, 23);
+    expect(keyEvent.charCode, 63);
+    handlerCallCount++;
+  });
+
+  var subscription3 = streamUp.listen((keyEvent) {
+    expect(keyEvent.keyCode, predicate([16, 191].contains));
+    expect(keyEvent.charCode, 0);
+    handlerCallCount++;
+  });
+
+  streamDown.add(new KeyEvent('keydown', keyCode: 16, charCode: 0));
+  streamDown.add(new KeyEvent('keydown', keyCode: 191, charCode: 0));
+
+  streamPress.add(new KeyEvent('keypress', keyCode: 23, charCode: 63));
+
+  streamUp.add(new KeyEvent('keyup', keyCode: 191, charCode: 0));
+  streamUp.add(new KeyEvent('keyup', keyCode: 16, charCode: 0));
+  subscription.cancel();
+  subscription2.cancel();
+  subscription3.cancel();
+
+  expect(handlerCallCount, 5);
+}
+
+void testKeyEventKeyboardEvent() {
+  int handlerCallCount = 0;
+  window.onKeyDown.listen((event) {
+    expect(event.keyCode, 16);
+    handlerCallCount++;
+  });
+  CustomStream<KeyEvent> streamDown =
+      KeyEvent.keyDownEvent.forTarget(document.body!) as CustomStream<KeyEvent>;
+  streamDown.add(new KeyEvent('keydown', keyCode: 16, charCode: 0));
+  expect(handlerCallCount, 1);
+}
+
+main() {
+  testKeyboardEventConstructor();
+  testKeys();
+  testConstructKeyEvent();
+  testKeyEventSequence();
+  testKeyEventKeyboardEvent();
+}
diff --git a/tests/lib/html/localstorage_test.dart b/tests/lib/html/localstorage_test.dart
new file mode 100644
index 0000000..57db920
--- /dev/null
+++ b/tests/lib/html/localstorage_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  setUp(() {
+    window.localStorage['key1'] = 'val1';
+    window.localStorage['key2'] = 'val2';
+    window.localStorage['key3'] = 'val3';
+  });
+
+  tearDown(() {
+    window.localStorage.clear();
+  });
+
+  test('containsValue', () {
+    expect(window.localStorage.containsValue('does not exist'), isFalse);
+    expect(window.localStorage.containsValue('key1'), isFalse);
+    expect(window.localStorage.containsValue('val1'), isTrue);
+    expect(window.localStorage.containsValue('val3'), isTrue);
+  });
+
+  test('containsKey', () {
+    expect(window.localStorage.containsKey('does not exist'), isFalse);
+    expect(window.localStorage.containsKey('val1'), isFalse);
+    expect(window.localStorage.containsKey('key1'), isTrue);
+    expect(window.localStorage.containsKey('key3'), isTrue);
+  });
+
+  test('[]', () {
+    expect(window.localStorage['does not exist'], isNull);
+    expect(window.localStorage['key1'], 'val1');
+    expect(window.localStorage['key3'], 'val3');
+  });
+
+  test('[]=', () {
+    expect(window.localStorage['key4'], isNull);
+    window.localStorage['key4'] = 'val4';
+    expect(window.localStorage['key4'], 'val4');
+
+    expect(window.localStorage['key3'], 'val3');
+    window.localStorage['key3'] = 'val3-new';
+    expect(window.localStorage['key3'], 'val3-new');
+  });
+
+  test('putIfAbsent', () {
+    expect(window.localStorage['key4'], isNull);
+    expect(window.localStorage.putIfAbsent('key4', () => 'val4'), 'val4');
+    expect(window.localStorage['key4'], 'val4');
+
+    expect(window.localStorage['key3'], 'val3');
+    expect(
+        window.localStorage.putIfAbsent('key3', () {
+          fail('should not be called');
+          return 'unused';
+        }),
+        'val3');
+    expect(window.localStorage['key3'], 'val3');
+  });
+
+  test('remove', () {
+    expect(window.localStorage.remove('does not exist'), isNull);
+    expect(window.localStorage.remove('key3'), 'val3');
+    expect(window.localStorage, equals({'key1': 'val1', 'key2': 'val2'}));
+  });
+
+  test('clear', () {
+    window.localStorage.clear();
+    expect(window.localStorage, equals({}));
+  });
+
+  test('forEach', () {
+    var results = <String, String>{};
+    window.localStorage.forEach((k, v) {
+      results[k] = v;
+    });
+    expect(results, equals({'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}));
+  });
+
+  test('getKeys', () {
+    expect(window.localStorage.keys.toList(),
+        unorderedEquals(['key1', 'key2', 'key3']));
+  });
+
+  test('getVals', () {
+    expect(window.localStorage.values.toList(),
+        unorderedEquals(['val1', 'val2', 'val3']));
+  });
+
+  test('getEntries', () {
+    var results = <String, String>{};
+    window.localStorage.entries.forEach((e) {
+      results[e.key] = e.value;
+    });
+    expect(results, equals({'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}));
+  });
+
+  test('length', () {
+    expect(window.localStorage.length, 3);
+    window.localStorage.clear();
+    expect(window.localStorage.length, 0);
+  });
+
+  test('isEmpty', () {
+    expect(window.localStorage.isEmpty, isFalse);
+    window.localStorage.clear();
+    expect(window.localStorage.isEmpty, isTrue);
+  });
+}
diff --git a/tests/lib/html/location_test.dart b/tests/lib/html/location_test.dart
new file mode 100644
index 0000000..0b8369c
--- /dev/null
+++ b/tests/lib/html/location_test.dart
@@ -0,0 +1,34 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isLocation = predicate((x) => x is Location, 'is a Location');
+
+  test('location hash', () {
+    final location = window.location;
+    expect(location, isLocation);
+
+    // The only navigation we dare try is hash.
+    location.hash = 'hello';
+    var h = location.hash;
+    expect(h, '#hello');
+  });
+
+  test('location.origin', () {
+    var origin = window.location.origin;
+
+    // We build up the origin from Uri, then make sure that it matches.
+    var uri = Uri.parse(window.location.href);
+    var reconstructedOrigin = '${uri.scheme}://${uri.host}';
+    if (uri.port != 0) {
+      reconstructedOrigin = '$reconstructedOrigin:${uri.port}';
+    }
+
+    expect(origin, reconstructedOrigin);
+  });
+}
diff --git a/tests/lib/html/media_stream_test.dart b/tests/lib/html/media_stream_test.dart
new file mode 100644
index 0000000..7dc5bde
--- /dev/null
+++ b/tests/lib/html/media_stream_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported_media', () {
+    test('supported', () {
+      expect(MediaStream.supported, true);
+    });
+  });
+
+  group('supported_MediaStreamEvent', () {
+    test('supported', () {
+      expect(MediaStreamEvent.supported, true);
+    });
+  });
+
+  group('supported_MediaStreamTrackEvent', () {
+    test('supported', () {
+      expect(MediaStreamTrackEvent.supported, true);
+    });
+  });
+
+  group('constructors', () {
+    test('MediaStreamEvent', () {
+      var expectation = MediaStreamEvent.supported ? returnsNormally : throws;
+      expect(() {
+        var event = new Event.eventType('MediaStreamEvent', 'media');
+        expect(event is MediaStreamEvent, isTrue);
+      }, expectation);
+    });
+
+    test('MediaStreamTrackEvent', () {
+      var expectation =
+          MediaStreamTrackEvent.supported ? returnsNormally : throws;
+      expect(() {
+        var event = new Event.eventType('MediaStreamTrackEvent', 'media');
+        expect(event is MediaStreamTrackEvent, isTrue);
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/lib/html/mediadevices_test.dart b/tests/lib/html/mediadevices_test.dart
new file mode 100644
index 0000000..abc803a
--- /dev/null
+++ b/tests/lib/html/mediadevices_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+test() async {
+  var list = await window.navigator.mediaDevices.enumerateDevices();
+  Expect.isTrue(list is List<dynamic>, "Expected list to be List<dynamic>");
+}
+
+void main() {
+  asyncStart();
+  test().then((_) => asyncEnd());
+}
diff --git a/tests/lib/html/mediasource_test.dart b/tests/lib/html/mediasource_test.dart
new file mode 100644
index 0000000..ac6765a
--- /dev/null
+++ b/tests/lib/html/mediasource_test.dart
@@ -0,0 +1,41 @@
+// 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:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isMediaSource = predicate((x) => x is MediaSource, 'is a MediaSource');
+
+  group('supported', () {
+    test('supported', () {
+      expect(MediaSource.supported, true);
+    });
+  });
+
+  // TODO(alanknight): Actually exercise this, right now the tests are trivial.
+  group('functional', () {
+    var source;
+    if (MediaSource.supported) {
+      source = new MediaSource();
+    }
+
+    test('constructorTest', () {
+      if (MediaSource.supported) {
+        expect(source, isNotNull);
+        expect(source, isMediaSource);
+      }
+    });
+
+    test('media types', () {
+      if (MediaSource.supported) {
+        expect(MediaSource.isTypeSupported('text/html'), false);
+        expect(MediaSource.isTypeSupported('video/webm;codecs="vp8,vorbis"'),
+            true);
+      }
+    });
+  });
+}
diff --git a/tests/lib/html/message_channel_test.dart b/tests/lib/html/message_channel_test.dart
new file mode 100644
index 0000000..c6029dd
--- /dev/null
+++ b/tests/lib/html/message_channel_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() async {
+  var gotOnMessage = false;
+  var gotEventListener = false;
+
+  Completer completer = new Completer();
+
+  var channel = new MessageChannel();
+  channel.port1.postMessage("Tickle me.");
+
+  channel.port2.onMessage.listen((MessageEvent e) {
+    expect(e.data, "Tickle me.");
+    gotOnMessage = true;
+  });
+
+  channel.port2.addEventListener("message", (message) {
+    var msg = message as MessageEvent;
+    expect(msg.data, "Tickle me.");
+    gotEventListener = true;
+    completer.complete();
+  });
+
+  // Wait for the event listener.
+  await completer.future;
+
+  // Make sure both fired.
+  expect(gotOnMessage, true);
+  expect(gotEventListener, true);
+}
diff --git a/tests/lib/html/messageevent_test.dart b/tests/lib/html/messageevent_test.dart
new file mode 100644
index 0000000..83811c9
--- /dev/null
+++ b/tests/lib/html/messageevent_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('new MessageEvent', () {
+    final event = new MessageEvent('type',
+        cancelable: true,
+        data: 'data',
+        origin: 'origin',
+        lastEventId: 'lastEventId');
+
+    expect(event.type, equals('type'));
+    expect(event.bubbles, isFalse);
+    expect(event.cancelable, isTrue);
+    expect(event.data, equals('data'));
+    expect(event.origin, equals('origin'));
+    // IE allows setting this but just ignores it.
+    // expect(event.lastEventId, equals('lastEventId'));
+    expect(event.source, window);
+    // TODO(antonm): accessing ports is not supported yet.
+  });
+}
diff --git a/tests/lib/html/mouse_event_test.dart b/tests/lib/html/mouse_event_test.dart
new file mode 100644
index 0000000..7d7b0d9
--- /dev/null
+++ b/tests/lib/html/mouse_event_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('relatedTarget', () {
+    var event = new MouseEvent('mouseout');
+    expect(event.relatedTarget, isNull);
+
+    event = new MouseEvent('mouseout', relatedTarget: document.body);
+    expect(event.relatedTarget, document.body);
+  });
+}
diff --git a/tests/lib/html/mutationobserver_test.dart b/tests/lib/html/mutationobserver_test.dart
new file mode 100644
index 0000000..7ee71fe
--- /dev/null
+++ b/tests/lib/html/mutationobserver_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mutationobserver_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+// Due to https://code.google.com/p/chromium/issues/detail?id=329103
+// mutationObservers sometimes do not fire if the node being observed is GCed
+// so we keep around references to all nodes we have created mutation
+// observers for.
+var keepAlive = [];
+
+void testSupported() {
+  expect(MutationObserver.supported, true);
+}
+
+mutationCallback(Completer done, int count, expectation) {
+  final nodes = [];
+
+  callback(mutations, observer) {
+    for (MutationRecord mutation in mutations) {
+      for (Node node in mutation.addedNodes) {
+        nodes.add(node);
+      }
+    }
+    if (nodes.length >= count) {
+      expect(nodes.length, count);
+      expect(nodes, expectation);
+      done.complete();
+    }
+  }
+
+  // If it's not supported, don't block waiting for it.
+  if (!MutationObserver.supported) {
+    done.complete();
+    return (mutations, observer) {};
+  }
+
+  return callback;
+}
+
+void testEmptyOptionsIsSyntaxError(expectation) {
+  expect(() {
+    var mutationObserver = new MutationObserver((mutations, observer) {
+      expect(false, isTrue, reason: 'Should not be reached');
+    });
+    expect(() {
+      mutationObserver.observe(document);
+    }, throws);
+  }, expectation);
+}
+
+Future<Null> testDirectParallelOptionsNamed(expectation) {
+  final done = new Completer<Null>();
+  expect(() {
+    var container = new DivElement();
+    keepAlive.add(container);
+    var div1 = new DivElement();
+    var div2 = new DivElement();
+    var mutationObserver =
+        new MutationObserver(mutationCallback(done, 2, equals([div1, div2])));
+    mutationObserver.observe(container, childList: true);
+
+    container.append(div1);
+    container.append(div2);
+  }, expectation);
+  return done.future;
+}
+
+Future<Null> testDirectNestedOptionsNamed(expectation) {
+  final done = new Completer<Null>();
+  expect(() {
+    var container = new DivElement();
+    keepAlive.add(container);
+    var div1 = new DivElement();
+    var div2 = new DivElement();
+    var mutationObserver =
+        new MutationObserver(mutationCallback(done, 1, equals([div1])));
+    mutationObserver.observe(container, childList: true);
+
+    container.append(div1);
+    div1.append(div2);
+  }, expectation);
+  return done.future;
+}
+
+Future<Null> testSubtreeOptionsNamed(expectation) {
+  final done = new Completer<Null>();
+  expect(() {
+    var container = new DivElement();
+    keepAlive.add(container);
+    var div1 = new DivElement();
+    var div2 = new DivElement();
+    var mutationObserver =
+        new MutationObserver(mutationCallback(done, 2, equals([div1, div2])));
+    mutationObserver.observe(container, childList: true, subtree: true);
+
+    container.append(div1);
+    div1.append(div2);
+  }, expectation);
+  return done.future;
+}
+
+/**
+ * Test suite for Mutation Observers. This is just a small set of sanity
+ * checks, not a complete test suite.
+ */
+main() async {
+  testSupported();
+
+  final expectation = MutationObserver.supported ? returnsNormally : throws;
+  testEmptyOptionsIsSyntaxError(expectation);
+  await testDirectParallelOptionsNamed(expectation);
+  await testDirectNestedOptionsNamed(expectation);
+  await testSubtreeOptionsNamed(expectation);
+}
diff --git a/tests/lib/html/native_gc_test.dart b/tests/lib/html/native_gc_test.dart
new file mode 100644
index 0000000..42a5a50
--- /dev/null
+++ b/tests/lib/html/native_gc_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library NativeGCTest;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+var testEvent = new EventStreamProvider<Event>('test');
+
+void testEventListener() {
+  final int N = 1000000;
+  final int M = 1000;
+
+  var div;
+  for (int i = 0; i < M; ++i) {
+    // This memory should be freed when the listener below is
+    // collected.
+    List<int> l = new List<int>.filled(N, 0);
+
+    // Record the iteration number.
+    l[N - 1] = i;
+
+    div = new Element.tag('div');
+    testEvent.forTarget(div).listen((_) {
+      // Only the final iteration's listener should be invoked.
+      // Note: the reference to l keeps the entire list alive.
+      expect(l[N - 1], M - 1);
+    });
+  }
+
+  final event = new Event('test');
+  div.dispatchEvent(event);
+}
+
+Future<Null> testWindowEventListener() {
+  String message = 'WindowEventListenerTestPingMessage';
+
+  Element testDiv = new DivElement();
+  testDiv.id = '#TestDiv';
+  document.body!.append(testDiv);
+  window.onMessage.listen((e) {
+    if (e.data == message) testDiv.click();
+  });
+
+  for (int i = 0; i < 100; ++i) {
+    triggerMajorGC();
+  }
+
+  final done = new Completer<Null>();
+  testDiv.onClick.listen(((_) {
+    done.complete();
+  }));
+  window.postMessage(message, '*');
+  return done.future;
+}
+
+main() async {
+  testEventListener();
+  await testWindowEventListener();
+}
+
+void triggerMajorGC() {
+  List<int> list = new List<int>.filled(1000000, 0);
+  Element div = new DivElement();
+  div.onClick.listen((e) => print(list[0]));
+}
diff --git a/tests/lib/html/navigator_test.dart b/tests/lib/html/navigator_test.dart
new file mode 100644
index 0000000..02cbafd
--- /dev/null
+++ b/tests/lib/html/navigator_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.isNotNull(window.navigator.language);
+}
diff --git a/tests/lib/html/node_test.dart b/tests/lib/html/node_test.dart
new file mode 100644
index 0000000..2e90418
--- /dev/null
+++ b/tests/lib/html/node_test.dart
@@ -0,0 +1,341 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:svg' as svg;
+
+import 'package:expect/minitest.dart';
+
+Node makeNode() => new Element.tag('div');
+Element makeNodeWithChildren() =>
+    new Element.html("<div>Foo<br/><!--baz--></div>");
+
+void testUnsupported(String name, void f()) {
+  test(name, () {
+    expect(f, throwsUnsupportedError);
+  });
+}
+
+main() {
+  var isText = predicate((x) => x is Text, 'is a Text');
+  var isComment = predicate((x) => x is Comment, 'is a Comment');
+  var isBRElement = predicate((x) => x is BRElement, 'is a BRElement');
+  var isHRElement = predicate((x) => x is HRElement, 'is a HRElement');
+  var isNodeList = predicate((x) => x is List<Node>, 'is a List<Node>');
+  var isImageElement =
+      predicate((x) => x is ImageElement, 'is an ImageElement');
+  var isInputElement =
+      predicate((x) => x is InputElement, 'is an InputElement');
+
+  group('functional', () {
+    test('toString', () {
+      final nodes = makeNodeWithChildren();
+      // TODO(efortuna): Update this test when you have actual toString methods
+      // for the items in the node List as well.
+      expect(nodes.nodes.toString(), "[Foo, br, baz]");
+      final node = makeNode();
+      expect(node.nodes.toString(), '[]');
+    });
+
+    test('replaceWith', () {
+      final node = makeNodeWithChildren();
+      final subnode = node.nodes[1];
+      final out = subnode.replaceWith(new Text('Bar'));
+      expect(out, equals(subnode), reason: '#replaceWith should be chainable');
+      expect(node.nodes.length, 3);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[0].text, 'Foo');
+      expect(node.nodes[1], isText);
+      expect(node.nodes[1].text, 'Bar');
+      expect(node.nodes[2], isComment);
+    });
+
+    test('append', () {
+      var node = makeNode();
+      node.append(new Element.tag('hr'));
+      expect(node.nodes.last, isHRElement);
+    });
+
+    test('remove', () {
+      final node = makeNodeWithChildren();
+      final subnode = node.nodes[1];
+      subnode.remove();
+      expect(node.nodes.length, 2);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isComment);
+    });
+
+    test('contains', () {
+      final Node node =
+          new Element.html("<div>Foo<span><div>Bar<div></span></div>");
+      // IE10 returns false for contains of nodes.
+      //expect(node.contains(node.nodes.first), isTrue);
+      expect(node.contains(node.nodes[1].nodes.first), isTrue);
+      expect(node.contains(new Text('Foo')), isFalse);
+    });
+
+    test('insertAllBefore', () {
+      var node = makeNodeWithChildren();
+      var b = new DivElement();
+      b.nodes.addAll([new HRElement(), new ImageElement(), new InputElement()]);
+      node.insertAllBefore(b.nodes, node.nodes[1]);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isImageElement);
+      expect(node.nodes[3], isInputElement);
+      expect(node.nodes[4], isBRElement);
+      expect(node.nodes[5], isComment);
+
+      var nodes = [new HRElement(), new ImageElement(), new InputElement()];
+      node.insertAllBefore(nodes, node.nodes[5]);
+
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isImageElement);
+      expect(node.nodes[3], isInputElement);
+      expect(node.nodes[4], isBRElement);
+      expect(node.nodes[5], isHRElement);
+      expect(node.nodes[6], isImageElement);
+      expect(node.nodes[7], isInputElement);
+      expect(node.nodes[8], isComment);
+    });
+  });
+
+  group('nodes', () {
+    test('is a NodeList', () {
+      expect(makeNodeWithChildren().nodes, isNodeList);
+    });
+
+    test('indexer', () {
+      var node = new DivElement();
+      expect(() {
+        node.nodes[0];
+      }, throwsRangeError);
+
+      expect(() {
+        node.nodes[-1];
+      }, throwsRangeError);
+    });
+
+    test('first', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes.first, isText);
+
+      node = new DivElement();
+      expect(() {
+        node = node.nodes.first as Element;
+      }, throwsStateError);
+    });
+
+    test('last', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes.last, isComment);
+    });
+
+    test('forEach', () {
+      var nodes = [];
+      var node = makeNodeWithChildren();
+      node.nodes.forEach((n) => nodes.add(n));
+      expect(nodes[0], isText);
+      expect(nodes[1], isBRElement);
+      expect(nodes[2], isComment);
+    });
+
+    test('where', () {
+      var filtered =
+          makeNodeWithChildren().nodes.where((n) => n is BRElement).toList();
+      expect(filtered.length, 1);
+      expect(filtered[0], isBRElement);
+      expect(filtered, isNodeList);
+    });
+
+    test('every', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes.every((n) => n is Node), isTrue);
+      expect(node.nodes.every((n) => n is Comment), isFalse);
+    });
+
+    test('any', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes.any((n) => n is Comment), isTrue);
+      expect(node.nodes.any((n) => n is svg.SvgElement), isFalse);
+    });
+
+    test('isEmpty', () {
+      expect(makeNode().nodes.isEmpty, isTrue);
+      expect(makeNodeWithChildren().nodes.isEmpty, isFalse);
+    });
+
+    test('length', () {
+      expect(makeNode().nodes.length, 0);
+      expect(makeNodeWithChildren().nodes.length, 3);
+    });
+
+    test('[]', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isBRElement);
+      expect(node.nodes[2], isComment);
+    });
+
+    test('[]=', () {
+      var node = makeNodeWithChildren();
+      node.nodes[1] = new Element.tag('hr');
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isComment);
+    });
+
+    test('add', () {
+      var node = makeNode();
+      node.nodes.add(new Element.tag('hr'));
+      expect(node.nodes.last, isHRElement);
+    });
+
+    test('iterator', () {
+      var nodes = [];
+      var node = makeNodeWithChildren();
+      for (var subnode in node.nodes) {
+        nodes.add(subnode);
+      }
+      expect(nodes[0], isText);
+      expect(nodes[1], isBRElement);
+      expect(nodes[2], isComment);
+    });
+
+    test('addAll', () {
+      var node = makeNodeWithChildren();
+      node.nodes.addAll([
+        new Element.tag('hr'),
+        new Element.tag('img'),
+        new Element.tag('input')
+      ]);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isBRElement);
+      expect(node.nodes[2], isComment);
+      expect(node.nodes[3], isHRElement);
+      expect(node.nodes[4], isImageElement);
+      expect(node.nodes[5], isInputElement);
+
+      var a = makeNodeWithChildren();
+      var b = makeNodeWithChildren();
+      var childrenLength = a.children.length + b.children.length;
+      var nodesLength = a.nodes.length + b.nodes.length;
+
+      a.children.addAll(b.children);
+      expect(b.children.length, 0);
+      expect(a.children.length, childrenLength);
+
+      b.nodes.addAll(a.children);
+      expect(a.children.length, 0);
+      expect(b.children.length, childrenLength);
+
+      a.nodes.addAll(b.nodes);
+      expect(b.nodes.length, 0);
+      expect(a.nodes.length, nodesLength);
+    });
+
+    test('insert', () {
+      var node = new DivElement();
+      node.nodes.insert(0, new BRElement());
+      expect(node.nodes[0], isBRElement);
+      node.nodes.insert(0, new HRElement());
+      expect(node.nodes[0], isHRElement);
+      node.nodes.insert(1, new ImageElement());
+      expect(node.nodes[1], isImageElement);
+      node.nodes.insert(node.nodes.length, new InputElement());
+      expect(node.nodes.last, isInputElement);
+    });
+
+    test('clear', () {
+      var node = makeNodeWithChildren();
+      node.nodes.clear();
+      expect(node.nodes, []);
+    });
+
+    test('removeLast', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes.removeLast(), isComment);
+      expect(node.nodes.length, 2);
+      expect(node.nodes.removeLast(), isBRElement);
+      expect(node.nodes.length, 1);
+    });
+
+    test('getRange', () {
+      var items = makeNodeWithChildren().nodes.getRange(0, 1);
+      expect(items.length, 1);
+      expect(items.first, isText);
+    });
+
+    test('sublist', () {
+      var node = makeNodeWithChildren();
+      expect(node.nodes.sublist(1, 3), isNodeList);
+    });
+
+    test('insertAll', () {
+      var node = makeNodeWithChildren();
+      var b = new DivElement();
+      b.nodes.addAll([new HRElement(), new ImageElement(), new InputElement()]);
+      node.nodes.insertAll(1, b.nodes);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isImageElement);
+      expect(node.nodes[3], isInputElement);
+      expect(node.nodes[4], isBRElement);
+      expect(node.nodes[5], isComment);
+
+      var nodes = [new HRElement(), new ImageElement(), new InputElement()];
+      node.nodes.insertAll(5, nodes);
+
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isImageElement);
+      expect(node.nodes[3], isInputElement);
+      expect(node.nodes[4], isBRElement);
+      expect(node.nodes[5], isHRElement);
+      expect(node.nodes[6], isImageElement);
+      expect(node.nodes[7], isInputElement);
+      expect(node.nodes[8], isComment);
+
+      var d = new DivElement();
+      var ns = d.nodes;
+      // `insertAll` should work when positioned at end.
+      ns.insertAll(ns.length, [new HRElement()]);
+      expect(ns.length, 1);
+      expect(ns[0], isHRElement);
+    });
+
+    testUnsupported('removeRange', () {
+      makeNodeWithChildren().nodes.removeRange(0, 1);
+    });
+
+    testUnsupported('replaceRange', () {
+      makeNodeWithChildren().nodes.replaceRange(0, 1, [new InputElement()]);
+    });
+
+    testUnsupported('fillRange', () {
+      makeNodeWithChildren().nodes.fillRange(0, 1, null);
+    });
+
+    testUnsupported('setAll', () {
+      makeNodeWithChildren().nodes.setAll(0, [new InputElement()]);
+    });
+  });
+
+  group('iterating', () {
+    test('NodeIterator', () {
+      var root = makeNodeWithChildren();
+      var nodeIterator = new NodeIterator(root, NodeFilter.SHOW_COMMENT);
+      expect(nodeIterator.nextNode(), isComment);
+      expect(nodeIterator.nextNode(), isNull);
+    });
+
+    test('TreeWalker', () {
+      var root = makeNodeWithChildren();
+      var treeWalker = new TreeWalker(root, NodeFilter.SHOW_COMMENT);
+      expect(treeWalker.nextNode(), isComment);
+      expect(treeWalker.nextNode(), isNull);
+    });
+  });
+}
diff --git a/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
new file mode 100644
index 0000000..0faaf09
--- /dev/null
+++ b/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
@@ -0,0 +1,484 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This tests HTML validation and sanitization, which is very important
+/// for prevent XSS or other attacks. If you suppress this, or parts of it
+/// please make it a critical bug and bring it to the attention of the
+/// dart:html maintainers.
+library node_validator_test;
+
+import 'dart:html';
+import 'dart:svg' as svg;
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+void validateHtml(String html, String reference, NodeValidator validator) {
+  var a = document.body!.createFragment(html, validator: validator);
+  var b = document.body!
+      .createFragment(reference, treeSanitizer: NodeTreeSanitizer.trusted);
+
+  // Prevent a false pass when both the html and the reference both get entirely
+  // deleted, which is technically a match, but unlikely to be what we meant.
+  if (reference != '') {
+    expect(b.childNodes.length > 0, isTrue);
+  }
+  validateNodeTree(a, b);
+}
+
+class RecordingUriValidator implements UriPolicy {
+  final List<String> calls = <String>[];
+
+  bool allowsUri(String uri) {
+    calls.add('$uri');
+    return false;
+  }
+
+  void reset() {
+    calls.clear();
+  }
+}
+
+void testHtml(String name, NodeValidator validator, String html,
+    [String? reference]) {
+  test(name, () {
+    if (reference == null) {
+      reference = html;
+    }
+
+    validateHtml(html, reference!, validator);
+  });
+}
+
+main() {
+  group('DOM_sanitization', () {
+    var validator = new NodeValidatorBuilder.common();
+
+    testHtml('allows simple constructs', validator,
+        '<div class="baz">something</div>');
+
+    testHtml('blocks unknown attributes', validator,
+        '<div foo="baz">something</div>', '<div>something</div>');
+
+    testHtml('blocks custom element', validator,
+        '<x-my-element>something</x-my-element>', '');
+
+    testHtml('blocks custom is element', validator,
+        '<div is="x-my-element">something</div>', '');
+
+    testHtml(
+        'blocks body elements', validator, '<body background="s"></body>', '');
+
+    testHtml(
+        'allows select elements',
+        validator,
+        '<select>'
+            '<option>a</option>'
+            '</select>');
+
+    testHtml('blocks sequential script elements', validator,
+        '<div><script></script><script></script></div>', '<div></div>');
+
+    testHtml('blocks inline styles', validator,
+        '<div style="background: red"></div>', '<div></div>');
+
+    testHtml('blocks namespaced attributes', validator,
+        '<div ns:foo="foo"></div>', '<div></div>');
+
+    testHtml('blocks namespaced common attributes', validator,
+        '<div ns:class="foo"></div>', '<div></div>');
+
+    testHtml('blocks namespaced common elements', validator,
+        '<ns:div></ns:div>', '');
+
+    testHtml('allows CDATA sections', validator,
+        '<span>![CDATA[ some text ]]></span>');
+
+    testHtml('backquotes not removed', validator,
+        '<img src="dice.png" alt="``onload=xss()" />');
+
+    testHtml('0x3000 not removed', validator,
+        '<a href="&#x3000;javascript:alert(1)">CLICKME</a>');
+
+    test('sanitizes template contents', () {
+      if (!TemplateElement.supported) return;
+
+      var html = '<template>'
+          '<div></div>'
+          '<script></script>'
+          '<img src="http://example.com/foo"/>'
+          '</template>';
+
+      var fragment = document.body!.createFragment(html, validator: validator);
+      var template = fragment.nodes.single as TemplateElement;
+
+      var expectedContent = document.body!.createFragment('<div></div>'
+          '<img/>');
+
+      validateNodeTree(template.content, expectedContent);
+    });
+
+    test("appendHtml is sanitized", () {
+      var html = '<body background="s"></body><div></div>';
+      document.body!.appendHtml('<div id="stuff"></div>');
+      var stuff = document.querySelector("#stuff")!;
+      stuff.appendHtml(html);
+      expect(stuff.childNodes.length, 1);
+      stuff.remove();
+    });
+
+    test("documentFragment.appendHtml is sanitized", () {
+      var html = '<div id="things></div>';
+      var fragment = new DocumentFragment.html(html);
+      fragment.appendHtml('<div id="bad"><script></script></div>');
+      expect(fragment.childNodes.length, 1);
+      var child = fragment.childNodes[0] as Element;
+      expect(child.id, "bad");
+      expect(child.childNodes.length, 0);
+    });
+
+    testHtml(
+        "sanitizes embed",
+        validator,
+        "<div><embed src='' type='application/x-shockwave-flash'></embed></div>",
+        "<div></div>");
+  });
+
+  group('URI_sanitization', () {
+    var recorder = new RecordingUriValidator();
+    var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder);
+
+    checkUriPolicyCalls(String name, String html, String reference,
+        List<String> expectedCalls) {
+      test(name, () {
+        recorder.reset();
+
+        validateHtml(html, reference, validator);
+        expect(recorder.calls, expectedCalls);
+      });
+    }
+
+    checkUriPolicyCalls('a::href', '<a href="s"></a>', '<a></a>', ['s']);
+
+    checkUriPolicyCalls(
+        'area::href', '<area href="s"></area>', '<area></area>', ['s']);
+
+    checkUriPolicyCalls(
+        'blockquote::cite',
+        '<blockquote cite="s"></blockquote>',
+        '<blockquote></blockquote>',
+        ['s']);
+    checkUriPolicyCalls(
+        'command::icon', '<command icon="s"/>', '<command/>', ['s']);
+    checkUriPolicyCalls('img::src', '<img src="s"/>', '<img/>', ['s']);
+    checkUriPolicyCalls('input::src', '<input src="s"/>', '<input/>', ['s']);
+    checkUriPolicyCalls(
+        'ins::cite', '<ins cite="s"></ins>', '<ins></ins>', ['s']);
+    checkUriPolicyCalls('q::cite', '<q cite="s"></q>', '<q></q>', ['s']);
+    checkUriPolicyCalls(
+        'video::poster', '<video poster="s"/>', '<video/>', ['s']);
+  });
+
+  group('allowNavigation', () {
+    var validator = new NodeValidatorBuilder()..allowNavigation();
+
+    testHtml('allows anchor tags', validator, '<a href="#foo">foo</a>');
+
+    testHtml('allows form elements', validator,
+        '<form method="post" action="/foo"></form>');
+
+    testHtml('disallows script navigation', validator,
+        '<a href="javascript:foo = 1">foo</a>', '<a>foo</a>');
+
+    testHtml('disallows cross-site navigation', validator,
+        '<a href="http://example.com">example.com</a>', '<a>example.com</a>');
+
+    testHtml('blocks other elements', validator,
+        '<a href="#foo"><b>foo</b></a>', '<a href="#foo"></a>');
+
+    testHtml('blocks tag extension', validator, '<a is="x-foo"></a>', '');
+  });
+
+  group('allowImages', () {
+    var validator = new NodeValidatorBuilder()..allowImages();
+
+    testHtml('allows images', validator,
+        '<img src="/foo.jpg" alt="something" width="100" height="100"/>');
+
+    testHtml('blocks onerror', validator,
+        '<img src="/foo.jpg" onerror="something"/>', '<img src="/foo.jpg"/>');
+
+    testHtml('enforces same-origin', validator,
+        '<img src="http://example.com/foo.jpg"/>', '<img/>');
+  });
+
+  group('allowCustomElement', () {
+    var validator = new NodeValidatorBuilder()
+      ..allowCustomElement('x-foo', attributes: ['bar'], uriAttributes: ['baz'])
+      ..allowHtml5();
+
+    testHtml('allows custom elements', validator,
+        '<x-foo bar="something" baz="/foo.jpg"></x-foo>');
+
+    testHtml('validates custom tag URIs', validator,
+        '<x-foo baz="http://example.com/foo.jpg"></x-foo>', '<x-foo></x-foo>');
+
+    testHtml('blocks type extensions', validator, '<div is="x-foo"></div>', '');
+
+    testHtml('blocks tags on non-matching elements', validator,
+        '<div bar="foo"></div>', '<div></div>');
+  });
+
+  group('identify Uri attributes listed as attributes', () {
+    var validator = new NodeValidatorBuilder()
+      ..allowElement('a', attributes: ['href']);
+
+    testHtml(
+        'reject different-origin link',
+        validator,
+        '<a href="http://www.google.com/foo">Google-Foo</a>',
+        '<a>Google-Foo</a>');
+  });
+
+  group('allowTagExtension', () {
+    var validator = new NodeValidatorBuilder()
+      ..allowTagExtension('x-foo', 'div',
+          attributes: ['bar'], uriAttributes: ['baz'])
+      ..allowHtml5();
+
+    testHtml('allows tag extensions', validator,
+        '<div is="x-foo" bar="something" baz="/foo.jpg"></div>');
+
+    testHtml('blocks custom elements', validator, '<x-foo></x-foo>', '');
+
+    testHtml(
+        'validates tag extension URIs',
+        validator,
+        '<div is="x-foo" baz="http://example.com/foo.jpg"></div>',
+        '<div is="x-foo"></div>');
+
+    testHtml('blocks tags on non-matching elements', validator,
+        '<div bar="foo"></div>', '<div></div>');
+
+    testHtml('blocks non-matching tags', validator,
+        '<span is="x-foo">something</span>', '');
+
+    validator = new NodeValidatorBuilder()
+      ..allowTagExtension('x-foo', 'div',
+          attributes: ['bar'], uriAttributes: ['baz'])
+      ..allowTagExtension('x-else', 'div');
+
+    testHtml('blocks tags on non-matching custom elements', validator,
+        '<div bar="foo" is="x-else"></div>', '<div is="x-else"></div>');
+  });
+
+  group('allowTemplating', () {
+    var validator = new NodeValidatorBuilder()
+      ..allowTemplating()
+      ..allowHtml5();
+
+    testHtml(
+        'allows templates', validator, '<template bind="{{a}}"></template>');
+
+    testHtml('allows template attributes', validator,
+        '<template bind="{{a}}" ref="foo" repeat="{{}}" if="{{}}" syntax="foo"></template>');
+
+    testHtml('allows template attribute', validator,
+        '<div template repeat="{{}}"></div>');
+
+    testHtml('blocks illegal template attribute', validator,
+        '<div template="foo" repeat="{{}}"></div>', '<div></div>');
+  });
+
+  group('allowSvg', () {
+    var validator = new NodeValidatorBuilder()
+      ..allowSvg()
+      ..allowTextElements();
+
+    testHtml(
+        'allows basic SVG',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+            '<image xlink:href="foo" data-foo="bar"/>'
+            '</svg>');
+
+    testHtml(
+        'blocks script elements',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg>'
+            '<script></script>'
+            '</svg>',
+        '');
+
+    testHtml(
+        'blocks script elements but allows other',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg>'
+            '<script></script><ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
+            '</svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg>'
+            '<ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
+            '</svg>');
+
+    testHtml(
+        'blocks script handlers',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+            '<image xlink:href="foo" onerror="something"/>'
+            '</svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+            '<image xlink:href="foo"/>'
+            '</svg>');
+
+    testHtml(
+        'blocks foreignObject content',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg">'
+            '<foreignobject width="100" height="150">'
+            '<body xmlns="http://www.w3.org/1999/xhtml">'
+            '<div>Some content</div>'
+            '</body>'
+            '</foreignobject>'
+            '<b>42</b>'
+            '</svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg">'
+            '<b>42</b>'
+            '</svg>');
+  });
+
+  group('allowInlineStyles', () {
+    var validator = new NodeValidatorBuilder()
+      ..allowTextElements()
+      ..allowInlineStyles();
+
+    testHtml('allows inline styles', validator,
+        '<span style="background-color:red">text</span>');
+
+    testHtml('blocks other attributes', validator,
+        '<span class="red-span"></span>', '<span></span>');
+
+    validator = new NodeValidatorBuilder()
+      ..allowTextElements()
+      ..allowInlineStyles(tagName: 'span');
+
+    testHtml('scoped allows inline styles on spans', validator,
+        '<span style="background-color:red">text</span>');
+
+    testHtml('scoped blocks inline styles on LIs', validator,
+        '<li style="background-color:red">text</li>', '<li>text</li>');
+  });
+
+  group('throws', () {
+    var validator = new NodeValidator.throws(new NodeValidatorBuilder.common());
+
+    var validationError = throwsArgumentError;
+
+    test('does not throw on valid syntax', () {
+      expect(() {
+        document.body!.createFragment('<div></div>', validator: validator);
+      }, returnsNormally);
+    });
+
+    test('throws on invalid elements', () {
+      expect(() {
+        document.body!.createFragment('<foo></foo>', validator: validator);
+      }, validationError);
+    });
+
+    test('throws on invalid attributes', () {
+      expect(() {
+        document.body!
+            .createFragment('<div foo="bar"></div>', validator: validator);
+      }, validationError);
+    });
+
+    test('throws on invalid attribute values', () {
+      expect(() {
+        document.body!.createFragment('<img src="http://example.com/foo.jpg"/>',
+            validator: validator);
+      }, validationError);
+    });
+  });
+
+  group('svg', () {
+    test('parsing', () {
+      var svgText = '<svg xmlns="http://www.w3.org/2000/svg'
+          'xmlns:xlink="http://www.w3.org/1999/xlink">'
+          '<image xlink:href="foo" data-foo="bar"/>'
+          '</svg>';
+
+      var fragment = new DocumentFragment.svg(svgText);
+      var element = fragment.nodes.first as Element;
+      expect(element is svg.SvgSvgElement, isTrue);
+      expect(element.children[0] is svg.ImageElement, isTrue);
+    });
+  });
+
+  group('dom_clobbering', () {
+    var validator = new NodeValidatorBuilder.common();
+
+    testHtml(
+        'DOM clobbering of attributes with single node',
+        validator,
+        "<form id='single_node_clobbering' onmouseover='alert(1)'><input name='attributes'>",
+        "");
+
+    testHtml(
+        'DOM clobbering of attributes with multiple nodes',
+        validator,
+        "<form onmouseover='alert(1)'><input name='attributes'>"
+            "<input name='attributes'>",
+        "");
+
+    testHtml('DOM clobbering of lastChild', validator,
+        "<form><input name='lastChild'><input onmouseover='alert(1)'>", "");
+
+    testHtml(
+        'DOM clobbering of both children and lastChild',
+        validator,
+        "<form><input name='lastChild'><input name='children'>"
+            "<input id='children'><input onmouseover='alert(1)'>",
+        "");
+
+    testHtml(
+        'DOM clobbering of both children and lastChild, different order',
+        validator,
+        "<form><input name='children'><input name='children'>"
+            "<input id='children' name='lastChild'>"
+            "<input id='bad' onmouseover='alert(1)'>",
+        "");
+
+    test('tagName makes containing form invalid', () {
+      var fragment = document.body!.createFragment(
+          "<form onmouseover='alert(2)'><input name='tagName'>",
+          validator: validator);
+      var form = fragment.lastChild as FormElement?;
+      // If the tagName was clobbered, the sanitizer should have removed
+      // the whole thing and form is null.
+      // If the tagName was not clobbered, then there will be content,
+      // but the tagName should be the normal value. IE11 has started
+      // doing this.
+      if (form != null) {
+        expect(form.tagName, 'FORM');
+      }
+    });
+
+    test('tagName without mouseover', () {
+      var fragment = document.body!
+          .createFragment("<form><input name='tagName'>", validator: validator);
+      var form = fragment.lastChild as FormElement?;
+      // If the tagName was clobbered, the sanitizer should have removed
+      // the whole thing and form is null.
+      // If the tagName was not clobbered, then there will be content,
+      // but the tagName should be the normal value.
+      if (form != null) {
+        expect(form.tagName, 'FORM');
+      }
+    });
+  });
+}
diff --git a/tests/lib/html/non_instantiated_is_test.dart b/tests/lib/html/non_instantiated_is_test.dart
new file mode 100644
index 0000000..0865b07
--- /dev/null
+++ b/tests/lib/html/non_instantiated_is_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js, that used to emit wrong code on is
+// checks of native classes that are not instantiated.
+
+import 'dart:html';
+
+import 'package:expect/expect.dart';
+
+var a = [new Object()];
+
+main() {
+  Expect.isFalse(a[0] is Node);
+}
diff --git a/tests/lib/html/notification_permission_test.dart b/tests/lib/html/notification_permission_test.dart
new file mode 100644
index 0000000..0edd8ee
--- /dev/null
+++ b/tests/lib/html/notification_permission_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  test('Notification.requestPermission', () async {
+    String permission = await Notification.requestPermission();
+    expect(permission, isNotNull);
+  });
+}
diff --git a/tests/lib/html/notification_test.dart b/tests/lib/html/notification_test.dart
new file mode 100644
index 0000000..283dc5b
--- /dev/null
+++ b/tests/lib/html/notification_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported_notification', () {
+    test('supported', () {
+      expect(Notification.supported, true);
+    });
+  });
+
+  group('constructors', () {
+    // Test that we create the notification and that the parameters have
+    // the expected values. Note that these won't actually display, because
+    // we haven't asked for permission, which would have to be done
+    // interactively, so can't run on a bot.
+    test('Notification', () {
+      var expectation = Notification.supported ? returnsNormally : throws;
+      expect(() {
+        var allDefaults = new Notification("Hello world");
+        var allSpecified = new Notification("Deluxe notification",
+            dir: "rtl",
+            body: 'All parameters set',
+            icon: 'icon.png',
+            tag: 'tag',
+            lang: 'en_US');
+        expect(allDefaults is Notification, isTrue);
+        expect(allSpecified is Notification, isTrue);
+        expect(allDefaults.title, "Hello world");
+        expect(allSpecified.title, "Deluxe notification");
+        expect(allSpecified.dir, "rtl");
+        expect(allSpecified.body, "All parameters set");
+        var icon = allSpecified.icon;
+        var tail = Uri.parse(icon).pathSegments.last;
+        expect(tail, "icon.png");
+        expect(allSpecified.tag, "tag");
+        expect(allSpecified.lang, "en_US");
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/lib/html/performance_api_test.dart b/tests/lib/html/performance_api_test.dart
new file mode 100644
index 0000000..2e5643d
--- /dev/null
+++ b/tests/lib/html/performance_api_test.dart
@@ -0,0 +1,34 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(Performance.supported, true);
+    });
+  });
+
+  group('performance', () {
+    test('PerformanceApi', () {
+      // Check that code below will not throw exceptions if supported.
+      var expectation = Performance.supported ? returnsNormally : throws;
+      expect(() {
+        var requestStart = window.performance.timing.requestStart;
+        var responseStart = window.performance.timing.responseStart;
+        var responseEnd = window.performance.timing.responseEnd;
+
+        var loading = window.performance.timing.domLoading;
+        var loadedStart = window.performance.timing.domContentLoadedEventStart;
+        var loadedEnd = window.performance.timing.domContentLoadedEventEnd;
+        var complete = window.performance.timing.domComplete;
+
+        var loadEventStart = window.performance.timing.loadEventStart;
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/lib/html/postmessage_anonymous_test.dart b/tests/lib/html/postmessage_anonymous_test.dart
new file mode 100644
index 0000000..1a6562e
--- /dev/null
+++ b/tests/lib/html/postmessage_anonymous_test.dart
@@ -0,0 +1,53 @@
+// 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.
+
+@JS()
+library postmessage_anonymous_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:expect/expect.dart';
+import 'package:js/js.dart';
+
+const String JS_CODE = """
+window.addEventListener('message', handler);
+function handler(e) {
+  var data = e.data;
+  if (typeof data == 'string') return;
+  if (data.recipient != 'JS') return;
+  var response = {recipient: 'DART', msg: data.msg};
+  window.removeEventListener('message', handler);
+  window.postMessage(response, '*');
+}
+""";
+
+const String TEST_MSG = "hello world";
+
+@JS()
+@anonymous
+class Message {
+  external String get recipient;
+  external String get msg;
+  external factory Message({required String recipient, required String msg});
+}
+
+main() {
+  var subscription;
+  subscription = window.onMessage.listen((e) {
+    var data = e.data;
+    if (data is String) return;
+    if (data['recipient'] != 'DART') return;
+    subscription.cancel();
+    Expect.equals(TEST_MSG, data['msg']);
+  });
+  injectSource(JS_CODE);
+  window.postMessage(Message(recipient: 'JS', msg: TEST_MSG), '*');
+}
+
+void injectSource(String code) {
+  final script = new ScriptElement();
+  script.type = 'text/javascript';
+  script.innerHtml = code;
+  document.body!.append(script);
+}
diff --git a/tests/lib/html/postmessage_structured_test.dart b/tests/lib/html/postmessage_structured_test.dart
new file mode 100644
index 0000000..ace743d
--- /dev/null
+++ b/tests/lib/html/postmessage_structured_test.dart
@@ -0,0 +1,193 @@
+// 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
+
+library postmessage_js_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:collection' show HashMap, SplayTreeMap;
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+final isMap = predicate((v) => v is Map);
+
+void injectSource(String code) {
+  final script = new ScriptElement();
+  script.type = 'text/javascript';
+  script.innerHtml = code;
+  document.body!.append(script);
+}
+
+Future go(String name, dynamic value) {
+  // Round-trip graph from Dart to JavaScript and back.
+
+  final JS_CODE = """
+            window.addEventListener('message', handler);
+            function handler(e) {
+              var data = e.data;
+              if (typeof data == 'string') return;
+              if (data.recipient != 'JS') return;
+              window.console.log(data.data);
+              var response = {recipient: 'DART', data: data.data};
+              window.removeEventListener('message', handler);
+              window.postMessage(response, '*');
+            }
+            """;
+  final done = new Completer();
+  var subscription;
+  subscription = window.onMessage.listen((e) {
+    var data = e.data;
+    if (data is String) return; // Messages from unit test protocol.
+    if (data['recipient'] != 'DART') return; // Not for me.
+    try {
+      subscription.cancel();
+      expect(data, isMap);
+      var returnedValue = data['data'];
+      expect(returnedValue, notEquals(value));
+      verifyGraph(value, returnedValue);
+      done.complete();
+    } catch (e) {
+      done.completeError('$name failed: $e');
+    }
+  });
+  injectSource(JS_CODE);
+  window.postMessage({'recipient': 'JS', 'data': value}, '*');
+  return done.future;
+}
+
+Future primitives() async {
+  await testJsToDartPostmessage();
+
+  var obj1 = {'a': 100, 'b': 's'};
+  var obj2 = {'x': obj1, 'y': obj1}; // DAG.
+
+  var obj3 = <String, dynamic>{};
+  obj3['a'] = 100;
+  obj3['b'] = obj3; // Cycle.
+
+  var obj4 = new SplayTreeMap<String, dynamic>(); // Different implementation.
+  obj4['a'] = 100;
+  obj4['b'] = 's';
+
+  var cyclic_list = <dynamic>[1, 2, 3];
+  cyclic_list[1] = cyclic_list;
+
+  await go('test_simple_list', [1, 2, 3]);
+  await go('test_map', obj1);
+  await go('test_DAG', obj2);
+  await go('test_cycle', obj3);
+  await go('test_simple_splay', obj4);
+  await go('const_array_1', const [
+    const [1],
+    const [2]
+  ]);
+  await go('const_array_dag', const [
+    const [1],
+    const [1]
+  ]);
+  await go('array_deferred_copy', [1, 2, 3, obj3, obj3, 6]);
+  await go('array_deferred_copy_2', [
+    1,
+    2,
+    3,
+    [4, 5, obj3],
+    [obj3, 6]
+  ]);
+  await go('cyclic_list', cyclic_list);
+}
+
+Future testJsToDartPostmessage() {
+  // Pass an object literal from JavaScript. It should be seen as a Dart Map.
+  final JS_CODE = """
+        window.postMessage({eggs: 3}, '*');
+        """;
+  final done = new Completer();
+  var subscription = null;
+  subscription = window.onMessage.listen((e) {
+    var data = e.data;
+    if (data is String) return; //    Messages from unit test protocol.
+    try {
+      subscription.cancel();
+      expect(data, isMap);
+      expect(data['eggs'], equals(3));
+      done.complete();
+    } catch (e) {
+      done.completeError(e);
+    }
+  });
+  injectSource(JS_CODE);
+  return done.future;
+}
+
+Future morePrimitives() async {
+  await testJsToDartNullPrototypeEventdata();
+}
+
+Future testJsToDartNullPrototypeEventdata() {
+  // Pass an object with a null prototype from JavaScript.
+  // It should be seen as a Dart Map.
+  final JS_CODE = """
+       // Call anonymous function to create a local scope.
+       (function() {
+          var o = Object.create(null);
+          o.eggs = 3;
+          var foo = new MessageEvent('stuff', {data: o});
+          window.dispatchEvent(foo);
+        })();
+      """;
+  final done = new Completer();
+  var subscription = null;
+  subscription = window.on['stuff'].listen((e) {
+    var data = (e as MessageEvent).data;
+    if (data is String) return; // Messages from unit test protocol.
+    try {
+      subscription.cancel();
+      expect(data, isMap);
+      expect(data['eggs'], equals(3));
+      done.complete();
+    } catch (e) {
+      done.completeError(e);
+    }
+  });
+  injectSource(JS_CODE);
+  return done.future;
+}
+
+Future typedArrays() async {
+  var array_buffer = new Uint8List(16).buffer;
+  var view_a = new Float32List.view(array_buffer, 0, 4);
+  var view_b = new Uint8List.view(array_buffer, 1, 13);
+  var typed_arrays_list = [view_a, array_buffer, view_b];
+
+  // Note that FF is failing this test because in the sent message:
+  // view_a.buffer == array_buffer
+  // But in the response:
+  // view_a.buffer != array_buffer
+  await go('typed_arrays_list', typed_arrays_list);
+}
+
+Future iframe() async {
+  await postMessageClonesData();
+}
+
+Future postMessageClonesData() {
+  var iframe = new IFrameElement();
+  var future = iframe.onLoad.first.then((_) {
+    iframe.contentWindow!.postMessage(new HashMap<String, num>(), '*');
+  });
+  iframe.src = 'about:blank';
+  document.body!.append(iframe);
+
+  return future;
+}
+
+main() async {
+  await primitives();
+  await morePrimitives();
+  await typedArrays();
+  await iframe();
+}
diff --git a/tests/lib/html/private_extension_member_test.dart b/tests/lib/html/private_extension_member_test.dart
new file mode 100644
index 0000000..4512d9e
--- /dev/null
+++ b/tests/lib/html/private_extension_member_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+import 'dart:html';
+
+main() {
+  // Regression test for: https://github.com/dart-lang/dev_compiler/issues/508.
+  // "dart:html" defines some private members on native DOM types and we need
+  // to ensure those can be accessed correctly.
+  //
+  // The createFragment() method sets `_innerHtml` on the element, so we use it
+  // as a test case.
+  Expect.equals("[object DocumentFragment]",
+      new BRElement().createFragment("Hi").toString());
+}
diff --git a/tests/lib/html/query_test.dart b/tests/lib/html/query_test.dart
new file mode 100644
index 0000000..82ffa2f
--- /dev/null
+++ b/tests/lib/html/query_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  final div = new DivElement();
+  final canvas = new CanvasElement(width: 200, height: 200);
+  canvas.id = 'testcanvas';
+  final element = new Element.html("<div><br/><img/><input/><img/></div>");
+  document.body!.nodes.addAll([div, canvas, element]);
+
+  var isCanvasElement =
+      predicate((x) => x is CanvasElement, 'is a CanvasElement');
+  var isImageElement =
+      predicate((x) => x is ImageElement, 'is an ImageElement');
+
+  test('query', () {
+    Element? e = querySelector('#testcanvas');
+    expect(e, isNotNull);
+    expect(e!.id, 'testcanvas');
+    expect(e, isCanvasElement);
+    expect(e, canvas);
+  });
+
+  test('query (None)', () {
+    Element? e = querySelector('#nothere');
+    expect(e, isNull);
+  });
+
+  test('queryAll (One)', () {
+    List l = querySelectorAll('canvas');
+    expect(l.length, 1);
+    expect(l[0], canvas);
+  });
+
+  test('queryAll (Multiple)', () {
+    List l = querySelectorAll('img');
+    expect(l.length, 2);
+    expect(l[0], isImageElement);
+    expect(l[1], isImageElement);
+    expect(l[0] == l[1], isFalse);
+  });
+
+  test('queryAll (None)', () {
+    List l = querySelectorAll('video');
+    expect(l.isEmpty, isTrue);
+  });
+}
diff --git a/tests/lib/html/queryall_test.dart b/tests/lib/html/queryall_test.dart
new file mode 100644
index 0000000..6516a3c
--- /dev/null
+++ b/tests/lib/html/queryall_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isElement = predicate((x) => x is Element, 'is an Element');
+  var isCanvasElement =
+      predicate((x) => x is CanvasElement, 'is a CanvasElement');
+  var isDivElement = predicate((x) => x is DivElement, 'is a isDivElement');
+
+  var div = new DivElement();
+  div.id = 'test';
+  document.body!.append(div);
+
+  div.nodes.addAll([
+    new DivElement(),
+    new CanvasElement(),
+    new DivElement(),
+    new Text('Hello'),
+    new DivElement(),
+    new Text('World'),
+    new CanvasElement()
+  ]);
+
+  test('querySelectorAll', () {
+    List<Node> all = querySelectorAll('*');
+    for (var e in all) {
+      expect(e, isElement);
+    }
+  });
+
+  test('document.querySelectorAll', () {
+    List<Element> all1 = querySelectorAll('*');
+    List<Element> all2 = document.querySelectorAll('*');
+    expect(all1.length, equals(all2.length));
+    for (var i = 0; i < all1.length; ++i) {
+      expect(all1[i], equals(all2[i]));
+    }
+  });
+
+  test('querySelectorAll-canvas', () {
+    var all = querySelectorAll('canvas');
+    for (var e in all) {
+      expect(e, isCanvasElement);
+    }
+    expect(all.length, equals(2));
+  });
+
+  test('querySelectorAll-contains', () {
+    List<Element> all = querySelectorAll('*');
+    for (var e in all) {
+      expect(all.contains(e), isTrue);
+    }
+  });
+
+  test('querySelectorAll-where', () {
+    List<Element> all = querySelectorAll('*');
+    var canvases = all.where((e) => e is CanvasElement);
+    for (var e in canvases) {
+      expect(e is CanvasElement, isTrue);
+    }
+    expect(canvases.length, equals(2));
+  });
+
+  test('node.querySelectorAll', () {
+    List<Element> list = div.querySelectorAll('*');
+    expect(list.length, equals(5));
+    expect(list[0], isDivElement);
+    expect(list[1], isCanvasElement);
+    expect(list[2], isDivElement);
+    expect(list[3], isDivElement);
+    expect(list[4], isCanvasElement);
+  });
+
+  test('immutable', () {
+    List<Element> list = div.querySelectorAll('*');
+    int len = list.length;
+    expect(() {
+      list.add(new DivElement());
+    }, throwsUnsupportedError);
+    expect(list.length, equals(len));
+  });
+}
diff --git a/tests/lib/html/range_test.dart b/tests/lib/html/range_test.dart
new file mode 100644
index 0000000..489d1d9
--- /dev/null
+++ b/tests/lib/html/range_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supports_createContextualFragment', () {
+      expect(Range.supportsCreateContextualFragment, isTrue);
+    });
+  });
+
+  group('functional', () {
+    test('supported works', () {
+      var range = new Range();
+      range.selectNode(document.body!);
+
+      var expectation =
+          Range.supportsCreateContextualFragment ? returnsNormally : throws;
+
+      expect(() {
+        range.createContextualFragment('<div></div>');
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/lib/html/request_animation_frame_test.dart b/tests/lib/html/request_animation_frame_test.dart
new file mode 100644
index 0000000..d0c0447
--- /dev/null
+++ b/tests/lib/html/request_animation_frame_test.dart
@@ -0,0 +1,61 @@
+// 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.
+
+library RequestAnimationFrameTest;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+Future testOneShot() async {
+  final done = new Completer();
+  window.requestAnimationFrame(done.complete);
+  await done.future;
+}
+
+Future testTwoShot() async {
+  final done = new Completer();
+  window.requestAnimationFrame((timestamp1) {
+    window.requestAnimationFrame((timestamp2) {
+      // Not monotonic on Safari and IE.
+      // expect(timestamp2, greaterThan(timestamp1),
+      //    reason: 'timestamps ordered');
+      done.complete();
+    });
+  });
+  await done.future;
+}
+
+// How do we test that a callback is never called?  We can't wrap the uncalled
+// callback with 'expectAsync'.  Will request several frames and try
+// cancelling the one that is not the last.
+Future testCancel1() async {
+  final done = new Completer();
+  var frame1 = window.requestAnimationFrame((timestamp1) {
+    fail('Should have been cancelled');
+  });
+  var frame2 = window.requestAnimationFrame(done.complete);
+  window.cancelAnimationFrame(frame1);
+  await done.future;
+}
+
+Future testCancel2() async {
+  final done1 = new Completer();
+  final done2 = new Completer();
+  var frame1 = window.requestAnimationFrame(done1.complete);
+  var frame2 = window.requestAnimationFrame((timestamp2) {
+    fail('Should have been cancelled');
+  });
+  var frame3 = window.requestAnimationFrame(done2.complete);
+  window.cancelAnimationFrame(frame2);
+  await Future.wait([done1.future, done2.future]);
+}
+
+main() async {
+  await testOneShot();
+  await testTwoShot();
+  await testCancel1();
+  await testCancel2();
+}
diff --git a/tests/lib/html/rtc_test.dart b/tests/lib/html/rtc_test.dart
new file mode 100644
index 0000000..6b3c3581
--- /dev/null
+++ b/tests/lib/html/rtc_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(RtcPeerConnection.supported, isTrue);
+    });
+  });
+
+  group('functionality', () {
+    // More thorough testing of this API requires the user to
+    // explicitly click "allow this site to access my camera and/or microphone."
+    // or particularly allow that site to always have those permission on each
+    // computer the test is run. For more through tests, see
+    // interactive_test.dart.
+    if (RtcPeerConnection.supported) {
+      test('peer connection', () {
+        var pc = new RtcPeerConnection({
+          'iceServers': [
+            {'url': 'stun:216.93.246.18:3478'}
+          ]
+        });
+        expect(pc is RtcPeerConnection, isTrue);
+        pc.onIceCandidate.listen((candidate) {});
+      });
+
+      test('ice candidate', () {
+        var candidate =
+            new RtcIceCandidate({'sdpMLineIndex': 1, 'candidate': 'hello'});
+        expect(candidate is RtcIceCandidate, isTrue);
+      });
+
+      test('session description', () {
+        var description =
+            new RtcSessionDescription({'sdp': 'foo', 'type': 'offer'});
+        expect(description is RtcSessionDescription, isTrue);
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/selectelement_test.dart b/tests/lib/html/selectelement_test.dart
new file mode 100644
index 0000000..22b19fa
--- /dev/null
+++ b/tests/lib/html/selectelement_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('selectedOptions', () {
+    var element = new SelectElement();
+    element.multiple = false;
+    var options = [
+      new OptionElement(),
+      new DivElement(),
+      new OptionElement(data: 'data', value: 'two', selected: true),
+      new DivElement(),
+      new OptionElement(data: 'data', value: 'two', selected: true),
+      new OptionElement(),
+    ];
+    element.children.addAll(options);
+    expect(element.selectedOptions.length, 1);
+    expect(element.selectedOptions[0], equals(options[4]));
+  });
+
+  test('multiple selectedOptions', () {
+    var element = new SelectElement();
+    element.multiple = true;
+    var options = [
+      new OptionElement(),
+      new DivElement(),
+      new OptionElement(data: 'data', value: 'two', selected: true),
+      new DivElement(),
+      new OptionElement(data: 'data', value: 'two', selected: true),
+      new OptionElement(),
+      new OptionElement(data: 'data', value: 'two', selected: false),
+    ];
+    element.children.addAll(options);
+    expect(element.selectedOptions.length, 2);
+    expect(element.selectedOptions[0], equals(options[2]));
+    expect(element.selectedOptions[1], equals(options[4]));
+  });
+
+  test('options', () {
+    var element = new SelectElement();
+    var options = [
+      new OptionElement(),
+      new OptionElement(data: 'data', value: 'two', selected: true),
+      new OptionElement(data: 'data', value: 'two', selected: true),
+      new OptionElement(),
+    ];
+    element.children.addAll(options);
+    // Use last to make sure that the list was correctly wrapped.
+    expect(element.options.last, equals(options[3]));
+  });
+
+  test('optgroup', () {
+    var element = new Element.html('<select>'
+        '<option>1</option>'
+        '<optgroup>'
+        '<option>2</option>'
+        '</optgroup>'
+        '</select>') as SelectElement;
+
+    expect(element.options.length, 2);
+    element.selectedIndex = 1;
+
+    var optGroup = element.children[1];
+    expect(optGroup is OptGroupElement, isTrue);
+    expect((optGroup.children.single as OptionElement).selected, isTrue);
+    expect(element.selectedOptions, optGroup.children);
+  });
+}
diff --git a/tests/lib/html/serialized_script_value_test.dart b/tests/lib/html/serialized_script_value_test.dart
new file mode 100644
index 0000000..02370b8
--- /dev/null
+++ b/tests/lib/html/serialized_script_value_test.dart
@@ -0,0 +1,54 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+serializationTest(name, value) {
+  test(name, () {
+    // To check how value is serialized and deserialized, we create a
+    // MessageEvent.
+    final event =
+        new MessageEvent('', data: value, origin: '', lastEventId: '');
+    verifyGraph(value, event.data);
+  });
+}
+
+main() {
+  serializationTest('null', null);
+  serializationTest('int', 1);
+  serializationTest('double', 2.39);
+  serializationTest('string', 'hey!');
+
+  final simpleMap = {'a': 100, 'b': 's'};
+  final dagMap = {'x': simpleMap, 'y': simpleMap};
+  final cyclicMap = {'b': dagMap};
+  cyclicMap['a'] = cyclicMap;
+  serializationTest('simple map', simpleMap);
+  serializationTest('dag map', dagMap);
+  serializationTest('cyclic map', cyclicMap);
+
+  final simpleList = [100, 's'];
+  final dagList = [simpleList, simpleList];
+  final cyclicList = [dagList];
+  cyclicList.add(cyclicList);
+  serializationTest('simple list', simpleList);
+  serializationTest('dag list', dagList);
+  serializationTest('cyclic list', cyclicList);
+
+  serializationTest('datetime', [new DateTime.now()]);
+
+  var blob = new Blob(
+      ['Indescribable... Indestructible! Nothing can stop it!'], 'text/plain');
+  serializationTest('blob', [blob]);
+
+  var canvas = new CanvasElement();
+  canvas.width = 100;
+  canvas.height = 100;
+  var imageData = canvas.context2D.getImageData(0, 0, 1, 1);
+  serializationTest('imagedata', [imageData]);
+}
diff --git a/tests/lib/html/shadow_dom_test.dart b/tests/lib/html/shadow_dom_test.dart
new file mode 100644
index 0000000..3199982
--- /dev/null
+++ b/tests/lib/html/shadow_dom_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(ShadowRoot.supported, true);
+    });
+  });
+
+  group('ShadowDOM_tests', () {
+    var div1, div2, shadowRoot, paragraph1, paragraph2;
+
+    init() {
+      paragraph1 = new ParagraphElement();
+      paragraph2 = new ParagraphElement();
+      [paragraph1, paragraph2].forEach((p) {
+        p.classes.add('foo');
+      });
+      div1 = new DivElement();
+      div2 = new DivElement();
+      div1.classes.add('foo');
+      shadowRoot = div2.createShadowRoot();
+      shadowRoot.append(paragraph1);
+      shadowRoot.append(new ContentElement());
+      div2.append(paragraph2);
+      document.body!.append(div1);
+      document.body!.append(div2);
+    }
+
+    var expectation = ShadowRoot.supported ? returnsNormally : throws;
+
+    test("Shadowed nodes aren't visible to queries from outside ShadowDOM", () {
+      expect(() {
+        init();
+
+        expect(querySelectorAll('.foo'), equals([div1, paragraph2]));
+      }, expectation);
+    });
+
+    test('Parent node of a shadow root must be null.', () {
+      expect(() {
+        init();
+
+        expect(shadowRoot.parent, isNull);
+      }, expectation);
+    });
+
+    // TODO(samhop): test that <content> and <content select="foo"> and
+    // <shadow>
+    // work properly. This is blocked on having a good way to do browser
+    // rendering tests.
+
+    test('Querying in shadowed fragment respects the shadow boundary.', () {
+      expect(() {
+        init();
+
+        expect(shadowRoot.querySelectorAll('.foo'), equals([paragraph1]));
+      }, expectation);
+    });
+
+    if (ShadowRoot.supported) {
+      test('Shadowroot contents are distributed', () {
+        var div = new DivElement();
+
+        var box1 = new DivElement()..classes.add('foo');
+        div.append(box1);
+
+        var box2 = new DivElement();
+        div.append(box2);
+
+        var sRoot = div.createShadowRoot();
+        var content1 = new ContentElement()..select = ".foo";
+        sRoot.append(content1);
+
+        var content2 = new ContentElement();
+        sRoot.append(content2);
+
+        expect(content1.getDistributedNodes(), [box1]);
+        expect(content2.getDistributedNodes(), [box2]);
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/shadowroot_test.dart b/tests/lib/html/shadowroot_test.dart
new file mode 100644
index 0000000..85c4ac1
--- /dev/null
+++ b/tests/lib/html/shadowroot_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isShadowRoot = predicate((x) => x is ShadowRoot, 'is a ShadowRoot');
+
+  test('ShadowRoot supported', () {
+    var isSupported = ShadowRoot.supported;
+
+    // If it's supported, then it should work. Otherwise should fail.
+    if (isSupported) {
+      var div = new DivElement();
+      var shadowRoot = div.createShadowRoot();
+      expect(shadowRoot, isShadowRoot);
+      expect(div.shadowRoot, shadowRoot);
+    } else {
+      expect(() => new DivElement().createShadowRoot(), throws);
+    }
+  });
+}
diff --git a/tests/lib/html/small.mp4 b/tests/lib/html/small.mp4
new file mode 100644
index 0000000..5bb2780
--- /dev/null
+++ b/tests/lib/html/small.mp4
Binary files differ
diff --git a/tests/lib/html/small.webm b/tests/lib/html/small.webm
new file mode 100644
index 0000000..ff01e61
--- /dev/null
+++ b/tests/lib/html/small.webm
Binary files differ
diff --git a/tests/lib/html/speechrecognition_test.dart b/tests/lib/html/speechrecognition_test.dart
new file mode 100644
index 0000000..066faf0
--- /dev/null
+++ b/tests/lib/html/speechrecognition_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(SpeechRecognition.supported, true);
+    });
+  });
+
+  group('types', () {
+    var expectation = SpeechRecognition.supported ? returnsNormally : throws;
+
+    test('SpeechRecognition', () {
+      expect(() {
+        var s = new SpeechRecognition();
+        expect(s is SpeechRecognition, true);
+        expect(s.onStart.listen is Function, true);
+      }, expectation);
+    });
+
+    test('SpeechRecognitionEvent', () {
+      expect(() {
+        var e = new SpeechRecognitionEvent('speech');
+        expect(e is SpeechRecognitionEvent, true);
+      }, expectation);
+    });
+
+    test('SpeechRecognitionError', () {
+      expect(() {
+        var e = new SpeechRecognitionError('speech');
+        expect(e is SpeechRecognitionError, true);
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/lib/html/storage_promise_test.dart b/tests/lib/html/storage_promise_test.dart
new file mode 100644
index 0000000..4c8e54d
--- /dev/null
+++ b/tests/lib/html/storage_promise_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library interactive_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+import 'package:async_helper/async_helper.dart';
+
+main() async {
+  bool thenEstimateBefore = false;
+  bool thenEstimateAfter = false;
+  bool thenEstimateDone = false;
+  late Map thenEstimate;
+  test('Basic Promise Test', () async {
+    try {
+      thenEstimateBefore = true;
+      window.navigator.storage.estimate().then((value) {
+        thenEstimate = value!;
+        thenEstimateDone = true;
+      });
+      thenEstimateAfter = true;
+    } catch (msg) {
+      fail("StorageManger failed: $msg");
+    }
+
+    Map estimate = await window.navigator.storage.estimate() as Map;
+
+    expect(thenEstimate['usage'] >= 0, true);
+    expect(thenEstimate['quota'] > 1, true);
+    expect(thenEstimate['usage'], estimate['usage']);
+    expect(thenEstimate['quota'], estimate['quota']);
+
+    expect(thenEstimateBefore, true);
+    expect(thenEstimateAfter, true);
+    expect(thenEstimateDone, true);
+  });
+}
diff --git a/tests/lib/html/storage_test.dart b/tests/lib/html/storage_test.dart
new file mode 100644
index 0000000..21f6e82
--- /dev/null
+++ b/tests/lib/html/storage_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('GetItem', () {
+    final value = window.localStorage['does not exist'];
+    expect(value, isNull);
+  });
+  test('SetItem', () {
+    final key = 'foo';
+    final value = 'bar';
+    window.localStorage[key] = value;
+    final stored = window.localStorage[key];
+    expect(stored, value);
+  });
+
+  test('event', () {
+    // Bug 8076 that not all optional params are optional in Dartium.
+    var event = new StorageEvent('something',
+        oldValue: 'old', newValue: 'new', url: 'url', key: 'key');
+    expect(event is StorageEvent, isTrue);
+    expect(event.oldValue, 'old');
+    expect(event.newValue, 'new');
+  });
+}
diff --git a/tests/lib/html/streams_test.dart b/tests/lib/html/streams_test.dart
new file mode 100644
index 0000000..2d5c210
--- /dev/null
+++ b/tests/lib/html/streams_test.dart
@@ -0,0 +1,278 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+class StreamHelper {
+  var _a;
+  StreamHelper() {
+    _a = new TextInputElement();
+    document.body!.append(_a);
+  }
+
+  Element get element => _a;
+  Stream<Event?> get stream => _a.onFocus;
+
+  // Causes an event on a to be fired.
+  void pulse() {
+    var event = new Event('focus');
+    _a.dispatchEvent(event);
+  }
+}
+
+main() {
+  test('simple', () {
+    var helper = new StreamHelper();
+
+    var callCount = 0;
+    helper.stream.listen((Event? e) {
+      ++callCount;
+    });
+
+    helper.pulse();
+    expect(callCount, 1);
+  });
+
+  test('broadcast', () {
+    var stream = new DivElement().onClick;
+    expect(stream.asBroadcastStream(), stream);
+    expect(stream.isBroadcast, isTrue);
+  });
+
+  // Validates that capturing events fire on parent before child.
+  test('capture', () {
+    var parent = new DivElement();
+    document.body!.append(parent);
+
+    var helper = new StreamHelper();
+    parent.append(helper.element);
+
+    var childCallCount = 0;
+    var parentCallCount = 0;
+    Element.focusEvent.forTarget(parent, useCapture: true).listen((Event e) {
+      ++parentCallCount;
+      expect(childCallCount, 0);
+    });
+
+    Element.focusEvent
+        .forTarget(helper.element, useCapture: true)
+        .listen((Event e) {
+      ++childCallCount;
+      expect(parentCallCount, 1);
+    });
+
+    helper.pulse();
+    expect(childCallCount, 1);
+    expect(parentCallCount, 1);
+  });
+
+  test('cancel', () {
+    var helper = new StreamHelper();
+
+    var callCount = 0;
+    var subscription = helper.stream.listen((_) {
+      ++callCount;
+    });
+
+    helper.pulse();
+    expect(callCount, 1);
+
+    subscription.cancel();
+    helper.pulse();
+    expect(callCount, 1);
+
+    expect(() {
+      subscription.onData((_) {});
+    }, throws);
+
+    // Calling these after a cancel does nothing.
+    subscription.cancel();
+    subscription.pause();
+    subscription.resume();
+  });
+
+  test('pause/resume', () {
+    var helper = new StreamHelper();
+
+    var callCount = 0;
+    var subscription = helper.stream.listen((_) {
+      ++callCount;
+    });
+
+    helper.pulse();
+    expect(callCount, 1);
+
+    subscription.pause();
+    helper.pulse();
+    expect(callCount, 1);
+
+    subscription.resume();
+    helper.pulse();
+    expect(callCount, 2);
+
+    var completer = new Completer<int>.sync();
+    subscription.pause(completer.future);
+    helper.pulse();
+    expect(callCount, 2);
+
+    // Paused, should have no impact.
+    subscription.pause();
+    helper.pulse();
+    subscription.resume();
+    helper.pulse();
+    expect(callCount, 2);
+
+    completer.complete(0);
+    helper.pulse();
+    expect(callCount, 3);
+
+    // Not paused, but resuming once too often is ok.
+    subscription.resume();
+  });
+
+  test('onData', () {
+    var helper = new StreamHelper();
+
+    var callCountOne = 0;
+    var subscription = helper.stream.listen((_) {
+      ++callCountOne;
+    });
+
+    helper.pulse();
+    expect(callCountOne, 1);
+
+    var callCountTwo = 0;
+    subscription.onData((_) {
+      ++callCountTwo;
+    });
+
+    helper.pulse();
+    expect(callCountOne, 1);
+    expect(callCountTwo, 1);
+  });
+
+  test('null onData', () {
+    var helper = new StreamHelper();
+
+    var subscription = helper.stream.listen(null);
+    helper.pulse();
+
+    var callCountOne = 0;
+    subscription.onData((_) {
+      ++callCountOne;
+    });
+    helper.pulse();
+    expect(callCountOne, 1);
+
+    subscription.onData(null);
+    helper.pulse();
+    expect(callCountOne, 1);
+  });
+
+  var stream = new StreamHelper().stream;
+  // Streams have had some type-checking issues, these tests just validate that
+  // those are OK.
+  test('first', () {
+    stream.first.then((_) {});
+  });
+
+  test('asBroadcastStream', () {
+    stream.asBroadcastStream().listen((_) {});
+  });
+
+  test('where', () {
+    stream.where((_) => true).listen((_) {});
+  });
+
+  test('map', () {
+    stream.map((_) => null).listen((_) {});
+  });
+
+  test('reduce', () {
+    stream.reduce((a, b) => null).then((_) {});
+  });
+
+  test('fold', () {
+    stream.fold(null, (a, b) => null).then((_) {});
+  });
+
+  test('contains', () {
+    stream.contains((_) => true).then((_) {});
+  });
+
+  test('every', () {
+    stream.every((_) => true).then((_) {});
+  });
+
+  test('any', () {
+    stream.any((_) => true).then((_) {});
+  });
+
+  test('length', () {
+    stream.length.then((_) {});
+  });
+
+  test('isEmpty', () {
+    stream.isEmpty.then((_) {});
+  });
+
+  test('toList', () {
+    stream.toList().then((_) {});
+  });
+
+  test('toSet', () {
+    stream.toSet().then((_) {});
+  });
+
+  test('take', () {
+    stream.take(1).listen((_) {});
+  });
+
+  test('takeWhile', () {
+    stream.takeWhile((_) => false).listen((_) {});
+  });
+
+  test('skip', () {
+    stream.skip(0).listen((_) {});
+  });
+
+  test('skipWhile', () {
+    stream.skipWhile((_) => false).listen((_) {});
+  });
+
+  test('distinct', () {
+    stream.distinct((a, b) => false).listen((_) {});
+  });
+
+  test('first', () {
+    stream.first.then((_) {});
+  });
+
+  test('last', () {
+    stream.last.then((_) {});
+  });
+
+  test('single', () {
+    stream.single.then((_) {});
+  });
+
+  test('firstWhere', () {
+    stream.firstWhere((_) => true).then((_) {});
+  });
+
+  test('lastWhere', () {
+    stream.lastWhere((_) => true).then((_) {});
+  });
+
+  test('singleWhere', () {
+    stream.singleWhere((_) => true).then((_) {});
+  });
+
+  test('elementAt', () {
+    stream.elementAt(0).then((_) {});
+  });
+}
diff --git a/tests/lib/html/svg_test.dart b/tests/lib/html/svg_test.dart
new file mode 100644
index 0000000..1e9a282
--- /dev/null
+++ b/tests/lib/html/svg_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:svg' as svg;
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('svgPresence', () {
+    var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
+
+    test('simpleRect', () {
+      var div = new Element.tag('div');
+      document.body!.append(div);
+      div.setInnerHtml(r'''
+<svg id='svg1' width='200' height='100'>
+<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
+</svg>
+''', validator: new NodeValidatorBuilder()..allowSvg());
+
+      var e = document.querySelector('#svg1');
+      expect(e, isNotNull);
+
+      svg.RectElement r = document.querySelector('#rect1') as svg.RectElement;
+      expect(r.x.baseVal.value, 10);
+      expect(r.y.baseVal.value, 20);
+      expect(r.height.baseVal.value, 40);
+      expect(r.width.baseVal.value, 130);
+      expect(r.rx.baseVal.value, 5);
+    });
+
+    test('trailing newline', () {
+      // Ensures that we handle SVG with trailing newlines.
+      var logo = new svg.SvgElement.svg("""
+        <svg xmlns='http://www.w3.org/2000/svg' version='1.1'>
+          <path/>
+        </svg>
+        """);
+
+      expect(logo, isSvgElement);
+    });
+  });
+
+  group('svgInterfaceMatch', () {
+    // Test that SVG elements explicitly implement the IDL interfaces (is-checks
+    // only, see SVGTest3 for behavioural tests).
+    insertTestDiv() {
+      var element = new Element.tag('div');
+      element.setInnerHtml(r'''
+<svg id='svg1' width='200' height='100'>
+<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
+</svg>
+''', validator: new NodeValidatorBuilder()..allowSvg());
+      document.body!.append(element);
+      return element;
+    }
+
+    var isElement = predicate((x) => x is Element, 'is an Element');
+    var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
+    var isSvgSvgElement =
+        predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
+    var isNotSvgSvgElement =
+        predicate((x) => x is! svg.SvgSvgElement, 'is not a SvgSvgElement');
+    var isNode = predicate((x) => x is Node, 'is a Node');
+    var isSvgNumber = predicate((x) => x is svg.Number, 'is a svg.Number');
+    var isNotSvgNumber =
+        predicate((x) => x is! svg.Number, 'is not a svg.Number');
+    var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
+    var isNotSvgRect = predicate((x) => x is! svg.Rect, 'is not a svg.Rect');
+
+    test('rect_isChecks', () {
+      var div = insertTestDiv();
+      var r = document.querySelector('#rect1');
+
+      // Direct inheritance chain
+      expect(r, isSvgElement);
+      expect(r, isElement);
+      expect(r, isNode);
+
+      // Interfaces not implemented.
+      expect(r, isNotSvgNumber);
+      expect(r, isNotSvgRect);
+      expect(r, isNotSvgSvgElement);
+
+      div.remove();
+    });
+  });
+
+  insertTestDiv() {
+    var element = new Element.tag('div');
+    element.innerHtml = r'''
+<svg id='svg1' width='200' height='100'>
+<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
+</svg>
+''';
+    document.body!.append(element);
+    return element;
+  }
+
+  group('svgBehavioral', () {
+    // Test that SVG elements have the operations advertised through all the IDL
+    // interfaces.  This is a 'duck typing' test, and does not explicitly use
+    // 'is' checks on the expected interfaces (that is in the test group above).
+
+    var isString = predicate((x) => x is String, 'is a String');
+    var isStringList = predicate((x) => x is List<String>, 'is a List<String>');
+    var isSvgMatrix = predicate((x) => x is svg.Matrix, 'is a svg.Matrix');
+    var isSvgAnimatedBoolean =
+        predicate((x) => x is svg.AnimatedBoolean, 'is an svg.AnimatedBoolean');
+    var isSvgAnimatedString =
+        predicate((x) => x is svg.AnimatedString, 'is an svg.AnimatedString');
+    var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
+    var isSvgAnimatedTransformList = predicate(
+        (x) => x is svg.AnimatedTransformList,
+        'is an svg.AnimatedTransformList');
+    var isCssStyleDeclaration =
+        predicate((x) => x is CssStyleDeclaration, 'is a CssStyleDeclaration');
+
+    testRect(name, checker) {
+      test(name, () {
+        var div = insertTestDiv();
+        var r = document.querySelector('#rect1');
+        checker(r);
+        div.remove();
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/svgelement_test.dart b/tests/lib/html/svgelement_test.dart
new file mode 100644
index 0000000..24d7470
--- /dev/null
+++ b/tests/lib/html/svgelement_test.dart
@@ -0,0 +1,478 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:svg' as svg;
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isSvgSvgElement =
+      predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
+
+  List<String> _nodeStrings(Iterable<Node> input) {
+    final List<String> out = [];
+    for (Node n in input) {
+      if (n is Element) {
+        Element e = n;
+        out.add(e.tagName);
+      } else {
+        out.add(n.text!);
+      }
+    }
+    return out;
+  }
+
+  testConstructor(String tagName, Function isExpectedClass,
+      [bool expectation = true, allowsInnerHtml = true]) {
+    test(tagName, () {
+      expect(isExpectedClass(new svg.SvgElement.tag(tagName)), expectation);
+      if (allowsInnerHtml) {
+        expect(isExpectedClass(new svg.SvgElement.svg('<$tagName></$tagName>')),
+            expectation && allowsInnerHtml);
+      }
+    });
+  }
+
+  group('additionalConstructors', () {
+    test('valid', () {
+      final svgContent = "<svg version=\"1.1\">\n"
+          "  <circle></circle>\n"
+          "  <path></path>\n"
+          "</svg>";
+      final el = new svg.SvgElement.svg(svgContent);
+      expect(el, isSvgSvgElement);
+      expect(
+          el.innerHtml,
+          anyOf([
+            "<circle></circle><path></path>",
+            '<circle '
+                'xmlns="http://www.w3.org/2000/svg" /><path '
+                'xmlns="http://www.w3.org/2000/svg" />'
+          ]));
+      expect(
+          el.outerHtml,
+          anyOf([
+            svgContent,
+            '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">\n  '
+                '<circle />\n  <path />\n</svg>'
+          ]));
+    });
+
+    test('has no parent',
+        () => expect(new svg.SvgElement.svg('<circle/>').parent, isNull));
+
+    test('empty', () {
+      expect(() => new svg.SvgElement.svg(""), throwsStateError);
+    });
+
+    test('too many elements', () {
+      expect(() => new svg.SvgElement.svg("<circle></circle><path></path>"),
+          throwsStateError);
+    });
+  });
+
+  // Unfortunately, because the filtering mechanism in unittest is a regex done
+  group('supported_animate', () {
+    test('supported', () {
+      expect(svg.AnimateElement.supported, true);
+    });
+  });
+
+  group('supported_animateMotion', () {
+    test('supported', () {
+      expect(svg.AnimateMotionElement.supported, true);
+    });
+  });
+
+  group('supported_animateTransform', () {
+    test('supported', () {
+      expect(svg.AnimateTransformElement.supported, true);
+    });
+  });
+
+  group('supported_feBlend', () {
+    test('supported', () {
+      expect(svg.FEBlendElement.supported, true);
+    });
+  });
+
+  group('supported_feColorMatrix', () {
+    test('supported', () {
+      expect(svg.FEColorMatrixElement.supported, true);
+    });
+  });
+
+  group('supported_feComponentTransfer', () {
+    test('supported', () {
+      expect(svg.FEComponentTransferElement.supported, true);
+    });
+  });
+
+  group('supported_feConvolveMatrix', () {
+    test('supported', () {
+      expect(svg.FEConvolveMatrixElement.supported, true);
+    });
+  });
+
+  group('supported_feDiffuseLighting', () {
+    test('supported', () {
+      expect(svg.FEDiffuseLightingElement.supported, true);
+    });
+  });
+
+  group('supported_feDisplacementMap', () {
+    test('supported', () {
+      expect(svg.FEDisplacementMapElement.supported, true);
+    });
+  });
+
+  group('supported_feDistantLight', () {
+    test('supported', () {
+      expect(svg.FEDistantLightElement.supported, true);
+    });
+  });
+
+  group('supported_feFlood', () {
+    test('supported', () {
+      expect(svg.FEFloodElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncA', () {
+    test('supported', () {
+      expect(svg.FEFuncAElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncB', () {
+    test('supported', () {
+      expect(svg.FEFuncBElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncG', () {
+    test('supported', () {
+      expect(svg.FEFuncGElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncR', () {
+    test('supported', () {
+      expect(svg.FEFuncRElement.supported, true);
+    });
+  });
+
+  group('supported_feGaussianBlur', () {
+    test('supported', () {
+      expect(svg.FEGaussianBlurElement.supported, true);
+    });
+  });
+
+  group('supported_feImage', () {
+    test('supported', () {
+      expect(svg.FEImageElement.supported, true);
+    });
+  });
+
+  group('supported_feMerge', () {
+    test('supported', () {
+      expect(svg.FEMergeElement.supported, true);
+    });
+  });
+
+  group('supported_feMergeNode', () {
+    test('supported', () {
+      expect(svg.FEMergeNodeElement.supported, true);
+    });
+  });
+
+  group('supported_feOffset', () {
+    test('supported', () {
+      expect(svg.FEOffsetElement.supported, true);
+    });
+  });
+
+  group('supported_feComponentTransfer', () {
+    test('supported', () {
+      expect(svg.FEPointLightElement.supported, true);
+    });
+  });
+
+  group('supported_feSpecularLighting', () {
+    test('supported', () {
+      expect(svg.FESpecularLightingElement.supported, true);
+    });
+  });
+
+  group('supported_feComponentTransfer', () {
+    test('supported', () {
+      expect(svg.FESpotLightElement.supported, true);
+    });
+  });
+
+  group('supported_feTile', () {
+    test('supported', () {
+      expect(svg.FETileElement.supported, true);
+    });
+  });
+
+  group('supported_feTurbulence', () {
+    test('supported', () {
+      expect(svg.FETurbulenceElement.supported, true);
+    });
+  });
+
+  group('supported_filter', () {
+    test('supported', () {
+      expect(svg.FilterElement.supported, true);
+    });
+  });
+
+  group('supported_foreignObject', () {
+    test('supported', () {
+      expect(svg.ForeignObjectElement.supported, true);
+    });
+  });
+
+  group('supported_set', () {
+    test('supported', () {
+      expect(svg.SetElement.supported, true);
+    });
+  });
+
+  group('constructors', () {
+    testConstructor('a', (e) => e is svg.AElement);
+    testConstructor('circle', (e) => e is svg.CircleElement);
+    testConstructor('clipPath', (e) => e is svg.ClipPathElement);
+    testConstructor('defs', (e) => e is svg.DefsElement);
+    testConstructor('desc', (e) => e is svg.DescElement);
+    testConstructor('ellipse', (e) => e is svg.EllipseElement);
+    testConstructor('g', (e) => e is svg.GElement);
+    testConstructor('image', (e) => e is svg.ImageElement);
+    testConstructor('line', (e) => e is svg.LineElement);
+    testConstructor('linearGradient', (e) => e is svg.LinearGradientElement);
+    testConstructor('marker', (e) => e is svg.MarkerElement);
+    testConstructor('mask', (e) => e is svg.MaskElement);
+    testConstructor('path', (e) => e is svg.PathElement);
+    testConstructor('pattern', (e) => e is svg.PatternElement);
+    testConstructor('polygon', (e) => e is svg.PolygonElement);
+    testConstructor('polyline', (e) => e is svg.PolylineElement);
+    testConstructor('radialGradient', (e) => e is svg.RadialGradientElement);
+    testConstructor('rect', (e) => e is svg.RectElement);
+    test('script', () {
+      expect(new svg.SvgElement.tag('script') is svg.ScriptElement, isTrue);
+    });
+    testConstructor('stop', (e) => e is svg.StopElement);
+    testConstructor('style', (e) => e is svg.StyleElement);
+    testConstructor('switch', (e) => e is svg.SwitchElement);
+    testConstructor('symbol', (e) => e is svg.SymbolElement);
+    testConstructor('tspan', (e) => e is svg.TSpanElement);
+    testConstructor('text', (e) => e is svg.TextElement);
+    testConstructor('textPath', (e) => e is svg.TextPathElement);
+    testConstructor('title', (e) => e is svg.TitleElement);
+    testConstructor('use', (e) => e is svg.UseElement);
+    testConstructor('view', (e) => e is svg.ViewElement);
+    // TODO(alanknight): Issue 23144
+    testConstructor('animate', (e) => e is svg.AnimateElement,
+        svg.AnimateElement.supported);
+    testConstructor('animateMotion', (e) => e is svg.AnimateMotionElement,
+        svg.AnimateMotionElement.supported);
+    testConstructor('animateTransform', (e) => e is svg.AnimateTransformElement,
+        svg.AnimateTransformElement.supported);
+    testConstructor('feBlend', (e) => e is svg.FEBlendElement,
+        svg.FEBlendElement.supported);
+    testConstructor('feColorMatrix', (e) => e is svg.FEColorMatrixElement,
+        svg.FEColorMatrixElement.supported);
+    testConstructor(
+        'feComponentTransfer',
+        (e) => e is svg.FEComponentTransferElement,
+        svg.FEComponentTransferElement.supported);
+    testConstructor('feConvolveMatrix', (e) => e is svg.FEConvolveMatrixElement,
+        svg.FEConvolveMatrixElement.supported);
+    testConstructor(
+        'feDiffuseLighting',
+        (e) => e is svg.FEDiffuseLightingElement,
+        svg.FEDiffuseLightingElement.supported);
+    testConstructor(
+        'feDisplacementMap',
+        (e) => e is svg.FEDisplacementMapElement,
+        svg.FEDisplacementMapElement.supported);
+    testConstructor('feDistantLight', (e) => e is svg.FEDistantLightElement,
+        svg.FEDistantLightElement.supported);
+    testConstructor('feFlood', (e) => e is svg.FEFloodElement,
+        svg.FEFloodElement.supported);
+    testConstructor('feFuncA', (e) => e is svg.FEFuncAElement,
+        svg.FEFuncAElement.supported);
+    testConstructor('feFuncB', (e) => e is svg.FEFuncBElement,
+        svg.FEFuncBElement.supported);
+    testConstructor('feFuncG', (e) => e is svg.FEFuncGElement,
+        svg.FEFuncGElement.supported);
+    testConstructor('feFuncR', (e) => e is svg.FEFuncRElement,
+        svg.FEFuncRElement.supported);
+    testConstructor('feGaussianBlur', (e) => e is svg.FEGaussianBlurElement,
+        svg.FEGaussianBlurElement.supported);
+    testConstructor('feImage', (e) => e is svg.FEImageElement,
+        svg.FEImageElement.supported);
+    testConstructor('feMerge', (e) => e is svg.FEMergeElement,
+        svg.FEMergeElement.supported);
+    testConstructor('feMergeNode', (e) => e is svg.FEMergeNodeElement,
+        svg.FEMergeNodeElement.supported);
+    testConstructor('feOffset', (e) => e is svg.FEOffsetElement,
+        svg.FEOffsetElement.supported);
+    testConstructor('fePointLight', (e) => e is svg.FEPointLightElement,
+        svg.FEPointLightElement.supported);
+    testConstructor(
+        'feSpecularLighting',
+        (e) => e is svg.FESpecularLightingElement,
+        svg.FESpecularLightingElement.supported);
+    testConstructor('feSpotLight', (e) => e is svg.FESpotLightElement,
+        svg.FESpotLightElement.supported);
+    testConstructor(
+        'feTile', (e) => e is svg.FETileElement, svg.FETileElement.supported);
+    testConstructor('feTurbulence', (e) => e is svg.FETurbulenceElement,
+        svg.FETurbulenceElement.supported);
+    testConstructor(
+        'filter', (e) => e is svg.FilterElement, svg.FilterElement.supported);
+    testConstructor('foreignObject', (e) => e is svg.ForeignObjectElement,
+        svg.ForeignObjectElement.supported, false);
+    testConstructor('metadata', (e) => e is svg.MetadataElement);
+    testConstructor(
+        'set', (e) => e is svg.SetElement, svg.SetElement.supported);
+  });
+
+  group('outerHtml', () {
+    test('outerHtml', () {
+      final el = new svg.SvgSvgElement();
+      el.children.add(new svg.CircleElement());
+      el.children.add(new svg.PathElement());
+      expect(
+          [
+            '<svg version="1.1"><circle></circle><path></path></svg>',
+            '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">'
+                '<circle /><path /></svg>',
+          ].contains(el.outerHtml),
+          true);
+    });
+  });
+
+  group('innerHtml', () {
+    test('get', () {
+      final el = new svg.SvgSvgElement();
+      el.children.add(new svg.CircleElement());
+      el.children.add(new svg.PathElement());
+      // Allow for odd IE serialization.
+      expect(
+          [
+            '<circle></circle><path></path>',
+            '<circle xmlns="http://www.w3.org/2000/svg" />'
+                '<path xmlns="http://www.w3.org/2000/svg" />'
+          ].contains(el.innerHtml),
+          true);
+    });
+
+    test('set', () {
+      final el = new svg.SvgSvgElement();
+      el.children.add(new svg.CircleElement());
+      el.children.add(new svg.PathElement());
+      el.innerHtml = '<rect></rect><a></a>';
+      expect(_nodeStrings(el.children), ["rect", "a"]);
+    });
+  });
+
+  group('elementget', () {
+    test('get', () {
+      final el = new svg.SvgElement.svg("""
+<svg version="1.1">
+  <circle></circle>
+  <path></path>
+  text
+</svg>""");
+      expect(_nodeStrings(el.children), ["circle", "path"]);
+    });
+
+    test('resize', () {
+      var el = new svg.SvgSvgElement();
+      var items = [new svg.CircleElement(), new svg.RectElement()];
+      el.children = items;
+      expect(el.children.length, 2);
+      el.children.length = 1;
+      expect(el.children.length, 1);
+      expect(el.children.contains(items[0]), true);
+      expect(el.children.contains(items[1]), false);
+
+      el.children.length = 0;
+      expect(el.children.contains(items[0]), false);
+    });
+  });
+
+  group('elementset', () {
+    test('set', () {
+      final el = new svg.SvgSvgElement();
+      el.children = [
+        new svg.SvgElement.tag("circle"),
+        new svg.SvgElement.tag("path")
+      ];
+      expect(el.nodes.length, 2);
+      expect(el.nodes[0] is svg.CircleElement, true);
+      expect(el.nodes[1] is svg.PathElement, true);
+    });
+  });
+
+  group('css', () {
+    test('classes', () {
+      var el = new svg.CircleElement();
+      var classes = el.classes;
+      expect(el.classes.length, 0);
+      classes.toggle('foo');
+      expect(el.classes.length, 1);
+      classes.toggle('foo');
+      expect(el.classes.length, 0);
+    });
+
+    test('classes-add-bad', () {
+      var el = new svg.CircleElement();
+      expect(() => el.classes.add(''), throws);
+      expect(() => el.classes.add('foo bar'), throws);
+    });
+    test('classes-remove-bad', () {
+      var el = new svg.CircleElement();
+      expect(() => el.classes.remove(''), throws);
+      expect(() => el.classes.remove('foo bar'), throws);
+    });
+    test('classes-toggle-token', () {
+      var el = new svg.CircleElement();
+      expect(() => el.classes.toggle(''), throws);
+      expect(() => el.classes.toggle('', true), throws);
+      expect(() => el.classes.toggle('', false), throws);
+      expect(() => el.classes.toggle('foo bar'), throws);
+      expect(() => el.classes.toggle('foo bar', true), throws);
+      expect(() => el.classes.toggle('foo bar', false), throws);
+    });
+    test('classes-contains-bad', () {
+      var el = new svg.CircleElement();
+      // Non-strings => false, strings must be valid tokens.
+      expect(el.classes.contains(1), isFalse);
+      expect(() => el.classes.contains(''), throws);
+      expect(() => el.classes.contains('foo bar'), throws);
+    });
+  });
+
+  group('getBoundingClientRect', () {
+    test('is a Rectangle', () {
+      var element = new svg.RectElement();
+      element.attributes['width'] = '100';
+      element.attributes['height'] = '100';
+      var root = new svg.SvgSvgElement();
+      root.append(element);
+
+      document.body!.append(root);
+
+      var rect = element.getBoundingClientRect();
+      expect(rect is Rectangle, isTrue);
+      expect(rect.width, closeTo(100, 1));
+      expect(rect.height, closeTo(100, 1));
+    });
+  });
+}
diff --git a/tests/lib/html/table_test.dart b/tests/lib/html/table_test.dart
new file mode 100644
index 0000000..cb7a4e2
--- /dev/null
+++ b/tests/lib/html/table_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('createTBody', () {
+    var table = new TableElement();
+    var head = table.createTHead();
+    expect(table.tHead, head);
+
+    var headerRow = head.addRow();
+    var headerCell = headerRow.addCell();
+    headerCell.text = 'Header Cell';
+
+    var caption = table.createCaption();
+    expect(table.caption, caption);
+
+    var body = table.createTBody();
+    expect(table.tBodies.length, 1);
+    expect(table.tBodies[0], body);
+
+    var bodyRow = body.addRow();
+    expect(body.rows.length, 1);
+    expect(body.rows[0], bodyRow);
+
+    var bodyCell = bodyRow.addCell();
+    bodyCell.text = 'Body Cell';
+    expect(bodyRow.cells.length, 1);
+    expect(bodyRow.cells[0], bodyCell);
+
+    var foot = table.createTFoot();
+    expect(table.tFoot, foot);
+
+    var footerRow = foot.addRow();
+    expect(foot.rows.length, 1);
+    expect(foot.rows[0], footerRow);
+
+    var footerCell = footerRow.addCell();
+    footerCell.text = 'Footer Cell';
+    expect(footerRow.cells.length, 1);
+    expect(footerRow.cells[0], footerCell);
+
+    var body2 = table.createTBody();
+    var bodyRow2 = body2.addRow();
+    var bodyCell2 = bodyRow2.addCell();
+    bodyCell2.text = 'Body Cell2';
+
+    expect(body2.rows.length, 1);
+
+    expect(table.tBodies.length, 2);
+    expect(table.tBodies[1], body2);
+  });
+}
diff --git a/tests/lib/html/text_event_test.dart b/tests/lib/html/text_event_test.dart
new file mode 100644
index 0000000..26c7a2a
--- /dev/null
+++ b/tests/lib/html/text_event_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+import 'event_test.dart';
+
+main() {
+  eventTest('TextEvent', () => new TextEvent('foo', view: window, data: 'data'),
+      (ev) {
+    expect(ev.data, 'data');
+  });
+}
diff --git a/tests/lib/html/touchevent_test.dart b/tests/lib/html/touchevent_test.dart
new file mode 100644
index 0000000..d91abb9
--- /dev/null
+++ b/tests/lib/html/touchevent_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('Basic TouchEvent', () {
+    if (TouchEvent.supported) {
+      var e = new TouchEvent('touch');
+      expect(e is TouchEvent, isTrue);
+    }
+  });
+}
diff --git a/tests/lib/html/track_element_constructor_test.dart b/tests/lib/html/track_element_constructor_test.dart
new file mode 100644
index 0000000..9fa006b
--- /dev/null
+++ b/tests/lib/html/track_element_constructor_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A regression test for dart2js generating illegal JavaScript code
+// dynamically in non-csp mode.  The name of the field "defaultValue"
+// in JavaScript is "default".  This meant that dart2js would create a
+// constructor function that looked like this:
+//
+// function TrackElement(default) { this.default = default; }
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+void main() {
+  test('', () {
+    if (!TrackElement.supported) return;
+    document.body!.append(new TrackElement()..defaultValue = true);
+    var trackElement = document.querySelector('track') as TrackElement;
+    if (!trackElement.defaultValue) {
+      throw 'Expected default value to be true';
+    }
+    trackElement.defaultValue = false;
+    if (trackElement.defaultValue) {
+      throw 'Expected default value to be false';
+    }
+  });
+}
diff --git a/tests/lib/html/transferables_test.dart b/tests/lib/html/transferables_test.dart
new file mode 100644
index 0000000..1f51643
--- /dev/null
+++ b/tests/lib/html/transferables_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+library TransferableTest;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+var isByteBuffer = predicate((x) => x is ByteBuffer, 'is an ByteBuffer');
+
+Future testTransferableTest() {
+  final buffer = (new Float32List(3)).buffer;
+  window.postMessage(
+      {'id': 'transferable data', 'buffer': buffer}, '*', [buffer]);
+
+  return window.onMessage.firstWhere((e) {
+    return e.data is Map && e.data['id'] == 'transferable data';
+  }).then((messageEvent) {
+    expect(messageEvent.data['buffer'], isByteBuffer);
+  });
+}
+
+main() async {
+  if (Platform.supportsTypedData) {
+    await testTransferableTest();
+  }
+}
diff --git a/tests/lib/html/transition_event_test.dart b/tests/lib/html/transition_event_test.dart
new file mode 100644
index 0000000..4376016
--- /dev/null
+++ b/tests/lib/html/transition_event_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+library transition_event_test;
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:expect/minitest.dart';
+
+Future testTransitionEnd() async {
+  var element = new DivElement();
+  document.body!.append(element);
+
+  element.style.opacity = '0';
+  element.style.width = '100px';
+  element.style.height = '100px';
+  element.style.background = 'red';
+  element.style.transition = 'opacity .1s';
+
+  final done = new Completer();
+
+  new Timer(const Duration(milliseconds: 100), () {
+    element.onTransitionEnd.first.then((e) {
+      expect(e is TransitionEvent, isTrue);
+      expect(e.propertyName, 'opacity');
+    }).then(done.complete, onError: done.completeError);
+
+    element.style.opacity = '1';
+  });
+
+  await done.future;
+}
+
+main() async {
+  expect(CssStyleDeclaration.supportsTransitions, isTrue);
+  if (CssStyleDeclaration.supportsTransitions) {
+    await testTransitionEnd();
+  }
+}
diff --git a/tests/lib/html/trusted_html_tree_sanitizer_test.dart b/tests/lib/html/trusted_html_tree_sanitizer_test.dart
new file mode 100644
index 0000000..a0d92ed
--- /dev/null
+++ b/tests/lib/html/trusted_html_tree_sanitizer_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This tests HTML validation and sanitization, which is very important
+/// for prevent XSS or other attacks. If you suppress this, or parts of it
+/// please make it a critical bug and bring it to the attention of the
+/// dart:html maintainers.
+import 'dart:js' as js;
+import 'dart:html';
+import 'dart:svg' as svg;
+
+import 'package:expect/minitest.dart';
+
+import 'utils.dart';
+
+var oldAdoptNode;
+var jsDocument;
+
+/// We want to verify that with the trusted sanitizer we are not
+/// creating a document fragment. So make DocumentFragment operation
+/// throw.
+makeDocumentFragmentAdoptionThrow() {
+  var document = js.context['document'];
+  jsDocument = new js.JsObject.fromBrowserObject(document);
+  oldAdoptNode = jsDocument['adoptNode'];
+  jsDocument['adoptNode'] = null;
+}
+
+restoreOldAdoptNode() {
+  jsDocument['adoptNode'] = oldAdoptNode;
+}
+
+main() {
+  group('not_create_document_fragment', () {
+    setUp(makeDocumentFragmentAdoptionThrow);
+    tearDown(restoreOldAdoptNode);
+
+    test('setInnerHtml', () {
+      document.body!.setInnerHtml('<div foo="baz">something</div>',
+          treeSanitizer: NodeTreeSanitizer.trusted);
+      expect(document.body!.innerHtml, '<div foo="baz">something</div>');
+    });
+
+    test("appendHtml", () {
+      var oldStuff = document.body!.innerHtml;
+      var newStuff = '<div rumplestiltskin="value">content</div>';
+      document.body!
+          .appendHtml(newStuff, treeSanitizer: NodeTreeSanitizer.trusted);
+      expect(document.body!.innerHtml, oldStuff + newStuff);
+    });
+  });
+
+  group('untrusted', () {
+    setUp(makeDocumentFragmentAdoptionThrow);
+    tearDown(restoreOldAdoptNode);
+    test('untrusted', () {
+      expect(() => document.body!.innerHtml = "<p>anything</p>", throws);
+    });
+  });
+}
diff --git a/tests/lib/html/typed_arrays_1_test.dart b/tests/lib/html/typed_arrays_1_test.dart
new file mode 100644
index 0000000..c624c62
--- /dev/null
+++ b/tests/lib/html/typed_arrays_1_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isList = predicate((x) => x is List, 'is a List');
+  var isNumList = predicate((x) => x is List<num>, 'is a List<num>');
+  var isNotStringList =
+      predicate((x) => x is! List<String>, 'is not a List<String>');
+  var expectation = Platform.supportsTypedData ? returnsNormally : throws;
+
+  group('supported', () {
+    test('supported', () {
+      expect(Platform.supportsTypedData, true);
+    });
+  });
+
+  group('arrays', () {
+    test('createByLengthTest', () {
+      expect(() {
+        var a = new Float32List(10);
+        expect(a.length, 10);
+        expect(a.lengthInBytes, 40);
+        expect(a[4], 0);
+      }, expectation);
+    });
+
+    test('aliasTest', () {
+      expect(() {
+        var a1 = new Uint8List.fromList([0, 0, 1, 0x45]);
+        var a2 = new Float32List.view(a1.buffer);
+
+        expect(a1.lengthInBytes, a2.lengthInBytes);
+
+        expect(a2.length, 1);
+
+        // 0x45010000 = 2048+16
+        expect(a2[0], 2048 + 16);
+
+        a1[2] = 0;
+        // 0x45000000 = 2048
+        expect(a2[0], 2048);
+
+        a1[3]--;
+        a1[2] += 128;
+        // 0x44800000 = 1024
+        expect(a2[0], 1024);
+      }, expectation);
+    });
+
+    // Generic type checking is not available in dart2js, so use this check to
+    // see if we should check for it.
+    var supportsTypeTest = !(new List<String>.empty() is List<int>);
+
+    if (supportsTypeTest) {
+      test('typeTests', () {
+        expect(() {
+          var a = new Float32List(10);
+          expect(a, isList);
+          expect(a, isNumList);
+          expect(a, isNotStringList);
+        }, expectation);
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/typed_arrays_2_test.dart b/tests/lib/html/typed_arrays_2_test.dart
new file mode 100644
index 0000000..51bd8c7
--- /dev/null
+++ b/tests/lib/html/typed_arrays_2_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('viewTest_dynamic', () {
+    var a1 = new Uint8List(1024);
+    for (int i = 0; i < a1.length; i++) {
+      a1[i] = i; // 0,1,2,...,254,255,0,1,2,...
+    }
+
+    var a2 = new Uint32List.view(a1.buffer);
+    expect(1024 ~/ 4, a2.length);
+    expect(a2[0], 0x03020100);
+    expect(a2[1], 0x07060504);
+    expect(a2[2], 0x0B0A0908);
+    expect(a2[50], 0xCBCAC9C8);
+    expect(a2[51], 0xCFCECDCC);
+    expect(a2[64], 0x03020100);
+
+    a2 = new Uint32List.view(a1.buffer, 200);
+    expect(a2.length, (1024 - 200) ~/ 4);
+    expect(a2[0], 0xCBCAC9C8);
+    expect(a2[1], 0xCFCECDCC);
+    expect(a2[14], 0x03020100);
+
+    a2 = new Uint32List.view(a1.buffer, 456, 20);
+    expect(a2.length, 20);
+    expect(a2[0], 0xCBCAC9C8);
+    expect(a2[1], 0xCFCECDCC);
+    expect(a2[14], 0x03020100);
+
+    // OPTIONALS a2 = new Uint32List.view(a1.buffer, length: 30, byteOffset: 456);
+    a2 = new Uint32List.view(a1.buffer, 456, 30);
+    expect(a2.length, 30);
+    expect(a2[0], 0xCBCAC9C8);
+    expect(a2[1], 0xCFCECDCC);
+    expect(a2[14], 0x03020100);
+  });
+
+  test('viewTest_typed', () {
+    Uint8List a1 = new Uint8List(1024);
+    for (int i = 0; i < a1.length; i++) {
+      a1[i] = i;
+    }
+
+    Uint32List a2 = new Uint32List.view(a1.buffer);
+    expect(a2.length, 1024 ~/ 4);
+    expect(a2[0], 0x03020100);
+    expect(a2[50], 0xCBCAC9C8);
+    expect(a2[51], 0xCFCECDCC);
+    expect(a2[64], 0x03020100);
+
+    a2 = new Uint32List.view(a1.buffer, 200);
+    expect(a2.length, (1024 - 200) ~/ 4);
+    expect(a2[0], 0xCBCAC9C8);
+    expect(a2[1], 0xCFCECDCC);
+    expect(a2[14], 0x03020100);
+
+    a2 = new Uint32List.view(a1.buffer, 456, 20);
+    expect(20, a2.length);
+    expect(a2[0], 0xCBCAC9C8);
+    expect(a2[1], 0xCFCECDCC);
+    expect(a2[14], 0x03020100);
+
+    // OPTIONALS a2 = new Uint32List.view(a1.buffer, length: 30, byteOffset: 456);
+    a2 = new Uint32List.view(a1.buffer, 456, 30);
+    expect(a2.length, 30);
+    expect(a2[0], 0xCBCAC9C8);
+    expect(a2[1], 0xCFCECDCC);
+    expect(a2[14], 0x03020100);
+  });
+}
diff --git a/tests/lib/html/typed_arrays_3_test.dart b/tests/lib/html/typed_arrays_3_test.dart
new file mode 100644
index 0000000..7a07f86
--- /dev/null
+++ b/tests/lib/html/typed_arrays_3_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('setElementsTest_dynamic', () {
+    var a1 = new Int8List(1024);
+
+    a1.setRange(4, 7, [0x50, 0x60, 0x70]);
+
+    var a2 = new Uint32List.view(a1.buffer);
+    expect(a2[0], 0x00000000);
+    expect(a2[1], 0x00706050);
+
+    a2.setRange(2, 3, [0x01020304]);
+    expect(a1[8], 0x04);
+    expect(a1[11], 0x01);
+  });
+
+  test('setElementsTest_typed', () {
+    Int8List a1 = new Int8List(1024);
+
+    a1.setRange(4, 7, [0x50, 0x60, 0x70]);
+
+    Uint32List a2 = new Uint32List.view(a1.buffer);
+    expect(a2[0], 0x00000000);
+    expect(a2[1], 0x00706050);
+
+    a2.setRange(2, 3, [0x01020304]);
+    expect(a1[8], 0x04);
+    expect(a1[11], 0x01);
+  });
+}
diff --git a/tests/lib/html/typed_arrays_4_test.dart b/tests/lib/html/typed_arrays_4_test.dart
new file mode 100644
index 0000000..ba8ee16
--- /dev/null
+++ b/tests/lib/html/typed_arrays_4_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('indexOf_dynamic', () {
+    var a1 = new Uint8List(1024);
+    for (int i = 0; i < a1.length; i++) {
+      a1[i] = i;
+    }
+
+    expect(a1.indexOf(50), 50);
+    expect(a1.indexOf(50, 50), 50);
+    expect(a1.indexOf(50, 51), 256 + 50);
+
+    expect(a1.lastIndexOf(50), 768 + 50);
+    expect(a1.lastIndexOf(50, 768 + 50), 768 + 50);
+    expect(a1.lastIndexOf(50, 768 + 50 - 1), 512 + 50);
+  });
+
+  test('indexOf_typed', () {
+    Uint8List a1 = new Uint8List(1024);
+    for (int i = 0; i < a1.length; i++) {
+      a1[i] = i;
+    }
+
+    expect(a1.indexOf(50), 50);
+    expect(a1.indexOf(50, 50), 50);
+    expect(a1.indexOf(50, 51), 256 + 50);
+
+    expect(a1.lastIndexOf(50), 768 + 50);
+    expect(a1.lastIndexOf(50, 768 + 50), 768 + 50);
+    expect(a1.lastIndexOf(50, 768 + 50 - 1), 512 + 50);
+  });
+}
diff --git a/tests/lib/html/typed_arrays_5_test.dart b/tests/lib/html/typed_arrays_5_test.dart
new file mode 100644
index 0000000..e7b1e9b
--- /dev/null
+++ b/tests/lib/html/typed_arrays_5_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('filter_dynamic', () {
+    var a = new Float32List(1024);
+    for (int i = 0; i < a.length; i++) {
+      a[i] = i.toDouble();
+    }
+
+    expect(a.where((x) => x >= 1000).length, equals(24));
+  });
+
+  test('filter_typed', () {
+    Float32List a = new Float32List(1024);
+    for (int i = 0; i < a.length; i++) {
+      a[i] = i.toDouble();
+    }
+
+    expect(a.where((x) => x >= 1000).length, equals(24));
+  });
+
+  test('contains', () {
+    var a = new Int16List(1024);
+    for (int i = 0; i < a.length; i++) {
+      a[i] = i;
+    }
+    expect(a.contains(0), isTrue);
+    expect(a.contains(5), isTrue);
+    expect(a.contains(1023), isTrue);
+
+    expect(a.contains(-5), isFalse);
+    expect(a.contains(-1), isFalse);
+    expect(a.contains(1024), isFalse);
+  });
+}
diff --git a/tests/lib/html/typed_arrays_arraybuffer_test.dart b/tests/lib/html/typed_arrays_arraybuffer_test.dart
new file mode 100644
index 0000000..784a9e2
--- /dev/null
+++ b/tests/lib/html/typed_arrays_arraybuffer_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('constructor', () {
+    var a = new Int8List(100);
+    expect(a.lengthInBytes, 100);
+  });
+
+  test('sublist1', () {
+    var a = new Int8List(100);
+    var s = a.sublist(10, 40);
+    expect(s.length, 30);
+  });
+
+  test('sublist2', () {
+    var a = new Int8List(100);
+    expect(() => a.sublist(10, 400), throwsRangeError);
+  });
+
+  test('sublist3', () {
+    var a = new Int8List(100);
+    expect(() => a.sublist(50, 10), throwsRangeError);
+  });
+
+  test('sublist4', () {
+    var a = new Int8List(100);
+    expect(() => a.sublist(-90, -30), throwsRangeError);
+  });
+}
diff --git a/tests/lib/html/typed_arrays_dataview_test.dart b/tests/lib/html/typed_arrays_dataview_test.dart
new file mode 100644
index 0000000..e774a6d
--- /dev/null
+++ b/tests/lib/html/typed_arrays_dataview_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('create', () {
+    var bd = new ByteData(100);
+    expect(bd.lengthInBytes, 100);
+    expect(bd.offsetInBytes, 0);
+
+    var a1 = new Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8]);
+
+    var bd2 = new ByteData.view(a1.buffer);
+    expect(bd2.lengthInBytes, 8);
+    expect(bd2.offsetInBytes, 0);
+
+    var bd3 = new ByteData.view(a1.buffer, 2);
+    expect(bd3.lengthInBytes, 6);
+    expect(bd3.offsetInBytes, 2);
+
+    var bd4 = new ByteData.view(a1.buffer, 3, 4);
+    expect(bd4.lengthInBytes, 4);
+    expect(bd4.offsetInBytes, 3);
+  });
+
+  test('access8', () {
+    var a1 = new Uint8List.fromList([0, 0, 3, 255, 0, 0, 0, 0, 0, 0]);
+
+    var bd = new ByteData.view(a1.buffer, 2, 6);
+
+    expect(bd.getInt8(0), equals(3));
+    expect(bd.getInt8(1), equals(-1));
+    expect(bd.getUint8(0), equals(3));
+    expect(bd.getUint8(1), equals(255));
+
+    bd.setInt8(2, -56);
+    expect(bd.getInt8(2), equals(-56));
+    expect(bd.getUint8(2), equals(200));
+
+    bd.setUint8(3, 200);
+    expect(bd.getInt8(3), equals(-56));
+    expect(bd.getUint8(3), equals(200));
+  });
+
+  test('access16', () {
+    var a1 = new Uint8List.fromList([0, 0, 3, 255, 0, 0, 0, 0, 0, 0]);
+
+    var bd = new ByteData.view(a1.buffer, 2);
+
+    expect(bd.lengthInBytes, equals(10 - 2));
+
+    expect(bd.getInt16(0), equals(1023));
+    expect(bd.getInt16(0, Endian.big), equals(1023));
+    expect(bd.getInt16(0, Endian.little), equals(-253));
+
+    expect(bd.getUint16(0), equals(1023));
+    expect(bd.getUint16(0, Endian.big), equals(1023));
+    expect(bd.getUint16(0, Endian.little), equals(0xFF03));
+
+    bd.setInt16(2, -1);
+    expect(bd.getInt16(2), equals(-1));
+    expect(bd.getUint16(2), equals(0xFFFF));
+  });
+
+  test('access32', () {
+    var a1 = new Uint8List.fromList([0, 0, 3, 255, 0, 0, 0, 0, 0, 0]);
+
+    var bd = new ByteData.view(a1.buffer);
+
+    expect(bd.getInt32(0), equals(1023));
+    expect(bd.getInt32(0, Endian.big), equals(1023));
+    expect(bd.getInt32(0, Endian.little), equals(-0xFD0000));
+
+    expect(bd.getUint32(0), equals(1023));
+    expect(bd.getUint32(0, Endian.big), equals(1023));
+    expect(bd.getUint32(0, Endian.little), equals(0xFF030000));
+  });
+}
diff --git a/tests/lib/html/typed_arrays_range_checks_test.dart b/tests/lib/html/typed_arrays_range_checks_test.dart
new file mode 100644
index 0000000..f6d8dbf
--- /dev/null
+++ b/tests/lib/html/typed_arrays_range_checks_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+const N = 1024;
+
+class _TestList {
+  _TestList(int n);
+
+  operator [](int i) => i;
+  operator []=(int i, v) {}
+}
+
+_obfuscatedList() {
+  var a = new Uint8List(N);
+  var b = new _TestList(N);
+  var k = 0;
+  for (int i = 0; i < 10; ++i) {
+    k += i;
+  }
+  return (k == 45) ? a : b;
+}
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('outOfRangeAccess', () {
+    var a = _obfuscatedList();
+
+    expect(() => a[a.length], throws);
+    expect(() => a[a.length + 1], throws);
+    expect(() => a[a.length + N], throws);
+
+    expect(() => a[-1], throws);
+    expect(() => a[1.5], throws);
+    expect(() => a['length'], throws);
+
+    expect(() => a[a.length] = 0xdeadbeef, throws);
+    expect(() => a[a.length + 1] = 0xdeadbeef, throws);
+    expect(() => a[a.length + N] = 0xdeadbeef, throws);
+
+    expect(() => a[-1] = 0xdeadbeef, throws);
+    expect(() => a[1.5] = 0xdeadbeef, throws);
+    expect(() => a['length'] = 1, throws);
+  });
+}
diff --git a/tests/lib/html/typed_arrays_simd_test.dart b/tests/lib/html/typed_arrays_simd_test.dart
new file mode 100644
index 0000000..3f4919a
--- /dev/null
+++ b/tests/lib/html/typed_arrays_simd_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+const _FLOATING_POINT_ERROR = 0.0000000001;
+floatEquals(value) => closeTo(value, _FLOATING_POINT_ERROR);
+
+class MyFloat32x4 {
+  num x = 0.0;
+  num y = 0.0;
+  num z = 0.0;
+  num w = 0.0;
+}
+
+main() {
+  // Only perform tests if ArrayBuffer is supported.
+  if (!Platform.supportsTypedData) {
+    return;
+  }
+
+  test('test Float32x4', () {
+    if (Platform.supportsSimd) {
+      final val = new Float32x4(1.0, 2.0, 3.0, 4.0);
+      expect(val.x, floatEquals(1.0));
+      expect(val.y, floatEquals(2.0));
+      expect(val.z, floatEquals(3.0));
+      expect(val.w, floatEquals(4.0));
+      final val2 = val + val;
+      expect(val2.x, floatEquals(2.0));
+      expect(val2.y, floatEquals(4.0));
+      expect(val2.z, floatEquals(6.0));
+      expect(val2.w, floatEquals(8.0));
+    }
+  });
+
+  test('test Float32x4List', () {
+    var counter;
+    final list = new Float32List(12);
+    for (int i = 0; i < list.length; ++i) {
+      list[i] = i * 1.0;
+    }
+    if (Platform.supportsSimd) {
+      counter = new Float32x4.zero();
+      final simdlist = new Float32x4List.view(list.buffer);
+      for (int i = 0; i < simdlist.length; ++i) {
+        counter += simdlist[i];
+      }
+    } else {
+      counter = new MyFloat32x4();
+      for (int i = 0; i < list.length; i += 4) {
+        counter.x += list[i];
+        counter.y += list[i + 1];
+        counter.z += list[i + 2];
+        counter.w += list[i + 3];
+      }
+    }
+    expect(counter.x, floatEquals(12.0));
+    expect(counter.y, floatEquals(15.0));
+    expect(counter.z, floatEquals(18.0));
+    expect(counter.w, floatEquals(21.0));
+  });
+
+  test('test Int32x4', () {
+    if (Platform.supportsSimd) {
+      final val = new Int32x4(1, 2, 3, 4);
+      expect(val.x, equals(1));
+      expect(val.y, equals(2));
+      expect(val.z, equals(3));
+      expect(val.w, equals(4));
+      final val2 = val ^ val;
+      expect(val2.x, equals(0));
+      expect(val2.y, equals(0));
+      expect(val2.z, equals(0));
+      expect(val2.w, equals(0));
+    }
+  });
+}
diff --git a/tests/lib/html/typing_test.dart b/tests/lib/html/typing_test.dart
new file mode 100644
index 0000000..9fa3628
--- /dev/null
+++ b/tests/lib/html/typing_test.dart
@@ -0,0 +1,41 @@
+// 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:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isStyleSheetList =
+      predicate((x) => x is List<StyleSheet>, 'is a List<StyleSheet>');
+
+  test('NodeList', () {
+    List<Element> asList = window.document.querySelectorAll('body');
+    // Check it's Iterable
+    int counter = 0;
+    for (Element node in window.document.querySelectorAll('body')) {
+      counter++;
+    }
+    expect(counter, 1);
+    counter = 0;
+    window.document.querySelectorAll('body').forEach((e) {
+      counter++;
+    });
+    expect(counter, 1);
+  });
+
+  test('StyleSheetList', () {
+    var document = window.document as HtmlDocument;
+    List<StyleSheet> asList = document.styleSheets;
+    expect(asList, isStyleSheetList);
+    // Check it's Iterable.
+    int counter = 0;
+    for (StyleSheet styleSheet in document.styleSheets) {
+      counter++;
+    }
+
+    // There is one style sheet from the test framework.
+    expect(counter, 1);
+  });
+}
diff --git a/tests/lib/html/unknownelement_test.dart b/tests/lib/html/unknownelement_test.dart
new file mode 100644
index 0000000..a964bb8
--- /dev/null
+++ b/tests/lib/html/unknownelement_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var isUnknownElement =
+      predicate((x) => x is UnknownElement, 'is an UnknownELement');
+
+  dynamic foo = new Element.tag('foo');
+  foo.id = 'foo';
+  var bar = new Element.tag('bar');
+  bar.id = 'bar';
+  document.body!.nodes.addAll(<Node>[foo, bar]);
+
+  test('type-check', () {
+    expect(foo, isUnknownElement);
+    expect(bar, isUnknownElement);
+    expect(querySelector('#foo'), equals(foo));
+    expect(querySelector('#bar'), equals(bar));
+  });
+
+  test('dispatch-fail', () {
+    expect(() => foo.method1(), throwsNoSuchMethodError);
+    expect(() => foo.field1, throwsNoSuchMethodError);
+    expect(() {
+      foo.field1 = 42;
+    }, throwsNoSuchMethodError);
+  });
+}
diff --git a/tests/lib/html/uri_test.dart b/tests/lib/html/uri_test.dart
new file mode 100644
index 0000000..32ec865
--- /dev/null
+++ b/tests/lib/html/uri_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('Uri.base', () {
+    expect(Uri.base.scheme, "http");
+    expect(Uri.base.toString(), window.location.href);
+  });
+}
diff --git a/tests/lib/html/url_test.dart b/tests/lib/html/url_test.dart
new file mode 100644
index 0000000..201f523
--- /dev/null
+++ b/tests/lib/html/url_test.dart
@@ -0,0 +1,75 @@
+// 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.
+
+library url_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:expect/minitest.dart';
+
+Blob createImageBlob() {
+  var canvas = new CanvasElement();
+  canvas.width = 100;
+  canvas.height = 100;
+
+  var context = canvas.context2D;
+  context.fillStyle = 'red';
+  context.fillRect(0, 0, canvas.width, canvas.height);
+
+  var dataUri = canvas.toDataUrl('image/png');
+  var byteString = window.atob(dataUri.split(',')[1]);
+  var mimeString = dataUri.split(',')[0].split(':')[1].split(';')[0];
+
+  var arrayBuffer = new Uint8List(byteString.length);
+  var dataArray = new Uint8List.view(arrayBuffer.buffer);
+  for (var i = 0; i < byteString.length; i++) {
+    dataArray[i] = byteString.codeUnitAt(i);
+  }
+
+  var blob = new Blob([arrayBuffer], 'image/png');
+  return blob;
+}
+
+Future testCreateObjectUrlFromBlob() async {
+  final done = new Completer();
+  var blob = createImageBlob();
+  var url = Url.createObjectUrlFromBlob(blob);
+  expect(url.length, greaterThan(0));
+  expect(url.startsWith('blob:'), isTrue);
+
+  var img = new ImageElement();
+  img.onLoad.listen((_) {
+    expect(img.complete, true);
+    done.complete();
+  });
+  img.onError.listen((_) {
+    fail('URL failed to load.');
+  });
+  img.src = url;
+  await done.future;
+}
+
+Future testRevokeObjectUrl() async {
+  final done = new Completer();
+  var blob = createImageBlob();
+  var url = Url.createObjectUrlFromBlob(blob);
+  expect(url.startsWith('blob:'), isTrue);
+  Url.revokeObjectUrl(url);
+
+  var img = new ImageElement();
+  // Image should fail to load since the URL was revoked.
+  img.onError.listen(done.complete);
+  img.onLoad.listen((_) {
+    fail('URL should not have loaded.');
+  });
+  img.src = url;
+  await done.future;
+}
+
+main() async {
+  await testCreateObjectUrlFromBlob();
+  await testRevokeObjectUrl();
+}
diff --git a/tests/lib/html/utils.dart b/tests/lib/html/utils.dart
new file mode 100644
index 0000000..8a6304a
--- /dev/null
+++ b/tests/lib/html/utils.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// The test runner for DDC does not handle tests that import files using
+/// relative imports that reach outside of the directory containing the test
+/// (i.e. "../" imports). Since tests both in this directory and in "custom/"
+/// use utils.dart, it needs to be accessible from both places.
+///
+/// We could have every test outside of "custom/" import "custom/utils.dart",
+/// but that feels weird since "utils.dart" doesn't have anything to do with
+/// custom elements.
+///
+/// Instead, it lives there, but is exported from here for the tests in this
+/// directory to import.
+// TODO(rnystrom): If the DDC test runner is fixed to use a different module
+// root that handles "../" imports, move "custom/utils.dart" to here.
+export 'custom/utils.dart';
diff --git a/tests/lib/html/webgl_1_test.dart b/tests/lib/html/webgl_1_test.dart
new file mode 100644
index 0000000..9c3b420
--- /dev/null
+++ b/tests/lib/html/webgl_1_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:typed_data';
+import 'dart:web_gl';
+import 'dart:web_gl' as gl;
+
+import 'package:expect/minitest.dart';
+
+// Test that WebGL is present in dart:web_gl API
+
+final isRenderingContext = predicate((x) => x is RenderingContext);
+final isContextAttributes = predicate((x) => x is Map);
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(RenderingContext.supported, isTrue);
+    });
+  });
+
+  group('functional', () {
+    test('unsupported fails', () {
+      var canvas = new CanvasElement();
+      var context = canvas.getContext3d();
+      if (RenderingContext.supported) {
+        expect(context, isNotNull);
+        expect(context, isRenderingContext);
+      } else {
+        expect(context, isNull);
+      }
+    });
+
+    if (RenderingContext.supported) {
+      test('simple', () {
+        var canvas = new CanvasElement();
+        var context =
+            canvas.getContext('experimental-webgl') as gl.RenderingContext;
+        var shader = context.createShader(gl.WebGL.VERTEX_SHADER);
+        context.shaderSource(shader, 'void main() { }');
+        context.compileShader(shader);
+        var success =
+            context.getShaderParameter(shader, gl.WebGL.COMPILE_STATUS);
+        expect(success, isTrue);
+      });
+
+      test('getContext3d', () {
+        var canvas = new CanvasElement();
+        var context = canvas.getContext3d();
+        expect(context, isNotNull);
+        expect(context, isRenderingContext);
+
+        context = canvas.getContext3d(depth: false);
+        expect(context, isNotNull);
+        expect(context, isRenderingContext);
+      });
+
+      test('texImage2D', () {
+        var canvas = new CanvasElement();
+        gl.RenderingContext context = canvas.getContext3d();
+        var pixels = new Uint8List.fromList([0, 0, 3, 255, 0, 0, 0, 0, 0, 0]);
+        context.texImage2D(1, 1, 1, 1, 10, 10, 1, 1, pixels);
+
+        canvas = new CanvasElement();
+        document.body!.children.add(canvas);
+        CanvasRenderingContext2D context2 =
+            canvas.getContext('2d') as CanvasRenderingContext2D;
+        context.texImage2D(
+            1, 1, 1, 1, 10, context2.getImageData(10, 10, 10, 10));
+
+        context.texImage2D(1, 1, 1, 1, 10, new ImageElement());
+        context.texImage2D(1, 1, 1, 1, 10, new CanvasElement());
+        context.texImage2D(1, 1, 1, 1, 10, new VideoElement());
+      });
+
+      test('texSubImage2D', () {
+        var canvas = new CanvasElement();
+        gl.RenderingContext context = canvas.getContext3d();
+        var pixels = new Uint8List.fromList([0, 0, 3, 255, 0, 0, 0, 0, 0, 0]);
+        context.texSubImage2D(1, 1, 1, 1, 1, 10, 10, 1, pixels);
+
+        canvas = new CanvasElement();
+        document.body!.children.add(canvas);
+        CanvasRenderingContext2D context2 =
+            canvas.getContext('2d') as CanvasRenderingContext2D;
+        context.texSubImage2D(
+            1, 1, 1, 1, 1, 10, context2.getImageData(10, 10, 10, 10));
+
+        context.texSubImage2D(1, 1, 1, 1, 1, 10, new ImageElement());
+        context.texSubImage2D(1, 1, 1, 1, 1, 10, new CanvasElement());
+        context.texSubImage2D(1, 1, 1, 1, 1, 10, new VideoElement());
+      });
+
+      test('getContextAttributes', () {
+        var canvas = new CanvasElement();
+        var context = canvas.getContext3d();
+        var attributes = context.getContextAttributes();
+
+        expect(attributes, isNotNull);
+        expect(attributes, isContextAttributes);
+
+        expect(attributes!['alpha'], isBoolean);
+        expect(attributes['antialias'], isBoolean);
+        expect(attributes['depth'], isBoolean);
+        expect(attributes['premultipliedAlpha'], isBoolean);
+        expect(attributes['preserveDrawingBuffer'], isBoolean);
+        expect(attributes['stencil'], isBoolean);
+      });
+    }
+  });
+}
+
+final isBoolean = predicate((v) => v == true || v == false);
diff --git a/tests/lib/html/webgl_extensions_test.dart b/tests/lib/html/webgl_extensions_test.dart
new file mode 100644
index 0000000..133cc7f
--- /dev/null
+++ b/tests/lib/html/webgl_extensions_test.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library web_gl_test;
+
+import 'dart:html';
+import 'dart:web_gl';
+
+import 'package:expect/minitest.dart';
+
+final isAngleInstancedArrays = (v) => v is AngleInstancedArrays;
+final isExtBlendMinMax = (v) => v is ExtBlendMinMax;
+final isExtFragDepth = (v) => v is ExtFragDepth;
+final isEXTsRgb = (v) => v is EXTsRgb;
+final isExtShaderTextureLod = (v) => v is ExtShaderTextureLod;
+final isExtTextureFilterAnisotropic = (v) => v is ExtTextureFilterAnisotropic;
+final isOesElementIndexUint = (v) => v is OesElementIndexUint;
+final isOesStandardDerivatives = (v) => v is OesStandardDerivatives;
+final isOesTextureFloat = (v) => v is OesTextureFloat;
+final isOesTextureFloatLinear = (v) => v is OesTextureFloatLinear;
+final isOesTextureHalfFloat = (v) => v is OesTextureHalfFloat;
+final isOesTextureHalfFloatLinear = (v) => v is OesTextureHalfFloatLinear;
+final isOesVertexArrayObject = (v) => v is OesVertexArrayObject;
+final isCompressedTextureAtc = (v) => v is CompressedTextureAtc;
+final isCompressedTextureETC1 = (v) => v is CompressedTextureETC1;
+final isCompressedTexturePvrtc = (v) => v is CompressedTexturePvrtc;
+final isCompressedTextureS3TC = (v) => v is CompressedTextureS3TC;
+final isDebugRendererInfo = (v) => v is DebugRendererInfo;
+final isDebugShaders = (v) => v is DebugShaders;
+final isDepthTexture = (v) => v is DepthTexture;
+final isDrawBuffers = (v) => v is DrawBuffers;
+final isLoseContext = (v) => v is LoseContext;
+
+final isFunction = predicate((v) => v is Function);
+
+// Test that various webgl extensions are available. Only test advertised
+// supported extensions. If the extension has methods, we just test the presence
+// of some methods - we don't test if functionality works.
+
+main() {
+  if (!RenderingContext.supported) return;
+
+  const allExtensions = const [
+    'ANGLE_instanced_arrays',
+    'EXT_blend_minmax',
+    'EXT_color_buffer_float',
+    'EXT_color_buffer_half_float',
+    'EXT_disjoint_timer_query',
+    'EXT_frag_depth',
+    'EXT_sRGB',
+    'EXT_shader_texture_lod',
+    'EXT_texture_filter_anisotropic',
+    'OES_element_index_uint',
+    'OES_standard_derivatives',
+    'OES_texture_float',
+    'OES_texture_float_linear',
+    'OES_texture_half_float',
+    'OES_texture_half_float_linear',
+    'OES_vertex_array_object',
+    'WEBGL_color_buffer_float',
+    'WEBGL_compressed_texture_atc',
+    'WEBGL_compressed_texture_es3',
+    'WEBGL_compressed_texture_etc1',
+    'WEBGL_compressed_texture_pvrtc',
+    'WEBGL_compressed_texture_s3tc',
+    'WEBGL_debug_renderer_info',
+    'WEBGL_debug_shaders',
+    'WEBGL_depth_texture',
+    'WEBGL_draw_buffers',
+    'WEBGL_lose_context',
+  ];
+
+  getExtension(String name) {
+    expect(name, anyOf(allExtensions), reason: 'unknown extension');
+    var canvas = new CanvasElement();
+    var context = canvas.getContext3d();
+    var supportedExtensions = context.getSupportedExtensions()!;
+    if (supportedExtensions.contains(name)) {
+      var extension = context.getExtension(name);
+      expect(extension, isNotNull);
+      return extension;
+    }
+    return null;
+  }
+
+  testType(name, typeMatcher) {
+    test('type', () {
+      var extension = getExtension(name);
+      if (extension == null) return;
+      expect(extension, predicate(typeMatcher));
+      // Ensure that isInstanceOf<X> is not instantiated for an erroneous type
+      // X.  If X is erroneous, there is only a warning at compile time and X is
+      // treated as dynamic, which would make the above line pass.
+      expect(typeMatcher(1), false, reason: 'invalid typeMatcher');
+    });
+  }
+
+  group('ANGLE_instanced_arrays', () {
+    const name = 'ANGLE_instanced_arrays';
+    testType(name, isAngleInstancedArrays);
+    test('vertexAttribDivisorAngle', () {
+      AngleInstancedArrays? extension =
+          getExtension(name) as AngleInstancedArrays?;
+      if (extension == null) return;
+      expect(extension.vertexAttribDivisorAngle, isFunction);
+    });
+  });
+
+  group('EXT_blend_minmax', () {
+    testType('EXT_blend_minmax', isExtBlendMinMax);
+  });
+
+  group('EXT_frag_depth', () {
+    testType('EXT_frag_depth', isExtFragDepth);
+  });
+
+  group('EXT_sRGB', () {
+    testType('EXT_sRGB', isEXTsRgb);
+  });
+
+  group('EXT_shader_texture_lod', () {
+    testType('EXT_shader_texture_lod', isExtShaderTextureLod);
+  });
+
+  group('EXT_texture_filter_anisotropic', () {
+    testType('EXT_texture_filter_anisotropic', isExtTextureFilterAnisotropic);
+  });
+
+  group('OES_element_index_uint', () {
+    testType('OES_element_index_uint', isOesElementIndexUint);
+  });
+
+  group('OES_standard_derivatives', () {
+    testType('OES_standard_derivatives', isOesStandardDerivatives);
+  });
+
+  group('OES_texture_float', () {
+    testType('OES_texture_float', isOesTextureFloat);
+  });
+
+  group('OES_texture_float_linear', () {
+    testType('OES_texture_float_linear', isOesTextureFloatLinear);
+  });
+
+  group('OES_texture_half_float', () {
+    testType('OES_texture_half_float', isOesTextureHalfFloat);
+  });
+
+  group('OES_texture_half_float_linear', () {
+    testType('OES_texture_half_float_linear', isOesTextureHalfFloatLinear);
+  });
+
+  group('OES_vertex_array_object', () {
+    testType('OES_vertex_array_object', isOesVertexArrayObject);
+  });
+
+  group('WEBGL_compressed_texture_atc', () {
+    testType('WEBGL_compressed_texture_atc', isCompressedTextureAtc);
+  });
+
+  group('WEBGL_compressed_texture_etc1', () {
+    testType('WEBGL_compressed_texture_etc1', isCompressedTextureETC1);
+  });
+
+  group('WEBGL_compressed_texture_pvrtc', () {
+    testType('WEBGL_compressed_texture_pvrtc', isCompressedTexturePvrtc);
+  });
+
+  group('WEBGL_compressed_texture_s3tc', () {
+    testType('WEBGL_compressed_texture_s3tc', isCompressedTextureS3TC);
+  });
+
+  group('WEBGL_debug_renderer_info', () {
+    testType('WEBGL_debug_renderer_info', isDebugRendererInfo);
+  });
+
+  group('WEBGL_debug_shaders', () {
+    testType('WEBGL_debug_shaders', isDebugShaders);
+  });
+
+  group('WEBGL_depth_texture', () {
+    testType('WEBGL_depth_texture', isDepthTexture);
+  });
+
+  group('WEBGL_draw_buffers', () {
+    const name = 'WEBGL_draw_buffers';
+    testType(name, isDrawBuffers);
+    test('drawBuffersWebgl', () {
+      DrawBuffers? extension = getExtension(name) as DrawBuffers?;
+      if (extension == null) return;
+      expect(extension.drawBuffersWebgl, isFunction);
+    });
+  });
+
+  group('WEBGL_lose_context', () {
+    const name = 'WEBGL_lose_context';
+    testType(name, isLoseContext);
+    test('loseContext', () {
+      LoseContext? extension = getExtension(name) as LoseContext?;
+      if (extension == null) return;
+      expect(extension.loseContext, isFunction);
+    });
+  });
+}
diff --git a/tests/lib/html/websocket_test.dart b/tests/lib/html/websocket_test.dart
new file mode 100644
index 0000000..a7bd01a
--- /dev/null
+++ b/tests/lib/html/websocket_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library WebSocketTest;
+
+import 'dart:html';
+
+import 'package:async_helper/async_minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(WebSocket.supported, true);
+    });
+  });
+
+  group('websocket', () {
+    var expectation = WebSocket.supported ? returnsNormally : throws;
+
+    test('constructorTest', () {
+      expect(() {
+        var socket = new WebSocket('ws://localhost/ws', 'chat');
+        expect(socket, isNotNull);
+        expect(socket, isInstanceOf<WebSocket>());
+      }, expectation);
+    });
+
+    if (WebSocket.supported) {
+      test('echo', () {
+        var socket = new WebSocket('ws://${window.location.host}/ws');
+
+        socket.onOpen.first.then((_) {
+          socket.send('hello!');
+        });
+
+        return socket.onMessage.first.then((MessageEvent e) {
+          expect(e.data, 'hello!');
+          socket.close();
+        });
+      });
+
+      test('error handling', () {
+        var socket = new WebSocket('ws://${window.location.host}/ws');
+        socket.onOpen.first.then((_) => socket.send('close-with-error'));
+        return socket.onError.first.then((e) {
+          print('$e was caught, yay!');
+          socket.close();
+        });
+      });
+    }
+  });
+}
diff --git a/tests/lib/html/websql_test.dart b/tests/lib/html/websql_test.dart
new file mode 100644
index 0000000..36daf6c
--- /dev/null
+++ b/tests/lib/html/websql_test.dart
@@ -0,0 +1,122 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library WebDBTest;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:web_sql';
+
+import 'package:async_helper/async_minitest.dart';
+
+Future<SqlResultSet> createTable(
+    SqlTransaction transaction, String tableName, String columnName) async {
+  return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []);
+}
+
+Future<SqlResultSet> insertTable(SqlTransaction transaction, String tableName,
+    String columnName, value) async {
+  final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)';
+  return transaction.executeSql(sql, [value]);
+}
+
+Future<SqlResultSet> queryTable(
+    SqlTransaction transaction, String tableName) async {
+  final sql = 'SELECT * FROM $tableName';
+  return transaction.executeSql(sql, []);
+}
+
+Future<SqlResultSet?> dropTable(SqlTransaction transaction, String tableName,
+    [bool ignoreFailure = false]) async {
+  try {
+    var result = await transaction.executeSql('DROP TABLE $tableName', []);
+    return result;
+  } catch (error) {
+    if (!ignoreFailure) throw error;
+  }
+}
+
+final tableName = 'test_table';
+final columnName = 'test_data';
+
+late SqlDatabase db;
+late SqlTransaction tx;
+
+Future setup() async {
+  if (SqlDatabase.supported) {
+    db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+    expect(db, isNotNull, reason: 'Unable to open database');
+
+    tx = await db.transaction_future();
+    expect(tx, isNotNull, reason: "Transaction not ready");
+  }
+}
+
+main() async {
+  await setup();
+
+  group('Database', () {
+    test('Open/Transaction', () async {
+      if (!SqlDatabase.supported) return;
+
+      expect(tx, isNotNull, reason: "Transaction not ready");
+
+      // Should not succeed table doesn't exist to be dropped.
+      try {
+        await dropTable(tx, tableName);
+        expect(false, true, reason: "dropTable should fail");
+      } catch (error) {
+        expect(error.message,
+            "could not prepare statement (1 no such table: test_table)");
+      }
+    });
+
+    test('create', () async {
+      if (!SqlDatabase.supported) return;
+
+      expect(tx, isNotNull, reason: "Transaction not ready");
+      try {
+        SqlResultSet createResult =
+            await createTable(tx, tableName, columnName);
+        expect(createResult.insertId, 0);
+      } catch (error) {
+        expect(false, true, reason: "createTable failed - ${error.message}");
+      }
+    });
+
+    test('insert', () async {
+      if (!SqlDatabase.supported) return;
+
+      expect(tx, isNotNull, reason: "Transaction not ready");
+      try {
+        SqlResultSet insertResult =
+            await insertTable(tx, tableName, columnName, 'Some text data');
+        expect(insertResult.insertId, 1);
+        expect(insertResult.rowsAffected, 1);
+      } catch (error) {
+        expect(false, true, reason: "insert failed - ${error.message}");
+      }
+    });
+
+    test('query', () async {
+      if (!SqlDatabase.supported) return;
+
+      expect(tx, isNotNull, reason: "Transaction not ready");
+      try {
+        SqlResultSet queryResult = await queryTable(tx, tableName);
+        expect(queryResult.rows.length, 1);
+        expect(queryResult.rows[0]['test_data'], "Some text data");
+      } catch (error) {
+        expect(false, true, reason: "queryTable failed - ${error.message}");
+      }
+    });
+
+    test('cleanup', () async {
+      if (!SqlDatabase.supported) return;
+
+      expect(tx, isNotNull, reason: "Transaction not ready");
+      await dropTable(tx, tableName, true);
+    });
+  });
+}
diff --git a/tests/lib/html/wheelevent_test.dart b/tests/lib/html/wheelevent_test.dart
new file mode 100644
index 0000000..2614ae0
--- /dev/null
+++ b/tests/lib/html/wheelevent_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library wheel_event_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+Future testWheelEvent() async {
+  final done = new Completer();
+  var element = new DivElement();
+  var eventType = Element.mouseWheelEvent.getEventType(element);
+
+  element.onMouseWheel.listen((e) {
+    try {
+      expect(e.screen.x, 100);
+      expect(e.deltaX, 0);
+      expect(e.deltaY.toDouble(), 240.0);
+      expect(e.deltaMode, WheelEvent.DOM_DELTA_PAGE);
+      done.complete();
+    } catch (e) {
+      done.completeError(e);
+    }
+  });
+  var event = new WheelEvent(eventType,
+      deltaX: 0,
+      deltaY: 240,
+      deltaMode: WheelEvent.DOM_DELTA_PAGE,
+      screenX: 100);
+  element.dispatchEvent(event);
+  await done.future;
+}
+
+Future testWheelEventWithDeltaZ() async {
+  final done = new Completer();
+  var element = new DivElement();
+  var eventType = Element.mouseWheelEvent.getEventType(element);
+
+  element.onMouseWheel.listen((e) {
+    try {
+      expect(e.deltaX, 0);
+      expect(e.deltaY, 0);
+      expect(e.screen.x, 0);
+      expect(e.deltaZ.toDouble(), 1.0);
+      done.complete();
+    } catch (e) {
+      done.completeError(e);
+    }
+  });
+  var event = new WheelEvent(eventType, deltaZ: 1.0);
+  element.dispatchEvent(event);
+  await done.future;
+}
+
+Future testWheelEventStream() async {
+  final done = new Completer();
+  var element = new DivElement();
+  var eventType = Element.mouseWheelEvent.getEventType(element);
+
+  element.onMouseWheel.listen((e) {
+    try {
+      expect(e.screen.x, 100);
+      expect(e.deltaX.toDouble(), 240.0);
+      expect(e.deltaY, 0);
+      done.complete();
+    } catch (e) {
+      done.completeError(e);
+    }
+  });
+  var event = new WheelEvent(eventType, deltaX: 240, deltaY: 0, screenX: 100);
+  element.dispatchEvent(event);
+  await done.future;
+}
+
+main() async {
+  await testWheelEvent();
+  await testWheelEventWithDeltaZ();
+  await testWheelEventStream();
+}
diff --git a/tests/lib/html/window_eq_test.dart b/tests/lib/html/window_eq_test.dart
new file mode 100644
index 0000000..03be5ef
--- /dev/null
+++ b/tests/lib/html/window_eq_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  var obfuscated = null;
+
+  test('notNull', () {
+    expect(window, isNotNull);
+    expect(window != obfuscated, isTrue);
+  });
+}
diff --git a/tests/lib/html/window_mangling_test.dart b/tests/lib/html/window_mangling_test.dart
new file mode 100644
index 0000000..f427a34
--- /dev/null
+++ b/tests/lib/html/window_mangling_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html' as dom;
+
+import 'package:expect/minitest.dart';
+
+// Defined in dom.Window.
+get navigator => "Dummy";
+
+$eq(x, y) => false;
+$eq$(x, y) => false;
+
+main() {
+  var win = dom.window;
+
+  test('windowMethod', () {
+    final message = navigator;
+    final x = win.navigator;
+    expect(x, notEquals(message));
+  });
+
+  test('windowEquals', () {
+    expect($eq(win, win), isFalse);
+    expect(win == win, isTrue);
+  });
+
+  test('windowEquals', () {
+    expect($eq$(win, win), isFalse);
+    expect(win == win, isTrue);
+  });
+}
diff --git a/tests/lib/html/window_nosuchmethod_test.dart b/tests/lib/html/window_nosuchmethod_test.dart
new file mode 100644
index 0000000..5e3556f
--- /dev/null
+++ b/tests/lib/html/window_nosuchmethod_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html' as dom;
+
+import 'package:expect/minitest.dart';
+
+// Not defined in dom.Window.
+foo(x) => x;
+
+class Unused {
+  foo(x) => 'not $x';
+}
+
+int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
+
+main() {
+  var things = <dynamic>[new Unused(), dom.window];
+
+  test('windowNonMethod', () {
+    var win = things[inscrutable(1)];
+    final message = foo("Hello World");
+    expect(() => win.foo(message), throwsNoSuchMethodError);
+  });
+
+  test('foo', () {
+    var win = things[inscrutable(0)];
+    String x = win.foo('bar');
+    expect(x, 'not bar');
+  });
+
+  // Use dom.window directly in case the compiler does type inference.
+  test('windowNonMethod2', () {
+    final message = foo("Hello World");
+    expect(() => (dom.window as dynamic).foo(message), throwsNoSuchMethodError);
+  });
+}
diff --git a/tests/lib/html/window_test.dart b/tests/lib/html/window_test.dart
new file mode 100644
index 0000000..ab79e66
--- /dev/null
+++ b/tests/lib/html/window_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  test('scrollXY', () {
+    expect(window.scrollX, 0);
+    expect(window.scrollY, 0);
+  });
+}
diff --git a/tests/lib/html/worker_api_test.dart b/tests/lib/html/worker_api_test.dart
new file mode 100644
index 0000000..92a0198
--- /dev/null
+++ b/tests/lib/html/worker_api_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:isolate';
+
+import 'package:async_helper/async_minitest.dart';
+
+worker(message) {
+  var uri = message[0];
+  var replyTo = message[1];
+  try {
+    var url = Url.createObjectUrl(new Blob([''], 'application/javascript'));
+    Url.revokeObjectUrl(url);
+    replyTo.send('Hello from Worker');
+  } catch (e) {
+    replyTo.send('Error: $e');
+  }
+}
+
+main() {
+  test('Use Worker API in Worker', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(worker, ['', response.sendPort]);
+    remote.then((_) => response.first).then(
+        expectAsync((reply) => expect(reply, equals('Hello from Worker'))));
+  });
+}
diff --git a/tests/lib/html/worker_functional_test.dart b/tests/lib/html/worker_functional_test.dart
new file mode 100644
index 0000000..cf3d5ab
--- /dev/null
+++ b/tests/lib/html/worker_functional_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library worker_test;
+
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+
+main() {
+  var workerScript = '''postMessage('WorkerMessage');''';
+
+  test('unsupported', () {
+    if (!Worker.supported) {
+      expect(() => new Worker('worker.js'), throws);
+    } else {
+      new Worker('worker.js').onError.first.then(expectAsync((e) {
+        // This event is expected, "worker.js" doesn't exist.  But the event
+        // *sometimes* propagates to window.onerror in Firefox which causes
+        // this test to fail, so let's stop any further propagation:
+        e.preventDefault();
+        e.stopImmediatePropagation();
+      }));
+    }
+  });
+
+  if (!Worker.supported) return;
+
+  test('works', () {
+    // Use Blob to make a local URL so we don't have to have a separate file.
+    // This does not work on browsers using CSP (Content Security Policy).
+    var blob = new Blob([workerScript], 'text/javascript');
+    var url = Url.createObjectUrl(blob);
+    var worker = new Worker(url);
+    var test = expectAsync((e) {
+      expect(e.data, 'WorkerMessage');
+    });
+    worker.onMessage.first.then(test);
+  });
+}
diff --git a/tests/lib/html/worker_supported_test.dart b/tests/lib/html/worker_supported_test.dart
new file mode 100644
index 0000000..fecb78e
--- /dev/null
+++ b/tests/lib/html/worker_supported_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library worker_test;
+
+import 'package:expect/minitest.dart';
+import 'dart:html';
+
+main() {
+  test('supported', () {
+    expect(Worker.supported, isTrue);
+  });
+}
diff --git a/tests/lib/html/wrapping_collections_test.dart b/tests/lib/html/wrapping_collections_test.dart
new file mode 100644
index 0000000..d61b84b
--- /dev/null
+++ b/tests/lib/html/wrapping_collections_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:html_common';
+import 'dart:js' as js;
+
+import 'package:expect/minitest.dart';
+
+/// Test that if we access objects through JS-interop we get the
+/// appropriate objects, even if dart:html maps them.
+main() {
+  test("Access through JS-interop", () {
+    var performance = js.context['performance'];
+    var entries = performance.callMethod('getEntries', const []);
+    entries.forEach((x) {
+      expect(x is js.JsObject, isTrue);
+    });
+  });
+}
diff --git a/tests/lib/html/xhr_cross_origin_data.txt b/tests/lib/html/xhr_cross_origin_data.txt
new file mode 100644
index 0000000..5872d96
--- /dev/null
+++ b/tests/lib/html/xhr_cross_origin_data.txt
@@ -0,0 +1 @@
+{"version":"1.0","encoding":"UTF-8","feed":{"xmlns":"http://www.w3.org/2005/Atom","xmlns$openSearch":"http://a9.com/-/spec/opensearch/1.1/","xmlns$gd":"http://schemas.google.com/g/2005","xmlns$issues":"http://schemas.google.com/projecthosting/issues/2009","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full"},"updated":{"$t":"2012-10-17T19:55:25.326Z"},"title":{"$t":"Issues - dart"},"subtitle":{"$t":"Issues - dart"},"link":[{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/list"},{"rel":"http://schemas.google.com/g/2005#feed","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full"},{"rel":"http://schemas.google.com/g/2005#post","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full?alt=json&max-results=25"},{"rel":"next","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full?alt=json&start-index=26&max-results=25"}],"generator":{"$t":"ProjectHosting","version":"1.0","uri":"http://code.google.com/feeds/issues"},"openSearch$totalResults":{"$t":6004},"openSearch$startIndex":{"$t":1},"openSearch$itemsPerPage":{"$t":25},"entry":[{"gd$etag":"W/\"CE8DRX47eCl7ImA9WhdaEEw.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/1"},"published":{"$t":"2011-10-06T15:11:23.000Z"},"updated":{"$t":"2011-10-19T08:27:54.000Z"},"title":{"$t":"Process tests sometimes cause timeout on Linux"},"content":{"$t":"Either of the process tests\r\n\r\n  ProcessExitTest.dart\r\n  ProcessSegfaultTest.dart\r\n  ProcessStartExceptionTest.dart\r\n  ProcessStderrTest.dart\r\n  ProcessStdoutTest.dart\r\n\r\ncan hang on Linux. It happens once every ~25 runs.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/1/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=1"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/1"}],"author":[{"name":{"$t":"sgjesse@google.com"},"uri":{"$t":"/u/sgjesse@google.com/"}}],"issues$cc":[{"issues$uri":{"$t":"/u/100337825224881731112/"},"issues$username":{"$t":"fmal...@google.com"}}],"issues$closedDate":{"$t":"2011-10-19T08:27:54.000Z"},"issues$id":{"$t":1},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$owner":{"issues$uri":{"$t":"/u/sgjesse@google.com/"},"issues$username":{"$t":"sgjesse@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"DUUAQH47eCl7ImA9WhdUGUU.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/2"},"published":{"$t":"2011-10-07T07:53:55.000Z"},"updated":{"$t":"2011-10-07T11:34:01.000Z"},"title":{"$t":"EchoServer tests occasionally crash on Windows"},"content":{"$t":"The EchoServer tests occasionally hits what should be an unreachable path.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/2/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=2"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/2"}],"author":[{"name":{"$t":"ager@google.com"},"uri":{"$t":"/u/ager@google.com/"}}],"issues$cc":[{"issues$uri":{"$t":"/u/sgjesse@google.com/"},"issues$username":{"$t":"sgjesse@google.com"}}],"issues$closedDate":{"$t":"2011-10-07T11:34:01.000Z"},"issues$id":{"$t":2},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-High"},{"$t":"OpSys-Windows"}],"issues$owner":{"issues$uri":{"$t":"/u/ager@google.com/"},"issues$username":{"$t":"ager@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"DUYMQH47eCl7ImA9WhdbFE8.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/3"},"published":{"$t":"2011-10-10T10:34:32.000Z"},"updated":{"$t":"2011-10-12T13:46:21.000Z"},"title":{"$t":"Dart_Snapshot conflicting uses"},"content":{"$t":"Trying to build Dart after clean checkout from SVN gives me :\r\n\r\nruntime/vm/dart_api_impl.cc: In function ‘void* dart::Dart_CreateIsolate(void*, void*)’:\r\nruntime/vm/dart_api_impl.cc:38:71: error: declaration of ‘void* dart::Dart_CreateIsolate(void*, void*)’ with C language linkage\r\nruntime/include/dart_api.h:185:26: error: conflicts with previous declaration ‘void* Dart_CreateIsolate(const Dart_Snapshot*, void*)’\r\n\r\nI ended up changing the dart_api_impl.cc declaration to use const Dart_Snapshot* and did a cast to (void*) in order to call Dart::CreateIsolate((void*)snapshot, data);","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/3/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=3"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/3"}],"author":[{"name":{"$t":"nelson.s...@gmail.com"},"uri":{"$t":"/u/114313790760784276282/"}}],"issues$closedDate":{"$t":"2011-10-11T15:43:38.000Z"},"issues$id":{"$t":3},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$owner":{"issues$uri":{"$t":"/u/asiva@google.com/"},"issues$username":{"$t":"asiva@google.com"}},"issues$stars":{"$t":13},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"Dk4MRn47eCl7ImA9WhdbEkk.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/4"},"published":{"$t":"2011-10-10T10:44:36.000Z"},"updated":{"$t":"2011-10-10T11:09:47.000Z"},"title":{"$t":"Not-implemented iteration for objects"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n\r\n  main() {\r\n    var obj = {&quot;a&quot;: 1, &quot;b&quot;: 2};\r\n    for (var key in obj) {\r\n      print(key);\r\n    }\r\n  }\r\nhttp://try-dart-lang.appspot.com/s/EmEO\r\n\r\nWhat is the expected output?\r\na\r\nb\r\n\r\nWhat do you see instead?\r\nNoSuchMethodException - receiver: '' function name: 'iterator$named' arguments: []]\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\nOnline dart compiler.\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\n\r\nIn the specification it says that &quot;for in&quot; construct is desugared into var n0 = e.iterator(); while (n0.hasNext()) { finalVarOrType id = n0.next();\r\nIt is not working because obj.iterator does not exist.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/4/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=4"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/4"}],"author":[{"name":{"$t":"vjeuxx"},"uri":{"$t":"/u/vjeuxx/"}}],"issues$closedDate":{"$t":"2011-10-10T11:09:47.000Z"},"issues$id":{"$t":4},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Invalid"}},{"gd$etag":"W/\"AkIGQH47eCl7ImA9WhdbEks.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/5"},"published":{"$t":"2011-10-10T11:03:05.000Z"},"updated":{"$t":"2011-10-10T17:42:01.000Z"},"title":{"$t":"Variables in single/double quotes."},"content":{"$t":"Can we use the PHP view that single quotes don't contain variables, but double quotes do... this may help the parser in speed, but more importantly it means the programmer doesn't have to check for and escape variables in single quoted strings.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/5/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=5"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/5"}],"author":[{"name":{"$t":"cr...@craigfrancis.co.uk"},"uri":{"$t":"/u/105349735893558381122/"}}],"issues$closedDate":{"$t":"2011-10-10T17:42:01.000Z"},"issues$id":{"$t":5},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$stars":{"$t":3},"issues$state":{"$t":"closed"},"issues$status":{"$t":"WontFix"}},{"gd$etag":"W/\"DEIGQX47eCl7ImA9WhRTEUg.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/6"},"published":{"$t":"2011-10-10T11:38:13.000Z"},"updated":{"$t":"2011-11-01T14:08:40.000Z"},"title":{"$t":"Type checking is broken"},"content":{"$t":"Use dartc_test to run:\r\n\r\nbool foo(bool bar()) =&gt; bar();\r\n\r\nbool bar() {}\r\n\r\nmain() {\r\n  foo(bar);\r\n}\r\n\r\nwith --enable_type_checks.\r\n\r\nAn error is thrown because the type of bar is not bool.\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/6/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=6"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/6"}],"author":[{"name":{"$t":"benl@google.com"},"uri":{"$t":"/u/benl@google.com/"}}],"issues$closedDate":{"$t":"2011-11-01T14:08:40.000Z"},"issues$id":{"$t":6},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Area-Compiler"}],"issues$owner":{"issues$uri":{"$t":"/u/jat@google.com/"},"issues$username":{"$t":"jat@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"DEEAQH47eCl7ImA9WhdbFE8.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/7"},"published":{"$t":"2011-10-10T12:32:40.000Z"},"updated":{"$t":"2011-10-12T13:37:21.000Z"},"title":{"$t":"declaredIndentifier typos in Dart Language Specification, Draft Version 0.01, October 10th, 2011"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. Open http://www.dartlang.org/docs/spec/dartLangSpec.pdf\r\n2. Search for &quot;indent&quot; (without the quotes)\r\n3. Notice how this should rather read ident instead.\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\n\r\nI see what must be a typo.\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\n\r\nDart Programming Language Specification\r\nDraft Version 0.01\r\nThe Dart Team\r\nOctober 10th, 2011\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\n\r\nHere is a copy/paste from the pdf (with the fi ligature manually reapaired). See my (sic) annotations for where I think the typos are:\r\n\r\n11.9\r\n\r\nTry\r\n\r\nThe try statement supports the definition of exception handling code in a struc-\r\ntured way.\r\n\r\ntryStatement:\r\ntry block (catchPart+ finallyPart? | finallyPart)\r\n;\r\n\r\ncatchPart:\r\ncatch ‘(’ declaredIndentifier (sic) (‘, ’ declaredIndentifier (sic))? ‘)’ block\r\n;\r\n\r\nfinallyPart:\r\nfinally block\r\n;\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/7/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=7"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/7"}],"author":[{"name":{"$t":"adrian.a...@gmail.com"},"uri":{"$t":"/u/114973624116584041537/"}}],"issues$closedDate":{"$t":"2011-10-12T13:37:21.000Z"},"issues$id":{"$t":7},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Component-Docs"}],"issues$owner":{"issues$uri":{"$t":"/u/102708310591662789853/"},"issues$username":{"$t":"gbra...@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Done"}},{"gd$etag":"W/\"D0QNQ347eCl7ImA9WhdbEkg.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/8"},"published":{"$t":"2011-10-10T12:46:09.000Z"},"updated":{"$t":"2011-10-10T14:03:12.000Z"},"title":{"$t":"Build Failure for standalone VM"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n&gt; Follow steps to build VM mentioned at http://code.google.com/p/dart/wiki/Building#Building_the_standalone_VM\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\nBuild should be success, but it fails.\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\nLatest version.\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\n\r\nError output:\r\n~/dart/runtime$ ../tools/build.py --arch=ia32\r\nmake -j 1 BUILDTYPE=Debug_ia32 all\r\n  CXX(target) out/Debug_ia32/obj.target/libdart/runtime/vm/dart_api_impl.o\r\ncc1plus: warnings being treated as errors\r\n../runtime/vm/dart_api_impl.cc: In function ‘void* dart::Dart_CreateIsolate(void*, void*)’:\r\n../runtime/vm/dart_api_impl.cc:38:71: error: declaration of ‘void* dart::Dart_CreateIsolate(void*, void*)’ with C language linkage\r\n../runtime/include/dart_api.h:185:26: error: conflicts with previous declaration ‘void* Dart_CreateIsolate(const Dart_Snapshot*, void*)’\r\nmake: *** [out/Debug_ia32/obj.target/libdart/runtime/vm/dart_api_impl.o] Error 1\r\nBUILD FAILED\r\n\r\n\r\nIs this a known issue? or am I doing something wrong?\r\n\r\nthanks,\r\nswarup","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/8/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=8"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/8"}],"author":[{"name":{"$t":"me.s...@gmail.com"},"uri":{"$t":"/u/112564033093352645938/"}}],"issues$closedDate":{"$t":"2011-10-10T14:03:12.000Z"},"issues$id":{"$t":8},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$mergedInto":{"issues$id":{"$t":3},"issues$project":{"$t":"dart"}},"issues$stars":{"$t":2},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Duplicate"}},{"gd$etag":"W/\"CEMMQH47eCl7ImA9WhdbE0g.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/9"},"published":{"$t":"2011-10-10T13:08:33.000Z"},"updated":{"$t":"2011-10-11T17:01:21.000Z"},"title":{"$t":"\"variable set but not used\" error during build of VM"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. &gt; Follow steps to build VM mentioned at http://code.google.com/p/dart/wiki/Building#Building_the_standalone_VM\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\nI get some &quot;variable X set but not used&quot;-type warnings, that -Werror escalates to errors, halting the build.\r\nAs a temporary measure, I removed -Werror from all *.mk files, which allows me to build the standalone VM successfully.\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\nRecent svn on arch linux using gcc version 4.6.1 20110819 (prerelease) \r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\nHere is a full list of the warnings (without -Werror and therefor not turned to errors)\r\n\r\n\r\nthird_party/v8/src/ia32/full-codegen-ia32.cc: In member function ‘virtual void v8::internal::FullCodeGenerator::VisitCompareOperation(v8::internal::CompareOperation*)’:\r\nthird_party/v8/src/ia32/full-codegen-ia32.cc:4085:12: warning: variable ‘strict’ set but not used [-Wunused-but-set-variable]\r\n  CXX(host) out/Debug_ia32/obj.host/v8_base/third_party/v8/src/ia32/lithium-gap-resolver-ia32.o\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc: In member function ‘void v8::internal::LCodeGen::DoLoadKeyedFastDoubleElement(v8::internal::LLoadKeyedFastDoubleElement*)’:\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc:2235:12: warning: variable ‘elements’ set but not used [-Wunused-but-set-variable]\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc: In member function ‘void v8::internal::LCodeGen::DoStoreKeyedFastDoubleElement(v8::internal::LStoreKeyedFastDoubleElement*)’:\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc:3100:12: warning: variable ‘elements’ set but not used [-Wunused-but-set-variable]\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc:3101:12: warning: variable ‘key’ set but not used [-Wunused-but-set-variable]\r\n\r\n\r\nthird_party/v8/src/ia32/full-codegen-ia32.cc: In member function ‘virtual void v8::internal::FullCodeGenerator::VisitCompareOperation(v8::internal::CompareOperation*)’:\r\nthird_party/v8/src/ia32/full-codegen-ia32.cc:4085:12: warning: variable ‘strict’ set but not used [-Wunused-but-set-variable]\r\n  CXX(target) out/Debug_ia32/obj.target/v8_base/third_party/v8/src/ia32/lithium-gap-resolver-ia32.o\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc: In member function ‘void v8::internal::LCodeGen::DoLoadKeyedFastDoubleElement(v8::internal::LLoadKeyedFastDoubleElement*)’:\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc:2235:12: warning: variable ‘elements’ set but not used [-Wunused-but-set-variable]\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc: In member function ‘void v8::internal::LCodeGen::DoStoreKeyedFastDoubleElement(v8::internal::LStoreKeyedFastDoubleElement*)’:\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc:3100:12: warning: variable ‘elements’ set but not used [-Wunused-but-set-variable]\r\nthird_party/v8/src/ia32/lithium-codegen-ia32.cc:3101:12: warning: variable ‘key’ set but not used [-Wunused-but-set-variable]\r\n\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/9/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=9"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/9"}],"author":[{"name":{"$t":"waq...@gmail.com"},"uri":{"$t":"/u/110067472520212772478/"}}],"issues$closedDate":{"$t":"2011-10-10T13:20:54.000Z"},"issues$id":{"$t":9},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$mergedInto":{"issues$id":{"$t":43},"issues$project":{"$t":"dart"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Duplicate"}},{"gd$etag":"W/\"DE4GRX47eCl7ImA9WhdbGEo.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/10"},"published":{"$t":"2011-10-10T13:21:56.000Z"},"updated":{"$t":"2011-10-17T18:42:04.000Z"},"title":{"$t":"dartc build failure: private DartNode.setParent()"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. build dart compiler\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\ndart/compiler/java/com/google/dart/compiler/ast/DartNode.java fails to compile with the following error:\r\n    [javac] /data/down/devel/dart/dart/compiler/java/com/google/dart/compiler/ast/DartNode.java:122: error: setParent(DartNode) has private access in DartNode\r\n    [javac]        child.setParent(this);\r\n    [javac]             ^\r\n\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\ndart svn, javac 1.7.0 on arch linux\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\nMaking setParent() protected instead of private fixes the issue for me, allowing it to be called from protected method becomeParentOf() of the same class.\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/10/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=10"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/10"}],"author":[{"name":{"$t":"waq...@gmail.com"},"uri":{"$t":"/u/110067472520212772478/"}}],"issues$closedDate":{"$t":"2011-10-17T18:42:04.000Z"},"issues$id":{"$t":10},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Area-Compiler"}],"issues$owner":{"issues$uri":{"$t":"/u/116010686905328984286/"},"issues$username":{"$t":"johnl...@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"D0MCRH47eCl7ImA9WhdbEks.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/11"},"published":{"$t":"2011-10-10T14:07:17.000Z"},"updated":{"$t":"2011-10-10T16:51:05.000Z"},"title":{"$t":"Error in first online tutorial"},"content":{"$t":"\r\n1. Enter any 3 russian symbols instead of &quot;World&quot;\r\n2. Run.\r\n3. Program prints &quot;Hello, хуй!&quot;\r\n\r\nхуй - russian dirty word. Do you have russian programmers? ;)\r\n\r\nI'm using google chrome 14 to try this tutorial.\r\nIn some cases (when number of russian symbols is more then 3) it prints squares instead of letters (it's encoding problems i think ;)\r\n\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/11/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=11"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/11"}],"author":[{"name":{"$t":"podg...@gmail.com"},"uri":{"$t":"/u/105898658743680019064/"}}],"issues$closedDate":{"$t":"2011-10-10T16:51:05.000Z"},"issues$id":{"$t":11},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$owner":{"issues$uri":{"$t":"/u/100337825224881731112/"},"issues$username":{"$t":"fmal...@google.com"}},"issues$stars":{"$t":2},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"A0UBSH47eCl7ImA9WhdbE04.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/12"},"published":{"$t":"2011-10-10T14:28:03.000Z"},"updated":{"$t":"2011-10-11T13:20:59.000Z"},"title":{"$t":"compiler should be be independant of browser code"},"content":{"$t":"Request: Make the Dart-&gt;JS compiler as a seperate file from the browser checking code so that the project can be included in other projects such as Node.JS\r\n\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/12/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=12"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/12"}],"author":[{"name":{"$t":"xdr...@gmail.com"},"uri":{"$t":"/u/117476521218063886204/"}}],"issues$closedDate":{"$t":"2011-10-11T13:20:59.000Z"},"issues$id":{"$t":12},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$stars":{"$t":3},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Invalid"}},{"gd$etag":"W/\"CkEHQ347eCl7ImA9WhJSEkk.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/13"},"published":{"$t":"2011-10-10T14:33:33.000Z"},"updated":{"$t":"2012-07-02T14:50:32.000Z"},"title":{"$t":"Add C#-style extension methods"},"content":{"$t":"Unless I'm reading the spec and examples wrong, it looks as if Dart uses the horrific Java approach of providing utility methods that operate on a interface, by putting them as static methods within some class with a name like 'Arrays' or 'Collections'. This is nonsense, especially when Linq and extension methods in C# have demonstrated a far superior approach, and Dart should provide an equivalent mechanism.\r\n\r\nAn obvious, easy way to add this would be that top level functions can optionally be called on an object using the dot operator, in which case the calling instance is passed as the first function parameter.\r\n\r\nE.g. to write a generic first method that operates over an iterator for a supplied predicate:\r\n\r\nT first&lt;T&gt;(Iterator&lt;T&gt; iterator, bool predicate(T obj)) {\r\n    while (iterator.hasNext()) {\r\n        if (predicate(iterator.next()) {\r\n            return true;\r\n        }\r\n    }\r\n    return false;\r\n}\r\n\r\nThis could be called on an instance of an iterator as follows:\r\n\r\nvar jon = peopleIterator.first((p) =&gt; p.name == 'Jon');\r\n\r\nUsing extension methods that also return iterators, they can then chained together to form fluent expressions:\r\n\r\nvar fiveOldestJons = peopleInterator.where((p) =&gt; p.name == 'Jon').orderBy((p) =&gt; p.age).take(5);\r\n\r\nIt's worrying looking through the language design that you don't seem to looked much beyond JavaScript and Java for your inspiration in Dart. I can't speak for users of other languages, but I strongly doubt C# developers will be particularly impressed by a lot of the Java style anachronisms, and I'd urge you to cast your net a little more widely in general.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/13/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=13"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/13"}],"author":[{"name":{"$t":"jon.rimmer"},"uri":{"$t":"/u/jon.rimmer/"}}],"issues$closedDate":{"$t":"2011-10-12T13:44:38.000Z"},"issues$id":{"$t":13},"issues$label":[{"$t":"Type-Enhancement"},{"$t":"Priority-Medium"},{"$t":"Area-Language"}],"issues$stars":{"$t":25},"issues$state":{"$t":"closed"},"issues$status":{"$t":"WontFix"}},{"gd$etag":"W/\"Ck4BRn47eCl7ImA9WhRaF04.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/14"},"published":{"$t":"2011-10-10T15:34:16.000Z"},"updated":{"$t":"2012-02-20T09:42:37.000Z"},"title":{"$t":"Add Tau constant to core Math class"},"content":{"$t":"With a new language, we are taking the opportunity to introduce better concepts, right? So please add Tau, the ratio of a circle's circumference to its radius (i.e. 2pi), to the Math class.\r\n\r\nLeave Math.PI as is, but please add Math.TAU\r\n\r\nThis is a safe addition with no side effects and minimal impact to the language and runtime.\r\n\r\nTau manifesto: http://tauday.com/\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/14/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=14"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/14"}],"author":[{"name":{"$t":"peter.ge...@gmail.com"},"uri":{"$t":"/u/116327704440122793403/"}}],"issues$closedDate":{"$t":"2012-02-16T00:26:22.000Z"},"issues$id":{"$t":14},"issues$label":[{"$t":"Type-Enhancement"},{"$t":"Priority-Medium"},{"$t":"Area-Library"}],"issues$owner":{"issues$uri":{"$t":"/u/jjb@google.com/"},"issues$username":{"$t":"jjb@google.com"}},"issues$stars":{"$t":17},"issues$state":{"$t":"closed"},"issues$status":{"$t":"WontFix"}},{"gd$etag":"W/\"DE8BQH47eCl7ImA9WhdaEkw.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/15"},"published":{"$t":"2011-10-10T15:36:24.000Z"},"updated":{"$t":"2011-10-21T17:07:31.000Z"},"title":{"$t":"jQuery integration"},"content":{"$t":"I may be mis-understanding dart, but I would like to put in a request that Google's engineers/someone smarter than me add jQuery as a possible library.\r\n\r\nFor instance, how would I accomplish the following using dart?\r\n\r\n&lt;pre&gt;\r\n$(&quot;p&quot;).click({function(){ alert(&quot;You clicked a paragraph tag!&quot;); });\r\n&lt;/pre&gt;\r\n\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/15/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=15"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/15"}],"author":[{"name":{"$t":"bri...@dearing-group.com"},"uri":{"$t":"/u/108006530617416183710/"}}],"issues$closedDate":{"$t":"2011-10-21T16:26:31.000Z"},"issues$id":{"$t":15},"issues$label":[{"$t":"Type-Enhancement"},{"$t":"Priority-Medium"},{"$t":"Area-UI"}],"issues$stars":{"$t":10},"issues$state":{"$t":"closed"},"issues$status":{"$t":"WontFix"}},{"gd$etag":"W/\"CUQNQ347eCl7ImA9WhdbE0g.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/16"},"published":{"$t":"2011-10-10T16:04:28.000Z"},"updated":{"$t":"2011-10-11T17:16:32.000Z"},"title":{"$t":"Generics disappear on try.dartlang.org"},"content":{"$t":"Go to try.dartlang.org, then insert and execute this code:\r\nclass PointlessValueWrapper {\r\n  PointlessValueWrapper(Type pointlessArgument);\r\n}\r\nmain() {\r\n  new PointlessValueWrapper(5);\r\n  new PointlessValueWrapper(&quot;Hello!&quot;);\r\n}\r\n\r\nAs expected, line 6 raises a warning.\r\n\r\nNow, open the link on the top right in a new tab. You'll see the same code, except the type parameters are missing. Because of this, line 2 now produces an error.\r\n\r\nI expect a tokeniser somewhere is misbehaving.\r\n\r\nUsing Firefox/Nightly (which is at version 10, at the moment).","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/16/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=16"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/16"}],"author":[{"name":{"$t":"pimmhoge...@gmail.com"},"uri":{"$t":"/u/117820825527967972339/"}}],"issues$closedDate":{"$t":"2011-10-11T17:16:32.000Z"},"issues$id":{"$t":16},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Area-Dartboard"}],"issues$owner":{"issues$uri":{"$t":"/u/103267283189406017873/"},"issues$username":{"$t":"knor...@google.com"}},"issues$stars":{"$t":0},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Verified"}},{"gd$etag":"W/\"D0UDRH47eCl7ImA9WhdbEks.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/17"},"published":{"$t":"2011-10-10T16:11:37.000Z"},"updated":{"$t":"2011-10-10T16:47:55.000Z"},"title":{"$t":"Can't build editor"},"content":{"$t":"In editor/build/README.txt:\r\n\r\n---\r\nTo begin, make sure the Dart plugin and feature sources are checked out from\r\nSVN. Edit rcpinit.sh to define the location of the TRUNK directory that was\r\nchecked out. Also checkout the usage profile plugin and feature from perforce.\r\nDefine that directory in rcpinit.sh as GDT_PROF. You only the the usage\r\nprofiler, not all of GPE.\r\n---\r\n\r\nBut google plugin for eclipse is not open-sourced yet:\r\nhttp://code.google.com/eclipse/docs/faq.html#source\r\n\r\nWhere can I find smth like /src/prof-git5/google3/third_party/java/google_plugin_eclipse/opensource/trunk\r\nfor building editor?","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/17/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=17"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/17"}],"author":[{"name":{"$t":"bats...@gmail.com"},"uri":{"$t":"/u/108382165757819799147/"}}],"issues$closedDate":{"$t":"2011-10-10T16:23:46.000Z"},"issues$id":{"$t":17},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Done"}},{"gd$etag":"W/\"CEYMRn47eCl7ImA9WhJbFU0.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/18"},"published":{"$t":"2011-10-10T16:31:10.000Z"},"updated":{"$t":"2012-09-24T15:56:27.000Z"},"title":{"$t":"Building dart on Mac OS X Lion with xcode 4"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. checkout source code\r\n2. run tools/build.py\r\n\r\nResult:\r\n=== BUILD NATIVE TARGET v8_base OF PROJECT v8 WITH CONFIGURATION Debug_x64 ===\r\n** BUILD FAILED **\r\n\r\nThe problem is in macosx sdk version. Google Dart needs 10.5 for building, but there are no macosx10.5 sdk in XCode 4 in Lion.\r\n\r\nWorkaround: specify sdk manually in build.py:\r\nIndex: tools/build.py\r\n===================================================================\r\n--- tools/build.py  (revision 296)\r\n+++ tools/build.py  (working copy)\r\n@@ -106,6 +106,8 @@\r\n         if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):\r\n           project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()\r\n         args = ['xcodebuild',\r\n+                '-sdk',\r\n+                'macosx10.6',\r\n                 '-project',\r\n                 project_file,\r\n                 '-target',\r\n\r\nFull instruction for workaround on Lion:\r\nhttp://batsuev.com/2011/10/building-google-dart-on-os-x-lion-with-xcode-4/\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/18/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=18"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/18"}],"author":[{"name":{"$t":"bats...@gmail.com"},"uri":{"$t":"/u/108382165757819799147/"}}],"issues$cc":[{"issues$uri":{"$t":"/u/efortuna@google.com/"},"issues$username":{"$t":"efortuna@google.com"}},{"issues$uri":{"$t":"/u/dgrove@google.com/"},"issues$username":{"$t":"dgrove@google.com"}}],"issues$id":{"$t":18},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Area-Build"},{"$t":"Milestone-M2"}],"issues$owner":{"issues$uri":{"$t":"/u/iposva@google.com/"},"issues$username":{"$t":"iposva@google.com"}},"issues$stars":{"$t":22},"issues$state":{"$t":"open"},"issues$status":{"$t":"Accepted"}},{"gd$etag":"W/\"D0EBSH47eCl7ImA9WhdbEko.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/19"},"published":{"$t":"2011-10-10T17:36:20.000Z"},"updated":{"$t":"2011-10-10T19:40:59.000Z"},"title":{"$t":"Integration with Eclipse"},"content":{"$t":"There should be a good integration towards common IDE's like Eclipse. ","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/19/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=19"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/19"}],"author":[{"name":{"$t":"ad...@trollweb.no"},"uri":{"$t":"/u/108751899022404107859/"}}],"issues$closedDate":{"$t":"2011-10-10T19:40:59.000Z"},"issues$id":{"$t":19},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$stars":{"$t":0},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Invalid"}},{"gd$etag":"W/\"DE4BRX47eCl7ImA9WhdbE0k.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/20"},"published":{"$t":"2011-10-10T17:48:37.000Z"},"updated":{"$t":"2011-10-11T15:29:14.000Z"},"title":{"$t":"typo in initial example on try-dart-lang.appspot.com"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. Visit http://try-dart-lang.appspot.com/\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\n\r\nI expected to see coherent wording. Instead, I see &quot;When you run the code … it it submitted to AppEngine&quot;. I believe the intended wording was &quot;When you run the code, it is submitted to AppEngine&quot;.\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\n\r\nThe live version on Chrome and Fedora.\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\n\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/20/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=20"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/20"}],"author":[{"name":{"$t":"mich...@ficarra.me"},"uri":{"$t":"/u/111990041337538184628/"}}],"issues$closedDate":{"$t":"2011-10-11T14:01:40.000Z"},"issues$id":{"$t":20},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Component-Docs"}],"issues$owner":{"issues$uri":{"$t":"/u/pdr@google.com/"},"issues$username":{"$t":"pdr@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"Ck8AQH47eCl7ImA9WhdbE0k.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/21"},"published":{"$t":"2011-10-10T17:55:20.000Z"},"updated":{"$t":"2011-10-11T13:47:21.000Z"},"title":{"$t":"Include Open Sans Bold web font in dartlang.org pages"},"content":{"$t":"The pages on dartlang.org use this tag to load Open Sans:\r\n\r\n&lt;link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'&gt;\r\n\r\nThis doesn't load the boldface file, while some parts like .intro &gt; dl &gt; dt are set in boldface. Currently this means that the regular font is made bold programmatically at these places, which looks very bad.\r\n\r\nInstead, please use this tag:\r\n\r\n&lt;link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'&gt;","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/21/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=21"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/21"}],"author":[{"name":{"$t":"sander.d...@gmail.com"},"uri":{"$t":"/u/117653750014788020856/"}}],"issues$closedDate":{"$t":"2011-10-11T13:47:21.000Z"},"issues$id":{"$t":21},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Component-Docs"}],"issues$owner":{"issues$uri":{"$t":"/u/drfibonacci@google.com/"},"issues$username":{"$t":"drfibonacci@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}},{"gd$etag":"W/\"CE4DR347eCl7ImA9WhJaEko.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/22"},"published":{"$t":"2011-10-10T18:47:48.000Z"},"updated":{"$t":"2012-10-03T14:02:56.000Z"},"title":{"$t":"Support non-nullable types."},"content":{"$t":"Short version: Null pointers are a really good way to mess up a program at runtime, and I'd like the Dart team to reevaluate whether they're absolutely required.\r\n\r\nSlightly longer version: I would say the #1 cause of issues in my programs (excluding logical errors/requirements errors) are NPEs. Having a language support NPE removal, be it via some clever compiler warning or simply removing null altogether, would be wonderful. I'm personally partial to Scala's method of null removal, but I'm sure PL gurus like yourselves have seen many others.\r\n\r\nDart has a stated goal of avoiding the creation of programs that &quot;are difficult to debug or maintain.&quot; NPEs are a huge pain point in this regard. I'd be really happy if the Dart team reevaluated whether they are absolutely required to achieve the other aims.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/22/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=22"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/22"}],"author":[{"name":{"$t":"cfle...@gmail.com"},"uri":{"$t":"/u/117457048271408990845/"}}],"issues$id":{"$t":22},"issues$label":[{"$t":"Type-Enhancement"},{"$t":"Priority-Medium"},{"$t":"Area-Language"},{"$t":"Milestone-Later"}],"issues$owner":{"issues$uri":{"$t":"/u/102708310591662789853/"},"issues$username":{"$t":"gbra...@google.com"}},"issues$stars":{"$t":110},"issues$state":{"$t":"open"},"issues$status":{"$t":"Triaged"}},{"gd$etag":"W/\"A0YNSH47eCl7ImA9WhdbE04.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/23"},"published":{"$t":"2011-10-10T19:00:32.000Z"},"updated":{"$t":"2011-10-11T13:19:59.000Z"},"title":{"$t":"The example Fibonacci is not responsive most of the times"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. At dartland.org, choose the example Fibonacci.\r\n2. Instead of 20, as a parameter for the function Fib, use 50.\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\nI was expecting a numeric output generated by the function. Instead, the page freezes or crashes.\r\n\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\nn/a. Google Chrome on Windows 7\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\n\r\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/23/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=23"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/23"}],"author":[{"name":{"$t":"guilherm...@gmail.com"},"uri":{"$t":"/u/117803371227799387793/"}}],"issues$closedDate":{"$t":"2011-10-11T13:19:59.000Z"},"issues$id":{"$t":23},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$stars":{"$t":0},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Invalid"}},{"gd$etag":"W/\"CU8BSH47eCl7ImA9WhdbEko.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/24"},"published":{"$t":"2011-10-10T19:01:19.000Z"},"updated":{"$t":"2011-10-10T19:10:59.000Z"},"title":{"$t":"Allowing null pointers is undesirable"},"content":{"$t":"Short version: Null pointers are a really good way to mess up a program at runtime, and I'd like the Dart team to reevaluate whether they're absolutely required.\r\n\r\nSlightly longer version: I would say the #1 cause of issues in my programs (excluding logical errors/requirements errors) are NPEs. Having a language support NPE removal, be it via some clever compiler warning or simply removing null altogether, would be wonderful. I'm personally partial to Scala's method of null removal, but I'm sure PL gurus like yourselves have seen many others.\r\n\r\nDart has a stated goal of avoiding the creation of programs that &quot;are difficult to debug or maintain.&quot; NPEs are a huge pain point in this regard. I'd be really happy if the Dart team reevaluated whether they are absolutely required to achieve the other aims.","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/24/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=24"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/24"}],"author":[{"name":{"$t":"cfle...@gmail.com"},"uri":{"$t":"/u/117457048271408990845/"}}],"issues$closedDate":{"$t":"2011-10-10T19:10:59.000Z"},"issues$id":{"$t":24},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"}],"issues$mergedInto":{"issues$id":{"$t":22},"issues$project":{"$t":"dart"}},"issues$stars":{"$t":2},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Duplicate"}},{"gd$etag":"W/\"C0EBRX47eCl7ImA9WhdbE0k.\"","id":{"$t":"http://code.google.com/feeds/issues/p/dart/issues/full/25"},"published":{"$t":"2011-10-10T19:50:14.000Z"},"updated":{"$t":"2011-10-11T14:00:54.000Z"},"title":{"$t":"Another typo in http://try-dart-lang.appspot.com/ code comments"},"content":{"$t":"\u003cb\u003eWhat steps will reproduce the problem?\u003c/b\u003e\n1. Visit http://try-dart-lang.appspot.com/\r\n\r\n\u003cb\u003eWhat is the expected output? What do you see instead?\u003c/b\u003e\n\r\nIn addition to issue20, I spotted another typo, marked with (sic) below.\r\n\r\nThe first or second &quot;of&quot; can be deleted, whichever you prefer :-)\r\n\r\n&quot;// Here you can try out the Dart Language from the comfort of of (sic) your own&quot;\r\n\r\n\u003cb\u003eWhat version of the product are you using? On what operating system?\u003c/b\u003e\n\r\nAbove URL at the time of this issue submission.\r\n\r\n\u003cb\u003ePlease provide any additional information below.\u003c/b\u003e\n","type":"html"},"link":[{"rel":"replies","type":"application/atom+xml","href":"http://code.google.com/feeds/issues/p/dart/issues/25/comments/full"},{"rel":"alternate","type":"text/html","href":"http://code.google.com/p/dart/issues/detail?id=25"},{"rel":"self","type":"application/atom+xml","href":"https://code.google.com/feeds/issues/p/dart/issues/full/25"}],"author":[{"name":{"$t":"adrian.a...@gmail.com"},"uri":{"$t":"/u/114973624116584041537/"}}],"issues$closedDate":{"$t":"2011-10-11T14:00:54.000Z"},"issues$id":{"$t":25},"issues$label":[{"$t":"Type-Defect"},{"$t":"Priority-Medium"},{"$t":"Component-Docs"}],"issues$owner":{"issues$uri":{"$t":"/u/pdr@google.com/"},"issues$username":{"$t":"pdr@google.com"}},"issues$stars":{"$t":1},"issues$state":{"$t":"closed"},"issues$status":{"$t":"Fixed"}}]}}
diff --git a/tests/lib/html/xhr_cross_origin_test.dart b/tests/lib/html/xhr_cross_origin_test.dart
new file mode 100644
index 0000000..7bc0a20
--- /dev/null
+++ b/tests/lib/html/xhr_cross_origin_test.dart
@@ -0,0 +1,105 @@
+// 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.
+
+library XHRCrossOriginTest;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:async_helper/async_minitest.dart';
+import 'dart:html';
+import "dart:convert";
+
+/**
+ * Examine the value of "crossOriginPort" as passed in from the url from
+ * [window.location] to determine what the cross-origin port is for
+ * this test.
+ */
+// TODO(efortuna): If we need to use this function frequently, make a
+// url_analyzer library that is part of test.dart that these tests can import.
+int get crossOriginPort {
+  var searchUrl = window.location.search;
+  var crossOriginStr = 'crossOriginPort=';
+  var index = searchUrl.indexOf(crossOriginStr);
+  var nextArg = searchUrl.indexOf('&', index);
+  return int.parse(searchUrl.substring(index + crossOriginStr.length,
+      nextArg == -1 ? searchUrl.length : nextArg));
+}
+
+var port = crossOriginPort;
+var host = '${window.location.protocol}//${window.location.hostname}:$port';
+
+Future testGetCrossDomain() async {
+  var gotError = false;
+  var url = '$host/root_dart/tests/lib/html/xhr_cross_origin_data.txt';
+  try {
+    var xhr = await HttpRequest.request(url);
+    var data = json.decode(xhr.response);
+    expect(data.containsKey('feed'), isTrue);
+    expect(data['feed'].containsKey('entry'), isTrue);
+    expect(data, isMap);
+  } catch (e) {
+    // Consume errors when not supporting cross origin.
+    gotError = true;
+  }
+  // Expect that we got an error when cross origin is not supported.
+  expect(gotError, !HttpRequest.supportsCrossOrigin);
+}
+
+Future testRequestCrossOrigin() async {
+  var url = '$host/root_dart/tests/lib/html/xhr_cross_origin_data.txt';
+  var response = await HttpRequest.requestCrossOrigin(url);
+  expect(response.contains('feed'), isTrue);
+}
+
+Future testRequestCrossOriginErrors() async {
+  try {
+    var response = await HttpRequest.requestCrossOrigin('does_not_exist');
+    fail('404s should fail request.');
+  } catch (_) {
+    // Expected failure.
+  }
+}
+
+void testCrossDomain() {
+  var url = '$host/root_dart/tests/lib/html/xhr_cross_origin_data.txt';
+  var xhr = new HttpRequest();
+  xhr.open('GET', url, async: true);
+  var validate = expectAsync((data) {
+    expect(data.containsKey('feed'), isTrue);
+    expect(data['feed'].containsKey('entry'), isTrue);
+    expect(data, isMap);
+  });
+  xhr.onReadyStateChange.listen((e) {
+    if (xhr.readyState == HttpRequest.DONE) {
+      validate(json.decode(xhr.response));
+    }
+  });
+  xhr.send();
+}
+
+Future testGetWithCredentialsCrossDomain() async {
+  var url = '$host/root_dart/tests/lib/html/xhr_cross_origin_data.txt';
+  var xhr = await HttpRequest.request(url, withCredentials: true);
+  var data = json.decode(xhr.response);
+  expect(data.containsKey('feed'), isTrue);
+  expect(data['feed'].containsKey('entry'), isTrue);
+  expect(data, isMap);
+}
+
+main() {
+  test('supported', () {
+    expect(HttpRequest.supportsCrossOrigin, isTrue);
+  });
+
+  asyncTest(() async {
+    await testGetCrossDomain();
+    await testRequestCrossOrigin();
+    await testRequestCrossOriginErrors();
+    // Skip the rest if not supported.
+    if (!HttpRequest.supportsCrossOrigin) {
+      return;
+    }
+    testCrossDomain();
+    await testGetWithCredentialsCrossDomain();
+  });
+}
diff --git a/tests/lib/html/xhr_test.dart b/tests/lib/html/xhr_test.dart
new file mode 100644
index 0000000..c885248
--- /dev/null
+++ b/tests/lib/html/xhr_test.dart
@@ -0,0 +1,265 @@
+// 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.
+
+library XHRTest;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
+import 'dart:typed_data';
+
+import 'package:async_helper/async_minitest.dart';
+import 'package:async_helper/async_helper.dart';
+
+// Cache blocker is a workaround for:
+// https://code.google.com/p/dart/issues/detail?id=11834
+var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
+var url = '/root_dart/tests/lib/html/xhr_cross_origin_data.txt?'
+    'cacheBlock=$cacheBlocker';
+
+void validate200Response(xhr) {
+  expect(xhr.status, 200);
+  var data = json.decode(xhr.responseText);
+  expect(data.containsKey('feed'), isTrue);
+  expect(data['feed'].containsKey('entry'), isTrue);
+  expect(data, isMap);
+}
+
+void validate404(xhr) {
+  expect(xhr.status, 404);
+  // We cannot say much about xhr.responseText, most HTTP servers will
+  // include an HTML page explaining the error to a human.
+  String responseText = xhr.responseText;
+  expect(responseText, isNotNull);
+}
+
+Future testXhrNoFile() async {
+  HttpRequest xhr = new HttpRequest();
+  xhr.open("GET", "NonExistingFile", async: true);
+  var completer = new Completer<void>();
+  xhr.onReadyStateChange.listen((event) {
+    if (!completer.isCompleted && xhr.readyState == HttpRequest.DONE) {
+      completer.complete();
+      validate404(xhr);
+    }
+  });
+  xhr.send();
+  await completer;
+}
+
+Future testXhrFile() async {
+  var loadEndCalled = false;
+
+  var xhr = new HttpRequest();
+  xhr.open('GET', url, async: true);
+  var completer = new Completer<void>();
+  xhr.onReadyStateChange.listen((e) {
+    if (!completer.isCompleted && xhr.readyState == HttpRequest.DONE) {
+      completer.complete();
+      validate200Response(xhr);
+
+      Timer.run(expectAsync(() {
+        expect(loadEndCalled, HttpRequest.supportsLoadEndEvent);
+      }));
+    }
+  });
+
+  xhr.onLoadEnd.listen((ProgressEvent e) {
+    loadEndCalled = true;
+  });
+  xhr.send();
+  await completer;
+}
+
+Future testRequestNoFile() async {
+  try {
+    await HttpRequest.request('NonExistingFile');
+    fail('Request should not have succeeded.');
+  } catch (error) {
+    HttpRequest xhr = error.target;
+    expect(xhr.readyState, HttpRequest.DONE);
+    validate404(xhr);
+  }
+}
+
+Future testRequestFile() async {
+  var xhr = await HttpRequest.request(url);
+  expect(xhr.readyState, HttpRequest.DONE);
+  validate200Response(xhr);
+}
+
+Future testRequestOnProgress() async {
+  var progressCalled = false;
+  var xhr = await HttpRequest.request(url, onProgress: (_) {
+    progressCalled = true;
+  });
+  expect(xhr.readyState, HttpRequest.DONE);
+  expect(progressCalled, HttpRequest.supportsProgressEvent);
+  validate200Response(xhr);
+}
+
+Future testRequestWithCredentialsNoFile() async {
+  try {
+    await HttpRequest.request('NonExistingFile', withCredentials: true);
+    fail('Request should not have succeeded.');
+  } catch (error) {
+    HttpRequest xhr = error.target;
+    expect(xhr.readyState, HttpRequest.DONE);
+    validate404(xhr);
+  }
+}
+
+Future testRequestWithCredentialsFile() async {
+  try {
+    HttpRequest xhr = await HttpRequest.request(url, withCredentials: true);
+    expect(xhr.readyState, HttpRequest.DONE);
+    validate200Response(xhr);
+  } catch (_) {
+    fail('Request should succeed.');
+  }
+}
+
+Future testGetStringFile() => HttpRequest.getString(url);
+
+Future testGetStringNoFile() async {
+  try {
+    await HttpRequest.getString('NonExistingFile');
+    fail('Succeeded for non-existing file.');
+  } catch (error) {
+    HttpRequest xhr = error.target;
+    expect(xhr.readyState, HttpRequest.DONE);
+    validate404(xhr);
+  }
+}
+
+Future testRequestResponseTypeArrayBuffer() async {
+  if (Platform.supportsTypedData) {
+    var xhr = await HttpRequest.request(url,
+        responseType: 'arraybuffer',
+        requestHeaders: {'Content-Type': 'text/xml'});
+    expect(xhr.status, 200);
+    var byteBuffer = xhr.response;
+    expect(byteBuffer, isInstanceOf<ByteBuffer>());
+    expect(byteBuffer, isNotNull);
+  }
+}
+
+Future testOverrideMimeType() async {
+  bool gotError = false;
+  try {
+    await HttpRequest.request(url, mimeType: 'application/binary');
+  } catch (_) {
+    gotError = true;
+  }
+  expect(gotError, !HttpRequest.supportsOverrideMimeType);
+}
+
+Future testXhrUpload() async {
+  if (Platform.supportsTypedData) {
+    var xhr = new HttpRequest();
+    var progressCalled = false;
+    xhr.upload.onProgress.listen((e) {
+      progressCalled = true;
+    });
+
+    xhr.open(
+        'POST', '${window.location.protocol}//${window.location.host}/echo');
+
+    // 10MB of payload data w/ a bit of data to make sure it
+    // doesn't get compressed to nil.
+    var data = new Uint8List(1 * 1024 * 1024);
+    for (var i = 0; i < data.length; ++i) {
+      data[i] = i & 0xFF;
+    }
+    xhr.send(new Uint8List.view(data.buffer));
+
+    await xhr.onLoad.first;
+    expect(progressCalled, isTrue, reason: 'onProgress should be fired');
+  }
+}
+
+Future testXhrPostFormData() async {
+  var data = {'name': 'John', 'time': '2 pm'};
+
+  var parts = [];
+  for (var key in data.keys) {
+    parts.add('${Uri.encodeQueryComponent(key)}='
+        '${Uri.encodeQueryComponent(data[key]!)}');
+  }
+  var encodedData = parts.join('&');
+
+  var xhr = await HttpRequest.postFormData(
+      '${window.location.protocol}//${window.location.host}/echo', data);
+  expect(xhr.responseText, encodedData);
+}
+
+Future testRequestResponseTypeBlob() async {
+  if (Platform.supportsTypedData) {
+    var xhr = await HttpRequest.request(url, responseType: 'blob');
+    expect(xhr.status, 200);
+    var blob = xhr.response;
+    expect(blob is Blob, isTrue);
+    expect(blob, isNotNull);
+  }
+}
+
+Future testResponseTypeJson() async {
+  var url = '${window.location.protocol}//${window.location.host}/echo';
+  var data = {
+    'key': 'value',
+    'a': 'b',
+    'one': 2,
+  };
+
+  var xhr = await HttpRequest.request(url,
+      method: 'POST', sendData: json.encode(data), responseType: 'json');
+  expect(xhr.status, 200);
+  var jsonResponse = xhr.response;
+  expect(jsonResponse, data);
+}
+
+Future testResponseHeaders() async {
+  var xhr = await HttpRequest.request(url);
+  var contentTypeHeader = xhr.responseHeaders['content-type'];
+  expect(contentTypeHeader, isNotNull);
+  // Should be like: 'text/plain; charset=utf-8'
+  expect(contentTypeHeader!.contains('text/plain'), isTrue);
+  expect(contentTypeHeader.contains('charset=utf-8'), isTrue);
+}
+
+main() {
+  test('supportsProgressEvent', () {
+    expect(HttpRequest.supportsProgressEvent, isTrue);
+  });
+
+  test('supportsOnLoadEnd', () {
+    expect(HttpRequest.supportsLoadEndEvent, isTrue);
+  });
+
+  test('supportsOverrideMimeType', () {
+    expect(HttpRequest.supportsOverrideMimeType, isTrue);
+  });
+
+  asyncTest(() async {
+    await testXhrNoFile();
+    await testXhrFile();
+    await testRequestNoFile();
+    await testRequestFile();
+    await testRequestOnProgress();
+    await testRequestWithCredentialsNoFile();
+    await testRequestWithCredentialsFile();
+    await testGetStringFile();
+    await testGetStringNoFile();
+    await testRequestResponseTypeArrayBuffer();
+    await testOverrideMimeType();
+    await testXhrUpload();
+    await testXhrPostFormData();
+
+    await testRequestResponseTypeBlob();
+
+    await testResponseTypeJson();
+
+    await testResponseHeaders();
+  });
+}
diff --git a/tests/lib/html/xsltprocessor_test.dart b/tests/lib/html/xsltprocessor_test.dart
new file mode 100644
index 0000000..61cb5a0
--- /dev/null
+++ b/tests/lib/html/xsltprocessor_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() {
+  group('supported', () {
+    test('supported', () {
+      expect(XsltProcessor.supported, true);
+    });
+  });
+
+  group('functional', () {
+    var isXsltProcessor =
+        predicate((x) => x is XsltProcessor, 'is an XsltProcessor');
+
+    var expectation = XsltProcessor.supported ? returnsNormally : throws;
+
+    test('constructorTest', () {
+      expect(() {
+        var processor = new XsltProcessor();
+        expect(processor, isNotNull);
+        expect(processor, isXsltProcessor);
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/lib/isolate/function_send1_test.dart b/tests/lib/isolate/function_send1_test.dart
index b25042e..1955c96 100644
--- a/tests/lib/isolate/function_send1_test.dart
+++ b/tests/lib/isolate/function_send1_test.dart
@@ -135,12 +135,12 @@
 void testUnsendable(name, func) {
   asyncStart();
   Isolate.spawnUri(Uri.parse("function_send_test.dart"), [], func)
-      .then((v) => throw "allowed spawn direct?", onError: (e, s) {
+      .then<void>((v) => throw "allowed spawn direct?", onError: (e, s) {
     asyncEnd();
   });
   asyncStart();
   Isolate.spawnUri(Uri.parse("function_send_test.dart"), [], [func])
-      .then((v) => throw "allowed spawn wrapped?", onError: (e, s) {
+      .then<void>((v) => throw "allowed spawn wrapped?", onError: (e, s) {
     asyncEnd();
   });
 }
diff --git a/tests/lib/isolate/function_send_test.dart b/tests/lib/isolate/function_send_test.dart
index 24e9d77..38b4698 100644
--- a/tests/lib/isolate/function_send_test.dart
+++ b/tests/lib/isolate/function_send_test.dart
@@ -175,12 +175,12 @@
 
 void testUnsendable(name, func) {
   asyncStart();
-  Isolate.spawn(nop, func).then((v) => throw "allowed spawn direct?",
+  Isolate.spawn(nop, func).then<void>((v) => throw "allowed spawn direct?",
       onError: (e, s) {
     asyncEnd();
   });
   asyncStart();
-  Isolate.spawn(nop, [func]).then((v) => throw "allowed spawn wrapped?",
+  Isolate.spawn(nop, [func]).then<void>((v) => throw "allowed spawn wrapped?",
       onError: (e, s) {
     asyncEnd();
   });
@@ -191,10 +191,10 @@
   });
   Expect.throws(() {
     noReply.sendPort.send(func);
-  }, null, "send direct");
+  }, (_) => true, "send direct");
   Expect.throws(() {
     noReply.sendPort.send([func]);
-  }, null, "send wrapped");
+  }, (_) => true, "send wrapped");
   scheduleMicrotask(() {
     noReply.close();
     asyncEnd();
@@ -210,7 +210,7 @@
     } finally {
       p.send(0); //   Closes echo port.
     }
-  }).then((p) => throw "unreachable 2", onError: (e, s) {
+  }).then<void>((p) => throw "unreachable 2", onError: (e, s) {
     asyncEnd();
   });
 }
diff --git a/tests/lib/isolate/issue_21398_parent_isolate_test.dart b/tests/lib/isolate/issue_21398_parent_isolate_test.dart
index 34e91de..5264827 100644
--- a/tests/lib/isolate/issue_21398_parent_isolate_test.dart
+++ b/tests/lib/isolate/issue_21398_parent_isolate_test.dart
@@ -29,8 +29,10 @@
   // First spawn an isolate using spawnURI and have it
   // send back a "non-literal" like object.
   asyncStart();
-  Isolate.spawnUri(Uri.parse('issue_21398_child_isolate.dart'), [],
-      [new FromMainIsolate(), receive1.sendPort]).catchError((error) {
+  Future<Isolate?>.value(Isolate.spawnUri(
+      Uri.parse('issue_21398_child_isolate.dart'),
+      [],
+      [new FromMainIsolate(), receive1.sendPort])).catchError((error) {
     Expect.isTrue(error is ArgumentError);
     asyncEnd();
   });
diff --git a/tests/lib/isolate/message3_test.dart b/tests/lib/isolate/message3_test.dart
index 0bc63ff..f1f11bf 100644
--- a/tests/lib/isolate/message3_test.dart
+++ b/tests/lib/isolate/message3_test.dart
@@ -60,7 +60,11 @@
 }
 
 class E {
+  // Make sure E.fun is not removed by the tree shaker, as this test verifies
+  // that an object with a tear-off in E.fun cannot be sent.
+  @pragma("vm:entry-point")
   Function fun;
+
   E(this.fun);
 
   static fooFun() => 499;
diff --git a/tests/lib/isolate/native_wrapper_message_test.dart b/tests/lib/isolate/native_wrapper_message_test.dart
index 2b663d5..366a84b 100644
--- a/tests/lib/isolate/native_wrapper_message_test.dart
+++ b/tests/lib/isolate/native_wrapper_message_test.dart
@@ -28,7 +28,7 @@
   var snd = Isolate.spawn(echo, msg);
 
   asyncStart();
-  snd.catchError((e) {
+  Future<Isolate?>.value(snd).catchError((e) {
     Expect.isTrue(e is ArgumentError);
     Expect.isTrue("$e".contains("NativeWrapper"));
     port.close();
diff --git a/tests/lib/isolate/nnbd_spawn_autodetect_test.dart b/tests/lib/isolate/nnbd_spawn_autodetect_test.dart
new file mode 100644
index 0000000..3e9c617
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawn_autodetect_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:async_helper/async_minitest.dart";
+
+void testNullSafetyMode(String filePath, String version, String expected) {
+  File mainIsolate = new File(filePath);
+  mainIsolate.writeAsStringSync('''
+    // $version
+    import \'dart:isolate\';
+
+    spawnFunc(List args) {
+      var data = args[0];
+      var replyTo = args[1];
+      try {
+        int x = null as int;
+        replyTo.send(\'re: weak\');
+      } catch (ex) {
+        replyTo.send(\'re: strong\');
+      }
+    }
+
+    void main() async {
+      const String debugName = \'spawnedIsolate\';
+      final exitPort = ReceivePort();
+      final port = new ReceivePort();
+      port.listen((msg) {
+          print(msg);
+          port.close();
+      });
+
+      final isolate = await Isolate.spawn(
+          spawnFunc,
+          [\'re: hi\', port.sendPort],
+          paused: false,
+          debugName: debugName,
+          onExit: exitPort.sendPort);
+
+      // Explicitly await spawned isolate exit to enforce main isolate not
+      // completing (and the stand-alone runtime exiting) before the spawned
+      // isolate is done.
+      await exitPort.first;
+    }
+    ''');
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--enable-experiment=non-nullable");
+  args.add(mainIsolate.path);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+
+  try {
+    // Strong Isolate Spawning another Strong Isolate using spawn.
+    testNullSafetyMode("$tmpDirPath/strong.dart", '', 're: strong');
+
+    // Weak Isolate Spawning a Weak Isolate using spawn.
+    testNullSafetyMode("$tmpDirPath/weak.dart", '@dart=2.6', 're: weak');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_test.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_test.dart
new file mode 100644
index 0000000..49afc571
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawnuri_autodetect_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:async_helper/async_minitest.dart";
+
+void testNullSafetyMode(String filePath, String uri, String expected) {
+  File mainIsolate = new File(filePath);
+  mainIsolate.writeAsStringSync('''
+    library spawn_tests;
+
+    import \'dart:isolate\';
+
+    void main() async {
+      const String debugName = \'spawnedIsolate\';
+      final exitPort = ReceivePort();
+      final port = new ReceivePort();
+      port.listen((msg) {
+          print(msg);
+          port.close();
+      });
+
+      final isolate = await Isolate.spawnUri(
+        Uri.parse(\'$uri\'),
+          [\'re: hi\'],
+          port.sendPort,
+          paused: false,
+          debugName: debugName,
+          onExit: exitPort.sendPort);
+
+      // Explicitly await spawned isolate exit to enforce main isolate not
+      // completing (and the stand-alone runtime exiting) before the spawned
+      // isolate is done.
+      await exitPort.first;
+    }
+    ''');
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--enable-experiment=non-nullable");
+  args.add(mainIsolate.path);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+
+  // Generate code for an isolate to run in strong mode.
+  File strongIsolate = new File("$tmpDirPath/strong_isolate.dart");
+  strongIsolate.writeAsStringSync('''
+    library SpawnUriStrongIsolate;
+    main(List<String> args, replyTo) {
+      var data = args[0];
+      try {
+        int x = null as int;
+        replyTo.send(\'re: weak\');
+      } catch (ex) {
+        replyTo.send(\'re: strong\');
+      }
+    }
+    ''');
+
+  // Generate code for an isolate to run in weak mode.
+  File weakIsolate = new File("$tmpDirPath/weak_isolate.dart");
+  weakIsolate.writeAsStringSync('''
+    // @dart=2.7
+    library SpawnUriStrongIsolate;
+    main(List<String> args, replyTo) {
+      var data = args[0];
+      try {
+        int x = null as int;
+        replyTo.send(\'re: weak\');
+      } catch (ex) {
+        replyTo.send(\'re: strong\');
+      }
+    }
+    ''');
+
+  try {
+    // Strong Isolate Spawning another Strong Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/strong_strong.dart", strongIsolate.path, 're: strong');
+
+    // Strong Isolate Spawning a Weak Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/strong_weak.dart", weakIsolate.path, 're: weak');
+
+    // Weak Isolate Spawning a Strong Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/weak_strong.dart", strongIsolate.path, 're: strong');
+
+    // Weak Isolate Spawning a Weak Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/weak_weak.dart", weakIsolate.path, 're: weak');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/no_package_test.dart b/tests/lib/isolate/no_package_test.dart
new file mode 100644
index 0000000..833e56b
--- /dev/null
+++ b/tests/lib/isolate/no_package_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:async_helper/async_minitest.dart";
+
+void testNoPackages(String filePath, String uri, String expected) {
+  File mainIsolate = new File(filePath);
+  mainIsolate.writeAsStringSync('''
+    library spawn_tests;
+
+    import \'dart:isolate\';
+
+    void main() async {
+      const String debugName = \'spawnedIsolate\';
+      final exitPort = ReceivePort();
+      final port = new ReceivePort();
+      port.listen((msg) {
+          print(msg);
+          port.close();
+      });
+
+      final isolate = await Isolate.spawnUri(
+        Uri.parse(\'$uri\'),
+          [\'$expected\'],
+          port.sendPort,
+          paused: false,
+          debugName: debugName,
+          onExit: exitPort.sendPort);
+
+      // Explicitly await spawned isolate exit to enforce main isolate not
+      // completing (and the stand-alone runtime exiting) before the spawned
+      // isolate is done.
+      await exitPort.first;
+    }
+    ''');
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add(mainIsolate.path);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+
+  // Generate code for an isolate to run without any package specification.
+  File noPackageIsolate = new File("$tmpDirPath/no_package.dart");
+  noPackageIsolate.writeAsStringSync('''
+    library SpawnUriIsolate;
+    main(List<String> args, replyTo) {
+      var data = args[0];
+      replyTo.send(data);
+    }
+    ''');
+
+  try {
+    // Isolate Spawning another Isolate without any package specification.
+    testNoPackages("$tmpDirPath/no_package_isolate.dart", noPackageIsolate.path,
+        're: no package');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/package_config_getter_test.dart b/tests/lib/isolate/package_config_getter_test.dart
new file mode 100644
index 0000000..0b7d506
--- /dev/null
+++ b/tests/lib/isolate/package_config_getter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+import 'spawn_uri__package_uri__test.dart';
+
+final executable = Platform.executable;
+
+main() async {
+  // Make a folder structure that has both ".dart_tool/package_config.json" and
+  // ".packages" and ensure VM prefers to use ".packages".
+  await withTempDir((String tempDir) async {
+    // Setup ".packages" with "foo -> ..." mapping.
+    final dotPackagesPath = path.join(tempDir, '.packages');
+    final dotPackagesFile = File(dotPackagesPath);
+    await dotPackagesFile.writeAsString(buildDotPackages('foo'));
+
+    // Setup bogus ".dart_tool/package_config.json" with "invalid -> ..."
+    // mapping.
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonPath =
+        path.join(dotDartToolDir, 'package_config.json');
+    final packageConfigJsonFile = File(packageConfigJsonPath);
+    await packageConfigJsonFile
+        .writeAsString(buildPackageConfig('invalid', true));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    await File(mainFile).writeAsString('''
+import 'dart:io' as io;
+import 'dart:isolate';
+
+main() async {
+  final uri = await Isolate.packageConfig;
+  final expectedUri = Uri.parse('${dotPackagesFile.uri}');
+  if (uri != expectedUri) {
+    throw 'VM should use .packages file (but used \$uri).';
+  }
+}
+''');
+
+    await run(executable, [mainFile]);
+  });
+}
diff --git a/tests/lib/isolate/package_config_test.dart b/tests/lib/isolate/package_config_test.dart
index cc345ee..c9b4f02 100644
--- a/tests/lib/isolate/package_config_test.dart
+++ b/tests/lib/isolate/package_config_test.dart
@@ -8,33 +8,26 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_CONFIG = "foobar:///no/such/file/";
+const String packageConfig = "foobar:///no/such/file/";
+const String errorString = "IsolateSpawnException: Unable to spawn isolate:";
+const String errorString2 = "Error when reading '$packageConfig'";
 
-main([args, port]) async {
-  if (port != null) {
-    testPackageConfig(port);
-    return;
+main([args, msg]) async {
+  if (msg != null) {
+    throw 'unreachable';
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageConfig: Uri.parse(SPAWN_PACKAGE_CONFIG));
-  p.handler = (msg) {
-    p.close();
-    if (msg[0] != SPAWN_PACKAGE_CONFIG) {
-      throw "Bad package config in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Non-null loaded package config in isolate: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package config: ${await Isolate.packageConfig}");
-}
-
-testPackageConfig(port) async {
-  var packageConfigStr = Platform.packageConfig;
-  var packageConfig = await Isolate.packageConfig;
-  print("Spawned isolate's package config flag: $packageConfigStr");
-  print("Spawned isolate's loaded package config: $packageConfig");
-  port.send([packageConfigStr, packageConfig.toString()]);
+  dynamic error;
+  try {
+    await Isolate.spawnUri(Platform.script, [], 'msg',
+        packageConfig: Uri.parse('foobar:///no/such/file/'));
+  } catch (e) {
+    error = e;
+  }
+  if (error == null) throw 'Expected a Spawning error.';
+  if (!'$error'.contains(errorString)) {
+    throw 'Epected: $errorString to contain "$errorString"';
+  }
+  if (!'$error'.contains(errorString2)) {
+    throw 'Epected: $errorString to contain "$errorString2"';
+  }
 }
diff --git a/tests/lib/isolate/package_resolve_test.dart b/tests/lib/isolate/package_resolve_test.dart
index 241732e..50686a3 100644
--- a/tests/lib/isolate/package_resolve_test.dart
+++ b/tests/lib/isolate/package_resolve_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -8,44 +8,67 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_ROOT = "file:///no/such/package/root/";
-final PACKAGE_URI = "package:foo/bar.dart";
-final PACKAGE_PATH = "file:///no/such/package/root/foo/bar.dart";
+final packageUriToResolve = "package:foo/bar.dart";
+final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
+
+final dotPackages = """
+# This is the content of a .packages file.
+foo:file:///no/such/directory/lib/
+""";
+
+final packageConfigJson = """
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///no/such/directory",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    }
+  ]
+}
+""";
 
 main([args, port]) async {
   if (port != null) {
     testPackageResolution(port);
     return;
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
-  p.handler = (msg) {
-    p.close();
-    if (msg is! List) {
-      print(msg.runtimeType);
-      throw "Failure return from spawned isolate:\n\n$msg";
-    }
-    if (msg[0] != null) {
-      throw "Bad package root in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Package path not matching: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+  await runTest(dotPackages);
+  await runTest(packageConfigJson);
+}
+
+Future runTest(String packageConfig) async {
+  final data = Uri.dataFromString(packageConfig);
+  final port = ReceivePort();
+  await Isolate.spawnUri(Platform.script, [], port.sendPort,
+      packageConfig: data);
+  final msg = await port.first;
+  if (msg is! List) {
+    print(msg.runtimeType);
+    throw "Failure return from spawned isolate:\n\n$msg";
+  }
+  if (msg[0] != data.toString()) {
+    throw "Bad package config in child isolate: ${msg[0]}\n"
+        "Expected: $data";
+  }
+  if (msg[1] != packageResolvedUri) {
+    throw "Package path not matching: ${msg[1]}";
+  }
+  print("SUCCESS");
 }
 
 testPackageResolution(port) async {
   try {
-    var packageRootStr = Platform.packageRoot;
-    var packageRoot = await Isolate.packageRoot;
-    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
-    print("Spawned isolate's package root flag: $packageRootStr");
-    print("Spawned isolate's loaded package root: $packageRoot");
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg =
+        await Isolate.resolvePackageUri(Uri.parse(packageUriToResolve));
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
     print("Spawned isolate's resolved package path: $resolvedPkg");
-    port.send([packageRoot.toString(), resolvedPkg.toString()]);
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
   } catch (e, s) {
     port.send("$e\n$s\n");
   }
diff --git a/tests/lib/isolate/spawn_uri__package_uri__test.dart b/tests/lib/isolate/spawn_uri__package_uri__test.dart
new file mode 100644
index 0000000..d5efa2c
--- /dev/null
+++ b/tests/lib/isolate/spawn_uri__package_uri__test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+final executable = Platform.executable;
+
+main() async {
+  // Run the Dart VM with or without:
+  //     --packages=<packages|package_config>
+  for (final runWithPackagesArg in const [true, false]) {
+    // Run the isolate with or without
+    //    Isolate.spawnUri(..., packageConfig: <packages|package_config>)
+    print('TEST runWithPackagesArg = $runWithPackagesArg ');
+    for (final spawnWithPackageConfig in const [true, false]) {
+      print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
+      final bool checkForResolveUri =
+          runWithPackagesArg || !spawnWithPackageConfig;
+      await runDotPackagesTest(
+          runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri);
+      for (final optionalPackageUri in const [true, false]) {
+        print('TEST optionalPackageUri = $optionalPackageUri');
+        await runPackageConfigTest(runWithPackagesArg, spawnWithPackageConfig,
+            optionalPackageUri, checkForResolveUri);
+      }
+    }
+  }
+}
+
+Future runPackageConfigTest(bool withPackagesArg, bool spawnWithArg,
+    bool optionalPackageUri, bool checkForResolveUri) async {
+  await withApplicationDirAndDotDartToolPackageConfig(
+      (String tempDir, String packageJson, String mainFile) async {
+    final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
+    await run(executable, args);
+  }, spawnWithArg, optionalPackageUri, checkForResolveUri);
+}
+
+Future runDotPackagesTest(
+    bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
+  await withApplicationDirAndDotPackages(
+      (String tempDir, String dotPackagesFile, String mainFile) async {
+    final args = [
+      if (withPackagesArg) '--packages=$dotPackagesFile',
+      mainFile,
+    ];
+    await run(executable, args);
+  }, spawnWithArg, checkForResolveUri);
+}
+
+Future withApplicationDirAndDotPackages(
+    Future fn(String tempDir, String packagesDir, String mainFile),
+    bool spawnWithArg,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".packages"
+    final dotPackagesFile =
+        path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
+    await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? dotPackagesFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, dotPackagesFile, mainFile);
+  });
+}
+
+Future withApplicationDirAndDotDartToolPackageConfig(
+    Future fn(String tempDir, String packageJson, String mainFile),
+    bool spawnWithArg,
+    bool optionalPackageUri,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".dart_tool/package_config.json"
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonFile = path.join(
+        dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
+    await File(packageConfigJsonFile)
+        .writeAsString(buildPackageConfig('foo', optionalPackageUri));
+
+    // Setup actual application
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? packageConfigJsonFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, packageConfigJsonFile, mainFile);
+  });
+}
+
+Future withTempDir(Future fn(String dir)) async {
+  final dir = await Directory.systemTemp.createTemp('spawn_uri');
+  try {
+    await fn(dir.absolute.path);
+  } finally {
+    await dir.delete(recursive: true);
+  }
+}
+
+Future<ProcessResult> run(String executable, List<String> args,
+    {String? cwd}) async {
+  print('Running $executable ${args.join(' ')}');
+  final String workingDirectory = cwd ?? Directory.current.absolute.path;
+  final result = await Process.run(executable, ['--trace-loading', ...args],
+      workingDirectory: workingDirectory);
+  print('exitCode:\n${result.exitCode}');
+  print('stdout:\n${result.stdout}');
+  print('stdout:\n${result.stderr}');
+  Expect.equals(0, result.exitCode);
+  return result;
+}
+
+String buildDotPackages(String packageName) => '$packageName:.';
+
+String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "$packageName",
+      "rootUri": "../"
+      ${optionalPackageUri ? ', "packageUri": "./"' : ''}
+    }
+  ]
+}
+''';
+
+String buildChildIsolate() => '''
+  import 'dart:isolate';
+
+  main(List<String> args, SendPort message) {
+    message.send('child isolate is done');
+  }
+''';
+
+String buildMainIsolate(
+        String spawnUri, String? packageConfigUri, String? childIsolatePath) =>
+    '''
+  import 'dart:isolate';
+  import 'dart:io' as io;
+
+  main(List<String> args) async {
+    io.exitCode = 1;
+
+    final uri = Uri.parse('$spawnUri');
+    final resolvedUri = await Isolate.resolvePackageUri(uri);
+    if ("""\${resolvedUri?.toFilePath()}""" != r"""$childIsolatePath""") {
+      throw 'Could not Isolate.resolvePackageUri(uri).';
+    }
+
+    final rp = ReceivePort();
+    final isolateArgs = <String>['a'];
+    await Isolate.spawnUri(
+        uri,
+        isolateArgs,
+        rp.sendPort,
+        packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
+    final childIsolateMessage = await rp.first;
+    if (childIsolateMessage != 'child isolate is done') {
+      throw 'Did not receive correct message from child isolate.';
+    }
+
+    // Test was successful.
+    io.exitCode = 0;
+  }
+''';
diff --git a/tests/lib/isolate/stacktrace_message_test.dart b/tests/lib/isolate/stacktrace_message_test.dart
index 41a0820..b8ab5ab 100644
--- a/tests/lib/isolate/stacktrace_message_test.dart
+++ b/tests/lib/isolate/stacktrace_message_test.dart
@@ -14,7 +14,7 @@
   ReceivePort reply = new ReceivePort();
   Isolate.spawn(runTest, reply.sendPort);
   reply.first.then((pair) {
-    StackTrace stack = pair[0];
+    StackTrace? stack = pair[0];
     String stackString = pair[1];
     if (stack == null) {
       print("Failed to send stack-trace");
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 432516a..cd733a9 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -11,6 +11,9 @@
 developer/timeline_test: Skip # Not supported
 isolate/issue_24243_parent_isolate_test: Skip # Requires checked mode
 
+[ $runtime == dart_precompiled ]
+isolate/package_config_getter_test: SkipByDesign # AOT mode doesn't preserve package structure.
+
 [ $runtime == ff ]
 convert/streamed_conversion_utf8_decode_test: Slow, Pass # Issue 12029
 mirrors/mirrors_reader_test: Slow, Pass # Issue 16589
@@ -24,6 +27,9 @@
 html/indexeddb_3_test: Skip # Times out 1 out of 10.
 html/worker_api_test: Skip # Issue 13221
 
+[ $runtime != vm ]
+isolate/spawn_uri__package_uri__test: SkipByDesign # This test uses Isolate.spawnUri and only works in JIT mode.
+
 [ $system == windows ]
 html/xhr_test/xhr: Skip # Times out.  Issue 21527
 
@@ -49,13 +55,6 @@
 [ $arch != x64 || $compiler == dartkb || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
 
-[ $compiler != none || $runtime != vm ]
-isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
-isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
-isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
-isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
-isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
-
 [ $mode == product || $runtime != vm ]
 isolate/checked_test: Skip # Unsupported.
 
@@ -91,8 +90,15 @@
 isolate/mint_maker_test: Skip # Isolate.spawnUri
 isolate/nested_spawn2_test: Skip # Isolate.spawnUri
 isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/nnbd_spawn_autodetect_test: Skip # Auto detect not for precompiled.
+isolate/nnbd_spawnuri_autodetect_test: Skip # Auto detect not for precompiled.
+isolate/no_package_test: Skip # Isolate.spawnUri
+isolate/package_config_test: Skip # Isolate.spawnUri
 isolate/raw_port_test: Skip # Isolate.spawnUri
 isolate/request_reply_test: Skip # Isolate.spawnUri
+isolate/scenarios/automatic_resolution_spec/package_resolve_test: Skip # Isolate.spawnUri
+isolate/scenarios/package_relative_spec/package_relative_spec_test: Skip # Isolate.spawnUri
+isolate/scenarios/short_package/short_package_test: Skip # Isolate.spawnUri
 isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
 isolate/spawn_function_test: Skip # Isolate.spawnUri
 isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
@@ -106,6 +112,13 @@
 isolate/static_function_test: Skip # Isolate.spawnUri
 isolate/unresolved_ports_test: Skip # Isolate.spawnUri
 
+[ $runtime != vm || $compiler != dartk && $compiler != none ]
+isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
+isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
+isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
+isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
+isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
+
 [ $hot_reload || $hot_reload_rollback ]
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/utf85_test: SkipSlow
diff --git a/tests/lib/lib_vm.status b/tests/lib/lib_vm.status
index 92cc427..ae42a72 100644
--- a/tests/lib/lib_vm.status
+++ b/tests/lib/lib_vm.status
@@ -139,6 +139,9 @@
 isolate/non_fatal_exception_in_timer_callback_test/sleep: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/object_leak_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ondone_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_config_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_root_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/pause_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ping_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/port_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
@@ -147,12 +150,15 @@
 isolate/regress_flutter_22796_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/request_reply_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/resolve_package_uri_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/scenarios/package_data_uri_spec/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/send_private_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/simple_message_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_custom_class_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_generic_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri__package_uri__test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_exported_main_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri_fail_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_from_isolate_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_multi_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tests/lib/math/implement_rectangle_test.dart b/tests/lib/math/implement_rectangle_test.dart
index 3a31ed8..f6f6a91 100644
--- a/tests/lib/math/implement_rectangle_test.dart
+++ b/tests/lib/math/implement_rectangle_test.dart
@@ -25,9 +25,9 @@
 
   Rectangle(this.left, this.top, this.width, this.height);
 
-  T get right => left + width;
+  T get right => (left + width) as T;
 
-  T get bottom => top + height;
+  T get bottom => (top + height) as T;
 
   Point<T> get topLeft => new Point<T>(left, top);
 
@@ -58,7 +58,8 @@
     T rTop = min(top, other.top);
     T rRight = max(right, other.right);
     T rBottom = max(bottom, other.bottom);
-    return new Rectangle<T>(rLeft, rTop, rRight - rLeft, rBottom - rTop);
+    return new Rectangle<T>(
+        rLeft, rTop, (rRight - rLeft) as T, (rBottom - rTop) as T);
   }
 
   /// Tests whether `this` entirely contains [another].
@@ -75,6 +76,7 @@
     T rTop = max(top, rect.top);
     T rRight = min(right, rect.right);
     T rBottom = min(bottom, rect.bottom);
-    return new Rectangle<T>(rLeft, rTop, rRight - rLeft, rBottom - rTop);
+    return new Rectangle<T>(
+        rLeft, rTop, (rRight - rLeft) as T, (rBottom - rTop) as T);
   }
 }
diff --git a/tests/lib/math/rectangle_test.dart b/tests/lib/math/rectangle_test.dart
index f6b5ed2..f6cf2b2 100644
--- a/tests/lib/math/rectangle_test.dart
+++ b/tests/lib/math/rectangle_test.dart
@@ -68,8 +68,8 @@
     var r1 = createRectangle(test[1]);
     var expected = createRectangle(test[2]);
 
-    Expect.equals(expected, r0.intersection(r1));
-    Expect.equals(expected, r1.intersection(r0));
+    Expect.equals(expected, r0?.intersection(r1!));
+    Expect.equals(expected, r1?.intersection(r0!));
   }
 }
 
@@ -114,8 +114,8 @@
     var r1 = createRectangle(test[1]);
     var expected = createRectangle(test[2]);
 
-    Expect.equals(expected, r0.boundingBox(r1));
-    Expect.equals(expected, r1.boundingBox(r0));
+    Expect.equals(expected, r0?.boundingBox(r1!));
+    Expect.equals(expected, r1?.boundingBox(r0!));
   }
 }
 
diff --git a/tests/lib/mirrors/instance_members_easier_test.dart b/tests/lib/mirrors/instance_members_easier_test.dart
index e71fb13..ccd1b4f 100644
--- a/tests/lib/mirrors/instance_members_easier_test.dart
+++ b/tests/lib/mirrors/instance_members_easier_test.dart
@@ -54,15 +54,18 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
-  Expect.setEquals([
-    #instanceVariable,
-    const Symbol('instanceVariable='),
-    #inheritedInstanceVariable,
-    const Symbol('inheritedInstanceVariable=')
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+  Expect.setEquals(
+      [
+        #instanceVariable,
+        const Symbol('instanceVariable='),
+        #inheritedInstanceVariable,
+        const Symbol('inheritedInstanceVariable=')
+      ],
+      selectKeys(
+          cm.instanceMembers, (dynamic dm) => !dm.isPrivate && dm.isSynthetic));
 
   cm = reflectClass(Derived);
   Expect.setEquals([
@@ -75,7 +78,7 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
 
   cm = reflectClass(EasierMixinApplication);
   Expect.setEquals([
@@ -87,5 +90,5 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
 }
diff --git a/tests/lib/mirrors/instance_members_test.dart b/tests/lib/mirrors/instance_members_test.dart
index c71b5fa5..1eeb39a 100644
--- a/tests/lib/mirrors/instance_members_test.dart
+++ b/tests/lib/mirrors/instance_members_test.dart
@@ -40,15 +40,18 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
-  Expect.setEquals([
-    #instanceVariable,
-    const Symbol('instanceVariable='),
-    #inheritedInstanceVariable,
-    const Symbol('inheritedInstanceVariable='),
-    #mixinInstanceVariable,
-    const Symbol('mixinInstanceVariable=')
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+  Expect.setEquals(
+      [
+        #instanceVariable,
+        const Symbol('instanceVariable='),
+        #inheritedInstanceVariable,
+        const Symbol('inheritedInstanceVariable='),
+        #mixinInstanceVariable,
+        const Symbol('mixinInstanceVariable=')
+      ],
+      selectKeys(
+          cm.instanceMembers, (dynamic dm) => !dm.isPrivate && dm.isSynthetic));
 }
diff --git a/tests/lib/mirrors/instance_members_with_override_test.dart b/tests/lib/mirrors/instance_members_with_override_test.dart
index f1065c5..7325248 100644
--- a/tests/lib/mirrors/instance_members_with_override_test.dart
+++ b/tests/lib/mirrors/instance_members_with_override_test.dart
@@ -49,7 +49,7 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(sMirror.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(sMirror.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
   Expect.equals(sMirror, sMirror.instanceMembers[#field]!.owner);
@@ -74,7 +74,7 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cMirror.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cMirror.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
   Expect.equals(cMirror, cMirror.instanceMembers[#field]!.owner);
diff --git a/tests/lib/mirrors/relation_subclass_test.dart b/tests/lib/mirrors/relation_subclass_test.dart
index 7e83931..a80194a 100644
--- a/tests/lib/mirrors/relation_subclass_test.dart
+++ b/tests/lib/mirrors/relation_subclass_test.dart
@@ -96,12 +96,12 @@
   TypeMirror IntGenRef = (IntGen as TypedefMirror).referent;
   TypeMirror DubGenRef = (DubGen as TypedefMirror).referent;
 
-  Expect.isFalse(Func.isSubclassOf(NumPredRef));
-  Expect.isFalse(Func.isSubclassOf(IntPredRef));
-  Expect.isFalse(Func.isSubclassOf(DubPredRef));
-  Expect.isFalse(Func.isSubclassOf(NumGenRef));
-  Expect.isFalse(Func.isSubclassOf(IntGenRef));
-  Expect.isFalse(Func.isSubclassOf(DubGenRef));
+  Expect.isFalse(Func.isSubclassOf(NumPredRef as ClassMirror));
+  Expect.isFalse(Func.isSubclassOf(IntPredRef as ClassMirror));
+  Expect.isFalse(Func.isSubclassOf(DubPredRef as ClassMirror));
+  Expect.isFalse(Func.isSubclassOf(NumGenRef as ClassMirror));
+  Expect.isFalse(Func.isSubclassOf(IntGenRef as ClassMirror));
+  Expect.isFalse(Func.isSubclassOf(DubGenRef as ClassMirror));
 
   // The spec doesn't require these to be either value, only that they implement
   // Function.
diff --git a/tests/lib/mirrors/static_members_easier_test.dart b/tests/lib/mirrors/static_members_easier_test.dart
index 43b02b9..105a1c6 100644
--- a/tests/lib/mirrors/static_members_easier_test.dart
+++ b/tests/lib/mirrors/static_members_easier_test.dart
@@ -27,5 +27,5 @@
   ], selectKeys(cm.staticMembers, (dm) => true));
 
   Expect.setEquals([#staticVariable, const Symbol('staticVariable=')],
-      selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+      selectKeys(cm.staticMembers, (dynamic dm) => dm.isSynthetic));
 }
diff --git a/tests/lib/mirrors/static_members_test.dart b/tests/lib/mirrors/static_members_test.dart
index beeed6d..74cbb42 100644
--- a/tests/lib/mirrors/static_members_test.dart
+++ b/tests/lib/mirrors/static_members_test.dart
@@ -36,5 +36,5 @@
     const Symbol('staticVariable='),
     MirrorSystem.getSymbol('_staticVariable', lm),
     MirrorSystem.getSymbol('_staticVariable=', lm)
-  ], selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+  ], selectKeys(cm.staticMembers, (dynamic dm) => dm.isSynthetic));
 }
diff --git a/tests/lib/mirrors/synthetic_accessor_properties_test.dart b/tests/lib/mirrors/synthetic_accessor_properties_test.dart
index 9d1d6e3..cb32c8a 100644
--- a/tests/lib/mirrors/synthetic_accessor_properties_test.dart
+++ b/tests/lib/mirrors/synthetic_accessor_properties_test.dart
@@ -45,8 +45,7 @@
   Expect.equals(reflectClass(num), mm.returnType);
   Expect.listEquals([], mm.parameters);
 
-  mm = cm.instanceMembers[const Symbol('finalInstanceField=')] as MethodMirror;
-  Expect.isNull(mm);
+  Expect.isNull(cm.instanceMembers[const Symbol('finalInstanceField=')]);
 
   mm = cm.staticMembers[#staticField] as MethodMirror;
   expect('Method(s(staticField) in s(C), synthetic, static, getter)', mm);
@@ -67,6 +66,5 @@
   Expect.equals(reflectClass(int), mm.returnType);
   Expect.listEquals([], mm.parameters);
 
-  mm = cm.staticMembers[const Symbol('finalStaticField=')] as MethodMirror;
-  Expect.isNull(mm);
+  Expect.isNull(cm.staticMembers[const Symbol('finalStaticField=')]);
 }
diff --git a/tests/lib/mirrors/typedef_reflected_type_test.dart b/tests/lib/mirrors/typedef_reflected_type_test.dart
index 7b017f5..43b1378 100644
--- a/tests/lib/mirrors/typedef_reflected_type_test.dart
+++ b/tests/lib/mirrors/typedef_reflected_type_test.dart
@@ -12,7 +12,7 @@
 typedef int Bar();
 
 class C {
-  Bar fun(Foo<int> x) => null;
+  Bar fun(Foo<int> x) => () => 123;
 }
 
 main() {
diff --git a/tests/lib_2/async/futures_test.dart b/tests/lib_2/async/futures_test.dart
index a98d612..26b3019 100644
--- a/tests/lib_2/async/futures_test.dart
+++ b/tests/lib_2/async/futures_test.dart
@@ -77,6 +77,15 @@
   });
 }
 
+// Regression test for https://github.com/dart-lang/sdk/issues/41656
+Future testWaitWithErrorAndNonErrorEager() {
+  return Future(() {
+    var f1 = Future(() => throw "Error");
+    var f2 = Future(() => 3);
+    return Future.wait([f1, f2], eagerError: true);
+  }).then((_) => 0, onError: (_) => -1);
+}
+
 Future testWaitWithMultipleErrorsEager() {
   final futures = new List<Future>();
   final c1 = new Completer();
@@ -250,6 +259,7 @@
   futures.add(testWaitWithMultipleValues());
   futures.add(testWaitWithSingleError());
   futures.add(testWaitWithMultipleErrors());
+  futures.add(testWaitWithErrorAndNonErrorEager());
   futures.add(testWaitWithMultipleErrorsEager());
   futures.add(testWaitWithSingleErrorWithStackTrace());
   futures.add(testWaitWithMultipleErrorsWithStackTrace());
@@ -265,7 +275,7 @@
 
   asyncStart();
   Future.wait(futures).then((List list) {
-    Expect.equals(18, list.length);
+    Expect.equals(19, list.length);
     asyncEnd();
   });
 }
diff --git a/tests/lib_2/convert/chunked_conversion_utf82_test.dart b/tests/lib_2/convert/chunked_conversion_utf82_test.dart
index bc0b200..2e07f87 100644
--- a/tests/lib_2/convert/chunked_conversion_utf82_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf82_test.dart
@@ -46,11 +46,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -77,11 +80,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -220,44 +223,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/chunked_conversion_utf86_test.dart b/tests/lib_2/convert/chunked_conversion_utf86_test.dart
index a42e752..8c9a08c 100644
--- a/tests/lib_2/convert/chunked_conversion_utf86_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf86_test.dart
@@ -28,11 +28,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -59,11 +62,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -202,44 +205,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/chunked_conversion_utf87_test.dart b/tests/lib_2/convert/chunked_conversion_utf87_test.dart
index 9794690..67929af 100644
--- a/tests/lib_2/convert/chunked_conversion_utf87_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf87_test.dart
@@ -49,11 +49,14 @@
   return utf8.decode(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -80,11 +83,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -223,44 +226,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/chunked_conversion_utf88_test.dart b/tests/lib_2/convert/chunked_conversion_utf88_test.dart
index 58cecaa..8b19b2a 100644
--- a/tests/lib_2/convert/chunked_conversion_utf88_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf88_test.dart
@@ -112,8 +112,7 @@
   const LEADING_SURROGATE = 0xd801;
   const TRAILING_SURROGATE = 0xdc12;
   const UTF8_ENCODING = const [0xf0, 0x90, 0x90, 0x92];
-  const UTF8_LEADING = const [0xed, 0xa0, 0x81];
-  const UTF8_TRAILING = const [0xed, 0xb0, 0x92];
+  const UTF8_REPLACEMENT = const [0xef, 0xbf, 0xbd];
   const CHAR_A = 0x61;
 
   // Test surrogates at all kinds of locations.
@@ -129,17 +128,17 @@
     codeUnits[i] = LEADING_SURROGATE;
     var str = new String.fromCharCodes(codeUnits);
     var bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits.length = i + 2;
@@ -157,36 +156,36 @@
     codeUnits[i + 1] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits.length = i + 3;
@@ -208,12 +207,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
@@ -221,12 +220,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
@@ -234,12 +233,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     // Make sure the invariant is correct.
diff --git a/tests/lib_2/convert/json_utf8_chunk_test.dart b/tests/lib_2/convert/json_utf8_chunk_test.dart
index ec47339..cf5064e 100644
--- a/tests/lib_2/convert/json_utf8_chunk_test.dart
+++ b/tests/lib_2/convert/json_utf8_chunk_test.dart
@@ -284,69 +284,69 @@
 void testMalformed() {
   // Overlong encodings.
   jsonMalformedTest(
-      "overlong-0-2", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-0-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-0-4", "@\uFFFD@",
+      "overlong-0-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest(
-      "overlong-7f-2", "@\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-7f-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7f-4", "@\uFFFD@",
+      "overlong-7f-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x81, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-80-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-80-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-80-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-80-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x82, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-7ff-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7ff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-7ff-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7ff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x9f, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest("overlong-800-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-800-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0xa0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-ffff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-ffff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x8f, 0xbf, 0xbf, 0x40, 0x22]);
 
   // Unterminated multibyte sequences.
   jsonMalformedTest(
       "unterminated-2-normal", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-3-normal", "@\uFFFD\uFFFD@",
       [0x22, 0x40, 0xe0, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-4-normal", "@\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-multi", "@\uFFFD\x80@",
       [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-escape", "@\uFFFD\n@",
       [0x22, 0x40, 0xc0, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xe0, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-end", "@\uFFFD", [0x22, 0x40, 0xc0, 0x22]);
 
   jsonMalformedTest(
-      "unterminated-3-end", "@\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
+      "unterminated-3-end", "@\uFFFD\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
 
-  jsonMalformedTest(
-      "unterminated-4-end", "@\uFFFD", [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
+  jsonMalformedTest("unterminated-4-end", "@\uFFFD\uFFFD\uFFFD",
+      [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
 
   // Unexpected continuation byte
   // - after a normal character.
@@ -372,13 +372,13 @@
       "leading-2", "@\uFFFD\x80@", [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-3-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-3-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-3-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-4-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-3", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-3", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   // Overlong encodings of ASCII outside of strings always fail.
diff --git a/tests/lib_2/convert/utf82_test.dart b/tests/lib_2/convert/utf82_test.dart
index df08103..cf0c2b0 100644
--- a/tests/lib_2/convert/utf82_test.dart
+++ b/tests/lib_2/convert/utf82_test.dart
@@ -28,11 +28,14 @@
   return new Utf8Codec(allowMalformed: true).decoder.convert(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -64,11 +67,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -207,44 +210,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/utf84_test.dart b/tests/lib_2/convert/utf84_test.dart
index bc1db59..566b1fa 100755
--- a/tests/lib_2/convert/utf84_test.dart
+++ b/tests/lib_2/convert/utf84_test.dart
@@ -727,10 +727,14 @@
   Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
   Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
-  Expect
-      .listEquals([0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
+  Expect.listEquals(
+      [0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
 
   // unexpected continuation bytes
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
@@ -795,12 +799,15 @@
   // Sequences with last continuation byte missing
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
       "2-byte sequence with last byte missing");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80]), "3-byte sequence with last byte missing");
   Expect.listEquals(
-      [unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80]),
-      "4-byte sequence with last byte missing");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xe0, 0x80]),
+      "3-byte sequence with last byte missing");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80]), "4-byte sequence with last byte missing");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -871,6 +878,9 @@
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune
       ],
       utf8ToRunes([
@@ -890,8 +900,8 @@
         0x80,
         0x80,
         0xdf,
-        0xef,
-        0xbf,
+        0xef, // These two bytes form one incomplete sequence.
+        0xbf, // All others form one per byte.
         0xf7,
         0xbf,
         0xbf,
@@ -908,10 +918,10 @@
       "Concatenation of incomplete sequences");
 
   // Impossible bytes
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -921,11 +931,20 @@
 
   // Overlong sequences
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0xaf]), "c0 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0xaf]),
+      "c0 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -943,11 +962,20 @@
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc1, 0xbf]),
+      "c1 bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -965,11 +993,20 @@
   ], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0x80]), "c0 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0x80]),
+      "c0 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
diff --git a/tests/lib_2/convert/utf85_test.dart b/tests/lib_2/convert/utf85_test.dart
index 3f287e9..a380991 100644
--- a/tests/lib_2/convert/utf85_test.dart
+++ b/tests/lib_2/convert/utf85_test.dart
@@ -9,7 +9,7 @@
 
 main() {
   for (int i = 0; i <= 0x10FFFF; i++) {
-    if (i == unicodeBomCharacterRune) continue;
+    if (i == unicodeBomCharacterRune || (i & 0x1FF800) == 0xD800) continue;
     Expect.equals(
         i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
   }
diff --git a/tests/lib_2/convert/utf8_encode_test.dart b/tests/lib_2/convert/utf8_encode_test.dart
index 1e611bb..0a43e14 100644
--- a/tests/lib_2/convert/utf8_encode_test.dart
+++ b/tests/lib_2/convert/utf8_encode_test.dart
@@ -25,8 +25,8 @@
   String ascii = "ABCDE";
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0));
-  Expect
-      .listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
+  Expect.listEquals(
+      [0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
   Expect.listEquals([0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 1));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44], encoder.convert(ascii, 0, 4));
   Expect.listEquals([0x42, 0x43, 0x44], encoder.convert(ascii, 1, 4));
@@ -50,6 +50,6 @@
   Expect.listEquals(
       [0xc2, 0x82, 0xe1, 0x81, 0x81], encoder.convert(unicode, 1, 3));
   // Split in the middle of a surrogate pair.
-  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xed, 0xa0, 0x80],
+  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xef, 0xbf, 0xbd],
       encoder.convert(unicode, 1, 4));
 }
diff --git a/tests/lib_2/convert/utf8_test.dart b/tests/lib_2/convert/utf8_test.dart
index 858c982..6f97fd0 100644
--- a/tests/lib_2/convert/utf8_test.dart
+++ b/tests/lib_2/convert/utf8_test.dart
@@ -73,28 +73,29 @@
 
   // Bad encoding, points to first bad byte.
   testExn([0x80, 0x00], 0);
-  testExn([0xC0, 0x00], 1);
-  testExn([0xE0, 0x00], 1);
-  testExn([0xE0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x00], 1);
-  testExn([0xF0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x80, 0x80, 0x00], 3);
+  testExn([0xC2, 0x00], 1);
+  testExn([0xE2, 0x00], 1);
+  testExn([0xE2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x00], 1);
+  testExn([0xF2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x80, 0x80, 0x00], 3);
   testExn([0xF8, 0x00], 0);
   // Short encoding, points to end.
-  testExn([0xC0], 1);
-  testExn([0xE0], 1);
-  testExn([0xE0, 0x80], 2);
-  testExn([0xF0], 1);
-  testExn([0xF0, 0x80], 2);
-  testExn([0xF0, 0x80, 0x80], 3);
-  // Overlong encoding, points to start of encoding.
+  testExn([0xC2], 1);
+  testExn([0xE2], 1);
+  testExn([0xE2, 0x80], 2);
+  testExn([0xF2], 1);
+  testExn([0xF2, 0x80], 2);
+  testExn([0xF2, 0x80, 0x80], 3);
+  // Overlong encoding, points to byte that gave enough information to conclude
+  // that it was overlong.
   testExn([0xC0, 0x80], 0);
   testExn([0xC1, 0xBF], 0);
-  testExn([0xE0, 0x80, 0x80], 0);
-  testExn([0xE0, 0x9F, 0xBF], 0);
-  testExn([0xF0, 0x80, 0x80, 0x80], 0);
-  testExn([0xF0, 0x8F, 0xBF, 0xBF], 0);
+  testExn([0xE0, 0x80, 0x80], 1);
+  testExn([0xE0, 0x9F, 0xBF], 1);
+  testExn([0xF0, 0x80, 0x80, 0x80], 1);
+  testExn([0xF0, 0x8F, 0xBF, 0xBF], 1);
   // Invalid character (value too large, over 0x10FFFF).
-  testExn([0xF4, 0x90, 0x80, 0x80], 0);
+  testExn([0xF4, 0x90, 0x80, 0x80], 1);
   testExn([0xF7, 0xBF, 0xBF, 0xBF], 0);
 }
diff --git a/tests/lib_2/html/canvasrendering/draw_image_video_element_test.dart b/tests/lib_2/html/canvasrendering/draw_image_video_element_test.dart
index c6aa721..e2899d7 100644
--- a/tests/lib_2/html/canvasrendering/draw_image_video_element_test.dart
+++ b/tests/lib_2/html/canvasrendering/draw_image_video_element_test.dart
@@ -72,7 +72,6 @@
 Future testWithThreeParams() async {
   setupFunc();
 
-  var playFuture = video.onCanPlay.first;
   video.onError.listen((_) {
     throw ('URL failed to load.');
   });
@@ -86,7 +85,13 @@
     window.console.log('Video is not supported on this system.');
   }
 
-  await playFuture;
+  // Without user interaction, playing the video requires autoplay to be enabled
+  // and autoplay can only be enabled if muted. We loop the video so there is
+  // always an active frame that can be drawn.
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
   context.drawImage(video, 50, 50);
 
   expectPixelFilled(50, 50);
@@ -101,7 +106,6 @@
 Future testWithFiveParams() async {
   setupFunc();
 
-  var playFuture = video.onCanPlay.first;
   video.onError.listen((_) {
     throw ('URL failed to load.');
   });
@@ -117,7 +121,10 @@
     window.console.log('Video is not supported on this system.');
   }
 
-  await playFuture;
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
   context.drawImageToRect(video, new Rectangle(50, 50, 20, 20));
 
   expectPixelFilled(50, 50);
@@ -134,7 +141,6 @@
 Future testWithNineParams() async {
   setupFunc();
 
-  var playFuture = video.onCanPlay.first;
   video.onError.listen((_) {
     throw ('URL failed to load.');
   });
@@ -150,7 +156,10 @@
     window.console.log('Video is not supported on this system.');
   }
 
-  await playFuture;
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
   context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
       sourceRect: new Rectangle(2, 2, 6, 6));
 
@@ -171,7 +180,6 @@
   video = new VideoElement();
   canvas = new CanvasElement();
 
-  var playFuture = video.onCanPlay.first;
   video.onError.listen((_) {
     throw ('URL failed to load.');
   });
@@ -187,7 +195,10 @@
     window.console.log('Video is not supported on this system.');
   }
 
-  await playFuture;
+  video.loop = true;
+  video.muted = true;
+  video.autoplay = true;
+  await video.play();
   context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
       sourceRect: new Rectangle(2, 2, 6, 6));
 
diff --git a/tests/lib_2/html/element_classes_svg_test.dart b/tests/lib_2/html/element_classes_svg_test.dart
index 23a6de0..3beb9d7 100644
--- a/tests/lib_2/html/element_classes_svg_test.dart
+++ b/tests/lib_2/html/element_classes_svg_test.dart
@@ -139,7 +139,7 @@
   test('listAdd', () {
     var elements = elementsSetup();
     var added = elements.classes.add('lassie');
-    expect(added, isNull);
+    expect(added, isFalse);
 
     expect(view(elements.classes), '[classy, foo, lassie, quux, qux, yes]');
     expect(
diff --git a/tests/lib_2/html/js_typed_interop_default_arg_static_test.dart b/tests/lib_2/html/js_typed_interop_default_arg_static_test.dart
new file mode 100644
index 0000000..25adc67
--- /dev/null
+++ b/tests/lib_2/html/js_typed_interop_default_arg_static_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  var Foo = {
+    get42: function(b) { return arguments.length >= 1 ? b : 42; }
+  };
+""");
+}
+
+@JS()
+class Foo {
+  external static num get42([num b = 3
+      // TODO(41375): This should be a static error. It's invalid to have a
+      // default value.
+      ]);
+}
+
+main() {
+  _injectJs();
+
+  test('call tearoff from dart with default', () {
+    var f = Foo.get42;
+    // Note: today both SSA and CPS remove the extra argument on static calls,
+    // but they fail to do so on tearoffs.
+    expect(f(), 3);
+    // TODO(41375): Remove this once the above is resolved. This is temporary
+    // to track this test failure.
+    throw ("This test should not execute. It should fail to compile above.");
+  });
+}
diff --git a/tests/lib_2/html/js_typed_interop_default_arg_test.dart b/tests/lib_2/html/js_typed_interop_default_arg_test.dart
index 5d47a50..b37df7d 100644
--- a/tests/lib_2/html/js_typed_interop_default_arg_test.dart
+++ b/tests/lib_2/html/js_typed_interop_default_arg_test.dart
@@ -15,19 +15,14 @@
     ..type = 'text/javascript'
     ..innerHtml = r"""
   var Foo = {
-    get42: function(b) { return arguments.length >= 1 ? b : 42; },
-    get43: function(b) { return arguments.length >= 1 ? b : 43; }
+    get42: function(b) { return arguments.length >= 1 ? b : 42; }
   };
 """);
 }
 
 @JS()
 class Foo {
-  // Note: it's invalid to provide a default value.
-  external static num get42([num b
-      = 3 // //# default_value: compile-time error
-      ]);
-  external static num get43([num b]);
+  external static num get42([num b]);
 }
 
 main() {
@@ -40,16 +35,11 @@
 
   test('call tearoff from dart with arg', () {
     var f = Foo.get42;
-    expect(f(2), 2); //# explicit_argument: ok
+    expect(f(2), 2);
   });
 
-  test('call tearoff from dart with default', () {
+  test('call tearoff from dart with no arg', () {
     var f = Foo.get42;
-    // Note: today both SSA and CPS remove the extra argument on static calls,
-    // but they fail to do so on tearoffs.
-    expect(f(), 3); //# default_value: continued
-
-    f = Foo.get43;
-    expect(f(), 43);
+    expect(f(), 42);
   });
 }
diff --git a/tests/lib_2/html/js_typed_interop_type1_test.dart b/tests/lib_2/html/js_typed_interop_type1_test.dart
index e10aea3..ca82833 100644
--- a/tests/lib_2/html/js_typed_interop_type1_test.dart
+++ b/tests/lib_2/html/js_typed_interop_type1_test.dart
@@ -45,5 +45,5 @@
   var f = new F(6);
 
   Expect.equals(testA(a), 1);
-  Expect.equals(testF(f), 6); //# 01: ok
+  Expect.equals(testF(f), 6);
 }
diff --git a/tests/lib_2/html/js_typed_interop_type2_test.dart b/tests/lib_2/html/js_typed_interop_type2_test.dart
index aa6f3bf..b9558bb 100644
--- a/tests/lib_2/html/js_typed_interop_type2_test.dart
+++ b/tests/lib_2/html/js_typed_interop_type2_test.dart
@@ -41,5 +41,5 @@
   dynamic d = new D(foo: 4);
   var f = new F(6);
   Expect.equals(testC(d), 4);
-  Expect.equals(testF(f), 6); //# 01: ok
+  Expect.equals(testF(f), 6);
 }
diff --git a/tests/lib_2/html/js_util_test.dart b/tests/lib_2/html/js_util_test.dart
index 0166e9c..d32df10 100644
--- a/tests/lib_2/html/js_util_test.dart
+++ b/tests/lib_2/html/js_util_test.dart
@@ -360,12 +360,12 @@
     });
   });
 
-  void testResolvedPromise() async {
+  Future<void> testResolvedPromise() async {
     final String result = await js_util.promiseToFuture(resolvedPromise);
     expect(result, equals('resolved'));
   }
 
-  void testRejectedPromise() async {
+  Future<void> testRejectedPromise() async {
     try {
       final String result = await promiseToFuture(rejectedPromise);
       fail('expected Future to throw an error');
@@ -374,7 +374,7 @@
     }
   }
 
-  void testReturnRejectedPromise() async {
+  Future<void> testReturnRejectedPromise() async {
     final String result = await promiseToFuture(getResolvedPromise());
     expect(result, equals('resolved'));
   }
diff --git a/tests/lib_2/isolate/message3_test.dart b/tests/lib_2/isolate/message3_test.dart
index aa3166c..6536b36 100644
--- a/tests/lib_2/isolate/message3_test.dart
+++ b/tests/lib_2/isolate/message3_test.dart
@@ -60,7 +60,11 @@
 }
 
 class E {
+  // Make sure E.fun is not removed by the tree shaker, as this test verifies
+  // that an object with a tear-off in E.fun cannot be sent.
+  @pragma("vm:entry-point")
   Function fun;
+
   E(this.fun);
 
   static fooFun() => 499;
diff --git a/tests/lib_2/isolate/package_config_getter_test.dart b/tests/lib_2/isolate/package_config_getter_test.dart
new file mode 100644
index 0000000..0b7d506
--- /dev/null
+++ b/tests/lib_2/isolate/package_config_getter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+import 'spawn_uri__package_uri__test.dart';
+
+final executable = Platform.executable;
+
+main() async {
+  // Make a folder structure that has both ".dart_tool/package_config.json" and
+  // ".packages" and ensure VM prefers to use ".packages".
+  await withTempDir((String tempDir) async {
+    // Setup ".packages" with "foo -> ..." mapping.
+    final dotPackagesPath = path.join(tempDir, '.packages');
+    final dotPackagesFile = File(dotPackagesPath);
+    await dotPackagesFile.writeAsString(buildDotPackages('foo'));
+
+    // Setup bogus ".dart_tool/package_config.json" with "invalid -> ..."
+    // mapping.
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonPath =
+        path.join(dotDartToolDir, 'package_config.json');
+    final packageConfigJsonFile = File(packageConfigJsonPath);
+    await packageConfigJsonFile
+        .writeAsString(buildPackageConfig('invalid', true));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    await File(mainFile).writeAsString('''
+import 'dart:io' as io;
+import 'dart:isolate';
+
+main() async {
+  final uri = await Isolate.packageConfig;
+  final expectedUri = Uri.parse('${dotPackagesFile.uri}');
+  if (uri != expectedUri) {
+    throw 'VM should use .packages file (but used \$uri).';
+  }
+}
+''');
+
+    await run(executable, [mainFile]);
+  });
+}
diff --git a/tests/lib_2/isolate/package_config_test.dart b/tests/lib_2/isolate/package_config_test.dart
index 3039f3e..c9b4f02 100644
--- a/tests/lib_2/isolate/package_config_test.dart
+++ b/tests/lib_2/isolate/package_config_test.dart
@@ -8,33 +8,26 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_CONFIG = "foobar:///no/such/file/";
+const String packageConfig = "foobar:///no/such/file/";
+const String errorString = "IsolateSpawnException: Unable to spawn isolate:";
+const String errorString2 = "Error when reading '$packageConfig'";
 
-main([args, port]) async {
-  if (port != null) {
-    testPackageConfig(port);
-    return;
+main([args, msg]) async {
+  if (msg != null) {
+    throw 'unreachable';
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageConfig: Uri.parse(SPAWN_PACKAGE_CONFIG));
-  p.handler = (msg) {
-    p.close();
-    if (msg[0] != SPAWN_PACKAGE_CONFIG) {
-      throw "Bad package config in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Non-null loaded package config in isolate: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package config: ${await Isolate.packageConfig}");
-}
-
-testPackageConfig(port) async {
-  var packageConfigStr = Platform.packageConfig;
-  var packageConfig = await Isolate.packageConfig;
-  print("Spawned isolate's package config flag: $packageConfigStr");
-  print("Spawned isolate's loaded package config: $packageConfig");
-  port.send([packageConfigStr, packageConfig?.toString()]);
+  dynamic error;
+  try {
+    await Isolate.spawnUri(Platform.script, [], 'msg',
+        packageConfig: Uri.parse('foobar:///no/such/file/'));
+  } catch (e) {
+    error = e;
+  }
+  if (error == null) throw 'Expected a Spawning error.';
+  if (!'$error'.contains(errorString)) {
+    throw 'Epected: $errorString to contain "$errorString"';
+  }
+  if (!'$error'.contains(errorString2)) {
+    throw 'Epected: $errorString to contain "$errorString2"';
+  }
 }
diff --git a/tests/lib_2/isolate/package_resolve_test.dart b/tests/lib_2/isolate/package_resolve_test.dart
index 4379b4c..50686a3 100644
--- a/tests/lib_2/isolate/package_resolve_test.dart
+++ b/tests/lib_2/isolate/package_resolve_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -8,44 +8,67 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_ROOT = "file:///no/such/package/root/";
-final PACKAGE_URI = "package:foo/bar.dart";
-final PACKAGE_PATH = "file:///no/such/package/root/foo/bar.dart";
+final packageUriToResolve = "package:foo/bar.dart";
+final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
+
+final dotPackages = """
+# This is the content of a .packages file.
+foo:file:///no/such/directory/lib/
+""";
+
+final packageConfigJson = """
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///no/such/directory",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    }
+  ]
+}
+""";
 
 main([args, port]) async {
   if (port != null) {
     testPackageResolution(port);
     return;
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
-  p.handler = (msg) {
-    p.close();
-    if (msg is! List) {
-      print(msg.runtimeType);
-      throw "Failure return from spawned isolate:\n\n$msg";
-    }
-    if (msg[0] != null) {
-      throw "Bad package root in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Package path not matching: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+  await runTest(dotPackages);
+  await runTest(packageConfigJson);
+}
+
+Future runTest(String packageConfig) async {
+  final data = Uri.dataFromString(packageConfig);
+  final port = ReceivePort();
+  await Isolate.spawnUri(Platform.script, [], port.sendPort,
+      packageConfig: data);
+  final msg = await port.first;
+  if (msg is! List) {
+    print(msg.runtimeType);
+    throw "Failure return from spawned isolate:\n\n$msg";
+  }
+  if (msg[0] != data.toString()) {
+    throw "Bad package config in child isolate: ${msg[0]}\n"
+        "Expected: $data";
+  }
+  if (msg[1] != packageResolvedUri) {
+    throw "Package path not matching: ${msg[1]}";
+  }
+  print("SUCCESS");
 }
 
 testPackageResolution(port) async {
   try {
-    var packageRootStr = Platform.packageRoot;
-    var packageRoot = await Isolate.packageRoot;
-    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
-    print("Spawned isolate's package root flag: $packageRootStr");
-    print("Spawned isolate's loaded package root: $packageRoot");
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg =
+        await Isolate.resolvePackageUri(Uri.parse(packageUriToResolve));
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
     print("Spawned isolate's resolved package path: $resolvedPkg");
-    port.send([packageRoot?.toString(), resolvedPkg?.toString()]);
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
   } catch (e, s) {
     port.send("$e\n$s\n");
   }
diff --git a/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart b/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
index ddb77c4..50686a3 100644
--- a/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
+++ b/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
@@ -2,15 +2,32 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=--enable-isolate-groups
+// VMOptions=--no-enable-isolate-groups
+
 import 'dart:io';
 import 'dart:isolate';
 
-final PACKAGE_URI = "package:foo/bar.dart";
-final PACKAGE_PATH = "file:///no/such/directory/bar.dart";
+final packageUriToResolve = "package:foo/bar.dart";
+final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
 
-final PACKAGE_SPEC = """
+final dotPackages = """
 # This is the content of a .packages file.
-foo:file:///no/such/directory/
+foo:file:///no/such/directory/lib/
+""";
+
+final packageConfigJson = """
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///no/such/directory",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    }
+  ]
+}
 """;
 
 main([args, port]) async {
@@ -18,34 +35,36 @@
     testPackageResolution(port);
     return;
   }
-  var data = new Uri.dataFromString(PACKAGE_SPEC);
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort, packageConfig: data);
-  p.handler = (msg) {
-    p.close();
-    if (msg is! List) {
-      print(msg.runtimeType);
-      throw "Failure return from spawned isolate:\n\n$msg";
-    }
-    if (msg[0] != data.toString()) {
-      throw "Bad package config in child isolate: ${msg[0]}\n"
-          "Expected: $data";
-    }
-    if (msg[1] != PACKAGE_PATH) {
-      throw "Package path not matching: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+  await runTest(dotPackages);
+  await runTest(packageConfigJson);
+}
+
+Future runTest(String packageConfig) async {
+  final data = Uri.dataFromString(packageConfig);
+  final port = ReceivePort();
+  await Isolate.spawnUri(Platform.script, [], port.sendPort,
+      packageConfig: data);
+  final msg = await port.first;
+  if (msg is! List) {
+    print(msg.runtimeType);
+    throw "Failure return from spawned isolate:\n\n$msg";
+  }
+  if (msg[0] != data.toString()) {
+    throw "Bad package config in child isolate: ${msg[0]}\n"
+        "Expected: $data";
+  }
+  if (msg[1] != packageResolvedUri) {
+    throw "Package path not matching: ${msg[1]}";
+  }
+  print("SUCCESS");
 }
 
 testPackageResolution(port) async {
   try {
-    var packageRootStr = Platform.packageRoot;
     var packageConfigStr = Platform.packageConfig;
     var packageConfig = await Isolate.packageConfig;
-    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
-    print("Spawned isolate's package root flag: $packageRootStr");
+    var resolvedPkg =
+        await Isolate.resolvePackageUri(Uri.parse(packageUriToResolve));
     print("Spawned isolate's package config flag: $packageConfigStr");
     print("Spawned isolate's loaded package config: $packageConfig");
     print("Spawned isolate's resolved package path: $resolvedPkg");
diff --git a/tests/lib_2/isolate/spawn_uri__package_uri__test.dart b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
new file mode 100644
index 0000000..61837fc
--- /dev/null
+++ b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+final executable = Platform.executable;
+
+main() async {
+  // Run the Dart VM with or without:
+  //     --packages=<packages|package_config>
+  for (final runWithPackagesArg in const [true, false]) {
+    // Run the isolate with or without
+    //    Isolate.spawnUri(..., packageConfig: <packages|package_config>)
+    print('TEST runWithPackagesArg = $runWithPackagesArg ');
+    for (final spawnWithPackageConfig in const [true, false]) {
+      print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
+      final bool checkForResolveUri =
+          runWithPackagesArg || !spawnWithPackageConfig;
+      await runDotPackagesTest(
+          runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri);
+      for (final optionalPackageUri in const [true, false]) {
+        print('TEST optionalPackageUri = $optionalPackageUri');
+        await runPackageConfigTest(runWithPackagesArg, spawnWithPackageConfig,
+            optionalPackageUri, checkForResolveUri);
+      }
+    }
+  }
+}
+
+Future runPackageConfigTest(bool withPackagesArg, bool spawnWithArg,
+    bool optionalPackageUri, bool checkForResolveUri) async {
+  await withApplicationDirAndDotDartToolPackageConfig(
+      (String tempDir, String packageJson, String mainFile) async {
+    final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
+    await run(executable, args);
+  }, spawnWithArg, optionalPackageUri, checkForResolveUri);
+}
+
+Future runDotPackagesTest(
+    bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
+  await withApplicationDirAndDotPackages(
+      (String tempDir, String dotPackagesFile, String mainFile) async {
+    final args = [
+      if (withPackagesArg) '--packages=$dotPackagesFile',
+      mainFile,
+    ];
+    await run(executable, args);
+  }, spawnWithArg, checkForResolveUri);
+}
+
+Future withApplicationDirAndDotPackages(
+    Future fn(String tempDir, String packagesDir, String mainFile),
+    bool spawnWithArg,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".packages"
+    final dotPackagesFile =
+        path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
+    await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? dotPackagesFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, dotPackagesFile, mainFile);
+  });
+}
+
+Future withApplicationDirAndDotDartToolPackageConfig(
+    Future fn(String tempDir, String packageJson, String mainFile),
+    bool spawnWithArg,
+    bool optionalPackageUri,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".dart_tool/package_config.json"
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonFile = path.join(
+        dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
+    await File(packageConfigJsonFile)
+        .writeAsString(buildPackageConfig('foo', optionalPackageUri));
+
+    // Setup actual application
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? packageConfigJsonFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, packageConfigJsonFile, mainFile);
+  });
+}
+
+Future withTempDir(Future fn(String dir)) async {
+  final dir = await Directory.systemTemp.createTemp('spawn_uri');
+  try {
+    await fn(dir.absolute.path);
+  } finally {
+    await dir.delete(recursive: true);
+  }
+}
+
+Future<ProcessResult> run(String executable, List<String> args,
+    {String cwd}) async {
+  print('Running $executable ${args.join(' ')}');
+  final String workingDirectory = cwd ?? Directory.current.absolute.path;
+  final result = await Process.run(executable, ['--trace-loading', ...args],
+      workingDirectory: workingDirectory);
+  print('exitCode:\n${result.exitCode}');
+  print('stdout:\n${result.stdout}');
+  print('stdout:\n${result.stderr}');
+  Expect.equals(0, result.exitCode);
+  return result;
+}
+
+String buildDotPackages(String packageName) => '$packageName:.';
+
+String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "$packageName",
+      "rootUri": "../"
+      ${optionalPackageUri ? ', "packageUri": "./"' : ''}
+    }
+  ]
+}
+''';
+
+String buildChildIsolate() => '''
+  import 'dart:isolate';
+
+  main(List<String> args, SendPort message) {
+    message.send('child isolate is done');
+  }
+''';
+
+String buildMainIsolate(
+        String spawnUri, String packageConfigUri, String childIsolatePath) =>
+    '''
+  import 'dart:isolate';
+  import 'dart:io' as io;
+
+  main(List<String> args) async {
+    io.exitCode = 1;
+
+    final uri = Uri.parse('$spawnUri');
+    final resolvedUri = await Isolate.resolvePackageUri(uri);
+    if ("""\${resolvedUri?.toFilePath()}""" != r"""$childIsolatePath""") {
+      throw 'Could not Isolate.resolvePackageUri(uri).';
+    }
+
+    final rp = ReceivePort();
+    final isolateArgs = <String>['a'];
+    await Isolate.spawnUri(
+        uri,
+        isolateArgs,
+        rp.sendPort,
+        packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
+    final childIsolateMessage = await rp.first;
+    if (childIsolateMessage != 'child isolate is done') {
+      throw 'Did not receive correct message from child isolate.';
+    }
+
+    // Test was successful.
+    io.exitCode = 0;
+  }
+''';
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 432516a..3365351 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -11,6 +11,9 @@
 developer/timeline_test: Skip # Not supported
 isolate/issue_24243_parent_isolate_test: Skip # Requires checked mode
 
+[ $runtime == dart_precompiled ]
+isolate/package_config_getter_test: SkipByDesign # AOT mode doesn't preserve package structure.
+
 [ $runtime == ff ]
 convert/streamed_conversion_utf8_decode_test: Slow, Pass # Issue 12029
 mirrors/mirrors_reader_test: Slow, Pass # Issue 16589
@@ -24,6 +27,9 @@
 html/indexeddb_3_test: Skip # Times out 1 out of 10.
 html/worker_api_test: Skip # Issue 13221
 
+[ $runtime != vm ]
+isolate/spawn_uri__package_uri__test: SkipByDesign # This test uses Isolate.spawnUri and only works in JIT mode.
+
 [ $system == windows ]
 html/xhr_test/xhr: Skip # Times out.  Issue 21527
 
@@ -49,13 +55,6 @@
 [ $arch != x64 || $compiler == dartkb || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
 
-[ $compiler != none || $runtime != vm ]
-isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
-isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
-isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
-isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
-isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
-
 [ $mode == product || $runtime != vm ]
 isolate/checked_test: Skip # Unsupported.
 
@@ -91,8 +90,12 @@
 isolate/mint_maker_test: Skip # Isolate.spawnUri
 isolate/nested_spawn2_test: Skip # Isolate.spawnUri
 isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/package_config_test: Skip # Isolate.spawnUri
 isolate/raw_port_test: Skip # Isolate.spawnUri
 isolate/request_reply_test: Skip # Isolate.spawnUri
+isolate/scenarios/automatic_resolution_spec/package_resolve_test: Skip # Isolate.spawnUri
+isolate/scenarios/package_relative_spec/package_relative_spec_test: Skip # Isolate.spawnUri
+isolate/scenarios/short_package/short_package_test: Skip # Isolate.spawnUri
 isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
 isolate/spawn_function_test: Skip # Isolate.spawnUri
 isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
@@ -106,6 +109,13 @@
 isolate/static_function_test: Skip # Isolate.spawnUri
 isolate/unresolved_ports_test: Skip # Isolate.spawnUri
 
+[ $runtime != vm || $compiler != dartk && $compiler != none ]
+isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
+isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
+isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
+isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
+isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
+
 [ $hot_reload || $hot_reload_rollback ]
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/utf85_test: SkipSlow
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 78b9986..65cb43c 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -124,6 +124,9 @@
 isolate/non_fatal_exception_in_timer_callback_test/sleep: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/object_leak_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ondone_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_config_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_root_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/pause_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ping_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/port_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
@@ -132,12 +135,15 @@
 isolate/regress_flutter_22796_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/request_reply_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/resolve_package_uri_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/scenarios/package_data_uri_spec/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/send_private_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/simple_message_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_custom_class_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_generic_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri__package_uri__test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_exported_main_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri_fail_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_from_isolate_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_multi_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tests/modular/subclass/f1.dart b/tests/modular/subclass/f1.dart
index 00f7709..2f8ed7a 100644
--- a/tests/modular/subclass/f1.dart
+++ b/tests/modular/subclass/f1.dart
@@ -1,10 +1,11 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 import 'f0.dart';
 
 class B1 extends A0 {
-  A0 get foo => null;
+  A0 get foo => A0();
 }
 
 A0 createA0() => new A0();
diff --git a/tests/standalone/array_bounds_check_generalization_test.dart b/tests/standalone/array_bounds_check_generalization_test.dart
index 96b5946..537b0b2 100644
--- a/tests/standalone/array_bounds_check_generalization_test.dart
+++ b/tests/standalone/array_bounds_check_generalization_test.dart
@@ -72,7 +72,7 @@
 
 main() {
   var a = const [0, 1, 2, 3, 4, 5, 6, 7];
-  var b = new List(a.length);
+  var b = List.filled(a.length, -1);
   for (var i = 0; i < 10000; i++) {
     Expect.equals(a.last, test1(a, 0, 1, a.length));
     Expect.equals(a.last, test2(a, b));
@@ -84,6 +84,6 @@
 
   test1(a, 0, 2, a.length ~/ 2);
   Expect.throws(() => test1(a, 1, 1, a.length));
-  Expect.throws(() => test2(a, new List(a.length - 1)));
+  Expect.throws(() => test2(a, List.filled(a.length - 1, -1)));
   Expect.throws(() => test6(a, 4, 3));
 }
diff --git a/tests/standalone/io/directory_error_test.dart b/tests/standalone/io/directory_error_test.dart
index 892b0a6..159d827 100644
--- a/tests/standalone/io/directory_error_test.dart
+++ b/tests/standalone/io/directory_error_test.dart
@@ -34,7 +34,7 @@
   Expect.throws(() => inNonExistent.createSync(),
       (e) => checkCreateInNonExistentFileSystemException(e));
 
-  inNonExistent.create().catchError((error) {
+  Future<Directory?>.value(inNonExistent.create()).catchError((error) {
     checkCreateInNonExistentFileSystemException(error);
     done();
   });
@@ -59,7 +59,8 @@
   Expect.throws(() => nonExistent.createTempSync('tempdir'),
       (e) => checkCreateTempInNonExistentFileSystemException(e));
 
-  nonExistent.createTemp('tempdir').catchError((error) {
+  Future<Directory?>.value(nonExistent.createTemp('tempdir'))
+      .catchError((error) {
     checkCreateTempInNonExistentFileSystemException(error);
     done();
   });
@@ -79,7 +80,7 @@
   Expect.throws(() => nonExistent.deleteSync(),
       (e) => checkDeleteNonExistentFileSystemException(e));
 
-  nonExistent.delete().catchError((error) {
+  Future<FileSystemEntity?>.value(nonExistent.delete()).catchError((error) {
     checkDeleteNonExistentFileSystemException(error);
     done();
   });
@@ -100,7 +101,8 @@
   Expect.throws(() => nonExistent.deleteSync(recursive: true),
       (e) => checkDeleteRecursivelyNonExistentFileSystemException(e));
 
-  nonExistent.delete(recursive: true).catchError((error) {
+  Future<FileSystemEntity?>.value(nonExistent.delete(recursive: true))
+      .catchError((error) {
     checkDeleteRecursivelyNonExistentFileSystemException(error);
     done();
   });
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index ddd3760..5c29207 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -196,8 +196,8 @@
           }
         }
 
-        long.delete().catchError(onError);
-        long.delete(recursive: true).catchError(onError);
+        Future<void>.value(long.delete()).catchError(onError);
+        Future<void>.value(long.delete(recursive: true)).catchError(onError);
       });
     });
   }
@@ -453,7 +453,7 @@
 class NestedTempDirectoryTest {
   List<Directory> createdDirectories;
 
-  NestedTempDirectoryTest.run() : createdDirectories = new List<Directory>() {
+  NestedTempDirectoryTest.run() : createdDirectories = <Directory>[] {
     Directory.systemTemp.createTemp('dart_directory').then(createPhaseCallback);
   }
 
@@ -511,7 +511,7 @@
 
   asyncStart();
   var future = new Directory(location).createTemp('dart_tempdir');
-  future.catchError((_) => asyncEnd());
+  Future<Directory?>.value(future).catchError((_) => asyncEnd());
 }
 
 testCreateExistingSync() {
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 7583b71..1ba41eb 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -74,7 +74,7 @@
     File file = new File(filename);
     Expect.isTrue('$file'.contains(file.path));
     var subscription;
-    List<int> buffer = new List<int>();
+    List<int> buffer = <int>[];
     subscription = file.openRead().listen((d) {
       buffer.addAll(d);
       if (buffer.length >= 12) {
@@ -105,7 +105,7 @@
     int bytesRead;
 
     var file1 = new File(inFilename);
-    List<int> buffer = new List<int>();
+    List<int> buffer = <int>[];
     file1.openRead().listen((d) {
       buffer.addAll(d);
     }, onDone: () {
@@ -118,7 +118,7 @@
       output.flush().then((_) => output.close());
       output.done.then((_) {
         // Now read the contents of the file just written.
-        List<int> buffer2 = new List<int>();
+        List<int> buffer2 = <int>[];
         new File(outFilename).openRead().listen((d) {
           buffer2.addAll(d);
         }, onDone: () {
@@ -819,11 +819,11 @@
     }
 
     read(0, 3, 3, [1, 2, 3]);
-    read(0, 2, 2, [1, 2, null]);
-    read(1, 2, 1, [null, 1, null]);
-    read(1, 3, 2, [null, 1, 2]);
-    read(2, 3, 1, [null, null, 1]);
-    read(0, 0, 0, [null, null, null]);
+    read(0, 2, 2, [1, 2, -1]);
+    read(1, 2, 1, [-1, 1, -1]);
+    read(1, 3, 2, [-1, 1, 2]);
+    read(2, 3, 1, [-1, -1, 1]);
+    read(0, 0, 0, [-1, -1, -1]);
 
     openedFile.closeSync();
   }
@@ -1296,7 +1296,7 @@
     int done = 0;
     bool error = false;
     void getLength() {
-      file.length().catchError((e) {
+      Future<int?>.value(file.length()).catchError((e) {
         error = true;
       }).whenComplete(() {
         if (++done == 2) {
@@ -1564,9 +1564,12 @@
         .then((_) => lift(Expect.isFalse)(newfile.exists()))
         .then((_) {
       if (Platform.operatingSystem != "windows") {
-        new Link(source).create(dest).then((_) => file.rename("xxx")).then((_) {
+        Future<File?>.value(new Link(source)
+            .create(dest)
+            .then((_) => file.rename("xxx"))
+            .then((_) {
           throw "Rename of broken link succeeded";
-        }).catchError((e) {
+        })).catchError((e) {
           Expect.isTrue(e is FileSystemException);
           asyncTestDone("testRename$targetExists");
         });
diff --git a/tests/standalone/io/gzip_format_exception_test.dart b/tests/standalone/io/gzip_format_exception_test.dart
new file mode 100644
index 0000000..2b00af7
--- /dev/null
+++ b/tests/standalone/io/gzip_format_exception_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+// This tests whether a FormatException is thrown on bad data.
+main() {
+  Expect.throwsFormatException(() => GZipCodec().decoder.convert([10, 20, 30]));
+}
diff --git a/tests/standalone/io/http_ban_http_embedder_test.dart b/tests/standalone/io/http_ban_http_embedder_test.dart
new file mode 100644
index 0000000..7fd3cb3
--- /dev/null
+++ b/tests/standalone/io/http_ban_http_embedder_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=-Ddart.library.io.allow_http=false
+
+import 'dart:async';
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+
+import 'http_ban_http_normal_test.dart';
+import 'http_bind_test.dart';
+
+Future<void> testWithHostname() async {
+  await testBanHttp(await getLocalHostIP(), (httpClient, httpUri) async {
+    asyncExpectThrows(
+        () async => await httpClient.getUrl(httpUri), (e) => e is StateError);
+    asyncExpectThrows(
+        () async => await runZoned(() => httpClient.getUrl(httpUri),
+            zoneValues: {#dart.library.io.allow_http: 'foo'}),
+        (e) => e is StateError);
+    asyncExpectThrows(
+        () async => await runZoned(() => httpClient.getUrl(httpUri),
+            zoneValues: {#dart.library.io.allow_http: false}),
+        (e) => e is StateError);
+    await asyncTest(() => runZoned(() => httpClient.getUrl(httpUri),
+        zoneValues: {#dart.library.io.allow_http: true}));
+  });
+}
+
+Future<void> testWithLoopback() async {
+  await testBanHttp("127.0.0.1", (httpClient, uri) async {
+    await asyncTest(
+        () => httpClient.getUrl(Uri.parse('http://localhost:${uri.port}')));
+    await asyncTest(
+        () => httpClient.getUrl(Uri.parse('http://127.0.0.1:${uri.port}')));
+  });
+}
+
+Future<void> testWithIPv6() async {
+  if (await supportsIPV6()) {
+    await testBanHttp("::1", (httpClient, uri) async {
+      await asyncTest(() => httpClient.getUrl(uri));
+    });
+  }
+}
+
+Future<void> testWithHTTPS() async {
+  await testBanHttp(await getLocalHostIP(), (httpClient, uri) async {
+    asyncExpectThrows(
+        () => httpClient.getUrl(Uri(
+              scheme: 'https',
+              host: uri.host,
+              port: uri.port,
+            )),
+        (e) => e is SocketException || e is HandshakeException);
+  });
+}
+
+main() {
+  asyncStart();
+  Future.wait(<Future>[
+    testWithHostname(),
+    testWithLoopback(),
+    testWithIPv6(),
+    testWithHTTPS(),
+  ]).then((_) => asyncEnd());
+}
diff --git a/tests/standalone/io/http_ban_http_normal_test.dart b/tests/standalone/io/http_ban_http_normal_test.dart
new file mode 100644
index 0000000..118dd4c
--- /dev/null
+++ b/tests/standalone/io/http_ban_http_normal_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+
+Future<String> getLocalHostIP() async {
+  final interfaces = await NetworkInterface.list(
+      includeLoopback: false, type: InternetAddressType.IPv4);
+  return interfaces.first.addresses.first.address;
+}
+
+Future<void> testBanHttp(String serverHost,
+    Future<void> testCode(HttpClient client, Uri uri)) async {
+  final httpClient = new HttpClient();
+  final server = await HttpServer.bind(serverHost, 0);
+  final uri = Uri(scheme: 'http', host: serverHost, port: server.port);
+  try {
+    await testCode(httpClient, uri);
+  } finally {
+    httpClient.close(force: true);
+    await server.close();
+  }
+}
+
+main() async {
+  await asyncTest(() async {
+    final host = await getLocalHostIP();
+    // Normal HTTP request succeeds.
+    await testBanHttp(host, (httpClient, uri) async {
+      await asyncTest(() => httpClient.getUrl(uri));
+    });
+    // We can ban HTTP explicitly.
+    await testBanHttp(host, (httpClient, uri) async {
+      asyncExpectThrows(
+          () async => await runZoned(() => httpClient.getUrl(uri),
+              zoneValues: {#dart.library.io.allow_http: false}),
+          (e) => e is StateError);
+    });
+  });
+}
diff --git a/tests/standalone/io/http_client_connect_test.dart b/tests/standalone/io/http_client_connect_test.dart
index 284c441d..79351cd 100644
--- a/tests/standalone/io/http_client_connect_test.dart
+++ b/tests/standalone/io/http_client_connect_test.dart
@@ -55,7 +55,9 @@
 void testGetInvalidHost() {
   asyncStart();
   var client = new HttpClient();
-  client.get("__SOMETHING_INVALID__", 8888, "/").catchError((error) {
+  Future<HttpClientRequest?>.value(
+          client.get("__SOMETHING_INVALID__", 8888, "/"))
+      .catchError((error) {
     client.close();
     asyncEnd();
   });
diff --git a/tests/standalone/io/http_client_request_test.dart b/tests/standalone/io/http_client_request_test.dart
index dae2b2a..43fe994 100644
--- a/tests/standalone/io/http_client_request_test.dart
+++ b/tests/standalone/io/http_client_request_test.dart
@@ -47,7 +47,7 @@
     request.contentLength = 0;
     request.add([0]);
     request.close();
-    request.done.catchError((error) {
+    Future<HttpClientResponse?>.value(request.done).catchError((error) {
       asyncEnd();
     }, test: (e) => e is HttpException);
     return request.done;
@@ -59,7 +59,7 @@
     request.add([0, 0, 0]);
     request.add([0, 0, 0]);
     request.close();
-    request.done.catchError((error) {
+    Future<HttpClientResponse?>.value(request.done).catchError((error) {
       asyncEnd();
     }, test: (e) => e is HttpException);
     return request.done;
@@ -72,7 +72,7 @@
     request.add(new Uint8List(64 * 1024));
     request.add(new Uint8List(64 * 1024));
     request.close();
-    request.done.catchError((error) {
+    Future<HttpClientResponse?>.value(request.done).catchError((error) {
       asyncEnd();
     }, test: (e) => e is HttpException);
     return request.done;
@@ -84,7 +84,7 @@
   testClientRequest((request) {
     request.contentLength = 5;
     request.close();
-    request.done.catchError((error) {
+    Future<HttpClientResponse?>.value(request.done).catchError((error) {
       asyncEnd();
     }, test: (e) => e is HttpException);
     return request.done;
@@ -95,7 +95,7 @@
     request.contentLength = 5;
     request.add([0]);
     request.close();
-    request.done.catchError((error) {
+    Future<HttpClientResponse?>.value(request.done).catchError((error) {
       asyncEnd();
     }, test: (e) => e is HttpException);
     return request.done;
diff --git a/tests/standalone/io/http_close_test.dart b/tests/standalone/io/http_close_test.dart
index d07175f..7de6f94 100644
--- a/tests/standalone/io/http_close_test.dart
+++ b/tests/standalone/io/http_close_test.dart
@@ -132,11 +132,12 @@
     });
     var client = HttpClient();
     for (int i = 0; i < connections; i++) {
-      client.post("127.0.0.1", server.port, "/").then((request) {
+      Future<HttpClientResponse?>.value(
+          client.post("127.0.0.1", server.port, "/").then((request) {
         request.contentLength = 110;
         request.write("0123456789");
         return request.close();
-      }).catchError((_) {
+      })).catchError((_) {
         clientErrors++;
       });
     }
diff --git a/tests/standalone/io/http_compression_test.dart b/tests/standalone/io/http_compression_test.dart
index ae5507c..594d5d7 100644
--- a/tests/standalone/io/http_compression_test.dart
+++ b/tests/standalone/io/http_compression_test.dart
@@ -11,8 +11,8 @@
 import 'dart:io';
 import 'dart:typed_data';
 
-void testServerCompress({bool clientAutoUncompress: true}) async {
-  void test(List<int> data) async {
+Future<void> testServerCompress({bool clientAutoUncompress: true}) async {
+  Future<void> test(List<int> data) async {
     final server = await HttpServer.bind("127.0.0.1", 0);
     server.autoCompress = true;
     server.listen((request) {
@@ -45,8 +45,8 @@
   await test(longBuffer);
 }
 
-void testAcceptEncodingHeader() async {
-  void test(String encoding, bool valid) async {
+Future<void> testAcceptEncodingHeader() async {
+  Future<void> test(String encoding, bool valid) async {
     final server = await HttpServer.bind("127.0.0.1", 0);
     server.autoCompress = true;
     server.listen((request) {
@@ -78,7 +78,7 @@
   await test('gzipx;', false);
 }
 
-void testDisableCompressTest() async {
+Future<void> testDisableCompressTest() async {
   final server = await HttpServer.bind("127.0.0.1", 0);
   Expect.equals(false, server.autoCompress);
   server.listen((request) {
diff --git a/tests/standalone/io/http_cookie_date_test.dart b/tests/standalone/io/http_cookie_date_test.dart
index 6b94254..fd5de9a 100644
--- a/tests/standalone/io/http_cookie_date_test.dart
+++ b/tests/standalone/io/http_cookie_date_test.dart
@@ -16,6 +16,7 @@
 import "package:expect/expect.dart";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 33c28a3..8d41dd2 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -17,6 +17,7 @@
 import "package:expect/expect.dart";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index 6951916..4f27fcf 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -17,6 +17,7 @@
 import "package:expect/expect.dart";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index fbdb5ed..58ecb8e 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -274,23 +274,23 @@
   HttpClient client = new HttpClient(context: clientContext);
 
   client.findProxy = (Uri uri) => "";
-  client
-      .getUrl(Uri.parse("http://www.google.com/test"))
+  Future<HttpClientRequest?>.value(
+          client.getUrl(Uri.parse("http://www.google.com/test")))
       .catchError((error) {}, test: (e) => e is HttpException);
 
   client.findProxy = (Uri uri) => "XXX";
-  client
-      .getUrl(Uri.parse("http://www.google.com/test"))
+  Future<HttpClientRequest?>.value(
+          client.getUrl(Uri.parse("http://www.google.com/test")))
       .catchError((error) {}, test: (e) => e is HttpException);
 
   client.findProxy = (Uri uri) => "PROXY www.google.com";
-  client
-      .getUrl(Uri.parse("http://www.google.com/test"))
+  Future<HttpClientRequest?>.value(
+          client.getUrl(Uri.parse("http://www.google.com/test")))
       .catchError((error) {}, test: (e) => e is HttpException);
 
   client.findProxy = (Uri uri) => "PROXY www.google.com:http";
-  client
-      .getUrl(Uri.parse("http://www.google.com/test"))
+  Future<HttpClientRequest?>.value(
+          client.getUrl(Uri.parse("http://www.google.com/test")))
       .catchError((error) {}, test: (e) => e is HttpException);
 }
 
diff --git a/tests/standalone/io/http_read_test.dart b/tests/standalone/io/http_read_test.dart
index 6c6a103..b6f4a7e 100644
--- a/tests/standalone/io/http_read_test.dart
+++ b/tests/standalone/io/http_read_test.dart
@@ -187,7 +187,7 @@
         return request.close();
       }).then((response) {
         Expect.equals(HttpStatus.ok, response.statusCode);
-        List<int> body = new List<int>();
+        List<int> body = <int>[];
         response.listen(body.addAll, onDone: () {
           Expect.equals(data, new String.fromCharCodes(body));
           count++;
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index 9b19d73..c008a34 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -337,9 +337,9 @@
   setupServer().then((server) {
     HttpClient client = new HttpClient();
 
-    client
-        .getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
-        .then((HttpClientRequest request) => request.close())
+    Future<HttpClientResponse?>.value(client
+            .getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
+            .then((HttpClientRequest request) => request.close()))
         .catchError((error) {
       Expect.equals(5, error.redirects.length);
       server.close();
@@ -353,9 +353,9 @@
     HttpClient client = new HttpClient();
 
     int redirectCount = 0;
-    client
-        .getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
-        .then((HttpClientRequest request) => request.close())
+    Future<HttpClientResponse?>.value(client
+            .getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
+            .then((HttpClientRequest request) => request.close()))
         .catchError((error) {
       Expect.equals(2, error.redirects.length);
       server.close();
diff --git a/tests/standalone/io/http_reuse_server_port_test.dart b/tests/standalone/io/http_reuse_server_port_test.dart
index afcaf61..d78e29f 100644
--- a/tests/standalone/io/http_reuse_server_port_test.dart
+++ b/tests/standalone/io/http_reuse_server_port_test.dart
@@ -49,7 +49,7 @@
   asyncStart();
   runServer(0, 10, true).then((int port) {
     // Stress test the port reusing it 10 times.
-    Future.forEach(new List(10), (_) {
+    Future.forEach(List.filled(10, null), (_) {
       return runServer(port, 10, true);
     }).then((_) {
       asyncEnd();
@@ -61,7 +61,7 @@
   asyncStart();
   runServer(0, 10, false).then((int port) {
     // Stress test the port reusing it 10 times.
-    Future.forEach(new List(10), (_) {
+    Future.forEach(List.filled(10, null), (_) {
       return runServer(port, 10, false);
     }).then((_) {
       asyncEnd();
diff --git a/tests/standalone/io/http_server_early_client_close_test.dart b/tests/standalone/io/http_server_early_client_close_test.dart
index 33ab0e1..bc1403a 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -75,7 +75,7 @@
 }
 
 void testEarlyClose1() {
-  List<EarlyCloseTest> tests = new List<EarlyCloseTest>();
+  List<EarlyCloseTest> tests = <EarlyCloseTest>[];
   void add(Object data, [String? exception, bool expectRequest = false]) {
     tests.add(new EarlyCloseTest(data, exception, expectRequest));
   }
diff --git a/tests/standalone/io/http_shutdown_test.dart b/tests/standalone/io/http_shutdown_test.dart
index c04a537..68fcbde 100644
--- a/tests/standalone/io/http_shutdown_test.dart
+++ b/tests/standalone/io/http_shutdown_test.dart
@@ -156,7 +156,7 @@
             // TODO(sgjesse): Make this test work with
             //request.response instead of request.close() return
             //return request.response;
-            request.done.catchError((e) {});
+            Future<HttpClientResponse?>.value(request.done).catchError((e) {});
             return request.close();
           })
           .then((response) {})
diff --git a/tests/standalone/io/internet_address_test.dart b/tests/standalone/io/internet_address_test.dart
index 493957e..d4d6a06 100644
--- a/tests/standalone/io/internet_address_test.dart
+++ b/tests/standalone/io/internet_address_test.dart
@@ -74,6 +74,55 @@
   Expect.throwsArgumentError(() => new InternetAddress("::FFFF::1"));
 }
 
+void testTryParse() {
+  var loopback4 = InternetAddress.tryParse("127.0.0.1")!;
+  Expect.equals(InternetAddressType.IPv4, loopback4.type);
+  Expect.equals("127.0.0.1", loopback4.host);
+  Expect.equals("127.0.0.1", loopback4.address);
+  Expect.isFalse(loopback4.isMulticast);
+
+  var loopback6 = InternetAddress.tryParse("::1")!;
+  Expect.equals(InternetAddressType.IPv6, loopback6.type);
+  Expect.equals("::1", loopback6.host);
+  Expect.equals("::1", loopback6.address);
+  Expect.isFalse(loopback6.isMulticast);
+
+  var ip4 = InternetAddress.tryParse("10.20.30.40")!;
+  Expect.equals(InternetAddressType.IPv4, ip4.type);
+  Expect.equals("10.20.30.40", ip4.host);
+  Expect.equals("10.20.30.40", ip4.address);
+  Expect.isFalse(ip4.isMulticast);
+
+  var ip6 = InternetAddress.tryParse("10:20::30:40")!;
+  Expect.equals(InternetAddressType.IPv6, ip6.type);
+  Expect.equals("10:20::30:40", ip6.host);
+  Expect.equals("10:20::30:40", ip6.address);
+  Expect.isFalse(ip6.isMulticast);
+
+  var multicast4 = InternetAddress.tryParse("224.1.2.3")!;
+  Expect.equals(InternetAddressType.IPv4, multicast4.type);
+  Expect.isTrue(multicast4.isMulticast);
+
+  var multicast6 = InternetAddress.tryParse("FF00::1:2:3")!;
+  Expect.equals(InternetAddressType.IPv6, multicast6.type);
+  Expect.isTrue(multicast6.isMulticast);
+
+  var lowercase = InternetAddress.tryParse("ff00::1:2:3")!;
+  Expect.equals(InternetAddressType.IPv6, lowercase.type);
+  Expect.equals("ff00::1:2:3", lowercase.host);
+  Expect.equals("ff00::1:2:3", lowercase.address);
+
+  Expect.isNull(InternetAddress.tryParse("1.2.3"));
+  Expect.isNull(InternetAddress.tryParse("1.2.3.4.5"));
+  Expect.isNull(InternetAddress.tryParse("192.168.256.0"));
+  Expect.isNull(InternetAddress.tryParse("192.168.999.0"));
+  Expect.isNull(InternetAddress.tryParse("1.-2.3.4"));
+  Expect.isNull(InternetAddress.tryParse(""));
+  Expect.isNull(InternetAddress.tryParse("FFFG::0"));
+  Expect.isNull(InternetAddress.tryParse("FFF@::0"));
+  Expect.isNull(InternetAddress.tryParse("::FFFF::1"));
+}
+
 void testEquality() {
   Expect.equals(
       new InternetAddress("127.0.0.1"), new InternetAddress("127.0.0.1"));
@@ -163,6 +212,7 @@
 void main() {
   testDefaultAddresses();
   testConstructor();
+  testTryParse();
   testEquality();
   testLookup();
   testReverseLookup();
diff --git a/tests/standalone/io/process_check_arguments_test.dart b/tests/standalone/io/process_check_arguments_test.dart
index f6bfd0b..9922dc1 100644
--- a/tests/standalone/io/process_check_arguments_test.dart
+++ b/tests/standalone/io/process_check_arguments_test.dart
@@ -36,4 +36,5 @@
   test([scriptFile.path, '4', '0', 'a\tb', 'a']);
   test([scriptFile.path, '4', '0', 'a\tb', 'a\t\t\t\tb']);
   test([scriptFile.path, '4', '0', 'a\tb', 'a    b']);
+  test([scriptFile.path, '5', '0', 'a\tb', 'a    b', '']);
 }
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index 87dda6a..a461480 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -528,8 +528,9 @@
         }
 
         try {
-          RawSecureSocket.secureServer(client, serverContext,
-                  subscription: subscription)
+          Future<RawSecureSocket?>.value(RawSecureSocket.secureServer(
+                  client, serverContext,
+                  subscription: subscription))
               .catchError((_) {})
               .whenComplete(() {
             if (pausedServer) {
@@ -556,7 +557,8 @@
           subscription.pause();
         }
         try {
-          RawSecureSocket.secure(socket, subscription: subscription)
+          Future<RawSecureSocket?>.value(
+                  RawSecureSocket.secure(socket, subscription: subscription))
               .catchError((_) {})
               .whenComplete(() {
             if (pausedClient) {
diff --git a/tests/standalone/io/regress_8828_test.dart b/tests/standalone/io/regress_8828_test.dart
index 22225c8..de9891d 100644
--- a/tests/standalone/io/regress_8828_test.dart
+++ b/tests/standalone/io/regress_8828_test.dart
@@ -24,7 +24,7 @@
     client.get("127.0.0.1", server.port, "/").then((HttpClientRequest request) {
       return request.close();
     }).then((HttpClientResponse response) {
-      List<int> body = new List();
+      List<int> body = [];
       response.listen(body.addAll, onDone: () {
         Expect.equals(
             "first line\nsecond line\n", new String.fromCharCodes(body));
diff --git a/tests/standalone/io/socket_cancel_connect_test.dart b/tests/standalone/io/socket_cancel_connect_test.dart
index 7a2e112..a2c0491 100644
--- a/tests/standalone/io/socket_cancel_connect_test.dart
+++ b/tests/standalone/io/socket_cancel_connect_test.dart
@@ -19,6 +19,7 @@
   Socket.startConnect("8.8.8.7", 80).then((task) {
     task.socket.timeout(timeout, onTimeout: () {
       task.cancel();
+      return task.socket;
     });
     task.socket.then((socket) {
       Expect.fail("Unexpected connection made.");
diff --git a/tests/standalone/io/socket_finalizer_test.dart b/tests/standalone/io/socket_finalizer_test.dart
index 5718559..c82be22 100644
--- a/tests/standalone/io/socket_finalizer_test.dart
+++ b/tests/standalone/io/socket_finalizer_test.dart
@@ -48,6 +48,6 @@
 }
 
 @pragma('vm:never-inline')
-produceGarbage() => all.add(List(1024));
+produceGarbage() => all.add(List.filled(1024, null));
 
 final all = [];
diff --git a/tests/standalone/io/socket_invalid_arguments_test.dart b/tests/standalone/io/socket_invalid_arguments_test.dart
index 3e8b889..8e44afd 100644
--- a/tests/standalone/io/socket_invalid_arguments_test.dart
+++ b/tests/standalone/io/socket_invalid_arguments_test.dart
@@ -28,30 +28,6 @@
   }
 }
 
-testAdd(buffer) {
-  asyncStart();
-  asyncStart();
-  ServerSocket.bind("127.0.0.1", 0).then((server) {
-    server.listen((socket) => socket.destroy());
-    Socket.connect("127.0.0.1", server.port).then((socket) {
-      int errors = 0;
-      socket.done.catchError((e) {
-        errors++;
-      }).then((_) {
-        Expect.equals(1, errors);
-        asyncEnd();
-        server.close();
-      });
-      socket.listen((_) {}, onError: (error) {
-        Expect.fail("Error on stream");
-      }, onDone: () {
-        asyncEnd();
-      });
-      socket.add(buffer);
-    });
-  });
-}
-
 testServerSocketCreation(address, port, backlog) {
   asyncStart();
   var server;
@@ -66,16 +42,8 @@
 
 main() {
   asyncStart();
-  testSocketCreation("string", null);
-  testSocketCreation(null, null);
   testSocketCreation("localhost", -1);
   testSocketCreation("localhost", 65536);
-  testAdd(null);
-  // TODO(8233): Throw ArgumentError from API implementation.
-  // testAdd([-1]);
-  // testAdd([2222222222222222222222222222222]);
-  // testAdd([1, 2, 3, null]);
-  // testAdd([new NotAnInteger()]);
   testServerSocketCreation("string", null, null);
   testServerSocketCreation("string", 123, null);
   testServerSocketCreation("localhost", -1, 123);
diff --git a/tests/standalone/io/socket_upgrade_to_secure_test.dart b/tests/standalone/io/socket_upgrade_to_secure_test.dart
index 116de62..4798d14 100644
--- a/tests/standalone/io/socket_upgrade_to_secure_test.dart
+++ b/tests/standalone/io/socket_upgrade_to_secure_test.dart
@@ -102,8 +102,8 @@
     return completer.future;
   }
 
-  Future<RawSocket> runClient(Socket socket) {
-    Completer<RawSocket> completer = new Completer<RawSocket>();
+  Future<RawSocket?> runClient(Socket socket) {
+    Completer<RawSocket?> completer = new Completer<RawSocket?>();
     var dataReceived = <int>[];
     socket.listen((data) {
       dataReceived.addAll(data);
diff --git a/tests/standalone/io/test_extension.dart b/tests/standalone/io/test_extension.dart
index beed87c..4bd7d8f 100644
--- a/tests/standalone/io/test_extension.dart
+++ b/tests/standalone/io/test_extension.dart
@@ -14,7 +14,7 @@
   String toString() => 'cat $x';
 
   // Implements (a != null) ? a : b using a native C++ function and the API.
-  static int ifNull(a, b) native 'TestExtension_IfNull';
+  static int? ifNull(a, b) native 'TestExtension_IfNull';
 
   static int throwMeTheBall(ball) native 'TestExtension_ThrowMeTheBall';
 }
diff --git a/tests/standalone/io/unix_socket_test.dart b/tests/standalone/io/unix_socket_test.dart
index cc6ed79..7c52777 100644
--- a/tests/standalone/io/unix_socket_test.dart
+++ b/tests/standalone/io/unix_socket_test.dart
@@ -74,7 +74,7 @@
   var socket = await Socket.connect(address, server.port);
   socket.write(" socket content");
 
-  await socket.destroy();
+  socket.destroy();
   await server.close();
 }
 
@@ -138,7 +138,7 @@
 }
 
 // Create socket in temp directory
-Future withTempDir(String prefix, void test(Directory dir)) async {
+Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
   var tempDir = Directory.systemTemp.createTempSync(prefix);
   try {
     await test(tempDir);
diff --git a/tests/standalone/io/web_socket_protocol_processor_test.dart b/tests/standalone/io/web_socket_protocol_processor_test.dart
index fc50c61..f7460e2 100644
--- a/tests/standalone/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone/io/web_socket_protocol_processor_test.dart
@@ -18,6 +18,7 @@
 import "dart:isolate";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 45b94e8..9b0e789 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -289,7 +289,7 @@
         request.response.close();
       });
 
-      createClient(server.port).catchError((error) {
+      Future<WebSocket?>.value(createClient(server.port)).catchError((error) {
         server.close();
       });
     });
diff --git a/tests/standalone/io/web_socket_typed_data_test.dart b/tests/standalone/io/web_socket_typed_data_test.dart
index 595ca60..c05cdb7 100644
--- a/tests/standalone/io/web_socket_typed_data_test.dart
+++ b/tests/standalone/io/web_socket_typed_data_test.dart
@@ -200,7 +200,7 @@
         webSocket.listen((message) => Expect.fail("No message expected"),
             onDone: () => completer.complete(true),
             onError: (e) => completer.completeError(e));
-        webSocket.add(new List()..add(i));
+        webSocket.add([i]);
       });
       return completer.future;
     }
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index cfbe667..01f6276 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -13,6 +13,8 @@
 
 [ $system == android ]
 entrypoints_verification_test: Skip # Requires shared objects which the test script doesn't "adb push".
+io/http_ban_http_embedder_test: Skip # Requires http server bound to non-loopback; not provided by system.
+io/http_ban_http_normal_test: Skip # Requires http server bound to non-loopback; not provided by system.
 
 [ $arch == ia32 && $builder_tag == optimization_counter_threshold ]
 io/file_lock_test: SkipSlow # Timeout
diff --git a/tests/standalone_2/fragmentation_test.dart b/tests/standalone_2/fragmentation_test.dart
index b083ec1..f24ea09 100644
--- a/tests/standalone_2/fragmentation_test.dart
+++ b/tests/standalone_2/fragmentation_test.dart
@@ -18,6 +18,10 @@
 // VMOptions=--concurrent_mark --concurrent_sweep
 // VMOptions=--concurrent_mark --use_compactor
 // VMOptions=--concurrent_mark --use_compactor --force_evacuation
+// VMOptions=--scavenger_tasks=0
+// VMOptions=--scavenger_tasks=1
+// VMOptions=--scavenger_tasks=2
+// VMOptions=--scavenger_tasks=3
 
 main() {
   final List<List> arrays = [];
diff --git a/tests/standalone_2/io/gzip_format_exception_test.dart b/tests/standalone_2/io/gzip_format_exception_test.dart
new file mode 100644
index 0000000..2b00af7
--- /dev/null
+++ b/tests/standalone_2/io/gzip_format_exception_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+// This tests whether a FormatException is thrown on bad data.
+main() {
+  Expect.throwsFormatException(() => GZipCodec().decoder.convert([10, 20, 30]));
+}
diff --git a/tests/standalone_2/io/http_ban_http_embedder_test.dart b/tests/standalone_2/io/http_ban_http_embedder_test.dart
new file mode 100644
index 0000000..7fd3cb3
--- /dev/null
+++ b/tests/standalone_2/io/http_ban_http_embedder_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=-Ddart.library.io.allow_http=false
+
+import 'dart:async';
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+
+import 'http_ban_http_normal_test.dart';
+import 'http_bind_test.dart';
+
+Future<void> testWithHostname() async {
+  await testBanHttp(await getLocalHostIP(), (httpClient, httpUri) async {
+    asyncExpectThrows(
+        () async => await httpClient.getUrl(httpUri), (e) => e is StateError);
+    asyncExpectThrows(
+        () async => await runZoned(() => httpClient.getUrl(httpUri),
+            zoneValues: {#dart.library.io.allow_http: 'foo'}),
+        (e) => e is StateError);
+    asyncExpectThrows(
+        () async => await runZoned(() => httpClient.getUrl(httpUri),
+            zoneValues: {#dart.library.io.allow_http: false}),
+        (e) => e is StateError);
+    await asyncTest(() => runZoned(() => httpClient.getUrl(httpUri),
+        zoneValues: {#dart.library.io.allow_http: true}));
+  });
+}
+
+Future<void> testWithLoopback() async {
+  await testBanHttp("127.0.0.1", (httpClient, uri) async {
+    await asyncTest(
+        () => httpClient.getUrl(Uri.parse('http://localhost:${uri.port}')));
+    await asyncTest(
+        () => httpClient.getUrl(Uri.parse('http://127.0.0.1:${uri.port}')));
+  });
+}
+
+Future<void> testWithIPv6() async {
+  if (await supportsIPV6()) {
+    await testBanHttp("::1", (httpClient, uri) async {
+      await asyncTest(() => httpClient.getUrl(uri));
+    });
+  }
+}
+
+Future<void> testWithHTTPS() async {
+  await testBanHttp(await getLocalHostIP(), (httpClient, uri) async {
+    asyncExpectThrows(
+        () => httpClient.getUrl(Uri(
+              scheme: 'https',
+              host: uri.host,
+              port: uri.port,
+            )),
+        (e) => e is SocketException || e is HandshakeException);
+  });
+}
+
+main() {
+  asyncStart();
+  Future.wait(<Future>[
+    testWithHostname(),
+    testWithLoopback(),
+    testWithIPv6(),
+    testWithHTTPS(),
+  ]).then((_) => asyncEnd());
+}
diff --git a/tests/standalone_2/io/http_ban_http_normal_test.dart b/tests/standalone_2/io/http_ban_http_normal_test.dart
new file mode 100644
index 0000000..118dd4c
--- /dev/null
+++ b/tests/standalone_2/io/http_ban_http_normal_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+
+Future<String> getLocalHostIP() async {
+  final interfaces = await NetworkInterface.list(
+      includeLoopback: false, type: InternetAddressType.IPv4);
+  return interfaces.first.addresses.first.address;
+}
+
+Future<void> testBanHttp(String serverHost,
+    Future<void> testCode(HttpClient client, Uri uri)) async {
+  final httpClient = new HttpClient();
+  final server = await HttpServer.bind(serverHost, 0);
+  final uri = Uri(scheme: 'http', host: serverHost, port: server.port);
+  try {
+    await testCode(httpClient, uri);
+  } finally {
+    httpClient.close(force: true);
+    await server.close();
+  }
+}
+
+main() async {
+  await asyncTest(() async {
+    final host = await getLocalHostIP();
+    // Normal HTTP request succeeds.
+    await testBanHttp(host, (httpClient, uri) async {
+      await asyncTest(() => httpClient.getUrl(uri));
+    });
+    // We can ban HTTP explicitly.
+    await testBanHttp(host, (httpClient, uri) async {
+      asyncExpectThrows(
+          () async => await runZoned(() => httpClient.getUrl(uri),
+              zoneValues: {#dart.library.io.allow_http: false}),
+          (e) => e is StateError);
+    });
+  });
+}
diff --git a/tests/standalone_2/io/http_compression_test.dart b/tests/standalone_2/io/http_compression_test.dart
index 2e0b45f..ca9f2cf 100644
--- a/tests/standalone_2/io/http_compression_test.dart
+++ b/tests/standalone_2/io/http_compression_test.dart
@@ -11,8 +11,8 @@
 import 'dart:io';
 import 'dart:typed_data';
 
-void testServerCompress({bool clientAutoUncompress: true}) async {
-  void test(List<int> data) async {
+Future<void> testServerCompress({bool clientAutoUncompress: true}) async {
+  Future<void> test(List<int> data) async {
     final server = await HttpServer.bind("127.0.0.1", 0);
     server.autoCompress = true;
     server.listen((request) {
@@ -44,8 +44,8 @@
   await test(longBuffer);
 }
 
-void testAcceptEncodingHeader() async {
-  void test(String encoding, bool valid) async {
+Future<void> testAcceptEncodingHeader() async {
+  Future<void> test(String encoding, bool valid) async {
     final server = await HttpServer.bind("127.0.0.1", 0);
     server.autoCompress = true;
     server.listen((request) {
@@ -77,7 +77,7 @@
   await test('gzipx;', false);
 }
 
-void testDisableCompressTest() async {
+Future<void> testDisableCompressTest() async {
   final server = await HttpServer.bind("127.0.0.1", 0);
   Expect.equals(false, server.autoCompress);
   server.listen((request) {
diff --git a/tests/standalone_2/io/http_cookie_date_test.dart b/tests/standalone_2/io/http_cookie_date_test.dart
index 6b94254..fd5de9a 100644
--- a/tests/standalone_2/io/http_cookie_date_test.dart
+++ b/tests/standalone_2/io/http_cookie_date_test.dart
@@ -16,6 +16,7 @@
 import "package:expect/expect.dart";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone_2/io/http_headers_test.dart b/tests/standalone_2/io/http_headers_test.dart
index 6e99646..1f8e7e5 100644
--- a/tests/standalone_2/io/http_headers_test.dart
+++ b/tests/standalone_2/io/http_headers_test.dart
@@ -17,6 +17,7 @@
 import "package:expect/expect.dart";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone_2/io/http_parser_test.dart b/tests/standalone_2/io/http_parser_test.dart
index 6951916..4f27fcf 100644
--- a/tests/standalone_2/io/http_parser_test.dart
+++ b/tests/standalone_2/io/http_parser_test.dart
@@ -17,6 +17,7 @@
 import "package:expect/expect.dart";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone_2/io/internet_address_test.dart b/tests/standalone_2/io/internet_address_test.dart
index d35e91c..6d2dd54 100644
--- a/tests/standalone_2/io/internet_address_test.dart
+++ b/tests/standalone_2/io/internet_address_test.dart
@@ -74,6 +74,55 @@
   Expect.throwsArgumentError(() => new InternetAddress("::FFFF::1"));
 }
 
+void testTryParse() {
+  var loopback4 = InternetAddress.tryParse("127.0.0.1");
+  Expect.equals(InternetAddressType.IPv4, loopback4.type);
+  Expect.equals("127.0.0.1", loopback4.host);
+  Expect.equals("127.0.0.1", loopback4.address);
+  Expect.isFalse(loopback4.isMulticast);
+
+  var loopback6 = InternetAddress.tryParse("::1");
+  Expect.equals(InternetAddressType.IPv6, loopback6.type);
+  Expect.equals("::1", loopback6.host);
+  Expect.equals("::1", loopback6.address);
+  Expect.isFalse(loopback6.isMulticast);
+
+  var ip4 = InternetAddress.tryParse("10.20.30.40");
+  Expect.equals(InternetAddressType.IPv4, ip4.type);
+  Expect.equals("10.20.30.40", ip4.host);
+  Expect.equals("10.20.30.40", ip4.address);
+  Expect.isFalse(ip4.isMulticast);
+
+  var ip6 = InternetAddress.tryParse("10:20::30:40");
+  Expect.equals(InternetAddressType.IPv6, ip6.type);
+  Expect.equals("10:20::30:40", ip6.host);
+  Expect.equals("10:20::30:40", ip6.address);
+  Expect.isFalse(ip6.isMulticast);
+
+  var multicast4 = InternetAddress.tryParse("224.1.2.3");
+  Expect.equals(InternetAddressType.IPv4, multicast4.type);
+  Expect.isTrue(multicast4.isMulticast);
+
+  var multicast6 = InternetAddress.tryParse("FF00::1:2:3");
+  Expect.equals(InternetAddressType.IPv6, multicast6.type);
+  Expect.isTrue(multicast6.isMulticast);
+
+  var lowercase = InternetAddress.tryParse("ff00::1:2:3");
+  Expect.equals(InternetAddressType.IPv6, lowercase.type);
+  Expect.equals("ff00::1:2:3", lowercase.host);
+  Expect.equals("ff00::1:2:3", lowercase.address);
+
+  Expect.isNull(InternetAddress.tryParse("1.2.3"));
+  Expect.isNull(InternetAddress.tryParse("1.2.3.4.5"));
+  Expect.isNull(InternetAddress.tryParse("192.168.256.0"));
+  Expect.isNull(InternetAddress.tryParse("192.168.999.0"));
+  Expect.isNull(InternetAddress.tryParse("1.-2.3.4"));
+  Expect.isNull(InternetAddress.tryParse(""));
+  Expect.isNull(InternetAddress.tryParse("FFFG::0"));
+  Expect.isNull(InternetAddress.tryParse("FFF@::0"));
+  Expect.isNull(InternetAddress.tryParse("::FFFF::1"));
+}
+
 void testEquality() {
   Expect.equals(
       new InternetAddress("127.0.0.1"), new InternetAddress("127.0.0.1"));
@@ -162,6 +211,7 @@
 void main() {
   testDefaultAddresses();
   testConstructor();
+  testTryParse();
   testEquality();
   testLookup();
   testReverseLookup();
diff --git a/tests/standalone_2/io/process_check_arguments_test.dart b/tests/standalone_2/io/process_check_arguments_test.dart
index c79c00e..366223d 100644
--- a/tests/standalone_2/io/process_check_arguments_test.dart
+++ b/tests/standalone_2/io/process_check_arguments_test.dart
@@ -36,4 +36,5 @@
   test([scriptFile.path, '4', '0', 'a\tb', 'a']);
   test([scriptFile.path, '4', '0', 'a\tb', 'a\t\t\t\tb']);
   test([scriptFile.path, '4', '0', 'a\tb', 'a    b']);
+  test([scriptFile.path, '5', '0', 'a\tb', 'a    b', '']);
 }
diff --git a/tests/standalone_2/io/unix_socket_test.dart b/tests/standalone_2/io/unix_socket_test.dart
index cc6ed79..7c52777 100644
--- a/tests/standalone_2/io/unix_socket_test.dart
+++ b/tests/standalone_2/io/unix_socket_test.dart
@@ -74,7 +74,7 @@
   var socket = await Socket.connect(address, server.port);
   socket.write(" socket content");
 
-  await socket.destroy();
+  socket.destroy();
   await server.close();
 }
 
@@ -138,7 +138,7 @@
 }
 
 // Create socket in temp directory
-Future withTempDir(String prefix, void test(Directory dir)) async {
+Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
   var tempDir = Directory.systemTemp.createTempSync(prefix);
   try {
     await test(tempDir);
diff --git a/tests/standalone_2/io/web_socket_protocol_processor_test.dart b/tests/standalone_2/io/web_socket_protocol_processor_test.dart
index fc50c61..f7460e2 100644
--- a/tests/standalone_2/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone_2/io/web_socket_protocol_processor_test.dart
@@ -18,6 +18,7 @@
 import "dart:isolate";
 
 part "../../../sdk/lib/_http/crypto.dart";
+part "../../../sdk/lib/_http/embedder_config.dart";
 part "../../../sdk/lib/_http/http_impl.dart";
 part "../../../sdk/lib/_http/http_date.dart";
 part "../../../sdk/lib/_http/http_parser.dart";
diff --git a/tests/standalone_2/regress_41329_absolute_test.dart b/tests/standalone_2/regress_41329_absolute_test.dart
new file mode 100644
index 0000000..5673b99
--- /dev/null
+++ b/tests/standalone_2/regress_41329_absolute_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:path/path.dart' as p;
+import 'package:expect/expect.dart';
+
+Future<void> main() async {
+  final origDir = Directory.current;
+  final exePath = Platform.resolvedExecutable;
+  final d = Directory.systemTemp.createTempSync('dart_symlink');
+
+  // Roughly emulate a Brew installation:
+  //   - $BREW/bin/dart -> ../Cellar/dart/2.8.0-dev.20.0/bin/dart
+  //   - $BREW/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart
+  final a = Directory('${d.path}/usr/local/bin');
+  a.createSync(recursive: true);
+
+  // /usr/local/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart
+  Directory.current = a;
+  final linkLocation = '../Cellar/dart/2.8.0-dev.20.0/bin/dart';
+  final link = Link(linkLocation);
+  link.createSync(exePath, recursive: true);
+
+  // /usr/local/bin/dart -> /usr/local/Cellar/dart/2.8.0-dev.20/bin/dart
+  final link2 = Link('dart')..createSync(linkLocation, recursive: true);
+  final path = Uri.parse(link2.absolute.path).path;
+  Directory.current = origDir;
+  final result = await Process.run('${path}',
+      [p.relative(Platform.script.resolve('regress_41329_helper.dart').path)]);
+  Expect.equals(result.stdout, '');
+  Expect.equals(result.stderr, '');
+  Expect.equals(result.exitCode, 42);
+}
diff --git a/tests/standalone_2/regress_41329_helper.dart b/tests/standalone_2/regress_41329_helper.dart
new file mode 100644
index 0000000..f6f82dd
--- /dev/null
+++ b/tests/standalone_2/regress_41329_helper.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.
+
+import 'dart:io';
+
+main() {
+  exitCode = 42;
+}
diff --git a/tests/standalone_2/regress_41329_relative_test.dart b/tests/standalone_2/regress_41329_relative_test.dart
new file mode 100644
index 0000000..5673b99
--- /dev/null
+++ b/tests/standalone_2/regress_41329_relative_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:path/path.dart' as p;
+import 'package:expect/expect.dart';
+
+Future<void> main() async {
+  final origDir = Directory.current;
+  final exePath = Platform.resolvedExecutable;
+  final d = Directory.systemTemp.createTempSync('dart_symlink');
+
+  // Roughly emulate a Brew installation:
+  //   - $BREW/bin/dart -> ../Cellar/dart/2.8.0-dev.20.0/bin/dart
+  //   - $BREW/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart
+  final a = Directory('${d.path}/usr/local/bin');
+  a.createSync(recursive: true);
+
+  // /usr/local/Cellar/dart/2.8.0-dev.20.0/bin/dart -> $DART_SDK/bin/dart
+  Directory.current = a;
+  final linkLocation = '../Cellar/dart/2.8.0-dev.20.0/bin/dart';
+  final link = Link(linkLocation);
+  link.createSync(exePath, recursive: true);
+
+  // /usr/local/bin/dart -> /usr/local/Cellar/dart/2.8.0-dev.20/bin/dart
+  final link2 = Link('dart')..createSync(linkLocation, recursive: true);
+  final path = Uri.parse(link2.absolute.path).path;
+  Directory.current = origDir;
+  final result = await Process.run('${path}',
+      [p.relative(Platform.script.resolve('regress_41329_helper.dart').path)]);
+  Expect.equals(result.stdout, '');
+  Expect.equals(result.stderr, '');
+  Expect.equals(result.exitCode, 42);
+}
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index cfbe667..01f6276 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -13,6 +13,8 @@
 
 [ $system == android ]
 entrypoints_verification_test: Skip # Requires shared objects which the test script doesn't "adb push".
+io/http_ban_http_embedder_test: Skip # Requires http server bound to non-loopback; not provided by system.
+io/http_ban_http_normal_test: Skip # Requires http server bound to non-loopback; not provided by system.
 
 [ $arch == ia32 && $builder_tag == optimization_counter_threshold ]
 io/file_lock_test: SkipSlow # Timeout
diff --git a/third_party/pkg_tested/pkg_tested.status b/third_party/pkg_tested/pkg_tested.status
index 47ab254..0b31420 100644
--- a/third_party/pkg_tested/pkg_tested.status
+++ b/third_party/pkg_tested/pkg_tested.status
@@ -15,7 +15,6 @@
 pub/test/transformer/loads_a_diamond_transformer_dependency_graph_test: Pass, Slow
 
 [ $runtime == vm ]
-dart_style/test/command_line_test: Skip # Issue 33473
 http_io/test/http_cross_process_test: Skip # Fails with --no-preview-dart-2
 http_io/test/http_proxy_advanced_test: Pass, RuntimeError # flaky
 http_io/test/http_proxy_test: Pass, RuntimeError # flaky
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index 597f3da..decbb70 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -30,3 +30,4 @@
 Trigger bots
 Switch benchmark builders to Ubuntu 16.04
 Land a CL with no tryjobs, to validate a fix in copying approvals
+Confirm all approvals took effect
diff --git a/tools/VERSION b/tools/VERSION
index 3ce66e6..a787e17 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -31,9 +31,9 @@
 #
 CHANNEL beta
 MAJOR 2
-MINOR 8
+MINOR 9
 PATCH 0
-PRERELEASE 20
-PRERELEASE_PATCH 11
+PRERELEASE 8
+PRERELEASE_PATCH 1
 ABI_VERSION 32
 OLDEST_SUPPORTED_ABI_VERSION 32
diff --git a/tools/bots/dart_tests.isolate b/tools/bots/dart_tests.isolate
index 8d72bf3..bb9e7f6 100644
--- a/tools/bots/dart_tests.isolate
+++ b/tools/bots/dart_tests.isolate
@@ -11,7 +11,6 @@
               'third_party/pkg_tested/',
               'third_party/d8/',
               'third_party/firefox_jsshell/',
-              'third_party/observatory_pub_packages/packages/web_components/',
               'tests/angular/',
               'tests/compiler/',
               'tests/corelib_2/',
diff --git a/tools/bots/get_builder_status.dart b/tools/bots/get_builder_status.dart
index cb0d3c4..725c9f4 100755
--- a/tools/bots/get_builder_status.dart
+++ b/tools/bots/get_builder_status.dart
@@ -23,8 +23,6 @@
 String builderBase;
 int buildNumber;
 String token;
-List<String> configurations;
-Map<String, List<Map<String, dynamic>>> failures = {};
 http.Client client;
 
 String get buildTable => builder.endsWith('-try') ? 'try_builds' : 'builds';
@@ -77,19 +75,21 @@
       if (document != null) {
         bool success = booleanFieldOrFalse(document, 'success');
         bool completed = booleanFieldOrFalse(document, 'completed');
-        bool activeFailures = booleanFieldOrFalse(document, 'active_failures');
         if (completed) {
-          if (success) {
-            print('No unapproved new failures');
-            if (activeFailures == true) {
-              print('There are unapproved failures from previous builds');
-              await printResults();
-            }
+          print(success
+              ? 'No new unapproved failures'
+              : 'There are new unapproved failures on this build');
+          if (builder.endsWith('-try')) exit(success ? 0 : 1);
+          final configurations = await getConfigurations();
+          final failures = await fetchActiveFailures(configurations);
+          if (failures.isNotEmpty) {
+            print('There are unapproved failures');
+            printActiveFailures(failures);
+            exit(1);
           } else {
-            print('There are unapproved new failures on this build');
-            await printResults();
+            print('There are no unapproved failures');
+            exit(0);
           }
-          exit((success && (activeFailures != true)) ? 0 : 1);
         }
         String chunks =
             (document['fields']['num_chunks'] ?? const {})['integerValue'];
@@ -116,13 +116,6 @@
   exit(2);
 }
 
-void printResults() async {
-  if (builder.endsWith('-try')) return;
-  configurations = await getConfigurations();
-  await printActiveFailures();
-  await printResultsFeedLink();
-}
-
 Future<List<String>> getConfigurations() async {
   final response = await runFirestoreQuery(configurationsQuery());
   if (response.statusCode == HttpStatus.ok) {
@@ -154,7 +147,9 @@
   return 'missing hash for commit $index';
 }
 
-Future<void> printActiveFailures() async {
+Future<Map<String, List<Map<String, dynamic>>>> fetchActiveFailures(
+    List<String> configurations) async {
+  final failures = <String, List<Map<String, dynamic>>>{};
   for (final configuration in configurations) {
     final response =
         await runFirestoreQuery(unapprovedFailuresQuery(configuration));
@@ -166,8 +161,10 @@
         final fields = document['fields'];
         failures.putIfAbsent(configuration, () => []).add({
           'name': fields['name']['stringValue'],
-          'start': int.parse(fields['blamelist_start_index']['integerValue']),
-          'end': int.parse(fields['blamelist_end_index']['integerValue']),
+          'start_commit': await commitHash(
+              int.parse(fields['blamelist_start_index']['integerValue'])),
+          'end_commit': await commitHash(
+              int.parse(fields['blamelist_end_index']['integerValue'])),
           'result': fields['result']['stringValue'],
           'expected': fields['expected']['stringValue'],
           'previous': fields['previous_result']['stringValue'],
@@ -175,6 +172,10 @@
       }
     }
   }
+  return failures;
+}
+
+void printActiveFailures(Map<String, List<Map<String, dynamic>>> failures) {
   for (final configuration in failures.keys) {
     print('($configuration):');
     for (final failure in failures[configuration]) {
@@ -188,30 +189,16 @@
         ', expected ',
         failure['expected'],
         ') at ',
-        (await commitHash(failure['start'])).substring(0, 6),
-        if (failure['start'] != failure['end']) ...[
+        failure['start_commit'].substring(0, 6),
+        if (failure['end_commit'] != failure['start_commit']) ...[
           '..',
-          (await commitHash(failure['end'])).substring(0, 6)
+          failure['end_commit'].substring(0, 6)
         ]
       ].join(''));
     }
   }
 }
 
-void printResultsFeedLink() async {
-  if (builder.endsWith('-try')) return;
-  final groups = {
-    for (final configuration in configurations) configuration.split('-').first
-  };
-  String fragment = [
-    'showLatestFailures=true',
-    'showUnapprovedOnly=true',
-    if (groups.isNotEmpty) 'configurationGroups=${groups.join(',')}'
-  ].join('&');
-  final link = 'https://dart-ci.firebaseapp.com/#$fragment';
-  print('\nFailures link: $link');
-}
-
 Future<http.Response> runFirestoreQuery(String query) {
   final headers = {
     'Authorization': 'Bearer $token',
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 1ab78cd..9dc2f2f 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -40,6 +40,12 @@
       "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/compiler/",
       "tests/corelib_2/",
       "tests/dart/",
@@ -53,7 +59,6 @@
       "tests/ffi_2/",
       "third_party/babel/babel.min.js",
       "third_party/d8/",
-      "third_party/observatory_pub_packages/packages/web_components/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
       "third_party/requirejs/",
@@ -75,6 +80,12 @@
       "sdk_nnbd/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-co19.status",
       "tests/co19_2/co19_2-dart2js.status",
@@ -97,7 +108,6 @@
       "tests/ffi_2/",
       "third_party/babel/babel.min.js",
       "third_party/d8/",
-      "third_party/observatory_pub_packages/packages/web_components/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
       "third_party/requirejs/",
@@ -122,6 +132,12 @@
       "sdk/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-co19.status",
       "tests/co19_2/co19_2-dart2js.status",
@@ -165,6 +181,12 @@
       "sdk_nnbd/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-co19.status",
       "tests/co19_2/co19_2-dart2js.status",
@@ -173,10 +195,13 @@
       "tests/co19_2/co19_2-runtime.status",
       "tests/compiler/",
       "tests/corelib_2/",
+      "tests/corelib/",
       "tests/dart/",
       "tests/kernel/",
       "tests/language_2/",
+      "tests/language/",
       "tests/lib_2/",
+      "tests/lib/",
       "tests/light_unittest.dart",
       "tests/search/",
       "tests/standalone_2/",
@@ -204,6 +229,12 @@
       "sdk_nnbd/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-co19.status",
       "tests/co19_2/co19_2-dart2js.status",
@@ -245,7 +276,6 @@
       "out/ReleaseX64/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
-      "third_party/observatory_pub_packages/packages/",
       "tools/sdks/dart-sdk/",
       "pkg/_fe_analyzer_shared/",
       "pkg/async_helper/",
@@ -305,9 +335,14 @@
       "third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip",
       "third_party/pkg/",
       "third_party/pkg_tested/",
-      "third_party/observatory_pub_packages/packages/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-co19.status",
       "tests/co19_2/co19_2-dart2js.status",
@@ -331,6 +366,7 @@
       "pkg/dart_internal/",
       "pkg/dart2native/",
       "pkg/dart2js_tools/",
+      "pkg/dds/",
       "pkg/expect/",
       "pkg/front_end/",
       "pkg/js/",
@@ -391,9 +427,14 @@
       "third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip",
       "third_party/pkg/",
       "third_party/pkg_tested/",
-      "third_party/observatory_pub_packages/packages/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-co19.status",
       "tests/co19_2/co19_2-dart2js.status",
@@ -417,6 +458,7 @@
       "pkg/dart_internal/",
       "pkg/dart2native/",
       "pkg/dart2js_tools/",
+      "pkg/dds/",
       "pkg/expect/",
       "pkg/front_end/",
       "pkg/js/",
@@ -455,6 +497,18 @@
         "use-sdk": true
       }
     },
+    "unittest-weak-asserts-no-sdk-(linux|mac|win)": {
+       "options": {
+         "compiler": "dartk",
+         "enable-asserts": true,
+         "mode": "release",
+         "runtime": "vm",
+         "timeout": 240,
+         "enable-experiment": [
+           "non-nullable"
+         ]
+       }
+    },
     "analyzer-unittest-asserts-(debug|product|release)-(linux|mac|win)": {
       "options": {
         "compiler": "dartk",
@@ -624,7 +678,7 @@
         "host-checked": true
       }
     },
-    "dart2js-hostasserts-weak-(linux|mac|win)-x64-(d8|chrome)": {
+    "dart2js-hostasserts-weak-(linux|win)-x64-(d8|chrome)": {
       "options": {
         "builder-tag": "dart2js-weak",
         "enable-experiment": [
@@ -632,8 +686,55 @@
         ],
         "dart2js-options": [
           "--no-null-safety",
-          "--libraries-spec=sdk_nnbd/lib/libraries.json"
+          "--libraries-spec=sdk_nnbd/lib/libraries.json",
+          "--platform-binaries=out/ReleaseX64NNBD/"
         ],
+        "timeout": 240,
+        "host-checked": true
+      }
+    },
+    "dart2js-hostasserts-weak-mac-x64-(d8|chrome)": {
+      "options": {
+        "builder-tag": "dart2js-weak",
+        "enable-experiment": [
+          "non-nullable"
+        ],
+        "dart2js-options": [
+          "--no-null-safety",
+          "--libraries-spec=sdk_nnbd/lib/libraries.json",
+          "--platform-binaries=xcodebuild/ReleaseX64NNBD/"
+        ],
+        "timeout": 240,
+        "host-checked": true
+      }
+    },
+    "dart2js-hostasserts-strong-(linux|win)-x64-(d8|chrome)": {
+      "options": {
+        "builder-tag": "dart2js-strong",
+        "enable-experiment": [
+          "non-nullable"
+        ],
+        "dart2js-options": [
+          "--null-safety",
+          "--libraries-spec=sdk_nnbd/lib/libraries.json",
+          "--platform-binaries=out/ReleaseX64NNBD/"
+        ],
+        "timeout": 240,
+        "host-checked": true
+      }
+    },
+    "dart2js-hostasserts-strong-mac-x64-(d8|chrome)": {
+      "options": {
+        "builder-tag": "dart2js-strong",
+        "enable-experiment": [
+          "non-nullable"
+        ],
+        "dart2js-options": [
+          "--null-safety",
+          "--libraries-spec=sdk_nnbd/lib/libraries.json",
+          "--platform-binaries=xcodebuild/ReleaseX64NNBD/"
+        ],
+        "timeout": 240,
         "host-checked": true
       }
     },
@@ -669,7 +770,7 @@
       }
     },
     "dartk-android-(debug|product|release)-(arm|arm64)": {},
-    "dartkp-(linux|win|mac)-(debug|product|release)-(simarm|simarm64)": {
+    "dartkp-(linux|win|mac)-(debug|product|release)-(arm64|simarm|simarm64)": {
       "options": {
         "use-elf": true
       }
@@ -726,12 +827,23 @@
       }
     },
     "dartk-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {},
+    "dartk-linux-debug-(ia32|x64)-canary": {
+      "options": {
+        "builder-tag": "canary"
+      }
+    },
     "dartkp-weak-asserts-(linux|mac)-(debug|product|release)-x64": {
       "options": {
         "enable-experiment": [
           "non-nullable"
         ],
-        "enable-asserts": true
+	"gen-kernel-options": [
+          "--no-null-safety"
+        ],
+        "enable-asserts": true,
+	"vm-options": [
+          "--no-null-safety"
+        ]
       }
     },
     "dartkp-weak-asserts-win-(debug|product|release)-x64": {
@@ -739,8 +851,14 @@
         "enable-experiment": [
           "non-nullable"
         ],
+	"gen-kernel-options": [
+          "--no-null-safety"
+        ],
         "enable-asserts": true,
-        "use-elf": true
+        "use-elf": true,
+	"vm-options": [
+          "--no-null-safety"
+        ]
       }
     },
     "dartk-weak-asserts-(linux|mac|win)-(debug|product|release)-x64": {
@@ -748,7 +866,10 @@
         "enable-experiment": [
           "non-nullable"
         ],
-        "enable-asserts": true
+        "enable-asserts": true,
+	"vm-options": [
+          "--no-null-safety"
+        ]
       }
     },
     "dartk-strong-(linux|mac|win)-(debug|product|release)-x64": {
@@ -756,9 +877,6 @@
         "enable-experiment": [
           "non-nullable"
         ],
-        "gen-kernel-options": [
-          "--null-safety"
-        ],
         "vm-options": [
           "--null-safety"
         ]
@@ -914,6 +1032,9 @@
         ]
       }
     },
+    "dartkb-abi-linux-release-x64": {
+      "__comment__": "This configuration is only used for a custom test runner. If it conflicts with a new configuration you are adding, you can make this configuration more specific by adding options."
+    },
     "dartdevk-checked-(linux|mac|win)-(debug|product|release)-(chrome|firefox)": {
       "options": {
         "checked": true,
@@ -1204,14 +1325,14 @@
         {
           "name": "vm ia32 tests",
           "arguments": [
-            "-ndartk-linux-debug-ia32",
+            "-ndartk-linux-debug-ia32-canary",
             "vm"
           ]
         },
         {
           "name": "vm x64 tests",
           "arguments": [
-            "-ndartk-linux-debug-x64",
+            "-ndartk-linux-debug-x64-canary",
             "vm"
           ]
         }
@@ -1361,10 +1482,11 @@
             "ffi",
             "language",
             "lib",
+	    "co19/LanguageFeatures/nnbd",
             "standalone/io"
           ]
         },
-	{
+        {
           "name": "vm nnbd tests in strong mode",
           "arguments": [
             "-ndartkp-strong-${system}-${mode}-${arch}",
@@ -1372,6 +1494,7 @@
             "ffi",
             "language",
             "lib",
+	    "co19/LanguageFeatures/nnbd",
             "standalone/io"
           ]
         }
@@ -1525,100 +1648,33 @@
     {
       "builders": [
         "vm-kernel-asan-linux-release-ia32",
-        "vm-kernel-asan-linux-release-x64"
-      ],
-      "meta": {
-        "description": "This configuration is used by the vm builders with AddressSanitizer (asan)."
-      },
-      "steps": [
-        {
-          "name": "configure dart",
-          "script": "tools/gn.py",
-          "arguments": [
-            "--mode=${mode}",
-            "--arch=${arch}",
-            "--sanitizer=asan"
-          ]
-        },
-        {
-          "name": "build dart",
-          "script": "tools/build.py",
-          "arguments": [
-            "--sanitizer=asan",
-            "runtime"
-          ]
-        },
-        {
-          "name": "vm tests",
-          "arguments": [
-            "-ndartk-asan-linux-release-${arch}"
-          ]
-        }
-      ]
-    },
-    {
-      "builders": [
+        "vm-kernel-asan-linux-release-x64",
         "vm-kernel-lsan-linux-release-ia32",
-        "vm-kernel-lsan-linux-release-x64"
+        "vm-kernel-lsan-linux-release-x64",
+        "vm-kernel-msan-linux-release-x64",
+        "vm-kernel-ubsan-linux-release-ia32",
+        "vm-kernel-ubsan-linux-release-x64"
       ],
       "meta": {
-        "description": "This configuration is used by the vm builders with LeakSanitizer (lsan)."
+        "description": "This configuration is used by the VM/JIT builders with sanitizers."
       },
       "steps": [
         {
           "name": "configure dart",
           "script": "tools/gn.py",
-          "arguments": [
-            "--mode=${mode}",
-            "--arch=${arch}",
-            "--sanitizer=lsan"
-          ]
+          "arguments": []
         },
         {
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "--sanitizer=lsan",
             "runtime"
           ]
         },
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartk-lsan-linux-release-${arch}"
-          ]
-        }
-      ]
-    },
-    {
-      "builders": [
-        "vm-kernel-msan-linux-release-x64"
-      ],
-      "meta": {
-        "description": "This configuration is used by the vm builders with MemorySanitizer (msan)."
-      },
-      "steps": [
-        {
-          "name": "configure dart",
-          "script": "tools/gn.py",
-          "arguments": [
-            "--mode=${mode}",
-            "--arch=${arch}",
-            "--sanitizer=msan"
-          ]
-        },
-        {
-          "name": "build dart",
-          "script": "tools/build.py",
-          "arguments": [
-            "--sanitizer=msan",
-            "runtime"
-          ]
-        },
-        {
-          "name": "vm tests",
-          "arguments": [
-            "-ndartk-msan-linux-release-${arch}"
+            "-ndartk-${sanitizer}-${system}-${mode}-${arch}"
           ]
         }
       ]
@@ -1628,30 +1684,25 @@
         "vm-kernel-tsan-linux-release-x64"
       ],
       "meta": {
-        "description": "This configuration is used by the vm builders with ThreadSanitizer (tsan)."
+        "description": "This configuration is used by the VM/JIT builders with sanitizers."
       },
       "steps": [
         {
           "name": "configure dart",
           "script": "tools/gn.py",
-          "arguments": [
-            "--mode=${mode}",
-            "--arch=${arch}",
-            "--sanitizer=tsan"
-          ]
+          "arguments": []
         },
         {
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "--sanitizer=tsan",
             "runtime"
           ]
         },
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartk-tsan-linux-release-${arch}",
+            "-ndartk-${sanitizer}-${system}-${mode}-${arch}",
             "vm"
           ]
         }
@@ -1659,34 +1710,64 @@
     },
     {
       "builders": [
-        "vm-kernel-ubsan-linux-release-ia32",
-        "vm-kernel-ubsan-linux-release-x64"
+        "vm-kernel-precomp-asan-linux-release-x64",
+        "vm-kernel-precomp-lsan-linux-release-x64",
+        "vm-kernel-precomp-msan-linux-release-x64",
+        "vm-kernel-precomp-ubsan-linux-release-x64"
       ],
       "meta": {
-        "description": "This configuration is used by the vm builders with UndefinedBehaviorSanitizer (ubsan)."
+        "description": "This configuration is used by the VM/AOT builders with sanitizers."
       },
       "steps": [
         {
           "name": "configure dart",
           "script": "tools/gn.py",
-          "arguments": [
-            "--mode=${mode}",
-            "--arch=${arch}",
-            "--sanitizer=ubsan"
-          ]
+          "arguments": []
         },
         {
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "--sanitizer=ubsan",
-            "runtime"
+            "runtime",
+            "runtime_precompiled"
           ]
         },
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartk-ubsan-linux-release-${arch}"
+            "-ndartkp-${sanitizer}-${system}-${mode}-${arch}",
+            "vm",
+            "standalone_2"
+          ]
+        }
+      ]
+    },
+    {
+      "builders": [
+        "vm-kernel-precomp-tsan-linux-release-x64"
+      ],
+      "meta": {
+        "description": "This configuration is used by the VM/AOT builders with sanitizers."
+      },
+      "steps": [
+        {
+          "name": "configure dart",
+          "script": "tools/gn.py",
+          "arguments": []
+        },
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "runtime",
+            "runtime_precompiled"
+          ]
+        },
+        {
+          "name": "vm tests",
+          "arguments": [
+            "-ndartkp-${sanitizer}-${system}-${mode}-${arch}",
+            "vm"
           ]
         }
       ]
@@ -1766,6 +1847,7 @@
             "ffi",
             "language",
             "lib",
+	    "co19/LanguageFeatures/nnbd",
             "standalone/io"
           ]
         },
@@ -1777,6 +1859,7 @@
             "ffi",
             "language",
             "lib",
+	    "co19/LanguageFeatures/nnbd",
             "standalone/io"
           ]
         }
@@ -1874,6 +1957,33 @@
     },
     {
       "builders": [
+        "cross-vm-precomp-linux-release-arm64"
+      ],
+      "meta": {
+        "description": "This configuration is for the cross arm AOT builders."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "dart_precompiled_runtime",
+            "gen_snapshot",
+            "runtime_kernel"
+          ]
+        },
+        {
+          "name": "vm tests",
+          "arguments": [
+            "-ndartkp-${system}-${mode}-${arch}"
+          ],
+          "fileset": "vm-kernel",
+          "shards": 1
+        }
+      ]
+    },
+    {
+      "builders": [
         "app-kernel-linux-debug-x64",
         "app-kernel-linux-product-x64",
         "app-kernel-linux-release-x64"
@@ -2046,6 +2156,17 @@
           ]
         },
         {
+          "name": "ddc weak modular tests",
+          "script": "out/ReleaseX64NNBD/dart-sdk/bin/dart",
+          "testRunner": true,
+          "arguments": [
+            "pkg/dev_compiler/test/modular_suite_nnbd.dart",
+            "-ndartdevk-weak-${system}-release-chrome",
+            "--verbose",
+            "--use-sdk"
+          ]
+        },
+        {
           "name": "ddc nnbd weak tests",
           "arguments": [
             "-ndartdevk-weak-linux-release-chrome",
@@ -2625,7 +2746,8 @@
             "language_2",
             "corelib_2",
             "dart2js_extra",
-            "dart2js_native"
+            "dart2js_native",
+            "kernel"
           ],
           "shards": 6,
           "fileset": "dart2js_hostasserts_nnbd"
@@ -2649,6 +2771,48 @@
           ],
           "shards": 6,
           "fileset": "dart2js_hostasserts_nnbd"
+        },
+        {
+          "name": "dart2js nnbd strong tests",
+          "arguments": [
+            "-ndart2js-hostasserts-strong-linux-x64-d8",
+            "--dart2js-batch",
+            "language",
+            "corelib",
+            "dart2js_extra",
+            "dart2js_native",
+            "kernel"
+          ],
+          "shards": 6,
+          "fileset": "dart2js_hostasserts_nnbd"
+        },
+        {
+          "name": "dart2js nnbd strong lib tests",
+          "arguments": [
+            "-ndart2js-hostasserts-strong-linux-x64-chrome",
+            "--dart2js-batch",
+            "lib"
+          ],
+          "shards": 3,
+          "fileset": "dart2js_hostasserts_nnbd"
+        },
+        {
+          "name": "dart2js nnbd strong co19 tests",
+          "arguments": [
+            "-ndart2js-hostasserts-strong-linux-x64-chrome",
+            "--dart2js-batch",
+            "co19/LanguageFeatures/nnbd"
+          ],
+          "shards": 6,
+          "fileset": "dart2js_hostasserts_nnbd"
+        },
+        {
+          "name": "dart2js nnbd unit tests",
+          "arguments": [
+            "-nunittest-weak-asserts-no-sdk-linux",
+            "dart2js",
+            "pkg//compiler/"
+          ]
         }
       ]
     },
@@ -2919,6 +3083,15 @@
           ]
         },
         {
+          "name": "nnbd_migration unit tests",
+          "arguments": [
+            "-nanalyzer-unittest-asserts-${mode}-${system}",
+            "pkg/nnbd_migration"
+          ],
+          "shards": 2,
+          "fileset": "analyzer_unit_tests"
+        },
+        {
           "name": "analyze tests co19_2",
           "arguments": [
             "-nanalyzer-asserts-${system}",
@@ -3000,6 +3173,13 @@
             "-nanalyzer-asserts-strong-${system}",
             "co19/LanguageFeatures/nnbd"
           ]
+        },
+        {
+          "name": "analyze nnbd weak co19 tests",
+          "arguments": [
+            "-nanalyzer-asserts-weak-${system}",
+            "co19/LanguageFeatures/nnbd"
+          ]
         }
       ]
     },
@@ -3257,7 +3437,6 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
           "arguments": [
             "--fatal-warnings",
-            "--packages=runtime/observatory/.packages",
             "runtime/observatory"
           ]
         },
@@ -3305,7 +3484,7 @@
           "name": "package unit tests",
           "arguments": [
             "-nunittest-asserts-${mode}-${system}",
-            "pkg/pkg/(?!(analyzer*|analysis_server|front_end|kernel)/)"
+            "pkg/pkg/(?!(analyzer*|analysis_server|front_end|kernel|nnbd_migration)/)"
           ]
         },
         {
@@ -3343,7 +3522,7 @@
           "name": "package unit tests",
           "arguments": [
             "-nunittest-asserts-${mode}-${system}",
-            "pkg/pkg/(?!(analyzer*|analysis_server|front_end|kernel)/)"
+            "pkg/pkg/(?!(analyzer*|analysis_server|front_end|kernel|nnbd_migration)/)"
           ]
         },
         {
@@ -3448,41 +3627,6 @@
           "arguments": [
             "clean"
           ]
-        },
-        {
-          "name": "generate ninja for linux-x64-bytecode",
-          "script": "tools/gn.py",
-          "arguments": [
-            "--mode=release",
-            "--arch=x64",
-            "--bytecode"
-          ]
-        },
-        {
-          "name": "build linux-x64-bytecode for benchmarking",
-          "script": "tools/build.py",
-          "arguments": [
-            "--mode=release",
-            "--arch=x64",
-            "create_sdk",
-            "runtime",
-            "gen_snapshot",
-            "dart_precompiled_runtime"
-          ]
-        },
-        {
-          "name": "archive linux-x64-bytecode for benchmarking",
-          "script": "tools/bots/try_benchmarks.sh",
-          "arguments": [
-            "linux-x64-bytecode-archive"
-          ]
-        },
-        {
-          "name": "try linux-x64-bytecode benchmarking",
-          "script": "tools/bots/try_benchmarks.sh",
-          "arguments": [
-            "linux-x64-bytecode-benchmark"
-          ]
         }
       ]
     },
@@ -3609,7 +3753,8 @@
         {
           "name": "run tests",
           "script": "tools/run_abi_tests.py",
-          "testRunner": true
+          "testRunner": true,
+          "arguments": ["-ndartkb-abi-linux-release-x64"]
         }
       ]
     },
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index cd1fbe6..365df82 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -26,9 +26,6 @@
     linux-x64-build - Build linux-x64 for benchmarking.
     linux-x64-archive - Archive linux-x64.
     linux-x64-benchmark - Try linux-x64 benchmarking.
-    linux-x64-bytecode-build - Build linux-x64 with bytecode for benchmarking.
-    linux-x64-bytecode-archive - Archive linux-x64 with bytecode.
-    linux-x64-bytecode-benchmark - Try linux-x64 with bytecode benchmarking.
 EOF
   exit 1
 fi
@@ -191,19 +188,13 @@
     out/ReleaseIA32/dart benchmarks/FfiStruct/dart/FfiStruct.dart
     cd ..
     rm -rf tmp
-  elif [ "$command" = linux-x64-build ] ||
-       [ "$command" = linux-x64-bytecode-build ]; then
+  elif [ "$command" = linux-x64-build ]; then
     # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync.
-    if [ "$command" = linux-x64-bytecode-build ]; then
-      # Beware: Don't mix --bytecode with a non-bytecode out/.
-      ./tools/gn.py --mode=release --arch=x64 --bytecode
-    fi
     ./tools/build.py --mode=release --arch=x64 create_sdk
     ./tools/build.py --mode=release --arch=x64 runtime
     ./tools/build.py --mode=release --arch=x64 gen_snapshot
     ./tools/build.py --mode=release --arch=x64 dart_precompiled_runtime
-  elif [ "$command" = linux-x64-archive ] ||
-       [ "$command" = linux-x64-bytecode-archive ]; then
+  elif [ "$command" = linux-x64-archive ]; then
     strip -w \
       -K 'kDartVmSnapshotData' \
       -K 'kDartVmSnapshotInstructions' \
@@ -309,8 +300,7 @@
       runtime/lib \
       benchmarks \
       || (rm -f linux-x64.tar.gz; exit 1)
-  elif [ "$command" = linux-x64-benchmark ] ||
-       [ "$command" = linux-x64-bytecode-benchmark ]; then
+  elif [ "$command" = linux-x64-benchmark ]; then
     rm -rf tmp
     mkdir tmp
     cd tmp
@@ -323,13 +313,7 @@
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages hello.dart
     DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/precompiler2 --packages=.packages hello.dart blob.bin
     DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/dart_precompiled_runtime2 --profile-period=10000 blob.bin
-    DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/precompiler2 --no-gen-bytecode --packages=.packages hello.dart blob.bin
-    DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/dart_precompiled_runtime2 --profile-period=10000 blob.bin
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --optimization-counter-threshold=-1 hello.dart
-    out/ReleaseX64/dart --profile-period=10000 --packages=.packages --enable-interpreter hello.dart
-    out/ReleaseX64/dart --profile-period=10000 --packages=.packages --enable-interpreter --compilation-counter-threshold=-1 hello.dart
-    out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler hello.dart
-    out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler --optimization-counter-threshold=-1 hello.dart
     out/ReleaseX64/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
     out/ReleaseX64/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 150f727..d4f94297 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -4,7 +4,7 @@
 interface WaveShaperNode {
   // TODO(ager): Auto-generate this custom method when the info about retaining
   // typed arrays is in the IDL.
-  [Custom=Setter] attribute Float32Array curve;
+  [Custom=Setter] attribute Float32Array? curve;
 };
 
 [DartSupplemental]
@@ -40,14 +40,14 @@
 
 [DartSupplemental]
 interface Element {
-  readonly attribute Element nextElementSibling;
-  readonly attribute Element previousElementSibling;
+  readonly attribute Element? nextElementSibling;
+  readonly attribute Element? previousElementSibling;
 };
 
 [DartSupplemental]
 interface CharacterData {
-  readonly attribute Element nextElementSibling;
-  readonly attribute Element previousElementSibling;
+  readonly attribute Element? nextElementSibling;
+  readonly attribute Element? previousElementSibling;
 };
 
 [Callback]
@@ -418,6 +418,9 @@
   [DartSuppress] void scroll(long x, long y);
   [DartSuppress] void scroll(long x, long y, Dictionary scrollOptions);
   [RaisesException] void scroll(long x, long y, optional Dictionary scrollOptions);
+
+  [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject, DartSuppress] readonly attribute VisualViewport visualViewport;
+  [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject] readonly attribute VisualViewport? visualViewport;
 };
 
 [DartSupplemental]
diff --git a/tools/dom/nnbd_src/AttributeMap.dart b/tools/dom/nnbd_src/AttributeMap.dart
index fad3c44..88f3bd4 100644
--- a/tools/dom/nnbd_src/AttributeMap.dart
+++ b/tools/dom/nnbd_src/AttributeMap.dart
@@ -96,7 +96,7 @@
   _ElementAttributeMap(Element element) : super(element);
 
   bool containsKey(Object? key) {
-    return _element._hasAttribute(key as String);
+    return key is String && _element._hasAttribute(key);
   }
 
   String? operator [](Object? key) {
@@ -122,8 +122,8 @@
   // Inline this because almost all call sites of [remove] do not use [value],
   // and the annotations on the `getAttribute` call allow it to be removed.
   @pragma('dart2js:tryInline')
-  static String _remove(Element element, String key) {
-    String value = JS(
+  static String? _remove(Element element, String key) {
+    String? value = JS(
         // throws:null(1) is not accurate since [key] could be malformed, but
         // [key] is checked again by `removeAttributeNS`.
         'returns:String|Null;depends:all;effects:none;throws:null(1)',
@@ -139,12 +139,12 @@
  * Wrapper to expose namespaced attributes as a typed map.
  */
 class _NamespacedAttributeMap extends _AttributeMap {
-  final String _namespace;
+  final String? _namespace;
 
   _NamespacedAttributeMap(Element element, this._namespace) : super(element);
 
   bool containsKey(Object? key) {
-    return _element._hasAttributeNS(_namespace, key as String);
+    return key is String && _element._hasAttributeNS(_namespace, key);
   }
 
   String? operator [](Object? key) {
@@ -172,8 +172,8 @@
   // returned [value], and the annotations on the `getAttributeNS` call allow it
   // to be removed.
   @pragma('dart2js:tryInline')
-  static String _remove(String namespace, Element element, String key) {
-    String value = JS(
+  static String? _remove(String? namespace, Element element, String key) {
+    String? value = JS(
         // throws:null(1) is not accurate since [key] could be malformed, but
         // [key] is checked again by `removeAttributeNS`.
         'returns:String|Null;depends:all;effects:none;throws:null(1)',
diff --git a/tools/dom/nnbd_src/CssClassSet.dart b/tools/dom/nnbd_src/CssClassSet.dart
index 9b38b8d..6a76202 100644
--- a/tools/dom/nnbd_src/CssClassSet.dart
+++ b/tools/dom/nnbd_src/CssClassSet.dart
@@ -17,7 +17,8 @@
    * after the operation, and returns `false` if [value] is absent after the
    * operation.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To toggle multiple classes, use
@@ -51,7 +52,8 @@
    * If this CssClassSet corresponds to one element. Returns true if [value] was
    * added to the set, otherwise false.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To add multiple classes use
diff --git a/tools/dom/nnbd_src/Validators.dart b/tools/dom/nnbd_src/Validators.dart
index 26dac65..a498da9 100644
--- a/tools/dom/nnbd_src/Validators.dart
+++ b/tools/dom/nnbd_src/Validators.dart
@@ -262,7 +262,7 @@
   /// important attributes we want to check, remove it if it's not valid
   /// or not allowed, either as a whole or particular attributes.
   void _sanitizeElement(Element element, Node? parent, bool corrupted,
-      String text, String tag, Map attrs, String isAttr) {
+      String text, String tag, Map attrs, String? isAttr) {
     if (false != corrupted) {
       _removeNode(element, parent);
       window.console
diff --git a/tools/dom/nnbd_src/shared_html.dart b/tools/dom/nnbd_src/shared_html.dart
index 5e7bc8e..f86f288 100644
--- a/tools/dom/nnbd_src/shared_html.dart
+++ b/tools/dom/nnbd_src/shared_html.dart
@@ -4,14 +4,15 @@
 
 part of dart.dom.html;
 
-void Function(T)? _wrapZone<T>(void Function(T) callback) {
+void Function(T)? _wrapZone<T>(void Function(T)? callback) {
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.root) return callback;
   if (callback == null) return null;
   return Zone.current.bindUnaryCallbackGuarded(callback);
 }
 
-void Function(T1, T2)? _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
+void Function(T1, T2)? _wrapBinaryZone<T1, T2>(
+    void Function(T1, T2)? callback) {
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.root) return callback;
   if (callback == null) return null;
diff --git a/tools/dom/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
index 0636a47..e768ee4 100755
--- a/tools/dom/scripts/databasebuilder.py
+++ b/tools/dom/scripts/databasebuilder.py
@@ -271,6 +271,8 @@
             res = node.id
             if res.startswith('unsigned '):
                 res = res[len('unsigned '):]
+            if hasattr(node, 'nullable') and node.nullable:
+                res += '?'
             return res
 
         res = []
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 2174db6..44c721e 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -490,7 +490,10 @@
         if len(set(DartType(arg.type.id) for arg in args)) == 1:
             nullable = False
             for arg in args:
-                nullable = nullable or getattr(arg.type, 'nullable', False)
+                # If the 'TreatNullAs' attribute exists, the param technically
+                # is nullable. The conversion happens in the browser.
+                nullable = nullable or getattr(arg.type, 'nullable', False) or \
+                    'TreatNullAs' in arg.ext_attrs
             return (type_ids[0], nullable)
         else:
             return (None, False)
@@ -1271,8 +1274,10 @@
         if self._data.dart_type:
             return self._data.dart_type
         if self.list_item_type() and not self.has_generated_interface():
-            return 'List<%s>' % self._type_registry.TypeInfo(
-                self._data.item_type).dart_type()
+            item_nullable = '?' if self._data.item_type_nullable and \
+                global_options_hack.nnbd else ''
+            return 'List<%s%s>' % (self._type_registry.TypeInfo(
+                self._data.item_type).dart_type(), item_nullable)
         return self._dart_interface_name
 
     def narrow_dart_type(self):
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 68a721f..b017597 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -1413,13 +1413,17 @@
                     self._members_emitter.Emit(
                         '\n'
                         '  // Use implementation from $SUPER.\n'
-                        '  // $TYPE get $NAME native;\n'
-                        '  // void set $NAME($TYPE value) native;\n',
+                        '  // $GET_TYPE get $NAME native;\n'
+                        '  // void set $NAME($SET_TYPE value) native;\n',
                         SUPER=super_attribute_interface,
                         NAME=html_name,
-                        TYPE=self.SecureOutputType(attribute.type.id,
+                        GET_TYPE=self.SecureOutputType(attribute.type.id,
                             can_narrow_type=read_only,
-                            nullable=attribute.type.nullable))
+                            nullable=attribute.type.nullable),
+                        SET_TYPE=self.SecureOutputType(attribute.type.id,
+                            can_narrow_type=read_only,
+                            nullable=attribute.type.nullable or \
+                                'TreatNullAs' in attribute.ext_attrs))
                     return
             self._members_emitter.Emit('\n  // Shadowing definition.')
             self._AddAttributeUsingProperties(attribute, html_name, read_only)
@@ -1548,7 +1552,7 @@
         conversion = self._InputConversion(attr.type.id, attr.id)
         if conversion:
             return self._AddConvertingSetter(attr, html_name, conversion)
-        nullable_type = attr.type.nullable
+        nullable_type = attr.type.nullable or 'TreatNullAs' in attr.ext_attrs
         # If this attr has an output conversion, it is possible that there is a
         # converting getter. We need to make sure the setter type matches the
         # getter type.
@@ -1592,8 +1596,8 @@
 
     def _AddConvertingSetter(self, attr, html_name, conversion):
         # If the attribute is nullable, the setter should be nullable.
-        nullable_in = attr.type.nullable and \
-            not conversion.input_type == 'dynamic'
+        nullable_in = (attr.type.nullable or 'TreatNullAs' in attr.ext_attrs) \
+            and not conversion.input_type == 'dynamic'
         nullable_out = conversion.nullable_output and \
             not conversion.output_type == 'dynamic'
         self._members_emitter.Emit(
diff --git a/tools/dom/src/CssClassSet.dart b/tools/dom/src/CssClassSet.dart
index 445dc08..d1507bc 100644
--- a/tools/dom/src/CssClassSet.dart
+++ b/tools/dom/src/CssClassSet.dart
@@ -17,7 +17,8 @@
    * after the operation, and returns `false` if [value] is absent after the
    * operation.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To toggle multiple classes, use
@@ -51,7 +52,8 @@
    * If this CssClassSet corresponds to one element. Returns true if [value] was
    * added to the set, otherwise false.
    *
-   * If this corresponds to many elements, `null` is always returned.
+   * If this CssClassSet corresponds to many elements, `false` is always
+   * returned.
    *
    * [value] must be a valid 'token' representing a single class, i.e. a
    * non-empty string containing no whitespace.  To add multiple classes use
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index d2b2c9d..22b74d9 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -7,7 +7,7 @@
 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
   factory $CLASSNAME() => document.createDocumentFragment();
 
-  factory $CLASSNAME.html(String html,
+  factory $CLASSNAME.html(String$NULLABLE html,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
 
@@ -15,7 +15,7 @@
       validator: validator, treeSanitizer: treeSanitizer);
   }
 
-  factory $CLASSNAME.svg(String svgContent,
+  factory $CLASSNAME.svg(String$NULLABLE svgContent,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
 
@@ -66,11 +66,11 @@
     return e.innerHtml;
   }
 
-  set innerHtml(String value) {
+  set innerHtml(String$NULLABLE value) {
     this.setInnerHtml(value);
   }
 
-  void setInnerHtml(String html,
+  void setInnerHtml(String$NULLABLE html,
     {NodeValidator$NULLABLE validator,
      NodeTreeSanitizer$NULLABLE treeSanitizer}) {
 
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 2a270b6..6523947 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -120,6 +120,10 @@
     }
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
   void setAll(int index, Iterable<Element> iterable) {
     throw new UnimplementedError();
   }
@@ -130,6 +134,9 @@
 
   Element removeAt(int index) {
     final result = this[index];
+  $if NNBD
+    // TODO(41258): Remove null check after unfork/strong mode.
+  $endif
     if (result != null) {
       _element._removeChild(result);
     }
@@ -138,9 +145,7 @@
 
   Element removeLast() {
     final result = this.last;
-    if (result != null) {
-      _element._removeChild(result);
-    }
+    _element._removeChild(result);
     return result;
   }
 
@@ -345,7 +350,7 @@
    * * [NodeValidator]
    *
    */
-  factory Element.html(String html,
+  factory Element.html(String$NULLABLE html,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     var fragment = document.body$NULLASSERT.createFragment(html,
@@ -566,6 +571,9 @@
 
   @pragma('dart2js:tryInline')
   String$NULLABLE getAttribute(String name) {
+$if NNBD
+    // TODO(41258): Delete this assertion after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     return _getAttribute(name);
@@ -573,6 +581,9 @@
 
   @pragma('dart2js:tryInline')
   String$NULLABLE getAttributeNS(String$NULLABLE namespaceURI, String name) {
+$if NNBD
+    // TODO(41258): Delete this assertion after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
     assert(name != null, 'Attribute name cannot be null');
@@ -581,6 +592,9 @@
 
   @pragma('dart2js:tryInline')
   bool hasAttribute(String name) {
+$if NNBD
+    // TODO(41258): Delete this assertion after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     return _hasAttribute(name);
@@ -588,6 +602,9 @@
 
   @pragma('dart2js:tryInline')
   bool hasAttributeNS(String$NULLABLE namespaceURI, String name) {
+$if NNBD
+    // TODO(41258): Delete this assertion after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
     assert(name != null, 'Attribute name cannot be null');
@@ -596,6 +613,9 @@
 
   @pragma('dart2js:tryInline')
   void removeAttribute(String name) {
+$if NNBD
+    // TODO(41258): Delete this assertion after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     _removeAttribute(name);
@@ -603,6 +623,9 @@
 
   @pragma('dart2js:tryInline')
   void removeAttributeNS(String$NULLABLE namespaceURI, String name) {
+$if NNBD
+    // TODO(41258): Delete this assertion after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     _removeAttributeNS(namespaceURI, name);
@@ -610,6 +633,9 @@
 
   @pragma('dart2js:tryInline')
   void setAttribute(String name, String value) {
+$if NNBD
+    // TODO(41258): Delete these assertions after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
@@ -618,6 +644,9 @@
 
   @pragma('dart2js:tryInline')
   void setAttributeNS(String$NULLABLE namespaceURI, String name, String value) {
+$if NNBD
+    // TODO(41258): Delete these assertions after forcing strong mode.
+$endif
     // Protect [name] against string conversion to "null" or "undefined".
     assert(name != null, 'Attribute name cannot be null');
     // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
@@ -1295,7 +1324,7 @@
    * * [NodeValidator]
    * * [NodeTreeSanitizer]
    */
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String$NULLABLE html,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     if (treeSanitizer == null) {
@@ -1345,7 +1374,7 @@
     if (Range.supportsCreateContextualFragment &&
         _canBeUsedToCreateContextualFragment) {
       _parseRange$NULLASSERT.selectNodeContents(contextElement);
-      fragment = _parseRange$NULLASSERT.createContextualFragment(html);
+      fragment = _parseRange$NULLASSERT.createContextualFragment(html$NULLASSERT);
     } else {
       contextElement._innerHtml = html;
 
@@ -1389,7 +1418,7 @@
    * This uses the default sanitization behavior to sanitize the HTML fragment,
    * use [setInnerHtml] to override the default behavior.
    */
-  set innerHtml(String html) {
+  set innerHtml(String$NULLABLE html) {
     this.setInnerHtml(html);
   }
 
@@ -1414,15 +1443,15 @@
    * * [NodeValidator]
    * * [NodeTreeSanitizer]
    */
-  void setInnerHtml(String html,
+  void setInnerHtml(String$NULLABLE html,
     {NodeValidator$NULLABLE validator,
      NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     text = null;
     if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
       _innerHtml = html;
     } else {
-      append(createFragment(
-          html, validator: validator, treeSanitizer: treeSanitizer));
+      append(createFragment(html, validator: validator,
+          treeSanitizer: treeSanitizer));
     }
   }
   String get innerHtml => _innerHtml;
diff --git a/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
index 11c04d4..f2005af 100644
--- a/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
@@ -66,7 +66,7 @@
   set name(String value);
 
   String get value;
-  set value(String value);
+  set value(String$NULLABLE value);
 
   List<Node> get labels;
 
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
index d53310c..7add9d0 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
@@ -34,7 +34,7 @@
   @JSName('createTBody')
   TableSectionElement _nativeCreateTBody() native;
 
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String$NULLABLE html,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     if (Range.supportsCreateContextualFragment) {
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
index 5d689c7..7ac5c5c 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
@@ -16,7 +16,7 @@
   TableCellElement insertCell(int index) =>
       _insertCell(index) $#NULLSAFECAST(as TableCellElement);
 
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String$NULLABLE html,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     if (Range.supportsCreateContextualFragment) {
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
index 0b3b665..6bdd040 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
@@ -15,7 +15,7 @@
 
   TableRowElement insertRow(int index) => _insertRow(index) $#NULLSAFECAST(as TableRowElement);
 
-  DocumentFragment createFragment(String html,
+  DocumentFragment createFragment(String$NULLABLE html,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     if (Range.supportsCreateContextualFragment) {
diff --git a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
index ea670cc..d030d27 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
@@ -16,13 +16,13 @@
    *
    * * <https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin>
    */
-  void setInnerHtml(String html,
+  void setInnerHtml(String$NULLABLE html,
     {NodeValidator$NULLABLE validator,
      NodeTreeSanitizer$NULLABLE treeSanitizer}) {
     text = null;
     content.nodes.clear();
-    var fragment = createFragment(
-        html, validator: validator, treeSanitizer: treeSanitizer);
+    var fragment = createFragment(html, validator: validator,
+        treeSanitizer: treeSanitizer);
 
     content.append(fragment);
   }
diff --git a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
index 638e458..95da121 100644
--- a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
@@ -141,7 +141,7 @@
     request.onError.listen(controller.addError);
 
     request.onSuccess.listen((e) {
-      T cursor = request.result as dynamic;
+      T$NULLABLE cursor = request.result as dynamic;
       if (cursor == null) {
         controller.close();
       } else {
diff --git a/tools/dom/templates/html/impl/impl_Navigator.darttemplate b/tools/dom/templates/html/impl/impl_Navigator.darttemplate
index 5265a5b..3b2493b 100644
--- a/tools/dom/templates/html/impl/impl_Navigator.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Navigator.darttemplate
@@ -6,7 +6,7 @@
 
 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
 
-  List<Gamepad> getGamepads() {
+  List<Gamepad$NULLABLE> getGamepads() {
     var gamepadList = _getGamepads();
 
     // If no prototype we need one for the world to hookup to the proper Dart class.
diff --git a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
index 1e66365..ca93287 100644
--- a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
@@ -82,11 +82,11 @@
     return container.innerHtml;
   }
 
-  set innerHtml(String value) {
+  set innerHtml(String$NULLABLE value) {
     this.setInnerHtml(value);
   }
 
-  DocumentFragment createFragment(String svg,
+  DocumentFragment createFragment(String$NULLABLE svg,
       {NodeValidator$NULLABLE validator,
        NodeTreeSanitizer$NULLABLE treeSanitizer}) {
 
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index a441144..227b2d5 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -77,7 +77,7 @@
 # presumed to be in this version.  Experiment flags will not affect
 # files that specify an earlier version.
 
-current-version: 2.8
+current-version: 2.9
 
 features:
   extension-methods:
diff --git a/tools/gardening/pubspec.yaml b/tools/gardening/pubspec.yaml
index ca78789..dc6fcca 100644
--- a/tools/gardening/pubspec.yaml
+++ b/tools/gardening/pubspec.yaml
@@ -2,6 +2,8 @@
 # gardening by making it a package.
 name: gardening
 #version: do-not-upload
+environment:
+  sdk: "^2.7.0"
 dependencies:
   args:
   http:
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 3d415c3..1833b60 100755
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -8,9 +8,6 @@
 import 'package:pub_semver/pub_semver.dart';
 import 'package:yaml/yaml.dart';
 
-/// Version to use if a package doesn't constrain the language version.
-final defaultVersion = Version(2, 7, 0);
-
 final repoRoot = p.dirname(p.dirname(p.fromUri(Platform.script)));
 final configFilePath = p.join(repoRoot, '.dart_tool/package_config.json');
 
@@ -34,6 +31,7 @@
     packageDirectory('pkg/front_end/testcases/general_nnbd_opt_out/'),
     packageDirectory('pkg/front_end/testcases/late_lowering/'),
     packageDirectory('pkg/front_end/testcases/nnbd/'),
+    packageDirectory('pkg/front_end/testcases/nonfunction_type_aliases/'),
   ];
 
   var packages = [
@@ -74,18 +72,20 @@
     List<String> packageDirs) sync* {
   for (var packageDir in packageDirs) {
     var version = pubspecLanguageVersion(packageDir);
-    if (version == null) {
-      print('Warning: Unknown language version for ${p.basename(packageDir)}.');
-      version = defaultVersion;
-    }
-
     var hasLibDirectory = Directory(p.join(packageDir, 'lib')).existsSync();
 
+    // TODO(rnystrom): Currently, the pre-built SDK does not allow language
+    // version 2.9.0. Until that's fixed, if we see that version, just write
+    // no version at all so that implementations use the current language
+    // version.
+    if (version.toString() == '2.9.0') version = null;
+
     yield {
       'name': p.basename(packageDir),
       'rootUri': p.relative(packageDir, from: p.dirname(configFilePath)),
       if (hasLibDirectory) 'packageUri': 'lib/',
-      'languageVersion': '${version.major}.${version.minor}'
+      if (version != null)
+        'languageVersion': '${version.major}.${version.minor}'
     };
   }
 }
diff --git a/tools/migration/bin/migrate.dart b/tools/migration/bin/migrate.dart
index d327040..9edeef7 100644
--- a/tools/migration/bin/migrate.dart
+++ b/tools/migration/bin/migrate.dart
@@ -23,6 +23,10 @@
   var step = arguments[0];
   var testDir = arguments[1];
 
+  // If the test directory is just a single identifier, assume it's a language
+  // test subdirectory.
+  if (!testDir.contains("/")) testDir = "language_2/$testDir";
+
   switch (step) {
     case "branch":
       _createBranch(testDir);
@@ -32,6 +36,10 @@
       _copyFiles(testDir);
       break;
 
+    case "fork":
+      _forkFiles(testDir);
+      break;
+
     case "analyze":
       _analyzeFiles(testDir);
       break;
@@ -44,23 +52,15 @@
 
 /// Creates a Git branch whose name matches [testDir].
 void _createBranch(String testDir) {
-  var dirName = toNnbdPath(testDir)
-      .replaceAll("/", "-")
-      .replaceAll("_", "-")
-      .replaceAll(RegExp("[^a-z0-9-]"), "");
-  var branchName = "migrate-$dirName";
-  if (runProcess("git", ["checkout", "-b", branchName])) {
-    print(green("Created and switched to Git branch '$branchName'."));
+  if (_createGitBranch(testDir)) {
     _showNextStep("Next, copy the migrated files over", "copy", testDir);
-  } else {
-    print(red("Failed to create Git branch '$branchName'."));
   }
 }
 
 /// Copies files from [testDir] to the corresponding NNBD test directory.
 ///
 /// Checks for collisions.
-void _copyFiles(String testDir) {
+void _copyFiles(String testDir, {bool showNextStep = false}) {
   for (var from in listFiles(testDir)) {
     var to = toNnbdPath(from);
     if (fileExists(to)) {
@@ -77,10 +77,36 @@
   }
 
   print(green("Copied files from $testDir -> ${toNnbdPath(testDir)}."));
-  print("Next, commit the new files and upload a new CL with them:");
+  if (showNextStep) {
+    print("Next, commit the new files and upload a new CL with them:");
+    print("");
+    print(bold("  git add ."));
+    print(bold("  git commit -m \"Migrate $testDir to NNBD\"."));
+    print(bold("  git cl upload --bypass-hooks"));
+    _showNextStep("Then use analyzer to migrate the files", "analyze", testDir);
+  }
+}
+
+/// Same as "branch" + "copy" then a commit.
+///
+/// Creates a branch, copies files over, and then commits them.
+void _forkFiles(String testDir) {
+  if (!_createGitBranch(testDir)) return;
+  _copyFiles(testDir, showNextStep: false);
+
+  if (!runProcess("git", ["add", "."])) {
+    print(red("Failed to stage changes."));
+    return;
+  }
+
+  if (!runProcess("git", ["commit", "-m", "Migrate $testDir to NNBD."])) {
+    print(red("Failed to commit changes."));
+    return;
+  }
+
+  print(green("Copied files to a new branch and committed."));
+  print("Next, upload a new CL with them:");
   print("");
-  print(bold("  git add ."));
-  print(bold("  git commit -m \"Migrate $testDir to NNBD\"."));
   print(bold("  git cl upload --bypass-hooks"));
   _showNextStep("Then use analyzer to migrate the files", "analyze", testDir);
 }
@@ -110,3 +136,19 @@
   print(bold("  dart tools/migration/bin/migrate.dart "
       "${dryRun ? '--dry-run ' : ''}$step $testDir"));
 }
+
+bool _createGitBranch(String testDir) {
+  var dirName = toNnbdPath(testDir)
+      .replaceAll("/", "-")
+      .replaceAll("_", "-")
+      .replaceAll(RegExp("[^a-z0-9-]"), "");
+  var branchName = "migrate-$dirName";
+  var success = runProcess("git", ["checkout", "-b", branchName]);
+  if (success) {
+    print(green("Created and switched to Git branch '$branchName'."));
+  } else {
+    print(red("Failed to create Git branch '$branchName'."));
+  }
+
+  return success;
+}
diff --git a/tools/migration/bin/progress.dart b/tools/migration/bin/progress.dart
index 270caa8..d14b838 100644
--- a/tools/migration/bin/progress.dart
+++ b/tools/migration/bin/progress.dart
@@ -30,6 +30,8 @@
   var totalMigratedFiles = 0;
   var totalMigratedLines = 0;
 
+  var skipCompleteSubfolders = arguments.contains("--incomplete");
+
   for (var rootDir in legacyRootDirs) {
     var subdirs = Directory(p.join(testRoot, rootDir))
         .listSync()
@@ -59,6 +61,7 @@
       }
 
       if (files == 0) continue;
+      if (skipCompleteSubfolders && lines == migratedLines) continue;
 
       _show(dir, migratedFiles, files, migratedLines, lines);
       totalFiles += files;
diff --git a/tools/migration/bin/test.dart b/tools/migration/bin/test.dart
new file mode 100644
index 0000000..1f39c51
--- /dev/null
+++ b/tools/migration/bin/test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A little utility script to make it easier to run NNBD and legacy tests.
+import 'dart:io';
+
+import 'package:args/args.dart';
+
+import 'package:migration/src/io.dart';
+import 'package:migration/src/test_directories.dart';
+
+/// Maps "normal" names for Dart implementations to their test runner compiler
+/// names.
+const compilerNames = {
+  "analyzer": "dart2analyzer",
+  "cfe": "fasta",
+  "dart2js": "dart2js",
+  "ddc": "dartdevk",
+  "vm": "dartk",
+};
+
+const configurations = {
+  "analyzer": "analyzer-asserts-strong-linux",
+  "cfe": "cfe-strong-linux",
+  "dart2js": "dart2js-weak-linux-x64-d8",
+  "ddc": "dartdevk-strong-linux-release-chrome",
+  "vm": "dartk-strong-linux-release-x64",
+};
+
+void main(List<String> arguments) async {
+  var testDir = "";
+  var isLegacy = false;
+  var compiler = "ddc";
+
+  var argParser = ArgParser();
+  argParser.addFlag("legacy",
+      help: "Run the legacy tests.",
+      negatable: false,
+      callback: (flag) => isLegacy = flag);
+
+  argParser.addOption("configuration",
+      abbr: "c",
+      help: "Which Dart implementation to run the tests on.",
+      allowed: ["analyzer", "cfe", "dart2js", "ddc", "vm"],
+      callback: (option) => compiler = option as String);
+
+  if (arguments.contains("--help")) {
+    showUsage(argParser);
+  }
+
+  try {
+    var argResults = argParser.parse(arguments);
+
+    if (argResults.rest.length != 1) {
+      showUsage(argParser, "Missing test directory.");
+    }
+
+    testDir = argResults.rest[0];
+
+    // If the test directory is just a single identifier, assume it's a language
+    // test subdirectory.
+    if (!testDir.contains("/")) testDir = "language_2/$testDir";
+  } on FormatException catch (exception) {
+    showUsage(argParser, exception.message);
+  }
+
+  if (!isLegacy) testDir = toNnbdPath(testDir);
+
+  // DDC doesn't have a Mac bot so when running DDC tests on a Mac, use a manual
+  // configuration. Otherwise, use the right named configuration.
+  List<String> testArgs;
+  if (Platform.isLinux || compiler != "ddc") {
+    var configuration = configurations[compiler];
+    if (!Platform.isLinux) {
+      // TODO(rnystrom): We'll probably never need to run this script on
+      // Windows, but if we do... do that.
+      configuration = configuration.replaceAll("linux", "mac");
+    }
+
+    testArgs = ["-n$configuration", testDir];
+  } else {
+    testArgs = [
+      "--mode=release",
+      if (!isLegacy) ...[
+        "--enable-experiment=non-nullable",
+        "--nnbd=strong",
+      ],
+      "--compiler=${compilerNames[compiler]}",
+      testDir,
+    ];
+  }
+
+  print("Running tools/test.py ${testArgs.join(' ')}");
+  await runProcessAsync("tools/test.py", testArgs);
+}
+
+void showUsage(ArgParser argParser, [String error]) {
+  if (error != null) {
+    print(error);
+    print("");
+  }
+  print("Usage: dart test.dart <source dir>");
+  print(argParser.usage);
+  exit(error == null ? 0 : 1);
+}
diff --git a/tools/migration/lib/src/io.dart b/tools/migration/lib/src/io.dart
index 638b27b5..faa68cb 100644
--- a/tools/migration/lib/src/io.dart
+++ b/tools/migration/lib/src/io.dart
@@ -131,6 +131,20 @@
   return result.exitCode == 0;
 }
 
+Future<bool> runProcessAsync(String executable, List<String> arguments,
+    {String workingDirectory}) async {
+  if (dryRun) {
+    print("Dry run: run $executable ${arguments.join(' ')}");
+    return true;
+  }
+
+  var process = await Process.start(executable, arguments);
+  process.stdout.listen(stdout.add);
+  process.stderr.listen(stderr.add);
+
+  return (await process.exitCode) == 0;
+}
+
 /// Returns a list of the paths to all files within [dir], which is
 /// assumed to be relative to the SDK's "tests" directory and having file with
 /// an extension in [extensions].
diff --git a/tools/run_abi_tests.py b/tools/run_abi_tests.py
index e32f008..cecf86a 100644
--- a/tools/run_abi_tests.py
+++ b/tools/run_abi_tests.py
@@ -27,7 +27,12 @@
         default=os.path.join(outDir, 'logs'),
         metavar='DIR',
         dest='logDir',
-        help='Directory to output restuls.json and logs.json to.')
+        help='Directory to output results.json and logs.json to.')
+    parser.add_argument(
+        '-n',
+        metavar='NAME',
+        dest='configuration_name',
+        help='Name of the configuration to use in the results.')
     return parser.parse_args()
 
 
@@ -137,10 +142,10 @@
 
 # Diff the results of a test for each version and construct a new test result
 # that reports whether the test results match for each version.
-def diffResults(results):
+def diffResults(results, configuration_name):
     outResult = pickOne(results)
     exp = results[None]['result'] if None in results else None
-    outResult['configuration'] = 'dartkb-abi-linux-release-x64'
+    outResult['configuration'] = configuration_name
     outResult['expected'] = exp
     outResult['result'] = exp
     outResult['matches'] = True
@@ -158,12 +163,12 @@
 
 # Create a log entry for a test that has diffs. Concatenate all the log records
 # and include which tests failed.
-def makeLog(diffs, results, logRecords):
+def makeLog(diffs, results, logRecords, configuration_name):
     result = pickOne(results)
     logs = ["%s: %s" % (str(v), l['log']) for v, l in logRecords.items()]
     return {
         'name': result['name'],
-        'configuration': 'dartkb-abi-linux-release-x64',
+        'configuration': configuration_name,
         'result': result['result'],
         'log': '\n\n\n'.join([repr(diffs)] + logs),
     }
@@ -179,12 +184,15 @@
     with open(resultFileName, 'w') as resultFile:
         with open(logFileName, 'w') as logFile:
             for name, results in allResults.items():
-                outResult, diffs = diffResults(results)
+                outResult, diffs = diffResults(results,
+                                               flags.configuration_name)
                 resultFile.write(json.dumps(outResult) + '\n')
                 if diffs:
                     logRecords = allLogs[name] if name in allLogs else []
                     logFile.write(
-                        json.dumps(makeLog(diffs, results, logRecords)) + '\n')
+                        json.dumps(
+                            makeLog(diffs, results, logRecords, flags.
+                                    configuration_name)) + '\n')
     print('Log files emitted to %s and %s' % (resultFileName, logFileName))
 
 
diff --git a/tools/sdks/update.sh b/tools/sdks/update.sh
index 6f1cc4e..dc96ef1 100755
--- a/tools/sdks/update.sh
+++ b/tools/sdks/update.sh
@@ -9,8 +9,8 @@
 fi
 
 case "$1" in
-*-dev.*.0) channel="dev";;
-*-dev.*) channel="beta";;
+*-*.0.dev) channel="dev";;
+*-*.*.beta) channel="beta";;
 *) channel="stable";;
 esac
 
@@ -83,3 +83,5 @@
 rm -rf sdk
 
 popd
+
+gclient setdep --var="sdk_tag=version:$1"
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 7878730..a374fc2 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -339,7 +339,8 @@
       if (summaryOnly) {
         incrementalComponent.uriToSource.clear();
         incrementalComponent.problemsAsJson = null;
-        incrementalComponent.mainMethod = null;
+        incrementalComponent.setMainMethodAndMode(
+            null, true, incrementalComponent.mode);
         target.performOutlineTransformations(incrementalComponent);
         makeStable(incrementalComponent);
         return Future.value(fe.serializeComponent(incrementalComponent,
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index cfaa8d9..dda6c4e 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -66,12 +66,12 @@
   training_args = [
     "--packages=" + rebase_path("../../.packages"),
     "--libraries-spec=" + rebase_path("../../$libraries_specification_path"),
-  ]
 
-  if (use_nnbd) {
-    training_args += [ "--enable-experiment=non-nullable" ]
-  }
-  training_args += [ rebase_path("$target_gen_dir/dart2js.dart") ]
+    # Specifying the platform explicitly elides running the CFE on the sdk
+    # sources.
+    "--platform-binaries=" + rebase_path("$root_out_dir/"),
+    rebase_path("$target_gen_dir/dart2js.dart"),
+  ]
 }
 
 compile_platform("compile_dart2js_platform") {
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index 495643d..44a5426 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -18,8 +18,20 @@
                             ],
                             "list lines")
 
-application_snapshot("dartdev") {
+group("dartdev") {
+  deps = [ ":copy_dartdev_snapshot" ]
+}
+
+copy("copy_dartdev_snapshot") {
+  visibility = [ ":dartdev" ]
+  deps = [ ":generate_dartdev_snapshot" ]
+  sources = [ "$root_gen_dir/dartdev.dart.snapshot" ]
+  outputs = [ "$root_out_dir/dartdev.dart.snapshot" ]
+}
+
+application_snapshot("generate_dartdev_snapshot") {
   main_dart = "../../pkg/dartdev/bin/dartdev.dart"
   training_args = [ "--help" ]
   inputs = dartdev_files + dartfix_files
+  output = "$root_gen_dir/dartdev.dart.snapshot"
 }